===== ./completion/meson.build =====
# Copyright 2022 Collabora Ltd.
# SPDX-License-Identifier: LGPL-2.1-or-later

install_data(
  'flatpak',
  install_dir : get_option('datadir') / 'bash-completion' / 'completions',
)
install_data(
  '_flatpak',
  install_dir : get_option('datadir') / 'zsh' / 'site-functions',
)
install_data(
  'flatpak.fish',
  install_dir : get_option('datadir') / 'fish' / 'vendor_completions.d',
)

===== ./completion/flatpak =====
# Check for bash
[ -z "$BASH_VERSION" ] && return

####################################################################################################

__flatpak() {
    local IFS=$'\n'
    local cur=`_get_cword :`
    RES=($(flatpak complete "${COMP_LINE}" "${COMP_POINT}" "${cur}"))

    COMPREPLY=()
    for i in "${!RES[@]}"; do
        if [[ "${RES[$i]}" = "__FLATPAK_FILE" ]]; then
            declare -a COMPGEN_OPTS=('-f')
        elif [[ "${RES[$i]}" = "__FLATPAK_BUNDLE_FILE" ]]; then
            declare -a COMPGEN_OPTS=('-f' '-X' '!*.flatpak')
        elif [[ "${RES[$i]}" = "__FLATPAK_BUNDLE_OR_REF_FILE" ]]; then
            declare -a COMPGEN_OPTS=('-f' '-X' '!*.flatpak@(|ref)')
        elif [[ "${RES[$i]}" = "__FLATPAK_DIR" ]]; then
            declare -a COMPGEN_OPTS=('-d')
        else
            declare -a COMPGEN_OPTS=()
        fi

        if [[ ${#COMPGEN_OPTS[@]} -ne 0 ]]; then
            if [[ "${cur}" = "=" ]]; then
                CUR=""
            else
                CUR="${cur}"
            fi
            COMPREPLY=("${COMPREPLY[@]}" $(compgen ${COMPGEN_OPTS[@]} -- "${CUR}") )
        else
            COMPREPLY=("${COMPREPLY[@]}" "${RES[$i]}")
        fi
    done
}

####################################################################################################

complete -o nospace -F __flatpak flatpak

===== ./completion/_flatpak =====
#compdef flatpak

emulate -L zsh

local index
(( index = ${(c)#words[0,CURRENT]} + $#PREFIX + 1 ))


local resp=($(flatpak complete "$words" $index "$words[CURRENT]"))

_description options opt_expl option
_description arguments arg_expl argument

local match
for match in $resp; do
  case $match in
    __FLATPAK_FILE) _files;;
    __FLATPAK_BUNDLE_FILE) _path_files -g '*.flatpak';;
    __FLATPAK_BUNDLE_OR_REF_FILE) _path_files -g '*.flatpak(|ref)';;
    __FLATPAK_DIR) _path_files -/;;
    -*=) compadd $opt_expl[@] -S "" -- $match;;
    -*) compadd $opt_expl[@] -- $match;;
    *) compadd $arg_expl[@] $match;;
  esac
done

# vim: ft=zsh

===== ./completion/flatpak.fish =====
function __fish_complete_flatpak
    set current_cmd (commandline -p)
    set current_position (commandline -C)
    set current_token (commandline -ct)
    command flatpak complete "$current_cmd" "$current_position" "$current_token" | while read fp_sugg
        set sugg (string trim -- "$fp_sugg")
        switch "$sugg"
            case __FLATPAK_FILE
                __fish_complete_path "$current_token"
            case __FLATPAK_BUNDLE_FILE
                __fish_complete_suffix "$current_token" '.flatpak'
            case __FLATPAK_BUNDLE_OR_REF_FILE
                __fish_complete_suffix "$current_token" '.flatpak'
                __fish_complete_suffix "$current_token" '.flatpakref'
            case __FLATPAK_DIR
                __fish_complete_directories "$current_token"
            case '*'
                # completing a value for option
                if string match -- "--*=" "$current_token"
                    echo "$current_token$sugg"
                else
                    echo "$sugg"
                end
        end
    end
    return
end

function __fish_flatpak_complete_files
    if __fish_seen_subcommand_from run build
        set pos_args 0
        for t in (commandline -co)
            if string match --invert -- "-*" "$t"
                set pos_args (math "$pos_args+1")
            end
        end
        if test $pos_args -gt 2
            return 0
        end
    end
    return 1
end

complete -c flatpak -f -n "not __fish_flatpak_complete_files" -a '(__fish_complete_flatpak)'
complete -c flatpak -n "__fish_flatpak_complete_files" -a '(__fish_complete_flatpak)'

===== ./COPYING =====
                  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!

===== ./README.md =====
<p align="center">
  <img src="https://github.com/flatpak/flatpak/blob/main/flatpak.png?raw=true" alt="Flatpak icon"/>
</p>

Flatpak is a system for building, distributing, and running sandboxed
desktop applications on Linux.

See https://flatpak.org/ for more information.

Flatpak is available in the package repositories of most Linux distributions
and can be installed from there. See https://flatpak.org/setup/ for quick
setup instructions for many distributions.

Community discussion happens in [#flatpak:matrix.org](https://matrix.to/#/#flatpak:matrix.org), on [the mailing list](https://lists.freedesktop.org/mailman/listinfo/flatpak), and on [the Flathub Discourse](https://discourse.flathub.org/).

Read documentation for Flatpak [here](https://docs.flatpak.org/en/latest/index.html).

# Contributing

Flatpak welcomes contributions from anyone! Here are some ways you can help:
* Fix [one of the issues](https://github.com/flatpak/flatpak/issues/) and submit a PR
* Update flatpak's translations and submit a PR
* Improve flatpak's documentation, hosted at http://docs.flatpak.org and developed over in [flatpak-docs](https://github.com/flatpak/flatpak-docs)
* Find a bug and [submit a detailed report](https://github.com/flatpak/flatpak/issues/new) including your OS, flatpak version, and the steps to reproduce
* Add your favorite application to [Flathub](https://flathub.org) by writing a flatpak-builder manifest and [submitting it](https://github.com/flathub/flathub/wiki/App-Submission)
* Improve the [Flatpak support](https://github.com/flatpak/flatpak/wiki/Distribution) in your favorite Linux distribution

# Hacking
See [CONTRIBUTING.md](CONTRIBUTING.md)

# Related Projects

Here are some notable projects in the Flatpak ecosystem:
* [Flatseal](https://github.com/tchx84/flatseal): An app for managing permissions of Flatpak apps without using the CLI
* [Flat-manager](https://github.com/flatpak/flat-manager): A tool for managing Flatpak repositories

===== ./system-helper/org.freedesktop.Flatpak.SystemHelper.conf =====
<?xml version="1.0" encoding="UTF-8"?> <!-- -*- XML -*- -->

<!DOCTYPE busconfig PUBLIC
 "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
 "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
<busconfig>

  <!-- This configuration file specifies the required security policies
       for the the flatpak system helper to work. -->

  <policy user="root">
    <allow own="org.freedesktop.Flatpak.SystemHelper"/>
  </policy>

 <!-- Allow anyone to call into the service - we'll reject callers using PolicyKit -->
  <policy context="default">
    <allow send_destination="org.freedesktop.Flatpak.SystemHelper"
           send_interface="org.freedesktop.Flatpak.SystemHelper"/>
    <allow send_destination="org.freedesktop.Flatpak.SystemHelper"
           send_interface="org.freedesktop.DBus.Introspectable"/>
    <allow send_destination="org.freedesktop.Flatpak.SystemHelper"
           send_interface="org.freedesktop.DBus.Peer"/>
  </policy>

</busconfig>

===== ./system-helper/org.freedesktop.Flatpak.SystemHelper.service.in =====
[D-BUS Service]
Name=org.freedesktop.Flatpak.SystemHelper
Exec=@libexecdir@/flatpak-system-helper@extraargs@
SystemdService=flatpak-system-helper.service
User=root

===== ./system-helper/flatpak.conf.in =====
u @SYSTEM_HELPER_USER@ - "Flatpak system helper" -

===== ./system-helper/org.freedesktop.Flatpak.policy.in =====
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE policyconfig PUBLIC
 "-//freedesktop//DTD PolicyKit Policy Configuration 1.0//EN"
 "http://www.freedesktop.org/standards/PolicyKit/1.0/policyconfig.dtd">
<policyconfig>

  <!--
    Policy definitions for Flatpak system actions.
    Copyright (c) 2016 Alexander Larsson <alexl@redhat.com>
  -->

  <vendor>The Flatpak Project</vendor>
  <vendor_url>https://github.com/flatpak/flatpak</vendor_url>
  <icon_name>package-x-generic</icon_name>

  <action id="org.freedesktop.Flatpak.app-install">
    <!-- SECURITY:
          - Normal users need admin authentication to install software
            system-wide.
          - Note that we install polkit rules that allow local users
            in the wheel group to install without authenticating.
     -->
    <description>Install signed application</description>
    <message>Authentication is required to install software</message>
    <icon_name>package-x-generic</icon_name>
    <defaults>
      <allow_any>auth_admin</allow_any>
      <allow_inactive>auth_admin</allow_inactive>
      <allow_active>auth_admin_keep</allow_active>
    </defaults>
    <annotate key="org.freedesktop.policykit.imply">org.freedesktop.Flatpak.app-update org.freedesktop.Flatpak.runtime-install org.freedesktop.Flatpak.runtime-update</annotate>
  </action>

  <action id="org.freedesktop.Flatpak.runtime-install">
    <!-- SECURITY:
          - Normal users need admin authentication to install software
            system-wide.
          - Note that we install polkit rules that allow local users
            in the wheel group to install without authenticating.
    -->
    <description>Install signed runtime</description>
    <message>Authentication is required to install software</message>
    <icon_name>package-x-generic</icon_name>
    <defaults>
      <allow_any>auth_admin</allow_any>
      <allow_inactive>auth_admin</allow_inactive>
      <allow_active>auth_admin_keep</allow_active>
    </defaults>
    <annotate key="org.freedesktop.policykit.imply">org.freedesktop.Flatpak.runtime-update</annotate>
  </action>

  <action id="org.freedesktop.Flatpak.app-update">
    <!-- SECURITY:
          - Normal users do not require admin authentication to update an
            app as the commit will be signed, and the action is required
            to update the system when unattended.
          - Changing this to anything other than 'yes' will break unattended
            updates.
     -->
    <description>Update signed application</description>
    <message>Authentication is required to update software</message>
    <icon_name>package-x-generic</icon_name>
    <defaults>
      <allow_any>auth_admin</allow_any>
      <allow_inactive>auth_admin</allow_inactive>
      <allow_active>yes</allow_active>
    </defaults>
    <annotate key="org.freedesktop.policykit.imply">org.freedesktop.Flatpak.runtime-install org.freedesktop.Flatpak.runtime-update</annotate>
  </action>

  <action id="org.freedesktop.Flatpak.runtime-update">
    <!-- SECURITY:
          - Normal users do not require admin authentication to update a
            runtime as the commit will be signed, and the action is required
            to update the system when unattended.
          - Changing this to anything other than 'yes' will break unattended
            updates.
     -->
    <description>Update signed runtime</description>
    <message>Authentication is required to update software</message>
    <icon_name>package-x-generic</icon_name>
    <defaults>
      <allow_any>auth_admin</allow_any>
      <allow_inactive>auth_admin</allow_inactive>
      <allow_active>yes</allow_active>
    </defaults>
  </action>

  <action id="org.freedesktop.Flatpak.update-remote">
    <!-- SECURITY:
          - Normal users do not need authentication to update metadata
            from signed repositories.
     -->
    <description>Update remote metadata</description>
    <message>Authentication is required to update remote info</message>
    <icon_name>package-x-generic</icon_name>
    <defaults>
      <allow_any>auth_admin</allow_any>
      <allow_inactive>auth_admin</allow_inactive>
      <allow_active>yes</allow_active>
    </defaults>
  </action>

  <action id="org.freedesktop.Flatpak.modify-repo">
    <!-- SECURITY:
          - Normal users do not need authentication to modify the
            OSTree repository
          - Note that we install polkit rules that allow local users
            in the wheel group to modify repos without authenticating.
     -->
    <description>Update system repository</description>
    <message>Authentication is required to modify a system repository</message>
    <icon_name>package-x-generic</icon_name>
    <defaults>
      <allow_any>auth_admin</allow_any>
      <allow_inactive>auth_admin</allow_inactive>
      <allow_active>yes</allow_active>
    </defaults>
  </action>

  <action id="org.freedesktop.Flatpak.install-bundle">
    <!-- SECURITY:
          - Normal users need admin authentication to install software
            system-wide.
     -->
    <description>Install bundle</description>
    <message>Authentication is required to install software from $(path)</message>
    <icon_name>package-x-generic</icon_name>
    <defaults>
      <allow_any>auth_admin</allow_any>
      <allow_inactive>auth_admin</allow_inactive>
      <allow_active>auth_admin_keep</allow_active>
    </defaults>
    <annotate key="org.freedesktop.policykit.imply">org.freedesktop.Flatpak.runtime-install org.freedesktop.Flatpak.runtime-update</annotate>
  </action>

  <action id="org.freedesktop.Flatpak.runtime-uninstall">
    <!-- SECURITY:
          - Normal users need admin authentication to uninstall software
            system-wide.
          - Note that we install polkit rules that allow local users
            in the wheel group to uninstall without authenticating.
     -->
    <description>Uninstall runtime</description>
    <message>Authentication is required to uninstall software</message>
    <icon_name>package-x-generic</icon_name>
    <defaults>
      <allow_any>auth_admin</allow_any>
      <allow_inactive>auth_admin</allow_inactive>
      <allow_active>auth_admin_keep</allow_active>
    </defaults>
  </action>

  <action id="org.freedesktop.Flatpak.app-uninstall">
    <!-- SECURITY:
          - Normal users need admin authentication to uninstall software
            system-wide.
          - Note that we install polkit rules that allow local users
            in the wheel group to uninstall without authenticating.
     -->
    <description>Uninstall app</description>
    <message>Authentication is required to uninstall $(ref)</message>
    <icon_name>package-x-generic</icon_name>
    <defaults>
      <allow_any>auth_admin</allow_any>
      <allow_inactive>auth_admin</allow_inactive>
      <allow_active>auth_admin_keep</allow_active>
    </defaults>
    <annotate key="org.freedesktop.policykit.imply">org.freedesktop.Flatpak.runtime-uninstall</annotate>
  </action>

  <action id="org.freedesktop.Flatpak.configure-remote">
    <!-- SECURITY:
          - Normal users need admin authentication to configure system-wide
            software repositories.
     -->
    <description>Configure Remote</description>
    <message>Authentication is required to configure software repositories</message>
    <icon_name>package-x-generic</icon_name>
    <defaults>
      <allow_any>auth_admin</allow_any>
      <allow_inactive>auth_admin</allow_inactive>
      <allow_active>auth_admin_keep</allow_active>
    </defaults>
  </action>

  <action id="org.freedesktop.Flatpak.configure">
    <!-- SECURITY:
          - Normal users need admin authentication to configure the system-wide
            Flatpak installation.
     -->
    <description>Configure</description>
    <message>Authentication is required to configure software installation</message>
    <icon_name>package-x-generic</icon_name>
    <defaults>
      <allow_any>auth_admin</allow_any>
      <allow_inactive>auth_admin</allow_inactive>
      <allow_active>auth_admin_keep</allow_active>
    </defaults>
  </action>

  <action id="org.freedesktop.Flatpak.appstream-update">
    <!-- SECURITY:
          - Normal users do not require admin authentication to update
            appstream data as it will be signed, and the action is required
            to update the system when unattended.
          - Changing this to anything other than 'yes' will break unattended
            updates.
     -->
    <description>Update appstream</description>
    <message>Authentication is required to update information about software</message>
    <icon_name>package-x-generic</icon_name>
    <defaults>
      <allow_any>auth_admin</allow_any>
      <allow_inactive>auth_admin</allow_inactive>
      <allow_active>yes</allow_active>
    </defaults>
  </action>

  <action id="org.freedesktop.Flatpak.metadata-update">
    <!-- SECURITY:
          - Normal users do not require admin authentication to update
            metadata as it will be signed, and the action is required
            to update the system when unattended.
          - Changing this to anything other than 'yes' will break unattended
            updates.
     -->
    <description>Update metadata</description>
    <message>Authentication is required to update metadata</message>
    <icon_name>package-x-generic</icon_name>
    <defaults>
      <allow_any>auth_admin</allow_any>
      <allow_inactive>auth_admin</allow_inactive>
      <allow_active>yes</allow_active>
    </defaults>
  </action>

  <action id="org.freedesktop.Flatpak.override-parental-controls">
    <!-- SECURITY:
          - Authorisation to actually install software is controlled by
            org.freedesktop.Flatpak.app-install.
          - This action is checked after app-install, as it can only be done
            once the app’s data (including its content rating) has been
            downloaded.
          - This action is checked to see if the installation should be allowed
            based on whether the app being installed has content which doesn’t
            comply with the user’s parental controls policy (the content is
            ‘too extreme’).
          - It is checked only if an app has too extreme content for the user
            who is trying to install it (in which case, the app is ‘unsafe’).
          - Typically, normal users will need admin permission to install apps
            with extreme content; admins will be able to install it without
            additional checks.
          - In order to configure the policy so that admins can install safe and
            unsafe software anywhere without authorisation, and non-admins can
            install safe software in their user or system dirs without
            authorisation, but need authorisation to install unsafe software
            anywhere:
             * Unconditionally return `yes` from `app-install`.
             * Return `auth_admin` from `override-parental-controls` for users
               not in `@privileged_group@`, and `yes` for users in it.
             * Set the malcontent `is-{user,system}-installation-allowed`
               properties of all non-admins’ parental controls policies to true.
          - In order to configure the policy so that admins can install safe and
            unsafe software anywhere without authorisation, and non-admins can
            install safe software in their user dir without authorisation, but
            need authorisation to install safe software in the system dir or to
            install unsafe software anywhere:
             * Unconditionally return `yes` from `app-install`.
             * Return `auth_admin` from `override-parental-controls` for users
               not in `@privileged_group@`, and `yes` for users in it.
             * Set the malcontent `is-user-installation-allowed` property of all
               non-admins’ parental controls policies to true.
             * Set the malcontent `is-system-installation-allowed` property of
               all non-admins’ parental controls policies to false.
          - In order to configure the policy so that all users (including
            admins) can install safe software anywhere without authorisation,
            but need authorisation to install unsafe software anywhere (i.e.
            applying parental controls to admins too):
             * Unconditionally return `yes` from `app-install`.
             * Unconditionally return `auth_admin` from `override-parental-controls`.
             * Set the malcontent `is-user-installation-allowed` property of all
               users’ parental controls policies to true.
             * Set the malcontent `is-system-installation-allowed` property of
               all users’ parental controls policies to true.
     -->
    <description>Override parental controls for installs</description>
    <message>Authentication is required to install software which is restricted by your parental controls policy</message>
    <icon_name>package-x-generic</icon_name>
    <defaults>
      <allow_any>auth_admin</allow_any>
      <allow_inactive>auth_admin</allow_inactive>
      <allow_active>auth_admin</allow_active>
    </defaults>
    <annotate key="org.freedesktop.policykit.imply">org.freedesktop.Flatpak.override-parental-controls-update</annotate>
  </action>

  <action id="org.freedesktop.Flatpak.override-parental-controls-update">
    <!-- SECURITY:
          - This is like org.freedesktop.Flatpak.override-parental-controls, but
            it’s queried for app updates, whereas the former is queried for app
            installs.
          - As with the above action, this one is only queried if
            org.freedesktop.Flatpak.app-update has allowed the app update, and
            only if the app being updated has too extreme content for the user
            who is trying to update it.
          - The default policy for this is to *allow* updates to ‘too extreme’
            apps by default, on the basis that having an out-of-date (i.e.
            insecure or unsupported) app is a worse outcome than automatically
            installing an update which has radically different content from the
            version of the app which the parent originally vetted and installed.
     -->
    <description>Override parental controls for updates</description>
    <message>Authentication is required to update software which is restricted by your parental controls policy</message>
    <icon_name>package-x-generic</icon_name>
    <defaults>
      <allow_any>auth_admin</allow_any>
      <allow_inactive>auth_admin</allow_inactive>
      <allow_active>yes</allow_active>
    </defaults>
  </action>

</policyconfig>


===== ./system-helper/meson.build =====
# Copyright 2022 Collabora Ltd.
# SPDX-License-Identifier: LGPL-2.1-or-later

executable(
  'flatpak-system-helper',
  dependencies : base_deps + [
    appstream_dep,
    json_glib_dep,
    libflatpak_common_base_dep,
    libflatpak_common_dep,
    libglnx_dep,
    libostree_dep,
    polkit_agent_dep,
  ],
  install : true,
  install_dir : get_option('libexecdir'),
  sources : ['flatpak-system-helper.c'],
)

configure_file(
  input : 'flatpak-system-helper.service.in',
  output : 'flatpak-system-helper.service',
  configuration : service_conf_data,
  install_dir : get_option('systemdsystemunitdir'),
)

configure_file(
  input : 'org.freedesktop.Flatpak.SystemHelper.service.in',
  output : 'org.freedesktop.Flatpak.SystemHelper.service',
  configuration : service_conf_data,
  install_dir : get_option('datadir') / 'dbus-1' / 'system-services',
)

install_data(
  'org.freedesktop.Flatpak.SystemHelper.conf',
  install_dir : dbus_config_dir,
)

conf_data = configuration_data()
conf_data.set('privileged_group', get_option('privileged_group'))
configure_file(
  input : 'org.freedesktop.Flatpak.rules.in',
  output : 'org.freedesktop.Flatpak.rules',
  configuration : conf_data,
  install_dir : get_option('datadir') / 'polkit-1' / 'rules.d',
)

i18n.merge_file(
  input : 'org.freedesktop.Flatpak.policy.in',
  output : 'org.freedesktop.Flatpak.policy',
  po_dir : '../po',
  install : true,
  install_dir : get_option('datadir') / 'polkit-1' / 'actions',
)

conf_data = configuration_data()
conf_data.set('SYSTEM_HELPER_USER', get_option('system_helper_user'))
configure_file(
  input : 'flatpak.conf.in',
  output : 'flatpak.conf',
  configuration : conf_data,
  install_dir : get_option('sysusersdir'),
)

===== ./system-helper/flatpak-system-helper.h =====
/*
 * Copyright © 2021 Collabora Ltd.
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 */

#ifndef __FLATPAK_SYSTEM_HELPER_H__
#define __FLATPAK_SYSTEM_HELPER_H__

#define FLATPAK_SYSTEM_HELPER_BUS_NAME "org.freedesktop.Flatpak.SystemHelper"
#define FLATPAK_SYSTEM_HELPER_PATH "/org/freedesktop/Flatpak/SystemHelper"
#define FLATPAK_SYSTEM_HELPER_INTERFACE FLATPAK_SYSTEM_HELPER_BUS_NAME

#endif

===== ./system-helper/flatpak-system-helper.c =====
/* vi:set et sw=2 sts=2 cin cino=t0,f0,(0,{s,>2s,n-s,^-s,e-s:
 * Copyright © 2014 Red Hat, Inc
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Alexander Larsson <alexl@redhat.com>
 */

#include "config.h"

#include <locale.h>
#include <stdlib.h>
#include <string.h>
#include <gio/gio.h>
#include <glib/gprintf.h>
#include <polkit/polkit.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <pwd.h>
#include <gio/gunixfdlist.h>
#include <sys/mount.h>
#include <fcntl.h>
#include <unistd.h>

#include <glib-unix.h>

#include "flatpak-dbus-generated.h"
#include "flatpak-dir-private.h"
#include "flatpak-error.h"
#include "flatpak-image-source-private.h"
#include "flatpak-oci-registry-private.h"
#include "flatpak-progress-private.h"
#include "flatpak-system-helper.h"
#include "flatpak-utils-base-private.h"
#include "flatpak-utils-private.h"

static PolkitAuthority *authority = NULL;
static FlatpakSystemHelper *helper = NULL;
static GMainLoop *main_loop = NULL;
static guint name_owner_id = 0;

G_LOCK_DEFINE (cache_dirs_in_use);
static GHashTable *cache_dirs_in_use = NULL;

static gboolean on_session_bus = FALSE;
static gboolean disable_revokefs = FALSE;
static gboolean no_idle_exit = FALSE;

static int opt_verbose;
static gboolean opt_ostree_verbose;

#define IDLE_TIMEOUT_SECS 10 * 60

/* This uses a weird Auto prefix to avoid conflicts with later added polkit types.
 */
typedef PolkitAuthorizationResult AutoPolkitAuthorizationResult;
typedef PolkitDetails             AutoPolkitDetails;
typedef PolkitSubject             AutoPolkitSubject;

G_DEFINE_AUTOPTR_CLEANUP_FUNC (AutoPolkitAuthorizationResult, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (AutoPolkitDetails, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (AutoPolkitSubject, g_object_unref)

typedef struct
{
  FlatpakSystemHelper *object;
  GDBusMethodInvocation *invocation;
  GCancellable *cancellable;
  gboolean preserve_pull;     /* Whether to preserve partially pulled repo on pull failure */

  guint watch_id;
  uid_t uid;                  /* uid of the client initiating the pull */

  gint client_socket;         /* fd that is send back to the client for spawning revoke-fuse */
  gint backend_exit_socket;   /* write end of a pipe which helps terminating revokefs backend if
                                 system helper exits abruptly */

  gchar *src_dir;             /* source directory containing the actual child repo */
  gchar *unique_name;

  GSubprocess *revokefs_backend;
} OngoingPull;

static void
terminate_revokefs_backend (OngoingPull *pull)
{
  /* Terminating will guarantee that all access to write operations are revoked. */
  if (shutdown (pull->client_socket, SHUT_RDWR) == -1 ||
      !g_subprocess_wait (pull->revokefs_backend, NULL, NULL))
    {
      g_warning ("Failed to shutdown client socket, killing backend writer process");
      g_subprocess_force_exit (pull->revokefs_backend);
    }

  g_clear_object (&pull->revokefs_backend);
}

static gboolean
remove_dir_from_cache_dirs_in_use (const char *src_dir)
{
  gboolean res;

  G_LOCK (cache_dirs_in_use);
  res = g_hash_table_remove (cache_dirs_in_use, src_dir);
  G_UNLOCK (cache_dirs_in_use);

  return res;
}

static void
ongoing_pull_free (OngoingPull *pull)
{
  g_autoptr(GFile) src_dir_file = NULL;
  g_autoptr(GError) local_error = NULL;

  g_clear_handle_id (&pull->watch_id, g_bus_unwatch_name);

  src_dir_file = g_file_new_for_path (pull->src_dir);

  if (pull->revokefs_backend)
    terminate_revokefs_backend (pull);

  if (!pull->preserve_pull &&
      !flatpak_rm_rf (src_dir_file, NULL, &local_error))
    {
      g_warning ("Unable to remove ongoing pull's src dir at %s: %s",
                 pull->src_dir, local_error->message);
      g_clear_error (&local_error);
    }

  remove_dir_from_cache_dirs_in_use (pull->src_dir);

  g_clear_pointer (&pull->src_dir, g_free);
  g_clear_pointer (&pull->unique_name, g_free);
  close (pull->client_socket);
  close (pull->backend_exit_socket);

  g_clear_object (&pull->cancellable);
  g_slice_free (OngoingPull, pull);
}

G_DEFINE_AUTOPTR_CLEANUP_FUNC (OngoingPull, ongoing_pull_free);

static void
skeleton_died_cb (gpointer data)
{
  g_info ("skeleton finalized, exiting");
  g_main_loop_quit (main_loop);
}

static gboolean
unref_skeleton_in_timeout_cb (gpointer user_data)
{
  static gboolean unreffed = FALSE;

  g_info ("unreffing helper main ref");
  if (!unreffed)
    {
      g_object_unref (helper);
      unreffed = TRUE;
    }

  return G_SOURCE_REMOVE;
}

static void
unref_skeleton_in_timeout (void)
{
  if (name_owner_id)
    g_bus_unown_name (name_owner_id);
  name_owner_id = 0;

  /* After we've lost the name or idled we drop the main ref on the helper
     so that we'll exit when it drops to zero. However, if there are
     outstanding calls these will keep the refcount up during the
     execution of them. We do the unref on a timeout to make sure
     we're completely draining the queue of (stale) requests. */
  g_timeout_add (500, unref_skeleton_in_timeout_cb, NULL);
}

static gboolean
idle_timeout_cb (gpointer user_data)
{
  G_LOCK (cache_dirs_in_use);
  guint ongoing_pulls_len = g_hash_table_size (cache_dirs_in_use);
  G_UNLOCK (cache_dirs_in_use);
  if (ongoing_pulls_len != 0)
    return G_SOURCE_CONTINUE;

  if (name_owner_id)
    {
      g_info ("Idle - unowning name");
      unref_skeleton_in_timeout ();
    }
  return G_SOURCE_REMOVE;
}

G_LOCK_DEFINE_STATIC (idle);
static void
schedule_idle_callback (void)
{
  static guint idle_timeout_id = 0;

  G_LOCK (idle);

  if (!no_idle_exit)
    {
      if (idle_timeout_id != 0)
        g_source_remove (idle_timeout_id);

      idle_timeout_id = g_timeout_add_seconds (IDLE_TIMEOUT_SECS, idle_timeout_cb, NULL);
    }

  G_UNLOCK (idle);
}

static FlatpakDir *
dir_get_system (const char             *installation,
                GDBusMethodInvocation  *invocation,
                gboolean                no_interaction,
                GError                **error)
{
  FlatpakDir *system = NULL;
  const char *sender;
  g_autoptr(AutoPolkitSubject) subject = NULL;

  if (installation != NULL && *installation != '\0')
    system = flatpak_dir_get_system_by_id (installation, NULL, error);
  else
    system = flatpak_dir_get_system_default ();

  /* This can happen in case of error with flatpak_dir_get_system_by_id(). */
  if (system == NULL)
    return NULL;

  sender = g_dbus_method_invocation_get_sender (invocation);
  subject = polkit_system_bus_name_new (sender);

  flatpak_dir_set_subject (system, subject);
  flatpak_dir_set_no_system_helper (system, TRUE);
  flatpak_dir_set_no_interaction (system, no_interaction);

  return system;
}

static void
flatpak_invocation_return_error (GDBusMethodInvocation *invocation,
                                 GError                *error,
                                 const char            *fmt,
                                 ...) G_GNUC_PRINTF (3, 4);

static void
flatpak_invocation_return_error (GDBusMethodInvocation *invocation,
                                 GError                *error,
                                 const char            *fmt,
                                 ...)
{
  if (error->domain == FLATPAK_ERROR)
    g_dbus_method_invocation_return_gerror (invocation, error);
  else
    {
      va_list args;
      g_autofree char *prefix = NULL;
      va_start (args, fmt);
      g_vasprintf (&prefix, fmt, args);
      va_end (args);
      g_dbus_method_invocation_return_error (invocation,
                                             G_DBUS_ERROR, G_DBUS_ERROR_FAILED,
                                             "%s: %s", prefix, error->message);
    }
}

static gboolean
get_connection_uid (GDBusMethodInvocation *invocation, uid_t *out_uid, GError **error)
{
  GDBusConnection *connection = g_dbus_method_invocation_get_connection (invocation);
  const gchar *sender = g_dbus_method_invocation_get_sender (invocation);
  g_autoptr(GVariant) dict = NULL;
  g_autoptr(GVariant) credentials = NULL;

  credentials = g_dbus_connection_call_sync (connection,
                                             "org.freedesktop.DBus",
                                             "/org/freedesktop/DBus",
                                             "org.freedesktop.DBus",
                                             "GetConnectionCredentials",
                                             g_variant_new ("(s)", sender),
                                             G_VARIANT_TYPE ("(a{sv})"), G_DBUS_CALL_FLAGS_NONE,
                                             G_MAXINT, NULL, error);
  if (credentials == NULL)
    return FALSE;

  dict = g_variant_get_child_value (credentials, 0);

   if (!g_variant_lookup (dict, "UnixUserID", "u", out_uid))
    {
      g_set_error (error, G_DBUS_ERROR, G_DBUS_ERROR_FAILED,
                   "Failed to query UnixUserID for the bus name: %s", sender);
      return FALSE;
    }

  return TRUE;
}

static OngoingPull *
take_ongoing_pull_by_dir (const char *src_dir,
                          uid_t       uid)
{
  OngoingPull *pull = NULL;
  char *cache_dir_name = NULL;

  G_LOCK (cache_dirs_in_use);
  if (g_hash_table_steal_extended (cache_dirs_in_use, src_dir,
                                   (gpointer) &cache_dir_name,
                                   (gpointer) &pull))
    {
      if (pull && pull->uid == uid)
        {
          /* Keep src_dir key inside hashtable but remove its OngoingPull
           * value and set it to NULL. This way src_dir is still marked
           * as in-use (as Deploy or CancelPull might be executing on it,
           * whereas OngoingPull ownership is transferred to respective
           * callers. */
          g_hash_table_insert (cache_dirs_in_use, cache_dir_name, NULL);
        }
      else
        {
          /* Otherwise, re-insert what is currently there and return NULL */
          g_hash_table_insert (cache_dirs_in_use, cache_dir_name, pull);
          pull = NULL;
        }
    }
  G_UNLOCK (cache_dirs_in_use);

  return pull;
}

static gboolean
handle_deploy (FlatpakSystemHelper   *object,
               GDBusMethodInvocation *invocation,
               const gchar           *arg_repo_path,
               guint32                arg_flags,
               const gchar           *arg_ref,
               const gchar           *arg_origin,
               const gchar *const    *arg_subpaths,
               const gchar *const    *arg_previous_ids,
               const gchar           *arg_installation)
{
  g_autoptr(FlatpakDir) system = NULL;
  g_autoptr(GFile) repo_file = g_file_new_for_path (arg_repo_path);
  g_autoptr(GError) error = NULL;
  g_autoptr(GFile) deploy_dir = NULL;
  gboolean is_oci;
  gboolean is_update;
  gboolean no_deploy;
  gboolean local_pull;
  gboolean reinstall;
  gboolean update_pinned;
  gboolean update_preinstalled;
  g_autofree char *url = NULL;
  g_autoptr(OngoingPull) ongoing_pull = NULL;
  g_autofree gchar *src_dir = NULL;
  g_autoptr(FlatpakDecomposed) ref = NULL;

  g_info ("Deploy %s %u %s %s %s", arg_repo_path, arg_flags, arg_ref, arg_origin, arg_installation);

  system = dir_get_system (arg_installation, invocation, (arg_flags & FLATPAK_HELPER_DEPLOY_FLAGS_NO_INTERACTION) != 0, &error);
  if (system == NULL)
    {
      g_dbus_method_invocation_return_gerror (invocation, error);
      return G_DBUS_METHOD_INVOCATION_HANDLED;
    }

  if ((arg_flags & ~FLATPAK_HELPER_DEPLOY_FLAGS_ALL) != 0)
    {
      g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS,
                                             "Unsupported flags enabled: 0x%x", (arg_flags & ~FLATPAK_HELPER_DEPLOY_FLAGS_ALL));
      return G_DBUS_METHOD_INVOCATION_HANDLED;
    }

  if (strlen (arg_repo_path) > 0)
    {
      g_autoptr(GError) local_error = NULL;
      uid_t uid;

      if (!g_file_query_exists (repo_file, NULL))
        {
          g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS,
                                                 "Path does not exist");
          return G_DBUS_METHOD_INVOCATION_HANDLED;
        }

      /* Ensure that pull's uid is same as the caller's uid */
      if (!get_connection_uid (invocation, &uid, &local_error))
        {
          g_dbus_method_invocation_return_gerror (invocation, local_error);
          return G_DBUS_METHOD_INVOCATION_HANDLED;
        }

      src_dir = g_path_get_dirname (arg_repo_path);
      ongoing_pull = take_ongoing_pull_by_dir (src_dir, uid);
      if (ongoing_pull != NULL)
        {
          terminate_revokefs_backend (ongoing_pull);

          if (!flatpak_canonicalize_permissions (AT_FDCWD,
                                                 arg_repo_path,
                                                 getuid() == 0 ? 0 : -1,
                                                 getuid() == 0 ? 0 : -1,
                                                 &local_error))
            {
              g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_FAILED,
                                                     "Failed to canonicalize permissions of repo %s: %s",
                                                     arg_repo_path, local_error->message);
              return G_DBUS_METHOD_INVOCATION_HANDLED;
            }

          /* At this point, the cache-dir's repo is owned by root. Hence, any failure
           * from here on, should always cleanup the cache-dir and not preserve it to be reused. */
          ongoing_pull->preserve_pull = FALSE;
        }
    }

  ref = flatpak_decomposed_new_from_ref (arg_ref, &error);
  if (ref == NULL)
    {
      g_dbus_method_invocation_return_gerror (invocation, error);
      return G_DBUS_METHOD_INVOCATION_HANDLED;
    }

  no_deploy = (arg_flags & FLATPAK_HELPER_DEPLOY_FLAGS_NO_DEPLOY) != 0;
  local_pull = (arg_flags & FLATPAK_HELPER_DEPLOY_FLAGS_LOCAL_PULL) != 0;
  reinstall = (arg_flags & FLATPAK_HELPER_DEPLOY_FLAGS_REINSTALL) != 0;
  update_pinned = (arg_flags & FLATPAK_HELPER_DEPLOY_FLAGS_UPDATE_PINNED) != 0;
  update_preinstalled = (arg_flags & FLATPAK_HELPER_DEPLOY_FLAGS_UPDATE_PREINSTALLED) != 0;

  deploy_dir = flatpak_dir_get_if_deployed (system, ref, NULL, NULL);

  is_update = (deploy_dir && !reinstall);
  if (is_update)
    {
      g_autofree char *real_origin = NULL;
      real_origin = flatpak_dir_get_origin (system, ref, NULL, NULL);
      if (g_strcmp0 (real_origin, arg_origin) != 0)
        {
          g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS,
                                                 "Wrong origin %s for update", arg_origin);
          return G_DBUS_METHOD_INVOCATION_HANDLED;
        }
    }

  if (!flatpak_dir_ensure_repo (system, NULL, &error))
    {
      flatpak_invocation_return_error (invocation, error, "Can't open system repo %s", arg_installation);
      return G_DBUS_METHOD_INVOCATION_HANDLED;
    }

  is_oci = flatpak_dir_get_remote_oci (system, arg_origin);

  if (is_update && !is_oci)
    {
      /* Take this opportunity to clean up refs/mirrors/ since a prune will happen
       * after this update operation. See
       * https://github.com/flatpak/flatpak/issues/3222
       */
      if (!flatpak_dir_delete_mirror_refs (system, FALSE, NULL, &error))
        {
          flatpak_invocation_return_error (invocation, error, "Can't delete mirror refs");
          return G_DBUS_METHOD_INVOCATION_HANDLED;
        }
    }

  if (strlen (arg_repo_path) > 0 && is_oci)
    {
      g_autoptr(GFile) registry_file = g_file_new_for_path (arg_repo_path);
      g_autoptr(FlatpakImageSource) image_source = NULL;
      g_autoptr(FlatpakRemoteState) state = NULL;
      g_autoptr(GHashTable) remote_refs = NULL;
      g_autofree char *checksum = NULL;
      const char *image_source_digest;
      const char *verified_digest;
      g_autofree char *upstream_url = NULL;
      g_autoptr(FlatpakImageSource) system_image_source = NULL;

      if (!ostree_repo_remote_get_url (flatpak_dir_get_repo (system),
                                       arg_origin,
                                       &upstream_url,
                                       &error))
        {
          flatpak_invocation_return_error (invocation, error, "Unable to get the URL for remote %s", arg_origin);
          return G_DBUS_METHOD_INVOCATION_HANDLED;
        }

      image_source = flatpak_image_source_new_local (registry_file, arg_ref, NULL, &error);
      if (image_source == NULL)
        {
          g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_FAILED,
                                                 "Can't open child OCI registry: %s", error->message);
          return G_DBUS_METHOD_INVOCATION_HANDLED;
        }

      state = flatpak_dir_get_remote_state (system, arg_origin, FALSE, NULL, &error);
      if (state == NULL)
        {
          g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_FAILED,
                                                 "%s: Can't get remote state: %s", arg_origin, error->message);
          return G_DBUS_METHOD_INVOCATION_HANDLED;
        }

      /* We need to use list_all_remote_refs because we don't care about
       * enumerate vs. noenumerate.
       */
      if (!flatpak_dir_list_all_remote_refs (system, state, &remote_refs, NULL, &error))
        {
          g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_FAILED,
                                                 "%s: Can't list refs: %s", arg_origin, error->message);
          return G_DBUS_METHOD_INVOCATION_HANDLED;
        }

      verified_digest = g_hash_table_lookup (remote_refs, ref);
      if (!verified_digest)
        {
          g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_FAILED,
                                                 "%s: ref %s not found", arg_origin, arg_ref);
          return G_DBUS_METHOD_INVOCATION_HANDLED;
        }

      image_source_digest = flatpak_image_source_get_digest (image_source);

      if (!g_str_has_prefix (image_source_digest, "sha256:") ||
          strcmp (image_source_digest + strlen ("sha256:"), verified_digest) != 0)
        {
          g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_FAILED,
                                                 "%s: manifest hash in downloaded content does not match ref %s", arg_origin, arg_ref);
          return G_DBUS_METHOD_INVOCATION_HANDLED;
        }

      system_image_source =
        flatpak_remote_state_fetch_image_source (state,
                                                 system,
                                                 arg_ref,
                                                 verified_digest,
                                                 NULL,
                                                 NULL, &error);
      if (!system_image_source)
        {
          g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_FAILED,
                                                 "Can't fetch image source: %s", error->message);
          return G_DBUS_METHOD_INVOCATION_HANDLED;
        }

      checksum = flatpak_pull_from_oci (flatpak_dir_get_repo (system), image_source, system_image_source,
                                        arg_origin, arg_ref, FLATPAK_PULL_FLAGS_NONE, NULL, NULL, NULL, &error);
      if (checksum == NULL)
        {
          g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_FAILED,
                                                 "Can't pull ref %s from child OCI registry index: %s", arg_ref, error->message);
          return G_DBUS_METHOD_INVOCATION_HANDLED;
        }

      if (!flatpak_dir_pull_oci_extra_data (flatpak_dir_get_repo (system), image_source,
                                            checksum, NULL, &error))
        {
          g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_FAILED,
                                                 "Can't pull extra data for ref %s from child OCI registry index: %s",
                                                 arg_ref, error->message);
          return G_DBUS_METHOD_INVOCATION_HANDLED;
        }
    }
  else if (strlen (arg_repo_path) > 0)
    {
      if (!flatpak_dir_pull_untrusted_local (system, arg_repo_path,
                                             arg_origin,
                                             arg_ref,
                                             (const char **) arg_subpaths,
                                             NULL, NULL, &error))
        {
          flatpak_invocation_return_error (invocation, error, "Error pulling from repo");
          return G_DBUS_METHOD_INVOCATION_HANDLED;
        }
    }
  else if (local_pull)
    {
      g_autoptr(FlatpakRemoteState) state = NULL;
      if (!ostree_repo_remote_get_url (flatpak_dir_get_repo (system),
                                       arg_origin,
                                       &url,
                                       &error))
        {
          flatpak_invocation_return_error (invocation, error, "Unable to get the URL for remote %s", arg_origin);
          return G_DBUS_METHOD_INVOCATION_HANDLED;
        }

      if (!g_str_has_prefix (url, "file:"))
        {
          g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_FAILED,
                                                 "Local pull url doesn't start with file://");
          return G_DBUS_METHOD_INVOCATION_HANDLED;
        }

      state = flatpak_dir_get_remote_state_optional (system, arg_origin, FALSE, NULL, &error);
      if (state == NULL)
        {
          flatpak_invocation_return_error (invocation, error, "Error getting remote state");
          return G_DBUS_METHOD_INVOCATION_HANDLED;
        }

      if (!flatpak_dir_pull (system, state, arg_ref, NULL, (const char **) arg_subpaths, NULL, NULL, NULL, NULL, NULL,
                             FLATPAK_PULL_FLAGS_NONE, OSTREE_REPO_PULL_FLAGS_UNTRUSTED, NULL,
                             NULL, &error))
        {
          flatpak_invocation_return_error (invocation, error, "Error pulling from repo");
          return G_DBUS_METHOD_INVOCATION_HANDLED;
        }
    }

  if (!no_deploy)
    {
      if (deploy_dir && !reinstall)
        {
          if (!flatpak_dir_deploy_update (system, ref, NULL,
                                          (const char **) arg_subpaths,
                                          (const char **) arg_previous_ids,
                                          NULL, &error))
            {
              flatpak_invocation_return_error (invocation, error, "Error deploying");
              return G_DBUS_METHOD_INVOCATION_HANDLED;
            }
        }
      else
        {
          if (!flatpak_dir_deploy_install (system, ref, arg_origin,
                                           (const char **) arg_subpaths,
                                           (const char **) arg_previous_ids,
                                           reinstall, update_pinned, update_preinstalled,
                                           NULL, &error))
            {
              flatpak_invocation_return_error (invocation, error, "Error deploying");
              return G_DBUS_METHOD_INVOCATION_HANDLED;
            }
        }
    }

  flatpak_system_helper_complete_deploy (object, invocation);

  return G_DBUS_METHOD_INVOCATION_HANDLED;
}

static gboolean
handle_cancel_pull (FlatpakSystemHelper   *object,
                    GDBusMethodInvocation *invocation,
                    guint                  arg_flags,
                    const gchar           *arg_installation,
                    const gchar           *arg_src_dir)
{
  OngoingPull *ongoing_pull;
  g_autoptr(FlatpakDir) system = NULL;
  g_autoptr(GError) error = NULL;
  uid_t uid;

  g_info ("CancelPull %s %u %s", arg_installation, arg_flags, arg_src_dir);

  system = dir_get_system (arg_installation, invocation, (arg_flags & FLATPAK_HELPER_CANCEL_PULL_FLAGS_NO_INTERACTION) != 0, &error);
  if (system == NULL)
    {
      g_dbus_method_invocation_return_gerror (invocation, error);
      return G_DBUS_METHOD_INVOCATION_HANDLED;
    }

  if (!get_connection_uid (invocation, &uid, &error))
    {
      g_dbus_method_invocation_return_gerror (invocation, error);
      return G_DBUS_METHOD_INVOCATION_HANDLED;
    }

  ongoing_pull = take_ongoing_pull_by_dir (arg_src_dir, uid);
  if (ongoing_pull == NULL)
    {
      g_set_error (&error, G_DBUS_ERROR, G_DBUS_ERROR_FAILED,
                   "Cannot find ongoing pull to cancel at %s", arg_src_dir);
      g_dbus_method_invocation_return_gerror (invocation, error);
      return G_DBUS_METHOD_INVOCATION_HANDLED;
    }

  ongoing_pull->preserve_pull = (arg_flags & FLATPAK_HELPER_CANCEL_PULL_FLAGS_PRESERVE_PULL) != 0;
  ongoing_pull_free (ongoing_pull);

  flatpak_system_helper_complete_cancel_pull (object, invocation);
  return G_DBUS_METHOD_INVOCATION_HANDLED;
}

static gboolean
handle_deploy_appstream (FlatpakSystemHelper   *object,
                         GDBusMethodInvocation *invocation,
                         const gchar           *arg_repo_path,
                         guint                  arg_flags,
                         const gchar           *arg_origin,
                         const gchar           *arg_arch,
                         const gchar           *arg_installation)
{
  g_autoptr(FlatpakDir) system = NULL;
  g_autoptr(GError) error = NULL;
  g_autofree char *new_branch = NULL;
  g_autofree char *old_branch = NULL;
  g_autofree char *subset = NULL;
  gboolean is_oci;

  g_info ("DeployAppstream %s %u %s %s %s", arg_repo_path, arg_flags, arg_origin, arg_arch, arg_installation);

  system = dir_get_system (arg_installation, invocation, (arg_flags & FLATPAK_HELPER_DEPLOY_APPSTREAM_FLAGS_NO_INTERACTION) != 0, &error);
  if (system == NULL)
    {
      g_dbus_method_invocation_return_gerror (invocation, error);
      return G_DBUS_METHOD_INVOCATION_HANDLED;
    }

  if (strlen (arg_repo_path) > 0)
    {
      g_autoptr(GFile) repo_file = g_file_new_for_path (arg_repo_path);
      if (!g_file_query_exists (repo_file, NULL))
        {
          g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS,
                                                 "Path does not exist");
          return G_DBUS_METHOD_INVOCATION_HANDLED;
        }
    }

  if (!flatpak_dir_ensure_repo (system, NULL, &error))
    {
      g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_FAILED,
                                             "Can't open system repo %s", error->message);
      return G_DBUS_METHOD_INVOCATION_HANDLED;
    }

  is_oci = flatpak_dir_get_remote_oci (system, arg_origin);

  subset = flatpak_dir_get_remote_subset (system, arg_origin);

  if (subset)
    {
      new_branch = g_strdup_printf ("appstream2/%s-%s", subset, arg_arch);
      old_branch = g_strdup_printf ("appstream/%s-%s", subset, arg_arch);
    }
  else
    {
      new_branch = g_strdup_printf ("appstream2/%s", arg_arch);
      old_branch = g_strdup_printf ("appstream/%s", arg_arch);
    }

  if (is_oci)
    {
      g_auto(FlatpakMainContext) context = FLATKPAK_MAIN_CONTEXT_INIT;

      /* This does http requests spinning the current mainloop, so we need one
         for this thread. */
      flatpak_progress_init_main_context (NULL, &context);
      /* In the OCI case, we just do the full update, including network i/o, in the
       * system helper, see comment in flatpak_dir_update_appstream()
       */
      if (!flatpak_dir_update_appstream (system,
                                         arg_origin,
                                         arg_arch,
                                         NULL,
                                         NULL,
                                         NULL,
                                         &error))
        {
          flatpak_invocation_return_error (invocation, error, "Error updating appstream");
          return G_DBUS_METHOD_INVOCATION_HANDLED;
        }

      flatpak_system_helper_complete_deploy_appstream (object, invocation);
      return G_DBUS_METHOD_INVOCATION_HANDLED;
    }
  else if (strlen (arg_repo_path) > 0)
    {
      g_autoptr(GError) first_error = NULL;
      g_autoptr(GError) second_error = NULL;

      if (!flatpak_dir_pull_untrusted_local (system, arg_repo_path,
                                             arg_origin,
                                             new_branch,
                                             NULL,
                                             NULL,
                                             NULL, &first_error))
        {
          if (!flatpak_dir_pull_untrusted_local (system, arg_repo_path,
                                                 arg_origin,
                                                 old_branch,
                                                 NULL,
                                                 NULL,
                                                 NULL, &second_error))
            {
              g_prefix_error (&first_error, "Error updating appstream2: ");
              g_prefix_error (&second_error, "%s; Error updating appstream: ", first_error->message);
              g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_FAILED,
                                                     "Error pulling from repo: %s", second_error->message);
              return G_DBUS_METHOD_INVOCATION_HANDLED;
            }
        }
    }
  else /* empty path == local pull */
    {
      g_autoptr(FlatpakRemoteState) state = NULL;
      g_autoptr(GError) first_error = NULL;
      g_autoptr(GError) second_error = NULL;
      g_autofree char *url = NULL;

      if (!ostree_repo_remote_get_url (flatpak_dir_get_repo (system),
                                       arg_origin,
                                       &url,
                                       &error))
        {
          flatpak_invocation_return_error (invocation, error, "Unable to get the URL for remote %s", arg_origin);
          return G_DBUS_METHOD_INVOCATION_HANDLED;
        }

      if (!g_str_has_prefix (url, "file:"))
        {
          g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_FAILED,
                                                 "Local pull url doesn't start with file://");
          return G_DBUS_METHOD_INVOCATION_HANDLED;
        }

      state = flatpak_dir_get_remote_state_optional (system, arg_origin, FALSE, NULL, &error);
      if (state == NULL)
        {
          flatpak_invocation_return_error (invocation, error, "Error getting remote state");
          return G_DBUS_METHOD_INVOCATION_HANDLED;
        }

      if (!flatpak_dir_pull (system, state, new_branch, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
                             FLATPAK_PULL_FLAGS_NONE, OSTREE_REPO_PULL_FLAGS_UNTRUSTED, NULL,
                             NULL, &first_error))
        {
          if (!flatpak_dir_pull (system, state, old_branch, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
                                 FLATPAK_PULL_FLAGS_NONE, OSTREE_REPO_PULL_FLAGS_UNTRUSTED, NULL,
                                 NULL, &second_error))
            {
              g_prefix_error (&first_error, "Error updating appstream2: ");
              g_prefix_error (&second_error, "%s; Error updating appstream: ", first_error->message);
              g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_FAILED,
                                                     "Error pulling from repo: %s", second_error->message);
              return G_DBUS_METHOD_INVOCATION_HANDLED;
            }
        }
    }

  if (!flatpak_dir_deploy_appstream (system,
                                     arg_origin,
                                     arg_arch,
                                     NULL,
                                     NULL,
                                     &error))
    {
      flatpak_invocation_return_error (invocation, error, "Error deploying appstream");
      return G_DBUS_METHOD_INVOCATION_HANDLED;
    }

  flatpak_system_helper_complete_deploy_appstream (object, invocation);

  return G_DBUS_METHOD_INVOCATION_HANDLED;
}

static gboolean
handle_uninstall (FlatpakSystemHelper   *object,
                  GDBusMethodInvocation *invocation,
                  guint                  arg_flags,
                  const gchar           *arg_ref,
                  const gchar           *arg_installation)
{
  g_autoptr(FlatpakDir) system = NULL;
  g_autoptr(GError) error = NULL;
  g_autoptr(FlatpakDecomposed) ref = NULL;

  g_info ("Uninstall %u %s %s", arg_flags, arg_ref, arg_installation);

  system = dir_get_system (arg_installation, invocation, (arg_flags & FLATPAK_HELPER_UNINSTALL_FLAGS_NO_INTERACTION) != 0, &error);
  if (system == NULL)
    {
      g_dbus_method_invocation_return_gerror (invocation, error);
      return G_DBUS_METHOD_INVOCATION_HANDLED;
    }

  ref = flatpak_decomposed_new_from_ref (arg_ref, &error);
  if (ref == NULL)
    {
      g_dbus_method_invocation_return_gerror (invocation, error);
      return G_DBUS_METHOD_INVOCATION_HANDLED;
    }

  if ((arg_flags & ~FLATPAK_HELPER_UNINSTALL_FLAGS_ALL) != 0)
    {
      g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS,
                                             "Unsupported flags enabled: 0x%x", (arg_flags & ~FLATPAK_HELPER_UNINSTALL_FLAGS_ALL));
      return G_DBUS_METHOD_INVOCATION_HANDLED;
    }

  if (!flatpak_dir_ensure_repo (system, NULL, &error))
    {
      g_dbus_method_invocation_return_gerror (invocation, error);
      return G_DBUS_METHOD_INVOCATION_HANDLED;
    }

  if (!flatpak_dir_uninstall (system, ref, arg_flags, NULL, &error))
    {
      flatpak_invocation_return_error (invocation, error, "Error uninstalling");
      return G_DBUS_METHOD_INVOCATION_HANDLED;
    }

  flatpak_system_helper_complete_uninstall (object, invocation);

  return G_DBUS_METHOD_INVOCATION_HANDLED;
}

static gboolean
handle_install_bundle (FlatpakSystemHelper   *object,
                       GDBusMethodInvocation *invocation,
                       const gchar           *arg_bundle_path,
                       guint32                arg_flags,
                       const gchar           *arg_remote,
                       const gchar           *arg_installation)
{
  g_autoptr(FlatpakDir) system = NULL;
  g_autoptr(GFile) bundle_file = g_file_new_for_path (arg_bundle_path);
  g_autoptr(GError) error = NULL;
  g_autoptr(FlatpakDecomposed) ref = NULL;
  gboolean reinstall;

  g_info ("InstallBundle %s %u %s %s", arg_bundle_path, arg_flags, arg_remote, arg_installation);

  system = dir_get_system (arg_installation, invocation, (arg_flags & FLATPAK_HELPER_INSTALL_BUNDLE_FLAGS_NO_INTERACTION) != 0, &error);
  if (system == NULL)
    {
      g_dbus_method_invocation_return_gerror (invocation, error);
      return G_DBUS_METHOD_INVOCATION_HANDLED;
    }

  if ((arg_flags & ~FLATPAK_HELPER_INSTALL_BUNDLE_FLAGS_ALL) != 0)
    {
      g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS,
                                             "Unsupported flags enabled: 0x%x", (arg_flags & ~FLATPAK_HELPER_INSTALL_BUNDLE_FLAGS_ALL));
      return G_DBUS_METHOD_INVOCATION_HANDLED;
    }

  if (!g_file_query_exists (bundle_file, NULL))
    {
      g_dbus_method_invocation_return_error (invocation, G_IO_ERROR, G_IO_ERROR_NOT_FOUND,
                                             "Bundle %s does not exist", arg_bundle_path);
      return G_DBUS_METHOD_INVOCATION_HANDLED;
    }

  reinstall = (arg_flags & FLATPAK_HELPER_INSTALL_BUNDLE_FLAGS_REINSTALL) != 0;
  if (!flatpak_dir_install_bundle (system, reinstall, bundle_file, arg_remote, &ref, NULL, &error))
    {
      flatpak_invocation_return_error (invocation, error, "Error installing bundle");
      return G_DBUS_METHOD_INVOCATION_HANDLED;
    }

  flatpak_system_helper_complete_install_bundle (object, invocation, flatpak_decomposed_get_ref (ref));

  return G_DBUS_METHOD_INVOCATION_HANDLED;
}


static gboolean
handle_configure_remote (FlatpakSystemHelper   *object,
                         GDBusMethodInvocation *invocation,
                         guint                  arg_flags,
                         const gchar           *arg_remote,
                         const gchar           *arg_config,
                         GVariant              *arg_gpg_key,
                         const gchar           *arg_installation)
{
  g_autoptr(FlatpakDir) system = NULL;
  g_autoptr(GError) error = NULL;
  g_autoptr(GKeyFile) config = g_key_file_new ();
  g_autofree char *group = g_strdup_printf ("remote \"%s\"", arg_remote);
  g_autoptr(GBytes) gpg_data = NULL;
  gboolean force_remove;

  g_info ("ConfigureRemote %u %s %s", arg_flags, arg_remote, arg_installation);

  system = dir_get_system (arg_installation, invocation, (arg_flags & FLATPAK_HELPER_CONFIGURE_REMOTE_FLAGS_NO_INTERACTION) != 0, &error);
  if (system == NULL)
    {
      g_dbus_method_invocation_return_gerror (invocation, error);
      return G_DBUS_METHOD_INVOCATION_HANDLED;
    }

  if (*arg_remote == 0 || strchr (arg_remote, '/') != NULL)
    {
      g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS,
                                             "Invalid remote name: %s", arg_remote);
      return G_DBUS_METHOD_INVOCATION_HANDLED;
    }

  if ((arg_flags & ~FLATPAK_HELPER_CONFIGURE_REMOTE_FLAGS_ALL) != 0)
    {
      g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS,
                                             "Unsupported flags enabled: 0x%x", (arg_flags & ~FLATPAK_HELPER_CONFIGURE_REMOTE_FLAGS_ALL));
      return G_DBUS_METHOD_INVOCATION_HANDLED;
    }

  if (!g_key_file_load_from_data (config, arg_config, strlen (arg_config),
                                  G_KEY_FILE_NONE, &error))
    {
      g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS,
                                             "Invalid config: %s\n", error->message);
      return G_DBUS_METHOD_INVOCATION_HANDLED;
    }

  if (!flatpak_dir_ensure_repo (system, NULL, &error))
    {
      g_dbus_method_invocation_return_gerror (invocation, error);
      return G_DBUS_METHOD_INVOCATION_HANDLED;
    }

  if (g_variant_get_size (arg_gpg_key) > 0)
    gpg_data = g_variant_get_data_as_bytes (arg_gpg_key);

  force_remove = (arg_flags & FLATPAK_HELPER_CONFIGURE_REMOTE_FLAGS_FORCE_REMOVE) != 0;

  if (g_key_file_has_group (config, group))
    {
      if (!flatpak_dir_modify_remote (system, arg_remote, config, gpg_data, NULL, &error))
        {
          flatpak_invocation_return_error (invocation, error, "Error modifying remote");
          return G_DBUS_METHOD_INVOCATION_HANDLED;
        }
    }
  else
    {
      if (!flatpak_dir_remove_remote (system, force_remove, arg_remote, NULL, &error))
        {
          flatpak_invocation_return_error (invocation, error, "Error removing remote");
          return G_DBUS_METHOD_INVOCATION_HANDLED;
        }
    }

  flatpak_system_helper_complete_configure_remote (object, invocation);

  return G_DBUS_METHOD_INVOCATION_HANDLED;
}

static gboolean
handle_configure (FlatpakSystemHelper   *object,
                  GDBusMethodInvocation *invocation,
                  guint                  arg_flags,
                  const gchar           *arg_key,
                  const gchar           *arg_value,
                  const gchar           *arg_installation)
{
  g_autoptr(FlatpakDir) system = NULL;
  g_autoptr(GError) error = NULL;

  g_info ("Configure %u %s=%s %s", arg_flags, arg_key, arg_value, arg_installation);

  system = dir_get_system (arg_installation, invocation, (arg_flags & FLATPAK_HELPER_CONFIGURE_FLAGS_NO_INTERACTION) != 0, &error);
  if (system == NULL)
    {
      g_dbus_method_invocation_return_gerror (invocation, error);
      return G_DBUS_METHOD_INVOCATION_HANDLED;
    }

  if ((arg_flags & ~FLATPAK_HELPER_CONFIGURE_FLAGS_ALL) != 0)
    {
      g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS,
                                             "Unsupported flags enabled: 0x%x", (arg_flags & ~FLATPAK_HELPER_CONFIGURE_FLAGS_ALL));
      return G_DBUS_METHOD_INVOCATION_HANDLED;
    }

  if ((strcmp (arg_key, "languages") != 0) &&
      (strcmp (arg_key, "extra-languages") != 0) &&
      (strcmp (arg_key, "masked") != 0) &&
      (strcmp (arg_key, "pinned") != 0))
    {
      g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS,
                                             "Unsupported key: %s", arg_key);
      return G_DBUS_METHOD_INVOCATION_HANDLED;
    }

  if ((arg_flags & FLATPAK_HELPER_CONFIGURE_FLAGS_UNSET) != 0)
    arg_value = NULL;

  if (!flatpak_dir_ensure_repo (system, NULL, &error))
    {
      g_dbus_method_invocation_return_gerror (invocation, error);
      return G_DBUS_METHOD_INVOCATION_HANDLED;
    }

  if (!flatpak_dir_set_config (system, arg_key, arg_value, &error))
    {
      flatpak_invocation_return_error (invocation, error, "Error setting config");
      return G_DBUS_METHOD_INVOCATION_HANDLED;
    }

  flatpak_system_helper_complete_configure (object, invocation);

  return G_DBUS_METHOD_INVOCATION_HANDLED;
}

static gboolean
handle_update_remote (FlatpakSystemHelper   *object,
                      GDBusMethodInvocation *invocation,
                      guint                  arg_flags,
                      const gchar           *arg_remote,
                      const gchar           *arg_installation,
                      const gchar           *arg_summary_path,
                      const gchar           *arg_summary_sig_path)
{
  g_autoptr(FlatpakDir) system = NULL;
  g_autoptr(GError) error = NULL;
  char *summary_data = NULL;
  gsize summary_size;
  g_autoptr(GBytes) summary_bytes = NULL;
  char *summary_sig_data = NULL;
  gsize summary_sig_size;
  g_autoptr(GBytes) summary_sig_bytes = NULL;
  g_autoptr(FlatpakRemoteState) state = NULL;
  gboolean summary_is_index = (arg_flags & FLATPAK_HELPER_UPDATE_REMOTE_FLAGS_SUMMARY_IS_INDEX) != 0;

  g_info ("UpdateRemote %u %s %s %s %s", arg_flags, arg_remote, arg_installation, arg_summary_path, arg_summary_sig_path);

  system = dir_get_system (arg_installation, invocation, (arg_flags & FLATPAK_HELPER_UPDATE_REMOTE_FLAGS_NO_INTERACTION) != 0, &error);
  if (system == NULL)
    {
      g_dbus_method_invocation_return_gerror (invocation, error);
      return G_DBUS_METHOD_INVOCATION_HANDLED;
    }

  if (*arg_remote == 0 || strchr (arg_remote, '/') != NULL)
    {
      g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS,
                                             "Invalid remote name: %s", arg_remote);
      return G_DBUS_METHOD_INVOCATION_HANDLED;
    }

  if ((arg_flags & ~FLATPAK_HELPER_UPDATE_REMOTE_FLAGS_ALL) != 0)
    {
      g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS,
                                             "Unsupported flags enabled: 0x%x", (arg_flags & ~FLATPAK_HELPER_UPDATE_REMOTE_FLAGS_ALL));
      return G_DBUS_METHOD_INVOCATION_HANDLED;
    }

  if (!g_file_get_contents (arg_summary_path, &summary_data, &summary_size, &error))
    {
      g_dbus_method_invocation_return_gerror (invocation, error);
      return G_DBUS_METHOD_INVOCATION_HANDLED;
    }
  summary_bytes = g_bytes_new_take (summary_data, summary_size);

  if (*arg_summary_sig_path != 0)
    {
      if (!g_file_get_contents (arg_summary_sig_path, &summary_sig_data, &summary_sig_size, &error))
        {
          g_dbus_method_invocation_return_gerror (invocation, error);
          return G_DBUS_METHOD_INVOCATION_HANDLED;
        }
      summary_sig_bytes = g_bytes_new_take (summary_sig_data, summary_sig_size);
    }

  if (summary_is_index)
    state = flatpak_dir_get_remote_state_for_index (system, arg_remote, summary_bytes, summary_sig_bytes, NULL, &error);
  else
    state = flatpak_dir_get_remote_state_for_summary (system, arg_remote, summary_bytes, summary_sig_bytes, NULL, &error);
  if (state == NULL)
    {
      flatpak_invocation_return_error (invocation, error, "Error getting remote state");
      return G_DBUS_METHOD_INVOCATION_HANDLED;
    }

  if (summary_sig_bytes == NULL)
    {
      g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS,
                                             "UpdateRemote requires a summary signature");
      return G_DBUS_METHOD_INVOCATION_HANDLED;
    }

  if (!flatpak_dir_update_remote_configuration_for_state (system, state, FALSE, NULL, NULL, &error))
    {
      flatpak_invocation_return_error (invocation, error, "Error updating remote config");
      return G_DBUS_METHOD_INVOCATION_HANDLED;
    }

  flatpak_system_helper_complete_update_remote (object, invocation);

  return G_DBUS_METHOD_INVOCATION_HANDLED;
}

static gboolean
handle_remove_local_ref (FlatpakSystemHelper   *object,
                         GDBusMethodInvocation *invocation,
                         guint                  arg_flags,
                         const gchar           *arg_remote,
                         const gchar           *arg_ref,
                         const gchar           *arg_installation)
{
  g_autoptr(FlatpakDir) system = NULL;
  g_autoptr(GError) error = NULL;

  g_info ("RemoveLocalRef %u %s %s %s", arg_flags, arg_remote, arg_ref, arg_installation);

  system = dir_get_system (arg_installation, invocation, (arg_flags & FLATPAK_HELPER_REMOVE_LOCAL_REF_FLAGS_NO_INTERACTION) != 0, &error);
  if (system == NULL)
    {
      g_dbus_method_invocation_return_gerror (invocation, error);
      return G_DBUS_METHOD_INVOCATION_HANDLED;
    }

  if ((arg_flags & ~FLATPAK_HELPER_REMOVE_LOCAL_REF_FLAGS_ALL) != 0)
    {
      g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS,
                                             "Unsupported flags enabled: 0x%x", (arg_flags & ~FLATPAK_HELPER_REMOVE_LOCAL_REF_FLAGS_ALL));
      return G_DBUS_METHOD_INVOCATION_HANDLED;
    }

  if (*arg_remote == 0 || strchr (arg_remote, '/') != NULL)
    {
      g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS,
                                             "Invalid remote name: %s", arg_remote);
      return G_DBUS_METHOD_INVOCATION_HANDLED;
    }

  if (!flatpak_dir_ensure_repo (system, NULL, &error))
    {
      g_dbus_method_invocation_return_gerror (invocation, error);
      return G_DBUS_METHOD_INVOCATION_HANDLED;
    }

  if (!flatpak_dir_remove_ref (system, arg_remote, arg_ref, NULL, &error))
    {
      flatpak_invocation_return_error (invocation, error, "Error removing ref");
      return G_DBUS_METHOD_INVOCATION_HANDLED;
    }

  flatpak_system_helper_complete_remove_local_ref (object, invocation);

  return G_DBUS_METHOD_INVOCATION_HANDLED;
}

static gboolean
handle_prune_local_repo (FlatpakSystemHelper   *object,
                         GDBusMethodInvocation *invocation,
                         guint                  arg_flags,
                         const gchar           *arg_installation)
{
  g_autoptr(FlatpakDir) system = NULL;
  g_autoptr(GError) error = NULL;

  g_info ("PruneLocalRepo %u %s", arg_flags, arg_installation);

  system = dir_get_system (arg_installation, invocation, (arg_flags & FLATPAK_HELPER_PRUNE_LOCAL_REPO_FLAGS_NO_INTERACTION) != 0, &error);
  if (system == NULL)
    {
      g_dbus_method_invocation_return_gerror (invocation, error);
      return G_DBUS_METHOD_INVOCATION_HANDLED;
    }

  if ((arg_flags & ~FLATPAK_HELPER_PRUNE_LOCAL_REPO_FLAGS_ALL) != 0)
    {
      g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS,
                                             "Unsupported flags enabled: 0x%x", (arg_flags & ~FLATPAK_HELPER_PRUNE_LOCAL_REPO_FLAGS_ALL));
      return G_DBUS_METHOD_INVOCATION_HANDLED;
    }

  if (!flatpak_dir_ensure_repo (system, NULL, &error))
    {
      g_dbus_method_invocation_return_gerror (invocation, error);
      return G_DBUS_METHOD_INVOCATION_HANDLED;
    }

  if (!flatpak_dir_prune (system, NULL, &error))
    {
      flatpak_invocation_return_error (invocation, error, "Error pruning repo");
      return G_DBUS_METHOD_INVOCATION_HANDLED;
    }

  flatpak_system_helper_complete_prune_local_repo (object, invocation);

  return G_DBUS_METHOD_INVOCATION_HANDLED;
}


static gboolean
handle_ensure_repo (FlatpakSystemHelper   *object,
                    GDBusMethodInvocation *invocation,
                    guint                  arg_flags,
                    const gchar           *arg_installation)
{
  g_autoptr(FlatpakDir) system = NULL;
  g_autoptr(GError) error = NULL;
  g_autoptr(GError) local_error = NULL;

  g_info ("EnsureRepo %u %s", arg_flags, arg_installation);

  system = dir_get_system (arg_installation, invocation, (arg_flags & FLATPAK_HELPER_ENSURE_REPO_FLAGS_NO_INTERACTION) != 0, &error);
  if (system == NULL)
    {
      g_dbus_method_invocation_return_gerror (invocation, error);
      return G_DBUS_METHOD_INVOCATION_HANDLED;
    }

  if ((arg_flags & ~FLATPAK_HELPER_ENSURE_REPO_FLAGS_ALL) != 0)
    {
      g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS,
                                             "Unsupported flags enabled: 0x%x", (arg_flags & ~FLATPAK_HELPER_ENSURE_REPO_FLAGS_ALL));
      return G_DBUS_METHOD_INVOCATION_HANDLED;
    }

  if (!flatpak_dir_ensure_repo (system, NULL, &error))
    {
      g_dbus_method_invocation_return_gerror (invocation, error);
      return G_DBUS_METHOD_INVOCATION_HANDLED;
    }

  if (!flatpak_dir_migrate_config (system, NULL, NULL, &local_error))
    g_warning ("Failed to migrate configuration for installation %s: %s", arg_installation, local_error->message);

  flatpak_system_helper_complete_ensure_repo (object, invocation);

  return G_DBUS_METHOD_INVOCATION_HANDLED;
}

static gboolean
handle_run_triggers (FlatpakSystemHelper   *object,
                     GDBusMethodInvocation *invocation,
                     guint                  arg_flags,
                     const gchar           *arg_installation)
{
  g_autoptr(FlatpakDir) system = NULL;
  g_autoptr(GError) error = NULL;

  g_info ("RunTriggers %u %s", arg_flags, arg_installation);

  system = dir_get_system (arg_installation, invocation, (arg_flags & FLATPAK_HELPER_RUN_TRIGGERS_FLAGS_NO_INTERACTION) != 0, &error);
  if (system == NULL)
    {
      g_dbus_method_invocation_return_gerror (invocation, error);
      return G_DBUS_METHOD_INVOCATION_HANDLED;
    }

  if ((arg_flags & ~FLATPAK_HELPER_RUN_TRIGGERS_FLAGS_ALL) != 0)
    {
      g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS,
                                             "Unsupported flags enabled: 0x%x", (arg_flags & ~FLATPAK_HELPER_RUN_TRIGGERS_FLAGS_ALL));
      return G_DBUS_METHOD_INVOCATION_HANDLED;
    }

  if (!flatpak_dir_ensure_repo (system, NULL, &error))
    {
      g_dbus_method_invocation_return_gerror (invocation, error);
      return G_DBUS_METHOD_INVOCATION_HANDLED;
    }

  if (!flatpak_dir_run_triggers (system, NULL, &error))
    {
      flatpak_invocation_return_error (invocation, error, "Error running triggers");
      return G_DBUS_METHOD_INVOCATION_HANDLED;
    }

  flatpak_system_helper_complete_run_triggers (object, invocation);

  return G_DBUS_METHOD_INVOCATION_HANDLED;
}

static gboolean
check_for_system_helper_user (struct passwd  *passwd,
                              gchar         **passwd_buf,
                              GError        **error)
{
  struct passwd *result = NULL;
  g_autofree gchar *buf = NULL;
  size_t bufsize;
  int err;

  bufsize = sysconf (_SC_GETPW_R_SIZE_MAX);
  if (bufsize == -1)          /* Value was indeterminate */
     bufsize = 16384;        /* Should be more than enough */

  while (!result)
    {
      buf = g_malloc0 (bufsize);
      err = getpwnam_r (SYSTEM_HELPER_USER, passwd, buf, bufsize, &result);
      if (result == NULL)
        {
          if (err == ERANGE)     /* Insufficient buffer space */
            {
              g_free (buf);
              bufsize *= 2;
              continue;
            }
          else if (err == 0)     /* User SYSTEM_HELPER_USER 's record was not found*/
            {
              g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND,
                           "User %s does not exist in password file entry", SYSTEM_HELPER_USER);
              return FALSE;
            }
          else
            {
              g_set_error (error, G_IO_ERROR, g_io_error_from_errno (err),
                           "Failed to query user %s from password file entry", SYSTEM_HELPER_USER);
              return FALSE;
            }
        }
    }

  *passwd_buf = g_steal_pointer (&buf);

  return TRUE;
}

static void
revokefs_fuse_backend_child_setup (gpointer user_data)
{
  struct passwd *passwd = user_data;

  /* We use 5 instead of 3 here, because fd 3 is the inherited SOCK_SEQPACKET
   * socket and fd 4 is the --close-with-fd pipe; both were dup2()'d into place
   * before this by GSubprocess */
  g_fdwalk_set_cloexec (5);

  if (setgid (passwd->pw_gid) == -1)
    {
      g_warning ("Failed to setgid(%d) for revokefs backend: %s",
                 passwd->pw_gid, g_strerror (errno));
      exit (1);
    }

  if (setuid (passwd->pw_uid) == -1)
    {
      g_warning ("Failed to setuid(%d) for revokefs backend: %s",
                 passwd->pw_uid, g_strerror (errno));
      exit (1);
    }
}

static void
name_vanished_cb (GDBusConnection *connection, const gchar *name, gpointer user_data)
{
  const gchar *unique_name = (const gchar *) user_data;
  g_autoptr(GPtrArray) cleanup_pulls = NULL;
  GHashTableIter iter;
  gpointer value;

  cleanup_pulls = g_ptr_array_new_with_free_func ((GDestroyNotify) ongoing_pull_free);

  G_LOCK (cache_dirs_in_use);
  g_hash_table_iter_init (&iter, cache_dirs_in_use);
  while (g_hash_table_iter_next (&iter, NULL, &value))
    {
      OngoingPull *pull = (OngoingPull *) value;
      if (g_strcmp0 (pull->unique_name, unique_name) == 0)
        {
          g_ptr_array_add (cleanup_pulls, pull);
          g_hash_table_iter_remove (&iter);
        }
    }
  G_UNLOCK (cache_dirs_in_use);
}

static OngoingPull *
ongoing_pull_new (FlatpakSystemHelper   *object,
                  GDBusMethodInvocation *invocation,
                  struct passwd         *passwd,
                  uid_t                  uid,
                  const gchar           *src,
                  GError               **error)
{
  GDBusConnection *connection = g_dbus_method_invocation_get_connection (invocation);
  g_autoptr(OngoingPull) pull = NULL;
  g_autoptr(GSubprocessLauncher) launcher = NULL;
  int sockets[2], exit_sockets[2];
  const char *revokefs_fuse_bin = LIBEXECDIR "/revokefs-fuse";

  pull = g_slice_new0 (OngoingPull);
  pull->object = object;
  pull->invocation = invocation;
  pull->src_dir = g_strdup (src);
  pull->cancellable = g_cancellable_new ();
  pull->uid = uid;
  pull->preserve_pull = FALSE;
  pull->unique_name = g_strdup (g_dbus_connection_get_unique_name (connection));

  pull->watch_id = g_bus_watch_name_on_connection (connection,
                                                   pull->unique_name,
                                                   G_BUS_NAME_WATCHER_FLAGS_NONE, NULL,
                                                   name_vanished_cb,
                                                   g_strdup (g_dbus_connection_get_unique_name (connection)),
                                                   g_free);

  if (socketpair (AF_UNIX, SOCK_SEQPACKET, 0, sockets) == -1)
    {
      glnx_throw_errno_prefix (error, "Failed to get a socketpair");
      return NULL;
    }

  if (pipe2 (exit_sockets, O_CLOEXEC) == -1)
    {
      glnx_throw_errno_prefix (error, "Failed to create a pipe");
      close (sockets[0]);
      close (sockets[1]);
      return NULL;
    }

  /* We use INHERIT_FDS and close them in the child_setup
   * to work around a deadlock in GLib < 2.60 */
  launcher = g_subprocess_launcher_new (G_SUBPROCESS_FLAGS_INHERIT_FDS);
  g_subprocess_launcher_set_child_setup (launcher, revokefs_fuse_backend_child_setup, passwd, NULL);
  g_subprocess_launcher_take_fd (launcher, sockets[0], 3);
  fcntl (sockets[1], F_SETFD, FD_CLOEXEC);
  pull->client_socket = sockets[1];

  g_subprocess_launcher_take_fd (launcher, exit_sockets[0], 4);
  pull->backend_exit_socket = exit_sockets[1];

  if (g_getenv ("FLATPAK_REVOKEFS_FUSE"))
    revokefs_fuse_bin = g_getenv ("FLATPAK_REVOKEFS_FUSE");

  pull->revokefs_backend = g_subprocess_launcher_spawn (launcher,
                                                        error,
                                                        revokefs_fuse_bin,
                                                        "--backend",
                                                        "--socket=3",
                                                        "--exit-with-fd=4",
                                                        src, NULL);
  if (pull->revokefs_backend == NULL)
    return NULL;

  return g_steal_pointer (&pull);
}

static gboolean
reuse_cache_dir_if_available (const gchar    *repo_tmp,
                              gchar         **out_src_dir,
                              struct passwd  *passwd)
{
  g_autoptr(GFileEnumerator) enumerator = NULL;
  g_autoptr(GFile) repo_tmpfile = NULL;
  GFileInfo *file_info = NULL;
  g_autoptr(GError) error = NULL;
  const gchar *name;
  gboolean res = FALSE;

  g_info ("Checking for any temporary cache directory available to reuse");

  repo_tmpfile = g_file_new_for_path (repo_tmp);
  enumerator = g_file_enumerate_children (repo_tmpfile,
                                          G_FILE_ATTRIBUTE_STANDARD_NAME ","
                                          G_FILE_ATTRIBUTE_STANDARD_TYPE,
                                          G_FILE_QUERY_INFO_NONE, NULL, &error);
  if (enumerator == NULL)
    {
      g_warning ("Failed to enumerate %s: %s", repo_tmp, error->message);
      return FALSE;
    }

  while (TRUE)
    {
      if (!g_file_enumerator_iterate (enumerator, &file_info, NULL, NULL, &error))
        {
          g_warning ("Error while iterating %s: %s", repo_tmp, error->message);
          break;
        }

      if (file_info == NULL || res == TRUE)
        break;

      name = g_file_info_get_name (file_info);
      if (g_file_info_get_file_type (file_info) == G_FILE_TYPE_DIRECTORY &&
          g_str_has_prefix (name, "flatpak-cache-"))
        {
          g_autoptr(GFile) cache_dir_file = g_file_get_child (repo_tmpfile, name);
          g_autofree gchar *cache_dir_name = g_file_get_path (cache_dir_file);

          G_LOCK (cache_dirs_in_use);
          if (!g_hash_table_contains (cache_dirs_in_use, cache_dir_name))
            {
              struct stat st_buf;

              /* We are able to find a cache dir which is not in use. */
              if (stat (cache_dir_name, &st_buf) == 0 &&
                  st_buf.st_uid == passwd->pw_uid &&        /* should be owned by SYSTEM_HELPER_USER */
                  (st_buf.st_mode & 0022) == 0)             /* should not be world-writeable */
                {
                  gboolean did_not_exist = g_hash_table_insert (cache_dirs_in_use,
                                                                g_strdup (cache_dir_name),
                                                                NULL);
                  g_assert (did_not_exist);
                  *out_src_dir = g_steal_pointer (&cache_dir_name);
                  res = TRUE;
                }
            }
          G_UNLOCK (cache_dirs_in_use);
        }
    }

  return res;
}

static gboolean
handle_get_revokefs_fd (FlatpakSystemHelper   *object,
                        GDBusMethodInvocation *invocation,
                        GUnixFDList           *arg_fdlist,
                        guint                  arg_flags,
                        const gchar           *arg_installation)
{
  g_autoptr(FlatpakDir) system = NULL;
  g_autoptr(GUnixFDList) fd_list = NULL;
  g_autoptr(GError) error = NULL;
  g_autofree gchar *src_dir = NULL;
  g_autofree gchar *flatpak_dir = NULL;
  g_autofree gchar *repo_tmp = NULL;
  g_autofree gchar *passwd_buf = NULL;
  struct passwd passwd = { NULL };
  OngoingPull *new_pull;
  uid_t uid;
  int fd_index = -1;

  g_info ("GetRevokefsFd %u %s", arg_flags, arg_installation);

  if (disable_revokefs)
    {
      g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_NOT_SUPPORTED, "RevokeFS disabled");
      return G_DBUS_METHOD_INVOCATION_HANDLED;
    }

  system = dir_get_system (arg_installation, invocation, (arg_flags & FLATPAK_HELPER_GET_REVOKEFS_FD_FLAGS_NO_INTERACTION) != 0, &error);
  if (system == NULL)
    {
      g_dbus_method_invocation_return_gerror (invocation, error);
      return G_DBUS_METHOD_INVOCATION_HANDLED;
    }

  if ((arg_flags & ~FLATPAK_HELPER_GET_REVOKEFS_FD_FLAGS_ALL) != 0)
    {
      g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS,
                                             "Unsupported flags enabled: 0x%x", (arg_flags & ~FLATPAK_HELPER_GET_REVOKEFS_FD_FLAGS_ALL));
      return G_DBUS_METHOD_INVOCATION_HANDLED;
    }

  if (on_session_bus)
    {
      passwd.pw_uid = getuid();
      passwd.pw_gid = getgid();
    }
  else if (!check_for_system_helper_user (&passwd, &passwd_buf, &error))
    {
      g_dbus_method_invocation_return_gerror (invocation, error);
      return G_DBUS_METHOD_INVOCATION_HANDLED;
    }

  if (!get_connection_uid (invocation, &uid, &error))
    {
      g_dbus_method_invocation_return_gerror (invocation, error);
      return G_DBUS_METHOD_INVOCATION_HANDLED;
    }

  flatpak_dir = g_file_get_path (flatpak_dir_get_path (system));
  repo_tmp = g_build_filename (flatpak_dir, "repo", "tmp", NULL);

   if (reuse_cache_dir_if_available (repo_tmp, &src_dir, &passwd))
     g_info ("Cache dir %s can be reused", src_dir);
  else
    {
      /* Create a new cache dir and add it to cache_dirs_in_use. Do all this under
       * a lock, so that a different pull does not snatch this directory up using
       * reuse_cache_dir_if_available. */
      G_LOCK (cache_dirs_in_use);
      src_dir = g_mkdtemp_full (g_build_filename (repo_tmp, "flatpak-cache-XXXXXX", NULL), 0755);
      if (src_dir == NULL)
        {
          G_UNLOCK (cache_dirs_in_use);
          glnx_throw_errno_prefix (&error, "Failed to create new cache-dir at %s", repo_tmp);
          g_dbus_method_invocation_return_gerror (invocation, error);
          return G_DBUS_METHOD_INVOCATION_HANDLED;
        }
      g_hash_table_insert (cache_dirs_in_use, g_strdup (src_dir), NULL);
      G_UNLOCK (cache_dirs_in_use);

      if (chown (src_dir, passwd.pw_uid, passwd.pw_gid) == -1)
        {
          remove_dir_from_cache_dirs_in_use (src_dir);
          glnx_throw_errno_prefix (&error, "Failed to chown %s to user %s",
                                   src_dir, passwd.pw_name);
          g_dbus_method_invocation_return_gerror (invocation, error);
          return G_DBUS_METHOD_INVOCATION_HANDLED;
        }
    }

  new_pull = ongoing_pull_new (object, invocation, &passwd, uid, src_dir, &error);
  if (error != NULL)
    {
      remove_dir_from_cache_dirs_in_use (src_dir);
      g_dbus_method_invocation_return_gerror (invocation, error);
      return G_DBUS_METHOD_INVOCATION_HANDLED;
    }

  G_LOCK (cache_dirs_in_use);
  g_hash_table_insert (cache_dirs_in_use, g_strdup (src_dir), new_pull);
  G_UNLOCK (cache_dirs_in_use);

  fd_list = g_unix_fd_list_new ();
  fd_index = g_unix_fd_list_append (fd_list, new_pull->client_socket, NULL);

  flatpak_system_helper_complete_get_revokefs_fd (object, invocation,
                                                  fd_list, g_variant_new_handle (fd_index),
                                                  new_pull->src_dir);

  return G_DBUS_METHOD_INVOCATION_HANDLED;
}

static gboolean
handle_update_summary (FlatpakSystemHelper   *object,
                       GDBusMethodInvocation *invocation,
                       guint                  arg_flags,
                       const gchar           *arg_installation)
{
  g_autoptr(FlatpakDir) system = NULL;
  g_autoptr(GError) error = NULL;
  gboolean delete_summary;

  g_info ("UpdateSummary %u %s", arg_flags, arg_installation);

  system = dir_get_system (arg_installation, invocation, (arg_flags & FLATPAK_HELPER_UPDATE_SUMMARY_FLAGS_NO_INTERACTION) != 0, &error);
  if (system == NULL)
    {
      g_dbus_method_invocation_return_gerror (invocation, error);
      return G_DBUS_METHOD_INVOCATION_HANDLED;
    }

  if ((arg_flags & ~FLATPAK_HELPER_UPDATE_SUMMARY_FLAGS_ALL) != 0)
    {
      g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS,
                                             "Unsupported flags enabled: 0x%x", (arg_flags & ~FLATPAK_HELPER_UPDATE_SUMMARY_FLAGS_ALL));
      return G_DBUS_METHOD_INVOCATION_HANDLED;
    }

  if (!flatpak_dir_ensure_repo (system, NULL, &error))
    {
      g_dbus_method_invocation_return_gerror (invocation, error);
      return G_DBUS_METHOD_INVOCATION_HANDLED;
    }
  delete_summary = (arg_flags & FLATPAK_HELPER_UPDATE_SUMMARY_FLAGS_DELETE) != 0;
  if (!flatpak_dir_update_summary (system, delete_summary, NULL, &error))
    {
      flatpak_invocation_return_error (invocation, error, "Error %s summary",
                                       delete_summary ? "deleting" : "updating");
      return G_DBUS_METHOD_INVOCATION_HANDLED;
    }

  flatpak_system_helper_complete_update_summary (object, invocation);

  return G_DBUS_METHOD_INVOCATION_HANDLED;
}

static gboolean
handle_generate_oci_summary (FlatpakSystemHelper   *object,
                             GDBusMethodInvocation *invocation,
                             guint                  arg_flags,
                             const gchar           *arg_origin,
                             const gchar           *arg_installation)
{
  g_autoptr(FlatpakDir) system = NULL;
  g_autoptr(GError) error = NULL;
  gboolean only_cached;
  gboolean is_oci;

  g_info ("GenerateOciSummary %u %s %s", arg_flags, arg_origin, arg_installation);

  system = dir_get_system (arg_installation, invocation, (arg_flags & FLATPAK_HELPER_GENERATE_OCI_SUMMARY_FLAGS_NO_INTERACTION) != 0, &error);
  if (system == NULL)
    {
      g_dbus_method_invocation_return_gerror (invocation, error);
      return G_DBUS_METHOD_INVOCATION_HANDLED;
    }

  if ((arg_flags & ~FLATPAK_HELPER_GENERATE_OCI_SUMMARY_FLAGS_ALL) != 0)
    {
      g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS,
                                             "Unsupported flags enabled: 0x%x", (arg_flags & ~FLATPAK_HELPER_GENERATE_OCI_SUMMARY_FLAGS_ALL));
      return G_DBUS_METHOD_INVOCATION_HANDLED;
    }

  only_cached = (arg_flags & FLATPAK_HELPER_GENERATE_OCI_SUMMARY_FLAGS_ONLY_CACHED) != 0;

  if (!flatpak_dir_ensure_repo (system, NULL, &error))
    {
      g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_FAILED,
                                             "Can't open system repo %s", error->message);
      return G_DBUS_METHOD_INVOCATION_HANDLED;
    }

  is_oci = flatpak_dir_get_remote_oci (system, arg_origin);
  if (!is_oci)
    {
      g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS,
                                             "%s is not a OCI remote", arg_origin);
      return G_DBUS_METHOD_INVOCATION_HANDLED;
    }

  if (!flatpak_dir_remote_make_oci_summary (system, arg_origin, only_cached, NULL, NULL, &error))
    {
      flatpak_invocation_return_error (invocation, error, "Failed to update OCI summary");
      return G_DBUS_METHOD_INVOCATION_HANDLED;
    }


  flatpak_system_helper_complete_generate_oci_summary (object, invocation);

  return G_DBUS_METHOD_INVOCATION_HANDLED;
}

static gboolean
dir_ref_is_installed (FlatpakDir *dir,
                      FlatpakDecomposed *ref)
{
  g_autoptr(GBytes) deploy_data = NULL;

  deploy_data = flatpak_dir_get_deploy_data (dir, ref, FLATPAK_DEPLOY_VERSION_ANY, NULL, NULL);

  return deploy_data != NULL;
}

static gboolean
flatpak_authorize_method_handler (GDBusInterfaceSkeleton *interface,
                                  GDBusMethodInvocation  *invocation,
                                  gpointer                user_data)
{
  const gchar *method_name = g_dbus_method_invocation_get_method_name (invocation);
  const gchar *sender = g_dbus_method_invocation_get_sender (invocation);
  GVariant *parameters = g_dbus_method_invocation_get_parameters (invocation);
  g_autoptr(AutoPolkitSubject) subject = polkit_system_bus_name_new (sender);
  g_autoptr(AutoPolkitDetails) details = polkit_details_new ();
  const gchar *action = NULL;
  gboolean authorized = FALSE;
  gboolean no_interaction = FALSE;

  /* Ensure we don't idle exit */
  schedule_idle_callback ();

  if (on_session_bus)
    {
      /* This is test code, make sure it never runs with privileges */
      g_assert (geteuid () != 0);
      g_assert (getuid () != 0);
      g_assert (getegid () != 0);
      g_assert (getgid () != 0);
      authorized = TRUE;
    }
  else if (g_strcmp0 (method_name, "Deploy") == 0)
    {
      const char *installation;
      const char *ref_str, *origin;
      guint32 flags;

      g_variant_get_child (parameters, 1, "u", &flags);
      g_variant_get_child (parameters, 2, "&s", &ref_str);
      g_variant_get_child (parameters, 3, "&s", &origin);
      g_variant_get_child (parameters, 6, "&s", &installation);

      /* For metadata updates, redirect to the metadata-update action which
       * should basically always be allowed */
      if (g_strcmp0 (ref_str, OSTREE_REPO_METADATA_REF) == 0)
        {
          action = "org.freedesktop.Flatpak.metadata-update";
        }
      else
        {
          g_autoptr(GError) error = NULL;
          g_autoptr(FlatpakDecomposed) ref = NULL;
          gboolean is_app, is_install;

          ref = flatpak_decomposed_new_from_ref (ref_str, &error);
          if (ref == NULL)
            {
              g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_FAILED,
                                                     "Error deployings: %s", error->message);
              return FALSE;
            }

          no_interaction = (flags & FLATPAK_HELPER_DEPLOY_FLAGS_NO_INTERACTION) != 0;

          /* These flags allow clients to "upgrade" the permission,
           * avoiding the need for multiple polkit dialogs when we first
           * update a runtime, then install the app that needs it.
           *
           * Note that our policy has implications:
           * app-install > app-update > runtime-install > runtime-update
           * which means that these hints only ever select a stronger
           * permission, and are safe in that sense.
           */

          if ((flags & FLATPAK_HELPER_DEPLOY_FLAGS_APP_HINT) != 0)
            is_app = TRUE;
          else
            is_app = flatpak_decomposed_is_app (ref);

          if ((flags & FLATPAK_HELPER_DEPLOY_FLAGS_INSTALL_HINT) != 0 ||
              (flags & FLATPAK_HELPER_DEPLOY_FLAGS_REINSTALL) != 0)
            is_install = TRUE;
          else
            {
              g_autoptr(FlatpakDir) system = dir_get_system (installation,
                                                             invocation,
                                                             no_interaction,
                                                             &error);

              if (system == NULL)
                {
                  g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_FAILED,
                                                         "Error getting installation %s: %s", installation, error->message);
                  return FALSE;
                }

              is_install = !dir_ref_is_installed (system, ref);
            }

          if (is_install)
            {
              if (is_app)
                action = "org.freedesktop.Flatpak.app-install";
              else
                action = "org.freedesktop.Flatpak.runtime-install";
            }
          else
            {
              if (is_app)
                action = "org.freedesktop.Flatpak.app-update";
              else
                action = "org.freedesktop.Flatpak.runtime-update";
            }
        }

      polkit_details_insert (details, "origin", origin);
      polkit_details_insert (details, "ref", ref_str);
    }
  else if (g_strcmp0 (method_name, "DeployAppstream") == 0)
    {
      guint32 flags;
      const char *arch, *origin;

      g_variant_get_child (parameters, 1, "u", &flags);
      g_variant_get_child (parameters, 2, "&s", &origin);
      g_variant_get_child (parameters, 3, "&s", &arch);

      action = "org.freedesktop.Flatpak.appstream-update";
      no_interaction = (flags & FLATPAK_HELPER_DEPLOY_APPSTREAM_FLAGS_NO_INTERACTION) != 0;

      polkit_details_insert (details, "origin", origin);
      polkit_details_insert (details, "arch", arch);
    }
  else if (g_strcmp0 (method_name, "InstallBundle") == 0)
    {
      const char *path;
      guint32 flags;

      g_variant_get_child (parameters, 0, "^&ay", &path);
      g_variant_get_child (parameters, 1, "u", &flags);

      action = "org.freedesktop.Flatpak.install-bundle";
      no_interaction = (flags & FLATPAK_HELPER_INSTALL_BUNDLE_FLAGS_NO_INTERACTION) != 0;

      polkit_details_insert (details, "path", path);
    }
  else if (g_strcmp0 (method_name, "Uninstall") == 0)
    {
      const char *installation;
      const char *ref_str;
      gboolean is_app;
      guint32 flags;
      g_autoptr(GError) error = NULL;
      g_autoptr(FlatpakDecomposed) ref = NULL;

      g_variant_get_child (parameters, 0, "u", &flags);
      g_variant_get_child (parameters, 1, "&s", &ref_str);
      g_variant_get_child (parameters, 2, "&s", &installation);

      ref = flatpak_decomposed_new_from_ref (ref_str, &error);
      if (ref == NULL)
        {
          g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_FAILED,
                                                 "Error uninstalling: %s", error->message);
          return FALSE;
        }

      is_app = flatpak_decomposed_is_app (ref);
      if (is_app)
        action = "org.freedesktop.Flatpak.app-uninstall";
      else
        action = "org.freedesktop.Flatpak.runtime-uninstall";
      no_interaction = (flags & FLATPAK_HELPER_UNINSTALL_FLAGS_NO_INTERACTION) != 0;

      /* For the app-uninstall action the message shown to the user includes
       * the app, so let's get the human friendly name if possible. Unlike some
       * of the other actions, app-uninstall isn't implied by any other, and
       * only implies runtime-uninstall, so it seems alright to include what
       * app is being uninstalled. */
      if (is_app)
        {
          g_autoptr(FlatpakDir) system = NULL;
          g_autoptr(GBytes) deploy_data = NULL;
          g_autoptr(GError) sys_error = NULL;
          const char *name = NULL;

          system = dir_get_system (installation, invocation, no_interaction, &sys_error);
          if (system == NULL)
            {
              g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_FAILED,
                                                     "Error getting installation %s: %s", installation, sys_error->message);
              return FALSE;
            }

          deploy_data = flatpak_dir_get_deploy_data (system, ref, FLATPAK_DEPLOY_VERSION_CURRENT, NULL, NULL);
          if (deploy_data != NULL)
            name = flatpak_deploy_data_get_appdata_name (deploy_data);
          if (name != NULL && *name != '\0')
            polkit_details_insert (details, "ref", name);
          else
            polkit_details_insert (details, "ref", flatpak_decomposed_get_ref (ref));
        }
      else
        polkit_details_insert (details, "ref", flatpak_decomposed_get_ref (ref));
    }
  else if (g_strcmp0 (method_name, "ConfigureRemote") == 0)
    {
      const char *remote;
      guint32 flags;

      g_variant_get_child (parameters, 0, "u", &flags);
      g_variant_get_child (parameters, 1, "&s", &remote);

      action = "org.freedesktop.Flatpak.configure-remote";
      no_interaction = (flags & FLATPAK_HELPER_CONFIGURE_REMOTE_FLAGS_NO_INTERACTION) != 0;

      polkit_details_insert (details, "remote", remote);
    }
  else if (g_strcmp0 (method_name, "Configure") == 0)
    {
      const char *key;
      guint32 flags;

      g_variant_get_child (parameters, 0, "u", &flags);
      g_variant_get_child (parameters, 1, "&s", &key);

      action = "org.freedesktop.Flatpak.configure";
      no_interaction = (flags & FLATPAK_HELPER_CONFIGURE_FLAGS_NO_INTERACTION) != 0;

      polkit_details_insert (details, "key", key);
    }
  else if (g_strcmp0 (method_name, "UpdateRemote") == 0)
    {
      const char *remote;
      guint32 flags;

      g_variant_get_child (parameters, 0, "u", &flags);
      g_variant_get_child (parameters, 1, "&s", &remote);

      action = "org.freedesktop.Flatpak.update-remote";
      no_interaction = (flags & FLATPAK_HELPER_UPDATE_REMOTE_FLAGS_NO_INTERACTION) != 0;

      polkit_details_insert (details, "remote", remote);
    }
  else if (g_strcmp0 (method_name, "RemoveLocalRef") == 0 ||
           g_strcmp0 (method_name, "PruneLocalRepo") == 0 ||
           g_strcmp0 (method_name, "EnsureRepo") == 0 ||
           g_strcmp0 (method_name, "RunTriggers") == 0 ||
           g_strcmp0 (method_name, "GetRevokefsFd") == 0 ||
           g_strcmp0 (method_name, "CancelPull") == 0)
    {
      guint32 flags;

      action = "org.freedesktop.Flatpak.modify-repo";

      /* all of these methods have flags as first argument, and 1 << 0 as 'no-interaction' */
      g_variant_get_child (parameters, 0, "u", &flags);
      no_interaction = (flags & (1 << 0)) != 0;
    }
  else if (g_strcmp0 (method_name, "UpdateSummary") == 0 ||
           g_strcmp0 (method_name, "GenerateOciSummary") == 0)
    {
      guint32 flags;
      action = "org.freedesktop.Flatpak.metadata-update";

      /* all of these methods have flags as first argument, and 1 << 0 as 'no-interaction' */
      g_variant_get_child (parameters, 0, "u", &flags);
      no_interaction = (flags & (1 << 0)) != 0;
    }

  if (action)
    {
      g_autoptr(AutoPolkitAuthorizationResult) result = NULL;
      g_autoptr(GError) error = NULL;
      PolkitCheckAuthorizationFlags auth_flags;

      if (no_interaction)
        auth_flags = POLKIT_CHECK_AUTHORIZATION_FLAGS_NONE;
      else
        auth_flags = POLKIT_CHECK_AUTHORIZATION_FLAGS_ALLOW_USER_INTERACTION;

      result = polkit_authority_check_authorization_sync (authority, subject,
                                                          action, details,
                                                          auth_flags,
                                                          NULL, &error);
      if (result == NULL)
        {
          g_dbus_error_strip_remote_error (error);
          g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_FAILED,
                                                 "Authorization error: %s", error->message);
          return FALSE;
        }

      authorized = polkit_authorization_result_get_is_authorized (result);
    }

  if (!authorized)
    {
      g_dbus_method_invocation_return_error (invocation,
                                             G_DBUS_ERROR,
                                             G_DBUS_ERROR_ACCESS_DENIED,
                                             "Flatpak system operation %s not allowed for user", method_name);
    }

  return authorized;
}

static void
on_bus_acquired (GDBusConnection *connection,
                 const gchar     *name,
                 gpointer         user_data)
{
  GError *error = NULL;

  g_info ("Bus acquired, creating skeleton");

  g_dbus_connection_set_exit_on_close (connection, FALSE);

  helper = flatpak_system_helper_skeleton_new ();

  flatpak_system_helper_set_version (FLATPAK_SYSTEM_HELPER (helper), 2);

  g_object_set_data_full (G_OBJECT (helper), "track-alive", GINT_TO_POINTER (42), skeleton_died_cb);

  g_dbus_interface_skeleton_set_flags (G_DBUS_INTERFACE_SKELETON (helper),
                                       G_DBUS_INTERFACE_SKELETON_FLAGS_HANDLE_METHOD_INVOCATIONS_IN_THREAD);

  g_signal_connect (helper, "handle-deploy", G_CALLBACK (handle_deploy), NULL);
  g_signal_connect (helper, "handle-deploy-appstream", G_CALLBACK (handle_deploy_appstream), NULL);
  g_signal_connect (helper, "handle-uninstall", G_CALLBACK (handle_uninstall), NULL);
  g_signal_connect (helper, "handle-install-bundle", G_CALLBACK (handle_install_bundle), NULL);
  g_signal_connect (helper, "handle-configure-remote", G_CALLBACK (handle_configure_remote), NULL);
  g_signal_connect (helper, "handle-configure", G_CALLBACK (handle_configure), NULL);
  g_signal_connect (helper, "handle-update-remote", G_CALLBACK (handle_update_remote), NULL);
  g_signal_connect (helper, "handle-remove-local-ref", G_CALLBACK (handle_remove_local_ref), NULL);
  g_signal_connect (helper, "handle-prune-local-repo", G_CALLBACK (handle_prune_local_repo), NULL);
  g_signal_connect (helper, "handle-ensure-repo", G_CALLBACK (handle_ensure_repo), NULL);
  g_signal_connect (helper, "handle-run-triggers", G_CALLBACK (handle_run_triggers), NULL);
  g_signal_connect (helper, "handle-update-summary", G_CALLBACK (handle_update_summary), NULL);
  g_signal_connect (helper, "handle-generate-oci-summary", G_CALLBACK (handle_generate_oci_summary), NULL);
  g_signal_connect (helper, "handle-get-revokefs-fd", G_CALLBACK (handle_get_revokefs_fd), NULL);
  g_signal_connect (helper, "handle-cancel-pull", G_CALLBACK (handle_cancel_pull), NULL);

  g_signal_connect (helper, "g-authorize-method",
                    G_CALLBACK (flatpak_authorize_method_handler),
                    NULL);

  if (!g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (helper),
                                         connection,
                                         FLATPAK_SYSTEM_HELPER_PATH,
                                         &error))
    {
      g_warning ("error: %s", error->message);
      g_error_free (error);
    }
}

static void
on_name_acquired (GDBusConnection *connection,
                  const gchar     *name,
                  gpointer         user_data)
{
  g_info ("Name acquired");
}

static void
on_name_lost (GDBusConnection *connection,
              const gchar     *name,
              gpointer         user_data)
{
  g_info ("Name lost");
  unref_skeleton_in_timeout ();
}

static void
binary_file_changed_cb (GFileMonitor     *file_monitor,
                        GFile            *file,
                        GFile            *other_file,
                        GFileMonitorEvent event_type,
                        gpointer          data)
{
  static gboolean got_it = FALSE;

  if (!got_it)
    {
      g_info ("binary file changed");
      unref_skeleton_in_timeout ();
    }

  got_it = TRUE;
}

static void
message_handler (const gchar   *log_domain,
                 GLogLevelFlags log_level,
                 const gchar   *message,
                 gpointer       user_data)
{
  /* Make this look like normal console output */
  if (log_level & (G_LOG_LEVEL_DEBUG | G_LOG_LEVEL_INFO))
    g_printerr ("FH: %s\n", message);
  else
    g_printerr ("%s: %s\n", g_get_prgname (), message);
}

static gboolean
opt_verbose_cb (const gchar *option_name,
                const gchar *value,
                gpointer     data,
                GError     **error)
{
  opt_verbose++;
  return TRUE;
}

int
main (int    argc,
      char **argv)
{
  gchar exe_path[PATH_MAX + 1];
  ssize_t exe_path_len;
  gboolean replace;
  gboolean show_version;
  GBusNameOwnerFlags flags;
  g_autoptr(GOptionContext) context = NULL;
  g_autoptr(GError) error = NULL;
  const GOptionEntry options[] = {
    { "replace", 'r', 0, G_OPTION_ARG_NONE, &replace,  "Replace old daemon.", NULL },
    { "verbose", 'v', G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK, &opt_verbose_cb, "Show debug information, -vv for more detail", NULL },
    { "ostree-verbose", 0, 0, G_OPTION_ARG_NONE, &opt_ostree_verbose,"Show OSTree debug information", NULL },
    { "session", 0, 0, G_OPTION_ARG_NONE, &on_session_bus,  "Run in session, not system scope (for tests).", NULL },
    { "no-idle-exit", 0, 0, G_OPTION_ARG_NONE, &no_idle_exit,  "Don't exit when idle.", NULL },
    { "version", 0, 0, G_OPTION_ARG_NONE, &show_version, "Show program version.", NULL},
    { NULL }
  };

  /* The child repo shared between the client process and the
     system-helper really needs to support creating files that
     are readable by others, so override the umask to 022
     Ideally this should be set when needed, but umask is thread-unsafe
     so there is really no local way to fix this.
  */
  umask(022);

  setlocale (LC_ALL, "");

  g_setenv ("GIO_USE_VFS", "local", TRUE);

  if (g_getenv ("FLATPAK_DISABLE_REVOKEFS"))
    disable_revokefs = TRUE;

  g_set_prgname (argv[0]);

  g_log_set_handler (G_LOG_DOMAIN, G_LOG_LEVEL_MESSAGE, message_handler, NULL);

  context = g_option_context_new ("");

  replace = FALSE;
  show_version = FALSE;

  g_option_context_set_summary (context, "Flatpak system helper");
  g_option_context_add_main_entries (context, options, GETTEXT_PACKAGE);

  if (!g_option_context_parse (context, &argc, &argv, &error))
    {
      g_printerr ("%s: %s", g_get_application_name (), error->message);
      g_printerr ("\n");
      g_printerr ("Try \"%s --help\" for more information.",
                  g_get_prgname ());
      g_printerr ("\n");
      g_option_context_free (context);
      return 1;
    }

  if (show_version)
    {
      g_print (PACKAGE_STRING "\n");
      return 0;
    }

  if (opt_verbose > 0)
    g_log_set_handler (G_LOG_DOMAIN, G_LOG_LEVEL_INFO, message_handler, NULL);
  if (opt_verbose > 1)
    g_log_set_handler (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, message_handler, NULL);

  if (opt_ostree_verbose)
    g_log_set_handler ("OSTree", G_LOG_LEVEL_DEBUG | G_LOG_LEVEL_INFO, message_handler, NULL);

  if (!on_session_bus)
    {
      authority = polkit_authority_get_sync (NULL, &error);
      if (authority == NULL)
        {
          g_printerr ("Can't get polkit authority: %s\n", error->message);
          return 1;
        }
    }

  exe_path_len = readlink ("/proc/self/exe", exe_path, sizeof (exe_path) - 1);
  if (exe_path_len > 0)
    {
      exe_path[exe_path_len] = 0;
      GFileMonitor *monitor;
      g_autoptr(GFile) exe = NULL;
      g_autoptr(GError) local_error = NULL;

      exe = g_file_new_for_path (exe_path);
      monitor =  g_file_monitor_file (exe,
                                      G_FILE_MONITOR_NONE,
                                      NULL,
                                      &local_error);
      if (monitor == NULL)
        g_warning ("Failed to set watch on %s: %s", exe_path, error->message);
      else
        g_signal_connect (monitor, "changed",
                          G_CALLBACK (binary_file_changed_cb), NULL);
    }

  flags = G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT;
  if (replace)
    flags |= G_BUS_NAME_OWNER_FLAGS_REPLACE;

  name_owner_id = g_bus_own_name (on_session_bus ? G_BUS_TYPE_SESSION  : G_BUS_TYPE_SYSTEM,
                                  FLATPAK_SYSTEM_HELPER_BUS_NAME,
                                  flags,
                                  on_bus_acquired,
                                  on_name_acquired,
                                  on_name_lost,
                                  NULL,
                                  NULL);

  cache_dirs_in_use = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);

  /* Ensure we don't idle exit */
  schedule_idle_callback ();

  main_loop = g_main_loop_new (NULL, FALSE);
  g_main_loop_run (main_loop);

  G_LOCK (cache_dirs_in_use);
  g_clear_pointer (&cache_dirs_in_use, g_hash_table_destroy);
  G_UNLOCK (cache_dirs_in_use);

  return 0;
}

===== ./system-helper/org.freedesktop.Flatpak.rules.in =====
polkit.addRule(function(action, subject) {
    if ((action.id == "org.freedesktop.Flatpak.app-install" ||
         action.id == "org.freedesktop.Flatpak.runtime-install"||
         action.id == "org.freedesktop.Flatpak.app-uninstall" ||
         action.id == "org.freedesktop.Flatpak.runtime-uninstall" ||
         action.id == "org.freedesktop.Flatpak.modify-repo") &&
        subject.active == true && subject.local == true &&
        subject.isInGroup("@privileged_group@")) {
            return polkit.Result.YES;
    }

    return polkit.Result.NOT_HANDLED;
});

polkit.addRule(function(action, subject) {
    if (action.id == "org.freedesktop.Flatpak.override-parental-controls") {
            return polkit.Result.AUTH_ADMIN;
    }

    return polkit.Result.NOT_HANDLED;
});

===== ./system-helper/flatpak-system-helper.service.in =====
[Unit]
Description=flatpak system helper

[Service]
BusName=org.freedesktop.Flatpak.SystemHelper
Environment=XDG_DATA_DIRS=@localstatedir@/lib/flatpak/exports/share/:/usr/local/share/:/usr/share/
ExecStart=@libexecdir@/flatpak-system-helper
Type=dbus
IOSchedulingClass=idle

===== ./CODE_OF_CONDUCT.md =====
# Code of Conduct

## 1. Purpose

A primary goal of Flatpak is to be inclusive to the largest number of contributors, with the most varied and diverse backgrounds possible. As such, we are committed to providing a friendly, safe and welcoming environment for all, regardless of gender, sexual orientation, ability, ethnicity, socioeconomic status, and religion (or lack thereof).

This code of conduct outlines our expectations for all those who participate in our community, as well as the consequences for unacceptable behavior.

We invite all those who participate in Flatpak to help us create safe and positive experiences for everyone.

## 2. Open Source Citizenship

A supplemental goal of this Code of Conduct is to increase open source citizenship by encouraging participants to recognize and strengthen the relationships between our actions and their effects on our community.

Communities mirror the societies in which they exist and positive action is essential to counteract the many forms of inequality and abuses of power that exist in society.

If you see someone who is making an extra effort to ensure our community is welcoming, friendly, and encourages all participants to contribute to the fullest extent, we want to know.

## 3. Expected Behavior

The following behaviors are expected and requested of all community members:

*   Participate in an authentic and active way. In doing so, you contribute to the health and longevity of this community.
*   Exercise consideration and respect in your speech and actions.
*   Attempt collaboration before conflict.
*   Refrain from demeaning, discriminatory, or harassing behavior and speech.
*   Be mindful of your surroundings and of your fellow participants. Alert community leaders if you notice a dangerous situation, someone in distress, or violations of this Code of Conduct, even if they seem inconsequential.
*   Remember that community event venues may be shared with members of the public; please be respectful to all patrons of these locations.

## 4. Unacceptable Behavior

The following behaviors are considered harassment and are unacceptable within our community:

*   Violence, threats of violence or violent language directed against another person.
*   Sexist, racist, homophobic, transphobic, ableist or otherwise discriminatory jokes and language.
*   Posting or displaying sexually explicit or violent material.
*   Posting or threatening to post other people’s personally identifying information ("doxing").
*   Personal insults, particularly those related to gender, sexual orientation, race, religion, or disability.
*   Inappropriate photography or recording.
*   Inappropriate physical contact. You should have someone’s consent before touching them.
*   Unwelcome sexual attention. This includes, sexualized comments or jokes; inappropriate touching, groping, and unwelcomed sexual advances.
*   Deliberate intimidation, stalking or following (online or in person).
*   Advocating for, or encouraging, any of the above behavior.
*   Sustained disruption of community events, including talks and presentations.

## 5. Consequences of Unacceptable Behavior

Unacceptable behavior from any community member, including sponsors and those with decision-making authority, will not be tolerated.

Anyone asked to stop unacceptable behavior is expected to comply immediately.

If a community member engages in unacceptable behavior, the community organizers may take any action they deem appropriate, up to and including a temporary ban or permanent expulsion from the community without warning (and without refund in the case of a paid event).

## 6. Reporting Guidelines

If you are subject to or witness unacceptable behavior, or have any other concerns, please notify a community organizer as soon as possible. alexander.larsson@gmail.com.



Additionally, community organizers are available to help community members engage with local law enforcement or to otherwise help those experiencing unacceptable behavior feel safe. In the context of in-person events, organizers will also provide escorts as desired by the person experiencing distress.

## 7. Addressing Grievances

If you feel you have been falsely or unfairly accused of violating this Code of Conduct, you should notify Flatpak with a concise description of your grievance. Your grievance will be handled in accordance with our existing governing policies.



## 8. Scope

We expect all community participants (contributors, paid or otherwise; sponsors; and other guests) to abide by this Code of Conduct in all community venues–online and in-person–as well as in all one-on-one communications pertaining to community business.

This code of conduct and its related procedures also applies to unacceptable behavior occurring outside the scope of community activities when such behavior has the potential to adversely affect the safety and well-being of community members.

## 9. Contact info

alexander.larsson@gmail.com

## 10. License and attribution

This Code of Conduct is distributed under a [Creative Commons Attribution-ShareAlike license](http://creativecommons.org/licenses/by-sa/3.0/).

Portions of text derived from the [Django Code of Conduct](https://www.djangoproject.com/conduct/) and the [Geek Feminism Anti-Harassment Policy](http://geekfeminism.wikia.com/wiki/Conference_anti-harassment/Policy).

Retrieved on November 22, 2016 from [http://citizencodeofconduct.org/](http://citizencodeofconduct.org/)

===== ./env.d/60-flatpak =====
#!/bin/sh
export GIO_USE_VFS=local
exec flatpak --print-updated-env

===== ./env.d/meson.build =====
# Copyright 2022 Collabora Ltd.
# SPDX-License-Identifier: LGPL-2.1-or-later

install_data(
  '60-flatpak',
  install_dir : get_option('systemduserenvgendir'),
)
install_data(
  '60-flatpak-system-only',
  install_dir : get_option('systemdsystemenvgendir'),
)

if get_option('gdm_env_file')
  conf_data = configuration_data()
  conf_data.set('localstatedir', get_option('prefix') / get_option('localstatedir'))
  conf_data.set('sysconfdir', get_option('prefix') / get_option('sysconfdir'))
  configure_file(
    input : 'flatpak.env.in',
    output : 'flatpak.env',
    configuration : conf_data,
    install_dir : get_option('datadir') / 'gdm' / 'env.d',
  )
endif

===== ./env.d/flatpak.env.in =====
XDG_DATA_DIRS=$HOME/.local/share/flatpak/exports/share/:@localstatedir@/lib/flatpak/exports/share/:/usr/local/share/:/usr/share/

===== ./env.d/60-flatpak-system-only =====
#!/bin/sh
export GIO_USE_VFS=local
exec flatpak --print-updated-env --print-system-only

===== ./SECURITY.md =====
# Security policy for Flatpak

 * [Supported Versions](#Supported-Versions)
 * [Reporting a Vulnerability](#Reporting-a-Vulnerability)
 * [Security Announcements](#Security-Announcements)
 * [Acknowledgements](#Acknowledgements)

## Supported Versions

In stable branches and released packages, this table is likely to be outdated;
please check
[the latest version](https://github.com/flatpak/flatpak/blob/main/SECURITY.md).

| Version  | Supported          | Status
| -------- | ------------------ | -------------------------------------------------------------- |
| 1.19.x   | :hammer:           | Development branch, releases may include non-security changes  |
| 1.18.x   | :white_check_mark: | Stable branch, recommended for use in distributions            |
| ≤ 1.17.x | :x:                | Older branches, no longer supported                            |

The latest stable branch (currently 1.18.x) is the highest priority for
security fixes.
If a security vulnerability is reported under embargo, having new releases
for older stable branches will not always be treated as a blocker for
lifting the embargo.

## Reporting a Vulnerability

If you think you've identified a security issue in Flatpak, please DO NOT
report the issue publicly via the GitHub issue tracker, mailing list,
Matrix, IRC or any other public medium. Instead, send an email with as
many details as possible to
[flatpak-security@lists.freedesktop.org](mailto:flatpak-security@lists.freedesktop.org).
This is a private mailing list for the Flatpak maintainers.

Please do **not** create a public issue.

## Security Announcements

The [flatpak@lists.freedesktop.org](mailto:flatpak@lists.freedesktop.org) email list is used for messages about
Flatpak security announcements, as well as general announcements and
discussions.
You can join the list [here](https://lists.freedesktop.org/mailman/listinfo/flatpak).

## Acknowledgements

This text was partially based on the [github.com/containers security policy](https://github.com/containers/common/blob/main/SECURITY.md).

===== ./.editorconfig =====
root = true

[*]
charset = utf-8
end_of_line = lf

[*.[ch]]
indent_size = 2
indent_style = space
insert_final_newline = true
# For any stray tabs that may sneak in:
tab_width = 8

[meson.build]
indent_size = 2
indent_style = space


===== ./subprojects/dbus-proxy.wrap =====
[wrap-git]
url = https://github.com/flatpak/xdg-dbus-proxy
# 0.1.7
revision = 6a170fa77e3cbecb48f9dd2478fe5c0a119eb467
depth = 1

===== ./subprojects/README.md =====
Subprojects built as part of Flatpak
====================================

<!-- This document:
Copyright 2023-2024 Collabora Ltd.
SPDX-License-Identifier: MIT
-->

bubblewrap
----------

Upstream: <https://github.com/containers/bubblewrap>

To use a system copy instead, configure with `-Dsystem_bubblewrap=bwrap`
or similar.

To update the suggested version, edit bubblewrap.wrap.

dbus-proxy
----------

Upstream: <https://github.com/flatpak/xdg-dbus-proxy>

To use a system copy instead, configure with
`-Dsystem_dbus_proxy=xdg-dbus-proxy` or similar.

To update the suggested version, edit dbus-proxy.wrap.

libglnx
-------

Upstream: <https://gitlab.gnome.org/GNOME/libglnx/>

This is a "copylib", similar to gnulib, which only supports being
integrated as a subproject and does not guarantee a stable API.
A suitable version is vendored into Flatpak using `git subtree`, to make
our source releases self-contained (if system copies of bubblewrap and
dbus-proxy are used).

To compare with upstream:

    git remote add --no-tags libglnx https://gitlab.gnome.org/GNOME/libglnx.git
    git fetch libglnx
    git diff HEAD:subprojects/libglnx libglnx/master

To merge from upstream:

    git fetch libglnx
    git subtree merge -P subprojects/libglnx libglnx/master
    git commit --amend -s

variant-schema-compiler
-----------------------

Upstream: <https://gitlab.gnome.org/alexl/variant-schema-compiler>

This is a "copylib" like libglnx.

To compare with upstream or merge from upstream, the procedure is similar
to libglnx (see above).

===== ./subprojects/variant-schema-compiler/COPYING =====
The variant-schema compiler, as well as the generated code is covered
by the MIT license:

# Copyright © 2020-2021 Red Hat
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the "Software"),
# to deal in the Software without restriction, including without limitation
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
# and/or sell copies of the Software, and to permit persons to whom the
# Software is furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice (including the next
# paragraph) shall be included in all copies or substantial portions of the
# Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
# IN THE SOFTWARE.

===== ./subprojects/variant-schema-compiler/README.md =====
variant-schema-compiler takes a schema describing a set of GVariant types and generates C code to efficiently access variants in these formats in a typesafe way.

A simple example is `gadget.gv`:
```
type Gadget {
  name: string;
  size: {
     width: int32;
     height: int32;
  };
  array: []int32;
  dict: [string]int32;
};
```

You compile this like:
```
variant-schema-compiler --prefix myapp --outfile gadget.h gadget.gv
```

Which will generate a header file `gadget.h` that you can include in your code.

This will define a structure MyappGadgetRef which you can create from a GVariant with
`myapp_gadget_from_gvariant()` or directly from raw memory using `myapp_gadget_from_bytes()` or
`myapp_gadget_from_data()`. You can then use the generated accessor functions to get the fields
of the variant.

As an example, here is a sample of accessors defined by the above:
```
const char *myapp_gadget_get_name (MyappGadgetRef v);
MyappGadgetSizeRef myapp_gadget_get_size (MyappGadgetRef v);
MyappArrayofint32Ref myapp_gadget_get_array (MyappGadgetRef v);
const gint32 *myapp_gadget_peek_array (MyappGadgetRef v,
                                       gsize *len);
gboolean myapp_gadget_dict_lookup (MyappGadgetDictRef v,
                                   const char * key,
                                   gint32 *out);
```

Using such accessors is much faster than working with the GVariant API for a number of reasons:
 * Getting a child item doesn't allocate a new GVariant object (no generated accessor API allocates memory).
 * No constant ref:ing and unref:ing of GVariants.
 * All the accessors are inlined and coded to be very efficient
 * Less validation than the generic GVariant APIs.

Additionally the APIs are just nicer to use due to using named fields of tuples/structs instead of indexes.

Of course there are some disadvantages, for instance:
  * Only pre-declared types are supported.
  * Less validation means you should not use it for untrusted data.
  * Lack of ownership (ref/unref) means you have to make sure memory ownership is correct in other ways.

However, in many usecases this is not a problem.

Note that the main binding object (the XxxRef:s) are value types (internally they are a basepointer + size tuple) and
not pointers. Also, there is no reference counting, so it is up to the caller to ensure that the memory referenced by
the variant ref is kept alive.

Some GVariant types are "fixed size", which means that all instances of these types have a well known size. 
GVariant encodes such data in a way that is very efficient to access, (with padding as needed, etc).
For such types the compiler also generates a regular struct, which makes it very easy to use these.

For example:
```
type Fixed {
  small: byte;
  large: uint32;
  medium: int16;
  other: {
    huge: double;
  };
};

type User {
  one: Fixed;
  many:  []Fixed;
};
```

Will generate: (among other things)
```
typedef struct {
  double huge;
} MyappFixedOther;

typedef struct {
  guint8 small;
  guchar _padding1[3];
  guint32 large;
  gint16 medium;
  guchar _padding2[6];
  MyappFixedOther other;
} MyappFixed;

MyappFixed *myapp_fixed_peek (MyappFixedRef v);
const MyappFixed *myapp_user_peek_one (MyappUserRef v);
const MyappFixed *myapp_user_peek_many (MyappUserRef v, gsize *len);
```

Here are some more interesting features:
 * field endianness attributes which are auto-applied by the getters().
 * Inline naming of subtypes.
 * Automatically generated formatters/printers.
 * Generation of gvariant typestrings and field index defines for the types

===== ./subprojects/variant-schema-compiler/variant-schema-compiler =====
#!/usr/bin/env python3

# Copyright © 2020-2021 Red Hat
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the "Software"),
# to deal in the Software without restriction, including without limitation
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
# and/or sell copies of the Software, and to permit persons to whom the
# Software is furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice (including the next
# paragraph) shall be included in all copies or substantial portions of the
# Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
# IN THE SOFTWARE.

# This license also covers the generated code created by the app

import argparse
import sys
import os
from pyparsing import *

typename_prefix = ""
funcname_prefix = ""
internal_validation = False

LBRACK, RBRACK, LBRACE, RBRACE, COLON, SEMI = map(Suppress, "[]{}:;")

ident = Word(alphas + "_", alphanums + "_").setName("identifier")

named_types = {}

basic_types = {
    "boolean": ("b", True, 1, "gboolean", "", '%s'),
    "byte": ("y", True, 1, "guint8", "byte ", '0x%02x'),
    "int16": ("n", True, 2, "gint16", "int16 ", '%"G_GINT16_FORMAT"'),
    "uint16": ("q", True, 2, "guint16", "uint16 ", '%"G_GUINT16_FORMAT"'),
    "int32": ("i", True, 4, "gint32", "", '%"G_GINT32_FORMAT"'),
    "uint32": ("u", True, 4, "guint32", "uint32 ", '%"G_GUINT32_FORMAT"'),
    "int64": ("x", True, 8, "gint64", "int64 ", '%"G_GINT64_FORMAT"'),
    "uint64": ("t", True, 8, "guint64", "uint64 ", '%"G_GUINT64_FORMAT"'),
    "handle": ("h", True, 4, "guint32", "handle ", '%"G_GINT32_FORMAT"'),
    "double": ("d", True, 8, "double", "", None), # double formating is special
    "string": ("s", False, 1, "const char *", "", None), # String formating is special
    "objectpath": ("o", False, 1, "const char *", "objectpath ", "\\'%s\\'"),
    "signature": ("g", False, 1, "const char *", "signature ", "\\'%s\\'"),
}


def snake_case_to_CamelCase(name):
    res = ""
    for run in name.split("_"):
        res = res + run[0].upper() + run[1:]
    return res

def CamelCase_to_snake_case(name):
    res = ""
    for i, c in enumerate(name):
        if c.isupper():
            if i > 0:
                res = res + "_"
            res = res + c.lower()
        else:
            res = res + c
    return res

def remove_prefix(text, prefix):
    return text[text.startswith(prefix) and len(prefix):]

output_c_file = None
def writeC(code, continued = False):
    if output_file:
        output_file.write(code)
        if not continued:
            output_file.write('\n')
    else:
        print(code, end='' if continued else '\n')

output_h_file = None
def writeH(code, continued = False):
    if output_h_file:
        output_h_file.write(code)
        if not continued:
            output_h_file.write('\n')
    else:
        print(code, end='' if continued else '\n')

def genC(code, extra_vars = None):
    vars = {
        'Prefix': typename_prefix,
        'prefix_': funcname_prefix,
        'PREFIX_': funcname_prefix.upper()
    }
    if extra_vars:
        vars = {**vars, **extra_vars}
    res = code.format_map(vars)
    if res[:1] == '\n':
        res = res[1:]
    return res
def escapeC(s):
    return s.replace('{', '{{').replace('}', '}}')

def C(code, extra_vars = None, continued = False):
    writeC(genC(code, extra_vars), continued)

def H(code, extra_vars = None, continued = False):
    writeH(genC(code, extra_vars), continued)

def generate_header(filename):
    H("""
#ifndef __{PREFIX_}__{FILENAME}__H__
#define __{PREFIX_}__{FILENAME}__H__
/* generated code for {filename} */
#include <string.h>
#include <glib.h>

/********** Basic types *****************/

typedef struct {{
 gconstpointer base;
 gsize size;
}} {Prefix}Ref;
""", {
    "filename": filename,
    "FILENAME": filename.upper().replace(".", "_").replace(" ", "_").replace("-", "_"),
} )

    C("""
/* Make sure generated code works with older glib versions without g_memdup2 */
static inline gpointer
_{prefix_}memdup2(gconstpointer mem, gsize byte_size)
{{
#if GLIB_CHECK_VERSION(2, 68, 0)
    return g_memdup2(mem, byte_size);
#else
    gpointer new_mem;

    if (mem && byte_size != 0) {{
        new_mem = g_malloc(byte_size);
        memcpy(new_mem, mem, byte_size);
    }} else {{
        new_mem = NULL;
    }}

    return new_mem;
#endif
}}

#define {PREFIX_}REF_READ_FRAME_OFFSET(_v, _index) {prefix_}ref_read_unaligned_le ((guchar*)((_v).base) + (_v).size - (offset_size * ((_index) + 1)), offset_size)
#define {PREFIX_}REF_ALIGN(_offset, _align_to) ((_offset + _align_to - 1) & ~(gsize)(_align_to - 1))

/* Note: clz is undefinded for 0, so never call this size == 0 */
G_GNUC_CONST static inline guint
{prefix_}ref_get_offset_size (gsize size)
{{
#if defined(__GNUC__) && (__GNUC__ >= 4) && defined(__OPTIMIZE__) && defined(__LP64__)
  /* Instead of using a lookup table we use nibbles in a lookup word */
  guint32 v = (guint32)0x88884421;
  return (v >> (((__builtin_clzl(size) ^ 63) / 8) * 4)) & 0xf;
#else
  if (size > G_MAXUINT16)
    {{
      if (size > G_MAXUINT32)
        return 8;
      else
        return 4;
    }}
  else
    {{
      if (size > G_MAXUINT8)
         return 2;
      else
         return 1;
    }}
#endif
}}

G_GNUC_PURE static inline guint64
{prefix_}ref_read_unaligned_le (guchar *bytes, guint   size)
{{
  union
  {{
    guchar bytes[8];
    guint64 integer;
  }} tmpvalue;

  tmpvalue.integer = 0;
  /* we unroll the size checks here so that memcpy gets constant args */
  if (size >= 4)
    {{
      if (size == 8)
        memcpy (&tmpvalue.bytes, bytes, 8);
      else
        memcpy (&tmpvalue.bytes, bytes, 4);
    }}
  else
    {{
      if (size == 2)
        memcpy (&tmpvalue.bytes, bytes, 2);
      else
        memcpy (&tmpvalue.bytes, bytes, 1);
    }}

  return GUINT64_FROM_LE (tmpvalue.integer);
}}

static inline void
__{prefix_}gstring_append_double (GString *string, double d)
{{
  gchar buffer[100];
  gint i;

  g_ascii_dtostr (buffer, sizeof buffer, d);
  for (i = 0; buffer[i]; i++)
    if (buffer[i] == '.' || buffer[i] == 'e' ||
        buffer[i] == 'n' || buffer[i] == 'N')
      break;

  /* if there is no '.' or 'e' in the float then add one */
  if (buffer[i] == '\\0')
    {{
      buffer[i++] = '.';
      buffer[i++] = '0';
      buffer[i++] = '\\0';
    }}
   g_string_append (string, buffer);
}}

static inline void
__{prefix_}gstring_append_string (GString *string, const char *str)
{{
  gunichar quote = strchr (str, '\\'') ? '"' : '\\'';

  g_string_append_c (string, quote);
  while (*str)
    {{
      gunichar c = g_utf8_get_char (str);

      if (c == quote || c == '\\\\')
        g_string_append_c (string, '\\\\');

      if (g_unichar_isprint (c))
        g_string_append_unichar (string, c);
      else
        {{
          g_string_append_c (string, '\\\\');
          if (c < 0x10000)
            switch (c)
              {{
              case '\\a':
                g_string_append_c (string, 'a');
                break;

              case '\\b':
                g_string_append_c (string, 'b');
                break;

              case '\\f':
                g_string_append_c (string, 'f');
                break;

              case '\\n':
                g_string_append_c (string, 'n');
                break;

              case '\\r':
                g_string_append_c (string, 'r');
                break;

              case '\\t':
                g_string_append_c (string, 't');
                break;

              case '\\v':
                g_string_append_c (string, 'v');
                break;

              default:
                g_string_append_printf (string, "u%04x", c);
                break;
              }}
           else
             g_string_append_printf (string, "U%08x", c);
        }}

      str = g_utf8_next_char (str);
    }}

  g_string_append_c (string, quote);
}}
""")

    C("""
/************** {Prefix}VariantRef *******************/
""")

    H("""
typedef struct {{
 gconstpointer base;
 gsize size;
}} {Prefix}VariantRef;
""")

    C("""
static inline {Prefix}Ref
{prefix_}variant_get_child ({Prefix}VariantRef v, const GVariantType **out_type)
{{
  if (v.size)
    {{
      guchar *base = (guchar *)v.base;
      gsize size = v.size - 1;

      /* find '\\0' character */
      while (size > 0 && base[size] != 0)
        size--;

      /* ensure we didn't just hit the start of the string */
      if (base[size] == 0)
       {{
          const char *type_string = (char *) base + size + 1;
          const char *limit = (char *)base + v.size;
          const char *end;

          if (g_variant_type_string_scan (type_string, limit, &end) && end == limit)
            {{
              if (out_type)
                *out_type = (const GVariantType *)type_string;
              return ({Prefix}Ref) {{ v.base, size }};
            }}
       }}
    }}
  if (out_type)
    *out_type = G_VARIANT_TYPE_UNIT;
  return  ({Prefix}Ref) {{ "\\0", 1 }};
}}

static inline const GVariantType *
{prefix_}variant_get_type ({Prefix}VariantRef v)
{{
  if (v.size)
    {{
      guchar *base = (guchar *)v.base;
      gsize size = v.size - 1;

      /* find '\\0' character */
      while (size > 0 && base[size] != 0)
        size--;

      /* ensure we didn't just hit the start of the string */
      if (base[size] == 0)
       {{
          const char *type_string = (char *) base + size + 1;
          const char *limit = (char *)base + v.size;
          const char *end;

          if (g_variant_type_string_scan (type_string, limit, &end) && end == limit)
             return (const GVariantType *)type_string;
       }}
    }}
  return  G_VARIANT_TYPE_UNIT;
}}

static inline gboolean
{prefix_}variant_is_type ({Prefix}VariantRef v, const GVariantType *type)
{{
   return g_variant_type_equal ({prefix_}variant_get_type (v), type);
}}

static inline {Prefix}VariantRef
{prefix_}variant_from_gvariant (GVariant *v)
{{
  g_assert (g_variant_type_equal (g_variant_get_type (v), G_VARIANT_TYPE_VARIANT));
  return ({Prefix}VariantRef) {{ g_variant_get_data (v), g_variant_get_size (v) }};
}}

static inline {Prefix}VariantRef
{prefix_}variant_from_bytes (GBytes *b)
{{
  return ({Prefix}VariantRef) {{ g_bytes_get_data (b, NULL), g_bytes_get_size (b) }};
}}

static inline {Prefix}VariantRef
{prefix_}variant_from_data (gconstpointer data, gsize size)
{{
  return ({Prefix}VariantRef) {{ data, size }};
}}

static inline GVariant *
{prefix_}variant_dup_to_gvariant ({Prefix}VariantRef v)
{{
  guint8 *duped = _{prefix_}memdup2 (v.base, v.size);
  return g_variant_new_from_data (G_VARIANT_TYPE_VARIANT, duped, v.size, TRUE, g_free, duped);
}}

static inline GVariant *
{prefix_}variant_to_gvariant ({Prefix}VariantRef v,
                              GDestroyNotify      notify,
                              gpointer            user_data)
{{
  return g_variant_new_from_data (G_VARIANT_TYPE_VARIANT, v.base, v.size, TRUE, notify, user_data);
}}

static inline GVariant *
{prefix_}variant_to_owned_gvariant ({Prefix}VariantRef v,
                                     GVariant *base)
{{
  return {prefix_}variant_to_gvariant (v, (GDestroyNotify)g_variant_unref, g_variant_ref (base));
}}

static inline GVariant *
{prefix_}variant_peek_as_variant ({Prefix}VariantRef v)
{{
  return g_variant_new_from_data (G_VARIANT_TYPE_VARIANT, v.base, v.size, TRUE, NULL, NULL);
}}

static inline {Prefix}VariantRef
{prefix_}variant_from_variant ({Prefix}VariantRef v)
{{
  const GVariantType  *type;
  {Prefix}Ref child = {prefix_}variant_get_child (v, &type);
  g_assert (g_variant_type_equal(type, G_VARIANT_TYPE_VARIANT));
  return {prefix_}variant_from_data (child.base, child.size);
}}

static inline GVariant *
{prefix_}variant_dup_child_to_gvariant ({Prefix}VariantRef v)
{{
  const GVariantType  *type;
  {Prefix}Ref child = {prefix_}variant_get_child (v, &type);
  guint8 *duped = _{prefix_}memdup2 (child.base, child.size);
  return g_variant_new_from_data (type, duped, child.size, TRUE, g_free, duped);
}}

static inline GVariant *
{prefix_}variant_peek_child_as_variant ({Prefix}VariantRef v)
{{
  const GVariantType  *type;
  {Prefix}Ref child = {prefix_}variant_get_child (v, &type);
  return g_variant_new_from_data (type, child.base, child.size, TRUE, NULL, NULL);
}}

static inline GString *
{prefix_}variant_format ({Prefix}VariantRef v, GString *s, gboolean type_annotate)
{{
#ifdef {PREFIX_}DEEP_VARIANT_FORMAT
  GVariant *gv = {prefix_}variant_peek_as_variant (v);
  return g_variant_print_string (gv, s, TRUE);
#else
  const GVariantType  *type = {prefix_}variant_get_type (v);
  g_string_append_printf (s, "<@%.*s>", (int)g_variant_type_get_string_length (type), (const char *)type);
  return s;
#endif
}}

static inline char *
{prefix_}variant_print ({Prefix}VariantRef v, gboolean type_annotate)
{{
  GString *s = g_string_new ("");
  {prefix_}variant_format (v, s, type_annotate);
  return g_string_free (s, FALSE);
}}""", {'filename': filename})

    for kind in basic_types.keys():
        basic_type = basic_types[kind]
        ctype = basic_type[3]
        if kind == "boolean":
            read_ctype = "guint8"
        else:
            read_ctype = ctype
        fixed = basic_type[1]
        C("""
static inline {ctype}
{prefix_}variant_get_{kind} ({Prefix}VariantRef v)
{{""", {"kind": kind, 'ctype': ctype})
        if fixed:
            C("  return ({ctype})*(({read_ctype} *)v.base);", {'ctype': ctype, 'read_ctype': read_ctype})
        else:
            C("  return ({ctype})v.base;", {'ctype': ctype, 'read_ctype': read_ctype})
        C("}}")

    if internal_validation:
        C("""
static inline void
{prefix_}validate_length (const GVariantType *type, gconstpointer base, gsize size, gsize length)
{{
  GVariant *v = g_variant_ref_sink (g_variant_new_from_data (type, base, size, FALSE, NULL, NULL));
  g_assert (length == g_variant_n_children (v));
  g_variant_unref (v);
}}

static inline void
{prefix_}validate_child (const GVariantType *type, gconstpointer base, gsize size, gsize index, gconstpointer child_base, gsize child_size)
{{
  GVariant *v = g_variant_ref_sink (g_variant_new_from_data (type, base, size, FALSE, NULL, NULL));
  GVariant *child = g_variant_get_child_value (v, index);
  g_assert (child != NULL);
  g_assert (child_size == g_variant_get_size (child));
  gconstpointer child_data = g_variant_get_data (child);
  g_assert (child_base == child_data || (child_data == NULL && child_size == 0));
  g_variant_unref (child);
  g_variant_unref (v);
}}""")

def generate_footer(filename):
    H("#endif")

def align_down(value, alignment):
    return value & ~(alignment - 1)

def align_up(value, alignment):
    return align_down(value + alignment - 1, alignment)

def add_named_type(name, type):
    assert not name in named_types
    type.set_typename(name, True)
    named_types[name] = type

def get_named_type(name):
    name = typename_prefix + name
    if not name in named_types:
        print ("Unknown type %s" % remove_prefix(name, typename_prefix))
        sys.exit(1)
    return named_types[name]

class TypeDef:
    def __init__(self, name, type):
        name = typename_prefix + name
        self.name = name
        self.type = type

        add_named_type(name, type)

    def generate(self, generated):
        def do_generate (type, generated):
            for c in type.get_children():
                do_generate (c, generated)
            if type.typename != None and type.typename not in generated:
                generated[type.typename] = True
                type.generate()

        do_generate(self.type, generated)


class Type:
    def __init__(self):
        self.typename = None

    def typestring(self):
        assert False

    def set_typename(self, name, override = False):
        if self.typename == None or override:
            self.typename = name
            self.propagate_typename(name)

    def propagate_typename(self, typename):
        pass

    def is_basic(self):
        return False

    def is_fixed(self):
        return False

    def get_fixed_size(self):
         return None

    def alignment(self):
        return 1

    def get_children(self):
        return []

    def add_expansion_vars(self, vars):
        pass

    def genC(self, code, extra_vars = None):
        vars = {
            'TypeName': self.typename,
            'typestring': self.typestring(),
            'ctype': self.get_ctype(),
            'alignment': self.alignment(),
            'fixed_size': self.get_fixed_size()
        }
        if self.typename:
            vars['TypeNameRef'] = self.typename + 'Ref'
            snake = CamelCase_to_snake_case(self.typename)
            vars['type_name_'] = snake + '_'
            vars['TYPE_NAME_'] = snake.upper() + '_'
        if self.is_fixed():
            vars['fixed_ctype'] = self.get_fixed_ctype()

        if extra_vars:
            vars = {**vars, **extra_vars}
        self.add_expansion_vars(vars)
        return genC(code, vars)

    def C(self, code, extra_vars = None, continued=False):
        writeC(self.genC(code, extra_vars), continued)

    def H(self, code, extra_vars = None, continued=False):
        writeH(self.genC(code, extra_vars), continued)

    def generate_types(self):
        self.C('''

/************** {TypeName} *******************/''')

        self.H('''
#define {TYPE_NAME_}TYPESTRING "{typestring}"
#define {TYPE_NAME_}TYPEFORMAT ((const GVariantType *) {TYPE_NAME_}TYPESTRING)

typedef struct {{
 gconstpointer base;
 gsize size;
}} {TypeNameRef};
''')

    def generate_standard_functions(self):
        C=self.C
        C('''

static inline {TypeNameRef}
{type_name_}from_gvariant (GVariant *v)
{{
  g_assert (g_variant_type_equal (g_variant_get_type (v), {TYPE_NAME_}TYPESTRING));
  return ({TypeNameRef}) {{ g_variant_get_data (v), g_variant_get_size (v) }};
}}

static inline {TypeNameRef}
{type_name_}from_bytes (GBytes *b)
{{''')
        if self.is_fixed():
            C('''
  g_assert (g_bytes_get_size (b) == {fixed_size});
''')
        C('''
  return ({TypeNameRef}) {{ g_bytes_get_data (b, NULL), g_bytes_get_size (b) }};
}}

static inline {TypeNameRef}
{type_name_}from_data (gconstpointer data, gsize size)
{{''')
        if self.is_fixed():
            C('''
  g_assert (size == {fixed_size});
''')
        C('''
  return ({TypeNameRef}) {{ data, size }};
}}

static inline GVariant *
{type_name_}dup_to_gvariant ({TypeNameRef} v)
{{
  guint8 *duped = _{prefix_}memdup2 (v.base, v.size);
  return g_variant_new_from_data ({TYPE_NAME_}TYPEFORMAT, duped, v.size, TRUE, g_free, duped);
}}

static inline GVariant *
{type_name_}to_gvariant ({TypeNameRef} v,
                             GDestroyNotify      notify,
                             gpointer            user_data)
{{
  return g_variant_new_from_data ({TYPE_NAME_}TYPEFORMAT, v.base, v.size, TRUE, notify, user_data);
}}

static inline GVariant *
{type_name_}to_owned_gvariant ({TypeNameRef} v, GVariant *base)
{{
  return {type_name_}to_gvariant (v, (GDestroyNotify)g_variant_unref, g_variant_ref (base));
}}

static inline GVariant *
{type_name_}peek_as_gvariant ({TypeNameRef} v)
{{
  return g_variant_new_from_data ({TYPE_NAME_}TYPEFORMAT, v.base, v.size, TRUE, NULL, NULL);
}}

static inline {TypeNameRef}
{type_name_}from_variant ({Prefix}VariantRef v)
{{
  const GVariantType  *type;
  {Prefix}Ref child = {prefix_}variant_get_child (v, &type);
  g_assert (g_variant_type_equal(type, {TYPE_NAME_}TYPESTRING));
  return {type_name_}from_data (child.base, child.size);
}}
''')

    def generate_print(self):
        self.C('''

static inline char *
{type_name_}print ({TypeNameRef} v, gboolean type_annotate)
{{
  GString *s = g_string_new ("");
  {type_name_}format (v, s, type_annotate);
  return g_string_free (s, FALSE);
}}''')

    def get_ctype(self):
         return self.typename + "Ref"

    def get_fixed_ctype(self):
         return self.typename

    def can_printf_format(self):
         return False

    def can_compare(self):
         return False

    def generate_append_value(self, value, with_type_annotate):
        return self.genC("{type_name_}format ({value}, s, {type_annotate});", {'value': value, 'type_annotate': with_type_annotate})

class BasicType(Type):
    def __init__(self, kind):
        super().__init__()
        assert kind in basic_types
        self.kind = kind
    def __repr__(self):
         return "BasicType(%s)" % self.kind
    def typestring(self):
         return basic_types[self.kind][0]
    def set_typename(self, name):
        pass # No names for basic types
    def is_basic(self):
        return True
    def is_fixed(self):
         return basic_types[self.kind][1]
    def get_fixed_size(self):
         return basic_types[self.kind][2]
    def alignment(self):
         return basic_types[self.kind][2]
    def get_ctype(self):
         return basic_types[self.kind][3]
    def get_read_ctype(self):
        if self.kind == "boolean":
            return "guint8"
        return self.get_ctype()
    def get_fixed_ctype(self):
         return self.get_read_ctype()
    def get_type_annotation(self):
        return basic_types[self.kind][4]
    def get_format_string(self):
        return basic_types[self.kind][5]
    def convert_value_for_format(self, value):
        if self.kind == "boolean":
            value = '(%s) ? "true" : "false"' % value
        return value
    def can_printf_format(self):
         return self.get_format_string() != None
    def add_expansion_vars(self, vars):
        vars['readctype'] = self.get_read_ctype()
    def generate_append_value(self, value, with_type_annotate):
        # Special case some basic types
        genC = self.genC
        if self.kind == "string":
            return genC('__{prefix_}gstring_append_string (s, {value});', {'value': value})
        elif self.kind == "double":
            return genC ('__{prefix_}gstring_append_double (s, {value});', {'value': value})
        else:
            value = self.convert_value_for_format(value)
            if with_type_annotate != "FALSE" and self.get_type_annotation() != "":
                return genC('g_string_append_printf (s, "%s{format}", {type_annotate} ? "{annotate}" : "", {value});',
                  {
                      'format': self.get_format_string(),
                      'type_annotate': with_type_annotate,
                      'annotate': self.get_type_annotation(),
                      'value': value
                  })
            else:
                return genC('g_string_append_printf (s, "{format}", {value});',
                  {
                      'format': self.get_format_string(),
                      'value': value
                  }
                )
    def can_compare(self):
        return True
    def compare_code(self, val1, val2):
        if self.is_fixed():
            if self.kind == "uint64" or self.kind == "int64":
                return "((%s) < (%s) ? -1 : (((%s) == (%s) ? 0 : 1))" % (val1, val2, val1, val2)
            else:
                return "((%s) - (%s))" % (val1, val2)
        else: # String type
            return "strcmp(%s, %s)" % (val1, val2)
    def equal_code(self, val1, val2):
        if self.is_fixed():
            return "%s == %s" % (val1, val2)
        else: # String type
            return "strcmp(%s, %s) == 0" % (val1, val2)
    def canonicalize_code(self, val):
        if self.kind == "boolean":
            return "!!%s" % val
        return val

class ArrayType(Type):
    def __init__(self, element_type):
        super().__init__()
        self.element_type = element_type

        if element_type.is_basic():
            self.typename = typename_prefix + "Arrayof" + self.element_type.kind
        elif element_type.typename:
            self.typename = typename_prefix + "Arrayof" + remove_prefix(element_type.typename, typename_prefix)

    def __repr__(self):
         return "ArrayType<%s>(%s)" % (self.typename, repr(self.element_type))
    def typestring(self):
         return "a" + self.element_type.typestring()
    def propagate_typename(self, name):
        self.element_type.set_typename (name + "Element")
    def alignment(self):
        return self.element_type.alignment()
    def get_children(self):
        return [self.element_type]
    def add_expansion_vars(self, vars):
        vars['element_ctype'] = self.element_type.get_ctype()
        vars['ElementTypename'] = self.element_type.typename
        if self.element_type.typename:
            vars['ElementTypenameRef'] = self.element_type.typename + "Ref"
        vars['element_fixed_size'] = self.element_type.get_fixed_size()
        if self.element_type.is_fixed():
            vars['element_fixed_ctype'] = self.element_type.get_fixed_ctype()
        vars['element_alignment'] = self.element_type.alignment()
        if self.element_type.is_basic():
            vars['element_read_ctype'] = self.element_type.get_read_ctype()

    def generate(self):
        super().generate_types()
        super().generate_standard_functions()
        C = self.C
        C("static inline gsize")
        C("{type_name_}get_length ({TypeNameRef} v)")
        C("{{")
        if self.element_type.is_fixed():
            C("  gsize length = v.size / {element_fixed_size};")
        else:
            C("  if (v.size == 0)");
            C("    return 0;");
            C("  guint offset_size = {prefix_}ref_get_offset_size (v.size);");
            C("  gsize last_end = {PREFIX_}REF_READ_FRAME_OFFSET(v, 0);");
            C("  gsize offsets_array_size;")
            C("  if (last_end > v.size)")
            C("    return 0;")
            C("  offsets_array_size = v.size - last_end;")
            C("  if (offsets_array_size % offset_size != 0)")
            C("    return 0;")
            C("  gsize length  = offsets_array_size / offset_size;")
        if internal_validation:
            C("  {prefix_}validate_length ({TYPE_NAME_}TYPEFORMAT, v.base, v.size, length);")
        C("  return length;")
        C("}}")
        C("")
        C("static inline {element_ctype}")
        C("{type_name_}get_at ({TypeNameRef} v, gsize index)")
        C("{{")
        if self.element_type.is_fixed():
            if self.element_type.is_basic():
                C("  return ({element_ctype})G_STRUCT_MEMBER({element_read_ctype}, v.base, index * {element_fixed_size});")
            else:
                C("  return ({ElementTypenameRef}) {{ G_STRUCT_MEMBER_P(v.base, index * {element_fixed_size}), {element_fixed_size}}};")
        else:
            # non-fixed size
            C("  guint offset_size = {prefix_}ref_get_offset_size (v.size);")
            C("  gsize last_end = {PREFIX_}REF_READ_FRAME_OFFSET(v, 0);");
            C("  gsize len = (v.size - last_end) / offset_size;")
            # Here we assume last_end is verified in get_length(), its not safe anyway to call get_at() without checking the length first
            C("  gsize start = (index > 0) ? {PREFIX_}REF_ALIGN({PREFIX_}REF_READ_FRAME_OFFSET(v, len - index), {element_alignment}) : 0;")
            C("  G_GNUC_UNUSED gsize end = {PREFIX_}REF_READ_FRAME_OFFSET(v, len - index - 1);")
            C("  g_assert (start <= end);")
            C("  g_assert (end <= last_end);")

            if internal_validation:
                C("  {prefix_}validate_child ({TYPE_NAME_}TYPEFORMAT, v.base, v.size, index, ((const char *)v.base) + start, end - start);");

            if self.element_type.is_basic(): # non-fixed basic == Stringlike
                C("  const char *base = (const char *)v.base;")
                C("  g_assert (base[end-1] == 0);")
                C("  return base + start;")
            else:
                C("  return ({ElementTypenameRef}) {{ ((const char *)v.base) + start, end - start }};")
        C("}}")

        if self.element_type.is_fixed():
            C("""

static inline const {element_fixed_ctype} *
{type_name_}peek ({TypeNameRef} v)
{{
  return (const {element_fixed_ctype} *)v.base;
}}""");
        elif self.element_type.is_basic(): # Array of string type
            C("""

static inline {element_ctype}*
{type_name_}to_strv ({TypeNameRef} v, gsize *length_out)
{{
  gsize length = {type_name_}get_length (v);
  gsize i;
  const char **resv = g_new (const char *, length + 1);

  for (i = 0; i < length; i++)
    resv[i] = {type_name_}get_at (v, i);
  resv[i] = NULL;

  if (length_out)
    *length_out = length;

  return resv;
}}""");

        C("""

static inline GString *
{type_name_}format ({TypeNameRef} v, GString *s, gboolean type_annotate)
{{
  gsize len = {type_name_}get_length (v);
  gsize i;
  if (len == 0 && type_annotate)
    g_string_append_printf (s, \"@%s \", {TYPE_NAME_}TYPESTRING);
  g_string_append_c (s, '[');
  for (i = 0; i < len; i++)
    {{
      if (i != 0)
        g_string_append (s, \", \");
      {append_element_code}
    }}
  g_string_append_c (s, ']');
  return s;
}}""",  {
    'append_element_code': escapeC(self.element_type.generate_append_value(self.genC("{type_name_}get_at (v, i)"), "((i == 0) ? type_annotate : FALSE)"))
})

        self.generate_print()

class DictType(Type):
    def __init__(self, attributes, key_type, value_type):
        super().__init__()
        self.attributes = list(attributes)
        self.key_type = key_type
        self.value_type = value_type

        self._fixed_element = value_type.is_fixed() and key_type.is_fixed();
        if self._fixed_element:
            fixed_pos = key_type.get_fixed_size()
            fixed_pos = align_up(fixed_pos, value_type.alignment()) + value_type.get_fixed_size()
            self._fixed_element_size = align_up(fixed_pos, self.alignment())
        else:
            self._fixed_element_size = None

    def __repr__(self):
         return "DictType<%s>(%s, %s)" % (self.typename, repr(self.key_type), repr(self.value_type))
    def typestring(self):
         return "a{%s%s}" % (self.key_type.typestring(), self.value_type.typestring())
    def propagate_typename(self, name):
        self.value_type.set_typename (name + "Value")
    def alignment(self):
        return max(self.value_type.alignment(), self.key_type.alignment())
    def element_is_fixed(self):
        return self._fixed_element
    def element_fixed_size(self):
        return self._fixed_element_size
    def get_children(self):
        return [self.key_type, self.value_type]
    def add_expansion_vars(self, vars):
        vars['element_fixed_size'] = self.element_fixed_size()
        vars['element_typeformat'] = '((const GVariantType *) "' + self.typestring()[1:] + '")'
        vars['value_ctype'] = self.value_type.get_ctype()
        vars['value_typename'] = self.value_type.typename
        vars['value_fixed_size'] = self.value_type.get_fixed_size()
        vars['value_alignment'] = self.value_type.alignment()
        if self.value_type.is_basic():
            vars['value_read_ctype'] = self.value_type.get_read_ctype()
        vars['key_fixed_size'] = self.key_type.get_fixed_size()
        vars['key_ctype'] = self.key_type.get_ctype()
        if self.key_type.is_basic():
            vars['key_read_ctype'] = self.key_type.get_read_ctype()

    def generate(self):
        C=self.C
        H=self.H
        super().generate_types()
        H('''
typedef struct {{
 gconstpointer base;
 gsize size;
}} {TypeName}EntryRef;
''')

        if self.element_is_fixed():
            H("typedef struct {{")
            pad_index = 1;
            pos = 0
            for k, t in [("key", self.key_type), ("value", self.value_type)]:
                old_pos = pos
                pos = align_up(pos, t.alignment())
                if pos > old_pos:
                    H("  guchar _padding{pad_index}[{pad_count}];", {'pad_index': pad_index , 'pad_count': pos - old_pos})
                    pad_index += 1
                H("  {field_type} {fieldname};", {'field_type': t.get_fixed_ctype(), 'fieldname': k})
                pos += t.get_fixed_size()
            old_pos = pos
            pos = align_up(pos, self.alignment())
            if pos > old_pos:
                H("  guchar _padding{pad_index}[{pad_count}];", {'pad_index': pad_index , 'pad_count': pos - old_pos})
                pad_index += 1
            H("}} {TypeName}Entry;")
            H("")

        super().generate_standard_functions()
        C('')

        C("static inline gsize")
        C("{type_name_}get_length ({TypeNameRef} v)")
        C("{{")
        if self.element_is_fixed():
            C("  gsize length = v.size / {element_fixed_size};")
        else:
            C("  if (v.size == 0)");
            C("    return 0;");
            C("  guint offset_size = {prefix_}ref_get_offset_size (v.size);");
            C("  gsize last_end = {PREFIX_}REF_READ_FRAME_OFFSET(v, 0);");
            C("  gsize offsets_array_size;")
            C("  if (last_end > v.size)")
            C("    return 0;")
            C("  offsets_array_size = v.size - last_end;")
            C("  if (offsets_array_size % offset_size != 0)")
            C("    return 0;")
            C("  gsize length = offsets_array_size / offset_size;")
        if internal_validation:
            C("  {prefix_}validate_length ({TYPE_NAME_}TYPEFORMAT, v.base, v.size, length);")
        C("  return length;")
        C("}}")

        C('')

        C("static inline {TypeName}EntryRef")
        C("{type_name_}get_at ({TypeNameRef} v, gsize index)")
        C("{{")
        C("  {TypeName}EntryRef res;");
        if self.element_is_fixed():
            C("  res = ({TypeName}EntryRef) {{ G_STRUCT_MEMBER_P(v.base, index * {element_fixed_size}), {element_fixed_size} }};")
        else:
            # non-fixed size
            C("  guint offset_size = {prefix_}ref_get_offset_size (v.size);")
            C("  gsize last_end = {PREFIX_}REF_READ_FRAME_OFFSET(v, 0);");
            C("  gsize len = (v.size - last_end) / offset_size;")
            # Here we assume last_end is verified in get_length(), its not safe anyway to call get_at() without checking the length first
            C("  gsize start = (index > 0) ? {PREFIX_}REF_ALIGN({PREFIX_}REF_READ_FRAME_OFFSET(v, len - index), {alignment}) : 0;")
            C("  gsize end = {PREFIX_}REF_READ_FRAME_OFFSET(v, len - index - 1);");
            C("  g_assert (start <= end);")
            C("  g_assert (end <= last_end);")
            C("  res = ({TypeName}EntryRef) {{ ((const char *)v.base) + start, end - start }};")
        if internal_validation:
            C("  {prefix_}validate_child ({TYPE_NAME_}TYPEFORMAT, v.base, v.size, index, res.base, res.size);")
        C("  return res;")
        C("}}")

        C('')

        if self.element_is_fixed():
            C("""
static inline const {TypeName}Entry *
{type_name_}peek ({TypeNameRef} v) {{
  return (const {TypeName}Entry *)v.base;
}}
""");


        C("static inline {key_ctype}")
        C("{type_name_}entry_get_key ({TypeName}EntryRef v)")
        C("{{")
        # Keys are always basic
        if self.key_type.is_fixed():
            if not self.element_is_fixed(): # No need to verify size if the entire element is fixed
                C("  g_assert (v.size >= {key_fixed_size});")
            if internal_validation:
                C("  {prefix_}validate_child ({element_typeformat}, v.base, v.size, 0, v.base, {key_fixed_size});")
            C("  return ({key_ctype})*(({key_read_ctype} *)v.base);")
        else: # string-style
            C("  guint offset_size = {prefix_}ref_get_offset_size (v.size);")
            C("  G_GNUC_UNUSED gsize end = {PREFIX_}REF_READ_FRAME_OFFSET(v, 0);");
            C("  const char *base = (const char *)v.base;")
            C("  g_assert (end < v.size);")
            C("  g_assert (base[end-1] == 0);")
            if internal_validation:
                C("  {prefix_}validate_child ({element_typeformat}, v.base, v.size, 0, v.base, end);")
            C("  return base;")
        C("}}")

        C('')

        C("static inline {value_ctype}")
        C("{type_name_}entry_get_value ({TypeName}EntryRef v)")
        C("{{")
        if not self.key_type.is_fixed():
            C("  guint offset_size = {prefix_}ref_get_offset_size (v.size);")
            C("  gsize end = {PREFIX_}REF_READ_FRAME_OFFSET(v, 0);");
            C("  gsize offset = {PREFIX_}REF_ALIGN(end, {value_alignment});")
            if self.value_type.is_fixed():
                C("  g_assert (offset == v.size - offset_size - {value_fixed_size});");
            else:
                C("  g_assert (offset <= v.size);")
            offset = "offset"
            end = "(v.size - offset_size)"
        else:
            # Fixed key, so known offset
            offset = align_up(self.key_type.get_fixed_size(), self.value_type.alignment())
            end = "v.size"
            if not self.value_type.is_fixed():
                C("  g_assert (v.size >= {offset});", {'offset': offset})

        if internal_validation:
            C("  {prefix_}validate_child ({element_typeformat}, v.base, v.size, 1, (char *)v.base + {offset},  {end} - {offset});", {'offset': offset, 'end': end })

        if self.value_type.is_basic():
            if self.value_type.is_fixed():
                C("  return ({value_ctype})*(({value_read_ctype} *)((char *)v.base + {offset}));", {'offset': offset})
            else: # string-style
                C("  g_assert (((char *)v.base)[{end} - 1] == 0);", {'end': end })
                C("  return ({value_ctype})v.base + {offset};", {'offset': offset})
        else:
            C("  return ({value_typename}Ref) {{ (char *)v.base + {offset}, {end} - {offset} }};", {'offset': offset, 'end': end })

        C("}}")

        C('')

        C("""
static inline gboolean
{type_name_}lookup ({TypeNameRef} v, {key_ctype} key, gsize *index_out, {value_ctype} *out)
{{
  {key_ctype} canonical_key = {canonicalize};""", { 'canonicalize': self.key_type.canonicalize_code("key") })
        if self.element_is_fixed():
            if "sorted" in self.attributes and self.key_type.can_compare(): # Sorted, fixed
                C("""
  gsize len = v.size / {element_fixed_size};
  gsize start = 0;
  gsize end = len;

  while (start < end)
    {{
      gsize mid = (end + start) / 2;
      {TypeName}EntryRef e = {{ ((const char *)v.base) + mid * {element_fixed_size}, {element_fixed_size} }};
      {key_ctype} e_key = {type_name_}entry_get_key (e);
      gint32 cmp = {compare};
      if (cmp == 0)
        {{
           if (index_out)
             *index_out = mid;
           if (out)
             *out = {type_name_}entry_get_value (e);
           return TRUE;
        }}
      if (cmp < 0)
        end = mid; /* canonical_key < e_key */
      else
        start = mid + 1; /* canonical_key > e_key */
    }}
    return FALSE;
}}""", {'compare': self.key_type.compare_code("canonical_key", "e_key")})
            else: # Unsorted, fixed size
                C("""
  const guchar *p = v.base;
  const guchar *end = p + v.size;
  gsize i = 0;

  while (p < end)
    {{
        {TypeName}EntryRef e = {{ p, {element_fixed_size} }};
        {key_ctype} e_key = {type_name_}entry_get_key (e);
        if ({equal})
          {{
             if (index_out)
               *index_out = i;
             if (out)
               *out = {type_name_}entry_get_value (e);
             return TRUE;
          }}
         i++;
         p += {element_fixed_size};
    }}
    return FALSE;
}}""", {
    'equal': self.key_type.equal_code("canonical_key", "e_key"),
    'canonicalize': self.key_type.canonicalize_code("key")
})
        else:
            C("""
  if (v.size == 0)
    return FALSE;
  guint offset_size = {prefix_}ref_get_offset_size (v.size);
  gsize last_end = {PREFIX_}REF_READ_FRAME_OFFSET(v, 0);
  if (last_end > v.size)
    return FALSE;
  gsize offsets_array_size = v.size - last_end;
  if (offsets_array_size % offset_size != 0)
    return FALSE;
  gsize len = offsets_array_size / offset_size;""")
            if "sorted" in self.attributes and self.key_type.can_compare(): # Sorted, non-fixed size
                C("""
  gsize start = 0;
  gsize end = len;

  while (start < end)
    {{
      gsize mid = (end + start) / 2;
      gsize mid_end = {PREFIX_}REF_READ_FRAME_OFFSET(v, len - mid - 1);
      gsize mid_start = mid == 0 ? 0 : {PREFIX_}REF_ALIGN({PREFIX_}REF_READ_FRAME_OFFSET(v, len - mid), {alignment});
      g_assert (mid_start <= mid_end);
      g_assert (mid_end <= last_end);
      {TypeName}EntryRef e = {{ ((const char *)v.base) + mid_start, mid_end - mid_start }};
      {key_ctype} e_key = {type_name_}entry_get_key (e);
      gint32 cmp = {compare};
      if (cmp == 0)
        {{
           if (index_out)
             *index_out = mid;
           if (out)
             *out = {type_name_}entry_get_value (e);
           return TRUE;
        }}
      if (cmp < 0)
        end = mid; /* canonical_key < e_key */
      else
        start = mid + 1; /* canonical_key > e_key */
    }}
    return FALSE;
}}""", { 'compare': self.key_type.compare_code("canonical_key", "e_key")})
            else: # Unsorted, non-fixed size
                C("""
  gsize start = 0;
  gsize i;

  for (i = 0; i < len; i++)
    {{
      gsize end = {PREFIX_}REF_READ_FRAME_OFFSET(v, len - i - 1);
      {TypeName}EntryRef e = {{ ((const guchar *)v.base) + start, end - start }};
      g_assert (start <= end);
      g_assert (end <= last_end);
      {key_ctype} e_key = {type_name_}entry_get_key (e);
      if ({equal})
        {{
           if (index_out)
             *index_out = i;
           if (out)
             *out = {type_name_}entry_get_value (e);
           return TRUE;
        }}
      start = {PREFIX_}REF_ALIGN(end, {alignment});
    }}
    return FALSE;
}}""", { 'equal': self.key_type.equal_code("canonical_key", "e_key") })

            C('')

            if isinstance(self.value_type, VariantType):
                for kind in basic_types.keys():
                    basic_type = basic_types[kind]
                    ctype = basic_type[3]
                    typechar = basic_type[0]
                    C("""
static inline {ctype}
{type_name_}lookup_{kind} ({TypeNameRef} v, {key_ctype} key, {ctype} default_value)
{{
   {Prefix}VariantRef value_v;

  if ({type_name_}lookup (v, key, NULL, &value_v) &&
      *(const char *){prefix_}variant_get_type (value_v) == '{typechar}')
    return {prefix_}variant_get_{kind} (value_v);
  return default_value;
}}
""", {
    'ctype': ctype,
    'typechar': typechar,
    "kind": kind
})


        C(
"""static inline GString *
{type_name_}format ({TypeNameRef} v, GString *s, gboolean type_annotate)
{{
  gsize len = {type_name_}get_length (v);
  gsize i;

  if (len == 0 && type_annotate)
    g_string_append_printf (s, \"@%s \", {TYPE_NAME_}TYPESTRING);

  g_string_append_c (s, '{{');
  for (i = 0; i < len; i++)
    {{
      {TypeName}EntryRef entry = {type_name_}get_at (v, i);
      if (i != 0)
        g_string_append (s, \", \");
      {append_key_code}
      g_string_append (s, ": ");
      {append_value_code}
    }}
  g_string_append_c (s, '}}');
  return s;
}}""",{
    'append_key_code': escapeC(self.key_type.generate_append_value(self.genC("{type_name_}entry_get_key (entry)"), "type_annotate")),
    'append_value_code': escapeC(self.value_type.generate_append_value(self.genC("{type_name_}entry_get_value (entry)"), "type_annotate")),
})

        self.generate_print()

class MaybeType(Type):
    def __init__(self, element_type):
        super().__init__()
        self.element_type = element_type
        if element_type.is_basic():
            self.typename = typename_prefix + "Maybe" + self.element_type.kind
        elif element_type.typename:
            self.typename = typename_prefix + "Maybe" + remove_prefix(element_type.typename, typename_prefix)
    def __repr__(self):
         return "MaybeType<%s>(%s, %s)" % (self.typename, repr(self.element_type))
    def typestring(self):
         return "m" + self.element_type.typestring()
    def propagate_typename(self, name):
        self.element_type.set_typename (name + "Element")
    def alignment(self):
        return self.element_type.alignment()
    def get_children(self):
        return [self.element_type]
    def add_expansion_vars(self, vars):
        vars['element_ctype'] = self.element_type.get_ctype()
        vars['ElementTypename'] = self.element_type.typename
        if self.element_type.typename:
            vars['ElementTypenameRef'] = self.element_type.typename + "Ref"
        vars['element_fixed_size'] = self.element_type.get_fixed_size()
        vars['element_alignment'] = self.element_type.alignment()
        if self.element_type.is_basic():
            vars['element_read_ctype'] = self.element_type.get_read_ctype()

    def generate(self):
        super().generate_types()
        super().generate_standard_functions()

        C=self.C
        # has_value
        C(
"""static inline gboolean
{type_name_}has_value({TypeNameRef} v)
{{
  return v.size != 0;
}}""")

        # Getter
        C("static inline {element_ctype}")
        C("{type_name_}get_value ({TypeNameRef} v)")
        C("{{")
        if self.element_type.is_fixed():
            C("  g_assert (v.size == {element_fixed_size});")
        else:
            if self.element_type.is_basic(): # string type
                C("  g_assert (v.size >= 2);") # Must be at least extra zero byte plus a terminating zero
            else:
                C("  g_assert (v.size >= 1);") # Must be at least extra zero byte

        if self.element_type.is_basic():
            if self.element_type.is_fixed():
                C("  return ({element_ctype})*(({element_read_ctype} *)v.base);")
            else: # string
                C("  const char *base = (const char *)v.base;")
                C("  g_assert (base[v.size - 2] == 0);")
                C("  return base;")
        else:
            if self.element_type.is_fixed():
                # Fixed means use whole size
                size = "v.size"
            else:
                # Otherwise, ignore extra zero byte
                size = "(v.size - 1)"
            if internal_validation:
                C("  {prefix_}validate_child ({TYPE_NAME_}TYPEFORMAT, v.base, v.size, 0, ((const char *)v.base), {size});", { 'size': size })
            C("  return ({ElementTypenameRef}) {{ v.base, {size} }};", { 'size': size })
        C("}}")

        C("static inline GString *")
        C("{type_name_}format ({TypeNameRef} v, GString *s, gboolean type_annotate)")
        C("{{")
        C("  if (type_annotate)")
        C('    g_string_append_printf (s, "@%s ", {TYPE_NAME_}TYPESTRING);')
        C("  if (v.size != 0)")
        C("    {{")
        if isinstance(self.element_type, MaybeType):
            C('      g_string_append (s, "just ");')
        C('      {append_element_code}', {
            'append_element_code': escapeC(self.element_type.generate_append_value(self.genC("{type_name_}get_value (v)"), "FALSE"))
        })
        C("    }}")
        C("  else")
        C("    {{")
        C('      g_string_append (s, "nothing");')
        C("    }}")
        C("  return s;")
        C("}}")
        self.generate_print()

class VariantType(Type):
    def __init__(self):
        super().__init__()
        self.typename = typename_prefix + "Variant"
    def __repr__(self):
         return "VariantType()"
    def typestring(self):
         return "v"
    def set_typename(self, name):
        pass # No names for variant
    def alignment(self):
        return 8
    def generate(self):
        pass # These are hardcoded in the prefix so all types can use it

class Field:
    def __init__(self, name, attributes, type):
        self.name = name
        self.attributes = list(attributes)
        self.type = type
        self.last = False
        self.struct = None
        self.index = None

    def __repr__(self):
         return "Field(%s, %s)" % (self.name, self.type)

    def propagate_typename(self, struct_name):
        self.type.set_typename (struct_name + snake_case_to_CamelCase (self.name))

    def genC(self, code, extra_vars = None):
        vars = {
            'fieldname': self.name,
            'FIELDNAME': self.name.upper(),
            'StructName': self.struct.typename,
            'StructNameRef': self.struct.typename + "Ref",
            'STRUCT_NAME_': CamelCase_to_snake_case(self.struct.typename).upper() + '_',
            'struct_name_': CamelCase_to_snake_case(self.struct.typename) + '_',
            'fieldindex': self.fieldindex,
        }
        if extra_vars:
            vars = {**vars, **extra_vars}
        return self.type.genC(code, vars)

    def C(self, code, extra_vars = None, continued = False):
        writeC(self.genC(code, extra_vars), continued=continued)

    def H(self, code, extra_vars = None, continued = False):
        writeH(self.genC(code, extra_vars), continued=continued)

    def generate(self):
        # Getter
        C=self.C
        H=self.H
        genC=self.genC
        H("#define {STRUCT_NAME_}INDEXOF_{FIELDNAME} {fieldindex}")
        H("")
        C("static inline {ctype}")
        C("{struct_name_}get_{fieldname} ({StructName}Ref v)")
        C("{{")

        if not self.type.is_fixed() or self.table_i >= 0:
            C("  guint offset_size = {prefix_}ref_get_offset_size (v.size);");

        if self.table_i == -1:
            offset = "((%d) & (~(gsize)%d)) + %d" % (self.table_a + self.table_b, self.table_b, self.table_c)
        else:
            C("  gsize last_end = {PREFIX_}REF_READ_FRAME_OFFSET(v, {table_i});", {'table_i': self.table_i });
            offset = "((last_end + %d) & (~(gsize)%d)) + %d" % (self.table_a + self.table_b, self.table_b, self.table_c)
        C("  guint offset = {offset};", {'offset': offset});

        if self.type.is_basic():
            if self.type.is_fixed():
                if not self.struct.is_fixed():
                    C("  g_assert (offset + {fixed_size} <= v.size);");
                val = genC("({ctype})G_STRUCT_MEMBER({readctype}, v.base, offset)")
                if "bigendian" in self.attributes:
                    val = "%s_FROM_BE(%s)" % (self.type.get_ctype().upper(), val)
                if "littleendian" in self.attributes:
                    val = "%s_FROM_LE(%s)" % (self.type.get_ctype().upper(), val)
                C("  return {val};", {"val": val})
            else: # string
                C("  const char *base = (const char *)v.base;")
                C("  gsize start = offset;");
                if self.last:
                    C("  G_GNUC_UNUSED gsize end = v.size - offset_size * {framing_offset_size};", {'framing_offset_size': self.struct.framing_offset_size })
                else:
                    C("  G_GNUC_UNUSED gsize end = {PREFIX_}REF_READ_FRAME_OFFSET(v, %d);" % (self.table_i + 1));
                C("  g_assert (start <= end);");
                C("  g_assert (end <= v.size);");
                C("  g_assert (base[end-1] == 0);");
                if internal_validation:
                    C("  {prefix_}validate_child ({STRUCT_NAME_}TYPEFORMAT, v.base, v.size, {fieldindex}, (const char *)v.base + start, end - start);")
                C("  return &G_STRUCT_MEMBER(const char, v.base, start);")
        else:
            if self.type.is_fixed():
                if not self.struct.is_fixed():
                    C("  g_assert (offset + {fixed_size} <= v.size);");
                C("  return ({TypeNameRef}) {{ G_STRUCT_MEMBER_P(v.base, offset), {fixed_size} }};")
            else:
                C("  gsize start = offset;");
                if self.last:
                    C("  gsize end = v.size - offset_size * {framing_offset_size};", {'framing_offset_size': self.struct.framing_offset_size })
                else:
                    C("  gsize end = {PREFIX_}REF_READ_FRAME_OFFSET(v, %d);" % (self.table_i + 1));
                C("  g_assert (start <= end);");
                C("  g_assert (end <= v.size);");
                if internal_validation:
                    C("  {prefix_}validate_child ({STRUCT_NAME_}TYPEFORMAT, v.base, v.size, {fieldindex}, (const char *)v.base + start, end - start);")
                C("  return ({TypeNameRef}) {{ G_STRUCT_MEMBER_P(v.base, start), end - start }};")
        C("}}")
        C("")

        if self.type.is_fixed() and not self.type.is_basic():
            C(
"""static inline const {fixed_ctype} *
{struct_name_}peek_{fieldname} ({StructName}Ref v) {{
  return ({fixed_ctype} *){struct_name_}get_{fieldname} (v).base;
}}
""")
        elif isinstance(self.type, ArrayType) and self.type.element_type.is_fixed():
            C(
"""static inline const {element_fixed_ctype} *
{struct_name_}peek_{fieldname} ({StructName}Ref v, gsize *len) {{
  {ctype} a = {struct_name_}get_{fieldname} (v);
  if (len != NULL)
    *len = {type_name_}get_length (a);
  return (const {element_fixed_ctype} *)a.base;
}}
""", {
    'element_fixed_ctype': self.type.element_type.get_fixed_ctype(),
})
        elif isinstance(self.type, DictType) and self.type.element_is_fixed():
            C(
"""static inline const {element_fixed_ctype} *
{struct_name_}peek_{fieldname} ({StructName}Ref v, gsize *len) {{
  {ctype} a = {struct_name_}get_{fieldname} (v);
  if (len != NULL)
    *len = {type_name_}get_length (a);
  return (const {element_fixed_ctype} *)a.base;
}}
""", {
    'element_fixed_ctype': self.type.typename + "Entry",
})

    def generate_fixed(self):
        comments = []
        if "bigendian" in self.attributes:
            comments.append("big endian")
        if "littleendian" in self.attributes:
            comments.append("little endian")
        self.H("  {field_type} {fieldname};{comment}", {
            'field_type': self.type.get_fixed_ctype(),
            'comment': "" if len(comments) == 0 else "/* " +  ",".join(comments) + " */",
        })

class StructType(Type):
    def __init__(self, fields):
        super().__init__()
        self.fields = list(fields)

        if len(self.fields) > 0:
            self.fields[len(self.fields) - 1].last = True

        for i, f in enumerate(self.fields):
            f.struct = self
            f.fieldindex = i

        framing_offset_size = 0
        fixed = True
        fixed_pos = 0
        for f in fields:
            if f.type.is_fixed():
                fixed_pos = align_up(fixed_pos, f.type.alignment()) + f.type.get_fixed_size()
            else:
                fixed = False
                if not f.last:
                    framing_offset_size = framing_offset_size + 1

        self.framing_offset_size = framing_offset_size
        self._fixed = fixed
        self._fixed_size = None;
        if fixed:
            if fixed_pos == 0: # Special case unit struct
                self._fixed_size = 1;
            else:
                # Round up to alignment
                self._fixed_size = align_up(fixed_pos, self.alignment())

        def tuple_align(offset, alignment):
            return offset + ((-offset) & alignment)

        # This is code equivalend to tuple_generate_table() in gvariantinfo.c, see its docs
        i = -1
        a = 0
        b = 0
        c = 0
        for f in fields:
            d = f.type.alignment() - 1;
            e = f.type.get_fixed_size() if f.type.is_fixed() else 0

            # align to 'd'
            if d <= b: # rule 1
                c = tuple_align(c, d)
            else: # rule 2
                a = a + tuple_align(c, b)
                b = d
                c = 0

            # the start of the item is at this point (ie: right after we
            # have aligned for it).  store this information in the table.
            f.table_i = i
            f.table_a = a
            f.table_b = b
            f.table_c = c

            # "move past" the item by adding in its size.
            if e == 0:
                # variable size:
                #
                # we'll have an offset stored to mark the end of this item, so
                # just bump the offset index to give us a new starting point
                # and reset all the counters.
                i = i + 1
                a = b = c = 0
            else:
                # fixed size
                c = c + e # rule 3

    def __repr__(self):
        return "StructType<%s>(%s)" % (self.typename, ",".join(map(repr, self.fields)))

    def typestring(self):
        res = ['(']
        for f in self.fields:
            res.append(f.type.typestring())
        res.append(')')
        return "".join(res)

    def get_children(self):
        children = []
        for f in self.fields:
            children.append(f.type)
        return children

    def propagate_typename(self, name):
        for f in self.fields:
            f.propagate_typename(name)

    def alignment(self):
        alignment = 1;
        for f in self.fields:
            alignment = max(alignment, f.type.alignment())
        return alignment

    def is_fixed(self):
        return self._fixed;
    def get_fixed_size(self):
        return self._fixed_size

    def generate(self):
        C=self.C
        H=self.H
        super().generate_types()

        if self.is_fixed():
            H("typedef struct {{")
            pos = 0
            pad_index = 1;
            for f in self.fields:
                old_pos = pos
                pos = align_up(pos, f.type.alignment())
                if pos > old_pos:
                    H("  guchar _padding{pad_index}[{pad_count}];", {'pad_index': pad_index , 'pad_count': pos - old_pos})
                    pad_index += 1
                f.generate_fixed()
                pos += f.type.get_fixed_size()
            old_pos = pos
            pos = align_up(pos, self.alignment())
            if pos > old_pos:
                H("  guchar _padding{pad_index}[{pad_count}];", {'pad_index': pad_index , 'pad_count': pos - old_pos})
                pad_index += 1
            H("}} {TypeName};")


        super().generate_standard_functions()

        if self.is_fixed():
            C(
"""static inline const {fixed_ctype} *
{type_name_}peek ({TypeNameRef} v) {{
  return (const {fixed_ctype} *)v.base;
}}
""");

        for f in self.fields:
            f.generate()

        C("static inline GString *")
        C("{type_name_}format ({TypeNameRef} v, GString *s, gboolean type_annotate)")
        C("{{")

        # Create runs of things we can combine into single printf
        field_runs = []
        current_run = None
        for f in self.fields:
            if current_run and f.type.can_printf_format() == current_run[0].type.can_printf_format():
                current_run.append(f)
            else:
                current_run = [f]
                field_runs.append(current_run)

        for i, run in enumerate(field_runs):
            if run[0].type.can_printf_format():
                # A run of printf fields
                C('  g_string_append_printf (s, "%s' % ("(" if i == 0 else ""), continued=True)
                for f in run:
                    if f.type.get_type_annotation() != "":
                        C('%s', continued=True)
                    C('%s' % (f.type.get_format_string()), continued=True)
                    if not f.last:
                        C(', ', continued=True)
                    elif len(self.fields) == 1:
                        C(',)', continued=True)
                    else:
                        C(')', continued=True)
                C('",')
                for j, f in enumerate(run):
                    if f.type.get_type_annotation() != "":
                        C('                   type_annotate ? "%s" : "",' % (f.type.get_type_annotation()))
                    value = f.type.convert_value_for_format(f.genC("{struct_name_}get_{fieldname} (v)"))
                    C('                   %s%s' % (value, "," if j != len(run) - 1 else ");"))
            else:
                # A run of container fields
                if i == 0:
                    C('  g_string_append (s, "(");')
                for f in run:
                    C('  {append_field_code}', {'append_field_code': escapeC(f.type.generate_append_value(f.genC("{struct_name_}get_{fieldname} (v)"), "type_annotate"))})
                    if not f.last:
                        C('  g_string_append (s, ", ");')
                    elif len(self.fields) == 1:
                        C('  g_string_append (s, ",)");')
                    else:
                        C('  g_string_append (s, ")");')
        C("  return s;")
        C("}}")
        self.generate_print()

typeSpec = Forward()

basicType = oneOf(list(basic_types.keys())).setParseAction(lambda toks: BasicType(toks[0]))

variantType = Keyword("variant").setParseAction(lambda toks: VariantType())

arrayType = (LBRACK + RBRACK + typeSpec).setParseAction(lambda toks: ArrayType(toks[0]))

indexAttribute = oneOf("sorted")

dictType = (LBRACK + Group(ZeroOrMore(indexAttribute)) + basicType + RBRACK + typeSpec).setParseAction(lambda toks: DictType(toks[0], toks[1], toks[2]))

maybeType = (Suppress("?") + typeSpec).setParseAction(lambda toks: MaybeType(toks[0]))

fieldAttribute = oneOf("bigendian littleendian")

field = (ident + COLON + Group(ZeroOrMore(fieldAttribute)) + typeSpec + SEMI).setParseAction(lambda toks: Field(toks[0], toks[1], toks[2]))

structType = (LBRACE + ZeroOrMore(field) + RBRACE).setParseAction(lambda toks: StructType(toks))

namedType = ident.copy().setParseAction(lambda toks: get_named_type(str(toks[0])))

def handleNameableType(toks):
    type = toks[-1]
    if len(toks) == 2:
        name = toks[0]
        add_named_type(typename_prefix + name, type)
    return type

nameableType = (Optional(Combine(Suppress("'") + ident)) + (arrayType ^ maybeType ^ dictType ^ structType)).setParseAction(handleNameableType)

typeSpec <<= basicType  ^ variantType ^ namedType ^ nameableType

typeDef = (Suppress(Keyword("type")) + ident + typeSpec + SEMI).setParseAction(lambda toks: TypeDef(toks[0], toks[1]))

typeDefs = ZeroOrMore(typeDef).ignore(cppStyleComment)

def generate(typedefs, filename):
    generate_header(filename)
    generated = {}
    for td in typedefs:
        td.generate(generated)
    generate_footer(filename)

if __name__ == "__main__":
    parser = argparse.ArgumentParser(description='Generate variant accessors.')
    parser.add_argument('--prefix', help='prefix')
    parser.add_argument('--outfile', help='output filename')
    parser.add_argument('--outfile-header', help='output filename')
    parser.add_argument('--internal-validation', help='enable internal validation', action='store_true')
    parser.add_argument('file')
    args = parser.parse_args()
    if args.prefix:
        typename_prefix = snake_case_to_CamelCase(args.prefix)
        funcname_prefix = args.prefix + "_"
    if args.outfile:
        output_file = open(args.outfile, "w")
        output_h_file = output_file
    if args.outfile_header:
        output_h_file = open(args.outfile_header, "w")

    internal_validation = args.internal_validation

    with open(args.file, "r") as f:
        testdata = f.read()
        try:
            typedefs = typeDefs.parseString(testdata, parseAll=True)
            generate(typedefs, os.path.basename(args.file))
        except ParseException as pe:
            print("Parse error:", pe)
            sys.exit(1)

===== ./subprojects/variant-schema-compiler/TODO.md =====
TODO:
 * Add more tests
 * More attributes: untrusted

Maybe TODO:
 * Add more optional checking (out of bounds, validity, etc)

===== ./subprojects/variant-schema-compiler/sample.c =====
#define SAMPLE_DEEP_VARIANT_FORMAT
#include "sample.h"
#include "sample-impl.h"

void
test_sample_variant (GVariant *v)
{
  SampleTestRef t;
  SampleVarRef var;
  GVariant *varv;
  const char *res;
  gint32 resi;
  SampleVariantRef resv;

  g_print ("sample type: %s\n", g_variant_get_type_string (v));
  g_print ("sample: %s\n", g_variant_print (v, FALSE));
  g_print ("sample with types: %s\n", g_variant_print (v, TRUE));

  g_assert (g_variant_type_equal (g_variant_get_type(v), SAMPLE_TEST_TYPEFORMAT));

  t = sample_test_from_gvariant (v);
  g_print ("custom: %s\n", sample_test_print (t, FALSE));
  g_print ("custom with types: %s\n", sample_test_print (t, TRUE));

  g_assert_cmpstr (g_variant_print (v, FALSE), ==, sample_test_print (t, FALSE));
  g_assert_cmpstr (g_variant_print (v, TRUE), ==, sample_test_print (t, TRUE));

  var = sample_var_from_variant(sample_test_get_v(t));
  varv = g_variant_get_variant (g_variant_get_child_value (v, SAMPLE_TEST_INDEXOF_V));
  g_assert_cmpstr (g_variant_print (varv, TRUE), ==, sample_var_print (var, TRUE));

  SampleTestD1Ref d1 = sample_test_get_d1(t);
  GVariant *v2 = sample_test_d1_dup_to_gvariant(d1);
  g_assert_cmpstr (g_variant_print (v2, TRUE), ==, sample_test_d1_print(d1, FALSE));

  g_assert (!sample_test_d1_lookup(d1, 0,NULL , &resi));
  g_assert (sample_test_d1_lookup(d1, 1,NULL , &resi));
  g_assert_cmpint (resi, ==, 2);
  g_assert (!sample_test_d1_lookup(d1, 2,NULL , &resi));
  g_assert (sample_test_d1_lookup(d1, 3,NULL , &resi));
  g_assert_cmpint (resi, ==, 4);
  g_assert (!sample_test_d1_lookup(d1, 4,NULL , &resi));
  g_assert (sample_test_d1_lookup(d1, 5,NULL , &resi));
  g_assert_cmpint (resi, ==, 6);
  g_assert (!sample_test_d1_lookup(d1, 6,NULL , &resi));

  SampleD1sRef d1s = sample_test_get_d1s(t);
  GVariant *v2s = sample_d1s_dup_to_gvariant(d1s);
  g_assert_cmpstr (g_variant_print (v2s, TRUE), ==, sample_d1s_print(d1s, FALSE));

  g_assert (!sample_d1s_lookup(d1s, 0,NULL , &resi));
  g_assert (sample_d1s_lookup(d1s, 1,NULL , &resi));
  g_assert_cmpint (resi, ==, 2);
  g_assert (!sample_d1s_lookup(d1s, 2,NULL , &resi));
  g_assert (sample_d1s_lookup(d1s, 3,NULL , &resi));
  g_assert_cmpint (resi, ==, 4);
  g_assert (!sample_d1s_lookup(d1s, 4,NULL , &resi));
  g_assert (sample_d1s_lookup(d1s, 5,NULL , &resi));
  g_assert_cmpint (resi, ==, 6);
  g_assert (!sample_d1s_lookup(d1s, 6,NULL , &resi));

  SampleD2Ref d2 = sample_test_get_d2(t);
  GVariant *v3 = sample_d2_dup_to_gvariant(d2);
  g_assert_cmpstr (g_variant_print (v3, TRUE), ==, sample_d2_print(d2, FALSE));

  g_assert (sample_d2_lookup(d2, 1,NULL , &res));
  g_assert_cmpstr (res, ==, "a");
  g_assert (sample_d2_lookup(d2, 3,NULL , &res));
  g_assert_cmpstr (res, ==, "b");
  g_assert (!sample_d2_lookup(d2, 2,NULL , &res));

  SampleMetadataRef meta = sample_test_get_meta(t);
  GVariant *meta_v = sample_metadata_dup_to_gvariant(meta);

  g_assert (g_variant_type_equal (g_variant_get_type(meta_v), SAMPLE_METADATA_TYPEFORMAT));
  g_assert_cmpstr (g_variant_print (meta_v, FALSE), ==, sample_metadata_print (meta, FALSE));
  g_assert_cmpstr (g_variant_print (meta_v, TRUE), ==, sample_metadata_print (meta, TRUE));

  g_assert (sample_metadata_lookup(meta, "bar",NULL , &resv));
  g_assert_cmpstr ("<1>", ==, sample_variant_print (resv, TRUE));
  g_assert (sample_metadata_lookup(meta, "foo",NULL , &resv));
  g_assert_cmpstr ("<'s'>", ==, sample_variant_print (resv, TRUE));
  g_assert (!sample_metadata_lookup(meta, "missing",NULL , &resv));

  SampleSortedMetadataRef metas = sample_test_get_metas(t);
  GVariant *metas_v = sample_sorted_metadata_dup_to_gvariant(metas);

  g_assert (g_variant_type_equal (g_variant_get_type(metas_v), SAMPLE_SORTED_METADATA_TYPEFORMAT));
  g_assert_cmpstr (g_variant_print (metas_v, FALSE), ==, sample_sorted_metadata_print (metas, FALSE));
  g_assert_cmpstr (g_variant_print (metas_v, TRUE), ==, sample_sorted_metadata_print (metas, TRUE));

  g_assert (!sample_sorted_metadata_lookup(metas, "aaa",NULL , &resv));
  g_assert (sample_sorted_metadata_lookup(metas, "bar",NULL , &resv));
  g_assert_cmpstr ("<1>", ==, sample_variant_print (resv, TRUE));
  g_assert (!sample_sorted_metadata_lookup(metas, "ccc",NULL , &resv));
  g_assert (sample_sorted_metadata_lookup(metas, "foo",NULL , &resv));
  g_assert_cmpstr ("<'s'>", ==, sample_variant_print (resv, TRUE));
  g_assert (!sample_sorted_metadata_lookup(metas, "dddmissing",NULL , &resv));
}

int
main (int argc,
      char *argv[])
{
  GVariant *v;

#define DATA \
  "([32, 22], '%s', uint16 16, "                                        \
    "('s2', 322), ('ssss2', 3222), (323,), 324, "                       \
    "<(int16 67, 1023, byte 3, (uint16 5, byte 6))>, "                                          \
    "[(int16 68, 1025, byte 42, (uint16 7, byte 8)), (int16 69, 1026, byte 42, (uint16 9, byte 11))]"                              \
    ", {1:2, 3:4, 5:6}, {1:2, 3:4, 5:6}, {'bar': <1>, 'foo': <'s'>}, {'bar': <1>, 'foo': <'s'>}, {1:'a', 3:'b'}, "        \
    "just (objectpath '/', signature 's', true, handle 3, int64 88, uint64 89, 3.1415 )"             \
    ")"

  v = g_variant_new_parsed (g_strdup_printf (DATA, "s"));
  test_sample_variant(v);

  /* Try with larger offsets */
  v = g_variant_new_parsed (g_strdup_printf (DATA, "sxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"));
  test_sample_variant(v);
}

===== ./subprojects/variant-schema-compiler/Makefile =====
PREFIX = /usr/local
CC ?= gcc
CFLAGS ?= -g -Wall
PKG_CONFIG ?= pkg-config
GLIB_CFLAGS = `$(PKG_CONFIG) --cflags glib-2.0`
GLIB_LIBS = `$(PKG_CONFIG) --libs glib-2.0`

all: sample ostree_test performance selftests

sample.h: variant-schema-compiler sample.gv
	./variant-schema-compiler --internal-validation --outfile sample-impl.h --outfile-header=sample.h --prefix=sample sample.gv

sample: sample.c sample.h
	$(CC) $(GLIB_CFLAGS) $(CFLAGS) -o sample sample.c $(GLIB_LIBS)

performance.h: variant-schema-compiler performance.gv
	./variant-schema-compiler --outfile performance.h --prefix=performance performance.gv

performance: performance.c performance.h
	$(CC) $(GLIB_CFLAGS) $(CFLAGS) -O2 -o performance performance.c $(GLIB_LIBS)

ostree_test.h: variant-schema-compiler ostree.gv
	./variant-schema-compiler --outfile ostree_test.h --prefix=ot ostree.gv

ostree_test: ostree_test.c ostree_test.h
	$(CC) $(GLIB_CFLAGS) $(CFLAGS) -o ostree_test ostree_test.c $(GLIB_LIBS)

selftests: selftests.c ostree_test.h
	$(CC) $(GLIB_CFLAGS) $(CFLAGS) -o selftests -O2 selftests.c $(GLIB_LIBS)

clean:
	rm -f sample.h sample performance.h performance ostree_test.h ostree_test

.PHONY: install
install: variant-schema-compiler
	mkdir -p $(DESTDIR)$(PREFIX)/bin
	install -T $< $(DESTDIR)$(PREFIX)/bin/variant-schema-compiler

.PHONY: uninstall
uninstall:
	rm -f $(DESTDIR)$(PREFIX)/bin/variant-schema-compiler

===== ./subprojects/variant-schema-compiler/performance.c =====
#include "performance.h"

gint32
sum_gvariant (GVariant *v)
{
  guint32 sum;
  gint16 a;
  gint32 b;
  const char *c;
  GVariant *list;
  guchar d;
  guint16 tuple_a;
  guchar tuple_b;
  gsize len, i;
  gint32 list_a;
  guint16 list_b;

  g_variant_get (v, "(ni&s@a(iq)y(qy))",
                 &a, &b, &c, &list, &d, &tuple_a, &tuple_b);
  sum = a + b + strlen(c) + d + tuple_a + tuple_b;

  len = g_variant_n_children (list);
  for (i = 0; i < len; i++)
    {
      g_variant_get_child (list, i, "(iq)", &list_a, &list_b);
      sum += list_a + list_b;
    }

  return sum;
}

gint32
sum_generated (PerformanceContainerRef v)
{
  guint32 sum;
  PerformanceTupleRef tuple;
  PerformanceListRef list;
  PerformanceItemRef item;
  gsize len, i;

  tuple = performance_container_get_tuple (v);
  sum = performance_container_get_a(v) +
    performance_container_get_b(v) +
    strlen(performance_container_get_c(v)) +
    performance_container_get_d(v) +
    performance_tuple_get_a (tuple) +
    performance_tuple_get_b (tuple);

  list = performance_container_get_list (v);
  len = performance_list_get_length (list);
  for (i = 0; i < len; i++)
    {
     item = performance_list_get_at (list, i);
     sum += performance_item_get_a (item) + performance_item_get_b (item);
    }

  return sum;
}


int
main (int argc,
      char *argv[])
{
  GVariant *v;
  gconstpointer serialized_data;
  int i, count = 100000;
  guint64 total;
  GTimer *timer = g_timer_new ();
  PerformanceContainerRef c;

#define DATA "(int16 17, 32, 'foobar', [(44, uint16 12), (48, uint16 14), (99, uint16 100)], byte 128, (uint16 4, byte 11))"

  v = g_variant_new_parsed (DATA);
  g_assert (g_variant_type_equal (g_variant_get_type (v), PERFORMANCE_CONTAINER_TYPEFORMAT));

  /* Ensure data is serialized */
  serialized_data = g_variant_get_data (v);

  /* Warmup */
  total = 0;
  for (i = 0; i < 10; i++)
    total += sum_gvariant (v);
  g_assert (total == 10 * 515);

  total = 0;
  g_timer_start (timer);
  for (i = 0; i < count; i++)
    {
      total += sum_gvariant (v);
      total += sum_gvariant (v);
      total += sum_gvariant (v);
      total += sum_gvariant (v);
      total += sum_gvariant (v);
    }
  g_timer_stop (timer);
  g_assert (total == 5 * count * 515);

  g_print ("GVariant performance: %.1f kiloiterations per second\n", (count/1000.0)/g_timer_elapsed (timer, NULL));

  c = performance_container_from_gvariant (v);

  /* Warmup */
  total = 0;
  for (i = 0; i < 10; i++)
    total += sum_generated (c);
  g_assert (total == 10 * 515);

  g_timer_reset (timer);

  total = 0;
  g_timer_start (timer);
  for (i = 0; i < count; i++)
    {
      total += sum_generated (c);
      total += sum_generated (c);
      total += sum_generated (c);
      total += sum_generated (c);
      total += sum_generated (c);
    }
  g_timer_stop (timer);
  g_assert (total == 5 * count * 515);

  g_print ("Generated performance: %.1f kiloiterations per second\n", (count/1000.0)/g_timer_elapsed (timer, NULL));

  return 0;
}

===== ./subprojects/variant-schema-compiler/performance.gv =====
type Container {
  a: int16;
  b: int32;
  c: string;
  list: 'List [] 'Item {
     a: int32;
     b: uint16;
  };
  d: byte;
  tuple : 'Tuple {
    a: uint16;
    b: byte;
  };
};

===== ./subprojects/variant-schema-compiler/ostree.gv =====
/* Commonly used, give a name */
type Metadata [string] variant;
type Checksum []byte;

type Summary {
    ref_map: [string] 'SummaryInfo {
        size: uint64;
        checksum: Checksum;
        metadata: Metadata;
    };
    metadata: Metadata;
};

type Commit {
    metadata: Metadata;
    parent: Checksum;
    related: [] 'Related {
        ref: string;
        commit: Checksum;
    };
    subject: string;
    body: string;
    timestamp: uint64;
    root_contents: Checksum;
    root_metadata: Checksum;
};

type TreeMeta {
  files: [] 'TreeFile {
    name: string;
    checksum: Checksum;
  };
  dirs: [] 'TreeDir {
    name: string;
    tree_checksum: Checksum;
    meta_checksum: Checksum;
  };
};

type Xattr {
  name: []byte;
  value: []byte;
};

type DirMeta {
  uid: bigendian uint32;
  gid: bigendian uint32;
  mode: bigendian uint32;
  xattrs: [] Xattr;
};

type FileMeta {
  uid: bigendian uint32;
  gid: bigendian uint32;
  mode: bigendian uint32;
  xattrs: [] Xattr;
};

type DeltaFallback {
  objtype: byte;
  checksum: Checksum;
  compressed_size: uint64; /* non-canonical endian */
  uncompressed_size: uint64; /* non-canonical endian */
};

type DeltaMetaEntry {
  version: uint32 ; /* non canonical endian */
  checksum: Checksum;
  size: uint64; /* non-canonical endian */
  usize: uint64; /* non-canonical endian */
  objects: [] 'DeltaObject {
    objtype: byte;
    object: Checksum;
  };
};

type DeltaSuperblock {
  metadata: Metadata;
  timestamp: bigendian uint64;
  from: Checksum;
  to: Checksum;
  commit: Commit;
  apply_before: [] 'DeltaName {
    from: Checksum;
    to: Checksum;
  };
  parts: []DeltaMetaEntry;
  fallbacks: []DeltaFallback;
};

type DeltaPayload {
  modes: [] 'DeltaMode {
      uid: uint32;
      gid: uint32;
      mode: uint32;
  };
  xattrs: [][]Xattr;
  raw_data: []byte;
  operations: []byte;
};

===== ./subprojects/variant-schema-compiler/ostree_test.c =====
#include "ostree_test.h"

static void
handle (char *filename)
{
  g_autoptr(GError) error = NULL;
  g_autofree char *contents = NULL;
  gsize size;

  if (!g_file_get_contents (filename, &contents, &size, &error))
    {
      g_print ("Failed to load %s: %s\n", filename, error->message);
      return;
    }

  if (g_str_has_suffix (filename, ".commit"))
    {
      OtCommitRef commit = ot_commit_from_data (contents, size);
      g_autofree char *s = ot_commit_print (commit, TRUE);
      g_print ("%s: %s\n", filename, s);
    }
  else if (g_str_has_suffix (filename, ".dirtree"))
    {
      OtTreeMetaRef tree = ot_tree_meta_from_data (contents, size);
      g_autofree char *s = ot_tree_meta_print (tree, TRUE);
      g_print ("%s: %s\n", filename, s);
    }
  else if (g_str_has_suffix (filename, ".dirmeta"))
    {
      OtDirMetaRef dir = ot_dir_meta_from_data (contents, size);
      g_autofree char *s = ot_dir_meta_print (dir, TRUE);
      g_print ("%s: %s\n", filename, s);
    }
  else if (g_str_has_suffix (filename, "summary"))
    {
      OtSummaryRef summary = ot_summary_from_data (contents, size);
      g_autofree char *s = ot_summary_print (summary, TRUE);
      g_print ("%s: %s\n", filename, s);
    }
  else
    {
      g_print ("Unknown type %s\n", filename);
    }
}


int
main (int argc,
      char *argv[])
{
  for (int i = 1; i < argc; i++)
    handle (argv[i]);

  return 0;
}

===== ./subprojects/variant-schema-compiler/sample.gv =====
type Metadata [string] variant;
type SortedMetadata [sorted string] variant;

type Var {
  foo: int16;
  bar: int32;
  b: byte;
  the_rest: {
    gazonk: uint16;
    b: byte;
  };
};

type Test {
  foo: []int32;
  s: string;
  sh: uint16;
  sub: 'Sub {
    str: string;
    bar: int32;
  };
  subagain: Sub;
  sub2: 'Sub2 {
    bar: int32;
  };
  bar: int32;
  v: variant;
  arr: []Var;
  d1: [int32]int32;
  d1s: 'D1s [sorted int32]int32; /* Sorted, so we can test binary search fixed lookup */
  meta: Metadata;
  metas: SortedMetadata;
  d2: 'D2 [int32]string;
  optional: ? 'Optional {
    op: objectpath;
    s: signature;
    b: boolean;
    h: handle;
    large: int64;
    larger: uint64;
    pi: double;
  };
};

type LotsOfDicts {
 foo: [byte]int16;
 foo2: [int16]{a: int32;};
};

type Endian {
  little: littleendian uint16;
  big: bigendian int32;
};

===== ./subprojects/variant-schema-compiler/.gitignore =====
ostree_test
ostree_test.h
sample
sample.h
performance
performance.h

===== ./subprojects/variant-schema-compiler/selftests.c =====
#include "ostree_test.h"


static guint
slow_get_offset_size (gsize size)
{
  if (size > G_MAXUINT16)
    {
      if (size > G_MAXUINT32)
        return 8;
      else
        return 4;
    }
  else
    {
      if (size > G_MAXUINT8)
         return 2;
      else
         return 1;
    }
}

int
main (int argc,
      char *argv[])
{
  g_print ("Validating ot_ref_get_offset_size up to G_MAXUINT32\n");
  for (gsize i = 1; i < G_MAXUINT32; i++)
    {
      guint res = ot_ref_get_offset_size (i);
      if (res != slow_get_offset_size (i))
        {
          g_print ("failed: ot_ref_get_offset_size (%"G_GSIZE_FORMAT") == %d, should be %d\n", i, res, slow_get_offset_size (i));
          exit (1);
        }
    }

#if GLIB_SIZEOF_SIZE_T > 4
  g_print ("Validating ot_ref_get_offset_size up to 2*G_MAXUINT32\n");
  for (gsize i = (gsize)G_MAXUINT32; i < (gsize)G_MAXUINT32 * 2; i++)
    {
      guint res = ot_ref_get_offset_size (i);
      if (res != slow_get_offset_size (i))
        {
          g_print ("failed: ot_ref_get_offset_size (%"G_GSIZE_FORMAT") == %d, should be %d\n", i, res, slow_get_offset_size (i));
          exit (1);
        }
    }
#endif

  return 0;
}

===== ./subprojects/libglnx/libglnx.h =====
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
 *
 * Copyright (C) 2012,2013,2015 Colin Walters <walters@verbum.org>.
 * SPDX-License-Identifier: LGPL-2.0-or-later
 *
 * 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 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., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

#pragma once

#include <gio/gio.h>

G_BEGIN_DECLS

#include <glnx-macros.h>
#include <glnx-missing.h>
#include <glnx-local-alloc.h>
#include <glnx-backport-autocleanups.h>
#include <glnx-backport-testutils.h>
#include <glnx-backports.h>
#include <glnx-chase.h>
#include <glnx-lockfile.h>
#include <glnx-errors.h>
#include <glnx-dirfd.h>
#include <glnx-shutil.h>
#include <glnx-xattrs.h>
#include <glnx-console.h>
#include <glnx-fdio.h>

G_END_DECLS

===== ./subprojects/libglnx/COPYING =====
This project's licensing is REUSE-compliant <https://reuse.software/>.
See individual files for full details of copyright and licensing,
and see LICENSES/*.txt for the license text.

===== ./subprojects/libglnx/glnx-missing-syscall.h =====
/***
  This file was originally part of systemd.

  Copyright 2010 Lennart Poettering
  Copyright 2016 Zbigniew Jędrzejewski-Szmek
  SPDX-License-Identifier: LGPL-2.1-or-later

  systemd 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.

  systemd 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 systemd; If not, see <http://www.gnu.org/licenses/>.
***/

/* Missing glibc definitions to access certain kernel APIs.
   This file is last updated from systemd git:

   commit 71e5200f94b22589922704aa4abdf95d4fe2e528
   Author:     Daniel Mack <daniel@zonque.org>
   AuthorDate: Tue Oct 18 17:57:10 2016 +0200
   Commit:     Lennart Poettering <lennart@poettering.net>
   CommitDate: Fri Sep 22 15:24:54 2017 +0200

   Add abstraction model for BPF programs
*/

#include "libglnx-config.h"
#include <glib.h>
#include <stdint.h>

#if !HAVE_DECL_RENAMEAT2
#  ifndef __NR_renameat2
#    if defined __x86_64__
#      define __NR_renameat2 316
#    elif defined __arm__
#      define __NR_renameat2 382
#    elif defined __aarch64__
#      define __NR_renameat2 276
#    elif defined _MIPS_SIM
#      if _MIPS_SIM == _MIPS_SIM_ABI32
#        define __NR_renameat2 4351
#      endif
#      if _MIPS_SIM == _MIPS_SIM_NABI32
#        define __NR_renameat2 6315
#      endif
#      if _MIPS_SIM == _MIPS_SIM_ABI64
#        define __NR_renameat2 5311
#      endif
#    elif defined __i386__
#      define __NR_renameat2 353
#    elif defined __powerpc64__
#      define __NR_renameat2 357
#    elif defined __s390__ || defined __s390x__
#      define __NR_renameat2 347
#    elif defined __arc__
#      define __NR_renameat2 276
#    else
#      warning "__NR_renameat2 unknown for your architecture"
#    endif
#  endif

static inline int renameat2(int oldfd, const char *oldname, int newfd, const char *newname, unsigned flags) {
#  ifdef __NR_renameat2
        return syscall(__NR_renameat2, oldfd, oldname, newfd, newname, flags);
#  else
        errno = ENOSYS;
        return -1;
#  endif
}
#endif

#if !HAVE_DECL_MEMFD_CREATE
#  ifndef __NR_memfd_create
#    if defined __x86_64__
#      define __NR_memfd_create 319
#    elif defined __arm__
#      define __NR_memfd_create 385
#    elif defined __aarch64__
#      define __NR_memfd_create 279
#    elif defined __s390__
#      define __NR_memfd_create 350
#    elif defined _MIPS_SIM
#      if _MIPS_SIM == _MIPS_SIM_ABI32
#        define __NR_memfd_create 4354
#      endif
#      if _MIPS_SIM == _MIPS_SIM_NABI32
#        define __NR_memfd_create 6318
#      endif
#      if _MIPS_SIM == _MIPS_SIM_ABI64
#        define __NR_memfd_create 5314
#      endif
#    elif defined __i386__
#      define __NR_memfd_create 356
#    elif defined __arc__
#      define __NR_memfd_create 279
#    else
#      warning "__NR_memfd_create unknown for your architecture"
#    endif
#  endif

static inline int memfd_create(const char *name, unsigned int flags) {
#  ifdef __NR_memfd_create
        return syscall(__NR_memfd_create, name, flags);
#  else
        errno = ENOSYS;
        return -1;
#  endif
}
#endif

/* Copied from systemd git:
   commit 6bda23dd6aaba50cf8e3e6024248cf736cc443ca
   Author:     Yu Watanabe <watanabe.yu+github@gmail.com>
   AuthorDate: Thu Jul 27 20:22:54 2017 +0900
   Commit:     Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
   CommitDate: Thu Jul 27 07:22:54 2017 -0400
*/
#if !HAVE_DECL_COPY_FILE_RANGE
#  ifndef __NR_copy_file_range
#    if defined(__x86_64__)
#      define __NR_copy_file_range 326
#    elif defined(__i386__)
#      define __NR_copy_file_range 377
#    elif defined __s390__
#      define __NR_copy_file_range 375
#    elif defined __arm__
#      define __NR_copy_file_range 391
#    elif defined __aarch64__
#      define __NR_copy_file_range 285
#    elif defined __powerpc__
#      define __NR_copy_file_range 379
#    elif defined __arc__
#      define __NR_copy_file_range 285
#    else
#      warning "__NR_copy_file_range not defined for your architecture"
#    endif
#  endif

static inline ssize_t missing_copy_file_range(int fd_in, loff_t *off_in,
                                              int fd_out, loff_t *off_out,
                                              size_t len,
                                              unsigned int flags) {
#  ifdef __NR_copy_file_range
        return syscall(__NR_copy_file_range, fd_in, off_in, fd_out, off_out, len, flags);
#  else
        errno = ENOSYS;
        return -1;
#  endif
}

#  define copy_file_range missing_copy_file_range
#endif

#ifndef __IGNORE_close_range
#  if defined(__aarch64__)
#    define systemd_NR_close_range 436
#  elif defined(__alpha__)
#    define systemd_NR_close_range 546
#  elif defined(__arc__) || defined(__tilegx__)
#    define systemd_NR_close_range 436
#  elif defined(__arm__)
#    define systemd_NR_close_range 436
#  elif defined(__i386__)
#    define systemd_NR_close_range 436
#  elif defined(__ia64__)
#    define systemd_NR_close_range 1460
#  elif defined(__loongarch_lp64)
#    define systemd_NR_close_range 436
#  elif defined(__m68k__)
#    define systemd_NR_close_range 436
#  elif defined(_MIPS_SIM)
#    if _MIPS_SIM == _MIPS_SIM_ABI32
#      define systemd_NR_close_range 4436
#    elif _MIPS_SIM == _MIPS_SIM_NABI32
#      define systemd_NR_close_range 6436
#    elif _MIPS_SIM == _MIPS_SIM_ABI64
#      define systemd_NR_close_range 5436
#    else
#      error "Unknown MIPS ABI"
#    endif
#  elif defined(__hppa__)
#    define systemd_NR_close_range 436
#  elif defined(__powerpc__)
#    define systemd_NR_close_range 436
#  elif defined(__riscv)
#    if __riscv_xlen == 32
#      define systemd_NR_close_range 436
#    elif __riscv_xlen == 64
#      define systemd_NR_close_range 436
#    else
#      error "Unknown RISC-V ABI"
#    endif
#  elif defined(__s390__)
#    define systemd_NR_close_range 436
#  elif defined(__sparc__)
#    define systemd_NR_close_range 436
#  elif defined(__x86_64__)
#    if defined(__ILP32__)
#      define systemd_NR_close_range (436 | /* __X32_SYSCALL_BIT */ 0x40000000)
#    else
#      define systemd_NR_close_range 436
#    endif
#  elif !defined(missing_arch_template)
#    warning "close_range() syscall number is unknown for your architecture"
#  endif

/* may be an (invalid) negative number due to libseccomp, see PR 13319 */
#  if defined __NR_close_range && __NR_close_range >= 0
#    if defined systemd_NR_close_range
G_STATIC_ASSERT(__NR_close_range == systemd_NR_close_range);
#    endif
#  else
#    if defined __NR_close_range
#      undef __NR_close_range
#    endif
#    if defined systemd_NR_close_range && systemd_NR_close_range >= 0
#      define __NR_close_range systemd_NR_close_range
#    endif
#  endif
#endif

#if !defined(HAVE_CLOSE_RANGE) && defined(__NR_close_range)
static inline int
inline_close_range (unsigned int low,
                    unsigned int high,
                    int flags)
{
  return syscall (__NR_close_range, low, high, flags);
}
#define close_range(low, high, flags) inline_close_range(low, high, flags)
#define HAVE_CLOSE_RANGE
#endif

#ifndef __IGNORE_statx
#  if defined(__aarch64__)
#    define systemd_NR_statx 291
#  elif defined(__alpha__)
#    define systemd_NR_statx 522
#  elif defined(__arc__) || defined(__tilegx__)
#    define systemd_NR_statx 291
#  elif defined(__arm__)
#    define systemd_NR_statx 397
#  elif defined(__i386__)
#    define systemd_NR_statx 383
#  elif defined(__ia64__)
#    define systemd_NR_statx 1350
#  elif defined(__loongarch_lp64)
#    define systemd_NR_statx 291
#  elif defined(__m68k__)
#    define systemd_NR_statx 379
#  elif defined(_MIPS_SIM)
#    if _MIPS_SIM == _MIPS_SIM_ABI32
#      define systemd_NR_statx 4366
#    elif _MIPS_SIM == _MIPS_SIM_NABI32
#      define systemd_NR_statx 6330
#    elif _MIPS_SIM == _MIPS_SIM_ABI64
#      define systemd_NR_statx 5326
#    else
#      error "Unknown MIPS ABI"
#    endif
#  elif defined(__hppa__)
#    define systemd_NR_statx 349
#  elif defined(__powerpc__)
#    define systemd_NR_statx 383
#  elif defined(__riscv)
#    if __riscv_xlen == 32
#      define systemd_NR_statx 291
#    elif __riscv_xlen == 64
#      define systemd_NR_statx 291
#    else
#      error "Unknown RISC-V ABI"
#    endif
#  elif defined(__s390__)
#    define systemd_NR_statx 379
#  elif defined(__sparc__)
#    define systemd_NR_statx 360
#  elif defined(__x86_64__)
#    if defined(__ILP32__)
#      define systemd_NR_statx (332 | /* __X32_SYSCALL_BIT */ 0x40000000)
#    else
#      define systemd_NR_statx 332
#    endif
#  elif !defined(missing_arch_template)
#    warning "statx() syscall number is unknown for your architecture"
#  endif

/* may be an (invalid) negative number due to libseccomp, see PR 13319 */
#  if defined __NR_statx && __NR_statx >= 0
#    if defined systemd_NR_statx
G_STATIC_ASSERT (__NR_statx == systemd_NR_statx);
#    endif
#  else
#    if defined __NR_statx
#      undef __NR_statx
#    endif
#    if defined systemd_NR_statx && systemd_NR_statx >= 0
#      define __NR_statx systemd_NR_statx
#    endif
#  endif
#endif

#if !defined(HAVE_GLNX_STATX) && defined(__NR_statx)
#define GLNX_STATX_TYPE              0x00000001U     /* Want/got stx_mode & S_IFMT */
#define GLNX_STATX_MODE              0x00000002U     /* Want/got stx_mode & ~S_IFMT */
#define GLNX_STATX_NLINK             0x00000004U     /* Want/got stx_nlink */
#define GLNX_STATX_UID               0x00000008U     /* Want/got stx_uid */
#define GLNX_STATX_GID               0x00000010U     /* Want/got stx_gid */
#define GLNX_STATX_ATIME             0x00000020U     /* Want/got stx_atime */
#define GLNX_STATX_MTIME             0x00000040U     /* Want/got stx_mtime */
#define GLNX_STATX_CTIME             0x00000080U     /* Want/got stx_ctime */
#define GLNX_STATX_INO               0x00000100U     /* Want/got stx_ino */
#define GLNX_STATX_SIZE              0x00000200U     /* Want/got stx_size */
#define GLNX_STATX_BLOCKS            0x00000400U     /* Want/got stx_blocks */
#define GLNX_STATX_BASIC_STATS       0x000007ffU     /* The stuff in the normal stat struct */
#define GLNX_STATX_BTIME             0x00000800U     /* Want/got stx_btime */
#define GLNX_STATX_MNT_ID            0x00001000U     /* Got stx_mnt_id */
#define GLNX_STATX_DIOALIGN          0x00002000U     /* Want/got direct I/O alignment info */
#define GLNX_STATX_MNT_ID_UNIQUE     0x00004000U     /* Want/got extended stx_mount_id */
#define GLNX_STATX_SUBVOL            0x00008000U     /* Want/got stx_subvol */
#define GLNX_STATX_WRITE_ATOMIC      0x00010000U     /* Want/got atomic_write_* fields */
#define GLNX_STATX_DIO_READ_ALIGN    0x00020000U     /* Want/got dio read alignment info */
#define GLNX_STATX__RESERVED         0x80000000U     /* Reserved for future struct statx expansion */

struct glnx_statx_timestamp
{
  int64_t tv_sec;
  uint32_t tv_nsec;
  int32_t __reserved;
};

struct glnx_statx
{
  uint32_t stx_mask;
  uint32_t stx_blksize;
  uint64_t stx_attributes;
  uint32_t stx_nlink;
  uint32_t stx_uid;
  uint32_t stx_gid;
  uint16_t stx_mode;
  uint16_t __spare0[1];
  uint64_t stx_ino;
  uint64_t stx_size;
  uint64_t stx_blocks;
  uint64_t stx_attributes_mask;
  struct glnx_statx_timestamp stx_atime;
  struct glnx_statx_timestamp stx_btime;
  struct glnx_statx_timestamp stx_ctime;
  struct glnx_statx_timestamp stx_mtime;
  uint32_t stx_rdev_major;
  uint32_t stx_rdev_minor;
  uint32_t stx_dev_major;
  uint32_t stx_dev_minor;
  uint64_t stx_mnt_id;
  uint32_t stx_dio_mem_align;
  uint32_t stx_dio_offset_align;
  uint64_t stx_subvol;
  uint32_t stx_atomic_write_unit_min;
  uint32_t stx_atomic_write_unit_max;
  uint32_t stx_atomic_write_segments_max;
  uint32_t stx_dio_read_offset_align;
  uint32_t stx_atomic_write_unit_max_opt;
  uint32_t	__spare2[1];
  uint64_t	__spare3[8];
};

static inline int
glnx_statx_syscall (int                dfd,
                    const char        *filename,
                    unsigned           flags,
                    unsigned int       mask,
                    struct glnx_statx *buf)
{
	memset (buf, 0xbf, sizeof (*buf));
	return syscall (__NR_statx, dfd, filename, flags, mask, buf);
  return 0;
}

#define HAVE_GLNX_STATX
#endif

/* Copied from systemd git: ff83795469 ("boot: Improve log message")
 * - open_tree
 * - openat2
 */

#ifndef __IGNORE_open_tree
#  if defined(__aarch64__)
#    define systemd_NR_open_tree 428
#  elif defined(__alpha__)
#    define systemd_NR_open_tree 538
#  elif defined(__arc__) || defined(__tilegx__)
#    define systemd_NR_open_tree 428
#  elif defined(__arm__)
#    define systemd_NR_open_tree 428
#  elif defined(__i386__)
#    define systemd_NR_open_tree 428
#  elif defined(__ia64__)
#    define systemd_NR_open_tree 1452
#  elif defined(__loongarch_lp64)
#    define systemd_NR_open_tree 428
#  elif defined(__m68k__)
#    define systemd_NR_open_tree 428
#  elif defined(_MIPS_SIM)
#    if _MIPS_SIM == _MIPS_SIM_ABI32
#      define systemd_NR_open_tree 4428
#    elif _MIPS_SIM == _MIPS_SIM_NABI32
#      define systemd_NR_open_tree 6428
#    elif _MIPS_SIM == _MIPS_SIM_ABI64
#      define systemd_NR_open_tree 5428
#    else
#      error "Unknown MIPS ABI"
#    endif
#  elif defined(__hppa__)
#    define systemd_NR_open_tree 428
#  elif defined(__powerpc__)
#    define systemd_NR_open_tree 428
#  elif defined(__riscv)
#    if __riscv_xlen == 32
#      define systemd_NR_open_tree 428
#    elif __riscv_xlen == 64
#      define systemd_NR_open_tree 428
#    else
#      error "Unknown RISC-V ABI"
#    endif
#  elif defined(__s390__)
#    define systemd_NR_open_tree 428
#  elif defined(__sparc__)
#    define systemd_NR_open_tree 428
#  elif defined(__x86_64__)
#    if defined(__ILP32__)
#      define systemd_NR_open_tree (428 | /* __X32_SYSCALL_BIT */ 0x40000000)
#    else
#      define systemd_NR_open_tree 428
#    endif
#  elif !defined(missing_arch_template)
#    warning "open_tree() syscall number is unknown for your architecture"
#  endif

/* may be an (invalid) negative number due to libseccomp, see PR 13319 */
#  if defined __NR_open_tree && __NR_open_tree >= 0
#    if defined systemd_NR_open_tree
G_STATIC_ASSERT (__NR_open_tree == systemd_NR_open_tree);
#    endif
#  else
#    if defined __NR_open_tree
#      undef __NR_open_tree
#    endif
#    if defined systemd_NR_open_tree && systemd_NR_open_tree >= 0
#      define __NR_open_tree systemd_NR_open_tree
#    endif
#  endif
#endif

#if !defined(HAVE_OPEN_TREE) && defined(__NR_open_tree)
#ifndef OPEN_TREE_CLONE
#define OPEN_TREE_CLONE 1
#endif

#ifndef OPEN_TREE_CLOEXEC
#define OPEN_TREE_CLOEXEC O_CLOEXEC
#endif

static inline int
inline_open_tree (int         dfd,
                  const char *filename,
                  unsigned    flags)
{
  return syscall(__NR_open_tree, dfd, filename, flags);
}
#define open_tree inline_open_tree
#define HAVE_OPEN_TREE
#endif

#ifndef __IGNORE_openat2
#  if defined(__aarch64__)
#    define systemd_NR_openat2 437
#  elif defined(__alpha__)
#    define systemd_NR_openat2 547
#  elif defined(__arc__) || defined(__tilegx__)
#    define systemd_NR_openat2 437
#  elif defined(__arm__)
#    define systemd_NR_openat2 437
#  elif defined(__i386__)
#    define systemd_NR_openat2 437
#  elif defined(__ia64__)
#    define systemd_NR_openat2 1461
#  elif defined(__loongarch_lp64)
#    define systemd_NR_openat2 437
#  elif defined(__m68k__)
#    define systemd_NR_openat2 437
#  elif defined(_MIPS_SIM)
#    if _MIPS_SIM == _MIPS_SIM_ABI32
#      define systemd_NR_openat2 4437
#    elif _MIPS_SIM == _MIPS_SIM_NABI32
#      define systemd_NR_openat2 6437
#    elif _MIPS_SIM == _MIPS_SIM_ABI64
#      define systemd_NR_openat2 5437
#    else
#      error "Unknown MIPS ABI"
#    endif
#  elif defined(__hppa__)
#    define systemd_NR_openat2 437
#  elif defined(__powerpc__)
#    define systemd_NR_openat2 437
#  elif defined(__riscv)
#    if __riscv_xlen == 32
#      define systemd_NR_openat2 437
#    elif __riscv_xlen == 64
#      define systemd_NR_openat2 437
#    else
#      error "Unknown RISC-V ABI"
#    endif
#  elif defined(__s390__)
#    define systemd_NR_openat2 437
#  elif defined(__sparc__)
#    define systemd_NR_openat2 437
#  elif defined(__x86_64__)
#    if defined(__ILP32__)
#      define systemd_NR_openat2 (437 | /* __X32_SYSCALL_BIT */ 0x40000000)
#    else
#      define systemd_NR_openat2 437
#    endif
#  elif !defined(missing_arch_template)
#    warning "openat2() syscall number is unknown for your architecture"
#  endif

/* may be an (invalid) negative number due to libseccomp, see PR 13319 */
#  if defined __NR_openat2 && __NR_openat2 >= 0
#    if defined systemd_NR_openat2
G_STATIC_ASSERT (__NR_openat2 == systemd_NR_openat2);
#    endif
#  else
#    if defined __NR_openat2
#      undef __NR_openat2
#    endif
#    if defined systemd_NR_openat2 && systemd_NR_openat2 >= 0
#      define __NR_openat2 systemd_NR_openat2
#    endif
#  endif
#endif

#if !defined(HAVE_OPENAT2) && defined(__NR_openat2)
#ifndef RESOLVE_NO_XDEV
#define RESOLVE_NO_XDEV 0x01
#endif

#ifndef RESOLVE_NO_MAGICLINKS
#define RESOLVE_NO_MAGICLINKS 0x02
#endif

#ifndef RESOLVE_NO_SYMLINKS
#define RESOLVE_NO_SYMLINKS 0x04
#endif

#ifndef RESOLVE_BENEATH
#define RESOLVE_BENEATH 0x08
#endif

#ifndef RESOLVE_IN_ROOT
#define RESOLVE_IN_ROOT 0x10
#endif

#ifndef RESOLVE_CACHED
#define RESOLVE_CACHED 0x20
#endif

struct inline_open_how {
        uint64_t flags;
        uint64_t mode;
        uint64_t resolve;
};
#define open_how inline_open_how

static inline int
inline_openat2 (int         dfd,
                const char *filename,
                void       *buffer,
                size_t      size)
{
  return syscall(__NR_openat2, dfd, filename, buffer, size);
}
#define openat2 inline_openat2
#define HAVE_OPENAT2
#endif

===== ./subprojects/libglnx/glnx-console.h =====
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
 *
 * Copyright (C) 2013,2014,2015 Colin Walters <walters@verbum.org>
 * SPDX-License-Identifier: LGPL-2.0-or-later
 *
 * This program 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 of the licence 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., 59 Temple Place, Suite 330,
 * Boston, MA 02111-1307, USA.
 */

#pragma once

#include <glnx-backport-autocleanups.h>

G_BEGIN_DECLS

struct GLnxConsoleRef {
  gboolean locked;
  gboolean is_tty;
};

typedef struct GLnxConsoleRef GLnxConsoleRef;

gboolean glnx_stdout_is_tty (void);

void	 glnx_console_lock (GLnxConsoleRef *ref);

void	 glnx_console_text (const char     *text);

void	 glnx_console_progress_text_percent (const char     *text,
                                           guint           percentage);

void	 glnx_console_progress_n_items (const char     *text,
                                      guint           current,
                                      guint           total);

void	 glnx_console_unlock (GLnxConsoleRef *ref);

guint    glnx_console_lines (void);

guint    glnx_console_columns (void);

static inline void
glnx_console_ref_cleanup (GLnxConsoleRef *p)
{
  if (p->locked)
    glnx_console_unlock (p);
}
G_DEFINE_AUTO_CLEANUP_CLEAR_FUNC(GLnxConsoleRef, glnx_console_ref_cleanup)

G_END_DECLS

===== ./subprojects/libglnx/README.md =====
libglnx is the successor to [libgsystem](https://gitlab.gnome.org/Archive/libgsystem).

It is for modules which depend on both GLib and Linux, intended to be
used as a git submodule.

Features:

 - File APIs which use `openat()` like APIs, but also take a `GCancellable`
   to support dynamic cancellation
 - APIs also have a `GError` parameter
 - High level "shutil", somewhat inspired by Python's
 - A "console" API for tty output
 - A backport of the GLib cleanup macros for projects which can't yet take
   a dependency on 2.40.

Why?
----

There are multiple projects which have a hard dependency on Linux and
GLib, such as NetworkManager, ostree, flatpak, etc.  It makes sense
for them to be able to share Linux-specific APIs.

This module also contains some code taken from systemd, which has very
high quality LGPLv2+ shared library code, but most of the internal
shared library is private, and not namespaced.

One could also compare this project to gnulib; the salient differences
there are that at least some of this module is eventually destined for
inclusion in GLib.

Adding this to your project
---------------------------

## Meson

First, set up a Git submodule:

```
git submodule add https://gitlab.gnome.org/GNOME/libglnx subprojects/libglnx
```

Or a Git [subtree](https://github.com/git/git/blob/master/contrib/subtree/git-subtree.txt):

```
git remote add libglnx https://gitlab.gnome.org/GNOME/libglnx.git
git fetch libglnx
git subtree add -P subprojects/libglnx libglnx/master
```

Then, in your top-level `meson.build`:

```
libglnx_dep = subproject('libglnx').get_variable('libglnx_dep')
# now use libglnx_dep in your dependencies
```

Porting from libgsystem
-----------------------

For all of the filesystem access code, libglnx exposes only
fd-relative API, not `GFile*`.  It does use `GCancellable` where
applicable.

For local allocation macros, you should start using the `g_auto`
macros from GLib.  A backport is included in libglnx.  There are a few
APIs not defined in GLib yet, such as `glnx_autofd`.

`gs_transfer_out_value` is replaced by `g_steal_pointer`.

Contributing
------------

Development happens in GNOME Gitlab: https://gitlab.gnome.org/GNOME/libglnx

(If you're seeing this on the Github mirror, we used to do development
 on Github but that was before GNOME deployed Gitlab.)

<!--
Copyright 2015-2018 Colin Walters
Copyright 2019 Endless OS Foundation LLC
SPDX-License-Identifier: LGPL-2.1-or-later
-->

===== ./subprojects/libglnx/glnx-fdio.c =====
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
 *
 * Copyright (C) 2014,2015 Colin Walters <walters@verbum.org>.
 * SPDX-License-Identifier: LGPL-2.0-or-later
 *
 * Portions derived from systemd:
 *  Copyright 2010 Lennart Poettering
 *
 * 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 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., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

#include "libglnx-config.h"

#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>
#include <sys/ioctl.h>
#include <sys/sendfile.h>
#include <errno.h>

#include <glnx-fdio.h>
#include <glnx-dirfd.h>
#include <glnx-errors.h>
#include <glnx-xattrs.h>
#include <glnx-backport-autoptr.h>
#include <glnx-backports.h>
#include <glnx-local-alloc.h>
#include <glnx-missing.h>

/* The standardized version of BTRFS_IOC_CLONE */
#ifndef FICLONE
#define FICLONE _IOW(0x94, 9, int)
#endif

/* Returns the number of chars needed to format variables of the
 * specified type as a decimal string. Adds in extra space for a
 * negative '-' prefix (hence works correctly on signed
 * types). Includes space for the trailing NUL. */
#define DECIMAL_STR_MAX(type)                                           \
        (2+(sizeof(type) <= 1 ? 3 :                                     \
            sizeof(type) <= 2 ? 5 :                                     \
            sizeof(type) <= 4 ? 10 :                                    \
            sizeof(type) <= 8 ? 20 : sizeof(int[-2*(sizeof(type) > 8)])))

gboolean
glnx_stdio_file_flush (FILE *f, GError **error)
{
  if (fflush (f) != 0)
    return glnx_throw_errno_prefix (error, "fflush");
  if (ferror (f) != 0)
    return glnx_throw_errno_prefix (error, "ferror");
  return TRUE;
}

/* An implementation of renameat2(..., RENAME_NOREPLACE)
 * with fallback to a non-atomic version.
 */
int
glnx_renameat2_noreplace (int olddirfd, const char *oldpath,
                          int newdirfd, const char *newpath)
{
#ifndef ENABLE_WRPSEUDO_COMPAT
  if (renameat2 (olddirfd, oldpath, newdirfd, newpath, RENAME_NOREPLACE) < 0)
    {
      if (G_IN_SET(errno, EINVAL, ENOSYS))
        {
          /* Fall through */
        }
      else
        {
          return -1;
        }
    }
  else
    return TRUE;
#endif

  if (linkat (olddirfd, oldpath, newdirfd, newpath, 0) < 0)
    return -1;

  if (unlinkat (olddirfd, oldpath, 0) < 0)
    return -1;

  return 0;
}

static gboolean
rename_file_noreplace_at (int olddirfd, const char *oldpath,
                          int newdirfd, const char *newpath,
                          gboolean ignore_eexist,
                          GError **error)
{
  if (glnx_renameat2_noreplace (olddirfd, oldpath,
                                newdirfd, newpath) < 0)
    {
      if (errno == EEXIST && ignore_eexist)
        {
          (void) unlinkat (olddirfd, oldpath, 0);
          return TRUE;
        }
      else
        return glnx_throw_errno_prefix (error, "renameat");
    }
  return TRUE;
}

/* An implementation of renameat2(..., RENAME_EXCHANGE)
 * with fallback to a non-atomic version.
 */
int
glnx_renameat2_exchange (int olddirfd, const char *oldpath,
                         int newdirfd, const char *newpath)
{
#ifndef ENABLE_WRPSEUDO_COMPAT
  if (renameat2 (olddirfd, oldpath, newdirfd, newpath, RENAME_EXCHANGE) == 0)
    return 0;
  else
    {
      if (G_IN_SET(errno, ENOSYS, EINVAL))
        {
          /* Fall through */
        }
      else
        {
          return -1;
        }
    }
#endif

  /* Fallback */
  { char *old_tmp_name_buf = glnx_strjoina (oldpath, ".XXXXXX");
    /* This obviously isn't race-free, but doing better gets tricky, since if
     * we're here the kernel isn't likely to support RENAME_NOREPLACE either.
     * Anyways, upgrade the kernel. Failing that, avoid use of this function in
     * shared subdirectories like /tmp.
     */
    glnx_gen_temp_name (old_tmp_name_buf);
    const char *old_tmp_name = old_tmp_name_buf;

    /* Move old out of the way */
    if (renameat (olddirfd, oldpath, olddirfd, old_tmp_name) < 0)
      return -1;
    /* Now move new into its place */
    if (renameat (newdirfd, newpath, olddirfd, oldpath) < 0)
      return -1;
    /* And finally old(tmp) into new */
    if (renameat (olddirfd, old_tmp_name, newdirfd, newpath) < 0)
      return -1;
  }
  return 0;
}

/* Deallocate a tmpfile, closing the fd and deleting the path, if any. This is
 * normally called by default by the autocleanup attribute, but you can also
 * invoke this directly.
 */
void
glnx_tmpfile_clear (GLnxTmpfile *tmpf)
{
  /* Support being passed NULL so we work nicely in a GPtrArray */
  if (!tmpf)
    return;
  if (!tmpf->initialized)
    return;
  glnx_close_fd (&tmpf->fd);
  /* If ->path is set, we're likely aborting due to an error. Clean it up */
  if (tmpf->path)
    {
      (void) unlinkat (tmpf->src_dfd, tmpf->path, 0);
      g_free (tmpf->path);
    }
  tmpf->initialized = FALSE;
}

static gboolean
open_tmpfile_core (int dfd, const char *subpath,
                   int flags,
                   GLnxTmpfile *out_tmpf,
                   GError **error)
{
  /* Picked this to match mkstemp() */
  const guint mode = 0600;

  dfd = glnx_dirfd_canonicalize (dfd);

  /* Creates a temporary file, that shall be renamed to "target"
   * later. If possible, this uses O_TMPFILE – in which case
   * "ret_path" will be returned as NULL. If not possible a the
   * tempoary path name used is returned in "ret_path". Use
   * link_tmpfile() below to rename the result after writing the file
   * in full. */
#if defined(O_TMPFILE) && !defined(DISABLE_OTMPFILE) && !defined(ENABLE_WRPSEUDO_COMPAT)
  {
    glnx_autofd int fd = openat (dfd, subpath, O_TMPFILE|flags, mode);
    if (fd == -1 && !(G_IN_SET(errno, ENOSYS, EISDIR, EOPNOTSUPP)))
      return glnx_throw_errno_prefix (error, "open(O_TMPFILE)");
    if (fd != -1)
      {
        /* Workaround for https://sourceware.org/bugzilla/show_bug.cgi?id=17523
         * See also https://github.com/ostreedev/ostree/issues/991
         */
        if (fchmod (fd, mode) < 0)
          return glnx_throw_errno_prefix (error, "fchmod");
        out_tmpf->initialized = TRUE;
        out_tmpf->src_dfd = dfd; /* Copied; caller must keep open */
        out_tmpf->fd = g_steal_fd (&fd);
        out_tmpf->path = NULL;
        return TRUE;
      }
  }
  /* Fallthrough */
#endif

  const guint count_max = 100;
  { g_autofree char *tmp = g_strconcat (subpath, "/tmp.XXXXXX", NULL);

    for (guint count = 0; count < count_max; count++)
      {
        glnx_gen_temp_name (tmp);

        glnx_autofd int fd = openat (dfd, tmp, O_CREAT|O_EXCL|O_NOFOLLOW|O_NOCTTY|flags, mode);
        if (fd < 0)
          {
            if (errno == EEXIST)
              continue;
            else
              return glnx_throw_errno_prefix (error, "Creating temp file");
          }
        else
          {
            out_tmpf->initialized = TRUE;
            out_tmpf->src_dfd = dfd;  /* Copied; caller must keep open */
            out_tmpf->fd = g_steal_fd (&fd);
            out_tmpf->path = g_steal_pointer (&tmp);
            return TRUE;
          }
      }
  }
  g_set_error (error, G_IO_ERROR, G_IO_ERROR_EXISTS,
               "Exhausted %u attempts to create temporary file", count_max);
  return FALSE;
}

/* Allocate a temporary file, using Linux O_TMPFILE if available. The file mode
 * will be 0600.
 *
 * The result will be stored in @out_tmpf, which is caller allocated
 * so you can store it on the stack in common scenarios.
 *
 * The directory fd @dfd must live at least as long as the output @out_tmpf.
 */
gboolean
glnx_open_tmpfile_linkable_at (int dfd,
                               const char *subpath,
                               int flags,
                               GLnxTmpfile *out_tmpf,
                               GError **error)
{
  /* Don't allow O_EXCL, as that has a special meaning for O_TMPFILE;
   * it's used for glnx_open_anonymous_tmpfile().
   */
  g_return_val_if_fail ((flags & O_EXCL) == 0, FALSE);

  return open_tmpfile_core (dfd, subpath, flags, out_tmpf, error);
}


/* A variant of `glnx_open_tmpfile_linkable_at()` which doesn't support linking.
 * Useful for true temporary storage. The fd will be allocated in the specified
 * directory.
 */
gboolean
glnx_open_anonymous_tmpfile_full (int          flags,
                                  const char  *dir,
                                  GLnxTmpfile *out_tmpf,
                                  GError     **error)
{
  /* Add in O_EXCL */
  if (!open_tmpfile_core (AT_FDCWD, dir, flags | O_EXCL, out_tmpf, error))
    return FALSE;
  if (out_tmpf->path)
    {
      (void) unlinkat (out_tmpf->src_dfd, out_tmpf->path, 0);
      g_clear_pointer (&out_tmpf->path, g_free);
    }
  out_tmpf->anonymous = TRUE;
  out_tmpf->src_dfd = -1;
  return TRUE;
}

/* A variant of `glnx_open_tmpfile_linkable_at()` which doesn't support linking.
 * Useful for true temporary storage. The fd will be allocated in `$TMPDIR` if
 * set or `/var/tmp` otherwise.
 *
 * If you need the file on a specific filesystem use glnx_open_anonymous_tmpfile_full()
 * which lets you pass a directory.
 */
gboolean
glnx_open_anonymous_tmpfile (int          flags,
                             GLnxTmpfile *out_tmpf,
                             GError     **error)
{
  return glnx_open_anonymous_tmpfile_full (flags,
                                           getenv("TMPDIR") ?: "/var/tmp",
                                           out_tmpf,
                                           error);
}

static const char proc_self_fd_slash[] = "/proc/self/fd/";

/* Use this after calling glnx_open_tmpfile_linkable_at() to give
 * the file its final name (link into place).
 */
gboolean
glnx_link_tmpfile_at (GLnxTmpfile *tmpf,
                      GLnxLinkTmpfileReplaceMode mode,
                      int target_dfd,
                      const char *target,
                      GError **error)
{
  const gboolean replace = (mode == GLNX_LINK_TMPFILE_REPLACE);
  const gboolean ignore_eexist = (mode == GLNX_LINK_TMPFILE_NOREPLACE_IGNORE_EXIST);

  g_return_val_if_fail (!tmpf->anonymous, FALSE);
  g_return_val_if_fail (tmpf->fd >= 0, FALSE);
  g_return_val_if_fail (tmpf->src_dfd == AT_FDCWD || tmpf->src_dfd >= 0, FALSE);

  /* Unlike the original systemd code, this function also supports
   * replacing existing files.
   */

  /* We have `tmpfile_path` for old systems without O_TMPFILE. */
  if (tmpf->path)
    {
      if (replace)
        {
          /* We have a regular tempfile, we're overwriting - this is a
           * simple renameat().
           */
          if (renameat (tmpf->src_dfd, tmpf->path, target_dfd, target) < 0)
            return glnx_throw_errno_prefix (error, "renameat");
        }
      else
        {
          /* We need to use renameat2(..., NOREPLACE) or emulate it */
          if (!rename_file_noreplace_at (tmpf->src_dfd, tmpf->path, target_dfd, target,
                                         ignore_eexist,
                                         error))
            return FALSE;
        }
      /* Now, clear the pointer so we don't try to unlink it */
      g_clear_pointer (&tmpf->path, g_free);
    }
  else
    {
      /* This case we have O_TMPFILE, so our reference to it is via /proc/self/fd */
      char proc_fd_path[sizeof (proc_self_fd_slash) + DECIMAL_STR_MAX(tmpf->fd)];
      snprintf (proc_fd_path, sizeof (proc_fd_path), "%s%i", proc_self_fd_slash, tmpf->fd);

      if (replace)
        {
          /* In this case, we had our temp file atomically hidden, but now
           * we need to make it visible in the FS so we can do a rename.
           * Ideally, linkat() would gain AT_REPLACE or so.
           */
          /* TODO - avoid double alloca, we can just alloca a copy of
           * the pathname plus space for tmp.XXXXX */
          char *dnbuf = strdupa (target);
          const char *dn = dirname (dnbuf);
          char *tmpname_buf = glnx_strjoina (dn, "/tmp.XXXXXX");

          const guint count_max = 100;
          guint count;
          for (count = 0; count < count_max; count++)
            {
              glnx_gen_temp_name (tmpname_buf);

              if (linkat (AT_FDCWD, proc_fd_path, target_dfd, tmpname_buf, AT_SYMLINK_FOLLOW) < 0)
                {
                  if (errno == EEXIST)
                    continue;
                  else
                    return glnx_throw_errno_prefix (error, "linkat");
                }
              else
                break;
            }
          if (count == count_max)
            {
              g_set_error (error, G_IO_ERROR, G_IO_ERROR_EXISTS,
               "Exhausted %u attempts to create temporary file", count);
              return FALSE;
            }
          if (!glnx_renameat (target_dfd, tmpname_buf, target_dfd, target, error))
            {
              /* This is currently the only case where we need to have
               * a cleanup unlinkat() still with O_TMPFILE.
               */
              (void) unlinkat (target_dfd, tmpname_buf, 0);
              return FALSE;
            }
        }
      else
        {
          if (linkat (AT_FDCWD, proc_fd_path, target_dfd, target, AT_SYMLINK_FOLLOW) < 0)
            {
              if (errno == EEXIST && mode == GLNX_LINK_TMPFILE_NOREPLACE_IGNORE_EXIST)
                ;
              else
                return glnx_throw_errno_prefix (error, "linkat");
            }
        }

    }
  return TRUE;
}

/* glnx_tmpfile_reopen_rdonly:
 * @tmpf: tmpfile
 * @error: Error
 *
 * Give up write access to the file descriptior.  One use
 * case for this is fs-verity, which requires a read-only fd.
 * It could also be useful to allocate an anonymous tmpfile
 * write some sort of caching/indexing data to it, then reopen it
 * read-only thereafter.
 **/
gboolean
glnx_tmpfile_reopen_rdonly (GLnxTmpfile *tmpf,
                            GError **error)
{
  g_return_val_if_fail (tmpf->fd >= 0, FALSE);
  g_return_val_if_fail (tmpf->src_dfd == AT_FDCWD || tmpf->src_dfd >= 0, FALSE);

  glnx_fd_close int rdonly_fd = -1;

  if (tmpf->path)
    {
      if (!glnx_openat_rdonly (tmpf->src_dfd, tmpf->path, FALSE, &rdonly_fd, error))
        return FALSE;
    }
  else
    {
      /* This case we have O_TMPFILE, so our reference to it is via /proc/self/fd */
      char proc_fd_path[sizeof (proc_self_fd_slash) + DECIMAL_STR_MAX(tmpf->fd)];
      snprintf (proc_fd_path, sizeof (proc_fd_path), "%s%i", proc_self_fd_slash, tmpf->fd);

      if (!glnx_openat_rdonly (AT_FDCWD, proc_fd_path, TRUE, &rdonly_fd, error))
        return FALSE;
    }

  glnx_close_fd (&tmpf->fd);
  tmpf->fd = g_steal_fd (&rdonly_fd);
  return TRUE;
}

/**
 * glnx_openat_rdonly:
 * @dfd: File descriptor for origin directory
 * @path: Pathname, relative to @dfd
 * @follow: Whether or not to follow symbolic links in the final component
 * @out_fd: (out): File descriptor
 * @error: Error
 *
 * Use openat() to open a file, with flags `O_RDONLY | O_CLOEXEC | O_NOCTTY`.
 * Like the other libglnx wrappers, will use `TEMP_FAILURE_RETRY` and
 * also includes @path in @error in case of failure.
 */
gboolean
glnx_openat_rdonly (int             dfd,
                    const char     *path,
                    gboolean        follow,
                    int            *out_fd,
                    GError        **error)
{
  int flags = O_RDONLY | O_CLOEXEC | O_NOCTTY;
  if (!follow)
    flags |= O_NOFOLLOW;
  int fd = TEMP_FAILURE_RETRY (openat (dfd, path, flags));
  if (fd == -1)
    return glnx_throw_errno_prefix (error, "openat(%s)", path);
  *out_fd = fd;
  return TRUE;
}

static guint8*
glnx_fd_readall_malloc (int               fd,
                        gsize            *out_len,
                        gboolean          nul_terminate,
                        GCancellable     *cancellable,
                        GError          **error)
{
  const guint maxreadlen = 4096;

  struct stat stbuf;
  if (!glnx_fstat (fd, &stbuf, error))
    return FALSE;

  gsize buf_allocated;
  if (S_ISREG (stbuf.st_mode) && stbuf.st_size > 0)
    buf_allocated = stbuf.st_size;
  else
    buf_allocated = 16;

  g_autofree guint8* buf = g_malloc (buf_allocated);

  gsize buf_size = 0;
  while (TRUE)
    {
      gsize readlen = MIN (buf_allocated - buf_size, maxreadlen);

      if (g_cancellable_set_error_if_cancelled (cancellable, error))
        return FALSE;

      gssize bytes_read;
      do
        bytes_read = read (fd, buf + buf_size, readlen);
      while (G_UNLIKELY (bytes_read == -1 && errno == EINTR));
      if (G_UNLIKELY (bytes_read == -1))
        return glnx_null_throw_errno (error);
      if (bytes_read == 0)
        break;

      buf_size += bytes_read;
      if (buf_allocated - buf_size < maxreadlen)
        buf = g_realloc (buf, buf_allocated *= 2);
    }

  if (nul_terminate)
    {
      if (buf_allocated - buf_size == 0)
        buf = g_realloc (buf, buf_allocated + 1);
      buf[buf_size] = '\0';
    }

  *out_len = buf_size;
  return g_steal_pointer (&buf);
}

/**
 * glnx_fd_readall_bytes:
 * @fd: A file descriptor
 * @cancellable: Cancellable:
 * @error: Error
 *
 * Read all data from file descriptor @fd into a #GBytes.  It's
 * recommended to only use this for small files.
 *
 * Returns: (transfer full): A newly allocated #GBytes
 */
GBytes *
glnx_fd_readall_bytes (int               fd,
                       GCancellable     *cancellable,
                       GError          **error)
{
  gsize len;
  guint8 *buf = glnx_fd_readall_malloc (fd, &len, FALSE, cancellable, error);
  if (!buf)
    return NULL;
  return g_bytes_new_take (buf, len);
}

/**
 * glnx_fd_readall_utf8:
 * @fd: A file descriptor
 * @out_len: (out): Returned length
 * @cancellable: Cancellable:
 * @error: Error
 *
 * Read all data from file descriptor @fd, validating
 * the result as UTF-8.
 *
 * Returns: (transfer full): A string validated as UTF-8, or %NULL on error.
 */
char *
glnx_fd_readall_utf8 (int               fd,
                      gsize            *out_len,
                      GCancellable     *cancellable,
                      GError          **error)
{
  gsize len;
  g_autofree guint8 *buf = glnx_fd_readall_malloc (fd, &len, TRUE, cancellable, error);
  if (!buf)
    return FALSE;

  if (!g_utf8_validate ((char*)buf, len, NULL))
    {
      g_set_error (error,
                   G_IO_ERROR,
                   G_IO_ERROR_INVALID_DATA,
                   "Invalid UTF-8");
      return FALSE;
    }

  if (out_len)
    *out_len = len;
  return (char*)g_steal_pointer (&buf);
}

/**
 * glnx_file_get_contents_utf8_at:
 * @dfd: Directory file descriptor
 * @subpath: Path relative to @dfd
 * @out_len: (out) (allow-none): Optional length
 * @cancellable: Cancellable
 * @error: Error
 *
 * Read the entire contents of the file referred
 * to by @dfd and @subpath, validate the result as UTF-8.
 * The length is optionally stored in @out_len.
 *
 * Returns: (transfer full): UTF-8 validated text, or %NULL on error
 */
char *
glnx_file_get_contents_utf8_at (int                   dfd,
                                const char           *subpath,
                                gsize                *out_len,
                                GCancellable         *cancellable,
                                GError              **error)
{
  dfd = glnx_dirfd_canonicalize (dfd);

  glnx_autofd int fd = -1;
  if (!glnx_openat_rdonly (dfd, subpath, TRUE, &fd, error))
    return NULL;

  gsize len;
  g_autofree char *buf = glnx_fd_readall_utf8 (fd, &len, cancellable, error);
  if (G_UNLIKELY(!buf))
    return FALSE;

  if (out_len)
    *out_len = len;
  return g_steal_pointer (&buf);
}

/**
 * glnx_readlinkat_malloc:
 * @dfd: Directory file descriptor
 * @subpath: Subpath
 * @cancellable: Cancellable
 * @error: Error
 *
 * Read the value of a symlink into a dynamically
 * allocated buffer.
 */
char *
glnx_readlinkat_malloc (int            dfd,
                        const char    *subpath,
                        G_GNUC_UNUSED GCancellable *cancellable,
                        GError       **error)
{
  dfd = glnx_dirfd_canonicalize (dfd);

  size_t l = 100;
  for (;;)
    {
      g_autofree char *c = g_malloc (l);
      ssize_t n = TEMP_FAILURE_RETRY (readlinkat (dfd, subpath, c, l-1));
      if (n < 0)
        return glnx_null_throw_errno_prefix (error, "readlinkat");

      if ((size_t) n < l-1)
        {
          c[n] = 0;
          return g_steal_pointer (&c);
        }

      l *= 2;
    }

  g_assert_not_reached ();
}

static gboolean
copy_symlink_at (int                   src_dfd,
                 const char           *src_subpath,
                 const struct stat    *src_stbuf,
                 int                   dest_dfd,
                 const char           *dest_subpath,
                 GLnxFileCopyFlags     copyflags,
                 GCancellable         *cancellable,
                 GError              **error)
{
  g_autofree char *buf = glnx_readlinkat_malloc (src_dfd, src_subpath, cancellable, error);
  if (!buf)
    return FALSE;

  if (TEMP_FAILURE_RETRY (symlinkat (buf, dest_dfd, dest_subpath)) != 0)
    return glnx_throw_errno_prefix (error, "symlinkat");

  if (!(copyflags & GLNX_FILE_COPY_NOXATTRS))
    {
      g_autoptr(GVariant) xattrs = NULL;

      if (!glnx_dfd_name_get_all_xattrs (src_dfd, src_subpath, &xattrs,
                                         cancellable, error))
        return FALSE;

      if (!glnx_dfd_name_set_all_xattrs (dest_dfd, dest_subpath, xattrs,
                                         cancellable, error))
        return FALSE;
    }

  if (TEMP_FAILURE_RETRY (fchownat (dest_dfd, dest_subpath,
                                    src_stbuf->st_uid, src_stbuf->st_gid,
                                    AT_SYMLINK_NOFOLLOW)) != 0)
    return glnx_throw_errno_prefix (error, "fchownat");

  return TRUE;
}

#define COPY_BUFFER_SIZE (16*1024)

/* Most of the code below is from systemd, but has been reindented to GNU style,
 * and changed to use POSIX error conventions (return -1, set errno) to more
 * conveniently fit in with the rest of libglnx.
 */

/* Like write(), but loop until @nbytes are written, or an error
 * occurs.
 *
 * On error, -1 is returned an @errno is set.  NOTE: This is an
 * API change from previous versions of this function.
 */
int
glnx_loop_write(int fd, const void *buf, size_t nbytes)
{
  g_return_val_if_fail (fd >= 0, -1);
  g_return_val_if_fail (buf, -1);

  errno = 0;

  const uint8_t *p = buf;
  while (nbytes > 0)
    {
      ssize_t k = write(fd, p, nbytes);
      if (k < 0)
        {
          if (errno == EINTR)
            continue;

          return -1;
        }

      if (k == 0) /* Can't really happen */
        {
          errno = EIO;
          return -1;
        }

      p += k;
      nbytes -= k;
    }

  return 0;
}

/* Read from @fdf until EOF, writing to @fdt. If max_bytes is -1, a full-file
 * clone will be attempted. Otherwise Linux copy_file_range(), sendfile()
 * syscall will be attempted.  If none of those work, this function will do a
 * plain read()/write() loop.
 *
 * The file descriptor @fdf must refer to a regular file.
 *
 * If provided, @max_bytes specifies the maximum number of bytes to read from @fdf.
 * On error, this function returns `-1` and @errno will be set.
 */
int
glnx_regfile_copy_bytes (int fdf, int fdt, off_t max_bytes)
{
  /* Last updates from systemd as of commit 6bda23dd6aaba50cf8e3e6024248cf736cc443ca */
  static int have_cfr = -1; /* -1 means unknown */
  bool try_cfr = have_cfr != 0;
  static int have_sendfile = -1; /* -1 means unknown */
  bool try_sendfile = have_sendfile != 0;

  g_return_val_if_fail (fdf >= 0, -1);
  g_return_val_if_fail (fdt >= 0, -1);
  g_return_val_if_fail (max_bytes >= -1, -1);

  /* If we've requested to copy the whole range, try a full-file clone first.
   */
  if (max_bytes == (off_t) -1 &&
      lseek (fdf, 0, SEEK_CUR) == 0 &&
      lseek (fdt, 0, SEEK_CUR) == 0)
    {
      if (ioctl (fdt, FICLONE, fdf) == 0)
        {
          /* All the other methods advance the fds. Do it here too for consistency. */
          if (lseek (fdf, 0, SEEK_END) < 0)
            return -1;
          if (lseek (fdt, 0, SEEK_END) < 0)
            return -1;

          return 0;
        }

      /* Fall through */
      struct stat stbuf;

      /* Gather the size so we can provide the whole thing at once to
       * copy_file_range() or sendfile().
       */
      if (fstat (fdf, &stbuf) < 0)
        return -1;

      if (stbuf.st_size > 0)
        max_bytes = stbuf.st_size;
    }

  while (TRUE)
    {
      ssize_t n;

      /* First, try copy_file_range(). Note this is an inlined version of
       * try_copy_file_range() from systemd upstream, which works better since
       * we use POSIX errno style.
       */
      if (try_cfr && max_bytes != (off_t) -1)
        {
          n = copy_file_range (fdf, NULL, fdt, NULL, max_bytes, 0u);
          if (n < 0)
            {
              if (errno == ENOSYS)
                {
                  /* No cfr in kernel, mark as permanently unavailable
                   * and fall through to sendfile().
                   */
                  have_cfr = 0;
                  try_cfr = false;
                }
              else if (G_IN_SET (errno, EXDEV, EINVAL, EOPNOTSUPP))
                /* We won't try cfr again for this run, but let's be
                 * conservative and not mark it as available/unavailable until
                 * we know for sure.
                 */
                try_cfr = false;
              else
                return -1;
            }
          else
            {
              /* cfr worked, mark it as available */
              if (have_cfr == -1)
                have_cfr = 1;

              if (n == 0) /* EOF */
                break;
              else
                /* Success! */
                goto next;
            }
        }

      /* Next try sendfile(); this version is also changed from systemd upstream
       * to match the same logic we have for copy_file_range().
       */
      if (try_sendfile && max_bytes != (off_t) -1)
        {
          n = sendfile (fdt, fdf, NULL, max_bytes);
          if (n < 0)
            {
              if (G_IN_SET (errno, EINVAL, ENOSYS))
                {
                  /* No sendfile(), or it doesn't work on regular files.
                   * Mark it as permanently unavailable, and fall through
                   * to plain read()/write().
                   */
                  have_sendfile = 0;
                  try_sendfile = false;
                }
              else
                return -1;
            }
          else
            {
              /* sendfile() worked, mark it as available */
              if (have_sendfile == -1)
                have_sendfile = 1;

              if (n == 0) /* EOF */
                break;
              else if (n > 0)
                /* Succcess! */
                goto next;
            }
        }

      /* As a fallback just copy bits by hand */
      { size_t m = COPY_BUFFER_SIZE;
        if (max_bytes != (off_t) -1)
          {
            if ((off_t) m > max_bytes)
              m = (size_t) max_bytes;
          }
        char buf[m];

        n = TEMP_FAILURE_RETRY (read (fdf, buf, m));
        if (n < 0)
          return -1;
        if (n == 0) /* EOF */
          break;

        if (glnx_loop_write (fdt, buf, (size_t) n) < 0)
          return -1;
      }

    next:
      if (max_bytes != (off_t) -1)
        {
          g_assert_cmpint (max_bytes, >=, n);
          max_bytes -= n;
          if (max_bytes == 0)
            break;
        }
    }

  return 0;
}

/**
 * glnx_file_copy_at:
 * @src_dfd: Source directory fd
 * @src_subpath: Subpath relative to @src_dfd
 * @src_stbuf: (allow-none): Optional stat buffer for source; if a stat() has already been done
 * @dest_dfd: Target directory fd
 * @dest_subpath: Destination name
 * @copyflags: Flags
 * @cancellable: cancellable
 * @error: Error
 *
 * Perform a full copy of the regular file or symbolic link from @src_subpath to
 * @dest_subpath; if @src_subpath is anything other than a regular file or
 * symbolic link, an error will be returned.
 *
 * If the source is a regular file and the destination exists as a symbolic
 * link, the symbolic link will not be followed; rather the link itself will be
 * replaced. Related to this: for regular files, when `GLNX_FILE_COPY_OVERWRITE`
 * is specified, this function always uses `O_TMPFILE` (if available) and does a
 * rename-into-place rather than `open(O_TRUNC)`.
 */
gboolean
glnx_file_copy_at (int                   src_dfd,
                   const char           *src_subpath,
                   const struct stat    *src_stbuf,
                   int                   dest_dfd,
                   const char           *dest_subpath,
                   GLnxFileCopyFlags     copyflags,
                   GCancellable         *cancellable,
                   GError              **error)
{
  /* Canonicalize dfds */
  src_dfd = glnx_dirfd_canonicalize (src_dfd);
  dest_dfd = glnx_dirfd_canonicalize (dest_dfd);

  if (g_cancellable_set_error_if_cancelled (cancellable, error))
    return FALSE;

  /* Automatically do stat() if no stat buffer was supplied */
  struct stat local_stbuf;
  if (!src_stbuf)
    {
      if (!glnx_fstatat (src_dfd, src_subpath, &local_stbuf, AT_SYMLINK_NOFOLLOW, error))
        return FALSE;
      src_stbuf = &local_stbuf;
    }

  /* For symlinks, defer entirely to copy_symlink_at() */
  if (S_ISLNK (src_stbuf->st_mode))
    {
      return copy_symlink_at (src_dfd, src_subpath, src_stbuf,
                              dest_dfd, dest_subpath,
                              copyflags,
                              cancellable, error);
    }
  else if (!S_ISREG (src_stbuf->st_mode))
    {
      g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
                   "Cannot copy non-regular/non-symlink file: %s", src_subpath);
      return FALSE;
    }

  /* Regular file path below here */

  glnx_autofd int src_fd = -1;
  if (!glnx_openat_rdonly (src_dfd, src_subpath, FALSE, &src_fd, error))
    return FALSE;

  /* Open a tmpfile for dest. Particularly for AT_FDCWD calls, we really want to
   * open in the target directory, otherwise we may not be able to link.
   */
  g_auto(GLnxTmpfile) tmp_dest = { 0, };
  { char *dnbuf = strdupa (dest_subpath);
    const char *dn = dirname (dnbuf);
    if (!glnx_open_tmpfile_linkable_at (dest_dfd, dn, O_WRONLY | O_CLOEXEC,
                                        &tmp_dest, error))
      return FALSE;
  }

  if (glnx_regfile_copy_bytes (src_fd, tmp_dest.fd, (off_t) -1) < 0)
    return glnx_throw_errno_prefix (error, "regfile copy");

  if (!(copyflags & GLNX_FILE_COPY_NOCHOWN))
    {
      if (fchown (tmp_dest.fd, src_stbuf->st_uid, src_stbuf->st_gid) != 0)
        return glnx_throw_errno_prefix (error, "fchown");
    }

  if (!(copyflags & GLNX_FILE_COPY_NOXATTRS))
    {
      g_autoptr(GVariant) xattrs = NULL;

      if (!glnx_fd_get_all_xattrs (src_fd, &xattrs,
                                   cancellable, error))
        return FALSE;

      if (!glnx_fd_set_all_xattrs (tmp_dest.fd, xattrs,
                                   cancellable, error))
        return FALSE;
    }

  /* Always chmod after setting xattrs, in case the file has mode 0400 or less,
   * like /etc/shadow.  Linux currently allows write() on non-writable open files
   * but not fsetxattr().
   */
  if (fchmod (tmp_dest.fd, src_stbuf->st_mode & 07777) != 0)
    return glnx_throw_errno_prefix (error, "fchmod");

  struct timespec ts[2];
  ts[0] = src_stbuf->st_atim;
  ts[1] = src_stbuf->st_mtim;
  (void) futimens (tmp_dest.fd, ts);

  if (copyflags & GLNX_FILE_COPY_DATASYNC)
    {
      if (fdatasync (tmp_dest.fd) < 0)
        return glnx_throw_errno_prefix (error, "fdatasync");
    }

  const GLnxLinkTmpfileReplaceMode replacemode =
    (copyflags & GLNX_FILE_COPY_OVERWRITE) ?
    GLNX_LINK_TMPFILE_REPLACE :
    GLNX_LINK_TMPFILE_NOREPLACE;

  if (!glnx_link_tmpfile_at (&tmp_dest, replacemode, dest_dfd, dest_subpath, error))
    return FALSE;

  return TRUE;
}

/**
 * glnx_file_replace_contents_at:
 * @dfd: Directory fd
 * @subpath: Subpath
 * @buf: (array len=len) (element-type guint8): File contents
 * @len: Length (if `-1`, assume @buf is `NUL` terminated)
 * @flags: Flags
 * @cancellable: Cancellable
 * @error: Error
 *
 * Create a new file, atomically replacing the contents of @subpath
 * (relative to @dfd) with @buf.  By default, if the file already
 * existed, fdatasync() will be used before rename() to ensure stable
 * contents.  This and other behavior can be controlled via @flags.
 *
 * Note that no metadata from the existing file is preserved, such as
 * uid/gid or extended attributes.  The default mode will be `0644`.
 */ 
gboolean
glnx_file_replace_contents_at (int                   dfd,
                               const char           *subpath,
                               const guint8         *buf,
                               gsize                 len,
                               GLnxFileReplaceFlags  flags,
                               GCancellable         *cancellable,
                               GError              **error)
{
  return glnx_file_replace_contents_with_perms_at (dfd, subpath, buf, len,
                                                   (mode_t) -1, (uid_t) -1, (gid_t) -1,
                                                   flags, cancellable, error);
}

/**
 * glnx_file_replace_contents_with_perms_at:
 * @dfd: Directory fd
 * @subpath: Subpath
 * @buf: (array len=len) (element-type guint8): File contents
 * @len: Length (if `-1`, assume @buf is `NUL` terminated)
 * @mode: File mode; if `-1`, use `0644`
 * @flags: Flags
 * @cancellable: Cancellable
 * @error: Error
 *
 * Like glnx_file_replace_contents_at(), but also supports
 * setting mode, and uid/gid.
 */ 
gboolean
glnx_file_replace_contents_with_perms_at (int                   dfd,
                                          const char           *subpath,
                                          const guint8         *buf,
                                          gsize                 len,
                                          mode_t                mode,
                                          uid_t                 uid,
                                          gid_t                 gid,
                                          GLnxFileReplaceFlags  flags,
                                          G_GNUC_UNUSED GCancellable *cancellable,
                                          GError              **error)
{
  char *dnbuf = strdupa (subpath);
  const char *dn = dirname (dnbuf);
  gboolean increasing_mtime = (flags & GLNX_FILE_REPLACE_INCREASING_MTIME) != 0;
  gboolean nodatasync = (flags & GLNX_FILE_REPLACE_NODATASYNC) != 0;
  gboolean datasync_new = (flags & GLNX_FILE_REPLACE_DATASYNC_NEW) != 0;
  struct stat stbuf;
  gboolean has_stbuf = FALSE;

  dfd = glnx_dirfd_canonicalize (dfd);

  /* With O_TMPFILE we can't use umask, and we can't sanely query the
   * umask...let's assume something relatively standard.
   */
  if (mode == (mode_t) -1)
    mode = 0644;

  g_auto(GLnxTmpfile) tmpf = { 0, };
  if (!glnx_open_tmpfile_linkable_at (dfd, dn, O_WRONLY | O_CLOEXEC,
                                      &tmpf, error))
    return FALSE;

  if (len == (gsize) -1)
    len = strlen ((char*)buf);

  if (!glnx_try_fallocate (tmpf.fd, 0, len, error))
    return FALSE;

  if (glnx_loop_write (tmpf.fd, buf, len) < 0)
    return glnx_throw_errno_prefix (error, "write");

  if (!nodatasync || increasing_mtime)
    {
      if (!glnx_fstatat_allow_noent (dfd, subpath, &stbuf, AT_SYMLINK_NOFOLLOW, error))
        return FALSE;
      has_stbuf = errno != ENOENT;
    }

  if (!nodatasync)
    {
      gboolean do_sync;
      if (!has_stbuf)
        do_sync = datasync_new;
      else
        do_sync = TRUE;

      if (do_sync)
        {
          if (TEMP_FAILURE_RETRY (fdatasync (tmpf.fd)) != 0)
            return glnx_throw_errno_prefix (error, "fdatasync");
        }
    }

  if (uid != (uid_t) -1)
    {
      if (TEMP_FAILURE_RETRY (fchown (tmpf.fd, uid, gid)) != 0)
        return glnx_throw_errno_prefix (error, "fchown");
    }

  if (TEMP_FAILURE_RETRY (fchmod (tmpf.fd, mode)) != 0)
    return glnx_throw_errno_prefix (error, "fchmod");

  if (increasing_mtime && has_stbuf)
    {
      struct stat fd_stbuf;

      if (fstat (tmpf.fd, &fd_stbuf) != 0)
        return glnx_throw_errno_prefix (error, "fstat");

      /* We want to ensure that the new file has a st_mtime (i.e. the second precision)
       * is incrementing to avoid mtime check issues when files change often.
       */
      if (fd_stbuf.st_mtime <= stbuf.st_mtime)
        {
          struct timespec ts[2] = { {0, UTIME_OMIT}, {stbuf.st_mtime + 1, 0} };
          if (TEMP_FAILURE_RETRY (futimens (tmpf.fd, ts)) != 0)
            return glnx_throw_errno_prefix (error, "futimens");
        }
    }

  if (!glnx_link_tmpfile_at (&tmpf, GLNX_LINK_TMPFILE_REPLACE,
                             dfd, subpath, error))
    return FALSE;

  return TRUE;
}

/**
 * glnx_fd_reopen:
 * @fd: a file descriptor
 * @flags: combination of openat flags
 * @error: a #GError
 *
 * Reopens the specified fd with new flags. This is useful for converting an
 * O_PATH fd into a regular one, or to turn O_RDWR fds into O_RDONLY fds.
 *
 * This implicitly sets `O_CLOEXEC | O_NOCTTY` in @flags.
 *
 * `O_CREAT` isn't allowed in @flags.
 *
 * This doesn't work on sockets (since they cannot be open()ed, ever).
 *
 * This implicitly resets the file read index to 0.
 *
 * If AT_FDCWD is specified as file descriptor, the function returns an fd to
 * the current working directory.
 *
 * If the specified file descriptor refers to a symlink via O_PATH, then this
 * function cannot be used to follow that symlink. Because we cannot have
 * non-O_PATH fds to symlinks reopening it without O_PATH will always result in
 * ELOOP. Or in other words: if you have an O_PATH fd to a symlink you can
 * reopen it only if you pass O_PATH again.
 */
int
glnx_fd_reopen (int      fd,
                int      flags,
                GError **error)
{
  glnx_autofd int new_fd = -1;

  g_return_val_if_fail (fd >= 0 || fd == AT_FDCWD, -1);
  g_return_val_if_fail ((flags & O_CREAT) == 0, -1);

  /* */
  flags |= O_CLOEXEC | O_NOCTTY;

  /* O_NOFOLLOW is not allowed in fd_reopen(), because after all this is
   * primarily implemented via a symlink-based interface in /proc/self/fd. Let's
   * refuse this here early. Note that the kernel would generate ELOOP here too,
   * hence this manual check is mostly redundant – the only reason we add it
   * here is so that the O_DIRECTORY special case (see below) behaves the same
   * way as the non-O_DIRECTORY case. */
  if ((flags & O_NOFOLLOW) != 0)
    {
      errno = ELOOP;
      return glnx_fd_throw_errno (error);
    }

  if ((flags & O_DIRECTORY) != 0 || fd == AT_FDCWD)
    {
      /* If we shall reopen the fd as directory we can just go via "." and thus
       * bypass the whole magic /proc/ directory, and make ourselves independent
       * of that being mounted. */
      new_fd = openat (fd, ".", flags | O_DIRECTORY);
    }
  else
    {
      g_autofree char *proc_fd_path = NULL;

      proc_fd_path = g_strdup_printf ("/proc/self/fd/%d", fd);
      new_fd = open (proc_fd_path, flags);
    }

  if (new_fd < 0)
    return glnx_fd_throw_errno (error);

  return g_steal_fd (&new_fd);
}

===== ./subprojects/libglnx/glnx-backports.c =====
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
 *
 * Copyright 2000-2022 Red Hat, Inc.
 * Copyright 2006-2007 Matthias Clasen
 * Copyright 2006 Padraig O'Briain
 * Copyright 2007 Lennart Poettering
 * Copyright (C) 2015 Colin Walters <walters@verbum.org>
 * Copyright 2018-2022 Endless OS Foundation, LLC
 * Copyright 2018 Peter Wu
 * Copyright 2019 Ting-Wei Lan
 * Copyright 2019 Sebastian Schwarz
 * Copyright 2020 Matt Rose
 * Copyright 2021 Casper Dik
 * Copyright 2022 Alexander Richardson
 * Copyright 2022 Ray Strode
 * Copyright 2022 Thomas Haller
 * Copyright 2023-2024 Collabora Ltd.
 * Copyright 2023 Sebastian Wilhelmi
 * Copyright 2023 CaiJingLong
 * SPDX-License-Identifier: LGPL-2.1-or-later
 *
 * 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 licence 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, see <http://www.gnu.org/licenses/>.
 */

#include "libglnx-config.h"

#include "glnx-backports.h"
#include "glnx-missing.h"

#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <stdlib.h>
#include <sys/resource.h>
#include <sys/syscall.h>
#include <sys/types.h>
#include <unistd.h>

#if !GLIB_CHECK_VERSION(2, 44, 0)
gboolean
glnx_strv_contains (const gchar * const *strv,
                    const gchar         *str)
{
  g_return_val_if_fail (strv != NULL, FALSE);
  g_return_val_if_fail (str != NULL, FALSE);

  for (; *strv != NULL; strv++)
    {
      if (g_str_equal (str, *strv))
        return TRUE;
    }

  return FALSE;
}

gboolean
glnx_set_object (GObject **object_ptr,
                 GObject  *new_object)
{
  GObject *old_object = *object_ptr;

  if (old_object == new_object)
    return FALSE;

  if (new_object != NULL)
    g_object_ref (new_object);

  *object_ptr = new_object;

  if (old_object != NULL)
    g_object_unref (old_object);

  return TRUE;
}
#endif

#if !GLIB_CHECK_VERSION(2, 60, 0)
gboolean
_glnx_strv_equal (const gchar * const *strv1,
                  const gchar * const *strv2)
{
  g_return_val_if_fail (strv1 != NULL, FALSE);
  g_return_val_if_fail (strv2 != NULL, FALSE);

  if (strv1 == strv2)
    return TRUE;

  for (; *strv1 != NULL && *strv2 != NULL; strv1++, strv2++)
    {
      if (!g_str_equal (*strv1, *strv2))
        return FALSE;
    }

  return (*strv1 == NULL && *strv2 == NULL);
}
#endif

#if !GLIB_CHECK_VERSION(2, 76, 0)
gboolean
_glnx_close (gint     fd,
             GError **error)
{
  int res;

  /* Important: if @error is NULL, we must not do anything that is
   * not async-signal-safe.
   */
  res = close (fd);

  if (res == -1)
    {
      int errsv = errno;

      if (errsv == EINTR)
        {
          /* Just ignore EINTR for now; a retry loop is the wrong thing to do
           * on Linux at least.  Anyone who wants to add a conditional check
           * for e.g. HP-UX is welcome to do so later...
           *
           * close_func_with_invalid_fds() in gspawn.c has similar logic.
           *
           * https://lwn.net/Articles/576478/
           * http://lkml.indiana.edu/hypermail/linux/kernel/0509.1/0877.html
           * https://bugzilla.gnome.org/show_bug.cgi?id=682819
           * http://utcc.utoronto.ca/~cks/space/blog/unix/CloseEINTR
           * https://sites.google.com/site/michaelsafyan/software-engineering/checkforeintrwheninvokingclosethinkagain
           *
           * `close$NOCANCEL()` in gstdioprivate.h, on macOS, ensures that the fd is
           * closed even if it did return EINTR.
           */
          return TRUE;
        }

      if (error)
        {
          g_set_error_literal (error, G_FILE_ERROR,
                               g_file_error_from_errno (errsv),
                               g_strerror (errsv));
        }

      if (errsv == EBADF)
        {
          /* There is a bug. Fail an assertion. Note that this function is supposed to be
           * async-signal-safe, but in case an assertion fails, all bets are already off. */
          if (fd >= 0)
            {
              /* Closing an non-negative, invalid file descriptor is a bug. The bug is
               * not necessarily in the caller of _glnx_close(), but somebody else
               * might have wrongly closed fd. In any case, there is a serious bug
               * somewhere. */
              g_critical ("_glnx_close(fd:%d) failed with EBADF. The tracking of file descriptors got messed up", fd);
            }
          else
            {
              /* Closing a negative "file descriptor" is less problematic. It's still a nonsensical action
               * from the caller. Assert against that too. */
              g_critical ("_glnx_close(fd:%d) failed with EBADF. This is not a valid file descriptor", fd);
            }
        }

      errno = errsv;

      return FALSE;
    }

  return TRUE;
}
#endif

#if !GLIB_CHECK_VERSION(2, 80, 0)
/* This function is called between fork() and exec() and hence must be
 * async-signal-safe (see signal-safety(7)). */
static int
set_cloexec (void *data, gint fd)
{
  if (fd >= GPOINTER_TO_INT (data))
    fcntl (fd, F_SETFD, FD_CLOEXEC);

  return 0;
}

/* fdwalk()-compatible callback to close a fd for non-compliant
 * implementations of fdwalk() that potentially pass already
 * closed fds.
 *
 * It is not an error to pass an invalid fd to this function.
 *
 * This function is called between fork() and exec() and hence must be
 * async-signal-safe (see signal-safety(7)).
 */
G_GNUC_UNUSED static int
close_func_with_invalid_fds (void *data, int fd)
{
  /* We use close and not g_close here because on some platforms, we
   * don't know how to close only valid, open file descriptors, so we
   * have to pass bad fds to close too. g_close warns if given a bad
   * fd.
   *
   * This function returns no error, because there is nothing that the caller
   * could do with that information. That is even the case for EINTR. See
   * g_close() about the specialty of EINTR and why that is correct.
   * If g_close() ever gets extended to handle EINTR specially, then this place
   * should get updated to do the same handling.
   */
  if (fd >= GPOINTER_TO_INT (data))
    close (fd);

  return 0;
}

#ifdef __linux__
struct linux_dirent64
{
  guint64        d_ino;    /* 64-bit inode number */
  guint64        d_off;    /* 64-bit offset to next structure */
  unsigned short d_reclen; /* Size of this dirent */
  unsigned char  d_type;   /* File type */
  char           d_name[]; /* Filename (null-terminated) */
};

/* This function is called between fork() and exec() and hence must be
 * async-signal-safe (see signal-safety(7)). */
static gint
filename_to_fd (const char *p)
{
  char c;
  int fd = 0;
  const int cutoff = G_MAXINT / 10;
  const int cutlim = G_MAXINT % 10;

  if (*p == '\0')
    return -1;

  while ((c = *p++) != '\0')
    {
      if (c < '0' || c > '9')
        return -1;
      c -= '0';

      /* Check for overflow. */
      if (fd > cutoff || (fd == cutoff && c > cutlim))
        return -1;

      fd = fd * 10 + c;
    }

  return fd;
}
#endif

static int safe_fdwalk_with_invalid_fds (int (*cb)(void *data, int fd), void *data);

/* This function is called between fork() and exec() and hence must be
 * async-signal-safe (see signal-safety(7)). */
static int
safe_fdwalk (int (*cb)(void *data, int fd), void *data)
{
#if 0
  /* Use fdwalk function provided by the system if it is known to be
   * async-signal safe.
   *
   * Currently there are no operating systems known to provide a safe
   * implementation, so this section is not used for now.
   */
  return fdwalk (cb, data);
#else
  /* Fallback implementation of fdwalk. It should be async-signal safe, but it
   * may fail on non-Linux operating systems. See safe_fdwalk_with_invalid_fds
   * for a slower alternative.
   */

#ifdef __linux__
  gint fd;
  gint res = 0;

  /* Avoid use of opendir/closedir since these are not async-signal-safe. */
  int dir_fd = open ("/proc/self/fd", O_RDONLY | O_DIRECTORY);
  if (dir_fd >= 0)
    {
      /* buf needs to be aligned correctly to receive linux_dirent64.
       * C11 has _Alignof for this purpose, but for now a
       * union serves the same purpose. */
      union
      {
        char buf[4096];
        struct linux_dirent64 alignment;
      } u;
      int pos, nread;
      struct linux_dirent64 *de;

      while ((nread = syscall (SYS_getdents64, dir_fd, u.buf, sizeof (u.buf))) > 0)
        {
          for (pos = 0; pos < nread; pos += de->d_reclen)
            {
              de = (struct linux_dirent64 *) (u.buf + pos);

              fd = filename_to_fd (de->d_name);
              if (fd < 0 || fd == dir_fd)
                  continue;

              if ((res = cb (data, fd)) != 0)
                  break;
            }
        }

      close (dir_fd);
      return res;
    }

  /* If /proc is not mounted or not accessible we fail here and rely on
   * safe_fdwalk_with_invalid_fds to fall back to the old
   * rlimit trick. */

#endif

#if defined(__sun__) && defined(F_PREVFD) && defined(F_NEXTFD)
/*
 * Solaris 11.4 has a signal-safe way which allows
 * us to find all file descriptors in a process.
 *
 * fcntl(fd, F_NEXTFD, maxfd)
 * - returns the first allocated file descriptor <= maxfd  > fd.
 *
 * fcntl(fd, F_PREVFD)
 * - return highest allocated file descriptor < fd.
 */
  gint fd;
  gint res = 0;

  open_max = fcntl (INT_MAX, F_PREVFD); /* find the maximum fd */
  if (open_max < 0) /* No open files */
    return 0;

  for (fd = -1; (fd = fcntl (fd, F_NEXTFD, open_max)) != -1; )
    if ((res = cb (data, fd)) != 0 || fd == open_max)
      break;

  return res;
#endif

  return safe_fdwalk_with_invalid_fds (cb, data);
#endif
}

/* This function is called between fork() and exec() and hence must be
 * async-signal-safe (see signal-safety(7)). */
static int
safe_fdwalk_with_invalid_fds (int (*cb)(void *data, int fd), void *data)
{
  /* Fallback implementation of fdwalk. It should be async-signal safe, but it
   * may be slow, especially on systems allowing very high number of open file
   * descriptors.
   */
  gint open_max = -1;
  gint fd;
  gint res = 0;

#if 0 && defined(HAVE_SYS_RESOURCE_H)
  struct rlimit rl;

  /* Use getrlimit() function provided by the system if it is known to be
   * async-signal safe.
   *
   * Currently there are no operating systems known to provide a safe
   * implementation, so this section is not used for now.
   */
  if (getrlimit (RLIMIT_NOFILE, &rl) == 0 && rl.rlim_max != RLIM_INFINITY)
    open_max = rl.rlim_max;
#endif
#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__APPLE__)
  /* Use sysconf() function provided by the system if it is known to be
   * async-signal safe.
   *
   * FreeBSD: sysconf() is included in the list of async-signal safe functions
   * found in https://man.freebsd.org/sigaction(2).
   *
   * OpenBSD: sysconf() is included in the list of async-signal safe functions
   * found in https://man.openbsd.org/sigaction.2.
   *
   * Apple: sysconf() is included in the list of async-signal safe functions
   * found in https://opensource.apple.com/source/xnu/xnu-517.12.7/bsd/man/man2/sigaction.2
   */
  if (open_max < 0)
    open_max = sysconf (_SC_OPEN_MAX);
#endif
  /* Hardcoded fallback: the default process hard limit in Linux as of 2020 */
  if (open_max < 0)
    open_max = 4096;

#if defined(__APPLE__) && defined(HAVE_LIBPROC_H)
  /* proc_pidinfo isn't documented as async-signal-safe but looking at the implementation
   * in the darwin tree here:
   *
   * https://opensource.apple.com/source/Libc/Libc-498/darwin/libproc.c.auto.html
   *
   * It's just a thin wrapper around a syscall, so it's probably okay.
   */
  {
    char buffer[4096 * PROC_PIDLISTFD_SIZE];
    ssize_t buffer_size;

    buffer_size = proc_pidinfo (getpid (), PROC_PIDLISTFDS, 0, buffer, sizeof (buffer));

    if (buffer_size > 0 &&
        sizeof (buffer) >= (size_t) buffer_size &&
        (buffer_size % PROC_PIDLISTFD_SIZE) == 0)
      {
        const struct proc_fdinfo *fd_info = (const struct proc_fdinfo *) buffer;
        size_t number_of_fds = (size_t) buffer_size / PROC_PIDLISTFD_SIZE;

        for (size_t i = 0; i < number_of_fds; i++)
          if ((res = cb (data, fd_info[i].proc_fd)) != 0)
            break;

        return res;
      }
  }
#endif

  for (fd = 0; fd < open_max; fd++)
      if ((res = cb (data, fd)) != 0)
          break;

  return res;
}

/**
 * g_fdwalk_set_cloexec:
 * @lowfd: Minimum fd to act on, which must be non-negative
 *
 * Mark every file descriptor equal to or greater than @lowfd to be closed
 * at the next `execve()` or similar, as if via the `FD_CLOEXEC` flag.
 *
 * Typically @lowfd will be 3, to leave standard input, standard output
 * and standard error open after exec.
 *
 * This is the same as Linux `close_range (lowfd, ~0U, CLOSE_RANGE_CLOEXEC)`,
 * but portable to other OSs and to older versions of Linux.
 *
 * This function is async-signal safe, making it safe to call from a
 * signal handler or a [callback@GLib.SpawnChildSetupFunc], as long as @lowfd is
 * non-negative.
 * See [`signal(7)`](man:signal(7)) and
 * [`signal-safety(7)`](man:signal-safety(7)) for more details.
 *
 * Returns: 0 on success, -1 with errno set on error
 * Since: 2.80
 */
int
_glnx_fdwalk_set_cloexec (int lowfd)
{
  int ret;

  g_return_val_if_fail (lowfd >= 0, (errno = EINVAL, -1));

#if defined(HAVE_CLOSE_RANGE) && defined(CLOSE_RANGE_CLOEXEC)
  /* close_range() is available in Linux since kernel 5.9, and on FreeBSD at
   * around the same time. It was designed for use in async-signal-safe
   * situations: https://bugs.python.org/issue38061
   *
   * The `CLOSE_RANGE_CLOEXEC` flag was added in Linux 5.11, and is not yet
   * present in FreeBSD.
   *
   * Handle ENOSYS in case it’s supported in libc but not the kernel; if so,
   * fall back to safe_fdwalk(). Handle EINVAL in case `CLOSE_RANGE_CLOEXEC`
   * is not supported. */
  ret = close_range (lowfd, G_MAXUINT, CLOSE_RANGE_CLOEXEC);
  if (ret == 0 || !(errno == ENOSYS || errno == EINVAL))
    return ret;
#endif  /* HAVE_CLOSE_RANGE */

  ret = safe_fdwalk (set_cloexec, GINT_TO_POINTER (lowfd));

  return ret;
}

/**
 * g_closefrom:
 * @lowfd: Minimum fd to close, which must be non-negative
 *
 * Close every file descriptor equal to or greater than @lowfd.
 *
 * Typically @lowfd will be 3, to leave standard input, standard output
 * and standard error open.
 *
 * This is the same as Linux `close_range (lowfd, ~0U, 0)`,
 * but portable to other OSs and to older versions of Linux.
 * Equivalently, it is the same as BSD `closefrom (lowfd)`, but portable,
 * and async-signal-safe on all OSs.
 *
 * This function is async-signal safe, making it safe to call from a
 * signal handler or a [callback@GLib.SpawnChildSetupFunc], as long as @lowfd is
 * non-negative.
 * See [`signal(7)`](man:signal(7)) and
 * [`signal-safety(7)`](man:signal-safety(7)) for more details.
 *
 * Returns: 0 on success, -1 with errno set on error
 * Since: 2.80
 */
int
_glnx_closefrom (int lowfd)
{
  int ret;

  g_return_val_if_fail (lowfd >= 0, (errno = EINVAL, -1));

#if defined(HAVE_CLOSE_RANGE)
  /* close_range() is available in Linux since kernel 5.9, and on FreeBSD at
   * around the same time. It was designed for use in async-signal-safe
   * situations: https://bugs.python.org/issue38061
   *
   * Handle ENOSYS in case it’s supported in libc but not the kernel; if so,
   * fall back to safe_fdwalk(). */
  ret = close_range (lowfd, G_MAXUINT, 0);
  if (ret == 0 || errno != ENOSYS)
    return ret;
#endif  /* HAVE_CLOSE_RANGE */

#if defined(__FreeBSD__) || defined(__OpenBSD__) || \
  (defined(__sun__) && defined(F_CLOSEFROM))
  /* Use closefrom function provided by the system if it is known to be
   * async-signal safe.
   *
   * FreeBSD: closefrom is included in the list of async-signal safe functions
   * found in https://man.freebsd.org/sigaction(2).
   *
   * OpenBSD: closefrom is not included in the list, but a direct system call
   * should be safe to use.
   *
   * In Solaris as of 11.3 SRU 31, closefrom() is also a direct system call.
   * On such systems, F_CLOSEFROM is defined.
   */
  (void) closefrom (lowfd);
  return 0;
#elif defined(__DragonFly__)
  /* It is unclear whether closefrom function included in DragonFlyBSD libc_r
   * is safe to use because it calls a lot of library functions. It is also
   * unclear whether libc_r itself is still being used. Therefore, we do a
   * direct system call here ourselves to avoid possible issues.
   */
  (void) syscall (SYS_closefrom, lowfd);
  return 0;
#elif defined(F_CLOSEM)
  /* NetBSD and AIX have a special fcntl command which does the same thing as
   * closefrom. NetBSD also includes closefrom function, which seems to be a
   * simple wrapper of the fcntl command.
   */
  return fcntl (lowfd, F_CLOSEM);
#else
  ret = safe_fdwalk (close_func_with_invalid_fds, GINT_TO_POINTER (lowfd));

  return ret;
#endif
}
#endif /* !2.80.0 */

===== ./subprojects/libglnx/glnx-errors.c =====
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
 *
 * Copyright (C) 2014,2015 Colin Walters <walters@verbum.org>.
 * SPDX-License-Identifier: LGPL-2.0-or-later
 *
 * 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 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., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

#include "libglnx-config.h"

#include <glnx-backport-autocleanups.h>
#include <glnx-errors.h>

/* Set @error with G_IO_ERROR/G_IO_ERROR_FAILED.
 *
 * This function returns %FALSE so it can be used conveniently in a single
 * statement:
 *
 * ```
 *   if (strcmp (foo, "somevalue") != 0)
 *     return glnx_throw (error, "key must be somevalue, not '%s'", foo);
 * ```
 */
gboolean
glnx_throw (GError    **error,
            const char *fmt,
            ...)
{
  if (error == NULL)
    return FALSE;

  va_list args;
  va_start (args, fmt);
  GError *new = g_error_new_valist (G_IO_ERROR, G_IO_ERROR_FAILED, fmt, args);
  va_end (args);
  g_propagate_error (error, g_steal_pointer (&new));
  return FALSE;
}

void
glnx_real_set_prefix_error_va (GError     *error,
                               const char *format,
                               va_list     args)
{
  if (error == NULL)
    return;

  g_autofree char *old_msg = g_steal_pointer (&error->message);
  g_autoptr(GString) buf = g_string_new ("");
  g_string_append_vprintf (buf, format, args);
  g_string_append (buf, ": ");
  g_string_append (buf, old_msg);
  error->message = g_string_free (g_steal_pointer (&buf), FALSE);
}

/* Prepend to @error's message by `$prefix: ` where `$prefix` is computed via
 * printf @fmt. Returns %FALSE so it can be used conveniently in a single
 * statement:
 *
 * ```
 *   if (!function_that_fails (s, error))
 *     return glnx_throw_prefix (error, "while handling '%s'", s);
 * ```
 * */
gboolean
glnx_prefix_error (GError    **error,
                   const char *fmt,
                   ...)
{
  if (error == NULL)
    return FALSE;

  va_list args;
  va_start (args, fmt);
  glnx_real_set_prefix_error_va (*error, fmt, args);
  va_end (args);
  return FALSE;
}

void
glnx_real_set_prefix_error_from_errno_va (GError     **error,
                                          gint         errsv,
                                          const char  *format,
                                          va_list      args)
{
  if (!error)
    return;

  g_set_error_literal (error,
                       G_IO_ERROR,
                       g_io_error_from_errno (errsv),
                       g_strerror (errsv));
  glnx_real_set_prefix_error_va (*error, format, args);
}

/* Set @error using the value of `$prefix: g_strerror (errno)` where `$prefix`
 * is computed via printf @fmt.
 *
 * This function returns %FALSE so it can be used conveniently in a single
 * statement:
 *
 * ```
 *   return glnx_throw_errno_prefix (error, "unlinking %s", pathname);
 * ```
 */
gboolean
glnx_throw_errno_prefix (GError    **error,
                         const char *fmt,
                         ...)
{
  int errsv = errno;
  va_list args;
  va_start (args, fmt);
  glnx_real_set_prefix_error_from_errno_va (error, errsv, fmt, args);
  va_end (args);
  /* See comment in glnx_throw_errno() about preserving errno */
  errno = errsv;
  return FALSE;
}

===== ./subprojects/libglnx/glnx-backport-testutils.c =====
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
 *
 * Copyright 2015 Colin Walters
 * Copyright 2020 Niels De Graef
 * Copyright 2021-2022 Collabora Ltd.
 * SPDX-License-Identifier: LGPL-2.1-or-later
 *
 * This program 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 licence 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., 59 Temple Place, Suite 330,
 * Boston, MA 02111-1307, USA.
 */

#include "libglnx-config.h"

#include <string.h>
#include <unistd.h>

#include <glib/gprintf.h>

#include "glnx-backport-autocleanups.h"
#include "glnx-backport-autoptr.h"
#include "glnx-backport-testutils.h"
#include "glnx-backports.h"

#include <sys/prctl.h>
#include <sys/resource.h>

#if !GLIB_CHECK_VERSION (2, 68, 0)
/* Backport of g_assertion_message_cmpstrv() */
void
_glnx_assertion_message_cmpstrv (const char         *domain,
                                 const char         *file,
                                 int                 line,
                                 const char         *func,
                                 const char         *expr,
                                 const char * const *arg1,
                                 const char * const *arg2,
                                 gsize               first_wrong_idx)
{
  const char *s1 = arg1[first_wrong_idx], *s2 = arg2[first_wrong_idx];
  char *a1, *a2, *s, *t1 = NULL, *t2 = NULL;

  a1 = g_strconcat ("\"", t1 = g_strescape (s1, NULL), "\"", NULL);
  a2 = g_strconcat ("\"", t2 = g_strescape (s2, NULL), "\"", NULL);
  g_free (t1);
  g_free (t2);
  s = g_strdup_printf ("assertion failed (%s): first differing element at index %" G_GSIZE_FORMAT ": %s does not equal %s",
                       expr, first_wrong_idx, a1, a2);
  g_free (a1);
  g_free (a2);
  g_assertion_message (domain, file, line, func, s);
  g_free (s);
}
#endif

#if !GLIB_CHECK_VERSION(2, 70, 0)
/*
 * Same as g_test_message(), but split messages with newlines into
 * multiple separate messages to avoid corrupting stdout, even in older
 * GLib versions that didn't do this
 */
void
_glnx_test_message_safe (const char *format,
                         ...)
{
  g_autofree char *message = NULL;
  va_list ap;
  char *line;
  char *saveptr = NULL;

  va_start (ap, format);
  g_vasprintf (&message, format, ap);
  va_end (ap);

  for (line = strtok_r (message, "\n", &saveptr);
       line != NULL;
       line = strtok_r (NULL, "\n", &saveptr))
    (g_test_message) ("%s", line);
}

/* Backport of g_test_fail_printf() */
void
_glnx_test_fail_printf (const char *format,
                        ...)
{
  g_autofree char *message = NULL;
  va_list ap;

  va_start (ap, format);
  g_vasprintf (&message, format, ap);
  va_end (ap);

  /* This is the closest we can do in older GLib */
  g_test_message ("Bail out! %s", message);
  g_test_fail ();
}

/* Backport of g_test_skip_printf() */
void
_glnx_test_skip_printf (const char *format,
                        ...)
{
  g_autofree char *message = NULL;
  va_list ap;

  va_start (ap, format);
  g_vasprintf (&message, format, ap);
  va_end (ap);

  g_test_skip (message);
}

/* Backport of g_test_incomplete_printf() */
void
_glnx_test_incomplete_printf (const char *format,
                              ...)
{
  g_autofree char *message = NULL;
  va_list ap;

  va_start (ap, format);
  g_vasprintf (&message, format, ap);
  va_end (ap);

#if GLIB_CHECK_VERSION(2, 58, 0)
  /* Since 2.58, g_test_incomplete() sets the exit status correctly. */
  g_test_incomplete (message);
#elif GLIB_CHECK_VERSION (2, 38, 0)
  /* Before 2.58, g_test_incomplete() was treated like a failure for the
   * purposes of setting the exit status, so prefer to use (our wrapper
   * around) g_test_skip(). */
  g_test_skip_printf ("TODO: %s", message);
#else
  g_test_message ("TODO: %s", message);
#endif
}
#endif

#if !GLIB_CHECK_VERSION (2, 78, 0)
void
_glnx_test_disable_crash_reporting (void)
{
  struct rlimit limit = { 0, 0 };

  (void) setrlimit (RLIMIT_CORE, &limit);

  /* On Linux, RLIMIT_CORE = 0 is ignored if core dumps are
   * configured to be written to a pipe, but PR_SET_DUMPABLE is not. */
  (void) prctl (PR_SET_DUMPABLE, 0, 0, 0, 0);
}
#endif

===== ./subprojects/libglnx/LICENSES/LGPL-2.1-or-later.txt =====
                  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!

===== ./subprojects/libglnx/LICENSES/LGPL-2.0-or-later.txt =====
GNU LIBRARY GENERAL PUBLIC LICENSE

Version 2, June 1991

Copyright (C) 1991 Free Software Foundation, Inc.
51 Franklin St, 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 library GPL.  It is numbered 2 because it goes with version 2 of the ordinary GPL.]

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 Library General Public License, applies to some specially designated Free Software Foundation software, and to any other libraries whose authors decide to use it. You can use it for your libraries, too.

When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things.

To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the 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 a program 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.

Our method of protecting your rights has two steps: (1) copyright the library, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the library.

Also, for each distributor's protection, we want to make certain that everyone understands that there is no warranty for this free library. If the library is modified by someone else and passed on, we want its recipients to know that what they have is not the original version, so that any problems introduced by others will not reflect on the original authors' reputations.

Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that companies distributing free software will individually obtain patent licenses, thus in effect transforming the program into proprietary software. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all.

Most GNU software, including some libraries, is covered by the ordinary GNU General Public License, which was designed for utility programs. This license, the GNU Library General Public License, applies to certain designated libraries. This license is quite different from the ordinary one; be sure to read it in full, and don't assume that anything in it is the same as in the ordinary license.

The reason we have a separate public license for some libraries is that they blur the distinction we usually make between modifying or adding to a program and simply using it. Linking a program with a library, without changing the library, is in some sense simply using the library, and is analogous to running a utility program or application program. However, in a textual and legal sense, the linked executable is a combined work, a derivative of the original library, and the ordinary General Public License treats it as such.

Because of this blurred distinction, using the ordinary General Public License for libraries did not effectively promote software sharing, because most developers did not use the libraries. We concluded that weaker conditions might promote sharing better.

However, unrestricted linking of non-free programs would deprive the users of those programs of all benefit from the free status of the libraries themselves. This Library General Public License is intended to permit developers of non-free programs to use free libraries, while preserving your freedom as a user of such programs to change the free libraries that are incorporated in them. (We have not seen how to achieve this as regards changes in header files, but we have achieved it as regards changes in the actual functions of the Library.) The hope is that this will lead to faster development of free libraries.

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, while the latter only works together with the library.

Note that it is possible for a library to be covered by the ordinary General Public License rather than by this special one.

TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION

0. This License Agreement applies to any software library which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Library 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 compile 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) 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.

     c) 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.

     d) 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 source code 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 to 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 Library 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 an 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 Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details.

     You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin St, 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!

===== ./subprojects/libglnx/LICENSES/LicenseRef-old-glib-tests.txt =====
This work is provided "as is"; redistribution and modification
in whole or in part, in any medium, physical or electronic is
permitted without restriction.

This work 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.

In no event shall the authors or contributors be liable for any
direct, indirect, incidental, special, exemplary, or consequential
damages (including, but not limited to, procurement of substitute
goods or services; loss of use, data, or profits; or business
interruption) however caused and on any theory of liability, whether
in contract, strict liability, or tort (including negligence or
otherwise) arising in any way out of the use of this software, even
if advised of the possibility of such damage.

===== ./subprojects/libglnx/glnx-shutil.c =====
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
 *
 * Copyright (C) 2014,2015 Colin Walters <walters@verbum.org>.
 * SPDX-License-Identifier: LGPL-2.0-or-later
 *
 * 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 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., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

#include "libglnx-config.h"

#include <string.h>

#include <glnx-shutil.h>
#include <glnx-errors.h>
#include <glnx-fdio.h>
#include <glnx-local-alloc.h>

static gboolean
unlinkat_allow_noent (int dfd,
                      const char *path,
                      int flags,
                      GError **error)
{
  if (unlinkat (dfd, path, flags) == -1)
    {
      if (errno != ENOENT)
        return glnx_throw_errno_prefix (error, "unlinkat(%s)", path);
    }
  return TRUE;
}

static gboolean
glnx_shutil_rm_rf_children (GLnxDirFdIterator    *dfd_iter,
                            GCancellable       *cancellable,
                            GError            **error)
{
  struct dirent *dent;

  while (TRUE)
    {
      if (!glnx_dirfd_iterator_next_dent_ensure_dtype (dfd_iter, &dent, cancellable, error))
        return FALSE;
      if (dent == NULL)
        break;

      if (dent->d_type == DT_DIR)
        {
          g_auto(GLnxDirFdIterator) child_dfd_iter = { 0, };

          if (!glnx_dirfd_iterator_init_at (dfd_iter->fd, dent->d_name, FALSE,
                                            &child_dfd_iter, error))
            return FALSE;

          if (!glnx_shutil_rm_rf_children (&child_dfd_iter, cancellable, error))
            return FALSE;

          if (!glnx_unlinkat (dfd_iter->fd, dent->d_name, AT_REMOVEDIR, error))
            return FALSE;
        }
      else
        {
          if (!unlinkat_allow_noent (dfd_iter->fd, dent->d_name, 0, error))
            return FALSE;
        }
    }

  return TRUE;
}

/**
 * glnx_shutil_rm_rf_at:
 * @dfd: A directory file descriptor, or `AT_FDCWD` or `-1` for current
 * @path: Path
 * @cancellable: Cancellable
 * @error: Error
 *
 * Recursively delete the filename referenced by the combination of
 * the directory fd @dfd and @path; it may be a file or directory.  No
 * error is thrown if @path does not exist.
 */
gboolean
glnx_shutil_rm_rf_at (int                   dfd,
                      const char           *path,
                      GCancellable         *cancellable,
                      GError              **error)
{
  dfd = glnx_dirfd_canonicalize (dfd);

  /* With O_NOFOLLOW first */
  glnx_autofd int target_dfd =
    openat (dfd, path, O_RDONLY | O_NONBLOCK | O_DIRECTORY | O_CLOEXEC | O_NOFOLLOW);

  if (target_dfd == -1)
    {
      int errsv = errno;
      if (errsv == ENOENT)
        {
          ;
        }
      else if (errsv == ENOTDIR || errsv == ELOOP)
        {
          if (!glnx_unlinkat (dfd, path, 0, error))
            return FALSE;
        }
      else
        return glnx_throw_errno_prefix (error, "open(%s)", path);
    }
  else
    {
      g_auto(GLnxDirFdIterator) dfd_iter = { 0, };
      if (!glnx_dirfd_iterator_init_take_fd (&target_dfd, &dfd_iter, error))
        return FALSE;

      if (!glnx_shutil_rm_rf_children (&dfd_iter, cancellable, error))
        return glnx_prefix_error (error, "Removing %s", path);

      if (!unlinkat_allow_noent (dfd, path, AT_REMOVEDIR, error))
        return FALSE;
    }

  return TRUE;
}

static gboolean
mkdir_p_at_internal (int              dfd,
                     char            *path,
                     int              mode,
                     GCancellable    *cancellable,
                     GError         **error)
{
  gboolean did_recurse = FALSE;

  if (g_cancellable_set_error_if_cancelled (cancellable, error))
    return FALSE;

 again:
  if (mkdirat (dfd, path, mode) == -1)
    {
      if (errno == ENOENT && !did_recurse)
        {
          char *lastslash;

          lastslash = strrchr (path, '/');
          if (lastslash == NULL)
            {
              /* This can happen if @dfd was deleted between being opened and
               * passed to mkdir_p_at_internal(). */
              return glnx_throw_errno_prefix (error, "mkdir(%s)", path);
            }

          /* Note we can mutate the buffer as we dup'd it */
          *lastslash = '\0';

          if (!glnx_shutil_mkdir_p_at (dfd, path, mode,
                                       cancellable, error))
            return FALSE;

          /* Now restore it for another mkdir attempt */
          *lastslash = '/';

          did_recurse = TRUE;
          goto again;
        }
      else if (errno == EEXIST)
        {
          /* Fall through; it may not have been a directory,
           * but we'll find that out on the next call up.
           */
        }
      else
        return glnx_throw_errno_prefix (error, "mkdir(%s)", path);
    }

  return TRUE;
}

/**
 * glnx_shutil_mkdir_p_at:
 * @dfd: Directory fd
 * @path: Directory path to be created
 * @mode: Mode for newly created directories
 * @cancellable: Cancellable
 * @error: Error
 *
 * Similar to g_mkdir_with_parents(), except operates relative to the
 * directory fd @dfd.
 *
 * See also glnx_ensure_dir() for a non-recursive version.
 *
 * This will return %G_IO_ERROR_NOT_FOUND if @dfd has been deleted since being
 * opened. It may return other errors from mkdirat() in other situations.
 */
gboolean
glnx_shutil_mkdir_p_at (int                   dfd,
                        const char           *path,
                        int                   mode,
                        GCancellable         *cancellable,
                        GError              **error)
{
  struct stat stbuf;
  char *buf;

  /* Fast path stat to see whether it already exists */
  if (fstatat (dfd, path, &stbuf, AT_SYMLINK_NOFOLLOW) == 0)
    {
      /* Note early return */
      if (S_ISDIR (stbuf.st_mode))
        return TRUE;
    }

  buf = strdupa (path);

  if (!mkdir_p_at_internal (dfd, buf, mode, cancellable, error))
    return FALSE;

  return TRUE;
}

/**
 * glnx_shutil_mkdir_p_at_open:
 * @dfd: Directory fd
 * @path: Directory path to be created
 * @mode: Mode for newly created directories
 * @out_dfd: (out caller-allocates): Return location for an FD to @dfd/@path,
 *    or `-1` on error
 * @cancellable: (nullable): Cancellable, or %NULL
 * @error: Return location for a #GError, or %NULL
 *
 * Similar to glnx_shutil_mkdir_p_at(), except it opens the resulting directory
 * and returns a directory FD to it. Currently, this is not guaranteed to be
 * race-free.
 *
 * Returns: %TRUE on success, %FALSE otherwise
 * Since: UNRELEASED
 */
gboolean
glnx_shutil_mkdir_p_at_open (int            dfd,
                             const char    *path,
                             int            mode,
                             int           *out_dfd,
                             GCancellable  *cancellable,
                             GError       **error)
{
  /* FIXME: It’s not possible to eliminate the race here until
   * openat(O_DIRECTORY | O_CREAT) works (and returns a directory rather than a
   * file). It appears to be not supported in current kernels. (Tested with
   * 4.10.10-200.fc25.x86_64.) */
  *out_dfd = -1;

  if (!glnx_shutil_mkdir_p_at (dfd, path, mode, cancellable, error))
    return FALSE;

  return glnx_opendirat (dfd, path, TRUE, out_dfd, error);
}

===== ./subprojects/libglnx/glnx-missing.h =====
#pragma once

/***
  This file was originally part of systemd.

  Copyright 2010 Lennart Poettering
  SPDX-License-Identifier: LGPL-2.1-or-later

  systemd 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.

  systemd 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 systemd; If not, see <http://www.gnu.org/licenses/>.
***/

/* Missing glibc definitions to access certain kernel APIs.
   This file is last updated from systemd git:

   commit 71e5200f94b22589922704aa4abdf95d4fe2e528
   Author:     Daniel Mack <daniel@zonque.org>
   AuthorDate: Tue Oct 18 17:57:10 2016 +0200
   Commit:     Lennart Poettering <lennart@poettering.net>
   CommitDate: Fri Sep 22 15:24:54 2017 +0200

   Add abstraction model for BPF programs
*/

#include <errno.h>
#include <fcntl.h>
#include <stdlib.h>
#include <sys/resource.h>
#include <sys/syscall.h>
#include <unistd.h>

/* The precise definition of __O_TMPFILE is arch specific; use the
 * values defined by the kernel (note: some are hexa, some are octal,
 * duplicated as-is from the kernel definitions):
 * - alpha, parisc, sparc: each has a specific value;
 * - others: they use the "generic" value.
 */

#ifndef __O_TMPFILE
#if defined(__alpha__)
#define __O_TMPFILE     0100000000
#elif defined(__parisc__) || defined(__hppa__)
#define __O_TMPFILE     0400000000
#elif defined(__sparc__) || defined(__sparc64__)
#define __O_TMPFILE     0x2000000
#else
#define __O_TMPFILE     020000000
#endif
#endif

/* a horrid kludge trying to make sure that this will fail on old kernels */
#ifndef O_TMPFILE
#define O_TMPFILE (__O_TMPFILE | O_DIRECTORY)
#endif

#ifndef RENAME_NOREPLACE
#define RENAME_NOREPLACE (1 << 0)
#endif
#ifndef RENAME_EXCHANGE
#define RENAME_EXCHANGE (1 << 1)
#endif

#ifndef F_LINUX_SPECIFIC_BASE
#define F_LINUX_SPECIFIC_BASE 1024
#endif

#ifndef F_ADD_SEALS
#define F_ADD_SEALS (F_LINUX_SPECIFIC_BASE + 9)
#define F_GET_SEALS (F_LINUX_SPECIFIC_BASE + 10)

#define F_SEAL_SEAL     0x0001  /* prevent further seals from being set */
#define F_SEAL_SHRINK   0x0002  /* prevent file from shrinking */
#define F_SEAL_GROW     0x0004  /* prevent file from growing */
#define F_SEAL_WRITE    0x0008  /* prevent writes */
#endif

#ifndef MFD_ALLOW_SEALING
#define MFD_ALLOW_SEALING 0x0002U
#endif

#ifndef MFD_CLOEXEC
#define MFD_CLOEXEC 0x0001U
#endif

#ifndef CLOSE_RANGE_UNSHARE
#define CLOSE_RANGE_UNSHARE (1U << 1)
#endif

#ifndef CLOSE_RANGE_CLOEXEC
#define CLOSE_RANGE_CLOEXEC (1U << 2)
#endif

#include "glnx-missing-syscall.h"

===== ./subprojects/libglnx/.gitlab-ci.yml =====
# Copyright 2019 Endless OS Foundation LLC
# SPDX-License-Identifier: LGPL-2.0-or-later

image: registry.fedoraproject.org/fedora:30

stages:
  - build

before_script:
  - dnf install -y gcc git meson ninja-build "pkgconfig(gio-2.0)" "pkgconfig(gio-unix-2.0)" "pkgconfig(glib-2.0)" xz

build:
  stage: build
  script:
    - meson _build .
    - ninja -C _build
    - meson test -C _build
    # Run it again! This previously did not work.
    - meson test -C _build
    # Ensure that we can build as a subproject
    - rm -fr _build/meson-dist
    - meson dist -C _build
    - mkdir -p tests/use-as-subproject/subprojects/libglnx
    - tar --strip-components=1 -C tests/use-as-subproject/subprojects/libglnx -xf _build/meson-dist/*.tar.xz
    - meson tests/use-as-subproject/_build tests/use-as-subproject
    - ninja -C tests/use-as-subproject/_build
    - meson test -C tests/use-as-subproject/_build
  artifacts:
    when: on_failure
    name: "libglnx-${CI_COMMIT_REF_NAME}-${CI_JOB_NAME}"
    paths:
      - "${CI_PROJECT_DIR}/_build/meson-logs"

reuse:
  stage: build
  image:
    name: fsfe/reuse:latest
    entrypoint: [""]
  before_script: []
  script:
    - reuse lint

===== ./subprojects/libglnx/glnx-xattrs.h =====
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
 *
 * Copyright (C) 2014,2015 Colin Walters <walters@verbum.org>.
 * SPDX-License-Identifier: LGPL-2.0-or-later
 *
 * 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 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., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

#pragma once

#include <glnx-backport-autocleanups.h>
#include <limits.h>
#include <dirent.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/xattr.h>

G_BEGIN_DECLS

gboolean
glnx_dfd_name_get_all_xattrs (int                    dfd,
                              const char            *name,
                              GVariant             **out_xattrs,
                              GCancellable          *cancellable,
                              GError               **error);

gboolean
glnx_fd_get_all_xattrs (int                    fd,
                        GVariant             **out_xattrs,
                        GCancellable          *cancellable,
                        GError               **error);

gboolean
glnx_dfd_name_set_all_xattrs (int            dfd,
                              const char    *name,
                              GVariant      *xattrs,
                              GCancellable  *cancellable,
                              GError       **error);

gboolean
glnx_fd_set_all_xattrs (int            fd,
                        GVariant      *xattrs,
                        GCancellable  *cancellable,
                        GError       **error);

GBytes *
glnx_lgetxattrat (int            dfd,
                  const char    *subpath,
                  const char    *attribute,
                  GError       **error);

GBytes *
glnx_fgetxattr_bytes (int            fd,
                      const char    *attribute,
                      GError       **error);

gboolean
glnx_lsetxattrat (int            dfd,
                  const char    *subpath,
                  const char    *attribute,
                  const guint8  *value,
                  gsize          len,
                  int            flags,
                  GError       **error);

G_END_DECLS

===== ./subprojects/libglnx/glnx-local-alloc.h =====
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
 *
 * Copyright (C) 2012,2015 Colin Walters <walters@verbum.org>.
 * SPDX-License-Identifier: LGPL-2.0-or-later
 *
 * 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 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., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

#pragma once

#include <gio/gio.h>
#include <errno.h>

#include "glnx-backports.h"

G_BEGIN_DECLS

/**
 * glnx_unref_object:
 *
 * Call g_object_unref() on a variable location when it goes out of
 * scope.  Note that unlike g_object_unref(), the variable may be
 * %NULL.
 */
#define glnx_unref_object __attribute__ ((cleanup(glnx_local_obj_unref)))
static inline void
glnx_local_obj_unref (void *v)
{
  GObject *o = *(GObject **)v;
  if (o)
    g_object_unref (o);
}

/* Backwards-compat with older libglnx */
#define glnx_steal_fd g_steal_fd

/**
 * glnx_close_fd:
 * @fdp: Pointer to fd
 *
 * Effectively `close (g_steal_fd (&fd))`.  Also
 * asserts that `close()` did not raise `EBADF` - encountering
 * that error is usually a critical bug in the program.
 */
static inline void
glnx_close_fd (int *fdp)
{
  int errsv;

  g_assert (fdp);

  int fd = g_steal_fd (fdp);
  if (fd >= 0)
    {
      errsv = errno;
      if (close (fd) < 0)
        g_assert (errno != EBADF);
      errno = errsv;
    }
}

/**
 * glnx_fd_close:
 *
 * Deprecated in favor of `glnx_autofd`.
 */
#define glnx_fd_close __attribute__((cleanup(glnx_close_fd)))
/**
 * glnx_autofd:
 *
 * Call close() on a variable location when it goes out of scope.
 */
#define glnx_autofd __attribute__((cleanup(glnx_close_fd)))

G_END_DECLS

===== ./subprojects/libglnx/glnx-chase.c =====
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
 *
 * Copyright (C) 2026 Red Hat, Inc.
 * SPDX-License-Identifier: LGPL-2.1-or-later
 *
 * glnx_chaseat was inspired by systemd's chase
 */

#include "libglnx-config.h"

#include <fcntl.h>
#include <stdint.h>
#include <sys/mount.h>
#include <sys/statfs.h>
#include <sys/syscall.h>
#include <sys/vfs.h>
#include <unistd.h>

#include <glnx-backports.h>
#include <glnx-errors.h>
#include <glnx-fdio.h>
#include <glnx-local-alloc.h>
#include <glnx-missing.h>

#include <glnx-chase.h>

#define AUTOFS_SUPER_MAGIC 0x0187 /* man fstatfs */

#define GLNX_CHASE_DEBUG_NO_OPENAT2 (1U << 31)
#define GLNX_CHASE_DEBUG_NO_OPEN_TREE (1U << 30)

#define GLNX_CHASE_ALL_DEBUG_FLAGS \
  (GLNX_CHASE_DEBUG_NO_OPENAT2 | \
   GLNX_CHASE_DEBUG_NO_OPEN_TREE)

#define GLNX_CHASE_ALL_REGULAR_FLAGS \
  (GLNX_CHASE_NO_AUTOMOUNT | \
   GLNX_CHASE_NOFOLLOW | \
   GLNX_CHASE_RESOLVE_BENEATH | \
   GLNX_CHASE_RESOLVE_IN_ROOT | \
   GLNX_CHASE_RESOLVE_NO_SYMLINKS | \
   GLNX_CHASE_MUST_BE_REGULAR | \
   GLNX_CHASE_MUST_BE_DIRECTORY | \
   GLNX_CHASE_MUST_BE_SOCKET)

#define GLNX_CHASE_ALL_FLAGS \
  (GLNX_CHASE_ALL_DEBUG_FLAGS | GLNX_CHASE_ALL_REGULAR_FLAGS)

typedef GQueue GlnxStatxQueue;

static void
glnx_statx_queue_push (GlnxStatxQueue          *queue,
                       const struct glnx_statx *st)
{
  struct glnx_statx *copy;

  copy = g_memdup2 (st, sizeof (*st));
  g_queue_push_tail (queue, copy);
}

static void
glnx_statx_queue_free_element (gpointer element,
                               G_GNUC_UNUSED gpointer userdata)
{
  g_free (element);
}

static void
glnx_statx_queue_free (GlnxStatxQueue *squeue)
{
  GQueue *queue = (GQueue *) squeue;

  /* Same as g_queue_clear_full (queue, g_free), but works for <2.60 */
  g_queue_foreach (queue, glnx_statx_queue_free_element, NULL);
  g_queue_clear (queue);
}

G_DEFINE_AUTO_CLEANUP_CLEAR_FUNC(GlnxStatxQueue, glnx_statx_queue_free)

static gboolean
glnx_statx_inode_same (const struct glnx_statx *a,
                       const struct glnx_statx *b)
{
  g_assert ((a->stx_mask & (GLNX_STATX_TYPE | GLNX_STATX_INO)) ==
            (GLNX_STATX_TYPE | GLNX_STATX_INO));
  g_assert ((b->stx_mask & (GLNX_STATX_TYPE | GLNX_STATX_INO)) ==
            (GLNX_STATX_TYPE | GLNX_STATX_INO));

  return ((a->stx_mode ^ b->stx_mode) & S_IFMT) == 0 &&
         a->stx_dev_major == b->stx_dev_major &&
         a->stx_dev_minor == b->stx_dev_minor &&
         a->stx_ino == b->stx_ino;
}

static gboolean
glnx_statx_mount_same (const struct glnx_statx *a,
                       const struct glnx_statx *b)
{
  g_assert ((a->stx_mask & (GLNX_STATX_MNT_ID | GLNX_STATX_MNT_ID_UNIQUE)) != 0);
  g_assert ((b->stx_mask & (GLNX_STATX_MNT_ID | GLNX_STATX_MNT_ID_UNIQUE)) != 0);

  return a->stx_mnt_id == b->stx_mnt_id;
}

static gboolean
glnx_chase_statx (int                 dfd,
                  int                 additional_flags,
                  struct glnx_statx  *buf,
                  GError            **error)
{
  if (!glnx_statx (dfd, "",
                   AT_EMPTY_PATH | AT_SYMLINK_NOFOLLOW | additional_flags,
                   GLNX_STATX_TYPE | GLNX_STATX_INO |
                   GLNX_STATX_MNT_ID | GLNX_STATX_MNT_ID_UNIQUE,
                   buf,
                   error))
    return FALSE;

  if ((buf->stx_mask & (GLNX_STATX_TYPE | GLNX_STATX_INO)) !=
        (GLNX_STATX_TYPE | GLNX_STATX_INO) ||
      (buf->stx_mask & (GLNX_STATX_MNT_ID | GLNX_STATX_MNT_ID_UNIQUE)) == 0)
    {
      errno = ENODATA;
      return glnx_throw_errno_prefix (error,
                                      "statx didn't return all required fields");
    }

  return TRUE;
}

/* TODO: procfs magiclinks handling */

/* open_tree subset which transparently falls back to openat.
 *
 * Returned fd is always OPATH and CLOEXEC.
 *
 * With NO_AUTOMOUNT this function never triggers automounts. Otherwise, it only
 * guarantees to trigger an automount which is on last segment of the path!
 *
 * flags can be a combinations of:
 *  - GLNX_CHASE_NO_AUTOMOUNT
 *  - GLNX_CHASE_NOFOLLOW
 */
static int
chase_open_tree (int              dirfd,
                 const char      *path,
                 GlnxChaseFlags   flags,
                 GError         **error)
{
  glnx_autofd int fd = -1;
  static gboolean can_open_tree = TRUE;
  unsigned int openat_flags = 0;

  g_assert ((flags & ~(GLNX_CHASE_NO_AUTOMOUNT |
                       GLNX_CHASE_NOFOLLOW |
                       GLNX_CHASE_ALL_DEBUG_FLAGS)) == 0);

  /* First we try to actually use open_tree, and then fall back to the impl
   * using openat.
   * Technically racy (static, not synced), but both paths work fine so it
   * doesn't matter. */
  if (can_open_tree && (flags & GLNX_CHASE_DEBUG_NO_OPEN_TREE) == 0)
    {
      unsigned int open_tree_flags = 0;

      open_tree_flags = OPEN_TREE_CLOEXEC;
      if ((flags & GLNX_CHASE_NOFOLLOW) != 0)
        open_tree_flags |= AT_SYMLINK_NOFOLLOW;
      if ((flags & GLNX_CHASE_NO_AUTOMOUNT) != 0)
        open_tree_flags |= AT_NO_AUTOMOUNT;

      fd = open_tree (dirfd, path, open_tree_flags);

      /* If open_tree is not supported, or blocked (EPERM), we fall back to
       * openat */
      if (fd < 0 && G_IN_SET (errno,
                              EOPNOTSUPP,
                              ENOTTY,
                              ENOSYS,
                              EAFNOSUPPORT,
                              EPFNOSUPPORT,
                              EPROTONOSUPPORT,
                              ESOCKTNOSUPPORT,
                              ENOPROTOOPT,
                              EPERM))
        can_open_tree = FALSE;
      else if (fd < 0)
        return glnx_fd_throw_errno_prefix (error, "open_tree");
      else
        return g_steal_fd (&fd);
    }

  openat_flags = O_CLOEXEC | O_PATH;
  if ((flags & GLNX_CHASE_NOFOLLOW) != 0)
    openat_flags |= O_NOFOLLOW;

  fd = openat (dirfd, path, openat_flags);
  if (fd < 0)
    return glnx_fd_throw_errno_prefix (error, "openat in open_tree fallback");

  /* openat does not trigger automounts, so we have to manually do so
   * unless NO_AUTOMOUNT was specified */
  if ((flags & GLNX_CHASE_NO_AUTOMOUNT) == 0)
    {
      struct statfs stfs;

      if (fstatfs (fd, &stfs) < 0)
        return glnx_fd_throw_errno_prefix (error, "fstatfs in open_tree fallback");

      /* fstatfs(2) can then be used to determine if it is, in fact, an
       * untriggered automount point (.f_type == AUTOFS_SUPER_MAGIC). */
      if (stfs.f_type == AUTOFS_SUPER_MAGIC)
        {
          glnx_autofd int new_fd = -1;

          new_fd = openat (fd, ".", openat_flags | O_DIRECTORY);
          /* For some reason, openat with O_PATH | O_DIRECTORY does trigger
           * automounts, without us having to actually open the file, so let's
           * use this here. It only works for directories though. */
          if (new_fd >= 0)
            return g_steal_fd (&new_fd);

          if (errno != ENOTDIR)
            return glnx_fd_throw_errno_prefix (error, "openat(O_DIRECTORY) in autofs mount open_tree fallback");

          /* The automount is a directory, so let's try to open the file,
           * which can fail because we are missing permissions, but that's
           * okay, we only need to trigger automount. */
          new_fd = openat (fd, ".", (openat_flags & ~O_PATH) |
                                    O_RDONLY | O_NONBLOCK | O_CLOEXEC | O_NOCTTY);
          glnx_close_fd (&new_fd);

          /* And try again with O_PATH */
          new_fd = openat (dirfd, path, openat_flags);
          if (new_fd < 0)
            return glnx_fd_throw_errno_prefix (error, "reopening in autofs mount open_tree fallback");

          if (fstatfs (new_fd, &stfs) < 0)
            return glnx_fd_throw_errno_prefix (error, "fstatfs in autofs mount open_tree fallback");

          /* bail if we didn't manage to trigger the automount */
          if (stfs.f_type == AUTOFS_SUPER_MAGIC)
            {
              errno = EOPNOTSUPP;
              return glnx_fd_throw_errno_prefix (error, "unable to trigger automount");
            }

          return g_steal_fd (&new_fd);
        }
    }

  return g_steal_fd (&fd);
}

static int
open_cwd (GlnxChaseFlags   flags,
          GError         **error)
{
  GLNX_AUTO_PREFIX_ERROR ("cannot open working directory", error);

  /* NO_AUTOMOUNT should be fine here because automount must have been
   * triggered already for the CWD */
  return chase_open_tree (AT_FDCWD, ".",
                          (flags & GLNX_CHASE_ALL_DEBUG_FLAGS) |
                          GLNX_CHASE_NO_AUTOMOUNT |
                          GLNX_CHASE_NOFOLLOW,
                          error);
}

static int
open_root (GlnxChaseFlags   flags,
           GError         **error)
{
  GLNX_AUTO_PREFIX_ERROR ("cannot open root directory", error);

  /* NO_AUTOMOUNT should be fine here because automount must have been
   * triggered already for the root */
  return chase_open_tree (AT_FDCWD, "/",
                          (flags & GLNX_CHASE_ALL_DEBUG_FLAGS) |
                          GLNX_CHASE_NO_AUTOMOUNT |
                          GLNX_CHASE_NOFOLLOW,
                          error);
}

/* This returns the next segment of a path and tells us if it is the last
 * segment.
 *
 * Importantly, a segment is anything after a "/", even if it is empty  or ".".
 *
 * For example:
 *   "" -> ""
 *   "/" -> ""
 *   "////" -> ""
 *   "foo/bar" -> "foo", "bar"
 *   "foo//bar" -> "foo", "bar"
 *   "///foo//bar" -> "foo", "bar"
 *   "///foo//bar/" -> "foo", "bar", ""
 *   "///foo//bar/." -> "foo", "bar", "."
 */
static char *
extract_next_segment (const char **remaining,
                      gboolean    *is_last)
{
  const char *r = *remaining;
  const char *s;
  size_t len = 0;

  while (r[0] != '\0' && G_IS_DIR_SEPARATOR (r[0]))
    r++;

  s = r;

  while (r[0] != '\0' && !G_IS_DIR_SEPARATOR (r[0]))
    {
      r++;
      len++;
    }

  *is_last = (r[0] == '\0');
  *remaining = r;
  return g_strndup (s, len);
}

/* This iterates over the segments of path and opens the corresponding
 * directories or files. This gives us the opportunity to implement openat2
 * like RESOLVE_ semantics, without actually needing openat2.
 * It also allows us to implement features which openat2 does not have because
 * we're in full control over the resolving.
 */
static int
chase_manual (int              dirfd,
              const char      *path,
              GlnxChaseFlags   flags,
              GError         **error)
{
  gboolean is_absolute;
  g_autofree char *buffer = NULL;
  const char *remaining;
  glnx_autofd int owned_root_fd = -1;
  int root_fd;
  glnx_autofd int owned_fd = -1;
  int fd;
  int remaining_follows = GLNX_CHASE_MAX;
  struct glnx_statx st;
  g_auto(GlnxStatxQueue) path_st = G_QUEUE_INIT;
  int no_automount;

  /* Take a shortcut if
   * - none of the resolve flags are set (they would require work here)
   * - NO_AUTOMOUNT is set (chase_open_tree only triggers the automount for
   *   last component in some cases)
   *
   * TODO: if we have a guarantee that the open_tree syscall works, we can
   * shortcut even without GLNX_CHASE_NO_AUTOMOUNT
   */
  if ((flags & (GLNX_CHASE_NO_AUTOMOUNT |
                GLNX_CHASE_RESOLVE_BENEATH |
                GLNX_CHASE_RESOLVE_IN_ROOT |
                GLNX_CHASE_RESOLVE_NO_SYMLINKS)) == GLNX_CHASE_NO_AUTOMOUNT)
    {
      GlnxChaseFlags open_tree_flags =
        (flags & (GLNX_CHASE_NOFOLLOW | GLNX_CHASE_ALL_DEBUG_FLAGS));

      return chase_open_tree (dirfd, path, open_tree_flags, error);
    }

  no_automount = (flags & GLNX_CHASE_NO_AUTOMOUNT) != 0 ? AT_NO_AUTOMOUNT : 0;

  is_absolute = g_path_is_absolute (path);

  if (is_absolute && (flags & GLNX_CHASE_RESOLVE_BENEATH) != 0)
    {
      /* Absolute paths always get rejected with RESOLVE_BENEATH with errno
       * EXDEV */

      errno = EXDEV;
      return glnx_fd_throw_errno_prefix (error, "absolute path not allowed for RESOLVE_BENEATH");
    }
  else if (!is_absolute ||
           (is_absolute && (flags & GLNX_CHASE_RESOLVE_IN_ROOT) != 0))
    {
      /* The absolute path is relative to dirfd with GLNX_CHASE_RESOLVE_IN_ROOT,
       * and a relative path is always relative. */

      /* In both cases we use dirfd as our chase root */
      if (dirfd == AT_FDCWD)
        {
          owned_root_fd = root_fd = open_cwd (flags, error);
          if (root_fd < 0)
            return -1;
        }
      else
        {
          root_fd = dirfd;
        }
    }
  else
    {
      /* For absolute paths, we ignore dirfd, we use the actual root / for our
       * chase root */
      g_assert (is_absolute);

      owned_root_fd = root_fd = open_root (flags, error);
      if (root_fd < 0)
        return -1;
    }

  /* At this point, we always have (a relative) path, relative to root_fd */
  is_absolute = FALSE;
  g_assert (root_fd >= 0);

  /* Add root to path_st, so we can verify if we get back to it */
  if (!glnx_chase_statx (root_fd, no_automount, &st, error))
    return -1;

  glnx_statx_queue_push (&path_st, &st);

  /* Let's start walking the path! */
  buffer = g_strdup (path);
  remaining = buffer;
  fd = root_fd;

  for (;;)
    {
      g_autofree char *segment = NULL;
      gboolean is_last;
      glnx_autofd int next_fd = -1;

      segment = extract_next_segment (&remaining, &is_last);

      /* If we encounter an empty segment ("", "."), we stay where we are and
       * ignore the segment, or just exit if it is the last segment. */
      if (g_strcmp0 (segment, "") == 0 || g_strcmp0 (segment, ".") == 0)
        {
          if (is_last)
            break;
          continue;
        }

      /* Special handling for going down the tree with RESOLVE_ flags */
      if (g_strcmp0 (segment, "..") == 0)
        {
          /* path_st contains the stat of the root if we're at root, so the
           * length is 1 in that case, and going lower than the root is not
           * allowed here! */

          if (path_st.length <= 1 && (flags & GLNX_CHASE_RESOLVE_BENEATH) != 0)
            {
              /* With RESOLVE_BENEATH, error out if we would end up above the
               * root fd */
              errno = EXDEV;
              return glnx_fd_throw_errno_prefix (error, "attempted to traverse above root path via \"..\"");
            }
          else if (path_st.length <= 1 && (flags & GLNX_CHASE_RESOLVE_IN_ROOT) != 0)
            {
              /* With RESOLVE_IN_ROOT, we pretend that we hit the real root,
               * and stay there, just like the kernel does. */
              continue;
            }
        }

      {
        /* Open the next segment. We always use GLNX_CHASE_NOFOLLOW here to be
         * able to ensure the RESOLVE flags, and automount behavior. */

        GlnxChaseFlags open_tree_flags =
          GLNX_CHASE_NOFOLLOW |
          (flags & (GLNX_CHASE_NO_AUTOMOUNT | GLNX_CHASE_ALL_DEBUG_FLAGS));

        next_fd = chase_open_tree (fd, segment, open_tree_flags, error);
        if (next_fd < 0)
          return -1;
      }

      if (!glnx_chase_statx (next_fd, no_automount, &st, error))
        return -1;

      /* We resolve links if: they are not in the last component, or if they
       * are the last component and NOFOLLOW is not set. */
      if (S_ISLNK (st.stx_mode) &&
          (!is_last || (flags & GLNX_CHASE_NOFOLLOW) == 0))
        {
          g_autofree char *link = NULL;
          g_autofree char *new_buffer = NULL;

          /* ...however, we do not resolve symlinks with NO_SYMLINKS, and use
           * remaining_follows to ensure we don't loop forever. */
          if ((flags & GLNX_CHASE_RESOLVE_NO_SYMLINKS) != 0 ||
              --remaining_follows <= 0)
            {
              errno = ELOOP;
              return glnx_fd_throw_errno_prefix (error, "followed too many symlinks");
            }

          /* AT_EMPTY_PATH is implied for readlinkat */
          link = glnx_readlinkat_malloc (next_fd, "", NULL, error);
          if (!link)
            return -1;

          if (g_path_is_absolute (link) &&
              (flags & GLNX_CHASE_RESOLVE_BENEATH) != 0)
            {
              errno = EXDEV;
              return glnx_fd_throw_errno_prefix (error, "absolute symlink not allowed for RESOLVE_BENEATH");
            }

          /* The link can be absolute, and we handle that below, by changing the
           * dirfd. The path *remains* and absolute path internally, but that is
           * okay because we always interpret any path (even absolute ones) as
           * being relative to the dirfd */
          new_buffer = g_strdup_printf ("%s/%s", link, remaining);
          g_clear_pointer (&buffer, g_free);
          buffer = g_steal_pointer (&new_buffer);
          remaining = buffer;

          if (g_path_is_absolute (link))
            {
              if ((flags & GLNX_CHASE_RESOLVE_IN_ROOT) != 0)
                {
                  /* If the path was absolute, and RESOLVE_IN_ROOT is set, we
                   * will resolve the remaining path relative to root_fd */

                  g_clear_fd (&owned_fd, NULL);
                  fd = root_fd;
                }
              else
                {
                  /* If the path was absolute, we will resolve the remaining
                   * path relative to the real root */

                  g_clear_fd (&owned_fd, NULL);
                  fd = owned_fd = open_root (flags, error);
                  if (fd < 0)
                    return -1;
                }

              /* path_st must only contain the new root at this point */
              if (!glnx_chase_statx (fd, no_automount, &st, error))
                return -1;

              glnx_statx_queue_free (&path_st);
              g_queue_init (&path_st);
              glnx_statx_queue_push (&path_st, &st);
            }

          continue;
        }

      /* Either adds an element to path_st or removes one if we got down the
       * tree. This also checks that going down the tree ends up at the inode
       * we saw before (if we saw it before). */
      if (g_strcmp0 (segment, "..") == 0)
        {
          g_autofree struct glnx_statx *old_tail = NULL;
          struct glnx_statx *lower_st;

          old_tail = g_queue_pop_tail (&path_st);

          lower_st = g_queue_peek_tail (&path_st);
          if (lower_st &&
              (!glnx_statx_mount_same (&st, lower_st) ||
               !glnx_statx_inode_same (&st, lower_st)))
            {
              errno = EXDEV;
              return glnx_fd_throw_errno_prefix (error, "a parent directory changed while traversing");
            }
        }
      else
        {
          glnx_statx_queue_push (&path_st, &st);
        }

      /* There is still another path component, but the next fd is not a
       * a directory. We need the fd to be a directory though, to open the next
       * segment from. So bail with the appropriate error. */
      if (!is_last && !S_ISDIR (st.stx_mode))
        {
          errno = ENOTDIR;
          return glnx_fd_throw_errno_prefix (error, "a non-final path segment is not a directory");
        }

      g_clear_fd (&owned_fd, NULL);
      fd = owned_fd = g_steal_fd (&next_fd);

      if (is_last)
        break;
    }

  /* We need an owned fd to return. Only having fd and not owned_fd can happen
   * if we never finished a single iteration, or if an absolute path with
   * RESOLVE_IN_ROOT makes us point at root_fd.
   * We just re-open fd to always get an owned fd.
   * Note that this only works because in all cases where owned_fd does not
   * exists, fd is a directory. */
  if (owned_fd < 0)
    {
      owned_fd = openat (fd, ".", O_PATH | O_CLOEXEC | O_NOFOLLOW);
      if (owned_fd < 0)
        return glnx_fd_throw_errno_prefix (error, "reopening failed");
    }

  return g_steal_fd (&owned_fd);
}

/**
 * glnx_chaseat:
 * @dirfd: a directory file descriptor
 * @path: a path
 * @flags: combination of GlnxChaseFlags flags
 * @error: a #GError
 *
 * Behaves similar to openat, but with a number of differences:
 *
 * - All file descriptors which get returned are O_PATH and O_CLOEXEC. If you
 *   want to actually open the file for reading or writing, use glnx_fd_reopen,
 *   openat, or other at-style functions.
 * - By default, automounts get triggered and the O_PATH fd will point to inodes
 *   in the newly mounted filesystem if an automount is encountered. This can be
 *   turned off with GLNX_CHASE_NO_AUTOMOUNT.
 * - The GLNX_CHASE_RESOLVE_ flags can be used to safely deal with symlinks.
 *
 * Returns: the chased file, or -1 with @error set on error
 */
int
glnx_chaseat (int              dirfd,
              const char      *path,
              GlnxChaseFlags   flags,
              GError         **error)
{
  static gboolean can_openat2 = TRUE;
  glnx_autofd int fd = -1;

  g_return_val_if_fail (dirfd >= 0 || dirfd == AT_FDCWD, -1);
  g_return_val_if_fail (path != NULL, -1);
  g_return_val_if_fail ((flags & ~(GLNX_CHASE_ALL_FLAGS)) == 0, -1);
  g_return_val_if_fail (error == NULL || *error == NULL, -1);

  {
    int must_flags = flags & (GLNX_CHASE_MUST_BE_REGULAR |
                              GLNX_CHASE_MUST_BE_DIRECTORY |
                              GLNX_CHASE_MUST_BE_SOCKET);
    /* check that no more than one bit is set (= power of two) */
    g_return_val_if_fail ((must_flags & (must_flags - 1)) == 0, -1);
  }

  /* TODO: Add a callback which is called for every resolved path segment, to
   * allow users to verify and expand the functionality safely. */

  /* We need the manual impl for NO_AUTOMOUNT, and we can skip this, if we don't
   * have openat2 at all.
   * Technically racy (static, not synced), but both paths work fine so it
   * doesn't matter. */
  if (can_openat2 && (flags & GLNX_CHASE_NO_AUTOMOUNT) == 0 &&
      (flags & GLNX_CHASE_DEBUG_NO_OPENAT2) == 0)
    {
      uint64_t openat2_flags = 0;
      uint64_t openat2_resolve = 0;
      struct open_how how;

      openat2_flags = O_PATH | O_CLOEXEC;
      if ((flags & GLNX_CHASE_NOFOLLOW) != 0)
        openat2_flags |= O_NOFOLLOW;

      openat2_resolve |= RESOLVE_NO_MAGICLINKS;
      if ((flags & GLNX_CHASE_RESOLVE_BENEATH) != 0)
        openat2_resolve |= RESOLVE_BENEATH;
      if ((flags & GLNX_CHASE_RESOLVE_IN_ROOT) != 0)
        openat2_resolve |= RESOLVE_IN_ROOT;
      if ((flags & GLNX_CHASE_RESOLVE_NO_SYMLINKS) != 0)
        openat2_resolve |= RESOLVE_NO_SYMLINKS;

      how = (struct open_how) {
        .flags = openat2_flags,
        .mode = 0,
        .resolve = openat2_resolve,
      };

      fd = openat2 (dirfd, path, &how, sizeof (how));
      if (fd < 0)
        {
          /* If the syscall is not implemented (ENOSYS) or blocked by
           * seccomp (EPERM), we need to fall back to the manual path chasing
           * via open_tree. */
          if (G_IN_SET (errno, ENOSYS, EPERM))
            can_openat2 = FALSE;
          else
            return glnx_fd_throw_errno (error);
        }
    }

  if (fd < 0)
    {
      fd = chase_manual (dirfd, path, flags, error);
      if (fd < 0)
        return -1;
    }

  if ((flags & (GLNX_CHASE_MUST_BE_REGULAR |
                GLNX_CHASE_MUST_BE_DIRECTORY |
                GLNX_CHASE_MUST_BE_SOCKET)) != 0)
    {
      struct glnx_statx st;

      if (!glnx_statx (fd, "",
                       AT_EMPTY_PATH | AT_SYMLINK_NOFOLLOW |
                       ((flags & GLNX_CHASE_NO_AUTOMOUNT) ? AT_NO_AUTOMOUNT : 0),
                       GLNX_STATX_TYPE,
                       &st,
                       error))
        return -1;

      if ((st.stx_mask & GLNX_STATX_TYPE) == 0)
        {
          errno = ENODATA;
          return glnx_fd_throw_errno_prefix (error, "unable to get file type");
        }

      if ((flags & GLNX_CHASE_MUST_BE_REGULAR) != 0 &&
          !S_ISREG (st.stx_mode))
        {
          if (S_ISDIR (st.stx_mode))
            errno = EISDIR;
          else
            errno = EBADFD;

          return glnx_fd_throw_errno_prefix (error, "not a regular file");
        }

      if ((flags & GLNX_CHASE_MUST_BE_DIRECTORY) != 0 &&
          !S_ISDIR (st.stx_mode))
        {
          errno = ENOTDIR;
          return glnx_fd_throw_errno_prefix (error, "not a directory");
        }

      if ((flags & GLNX_CHASE_MUST_BE_SOCKET) != 0 &&
          !S_ISSOCK (st.stx_mode))
        {
          errno = ENOTSOCK;
          return glnx_fd_throw_errno_prefix (error, "not a socket");
        }
    }

  return g_steal_fd (&fd);
}

/**
 * glnx_chase_and_statxat:
 * @dirfd: a directory file descriptor
 * @path: a path
 * @flags: combination of GlnxChaseFlags flags
 * @mask: combination of GLNX_STATX_ flags
 * @statbuf: a pointer to a struct glnx_statx which will be filled out
 * @error: a #GError
 *
 * Stats the file at @path relative to @dirfd and fills out @statbuf with the
 * result according to the interest mask @mask.
 *
 * See glnx_chaseat for the meaning of @dirfd, @path, and @flags.
 *
 * Returns: the chased file, or -1 with @error set on error
 */
int
glnx_chase_and_statxat (int                 dirfd,
                        const char         *path,
                        GlnxChaseFlags      flags,
                        unsigned int        mask,
                        struct glnx_statx  *statbuf,
                        GError            **error)
{
  glnx_autofd int fd = -1;

  /* other args are checked by glnx_chaseat */
  g_return_val_if_fail (statbuf != NULL, FALSE);

  fd = glnx_chaseat (dirfd, path, flags, error);
  if (fd < 0)
    return -1;

  if (!glnx_statx (fd, "",
                   AT_EMPTY_PATH | AT_SYMLINK_NOFOLLOW |
                   ((flags & GLNX_CHASE_NO_AUTOMOUNT) ? AT_NO_AUTOMOUNT : 0),
                   mask,
                   statbuf,
                   error))
    return -1;

  return g_steal_fd (&fd);
}

===== ./subprojects/libglnx/libglnx.doap =====
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright 2015 Colin Walters
SPDX-License-Identifier: LGPL-2.1-or-later
-->
<Project xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
         xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
         xmlns:foaf="http://xmlns.com/foaf/0.1/"
         xmlns:gnome="http://api.gnome.org/doap-extensions#"
         xmlns="http://usefulinc.com/ns/doap#">

  <name>libglnx</name>
  <shortname>libglnx</shortname>

  <shortdesc xml:lang="en">"Copylib" for system service modules using GLib with Linux</shortdesc>

  <description xml:lang="en">This module is intended for use by
  infrastructure code using GLib that is also Linux specific, such as
  ostree, NetworkManager, and others.
  </description>

  <license rdf:resource="http://usefulinc.com/doap/licenses/lgpl" />
  <support-forum rdf:resource="https://discourse.gnome.org/c/platform/5" />

  <programming-language>C</programming-language>

  <maintainer>
    <foaf:Person>
      <foaf:name>Colin Walters</foaf:name>
      <foaf:mbox rdf:resource="mailto:walters@verbum.org"/>
      <gnome:userid>walters</gnome:userid>
    </foaf:Person>
  </maintainer>

</Project>

===== ./subprojects/libglnx/glnx-fdio.h =====
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
 *
 * Copyright (C) 2014,2015 Colin Walters <walters@verbum.org>.
 * SPDX-License-Identifier: LGPL-2.0-or-later
 *
 * 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 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., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

#pragma once

#include <glnx-backport-autocleanups.h>
#include <glnx-missing.h>
#include <gio/gfiledescriptorbased.h>
#include <limits.h>
#include <dirent.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <stdio.h>
#include <sys/xattr.h>
// For dirname(), and previously basename()
#include <libgen.h>

#include <glnx-macros.h>
#include <glnx-errors.h>

G_BEGIN_DECLS

/* Irritatingly, g_basename() which is what we want
 * is deprecated.
 */
static inline
const char *glnx_basename (const char *path)
{
  const gchar *base = strrchr (path, G_DIR_SEPARATOR);

  if (base)
    return base + 1;

  return path;
}

/* Utilities for standard FILE* */
static inline void
glnx_stdio_file_cleanup (void *filep)
{
  FILE *f = (FILE*)filep;
  if (f)
    fclose (f);
}
G_DEFINE_AUTOPTR_CLEANUP_FUNC(FILE, glnx_stdio_file_cleanup)

/**
 * glnx_stdio_file_flush:
 * Call fflush() and check ferror().
 */
gboolean
glnx_stdio_file_flush (FILE *f, GError **error);

typedef struct {
  gboolean initialized;
  gboolean anonymous;
  int src_dfd;
  int fd;
  char *path;
} GLnxTmpfile;
void glnx_tmpfile_clear (GLnxTmpfile *tmpf);
G_DEFINE_AUTO_CLEANUP_CLEAR_FUNC(GLnxTmpfile, glnx_tmpfile_clear)

gboolean
glnx_open_anonymous_tmpfile (int flags,
                             GLnxTmpfile *out_tmpf,
                             GError **error);

gboolean
glnx_open_anonymous_tmpfile_full (int flags,
                                  const char *dir,
                                  GLnxTmpfile *out_tmpf,
                                  GError **error);


gboolean
glnx_open_tmpfile_linkable_at (int dfd,
                               const char *subpath,
                               int flags,
                               GLnxTmpfile *out_tmpf,
                               GError **error);

typedef enum {
  GLNX_LINK_TMPFILE_REPLACE,
  GLNX_LINK_TMPFILE_NOREPLACE,
  GLNX_LINK_TMPFILE_NOREPLACE_IGNORE_EXIST
} GLnxLinkTmpfileReplaceMode;

gboolean
glnx_link_tmpfile_at (GLnxTmpfile *tmpf,
                      GLnxLinkTmpfileReplaceMode flags,
                      int target_dfd,
                      const char *target,
                      GError **error);

gboolean
glnx_tmpfile_reopen_rdonly (GLnxTmpfile *tmpf,
                            GError **error);

gboolean
glnx_openat_rdonly (int             dfd,
                    const char     *path,
                    gboolean        follow,
                    int            *out_fd,
                    GError        **error);

GBytes *
glnx_fd_readall_bytes (int               fd,
                       GCancellable     *cancellable,
                       GError          **error);

char *
glnx_fd_readall_utf8 (int               fd,
                      gsize            *out_len,
                      GCancellable     *cancellable,
                      GError          **error);

char *
glnx_file_get_contents_utf8_at (int                   dfd,
                                const char           *subpath,
                                gsize                *out_len,
                                GCancellable         *cancellable,
                                GError              **error);

/**
 * GLnxFileReplaceFlags:
 * @GLNX_FILE_REPLACE_DATASYNC_NEW: Call fdatasync() even if the file did not exist
 * @GLNX_FILE_REPLACE_NODATASYNC: Never call fdatasync()
 * @GLNX_FILE_REPLACE_INCREASING_MTIME: Ensure that st_mtime increases (in second precision)
 *
 * Flags controlling file replacement.
 */
typedef enum {
  GLNX_FILE_REPLACE_DATASYNC_NEW = (1 << 0),
  GLNX_FILE_REPLACE_NODATASYNC = (1 << 1),
  GLNX_FILE_REPLACE_INCREASING_MTIME = (1 << 2),
} GLnxFileReplaceFlags;

gboolean
glnx_file_replace_contents_at (int                   dfd,
                               const char           *subpath,
                               const guint8         *buf,
                               gsize                 len,
                               GLnxFileReplaceFlags  flags,
                               GCancellable         *cancellable,
                               GError              **error);

gboolean
glnx_file_replace_contents_with_perms_at (int                   dfd,
                                          const char           *subpath,
                                          const guint8         *buf,
                                          gsize                 len,
                                          mode_t                mode,
                                          uid_t                 uid,
                                          gid_t                 gid,
                                          GLnxFileReplaceFlags  flags,
                                          GCancellable         *cancellable,
                                          GError              **error);

char *
glnx_readlinkat_malloc (int            dfd,
                        const char    *subpath,
                        GCancellable  *cancellable,
                        GError       **error);

int
glnx_loop_write (int fd, const void *buf, size_t nbytes);

int
glnx_regfile_copy_bytes (int fdf, int fdt, off_t max_bytes);

typedef enum {
  GLNX_FILE_COPY_OVERWRITE = (1 << 0),
  GLNX_FILE_COPY_NOXATTRS = (1 << 1),
  GLNX_FILE_COPY_DATASYNC = (1 << 2),
  GLNX_FILE_COPY_NOCHOWN = (1 << 3)
} GLnxFileCopyFlags;

gboolean
glnx_file_copy_at (int                   src_dfd,
                   const char           *src_subpath,
                   const struct stat    *src_stbuf,
                   int                   dest_dfd,
                   const char           *dest_subpath,
                   GLnxFileCopyFlags     copyflags,
                   GCancellable         *cancellable,
                   GError              **error);

int glnx_renameat2_noreplace (int olddirfd, const char *oldpath,
                              int newdirfd, const char *newpath);
int glnx_renameat2_exchange (int olddirfd, const char *oldpath,
                             int newdirfd, const char *newpath);

#ifdef _GNU_SOURCE
/**
 * glnx_try_fallocate:
 * @fd: File descriptor
 * @size: Size
 * @error: Error
 *
 * Wrapper for Linux fallocate().  Explicitly ignores a @size of zero.
 * Also, will silently do nothing if the underlying filesystem doesn't
 * support it.  Use this instead of posix_fallocate(), since the glibc fallback
 * is bad: https://sourceware.org/bugzilla/show_bug.cgi?id=18515
 */
static inline gboolean
glnx_try_fallocate (int      fd,
                    off_t    offset,
                    off_t    size,
                    GError **error)
{
  /* This is just nicer than throwing an error */
  if (size == 0)
    return TRUE;

  if (fallocate (fd, 0, offset, size) < 0)
    {
      if (G_IN_SET(errno, ENOSYS, EOPNOTSUPP))
        ; /* Ignore */
      else
        return glnx_throw_errno_prefix (error, "fallocate");
    }

  return TRUE;
}
#endif

/**
 * glnx_fstat:
 * @fd: FD to stat
 * @buf: (out caller-allocates): Return location for stat details
 * @error: Return location for a #GError, or %NULL
 *
 * Wrapper around fstat() which adds #GError support and ensures that it retries
 * on %EINTR.
 *
 * Returns: %TRUE on success, %FALSE otherwise
 * Since: UNRELEASED
 */
static inline gboolean
glnx_fstat (int           fd,
            struct stat  *buf,
            GError      **error)
{
  if (TEMP_FAILURE_RETRY (fstat (fd, buf)) != 0)
    return glnx_throw_errno_prefix (error, "fstat");
  return TRUE;
}

/**
 * glnx_fchmod:
 * @fd: FD
 * @mode: Mode
 * @error: Return location for a #GError, or %NULL
 *
 * Wrapper around fchmod() which adds #GError support and ensures that it
 * retries on %EINTR.
 *
 * Returns: %TRUE on success, %FALSE otherwise
 * Since: UNRELEASED
 */
static inline gboolean
glnx_fchmod (int           fd,
             mode_t        mode,
             GError      **error)
{
  if (TEMP_FAILURE_RETRY (fchmod (fd, mode)) != 0)
    return glnx_throw_errno_prefix (error, "fchmod");
  return TRUE;
}

/**
 * glnx_fstatat:
 * @dfd: Directory FD to stat beneath
 * @path: Path to stat beneath @dfd
 * @buf: (out caller-allocates): Return location for stat details
 * @flags: Flags to pass to fstatat()
 * @error: Return location for a #GError, or %NULL
 *
 * Wrapper around fstatat() which adds #GError support and ensures that it
 * retries on %EINTR.
 *
 * Returns: %TRUE on success, %FALSE otherwise
 * Since: UNRELEASED
 */
static inline gboolean
glnx_fstatat (int           dfd,
              const gchar  *path,
              struct stat  *buf,
              int           flags,
              GError      **error)
{
  if (TEMP_FAILURE_RETRY (fstatat (dfd, path, buf, flags)) != 0)
    return glnx_throw_errno_prefix (error, "fstatat(%s)", path);
  return TRUE;
}

/**
 * glnx_statx:
 * @dfd: Directory FD to stat beneath
 * @path: Path to stat beneath @dfd
 * @flags: Flags to pass to statx()
 * @mask: Mask to pass to statx()
 * @buf: (out caller-allocates): Return location for statx details
 * @error: Return location for a #GError, or %NULL
 *
 * Wrapper around statx() which adds #GError support and ensures that it
 * retries on %EINTR.
 *
 * The mask to pass must be a combination of GLNX_STATX_* flags which are
 * defined by glnx, which map up with the struct glnx_statx.
 *
 * Returns: %TRUE on success, or %FALSE setting both @error and `errno`
 * Since: UNRELEASED
 */
static inline gboolean
glnx_statx (int                 dfd,
            const char         *path,
            unsigned            flags,
            unsigned int        mask,
            struct glnx_statx  *buf,
            GError            **error)
{
  if (TEMP_FAILURE_RETRY (glnx_statx_syscall (dfd, path, flags, mask, buf)) != 0)
    return glnx_throw_errno_prefix (error, "statx(%s)", path);
  return TRUE;
}

/**
 * glnx_fstatat_allow_noent:
 * @dfd: Directory FD to stat beneath
 * @path: Path to stat beneath @dfd
 * @buf: (out caller-allocates) (allow-none): Return location for stat details
 * @flags: Flags to pass to fstatat()
 * @error: Return location for a #GError, or %NULL
 *
 * Like glnx_fstatat(), but handles `ENOENT` in a non-error way.  Instead,
 * on success `errno` will be zero, otherwise it will be preserved.  Hence
 * you can test `if (errno == 0)` to conditionalize on the file existing,
 * or `if (errno == ENOENT)` for non-existence.
 *
 * Returns: %TRUE on success, %FALSE otherwise (errno is preserved)
 * Since: UNRELEASED
 */
static inline gboolean
glnx_fstatat_allow_noent (int               dfd,
                          const char       *path,
                          struct stat      *out_buf,
                          int               flags,
                          GError          **error)
{
  G_GNUC_UNUSED struct stat unused_stbuf;
  if (TEMP_FAILURE_RETRY (fstatat (dfd, path, out_buf ? out_buf : &unused_stbuf, flags)) != 0)
    {
      if (errno != ENOENT)
        return glnx_throw_errno_prefix (error, "fstatat(%s)", path);
      /* Note we preserve errno as ENOENT */
    }
  else
    errno = 0;
  return TRUE;
}

/**
 * glnx_renameat:
 *
 * Wrapper around renameat() which adds #GError support and ensures that it
 * retries on %EINTR.
 */
static inline gboolean
glnx_renameat (int           src_dfd,
               const gchar  *src_path,
               int           dest_dfd,
               const gchar  *dest_path,
               GError      **error)
{
  if (TEMP_FAILURE_RETRY (renameat (src_dfd, src_path, dest_dfd, dest_path)) != 0)
    return glnx_throw_errno_prefix (error, "renameat(%s, %s)", src_path, dest_path);
  return TRUE;
}

/**
 * glnx_unlinkat:
 *
 * Wrapper around unlinkat() which adds #GError support and ensures that it
 * retries on %EINTR.
 */
static inline gboolean
glnx_unlinkat (int           dfd,
               const gchar  *path,
               int           flags,
               GError      **error)
{
  if (TEMP_FAILURE_RETRY (unlinkat (dfd, path, flags)) != 0)
    return glnx_throw_errno_prefix (error, "unlinkat(%s)", path);
  return TRUE;
}

int glnx_fd_reopen (int      fd,
                    int      flags,
                    GError **error);

G_END_DECLS

===== ./subprojects/libglnx/glnx-chase.h =====
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
 *
 * Copyright (C) 2026 Red Hat, Inc.
 * SPDX-License-Identifier: LGPL-2.1-or-later
 */

#pragma once

#include <glib.h>

typedef enum _GlnxChaseFlags {
  /* Default */
  GLNX_CHASE_DEFAULT = 0,
  /* Disable triggering of automounts */
  GLNX_CHASE_NO_AUTOMOUNT = 1 << 1,
  /* Do not follow the path's right-most component. When the path's right-most
   * component refers to symlink, return O_PATH fd of the symlink. */
  GLNX_CHASE_NOFOLLOW = 1 << 2,
  /* Do not permit the path resolution to succeed if any component of the
   * resolution is not a descendant of the directory indicated by dirfd. */
  GLNX_CHASE_RESOLVE_BENEATH = 1 << 3,
  /* Symlinks are resolved relative to the given dirfd instead of root. */
  GLNX_CHASE_RESOLVE_IN_ROOT = 1 << 4,
  /* Fail if any symlink is encountered. */
  GLNX_CHASE_RESOLVE_NO_SYMLINKS = 1 << 5,
  /* Fail if the path's right-most component is not a regular file */
  GLNX_CHASE_MUST_BE_REGULAR = 1 << 6,
  /* Fail if the path's right-most component is not a directory */
  GLNX_CHASE_MUST_BE_DIRECTORY = 1 << 7,
  /* Fail if the path's right-most component is not a socket */
  GLNX_CHASE_MUST_BE_SOCKET = 1 << 8,
} GlnxChaseFlags;

/* How many iterations to execute before returning ELOOP */
#define GLNX_CHASE_MAX 32

G_BEGIN_DECLS

int glnx_chaseat (int              dirfd,
                  const char      *path,
                  GlnxChaseFlags   flags,
                  GError         **error);

int glnx_chase_and_statxat (int                 dirfd,
                            const char         *path,
                            GlnxChaseFlags      flags,
                            unsigned int        mask,
                            struct glnx_statx  *statbuf,
                            GError            **error);

G_END_DECLS

===== ./subprojects/libglnx/glnx-local-alloc.c =====
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
 *
 * Copyright (C) 2012,2015 Colin Walters <walters@verbum.org>
 * SPDX-License-Identifier: LGPL-2.0-or-later
 *
 * 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 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., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

#include "libglnx-config.h"

#include "glnx-local-alloc.h"

/**
 * SECTION:glnxlocalalloc
 * @title: GLnx local allocation
 * @short_description: Release local variables automatically when they go out of scope
 *
 * These macros leverage the GCC extension __attribute__ ((cleanup))
 * to allow calling a cleanup function such as g_free() when a
 * variable goes out of scope.  See <ulink
 * url="http://gcc.gnu.org/onlinedocs/gcc/Variable-Attributes.html">
 * for more information on the attribute.
 *
 * The provided macros make it easy to use the cleanup attribute for
 * types that come with GLib.  The primary two are #glnx_free and
 * #glnx_unref_object, which correspond to g_free() and
 * g_object_unref(), respectively.
 *
 * The rationale behind this is that particularly when handling error
 * paths, it can be very tricky to ensure the right variables are
 * freed.  With this, one simply applies glnx_unref_object to a
 * locally-allocated #GFile for example, and it will be automatically
 * unreferenced when it goes out of scope.
 *
 * Note - you should only use these macros for <emphasis>stack
 * allocated</emphasis> variables.  They don't provide garbage
 * collection or let you avoid freeing things.  They're simply a
 * compiler assisted deterministic mechanism for calling a cleanup
 * function when a stack frame ends.
 *
 * <example id="gs-lfree"><title>Calling g_free automatically</title>
 * <programlisting>
 *
 * GFile *
 * create_file (GError **error)
 * {
 *   glnx_free char *random_id = NULL;
 *
 *   if (!prepare_file (error))
 *     return NULL;
 *
 *   random_id = alloc_random_id ();
 *
 *   return create_file_real (error);
 *   // Note that random_id is freed here automatically
 * }
 * </programlisting>
 * </example>
 *
 */

===== ./subprojects/libglnx/tests/libglnx-testlib.h =====
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
 *
 * Copyright (C) 2017 Red Hat, Inc.
 * Copyright 2019 Collabora Ltd.
 * SPDX-License-Identifier: LGPL-2.0-or-later
 *
 * 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 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., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

#pragma once

#include <glib.h>

#include "glnx-backport-autoptr.h"

typedef GError _GLnxTestAutoError;
static inline void
_glnx_test_auto_error_cleanup (_GLnxTestAutoError *autoerror)
{
  g_assert_no_error (autoerror);
  /* We could add a clear call here, but no point...we'll have aborted */
}
G_DEFINE_AUTOPTR_CLEANUP_FUNC(_GLnxTestAutoError, _glnx_test_auto_error_cleanup);

#define _GLNX_TEST_DECLARE_ERROR(local_error, error)      \
  g_autoptr(_GLnxTestAutoError) local_error = NULL; \
  GError **error = &local_error

typedef struct _GLnxTestAutoTempDir _GLnxTestAutoTempDir;

_GLnxTestAutoTempDir *_glnx_test_auto_temp_dir_enter (void);
void _glnx_test_auto_temp_dir_leave (_GLnxTestAutoTempDir *dir);
G_DEFINE_AUTOPTR_CLEANUP_FUNC(_GLnxTestAutoTempDir, _glnx_test_auto_temp_dir_leave);

#define _GLNX_TEST_SCOPED_TEMP_DIR \
  G_GNUC_UNUSED g_autoptr(_GLnxTestAutoTempDir) temp_dir = _glnx_test_auto_temp_dir_enter ()

===== ./subprojects/libglnx/tests/test-libglnx-errors.c =====
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
 *
 * Copyright (C) 2017 Red Hat, Inc.
 * SPDX-License-Identifier: LGPL-2.0-or-later
 *
 * 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 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., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

#include "libglnx-config.h"
#include "libglnx.h"
#include <glib.h>
#include <stdlib.h>
#include <gio/gio.h>
#include <string.h>

static void
test_error_throw (void)
{
  g_autoptr(GError) error = NULL;

  g_assert (!glnx_throw (&error, "foo: %s %d", "hello", 42));
  g_assert_error (error, G_IO_ERROR, G_IO_ERROR_FAILED);
  g_assert_cmpstr (error->message, ==, "foo: hello 42");
  g_clear_error (&error);

  gpointer dummy = glnx_null_throw (&error, "literal foo");
  g_assert (dummy == NULL);
  g_assert_error (error, G_IO_ERROR, G_IO_ERROR_FAILED);
  g_assert_cmpstr (error->message, ==, "literal foo");
  g_clear_error (&error);

  gpointer dummy2 = glnx_null_throw (&error, "foo: %s %d", "hola", 24);
  g_assert (dummy2 == NULL);
  g_assert_error (error, G_IO_ERROR, G_IO_ERROR_FAILED);
  g_assert_cmpstr (error->message, ==, "foo: hola 24");
  g_clear_error (&error);
}

static void
test_error_errno (void)
{
  g_autoptr(GError) error = NULL;
  const char noent_path[] = "/enoent-this-should-not-exist";
  int fd;

  fd = open (noent_path, O_RDONLY);
  if (fd < 0)
    {
      g_assert (!glnx_throw_errno (&error));
      g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND);
      g_assert (!glnx_prefix_error (&error, "myprefix"));
      g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND);
      g_assert (g_str_has_prefix (error->message, "myprefix: "));
      g_clear_error (&error);
    }
  else
    g_assert_cmpint (fd, ==, -1);

  fd = open (noent_path, O_RDONLY);
  if (fd < 0)
    {
      gpointer dummy = glnx_null_throw_errno (&error);
      g_assert (dummy == NULL);
      g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND);
      dummy = glnx_prefix_error_null (&error, "myprefix");
      g_assert (dummy == NULL);
      g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND);
      g_assert (g_str_has_prefix (error->message, "myprefix: "));
      g_clear_error (&error);
    }
  else
    g_assert_cmpint (fd, ==, -1);

  fd = open (noent_path, O_RDONLY);
  if (fd < 0)
    {
      g_autofree char *expected_prefix = g_strdup_printf ("Failed to open %s", noent_path);
      g_assert (!glnx_throw_errno_prefix (&error, "Failed to open %s", noent_path));
      g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND);
      g_assert (g_str_has_prefix (error->message, expected_prefix));
      g_clear_error (&error);
      /* And test the legacy wrapper */
      glnx_set_prefix_error_from_errno (&error, "Failed to open %s", noent_path);
      g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND);
      g_assert (g_str_has_prefix (error->message, expected_prefix));
      g_clear_error (&error);
    }
  else
    g_assert_cmpint (fd, ==, -1);

  fd = open (noent_path, O_RDONLY);
  if (fd < 0)
    {
      gpointer dummy = glnx_null_throw_errno_prefix (&error, "Failed to open file");
      g_assert (dummy == NULL);
      g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND);
      g_assert (g_str_has_prefix (error->message, "Failed to open file"));
      g_clear_error (&error);
    }
  else
    g_assert_cmpint (fd, ==, -1);

  fd = open (noent_path, O_RDONLY);
  if (fd < 0)
    {
      gpointer dummy = glnx_null_throw_errno_prefix (&error, "Failed to open %s", noent_path);
      g_assert (dummy == NULL);
      g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND);
      g_assert (g_str_has_prefix (error->message, glnx_strjoina ("Failed to open ", noent_path)));
      g_clear_error (&error);
    }
  else
    g_assert_cmpint (fd, ==, -1);
}

static void
test_error_auto_nothrow (GError **error)
{
  GLNX_AUTO_PREFIX_ERROR("foo", error);
  /* Side effect to avoid otherwise empty function */
  g_assert_no_error (*error);
}

static void
test_error_auto_throw (GError **error)
{
  GLNX_AUTO_PREFIX_ERROR("foo", error);
  (void) glnx_throw (error, "oops");
}

static void
test_error_auto_throw_recurse (GError **error)
{
  GLNX_AUTO_PREFIX_ERROR("foo", error);

  if (TRUE)
    {
      GLNX_AUTO_PREFIX_ERROR("bar", error);
      (void) glnx_throw (error, "oops");
    }
}

static void
test_error_auto (void)
{
  g_autoptr(GError) error = NULL;
  test_error_auto_nothrow (&error);
  g_assert_no_error (error);
  test_error_auto_throw (&error);
  g_assert_nonnull (error);
  g_assert_cmpstr (error->message, ==, "foo: oops");
  g_clear_error (&error);
  test_error_auto_throw_recurse (&error);
  g_assert_nonnull (error);
  g_assert_cmpstr (error->message, ==, "foo: bar: oops");
}

int main (int argc, char **argv)
{
  int ret;

  g_test_init (&argc, &argv, NULL);

  g_test_add_func ("/error-throw", test_error_throw);
  g_test_add_func ("/error-errno", test_error_errno);
  g_test_add_func ("/error-auto", test_error_auto);

  ret = g_test_run();

  return ret;
}

===== ./subprojects/libglnx/tests/test-libglnx-backports.c =====
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
 *
 * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
 * Copyright (C) 2011 Red Hat, Inc.
 * Copyright (C) 2018 Endless OS Foundation, LLC
 * Copyright 2019 Emmanuel Fleury
 * Copyright 2021-2024 Collabora Ltd.
 * SPDX-License-Identifier: LGPL-2.1-or-later AND LicenseRef-old-glib-tests
 */

#include "libglnx-config.h"
#include "libglnx.h"

#include <glib/gstdio.h>
#include <glib-unix.h>

#include <sys/wait.h>
#include <unistd.h>

static void
async_signal_safe_message (const char *message)
{
  if (write (2, message, strlen (message)) < 0 ||
      write (2, "\n", 1) < 0)
    {
      /* ignore: not much we can do */
    }
}

static void test_closefrom_subprocess_einval (void);

static void
test_closefrom (void)
{
  /* Enough file descriptors to be confident that we're operating on
   * all of them */
  const int N_FDS = 20;
  int *fds;
  int fd;
  int i;
  pid_t child;
  int wait_status;

  /* The loop that populates @fds with pipes assumes this */
  g_assert (N_FDS % 2 == 0);

  for (fd = 0; fd <= 2; fd++)
    {
      int flags;

      g_assert_no_errno ((flags = fcntl (fd, F_GETFD)));
      g_assert_no_errno (fcntl (fd, F_SETFD, flags & ~FD_CLOEXEC));
    }

  fds = g_new0 (int, N_FDS);

  for (i = 0; i < N_FDS; i += 2)
    {
      GError *error = NULL;
      int pipefd[2];
      int res;

      /* Intentionally neither O_CLOEXEC nor FD_CLOEXEC */
      res = g_unix_open_pipe (pipefd, 0, &error);
      g_assert (res);
      g_assert_no_error (error);
      g_clear_error (&error);
      fds[i] = pipefd[0];
      fds[i + 1] = pipefd[1];
    }

  child = fork ();

  /* Child process exits with status = 100 + the first wrong fd,
   * or 0 if all were correct */
  if (child == 0)
    {
      for (i = 0; i < N_FDS; i++)
        {
          int flags = fcntl (fds[i], F_GETFD);

          if (flags == -1)
            {
              async_signal_safe_message ("fd should not have been closed");
              _exit (100 + fds[i]);
            }

          if (flags & FD_CLOEXEC)
            {
              async_signal_safe_message ("fd should not have been close-on-exec yet");
              _exit (100 + fds[i]);
            }
        }

      g_fdwalk_set_cloexec (3);

      for (i = 0; i < N_FDS; i++)
        {
          int flags = fcntl (fds[i], F_GETFD);

          if (flags == -1)
            {
              async_signal_safe_message ("fd should not have been closed");
              _exit (100 + fds[i]);
            }

          if (!(flags & FD_CLOEXEC))
            {
              async_signal_safe_message ("fd should have been close-on-exec");
              _exit (100 + fds[i]);
            }
        }

      g_closefrom (3);

      for (fd = 0; fd <= 2; fd++)
        {
          int flags = fcntl (fd, F_GETFD);

          if (flags == -1)
            {
              async_signal_safe_message ("fd should not have been closed");
              _exit (100 + fd);
            }

          if (flags & FD_CLOEXEC)
            {
              async_signal_safe_message ("fd should not have been close-on-exec");
              _exit (100 + fd);
            }
        }

      for (i = 0; i < N_FDS; i++)
        {
          if (fcntl (fds[i], F_GETFD) != -1 || errno != EBADF)
            {
              async_signal_safe_message ("fd should have been closed");
              _exit (100 + fds[i]);
            }
        }

      _exit (0);
    }

  g_assert_no_errno (waitpid (child, &wait_status, 0));

  if (WIFEXITED (wait_status))
    {
      int exit_status = WEXITSTATUS (wait_status);

      if (exit_status != 0)
        g_test_fail_printf ("File descriptor %d in incorrect state", exit_status - 100);
    }
  else
    {
      g_test_fail_printf ("Unexpected wait status %d", wait_status);
    }

  for (i = 0; i < N_FDS; i++)
    g_assert_no_errno (close (fds[i]));

  g_free (fds);

  if (g_test_undefined ())
    {
#if GLIB_CHECK_VERSION (2, 38, 0)
      g_test_trap_subprocess ("/glib-unix/closefrom/subprocess/einval",
                              0, G_TEST_SUBPROCESS_DEFAULT);
#else
      if (g_test_trap_fork (0, 0))
        {
          test_closefrom_subprocess_einval ();
          exit (0);
        }

#endif
      g_test_trap_assert_passed ();
    }
}

static void
test_closefrom_subprocess_einval (void)
{
  int res;
  int errsv;

  g_log_set_always_fatal (G_LOG_FATAL_MASK);
  g_log_set_fatal_mask ("GLib", G_LOG_FATAL_MASK);

  errno = 0;
  res = g_closefrom (-1);
  errsv = errno;
  g_assert_cmpint (res, ==, -1);
  g_assert_cmpint (errsv, ==, EINVAL);

  errno = 0;
  res = g_fdwalk_set_cloexec (-42);
  errsv = errno;
  g_assert_cmpint (res, ==, -1);
  g_assert_cmpint (errsv, ==, EINVAL);
}

/* Testing g_memdup2() function with various positive and negative cases */
static void
test_memdup2 (void)
{
  gchar *str_dup = NULL;
  const gchar *str = "The quick brown fox jumps over the lazy dog";

  /* Testing negative cases */
  g_assert_null (g_memdup2 (NULL, 1024));
  g_assert_null (g_memdup2 (str, 0));
  g_assert_null (g_memdup2 (NULL, 0));

  /* Testing normal usage cases */
  str_dup = g_memdup2 (str, strlen (str) + 1);
  g_assert_nonnull (str_dup);
  g_assert_cmpstr (str, ==, str_dup);

  g_free (str_dup);
}

static void
test_steal_fd (void)
{
  GError *error = NULL;
  gchar *tmpfile = NULL;
  int fd = -42;
  int borrowed;
  int stolen;

  g_assert_cmpint (g_steal_fd (&fd), ==, -42);
  g_assert_cmpint (fd, ==, -1);
  g_assert_cmpint (g_steal_fd (&fd), ==, -1);
  g_assert_cmpint (fd, ==, -1);

  fd = g_file_open_tmp (NULL, &tmpfile, &error);
  g_assert_cmpint (fd, >=, 0);
  g_assert_no_error (error);
  borrowed = fd;
  stolen = g_steal_fd (&fd);
  g_assert_cmpint (fd, ==, -1);
  g_assert_cmpint (borrowed, ==, stolen);

  g_assert_no_errno (close (g_steal_fd (&stolen)));
  g_assert_cmpint (stolen, ==, -1);

  g_assert_no_errno (remove (tmpfile));
  g_free (tmpfile);

  /* Backwards compatibility with older libglnx: glnx_steal_fd is the same
   * as g_steal_fd */
  fd = -23;
  g_assert_cmpint (glnx_steal_fd (&fd), ==, -23);
  g_assert_cmpint (fd, ==, -1);
}

/* Test g_strv_equal() works for various inputs. */
static void
test_strv_equal (void)
{
  const gchar *strv_empty[] = { NULL };
  const gchar *strv_empty2[] = { NULL };
  const gchar *strv_simple[] = { "hello", "you", NULL };
  const gchar *strv_simple2[] = { "hello", "you", NULL };
  const gchar *strv_simple_reordered[] = { "you", "hello", NULL };
  const gchar *strv_simple_superset[] = { "hello", "you", "again", NULL };
  const gchar *strv_another[] = { "not", "a", "coded", "message", NULL };

  g_assert_true (g_strv_equal (strv_empty, strv_empty));
  g_assert_true (g_strv_equal (strv_empty, strv_empty2));
  g_assert_true (g_strv_equal (strv_empty2, strv_empty));
  g_assert_false (g_strv_equal (strv_empty, strv_simple));
  g_assert_false (g_strv_equal (strv_simple, strv_empty));
  g_assert_true (g_strv_equal (strv_simple, strv_simple));
  g_assert_true (g_strv_equal (strv_simple, strv_simple2));
  g_assert_true (g_strv_equal (strv_simple2, strv_simple));
  g_assert_false (g_strv_equal (strv_simple, strv_simple_reordered));
  g_assert_false (g_strv_equal (strv_simple_reordered, strv_simple));
  g_assert_false (g_strv_equal (strv_simple, strv_simple_superset));
  g_assert_false (g_strv_equal (strv_simple_superset, strv_simple));
  g_assert_false (g_strv_equal (strv_simple, strv_another));
  g_assert_false (g_strv_equal (strv_another, strv_simple));
}

int main (int argc, char **argv)
{
  g_test_init (&argc, &argv, NULL);

  g_test_add_func ("/glib-unix/closefrom", test_closefrom);
#if GLIB_CHECK_VERSION (2, 38, 0)
  g_test_add_func ("/glib-unix/closefrom/subprocess/einval",
                   test_closefrom_subprocess_einval);
#endif
  g_test_add_func ("/mainloop/steal-fd", test_steal_fd);
  g_test_add_func ("/strfuncs/memdup2", test_memdup2);
  g_test_add_func ("/strfuncs/strv-equal", test_strv_equal);
  return g_test_run();
}

===== ./subprojects/libglnx/tests/test-libglnx-shutil.c =====
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
 *
 * Copyright © 2017-2019 Endless OS Foundation LLC
 * Copyright © 2024 Collabora Ltd.
 * SPDX-License-Identifier: LGPL-2.0-or-later
 *
 * 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 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., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

#include "libglnx-config.h"
#include "libglnx.h"
#include <glib.h>
#include <stdlib.h>
#include <gio/gio.h>
#include <err.h>
#include <string.h>

#include "libglnx-testlib.h"

static void
test_mkdir_p_parent_unsuitable (void)
{
  _GLNX_TEST_SCOPED_TEMP_DIR;
  _GLNX_TEST_DECLARE_ERROR(local_error, error);
  glnx_autofd int dfd = -1;

  if (!glnx_ensure_dir (AT_FDCWD, "test", 0755, error))
    return;
  if (!glnx_opendirat (AT_FDCWD, "test", FALSE, &dfd, error))
    return;

  if (!glnx_file_replace_contents_at (dfd, "file",
                                      (const guint8 *) "", 0,
                                      GLNX_FILE_REPLACE_NODATASYNC,
                                      NULL, error))
    return;

  if (symlinkat ("nosuchtarget", dfd, "link") < 0)
    {
      glnx_throw_errno_prefix (error, "symlinkat");
      return;
    }

  glnx_shutil_mkdir_p_at (dfd, "file/baz", 0755, NULL, error);
  g_test_message ("mkdir %s -> %s", "file/baz",
                  local_error ? local_error->message : "success");
  g_assert_error (local_error, G_IO_ERROR, G_IO_ERROR_NOT_DIRECTORY);
  g_clear_error (&local_error);

  glnx_shutil_mkdir_p_at (dfd, "link/baz", 0755, NULL, error);
  g_test_message ("mkdir %s -> %s", "link/baz",
                  local_error ? local_error->message : "success");
  g_assert_error (local_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND);
  g_clear_error (&local_error);
}

static void
test_mkdir_p_enoent (void)
{
  _GLNX_TEST_SCOPED_TEMP_DIR;
  _GLNX_TEST_DECLARE_ERROR(local_error, error);
  glnx_autofd int dfd = -1;

  if (!glnx_ensure_dir (AT_FDCWD, "test", 0755, error))
    return;
  if (!glnx_opendirat (AT_FDCWD, "test", FALSE, &dfd, error))
    return;
  if (rmdir ("test") < 0)
    return (void) glnx_throw_errno_prefix (error, "rmdir(%s)", "test");

  /* This should fail with ENOENT. */
  glnx_shutil_mkdir_p_at (dfd, "blah/baz", 0755, NULL, error);
  g_assert_error (local_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND);
  g_clear_error (&local_error);
}

int
main (int    argc,
      char **argv)
{
  int ret;

  g_test_init (&argc, &argv, NULL);

  g_test_add_func ("/mkdir-p/enoent", test_mkdir_p_enoent);
  g_test_add_func ("/mkdir-p/parent-unsuitable", test_mkdir_p_parent_unsuitable);

  ret = g_test_run();

  return ret;
}

===== ./subprojects/libglnx/tests/test-libglnx-fdio.c =====
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
 *
 * Copyright (C) 2017 Red Hat, Inc.
 * SPDX-License-Identifier: LGPL-2.0-or-later
 *
 * 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 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., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

#include "libglnx-config.h"
#include "libglnx.h"
#include <glib.h>
#include <stdlib.h>
#include <gio/gio.h>
#include <err.h>
#include <string.h>

#include "libglnx-testlib.h"

static gboolean
renameat_test_setup (int *out_srcfd, int *out_destfd,
                     GError **error)
{
  glnx_autofd int srcfd = -1;
  glnx_autofd int destfd = -1;

  (void) glnx_shutil_rm_rf_at (AT_FDCWD, "srcdir", NULL, NULL);
  if (mkdir ("srcdir", 0755) < 0)
    err (1, "mkdir");
  if (!glnx_opendirat (AT_FDCWD, "srcdir", TRUE, &srcfd, error))
    return FALSE;
  (void) glnx_shutil_rm_rf_at (AT_FDCWD, "destdir", NULL, NULL);
  if (mkdir ("destdir", 0755) < 0)
    err (1, "mkdir");
  if (!glnx_opendirat (AT_FDCWD, "destdir", TRUE, &destfd, error))
    return FALSE;

  if (!glnx_file_replace_contents_at (srcfd, "foo", (guint8*)"foo contents", strlen ("foo contents"),
                                      GLNX_FILE_REPLACE_NODATASYNC, NULL, error))
    return FALSE;
  if (!glnx_file_replace_contents_at (destfd, "bar", (guint8*)"bar contents", strlen ("bar contents"),
                                      GLNX_FILE_REPLACE_NODATASYNC, NULL, error))
    return FALSE;

  *out_srcfd = srcfd; srcfd = -1;
  *out_destfd = destfd; destfd = -1;
  return TRUE;
}

static void
test_renameat2_noreplace (void)
{
  _GLNX_TEST_DECLARE_ERROR(local_error, error);
  glnx_autofd int srcfd = -1;
  glnx_autofd int destfd = -1;
  struct stat stbuf;

  if (!renameat_test_setup (&srcfd, &destfd, error))
    return;

  if (glnx_renameat2_noreplace (srcfd, "foo", destfd, "bar") == 0)
    g_assert_not_reached ();
  else
    {
      g_assert_cmpint (errno, ==, EEXIST);
    }

  if (glnx_renameat2_noreplace (srcfd, "foo", destfd, "baz") < 0)
    return (void)glnx_throw_errno_prefix (error, "renameat");
  if (!glnx_fstatat (destfd, "bar", &stbuf, AT_SYMLINK_NOFOLLOW, error))
    return;

  if (fstatat (srcfd, "foo", &stbuf, AT_SYMLINK_NOFOLLOW) == 0)
    g_assert_not_reached ();
  else
    g_assert_cmpint (errno, ==, ENOENT);
}

static void
test_renameat2_exchange (void)
{
  _GLNX_TEST_DECLARE_ERROR(local_error, error);

  glnx_autofd int srcfd = -1;
  glnx_autofd int destfd = -1;
  if (!renameat_test_setup (&srcfd, &destfd, error))
    return;

  if (glnx_renameat2_exchange (AT_FDCWD, "srcdir", AT_FDCWD, "destdir") < 0)
    return (void)glnx_throw_errno_prefix (error, "renameat");

  /* Ensure the dir fds are the same */
  struct stat stbuf;
  if (!glnx_fstatat (srcfd, "foo", &stbuf, AT_SYMLINK_NOFOLLOW, error))
    return;
  if (!glnx_fstatat (destfd, "bar", &stbuf, AT_SYMLINK_NOFOLLOW, error))
    return;
  /* But the dirs should be swapped */
  if (!glnx_fstatat (AT_FDCWD, "destdir/foo", &stbuf, AT_SYMLINK_NOFOLLOW, error))
    return;
  if (!glnx_fstatat (AT_FDCWD, "srcdir/bar", &stbuf, AT_SYMLINK_NOFOLLOW, error))
    return;
}

static void
test_tmpfile (void)
{
  _GLNX_TEST_DECLARE_ERROR(local_error, error);

  g_auto(GLnxTmpfile) tmpf = { 0, };
  if (!glnx_open_tmpfile_linkable_at (AT_FDCWD, ".", O_WRONLY|O_CLOEXEC, &tmpf, error))
    return;
  if (glnx_loop_write (tmpf.fd, "foo", strlen ("foo")) < 0)
    return (void)glnx_throw_errno_prefix (error, "write");
  if (glnx_link_tmpfile_at (&tmpf, GLNX_LINK_TMPFILE_NOREPLACE, AT_FDCWD, "foo", error))
    return;
}

static void
test_stdio_file (void)
{
  _GLNX_TEST_DECLARE_ERROR(local_error, error);
  g_auto(GLnxTmpfile) tmpf = { 0, };
  g_autoptr(FILE) f = NULL;

  if (!glnx_open_anonymous_tmpfile (O_RDWR|O_CLOEXEC, &tmpf, error))
    return;
  f = fdopen (tmpf.fd, "w");
  tmpf.fd = -1; /* Ownership was transferred via fdopen() */
  if (!f)
    return (void)glnx_throw_errno_prefix (error, "fdopen");
  if (fwrite ("hello", 1, strlen ("hello"), f) != strlen ("hello"))
    return (void)glnx_throw_errno_prefix (error, "fwrite");
  if (!glnx_stdio_file_flush (f, error))
    return;
}

static void
test_fstatat (void)
{
  _GLNX_TEST_DECLARE_ERROR(local_error, error);
  struct stat stbuf = { 0, };

  if (!glnx_fstatat_allow_noent (AT_FDCWD, ".", &stbuf, 0, error))
    return;
  g_assert_cmpint (errno, ==, 0);
  g_assert_no_error (local_error);
  g_assert (S_ISDIR (stbuf.st_mode));
  if (!glnx_fstatat_allow_noent (AT_FDCWD, "nosuchfile", &stbuf, 0, error))
    return;
  g_assert_cmpint (errno, ==, ENOENT);
  g_assert_no_error (local_error);

  /* test NULL parameter for stat */
  if (!glnx_fstatat_allow_noent (AT_FDCWD, ".", NULL, 0, error))
    return;
  g_assert_cmpint (errno, ==, 0);
  g_assert_no_error (local_error);
  if (!glnx_fstatat_allow_noent (AT_FDCWD, "nosuchfile", NULL, 0, error))
    return;
  g_assert_cmpint (errno, ==, ENOENT);
  g_assert_no_error (local_error);
}

static void
test_filecopy (void)
{
  _GLNX_TEST_DECLARE_ERROR(local_error, error);
  const char foo[] = "foo";
  struct stat stbuf;

  if (!glnx_ensure_dir (AT_FDCWD, "subdir", 0755, error))
    return;

  if (!glnx_file_replace_contents_at (AT_FDCWD, foo, (guint8*)foo, sizeof (foo),
                                      GLNX_FILE_REPLACE_NODATASYNC, NULL, error))
    return;

  /* Copy it into both the same dir and a subdir */
  if (!glnx_file_copy_at (AT_FDCWD, foo, NULL, AT_FDCWD, "bar",
                          GLNX_FILE_COPY_NOXATTRS, NULL, error))
    return;
  if (!glnx_file_copy_at (AT_FDCWD, foo, NULL, AT_FDCWD, "subdir/bar",
                          GLNX_FILE_COPY_NOXATTRS, NULL, error))
    return;
  if (!glnx_fstatat (AT_FDCWD, "subdir/bar", &stbuf, 0, error))
    return;

  if (glnx_file_copy_at (AT_FDCWD, foo, NULL, AT_FDCWD, "bar",
                         GLNX_FILE_COPY_NOXATTRS, NULL, error))
    g_assert_not_reached ();
  g_assert_error (local_error, G_IO_ERROR, G_IO_ERROR_EXISTS);
  g_clear_error (&local_error);

  if (!glnx_file_copy_at (AT_FDCWD, foo, NULL, AT_FDCWD, "bar",
                          GLNX_FILE_COPY_NOXATTRS | GLNX_FILE_COPY_OVERWRITE,
                          NULL, error))
    return;

  if (symlinkat ("nosuchtarget", AT_FDCWD, "link") < 0)
    return (void) glnx_throw_errno_prefix (error, "symlinkat");

  /* Shouldn't be able to overwrite a symlink without GLNX_FILE_COPY_OVERWRITE */
  if (glnx_file_copy_at (AT_FDCWD, foo, NULL, AT_FDCWD, "link",
                         GLNX_FILE_COPY_NOXATTRS,
                         NULL, error))
    g_assert_not_reached ();
  g_assert_error (local_error, G_IO_ERROR, G_IO_ERROR_EXISTS);
  g_clear_error (&local_error);

  /* Test overwriting symlink */
  if (!glnx_file_copy_at (AT_FDCWD, foo, NULL, AT_FDCWD, "link",
                          GLNX_FILE_COPY_NOXATTRS | GLNX_FILE_COPY_OVERWRITE,
                          NULL, error))
    return;

  if (!glnx_fstatat_allow_noent (AT_FDCWD, "nosuchtarget", &stbuf, AT_SYMLINK_NOFOLLOW, error))
    return;
  g_assert_cmpint (errno, ==, ENOENT);
  g_assert_no_error (local_error);

  if (!glnx_fstatat (AT_FDCWD, "link", &stbuf, AT_SYMLINK_NOFOLLOW, error))
    return;
  g_assert (S_ISREG (stbuf.st_mode));
}

static void
test_filecopy_procfs (void)
{
  const char * const pseudo_files[] =
  {
    /* A file in /proc that stat()s as empty (at least on Linux 5.15) */
    "/proc/version",
    /* A file in /sys that stat()s as empty (at least on Linux 5.15) */
    "/sys/fs/cgroup/cgroup.controllers",
    /* A file in /sys that stat()s as non-empty (at least on Linux 5.15) */
    "/sys/fs/ext4/features/meta_bg_resize",
  };
  gsize i;

  for (i = 0; i < G_N_ELEMENTS (pseudo_files); i++)
    {
      _GLNX_TEST_DECLARE_ERROR(local_error, error);
      g_autofree char *contents = NULL;
      g_autofree char *contents_of_copy = NULL;
      gsize len;
      gsize len_copy;

      if (!g_file_get_contents (pseudo_files[i], &contents, &len, error))
        {
          g_test_message ("Not testing %s: %s",
                          pseudo_files[i], local_error->message);
          g_clear_error (&local_error);
          continue;
        }

      if (!glnx_file_copy_at (AT_FDCWD, pseudo_files[i], NULL,
                              AT_FDCWD, "copy",
                              (GLNX_FILE_COPY_OVERWRITE |
                               GLNX_FILE_COPY_NOCHOWN |
                               GLNX_FILE_COPY_NOXATTRS),
                              NULL, error))
        return;

      g_assert_no_error (local_error);

      if (!g_file_get_contents ("copy", &contents_of_copy, &len_copy, error))
        return;

      g_assert_no_error (local_error);

      g_assert_cmpstr (contents, ==, contents_of_copy);
      g_assert_cmpuint (len, ==, len_copy);
    }
}

static void
test_fd_reopen (void)
{
  g_autoptr(GError) error = NULL;
  glnx_autofd int dfd = -1;
  glnx_autofd int opath_fd = -1;
  glnx_autofd int regular_fd = -1;
  glnx_autofd int testfile_fd = -1;
  glnx_autofd int link_opath_fd = -1;
  glnx_autofd int reopened_fd = -1;
  struct stat st1, st2;
  const char *test_data = "test content";
  char buf[100];
  ssize_t n;
  gboolean ok;
  int flags;

  /* Create a test directory and file */
  ok = glnx_shutil_mkdir_p_at_open (AT_FDCWD, "reopen_test", 0755, &dfd, NULL, &error);
  g_assert_no_error (error);
  g_assert_true (ok);
  g_assert_no_errno (dfd);

  glnx_file_replace_contents_at (dfd, "testfile",
                                 (const void *) test_data, strlen (test_data),
                                 GLNX_FILE_REPLACE_NODATASYNC, NULL, &error);
  g_assert_no_error (error);

  /* Test 1: Reopen O_PATH fd as regular fd for reading and writing */
  opath_fd = openat (dfd, "testfile", O_PATH | O_CLOEXEC);
  g_assert_no_errno (opath_fd);

  regular_fd = glnx_fd_reopen (opath_fd, O_RDWR, &error);
  g_assert_no_errno (regular_fd);
  g_assert_no_error (error);

  flags = fcntl (regular_fd, F_GETFL);
  g_assert_no_errno (flags);
  g_assert_cmpint (flags & (O_RDONLY | O_WRONLY | O_RDWR), ==, O_RDWR);
  g_assert_cmpint (flags & (O_PATH | O_DIRECTORY | O_NOFOLLOW), ==, 0);
  flags = fcntl (regular_fd, F_GETFD);
  g_assert_no_errno (flags);
  g_assert_cmpint (flags & FD_CLOEXEC, ==, FD_CLOEXEC);

  /* Verify we can read from the reopened fd */
  n = read (regular_fd, buf, sizeof (buf));
  g_assert_cmpmem (buf, n, test_data, strlen (test_data));

  g_clear_fd (&regular_fd, NULL);
  g_clear_fd (&opath_fd, NULL);

  /* Test 2: Reopen directory fd with O_DIRECTORY */
  opath_fd = openat (AT_FDCWD, "reopen_test", O_PATH | O_CLOEXEC);
  g_assert_no_errno (opath_fd);

  reopened_fd = glnx_fd_reopen (opath_fd, O_RDONLY | O_DIRECTORY, &error);
  g_assert_no_error (error);
  g_assert_no_errno (reopened_fd);

  flags = fcntl (reopened_fd, F_GETFL);
  g_assert_no_errno (flags);
  g_assert_cmpint (flags & (O_RDONLY | O_WRONLY | O_RDWR), ==, O_RDONLY);
  g_assert_cmpint (flags & (O_PATH | O_DIRECTORY | O_NOFOLLOW), ==, O_DIRECTORY);
  flags = fcntl (reopened_fd, F_GETFD);
  g_assert_no_errno (flags);
  g_assert_cmpint (flags & FD_CLOEXEC, ==, FD_CLOEXEC);

  /* Verify both fds point to the same inode */
  g_assert_no_errno (fstat (opath_fd, &st1));
  g_assert_no_errno (fstat (reopened_fd, &st2));
  g_assert_cmpint (st1.st_ino, ==, st2.st_ino);

  g_clear_fd (&reopened_fd, NULL);
  g_clear_fd (&opath_fd, NULL);

  /* Test 3: Reopen AT_FDCWD */
  reopened_fd = glnx_fd_reopen (AT_FDCWD, O_RDONLY | O_DIRECTORY, &error);
  g_assert_no_error (error);
  g_assert_no_errno (reopened_fd);

  g_clear_fd (&reopened_fd, NULL);

  /* Test 4: Test that O_NOFOLLOW is rejected */
  opath_fd = openat (dfd, "testfile", O_PATH | O_CLOEXEC);
  g_assert_no_errno (opath_fd);

  regular_fd = glnx_fd_reopen (opath_fd, O_RDONLY | O_NOFOLLOW, &error);
  g_assert_cmpint (regular_fd, <, 0);
  g_assert_error (error, G_IO_ERROR, G_IO_ERROR_TOO_MANY_LINKS);
  g_clear_error (&error);

  g_clear_fd (&opath_fd, NULL);

  /* Test 5: Reopen O_PATH fd to symlink with O_PATH (should work) */
  g_assert_no_errno (symlinkat ("testfile", dfd, "testlink"));

  link_opath_fd = openat (dfd, "testlink", O_PATH | O_NOFOLLOW);
  g_assert_no_errno (link_opath_fd);

  /* Verify it's a symlink */
  g_assert_no_errno (fstatat (link_opath_fd, "", &st1, AT_EMPTY_PATH | AT_SYMLINK_NOFOLLOW));
  g_assert_true (S_ISLNK (st1.st_mode));

  /* Reopen with O_PATH should work */
  reopened_fd = glnx_fd_reopen (link_opath_fd, O_PATH, &error);
  g_assert_no_error (error);
  g_assert_no_errno (reopened_fd);

  flags = fcntl (reopened_fd, F_GETFL);
  g_assert_no_errno (flags);
  g_assert_cmpint (flags & (O_RDONLY | O_WRONLY | O_RDWR), ==, O_RDONLY);
  g_assert_cmpint (flags & (O_PATH | O_DIRECTORY | O_NOFOLLOW), ==, O_PATH);
  flags = fcntl (reopened_fd, F_GETFD);
  g_assert_no_errno (flags);
  g_assert_cmpint (flags & FD_CLOEXEC, ==, FD_CLOEXEC);

  /* Verify both point to the same symlink */
  g_assert_no_errno (fstatat (reopened_fd, "", &st2, AT_EMPTY_PATH | AT_SYMLINK_NOFOLLOW));
  g_assert_cmpint (st1.st_ino, ==, st2.st_ino);
  g_assert_true (S_ISLNK (st2.st_mode));

  g_clear_fd (&reopened_fd, NULL);

  /* Test 6: Reopening O_PATH fd to symlink without O_PATH should fail with ELOOP */
  reopened_fd = glnx_fd_reopen (link_opath_fd, O_RDONLY, &error);
  g_assert_cmpint (reopened_fd, <, 0);
  g_assert_error (error, G_IO_ERROR, G_IO_ERROR_TOO_MANY_LINKS);
  g_clear_error (&error);

  g_clear_fd (&link_opath_fd, NULL);

  /* Test 7: Verify read index is reset */
  testfile_fd = openat (dfd, "testfile", O_RDONLY | O_CLOEXEC);
  g_assert_no_errno (testfile_fd);

  /* Read some data to advance the read index */
  n = read (testfile_fd, buf, 4);
  g_assert_cmpint (n, ==, 4);

  /* Reopen should reset the read index */
  reopened_fd = glnx_fd_reopen (testfile_fd, O_RDONLY, &error);
  g_assert_no_error (error);
  g_assert_no_errno (reopened_fd);

  /* Should read from the beginning again */
  n = read (reopened_fd, buf, sizeof (buf));
  g_assert_cmpmem (buf, n, test_data, strlen (test_data));

  g_clear_fd (&reopened_fd, NULL);
  g_clear_fd (&testfile_fd, NULL);
}

int main (int argc, char **argv)
{
  _GLNX_TEST_SCOPED_TEMP_DIR;
  int ret;

  g_test_init (&argc, &argv, NULL);

  g_test_add_func ("/tmpfile", test_tmpfile);
  g_test_add_func ("/stdio-file", test_stdio_file);
  g_test_add_func ("/filecopy", test_filecopy);
  g_test_add_func ("/filecopy-procfs", test_filecopy_procfs);
  g_test_add_func ("/renameat2-noreplace", test_renameat2_noreplace);
  g_test_add_func ("/renameat2-exchange", test_renameat2_exchange);
  g_test_add_func ("/fstat", test_fstatat);
  g_test_add_func ("/fd-reopen", test_fd_reopen);

  ret = g_test_run();

  return ret;
}

===== ./subprojects/libglnx/tests/testing-helper.c =====
/*
 * Based on glib/tests/testing-helper.c from GLib
 *
 * Copyright 2018-2022 Collabora Ltd.
 * Copyright 2019 Руслан Ижбулатов
 * Copyright 2018-2022 Endless OS Foundation LLC
 *
 * SPDX-License-Identifier: LGPL-2.1-or-later
 *
 * 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, see
 * <http://www.gnu.org/licenses/>.
 */

#include "libglnx-config.h"
#include "libglnx.h"

#include <glib.h>
#include <glib/gstdio.h>
#include <locale.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>

static const char *null = NULL;
static const char *nonnull = "not null";

static void
test_pass (void)
{
}

static void
test_messages (void)
{
  g_test_message ("This message has multiple lines.\n"
                  "In older GLib, it would corrupt TAP output.\n"
                  "That's why libglnx provides a wrapper.\n");
}

static void
test_assertion_failure_true (void)
{
  g_assert_true (null != NULL);
}

static void
test_assertion_failure_false (void)
{
  g_assert_false (null == NULL);
}

static void
test_assertion_failure_nonnull (void)
{
  g_assert_nonnull (null);
}

static void
test_assertion_failure_null (void)
{
  g_assert_null (nonnull);
}

static void
test_assertion_failure_mem_null_nonnull (void)
{
  g_assert_cmpmem (null, 0, nonnull, strlen (nonnull));
}

static void
test_assertion_failure_mem_nonnull_null (void)
{
  g_assert_cmpmem (nonnull, strlen (nonnull), null, 0);
}

static void
test_assertion_failure_mem_len (void)
{
  g_assert_cmpmem (nonnull, strlen (nonnull), nonnull, 0);
}

static void
test_assertion_failure_mem_cmp (void)
{
  g_assert_cmpmem (nonnull, 4, nonnull + 4, 4);
}

static void
test_assertion_failure_cmpfloat_with_epsilon (void)
{
  g_assert_cmpfloat_with_epsilon (1.0, 1.5, 0.001);
}

static void
test_assertion_failure_cmpvariant (void)
{
  g_autoptr(GVariant) a = g_variant_ref_sink (g_variant_new ("i", 42));
  g_autoptr(GVariant) b = g_variant_ref_sink (g_variant_new ("u", 42));

  g_assert_cmpvariant (a, b);
}

static void
test_assertion_failure_errno (void)
{
  g_assert_no_errno (mkdir ("/", 0755));
}

static void
test_assertion_failure_cmpstrv_null_nonnull (void)
{
  const char * const b[] = { NULL };

  g_assert_cmpstrv (NULL, b);
}

static void
test_assertion_failure_cmpstrv_nonnull_null (void)
{
  const char * const a[] = { NULL };

  g_assert_cmpstrv (a, NULL);
}

static void
test_assertion_failure_cmpstrv_len (void)
{
  const char * const a[] = { "one", NULL };
  const char * const b[] = { NULL };

  g_assert_cmpstrv (a, b);
}

static void
test_assertion_failure_cmpstrv_cmp (void)
{
  const char * const a[] = { "one", "two", NULL };
  const char * const b[] = { "one", "three", NULL };

  g_assert_cmpstrv (a, b);
}

static void
test_skip (void)
{
  g_test_skip ("not enough tea");
}

static void
test_skip_printf (void)
{
  const char *beverage = "coffee";

  g_test_skip_printf ("not enough %s", beverage);
}

static void
test_fail (void)
{
  g_test_fail ();
}

static void
test_fail_printf (void)
{
  g_test_fail_printf ("this test intentionally left failing");
}

static void
test_incomplete (void)
{
  g_test_incomplete ("mind reading not implemented yet");
}

static void
test_incomplete_printf (void)
{
  const char *operation = "telekinesis";

  g_test_incomplete_printf ("%s not implemented yet", operation);
}

static void
test_summary (void)
{
  g_test_summary ("Tests that g_test_summary() works with TAP, by outputting a "
                  "known summary message in testing-helper, and checking for "
                  "it in the TAP output later.");
}

int
main (int   argc,
      char *argv[])
{
  char *argv1;

  setlocale (LC_ALL, "");

#ifdef G_OS_WIN32
  /* Windows opens std streams in text mode, with \r\n EOLs.
   * Sometimes it's easier to force a switch to binary mode than
   * to account for extra \r in testcases.
   */
  setmode (fileno (stdout), O_BINARY);
#endif

  g_return_val_if_fail (argc > 1, 1);
  argv1 = argv[1];

  if (argc > 2)
    memmove (&argv[1], &argv[2], (argc - 2) * sizeof (char *));

  argc -= 1;
  argv[argc] = NULL;

  if (g_strcmp0 (argv1, "init-null-argv0") == 0)
    {
      int test_argc = 0;
      char *test_argva[1] = { NULL };
      char **test_argv = test_argva;

      /* Test that `g_test_init()` can handle being called with an empty argv
       * and argc == 0. While this isn’t recommended, it is possible for another
       * process to use execve() to call a gtest process this way, so we’d
       * better handle it gracefully.
       *
       * This test can’t be run after `g_test_init()` has been called normally,
       * as it isn’t allowed to be called more than once in a process. */
      g_test_init (&test_argc, &test_argv, NULL);

      return 0;
    }

  g_test_init (&argc, &argv, NULL);
  g_test_disable_crash_reporting ();
#if GLIB_CHECK_VERSION(2, 38, 0)
  g_test_set_nonfatal_assertions ();
#endif

  if (g_strcmp0 (argv1, "pass") == 0)
    {
      g_test_add_func ("/pass", test_pass);
    }
  else if (g_strcmp0 (argv1, "messages") == 0)
    {
      g_test_add_func ("/messages", test_messages);
    }
  else if (g_strcmp0 (argv1, "skip") == 0)
    {
      g_test_add_func ("/skip", test_skip);
    }
  else if (g_strcmp0 (argv1, "skip-printf") == 0)
    {
      g_test_add_func ("/skip-printf", test_skip_printf);
    }
  else if (g_strcmp0 (argv1, "incomplete") == 0)
    {
      g_test_add_func ("/incomplete", test_incomplete);
    }
  else if (g_strcmp0 (argv1, "incomplete-printf") == 0)
    {
      g_test_add_func ("/incomplete-printf", test_incomplete_printf);
    }
  else if (g_strcmp0 (argv1, "fail") == 0)
    {
      g_test_add_func ("/fail", test_fail);
    }
  else if (g_strcmp0 (argv1, "fail-printf") == 0)
    {
      g_test_add_func ("/fail-printf", test_fail_printf);
    }
  else if (g_strcmp0 (argv1, "all-non-failures") == 0)
    {
      g_test_add_func ("/pass", test_pass);
      g_test_add_func ("/skip", test_skip);
      g_test_add_func ("/incomplete", test_incomplete);
    }
  else if (g_strcmp0 (argv1, "all") == 0)
    {
      g_test_add_func ("/pass", test_pass);
      g_test_add_func ("/skip", test_skip);
      g_test_add_func ("/incomplete", test_incomplete);
      g_test_add_func ("/fail", test_fail);
    }
  else if (g_strcmp0 (argv1, "skip-options") == 0)
    {
      /* The caller is expected to skip some of these with
       * -p/-r, -s/-x and/or --GTestSkipCount */
      g_test_add_func ("/a", test_pass);
      g_test_add_func ("/b", test_pass);
      g_test_add_func ("/b/a", test_pass);
      g_test_add_func ("/b/b", test_pass);
      g_test_add_func ("/b/b/a", test_pass);
      g_test_add_func ("/prefix/a", test_pass);
      g_test_add_func ("/prefix/b/b", test_pass);
      g_test_add_func ("/prefix-long/a", test_pass);
      g_test_add_func ("/c/a", test_pass);
      g_test_add_func ("/d/a", test_pass);
    }
  else if (g_strcmp0 (argv1, "summary") == 0)
    {
      g_test_add_func ("/summary", test_summary);
    }
  else if (g_strcmp0 (argv1, "assertion-failures") == 0)
    {
      /* Use -p to select a specific one of these */
#define T(x) g_test_add_func ("/assertion-failure/" #x, test_assertion_failure_ ## x)
      T (true);
      T (false);
      T (nonnull);
      T (null);
      T (mem_null_nonnull);
      T (mem_nonnull_null);
      T (mem_len);
      T (mem_cmp);
      T (cmpfloat_with_epsilon);
      T (cmpvariant);
      T (errno);
      T (cmpstrv_null_nonnull);
      T (cmpstrv_nonnull_null);
      T (cmpstrv_len);
      T (cmpstrv_cmp);
#undef T
    }
  else
    {
      g_assert_not_reached ();
    }

  return g_test_run ();
}

===== ./subprojects/libglnx/tests/use-as-subproject/README =====
This is a simple example of a project that uses libglnx as a subproject.
The intention is that if this project can successfully build and use libglnx
as a subproject, then so could Flatpak.

<!--
Copyright 2022 Collabora Ltd.
SPDX-License-Identifier: LGPL-2.0-or-later
-->

===== ./subprojects/libglnx/tests/use-as-subproject/trivial.c =====
/*
 * Copyright 2022 Collabora Ltd.
 * SPDX-License-Identifier: LGPL-2.0-or-later
 */

#include <glib.h>

int
main (void)
{
  GError *error = NULL;

  g_clear_error (&error);
  return 0;
}

===== ./subprojects/libglnx/tests/use-as-subproject/meson.build =====
# Copyright 2022 Collabora Ltd.
# SPDX-License-Identifier: LGPL-2.0-or-later

project(
  'use-libglnx-as-subproject',
  'c',
  default_options : [
    'c_std=gnu99',
    'warning_level=3',
  ],
  version : '0',
  meson_version : '>=0.49.0',
)

configure_file(
  copy : true,
  input : 'dummy-config.h.in',
  output : 'config.h',
)

glib_dep = dependency('glib-2.0')

libglnx = subproject('libglnx')
libglnx_dep = libglnx.get_variable('libglnx_dep')
libglnx_testlib_dep = libglnx.get_variable('libglnx_testlib_dep')

# This executable is compiled at warning_level=3 by default
executable(
  'trivial',
  'trivial.c',
  dependencies : [glib_dep],
)

# These can't be compiled at warning_level=3 because they use non-ISO
# compiler features in the libglnx headers, which would be warnings or
# errors with -Wpedantic
executable(
  'use-libglnx',
  'use-libglnx.c',
  dependencies : [libglnx_dep, glib_dep],
  override_options : ['warning_level=2'],
)
executable(
  'use-testlib',
  'use-testlib.c',
  dependencies : [libglnx_testlib_dep, glib_dep],
  override_options : ['warning_level=2'],
)

===== ./subprojects/libglnx/tests/use-as-subproject/use-libglnx.c =====
/*
 * Copyright 2022 Collabora Ltd.
 * SPDX-License-Identifier: LGPL-2.0-or-later
 */

#include <libglnx.h>

int
main (void)
{
  GError *error = NULL;

  glnx_throw (&error, "whatever");
  g_clear_error (&error);
  return 0;
}

===== ./subprojects/libglnx/tests/use-as-subproject/dummy-config.h.in =====
/*
 * Copyright 2022 Collabora Ltd.
 * SPDX-License-Identifier: LGPL-2.0-or-later
 */

#error Should not use superproject generated config.h to compile libglnx

===== ./subprojects/libglnx/tests/use-as-subproject/.gitignore =====
# Copyright 2022 Collabora Ltd.
# SPDX-License-Identifier: LGPL-2.0-or-later

/_build/
/subprojects/

===== ./subprojects/libglnx/tests/use-as-subproject/config.h =====
/*
 * Copyright 2022 Collabora Ltd.
 * SPDX-License-Identifier: LGPL-2.0-or-later
 */

#error Should not use superproject config.h to compile libglnx

===== ./subprojects/libglnx/tests/use-as-subproject/use-testlib.c =====
/*
 * Copyright 2022 Collabora Ltd.
 * SPDX-License-Identifier: LGPL-2.0-or-later
 */

#include <libglnx.h>
#include <libglnx-testlib.h>

int
main (void)
{
  _GLNX_TEST_DECLARE_ERROR (local_error, error);

  glnx_throw (error, "Whatever");
  g_clear_error (&local_error);
  return 0;
}

===== ./subprojects/libglnx/tests/libglnx-testlib.c =====
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
 *
 * Copyright 2019 Collabora Ltd.
 * SPDX-License-Identifier: LGPL-2.0-or-later
 *
 * 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 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., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

#include "libglnx-config.h"
#include "libglnx-testlib.h"

#include <errno.h>

#include <glib/gstdio.h>

#include "libglnx.h"

struct _GLnxTestAutoTempDir
{
  gchar *old_cwd;
  int old_cwd_fd;
  GLnxTmpDir temp_dir;
};

_GLnxTestAutoTempDir *
_glnx_test_auto_temp_dir_enter (void)
{
  GError *error = NULL;
  _GLnxTestAutoTempDir *ret = g_new0 (_GLnxTestAutoTempDir, 1);

  glnx_mkdtemp ("glnx-test-XXXXXX", 0700, &ret->temp_dir, &error);
  g_assert_no_error (error);

  /* just for better diagnostics */
  ret->old_cwd = g_get_current_dir ();

  glnx_opendirat (-1, ".", TRUE, &ret->old_cwd_fd, &error);
  g_assert_no_error (error);

  if (fchdir (ret->temp_dir.fd) != 0)
    g_error ("fchdir(<fd for \"%s\">): %s", ret->temp_dir.path, g_strerror (errno));

  return ret;
}

void
_glnx_test_auto_temp_dir_leave (_GLnxTestAutoTempDir *dir)
{
  GError *error = NULL;

  if (fchdir (dir->old_cwd_fd) != 0)
    g_error ("fchdir(<fd for \"%s\">): %s", dir->old_cwd, g_strerror (errno));

  glnx_tmpdir_delete (&dir->temp_dir, NULL, &error);
  g_assert_no_error (error);

  glnx_close_fd (&dir->old_cwd_fd);

  g_free (dir->old_cwd);
  g_free (dir);
}

===== ./subprojects/libglnx/tests/test-libglnx-testing.c =====
/*
 * Copyright 2022 Simon McVittie
 * SPDX-License-Identifier: LGPL-2.1-or-later
 *
 * 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, see
 * <http://www.gnu.org/licenses/>.
 */

#include "libglnx-config.h"
#include "libglnx.h"

#include <glib.h>
#include <glib/gstdio.h>

#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/wait.h>

#if GLIB_CHECK_VERSION (2, 38, 0)
#define GTEST_TAP_OR_VERBOSE "--tap"
#else
#define GTEST_TAP_OR_VERBOSE "--verbose"
#endif

static const char *null = NULL;
static const char *nonnull = "not null";

static void
test_assertions (void)
{
  const char *other_nonnull = "not null";
  g_autoptr(GVariant) va = g_variant_ref_sink (g_variant_new ("i", 42));
  g_autoptr(GVariant) vb = g_variant_ref_sink (g_variant_new ("i", 42));
  const char * const strv1[] = {"one", "two", NULL};
  const char * const strv2[] = {"one", "two", NULL};
  GStatBuf statbuf;

  g_assert_true (null == NULL);
  g_assert_false (null != NULL);
  g_assert_null (null);
  g_assert_nonnull (nonnull);
  g_assert_cmpmem (null, 0, null, 0);
  g_assert_cmpmem (nonnull, strlen (nonnull), other_nonnull, strlen (other_nonnull));
  g_assert_cmpfloat_with_epsilon (1.0, 1.00001, 0.01);
  g_assert_cmpvariant (va, vb);
  g_assert_no_errno (g_stat ("/", &statbuf));
  g_assert_cmpstrv (NULL, NULL);
  g_assert_cmpstrv (&null, &null);
  g_assert_cmpstrv (strv1, strv2);
}

static void
test_assertion_failures (void)
{
  static const char * const assertion_failures[] =
  {
    "true",
    "false",
    "nonnull",
    "null",
    "mem_null_nonnull",
    "mem_nonnull_null",
    "mem_len",
    "mem_cmp",
    "cmpfloat_with_epsilon",
    "cmpvariant",
    "errno",
    "cmpstrv_null_nonnull",
    "cmpstrv_nonnull_null",
    "cmpstrv_len",
    "cmpstrv_cmp",
  };
  g_autoptr(GError) error = NULL;
  g_autofree char *self = NULL;
  g_autofree char *dir = NULL;
  g_autofree char *exe = NULL;
  gsize i;

  self = glnx_readlinkat_malloc (-1, "/proc/self/exe", NULL, &error);
  g_assert_no_error (error);

  dir = g_path_get_dirname (self);
  exe = g_build_filename (dir, "testing-helper", NULL);

  for (i = 0; i < G_N_ELEMENTS (assertion_failures); i++)
    {
      g_autofree char *out = NULL;
      g_autofree char *err = NULL;
      g_autofree char *name = g_strdup_printf ("/assertion-failure/%s", assertion_failures[i]);
      int wait_status = -1;
      const char *argv[] = { NULL, "assertion-failures", "-p", NULL, NULL, NULL };
      char *line;
      char *saveptr = NULL;

      argv[0] = exe;
      argv[3] = name;
      argv[4] = GTEST_TAP_OR_VERBOSE;
      g_test_message ("%s assertion-failures -p %s %s...", exe, name, GTEST_TAP_OR_VERBOSE);

      g_spawn_sync (NULL,   /* cwd */
                    (char **) argv,
                    NULL,   /* envp */
                    G_SPAWN_DEFAULT,
                    NULL,   /* child setup */
                    NULL,   /* user data */
                    &out,
                    &err,
                    &wait_status,
                    &error);
      g_assert_no_error (error);

      g_assert_nonnull (out);
      g_assert_nonnull (err);

      for (line = strtok_r (out, "\n", &saveptr);
           line != NULL;
           line = strtok_r (NULL, "\n", &saveptr))
        g_test_message ("stdout: %s", line);

      saveptr = NULL;

      for (line = strtok_r (err, "\n", &saveptr);
           line != NULL;
           line = strtok_r (NULL, "\n", &saveptr))
        g_test_message ("stderr: %s", line);

      g_test_message ("wait status: 0x%x", wait_status);

      /* It exited with a nonzero status that was not exit status 77 */
      G_STATIC_ASSERT (WIFEXITED (0));
      G_STATIC_ASSERT (WEXITSTATUS (0) == 0);
      g_assert_cmphex (wait_status, !=, 0);
      G_STATIC_ASSERT (WIFEXITED (77 << 8));
      G_STATIC_ASSERT (WEXITSTATUS (77 << 8) == 77);
      g_assert_cmphex (wait_status, !=, (77 << 8));
    }
}

static void
test_failures (void)
{
  static const char * const failures[] =
  {
    "fail",
    "fail-printf",
  };
  g_autoptr(GError) error = NULL;
  g_autofree char *self = NULL;
  g_autofree char *dir = NULL;
  g_autofree char *exe = NULL;
  gsize i;

  self = glnx_readlinkat_malloc (-1, "/proc/self/exe", NULL, &error);
  g_assert_no_error (error);

  dir = g_path_get_dirname (self);
  exe = g_build_filename (dir, "testing-helper", NULL);

  for (i = 0; i < G_N_ELEMENTS (failures); i++)
    {
      g_autofree char *out = NULL;
      g_autofree char *err = NULL;
      int wait_status = -1;
      const char *argv[] = { NULL, NULL, NULL, NULL };
      char *line;
      char *saveptr = NULL;

      argv[0] = exe;
      argv[1] = failures[i];
      argv[2] = GTEST_TAP_OR_VERBOSE;
      g_test_message ("%s %s %s...", exe, failures[i], GTEST_TAP_OR_VERBOSE);

      g_spawn_sync (NULL,   /* cwd */
                    (char **) argv,
                    NULL,   /* envp */
                    G_SPAWN_DEFAULT,
                    NULL,   /* child setup */
                    NULL,   /* user data */
                    &out,
                    &err,
                    &wait_status,
                    &error);
      g_assert_no_error (error);

      for (line = strtok_r (out, "\n", &saveptr);
           line != NULL;
           line = strtok_r (NULL, "\n", &saveptr))
        g_test_message ("stdout: %s", line);

      saveptr = NULL;

      for (line = strtok_r (err, "\n", &saveptr);
           line != NULL;
           line = strtok_r (NULL, "\n", &saveptr))
        g_test_message ("stderr: %s", line);

      g_test_message ("wait status: 0x%x", wait_status);

      G_STATIC_ASSERT (WIFEXITED (0));
      G_STATIC_ASSERT (WEXITSTATUS (0) == 0);
      G_STATIC_ASSERT (WIFEXITED (77 << 8));
      G_STATIC_ASSERT (WEXITSTATUS (77 << 8) == 77);

      g_assert_cmphex (wait_status, !=, 0);
      g_assert_cmphex (wait_status, !=, (77 << 8));
    }
}

static void
test_skips (void)
{
  static const char * const skips[] =
  {
    "skip",
    "skip-printf",
    "incomplete",
    "incomplete-printf",
  };
  g_autoptr(GError) error = NULL;
  g_autofree char *self = NULL;
  g_autofree char *dir = NULL;
  g_autofree char *exe = NULL;
  gsize i;

  self = glnx_readlinkat_malloc (-1, "/proc/self/exe", NULL, &error);
  g_assert_no_error (error);

  dir = g_path_get_dirname (self);
  exe = g_build_filename (dir, "testing-helper", NULL);

  for (i = 0; i < G_N_ELEMENTS (skips); i++)
    {
      g_autofree char *out = NULL;
      g_autofree char *err = NULL;
      int wait_status = -1;
      const char *argv[] = { NULL, NULL, NULL, NULL };
      char *line;
      char *saveptr = NULL;

      argv[0] = exe;
      argv[1] = skips[i];
      argv[2] = GTEST_TAP_OR_VERBOSE;
      g_test_message ("%s %s %s...", exe, skips[i], GTEST_TAP_OR_VERBOSE);

      g_spawn_sync (NULL,   /* cwd */
                    (char **) argv,
                    NULL,   /* envp */
                    G_SPAWN_DEFAULT,
                    NULL,   /* child setup */
                    NULL,   /* user data */
                    &out,
                    &err,
                    &wait_status,
                    &error);
      g_assert_no_error (error);

      for (line = strtok_r (out, "\n", &saveptr);
           line != NULL;
           line = strtok_r (NULL, "\n", &saveptr))
        g_test_message ("stdout: %s", line);

      saveptr = NULL;

      for (line = strtok_r (err, "\n", &saveptr);
           line != NULL;
           line = strtok_r (NULL, "\n", &saveptr))
        g_test_message ("stderr: %s", line);

      g_test_message ("wait status: 0x%x", wait_status);

      G_STATIC_ASSERT (WIFEXITED (0));
      G_STATIC_ASSERT (WEXITSTATUS (0) == 0);
      G_STATIC_ASSERT (WIFEXITED (77 << 8));
      G_STATIC_ASSERT (WEXITSTATUS (77 << 8) == 77);

      /* Ideally the exit status is 77, but it might be 0 with older GLib */
      if (wait_status != 0)
        g_assert_cmphex (wait_status, ==, (77 << 8));
    }
}

static void
test_successes (void)
{
  static const char * const successes[] =
  {
    "messages",
    "pass",
    "summary",
  };
  g_autoptr(GError) error = NULL;
  g_autofree char *self = NULL;
  g_autofree char *dir = NULL;
  g_autofree char *exe = NULL;
  gsize i;

  self = glnx_readlinkat_malloc (-1, "/proc/self/exe", NULL, &error);
  g_assert_no_error (error);

  dir = g_path_get_dirname (self);
  exe = g_build_filename (dir, "testing-helper", NULL);

  for (i = 0; i < G_N_ELEMENTS (successes); i++)
    {
      g_autofree char *out = NULL;
      g_autofree char *err = NULL;
      int wait_status = -1;
      const char *argv[] = { NULL, NULL, NULL, NULL };
      char *line;
      char *saveptr = NULL;

      argv[0] = exe;
      argv[1] = successes[i];
      argv[2] = GTEST_TAP_OR_VERBOSE;
      g_test_message ("%s %s %s...", exe, successes[i], GTEST_TAP_OR_VERBOSE);

      g_spawn_sync (NULL,   /* cwd */
                    (char **) argv,
                    NULL,   /* envp */
                    G_SPAWN_DEFAULT,
                    NULL,   /* child setup */
                    NULL,   /* user data */
                    &out,
                    &err,
                    &wait_status,
                    &error);
      g_assert_no_error (error);

      for (line = strtok_r (out, "\n", &saveptr);
           line != NULL;
           line = strtok_r (NULL, "\n", &saveptr))
        g_test_message ("stdout: %s", line);

      saveptr = NULL;

      for (line = strtok_r (err, "\n", &saveptr);
           line != NULL;
           line = strtok_r (NULL, "\n", &saveptr))
        g_test_message ("stderr: %s", line);

      g_test_message ("wait status: 0x%x", wait_status);

      G_STATIC_ASSERT (WIFEXITED (0));
      G_STATIC_ASSERT (WEXITSTATUS (0) == 0);
      g_assert_cmphex (wait_status, ==, 0);
    }
}

int
main (int argc, char **argv)
{
  g_test_init (&argc, &argv, NULL);
  g_test_add_func ("/assertions", test_assertions);
  g_test_add_func ("/assertion_failures", test_assertion_failures);
  g_test_add_func ("/failures", test_failures);
  g_test_add_func ("/skips", test_skips);
  g_test_add_func ("/successes", test_successes);
  return g_test_run();
}

===== ./subprojects/libglnx/tests/meson.build =====
# Copyright 2019 Endless OS Foundation LLC
# Copyright 2019 Collabora Ltd.
# SPDX-License-Identifier: LGPL-2.1-or-later

libglnx_testlib = static_library(
  'glnx-testlib',
  'libglnx-testlib.c',
  'libglnx-testlib.h',
  dependencies : [
    libglnx_dep,
    libglnx_deps,
  ],
  install : false,
)
libglnx_testlib_dep = declare_dependency(
  dependencies : [
    libglnx_dep,
    libglnx_deps,
  ],
  include_directories : include_directories('.'),
  link_with : libglnx_testlib,
)

if get_option('tests')
  testing_helper = executable(
    'testing-helper',
    'testing-helper.c',
    dependencies : [
      libglnx_dep,
      libglnx_deps,
    ],
    install : false,
  )

  test_names = [
    'backports',
    'chase',
    'errors',
    'fdio',
    'macros',
    'shutil',
    'testing',
    'xattrs',
  ]

  foreach test_name : test_names
    exe = executable(test_name,
      [
        'test-libglnx-' + test_name + '.c',
      ],
      dependencies: [
        libglnx_dep,
        libglnx_deps,
        libglnx_testlib_dep,
      ],
    )
    test(test_name, exe, depends: testing_helper)
  endforeach
endif

===== ./subprojects/libglnx/tests/test-libglnx-xattrs.c =====
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
 *
 * Copyright (C) 2017 Red Hat, Inc.
 * SPDX-License-Identifier: LGPL-2.0-or-later
 *
 * 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 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., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

#include "libglnx-config.h"
#include "libglnx.h"
#include <glib.h>
#include <stdlib.h>
#include <gio/gio.h>
#include <string.h>

#define XATTR_THREAD_RUN_TIME_USECS (5 * G_USEC_PER_SEC)

struct XattrWorker {
  int dfd;
  gboolean is_writer;
  guint n_attrs_read;
};

typedef enum {
  WRITE_RUN_MUTATE,
  WRITE_RUN_CREATE,
} WriteType;

static gboolean
set_random_xattr_value (int fd, const char *name, GError **error)
{
  const guint8 randxattrbyte = g_random_int_range (0, 256);
  const guint32 randxattrvalue_len = (g_random_int () % 256) + 1; /* Picked to be not too small or large */
  g_autofree char *randxattrvalue = g_malloc (randxattrvalue_len);

  memset (randxattrvalue, randxattrbyte, randxattrvalue_len);

  if (fsetxattr (fd, name, randxattrvalue, randxattrvalue_len, 0) < 0)
    {
      glnx_set_error_from_errno (error);
      return FALSE;
    }

  return TRUE;
}

static gboolean
add_random_xattrs (int fd, GError **error)
{
  const guint nattrs = MIN (2, g_random_int () % 16);

  for (guint i = 0; i < nattrs; i++)
    {
      guint32 randxattrname_v = g_random_int ();
      g_autofree char *randxattrname = g_strdup_printf ("user.test%u", randxattrname_v);

      if (!set_random_xattr_value (fd, randxattrname, error))
        return FALSE;
    }

  return TRUE;
}

static gboolean
do_write_run (GLnxDirFdIterator *dfd_iter, GError **error)
{
  WriteType wtype = g_random_int () % 2;

  if (wtype == WRITE_RUN_CREATE)
    {
      guint32 randname_v = g_random_int ();
      g_autofree char *randname = g_strdup_printf ("file%u", randname_v);
      glnx_autofd int fd = -1;

    again:
      fd = openat (dfd_iter->fd, randname, O_CREAT | O_EXCL, 0644);
      if (fd < 0)
        {
          if (errno == EEXIST)
            {
              g_printerr ("Congratulations!  I suggest purchasing a lottery ticket today!\n");
              goto again;
            }
          else
            {
              glnx_set_error_from_errno (error);
              return FALSE;
            }
        }

      if (!add_random_xattrs (fd, error))
        return FALSE;
      }
  else if (wtype == WRITE_RUN_MUTATE)
    {
      while (TRUE)
        {
          struct dirent *dent;
          if (!glnx_dirfd_iterator_next_dent (dfd_iter, &dent, NULL, error))
            return FALSE;
          if (!dent)
            break;

          glnx_autofd int fd = -1;
          if (!glnx_openat_rdonly (dfd_iter->fd, dent->d_name, FALSE, &fd, error))
            return FALSE;

          g_autoptr(GVariant) current_xattrs = NULL;
          if (!glnx_fd_get_all_xattrs (fd, &current_xattrs, NULL, error))
            return FALSE;

          for (size_t i = 0; i < g_variant_n_children (current_xattrs); i++)
            {
              const char *name, *value;
              g_variant_get_child (current_xattrs, i, "(^&ay^&ay)", &name, &value);

              /* We don't want to potentially test/change xattrs like security.selinux
               * that were injected by the system.
               */
              if (!g_str_has_prefix (name, "user.test"))
                continue;

              if (!set_random_xattr_value (fd, name, error))
                return FALSE;
            }
        }
    }
  else
    g_assert_not_reached ();

  return TRUE;
}

static gboolean
do_read_run (GLnxDirFdIterator *dfd_iter,
             guint *out_n_read,
             GError **error)
{
  guint nattrs = 0;
  while (TRUE)
    {
      struct dirent *dent;
      if (!glnx_dirfd_iterator_next_dent (dfd_iter, &dent, NULL, error))
        return FALSE;
      if (!dent)
        break;

      glnx_autofd int fd = -1;
      if (!glnx_openat_rdonly (dfd_iter->fd, dent->d_name, FALSE, &fd, error))
        return FALSE;

      g_autoptr(GVariant) current_xattrs = NULL;
      if (!glnx_fd_get_all_xattrs (fd, &current_xattrs, NULL, error))
        return FALSE;

      /* We don't actually care about the values, just use the variable
       * to avoid compiler warnings.
       */
      nattrs += g_variant_n_children (current_xattrs);
    }

  *out_n_read = nattrs;
  return TRUE;
}

static gpointer
xattr_thread (gpointer data)
{
  g_autoptr(GError) local_error = NULL;
  GError **error = &local_error;
  struct XattrWorker *worker = data;
  gint64 end_time = g_get_monotonic_time () + XATTR_THREAD_RUN_TIME_USECS;
  guint n_read = 0;

  while (g_get_monotonic_time () < end_time)
    {
      g_auto(GLnxDirFdIterator) dfd_iter = { 0, };

      if (!glnx_dirfd_iterator_init_at (worker->dfd, ".", TRUE, &dfd_iter, error))
        goto out;

      if (worker->is_writer)
        {
          if (!do_write_run (&dfd_iter, error))
            goto out;
        }
      else
        {
          if (!do_read_run (&dfd_iter, &n_read, error))
            goto out;
        }
    }

 out:
  g_assert_no_error (local_error);

  return GINT_TO_POINTER (n_read);
}

static void
test_xattr_races (void)
{
  /* If for some reason we're built in a VM which only has one vcpu, let's still
   * at least make the test do something.
   */
  /* FIXME - this deadlocks for me on 4.9.4-201.fc25.x86_64, whether
   * using overlayfs or xfs as source/dest.
   */
#if GLIB_CHECK_VERSION (2, 36, 0)
  const guint nprocs = MAX (4, g_get_num_processors ());
#else
  const guint nprocs = 4;
#endif
  struct XattrWorker wdata[nprocs];
  GThread *threads[nprocs];
  g_autoptr(GError) local_error = NULL;
  GError **error = &local_error;
  g_auto(GLnxTmpDir) tmpdir = { 0, };
  g_autofree char *tmpdir_path = g_strdup_printf ("%s/libglnx-xattrs-XXXXXX",
                                                  getenv ("TMPDIR") ?: "/var/tmp");
  guint nread = 0;

  if (!glnx_mkdtempat (AT_FDCWD, tmpdir_path, 0700,
                       &tmpdir, error))
    goto out;

  /* Support people building/testing on tmpfs https://github.com/flatpak/flatpak/issues/686 */
  if (fsetxattr (tmpdir.fd, "user.test", "novalue", strlen ("novalue"), 0) < 0)
    {
      if (errno == EOPNOTSUPP)
        {
          g_test_skip ("no xattr support");
          return;
        }
      else
        {
          glnx_set_error_from_errno (error);
          goto out;
        }
    }

  for (guint i = 0; i < nprocs; i++)
    {
      struct XattrWorker *worker = &wdata[i];
      worker->dfd = tmpdir.fd;
      worker->is_writer = i % 2 == 0;
      threads[i] = g_thread_new (NULL, xattr_thread, worker);
    }

  for (guint i = 0; i < nprocs; i++)
    {
      if (wdata[i].is_writer)
        (void) g_thread_join (threads[i]);
      else
        nread += GPOINTER_TO_UINT (g_thread_join (threads[i]));
    }

  g_print ("Read %u xattrs race free!\n", nread);

 out:
  g_assert_no_error (local_error);
}

int main (int argc, char **argv)
{
  int ret;

  g_test_init (&argc, &argv, NULL);

  g_test_add_func ("/xattr-races", test_xattr_races);

  ret = g_test_run();

  return ret;
}

===== ./subprojects/libglnx/tests/test-libglnx-chase.c =====
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
 *
 * Copyright (C) 2026 Red Hat, Inc.
 * SPDX-License-Identifier: LGPL-2.0-or-later
 */

#include "libglnx-config.h"
#include "libglnx.h"
#include <glib.h>
#include <stdlib.h>
#include <gio/gio.h>
#include <err.h>
#include <string.h>

#include "libglnx-testlib.h"

#define GLNX_CHASE_DEBUG_NO_OPENAT2 (1U << 31)
#define GLNX_CHASE_DEBUG_NO_OPEN_TREE (1U << 30)

const char *test_paths[] = {
  "file/baz",
  "file/baz/",
  "file/baz/.",
  "file/baz/../baz",
  "file////baz/..//baz",
  "file////baz/..//../file/baz",
};

static ino_t
get_ino (int fd)
{
  int r;
  struct stat st;

  r = fstatat (fd, "", &st, AT_EMPTY_PATH | AT_SYMLINK_NOFOLLOW);
  g_assert_cmpint (r, >=, 0);

  return st.st_ino;
}

static ino_t
path_get_ino (const char *path)
{
  int r;
  struct stat st;

  r = fstatat (AT_FDCWD, path, &st, AT_EMPTY_PATH | AT_SYMLINK_NOFOLLOW);
  g_assert_cmpint (r, >=, 0);

  return st.st_ino;
}

static char *
get_abspath (int         dfd,
             const char *path)
{
  g_autofree char *proc_fd_path = NULL;
  g_autofree char *abs = NULL;
  g_autoptr(GError) error = NULL;

  proc_fd_path = g_strdup_printf ("/proc/self/fd/%d", dfd);
  abs = glnx_readlinkat_malloc (AT_FDCWD, proc_fd_path, NULL, &error);
  g_assert_no_error (error);
  g_assert_nonnull (abs);

  return g_strdup_printf ("%s/%s", abs, path);
}

static void
check_chase (int             dfd,
             const char     *path,
             GlnxChaseFlags  flags,
             int             expected_ino)
{
  g_autoptr(GError) error = NULL;
  glnx_autofd int chase_fd = -1;

  /* let's try to test the openat2 impl */
  chase_fd = glnx_chaseat (dfd, path, flags, &error);
  g_assert_no_error (error);
  g_assert_cmpint (chase_fd, >=, 0);
  g_assert_cmpint (get_ino (chase_fd), ==, expected_ino);
  g_clear_fd (&chase_fd, NULL);

  /* let's try to test the open_tree impl */
  chase_fd = glnx_chaseat (dfd, path,
                           flags | GLNX_CHASE_DEBUG_NO_OPENAT2,
                           &error);
  g_assert_no_error (error);
  g_assert_cmpint (chase_fd, >=, 0);
  g_assert_cmpint (get_ino (chase_fd), ==, expected_ino);
  g_clear_fd (&chase_fd, NULL);

  /* let's try to test the openat impl */
  chase_fd = glnx_chaseat (dfd, path,
                           flags |
                           GLNX_CHASE_DEBUG_NO_OPENAT2 |
                           GLNX_CHASE_DEBUG_NO_OPEN_TREE,
                           &error);
  g_assert_no_error (error);
  g_assert_cmpint (chase_fd, >=, 0);
  g_assert_cmpint (get_ino (chase_fd), ==, expected_ino);
  g_clear_fd (&chase_fd, NULL);
}

static void
check_chase_error (int             dfd,
                   const char     *path,
                   GlnxChaseFlags  flags,
                   GQuark          err_domain,
                   gint            err_code)
{
  g_autoptr(GError) error = NULL;
  glnx_autofd int chase_fd = -1;

  /* let's try to test the openat2 impl */
  chase_fd = glnx_chaseat (dfd, path, flags, &error);
  g_assert_cmpint (chase_fd, <, 0);
  g_assert_error (error, err_domain, err_code);
  g_clear_error (&error);

  /* let's try to test the open_tree impl */
  chase_fd = glnx_chaseat (dfd, path,
                           flags | GLNX_CHASE_DEBUG_NO_OPENAT2,
                           &error);
  g_assert_cmpint (chase_fd, <, 0);
  g_assert_error (error, err_domain, err_code);
  g_clear_error (&error);

  /* let's try to test the openat impl */
  chase_fd = glnx_chaseat (dfd, path,
                           flags |
                           GLNX_CHASE_DEBUG_NO_OPENAT2 |
                           GLNX_CHASE_DEBUG_NO_OPEN_TREE,
                           &error);
  g_assert_cmpint (chase_fd, <, 0);
  g_assert_error (error, err_domain, err_code);
  g_clear_error (&error);
}

static void
test_chase_relative (void)
{
  g_autoptr(GError) error = NULL;
  glnx_autofd int dfd = -1;
  int expected_ino;

  g_assert_true (glnx_shutil_mkdir_p_at_open (AT_FDCWD, "file/baz", 0755,
                                              &dfd,
                                              NULL, &error));
  g_assert_no_error (error);
  g_assert_cmpint (dfd, >=, 0);

  expected_ino = get_ino (dfd);

  for (size_t i = 0; i < G_N_ELEMENTS (test_paths); i++)
    check_chase (AT_FDCWD, test_paths[i], 0, expected_ino);

  check_chase_error (AT_FDCWD, "nope", 0, G_IO_ERROR, G_IO_ERROR_NOT_FOUND);
}

static void
test_chase_relative_fd (void)
{
  g_autoptr(GError) error = NULL;
  glnx_autofd int dfd = -1;
  int expected_ino;
  glnx_autofd int cwdfd = -1;

  g_assert_true (glnx_shutil_mkdir_p_at_open (AT_FDCWD, "file/baz", 0755,
                                              &dfd,
                                              NULL, &error));
  g_assert_no_error (error);
  g_assert_cmpint (dfd, >=, 0);

  expected_ino = get_ino (dfd);

  cwdfd = openat (AT_FDCWD, ".", O_PATH | O_CLOEXEC | O_NOFOLLOW);
  g_assert_cmpint (cwdfd, >=, 0);

  for (size_t i = 0; i < G_N_ELEMENTS (test_paths); i++)
    check_chase (cwdfd, test_paths[i], 0, expected_ino);

  check_chase_error (cwdfd, "nope", 0, G_IO_ERROR, G_IO_ERROR_NOT_FOUND);
}

static void
test_chase_absolute (void)
{
  g_autoptr(GError) error = NULL;
  glnx_autofd int dfd = -1;
  int expected_ino;
  glnx_autofd int cwdfd = -1;
  g_autofree char *proc_fd_path = NULL;
  g_autofree char *cwd_path = NULL;

  g_assert_true (glnx_shutil_mkdir_p_at_open (AT_FDCWD, "file/baz", 0755,
                                              &dfd,
                                              NULL, &error));
  g_assert_no_error (error);
  g_assert_cmpint (dfd, >=, 0);

  expected_ino = get_ino (dfd);

  cwdfd = openat (AT_FDCWD, ".", O_PATH | O_CLOEXEC | O_NOFOLLOW);
  g_assert_cmpint (cwdfd, >=, 0);

  cwd_path = get_abspath (cwdfd, "");

  for (size_t i = 0; i < G_N_ELEMENTS (test_paths); i++)
    {
      g_autofree char *abspath = NULL;

      abspath = g_strdup_printf ("%s/%s", cwd_path, test_paths[i]);
      check_chase (AT_FDCWD, abspath, 0, expected_ino);
    }

  check_chase_error (AT_FDCWD, "/nope/nope/nope/345298308497623012313243543", 0,
                     G_IO_ERROR, G_IO_ERROR_NOT_FOUND);
}

static void
test_chase_link (void)
{
  g_autoptr(GError) error = NULL;
  glnx_autofd int dfd = -1;
  int link_ino;
  int target_ino;

  g_assert_true (glnx_shutil_mkdir_p_at_open (AT_FDCWD, "file/baz", 0755,
                                              &dfd,
                                              NULL, &error));
  g_assert_no_error (error);
  g_assert_cmpint (dfd, >=, 0);

  g_assert_cmpint (symlinkat ("file/baz", AT_FDCWD, "link"), ==, 0);

  target_ino = get_ino (dfd);
  link_ino = path_get_ino ("link");

  check_chase (AT_FDCWD, "link", 0, target_ino);
  check_chase (AT_FDCWD, "link/", 0, target_ino);
  check_chase (AT_FDCWD, "link///", 0, target_ino);
  check_chase (AT_FDCWD, "link/.//.", 0, target_ino);
  check_chase (AT_FDCWD, "link", 0, target_ino);

  check_chase (AT_FDCWD, "link", GLNX_CHASE_NOFOLLOW, link_ino);
  check_chase (AT_FDCWD, "./file/../link", GLNX_CHASE_NOFOLLOW, link_ino);
  check_chase (AT_FDCWD, "link/", GLNX_CHASE_NOFOLLOW, target_ino);
  check_chase (AT_FDCWD, "././link/.", GLNX_CHASE_NOFOLLOW, target_ino);
  check_chase (AT_FDCWD, "link/.//", GLNX_CHASE_NOFOLLOW, target_ino);

  check_chase (AT_FDCWD, "link",
               GLNX_CHASE_NOFOLLOW | GLNX_CHASE_RESOLVE_NO_SYMLINKS,
               link_ino);
  check_chase_error (AT_FDCWD, "link",
                     GLNX_CHASE_RESOLVE_NO_SYMLINKS,
                     G_IO_ERROR, G_IO_ERROR_TOO_MANY_LINKS);
}

static void
test_chase_resolve (void)
{
  g_autoptr(GError) error = NULL;
  glnx_autofd int foo_dfd = -1;
  glnx_autofd int bar_dfd = -1;
  g_autofree char *foo_abspath = NULL;
  int ino;

  g_assert_true (glnx_shutil_mkdir_p_at_open (AT_FDCWD, "foo", 0755,
                                              &foo_dfd,
                                              NULL, &error));
  g_assert_no_error (error);
  g_assert_cmpint (foo_dfd, >=, 0);

  g_assert_true (glnx_shutil_mkdir_p_at_open (AT_FDCWD, "foo/bar", 0755,
                                              &bar_dfd,
                                              NULL, &error));
  g_assert_no_error (error);
  g_assert_cmpint (bar_dfd, >=, 0);

  foo_abspath = get_abspath (foo_dfd, "");

  g_assert_cmpint (symlinkat ("..", foo_dfd, "link1"), ==, 0);
  g_assert_cmpint (symlinkat ("bar/../..", foo_dfd, "link2"), ==, 0);
  g_assert_cmpint (symlinkat (foo_abspath, foo_dfd, "link3"), ==, 0);
  g_assert_cmpint (symlinkat ("/bar", foo_dfd, "link4"), ==, 0);
  g_assert_cmpint (symlinkat ("link1/foo", foo_dfd, "link5"), ==, 0);
  g_assert_cmpint (symlinkat ("link7", foo_dfd, "link6"), ==, 0);
  g_assert_cmpint (symlinkat ("link6", foo_dfd, "link7"), ==, 0);

  ino = get_ino (bar_dfd);

  /* A bunch of different ways to get from CWD and foo to bar */
  check_chase (foo_dfd, "./bar", 0, ino);
  check_chase (foo_dfd, "../foo/bar", 0, ino);
  check_chase (foo_dfd, "link1/foo/bar", 0, ino);
  check_chase (AT_FDCWD, "foo/link1/foo/bar", 0, ino);
  check_chase (foo_dfd, "link2/foo/bar", 0, ino);
  check_chase (AT_FDCWD, ".///foo/./link2/foo/bar", 0, ino);
  check_chase (foo_dfd, "link3/bar", 0, ino);
  check_chase (AT_FDCWD, ".///foo/./link3/bar", 0, ino);
  check_chase (foo_dfd, "link5/bar", 0, ino);

  /* check that NO_SYMLINKS works with a component in the middle */
  check_chase_error (AT_FDCWD, "foo/link3/bar",
                     GLNX_CHASE_RESOLVE_NO_SYMLINKS,
                     G_IO_ERROR, G_IO_ERROR_TOO_MANY_LINKS);

  /* link6 points to link 7, points to link6, ... This should error out! */
  check_chase_error (foo_dfd, "link6/bar", 0,
                     G_IO_ERROR, G_IO_ERROR_TOO_MANY_LINKS);

  /* Test with links which never go below the dfd */
  check_chase (AT_FDCWD, "foo/link1/foo/bar",
               GLNX_CHASE_RESOLVE_BENEATH,
               ino);
  check_chase (AT_FDCWD, "foo/link2/foo/bar",
               GLNX_CHASE_RESOLVE_BENEATH,
               ino);
  /* An absolute link is always below the dfd */
  check_chase_error (AT_FDCWD, "foo/link3/foo/bar",
                     GLNX_CHASE_RESOLVE_BENEATH,
                     G_IO_ERROR, G_IO_ERROR_FAILED);

  /* Same, but from foo instead of cwd */
  check_chase_error (foo_dfd, "link1/foo/bar",
                     GLNX_CHASE_RESOLVE_BENEATH,
                     G_IO_ERROR, G_IO_ERROR_FAILED);
  check_chase_error (foo_dfd, "link2/foo/bar",
                     GLNX_CHASE_RESOLVE_BENEATH,
                     G_IO_ERROR, G_IO_ERROR_FAILED);
  check_chase_error (foo_dfd, "link3/foo/bar",
                     GLNX_CHASE_RESOLVE_BENEATH,
                     G_IO_ERROR, G_IO_ERROR_FAILED);

  /* Check that trying to be below the dfd with RESOLVE_IN_ROOT resolves to the
   * dfd itself */
  check_chase (foo_dfd, "link1/bar",
               GLNX_CHASE_RESOLVE_IN_ROOT,
               ino);
  check_chase (foo_dfd, "link2/bar",
               GLNX_CHASE_RESOLVE_IN_ROOT,
               ino);
  /* The absolute link is relative to dfd with RESOLVE_IN_ROOT, so this
   * fails... */
  check_chase_error (foo_dfd, "link3",
                     GLNX_CHASE_RESOLVE_IN_ROOT,
                     G_IO_ERROR, G_IO_ERROR_NOT_FOUND);
  /* ... but the link /bar resolves correctly from foo as dfd. */
  check_chase (foo_dfd, "link4",
               GLNX_CHASE_RESOLVE_IN_ROOT,
               ino);
}

static void
test_chase_resolve_in_root_absolute (void)
{
  g_autoptr(GError) error = NULL;
  glnx_autofd int foo_dfd = -1;
  glnx_autofd int bar_dfd = -1;
  glnx_autofd int baz_dfd = -1;

  g_assert_true (glnx_shutil_mkdir_p_at_open (AT_FDCWD, "foo", 0755,
                                              &foo_dfd,
                                              NULL, &error));
  g_assert_no_error (error);
  g_assert_cmpint (foo_dfd, >=, 0);

  g_assert_true (glnx_shutil_mkdir_p_at_open (AT_FDCWD, "foo/bar", 0755,
                                              &bar_dfd,
                                              NULL, &error));
  g_assert_no_error (error);
  g_assert_cmpint (bar_dfd, >=, 0);

  g_assert_true (glnx_shutil_mkdir_p_at_open (AT_FDCWD, "foo/bar/baz", 0755,
                                              &baz_dfd,
                                              NULL, &error));
  g_assert_no_error (error);
  g_assert_cmpint (baz_dfd, >=, 0);

  /* Test the absolute symlink doesn't break tracking of the root level */
  g_assert_cmpint (symlinkat ("/..", baz_dfd, "link1"), ==, 0);

  /* We should not be able to break out of the root! */
  check_chase (bar_dfd, "./baz/link1", GLNX_CHASE_RESOLVE_IN_ROOT, get_ino (bar_dfd));
}

static void
check_chase_and_statxat (int             dfd,
                         const char     *path,
                         GlnxChaseFlags  flags,
                         ino_t           expected_ino,
                         mode_t          expected_type)
{
  g_autoptr(GError) error = NULL;
  glnx_autofd int chase_fd = -1;
  struct glnx_statx stx;

  /* let's try to test the openat2 impl */
  chase_fd = glnx_chase_and_statxat (dfd, path, flags,
                                     GLNX_STATX_TYPE | GLNX_STATX_INO,
                                     &stx, &error);
  g_assert_cmpint (chase_fd, >=, 0);
  g_assert_no_error (error);
  g_assert_cmpint (stx.stx_ino, ==, expected_ino);
  g_assert_cmpint (stx.stx_mode & S_IFMT, ==, expected_type);
  g_clear_fd (&chase_fd, NULL);

  /* let's try to test the open_tree impl */
  chase_fd = glnx_chase_and_statxat (dfd, path,
                                     flags | GLNX_CHASE_DEBUG_NO_OPENAT2,
                                     GLNX_STATX_TYPE | GLNX_STATX_INO,
                                     &stx, &error);
  g_assert_cmpint (chase_fd, >=, 0);
  g_assert_no_error (error);
  g_assert_cmpint (stx.stx_ino, ==, expected_ino);
  g_assert_cmpint (stx.stx_mode & S_IFMT, ==, expected_type);
  g_clear_fd (&chase_fd, NULL);

  /* let's try to test the openat impl */
  chase_fd = glnx_chase_and_statxat (dfd, path,
                                     flags |
                                     GLNX_CHASE_DEBUG_NO_OPENAT2 |
                                     GLNX_CHASE_DEBUG_NO_OPEN_TREE,
                                     GLNX_STATX_TYPE | GLNX_STATX_INO,
                                     &stx, &error);
  g_assert_cmpint (chase_fd, >=, 0);
  g_assert_no_error (error);
  g_assert_cmpint (stx.stx_ino, ==, expected_ino);
  g_assert_cmpint (stx.stx_mode & S_IFMT, ==, expected_type);
  g_clear_fd (&chase_fd, NULL);
}

static void
check_chase_and_statxat_error (int             dfd,
                               const char     *path,
                               GlnxChaseFlags  flags,
                               GQuark          err_domain,
                               gint            err_code)
{
  g_autoptr(GError) error = NULL;
  glnx_autofd int chase_fd = -1;
  struct glnx_statx stx;

  /* let's try to test the openat2 impl */
  chase_fd = glnx_chase_and_statxat (dfd, path, flags,
                                     GLNX_STATX_TYPE | GLNX_STATX_INO,
                                     &stx, &error);
  g_assert_cmpint (chase_fd, <, 0);
  g_assert_error (error, err_domain, err_code);
  g_clear_error (&error);

  /* let's try to test the open_tree impl */
  chase_fd = glnx_chase_and_statxat (dfd, path,
                                     flags | GLNX_CHASE_DEBUG_NO_OPENAT2,
                                     GLNX_STATX_TYPE | GLNX_STATX_INO,
                                     &stx, &error);
  g_assert_cmpint (chase_fd, <, 0);
  g_assert_error (error, err_domain, err_code);
  g_clear_error (&error);

  /* let's try to test the openat impl */
  chase_fd = glnx_chase_and_statxat (dfd, path,
                                     flags |
                                     GLNX_CHASE_DEBUG_NO_OPENAT2 |
                                     GLNX_CHASE_DEBUG_NO_OPEN_TREE,
                                     GLNX_STATX_TYPE | GLNX_STATX_INO,
                                     &stx, &error);
  g_assert_cmpint (chase_fd, <, 0);
  g_assert_error (error, err_domain, err_code);
  g_clear_error (&error);
}

static void
test_chase_and_statxat_basic (void)
{
  g_autoptr(GError) error = NULL;
  glnx_autofd int dfd = -1;
  glnx_autofd int file_fd = -1;
  ino_t expected_ino;

  g_assert_true (glnx_shutil_mkdir_p_at_open (AT_FDCWD, "file/baz", 0755,
                                              &dfd,
                                              NULL, &error));
  g_assert_no_error (error);
  g_assert_cmpint (dfd, >=, 0);

  expected_ino = get_ino (dfd);

  /* Test with various path forms */
  for (size_t i = 0; i < G_N_ELEMENTS (test_paths); i++)
    check_chase_and_statxat (AT_FDCWD, test_paths[i], 0, expected_ino, S_IFDIR);

  /* Create a regular file and test it */
  file_fd = openat (dfd, "testfile", O_WRONLY | O_CREAT | O_CLOEXEC, 0644);
  g_assert_cmpint (file_fd, >=, 0);
  g_clear_fd (&file_fd, NULL);

  expected_ino = path_get_ino ("file/baz/testfile");
  check_chase_and_statxat (AT_FDCWD, "file/baz/testfile", 0, expected_ino, S_IFREG);

  /* Test error cases */
  check_chase_and_statxat_error (AT_FDCWD, "nope", 0, G_IO_ERROR, G_IO_ERROR_NOT_FOUND);
}

static void
test_chase_and_statxat_symlink (void)
{
  g_autoptr(GError) error = NULL;
  glnx_autofd int dfd = -1;
  glnx_autofd int chase_fd = -1;
  ino_t link_ino;
  ino_t target_ino;
  struct glnx_statx stx;

  g_assert_true (glnx_shutil_mkdir_p_at_open (AT_FDCWD, "file/baz", 0755,
                                              &dfd,
                                              NULL, &error));
  g_assert_no_error (error);
  g_assert_cmpint (dfd, >=, 0);

  g_assert_cmpint (symlinkat ("file/baz", AT_FDCWD, "fstatlink"), ==, 0);

  target_ino = get_ino (dfd);
  link_ino = path_get_ino ("fstatlink");

  /* Following symlinks should give us the directory */
  check_chase_and_statxat (AT_FDCWD, "fstatlink", 0, target_ino, S_IFDIR);
  check_chase_and_statxat (AT_FDCWD, "fstatlink/", 0, target_ino, S_IFDIR);

  /* With NOFOLLOW, we should get the symlink itself */
  check_chase_and_statxat (AT_FDCWD, "fstatlink", GLNX_CHASE_NOFOLLOW, link_ino, S_IFLNK);

  /* Verify we can distinguish between regular files, directories, and symlinks */
  chase_fd = glnx_chase_and_statxat (AT_FDCWD, "fstatlink", GLNX_CHASE_NOFOLLOW,
                                     GLNX_STATX_TYPE | GLNX_STATX_INO,
                                     &stx, &error);
  g_assert_cmpint (chase_fd, >=, 0);
  g_assert_no_error (error);
  g_assert_true (S_ISLNK (stx.stx_mode));
  g_clear_fd (&chase_fd, NULL);

  chase_fd = glnx_chase_and_statxat (AT_FDCWD, "fstatlink", 0,
                                     GLNX_STATX_TYPE | GLNX_STATX_INO,
                                     &stx, &error);
  g_assert_cmpint (chase_fd, >=, 0);
  g_assert_no_error (error);
  g_assert_true (S_ISDIR (stx.stx_mode));
  g_clear_fd (&chase_fd, NULL);

  /* Test with RESOLVE_NO_SYMLINKS */
  check_chase_and_statxat_error (AT_FDCWD, "fstatlink",
                                 GLNX_CHASE_RESOLVE_NO_SYMLINKS,
                                 G_IO_ERROR, G_IO_ERROR_TOO_MANY_LINKS);
}

static void
test_chase_and_statxat_permissions (void)
{
  g_autoptr(GError) error = NULL;
  glnx_autofd int dfd = -1;
  glnx_autofd int file_fd = -1;
  glnx_autofd int chase_fd = -1;
  struct glnx_statx stx;
  mode_t expected_mode = 0640;

  g_assert_true (glnx_shutil_mkdir_p_at_open (AT_FDCWD, "permtest", 0755,
                                              &dfd,
                                              NULL, &error));
  g_assert_no_error (error);

  /* Create a file with specific permissions */
  file_fd = openat (dfd, "testfile", O_WRONLY | O_CREAT | O_CLOEXEC, expected_mode);
  g_assert_cmpint (file_fd, >=, 0);
  g_clear_fd (&file_fd, NULL);

  /* Verify that glnx_chase_and_statxat returns the correct permissions */
  chase_fd = glnx_chase_and_statxat (dfd, "testfile", 0,
                                     GLNX_STATX_TYPE | GLNX_STATX_MODE,
                                     &stx, &error);
  g_assert_cmpint (chase_fd, >=, 0);
  g_assert_no_error (error);
  g_assert_cmpint (stx.stx_mode & 0777, ==, expected_mode);
  g_assert_true (S_ISREG (stx.stx_mode));
  g_clear_fd (&chase_fd, NULL);
}

int main (int argc, char **argv)
{
  _GLNX_TEST_SCOPED_TEMP_DIR;
  int ret;

  g_test_init (&argc, &argv, NULL);

  g_test_add_func ("/chase-relative", test_chase_relative);
  g_test_add_func ("/chase-relative-fd", test_chase_relative_fd);
  g_test_add_func ("/chase-absolute", test_chase_absolute);
  g_test_add_func ("/chase-link", test_chase_link);
  g_test_add_func ("/chase-resolve", test_chase_resolve);
  g_test_add_func ("/chase-resolve-in-root-absolute", test_chase_resolve_in_root_absolute);
  g_test_add_func ("/chase-and-statxat-basic", test_chase_and_statxat_basic);
  g_test_add_func ("/chase-and-statxat-symlink", test_chase_and_statxat_symlink);
  g_test_add_func ("/chase-and-statxat-permissions", test_chase_and_statxat_permissions);

  ret = g_test_run();

  return ret;
}

===== ./subprojects/libglnx/tests/test-libglnx-macros.c =====
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
 *
 * Copyright (C) 2017 Red Hat, Inc.
 * SPDX-License-Identifier: LGPL-2.0-or-later
 *
 * 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 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., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

#include "libglnx-config.h"
#include "libglnx.h"
#include <glib.h>
#include <stdlib.h>
#include <gio/gio.h>
#include <string.h>

static void
test_info (void)
{
  g_info ("hello, world");
  g_info ("answer=%d", 42);
}

static void
test_inset (void)
{
  g_assert (G_IN_SET (7, 7));
  g_assert (G_IN_SET (7, 42, 7));
  g_assert (G_IN_SET (7, 7,42,3,9));
  g_assert (G_IN_SET (42, 7,42,3,9));
  g_assert (G_IN_SET (3, 7,42,3,9));
  g_assert (G_IN_SET (9, 7,42,3,9));
  g_assert (!G_IN_SET (8, 7,42,3,9));
  g_assert (!G_IN_SET (-1, 7,42,3,9));
  g_assert (G_IN_SET ('x', 'a', 'x', 'c'));
  g_assert (!G_IN_SET ('y', 'a', 'x', 'c'));
}

static void
test_hash_table_foreach (void)
{
  /* use var names all different from the macro metavars to ensure proper
   * substitution */
  g_autoptr(GHashTable) table = g_hash_table_new (g_str_hash, g_str_equal);
  const char *keys[] = {"key1", "key2"};
  const char *vals[] = {"val1", "val2"};
  g_hash_table_insert (table, (gpointer)keys[0], (gpointer)vals[0]);
  g_hash_table_insert (table, (gpointer)keys[1], (gpointer)vals[1]);

  guint i = 0;
  GLNX_HASH_TABLE_FOREACH_IT (table, it, const char*, key, const char*, val)
    {
      g_assert_cmpstr (key, ==, keys[i]);
      g_assert_cmpstr (val, ==, vals[i]);
      i++;
    }
  g_assert_cmpuint (i, ==, 2);

  i = 0;
  GLNX_HASH_TABLE_FOREACH_IT (table, it, const char*, key, const char*, val)
    {
      g_hash_table_iter_remove (&it);
      break;
    }
  g_assert_cmpuint (g_hash_table_size (table), ==, 1);

  g_hash_table_insert (table, (gpointer)keys[1], (gpointer)vals[1]);
  g_assert_cmpuint (g_hash_table_size (table), ==, 1);

  g_hash_table_insert (table, (gpointer)keys[0], (gpointer)vals[0]);
  g_assert_cmpuint (g_hash_table_size (table), ==, 2);

  i = 0;
  GLNX_HASH_TABLE_FOREACH_KV (table, const char*, key, const char*, val)
    {
      g_assert_cmpstr (key, ==, keys[i]);
      g_assert_cmpstr (val, ==, vals[i]);
      i++;
    }
  g_assert_cmpuint (i, ==, 2);

  i = 0;
  GLNX_HASH_TABLE_FOREACH (table, const char*, key)
    {
      g_assert_cmpstr (key, ==, keys[i]);
      i++;
    }
  g_assert_cmpuint (i, ==, 2);

  i = 0;
  GLNX_HASH_TABLE_FOREACH_V (table, const char*, val)
    {
      g_assert_cmpstr (val, ==, vals[i]);
      i++;
    }
  g_assert_cmpuint (i, ==, 2);
}

int main (int argc, char **argv)
{
  g_test_init (&argc, &argv, NULL);
  g_test_add_func ("/info", test_info);
  g_test_add_func ("/inset", test_inset);
  g_test_add_func ("/hash_table_foreach", test_hash_table_foreach);
  return g_test_run();
}

===== ./subprojects/libglnx/glnx-macros.h =====
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
 *
 * Copyright (C) 2017 Colin Walters <walters@verbum.org>
 * With original source from systemd:
 * Copyright 2010 Lennart Poettering
 * SPDX-License-Identifier: LGPL-2.0-or-later
 *
 * 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 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., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

#pragma once

#include <stdlib.h>
#include <string.h>
#include <gio/gio.h>

G_BEGIN_DECLS

/* All of these are for C only. */
#ifndef __GI_SCANNER__

/* fixes builds against musl, taken from glibc unistd.h */
#ifndef TEMP_FAILURE_RETRY
#define TEMP_FAILURE_RETRY(expression) \
  (__extension__                                                              \
    ({ long int __result;                                                     \
       do __result = (long int) (expression);                                 \
       while (__result == -1L && errno == EINTR);                             \
       __result; }))
#endif

/* Taken from https://github.com/systemd/systemd/src/basic/string-util.h
 * at revision v228-666-gcf6c8c4
 */
#define glnx_strjoina(a, ...)                                           \
        ({                                                              \
                const char *_appendees_[] = { a, __VA_ARGS__ };         \
                char *_d_, *_p_;                                        \
                size_t _len_ = 0;                                       \
                unsigned _i_;                                           \
                for (_i_ = 0; _i_ < G_N_ELEMENTS(_appendees_) && _appendees_[_i_]; _i_++) \
                        _len_ += strlen(_appendees_[_i_]);              \
                _p_ = _d_ = (char*) alloca(_len_ + 1);                          \
                for (_i_ = 0; _i_ < G_N_ELEMENTS(_appendees_) && _appendees_[_i_]; _i_++) \
                        _p_ = stpcpy(_p_, _appendees_[_i_]);            \
                *_p_ = 0;                                               \
                _d_;                                                    \
        })

#ifndef G_IN_SET

/* Infrastructure for `G_IN_SET`; this code is copied from
 * systemd's macro.h - please treat that version as canonical
 * and submit patches first to systemd.
 */
#define _G_INSET_CASE_F(X) case X:
#define _G_INSET_CASE_F_1(CASE, X) _G_INSET_CASE_F(X)
#define _G_INSET_CASE_F_2(CASE, X, ...)  CASE(X) _G_INSET_CASE_F_1(CASE, __VA_ARGS__)
#define _G_INSET_CASE_F_3(CASE, X, ...)  CASE(X) _G_INSET_CASE_F_2(CASE, __VA_ARGS__)
#define _G_INSET_CASE_F_4(CASE, X, ...)  CASE(X) _G_INSET_CASE_F_3(CASE, __VA_ARGS__)
#define _G_INSET_CASE_F_5(CASE, X, ...)  CASE(X) _G_INSET_CASE_F_4(CASE, __VA_ARGS__)
#define _G_INSET_CASE_F_6(CASE, X, ...)  CASE(X) _G_INSET_CASE_F_5(CASE, __VA_ARGS__)
#define _G_INSET_CASE_F_7(CASE, X, ...)  CASE(X) _G_INSET_CASE_F_6(CASE, __VA_ARGS__)
#define _G_INSET_CASE_F_8(CASE, X, ...)  CASE(X) _G_INSET_CASE_F_7(CASE, __VA_ARGS__)
#define _G_INSET_CASE_F_9(CASE, X, ...)  CASE(X) _G_INSET_CASE_F_8(CASE, __VA_ARGS__)
#define _G_INSET_CASE_F_10(CASE, X, ...) CASE(X) _G_INSET_CASE_F_9(CASE, __VA_ARGS__)
#define _G_INSET_CASE_F_11(CASE, X, ...) CASE(X) _G_INSET_CASE_F_10(CASE, __VA_ARGS__)
#define _G_INSET_CASE_F_12(CASE, X, ...) CASE(X) _G_INSET_CASE_F_11(CASE, __VA_ARGS__)
#define _G_INSET_CASE_F_13(CASE, X, ...) CASE(X) _G_INSET_CASE_F_12(CASE, __VA_ARGS__)
#define _G_INSET_CASE_F_14(CASE, X, ...) CASE(X) _G_INSET_CASE_F_13(CASE, __VA_ARGS__)
#define _G_INSET_CASE_F_15(CASE, X, ...) CASE(X) _G_INSET_CASE_F_14(CASE, __VA_ARGS__)
#define _G_INSET_CASE_F_16(CASE, X, ...) CASE(X) _G_INSET_CASE_F_15(CASE, __VA_ARGS__)
#define _G_INSET_CASE_F_17(CASE, X, ...) CASE(X) _G_INSET_CASE_F_16(CASE, __VA_ARGS__)
#define _G_INSET_CASE_F_18(CASE, X, ...) CASE(X) _G_INSET_CASE_F_17(CASE, __VA_ARGS__)
#define _G_INSET_CASE_F_19(CASE, X, ...) CASE(X) _G_INSET_CASE_F_18(CASE, __VA_ARGS__)
#define _G_INSET_CASE_F_20(CASE, X, ...) CASE(X) _G_INSET_CASE_F_19(CASE, __VA_ARGS__)

#define _G_INSET_GET_CASE_F(_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,NAME,...) NAME
#define _G_INSET_FOR_EACH_MAKE_CASE(...) \
  _G_INSET_GET_CASE_F(__VA_ARGS__,_G_INSET_CASE_F_20,_G_INSET_CASE_F_19,_G_INSET_CASE_F_18,_G_INSET_CASE_F_17,_G_INSET_CASE_F_16,_G_INSET_CASE_F_15,_G_INSET_CASE_F_14,_G_INSET_CASE_F_13,_G_INSET_CASE_F_12,_G_INSET_CASE_F_11, \
                               _G_INSET_CASE_F_10,_G_INSET_CASE_F_9,_G_INSET_CASE_F_8,_G_INSET_CASE_F_7,_G_INSET_CASE_F_6,_G_INSET_CASE_F_5,_G_INSET_CASE_F_4,_G_INSET_CASE_F_3,_G_INSET_CASE_F_2,_G_INSET_CASE_F_1) \
                   (_G_INSET_CASE_F,__VA_ARGS__)

/* Note: claiming the name here even though it isn't upstream yet
 * https://bugzilla.gnome.org/show_bug.cgi?id=783751
 */
/**
 * G_IN_SET:
 * @x: Integer (or smaller) sized value
 * @...: Elements to compare
 *
 * It's quite common to test whether or not `char` values or Unix @errno (among) others
 * are members of a small set.  Normally one has to choose to either use `if (x == val || x == otherval ...)`
 * or a `switch` statement.  This macro is useful to reduce duplication in the first case,
 * where one can write simply `if (G_IN_SET (x, val, otherval))`, and avoid the verbosity
 * that the `switch` statement requires.
 */
#define G_IN_SET(x, ...)                          \
        ({                                      \
                gboolean _g_inset_found = FALSE;            \
                /* If the build breaks in the line below, you need to extend the case macros */ \
                static G_GNUC_UNUSED char _static_assert__macros_need_to_be_extended[20 - sizeof((int[]){__VA_ARGS__})/sizeof(int)]; \
                switch(x) {                     \
                _G_INSET_FOR_EACH_MAKE_CASE(__VA_ARGS__) \
                        _g_inset_found = TRUE;          \
                        break;                  \
                default:                        \
                        break;                  \
                }                               \
                _g_inset_found;                 \
        })

#endif /* ifndef G_IN_SET */

#define _GLNX_CONCAT(a, b)  a##b
#define _GLNX_CONCAT_INDIRECT(a, b) _GLNX_CONCAT(a, b)
#define _GLNX_MAKE_ANONYMOUS(a) _GLNX_CONCAT_INDIRECT(a, __COUNTER__)

#define _GLNX_HASH_TABLE_FOREACH_IMPL_KV(guard, ht, it, kt, k, vt, v)          \
    gboolean guard = TRUE;                                                     \
    G_STATIC_ASSERT (sizeof (kt) == sizeof (void*));                           \
    G_STATIC_ASSERT (sizeof (vt) == sizeof (void*));                           \
    for (GHashTableIter it;                                                    \
         guard && ({ g_hash_table_iter_init (&it, ht), TRUE; });               \
         guard = FALSE)                                                        \
            for (kt k; guard; guard = FALSE)                                   \
                for (vt v; g_hash_table_iter_next (&it, (void**)&k, (void**)&v);)


/* Cleaner method to iterate over a GHashTable. I.e. rather than
 *
 *   gpointer k, v;
 *   GHashTableIter it;
 *   g_hash_table_iter_init (&it, table);
 *   while (g_hash_table_iter_next (&it, &k, &v))
 *     {
 *       const char *str = k;
 *       GPtrArray *arr = v;
 *       ...
 *     }
 *
 * you can simply do
 *
 *   GLNX_HASH_TABLE_FOREACH_IT (table, it, const char*, str, GPtrArray*, arr)
 *     {
 *       ...
 *     }
 *
 * All variables are scoped within the loop. You may use the `it` variable as
 * usual, e.g. to remove an element using g_hash_table_iter_remove(&it). There
 * are shorter variants for the more common cases where you do not need access
 * to the iterator or to keys/values:
 *
 *   GLNX_HASH_TABLE_FOREACH (table, const char*, str) { ... }
 *   GLNX_HASH_TABLE_FOREACH_V (table, MyData*, data) { ... }
 *   GLNX_HASH_TABLE_FOREACH_KV (table, const char*, str, MyData*, data) { ... }
 *
 */
#define GLNX_HASH_TABLE_FOREACH_IT(ht, it, kt, k, vt, v) \
    _GLNX_HASH_TABLE_FOREACH_IMPL_KV( \
         _GLNX_MAKE_ANONYMOUS(_glnx_ht_iter_guard_), ht, it, kt, k, vt, v)

/* Variant of GLNX_HASH_TABLE_FOREACH without having to specify an iterator. An
 * anonymous iterator will be created. */
#define GLNX_HASH_TABLE_FOREACH_KV(ht, kt, k, vt, v) \
    _GLNX_HASH_TABLE_FOREACH_IMPL_KV( \
         _GLNX_MAKE_ANONYMOUS(_glnx_ht_iter_guard_), ht, \
         _GLNX_MAKE_ANONYMOUS(_glnx_ht_iter_it_), kt, k, vt, v)

/* Variant of GLNX_HASH_TABLE_FOREACH_KV which omits unpacking keys. */
#define GLNX_HASH_TABLE_FOREACH_V(ht, vt, v) \
    _GLNX_HASH_TABLE_FOREACH_IMPL_KV( \
         _GLNX_MAKE_ANONYMOUS(_glnx_ht_iter_guard_), ht, \
         _GLNX_MAKE_ANONYMOUS(_glnx_ht_iter_it_), \
         gpointer, _GLNX_MAKE_ANONYMOUS(_glnx_ht_iter_v_), \
         vt, v)

/* Variant of GLNX_HASH_TABLE_FOREACH_KV which omits unpacking vals. */
#define GLNX_HASH_TABLE_FOREACH(ht, kt, k) \
    _GLNX_HASH_TABLE_FOREACH_IMPL_KV( \
         _GLNX_MAKE_ANONYMOUS(_glnx_ht_iter_guard_), ht, \
         _GLNX_MAKE_ANONYMOUS(_glnx_ht_iter_it_), kt, k, \
         gpointer, _GLNX_MAKE_ANONYMOUS(_glnx_ht_iter_v_))

#endif /* GI_SCANNER */

G_END_DECLS

===== ./subprojects/libglnx/glnx-dirfd.h =====
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
 *
 * Copyright (C) 2014,2015 Colin Walters <walters@verbum.org>.
 * SPDX-License-Identifier: LGPL-2.0-or-later
 *
 * 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 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., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

#pragma once

#include <glnx-backport-autocleanups.h>
#include <glnx-macros.h>
#include <glnx-errors.h>
#include <limits.h>
#include <dirent.h>
#include <sys/stat.h>
#include <fcntl.h>

G_BEGIN_DECLS
 
/**
 * glnx_dirfd_canonicalize:
 * @fd: A directory file descriptor
 *
 * It's often convenient in programs to use `-1` for "unassigned fd",
 * and also because gobject-introspection doesn't support `AT_FDCWD`,
 * libglnx honors `-1` to mean `AT_FDCWD`.  This small inline function
 * canonicalizes `-1 -> AT_FDCWD`.
 */
static inline int
glnx_dirfd_canonicalize (int fd)
{
  if (fd == -1)
    return AT_FDCWD;
  return fd;
}

struct GLnxDirFdIterator {
  gboolean initialized;
  int fd;
  gpointer padding_data[4];
};

typedef struct GLnxDirFdIterator GLnxDirFdIterator;
gboolean glnx_dirfd_iterator_init_at (int dfd, const char *path,
                                    gboolean follow,
                                    GLnxDirFdIterator *dfd_iter, GError **error);
gboolean glnx_dirfd_iterator_init_take_fd (int *dfd, GLnxDirFdIterator *dfd_iter, GError **error);
gboolean glnx_dirfd_iterator_next_dent (GLnxDirFdIterator  *dfd_iter,
                                        struct dirent     **out_dent,
                                        GCancellable       *cancellable,
                                        GError            **error);
gboolean glnx_dirfd_iterator_next_dent_ensure_dtype (GLnxDirFdIterator  *dfd_iter,
                                                     struct dirent     **out_dent,
                                                     GCancellable       *cancellable,
                                                     GError            **error);
void glnx_dirfd_iterator_rewind (GLnxDirFdIterator  *dfd_iter);
void glnx_dirfd_iterator_clear (GLnxDirFdIterator *dfd_iter);

G_DEFINE_AUTO_CLEANUP_CLEAR_FUNC(GLnxDirFdIterator, glnx_dirfd_iterator_clear)

int glnx_opendirat_with_errno (int           dfd,
                               const char   *path,
                               gboolean      follow);

gboolean glnx_opendirat (int             dfd,
                         const char     *path,
                         gboolean        follow,
                         int            *out_fd,
                         GError        **error);

char *glnx_fdrel_abspath (int         dfd,
                          const char *path);

void glnx_gen_temp_name (gchar *tmpl);

/**
 * glnx_ensure_dir:
 * @dfd: directory fd
 * @path: Directory path
 * @mode: Mode
 * @error: Return location for a #GError, or %NULL
 *
 * Wrapper around mkdirat() which adds #GError support, ensures that
 * it retries on %EINTR, and also ignores `EEXIST`.
 *
 * See also `glnx_shutil_mkdir_p_at()` for recursive handling.
 *
 * Returns: %TRUE on success, %FALSE otherwise
 */
static inline gboolean
glnx_ensure_dir (int           dfd,
                 const char   *path,
                 mode_t        mode,
                 GError      **error)
{
  if (TEMP_FAILURE_RETRY (mkdirat (dfd, path, mode)) != 0)
    {
      if (G_UNLIKELY (errno != EEXIST))
        return glnx_throw_errno_prefix (error, "mkdirat(%s)", path);
    }
  return TRUE;
}

typedef struct {
  gboolean initialized;
  int src_dfd;
  int fd;
  char *path;
} GLnxTmpDir;
gboolean glnx_tmpdir_delete (GLnxTmpDir *tmpf, GCancellable *cancellable, GError **error);
void glnx_tmpdir_unset (GLnxTmpDir *tmpf);
static inline void
glnx_tmpdir_cleanup (GLnxTmpDir *tmpf)
{
  (void)glnx_tmpdir_delete (tmpf, NULL, NULL);
}
G_DEFINE_AUTO_CLEANUP_CLEAR_FUNC(GLnxTmpDir, glnx_tmpdir_cleanup)

gboolean glnx_mkdtempat (int dfd, const char *tmpl, int mode,
                         GLnxTmpDir *out_tmpdir, GError **error);

gboolean glnx_mkdtemp (const char *tmpl, int      mode,
                       GLnxTmpDir *out_tmpdir, GError **error);

G_END_DECLS

===== ./subprojects/libglnx/meson.build =====
# Copyright 2019 Endless OS Foundation LLC
# Copyright 2019 Collabora Ltd.
# SPDX-License-Identifier: LGPL-2.1-or-later

project(
  'libglnx',
  'c',
  default_options : [
    'c_std=gnu99',
    'warning_level=2',
  ],
)

add_project_arguments('-D_GNU_SOURCE', language: 'c')
add_project_arguments('-Wno-unused-local-typedefs', language: 'c')

# We are intentionally using non-ISO features in this (sub)project,
# even if a parent project wants to use pedantic warnings
add_project_arguments('-Wno-pedantic', language: 'c')
add_project_arguments('-Wno-variadic-macros', language: 'c')

cc = meson.get_compiler('c')


check_functions = [
  'renameat2',
  'memfd_create',
  'copy_file_range',
]
conf = configuration_data()
foreach check_function : check_functions
  have_it = cc.compiles('''
    #include <sys/types.h>
    #include <unistd.h>
    #include <stdio.h>
    #include <sys/mount.h>
    #include <fcntl.h>
    #include <sched.h>
    #include <linux/loop.h>
    #include <linux/random.h>
    #include <sys/mman.h>

    void func (void) {
      (void) ''' + check_function + ''';
    }
    ''',
    args : '-D_GNU_SOURCE',
    name : check_function + '() is declared',
  )
  conf.set10('HAVE_DECL_' + check_function.underscorify().to_upper(), have_it)
endforeach

check_functions = [
  'close_range',
]
foreach check_function : check_functions
  if cc.has_function(check_function)
    conf.set('HAVE_' + check_function.underscorify().to_upper(), 1)
  endif
endforeach

config_h = configure_file(
  output : 'libglnx-config.h',
  configuration : conf,
)

libglnx_deps = [
  dependency('gio-2.0'),
  dependency('gio-unix-2.0'),
]
libglnx_inc = include_directories('.')
libglnx_sources = [
  'glnx-backport-autocleanups.h',
  'glnx-backport-autoptr.h',
  'glnx-backport-testutils.c',
  'glnx-backport-testutils.h',
  'glnx-backports.c',
  'glnx-backports.h',
  'glnx-chase.c',
  'glnx-chase.h',
  'glnx-console.c',
  'glnx-console.h',
  'glnx-dirfd.c',
  'glnx-dirfd.h',
  'glnx-errors.c',
  'glnx-errors.h',
  'glnx-fdio.c',
  'glnx-fdio.h',
  'glnx-local-alloc.c',
  'glnx-local-alloc.h',
  'glnx-lockfile.c',
  'glnx-lockfile.h',
  'glnx-macros.h',
  'glnx-missing.h',
  'glnx-missing-syscall.h',
  'glnx-shutil.c',
  'glnx-shutil.h',
  'glnx-xattrs.c',
  'glnx-xattrs.h',
  'libglnx.h',
]

libglnx = static_library('glnx',
  libglnx_sources,
  dependencies : libglnx_deps,
  gnu_symbol_visibility : 'hidden',
  include_directories : libglnx_inc,
  install : false)
libglnx_dep = declare_dependency(
  dependencies : libglnx_deps,
  include_directories : libglnx_inc,
  link_with : libglnx)

subdir('tests')


===== ./subprojects/libglnx/glnx-console.c =====
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
 *
 * Copyright (C) 2013,2014,2015 Colin Walters <walters@verbum.org>
 * SPDX-License-Identifier: LGPL-2.0-or-later
 *
 * This program 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 of the licence 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., 59 Temple Place, Suite 330,
 * Boston, MA 02111-1307, USA.
 */

#include "libglnx-config.h"

#include "glnx-console.h"

#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <stdio.h>
#include <errno.h>
#include <sys/ioctl.h>

/* For people with widescreen monitors and maximized terminals, it looks pretty
 * bad to have an enormous progress bar. For much the same reason as web pages
 * tend to have a maximum width;
 * https://ux.stackexchange.com/questions/48982/suggest-good-max-width-for-fluid-width-design
 */
#define MAX_PROGRESSBAR_COLUMNS 20

/* Max updates output per second.  On a tty there's no point to rendering
 * extremely fast; and for a non-tty we're probably in a Jenkins job
 * or whatever and having percentages spam multiple lines there is annoying.
 */
#define MAX_TTY_UPDATE_HZ (5)
#define MAX_NONTTY_UPDATE_HZ (1)

static gboolean locked;
static guint64 last_update_ms; /* monotonic time in millis we last updated */

gboolean
glnx_stdout_is_tty (void)
{
  static gsize initialized = 0;
  static gboolean stdout_is_tty_v;

  if (g_once_init_enter (&initialized))
    {
      stdout_is_tty_v = isatty (1);
      g_once_init_leave (&initialized, 1);
    }

  return stdout_is_tty_v;
}

static volatile guint cached_columns = 0;
static volatile guint cached_lines = 0;

static int
fd_columns (int fd)
{
  struct winsize ws = {};

  if (ioctl (fd, TIOCGWINSZ, &ws) < 0)
    return -errno;

  if (ws.ws_col <= 0)
    return -EIO;

  return ws.ws_col;
}

/**
 * glnx_console_columns:
 * 
 * Returns: The number of columns for terminal output
 */
guint
glnx_console_columns (void)
{
  if (G_UNLIKELY (cached_columns == 0))
    {
      int c;

      c = fd_columns (STDOUT_FILENO);

      if (c <= 0)
        c = 80;

      if (c > 256)
        c = 256;

      cached_columns = c;
    }

  return cached_columns;
}

static int
fd_lines (int fd)
{
  struct winsize ws = {};

  if (ioctl (fd, TIOCGWINSZ, &ws) < 0)
    return -errno;

  if (ws.ws_row <= 0)
    return -EIO;

  return ws.ws_row;
}

/**
 * glnx_console_lines:
 * 
 * Returns: The number of lines for terminal output
 */
guint
glnx_console_lines (void)
{
  if (G_UNLIKELY (cached_lines == 0))
    {
      int l;

      l = fd_lines (STDOUT_FILENO);

      if (l <= 0)
        l = 24;

      cached_lines = l;
    }

  return cached_lines;
}

static void
on_sigwinch (G_GNUC_UNUSED int signum)
{
  cached_columns = 0;
  cached_lines = 0;
}

void
glnx_console_lock (GLnxConsoleRef *console)
{
  static gsize sigwinch_initialized = 0;

  g_return_if_fail (!locked);
  g_return_if_fail (!console->locked);

  console->is_tty = glnx_stdout_is_tty ();

  locked = console->locked = TRUE;

  if (console->is_tty)
    {
      if (g_once_init_enter (&sigwinch_initialized))
        {
          signal (SIGWINCH, on_sigwinch);
          g_once_init_leave (&sigwinch_initialized, 1);
        }
      
      { static const char initbuf[] = { 0x1B, 0x37 };
        (void) fwrite (initbuf, 1, sizeof (initbuf), stdout);
      }
    }
}

static void
printpad (const char *padbuf,
          guint       padbuf_len,
          guint       n)
{
  const guint d = n / padbuf_len;
  const guint r = n % padbuf_len;
  guint i;

  for (i = 0; i < d; i++)
    fwrite (padbuf, 1, padbuf_len, stdout);
  fwrite (padbuf, 1, r, stdout);
}

static void
text_percent_internal (const char *text,
                       int percentage)
{
  /* Check whether we're trying to render too fast; unless percentage is 100, in
   * which case we assume this is the last call, so we always render it.
   */
  const guint64 current_ms = g_get_monotonic_time () / 1000;
  if (percentage != 100)
    {
      const guint64 diff_ms = current_ms - last_update_ms;
      if (glnx_stdout_is_tty ())
        {
          if (diff_ms < (1000/MAX_TTY_UPDATE_HZ))
            return;
        }
      else
        {
          if (diff_ms < (1000/MAX_NONTTY_UPDATE_HZ))
            return;
        }
    }
  last_update_ms = current_ms;

  static const char equals[] = "====================";
  const guint n_equals = sizeof (equals) - 1;
  static const char spaces[] = "                    ";
  const guint n_spaces = sizeof (spaces) - 1;
  const guint ncolumns = glnx_console_columns ();
  const guint bar_min = 10;

  if (text && !*text)
    text = NULL;

  const guint input_textlen = text ? strlen (text) : 0;

  if (!glnx_stdout_is_tty ())
    {
      if (text)
        fprintf (stdout, "%s", text);
      if (percentage != -1)
        {
          if (text)
            fputc (' ', stdout);
          fprintf (stdout, "%u%%", percentage);
        }
      fputc ('\n', stdout);
      fflush (stdout);
      return;
    }

  if (ncolumns < bar_min)
    return; /* TODO: spinner */

  /* Restore cursor */
  { const char beginbuf[2] = { 0x1B, 0x38 };
    (void) fwrite (beginbuf, 1, sizeof (beginbuf), stdout);
  }

  if (percentage == -1)
    {
      if (text != NULL)
        fwrite (text, 1, input_textlen, stdout);

      /* Overwrite remaining space, if any */
      if (ncolumns > input_textlen)
        printpad (spaces, n_spaces, ncolumns - input_textlen);
    }
  else
    {
      const guint textlen = MIN (input_textlen, ncolumns - bar_min);
      const guint barlen = MIN (MAX_PROGRESSBAR_COLUMNS, ncolumns - (textlen + 1));

      if (text && textlen > 0)
        {
          fwrite (text, 1, textlen, stdout);
          fputc (' ', stdout);
        }

      {
        const guint nbraces = 2;
        const guint textpercent_len = 5;
        const guint bar_internal_len = barlen - nbraces - textpercent_len;
        const guint eqlen = bar_internal_len * (percentage / 100.0);
        const guint spacelen = bar_internal_len - eqlen;

        fputc ('[', stdout);
        printpad (equals, n_equals, eqlen);
        printpad (spaces, n_spaces, spacelen);
        fputc (']', stdout);
        fprintf (stdout, " %3d%%", percentage);
      }
    }

  fflush (stdout);
}

/**
 * glnx_console_progress_text_percent:
 * @text: Show this text before the progress bar
 * @percentage: An integer in the range of 0 to 100
 *
 * On a tty, print to the console @text followed by an ASCII art
 * progress bar whose percentage is @percentage.  If stdout is not a
 * tty, a more basic line by line change will be printed.
 *
 * You must have called glnx_console_lock() before invoking this
 * function.
 *
 */
void
glnx_console_progress_text_percent (const char *text,
                                    guint percentage)
{
  g_return_if_fail (percentage <= 100);

  text_percent_internal (text, percentage);
}

/**
 * glnx_console_progress_n_items:
 * @text: Show this text before the progress bar
 * @current: An integer for how many items have been processed
 * @total: An integer for how many items there are total
 *
 * On a tty, print to the console @text followed by [@current/@total],
 * then an ASCII art progress bar, like glnx_console_progress_text_percent().
 *
 * You must have called glnx_console_lock() before invoking this
 * function.
 */
void
glnx_console_progress_n_items (const char     *text,
                               guint           current,
                               guint           total)
{
  g_return_if_fail (current <= total);
  g_return_if_fail (total > 0);

  g_autofree char *newtext = g_strdup_printf ("%s (%u/%u)", text, current, total);
  /* Special case current == total to ensure we end at 100% */
  int percentage = (current == total) ? 100 : (((double)current) / total * 100);
  glnx_console_progress_text_percent (newtext, percentage);
}

void
glnx_console_text (const char *text)
{
  text_percent_internal (text, -1);
}

/**
 * glnx_console_unlock:
 *
 * Print a newline, and reset all cached console progress state.
 *
 * This function does nothing if stdout is not a tty.
 */
void
glnx_console_unlock (GLnxConsoleRef *console)
{
  g_return_if_fail (locked);
  g_return_if_fail (console->locked);

  if (console->is_tty)
    fputc ('\n', stdout);
      
  locked = console->locked = FALSE;
}

===== ./subprojects/libglnx/glnx-backport-testutils.h =====
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
 *
 * Copyright 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
 * Copyright 2015 Colin Walters <walters@verbum.org>
 * Copyright 2014 Dan Winship
 * Copyright 2015 Colin Walters
 * Copyright 2017 Emmanuele Bassi
 * Copyright 2018-2019 Endless OS Foundation LLC
 * Copyright 2020 Niels De Graef
 * Copyright 2021-2022 Collabora Ltd.
 * SPDX-License-Identifier: LGPL-2.1-or-later
 *
 * 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., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

#pragma once

#include <gio/gio.h>

#include "glnx-backports.h"

G_BEGIN_DECLS

#ifndef g_assert_true       /* added in 2.38 */
#define g_assert_true(x) g_assert ((x))
#endif

#ifndef g_assert_false      /* added in 2.38 */
#define g_assert_false(x) g_assert (!(x))
#endif

#ifndef g_assert_nonnull    /* added in 2.40 */
#define g_assert_nonnull(x) g_assert (x != NULL)
#endif

#ifndef g_assert_null       /* added in 2.40 */
#define g_assert_null(x) g_assert (x == NULL)
#endif

#if !GLIB_CHECK_VERSION (2, 38, 0)
/* Not exactly equivalent, but close enough */
#define g_test_skip(s) g_test_message ("SKIP: %s", s)
#endif

#if !GLIB_CHECK_VERSION (2, 58, 0)
/* Before 2.58, g_test_incomplete() didn't set the exit status correctly */
#define g_test_incomplete(s) _glnx_test_incomplete_printf ("%s", s)
#endif

#if !GLIB_CHECK_VERSION (2, 46, 0)
#define g_assert_cmpmem(m1, l1, m2, l2) G_STMT_START {\
                                             gconstpointer __m1 = m1, __m2 = m2; \
                                             int __l1 = l1, __l2 = l2; \
                                             if (__l1 != 0 && __m1 == NULL) \
                                               g_assertion_message (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, \
                                                                    "assertion failed (" #l1 " == 0 || " #m1 " != NULL)"); \
                                             else if (__l2 != 0 && __m2 == NULL) \
                                               g_assertion_message (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, \
                                                                    "assertion failed (" #l2 " == 0 || " #m2 " != NULL)"); \
                                             else if (__l1 != __l2) \
                                               g_assertion_message_cmpnum (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, \
                                                                           #l1 " (len(" #m1 ")) == " #l2 " (len(" #m2 "))", \
                                                                           (long double) __l1, "==", (long double) __l2, 'i'); \
                                             else if (__l1 != 0 && __m2 != NULL && memcmp (__m1, __m2, __l1) != 0) \
                                               g_assertion_message (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, \
                                                                    "assertion failed (" #m1 " == " #m2 ")"); \
                                        } G_STMT_END
#endif

#if !GLIB_CHECK_VERSION (2, 58, 0)
#define g_assert_cmpfloat_with_epsilon(n1,n2,epsilon) \
                                        G_STMT_START { \
                                             double __n1 = (n1), __n2 = (n2), __epsilon = (epsilon); \
                                             if (G_APPROX_VALUE (__n1,  __n2, __epsilon)) ; else \
                                               g_assertion_message_cmpnum (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, \
                                                 #n1 " == " #n2 " (+/- " #epsilon ")", __n1, "==", __n2, 'f'); \
                                        } G_STMT_END
#endif

#if !GLIB_CHECK_VERSION (2, 60, 0)
#define g_assert_cmpvariant(v1, v2) \
  G_STMT_START \
  { \
    GVariant *__v1 = (v1), *__v2 = (v2); \
    if (!g_variant_equal (__v1, __v2)) \
      { \
        gchar *__s1, *__s2, *__msg; \
        __s1 = g_variant_print (__v1, TRUE); \
        __s2 = g_variant_print (__v2, TRUE); \
        __msg = g_strdup_printf ("assertion failed (" #v1 " == " #v2 "): %s does not equal %s", __s1, __s2); \
        g_assertion_message (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, __msg); \
        g_free (__s1); \
        g_free (__s2); \
        g_free (__msg); \
      } \
  } \
  G_STMT_END
#endif

#if !GLIB_CHECK_VERSION (2, 62, 0)
/* Not exactly equivalent, but close enough */
#define g_test_summary(s) g_test_message ("SUMMARY: %s", s)
#endif

#if !GLIB_CHECK_VERSION (2, 66, 0)
#define g_assert_no_errno(expr)         G_STMT_START { \
                                             int __ret, __errsv; \
                                             errno = 0; \
                                             __ret = expr; \
                                             __errsv = errno; \
                                             if (__ret < 0) \
                                               { \
                                                 gchar *__msg; \
                                                 __msg = g_strdup_printf ("assertion failed (" #expr " >= 0): errno %i: %s", __errsv, g_strerror (__errsv)); \
                                                 g_assertion_message (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, __msg); \
                                                 g_free (__msg); \
                                               } \
                                        } G_STMT_END
#endif

#if !GLIB_CHECK_VERSION (2, 68, 0)
#define g_assertion_message_cmpstrv _glnx_assertion_message_cmpstrv
void _glnx_assertion_message_cmpstrv (const char         *domain,
                                      const char         *file,
                                      int                 line,
                                      const char         *func,
                                      const char         *expr,
                                      const char * const *arg1,
                                      const char * const *arg2,
                                      gsize               first_wrong_idx);
#define g_assert_cmpstrv(strv1, strv2) \
  G_STMT_START \
  { \
    const char * const *__strv1 = (const char * const *) (strv1); \
    const char * const *__strv2 = (const char * const *) (strv2); \
    if (!__strv1 || !__strv2) \
      { \
        if (__strv1) \
          { \
            g_assertion_message (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, \
                                 "assertion failed (" #strv1 " == " #strv2 "): " #strv2 " is NULL, but " #strv1 " is not"); \
          } \
        else if (__strv2) \
          { \
            g_assertion_message (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, \
                                 "assertion failed (" #strv1 " == " #strv2 "): " #strv1 " is NULL, but " #strv2 " is not"); \
          } \
      } \
    else \
      { \
        guint __l1 = g_strv_length ((char **) __strv1); \
        guint __l2 = g_strv_length ((char **) __strv2); \
        if (__l1 != __l2) \
          { \
            char *__msg; \
            __msg = g_strdup_printf ("assertion failed (" #strv1 " == " #strv2 "): length %u does not equal length %u", __l1, __l2); \
            g_assertion_message (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, __msg); \
            g_free (__msg); \
          } \
        else \
          { \
            guint __i; \
            for (__i = 0; __i < __l1; __i++) \
              { \
                if (g_strcmp0 (__strv1[__i], __strv2[__i]) != 0) \
                  { \
                    g_assertion_message_cmpstrv (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, \
                                                 #strv1 " == " #strv2, \
                                                 __strv1, __strv2, __i); \
                  } \
              } \
          } \
      } \
  } \
  G_STMT_END
#endif

#if !GLIB_CHECK_VERSION (2, 70, 0)
/* Before 2.70, diagnostic messages containing newlines were problematic */
#define g_test_message(...) _glnx_test_message_safe (__VA_ARGS__)
void _glnx_test_message_safe (const char *format, ...) G_GNUC_PRINTF (1, 2);

#define g_test_fail_printf _glnx_test_fail_printf
void _glnx_test_fail_printf (const char *format, ...) G_GNUC_PRINTF (1, 2);
#define g_test_skip_printf _glnx_test_skip_printf
void _glnx_test_skip_printf (const char *format, ...) G_GNUC_PRINTF (1, 2);
#define g_test_incomplete_printf _glnx_test_incomplete_printf
void _glnx_test_incomplete_printf (const char *format, ...) G_GNUC_PRINTF (1, 2);
#endif

#if !GLIB_CHECK_VERSION (2, 78, 0)
#define g_test_disable_crash_reporting _glnx_test_disable_crash_reporting
void _glnx_test_disable_crash_reporting (void);
#endif

G_END_DECLS

===== ./subprojects/libglnx/glnx-errors.h =====
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
 *
 * Copyright (C) 2014,2015 Colin Walters <walters@verbum.org>.
 * SPDX-License-Identifier: LGPL-2.0-or-later
 *
 * 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 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., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

#pragma once

#include <glnx-backport-autocleanups.h>
#include <errno.h>

G_BEGIN_DECLS

gboolean glnx_throw (GError **error, const char *fmt, ...) G_GNUC_PRINTF (2,3);

/* Like `glnx_throw ()`, but returns %NULL. */
#define glnx_null_throw(error, args...) \
  ({glnx_throw (error, args); NULL;})

/* Like glnx_throw(), but yields -1 (invalid fd). */
#define glnx_fd_throw(error, args...) \
  ({glnx_throw (error, args); -1;})

/* Implementation detail of glnx_throw_prefix() */
void glnx_real_set_prefix_error_va (GError     *error,
                                    const char *format,
                                    va_list     args) G_GNUC_PRINTF (2,0);

gboolean glnx_prefix_error (GError **error, const char *fmt, ...) G_GNUC_PRINTF (2,3);

/* Like `glnx_prefix_error ()`, but returns %NULL. */
#define glnx_prefix_error_null(error, args...) \
  ({glnx_prefix_error (error, args); NULL;})

/**
 * GLNX_AUTO_PREFIX_ERROR:
 *
 * An autocleanup-based macro to automatically call `g_prefix_error()` (also with a colon+space `: `)
 * when it goes out of scope.  This is useful when one wants error strings built up by the callee
 * function, not all callers.
 *
 * ```
 * gboolean start_http_request (..., GError **error)
 * {
 *   GLNX_AUTO_PREFIX_ERROR ("HTTP request", error)
 *
 *   if (!libhttp_request_start (..., error))
 *     return FALSE;
 *   ...
 *   return TRUE;
 * ```
 */
typedef struct {
  const char *prefix;
  GError **error;
} GLnxAutoErrorPrefix;
static inline void
glnx_cleanup_auto_prefix_error (GLnxAutoErrorPrefix *prefix)
{
  if (prefix->error && *(prefix->error))
    g_prefix_error (prefix->error, "%s: ", prefix->prefix);
}
G_DEFINE_AUTO_CLEANUP_CLEAR_FUNC(GLnxAutoErrorPrefix, glnx_cleanup_auto_prefix_error)
#define GLNX_AUTO_PREFIX_ERROR(text, error) \
  G_GNUC_UNUSED g_auto(GLnxAutoErrorPrefix) _GLNX_MAKE_ANONYMOUS(_glnxautoprefixerror_) = { text, error }

/* Set @error using the value of `g_strerror (errno)`.
 *
 * This function returns %FALSE so it can be used conveniently in a single
 * statement:
 *
 * ```
 *   if (unlinkat (fd, somepathname) < 0)
 *     return glnx_throw_errno (error);
 * ```
 */
static inline gboolean
glnx_throw_errno (GError **error)
{
  /* Save the value of errno, in case one of the
   * intermediate function calls happens to set it.
   */
  int errsv = errno;
  g_set_error_literal (error, G_IO_ERROR,
                       g_io_error_from_errno (errsv),
                       g_strerror (errsv));
  /* We also restore the value of errno, since that's
   * what was done in a long-ago libgsystem commit
   * https://gitlab.gnome.org/Archive/libgsystem/-/commit/ed106741f7a0596dc8b960b31fdae671d31d666d
   * but I certainly can't remember now why I did that.
   */
  errno = errsv;
  return FALSE;
}

/* Like glnx_throw_errno(), but yields a NULL pointer. */
#define glnx_null_throw_errno(error) \
  ({glnx_throw_errno (error); NULL;})

/* Like glnx_throw_errno(), but yields -1 (invalid fd). */
#define glnx_fd_throw_errno(error) \
  ({glnx_throw_errno (error); -1;})

/* Implementation detail of glnx_throw_errno_prefix() */
void glnx_real_set_prefix_error_from_errno_va (GError     **error,
                                               gint         errsv,
                                               const char  *format,
                                               va_list      args) G_GNUC_PRINTF (3,0);

gboolean glnx_throw_errno_prefix (GError **error, const char *fmt, ...) G_GNUC_PRINTF (2,3);

/* Like glnx_throw_errno_prefix(), but yields a NULL pointer. */
#define glnx_null_throw_errno_prefix(error, args...) \
  ({glnx_throw_errno_prefix (error, args); NULL;})

/* Like glnx_throw_errno_prefix(), but yields -1 (invalid fd). */
#define glnx_fd_throw_errno_prefix(error, args...) \
  ({glnx_throw_errno_prefix (error, args); -1;})

/* BEGIN LEGACY APIS */

#define glnx_set_error_from_errno(error)                \
  do {                                                  \
    glnx_throw_errno (error);                           \
  } while (0);

#define glnx_set_prefix_error_from_errno(error, format, args...)  \
  do {                                                            \
    glnx_throw_errno_prefix (error, format, args);                \
  } while (0);

G_END_DECLS

===== ./subprojects/libglnx/meson_options.txt =====
# Copyright 2022 Collabora Ltd.
# SPDX-License-Identifier: LGPL-2.0-or-later

option(
  'tests',
  type : 'boolean',
  description : 'build and run unit tests',
  value : true,
)

===== ./subprojects/libglnx/Makefile-libglnx.am =====
# Copyright (C) 2015 Colin Walters <walters@verbum.org>
# SPDX-License-Identifier: LGPL-2.0-or-later
#
# 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 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., 59 Temple Place - Suite 330,
# Boston, MA 02111-1307, USA.

EXTRA_DIST += \
	$(libglnx_srcpath)/README.md \
	$(libglnx_srcpath)/COPYING \
	$(libglnx_srcpath)/LICENSES/LGPL-2.0-or-later.txt \
	$(libglnx_srcpath)/LICENSES/LGPL-2.1-or-later.txt \
	$(libglnx_srcpath)/libglnx.m4 \
	$(NULL)

BUILT_SOURCES += $(top_builddir)/libglnx-config.h
CLEANFILES += $(top_builddir)/libglnx-config.h
$(top_builddir)/libglnx-config.h: Makefile.am
	echo '#include "config.h"' > $@

libglnx_la_SOURCES = \
	$(libglnx_srcpath)/glnx-macros.h \
	$(libglnx_srcpath)/glnx-backport-autocleanups.h \
	$(libglnx_srcpath)/glnx-backport-autoptr.h \
	$(libglnx_srcpath)/glnx-backport-testutils.h \
	$(libglnx_srcpath)/glnx-backport-testutils.c \
	$(libglnx_srcpath)/glnx-backports.h \
	$(libglnx_srcpath)/glnx-backports.c \
	$(libglnx_srcpath)/glnx-chase.h \
	$(libglnx_srcpath)/glnx-chase.c \
	$(libglnx_srcpath)/glnx-local-alloc.h \
	$(libglnx_srcpath)/glnx-local-alloc.c \
	$(libglnx_srcpath)/glnx-errors.h \
	$(libglnx_srcpath)/glnx-errors.c \
	$(libglnx_srcpath)/glnx-console.h \
	$(libglnx_srcpath)/glnx-console.c \
	$(libglnx_srcpath)/glnx-dirfd.h \
	$(libglnx_srcpath)/glnx-dirfd.c \
	$(libglnx_srcpath)/glnx-fdio.h \
	$(libglnx_srcpath)/glnx-fdio.c \
	$(libglnx_srcpath)/glnx-lockfile.h \
	$(libglnx_srcpath)/glnx-lockfile.c \
	$(libglnx_srcpath)/glnx-missing-syscall.h \
	$(libglnx_srcpath)/glnx-missing.h \
	$(libglnx_srcpath)/glnx-xattrs.h \
	$(libglnx_srcpath)/glnx-xattrs.c \
	$(libglnx_srcpath)/glnx-shutil.h \
	$(libglnx_srcpath)/glnx-shutil.c \
	$(libglnx_srcpath)/libglnx.h \
	$(libglnx_srcpath)/tests/libglnx-testlib.h \
	$(NULL)

libglnx_la_CFLAGS = $(AM_CFLAGS) $(libglnx_cflags) -I$(builddir)
libglnx_la_LDFLAGS = -avoid-version -Bsymbolic-functions -export-symbols-regex "^glnx_" -no-undefined -export-dynamic 
libglnx_la_LIBADD = $(libglnx_libs)

libglnx_tests = test-libglnx-xattrs test-libglnx-fdio test-libglnx-errors test-libglnx-macros test-libglnx-shutil
TESTS += $(libglnx_tests)

libglnx_testlib_sources = $(libglnx_srcpath)/tests/libglnx-testlib.c

check_PROGRAMS += $(libglnx_tests)
test_libglnx_xattrs_SOURCES = $(libglnx_testlib_sources) $(libglnx_srcpath)/tests/test-libglnx-xattrs.c
test_libglnx_xattrs_CFLAGS = $(AM_CFLAGS) $(libglnx_cflags)
test_libglnx_xattrs_LDADD = $(libglnx_libs) libglnx.la

test_libglnx_fdio_SOURCES = $(libglnx_testlib_sources) $(libglnx_srcpath)/tests/test-libglnx-fdio.c
test_libglnx_fdio_CFLAGS = $(AM_CFLAGS) $(libglnx_cflags)
test_libglnx_fdio_LDADD = $(libglnx_libs) libglnx.la

test_libglnx_errors_SOURCES = $(libglnx_testlib_sources) $(libglnx_srcpath)/tests/test-libglnx-errors.c
test_libglnx_errors_CFLAGS = $(AM_CFLAGS) $(libglnx_cflags)
test_libglnx_errors_LDADD = $(libglnx_libs) libglnx.la

test_libglnx_macros_SOURCES = $(libglnx_testlib_sources) $(libglnx_srcpath)/tests/test-libglnx-macros.c
test_libglnx_macros_CFLAGS = $(AM_CFLAGS) $(libglnx_cflags)
test_libglnx_macros_LDADD = $(libglnx_libs) libglnx.la

test_libglnx_shutil_SOURCES = $(libglnx_testlib_sources) $(libglnx_srcpath)/tests/test-libglnx-shutil.c
test_libglnx_shutil_CFLAGS = $(AM_CFLAGS) $(libglnx_cflags)
test_libglnx_shutil_LDADD = $(libglnx_libs) libglnx.la

===== ./subprojects/libglnx/glnx-backport-autoptr.h =====
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
 *
 * Copyright (C) 2015 Colin Walters <walters@verbum.org>
 * SPDX-License-Identifier: LGPL-2.0-or-later
 * 
 * GLIB - Library of useful routines for C programming
 * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
 *
 * 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 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., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

#pragma once

#include <gio/gio.h>

G_BEGIN_DECLS

#if !GLIB_CHECK_VERSION(2, 43, 4)

#define _GLIB_AUTOPTR_FUNC_NAME(TypeName) glib_autoptr_cleanup_##TypeName
#define _GLIB_AUTOPTR_TYPENAME(TypeName)  TypeName##_autoptr
#define _GLIB_AUTO_FUNC_NAME(TypeName)    glib_auto_cleanup_##TypeName
#define _GLIB_CLEANUP(func)               __attribute__((cleanup(func)))
#define _GLIB_DEFINE_AUTOPTR_CHAINUP(ModuleObjName, ParentName) \
  typedef ModuleObjName *_GLIB_AUTOPTR_TYPENAME(ModuleObjName);                                          \
  static inline void _GLIB_AUTOPTR_FUNC_NAME(ModuleObjName) (ModuleObjName **_ptr) {                     \
    _GLIB_AUTOPTR_FUNC_NAME(ParentName) ((ParentName **) _ptr); }                                        \


/* these macros are API */
#define G_DEFINE_AUTOPTR_CLEANUP_FUNC(TypeName, func) \
  typedef TypeName *_GLIB_AUTOPTR_TYPENAME(TypeName);                                                           \
  G_GNUC_BEGIN_IGNORE_DEPRECATIONS                                                                              \
  static inline void _GLIB_AUTOPTR_FUNC_NAME(TypeName) (TypeName **_ptr) { if (*_ptr) (func) (*_ptr); }         \
  G_GNUC_END_IGNORE_DEPRECATIONS
#define G_DEFINE_AUTO_CLEANUP_CLEAR_FUNC(TypeName, func) \
  G_GNUC_BEGIN_IGNORE_DEPRECATIONS                                                                              \
  static inline void _GLIB_AUTO_FUNC_NAME(TypeName) (TypeName *_ptr) { (func) (_ptr); }                         \
  G_GNUC_END_IGNORE_DEPRECATIONS
#define G_DEFINE_AUTO_CLEANUP_FREE_FUNC(TypeName, func, none) \
  G_GNUC_BEGIN_IGNORE_DEPRECATIONS                                                                              \
  static inline void _GLIB_AUTO_FUNC_NAME(TypeName) (TypeName *_ptr) { if (*_ptr != none) (func) (*_ptr); }     \
  G_GNUC_END_IGNORE_DEPRECATIONS
#define g_autoptr(TypeName) _GLIB_CLEANUP(_GLIB_AUTOPTR_FUNC_NAME(TypeName)) _GLIB_AUTOPTR_TYPENAME(TypeName)
#define g_auto(TypeName) _GLIB_CLEANUP(_GLIB_AUTO_FUNC_NAME(TypeName)) TypeName
#define g_autofree _GLIB_CLEANUP(g_autoptr_cleanup_generic_gfree)

/**
 * g_steal_pointer:
 * @pp: a pointer to a pointer
 *
 * Sets @pp to %NULL, returning the value that was there before.
 *
 * Conceptually, this transfers the ownership of the pointer from the
 * referenced variable to the "caller" of the macro (ie: "steals" the
 * reference).
 *
 * The return value will be properly typed, according to the type of
 * @pp.
 *
 * This can be very useful when combined with g_autoptr() to prevent the
 * return value of a function from being automatically freed.  Consider
 * the following example (which only works on GCC and clang):
 *
 * |[
 * GObject *
 * create_object (void)
 * {
 *   g_autoptr(GObject) obj = g_object_new (G_TYPE_OBJECT, NULL);
 *
 *   if (early_error_case)
 *     return NULL;
 *
 *   return g_steal_pointer (&obj);
 * }
 * ]|
 *
 * It can also be used in similar ways for 'out' parameters and is
 * particularly useful for dealing with optional out parameters:
 *
 * |[
 * gboolean
 * get_object (GObject **obj_out)
 * {
 *   g_autoptr(GObject) obj = g_object_new (G_TYPE_OBJECT, NULL);
 *
 *   if (early_error_case)
 *     return FALSE;
 *
 *   if (obj_out)
 *     *obj_out = g_steal_pointer (&obj);
 *
 *   return TRUE;
 * }
 * ]|
 *
 * In the above example, the object will be automatically freed in the
 * early error case and also in the case that %NULL was given for
 * @obj_out.
 *
 * Since: 2.44
 */
static inline gpointer
(g_steal_pointer) (gpointer pp)
{
  gpointer *ptr = (gpointer *) pp;
  gpointer ref;

  ref = *ptr;
  *ptr = NULL;

  return ref;
}

/* type safety */
#define g_steal_pointer(pp) \
  (0 ? (*(pp)) : (g_steal_pointer) (pp))

#endif /* !GLIB_CHECK_VERSION(2, 43, 3) */

G_END_DECLS

===== ./subprojects/libglnx/libglnx.m4 =====
# Copyright 2016 Colin Walters
# Copyright 2020 Endless OS Foundation LLC
# SPDX-License-Identifier: LGPL-2.1-or-later

AC_DEFUN([LIBGLNX_CONFIGURE],
[
dnl This defines HAVE_DECL_FOO to 1 if found or 0 if not
AC_CHECK_DECLS([
        renameat2,
        memfd_create,
        copy_file_range],
        [], [], [[
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/mount.h>
#include <fcntl.h>
#include <sched.h>
#include <linux/loop.h>
#include <linux/random.h>
#include <sys/mman.h>
]])
dnl This defines HAVE_FOO to 1 if found, or leaves it undefined if not:
dnl not the same!
AC_CHECK_FUNCS([close_range])

AC_ARG_ENABLE(otmpfile,
              [AS_HELP_STRING([--disable-otmpfile],
                              [Disable use of O_TMPFILE [default=no]])],,
              [enable_otmpfile=yes])
AS_IF([test $enable_otmpfile = yes], [], [
  AC_DEFINE([DISABLE_OTMPFILE], 1, [Define if we should avoid using O_TMPFILE])])

AC_ARG_ENABLE(wrpseudo-compat,
              [AS_HELP_STRING([--enable-wrpseudo-compat],
                              [Disable use of syscall() in some cases for compatibility with pseudo [default=no]])],,
              [enable_wrpseudo_compat=no])
AS_IF([test $enable_wrpseudo_compat = no], [], [
  AC_DEFINE([ENABLE_WRPSEUDO_COMPAT], 1, [Define if we should be compatible with pseudo])])

dnl end LIBGLNX_CONFIGURE
])

===== ./subprojects/libglnx/glnx-shutil.h =====
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
 *
 * Copyright (C) 2014,2015 Colin Walters <walters@verbum.org>.
 * SPDX-License-Identifier: LGPL-2.0-or-later
 *
 * 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 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., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

#pragma once

#include <glnx-dirfd.h>

G_BEGIN_DECLS

gboolean
glnx_shutil_rm_rf_at (int                   dfd,
                      const char           *path,
                      GCancellable         *cancellable,
                      GError              **error);

gboolean
glnx_shutil_mkdir_p_at (int                   dfd,
                        const char           *path,
                        int                   mode,
                        GCancellable         *cancellable,
                        GError              **error);

gboolean
glnx_shutil_mkdir_p_at_open (int            dfd,
                             const char    *path,
                             int            mode,
                             int           *out_dfd,
                             GCancellable  *cancellable,
                             GError       **error);

G_END_DECLS

===== ./subprojects/libglnx/glnx-dirfd.c =====
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
 *
 * Copyright (C) 2014,2015 Colin Walters <walters@verbum.org>.
 * SPDX-License-Identifier: LGPL-2.0-or-later
 *
 * 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 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., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

#include "libglnx-config.h"

#include <string.h>

#include <glnx-dirfd.h>
#include <glnx-fdio.h>
#include <glnx-errors.h>
#include <glnx-local-alloc.h>
#include <glnx-shutil.h>

/**
 * glnx_opendirat_with_errno:
 * @dfd: File descriptor for origin directory
 * @name: Pathname, relative to @dfd
 * @follow: Whether or not to follow symbolic links
 *
 * Use openat() to open a directory, using a standard set of flags.
 * This function sets errno.
 */
int
glnx_opendirat_with_errno (int           dfd,
                           const char   *path,
                           gboolean      follow)
{
  int flags = O_RDONLY | O_NONBLOCK | O_DIRECTORY | O_CLOEXEC | O_NOCTTY;
  if (!follow)
    flags |= O_NOFOLLOW;

  dfd = glnx_dirfd_canonicalize (dfd);

  return openat (dfd, path, flags);
}

/**
 * glnx_opendirat:
 * @dfd: File descriptor for origin directory
 * @path: Pathname, relative to @dfd
 * @follow: Whether or not to follow symbolic links
 * @error: Error
 *
 * Use openat() to open a directory, using a standard set of flags.
 */
gboolean
glnx_opendirat (int             dfd,
                const char     *path,
                gboolean        follow,
                int            *out_fd,
                GError        **error)
{
  int ret = glnx_opendirat_with_errno (dfd, path, follow);
  if (ret == -1)
    return glnx_throw_errno_prefix (error, "opendir(%s)", path);
  *out_fd = ret;
  return TRUE;
}

struct GLnxRealDirfdIterator
{
  gboolean initialized;
  int fd;
  DIR *d;
};
typedef struct GLnxRealDirfdIterator GLnxRealDirfdIterator;

/**
 * glnx_dirfd_iterator_init_at:
 * @dfd: File descriptor, may be AT_FDCWD or -1
 * @path: Path, may be relative to @dfd
 * @follow: If %TRUE and the last component of @path is a symlink, follow it
 * @out_dfd_iter: (out caller-allocates): A directory iterator, will be initialized
 * @error: Error
 *
 * Initialize @out_dfd_iter from @dfd and @path.
 */
gboolean
glnx_dirfd_iterator_init_at (int                     dfd,
                             const char             *path,
                             gboolean                follow,
                             GLnxDirFdIterator      *out_dfd_iter,
                             GError                **error)
{
  glnx_autofd int fd = -1;
  if (!glnx_opendirat (dfd, path, follow, &fd, error))
    return FALSE;

  if (!glnx_dirfd_iterator_init_take_fd (&fd, out_dfd_iter, error))
    return FALSE;

  return TRUE;
}

/**
 * glnx_dirfd_iterator_init_take_fd:
 * @dfd: File descriptor - ownership is taken, and the value is set to -1
 * @dfd_iter: A directory iterator
 * @error: Error
 *
 * Steal ownership of @dfd, using it to initialize @dfd_iter for
 * iteration.
 */
gboolean
glnx_dirfd_iterator_init_take_fd (int               *dfd,
                                  GLnxDirFdIterator *dfd_iter,
                                  GError           **error)
{
  GLnxRealDirfdIterator *real_dfd_iter = (GLnxRealDirfdIterator*) dfd_iter;
  DIR *d = fdopendir (*dfd);
  if (!d)
    return glnx_throw_errno_prefix (error, "fdopendir");

  real_dfd_iter->fd = g_steal_fd (dfd);
  real_dfd_iter->d = d;
  real_dfd_iter->initialized = TRUE;

  return TRUE;
}

/**
 * glnx_dirfd_iterator_next_dent:
 * @dfd_iter: A directory iterator
 * @out_dent: (out) (transfer none): Pointer to dirent; do not free
 * @cancellable: Cancellable
 * @error: Error
 *
 * Read the next value from @dfd_iter, causing @out_dent to be
 * updated.  If end of stream is reached, @out_dent will be set
 * to %NULL, and %TRUE will be returned.
 */
gboolean
glnx_dirfd_iterator_next_dent (GLnxDirFdIterator  *dfd_iter,
                               struct dirent     **out_dent,
                               GCancellable       *cancellable,
                               GError             **error)
{
  GLnxRealDirfdIterator *real_dfd_iter = (GLnxRealDirfdIterator*) dfd_iter;

  g_return_val_if_fail (out_dent, FALSE);
  g_return_val_if_fail (dfd_iter->initialized, FALSE);

  if (g_cancellable_set_error_if_cancelled (cancellable, error))
    return FALSE;

  do
    {
      errno = 0;
      *out_dent = readdir (real_dfd_iter->d);
      if (*out_dent == NULL && errno != 0)
        return glnx_throw_errno_prefix (error, "readdir");
    } while (*out_dent &&
             (strcmp ((*out_dent)->d_name, ".") == 0 ||
              strcmp ((*out_dent)->d_name, "..") == 0));

  return TRUE;
}

/**
 * glnx_dirfd_iterator_rewind:
 * @dfd_iter: A directory iterator
 *
 * Rewind to the beginning of @dfd_iter. The next call to
 * glnx_dirfd_iterator_next_dent() will provide the first entry in the
 * directory.
 */
void
glnx_dirfd_iterator_rewind (GLnxDirFdIterator  *dfd_iter)
{
  GLnxRealDirfdIterator *real_dfd_iter = (GLnxRealDirfdIterator*) dfd_iter;

  g_return_if_fail (dfd_iter->initialized);

  rewinddir (real_dfd_iter->d);
}

/**
 * glnx_dirfd_iterator_next_dent_ensure_dtype:
 * @dfd_iter: A directory iterator
 * @out_dent: (out) (transfer none): Pointer to dirent; do not free
 * @cancellable: Cancellable
 * @error: Error
 *
 * A variant of @glnx_dirfd_iterator_next_dent, which will ensure the
 * `dent->d_type` member is filled in by calling `fstatat`
 * automatically if the underlying filesystem type sets `DT_UNKNOWN`.
 */
gboolean
glnx_dirfd_iterator_next_dent_ensure_dtype (GLnxDirFdIterator  *dfd_iter,
                                            struct dirent     **out_dent,
                                            GCancellable       *cancellable,
                                            GError            **error)
{
  g_return_val_if_fail (out_dent, FALSE);

  if (!glnx_dirfd_iterator_next_dent (dfd_iter, out_dent, cancellable, error))
    return FALSE;

  struct dirent *ret_dent = *out_dent;
  if (ret_dent)
    {

      if (ret_dent->d_type == DT_UNKNOWN)
        {
          struct stat stbuf;
          if (!glnx_fstatat (dfd_iter->fd, ret_dent->d_name, &stbuf, AT_SYMLINK_NOFOLLOW, error))
            return FALSE;
          ret_dent->d_type = IFTODT (stbuf.st_mode);
        }
    }

  return TRUE;
}

/**
 * glnx_dirfd_iterator_clear:
 * @dfd_iter: Iterator, will be de-initialized
 *
 * Unset @dfd_iter, freeing any resources.  If @dfd_iter is not
 * initialized, do nothing.
 */
void
glnx_dirfd_iterator_clear (GLnxDirFdIterator *dfd_iter)
{
  GLnxRealDirfdIterator *real_dfd_iter = (GLnxRealDirfdIterator*) dfd_iter;
  /* fd is owned by dfd_iter */
  if (!real_dfd_iter->initialized)
    return;
  (void) closedir (real_dfd_iter->d);
  real_dfd_iter->initialized = FALSE;
}

/**
 * glnx_fdrel_abspath:
 * @dfd: Directory fd
 * @path: Path
 *
 * Turn a fd-relative pair into something that can be used for legacy
 * APIs expecting absolute paths.
 *
 * This is Linux specific, and only valid inside this process (unless
 * you set up the child process to have the exact same fd number, but
 * don't try that).
 */
char *
glnx_fdrel_abspath (int         dfd,
                    const char *path)
{
  dfd = glnx_dirfd_canonicalize (dfd);
  if (dfd == AT_FDCWD)
    return g_strdup (path);
  return g_strdup_printf ("/proc/self/fd/%d/%s", dfd, path);
}

/**
 * glnx_gen_temp_name:
 * @tmpl: (type filename): template directory name, the last 6 characters will be replaced
 *
 * Replace the last 6 characters of @tmpl with random ASCII.  You must
 * use this in combination with a mechanism to ensure race-free file
 * creation such as `O_EXCL`.
 */
void
glnx_gen_temp_name (gchar *tmpl)
{
  g_return_if_fail (tmpl != NULL);
  const size_t len = strlen (tmpl);
  g_return_if_fail (len >= 6);

  static const char letters[] =
    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
  static const int NLETTERS = sizeof (letters) - 1;

  char *XXXXXX = tmpl + (len - 6);
  for (int i = 0; i < 6; i++)
    XXXXXX[i] = letters[g_random_int_range(0, NLETTERS)];
}

/**
 * glnx_mkdtempat:
 * @dfd: Directory fd
 * @tmpl: (type filename): Initial template directory name, last 6 characters will be replaced
 * @mode: permissions with which to create the temporary directory
 * @out_tmpdir: (out caller-allocates): Initialized tempdir structure
 * @error: Error
 *
 * Somewhat similar to g_mkdtemp_full(), but fd-relative, and returns a
 * structure that uses autocleanups.  Note that the supplied @dfd lifetime
 * must match or exceed that of @out_tmpdir in order to remove the directory.
 */
gboolean
glnx_mkdtempat (int dfd, const char *tmpl, int mode,
                GLnxTmpDir *out_tmpdir, GError **error)
{
  g_return_val_if_fail (tmpl != NULL, FALSE);
  g_return_val_if_fail (out_tmpdir != NULL, FALSE);
  g_return_val_if_fail (!out_tmpdir->initialized, FALSE);

  dfd = glnx_dirfd_canonicalize (dfd);

  g_autofree char *path = g_strdup (tmpl);
  for (int count = 0; count < 100; count++)
    {
      glnx_gen_temp_name (path);

      /* Ideally we could use openat(O_DIRECTORY | O_CREAT | O_EXCL) here
       * to create and open the directory atomically, but that’s not supported by
       * current kernel versions: http://www.openwall.com/lists/oss-security/2014/11/26/14
       * (Tested on kernel 4.10.10-200.fc25.x86_64). For the moment, accept a
       * TOCTTOU race here. */
      if (mkdirat (dfd, path, mode) == -1)
        {
          if (errno == EEXIST)
            continue;

          /* Any other error will apply also to other names we might
           *  try, and there are 2^32 or so of them, so give up now.
           */
          return glnx_throw_errno_prefix (error, "mkdirat");
        }

      /* And open it */
      glnx_autofd int ret_dfd = -1;
      if (!glnx_opendirat (dfd, path, FALSE, &ret_dfd, error))
        {
          /* If we fail to open, let's try to clean up */
          (void)unlinkat (dfd, path, AT_REMOVEDIR);
          return FALSE;
        }

      /* Return the initialized directory struct */
      out_tmpdir->initialized = TRUE;
      out_tmpdir->src_dfd = dfd; /* referenced; see above docs */
      out_tmpdir->fd = g_steal_fd (&ret_dfd);
      out_tmpdir->path = g_steal_pointer (&path);
      return TRUE;
    }

  /* Failure */
  g_set_error (error, G_IO_ERROR, G_IO_ERROR_EXISTS,
               "glnx_mkdtempat ran out of combinations to try");
  return FALSE;
}

/**
 * glnx_mkdtemp:
 * @tmpl: (type filename): Source template directory name, last 6 characters will be replaced
 * @mode: permissions to create the temporary directory with
 * @out_tmpdir: (out caller-allocates): Return location for tmpdir data
 * @error: Return location for a #GError, or %NULL
 *
 * Similar to glnx_mkdtempat(), but will use g_get_tmp_dir() as the parent
 * directory to @tmpl.
 *
 * Returns: %TRUE on success, %FALSE otherwise
 * Since: UNRELEASED
 */
gboolean
glnx_mkdtemp (const gchar   *tmpl,
              int      mode,
              GLnxTmpDir *out_tmpdir,
              GError **error)
{
  g_autofree char *path = g_build_filename (g_get_tmp_dir (), tmpl, NULL);
  return glnx_mkdtempat (AT_FDCWD, path, mode,
                         out_tmpdir, error);
}

static gboolean
_glnx_tmpdir_free (GLnxTmpDir *tmpd,
                   gboolean    delete_dir,
                   GCancellable *cancellable,
                   GError    **error)
{
  /* Support being passed NULL so we work nicely in a GPtrArray */
  if (!(tmpd && tmpd->initialized))
    return TRUE;
  g_assert_cmpint (tmpd->fd, !=, -1);
  glnx_close_fd (&tmpd->fd);
  g_assert (tmpd->path);
  g_assert_cmpint (tmpd->src_dfd, !=, -1);
  g_autofree char *path = tmpd->path; /* Take ownership */
  tmpd->initialized = FALSE;
  if (delete_dir)
    {
      if (!glnx_shutil_rm_rf_at (tmpd->src_dfd, path, cancellable, error))
        return FALSE;
    }
  return TRUE;
}

/**
 * glnx_tmpdir_delete:
 * @tmpf: Temporary dir
 * @cancellable: Cancellable
 * @error: Error
 *
 * Deallocate a tmpdir, closing the fd and recursively deleting the path. This
 * is normally called indirectly via glnx_tmpdir_cleanup() by the autocleanup
 * attribute, but you can also invoke this directly.
 *
 * If an error occurs while deleting the filesystem path, @tmpf will still have
 * been deallocated and should not be reused.
 *
 * See also `glnx_tmpdir_unset` to avoid deleting the path.
 */
gboolean
glnx_tmpdir_delete (GLnxTmpDir *tmpf, GCancellable *cancellable, GError **error)
{
  return _glnx_tmpdir_free (tmpf, TRUE, cancellable, error);
}

/**
 * glnx_tmpdir_unset:
 * @tmpf: Temporary dir
 * @cancellable: Cancellable
 * @error: Error
 *
 * Deallocate a tmpdir, but do not delete the filesystem path.  See also
 * `glnx_tmpdir_delete()`.
 */
void
glnx_tmpdir_unset (GLnxTmpDir *tmpf)
{
  (void) _glnx_tmpdir_free (tmpf, FALSE, NULL, NULL);
}

===== ./subprojects/libglnx/.gitignore =====
# Copyright 2015 Colin Walters
# SPDX-License-Identifier: LGPL-2.1-or-later

# A path ostree writes to work around automake bug with
# subdir-objects
Makefile-libglnx.am.inc

libglnx-config.h

# Some standard bits
.deps
.libs
.dirstamp
*.typelib
*.la
*.lo
*.o
*.pyc
*.stamp
*~


===== ./subprojects/libglnx/glnx-backport-autocleanups.h =====
/*
 * Copyright © 2015 Canonical Limited
 * SPDX-License-Identifier: LGPL-2.0-or-later
 *
 * 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 of the licence, 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, see <http://www.gnu.org/licenses/>.
 *
 * Author: Ryan Lortie <desrt@desrt.ca>
 */

#pragma once

#include <glnx-backport-autoptr.h>

#if !GLIB_CHECK_VERSION(2, 43, 4)

static inline void
g_autoptr_cleanup_generic_gfree (void *p)
{ 
  void **pp = (void**)p;
  if (*pp)
    g_free (*pp);
}

G_DEFINE_AUTOPTR_CLEANUP_FUNC(GAsyncQueue, g_async_queue_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GBookmarkFile, g_bookmark_file_free)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GBytes, g_bytes_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GChecksum, g_checksum_free)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GDateTime, g_date_time_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GDir, g_dir_close)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GError, g_error_free)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GHashTable, g_hash_table_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GHmac, g_hmac_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GIOChannel, g_io_channel_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GKeyFile, g_key_file_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GList, g_list_free)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GArray, g_array_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GPtrArray, g_ptr_array_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GMainContext, g_main_context_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GMainLoop, g_main_loop_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GSource, g_source_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GMappedFile, g_mapped_file_unref)
#if GLIB_CHECK_VERSION(2, 36, 0)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GMarkupParseContext, g_markup_parse_context_unref)
#endif
G_DEFINE_AUTOPTR_CLEANUP_FUNC(gchar, g_free)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GNode, g_node_destroy)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GOptionContext, g_option_context_free)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GOptionGroup, g_option_group_free)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GPatternSpec, g_pattern_spec_free)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GQueue, g_queue_free)
G_DEFINE_AUTO_CLEANUP_CLEAR_FUNC(GQueue, g_queue_clear)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GRand, g_rand_free)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GRegex, g_regex_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GMatchInfo, g_match_info_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GScanner, g_scanner_destroy)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GSequence, g_sequence_free)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GSList, g_slist_free)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GStringChunk, g_string_chunk_free)
G_DEFINE_AUTO_CLEANUP_FREE_FUNC(GStrv, g_strfreev, NULL)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GThread, g_thread_unref)
G_DEFINE_AUTO_CLEANUP_CLEAR_FUNC(GMutex, g_mutex_clear)
G_DEFINE_AUTO_CLEANUP_CLEAR_FUNC(GCond, g_cond_clear)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GTimer, g_timer_destroy)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GTimeZone, g_time_zone_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GTree, g_tree_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GVariant, g_variant_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GVariantBuilder, g_variant_builder_unref)
G_DEFINE_AUTO_CLEANUP_CLEAR_FUNC(GVariantBuilder, g_variant_builder_clear)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GVariantIter, g_variant_iter_free)
#if GLIB_CHECK_VERSION(2, 40, 0)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GVariantDict, g_variant_dict_unref)
G_DEFINE_AUTO_CLEANUP_CLEAR_FUNC(GVariantDict, g_variant_dict_clear)
#endif
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GVariantType, g_variant_type_free)
#if GLIB_CHECK_VERSION(2, 40, 0)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GSubprocess, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GSubprocessLauncher, g_object_unref)
#endif

/* Add GObject-based types as needed. */
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GAsyncResult, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GCancellable, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GConverter, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GConverterOutputStream, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GDataInputStream, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GFile, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GFileEnumerator, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GFileIOStream, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GFileInfo, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GFileInputStream, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GFileMonitor, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GFileOutputStream, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GInputStream, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GMemoryInputStream, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GMemoryOutputStream, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GMount, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GOutputStream, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GSocket, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GSocketAddress, g_object_unref)
#if GLIB_CHECK_VERSION(2, 36, 0)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GTask, g_object_unref)
#endif
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GTlsCertificate, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GTlsDatabase, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GTlsInteraction, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GDBusConnection, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GDBusMessage, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GVolumeMonitor, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GZlibCompressor, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GZlibDecompressor, g_object_unref)

#endif

#if !GLIB_CHECK_VERSION(2, 45, 8)

static inline void
g_autoptr_cleanup_gstring_free (GString *string)
{
  if (string)
    g_string_free (string, TRUE);
}

G_DEFINE_AUTOPTR_CLEANUP_FUNC(GString, g_autoptr_cleanup_gstring_free)

#endif

===== ./subprojects/libglnx/glnx-xattrs.c =====
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
 *
 * Copyright (C) 2014,2015 Colin Walters <walters@verbum.org>.
 * SPDX-License-Identifier: LGPL-2.0-or-later
 *
 * 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 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., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

#include "libglnx-config.h"

#include <string.h>
#include <stdio.h>

#include <glnx-macros.h>
#include <glnx-xattrs.h>
#include <glnx-errors.h>
#include <glnx-local-alloc.h>

static GVariant *
variant_new_ay_bytes (GBytes *bytes)
{
  gsize size;
  gconstpointer data;
  data = g_bytes_get_data (bytes, &size);
  g_bytes_ref (bytes);
  return g_variant_new_from_data (G_VARIANT_TYPE ("ay"), data, size,
                                  TRUE, (GDestroyNotify)g_bytes_unref, bytes);
}

static char *
canonicalize_xattrs (char    *xattr_string,
                     size_t   len)
{
  char *p;
  GSList *xattrs = NULL;
  GSList *iter;
  GString *result;

  result = g_string_new (0);

  p = xattr_string;
  while (p < xattr_string+len)
    {
      xattrs = g_slist_prepend (xattrs, p);
      p += strlen (p) + 1;
    }

  xattrs = g_slist_sort (xattrs, (GCompareFunc) strcmp);
  for (iter = xattrs; iter; iter = iter->next) {
    g_string_append (result, iter->data);
    g_string_append_c (result, '\0');
  }

  g_slist_free (xattrs);
  return g_string_free (result, FALSE);
}

static gboolean
read_xattr_name_array (const char *path,
                       int         fd,
                       const char *xattrs,
                       size_t      len,
                       GVariantBuilder *builder,
                       GError  **error)
{
  gboolean ret = FALSE;
  const char *p;
  int r;
  const char *funcstr;

  g_assert (path != NULL || fd != -1);

  funcstr = fd != -1 ? "fgetxattr" : "lgetxattr";

  for (p = xattrs; p < xattrs+len; p = p + strlen (p) + 1)
    {
      ssize_t bytes_read;
      g_autofree char *buf = NULL;
      g_autoptr(GBytes) bytes = NULL;

    again:
      if (fd != -1)
        bytes_read = fgetxattr (fd, p, NULL, 0);
      else
        bytes_read = lgetxattr (path, p, NULL, 0);
      if (bytes_read < 0)
        {
          if (errno == ENODATA)
            continue;

          glnx_set_prefix_error_from_errno (error, "%s", funcstr);
          goto out;
        }
      if (bytes_read == 0)
        continue;

      buf = g_malloc (bytes_read);
      if (fd != -1)
        r = fgetxattr (fd, p, buf, bytes_read);
      else
        r = lgetxattr (path, p, buf, bytes_read);
      if (r < 0)
        {
          if (errno == ERANGE)
            {
              g_free (g_steal_pointer (&buf));
              goto again;
            }
          else if (errno == ENODATA)
            continue;

          glnx_set_prefix_error_from_errno (error, "%s", funcstr);
          goto out;
        }

      bytes = g_bytes_new_take (g_steal_pointer (&buf), bytes_read);
      g_variant_builder_add (builder, "(@ay@ay)",
                             g_variant_new_bytestring (p),
                             variant_new_ay_bytes (bytes));
    }

  ret = TRUE;
 out:
  return ret;
}

static gboolean
get_xattrs_impl (const char      *path,
                 int              fd,
                 GVariant       **out_xattrs,
                 G_GNUC_UNUSED GCancellable *cancellable,
                 GError         **error)
{
  gboolean ret = FALSE;
  ssize_t bytes_read, real_size;
  g_autofree char *xattr_names = NULL;
  g_autofree char *xattr_names_canonical = NULL;
  GVariantBuilder builder;
  gboolean builder_initialized = FALSE;
  g_autoptr(GVariant) ret_xattrs = NULL;

  g_assert (path != NULL || fd != -1);

  g_variant_builder_init (&builder, G_VARIANT_TYPE ("a(ayay)"));
  builder_initialized = TRUE;

 again:
  if (path)
    bytes_read = llistxattr (path, NULL, 0);
  else
    bytes_read = flistxattr (fd, NULL, 0);

  if (bytes_read < 0)
    {
      if (errno != ENOTSUP)
        {
          glnx_set_prefix_error_from_errno (error, "%s", "llistxattr");
          goto out;
        }
    }
  else if (bytes_read > 0)
    {
      xattr_names = g_malloc (bytes_read);
      if (path)
        real_size = llistxattr (path, xattr_names, bytes_read);
      else
        real_size = flistxattr (fd, xattr_names, bytes_read);
      if (real_size < 0)
        {
          if (errno == ERANGE)
            {
              g_free (g_steal_pointer (&xattr_names));
              goto again;
            }
          glnx_set_prefix_error_from_errno (error, "%s", "llistxattr");
          goto out;
        }
      else if (real_size > 0)
        {
          xattr_names_canonical = canonicalize_xattrs (xattr_names, real_size);

          if (!read_xattr_name_array (path, fd, xattr_names_canonical, real_size, &builder, error))
            goto out;
        }
    }

  ret_xattrs = g_variant_builder_end (&builder);
  builder_initialized = FALSE;
  g_variant_ref_sink (ret_xattrs);
  
  ret = TRUE;
  if (out_xattrs)
    *out_xattrs = g_steal_pointer (&ret_xattrs);
 out:
  if (!builder_initialized)
    g_variant_builder_clear (&builder);
  return ret;
}

/**
 * glnx_fd_get_all_xattrs:
 * @fd: a file descriptor
 * @out_xattrs: (out): A new #GVariant containing the extended attributes
 * @cancellable: Cancellable
 * @error: Error
 *
 * Read all extended attributes from @fd in a canonical sorted order, and
 * set @out_xattrs with the result.
 *
 * If the filesystem does not support extended attributes, @out_xattrs
 * will have 0 elements, and this function will return successfully.
 */
gboolean
glnx_fd_get_all_xattrs (int            fd,
                        GVariant     **out_xattrs,
                        GCancellable  *cancellable,
                        GError       **error)
{
  return get_xattrs_impl (NULL, fd, out_xattrs,
                          cancellable, error);
}

/**
 * glnx_dfd_name_get_all_xattrs:
 * @dfd: Parent directory file descriptor
 * @name: File name
 * @out_xattrs: (out): Extended attribute set
 * @cancellable: Cancellable
 * @error: Error
 *
 * Load all extended attributes for the file named @name residing in
 * directory @dfd.
 */
gboolean
glnx_dfd_name_get_all_xattrs (int            dfd,
                              const char    *name,
                              GVariant     **out_xattrs,
                              GCancellable  *cancellable,
                              GError       **error)
{
  if (G_IN_SET(dfd, AT_FDCWD, -1))
    {
      return get_xattrs_impl (name, -1, out_xattrs, cancellable, error);
    }
  else
    {
      char buf[PATH_MAX];
      /* A workaround for the lack of lgetxattrat(), thanks to Florian Weimer:
       * https://mail.gnome.org/archives/ostree-list/2014-February/msg00017.html
       */
      snprintf (buf, sizeof (buf), "/proc/self/fd/%d/%s", dfd, name);
      return get_xattrs_impl (buf, -1, out_xattrs, cancellable, error);
    }
}

static gboolean
set_all_xattrs_for_path (const char    *path,
                         GVariant      *xattrs,
                         G_GNUC_UNUSED GCancellable *cancellable,
                         GError       **error)
{
  const guint n = g_variant_n_children (xattrs);
  for (guint i = 0; i < n; i++)
    {
      const guint8* name;
      g_autoptr(GVariant) value = NULL;
      g_variant_get_child (xattrs, i, "(^&ay@ay)",
                           &name, &value);

      gsize value_len;
      const guint8* value_data = g_variant_get_fixed_array (value, &value_len, 1);

      if (lsetxattr (path, (char*)name, (char*)value_data, value_len, 0) < 0)
        return glnx_throw_errno_prefix (error, "lsetxattr(%s)", name);
    }

  return TRUE;
}

/**
 * glnx_dfd_name_set_all_xattrs:
 * @dfd: Parent directory file descriptor
 * @name: File name
 * @xattrs: Extended attribute set
 * @cancellable: Cancellable
 * @error: Error
 *
 * Set all extended attributes for the file named @name residing in
 * directory @dfd.
 */
gboolean
glnx_dfd_name_set_all_xattrs (int            dfd,
                              const char    *name,
                              GVariant      *xattrs,
                              GCancellable  *cancellable,
                              GError       **error)
{
  if (G_IN_SET(dfd, AT_FDCWD, -1))
    {
      return set_all_xattrs_for_path (name, xattrs, cancellable, error);
    }
  else
    {
      char buf[PATH_MAX];
      /* A workaround for the lack of lsetxattrat(), thanks to Florian Weimer:
       * https://mail.gnome.org/archives/ostree-list/2014-February/msg00017.html
       */
      snprintf (buf, sizeof (buf), "/proc/self/fd/%d/%s", dfd, name);
      return set_all_xattrs_for_path (buf, xattrs, cancellable, error);
    }
}

/**
 * glnx_fd_set_all_xattrs:
 * @fd: File descriptor
 * @xattrs: Extended attributes
 * @cancellable: Cancellable
 * @error: Error
 *
 * For each attribute in @xattrs, set its value on the file or
 * directory referred to by @fd.  This function does not remove any
 * attributes not in @xattrs.
 */
gboolean
glnx_fd_set_all_xattrs (int            fd,
                        GVariant      *xattrs,
                        G_GNUC_UNUSED GCancellable *cancellable,
                        GError       **error)
{
  const guint n = g_variant_n_children (xattrs);
  for (guint i = 0; i < n; i++)
    {
      const guint8* name;
      g_autoptr(GVariant) value = NULL;
      g_variant_get_child (xattrs, i, "(^&ay@ay)",
                           &name, &value);

      gsize value_len;
      const guint8* value_data = g_variant_get_fixed_array (value, &value_len, 1);

      if (TEMP_FAILURE_RETRY (fsetxattr (fd, (char*)name, (char*)value_data, value_len, 0)) < 0)
        return glnx_throw_errno_prefix (error, "Setting xattrs: fsetxattr(%s)", name);
    }

  return TRUE;
}

/**
 * glnx_lgetxattrat:
 * @dfd: Directory file descriptor
 * @subpath: Subpath
 * @attribute: Extended attribute to retrieve
 * @error: Error
 *
 * Retrieve an extended attribute value, relative to a directory file
 * descriptor.
 */
GBytes *
glnx_lgetxattrat (int            dfd,
                  const char    *subpath,
                  const char    *attribute,
                  GError       **error)
{
  char pathbuf[PATH_MAX];
  snprintf (pathbuf, sizeof (pathbuf), "/proc/self/fd/%d/%s", dfd, subpath);

  ssize_t bytes_read, real_size;
  if (TEMP_FAILURE_RETRY (bytes_read = lgetxattr (pathbuf, attribute, NULL, 0)) < 0)
    return glnx_null_throw_errno_prefix (error, "lgetxattr(%s)", attribute);

  g_autofree guint8 *buf = g_malloc (bytes_read);
  if (TEMP_FAILURE_RETRY (real_size = lgetxattr (pathbuf, attribute, buf, bytes_read)) < 0)
    return glnx_null_throw_errno_prefix (error, "lgetxattr(%s)", attribute);

  return g_bytes_new_take (g_steal_pointer (&buf), real_size);
}

/**
 * glnx_fgetxattr_bytes:
 * @fd: Directory file descriptor
 * @attribute: Extended attribute to retrieve
 * @error: Error
 *
 * Returns: (transfer full): An extended attribute value, or %NULL on error
 */
GBytes *
glnx_fgetxattr_bytes (int            fd,
                      const char    *attribute,
                      GError       **error)
{
  ssize_t bytes_read, real_size;

  if (TEMP_FAILURE_RETRY (bytes_read = fgetxattr (fd, attribute, NULL, 0)) < 0)
    return glnx_null_throw_errno_prefix (error, "fgetxattr(%s)", attribute);

  g_autofree guint8 *buf = g_malloc (bytes_read);
  if (TEMP_FAILURE_RETRY (real_size = fgetxattr (fd, attribute, buf, bytes_read)) < 0)
    return glnx_null_throw_errno_prefix (error, "fgetxattr(%s)", attribute);

  return g_bytes_new_take (g_steal_pointer (&buf), real_size);
}

/**
 * glnx_lsetxattrat:
 * @dfd: Directory file descriptor
 * @subpath: Path
 * @attribute: An attribute name
 * @value: (array length=len) (element-type guint8): Attribute value
 * @len: Length of @value
 * @flags: Flags, containing either XATTR_CREATE or XATTR_REPLACE
 * @error: Error
 *
 * Set an extended attribute, relative to a directory file descriptor.
 */
gboolean
glnx_lsetxattrat (int            dfd,
                  const char    *subpath,
                  const char    *attribute,
                  const guint8  *value,
                  gsize          len,
                  int            flags,
                  GError       **error)
{
  char pathbuf[PATH_MAX];
  snprintf (pathbuf, sizeof (pathbuf), "/proc/self/fd/%d/%s", dfd, subpath);

  if (TEMP_FAILURE_RETRY (lsetxattr (pathbuf, attribute, value, len, flags)) < 0)
    return glnx_throw_errno_prefix (error, "lsetxattr(%s)", attribute);

  return TRUE;
}


===== ./subprojects/libglnx/glnx-lockfile.c =====
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/

/***
  This file is part of systemd.
  Now copied into libglnx:
    - Use GError

  Copyright 2010 Lennart Poettering
  Copyright 2015 Colin Walters <walters@verbum.org>
  SPDX-License-Identifier: LGPL-2.1-or-later

  systemd 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.

  systemd 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 systemd; If not, see <http://www.gnu.org/licenses/>.
***/

#include "libglnx-config.h"

#include <stdlib.h>
#include <stdbool.h>
#include <errno.h>
#include <string.h>
#include <stdio.h>
#include <limits.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/file.h>
#include <sys/stat.h>
#include <fcntl.h>

#include "glnx-lockfile.h"
#include "glnx-errors.h"
#include "glnx-fdio.h"
#include "glnx-backport-autocleanups.h"
#include "glnx-local-alloc.h"

#define newa(t, n) ((t*) alloca(sizeof(t)*(n)))

/**
 * glnx_make_lock_file:
 * @dfd: Directory file descriptor (if not `AT_FDCWD`, must have lifetime `>=` @out_lock)
 * @p: Path
 * @operation: one of `LOCK_SH`, `LOCK_EX`, `LOCK_UN`, as passed to flock()
 * @out_lock: (out) (caller allocates): Return location for lock
 * @error: Error
 *
 * Block until a lock file named @p (relative to @dfd) can be created,
 * using the flags in @operation, returning the lock data in the
 * caller-allocated location @out_lock.
 *
 * This API wraps new-style process locking if available, otherwise
 * falls back to BSD locks.
 */
gboolean
glnx_make_lock_file(int dfd, const char *p, int operation, GLnxLockFile *out_lock, GError **error) {
        glnx_autofd int fd = -1;
        g_autofree char *t = NULL;
        int r;

        g_return_val_if_fail (p != NULL, FALSE);

        /*
         * We use UNPOSIX locks if they are available. They have nice
         * semantics, and are mostly compatible with NFS. However,
         * they are only available on new kernels. When we detect we
         * are running on an older kernel, then we fall back to good
         * old BSD locks. They also have nice semantics, but are
         * slightly problematic on NFS, where they are upgraded to
         * POSIX locks, even though locally they are orthogonal to
         * POSIX locks.
         */

        t = g_strdup(p);

        for (;;) {
#ifdef F_OFD_SETLK
                struct flock fl = {
                        .l_type = (operation & ~LOCK_NB) == LOCK_EX ? F_WRLCK : F_RDLCK,
                        .l_whence = SEEK_SET,
                };
#endif
                struct stat st;

                fd = openat(dfd, p, O_CREAT|O_RDWR|O_NOFOLLOW|O_CLOEXEC|O_NOCTTY, 0600);
                if (fd < 0)
                        return glnx_throw_errno(error);

                /* Unfortunately, new locks are not in RHEL 7.1 glibc */
#ifdef F_OFD_SETLK
                r = fcntl(fd, (operation & LOCK_NB) ? F_OFD_SETLK : F_OFD_SETLKW, &fl);
#else
                r = -1;
                errno = EINVAL;
#endif
                if (r < 0) {

                        /* If the kernel is too old, use good old BSD locks */
                        if (errno == EINVAL)
                                r = flock(fd, operation);

                        if (r < 0)
                                return glnx_throw_errno_prefix (error, "flock");
                }

                /* If we acquired the lock, let's check if the file
                 * still exists in the file system. If not, then the
                 * previous exclusive owner removed it and then closed
                 * it. In such a case our acquired lock is worthless,
                 * hence try again. */

                if (!glnx_fstat (fd, &st, error))
                        return FALSE;
                if (st.st_nlink > 0)
                        break;

                glnx_close_fd (&fd);
        }

        /* Note that if this is not AT_FDCWD, the caller takes responsibility
         * for the fd's lifetime being >= that of the lock.
         */
        out_lock->initialized = TRUE;
        out_lock->dfd = dfd;
        out_lock->path = g_steal_pointer (&t);
        out_lock->fd = g_steal_fd (&fd);
        out_lock->operation = operation;
        return TRUE;
}

void glnx_release_lock_file(GLnxLockFile *f) {
        int r;

        if (!(f && f->initialized))
                return;

        if (f->path) {

                /* If we are the exclusive owner we can safely delete
                 * the lock file itself. If we are not the exclusive
                 * owner, we can try becoming it. */

                if (f->fd >= 0 &&
                    (f->operation & ~LOCK_NB) == LOCK_SH) {
#ifdef F_OFD_SETLK
                        static const struct flock fl = {
                                .l_type = F_WRLCK,
                                .l_whence = SEEK_SET,
                        };

                        r = fcntl(f->fd, F_OFD_SETLK, &fl);
#else
                        r = -1;
                        errno = EINVAL;
#endif
                        if (r < 0 && errno == EINVAL)
                                r = flock(f->fd, LOCK_EX|LOCK_NB);

                        if (r >= 0)
                                f->operation = LOCK_EX|LOCK_NB;
                }

                if ((f->operation & ~LOCK_NB) == LOCK_EX) {
                        (void) unlinkat(f->dfd, f->path, 0);
                }

                g_free(f->path);
                f->path = NULL;
        }

        glnx_close_fd (&f->fd);
        f->operation = 0;
        f->initialized = FALSE;
}

===== ./subprojects/libglnx/glnx-lockfile.h =====
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/

#pragma once

/***
  This file is part of systemd.

  Copyright 2011 Lennart Poettering
  Copyright 2015 Colin Walters <walters@verbum.org>
  SPDX-License-Identifier: LGPL-2.1-or-later

  systemd 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.

  systemd 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 systemd; If not, see <http://www.gnu.org/licenses/>.
***/

#include "glnx-backport-autoptr.h"

typedef struct GLnxLockFile {
        gboolean initialized;
        int dfd;
        char *path;
        int fd;
        int operation;
} GLnxLockFile;

gboolean glnx_make_lock_file(int dfd, const char *p, int operation, GLnxLockFile *ret, GError **error);
void glnx_release_lock_file(GLnxLockFile *f);

G_DEFINE_AUTO_CLEANUP_CLEAR_FUNC(GLnxLockFile, glnx_release_lock_file)

===== ./subprojects/libglnx/glnx-backports.h =====
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
 *
 * Copyright 1998 Manish Singh
 * Copyright 1998 Tim Janik
 * Copyright (C) 2015 Colin Walters <walters@verbum.org>
 * Copyright (C) 2018 Endless OS Foundation, LLC
 * Copyright 2017 Emmanuele Bassi
 * SPDX-License-Identifier: LGPL-2.1-or-later
 * 
 * GLIB - Library of useful routines for C programming
 * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
 *
 * 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, see <http://www.gnu.org/licenses/>.
 */

#pragma once

#include <string.h>

#include <glib-unix.h>
#include <glib/gstdio.h>
#include <gio/gio.h>

G_BEGIN_DECLS

#if !GLIB_CHECK_VERSION(2, 34, 0)
#define g_clear_pointer(pp, destroy) \
  G_STMT_START {                                                               \
    G_STATIC_ASSERT (sizeof *(pp) == sizeof (gpointer));                       \
    /* Only one access, please; work around type aliasing */                   \
    union { char *in; gpointer *out; } _pp;                                    \
    gpointer _p;                                                               \
    /* This assignment is needed to avoid a gcc warning */                     \
    GDestroyNotify _destroy = (GDestroyNotify) (destroy);                      \
                                                                               \
    _pp.in = (char *) (pp);                                                    \
    _p = *_pp.out;                                                             \
    if (_p)                                                                    \
      {                                                                        \
        *_pp.out = NULL;                                                       \
        _destroy (_p);                                                         \
      }                                                                        \
  } G_STMT_END
#endif

#if !GLIB_CHECK_VERSION(2, 76, 0)
gboolean _glnx_close (gint     fd,
                      GError **error);
#else
#define _glnx_close g_close
#endif

#if !GLIB_CHECK_VERSION(2, 76, 0)
static inline gboolean
g_clear_fd (int     *fd_ptr,
            GError **error)
{
  int fd = *fd_ptr;

  *fd_ptr = -1;

  if (fd < 0)
    return TRUE;

  /* Suppress "Not available before" warning */
  G_GNUC_BEGIN_IGNORE_DEPRECATIONS
  /* This importantly calls _glnx_close to always get async-signal-safe if
   * error == NULL */
  return _glnx_close (fd, error);
  G_GNUC_END_IGNORE_DEPRECATIONS
}
#endif

#if !GLIB_CHECK_VERSION(2, 40, 0)
#define g_info(...) g_log (G_LOG_DOMAIN, G_LOG_LEVEL_INFO, __VA_ARGS__)
#endif

#if !GLIB_CHECK_VERSION(2, 44, 0)

#define g_strv_contains glnx_strv_contains
gboolean              glnx_strv_contains  (const gchar * const *strv,
                                           const gchar         *str);

#define g_set_object(object_ptr, new_object) \
 (/* Check types match. */ \
  0 ? *(object_ptr) = (new_object), FALSE : \
  glnx_set_object ((GObject **) (object_ptr), (GObject *) (new_object)) \
 )
gboolean              glnx_set_object  (GObject **object_ptr,
                                        GObject  *new_object);

#endif /* !GLIB_CHECK_VERSION(2, 44, 0) */

#if !GLIB_CHECK_VERSION(2, 38, 0)
#define G_SPAWN_DEFAULT ((GSpawnFlags) 0)
#endif

#if !GLIB_CHECK_VERSION(2, 42, 0)
#define G_OPTION_FLAG_NONE ((GOptionFlags) 0)
#endif

#ifndef G_PID_FORMAT  /* added in 2.50 */
#define G_PID_FORMAT "i"
#endif

#if !GLIB_CHECK_VERSION(2, 60, 0)
#define g_strv_equal _glnx_strv_equal
gboolean _glnx_strv_equal (const gchar * const *strv1,
                           const gchar * const *strv2);
#endif

#ifndef G_DBUS_METHOD_INVOCATION_HANDLED    /* added in 2.68 */
#define G_DBUS_METHOD_INVOCATION_HANDLED TRUE
#endif

#ifndef G_DBUS_METHOD_INVOCATION_UNHANDLED  /* added in 2.68 */
#define G_DBUS_METHOD_INVOCATION_UNHANDLED FALSE
#endif

#if !GLIB_CHECK_VERSION(2, 68, 0)
static inline gpointer _glnx_memdup2 (gconstpointer mem,
                                      gsize         byte_size) G_GNUC_ALLOC_SIZE(2);
static inline gpointer
_glnx_memdup2 (gconstpointer mem,
               gsize         byte_size)
{
  gpointer new_mem;

  if (mem && byte_size != 0)
    {
      new_mem = g_malloc (byte_size);
      memcpy (new_mem, mem, byte_size);
    }
  else
    new_mem = NULL;

  return new_mem;
}
#define g_memdup2 _glnx_memdup2
#endif

#ifndef G_OPTION_ENTRY_NULL   /* added in 2.70 */
#define G_OPTION_ENTRY_NULL { NULL, 0, 0, 0, NULL, NULL, NULL }
#endif

#ifndef G_APPROX_VALUE  /* added in 2.58 */
#define G_APPROX_VALUE(a, b, epsilon) \
  (((a) > (b) ? (a) - (b) : (b) - (a)) < (epsilon))
#endif

static inline int
_glnx_steal_fd (int *fdp)
{
#if GLIB_CHECK_VERSION(2, 70, 0)
  /* Allow it to be used without deprecation warnings, even if the target
   * GLib version is older */
  G_GNUC_BEGIN_IGNORE_DEPRECATIONS
  return g_steal_fd (fdp);
  G_GNUC_END_IGNORE_DEPRECATIONS
#else
  int fd = *fdp;
  *fdp = -1;
  return fd;
#endif
}
#define g_steal_fd _glnx_steal_fd

#if !GLIB_CHECK_VERSION(2, 74, 0)
#define G_APPLICATION_DEFAULT_FLAGS ((GApplicationFlags) 0)
#define G_CONNECT_DEFAULT ((GConnectFlags) 0)
#define G_IO_FLAG_NONE ((GIOFlags) 0)
#define G_MARKUP_DEFAULT_FLAGS ((GMarkupParseFlags) 0)
#define G_REGEX_DEFAULT ((GRegexCompileFlags) 0)
#define G_REGEX_MATCH_DEFAULT ((GRegexMatchFlags) 0)
#define G_TEST_SUBPROCESS_DEFAULT ((GTestSubprocessFlags) 0)
#define G_TEST_TRAP_DEFAULT ((GTestTrapFlags) 0)
#define G_TLS_CERTIFICATE_NO_FLAGS ((GTlsCertificateFlags) 0)
#define G_TYPE_FLAG_NONE ((GTypeFlags) 0)
#endif

#if !GLIB_CHECK_VERSION(2, 80, 0)
#define g_closefrom _glnx_closefrom
int _glnx_closefrom (int lowfd);
#define g_fdwalk_set_cloexec _glnx_fdwalk_set_cloexec
int _glnx_fdwalk_set_cloexec (int lowfd);
#endif

G_END_DECLS

===== ./subprojects/.gitignore =====
/.wraplock
bubblewrap/
dbus-proxy/

===== ./subprojects/bubblewrap.wrap =====
[wrap-git]
url = https://github.com/containers/bubblewrap.git
# v0.11.0
revision = 9ca3b05ec787acfb4b17bed37db5719fa777834f
depth = 1

===== ./.flake8 =====
[flake8]
max-line-length = 100

===== ./tools/usb/README.md =====
# USB device list generators

These are examples of functional Python 3 scripts to generate the USB
devices lists from some well-known packages.

## epsonscan2-parse.py

This will generate the list for Epson Scan2 based on the udev rules
shipped with the package.

## gphoto2-parse.py

This will parse the output of `print-camera-list` from libgphoto to
generate the list of USB devices.

## libsane-parse.py

This will generate the list for SANE based on the udev rules shipped
with the package.

## utsushi-parse.py

This will parse the SANE .desc shipping with Utsushi to generate the
USB device list.

===== ./tools/usb/utsushi-parse.py =====
#!/bin/env python3
#
# Copyright © 2024 GNOME Foundation, Inc.
#
# This program 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, see <http://www.gnu.org/licenses/>.
#
# Authors:
#       Hubert Figuière <hub@figuiere.net>
#
# Convert utsushi device list (SANE .desc).

import subprocess
import re

device_match = re.compile(r"^:usbid[\s]+\"0x([\dabcdef]*)\"[\s]+\"0x([\dabcdef]*)\"")
file = open('sane/utsushi.desc', 'r')

vendor = 0
while True:
    line = file.readline()
    if not line:
        break
    m = device_match.match(line)
    if m is not None:
        print("--usb=vnd:{}+dev:{}".format(m.group(1), m.group(2)))

===== ./tools/usb/gphoto2-parse.py =====
#!/bin/env python3
#
# Copyright © 2024 GNOME Foundation, Inc.
#
# This program 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, see <http://www.gnu.org/licenses/>.
#
# Authors:
#       Hubert Figuière <hub@figuiere.net>
#
# Convert the output of libgphoto2 print-camera-list.

import subprocess
import re

device_match = re.compile(r"^([\dabcdef]*):([\dabcdef]*)")
file = subprocess.Popen(['./packaging/generic/print-camera-list', 'idlist'], stdout=subprocess.PIPE).stdout

vendor = 0
while True:
    line = file.readline()
    if not line:
        break
    line = line.decode('utf-8')
    m = device_match.match(line)
    if m is not None:
        print("--usb=vnd:{}+dev:{}".format(m.group(1), m.group(2)))
    print("--usb=cls:6")

===== ./tools/usb/libsane-parse.py =====
#!/bin/env python3
#
# Copyright © 2024 GNOME Foundation, Inc.
#
# This program 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, see <http://www.gnu.org/licenses/>.
#
# Authors:
#       Hubert Figuière <hub@figuiere.net>
#
# Convert libsane udev rules.

import re

device_match = re.compile(r"ATTR\{idVendor\}==\"([\dabcdef]*)\",[\s]*ATTR\{idProduct\}==\"([\dabcdef]*)\"")
file = open('libsane.rules', 'r')

vendor = 0
while True:
    line = file.readline()
    if not line:
        break

    m = device_match.match(line)
    if m is not None:
        print("--usb=vnd:{}+dev:{}".format(m.group(1), m.group(2)))


===== ./tools/usb/epsonscan2-parse.py =====
#!/bin/env python3
#
# Copyright © 2024 GNOME Foundation, Inc.
#
# This program 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, see <http://www.gnu.org/licenses/>.
#
# Authors:
#       Hubert Figuière <hub@figuiere.net>
#
# Convert epsonscan2 rules.


import re

vendor_match = re.compile(r"^ATTR\{idVendor\}!=\"([\dabcdef]*)\"")
device_match = re.compile(r"^ATTRS\{idProduct\}==\"([\dabcdef]*)\"")
file = open('epsonscan2.rules', 'r')

vendor = 0
while True:
    line = file.readline()
    if not line:
        break
    line = line.strip()
    m = vendor_match.match(line)
    if m is not None:
        vendor = m.group(1)
        continue

    m = device_match.match(line)
    if m is not None:
        print("--usb=vnd:{}+dev:{}".format(vendor, m.group(1)))

===== ./selinux/build-selinux.sh =====
#!/bin/sh
# Copyright 2019 Red Hat Inc.
# Copyright 2022 Collabora Ltd.
# SPDX-License-Identifier: LGPL-2.1-or-later

set -eu

TMP=$(mktemp -d selinux-build-XXXXXX)
output="$1"
shift
cp -- "$@" "$TMP/"

make -C "$TMP" -f /usr/share/selinux/devel/Makefile flatpak.pp
bzip2 -9 "$TMP/flatpak.pp"
cp "$TMP/flatpak.pp.bz2" "$output"
rm -fr "$TMP"

===== ./selinux/flatpak.if =====
## <summary></summary>

#########################################
## <summary>
##	Transition to flatpak named content in user home
## </summary>
## <param name="domain">
##	<summary>
##      Domain allowed access.
##	</summary>
## </param>
#
interface(`flatpak_named_filetrans_home_content',`
	gen_require(`
		type flatpak_home_t;
	')

	optional_policy(`
		gnome_data_filetrans($1, flatpak_home_t, dir, "flatpak")
	')
')

===== ./selinux/flatpak.fc =====
/usr/libexec/flatpak-system-helper	--	gen_context(system_u:object_r:flatpak_helper_exec_t,s0)

HOME_DIR/\.local/share/flatpak(/.*)?		gen_context(system_u:object_r:flatpak_home_t,s0)

===== ./selinux/meson.build =====
# Copyright 2022 Collabora Ltd.
# SPDX-License-Identifier: LGPL-2.1-or-later

custom_target(
  'flatpak.pp.bz2',
  input : ['flatpak.te', 'flatpak.fc'],
  output : ['flatpak.pp.bz2'],
  build_by_default : true,
  command : [
    files('build-selinux.sh'),
    '@OUTPUT0@',
    '@INPUT@',
  ],
  install : true,
  install_dir : get_option('datadir') / 'selinux' / 'packages',
)

install_data(
  'flatpak.if',
  install_dir : get_option('datadir') / 'selinux' / 'devel' / 'include' / 'distributed',
)

===== ./selinux/flatpak.te =====
policy_module(flatpak, 0.0.1)

# The flatpak-system helper used to be a regular unconfined_service_t
# but this failed because it was not allowed to pass a unix socket fd
# over dbus-daemon. This module fixes that by creating an unconfined
# domain with some additional dbus permissions.

# I did try to make the domain confined, but it needs a lot of
# permissions and my selinux-foo just isn't good enough.

type flatpak_helper_t;
type flatpak_helper_exec_t;
init_daemon_domain(flatpak_helper_t, flatpak_helper_exec_t)

type flatpak_home_t;
userdom_user_home_content(flatpak_home_t)

auth_read_passwd(flatpak_helper_t)
files_list_var_lib(flatpak_helper_t)
files_read_var_lib_files(flatpak_helper_t)
files_read_var_lib_symlinks(flatpak_helper_t)

ifdef(`corecmd_watch_bin_dirs',`
    corecmd_watch_bin_dirs(flatpak_helper_t)
')

optional_policy(`
    dbus_stub()
    dbus_system_domain(flatpak_helper_t, flatpak_helper_exec_t)

    # Allow passing the revokefs socket over dbus
    allow system_dbusd_t flatpak_helper_t:unix_stream_socket rw_stream_socket_perms;
')

optional_policy(`
   policykit_dbus_chat(flatpak_helper_t)
')

optional_policy(`
   systemd_userdbd_stream_connect(flatpak_helper_t)
')

optional_policy(`                   
    unconfined_domain(flatpak_helper_t)
')

===== ./profile/flatpak.csh =====
set _flatpak=`where flatpak | head -n 1`
if ( ${%_flatpak} > 0 ) then
    if ( ! ${?XDG_DATA_HOME} ) setenv XDG_DATA_HOME "$HOME/.local/share"
    if ( ${%XDG_DATA_HOME} == 0 ) setenv XDG_DATA_HOME "$HOME/.local/share"
    if ( ! ${?XDG_DATA_DIRS} ) setenv XDG_DATA_DIRS /usr/local/share:/usr/share
    if ( ${%XDG_DATA_DIRS} == 0 ) setenv XDG_DATA_DIRS /usr/local/share:/usr/share
    set _new_dirs=""
    foreach _line (`(unset G_MESSAGES_DEBUG; echo "${XDG_DATA_HOME}"/flatpak; setenv GIO_USE_VFS local; flatpak --installations)`)
        set _line=${_line}/exports/share
	if ( ":${XDG_DATA_DIRS}:" =~ *:${_line}:* ) continue
	if ( ":${XDG_DATA_DIRS}:" =~ *:${_line}/:* ) continue
	if ( ${%_new_dirs} > 0 ) set _new_dirs="${_new_dirs}:"
	set _new_dirs="${_new_dirs}${_line}"
    end
    if ( ${%_new_dirs} > 0 ) then
	set _new_dirs="${_new_dirs}:"
	setenv XDG_DATA_DIRS "${_new_dirs}${XDG_DATA_DIRS}"
    endif
endif
unset _flatpak _line _new_dirs

===== ./profile/meson.build =====
# Copyright 2022 Collabora Ltd.
# SPDX-License-Identifier: LGPL-2.1-or-later

install_data(
  'flatpak.csh',
  'flatpak.sh',
  install_dir : profile_dir,
)
install_data(
  'flatpak.fish',
  install_dir : get_option('datadir') / 'fish' / 'vendor_conf.d',
)

===== ./profile/flatpak.fish =====
if type -q flatpak
    # Fast-path: skip spawning `flatpak --installations` when the canonical
    # user installation's exports/share is already present in $XDG_DATA_DIRS.
    set -x --path XDG_DATA_DIRS $XDG_DATA_DIRS

    set -l __flatpak_xdg_data_home $HOME/.local/share
    set -q XDG_DATA_HOME; and set __flatpak_xdg_data_home $XDG_DATA_HOME

    if not contains -- "$__flatpak_xdg_data_home/flatpak/exports/share" $XDG_DATA_DIRS
        set -q XDG_DATA_DIRS[1]; or set XDG_DATA_DIRS /usr/local/share /usr/share
        set -q XDG_DATA_HOME; or set -l XDG_DATA_HOME $HOME/.local/share

        set -l installations $XDG_DATA_HOME/flatpak
        begin
            set -le G_MESSAGES_DEBUG
            set -lx GIO_USE_VFS local
            set installations $installations (flatpak --installations)
        end

        for dir in {$installations[-1..1]}/exports/share
            if not contains $dir $XDG_DATA_DIRS
                set -p XDG_DATA_DIRS $dir
            end
        end
    end
end

===== ./profile/flatpak.sh =====
# shellcheck shell=sh
if command -v flatpak > /dev/null; then
    # set XDG_DATA_DIRS to include Flatpak installations

    new_dirs=$(
        (
            unset G_MESSAGES_DEBUG
            echo "${XDG_DATA_HOME:-"$HOME/.local/share"}/flatpak"
            GIO_USE_VFS=local flatpak --installations
        ) | (
            new_dirs=
            while read -r install_path
            do
                share_path=$install_path/exports/share
                case ":$XDG_DATA_DIRS:" in
                    (*":$share_path:"*) :;;
                    (*":$share_path/:"*) :;;
                    (*) new_dirs=${new_dirs:+${new_dirs}:}$share_path;;
                esac
            done
            echo "$new_dirs"
        )
    )

    export XDG_DATA_DIRS
    XDG_DATA_DIRS="${new_dirs:+${new_dirs}:}${XDG_DATA_DIRS:-/usr/local/share:/usr/share}"

    unset new_dirs
fi

===== ./revokefs/writer.h =====
/*
 * Copyright (C) 2018 Alexander Larsson <alexl@redhat.com>
 *
 * SPDX-License-Identifier: LGPL-2.0+
 *
 * 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 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., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

#ifndef __REVOKEFS_WRITER_H__
#define __REVOKEFS_WRITER_H__

int request_mkdir(int writer_socket, const char *path, mode_t mode);
int request_rmdir (int writer_socket, const char *path);
int request_unlink (int writer_socket, const char *path);
int request_symlink (int writer_socket, const char *from, const char *to);
int request_link (int writer_socket, const char *from, const char *to);
int request_rename (int writer_socket, const char *from, const char *to, unsigned int flags);
int request_chmod(int writer_socket, const char *path, mode_t mode);
int request_chown(int writer_socket, const char *path, uid_t uid, gid_t gid);
int request_truncate (int writer_socket, const char *path, off_t size);
int request_utimens (int writer_socket, const char *path, const struct timespec tv[2]);
int request_open (int writer_socket, const char *path, mode_t mode, int flags);
int request_read (int writer_socket, int fd, char *buf, size_t size, off_t offset);
int request_write (int writer_socket, int fd, const char *buf, size_t size, off_t offset);
int request_fsync (int writer_socket, int fd);
int request_close (int writer_socket, int fd);
int request_access (int writer_socket, const char *path, int mode);

void  do_writer (int basefd, int socket, int exit_with_fd);


typedef enum {
  REVOKE_FS_MKDIR,
  REVOKE_FS_RMDIR,
  REVOKE_FS_UNLINK,
  REVOKE_FS_SYMLINK,
  REVOKE_FS_LINK,
  REVOKE_FS_RENAME,
  REVOKE_FS_CHMOD,
  REVOKE_FS_CHOWN,
  REVOKE_FS_TRUNCATE,
  REVOKE_FS_UTIMENS,
  REVOKE_FS_OPEN,
  REVOKE_FS_READ,
  REVOKE_FS_WRITE,
  REVOKE_FS_FSYNC,
  REVOKE_FS_CLOSE,
  REVOKE_FS_ACCESS,
} RevokefsOps;

typedef struct {
  guint32 op;
  guint64 arg1;
  guint64 arg2;
  guint64 arg3;
  guchar data[];
} RevokefsRequest;

typedef struct {
  gint32 result;

  guchar data[];
} RevokefsResponse;

#define REQUEST_SIZE(__data_size) (sizeof(RevokefsRequest) + (__data_size))
#define RESPONSE_SIZE(__data_size) (sizeof(RevokefsResponse) + (__data_size))

#define MAX_DATA_SIZE 16384
#define MAX_REQUEST_SIZE REQUEST_SIZE(MAX_DATA_SIZE)
#define MAX_RESPONSE_SIZE RESPONSE_SIZE(MAX_DATA_SIZE)

#endif /* __REVOKEFS_WRITER_H__ */

===== ./revokefs/writer.c =====
/* vi:set et sw=2 sts=2 cin cino=t0,f0,(0,{s,>2s,n-s,^-s,e-s:
 * Copyright (C) 2018 Alexander Larsson <alexl@redhat.com>
 *
 * SPDX-License-Identifier: LGPL-2.0+
 *
 * 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 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., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

#ifndef FUSE_USE_VERSION
#error config.h needs to define FUSE_USE_VERSION
#endif

#include <sys/types.h>
#include <sys/stat.h>
#include <sys/statvfs.h>
#include <sys/socket.h>
#include <stdio.h>
#include <err.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/xattr.h>
#include <dirent.h>
#include <unistd.h>
#include <poll.h>
#include <fuse.h>

#include <glib.h>

#include "writer.h"
#include "libglnx.h"

static int basefd = -1;

static GHashTable *outstanding_fds;

static GMutex mutex;

static ssize_t
do_request (int writer_socket,
            RevokefsRequest *request,
            const void *data,
            size_t data_size,
            const void *data2,
            size_t data2_size,
            RevokefsResponse *response,
            void *response_data,
            size_t response_data_size)
{
  size_t request_size;
  size_t response_max_size;
  ssize_t written_size, read_size;
  struct iovec write_vecs[3] = {};
  int n_write_vecs = 0;
  struct iovec read_vecs[2] = {};
  int n_read_vecs = 0;
  g_autoptr(GMutexLocker) locker = NULL;

  request_size = sizeof (RevokefsRequest);
  write_vecs[n_write_vecs].iov_base = (char *)request;
  write_vecs[n_write_vecs++].iov_len = request_size;

  if (data)
    {
      write_vecs[n_write_vecs].iov_base = (char *)data;
      write_vecs[n_write_vecs++].iov_len = data_size;
      request_size += data_size;
    }

  if (data2)
    {
      write_vecs[n_write_vecs].iov_base = (char *)data2;
      write_vecs[n_write_vecs++].iov_len = data2_size;
      request_size += data2_size;
    }

  locker = g_mutex_locker_new (&mutex);
  written_size = TEMP_FAILURE_RETRY (writev (writer_socket, write_vecs, n_write_vecs));
  if (written_size == -1)
    {
      g_printerr ("Write to socket returned error %d\n", errno);
      return -1;
    }
  if (written_size != request_size)
    {
      g_printerr ("Partial Write to socket\n");
      return -1;
    }

  response_max_size = sizeof (RevokefsResponse);
  read_vecs[n_read_vecs].iov_base = (char *)response;
  read_vecs[n_read_vecs++].iov_len = response_max_size;

  if (response_data)
    {
      read_vecs[n_read_vecs].iov_base = response_data;
      read_vecs[n_read_vecs++].iov_len = response_data_size;
      response_max_size += response_data_size;
    }

  read_size = TEMP_FAILURE_RETRY (readv (writer_socket, read_vecs, n_read_vecs));
  if (read_size == -1)
    {
      g_printerr ("Read from socket returned error %d\n", errno);
      return -1;
    }

  if (read_size < sizeof (RevokefsResponse))
    {
      g_printerr ("Invalid read size %zd\n", read_size);
      return -1;
    }

  return read_size - sizeof (RevokefsResponse);
}

static int
request_path_i64_i64 (int writer_socket, RevokefsOps op, const char *path, guint64 arg1, guint64 arg2)
{
  RevokefsRequest request = { op };
  RevokefsResponse response;
  size_t path_len = strlen (path);
  ssize_t response_data_len;

  if (path_len > MAX_DATA_SIZE)
    return -ENAMETOOLONG;

  request.arg1 = arg1;
  request.arg2 = arg2;

  response_data_len = do_request (writer_socket, &request, path, path_len, NULL, 0,
                                  &response, NULL, 0);
  if (response_data_len != 0)
    return -EIO;

  return response.result;
}

static int
request_path_int_int (int writer_socket, RevokefsOps op, const char *path, int arg1, int arg2)
{
  return request_path_i64_i64 (writer_socket, op, path, arg1, arg2);
}

static int
request_path_int (int writer_socket, RevokefsOps op, const char *path, int arg1)
{
  return request_path_int_int (writer_socket, op, path, arg1, 0);
}

static int
request_path (int writer_socket, RevokefsOps op, const char *path)
{
  return request_path_int_int (writer_socket, op, path, 0, 0);
}

static int
request_path_data (int writer_socket, RevokefsOps op, const char *path,
                   const char *data, size_t data_len, guint64 flags)
{
  RevokefsRequest request = { op };
  RevokefsResponse response;
  size_t path_len = strlen (path);
  size_t total_len = path_len + data_len;
  ssize_t response_data_len;

  if (total_len > MAX_DATA_SIZE)
    return -ENAMETOOLONG;

  request.arg1 = path_len;
  request.arg2 = flags;

  response_data_len = do_request (writer_socket, &request, path, path_len, data, data_len,
                                  &response, NULL, 0);
  if (response_data_len != 0)
    return -EIO;

  return response.result;
}

static int
request_path_path (int writer_socket, RevokefsOps op, const char *path1, const char *path2)
{
  return request_path_data (writer_socket, op, path1, path2, strlen(path2), 0);
}

static gboolean
validate_path (char *path)
{
  char *end_segment;

  /* No absolute or empty paths */
  if (*path == '/' || *path == 0)
    return FALSE;

  while (*path != 0)
    {
      end_segment = strchr (path, '/');
      if (end_segment == NULL)
        end_segment = path + strlen (path);

      if (strncmp (path, "..", 2) == 0)
        return FALSE;

      path = end_segment;
      while (*path == '/')
        path++;
    }

  return TRUE;
}

static char *
get_valid_path (guchar *data, size_t len)
{
  char *path = g_strndup ((const char *) data, len);

  if (!validate_path (path))
    {
      g_printerr ("Invalid path argument %s\n", path);
      exit (1);
    }

  return path;
}

static int
mask_mode (int mode)
{
  /* mask setuid, setgid and world-writable permissions bits */
  return mode & ~S_ISUID & ~S_ISGID & ~(S_IWGRP | S_IWOTH);
}

static void
get_any_path_and_valid_path (RevokefsRequest *request,
                             gsize data_size,
                             char **any_path1,
                             char **valid_path2)
{
  if (request->arg1 >= data_size)
    {
      g_printerr ("Invalid path1 size\n");
      exit (1);
    }

  *any_path1 = g_strndup ((const char *) request->data, request->arg1);
  *valid_path2 = get_valid_path (request->data + request->arg1, data_size - request->arg1);
}

static void
get_valid_2path (RevokefsRequest *request,
                 gsize data_size,
                 char **path1,
                 char **path2)
{
  if (request->arg1 >= data_size)
    {
      g_printerr ("Invalid path1 size\n");
      exit (1);
    }

  *path1 = get_valid_path (request->data, request->arg1);
  *path2 = get_valid_path (request->data + request->arg1, data_size - request->arg1);
}

static ssize_t
handle_mkdir (RevokefsRequest *request,
              gsize data_size,
              RevokefsResponse *response)
{
  g_autofree char *path = get_valid_path (request->data, data_size);
  int mode = request->arg1;

  if (mkdirat (basefd, path, mask_mode (mode)) == -1)
    response->result = -errno;
  else
    response->result = 0;

  return 0;
}

int
request_mkdir (int writer_socket, const char *path, mode_t mode)
{
  return request_path_int (writer_socket, REVOKE_FS_MKDIR, path, mode);
}

static ssize_t
handle_rmdir (RevokefsRequest *request,
              gsize data_size,
              RevokefsResponse *response)
{
  g_autofree char *path = get_valid_path (request->data, data_size);

  if (unlinkat (basefd, path, AT_REMOVEDIR) == -1)
    response->result = -errno;
  else
    response->result = 0;

  return 0;
}

int
request_rmdir (int writer_socket, const char *path)
{
  return request_path (writer_socket, REVOKE_FS_RMDIR, path);
}

static ssize_t
handle_unlink (RevokefsRequest *request,
              gsize data_size,
              RevokefsResponse *response)
{
  g_autofree char *path = get_valid_path (request->data, data_size);

  if (unlinkat (basefd, path, 0) == -1)
    response->result = -errno;
  else
    response->result = 0;

  return 0;
}

int
request_unlink (int writer_socket, const char *path)
{
  return request_path (writer_socket, REVOKE_FS_UNLINK, path);
}

static ssize_t
handle_symlink (RevokefsRequest *request,
                gsize data_size,
                RevokefsResponse *response)
{
  g_autofree char *from = NULL;
  g_autofree char *to = NULL;

  /* from doesn't have to be a valid path, it can be absolute or whatever */
  get_any_path_and_valid_path (request, data_size,  &from, &to);

  if (symlinkat (from, basefd, to) == -1)
    response->result = -errno;
  else
    response->result = 0;

  return 0;
}

int
request_symlink (int writer_socket, const char *from, const char *to)
{
  return request_path_path (writer_socket, REVOKE_FS_SYMLINK, from, to);
}

static ssize_t
handle_link (RevokefsRequest *request,
             gsize data_size,
             RevokefsResponse *response)
{
  g_autofree char *from = NULL;
  g_autofree char *to = NULL;

  get_valid_2path (request, data_size,  &from, &to);

  if (linkat (basefd, from, basefd, to, 0) == -1)
    response->result = -errno;
  else
    response->result = 0;

  return 0;
}

int
request_link (int writer_socket, const char *from, const char *to)
{
  return request_path_path (writer_socket, REVOKE_FS_LINK, from, to);
}

static ssize_t
handle_rename (RevokefsRequest *request,
             gsize data_size,
             RevokefsResponse *response)
{
  g_autofree char *from = NULL;
  g_autofree char *to = NULL;
  unsigned int flags;

  get_valid_2path (request, data_size,  &from, &to);
  flags = (unsigned int)request->arg2;

  if (renameat2 (basefd, from, basefd, to, flags) == -1)
    response->result = -errno;
  else
    response->result = 0;

  return 0;
}

int
request_rename (int writer_socket,
                const char *from,
                const char *to,
                unsigned int flags)
{
  return request_path_data (writer_socket, REVOKE_FS_RENAME, from, to, strlen (to), flags);
}

static ssize_t
handle_chmod (RevokefsRequest *request,
              gsize data_size,
              RevokefsResponse *response)
{
  g_autofree char *path = get_valid_path (request->data, data_size);
  int mode = request->arg1;

  /* Note we can't use AT_SYMLINK_NOFOLLOW yet;
   * https://marc.info/?l=linux-kernel&m=148830147803162&w=2
   * https://marc.info/?l=linux-fsdevel&m=149193779929561&w=2
   */
  if (fchmodat (basefd, path, mask_mode (mode), 0) != 0)
    response->result = -errno;
  else
    response->result = 0;

  return 0;
}

int
request_chmod(int writer_socket, const char *path, mode_t mode)
{
  return request_path_int (writer_socket, REVOKE_FS_CHMOD, path, mode);
}

static ssize_t
handle_chown (RevokefsRequest *request,
              gsize data_size,
              RevokefsResponse *response)
{
  g_autofree char *path = get_valid_path (request->data, data_size);
  uid_t uid = request->arg1;
  gid_t gid = request->arg2;

  if (fchownat (basefd, path, uid, gid, AT_SYMLINK_NOFOLLOW) != 0)
    response->result = -errno;
  else
    response->result = 0;

  return 0;
}

int
request_chown(int writer_socket, const char *path, uid_t uid, gid_t gid)
{
  return request_path_int_int (writer_socket, REVOKE_FS_CHOWN, path, uid, gid);
}

static ssize_t
handle_truncate (RevokefsRequest *request,
                 gsize data_size,
                 RevokefsResponse *response)
{
  g_autofree char *path = get_valid_path (request->data, data_size);
  off_t size = request->arg1;

  glnx_autofd int fd = openat (basefd, path, O_NOFOLLOW|O_WRONLY);
  if (fd == -1)
    response->result = -errno;
  else
    {
      if (ftruncate (fd, size) == -1)
        response->result = -errno;
      else
        response->result = 0;
    }

  return 0;
}

int
request_truncate (int writer_socket, const char *path, off_t size)
{
  return request_path_i64_i64 (writer_socket, REVOKE_FS_TRUNCATE, path, size, 0);
}

static ssize_t
handle_utimens (RevokefsRequest *request,
                gsize data_size,
                RevokefsResponse *response)
{
  g_autofree char *path = NULL;
  struct timespec *tv;

  if (request->arg1 + sizeof (struct timespec) * 2 != data_size)
    {
      g_printerr ("Invalid data size\n");
      exit (1);
    }

  path = get_valid_path (request->data, request->arg1);
  tv = (struct timespec *)(request->data + request->arg1);

  if (utimensat (basefd, path, tv, AT_SYMLINK_NOFOLLOW) == -1)
    response->result = -errno;
  else
    response->result = 0;

  return 0;
}

int
request_utimens (int writer_socket, const char *path, const struct timespec tv[2])
{
  return request_path_data (writer_socket, REVOKE_FS_UTIMENS, path,
                            (const char *)tv, sizeof (struct timespec) * 2, 0);
}

static ssize_t
handle_open (RevokefsRequest *request,
             gsize data_size,
             RevokefsResponse *response)
{
  g_autofree char *path = get_valid_path (request->data, data_size);
  int mode = request->arg1;
  int flags = request->arg2;
  int fd;


  /* We need to specially handle O_TRUNC. Also, Fuse should have already
   * resolved symlinks, but use O_NOFOLLOW to be safe to avoid following
   * symlinks to some other filesystem. */
  fd = openat (basefd, path, (flags & ~O_TRUNC) | O_NOFOLLOW, mask_mode (mode));
  if (fd == -1)
    response->result = -errno;
  else
    {
      response->result = 0;
      if (flags & O_TRUNC)
        {
          if (ftruncate (fd, 0) == -1)
            response->result = -errno;
        }

      if (response->result == 0)
        {
          g_hash_table_insert (outstanding_fds, GUINT_TO_POINTER(fd), GUINT_TO_POINTER(1));
          response->result = fd;
        }
      else
        (void) close (fd);
    }

  return 0;
}

int
request_open (int writer_socket, const char *path, mode_t mode, int flags)
{
  return request_path_int_int (writer_socket, REVOKE_FS_OPEN, path, mode, flags);
}

static ssize_t
handle_read (RevokefsRequest *request,
             gsize data_size,
             RevokefsResponse *response)
{
  int r;
  int fd = request->arg1;
  size_t size = request->arg2;
  off_t offset = request->arg3;

  if (size > MAX_DATA_SIZE)
    size = MAX_DATA_SIZE;

  if (g_hash_table_lookup (outstanding_fds, GUINT_TO_POINTER(fd)) == NULL)
    {
      response->result = -EBADFD;
      return 0;
    }

  r = pread (fd, response->data, size, offset);
  if (r == -1)
    {
      response->result = -errno;
      return 0;
    }
  else
    {
      response->result = r;
      return r;
    }
}

int
request_read (int writer_socket, int fd, char *buf, size_t size, off_t offset)
{
  RevokefsRequest request = { REVOKE_FS_READ };
  RevokefsResponse response;
  ssize_t response_data_len;

  request.arg1 = fd;
  request.arg2 = size;
  request.arg3 = offset;

  response_data_len = do_request (writer_socket, &request, NULL, 0, NULL, 0,
                                  &response, buf, size);
  if (response_data_len < 0)
    return -EIO;

  return response.result;
}

static ssize_t
handle_write (RevokefsRequest *request,
              gsize data_size,
              RevokefsResponse *response)
{
  int r;
  int fd = request->arg1;
  off_t offset = request->arg2;

  if (g_hash_table_lookup (outstanding_fds, GUINT_TO_POINTER(fd)) == NULL)
    {
      response->result = -EBADFD;
      return 0;
    }

  r = pwrite (fd, request->data, data_size, offset);
  if (r == -1)
    response->result = -errno;
  else
    response->result = r;

  return 0;
}

int
request_write (int writer_socket, int fd, const char *buf, size_t size, off_t offset)
{
  RevokefsRequest request = { REVOKE_FS_WRITE };
  RevokefsResponse response;
  ssize_t response_data_len;

  if (size > MAX_DATA_SIZE)
    size = MAX_DATA_SIZE;

  request.arg1 = fd;
  request.arg2 = offset;

  response_data_len = do_request (writer_socket, &request, buf, size, NULL, 0,
                                  &response, NULL, 0);
  if (response_data_len < 0)
    return -EIO;

  return response.result;
}

static ssize_t
handle_fsync (RevokefsRequest *request,
              gsize data_size,
              RevokefsResponse *response)
{
  int r;
  int fd = request->arg1;

  if (g_hash_table_lookup (outstanding_fds, GUINT_TO_POINTER(fd)) == NULL)
    {
      response->result = -EBADFD;
      return 0;
    }

  r = fsync (fd);
  if (r == -1)
    response->result = -errno;
  else
    response->result = r;

  return 0;
}

int
request_fsync (int writer_socket, int fd)
{
  RevokefsRequest request = { REVOKE_FS_FSYNC };
  RevokefsResponse response;
  ssize_t response_data_len;

  request.arg1 = fd;

  response_data_len = do_request (writer_socket, &request, NULL, 0, NULL, 0,
                                  &response, NULL, 0);
  if (response_data_len < 0)
    return -EIO;

  return response.result;
}

static ssize_t
handle_close (RevokefsRequest *request,
              gsize data_size,
              RevokefsResponse *response)
{
  int fd = request->arg1;

  if (!g_hash_table_remove (outstanding_fds, GUINT_TO_POINTER(fd)))
    {
      response->result = -EBADFD;
      return 0;
    }

  close (fd);
  response->result = 0;
  return 0;
}

int
request_close (int writer_socket, int fd)
{
  RevokefsRequest request = { REVOKE_FS_CLOSE };
  RevokefsResponse response;
  ssize_t response_data_len;

  request.arg1 = fd;
  response_data_len = do_request (writer_socket, &request, NULL, 0, NULL, 0,
                                  &response, NULL, 0);
  if (response_data_len < 0)
    return -EIO;

  return response.result;
}

static ssize_t
handle_access (RevokefsRequest *request,
               gsize data_size,
               RevokefsResponse *response)
{
  g_autofree char *path = get_valid_path (request->data, data_size);
  int mode = request->arg1;

  /* Apparently at least GNU coreutils rm calls `faccessat(W_OK)`
   * before trying to do an unlink.  So...we'll just lie about
   * writable access here.
   */
  if (faccessat (basefd, path, mode, AT_SYMLINK_NOFOLLOW) == -1)
    response->result = -errno;
  else
    response->result = 0;

  return 0;
}

int
request_access (int writer_socket, const char *path, int mode)
{
  return request_path_int (writer_socket, REVOKE_FS_ACCESS, path, mode);
}

void
do_writer (int basefd_arg,
           int fuse_socket,
           int exit_with_fd)
{
  guchar request_buffer[MAX_REQUEST_SIZE];
  RevokefsRequest *request = (RevokefsRequest *)&request_buffer;
  guchar response_buffer[MAX_RESPONSE_SIZE];
  RevokefsResponse *response = (RevokefsResponse *)&response_buffer;

  basefd = basefd_arg;
  outstanding_fds = g_hash_table_new (g_direct_hash, g_direct_equal);

  while (1)
    {
      ssize_t data_size, size;
      ssize_t response_data_size, response_size, written_size;
      int res;
      struct pollfd pollfds[2] =  {
         {fuse_socket, POLLIN, 0 },
         {exit_with_fd, POLLIN, 0 },
      };

      res = poll(pollfds, exit_with_fd >= 0 ? 2 : 1, -1);
      if (res < 0)
        {
          perror ("Got error polling sockets: ");
          exit (1);
        }

      if (exit_with_fd >= 0 && (pollfds[1].revents & (POLLERR|POLLHUP)) != 0)
        {
          g_printerr ("Received EOF on exit-with-fd argument");
          exit (1);
        }

      if ((pollfds[0].revents & POLLIN) == 0)
        continue;

      size = TEMP_FAILURE_RETRY (read (fuse_socket, request_buffer, sizeof (request_buffer)));
      if (size == -1)
        {
          perror ("Got error reading from fuse socket: ");
          exit (1);
        }

      if (size == 0)
        {
          /* Fuse filesystem finished */
          exit (1);
        }

      if (size < sizeof (RevokefsRequest))
        {
          g_printerr ("Invalid request size %zd", size);
          exit (1);
        }

      data_size = size - sizeof (RevokefsRequest);
      memset (response_buffer, 0, sizeof(RevokefsResponse));

      switch (request->op)
        {
        case REVOKE_FS_MKDIR:
          response_data_size = handle_mkdir (request, data_size, response);
          break;
        case REVOKE_FS_RMDIR:
          response_data_size = handle_rmdir (request, data_size, response);
          break;
        case REVOKE_FS_UNLINK:
          response_data_size = handle_unlink (request, data_size, response);
          break;
        case REVOKE_FS_SYMLINK:
          response_data_size = handle_symlink (request, data_size, response);
          break;
        case REVOKE_FS_LINK:
          response_data_size = handle_link (request, data_size, response);
          break;
        case REVOKE_FS_RENAME:
          response_data_size = handle_rename (request, data_size, response);
          break;
        case REVOKE_FS_CHMOD:
          response_data_size = handle_chmod (request, data_size, response);
          break;
        case REVOKE_FS_CHOWN:
          response_data_size = handle_chown (request, data_size, response);
          break;
        case REVOKE_FS_TRUNCATE:
          response_data_size = handle_truncate (request, data_size, response);
          break;
        case REVOKE_FS_UTIMENS:
          response_data_size = handle_utimens (request, data_size, response);
          break;
        case REVOKE_FS_OPEN:
          response_data_size = handle_open (request, data_size, response);
          break;
        case REVOKE_FS_READ:
          response_data_size = handle_read (request, data_size, response);
          break;
        case REVOKE_FS_WRITE:
          response_data_size = handle_write (request, data_size, response);
          break;
        case REVOKE_FS_FSYNC:
          response_data_size = handle_fsync (request, data_size, response);
          break;
        case REVOKE_FS_CLOSE:
          response_data_size = handle_close (request, data_size, response);
          break;
        case REVOKE_FS_ACCESS:
          response_data_size = handle_access (request, data_size, response);
          break;
        default:
          g_printerr ("Invalid request op %d", (guint) request->op);
          exit (1);
        }

      if (response_data_size < 0 || response_data_size > MAX_DATA_SIZE)
        {
          g_printerr ("Invalid response size %zd", response_data_size);
          exit (1);
        }

      response_size = RESPONSE_SIZE(response_data_size);

      written_size = TEMP_FAILURE_RETRY (write (fuse_socket, response_buffer, response_size));
      if (written_size == -1)
        {
          perror ("Got error writing to fuse socket: ");
          exit (1);
        }

      if (written_size != response_size)
        {
          g_printerr ("Got partial write to fuse socket");
          exit (1);
        }
    }
}

===== ./revokefs/demo.c =====
#include <glib.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <unistd.h>
#include <fcntl.h>

int
main (int argc, char *argv[])
{
  int sockets[2];
  g_autofree char *socket_0 = NULL;
  g_autofree char *socket_1 = NULL;
  GError *error = NULL;
  char buf[20];
  GPid backend_pid, fuse_pid;

  if (argc != 3)
    {
      g_printerr ("Usage: revokefs-demo basepath targetpath\n");
      exit (EXIT_FAILURE);
    }

  if (socketpair(AF_UNIX, SOCK_SEQPACKET, 0, sockets))
    {
      perror ("Failed to create socket pair");
      exit (EXIT_FAILURE);
    }

  socket_0 = g_strdup_printf ("--socket=%d", sockets[0]);
  socket_1 = g_strdup_printf ("--socket=%d", sockets[1]);

  const char * const backend_argv[] =
    {
     "./revokefs-fuse",
     "--backend",
     socket_0,
     argv[1],
     NULL
    };

  /* Don't inherit fuse socket in backend */
  fcntl (sockets[1], F_SETFD, FD_CLOEXEC);
  if (!g_spawn_async (NULL,
                      (char **) backend_argv,
                      NULL,
                      G_SPAWN_LEAVE_DESCRIPTORS_OPEN,
                      NULL, NULL,
                      &backend_pid, &error))
    {
      g_printerr ("Failed to launch backend: %s", error->message);
      exit (EXIT_FAILURE);
    }
  close (sockets[0]); /* Close backend side now so it doesn't get into the fuse child */

  const char * const fuse_argv[] =
    {
     "./revokefs-fuse",
     socket_1,
     argv[1],
     argv[2],
     NULL
    };

  if (!g_spawn_async (NULL,
                      (char **) fuse_argv,
                      NULL,
                      G_SPAWN_LEAVE_DESCRIPTORS_OPEN,
                      NULL, NULL,
                      &fuse_pid, &error))
    {
      g_printerr ("Failed to launch backend: %s", error->message);
      exit (EXIT_FAILURE);
    }

  g_print ("Started revokefs, press enter to revoke");
  if (!fgets(buf, sizeof(buf), stdin))
    {
      perror ("fgets");
    }

  g_print ("Revoking write permissions");
  shutdown (sockets[1], SHUT_RDWR);
}

===== ./revokefs/meson.build =====
# Copyright 2022 Collabora Ltd.
# SPDX-License-Identifier: LGPL-2.1-or-later

executable(
  'revokefs-fuse',
  dependencies : [
    base_deps,
    fuse_dep,
    libglnx_dep,
  ],
  install : true,
  install_dir : get_option('libexecdir'),
  sources : [
    'main.c',
    'writer.c',
  ],
)

executable(
  'revokefs-demo',
  install : false,
  sources : ['demo.c'],
  dependencies : base_deps,
)

===== ./revokefs/main.c =====
/* vi:set et sw=2 sts=2 cin cino=t0,f0,(0,{s,>2s,n-s,^-s,e-s:
 * Copyright (C) 2015,2016 Colin Walters <walters@verbum.org>
 * Copyright (C) 2018 Alexander Larsson <alexl@redhat.com>
 *
 * SPDX-License-Identifier: LGPL-2.0+
 *
 * 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 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., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

#ifndef FUSE_USE_VERSION
#error config.h needs to define FUSE_USE_VERSION
#endif

#include <sys/types.h>
#include <sys/stat.h>
#include <sys/statvfs.h>
#include <sys/socket.h>
#include <stdio.h>
#include <err.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/xattr.h>
#include <dirent.h>
#include <unistd.h>
#include <fuse.h>

#include <glib.h>

#include "writer.h"
#include "libglnx.h"

/* fh >= REMOTE_FD_OFFSET means the fd is in the writer side, otherwise it is local */
#define REMOTE_FD_OFFSET ((guint64)G_MAXUINT32)

// Global to store our read-write path
static char *base_path = NULL;
static int basefd = -1;
static int writer_socket = -1;

static inline const char *
ENSURE_RELPATH (const char *path)
{
  path = path + strspn (path, "/");
  if (*path == 0)
    return ".";
  return path;
}

static int
#if FUSE_USE_VERSION >= 31
callback_getattr (const char *path, struct stat *st_data, struct fuse_file_info *finfo)
#else
callback_getattr (const char *path, struct stat *st_data)
#endif
{
  path = ENSURE_RELPATH (path);
  if (!*path)
    {
      if (fstat (basefd, st_data) == -1)
        return -errno;
    }
  else
    {
      if (fstatat (basefd, path, st_data, AT_SYMLINK_NOFOLLOW) == -1)
        return -errno;
    }
  return 0;
}

static int
callback_readlink (const char *path, char *buf, size_t size)
{
  int r;

  path = ENSURE_RELPATH (path);

  /* Note FUSE wants the string to be always nul-terminated, even if
   * truncated.
   */
  r = readlinkat (basefd, path, buf, size - 1);
  if (r == -1)
    return -errno;
  buf[r] = '\0';
  return 0;
}

static int
#if FUSE_USE_VERSION >= 31
callback_readdir (const char *path, void *buf, fuse_fill_dir_t filler,
                  off_t offset, struct fuse_file_info *fi, enum fuse_readdir_flags flags)
#else
callback_readdir (const char *path, void *buf, fuse_fill_dir_t filler,
                  off_t offset, struct fuse_file_info *fi)
#endif
{
  DIR *dp;
  struct dirent *de;
  int dfd;

  path = ENSURE_RELPATH (path);

  if (!*path)
    {
      dfd = fcntl (basefd, F_DUPFD_CLOEXEC, 3);
      if (dfd < 0)
        return -errno;
      lseek (dfd, 0, SEEK_SET);
    }
  else
    {
      dfd = glnx_opendirat_with_errno (basefd, path, TRUE);
      if (dfd == -1)
        return -errno;
    }

  /* Transfers ownership of fd */
  dp = fdopendir (dfd);
  if (dp == NULL)
    return -errno;

  while ((de = readdir (dp)) != NULL)
    {
      struct stat st;
      memset (&st, 0, sizeof (st));
      st.st_ino = de->d_ino;
      st.st_mode = de->d_type << 12;

#if FUSE_USE_VERSION >= 31
      if (filler (buf, de->d_name, &st, 0, 0))
        break;
#else
      if (filler (buf, de->d_name, &st, 0))
        break;
#endif
    }

  (void) closedir (dp);
  return 0;
}

static int
callback_mknod (const char *path, mode_t mode, dev_t rdev)
{
  return -EROFS;
}

static int
callback_mkdir (const char *path, mode_t mode)
{
  path = ENSURE_RELPATH (path);
  return request_mkdir (writer_socket, path, mode);
}

static int
callback_unlink (const char *path)
{
  path = ENSURE_RELPATH (path);
  return request_unlink (writer_socket, path);
}

static int
callback_rmdir (const char *path)
{
  path = ENSURE_RELPATH (path);
  return request_rmdir (writer_socket, path);
}

static int
callback_symlink (const char *from, const char *to)
{
  struct stat stbuf;
  int res;

  to = ENSURE_RELPATH (to);

  res = request_symlink (writer_socket, from, to);
  if (res < 0)
    return res;

  if (fstatat (basefd, to, &stbuf, AT_SYMLINK_NOFOLLOW) == -1)
    {
      fprintf (stderr, "Failed to find newly created symlink '%s': %s\n",
               to, g_strerror (errno));
      exit (EXIT_FAILURE);
    }
  return 0;
}

static int
#if FUSE_USE_VERSION >= 31
callback_rename (const char *from, const char *to, unsigned int flags)
#else
callback_rename (const char *from, const char *to)
#endif
{
#if FUSE_USE_VERSION < 31
  unsigned int flags = 0;
#endif

  from = ENSURE_RELPATH (from);
  to = ENSURE_RELPATH (to);

  return request_rename (writer_socket, from, to, flags);
}

static int
callback_link (const char *from, const char *to)
{
  from = ENSURE_RELPATH (from);
  to = ENSURE_RELPATH (to);

  return request_link (writer_socket, from, to);
}

static int
#if FUSE_USE_VERSION >= 31
callback_chmod (const char *path, mode_t mode, struct fuse_file_info *finfo)
#else
callback_chmod (const char *path, mode_t mode)
#endif
{
  path = ENSURE_RELPATH (path);
  return request_chmod (writer_socket, path, mode);
}

static int
#if FUSE_USE_VERSION >= 31
callback_chown (const char *path, uid_t uid, gid_t gid, struct fuse_file_info *finfo)
#else
callback_chown (const char *path, uid_t uid, gid_t gid)
#endif
{
  path = ENSURE_RELPATH (path);
  return request_chown (writer_socket, path, uid, gid);
}

static int
#if FUSE_USE_VERSION >= 31
callback_truncate (const char *path, off_t size, struct fuse_file_info *finfo)
#else
callback_truncate (const char *path, off_t size)
#endif
{
  path = ENSURE_RELPATH (path);
  return request_truncate (writer_socket, path, size);
}

static int
#if FUSE_USE_VERSION >= 31
callback_utimens (const char *path, const struct timespec tv[2], struct fuse_file_info *finfo)
#else
callback_utimens (const char *path, const struct timespec tv[2])
#endif
{
  path = ENSURE_RELPATH (path);

  return request_utimens (writer_socket, path, tv);
}

static int
do_open (const char *path, mode_t mode, struct fuse_file_info *finfo)
{
  int fd;

  path = ENSURE_RELPATH (path);

  if ((finfo->flags & O_ACCMODE) == O_RDONLY)
    {
      /* Read */
      fd = openat (basefd, path, finfo->flags, mode);
      if (fd == -1)
        return -errno;

      finfo->fh = fd;
    }
  else
    {
      /* Write */

      fd = request_open (writer_socket, path, mode, finfo->flags);
      if (fd < 0)
        return fd;

      finfo->fh = fd + REMOTE_FD_OFFSET;

      /* Ensure all I/O requests bypass the page cache and are sent to
       * the backend. */
      finfo->direct_io = 1;
    }

  return 0;
}

static int
callback_open (const char *path, struct fuse_file_info *finfo)
{
  return do_open (path, 0, finfo);
}

static int
callback_create(const char *path, mode_t mode, struct fuse_file_info *finfo)
{
  return do_open (path, mode, finfo);
}

static int
callback_read (const char *path, char *buf, size_t size, off_t offset,
               struct fuse_file_info *finfo)
{
  int r;
  if (finfo->fh >= REMOTE_FD_OFFSET)
    {
      return request_read (writer_socket, finfo->fh - REMOTE_FD_OFFSET, buf, size, offset);
    }
  else
    {
      r = pread (finfo->fh, buf, size, offset);
      if (r == -1)
        return -errno;
      return r;
    }
}

static int
callback_write (const char *path, const char *buf, size_t size, off_t offset,
                struct fuse_file_info *finfo)
{
  int r;

  if (finfo->fh >= REMOTE_FD_OFFSET)
    {
      return request_write (writer_socket, finfo->fh - REMOTE_FD_OFFSET, buf, size, offset);
    }
  else
    {
      r = pwrite (finfo->fh, buf, size, offset);
      if (r == -1)
        return -errno;
      return r;
    }
}

static int
callback_statfs (const char *path, struct statvfs *st_buf)
{
  if (fstatvfs (basefd, st_buf) == -1)
    return -errno;
  return 0;
}

static int
callback_release (const char *path, struct fuse_file_info *finfo)
{
  if (finfo->fh >= REMOTE_FD_OFFSET)
    {
      return request_close (writer_socket, finfo->fh - REMOTE_FD_OFFSET);
    }
  else
    {
      (void) close (finfo->fh);
      return 0;
    }
}

static int
callback_fsync (const char *path, int crap, struct fuse_file_info *finfo)
{
  if (finfo->fh >= REMOTE_FD_OFFSET)
    {
      return request_fsync (writer_socket, finfo->fh - REMOTE_FD_OFFSET);
    }
  else
    {
      if (fsync (finfo->fh) == -1)
        return -errno;
      return 0;
    }
}

static int
callback_access (const char *path, int mode)
{
  path = ENSURE_RELPATH (path);

  /* Apparently at least GNU coreutils rm calls `faccessat(W_OK)`
   * before trying to do an unlink.  So...we'll just lie about
   * writable access here.
   */
  if (faccessat (basefd, path, mode, AT_SYMLINK_NOFOLLOW) == -1)
    return -errno;
  return 0;
}

static int
callback_setxattr (const char *path, const char *name, const char *value,
                   size_t size, int flags)
{
  return -ENOTSUP;
}

static int
callback_getxattr (const char *path, const char *name, char *value,
                   size_t size)
{
  return -ENOTSUP;
}

/*
 * List the supported extended attributes.
 */
static int
callback_listxattr (const char *path, char *list, size_t size)
{
  return -ENOTSUP;

}

/*
 * Remove an extended attribute.
 */
static int
callback_removexattr (const char *path, const char *name)
{
  return -ENOTSUP;

}

struct fuse_operations callback_oper = {
  .getattr = callback_getattr,
  .readlink = callback_readlink,
  .readdir = callback_readdir,
  .mknod = callback_mknod,
  .mkdir = callback_mkdir,
  .symlink = callback_symlink,
  .unlink = callback_unlink,
  .rmdir = callback_rmdir,
  .rename = callback_rename,
  .link = callback_link,
  .chmod = callback_chmod,
  .chown = callback_chown,
  .truncate = callback_truncate,
  .utimens = callback_utimens,
  .create = callback_create,
  .open = callback_open,
  .read = callback_read,
  .write = callback_write,
  .statfs = callback_statfs,
  .release = callback_release,
  .fsync = callback_fsync,
  .access = callback_access,

  /* Extended attributes support for userland interaction */
  .setxattr = callback_setxattr,
  .getxattr = callback_getxattr,
  .listxattr = callback_listxattr,
  .removexattr = callback_removexattr
};

enum {
  KEY_HELP,
};

static void
usage (const char *progname)
{
  fprintf (stdout,
           "usage: %s basepath mountpoint [options]\n"
           "\n"
           "   Makes basepath visible at mountpoint such that files are writeable only through\n"
           "   fd passed in the --socket argument.\n"
           "\n"
           "general options:\n"
           "   -o opt,[opt...]     mount options\n"
           "   -h  --help          print help\n"
           "   --socket=fd         Pass in the socket fd\n"
           "   --backend           Run the backend instead of fuse\n"
           "   --exit-with-fd=fd   With --backend, exit when the given file descriptor is closed\n"
           "\n", progname);
}

static int
revokefs_opt_proc (void *data,
                   const char *arg,
                   int key,
                   struct fuse_args *outargs)
{
  (void) data;

  switch (key)
    {
    case FUSE_OPT_KEY_NONOPT:
      if (base_path == NULL)
        {
          base_path = g_strdup (arg);
          return 0;
        }
      return 1;
    case FUSE_OPT_KEY_OPT:
      return 1;
    case KEY_HELP:
      usage (outargs->argv[0]);
      exit (EXIT_SUCCESS);
    default:
      fprintf (stderr, "see `%s -h' for usage\n", outargs->argv[0]);
      exit (EXIT_FAILURE);
    }
  return 1;
}

struct revokefs_config {
  int socket_fd;
  int exit_with_fd;
  int backend;
};

#define REVOKEFS_OPT(t, p, v) { t, offsetof(struct revokefs_config, p), v }

static struct fuse_opt revokefs_opts[] = {
  REVOKEFS_OPT ("--socket=%i", socket_fd, -1),
  REVOKEFS_OPT ("--exit-with-fd=%i", exit_with_fd, -1),
  REVOKEFS_OPT ("--backend", backend, 1),

  FUSE_OPT_KEY ("-h", KEY_HELP),
  FUSE_OPT_KEY ("--help", KEY_HELP),
  FUSE_OPT_END
};

int
main (int argc, char *argv[])
{
  struct fuse_args args = FUSE_ARGS_INIT (argc, argv);
  int res;
  struct revokefs_config conf = { -1, -1 };
  int status = 0;

  res = fuse_opt_parse (&args, &conf, revokefs_opts, revokefs_opt_proc);
  if (res != 0)
    {
      fprintf (stderr, "Invalid arguments\n");
      fprintf (stderr, "see `%s -h' for usage\n", argv[0]);
      status = EXIT_FAILURE;
      goto out;
    }

  if (base_path == NULL)
    {
      fprintf (stderr, "Missing basepath\n");
      fprintf (stderr, "see `%s -h' for usage\n", argv[0]);
      status = EXIT_FAILURE;
      goto out;
    }

  basefd = glnx_opendirat_with_errno (AT_FDCWD, base_path, TRUE);
  if (basefd == -1)
    {
      perror ("opening basepath: ");
      status = EXIT_FAILURE;
      goto out;
    }

  if (conf.backend)
    {
      if (conf.socket_fd == -1)
        {
          fprintf (stderr, "No --socket passed, required for --backend\n");
          status = EXIT_FAILURE;
          goto out;
        }

      do_writer (basefd, conf.socket_fd, conf.exit_with_fd);
      goto out;
    }

  if (conf.socket_fd != -1)
    {
      writer_socket = conf.socket_fd;
    }
  else
    {
      int sockets[2];
      pid_t pid;

      if (socketpair(AF_UNIX, SOCK_SEQPACKET, 0, sockets))
        {
          perror ("Failed to create socket pair");
          status = EXIT_FAILURE;
          goto out;
        }

      pid = fork ();
      if (pid == -1)
        {
          perror ("Failed to fork writer");
          status = EXIT_FAILURE;
          goto out;
        }

      if (pid == 0)
        {
          /* writer process */
          close (sockets[0]);
          do_writer (basefd, sockets[1], -1);
          goto out;
        }

      /* Main process */
      close (sockets[1]);
      writer_socket = sockets[0];
    }

  fuse_main (args.argc, args.argv, &callback_oper, NULL);

out:
  fuse_opt_free_args (&args);
  return status;
}

===== ./app/flatpak-builtins-remote-modify.c =====
/* vi:set et sw=2 sts=2 cin cino=t0,f0,(0,{s,>2s,n-s,^-s,e-s:
 * Copyright © 2014 Red Hat, Inc
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Alexander Larsson <alexl@redhat.com>
 */

#include "config.h"

#include <locale.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

#include <glib/gi18n.h>

#include "libglnx.h"

#include "flatpak-builtins.h"
#include "flatpak-builtins-utils.h"
#include "flatpak-utils-private.h"

static gboolean opt_no_gpg_verify;
static gboolean opt_do_gpg_verify;
static gboolean opt_do_enumerate;
static gboolean opt_no_enumerate;
static gboolean opt_do_deps;
static gboolean opt_no_deps;
static gboolean opt_enable;
static gboolean opt_update_metadata;
static gboolean opt_disable;
static gboolean opt_no_filter;
static gboolean opt_do_follow_redirect;
static gboolean opt_no_follow_redirect;
static int opt_prio = -1;
static char *opt_filter;
static char *opt_title;
static char *opt_comment;
static char *opt_description;
static char *opt_homepage;
static char *opt_icon;
static char *opt_subset;
static char *opt_default_branch;
static char *opt_url;
static char *opt_collection_id = NULL;
static char *opt_authenticator_name = NULL;
static char **opt_authenticator_options = NULL;
static gboolean opt_authenticator_install = -1;
static char **opt_gpg_import;
static char *opt_signature_lookaside = NULL;


static GOptionEntry modify_options[] = {
  { "gpg-verify", 0, 0, G_OPTION_ARG_NONE, &opt_do_gpg_verify, N_("Enable GPG verification"), NULL },
  { "enumerate", 0, 0, G_OPTION_ARG_NONE, &opt_do_enumerate, N_("Mark the remote as enumerate"), NULL },
  { "use-for-deps", 0, 0, G_OPTION_ARG_NONE, &opt_do_deps, N_("Mark the remote as used for dependencies"), NULL },
  { "url", 0, 0, G_OPTION_ARG_STRING, &opt_url, N_("Set a new URL"), N_("URL") },
  { "subset", 0, 0, G_OPTION_ARG_STRING, &opt_subset, N_("Set a new subset to use"), N_("SUBSET") },
  { "enable", 0, 0, G_OPTION_ARG_NONE, &opt_enable, N_("Enable the remote"), NULL },
  { "update-metadata", 0, 0, G_OPTION_ARG_NONE, &opt_update_metadata, N_("Update extra metadata from the summary file"), NULL },
  { NULL }
};

static GOptionEntry common_options[] = {
  { "no-gpg-verify", 0, 0, G_OPTION_ARG_NONE, &opt_no_gpg_verify, N_("Disable GPG verification"), NULL },
  { "no-enumerate", 0, 0, G_OPTION_ARG_NONE, &opt_no_enumerate, N_("Mark the remote as don't enumerate"), NULL },
  { "no-use-for-deps", 0, 0, G_OPTION_ARG_NONE, &opt_no_deps, N_("Mark the remote as don't use for deps"), NULL },
  { "prio", 0, 0, G_OPTION_ARG_INT, &opt_prio, N_("Set priority (default 1, higher is more prioritized)"), N_("PRIORITY") },
  { "title", 0, 0, G_OPTION_ARG_STRING, &opt_title, N_("A nice name to use for this remote"), N_("TITLE") },
  { "comment", 0, 0, G_OPTION_ARG_STRING, &opt_comment, N_("A one-line comment for this remote"), N_("COMMENT") },
  { "description", 0, 0, G_OPTION_ARG_STRING, &opt_description, N_("A full-paragraph description for this remote"), N_("DESCRIPTION") },
  { "homepage", 0, 0, G_OPTION_ARG_STRING, &opt_homepage, N_("URL for a website for this remote"), N_("URL") },
  { "icon", 0, 0, G_OPTION_ARG_STRING, &opt_icon, N_("URL for an icon for this remote"), N_("URL") },
  { "default-branch", 0, 0, G_OPTION_ARG_STRING, &opt_default_branch, N_("Default branch to use for this remote"), N_("BRANCH") },
  { "collection-id", 0, 0, G_OPTION_ARG_STRING, &opt_collection_id, N_("Collection ID"), N_("COLLECTION-ID") },
  { "gpg-import", 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &opt_gpg_import, N_("Import GPG key from FILE (- for stdin)"), N_("FILE") },
  { "signature-lookaside", 0, 0, G_OPTION_ARG_STRING, &opt_signature_lookaside, N_("Load signatures from URL"), N_("URL") },
  { "no-filter", 0, 0, G_OPTION_ARG_NONE, &opt_no_filter, N_("Disable local filter"), NULL },
  { "filter", 0, 0, G_OPTION_ARG_FILENAME, &opt_filter, N_("Set path to local filter FILE"), N_("FILE") },
  { "disable", 0, 0, G_OPTION_ARG_NONE, &opt_disable, N_("Disable the remote"), NULL },
  { "authenticator-name", 0, 0, G_OPTION_ARG_STRING, &opt_authenticator_name, N_("Name of authenticator"), N_("NAME") },
  { "authenticator-option", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_authenticator_options, N_("Authenticator options"), N_("KEY=VALUE") },
  { "authenticator-install", 0, 0, G_OPTION_ARG_NONE, &opt_authenticator_install, N_("Autoinstall authenticator"), NULL },
  { "no-authenticator-install", 0, G_OPTION_FLAG_REVERSE, G_OPTION_ARG_NONE, &opt_authenticator_install, N_("Don't autoinstall authenticator"), NULL },
  { "follow-redirect", 0, G_OPTION_FLAG_REVERSE, G_OPTION_ARG_NONE, &opt_do_follow_redirect, N_("Follow the redirect set in the summary file"), NULL },
  { "no-follow-redirect", 0, G_OPTION_FLAG_REVERSE, G_OPTION_ARG_NONE, &opt_no_follow_redirect, N_("Don't follow the redirect set in the summary file"), NULL },
  { NULL }
};

static GKeyFile *
get_config_from_opts (FlatpakDir *dir, const char *remote_name, gboolean *changed)
{
  OstreeRepo *repo;
  GKeyFile *config;
  g_autofree char *group = g_strdup_printf ("remote \"%s\"", remote_name);

  repo = flatpak_dir_get_repo (dir);
  if (repo == NULL)
    config = g_key_file_new ();
  else
    config = ostree_repo_copy_config (repo);

  if (opt_no_gpg_verify)
    {
      g_key_file_set_boolean (config, group, "gpg-verify", FALSE);
      g_key_file_set_boolean (config, group, "gpg-verify-summary", FALSE);
      *changed = TRUE;
    }

  if (opt_do_gpg_verify)
    {
      g_key_file_set_boolean (config, group, "gpg-verify", TRUE);
      g_key_file_set_boolean (config, group, "gpg-verify-summary", TRUE);
      *changed = TRUE;
    }

  if (opt_url)
    {
      if (g_str_has_prefix (opt_url, "metalink="))
        g_key_file_set_string (config, group, "metalink", opt_url + strlen ("metalink="));
      else
        {
          g_key_file_set_string (config, group, "url", opt_url);
          g_key_file_set_boolean (config, group, "url-is-set", TRUE);
        }
      *changed = TRUE;
    }

  if (opt_collection_id)
    {
      g_key_file_set_string (config, group, "collection-id", opt_collection_id);
      *changed = TRUE;
    }

  if (opt_subset)
    {
      g_key_file_set_string (config, group, "xa.subset", opt_subset);
      g_key_file_set_boolean (config, group, "xa.subset-is-set", TRUE);
      *changed = TRUE;
    }

  if (opt_title)
    {
      g_key_file_set_string (config, group, "xa.title", opt_title);
      g_key_file_set_boolean (config, group, "xa.title-is-set", TRUE);
      *changed = TRUE;
    }

  if (opt_comment)
    {
      g_key_file_set_string (config, group, "xa.comment", opt_comment);
      g_key_file_set_boolean (config, group, "xa.comment-is-set", TRUE);
      *changed = TRUE;
    }

  if (opt_description)
    {
      g_key_file_set_string (config, group, "xa.description", opt_description);
      g_key_file_set_boolean (config, group, "xa.description-is-set", TRUE);
      *changed = TRUE;
    }

  if (opt_homepage)
    {
      g_key_file_set_string (config, group, "xa.homepage", opt_homepage);
      g_key_file_set_boolean (config, group, "xa.homepage-is-set", TRUE);
      *changed = TRUE;
    }

  if (opt_icon)
    {
      g_key_file_set_string (config, group, "xa.icon", opt_icon);
      g_key_file_set_boolean (config, group, "xa.icon-is-set", TRUE);
      *changed = TRUE;
    }

  if (opt_default_branch)
    {
      g_key_file_set_string (config, group, "xa.default-branch", opt_default_branch);
      g_key_file_set_boolean (config, group, "xa.default-branch-is-set", TRUE);
      *changed = TRUE;
    }

  if (opt_filter || opt_no_filter)
    {
      g_key_file_set_string (config, group, "xa.filter", opt_no_filter ? "" : opt_filter);
      *changed = TRUE;
    }

  if (opt_no_enumerate)
    {
      g_key_file_set_boolean (config, group, "xa.noenumerate", TRUE);
      *changed = TRUE;
    }

  if (opt_do_enumerate)
    {
      g_key_file_set_boolean (config, group, "xa.noenumerate", FALSE);
      *changed = TRUE;
    }

  if (opt_no_deps)
    {
      g_key_file_set_boolean (config, group, "xa.nodeps", TRUE);
      *changed = TRUE;
    }

  if (opt_do_deps)
    {
      g_key_file_set_boolean (config, group, "xa.nodeps", FALSE);
      *changed = TRUE;
    }

  if (opt_disable)
    {
      g_key_file_set_boolean (config, group, "xa.disable", TRUE);
      *changed = TRUE;
    }
  else if (opt_enable)
    {
      g_key_file_set_boolean (config, group, "xa.disable", FALSE);
      *changed = TRUE;
    }

  if (opt_prio != -1)
    {
      g_autofree char *prio_as_string = g_strdup_printf ("%d", opt_prio);
      g_key_file_set_string (config, group, "xa.prio", prio_as_string);
      *changed = TRUE;
    }

  if (opt_signature_lookaside)
    {
      g_key_file_set_string (config, group, "xa.signature-lookaside", opt_signature_lookaside);
      *changed = TRUE;
    }

  if (opt_authenticator_name)
    {
      g_key_file_set_string (config, group, "xa.authenticator-name", opt_authenticator_name);
      g_key_file_set_boolean (config, group, "xa.authenticator-name-is-set", TRUE);
      *changed = TRUE;
    }

  if (opt_authenticator_install != -1)
    {
      g_key_file_set_boolean (config, group, "xa.authenticator-install", opt_authenticator_install);
      g_key_file_set_boolean (config, group, "xa.authenticator-install-is-set", TRUE);
      *changed = TRUE;
    }

  if (opt_authenticator_options)
    {
      for (int i = 0; opt_authenticator_options[i] != NULL; i++)
        {
          g_auto(GStrv) split = g_strsplit (opt_authenticator_options[i], "=", 2);
          g_autofree char *key = g_strdup_printf ("xa.authenticator-options.%s", split[0]);

          if (split[0] == NULL || split[1] == NULL || *split[1] == 0)
            g_key_file_remove_key (config, group, key, NULL);
          else
            g_key_file_set_string (config, group, key, split[1]);
        }
      *changed = TRUE;
    }

  if (opt_do_follow_redirect)
    {
      g_key_file_set_boolean (config, group, "url-is-set", FALSE);
      *changed = TRUE;
    }

  if (opt_no_follow_redirect)
    {
      g_key_file_set_boolean (config, group, "url-is-set", TRUE);
      *changed = TRUE;
    }

  return config;
}

gboolean
flatpak_builtin_remote_modify (int argc, char **argv, GCancellable *cancellable, GError **error)
{
  g_autoptr(GOptionContext) context = NULL;
  g_autoptr(GPtrArray) dirs = NULL;
  g_autoptr(FlatpakDir) preferred_dir = NULL;
  g_autoptr(GKeyFile) config = NULL;
  g_autoptr(GBytes) gpg_data = NULL;
  const char *remote_name;
  gboolean changed = FALSE;

  context = g_option_context_new (_("NAME - Modify a remote repository"));
  g_option_context_set_translation_domain (context, GETTEXT_PACKAGE);

  g_option_context_add_main_entries (context, common_options, NULL);

  if (!flatpak_option_context_parse (context, modify_options, &argc, &argv,
                                     FLATPAK_BUILTIN_FLAG_STANDARD_DIRS, &dirs, cancellable, error))
    return FALSE;

  if (argc < 2)
    return usage_error (context, _("Remote NAME must be specified"), error);

  remote_name = argv[1];

  if (!flatpak_resolve_duplicate_remotes (dirs, remote_name, FALSE, &preferred_dir, cancellable, error))
    return FALSE;

  if (opt_update_metadata)
    {
      g_autoptr(GError) local_error = NULL;

      g_print (_("Updating extra metadata from remote summary for %s\n"), remote_name);
      if (!flatpak_dir_update_remote_configuration (preferred_dir, remote_name, NULL, NULL, cancellable, &local_error))
        {
          g_printerr (_("Error updating extra metadata for '%s': %s\n"), remote_name, local_error->message);
          return flatpak_fail (error, _("Could not update extra metadata for %s"), remote_name);
        }

      /* Reload changed configuration */
      if (!flatpak_dir_recreate_repo (preferred_dir, cancellable, error))
        return FALSE;
    }

  if (opt_authenticator_name && !g_dbus_is_name (opt_authenticator_name))
    return flatpak_fail (error, _("Invalid authenticator name %s"), opt_authenticator_name);

  config = get_config_from_opts (preferred_dir, remote_name, &changed);

  if (opt_gpg_import != NULL)
    {
      gpg_data = flatpak_load_gpg_keys (opt_gpg_import, cancellable, error);
      if (gpg_data == NULL)
        return FALSE;
      changed = TRUE;
    }

  if (!changed)
    return TRUE;

  return flatpak_dir_modify_remote (preferred_dir, remote_name, config, gpg_data, cancellable, error);
}

gboolean
flatpak_complete_remote_modify (FlatpakCompletion *completion)
{
  g_autoptr(GOptionContext) context = NULL;
  g_autoptr(GPtrArray) dirs = NULL;
  int i;

  context = g_option_context_new ("");
  g_option_context_add_main_entries (context, common_options, NULL);
  if (!flatpak_option_context_parse (context, modify_options, &completion->argc, &completion->argv,
                                     FLATPAK_BUILTIN_FLAG_STANDARD_DIRS, &dirs, NULL, NULL))
    return FALSE;

  switch (completion->argc)
    {
    case 0:
    case 1: /* REMOTE */
      flatpak_complete_options (completion, global_entries);
      flatpak_complete_options (completion, common_options);
      flatpak_complete_options (completion, modify_options);
      flatpak_complete_options (completion, user_entries);

      for (i = 0; i < dirs->len; i++)
        {
          FlatpakDir *dir = g_ptr_array_index (dirs, i);
          int j;
          g_auto(GStrv) remotes = flatpak_dir_list_remotes (dir, NULL, NULL);
          if (remotes == NULL)
            return FALSE;
          for (j = 0; remotes[j] != NULL; j++)
            flatpak_complete_word (completion, "%s ", remotes[j]);
        }

      break;
    }

  return TRUE;
}

===== ./app/flatpak-builtins-build-init.c =====
/* vi:set et sw=2 sts=2 cin cino=t0,f0,(0,{s,>2s,n-s,^-s,e-s:
 * Copyright © 2014 Red Hat, Inc
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Alexander Larsson <alexl@redhat.com>
 */

#include "config.h"

#include <locale.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

#include <glib/gi18n.h>

#include "libglnx.h"

#include "flatpak-builtins.h"
#include "flatpak-builtins-utils.h"
#include "flatpak-utils-private.h"
#include "flatpak-ref.h"
#include "flatpak-run-private.h"

static char *opt_arch;
static char *opt_var;
static char *opt_type;
static char *opt_sdk_dir;
static char **opt_sdk_extensions;
static char **opt_extensions;
static char **opt_tags;
static char *opt_extension_tag;
static char *opt_base;
static char *opt_base_version;
static char **opt_base_extensions;
static gboolean opt_writable_sdk;
static gboolean opt_update;

static GOptionEntry options[] = {
  { "arch", 0, 0, G_OPTION_ARG_STRING, &opt_arch, N_("Arch to use"), N_("ARCH") },
  { "var", 'v', 0, G_OPTION_ARG_STRING, &opt_var, N_("Initialize var from named runtime"), N_("RUNTIME") },
  { "base", 0, 0, G_OPTION_ARG_STRING, &opt_base, N_("Initialize apps from named app"), N_("APP") },
  { "base-version", 0, 0, G_OPTION_ARG_STRING, &opt_base_version, N_("Specify version for --base"), N_("VERSION") },
  { "base-extension", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_base_extensions, N_("Include this base extension"), N_("EXTENSION") },
  { "extension-tag", 0, 0, G_OPTION_ARG_STRING, &opt_extension_tag, N_("Extension tag to use if building extension"), N_("EXTENSION_TAG") },
  { "writable-sdk", 'w', 0, G_OPTION_ARG_NONE, &opt_writable_sdk, N_("Initialize /usr with a writable copy of the sdk"), NULL },
  { "type", 0, 0, G_OPTION_ARG_STRING, &opt_type, N_("Specify the build type (app, runtime, extension)"), N_("TYPE") },
  { "tag", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_tags, N_("Add a tag"), N_("TAG") },
  { "sdk-extension", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_sdk_extensions, N_("Include this sdk extension in /usr"), N_("EXTENSION") },
  { "extension", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_extensions, N_("Add extension point info"),  N_("NAME=VARIABLE[=VALUE]") },
  { "sdk-dir", 0, 0, G_OPTION_ARG_STRING, &opt_sdk_dir, N_("Where to store sdk (defaults to 'usr')"), N_("DIR") },
  { "update", 0, 0, G_OPTION_ARG_NONE, &opt_update, N_("Re-initialize the sdk/var"), NULL },
  { NULL }
};

#define GIT_IGNORE_FILE \
  "# This file is autogenerated by flatpak build-init\n" \
  "*\n"

static gboolean
ensure_extensions (FlatpakDeploy *src_deploy, const char *default_arch, const char *default_branch,
                   char *src_extensions[], GFile *top_dir, GCancellable *cancellable, GError **error)
{
  g_autoptr(GKeyFile) metakey = flatpak_deploy_get_metadata (src_deploy);
  GList *extensions = NULL, *l;
  int i;

  /* We leak this on failure, as we have no autoptr for deep lists.. */
  extensions = flatpak_list_extensions (metakey, default_arch, default_branch);

  for (i = 0; src_extensions[i] != NULL; i++)
    {
      const char *requested_extension = src_extensions[i];
      g_autofree char *requested_extension_name = NULL;
      gboolean found = FALSE;

      /* Remove any '@' from the name */
      flatpak_parse_extension_with_tag (requested_extension,
                                        &requested_extension_name,
                                        NULL);

      for (l = extensions; l != NULL; l = l->next)
        {
          FlatpakExtension *ext = l->data;

          if (strcmp (ext->installed_id, requested_extension_name) == 0 ||
              strcmp (ext->id, requested_extension_name) == 0)
            {
              if (!ext->is_unmaintained)
                {
                  g_autoptr(FlatpakDir) src_dir = NULL;
                  g_autoptr(GFile) deploy = NULL;
                  g_autoptr(GBytes) deploy_data = NULL;
                  g_autofree const char **subpaths = NULL;

                  deploy = flatpak_find_deploy_dir_for_ref (ext->ref, &src_dir, cancellable, error);
                  if (deploy == NULL)
                    return FALSE;
                  deploy_data = flatpak_dir_get_deploy_data (src_dir, ext->ref, FLATPAK_DEPLOY_VERSION_ANY, cancellable, error);
                  if (deploy_data == NULL)
                    return FALSE;

                  subpaths = flatpak_deploy_data_get_subpaths (deploy_data);
                  if (subpaths[0] != NULL)
                    return flatpak_fail (error, _("Requested extension %s/%s/%s is only partially installed"), ext->installed_id, default_arch, default_branch);
                }

              if (top_dir)
                {
                  g_autoptr(GFile) target = g_file_resolve_relative_path (top_dir, ext->directory);
                  g_autoptr(GFile) target_parent = g_file_get_parent (target);
                  g_autoptr(GFile) ext_deploy_files = g_file_new_for_path (ext->files_path);

                  if (!flatpak_mkdir_p (target_parent, cancellable, error))
                    return FALSE;

                  /* An extension overrides whatever is there before, so we clean up first */
                  if (!flatpak_rm_rf (target, cancellable, error))
                    return FALSE;

                  if (!flatpak_cp_a (ext_deploy_files, target,
                                     FLATPAK_CP_FLAGS_NO_CHOWN,
                                     cancellable, error))
                    return FALSE;
                }

              found = TRUE;
            }
        }

      if (!found)
        {
          g_list_free_full (extensions, (GDestroyNotify) flatpak_extension_free);
          return flatpak_fail (error, _("Requested extension %s/%s/%s not installed"), requested_extension_name, default_arch, default_branch);
        }
    }

  g_list_free_full (extensions, (GDestroyNotify) flatpak_extension_free);

  return TRUE;
}

static char *
maybe_format_extension_tag (const char *extension_tag)
{
  if (extension_tag != NULL)
    {
      return g_strdup_printf ("tag=%s\n", extension_tag);
    }

  return g_strdup ("");
}

gboolean
flatpak_builtin_build_init (int argc, char **argv, GCancellable *cancellable, GError **error)
{
  g_autoptr(GOptionContext) context = NULL;
  g_autoptr(GFile) var_deploy_files = NULL;
  g_autoptr(GFile) base = NULL;
  g_autoptr(GFile) files_dir = NULL;
  g_autoptr(GFile) usr_dir = NULL;
  g_autoptr(GFile) var_dir = NULL;
  g_autoptr(GFile) var_tmp_dir = NULL;
  g_autoptr(GFile) var_run_dir = NULL;
  g_autoptr(GFile) metadata_file = NULL;
  g_autoptr(GFile) gitignore_file = NULL;
  g_autoptr(GString) metadata_contents = NULL;
  g_autoptr(GError) my_error = NULL;
  g_autoptr(FlatpakDeploy) runtime_deploy = NULL;
  g_autoptr(FlatpakDeploy) sdk_deploy = NULL;
  const char *app_id;
  const char *directory;
  const char *sdk_pref;
  const char *runtime_pref;
  const char *default_branch = NULL;
  g_autofree char *sdk_branch = NULL;
  g_autofree char *sdk_arch = NULL;
  g_autofree char *base_ref = NULL;
  g_autoptr(FlatpakDecomposed) runtime_ref = NULL;
  g_autofree char *extension_runtime_pref = NULL;
  g_autoptr(FlatpakDecomposed) var_ref = NULL;
  g_autoptr(FlatpakDecomposed) sdk_ref = NULL;
  FlatpakKinds kinds;
  int i;
  g_autoptr(FlatpakDir) sdk_dir = NULL;
  g_autoptr(FlatpakDir) runtime_dir = NULL;
  gboolean is_app = FALSE;
  gboolean is_extension = FALSE;
  gboolean is_runtime = FALSE;
  g_autoptr(GKeyFile) keyfile = g_key_file_new ();
  g_autofree char *keyfile_data = NULL;
  gsize keyfile_data_len;

  context = g_option_context_new (_("DIRECTORY APPNAME SDK RUNTIME [BRANCH] - Initialize a directory for building"));
  g_option_context_set_translation_domain (context, GETTEXT_PACKAGE);

  if (!flatpak_option_context_parse (context, options, &argc, &argv, FLATPAK_BUILTIN_FLAG_NO_DIR, NULL, cancellable, error))
    return FALSE;

  if (argc < 5)
    return usage_error (context, _("RUNTIME must be specified"), error);

  if (argc > 6)
    return usage_error (context, _("Too many arguments"), error);

  directory = argv[1];
  app_id = argv[2];
  sdk_pref = argv[3];
  runtime_pref = argv[4];
  if (argc >= 6)
    default_branch = argv[5];

  if (opt_type != NULL)
    {
      if (strcmp (opt_type, "app") == 0)
        is_app = TRUE;
      else if (strcmp (opt_type, "extension") == 0)
        is_extension = TRUE;
      else if (strcmp (opt_type, "runtime") == 0)
        is_runtime = TRUE;
      else
        return flatpak_fail (error, _("'%s' is not a valid build type name, use app, runtime or extension"), opt_type);
    }
  else
    is_app = TRUE;

  if (!flatpak_is_valid_name (app_id, -1, &my_error))
    return flatpak_fail (error, _("'%s' is not a valid application name: %s"), app_id, my_error->message);


  kinds = FLATPAK_KINDS_RUNTIME;
  sdk_dir = flatpak_find_installed_pref (sdk_pref, kinds, opt_arch, default_branch, TRUE, FALSE, FALSE, NULL,
                                         &sdk_ref, cancellable, error);
  if (sdk_dir == NULL)
    return FALSE;

  kinds = FLATPAK_KINDS_RUNTIME;
  if (is_extension)
    kinds |= FLATPAK_KINDS_APP;

  runtime_dir = flatpak_find_installed_pref (runtime_pref, kinds, opt_arch, default_branch, TRUE, FALSE, FALSE, NULL,
                                             &runtime_ref, cancellable, error);
  if (runtime_dir == NULL)
    return FALSE;

  if (is_extension)
    {
      /* The "runtime" can be an app in case we're building an extension */
      if (flatpak_decomposed_is_app (runtime_ref))
        {
          g_autoptr(GKeyFile) runtime_metadata = NULL;

          runtime_deploy = flatpak_dir_load_deployed (runtime_dir, runtime_ref, NULL, cancellable, error);
          if (runtime_deploy == NULL)
            return FALSE;

          runtime_metadata = flatpak_deploy_get_metadata (runtime_deploy);
          extension_runtime_pref = g_key_file_get_string (runtime_metadata, FLATPAK_METADATA_GROUP_APPLICATION,
                                                          FLATPAK_METADATA_KEY_RUNTIME, NULL);
          g_assert (extension_runtime_pref);
        }
      else
        extension_runtime_pref = flatpak_decomposed_dup_pref (runtime_ref);
    }

  base = g_file_new_for_commandline_arg (directory);
  if (flatpak_file_get_path_cached (base) == NULL)
    return flatpak_fail (error, _("'%s' is not a valid filename"), directory);

  if (!flatpak_mkdir_p (base, cancellable, error))
    return FALSE;

  files_dir = g_file_get_child (base, "files");
  var_dir = g_file_get_child (base, "var");
  var_tmp_dir = g_file_get_child (var_dir, "tmp");
  var_run_dir = g_file_get_child (var_dir, "run");
  metadata_file = g_file_get_child (base, "metadata");
  gitignore_file = g_file_get_child (base, ".gitignore");

  if (!opt_update &&
      g_file_query_exists (files_dir, cancellable))
    return flatpak_fail (error, _("Build directory %s already initialized"), directory);

  sdk_deploy = flatpak_dir_load_deployed (sdk_dir, sdk_ref, NULL, cancellable, error);
  if (sdk_deploy == NULL)
    return FALSE;

  if (opt_writable_sdk || is_runtime)
    {
      g_autoptr(GFile) sdk_deploy_files = NULL;

      if (opt_sdk_dir)
        usr_dir = g_file_get_child (base, opt_sdk_dir);
      else
        usr_dir = g_file_get_child (base, "usr");

      if (!flatpak_rm_rf (usr_dir, NULL, &my_error))
        {
          if (!g_error_matches (my_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
            {
              g_propagate_error (error, g_steal_pointer (&my_error));
              return FALSE;
            }

          g_clear_error (&my_error);
        }

      sdk_deploy_files = flatpak_deploy_get_files (sdk_deploy);
      if (!flatpak_cp_a (sdk_deploy_files, usr_dir, FLATPAK_CP_FLAGS_NO_CHOWN, cancellable, error))
        return FALSE;
    }

  sdk_branch = flatpak_decomposed_dup_branch (sdk_ref);
  sdk_arch = flatpak_decomposed_dup_arch (sdk_ref);

  if (opt_sdk_extensions &&
      !ensure_extensions (sdk_deploy, sdk_arch, sdk_branch,
                          opt_sdk_extensions, usr_dir, cancellable, error))
    return FALSE;

  if (opt_var)
    {
      var_ref = flatpak_decomposed_new_from_parts (FLATPAK_KINDS_RUNTIME, opt_var, opt_arch, default_branch, error);
      if (var_ref == NULL)
        return FALSE;

      var_deploy_files = flatpak_find_files_dir_for_ref (var_ref, cancellable, error);
      if (var_deploy_files == NULL)
        return FALSE;
    }

  if (opt_update)
    return TRUE;

  if (!g_file_make_directory (files_dir, cancellable, error))
    return FALSE;

  if (opt_base)
    {
      const char *base_branch;
      g_autoptr(GFile) base_deploy_files = NULL;
      g_autoptr(FlatpakDeploy) base_deploy = NULL;

      base_branch = opt_base_version ? opt_base_version : "master";
      base_ref = flatpak_build_app_ref (opt_base, base_branch, opt_arch);
      base_deploy = flatpak_find_deploy_for_ref (base_ref, NULL, NULL, cancellable, error);
      if (base_deploy == NULL)
        return FALSE;

      base_deploy_files = flatpak_deploy_get_files (base_deploy);
      if (!flatpak_cp_a (base_deploy_files, files_dir,
                         FLATPAK_CP_FLAGS_MERGE | FLATPAK_CP_FLAGS_NO_CHOWN,
                         cancellable, error))
        return FALSE;


      if (opt_base_extensions &&
          !ensure_extensions (base_deploy, opt_arch, base_branch,
                              opt_base_extensions, files_dir, cancellable, error))
        return FALSE;
    }

  if (var_deploy_files)
    {
      if (!flatpak_cp_a (var_deploy_files, var_dir, FLATPAK_CP_FLAGS_NONE, cancellable, error))
        return FALSE;
    }
  else
    {
      if (!g_file_make_directory (var_dir, cancellable, error))
        return FALSE;
    }

  if (!flatpak_mkdir_p (var_tmp_dir, cancellable, error))
    return FALSE;

  if (!g_file_query_exists (var_run_dir, cancellable) &&
      !g_file_make_symbolic_link (var_run_dir, "/run", cancellable, error))
    return FALSE;


  metadata_contents = g_string_new ("");
  if (is_app)
    g_string_append (metadata_contents, "[Application]\n");
  else
    g_string_append (metadata_contents, "[Runtime]\n");

  g_string_append_printf (metadata_contents,
                          "name=%s\n",
                          app_id);

  /* The "runtime" can be an app in case we're building an extension */
  if (flatpak_decomposed_is_runtime (runtime_ref))
    g_string_append_printf (metadata_contents,
                            "runtime=%s\n",
                            flatpak_decomposed_get_pref (runtime_ref));

  if (flatpak_decomposed_is_runtime (sdk_ref))
    g_string_append_printf (metadata_contents,
                            "sdk=%s\n",
                            flatpak_decomposed_get_pref (sdk_ref));

  if (base_ref)
    g_string_append_printf (metadata_contents,
                            "base=%s\n", base_ref);


  if (opt_tags != NULL)
    {
      g_string_append (metadata_contents, "tags=");
      for (i = 0; opt_tags[i] != NULL; i++)
        {
          g_string_append (metadata_contents, opt_tags[i]);
          g_string_append_c (metadata_contents, ';');
        }
      g_string_append_c (metadata_contents, '\n');
    }

  if (is_extension)
    {
      g_autofree char *optional_extension_tag = maybe_format_extension_tag (opt_extension_tag);
      g_string_append_printf (metadata_contents,
                              "\n"
                              "[ExtensionOf]\n"
                              "ref=%s\n"
                              "runtime=%s\n"
                              "%s\n",
                              flatpak_decomposed_get_ref (runtime_ref),
                              extension_runtime_pref,
                              optional_extension_tag);
    }

  /* Do the rest of the work as a keyfile, as we need things like full escaping, etc.
   * We should probably do everything this way actually...   */
  if (!g_key_file_load_from_data (keyfile, metadata_contents->str, metadata_contents->len, 0, NULL))
    return flatpak_fail (error, "Internal error parsing generated keyfile");

  for (i = 0; opt_extensions != NULL && opt_extensions[i] != NULL; i++)
    {
      g_auto(GStrv) elements = NULL;
      g_autofree char *groupname = NULL;

      elements = g_strsplit (opt_extensions[i], "=", 3);
      if (g_strv_length (elements) < 2)
        return flatpak_fail (error, _("Too few elements in --extension argument %s, format should be NAME=VAR[=VALUE]"), opt_extensions[i]);

      if (!flatpak_is_valid_name (elements[0], -1, error))
        return glnx_prefix_error (error, _("Invalid extension name %s"), elements[0]);

      groupname = g_strconcat (FLATPAK_METADATA_GROUP_PREFIX_EXTENSION,
                               elements[0], NULL);

      g_key_file_set_string (keyfile, groupname, elements[1], elements[2] ? elements[2] : "true");
    }

  keyfile_data = g_key_file_to_data (keyfile, &keyfile_data_len, NULL);

  if (!g_file_replace_contents (metadata_file,
                                keyfile_data, keyfile_data_len, NULL, FALSE,
                                G_FILE_CREATE_REPLACE_DESTINATION,
                                NULL, cancellable, error))
    return FALSE;

  if (!g_file_replace_contents (gitignore_file,
                                GIT_IGNORE_FILE, sizeof (GIT_IGNORE_FILE),
                                NULL, FALSE,
                                G_FILE_CREATE_REPLACE_DESTINATION,
                                NULL, cancellable, error))
    return FALSE;

  return TRUE;
}

gboolean
flatpak_complete_build_init (FlatpakCompletion *completion)
{
  g_autoptr(GOptionContext) context = NULL;
  g_autoptr(FlatpakDir) user_dir = NULL;
  g_autoptr(FlatpakDir) system_dir = NULL;

  context = g_option_context_new ("");

  if (!flatpak_option_context_parse (context, options, &completion->argc, &completion->argv,
                                     FLATPAK_BUILTIN_FLAG_NO_DIR, NULL, NULL, NULL))
    return FALSE;

  switch (completion->argc)
    {
    case 0:
    case 1: /* DIR */
      flatpak_complete_options (completion, global_entries);
      flatpak_complete_options (completion, options);

      flatpak_complete_dir (completion);
      break;

    case 2: /* APP */
      break;

    case 3: /* RUNTIME */
    case 4: /* SDK */
      user_dir = flatpak_dir_get_user ();
      {
        g_autoptr(GError) error = NULL;
        g_autoptr(GPtrArray) refs = flatpak_dir_find_installed_refs (user_dir, NULL, NULL, opt_arch,
                                                                     FLATPAK_KINDS_RUNTIME,
                                                                     FIND_MATCHING_REFS_FLAGS_NONE,
                                                                     &error);
        if (refs == NULL)
          flatpak_completion_debug ("find local refs error: %s", error->message);

        flatpak_complete_ref_id (completion, refs);
      }

      system_dir = flatpak_dir_get_system_default ();
      {
        g_autoptr(GError) error = NULL;
        g_autoptr(GPtrArray) refs = flatpak_dir_find_installed_refs (system_dir, NULL, NULL, opt_arch,
                                                                     FLATPAK_KINDS_RUNTIME,
                                                                     FIND_MATCHING_REFS_FLAGS_NONE,
                                                                     &error);
        if (refs == NULL)
          flatpak_completion_debug ("find local refs error: %s", error->message);

        flatpak_complete_ref_id (completion, refs);
      }

      break;

    case 5: /* BRANCH */
      user_dir = flatpak_dir_get_user ();
      {
        g_autoptr(GError) error = NULL;
        g_autoptr(GPtrArray) refs = flatpak_dir_find_installed_refs (user_dir, completion->argv[3], NULL, opt_arch,
                                                                     FLATPAK_KINDS_RUNTIME,
                                                                     FIND_MATCHING_REFS_FLAGS_NONE,
                                                                     &error);
        if (refs == NULL)
          flatpak_completion_debug ("find local refs error: %s", error->message);

        flatpak_complete_ref_branch (completion, refs);
      }

      system_dir = flatpak_dir_get_system_default ();
      {
        g_autoptr(GError) error = NULL;
        g_autoptr(GPtrArray) refs = flatpak_dir_find_installed_refs (system_dir, completion->argv[3], NULL, opt_arch,
                                                                     FLATPAK_KINDS_RUNTIME,
                                                                     FIND_MATCHING_REFS_FLAGS_NONE,
                                                                     &error);
        if (refs == NULL)
          flatpak_completion_debug ("find local refs error: %s", error->message);

        flatpak_complete_ref_branch (completion, refs);
      }

      break;
    }

  return TRUE;
}

===== ./app/flatpak-builtins-list.c =====
/* vi:set et sw=2 sts=2 cin cino=t0,f0,(0,{s,>2s,n-s,^-s,e-s:
 * Copyright © 2014 Red Hat, Inc
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Alexander Larsson <alexl@redhat.com>
 */

#include "config.h"

#include <locale.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

#include <glib/gi18n.h>

#include "libglnx.h"

#include "flatpak-builtins.h"
#include "flatpak-builtins-utils.h"
#include "flatpak-utils-private.h"
#include "flatpak-table-printer.h"

static gboolean opt_show_details;
static gboolean opt_runtime;
static gboolean opt_app;
static gboolean opt_all;
static gboolean opt_json;
static char *opt_arch;
static char *opt_app_runtime;
static const char **opt_cols;

static GOptionEntry options[] = {
  { "show-details", 'd', 0, G_OPTION_ARG_NONE, &opt_show_details, N_("Show extra information"), NULL },
  { "runtime", 0, 0, G_OPTION_ARG_NONE, &opt_runtime, N_("List installed runtimes"), NULL },
  { "app", 0, 0, G_OPTION_ARG_NONE, &opt_app, N_("List installed applications"), NULL },
  { "arch", 0, 0, G_OPTION_ARG_STRING, &opt_arch, N_("Arch to show"), N_("ARCH") },
  { "all", 'a', 0, G_OPTION_ARG_NONE, &opt_all, N_("List all refs (including locale/debug)"), NULL },
  { "json", 'j', 0, G_OPTION_ARG_NONE, &opt_json, N_("Show output in JSON format"), NULL },
  { "app-runtime", 0, 0, G_OPTION_ARG_STRING, &opt_app_runtime, N_("List all applications using RUNTIME"), N_("RUNTIME") },
  { "columns", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_cols, N_("What information to show"), N_("FIELD,…")  },
  { NULL }
};

static Column all_columns[] = {
  { "name",         N_("Name"),           N_("Show the name"),           1, FLATPAK_ELLIPSIZE_MODE_END, 1, 1 },
  { "description",  N_("Description"),    N_("Show the description"),    1, FLATPAK_ELLIPSIZE_MODE_END, 1, 0 },
  { "application",  N_("Application ID"), N_("Show the application ID"), 1, FLATPAK_ELLIPSIZE_MODE_START, 0, 1 },
  { "version",      N_("Version"),        N_("Show the version"),        1, FLATPAK_ELLIPSIZE_MODE_NONE, 1, 1 },
  { "branch",       N_("Branch"),         N_("Show the branch"),         1, FLATPAK_ELLIPSIZE_MODE_NONE, 0, 1 },
  { "arch",         N_("Arch"),           N_("Show the architecture"),   1, FLATPAK_ELLIPSIZE_MODE_NONE, 0, 1, 1 },
  { "runtime",      N_("Runtime"),        N_("Show the used runtime"),   1, FLATPAK_ELLIPSIZE_MODE_START, 0, 0 },
  { "origin",       N_("Origin"),         N_("Show the origin remote"),  1, FLATPAK_ELLIPSIZE_MODE_NONE, 1, 1, 1 },
  { "installation", N_("Installation"),   N_("Show the installation"),   1, FLATPAK_ELLIPSIZE_MODE_NONE, 1, 0 },
  { "ref",          N_("Ref"),            N_("Show the ref"),            1, FLATPAK_ELLIPSIZE_MODE_NONE, 1, 0 },
  { "active",       N_("Active commit"),  N_("Show the active commit"),  1, FLATPAK_ELLIPSIZE_MODE_NONE, 1, 0 },
  { "latest",       N_("Latest commit"),  N_("Show the latest commit"),  1, FLATPAK_ELLIPSIZE_MODE_NONE, 1, 0 },
  { "size",         N_("Installed size"), N_("Show the installed size"), 1, FLATPAK_ELLIPSIZE_MODE_NONE, 1, 0 },
  { "options",      N_("Options"),        N_("Show options"),            1, FLATPAK_ELLIPSIZE_MODE_END, 1, 0 },
  { NULL }
};

/* Associates a flatpak installation's directory with
 * the list of references for apps and runtimes */
typedef struct
{
  FlatpakDir *dir;
  GPtrArray  *refs;
} RefsData;

static RefsData *
refs_data_new (FlatpakDir *dir, GPtrArray *refs)
{
  RefsData *refs_data = g_new0 (RefsData, 1);

  refs_data->dir = g_object_ref (dir);
  refs_data->refs = g_ptr_array_ref (refs);
  return refs_data;
}

static void
refs_data_free (RefsData *refs_data)
{
  g_object_unref (refs_data->dir);
  g_ptr_array_unref (refs_data->refs);
  g_free (refs_data);
}

static gboolean
print_table_for_refs (gboolean      print_apps,
                      GPtrArray   * refs_array,
                      const char   *arch,
                      const char   *app_runtime,
                      Column       *columns,
                      GCancellable *cancellable,
                      GError      **error)
{
  g_autoptr(FlatpakTablePrinter) printer = NULL;
  int i;
  FlatpakKinds match_kinds;
  g_autofree char *match_id = NULL;
  g_autofree char *match_arch = NULL;
  g_autofree char *match_branch = NULL;

  if (columns[0].name == NULL)
    return TRUE;

  printer = flatpak_table_printer_new ();

  flatpak_table_printer_set_columns (printer, columns,
                                     opt_cols == NULL && !opt_show_details);

  if (app_runtime)
    {
      if (!flatpak_split_partial_ref_arg (app_runtime, FLATPAK_KINDS_RUNTIME, NULL, NULL,
                                          &match_kinds, &match_id, &match_arch, &match_branch, error))
        return FALSE;
    }

  for (i = 0; i < refs_array->len; i++)
    {
      RefsData *refs_data = NULL;
      FlatpakDir *dir = NULL;
      GPtrArray *dir_refs = NULL;
      g_autoptr(GHashTable) ref_hash = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, NULL);
      int j;

      refs_data = (RefsData *) g_ptr_array_index (refs_array, i);
      dir = refs_data->dir;
      dir_refs = refs_data->refs;

      for (j = 0; j < dir_refs->len; j++)
        {
          FlatpakDecomposed *ref = g_ptr_array_index (dir_refs, j);
          g_hash_table_add (ref_hash, (char *)flatpak_decomposed_get_ref (ref));
        }

      for (j = 0; j < dir_refs->len; j++)
        {
          FlatpakDecomposed *ref = g_ptr_array_index (dir_refs, j);
          const char *partial_ref;
          const char *repo = NULL;
          g_autoptr(FlatpakDeploy) deploy = NULL;
          g_autoptr(GBytes) deploy_data = NULL;
          g_autoptr(GError) local_error = NULL;
          const char *active;
          const char *alt_id;
          const char *eol;
          const char *eol_rebase;
          const char *appdata_name;
          const char *appdata_summary;
          const char *appdata_version;
          const char *runtime;
          g_autofree char *latest = NULL;
          g_autofree const char **subpaths = NULL;
          int k;

          partial_ref = flatpak_decomposed_get_pref (ref);

          if (arch != NULL && !flatpak_decomposed_is_arch (ref, arch))
            continue;

          deploy = flatpak_dir_load_deployed (dir, ref, NULL, cancellable, &local_error);

          if (deploy == NULL)
            {
              g_warning (_("Unable to load details of %s: %s"),
                         partial_ref, local_error->message);
              g_clear_error (&local_error);
              continue;
            }

          deploy_data = flatpak_deploy_get_deploy_data (deploy, FLATPAK_DEPLOY_VERSION_CURRENT, cancellable, &local_error);

          if (deploy_data == NULL)
            {
              g_warning (_("Unable to inspect current version of %s: %s"),
                         partial_ref, local_error->message);
              g_clear_error (&local_error);
              continue;
            }

          runtime = flatpak_deploy_data_get_runtime (deploy_data);

          if (app_runtime)
            {
              if (runtime)
                {
                  g_auto(GStrv) pref = g_strsplit (runtime, "/", 3);
                  if ((match_id && pref[0] && strcmp (pref[0], match_id) != 0) ||
                      (match_arch && pref[1] && strcmp (pref[1], match_arch) != 0) ||
                      (match_branch && pref[2] && strcmp (pref[2], match_branch) != 0))
                    continue;
                }
            }

          g_autofree char *ref_id = flatpak_decomposed_dup_id (ref);
          g_autofree char *ref_arch = flatpak_decomposed_dup_arch (ref);
          g_autofree char *ref_branch = flatpak_decomposed_dup_branch (ref);

          if (!opt_all &&
              flatpak_decomposed_is_runtime (ref) &&
              flatpak_decomposed_id_is_subref (ref))
            {
              g_autoptr(FlatpakDecomposed) extensionof_decomposed = NULL;
              const char *extension_of = flatpak_deploy_data_get_extension_of (deploy_data);
              if (extension_of != NULL)
                extensionof_decomposed = flatpak_decomposed_new_from_ref (extension_of, NULL);
              if (extensionof_decomposed != NULL)
                {
                  if (!opt_app && flatpak_decomposed_is_app (extensionof_decomposed))
                    continue;

                  if (g_hash_table_lookup (ref_hash, extension_of))
                    continue;
                }
            }

          repo = flatpak_deploy_data_get_origin (deploy_data);

          active = flatpak_deploy_data_get_commit (deploy_data);
          alt_id = flatpak_deploy_data_get_alt_id (deploy_data);
          eol = flatpak_deploy_data_get_eol (deploy_data);
          eol_rebase = flatpak_deploy_data_get_eol_rebase (deploy_data);
          appdata_name = flatpak_deploy_data_get_appdata_name (deploy_data);
          appdata_summary = flatpak_deploy_data_get_appdata_summary (deploy_data);
          appdata_version = flatpak_deploy_data_get_appdata_version (deploy_data);

          latest = flatpak_dir_read_latest (dir, repo, flatpak_decomposed_get_ref (ref), NULL, NULL, NULL);
          if (latest)
            {
              if (strcmp (active, latest) == 0)
                {
                  g_free (latest);
                  latest = g_strdup ("-");
                }
              else
                {
                  latest[MIN (strlen (latest), 12)] = 0;
                }
            }
          else
            {
              latest = g_strdup ("?");
            }

          for (k = 0; columns[k].name; k++)
            {
              if (strcmp (columns[k].name, "name") == 0)
                {
                  const char *name = NULL;
                  g_autofree char *readable_id = NULL;

                  if (appdata_name)
                    name = appdata_name;
                  else
                    {
                      readable_id = flatpak_decomposed_dup_readable_id (ref);
                      name = readable_id;
                    }

                  flatpak_table_printer_add_column (printer, name);
                }
              else if (strcmp (columns[k].name, "description") == 0)
                {
                  const char *description = appdata_summary ? appdata_summary : "";
                  flatpak_table_printer_add_column (printer, description);
                }
              else if (strcmp (columns[k].name, "version") == 0)
                flatpak_table_printer_add_column (printer, appdata_version ? appdata_version : "");
              else if (strcmp (columns[k].name, "installation") == 0)
                flatpak_table_printer_add_column (printer, flatpak_dir_get_name_cached (dir));
              else if (strcmp (columns[k].name, "runtime") == 0)
                flatpak_table_printer_add_column (printer, runtime ? runtime : "");
              else if (strcmp (columns[k].name, "ref") == 0)
                flatpak_table_printer_add_column (printer, partial_ref);
              else if (strcmp (columns[k].name, "application") == 0)
                flatpak_table_printer_add_column (printer, ref_id);
              else if (strcmp (columns[k].name, "arch") == 0)
                flatpak_table_printer_add_column (printer, ref_arch);
              else if (strcmp (columns[k].name, "branch") == 0)
                flatpak_table_printer_add_column (printer, ref_branch);
              else if (strcmp (columns[k].name, "origin") == 0)
                flatpak_table_printer_add_column (printer, repo);
              else if (strcmp (columns[k].name, "active") == 0)
                flatpak_table_printer_add_column_len (printer, active, 12);
              else if (strcmp (columns[k].name, "latest") == 0)
                flatpak_table_printer_add_column_len (printer, latest, 12);
              else if (strcmp (columns[k].name, "size") == 0)
                {
                  g_autofree char *size_s = NULL;
                  guint64 size = 0;

                  size = flatpak_deploy_data_get_installed_size (deploy_data);
                  size_s = g_format_size (size);
                  flatpak_table_printer_add_decimal_column (printer, size_s);
                }
              else if (strcmp (columns[k].name, "options") == 0)
                {
                  flatpak_table_printer_add_column (printer, ""); /* Options */

                  if (refs_array->len > 1)
                    {
                      g_autofree char *source = flatpak_dir_get_name (dir);
                      flatpak_table_printer_append_with_comma (printer, source);
                    }

                  if (alt_id)
                    flatpak_table_printer_append_with_comma_printf (printer, "alt-id=%.12s", alt_id);

                  if (flatpak_decomposed_is_app (ref))
                    {
                      g_autoptr(FlatpakDecomposed) current = flatpak_dir_current_ref (dir, ref_id, cancellable);
                      if (current && flatpak_decomposed_equal (ref, current))
                        flatpak_table_printer_append_with_comma (printer, "current");
                    }
                  else
                    {
                      if (print_apps)
                        flatpak_table_printer_append_with_comma (printer, "runtime");
                    }

                  subpaths = flatpak_deploy_data_get_subpaths (deploy_data);
                  if (subpaths[0] != NULL)
                    {
                      g_autofree char *paths = g_strjoinv (" ", (char **) subpaths);
                      g_autofree char *value = g_strconcat ("partial (", paths, ")", NULL);
                      flatpak_table_printer_append_with_comma (printer, value);
                    }

                  if (eol)
                    flatpak_table_printer_append_with_comma_printf (printer, "eol=%s", eol);
                  if (eol_rebase)
                    flatpak_table_printer_append_with_comma_printf (printer, "eol-rebase=%s", eol_rebase);
                }
            }

          flatpak_table_printer_set_key (printer, flatpak_decomposed_get_ref (ref));
          flatpak_table_printer_finish_row (printer);
        }
    }

  flatpak_table_printer_sort (printer, (GCompareFunc) flatpak_compare_ref);

  if (flatpak_table_printer_get_current_row (printer) > 0)
    {
      opt_json ? flatpak_table_printer_print_json (printer) : flatpak_table_printer_print (printer);
    }

  return TRUE;
}

static gboolean
print_installed_refs (gboolean      app,
                      gboolean      runtime,
                      GPtrArray    *dirs,
                      const char   *arch,
                      const char   *app_runtime,
                      Column       *cols,
                      GCancellable *cancellable,
                      GError      **error)
{
  g_autoptr(GPtrArray) refs_array = NULL;
  int i;

  refs_array = g_ptr_array_new_with_free_func ((GDestroyNotify) refs_data_free);

  for (i = 0; i < dirs->len; i++)
    {
      FlatpakDir *dir = g_ptr_array_index (dirs, i);
      g_autoptr(GPtrArray) refs = NULL;

      refs = flatpak_dir_list_refs (dir, flatpak_kinds_from_bools (app, runtime),
                                    cancellable, error);
      if (refs == NULL)
        return FALSE;

      g_ptr_array_add (refs_array, refs_data_new (dir, refs));
    }

  if (!print_table_for_refs (app, refs_array, arch, app_runtime, cols, cancellable, error))
    return FALSE;

  return TRUE;
}

gboolean
flatpak_builtin_list (int argc, char **argv, GCancellable *cancellable, GError **error)
{
  g_autoptr(GOptionContext) context = NULL;
  g_autoptr(GPtrArray) dirs = NULL;
  g_autofree char *col_help = NULL;
  g_autofree Column *columns = NULL;

  context = g_option_context_new (_(" - List installed apps and/or runtimes"));
  g_option_context_set_translation_domain (context, GETTEXT_PACKAGE);
  col_help = column_help (all_columns);
  g_option_context_set_description (context, col_help);

  if (!flatpak_option_context_parse (context, options, &argc, &argv,
                                     FLATPAK_BUILTIN_FLAG_ALL_DIRS | FLATPAK_BUILTIN_FLAG_OPTIONAL_REPO,
                                     &dirs, cancellable, error))
    return FALSE;

  if (argc > 1)
    return usage_error (context, _("Too many arguments"), error);

  if (!opt_app && !opt_runtime)
    {
      opt_app = TRUE;
      opt_runtime = !opt_app_runtime;
    }

  /* Default to showing installation if we're listing multiple installations */
  if (dirs->len > 1)
    {
      int c = find_column (all_columns, "installation", NULL);
      g_assert (c != -1);
      all_columns[c].def = 1;
    }

  columns = handle_column_args (all_columns, opt_show_details, opt_cols, error);
  if (columns == NULL)
    return FALSE;

  return print_installed_refs (opt_app, opt_runtime,
                               dirs,
                               opt_arch,
                               opt_app_runtime,
                               columns,
                               cancellable, error);
}

gboolean
flatpak_complete_list (FlatpakCompletion *completion)
{
  flatpak_complete_options (completion, global_entries);
  flatpak_complete_options (completion, options);
  flatpak_complete_options (completion, user_entries);
  flatpak_complete_columns (completion, all_columns);
  return TRUE;
}

===== ./app/flatpak-quiet-transaction.c =====
/* vi:set et sw=2 sts=2 cin cino=t0,f0,(0,{s,>2s,n-s,^-s,e-s:
 * Copyright © 2019 Red Hat, Inc
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Matthias Clasen <mclasen@redhat.com>
 */

#include "config.h"

#include "flatpak-quiet-transaction.h"
#include "flatpak-transaction-private.h"
#include "flatpak-installation-private.h"
#include "flatpak-run-private.h"
#include "flatpak-table-printer.h"
#include "flatpak-utils-private.h"
#include "flatpak-error.h"
#include <glib/gi18n.h>


struct _FlatpakQuietTransaction
{
  FlatpakTransaction parent;
  gboolean got_error;
};

struct _FlatpakQuietTransactionClass
{
  FlatpakTransactionClass parent_class;
};

G_DEFINE_TYPE (FlatpakQuietTransaction, flatpak_quiet_transaction, FLATPAK_TYPE_TRANSACTION);

static int
choose_remote_for_ref (FlatpakTransaction *transaction,
                       const char         *for_ref,
                       const char         *runtime_ref,
                       const char * const *remotes)
{
  return 0;
}

static gboolean
add_new_remote (FlatpakTransaction            *transaction,
                FlatpakTransactionRemoteReason reason,
                const char                    *from_id,
                const char                    *remote_name,
                const char                    *url)
{
  return TRUE;
}

static void
new_operation (FlatpakTransaction          *transaction,
               FlatpakTransactionOperation *op,
               FlatpakTransactionProgress  *progress)
{
  FlatpakTransactionOperationType op_type = flatpak_transaction_operation_get_operation_type (op);
  const char *ref = flatpak_transaction_operation_get_ref (op);

  switch (op_type)
    {
    case FLATPAK_TRANSACTION_OPERATION_INSTALL_BUNDLE:
    case FLATPAK_TRANSACTION_OPERATION_INSTALL:
      g_print (_("Installing %s\n"), ref);
      break;

    case FLATPAK_TRANSACTION_OPERATION_UPDATE:
      g_print (_("Updating %s\n"), ref);
      break;

    case FLATPAK_TRANSACTION_OPERATION_UNINSTALL:
      g_print (_("Uninstalling %s\n"), ref);
      break;

    default:
      g_assert_not_reached ();
      break;
    }
}

static void
print_op_error_msg (FlatpakTransactionOperationType  operation_type,
                    FlatpakRef                      *rref,
                    const char                      *msg,
                    gboolean                         non_fatal)
{
  /* Here we go to great lengths not to split the sentences. See
   * https://wiki.gnome.org/TranslationProject/DevGuidelines/Never%20split%20sentences
   */
  switch (operation_type)
    {
    case FLATPAK_TRANSACTION_OPERATION_INSTALL:
      if (non_fatal)
        g_printerr (_("Warning: Failed to install %s: %s\n"),
                    flatpak_ref_get_name (rref), msg);
      else
        g_printerr (_("Error: Failed to install %s: %s\n"),
                    flatpak_ref_get_name (rref), msg);
      break;

    case FLATPAK_TRANSACTION_OPERATION_UPDATE:
      if (non_fatal)
        g_printerr (_("Warning: Failed to update %s: %s\n"),
                    flatpak_ref_get_name (rref), msg);
      else
        g_printerr (_("Error: Failed to update %s: %s\n"),
                    flatpak_ref_get_name (rref), msg);
      break;

    case FLATPAK_TRANSACTION_OPERATION_INSTALL_BUNDLE:
      if (non_fatal)
        g_printerr (_("Warning: Failed to install bundle %s: %s\n"),
                    flatpak_ref_get_name (rref), msg);
      else
        g_printerr (_("Error: Failed to install bundle %s: %s\n"),
                    flatpak_ref_get_name (rref), msg);
      break;

    case FLATPAK_TRANSACTION_OPERATION_UNINSTALL:
      if (non_fatal)
        g_printerr (_("Warning: Failed to uninstall %s: %s\n"),
                    flatpak_ref_get_name (rref), msg);
      else
        g_printerr (_("Error: Failed to uninstall %s: %s\n"),
                    flatpak_ref_get_name (rref), msg);
      break;

    default:
      g_assert_not_reached ();
    }
}

static gboolean
operation_error (FlatpakTransaction            *transaction,
                 FlatpakTransactionOperation   *op,
                 const GError                  *error,
                 FlatpakTransactionErrorDetails detail)
{
  FlatpakQuietTransaction *self = FLATPAK_QUIET_TRANSACTION (transaction);
  FlatpakTransactionOperationType op_type = flatpak_transaction_operation_get_operation_type (op);
  const char *ref = flatpak_transaction_operation_get_ref (op);
  g_autoptr(FlatpakRef) rref = flatpak_ref_parse (ref, NULL);
  g_autofree char *msg = NULL;
  gboolean non_fatal = (detail & FLATPAK_TRANSACTION_ERROR_DETAILS_NON_FATAL) != 0;

  if (g_error_matches (error, FLATPAK_ERROR, FLATPAK_ERROR_SKIPPED))
    {
      g_print (_("Info: %s was skipped"), flatpak_ref_get_name (rref));
      return TRUE;
    }

  if (g_error_matches (error, FLATPAK_ERROR, FLATPAK_ERROR_ALREADY_INSTALLED))
    msg = g_strdup_printf (_("%s already installed"), flatpak_ref_get_name (rref));
  else if (g_error_matches (error, FLATPAK_ERROR, FLATPAK_ERROR_NOT_INSTALLED))
    msg = g_strdup_printf (_("%s not installed"), flatpak_ref_get_name (rref));
  else if (g_error_matches (error, FLATPAK_ERROR, FLATPAK_ERROR_NEED_NEW_FLATPAK))
    msg = g_strdup_printf (_("%s needs a later flatpak version"), flatpak_ref_get_name (rref));
  else if (g_error_matches (error, FLATPAK_ERROR, FLATPAK_ERROR_OUT_OF_SPACE))
    msg = g_strdup (_("Not enough disk space to complete this operation"));
  else
    msg = g_strdup (error->message);

  print_op_error_msg (op_type, rref, msg, non_fatal);

  if (non_fatal)
    return TRUE; /* Continue */

  self->got_error = TRUE;

  return non_fatal; /* Continue if non-fatal */
}

static void
install_authenticator (FlatpakTransaction            *old_transaction,
                       const char                    *remote,
                       const char                    *ref)
{
  g_autoptr(FlatpakTransaction)  transaction2 = NULL;
  g_autoptr(GError) local_error = NULL;
  g_autoptr(FlatpakInstallation) installation = flatpak_transaction_get_installation (old_transaction);
  g_autoptr(FlatpakDir) dir = flatpak_installation_get_dir (installation, NULL);

  if (dir == NULL)
    {
      /* This should not happen */
      g_warning ("No dir in install_authenticator");
      return;
    }

  transaction2 = flatpak_quiet_transaction_new (dir, &local_error);
  if (transaction2 == NULL)
    {
      g_printerr ("Unable to install authenticator: %s\n", local_error->message);
      return;
    }

  if (!flatpak_transaction_add_install (transaction2, remote, ref, NULL, &local_error))
    {
      if (!g_error_matches (local_error, FLATPAK_ERROR, FLATPAK_ERROR_ALREADY_INSTALLED))
        g_printerr ("Unable to install authenticator: %s\n", local_error->message);
      return;
    }

  if (!flatpak_transaction_run (transaction2, NULL, &local_error))
    {
      if (!g_error_matches (local_error, FLATPAK_ERROR, FLATPAK_ERROR_ABORTED))
        g_printerr ("Unable to install authenticator: %s\n", local_error->message);
      return;
    }

  return;
}

static gboolean
end_of_lifed_with_rebase (FlatpakTransaction *transaction,
                          const char         *remote,
                          const char         *ref,
                          const char         *reason,
                          const char         *rebased_to_ref,
                          const char        **previous_ids)
{
  FlatpakQuietTransaction *self = FLATPAK_QUIET_TRANSACTION (transaction);
  g_autoptr(FlatpakRef) rref = flatpak_ref_parse (ref, NULL);

  if (rebased_to_ref)
    g_print (_("Info: %s is end-of-life, in favor of %s\n"), flatpak_ref_get_name (rref), rebased_to_ref);
  else if (reason)
    g_print (_("Info: %s is end-of-life, with reason: %s\n"), flatpak_ref_get_name (rref), reason);

  if (rebased_to_ref && remote)
    {
      g_autoptr(GError) error = NULL;

      g_print (_("Updating to rebased version\n"));

      if (!flatpak_transaction_add_rebase_and_uninstall (transaction, remote, rebased_to_ref, ref, NULL, previous_ids, &error))
        {
          g_printerr (_("Failed to rebase %s to %s: %s\n"),
                      flatpak_ref_get_name (rref), rebased_to_ref, error->message);
          self->got_error = TRUE;
          return FALSE;
        }

      return TRUE;
    }

  return FALSE;
}

static gboolean
flatpak_quiet_transaction_run (FlatpakTransaction *transaction,
                               GCancellable       *cancellable,
                               GError            **error)
{
  FlatpakQuietTransaction *self = FLATPAK_QUIET_TRANSACTION (transaction);
  gboolean res;

  res = FLATPAK_TRANSACTION_CLASS (flatpak_quiet_transaction_parent_class)->run (transaction, cancellable, error);

  if (self->got_error)
    {
      g_clear_error (error);
      return FALSE; /* Don't report on stderr, we already reported */
    }

  if (!res)
    return FALSE;

  return TRUE;
}

static void
flatpak_quiet_transaction_init (FlatpakQuietTransaction *transaction)
{
}

static void
flatpak_quiet_transaction_class_init (FlatpakQuietTransactionClass *class)
{
  FlatpakTransactionClass *transaction_class = FLATPAK_TRANSACTION_CLASS (class);

  transaction_class->choose_remote_for_ref = choose_remote_for_ref;
  transaction_class->add_new_remote = add_new_remote;
  transaction_class->new_operation = new_operation;
  transaction_class->operation_error = operation_error;
  transaction_class->end_of_lifed_with_rebase = end_of_lifed_with_rebase;
  transaction_class->run = flatpak_quiet_transaction_run;
  transaction_class->install_authenticator = install_authenticator;
}

FlatpakTransaction *
flatpak_quiet_transaction_new (FlatpakDir *dir,
                               GError    **error)
{
  g_autoptr(FlatpakQuietTransaction) self = NULL;
  g_autoptr(FlatpakInstallation) installation = NULL;

  installation = flatpak_installation_new_for_dir (dir, NULL, error);
  if (installation == NULL)
    return NULL;

  self = g_initable_new (FLATPAK_TYPE_QUIET_TRANSACTION,
                         NULL, error,
                         "installation", installation,
                         NULL);

  if (self == NULL)
    return NULL;

  flatpak_transaction_set_no_interaction (FLATPAK_TRANSACTION (self), TRUE);
  flatpak_transaction_add_default_dependency_sources (FLATPAK_TRANSACTION (self));

  return FLATPAK_TRANSACTION (g_steal_pointer (&self));
}

===== ./app/flatpak-builtins-build-export.c =====
/* vi:set et sw=2 sts=2 cin cino=t0,f0,(0,{s,>2s,n-s,^-s,e-s:
 * Copyright © 2014 Red Hat, Inc
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Alexander Larsson <alexl@redhat.com>
 */

#include "config.h"

#include <locale.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

#include <glib/gi18n.h>

#include "libglnx.h"

#include "flatpak-builtins.h"
#include "flatpak-repo-utils-private.h"
#include "flatpak-utils-private.h"
#include "parse-datetime.h"

static char *opt_subject;
static char *opt_body;
static char *opt_arch;
static gboolean opt_runtime;
static gboolean opt_update_appstream;
static gboolean opt_no_update_summary;
static gboolean opt_disable_fsync;
static gboolean opt_disable_sandbox = FALSE;
static char **opt_gpg_key_ids;
static char **opt_exclude;
static char **opt_include;
static char *opt_gpg_homedir;
static char *opt_files;
static char *opt_metadata;
static char *opt_timestamp = NULL;
static char *opt_endoflife;
static char *opt_endoflife_rebase;
static char **opt_subsets;
static char *opt_collection_id = NULL;
static int opt_token_type = -1;
static gboolean opt_no_summary_index = FALSE;

static GOptionEntry options[] = {
  { "subject", 's', 0, G_OPTION_ARG_STRING, &opt_subject, N_("One line subject"), N_("SUBJECT") },
  { "body", 'b', 0, G_OPTION_ARG_STRING, &opt_body, N_("Full description"), N_("BODY") },
  { "arch", 0, 0, G_OPTION_ARG_STRING, &opt_arch, N_("Architecture to export for (must be host compatible)"), N_("ARCH") },
  { "runtime", 'r', 0, G_OPTION_ARG_NONE, &opt_runtime, N_("Commit runtime (/usr), not /app"), NULL },
  { "update-appstream", 0, 0, G_OPTION_ARG_NONE, &opt_update_appstream, N_("Update the appstream branch"), NULL },
  { "no-update-summary", 0, 0, G_OPTION_ARG_NONE, &opt_no_update_summary, N_("Don't update the summary"), NULL },
  { "files", 0, 0, G_OPTION_ARG_STRING, &opt_files, N_("Use alternative directory for the files"), N_("SUBDIR") },
  { "metadata", 0, 0, G_OPTION_ARG_STRING, &opt_metadata, N_("Use alternative file for the metadata"), N_("FILE") },
  { "gpg-sign", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_gpg_key_ids, N_("GPG Key ID to sign the commit with"), N_("KEY-ID") },
  { "exclude", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_exclude, N_("Files to exclude"), N_("PATTERN") },
  { "include", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_include, N_("Excluded files to include"), N_("PATTERN") },
  { "gpg-homedir", 0, 0, G_OPTION_ARG_STRING, &opt_gpg_homedir, N_("GPG Homedir to use when looking for keyrings"), N_("HOMEDIR") },
  { "subset", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_subsets, "Add to a named subset", "SUBSET" },
  { "end-of-life", 0, 0, G_OPTION_ARG_STRING, &opt_endoflife, N_("Mark build as end-of-life"), N_("REASON") },
  { "end-of-life-rebase", 0, 0, G_OPTION_ARG_STRING, &opt_endoflife_rebase, N_("Mark build as end-of-life, to be replaced with the given ID"), N_("ID") },
  { "token-type", 0, 0, G_OPTION_ARG_INT, &opt_token_type, N_("Set type of token needed to install this commit"), N_("VAL") },
  { "timestamp", 0, 0, G_OPTION_ARG_STRING, &opt_timestamp, N_("Override the timestamp of the commit"), N_("TIMESTAMP") },
  { "collection-id", 0, 0, G_OPTION_ARG_STRING, &opt_collection_id, N_("Collection ID"), "COLLECTION-ID" },
  { "disable-fsync", 0, 0, G_OPTION_ARG_NONE, &opt_disable_fsync, "Do not invoke fsync()", NULL },
  { "disable-sandbox", 0, 0, G_OPTION_ARG_NONE, &opt_disable_sandbox, "Do not sandbox icon validator", NULL },
  { "no-summary-index", 0, 0, G_OPTION_ARG_NONE, &opt_no_summary_index, N_("Don't generate a summary index"), NULL },

  { NULL }
};

static gboolean
metadata_get_arch (GFile *file, char **out_arch, GError **error)
{
  g_autofree char *path = NULL;
  g_autoptr(GKeyFile) keyfile = NULL;
  g_autofree char *runtime = NULL;
  g_auto(GStrv) parts = NULL;

  if (opt_arch != NULL)
    {
      *out_arch = g_strdup (opt_arch);
      return TRUE;
    }

  keyfile = g_key_file_new ();
  path = g_file_get_path (file);
  if (!g_key_file_load_from_file (keyfile, path, G_KEY_FILE_NONE, error))
    return FALSE;

  runtime = g_key_file_get_string (keyfile,
                                   "Application",
                                   "runtime", NULL);
  if (runtime == NULL)
    runtime = g_key_file_get_string (keyfile,
                                     "Application",
                                     "sdk", NULL);
  if (runtime == NULL)
    runtime = g_key_file_get_string (keyfile,
                                     "Runtime",
                                     "runtime", NULL);
  if (runtime == NULL)
    runtime = g_key_file_get_string (keyfile,
                                     "Runtime",
                                     "sdk", NULL);
  if (runtime == NULL)
    {
      *out_arch = g_strdup (flatpak_get_arch ());
      return TRUE;
    }

  parts = g_strsplit (runtime, "/", 0);
  if (g_strv_length (parts) != 3)
    return flatpak_fail (error, "Failed to determine arch from metadata runtime key: %s", runtime);

  *out_arch = g_strdup (parts[1]);

  return TRUE;
}

static gboolean
is_empty_directory (GFile *file, GCancellable *cancellable)
{
  g_autoptr(GFileEnumerator) file_enum = NULL;
  g_autoptr(GFileInfo) child_info = NULL;

  file_enum = g_file_enumerate_children (file, G_FILE_ATTRIBUTE_STANDARD_NAME,
                                         G_FILE_QUERY_INFO_NONE,
                                         cancellable, NULL);
  if (!file_enum)
    return FALSE;

  child_info = g_file_enumerator_next_file (file_enum, cancellable, NULL);
  if (child_info)
    return FALSE;

  return TRUE;
}

typedef struct
{
  const char **exclude;
  const char **include;
} CommitData;

static gboolean
matches_patterns (const char **patterns, const char *path)
{
  int i;

  if (patterns == NULL)
    return FALSE;

  for (i = 0; patterns[i] != NULL; i++)
    {
      if (flatpak_path_match_prefix (patterns[i], path) != NULL)
        return TRUE;
    }

  return FALSE;
}

static OstreeRepoCommitFilterResult
commit_filter (OstreeRepo *repo,
               const char *path,
               GFileInfo  *file_info,
               CommitData *commit_data)
{
  guint mode;

  /* No user info */
  g_file_info_set_attribute_uint32 (file_info, "unix::uid", 0);
  g_file_info_set_attribute_uint32 (file_info, "unix::gid", 0);

  /* In flatpak, there is no real reason for files to have different
   * permissions based on the group or user really, everything is
   * always used readonly for everyone. Having things be writeable
   * for anyone but the user just causes risks for the system-installed
   * case. So, we canonicalize the mode to writable only by the user,
   * readable to all, and executable for all for directories and
   * files that the user can execute.
   */
  mode = g_file_info_get_attribute_uint32 (file_info, "unix::mode");
  if (g_file_info_get_file_type (file_info) == G_FILE_TYPE_DIRECTORY)
    mode = 0755 | S_IFDIR;
  else if (g_file_info_get_file_type (file_info) == G_FILE_TYPE_REGULAR)
    {
      /* If use can execute, make executable by all */
      if (mode & S_IXUSR)
        mode = 0755 | S_IFREG;
      else /* otherwise executable by none */
        mode = 0644 | S_IFREG;
    }
  g_file_info_set_attribute_uint32 (file_info, "unix::mode", mode);

  if (matches_patterns (commit_data->exclude, path) &&
      !matches_patterns (commit_data->include, path))
    {
      g_info ("Excluding %s", path);
      return OSTREE_REPO_COMMIT_FILTER_SKIP;
    }

  return OSTREE_REPO_COMMIT_FILTER_ALLOW;
}

static gboolean
add_file_to_mtree (GFile             *file,
                   const char        *name,
                   OstreeRepo        *repo,
                   OstreeMutableTree *mtree,
                   GCancellable      *cancellable,
                   GError           **error)
{
  g_autoptr(GFileInfo) file_info = NULL;
  g_autoptr(GInputStream) raw_input = NULL;
  g_autoptr(GInputStream) input = NULL;
  guint64 length;
  g_autofree guchar *child_file_csum = NULL;
  g_autofree char *tmp_checksum = NULL;

  file_info = g_file_query_info (file,
                                 "standard::size",
                                 0, cancellable, error);
  if (file_info == NULL)
    return FALSE;

  g_file_info_set_name (file_info, name);
  g_file_info_set_file_type (file_info, G_FILE_TYPE_REGULAR);
  g_file_info_set_attribute_uint32 (file_info, "unix::uid", 0);
  g_file_info_set_attribute_uint32 (file_info, "unix::gid", 0);
  g_file_info_set_attribute_uint32 (file_info, "unix::mode", 0100644);

  raw_input = (GInputStream *) g_file_read (file, cancellable, error);
  if (raw_input == NULL)
    return FALSE;

  if (!ostree_raw_file_to_content_stream (raw_input,
                                          file_info, NULL,
                                          &input, &length,
                                          cancellable, error))
    return FALSE;

  if (!ostree_repo_write_content (repo, NULL, input, length,
                                  &child_file_csum, cancellable, error))
    return FALSE;

  tmp_checksum = ostree_checksum_from_bytes (child_file_csum);
  if (!ostree_mutable_tree_replace_file (mtree, name, tmp_checksum, error))
    return FALSE;

  return TRUE;
}

static gboolean
find_file_in_tree (GFile *base, const char *filename)
{
  g_autoptr(GFileEnumerator) enumerator = NULL;

  enumerator = g_file_enumerate_children (base,
                                          G_FILE_ATTRIBUTE_STANDARD_TYPE ","
                                          G_FILE_ATTRIBUTE_STANDARD_NAME,
                                          G_FILE_QUERY_INFO_NONE,
                                          NULL,
                                          NULL);
  if (!enumerator)
    return FALSE;

  do
    {
      g_autoptr(GFileInfo) info = g_file_enumerator_next_file (enumerator, NULL, NULL);
      GFileType type;
      const char *name;

      if (!info)
        return FALSE;

      type = g_file_info_get_file_type (info);
      name = g_file_info_get_name (info);

      if (type == G_FILE_TYPE_REGULAR && strcmp (name, filename) == 0)
        return TRUE;
      else if (type == G_FILE_TYPE_DIRECTORY)
        {
          g_autoptr(GFile) dir = g_file_get_child (base, name);
          if (find_file_in_tree (dir, filename))
            return TRUE;
        }
    }
  while (1);

  return FALSE;
}

typedef gboolean (* VisitFileFunc) (GFile   *file,
                                    GError **error);

static gboolean
visit_files_in_tree (GFile        *base,
                     VisitFileFunc visit_file,
                     gpointer      data)
{
  g_autoptr(GFileEnumerator) enumerator = NULL;
  GError **error = data;

  enumerator = g_file_enumerate_children (base,
                                          G_FILE_ATTRIBUTE_STANDARD_TYPE ","
                                          G_FILE_ATTRIBUTE_STANDARD_NAME,
                                          G_FILE_QUERY_INFO_NONE,
                                          NULL,
                                          NULL);
  if (!enumerator)
    return FALSE;

  do
    {
      GFileInfo *info;
      GFile *child;
      GFileType type;

      if (!g_file_enumerator_iterate (enumerator, &info, &child, NULL, error))
        return FALSE;

      if (!info)
        return TRUE;

      type = g_file_info_get_file_type (info);

      if (type == G_FILE_TYPE_REGULAR)
        {
          if (!visit_file (child, data))
            return FALSE;
        }
      else if (type == G_FILE_TYPE_DIRECTORY)
        {
          if (!visit_files_in_tree (child, visit_file, data))
            return FALSE;
        }
    }
  while (1);

  return TRUE;
}

G_GNUC_NULL_TERMINATED
static void
add_args (GPtrArray *argv_array, ...)
{
  va_list args;
  const char *arg;

  va_start (args, argv_array);
  while ((arg = va_arg (args, const gchar *)))
    g_ptr_array_add (argv_array, g_strdup (arg));
  va_end (args);
}

static gboolean
validate_icon_file (GFile *file, GError **error)
{
  g_autoptr(GPtrArray) args = NULL;
  const char *name;
  int status;
  g_autofree char *err = NULL;
  const char *validate_icon = LIBEXECDIR "/flatpak-validate-icon";

  name = flatpak_file_get_path_cached (file);

  if (g_getenv ("FLATPAK_VALIDATE_ICON"))
    validate_icon = g_getenv ("FLATPAK_VALIDATE_ICON");

  args = g_ptr_array_new_with_free_func (g_free);

#ifndef DISABLE_SANDBOXED_TRIGGERS
  if (!opt_disable_sandbox)
    add_args (args, validate_icon, "--sandbox", "512", "512", name, NULL);
  else
#endif
    add_args (args, validate_icon, "512", "512", name, NULL);

  g_ptr_array_add (args, NULL);

  if (!g_spawn_sync (NULL, (char **) args->pdata, NULL,
                     G_SPAWN_STDOUT_TO_DEV_NULL,
                     NULL, NULL, NULL, &err, &status, error))
    {
      g_info ("Icon validation: %s", (*error)->message);
      return FALSE;
    }

  if (!g_spawn_check_exit_status (status, NULL))
    {
      g_info ("Icon validation: %s", err);
      return flatpak_fail (error, "%s is not a valid icon: %s", name, err);
    }

  return TRUE;
}

static gboolean
validate_exported_icons (GFile      *export,
                         const char *app_id,
                         GError    **error)
{
  g_autoptr(GFile) icondir = NULL;

  icondir = g_file_resolve_relative_path (export, "share/icons/hicolor");
  visit_files_in_tree (icondir, validate_icon_file, error);

  return !*error;
}

static GFile *
convert_app_absolute_path (const char *path, GFile *files)
{
  g_autofree char *exec_path = NULL;

  if (g_path_is_absolute (path))
    {
      if (g_str_has_prefix (path, "/app/"))
        exec_path = g_strdup (path + 5);
      else
        exec_path = g_strdup (path);
    }
  else
    exec_path = g_strconcat ("bin/", path, NULL);

  return g_file_resolve_relative_path (files, exec_path);
}

static gboolean
validate_desktop_file (GFile      *desktop_file,
                       GFile      *export,
                       GFile      *files,
                       const char *app_id,
                       char      **icon,
                       gboolean   *activatable,
                       GError    **error)
{
  g_autofree char *path = g_file_get_path (desktop_file);
  g_autoptr(GSubprocess) subprocess = NULL;
  g_autofree char *stdout_buf = NULL;
  g_autofree char *stderr_buf = NULL;
  g_autoptr(GError) local_error = NULL;
  g_autoptr(GKeyFile) key_file = NULL;
  g_autofree char *command = NULL;
  g_auto(GStrv) argv = NULL;
  g_autoptr(GFile) bin_file = NULL;

  if (!g_file_query_exists (desktop_file, NULL))
    return TRUE;

  subprocess = g_subprocess_new (G_SUBPROCESS_FLAGS_STDOUT_PIPE |
                                 G_SUBPROCESS_FLAGS_STDERR_PIPE |
                                 G_SUBPROCESS_FLAGS_STDERR_MERGE,
                                 &local_error, "desktop-file-validate", path, NULL);
  if (!subprocess)
    {
      if (!g_error_matches (local_error, G_SPAWN_ERROR, G_SPAWN_ERROR_NOENT))
        g_print (_("WARNING: Error running desktop-file-validate: %s\n"), local_error->message);

      g_clear_error (&local_error);
      goto check_refs;
    }

  if (!g_subprocess_communicate_utf8 (subprocess, NULL, NULL, &stdout_buf, &stderr_buf, &local_error))
    {
      g_print (_("WARNING: Error reading from desktop-file-validate: %s\n"), local_error->message);
      g_clear_error (&local_error);
    }

  if (g_subprocess_get_if_exited (subprocess) &&
      g_subprocess_get_exit_status (subprocess) != 0)
    g_print (_("WARNING: Failed to validate desktop file %s: %s\n"), path, stdout_buf);

check_refs:
  /* Test that references to other files are valid */

  key_file = g_key_file_new ();
  if (!g_key_file_load_from_file (key_file, path, G_KEY_FILE_NONE, error))
    return FALSE;

  *activatable = g_key_file_get_boolean (key_file,
                                         G_KEY_FILE_DESKTOP_GROUP,
                                         G_KEY_FILE_DESKTOP_KEY_DBUS_ACTIVATABLE,
                                         NULL);

  /* Validate Exec command: Unless we have DBusActivatable=true the key should
   * be present and – if set to a non-empty value – should point to an existing
   * binary.
   *
   * Empty values are allowed, they will result in the default command being
   * run by Flatpak when starting the application.
   */
  command = g_key_file_get_string (key_file,
                                   G_KEY_FILE_DESKTOP_GROUP,
                                   G_KEY_FILE_DESKTOP_KEY_EXEC,
                                   &local_error);
  if (!command && *activatable == FALSE)
    {
      g_print (_("WARNING: Can't find Exec key in %s: %s\n"), path, local_error->message);
      g_clear_error (&local_error);
    }
  else if (command && strlen(command) > 0)
    {
      argv = g_strsplit (command, " ", 0);
      bin_file = convert_app_absolute_path (argv[0], files);
      if (!g_file_query_exists (bin_file, NULL))
        g_print (_("WARNING: Binary not found for Exec line in %s: %s\n"), path, command);
    }

  *icon = g_key_file_get_string (key_file,
                                 G_KEY_FILE_DESKTOP_GROUP,
                                 G_KEY_FILE_DESKTOP_KEY_ICON,
                                 NULL);
  if (*icon && !g_str_has_prefix (*icon, app_id))
    g_print (_("WARNING: Icon not matching app id in %s: %s\n"), path, *icon);

  return TRUE;
}

static gboolean
validate_icon (const char *icon,
               GFile      *export,
               const char *app_id,
               GError    **error)
{
  g_autoptr(GFile) icondir = NULL;
  g_autofree char *png = NULL;
  g_autofree char *svg  = NULL;

  if (!icon)
    return TRUE;

  icondir = g_file_resolve_relative_path (export, "share/icons/hicolor");
  png = g_strconcat (icon, ".png", NULL);
  svg  = g_strconcat (icon, ".svg", NULL);
  if (!find_file_in_tree (icondir, png) &&
      !find_file_in_tree (icondir, svg))
    g_print (_("WARNING: Icon referenced in desktop file but not exported: %s\n"), icon);

  return TRUE;
}

static gboolean
validate_service_file (GFile      *service_file,
                       gboolean    activatable,
                       GFile      *files,
                       const char *app_id,
                       GError    **error)
{
  g_autofree char *path = g_file_get_path (service_file);
  g_autoptr(GKeyFile) key_file = NULL;
  g_autofree char *name = NULL;
  g_autofree char *command = NULL;
  g_auto(GStrv) argv = NULL;
  g_autoptr(GFile) bin_file = NULL;

  if (!g_file_query_exists (service_file, NULL))
    {
      if (activatable)
        {
          g_set_error (error,
                       G_IO_ERROR, G_IO_ERROR_FAILED,
                       "Desktop file D-Bus activatable, but service file not exported: %s", path);
          return FALSE;
        }

      return TRUE;
    }

  key_file = g_key_file_new ();
  if (!g_key_file_load_from_file (key_file, path, G_KEY_FILE_NONE, error))
    return FALSE;

  name = g_key_file_get_string (key_file, "D-BUS Service", "Name", error);
  if (!name)
    {
      g_prefix_error (error, "Invalid service file %s: ", path);
      return FALSE;
    }

  if (strcmp (name, app_id) != 0)
    {
      g_set_error (error,
                   G_IO_ERROR, G_IO_ERROR_FAILED,
                   "Name in service file %s does not match app id: %s", path, name);
      return FALSE;
    }

  command = g_key_file_get_string (key_file, "D-BUS Service", "Exec", error);
  if (!command)
    {
      g_prefix_error (error, "Invalid service file %s: ", path);
      return FALSE;
    }

  argv = g_strsplit (command, " ", 0);

  bin_file = convert_app_absolute_path (argv[0], files);
  if (!g_file_query_exists (bin_file, NULL))
    g_print (_("WARNING: Binary not found for Exec line in %s: %s\n"), path, command);

  return TRUE;
}

static gboolean
get_subsets (char **subsets, GVariant **out)
{
  g_autoptr(GVariantBuilder) builder = g_variant_builder_new (G_VARIANT_TYPE ("as"));
  gboolean found = FALSE;

  if (subsets == NULL)
    return FALSE;

  for (int i = 0; subsets[i] != NULL; i++)
    {
      const char *subset = subsets[i];
      if (*subset != 0)
        {
          found = TRUE;
          g_variant_builder_add (builder, "s", subset);
        }
    }

  if (!found)
    return FALSE;

  *out = g_variant_ref_sink (g_variant_builder_end (builder));
  return TRUE;
}

static gboolean
validate_exports (GFile *export, GFile *files, const char *app_id, GError **error)
{
  g_autofree char *desktop_path = NULL;
  g_autoptr(GFile) desktop_file = NULL;
  g_autofree char *service_path = NULL;
  g_autoptr(GFile) service_file = NULL;
  g_autofree char *icon = NULL;
  gboolean activatable = FALSE;

  desktop_path = g_strconcat ("share/applications/", app_id, ".desktop", NULL);
  desktop_file = g_file_resolve_relative_path (export, desktop_path);

  if (!validate_desktop_file (desktop_file, export, files, app_id, &icon, &activatable, error))
    return FALSE;

  if (!validate_icon (icon, export, app_id, error))
    return FALSE;

  if (!validate_exported_icons (export, app_id, error))
    return FALSE;

  service_path = g_strconcat ("share/dbus-1/services/", app_id, ".service", NULL);
  service_file = g_file_resolve_relative_path (export, service_path);

  if (!validate_service_file (service_file, activatable, files, app_id, error))
    return FALSE;

  return TRUE;
}

static gboolean
collect_extra_data (GKeyFile *metakey, GVariantDict *metadata_dict, GError **error)
{
  g_auto(GStrv) keys = NULL;
  g_autoptr(GVariantBuilder) extra_data_sources_builder = NULL;
  g_autoptr(GVariant) extra_data_sources = NULL;
  int i;

  keys = g_key_file_get_keys (metakey, "Extra Data", NULL, NULL);
  if (keys == NULL)
    return TRUE;

  extra_data_sources_builder = g_variant_builder_new (G_VARIANT_TYPE ("a(ayttays)"));

  for (i = 0; keys[i] != NULL; i++)
    {
      const char *key = keys[i];
      if (g_str_has_prefix (key, "uri"))
        {
          const char *suffix = key + 3;
          g_autofree char *uri = NULL;
          g_autofree char *checksum_key = NULL;
          g_autofree char *size_key = NULL;
          g_autofree char *installed_size_key = NULL;
          g_autofree char *name_key = NULL;
          g_autofree char *checksum = NULL;
          g_autofree char *name = NULL;
          guint64 size, installed_size;

          checksum_key = g_strconcat ("checksum", suffix, NULL);
          size_key = g_strconcat ("size", suffix, NULL);
          installed_size_key = g_strconcat ("installed-size", suffix, NULL);
          name_key = g_strconcat ("name", suffix, NULL);

          uri = g_key_file_get_string (metakey, "Extra Data", key, error);
          if (uri == NULL)
            return FALSE;

          if (!g_str_has_prefix (uri, "http:") &&
              !g_str_has_prefix (uri, "https:"))
            {
              g_set_error (error, G_KEY_FILE_ERROR,
                           G_KEY_FILE_ERROR_INVALID_VALUE,
                           _("Invalid uri type %s, only http/https supported"), uri);
              return FALSE;
            }

          if (g_key_file_has_key (metakey, "Extra Data", name_key, NULL))
            {
              name = g_key_file_get_string (metakey, "Extra Data", name_key, error);
              if (name == NULL)
                return FALSE;
            }
          else
            {
              g_autoptr(GFile) file = g_file_new_for_uri (uri);
              name = g_file_get_basename (file);
              if (name == NULL || *name == 0)
                {
                  g_set_error (error, G_KEY_FILE_ERROR,
                               G_KEY_FILE_ERROR_INVALID_VALUE,
                               _("Unable to find basename in %s, specify a name explicitly"), uri);
                  return FALSE;
                }
            }

          if (strchr (name, '/') != NULL)
            {
              g_set_error (error, G_KEY_FILE_ERROR,
                           G_KEY_FILE_ERROR_INVALID_VALUE,
                           _("No slashes allowed in extra data name"));
              return FALSE;
            }

          checksum = g_key_file_get_string (metakey, "Extra Data", checksum_key, error);
          if (checksum == NULL)
            return FALSE;

          if (!ostree_validate_checksum_string (checksum, NULL))
            {
              g_set_error (error, G_KEY_FILE_ERROR,
                           G_KEY_FILE_ERROR_INVALID_VALUE,
                           _("Invalid format for sha256 checksum: '%s'"), checksum);
              return FALSE;
            }

          size = g_key_file_get_uint64 (metakey, "Extra Data", size_key, error);
          if (size == 0)
            {
              if (error != NULL && *error == NULL)
                g_set_error (error, G_KEY_FILE_ERROR,
                             G_KEY_FILE_ERROR_INVALID_VALUE,
                             _("Extra data sizes of zero not supported"));
              return FALSE;
            }

          installed_size = g_key_file_get_uint64 (metakey, "Extra Data", installed_size_key, NULL);

          g_variant_builder_add (extra_data_sources_builder,
                                 "(^aytt@ay&s)",
                                 name, GUINT64_TO_BE (size), GUINT64_TO_BE (installed_size),
                                 ostree_checksum_to_bytes_v (checksum), uri);
        }
    }

  extra_data_sources = g_variant_ref_sink (g_variant_builder_end (extra_data_sources_builder));
  g_variant_dict_insert_value (metadata_dict, "xa.extra-data-sources", extra_data_sources);

  return TRUE;
}

gboolean
flatpak_builtin_build_export (int argc, char **argv, GCancellable *cancellable, GError **error)
{
  gboolean ret = FALSE;
  g_autoptr(GOptionContext) context = NULL;
  g_autoptr(GFile) base = NULL;
  g_autoptr(GFile) files = NULL;
  g_autoptr(GFile) usr = NULL;
  g_autoptr(GFile) metadata = NULL;
  g_autoptr(GFile) export = NULL;
  g_autoptr(GFile) repofile = NULL;
  g_autoptr(GFile) root = NULL;
  g_autoptr(OstreeRepo) repo = NULL;
  const char *location;
  const char *directory;
  const char *branch;
  g_autofree char *arch = NULL;
  g_autofree char *full_branch = NULL;
  g_autofree char *id = NULL;
  g_autofree char *parent = NULL;
  g_autofree char *commit_checksum = NULL;
  g_autofree char *metadata_contents = NULL;
  g_autofree char *format_size = NULL;
  g_autoptr(OstreeMutableTree) mtree = NULL;
  g_autoptr(OstreeMutableTree) files_mtree = NULL;
  g_autoptr(OstreeMutableTree) export_mtree = NULL;
  g_autoptr(GKeyFile) metakey = NULL;
  g_autoptr(GError) my_error = NULL;
  gsize metadata_size;
  g_autofree char *subject = NULL;
  g_autofree char *body = NULL;
  OstreeRepoTransactionStats stats;
  g_autoptr(OstreeRepoCommitModifier) modifier = NULL;
  CommitData commit_data = {0};
  g_auto(GVariantDict) metadata_dict = FLATPAK_VARIANT_DICT_INITIALIZER;
  g_autoptr(GVariant) metadata_dict_v = NULL;
  g_autoptr(GVariant) subsets_v = NULL;
  gboolean is_runtime = FALSE;
  gboolean is_extension = FALSE;
  guint64 installed_size = 0, download_size = 0;
  struct timespec ts;
  const char *collection_id;

  context = g_option_context_new (_("LOCATION DIRECTORY [BRANCH] - Create a repository from a build directory"));
  g_option_context_set_translation_domain (context, GETTEXT_PACKAGE);

  if (!flatpak_option_context_parse (context, options, &argc, &argv, FLATPAK_BUILTIN_FLAG_NO_DIR, NULL, cancellable, error))
    goto out;

  if (argc < 3)
    {
      usage_error (context, _("LOCATION and DIRECTORY must be specified"), error);
      goto out;
    }

  if (argc > 4)
    {
      usage_error (context, _("Too many arguments"), error);
      goto out;
    }

  location = argv[1];
  directory = argv[2];

  if (argc >= 4)
    branch = argv[3];
  else
    branch = "master";

  if (opt_collection_id != NULL &&
      !ostree_validate_collection_id (opt_collection_id, &my_error))
    {
      flatpak_fail (error, _("‘%s’ is not a valid collection ID: %s"), opt_collection_id, my_error->message);
      goto out;
    }

  if (!flatpak_is_valid_branch (branch, -1, &my_error))
    {
      flatpak_fail (error, _("'%s' is not a valid branch name: %s"), branch, my_error->message);
      goto out;
    }

  base = g_file_new_for_commandline_arg (directory);
  if (opt_files)
    files = g_file_resolve_relative_path (base, opt_files);
  else
    files = g_file_get_child (base, "files");
  if (opt_files)
    usr = g_file_resolve_relative_path (base, opt_files);
  else
    usr = g_file_get_child (base, "usr");
  if (opt_metadata)
    metadata = g_file_resolve_relative_path (base, opt_metadata);
  else
    metadata = g_file_get_child (base, "metadata");
  export = g_file_get_child (base, "export");

  if (!g_file_query_exists (files, cancellable) ||
      !g_file_query_exists (metadata, cancellable))
    {
      flatpak_fail (error, _("Build directory %s not initialized, use flatpak build-init"), directory);
      goto out;
    }

  if (!g_file_load_contents (metadata, cancellable, &metadata_contents, &metadata_size, NULL, error))
    goto out;

  metakey = g_key_file_new ();
  if (!g_key_file_load_from_data (metakey, metadata_contents, metadata_size, 0, error))
    goto out;

  id = g_key_file_get_string (metakey, "Application", "name", NULL);
  if (id == NULL)
    {
      id = g_key_file_get_string (metakey, "Runtime", "name", NULL);
      if (id == NULL)
        {
          flatpak_fail (error, _("No name specified in the metadata"));
          goto out;
        }
      is_runtime = TRUE;

      if (g_key_file_has_group (metakey, "ExtensionOf"))
        is_extension = TRUE;
    }

  if (!(opt_runtime || is_runtime) && !g_file_query_exists (export, cancellable))
    {
      flatpak_fail (error, "Build directory %s not finalized, use flatpak build-finish", directory);
      goto out;
    }

  g_variant_dict_init (&metadata_dict, NULL);

  if (!collect_extra_data (metakey, &metadata_dict, error))
    goto out;

  if (!(opt_runtime || is_runtime) &&
      !validate_exports (export, files, id, error))
    goto out;

  if (!metadata_get_arch (metadata, &arch, error))
    goto out;

  if (opt_subject)
    subject = g_strdup (opt_subject);
  else
    subject = g_strconcat ("Export ", id, NULL);
  if (opt_body)
    body = g_strdup (opt_body);
  else
    body = g_strdup_printf ("Name: %s\n"
                            "Arch: %s\n"
                            "Branch: %s\n"
                            "Built with: "PACKAGE_STRING "\n",
                            id, arch, branch);

  full_branch = g_strconcat ((opt_runtime || is_runtime) ? "runtime/" : "app/", id, "/", arch, "/", branch, NULL);

  repofile = g_file_new_for_commandline_arg (location);
  repo = ostree_repo_new (repofile);

  if (g_file_query_exists (repofile, cancellable) &&
      !is_empty_directory (repofile, cancellable))
    {
      const char *repo_collection_id;

      if (!ostree_repo_open (repo, cancellable, error))
        goto out;

      repo_collection_id = ostree_repo_get_collection_id (repo);
      if (!flatpak_repo_resolve_rev (repo, repo_collection_id, NULL, full_branch, TRUE,
                                     &parent, cancellable, error))
        goto out;

      if (opt_collection_id != NULL &&
          g_strcmp0 (repo_collection_id, opt_collection_id) != 0)
        {
          flatpak_fail (error, "Specified collection ID ‘%s’ doesn’t match collection ID in repository configuration ‘%s’.",
                        opt_collection_id, ostree_repo_get_collection_id (repo));
          goto out;
        }
    }
  else
    {
      if (opt_collection_id != NULL &&
          !ostree_repo_set_collection_id (repo, opt_collection_id, error))
        goto out;
      if (!ostree_repo_create (repo, OSTREE_REPO_MODE_ARCHIVE_Z2, cancellable, error))
        goto out;
    }

  if (opt_disable_fsync)
    ostree_repo_set_disable_fsync (repo, TRUE);

  /* Get the canonical collection ID which we’ll use for the commit. This might
   * be %NULL if the existing repo doesn’t have one and none was specified on
   * the command line. */
  collection_id = ostree_repo_get_collection_id (repo);

  if (!ostree_repo_prepare_transaction (repo, NULL, cancellable, error))
    goto out;

  /* This is useful only if the target is a "bare" rep, but this happens
     in flatpak-builder when committing to the cache repo. For other repos
     this is a no-op */
  if (!ostree_repo_scan_hardlinks (repo, cancellable, error))
    goto out;

  mtree = ostree_mutable_tree_new ();

  if (!flatpak_mtree_ensure_dir_metadata (repo, mtree, cancellable, error))
    goto out;

  if (!ostree_mutable_tree_ensure_dir (mtree, "files", &files_mtree, error))
    goto out;

  modifier = ostree_repo_commit_modifier_new (OSTREE_REPO_COMMIT_MODIFIER_FLAGS_SKIP_XATTRS,
                                              (OstreeRepoCommitFilter) commit_filter, &commit_data, NULL);

  if (is_extension)
    {
      commit_data.exclude = (const char **) opt_exclude;
      commit_data.include = (const char **) opt_include;
      if (!ostree_repo_write_directory_to_mtree (repo, files, files_mtree, modifier, cancellable, error))
        goto out;
      commit_data.exclude = NULL;
      commit_data.include = NULL;
    }
  else if (opt_runtime || is_runtime)
    {
      commit_data.exclude = (const char **) opt_exclude;
      commit_data.include = (const char **) opt_include;
      if (!ostree_repo_write_directory_to_mtree (repo, usr, files_mtree, modifier, cancellable, error))
        goto out;
      commit_data.exclude = NULL;
      commit_data.include = NULL;
    }
  else
    {
      commit_data.exclude = (const char **) opt_exclude;
      commit_data.include = (const char **) opt_include;
      if (!ostree_repo_write_directory_to_mtree (repo, files, files_mtree, modifier, cancellable, error))
        goto out;
      commit_data.exclude = NULL;
      commit_data.include = NULL;

      if (!ostree_mutable_tree_ensure_dir (mtree, "export", &export_mtree, error))
        goto out;

      if (!ostree_repo_write_directory_to_mtree (repo, export, export_mtree, modifier, cancellable, error))
        goto out;
    }

  if (!add_file_to_mtree (metadata, "metadata", repo, mtree, cancellable, error))
    goto out;

  if (!ostree_repo_write_mtree (repo, mtree, &root, cancellable, error))
    goto out;

  if (!flatpak_repo_collect_sizes (repo, root, &installed_size, &download_size, cancellable, error))
    goto out;

  /* Binding information. xa.ref is deprecated in favour of the OSTree keys, but
   * keep it around for backwards compatibility. */
  g_variant_dict_insert_value (&metadata_dict, "ostree.collection-binding",
                               g_variant_new_string ((collection_id != NULL) ? collection_id : ""));
  g_variant_dict_insert_value (&metadata_dict, "ostree.ref-binding",
                               g_variant_new_strv ((const gchar * const *) &full_branch, 1));
  g_variant_dict_insert_value (&metadata_dict, "xa.ref", g_variant_new_string (full_branch));

  g_variant_dict_insert_value (&metadata_dict, "xa.metadata", g_variant_new_string (metadata_contents));
  g_variant_dict_insert_value (&metadata_dict, "xa.installed-size", g_variant_new_uint64 (GUINT64_TO_BE (installed_size)));
  g_variant_dict_insert_value (&metadata_dict, "xa.download-size", g_variant_new_uint64 (GUINT64_TO_BE (download_size)));

  if (opt_endoflife && *opt_endoflife)
    g_variant_dict_insert_value (&metadata_dict, OSTREE_COMMIT_META_KEY_ENDOFLIFE,
                                 g_variant_new_string (opt_endoflife));

  if (opt_endoflife_rebase && *opt_endoflife_rebase)
    {
      g_auto(GStrv) full_ref_parts = g_strsplit (full_branch, "/", 0);
      g_autofree char *rebased_ref = g_build_filename (full_ref_parts[0], opt_endoflife_rebase, full_ref_parts[2], full_ref_parts[3], NULL);

      if (!flatpak_is_valid_name (opt_endoflife_rebase, -1, error))
        return glnx_prefix_error (error, "Invalid name in --end-of-life-rebase");

      g_variant_dict_insert_value (&metadata_dict, OSTREE_COMMIT_META_KEY_ENDOFLIFE_REBASE,
                                   g_variant_new_string (rebased_ref));
    }

  if (opt_token_type >= 0)
    g_variant_dict_insert_value (&metadata_dict, "xa.token-type",
                                 g_variant_new_int32 (GINT32_TO_LE (opt_token_type)));

  /* Skip "" subsets as they mean everything, so no  */
  if (get_subsets (opt_subsets, &subsets_v))
    g_variant_dict_insert_value (&metadata_dict, "xa.subsets", subsets_v);

  metadata_dict_v = g_variant_ref_sink (g_variant_dict_end (&metadata_dict));

  /* The timestamp is used for the commit metadata and AppStream data */
  if (opt_timestamp != NULL)
    {
      if (!parse_datetime (&ts, opt_timestamp, NULL))
        return flatpak_fail (error, _("Could not parse '%s'"), opt_timestamp);
    }

  if (opt_timestamp == NULL)
    {
      if (!ostree_repo_write_commit (repo, parent, subject, body, metadata_dict_v,
                                     OSTREE_REPO_FILE (root),
                                     &commit_checksum, cancellable, error))
        goto out;
    }
  else
    {
      if (!ostree_repo_write_commit_with_time (repo, parent, subject, body,
                                               metadata_dict_v,
                                               OSTREE_REPO_FILE (root),
                                               ts.tv_sec, &commit_checksum,
                                               cancellable, error))
        goto out;
    }

  if (opt_gpg_key_ids)
    {
      char **iter;

      for (iter = opt_gpg_key_ids; iter && *iter; iter++)
        {
          const char *keyid = *iter;

          if (!ostree_repo_sign_commit (repo,
                                        commit_checksum,
                                        keyid,
                                        opt_gpg_homedir,
                                        cancellable,
                                        error))
            goto out;
        }
    }

  if (collection_id != NULL)
    {
      OstreeCollectionRef ref = { (char *) collection_id, full_branch };
      ostree_repo_transaction_set_collection_ref (repo, &ref, commit_checksum);
    }
  else
    {
      ostree_repo_transaction_set_ref (repo, NULL, full_branch, commit_checksum);
    }

  if (!ostree_repo_commit_transaction (repo, &stats, cancellable, error))
    goto out;

  if (opt_update_appstream &&
      !flatpak_repo_generate_appstream (repo, (const char **) opt_gpg_key_ids, opt_gpg_homedir,
                                        (opt_timestamp != NULL) ? ts.tv_sec : 0, cancellable, error))
    return FALSE;

  if (!opt_no_update_summary)
    {
      FlatpakRepoUpdateFlags flags = FLATPAK_REPO_UPDATE_FLAG_NONE;

      if (opt_no_summary_index)
        flags |= FLATPAK_REPO_UPDATE_FLAG_DISABLE_INDEX;

      g_info ("Updating summary");
      if (!flatpak_repo_update (repo, flags,
                                (const char **) opt_gpg_key_ids,
                                opt_gpg_homedir,
                                cancellable,
                                error))
        goto out;
    }

  format_size = g_format_size (stats.content_bytes_written);

  g_print (_("Commit: %s\n"), commit_checksum);
  g_print (_("Metadata Total: %u\n"), stats.metadata_objects_total);
  g_print (_("Metadata Written: %u\n"), stats.metadata_objects_written);
  g_print (_("Content Total: %u\n"), stats.content_objects_total);
  g_print (_("Content Written: %u\n"), stats.content_objects_written);
  g_print (_("Content Bytes Written:"));
  g_print (" %" G_GUINT64_FORMAT " (%s)\n", stats.content_bytes_written, format_size);

  ret = TRUE;

out:
  if (repo)
    ostree_repo_abort_transaction (repo, cancellable, NULL);

  return ret;
}

gboolean
flatpak_complete_build_export (FlatpakCompletion *completion)
{
  g_autoptr(GOptionContext) context = NULL;

  context = g_option_context_new ("");

  if (!flatpak_option_context_parse (context, options, &completion->argc, &completion->argv,
                                     FLATPAK_BUILTIN_FLAG_NO_DIR, NULL, NULL, NULL))
    return FALSE;

  switch (completion->argc)
    {
    case 0:
    case 1: /* LOCATION */
      flatpak_complete_options (completion, global_entries);
      flatpak_complete_options (completion, options);

      flatpak_complete_dir (completion);
      break;

    case 2: /* DIR */
      flatpak_complete_dir (completion);
      break;
    }

  return TRUE;
}

===== ./app/flatpak-builtins-update.c =====
/* vi:set et sw=2 sts=2 cin cino=t0,f0,(0,{s,>2s,n-s,^-s,e-s:
 * Copyright © 2014 Red Hat, Inc
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Alexander Larsson <alexl@redhat.com>
 */

#include "config.h"

#include <locale.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

#include <glib/gi18n.h>

#include "libglnx.h"

#include "flatpak-builtins.h"
#include "flatpak-builtins-utils.h"
#include "flatpak-cli-transaction.h"
#include "flatpak-quiet-transaction.h"
#include "flatpak-utils-private.h"
#include "flatpak-error.h"

static char *opt_arch;
static char *opt_commit;
static char **opt_subpaths;
static char **opt_sideload_repos;
static gboolean opt_force_remove;
static gboolean opt_no_pull;
static gboolean opt_no_deploy;
static gboolean opt_no_related;
static gboolean opt_no_deps;
static gboolean opt_no_static_deltas;
static gboolean opt_runtime;
static gboolean opt_app;
static gboolean opt_appstream;
static gboolean opt_yes;
static gboolean opt_noninteractive;

static GOptionEntry options[] = {
  { "arch", 0, 0, G_OPTION_ARG_STRING, &opt_arch, N_("Arch to update for"), N_("ARCH") },
  { "commit", 0, 0, G_OPTION_ARG_STRING, &opt_commit, N_("Commit to deploy"), N_("COMMIT") },
  { "force-remove", 0, 0, G_OPTION_ARG_NONE, &opt_force_remove, N_("Remove old files even if running"), NULL },
  { "no-pull", 0, 0, G_OPTION_ARG_NONE, &opt_no_pull, N_("Don't pull, only update from local cache"), NULL },
  { "no-deploy", 0, 0, G_OPTION_ARG_NONE, &opt_no_deploy, N_("Don't deploy, only download to local cache"), NULL },
  { "no-related", 0, 0, G_OPTION_ARG_NONE, &opt_no_related, N_("Don't update related refs"), NULL},
  { "no-deps", 0, 0, G_OPTION_ARG_NONE, &opt_no_deps, N_("Don't verify/install runtime dependencies"), NULL },
  { "no-static-deltas", 0, 0, G_OPTION_ARG_NONE, &opt_no_static_deltas, N_("Don't use static deltas"), NULL },
  { "runtime", 0, 0, G_OPTION_ARG_NONE, &opt_runtime, N_("Look for runtime with the specified name"), NULL },
  { "app", 0, 0, G_OPTION_ARG_NONE, &opt_app, N_("Look for app with the specified name"), NULL },
  { "appstream", 0, 0, G_OPTION_ARG_NONE, &opt_appstream, N_("Update appstream for remote"), NULL },
  { "subpath", 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &opt_subpaths, N_("Only update this subpath"), N_("PATH") },
  { "assumeyes", 'y', 0, G_OPTION_ARG_NONE, &opt_yes, N_("Automatically answer yes for all questions"), NULL },
  { "noninteractive", 0, 0, G_OPTION_ARG_NONE, &opt_noninteractive, N_("Produce minimal output and don't ask questions"), NULL },
  /* Translators: A sideload is when you install from a local USB drive rather than the Internet. */
  { "sideload-repo", 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &opt_sideload_repos, N_("Use this local repo for sideloads"), N_("PATH") },
  { NULL }
};

gboolean
flatpak_builtin_update (int           argc,
                        char        **argv,
                        GCancellable *cancellable,
                        GError      **error)
{
  g_autoptr(GOptionContext) context = NULL;
  g_autoptr(GPtrArray) dirs = NULL;
  char **prefs = NULL;
  int i, j, k, n_prefs;
  const char *default_branch = NULL;
  FlatpakKinds kinds;
  g_autoptr(GPtrArray) transactions = NULL;
  gboolean has_updates;

  context = g_option_context_new (_("[REF…] - Update applications or runtimes"));
  g_option_context_set_translation_domain (context, GETTEXT_PACKAGE);

  if (!flatpak_option_context_parse (context, options, &argc, &argv,
                                     FLATPAK_BUILTIN_FLAG_ALL_DIRS | FLATPAK_BUILTIN_FLAG_OPTIONAL_REPO,
                                     &dirs, cancellable, error))
    return FALSE;

  if (opt_appstream)
    {
      if (!update_appstream (dirs, argc >= 2 ? argv[1] : NULL, opt_arch, 0, opt_noninteractive, cancellable, error))
        return FALSE;

      return TRUE;
    }

  if (opt_noninteractive)
    opt_yes = TRUE; /* Implied */

  prefs = &argv[1];
  n_prefs = argc - 1;

  /* Backwards compat for old "NAME [BRANCH]" argument version */
  if (argc == 3 && looks_like_branch (argv[2]))
    {
      default_branch = argv[2];
      n_prefs = 1;
    }

  /* It doesn't make sense to use the same commit for more than one thing */
  if (opt_commit && n_prefs != 1)
    return usage_error (context, _("With --commit, only one REF may be specified"), error);

  transactions = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref);

  /* Walk through the array backwards so we can safely remove */
  for (k = dirs->len; k > 0; k--)
    {
      FlatpakTransaction *transaction;

      FlatpakDir *dir = g_ptr_array_index (dirs, k - 1);
      OstreeRepo *repo = flatpak_dir_get_repo (dir);
      if (repo == NULL)
        {
          g_ptr_array_remove_index (dirs, k - 1);
          continue;
        }

      if (opt_noninteractive)
        transaction = flatpak_quiet_transaction_new (dir, error);
      else
        transaction = flatpak_cli_transaction_new (dir, opt_yes, FALSE, opt_arch != NULL, error);
      if (transaction == NULL)
        return FALSE;

      flatpak_transaction_set_no_pull (transaction, opt_no_pull);
      flatpak_transaction_set_no_deploy (transaction, opt_no_deploy);
      flatpak_transaction_set_disable_static_deltas (transaction, opt_no_static_deltas);
      flatpak_transaction_set_disable_dependencies (transaction, opt_no_deps);
      flatpak_transaction_set_disable_related (transaction, opt_no_related);
      if (opt_arch)
        flatpak_transaction_set_default_arch (transaction, opt_arch);

      if (!setup_sideload_repositories (transaction, opt_sideload_repos, cancellable, error))
        return FALSE;

      g_ptr_array_insert (transactions, 0, transaction);
    }

  kinds = flatpak_kinds_from_bools (opt_app, opt_runtime);

  if (!opt_noninteractive)
    g_print (_("Looking for updates…\n"));

  for (j = 0; j == 0 || j < n_prefs; j++)
    {
      const char *pref = NULL;
      FlatpakKinds matched_kinds;
      g_autofree char *match_id = NULL;
      g_autofree char *match_arch = NULL;
      g_autofree char *match_branch = NULL;
      gboolean found = FALSE;

      if (n_prefs == 0)
        {
          matched_kinds = kinds;
        }
      else
        {
          pref = prefs[j];
          if (!flatpak_split_partial_ref_arg (pref, kinds, opt_arch, default_branch,
                                              &matched_kinds, &match_id, &match_arch, &match_branch, error))
            return FALSE;
        }

      for (k = 0; k < dirs->len; k++)
        {
          FlatpakDir *dir = g_ptr_array_index (dirs, k);
          FlatpakTransaction *transaction = g_ptr_array_index (transactions, k);
          g_autoptr(GPtrArray) refs = NULL;

          refs = flatpak_dir_list_refs (dir, kinds, cancellable, error);
          if (refs == NULL)
            return FALSE;

          for (i = 0; i < refs->len; i++)
            {
              FlatpakDecomposed *ref = g_ptr_array_index (refs, i);

              if (match_id != NULL && !flatpak_decomposed_is_id (ref, match_id))
                continue;

              if (match_arch != NULL && !flatpak_decomposed_is_arch (ref, match_arch))
                continue;

              if (match_branch != NULL && !flatpak_decomposed_is_branch (ref, match_branch))
                continue;

              found = TRUE;
              if (flatpak_transaction_add_update (transaction, flatpak_decomposed_get_ref (ref),
                                                  (const char **) opt_subpaths, opt_commit, error))
                continue;

              if (g_error_matches (*error, FLATPAK_ERROR, FLATPAK_ERROR_REMOTE_NOT_FOUND))
                {
                  g_printerr (_("Unable to update %s: %s\n"), flatpak_decomposed_get_ref (ref), (*error)->message);
                  g_clear_error (error);
                }
              else
                {
                  return FALSE;
                }
            }
        }

      if (n_prefs > 0 && !found)
        {
          g_set_error (error, FLATPAK_ERROR, FLATPAK_ERROR_NOT_INSTALLED,
                       "%s not installed", pref);
          return FALSE;
        }
    }

  /* Add uninstall operations for any runtimes that are unused and EOL.
   * Strictly speaking these are not updates but "update" is the command people
   * run to keep their system maintained. It would be possible to do this in
   * the transaction that updates them to being EOL, but doing it here seems
   * more future-proof since we may want to use additional conditions to
   * determine if something is unused. See
   * https://github.com/flatpak/flatpak/issues/3799
   */
  if ((kinds & FLATPAK_KINDS_RUNTIME) && n_prefs == 0 && !opt_no_deps)
    {
      for (k = 0; k < dirs->len; k++)
        {
          FlatpakTransaction *transaction = g_ptr_array_index (transactions, k);
          flatpak_transaction_set_include_unused_uninstall_ops (transaction, TRUE);
        }
    }

  has_updates = FALSE;

  for (k = 0; k < dirs->len; k++)
    {
      FlatpakTransaction *transaction = g_ptr_array_index (transactions, k);

      if (flatpak_transaction_is_empty (transaction))
        continue;

      if (!flatpak_transaction_run (transaction, cancellable, error))
        {
          if (g_error_matches (*error, FLATPAK_ERROR, FLATPAK_ERROR_ABORTED))
            g_clear_error (error);  /* Don't report on stderr */

          return FALSE;
        }

      if (!flatpak_transaction_is_empty (transaction))
        has_updates = TRUE;
    }

  if (!has_updates)
    {
      g_print ("\n");
      g_print (_("Nothing to update.\n"));
    }

  if (n_prefs == 0)
    {
      if (!update_appstream (dirs, NULL, opt_arch, FLATPAK_APPSTREAM_TTL, opt_noninteractive, cancellable, error))
        return FALSE;
    }

  return TRUE;
}

gboolean
flatpak_complete_update (FlatpakCompletion *completion)
{
  g_autoptr(GOptionContext) context = NULL;
  g_autoptr(GPtrArray) dirs = NULL;
  FlatpakKinds kinds;
  int i;

  context = g_option_context_new ("");
  if (!flatpak_option_context_parse (context, options, &completion->argc, &completion->argv,
                                     FLATPAK_BUILTIN_FLAG_ALL_DIRS | FLATPAK_BUILTIN_FLAG_OPTIONAL_REPO,
                                     &dirs, NULL, NULL))
    return FALSE;

  kinds = flatpak_kinds_from_bools (opt_app, opt_runtime);

  switch (completion->argc)
    {
    case 0:
    default: /* REF */
      flatpak_complete_options (completion, global_entries);
      flatpak_complete_options (completion, options);
      flatpak_complete_options (completion, user_entries);

      for (i = 0; i < dirs->len; i++)
        {
          FlatpakDir *dir = g_ptr_array_index (dirs, i);
          flatpak_complete_partial_ref (completion, kinds, opt_arch, dir, NULL);
        }

      break;
    }

  return TRUE;
}

===== ./app/flatpak-builtins.h =====
/*
 * Copyright © 2014 Red Hat, Inc
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Alexander Larsson <alexl@redhat.com>
 */

#ifndef __FLATPAK_BUILTINS_H__
#define __FLATPAK_BUILTINS_H__

#include <ostree.h>
#include <gio/gio.h>

#include "flatpak-complete.h"
#include "flatpak-tty-utils-private.h"
#include "flatpak-utils-private.h"
#include "flatpak-dir-private.h"
#include "flatpak-dir-utils-private.h"
#include "flatpak-xml-utils-private.h"

G_BEGIN_DECLS

/**
 * FlatpakBuiltinFlags:
 * @FLATPAK_BUILTIN_FLAG_NO_DIR: Don't allow --user/--system/--installation and
 *    don't return any dir
 * @FLATPAK_BUILTIN_FLAG_OPTIONAL_REPO: Don't fail if we can't create an entire installation
 *    directory structure
 * @FLATPAK_BUILTIN_FLAG_ONE_DIR: Allow a single --user/--system/--installation option
 *    and return a single dir. If no option is specified, default to --system
 * @FLATPAK_BUILTIN_FLAG_STANDARD_DIRS: Allow repeated use of --user/--system/--installation
 *    and return multiple dirs. If no option is specified return system(default)+user.
 *    Implies %FLATPAK_BUILTIN_FLAG_OPTIONAL_REPO.
 * @FLATPAK_BUILTIN_FLAG_ALL_DIRS: Allow repeated use of --user/--system/--installation
 *    and return multiple dirs. If no option is specified, return all installations,
 *    starting with system(default)+user.
 *    Implies %FLATPAK_BUILTIN_FLAG_OPTIONAL_REPO.
 *
 * Flags affecting the behavior of flatpak_option_context_parse().
 *
 * If the default system installation is among the returned directories,
 * it will be returned first.
 */
typedef enum {
  FLATPAK_BUILTIN_FLAG_NO_DIR = 1 << 0,
  FLATPAK_BUILTIN_FLAG_OPTIONAL_REPO = 1 << 1,
  FLATPAK_BUILTIN_FLAG_ONE_DIR = 1 << 2,
  FLATPAK_BUILTIN_FLAG_STANDARD_DIRS = 1 << 3,
  FLATPAK_BUILTIN_FLAG_ALL_DIRS = 1 << 4,
} FlatpakBuiltinFlags;

gboolean flatpak_option_context_parse (GOptionContext     *context,
                                       const GOptionEntry *main_entries,
                                       int                *argc,
                                       char             ***argv,
                                       FlatpakBuiltinFlags flags,
                                       GPtrArray         **out_dirs,
                                       GCancellable       *cancellable,
                                       GError            **error);

extern GOptionEntry user_entries[];
extern GOptionEntry global_entries[];

gboolean usage_error (GOptionContext *context,
                      const char     *message,
                      GError        **error);

#define BUILTINPROTO(name) \
  gboolean flatpak_builtin_ ## name (int argc, char **argv, GCancellable * cancellable, GError **error); \
  gboolean flatpak_complete_ ## name (FlatpakCompletion * completion);


BUILTINPROTO (remote_add)
BUILTINPROTO (remote_modify)
BUILTINPROTO (remote_delete)
BUILTINPROTO (remote_ls)
BUILTINPROTO (remote_info)
BUILTINPROTO (remote_list)
BUILTINPROTO (install)
BUILTINPROTO (mask)
BUILTINPROTO (pin)
BUILTINPROTO (update)
BUILTINPROTO (make_current_app)
BUILTINPROTO (uninstall)
BUILTINPROTO (install_bundle)
BUILTINPROTO (list)
BUILTINPROTO (info)
BUILTINPROTO (run)
BUILTINPROTO (enter)
BUILTINPROTO (ps)
BUILTINPROTO (build_init)
BUILTINPROTO (build)
BUILTINPROTO (build_finish)
BUILTINPROTO (build_sign)
BUILTINPROTO (build_export)
BUILTINPROTO (build_bundle)
BUILTINPROTO (build_import)
BUILTINPROTO (build_commit_from)
BUILTINPROTO (build_update_repo)
BUILTINPROTO (document_export)
BUILTINPROTO (document_unexport)
BUILTINPROTO (document_info)
BUILTINPROTO (document_list)
BUILTINPROTO (permission_remove)
BUILTINPROTO (permission_set)
BUILTINPROTO (permission_list)
BUILTINPROTO (permission_show)
BUILTINPROTO (permission_reset)
BUILTINPROTO (override)
BUILTINPROTO (repo)
BUILTINPROTO (config)
BUILTINPROTO (search)
BUILTINPROTO (repair)
BUILTINPROTO (create_usb)
BUILTINPROTO (kill)
BUILTINPROTO (history)
BUILTINPROTO (preinstall)

#undef BUILTINPROTO

G_END_DECLS

#endif /* __FLATPAK_BUILTINS_H__ */

===== ./app/flatpak-builtins-build-update-repo.c =====
/* vi:set et sw=2 sts=2 cin cino=t0,f0,(0,{s,>2s,n-s,^-s,e-s:
 * Copyright © 2014-2019 Red Hat, Inc
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Alexander Larsson <alexl@redhat.com>
 */

#include "config.h"

#include <locale.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

#include <glib/gi18n.h>

#include "libglnx.h"

#include "flatpak-builtins.h"
#include "flatpak-repo-utils-private.h"
#include "flatpak-utils-base-private.h"
#include "flatpak-builtins-utils.h"
#include "flatpak-prune-private.h"

static char *opt_title;
static char *opt_comment;
static char *opt_description;
static char *opt_homepage;
static char *opt_icon;
static char *opt_redirect_url;
static char *opt_default_branch;
static char *opt_collection_id = NULL;
static gboolean opt_deploy_sideload_collection_id = FALSE;
static gboolean opt_deploy_collection_id = FALSE;
static gboolean opt_no_summary_index = FALSE;
static char **opt_gpg_import;
static char *opt_generate_delta_from;
static char *opt_generate_delta_to;
static char *opt_generate_delta_ref;
static char *opt_gpg_homedir;
static char **opt_gpg_key_ids;
static gboolean opt_prune;
static gboolean opt_prune_dry_run;
static gboolean opt_generate_deltas;
static gboolean opt_no_update_appstream;
static gboolean opt_no_update_summary;
static gint opt_prune_depth = -1;
static gint opt_static_delta_jobs;
static char **opt_static_delta_ignore_refs;
static char *opt_authenticator_name = NULL;
static gboolean opt_authenticator_install = -1;
static char **opt_authenticator_options = NULL;

static GOptionEntry options[] = {
  { "redirect-url", 0, 0, G_OPTION_ARG_STRING, &opt_redirect_url, N_("Redirect this repo to a new URL"), N_("URL") },
  { "title", 0, 0, G_OPTION_ARG_STRING, &opt_title, N_("A nice name to use for this repository"), N_("TITLE") },
  { "comment", 0, 0, G_OPTION_ARG_STRING, &opt_comment, N_("A one-line comment for this repository"), N_("COMMENT") },
  { "description", 0, 0, G_OPTION_ARG_STRING, &opt_description, N_("A full-paragraph description for this repository"), N_("DESCRIPTION") },
  { "homepage", 0, 0, G_OPTION_ARG_STRING, &opt_homepage, N_("URL for a website for this repository"), N_("URL") },
  { "icon", 0, 0, G_OPTION_ARG_STRING, &opt_icon, N_("URL for an icon for this repository"), N_("URL") },
  { "default-branch", 0, 0, G_OPTION_ARG_STRING, &opt_default_branch, N_("Default branch to use for this repository"), N_("BRANCH") },
  { "collection-id", 0, 0, G_OPTION_ARG_STRING, &opt_collection_id, N_("Collection ID"), N_("COLLECTION-ID") },
  /* Translators: A sideload is when you install from a local USB drive rather than the Internet. */
  { "deploy-sideload-collection-id", 0, 0, G_OPTION_ARG_NONE, &opt_deploy_sideload_collection_id, N_("Permanently deploy collection ID to client remote configurations, only for sideload support"), NULL },
  { "deploy-collection-id", 0, 0, G_OPTION_ARG_NONE, &opt_deploy_collection_id, N_("Permanently deploy collection ID to client remote configurations"), NULL },
  { "authenticator-name", 0, 0, G_OPTION_ARG_STRING, &opt_authenticator_name, N_("Name of authenticator for this repository"), N_("NAME") },
  { "authenticator-install", 0, 0, G_OPTION_ARG_NONE, &opt_authenticator_install, N_("Autoinstall authenticator for this repository"), NULL },
  { "no-authenticator-install", 0, G_OPTION_FLAG_REVERSE, G_OPTION_ARG_NONE, &opt_authenticator_install, N_("Don't autoinstall authenticator for this repository"), NULL },
  { "authenticator-option", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_authenticator_options, N_("Authenticator option"), N_("KEY=VALUE") },
  { "gpg-import", 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &opt_gpg_import, N_("Import new default GPG public key from FILE"), N_("FILE") },
  { "gpg-sign", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_gpg_key_ids, N_("GPG Key ID to sign the summary with"), N_("KEY-ID") },
  { "gpg-homedir", 0, 0, G_OPTION_ARG_STRING, &opt_gpg_homedir, N_("GPG Homedir to use when looking for keyrings"), N_("HOMEDIR") },
  { "generate-static-deltas", 0, 0, G_OPTION_ARG_NONE, &opt_generate_deltas, N_("Generate delta files"), NULL },
  { "no-update-summary", 0, 0, G_OPTION_ARG_NONE, &opt_no_update_summary, N_("Don't update the summary"), NULL },
  { "no-update-appstream", 0, 0, G_OPTION_ARG_NONE, &opt_no_update_appstream, N_("Don't update the appstream branch"), NULL },
  { "static-delta-jobs", 0, 0, G_OPTION_ARG_INT, &opt_static_delta_jobs, N_("Max parallel jobs when creating deltas (default: NUMCPUs)"), N_("NUM-JOBS") },
  { "static-delta-ignore-ref", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_static_delta_ignore_refs, N_("Don't create deltas matching refs"), N_("PATTERN") },
  { "prune", 0, 0, G_OPTION_ARG_NONE, &opt_prune, N_("Prune unused objects"), NULL },
  { "prune-dry-run", 0, 0, G_OPTION_ARG_NONE, &opt_prune_dry_run, N_("Prune but don't actually remove anything"), NULL },
  { "prune-depth", 0, 0, G_OPTION_ARG_INT, &opt_prune_depth, N_("Only traverse DEPTH parents for each commit (default: -1=infinite)"), N_("DEPTH") },
  { "generate-static-delta-from", 0, G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_STRING, &opt_generate_delta_from, NULL, NULL },
  { "generate-static-delta-to", 0, G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_STRING, &opt_generate_delta_to, NULL, NULL },
  { "generate-static-delta-ref", 0, G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_STRING, &opt_generate_delta_ref, NULL, NULL },
  { "no-summary-index", 0, 0, G_OPTION_ARG_NONE, &opt_no_summary_index, N_("Don't generate a summary index"), NULL },
  { NULL }
};

static void
_ostree_parse_delta_name (const char *delta_name,
                          char      **out_from,
                          char      **out_to)
{
  g_auto(GStrv) parts = g_strsplit (delta_name, "-", 2);

  if (parts[0] && parts[1])
    {
      *out_from = g_steal_pointer (&parts[0]);
      *out_to = g_steal_pointer (&parts[1]);
    }
  else
    {
      *out_from = NULL;
      *out_to = g_steal_pointer (&parts[0]);
    }
}

static char *
_ostree_get_relative_static_delta_path (const char *from,
                                        const char *to,
                                        const char *target)
{
  guint8 csum_to[OSTREE_SHA256_DIGEST_LEN];
  char to_b64[44];
  guint8 csum_to_copy[OSTREE_SHA256_DIGEST_LEN];
  GString *ret = g_string_new ("deltas/");

  ostree_checksum_inplace_to_bytes (to, csum_to);
  ostree_checksum_b64_inplace_from_bytes (csum_to, to_b64);
  ostree_checksum_b64_inplace_to_bytes (to_b64, csum_to_copy);

  g_assert (memcmp (csum_to, csum_to_copy, OSTREE_SHA256_DIGEST_LEN) == 0);

  if (from != NULL)
    {
      guint8 csum_from[OSTREE_SHA256_DIGEST_LEN];
      char from_b64[44];

      ostree_checksum_inplace_to_bytes (from, csum_from);
      ostree_checksum_b64_inplace_from_bytes (csum_from, from_b64);

      g_string_append_c (ret, from_b64[0]);
      g_string_append_c (ret, from_b64[1]);
      g_string_append_c (ret, '/');
      g_string_append (ret, from_b64 + 2);
      g_string_append_c (ret, '-');
    }

  g_string_append_c (ret, to_b64[0]);
  g_string_append_c (ret, to_b64[1]);
  if (from == NULL)
    g_string_append_c (ret, '/');
  g_string_append (ret, to_b64 + 2);

  if (target != NULL)
    {
      g_string_append_c (ret, '/');
      g_string_append (ret, target);
    }

  return g_string_free (ret, FALSE);
}

static gboolean
_ostree_repo_static_delta_delete (OstreeRepo   *self,
                                  const char   *delta_id,
                                  GCancellable *cancellable,
                                  GError      **error)
{
  gboolean ret = FALSE;
  g_autofree char *from = NULL;
  g_autofree char *to = NULL;
  g_autofree char *deltadir = NULL;
  struct stat buf;
  int repo_dir_fd = ostree_repo_get_dfd (self);

  _ostree_parse_delta_name (delta_id, &from, &to);
  deltadir = _ostree_get_relative_static_delta_path (from, to, NULL);

  if (fstatat (repo_dir_fd, deltadir, &buf, 0) != 0)
    {
      if (errno == ENOENT)
        g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND,
                     "Can't find delta %s", delta_id);
      else
        glnx_set_error_from_errno (error);

      goto out;
    }

  if (!glnx_shutil_rm_rf_at (repo_dir_fd, deltadir,
                             cancellable, error))
    goto out;

  ret = TRUE;
out:
  return ret;
}

static gboolean
generate_one_delta (OstreeRepo   *repo,
                    const char   *from,
                    const char   *to,
                    const char   *ref,
                    GCancellable *cancellable,
                    GError      **error)
{
  g_autoptr(GVariantBuilder) parambuilder = NULL;
  g_autoptr(GVariant) params = NULL;

  parambuilder = g_variant_builder_new (G_VARIANT_TYPE ("a{sv}"));
  /* Fall back for 1 meg files */
  g_variant_builder_add (parambuilder, "{sv}",
                         "min-fallback-size", g_variant_new_uint32 (1));
  params = g_variant_ref_sink (g_variant_builder_end (parambuilder));

  if (ref == NULL)
    ref = "";

  if (from == NULL)
    g_print (_("Generating delta: %s (%.10s)\n"), ref, to);
  else
    g_print (_("Generating delta: %s (%.10s-%.10s)\n"), ref, from, to);

  if (!ostree_repo_static_delta_generate (repo, OSTREE_STATIC_DELTA_GENERATE_OPT_MAJOR,
                                          from, to, NULL,
                                          params,
                                          cancellable, error))
    {
      if (from == NULL)
        g_prefix_error (error, _("Failed to generate delta %s (%.10s): "),
                        ref, to);
      else
        g_prefix_error (error, _("Failed to generate delta %s (%.10s-%.10s): "),
                        ref, from, to);
      return FALSE;
    }

  return TRUE;
}


static void
delta_generation_done (GObject      *source_object,
                       GAsyncResult *result,
                       gpointer      user_data)
{
  int *n_spawned_delta_generate = user_data;

  (*n_spawned_delta_generate)--;
}

static gboolean
spawn_delta_generation (GMainContext *context,
                        int          *n_spawned_delta_generate,
                        OstreeRepo   *repo,
                        GVariant     *params,
                        const char   *ref,
                        const char   *from,
                        const char   *to,
                        GError      **error)
{
  g_autoptr(GSubprocessLauncher) launcher = g_subprocess_launcher_new (0);
  g_autoptr(GSubprocess) subprocess = NULL;
  const char *argv[] = {
    "/proc/self/exe",
    "build-update-repo",
    "--generate-static-delta-ref",
    ref,
    "--generate-static-delta-to",
    to,
    NULL, NULL, NULL, NULL
  };
  int i = 6;
  g_autofree char *exe = NULL;

  exe = flatpak_readlink ("/proc/self/exe", NULL);
  if (exe)
    argv[0] = exe;

  if (from)
    {
      argv[i++] = "--generate-static-delta-from";
      argv[i++] = from;
    }

  argv[i++] = flatpak_file_get_path_cached (ostree_repo_get_path (repo));
  argv[i++] = NULL;

  g_assert (i <= G_N_ELEMENTS (argv));

  while (*n_spawned_delta_generate >= opt_static_delta_jobs)
    g_main_context_iteration (context, TRUE);

  subprocess = g_subprocess_launcher_spawnv (launcher, argv, error);
  if (subprocess == NULL)
    return FALSE;

  (*n_spawned_delta_generate)++;

  g_subprocess_wait_async (subprocess, NULL, delta_generation_done, n_spawned_delta_generate);

  return TRUE;
}

static gboolean
generate_all_deltas (OstreeRepo   *repo,
                     GPtrArray   **unwanted_deltas,
                     GCancellable *cancellable,
                     GError      **error)
{
  g_autoptr(GHashTable) all_refs = NULL;
  g_autoptr(GHashTable) all_deltas_hash = NULL;
  g_autoptr(GHashTable) wanted_deltas_hash = NULL;
  g_autoptr(GPtrArray) all_deltas = NULL;
  int i;
  GHashTableIter iter;
  gpointer key, value;
  g_autoptr(GVariantBuilder) parambuilder = NULL;
  g_autoptr(GVariant) params = NULL;
  int n_spawned_delta_generate = 0;
  g_autoptr(GMainContextPopDefault) context = NULL;
  g_autoptr(GPtrArray) ignore_patterns = g_ptr_array_new_with_free_func ((GDestroyNotify)g_pattern_spec_free);

  g_print ("Generating static deltas\n");

  parambuilder = g_variant_builder_new (G_VARIANT_TYPE ("a{sv}"));
  /* Fall back for 1 meg files */
  g_variant_builder_add (parambuilder, "{sv}",
                         "min-fallback-size", g_variant_new_uint32 (1));
  params = g_variant_ref_sink (g_variant_builder_end (parambuilder));

  if (!ostree_repo_list_static_delta_names (repo, &all_deltas,
                                            cancellable, error))
    return FALSE;

  wanted_deltas_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);

  all_deltas_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
  for (i = 0; i < all_deltas->len; i++)
    g_hash_table_insert (all_deltas_hash,
                         g_strdup (g_ptr_array_index (all_deltas, i)),
                         NULL);

  if (!ostree_repo_list_refs (repo, NULL, &all_refs,
                              cancellable, error))
    return FALSE;

  context = flatpak_main_context_new_default ();

  if (opt_static_delta_ignore_refs != NULL)
    {
      for (i = 0; opt_static_delta_ignore_refs[i] != NULL; i++)
        g_ptr_array_add (ignore_patterns,
                         g_pattern_spec_new (opt_static_delta_ignore_refs[i]));
    }

  g_hash_table_iter_init (&iter, all_refs);
  while (g_hash_table_iter_next (&iter, &key, &value))
    {
      const char *ref = key;
      const char *commit = value;
      g_autoptr(GVariant) variant = NULL;
      g_autoptr(GVariant) parent_variant = NULL;
      g_autofree char *parent_commit = NULL;
      g_autofree char *grandparent_commit = NULL;
      gboolean ignore_ref = FALSE;

      if (g_str_has_prefix (ref, "app/") || g_str_has_prefix (ref, "runtime/"))
        {
          g_auto(GStrv) parts = g_strsplit (ref, "/", 4);

          for (i = 0; i < ignore_patterns->len; i++)
            {
              GPatternSpec *pattern = g_ptr_array_index(ignore_patterns, i);
              if (g_pattern_match_string (pattern, parts[1]))
                {
                  ignore_ref = TRUE;
                  break;
                }
            }

        }
      else if (g_str_has_prefix (ref, "appstream/"))
        {
          /* Old appstream branch deltas poorly, and most users handle the new format */
          ignore_ref = TRUE;
        }
      else if (g_str_has_prefix (ref, "appstream2/"))
        {
          /* Always delta this */
          ignore_ref = FALSE;
        }
      else
        {
          /* Ignore unknown ref types */
          ignore_ref = TRUE;
        }

      if (ignore_ref)
        {
          g_info ("Ignoring deltas for ref %s", ref);
          continue;
        }

      if (!ostree_repo_load_variant (repo, OSTREE_OBJECT_TYPE_COMMIT, commit,
                                     &variant, NULL))
        {
          g_warning ("Couldn't load commit %s", commit);
          continue;
        }

      /* From empty */
      if (!g_hash_table_contains (all_deltas_hash, commit))
        {
          if (!spawn_delta_generation (context, &n_spawned_delta_generate, repo, params,
                                       ref, NULL, commit,
                                       error))
            return FALSE;
        }

      /* Mark this one as wanted */
      g_hash_table_insert (wanted_deltas_hash, g_strdup (commit), GINT_TO_POINTER (1));

      parent_commit = ostree_commit_get_parent (variant);

      if (parent_commit != NULL &&
          !ostree_repo_load_variant (repo, OSTREE_OBJECT_TYPE_COMMIT, parent_commit,
                                     &parent_variant, NULL))
        {
          g_warning ("Couldn't load parent commit %s", parent_commit);
          continue;
        }

      /* From parent */
      if (parent_variant != NULL)
        {
          g_autofree char *from_parent = g_strdup_printf ("%s-%s", parent_commit, commit);

          if (!g_hash_table_contains (all_deltas_hash, from_parent))
            {
              if (!spawn_delta_generation (context, &n_spawned_delta_generate, repo, params,
                                           ref, parent_commit, commit,
                                           error))
                return FALSE;
            }

          /* Mark parent-to-current as wanted */
          g_hash_table_insert (wanted_deltas_hash, g_strdup (from_parent), GINT_TO_POINTER (1));

          /* We also want to keep around the parent and the grandparent-to-parent deltas
           * because otherwise these will be deleted immediately which may cause a race if
           * someone is currently downloading them.
           * However, there is no need to generate these if they don't exist.
           */

          g_hash_table_insert (wanted_deltas_hash, g_strdup (parent_commit), GINT_TO_POINTER (1));
          grandparent_commit = ostree_commit_get_parent (parent_variant);
          if (grandparent_commit != NULL)
            g_hash_table_insert (wanted_deltas_hash,
                                 g_strdup_printf ("%s-%s", grandparent_commit, parent_commit),
                                 GINT_TO_POINTER (1));
        }
    }

  while (n_spawned_delta_generate > 0)
    g_main_context_iteration (context, TRUE);

  *unwanted_deltas = g_ptr_array_new_with_free_func (g_free);
  for (i = 0; i < all_deltas->len; i++)
    {
      const char *delta = g_ptr_array_index (all_deltas, i);
      if (!g_hash_table_contains (wanted_deltas_hash, delta))
        g_ptr_array_add (*unwanted_deltas, g_strdup (delta));
    }

  return TRUE;
}

gboolean
flatpak_builtin_build_update_repo (int argc, char **argv,
                                   GCancellable *cancellable, GError **error)
{
  g_autoptr(GOptionContext) context = NULL;
  g_autoptr(GFile) repofile = NULL;
  g_autoptr(OstreeRepo) repo = NULL;
  const char *location;
  g_autoptr(GPtrArray) unwanted_deltas = NULL;

  context = g_option_context_new (_("LOCATION - Update repository metadata"));
  g_option_context_set_translation_domain (context, GETTEXT_PACKAGE);

  if (!flatpak_option_context_parse (context, options, &argc, &argv, FLATPAK_BUILTIN_FLAG_NO_DIR, NULL, cancellable, error))
    return FALSE;

  if (argc < 2)
    return usage_error (context, _("LOCATION must be specified"), error);

  if (opt_static_delta_jobs <= 0)
    opt_static_delta_jobs = g_get_num_processors ();

  location = argv[1];

  repofile = g_file_new_for_commandline_arg (location);
  repo = ostree_repo_new (repofile);

  if (!ostree_repo_open (repo, cancellable, error))
    return FALSE;

  if (opt_generate_delta_to)
    {
      if (!generate_one_delta (repo, opt_generate_delta_from, opt_generate_delta_to, opt_generate_delta_ref, cancellable, error))
        return FALSE;
      return TRUE;
    }

  if (opt_title &&
      !flatpak_repo_set_title (repo, opt_title[0] ? opt_title : NULL, error))
    return FALSE;

  if (opt_comment &&
      !flatpak_repo_set_comment (repo, opt_comment[0] ? opt_comment : NULL, error))
    return FALSE;

  if (opt_description &&
      !flatpak_repo_set_description (repo, opt_description[0] ? opt_description : NULL, error))
    return FALSE;

  if (opt_homepage &&
      !flatpak_repo_set_homepage (repo, opt_homepage[0] ? opt_homepage : NULL, error))
    return FALSE;

  if (opt_icon &&
      !flatpak_repo_set_icon (repo, opt_icon[0] ? opt_icon : NULL, error))
    return FALSE;

  if (opt_redirect_url &&
      !flatpak_repo_set_redirect_url (repo, opt_redirect_url[0] ? opt_redirect_url : NULL, error))
    return FALSE;

  if (opt_default_branch &&
      !flatpak_repo_set_default_branch (repo, opt_default_branch[0] ? opt_default_branch : NULL, error))
    return FALSE;

  if (opt_authenticator_name &&
      !flatpak_repo_set_authenticator_name (repo, opt_authenticator_name[0] ? opt_authenticator_name : NULL, error))
    return FALSE;

  if (opt_authenticator_install != -1 &&
      !flatpak_repo_set_authenticator_install (repo, opt_authenticator_install, error))
    return FALSE;

  if (opt_authenticator_options)
    {
      for (int i = 0; opt_authenticator_options[i] != NULL; i++)
        {
          g_auto(GStrv) split = g_strsplit (opt_authenticator_options[i], "=", 2);
          const char *key = split[0];
          const char *value = NULL;

          if (split[0] != NULL && split[1] != NULL && *split[1] != 0)
            value = split[1];

          if (!flatpak_repo_set_authenticator_option (repo, key, value, error))
            return FALSE;
        }
    }

  if (opt_collection_id != NULL)
    {
      /* Only allow a transition from no collection ID to a non-empty collection ID.
       * Changing the collection ID between two different non-empty values is too
       * dangerous: it will break all clients who have previously pulled from the repository.
       * Require the user to recreate the repository from scratch in that case. */
      const char *old_collection_id = ostree_repo_get_collection_id (repo);
      const char *new_collection_id = opt_collection_id[0] ? opt_collection_id : NULL;

      if (old_collection_id != NULL &&
          g_strcmp0 (old_collection_id, new_collection_id) != 0)
        return flatpak_fail (error, "The collection ID of an existing repository cannot be changed. "
                                    "Recreate the repository to change or clear its collection ID.");

      if (!flatpak_repo_set_collection_id (repo, new_collection_id, error))
        return FALSE;
    }

  if (opt_deploy_sideload_collection_id &&
      !flatpak_repo_set_deploy_sideload_collection_id (repo, TRUE, error))
    return FALSE;

  if (opt_deploy_collection_id &&
      !flatpak_repo_set_deploy_collection_id (repo, TRUE, error))
    return FALSE;

  if (opt_gpg_import)
    {
      g_autoptr(GBytes) gpg_data = flatpak_load_gpg_keys (opt_gpg_import, cancellable, error);
      if (gpg_data == NULL)
        return FALSE;

      if (!flatpak_repo_set_gpg_keys (repo, gpg_data, error))
        return FALSE;
    }

  if (!opt_no_update_appstream)
    {
      g_print (_("Updating appstream branch\n"));
      if (!flatpak_repo_generate_appstream (repo, (const char **) opt_gpg_key_ids, opt_gpg_homedir, 0, cancellable, error))
        return FALSE;
    }

  if (opt_generate_deltas &&
      !generate_all_deltas (repo, &unwanted_deltas, cancellable, error))
    return FALSE;

  if (unwanted_deltas != NULL)
    {
      int i;
      for (i = 0; i < unwanted_deltas->len; i++)
        {
          const char *delta = g_ptr_array_index (unwanted_deltas, i);
          g_print ("Deleting unwanted delta: %s\n", delta);
          g_autoptr(GError) my_error = NULL;
          if (!_ostree_repo_static_delta_delete (repo, delta, cancellable, &my_error))
            g_printerr ("Unable to delete delta %s: %s\n", delta, my_error->message);
        }
    }

  if (!opt_no_update_summary)
    {
      FlatpakRepoUpdateFlags flags = FLATPAK_REPO_UPDATE_FLAG_NONE;

      if (opt_no_summary_index)
        flags |= FLATPAK_REPO_UPDATE_FLAG_DISABLE_INDEX;

      g_print (_("Updating summary\n"));
      if (!flatpak_repo_update (repo, flags, (const char **) opt_gpg_key_ids, opt_gpg_homedir, cancellable, error))
        return FALSE;
    }

  if (opt_prune || opt_prune_dry_run)
    {
      gint n_objects_total;
      gint n_objects_pruned;
      guint64 objsize_total;
      g_autofree char *formatted_freed_size = NULL;

      if (opt_prune_dry_run)
        g_print ("Pruning old commits (dry-run)\n");
      else
        g_print ("Pruning old commits\n");
      if (!flatpak_repo_prune (repo, opt_prune_depth, opt_prune_dry_run,
                              &n_objects_total, &n_objects_pruned, &objsize_total,
                              cancellable, error))
        return FALSE;


      if (!opt_prune_dry_run)
        {
          formatted_freed_size = g_format_size_full (objsize_total, 0);

          g_print (_("Total objects: %u\n"), n_objects_total);
          if (n_objects_pruned == 0)
            g_print (_("No unreachable objects\n"));
          else
            g_print (_("Deleted %u objects, %s freed\n"),
                    n_objects_pruned, formatted_freed_size);
      }
    }

  return TRUE;
}


gboolean
flatpak_complete_build_update_repo (FlatpakCompletion *completion)
{
  g_autoptr(GOptionContext) context = NULL;

  context = g_option_context_new ("");

  if (!flatpak_option_context_parse (context, options, &completion->argc, &completion->argv,
                                     FLATPAK_BUILTIN_FLAG_NO_DIR, NULL, NULL, NULL))
    return FALSE;

  switch (completion->argc)
    {
    case 0:
    case 1: /* LOCATION */
      flatpak_complete_options (completion, global_entries);
      flatpak_complete_options (completion, options);

      flatpak_complete_dir (completion);
      break;
    }

  return TRUE;
}

===== ./app/flatpak-builtins-permission-reset.c =====
/* vi:set et sw=2 sts=2 cin cino=t0,f0,(0,{s,>2s,n-s,^-s,e-s:
 * Copyright © 2018 Red Hat, Inc
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Matthias Clasen <mclasen@redhat.com>
 */

#include "config.h"

#include <locale.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>

#include <glib/gi18n.h>

#include "libglnx.h"
#include "flatpak-permission-dbus-generated.h"

#include "flatpak-builtins.h"
#include "flatpak-builtins-utils.h"
#include "flatpak-table-printer.h"
#include "flatpak-utils-private.h"
#include "flatpak-run-private.h"

static gboolean opt_all;

static GOptionEntry options[] = {
  { "all", 0, 0, G_OPTION_ARG_NONE, &opt_all, N_("Reset all permissions"), NULL },
  { NULL }
};

static gboolean
remove_for_app (XdpDbusPermissionStore *store,
                const char             *table,
                const char             *app_id,
                GError                **error)
{
  char **ids;
  int i;

  /* FIXME some portals cache their permission tables and assume that they're
   * the only writers, so they may miss these changes.
   * See https://github.com/flatpak/xdg-desktop-portal/issues/197
   */

  if (!xdp_dbus_permission_store_call_list_sync (store, table, &ids, NULL, error))
    return FALSE;

  for (i = 0; ids[i]; i++)
    {
      g_autoptr(GVariant) permissions = NULL;
      g_autoptr(GVariant) data = NULL;
      GVariantIter iter;
      char *key;
      GVariant *value;
      g_auto(GVariantBuilder) builder = FLATPAK_VARIANT_BUILDER_INITIALIZER;
      gboolean need_to_set = FALSE;

      g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sas}"));

      if (!xdp_dbus_permission_store_call_lookup_sync (store, table, ids[i],
                                                       &permissions, &data,
                                                       NULL, error))
        return FALSE;

      g_variant_iter_init (&iter, permissions);
      while (g_variant_iter_loop (&iter, "{s@as}", &key, &value))
        {
          if (app_id == NULL || strcmp (key, app_id) == 0)
            {
              need_to_set = TRUE;
              continue;
            }

          g_variant_builder_add (&builder, "{s@as}", key, value);
        }

      if (need_to_set)
        {
          if (!xdp_dbus_permission_store_call_set_sync (store, table, TRUE, ids[i],
                                                        g_variant_builder_end (&builder),
                                                        data ? data : g_variant_new_byte (0),
                                                        NULL, error))
            return FALSE;
        }
    }

  return TRUE;
}

gboolean
reset_permissions_for_app (const char *app_id,
                           GError    **error)
{
  g_autoptr(GDBusConnection) session_bus = NULL;
  XdpDbusPermissionStore *store = NULL;
  int i;
  g_auto(GStrv) tables = NULL;

  session_bus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, error);
  if (session_bus == NULL)
    return FALSE;

  store = xdp_dbus_permission_store_proxy_new_sync (session_bus, 0,
                                                    "org.freedesktop.impl.portal.PermissionStore",
                                                    "/org/freedesktop/impl/portal/PermissionStore",
                                                    NULL, error);
  if (store == NULL)
    return FALSE;

  tables = get_permission_tables (store);
  for (i = 0; tables[i]; i++)
    {
      if (!remove_for_app (store, tables[i], app_id, error))
        return FALSE;
    }

  return TRUE;
}

gboolean
flatpak_builtin_permission_reset (int argc, char **argv,
                                  GCancellable *cancellable,
                                  GError **error)
{
  g_autoptr(GOptionContext) context = NULL;
  const char *app_id;

  context = g_option_context_new (_("APP_ID - Reset permissions for an app"));
  g_option_context_set_translation_domain (context, GETTEXT_PACKAGE);

  if (!flatpak_option_context_parse (context, options, &argc, &argv,
                                     FLATPAK_BUILTIN_FLAG_NO_DIR,
                                     NULL, cancellable, error))
    return FALSE;

  if ((opt_all && argc != 1) || (!opt_all && argc != 2))
    return usage_error (context, _("Wrong number of arguments"), error);

  if (opt_all)
    app_id = NULL;
  else
    app_id = argv[1];

  return reset_permissions_for_app (app_id, error);
}

gboolean
flatpak_complete_permission_reset (FlatpakCompletion *completion)
{
  g_autoptr(GOptionContext) context = NULL;
  g_autoptr(GDBusConnection) session_bus = NULL;
  XdpDbusPermissionStore *store = NULL;
  g_autoptr(FlatpakDir) user_dir = NULL;
  g_autoptr(FlatpakDir) system_dir = NULL;

  context = g_option_context_new ("");

  if (!flatpak_option_context_parse (context, options, &completion->argc, &completion->argv,
                                     FLATPAK_BUILTIN_FLAG_NO_DIR, NULL, NULL, NULL))
    return FALSE;

  session_bus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL);
  if (session_bus == NULL)
    return FALSE;

  store = xdp_dbus_permission_store_proxy_new_sync (session_bus, 0,
                                                    "org.freedesktop.impl.portal.PermissionStore",
                                                    "/org/freedesktop/impl/portal/PermissionStore",
                                                    NULL, NULL);

  if (store == NULL)
    return FALSE;

  switch (completion->argc)
    {
    case 0:
    case 1: /* APP_ID */
      flatpak_complete_options (completion, global_entries);
      flatpak_complete_options (completion, options);


      user_dir = flatpak_dir_get_user ();
      system_dir = flatpak_dir_get_system_default ();
      flatpak_complete_partial_ref (completion, FLATPAK_KINDS_APP, FALSE, user_dir, NULL);
      flatpak_complete_partial_ref (completion, FLATPAK_KINDS_APP, FALSE, system_dir, NULL);

      break;

    default:
      break;
    }

  return TRUE;
}

===== ./app/flatpak-main.c =====
/* vi:set et sw=2 sts=2 cin cino=t0,f0,(0,{s,>2s,n-s,^-s,e-s:
 * Copyright © 2014 Red Hat, Inc
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Alexander Larsson <alexl@redhat.com>
 */

#include "config.h"

#include <locale.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <stdio.h>

#include <glib/gi18n.h>
#include <gio/gio.h>
#include "libglnx.h"

#ifdef USE_SYSTEM_HELPER
#include <polkit/polkit.h>
#include "flatpak-polkit-agent-text-listener.h"

/* Work with polkit before and after autoptr support was added */
typedef PolkitSubject AutoPolkitSubject;
G_DEFINE_AUTOPTR_CLEANUP_FUNC (AutoPolkitSubject, g_object_unref)
#endif

#include "flatpak-builtins.h"
#include "flatpak-builtins-utils.h"
#include "flatpak-utils-private.h"

static int opt_verbose;
static gboolean opt_ostree_verbose;
static gboolean opt_version;
static gboolean opt_default_arch;
static gboolean opt_supported_arches;
static gboolean opt_gl_drivers;
static gboolean opt_list_installations;
static gboolean opt_print_updated_env;
static gboolean opt_print_system_only;
static gboolean opt_user;
static gboolean opt_system;
static char **opt_installations;
static gboolean opt_help;

static gboolean is_in_complete;

typedef struct
{
  const char *name;
  const char *description;
  gboolean (*fn)(int           argc,
                 char        **argv,
                 GCancellable *cancellable,
                 GError      **error);
  gboolean (*complete)(FlatpakCompletion *completion);
  gboolean deprecated;
} FlatpakCommand;

static FlatpakCommand commands[] = {
  /* translators: please keep the leading space */
  { N_(" Manage installed applications and runtimes") },
  { "install", N_("Install an application or runtime"), flatpak_builtin_install, flatpak_complete_install },
  { "update", N_("Update an installed application or runtime"), flatpak_builtin_update, flatpak_complete_update },
  /* Alias upgrade to update to help users of yum/dnf */
  { "upgrade", NULL, flatpak_builtin_update, flatpak_complete_update, TRUE },
  { "uninstall", N_("Uninstall an installed application or runtime"), flatpak_builtin_uninstall, flatpak_complete_uninstall },
  /* Alias remove to uninstall to help users of yum/dnf/apt */
  { "remove", NULL, flatpak_builtin_uninstall, flatpak_complete_uninstall, TRUE },
  { "mask", N_("Mask out updates and automatic installation"), flatpak_builtin_mask, flatpak_complete_mask },
  { "pin", N_("Pin a runtime to prevent automatic removal"), flatpak_builtin_pin, flatpak_complete_pin },
  { "list", N_("List installed apps and/or runtimes"), flatpak_builtin_list, flatpak_complete_list },
  { "info", N_("Show info for installed app or runtime"), flatpak_builtin_info, flatpak_complete_info },
  { "history", N_("Show history"), flatpak_builtin_history, flatpak_complete_history },
  { "config", N_("Configure flatpak"), flatpak_builtin_config, flatpak_complete_config },
  { "repair", N_("Repair flatpak installation"), flatpak_builtin_repair, flatpak_complete_repair },
  { "create-usb", N_("Put applications or runtimes onto removable media"), flatpak_builtin_create_usb, flatpak_complete_create_usb },
  { "preinstall", N_("Install flatpaks that are part of the operating system"), flatpak_builtin_preinstall, flatpak_complete_preinstall },

  /* translators: please keep the leading newline and space */
  { N_("\n Find applications and runtimes") },
  { "search", N_("Search for remote apps/runtimes"), flatpak_builtin_search, flatpak_complete_search },

  /* translators: please keep the leading newline and space */
  { N_("\n Manage running applications") },
  { "run", N_("Run an application"), flatpak_builtin_run, flatpak_complete_run },
  { "override", N_("Override permissions for an application"), flatpak_builtin_override, flatpak_complete_override },
  { "make-current", N_("Specify default version to run"), flatpak_builtin_make_current_app, flatpak_complete_make_current_app },
  { "enter", N_("Enter the namespace of a running application"), flatpak_builtin_enter, flatpak_complete_enter },
  { "ps", N_("Enumerate running applications"), flatpak_builtin_ps, flatpak_complete_ps },
  { "kill", N_("Stop a running application"), flatpak_builtin_kill, flatpak_complete_kill },

  /* translators: please keep the leading newline and space */
  { N_("\n Manage file access") },
  { "documents", N_("List exported files"), flatpak_builtin_document_list, flatpak_complete_document_list },
  { "document-export", N_("Grant an application access to a specific file"), flatpak_builtin_document_export, flatpak_complete_document_export },
  { "document-unexport", N_("Revoke access to a specific file"), flatpak_builtin_document_unexport, flatpak_complete_document_unexport },
  { "document-info", N_("Show information about a specific file"), flatpak_builtin_document_info, flatpak_complete_document_info },
  { "document-list", NULL, flatpak_builtin_document_list, flatpak_complete_document_list, TRUE },

  /* translators: please keep the leading newline and space */
  { N_("\n Manage dynamic permissions") },
  { "permissions", N_("List permissions"), flatpak_builtin_permission_list, flatpak_complete_permission_list },
  { "permission-remove", N_("Remove item from permission store"), flatpak_builtin_permission_remove, flatpak_complete_permission_remove },
  { "permission-list", NULL, flatpak_builtin_permission_list, flatpak_complete_permission_list, TRUE },
  { "permission-set", N_("Set permissions"), flatpak_builtin_permission_set, flatpak_complete_permission_set },
  { "permission-show", N_("Show app permissions"), flatpak_builtin_permission_show, flatpak_complete_permission_show },
  { "permission-reset", N_("Reset app permissions"), flatpak_builtin_permission_reset, flatpak_complete_permission_reset },

  /* translators: please keep the leading newline and space */
  { N_("\n Manage remote repositories") },
  { "remotes", N_("List all configured remotes"), flatpak_builtin_remote_list, flatpak_complete_remote_list },
  { "remote-add", N_("Add a new remote repository (by URL)"), flatpak_builtin_remote_add, flatpak_complete_remote_add },
  { "remote-modify", N_("Modify properties of a configured remote"), flatpak_builtin_remote_modify, flatpak_complete_remote_modify },
  { "remote-delete", N_("Delete a configured remote"), flatpak_builtin_remote_delete, flatpak_complete_remote_delete },
  { "remote-list", NULL, flatpak_builtin_remote_list, flatpak_complete_remote_list, TRUE },
  { "remote-ls", N_("List contents of a configured remote"), flatpak_builtin_remote_ls, flatpak_complete_remote_ls },
  { "remote-info", N_("Show information about a remote app or runtime"), flatpak_builtin_remote_info, flatpak_complete_remote_info },

  /* translators: please keep the leading newline and space */
  { N_("\n Build applications") },
  { "build-init", N_("Initialize a directory for building"), flatpak_builtin_build_init, flatpak_complete_build_init },
  { "build", N_("Run a build command inside the build dir"), flatpak_builtin_build, flatpak_complete_build  },
  { "build-finish", N_("Finish a build dir for export"), flatpak_builtin_build_finish, flatpak_complete_build_finish },
  { "build-export", N_("Export a build dir to a repository"), flatpak_builtin_build_export, flatpak_complete_build_export },
  { "build-bundle", N_("Create a bundle file from a ref in a local repository"), flatpak_builtin_build_bundle, flatpak_complete_build_bundle },
  { "build-import-bundle", N_("Import a bundle file"), flatpak_builtin_build_import, flatpak_complete_build_import },
  { "build-sign", N_("Sign an application or runtime"), flatpak_builtin_build_sign, flatpak_complete_build_sign },
  { "build-update-repo", N_("Update the summary file in a repository"), flatpak_builtin_build_update_repo, flatpak_complete_build_update_repo },
  { "build-commit-from", N_("Create new commit based on existing ref"), flatpak_builtin_build_commit_from, flatpak_complete_build_commit_from },
  { "repo", N_("Show information about a repo"), flatpak_builtin_repo, flatpak_complete_repo },

  { NULL }
};

static gboolean
opt_verbose_cb (const gchar *option_name,
                const gchar *value,
                gpointer     data,
                GError     **error)
{
  opt_verbose++;
  return TRUE;
}


GOptionEntry global_entries[] = {
  { "verbose", 'v', G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK, &opt_verbose_cb, N_("Show debug information, -vv for more detail"), NULL },
  { "ostree-verbose", 0, 0, G_OPTION_ARG_NONE, &opt_ostree_verbose, N_("Show OSTree debug information"), NULL },
  { "help", '?', G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_NONE, &opt_help, NULL, NULL },
  { NULL }
};

static GOptionEntry empty_entries[] = {
  { "version", 0, 0, G_OPTION_ARG_NONE, &opt_version, N_("Print version information and exit"), NULL },
  { "default-arch", 0, 0, G_OPTION_ARG_NONE, &opt_default_arch, N_("Print default arch and exit"), NULL },
  { "supported-arches", 0, 0, G_OPTION_ARG_NONE, &opt_supported_arches, N_("Print supported arches and exit"), NULL },
  { "gl-drivers", 0, 0, G_OPTION_ARG_NONE, &opt_gl_drivers, N_("Print active gl drivers and exit"), NULL },
  { "installations", 0, 0, G_OPTION_ARG_NONE, &opt_list_installations, N_("Print paths for system installations and exit"), NULL },
  { "print-updated-env", 0, 0, G_OPTION_ARG_NONE, &opt_print_updated_env, N_("Print the updated environment needed to run flatpaks"), NULL },
  { "print-system-only", 0, 0, G_OPTION_ARG_NONE, &opt_print_system_only, N_("Only include the system installation with --print-updated-env"), NULL },
  { NULL }
};

GOptionEntry user_entries[] = {
  { "user", 'u', 0, G_OPTION_ARG_NONE, &opt_user, N_("Work on the user installation"), NULL },
  { "system", 0, 0, G_OPTION_ARG_NONE, &opt_system, N_("Work on the system-wide installation (default)"), NULL },
  { "installation", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_installations, N_("Work on a non-default system-wide installation"), N_("NAME") },
  { NULL }
};

static void
message_handler (const gchar   *log_domain,
                 GLogLevelFlags log_level,
                 const gchar   *message,
                 gpointer       user_data)
{
  g_printerr ("F: %s\n", message);
}

static void
no_message_handler (const char     *log_domain,
                    GLogLevelFlags  log_level,
                    const char     *message,
                    gpointer        user_data)
{
}

static GOptionContext *
flatpak_option_context_new_with_commands (FlatpakCommand *f_commands)
{
  GOptionContext *context;
  GString *summary;

  context = g_option_context_new (_("COMMAND"));
  g_option_context_set_translation_domain (context, GETTEXT_PACKAGE);

  summary = g_string_new (_("Builtin Commands:"));

  while (f_commands->name != NULL)
    {
      if (!f_commands->deprecated)
        {
          if (f_commands->fn != NULL)
            {
              g_string_append_printf (summary, "\n  %s", f_commands->name);
              /* Note: the 23 is there to align command descriptions with
               * the option descriptions produced by GOptionContext.
               */
              if (f_commands->description)
                g_string_append_printf (summary, "%*s%s", (int) (23 - strlen (f_commands->name)), "", _(f_commands->description));
            }
          else
            {
              g_string_append_printf (summary, "\n%s", _(f_commands->name));
            }
        }
      f_commands++;
    }

  g_option_context_set_summary (context, summary->str);

  g_string_free (summary, TRUE);

  return context;
}

static void
check_environment (void)
{
  const char * const *dirs;
  gboolean has_system = FALSE;
  gboolean has_user = FALSE;
  g_autofree char *system_exports = NULL;
  g_autofree char *user_exports = NULL;
  int i;
  int rows, cols;

  /* Only print warnings on ttys */
  if (!flatpak_fancy_output ())
    return;

  /* Don't recommend restarting the session when we're not in one */
  if (!g_getenv ("DBUS_SESSION_BUS_ADDRESS"))
    return;

  /* Avoid interfering with tests */
  if (g_getenv ("FLATPAK_SYSTEM_DIR") || g_getenv ("FLATPAK_USER_DIR"))
    return;

  system_exports = g_build_filename (FLATPAK_SYSTEMDIR, "exports/share", NULL);
  user_exports = g_build_filename (g_get_user_data_dir (), "flatpak/exports/share", NULL);

  dirs = g_get_system_data_dirs ();
  for (i = 0; dirs[i]; i++)
    {
      /* There should never be a relative path but just in case we don't want
       * g_file_new_for_path() to take the current directory into account.
       */
      if (!g_str_has_prefix (dirs[i], "/"))
        continue;

      /* Normalize the path using GFile to e.g. replace // with / */
      g_autoptr(GFile) dir_file = g_file_new_for_path (dirs[i]);
      g_autofree char *dir_path = g_file_get_path (dir_file);

      if (g_str_has_prefix (dir_path, system_exports))
        has_system = TRUE;
      if (g_str_has_prefix (dir_path, user_exports))
        has_user = TRUE;
    }

  flatpak_get_window_size (&rows, &cols);
  if (cols > 80)
    cols = 80;

  if (!has_system && !has_user)
    {
      g_autofree char *missing = NULL;
      missing = g_strdup_printf ("\n\n '%s'\n '%s'\n\n", system_exports, user_exports);
      g_print ("\n");
      /* Translators: this text is automatically wrapped, don't insert line breaks */
      print_wrapped (cols,
                     _("Note that the directories %s are not in the search path "
                       "set by the XDG_DATA_DIRS environment variable, so applications "
                       "installed by Flatpak may not appear on your desktop until the "
                       "session is restarted."),
                     missing);
      g_print ("\n");
    }
  else if (!has_system || !has_user)
    {
      g_autofree char *missing = NULL;
      missing = g_strdup_printf ("\n\n '%s'\n\n", !has_system ? system_exports : user_exports);
      g_print ("\n");
      /* Translators: this text is automatically wrapped, don't insert line breaks */
      print_wrapped (cols,
                     _("Note that the directory %s is not in the search path "
                       "set by the XDG_DATA_DIRS environment variable, so applications "
                       "installed by Flatpak may not appear on your desktop until the "
                       "session is restarted."),
                     missing);
      g_print ("\n");
    }
}

gboolean
flatpak_option_context_parse (GOptionContext     *context,
                              const GOptionEntry *main_entries,
                              int                *argc,
                              char             ***argv,
                              FlatpakBuiltinFlags flags,
                              GPtrArray         **out_dirs,
                              GCancellable       *cancellable,
                              GError            **error)
{
  g_autoptr(GPtrArray) dirs = NULL;

  if (__builtin_popcount (flags & (FLATPAK_BUILTIN_FLAG_NO_DIR |
                                   FLATPAK_BUILTIN_FLAG_ONE_DIR |
                                   FLATPAK_BUILTIN_FLAG_STANDARD_DIRS |
                                   FLATPAK_BUILTIN_FLAG_ALL_DIRS)) != 1)
    g_assert_not_reached ();

  if (!(flags & FLATPAK_BUILTIN_FLAG_NO_DIR))
    g_option_context_add_main_entries (context, user_entries, NULL);

  if (main_entries != NULL)
    g_option_context_add_main_entries (context, main_entries, NULL);

  g_option_context_add_main_entries (context, global_entries, NULL);

  /* We never want help output to interrupt completion */
  if (is_in_complete)
    g_option_context_set_help_enabled (context, FALSE);

  if (!g_option_context_parse (context, argc, argv, error))
    return FALSE;

  /* We never want verbose output in the complete case, that breaks completion */
  if (is_in_complete)
    {
      g_log_set_default_handler (no_message_handler, NULL);
    }
  else
    {
      if (opt_verbose > 0)
        g_log_set_handler (G_LOG_DOMAIN, G_LOG_LEVEL_INFO, message_handler, NULL);
      if (opt_verbose > 1)
        g_log_set_handler (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, message_handler, NULL);

      if (opt_ostree_verbose)
        g_log_set_handler ("OSTree", G_LOG_LEVEL_DEBUG | G_LOG_LEVEL_INFO, message_handler, NULL);

      if (opt_verbose > 0 || opt_ostree_verbose)
        flatpak_disable_fancy_output ();

      flatpak_set_debugging (opt_verbose > 1);
    }

  /* sudo flatpak --user ... would operate on the root user's installation,
   * which is almost certainly not what the user intended so just consider it
   * an error.
   */
  if (opt_user && running_under_sudo_root ())
    return flatpak_fail_error (error, FLATPAK_ERROR,
                               _("Refusing to operate under sudo with --user. "
                                 "Omit sudo to operate on the user installation, "
                                 "or use a root shell to operate on the root user's installation."));

  if (!(flags & FLATPAK_BUILTIN_FLAG_NO_DIR))
    {
      dirs = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref);
      int i;

      if (!(flags & FLATPAK_BUILTIN_FLAG_ONE_DIR))
        {
          /*
           * FLATPAK_BUILTIN_FLAG_STANDARD_DIRS or FLATPAK_BUILTIN_FLAG_ALL_DIRS
           * must be set.
           */

          /* If nothing is set, then we put the system dir first, which can be used as the default */
          if (opt_system || (!opt_user && opt_installations == NULL))
            g_ptr_array_add (dirs, flatpak_dir_get_system_default ());

          if (opt_user || (!opt_system && opt_installations == NULL))
            g_ptr_array_add (dirs, flatpak_dir_get_user ());

          if (opt_installations != NULL)
            {
              for (i = 0; opt_installations[i] != NULL; i++)
                {
                  FlatpakDir *installation_dir = NULL;

                  /* Already included the default system installation */
                  if (opt_system && g_strcmp0 (opt_installations[i], "default") == 0)
                    continue;

                  installation_dir = flatpak_dir_get_system_by_id (opt_installations[i], cancellable, error);
                  if (installation_dir == NULL)
                    return FALSE;

                  g_ptr_array_add (dirs, installation_dir);
                }
            }

          if (flags & FLATPAK_BUILTIN_FLAG_ALL_DIRS &&
              opt_installations == NULL && !opt_user && !opt_system)
            {
              g_autoptr(GPtrArray) system_dirs = NULL;

              g_ptr_array_set_size (dirs, 0);
              /* The first dir should be the default */
              g_ptr_array_add (dirs, flatpak_dir_get_system_default ());
              g_ptr_array_add (dirs, flatpak_dir_get_user ());

              system_dirs = flatpak_dir_get_system_list (cancellable, error);
              if (system_dirs == NULL)
                return FALSE;

              for (i = 0; i < system_dirs->len; i++)
                {
                  FlatpakDir *dir = g_ptr_array_index (system_dirs, i);
                  const char *id = flatpak_dir_get_id (dir);
                  if (g_strcmp0 (id, SYSTEM_DIR_DEFAULT_ID) != 0)
                    g_ptr_array_add (dirs, g_object_ref (dir));
                }
            }
        }
      else /* FLATPAK_BUILTIN_FLAG_ONE_DIR */
        {
          FlatpakDir *dir;

          if ((opt_system && opt_user) ||
              (opt_system && opt_installations != NULL) ||
              (opt_user && opt_installations != NULL) ||
              (opt_installations != NULL && opt_installations[1] != NULL))
            return usage_error (context, _("Multiple installations specified for a command "
                                           "that works on one installation"), error);

          if (opt_system || (!opt_user && opt_installations == NULL))
            dir = flatpak_dir_get_system_default ();
          else if (opt_user)
            dir = flatpak_dir_get_user ();
          else if (opt_installations != NULL)
            {
              dir = flatpak_dir_get_system_by_id (opt_installations[0], cancellable, error);
              if (dir == NULL)
                return FALSE;
            }
          else
            g_assert_not_reached ();

          g_ptr_array_add (dirs, dir);
        }

      for (i = 0; i < dirs->len; i++)
        {
          FlatpakDir *dir = g_ptr_array_index (dirs, i);

          if (flags & (FLATPAK_BUILTIN_FLAG_OPTIONAL_REPO |
                       FLATPAK_BUILTIN_FLAG_ALL_DIRS |
                       FLATPAK_BUILTIN_FLAG_STANDARD_DIRS))
            {
              if (!flatpak_dir_maybe_ensure_repo (dir, cancellable, error))
                return FALSE;
            }
          else
            {
              if (!flatpak_dir_ensure_repo (dir, cancellable, error))
                return FALSE;
            }

          flatpak_log_dir_access (dir);
        }
    }

  if (out_dirs)
    *out_dirs = g_steal_pointer (&dirs);

  return TRUE;
}

gboolean
usage_error (GOptionContext *context, const char *message, GError **error)
{
  g_autofree char *hint = NULL;

  hint = g_strdup_printf (_("See '%s --help'"), g_get_prgname ());
  g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "%s\n\n%s", message, hint);
  return FALSE;
}

static FlatpakCommand *
extract_command (int         *argc,
                 char       **argv,
                 const char **command_name_out)
{
  FlatpakCommand *command;
  const char *command_name = NULL;
  int in, out;

  /*
   * Parse the global options. We rearrange the options as
   * necessary, in order to pass relevant options through
   * to the commands, but also have them take effect globally.
   */
  for (in = 1, out = 1; in < *argc; in++, out++)
    {
      /* The non-option is the command, take it out of the arguments */
      if (argv[in][0] != '-')
        {
          if (command_name == NULL)
            {
              command_name = argv[in];
              out--;
              continue;
            }
        }

      argv[out] = argv[in];
    }

  *argc = out;
  argv[out] = NULL;

  command = commands;
  while (command->name)
    {
      if (command->fn != NULL &&
          g_strcmp0 (command_name, command->name) == 0)
        break;
      command++;
    }

  *command_name_out = command_name;

  return command;
}

static const char *
find_similar_command (const char *word,
                      gboolean   *option)
{
  int i, d, k;
  const char *suggestion;
  GOptionEntry *entries[3] = { global_entries, empty_entries, user_entries };

  d = G_MAXINT;
  suggestion = NULL;

  for (i = 0; commands[i].name; i++)
    {
      if (!commands[i].fn)
        continue;

      int d1 = flatpak_levenshtein_distance (word, -1, commands[i].name, -1);
      if (d1 < d)
        {
          d = d1;
          suggestion = commands[i].name;
          *option = FALSE;
        }
    }

  for (k = 0; k < 3; k++)
    {
      for (i = 0; entries[k][i].long_name; i++)
        {
          int d1 = flatpak_levenshtein_distance (word, -1, entries[k][i].long_name, -1);
          if (d1 < d)
            {
              d = d1;
              suggestion = entries[k][i].long_name;
              *option = TRUE;
            }
        }
    }

  return suggestion;
}

static gpointer
install_polkit_agent (void)
{
  gpointer agent = NULL;

#ifdef USE_SYSTEM_HELPER
  PolkitAgentListener *listener = NULL;
  g_autoptr(GError) local_error = NULL;
  g_autoptr(GDBusConnection) bus = NULL;
  const char *on_session;
  const char *env;
  const char *distro_name;

  on_session = g_getenv ("FLATPAK_SYSTEM_HELPER_ON_SESSION");
  if (on_session != NULL)
    return NULL;

  bus = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &local_error);

  if (bus == NULL)
    {
      g_info ("Unable to connect to system bus: %s", local_error->message);
      return NULL;
    }

  /* Install a polkit agent as fallback, in case we're running on a console */
  listener = flatpak_polkit_agent_text_listener_new (NULL, &local_error);
  if (listener == NULL)
    {
      g_info ("Failed to create polkit agent listener: %s", local_error->message);
    }
  else
    {
      g_autoptr(AutoPolkitSubject) subject = NULL;
      GVariantBuilder opt_builder;
      g_autoptr(GVariant) options = NULL;

      subject = polkit_unix_process_new_for_owner (getpid (), 0, getuid ());

      g_variant_builder_init (&opt_builder, G_VARIANT_TYPE_VARDICT);
      env = g_getenv ("WSL_INTEROP");
      distro_name = g_getenv ("WSL_DISTRO_NAME");
      if ((env == NULL || *env == '\0') &&
          (distro_name == NULL || *distro_name == '\0') &&
          g_strcmp0 (g_getenv ("FLATPAK_FORCE_TEXT_AUTH"), "1") != 0)
        g_variant_builder_add (&opt_builder, "{sv}", "fallback", g_variant_new_boolean (TRUE));
      options = g_variant_ref_sink (g_variant_builder_end (&opt_builder));

      agent = polkit_agent_listener_register_with_options (listener,
                                                           POLKIT_AGENT_REGISTER_FLAGS_RUN_IN_THREAD,
                                                           subject,
                                                           NULL,
                                                           options,
                                                           NULL,
                                                           &local_error);
      if (agent == NULL)
        {
          g_info ("Failed to register polkit agent listener: %s", local_error->message);
        }
      g_object_unref (listener);
    }
#endif

  return agent;
}

static void
uninstall_polkit_agent (gpointer *agent)
{
#ifdef USE_SYSTEM_HELPER
  if (*agent)
    polkit_agent_listener_unregister (*agent);
#endif
}

static int
flatpak_run (int      argc,
             char   **argv,
             GError **res_error)
{
  FlatpakCommand *command;
  GError *error = NULL;
  GCancellable *cancellable = NULL;
  g_autofree char *prgname = NULL;
  gboolean success = FALSE;
  const char *command_name = NULL;

  __attribute__((cleanup (uninstall_polkit_agent))) gpointer polkit_agent = NULL;

  command = extract_command (&argc, argv, &command_name);

  if (!command->fn)
    {
      g_autoptr(GOptionContext) context = NULL;
      g_autofree char *hint = NULL;
      g_autofree char *msg = NULL;

      context = flatpak_option_context_new_with_commands (commands);

      hint = g_strdup_printf (_("See '%s --help'"), g_get_prgname ());

      if (command_name != NULL)
        {
          const char *similar;
          gboolean option;

          similar = find_similar_command (command_name, &option);
          if (similar)
            msg = g_strdup_printf (_("'%s' is not a flatpak command. Did you mean '%s%s'?"),
                                   command_name, option ? "--" : "", similar);
          else
            msg = g_strdup_printf (_("'%s' is not a flatpak command"),
                                   command_name);
        }
      else
        {
          g_autoptr(GError) local_error = NULL;

          g_option_context_add_main_entries (context, empty_entries, NULL);
          g_option_context_add_main_entries (context, global_entries, NULL);
          if (g_option_context_parse (context, &argc, &argv, &local_error))
            {
              if (opt_version)
                {
                  g_print ("%s\n", PACKAGE_STRING);
                  return EXIT_SUCCESS;
                }

              if (opt_default_arch)
                {
                  g_print ("%s\n", flatpak_get_arch ());
                  return EXIT_SUCCESS;
                }

              if (opt_supported_arches)
                {
                  const char **arches = flatpak_get_arches ();
                  int i;
                  for (i = 0; arches[i] != NULL; i++)
                    g_print ("%s\n", arches[i]);
                  return EXIT_SUCCESS;
                }

              if (opt_gl_drivers)
                {
                  const char **drivers = flatpak_get_gl_drivers ();
                  int i;
                  for (i = 0; drivers[i] != NULL; i++)
                    g_print ("%s\n", drivers[i]);
                  return EXIT_SUCCESS;
                }

              if (opt_list_installations)
                {
                  GPtrArray *paths;

                  paths = flatpak_get_system_base_dir_locations (NULL, &local_error);
                  if (paths)
                    {
                      guint i;
                      for (i = 0; i < paths->len; i++)
                        {
                          GFile *file = paths->pdata[i];
                          g_print ("%s\n", flatpak_file_get_path_cached (file));
                        }
                      return EXIT_SUCCESS;
                    }
                }

              /* systemd environment generator for system and user installations.
               * Intended to be used only from the scripts in env.d/.
               * See `man systemd.environment-generator`. */
              if (opt_print_updated_env)
                {
                  g_autoptr(GPtrArray) installations = g_ptr_array_new_with_free_func (g_free);  /* (element-type GFile) */
                  GPtrArray *system_installation_locations;  /* (element-type GFile) */
                  const gchar * const *xdg_data_dirs = g_get_system_data_dirs ();
                  g_autoptr(GPtrArray) new_dirs = g_ptr_array_new_with_free_func (g_free);  /* (element-type filename) */
                  g_autofree gchar *new_dirs_joined = NULL;

                  /* Work out the set of installations we want in the environment. */
                  if (!opt_print_system_only)
                    {
                      g_autoptr(GFile) home_installation_location = flatpak_get_user_base_dir_location ();
                      g_ptr_array_add (installations, g_file_get_path (home_installation_location));
                    }

                  system_installation_locations = flatpak_get_system_base_dir_locations (NULL, &local_error);
                  if (local_error != NULL)
                    {
                      g_printerr ("%s\n", local_error->message);
                      return 1;
                    }

                  for (gsize i = 0; i < system_installation_locations->len; i++)
                    g_ptr_array_add (installations, g_file_get_path (system_installation_locations->pdata[i]));

                  /* Get the export path for each installation, and filter out
                   * ones which are already listed in @xdg_data_dirs. */
                  for (gsize i = 0; i < installations->len; i++)
                    {
                      g_autofree gchar *share_path = g_build_filename (installations->pdata[i], "exports", "share", NULL);
                      g_autofree gchar *share_path_with_slash = g_strconcat (share_path, "/", NULL);

                      if (g_strv_contains (xdg_data_dirs, share_path) || g_strv_contains (xdg_data_dirs, share_path_with_slash))
                        continue;

                      g_ptr_array_add (new_dirs, g_steal_pointer (&share_path));
                    }

                  /* Add the rest of the existing @xdg_data_dirs to the new list. */
                  for (gsize i = 0; xdg_data_dirs[i] != NULL; i++)
                    g_ptr_array_add (new_dirs, g_strdup (xdg_data_dirs[i]));
                  g_ptr_array_add (new_dirs, NULL);

                  /* Print in a format suitable for a system environment generator. */
                  new_dirs_joined = g_strjoinv (":", (gchar **) new_dirs->pdata);
                  g_print ("XDG_DATA_DIRS=%s\n", new_dirs_joined);

                  return EXIT_SUCCESS;
                }
            }

          if (local_error)
            msg = g_strdup (local_error->message);
          else
            msg = g_strdup (_("No command specified"));
        }

      g_set_error (&error, G_IO_ERROR, G_IO_ERROR_FAILED, "%s\n\n%s", msg, hint);

      goto out;
    }

  prgname = g_strdup_printf ("%s %s", g_get_prgname (), command_name);
  g_set_prgname (prgname);

  /* Only print environment warnings in some commonly used interactive operations so we
     avoid messing up output in commands where you might parse the output. */
  if (g_strcmp0 (command->name, "install") == 0 ||
      g_strcmp0 (command->name, "update") == 0 ||
      g_strcmp0 (command->name, "remote-add") == 0 ||
      g_strcmp0 (command->name, "run") == 0)
    check_environment ();

  /* Don't talk to dbus in enter, as it must be thread-free to setns, also
     skip run/build/history for performance reasons (no need to connect to dbus). */
  if (g_strcmp0 (command->name, "enter") != 0 &&
      g_strcmp0 (command->name, "run") != 0 &&
      g_strcmp0 (command->name, "build") != 0 &&
      g_strcmp0 (command->name, "history") != 0)
    polkit_agent = install_polkit_agent ();

  /* g_vfs_get_default can spawn threads */
  if (g_strcmp0 (command->name, "enter") != 0)
    {
      g_autofree const char *old_env = NULL;

      /* avoid gvfs (http://bugzilla.gnome.org/show_bug.cgi?id=526454) */
      old_env = g_strdup (g_getenv ("GIO_USE_VFS"));
      g_setenv ("GIO_USE_VFS", "local", TRUE);
      g_vfs_get_default ();
      if (old_env)
        g_setenv ("GIO_USE_VFS", old_env, TRUE);
      else
        g_unsetenv ("GIO_USE_VFS");
    }

  if (!command->fn (argc, argv, cancellable, &error))
    goto out;

  success = TRUE;
out:
  /* Note: We allow failures with NULL error (it means don't print anything), useful when e.g. the user aborted */
  g_assert (!success || error == NULL);

  if (error)
    {
      g_propagate_error (res_error, error);
    }

  return success ? 0 : 1;
}

static int
complete (int    argc,
          char **argv)
{
  g_autoptr(FlatpakCompletion) completion = NULL;
  FlatpakCommand *command;
  const char *command_name = NULL;

  is_in_complete = TRUE;

  completion = flatpak_completion_new (argv[2], argv[3], argv[4]);
  if (completion == NULL)
    return 1;

  command = extract_command (&completion->argc, completion->argv, &command_name);
  flatpak_completion_debug ("command=%p '%s'", command->fn, command->name);

  if (!command->fn)
    {
      FlatpakCommand *c = commands;
      while (c->name)
        {
          if (c->fn != NULL && !c->deprecated)
            flatpak_complete_word (completion, "%s ", c->name);
          c++;
        }

      flatpak_complete_options (completion, global_entries);
      flatpak_complete_options (completion, empty_entries);
      flatpak_complete_options (completion, user_entries);
    }
  else if (command->complete)
    {
      if (!command->complete (completion))
        return 1;
    }
  else
    {
      flatpak_complete_options (completion, global_entries);
    }

  return 0;
}

static void
handle_sigterm (int signum)
{
  flatpak_disable_raw_mode ();
  flatpak_show_cursor ();
  _exit (1);
}

int
main (int    argc,
      char **argv)
{
  g_autoptr(GError) error = NULL;
  int ret;
  struct sigaction action;

  /* The child repo shared between the client process and the
     system-helper really needs to support creating files that
     are readable by others, so override the umask to 022.
     Ideally this should be set when needed, but umask is thread-unsafe
     so there is really no local way to fix this.
  */
  umask(022);

  memset (&action, 0, sizeof (struct sigaction));
  action.sa_handler = handle_sigterm;
  sigaction (SIGTERM, &action, NULL);
  sigaction (SIGHUP, &action, NULL);
  sigaction (SIGINT, &action, NULL);

  setlocale (LC_ALL, "");
  bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
  bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
  textdomain (GETTEXT_PACKAGE);

  g_log_set_handler (G_LOG_DOMAIN, G_LOG_LEVEL_MESSAGE | G_LOG_LEVEL_WARNING, message_handler, NULL);

  g_set_prgname (argv[0]);

  if (argc >= 4 && strcmp (argv[1], "complete") == 0)
    return complete (argc, argv);

  ret = flatpak_run (argc, argv, &error);

  if (error != NULL)
    {
      const char *prefix = "";
      const char *suffix = "";
      if (flatpak_fancy_output ())
        {
          prefix = FLATPAK_ANSI_RED FLATPAK_ANSI_BOLD_ON;
          suffix = FLATPAK_ANSI_BOLD_OFF FLATPAK_ANSI_COLOR_RESET;
        }
      g_dbus_error_strip_remote_error (error);
      g_printerr ("%s%s %s%s\n", prefix, _("error:"), suffix, error->message);
    }

  return ret;
}

===== ./app/flatpak-cli-transaction.h =====
/*
 * Copyright © 2018 Red Hat, Inc
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Alexander Larsson <alexl@redhat.com>
 */

#ifndef __FLATPAK_CLI_TRANSACTION_H__
#define __FLATPAK_CLI_TRANSACTION_H__

#include "flatpak-transaction.h"
#include "flatpak-dir-private.h"

#define FLATPAK_TYPE_CLI_TRANSACTION flatpak_cli_transaction_get_type ()
G_DECLARE_FINAL_TYPE (FlatpakCliTransaction, flatpak_cli_transaction, FLATPAK, CLI_TRANSACTION, FlatpakTransaction)

FlatpakTransaction * flatpak_cli_transaction_new (FlatpakDir * dir,
                                                  gboolean disable_interaction,
                                                  gboolean stop_on_first_error,
                                                  gboolean non_default_arch,
                                                  GError **error);

#endif /* __FLATPAK_CLI_TRANSACTION_H__ */

===== ./app/flatpak-builtins-run.c =====
/* vi:set et sw=2 sts=2 cin cino=t0,f0,(0,{s,>2s,n-s,^-s,e-s:
 * Copyright © 2014 Red Hat, Inc
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Alexander Larsson <alexl@redhat.com>
 */

#include "config.h"

#include <locale.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>

#include <glib/gi18n.h>

#include "libglnx.h"

#include "flatpak-builtins.h"
#include "flatpak-utils-private.h"
#include "flatpak-error.h"
#include "flatpak-dbus-generated.h"
#include "flatpak-run-private.h"

static char *opt_arch;
static char *opt_branch;
static char *opt_command;
static char *opt_cwd;
static gboolean opt_devel;
static gboolean opt_log_session_bus;
static gboolean opt_log_system_bus;
static gboolean opt_log_a11y_bus;
static int opt_a11y_bus = -1;
static int opt_session_bus = -1;
static gboolean opt_no_documents_portal;
static gboolean opt_file_forwarding;
static gboolean opt_die_with_parent;
static gboolean opt_sandbox;
static char *opt_runtime;
static char *opt_runtime_version;
static char *opt_commit;
static char *opt_runtime_commit;
static int opt_parent_pid;
static gboolean opt_parent_expose_pids;
static gboolean opt_parent_share_pids;
static int opt_instance_id_fd = -1;
static char *opt_app_path;
static int opt_app_fd = -1;
static char *opt_usr_path;
static int opt_usr_fd = -1;
static gboolean opt_clear_env;
static GArray *opt_bind_fds = NULL;
static GArray *opt_ro_bind_fds = NULL;

static gboolean
option_bind_fd_cb (const char  *option_name,
                   const char  *value,
                   gpointer     data,
                   GError     **error)
{
  glnx_autofd int fd = -1;

  fd = flatpak_accept_fd_argument (option_name, value, error);

  if (fd < 0)
    return FALSE;

  g_array_append_val (opt_bind_fds, fd);
  fd = -1; /* ownership transferred to GArray */
  return TRUE;
}

static gboolean
option_ro_bind_fd_cb (const char  *option_name,
                      const char  *value,
                      gpointer     data,
                      GError     **error)
{
  glnx_autofd int fd = -1;

  fd = flatpak_accept_fd_argument (option_name, value, error);

  if (fd < 0)
    return FALSE;

  g_array_append_val (opt_ro_bind_fds, fd);
  fd = -1; /* ownership transferred to GArray */
  return TRUE;
}

static gboolean
opt_instance_id_fd_cb (const char  *option_name,
                       const char  *value,
                       gpointer     data,
                       GError     **error)
{
  glnx_autofd int fd = -1;

  fd = flatpak_accept_fd_argument (option_name, value, error);

  if (fd < 0)
    return FALSE;

  opt_instance_id_fd = g_steal_fd (&fd);
  return TRUE;
}

static gboolean
opt_app_fd_cb (const char  *option_name,
               const char  *value,
               gpointer     data,
               GError     **error)
{
  glnx_autofd int fd = -1;

  fd = flatpak_accept_fd_argument (option_name, value, error);

  if (fd < 0)
    return FALSE;

  opt_app_fd = g_steal_fd (&fd);
  return TRUE;
}

static gboolean
opt_usr_fd_cb (const char  *option_name,
               const char  *value,
               gpointer     data,
               GError     **error)
{
  glnx_autofd int fd = -1;

  fd = flatpak_accept_fd_argument (option_name, value, error);

  if (fd < 0)
    return FALSE;

  opt_usr_fd = g_steal_fd (&fd);
  return TRUE;
}

static GOptionEntry options[] = {
  { "arch", 0, 0, G_OPTION_ARG_STRING, &opt_arch, N_("Arch to use"), N_("ARCH") },
  { "command", 0, 0, G_OPTION_ARG_STRING, &opt_command, N_("Command to run"), N_("COMMAND") },
  { "cwd", 0, 0, G_OPTION_ARG_STRING, &opt_cwd, N_("Directory to run the command in"), N_("DIR") },
  { "branch", 0, 0, G_OPTION_ARG_STRING, &opt_branch, N_("Branch to use"), N_("BRANCH") },
  { "devel", 'd', 0, G_OPTION_ARG_NONE, &opt_devel, N_("Use development runtime"), NULL },
  { "runtime", 0, 0, G_OPTION_ARG_STRING, &opt_runtime, N_("Runtime to use"), N_("RUNTIME") },
  { "runtime-version", 0, 0, G_OPTION_ARG_STRING, &opt_runtime_version, N_("Runtime version to use"), N_("VERSION") },
  { "log-session-bus", 0, 0, G_OPTION_ARG_NONE, &opt_log_session_bus, N_("Log session bus calls"), NULL },
  { "log-system-bus", 0, 0, G_OPTION_ARG_NONE, &opt_log_system_bus, N_("Log system bus calls"), NULL },
  { "log-a11y-bus", 0, 0, G_OPTION_ARG_NONE, &opt_log_a11y_bus, N_("Log accessibility bus calls"), NULL },
  { "no-a11y-bus", 0, G_OPTION_FLAG_REVERSE, G_OPTION_ARG_NONE, &opt_a11y_bus, N_("Don't proxy accessibility bus calls"), NULL },
  { "a11y-bus", 0, 0, G_OPTION_ARG_NONE, &opt_a11y_bus, N_("Proxy accessibility bus calls (default except when sandboxed)"), NULL },
  { "no-session-bus", 0, G_OPTION_FLAG_REVERSE, G_OPTION_ARG_NONE, &opt_session_bus, N_("Don't proxy session bus calls"), NULL },
  { "session-bus", 0, 0, G_OPTION_ARG_NONE, &opt_session_bus, N_("Proxy session bus calls (default except when sandboxed)"), NULL },
  { "no-documents-portal", 0, 0, G_OPTION_ARG_NONE, &opt_no_documents_portal, N_("Don't start portals"), NULL },
  { "file-forwarding", 0, 0, G_OPTION_ARG_NONE, &opt_file_forwarding, N_("Enable file forwarding"), NULL },
  { "commit", 0, 0, G_OPTION_ARG_STRING, &opt_commit, N_("Run specified commit"), NULL },
  { "runtime-commit", 0, 0, G_OPTION_ARG_STRING, &opt_runtime_commit, N_("Use specified runtime commit"), NULL },
  { "sandbox", 0, 0, G_OPTION_ARG_NONE, &opt_sandbox, N_("Run completely sandboxed"), NULL },
  { "die-with-parent", 'p', 0, G_OPTION_ARG_NONE, &opt_die_with_parent, N_("Kill processes when the parent process dies"), NULL },
  { "parent-pid", 0, 0, G_OPTION_ARG_INT, &opt_parent_pid, N_("Use PID as parent pid for sharing namespaces"), N_("PID") },
  { "parent-expose-pids", 0, 0, G_OPTION_ARG_NONE, &opt_parent_expose_pids, N_("Make processes visible in parent namespace"), NULL },
  { "parent-share-pids", 0, 0, G_OPTION_ARG_NONE, &opt_parent_share_pids, N_("Share process ID namespace with parent"), NULL },
  { "instance-id-fd", 0, 0, G_OPTION_ARG_CALLBACK, &opt_instance_id_fd_cb, N_("Write the instance ID to the given file descriptor"), NULL },
  { "app-path", 0, 0, G_OPTION_ARG_FILENAME, &opt_app_path, N_("Use PATH instead of the app's /app"), N_("PATH") },
  { "app-fd", 0, 0, G_OPTION_ARG_CALLBACK, &opt_app_fd_cb, N_("Use FD instead of the app's /app"), N_("FD") },
  { "usr-path", 0, 0, G_OPTION_ARG_FILENAME, &opt_usr_path, N_("Use PATH instead of the runtime's /usr"), N_("PATH") },
  { "usr-fd", 0, 0, G_OPTION_ARG_CALLBACK, &opt_usr_fd_cb, N_("Use FD instead of the runtime's /usr"), N_("FD") },
  { "clear-env", 0, 0, G_OPTION_ARG_NONE, &opt_clear_env, N_("Clear all outside environment variables"), NULL },
  { "bind-fd", 0, 0, G_OPTION_ARG_CALLBACK | G_OPTION_FLAG_HIDDEN, &option_bind_fd_cb, N_("Bind mount the file or directory referred to by FD to its canonicalized path"), N_("FD") },
  { "ro-bind-fd", 0, 0, G_OPTION_ARG_CALLBACK | G_OPTION_FLAG_HIDDEN, &option_ro_bind_fd_cb, N_("Bind mount the file or directory referred to by FD read-only to its canonicalized path"), N_("FD") },
  { NULL }
};

gboolean
flatpak_builtin_run (int argc, char **argv, GCancellable *cancellable, GError **error)
{
  g_auto(GStrv) run_environ = NULL;
  g_autoptr(GOptionContext) context = NULL;
  g_autoptr(FlatpakDeploy) app_deploy = NULL;
  g_autoptr(FlatpakDecomposed) app_ref = NULL;
  g_autoptr(FlatpakDecomposed) runtime_ref = NULL;
  const char *pref;
  int i;
  int rest_argv_start = 0, rest_argc = 0;
  g_autoptr(FlatpakContext) arg_context = NULL;
  g_autofree char *id = NULL;
  g_autofree char *arch = NULL;
  g_autofree char *branch = NULL;
  FlatpakKinds kinds;
  g_autoptr(GError) local_error = NULL;
  g_autoptr(GPtrArray) dirs = NULL;
  FlatpakRunFlags flags = 0;
  glnx_autofd int app_fd = -1;
  glnx_autofd int usr_fd = -1;

  run_environ = g_get_environ ();

  opt_bind_fds = g_array_new (FALSE, FALSE, sizeof (int));
  opt_ro_bind_fds = g_array_new (FALSE, FALSE, sizeof (int));

  context = g_option_context_new (_("APP [ARGUMENT…] - Run an app"));
  g_option_context_set_translation_domain (context, GETTEXT_PACKAGE);

  for (i = 1; i < argc; i++)
    {
      /* The non-option is the command, take it out of the arguments */
      if (argv[i][0] != '-')
        {
          rest_argv_start = i;
          rest_argc = argc - i;
          argc = i;
          break;
        }
    }

  arg_context = flatpak_context_new ();
  g_option_context_add_group (context, flatpak_context_get_options (arg_context));

  if (!flatpak_option_context_parse (context, options, &argc, &argv,
                                     FLATPAK_BUILTIN_FLAG_ALL_DIRS | FLATPAK_BUILTIN_FLAG_OPTIONAL_REPO,
                                     &dirs, cancellable, error))
    return FALSE;

  /* Move the user dir to the front so it "wins" in case an app is in more than
   * one installation */
  if (dirs->len > 1)
    {
      /* Walk through the array backwards so we can safely remove */
      for (i = dirs->len; i > 0; i--)
        {
          FlatpakDir *dir = g_ptr_array_index (dirs, i - 1);
          if (flatpak_dir_is_user (dir))
            {
              g_ptr_array_insert (dirs, 0, g_object_ref (dir));
              g_ptr_array_remove_index (dirs, i);
              break;
            }
        }
    }

  if (rest_argc == 0)
    return usage_error (context, _("APP must be specified"), error);

  /* If we get here, then rest_argv_start must have been set >= 1 */
  g_assert (rest_argv_start > 0);
  pref = argv[rest_argv_start];

  if (!flatpak_split_partial_ref_arg (pref, FLATPAK_KINDS_APP | FLATPAK_KINDS_RUNTIME,
                                      opt_arch, opt_branch,
                                      &kinds, &id, &arch, &branch, error))
    return FALSE;

  if (branch == NULL || arch == NULL)
    {
      g_autoptr(FlatpakDecomposed) current_ref = flatpak_find_current_ref (id, NULL, NULL);
      if (current_ref)
        {
          if (branch == NULL)
            branch = flatpak_decomposed_dup_branch (current_ref);
          if (arch == NULL)
            arch = flatpak_decomposed_dup_arch (current_ref);
        }
    }

  if ((kinds & FLATPAK_KINDS_APP) != 0)
    {
      app_ref = flatpak_decomposed_new_from_parts (FLATPAK_KINDS_APP, id, arch, branch, &local_error);
      if (app_ref != NULL)
        app_deploy = flatpak_find_deploy_for_ref_in (dirs, flatpak_decomposed_get_ref (app_ref), opt_commit, cancellable, &local_error);

      if (app_deploy == NULL &&
          (!g_error_matches (local_error, FLATPAK_ERROR, FLATPAK_ERROR_NOT_INSTALLED) ||
           (kinds & FLATPAK_KINDS_RUNTIME) == 0))
        {
          g_propagate_error (error, g_steal_pointer (&local_error));
          return FALSE;
        }
      /* On error, local_error is set after this point so we can reuse
         this error rather than later errors, as the app-kind error
         is more likely interesting. */
    }

  if (app_deploy == NULL)
    {
      g_autoptr(FlatpakDeploy) runtime_deploy = NULL;
      g_autoptr(GError) local_error2 = NULL;
      g_autoptr(GPtrArray) ref_dir_pairs = NULL;
      RefDirPair *chosen_pair = NULL;
      const char *runtime_arch = arch;

      /* If arch is not specified, only run the default arch to avoid asking for prompts for non-primary arches,
         still asks for prompts if there are multiple branches though */
      if (runtime_arch == NULL)
        runtime_arch = flatpak_get_arch ();

      /* Whereas for apps we want to default to using the "current" one (see
       * flatpak-make-current(1)) runtimes don't have a concept of currentness.
       * So prompt if there's ambiguity about which branch to use */
      ref_dir_pairs = g_ptr_array_new_with_free_func ((GDestroyNotify) ref_dir_pair_free);
      for (i = 0; i < dirs->len; i++)
        {
          FlatpakDir *dir = g_ptr_array_index (dirs, i);
          g_autoptr(GPtrArray) refs = NULL;

          refs = flatpak_dir_find_installed_refs (dir, id, branch, runtime_arch, FLATPAK_KINDS_RUNTIME,
                                                  FIND_MATCHING_REFS_FLAGS_NONE, error);
          if (refs == NULL)
            return FALSE;
          else if (refs->len == 0)
            continue;

          for (int j = 0; j < refs->len; j++)
            {
              FlatpakDecomposed *ref = g_ptr_array_index (refs, j);
              RefDirPair *pair = ref_dir_pair_new (ref, dir);
              g_ptr_array_add (ref_dir_pairs, pair);
            }
        }

      if (ref_dir_pairs->len > 0)
        {
          g_autoptr(GPtrArray) chosen_pairs = NULL;
          g_autoptr(GPtrArray) chosen_dir_array = NULL;

          chosen_pairs = g_ptr_array_new ();

          if (!flatpak_resolve_matching_installed_refs (TRUE, TRUE, ref_dir_pairs, id, FALSE, chosen_pairs, error))
            return FALSE;

          g_assert (chosen_pairs->len == 1);
          chosen_pair = g_ptr_array_index (chosen_pairs, 0);

          /* For runtimes we don't need to pass a FlatpakDeploy object to
           * flatpak_run_app(), but get it anyway because we don't want to run
           * something that's not deployed */
          chosen_dir_array = g_ptr_array_new ();
          g_ptr_array_add (chosen_dir_array, chosen_pair->dir);
          runtime_deploy = flatpak_find_deploy_for_ref_in (chosen_dir_array, flatpak_decomposed_get_ref (chosen_pair->ref),
                                                           opt_commit ? opt_commit : opt_runtime_commit,
                                                           cancellable, &local_error2);
        }

      if (runtime_deploy == NULL)
        {
          /* Report old app-kind error, as its more likely right */
          if (local_error != NULL)
            g_propagate_error (error, g_steal_pointer (&local_error));
          else if (local_error2 != NULL)
            g_propagate_error (error, g_steal_pointer (&local_error2));
          else
            flatpak_fail_error (error, FLATPAK_ERROR_NOT_INSTALLED,
                                _("runtime/%s/%s/%s not installed"),
                                id ?: "*unspecified*",
                                arch ?: "*unspecified*",
                                branch ?: "*unspecified*");
          return FALSE;
        }

      runtime_ref = flatpak_decomposed_ref (chosen_pair->ref);

      /* Clear app-kind error */
      g_clear_error (&local_error);
    }

  /* Default to TRUE, unless sandboxed */
  if (opt_a11y_bus == -1)
    opt_a11y_bus = !opt_sandbox;
  if (opt_session_bus == -1)
    opt_session_bus = !opt_sandbox;

  if (opt_sandbox)
    flags |= FLATPAK_RUN_FLAG_SANDBOX | FLATPAK_RUN_FLAG_NO_SYSTEM_BUS_PROXY;
  if (opt_die_with_parent)
    flags |= FLATPAK_RUN_FLAG_DIE_WITH_PARENT;
  if (opt_devel)
    flags |= FLATPAK_RUN_FLAG_DEVEL;
  if (opt_log_session_bus)
    flags |= FLATPAK_RUN_FLAG_LOG_SESSION_BUS;
  if (opt_log_system_bus)
    flags |= FLATPAK_RUN_FLAG_LOG_SYSTEM_BUS;
  if (opt_log_a11y_bus)
    flags |= FLATPAK_RUN_FLAG_LOG_A11Y_BUS;
  if (opt_file_forwarding)
    flags |= FLATPAK_RUN_FLAG_FILE_FORWARDING;
  if (opt_no_documents_portal)
    flags |= FLATPAK_RUN_FLAG_NO_DOCUMENTS_PORTAL;
  if (opt_parent_expose_pids)
    flags |= FLATPAK_RUN_FLAG_PARENT_EXPOSE_PIDS;
  if (opt_parent_share_pids)
    flags |= FLATPAK_RUN_FLAG_PARENT_SHARE_PIDS;
  if (!opt_a11y_bus)
    flags |= FLATPAK_RUN_FLAG_NO_A11Y_BUS_PROXY;
  if (!opt_session_bus)
    flags |= FLATPAK_RUN_FLAG_NO_SESSION_BUS_PROXY;
  if (!opt_clear_env)
    flags |= FLATPAK_RUN_FLAG_CLEAR_ENV;

  if (opt_app_fd >= 0 && opt_app_path != NULL)
    {
      flatpak_fail_error (error, FLATPAK_ERROR,
                          _("app-fd and app-path cannot both be used"));
      return FALSE;
    }

  if (opt_app_fd >= 0)
    {
      app_fd = opt_app_fd;
    }
  else if (opt_app_path != NULL)
    {
      if (g_strcmp0 (opt_app_path, "") == 0)
        {
          app_fd = FLATPAK_RUN_APP_DEPLOY_APP_EMPTY;
        }
      else
        {
          app_fd = open (opt_app_path, O_PATH | O_CLOEXEC | O_NOFOLLOW);

          if (app_fd < 0)
            return glnx_throw_errno_prefix (error, "Failed to open app-path");
        }
    }
  else
    {
      app_fd = FLATPAK_RUN_APP_DEPLOY_APP_ORIGINAL;
    }

  if (opt_usr_fd >= 0 && opt_usr_path != NULL)
    {
      flatpak_fail_error (error, FLATPAK_ERROR,
                          _("usr-fd and usr-path cannot both be used"));
      return FALSE;
    }

  if (opt_usr_fd >= 0)
    {
      usr_fd = opt_usr_fd;
    }
  else if (opt_usr_path != NULL)
    {
      usr_fd = open (opt_usr_path, O_PATH | O_CLOEXEC | O_NOFOLLOW);

      if (usr_fd < 0)
        return glnx_throw_errno_prefix (error, "Failed to open usr-path");
    }
  else
    {
      usr_fd = FLATPAK_RUN_APP_DEPLOY_USR_ORIGINAL;
    }

  if (!flatpak_run_app (app_deploy ? app_ref : runtime_ref,
                        app_deploy,
                        app_fd,
                        arg_context,
                        opt_runtime,
                        opt_runtime_version,
                        opt_runtime_commit,
                        usr_fd,
                        opt_parent_pid,
                        flags,
                        opt_cwd,
                        opt_command,
                        &argv[rest_argv_start + 1],
                        rest_argc - 1,
                        opt_instance_id_fd,
                        (const char * const *) run_environ,
                        NULL,
                        opt_bind_fds,
                        opt_ro_bind_fds,
                        cancellable,
                        error))
    return FALSE;

  /* Not actually reached... */
  return TRUE;
}

gboolean
flatpak_complete_run (FlatpakCompletion *completion)
{
  g_autoptr(GOptionContext) context = NULL;
  g_autoptr(FlatpakDir) user_dir = NULL;
  g_autoptr(GPtrArray) system_dirs = NULL;
  g_autoptr(GError) error = NULL;
  int i;
  g_autoptr(FlatpakContext) arg_context = NULL;

  context = g_option_context_new ("");

  arg_context = flatpak_context_new ();
  g_option_context_add_group (context, flatpak_context_get_options (arg_context));

  if (!flatpak_option_context_parse (context, options, &completion->argc, &completion->argv,
                                     FLATPAK_BUILTIN_FLAG_ALL_DIRS | FLATPAK_BUILTIN_FLAG_OPTIONAL_REPO,
                                     NULL, NULL, NULL))
    return FALSE;

  switch (completion->argc)
    {
    case 0:
    case 1: /* NAME */
      flatpak_complete_options (completion, global_entries);
      flatpak_complete_options (completion, user_entries);
      flatpak_complete_options (completion, options);
      flatpak_complete_context (completion);

      user_dir = flatpak_dir_get_user ();
      {
        g_autoptr(GPtrArray) refs = flatpak_dir_find_installed_refs (user_dir, NULL, NULL, opt_arch,
                                                                     FLATPAK_KINDS_APP,
                                                                     FIND_MATCHING_REFS_FLAGS_NONE,
                                                                     &error);
        if (refs == NULL)
          flatpak_completion_debug ("find local refs error: %s", error->message);

        flatpak_complete_ref_id (completion, refs);
      }

      system_dirs = flatpak_dir_get_system_list (NULL, &error);
      if (system_dirs == NULL)
        {
          flatpak_completion_debug ("find system installations error: %s", error->message);
          break;
        }

      for (i = 0; i < system_dirs->len; i++)
        {
          FlatpakDir *dir = g_ptr_array_index (system_dirs, i);
          g_autoptr(GPtrArray) refs = flatpak_dir_find_installed_refs (dir, NULL, NULL, opt_arch,
                                                                       FLATPAK_KINDS_APP,
                                                                       FIND_MATCHING_REFS_FLAGS_NONE,
                                                                       &error);
          if (refs == NULL)
            flatpak_completion_debug ("find local refs error: %s", error->message);

          flatpak_complete_ref_id (completion, refs);
        }

      break;
    }

  return TRUE;
}

===== ./app/flatpak-builtins-build-bundle.c =====
/* vi:set et sw=2 sts=2 cin cino=t0,f0,(0,{s,>2s,n-s,^-s,e-s:
 * Copyright © 2015 Red Hat, Inc
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Alexander Larsson <alexl@redhat.com>
 */

#include "config.h"

#include <locale.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

#include <json-glib/json-glib.h>

#include <glib/gi18n.h>

#include <gio/gunixinputstream.h>

#include "libglnx.h"

#include "flatpak-builtins.h"
#include "flatpak-repo-utils-private.h"
#include "flatpak-utils-private.h"
#include "flatpak-oci-registry-private.h"
#include "flatpak-chain-input-stream-private.h"
#include "flatpak-builtins-utils.h"

#include <archive.h>
#include <archive_entry.h>

static char *opt_arch;
static char *opt_repo_url;
static char *opt_runtime_repo;
static gboolean opt_runtime = FALSE;
static char **opt_gpg_file;
static gboolean opt_oci = FALSE;
static gboolean opt_oci_use_labels = TRUE; // Unused now
static char *opt_oci_layer_compress;
static char **opt_gpg_key_ids;
static char *opt_gpg_homedir;
static char *opt_from_commit;

static GOptionEntry options[] = {
  { "runtime", 0, 0, G_OPTION_ARG_NONE, &opt_runtime, N_("Export runtime instead of app"), NULL },
  { "arch", 0, 0, G_OPTION_ARG_STRING, &opt_arch, N_("Arch to bundle for"), N_("ARCH") },
  { "repo-url", 0, 0, G_OPTION_ARG_STRING, &opt_repo_url, N_("URL for repo"), N_("URL") },
  { "runtime-repo", 0, 0, G_OPTION_ARG_STRING, &opt_runtime_repo, N_("URL for runtime flatpakrepo file"), N_("URL") },
  { "gpg-keys", 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &opt_gpg_file, N_("Add GPG key from FILE (- for stdin)"), N_("FILE") },
  { "gpg-sign", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_gpg_key_ids, N_("GPG Key ID to sign the OCI image with"), N_("KEY-ID") },
  { "gpg-homedir", 0, 0, G_OPTION_ARG_STRING, &opt_gpg_homedir, N_("GPG Homedir to use when looking for keyrings"), N_("HOMEDIR") },
  { "from-commit", 0, 0, G_OPTION_ARG_STRING, &opt_from_commit, N_("OSTree commit to create a delta bundle from"), N_("COMMIT") },
  { "oci", 0, 0, G_OPTION_ARG_NONE, &opt_oci, N_("Export oci image instead of flatpak bundle"), NULL },
  // This is not used anymore as it is the default, but accept it if old code uses it
  { "oci-use-labels", 0, G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_NONE, &opt_oci_use_labels, NULL, NULL },
  { "oci-layer-compress", 0, 0, G_OPTION_ARG_STRING, &opt_oci_layer_compress, N_("How to compress OCI image layers (default: gzip)"), "gzip|zstd" },
  { NULL }
};

static GBytes *
read_gpg_data (GCancellable *cancellable,
               GError      **error)
{
  g_autoptr(GInputStream) source_stream = NULL;
  guint n_keyrings = 0;
  g_autoptr(GPtrArray) streams = NULL;

  if (opt_gpg_file != NULL)
    n_keyrings = g_strv_length (opt_gpg_file);

  guint ii;

  streams = g_ptr_array_new_with_free_func (g_object_unref);

  for (ii = 0; ii < n_keyrings; ii++)
    {
      GInputStream *input_stream = NULL;

      if (strcmp (opt_gpg_file[ii], "-") == 0)
        {
          input_stream = g_unix_input_stream_new (STDIN_FILENO, FALSE);
        }
      else
        {
          g_autoptr(GFile) file = g_file_new_for_commandline_arg (opt_gpg_file[ii]);
          input_stream = G_INPUT_STREAM (g_file_read (file, cancellable, error));

          if (input_stream == NULL)
            return NULL;
        }

      /* Takes ownership. */
      g_ptr_array_add (streams, input_stream);
    }

  /* Chain together all the --keyring options as one long stream. */
  source_stream = (GInputStream *) flatpak_chain_input_stream_new (streams);

  return flatpak_read_stream (source_stream, FALSE, error);
}

static gboolean
get_bundle_appstream_data (GFile        *root,
                           const char   *full_branch,
                           const char   *name,
                           GKeyFile     *metadata,
                           gboolean      compress,
                           GBytes      **result,
                           GCancellable *cancellable,
                           GError      **error)
{
  g_autoptr(GFile) xmls_dir = NULL;
  g_autofree char *appstream_basename = NULL;
  g_autoptr(GFile) appstream_file = NULL;
  g_autoptr(GInputStream) xml_in = NULL;

  *result = NULL;

  xmls_dir = g_file_resolve_relative_path (root, "files/share/app-info/xmls");
  appstream_basename = g_strconcat (name, ".xml.gz", NULL);
  appstream_file = g_file_get_child (xmls_dir, appstream_basename);

  xml_in = (GInputStream *) g_file_read (appstream_file, cancellable, NULL);
  if (xml_in)
    {
      g_autoptr(FlatpakXml) appstream_root = NULL;
      g_autoptr(FlatpakXml) xml_root = flatpak_xml_parse (xml_in, TRUE,
                                                          cancellable, error);
      if (xml_root == NULL)
        return FALSE;

      appstream_root = flatpak_appstream_xml_new ();
      if (flatpak_appstream_xml_migrate (xml_root, appstream_root,
                                         full_branch, name, metadata))
        {
          g_autoptr(GBytes) xml_data = NULL;
          gboolean success = FALSE;

          if (compress)
            success = flatpak_appstream_xml_root_to_data (appstream_root, NULL, &xml_data, error);
          else
            success = flatpak_appstream_xml_root_to_data (appstream_root, &xml_data, NULL, error);

          if (!success)
            return FALSE;

          *result = g_steal_pointer (&xml_data);
        }
    }

  return TRUE;
}

typedef void (*IterateBundleIconsCallback) (const char *icon_size_name,
                                            GBytes     *png_data,
                                            gpointer    user_data);

static gboolean
iterate_bundle_icons (GFile                     *root,
                      const char                *name,
                      IterateBundleIconsCallback callback,
                      gpointer                   user_data,
                      GCancellable              *cancellable,
                      GError                   **error)
{
  g_autoptr(GFile) icons_dir =
    g_file_resolve_relative_path (root,
                                  "files/share/app-info/icons/flatpak");
  const char *icon_sizes[] = { "64x64", "128x128" };
  const char *icon_sizes_key[] = { "icon-64", "icon-128" };
  g_autofree char *icon_name = g_strconcat (name, ".png", NULL);
  gint i;

  for (i = 0; i < G_N_ELEMENTS (icon_sizes); i++)
    {
      g_autoptr(GFile) size_dir = g_file_get_child (icons_dir, icon_sizes[i]);
      g_autoptr(GFile) icon_file = g_file_get_child (size_dir, icon_name);
      g_autoptr(GInputStream) png_in = NULL;

      png_in = (GInputStream *) g_file_read (icon_file, cancellable, NULL);
      if (png_in != NULL)
        {
          g_autoptr(GBytes) png_data = flatpak_read_stream (png_in, FALSE, error);
          if (png_data == NULL)
            return FALSE;

          callback (icon_sizes_key[i], png_data, user_data);
        }
    }

  return TRUE;
}

static void
add_icon_to_metadata (const char *icon_size_name,
                      GBytes     *png_data,
                      gpointer    user_data)
{
  GVariantBuilder *metadata_builder = user_data;

  g_variant_builder_add (metadata_builder, "{sv}", icon_size_name,
                         g_variant_new_from_bytes (G_VARIANT_TYPE_BYTESTRING,
                                                   png_data, TRUE));
}

static gboolean
build_bundle (OstreeRepo *repo, const char *commit_checksum, GFile *file,
              const char *name, const char *full_branch,
              const char *from_commit,
              GCancellable *cancellable, GError **error)
{
  GVariantBuilder metadata_builder;
  GVariantBuilder param_builder;
  g_autoptr(GKeyFile) keyfile = NULL;
  g_autoptr(GBytes) xml_data = NULL;
  g_autoptr(GFile) metadata_file = NULL;
  g_autoptr(GInputStream) in = NULL;
  g_autoptr(GFile) root = NULL;
  g_autoptr(GBytes) gpg_data = NULL;
  g_autoptr(GVariant) params = NULL;
  g_autoptr(GVariant) metadata = NULL;
  const char *collection_id;

  if (!ostree_repo_read_commit (repo, commit_checksum, &root, NULL, NULL, error))
    return FALSE;

  g_variant_builder_init (&metadata_builder, G_VARIANT_TYPE ("a{sv}"));

  /* We add this first in the metadata, so this will become the file
   * format header.  The first part is readable to make it easy to
   * figure out the type. The uint32 is basically a random value, but
   * it ensures we have both zero and high bits sets, so we don't get
   * sniffed as text. Also, the last 01 can be used as a version
   * later.  Furthermore, the use of an uint32 lets us detect
   * byteorder issues.
   */
  g_variant_builder_add (&metadata_builder, "{sv}", "flatpak",
                         g_variant_new_uint32 (0xe5890001));

  g_variant_builder_add (&metadata_builder, "{sv}", "ref", g_variant_new_string (full_branch));

  metadata_file = g_file_resolve_relative_path (root, "metadata");

  keyfile = g_key_file_new ();

  in = (GInputStream *) g_file_read (metadata_file, cancellable, NULL);
  if (in != NULL)
    {
      g_autoptr(GBytes) bytes = flatpak_read_stream (in, TRUE, error);

      if (bytes == NULL)
        return FALSE;

      if (!g_key_file_load_from_data (keyfile,
                                      g_bytes_get_data (bytes, NULL),
                                      g_bytes_get_size (bytes),
                                      G_KEY_FILE_NONE, error))
        return FALSE;

      g_variant_builder_add (&metadata_builder, "{sv}", "metadata",
                             g_variant_new_string (g_bytes_get_data (bytes, NULL)));
    }

  if (!get_bundle_appstream_data (root, full_branch, name, keyfile, TRUE,
                                  &xml_data, cancellable, error))
    return FALSE;

  if (xml_data)
    {
      g_variant_builder_add (&metadata_builder, "{sv}", "appdata",
                             g_variant_new_from_bytes (G_VARIANT_TYPE_BYTESTRING,
                                                       xml_data, TRUE));

      if (!iterate_bundle_icons (root, name, add_icon_to_metadata,
                                 &metadata_builder, cancellable, error))
        return FALSE;
    }

  if (opt_repo_url)
    g_variant_builder_add (&metadata_builder, "{sv}", "origin", g_variant_new_string (opt_repo_url));

  if (opt_runtime_repo)
    g_variant_builder_add (&metadata_builder, "{sv}", "runtime-repo", g_variant_new_string (opt_runtime_repo));

  collection_id = ostree_repo_get_collection_id (repo);
  g_variant_builder_add (&metadata_builder, "{sv}", "collection-id",
                         g_variant_new_string (collection_id ? collection_id : ""));

  if (opt_gpg_file != NULL)
    {
      gpg_data = read_gpg_data (cancellable, error);
      if (gpg_data == NULL)
        return FALSE;
    }

  if (gpg_data)
    {
      g_variant_builder_add (&metadata_builder, "{sv}", "gpg-keys",
                             g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE,
                                                        g_bytes_get_data (gpg_data, NULL),
                                                        g_bytes_get_size (gpg_data),
                                                        1));
    }

  g_variant_builder_init (&param_builder, G_VARIANT_TYPE ("a{sv}"));
  g_variant_builder_add (&param_builder, "{sv}", "min-fallback-size", g_variant_new_uint32 (0));
  g_variant_builder_add (&param_builder, "{sv}", "compression", g_variant_new_byte ('x'));
  g_variant_builder_add (&param_builder, "{sv}", "bsdiff-enabled", g_variant_new_boolean (FALSE));
  g_variant_builder_add (&param_builder, "{sv}", "inline-parts", g_variant_new_boolean (TRUE));
  g_variant_builder_add (&param_builder, "{sv}", "include-detached", g_variant_new_boolean (TRUE));
  g_variant_builder_add (&param_builder, "{sv}", "filename", g_variant_new_bytestring (flatpak_file_get_path_cached (file)));

  params = g_variant_ref_sink (g_variant_builder_end (&param_builder));
  metadata = g_variant_ref_sink (g_variant_builder_end (&metadata_builder));

  if (!ostree_repo_static_delta_generate (repo,
                                          OSTREE_STATIC_DELTA_GENERATE_OPT_LOWLATENCY,
                                          from_commit,
                                          commit_checksum,
                                          metadata,
                                          params,
                                          cancellable,
                                          error))
    return FALSE;

  return TRUE;
}

static gchar *
timestamp_to_iso8601 (guint64 timestamp)
{
  GTimeVal stamp;

  stamp.tv_sec = timestamp;
  stamp.tv_usec = 0;

  return g_time_val_to_iso8601 (&stamp);
}

static gboolean
export_commit_to_archive (OstreeRepo *repo,
                          GFile *root,
                          guint64 timestamp,
                          struct archive *a,
                          GCancellable *cancellable, GError **error)
{
  OstreeRepoExportArchiveOptions opts = { 0, };

  opts.timestamp_secs = timestamp;

  if (!ostree_repo_export_tree_to_archive (repo, &opts, (OstreeRepoFile *) root, a,
                                           cancellable, error))
    return FALSE;

  return TRUE;
}

static void
add_icon_to_labels (const char *icon_size_name,
                    GBytes     *png_data,
                    gpointer    user_data)
{
  GHashTable *labels = user_data;
  g_autofree char *encoded = g_base64_encode (g_bytes_get_data (png_data, NULL),
                                              g_bytes_get_size (png_data));

  g_hash_table_replace (labels,
                        g_strconcat ("org.freedesktop.appstream.", icon_size_name, NULL),
                        g_strconcat ("data:image/png;base64,", encoded, NULL));
}

static GHashTable *
generate_labels (FlatpakOciDescriptor *layer_desc,
                 OstreeRepo *repo,
                 GFile *root,
                 const char *name,
                 const char *ref,
                 const char *commit_checksum,
                 const char *runtime_repo,
                 GVariant   *commit_data,
                 GCancellable *cancellable,
                 GError **error)
{
  g_autoptr(GFile) metadata_file = NULL;
  gsize metadata_size;
  g_autofree char *metadata_contents = NULL;
  g_autoptr(GHashTable) labels = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
  g_autoptr(GKeyFile) keyfile = NULL;
  g_autoptr(GBytes) xml_data = NULL;
  guint64 installed_size = 0;

  flatpak_oci_add_labels_for_commit (labels, ref, commit_checksum, commit_data);

  metadata_file = g_file_get_child (root, "metadata");
  if (g_file_load_contents (metadata_file, cancellable, &metadata_contents, &metadata_size, NULL, NULL) &&
      g_utf8_validate (metadata_contents, -1, NULL))
    {
      keyfile = g_key_file_new ();

      if (!g_key_file_load_from_data (keyfile,
                                      metadata_contents,
                                      metadata_size,
                                      G_KEY_FILE_NONE, error))
        return NULL;

      g_hash_table_replace (labels,
                            g_strdup ("org.flatpak.metadata"),
                            g_steal_pointer (&metadata_contents));
    }

  if (!flatpak_repo_collect_sizes (repo, root, &installed_size, NULL, NULL, error))
    return NULL;

  g_hash_table_replace (labels,
                        g_strdup ("org.flatpak.installed-size"),
                        g_strdup_printf ("%" G_GUINT64_FORMAT, installed_size));

  g_hash_table_replace (labels,
                        g_strdup ("org.flatpak.download-size"),
                        g_strdup_printf ("%" G_GUINT64_FORMAT, layer_desc->size));


  if (runtime_repo)
    g_hash_table_replace (labels,
                          g_strdup ("org.flatpak.runtime-repo"),
                          g_strdup (runtime_repo));

  if (!get_bundle_appstream_data (root, ref, name, keyfile, FALSE,
                                  &xml_data, cancellable, error))
    return FALSE;

  if (xml_data)
    {
      gsize xml_data_len;

      g_hash_table_replace (labels,
                            g_strdup ("org.freedesktop.appstream.appdata"),
                            g_bytes_unref_to_data (g_steal_pointer (&xml_data), &xml_data_len));

      if (!iterate_bundle_icons (root, name, add_icon_to_labels,
                                 labels, cancellable, error))
        return FALSE;
    }

  return g_steal_pointer (&labels);
}



static gboolean
build_oci (OstreeRepo                 *repo,
           const char                 *commit_checksum,
           GFile                      *dir,
           const char                 *name,
           const char                 *ref_str,
           FlatpakOciWriteLayerFlags   write_layer_flags,
           GCancellable               *cancellable,
           GError                    **error)
{
  g_autoptr(GFile) root = NULL;
  g_autoptr(GVariant) commit_data = NULL;
  g_autoptr(GVariant) commit_metadata = NULL;
  g_autofree char *dir_uri = NULL;
  g_autoptr(FlatpakOciRegistry) registry = NULL;
  g_autoptr(FlatpakOciLayerWriter) layer_writer = NULL;
  struct archive *archive;
  g_autofree char *uncompressed_digest = NULL;
  g_autofree char *timestamp = NULL;
  g_autoptr(FlatpakOciImage) image = NULL;
  g_autoptr(FlatpakOciDescriptor) layer_desc = NULL;
  g_autoptr(FlatpakOciDescriptor) image_desc = NULL;
  g_autoptr(FlatpakOciDescriptor) manifest_desc = NULL;
  g_autoptr(FlatpakOciManifest) manifest = NULL;
  g_autoptr(FlatpakOciIndex) index = NULL;
  g_autoptr(GHashTable) flatpak_labels = NULL;
  g_autoptr(FlatpakDecomposed) ref = NULL;
  g_autofree char *arch = NULL;
  int history_index;
  GTimeVal tv;

  if (!ostree_repo_read_commit (repo, commit_checksum, &root, NULL, NULL, error))
    return FALSE;

  if (!ostree_repo_load_variant (repo, OSTREE_OBJECT_TYPE_COMMIT, commit_checksum, &commit_data, error))
    return FALSE;

  if (!ostree_repo_read_commit_detached_metadata (repo, commit_checksum, &commit_metadata, cancellable, error))
    return FALSE;

  ref = flatpak_decomposed_new_from_ref (ref_str, error);
  if (ref == NULL)
    return FALSE;

  arch = flatpak_decomposed_dup_arch (ref);

  dir_uri = g_file_get_uri (dir);
  registry = flatpak_oci_registry_new (dir_uri, TRUE, -1, cancellable, error);
  if (registry == NULL)
    return FALSE;

  layer_writer = flatpak_oci_registry_write_layer (registry, write_layer_flags, cancellable, error);
  if (layer_writer == NULL)
    return FALSE;

  archive = flatpak_oci_layer_writer_get_archive (layer_writer);

  if (!export_commit_to_archive (repo, root, ostree_commit_get_timestamp (commit_data),
                                 archive, cancellable, error))
    return FALSE;

  if (!flatpak_oci_layer_writer_close (layer_writer,
                                       &uncompressed_digest,
                                       &layer_desc,
                                       cancellable,
                                       error))
    return FALSE;

  flatpak_labels = generate_labels (layer_desc, repo, root, name, flatpak_decomposed_get_ref (ref), commit_checksum, opt_runtime_repo, commit_data, cancellable, error);
  if (flatpak_labels == NULL)
    return FALSE;

  image = flatpak_oci_image_new ();
  flatpak_oci_image_set_layer (image, uncompressed_digest);
  flatpak_oci_image_set_architecture (image, flatpak_arch_to_oci_arch (arch));
  history_index = flatpak_oci_image_add_history (image);

  g_get_current_time (&tv);
  image->history[history_index]->created = g_time_val_to_iso8601 (&tv);
  image->history[history_index]->created_by = g_strdup ("flatpak build-bundle");

  flatpak_oci_copy_labels (flatpak_labels,
                           flatpak_oci_image_get_labels (image));

  timestamp = timestamp_to_iso8601 (ostree_commit_get_timestamp (commit_data));
  flatpak_oci_image_set_created (image, timestamp);

  image_desc = flatpak_oci_registry_store_json (registry, FLATPAK_JSON (image), cancellable, error);
  if (image_desc == NULL)
    return FALSE;

  manifest = flatpak_oci_manifest_new ();
  flatpak_oci_manifest_set_config (manifest, image_desc);
  flatpak_oci_manifest_set_layer (manifest, layer_desc);

  manifest_desc = flatpak_oci_registry_store_json (registry, FLATPAK_JSON (manifest), cancellable, error);
  if (manifest_desc == NULL)
    return FALSE;

  index = flatpak_oci_registry_load_index (registry, NULL, NULL);
  if (index == NULL)
    index = flatpak_oci_index_new ();

  flatpak_oci_index_add_manifest (index, flatpak_decomposed_get_ref (ref), manifest_desc);

  if (!flatpak_oci_registry_save_index (registry, index, cancellable, error))
    return FALSE;

  return TRUE;
}

static gboolean
_repo_resolve_rev (OstreeRepo *repo, const char *ref, char **out_rev,
                   GCancellable *cancellable, GError **error)
{
  g_autoptr(GError) my_error = NULL;

  g_return_val_if_fail (repo != NULL, FALSE);
  g_return_val_if_fail (ref != NULL, FALSE);
  g_return_val_if_fail (out_rev != NULL, FALSE);
  g_return_val_if_fail (*out_rev == NULL, FALSE);

  if (ostree_repo_resolve_rev (repo, ref, FALSE, out_rev, &my_error))
    return TRUE;
  else
    {
      g_autoptr(GHashTable) collection_refs = NULL;  /* (element-type OstreeCollectionRef utf8) */

      /* Fall back to iterating over every collection-ref. We can't use
       * ostree_repo_resolve_collection_ref() since we don't know the
       * collection ID. */
      if (!ostree_repo_list_collection_refs (repo, NULL, &collection_refs,
                                             OSTREE_REPO_LIST_REFS_EXT_NONE,
                                             cancellable, error))
        return FALSE;

      /* Take the checksum of the first matching ref. There's no point in
       * checking for duplicates because (a) it's not possible to install the
       * same app from two collections in the same flatpak installation and (b)
       * ostree_repo_resolve_rev() also takes the first matching ref. */
      GLNX_HASH_TABLE_FOREACH_KV (collection_refs, const OstreeCollectionRef *, c_r,
                                  const char*, checksum)
        {
          if (g_strcmp0 (c_r->ref_name, ref) == 0)
            {
              *out_rev = g_strdup (checksum);
              return TRUE;
            }
        }

      g_propagate_error (error, g_steal_pointer (&my_error));
      return FALSE;
    }
}

gboolean
flatpak_builtin_build_bundle (int argc, char **argv, GCancellable *cancellable, GError **error)
{
  g_autoptr(GOptionContext) context = NULL;
  g_autoptr(GFile) file = NULL;
  g_autoptr(GFile) repofile = NULL;
  g_autoptr(OstreeRepo) repo = NULL;
  g_autoptr(GError) my_error = NULL;
  const char *location;
  const char *filename;
  const char *name;
  const char *branch;
  g_autofree char *full_branch = NULL;
  g_autofree char *commit_checksum = NULL;

  context = g_option_context_new (_("LOCATION FILENAME NAME [BRANCH] - Create a single file bundle from a local repository"));
  g_option_context_set_translation_domain (context, GETTEXT_PACKAGE);

  if (!flatpak_option_context_parse (context, options, &argc, &argv, FLATPAK_BUILTIN_FLAG_NO_DIR, NULL, cancellable, error))
    return FALSE;

  if (argc < 4)
    return usage_error (context, _("LOCATION, FILENAME and NAME must be specified"), error);

  if (argc > 5)
    return usage_error (context, _("Too many arguments"), error);

  location = argv[1];
  filename = argv[2];
  name = argv[3];

  if (argc >= 5)
    branch = argv[4];
  else
    branch = "master";

  repofile = g_file_new_for_commandline_arg (location);
  repo = ostree_repo_new (repofile);

  if (!g_file_query_exists (repofile, cancellable))
    return flatpak_fail (error, _("'%s' is not a valid repository"), location);

  if (!ostree_repo_open (repo, cancellable, error))
    {
      g_prefix_error (error, _("'%s' is not a valid repository: "), location);
      return FALSE;
    }

  /* We can't use flatpak_repo_resolve_rev() here because it takes a NULL
   * remote name to mean the ref is local. */
  if (_repo_resolve_rev (repo, name, &commit_checksum, NULL, NULL))
    full_branch = g_strdup (name);
  else
    {
      if (!flatpak_is_valid_name (name, -1, &my_error))
        return flatpak_fail (error, _("'%s' is not a valid name: %s"), name, my_error->message);

      if (!flatpak_is_valid_branch (branch, -1, &my_error))
        return flatpak_fail (error, _("'%s' is not a valid branch name: %s"), branch, my_error->message);

      if (opt_runtime)
        full_branch = flatpak_build_runtime_ref (name, branch, opt_arch);
      else
        full_branch = flatpak_build_app_ref (name, branch, opt_arch);

      if (!_repo_resolve_rev (repo, full_branch, &commit_checksum, cancellable, error))
        return FALSE;
    }

  file = g_file_new_for_commandline_arg (filename);

  if (flatpak_file_get_path_cached (file) == NULL)
    return flatpak_fail (error, _("'%s' is not a valid filename"), filename);

  if (opt_oci)
    {
      FlatpakOciWriteLayerFlags write_layer_flags =
        FLATPAK_OCI_WRITE_LAYER_FLAGS_NONE;

      if (opt_oci_layer_compress == NULL)
        opt_oci_layer_compress = "gzip";

      if (strcmp(opt_oci_layer_compress, "gzip") == 0)
        write_layer_flags |= FLATPAK_OCI_WRITE_LAYER_FLAGS_NONE;
      else if (strcmp(opt_oci_layer_compress, "zstd") == 0)
        write_layer_flags |= FLATPAK_OCI_WRITE_LAYER_FLAGS_ZSTD;
      else
        return usage_error (context, _("--oci-layer-compress value must be gzip or zstd"), error);

      if (!build_oci (repo, commit_checksum, file, name, full_branch, write_layer_flags, cancellable, error))
        return FALSE;
    }
  else
    {
      if (!build_bundle (repo, commit_checksum, file, name, full_branch, opt_from_commit, cancellable, error))
        return FALSE;
    }

  return TRUE;
}

gboolean
flatpak_complete_build_bundle (FlatpakCompletion *completion)
{
  g_autoptr(GOptionContext) context = NULL;

  context = g_option_context_new ("");

  if (!flatpak_option_context_parse (context, options, &completion->argc, &completion->argv,
                                     FLATPAK_BUILTIN_FLAG_NO_DIR, NULL, NULL, NULL))
    return FALSE;

  switch (completion->argc)
    {
    case 0:
    case 1: /* LOCATION */
      flatpak_complete_options (completion, global_entries);
      flatpak_complete_options (completion, options);

      flatpak_complete_dir (completion);
      break;

    case 2: /* FILENAME */
      flatpak_complete_file (completion, "__FLATPAK_BUNDLE_FILE");
      break;
    }

  return TRUE;
}

===== ./app/flatpak-builtins-remote-list.c =====
/* vi:set et sw=2 sts=2 cin cino=t0,f0,(0,{s,>2s,n-s,^-s,e-s:
 * Copyright © 2014 Red Hat, Inc
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Alexander Larsson <alexl@redhat.com>
 */

#include "config.h"

#include <locale.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include <glib/gi18n.h>

#include "libglnx.h"

#include "flatpak-builtins.h"
#include "flatpak-builtins-utils.h"
#include "flatpak-utils-private.h"
#include "flatpak-table-printer.h"

static gboolean opt_show_details;
static gboolean opt_show_disabled;
static const char **opt_cols;
static gboolean opt_json;

static GOptionEntry options[] = {
  { "show-details", 'd', 0, G_OPTION_ARG_NONE, &opt_show_details, N_("Show remote details"), NULL },
  { "show-disabled", 0, 0, G_OPTION_ARG_NONE, &opt_show_disabled, N_("Show disabled remotes"), NULL },
  { "columns", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_cols, N_("What information to show"), N_("FIELD,…") },
  { "json", 'j', 0, G_OPTION_ARG_NONE, &opt_json, N_("Show output in JSON format"), NULL },
  { NULL }
};

static Column all_columns[] = {
  { "name",       N_("Name"),          N_("Show the name"),          0, FLATPAK_ELLIPSIZE_MODE_NONE, 1, 1 },
  { "title",      N_("Title"),         N_("Show the title"),         0, FLATPAK_ELLIPSIZE_MODE_NONE, 1, 0 },
  { "url",        N_("URL"),           N_("Show the URL"),           0, FLATPAK_ELLIPSIZE_MODE_NONE, 1, 0 },
  { "collection", N_("Collection ID"), N_("Show the collection ID"), 0, FLATPAK_ELLIPSIZE_MODE_NONE, 1, 0 },
  { "subset",     N_("Subset"),        N_("Show the subset"),        0, FLATPAK_ELLIPSIZE_MODE_NONE, 1, 0 },
  { "filter",     N_("Filter"),        N_("Show filter file"),       0, FLATPAK_ELLIPSIZE_MODE_NONE, 1, 0 },
  { "priority",   N_("Priority"),      N_("Show the priority"),      0, FLATPAK_ELLIPSIZE_MODE_NONE, 1, 0 },
  { "options",    N_("Options"),       N_("Show options"),           0, FLATPAK_ELLIPSIZE_MODE_NONE, 1, 1 },
  { "comment",    N_("Comment"),       N_("Show comment"),           0, FLATPAK_ELLIPSIZE_MODE_END,  1, 0 },
  { "description", N_("Description"),  N_("Show description"),       0, FLATPAK_ELLIPSIZE_MODE_END,  1, 0 },
  { "homepage",   N_("Homepage"),      N_("Show homepage"),          0, FLATPAK_ELLIPSIZE_MODE_NONE,  1, 0 },
  { "icon",       N_("Icon"),          N_("Show icon"),              0, FLATPAK_ELLIPSIZE_MODE_NONE,  1, 0 },
  { NULL }
};

static gboolean
list_remotes (GPtrArray *dirs, Column *columns, GCancellable *cancellable, GError **error)
{
  g_autoptr(FlatpakTablePrinter) printer = NULL;
  int i, j, k;

  if (columns[0].name == NULL)
    return TRUE;

  printer = flatpak_table_printer_new ();
  flatpak_table_printer_set_columns (printer, columns,
                                     opt_cols == NULL && !opt_show_details);

  for (j = 0; j < dirs->len; j++)
    {
      FlatpakDir *dir = g_ptr_array_index (dirs, j);
      g_auto(GStrv) remotes = NULL;

      remotes = flatpak_dir_list_remotes (dir, cancellable, error);
      if (remotes == NULL)
        return FALSE;

      for (i = 0; remotes[i] != NULL; i++)
        {
          char *remote_name = remotes[i];
          gboolean disabled;

          disabled = flatpak_dir_get_remote_disabled (dir, remote_name);
          if (disabled && !opt_show_disabled)
            continue;

          for (k = 0; columns[k].name; k++)
            {
              if (strcmp (columns[k].name, "name") == 0)
                flatpak_table_printer_add_column (printer, remote_name);
              else if (strcmp (columns[k].name, "title") == 0)
                {
                  g_autofree char *title = flatpak_dir_get_remote_title (dir, remote_name);
                  if (title)
                    flatpak_table_printer_add_column (printer, title);
                  else
                    flatpak_table_printer_add_column (printer, "-");
                }
              else if (strcmp (columns[k].name, "subset") == 0)
                {
                  g_autofree char *subset = flatpak_dir_get_remote_subset (dir, remote_name);
                  if (subset)
                    flatpak_table_printer_add_column (printer, subset);
                  else
                    flatpak_table_printer_add_column (printer, "-");
                }
              else if (strcmp (columns[k].name, "comment") == 0)
                {
                  g_autofree char *comment = flatpak_dir_get_remote_comment (dir, remote_name);
                  if (comment)
                    flatpak_table_printer_add_column (printer, comment);
                  else
                    flatpak_table_printer_add_column (printer, "-");
                }
              else if (strcmp (columns[k].name, "description") == 0)
                {
                  g_autofree char *description = flatpak_dir_get_remote_description (dir, remote_name);
                  if (description)
                    flatpak_table_printer_add_column (printer, description);
                  else
                    flatpak_table_printer_add_column (printer, "-");
                }
              else if (strcmp (columns[k].name, "filter") == 0)
                {
                  g_autofree char *filter = flatpak_dir_get_remote_filter (dir, remote_name);
                  if (filter)
                    flatpak_table_printer_add_column (printer, filter);
                  else
                    flatpak_table_printer_add_column (printer, "-");
                }
              else if (strcmp (columns[k].name, "homepage") == 0)
                {
                  g_autofree char *homepage = flatpak_dir_get_remote_homepage (dir, remote_name);
                  if (homepage)
                    flatpak_table_printer_add_column (printer, homepage);
                  else
                    flatpak_table_printer_add_column (printer, "-");
                }
              else if (strcmp (columns[k].name, "icon") == 0)
                {
                  g_autofree char *icon = flatpak_dir_get_remote_icon (dir, remote_name);
                  if (icon)
                    flatpak_table_printer_add_column (printer, icon);
                  else
                    flatpak_table_printer_add_column (printer, "-");
                }
              else if (strcmp (columns[k].name, "url") == 0)
                {
                  g_autofree char *remote_url = NULL;

                  if (ostree_repo_remote_get_url (flatpak_dir_get_repo (dir), remote_name, &remote_url, NULL))
                    flatpak_table_printer_add_column (printer, remote_url);
                  else
                    flatpak_table_printer_add_column (printer, "-");
                }
              else if (strcmp (columns[k].name, "collection") == 0)
                {
                  g_autofree char *id = flatpak_dir_get_remote_collection_id (dir, remote_name);
                  if (id != NULL)
                    flatpak_table_printer_add_column (printer, id);
                  else
                    flatpak_table_printer_add_column (printer, "-");
                }
              else if (strcmp (columns[k].name, "priority") == 0)
                {
                  int prio = flatpak_dir_get_remote_prio (dir, remote_name);
                  g_autofree char *prio_as_string = g_strdup_printf ("%d", prio);
                  flatpak_table_printer_add_column (printer, prio_as_string);
                }
              else if (strcmp (columns[k].name, "options") == 0)
                {
                  gboolean gpg_verify = TRUE;
                  g_autofree char *filter = flatpak_dir_get_remote_filter (dir, remote_name);

                  flatpak_table_printer_add_column (printer, ""); /* Options */

                  if (dirs->len > 1)
                    {
                      g_autofree char *dir_id = flatpak_dir_get_name (dir);
                      flatpak_table_printer_append_with_comma (printer, dir_id);
                    }

                  if (disabled)
                    flatpak_table_printer_append_with_comma (printer, "disabled");

                  if (flatpak_dir_get_remote_oci (dir, remote_name))
                    flatpak_table_printer_append_with_comma (printer, "oci");

                  if (flatpak_dir_get_remote_noenumerate (dir, remote_name))
                    flatpak_table_printer_append_with_comma (printer, "no-enumerate");

                  if (!ostree_repo_remote_get_gpg_verify (flatpak_dir_get_repo (dir), remote_name,
                                                          &gpg_verify, error))
                      return FALSE; /* shouldn't happen unless repo config is modified out-of-band */

                  if (!gpg_verify)
                    flatpak_table_printer_append_with_comma (printer, "no-gpg-verify");

                  if (filter != NULL && *filter != 0)
                    flatpak_table_printer_append_with_comma (printer, "filtered");
                }
            }

          flatpak_table_printer_finish_row (printer);
        }
    }

  opt_json ? flatpak_table_printer_print_json (printer) : flatpak_table_printer_print (printer);

  return TRUE;
}

gboolean
flatpak_builtin_remote_list (int argc, char **argv, GCancellable *cancellable, GError **error)
{
  g_autoptr(GOptionContext) context = NULL;
  g_autofree char *col_help = NULL;
  g_autofree Column *columns = NULL;
  g_autoptr(GPtrArray) dirs = NULL;

  context = g_option_context_new (_(" - List remote repositories"));
  g_option_context_set_translation_domain (context, GETTEXT_PACKAGE);
  col_help = column_help (all_columns);
  g_option_context_set_description (context, col_help);

  if (!flatpak_option_context_parse (context, options, &argc, &argv,
                                     FLATPAK_BUILTIN_FLAG_STANDARD_DIRS | FLATPAK_BUILTIN_FLAG_OPTIONAL_REPO, &dirs, cancellable, error))
    return FALSE;

  if (argc > 1)
    return usage_error (context, _("Too many arguments"), error);

  columns = handle_column_args (all_columns, opt_show_details, opt_cols, error);
  if (columns == NULL)
    return FALSE;

  return list_remotes (dirs, columns, cancellable, error);
}

gboolean
flatpak_complete_remote_list (FlatpakCompletion *completion)
{
  g_autoptr(GOptionContext) context = NULL;

  context = g_option_context_new ("");
  if (!flatpak_option_context_parse (context, options, &completion->argc, &completion->argv,
                                     FLATPAK_BUILTIN_FLAG_STANDARD_DIRS, NULL, NULL, NULL))
    return FALSE;

  switch (completion->argc)
    {
    case 0:
    case 1:
      flatpak_complete_options (completion, global_entries);
      flatpak_complete_options (completion, options);
      flatpak_complete_options (completion, user_entries);
      flatpak_complete_columns (completion, all_columns);

      break;
    }

  return TRUE;
}

===== ./app/flatpak-builtins-permission-set.c =====
/* vi:set et sw=2 sts=2 cin cino=t0,f0,(0,{s,>2s,n-s,^-s,e-s:
 * Copyright © 2018 Red Hat, Inc
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Matthias Clasen <mclasen@redhat.com>
 */

#include "config.h"

#include <locale.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>

#include <glib/gi18n.h>

#include "libglnx.h"
#include "flatpak-permission-dbus-generated.h"

#include "flatpak-builtins.h"
#include "flatpak-table-printer.h"
#include "flatpak-utils-private.h"
#include "flatpak-run-private.h"

static char *opt_data;

static GOptionEntry options[] = {
  { "data", 0, 0, G_OPTION_ARG_STRING, &opt_data, N_("Associate DATA with the entry"), N_("DATA") },
  { NULL }
};

static const char *tables[] = { "documents", "notifications", "desktop-used-apps", "devices",
                                "location", "inhibit", "background", NULL };
static const char *notification_ids[] = { "notification", NULL };
static const char *device_ids[] = { "speakers", "microphone", "camera", NULL };
static const char *location_ids[] = { "location", NULL };
static const char *inhibit_ids[] = { "inhibit", NULL };
static const char *background_ids[] = { "background", NULL };

static const char *document_perms[] = { "read", "write", "delete", "grant-permissions", NULL };
static const char *notification_perms[] = { "yes", "no", NULL };
static const char *device_perms[] = { "yes", "no", "ask", NULL };
static const char *inhibit_perms[] = { "logout", "switch", "suspend", "idle", NULL };

static const char **
get_known_permission_tables (void)
{
  return tables;
}

static const char **
get_known_ids_for_table (const char *table)
{
  if (strcmp (table, "notifications") == 0)
    return notification_ids;
  else if (strcmp (table, "devices") == 0)
    return device_ids;
  else if (strcmp (table, "location") == 0)
    return location_ids;
  else if (strcmp (table, "inhibit") == 0)
    return inhibit_ids;
  else if (strcmp (table, "background") == 0)
    return background_ids;

  return NULL;
}

static const char **
get_permission_values_for_table (const char *table)
{
  if (strcmp (table, "devices") == 0)
    return device_perms;
  else if (strcmp (table, "documents") == 0)
    return document_perms;
  else if (strcmp (table, "notifications") == 0)
    return notification_perms;
  else if (strcmp (table, "inhibit") == 0)
    return inhibit_perms;

  return NULL;
}

gboolean
flatpak_builtin_permission_set (int argc, char **argv,
                                GCancellable *cancellable,
                                GError **error)
{
  g_autoptr(GOptionContext) context = NULL;
  g_autoptr(GDBusConnection) session_bus = NULL;
  XdpDbusPermissionStore *store = NULL;
  const char *table;
  const char *id;
  const char *app_id;
  const char **perms;
  g_autoptr(GVariant) data = NULL;

  context = g_option_context_new (_("TABLE ID APP_ID [PERMISSION...] - Set permissions"));
  g_option_context_set_translation_domain (context, GETTEXT_PACKAGE);

  if (!flatpak_option_context_parse (context, options, &argc, &argv,
                                     FLATPAK_BUILTIN_FLAG_NO_DIR,
                                     NULL, cancellable, error))
    return FALSE;

  if (argc < 4)
    return usage_error (context, _("Too few arguments"), error);

  table = argv[1];
  id = argv[2];
  app_id = argv[3];
  perms = (const char **)&argv[4];

  if (opt_data)
    {
      data = g_variant_parse (NULL, opt_data, NULL, NULL, error);
      if (!data)
        {
          g_prefix_error (error, _("Failed to parse '%s' as GVariant: "), opt_data);
          return FALSE;
        }
    }

  session_bus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, error);
  if (session_bus == NULL)
    return FALSE;

  store = xdp_dbus_permission_store_proxy_new_sync (session_bus, 0,
                                                    "org.freedesktop.impl.portal.PermissionStore",
                                                    "/org/freedesktop/impl/portal/PermissionStore",
                                                    NULL, error);
  if (store == NULL)
    return FALSE;

  if (!xdp_dbus_permission_store_call_set_permission_sync (store, table, TRUE,
                                                           id, app_id, perms, 
                                                           NULL, error))
    return FALSE;

  if (data)
    {
      if (!xdp_dbus_permission_store_call_set_value_sync (store, table, FALSE,
                                                          id, g_variant_new_variant (data), NULL, error))
        return FALSE;
    }

  return TRUE;
}

gboolean
flatpak_complete_permission_set (FlatpakCompletion *completion)
{
  g_autoptr(GOptionContext) context = NULL;
  g_autoptr(GDBusConnection) session_bus = NULL;
  XdpDbusPermissionStore *store = NULL;
  int i;

  context = g_option_context_new ("");

  if (!flatpak_option_context_parse (context, options, &completion->argc, &completion->argv,
                                     FLATPAK_BUILTIN_FLAG_NO_DIR, NULL, NULL, NULL))
    return FALSE;

  session_bus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL);
  if (session_bus == NULL)
    return FALSE;

  store = xdp_dbus_permission_store_proxy_new_sync (session_bus, 0,
                                                    "org.freedesktop.impl.portal.PermissionStore",
                                                    "/org/freedesktop/impl/portal/PermissionStore",
                                                    NULL, NULL);

  if (store == NULL)
    return FALSE;

  switch (completion->argc)
    {
    case 0:
    case 1: /* TABLE */
      flatpak_complete_options (completion, global_entries);
      flatpak_complete_options (completion, options);

      {
        const char **known_tables = get_known_permission_tables ();
        for (i = 0; known_tables != NULL && known_tables[i] != NULL; i++)
          {
            flatpak_complete_word (completion, "%s ", known_tables[i]);
          }
      }

      break;

    case 2:
      {
        const char **ids = get_known_ids_for_table (completion->argv[1]);
        for (i = 0; ids != NULL && ids[i] != NULL; i++)
          {
            flatpak_complete_word (completion, "%s ", ids[i]);
          }
      }

      break;

    case 3:
      flatpak_complete_partial_ref (completion, FLATPAK_KINDS_APP, FALSE, flatpak_dir_get_user (), NULL);
      flatpak_complete_partial_ref (completion, FLATPAK_KINDS_APP, FALSE, flatpak_dir_get_system_default (), NULL);
      break;

    default:
      {
        const char **vals = get_permission_values_for_table (completion->argv[1]);
        for (i = 0; vals != NULL && vals[i] != NULL; i++)
          {
            int j;
            for (j = 4; j < completion->argc; j++)
              {
                if (strcmp (completion->argv[j], vals[i]) == 0)
                  break;
              }
            if (j == completion->argc)
              flatpak_complete_word (completion, "%s ", vals[i]);
          }
      }

      break;
    }

  return TRUE;
}

===== ./app/flatpak-builtins-mask.c =====
/* vi:set et sw=2 sts=2 cin cino=t0,f0,(0,{s,>2s,n-s,^-s,e-s:
 * Copyright © 2019 Red Hat, Inc
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Alexander Larsson <alexl@redhat.com>
 */

#include "config.h"

#include <locale.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

#include <glib/gi18n.h>

#include "libglnx.h"

#include "flatpak-builtins.h"
#include "flatpak-builtins-utils.h"
#include "flatpak-cli-transaction.h"
#include "flatpak-quiet-transaction.h"
#include "flatpak-utils-private.h"
#include "flatpak-error.h"

static gboolean opt_remove;

static GOptionEntry options[] = {
  { "remove", 0, 0, G_OPTION_ARG_NONE, &opt_remove, N_("Remove matching masks"), NULL },
  { NULL }
};

gboolean
flatpak_builtin_mask (int argc, char **argv, GCancellable *cancellable, GError **error)
{
  g_autoptr(GOptionContext) context = NULL;
  g_autoptr(GPtrArray) dirs = NULL;
  FlatpakDir *dir;
  int i;

  context = g_option_context_new (_("[PATTERN…] - disable updates and automatic installation matching patterns"));
  g_option_context_set_translation_domain (context, GETTEXT_PACKAGE);

  if (!flatpak_option_context_parse (context, options, &argc, &argv,
                                     FLATPAK_BUILTIN_FLAG_ONE_DIR,
                                     &dirs, cancellable, error))
    return FALSE;

  dir = g_ptr_array_index (dirs, 0);

  if (argc == 1)
    {
      g_autoptr(GPtrArray) patterns = NULL;

      patterns = flatpak_dir_get_config_patterns (dir, "masked");

      if (patterns->len == 0)
        {
          if (flatpak_fancy_output ())
            g_print (_("No masked patterns\n"));
        }
      else
        {
          if (flatpak_fancy_output ())
            g_print (_("Masked patterns:\n"));

          for (i = 0; i < patterns->len; i++)
            {
              const char *old = g_ptr_array_index (patterns, i);
              g_print ("  %s\n", old);
            }
        }
    }
  else
    {
      for (i = 1; i < argc; i++)
        {
          const char *pattern = argv[i];

          if (opt_remove)
            {
              if (!flatpak_dir_config_remove_pattern (dir, "masked", pattern, error))
                return FALSE;
            }
          else if (!flatpak_dir_config_append_pattern (dir, "masked", pattern,
                                                       FALSE, /* match apps or runtimes */
                                                       NULL, error))
            return FALSE;
        }
    }

  return TRUE;
}

gboolean
flatpak_complete_mask (FlatpakCompletion *completion)
{
  g_autoptr(GOptionContext) context = NULL;
  g_autoptr(GPtrArray) dirs = NULL;

  context = g_option_context_new ("");
  if (!flatpak_option_context_parse (context, options, &completion->argc, &completion->argv,
                                     FLATPAK_BUILTIN_FLAG_ONE_DIR | FLATPAK_BUILTIN_FLAG_OPTIONAL_REPO,
                                     &dirs, NULL, NULL))
    return FALSE;

  switch (completion->argc)
    {
    case 0:
    case 1: /* PATTERN */
      flatpak_complete_options (completion, global_entries);
      flatpak_complete_options (completion, options);
      flatpak_complete_options (completion, user_entries);
      break;
    }

  return TRUE;
}

===== ./app/flatpak-builtins-utils.c =====
/* vi:set et sw=2 sts=2 cin cino=t0,f0,(0,{s,>2s,n-s,^-s,e-s:
 * Copyright © 2014 Red Hat, Inc
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Alexander Larsson <alexl@redhat.com>
 */

#include "config.h"

#include <glib/gi18n.h>
#include <glib/gprintf.h>

#include <gio/gunixinputstream.h>
#include "flatpak-chain-input-stream-private.h"

#include "flatpak-ref.h"
#include "flatpak-builtins-utils.h"
#include "flatpak-tty-utils-private.h"
#include "flatpak-utils-private.h"
#include "flatpak-run-private.h"


void
remote_dir_pair_free (RemoteDirPair *pair)
{
  g_free (pair->remote_name);
  g_object_unref (pair->dir);
  g_free (pair);
}

RemoteDirPair *
remote_dir_pair_new (const char *remote_name, FlatpakDir *dir)
{
  RemoteDirPair *pair = g_new (RemoteDirPair, 1);

  pair->remote_name = g_strdup (remote_name);
  pair->dir = g_object_ref (dir);
  return pair;
}

RefDirPair *
ref_dir_pair_new (FlatpakDecomposed *ref, FlatpakDir *dir)
{
  RefDirPair *pair = g_new (RefDirPair, 1);

  pair->ref = flatpak_decomposed_ref (ref);
  pair->dir = g_object_ref (dir);
  return pair;
}

void
ref_dir_pair_free (RefDirPair *pair)
{
  flatpak_decomposed_unref (pair->ref);
  g_object_unref (pair->dir);
  g_free (pair);
}


gboolean
looks_like_branch (const char *branch)
{
  const char *dot;

  /* In particular, / is not a valid branch char, so
     this lets us distinguish full or partial refs as
     non-branches. */
  if (!flatpak_is_valid_branch (branch, -1, NULL))
    return FALSE;

  /* Dots are allowed in branches, but not really used much, while
     app ids require at least two, so that's a good check to
     distinguish the two */
  dot = strchr (branch, '.');
  if (dot != NULL)
    {
      if (strchr (dot + 1, '.') != NULL)
        return FALSE;
    }

  return TRUE;
}

FlatpakDir *
flatpak_find_installed_pref (const char *pref, FlatpakKinds kinds, const char *default_arch, const char *default_branch,
                             gboolean search_all, gboolean search_user, gboolean search_system, char **search_installations,
                             FlatpakDecomposed **out_ref, GCancellable *cancellable, GError **error)
{
  g_autofree char *id = NULL;
  g_autofree char *arch = NULL;
  g_autofree char *branch = NULL;
  g_autoptr(GError) lookup_error = NULL;
  g_autoptr(FlatpakDecomposed) ref = NULL;
  g_autoptr(FlatpakDir) dir = NULL;
  g_autoptr(GPtrArray) system_dirs = NULL;

  if (!flatpak_split_partial_ref_arg (pref, kinds, default_arch, default_branch,
                                      &kinds, &id, &arch, &branch, error))
    return NULL;

  if (search_user || search_all)
    {
      g_autoptr(FlatpakDir) user_dir = flatpak_dir_get_user ();

      ref = flatpak_dir_find_installed_ref (user_dir,
                                            id, branch, arch,
                                            kinds,
                                            &lookup_error);
      if (ref)
        dir = g_steal_pointer (&user_dir);

      if (g_error_matches (lookup_error, G_IO_ERROR, G_IO_ERROR_FAILED))
        {
          g_propagate_error (error, g_steal_pointer (&lookup_error));
          return NULL;
        }
    }

  if (ref == NULL && search_all)
    {
      int i;

      system_dirs = flatpak_dir_get_system_list (cancellable, error);
      if (system_dirs == NULL)
        return FALSE;

      for (i = 0; i < system_dirs->len; i++)
        {
          FlatpakDir *system_dir = g_ptr_array_index (system_dirs, i);

          g_clear_error (&lookup_error);

          ref = flatpak_dir_find_installed_ref (system_dir,
                                                id, branch, arch,
                                                kinds,
                                                &lookup_error);
          if (ref)
            {
              dir = g_object_ref (system_dir);
              break;
            }

          if (g_error_matches (lookup_error, G_IO_ERROR, G_IO_ERROR_FAILED))
            {
              g_propagate_error (error, g_steal_pointer (&lookup_error));
              return NULL;
            }
        }
    }
  else
    {
      if (ref == NULL && search_installations != NULL)
        {
          int i = 0;

          for (i = 0; search_installations[i] != NULL; i++)
            {
              g_autoptr(FlatpakDir) installation_dir = NULL;

              installation_dir = flatpak_dir_get_system_by_id (search_installations[i], cancellable, error);
              if (installation_dir == NULL)
                return FALSE;

              if (installation_dir)
                {
                  g_clear_error (&lookup_error);

                  ref = flatpak_dir_find_installed_ref (installation_dir,
                                                        id, branch, arch,
                                                        kinds,
                                                        &lookup_error);
                  if (ref)
                    {
                      dir = g_steal_pointer (&installation_dir);
                      break;
                    }

                  if (g_error_matches (lookup_error, G_IO_ERROR, G_IO_ERROR_FAILED))
                    {
                      g_propagate_error (error, g_steal_pointer (&lookup_error));
                      return NULL;
                    }
                }
            }
        }

      if (ref == NULL && search_system)
        {
          g_autoptr(FlatpakDir) system_dir = flatpak_dir_get_system_default ();

          g_clear_error (&lookup_error);

          ref = flatpak_dir_find_installed_ref (system_dir,
                                                id, branch, arch,
                                                kinds,
                                                &lookup_error);

          if (ref)
            dir = g_steal_pointer (&system_dir);
        }
    }

  if (ref == NULL)
    {
      g_propagate_error (error, g_steal_pointer (&lookup_error));
      return NULL;
    }

  *out_ref = g_steal_pointer (&ref);
  return g_steal_pointer (&dir);
}


static gboolean
open_source_stream (char         **gpg_import,
                    GInputStream **out_source_stream,
                    GCancellable  *cancellable,
                    GError       **error)
{
  g_autoptr(GInputStream) source_stream = NULL;
  guint n_keyrings = 0;
  g_autoptr(GPtrArray) streams = NULL;

  if (gpg_import != NULL)
    n_keyrings = g_strv_length (gpg_import);

  guint ii;

  streams = g_ptr_array_new_with_free_func (g_object_unref);

  for (ii = 0; ii < n_keyrings; ii++)
    {
      GInputStream *input_stream = NULL;

      if (strcmp (gpg_import[ii], "-") == 0)
        {
          input_stream = g_unix_input_stream_new (STDIN_FILENO, FALSE);
        }
      else
        {
          g_autoptr(GFile) file = g_file_new_for_commandline_arg (gpg_import[ii]);
          input_stream = G_INPUT_STREAM (g_file_read (file, cancellable, error));

          if (input_stream == NULL)
            {
              g_prefix_error (error, "The file %s specified for --gpg-import was not found: ", gpg_import[ii]);
              return FALSE;
            }
        }

      /* Takes ownership. */
      g_ptr_array_add (streams, input_stream);
    }

  /* Chain together all the --keyring options as one long stream. */
  source_stream = (GInputStream *) flatpak_chain_input_stream_new (streams);

  *out_source_stream = g_steal_pointer (&source_stream);

  return TRUE;
}

GBytes *
flatpak_load_gpg_keys (char        **gpg_import,
                       GCancellable *cancellable,
                       GError      **error)
{
  g_autoptr(GInputStream) input_stream = NULL;
  g_autoptr(GOutputStream) output_stream = NULL;
  gssize n_bytes_written;

  if (!open_source_stream (gpg_import, &input_stream, cancellable, error))
    return NULL;

  output_stream = g_memory_output_stream_new_resizable ();

  n_bytes_written = g_output_stream_splice (output_stream, input_stream,
                                            G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE |
                                            G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET,
                                            NULL, error);
  if (n_bytes_written < 0)
    return NULL;

  return g_memory_output_stream_steal_as_bytes (G_MEMORY_OUTPUT_STREAM (output_stream));
}

gboolean
flatpak_resolve_duplicate_remotes (GPtrArray    *dirs,
                                   const char   *remote_name,
                                   gboolean      opt_noninteractive,
                                   FlatpakDir  **out_dir,
                                   GCancellable *cancellable,
                                   GError      **error)
{
  g_autoptr(GPtrArray) dirs_with_remote = NULL;
  int chosen = 0;
  int i;

  dirs_with_remote = g_ptr_array_new ();
  for (i = 0; i < dirs->len; i++)
    {
      FlatpakDir *dir = g_ptr_array_index (dirs, i);
      g_auto(GStrv) remotes = NULL;
      int j = 0;

      remotes = flatpak_dir_list_remotes (dir, cancellable, error);
      if (remotes == NULL)
        return FALSE;

      for (j = 0; remotes[j] != NULL; j++)
        {
          const char *this_remote = remotes[j];

          if (g_strcmp0 (remote_name, this_remote) == 0)
            g_ptr_array_add (dirs_with_remote, dir);
        }
    }

  if (dirs_with_remote->len == 1)
    chosen = 1;
  else if (dirs_with_remote->len > 1)
    {
      if (opt_noninteractive)
        return flatpak_fail (error, _("Remote ‘%s’ found in multiple installations, unable to proceed in non-interactive mode"), remote_name);

      g_auto(GStrv) names = g_new0 (char *, dirs_with_remote->len + 1);
      for (i = 0; i < dirs_with_remote->len; i++)
        {
          FlatpakDir *dir = g_ptr_array_index (dirs_with_remote, i);
          names[i] = flatpak_dir_get_name (dir);
        }
      flatpak_format_choices ((const char **) names,
                              _("Remote ‘%s’ found in multiple installations:"), remote_name);
      chosen = flatpak_number_prompt (TRUE, 0, dirs_with_remote->len, _("Which do you want to use (0 to abort)?"));
      if (chosen == 0)
        return flatpak_fail (error, _("No remote chosen to resolve ‘%s’ which exists in multiple installations"), remote_name);
    }

  if (out_dir)
    {
      if (dirs_with_remote->len == 0)
        {
          if (dirs->len > 1 || dirs->len == 0)
            return flatpak_fail_error (error, FLATPAK_ERROR_REMOTE_NOT_FOUND,
                                       _("Remote \"%s\" not found\nHint: Use flatpak remote-add to add a remote"),
                                       remote_name);
          else
            {
              FlatpakDir *dir = g_ptr_array_index (dirs, 0);
              return flatpak_fail_error (error, FLATPAK_ERROR_REMOTE_NOT_FOUND,
                                         _("Remote \"%s\" not found in the %s installation"),
                                         remote_name, flatpak_dir_get_name_cached (dir));
            }
        }
      else
        *out_dir = g_object_ref (g_ptr_array_index (dirs_with_remote, chosen - 1));
    }

  return TRUE;
}

static char **
decomposed_refs_to_strv (GPtrArray *decomposed)
{
  GPtrArray *res = g_ptr_array_new ();
  for (int i = 0; i < decomposed->len; i++)
    {
      FlatpakDecomposed *ref = g_ptr_array_index (decomposed, i);
      g_ptr_array_add (res, flatpak_decomposed_dup_ref (ref));
    }
  g_ptr_array_add (res, NULL);

  return (char **) g_ptr_array_free (res, FALSE);
}

gboolean
flatpak_resolve_matching_refs (const char *remote_name,
                               FlatpakDir *dir,
                               gboolean    assume_yes,
                               GPtrArray  *refs,
                               const char *opt_search_ref,
                               gboolean    opt_noninteractive,
                               char      **out_ref,
                               GError    **error)
{
  guint chosen = 0;

  g_assert (refs->len > 0);

  if (opt_noninteractive && refs->len > 1)
    return flatpak_fail (error, _("Multiple refs match ‘%s’, unable to proceed in non-interactive mode"), opt_search_ref);

  /* When there's only one match, we only choose it without user interaction if
   * either the --assume-yes option was used or it's an exact match
   */
  if (refs->len == 1)
    {
      if (assume_yes)
        chosen = 1;
      else
        {
          FlatpakDecomposed *ref = g_ptr_array_index (refs, 0);
          g_autofree char *id = flatpak_decomposed_dup_id (ref);

          if (opt_search_ref != NULL && strcmp (id, opt_search_ref) == 0)
            chosen = 1;
        }
    }

  if (chosen == 0)
    {
      const char *dir_name = flatpak_dir_get_name_cached (dir);
      if (refs->len == 1)
        {
          FlatpakDecomposed *ref = g_ptr_array_index (refs, 0);
          if (flatpak_yes_no_prompt (TRUE, /* default to yes on Enter */
                                     _("Found ref ‘%s’ in remote ‘%s’ (%s).\nUse this ref?"),
                                     flatpak_decomposed_get_ref (ref), remote_name, dir_name))
            chosen = 1;
          else
            return flatpak_fail (error, _("No ref chosen to resolve matches for ‘%s’"), opt_search_ref);
        }
      else
        {
          g_auto(GStrv) refs_str = decomposed_refs_to_strv (refs);
          flatpak_format_choices ((const char **) refs_str,
                                  _("Similar refs found for ‘%s’ in remote ‘%s’ (%s):"),
                                  opt_search_ref, remote_name, dir_name);
          chosen = flatpak_number_prompt (TRUE, 0, refs->len, _("Which do you want to use (0 to abort)?"));
          if (chosen == 0)
            return flatpak_fail (error, _("No ref chosen to resolve matches for ‘%s’"), opt_search_ref);
        }
    }

  if (out_ref)
    {
      FlatpakDecomposed *ref = g_ptr_array_index (refs, chosen - 1);
      *out_ref = flatpak_decomposed_dup_ref (ref);
    }

  return TRUE;
}

/**
 * flatpak_resolve_matching_installed_refs:
 * @assume_yes: If set and @ref_dir_pairs contains only one match it will be
 *  chosen without user interaction even if it's not an exact match
 * @only_one: If set, only allow the user to choose one option (e.g. not a
 *  range or all of the above)
 * @ref_dir_pairs: (element-type #RefDirPair): the ref-dir pairs to choose from
 * @out_pairs: (element-type #RefDirPair): an array to which the user's choices
 *  will be added
 *
 * Prompts the user to choose between @ref_dir_pairs and add the chosen ones to @out_pairs.
 *
 * Returns: %TRUE if a choice was made, either by the user or automatically,
 *   and %FALSE otherwise with @error set
 */
gboolean
flatpak_resolve_matching_installed_refs (gboolean    assume_yes,
                                         gboolean    only_one,
                                         GPtrArray  *ref_dir_pairs,
                                         const char *opt_search_ref,
                                         gboolean    opt_noninteractive,
                                         GPtrArray  *out_pairs,
                                         GError    **error)
{
  guint chosen = 0;
  g_autofree int *choices = NULL;
  guint i, k;

  g_assert (ref_dir_pairs->len > 0);

  if (opt_noninteractive && ref_dir_pairs->len > 1)
    return flatpak_fail (error, _("Multiple installed refs match ‘%s’, unable to proceed in non-interactive mode"), opt_search_ref);

  /* When there's only one match, we only choose it without user interaction if
   * either the --assume-yes option was used or it's an exact match
   */
  if (ref_dir_pairs->len == 1)
    {
      if (assume_yes)
        chosen = 1;
      else
        {
          RefDirPair *pair = g_ptr_array_index (ref_dir_pairs, 0);
          g_autofree char *id = flatpak_decomposed_dup_id (pair->ref);
          if (opt_search_ref != NULL && strcmp (id, opt_search_ref) == 0)
            chosen = 1;
        }
    }

  if (chosen != 0)
    {
      g_ptr_array_add (out_pairs, g_ptr_array_index (ref_dir_pairs, chosen - 1));
      return TRUE;
    }
  else
    {
      if (ref_dir_pairs->len == 1)
        {
          RefDirPair *pair = g_ptr_array_index (ref_dir_pairs, 0);
          const char *dir_name = flatpak_dir_get_name_cached (pair->dir);
          if (flatpak_yes_no_prompt (TRUE, /* default to yes on Enter */
                                     _("Found installed ref ‘%s’ (%s). Is this correct?"),
                                     flatpak_decomposed_get_ref (pair->ref), dir_name))
            chosen = 1;
          else
            return flatpak_fail (error, _("No ref chosen to resolve matches for ‘%s’"), opt_search_ref);
        }
      else
        {
          int len = ref_dir_pairs->len + (only_one ? 0 : 1);
          g_auto(GStrv) names = g_new0 (char *, len + 1);
          for (i = 0; i < ref_dir_pairs->len; i++)
            {
              RefDirPair *pair = g_ptr_array_index (ref_dir_pairs, i);
              names[i] = g_strdup_printf ("%s (%s)", flatpak_decomposed_get_ref (pair->ref), flatpak_dir_get_name_cached (pair->dir));
            }
          if (!only_one)
            names[i] = g_strdup_printf (_("All of the above"));
          flatpak_format_choices ((const char **) names, _("Similar installed refs found for ‘%s’:"), opt_search_ref);

          if (only_one)
            chosen = flatpak_number_prompt (TRUE, 0, len, _("Which do you want to use (0 to abort)?"));
          else
            choices = flatpak_numbers_prompt (TRUE, 0, len, _("Which do you want to use (0 to abort)?"));

          if ((only_one && chosen == 0) || (!only_one && choices[0] == 0))
            return flatpak_fail (error, _("No ref chosen to resolve matches for ‘%s’"), opt_search_ref);
        }
    }

  if (choices)
    {
      for (i = 0; choices[i] != 0; i++)
        {
          chosen = choices[i];
          if (chosen == ref_dir_pairs->len + 1)
            {
              for (k = 0; k < ref_dir_pairs->len; k++)
                g_ptr_array_add (out_pairs, g_ptr_array_index (ref_dir_pairs, k));
            }
          else
            g_ptr_array_add (out_pairs, g_ptr_array_index (ref_dir_pairs, chosen - 1));
        }
    }
  else
    g_ptr_array_add (out_pairs, g_ptr_array_index (ref_dir_pairs, chosen - 1));

  return TRUE;
}

gboolean
flatpak_resolve_matching_remotes (GPtrArray      *remote_dir_pairs,
                                  const char     *opt_search_ref,
                                  gboolean        opt_noninteractive,
                                  RemoteDirPair **out_pair,
                                  GError        **error)
{
  guint chosen = 0; /* 1 indexed */

  g_assert (remote_dir_pairs->len > 0);

  if (opt_noninteractive && remote_dir_pairs->len > 1)
    return flatpak_fail (error, _("Multiple remotes have refs matching ‘%s’, unable to proceed in non-interactive mode"), opt_search_ref);

  /* Here we use the only matching remote even if --assumeyes wasn't specified
   * because the user will still be asked to confirm the operation in the next
   * step after the dependencies are resolved.
   */
  if (remote_dir_pairs->len == 1)
    {
      chosen = 1;
    }
  else
    {
      g_auto(GStrv) names = g_new0 (char *, remote_dir_pairs->len + 1);
      for (guint i = 0; i < remote_dir_pairs->len; i++)
        {
          RemoteDirPair *pair = g_ptr_array_index (remote_dir_pairs, i);
          names[i] = g_strdup_printf ("‘%s’ (%s)", pair->remote_name, flatpak_dir_get_name_cached (pair->dir));
        }
      flatpak_format_choices ((const char **) names, _("Remotes found with refs similar to ‘%s’:"), opt_search_ref);
      chosen = flatpak_number_prompt (TRUE, 0, remote_dir_pairs->len, _("Which do you want to use (0 to abort)?"));
      if (chosen == 0)
        return flatpak_fail (error, _("No remote chosen to resolve matches for ‘%s’"), opt_search_ref);
    }

  if (out_pair)
    *out_pair = g_ptr_array_index (remote_dir_pairs, chosen - 1);

  return TRUE;
}

/* Returns: the time in seconds since the file was modified, or %G_MAXUINT64 on error */
static guint64
get_file_age (GFile *file)
{
  guint64 now;
  guint64 mtime;
  g_autoptr(GFileInfo) info = NULL;

  info = g_file_query_info (file,
                            G_FILE_ATTRIBUTE_TIME_MODIFIED,
                            G_FILE_QUERY_INFO_NONE,
                            NULL,
                            NULL);
  if (info == NULL)
    return G_MAXUINT64;

  mtime = g_file_info_get_attribute_uint64 (info, G_FILE_ATTRIBUTE_TIME_MODIFIED);
  now = (guint64) g_get_real_time () / G_USEC_PER_SEC;
  if (mtime > now)
    return G_MAXUINT64;

  return (guint64) (now - mtime);
}

static guint64
get_appstream_timestamp (FlatpakDir *dir,
                         const char *remote,
                         const char *arch)
{
  g_autoptr(GFile) ts_file = NULL;
  g_autofree char *subdir = NULL;

  subdir = g_strdup_printf ("appstream/%s/%s/.timestamp", remote, arch);
  ts_file = g_file_resolve_relative_path (flatpak_dir_get_path (dir), subdir);
  return get_file_age (ts_file);
}


gboolean
update_appstream (GPtrArray    *dirs,
                  const char   *remote,
                  const char   *arch,
                  guint64       ttl,
                  gboolean      quiet,
                  GCancellable *cancellable,
                  GError      **error)
{
  gboolean changed;
  int i, j;

  g_return_val_if_fail (dirs != NULL, FALSE);

  if (arch == NULL)
    arch = flatpak_get_arch ();

  if (remote == NULL)
    {
      for (j = 0; j < dirs->len; j++)
        {
          FlatpakDir *dir = g_ptr_array_index (dirs, j);
          g_auto(GStrv) remotes = NULL;

          remotes = flatpak_dir_list_remotes (dir, cancellable, error);
          if (remotes == NULL)
            return FALSE;

          for (i = 0; remotes[i] != NULL; i++)
            {
              g_autoptr(GError) local_error = NULL;
              guint64 ts_file_age;

              ts_file_age = get_appstream_timestamp (dir, remotes[i], arch);
              if (ts_file_age < ttl)
                {
                  g_info ("%s:%s appstream age %" G_GUINT64_FORMAT " is less than ttl %" G_GUINT64_FORMAT, remotes[i], arch, ts_file_age, ttl);
                  continue;
                }
              else
                g_info ("%s:%s appstream age %" G_GUINT64_FORMAT " is greater than ttl %" G_GUINT64_FORMAT, remotes[i], arch, ts_file_age, ttl);

              if (flatpak_dir_get_remote_disabled (dir, remotes[i]) ||
                  flatpak_dir_get_remote_noenumerate (dir, remotes[i]))
                continue;

              if (flatpak_dir_is_user (dir))
                {
                  if (quiet)
                    g_info (_("Updating appstream data for user remote %s"), remotes[i]);
                  else
                    {
                      g_print (_("Updating appstream data for user remote %s"), remotes[i]);
                      g_print ("\n");
                    }
                }
              else
                {
                  if (quiet)
                    g_info (_("Updating appstream data for remote %s"), remotes[i]);
                  else
                    {
                      g_print (_("Updating appstream data for remote %s"), remotes[i]);
                      g_print ("\n");
                    }
                }
              if (!flatpak_dir_update_appstream (dir, remotes[i], arch, &changed,
                                                 NULL, cancellable, &local_error))
                {
                  if (quiet)
                    g_info ("%s: %s", _("Error updating"), local_error->message);
                  else
                    g_printerr ("%s: %s\n", _("Error updating"), local_error->message);
                }
            }
        }
    }
  else
    {
      gboolean found = FALSE;

      for (j = 0; j < dirs->len; j++)
        {
          FlatpakDir *dir = g_ptr_array_index (dirs, j);

          if (flatpak_dir_has_remote (dir, remote, NULL))
            {
              guint64 ts_file_age;

              found = TRUE;

              ts_file_age = get_appstream_timestamp (dir, remote, arch);
              if (ts_file_age < ttl)
                {
                  g_info ("%s:%s appstream age %" G_GUINT64_FORMAT " is less than ttl %" G_GUINT64_FORMAT, remote, arch, ts_file_age, ttl);
                  continue;
                }
              else
                g_info ("%s:%s appstream age %" G_GUINT64_FORMAT " is greater than ttl %" G_GUINT64_FORMAT, remote, arch, ts_file_age, ttl);

              if (!flatpak_dir_update_appstream (dir, remote, arch, &changed,
                                                 NULL, cancellable, error))
                return FALSE;
            }
        }

      if (!found)
        return flatpak_fail_error (error, FLATPAK_ERROR_REMOTE_NOT_FOUND,
                                   _("Remote \"%s\" not found"), remote);
    }

  return TRUE;
}

char **
get_permission_tables (XdpDbusPermissionStore *store)
{
  g_autofree char *path = NULL;
  GDir *dir;
  const char *name;
  GPtrArray *tables = NULL;

  tables = g_ptr_array_new ();

  path = g_build_filename (g_get_user_data_dir (), "flatpak/db", NULL);
  dir = g_dir_open (path, 0, NULL);
  if (dir != NULL)
    {
      while ((name = g_dir_read_name (dir)) != NULL)
        {
          g_ptr_array_add (tables, g_strdup (name));
        }
      g_dir_close (dir);
    }

  g_ptr_array_add (tables, NULL);

  return (char **) g_ptr_array_free (tables, FALSE);
}

/*** column handling ***/

static gboolean
parse_ellipsize_suffix (const char           *p,
                        FlatpakEllipsizeMode *mode,
                        GError              **error)
{
  if (g_str_equal (":", p))
    {
      g_autofree char *msg1 = g_strdup_printf (_("Ambiguous suffix: '%s'."), p);
      /* Translators: don't translate the values */
      const char *msg2 = _("Possible values are :s[tart], :m[iddle], :e[nd] or :f[ull]");
      return flatpak_fail (error, "%s %s", msg1, msg2);
    }
  else if (g_str_has_prefix (":full", p))
    *mode = FLATPAK_ELLIPSIZE_MODE_NONE;
  else if (g_str_has_prefix (":start", p))
    *mode = FLATPAK_ELLIPSIZE_MODE_START;
  else if (g_str_has_prefix (":middle", p))
    *mode = FLATPAK_ELLIPSIZE_MODE_MIDDLE;
  else if (g_str_has_prefix (":end", p))
    *mode = FLATPAK_ELLIPSIZE_MODE_END;
  else
    {
      g_autofree char *msg1 = g_strdup_printf (_("Invalid suffix: '%s'."), p);
      /* Translators: don't translate the values */
      const char *msg2 = _("Possible values are :s[tart], :m[iddle], :e[nd] or :f[ull]");
      return flatpak_fail (error, "%s %s", msg1, msg2);
    }

  return TRUE;
}

int
find_column (Column     *columns,
             const char *name,
             GError    **error)
{
  int i;
  int candidate;
  const char *p = strchr (name, ':');

  candidate = -1;
  for (i = 0; columns[i].name; i++)
    {
      if (g_str_equal (columns[i].name, name) ||
          (p != 0 && strncmp (columns[i].name, name, p - name) == 0))
        {
          candidate = i;
          break;
        }
      else if (g_str_has_prefix (columns[i].name, name))
        {
          if (candidate == -1)
            {
              candidate = i;
            }
          else
            {
              flatpak_fail (error, _("Ambiguous column: %s"), name);
              return -1;
            }
        }
    }

  if (candidate >= 0)
    {
      if (p && !parse_ellipsize_suffix (p, &columns[candidate].ellipsize, error))
        return -1;
      return candidate;
    }

  flatpak_fail (error, _("Unknown column: %s"), name);
  return -1;
}

static Column *
column_filter (Column     *columns,
               const char *col_arg,
               GError    **error)
{
  g_auto(GStrv) cols = g_strsplit (col_arg, ",", 0);
  int n_cols = g_strv_length (cols);
  g_autofree Column *result = g_new0 (Column, n_cols + 1);
  int i;

  for (i = 0; i < n_cols; i++)
    {
      int idx = find_column (columns, cols[i], error);
      if (idx < 0)
        return NULL;
      result[i] = columns[idx];
    }

  return g_steal_pointer (&result);
}

static gboolean
list_has (const char *list,
          const char *term)
{
  const char *p;
  int len;

  p = list;
  while (p)
    {
      p = strstr (p, term);
      len = strlen (term);
      if (!p)
        break;
      if ((p == list || p[-1] == ',') &&
          (p[len] == '\0' || p[len] == ','))
        return TRUE;
      p++;
    }

  return FALSE;
}

/* Returns column help suitable for passing to
 * g_option_context_set_description()
 */
char *
column_help (Column *columns)
{
  GString *s = g_string_new ("");
  int len;
  int i;

  g_string_append (s, _("Available columns:\n"));

  len = 0;
  for (i = 0; columns[i].name; i++)
    len = MAX (len, strlen (columns[i].name));

  len += 4;
  for (i = 0; columns[i].name; i++)
    g_string_append_printf (s, "  %-*s %s\n", len, columns[i].name, _(columns[i].desc));

  g_string_append_printf (s, "  %-*s %s\n", len, "all", _("Show all columns"));
  g_string_append_printf (s, "  %-*s %s\n", len, "help", _("Show available columns"));

  g_string_append_printf (s, "\n%s\n",
                          _("Append :s[tart], :m[iddle], :e[nd] or :f[ull] to change ellipsization"));
  return g_string_free (s, FALSE);
}

/* Returns a filtered list of columns, free with g_free.
 * opt_show_all should correspond to --show-details or be FALSE
 * opt_cols should correspond to --columns
 */
Column *
handle_column_args (Column      *all_columns,
                    gboolean     opt_show_all,
                    const char **opt_cols,
                    GError     **error)
{
  g_autofree char *cols = NULL;
  gboolean show_help = FALSE;
  gboolean show_all = opt_show_all;

  if (opt_cols)
    {
      int i;

      for (i = 0; opt_cols[i]; i++)
        {
          if (list_has (opt_cols[i], "help"))
            show_help = TRUE;
          else if (list_has (opt_cols[i], "all"))
            show_all = TRUE;
        }
    }

  if (show_help)
    {
      g_autofree char *col_help = column_help (all_columns);
      g_print ("%s", col_help);
      return g_new0 (Column, 1);
    }

  if (opt_cols && !show_all)
    cols = g_strjoinv (",", (char **) opt_cols);
  else
    {
      GString *s;
      int i;

      s = g_string_new ("");
      for (i = 0; all_columns[i].name; i++)
        {
          if ((show_all && all_columns[i].all) || all_columns[i].def)
            g_string_append_printf (s, "%s%s", s->len > 0 ? "," : "", all_columns[i].name);
        }
      cols = g_string_free (s, FALSE);
    }

  return column_filter (all_columns, cols, error);
}

char *
format_timestamp (guint64 timestamp)
{
  GDateTime *dt;
  char *str;

  dt = g_date_time_new_from_unix_utc (timestamp);
  if (dt == NULL)
    return g_strdup ("?");

  str = g_date_time_format (dt, "%Y-%m-%d %H:%M:%S +0000");
  g_date_time_unref (dt);

  return str;
}

char *
ellipsize_string (const char *text, int len)
{
  return ellipsize_string_full (text, len, FLATPAK_ELLIPSIZE_MODE_END);
}

char *
ellipsize_string_full (const char *text, int len, FlatpakEllipsizeMode mode)
{
  g_autofree char *ret = g_strdup (text);

  if (mode != FLATPAK_ELLIPSIZE_MODE_NONE && g_utf8_strlen (ret, -1) > len)
    {
      char *p;
      char *q;
      int i;
      int l1, l2;

      if (mode == FLATPAK_ELLIPSIZE_MODE_START)
        l1 = 0;
      else if (mode == FLATPAK_ELLIPSIZE_MODE_MIDDLE)
        l1 = len / 2;
      else
        l1 = len - 1;

      l2 = len - 1 - l1;

      p = ret;
      q = ret + strlen (ret);

      for (i = 0; i < l1; i++)
        p = g_utf8_next_char (p);
      p[0] = '\0';

      for (i = 0; i < l2; i++)
        q = g_utf8_prev_char (q);

      return g_strconcat (ret, "…", q, NULL);
    }

  return g_steal_pointer (&ret);
}

const char *
component_get_version_latest (AsComponent *component)
{
#if AS_CHECK_VERSION(1, 0, 0)
  AsReleaseList *releases = NULL;

  /* load releases without network access, ignoring any errors */
  as_component_load_releases (component, FALSE, NULL);

  /* fetch default releases even if previous loading has failed */
  releases = as_component_get_releases_plain (component);
  if (releases != NULL && as_release_list_len (releases) > 0)
    return as_release_get_version (as_release_list_index (releases, 0));
#else
  GPtrArray *releases = as_component_get_releases (component);

  if (releases != NULL && releases->len > 0)
    return as_release_get_version (AS_RELEASE (g_ptr_array_index (releases, 0)));
#endif

  return NULL;
}

AsComponent *
metadata_find_component (AsMetadata *mdata,
                         const char *ref)
{
  g_autoptr(FlatpakRef) rref = flatpak_ref_parse (ref, NULL);
  const char *cid = flatpak_ref_get_name (rref);
  g_autofree char *desktopid = g_strconcat (cid, ".desktop", NULL);

  for (int j = 0; j < 2; j++)
    {
      const char *id = j == 0 ? cid : desktopid;
#if AS_CHECK_VERSION(1, 0, 0)
      AsComponentBox *cbox = as_metadata_get_components (mdata);

      for (gsize i = 0; i < as_component_box_len (cbox); i++)
        {
          AsComponent *component = as_component_box_index (cbox, i);
          AsBundle *bundle;

          if (g_strcmp0 (as_component_get_id (component), id) != 0)
            continue;

          bundle = as_component_get_bundle (component, AS_BUNDLE_KIND_FLATPAK);
          if (bundle &&
              g_str_equal (as_bundle_get_id (bundle), ref))
            return component;
        }
#else
      GPtrArray *components = as_metadata_get_components (mdata);

      for (gsize i = 0; i < components->len; i++)
        {
          AsComponent *component = g_ptr_array_index (components, i);
          AsBundle *bundle;

          if (g_strcmp0 (as_component_get_id (component), id) != 0)
            continue;

          bundle = as_component_get_bundle (component, AS_BUNDLE_KIND_FLATPAK);
          if (bundle &&
              g_str_equal (as_bundle_get_id (bundle), ref))
            return component;
        }
#endif
    }

  return NULL;
}

/**
 * flatpak_dir_load_appstream_data:
 * @self: a #FlatpakDir
 * @remote_name: name of the remote to load the AppStream data for
 * @arch: (nullable): name of the architecture to load the AppStream data for,
 *    or %NULL to use the default
 * @store: the store to load into
 * @cancellable: (nullable): a #GCancellable, or %NULL
 * @error: return location for a #GError
 *
 * Load the cached AppStream data for the given @remote_name into @store, which
 * must have already been constructed using as_metadata_new(). If no cache
 * exists, %FALSE is returned with no error set. If there is an error loading or
 * parsing the cache, an error is returned.
 *
 * Returns: %TRUE if the cache exists and was loaded into @store; %FALSE
 *    otherwise
 */
gboolean
flatpak_dir_load_appstream_data (FlatpakDir   *self,
                                 const gchar  *remote_name,
                                 const gchar  *arch,
                                 AsMetadata   *mdata,
                                 GCancellable *cancellable,
                                 GError      **error)
{
  const char *install_path = flatpak_file_get_path_cached (flatpak_dir_get_path (self));
  g_autoptr(GFile) appstream_file = NULL;
  g_autofree char *appstream_path = NULL;
  g_autoptr(GError) local_error = NULL;
  gboolean success;

  if (arch == NULL)
    arch = flatpak_get_arch ();

  if (flatpak_dir_get_remote_oci (self, remote_name))
    appstream_path = g_build_filename (install_path, "appstream", remote_name,
                                       arch, "appstream.xml.gz",
                                       NULL);
  else
    appstream_path = g_build_filename (install_path, "appstream", remote_name,
                                       arch, "active", "appstream.xml.gz",
                                       NULL);

  appstream_file = g_file_new_for_path (appstream_path);
#if AS_CHECK_VERSION(0, 16, 0)
  as_metadata_set_format_style (mdata, AS_FORMAT_STYLE_CATALOG);
#else
  /* Deprecated name for the same thing */
  as_metadata_set_format_style (mdata, AS_FORMAT_STYLE_COLLECTION);
#endif
#if AS_CHECK_VERSION(0, 14, 0)
  success = as_metadata_parse_file (mdata, appstream_file, AS_FORMAT_KIND_XML, &local_error);
#else
  as_metadata_parse_file (mdata, appstream_file, AS_FORMAT_KIND_XML, &local_error);
  success = (local_error == NULL);
#endif

  /* We want to ignore ENOENT error as it is harmless and valid */
  if (local_error != NULL &&
      g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
    g_clear_error (&local_error);
  else if (local_error != NULL)
    g_propagate_error (error, g_steal_pointer (&local_error));

  return success;
}

void
print_aligned (int len, const char *title, const char *value)
{
  const char *on = "";
  const char *off = "";

  if (flatpak_fancy_output ())
    {
      on = FLATPAK_ANSI_BOLD_ON;
      off = FLATPAK_ANSI_BOLD_OFF;
    }

  g_print ("%s%*s%s%s %s\n", on, len - (int) cell_width (title), "", title, off, value);
}

void
print_aligned_take (int len, const char *title, char *value)
{
  print_aligned (len, title, value);
  g_free (value);
}

static const char *
skip_escape_sequence (const char *p)
{
  if (g_str_has_prefix (p, FLATPAK_ANSI_ALT_SCREEN_ON))
    p += strlen (FLATPAK_ANSI_ALT_SCREEN_ON);
  else if (g_str_has_prefix (p, FLATPAK_ANSI_ALT_SCREEN_OFF))
    p += strlen (FLATPAK_ANSI_ALT_SCREEN_OFF);
  else if (g_str_has_prefix (p, FLATPAK_ANSI_HIDE_CURSOR))
    p += strlen (FLATPAK_ANSI_HIDE_CURSOR);
  else if (g_str_has_prefix (p, FLATPAK_ANSI_SHOW_CURSOR))
    p += strlen (FLATPAK_ANSI_SHOW_CURSOR);
  else if (g_str_has_prefix (p, FLATPAK_ANSI_BOLD_ON))
    p += strlen (FLATPAK_ANSI_BOLD_ON);
  else if (g_str_has_prefix (p, FLATPAK_ANSI_BOLD_OFF))
    p += strlen (FLATPAK_ANSI_BOLD_OFF);
  else if (g_str_has_prefix (p, FLATPAK_ANSI_FAINT_ON))
    p += strlen (FLATPAK_ANSI_FAINT_ON);
  else if (g_str_has_prefix (p, FLATPAK_ANSI_FAINT_OFF))
    p += strlen (FLATPAK_ANSI_FAINT_OFF);
  else if (g_str_has_prefix (p, FLATPAK_ANSI_RED))
    p += strlen (FLATPAK_ANSI_RED);
  else if (g_str_has_prefix (p, FLATPAK_ANSI_GREEN))
    p += strlen (FLATPAK_ANSI_GREEN);
  else if (g_str_has_prefix (p, FLATPAK_ANSI_COLOR_RESET))
    p += strlen (FLATPAK_ANSI_COLOR_RESET);
  else if (g_str_has_prefix (p, FLATPAK_ANSI_ROW_N))
    p += strlen (FLATPAK_ANSI_ROW_N);
  else if (g_str_has_prefix (p, FLATPAK_ANSI_CLEAR))
    p += strlen (FLATPAK_ANSI_CLEAR);
  else if (g_str_has_prefix (p, "\x1b"))
    {
      g_warning ("Unknown Escape sequence");
      p++; /* avoid looping forever */
    }
  return p;
}

/* A variant of g_utf8_strlen that skips Escape sequences,
 * and takes character width into account
 */
int
cell_width (const char *text)
{
  const char *p = text;
  gunichar c;
  int width = 0;

  while (*p)
    {
      while (*p && *p == '\x1b')
        p = skip_escape_sequence (p);

      if (!*p)
        break;

      c = g_utf8_get_char (p);

      if (g_unichar_iswide (c))
        width += 2;
      else if (!g_unichar_iszerowidth (c))
        width += 1;

      p = g_utf8_next_char (p);
    }

  return width;
}

/* Advance text by num cells, skipping Escape sequences,
 * and taking character width into account
 */
const char *
cell_advance (const char *text,
              int         num)
{
  const char *p = text;
  gunichar c;
  int width = 0;

  while (width < num)
    {
      while (*p && *p == '\x1b')
        p = skip_escape_sequence (p);

      if (!*p)
        break;

      c = g_utf8_get_char (p);

      if (g_unichar_iswide (c))
        width += 2;
      else if (!g_unichar_iszerowidth (c))
        width += 1;

      p = g_utf8_next_char (p);
    }

  return p;
}

static void
print_line_wrapped (int cols, const char *line)
{
  g_auto(GStrv) words = g_strsplit (line, " ", 0);
  int i;
  int col = 0;

  for (i = 0; words[i]; i++)
    {
      int len = cell_width (words[i]);
      int space = col > 0;

      if (col + space + len >= cols)
        {
          g_print ("\n%s", words[i]);
          col = len;
        }
      else
        {
          g_print ("%*s%s", space, "", words[i]);
          col = col + space + len;
        }
    }
}

void
print_wrapped (int         cols,
               const char *text,
               ...)
{
  va_list args;
  g_autofree char *msg = NULL;
  g_auto(GStrv) lines = NULL;
  int i;

  va_start (args, text);
  g_vasprintf (&msg, text, args);
  va_end (args);

  lines = g_strsplit (msg, "\n", 0);
  for (i = 0; lines[i]; i++)
    {
      print_line_wrapped (cols, lines[i]);
      g_print ("\n");
    }
}

FlatpakRemoteState *
get_remote_state (FlatpakDir   *dir,
                  const char   *remote,
                  gboolean      cached,
                  gboolean      only_sideloaded,
                  const char   *opt_arch,
                  const char  **opt_sideload_repos,
                  GCancellable *cancellable,
                  GError      **error)
{
  g_autoptr(GError) local_error = NULL;
  FlatpakRemoteState *state = NULL;

  if (only_sideloaded)
    {
      state = flatpak_dir_get_remote_state_local_only (dir, remote, cancellable, error);
      if (state == NULL)
        return NULL;
    }
  else
    {
      state = flatpak_dir_get_remote_state_optional (dir, remote, cached, cancellable, &local_error);
      if (state == NULL && g_error_matches (local_error, FLATPAK_ERROR, FLATPAK_ERROR_NOT_CACHED))
        {
          g_clear_error (&local_error);
          state = flatpak_dir_get_remote_state_optional (dir, remote, FALSE, cancellable, &local_error);
        }

      if (state == NULL)
        {
          g_propagate_error (error, g_steal_pointer (&local_error));
          return NULL;
        }
    }

  if (opt_arch != NULL &&
      !ensure_remote_state_arch (dir, state, opt_arch, cached, only_sideloaded, cancellable, &local_error))
    return NULL;

  for (int i = 0; opt_sideload_repos != NULL && opt_sideload_repos[i] != NULL; i++)
     {
      g_autoptr(GFile) f = g_file_new_for_path (opt_sideload_repos[i]);
      flatpak_remote_state_add_sideload_dir (state, f);
     }

  return state;
}

/* Note: cached == TRUE here means prefer-cache, not only-cache */
gboolean
ensure_remote_state_arch (FlatpakDir         *dir,
                          FlatpakRemoteState *state,
                          const char         *arch,
                          gboolean            cached,
                          gboolean            only_sideloaded,
                          GCancellable       *cancellable,
                          GError            **error)
{
  g_autoptr(GError) local_error = NULL;

  g_return_val_if_fail (arch != NULL, FALSE);

  if (only_sideloaded)
    return TRUE;

  if (flatpak_remote_state_ensure_subsummary (state, dir, arch, cached, cancellable, &local_error))
    return TRUE;

  if (!g_error_matches (local_error, FLATPAK_ERROR, FLATPAK_ERROR_NOT_CACHED))
    {
      g_propagate_error (error, g_steal_pointer (&local_error));
      return FALSE;
    }

  return flatpak_remote_state_ensure_subsummary (state, dir, arch, FALSE, cancellable, error);
}

/* Note: cached == TRUE here means prefer-cache, not only-cache */
gboolean
ensure_remote_state_all_arches (FlatpakDir         *dir,
                                FlatpakRemoteState *state,
                                gboolean            cached,
                                gboolean            only_sideloaded,
                                GCancellable       *cancellable,
                                GError            **error)
{
  if (only_sideloaded)
    return TRUE;

  if (cached)
    {
      /* First try cached, this will not error on uncached arches */
      if (!flatpak_remote_state_ensure_subsummary_all_arches (state, dir, TRUE, cancellable, error))
        return FALSE;
    }

  /* Then download rest */
  if (!flatpak_remote_state_ensure_subsummary_all_arches (state, dir, FALSE, cancellable, error))
    return FALSE;

  return TRUE;
}

gboolean
setup_sideload_repositories (FlatpakTransaction *transaction,
                             char              **opt_sideload_repos,
                             GCancellable       *cancellable,
                             GError            **error)
{
  for (int i = 0; opt_sideload_repos != NULL && opt_sideload_repos[i] != NULL; i++)
    {
      const char *repo = opt_sideload_repos[i];
      if (g_str_has_prefix (repo, "oci:") || g_str_has_prefix (repo, "oci-archive:"))
        {
          if (!flatpak_transaction_add_sideload_image_collection (transaction, repo, cancellable, error))
            return FALSE;
        }
      else if (g_str_has_prefix (repo, "file:"))
        {
          g_autoptr(GFile) file = g_file_new_for_uri (repo);
          const char *path = flatpak_file_get_path_cached (file);
          flatpak_transaction_add_sideload_repo (transaction, path);
        }
      else
        {
          if (g_regex_match_simple ("^[A-Za-z][A-Za-z0-9+.-]*:", repo,
                                    G_REGEX_DEFAULT, G_REGEX_MATCH_DEFAULT))
            return flatpak_fail (error, _("Unknown scheme in sideload location %s"), repo);

          flatpak_transaction_add_sideload_repo (transaction, repo);
        }
    }

  return TRUE;
}

===== ./app/flatpak-builtins-build-import-bundle.c =====
/* vi:set et sw=2 sts=2 cin cino=t0,f0,(0,{s,>2s,n-s,^-s,e-s:
 * Copyright © 2015 Red Hat, Inc
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Alexander Larsson <alexl@redhat.com>
 */

#include "config.h"

#include <locale.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

#include <glib/gi18n.h>

#include "libglnx.h"

#include "flatpak-builtins.h"
#include "flatpak-image-source-private.h"
#include "flatpak-oci-registry-private.h"
#include "flatpak-repo-utils-private.h"
#include "flatpak-utils-private.h"

static char *opt_ref;
static gboolean opt_oci = FALSE;
static char **opt_gpg_key_ids;
static char *opt_gpg_homedir;
static gboolean opt_update_appstream;
static gboolean opt_no_update_summary;
static gboolean opt_no_summary_index = FALSE;

static GOptionEntry options[] = {
  { "ref", 0, 0, G_OPTION_ARG_STRING, &opt_ref, N_("Override the ref used for the imported bundle"), N_("REF") },
  { "oci", 0, 0, G_OPTION_ARG_NONE, &opt_oci, N_("Import oci image instead of flatpak bundle"), NULL },
  { "gpg-sign", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_gpg_key_ids, N_("GPG Key ID to sign the commit with"), N_("KEY-ID") },
  { "gpg-homedir", 0, 0, G_OPTION_ARG_STRING, &opt_gpg_homedir, N_("GPG Homedir to use when looking for keyrings"), N_("HOMEDIR") },
  { "update-appstream", 0, 0, G_OPTION_ARG_NONE, &opt_update_appstream, N_("Update the appstream branch"), NULL },
  { "no-update-summary", 0, 0, G_OPTION_ARG_NONE, &opt_no_update_summary, N_("Don't update the summary"), NULL },
  { "no-summary-index", 0, 0, G_OPTION_ARG_NONE, &opt_no_summary_index, N_("Don't generate a summary index"), NULL },
  { NULL }
};

static char *
import_oci (OstreeRepo *repo, GFile *file,
            GCancellable *cancellable, GError **error)
{
  g_autofree char *commit_checksum = NULL;
  g_autoptr(FlatpakImageSource) image_source = NULL;
  const char *ref;

  image_source = flatpak_image_source_new_local (file, opt_ref, cancellable, error);
  if (image_source == NULL)
    return NULL;

  ref = flatpak_image_source_get_ref (image_source);

  commit_checksum = flatpak_pull_from_oci (repo, image_source, NULL, NULL,
                                           ref, FLATPAK_PULL_FLAGS_NONE,
                                           NULL, NULL, cancellable, error);
  if (commit_checksum == NULL)
    return NULL;

  g_print (_("Importing %s (%s)\n"), ref, commit_checksum);

  return g_strdup (commit_checksum);
}

static char *
import_bundle (OstreeRepo *repo, GFile *file,
               GCancellable *cancellable, GError **error)
{
  g_autoptr(GVariant) metadata = NULL;
  g_autoptr(FlatpakDecomposed) bundle_ref = NULL;
  g_autofree char *to_checksum = NULL;
  const char *ref;

  /* Don’t need to check the collection ID of the bundle here;
   * flatpak_pull_from_bundle() does that. */
  metadata = flatpak_bundle_load (file, &to_checksum,
                                  &bundle_ref,
                                  NULL, NULL, NULL,
                                  NULL, NULL, NULL, error);
  if (metadata == NULL)
    return NULL;

  if (opt_ref != NULL)
    ref = opt_ref;
  else
    ref = flatpak_decomposed_get_ref (bundle_ref);

  g_print (_("Importing %s (%s)\n"), ref, to_checksum);
  if (!flatpak_pull_from_bundle (repo, file,
                                 NULL, ref, FALSE,
                                 cancellable,
                                 error))
    return NULL;

  return g_strdup (to_checksum);
}

gboolean
flatpak_builtin_build_import (int argc, char **argv, GCancellable *cancellable, GError **error)
{
  g_autoptr(GOptionContext) context = NULL;
  g_autoptr(GFile) file = NULL;
  g_autoptr(GFile) repofile = NULL;
  g_autoptr(OstreeRepo) repo = NULL;
  const char *location;
  const char *filename;
  g_autofree char *commit = NULL;

  context = g_option_context_new (_("LOCATION FILENAME - Import a file bundle into a local repository"));
  g_option_context_set_translation_domain (context, GETTEXT_PACKAGE);

  if (!flatpak_option_context_parse (context, options, &argc, &argv, FLATPAK_BUILTIN_FLAG_NO_DIR, NULL, cancellable, error))
    return FALSE;

  if (argc < 3)
    return usage_error (context, _("LOCATION and FILENAME must be specified"), error);

  if (argc > 3)
    return usage_error (context, _("Too many arguments"), error);

  location = argv[1];
  filename = argv[2];

  repofile = g_file_new_for_commandline_arg (location);
  repo = ostree_repo_new (repofile);

  if (!g_file_query_exists (repofile, cancellable))
    return flatpak_fail (error, _("'%s' is not a valid repository"), location);

  file = g_file_new_for_commandline_arg (filename);
  if (flatpak_file_get_path_cached (file) == NULL)
    return flatpak_fail (error, _("'%s' is not a valid filename"), filename);

  if (!ostree_repo_open (repo, cancellable, error))
    return FALSE;

  if (opt_oci)
    commit = import_oci (repo, file, cancellable, error);
  else
    commit = import_bundle (repo, file, cancellable, error);
  if (commit == NULL)
    return FALSE;

  if (opt_gpg_key_ids)
    {
      char **iter;

      for (iter = opt_gpg_key_ids; iter && *iter; iter++)
        {
          const char *keyid = *iter;
          g_autoptr(GError) local_error = NULL;

          if (!ostree_repo_sign_commit (repo,
                                        commit,
                                        keyid,
                                        opt_gpg_homedir,
                                        cancellable,
                                        &local_error))
            {
              if (!g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_EXISTS))
                {
                  g_propagate_error (error, g_steal_pointer (&local_error));
                  return FALSE;
                }
            }
        }
    }

  if (opt_update_appstream &&
      !flatpak_repo_generate_appstream (repo, (const char **) opt_gpg_key_ids, opt_gpg_homedir, 0, cancellable, error))
    return FALSE;

  if (!opt_no_update_summary)
    {
      FlatpakRepoUpdateFlags flags = FLATPAK_REPO_UPDATE_FLAG_NONE;

      if (opt_no_summary_index)
        flags |= FLATPAK_REPO_UPDATE_FLAG_DISABLE_INDEX;

      g_info ("Updating summary");
      if (!flatpak_repo_update (repo, flags,
                                (const char **) opt_gpg_key_ids,
                                opt_gpg_homedir,
                                cancellable,
                                error))
        return FALSE;
    }

  return TRUE;
}

gboolean
flatpak_complete_build_import (FlatpakCompletion *completion)
{
  g_autoptr(GOptionContext) context = NULL;

  context = g_option_context_new ("");

  if (!flatpak_option_context_parse (context, options, &completion->argc, &completion->argv,
                                     FLATPAK_BUILTIN_FLAG_NO_DIR, NULL, NULL, NULL))
    return FALSE;

  switch (completion->argc)
    {
    case 0:
    case 1: /* LOCATION */
      flatpak_complete_options (completion, global_entries);
      flatpak_complete_options (completion, options);

      flatpak_complete_dir (completion);
      break;

    case 2: /* FILENAME */
      flatpak_complete_file (completion, "__FLATPAK_BUNDLE_FILE");
      break;
    }

  return TRUE;
}

===== ./app/flatpak-polkit-agent-text-listener.c =====
/* vi:set et sw=2 sts=2 cin cino=t0,f0,(0,{s,>2s,n-s,^-s,e-s:
 * Copyright (C) 2008 Red Hat, Inc.
 *
 * 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 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., 59 Temple Place, Suite 330,
 * Boston, MA 02111-1307, USA.
 *
 * Author: David Zeuthen <davidz@redhat.com>
 */

#include "config.h"

#include <errno.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <pwd.h>

#include <termios.h>
#include <unistd.h>

#include "flatpak-polkit-agent-text-listener.h"

#include "flatpak-tty-utils-private.h"
#include "flatpak-utils-private.h"

#pragma GCC diagnostic ignored "-Wdeprecated-declarations"

struct _FlatpakPolkitAgentTextListener
{
  PolkitAgentListener parent_instance;

  GSimpleAsyncResult *simple;
  PolkitAgentSession *active_session;
  gulong cancel_id;
  GCancellable *cancellable;

  FILE *tty;
};

typedef struct
{
  PolkitAgentListenerClass parent_class;
} FlatpakPolkitAgentTextListenerClass;

static void flatpak_polkit_agent_text_listener_initiate_authentication (PolkitAgentListener  *_listener,
                                                                const gchar          *action_id,
                                                                const gchar          *message,
                                                                const gchar          *icon_name,
                                                                PolkitDetails        *details,
                                                                const gchar          *cookie,
                                                                GList                *identities,
                                                                GCancellable         *cancellable,
                                                                GAsyncReadyCallback   callback,
                                                                gpointer              user_data);

static gboolean flatpak_polkit_agent_text_listener_initiate_authentication_finish (PolkitAgentListener  *_listener,
                                                                           GAsyncResult         *res,
                                                                           GError              **error);

static void initable_iface_init (GInitableIface *initable_iface);

G_DEFINE_TYPE_WITH_CODE (FlatpakPolkitAgentTextListener, flatpak_polkit_agent_text_listener, POLKIT_AGENT_TYPE_LISTENER,
                         G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, initable_iface_init));

static void
flatpak_polkit_agent_text_listener_init (FlatpakPolkitAgentTextListener *listener)
{
}

static void
flatpak_polkit_agent_text_listener_finalize (GObject *object)
{
  FlatpakPolkitAgentTextListener *listener = FLATPAK_POLKIT_AGENT_TEXT_LISTENER (object);

  if (listener->tty != NULL)
    fclose (listener->tty);

  if (listener->active_session != NULL)
    g_object_unref (listener->active_session);

  if (G_OBJECT_CLASS (flatpak_polkit_agent_text_listener_parent_class)->finalize != NULL)
    G_OBJECT_CLASS (flatpak_polkit_agent_text_listener_parent_class)->finalize (object);
}

static void
flatpak_polkit_agent_text_listener_class_init (FlatpakPolkitAgentTextListenerClass *klass)
{
  GObjectClass *gobject_class;
  PolkitAgentListenerClass *listener_class;

  gobject_class = G_OBJECT_CLASS (klass);
  gobject_class->finalize = flatpak_polkit_agent_text_listener_finalize;

  listener_class = POLKIT_AGENT_LISTENER_CLASS (klass);
  listener_class->initiate_authentication = flatpak_polkit_agent_text_listener_initiate_authentication;
  listener_class->initiate_authentication_finish = flatpak_polkit_agent_text_listener_initiate_authentication_finish;
}

PolkitAgentListener *
flatpak_polkit_agent_text_listener_new (GCancellable  *cancellable,
                                        GError       **error)
{
  g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL);
  g_return_val_if_fail (error == NULL || *error == NULL, NULL);
  return POLKIT_AGENT_LISTENER (g_initable_new (FLATPAK_POLKIT_AGENT_TYPE_TEXT_LISTENER,
                                                cancellable,
                                                error,
                                                NULL));
}

static gboolean
initable_init (GInitable     *initable,
               GCancellable  *cancellable,
               GError       **error)
{
  FlatpakPolkitAgentTextListener *listener = FLATPAK_POLKIT_AGENT_TEXT_LISTENER (initable);
  gboolean ret;
  const gchar *tty_name;

  ret = FALSE;

  tty_name = ctermid (NULL);
  if (tty_name == NULL)
    {
      g_set_error (error, POLKIT_ERROR, POLKIT_ERROR_FAILED,
                   "Cannot determine pathname for current controlling terminal for the process: %s",
                   strerror (errno));
      goto out;
    }

  listener->tty = fopen (tty_name, "r+");
  if (listener->tty == NULL)
    {
      g_set_error (error, POLKIT_ERROR, POLKIT_ERROR_FAILED,
                   "Error opening current controlling terminal for the process (`%s'): %s",
                   tty_name, strerror (errno));
      goto out;
    }

  ret = TRUE;

 out:
  return ret;
}

static void
initable_iface_init (GInitableIface *initable_iface)
{
  initable_iface->init = initable_init;
}

static void
on_completed (PolkitAgentSession *session,
              gboolean            gained_authorization,
              gpointer            user_data)
{
  FlatpakPolkitAgentTextListener *listener = FLATPAK_POLKIT_AGENT_TEXT_LISTENER (user_data);

  if (flatpak_fancy_output ())
    fprintf (listener->tty, FLATPAK_ANSI_RED);
  if (gained_authorization)
    fprintf (listener->tty, "==== AUTHENTICATION COMPLETE ====\n");
  else
    fprintf (listener->tty, "==== AUTHENTICATION FAILED ====\n");
  if (flatpak_fancy_output ())
    {
      sleep (1); /* show the message for a bit */
      fprintf (listener->tty, FLATPAK_ANSI_COLOR_RESET FLATPAK_ANSI_ALT_SCREEN_OFF);
    }
  fflush (listener->tty);

  g_simple_async_result_complete_in_idle (listener->simple);

  g_object_unref (listener->simple);
  g_object_unref (listener->active_session);
  g_cancellable_disconnect (listener->cancellable, listener->cancel_id);
  g_object_unref (listener->cancellable);

  listener->simple = NULL;
  listener->active_session = NULL;
  listener->cancel_id = 0;
}

static void
on_request (PolkitAgentSession *session,
            const gchar        *request,
            gboolean            echo_on,
            gpointer            user_data)
{
  FlatpakPolkitAgentTextListener *listener = FLATPAK_POLKIT_AGENT_TEXT_LISTENER (user_data);
  struct termios ts, ots;
  GString *str;

  fprintf (listener->tty, "%s", request);
  fflush (listener->tty);

  setbuf (listener->tty, NULL);

  tcgetattr (fileno (listener->tty), &ts);
  ots = ts;
  ts.c_lflag &= ~(ECHO | ECHOE | ECHOK | ECHONL);
  tcsetattr (fileno (listener->tty), TCSAFLUSH, &ts);

  str = g_string_new (NULL);
  while (TRUE)
    {
      gint c;
      c = getc (listener->tty);
      if (c == '\n')
        {
          /* ok, done */
          break;
        }
      else if (c == EOF)
        {
          tcsetattr (fileno (listener->tty), TCSAFLUSH, &ots);
          g_error ("Got unexpected EOF while reading from controlling terminal.");
          abort ();
          break;
        }
      else
        {
          g_string_append_c (str, c);
        }
    }
  tcsetattr (fileno (listener->tty), TCSAFLUSH, &ots);
  putc ('\n', listener->tty);

  polkit_agent_session_response (session, str->str);
  memset (str->str, '\0', str->len);
  g_string_free (str, TRUE);
}

static void
on_show_error (PolkitAgentSession *session,
               const gchar        *text,
               gpointer            user_data)
{
  FlatpakPolkitAgentTextListener *listener = FLATPAK_POLKIT_AGENT_TEXT_LISTENER (user_data);
  fprintf (listener->tty, "Error: %s\n", text);
  fflush (listener->tty);
}

static void
on_show_info (PolkitAgentSession *session,
              const gchar        *text,
              gpointer            user_data)
{
  FlatpakPolkitAgentTextListener *listener = FLATPAK_POLKIT_AGENT_TEXT_LISTENER (user_data);
  fprintf (listener->tty, "Info: %s\n", text);
  fflush (listener->tty);
}

static void
on_cancelled (GCancellable *cancellable,
              gpointer      user_data)
{
  FlatpakPolkitAgentTextListener *listener = FLATPAK_POLKIT_AGENT_TEXT_LISTENER (user_data);
  fprintf (listener->tty, "Cancelled\n");
  fflush (listener->tty);
  polkit_agent_session_cancel (listener->active_session);
}

static gchar *
identity_to_human_readable_string (PolkitIdentity *identity)
{
  gchar *ret;

  g_return_val_if_fail (POLKIT_IS_IDENTITY (identity), NULL);

  ret = NULL;
  if (POLKIT_IS_UNIX_USER (identity))
    {
      struct passwd pw;
      struct passwd *ppw;
      char buf[2048];
      int res;

      res = getpwuid_r (polkit_unix_user_get_uid (POLKIT_UNIX_USER (identity)),
                        &pw,
                        buf,
                        sizeof buf,
                        &ppw);
      if (res != 0)
        {
          g_warning ("Error calling getpwuid_r: %s", strerror (res));
        }
      else
        {
          if (ppw->pw_gecos == NULL || strlen (ppw->pw_gecos) == 0 || strcmp (ppw->pw_gecos, ppw->pw_name) == 0)
            {
              ret = g_strdup_printf ("%s", ppw->pw_name);
            }
          else
            {
              ret = g_strdup_printf ("%s (%s)", ppw->pw_gecos, ppw->pw_name);
            }
        }
    }
  if (ret == NULL)
    ret = polkit_identity_to_string (identity);
  return ret;
}

static PolkitIdentity *
choose_identity (FlatpakPolkitAgentTextListener *listener,
                 GList                   *identities)
{
  GList *l;
  guint n;
  guint num_identities;
  GString *str;
  PolkitIdentity *ret;
  guint num;
  gchar *endp;

  ret = NULL;

  fprintf (listener->tty, "Multiple identities can be used for authentication:\n");
  for (l = identities, n = 0; l != NULL; l = l->next, n++)
    {
      PolkitIdentity *identity = POLKIT_IDENTITY (l->data);
      gchar *s;
      s = identity_to_human_readable_string (identity);
      fprintf (listener->tty, " %d.  %s\n", n + 1, s);
      g_free (s);
    }
  num_identities = n;
  fprintf (listener->tty, "Choose identity to authenticate as (1-%d): ", num_identities);
  fflush (listener->tty);

  str = g_string_new (NULL);
  while (TRUE)
    {
      gint c;
      c = getc (listener->tty);
      if (c == '\n')
        {
          /* ok, done */
          break;
        }
      else if (c == EOF)
        {
          g_error ("Got unexpected EOF while reading from controlling terminal.");
          abort ();
          break;
        }
      else
        {
          g_string_append_c (str, c);
        }
    }

  num = strtol (str->str, &endp, 10);
  if (str->len == 0 || *endp != '\0' || (num < 1 || num > num_identities))
    {
      fprintf (listener->tty, "Invalid response `%s'.\n", str->str);
      goto out;
    }

  ret = g_list_nth_data (identities, num-1);

 out:
  g_string_free (str, TRUE);
  return ret;
}


static void
flatpak_polkit_agent_text_listener_initiate_authentication (PolkitAgentListener  *_listener,
                                                            const gchar          *action_id,
                                                            const gchar          *message,
                                                            const gchar          *icon_name,
                                                            PolkitDetails        *details,
                                                            const gchar          *cookie,
                                                            GList                *identities,
                                                            GCancellable         *cancellable,
                                                            GAsyncReadyCallback   callback,
                                                            gpointer              user_data)
{
  FlatpakPolkitAgentTextListener *listener = FLATPAK_POLKIT_AGENT_TEXT_LISTENER (_listener);
  GSimpleAsyncResult *simple;
  PolkitIdentity *identity;

  simple = g_simple_async_result_new (G_OBJECT (listener),
                                      callback,
                                      user_data,
                                      flatpak_polkit_agent_text_listener_initiate_authentication);
  if (listener->active_session != NULL)
    {
      g_simple_async_result_set_error (simple, POLKIT_ERROR, POLKIT_ERROR_FAILED,
                                       "An authentication session is already underway.");
      g_simple_async_result_complete_in_idle (simple);
      g_object_unref (simple);
      goto out;
    }

  g_assert (g_list_length (identities) >= 1);

  if (flatpak_fancy_output ())
    {
      fprintf (listener->tty, FLATPAK_ANSI_ALT_SCREEN_ON FLATPAK_ANSI_RED);
    }

  fprintf (listener->tty, "==== AUTHENTICATING FOR %s ====\n", action_id);

  if (flatpak_fancy_output ())
    fprintf (listener->tty, FLATPAK_ANSI_COLOR_RESET);

  fprintf (listener->tty, "%s\n", message);

  /* handle multiple identities by asking which one to use */
  if (g_list_length (identities) > 1)
    {
      identity = choose_identity (listener, identities);
      if (identity == NULL)
        {
          fprintf (listener->tty, "\x1B[1;31m");
          fprintf (listener->tty, "==== AUTHENTICATION CANCELED ====\n");
          fprintf (listener->tty, "\x1B[0m");
          fflush (listener->tty);
          g_simple_async_result_set_error (simple,
                                           POLKIT_ERROR,
                                           POLKIT_ERROR_FAILED,
                                           "Authentication was canceled.");
          g_simple_async_result_complete_in_idle (simple);
          g_object_unref (simple);
          goto out;
        }
    }
  else
    {
      gchar *s;
      identity = identities->data;
      s = identity_to_human_readable_string (identity);
      fprintf (listener->tty,
               "Authenticating as: %s\n",
               s);
      g_free (s);
    }

  listener->active_session = polkit_agent_session_new (identity, cookie);
  g_signal_connect (listener->active_session,
                    "completed",
                    G_CALLBACK (on_completed),
                    listener);
  g_signal_connect (listener->active_session,
                    "request",
                    G_CALLBACK (on_request),
                    listener);
  g_signal_connect (listener->active_session,
                    "show-info",
                    G_CALLBACK (on_show_info),
                    listener);
  g_signal_connect (listener->active_session,
                    "show-error",
                    G_CALLBACK (on_show_error),
                    listener);

  listener->simple = simple;
  listener->cancellable = g_object_ref (cancellable);
  listener->cancel_id = g_cancellable_connect (cancellable,
                                               G_CALLBACK (on_cancelled),
                                               listener,
                                               NULL);

  polkit_agent_session_initiate (listener->active_session);

 out:
  ;
}

static gboolean
flatpak_polkit_agent_text_listener_initiate_authentication_finish (PolkitAgentListener  *_listener,
                                                                   GAsyncResult         *res,
                                                                   GError              **error)
{
  g_warn_if_fail (g_simple_async_result_get_source_tag (G_SIMPLE_ASYNC_RESULT (res)) ==
                  flatpak_polkit_agent_text_listener_initiate_authentication);

  if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error))
    return FALSE;

  return TRUE;
}

===== ./app/flatpak-builtins-search.c =====
/* vi:set et sw=2 sts=2 cin cino=t0,f0,(0,{s,>2s,n-s,^-s,e-s:
 * Copyright © 2017 Patrick Griffis
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Patrick Griffis <tingping@tingping.se>
 */

#include "config.h"

#include <glib/gi18n.h>
#include <appstream.h>

#include "flatpak-builtins.h"
#include "flatpak-builtins-utils.h"
#include "flatpak-dir-private.h"
#include "flatpak-table-printer.h"
#include "flatpak-utils-private.h"

static char *opt_arch;
static const char **opt_cols;
static gboolean opt_json;

static GOptionEntry options[] = {
  { "arch", 0, 0, G_OPTION_ARG_STRING, &opt_arch, N_("Arch to search for"), N_("ARCH") },
  { "columns", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_cols, N_("What information to show"), N_("FIELD,…") },
  { "json", 'j', 0, G_OPTION_ARG_NONE, &opt_json, N_("Show output in JSON format"), NULL },
  { NULL}
};

static Column all_columns[] = {
  { "name",        N_("Name"),        N_("Show the name"),               1, FLATPAK_ELLIPSIZE_MODE_END, 1, 1 },
  { "description", N_("Description"), N_("Show the description"),        1, FLATPAK_ELLIPSIZE_MODE_END, 1, 1 },
  { "application", N_("Application ID"), N_("Show the application ID"),     1, FLATPAK_ELLIPSIZE_MODE_START, 1, 1 },
  { "version",     N_("Version"),     N_("Show the version"),            1, FLATPAK_ELLIPSIZE_MODE_NONE, 1, 1 },
  { "branch",      N_("Branch"),      N_("Show the application branch"), 1, FLATPAK_ELLIPSIZE_MODE_NONE, 1, 1 },
  { "remotes",     N_("Remotes"),     N_("Show the remotes"),            1, FLATPAK_ELLIPSIZE_MODE_NONE, 1, 1 },
  { NULL }
};

static GPtrArray *
get_remote_stores (GPtrArray *dirs, const char *arch, GCancellable *cancellable)
{
  GError *error = NULL;
  GPtrArray *ret = g_ptr_array_new_with_free_func (g_object_unref);
  guint i, j;

  for (i = 0; i < dirs->len; ++i)
    {
      FlatpakDir *dir = g_ptr_array_index (dirs, i);
      g_auto(GStrv) remotes = NULL;

      flatpak_log_dir_access (dir);

      remotes = flatpak_dir_list_enumerated_remotes (dir, cancellable, &error);
      if (error)
        {
          g_warning ("%s", error->message);
          g_clear_error (&error);
          continue;
        }
      else if (remotes == NULL)
        continue;

      for (j = 0; remotes[j]; ++j)
        {
          g_autoptr(AsMetadata) mdata = as_metadata_new ();

          flatpak_dir_load_appstream_data (dir, remotes[j], arch, mdata, cancellable, &error);

          if (error)
            {
              g_warning ("%s", error->message);
              g_clear_error (&error);
            }

          g_object_set_data_full (G_OBJECT (mdata), "remote-name", g_strdup (remotes[j]), g_free);
          g_ptr_array_add (ret, g_steal_pointer (&mdata));
        }
    }
  return ret;
}

typedef struct MatchResult
{
  AsComponent *app;
  GPtrArray   *remotes;
  guint        score;
} MatchResult;

static void
match_result_free (MatchResult *result)
{
  g_object_unref (result->app);
  g_ptr_array_unref (result->remotes);
  g_free (result);
}

static MatchResult *
match_result_new (AsComponent *app, guint score)
{
  MatchResult *result = g_new (MatchResult, 1);

  result->app = g_object_ref (app);
  result->remotes = g_ptr_array_new_with_free_func (g_free);
  result->score = score;

  return result;
}

static void
match_result_add_remote (MatchResult *self, const char *remote)
{
  guint i;

  for (i = 0; i < self->remotes->len; ++i)
    {
      const char *remote_entry = g_ptr_array_index (self->remotes, i);
      if (!strcmp (remote, remote_entry))
        return;
    }
  g_ptr_array_add (self->remotes, g_strdup (remote));
}

static int
compare_by_score (MatchResult *a, MatchResult *b, gpointer user_data)
{
  // Reverse order, higher score comes first
  return (int) b->score - (int) a->score;
}

static gboolean
as_app_equal (AsComponent *app1, AsComponent *app2)
{
  if (app1 == app2)
    return TRUE;

  FlatpakDecomposed *app1_decomposed = g_object_get_data (G_OBJECT (app1), "decomposed");
  FlatpakDecomposed *app2_decomposed = g_object_get_data (G_OBJECT (app2), "decomposed");

  /* Ignore arch when comparing since it's not shown in the search output and
   * we don't want duplicate results for the same app with different arches.
   */
  return flatpak_decomposed_equal_except_arch (app1_decomposed, app2_decomposed);
}

static int
compare_apps (MatchResult *a, AsComponent *b)
{
  return !as_app_equal (a->app, b);
}

/* as_component_get_id() returns the appstream component ID which doesn't
 * necessarily match the flatpak app ID (e.g. sometimes there's a .desktop
 * suffix on the appstream ID) so this gets the flatpak app ID via the bundle
 * element
 */
static char *
component_get_flatpak_id (AsComponent *app)
{
  FlatpakDecomposed *app_decomposed = g_object_get_data (G_OBJECT (app), "decomposed");
  return flatpak_decomposed_dup_id (app_decomposed);
}

/* as_component_get_branch() seems to return NULL in practice, so use the
 * bundle id to get the branch
 */
static const char *
component_get_branch (AsComponent *app)
{
  FlatpakDecomposed *app_decomposed = g_object_get_data (G_OBJECT (app), "decomposed");
  return flatpak_decomposed_get_branch (app_decomposed);
}

static void
print_app (Column *columns, MatchResult *res, FlatpakTablePrinter *printer)
{
  const char *version = component_get_version_latest (res->app);
  g_autofree char *id = component_get_flatpak_id (res->app);
  const char *name = as_component_get_name (res->app);
  const char *comment = as_component_get_summary (res->app);
  guint i;

  for (i = 0; columns[i].name; i++)
    {
      if (strcmp (columns[i].name, "name") == 0)
        flatpak_table_printer_add_column (printer, name);
      if (strcmp (columns[i].name, "description") == 0)
        flatpak_table_printer_add_column (printer, comment);
      else if (strcmp (columns[i].name, "application") == 0)
        flatpak_table_printer_add_column (printer, id);
      else if (strcmp (columns[i].name, "version") == 0)
        flatpak_table_printer_add_column (printer, version);
      else if (strcmp (columns[i].name, "branch") == 0)
        flatpak_table_printer_add_column (printer, component_get_branch (res->app));
      else if (strcmp (columns[i].name, "remotes") == 0)
        {
          int j;
          flatpak_table_printer_add_column (printer, g_ptr_array_index (res->remotes, 0));
          for (j = 1; j < res->remotes->len; j++)
            flatpak_table_printer_append_with_comma (printer, g_ptr_array_index (res->remotes, j));
        }
    }
  flatpak_table_printer_finish_row (printer);
}

static void
print_matches (Column *columns, GSList *matches)
{
  g_autoptr(FlatpakTablePrinter) printer = NULL;
  GSList *s;

  printer = flatpak_table_printer_new ();

  flatpak_table_printer_set_columns (printer, columns, opt_cols != NULL);

  for (s = matches; s; s = s->next)
    {
      MatchResult *res = s->data;
      print_app (columns, res, printer);
    }

  opt_json ? flatpak_table_printer_print_json (printer) : flatpak_table_printer_print (printer);
}

gboolean
flatpak_builtin_search (int argc, char **argv, GCancellable *cancellable, GError **error)
{
  g_autoptr(GPtrArray) dirs = NULL;
  g_autofree char *col_help = NULL;
  g_autofree Column *columns = NULL;
  g_autoptr(GOptionContext) context = g_option_context_new (_("TEXT - Search remote apps/runtimes for text"));
  g_option_context_set_translation_domain (context, GETTEXT_PACKAGE);
  col_help = column_help (all_columns);
  g_option_context_set_description (context, col_help);

  if (!flatpak_option_context_parse (context, options, &argc, &argv,
                                     FLATPAK_BUILTIN_FLAG_ALL_DIRS | FLATPAK_BUILTIN_FLAG_OPTIONAL_REPO,
                                     &dirs, cancellable, error))
    return FALSE;

  if (argc < 2)
    return usage_error (context, _("TEXT must be specified"), error);

  columns = handle_column_args (all_columns, FALSE, opt_cols, error);
  if (columns == NULL)
    return FALSE;

  if (!update_appstream (dirs, NULL, opt_arch, FLATPAK_APPSTREAM_TTL, TRUE, cancellable, error))
    return FALSE;

  const char *search_text = argv[1];
  GSList *matches = NULL;
  guint j;

  // We want a store for each remote so we keep the remote information
  // as AsComponent doesn't currently contain that information
  g_autoptr(GPtrArray) remote_stores = get_remote_stores (dirs, opt_arch, cancellable);
  for (j = 0; j < remote_stores->len; ++j)
    {
      AsMetadata *mdata = g_ptr_array_index (remote_stores, j);
#if AS_CHECK_VERSION(1, 0, 0)
      AsComponentBox *apps = as_metadata_get_components (mdata);
#else
      GPtrArray *apps = as_metadata_get_components (mdata);
#endif

#if AS_CHECK_VERSION(1, 0, 0)
      for (guint i = 0; i < as_component_box_len (apps); ++i)
        {
          AsComponent *app = as_component_box_index (apps, i);
#else
      for (guint i = 0; i < apps->len; ++i)
        {
          AsComponent *app = g_ptr_array_index (apps, i);
#endif
          const char *remote_name = g_object_get_data (G_OBJECT (mdata), "remote-name");
          g_autoptr(FlatpakDecomposed) decomposed = NULL;

          AsBundle *bundle = as_component_get_bundle (app, AS_BUNDLE_KIND_FLATPAK);
          if (bundle == NULL || as_bundle_get_id (bundle) == NULL ||
              (decomposed = flatpak_decomposed_new_from_ref (as_bundle_get_id (bundle), NULL)) == NULL)
            {
              g_info ("Ignoring app %s from remote %s as it lacks a flatpak bundle",
                      as_component_get_id (app), remote_name);
              continue;
            }

          g_object_set_data_full (G_OBJECT (app), "decomposed", g_steal_pointer (&decomposed),
                                  (GDestroyNotify) flatpak_decomposed_unref);

          guint score = as_component_search_matches (app, search_text);
          if (score == 0)
            {
              g_autofree char *app_id = component_get_flatpak_id (app);
              const char *app_name = as_component_get_name (app);
              if (strcasestr (app_id, search_text) != NULL || strcasestr (app_name, search_text) != NULL)
                score = 50;
              else
                continue;
            }

          // Avoid duplicate entries, but show multiple remotes
          GSList *list_entry = g_slist_find_custom (matches, app,
                                                    (GCompareFunc) compare_apps);
          MatchResult *result = NULL;
          if (list_entry != NULL)
            result = list_entry->data;
          else
            {
              result = match_result_new (app, score);
              matches = g_slist_insert_sorted_with_data (matches, result,
                                                         (GCompareDataFunc) compare_by_score, NULL);
            }
          match_result_add_remote (result, remote_name);
        }
    }

  if (matches != NULL)
    {
      print_matches (columns, matches);
      g_slist_free_full (matches, (GDestroyNotify) match_result_free);
    }
  else
    {
      g_print ("%s\n", _("No matches found"));
    }
  return TRUE;
}

gboolean
flatpak_complete_search (FlatpakCompletion *completion)
{
  g_autoptr(GOptionContext) context = NULL;

  context = g_option_context_new ("");
  if (!flatpak_option_context_parse (context, options, &completion->argc, &completion->argv,
                                     FLATPAK_BUILTIN_FLAG_ALL_DIRS | FLATPAK_BUILTIN_FLAG_OPTIONAL_REPO,
                                     NULL, NULL, NULL))
    return FALSE;

  flatpak_complete_options (completion, global_entries);
  flatpak_complete_options (completion, options);
  flatpak_complete_options (completion, user_entries);
  flatpak_complete_columns (completion, all_columns);
  return TRUE;
}

===== ./app/flatpak-builtins-build-commit-from.c =====
/* vi:set et sw=2 sts=2 cin cino=t0,f0,(0,{s,>2s,n-s,^-s,e-s:
 * Copyright © 2015 Red Hat, Inc
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Alexander Larsson <alexl@redhat.com>
 */

#include "config.h"

#include <locale.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

#include <glib/gi18n.h>

#include "libglnx.h"

#include "flatpak-builtins.h"
#include "flatpak-repo-utils-private.h"
#include "flatpak-utils-private.h"
#include "parse-datetime.h"

static char *opt_src_repo;
static char *opt_src_ref;
static char *opt_subject;
static char *opt_body;
static gboolean opt_update_appstream;
static gboolean opt_no_update_summary;
static gboolean opt_untrusted;
static gboolean opt_disable_fsync;
static gboolean opt_force;
static char **opt_gpg_key_ids;
static char *opt_gpg_homedir;
static char *opt_endoflife;
static char **opt_endoflife_rebase;
static char **opt_endoflife_rebase_new;
static char **opt_subsets;
static char *opt_timestamp;
static char **opt_extra_collection_ids;
static int opt_token_type = -1;
static gboolean opt_no_summary_index = FALSE;

static GOptionEntry options[] = {
  { "src-repo", 0, 0, G_OPTION_ARG_STRING, &opt_src_repo, N_("Source repo dir"), N_("SRC-REPO") },
  { "src-ref", 0, 0, G_OPTION_ARG_STRING, &opt_src_ref, N_("Source repo ref"), N_("SRC-REF") },
  { "untrusted", 0, 0, G_OPTION_ARG_NONE, &opt_untrusted, "Do not trust SRC-REPO", NULL },
  { "force", 0, 0, G_OPTION_ARG_NONE, &opt_force, "Always commit, even if same content", NULL },
  { "extra-collection-id", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_extra_collection_ids, "Add an extra collection id ref and binding", "COLLECTION-ID" },
  { "subset", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_subsets, "Add to a named subset", "SUBSET" },
  { "subject", 's', 0, G_OPTION_ARG_STRING, &opt_subject, N_("One line subject"), N_("SUBJECT") },
  { "body", 'b', 0, G_OPTION_ARG_STRING, &opt_body, N_("Full description"), N_("BODY") },
  { "update-appstream", 0, 0, G_OPTION_ARG_NONE, &opt_update_appstream, N_("Update the appstream branch"), NULL },
  { "no-update-summary", 0, 0, G_OPTION_ARG_NONE, &opt_no_update_summary, N_("Don't update the summary"), NULL },
  { "gpg-sign", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_gpg_key_ids, N_("GPG Key ID to sign the commit with"), N_("KEY-ID") },
  { "gpg-homedir", 0, 0, G_OPTION_ARG_STRING, &opt_gpg_homedir, N_("GPG Homedir to use when looking for keyrings"), N_("HOMEDIR") },
  { "end-of-life", 0, 0, G_OPTION_ARG_STRING, &opt_endoflife, N_("Mark build as end-of-life"), N_("REASON") },
  { "end-of-life-rebase", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_endoflife_rebase, N_("Mark refs matching the OLDID prefix as end-of-life, to be replaced with the given NEWID"), N_("OLDID=NEWID") },
  { "token-type", 0, 0, G_OPTION_ARG_INT, &opt_token_type, N_("Set type of token needed to install this commit"), N_("VAL") },
  { "timestamp", 0, 0, G_OPTION_ARG_STRING, &opt_timestamp, N_("Override the timestamp of the commit (NOW for current time)"), N_("TIMESTAMP") },
  { "disable-fsync", 0, 0, G_OPTION_ARG_NONE, &opt_disable_fsync, "Do not invoke fsync()", NULL },
  { "no-summary-index", 0, 0, G_OPTION_ARG_NONE, &opt_no_summary_index, N_("Don't generate a summary index"), NULL },
  { NULL }
};

#define OSTREE_STATIC_DELTA_META_ENTRY_FORMAT "(uayttay)"
#define OSTREE_STATIC_DELTA_FALLBACK_FORMAT "(yaytt)"
#define OSTREE_STATIC_DELTA_SUPERBLOCK_FORMAT "(a{sv}tayay" OSTREE_COMMIT_GVARIANT_STRING "aya" OSTREE_STATIC_DELTA_META_ENTRY_FORMAT "a" OSTREE_STATIC_DELTA_FALLBACK_FORMAT ")"

static char *
_ostree_get_relative_static_delta_path (const char *from,
                                        const char *to,
                                        const char *target)
{
  guint8 csum_to[OSTREE_SHA256_DIGEST_LEN];
  char to_b64[44];
  guint8 csum_to_copy[OSTREE_SHA256_DIGEST_LEN];
  GString *ret = g_string_new ("deltas/");

  ostree_checksum_inplace_to_bytes (to, csum_to);
  ostree_checksum_b64_inplace_from_bytes (csum_to, to_b64);
  ostree_checksum_b64_inplace_to_bytes (to_b64, csum_to_copy);

  g_assert (memcmp (csum_to, csum_to_copy, OSTREE_SHA256_DIGEST_LEN) == 0);

  if (from != NULL)
    {
      guint8 csum_from[OSTREE_SHA256_DIGEST_LEN];
      char from_b64[44];

      ostree_checksum_inplace_to_bytes (from, csum_from);
      ostree_checksum_b64_inplace_from_bytes (csum_from, from_b64);

      g_string_append_c (ret, from_b64[0]);
      g_string_append_c (ret, from_b64[1]);
      g_string_append_c (ret, '/');
      g_string_append (ret, from_b64 + 2);
      g_string_append_c (ret, '-');
    }

  g_string_append_c (ret, to_b64[0]);
  g_string_append_c (ret, to_b64[1]);
  if (from == NULL)
    g_string_append_c (ret, '/');
  g_string_append (ret, to_b64 + 2);

  if (target != NULL)
    {
      g_string_append_c (ret, '/');
      g_string_append (ret, target);
    }

  return g_string_free (ret, FALSE);
}

static GVariant *
new_bytearray (const guchar *data,
               gsize         len)
{
  gpointer data_copy = g_memdup2 (data, len);
  GVariant *ret = g_variant_new_from_data (G_VARIANT_TYPE ("ay"), data_copy,
                                           len, FALSE, g_free, data_copy);

  return ret;
}

static gboolean
rewrite_delta (OstreeRepo *src_repo,
               const char *src_commit,
               OstreeRepo *dst_repo,
               const char *dst_commit,
               GVariant   *dst_commitv,
               const char *from,
               GError    **error)
{
  g_autoptr(GFile) src_delta_file = NULL;
  g_autoptr(GFile) dst_delta_file = NULL;
  g_autofree char *src_detached_key = _ostree_get_relative_static_delta_path (from, src_commit, "commitmeta");
  g_autofree char *dst_detached_key = _ostree_get_relative_static_delta_path (from, dst_commit, "commitmeta");
  g_autofree char *src_delta_dir = _ostree_get_relative_static_delta_path (from, src_commit, NULL);
  g_autofree char *dst_delta_dir = _ostree_get_relative_static_delta_path (from, dst_commit, NULL);
  g_autofree char *src_superblock_path = _ostree_get_relative_static_delta_path (from, src_commit, "superblock");
  g_autofree char *dst_superblock_path = _ostree_get_relative_static_delta_path (from, dst_commit, "superblock");
  GMappedFile *mfile = NULL;
  g_auto(GVariantBuilder) superblock_builder = FLATPAK_VARIANT_BUILDER_INITIALIZER;
  g_autoptr(GVariant) src_superblock = NULL;
  g_autoptr(GVariant) dst_superblock = NULL;
  g_autoptr(GBytes) bytes = NULL;
  g_autoptr(GVariant) dst_detached = NULL;
  g_autoptr(GVariant) src_metadata = NULL;
  g_autoptr(GVariant) src_recurse = NULL;
  g_autoptr(GVariant) src_parts = NULL;
  g_auto(GVariantDict) dst_metadata_dict = FLATPAK_VARIANT_DICT_INITIALIZER;
  int i;

  src_delta_file = g_file_resolve_relative_path (ostree_repo_get_path (src_repo), src_superblock_path);
  mfile = g_mapped_file_new (flatpak_file_get_path_cached (src_delta_file), FALSE, NULL);
  if (mfile == NULL)
    return TRUE; /* No superblock, not an error */

  bytes = g_mapped_file_get_bytes (mfile);
  g_mapped_file_unref (mfile);

  src_superblock = g_variant_ref_sink (g_variant_new_from_bytes (G_VARIANT_TYPE (OSTREE_STATIC_DELTA_SUPERBLOCK_FORMAT), bytes, FALSE));

  src_metadata = g_variant_get_child_value (src_superblock, 0);
  src_recurse = g_variant_get_child_value (src_superblock, 5);
  src_parts = g_variant_get_child_value (src_superblock, 6);

  if (g_variant_n_children (src_recurse) != 0)
    return flatpak_fail (error, "Recursive deltas not supported, ignoring");

  g_variant_builder_init (&superblock_builder, G_VARIANT_TYPE (OSTREE_STATIC_DELTA_SUPERBLOCK_FORMAT));

  g_variant_dict_init (&dst_metadata_dict, src_metadata);
  g_variant_dict_remove (&dst_metadata_dict, src_detached_key);
  if (ostree_repo_read_commit_detached_metadata (dst_repo, dst_commit, &dst_detached, NULL, NULL) &&
      dst_detached != NULL)
    g_variant_dict_insert_value (&dst_metadata_dict, dst_detached_key, dst_detached);

  g_variant_builder_add_value (&superblock_builder, g_variant_dict_end (&dst_metadata_dict));
  g_variant_builder_add_value (&superblock_builder, g_variant_get_child_value (src_superblock, 1)); /* timestamp */
  g_variant_builder_add_value (&superblock_builder, from ? ostree_checksum_to_bytes_v (from) : new_bytearray ((guchar *) "", 0));
  g_variant_builder_add_value (&superblock_builder, ostree_checksum_to_bytes_v (dst_commit));
  g_variant_builder_add_value (&superblock_builder, dst_commitv);
  g_variant_builder_add_value (&superblock_builder, src_recurse);
  g_variant_builder_add_value (&superblock_builder, src_parts);
  g_variant_builder_add_value (&superblock_builder, g_variant_get_child_value (src_superblock, 7)); /* fallback */

  dst_superblock = g_variant_ref_sink (g_variant_builder_end (&superblock_builder));

  if (!glnx_shutil_mkdir_p_at (ostree_repo_get_dfd (dst_repo), dst_delta_dir, 0755, NULL, error))
    return FALSE;

  for (i = 0; i < g_variant_n_children (src_parts); i++)
    {
      g_autofree char *src_part_path = g_strdup_printf ("%s/%d", src_delta_dir, i);
      g_autofree char *dst_part_path = g_strdup_printf ("%s/%d", dst_delta_dir, i);

      if (!glnx_file_copy_at (ostree_repo_get_dfd (src_repo),
                              src_part_path,
                              NULL,
                              ostree_repo_get_dfd (dst_repo),
                              dst_part_path,
                              GLNX_FILE_COPY_OVERWRITE | GLNX_FILE_COPY_NOXATTRS,
                              NULL, error))
        return FALSE;
    }

  dst_delta_file = g_file_resolve_relative_path (ostree_repo_get_path (dst_repo), dst_superblock_path);
  if (!flatpak_variant_save (dst_delta_file, dst_superblock, NULL, error))
    return FALSE;

  return TRUE;
}

static gboolean
get_subsets (char **subsets, GVariant **out)
{
  g_autoptr(GVariantBuilder) builder = g_variant_builder_new (G_VARIANT_TYPE ("as"));
  gboolean found = FALSE;

  if (subsets == NULL)
    return FALSE;

  for (int i = 0; subsets[i] != NULL; i++)
    {
      const char *subset = subsets[i];
      if (*subset != 0)
        {
          found = TRUE;
          g_variant_builder_add (builder, "s", subset);
        }
    }

  if (!found)
    return FALSE;

  *out = g_variant_ref_sink (g_variant_builder_end (builder));
  return TRUE;
}


gboolean
flatpak_builtin_build_commit_from (int argc, char **argv, GCancellable *cancellable, GError **error)
{
  g_autoptr(GOptionContext) context = NULL;
  g_autoptr(GFile) dst_repofile = NULL;
  g_autoptr(OstreeRepo) dst_repo = NULL;
  g_autoptr(GFile) src_repofile = NULL;
  g_autoptr(OstreeRepo) src_repo = NULL;
  g_autofree char *src_repo_uri = NULL;
  const char *dst_repo_arg;
  const char **dst_refs;
  int n_dst_refs = 0;
  g_autoptr(FlatpakRepoTransaction) transaction = NULL;
  g_autoptr(GPtrArray) src_refs = NULL;
  g_autoptr(GPtrArray) resolved_src_refs = NULL;
  OstreeRepoCommitState src_commit_state;
  struct timespec ts;
  guint64 timestamp;
  int i;
  const char *src_collection_id;

  context = g_option_context_new (_("DST-REPO [DST-REF…] - Make a new commit from existing commits"));
  g_option_context_set_translation_domain (context, GETTEXT_PACKAGE);

  if (!flatpak_option_context_parse (context, options, &argc, &argv, FLATPAK_BUILTIN_FLAG_NO_DIR, NULL, cancellable, error))
    return FALSE;

  if (argc < 2)
    return usage_error (context, _("DST-REPO must be specified"), error);

  dst_repo_arg = argv[1];

  dst_refs = (const char **) argv + 2;
  n_dst_refs = argc - 2;

  if (opt_src_repo == NULL && n_dst_refs != 1)
    return usage_error (context, _("If --src-repo is not specified, exactly one destination ref must be specified"), error);

  if (opt_src_ref != NULL && n_dst_refs != 1)
    return usage_error (context, _("If --src-ref is specified, exactly one destination ref must be specified"), error);

  if (opt_src_repo == NULL && opt_src_ref == NULL)
    return flatpak_fail (error, _("Either --src-repo or --src-ref must be specified"));

  /* Always create a commit if we're eol:ing, even though the app is the same */
  if (opt_endoflife != NULL || opt_endoflife_rebase != NULL)
    opt_force = TRUE;

  if (opt_endoflife_rebase)
    {
      opt_endoflife_rebase_new = g_new0 (char *, g_strv_length (opt_endoflife_rebase));

      for (i = 0; opt_endoflife_rebase[i] != NULL; i++)
        {
          char *rebase_old = opt_endoflife_rebase[i];
          char *rebase_new = strchr (rebase_old, '=');

          if (rebase_new == NULL) {
            return usage_error (context, _("Invalid argument format of use  --end-of-life-rebase=OLDID=NEWID"), error);
          }
          *rebase_new = 0;
          rebase_new++;

          if (!flatpak_is_valid_name (rebase_old, -1, error))
            return glnx_prefix_error (error, _("Invalid name %s in --end-of-life-rebase"), rebase_old);

          if (!flatpak_is_valid_name (rebase_new, -1, error))
            return glnx_prefix_error (error, _("Invalid name %s in --end-of-life-rebase"), rebase_new);

          opt_endoflife_rebase_new[i] = rebase_new;
        }
    }

  if (opt_timestamp)
    {
      if (!parse_datetime (&ts, opt_timestamp, NULL))
        return flatpak_fail (error, _("Could not parse '%s'"), opt_timestamp);
    }

  dst_repofile = g_file_new_for_commandline_arg (dst_repo_arg);
  if (!g_file_query_exists (dst_repofile, cancellable))
    return flatpak_fail (error, _("'%s' is not a valid repository"), dst_repo_arg);

  dst_repo = ostree_repo_new (dst_repofile);
  if (!ostree_repo_open (dst_repo, cancellable, error))
    return FALSE;

  if (opt_disable_fsync)
    ostree_repo_set_disable_fsync (dst_repo, TRUE);

  if (opt_src_repo)
    {
      src_repofile = g_file_new_for_commandline_arg (opt_src_repo);
      if (!g_file_query_exists (src_repofile, cancellable))
        return flatpak_fail (error, _("'%s' is not a valid repository"), opt_src_repo);

      src_repo_uri = g_file_get_uri (src_repofile);
      src_repo = ostree_repo_new (src_repofile);
      if (!ostree_repo_open (src_repo, cancellable, error))
        return FALSE;
    }
  else
    {
      src_repo = g_object_ref (dst_repo);
    }

  src_refs = g_ptr_array_new_with_free_func (g_free);
  if (opt_src_ref)
    {
      g_assert (n_dst_refs == 1);
      g_ptr_array_add (src_refs, g_strdup (opt_src_ref));
    }
  else
    {
      g_assert (opt_src_repo != NULL);
      if (n_dst_refs == 0)
        {
          g_autofree const char **keys = NULL;
          g_autoptr(GHashTable) all_src_refs = NULL;

          if (!ostree_repo_list_refs (src_repo, NULL, &all_src_refs,
                                      cancellable, error))
            return FALSE;

          keys = (const char **) g_hash_table_get_keys_as_array (all_src_refs, NULL);

          for (i = 0; keys[i] != NULL; i++)
            {
              if (g_str_has_prefix (keys[i], "runtime/") ||
                  g_str_has_prefix (keys[i], "app/"))
                g_ptr_array_add (src_refs, g_strdup (keys[i]));
            }
          n_dst_refs = src_refs->len;
          dst_refs = (const char **) src_refs->pdata;
        }
      else
        {
          for (i = 0; i < n_dst_refs; i++)
            g_ptr_array_add (src_refs, g_strdup (dst_refs[i]));
        }
    }

  src_collection_id = ostree_repo_get_collection_id (src_repo);
  resolved_src_refs = g_ptr_array_new_with_free_func (g_free);
  for (i = 0; i < src_refs->len; i++)
    {
      const char *src_ref = g_ptr_array_index (src_refs, i);
      char *resolved_ref;

      if (!flatpak_repo_resolve_rev (src_repo, src_collection_id, NULL, src_ref, FALSE,
                                     &resolved_ref, cancellable, error))
        return FALSE;

      g_ptr_array_add (resolved_src_refs, resolved_ref);
    }

  if (src_repo_uri != NULL)
    {
      OstreeRepoPullFlags pullflags = 0;
      GVariantBuilder builder;
      g_autoptr(OstreeAsyncProgressFinish) progress = NULL;
      g_auto(GLnxConsoleRef) console = { 0, };
      g_autoptr(GVariant) pull_options = NULL;
      gboolean res;

      if (opt_untrusted)
        pullflags |= OSTREE_REPO_PULL_FLAGS_UNTRUSTED;

      glnx_console_lock (&console);
      if (console.is_tty)
        progress = ostree_async_progress_new_and_connect (ostree_repo_pull_default_console_progress_changed, &console);

      g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sv}"));
      g_variant_builder_add (&builder, "{s@v}", "flags",
                             g_variant_new_variant (g_variant_new_int32 (pullflags)));
      g_variant_builder_add (&builder, "{s@v}", "refs",
                             g_variant_new_variant (g_variant_new_strv ((const char * const *) resolved_src_refs->pdata,
                                                                        resolved_src_refs->len)));
      g_variant_builder_add (&builder, "{s@v}", "depth",
                             g_variant_new_variant (g_variant_new_int32 (0)));

      pull_options = g_variant_ref_sink (g_variant_builder_end (&builder));
      res = ostree_repo_pull_with_options (dst_repo, src_repo_uri,
                                           pull_options,
                                           progress,
                                           cancellable, error);

      if (!res)
        return FALSE;
    }

  /* By now we have the commit with commit_id==resolved_ref and dependencies in dst_repo. We now create a new
   * commit based on the toplevel tree ref from that commit.
   * This is equivalent to:
   *   ostree commit --skip-if-unchanged --repo=${destrepo} --tree=ref=${resolved_ref}
   */

  transaction = flatpak_repo_transaction_start (dst_repo, cancellable, error);
  if (transaction == NULL)
    return FALSE;

  for (i = 0; i < resolved_src_refs->len; i++)
    {
      const char *dst_ref = dst_refs[i];
      const char *resolved_ref = g_ptr_array_index (resolved_src_refs, i);
      g_autofree char *dst_parent = NULL;
      g_autoptr(GFile) dst_parent_root = NULL;
      g_autoptr(GFile) src_ref_root = NULL;
      g_autoptr(GVariant) src_commitv = NULL;
      g_autoptr(GVariant) dst_commitv = NULL;
      g_autoptr(GVariant) subsets_v = NULL;
      g_autoptr(OstreeMutableTree) mtree = NULL;
      g_autoptr(GFile) dst_root = NULL;
      g_autoptr(GVariant) commitv_metadata = NULL;
      g_autoptr(GVariant) metadata = NULL;
      const char *subject;
      const char *body;
      g_autofree char *commit_checksum = NULL;
      GVariantBuilder metadata_builder;
      gint j;
      const char *dst_collection_id = NULL;
      const char *main_collection_id = NULL;
      g_autoptr(GPtrArray) collection_ids = NULL;

      dst_collection_id = ostree_repo_get_collection_id (dst_repo);

      if (!flatpak_repo_resolve_rev (dst_repo, dst_collection_id, NULL, dst_ref, TRUE,
                                     &dst_parent, cancellable, error))
        return FALSE;

      if (dst_parent != NULL &&
          !ostree_repo_read_commit (dst_repo, dst_parent, &dst_parent_root, NULL, cancellable, error))
        return FALSE;

      if (!ostree_repo_read_commit (dst_repo, resolved_ref, &src_ref_root, NULL, cancellable, error))
        return FALSE;

      if (!ostree_repo_load_commit (dst_repo, resolved_ref, &src_commitv, &src_commit_state, error))
        return FALSE;

      if (src_commit_state & OSTREE_REPO_COMMIT_STATE_PARTIAL)
        return flatpak_fail (error, _("Can't commit from partial source commit"));

      /* Don't create a new commit if this is the same tree */
      if (!opt_force && dst_parent_root != NULL && g_file_equal (dst_parent_root, src_ref_root))
        {
          g_print (_("%s: no change\n"), dst_ref);
          continue;
        }

      mtree = ostree_mutable_tree_new ();
      if (!ostree_repo_write_directory_to_mtree (dst_repo, src_ref_root, mtree, NULL,
                                                 cancellable, error))
        return FALSE;

      if (!ostree_repo_write_mtree (dst_repo, mtree, &dst_root, cancellable, error))
        return FALSE;

      commitv_metadata = g_variant_get_child_value (src_commitv, 0);

      g_variant_get_child (src_commitv, 3, "&s", &subject);
      if (opt_subject)
        subject = (const char *) opt_subject;
      g_variant_get_child (src_commitv, 4, "&s", &body);
      if (opt_body)
        body = (const char *) opt_body;

      collection_ids = g_ptr_array_new_with_free_func (g_free);
      if (dst_collection_id)
        {
          main_collection_id = dst_collection_id;
          g_ptr_array_add (collection_ids, g_strdup (dst_collection_id));
        }

      if (opt_extra_collection_ids != NULL)
        {
          for (j = 0; opt_extra_collection_ids[j] != NULL; j++)
            {
              const char *cid = opt_extra_collection_ids[j];
              if (main_collection_id == NULL)
                main_collection_id = cid; /* Fall back to first arg */

              if (g_strcmp0 (cid, dst_collection_id) != 0)
                g_ptr_array_add (collection_ids, g_strdup (cid));
            }
        }

      g_ptr_array_sort (collection_ids, (GCompareFunc) flatpak_strcmp0_ptr);

      /* Copy old metadata */
      g_variant_builder_init (&metadata_builder, G_VARIANT_TYPE ("a{sv}"));

      /* Bindings. xa.ref is deprecated but added anyway for backwards compatibility. */
      g_variant_builder_add (&metadata_builder, "{sv}", "ostree.collection-binding",
                             g_variant_new_string (main_collection_id ? main_collection_id : ""));
      if (collection_ids->len > 0)
        {
          g_autoptr(GVariantBuilder) cr_builder = g_variant_builder_new (G_VARIANT_TYPE ("a(ss)"));

          for (j = 0; j < collection_ids->len; j++)
            g_variant_builder_add (cr_builder, "(ss)", g_ptr_array_index (collection_ids, j), dst_ref);

          g_variant_builder_add (&metadata_builder, "{sv}", "ostree.collection-refs-binding",
                                 g_variant_builder_end (cr_builder));
        }
      g_variant_builder_add (&metadata_builder, "{sv}", "ostree.ref-binding",
                             g_variant_new_strv (&dst_ref, 1));
      g_variant_builder_add (&metadata_builder, "{sv}", "xa.ref", g_variant_new_string (dst_ref));

      /* Record the source commit. This is nice to have, but it also
         means the commit-from gets a different commit id, which
         avoids problems with e.g.  sharing .commitmeta files
         (signatures) */
      g_variant_builder_add (&metadata_builder, "{sv}", "xa.from_commit", g_variant_new_string (resolved_ref));

      if (opt_src_repo)
        {
          guint64 download_size;
          if (!flatpak_repo_collect_sizes (dst_repo, src_ref_root, NULL, &download_size,
                                           cancellable, error))
            {
              return FALSE;
            }
          g_variant_builder_add (&metadata_builder, "{sv}", "xa.download-size", g_variant_new_uint64 (GUINT64_TO_BE (download_size)));
        }

      for (j = 0; j < g_variant_n_children (commitv_metadata); j++)
        {
          g_autoptr(GVariant) child = g_variant_get_child_value (commitv_metadata, j);
          g_autoptr(GVariant) keyv = g_variant_get_child_value (child, 0);
          const char *key = g_variant_get_string (keyv, NULL);

          if (strcmp (key, "xa.ref") == 0 ||
              strcmp (key, "xa.from_commit") == 0 ||
              strcmp (key, "ostree.collection-binding") == 0 ||
              strcmp (key, "ostree.collection-refs-binding") == 0 ||
              strcmp (key, "ostree.ref-binding") == 0)
            continue;

          if (opt_src_repo && strcmp (key, "xa.download-size") == 0)
            continue;

          if (opt_endoflife &&
              strcmp (key, OSTREE_COMMIT_META_KEY_ENDOFLIFE) == 0)
            continue;

          if (opt_endoflife_rebase &&
              strcmp (key, OSTREE_COMMIT_META_KEY_ENDOFLIFE_REBASE) == 0)
            continue;

          if (opt_token_type >= 0 && strcmp (key, "xa.token-type") == 0)
            continue;

          if (opt_subsets != NULL && strcmp (key, "xa.subsets") == 0)
            continue;

          g_variant_builder_add_value (&metadata_builder, child);
        }

      if (opt_endoflife && *opt_endoflife)
        g_variant_builder_add (&metadata_builder, "{sv}", OSTREE_COMMIT_META_KEY_ENDOFLIFE,
                               g_variant_new_string (opt_endoflife));

      if (opt_endoflife_rebase)
        {
          g_auto(GStrv) dst_ref_parts = g_strsplit (dst_ref, "/", 0);

          for (j = 0; opt_endoflife_rebase[j] != NULL; j++)
            {
              const char *old_prefix = opt_endoflife_rebase[j];

              if (flatpak_has_name_prefix (dst_ref_parts[1], old_prefix))
                {
                  g_autofree char *new_id = g_strconcat (opt_endoflife_rebase_new[j], dst_ref_parts[1] + strlen(old_prefix), NULL);
                  g_autofree char *rebased_ref = g_build_filename (dst_ref_parts[0], new_id, dst_ref_parts[2], dst_ref_parts[3], NULL);

                  g_variant_builder_add (&metadata_builder, "{sv}", OSTREE_COMMIT_META_KEY_ENDOFLIFE_REBASE,
                                         g_variant_new_string (rebased_ref));
                  break;
                }
            }
        }

      if (opt_token_type >= 0)
        g_variant_builder_add (&metadata_builder, "{sv}", "xa.token-type",
                               g_variant_new_int32 (GINT32_TO_LE (opt_token_type)));

      /* Skip "" subsets as they mean everything. This way --subsets= causes old subsets to be stripped from the original commit */
      if (get_subsets (opt_subsets, &subsets_v))
        g_variant_builder_add (&metadata_builder, "{sv}", "xa.subsets", subsets_v);

      timestamp = ostree_commit_get_timestamp (src_commitv);
      if (opt_timestamp)
        timestamp = ts.tv_sec;

      metadata = g_variant_ref_sink (g_variant_builder_end (&metadata_builder));
      if (!ostree_repo_write_commit_with_time (dst_repo, dst_parent, subject, body, metadata,
                                               OSTREE_REPO_FILE (dst_root),
                                               timestamp,
                                               &commit_checksum, cancellable, error))
        return FALSE;

      g_print ("%s: %s\n", dst_ref, commit_checksum);

      if (!ostree_repo_load_commit (dst_repo, commit_checksum, &dst_commitv, NULL, error))
        return FALSE;

      /* This doesn't copy the detached metadata. I'm not sure if this is a problem.
       * The main thing there is commit signatures, and we can't copy those, as the commit hash changes.
       */

      if (opt_gpg_key_ids)
        {
          char **iter;

          for (iter = opt_gpg_key_ids; iter && *iter; iter++)
            {
              const char *keyid = *iter;
              g_autoptr(GError) my_error = NULL;

              if (!ostree_repo_sign_commit (dst_repo,
                                            commit_checksum,
                                            keyid,
                                            opt_gpg_homedir,
                                            cancellable,
                                            &my_error) &&
                  !g_error_matches (my_error, G_IO_ERROR, G_IO_ERROR_EXISTS))
                {
                  g_propagate_error (error, g_steal_pointer (&my_error));
                  return FALSE;
                }
            }
        }

      if (dst_collection_id != NULL)
        {
          OstreeCollectionRef ref = { (char *) dst_collection_id, (char *) dst_ref };
          ostree_repo_transaction_set_collection_ref (dst_repo, &ref, commit_checksum);
        }
      else
        {
          ostree_repo_transaction_set_ref (dst_repo, NULL, dst_ref, commit_checksum);
        }

      if (opt_extra_collection_ids)
        {
          for (j = 0; opt_extra_collection_ids[j] != NULL; j++)
            {
              OstreeCollectionRef ref = { (char *) opt_extra_collection_ids[j], (char *) dst_ref };
              ostree_repo_transaction_set_collection_ref (dst_repo, &ref, commit_checksum);
            }
        }

      /* Copy + Rewrite any deltas */
      {
        const char *from[2];
        gsize n_from = 0;

        if (dst_parent != NULL)
          from[n_from++] = dst_parent;
        from[n_from++] = NULL;

        for (j = 0; j < n_from; j++)
          {
            g_autoptr(GError) local_error = NULL;
            if (!rewrite_delta (src_repo, resolved_ref, dst_repo, commit_checksum, dst_commitv, from[j], &local_error))
              g_info ("Failed to copy delta: %s", local_error->message);
          }
      }
    }

  if (!ostree_repo_commit_transaction (dst_repo, NULL, cancellable, error))
    return FALSE;

  if (opt_update_appstream &&
      !flatpak_repo_generate_appstream (dst_repo, (const char **) opt_gpg_key_ids, opt_gpg_homedir, 0, cancellable, error))
    return FALSE;

  if (!opt_no_update_summary)
    {
      FlatpakRepoUpdateFlags flags = FLATPAK_REPO_UPDATE_FLAG_NONE;

      if (opt_no_summary_index)
        flags |= FLATPAK_REPO_UPDATE_FLAG_DISABLE_INDEX;

      g_info ("Updating summary");
      if (!flatpak_repo_update (dst_repo, flags,
                                (const char **) opt_gpg_key_ids,
                                opt_gpg_homedir,
                                cancellable,
                                error))
        return FALSE;
    }

  return TRUE;
}

gboolean
flatpak_complete_build_commit_from (FlatpakCompletion *completion)
{
  g_autoptr(GOptionContext) context = NULL;
  g_autoptr(GFile) dst_repofile = NULL;
  g_autoptr(OstreeRepo) dst_repo = NULL;
  g_autoptr(GFile) src_repofile = NULL;
  g_autoptr(OstreeRepo) src_repo = NULL;

  context = g_option_context_new ("");

  if (!flatpak_option_context_parse (context, options, &completion->argc, &completion->argv,
                                     FLATPAK_BUILTIN_FLAG_NO_DIR, NULL, NULL, NULL))
    return FALSE;

  switch (completion->argc)
    {
    case 0:
    case 1: /* DST-REPO */
      flatpak_complete_options (completion, global_entries);
      flatpak_complete_options (completion, options);

      flatpak_complete_dir (completion);
      break;

    case 2: /* DST-REF */
      dst_repofile = g_file_new_for_commandline_arg (completion->argv[1]);
      dst_repo = ostree_repo_new (dst_repofile);
      if (ostree_repo_open (dst_repo, NULL, NULL))
        flatpak_complete_ref (completion, dst_repo);

      if (opt_src_repo)
        {
          src_repofile = g_file_new_for_commandline_arg (opt_src_repo);
          src_repo = ostree_repo_new (src_repofile);
          if (ostree_repo_open (src_repo, NULL, NULL))
            flatpak_complete_ref (completion, src_repo);
        }

      break;
    }

  return TRUE;
}

===== ./app/flatpak-builtins-remote-add.c =====
/* vi:set et sw=2 sts=2 cin cino=t0,f0,(0,{s,>2s,n-s,^-s,e-s:
 * Copyright © 2014 Red Hat, Inc
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Alexander Larsson <alexl@redhat.com>
 */

#include "config.h"

#include <locale.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

#include <glib/gi18n.h>

#include "libglnx.h"

#include "flatpak-builtins.h"
#include "flatpak-builtins-utils.h"
#include "flatpak-repo-utils-private.h"
#include "flatpak-utils-http-private.h"
#include "flatpak-utils-private.h"

static gboolean opt_no_gpg_verify;
static gboolean opt_do_gpg_verify;
static gboolean opt_do_enumerate;
static gboolean opt_no_enumerate;
static gboolean opt_do_deps;
static gboolean opt_no_deps;
static gboolean opt_if_not_exists;
static gboolean opt_disable;
static int opt_prio = -1;
static char *opt_filter;
static char *opt_title;
static char *opt_comment;
static char *opt_description;
static char *opt_homepage;
static char *opt_icon;
static char *opt_subset;
static char *opt_default_branch;
static char *opt_url;
static char *opt_collection_id = NULL;
static gboolean opt_from;
static char **opt_gpg_import;
static char *opt_signature_lookaside = NULL;
static char *opt_authenticator_name = NULL;
static char **opt_authenticator_options = NULL;
static gboolean opt_authenticator_install = -1;
static gboolean opt_no_follow_redirect;

static GOptionEntry add_options[] = {
  { "if-not-exists", 0, 0, G_OPTION_ARG_NONE, &opt_if_not_exists, N_("Do nothing if the provided remote exists"), NULL },
  { "from", 0, 0, G_OPTION_ARG_NONE, &opt_from, N_("LOCATION specifies a configuration file, not the repo location"), NULL },
  { NULL }
};

static GOptionEntry common_options[] = {
  { "no-gpg-verify", 0, 0, G_OPTION_ARG_NONE, &opt_no_gpg_verify, N_("Disable GPG verification"), NULL },
  { "no-enumerate", 0, 0, G_OPTION_ARG_NONE, &opt_no_enumerate, N_("Mark the remote as don't enumerate"), NULL },
  { "no-use-for-deps", 0, 0, G_OPTION_ARG_NONE, &opt_no_deps, N_("Mark the remote as don't use for deps"), NULL },
  { "prio", 0, 0, G_OPTION_ARG_INT, &opt_prio, N_("Set priority (default 1, higher is more prioritized)"), N_("PRIORITY") },
  { "subset", 0, 0, G_OPTION_ARG_STRING, &opt_subset, N_("The named subset to use for this remote"), N_("SUBSET") },
  { "title", 0, 0, G_OPTION_ARG_STRING, &opt_title, N_("A nice name to use for this remote"), N_("TITLE") },
  { "comment", 0, 0, G_OPTION_ARG_STRING, &opt_comment, N_("A one-line comment for this remote"), N_("COMMENT") },
  { "description", 0, 0, G_OPTION_ARG_STRING, &opt_description, N_("A full-paragraph description for this remote"), N_("DESCRIPTION") },
  { "homepage", 0, 0, G_OPTION_ARG_STRING, &opt_homepage, N_("URL for a website for this remote"), N_("URL") },
  { "icon", 0, 0, G_OPTION_ARG_STRING, &opt_icon, N_("URL for an icon for this remote"), N_("URL") },
  { "default-branch", 0, 0, G_OPTION_ARG_STRING, &opt_default_branch, N_("Default branch to use for this remote"), N_("BRANCH") },
  { "collection-id", 0, 0, G_OPTION_ARG_STRING, &opt_collection_id, N_("Collection ID"), N_("COLLECTION-ID") },
  { "gpg-import", 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &opt_gpg_import, N_("Import GPG key from FILE (- for stdin)"), N_("FILE") },
  { "signature-lookaside", 0, 0, G_OPTION_ARG_STRING, &opt_signature_lookaside, N_("Load signatures from URL"), N_("URL") },
  { "filter", 0, 0, G_OPTION_ARG_FILENAME, &opt_filter, N_("Set path to local filter FILE"), N_("FILE") },
  { "disable", 0, 0, G_OPTION_ARG_NONE, &opt_disable, N_("Disable the remote"), NULL },
  { "authenticator-name", 0, 0, G_OPTION_ARG_STRING, &opt_authenticator_name, N_("Name of authenticator"), N_("NAME") },
  { "authenticator-option", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_authenticator_options, N_("Authenticator option"), N_("KEY=VALUE") },
  { "authenticator-install", 0, 0, G_OPTION_ARG_NONE, &opt_authenticator_install, N_("Autoinstall authenticator"), NULL },
  { "no-authenticator-install", 0, G_OPTION_FLAG_REVERSE, G_OPTION_ARG_NONE, &opt_authenticator_install, N_("Don't autoinstall authenticator"), NULL },
  { "no-follow_redirect", 0, G_OPTION_FLAG_REVERSE, G_OPTION_ARG_NONE, &opt_no_follow_redirect, N_("Don't follow the redirect set in the summary file"), NULL },
  { NULL }
};


static gboolean
get_config_from_opts (GKeyFile *config,
                      const char *remote_name,
                      GBytes    **gpg_data,
                      GError    **error)
{
  g_autofree char *group = g_strdup_printf ("remote \"%s\"", remote_name);

  if (opt_no_gpg_verify)
    {
      g_key_file_set_boolean (config, group, "gpg-verify", FALSE);
      g_key_file_set_boolean (config, group, "gpg-verify-summary", FALSE);
    }

  if (opt_do_gpg_verify)
    {
      g_key_file_set_boolean (config, group, "gpg-verify", TRUE);
      g_key_file_set_boolean (config, group, "gpg-verify-summary", TRUE);
    }

  if (opt_url)
    {
      if (g_str_has_prefix (opt_url, "metalink="))
        g_key_file_set_string (config, group, "metalink", opt_url + strlen ("metalink="));
      else
        g_key_file_set_string (config, group, "url", opt_url);
    }

  if (opt_collection_id)
    g_key_file_set_string (config, group, "collection-id", opt_collection_id);

  if (opt_subset)
    {
      g_key_file_set_string (config, group, "xa.subset", opt_subset);
      g_key_file_set_boolean (config, group, "xa.subset-is-set", TRUE);
    }

  if (opt_title)
    {
      g_key_file_set_string (config, group, "xa.title", opt_title);
      g_key_file_set_boolean (config, group, "xa.title-is-set", TRUE);
    }

  if (opt_comment)
    {
      g_key_file_set_string (config, group, "xa.comment", opt_comment);
      g_key_file_set_boolean (config, group, "xa.comment-is-set", TRUE);
    }

  if (opt_description)
    {
      g_key_file_set_string (config, group, "xa.description", opt_description);
      g_key_file_set_boolean (config, group, "xa.description-is-set", TRUE);
    }

  if (opt_homepage)
    {
      g_key_file_set_string (config, group, "xa.homepage", opt_homepage);
      g_key_file_set_boolean (config, group, "xa.homepage-is-set", TRUE);
    }

  if (opt_icon)
    {
      g_key_file_set_string (config, group, "xa.icon", opt_icon);
      g_key_file_set_boolean (config, group, "xa.icon-is-set", TRUE);
    }

  if (opt_default_branch)
    {
      g_key_file_set_string (config, group, "xa.default-branch", opt_default_branch);
      g_key_file_set_boolean (config, group, "xa.default-branch-is-set", TRUE);
    }

  if (opt_filter)
    g_key_file_set_string (config, group, "xa.filter", opt_filter);

  if (opt_no_enumerate)
    g_key_file_set_boolean (config, group, "xa.noenumerate", TRUE);

  if (opt_do_enumerate)
    g_key_file_set_boolean (config, group, "xa.noenumerate", FALSE);

  if (opt_no_deps)
    g_key_file_set_boolean (config, group, "xa.nodeps", TRUE);

  if (opt_do_deps)
    g_key_file_set_boolean (config, group, "xa.nodeps", FALSE);

  if (opt_disable)
    g_key_file_set_boolean (config, group, "xa.disable", TRUE);

  if (opt_prio != -1)
    {
      g_autofree char *prio_as_string = g_strdup_printf ("%d", opt_prio);
      g_key_file_set_string (config, group, "xa.prio", prio_as_string);
    }

  if (opt_gpg_import != NULL)
    {
      g_clear_pointer (gpg_data, g_bytes_unref); /* Free if set from flatpakrepo file */
      *gpg_data = flatpak_load_gpg_keys (opt_gpg_import, NULL, error);
      if (*gpg_data == NULL)
        return FALSE;
    }

  if (opt_signature_lookaside)
    g_key_file_set_string (config, group, "xa.signature-lookaside", opt_signature_lookaside);

  if (opt_authenticator_name)
    {
      g_key_file_set_string (config, group, "xa.authenticator-name", opt_authenticator_name);
      g_key_file_set_boolean (config, group, "xa.authenticator-name-is-set", TRUE);
    }

  if (opt_authenticator_install != -1)
    {
      g_key_file_set_boolean (config, group, "xa.authenticator-install", opt_authenticator_install);
      g_key_file_set_boolean (config, group, "xa.authenticator-install-is-set", TRUE);
    }

  if (opt_authenticator_options)
    {
      for (int i = 0; opt_authenticator_options[i] != NULL; i++)
        {
          g_auto(GStrv) split = g_strsplit (opt_authenticator_options[i], "=", 2);
          g_autofree char *key = g_strdup_printf ("xa.authenticator-options.%s", split[0]);

          if (split[0] == NULL || split[1] == NULL || *split[1] == 0)
            g_key_file_remove_key (config, group, key, NULL);
          else
            g_key_file_set_string (config, group, key, split[1]);
        }
    }

  if (opt_no_follow_redirect)
    g_key_file_set_boolean (config, group, "url-is-set", TRUE);

  return TRUE;
}

static GKeyFile *
load_options (const char *remote_name,
              const char *filename,
              GBytes    **gpg_data,
              GError    **error)
{
  g_autoptr(GError) local_error = NULL;
  g_autoptr(GKeyFile) keyfile = g_key_file_new ();
  g_autoptr(GKeyFile) config = NULL;
  g_autoptr(GBytes) bytes = NULL;

  if (g_str_has_prefix (filename, "http:") ||
      g_str_has_prefix (filename, "https:") ||
      g_str_has_prefix (filename, "file:"))
    {
      const char *options_data;
      gsize options_size;
      g_autoptr(FlatpakHttpSession) http_session = NULL;

      http_session = flatpak_create_http_session (PACKAGE_STRING);
      bytes = flatpak_load_uri (http_session, filename, 0, NULL, NULL, NULL, NULL, NULL, &local_error);

      if (bytes == NULL)
        {
          flatpak_fail (error, _("Can't load uri %s: %s\n"), filename, local_error->message);
          return NULL;
        }

      options_data = g_bytes_get_data (bytes, &options_size);
      if (!g_key_file_load_from_data (keyfile, options_data, options_size, 0, &local_error))
        {
          flatpak_fail (error, _("Can't load uri %s: %s\n"), filename, local_error->message);
          return NULL;
        }
    }
  else
    {
      if (!g_key_file_load_from_file (keyfile, filename, 0, &local_error))
        {
          flatpak_fail (error, _("Can't load file %s: %s\n"), filename, local_error->message);
          return NULL;
        }
    }

  config = flatpak_parse_repofile (remote_name, FALSE, keyfile, gpg_data, NULL, error);
  if (config == NULL)
    return NULL;

  return g_steal_pointer (&config);
}

gboolean
flatpak_builtin_remote_add (int argc, char **argv,
                            GCancellable *cancellable, GError **error)
{
  g_autoptr(GOptionContext) context = NULL;
  g_autoptr(GPtrArray) dirs = NULL;
  FlatpakDir *dir;
  g_autoptr(GFile) file = NULL;
  g_auto(GStrv) remotes = NULL;
  g_autofree char *remote_url = NULL;
  const char *remote_name;
  const char *location = NULL;
  g_autoptr(GKeyFile) config = NULL;
  g_autoptr(GBytes) gpg_data = NULL;
  g_autoptr(GError) local_error = NULL;

  context = g_option_context_new (_("NAME LOCATION - Add a remote repository"));
  g_option_context_set_translation_domain (context, GETTEXT_PACKAGE);

  g_option_context_add_main_entries (context, common_options, NULL);

  if (!flatpak_option_context_parse (context, add_options, &argc, &argv,
                                     FLATPAK_BUILTIN_FLAG_ONE_DIR,
                                     &dirs, cancellable, error))
    return FALSE;

  dir = g_ptr_array_index (dirs, 0);

  if (argc < 2)
    return usage_error (context, _("NAME must be specified"), error);

  if (argc < 3)
    return usage_error (context, _("LOCATION must be specified"), error);

  if (argc > 3)
    return usage_error (context, _("Too many arguments"), error);

  if (opt_collection_id != NULL &&
      !ostree_validate_collection_id (opt_collection_id, &local_error))
    return flatpak_fail (error, _("‘%s’ is not a valid collection ID: %s"), opt_collection_id, local_error->message);

  if (opt_collection_id != NULL &&
      (opt_no_gpg_verify || opt_gpg_import == NULL || opt_gpg_import[0] == NULL))
    return flatpak_fail (error, _("GPG verification is required if collections are enabled"));

  remote_name = argv[1];
  location = argv[2];

  if (opt_from ||
      flatpak_file_arg_has_suffix (location, ".flatpakrepo"))
    {
      config = load_options (remote_name, location, &gpg_data, error);
      if (config == NULL)
        return FALSE;
    }
  else
    {
      gboolean is_oci;

      config = g_key_file_new ();
      file = g_file_new_for_commandline_arg (location);
      if (g_file_is_native (file))
        remote_url = g_file_get_uri (file);
      else
        remote_url = g_strdup (location);
      opt_url = remote_url;

      /* Default to gpg verify, except for OCI registries */
      is_oci = opt_url && g_str_has_prefix (opt_url, "oci+");
      if (!opt_no_gpg_verify && !is_oci)
        opt_do_gpg_verify = TRUE;
    }

  if (!get_config_from_opts (config, remote_name, &gpg_data, error))
    return FALSE;

  remotes = flatpak_dir_list_remotes (dir, cancellable, error);
  if (remotes == NULL)
    return FALSE;

  if (g_strv_contains ((const char **) remotes, remote_name))
    {
      if (opt_if_not_exists)
        {
          /* Do nothing */

          /* Except, for historical reasons this applies/clears the filter of pre-existing
             remotes, so that a default-shipped filtering remote can be replaced, clearing the
             filter, by following  standard docs. */
          g_autofree char *group = g_strdup_printf ("remote \"%s\"", remote_name);
          g_autofree char *new_filter = g_key_file_get_string (config, group, "xa.filter", NULL);

          if (!flatpak_dir_compare_remote_filter (dir, remote_name, new_filter))
            {
              g_autoptr(GKeyFile) new_config = ostree_repo_copy_config (flatpak_dir_get_repo (dir));

              g_key_file_set_string (new_config, group, "xa.filter", new_filter ? new_filter : "");

              if (!flatpak_dir_modify_remote (dir, remote_name, new_config, NULL, cancellable, error))
                return FALSE;
            }

          return TRUE;
        }

      return flatpak_fail (error, _("Remote %s already exists"), remote_name);
    }

  if (opt_gpg_import != NULL)
    {
      g_clear_pointer (&gpg_data, g_bytes_unref);
      gpg_data = flatpak_load_gpg_keys (opt_gpg_import, cancellable, error);
      if (gpg_data == NULL)
        return FALSE;
    }

  if (opt_authenticator_name && !g_dbus_is_name (opt_authenticator_name))
    return flatpak_fail (error, _("Invalid authenticator name %s"), opt_authenticator_name);

  if (!flatpak_dir_modify_remote (dir, remote_name, config, gpg_data, cancellable, error))
    return FALSE;

  /* Reload previously changed configuration */
  if (!flatpak_dir_recreate_repo (dir, cancellable, error))
    return FALSE;

  /* We can't retrieve the extra metadata until the remote has been added locally, since
     ostree_repo_remote_fetch_summary() works with the repository's name, not its URL.
     Don't propagate IO failed errors here because we might just be offline - the
     remote should already be usable. */
  if (!flatpak_dir_update_remote_configuration (dir, remote_name, NULL, NULL, cancellable, &local_error))
    {
      if (local_error->domain == G_RESOLVER_ERROR || local_error->domain == G_IO_ERROR)
        {
          g_printerr (_("Warning: Could not update extra metadata for '%s': %s\n"), remote_name, local_error->message);
        }
      else
        {
          g_propagate_error (error, g_steal_pointer (&local_error));
          return FALSE;
        }
    }

  return TRUE;
}

gboolean
flatpak_complete_remote_add (FlatpakCompletion *completion)
{
  g_autoptr(GOptionContext) context = NULL;

  context = g_option_context_new ("");
  g_option_context_add_main_entries (context, common_options, NULL);
  if (!flatpak_option_context_parse (context, add_options, &completion->argc, &completion->argv,
                                     FLATPAK_BUILTIN_FLAG_ONE_DIR | FLATPAK_BUILTIN_FLAG_OPTIONAL_REPO,
                                     NULL, NULL, NULL))
    return FALSE;

  switch (completion->argc)
    {
    case 0:
    case 1:
      flatpak_complete_options (completion, global_entries);
      flatpak_complete_options (completion, common_options);
      flatpak_complete_options (completion, add_options);
      flatpak_complete_options (completion, user_entries);

      break;
    }

  return TRUE;
}

===== ./app/flatpak-tty-utils.c =====
/* vi:set et sw=2 sts=2 cin cino=t0,f0,(0,{s,>2s,n-s,^-s,e-s:
 * Copyright © 1995-1998 Free Software Foundation, Inc.
 * Copyright © 2014-2019 Red Hat, Inc
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Alexander Larsson <alexl@redhat.com>
 */

#include "config.h"
#include "flatpak-tty-utils-private.h"

#include <sys/ioctl.h>
#include <termios.h>
#include <unistd.h>

#include <glib/gi18n-lib.h>

static int fancy_output = -1;

void
flatpak_disable_fancy_output (void)
{
  fancy_output = FALSE;
}

void
flatpak_enable_fancy_output (void)
{
  fancy_output = TRUE;
}

gboolean
flatpak_fancy_output (void)
{
  static gsize fancy_output_once = 0;
  enum {
    PLAIN_OUTPUT = 1,
    FANCY_OUTPUT = 2
  };

  if (fancy_output != -1)
    return fancy_output;

  if (g_once_init_enter (&fancy_output_once))
    {
      if (g_strcmp0 (g_getenv ("FLATPAK_FANCY_OUTPUT"), "0") == 0)
        g_once_init_leave (&fancy_output_once, PLAIN_OUTPUT);
      else if (getenv ("G_MESSAGES_DEBUG"))
        g_once_init_leave (&fancy_output_once, PLAIN_OUTPUT);
      else if (!isatty (STDOUT_FILENO))
        g_once_init_leave (&fancy_output_once, PLAIN_OUTPUT);
      else
        g_once_init_leave (&fancy_output_once, FANCY_OUTPUT);
    }

  return fancy_output_once == FANCY_OUTPUT;
}

gboolean
flatpak_allow_fuzzy_matching (const char *term)
{
  if (strchr (term, '/') != NULL || strchr (term, '.') != NULL)
    return FALSE;

  /* This env var is used by the unit tests and only skips the tty test not the
   * check above.
   */
  if (g_strcmp0 (g_getenv ("FLATPAK_FORCE_ALLOW_FUZZY_MATCHING"), "1") == 0)
    return TRUE;

  if (!isatty (STDIN_FILENO) || !isatty (STDOUT_FILENO))
    return FALSE;

  return TRUE;
}

char *
flatpak_prompt (gboolean allow_empty,
                const char *prompt, ...)
{
  char buf[512];
  va_list var_args;
  g_autofree char *s = NULL;


  va_start (var_args, prompt);
  s = g_strdup_vprintf (prompt, var_args);
  va_end (var_args);

  while (TRUE)
    {
      g_print ("%s: ", s);

      if (!isatty (STDIN_FILENO) || !isatty (STDOUT_FILENO))
        {
          g_print ("n\n");
          return NULL;
        }

      if (fgets (buf, sizeof (buf), stdin) == NULL)
        return NULL;

      g_strstrip (buf);

      if (buf[0] != 0 || allow_empty)
        return g_strdup (buf);
    }
}

char *
flatpak_password_prompt (const char *prompt, ...)
{
  char buf[512];
  va_list var_args;
  g_autofree char *s = NULL;
  gboolean was_echo;


  va_start (var_args, prompt);
  s = g_strdup_vprintf (prompt, var_args);
  va_end (var_args);

  while (TRUE)
    {
      g_print ("%s: ", s);

      if (!isatty (STDIN_FILENO) || !isatty (STDOUT_FILENO))
        return NULL;

      was_echo = flatpak_set_tty_echo (FALSE);

      if (fgets (buf, sizeof (buf), stdin) == NULL)
        return NULL;

      flatpak_set_tty_echo (was_echo);

      g_strstrip (buf);

      /* We stole the return, so manual new line */
      g_print ("\n");
      return g_strdup (buf);
    }
}


gboolean
flatpak_yes_no_prompt (gboolean default_yes, const char *prompt, ...)
{
  char buf[512];
  va_list var_args;
  g_autofree char *s = NULL;


  va_start (var_args, prompt);
  s = g_strdup_vprintf (prompt, var_args);
  va_end (var_args);

  while (TRUE)
    {
      g_print ("%s %s: ", s, default_yes ? "[Y/n]" : "[y/n]");

      if (!isatty (STDIN_FILENO) || !isatty (STDOUT_FILENO))
        {
          g_print ("n\n");
          return FALSE;
        }

      if (fgets (buf, sizeof (buf), stdin) == NULL)
        return FALSE;

      g_strstrip (buf);

      if (default_yes && strlen (buf) == 0)
        return TRUE;

      if (g_ascii_strcasecmp (buf, "y") == 0 ||
          g_ascii_strcasecmp (buf, "yes") == 0)
        return TRUE;

      if (g_ascii_strcasecmp (buf, "n") == 0 ||
          g_ascii_strcasecmp (buf, "no") == 0)
        return FALSE;
    }
}

static gboolean
is_number (const char *s)
{
  if (*s == '\0')
    return FALSE;

  while (*s != 0)
    {
      if (!g_ascii_isdigit (*s))
        return FALSE;
      s++;
    }

  return TRUE;
}

long
flatpak_number_prompt (gboolean default_yes, int min, int max, const char *prompt, ...)
{
  char buf[512];
  va_list var_args;
  g_autofree char *s = NULL;

  va_start (var_args, prompt);
  s = g_strdup_vprintf (prompt, var_args);
  va_end (var_args);

  while (TRUE)
    {
      g_print ("%s [%d-%d]: ", s, min, max);

      if (!isatty (STDIN_FILENO) || !isatty (STDOUT_FILENO))
        {
          g_print ("0\n");
          return 0;
        }

      if (fgets (buf, sizeof (buf), stdin) == NULL)
        return 0;

      g_strstrip (buf);

      if (default_yes && strlen (buf) == 0 &&
          max - min == 1 && min == 0)
        return 1;

      if (is_number (buf))
        {
          long res = strtol (buf, NULL, 10);

          if (res >= min && res <= max)
            return res;
        }
    }
}

static gboolean
parse_range (char *s, int *a, int *b)
{
  char *p;

  p = strchr (s, '-');
  if (!p)
    return FALSE;

  p++;
  p[-1] = '\0';

  if (is_number (s) && is_number (p))
    {
      *a = (int) strtol (s, NULL, 10);
      *b = (int) strtol (p, NULL, 10);
      p[-1] = '-';
      return TRUE;
    }

  p[-1] = '-';
  return FALSE;
}

static void
add_number (GArray *numbers,
            int     num)
{
  int i;

  for (i = 0; i < numbers->len; i++)
    {
      if (g_array_index (numbers, int, i) == num)
        return;
    }

  g_array_append_val (numbers, num);
}

int *
flatpak_parse_numbers (const char *buf,
                       int         min,
                       int         max)
{
  g_autoptr(GArray) numbers = g_array_new (FALSE, FALSE, sizeof (int));
  g_auto(GStrv) parts = g_strsplit_set (buf, " ,", 0);
  int i, j;

  for (i = 0; parts[i]; i++)
    {
      int a, b;

      g_strstrip (parts[i]);

      if (parse_range (parts[i], &a, &b) &&
          min <= a && a <= max &&
          min <= b && b <= max)
        {
          for (j = a; j <= b; j++)
            add_number (numbers, j);
        }
      else if (is_number (parts[i]))
        {
          int res = (int) strtol (parts[i], NULL, 10);
          if (min <= res && res <= max)
            add_number (numbers, res);
          else
            return NULL;
        }
      else
        return NULL;
    }

  j = 0;
  g_array_append_val (numbers, j);

  return (int *) g_array_free (g_steal_pointer (&numbers), FALSE);
}

/* Returns a 0-terminated array of ints. Free with g_free */
int *
flatpak_numbers_prompt (gboolean default_yes, int min, int max, const char *prompt, ...)
{
  char buf[512];
  va_list var_args;
  g_autofree char *s = NULL;
  g_autofree int *choice = g_new0 (int, 2);
  int *numbers;

  va_start (var_args, prompt);
  s = g_strdup_vprintf (prompt, var_args);
  va_end (var_args);

  while (TRUE)
    {
      g_print ("%s [%d-%d]: ", s, min, max);

      if (!isatty (STDIN_FILENO) || !isatty (STDOUT_FILENO))
        {
          g_print ("0\n");
          choice[0] = 0;
          return g_steal_pointer (&choice);
        }

      if (fgets (buf, sizeof (buf), stdin) == NULL)
        {
          choice[0] = 0;
          return g_steal_pointer (&choice);
        }

      g_strstrip (buf);

      if (default_yes && strlen (buf) == 0 &&
          max - min == 1 && min == 0)
        {
          choice[0] = 0;
          return g_steal_pointer (&choice);
        }

      numbers = flatpak_parse_numbers (buf, min, max);
      if (numbers)
        return numbers;
    }
}

void
flatpak_format_choices (const char **choices,
                        const char  *prompt,
                        ...)
{
  va_list var_args;
  g_autofree char *s = NULL;
  int i;

  va_start (var_args, prompt);
  s = g_strdup_vprintf (prompt, var_args);
  va_end (var_args);

  g_print ("%s\n\n", s);
  for (i = 0; choices[i]; i++)
    g_print ("  %2d) %s\n", i + 1, choices[i]);
  g_print ("\n");
}

void
flatpak_get_window_size (int *rows, int *cols)
{
  struct winsize w;

  if (ioctl (STDOUT_FILENO, TIOCGWINSZ, &w) == 0)
    {
      /* For whatever reason, in buildbot this returns 0, 0 so add a fallback */
      if (w.ws_row == 0)
        w.ws_row = 24;
      if (w.ws_col == 0)
        w.ws_col = 80;
      *rows = w.ws_row;
      *cols = w.ws_col;
    }
  else
    {
      *rows = 24;
      *cols = 80;
    }
}

gboolean
flatpak_set_tty_echo (gboolean echo)
{
  struct termios term;
  gboolean was;

  tcgetattr (STDIN_FILENO, &term);
  was = (term.c_lflag & ECHO) != 0;

  if (echo)
    term.c_lflag |= ECHO;
  else
    term.c_lflag &= ~ECHO;
  tcsetattr (STDIN_FILENO, TCSANOW, &term);

  return was;
}

gboolean
flatpak_get_cursor_pos (int * row, int *col)
{
  fd_set readset;
  struct timeval time;
  struct termios term, initial_term;
  int res = 0;

  tcgetattr (STDIN_FILENO, &initial_term);
  term = initial_term;
  term.c_lflag &= ~ICANON;
  term.c_lflag &= ~ECHO;
  tcsetattr (STDIN_FILENO, TCSAFLUSH, &term);

  printf ("\033[6n");
  fflush (stdout);

  FD_ZERO (&readset);
  FD_SET (STDIN_FILENO, &readset);
  time.tv_sec = 0;
  time.tv_usec = 100000;

  if (select (STDIN_FILENO + 1, &readset, NULL, NULL, &time) == 1)
    res = scanf ("\033[%d;%dR", row, col);

  tcsetattr (STDIN_FILENO, TCSAFLUSH, &initial_term);

  return res == 2;
}

void
flatpak_hide_cursor (void)
{
  const size_t flatpak_hide_cursor_len = strlen (FLATPAK_ANSI_HIDE_CURSOR);
  const ssize_t write_ret = write (STDOUT_FILENO, FLATPAK_ANSI_HIDE_CURSOR,
                                   flatpak_hide_cursor_len);

  if (write_ret < 0)
    g_warning ("write() failed: %zd = write(STDOUT_FILENO, FLATPAK_ANSI_HIDE_CURSOR, %zu)",
               write_ret, flatpak_hide_cursor_len);
}

void
flatpak_show_cursor (void)
{
  const size_t flatpak_show_cursor_len = strlen (FLATPAK_ANSI_SHOW_CURSOR);
  const ssize_t write_ret = write (STDOUT_FILENO, FLATPAK_ANSI_SHOW_CURSOR,
                                   flatpak_show_cursor_len);

  if (write_ret < 0)
    g_warning ("write() failed: %zd = write(STDOUT_FILENO, FLATPAK_ANSI_SHOW_CURSOR, %zu)",
               write_ret, flatpak_show_cursor_len);
}

void
flatpak_enable_raw_mode (void)
{
  struct termios raw;

  tcgetattr (STDIN_FILENO, &raw);

  raw.c_lflag &= ~(ECHO | ICANON);

  tcsetattr (STDIN_FILENO, TCSAFLUSH, &raw);
}

void
flatpak_disable_raw_mode (void)
{
  struct termios raw;

  tcgetattr (STDIN_FILENO, &raw);

  raw.c_lflag |= (ECHO | ICANON);

  tcsetattr (STDIN_FILENO, TCSAFLUSH, &raw);
}

void
flatpak_print_escaped_string (const char        *s,
                              FlatpakEscapeFlags flags)
{
  g_autofree char *escaped = flatpak_escape_string (s, flags);
  g_print ("%s", escaped);
}

static gboolean
use_progress_escape_sequence (void)
{
  static gsize tty_progress_once = 0;
  enum {
    TTY_PROGRESS_ENABLED = 1,
    TTY_PROGRESS_DISABLED = 2
  };

  if (g_once_init_enter (&tty_progress_once))
    {
      if (g_strcmp0 (g_getenv ("FLATPAK_TTY_PROGRESS"), "0") == 0)
        g_once_init_leave (&tty_progress_once, TTY_PROGRESS_DISABLED);
      else
        g_once_init_leave (&tty_progress_once, TTY_PROGRESS_ENABLED);
    }

  return tty_progress_once == TTY_PROGRESS_ENABLED;
}

void
flatpak_pty_clear_progress (void)
{
  if (use_progress_escape_sequence ())
    g_print ("\033]9;4;0\e\\");
}

void
flatpak_pty_set_progress (guint percent)
{
  if (use_progress_escape_sequence ())
    g_print ("\033]9;4;1;%d\e\\", MIN (percent, 100));
}

===== ./app/flatpak-builtins-override.c =====
/* vi:set et sw=2 sts=2 cin cino=t0,f0,(0,{s,>2s,n-s,^-s,e-s:
 * Copyright © 2014 Red Hat, Inc
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Alexander Larsson <alexl@redhat.com>
 */

#include "config.h"

#include <locale.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>

#include <glib/gi18n.h>

#include "libglnx.h"

#include "flatpak-builtins.h"
#include "flatpak-utils-private.h"
#include "flatpak-run-private.h"

static gboolean opt_reset;
static gboolean opt_show;

static GOptionEntry options[] = {
  { "reset", 0, 0, G_OPTION_ARG_NONE, &opt_reset, N_("Remove existing overrides"), NULL },
  { "show", 0, 0, G_OPTION_ARG_NONE, &opt_show, N_("Show existing overrides"), NULL },
  { NULL }
};

gboolean
flatpak_builtin_override (int argc, char **argv, GCancellable *cancellable, GError **error)
{
  g_autoptr(GOptionContext) context = NULL;
  const char *app;
  g_autoptr(FlatpakContext) arg_context = NULL;
  g_autoptr(GPtrArray) dirs = NULL;
  FlatpakDir *dir;
  g_autoptr(GKeyFile) metakey = NULL;
  g_autoptr(FlatpakContext) overrides = NULL;
  g_autoptr(GError) my_error = NULL;

  context = g_option_context_new (_("[APP] - Override settings [for application]"));
  g_option_context_set_translation_domain (context, GETTEXT_PACKAGE);

  arg_context = flatpak_context_new ();
  g_option_context_add_group (context, flatpak_context_get_options (arg_context));

  if (!flatpak_option_context_parse (context, options, &argc, &argv,
                                     FLATPAK_BUILTIN_FLAG_ONE_DIR,
                                     &dirs, cancellable, error))
    return FALSE;

  dir = g_ptr_array_index (dirs, 0);

  if (argc > 2)
    return usage_error (context, _("Too many arguments"), error);

  if (argc >= 2)
    {
      app = argv[1];
      if (!flatpak_is_valid_name (app, -1, &my_error))
        return flatpak_fail (error, _("'%s' is not a valid application name: %s"), app, my_error->message);
    }
  else
    app = NULL;

  if (opt_reset)
    return flatpak_remove_override_keyfile (app, flatpak_dir_is_user (dir), &my_error);

  metakey = flatpak_load_override_keyfile (app, flatpak_dir_is_user (dir), &my_error);
  if (metakey == NULL)
    {
      if (!g_error_matches (my_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
        {
          g_propagate_error (error, g_steal_pointer (&my_error));
          return FALSE;
        }
      metakey = g_key_file_new ();
    }

  if (opt_show)
    {
      g_autofree char *data = NULL;

      data = g_key_file_to_data (metakey, NULL, error);
      if (data == NULL)
        return FALSE;

      g_print ("%s", data);
      return TRUE;
    }

  overrides = flatpak_context_new ();
  if (!flatpak_context_load_metadata (overrides, metakey, error))
    return FALSE;

  flatpak_context_merge (overrides, arg_context);

  flatpak_context_save_metadata (overrides, FALSE, metakey);

  if (!flatpak_save_override_keyfile (metakey, app, flatpak_dir_is_user (dir), error))
    return FALSE;

  return TRUE;
}

gboolean
flatpak_complete_override (FlatpakCompletion *completion)
{
  g_autoptr(GOptionContext) context = NULL;
  g_autoptr(GPtrArray) dirs = NULL;
  g_autoptr(GError) error = NULL;
  int i;
  g_autoptr(FlatpakContext) arg_context = NULL;

  context = g_option_context_new ("");

  arg_context = flatpak_context_new ();
  g_option_context_add_group (context, flatpak_context_get_options (arg_context));

  if (!flatpak_option_context_parse (context, options, &completion->argc, &completion->argv,
                                     FLATPAK_BUILTIN_FLAG_ONE_DIR | FLATPAK_BUILTIN_FLAG_OPTIONAL_REPO,
                                     &dirs, NULL, NULL))
    return FALSE;

  switch (completion->argc)
    {
    case 0:
    case 1: /* NAME */
      flatpak_complete_options (completion, global_entries);
      flatpak_complete_options (completion, user_entries);
      flatpak_complete_options (completion, options);
      flatpak_complete_context (completion);

      for (i = 0; i < dirs->len; i++)
        {
          FlatpakDir *dir = g_ptr_array_index (dirs, i);
          g_autoptr(GPtrArray) refs = flatpak_dir_find_installed_refs (dir, NULL, NULL, NULL,
                                                                       FLATPAK_KINDS_APP,
                                                                       FIND_MATCHING_REFS_FLAGS_NONE,
                                                                       &error);
          if (refs == NULL)
            flatpak_completion_debug ("find local refs error: %s", error->message);

          flatpak_complete_ref_id (completion, refs);
        }

      break;
    }

  return TRUE;
}

===== ./app/flatpak-builtins-document-info.c =====
/* vi:set et sw=2 sts=2 cin cino=t0,f0,(0,{s,>2s,n-s,^-s,e-s:
 * Copyright © 2016 Red Hat, Inc
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Matthias Clasen <mclasen@redhat.com>
 */

#include "config.h"

#include <locale.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>

#include <glib/gi18n.h>

#include "libglnx.h"
#include "flatpak-document-dbus-generated.h"

#include <gio/gunixfdlist.h>

#include "flatpak-builtins.h"
#include "flatpak-utils-private.h"
#include "flatpak-run-private.h"

static GOptionEntry options[] = {
  { NULL }
};

gboolean
flatpak_builtin_document_info (int argc, char **argv,
                               GCancellable *cancellable,
                               GError **error)
{
  g_autoptr(GOptionContext) context = NULL;
  g_autoptr(GDBusConnection) session_bus = NULL;
  const char *file;
  XdpDbusDocuments *documents;
  g_autofree char *mountpoint = NULL;
  g_autofree char *basename = NULL;
  g_autofree char *doc_id = NULL;
  g_autofree char *doc_path = NULL;
  g_autofree char *origin = NULL;
  const char *app_id;
  const char **perms;
  g_autoptr(GVariant) apps = NULL;
  g_autoptr(GVariantIter) iter = NULL;

  context = g_option_context_new (_("FILE - Get information about an exported file"));
  g_option_context_set_translation_domain (context, GETTEXT_PACKAGE);

  if (!flatpak_option_context_parse (context, options, &argc, &argv,
                                     FLATPAK_BUILTIN_FLAG_NO_DIR,
                                     NULL, cancellable, error))
    return FALSE;

  if (argc < 2)
    return usage_error (context, _("FILE must be specified"), error);

  if (argc > 2)
    return usage_error (context, _("Too many arguments"), error);

  file = argv[1];
  basename = g_path_get_basename (file);

  session_bus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, error);
  if (session_bus == NULL)
    return FALSE;

  documents = xdp_dbus_documents_proxy_new_sync (session_bus, 0,
                                                 "org.freedesktop.portal.Documents",
                                                 "/org/freedesktop/portal/documents",
                                                 NULL, error);
  if (documents == NULL)
    return FALSE;

  if (!xdp_dbus_documents_call_get_mount_point_sync (documents, &mountpoint,
                                                     NULL, error))
    return FALSE;

  if (!xdp_dbus_documents_call_lookup_sync (documents, file, &doc_id, NULL, error))
    return FALSE;

  if (strcmp (doc_id, "") == 0)
    {
      g_print (_("Not exported\n"));
      return TRUE;
    }

  doc_path = g_build_filename (mountpoint, doc_id, basename, NULL);

  if (!xdp_dbus_documents_call_info_sync (documents, doc_id, &origin, &apps,
                                          NULL, error))
    return FALSE;

  iter = g_variant_iter_new (apps);

  g_print ("id: %s\n", doc_id);
  g_print ("path: %s\n", doc_path);
  g_print ("origin: %s\n", origin);
  if (g_variant_iter_n_children (iter) > 0)
    g_print ("permissions:\n");
  while (g_variant_iter_next (iter, "{&s^a&s}", &app_id, &perms))
    {
      int i;
      g_print ("\t%s\t", app_id);
      for (i = 0; perms[i]; i++)
        {
          if (i > 0)
            g_print (", ");
          g_print ("%s", perms[i]);
        }
      g_print ("\n");
    }

  return TRUE;
}

gboolean
flatpak_complete_document_info (FlatpakCompletion *completion)
{
  g_autoptr(GOptionContext) context = NULL;

  context = g_option_context_new ("");

  if (!flatpak_option_context_parse (context, options, &completion->argc, &completion->argv,
                                     FLATPAK_BUILTIN_FLAG_NO_DIR, NULL, NULL, NULL))
    return FALSE;

  switch (completion->argc)
    {
    case 0:
    case 1: /* FILE */
      flatpak_complete_options (completion, global_entries);
      flatpak_complete_options (completion, options);

      flatpak_complete_file (completion, "__FLATPAK_FILE");
      break;
    }

  return TRUE;
}

===== ./app/flatpak-builtins-build-finish.c =====
/* vi:set et sw=2 sts=2 cin cino=t0,f0,(0,{s,>2s,n-s,^-s,e-s:
 * Copyright © 2014 Red Hat, Inc
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Alexander Larsson <alexl@redhat.com>
 */

#include "config.h"

#include <locale.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <ftw.h>

#include <glib/gi18n.h>

#include "libglnx.h"

#include "flatpak-builtins.h"
#include "flatpak-context-private.h"
#include "flatpak-dir-private.h"
#include "flatpak-utils-private.h"
#include "flatpak-run-private.h"

static char *opt_command;
static char *opt_require_version;
static char **opt_extra_data;
static char **opt_extensions;
static char **opt_remove_extensions;
static char **opt_metadata;
static gboolean opt_no_exports;
static gboolean opt_no_inherit_permissions;
static int opt_extension_prio = G_MININT;
static char *opt_sdk;
static char *opt_runtime;

static GOptionEntry options[] = {
  { "command", 0, 0, G_OPTION_ARG_STRING, &opt_command, N_("Command to set"), N_("COMMAND") },
  { "require-version", 0, 0, G_OPTION_ARG_STRING, &opt_require_version, N_("Flatpak version to require"), N_("MAJOR.MINOR.MICRO") },
  { "no-exports", 0, 0, G_OPTION_ARG_NONE, &opt_no_exports, N_("Don't process exports"), NULL },
  { "extra-data", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_extra_data, N_("Extra data info") },
  { "extension", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_extensions, N_("Add extension point info"),  N_("NAME=VARIABLE[=VALUE]") },
  { "remove-extension", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_remove_extensions, N_("Remove extension point info"),  N_("NAME") },
  { "extension-priority", 0, 0, G_OPTION_ARG_INT, &opt_extension_prio, N_("Set extension priority (only for extensions)"), N_("VALUE") },
  { "sdk", 0, 0, G_OPTION_ARG_STRING, &opt_sdk, N_("Change the sdk used for the app"),  N_("SDK") },
  { "runtime", 0, 0, G_OPTION_ARG_STRING, &opt_runtime, N_("Change the runtime used for the app"),  N_("RUNTIME") },
  { "metadata", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_metadata, N_("Set generic metadata option"),  N_("GROUP=KEY[=VALUE]") },
  { "no-inherit-permissions", 0, 0, G_OPTION_ARG_NONE, &opt_no_inherit_permissions, N_("Don't inherit permissions from runtime"), NULL },
  { NULL }
};

static gboolean
export_dir (int           source_parent_fd,
            const char   *source_name,
            const char   *source_relpath,
            int           destination_parent_fd,
            const char   *destination_name,
            char        **allowed_prefixes,
            char        **allowed_extensions,
            gboolean      require_exact_match,
            GCancellable *cancellable,
            GError      **error)
{
  int res;
  g_auto(GLnxDirFdIterator) source_iter = {0};
  glnx_autofd int destination_dfd = -1;
  struct dirent *dent;

  if (!glnx_dirfd_iterator_init_at (source_parent_fd, source_name, FALSE, &source_iter, error))
    return FALSE;

  do
    res = mkdirat (destination_parent_fd, destination_name, 0755);
  while (G_UNLIKELY (res == -1 && errno == EINTR));
  if (res == -1)
    {
      if (errno != EEXIST)
        {
          glnx_set_error_from_errno (error);
          return FALSE;
        }
    }

  if (!glnx_opendirat (destination_parent_fd, destination_name, TRUE,
                       &destination_dfd, error))
    return FALSE;

  while (TRUE)
    {
      struct stat stbuf;
      g_autofree char *source_printable = NULL;

      if (!glnx_dirfd_iterator_next_dent (&source_iter, &dent, cancellable, error))
        return FALSE;

      if (dent == NULL)
        break;

      if (fstatat (source_iter.fd, dent->d_name, &stbuf, AT_SYMLINK_NOFOLLOW) == -1)
        {
          if (errno == ENOENT)
            {
              continue;
            }
          else
            {
              glnx_set_error_from_errno (error);
              return FALSE;
            }
        }

      /* Don't export any hidden files or backups */
      if (g_str_has_prefix (dent->d_name, ".") ||
          g_str_has_suffix (dent->d_name, "~"))
        continue;

      if (S_ISDIR (stbuf.st_mode))
        {
          g_autofree gchar *child_relpath = g_build_filename (source_relpath, dent->d_name, NULL);

          if (!export_dir (source_iter.fd, dent->d_name, child_relpath, destination_dfd, dent->d_name,
                           allowed_prefixes, allowed_extensions, require_exact_match,
                           cancellable, error))
            return FALSE;
        }
      else if (S_ISREG (stbuf.st_mode))
        {
          g_autofree gchar *name_without_extension = NULL;
          int i;

          source_printable = g_build_filename (source_relpath, dent->d_name, NULL);

          for (i = 0; allowed_extensions[i] != NULL; i++)
            {
              if (g_str_has_suffix (dent->d_name, allowed_extensions[i]))
                break;
            }

          if (allowed_extensions[i] == NULL)
            {
              g_print (_("Not exporting %s, wrong extension\n"), source_printable);
              continue;
            }

          name_without_extension = g_strndup (dent->d_name, strlen (dent->d_name) - strlen (allowed_extensions[i]));

          if (!flatpak_name_matches_one_wildcard_prefix (name_without_extension, (const char * const *) allowed_prefixes, require_exact_match))
            {
              g_print (_("Not exporting %s, non-allowed export filename\n"), source_printable);
              continue;
            }

          g_print (_("Exporting %s\n"), source_printable);

          if (!glnx_file_copy_at (source_iter.fd, dent->d_name, &stbuf,
                                  destination_dfd, dent->d_name,
                                  GLNX_FILE_COPY_NOXATTRS,
                                  cancellable,
                                  error))
            return FALSE;
        }
      else
        {
          source_printable = g_build_filename (source_relpath, dent->d_name, NULL);
          g_info ("Not exporting non-regular file %s", source_printable);
        }
    }

  /* Try to remove the directory, as we don't want to export empty directories.
   * However, don't fail if the unlink fails due to the directory not being empty */
  do
    res = unlinkat (destination_parent_fd, destination_name, AT_REMOVEDIR);
  while (G_UNLIKELY (res == -1 && errno == EINTR));
  if (res == -1)
    {
      if (errno != ENOTEMPTY)
        {
          glnx_set_error_from_errno (error);
          return FALSE;
        }
    }

  return TRUE;
}

static gboolean
copy_exports (GFile        *source,
              GFile        *destination,
              const char   *source_prefix,
              char        **allowed_prefixes,
              char        **allowed_extensions,
              gboolean      require_exact_match,
              GCancellable *cancellable,
              GError      **error)
{
  if (!flatpak_mkdir_p (destination, cancellable, error))
    return FALSE;

  /* The fds are closed by this call */
  if (!export_dir (AT_FDCWD, flatpak_file_get_path_cached (source), source_prefix,
                   AT_FDCWD, flatpak_file_get_path_cached (destination),
                   allowed_prefixes, allowed_extensions, require_exact_match,
                   cancellable, error))
    return FALSE;

  return TRUE;
}

static gboolean
collect_exports (GFile          *base,
                 const char     *app_id,
                 FlatpakContext *arg_context,
                 GCancellable   *cancellable,
                 GError        **error)
{
  g_autoptr(GFile) files = NULL;
  g_autoptr(GFile) export = NULL;
  int i;
  const char *paths[] = {
    "share/applications",                 /* Copy desktop files */
    "share/mime/packages",                /* Copy MIME Type files */
    "share/icons",                        /* Icons */
    "share/dbus-1/services",              /* D-Bus service files */
    "share/gnome-shell/search-providers", /* Search providers */
    "share/krunner/dbusplugins",          /* KDE krunner DBus plugins */
    "share/appdata",                      /* Copy appdata/metainfo files (legacy path) */
    "share/metainfo",                     /* Copy appdata/metainfo files */
    "share/metainfo/releases",            /* Copy AppStream release files */
    NULL,
  };


  files = g_file_get_child (base, "files");

  export = g_file_get_child (base, "export");

  if (!flatpak_mkdir_p (export, cancellable, error))
    return FALSE;

  if (opt_no_exports)
    return TRUE;

  for (i = 0; paths[i]; i++)
    {
      const char * path = paths[i];
      g_autoptr(GFile) src = g_file_resolve_relative_path (files, path);
      g_auto(GStrv) allowed_prefixes = NULL;
      g_auto(GStrv) allowed_extensions = NULL;
      gboolean require_exact_match = FALSE;

      if (!flatpak_context_get_allowed_exports (arg_context, path, app_id,
                                                &allowed_extensions, &allowed_prefixes, &require_exact_match))
        return flatpak_fail (error, "Unexpectedly not allowed to export %s", path);

      if (g_file_query_exists (src, cancellable))
        {
          g_info ("Exporting from %s", path);
          g_autoptr(GFile) dest = NULL;
          g_autoptr(GFile) dest_parent = NULL;

          if (strcmp (path, "share/appdata") == 0)
            dest = g_file_resolve_relative_path (export, "share/metainfo");
          else
            dest = g_file_resolve_relative_path (export, path);

          dest_parent = g_file_get_parent (dest);
          g_info ("Ensuring export/%s parent exists", path);
          if (!flatpak_mkdir_p (dest_parent, cancellable, error))
            return FALSE;
          g_info ("Copying from files/%s", path);
          if (!copy_exports (src,
                             dest,
                             path,
                             allowed_prefixes,
                             allowed_extensions,
                             require_exact_match,
                             cancellable,
                             error))
            return FALSE;
        }
    }

  g_assert_no_error (*error);
  return TRUE;
}

static gboolean
update_metadata (GFile *base, FlatpakContext *arg_context, gboolean is_runtime, GCancellable *cancellable, GError **error)
{
  gboolean ret = FALSE;
  g_autoptr(GFile) metadata = NULL;
  g_autofree char *path = NULL;
  g_autoptr(GKeyFile) keyfile = NULL;
  g_autoptr(FlatpakContext) app_context = NULL;
  g_autoptr(FlatpakContext) inherited_context = NULL;
  GError *temp_error = NULL;
  const char *group;
  int i;

  metadata = g_file_get_child (base, "metadata");
  if (!g_file_query_exists (metadata, cancellable))
    goto out;

  if (is_runtime)
    group = FLATPAK_METADATA_GROUP_RUNTIME;
  else
    group = FLATPAK_METADATA_GROUP_APPLICATION;

  path = g_file_get_path (metadata);
  keyfile = g_key_file_new ();
  if (!g_key_file_load_from_file (keyfile, path, G_KEY_FILE_NONE, error))
    goto out;

  if (opt_sdk != NULL || opt_runtime != NULL)
    {
      g_autofree char *old_runtime = g_key_file_get_string (keyfile,
                                                            group,
                                                            FLATPAK_METADATA_KEY_RUNTIME, NULL);
      g_autofree char *old_sdk = g_key_file_get_string (keyfile,
                                                        group,
                                                        FLATPAK_METADATA_KEY_SDK,
                                                        NULL);
      const char *old_sdk_arch = NULL;
      const char *old_runtime_arch = NULL;
      const char *old_sdk_branch = NULL;
      const char *old_runtime_branch = NULL;
      g_auto(GStrv) old_sdk_parts = NULL;
      g_auto(GStrv) old_runtime_parts = NULL;

      if (old_sdk)
        old_sdk_parts = g_strsplit (old_sdk, "/", 3);

      if (old_runtime)
        old_runtime_parts = g_strsplit (old_runtime, "/", 3);

      if (old_sdk_parts != NULL)
        {
          old_sdk_arch = old_sdk_parts[1];
          old_sdk_branch = old_sdk_parts[2];
        }
      if (old_runtime_parts != NULL)
        {
          old_runtime_arch = old_runtime_parts[1];
          old_runtime_branch = old_runtime_parts[2];

          /* Use the runtime as fallback if sdk is not specified */
          if (old_sdk_parts == NULL)
            {
              old_sdk_arch = old_runtime_parts[1];
              old_sdk_branch = old_runtime_parts[2];
            }
        }

      if (opt_sdk)
        {
          g_autofree char *id = NULL;
          g_autofree char *arch = NULL;
          g_autofree char *branch = NULL;
          g_autofree char *ref = NULL;
          FlatpakKinds kinds;

          if (!flatpak_split_partial_ref_arg (opt_sdk, FLATPAK_KINDS_RUNTIME,
                                              old_sdk_arch, old_sdk_branch ? old_sdk_branch : "master",
                                              &kinds, &id, &arch, &branch, error))
            return FALSE;

          ref = flatpak_build_untyped_ref (id, branch, arch);
          g_key_file_set_string (keyfile, group, FLATPAK_METADATA_KEY_SDK, ref);
        }

      if (opt_runtime)
        {
          g_autofree char *id = NULL;
          g_autofree char *arch = NULL;
          g_autofree char *branch = NULL;
          g_autofree char *ref = NULL;
          FlatpakKinds kinds;

          if (!flatpak_split_partial_ref_arg (opt_runtime, FLATPAK_KINDS_RUNTIME,
                                              old_runtime_arch, old_runtime_branch ? old_runtime_branch : "master",
                                              &kinds, &id, &arch, &branch, error))
            return FALSE;

          ref = flatpak_build_untyped_ref (id, branch, arch);
          g_key_file_set_string (keyfile, group, FLATPAK_METADATA_KEY_RUNTIME, ref);
        }
    }

  if (!is_runtime)
    {
      if (g_key_file_has_key (keyfile, group, FLATPAK_METADATA_KEY_COMMAND, NULL))
        {
          g_info ("Command key is present");

          if (opt_command)
            g_key_file_set_string (keyfile, group, FLATPAK_METADATA_KEY_COMMAND, opt_command);
        }
      else if (opt_command)
        {
          g_info ("Using explicitly provided command %s", opt_command);

          g_key_file_set_string (keyfile, group, FLATPAK_METADATA_KEY_COMMAND, opt_command);
        }
      else
        {
          g_autofree char *command = NULL;
          g_autoptr(GFile) bin_dir = NULL;
          g_autoptr(GFileEnumerator) bin_enum = NULL;
          g_autoptr(GFileInfo) child_info = NULL;

          g_info ("Looking for executables");

          bin_dir = g_file_resolve_relative_path (base, "files/bin");
          if (g_file_query_exists (bin_dir, cancellable))
            {
              bin_enum = g_file_enumerate_children (bin_dir, G_FILE_ATTRIBUTE_STANDARD_NAME,
                                                    G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
                                                    cancellable, error);
              if (!bin_enum)
                goto out;

              while ((child_info = g_file_enumerator_next_file (bin_enum, cancellable, &temp_error)))
                {
                  if (command != NULL)
                    {
                      g_print (_("More than one executable found\n"));
                      break;
                    }
                  command = g_strdup (g_file_info_get_name (child_info));
                }
              if (temp_error != NULL)
                goto out;
            }

          if (command)
            {
              g_print (_("Using %s as command\n"), command);
              g_key_file_set_string (keyfile, group, FLATPAK_METADATA_KEY_COMMAND, command);
            }
          else
            {
              g_print (_("No executable found\n"));
            }
        }

      /* Inherit permissions from runtime by default */
      if (!opt_no_inherit_permissions)
        {
          g_autofree char *runtime_pref = NULL;
          g_autoptr(GFile) runtime_deploy_dir = NULL;

          runtime_pref = g_key_file_get_string (keyfile, group, FLATPAK_METADATA_KEY_RUNTIME, NULL);
          if (runtime_pref != NULL)
            {
              g_autoptr(FlatpakDecomposed) runtime_ref = flatpak_decomposed_new_from_pref (FLATPAK_KINDS_RUNTIME, runtime_pref, NULL);
              if (runtime_ref)
                runtime_deploy_dir = flatpak_find_deploy_dir_for_ref (runtime_ref, NULL, cancellable, NULL);
            }

          /* This is optional, because some weird uses of flatpak build-finish (like the test suite)
             may not have the actual runtime installed. Most will though, as otherwise flatpak build
             will not work. */
          if (runtime_deploy_dir != NULL)
            {
              g_autoptr(GFile) runtime_metadata_file = NULL;
              g_autofree char *runtime_metadata_contents = NULL;
              gsize runtime_metadata_size;
              g_autoptr(GKeyFile) runtime_metakey = NULL;

              runtime_metadata_file = g_file_get_child (runtime_deploy_dir, "metadata");
              if (!g_file_load_contents (runtime_metadata_file, cancellable,
                                         &runtime_metadata_contents, &runtime_metadata_size, NULL, error))
                goto out;

              runtime_metakey = g_key_file_new ();
              if (!g_key_file_load_from_data (runtime_metakey, runtime_metadata_contents, runtime_metadata_size, 0, error))
                goto out;

              inherited_context = flatpak_context_new ();
              if (!flatpak_context_load_metadata (inherited_context, runtime_metakey, error))
                goto out;

              /* non-permissions are inherited at runtime, so no need to inherit them */
              flatpak_context_reset_non_permissions (inherited_context);
            }
        }
    }

  if (opt_require_version)
    {
      g_autoptr(GError) local_error = NULL;

      g_key_file_set_string (keyfile, group, "required-flatpak", opt_require_version);
      if (!flatpak_check_required_version ("test", keyfile, &local_error) &&
          g_error_matches (local_error, FLATPAK_ERROR, FLATPAK_ERROR_INVALID_DATA))
        {
          flatpak_fail (error, _("Invalid --require-version argument: %s"), opt_require_version);
          goto out;
        }
    }

  app_context = flatpak_context_new ();
  if (inherited_context)
    flatpak_context_merge (app_context, inherited_context);
  if (!flatpak_context_load_metadata (app_context, keyfile, error))
    goto out;
  flatpak_context_merge (app_context, arg_context);
  flatpak_context_save_metadata (app_context, FALSE, keyfile);

  for (i = 0; opt_extra_data != NULL && opt_extra_data[i] != NULL; i++)
    {
      char *extra_data = opt_extra_data[i];
      g_auto(GStrv) elements = NULL;
      g_autofree char *suffix = NULL;
      g_autofree char *uri_key = NULL;
      g_autofree char *name_key = NULL;
      g_autofree char *size_key = NULL;
      g_autofree char *installed_size_key = NULL;
      g_autofree char *checksum_key = NULL;

      if (i == 0)
        suffix = g_strdup ("");
      else
        suffix = g_strdup_printf ("%d", i);

      elements = g_strsplit (extra_data, ":", 5);
      if (g_strv_length (elements) != 5)
        {
          flatpak_fail (error, _("Too few elements in --extra-data argument %s"), extra_data);
          goto out;
        }

      uri_key = g_strconcat (FLATPAK_METADATA_KEY_EXTRA_DATA_URI, suffix, NULL);
      name_key = g_strconcat (FLATPAK_METADATA_KEY_EXTRA_DATA_NAME, suffix, NULL);
      checksum_key = g_strconcat (FLATPAK_METADATA_KEY_EXTRA_DATA_CHECKSUM,
                                  suffix, NULL);
      size_key = g_strconcat (FLATPAK_METADATA_KEY_EXTRA_DATA_SIZE, suffix, NULL);
      installed_size_key = g_strconcat (FLATPAK_METADATA_KEY_EXTRA_DATA_INSTALLED_SIZE,
                                        suffix, NULL);

      if (strlen (elements[0]) > 0)
        g_key_file_set_string (keyfile, FLATPAK_METADATA_GROUP_EXTRA_DATA,
                               name_key, elements[0]);
      g_key_file_set_string (keyfile, FLATPAK_METADATA_GROUP_EXTRA_DATA,
                             checksum_key, elements[1]);
      g_key_file_set_string (keyfile, FLATPAK_METADATA_GROUP_EXTRA_DATA,
                             size_key, elements[2]);
      if (strlen (elements[3]) > 0)
        g_key_file_set_string (keyfile, FLATPAK_METADATA_GROUP_EXTRA_DATA,
                               installed_size_key, elements[3]);
      g_key_file_set_string (keyfile, FLATPAK_METADATA_GROUP_EXTRA_DATA,
                             uri_key, elements[4]);
    }

  for (i = 0; opt_metadata != NULL && opt_metadata[i] != NULL; i++)
    {
      g_auto(GStrv) elements = NULL;
      elements = g_strsplit (opt_metadata[i], "=", 3);
      if (g_strv_length (elements) < 2)
        {
          flatpak_fail (error, _("Too few elements in --metadata argument %s, format should be GROUP=KEY[=VALUE]]"), opt_metadata[i]);
          goto out;
        }

      g_key_file_set_string (keyfile, elements[0], elements[1], elements[2] ? elements[2] : "true");
    }

  for (i = 0; opt_remove_extensions != NULL && opt_remove_extensions[i] != NULL; i++)
    {
      g_autofree char *groupname = g_strconcat (FLATPAK_METADATA_GROUP_PREFIX_EXTENSION, opt_remove_extensions[i], NULL);

      g_key_file_remove_group (keyfile, groupname, NULL);
    }

  for (i = 0; opt_extensions != NULL && opt_extensions[i] != NULL; i++)
    {
      g_auto(GStrv) elements = NULL;
      g_autofree char *groupname = NULL;

      elements = g_strsplit (opt_extensions[i], "=", 3);
      if (g_strv_length (elements) < 2)
        {
          flatpak_fail (error, _("Too few elements in --extension argument %s, format should be NAME=VAR[=VALUE]"), opt_extensions[i]);
          goto out;
        }

      if (!flatpak_is_valid_name (elements[0], -1, error))
        {
          glnx_prefix_error (error, _("Invalid extension name %s"), elements[0]);
          goto out;
        }

      groupname = g_strconcat (FLATPAK_METADATA_GROUP_PREFIX_EXTENSION,
                               elements[0], NULL);

      g_key_file_set_string (keyfile, groupname, elements[1], elements[2] ? elements[2] : "true");
    }


  if (opt_extension_prio != G_MININT)
    g_key_file_set_integer (keyfile, FLATPAK_METADATA_GROUP_EXTENSION_OF,
                            FLATPAK_METADATA_KEY_PRIORITY, opt_extension_prio);

  if (!g_key_file_save_to_file (keyfile, path, error))
    goto out;

  ret = TRUE;

out:
  if (temp_error != NULL)
    g_propagate_error (error, temp_error);

  return ret;
}

gboolean
flatpak_builtin_build_finish (int argc, char **argv, GCancellable *cancellable, GError **error)
{
  g_autoptr(GOptionContext) context = NULL;
  g_autoptr(GFile) base = NULL;
  g_autoptr(GFile) files_dir = NULL;
  g_autoptr(GFile) export_dir = NULL;
  g_autoptr(GFile) metadata_file = NULL;
  g_autofree char *metadata_contents = NULL;
  g_autofree char *id = NULL;
  gboolean is_runtime = FALSE;
  gsize metadata_size;
  const char *directory;
  g_autoptr(GKeyFile) metakey = NULL;
  g_autoptr(FlatpakContext) arg_context = NULL;

  context = g_option_context_new (_("DIRECTORY - Finalize a build directory"));
  g_option_context_set_translation_domain (context, GETTEXT_PACKAGE);

  arg_context = flatpak_context_new ();
  g_option_context_add_group (context, flatpak_context_get_options (arg_context));

  if (!flatpak_option_context_parse (context, options, &argc, &argv, FLATPAK_BUILTIN_FLAG_NO_DIR, NULL, cancellable, error))
    return FALSE;

  if (argc < 2)
    return usage_error (context, _("DIRECTORY must be specified"), error);

  directory = argv[1];

  base = g_file_new_for_commandline_arg (directory);

  files_dir = g_file_get_child (base, "files");
  export_dir = g_file_get_child (base, "export");
  metadata_file = g_file_get_child (base, "metadata");

  if (!g_file_query_exists (files_dir, cancellable) ||
      !g_file_query_exists (metadata_file, cancellable))
    return flatpak_fail (error, _("Build directory %s not initialized"), directory);

  if (!g_file_load_contents (metadata_file, cancellable, &metadata_contents, &metadata_size, NULL, error))
    return FALSE;

  metakey = g_key_file_new ();
  if (!g_key_file_load_from_data (metakey, metadata_contents, metadata_size, 0, error))
    return FALSE;

  id = g_key_file_get_string (metakey, FLATPAK_METADATA_GROUP_APPLICATION,
                              FLATPAK_METADATA_KEY_NAME, NULL);
  if (id == NULL)
    {
      id = g_key_file_get_string (metakey, FLATPAK_METADATA_GROUP_RUNTIME,
                                  FLATPAK_METADATA_KEY_NAME, NULL);
      if (id == NULL)
        return flatpak_fail (error, _("No name specified in the metadata"));
      is_runtime = TRUE;
    }

  if (g_file_query_exists (export_dir, cancellable))
    return flatpak_fail (error, _("Build directory %s already finalized"), directory);

  if (!is_runtime)
    {
      g_info ("Collecting exports");
      if (!collect_exports (base, id, arg_context, cancellable, error))
        return FALSE;
    }

  g_info ("Updating metadata");
  if (!update_metadata (base, arg_context, is_runtime, cancellable, error))
    return FALSE;

  g_print (_("Please review the exported files and the metadata\n"));

  return TRUE;
}

gboolean
flatpak_complete_build_finish (FlatpakCompletion *completion)
{
  g_autoptr(GOptionContext) context = NULL;
  g_autoptr(FlatpakContext) arg_context = NULL;

  context = g_option_context_new ("");

  arg_context = flatpak_context_new ();
  g_option_context_add_group (context, flatpak_context_get_options (arg_context));

  if (!flatpak_option_context_parse (context, options, &completion->argc, &completion->argv,
                                     FLATPAK_BUILTIN_FLAG_NO_DIR, NULL, NULL, NULL))
    return FALSE;

  switch (completion->argc)
    {
    case 0:
    case 1: /* DIR */
      flatpak_complete_options (completion, global_entries);
      flatpak_complete_options (completion, options);
      flatpak_complete_context (completion);

      flatpak_complete_dir (completion);
      break;
    }

  return TRUE;
}

===== ./app/flatpak-complete.c =====
/* vi:set et sw=2 sts=2 cin cino=t0,f0,(0,{s,>2s,n-s,^-s,e-s:
 * Copyright © 2018 Red Hat, Inc
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Alexander Larsson <alexl@redhat.com>
 */

#include "config.h"

#include "flatpak-complete.h"
#include "flatpak-installation.h"
#include "flatpak-utils-private.h"

/* Uncomment to get debug traces in /tmp/flatpak-completion-debug.txt (nice
 * to not have it interfere with stdout/stderr)
 */
#if 0
void
flatpak_completion_debug (const gchar *format, ...)
{
  va_list var_args;
  gchar *s;
  static FILE *f = NULL;

  va_start (var_args, format);
  s = g_strdup_vprintf (format, var_args);
  if (f == NULL)
    f = fopen ("/tmp/flatpak-completion-debug.txt", "a+");
  fprintf (f, "%s\n", s);
  fflush (f);
  g_free (s);
}
#else
void
flatpak_completion_debug (const gchar *format, ...)
{
}
#endif

static gboolean
is_word_separator (char c)
{
  return g_ascii_isspace (c);
}

void
flatpak_complete_file (FlatpakCompletion *completion,
                       const char        *file_type)
{
  flatpak_completion_debug ("completing FILE");
  g_print ("%s\n", file_type);
}

void
flatpak_complete_dir (FlatpakCompletion *completion)
{
  flatpak_completion_debug ("completing DIR");
  g_print ("%s\n", "__FLATPAK_DIR");
}

void
flatpak_complete_word (FlatpakCompletion *completion,
                       const char *format,
                       ...)
{
  va_list args;
  const char *rest;
  const char *shell_cur;
  const char *shell_cur_end;
  g_autofree char *string = NULL;

  g_return_if_fail (format != NULL);

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wformat-nonliteral"
  va_start (args, format);
  string = g_strdup_vprintf (format, args);
  va_end (args);
#pragma GCC diagnostic pop

  if (!g_str_has_prefix (string, completion->cur))
    return;

  shell_cur = completion->shell_cur ? completion->shell_cur : "";

  rest = string + strlen (completion->cur);

  shell_cur_end = shell_cur + strlen (shell_cur);
  while (shell_cur_end > shell_cur &&
         rest > string &&
         shell_cur_end[-1] == rest[-1] &&
         /* I'm not sure exactly what bash is doing here with =, but this seems to work... */
         shell_cur_end[-1] != '=')
    {
      rest--;
      shell_cur_end--;
    }

  flatpak_completion_debug ("completing word: '%s' (%s)", string, rest);

  g_print ("%s\n", rest);
}

void
flatpak_complete_ref_id (FlatpakCompletion *completion,
                         GPtrArray         *refs)
{
  if (refs == NULL)
    return;

  for (int i = 0; i < refs->len; i++)
    {
      FlatpakDecomposed *ref = g_ptr_array_index (refs, i);
      g_autofree char *id = flatpak_decomposed_dup_id (ref);
      flatpak_complete_word (completion, "%s ", id);
    }
}

void
flatpak_complete_ref_branch (FlatpakCompletion *completion,
                             GPtrArray         *refs)
{
  if (refs == NULL)
    return;

  for (int i = 0; i < refs->len; i++)
    {
      FlatpakDecomposed *ref = g_ptr_array_index (refs, i);
      g_autofree char *branch = flatpak_decomposed_dup_branch (ref);
      flatpak_complete_word (completion, "%s ", branch);
    }
}

void
flatpak_complete_ref (FlatpakCompletion *completion,
                      OstreeRepo        *repo)
{
  g_autoptr(GHashTable) refs = NULL;
  flatpak_completion_debug ("completing REF");

  if (ostree_repo_list_refs (repo,
                             NULL,
                             &refs, NULL, NULL))
    {
      GHashTableIter hashiter;
      gpointer hashkey, hashvalue;

      g_hash_table_iter_init (&hashiter, refs);
      while ((g_hash_table_iter_next (&hashiter, &hashkey, &hashvalue)))
        {
          const char *ref = (const char *) hashkey;
          if (!(g_str_has_prefix (ref, "runtime/") ||
                g_str_has_prefix (ref, "app/")))
            continue;
          flatpak_complete_word (completion, "%s", ref);
        }
    }
}

static int
find_current_element (const char *str)
{
  int count = 0;

  if (g_str_has_prefix (str, "app/"))
    str += strlen ("app/");
  else if (g_str_has_prefix (str, "runtime/"))
    str += strlen ("runtime/");

  while (str != NULL)
    {
      str = strchr (str, '/');
      count++;
      if (str != NULL)
        str = str + 1;
    }

  return count;
}

void
flatpak_complete_partial_ref (FlatpakCompletion *completion,
                              FlatpakKinds       kinds,
                              const char        *only_arch,
                              FlatpakDir        *dir,
                              const char        *remote)
{
  FlatpakKinds matched_kinds;
  const char *pref;
  g_autofree char *id = NULL;
  g_autofree char *arch = NULL;
  g_autofree char *branch = NULL;
  g_autoptr(GPtrArray) refs = NULL;
  int element;
  const char *cur_parts[4] = { NULL };
  g_autoptr(GError) error = NULL;
  int i;

  pref = completion->cur;
  element = find_current_element (pref);
  if (element > 3)
    return;

  flatpak_split_partial_ref_arg_novalidate (pref, kinds,
                                            NULL, NULL,
                                            &matched_kinds, &id, &arch, &branch);

  cur_parts[1] = id;
  cur_parts[2] = arch ? arch : "";
  cur_parts[3] = branch ? branch : "";

  if (remote)
    {
      g_autoptr(FlatpakRemoteState) state = get_remote_state (dir, remote, TRUE, FALSE,
                                                              (element > 2) ? arch : only_arch, NULL,
                                                              NULL, &error);
      if (state != NULL)
        refs = flatpak_dir_find_remote_refs (dir, state,
                                             (element > 1) ? id : NULL,
                                             NULL, /* branch */
                                             NULL, /* default branch */
                                             (element > 2) ? arch : only_arch,
                                             NULL, /* default arch */
                                             matched_kinds,
                                             FIND_MATCHING_REFS_FLAGS_NONE,
                                             NULL, &error);
    }
  else
    {
      refs = flatpak_dir_find_installed_refs (dir,
                                              (element > 1) ? id : NULL,
                                              NULL, /* branch */
                                              (element > 2) ? arch : only_arch,
                                              matched_kinds,
                                              FIND_MATCHING_REFS_FLAGS_NONE,
                                              &error);
    }
  if (refs == NULL)
    flatpak_completion_debug ("find refs error: %s", error->message);

  for (i = 0; refs != NULL && i < refs->len; i++)
    {
      FlatpakDecomposed *ref = g_ptr_array_index (refs, i);
      int j;
      g_autoptr(GString) comp = NULL;
      g_auto(GStrv) parts = g_strsplit (flatpak_decomposed_get_ref (ref), "/", 0);

      if (!g_str_has_prefix (parts[element], cur_parts[element]))
        continue;

      if (flatpak_id_has_subref_suffix (parts[element], -1))
        {
          char *last_dot = strrchr (parts[element], '.');

          if (last_dot == NULL)
            continue; /* Shouldn't really happen */

          /* Only complete to subrefs if fully matching real part.
           * For example, only match org.foo.Bar.Sources for
           * "org.foo.Bar", "org.foo.Bar." or "org.foo.Bar.S", but
           * not for "org.foo" or other shorter prefixes.
           */
          if (strncmp (parts[element], cur_parts[element], last_dot - parts[element] - 1) != 0)
            continue;
        }

      comp = g_string_new (pref);
      g_string_append (comp, parts[element] + strlen (cur_parts[element]));

      /* Only complete on the last part if the user explicitly adds a / */
      if (element >= 2)
        {
          for (j = element + 1; j < 4; j++)
            {
              g_string_append (comp, "/");
              g_string_append (comp, parts[j]);
            }
        }

      flatpak_complete_word (completion, "%s", comp->str);
    }
}

static gboolean
switch_already_in_line (FlatpakCompletion *completion,
                        GOptionEntry      *entry)
{
  guint i = 0;
  guint line_part_len = 0;

  for (; i < completion->original_argc; ++i)
    {
      line_part_len = strlen (completion->original_argv[i]);
      if (line_part_len > 2 &&
          g_strcmp0 (&completion->original_argv[i][2], entry->long_name) == 0)
        return TRUE;

      if (line_part_len == 2 &&
          completion->original_argv[i][1] == entry->short_name)
        return TRUE;
    }

  return FALSE;
}

static gboolean
should_filter_out_option_from_completion (FlatpakCompletion *completion,
                                          GOptionEntry      *entry)
{
  switch (entry->arg)
    {
    case G_OPTION_ARG_NONE:
    case G_OPTION_ARG_STRING:
    case G_OPTION_ARG_INT:
    case G_OPTION_ARG_FILENAME:
    case G_OPTION_ARG_DOUBLE:
    case G_OPTION_ARG_INT64:
      return switch_already_in_line (completion, entry);

    default:
      return FALSE;
    }
}

void
flatpak_complete_options (FlatpakCompletion *completion,
                          GOptionEntry      *entries)
{
  GOptionEntry *e = entries;
  int i;

  if (completion->cur == NULL || completion->cur[0] != '-')
    return;

  while (e->long_name != NULL)
    {
      if (e->arg_description)
        {
          g_autofree char *prefix = g_strdup_printf ("--%s=", e->long_name);

          if (g_str_has_prefix (completion->cur, prefix))
            {
              if (strcmp (e->arg_description, "ARCH") == 0)
                {
                  const char *arches[] = {"i386", "x86_64", "aarch64", "arm"};
                  for (i = 0; i < G_N_ELEMENTS (arches); i++)
                    flatpak_complete_word (completion, "%s%s ", prefix, arches[i]);
                }
              else if (strcmp (e->arg_description, "SHARE") == 0)
                {
                  for (i = 0; flatpak_context_shares[i] != NULL; i++)
                    flatpak_complete_word (completion, "%s%s ", prefix, flatpak_context_shares[i]);
                }
              else if (strcmp (e->arg_description, "DEVICE") == 0)
                {
                  for (i = 0; flatpak_context_devices[i] != NULL; i++)
                    flatpak_complete_word (completion, "%s%s ", prefix, flatpak_context_devices[i]);
                }
              else if (strcmp (e->arg_description, "FEATURE") == 0)
                {
                  for (i = 0; flatpak_context_features[i] != NULL; i++)
                    flatpak_complete_word (completion, "%s%s ", prefix, flatpak_context_features[i]);
                }
              else if (strcmp (e->arg_description, "SOCKET") == 0)
                {
                  for (i = 0; flatpak_context_sockets[i] != NULL; i++)
                    flatpak_complete_word (completion, "%s%s ", prefix, flatpak_context_sockets[i]);
                }
              else if (strcmp (e->arg_description, "FILE") == 0)
                {
                  flatpak_complete_file (completion, "__FLATPAK_FILE");
                }
              else if (strcmp (e->long_name, "installation") == 0)
                {
                  g_autoptr(GPtrArray) installations = NULL;
                  installations = flatpak_get_system_installations (NULL, NULL);
                  for (i = 0; i < installations->len; i++)
                    {
                      FlatpakInstallation *inst = g_ptr_array_index (installations, i);
                      flatpak_complete_word (completion, "%s%s ", prefix, flatpak_installation_get_id (inst));
                    }
                }
              else if (strcmp (e->long_name, "columns") == 0)
                {
                  /* columns are treated separately */
                }
              else
                flatpak_complete_word (completion, "%s", prefix);
            }
          else
            flatpak_complete_word (completion, "%s", prefix);
        }
      else
        {
          /* If this is just a switch, then don't add it multiple
           * times */
          if (!should_filter_out_option_from_completion (completion, e))
            {
              flatpak_complete_word (completion, "--%s ", e->long_name);
            }
          else
            {
              flatpak_completion_debug ("switch --%s is already in line %s", e->long_name, completion->line);
            }
        }

      /* We may end up checking switch_already_in_line twice, but this is
       * for simplicity's sake - the alternative solution would be to
       * continue the loop early and have to increment e. */
      if (e->short_name != 0)
        {
          /* This is a switch, we may not want to add it */
          if (!e->arg_description)
            {
              if (!should_filter_out_option_from_completion (completion, e))
                {
                  flatpak_complete_word (completion, "-%c ", e->short_name);
                }
              else
                {
                  flatpak_completion_debug ("switch -%c is already in line %s", e->short_name, completion->line);
                }
            }
          else
            {
              flatpak_complete_word (completion, "-%c ", e->short_name);
            }
        }
      e++;
    }
}

static void
flatpak_complete_column (FlatpakCompletion *completion,
                         char             **used,
                         const char        *column)
{
  g_autoptr(GString) s = NULL;

  s = g_string_new ("");

  if (used[0] != NULL)
    {
      int i;

      if (g_strv_contains ((const char * const *) used, column))
        return;

      const char *last = NULL;
      last = used[g_strv_length (used) - 1];
      if (!g_str_has_prefix (column, last))
        return;

      for (i = 0; used[i + 1]; i++)
        {
          g_string_append (s, used[i]);
          g_string_append_c (s, ',');
        }
    }

  g_string_append (s, column);
  flatpak_completion_debug ("completing column: %s", s->str);

  g_print ("%s\n", s->str);
}

void
flatpak_complete_columns (FlatpakCompletion *completion,
                          Column            *columns)
{
  int i;
  const char *list = NULL;
  g_auto(GStrv) used = NULL;

  if (!g_str_has_prefix (completion->cur, "--columns="))
    return;

  list = completion->cur + strlen ("--columns=");
  if (strcmp (list, "all") == 0 ||
      strcmp (list, "help") == 0)
    return;

  used = g_strsplit (list, ",", 0);
  flatpak_completion_debug ("complete columns, used: '%s'", list);

  if (g_strv_length (used) <= 1)
    {
      flatpak_complete_column (completion, used, "all");
      flatpak_complete_column (completion, used, "help");
    }

  for (i = 0; columns[i].name; i++)
    flatpak_complete_column (completion, used, columns[i].name);
}

void
flatpak_complete_context (FlatpakCompletion *completion)
{
  flatpak_complete_options (completion, flatpak_context_get_option_entries ());
}

static gchar *
pick_word_at (const char *s,
              int         cursor,
              int        *out_word_begins_at)
{
  int begin, end;

  if (s[0] == '\0')
    {
      if (out_word_begins_at != NULL)
        *out_word_begins_at = -1;
      return NULL;
    }

  if (is_word_separator (s[cursor]) && ((cursor > 0 && is_word_separator (s[cursor - 1])) || cursor == 0))
    {
      if (out_word_begins_at != NULL)
        *out_word_begins_at = cursor;
      return g_strdup ("");
    }

  while (cursor > 0 && !is_word_separator (s[cursor - 1]))
    cursor--;
  begin = cursor;

  end = begin;
  while (!is_word_separator (s[end]) && s[end] != '\0')
    end++;

  if (out_word_begins_at != NULL)
    *out_word_begins_at = begin;

  return g_strndup (s + begin, end - begin);
}

static gboolean
parse_completion_line_to_argv (const char        *initial_completion_line,
                               FlatpakCompletion *completion)
{
  gboolean parse_result = g_shell_parse_argv (initial_completion_line,
                                              &completion->original_argc,
                                              &completion->original_argv,
                                              NULL);

  /* Make a shallow copy of argv, which will be our "working set" */
  completion->argc = completion->original_argc;
  completion->argv = g_memdup2 (completion->original_argv,
                                sizeof (gchar *) * (completion->original_argc + 1));

  return parse_result;
}

FlatpakCompletion *
flatpak_completion_new (const char *arg_line,
                        const char *arg_point,
                        const char *arg_cur)
{
  FlatpakCompletion *completion;
  g_autofree char *initial_completion_line = NULL;
  int _point;
  char *endp;
  int cur_begin;
  int i;

  _point = strtol (arg_point, &endp, 10);
  if (endp == arg_point || *endp != '\0')
    return NULL;

  /* Ensure we're not going oob if we got weird arguments. */
  _point = MIN (_point, strlen (arg_line));

  completion = g_new0 (FlatpakCompletion, 1);
  completion->line = g_strdup (arg_line);
  completion->shell_cur = g_strdup (arg_cur);
  completion->point = _point;

  flatpak_completion_debug ("========================================");
  flatpak_completion_debug ("completion_point=%d", completion->point);
  flatpak_completion_debug ("completion_shell_cur='%s'", completion->shell_cur);
  flatpak_completion_debug ("----");
  flatpak_completion_debug (" 0123456789012345678901234567890123456789012345678901234567890123456789");
  flatpak_completion_debug ("'%s'", completion->line);
  flatpak_completion_debug (" %*s^", completion->point, "");

  /* compute cur and prev */
  completion->prev = NULL;
  completion->cur = pick_word_at (completion->line, completion->point, &cur_begin);
  if (cur_begin > 0)
    {
      gint prev_end;
      for (prev_end = cur_begin - 1; prev_end >= 0; prev_end--)
        {
          if (!is_word_separator (completion->line[prev_end]))
            {
              completion->prev = pick_word_at (completion->line, prev_end, NULL);
              break;
            }
        }

      initial_completion_line = g_strndup (completion->line, cur_begin);
    }
  else
    initial_completion_line = g_strdup ("");

  flatpak_completion_debug ("'%s'", initial_completion_line);
  flatpak_completion_debug ("----");

  flatpak_completion_debug (" cur='%s'", completion->cur);
  flatpak_completion_debug ("prev='%s'", completion->prev);

  if (!parse_completion_line_to_argv (initial_completion_line,
                                      completion))
    {
      /* it's very possible the command line can't be parsed (for
       * example, missing quotes etc) - in that case, we just
       * don't autocomplete at all
       */
      flatpak_completion_free (completion);
      return NULL;
    }

  flatpak_completion_debug ("completion_argv %i:", completion->original_argc);
  for (i = 0; i < completion->original_argc; i++)
    flatpak_completion_debug ("%s", completion->original_argv[i]);

  flatpak_completion_debug ("----");

  return completion;
}

void
flatpak_completion_free (FlatpakCompletion *completion)
{
  g_free (completion->cur);
  g_free (completion->prev);
  g_free (completion->line);
  g_free (completion->argv);
  g_free (completion->shell_cur);
  g_strfreev (completion->original_argv);
  g_free (completion);
}

===== ./app/meson.build =====
# Copyright 2022 Collabora Ltd.
# SPDX-License-Identifier: LGPL-2.1-or-later

sources = [
  'flatpak-builtins-utils.c',
  'flatpak-table-printer.c',
  'flatpak-tty-utils.c',
]

parse_datetime = custom_target(
  'parse-datetime.c',
  input : [
    'parse-datetime.y',
  ],
  output : [
    'parse-datetime.c',
  ],
  build_by_default : true,
  command : [
    bison,
    '@INPUT@',
    '-o', '@OUTPUT@',
  ],
)

flatpak_permission_gdbus = gnome.gdbus_codegen(
  'flatpak-permission-dbus-generated',
  sources: [
    '../data/org.freedesktop.impl.portal.PermissionStore.xml',
  ],
  interface_prefix : 'org.freedesktop.impl.portal',
  namespace : 'XdpDbus',
)

libflatpak_app = static_library(
  'libflatpak-app',
  sources : sources + [parse_datetime[0]],
  dependencies : base_deps + [
    appstream_dep,
    json_glib_dep,
    libflatpak_common_base_dep,
    libglnx_dep,
    libostree_dep,
    libsystemd_dep,
    polkit_agent_dep,
  ],
  include_directories : [
    common_include_directories,
    include_directories('.'),
  ],
  install : false,
)
libflatpak_app_dep = declare_dependency(
  dependencies : [
    base_deps,
    appstream_dep,
    json_glib_dep,
    libglnx_dep,
    libostree_dep,
    libsystemd_dep,
    polkit_agent_dep,
  ],
  include_directories : [
    common_include_directories,
    include_directories('.'),
  ],
  link_with : [
    libflatpak_app,
  ],
)

sources = [
  'flatpak-builtins-build-bundle.c',
  'flatpak-builtins-build-commit-from.c',
  'flatpak-builtins-build-export.c',
  'flatpak-builtins-build-finish.c',
  'flatpak-builtins-build-import-bundle.c',
  'flatpak-builtins-build-init.c',
  'flatpak-builtins-build-sign.c',
  'flatpak-builtins-build-update-repo.c',
  'flatpak-builtins-build.c',
  'flatpak-builtins-config.c',
  'flatpak-builtins-create-usb.c',
  'flatpak-builtins-document-export.c',
  'flatpak-builtins-document-info.c',
  'flatpak-builtins-document-list.c',
  'flatpak-builtins-document-unexport.c',
  'flatpak-builtins-enter.c',
  'flatpak-builtins-history.c',
  'flatpak-builtins-info.c',
  'flatpak-builtins-install.c',
  'flatpak-builtins-kill.c',
  'flatpak-builtins-list.c',
  'flatpak-builtins-make-current.c',
  'flatpak-builtins-mask.c',
  'flatpak-builtins-override.c',
  'flatpak-builtins-permission-list.c',
  'flatpak-builtins-permission-remove.c',
  'flatpak-builtins-permission-reset.c',
  'flatpak-builtins-permission-set.c',
  'flatpak-builtins-permission-show.c',
  'flatpak-builtins-pin.c',
  'flatpak-builtins-preinstall.c',
  'flatpak-builtins-ps.c',
  'flatpak-builtins-remote-add.c',
  'flatpak-builtins-remote-delete.c',
  'flatpak-builtins-remote-info.c',
  'flatpak-builtins-remote-list.c',
  'flatpak-builtins-remote-ls.c',
  'flatpak-builtins-remote-modify.c',
  'flatpak-builtins-repair.c',
  'flatpak-builtins-repo.c',
  'flatpak-builtins-run.c',
  'flatpak-builtins-search.c',
  'flatpak-builtins-uninstall.c',
  'flatpak-builtins-update.c',
  'flatpak-cli-transaction.c',
  'flatpak-complete.c',
  'flatpak-main.c',
  'flatpak-quiet-transaction.c',
]

if build_system_helper
  sources += [
    'flatpak-polkit-agent-text-listener.c',
  ]
endif

flatpak_exe = executable(
  'flatpak',
  dependencies : base_deps + [
    appstream_dep,
    json_glib_dep,
    libflatpak_app_dep,
    libflatpak_common_dep,
    libflatpak_common_base_dep,
    libglnx_dep,
    libostree_dep,
    libsystemd_dep,
    polkit_agent_dep,
  ],
  install : true,
  install_dir : get_option('bindir'),
  sources : sources + flatpak_gdbus + flatpak_permission_gdbus,
)

===== ./app/flatpak-builtins-document-export.c =====
/* vi:set et sw=2 sts=2 cin cino=t0,f0,(0,{s,>2s,n-s,^-s,e-s:
 * Copyright © 2014 Red Hat, Inc
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Alexander Larsson <alexl@redhat.com>
 */

#include "config.h"

#include <locale.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>

#include <glib/gi18n.h>

#include "libglnx.h"
#include "flatpak-document-dbus-generated.h"

#include <gio/gunixfdlist.h>

#include "flatpak-builtins.h"
#include "flatpak-utils-private.h"
#include "flatpak-run-private.h"

/* Flags accepted by org.freedesktop.portal.Documents.AddFull */
enum {
  XDP_ADD_FLAGS_REUSE_EXISTING             =  (1 << 0),
  XDP_ADD_FLAGS_PERSISTENT                 =  (1 << 1),
  XDP_ADD_FLAGS_AS_NEEDED_BY_APP           =  (1 << 2),
  XDP_ADD_FLAGS_DIRECTORY                  =  (1 << 3),
};

static gboolean opt_unique = FALSE;
static gboolean opt_transient = FALSE;
static gboolean opt_noexist = FALSE;
static gboolean opt_allow_read = TRUE;
static gboolean opt_forbid_read = FALSE;
static gboolean opt_allow_write = FALSE;
static gboolean opt_forbid_write = FALSE;
static gboolean opt_allow_delete = FALSE;
static gboolean opt_forbid_delete = FALSE;
static gboolean opt_allow_grant_permissions = FALSE;
static gboolean opt_forbid_grant_permissions = FALSE;
static char **opt_apps = NULL;

static GOptionEntry options[] = {
  { "unique", 'u', 0, G_OPTION_ARG_NONE, &opt_unique, N_("Create a unique document reference"), NULL },
  { "transient", 't', 0, G_OPTION_ARG_NONE, &opt_transient, N_("Make the document transient for the current session"), NULL },
  { "noexist", 'n', 0, G_OPTION_ARG_NONE, &opt_noexist, N_("Don't require the file to exist already"), NULL },
  { "allow-read", 'r', 0, G_OPTION_ARG_NONE, &opt_allow_read, N_("Give the app read permissions"), NULL },
  { "allow-write", 'w', 0, G_OPTION_ARG_NONE, &opt_allow_write, N_("Give the app write permissions"), NULL },
  { "allow-delete", 'd', 0, G_OPTION_ARG_NONE, &opt_allow_delete, N_("Give the app delete permissions"), NULL },
  { "allow-grant-permission", 'g', 0, G_OPTION_ARG_NONE, &opt_allow_grant_permissions, N_("Give the app permissions to grant further permissions"), NULL },
  { "forbid-read", 0, 0, G_OPTION_ARG_NONE, &opt_forbid_read, N_("Revoke read permissions of the app"), NULL },
  { "forbid-write", 0, 0, G_OPTION_ARG_NONE, &opt_forbid_write, N_("Revoke write permissions of the app"), NULL },
  { "forbid-delete", 0, 0, G_OPTION_ARG_NONE, &opt_forbid_delete, N_("Revoke delete permissions of the app"), NULL },
  { "forbid-grant-permission", 0, 0, G_OPTION_ARG_NONE, &opt_forbid_grant_permissions, N_("Revoke the permission to grant further permissions"), NULL },
  { "app", 'a', 0, G_OPTION_ARG_STRING_ARRAY, &opt_apps, N_("Add permissions for this app"), N_("APPID") },
  { NULL }
};

gboolean
flatpak_builtin_document_export (int argc, char **argv,
                                 GCancellable *cancellable,
                                 GError **error)
{
  g_autoptr(GOptionContext) context = NULL;
  g_autoptr(GVariant) reply = NULL;
  g_autoptr(GDBusConnection) session_bus = NULL;
  g_autoptr(GPtrArray) permissions = NULL;
  g_autoptr(GPtrArray) revocations = NULL;
  const char *file;
  g_autofree char *mountpoint = NULL;
  g_autofree char *basename = NULL;
  g_autofree char *dirname = NULL;
  g_autofree char *doc_path = NULL;
  XdpDbusDocuments *documents;
  glnx_autofd int fd = -1;
  int i, fd_id;
  GUnixFDList *fd_list = NULL;
  const char *doc_id;
  struct stat stbuf;
  gboolean is_directory = FALSE;

  context = g_option_context_new (_("FILE - Export a file to apps"));
  g_option_context_set_translation_domain (context, GETTEXT_PACKAGE);

  if (!flatpak_option_context_parse (context, options, &argc, &argv,
                                     FLATPAK_BUILTIN_FLAG_NO_DIR,
                                     NULL, cancellable, error))
    return FALSE;

  if (argc < 2)
    return usage_error (context, _("FILE must be specified"), error);

  if (argc > 2)
    return usage_error (context, _("Too many arguments"), error);

  file = argv[1];
  dirname = g_path_get_dirname (file);
  basename = g_path_get_basename (file);

  session_bus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, error);
  if (session_bus == NULL)
    return FALSE;

  documents = xdp_dbus_documents_proxy_new_sync (session_bus, 0,
                                                 "org.freedesktop.portal.Documents",
                                                 "/org/freedesktop/portal/documents",
                                                 NULL, error);
  if (documents == NULL)
    return FALSE;

  if (!xdp_dbus_documents_call_get_mount_point_sync (documents, &mountpoint,
                                                     NULL, error))
    return FALSE;

  if (opt_noexist)
    fd = open (dirname, O_PATH | O_CLOEXEC);
  else
    fd = open (file, O_PATH | O_CLOEXEC);

  if (fd == -1)
    {
      glnx_set_error_from_errno (error);
      return FALSE;
    }

  if (fstat (fd, &stbuf) == 0 && S_ISDIR (stbuf.st_mode))
    is_directory = TRUE;

  if (is_directory)
    {
      guint portal_version = 0;
      g_autoptr(GVariant) ret = NULL;
      g_autoptr(GVariant) v = NULL;

      ret = g_dbus_connection_call_sync (session_bus,
                                         "org.freedesktop.portal.Documents",
                                         "/org/freedesktop/portal/documents",
                                         "org.freedesktop.DBus.Properties",
                                         "Get",
                                         g_variant_new ("(ss)", "org.freedesktop.portal.Documents", "version"),
                                         G_VARIANT_TYPE ("(v)"),
                                         0,
                                         G_MAXINT,
                                         NULL,
                                         NULL);
      if (ret)
        {
          g_variant_get (ret, "(v)", &v);
          g_variant_get (v, "u", &portal_version);

          if (portal_version < 4)
            return flatpak_fail (error, "Exporting directories needs version 4 of the document portal (have version %d)", portal_version);
        }
    }

  fd_list = g_unix_fd_list_new ();
  fd_id = g_unix_fd_list_append (fd_list, fd, error);
  glnx_close_fd (&fd);

  if (opt_noexist)
    {
      reply = g_dbus_connection_call_with_unix_fd_list_sync (session_bus,
                                                             "org.freedesktop.portal.Documents",
                                                             "/org/freedesktop/portal/documents",
                                                             "org.freedesktop.portal.Documents",
                                                             "AddNamed",
                                                             g_variant_new ("(h^aybb)", fd_id, basename, !opt_unique, !opt_transient),
                                                             G_VARIANT_TYPE ("(s)"),
                                                             G_DBUS_CALL_FLAGS_NONE,
                                                             30000,
                                                             fd_list, NULL,
                                                             NULL,
                                                             error);
    }
  else
    {
      if (is_directory)
        {
          guint flags = XDP_ADD_FLAGS_DIRECTORY;
          const char *perms[] = {NULL};

          if (!opt_unique)
            flags |= XDP_ADD_FLAGS_REUSE_EXISTING;
          if (!opt_transient)
            flags |= XDP_ADD_FLAGS_PERSISTENT;

          /* We only use AddFull for directories so that regular adds work with old portal versions */
          reply = g_dbus_connection_call_with_unix_fd_list_sync (session_bus,
                                                                 "org.freedesktop.portal.Documents",
                                                                 "/org/freedesktop/portal/documents",
                                                                 "org.freedesktop.portal.Documents",
                                                                 "AddFull",
                                                                 g_variant_new ("(@ahus^as)",
                                                                                g_variant_new_fixed_array (G_VARIANT_TYPE_HANDLE, &fd_id, 1, sizeof (fd_id)),
                                                                                flags,"", perms),
                                                                 G_VARIANT_TYPE ("(asa{sv})"),
                                                                 G_DBUS_CALL_FLAGS_NONE,
                                                                 30000,
                                                                 fd_list, NULL,
                                                                 NULL,
                                                                 error);
        }
      else
        reply = g_dbus_connection_call_with_unix_fd_list_sync (session_bus,
                                                               "org.freedesktop.portal.Documents",
                                                               "/org/freedesktop/portal/documents",
                                                               "org.freedesktop.portal.Documents",
                                                               "Add",
                                                               g_variant_new ("(hbb)", fd_id, !opt_unique, !opt_transient),
                                                               G_VARIANT_TYPE ("(s)"),
                                                               G_DBUS_CALL_FLAGS_NONE,
                                                               30000,
                                                               fd_list, NULL,
                                                               NULL,
                                                               error);
    }
  g_object_unref (fd_list);

  if (reply == NULL)
    return FALSE;

  if (is_directory)
    {
      g_autofree char **doc_ids = NULL;
      g_variant_get (reply, "(^a&s@a{sv})", &doc_ids, NULL);
      doc_id = doc_ids[0];
    }
  else
    {
      g_variant_get (reply, "(&s)", &doc_id);
    }

  permissions = g_ptr_array_new ();
  if (opt_allow_read)
    g_ptr_array_add (permissions, "read");
  if (opt_allow_write)
    g_ptr_array_add (permissions, "write");
  if (opt_allow_delete)
    g_ptr_array_add (permissions, "delete");
  if (opt_allow_grant_permissions)
    g_ptr_array_add (permissions, "grant-permissions");
  g_ptr_array_add (permissions, NULL);

  revocations = g_ptr_array_new ();
  if (opt_forbid_read)
    g_ptr_array_add (revocations, "read");
  if (opt_forbid_write)
    g_ptr_array_add (revocations, "write");
  if (opt_forbid_delete)
    g_ptr_array_add (revocations, "delete");
  if (opt_forbid_grant_permissions)
    g_ptr_array_add (revocations, "grant-permissions");
  g_ptr_array_add (revocations, NULL);

  for (i = 0; opt_apps != NULL && opt_apps[i] != NULL; i++)
    {
      if (!xdp_dbus_documents_call_grant_permissions_sync (documents,
                                                           doc_id,
                                                           opt_apps[i],
                                                           (const char **) permissions->pdata,
                                                           NULL,
                                                           error))
        return FALSE;

      if (!xdp_dbus_documents_call_revoke_permissions_sync (documents,
                                                            doc_id,
                                                            opt_apps[i],
                                                            (const char **) revocations->pdata,
                                                            NULL,
                                                            error))
        return FALSE;
    }

  doc_path = g_build_filename (mountpoint, doc_id, basename, NULL);
  g_print ("%s\n", doc_path);

  return TRUE;
}

gboolean
flatpak_complete_document_export (FlatpakCompletion *completion)
{
  g_autoptr(GOptionContext) context = NULL;

  context = g_option_context_new ("");

  if (!flatpak_option_context_parse (context, options, &completion->argc, &completion->argv,
                                     FLATPAK_BUILTIN_FLAG_NO_DIR, NULL, NULL, NULL))
    return FALSE;

  switch (completion->argc)
    {
    case 0:
    case 1: /* FILE */
      flatpak_complete_options (completion, global_entries);
      flatpak_complete_options (completion, options);

      flatpak_complete_file (completion, "__FLATPAK_FILE");
      break;
    }

  return TRUE;
}

===== ./app/flatpak-builtins-build.c =====
/* vi:set et sw=2 sts=2 cin cino=t0,f0,(0,{s,>2s,n-s,^-s,e-s:
 * Copyright © 2014 Red Hat, Inc
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Alexander Larsson <alexl@redhat.com>
 */

#include "config.h"

#include <locale.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>

#include <glib/gi18n.h>

#include "libglnx.h"

#include "flatpak-builtins.h"
#include "flatpak-utils-private.h"
#include "flatpak-run-private.h"

static gboolean opt_runtime;
static char *opt_build_dir;
static char **opt_bind_mounts;
static char *opt_sdk_dir;
static char *opt_metadata;
static gboolean opt_log_session_bus;
static gboolean opt_log_system_bus;
static gboolean opt_die_with_parent;
static gboolean opt_with_appdir;
static gboolean opt_readonly;

static GOptionEntry options[] = {
  { "runtime", 'r', 0, G_OPTION_ARG_NONE, &opt_runtime, N_("Use Platform runtime rather than Sdk"), NULL },
  { "readonly", 0, 0, G_OPTION_ARG_NONE, &opt_readonly, N_("Make destination readonly"), NULL },
  { "bind-mount", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_bind_mounts, N_("Add bind mount"), N_("DEST=SRC") },
  { "build-dir", 0, 0, G_OPTION_ARG_STRING, &opt_build_dir, N_("Start build in this directory"), N_("DIR") },
  { "sdk-dir", 0, 0, G_OPTION_ARG_STRING, &opt_sdk_dir, N_("Where to look for custom sdk dir (defaults to 'usr')"), N_("DIR") },
  { "metadata", 0, 0, G_OPTION_ARG_STRING, &opt_metadata, N_("Use alternative file for the metadata"), N_("FILE") },
  { "die-with-parent", 'p', 0, G_OPTION_ARG_NONE, &opt_die_with_parent, N_("Kill processes when the parent process dies"), NULL },
  { "with-appdir", 0, 0, G_OPTION_ARG_NONE, &opt_with_appdir, N_("Export application homedir directory to build"), NULL },
  { "log-session-bus", 0, 0, G_OPTION_ARG_NONE, &opt_log_session_bus, N_("Log session bus calls"), NULL },
  { "log-system-bus", 0, 0, G_OPTION_ARG_NONE, &opt_log_system_bus, N_("Log system bus calls"), NULL },
  { NULL }
};

static gboolean
has_bind_mount_for_path (FlatpakBwrap *bwrap, const char *dest_path)
{
  guint i;

  for (i = 0; i < bwrap->argv->len; i++)
    {
      const char *arg = g_ptr_array_index (bwrap->argv, i);

      if (g_strcmp0 (arg, "--bind") == 0 ||
          g_strcmp0 (arg, "--bind-try") == 0 ||
          g_strcmp0 (arg, "--ro-bind") == 0 ||
          g_strcmp0 (arg, "--ro-bind-try") == 0 ||
          g_strcmp0 (arg, "--bind-data") == 0 ||
          g_strcmp0 (arg, "--ro-bind-data") == 0)
        {
          /* For all bind mount types, the destination path is at index i+2.
           *
           *   --bind/--ro-bind/--bind-try/--ro-bind-try: type, src, dest
           *   --bind-data/--ro-bind-data: type, fd_string, dest
           */
          if (i + 2 < bwrap->argv->len)
            {
              const char *dest = g_ptr_array_index (bwrap->argv, i + 2);
              if (dest != NULL && g_strcmp0 (dest, dest_path) == 0)
                return TRUE;
            }
        }
    }

  return FALSE;
}

static void
add_empty_font_dirs_xml (FlatpakBwrap *bwrap)
{
  const char *font_dirs_path = "/run/host/font-dirs.xml";

  /* Check if a bind mount already exists for this path */
  if (has_bind_mount_for_path (bwrap, font_dirs_path))
    return;

  g_autoptr(GString) xml_snippet = g_string_new ("<?xml version=\"1.0\"?>\n"
                                                 "<!DOCTYPE fontconfig SYSTEM \"urn:fontconfig:fonts.dtd\">\n"
                                                 "<fontconfig></fontconfig>\n");

  if (!flatpak_bwrap_add_args_data (bwrap, "font-dirs.xml", xml_snippet->str, xml_snippet->len, font_dirs_path, NULL))
    g_warning ("Unable to add fontconfig data snippet");
}

/* Unset FD_CLOEXEC on the array of fds passed in @user_data */
static void
child_setup (gpointer user_data)
{
  GArray *fd_array = user_data;
  int i;

  /* If no fd_array was specified, don't care. */
  if (fd_array == NULL)
    return;

  /* Otherwise, mark not - close-on-exec all the fds in the array */
  for (i = 0; i < fd_array->len; i++)
    fcntl (g_array_index (fd_array, int, i), F_SETFD, 0);
}

static gboolean
find_matching_extension_group_in_metakey (GKeyFile   *metakey,
                                          const char *id,
                                          const char *specified_tag,
                                          char      **out_extension_group,
                                          GError    **error)
{
  g_auto(GStrv) groups = NULL;
  g_autofree char *extension_prefix = NULL;
  const char *last_seen_group = NULL;
  guint n_extension_groups = 0;
  GStrv iter = NULL;

  g_return_val_if_fail (out_extension_group != NULL, FALSE);

  groups =  g_key_file_get_groups (metakey, NULL);
  extension_prefix = g_strconcat (FLATPAK_METADATA_GROUP_PREFIX_EXTENSION,
                                  id,
                                  NULL);

  for (iter = groups; *iter != NULL; ++iter)
    {
      const char *group_name = *iter;
      const char *extension_name = NULL;
      g_autofree char *extension_tag = NULL;

      if (!g_str_has_prefix (group_name, extension_prefix))
        continue;

      ++n_extension_groups;
      extension_name = group_name + strlen (FLATPAK_METADATA_GROUP_PREFIX_EXTENSION);

      flatpak_parse_extension_with_tag (extension_name,
                                        NULL,
                                        &extension_tag);

      /* Check 1: Does this extension have the same tag as the
       * specified tag (including if both are NULL)? If so, use it */
      if (g_strcmp0 (extension_tag, specified_tag) == 0)
        {
          *out_extension_group = g_strdup (group_name);
          return TRUE;
        }

      /* Check 2: Keep track of this extension group as the last
       * seen one. If it was the only one then we can use it. */
      last_seen_group = group_name;
    }

  if (n_extension_groups == 1 && last_seen_group != NULL)
    {
      *out_extension_group = g_strdup (last_seen_group);
      return TRUE;
    }
  else if (n_extension_groups == 0)
    {
      /* Check 2: No extension groups, this is not an error case as
       * we check the parent later. */
      *out_extension_group = NULL;
      return TRUE;
    }

  g_set_error (error,
               G_IO_ERROR,
               G_IO_ERROR_FAILED,
               "Unable to resolve extension %s to a unique "
               "extension point in the parent app or runtime. Consider "
               "using the 'tag' key in ExtensionOf to disambiguate which "
               "extension point to build against.",
               id);

  return FALSE;
}

gboolean
flatpak_builtin_build (int argc, char **argv, GCancellable *cancellable, GError **error)
{
  g_autoptr(GOptionContext) context = NULL;
  g_autoptr(FlatpakDeploy) runtime_deploy = NULL;
  g_autoptr(GBytes) runtime_deploy_data = NULL;
  g_autoptr(FlatpakDeploy) extensionof_deploy = NULL;
  g_autoptr(GFile) var = NULL;
  g_autoptr(GFile) var_tmp = NULL;
  g_autoptr(GFile) var_lib = NULL;
  g_autoptr(GFile) usr = NULL;
  g_autoptr(GFile) res_deploy = NULL;
  g_autoptr(GFile) res_files = NULL;
  g_autoptr(GFile) app_files = NULL;
  gboolean app_files_ro = FALSE;
  g_autoptr(GFile) runtime_files = NULL;
  g_autoptr(GFile) metadata = NULL;
  g_autofree char *metadata_contents = NULL;
  g_autofree char *runtime_pref = NULL;
  g_autoptr(FlatpakDecomposed) runtime_ref = NULL;
  g_autofree char *extensionof_ref = NULL;
  g_autofree char *extensionof_tag = NULL;
  g_autofree char *extension_point = NULL;
  g_autofree char *extension_tmpfs_point = NULL;
  g_autoptr(GKeyFile) metakey = NULL;
  g_autoptr(GKeyFile) runtime_metakey = NULL;
  g_autoptr(FlatpakBwrap) bwrap = NULL;
  g_auto(GStrv) minimal_envp = NULL;
  gsize metadata_size;
  const char *directory = NULL;
  const char *command = "/bin/sh";
  g_autofree char *id = NULL;
  int i;
  int rest_argv_start, rest_argc;
  g_autoptr(FlatpakContext) arg_context = NULL;
  g_autoptr(FlatpakContext) app_context = NULL;
  gboolean custom_usr;
  FlatpakRunFlags run_flags;
  const char *group = NULL;
  const char *runtime_key = NULL;
  g_autofree char *dest = NULL;
  gboolean is_app = FALSE;
  gboolean is_extension = FALSE;
  gboolean is_app_extension = FALSE;
  g_autofree char *arch = NULL;
  g_autofree char *app_info_path = NULL;
  g_autofree char *app_extensions = NULL;
  g_autofree char *app_ld_path = NULL;
  g_autofree char *runtime_extensions = NULL;
  g_autofree char *runtime_ld_path = NULL;
  g_autofree char *instance_id_host_dir = NULL;
  g_autofree char *instance_id = NULL;
  char pid_str[64];
  g_autofree char *pid_path = NULL;
  g_autoptr(GFile) app_id_dir = NULL;
  FlatpakContextShares shares;
  FlatpakContextDevices devices;
  FlatpakContextSockets sockets;
  FlatpakContextFeatures features;

  context = g_option_context_new (_("DIRECTORY [COMMAND [ARGUMENT…]] - Build in directory"));
  g_option_context_set_translation_domain (context, GETTEXT_PACKAGE);

  rest_argc = 0;
  for (i = 1; i < argc; i++)
    {
      /* The non-option is the directory, take it out of the arguments */
      if (argv[i][0] != '-')
        {
          rest_argv_start = i;
          rest_argc = argc - i;
          argc = i;
          break;
        }
    }

  arg_context = flatpak_context_new ();
  g_option_context_add_group (context, flatpak_context_get_options (arg_context));

  if (!flatpak_option_context_parse (context, options, &argc, &argv, FLATPAK_BUILTIN_FLAG_NO_DIR, NULL, cancellable, error))
    return FALSE;

  if (rest_argc == 0)
    return usage_error (context, _("DIRECTORY must be specified"), error);

  directory = argv[rest_argv_start];
  if (rest_argc >= 2)
    command = argv[rest_argv_start + 1];

  res_deploy = g_file_new_for_commandline_arg (directory);
  metadata = g_file_get_child (res_deploy, opt_metadata ? opt_metadata : "metadata");

  if (!g_file_query_exists (res_deploy, NULL) ||
      !g_file_query_exists (metadata, NULL))
    return flatpak_fail (error, _("Build directory %s not initialized, use flatpak build-init"), directory);

  if (!g_file_load_contents (metadata, cancellable, &metadata_contents, &metadata_size, NULL, error))
    return FALSE;

  metakey = g_key_file_new ();
  if (!g_key_file_load_from_data (metakey, metadata_contents, metadata_size, 0, error))
    return FALSE;

  if (g_key_file_has_group (metakey, FLATPAK_METADATA_GROUP_APPLICATION))
    {
      group = FLATPAK_METADATA_GROUP_APPLICATION;
      is_app = TRUE;
    }
  else if (g_key_file_has_group (metakey, FLATPAK_METADATA_GROUP_RUNTIME))
    {
      group = FLATPAK_METADATA_GROUP_RUNTIME;
    }
  else
    return flatpak_fail (error, _("metadata invalid, not application or runtime"));

  extensionof_ref = g_key_file_get_string (metakey,
                                           FLATPAK_METADATA_GROUP_EXTENSION_OF,
                                           FLATPAK_METADATA_KEY_REF, NULL);
  if (extensionof_ref != NULL)
    {
      is_extension = TRUE;
      if (g_str_has_prefix (extensionof_ref, "app/"))
        is_app_extension = TRUE;
    }

  extensionof_tag = g_key_file_get_string (metakey,
                                           FLATPAK_METADATA_GROUP_EXTENSION_OF,
                                           FLATPAK_METADATA_KEY_TAG, NULL);

  id = g_key_file_get_string (metakey, group, FLATPAK_METADATA_KEY_NAME, error);
  if (id == NULL)
    return FALSE;

  if (opt_runtime)
    runtime_key = FLATPAK_METADATA_KEY_RUNTIME;
  else
    runtime_key = FLATPAK_METADATA_KEY_SDK;

  runtime_pref = g_key_file_get_string (metakey, group, runtime_key, error);
  if (runtime_pref == NULL)
    return FALSE;

  runtime_ref = flatpak_decomposed_new_from_pref (FLATPAK_KINDS_RUNTIME, runtime_pref, error);
  if (runtime_ref == NULL)
    return FALSE;

  arch = flatpak_decomposed_dup_arch (runtime_ref);

  custom_usr = FALSE;
  usr = g_file_get_child (res_deploy,  opt_sdk_dir ? opt_sdk_dir : "usr");
  if (g_file_query_exists (usr, cancellable))
    {
      custom_usr = TRUE;
      runtime_files = g_object_ref (usr);
    }
  else
    {
      runtime_deploy = flatpak_find_deploy_for_ref (flatpak_decomposed_get_ref (runtime_ref), NULL, NULL, cancellable, error);
      if (runtime_deploy == NULL)
        return FALSE;

      runtime_deploy_data = flatpak_deploy_get_deploy_data (runtime_deploy, FLATPAK_DEPLOY_VERSION_ANY, cancellable, error);
      if (runtime_deploy_data == NULL)
        return FALSE;

      runtime_metakey = flatpak_deploy_get_metadata (runtime_deploy);

      runtime_files = flatpak_deploy_get_files (runtime_deploy);
    }

  var = g_file_get_child (res_deploy, "var");
  var_tmp = g_file_get_child (var, "tmp");
  if (!flatpak_mkdir_p (var_tmp, cancellable, error))
    return FALSE;
  var_lib = g_file_get_child (var, "lib");
  if (!flatpak_mkdir_p (var_lib, cancellable, error))
    return FALSE;

  res_files = g_file_get_child (res_deploy, "files");

  if (is_app)
    {
      app_files = g_object_ref (res_files);
      if (opt_with_appdir)
        {
          app_id_dir = flatpak_get_data_dir (id);
          if (!flatpak_ensure_data_dir (app_id_dir, cancellable, NULL))
            g_clear_object (&app_id_dir);
        }
    }
  else if (is_extension)
    {
      g_autoptr(GKeyFile) x_metakey = NULL;
      g_autofree char *x_group = NULL;
      g_autofree char *x_dir = NULL;
      g_autofree char *x_subdir_suffix = NULL;
      char *x_subdir = NULL;
      g_autofree char *bare_extension_point = NULL;

      extensionof_deploy = flatpak_find_deploy_for_ref (extensionof_ref, NULL, NULL, cancellable, error);
      if (extensionof_deploy == NULL)
        return FALSE;

      x_metakey = flatpak_deploy_get_metadata (extensionof_deploy);

      /* Since we have tagged extensions, it is possible that an extension could
       * be listed more than once in the "parent" flatpak. In that case, we should
       * try and disambiguate using the following rules:
       *
       * 1. Use the 'tag=' key in the ExtensionOfSection and if not found:
       * 2. Use the only extension point available if there is only one.
       * 3. If there are no matching groups, return NULL.
       * 4. In all other cases, error out.
       */
      if (!find_matching_extension_group_in_metakey (x_metakey,
                                                     id,
                                                     extensionof_tag,
                                                     &x_group,
                                                     error))
        return FALSE;

      if (x_group == NULL)
        {
          /* Failed, look for subdirectories=true parent */
          char *last_dot = strrchr (id, '.');

          if (last_dot != NULL)
            {
              char *parent_id = g_strndup (id, last_dot - id);
              if (!find_matching_extension_group_in_metakey (x_metakey,
                                                             parent_id,
                                                             extensionof_tag,
                                                             &x_group,
                                                             error))
                return FALSE;

              if (x_group != NULL &&
                  g_key_file_get_boolean (x_metakey, x_group,
                                          FLATPAK_METADATA_KEY_SUBDIRECTORIES,
                                          NULL))
                x_subdir = last_dot + 1;
            }

          if (x_subdir == NULL)
            return flatpak_fail (error, _("No extension point matching %s in %s"), id, extensionof_ref);
        }

      x_dir = g_key_file_get_string (x_metakey, x_group,
                                     FLATPAK_METADATA_KEY_DIRECTORY, error);
      if (x_dir == NULL)
        return FALSE;

      x_subdir_suffix = g_key_file_get_string (x_metakey, x_group,
                                               FLATPAK_METADATA_KEY_SUBDIRECTORY_SUFFIX,
                                               NULL);

      if (is_app_extension)
        {
          app_files = flatpak_deploy_get_files (extensionof_deploy);
          app_files_ro = TRUE;
          if (x_subdir != NULL)
            extension_tmpfs_point = g_build_filename ("/app", x_dir, NULL);
          bare_extension_point = g_build_filename ("/app", x_dir, x_subdir, NULL);
        }
      else
        {
          if (x_subdir != NULL)
            extension_tmpfs_point = g_build_filename ("/usr", x_dir, NULL);
          bare_extension_point = g_build_filename ("/usr", x_dir, x_subdir, NULL);
        }

      extension_point = g_build_filename (bare_extension_point, x_subdir_suffix, NULL);
    }

  app_context = flatpak_app_compute_permissions (metakey,
                                                 runtime_metakey,
                                                 error);
  if (app_context == NULL)
    return FALSE;

  flatpak_context_merge (app_context, arg_context);

  shares = flatpak_run_compute_allowed_shares (app_context);
  devices = flatpak_run_compute_allowed_devices (app_context);
  sockets = flatpak_run_compute_allowed_sockets (app_context);
  features = flatpak_run_compute_allowed_features (app_context);

  minimal_envp = flatpak_run_get_minimal_env (TRUE, FALSE);
  bwrap = flatpak_bwrap_new (minimal_envp);
  flatpak_bwrap_add_args (bwrap, flatpak_get_bwrap (), NULL);

  run_flags =
    FLATPAK_RUN_FLAG_DEVEL | FLATPAK_RUN_FLAG_MULTIARCH | FLATPAK_RUN_FLAG_NO_SESSION_HELPER |
    FLATPAK_RUN_FLAG_SET_PERSONALITY | FLATPAK_RUN_FLAG_NO_A11Y_BUS_PROXY;
  if (opt_die_with_parent)
    run_flags |= FLATPAK_RUN_FLAG_DIE_WITH_PARENT;
  if (custom_usr)
    run_flags |= FLATPAK_RUN_FLAG_WRITABLE_ETC;

  run_flags |= flatpak_context_features_to_run_flags (features);

  /* Unless manually specified, we disable dbus proxy */
  if (!flatpak_context_get_needs_session_bus_proxy (arg_context))
    run_flags |= FLATPAK_RUN_FLAG_NO_SESSION_BUS_PROXY;

  if (!flatpak_context_get_needs_system_bus_proxy (arg_context))
    run_flags |= FLATPAK_RUN_FLAG_NO_SYSTEM_BUS_PROXY;

  if (opt_log_session_bus)
    run_flags |= FLATPAK_RUN_FLAG_LOG_SESSION_BUS;

  if (opt_log_system_bus)
    run_flags |= FLATPAK_RUN_FLAG_LOG_SYSTEM_BUS;

  /* Never set up an a11y bus for builds */
  run_flags |= FLATPAK_RUN_FLAG_NO_A11Y_BUS_PROXY;

  glnx_autofd int usr_fd = -1;
  usr_fd = open (flatpak_file_get_path_cached (runtime_files),
                 O_PATH | O_CLOEXEC | O_NOFOLLOW);
  if (usr_fd < 0)
    return glnx_throw_errno_prefix (error, "Failed to open runtime files");

  if (!flatpak_run_setup_base_argv (bwrap, usr_fd, app_id_dir, arch,
                                    run_flags, error))
    return FALSE;

  flatpak_bwrap_add_args (bwrap,
                          (custom_usr && !opt_readonly)  ? "--bind" : "--ro-bind", flatpak_file_get_path_cached (runtime_files), "/usr",
                          NULL);

  if (!custom_usr)
    flatpak_bwrap_add_args (bwrap,
                            "--lock-file", "/usr/.ref",
                            NULL);

  if (app_files)
    flatpak_bwrap_add_args (bwrap,
                            (app_files_ro || opt_readonly) ? "--ro-bind" : "--bind", flatpak_file_get_path_cached (app_files), "/app",
                            NULL);
  else
    flatpak_bwrap_add_args (bwrap,
                            "--dir", "/app",
                            NULL);

  if (extension_tmpfs_point)
    flatpak_bwrap_add_args (bwrap,
                            "--tmpfs", extension_tmpfs_point,
                            NULL);

  /* We add the actual bind below so that we're not shadowed by other extensions or their tmpfs */

  if (extension_point)
    dest = g_strdup (extension_point);
  else if (is_app)
    dest = g_strdup ("/app");
  else
    dest = g_strdup ("/usr");

  flatpak_bwrap_add_args (bwrap,
                          "--setenv", "FLATPAK_DEST", dest,
                          "--setenv", "FLATPAK_ID", id,
                          "--setenv", "FLATPAK_ARCH", arch,
                          NULL);

  /* Persist some stuff in /var. We can't persist everything because  that breaks /var things
   * from the host to work. For example the /home -> /var/home on atomic.
   * The interesting things to contain during the build is /var/tmp (for tempfiles shared during builds)
   * and things like /var/lib/rpm, if the installation uses packages.
   */
  flatpak_bwrap_add_args (bwrap,
                          "--bind", flatpak_file_get_path_cached (var_lib), "/var/lib",
                          NULL);
  flatpak_bwrap_add_args (bwrap,
                          "--bind", flatpak_file_get_path_cached (var_tmp), "/var/tmp",
                          NULL);

  flatpak_run_apply_env_vars (bwrap, app_context);

  if (is_app)
    {
      /* We don't actually know the final branchname yet, so use "nobranch" as fallback to avoid unexpected matches.
         This means any extension point used at build time must have explicit versions to work. */
      g_autoptr(FlatpakDecomposed) fake_ref =
        flatpak_decomposed_new_from_parts (FLATPAK_KINDS_APP, id, arch, "nobranch", NULL);
      if (fake_ref != NULL &&
          !flatpak_run_add_extension_args (bwrap, metakey, fake_ref, FALSE, "/app",
                                           &app_extensions, &app_ld_path,
                                           cancellable, error))
        return FALSE;
    }

  if (!custom_usr &&
      !flatpak_run_add_extension_args (bwrap, runtime_metakey, runtime_ref, FALSE, "/usr",
                                       &runtime_extensions, &runtime_ld_path,
                                       cancellable, error))
    return FALSE;

  flatpak_run_extend_ld_path (bwrap, app_ld_path, runtime_ld_path);

  /* Mount this after the above extensions so we always win */
  if (extension_point)
    flatpak_bwrap_add_args (bwrap,
                            "--bind", flatpak_file_get_path_cached (res_files), extension_point,
                            NULL);

  if (!flatpak_run_add_app_info_args (bwrap,
                                      app_files, app_files, NULL, app_extensions,
                                      runtime_files, runtime_files, runtime_deploy_data, runtime_extensions,
                                      id, NULL,
                                      runtime_ref,
                                      app_id_dir, app_context, NULL,
                                      sockets,
                                      FALSE, TRUE, TRUE,
                                      &app_info_path, -1,
                                      &instance_id_host_dir, NULL,
                                      &instance_id,
                                      error))
    return FALSE;

  if (!flatpak_run_add_environment_args (bwrap, app_info_path, run_flags, id,
                                         app_context,
                                         shares, devices, sockets, features,
                                         app_id_dir, NULL, -1,
                                         instance_id, NULL, cancellable, error))
    return FALSE;

  for (i = 0; opt_bind_mounts != NULL && opt_bind_mounts[i] != NULL; i++)
    {
      char *split = strchr (opt_bind_mounts[i], '=');
      if (split == NULL)
        {
          g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
                       _("Missing '=' in bind mount option '%s'"), opt_bind_mounts[i]);
          return FALSE;
        }

      *split++ = 0;
      flatpak_bwrap_add_args (bwrap,
                              "--bind", split, opt_bind_mounts[i],
                              NULL);
    }

  /* Add empty font-dirs.xml only if user hasn't already mapped it */
  add_empty_font_dirs_xml (bwrap);

  if (opt_build_dir != NULL)
    {
      flatpak_bwrap_add_args (bwrap,
                              "--chdir", opt_build_dir,
                              NULL);
    }

  flatpak_bwrap_populate_runtime_dir (bwrap, NULL);

  flatpak_bwrap_envp_to_args (bwrap);

  if (!flatpak_bwrap_bundle_args (bwrap, 1, -1, FALSE, error))
    return FALSE;

  flatpak_bwrap_add_args (bwrap, "--", command, NULL);

  flatpak_bwrap_append_argsv (bwrap,
                              &argv[rest_argv_start + 2],
                              rest_argc - 2);

  g_ptr_array_add (bwrap->argv, NULL);

  g_snprintf (pid_str, sizeof (pid_str), "%d", getpid ());
  pid_path = g_build_filename (instance_id_host_dir, "pid", NULL);
  g_file_set_contents (pid_path, pid_str, -1, NULL);

  /* Ensure we unset O_CLOEXEC */
  child_setup (bwrap->fds);
  if (execvpe (flatpak_get_bwrap (), (char **) bwrap->argv->pdata, bwrap->envp) == -1)
    {
      g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errno),
                   _("Unable to start app"));
      return FALSE;
    }

  /* Not actually reached... */
  return TRUE;
}

gboolean
flatpak_complete_build (FlatpakCompletion *completion)
{
  g_autoptr(GOptionContext) context = NULL;

  context = g_option_context_new ("");

  if (!flatpak_option_context_parse (context, options, &completion->argc, &completion->argv,
                                     FLATPAK_BUILTIN_FLAG_NO_DIR, NULL, NULL, NULL))
    return FALSE;

  switch (completion->argc)
    {
    case 0:
    case 1: /* DIR */
      flatpak_complete_options (completion, global_entries);
      flatpak_complete_options (completion, options);

      flatpak_complete_dir (completion);
      break;
    }

  return TRUE;
}

===== ./app/flatpak-builtins-pin.c =====
/* vi:set et sw=2 sts=2 cin cino=t0,f0,(0,{s,>2s,n-s,^-s,e-s:
 * Copyright © 2020 Endless OS Foundation LLC
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Matthew Leeds <matthew.leeds@endlessm.com>
 */

#include "config.h"

#include <locale.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

#include <glib/gi18n.h>

#include "libglnx.h"

#include "flatpak-builtins.h"
#include "flatpak-builtins-utils.h"
#include "flatpak-cli-transaction.h"
#include "flatpak-quiet-transaction.h"
#include "flatpak-utils-private.h"
#include "flatpak-error.h"

/* Note: the code here is copied from flatpak-builtins-mask.c */

static gboolean opt_remove;

static GOptionEntry options[] = {
  { "remove", 0, 0, G_OPTION_ARG_NONE, &opt_remove, N_("Remove matching pins"), NULL },
  { NULL }
};

gboolean
flatpak_builtin_pin (int argc, char **argv, GCancellable *cancellable, GError **error)
{
  g_autoptr(GOptionContext) context = NULL;
  g_autoptr(GPtrArray) dirs = NULL;
  FlatpakDir *dir;
  int i;

  context = g_option_context_new (_("[PATTERN…] - disable automatic removal of runtimes matching patterns"));
  g_option_context_set_translation_domain (context, GETTEXT_PACKAGE);

  if (!flatpak_option_context_parse (context, options, &argc, &argv,
                                     FLATPAK_BUILTIN_FLAG_ONE_DIR,
                                     &dirs, cancellable, error))
    return FALSE;

  dir = g_ptr_array_index (dirs, 0);

  if (argc == 1)
    {
      g_autoptr(GPtrArray) patterns = NULL;

      patterns = flatpak_dir_get_config_patterns (dir, "pinned");

      if (patterns->len == 0)
        {
          if (flatpak_fancy_output ())
            g_print (_("No pinned patterns\n"));
        }
      else
        {
          if (flatpak_fancy_output ())
            g_print (_("Pinned patterns:\n"));

          for (i = 0; i < patterns->len; i++)
            {
              const char *old = g_ptr_array_index (patterns, i);
              g_print ("  %s\n", old);
            }
        }
    }
  else
    {
      for (i = 1; i < argc; i++)
        {
          const char *pattern = argv[i];

          if (opt_remove)
            {
              if (!flatpak_dir_config_remove_pattern (dir, "pinned", pattern, error))
                return FALSE;
            }
          else if (!flatpak_dir_config_append_pattern (dir, "pinned", pattern,
                                                       TRUE, /* only match runtimes */
                                                       NULL, error))
            return FALSE;
        }
    }

  return TRUE;
}

gboolean
flatpak_complete_pin (FlatpakCompletion *completion)
{
  g_autoptr(GOptionContext) context = NULL;
  g_autoptr(GPtrArray) dirs = NULL;

  context = g_option_context_new ("");
  if (!flatpak_option_context_parse (context, options, &completion->argc, &completion->argv,
                                     FLATPAK_BUILTIN_FLAG_ONE_DIR | FLATPAK_BUILTIN_FLAG_OPTIONAL_REPO,
                                     &dirs, NULL, NULL))
    return FALSE;

  switch (completion->argc)
    {
    case 0:
    case 1: /* PATTERN */
      flatpak_complete_options (completion, global_entries);
      flatpak_complete_options (completion, options);
      flatpak_complete_options (completion, user_entries);
      break;
    }

  return TRUE;
}

===== ./app/flatpak-tty-utils-private.h =====
/*
 * Copyright © 2014 Red Hat, Inc
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 */

#pragma once

#include "libglnx.h"
#include "flatpak-utils-private.h"

#define FLATPAK_ANSI_ALT_SCREEN_ON "\x1b[?1049h"
#define FLATPAK_ANSI_ALT_SCREEN_OFF "\x1b[?1049l"
#define FLATPAK_ANSI_HIDE_CURSOR "\x1b[?25l"
#define FLATPAK_ANSI_SHOW_CURSOR "\x1b[?25h"
#define FLATPAK_ANSI_BOLD_ON "\x1b[1m"
#define FLATPAK_ANSI_BOLD_OFF "\x1b[22m"
#define FLATPAK_ANSI_FAINT_ON "\x1b[2m"
#define FLATPAK_ANSI_FAINT_OFF "\x1b[22m"
#define FLATPAK_ANSI_RED "\x1b[31m"
#define FLATPAK_ANSI_GREEN "\x1b[32m"
#define FLATPAK_ANSI_COLOR_RESET "\x1b[0m"

#define FLATPAK_ANSI_ROW_N "\x1b[%d;1H"
#define FLATPAK_ANSI_CLEAR "\x1b[0J"

gboolean flatpak_set_tty_echo (gboolean echo);
void flatpak_get_window_size (int *rows,
                              int *cols);
gboolean flatpak_get_cursor_pos (int *row,
                                 int *col);
void flatpak_hide_cursor (void);
void flatpak_show_cursor (void);

void flatpak_enable_raw_mode (void);
void flatpak_disable_raw_mode (void);

void     flatpak_disable_fancy_output (void);
void     flatpak_enable_fancy_output (void);
gboolean flatpak_fancy_output (void);

gboolean flatpak_allow_fuzzy_matching (const char *term);

char * flatpak_prompt (gboolean allow_empty,
                       const char *prompt,
                       ...) G_GNUC_PRINTF (2, 3);

char * flatpak_password_prompt (const char *prompt,
                                ...) G_GNUC_PRINTF (1, 2);

gboolean flatpak_yes_no_prompt (gboolean    default_yes,
                                const char *prompt,
                                ...) G_GNUC_PRINTF (2, 3);

long flatpak_number_prompt (gboolean    default_yes,
                            int         min,
                            int         max,
                            const char *prompt,
                            ...) G_GNUC_PRINTF (4, 5);
int *flatpak_numbers_prompt (gboolean    default_yes,
                             int         min,
                             int         max,
                             const char *prompt,
                             ...) G_GNUC_PRINTF (4, 5);
int *flatpak_parse_numbers (const char *buf,
                            int         min,
                            int         max);

void flatpak_format_choices (const char **choices,
                             const char  *prompt,
                             ...) G_GNUC_PRINTF (2, 3);

void   flatpak_print_escaped_string (const char        *s,
                                     FlatpakEscapeFlags flags);

void flatpak_pty_set_progress (guint percent);

void flatpak_pty_clear_progress (void);

===== ./app/flatpak-builtins-install.c =====
/* vi:set et sw=2 sts=2 cin cino=t0,f0,(0,{s,>2s,n-s,^-s,e-s:
 * Copyright © 2014 Red Hat, Inc
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Alexander Larsson <alexl@redhat.com>
 */

#include "config.h"

#include <locale.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

#include <glib/gi18n.h>

#include <gio/gunixinputstream.h>

#include "libglnx.h"

#include "flatpak-builtins.h"
#include "flatpak-builtins-utils.h"
#include "flatpak-transaction-private.h"
#include "flatpak-cli-transaction.h"
#include "flatpak-quiet-transaction.h"
#include "flatpak-utils-http-private.h"
#include "flatpak-utils-private.h"
#include "flatpak-error.h"
#include "flatpak-chain-input-stream-private.h"

static char *opt_arch;
static char **opt_gpg_file;
static char **opt_subpaths;
static char **opt_sideload_repos;
static gboolean opt_no_pull;
static gboolean opt_no_deploy;
static gboolean opt_no_related;
static gboolean opt_no_deps;
static gboolean opt_no_static_deltas;
static gboolean opt_runtime;
static gboolean opt_app;
static gboolean opt_include_sdk;
static gboolean opt_include_debug;
static gboolean opt_bundle;
static gboolean opt_from;
static gboolean opt_image;
static gboolean opt_yes;
static gboolean opt_reinstall;
static gboolean opt_noninteractive;
static gboolean opt_or_update;
static gboolean opt_no_auto_pin;

static GOptionEntry options[] = {
  { "arch", 0, 0, G_OPTION_ARG_STRING, &opt_arch, N_("Arch to install for"), N_("ARCH") },
  { "no-pull", 0, 0, G_OPTION_ARG_NONE, &opt_no_pull, N_("Don't pull, only install from local cache"), NULL },
  { "no-deploy", 0, 0, G_OPTION_ARG_NONE, &opt_no_deploy, N_("Don't deploy, only download to local cache"), NULL },
  { "no-related", 0, 0, G_OPTION_ARG_NONE, &opt_no_related, N_("Don't install related refs"), NULL },
  { "no-deps", 0, 0, G_OPTION_ARG_NONE, &opt_no_deps, N_("Don't verify/install runtime dependencies"), NULL },
  { "no-auto-pin", 0, 0, G_OPTION_ARG_NONE, &opt_no_auto_pin, N_("Don't automatically pin explicit installs"), NULL },
  { "no-static-deltas", 0, 0, G_OPTION_ARG_NONE, &opt_no_static_deltas, N_("Don't use static deltas"), NULL },
  { "runtime", 0, 0, G_OPTION_ARG_NONE, &opt_runtime, N_("Look for runtime with the specified name"), NULL },
  { "app", 0, 0, G_OPTION_ARG_NONE, &opt_app, N_("Look for app with the specified name"), NULL },
  { "include-sdk", 0, 0, G_OPTION_ARG_NONE, &opt_include_sdk, N_("Additionally install the SDK used to build the given refs") },
  { "include-debug", 0, 0, G_OPTION_ARG_NONE, &opt_include_debug, N_("Additionally install the debug info for the given refs and their dependencies") },
  { "bundle", 0, 0, G_OPTION_ARG_NONE, &opt_bundle, N_("Assume LOCATION is a .flatpak single-file bundle"), NULL },
  { "from", 0, 0, G_OPTION_ARG_NONE, &opt_from, N_("Assume LOCATION is a .flatpakref application description"), NULL },
  { "image", 0, 0, G_OPTION_ARG_NONE, &opt_image, N_("Assume LOCATION is containers-transports(5) reference to an OCI image"), NULL },
  { "gpg-file", 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &opt_gpg_file, N_("Check bundle signatures with GPG key from FILE (- for stdin)"), N_("FILE") },
  { "subpath", 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &opt_subpaths, N_("Only install this subpath"), N_("PATH") },
  { "assumeyes", 'y', 0, G_OPTION_ARG_NONE, &opt_yes, N_("Automatically answer yes for all questions"), NULL },
  { "reinstall", 0, 0, G_OPTION_ARG_NONE, &opt_reinstall, N_("Uninstall first if already installed"), NULL },
  { "noninteractive", 0, 0, G_OPTION_ARG_NONE, &opt_noninteractive, N_("Produce minimal output and don't ask questions"), NULL },
  { "or-update", 0, 0, G_OPTION_ARG_NONE, &opt_or_update, N_("Update install if already installed"), NULL },
  /* Translators: A sideload is when you install from a local USB drive rather than the Internet. */
  { "sideload-repo", 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &opt_sideload_repos, N_("Use this local repo for sideloads"), N_("PATH") },
  { NULL }
};

static GBytes *
read_gpg_data (GCancellable *cancellable,
               GError      **error)
{
  g_autoptr(GInputStream) source_stream = NULL;
  guint n_keyrings = 0;
  g_autoptr(GPtrArray) streams = NULL;

  if (opt_gpg_file != NULL)
    n_keyrings = g_strv_length (opt_gpg_file);

  guint ii;

  streams = g_ptr_array_new_with_free_func (g_object_unref);

  for (ii = 0; ii < n_keyrings; ii++)
    {
      GInputStream *input_stream = NULL;

      if (strcmp (opt_gpg_file[ii], "-") == 0)
        {
          input_stream = g_unix_input_stream_new (STDIN_FILENO, FALSE);
        }
      else
        {
          g_autoptr(GFile) file = g_file_new_for_commandline_arg (opt_gpg_file[ii]);
          input_stream = G_INPUT_STREAM (g_file_read (file, cancellable, error));

          if (input_stream == NULL)
            return NULL;
        }

      /* Takes ownership. */
      g_ptr_array_add (streams, input_stream);
    }

  /* Chain together all the --keyring options as one long stream. */
  source_stream = (GInputStream *) flatpak_chain_input_stream_new (streams);

  return flatpak_read_stream (source_stream, FALSE, error);
}

static FlatpakTransaction *
create_install_transaction (FlatpakDir    *dir,
                            GCancellable  *cancellable,
                            GError       **error)
{
  g_autoptr(FlatpakTransaction) transaction = NULL;

  if (opt_noninteractive)
    transaction = flatpak_quiet_transaction_new (dir, error);
  else
    transaction = flatpak_cli_transaction_new (dir, opt_yes, TRUE, opt_arch != NULL, error);

  if (transaction == NULL)
    return NULL;

  flatpak_transaction_set_no_pull (transaction, opt_no_pull);
  flatpak_transaction_set_no_deploy (transaction, opt_no_deploy);
  flatpak_transaction_set_disable_static_deltas (transaction, opt_no_static_deltas);
  flatpak_transaction_set_disable_dependencies (transaction, opt_no_deps);
  flatpak_transaction_set_disable_related (transaction, opt_no_related);
  flatpak_transaction_set_disable_auto_pin (transaction, opt_no_auto_pin);
  flatpak_transaction_set_reinstall (transaction, opt_reinstall);
  flatpak_transaction_set_auto_install_sdk (transaction, opt_include_sdk);
  flatpak_transaction_set_auto_install_debug (transaction, opt_include_debug);

  if (!setup_sideload_repositories (transaction, opt_sideload_repos, cancellable, error))
    return FALSE;

  return g_steal_pointer (&transaction);
}

static gboolean
install_bundle (FlatpakDir *dir,
                GOptionContext *context,
                int argc, char **argv,
                GCancellable *cancellable,
                GError **error)
{
  g_autoptr(GFile) file = NULL;
  const char *filename;
  g_autoptr(GBytes) gpg_data = NULL;
  g_autoptr(FlatpakTransaction) transaction = NULL;

  if (argc < 2)
    return usage_error (context, _("Bundle filename must be specified"), error);

  if (argc > 2)
    return usage_error (context, _("Too many arguments"), error);

  filename = argv[1];

  file = g_file_new_for_commandline_arg (filename);

  if (!g_file_is_native (file))
    return flatpak_fail (error, _("Remote bundles are not supported"));

  if (opt_gpg_file != NULL)
    {
      /* Override gpg_data from file */
      gpg_data = read_gpg_data (cancellable, error);
      if (gpg_data == NULL)
        return FALSE;
    }

  transaction = create_install_transaction (dir, cancellable, error);
  if (transaction == NULL)
    return FALSE;

  if (!flatpak_transaction_add_install_bundle (transaction, file, gpg_data, error))
    return FALSE;

  if (!flatpak_transaction_run (transaction, cancellable, error))
    {
      if (g_error_matches (*error, FLATPAK_ERROR, FLATPAK_ERROR_ABORTED))
        g_clear_error (error); /* Don't report on stderr */

      return FALSE;
    }

  return TRUE;
}

static gboolean
install_from (FlatpakDir *dir,
              GOptionContext *context,
              int argc, char **argv,
              GCancellable *cancellable,
              GError **error)
{
  g_autoptr(GFile) file = NULL;
  g_autoptr(GBytes) file_data = NULL;
  g_autofree char *data = NULL;
  gsize data_len;
  const char *filename;
  g_autoptr(FlatpakTransaction) transaction = NULL;

  if (argc < 2)
    return usage_error (context, _("Filename or uri must be specified"), error);

  if (argc > 2)
    return usage_error (context, _("Too many arguments"), error);


  filename = argv[1];

  if (g_str_has_prefix (filename, "flatpak+https:"))
    filename += strlen ("flatpak+");

  if (g_str_has_prefix (filename, "http:") ||
      g_str_has_prefix (filename, "https:"))
    {
      g_autoptr(FlatpakHttpSession) http_session = NULL;
      http_session = flatpak_create_http_session (PACKAGE_STRING);
      file_data = flatpak_load_uri (http_session, filename, 0, NULL, NULL, NULL, NULL, cancellable, error);
      if (file_data == NULL)
        {
          g_prefix_error (error, "Can't load uri %s: ", filename);
          return FALSE;
        }
    }
  else
    {
      file = g_file_new_for_commandline_arg (filename);

      if (!g_file_load_contents (file, cancellable, &data, &data_len, NULL, error))
        return FALSE;

      file_data = g_bytes_new_take (g_steal_pointer (&data), data_len);
    }

  transaction = create_install_transaction (dir, cancellable, error);
  if (transaction == NULL)
    return FALSE;

  if (!flatpak_transaction_add_install_flatpakref (transaction, file_data, error))
    return FALSE;

  if (!flatpak_transaction_run (transaction, cancellable, error))
    {
      if (g_error_matches (*error, FLATPAK_ERROR, FLATPAK_ERROR_ABORTED))
        g_clear_error (error); /* Don't report on stderr */

      return FALSE;
    }

  return TRUE;
}

static gboolean
install_image (FlatpakDir      *dir,
               GOptionContext  *context,
               int              argc,
               char           **argv,
               GCancellable    *cancellable,
               GError         **error)
{
  const char *location;
  g_autoptr(GBytes) gpg_data = NULL;
  g_autoptr(FlatpakTransaction) transaction = NULL;

  if (argc < 2)
    return usage_error (context, _("Image location must be specified"), error);

  if (argc > 2)
    return usage_error (context, _("Too many arguments"), error);

  location = argv[1];

  if (opt_gpg_file != NULL)
    {
      /* Override gpg_data from file */
      gpg_data = read_gpg_data (cancellable, error);
      if (gpg_data == NULL)
        return FALSE;
    }

  transaction = create_install_transaction (dir, cancellable, error);
  if (transaction == NULL)
    return FALSE;

  if (!flatpak_transaction_add_install_image (transaction, location, error))
    return FALSE;

  if (!flatpak_transaction_run (transaction, cancellable, error))
    {
      if (g_error_matches (*error, FLATPAK_ERROR, FLATPAK_ERROR_ABORTED))
        g_clear_error (error); /* Don't report on stderr */

      return FALSE;
    }

  return TRUE;
}

gboolean
flatpak_builtin_install (int argc, char **argv, GCancellable *cancellable, GError **error)
{
  g_autoptr(GOptionContext) context = NULL;
  g_autoptr(GPtrArray) dirs = NULL;
  g_autoptr(FlatpakDir) dir = NULL;
  g_autofree char *remote = NULL;
  g_autofree char *remote_url = NULL;
  char **prefs = NULL;
  int i, n_prefs;
  g_autofree char *target_branch = NULL;
  g_autofree char *default_branch = NULL;
  FlatpakKinds kinds;
  g_autoptr(FlatpakTransaction) transaction = NULL;
  g_autoptr(FlatpakDir) dir_with_remote = NULL;
  gboolean auto_remote = FALSE;

  context = g_option_context_new (_("[LOCATION/REMOTE] [REF…] - Install applications or runtimes"));
  g_option_context_set_translation_domain (context, GETTEXT_PACKAGE);

  if (!flatpak_option_context_parse (context, options, &argc, &argv,
                                     FLATPAK_BUILTIN_FLAG_ALL_DIRS | FLATPAK_BUILTIN_FLAG_OPTIONAL_REPO,
                                     &dirs, cancellable, error))
    return FALSE;

  /* Start with the default or specified dir, this is fine for opt_bundle or opt_from */
  dir = g_object_ref (g_ptr_array_index (dirs, 0));

  if (!opt_bundle && !opt_from && !opt_image && argc >= 2)
    {
      if (g_str_has_prefix (argv[1], "oci:") ||
          g_str_has_prefix (argv[1], "oci-archive:") ||
          g_str_has_prefix (argv[1], "docker:"))
        opt_image = TRUE;
      else if (flatpak_file_arg_has_suffix (argv[1], ".flatpakref"))
        opt_from = TRUE;
      else if (flatpak_file_arg_has_suffix (argv[1], ".flatpak"))
        opt_bundle = TRUE;
    }

  if (opt_bundle)
    return install_bundle (dir, context, argc, argv, cancellable, error);

  if (opt_from)
    return install_from (dir, context, argc, argv, cancellable, error);

  if (opt_image)
    return install_image (dir, context, argc, argv, cancellable, error);

  if (argc < 2)
    return usage_error (context, _("At least one REF must be specified"), error);

  if (argc == 2)
    auto_remote = TRUE;

  if (opt_noninteractive)
    opt_yes = TRUE; /* Implied */

  if (opt_include_sdk || opt_include_debug)
    opt_or_update = TRUE;

  kinds = flatpak_kinds_from_bools (opt_app, opt_runtime);

  if (!opt_noninteractive)
    g_print (_("Looking for matches…\n"));

  if (!auto_remote &&
      (g_path_is_absolute (argv[1]) ||
       g_str_has_prefix (argv[1], "./")))
    {
      g_autoptr(GFile) remote_file = g_file_new_for_commandline_arg (argv[1]);
      remote_url = g_file_get_uri (remote_file);
      remote = g_strdup (remote_url);
    }
  else
    {
      /* If the remote was used, and no single dir was specified, find which
       * one based on the remote. If the remote isn't found assume it's a ref
       * and we should auto-detect the remote. */
      if (!auto_remote)
        {
          g_autoptr(GError) local_error = NULL;
          if (!flatpak_resolve_duplicate_remotes (dirs, argv[1], opt_noninteractive, &dir_with_remote, cancellable, &local_error))
            {
              if (g_error_matches (local_error, FLATPAK_ERROR, FLATPAK_ERROR_REMOTE_NOT_FOUND))
                {
                  auto_remote = TRUE;
                }
              else
                {
                  g_propagate_error (error, g_steal_pointer (&local_error));
                  return FALSE;
                }
            }
        }

      if (!auto_remote)
        {
          remote = g_strdup (argv[1]);
          g_clear_object (&dir);
          dir = g_object_ref (dir_with_remote);
        }
      else
        {
          g_autoptr(GPtrArray) remote_dir_pairs = NULL;
          RemoteDirPair *chosen_pair = NULL;

          remote_dir_pairs = g_ptr_array_new_with_free_func ((GDestroyNotify) remote_dir_pair_free);

          /* Search all remotes for a matching ref. This is imperfect
           * because it only takes the first specified ref into account and
           * doesn't distinguish between an exact match and a fuzzy match, but
           * that's okay because the user will be asked to confirm the remote
           */
          for (i = 0; i < dirs->len; i++)
            {
              FlatpakDir *this_dir = g_ptr_array_index (dirs, i);
              g_auto(GStrv) remotes = NULL;
              guint j = 0;
              FindMatchingRefsFlags matching_refs_flags;

              remotes = flatpak_dir_list_remotes (this_dir, cancellable, error);
              if (remotes == NULL)
                return FALSE;

              if (!flatpak_allow_fuzzy_matching (argv[1]))
                matching_refs_flags = FIND_MATCHING_REFS_FLAGS_NONE;
              else
                matching_refs_flags = FIND_MATCHING_REFS_FLAGS_FUZZY;

              for (j = 0; remotes[j] != NULL; j++)
                {
                  const char *this_remote = remotes[j];
                  g_autofree char *this_default_branch = NULL;
                  g_autofree char *id = NULL;
                  g_autofree char *arch = NULL;
                  g_autofree char *branch = NULL;
                  FlatpakKinds matched_kinds;
                  g_autoptr(GPtrArray) refs = NULL;
                  g_autoptr(GError) local_error = NULL;

                  if (flatpak_dir_get_remote_disabled (this_dir, this_remote) ||
                      flatpak_dir_get_remote_noenumerate (this_dir, this_remote))
                    continue;

                  this_default_branch = flatpak_dir_get_remote_default_branch (this_dir, this_remote);

                  flatpak_split_partial_ref_arg_novalidate (argv[1], kinds, opt_arch, target_branch,
                                                            &matched_kinds, &id, &arch, &branch);

                  if (opt_no_pull)
                    refs = flatpak_dir_find_local_refs (this_dir, this_remote, id, branch, this_default_branch, arch,
                                                        flatpak_get_default_arch (),
                                                        matched_kinds, matching_refs_flags,
                                                        cancellable, &local_error);
                  else
                    {
                      g_autoptr(FlatpakRemoteState) state = get_remote_state (this_dir, this_remote, FALSE, FALSE,
                                                                              arch, (const char **)opt_sideload_repos,
                                                                              cancellable, error);
                      if (state == NULL)
                        return FALSE;

                      refs = flatpak_dir_find_remote_refs (this_dir, state, id, branch, this_default_branch, arch,
                                                           flatpak_get_default_arch (),
                                                           matched_kinds, matching_refs_flags,
                                                           cancellable, &local_error);
                      if (refs == NULL)
                        {
                          g_warning ("An error was encountered searching remote ‘%s’ for ‘%s’: %s", this_remote, argv[1], local_error->message);
                          continue;
                        }
                    }

                  if (refs->len == 0)
                    continue;
                  else
                    {
                      RemoteDirPair *pair = remote_dir_pair_new (this_remote, this_dir);
                      g_ptr_array_add (remote_dir_pairs, pair);
                    }
                }
            }

          if (remote_dir_pairs->len == 0)
            return flatpak_fail (error, _("No remote refs found for ‘%s’"), argv[1]);

          if (!flatpak_resolve_matching_remotes (remote_dir_pairs, argv[1], opt_noninteractive, &chosen_pair, error))
            return FALSE;

          remote = g_strdup (chosen_pair->remote_name);
          g_clear_object (&dir);
          dir = g_object_ref (chosen_pair->dir);
        }
    }

  if (auto_remote)
    {
      prefs = &argv[1];
      n_prefs = argc - 1;
    }
  else
    {
      prefs = &argv[2];
      n_prefs = argc - 2;
    }

  /* Backwards compat for old "REMOTE NAME [BRANCH]" argument version */
  if (argc == 4 && flatpak_is_valid_name (argv[2], -1, NULL) && looks_like_branch (argv[3]))
    {
      target_branch = g_strdup (argv[3]);
      n_prefs = 1;
    }

  default_branch = flatpak_dir_get_remote_default_branch (dir, remote);

  transaction = create_install_transaction (dir, cancellable, error);
  if (transaction == NULL)
    return FALSE;

  for (i = 0; i < n_prefs; i++)
    {
      const char *pref = prefs[i];
      FlatpakKinds matched_kinds;
      g_autofree char *id = NULL;
      g_autofree char *arch = NULL;
      g_autofree char *branch = NULL;
      g_autofree char *ref = NULL;
      g_autoptr(GPtrArray) refs = NULL;
      g_autoptr(GError) local_error = NULL;
      FindMatchingRefsFlags matching_refs_flags;

      if (!flatpak_allow_fuzzy_matching (pref))
        matching_refs_flags = FIND_MATCHING_REFS_FLAGS_NONE;
      else
        matching_refs_flags = FIND_MATCHING_REFS_FLAGS_FUZZY;

      if (matching_refs_flags & FIND_MATCHING_REFS_FLAGS_FUZZY)
        {
          flatpak_split_partial_ref_arg_novalidate (pref, kinds, opt_arch, target_branch,
                                                    &matched_kinds, &id, &arch, &branch);

          /* We used _novalidate so that the id can be partial, but we can still validate the branch */
          if (branch != NULL && !flatpak_is_valid_branch (branch, -1, &local_error))
            return flatpak_fail_error (error, FLATPAK_ERROR_INVALID_REF,
                                       _("Invalid branch %s: %s"), branch, local_error->message);
        }
      else if (!flatpak_split_partial_ref_arg (pref, kinds, opt_arch, target_branch,
                                               &matched_kinds, &id, &arch, &branch, error))
        {
          return FALSE;
        }

      if (opt_no_pull)
        refs = flatpak_dir_find_local_refs (dir, remote, id, branch, default_branch, arch,
                                            flatpak_get_default_arch (),
                                            matched_kinds, matching_refs_flags,
                                            cancellable, error);
      else
        {
          g_autoptr(FlatpakRemoteState) state = NULL;

          state = flatpak_transaction_ensure_remote_state (transaction, FLATPAK_TRANSACTION_OPERATION_INSTALL,
                                                           remote, arch, error);
          if (state == NULL)
            return FALSE;

          refs = flatpak_dir_find_remote_refs (dir, state, id, branch, default_branch, arch,
                                               flatpak_get_default_arch (),
                                               matched_kinds, matching_refs_flags,
                                               cancellable, error);
          if (refs == NULL)
            return FALSE;
        }

      if (refs->len == 0)
        {
          if (opt_no_pull)
            g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND, _("Nothing matches %s in local repository for remote %s"), id, remote);
          else
            g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND, _("Nothing matches %s in remote %s"), id, remote);
          return FALSE;
        }

      if (!flatpak_resolve_matching_refs (remote, dir, opt_yes, refs, id, opt_noninteractive, &ref, error))
        return FALSE;

      if (!flatpak_transaction_add_install (transaction, remote, ref, (const char **) opt_subpaths, &local_error))
        {
          if (!g_error_matches (local_error, FLATPAK_ERROR, FLATPAK_ERROR_ALREADY_INSTALLED))
            {
              g_propagate_error (error, g_steal_pointer (&local_error));
              return FALSE;
            }

          if (opt_or_update)
            {
              if (!flatpak_transaction_add_update (transaction, ref, (const char **) opt_subpaths, NULL, error))
                return FALSE;
            }
          else
            g_printerr (_("Skipping: %s\n"), local_error->message);
        }
    }

  if (!flatpak_transaction_run (transaction, cancellable, error))
    {
      if (g_error_matches (*error, FLATPAK_ERROR, FLATPAK_ERROR_ABORTED))
        g_clear_error (error); /* Don't report on stderr */

      return FALSE;
    }

  return TRUE;
}

gboolean
flatpak_complete_install (FlatpakCompletion *completion)
{
  g_autoptr(GOptionContext) context = NULL;
  g_autoptr(GPtrArray) dirs = NULL;
  FlatpakDir *dir;
  FlatpakKinds kinds;
  int i;

  context = g_option_context_new ("");
  if (!flatpak_option_context_parse (context, options, &completion->argc, &completion->argv,
                                     FLATPAK_BUILTIN_FLAG_ONE_DIR | FLATPAK_BUILTIN_FLAG_OPTIONAL_REPO,
                                     &dirs, NULL, NULL))
    return FALSE;

  dir = g_ptr_array_index (dirs, 0);

  kinds = flatpak_kinds_from_bools (opt_app, opt_runtime);

  switch (completion->argc)
    {
    case 0:
    case 1: /* LOCATION/REMOTE */
      flatpak_complete_options (completion, global_entries);
      flatpak_complete_options (completion, options);
      flatpak_complete_options (completion, user_entries);

      flatpak_complete_file (completion, "__FLATPAK_BUNDLE_OR_REF_FILE");

      {
        g_auto(GStrv) remotes = flatpak_dir_list_remotes (dir, NULL, NULL);
        if (remotes != NULL)
          {
            for (i = 0; remotes[i] != NULL; i++)
              flatpak_complete_word (completion, "%s ", remotes[i]);
          }
      }

      break;

    default: /* REF */
      flatpak_complete_partial_ref (completion, kinds, opt_arch, dir, completion->argv[1]);
      break;
    }

  return TRUE;
}

===== ./app/flatpak-builtins-config.c =====
/* vi:set et sw=2 sts=2 cin cino=t0,f0,(0,{s,>2s,n-s,^-s,e-s:
 * Copyright © 2017 Red Hat, Inc
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Alexander Larsson <alexl@redhat.com>
 */

#include "config.h"

#include <locale.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include <glib/gi18n.h>

#include "libglnx.h"

#include "flatpak-builtins.h"
#include "common/flatpak-dir-private.h"

static gboolean opt_get;
static gboolean opt_set;
static gboolean opt_unset;
static gboolean opt_list;

static GOptionEntry options[] = {
  { "list", 0, 0, G_OPTION_ARG_NONE, &opt_list, N_("List configuration keys and values"), NULL },
  { "get", 0, 0, G_OPTION_ARG_NONE, &opt_get, N_("Get configuration for KEY"), NULL },
  { "set", 0, 0, G_OPTION_ARG_NONE, &opt_set, N_("Set configuration for KEY to VALUE"), NULL },
  { "unset", 0, 0, G_OPTION_ARG_NONE, &opt_unset, N_("Unset configuration for KEY"), NULL },
  { NULL }
};

static gboolean
looks_like_a_language (const char *s)
{
  int len = strlen (s);
  int i;

  if (g_str_equal (s, "C") ||
      g_str_equal (s, "POSIX"))
    return TRUE;

  if (len < 2)
    return FALSE;

  for (i = 0; i < len; i++)
    {
      if (!g_ascii_isalpha (s[i]) || !g_ascii_islower (s[i]))
        return FALSE;
    }

  return TRUE;
}

static gboolean
looks_like_a_territory (const char *s)
{
  gsize len = strlen (s);
  gsize i;

  if (len < 2)
    return FALSE;

  for (i = 0; i < len; i++)
    {
      if (!g_ascii_isalpha (s[i]) || !g_ascii_isupper (s[i]))
        return FALSE;
    }

  return TRUE;
}

static gboolean
looks_like_a_codeset_or_modifier (const char *s)
{
  gsize len = strlen (s);
  gsize i;

  if (len < 1)
    return FALSE;

  for (i = 0; i < len; i++)
    {
      if (!g_ascii_isalnum (s[i]) && s[i] != '-')
        return FALSE;
    }

  return TRUE;
}

static gboolean
looks_like_a_locale (const char *s)
{
  g_autofree gchar *locale = g_strdup (s);
  gchar *language, *territory, *codeset, *modifier;

  modifier = strchr (locale, '@');
  if (modifier != NULL)
    *modifier++ = '\0';

  codeset = strchr (locale, '.');
  if (codeset != NULL)
    *codeset++ = '\0';

  territory = strchr (locale, '_');
  if (territory != NULL)
    *territory++ = '\0';

  language = locale;

  if (!looks_like_a_language (language))
    return FALSE;
  if (territory != NULL && !looks_like_a_territory (territory))
    return FALSE;
  if (codeset != NULL && !looks_like_a_codeset_or_modifier (codeset))
    return FALSE;
  if (modifier != NULL && !looks_like_a_codeset_or_modifier (modifier))
    return FALSE;

  return TRUE;
}

static char *
parse_locale (const char *value, GError **error)
{
  g_auto(GStrv) strs = NULL;
  int i;

  strs = g_strsplit (value, ";", 0);
  for (i = 0; strs[i]; i++)
    {
      if (!looks_like_a_language (strs[i]) && !looks_like_a_locale (strs[i]))
        {
          flatpak_fail (error, _("'%s' does not look like a language/locale code"), strs[i]);
          return NULL;
        }
    }

  return g_strdup (value);
}

static char *
parse_lang (const char *value, GError **error)
{
  g_auto(GStrv) strs = NULL;
  int i;

  if (strcmp (value, "*") == 0 ||
      strcmp (value, "*all*") == 0)
    return g_strdup ("");

  strs = g_strsplit (value, ";", 0);
  for (i = 0; strs[i]; i++)
    {
      if (!looks_like_a_language (strs[i]))
        {
          flatpak_fail (error, _("'%s' does not look like a language code"), strs[i]);
          return NULL;
        }
    }

  return g_strdup (value);
}

static char *
parse_boolean (const char  *value,
               GError     **error)
{
  if (g_strcmp0 (value, "true") == 0)
    return g_strdup ("true");
  else if (g_strcmp0 (value, "false") == 0)
    return g_strdup ("false");
  else
    {
      flatpak_fail (error, _("'%s' is not a valid value (use 'true' or 'false')"), value);
      return NULL;
    }
}

static char *
print_locale (const char *value)
{
  return g_strdup (value);
}

static char *
print_lang (const char *value)
{
  if (*value == 0)
    return g_strdup ("*all*");
  return g_strdup (value);
}

static char *
print_boolean (const char *value)
{
  if (!value)
    return g_strdup ("*unset*");
  
  if (g_strcmp0 (value, "true") == 0)
    return g_strdup ("true");
  else if (g_strcmp0 (value, "false") == 0)
    return g_strdup ("false");
  else
    return g_strdup ("*invalid*");
}

static char *
get_lang_default (FlatpakDir *dir)
{
  g_auto(GStrv) langs = flatpak_dir_get_default_locale_languages (dir);

  return g_strjoinv (";", langs);
}

static char *
get_report_os_info_default (FlatpakDir *dir)
{
  return g_strdup ("true");
}

typedef struct
{
  const char *name;
  char *(*parse)(const char *value, GError **error);
  char *(*print)(const char *value);
  char *(*get_default)(FlatpakDir * dir);
} ConfigKey;

ConfigKey keys[] = {
  { "languages", parse_lang, print_lang, get_lang_default },
  { "extra-languages", parse_locale, print_locale, NULL },
  { "report-os-info", parse_boolean, print_boolean, get_report_os_info_default },
};

static ConfigKey *
get_config_key (const char *arg, GError **error)
{
  int i;

  for (i = 0; i < G_N_ELEMENTS (keys); i++)
    {
      if (strcmp (keys[i].name, arg) == 0)
        return &keys[i];
    }

  flatpak_fail (error, _("Unknown configure key '%s'"), arg);
  return NULL;
}

static char *
print_config (FlatpakDir *dir, ConfigKey *key)
{
  g_autofree char *value = NULL;

  value = flatpak_dir_get_config (dir, key->name, NULL);
  if (value == NULL)
    return g_strdup ("*unset*");

  return key->print (value);
}

static gboolean
list_config (GOptionContext *context, int argc, char **argv, FlatpakDir *dir, GCancellable *cancellable, GError **error)
{
  int i;

  if (argc != 1)
    return usage_error (context, _("Too many arguments for --list"), error);

  for (i = 0; i < G_N_ELEMENTS (keys); i++)
    {
      const char *key = keys[i].name;
      g_autofree char *value = print_config (dir, &keys[i]);
      g_autofree char *default_value = NULL;

      g_print ("%s: %s", key, value);

      if (keys[i].get_default)
        default_value = keys[i].get_default (dir);
      if (default_value)
        {
          g_autofree char *printed = keys[i].print (default_value);
          g_print (" (default: %s)", printed);
        }
      g_print ("\n");
    }

  return TRUE;
}

static gboolean
get_config (GOptionContext *context, int argc, char **argv, FlatpakDir *dir, GCancellable *cancellable, GError **error)
{
  ConfigKey *key;
  g_autofree char *value = NULL;

  if (argc < 2)
    return usage_error (context, _("You must specify KEY"), error);
  else if (argc > 2)
    return usage_error (context, _("Too many arguments for --get"), error);

  key = get_config_key (argv[1], error);
  if (key == NULL)
    return FALSE;

  value = print_config (dir, key);
  if (value)
    g_print ("%s\n", value);
  else
    g_print ("*unset*\n");

  return TRUE;
}

static gboolean
set_config (GOptionContext *context, int argc, char **argv, FlatpakDir *dir, GCancellable *cancellable, GError **error)
{
  ConfigKey *key;
  g_autofree char *parsed = NULL;

  if (argc < 3)
    return usage_error (context, _("You must specify KEY and VALUE"), error);
  else if (argc > 3)
    return usage_error (context, _("Too many arguments for --set"), error);

  key = get_config_key (argv[1], error);
  if (key == NULL)
    return FALSE;

  parsed = key->parse (argv[2], error);
  if (!parsed)
    return FALSE;

  if (!flatpak_dir_set_config (dir, key->name, parsed, error))
    return FALSE;

  return TRUE;
}

static gboolean
unset_config (GOptionContext *context, int argc, char **argv, FlatpakDir *dir, GCancellable *cancellable, GError **error)
{
  ConfigKey *key;

  if (argc < 2)
    return usage_error (context, _("You must specify KEY"), error);
  else if (argc > 2)
    return usage_error (context, _("Too many arguments for --unset"), error);

  key = get_config_key (argv[1], error);
  if (key == NULL)
    return FALSE;

  if (!flatpak_dir_set_config (dir, key->name, argv[2], error))
    return FALSE;

  return TRUE;
}

gboolean
flatpak_builtin_config (int argc, char **argv, GCancellable *cancellable, GError **error)
{
  g_autoptr(GOptionContext) context = NULL;
  g_autoptr(GPtrArray) dirs = NULL;
  FlatpakDir *dir;

  context = g_option_context_new (_("[KEY [VALUE]] - Manage configuration"));
  g_option_context_set_translation_domain (context, GETTEXT_PACKAGE);

  if (!flatpak_option_context_parse (context, options, &argc, &argv,
                                     FLATPAK_BUILTIN_FLAG_ONE_DIR | FLATPAK_BUILTIN_FLAG_OPTIONAL_REPO,
                                     &dirs, cancellable, error))
    return FALSE;

  dir = g_ptr_array_index (dirs, 0);

  if (opt_get + opt_set + opt_unset + opt_list > 1)
    return usage_error (context, _("Can only use one of --list, --get, --set or --unset"), error);

  if (!opt_get && !opt_set && !opt_unset && !opt_list)
    opt_list = TRUE;

  if (opt_get)
    return get_config (context, argc, argv, dir, cancellable, error);
  else if (opt_set)
    return set_config (context, argc, argv, dir, cancellable, error);
  else if (opt_unset)
    return unset_config (context, argc, argv, dir, cancellable, error);
  else if (opt_list)
    return list_config (context, argc, argv, dir, cancellable, error);
  else
    return usage_error (context, _("Must specify one of --list, --get, --set or --unset"), error);

  return TRUE;
}

gboolean
flatpak_complete_config (FlatpakCompletion *completion)
{
  g_autoptr(GOptionContext) context = NULL;

  context = g_option_context_new ("");
  if (!flatpak_option_context_parse (context, options, &completion->argc, &completion->argv,
                                     FLATPAK_BUILTIN_FLAG_ONE_DIR | FLATPAK_BUILTIN_FLAG_OPTIONAL_REPO,
                                     NULL, NULL, NULL))
    return FALSE;

  switch (completion->argc)
    {
    case 0:
    case 1: /* KEY */
      flatpak_complete_options (completion, global_entries);
      flatpak_complete_options (completion, options);
      flatpak_complete_options (completion, user_entries);

      if (opt_set || opt_get || opt_unset)
        {
          int i;
          for (i = 0; i < G_N_ELEMENTS (keys); i++)
            flatpak_complete_word (completion, "%s", keys[i].name);
        }

      break;
    }

  return TRUE;
}

===== ./app/flatpak-builtins-document-list.c =====
/* vi:set et sw=2 sts=2 cin cino=t0,f0,(0,{s,>2s,n-s,^-s,e-s:
 * Copyright © 2016 Red Hat, Inc
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Matthias Clasen <mclasen@redhat.com>
 */

#include "config.h"

#include <locale.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>

#include <glib/gi18n.h>

#include "libglnx.h"
#include "flatpak-document-dbus-generated.h"

#include "flatpak-builtins.h"
#include "flatpak-utils-private.h"
#include "flatpak-run-private.h"
#include "flatpak-table-printer.h"

static const char **opt_cols;
static gboolean opt_json;

static GOptionEntry options[] = {
  { "columns", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_cols, N_("What information to show"), N_("FIELD,…")  },
  { "json", 'j', 0, G_OPTION_ARG_NONE, &opt_json, N_("Show output in JSON format"), NULL },
  { NULL }
};

static Column all_columns[] = {
  { "id",          N_("ID"),          N_("Show the document ID"),              0, FLATPAK_ELLIPSIZE_MODE_NONE, 1, 1 },
  { "path",        N_("Path"),        N_("Show the document path"),            0, FLATPAK_ELLIPSIZE_MODE_NONE, 1, 0 },
  { "origin",      N_("Origin"),      N_("Show the document path"),            0, FLATPAK_ELLIPSIZE_MODE_NONE, 1 },
  { "application", N_("Application"), N_("Show applications with permission"), 0, FLATPAK_ELLIPSIZE_MODE_NONE, 1, 0 },
  { "permissions", N_("Permissions"), N_("Show permissions for applications"), 0, FLATPAK_ELLIPSIZE_MODE_NONE, 1, 0 },
  { NULL }
};

static gboolean
print_documents (const char   *app_id,
                 Column       *columns,
                 GCancellable *cancellable,
                 GError      **error)
{
  g_autoptr(GDBusConnection) session_bus = NULL;
  XdpDbusDocuments *documents;
  g_autoptr(GVariant) apps = NULL;
  g_autoptr(GVariantIter) iter = NULL;
  const char *id;
  const char *origin;
  g_autoptr(FlatpakTablePrinter) printer = NULL;
  g_autofree char *mountpoint = NULL;
  gboolean need_perms = FALSE;
  gboolean found_documents_to_print = FALSE;
  int i;

  if (columns[0].name == NULL)
    return TRUE;

  session_bus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, error);
  if (session_bus == NULL)
    return FALSE;

  documents = xdp_dbus_documents_proxy_new_sync (session_bus, 0,
                                                 "org.freedesktop.portal.Documents",
                                                 "/org/freedesktop/portal/documents",
                                                 NULL, error);

  if (documents == NULL)
    return FALSE;

  if (!xdp_dbus_documents_call_list_sync (documents, app_id ? app_id : "", &apps, NULL, error))
    return FALSE;

  if (!xdp_dbus_documents_call_get_mount_point_sync (documents, &mountpoint, NULL, error))
    return FALSE;

  printer = flatpak_table_printer_new ();
  flatpak_table_printer_set_columns (printer, columns, opt_cols == NULL);
  for (i = 0; columns[i].name; i++)
    {
      if (strcmp (columns[i].name, "permissions") == 0 ||
          strcmp (columns[i].name, "application") == 0)
        {
          need_perms = TRUE;
          break;
        }
    }

  iter = g_variant_iter_new (apps);
  while (g_variant_iter_next (iter, "{&s^&ay}", &id, &origin))
    {
      g_autoptr(GVariant) apps2 = NULL;
      g_autoptr(GVariantIter) iter2 = NULL;
      const char *app_id2 = NULL;
      const char **perms = NULL;
      gboolean have_perms = FALSE, just_perms = FALSE;

      if (need_perms)
        {
          g_autofree char *origin2 = NULL;
          if (!xdp_dbus_documents_call_info_sync (documents, id, &origin2, &apps2, NULL, error))
            return FALSE;
          iter2 = g_variant_iter_new (apps2);
          have_perms = g_variant_iter_next (iter2, "{&s^a&s}", &app_id2, &perms);
        }

      do
        {
          for (i = 0; columns[i].name; i++)
            {
              if (strcmp (columns[i].name, "application") == 0)
                flatpak_table_printer_add_column (printer, app_id2);
              else if (strcmp (columns[i].name, "permissions") == 0)
                {
                  g_autofree char *value = NULL;
                  if (perms)
                    value = g_strjoinv (" ", (char **) perms);
                  flatpak_table_printer_add_column (printer, value);
                }
              else if (just_perms)
                flatpak_table_printer_add_column (printer, "");
              else if (strcmp (columns[i].name, "id") == 0)
                flatpak_table_printer_add_column (printer, id);
              else if (strcmp (columns[i].name, "origin") == 0)
                flatpak_table_printer_add_column (printer, origin);
              else if (strcmp (columns[i].name, "path") == 0)
                {
                  g_autofree char *basename = g_path_get_basename (origin);
                  g_autofree char *path = g_build_filename (mountpoint, id, basename, NULL);
                  flatpak_table_printer_add_column (printer, path);
                }
            }

          flatpak_table_printer_finish_row (printer);
          found_documents_to_print = TRUE;

          just_perms = TRUE;
        } while (have_perms && g_variant_iter_next (iter2, "{&s^a&s}", &app_id2, &perms));
    }
    if (!found_documents_to_print)
      {
        g_print (_("No documents found\n"));
        return TRUE;
      }
    
  opt_json ? flatpak_table_printer_print_json (printer) : flatpak_table_printer_print (printer);

  return TRUE;
}

gboolean
flatpak_builtin_document_list (int argc, char **argv,
                               GCancellable *cancellable,
                               GError **error)
{
  g_autoptr(GOptionContext) context = NULL;
  const char *app_id = NULL;
  g_autofree char *col_help = NULL;
  g_autofree Column *columns = NULL;

  context = g_option_context_new (_("[APPID] - List exported files"));
  g_option_context_set_translation_domain (context, GETTEXT_PACKAGE);
  col_help = column_help (all_columns);
  g_option_context_set_description (context, col_help);

  if (!flatpak_option_context_parse (context, options, &argc, &argv,
                                     FLATPAK_BUILTIN_FLAG_NO_DIR,
                                     NULL, cancellable, error))
    return FALSE;

  if (argc > 2)
    return usage_error (context, _("Too many arguments"), error);

  if (argc == 2)
    app_id = argv[1];

  columns = handle_column_args (all_columns, FALSE, opt_cols, error);
  if (columns == NULL)
    return FALSE;

  return print_documents (app_id, columns, cancellable, error);
}

gboolean
flatpak_complete_document_list (FlatpakCompletion *completion)
{
  g_autoptr(GOptionContext) context = NULL;
  g_autoptr(FlatpakDir) user_dir = NULL;
  g_autoptr(FlatpakDir) system_dir = NULL;
  g_autoptr(GError) error = NULL;

  context = g_option_context_new ("");

  if (!flatpak_option_context_parse (context, options, &completion->argc, &completion->argv,
                                     FLATPAK_BUILTIN_FLAG_NO_DIR, NULL, NULL, NULL))
    return FALSE;

  switch (completion->argc)
    {
    case 0:
    case 1: /* APPID */
      flatpak_complete_options (completion, global_entries);
      flatpak_complete_options (completion, options);
      flatpak_complete_columns (completion, all_columns);

      user_dir = flatpak_dir_get_user ();
      {
        g_autoptr(GPtrArray) refs = flatpak_dir_find_installed_refs (user_dir, NULL, NULL, NULL,
                                                                     FLATPAK_KINDS_APP,
                                                                     FIND_MATCHING_REFS_FLAGS_NONE,
                                                                     &error);
        if (refs == NULL)
          flatpak_completion_debug ("find local refs error: %s", error->message);

        flatpak_complete_ref_id (completion, refs);
      }

      system_dir = flatpak_dir_get_system_default ();
      {
        g_autoptr(GPtrArray) refs = flatpak_dir_find_installed_refs (system_dir, NULL, NULL, NULL,
                                                                     FLATPAK_KINDS_APP,
                                                                     FIND_MATCHING_REFS_FLAGS_NONE,
                                                                     &error);
        if (refs == NULL)
          flatpak_completion_debug ("find local refs error: %s", error->message);

        flatpak_complete_ref_id (completion, refs);
      }

      break;
    }

  return TRUE;
}

===== ./app/flatpak-builtins-remote-delete.c =====
/* vi:set et sw=2 sts=2 cin cino=t0,f0,(0,{s,>2s,n-s,^-s,e-s:
 * Copyright © 2014 Red Hat, Inc
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Alexander Larsson <alexl@redhat.com>
 */

#include "config.h"

#include <locale.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

#include <glib/gi18n.h>

#include "libglnx.h"

#include "flatpak-builtins.h"
#include "flatpak-builtins-utils.h"
#include "flatpak-quiet-transaction.h"

static gboolean opt_force;

static GOptionEntry delete_options[] = {
  { "force", 0, 0, G_OPTION_ARG_NONE, &opt_force, N_("Remove remote even if in use"), NULL },
  { NULL }
};


gboolean
flatpak_builtin_remote_delete (int argc, char **argv, GCancellable *cancellable, GError **error)
{
  g_autoptr(GOptionContext) context = NULL;
  g_autoptr(GPtrArray) dirs = NULL;
  g_autoptr(FlatpakDir) preferred_dir = NULL;
  gboolean removed_all_refs = FALSE;
  const char *remote_name;

  context = g_option_context_new (_("NAME - Delete a remote repository"));
  g_option_context_set_translation_domain (context, GETTEXT_PACKAGE);

  g_option_context_add_main_entries (context, delete_options, NULL);

  if (!flatpak_option_context_parse (context, NULL, &argc, &argv,
                                     FLATPAK_BUILTIN_FLAG_STANDARD_DIRS, &dirs, cancellable, error))
    return FALSE;

  if (argc < 2)
    return usage_error (context, _("NAME must be specified"), error);

  remote_name = argv[1];

  if (argc > 2)
    return usage_error (context, _("Too many arguments"), error);

  if (!flatpak_resolve_duplicate_remotes (dirs, remote_name, FALSE, &preferred_dir, cancellable, error))
    return FALSE;

  if (!opt_force)
    {
      g_autoptr(GPtrArray) refs = NULL;
      g_autoptr(GPtrArray) refs_to_remove = NULL;
      int i;

      refs = flatpak_dir_find_installed_refs (preferred_dir, NULL, NULL, NULL, FLATPAK_KINDS_APP | FLATPAK_KINDS_RUNTIME, 0, error);
      if (refs == NULL)
        return FALSE;

      refs_to_remove = g_ptr_array_new_with_free_func (g_free);

      for (i = 0; refs != NULL && i < refs->len; i++)
        {
          FlatpakDecomposed *ref = g_ptr_array_index (refs, i);
          g_autofree char *origin = flatpak_dir_get_origin (preferred_dir, ref, NULL, NULL);
          if (g_strcmp0 (origin, remote_name) == 0)
            g_ptr_array_add (refs_to_remove, flatpak_decomposed_dup_ref (ref));
        }

      if (refs_to_remove->len > 0)
        {
          g_autoptr(FlatpakTransaction) transaction = NULL;

          g_ptr_array_add (refs_to_remove, NULL);

          flatpak_format_choices ((const char **) refs_to_remove->pdata,
                                  _("The following refs are installed from remote '%s':"), remote_name);
          if (!flatpak_yes_no_prompt (FALSE, _("Remove them?")))
            return flatpak_fail_error (error, FLATPAK_ERROR_REMOTE_USED,
                                       _("Can't remove remote '%s' with installed refs"), remote_name);

          transaction = flatpak_quiet_transaction_new (preferred_dir, error);
          if (transaction == NULL)
            return FALSE;

          for (i = 0; i < refs_to_remove->len - 1; i++)
            {
              const char *ref = g_ptr_array_index (refs_to_remove, i);
              if (!flatpak_transaction_add_uninstall (transaction, ref, error))
                return FALSE;
            }

          if (!flatpak_transaction_run (transaction, cancellable, error))
            {
              if (g_error_matches (*error, FLATPAK_ERROR, FLATPAK_ERROR_ABORTED))
                g_clear_error (error);  /* Don't report on stderr */

              return FALSE;
            }

          removed_all_refs = TRUE;
        }
    }

  if (g_str_has_suffix (remote_name, "-origin") && removed_all_refs)
    // The remote has already been deleted because all its refs were deleted.
    return TRUE;

  if (!flatpak_dir_remove_remote (preferred_dir, opt_force, remote_name,
                                  cancellable, error))
    return FALSE;

  return TRUE;
}

gboolean
flatpak_complete_remote_delete (FlatpakCompletion *completion)
{
  g_autoptr(GOptionContext) context = NULL;
  g_autoptr(GPtrArray) dirs = NULL;
  int i;

  context = g_option_context_new ("");
  if (!flatpak_option_context_parse (context, delete_options, &completion->argc, &completion->argv,
                                     FLATPAK_BUILTIN_FLAG_STANDARD_DIRS, &dirs, NULL, NULL))
    return FALSE;

  switch (completion->argc)
    {
    case 0:
    case 1: /* REMOTE */
      flatpak_complete_options (completion, global_entries);
      flatpak_complete_options (completion, delete_options);
      flatpak_complete_options (completion, user_entries);

      for (i = 0; i < dirs->len; i++)
        {
          FlatpakDir *dir = g_ptr_array_index (dirs, i);
          int j;
          g_auto(GStrv) remotes = flatpak_dir_list_remotes (dir, NULL, NULL);
          if (remotes == NULL)
            return FALSE;
          for (j = 0; remotes[j] != NULL; j++)
            flatpak_complete_word (completion, "%s ", remotes[j]);
        }

      break;
    }

  return TRUE;
}

===== ./app/flatpak-builtins-ps.c =====
/* vi:set et sw=2 sts=2 cin cino=t0,f0,(0,{s,>2s,n-s,^-s,e-s:
 * Copyright © 2018 Red Hat, Inc
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Matthias Clasen <mclasen@redhat.com>
 */

#include "config.h"

#include <locale.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>

#include <glib/gi18n.h>

#include "libglnx.h"

#include "flatpak-builtins.h"
#include "flatpak-builtins-utils.h"
#include "flatpak-table-printer.h"
#include "flatpak-instance.h"

static const char **opt_cols;
static gboolean opt_json;

static GOptionEntry options[] = {
  { "columns", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_cols, N_("What information to show"), N_("FIELD,…") },
  { "json", 'j', 0, G_OPTION_ARG_NONE, &opt_json, N_("Show output in JSON format"), NULL },
  { NULL }
};

static Column all_columns[] = {
  { "instance",       N_("Instance"),    N_("Show the instance ID"),                0, FLATPAK_ELLIPSIZE_MODE_NONE, 1, 1 },
  { "pid",            N_("PID"),         N_("Show the PID of the wrapper process"), 0, FLATPAK_ELLIPSIZE_MODE_NONE, 1, 1 },
  { "child-pid",      N_("Child-PID"),   N_("Show the PID of the sandbox process"), 0, FLATPAK_ELLIPSIZE_MODE_NONE, 1, 0 },
  { "application",    N_("Application"), N_("Show the application ID"),             0, FLATPAK_ELLIPSIZE_MODE_NONE, 1, 1 },
  { "arch",           N_("Arch"),        N_("Show the architecture"),               0, FLATPAK_ELLIPSIZE_MODE_NONE, 1, 0 },
  { "branch",         N_("Branch"),      N_("Show the application branch"),         0, FLATPAK_ELLIPSIZE_MODE_NONE, 1, 0 },
  { "commit",         N_("Commit"),      N_("Show the application commit"),         0, FLATPAK_ELLIPSIZE_MODE_NONE, 1, 0 },
  { "runtime",        N_("Runtime"),     N_("Show the runtime ID"),                 0, FLATPAK_ELLIPSIZE_MODE_NONE, 1, 1 },
  { "runtime-branch", N_("R.-Branch"),   N_("Show the runtime branch"),             0, FLATPAK_ELLIPSIZE_MODE_NONE, 1, 0 },
  { "runtime-commit", N_("R.-Commit"),   N_("Show the runtime commit"),             0, FLATPAK_ELLIPSIZE_MODE_NONE, 1, 0 },
  { "active",         N_("Active"),      N_("Show whether the app is active"),      0, FLATPAK_ELLIPSIZE_MODE_NONE, 1, 0 },
  { "background",     N_("Background"),  N_("Show whether the app is background"),  0, FLATPAK_ELLIPSIZE_MODE_NONE, 1, 0 },
  { NULL }
};

enum {
  BACKGROUND,
  RUNNING,
  ACTIVE
};

static GVariant *
get_compositor_apps (void)
{
  g_autoptr(GDBusConnection) bus = NULL;
  g_autoptr(GVariant) ret = NULL;
  GVariant *list = NULL;
  const char *backends[] = {
    "org.freedesktop.impl.portal.desktop.gnome",
    /* Background portal was removed in 1.15.0, retained for compatibility */
    "org.freedesktop.impl.portal.desktop.gtk",
    "org.freedesktop.impl.portal.desktop.kde",
    NULL
  };
  int i;

  bus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL);
  if (!bus)
    return NULL;

  for (i = 0; backends[i]; i++)
    {
      g_autoptr(GError) error = NULL;

      ret = g_dbus_connection_call_sync (bus,
                                         backends[i],
                                         "/org/freedesktop/portal/desktop",
                                         "org.freedesktop.impl.portal.Background",
                                         "GetAppState",
                                         g_variant_new ("()"),
                                         G_VARIANT_TYPE ("(a{sv})"),
                                         G_DBUS_CALL_FLAGS_NO_AUTO_START,
                                         -1,
                                         NULL,
                                         &error);
      if (ret)
        break;
      if (error &&
          !g_error_matches (error, G_DBUS_ERROR, G_DBUS_ERROR_NAME_HAS_NO_OWNER) &&
          !g_error_matches (error, G_DBUS_ERROR, G_DBUS_ERROR_UNKNOWN_METHOD))
        return NULL;
    }

  if (ret)
    g_variant_get (ret, "(@a{sv})", &list);
  else
    g_info ("Failed to get information about running apps from background portal backends");

  return list;
}

static gboolean
enumerate_instances (Column *columns, GError **error)
{
  g_autoptr(GPtrArray) instances = NULL;
  g_autoptr(FlatpakTablePrinter) printer = NULL;
  int i, j;
  g_autoptr(GVariant) compositor_apps = NULL;

  if (columns[0].name == NULL)
    return TRUE;

  printer = flatpak_table_printer_new ();
  flatpak_table_printer_set_columns (printer, columns, opt_cols == NULL);

  instances = flatpak_instance_get_all ();
  if (instances->len == 0)
    {
      /* nothing to show */
      return TRUE;
    }

  for (i = 0; columns[i].name; i++)
    {
      if (strcmp (columns[i].name, "active") == 0 ||
          strcmp (columns[i].name, "background") == 0)
        {
          compositor_apps = get_compositor_apps ();
          break;
        }
    }

  for (j = 0; j < instances->len; j++)
    {
      FlatpakInstance *instance = (FlatpakInstance *) g_ptr_array_index (instances, j);

      for (i = 0; columns[i].name; i++)
        {
          if (strcmp (columns[i].name, "instance") == 0)
            flatpak_table_printer_add_column (printer, flatpak_instance_get_id (instance));
          else if (strcmp (columns[i].name, "pid") == 0)
            {
              g_autofree char *pid = g_strdup_printf ("%d", flatpak_instance_get_pid (instance));
              flatpak_table_printer_add_column (printer, pid);
            }
          else if (strcmp (columns[i].name, "child-pid") == 0)
            {
              g_autofree char *pid = g_strdup_printf ("%d", flatpak_instance_get_child_pid (instance));
              flatpak_table_printer_add_column (printer, pid);
            }
          else if (strcmp (columns[i].name, "application") == 0)
            flatpak_table_printer_add_column (printer, flatpak_instance_get_app (instance));
          else if (strcmp (columns[i].name, "arch") == 0)
            flatpak_table_printer_add_column (printer, flatpak_instance_get_arch (instance));
          else if (strcmp (columns[i].name, "branch") == 0)
            flatpak_table_printer_add_column (printer, flatpak_instance_get_branch (instance));
          else if (strcmp (columns[i].name, "commit") == 0)
            flatpak_table_printer_add_column_len (printer,
                                                  flatpak_instance_get_commit (instance),
                                                  12);
          else if (strcmp (columns[i].name, "runtime") == 0)
            {
              const char *ref_str = flatpak_instance_get_runtime (instance);
              if (ref_str != NULL)
                {
                  g_autoptr(FlatpakDecomposed) ref = flatpak_decomposed_new_from_ref (ref_str, NULL);
                  if (ref)
                    {
                      g_autofree char *id = flatpak_decomposed_dup_id (ref);
                      flatpak_table_printer_add_column (printer, id);
                    }
                }
            }
          else if (strcmp (columns[i].name, "runtime-branch") == 0)
            {
              const char *ref_str = flatpak_instance_get_runtime (instance);
              if (ref_str != NULL)
                {
                  g_autoptr(FlatpakDecomposed) ref = flatpak_decomposed_new_from_ref (ref_str, NULL);
                  if (ref)
                    flatpak_table_printer_add_column (printer, flatpak_decomposed_get_branch (ref));
                }
            }
          else if (strcmp (columns[i].name, "runtime-commit") == 0)
            flatpak_table_printer_add_column_len (printer,
                                                  flatpak_instance_get_runtime_commit (instance),
                                                  12);
          else if (strcmp (columns[i].name, "active") == 0 ||
                   strcmp (columns[i].name, "background") == 0)
           {
             const char *app = flatpak_instance_get_app (instance);
             if (compositor_apps && app)
               {
                 guint state;

                 if (!g_variant_lookup (compositor_apps, app, "u", &state))
                   state = BACKGROUND;

                 if ((strcmp (columns[i].name, "background") == 0 && state == BACKGROUND) ||
                     (strcmp (columns[i].name, "active") == 0 && state == ACTIVE))
                   flatpak_table_printer_add_column (printer, "🗸");
                 else
                   flatpak_table_printer_add_column (printer, "");
               }
             else
               flatpak_table_printer_add_column (printer, "?");
           }
        }

      flatpak_table_printer_finish_row (printer);
    }

  opt_json ? flatpak_table_printer_print_json (printer) : flatpak_table_printer_print (printer);

  return TRUE;
}

gboolean
flatpak_builtin_ps (int           argc,
                    char        **argv,
                    GCancellable *cancellable,
                    GError      **error)
{
  g_autoptr(GOptionContext) context = NULL;
  g_autofree char *col_help = NULL;
  g_autofree Column *columns = NULL;

  context = g_option_context_new (_(" - Enumerate running sandboxes"));
  g_option_context_set_translation_domain (context, GETTEXT_PACKAGE);
  col_help = column_help (all_columns);
  g_option_context_set_description (context, col_help);

  if (!flatpak_option_context_parse (context, options, &argc, &argv, FLATPAK_BUILTIN_FLAG_NO_DIR, NULL, cancellable, error))
    return FALSE;

  if (argc > 1)
    {
      usage_error (context, _("Extra arguments given"), error);
      return FALSE;
    }

  columns = handle_column_args (all_columns, FALSE, opt_cols, error);
  if (columns == NULL)
    return FALSE;

  return enumerate_instances (columns, error);
}

gboolean
flatpak_complete_ps (FlatpakCompletion *completion)
{
  flatpak_complete_options (completion, global_entries);
  flatpak_complete_options (completion, options);
  flatpak_complete_columns (completion, all_columns);

  return TRUE;
}

===== ./app/flatpak-builtins-remote-info.c =====
/* vi:set et sw=2 sts=2 cin cino=t0,f0,(0,{s,>2s,n-s,^-s,e-s:
 * Copyright © 2017 Red Hat, Inc
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Alexander Larsson <alexl@redhat.com>
 */

#include "config.h"

#include <locale.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

#include <glib/gi18n.h>

#include "libglnx.h"

#include "flatpak-builtins.h"
#include "flatpak-builtins-utils.h"
#include "flatpak-repo-utils-private.h"
#include "flatpak-utils-private.h"
#include "flatpak-table-printer.h"
#include "flatpak-variant-impl-private.h"

static char *opt_arch;
static char *opt_commit;
static gboolean opt_runtime;
static gboolean opt_app;
static gboolean opt_show_ref;
static gboolean opt_show_commit;
static gboolean opt_show_parent;
static gboolean opt_show_metadata;
static gboolean opt_log;
static gboolean opt_show_runtime;
static gboolean opt_show_sdk;
static gboolean opt_cached;
static gboolean opt_sideloaded;

static GOptionEntry options[] = {
  { "arch", 0, 0, G_OPTION_ARG_STRING, &opt_arch, N_("Arch to install for"), N_("ARCH") },
  { "commit", 0, 0, G_OPTION_ARG_STRING, &opt_commit, N_("Commit to show info for"), N_("COMMIT") },
  { "runtime", 0, 0, G_OPTION_ARG_NONE, &opt_runtime, N_("Look for runtime with the specified name"), NULL },
  { "app", 0, 0, G_OPTION_ARG_NONE, &opt_app, N_("Look for app with the specified name"), NULL },
  { "log", 0, 0, G_OPTION_ARG_NONE, &opt_log, N_("Display log"), NULL },
  { "show-ref", 'r', 0, G_OPTION_ARG_NONE, &opt_show_ref, N_("Show ref"), NULL },
  { "show-commit", 'c', 0, G_OPTION_ARG_NONE, &opt_show_commit, N_("Show commit"), NULL },
  { "show-parent", 'p', 0, G_OPTION_ARG_NONE, &opt_show_parent, N_("Show parent"), NULL },
  { "show-metadata", 'm', 0, G_OPTION_ARG_NONE, &opt_show_metadata, N_("Show metadata"), NULL },
  { "show-runtime", 0, 0, G_OPTION_ARG_NONE, &opt_show_runtime, N_("Show runtime"), NULL },
  { "show-sdk", 0, 0, G_OPTION_ARG_NONE, &opt_show_sdk, N_("Show sdk"), NULL },
  { "cached", 0, 0, G_OPTION_ARG_NONE, &opt_cached, N_("Use local caches even if they are stale"), NULL },
  /* Translators: A sideload is when you install from a local USB drive rather than the Internet. */
  { "sideloaded", 0, 0, G_OPTION_ARG_NONE, &opt_sideloaded, N_("Only list refs available as sideloads"), NULL },
  { NULL }
};

static void
maybe_print_space (gboolean *first)
{
  if (*first)
    *first = FALSE;
  else
    g_print (" ");
}

gboolean
flatpak_builtin_remote_info (int argc, char **argv, GCancellable *cancellable, GError **error)
{
  g_autoptr(GOptionContext) context = NULL;
  g_autoptr(GPtrArray) dirs = NULL;
  g_autoptr(FlatpakDir) preferred_dir = NULL;
  g_autoptr(GVariant) commit_v = NULL;
  const char *remote;
  const char *pref;
  g_autofree char *default_branch = NULL;
  FlatpakKinds kinds;
  FlatpakKinds matched_kinds;
  g_autofree char *match_id = NULL;
  g_autofree char *match_arch = NULL;
  g_autofree char *match_branch = NULL;
  g_autoptr(FlatpakDecomposed) ref = NULL;
  g_autofree char *commit = NULL;
  g_autofree char *parent = NULL;
  g_autoptr(FlatpakRemoteState) state = NULL;
  gboolean friendly = TRUE;
  const char *xa_metadata = NULL;
  const char *collection_id = NULL;
  const char *eol = NULL;
  const char *eol_rebase = NULL;
  g_autoptr(GKeyFile) metakey = NULL;
  guint64 installed_size = 0;
  guint64 download_size = 0;
  g_autofree char *formatted_installed_size = NULL;
  g_autofree char *formatted_download_size = NULL;
  const gchar *subject = NULL;
  guint64 timestamp;
  g_autofree char *formatted_timestamp = NULL;
  VarMetadataRef sparse_cache;

  context = g_option_context_new (_(" REMOTE REF - Show information about an application or runtime in a remote"));
  g_option_context_set_translation_domain (context, GETTEXT_PACKAGE);

  if (!flatpak_option_context_parse (context, options, &argc, &argv,
                                     FLATPAK_BUILTIN_FLAG_STANDARD_DIRS, &dirs, cancellable, error))
    return FALSE;

  if (!opt_app && !opt_runtime)
    opt_app = opt_runtime = TRUE;

  if (argc < 3)
    return usage_error (context, _("REMOTE and REF must be specified"), error);

  remote = argv[1];
  pref = argv[2];

  if (!flatpak_resolve_duplicate_remotes (dirs, remote, FALSE, &preferred_dir, cancellable, error))
    return FALSE;

  default_branch = flatpak_dir_get_remote_default_branch (preferred_dir, remote);
  kinds = flatpak_kinds_from_bools (opt_app, opt_runtime);

  if (!flatpak_split_partial_ref_arg (pref, kinds, opt_arch, NULL,
                                      &matched_kinds, &match_id, &match_arch, &match_branch, error))
    return FALSE;

  state = get_remote_state (preferred_dir, remote, opt_cached, opt_sideloaded, match_arch, NULL, NULL, error);
  if (state == NULL)
    return FALSE;

  ref = flatpak_dir_find_remote_ref (preferred_dir, state, match_id, match_branch, default_branch, match_arch,
                                     matched_kinds, cancellable, error);
  if (ref == NULL)
    return FALSE;

  if (opt_cached)
    {
      if (opt_commit)
        commit = g_strdup (opt_commit);
      else if (!flatpak_remote_state_lookup_ref (state, flatpak_decomposed_get_ref (ref),
                                                 &commit, NULL, NULL, NULL, NULL, error))
        {
          g_assert (error == NULL || *error != NULL);
          return FALSE;
        }
    }
  else
    {
      commit_v = flatpak_remote_state_load_ref_commit (state, preferred_dir, flatpak_decomposed_get_ref (ref),
                                                       opt_commit, NULL, &commit, cancellable, error);
      if (commit_v == NULL)
        return FALSE;
    }

  if (flatpak_remote_state_lookup_sparse_cache (state, flatpak_decomposed_get_ref (ref),
                                                &sparse_cache, NULL))
    {
      eol = var_metadata_lookup_string (sparse_cache, FLATPAK_SPARSE_CACHE_KEY_ENDOFLIFE, NULL);
      eol_rebase = var_metadata_lookup_string (sparse_cache, FLATPAK_SPARSE_CACHE_KEY_ENDOFLIFE_REBASE, NULL);
    }

  if (opt_show_ref || opt_show_commit || opt_show_parent || opt_show_metadata || opt_show_runtime || opt_show_sdk)
    friendly = FALSE;

  if (friendly)
    {
      int len;
      int rows, cols;
      int width;
      g_autoptr(AsMetadata) mdata = as_metadata_new ();
      AsComponent *cpt = NULL;
      const char *version = NULL;
      const char *license = NULL;
      g_autofree char *arch = flatpak_decomposed_dup_arch (ref);

      flatpak_get_window_size (&rows, &cols);

      flatpak_dir_load_appstream_data (preferred_dir, remote, arch, mdata, NULL, NULL);
      cpt = metadata_find_component (mdata, flatpak_decomposed_get_ref (ref));
      if (cpt)
        {
          const char *name = as_component_get_name (cpt);
          const char *comment = as_component_get_summary (cpt);

          print_wrapped (MIN (cols, 80), "\n%s - %s\n", name, comment);

          version = component_get_version_latest (cpt);
          license = as_component_get_project_license (cpt);
        }

      if (commit_v)
        {
          VarCommitRef var_commit = var_commit_from_gvariant (commit_v);
          VarMetadataRef commit_metadata;

          subject = var_commit_get_subject (var_commit);
          parent = ostree_commit_get_parent (commit_v);
          timestamp = ostree_commit_get_timestamp (commit_v);

          commit_metadata = var_commit_get_metadata (var_commit);
          xa_metadata = var_metadata_lookup_string (commit_metadata, "xa.metadata", NULL);

          if (xa_metadata == NULL)
            g_printerr (_("Warning: Commit has no flatpak metadata\n"));
          else
            {
              metakey = g_key_file_new ();
              if (!g_key_file_load_from_data (metakey, xa_metadata, -1, 0, error))
                return FALSE;
            }

          collection_id = var_metadata_lookup_string (commit_metadata, "ostree.collection-binding", NULL);

          installed_size = GUINT64_FROM_BE (var_metadata_lookup_uint64 (commit_metadata, "xa.installed-size", 0));
          download_size = GUINT64_FROM_BE (var_metadata_lookup_uint64 (commit_metadata, "xa.download-size", 0));

          formatted_installed_size = g_format_size (installed_size);
          formatted_download_size = g_format_size (download_size);
          formatted_timestamp = format_timestamp (timestamp);
        }

      len = 0;
      len = MAX (len, g_utf8_strlen (_("ID:"), -1));
      len = MAX (len, g_utf8_strlen (_("Ref:"), -1));
      len = MAX (len, g_utf8_strlen (_("Arch:"), -1));
      len = MAX (len, g_utf8_strlen (_("Branch:"), -1));
      if (version != NULL)
        len = MAX (len, g_utf8_strlen (_("Version:"), -1));
      if (license != NULL)
        len = MAX (len, g_utf8_strlen (_("License:"), -1));
      if (collection_id != NULL)
        len = MAX (len, g_utf8_strlen (_("Collection:"), -1));
      if (formatted_download_size)
        len = MAX (len, g_utf8_strlen (_("Download Size:"), -1));
      if (formatted_installed_size)
        len = MAX (len, g_utf8_strlen (_("Installed Size:"), -1));
      if (flatpak_decomposed_is_app (ref) == 0 && metakey != NULL)
        {
          len = MAX (len, g_utf8_strlen (_("Runtime:"), -1));
          len = MAX (len, g_utf8_strlen (_("Sdk:"), -1));
        }
      if (formatted_timestamp)
        len = MAX (len, g_utf8_strlen (_("Date:"), -1));
      if (subject)
        len = MAX (len, g_utf8_strlen (_("Subject:"), -1));
      len = MAX (len, g_utf8_strlen (_("Commit:"), -1));
      if (parent)
        len = MAX (len, g_utf8_strlen (_("Parent:"), -1));
      if (eol)
        len = MAX (len, strlen (_("End-of-life:")));
      if (eol_rebase)
        len = MAX (len, strlen (_("End-of-life-rebase:")));
      if (opt_log)
        len = MAX (len, g_utf8_strlen (_("History:"), -1));

      width = cols - (len + 1);

      print_aligned_take (len, _("ID:"), flatpak_decomposed_dup_id (ref));
      print_aligned (len, _("Ref:"), flatpak_decomposed_get_ref (ref));
      print_aligned (len, _("Arch:"), arch);
      print_aligned_take (len, _("Branch:"), flatpak_decomposed_dup_branch (ref));
      if (version != NULL)
        print_aligned (len, _("Version:"), version);
      if (license != NULL)
        print_aligned (len, _("License:"), license);
      if (collection_id != NULL)
        print_aligned (len, _("Collection:"), collection_id);
      if (formatted_download_size)
        print_aligned (len, _("Download Size:"), formatted_download_size);
      if (formatted_installed_size)
        print_aligned (len, _("Installed Size:"), formatted_installed_size);
      if (flatpak_decomposed_is_app (ref) && metakey != NULL)
        {
          g_autofree char *runtime = g_key_file_get_string (metakey, "Application", "runtime", error);
          print_aligned (len, _("Runtime:"), runtime ? runtime : "-");
        }
      if (flatpak_decomposed_is_app (ref) && metakey != NULL)
        {
          g_autofree char *sdk = g_key_file_get_string (metakey, "Application", "sdk", error);
          print_aligned (len, _("Sdk:"), sdk ? sdk : "-");
        }
      g_print ("\n");
      {
        g_autofree char *formatted_commit = ellipsize_string (commit, width);
        print_aligned (len, _("Commit:"), formatted_commit);
      }
      if (parent)
        {
          g_autofree char *formatted_commit = ellipsize_string (parent, width);
          print_aligned (len, _("Parent:"), formatted_commit);
        }
      if (eol)
        {
          g_autofree char *formatted_eol = ellipsize_string (eol, width);
          print_aligned (len, _("End-of-life:"), formatted_eol);
        }
      if (eol_rebase)
        {
          g_autofree char *formatted_eol = ellipsize_string (eol_rebase, width);
          print_aligned (len, _("End-of-life-rebase:"), formatted_eol);
        }

      if (subject)
        print_aligned (len, _("Subject:"), subject);
      if (formatted_timestamp)
        print_aligned (len, _("Date:"), formatted_timestamp);

      if (opt_log)
        {
          g_autofree char *p = g_strdup (parent);

          print_aligned (len, _("History:"), "\n");

          while (p)
            {
              g_autofree char *p_parent = NULL;
              const gchar *p_subject;
              guint64 p_timestamp;
              g_autofree char *p_formatted_timestamp = NULL;
              g_autoptr(GVariant) p_commit_v = NULL;
              VarCommitRef p_commit;

              p_commit_v = flatpak_remote_state_load_ref_commit (state, preferred_dir, flatpak_decomposed_get_ref (ref),
                                                                 p, NULL, NULL, cancellable, NULL);
              if (p_commit_v == NULL)
                break;

              p_parent = ostree_commit_get_parent (p_commit_v);
              p_timestamp = ostree_commit_get_timestamp (p_commit_v);
              p_formatted_timestamp = format_timestamp (p_timestamp);

              p_commit = var_commit_from_gvariant (p_commit_v);
              p_subject = var_commit_get_subject (p_commit);

              print_aligned (len, _(" Commit:"), p);
              print_aligned (len, _(" Subject:"), p_subject);
              print_aligned (len, _(" Date:"), p_formatted_timestamp);

              g_free (p);
              p = g_steal_pointer (&p_parent);
              if (p)
                g_print ("\n");
            }
        }
    }
  else
    {
      g_autoptr(GVariant) c_v = NULL;
      g_autofree char *c = g_strdup (commit);

      if (commit_v)
        c_v = g_variant_ref (commit_v);

      do
        {
          g_autofree char *p = NULL;
          g_autoptr(GVariant) c_m = NULL;
          gboolean first = TRUE;

          if (c_v)
            {
              c_m = g_variant_get_child_value (c_v, 0);
              p = ostree_commit_get_parent (c_v);
            }

          if (c_m)
            {
              g_variant_lookup (c_m, "xa.metadata", "&s", &xa_metadata);
              if (xa_metadata == NULL)
                g_printerr (_("Warning: Commit %s has no flatpak metadata\n"), c);
              else
                {
                  metakey = g_key_file_new ();
                  if (!g_key_file_load_from_data (metakey, xa_metadata, -1, 0, error))
                    return FALSE;
                }
            }

          if (opt_show_ref)
            {
              maybe_print_space (&first);
              g_print ("%s", flatpak_decomposed_get_ref (ref));
            }

          if (opt_show_commit)
            {
              maybe_print_space (&first);
              g_print ("%s", c);
            }

          if (opt_show_parent)
            {
              maybe_print_space (&first);
              g_print ("%s", p ? p : "-");
            }

          if (opt_show_runtime)
            {
              g_autofree char *runtime = NULL;
              maybe_print_space (&first);

              if (metakey)
                runtime = g_key_file_get_string (metakey, flatpak_decomposed_get_kind_metadata_group (ref), "runtime", NULL);
              g_print ("%s", runtime ? runtime : "-");
            }

          if (opt_show_sdk)
            {
              g_autofree char *sdk = NULL;
              maybe_print_space (&first);

              if (metakey)
                sdk = g_key_file_get_string (metakey, flatpak_decomposed_get_kind_metadata_group (ref), "sdk", NULL);
              g_print ("%s", sdk ? sdk : "-");
            }

          if (!first)
            g_print ("\n");

          if (opt_show_metadata)
            {
              if (xa_metadata != NULL)
                flatpak_print_escaped_string (xa_metadata,
                                              FLATPAK_ESCAPE_ALLOW_NEWLINES
                                              | FLATPAK_ESCAPE_DO_NOT_QUOTE);
              if (xa_metadata == NULL || !g_str_has_suffix (xa_metadata, "\n"))
                g_print ("\n");
            }

          g_free (c);
          c = g_steal_pointer (&p);

          if (c_v)
            g_variant_unref (c_v);
          c_v = NULL;

          if (c && opt_log)
            c_v = flatpak_remote_state_load_ref_commit (state, preferred_dir,
                                                        flatpak_decomposed_get_ref (ref),
                                                        c, NULL, NULL, cancellable, NULL);
        }
      while (c_v != NULL);
    }

  return TRUE;
}

gboolean
flatpak_complete_remote_info (FlatpakCompletion *completion)
{
  g_autoptr(GOptionContext) context = NULL;
  g_autoptr(GPtrArray) dirs = NULL;
  FlatpakKinds kinds;
  int i;

  context = g_option_context_new ("");

  if (!flatpak_option_context_parse (context, options, &completion->argc, &completion->argv,
                                     FLATPAK_BUILTIN_FLAG_STANDARD_DIRS, &dirs, NULL, NULL))
    return FALSE;

  kinds = flatpak_kinds_from_bools (opt_app, opt_runtime);

  switch (completion->argc)
    {
    case 0:
    case 1: /* REMOTE */
      flatpak_complete_options (completion, global_entries);
      flatpak_complete_options (completion, options);
      flatpak_complete_options (completion, user_entries);

      for (i = 0; i < dirs->len; i++)
        {
          FlatpakDir *dir = g_ptr_array_index (dirs, i);
          int j;
          g_auto(GStrv) remotes = flatpak_dir_list_remotes (dir, NULL, NULL);
          if (remotes == NULL)
            return FALSE;
          for (j = 0; remotes[j] != NULL; j++)
            flatpak_complete_word (completion, "%s ", remotes[j]);
        }

      break;

    default: /* REF */
      for (i = 0; i < dirs->len; i++)
        {
          FlatpakDir *dir = g_ptr_array_index (dirs, i);
          flatpak_complete_partial_ref (completion, kinds, opt_arch, dir, completion->argv[1]);
        }

      break;
    }

  return TRUE;
}

===== ./app/flatpak-builtins-document-unexport.c =====
/* vi:set et sw=2 sts=2 cin cino=t0,f0,(0,{s,>2s,n-s,^-s,e-s:
 * Copyright © 2016 Red Hat, Inc
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Matthias Clasen <mclasen@redhat.com>
 */

#include "config.h"

#include <locale.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>

#include <glib/gi18n.h>

#include "libglnx.h"
#include "flatpak-document-dbus-generated.h"

#include <gio/gunixfdlist.h>

#include "flatpak-builtins.h"
#include "flatpak-utils-private.h"
#include "flatpak-run-private.h"

static gboolean opt_doc_id;

static GOptionEntry options[] = {
  { "doc-id", 0, 0, G_OPTION_ARG_NONE, &opt_doc_id, N_("Specify the document ID"), NULL },
  { NULL }
};

gboolean
flatpak_builtin_document_unexport (int argc, char **argv,
                                   GCancellable *cancellable,
                                   GError **error)
{
  g_autoptr(GOptionContext) context = NULL;
  g_autoptr(GDBusConnection) session_bus = NULL;
  XdpDbusDocuments *documents;
  const char *file;
  g_autofree char *doc_id = NULL;

  context = g_option_context_new (_("FILE - Unexport a file to apps"));
  g_option_context_set_translation_domain (context, GETTEXT_PACKAGE);

  if (!flatpak_option_context_parse (context, options, &argc, &argv,
                                     FLATPAK_BUILTIN_FLAG_NO_DIR,
                                     NULL, cancellable, error))
    return FALSE;

  if (argc < 2)
    return usage_error (context, _("FILE must be specified"), error);

  if (argc > 2)
    return usage_error (context, _("Too many arguments"), error);

  file = argv[1];

  session_bus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, error);
  if (session_bus == NULL)
    return FALSE;

  documents = xdp_dbus_documents_proxy_new_sync (session_bus, 0,
                                                 "org.freedesktop.portal.Documents",
                                                 "/org/freedesktop/portal/documents",
                                                 NULL, error);
  if (documents == NULL)
    return FALSE;

  if (opt_doc_id)
    doc_id = g_strdup (file);
  else if (!xdp_dbus_documents_call_lookup_sync (documents, file, &doc_id, NULL, error))
    return FALSE;

  g_assert (doc_id != NULL);

  if (strcmp (doc_id, "") == 0)
    {
      g_print (_("Not exported\n"));
      return TRUE;
    }

  if (!xdp_dbus_documents_call_delete_sync (documents, doc_id, NULL, error))
    return FALSE;

  return TRUE;
}

static gboolean
_complete_document_ids (FlatpakCompletion  *completion,
                        GError            **error)
{
  g_autoptr(GDBusConnection) session_bus = NULL;
  XdpDbusDocuments *documents;
  g_autoptr(GVariant) apps = NULL;
  g_autoptr(GVariantIter) iter = NULL;
  const char *id;
  const char *origin;

  session_bus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, error);
  if (session_bus == NULL)
    return FALSE;

  documents = xdp_dbus_documents_proxy_new_sync (session_bus, 0,
                                                 "org.freedesktop.portal.Documents",
                                                 "/org/freedesktop/portal/documents",
                                                 NULL, error);
  if (documents == NULL)
    return FALSE;

  if (!xdp_dbus_documents_call_list_sync (documents, "", &apps, NULL, error))
    return FALSE;

  iter = g_variant_iter_new (apps);
  while (g_variant_iter_next (iter, "{&s^&ay}", &id, &origin))
    flatpak_complete_word (completion, "%s ", id);

  return TRUE;
}

gboolean
flatpak_complete_document_unexport (FlatpakCompletion *completion)
{
  g_autoptr(GOptionContext) context = NULL;
  g_autoptr(GError) error = NULL;

  context = g_option_context_new ("");

  if (!flatpak_option_context_parse (context, options, &completion->argc, &completion->argv,
                                     FLATPAK_BUILTIN_FLAG_NO_DIR, NULL, NULL, NULL))
    return FALSE;

  switch (completion->argc)
    {
    case 0:
    case 1: /* FILE */
      flatpak_complete_options (completion, global_entries);
      flatpak_complete_options (completion, options);

      if (!opt_doc_id)
        flatpak_complete_file (completion, "__FLATPAK_FILE");
      else if (!_complete_document_ids (completion, &error))
        flatpak_completion_debug ("complete document ids error: %s", error->message);

      break;
    }

  return TRUE;
}

===== ./app/flatpak-complete.h =====
/*
 * Copyright © 2018 Red Hat, Inc
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Alexander Larsson <alexl@redhat.com>
 */

#ifndef __FLATPAK_COMPLETE_H__
#define __FLATPAK_COMPLETE_H__

#include <ostree.h>
#include "flatpak-dir-private.h"
#include "flatpak-builtins-utils.h"

typedef struct FlatpakCompletion FlatpakCompletion;

struct FlatpakCompletion
{
  char  *shell_cur;
  char  *cur;
  char  *prev;
  char  *line;
  int    point;
  char **argv;
  char **original_argv;
  int    argc;
  int    original_argc;
};

void flatpak_completion_debug (const gchar *format,
                               ...) G_GNUC_PRINTF (1, 2);

FlatpakCompletion *flatpak_completion_new (const char *arg_line,
                                           const char *arg_point,
                                           const char *arg_cur);
void               flatpak_complete_word (FlatpakCompletion *completion,
                                          const char        *format,
                                          ...) G_GNUC_PRINTF (2, 3);
void               flatpak_complete_ref (FlatpakCompletion *completion,
                                         OstreeRepo        *repo);
void               flatpak_complete_ref_id (FlatpakCompletion *completion,
                                            GPtrArray         *refs);
void               flatpak_complete_ref_branch (FlatpakCompletion *completion,
                                                GPtrArray         *refs);
void               flatpak_complete_partial_ref (FlatpakCompletion *completion,
                                                 FlatpakKinds       kinds,
                                                 const char        *only_arch,
                                                 FlatpakDir        *dir,
                                                 const char        *remote);
void               flatpak_complete_file (FlatpakCompletion *completion,
                                          const char        *file_type);
void               flatpak_complete_dir (FlatpakCompletion *completion);
void               flatpak_complete_options (FlatpakCompletion *completion,
                                             GOptionEntry      *entries);
void               flatpak_complete_columns (FlatpakCompletion *completion,
                                             Column            *columns);
void               flatpak_completion_free (FlatpakCompletion *completion);
void               flatpak_complete_context (FlatpakCompletion *completion);

G_DEFINE_AUTOPTR_CLEANUP_FUNC (FlatpakCompletion, flatpak_completion_free)

#endif /* __FLATPAK_COMPLETE_H__ */

===== ./app/flatpak-builtins-permission-show.c =====
/* vi:set et sw=2 sts=2 cin cino=t0,f0,(0,{s,>2s,n-s,^-s,e-s:
 * Copyright © 2018 Red Hat, Inc
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Matthias Clasen <mclasen@redhat.com>
 */

#include "config.h"

#include <locale.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>

#include <glib/gi18n.h>

#include "libglnx.h"
#include "flatpak-permission-dbus-generated.h"

#include "flatpak-builtins.h"
#include "flatpak-builtins-utils.h"
#include "flatpak-table-printer.h"
#include "flatpak-utils-private.h"
#include "flatpak-run-private.h"

static gboolean opt_json;

static GOptionEntry options[] = {
  { "json", 'j', 0, G_OPTION_ARG_NONE, &opt_json, N_("Show output in JSON format"), NULL },
  { NULL }
};

static gboolean
list_for_app (XdpDbusPermissionStore *store,
              const char             *table,
              const char             *app_id,
              FlatpakTablePrinter    *printer,
              GError                **error)
{
  char **ids;
  int i;

  if (!xdp_dbus_permission_store_call_list_sync (store, table, &ids, NULL, error))
    return FALSE;

  for (i = 0; ids[i]; i++)
    {
      g_autoptr(GVariant) permissions = NULL;
      g_autoptr(GVariant) data = NULL;
      g_autoptr(GVariant) d = NULL;
      g_autofree char *txt = NULL;
      GVariantIter iter;
      char *key;
      GVariantIter *val;

      if (!xdp_dbus_permission_store_call_lookup_sync (store, table, ids[i], &permissions, &data, NULL, error))
        return FALSE;

      d = g_variant_get_child_value (data, 0);
      txt = g_variant_print (d, FALSE);

      g_variant_iter_init (&iter, permissions);
      while (g_variant_iter_loop (&iter, "{sas}", &key, &val))
        {
          char *p;

          if (strcmp (key, app_id) != 0)
            continue;

          flatpak_table_printer_add_column (printer, table);
          flatpak_table_printer_add_column (printer, ids[i]);
          flatpak_table_printer_add_column (printer, key);
          flatpak_table_printer_add_column (printer, "");

          while (g_variant_iter_loop (val, "s", &p))
            {
              flatpak_table_printer_append_with_comma (printer, p);
            }

          flatpak_table_printer_add_column (printer, txt);
          flatpak_table_printer_finish_row (printer);
        }
    }

  return TRUE;
}

gboolean
flatpak_builtin_permission_show (int argc, char **argv,
                                 GCancellable *cancellable,
                                 GError **error)
{
  g_autoptr(GOptionContext) context = NULL;
  g_autoptr(GDBusConnection) session_bus = NULL;
  XdpDbusPermissionStore *store = NULL;
  const char *app_id;
  g_autoptr(FlatpakTablePrinter) printer = NULL;
  int i;
  g_auto(GStrv) tables = NULL;

  context = g_option_context_new (_("APP_ID - Show permissions for an app"));
  g_option_context_set_translation_domain (context, GETTEXT_PACKAGE);

  if (!flatpak_option_context_parse (context, options, &argc, &argv,
                                     FLATPAK_BUILTIN_FLAG_NO_DIR,
                                     NULL, cancellable, error))
    return FALSE;

  if (argc != 2)
    return usage_error (context, _("Wrong number of arguments"), error);

  app_id = argv[1];

  session_bus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, error);
  if (session_bus == NULL)
    return FALSE;

  store = xdp_dbus_permission_store_proxy_new_sync (session_bus, 0,
                                                    "org.freedesktop.impl.portal.PermissionStore",
                                                    "/org/freedesktop/impl/portal/PermissionStore",
                                                    NULL, error);
  if (store == NULL)
    return FALSE;

  printer = flatpak_table_printer_new ();

  i = 0;
  flatpak_table_printer_set_column_title (printer, i++, _("Table"));
  flatpak_table_printer_set_column_title (printer, i++, _("Object"));
  flatpak_table_printer_set_column_title (printer, i++, _("App"));
  flatpak_table_printer_set_column_title (printer, i++, _("Permissions"));
  flatpak_table_printer_set_column_title (printer, i++, _("Data"));

  tables = get_permission_tables (store);
  for (i = 0; tables[i]; i++)
    {
      if (!list_for_app (store, tables[i], app_id, printer, error))
        return FALSE;
    }

  opt_json ? flatpak_table_printer_print_json (printer) : flatpak_table_printer_print (printer);

  return TRUE;
}

gboolean
flatpak_complete_permission_show (FlatpakCompletion *completion)
{
  g_autoptr(GOptionContext) context = NULL;
  g_autoptr(GDBusConnection) session_bus = NULL;
  XdpDbusPermissionStore *store = NULL;
  g_autoptr(FlatpakDir) user_dir = NULL;
  g_autoptr(FlatpakDir) system_dir = NULL;

  context = g_option_context_new ("");

  if (!flatpak_option_context_parse (context, options, &completion->argc, &completion->argv,
                                     FLATPAK_BUILTIN_FLAG_NO_DIR, NULL, NULL, NULL))
    return FALSE;

  session_bus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL);
  if (session_bus == NULL)
    return FALSE;

  store = xdp_dbus_permission_store_proxy_new_sync (session_bus, 0,
                                                    "org.freedesktop.impl.portal.PermissionStore",
                                                    "/org/freedesktop/impl/portal/PermissionStore",
                                                    NULL, NULL);

  if (store == NULL)
    return FALSE;

  switch (completion->argc)
    {
    case 0:
    case 1: /* APP_ID */
      flatpak_complete_options (completion, global_entries);
      flatpak_complete_options (completion, options);

      user_dir = flatpak_dir_get_user ();
      system_dir = flatpak_dir_get_system_default ();
      flatpak_complete_partial_ref (completion, FLATPAK_KINDS_APP, FALSE, user_dir, NULL);
      flatpak_complete_partial_ref (completion, FLATPAK_KINDS_APP, FALSE, system_dir, NULL);

      break;

    default:
      break;
    }

  return TRUE;
}

===== ./app/flatpak-builtins-create-usb.c =====
/* vi:set et sw=2 sts=2 cin cino=t0,f0,(0,{s,>2s,n-s,^-s,e-s:
 * Copyright © 2018 Matthew Leeds
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Matthew Leeds <matthew.leeds@endlessm.com>
 */

#include "config.h"

#include <locale.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

#include <glib/gi18n.h>

#include "libglnx.h"

#include "flatpak-builtins.h"
#include "flatpak-repo-utils-private.h"
#include "flatpak-builtins-utils.h"
#include "flatpak-utils-private.h"
#include "flatpak-error.h"

static char *opt_arch;
static char *opt_destination_repo;
static gboolean opt_runtime;
static gboolean opt_app;
static gboolean opt_allow_partial;

static GOptionEntry options[] = {
  { "app", 0, 0, G_OPTION_ARG_NONE, &opt_app, N_("Look for app with the specified name"), NULL },
  { "arch", 0, 0, G_OPTION_ARG_STRING, &opt_arch, N_("Arch to copy"), N_("ARCH") },
  { "destination-repo", 0, 0, G_OPTION_ARG_FILENAME, &opt_destination_repo, "Use custom repository directory within the mount", N_("DEST") },
  { "runtime", 0, 0, G_OPTION_ARG_NONE, &opt_runtime, N_("Look for runtime with the specified name"), NULL },
  { "allow-partial", 0, 0, G_OPTION_ARG_NONE, &opt_allow_partial, N_("Allow partial commits in the created repo"), NULL },
  { NULL }
};

typedef struct CommitAndSubpaths
{
  gchar  *commit;
  gchar **subpaths;
} CommitAndSubpaths;

static void
commit_and_subpaths_free (CommitAndSubpaths *c_s)
{
  g_free (c_s->commit);
  g_strfreev (c_s->subpaths);
  g_free (c_s);
}

static CommitAndSubpaths *
commit_and_subpaths_new (const char *commit, const char * const *subpaths)
{
  CommitAndSubpaths *c_s = g_new (CommitAndSubpaths, 1);

  c_s->commit = g_strdup (commit);
  c_s->subpaths = g_strdupv ((char **) subpaths);
  return c_s;
}

static char **
get_flatpak_subpaths_from_deploy_subpaths (const char * const *subpaths)
{
  g_autoptr(GPtrArray) resolved_subpaths = NULL;
  gsize i;

  if (subpaths == NULL || subpaths[0] == NULL)
    return NULL;

  resolved_subpaths = g_ptr_array_new_with_free_func (g_free);
  g_ptr_array_add (resolved_subpaths, g_strdup ("/metadata"));
  for (i = 0; subpaths[i] != NULL; i++)
    g_ptr_array_add (resolved_subpaths, g_build_filename ("/files", subpaths[i], NULL));
  g_ptr_array_add (resolved_subpaths, NULL);

  return (char **) g_ptr_array_free (g_steal_pointer (&resolved_subpaths), FALSE);
}

/* Add related refs specified in the metadata of @ref to @all_refs, also
 * updating @all_collection_ids with any new collection IDs. A warning will be
 * printed for related refs that are not installed, and they won't be added to
 * the list. */
static gboolean
add_related (GHashTable        *all_refs,
             GHashTable        *all_collection_ids,
             FlatpakDecomposed *ref,
             FlatpakDir        *dir,
             GCancellable      *cancellable,
             GError           **error)
{
  g_autoptr(GBytes) deploy_data = NULL;
  g_autoptr(FlatpakDeploy) deploy = NULL;
  g_autoptr(GKeyFile) metakey = NULL;
  const char *commit = NULL;
  g_autofree char *arch = NULL;
  g_autofree char *branch = NULL;
  GList *extensions, *l;

  g_info ("Finding related refs for ‘%s’", flatpak_decomposed_get_ref (ref));

  arch = flatpak_decomposed_dup_arch (ref);
  branch = flatpak_decomposed_dup_branch (ref);

  deploy_data = flatpak_dir_get_deploy_data (dir, ref, FLATPAK_DEPLOY_VERSION_ANY, cancellable, error);
  if (deploy_data == NULL)
    return FALSE;

  if (flatpak_deploy_data_has_subpaths (deploy_data) && !opt_allow_partial)
    g_printerr (_("Warning: Related ref ‘%s’ is partially installed. Use --allow-partial to suppress this message.\n"),
                flatpak_decomposed_get_ref (ref));

  commit = flatpak_deploy_data_get_commit (deploy_data);

  deploy = flatpak_dir_load_deployed (dir, ref, commit, cancellable, error);
  if (deploy == NULL)
    return FALSE;

  metakey = flatpak_deploy_get_metadata (deploy);

  extensions = flatpak_list_extensions (metakey, arch, branch);
  for (l = extensions; l; l = l->next)
    {
      FlatpakExtension *ext = l->data;
      g_autoptr(GBytes) ext_deploy_data = NULL;
      g_autoptr(OstreeCollectionRef) ext_collection_ref = NULL;
      g_autofree char *ext_collection_id = NULL;
      g_autofree const char **ext_subpaths = NULL;
      g_auto(GStrv) resolved_ext_subpaths = NULL;
      const char *ext_remote;
      const char *ext_commit = NULL;
      CommitAndSubpaths *c_s;
      g_autoptr(GVariant) extra_data_sources = NULL;

      if (ext->is_unmaintained)
        continue;

      g_assert (ext->ref);

      ext_deploy_data = flatpak_dir_get_deploy_data (dir, ext->ref, FLATPAK_DEPLOY_VERSION_ANY, cancellable, NULL);
      if (ext_deploy_data == NULL)
        {
          g_printerr (_("Warning: Omitting related ref ‘%s’ because it is not installed.\n"),
                      flatpak_decomposed_get_ref (ext->ref));
          continue;
        }

      if (flatpak_deploy_data_has_subpaths (ext_deploy_data) && !opt_allow_partial)
        {
          g_printerr (_("Warning: Related ref ‘%s’ is partially installed. Use --allow-partial to suppress this message.\n"),
                      flatpak_decomposed_get_ref (ext->ref));
        }

      ext_remote = flatpak_deploy_data_get_origin (ext_deploy_data);
      if (ext_remote == NULL)
        return FALSE;
      ext_collection_id = flatpak_dir_get_remote_collection_id (dir, ext_remote);
      if (ext_collection_id == NULL)
        {
          g_printerr (_("Warning: Omitting related ref ‘%s’ because its remote ‘%s’ does not have a collection ID set.\n"),
                      flatpak_decomposed_get_ref (ext->ref), ext_remote);
          continue;
        }

      ext_commit = flatpak_deploy_data_get_commit (ext_deploy_data);

      /* Emit a warning and omit it if it's extra-data
       * https://github.com/flatpak/flatpak/issues/969 */
      extra_data_sources = flatpak_repo_get_extra_data_sources (flatpak_dir_get_repo (dir), ext_commit, NULL, NULL);
      if (extra_data_sources != NULL && g_variant_n_children (extra_data_sources) > 0)
        {
           g_printerr (_("Warning: Omitting related ref ‘%s’ because it's extra-data.\n"),
                       flatpak_decomposed_get_ref (ext->ref));
           continue;
        }

      ext_subpaths = flatpak_deploy_data_get_subpaths (ext_deploy_data);
      resolved_ext_subpaths = get_flatpak_subpaths_from_deploy_subpaths (ext_subpaths);
      c_s = commit_and_subpaths_new (ext_commit, (const char * const *) resolved_ext_subpaths);

      g_hash_table_insert (all_collection_ids, g_strdup (ext_collection_id), g_strdup (ext_remote));
      ext_collection_ref = ostree_collection_ref_new (ext_collection_id, flatpak_decomposed_get_ref (ext->ref));
      g_hash_table_insert (all_refs, g_steal_pointer (&ext_collection_ref), c_s);
    }

  g_list_free_full (extensions, (GDestroyNotify) flatpak_extension_free);

  return TRUE;
}

/* Add the runtime and its related refs to @all_refs, also updating
 * @all_collection_ids with any new collection IDs */
static gboolean
add_runtime (GHashTable        *all_refs,
             GHashTable        *all_collection_ids,
             FlatpakDecomposed *ref,
             FlatpakDir        *dir,
             GCancellable      *cancellable,
             GError           **error)
{
  g_autoptr(GBytes) deploy_data = NULL;
  g_autoptr(GBytes) runtime_deploy_data = NULL;
  g_autoptr(FlatpakDeploy) deploy = NULL;
  g_autoptr(GKeyFile) metakey = NULL;
  g_autoptr(OstreeCollectionRef) runtime_collection_ref = NULL;
  g_autofree char *runtime_pref = NULL;
  g_autoptr(FlatpakDecomposed) runtime_ref = NULL;
  g_autofree char *runtime_remote = NULL;
  g_autofree char *runtime_collection_id = NULL;
  g_autofree const char **runtime_subpaths = NULL;
  g_auto(GStrv) resolved_runtime_subpaths = NULL;
  const char *commit = NULL;
  const char *runtime_commit = NULL;
  CommitAndSubpaths *c_s;
  g_autoptr(GVariant) extra_data_sources = NULL;

  g_info ("Finding the runtime for ‘%s’", flatpak_decomposed_get_ref (ref));

  deploy_data = flatpak_dir_get_deploy_data (dir, ref, FLATPAK_DEPLOY_VERSION_ANY, cancellable, error);
  if (deploy_data == NULL)
    return FALSE;

  commit = flatpak_deploy_data_get_commit (deploy_data);

  deploy = flatpak_dir_load_deployed (dir, ref, commit, cancellable, error);
  if (deploy == NULL)
    return FALSE;

  metakey = flatpak_deploy_get_metadata (deploy);

  runtime_pref = g_key_file_get_string (metakey, "Application", "runtime", error);
  if (runtime_pref == NULL)
    return FALSE;
  runtime_ref = flatpak_decomposed_new_from_pref (FLATPAK_KINDS_RUNTIME, runtime_pref, error);
  if (runtime_ref == NULL)
    return FALSE;

  runtime_deploy_data = flatpak_dir_get_deploy_data (dir, runtime_ref, FLATPAK_DEPLOY_VERSION_ANY, cancellable, error);
  if (runtime_deploy_data == NULL)
    return FALSE;
  runtime_remote = flatpak_dir_get_origin (dir, runtime_ref, cancellable, error);
  if (runtime_remote == NULL)
    return FALSE;
  runtime_collection_id = flatpak_dir_get_remote_collection_id (dir, runtime_remote);
  if (runtime_collection_id == NULL)
    return flatpak_fail (error,
                         _("Remote ‘%s’ does not have a collection ID set, which is required for P2P distribution of ‘%s’."),
                         runtime_remote, flatpak_decomposed_get_ref (runtime_ref));

  runtime_commit = flatpak_deploy_data_get_commit (runtime_deploy_data);

  /* Emit a warning and omit it if it's extra-data
   * https://github.com/flatpak/flatpak/issues/969 */
  extra_data_sources = flatpak_repo_get_extra_data_sources (flatpak_dir_get_repo (dir), runtime_commit, NULL, NULL);
  if (extra_data_sources != NULL && g_variant_n_children (extra_data_sources) > 0)
    {
       g_printerr (_("Warning: Omitting ref ‘%s’ (runtime of ‘%s’) because it's extra-data.\n"),
                   flatpak_decomposed_get_ref (runtime_ref), flatpak_decomposed_get_ref (ref));
       return TRUE;
    }

  runtime_subpaths = flatpak_deploy_data_get_subpaths (runtime_deploy_data);
  resolved_runtime_subpaths = get_flatpak_subpaths_from_deploy_subpaths (runtime_subpaths);
  c_s = commit_and_subpaths_new (runtime_commit, (const char * const *) resolved_runtime_subpaths);

  g_hash_table_insert (all_collection_ids, g_strdup (runtime_collection_id), g_strdup (runtime_remote));
  runtime_collection_ref = ostree_collection_ref_new (runtime_collection_id, flatpak_decomposed_get_ref (runtime_ref));
  g_hash_table_insert (all_refs, g_steal_pointer (&runtime_collection_ref), c_s);

  if (!add_related (all_refs, all_collection_ids, runtime_ref, dir, cancellable, error))
    return FALSE;

  return TRUE;
}

/* Copied from src/ostree/ot-builtin-create-usb.c in ostree.git, with slight modifications */
static gboolean
ostree_create_usb (GOptionContext *context,
                   OstreeRepo     *src_repo,
                   const char     *mount_root_path,
                   struct stat     mount_root_stbuf,
                   int             mount_root_dfd,
                   GHashTable     *all_refs,
                   GCancellable   *cancellable,
                   GError        **error)
{
  g_autoptr(OstreeAsyncProgressFinish) progress = NULL;
  g_auto(GLnxConsoleRef) console = { 0, };
  guint num_refs = 0;

  /* Open the destination repository on the USB stick or create it if it doesn’t exist.
   * Check it’s below @mount_root_path, and that it’s not the same as the source
   * repository. */
  const char *dest_repo_path = (opt_destination_repo != NULL) ? opt_destination_repo : ".ostree/repo";

  if (!glnx_shutil_mkdir_p_at (mount_root_dfd, dest_repo_path, 0755, cancellable, error))
    return FALSE;

  /* Always use the archive repo mode, which works on FAT file systems that
   * don't support xattrs, compresses files to save space, doesn't store
   * permission info directly in the file attributes, and is at least sometimes
   * more performant than bare-user */
  OstreeRepoMode mode = OSTREE_REPO_MODE_ARCHIVE;

  g_info ("%s: Creating repository in mode %u", G_STRFUNC, mode);
  g_autoptr(OstreeRepo) dest_repo = ostree_repo_create_at (mount_root_dfd, dest_repo_path,
                                                           mode, NULL, cancellable, error);

  if (dest_repo == NULL)
    return FALSE;

  struct stat dest_repo_stbuf;

  if (!glnx_fstat (ostree_repo_get_dfd (dest_repo), &dest_repo_stbuf, error))
    return FALSE;

  if (dest_repo_stbuf.st_dev != mount_root_stbuf.st_dev)
    return usage_error (context, "--destination-repo must be a descendent of MOUNT-PATH", error);

  if (ostree_repo_equal (src_repo, dest_repo))
    return usage_error (context, "--destination-repo must not be the source repository", error);

  if (!ostree_repo_is_writable (dest_repo, error))
    return glnx_prefix_error (error, "Cannot write to repository");

  /* Copy across all of the collection–refs to the destination repo. We have to
   * do it one ref at a time in order to get the subpaths right. */

  GLNX_HASH_TABLE_FOREACH_KV (all_refs, OstreeCollectionRef *, c_r, CommitAndSubpaths *, c_s)
  {
    GVariantBuilder builder;
    g_autoptr(GVariant) opts = NULL;
    OstreeRepoPullFlags flags = OSTREE_REPO_PULL_FLAGS_MIRROR;
    GVariantBuilder refs_builder;

    num_refs++;

    g_variant_builder_init (&refs_builder, G_VARIANT_TYPE ("a(sss)"));
    g_variant_builder_add (&refs_builder, "(sss)",
                           c_r->collection_id, c_r->ref_name,
                           c_s->commit ? c_s->commit : "");

    glnx_console_lock (&console);

    if (console.is_tty)
      progress = ostree_async_progress_new_and_connect (ostree_repo_pull_default_console_progress_changed, &console);

    g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sv}"));

    g_variant_builder_add (&builder, "{s@v}", "collection-refs",
                           g_variant_new_variant (g_variant_builder_end (&refs_builder)));
    if (c_s->subpaths != NULL)
      {
        g_variant_builder_add (&builder, "{s@v}", "subdirs",
                               g_variant_new_variant (g_variant_new_strv ((const char * const *) c_s->subpaths, -1)));
      }
    g_variant_builder_add (&builder, "{s@v}", "flags",
                           g_variant_new_variant (g_variant_new_int32 (flags)));
    g_variant_builder_add (&builder, "{s@v}", "depth",
                           g_variant_new_variant (g_variant_new_int32 (0)));
    opts = g_variant_ref_sink (g_variant_builder_end (&builder));

    g_autofree char *src_repo_uri = g_file_get_uri (ostree_repo_get_path (src_repo));

    if (!ostree_repo_pull_with_options (dest_repo, src_repo_uri,
                                        opts,
                                        progress,
                                        cancellable, error))
      {
        ostree_repo_abort_transaction (dest_repo, cancellable, NULL);
        return FALSE;
      }

    glnx_console_unlock (&console);
  }

  /* Ensure a summary file is present to make it easier to look up commit checksums. */
  /* FIXME: It should be possible to work without this, but find_remotes_cb() in
   * ostree-repo-pull.c currently assumes a summary file (signed or unsigned) is
   * present. */
  if (!ostree_repo_regenerate_summary (dest_repo, NULL, cancellable, error))
    return FALSE;

  /* Add the symlinks .ostree/repos.d/@symlink_name → @dest_repo_path, unless
   * the @dest_repo_path is a well-known one like ostree/repo, in which case no
   * symlink is necessary; #OstreeRepoFinderMount always looks there. */
  if (!g_str_equal (dest_repo_path, "ostree/repo") &&
      !g_str_equal (dest_repo_path, ".ostree/repo"))
    {
      if (!glnx_shutil_mkdir_p_at (mount_root_dfd, ".ostree/repos.d", 0755, cancellable, error))
        return FALSE;

      /* Find a unique name for the symlink. If a symlink already targets
       * @dest_repo_path, use that and don’t create a new one. */
      GLnxDirFdIterator repos_iter;
      gboolean need_symlink = TRUE;

      if (!glnx_dirfd_iterator_init_at (mount_root_dfd, ".ostree/repos.d", TRUE, &repos_iter, error))
        return FALSE;

      while (TRUE)
        {
          struct dirent *repo_dent;

          if (!glnx_dirfd_iterator_next_dent (&repos_iter, &repo_dent, cancellable, error))
            return FALSE;

          if (repo_dent == NULL)
            break;

          /* Does the symlink already point to this repository? (Or is the
           * repository itself present in repos.d?) We already guarantee that
           * they’re on the same device. */
          if (repo_dent->d_ino == dest_repo_stbuf.st_ino)
            {
              need_symlink = FALSE;
              break;
            }
        }
      glnx_dirfd_iterator_clear (&repos_iter);

      /* If we need a symlink, find a unique name for it and create it. */
      if (need_symlink)
        {
          /* Relative to .ostree/repos.d. */
          g_autofree char *relative_dest_repo_path = g_build_filename ("..", "..", dest_repo_path, NULL);
          guint i;
          const guint max_attempts = 100;

          for (i = 0; i < max_attempts; i++)
            {
              g_autofree char *symlink_path = g_strdup_printf (".ostree/repos.d/%02u-generated", i);

              int ret = TEMP_FAILURE_RETRY (symlinkat (relative_dest_repo_path, mount_root_dfd, symlink_path));
              if (ret < 0 && errno != EEXIST)
                return glnx_throw_errno_prefix (error, "symlinkat(%s → %s)", symlink_path, relative_dest_repo_path);
              else if (ret >= 0)
                break;
            }

          if (i == max_attempts)
            return glnx_throw (error, "Could not find an unused symlink name for the repository");
        }
    }

  /* Report success to the user. */
  g_autofree char *src_repo_path = g_file_get_path (ostree_repo_get_path (src_repo));

  g_print ("Copied %u/%u refs successfully from ‘%s’ to ‘%s’ repository in ‘%s’.\n", num_refs, num_refs,
           src_repo_path, dest_repo_path, mount_root_path);

  return TRUE;
}

gboolean
flatpak_builtin_create_usb (int argc, char **argv, GCancellable *cancellable, GError **error)
{
  g_autoptr(GOptionContext) context = NULL;
  g_autoptr(GPtrArray) dirs = NULL;
  g_autoptr(GHashTable) all_refs = NULL;
  g_autoptr(GHashTable) all_collection_ids = NULL;
  g_autoptr(GHashTable) remote_arch_map = NULL;
  FlatpakDir *dir = NULL;
  char **prefs = NULL;
  unsigned int i, n_prefs;
  FlatpakKinds kinds;
  OstreeRepo *src_repo;

  context = g_option_context_new (_("MOUNT-PATH [REF…] - Copy apps or runtimes onto removable media"));
  g_option_context_set_translation_domain (context, GETTEXT_PACKAGE);

  if (!flatpak_option_context_parse (context, options, &argc, &argv,
                                     FLATPAK_BUILTIN_FLAG_STANDARD_DIRS,
                                     &dirs, cancellable, error))
    return FALSE;

  if (argc < 3)
    return usage_error (context, _("MOUNT-PATH and REF must be specified"), error);

  /* Open the USB stick, which must exist. Allow automounting and following symlinks. */
  const char *mount_root_path = argv[1];
  struct stat mount_root_stbuf;

  glnx_autofd int mount_root_dfd = -1;
  if (!glnx_opendirat (AT_FDCWD, mount_root_path, TRUE, &mount_root_dfd, error))
    return FALSE;
  if (!glnx_fstat (mount_root_dfd, &mount_root_stbuf, error))
    return FALSE;

  prefs = &argv[2];
  n_prefs = argc - 2;

  kinds = flatpak_kinds_from_bools (opt_app, opt_runtime);

  /* This is a mapping from OstreeCollectionRef instances to CommitAndSubpaths
   * structs.  We need to tell ostree which commit to copy because the deployed
   * commit is not necessarily the latest one for a given ref, and we need the
   * subpaths because otherwise ostree will try and fail to pull the whole
   * commit */
  all_refs = g_hash_table_new_full (ostree_collection_ref_hash,
                                    ostree_collection_ref_equal,
                                    (GDestroyNotify) ostree_collection_ref_free,
                                    (GDestroyNotify) commit_and_subpaths_free);

  /* This maps from each remote name to a set of architectures */
  remote_arch_map = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) g_strfreev);

  /* This is a mapping from collection IDs to remote names. It is possible
   * for multiple remotes to have the same collection ID, but in that case
   * they should be mirrors of each other. */
  all_collection_ids = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);

  for (i = 0; i < n_prefs; i++)
    {
      const char *pref = NULL;
      FlatpakKinds matched_kinds;
      g_autofree char *id = NULL;
      g_autofree char *arch = NULL;
      g_autofree char *branch = NULL;
      g_autoptr(GError) local_error = NULL;
      g_autoptr(GError) first_error = NULL;
      g_autoptr(FlatpakDecomposed) installed_ref = NULL;
      g_autoptr(GPtrArray) dirs_with_ref = NULL;
      FlatpakDir *this_ref_dir = NULL;
      g_autofree char *remote = NULL;
      g_autofree char *ref_collection_id = NULL;
      g_autoptr(OstreeCollectionRef) collection_ref = NULL;
      unsigned int j = 0;
      const char **arches;
      FlatpakKinds installed_ref_kind = 0;

      pref = prefs[i];

      if (!flatpak_split_partial_ref_arg (pref, kinds, opt_arch, NULL,
                                          &matched_kinds, &id, &arch, &branch, error))
        return FALSE;

      dirs_with_ref = g_ptr_array_new ();
      for (j = 0; j < dirs->len; j++)
        {
          FlatpakDir *candidate_dir = g_ptr_array_index (dirs, j);
          g_autoptr(FlatpakDecomposed) ref = NULL;

          ref = flatpak_dir_find_installed_ref (candidate_dir, id, branch, arch,
                                                kinds, &local_error);
          if (ref == NULL)
            {
              if (g_error_matches (local_error, FLATPAK_ERROR, FLATPAK_ERROR_NOT_INSTALLED))
                {
                  if (first_error == NULL)
                    first_error = g_steal_pointer (&local_error);
                  g_clear_error (&local_error);
                }
              else
                {
                  g_propagate_error (error, g_steal_pointer (&local_error));
                  return FALSE;
                }
            }
          else
            {
              g_ptr_array_add (dirs_with_ref, candidate_dir);
              if (installed_ref == NULL)
                {
                  installed_ref = flatpak_decomposed_ref (ref);
                  installed_ref_kind = flatpak_decomposed_get_kinds (ref);
                }
            }
        }

      if (dirs_with_ref->len == 0)
        {
          g_assert (first_error != NULL);
          /* No match anywhere, return the first NOT_INSTALLED error */
          g_propagate_error (error, g_steal_pointer (&first_error));
          return FALSE;
        }

      if (dirs_with_ref->len > 1)
        {
          g_autoptr(GString) dir_names = g_string_new ("");
          for (j = 0; j < dirs_with_ref->len; j++)
            {
              FlatpakDir *dir_with_ref = g_ptr_array_index (dirs_with_ref, j);
              g_autofree char *dir_name = flatpak_dir_get_name (dir_with_ref);
              if (j > 0)
                g_string_append (dir_names, ", ");
              g_string_append (dir_names, dir_name);
            }

          return flatpak_fail (error,
                               _("Ref ‘%s’ found in multiple installations: %s. You must specify one."),
                               pref, dir_names->str);
        }

      this_ref_dir = g_ptr_array_index (dirs_with_ref, 0);
      if (dir == NULL)
        dir = this_ref_dir;
      else if (dir != this_ref_dir)
        {
          g_autofree char *dir_name = flatpak_dir_get_name (dir);
          g_autofree char *this_ref_dir_name = flatpak_dir_get_name (this_ref_dir);

          return flatpak_fail (error,
                               _("Refs must all be in the same installation (found in %s and %s)."),
                               dir_name, this_ref_dir_name);
        }

      g_assert (installed_ref);
      if (arch == NULL)
        arch = flatpak_decomposed_dup_arch (installed_ref);
      if (branch == NULL)
        branch = flatpak_decomposed_dup_branch (installed_ref);

      remote = flatpak_dir_get_origin (dir, installed_ref, cancellable, error);
      if (remote == NULL)
        return FALSE;

      ref_collection_id = flatpak_dir_get_remote_collection_id (dir, remote);
      if (ref_collection_id == NULL)
        return flatpak_fail (error,
                             _("Remote ‘%s’ does not have a collection ID set, which is required for P2P distribution of ‘%s’."),
                             remote, flatpak_decomposed_get_ref (installed_ref));

      arches = g_hash_table_lookup (remote_arch_map, remote);
      if (arches == NULL)
        {
          GPtrArray *arches_array = g_ptr_array_new ();
          g_ptr_array_add (arches_array, g_strdup (arch));
          g_ptr_array_add (arches_array, NULL);
          g_hash_table_insert (remote_arch_map, g_strdup (remote), g_ptr_array_free (arches_array, FALSE));
        }
      else if (!g_strv_contains (arches, arch))
        {
          GPtrArray *arches_array = g_ptr_array_new ();
          for (const char **iter = arches; *iter != NULL; ++iter)
            g_ptr_array_add (arches_array, g_strdup (*iter));
          g_ptr_array_add (arches_array, g_strdup (arch));
          g_ptr_array_add (arches_array, NULL);
          g_hash_table_replace (remote_arch_map, g_strdup (remote), g_ptr_array_free (arches_array, FALSE));
        }

      /* Add the main ref */
      {
        g_autoptr(GBytes) deploy_data = NULL;
        g_autoptr(GVariant) extra_data_sources = NULL;
        const char *commit;
        CommitAndSubpaths *c_s;

        deploy_data = flatpak_dir_get_deploy_data (dir, installed_ref, FLATPAK_DEPLOY_VERSION_ANY, cancellable, error);
        if (deploy_data == NULL)
          return FALSE;

        if (flatpak_deploy_data_has_subpaths (deploy_data) && !opt_allow_partial)
          g_printerr (_("Warning: Ref ‘%s’ is partially installed. Use --allow-partial to suppress this message.\n"),
                      flatpak_decomposed_get_ref (installed_ref));

        commit = flatpak_deploy_data_get_commit (deploy_data);

        /* Extra-data flatpaks can't be copied to a USB (the installation will
         * fail on the receiving end if they're offline) so error out if one
         * was specified. https://github.com/flatpak/flatpak/issues/969 */
        extra_data_sources = flatpak_repo_get_extra_data_sources (flatpak_dir_get_repo (dir), commit, NULL, NULL);
        if (extra_data_sources != NULL && g_variant_n_children (extra_data_sources) > 0)
          return flatpak_fail (error,
                               _("Installed ref ‘%s’ is extra-data, and cannot be distributed offline"),
                               flatpak_decomposed_get_ref (installed_ref));

        c_s = commit_and_subpaths_new (commit, NULL);

        g_hash_table_insert (all_collection_ids, g_strdup (ref_collection_id), g_strdup (remote));
        collection_ref = ostree_collection_ref_new (ref_collection_id, flatpak_decomposed_get_ref (installed_ref));
        g_hash_table_insert (all_refs, g_steal_pointer (&collection_ref), c_s);
      }

      /* Add dependencies and related refs */
      if (!(installed_ref_kind & FLATPAK_KINDS_RUNTIME) &&
          !add_runtime (all_refs, all_collection_ids, installed_ref, dir, cancellable, error))
        return FALSE;
      if (!add_related (all_refs, all_collection_ids, installed_ref, dir, cancellable, error))
        return FALSE;
    }

  g_assert (dir);
  src_repo = flatpak_dir_get_repo (dir);

  /* Add ostree-metadata and appstream refs for each collection ID */
  GLNX_HASH_TABLE_FOREACH_KV (all_collection_ids, const char *, collection_id, const char *, remote_name)
  {
    g_autoptr(OstreeCollectionRef) metadata_collection_ref = NULL;
    g_autoptr(OstreeCollectionRef) appstream_collection_ref = NULL;
    g_autoptr(OstreeCollectionRef) appstream2_collection_ref = NULL;
    g_autoptr(FlatpakRemoteState) state = NULL;
    g_autoptr(GError) local_error = NULL;
    g_autofree char *appstream_refspec = NULL;
    g_autofree char *appstream2_refspec = NULL;
    g_autofree char *appstream_ref = NULL;
    g_autofree char *appstream2_ref = NULL;
    const char **remote_arches;

    /* Try to update the repo metadata by creating a FlatpakRemoteState object,
     * but don't fail on error because we want this to work offline. */
    state = flatpak_dir_get_remote_state_optional (dir, remote_name, FALSE, cancellable, &local_error);
    if (state == NULL)
      {
        g_printerr (_("Warning: Couldn't update repo metadata for remote ‘%s’: %s\n"),
                    remote_name, local_error->message);
        g_clear_error (&local_error);
      }

    /* Add the ostree-metadata ref to the list if available */
    metadata_collection_ref = ostree_collection_ref_new (collection_id, OSTREE_REPO_METADATA_REF);
    if (ostree_repo_resolve_collection_ref (src_repo, metadata_collection_ref, FALSE,
                                            OSTREE_REPO_RESOLVE_REV_EXT_NONE,
                                            NULL, NULL, NULL))
      g_hash_table_insert (all_refs, g_steal_pointer (&metadata_collection_ref),
                           commit_and_subpaths_new (NULL, NULL));

    /* Add whatever appstream data is available for each arch */
    remote_arches = g_hash_table_lookup (remote_arch_map, remote_name);
    for (const char **iter = remote_arches; iter != NULL && *iter != NULL; ++iter)
      {
        const char *current_arch = *iter;
        g_autoptr(GPtrArray) appstream_dirs = NULL;
        g_autoptr(GError) appstream_error = NULL;
        g_autoptr(GError) appstream2_error = NULL;
        g_autofree char *commit = NULL;
        g_autofree char *commit2 = NULL;

        /* Try to update the appstream data, but don't fail on error because we
         * want this to work offline. */
        appstream_dirs = g_ptr_array_new ();
        g_ptr_array_add (appstream_dirs, dir);
        if (!update_appstream (appstream_dirs, remote_name, current_arch, 0, TRUE, cancellable, &local_error))
          {
            g_printerr (_("Warning: Couldn't update appstream data for remote ‘%s’ arch ‘%s’: %s\n"),
                        remote_name, current_arch, local_error->message);
            g_clear_error (&local_error);
          }

        /* Copy the appstream data if it exists. It's optional because without it
         * the USB will still be useful to the flatpak CLI even if GNOME Software
         * wouldn't display the contents. */
        appstream_refspec = g_strdup_printf ("%s:appstream/%s", remote_name, current_arch);
        appstream_ref = g_strdup_printf ("appstream/%s", current_arch);
        appstream_collection_ref = ostree_collection_ref_new (collection_id, appstream_ref);
        if (ostree_repo_resolve_rev (src_repo, appstream_refspec, FALSE,
                                     &commit, &appstream_error))
          {
            g_hash_table_insert (all_refs, g_steal_pointer (&appstream_collection_ref),
                                 commit_and_subpaths_new (commit, NULL));
          }

        /* Copy the appstream2 data if it exists. */
        appstream2_refspec = g_strdup_printf ("%s:appstream2/%s", remote_name, current_arch);
        appstream2_ref = g_strdup_printf ("appstream2/%s", current_arch);
        appstream2_collection_ref = ostree_collection_ref_new (collection_id, appstream2_ref);
        if (ostree_repo_resolve_rev (src_repo, appstream2_refspec, FALSE,
                                     &commit2, &appstream2_error))
          {
            g_hash_table_insert (all_refs, g_steal_pointer (&appstream2_collection_ref),
                                 commit_and_subpaths_new (commit2, NULL));
          }
        else
          {
            if (appstream_error != NULL)
              {
                /* Print a warning if both appstream and appstream2 are missing */
                g_printerr (_("Warning: Couldn't find appstream data for remote ‘%s’ arch ‘%s’: %s; %s\n"),
                            remote_name, current_arch, appstream2_error->message, appstream_error->message);
              }
            else
              {
                /* Appstream2 is only for efficiency, so just print a debug message */
                g_info (_("Couldn't find appstream2 data for remote ‘%s’ arch ‘%s’: %s\n"),
                         remote_name, current_arch, appstream2_error->message);
              }
          }
      }
  }

  /* Delete the local source repo summary if it exists. Old versions of this
   * command erroneously created it and if it's outdated that causes problems. */
  if (!flatpak_dir_update_summary (dir, TRUE, cancellable, error))
    return FALSE;

  /* Now use code copied from `ostree create-usb` to do the actual copying. We
   * can't just call out to `ostree` because (a) flatpak doesn't have a
   * dependency on the ostree command line tools and (b) we need to only pull
   * certain subpaths for partial refs. */
  /* FIXME: Use libostree after fixing https://github.com/ostreedev/ostree/issues/1610 */
  {
    g_autoptr(GString) all_refs_str = g_string_new ("");

    GLNX_HASH_TABLE_FOREACH (all_refs, OstreeCollectionRef *, collection_ref)
    {
      if (!ostree_validate_collection_id (collection_ref->collection_id, error))
        return FALSE;
      if (!ostree_validate_rev (collection_ref->ref_name, error))
        return FALSE;

      g_string_append_printf (all_refs_str, "(%s, %s) ", collection_ref->collection_id, collection_ref->ref_name);
    }
    g_info ("Copying the following refs: %s", all_refs_str->str);

    if (!ostree_create_usb (context, src_repo, mount_root_path, mount_root_stbuf,
                            mount_root_dfd, all_refs, cancellable, error))
      return FALSE;
  }

  return TRUE;
}

gboolean
flatpak_complete_create_usb (FlatpakCompletion *completion)
{
  g_autoptr(GOptionContext) context = NULL;
  g_autoptr(GPtrArray) dirs = NULL;
  FlatpakKinds kinds;
  int i;

  context = g_option_context_new ("");
  if (!flatpak_option_context_parse (context, options, &completion->argc, &completion->argv,
                                     FLATPAK_BUILTIN_FLAG_STANDARD_DIRS, &dirs, NULL, NULL))
    return FALSE;

  kinds = flatpak_kinds_from_bools (opt_app, opt_runtime);

  switch (completion->argc)
    {
    case 0:
    case 1: /* MOUNT-PATH */
      flatpak_complete_options (completion, global_entries);
      flatpak_complete_options (completion, options);
      flatpak_complete_options (completion, user_entries);

      flatpak_complete_file (completion, "__FLATPAK_DIR");

      break;

    default: /* REF */
      for (i = 0; i < dirs->len; i++)
        {
          FlatpakDir *dir = g_ptr_array_index (dirs, i);
          flatpak_complete_partial_ref (completion, kinds, opt_arch, dir, NULL);
        }
      break;
    }

  return TRUE;
}

===== ./app/flatpak-builtins-kill.c =====
/* vi:set et sw=2 sts=2 cin cino=t0,f0,(0,{s,>2s,n-s,^-s,e-s:
 * Copyright © 2018 Red Hat, Inc
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Matthias Clasen <mclasen@redhat.com>
 */

#include "config.h"

#include <locale.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <signal.h>

#include <glib/gi18n.h>

#include "libglnx.h"

#include "flatpak-builtins.h"
#include "flatpak-instance.h"

#define FLATPAK_BUILTIN_KILL_N_RETRIES 5
#define FLATPAK_BUILTIN_KILL_RETRY_SLEEP_USEC (G_USEC_PER_SEC / 10)

static GOptionEntry options[] = {
  { NULL }
};

static gboolean
instance_equal (FlatpakInstance *a,
                FlatpakInstance *b)
{
  return g_strcmp0 (flatpak_instance_get_id (a),
                    flatpak_instance_get_id (b)) == 0;
}

static GPtrArray *
kill_instances (GPtrArray *kill_list)
{
  g_autoptr(GPtrArray) instances = flatpak_instance_get_all ();
  g_autoptr(GPtrArray) remaining =
    g_ptr_array_new_with_free_func (g_object_unref);

  for (size_t i = 0; i < kill_list->len; i++)
    {
      FlatpakInstance *to_kill = g_ptr_array_index (kill_list, i);
      pid_t pid;

      if (!g_ptr_array_find_with_equal_func (instances, to_kill,
                                             (GEqualFunc) instance_equal,
                                             NULL))
        {
          g_info ("Instance %s disappeared", flatpak_instance_get_id (to_kill));
          continue;
        }

      pid = flatpak_instance_get_child_pid (to_kill);
      if (pid != 0)
        {
          kill (pid, SIGKILL);
          g_info ("Instance %s killed", flatpak_instance_get_id (to_kill));
          continue;
        }

      g_ptr_array_add (remaining, g_object_ref (to_kill));
    }

  return g_steal_pointer (&remaining);
}

static gboolean
kill_id (const char  *id,
         GError     **error)
{
  g_autoptr(GPtrArray) instances = flatpak_instance_get_all ();
  g_autoptr(GPtrArray) kill_list =
    g_ptr_array_new_with_free_func (g_object_unref);

  for (size_t i = 0; i < instances->len; i++)
    {
      FlatpakInstance *instance = g_ptr_array_index (instances, i);

      if (g_strcmp0 (id, flatpak_instance_get_app (instance)) != 0 &&
          g_strcmp0 (id, flatpak_instance_get_id (instance)) != 0)
        continue;

      g_info ("Found instance %s to kill", flatpak_instance_get_id (instance));

      g_ptr_array_add (kill_list, g_object_ref (instance));
    }

  if (kill_list->len == 0)
    return flatpak_fail (error, _("%s is not running"), id);

  for (size_t i = 0; i < FLATPAK_BUILTIN_KILL_N_RETRIES && kill_list->len > 0; i++)
    {
      g_autoptr (GPtrArray) remaining = NULL;

      if (i > 0)
        g_usleep (FLATPAK_BUILTIN_KILL_RETRY_SLEEP_USEC);

      remaining = kill_instances (kill_list);
      g_clear_pointer (&kill_list, g_ptr_array_unref);
      kill_list = g_steal_pointer (&remaining);
    }

  return TRUE;
}

gboolean
flatpak_builtin_kill (int           argc,
                      char        **argv,
                      GCancellable *cancellable,
                      GError      **error)
{
  g_autoptr(GOptionContext) context = NULL;
  const char *id;

  context = g_option_context_new (_("INSTANCE - Stop a running application"));
  g_option_context_set_translation_domain (context, GETTEXT_PACKAGE);

  if (!flatpak_option_context_parse (context, options, &argc, &argv, FLATPAK_BUILTIN_FLAG_NO_DIR, NULL, cancellable, error))
    return FALSE;

  if (argc > 2)
    {
      usage_error (context, _("Extra arguments given"), error);
      return FALSE;
    }

  if (argc < 2)
    {
      usage_error (context, _("Must specify the app to kill"), error);
      return FALSE;
    }

  id = argv[1];

  return kill_id (id, error);
}

gboolean
flatpak_complete_kill (FlatpakCompletion *completion)
{
  g_autoptr(GOptionContext) context = NULL;
  g_autoptr(GPtrArray) instances = NULL;
  int i;

  context = g_option_context_new ("");
  if (!flatpak_option_context_parse (context, options, &completion->argc, &completion->argv, FLATPAK_BUILTIN_FLAG_NO_DIR, NULL, NULL, NULL))
    return FALSE;

  switch (completion->argc)
    {
    case 0:
    case 1: /* NAME */
      flatpak_complete_options (completion, global_entries);
      flatpak_complete_options (completion, options);

      instances = flatpak_instance_get_all ();
      for (i = 0; i < instances->len; i++)
        {
          FlatpakInstance *instance = (FlatpakInstance *) g_ptr_array_index (instances, i);

          const char *app_name = flatpak_instance_get_app (instance);
          if (app_name)
            flatpak_complete_word (completion, "%s ", app_name);

          flatpak_complete_word (completion, "%s ", flatpak_instance_get_id (instance));
        }
      break;

    default:
      break;
    }

  return TRUE;
}

===== ./app/flatpak-builtins-build-sign.c =====
/* vi:set et sw=2 sts=2 cin cino=t0,f0,(0,{s,>2s,n-s,^-s,e-s:
 * Copyright © 2014 Red Hat, Inc
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Alexander Larsson <alexl@redhat.com>
 */

#include "config.h"

#include <locale.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

#include <glib/gi18n.h>

#include "libglnx.h"

#include "flatpak-builtins.h"
#include "flatpak-repo-utils-private.h"
#include "flatpak-utils-private.h"

static char *opt_arch;
static gboolean opt_runtime;
static char **opt_gpg_key_ids;
static char *opt_gpg_homedir;

static GOptionEntry options[] = {
  { "arch", 0, 0, G_OPTION_ARG_STRING, &opt_arch, N_("Arch to install for"), N_("ARCH") },
  { "runtime", 0, 0, G_OPTION_ARG_NONE, &opt_runtime, N_("Look for runtime with the specified name"), NULL },
  { "gpg-sign", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_gpg_key_ids, N_("GPG Key ID to sign the commit with"), N_("KEY-ID") },
  { "gpg-homedir", 0, 0, G_OPTION_ARG_STRING, &opt_gpg_homedir, N_("GPG Homedir to use when looking for keyrings"), N_("HOMEDIR") },
  { NULL }
};


gboolean
flatpak_builtin_build_sign (int argc, char **argv, GCancellable *cancellable, GError **error)
{
  g_autoptr(GOptionContext) context = NULL;
  g_autoptr(GFile) repofile = NULL;
  g_autoptr(OstreeRepo) repo = NULL;
  g_autoptr(GError) my_error = NULL;
  const char *location;
  const char *branch;
  const char *id = NULL;
  g_autofree char *commit_checksum = NULL;
  int i;
  char **iter;
  g_autoptr(GPtrArray) refs = g_ptr_array_new_with_free_func (g_free);
  const char *collection_id;

  context = g_option_context_new (_("LOCATION [ID [BRANCH]] - Sign an application or runtime"));
  g_option_context_set_translation_domain (context, GETTEXT_PACKAGE);

  if (!flatpak_option_context_parse (context, options, &argc, &argv, FLATPAK_BUILTIN_FLAG_NO_DIR, NULL, cancellable, error))
    return FALSE;

  if (argc < 2)
    return usage_error (context, _("LOCATION must be specified"), error);

  if (argc > 4)
    return usage_error (context, _("Too many arguments"), error);

  location = argv[1];
  if (argc >= 3)
    id = argv[2];

  if (argc >= 4)
    branch = argv[3];
  else
    branch = "master";

  if (id != NULL && !flatpak_is_valid_name (id, -1, &my_error))
    return flatpak_fail (error, _("'%s' is not a valid name: %s"), id, my_error->message);

  if (!flatpak_is_valid_branch (branch, -1, &my_error))
    return flatpak_fail (error, _("'%s' is not a valid branch name: %s"), branch, my_error->message);

  if (opt_gpg_key_ids == NULL)
    return flatpak_fail (error, _("No gpg key ids specified"));

  repofile = g_file_new_for_commandline_arg (location);
  repo = ostree_repo_new (repofile);

  if (!ostree_repo_open (repo, cancellable, error))
    return FALSE;

  collection_id = ostree_repo_get_collection_id (repo);

  if (id)
    {
      g_autofree char *ref = NULL;
      if (opt_runtime)
        ref = flatpak_build_runtime_ref (id, branch, opt_arch);
      else
        ref = flatpak_build_app_ref (id, branch, opt_arch);

      g_ptr_array_add (refs, g_steal_pointer (&ref));
    }
  else
    {
      g_autoptr(GHashTable) all_refs = NULL;
      GHashTableIter hashiter;
      gpointer key, value;

      if (!ostree_repo_list_refs_ext (repo, NULL, &all_refs,
                                      OSTREE_REPO_LIST_REFS_EXT_NONE,
                                      cancellable, error))
        return FALSE;

      /* Merge the prefix refs to the full refs table */
      g_hash_table_iter_init (&hashiter, all_refs);
      while (g_hash_table_iter_next (&hashiter, &key, &value))
        {
          if (g_str_has_prefix (key, "app/") ||
              g_str_has_prefix (key, "runtime/"))
            g_ptr_array_add (refs, g_strdup (key));
        }
    }

  for (i = 0; i < refs->len; i++)
    {
      const char *ref = g_ptr_array_index (refs, i);

      if (!flatpak_repo_resolve_rev (repo, collection_id, NULL, ref, FALSE,
                                     &commit_checksum, cancellable, error))
        return FALSE;

      for (iter = opt_gpg_key_ids; iter && *iter; iter++)
        {
          const char *keyid = *iter;
          g_autoptr(GError) local_error = NULL;

          if (!ostree_repo_sign_commit (repo,
                                        commit_checksum,
                                        keyid,
                                        opt_gpg_homedir,
                                        cancellable,
                                        &local_error))
            {
              if (!g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_EXISTS))
                {
                  g_propagate_error (error, g_steal_pointer (&local_error));
                  return FALSE;
                }
            }
        }
    }

  return TRUE;
}

gboolean
flatpak_complete_build_sign (FlatpakCompletion *completion)
{
  g_autoptr(GOptionContext) context = NULL;

  context = g_option_context_new ("");

  if (!flatpak_option_context_parse (context, options, &completion->argc, &completion->argv,
                                     FLATPAK_BUILTIN_FLAG_NO_DIR, NULL, NULL, NULL))
    return FALSE;

  switch (completion->argc)
    {
    case 0:
    case 1: /* LOCATION */
      flatpak_complete_options (completion, global_entries);
      flatpak_complete_options (completion, options);

      flatpak_complete_dir (completion);
      break;

    case 2: /* ID */
      break;

    case 3: /* BRANCH */
      break;
    }

  return TRUE;
}

===== ./app/flatpak-builtins-make-current.c =====
/* vi:set et sw=2 sts=2 cin cino=t0,f0,(0,{s,>2s,n-s,^-s,e-s:
 * Copyright © 2014 Red Hat, Inc
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Alexander Larsson <alexl@redhat.com>
 */

#include "config.h"

#include <locale.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

#include <glib/gi18n.h>

#include "libglnx.h"

#include "flatpak-builtins.h"
#include "flatpak-utils-private.h"

static char *opt_arch;

static GOptionEntry options[] = {
  { "arch", 0, 0, G_OPTION_ARG_STRING, &opt_arch, N_("Arch to make current for"), N_("ARCH") },
  { NULL }
};

gboolean
flatpak_builtin_make_current_app (int argc, char **argv, GCancellable *cancellable, GError **error)
{
  g_autoptr(GOptionContext) context = NULL;
  g_autoptr(GPtrArray) dirs = NULL;
  FlatpakDir *dir;
  g_autoptr(GFile) deploy_base = NULL;
  const char *pref;
  const char *default_branch = NULL;
  g_auto(GLnxLockFile) lock = { 0, };
  g_autofree char *id = NULL;
  g_autofree char *arch = NULL;
  g_autofree char *branch = NULL;
  g_autoptr(FlatpakDecomposed) ref = NULL;
  FlatpakKinds kinds;

  context = g_option_context_new (_("APP BRANCH - Make branch of application current"));
  g_option_context_set_translation_domain (context, GETTEXT_PACKAGE);

  if (!flatpak_option_context_parse (context, options, &argc, &argv,
                                     FLATPAK_BUILTIN_FLAG_ONE_DIR,
                                     &dirs, cancellable, error))
    return FALSE;

  dir = g_ptr_array_index (dirs, 0);

  if (argc < 2)
    return usage_error (context, _("APP must be specified"), error);

  if (argc > 3)
    return usage_error (context, _("Too many arguments"), error);

  pref = argv[1];

  if (argc >= 3)
    default_branch = argv[2];

  if (!flatpak_split_partial_ref_arg (pref, FLATPAK_KINDS_APP, opt_arch, default_branch,
                                      &kinds, &id, &arch, &branch, error))
    return FALSE;

  if (branch == NULL)
    return usage_error (context, _("BRANCH must be specified"), error);

  ref = flatpak_dir_find_installed_ref (dir, id, branch, arch, FLATPAK_KINDS_APP,
                                        error);
  if (ref == NULL)
    return FALSE;

  if (!flatpak_dir_lock (dir, &lock,
                         cancellable, error))
    return FALSE;

  deploy_base = flatpak_dir_get_deploy_dir (dir, ref);
  if (!g_file_query_exists (deploy_base, cancellable))
    return flatpak_fail (error, _("App %s branch %s is not installed"), id, branch);

  if (!flatpak_dir_make_current_ref (dir, ref, cancellable, error))
    return FALSE;

  if (!flatpak_dir_update_exports (dir, id, cancellable, error))
    return FALSE;

  glnx_release_lock_file (&lock);

  if (!flatpak_dir_mark_changed (dir, error))
    return FALSE;

  return TRUE;
}

gboolean
flatpak_complete_make_current_app (FlatpakCompletion *completion)
{
  g_autoptr(GOptionContext) context = NULL;
  g_autoptr(GPtrArray) dirs = NULL;
  FlatpakDir *dir;
  g_autoptr(GError) error = NULL;
  g_autoptr(GPtrArray) refs = NULL;

  context = g_option_context_new ("");
  if (!flatpak_option_context_parse (context, options, &completion->argc, &completion->argv,
                                     FLATPAK_BUILTIN_FLAG_ONE_DIR | FLATPAK_BUILTIN_FLAG_OPTIONAL_REPO,
                                     &dirs, NULL, NULL))
    return FALSE;

  dir = g_ptr_array_index (dirs, 0);

  switch (completion->argc)
    {
    case 0:
    case 1: /* NAME */
      flatpak_complete_options (completion, global_entries);
      flatpak_complete_options (completion, options);
      flatpak_complete_options (completion, user_entries);

      refs = flatpak_dir_find_installed_refs (dir, NULL, NULL, opt_arch,
                                              FLATPAK_KINDS_APP,
                                              FIND_MATCHING_REFS_FLAGS_NONE,
                                              &error);
      if (refs == NULL)
        flatpak_completion_debug ("find installed refs error: %s", error->message);
      flatpak_complete_ref_id (completion, refs);
      break;

    case 2: /* Branch */
      refs = flatpak_dir_find_installed_refs (dir, completion->argv[1], NULL, opt_arch,
                                              FLATPAK_KINDS_APP,
                                              FIND_MATCHING_REFS_FLAGS_NONE,
                                              &error);
      if (refs == NULL)
        flatpak_completion_debug ("find installed refs error: %s", error->message);

      flatpak_complete_ref_branch (completion, refs);
      break;

    default:
      break;
    }

  return TRUE;
}

===== ./app/flatpak-builtins-history.c =====
/* vi:set et sw=2 sts=2 cin cino=t0,f0,(0,{s,>2s,n-s,^-s,e-s:
 * Copyright © 2018 Red Hat, Inc
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Matthias Clasen
 */

#include "config.h"

#include <locale.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <pwd.h>

#include <glib/gi18n.h>

#include "libglnx.h"

#ifdef HAVE_LIBSYSTEMD
#include <systemd/sd-journal.h>
#endif

#include "flatpak-builtins.h"
#include "flatpak-builtins-utils.h"
#include "flatpak-utils-private.h"
#include "flatpak-table-printer.h"

static char *opt_since;
static char *opt_until;
static gboolean opt_reverse;
static const char **opt_cols;
static gboolean opt_json;

static GOptionEntry options[] = {
  { "since", 0, 0, G_OPTION_ARG_STRING, &opt_since, N_("Only show changes after TIME"), N_("TIME") },
  { "until", 0, 0, G_OPTION_ARG_STRING, &opt_until, N_("Only show changes before TIME"), N_("TIME") },
  { "reverse", 0, 0, G_OPTION_ARG_NONE, &opt_reverse, N_("Show newest entries first"), NULL },
  { "columns", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_cols, N_("What information to show"), N_("FIELD,…") },
  { "json", 'j', 0, G_OPTION_ARG_NONE, &opt_json, N_("Show output in JSON format"), NULL },
  { NULL }
};

static Column all_columns[] = {
  { "time",         N_("Time"),         N_("Show when the change happened"),   0, FLATPAK_ELLIPSIZE_MODE_NONE, 1, 1 },
  { "change",       N_("Change"),       N_("Show the kind of change"),         0, FLATPAK_ELLIPSIZE_MODE_NONE, 1, 1 },
  { "ref",          N_("Ref"),          N_("Show the ref"),                    0, FLATPAK_ELLIPSIZE_MODE_NONE, 0, 0 },
  { "application",  N_("Application"),  N_("Show the application/runtime ID"), 0, FLATPAK_ELLIPSIZE_MODE_NONE, 1, 1 },
  { "arch",         N_("Arch"),         N_("Show the architecture"),           0, FLATPAK_ELLIPSIZE_MODE_NONE, 1, 0 },
  { "branch",       N_("Branch"),       N_("Show the branch"),                 0, FLATPAK_ELLIPSIZE_MODE_NONE, 1, 1 },
  { "installation", N_("Installation"), N_("Show the affected installation"),  0, FLATPAK_ELLIPSIZE_MODE_NONE, 1, 1 },
  { "remote",       N_("Remote"),       N_("Show the remote"),                 0, FLATPAK_ELLIPSIZE_MODE_NONE, 1, 1 },
  { "commit",       N_("Commit"),       N_("Show the current commit"),         0, FLATPAK_ELLIPSIZE_MODE_NONE, 1, 0 },
  { "old-commit",   N_("Old Commit"),   N_("Show the previous commit"),        0, FLATPAK_ELLIPSIZE_MODE_NONE, 1, 0 },
  { "url",          N_("URL"),          N_("Show the remote URL"),             0, FLATPAK_ELLIPSIZE_MODE_NONE, 1, 0 },
  { "user",         N_("User"),         N_("Show the user doing the change"),  0, FLATPAK_ELLIPSIZE_MODE_NONE, 1, 0 },
  { "tool",         N_("Tool"),         N_("Show the tool that was used"),     0, FLATPAK_ELLIPSIZE_MODE_NONE, 1, 0 },
  { "version",      N_("Version"),      N_("Show the Flatpak version"),        0, FLATPAK_ELLIPSIZE_MODE_NONE, 1, 0 },
  { NULL }
};

#ifdef HAVE_LIBSYSTEMD

static char *
get_field (sd_journal *j,
           const char *name,
           GError    **error)
{
  const char *data;
  gsize len;
  int r;

  if ((r = sd_journal_get_data (j, name, (const void **) &data, &len)) < 0)
    {
      if (r != -ENOENT)
        g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
                     _("Failed to get journal data (%s): %s"),
                     name, strerror (-r));

      return NULL;
    }

  return g_strndup (data + strlen (name) + 1, len - (strlen (name) + 1));
}

static GDateTime *
get_time (sd_journal *j,
          GError    **error)
{
  g_autofree char *value = NULL;
  GError *local_error = NULL;
  gint64 t;

  value = get_field (j, "_SOURCE_REALTIME_TIMESTAMP", &local_error);

  if (local_error)
    {
      g_propagate_error (error, local_error);
      return NULL;
    }

  t = g_ascii_strtoll (value, NULL, 10) / 1000000;
  return g_date_time_new_from_unix_local (t);
}

static gboolean
print_history (GPtrArray    *dirs,
               Column       *columns,
               GDateTime    *since,
               GDateTime    *until,
               gboolean      reverse,
               GCancellable *cancellable,
               GError      **error)
{
  g_autoptr(FlatpakTablePrinter) printer = NULL;
  sd_journal *j;
  int r;
  int i;
  int k;
  int ret;

  if (columns[0].name == NULL)
    return TRUE;

  printer = flatpak_table_printer_new ();

  flatpak_table_printer_set_columns (printer, columns, opt_cols == NULL);

  if ((r = sd_journal_open (&j, 0)) < 0)
    {
      g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
                   _("Failed to open journal: %s"), strerror (-r));
      return FALSE;
    }

  if ((r = sd_journal_add_match (j, "MESSAGE_ID=" FLATPAK_MESSAGE_ID, 0)) < 0)
    {
      g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
                   _("Failed to add match to journal: %s"), strerror (-r));
      return FALSE;
    }

  if (reverse)
    ret = sd_journal_seek_tail (j);
  else
    ret = sd_journal_seek_head (j);
  if (ret == 0)
    while ((reverse && sd_journal_previous (j) > 0) ||
           (!reverse && sd_journal_next (j) > 0))
      {
        g_autofree char *ref_str = NULL;
        g_autofree char *remote = NULL;

        /* determine whether to skip this entry */

        ref_str = get_field (j, "REF", error);
        if (*error)
          return FALSE;

        /* Appstream pulls are probably not interesting, and they are confusing
         * since by default we include the Application column which shows up blank.
         */
        if (ref_str && ref_str[0] && g_str_has_prefix (ref_str, "appstream"))
          continue;

        remote = get_field (j, "REMOTE", error);
        if (*error)
          return FALSE;

        /* Exclude pull to temp repo */
        if (remote && remote[0] == '/')
          continue;

        if (dirs)
          {
            gboolean include = FALSE;
            g_autofree char *installation = get_field (j, "INSTALLATION", NULL);

            for (i = 0; i < dirs->len && !include; i++)
              {
                g_autofree char *name = flatpak_dir_get_name (dirs->pdata[i]);
                if (g_strcmp0 (name, installation) == 0)
                  include = TRUE;
              }
            if (!include)
              continue;
          }

        if (since || until)
          {
            g_autoptr(GDateTime) time = get_time (j, NULL);

            if (since && time && g_date_time_difference (since, time) >= 0)
              continue;

            if (until && time && g_date_time_difference (until, time) <= 0)
              continue;
          }

        for (k = 0; columns[k].name; k++)
          {
            if (strcmp (columns[k].name, "time") == 0)
              {
                g_autoptr(GDateTime) time = NULL;
                g_autofree char *s = NULL;

                time = get_time (j, error);
                if (*error)
                  return FALSE;

                s = g_date_time_format (time, "%b %e %T");
                flatpak_table_printer_add_column (printer, s);
              }
            else if (strcmp (columns[k].name, "change") == 0)
              {
                g_autofree char *op = get_field (j, "OPERATION", error);
                if (*error)
                  return FALSE;
                flatpak_table_printer_add_column (printer, op);
              }
            else if (strcmp (columns[k].name, "ref") == 0 ||
                     strcmp (columns[k].name, "application") == 0 ||
                     strcmp (columns[k].name, "arch") == 0 ||
                     strcmp (columns[k].name, "branch") == 0)
              {
                g_autofree char *value = NULL;

                if (ref_str && ref_str[0] &&
                    !flatpak_is_app_runtime_or_appstream_ref (ref_str) &&
                    g_strcmp0 (ref_str, OSTREE_REPO_METADATA_REF) != 0)
                  g_warning ("Unknown ref in history: %s", ref_str);

                if (strcmp (columns[k].name, "ref") == 0)
                  value = g_strdup (ref_str);
                else if (ref_str && ref_str[0] &&
                         (g_str_has_prefix (ref_str, "app/") ||
                          g_str_has_prefix (ref_str, "runtime/")))
                  {
                    g_autoptr(FlatpakDecomposed) ref = NULL;
                    ref = flatpak_decomposed_new_from_ref (ref_str, NULL);
                    if (ref == NULL)
                      g_warning ("Invalid ref in history: %s", ref_str);
                    else
                      {
                        if (strcmp (columns[k].name, "application") == 0)
                          value = flatpak_decomposed_dup_id (ref);
                        else if (strcmp (columns[k].name, "arch") == 0)
                          value = flatpak_decomposed_dup_arch (ref);
                        else
                          value = flatpak_decomposed_dup_branch (ref);
                      }
                  }

                  flatpak_table_printer_add_column (printer, value);
              }
            else if (strcmp (columns[k].name, "installation") == 0)
              {
                g_autofree char *installation = get_field (j, "INSTALLATION", error);
                if (*error)
                  return FALSE;
                flatpak_table_printer_add_column (printer, installation);
              }
            else if (strcmp (columns[k].name, "remote") == 0)
              {
                flatpak_table_printer_add_column (printer, remote);
              }
            else if (strcmp (columns[k].name, "commit") == 0)
              {
                g_autofree char *commit = get_field (j, "COMMIT", error);
                if (*error)
                  return FALSE;
                flatpak_table_printer_add_column_len (printer, commit, 12);
              }
            else if (strcmp (columns[k].name, "old-commit") == 0)
              {
                g_autofree char *old_commit = get_field (j, "OLD_COMMIT", error);
                if (*error)
                  return FALSE;
                flatpak_table_printer_add_column_len (printer, old_commit, 12);
              }
            else if (strcmp (columns[k].name, "url") == 0)
              {
                g_autofree char *url = get_field (j, "URL", error);
                if (*error)
                  return FALSE;
                flatpak_table_printer_add_column (printer, url);
              }
            else if (strcmp (columns[k].name, "user") == 0)
              {
                g_autofree char *id = get_field (j, "_UID", error);
                g_autofree char *oid = NULL;
                uid_t uid;
                struct passwd *pwd;

                if (*error)
                  return FALSE;

                uid = (uid_t) g_ascii_strtoull (id, NULL, 10);
                pwd = getpwuid (uid);
                if (pwd)
                  {
                    g_free (id);
                    id = g_strdup (pwd->pw_name);
                  }

                oid = get_field (j, "OBJECT_UID", NULL);
                if (oid)
                  {
                    /* flatpak-system-helper acting on behalf of sb else */
                    g_autofree char *str = NULL;
                    uid = (uid_t) g_ascii_strtoull (oid, NULL, 10);
                    pwd = getpwuid (uid);
                    str = g_strdup_printf ("%s (%s)", id, pwd ? pwd->pw_name : oid);
                    flatpak_table_printer_add_column (printer, str);
                  }
                else
                  flatpak_table_printer_add_column (printer, id);
              }
            else if (strcmp (columns[k].name, "tool") == 0)
              {
                g_autofree char *exe = get_field (j, "_EXE", error);
                g_autofree char *oexe = NULL;
                g_autofree char *tool = NULL;
                if (*error)
                  return FALSE;
                tool = g_path_get_basename (exe);
                oexe = get_field (j, "OBJECT_EXE", NULL);
                if (oexe)
                  {
                    /* flatpak-system-helper acting on behalf of sb else */
                    g_autofree char *otool = NULL;
                    g_autofree char *str = NULL;

                    otool = g_path_get_basename (oexe);
                    str = g_strdup_printf ("%s (%s)", tool, otool);
                    flatpak_table_printer_add_column (printer, str);
                  }
                else
                  flatpak_table_printer_add_column (printer, tool);
              }
            else if (strcmp (columns[k].name, "version") == 0)
              {
                g_autofree char *version = get_field (j, "FLATPAK_VERSION", error);
                if (*error)
                  return FALSE;
                flatpak_table_printer_add_column (printer, version);
              }
          }

        flatpak_table_printer_finish_row (printer);
      }

  opt_json ? flatpak_table_printer_print_json (printer) : flatpak_table_printer_print (printer);

  sd_journal_close (j);

  return TRUE;
}

#else

static gboolean
print_history (GPtrArray    *dirs,
               Column       *columns,
               GDateTime    *since,
               GDateTime    *until,
               gboolean      reverse,
               GCancellable *cancellable,
               GError      **error)
{
  if (columns[0].name == NULL)
    return TRUE;

  g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "history not available without libsystemd");
  return FALSE;
}

#endif

static GDateTime *
parse_time (const char *since_opt)
{
  g_autoptr(GDateTime) now = NULL;
  g_auto(GStrv) parts = NULL;
  int i;
  int days = 0;
  int hours = 0;
  int minutes = 0;
  int seconds = 0;
  const char *fmts[] = {
    "%H:%M",
    "%H:%M:%S",
    "%Y-%m-%d",
    "%Y-%m-%d %H:%M:%S"
  };

  now = g_date_time_new_now_local ();

  for (i = 0; i < G_N_ELEMENTS (fmts); i++)
    {
      const char *rest;
      struct tm tm;

      tm.tm_year = g_date_time_get_year (now);
      tm.tm_mon = g_date_time_get_month (now);
      tm.tm_mday = g_date_time_get_day_of_month (now);
      tm.tm_hour = 0;
      tm.tm_min = 0;
      tm.tm_sec = 0;

      rest = strptime (since_opt, fmts[i], &tm);
      if (rest && *rest == '\0')
        return g_date_time_new_local (tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec);
    }

  parts = g_strsplit (since_opt, " ", -1);

  for (i = 0; parts[i]; i++)
    {
      gint64 n;
      char *end;

      n = g_ascii_strtoll (parts[i], &end, 10);
      if (g_strcmp0 (end, "d") == 0 ||
          g_strcmp0 (end, "day") == 0 ||
          g_strcmp0 (end, "days") == 0)
        days = (int) n;
      else if (g_strcmp0 (end, "h") == 0 ||
               g_strcmp0 (end, "hour") == 0 ||
               g_strcmp0 (end, "hours") == 0)
        hours = (int) n;
      else if (g_strcmp0 (end, "m") == 0 ||
               g_strcmp0 (end, "minute") == 0 ||
               g_strcmp0 (end, "minutes") == 0)
        minutes = (int) n;
      else if (g_strcmp0 (end, "s") == 0 ||
               g_strcmp0 (end, "second") == 0 ||
               g_strcmp0 (end, "seconds") == 0)
        seconds = (int) n;
      else
        return NULL;
    }

  return g_date_time_add_full (now, 0, 0, -days, -hours, -minutes, -seconds);
}

gboolean
flatpak_builtin_history (int argc, char **argv, GCancellable *cancellable, GError **error)
{
  g_autoptr(GOptionContext) context = NULL;
  g_autoptr(GPtrArray) dirs = NULL;
  g_autoptr(GDateTime) since = NULL;
  g_autoptr(GDateTime) until = NULL;
  g_autofree char *col_help = NULL;
  g_autofree Column *columns = NULL;

  context = g_option_context_new (_(" - Show history"));
  g_option_context_set_translation_domain (context, GETTEXT_PACKAGE);
  col_help = column_help (all_columns);
  g_option_context_set_description (context, col_help);

  if (!flatpak_option_context_parse (context, options, &argc, &argv,
                                     FLATPAK_BUILTIN_FLAG_ALL_DIRS | FLATPAK_BUILTIN_FLAG_OPTIONAL_REPO,
                                     &dirs, cancellable, error))
    return FALSE;

  if (argc > 1)
    return usage_error (context, _("Too many arguments"), error);

  if (opt_since)
    {
      since = parse_time (opt_since);
      if (!since)
        {
          g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
                       _("Failed to parse the --since option"));
          return FALSE;
        }
    }

  if (opt_until)
    {
      until = parse_time (opt_until);
      if (!until)
        {
          g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
                       _("Failed to parse the --until option"));
          return FALSE;
        }
    }
  columns = handle_column_args (all_columns, FALSE, opt_cols, error);
  if (columns == NULL)
    return FALSE;

  if (!print_history (dirs, columns, since, until, opt_reverse, cancellable, error))
    return FALSE;

  return TRUE;
}

gboolean
flatpak_complete_history (FlatpakCompletion *completion)
{
  flatpak_complete_options (completion, global_entries);
  flatpak_complete_options (completion, user_entries);
  flatpak_complete_options (completion, options);
  flatpak_complete_columns (completion, all_columns);
  return TRUE;
}

===== ./app/parse-datetime.h =====
/* Parse a string into an internal time stamp.

   Copyright (C) 1995, 1997-1998, 2003-2004, 2007, 2009-2015 Free Software
   Foundation, Inc.

   This program 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 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/>.  */

#pragma once

#include <stdbool.h>
#include <time.h>

bool parse_datetime (struct timespec *,
                     char const *,
                     struct timespec const *);

===== ./app/flatpak-builtins-info.c =====
/* vi:set et sw=2 sts=2 cin cino=t0,f0,(0,{s,>2s,n-s,^-s,e-s:
 * Copyright © 2016 Red Hat, Inc
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Alexander Larsson <alexl@redhat.com>
 */

#include "config.h"

#include <locale.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

#include <glib/gi18n.h>

#include "libglnx.h"

#include "flatpak-builtins.h"
#include "flatpak-utils-private.h"
#include "flatpak-builtins-utils.h"
#include "flatpak-run-private.h"
#include "flatpak-variant-impl-private.h"

static gboolean opt_user;
static gboolean opt_system;
static gboolean opt_show_ref;
static gboolean opt_show_commit;
static gboolean opt_show_origin;
static gboolean opt_show_size;
static gboolean opt_show_metadata;
static gboolean opt_show_runtime;
static gboolean opt_show_sdk;
static gboolean opt_show_permissions;
static gboolean opt_show_extensions;
static gboolean opt_show_location;
static char *opt_arch;
static char **opt_installations;
static char *opt_file_access;

static GOptionEntry options[] = {
  { "arch", 0, 0, G_OPTION_ARG_STRING, &opt_arch, N_("Arch to use"), N_("ARCH") },
  { "user", 0, 0, G_OPTION_ARG_NONE, &opt_user, N_("Show user installations"), NULL },
  { "system", 0, 0, G_OPTION_ARG_NONE, &opt_system, N_("Show system-wide installations"), NULL },
  { "installation", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_installations, N_("Show specific system-wide installations"), N_("NAME") },
  { "show-ref", 'r', 0, G_OPTION_ARG_NONE, &opt_show_ref, N_("Show ref"), NULL },
  { "show-commit", 'c', 0, G_OPTION_ARG_NONE, &opt_show_commit, N_("Show commit"), NULL },
  { "show-origin", 'o', 0, G_OPTION_ARG_NONE, &opt_show_origin, N_("Show origin"), NULL },
  { "show-size", 's', 0, G_OPTION_ARG_NONE, &opt_show_size, N_("Show size"), NULL },
  { "show-metadata", 'm', 0, G_OPTION_ARG_NONE, &opt_show_metadata, N_("Show metadata"), NULL },
  { "show-runtime", 0, 0, G_OPTION_ARG_NONE, &opt_show_runtime, N_("Show runtime"), NULL },
  { "show-sdk", 0, 0, G_OPTION_ARG_NONE, &opt_show_sdk, N_("Show sdk"), NULL },
  { "show-permissions", 'M', 0, G_OPTION_ARG_NONE, &opt_show_permissions, N_("Show permissions"), NULL },
  { "file-access", 0, 0, G_OPTION_ARG_FILENAME, &opt_file_access, N_("Query file access"), N_("PATH") },
  { "show-extensions", 'e', 0, G_OPTION_ARG_NONE, &opt_show_extensions, N_("Show extensions"), NULL },
  { "show-location", 'l', 0, G_OPTION_ARG_NONE, &opt_show_location, N_("Show location"), NULL },
  { NULL }
};

/* Print space unless this is the first item */
static void
maybe_print_space (gboolean *first)
{
  if (*first)
    *first = FALSE;
  else
    g_print (" ");
}

gboolean
flatpak_builtin_info (int argc, char **argv, GCancellable *cancellable, GError **error)
{
  g_autoptr(GOptionContext) context = NULL;
  g_autoptr(FlatpakDecomposed) ref = NULL;
  g_autoptr(FlatpakDir) dir = NULL;
  g_autoptr(GBytes) deploy_data = NULL;
  g_autoptr(FlatpakDeploy) deploy = NULL;
  g_autoptr(GFile) deploy_dir = NULL;
  g_autoptr(GKeyFile) metakey = NULL;
  const char *commit = NULL;
  const char *alt_id = NULL;
  const char *eol;
  const char *eol_rebase;
  const char *name;
  const char *summary;
  const char *version;
  const char *license;
  const char *pref = NULL;
  const char *default_branch = NULL;
  const char *origin = NULL;
  guint64 size;
  gboolean search_all = FALSE;
  gboolean first = TRUE;
  FlatpakKinds kinds;
  const char *path;
  g_autofree char *formatted_size = NULL;
  gboolean friendly = TRUE;
  g_autofree const char **subpaths = NULL;
  int len = 0;
  int rows, cols;
  int width;

  context = g_option_context_new (_("NAME [BRANCH] - Get info about an installed app or runtime"));
  g_option_context_set_translation_domain (context, GETTEXT_PACKAGE);

  if (!flatpak_option_context_parse (context, options, &argc, &argv, FLATPAK_BUILTIN_FLAG_NO_DIR, NULL, cancellable, error))
    return FALSE;

  if (argc < 2)
    return usage_error (context, _("NAME must be specified"), error);
  pref = argv[1];

  if (argc >= 3)
    default_branch = argv[2];

  if (argc > 3)
    return usage_error (context, _("Too many arguments"), error);

  kinds = FLATPAK_KINDS_APP | FLATPAK_KINDS_RUNTIME;

  if (!opt_user && !opt_system && opt_installations == NULL)
    search_all = TRUE;

  dir = flatpak_find_installed_pref (pref, kinds, opt_arch, default_branch,
                                     search_all, opt_user, opt_system, opt_installations,
                                     &ref, cancellable, error);
  if (dir == NULL)
    return FALSE;

  deploy_data = flatpak_dir_get_deploy_data (dir, ref, FLATPAK_DEPLOY_VERSION_CURRENT, cancellable, error);
  if (deploy_data == NULL)
    return FALSE;

  deploy = flatpak_dir_load_deployed (dir, ref, NULL, cancellable, error);
  if (deploy == NULL)
    return FALSE;

  commit = flatpak_deploy_data_get_commit (deploy_data);
  alt_id = flatpak_deploy_data_get_alt_id (deploy_data);
  origin = flatpak_deploy_data_get_origin (deploy_data);
  size = flatpak_deploy_data_get_installed_size (deploy_data);
  formatted_size = g_format_size (size);
  deploy_dir = flatpak_deploy_get_dir (deploy);
  path = flatpak_file_get_path_cached (deploy_dir);
  subpaths = flatpak_deploy_data_get_subpaths (deploy_data);
  eol = flatpak_deploy_data_get_eol (deploy_data);
  eol_rebase = flatpak_deploy_data_get_eol_rebase (deploy_data);
  name = flatpak_deploy_data_get_appdata_name (deploy_data);
  summary = flatpak_deploy_data_get_appdata_summary (deploy_data);
  version = flatpak_deploy_data_get_appdata_version (deploy_data);
  license = flatpak_deploy_data_get_appdata_license (deploy_data);

  metakey = flatpak_deploy_get_metadata (deploy);

  if (opt_show_ref || opt_show_origin || opt_show_commit || opt_show_size || opt_show_metadata || opt_show_permissions ||
      opt_file_access || opt_show_location || opt_show_runtime || opt_show_sdk)
    friendly = FALSE;

  if (friendly)
    {
      g_autoptr(GVariant) commit_v = NULL;
      VarMetadataRef commit_metadata;
      guint64 timestamp;
      g_autofree char *formatted_timestamp = NULL;
      const gchar *subject = NULL;
      g_autofree char *parent = NULL;
      g_autofree char *latest = NULL;
      const char *xa_metadata = NULL;
      const char *collection_id = NULL;

      flatpak_get_window_size (&rows, &cols);

      if (name)
        {
          if (summary)
            print_wrapped (MIN (cols, 80), "\n%s - %s\n", name, summary);
          else
            print_wrapped (MIN (cols, 80), "\n%s\n", name);
        }

      latest = flatpak_dir_read_latest (dir, origin, flatpak_decomposed_get_ref (ref), NULL, NULL, NULL);
      if (latest == NULL)
        latest = g_strdup (_("ref not present in origin"));

      if (ostree_repo_load_commit (flatpak_dir_get_repo (dir), commit, &commit_v, NULL, NULL))
        {
          VarCommitRef var_commit = var_commit_from_gvariant (commit_v);

          subject = var_commit_get_subject (var_commit);
          parent = ostree_commit_get_parent (commit_v);
          timestamp = ostree_commit_get_timestamp (commit_v);

          formatted_timestamp = format_timestamp (timestamp);

          commit_metadata = var_commit_get_metadata (var_commit);
          xa_metadata = var_metadata_lookup_string (commit_metadata, "xa.metadata", NULL);
          if (xa_metadata == NULL)
            g_printerr (_("Warning: Commit has no flatpak metadata\n"));

          collection_id = var_metadata_lookup_string (commit_metadata, "ostree.collection-binding", NULL);
        }

      len = 0;
      len = MAX (len, g_utf8_strlen (_("ID:"), -1));
      len = MAX (len, g_utf8_strlen (_("Ref:"), -1));
      len = MAX (len, g_utf8_strlen (_("Arch:"), -1));
      len = MAX (len, g_utf8_strlen (_("Branch:"), -1));
      if (version)
        len = MAX (len, g_utf8_strlen (_("Version:"), -1));
      if (license)
        len = MAX (len, g_utf8_strlen (_("License:"), -1));
      if (collection_id != NULL)
        len = MAX (len, g_utf8_strlen (_("Collection:"), -1));
      len = MAX (len, g_utf8_strlen (_("Installation:"), -1));
      len = MAX (len, g_utf8_strlen (_("Installed Size:"), -1));
      if (flatpak_decomposed_is_app (ref))
        {
          len = MAX (len, g_utf8_strlen (_("Runtime:"), -1));
          len = MAX (len, g_utf8_strlen (_("Sdk:"), -1));
        }
      if (formatted_timestamp)
        len = MAX (len, g_utf8_strlen (_("Date:"), -1));
      if (subject)
        len = MAX (len, g_utf8_strlen (_("Subject:"), -1));
      if (strcmp (commit, latest) != 0)
        {
          len = MAX (len, g_utf8_strlen (_("Active commit:"), -1));
          len = MAX (len, g_utf8_strlen (_("Latest commit:"), -1));
        }
      else
        len = MAX (len, g_utf8_strlen (_("Commit:"), -1));
      if (parent)
        len = MAX (len, g_utf8_strlen (_("Parent:"), -1));
      if (alt_id)
        len = MAX (len, g_utf8_strlen (_("Alt-id:"), -1));
      if (eol)
        len = MAX (len, g_utf8_strlen (_("End-of-life:"), -1));
      if (eol_rebase)
        len = MAX (len, g_utf8_strlen (_("End-of-life-rebase:"), -1));
      if (subpaths[0] != NULL)
        len = MAX (len, g_utf8_strlen (_("Subdirectories:"), -1));
      len = MAX (len, g_utf8_strlen (_("Extension:"), -1));

      width = cols - (len + 1);

      print_aligned_take (len, _("ID:"), flatpak_decomposed_dup_id (ref));
      print_aligned (len, _("Ref:"), flatpak_decomposed_get_ref (ref));
      print_aligned_take (len, _("Arch:"), flatpak_decomposed_dup_arch (ref));
      print_aligned_take (len, _("Branch:"), flatpak_decomposed_dup_branch (ref));
      if (version)
        print_aligned (len, _("Version:"), version);
      if (license)
        print_aligned (len, _("License:"), license);
      print_aligned (len, _("Origin:"), origin ? origin : "-");
      if (collection_id)
        print_aligned (len, _("Collection:"), collection_id);
      print_aligned (len, _("Installation:"), flatpak_dir_get_name_cached (dir));
      print_aligned (len, _("Installed Size:"), formatted_size);
      if (flatpak_decomposed_is_app (ref))
        {
          g_autofree char *runtime = NULL;
          runtime = g_key_file_get_string (metakey,
                                           FLATPAK_METADATA_GROUP_APPLICATION,
                                           FLATPAK_METADATA_KEY_RUNTIME,
                                           error);
          print_aligned (len, _("Runtime:"), runtime ? runtime : "-");
        }
      if (flatpak_decomposed_is_app (ref))
        {
          g_autofree char *sdk = NULL;
          sdk = g_key_file_get_string (metakey,
                                       FLATPAK_METADATA_GROUP_APPLICATION,
                                       FLATPAK_METADATA_KEY_SDK,
                                       error);
          print_aligned (len, _("Sdk:"), sdk ? sdk : "-");
        }
      g_print ("\n");

      if (strcmp (commit, latest) != 0)
        {
          g_autofree char *formatted_commit = ellipsize_string (commit, width);
          print_aligned (len, _("Active commit:"), formatted_commit);
          g_free (formatted_commit);
          formatted_commit = ellipsize_string (latest, width);
          print_aligned (len, _("Latest commit:"), formatted_commit);
        }
      else
        {
          g_autofree char *formatted_commit = ellipsize_string (commit, width);
          print_aligned (len, _("Commit:"), formatted_commit);
        }
      if (parent)
        {
          g_autofree char *formatted_commit = ellipsize_string (parent, width);
          print_aligned (len, _("Parent:"), formatted_commit);
        }
      if (subject)
        print_aligned (len, _("Subject:"), subject);
      if (formatted_timestamp)
        print_aligned (len, _("Date:"), formatted_timestamp);
      if (subpaths[0] != NULL)
        {
          g_autofree char *s = g_strjoinv (",", (char **) subpaths);
          print_aligned (len, _("Subdirectories:"), s);
        }

      if (alt_id)
        print_aligned (len, _("Alt-id:"), alt_id);
      if (eol)
        {
          g_autofree char *formatted_eol = ellipsize_string (eol, width);
          print_aligned (len, _("End-of-life:"), formatted_eol);
        }
      if (eol_rebase)
        {
          g_autofree char *formatted_eol = ellipsize_string (eol_rebase, width);
          print_aligned (len, _("End-of-life-rebase:"), formatted_eol);
        }
    }
  else
    {
      if (opt_show_ref)
        {
          maybe_print_space (&first);
          g_print ("%s", flatpak_decomposed_get_ref (ref));
        }

      if (opt_show_origin)
        {
          maybe_print_space (&first);
          g_print ("%s", origin ? origin : "-");
        }

      if (opt_show_commit)
        {
          maybe_print_space (&first);
          g_print ("%s", commit);
        }

      if (opt_show_size)
        {
          maybe_print_space (&first);
          g_print ("%" G_GUINT64_FORMAT, size);
        }

      if (opt_show_location)
        {
          maybe_print_space (&first);
          g_print ("%s", path);
        }

      if (opt_show_runtime)
        {
          g_autofree char *runtime = NULL;
          maybe_print_space (&first);

          runtime = g_key_file_get_string (metakey,
                                           flatpak_decomposed_get_kind_metadata_group (ref),
                                           FLATPAK_METADATA_KEY_RUNTIME,
                                           NULL);
          g_print ("%s", runtime ? runtime : "-");
        }

      if (opt_show_sdk)
        {
          g_autofree char *sdk = NULL;
          maybe_print_space (&first);

          sdk = g_key_file_get_string (metakey,
                                       flatpak_decomposed_get_kind_metadata_group (ref),
                                       FLATPAK_METADATA_KEY_SDK,
                                       NULL);
          g_print ("%s", sdk ? sdk : "-");
        }

      if (!first)
        g_print ("\n");

      if (opt_show_metadata)
        {
          g_autoptr(GFile) file = NULL;
          g_autofree char *data = NULL;
          gsize data_size;

          file = g_file_get_child (deploy_dir, "metadata");

          if (!g_file_load_contents (file, cancellable, &data, &data_size, NULL, error))
            return FALSE;

          flatpak_print_escaped_string (data,
                                        FLATPAK_ESCAPE_ALLOW_NEWLINES
                                        | FLATPAK_ESCAPE_DO_NOT_QUOTE);
        }

      if (opt_show_permissions || opt_file_access)
        {
          g_autoptr(FlatpakContext) app_context = NULL;
          g_autoptr(GKeyFile) keyfile = NULL;
          g_autofree gchar *contents = NULL;

          app_context = flatpak_context_load_for_deploy (deploy, error);
          if (app_context == NULL)
            return FALSE;

          if (opt_show_permissions)
            {
              keyfile = g_key_file_new ();
              flatpak_context_save_metadata (app_context, TRUE, keyfile);
              contents = g_key_file_to_data (keyfile, NULL, error);
              if (contents == NULL)
                return FALSE;

              flatpak_print_escaped_string (contents,
                                            FLATPAK_ESCAPE_ALLOW_NEWLINES
                                            | FLATPAK_ESCAPE_DO_NOT_QUOTE);
            }

          if (opt_file_access)
            {
              g_autofree char *id = flatpak_decomposed_dup_id (ref);
              g_autoptr(FlatpakExports) exports = flatpak_context_get_exports (app_context, id);
              FlatpakFilesystemMode mode;

              mode = flatpak_exports_path_get_mode (exports, opt_file_access);
              if (mode == 0)
                g_print ("hidden\n");
              else if (mode == FLATPAK_FILESYSTEM_MODE_READ_ONLY)
                g_print ("read-only\n");
              else
                g_print ("read-write\n");
            }
        }
    }

  if (opt_show_extensions)
    {
      GList *extensions, *l;
      g_autofree char *ref_arch = flatpak_decomposed_dup_arch (ref);
      g_autofree char *ref_branch = flatpak_decomposed_dup_branch (ref);

      len = MAX (len, g_utf8_strlen (_("Extension:"), -1));
      len = MAX (len, g_utf8_strlen (_("ID:"), -1));
      len = MAX (len, g_utf8_strlen (_("Origin:"), -1));
      len = MAX (len, g_utf8_strlen (_("Commit:"), -1));
      len = MAX (len, g_utf8_strlen (_("Installation:"), -1));
      len = MAX (len, g_utf8_strlen (_("Installed Size:"), -1));
      len = MAX (len, g_utf8_strlen (_("Subpaths:"), -1));

      flatpak_get_window_size (&rows, &cols);
      width = cols - (len + 1);

      extensions = flatpak_list_extensions (metakey, ref_arch, ref_branch);
      for (l = extensions; l; l = l->next)
        {
          FlatpakExtension *ext = l->data;
          g_autofree const char **ext_subpaths = NULL;
          g_autoptr(GBytes) ext_deploy_data = NULL;
          g_autofree char *formatted = NULL;
          g_autofree char *ext_formatted_size = NULL;
          g_autofree char *formatted_commit = NULL;
          g_autofree char *ext_installation = NULL;

          if (ext->is_unmaintained)
            {
              formatted_commit = g_strdup (_("unmaintained"));
              origin = NULL;
              ext_installation = g_strdup (_("unknown"));
              size = 0;
              ext_formatted_size = g_strdup (_("unknown"));
              ext_subpaths = NULL;
            }
          else
            {
              g_autoptr(GFile) ext_deploy_dir = NULL;
              g_autoptr(FlatpakDir) ext_dir = NULL;

              ext_deploy_dir = flatpak_find_deploy_dir_for_ref (ext->ref, &ext_dir, cancellable, error);
              if (ext_deploy_dir == NULL)
                return FALSE;

              ext_deploy_data = flatpak_dir_get_deploy_data (ext_dir, ext->ref, FLATPAK_DEPLOY_VERSION_CURRENT, cancellable, error);
              if (ext_deploy_data == NULL)
                return FALSE;

              commit = flatpak_deploy_data_get_commit (ext_deploy_data);
              formatted_commit = ellipsize_string (commit, width);
              origin = flatpak_deploy_data_get_origin (ext_deploy_data);
              ext_installation = flatpak_dir_get_name (ext_dir);
              size = flatpak_deploy_data_get_installed_size (ext_deploy_data);
              formatted = g_format_size (size);
              ext_subpaths = flatpak_deploy_data_get_subpaths (ext_deploy_data);
              if (ext_subpaths && ext_subpaths[0] && size > 0)
                ext_formatted_size = g_strconcat ("<", formatted, NULL);
              else
                ext_formatted_size = g_steal_pointer (&formatted);
            }

          g_print ("\n");
          print_aligned (len, _("Extension:"), flatpak_decomposed_get_ref (ext->ref));
          print_aligned (len, _("ID:"), ext->id);
          print_aligned (len, _("Origin:"), origin ? origin : "-");
          print_aligned (len, _("Commit:"), formatted_commit);
          print_aligned (len, _("Installation:"), ext_installation);
          print_aligned (len, _("Installed Size:"), ext_formatted_size);

          if (ext_subpaths && ext_subpaths[0])
            {
              g_autofree char *s = g_strjoinv (",", (char **) ext_subpaths);
              print_aligned (len, _("Subpaths:"), s);
            }
        }

      g_list_free_full (extensions, (GDestroyNotify) flatpak_extension_free);
    }

  return TRUE;
}

gboolean
flatpak_complete_info (FlatpakCompletion *completion)
{
  g_autoptr(GOptionContext) context = NULL;
  g_autoptr(GPtrArray) dirs = NULL;
  g_autoptr(GError) error = NULL;
  FlatpakKinds kinds;
  int i;

  context = g_option_context_new ("");
  if (!flatpak_option_context_parse (context, options, &completion->argc, &completion->argv,
                                     FLATPAK_BUILTIN_FLAG_ALL_DIRS | FLATPAK_BUILTIN_FLAG_OPTIONAL_REPO, &dirs, NULL, NULL))
    return FALSE;

  kinds = FLATPAK_KINDS_APP | FLATPAK_KINDS_RUNTIME;

  switch (completion->argc)
    {
    case 0:
    case 1: /* NAME */
      flatpak_complete_options (completion, global_entries);
      flatpak_complete_options (completion, options);

      for (i = 0; i < dirs->len; i++)
        {
          FlatpakDir *dir = g_ptr_array_index (dirs, i);
          g_autoptr(GPtrArray) refs = flatpak_dir_find_installed_refs (dir, NULL, NULL, opt_arch,
                                                                       kinds, FIND_MATCHING_REFS_FLAGS_NONE, &error);
          if (refs == NULL)
            flatpak_completion_debug ("find local refs error: %s", error->message);

          flatpak_complete_ref_id (completion, refs);
        }
      break;

    case 2: /* BRANCH */
      for (i = 0; i < dirs->len; i++)
        {
          FlatpakDir *dir = g_ptr_array_index (dirs, i);
          g_autoptr(GPtrArray) refs = flatpak_dir_find_installed_refs (dir, completion->argv[1], NULL, opt_arch,
                                                                       kinds, FIND_MATCHING_REFS_FLAGS_NONE, &error);
          if (refs == NULL)
            flatpak_completion_debug ("find remote refs error: %s", error->message);

          flatpak_complete_ref_branch (completion, refs);
        }

      break;

    default:
      break;
    }

  return TRUE;
}

===== ./app/flatpak-builtins-utils.h =====
/*
 * Copyright © 2014 Red Hat, Inc
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Alexander Larsson <alexl@redhat.com>
 */

#ifndef __FLATPAK_BUILTINS_UTILS_H__
#define __FLATPAK_BUILTINS_UTILS_H__

#include <glib.h>
#include <appstream.h>
#include "libglnx.h"
#include "flatpak-utils-private.h"
#include "flatpak-dir-private.h"
#include "flatpak-permission-dbus-generated.h"
#include "flatpak-transaction.h"

/* AS_CHECK_VERSION was introduced in 0.14.0; we still support 0.12.0, so
 * behave as though versions without this macro are arbitrarily old */
#ifndef AS_CHECK_VERSION
#define AS_CHECK_VERSION(major, minor, micro) (0)
#endif

/* Appstream data expires after a day */
#define FLATPAK_APPSTREAM_TTL 86400

typedef struct RemoteDirPair
{
  gchar      *remote_name;
  FlatpakDir *dir;
} RemoteDirPair;

typedef struct RefDirPair
{
  FlatpakDecomposed *ref;
  FlatpakDir *dir;
} RefDirPair;

void         ref_dir_pair_free (RefDirPair *pair);
RefDirPair * ref_dir_pair_new (FlatpakDecomposed *ref,
                               FlatpakDir *dir);

void            remote_dir_pair_free (RemoteDirPair *pair);
RemoteDirPair * remote_dir_pair_new (const char *remote_name,
                                     FlatpakDir *dir);

gboolean    looks_like_branch (const char *branch);

GBytes * flatpak_load_gpg_keys (char        **gpg_import,
                                GCancellable *cancellable,
                                GError      **error);

FlatpakDir * flatpak_find_installed_pref (const char         *pref,
                                          FlatpakKinds        kinds,
                                          const char         *default_arch,
                                          const char         *default_branch,
                                          gboolean            search_all,
                                          gboolean            search_user,
                                          gboolean            search_system,
                                          char              **search_installations,
                                          FlatpakDecomposed **out_ref,
                                          GCancellable       *cancellable,
                                          GError            **error);

gboolean flatpak_resolve_duplicate_remotes (GPtrArray    *dirs,
                                            const char   *remote_name,
                                            gboolean      opt_noninteractive,
                                            FlatpakDir  **out_dir,
                                            GCancellable *cancellable,
                                            GError      **error);

gboolean flatpak_resolve_matching_refs (const char *remote_name,
                                        FlatpakDir *dir,
                                        gboolean    assume_yes,
                                        GPtrArray  *refs,
                                        const char *opt_search_ref,
                                        gboolean    opt_noninteractive,
                                        char      **out_ref,
                                        GError    **error);

gboolean flatpak_resolve_matching_installed_refs (gboolean    assume_yes,
                                                  gboolean    only_one,
                                                  GPtrArray  *ref_dir_pairs,
                                                  const char *opt_search_ref,
                                                  gboolean    opt_noninteractive,
                                                  GPtrArray  *out_pairs,
                                                  GError    **error);

gboolean flatpak_resolve_matching_remotes (GPtrArray      *remote_dir_pairs,
                                           const char     *opt_search_ref,
                                           gboolean        opt_noninteractive,
                                           RemoteDirPair **out_pair,
                                           GError        **error);

gboolean update_appstream (GPtrArray    *dirs,
                           const char   *remote,
                           const char   *arch,
                           guint64       ttl,
                           gboolean      quiet,
                           GCancellable *cancellable,
                           GError      **error);

char ** get_permission_tables (XdpDbusPermissionStore *store);
gboolean reset_permissions_for_app (const char *app_id,
                                    GError    **error);


/* --columns handling */

typedef enum {
  FLATPAK_ELLIPSIZE_MODE_NONE,
  FLATPAK_ELLIPSIZE_MODE_START,
  FLATPAK_ELLIPSIZE_MODE_MIDDLE,
  FLATPAK_ELLIPSIZE_MODE_END,
} FlatpakEllipsizeMode;

typedef struct
{
  const char          *name;
  const char          *title; /* use N_() */
  const char          *desc; /* use N_() */
  gboolean             expand;
  FlatpakEllipsizeMode ellipsize;
  gboolean             all;
  gboolean             def;
  gboolean             skip_unique_if_default;
} Column;

int find_column (Column     *columns,
                 const char *name,
                 GError    **error);
char   *column_help (Column *columns);
Column *handle_column_args (Column      *all_columns,
                            gboolean     opt_show_all,
                            const char **opt_cols,
                            GError     **error);

char *  format_timestamp (guint64 timestamp);


char *  ellipsize_string (const char *text,
                          int         len);
char *  ellipsize_string_full (const char          *text,
                               int                  len,
                               FlatpakEllipsizeMode mode);

void print_aligned (int         len,
                    const char *title,
                    const char *value);
void print_aligned_take (int         len,
                         const char *title,
                         char       *value);

AsComponent *metadata_find_component (AsMetadata *mdata,
                                         const char *ref);
const char *component_get_version_latest (AsComponent *component);

gboolean    flatpak_dir_load_appstream_data (FlatpakDir   *self,
                                             const gchar  *remote_name,
                                             const gchar  *arch,
                                             AsMetadata   *mdata,
                                             GCancellable *cancellable,
                                             GError      **error);

int         cell_width (const char *text);
const char *cell_advance (const char *text,
                          int         num);

void print_wrapped (int         columns,
                    const char *text,
                    ...) G_GNUC_PRINTF (2, 3);

FlatpakRemoteState * get_remote_state (FlatpakDir   *dir,
                                       const char   *remote,
                                       gboolean      cached,
                                       gboolean      only_sideloaded,
                                       const char   *opt_arch,
                                       const char  **opt_sideload_repos,
                                       GCancellable *cancellable,
                                       GError      **error);

gboolean ensure_remote_state_arch (FlatpakDir         *dir,
                                   FlatpakRemoteState *state,
                                   const char         *arch,
                                   gboolean            cached,
                                   gboolean            only_sideloaded,
                                   GCancellable       *cancellable,
                                   GError            **error);
gboolean ensure_remote_state_all_arches (FlatpakDir         *dir,
                                         FlatpakRemoteState *state,
                                         gboolean            cached,
                                         gboolean            only_sideloaded,
                                         GCancellable       *cancellable,
                                         GError            **error);

gboolean setup_sideload_repositories (FlatpakTransaction *transaction,
                                      char              **opt_sideload_repos,
                                      GCancellable       *cancellable,
                                      GError            **error);

#endif /* __FLATPAK_BUILTINS_UTILS_H__ */

===== ./app/flatpak-builtins-repo.c =====
/* vi:set et sw=2 sts=2 cin cino=t0,f0,(0,{s,>2s,n-s,^-s,e-s:
 * Copyright © 2017 Red Hat, Inc
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Matthias Clasen <mclasen@redhat.com>
 */

#include "config.h"

#include <locale.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

#include <glib/gi18n.h>

#include "libglnx.h"

#include "flatpak-builtins.h"
#include "flatpak-repo-utils-private.h"
#include "flatpak-utils-private.h"
#include "flatpak-table-printer.h"
#include "flatpak-variant-impl-private.h"

static gboolean opt_info;
static gboolean opt_branches;
static gboolean opt_subsets;
static gchar *opt_metadata_branch;
static gchar *opt_commits_branch;
static gchar *opt_subset;
static gboolean opt_json;

static gboolean
ostree_repo_mode_to_string (OstreeRepoMode mode,
                            const char   **out_mode,
                            GError       **error)
{
  const char *ret_mode;

  switch (mode)
    {
    case OSTREE_REPO_MODE_BARE:
      ret_mode = "bare";
      break;

    case OSTREE_REPO_MODE_BARE_USER:
      ret_mode = "bare-user";
      break;

    case OSTREE_REPO_MODE_BARE_USER_ONLY:
      ret_mode = "bare-user-only";
      break;

    case OSTREE_REPO_MODE_ARCHIVE:
      /* Legacy alias */
      ret_mode = "archive-z2";
      break;

    default:
      return glnx_throw (error, "Invalid mode '%d'", mode);
    }

  *out_mode = ret_mode;
  return TRUE;
}

static void
print_info (OstreeRepo *repo,
            GVariant   *index,
            GVariant   *summary)
{
  const char *title;
  const char *comment;
  const char *description;
  const char *homepage;
  const char *icon;
  const char *collection_id;
  const char *default_branch;
  const char *redirect_url;
  const char *deploy_collection_id;
  const char *authenticator_name;
  gboolean authenticator_install = FALSE;
  g_autoptr(GVariant) gpg_keys = NULL;
  OstreeRepoMode mode;
  const char *mode_string = "unknown";
  g_autoptr(GVariant) meta = NULL;
  g_autoptr(GVariant) refs = NULL;
  guint cache_version = 0;
  gboolean indexed_deltas = FALSE;

  mode = ostree_repo_get_mode (repo);
  ostree_repo_mode_to_string (mode, &mode_string, NULL);
  g_print (_("Repo mode: %s\n"), mode_string);

  if (index)
    meta = g_variant_get_child_value (index, 1);
  else
    meta = g_variant_get_child_value (summary, 1);

  g_print (_("Indexed summaries: %s\n"), index != NULL ? _("true") : _("false"));

  if (index)
    {
      VarSummaryIndexRef index_ref = var_summary_index_from_gvariant (index);
      VarSummaryIndexSubsummariesRef subsummaries = var_summary_index_get_subsummaries (index_ref);
      gsize n_subsummaries = var_summary_index_subsummaries_get_length (subsummaries);

      g_print (_("Subsummaries: "));
      for (gsize i = 0; i < n_subsummaries; i++)
        {
          VarSummaryIndexSubsummariesEntryRef entry = var_summary_index_subsummaries_get_at (subsummaries, i);
          const char *name = var_summary_index_subsummaries_entry_get_key (entry);

          if (i != 0)
            g_print (", ");
          g_print ("%s", name);
        }

      g_print ("\n");
    }

  g_variant_lookup (meta, "xa.cache-version", "u", &cache_version);
  g_print (_("Cache version: %d\n"), cache_version);

  g_variant_lookup (meta, "ostree.summary.indexed-deltas", "b", &indexed_deltas);
  g_print (_("Indexed deltas: %s\n"), indexed_deltas ? _("true") : _("false"));

  if (g_variant_lookup (meta, "xa.title", "&s", &title))
    g_print (_("Title: %s\n"), title);

  if (g_variant_lookup (meta, "xa.comment", "&s", &comment))
    g_print (_("Comment: %s\n"), comment);

  if (g_variant_lookup (meta, "xa.description", "&s", &description))
    g_print (_("Description: %s\n"), description);

  if (g_variant_lookup (meta, "xa.homepage", "&s", &homepage))
    g_print (_("Homepage: %s\n"), homepage);

  if (g_variant_lookup (meta, "xa.icon", "&s", &icon))
    g_print (_("Icon: %s\n"), icon);

  if (g_variant_lookup (meta, "collection-id", "&s", &collection_id))
    g_print (_("Collection ID: %s\n"), collection_id);

  if (g_variant_lookup (meta, "xa.default-branch", "&s", &default_branch))
    g_print (_("Default branch: %s\n"), default_branch);

  if (g_variant_lookup (meta, "xa.redirect-url", "&s", &redirect_url))
    g_print (_("Redirect URL: %s\n"), redirect_url);

  if (g_variant_lookup (meta, OSTREE_META_KEY_DEPLOY_COLLECTION_ID, "&s", &deploy_collection_id))
    g_print (_("Deploy collection ID: %s\n"), deploy_collection_id);

  if (g_variant_lookup (meta, "xa.authenticator-name", "&s", &authenticator_name))
    g_print (_("Authenticator name: %s\n"), authenticator_name);

  if (g_variant_lookup (meta, "xa.authenticator-install", "&s", &authenticator_install))
    g_print (_("Authenticator install: %s\n"), authenticator_install ? _("true") : _("false"));

  if ((gpg_keys = g_variant_lookup_value (meta, "xa.gpg-keys", G_VARIANT_TYPE_BYTESTRING)) != NULL)
    {
      const guchar *gpg_data = g_variant_get_data (gpg_keys);
      gsize gpg_size = g_variant_get_size (gpg_keys);
      g_autofree gchar *gpg_data_checksum = g_compute_checksum_for_data (G_CHECKSUM_SHA256, gpg_data, gpg_size);

      g_print (_("GPG key hash: %s\n"), gpg_data_checksum);
    }

  refs = g_variant_get_child_value (summary, 0);
  g_print (_("%zd summary branches\n"), g_variant_n_children (refs));
}

static void
print_branches_for_subsummary (FlatpakTablePrinter *printer,
                               const char *subsummary,
                               GVariant   *summary)
{
  g_autoptr(GVariant) meta = NULL;
  guint summary_version = 0;
  g_autofree char *subset = NULL;

  if (subsummary != NULL)
    {
      const char *dash = strrchr (subsummary, '-');
      if (dash)
        subset = g_strndup (subsummary, dash - subsummary);
    }

  if (opt_subset != NULL)
    {
      if (subset == NULL ||
          strcmp (subset, opt_subset) != 0)
        return; /* Not the requested subset, ignore */
    }

  meta = g_variant_get_child_value (summary, 1);

  g_variant_lookup (meta, "xa.summary-version", "u", &summary_version);

  if (summary_version == 1)
    {
      g_autoptr(GVariant) refs = g_variant_get_child_value (summary, 0);
      GVariantIter iter;
      const char *ref;
      GVariant *refdata_iter = NULL;

      g_variant_iter_init (&iter, refs);
      while (g_variant_iter_next (&iter, "(&s@(taya{sv}))", &ref, &refdata_iter))
        {
          g_autoptr(GVariant) refdata = refdata_iter;
          g_autoptr(GVariant) ref_meta = g_variant_get_child_value (refdata, 2);
          g_autoptr(GVariant) data = g_variant_lookup_value (ref_meta, "xa.data", NULL);
          guint64 installed_size;
          guint64 download_size;
          const char *metadata;
          const char *eol;

          if (data == NULL)
            continue;

          int old_row = flatpak_table_printer_lookup_row (printer, ref);
          if (old_row >= 0)
            {
              if (subset)
                flatpak_table_printer_append_cell_with_comma_unique (printer, old_row, 3, subset);
              continue;
            }

          g_variant_get (data, "(tt&s)", &installed_size, &download_size, &metadata);

          g_autofree char *installed = g_format_size (GUINT64_FROM_BE (installed_size));
          g_autofree char *download = g_format_size (GUINT64_FROM_BE (download_size));

          flatpak_table_printer_set_key (printer, ref);
          flatpak_table_printer_add_column (printer, ref);
          flatpak_table_printer_add_decimal_column (printer, installed);
          flatpak_table_printer_add_decimal_column (printer, download);

          /* Subset */
          flatpak_table_printer_add_column (printer, subset);

          flatpak_table_printer_add_column (printer, ""); /* Options */

          if (g_variant_lookup (ref_meta, FLATPAK_SPARSE_CACHE_KEY_ENDOFLIFE, "&s", &eol))
            flatpak_table_printer_append_with_comma_printf (printer, "eol=%s", eol);
          if (g_variant_lookup (ref_meta, FLATPAK_SPARSE_CACHE_KEY_ENDOFLIFE_REBASE, "&s", &eol))
            flatpak_table_printer_append_with_comma_printf (printer, "eol-rebase=%s", eol);


          flatpak_table_printer_finish_row (printer);
        }
    }
  else
    {
      g_autoptr(GVariant) cache = NULL;
      g_autoptr(GVariant) sparse_cache = NULL;

      g_variant_lookup (meta, "xa.sparse-cache", "@a{sa{sv}}", &sparse_cache);
      cache = g_variant_lookup_value (meta, "xa.cache", NULL);
      if (cache)
        {
          g_autoptr(GVariant) refdata = NULL;
          GVariantIter iter;
          const char *ref;
          guint64 installed_size;
          guint64 download_size;
          const char *metadata;

          refdata = g_variant_get_variant (cache);
          g_variant_iter_init (&iter, refdata);
          while (g_variant_iter_next (&iter, "{&s(tt&s)}", &ref, &installed_size, &download_size, &metadata))
            {
              g_autofree char *installed = g_format_size (GUINT64_FROM_BE (installed_size));
              g_autofree char *download = g_format_size (GUINT64_FROM_BE (download_size));

              int old_row = flatpak_table_printer_lookup_row (printer, ref);
              if (old_row >= 0)
                {
                  if (subset)
                    flatpak_table_printer_append_cell_with_comma_unique (printer, old_row, 3, subset);
                  continue;
                }

              flatpak_table_printer_set_key (printer, ref);
              flatpak_table_printer_add_column (printer, ref);
              flatpak_table_printer_add_decimal_column (printer, installed);
              flatpak_table_printer_add_decimal_column (printer, download);

              flatpak_table_printer_add_column (printer, subset);

              flatpak_table_printer_add_column (printer, ""); /* Options */

              if (sparse_cache)
                {
                  g_autoptr(GVariant) sparse = NULL;
                  if (g_variant_lookup (sparse_cache, ref, "@a{sv}", &sparse))
                    {
                      const char *eol;
                      if (g_variant_lookup (sparse, FLATPAK_SPARSE_CACHE_KEY_ENDOFLIFE, "&s", &eol))
                        flatpak_table_printer_append_with_comma_printf (printer, "eol=%s", eol);
                      if (g_variant_lookup (sparse, FLATPAK_SPARSE_CACHE_KEY_ENDOFLIFE_REBASE, "&s", &eol))
                        flatpak_table_printer_append_with_comma_printf (printer, "eol-rebase=%s", eol);
                    }
                }

              flatpak_table_printer_finish_row (printer);
            }

        }
    }
}

static void
print_branches (OstreeRepo *repo,
                GVariant   *index,
                GVariant   *summary)
{
  g_autoptr(FlatpakTablePrinter) printer = NULL;

  printer = flatpak_table_printer_new ();
  flatpak_table_printer_set_column_title (printer, 0, _("Ref"));
  flatpak_table_printer_set_column_title (printer, 1, _("Installed"));
  /* Translators: Download is used here as a noun */
  flatpak_table_printer_set_column_title (printer, 2, _("Download"));
  flatpak_table_printer_set_column_title (printer, 3, _("Subsets"));
  flatpak_table_printer_set_column_title (printer, 4, _("Options"));

  if (index != NULL)
    {
      VarSummaryIndexRef index_ref = var_summary_index_from_gvariant (index);
      VarSummaryIndexSubsummariesRef subsummaries = var_summary_index_get_subsummaries (index_ref);
      gsize n_subsummaries = var_summary_index_subsummaries_get_length (subsummaries);

      for (gsize i = 0; i < n_subsummaries; i++)
        {
          VarSummaryIndexSubsummariesEntryRef entry = var_summary_index_subsummaries_get_at (subsummaries, i);
          const char *name = var_summary_index_subsummaries_entry_get_key (entry);
          VarSubsummaryRef subsummary = var_summary_index_subsummaries_entry_get_value (entry);
          gsize checksum_bytes_len;
          const guchar *checksum_bytes;
          g_autofree char *digest = NULL;
          g_autoptr(GVariant) subsummary_v = NULL;
          g_autoptr(GError) error = NULL;

          checksum_bytes = var_subsummary_peek_checksum (subsummary, &checksum_bytes_len);
          if (G_UNLIKELY (checksum_bytes_len != OSTREE_SHA256_DIGEST_LEN))
            {
              g_printerr ("Invalid checksum for digested summary\n");
              continue;
            }
          digest = ostree_checksum_from_bytes (checksum_bytes);

          subsummary_v = flatpak_repo_load_digested_summary (repo, digest, &error);
          if (subsummary_v == NULL)
            {
              g_printerr ("Failed to load subsummary %s (digest %s)\n", name, digest);
              continue;
            }

          print_branches_for_subsummary (printer, name, subsummary_v);
        }
    }
  else
    print_branches_for_subsummary (printer, NULL, summary);

  flatpak_table_printer_sort (printer, (GCompareFunc) strcmp);

  opt_json ? flatpak_table_printer_print_json (printer) : flatpak_table_printer_print (printer);
}

static void
print_subsets (OstreeRepo *repo,
               GVariant   *index)
{
  g_autoptr(FlatpakTablePrinter) printer = NULL;

  printer = flatpak_table_printer_new ();
  flatpak_table_printer_set_column_title (printer, 0, _("Subset"));
  flatpak_table_printer_set_column_title (printer, 1, _("Digest"));
  flatpak_table_printer_set_column_title (printer, 2, _("History length"));

  if (index != NULL)
    {
      VarSummaryIndexRef index_ref = var_summary_index_from_gvariant (index);
      VarSummaryIndexSubsummariesRef subsummaries = var_summary_index_get_subsummaries (index_ref);
      gsize n_subsummaries = var_summary_index_subsummaries_get_length (subsummaries);

      for (gsize i = 0; i < n_subsummaries; i++)
        {
          VarSummaryIndexSubsummariesEntryRef entry = var_summary_index_subsummaries_get_at (subsummaries, i);
          const char *name = var_summary_index_subsummaries_entry_get_key (entry);
          VarSubsummaryRef subsummary = var_summary_index_subsummaries_entry_get_value (entry);
          gsize checksum_bytes_len;
          const guchar *checksum_bytes;
          g_autofree char *digest = NULL;
          VarArrayofChecksumRef history = var_subsummary_get_history (subsummary);
          gsize history_len = var_arrayof_checksum_get_length (history);

          if (opt_subset != NULL && !g_str_has_prefix (name, opt_subset))
            continue;

          checksum_bytes = var_subsummary_peek_checksum (subsummary, &checksum_bytes_len);
          if (G_UNLIKELY (checksum_bytes_len != OSTREE_SHA256_DIGEST_LEN))
            {
              g_printerr ("Invalid checksum for digested summary\n");
              continue;
            }
          digest = ostree_checksum_from_bytes (checksum_bytes);

          flatpak_table_printer_add_column (printer, name);
          flatpak_table_printer_add_column (printer, digest);
          flatpak_table_printer_take_column (printer, g_strdup_printf ("%"G_GSIZE_FORMAT, history_len));
          flatpak_table_printer_finish_row (printer);
        }
    }

  opt_json ? flatpak_table_printer_print_json (printer) : flatpak_table_printer_print (printer);
}


static void
print_metadata (OstreeRepo *repo,
                GVariant   *index,
                GVariant   *summary,
                const char *branch)
{
  g_autoptr(GVariant) meta = NULL;
  guint summary_version = 0;
  guint64 installed_size;
  guint64 download_size;
  const char *metadata;
  GVariantIter iter;
  const char *ref;
  g_autoptr(GVariant) subsummary_v = NULL;

  if (index)
    {
      g_autofree char *arch = flatpak_get_arch_for_ref (branch);

      if (arch != NULL)
        {
          VarSummaryIndexRef index_ref = var_summary_index_from_gvariant (index);
          VarSummaryIndexSubsummariesRef subsummaries = var_summary_index_get_subsummaries (index_ref);
          gsize n_subsummaries = var_summary_index_subsummaries_get_length (subsummaries);

          for (gsize i = 0; i < n_subsummaries; i++)
            {
              VarSummaryIndexSubsummariesEntryRef entry = var_summary_index_subsummaries_get_at (subsummaries, i);
              const char *name = var_summary_index_subsummaries_entry_get_key (entry);
              VarSubsummaryRef subsummary = var_summary_index_subsummaries_entry_get_value (entry);
              gsize checksum_bytes_len;
              const guchar *checksum_bytes;

              if (strcmp (name, arch) == 0)
                {
                  g_autofree char *digest = NULL;
                  g_autoptr(GError) error = NULL;

                  checksum_bytes = var_subsummary_peek_checksum (subsummary, &checksum_bytes_len);
                  if (G_UNLIKELY (checksum_bytes_len != OSTREE_SHA256_DIGEST_LEN))
                    break;

                  digest = ostree_checksum_from_bytes (checksum_bytes);

                  subsummary_v = flatpak_repo_load_digested_summary (repo, digest, &error);
                  if (subsummary_v == NULL)
                    g_printerr ("Failed to load subsummary %s (digest %s)\n", name, digest);
                  break;
                }
            }
        }
    }

  if (subsummary_v)
    summary = subsummary_v;

  meta = g_variant_get_child_value (summary, 1);

  g_variant_lookup (meta, "xa.summary-version", "u", &summary_version);

  if (summary_version == 1)
    {
      g_autoptr(GVariant) refs = g_variant_get_child_value (summary, 0);
      GVariant *refdata_iter = NULL;

      g_variant_iter_init (&iter, refs);
      while (g_variant_iter_next (&iter, "(&s@(taya{sv}))", &ref, &refdata_iter))
        {
          g_autoptr(GVariant) refdata = refdata_iter;
          g_autoptr(GVariant) ref_meta = g_variant_get_child_value (refdata, 2);

          if (strcmp (branch, ref) == 0)
            {
              g_autoptr(GVariant) data = g_variant_lookup_value (ref_meta, "xa.data", NULL);
              if (data)
                {
                  g_variant_get (data, "(tt&s)", &installed_size, &download_size, &metadata);
                  g_print ("%s\n", metadata);
                  break;
                }
            }
        }
    }
  else /* Version 0 */
    {
      g_autoptr(GVariant) cache = g_variant_lookup_value (meta, "xa.cache", NULL);
      if (cache)
        {
          g_autoptr(GVariant) refdata = g_variant_get_variant (cache);
          g_variant_iter_init (&iter, refdata);
          while (g_variant_iter_next (&iter, "{&s(tt&s)}", &ref, &installed_size, &download_size, &metadata))
            {
              if (strcmp (branch, ref) == 0)
                {
                  g_print ("%s\n", metadata);
                  break;
                }
            }
        }
    }
}

static void
dump_indented_lines (const gchar *data)
{
  const char * indent = "    ";
  const gchar *pos;

  for (;;)
    {
      pos = strchr (data, '\n');
      if (pos)
        {
          g_print ("%s%.*s", indent, (int) (pos + 1 - data), data);
          data = pos + 1;
        }
      else
        {
          if (data[0] != '\0')
            g_print ("%s%s\n", indent, data);
          break;
        }
    }
}

static void
dump_deltas_for_commit (GPtrArray  *deltas,
                        const char *checksum)
{
  int i;
  gboolean header_printed = FALSE;

  if (!deltas)
    return;

  for (i = 0; i < deltas->len; i++)
    {
      const char *delta = g_ptr_array_index (deltas, i);

      if (g_str_equal (delta, checksum))
        {
          if (!header_printed)
            {
              g_print ("Static Deltas:\n");
              header_printed = TRUE;
            }
          g_print ("  from scratch\n");
        }
      else if (strchr (delta, '-'))
        {
          g_auto(GStrv) parts = g_strsplit (delta, "-", 0);

          if (g_str_equal (parts[1], checksum))
            {
              if (!header_printed)
                {
                  g_print ("Static Deltas:\n");
                  header_printed = TRUE;
                }
              g_print ("  from %s\n", parts[0]);
            }
        }
    }

  if (header_printed)
    g_print ("\n");
}

static gboolean
dump_commit (const char *commit,
             GVariant   *variant,
             GPtrArray  *deltas,
             GError    **error)
{
  const gchar *subject;
  const gchar *body;
  guint64 timestamp;
  g_autofree char *str = NULL;

  /* See OSTREE_COMMIT_GVARIANT_FORMAT */
  g_variant_get (variant, "(a{sv}aya(say)&s&stayay)", NULL, NULL, NULL,
                 &subject, &body, &timestamp, NULL, NULL);

  timestamp = GUINT64_FROM_BE (timestamp);
  str = format_timestamp (timestamp);
  g_print ("Commit:  %s\n", commit);
  g_print ("Date:  %s\n", str);

  if (subject[0])
    {
      g_print ("\n");
      dump_indented_lines (subject);
    }
  else
    {
      g_print ("(no subject)\n");
    }

  if (body[0])
    {
      g_print ("\n");
      dump_indented_lines (body);
    }
  g_print ("\n");

  dump_deltas_for_commit (deltas, commit);

  return TRUE;
}

static gboolean
log_commit (OstreeRepo *repo,
            const char *checksum,
            gboolean    is_recurse,
            GPtrArray  *deltas,
            GError    **error)
{
  g_autoptr(GVariant) variant = NULL;
  g_autofree char *parent = NULL;
  gboolean ret = FALSE;
  GError *local_error = NULL;

  if (!ostree_repo_load_variant (repo, OSTREE_OBJECT_TYPE_COMMIT, checksum,
                                 &variant, &local_error))
    {
      if (is_recurse && g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
        {
          g_print ("<< History beyond this commit not fetched >>\n");
          g_clear_error (&local_error);
          ret = TRUE;
        }
      else
        {
          g_propagate_error (error, local_error);
        }
      goto out;
    }

  if (!dump_commit (checksum, variant, deltas, error))
    goto out;

  /* Get the parent of this commit */
  parent = ostree_commit_get_parent (variant);
  if (parent && !log_commit (repo, parent, TRUE, deltas, error))
    goto out;

  ret = TRUE;
out:
  return ret;
}

static gboolean
print_commits (OstreeRepo   *repo,
               const char   *collection_id,
               const char   *ref,
               GCancellable *cancellable,
               GError      **error)
{
  g_autofree char *checksum = NULL;
  g_autoptr(GPtrArray) deltas = NULL;

  if (!ostree_repo_list_static_delta_names (repo, &deltas, NULL, error))
    return FALSE;

  if (!flatpak_repo_resolve_rev (repo, collection_id, NULL, ref, FALSE, &checksum,
                                 cancellable, error))
    return FALSE;

  if (!log_commit (repo, checksum, FALSE, deltas, error))
    return FALSE;

  return TRUE;
}


static GOptionEntry options[] = {
  { "info", 0, 0, G_OPTION_ARG_NONE, &opt_info, N_("Print general information about the repository"), NULL },
  { "branches", 0, 0, G_OPTION_ARG_NONE, &opt_branches, N_("List the branches in the repository"), NULL },
  { "metadata", 0, 0, G_OPTION_ARG_STRING, &opt_metadata_branch, N_("Print metadata for a branch"), N_("BRANCH") },
  { "commits", 0, 0, G_OPTION_ARG_STRING, &opt_commits_branch, N_("Show commits for a branch"), N_("BRANCH") },
  { "subsets", 0, 0, G_OPTION_ARG_NONE, &opt_subsets, N_("Print information about the repo subsets"), NULL },
  { "subset", 0, 0, G_OPTION_ARG_STRING, &opt_subset, N_("Limit information to subsets with this prefix"), NULL },
  { "json", 'j', 0, G_OPTION_ARG_NONE, &opt_json, N_("Show output in JSON format"), NULL },
  { NULL }
};

gboolean
flatpak_builtin_repo (int argc, char **argv,
                      GCancellable *cancellable, GError **error)
{
  g_autoptr(GOptionContext) context = NULL;
  g_autoptr(GFile) location = NULL;
  g_autoptr(OstreeRepo) repo = NULL;
  g_autoptr(GVariant) index = NULL;
  g_autoptr(GVariant) summary = NULL;
  const char *collection_id;

  context = g_option_context_new (_("LOCATION - Repository maintenance"));
  g_option_context_set_translation_domain (context, GETTEXT_PACKAGE);

  if (!flatpak_option_context_parse (context, options, &argc, &argv, FLATPAK_BUILTIN_FLAG_NO_DIR, NULL, cancellable, error))
    return FALSE;

  if (argc < 2)
    return usage_error (context, _("LOCATION must be specified"), error);

  location = g_file_new_for_commandline_arg (argv[1]);
  repo = ostree_repo_new (location);
  if (!ostree_repo_open (repo, cancellable, error))
    return FALSE;

  collection_id = ostree_repo_get_collection_id (repo);

  index = flatpak_repo_load_summary_index (repo, NULL);
  summary = flatpak_repo_load_summary (repo, error);
  if (summary == NULL)
    {
      g_prefix_error (error, "Error getting repository metadata from summary file: ");
      return FALSE;
    }

  if (!opt_info && !opt_branches && !opt_metadata_branch && !opt_commits_branch && !opt_subsets)
    opt_info = TRUE;

  /* Print out the metadata. */
  if (opt_info)
    print_info (repo, index, summary);

  if (opt_branches)
    print_branches (repo, index, summary);

  if (opt_metadata_branch)
    print_metadata (repo, index, summary, opt_metadata_branch);

  if (opt_subsets)
    print_subsets (repo, index);

  if (opt_commits_branch)
    {
      if (!print_commits (repo, collection_id, opt_commits_branch, cancellable, error))
        return FALSE;
    }

  return TRUE;
}

gboolean
flatpak_complete_repo (FlatpakCompletion *completion)
{
  g_autoptr(GOptionContext) context = NULL;

  context = g_option_context_new ("");

  if (!flatpak_option_context_parse (context, options, &completion->argc, &completion->argv,
                                     FLATPAK_BUILTIN_FLAG_NO_DIR, NULL, NULL, NULL))
    return FALSE;

  switch (completion->argc)
    {
    case 0:
    case 1: /* LOCATION */
      flatpak_complete_options (completion, global_entries);
      flatpak_complete_options (completion, options);

      flatpak_complete_dir (completion);
      break;
    }

  return TRUE;
}

===== ./app/flatpak-builtins-repair.c =====
/* vi:set et sw=2 sts=2 cin cino=t0,f0,(0,{s,>2s,n-s,^-s,e-s:
 * Copyright © 2018 Red Hat, Inc
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Alexander Larsson <alexl@redhat.com>
 */

#include "config.h"

#include <locale.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

#include <glib/gi18n.h>

#include "libglnx.h"

#include "flatpak-builtins.h"
#include "flatpak-builtins-utils.h"
#include "flatpak-utils-private.h"
#include "flatpak-table-printer.h"
#include "flatpak-error.h"
#include "flatpak-quiet-transaction.h"

static gboolean opt_dry_run;
static gboolean opt_reinstall_all;

static GOptionEntry options[] = {
  { "dry-run", 0, 0, G_OPTION_ARG_NONE, &opt_dry_run, N_("Don't make any changes"), NULL },
  { "reinstall-all", 0, 0, G_OPTION_ARG_NONE, &opt_reinstall_all, N_("Reinstall all refs"), NULL },
  { NULL }
};

typedef enum {
  FSCK_STATUS_OK,
  FSCK_STATUS_HAS_MISSING_OBJECTS,
  FSCK_STATUS_HAS_INVALID_OBJECTS,
} FsckStatus;

static FsckStatus
fsck_one_object (OstreeRepo      *repo,
                 const char      *checksum,
                 OstreeObjectType objtype,
                 gboolean         allow_missing)
{
  g_autoptr(GError) local_error = NULL;

  if (!ostree_repo_fsck_object (repo, objtype, checksum, NULL, &local_error))
    {
      if (g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
        {
          g_clear_error (&local_error);
          if (!allow_missing)
            g_printerr (_("Object missing: %s.%s\n"), checksum,
                        ostree_object_type_to_string (objtype));
          return FSCK_STATUS_HAS_MISSING_OBJECTS;
        }
      else
        {
          if (opt_dry_run)
            {
              g_printerr (_("Object invalid: %s.%s\n"), checksum,
                          ostree_object_type_to_string (objtype));
            }
          else
            {
              g_printerr (_("%s, deleting object\n"), local_error->message);
              (void) ostree_repo_delete_object (repo, objtype, checksum, NULL, NULL);
            }
          return FSCK_STATUS_HAS_INVALID_OBJECTS;
        }
    }

  return FSCK_STATUS_OK;
}

/* This is used for leaf object types */
static FsckStatus
fsck_leaf_object (OstreeRepo      *repo,
                  const char      *checksum,
                  OstreeObjectType objtype,
                  GHashTable      *object_status_cache)
{
  g_autoptr(GVariant) key = NULL;
  gpointer cached_status;
  FsckStatus status = 0;

  key = g_variant_ref_sink (ostree_object_name_serialize (checksum, objtype));

  if (g_hash_table_lookup_extended (object_status_cache, key, NULL, &cached_status))
    {
      status = GPOINTER_TO_INT (cached_status);
    }
  else
    {
      status = fsck_one_object (repo, checksum, objtype, FALSE);
      g_hash_table_insert (object_status_cache, g_steal_pointer (&key), GINT_TO_POINTER (status));
    }

  return status;
}


static FsckStatus
fsck_dirtree (OstreeRepo *repo,
              gboolean    partial,
              const char *checksum,
              GHashTable *object_status_cache)
{
  OstreeRepoCommitIterResult iterres;
  g_autoptr(GError) local_error = NULL;
  FsckStatus status = 0;
  g_autoptr(GVariant) key = NULL;
  g_autoptr(GVariant) dirtree = NULL;
  gpointer cached_status;
  ostree_cleanup_repo_commit_traverse_iter
  OstreeRepoCommitTraverseIter iter = { 0, };

  key = g_variant_ref_sink (ostree_object_name_serialize (checksum, OSTREE_OBJECT_TYPE_DIR_TREE));
  if (g_hash_table_lookup_extended (object_status_cache, key, NULL, &cached_status))
    return GPOINTER_TO_INT (cached_status);

  /* First verify the dirtree itself */
  status = fsck_one_object (repo, checksum, OSTREE_OBJECT_TYPE_DIR_TREE, partial);

  if (status == FSCK_STATUS_OK)
    {
      if (!ostree_repo_load_variant (repo, OSTREE_OBJECT_TYPE_DIR_TREE, checksum,
                                     &dirtree, &local_error) ||
          !ostree_repo_commit_traverse_iter_init_dirtree (&iter, repo, dirtree, 0, &local_error))
        {
          g_printerr (_("Can't load object %s: %s\n"), checksum, local_error->message);
          g_clear_error (&local_error);
          status = MAX (status, FSCK_STATUS_HAS_INVALID_OBJECTS);
        }
      else
        {
          /* Then its children, recursively */
          while (TRUE)
            {
              iterres = ostree_repo_commit_traverse_iter_next (&iter, NULL, &local_error);
              if (iterres == OSTREE_REPO_COMMIT_ITER_RESULT_ERROR)
                {
                  /* Some internal error in the dir-object */
                  g_print ("%s\n", local_error->message);
                  g_clear_error (&local_error);
                  status = MAX (status, FSCK_STATUS_HAS_INVALID_OBJECTS);
                  break;
                }
              else if (iterres == OSTREE_REPO_COMMIT_ITER_RESULT_END)
                break;
              else if (iterres == OSTREE_REPO_COMMIT_ITER_RESULT_FILE)
                {
                  char *name;
                  char *commit_checksum;
                  FsckStatus file_status;

                  ostree_repo_commit_traverse_iter_get_file (&iter, &name, &commit_checksum);
                  file_status = fsck_leaf_object (repo, commit_checksum, OSTREE_OBJECT_TYPE_FILE, object_status_cache);
                  status = MAX (status, file_status);
                }
              else if (iterres == OSTREE_REPO_COMMIT_ITER_RESULT_DIR)
                {
                  char *name;
                  char *meta_checksum;
                  char *dirtree_checksum;
                  FsckStatus meta_status;
                  FsckStatus dirtree_status;

                  ostree_repo_commit_traverse_iter_get_dir (&iter, &name, &dirtree_checksum, &meta_checksum);

                  meta_status = fsck_leaf_object (repo, meta_checksum, OSTREE_OBJECT_TYPE_DIR_META, object_status_cache);
                  status = MAX (status, meta_status);

                  dirtree_status = fsck_dirtree (repo, partial, dirtree_checksum, object_status_cache);

                  status = MAX (status, dirtree_status);
                }
              else
                g_assert_not_reached ();
            }
        }
    }

  g_hash_table_insert (object_status_cache, g_steal_pointer (&key), GINT_TO_POINTER (status));
  return status;
}

static FsckStatus
fsck_commit (OstreeRepo *repo,
             const char *checksum,
             GHashTable *object_status_cache)
{
  g_autoptr(GError) local_error = NULL;
  g_autoptr(GVariant) commit = NULL;
  g_autoptr(GVariant) dirtree_csum_bytes = NULL;
  g_autofree char *dirtree_checksum = NULL;
  g_autoptr(GVariant) meta_csum_bytes = NULL;
  g_autofree char *meta_checksum = NULL;
  OstreeRepoCommitState commitstate = 0;
  FsckStatus status, dirtree_status, meta_status;
  gboolean partial;

  status = fsck_one_object (repo, checksum, OSTREE_OBJECT_TYPE_COMMIT, FALSE);
  if (status != FSCK_STATUS_OK)
    return status;

  if (!ostree_repo_load_commit (repo, checksum, &commit, &commitstate, &local_error))
    {
      /* This really shouldn't happen since we just fsck'd the commit, but
       * deleting it makes the most sense.
       */
      if (opt_dry_run)
        g_printerr (_("Commit invalid %s: %s\n"), checksum, local_error->message);
      else
        {
          g_printerr (_("Deleting invalid commit %s: %s\n"), checksum, local_error->message);
          (void) ostree_repo_delete_object (repo, OSTREE_OBJECT_TYPE_COMMIT, checksum, NULL, NULL);
        }

      g_clear_error (&local_error);
      return FSCK_STATUS_HAS_INVALID_OBJECTS;
    }

  partial = (commitstate & OSTREE_REPO_COMMIT_STATE_PARTIAL) != 0;

  g_variant_get_child (commit, 7, "@ay", &meta_csum_bytes);
  meta_checksum = ostree_checksum_from_bytes (ostree_checksum_bytes_peek (meta_csum_bytes));

  meta_status = fsck_leaf_object (repo, meta_checksum, OSTREE_OBJECT_TYPE_DIR_META, object_status_cache);
  status = MAX (status, meta_status);

  g_variant_get_child (commit, 6, "@ay", &dirtree_csum_bytes);
  dirtree_checksum = ostree_checksum_from_bytes (ostree_checksum_bytes_peek (dirtree_csum_bytes));

  dirtree_status = fsck_dirtree (repo, partial, dirtree_checksum, object_status_cache);
  status = MAX (status, dirtree_status);

  /* It's ok for partial commits to have missing objects
   * https://github.com/flatpak/flatpak/issues/4624
   */
  if (status == FSCK_STATUS_HAS_MISSING_OBJECTS && partial)
    status = FSCK_STATUS_OK;
  else if (status != FSCK_STATUS_OK && !partial)
    {
      if (opt_dry_run)
        g_printerr (_("Commit should be marked partial: %s\n"), checksum);
      else
        {
          g_printerr (_("Marking commit as partial: %s\n"), checksum);
          if (!ostree_repo_mark_commit_partial_reason (repo, checksum, TRUE,
                                                       OSTREE_REPO_COMMIT_STATE_FSCK_PARTIAL,
                                                       &local_error))
            {
              g_printerr ("%s\n", local_error->message);
              g_clear_error (&local_error);
            }
        }
    }

  return status;
}

static void
transaction_add_local_ref (FlatpakDir         *dir,
                           FlatpakTransaction *transaction,
                           FlatpakDecomposed  *ref)
{
  g_autoptr(GBytes) deploy_data = NULL;
  g_autoptr(GError) local_error = NULL;
  g_autofree char *repo_checksum = NULL;
  const char *origin;
  g_autofree const char **subpaths = NULL;

  deploy_data = flatpak_dir_get_deploy_data (dir, ref, FLATPAK_DEPLOY_VERSION_ANY, NULL, &local_error);
  if (deploy_data == NULL)
    {
      if (!g_error_matches (local_error, FLATPAK_ERROR, FLATPAK_ERROR_NOT_INSTALLED))
        g_printerr (_("Problems loading data for %s: %s\n"), flatpak_decomposed_get_ref (ref), local_error->message);
      g_clear_error (&local_error);
      return;
    }

  origin = flatpak_deploy_data_get_origin (deploy_data);
  subpaths = flatpak_deploy_data_get_subpaths (deploy_data);

  repo_checksum = flatpak_dir_read_latest (dir, origin, flatpak_decomposed_get_ref (ref), NULL, NULL, NULL);
  if (repo_checksum == NULL || opt_reinstall_all)
    {
      if (!flatpak_transaction_add_install (transaction, origin, flatpak_decomposed_get_ref (ref), subpaths, &local_error))
        {
          g_printerr (_("Error reinstalling %s: %s\n"), flatpak_decomposed_get_ref (ref), local_error->message);
          g_clear_error (&local_error);
        }
    }
}


gboolean
flatpak_builtin_repair (int argc, char **argv, GCancellable *cancellable, GError **error)
{
  g_autoptr(GOptionContext) context = NULL;
  g_autoptr(GPtrArray) dirs = NULL;
  g_autoptr(GPtrArray) refs = NULL;
  FlatpakDir *dir = NULL;
  g_autoptr(GHashTable) all_refs = NULL;
  g_autoptr(GHashTable) object_status_cache = NULL;
  g_autoptr(FlatpakTransaction) transaction = NULL;
  OstreeRepo *repo;
  g_autoptr(GFile) file = NULL;
  int i;

  context = g_option_context_new (_("- Repair a flatpak installation"));
  g_option_context_set_translation_domain (context, GETTEXT_PACKAGE);

  if (!flatpak_option_context_parse (context, options, &argc, &argv,
                                     FLATPAK_BUILTIN_FLAG_ONE_DIR, &dirs, cancellable, error))
    return FALSE;

  dir = g_ptr_array_index (dirs, 0);

  if (!flatpak_dir_ensure_repo (dir, cancellable, error))
    return FALSE;

  repo = flatpak_dir_get_repo (dir);

  g_print ("Working on the %s installation at %s\n",
           flatpak_dir_get_name_cached (dir),
           flatpak_file_get_path_cached (flatpak_dir_get_path (dir)));

  if (!opt_dry_run && !flatpak_dir_is_user (dir) && geteuid () != 0)
    {
      g_print ("Privileges are required to make changes; assuming --dry-run\n");
      opt_dry_run = TRUE;
    }

  /*
   * Try to repair a flatpak directory:
   *  + Delete any mirror refs which may be leaking disk space
   *    (https://github.com/flatpak/flatpak/issues/3222)
   *  + Scan all locally available refs
   *  + remove ref that don't correspond to a deployed ref
   *  + Verify the commits they point to and all object they reference:
   *  +  Remove any invalid objects
   *  +  Note any missing objects
   *  + Any refs that had invalid object, or non-partial refs that had missing
   *      objects are removed
   *  + Prune (depth=0) all object not references by a ref, which gets rid of
   *      any possibly invalid non-scanned objects
   *  * Remove leftover .removed contents
   *  + Enumerate all deployed refs:
   *      If they are not in the repo (or is partial for a non-subdir deploy),
   *      re-install them (pull + deploy)
   */

  if (!flatpak_dir_delete_mirror_refs (dir, opt_dry_run, cancellable, error))
    return FALSE;

  object_status_cache = g_hash_table_new_full (ostree_hash_object_name, g_variant_equal,
                                               (GDestroyNotify) g_variant_unref, NULL);

  /* Validate that the commit for each ref is available */
  if (!ostree_repo_list_refs (repo, NULL, &all_refs, cancellable, error))
    return FALSE;

  i = 0;
  GLNX_HASH_TABLE_FOREACH_KV (all_refs, const char *, refspec, const char *, checksum)
  {
    g_autofree char *remote = NULL;
    g_autofree char *ref_name = NULL;
    FsckStatus status;
    g_autoptr(FlatpakDecomposed) ref = NULL;
    g_autofree char *origin = NULL;

    i++;

    if (!ostree_parse_refspec (refspec, &remote, &ref_name, error))
      return FALSE;

    /* Does this look like a regular ref? */
    ref = flatpak_decomposed_new_from_ref (ref_name, NULL);
    if (ref == NULL)
      continue;

    origin = flatpak_dir_get_origin (dir, ref, cancellable, NULL);

    /* If so, is it deployed, and from this remote? */
    if (remote == NULL || g_strcmp0 (origin, remote) != 0)
      {
        if (!opt_dry_run)
          {
            g_print (_("Removing non-deployed ref %s…\n"), refspec);
            (void) ostree_repo_set_ref_immediate (repo, remote, ref_name, NULL,
                                                  cancellable, NULL);
          }
        else
          g_print (_("Skipping non-deployed ref %s…\n"), refspec);

        continue;
      }

    /* When printing progress, we have to print a newline character at the end,
     * otherwise errors printing in sections of the code that we don't control
     * won't have a leading newline.  Therefore, the status line will always
     * print a trailing newline, and here we just go up a line back onto the
     * previous progress line.

     * This does also mean that other areas of this code section that print
     * errors will need to print a trailing newline as well, otherwise the
     * output will overwrite any errors.
     */
    if (flatpak_fancy_output () && i != 1)
      g_print ("\033[A\r\033[K");

    g_print (_("[%d/%d] Verifying %s…\n"), i, g_hash_table_size (all_refs), refspec);

    status = fsck_commit (repo, checksum, object_status_cache);
    if (status != FSCK_STATUS_OK)
      {
        if (opt_dry_run)
          g_printerr (_("Dry run: "));

        switch (status)
          {
          case FSCK_STATUS_HAS_MISSING_OBJECTS:
            g_printerr (_("Deleting ref %s due to missing objects\n"), refspec);
            break;

          case FSCK_STATUS_HAS_INVALID_OBJECTS:
            g_printerr (_("Deleting ref %s due to invalid objects\n"), refspec);
            break;

          default:
            g_printerr (_("Deleting ref %s due to %d\n"), refspec, status);
            break;
          }

        if (!opt_dry_run)
          (void) ostree_repo_set_ref_immediate (repo, remote, ref_name, NULL,
                                                cancellable, NULL);

        /* If using fancy output, print another trailing newline, so the next
         * progress line won't overwrite these errors.
         */
        if (flatpak_fancy_output () && i < g_hash_table_size (all_refs))
          g_print ("\n");
      }
  }

  g_print (_("Checking remotes...\n"));

  GLNX_HASH_TABLE_FOREACH_KV (all_refs, const char *, refspec, const char *, checksum)
  {
    g_autofree char *remote = NULL;
    g_autofree char *ref_name = NULL;

    if (!ostree_parse_refspec (refspec, &remote, &ref_name, error))
      return FALSE;

    if (remote == NULL)
      continue;

    /* Does this look like a regular ref? */
    if (!g_str_has_prefix (ref_name, "app/") && !g_str_has_prefix (ref_name, "runtime/"))
      continue;

    if (!flatpak_dir_has_remote (dir, remote, NULL))
      g_print (_("Remote %s for ref %s is missing\n"), remote, ref_name);
    else if (flatpak_dir_get_remote_disabled (dir, remote))
      g_print (_("Remote %s for ref %s is disabled\n"), remote, ref_name);
  }

  if (opt_dry_run)
    return TRUE;

  g_print (_("Pruning objects\n"));

  if (!flatpak_dir_prune (dir, cancellable, error))
    return FALSE;

  file = flatpak_dir_get_removed_dir (dir);
  if (g_file_query_exists (file, cancellable))
    {
      g_print (_("Erasing .removed\n"));
      if (!flatpak_rm_rf (file, cancellable, error))
        return FALSE;
    }

  refs = flatpak_dir_list_refs (dir, FLATPAK_KINDS_APP | FLATPAK_KINDS_RUNTIME,
                                cancellable, error);

  transaction = flatpak_quiet_transaction_new (dir, error);
  if (transaction == NULL)
    return FALSE;

  flatpak_transaction_set_disable_dependencies (transaction, TRUE);
  flatpak_transaction_set_disable_related (transaction, TRUE);
  flatpak_transaction_set_reinstall (transaction, TRUE);
  flatpak_transaction_set_disable_auto_pin (transaction, TRUE);

  for (i = 0; i < refs->len; i++)
    {
      FlatpakDecomposed *ref = g_ptr_array_index (refs, i);
      transaction_add_local_ref (dir, transaction, ref);
    }

  if (!flatpak_transaction_is_empty (transaction))
    {
      if (opt_reinstall_all)
        g_print (_("Reinstalling refs\n"));
      else
        g_print (_("Reinstalling removed refs\n"));
      if (!flatpak_transaction_run (transaction, cancellable, error))
        return FALSE;
    }

  if (opt_reinstall_all)
    {
      g_print ("Reinstalling appstream\n");

      GLNX_HASH_TABLE_FOREACH_KV (all_refs, const char *, refspec, const char *, checksum)
      {
        g_autofree char *remote = NULL;
        g_autofree char *ref_name = NULL;

        if (!ostree_parse_refspec (refspec, &remote, &ref_name, error))
          return FALSE;

        /* Does this look like an appstream ref? */
        if (g_str_has_prefix (ref_name, "appstream"))
          {
            g_auto(GStrv) parts = g_strsplit (ref_name, "/", 0);
            gboolean changed;

            if (!flatpak_dir_remove_appstream (dir, remote, cancellable, error))
              {
                g_prefix_error (error, _("While removing appstream for %s: "), remote);
                return FALSE;
              }

            if (!flatpak_dir_deploy_appstream (dir, remote, parts[1], &changed,
                                               cancellable, error))
              {
                g_prefix_error (error, _("While deploying appstream for %s: "), remote);
                return FALSE;
              }
          }
      }
    }

  return TRUE;
}

gboolean
flatpak_complete_repair (FlatpakCompletion *completion)
{
  g_autoptr(GOptionContext) context = NULL;
  g_autoptr(GPtrArray) dirs = NULL;

  context = g_option_context_new ("");

  if (!flatpak_option_context_parse (context, options, &completion->argc, &completion->argv,
                                     FLATPAK_BUILTIN_FLAG_ONE_DIR | FLATPAK_BUILTIN_FLAG_OPTIONAL_REPO,
                                     &dirs, NULL, NULL))
    return FALSE;

  flatpak_complete_options (completion, global_entries);
  flatpak_complete_options (completion, options);
  flatpak_complete_options (completion, user_entries);

  return TRUE;
}

===== ./app/flatpak-quiet-transaction.h =====
/*
 * Copyright © 2019 Red Hat, Inc
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Matthias Clasen <mclasen@redhat.com>
 */

#ifndef __FLATPAK_QUIET_TRANSACTION_H__
#define __FLATPAK_QUIET_TRANSACTION_H__

#include "flatpak-transaction.h"
#include "flatpak-dir-private.h"

#define FLATPAK_TYPE_QUIET_TRANSACTION flatpak_quiet_transaction_get_type ()
G_DECLARE_FINAL_TYPE (FlatpakQuietTransaction, flatpak_quiet_transaction, FLATPAK, QUIET_TRANSACTION, FlatpakTransaction)

FlatpakTransaction * flatpak_quiet_transaction_new (FlatpakDir  * dir,
                                                    GError     **error);

#endif /* __FLATPAK_QUIET_TRANSACTION_H__ */

===== ./app/flatpak-table-printer.h =====
/*
 * Copyright © 2014 Red Hat, Inc
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Alexander Larsson <alexl@redhat.com>
 */

#ifndef __FLATPAK_TABLE_PRINTER_H__
#define __FLATPAK_TABLE_PRINTER_H__

#include <gio/gio.h>

#include "flatpak-builtins-utils.h"

typedef struct FlatpakTablePrinter FlatpakTablePrinter;

FlatpakTablePrinter *flatpak_table_printer_new (void);
void                flatpak_table_printer_free (FlatpakTablePrinter *printer);
void                flatpak_table_printer_set_column_title (FlatpakTablePrinter *printer,
                                                            int                  column,
                                                            const char          *title);
void                flatpak_table_printer_set_columns (FlatpakTablePrinter *printer,
                                                       Column              *columns,
                                                       gboolean             defaults);
void                flatpak_table_printer_add_column (FlatpakTablePrinter *printer,
                                                      const char          *text);
void                flatpak_table_printer_take_column (FlatpakTablePrinter *printer,
                                                       char                *text);
void                flatpak_table_printer_add_aligned_column (FlatpakTablePrinter *printer,
                                                              const char          *text,
                                                              int                  align);
void                flatpak_table_printer_add_decimal_column (FlatpakTablePrinter *printer,
                                                              const char          *text);
void                flatpak_table_printer_add_column_len (FlatpakTablePrinter *printer,
                                                          const char          *text,
                                                          gsize                len);
void                flatpak_table_printer_add_span (FlatpakTablePrinter *printer,
                                                    const char          *text);
void                flatpak_table_printer_append_with_comma (FlatpakTablePrinter *printer,
                                                             const char          *text);
void                flatpak_table_printer_append_with_comma_printf (FlatpakTablePrinter *printer,
                                                                    const char          *format,
                                                                    ...) G_GNUC_PRINTF (2, 3);
void                flatpak_table_printer_set_key (FlatpakTablePrinter *printer,
                                                   const char          *key);
void                flatpak_table_printer_finish_row (FlatpakTablePrinter *printer);
void                flatpak_table_printer_sort (FlatpakTablePrinter *printer,
                                                GCompareFunc         cmp);
int                 flatpak_table_printer_lookup_row (FlatpakTablePrinter *printer, const char *key);
void                flatpak_table_printer_print (FlatpakTablePrinter *printer);
void                flatpak_table_printer_print_json (FlatpakTablePrinter *printer);
void                flatpak_table_printer_print_full (FlatpakTablePrinter *printer,
                                                      int                  skip,
                                                      int                  columns,
                                                      int                 *table_height,
                                                      int                 *table_width);
int                 flatpak_table_printer_get_current_row (FlatpakTablePrinter *printer);
void                flatpak_table_printer_set_cell (FlatpakTablePrinter *printer,
                                                    int                  row,
                                                    int                  col,
                                                    const char          *cell);
void                flatpak_table_printer_append_cell (FlatpakTablePrinter *printer,
                                                       int                  row,
                                                       int                  col,
                                                       const char          *cell);
void                flatpak_table_printer_append_cell_with_comma (FlatpakTablePrinter *printer,
                                                                  int                  row,
                                                                  int                  col,
                                                                  const char          *cell);
void                flatpak_table_printer_append_cell_with_comma_unique (FlatpakTablePrinter *printer,
                                                                         int                  row,
                                                                         int                  col,
                                                                         const char          *cell);
void                flatpak_table_printer_set_decimal_cell (FlatpakTablePrinter *printer,
                                                            int                  row,
                                                            int                  col,
                                                            const char          *cell);
void               flatpak_table_printer_set_column_expand (FlatpakTablePrinter *printer,
                                                            int                  col,
                                                            gboolean             expand);
void               flatpak_table_printer_set_column_ellipsize (FlatpakTablePrinter *printer,
                                                               int                  col,
                                                               FlatpakEllipsizeMode mode);
void               flatpak_table_printer_set_column_skip_unique (FlatpakTablePrinter *printer,
                                                                 int                  column,
                                                                 gboolean             skip_unique);
void               flatpak_table_printer_set_column_skip_unique_string (FlatpakTablePrinter *printer,
                                                                        int                  column,
                                                                        const char          *str);


G_DEFINE_AUTOPTR_CLEANUP_FUNC (FlatpakTablePrinter, flatpak_table_printer_free)

#endif /* __FLATPAK_TABLE_PRINTER_H__ */

===== ./app/parse-datetime.y =====
%{
/* Parse a string into an internal time stamp.

   Copyright (C) 1999-2000, 2002-2015 Free Software Foundation, Inc.

   This program 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 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/>.  */

/* Originally written by Steven M. Bellovin <smb@research.att.com> while
   at the University of North Carolina at Chapel Hill.  Later tweaked by
   a couple of people on Usenet.  Completely overhauled by Rich $alz
   <rsalz@bbn.com> and Jim Berets <jberets@bbn.com> in August, 1990.

   Modified by Paul Eggert <eggert@twinsun.com> in August 1999 to do
   the right thing about local DST.  Also modified by Paul Eggert
   <eggert@cs.ucla.edu> in February 2004 to support
   nanosecond-resolution time stamps, and in October 2004 to support
   TZ strings in dates.  */

/* FIXME: Check for arithmetic overflow in all cases, not just
   some of them.  */


#include "config.h"
#include "parse-datetime.h"
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#include <sys/time.h>
#include <glib.h>
#include <stdint.h>

/* There's no need to extend the stack, so there's no need to involve
   alloca.  */
#define YYSTACK_USE_ALLOCA 0

static char *
xmemdup (void const *p, size_t s)
{
  char *result = g_malloc (s);
  memcpy (result, p, s);
  return result;
}

static void
gettime (struct timespec *ts)
 {
#ifdef HAVE_NANOTIME
   nanotime (ts);
#else

# if defined(CLOCK_REALTIME) && defined(HAVE_CLOCK_GETTIME)
   if (clock_gettime (CLOCK_REALTIME, ts) == 0)
     return;
# endif

   {
     struct timeval tv;
     gettimeofday (&tv, NULL);
     ts->tv_sec = tv.tv_sec;
     ts->tv_nsec = tv.tv_usec * 1000;
   }

#endif
 }

/* Tell Bison how much stack space is needed.  20 should be plenty for
   this grammar, which is not right recursive.  Beware setting it too
   high, since that might cause problems on machines whose
   implementations have lame stack-overflow checking.  */
#define YYMAXDEPTH 20
#define YYINITDEPTH YYMAXDEPTH

/* Since the code of parse-datetime.y is not included in the Emacs executable
   itself, there is no need to #define static in this file.  Even if
   the code were included in the Emacs executable, it probably
   wouldn't do any harm to #undef it here; this will only cause
   problems if we try to write to a static variable, which I don't
   think this code needs to do.  */
#ifdef emacs
# undef static
#endif

#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>


/* Bison's skeleton tests _STDLIB_H, while some stdlib.h headers
   use _STDLIB_H_ as witness.  Map the latter to the one bison uses.  */
/* FIXME: this is temporary.  Remove when we have a mechanism to ensure
   that the version we're using is fixed, too.  */
#ifdef _STDLIB_H_
# undef _STDLIB_H
# define _STDLIB_H 1
#endif

/* ISDIGIT differs from isdigit, as follows:
   - Its arg may be any int or unsigned int; it need not be an unsigned char
     or EOF.
   - It's typically faster.
   POSIX says that only '0' through '9' are digits.  Prefer ISDIGIT to
   isdigit unless it's important to use the locale's definition
   of "digit" even when the host does not conform to POSIX.  */
#define ISDIGIT(c) ((unsigned int) (c) - '0' <= 9)

/* Shift A right by B bits portably, by dividing A by 2**B and
   truncating towards minus infinity.  A and B should be free of side
   effects, and B should be in the range 0 <= B <= INT_BITS - 2, where
   INT_BITS is the number of useful bits in an int.  GNU code can
   assume that INT_BITS is at least 32.

   ISO C99 says that A >> B is implementation-defined if A < 0.  Some
   implementations (e.g., UNICOS 9.0 on a Cray Y-MP EL) don't shift
   right in the usual way when A < 0, so SHR falls back on division if
   ordinary A >> B doesn't seem to be the usual signed shift.  */
#define SHR(a, b)       \
  (-1 >> 1 == -1        \
   ? (a) >> (b)         \
   : (a) / (1 << (b)) - ((a) % (1 << (b)) < 0))

#define EPOCH_YEAR 1970
#define TM_YEAR_BASE 1900

#define HOUR(x) ((x) * 60)

/* Convert a possibly-signed character to an unsigned character.  This is
   a bit safer than casting to unsigned char, since it catches some type
   errors that the cast doesn't.  */
static unsigned char to_uchar (char ch) { return ch; }

/* FIXME: It also assumes that signed integer overflow silently wraps around,
   but this is not true any more with recent versions of GCC 4.  */

/* An integer value, and the number of digits in its textual
   representation.  */
typedef struct
{
  bool negative;
  long int value;
  size_t digits;
} textint;

/* An entry in the lexical lookup table.  */
typedef struct
{
  char const *name;
  int type;
  int value;
} table;

/* Meridian: am, pm, or 24-hour style.  */
enum { MERam, MERpm, MER24 };

enum { BILLION = 1000000000, LOG10_BILLION = 9 };

/* Relative times.  */
typedef struct
{
  /* Relative year, month, day, hour, minutes, seconds, and nanoseconds.  */
  long int year;
  long int month;
  long int day;
  long int hour;
  long int minutes;
  intmax_t seconds;
  int ns;
} relative_time;

#define RELATIVE_TIME_0 ((relative_time) { 0, 0, 0, 0, 0, 0, 0 })

/* Information passed to and from the parser.  */
typedef struct
{
  /* The input string remaining to be parsed. */
  const char *input;

  /* N, if this is the Nth Tuesday.  */
  long int day_ordinal;

  /* Day of week; Sunday is 0.  */
  int day_number;

  /* tm_isdst flag for the local zone.  */
  int local_isdst;

  /* Time zone, in minutes east of UTC.  */
  long int time_zone;

  /* Style used for time.  */
  int meridian;

  /* Gregorian year, month, day, hour, minutes, seconds, and nanoseconds.  */
  textint year;
  long int month;
  long int day;
  long int hour;
  long int minutes;
  struct timespec seconds; /* includes nanoseconds */

  /* Relative year, month, day, hour, minutes, seconds, and nanoseconds.  */
  relative_time rel;

  /* Presence or counts of nonterminals of various flavors parsed so far.  */
  bool timespec_seen;
  bool rels_seen;
  size_t dates_seen;
  size_t days_seen;
  size_t local_zones_seen;
  size_t dsts_seen;
  size_t times_seen;
  size_t zones_seen;

  /* Table of local time zone abbreviations, terminated by a null entry.  */
  table local_time_zone_table[3];
} parser_control;

union YYSTYPE;
static int yylex (union YYSTYPE *, parser_control *);
static int yyerror (parser_control const *, char const *);
static long int time_zone_hhmm (parser_control *, textint, long int);

/* Extract into *PC any date and time info from a string of digits
   of the form e.g., YYYYMMDD, YYMMDD, HHMM, HH (and sometimes YYY,
   YYYY, ...).  */
static void
digits_to_date_time (parser_control *pc, textint text_int)
{
  if (pc->dates_seen && ! pc->year.digits
      && ! pc->rels_seen && (pc->times_seen || 2 < text_int.digits))
    pc->year = text_int;
  else
    {
      if (4 < text_int.digits)
        {
          pc->dates_seen++;
          pc->day = text_int.value % 100;
          pc->month = (text_int.value / 100) % 100;
          pc->year.value = text_int.value / 10000;
          pc->year.digits = text_int.digits - 4;
        }
      else
        {
          pc->times_seen++;
          if (text_int.digits <= 2)
            {
              pc->hour = text_int.value;
              pc->minutes = 0;
            }
          else
            {
              pc->hour = text_int.value / 100;
              pc->minutes = text_int.value % 100;
            }
          pc->seconds.tv_sec = 0;
          pc->seconds.tv_nsec = 0;
          pc->meridian = MER24;
        }
    }
}

/* Increment PC->rel by FACTOR * REL (FACTOR is 1 or -1).  */
static void
apply_relative_time (parser_control *pc, relative_time rel, int factor)
{
  pc->rel.ns += factor * rel.ns;
  pc->rel.seconds += factor * rel.seconds;
  pc->rel.minutes += factor * rel.minutes;
  pc->rel.hour += factor * rel.hour;
  pc->rel.day += factor * rel.day;
  pc->rel.month += factor * rel.month;
  pc->rel.year += factor * rel.year;
  pc->rels_seen = true;
}

/* Set PC-> hour, minutes, seconds and nanoseconds members from arguments.  */
static void
set_hhmmss (parser_control *pc, long int hour, long int minutes,
            time_t sec, long int nsec)
{
  pc->hour = hour;
  pc->minutes = minutes;
  pc->seconds.tv_sec = sec;
  pc->seconds.tv_nsec = nsec;
}

%}

/* We want a reentrant parser, even if the TZ manipulation and the calls to
   localtime and gmtime are not reentrant.  */
%define api.pure
%parse-param { parser_control *pc }
%lex-param { parser_control *pc }

/* This grammar has 31 shift/reduce conflicts. */
%expect 31

%union
{
  long int intval;
  textint textintval;
  struct timespec timespec;
  relative_time rel;
}

%token <intval> tAGO
%token tDST

%token tYEAR_UNIT tMONTH_UNIT tHOUR_UNIT tMINUTE_UNIT tSEC_UNIT
%token <intval> tDAY_UNIT tDAY_SHIFT

%token <intval> tDAY tDAYZONE tLOCAL_ZONE tMERIDIAN
%token <intval> tMONTH tORDINAL tZONE

%token <textintval> tSNUMBER tUNUMBER
%token <timespec> tSDECIMAL_NUMBER tUDECIMAL_NUMBER

%type <intval> o_colon_minutes
%type <timespec> seconds signed_seconds unsigned_seconds

%type <rel> relunit relunit_snumber dayshift

%%

spec:
    timespec
  | items
  ;

timespec:
    '@' seconds
      {
        pc->seconds = $2;
        pc->timespec_seen = true;
      }
  ;

items:
    /* empty */
  | items item
  ;

item:
    datetime
      { pc->times_seen++; pc->dates_seen++; }
  | time
      { pc->times_seen++; }
  | local_zone
      { pc->local_zones_seen++; }
  | zone
      { pc->zones_seen++; }
  | date
      { pc->dates_seen++; }
  | day
      { pc->days_seen++; }
  | rel
  | number
  | hybrid
  ;

datetime:
    iso_8601_datetime
  ;

iso_8601_datetime:
    iso_8601_date 'T' iso_8601_time
  ;

time:
    tUNUMBER tMERIDIAN
      {
        set_hhmmss (pc, $1.value, 0, 0, 0);
        pc->meridian = $2;
      }
  | tUNUMBER ':' tUNUMBER tMERIDIAN
      {
        set_hhmmss (pc, $1.value, $3.value, 0, 0);
        pc->meridian = $4;
      }
  | tUNUMBER ':' tUNUMBER ':' unsigned_seconds tMERIDIAN
      {
        set_hhmmss (pc, $1.value, $3.value, $5.tv_sec, $5.tv_nsec);
        pc->meridian = $6;
      }
  | iso_8601_time
  ;

iso_8601_time:
    tUNUMBER zone_offset
      {
        set_hhmmss (pc, $1.value, 0, 0, 0);
        pc->meridian = MER24;
      }
  | tUNUMBER ':' tUNUMBER o_zone_offset
      {
        set_hhmmss (pc, $1.value, $3.value, 0, 0);
        pc->meridian = MER24;
      }
  | tUNUMBER ':' tUNUMBER ':' unsigned_seconds o_zone_offset
      {
        set_hhmmss (pc, $1.value, $3.value, $5.tv_sec, $5.tv_nsec);
        pc->meridian = MER24;
      }
  ;

o_zone_offset:
  /* empty */
  | zone_offset
  ;

zone_offset:
    tSNUMBER o_colon_minutes
      {
        pc->zones_seen++;
        pc->time_zone = time_zone_hhmm (pc, $1, $2);
      }
  ;

local_zone:
    tLOCAL_ZONE
      {
        pc->local_isdst = $1;
        pc->dsts_seen += (0 < $1);
      }
  | tLOCAL_ZONE tDST
      {
        pc->local_isdst = 1;
        pc->dsts_seen += (0 < $1) + 1;
      }
  ;

/* Note 'T' is a special case, as it is used as the separator in ISO
   8601 date and time of day representation. */
zone:
    tZONE
      { pc->time_zone = $1; }
  | 'T'
      { pc->time_zone = HOUR(7); }
  | tZONE relunit_snumber
      { pc->time_zone = $1;
        apply_relative_time (pc, $2, 1); }
  | 'T' relunit_snumber
      { pc->time_zone = HOUR(7);
        apply_relative_time (pc, $2, 1); }
  | tZONE tSNUMBER o_colon_minutes
      { pc->time_zone = $1 + time_zone_hhmm (pc, $2, $3); }
  | tDAYZONE
      { pc->time_zone = $1 + 60; }
  | tZONE tDST
      { pc->time_zone = $1 + 60; }
  ;

day:
    tDAY
      {
        pc->day_ordinal = 0;
        pc->day_number = $1;
      }
  | tDAY ','
      {
        pc->day_ordinal = 0;
        pc->day_number = $1;
      }
  | tORDINAL tDAY
      {
        pc->day_ordinal = $1;
        pc->day_number = $2;
      }
  | tUNUMBER tDAY
      {
        pc->day_ordinal = $1.value;
        pc->day_number = $2;
      }
  ;

date:
    tUNUMBER '/' tUNUMBER
      {
        pc->month = $1.value;
        pc->day = $3.value;
      }
  | tUNUMBER '/' tUNUMBER '/' tUNUMBER
      {
        /* Interpret as YYYY/MM/DD if the first value has 4 or more digits,
           otherwise as MM/DD/YY.
           The goal in recognizing YYYY/MM/DD is solely to support legacy
           machine-generated dates like those in an RCS log listing.  If
           you want portability, use the ISO 8601 format.  */
        if (4 <= $1.digits)
          {
            pc->year = $1;
            pc->month = $3.value;
            pc->day = $5.value;
          }
        else
          {
            pc->month = $1.value;
            pc->day = $3.value;
            pc->year = $5;
          }
      }
  | tUNUMBER tMONTH tSNUMBER
      {
        /* e.g. 17-JUN-1992.  */
        pc->day = $1.value;
        pc->month = $2;
        pc->year.value = -$3.value;
        pc->year.digits = $3.digits;
      }
  | tMONTH tSNUMBER tSNUMBER
      {
        /* e.g. JUN-17-1992.  */
        pc->month = $1;
        pc->day = -$2.value;
        pc->year.value = -$3.value;
        pc->year.digits = $3.digits;
      }
  | tMONTH tUNUMBER
      {
        pc->month = $1;
        pc->day = $2.value;
      }
  | tMONTH tUNUMBER ',' tUNUMBER
      {
        pc->month = $1;
        pc->day = $2.value;
        pc->year = $4;
      }
  | tUNUMBER tMONTH
      {
        pc->day = $1.value;
        pc->month = $2;
      }
  | tUNUMBER tMONTH tUNUMBER
      {
        pc->day = $1.value;
        pc->month = $2;
        pc->year = $3;
      }
  | iso_8601_date
  ;

iso_8601_date:
    tUNUMBER tSNUMBER tSNUMBER
      {
        /* ISO 8601 format.  YYYY-MM-DD.  */
        pc->year = $1;
        pc->month = -$2.value;
        pc->day = -$3.value;
      }
  ;

rel:
    relunit tAGO
      { apply_relative_time (pc, $1, $2); }
  | relunit
      { apply_relative_time (pc, $1, 1); }
  | dayshift
      { apply_relative_time (pc, $1, 1); }
  ;

relunit:
    tORDINAL tYEAR_UNIT
      { $$ = RELATIVE_TIME_0; $$.year = $1; }
  | tUNUMBER tYEAR_UNIT
      { $$ = RELATIVE_TIME_0; $$.year = $1.value; }
  | tYEAR_UNIT
      { $$ = RELATIVE_TIME_0; $$.year = 1; }
  | tORDINAL tMONTH_UNIT
      { $$ = RELATIVE_TIME_0; $$.month = $1; }
  | tUNUMBER tMONTH_UNIT
      { $$ = RELATIVE_TIME_0; $$.month = $1.value; }
  | tMONTH_UNIT
      { $$ = RELATIVE_TIME_0; $$.month = 1; }
  | tORDINAL tDAY_UNIT
      { $$ = RELATIVE_TIME_0; $$.day = $1 * $2; }
  | tUNUMBER tDAY_UNIT
      { $$ = RELATIVE_TIME_0; $$.day = $1.value * $2; }
  | tDAY_UNIT
      { $$ = RELATIVE_TIME_0; $$.day = $1; }
  | tORDINAL tHOUR_UNIT
      { $$ = RELATIVE_TIME_0; $$.hour = $1; }
  | tUNUMBER tHOUR_UNIT
      { $$ = RELATIVE_TIME_0; $$.hour = $1.value; }
  | tHOUR_UNIT
      { $$ = RELATIVE_TIME_0; $$.hour = 1; }
  | tORDINAL tMINUTE_UNIT
      { $$ = RELATIVE_TIME_0; $$.minutes = $1; }
  | tUNUMBER tMINUTE_UNIT
      { $$ = RELATIVE_TIME_0; $$.minutes = $1.value; }
  | tMINUTE_UNIT
      { $$ = RELATIVE_TIME_0; $$.minutes = 1; }
  | tORDINAL tSEC_UNIT
      { $$ = RELATIVE_TIME_0; $$.seconds = $1; }
  | tUNUMBER tSEC_UNIT
      { $$ = RELATIVE_TIME_0; $$.seconds = $1.value; }
  | tSDECIMAL_NUMBER tSEC_UNIT
      { $$ = RELATIVE_TIME_0; $$.seconds = $1.tv_sec; $$.ns = $1.tv_nsec; }
  | tUDECIMAL_NUMBER tSEC_UNIT
      { $$ = RELATIVE_TIME_0; $$.seconds = $1.tv_sec; $$.ns = $1.tv_nsec; }
  | tSEC_UNIT
      { $$ = RELATIVE_TIME_0; $$.seconds = 1; }
  | relunit_snumber
  ;

relunit_snumber:
    tSNUMBER tYEAR_UNIT
      { $$ = RELATIVE_TIME_0; $$.year = $1.value; }
  | tSNUMBER tMONTH_UNIT
      { $$ = RELATIVE_TIME_0; $$.month = $1.value; }
  | tSNUMBER tDAY_UNIT
      { $$ = RELATIVE_TIME_0; $$.day = $1.value * $2; }
  | tSNUMBER tHOUR_UNIT
      { $$ = RELATIVE_TIME_0; $$.hour = $1.value; }
  | tSNUMBER tMINUTE_UNIT
      { $$ = RELATIVE_TIME_0; $$.minutes = $1.value; }
  | tSNUMBER tSEC_UNIT
      { $$ = RELATIVE_TIME_0; $$.seconds = $1.value; }
  ;

dayshift:
    tDAY_SHIFT
      { $$ = RELATIVE_TIME_0; $$.day = $1; }
  ;

seconds: signed_seconds | unsigned_seconds;

signed_seconds:
    tSDECIMAL_NUMBER
  | tSNUMBER
      { $$.tv_sec = $1.value; $$.tv_nsec = 0; }
  ;

unsigned_seconds:
    tUDECIMAL_NUMBER
  | tUNUMBER
      { $$.tv_sec = $1.value; $$.tv_nsec = 0; }
  ;

number:
    tUNUMBER
      { digits_to_date_time (pc, $1); }
  ;

hybrid:
    tUNUMBER relunit_snumber
      {
        /* Hybrid all-digit and relative offset, so that we accept e.g.,
           "YYYYMMDD +N days" as well as "YYYYMMDD N days".  */
        digits_to_date_time (pc, $1);
        apply_relative_time (pc, $2, 1);
      }
  ;

o_colon_minutes:
    /* empty */
      { $$ = -1; }
  | ':' tUNUMBER
      { $$ = $2.value; }
  ;

%%

static table const meridian_table[] =
{
  { "AM",   tMERIDIAN, MERam },
  { "A.M.", tMERIDIAN, MERam },
  { "PM",   tMERIDIAN, MERpm },
  { "P.M.", tMERIDIAN, MERpm },
  { NULL, 0, 0 }
};

static table const dst_table[] =
{
  { "DST", tDST, 0 }
};

static table const month_and_day_table[] =
{
  { "JANUARY",  tMONTH,  1 },
  { "FEBRUARY", tMONTH,  2 },
  { "MARCH",    tMONTH,  3 },
  { "APRIL",    tMONTH,  4 },
  { "MAY",      tMONTH,  5 },
  { "JUNE",     tMONTH,  6 },
  { "JULY",     tMONTH,  7 },
  { "AUGUST",   tMONTH,  8 },
  { "SEPTEMBER",tMONTH,  9 },
  { "SEPT",     tMONTH,  9 },
  { "OCTOBER",  tMONTH, 10 },
  { "NOVEMBER", tMONTH, 11 },
  { "DECEMBER", tMONTH, 12 },
  { "SUNDAY",   tDAY,    0 },
  { "MONDAY",   tDAY,    1 },
  { "TUESDAY",  tDAY,    2 },
  { "TUES",     tDAY,    2 },
  { "WEDNESDAY",tDAY,    3 },
  { "WEDNES",   tDAY,    3 },
  { "THURSDAY", tDAY,    4 },
  { "THUR",     tDAY,    4 },
  { "THURS",    tDAY,    4 },
  { "FRIDAY",   tDAY,    5 },
  { "SATURDAY", tDAY,    6 },
  { NULL, 0, 0 }
};

static table const time_units_table[] =
{
  { "YEAR",     tYEAR_UNIT,      1 },
  { "MONTH",    tMONTH_UNIT,     1 },
  { "FORTNIGHT",tDAY_UNIT,      14 },
  { "WEEK",     tDAY_UNIT,       7 },
  { "DAY",      tDAY_UNIT,       1 },
  { "HOUR",     tHOUR_UNIT,      1 },
  { "MINUTE",   tMINUTE_UNIT,    1 },
  { "MIN",      tMINUTE_UNIT,    1 },
  { "SECOND",   tSEC_UNIT,       1 },
  { "SEC",      tSEC_UNIT,       1 },
  { NULL, 0, 0 }
};

/* Assorted relative-time words. */
static table const relative_time_table[] =
{
  { "TOMORROW", tDAY_SHIFT,      1 },
  { "YESTERDAY",tDAY_SHIFT,     -1 },
  { "TODAY",    tDAY_SHIFT,      0 },
  { "NOW",      tDAY_SHIFT,      0 },
  { "LAST",     tORDINAL,       -1 },
  { "THIS",     tORDINAL,        0 },
  { "NEXT",     tORDINAL,        1 },
  { "FIRST",    tORDINAL,        1 },
/*{ "SECOND",   tORDINAL,        2 }, */
  { "THIRD",    tORDINAL,        3 },
  { "FOURTH",   tORDINAL,        4 },
  { "FIFTH",    tORDINAL,        5 },
  { "SIXTH",    tORDINAL,        6 },
  { "SEVENTH",  tORDINAL,        7 },
  { "EIGHTH",   tORDINAL,        8 },
  { "NINTH",    tORDINAL,        9 },
  { "TENTH",    tORDINAL,       10 },
  { "ELEVENTH", tORDINAL,       11 },
  { "TWELFTH",  tORDINAL,       12 },
  { "AGO",      tAGO,           -1 },
  { "HENCE",    tAGO,            1 },
  { NULL, 0, 0 }
};

/* The universal time zone table.  These labels can be used even for
   time stamps that would not otherwise be valid, e.g., GMT time
   stamps in London during summer.  */
static table const universal_time_zone_table[] =
{
  { "GMT",      tZONE,     HOUR ( 0) }, /* Greenwich Mean */
  { "UT",       tZONE,     HOUR ( 0) }, /* Universal (Coordinated) */
  { "UTC",      tZONE,     HOUR ( 0) },
  { NULL, 0, 0 }
};

/* The time zone table.  This table is necessarily incomplete, as time
   zone abbreviations are ambiguous; e.g. Australians interpret "EST"
   as Eastern time in Australia, not as US Eastern Standard Time.
   You cannot rely on parse_datetime to handle arbitrary time zone
   abbreviations; use numeric abbreviations like "-0500" instead.  */
static table const time_zone_table[] =
{
  { "WET",      tZONE,     HOUR ( 0) }, /* Western European */
  { "WEST",     tDAYZONE,  HOUR ( 0) }, /* Western European Summer */
  { "BST",      tDAYZONE,  HOUR ( 0) }, /* British Summer */
  { "ART",      tZONE,    -HOUR ( 3) }, /* Argentina */
  { "BRT",      tZONE,    -HOUR ( 3) }, /* Brazil */
  { "BRST",     tDAYZONE, -HOUR ( 3) }, /* Brazil Summer */
  { "NST",      tZONE,   -(HOUR ( 3) + 30) },   /* Newfoundland Standard */
  { "NDT",      tDAYZONE,-(HOUR ( 3) + 30) },   /* Newfoundland Daylight */
  { "AST",      tZONE,    -HOUR ( 4) }, /* Atlantic Standard */
  { "ADT",      tDAYZONE, -HOUR ( 4) }, /* Atlantic Daylight */
  { "CLT",      tZONE,    -HOUR ( 4) }, /* Chile */
  { "CLST",     tDAYZONE, -HOUR ( 4) }, /* Chile Summer */
  { "EST",      tZONE,    -HOUR ( 5) }, /* Eastern Standard */
  { "EDT",      tDAYZONE, -HOUR ( 5) }, /* Eastern Daylight */
  { "CST",      tZONE,    -HOUR ( 6) }, /* Central Standard */
  { "CDT",      tDAYZONE, -HOUR ( 6) }, /* Central Daylight */
  { "MST",      tZONE,    -HOUR ( 7) }, /* Mountain Standard */
  { "MDT",      tDAYZONE, -HOUR ( 7) }, /* Mountain Daylight */
  { "PST",      tZONE,    -HOUR ( 8) }, /* Pacific Standard */
  { "PDT",      tDAYZONE, -HOUR ( 8) }, /* Pacific Daylight */
  { "AKST",     tZONE,    -HOUR ( 9) }, /* Alaska Standard */
  { "AKDT",     tDAYZONE, -HOUR ( 9) }, /* Alaska Daylight */
  { "HST",      tZONE,    -HOUR (10) }, /* Hawaii Standard */
  { "HAST",     tZONE,    -HOUR (10) }, /* Hawaii-Aleutian Standard */
  { "HADT",     tDAYZONE, -HOUR (10) }, /* Hawaii-Aleutian Daylight */
  { "SST",      tZONE,    -HOUR (12) }, /* Samoa Standard */
  { "WAT",      tZONE,     HOUR ( 1) }, /* West Africa */
  { "CET",      tZONE,     HOUR ( 1) }, /* Central European */
  { "CEST",     tDAYZONE,  HOUR ( 1) }, /* Central European Summer */
  { "MET",      tZONE,     HOUR ( 1) }, /* Middle European */
  { "MEZ",      tZONE,     HOUR ( 1) }, /* Middle European */
  { "MEST",     tDAYZONE,  HOUR ( 1) }, /* Middle European Summer */
  { "MESZ",     tDAYZONE,  HOUR ( 1) }, /* Middle European Summer */
  { "EET",      tZONE,     HOUR ( 2) }, /* Eastern European */
  { "EEST",     tDAYZONE,  HOUR ( 2) }, /* Eastern European Summer */
  { "CAT",      tZONE,     HOUR ( 2) }, /* Central Africa */
  { "SAST",     tZONE,     HOUR ( 2) }, /* South Africa Standard */
  { "EAT",      tZONE,     HOUR ( 3) }, /* East Africa */
  { "MSK",      tZONE,     HOUR ( 3) }, /* Moscow */
  { "MSD",      tDAYZONE,  HOUR ( 3) }, /* Moscow Daylight */
  { "IST",      tZONE,    (HOUR ( 5) + 30) },   /* India Standard */
  { "SGT",      tZONE,     HOUR ( 8) }, /* Singapore */
  { "KST",      tZONE,     HOUR ( 9) }, /* Korea Standard */
  { "JST",      tZONE,     HOUR ( 9) }, /* Japan Standard */
  { "GST",      tZONE,     HOUR (10) }, /* Guam Standard */
  { "NZST",     tZONE,     HOUR (12) }, /* New Zealand Standard */
  { "NZDT",     tDAYZONE,  HOUR (12) }, /* New Zealand Daylight */
  { NULL, 0, 0 }
};

/* Military time zone table.

   Note 'T' is a special case, as it is used as the separator in ISO
   8601 date and time of day representation. */
static table const military_table[] =
{
  { "A", tZONE, -HOUR ( 1) },
  { "B", tZONE, -HOUR ( 2) },
  { "C", tZONE, -HOUR ( 3) },
  { "D", tZONE, -HOUR ( 4) },
  { "E", tZONE, -HOUR ( 5) },
  { "F", tZONE, -HOUR ( 6) },
  { "G", tZONE, -HOUR ( 7) },
  { "H", tZONE, -HOUR ( 8) },
  { "I", tZONE, -HOUR ( 9) },
  { "K", tZONE, -HOUR (10) },
  { "L", tZONE, -HOUR (11) },
  { "M", tZONE, -HOUR (12) },
  { "N", tZONE,  HOUR ( 1) },
  { "O", tZONE,  HOUR ( 2) },
  { "P", tZONE,  HOUR ( 3) },
  { "Q", tZONE,  HOUR ( 4) },
  { "R", tZONE,  HOUR ( 5) },
  { "S", tZONE,  HOUR ( 6) },
  { "T", 'T',    0 },
  { "U", tZONE,  HOUR ( 8) },
  { "V", tZONE,  HOUR ( 9) },
  { "W", tZONE,  HOUR (10) },
  { "X", tZONE,  HOUR (11) },
  { "Y", tZONE,  HOUR (12) },
  { "Z", tZONE,  HOUR ( 0) },
  { NULL, 0, 0 }
};



/* Convert a time zone expressed as HH:MM into an integer count of
   minutes.  If MM is negative, then S is of the form HHMM and needs
   to be picked apart; otherwise, S is of the form HH.  As specified in
   http://www.opengroup.org/susv3xbd/xbd_chap08.html#tag_08_03, allow
   only valid TZ range, and consider first two digits as hours, if no
   minutes specified.  */

static long int
time_zone_hhmm (parser_control *pc, textint s, long int mm)
{
  long int n_minutes;

  /* If the length of S is 1 or 2 and no minutes are specified,
     interpret it as a number of hours.  */
  if (s.digits <= 2 && mm < 0)
    s.value *= 100;

  if (mm < 0)
    n_minutes = (s.value / 100) * 60 + s.value % 100;
  else
    n_minutes = s.value * 60 + (s.negative ? -mm : mm);

  /* If the absolute number of minutes is larger than 24 hours,
     arrange to reject it by incrementing pc->zones_seen.  Thus,
     we allow only values in the range UTC-24:00 to UTC+24:00.  */
  if (24 * 60 < labs (n_minutes))
    pc->zones_seen++;

  return n_minutes;
}

static int
to_hour (long int hours, int meridian)
{
  switch (meridian)
    {
    default: /* Pacify GCC.  */
    case MER24:
      return 0 <= hours && hours < 24 ? hours : -1;
    case MERam:
      return 0 < hours && hours < 12 ? hours : hours == 12 ? 0 : -1;
    case MERpm:
      return 0 < hours && hours < 12 ? hours + 12 : hours == 12 ? 12 : -1;
    }
}

static long int
to_year (textint textyear)
{
  long int year = textyear.value;

  if (year < 0)
    year = -year;

  /* XPG4 suggests that years 00-68 map to 2000-2068, and
     years 69-99 map to 1969-1999.  */
  else if (textyear.digits == 2)
    year += year < 69 ? 2000 : 1900;

  return year;
}

static table const *
lookup_zone (parser_control const *pc, char const *name)
{
  table const *tp;

  for (tp = universal_time_zone_table; tp->name; tp++)
    if (strcmp (name, tp->name) == 0)
      return tp;

  /* Try local zone abbreviations before those in time_zone_table, as
     the local ones are more likely to be right.  */
  for (tp = pc->local_time_zone_table; tp->name; tp++)
    if (strcmp (name, tp->name) == 0)
      return tp;

  for (tp = time_zone_table; tp->name; tp++)
    if (strcmp (name, tp->name) == 0)
      return tp;

  return NULL;
}

// #if ! HAVE_TM_GMTOFF
#if 1 // Always true for us
/* Yield the difference between *A and *B,
   measured in seconds, ignoring leap seconds.
   The body of this function is taken directly from the GNU C Library;
   see src/strftime.c.  */
static long int
tm_diff (struct tm const *a, struct tm const *b)
{
  /* Compute intervening leap days correctly even if year is negative.
     Take care to avoid int overflow in leap day calculations.  */
  int a4 = SHR (a->tm_year, 2) + SHR (TM_YEAR_BASE, 2) - ! (a->tm_year & 3);
  int b4 = SHR (b->tm_year, 2) + SHR (TM_YEAR_BASE, 2) - ! (b->tm_year & 3);
  int a100 = a4 / 25 - (a4 % 25 < 0);
  int b100 = b4 / 25 - (b4 % 25 < 0);
  int a400 = SHR (a100, 2);
  int b400 = SHR (b100, 2);
  int intervening_leap_days = (a4 - b4) - (a100 - b100) + (a400 - b400);
  long int ayear = a->tm_year;
  long int years = ayear - b->tm_year;
  long int days = (365 * years + intervening_leap_days
                   + (a->tm_yday - b->tm_yday));
  return (60 * (60 * (24 * days + (a->tm_hour - b->tm_hour))
                + (a->tm_min - b->tm_min))
          + (a->tm_sec - b->tm_sec));
}
#endif /* ! HAVE_TM_GMTOFF */

static table const *
lookup_word (parser_control const *pc, char *word)
{
  char *p;
  char *q;
  size_t wordlen;
  table const *tp;
  bool period_found;
  bool abbrev;

  /* Make it uppercase.  */
  for (p = word; *p; p++)
    {
      unsigned char ch = *p;
      *p = toupper (ch);
    }

  for (tp = meridian_table; tp->name; tp++)
    if (strcmp (word, tp->name) == 0)
      return tp;

  /* See if we have an abbreviation for a month. */
  wordlen = strlen (word);
  abbrev = wordlen == 3 || (wordlen == 4 && word[3] == '.');

  for (tp = month_and_day_table; tp->name; tp++)
    if ((abbrev ? strncmp (word, tp->name, 3) : strcmp (word, tp->name)) == 0)
      return tp;

  if ((tp = lookup_zone (pc, word)))
    return tp;

  if (strcmp (word, dst_table[0].name) == 0)
    return dst_table;

  for (tp = time_units_table; tp->name; tp++)
    if (strcmp (word, tp->name) == 0)
      return tp;

  /* Strip off any plural and try the units table again. */
  if (word[wordlen - 1] == 'S')
    {
      word[wordlen - 1] = '\0';
      for (tp = time_units_table; tp->name; tp++)
        if (strcmp (word, tp->name) == 0)
          return tp;
      word[wordlen - 1] = 'S';  /* For "this" in relative_time_table.  */
    }

  for (tp = relative_time_table; tp->name; tp++)
    if (strcmp (word, tp->name) == 0)
      return tp;

  /* Military time zones. */
  if (wordlen == 1)
    for (tp = military_table; tp->name; tp++)
      if (word[0] == tp->name[0])
        return tp;

  /* Drop out any periods and try the time zone table again. */
  for (period_found = false, p = q = word; (*p = *q); q++)
    if (*q == '.')
      period_found = true;
    else
      p++;
  if (period_found && (tp = lookup_zone (pc, word)))
    return tp;

  return NULL;
}

static int
yylex (union YYSTYPE *lvalp, parser_control *pc)
{
  unsigned char c;
  size_t count;

  for (;;)
    {
      while (c = *pc->input, isspace (c))
        pc->input++;

      if (ISDIGIT (c) || c == '-' || c == '+')
        {
          char const *p;
          int sign;
          unsigned long int value;
          if (c == '-' || c == '+')
            {
              sign = c == '-' ? -1 : 1;
              while (c = *++pc->input, isspace (c))
                continue;
              if (! ISDIGIT (c))
                /* skip the '-' sign */
                continue;
            }
          else
            sign = 0;
          p = pc->input;
          for (value = 0; ; value *= 10)
            {
              unsigned long int value1 = value + (c - '0');
              if (value1 < value)
                return '?';
              value = value1;
              c = *++p;
              if (! ISDIGIT (c))
                break;
              if (ULONG_MAX / 10 < value)
                return '?';
            }
          if ((c == '.' || c == ',') && ISDIGIT (p[1]))
            {
              time_t s;
              int ns;
              int digits;
              unsigned long int value1;

              /* Check for overflow when converting value to time_t.  */
              if (sign < 0)
                {
                  s = - value;
                  if (0 < s)
                    return '?';
                  value1 = -s;
                }
              else
                {
                  s = value;
                  if (s < 0)
                    return '?';
                  value1 = s;
                }
              if (value != value1)
                return '?';

              /* Accumulate fraction, to ns precision.  */
              p++;
              ns = *p++ - '0';
              for (digits = 2; digits <= LOG10_BILLION; digits++)
                {
                  ns *= 10;
                  if (ISDIGIT (*p))
                    ns += *p++ - '0';
                }

              /* Skip excess digits, truncating toward -Infinity.  */
              if (sign < 0)
                for (; ISDIGIT (*p); p++)
                  if (*p != '0')
                    {
                      ns++;
                      break;
                    }
              while (ISDIGIT (*p))
                p++;

              /* Adjust to the timespec convention, which is that
                 tv_nsec is always a positive offset even if tv_sec is
                 negative.  */
              if (sign < 0 && ns)
                {
                  s--;
                  if (! (s < 0))
                    return '?';
                  ns = BILLION - ns;
                }

              lvalp->timespec.tv_sec = s;
              lvalp->timespec.tv_nsec = ns;
              pc->input = p;
              return sign ? tSDECIMAL_NUMBER : tUDECIMAL_NUMBER;
            }
          else
            {
              lvalp->textintval.negative = sign < 0;
              if (sign < 0)
                {
                  lvalp->textintval.value = - value;
                  if (0 < lvalp->textintval.value)
                    return '?';
                }
              else
                {
                  lvalp->textintval.value = value;
                  if (lvalp->textintval.value < 0)
                    return '?';
                }
              lvalp->textintval.digits = p - pc->input;
              pc->input = p;
              return sign ? tSNUMBER : tUNUMBER;
            }
        }

      if (isalpha (c))
        {
          char buff[20];
          char *p = buff;
          table const *tp;

          do
            {
              if (p < buff + sizeof buff - 1)
                *p++ = c;
              c = *++pc->input;
            }
          while (isalpha (c) || c == '.');

          *p = '\0';
          tp = lookup_word (pc, buff);
          if (! tp)
            return '?';
          lvalp->intval = tp->value;
          return tp->type;
        }

      if (c != '(')
        return to_uchar (*pc->input++);

      count = 0;
      do
        {
          c = *pc->input++;
          if (c == '\0')
            return c;
          if (c == '(')
            count++;
          else if (c == ')')
            count--;
        }
      while (count != 0);
    }
}

/* Do nothing if the parser reports an error.  */
static int
yyerror (parser_control const *pc,
         char const *s)
{
  return 0;
}

/* If *TM0 is the old and *TM1 is the new value of a struct tm after
   passing it to mktime, return true if it's OK that mktime returned T.
   It's not OK if *TM0 has out-of-range members.  */

static bool
mktime_ok (struct tm const *tm0, struct tm const *tm1, time_t t)
{
  if (t == (time_t) -1)
    {
      /* Guard against falsely reporting an error when parsing a time
         stamp that happens to equal (time_t) -1, on a host that
         supports such a time stamp.  */
      tm1 = localtime (&t);
      if (!tm1)
        return false;
    }

  return ! ((tm0->tm_sec ^ tm1->tm_sec)
            | (tm0->tm_min ^ tm1->tm_min)
            | (tm0->tm_hour ^ tm1->tm_hour)
            | (tm0->tm_mday ^ tm1->tm_mday)
            | (tm0->tm_mon ^ tm1->tm_mon)
            | (tm0->tm_year ^ tm1->tm_year));
}

/* A reasonable upper bound for the size of ordinary TZ strings.
   Use heap allocation if TZ's length exceeds this.  */
enum { TZBUFSIZE = 100 };

/* Return a copy of TZ, stored in TZBUF if it fits, and heap-allocated
   otherwise.  */
static char *
get_tz (char tzbuf[TZBUFSIZE])
{
  char *tz = getenv ("TZ");
  if (tz)
    {
      size_t tzsize = strlen (tz) + 1;
      tz = (tzsize <= TZBUFSIZE
            ? memcpy (tzbuf, tz, tzsize)
            : xmemdup (tz, tzsize));
    }
  return tz;
}

/* Parse a date/time string, storing the resulting time value into *RESULT.
   The string itself is pointed to by P.  Return true if successful.
   P can be an incomplete or relative time specification; if so, use
   *NOW as the basis for the returned time.  */
bool
parse_datetime (struct timespec *result, char const *p,
                struct timespec const *now)
{
  time_t Start;
  long int Start_ns;
  struct tm const *tmp;
  struct tm tm = { 0, };
  struct tm tm0 = { 0, };
  parser_control pc;
  struct timespec gettime_buffer;
  unsigned char c;
  bool tz_was_altered = false;
  char *tz0 = NULL;
  char tz0buf[TZBUFSIZE];
  bool ok = true;

  if (! now)
    {
      gettime (&gettime_buffer);
      now = &gettime_buffer;
    }

  Start = now->tv_sec;
  Start_ns = now->tv_nsec;

  tmp = localtime (&now->tv_sec);
  if (! tmp)
    return false;

  while (c = *p, isspace (c))
    p++;

  if (strncmp (p, "TZ=\"", 4) == 0)
    {
      char const *tzbase = p + 4;
      size_t tzsize = 1;
      char const *s;

      for (s = tzbase; *s; s++, tzsize++)
        if (*s == '\\')
          {
            s++;
            if (! (*s == '\\' || *s == '"'))
              break;
          }
        else if (*s == '"')
          {
            char *z;
            char *tz1;
            char tz1buf[TZBUFSIZE];
            bool large_tz = TZBUFSIZE < tzsize;
            bool setenv_ok;
            tz0 = get_tz (tz0buf);
            z = tz1 = large_tz ? g_malloc (tzsize) : tz1buf;
            for (s = tzbase; *s != '"'; s++)
              *z++ = *(s += *s == '\\');
            *z = '\0';
            setenv_ok = setenv ("TZ", tz1, 1) == 0;
            if (large_tz)
              free (tz1);
            if (!setenv_ok)
              goto fail;
            tz_was_altered = true;

            p = s + 1;
            while (c = *p, isspace (c))
              p++;

            break;
          }
    }

  /* As documented, be careful to treat the empty string just like
     a date string of "0".  Without this, an empty string would be
     declared invalid when parsed during a DST transition.  */
  if (*p == '\0')
    p = "0";

  pc.input = p;
  pc.year.value = tmp->tm_year;
  pc.year.value += TM_YEAR_BASE;
  pc.year.digits = 0;
  pc.month = tmp->tm_mon + 1;
  pc.day = tmp->tm_mday;
  pc.hour = tmp->tm_hour;
  pc.minutes = tmp->tm_min;
  pc.seconds.tv_sec = tmp->tm_sec;
  pc.seconds.tv_nsec = Start_ns;
  tm.tm_isdst = tmp->tm_isdst;

  pc.meridian = MER24;
  pc.rel = RELATIVE_TIME_0;
  pc.timespec_seen = false;
  pc.rels_seen = false;
  pc.dates_seen = 0;
  pc.days_seen = 0;
  pc.times_seen = 0;
  pc.local_zones_seen = 0;
  pc.dsts_seen = 0;
  pc.zones_seen = 0;

#if HAVE_STRUCT_TM_TM_ZONE
  pc.local_time_zone_table[0].name = tmp->tm_zone;
  pc.local_time_zone_table[0].type = tLOCAL_ZONE;
  pc.local_time_zone_table[0].value = tmp->tm_isdst;
  pc.local_time_zone_table[1].name = NULL;

  /* Probe the names used in the next three calendar quarters, looking
     for a tm_isdst different from the one we already have.  */
  {
    int quarter;
    for (quarter = 1; quarter <= 3; quarter++)
      {
        time_t probe = Start + quarter * (90 * 24 * 60 * 60);
        struct tm const *probe_tm = localtime (&probe);
        if (probe_tm && probe_tm->tm_zone
            && probe_tm->tm_isdst != pc.local_time_zone_table[0].value)
          {
              {
                pc.local_time_zone_table[1].name = probe_tm->tm_zone;
                pc.local_time_zone_table[1].type = tLOCAL_ZONE;
                pc.local_time_zone_table[1].value = probe_tm->tm_isdst;
                pc.local_time_zone_table[2].name = NULL;
              }
            break;
          }
      }
  }
#else
#if HAVE_TZNAME
  {
# if !HAVE_DECL_TZNAME
    extern char *tzname[];
# endif
    int i;
    for (i = 0; i < 2; i++)
      {
        pc.local_time_zone_table[i].name = tzname[i];
        pc.local_time_zone_table[i].type = tLOCAL_ZONE;
        pc.local_time_zone_table[i].value = i;
      }
    pc.local_time_zone_table[i].name = NULL;
  }
#else
  pc.local_time_zone_table[0].name = NULL;
#endif
#endif

  if (pc.local_time_zone_table[0].name && pc.local_time_zone_table[1].name
      && ! strcmp (pc.local_time_zone_table[0].name,
                   pc.local_time_zone_table[1].name))
    {
      /* This locale uses the same abbreviation for standard and
         daylight times.  So if we see that abbreviation, we don't
         know whether it's daylight time.  */
      pc.local_time_zone_table[0].value = -1;
      pc.local_time_zone_table[1].name = NULL;
    }

  if (yyparse (&pc) != 0)
    goto fail;

  if (pc.timespec_seen)
    *result = pc.seconds;
  else
    {
      if (1 < (pc.times_seen | pc.dates_seen | pc.days_seen | pc.dsts_seen
               | (pc.local_zones_seen + pc.zones_seen)))
        goto fail;

      tm.tm_year = to_year (pc.year) - TM_YEAR_BASE;
      tm.tm_mon = pc.month - 1;
      tm.tm_mday = pc.day;
      if (pc.times_seen || (pc.rels_seen && ! pc.dates_seen && ! pc.days_seen))
        {
          tm.tm_hour = to_hour (pc.hour, pc.meridian);
          if (tm.tm_hour < 0)
            goto fail;
          tm.tm_min = pc.minutes;
          tm.tm_sec = pc.seconds.tv_sec;
        }
      else
        {
          tm.tm_hour = tm.tm_min = tm.tm_sec = 0;
          pc.seconds.tv_nsec = 0;
        }

      /* Let mktime deduce tm_isdst if we have an absolute time stamp.  */
      if (pc.dates_seen | pc.days_seen | pc.times_seen)
        tm.tm_isdst = -1;

      /* But if the input explicitly specifies local time with or without
         DST, give mktime that information.  */
      if (pc.local_zones_seen)
        tm.tm_isdst = pc.local_isdst;

      tm0 = tm;

      Start = mktime (&tm);

      if (! mktime_ok (&tm0, &tm, Start))
        {
          if (! pc.zones_seen)
            goto fail;
          else
            {
              /* Guard against falsely reporting errors near the time_t
                 boundaries when parsing times in other time zones.  For
                 example, suppose the input string "1969-12-31 23:00:00 -0100",
                 the current time zone is 8 hours ahead of UTC, and the min
                 time_t value is 1970-01-01 00:00:00 UTC.  Then the min
                 localtime value is 1970-01-01 08:00:00, and mktime will
                 therefore fail on 1969-12-31 23:00:00.  To work around the
                 problem, set the time zone to 1 hour behind UTC temporarily
                 by setting TZ="XXX1:00" and try mktime again.  */

              long int time_zone = pc.time_zone;
              long int abs_time_zone = time_zone < 0 ? - time_zone : time_zone;
              long int abs_time_zone_hour = abs_time_zone / 60;
              int abs_time_zone_min = abs_time_zone % 60;
              char tz1buf[sizeof "XXX+0:00"
                          + sizeof pc.time_zone * CHAR_BIT / 3];
              if (!tz_was_altered)
                tz0 = get_tz (tz0buf);
              sprintf (tz1buf, "XXX%s%ld:%02d", &"-"[time_zone < 0],
                       abs_time_zone_hour, abs_time_zone_min);
              if (setenv ("TZ", tz1buf, 1) != 0)
                goto fail;
              tz_was_altered = true;
              tm = tm0;
              Start = mktime (&tm);
              if (! mktime_ok (&tm0, &tm, Start))
                goto fail;
            }
        }

      if (pc.days_seen && ! pc.dates_seen)
        {
          tm.tm_mday += ((pc.day_number - tm.tm_wday + 7) % 7
                         + 7 * (pc.day_ordinal
                                - (0 < pc.day_ordinal
                                   && tm.tm_wday != pc.day_number)));
          tm.tm_isdst = -1;
          Start = mktime (&tm);
          if (Start == (time_t) -1)
            goto fail;
        }

      /* Add relative date.  */
      if (pc.rel.year | pc.rel.month | pc.rel.day)
        {
          int year = tm.tm_year + pc.rel.year;
          int month = tm.tm_mon + pc.rel.month;
          int day = tm.tm_mday + pc.rel.day;
          if (((year < tm.tm_year) ^ (pc.rel.year < 0))
              | ((month < tm.tm_mon) ^ (pc.rel.month < 0))
              | ((day < tm.tm_mday) ^ (pc.rel.day < 0)))
            goto fail;
          tm.tm_year = year;
          tm.tm_mon = month;
          tm.tm_mday = day;
          tm.tm_hour = tm0.tm_hour;
          tm.tm_min = tm0.tm_min;
          tm.tm_sec = tm0.tm_sec;
          tm.tm_isdst = tm0.tm_isdst;
          Start = mktime (&tm);
          if (Start == (time_t) -1)
            goto fail;
        }

      /* The only "output" of this if-block is an updated Start value,
         so this block must follow others that clobber Start.  */
      if (pc.zones_seen)
        {
          long int delta = pc.time_zone * 60;
          time_t t1;
#ifdef HAVE_TM_GMTOFF
          delta -= tm.tm_gmtoff;
#else
          time_t t = Start;
          struct tm const *gmt = gmtime (&t);
          if (! gmt)
            goto fail;
          delta -= tm_diff (&tm, gmt);
#endif
          t1 = Start - delta;
          if ((Start < t1) != (delta < 0))
            goto fail;  /* time_t overflow */
          Start = t1;
        }

      /* Add relative hours, minutes, and seconds.  On hosts that support
         leap seconds, ignore the possibility of leap seconds; e.g.,
         "+ 10 minutes" adds 600 seconds, even if one of them is a
         leap second.  Typically this is not what the user wants, but it's
         too hard to do it the other way, because the time zone indicator
         must be applied before relative times, and if mktime is applied
         again the time zone will be lost.  */
      {
        long int sum_ns = pc.seconds.tv_nsec + pc.rel.ns;
        long int normalized_ns = (sum_ns % BILLION + BILLION) % BILLION;
        time_t t0 = Start;
        long int d1 = 60 * 60 * pc.rel.hour;
        time_t t1 = t0 + d1;
        long int d2 = 60 * pc.rel.minutes;
        time_t t2 = t1 + d2;
        intmax_t d3 = pc.rel.seconds;
        intmax_t t3 = t2 + d3;
        long int d4 = (sum_ns - normalized_ns) / BILLION;
        intmax_t t4 = t3 + d4;
        time_t t5 = t4;

        if ((d1 / (60 * 60) ^ pc.rel.hour)
            | (d2 / 60 ^ pc.rel.minutes)
            | ((t1 < t0) ^ (d1 < 0))
            | ((t2 < t1) ^ (d2 < 0))
            | ((t3 < t2) ^ (d3 < 0))
            | ((t4 < t3) ^ (d4 < 0))
            | (t5 != t4))
          goto fail;

        result->tv_sec = t5;
        result->tv_nsec = normalized_ns;
      }
    }

  goto done;

 fail:
  ok = false;
 done:
  if (tz_was_altered)
    ok &= (tz0 ? setenv ("TZ", tz0, 1) : unsetenv ("TZ")) == 0;
  if (tz0 != tz0buf)
    free (tz0);
  return ok;
}

===== ./app/flatpak-builtins-enter.c =====
/* vi:set et sw=2 sts=2 cin cino=t0,f0,(0,{s,>2s,n-s,^-s,e-s:
 * Copyright © 2014 Red Hat, Inc
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Alexander Larsson <alexl@redhat.com>
 */

#include "config.h"

#include <locale.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>

#include <glib/gi18n.h>

#include "libglnx.h"

#include "flatpak-builtins.h"
#include "flatpak-utils-private.h"
#include "flatpak-dbus-generated.h"
#include "flatpak-run-private.h"
#include "flatpak-instance.h"
#include <sys/capability.h>

static GOptionEntry options[] = {
  { NULL }
};

static void
drop_all_caps (void)
{
  struct __user_cap_header_struct hdr = { _LINUX_CAPABILITY_VERSION_3, 0 };
  struct __user_cap_data_struct data[2] = { { 0 } };

  capset (&hdr, data);
}

gboolean
flatpak_builtin_enter (int           argc,
                       char        **argv,
                       GCancellable *cancellable,
                       GError      **error)
{
  g_autoptr(GOptionContext) context = NULL;
  int rest_argv_start, rest_argc;
  const char *ns_name[] = { "user_base", "ipc", "net", "pid", "mnt", "user" };
  int ns_fd[G_N_ELEMENTS (ns_name)];
  ino_t user_base_ino = 0;
  char *pid_s;
  int pid, i;
  g_autofree char *environment_path = NULL;
  g_autoptr(GPtrArray) argv_array = NULL;
  g_autoptr(GPtrArray) envp_array = NULL;
  g_autofree char *environment = NULL;
  gsize environment_len;
  char *e;
  g_autofree char *pulse_path = NULL;
  g_autofree char *session_bus_path = NULL;
  g_autofree char *xdg_runtime_dir = NULL;
  g_autofree char *stat_path = NULL;
  g_autofree char *root_path = NULL;
  g_autofree char *root_link = NULL;
  g_autofree char *cwd_path = NULL;
  g_autofree char *cwd_link = NULL;
  int status;
  struct stat stat_buf;
  uid_t uid;
  gid_t gid;
  g_autoptr(GPtrArray) instances = NULL;
  int j;

  context = g_option_context_new (_("INSTANCE COMMAND [ARGUMENT…] - Run a command inside a running sandbox"));
  g_option_context_set_translation_domain (context, GETTEXT_PACKAGE);

  rest_argc = 0;
  rest_argv_start = 0;

  for (i = 1; i < argc; i++)
    {
      /* The non-option is the command, take it out of the arguments */
      if (argv[i][0] != '-')
        {
          rest_argv_start = i;
          rest_argc = argc - i;
          argc = i;
          break;
        }
    }

  if (!flatpak_option_context_parse (context, options, &argc, &argv, FLATPAK_BUILTIN_FLAG_NO_DIR, NULL, cancellable, error))
    return FALSE;

  if (rest_argc < 2)
    {
      usage_error (context, _("INSTANCE and COMMAND must be specified"), error);
      return FALSE;
    }

  /* If this wasn't true, rest_argc would still be 0 */
  g_assert (rest_argv_start >= 1);

  pid_s = argv[rest_argv_start];
  pid = atoi (pid_s);

  /* Check to see if it matches some running instance, otherwise use
     as pid if it looks as a number. */
  instances = flatpak_instance_get_all ();
  for (j = 0; j < instances->len; j++)
    {
      FlatpakInstance *instance = (FlatpakInstance *) g_ptr_array_index (instances, j);

      if (pid == flatpak_instance_get_pid (instance) ||
          g_strcmp0 (pid_s, flatpak_instance_get_app (instance)) == 0 ||
          strcmp (pid_s, flatpak_instance_get_id (instance)) == 0)
        {
          pid = flatpak_instance_get_child_pid (instance);
          break;
        }
    }

  if (pid <= 0)
    return flatpak_fail (error, _("%s is neither a pid nor an application or instance ID"), pid_s);

  stat_path = g_strdup_printf ("/proc/%d/root", pid);
  if (stat (stat_path, &stat_buf))
    {
      if (errno == EACCES)
        return flatpak_fail (error, _("entering not supported (need unprivileged user namespaces, or sudo -E)"));
      return flatpak_fail (error, _("No such pid %s"), pid_s);
    }

  uid = stat_buf.st_uid;
  gid = stat_buf.st_gid;

  environment_path = g_strdup_printf ("/proc/%d/environ", pid);
  if (!g_file_get_contents (environment_path, &environment, &environment_len, error))
    return FALSE;

  cwd_path = g_strdup_printf ("/proc/%d/cwd", pid);
  cwd_link = glnx_readlinkat_malloc (-1, cwd_path, NULL, error);
  if (cwd_link == NULL)
    return glnx_prefix_error (error, _("Can't read cwd"));

  root_path = g_strdup_printf ("/proc/%d/root", pid);
  root_link = glnx_readlinkat_malloc (-1, root_path, NULL, error);
  if (root_link == NULL)
    return glnx_prefix_error (error, _("Can't read root"));

  for (i = 0; i < G_N_ELEMENTS (ns_name); i++)
    {
      g_autofree char *path = NULL;
      g_autofree char *self_path = NULL;
      struct stat path_stat, self_path_stat;

      if (strcmp (ns_name[i], "user_base") == 0)
        {
          /* We could use the NS_GET_USERNS ioctl instead of the .userns bind hack, but that would require >= 4.9 kernel */
          path = g_strdup_printf ("%s/run/.userns", root_path);
          self_path = g_strdup ("/proc/self/ns/user");
        }
      else
        {
          path = g_strdup_printf ("/proc/%d/ns/%s", pid, ns_name[i]);
          self_path = g_strdup_printf ("/proc/self/ns/%s", ns_name[i]);
        }

      if (stat (path, &path_stat) != 0)
        {
          if (errno == ENOENT)
            {
              /* If for whatever reason the namespace doesn't exist, skip it */
              ns_fd[i] = -1;
              continue;
            }
          return glnx_prefix_error (error, _("Invalid %s namespace for pid %d"), ns_name[i], pid);
        }

      if (strcmp (ns_name[i], "user") == 0 && path_stat.st_ino == user_base_ino)
        {
          /* bubblewrap did not create an intermediate user namespace */
          ns_fd[i] = -1;
          continue;
        }

      if (stat (self_path, &self_path_stat) != 0)
        return glnx_prefix_error (error, _("Invalid %s namespace for self"), ns_name[i]);

      if (self_path_stat.st_ino == path_stat.st_ino)
        {
          /* No need to setns to the same namespace, it will only fail */
          ns_fd[i] = -1;
          continue;
        }

      if (strcmp (ns_name[i], "user_base") == 0)
        user_base_ino = path_stat.st_ino;

      ns_fd[i] = open (path, O_RDONLY);
      if (ns_fd[i] == -1)
        return flatpak_fail (error, _("Can't open %s namespace: %s"), ns_name[i], g_strerror (errno));
    }

  for (i = 0; i < G_N_ELEMENTS (ns_fd); i++)
    {
      if (ns_fd[i] != -1)
        {
          if (setns (ns_fd[i], 0) == -1)
            {
              if (errno == EPERM)
                return flatpak_fail (error, _("entering not supported (need unprivileged user namespaces)"));
              return flatpak_fail (error, _("Can't enter %s namespace: %s"), ns_name[i], g_strerror (errno));
            }
          close (ns_fd[i]);
        }
    }

  if (chdir (cwd_link))
    return flatpak_fail (error, _("Can't chdir"));

  if (chroot (root_link))
    return flatpak_fail (error, _("Can't chroot"));

  if (setgid (gid))
    return flatpak_fail (error, _("Can't switch gid"));

  if (setuid (uid))
    return flatpak_fail (error, _("Can't switch uid"));

  drop_all_caps ();

  envp_array = g_ptr_array_new_with_free_func (g_free);
  for (e = environment; e < environment + environment_len; e = e + strlen (e) + 1)
    {
      if (*e != 0 &&
          !g_str_has_prefix (e, "PULSE_SERVER=") &&
          !g_str_has_prefix (e, "PULSE_CLIENTCONFIG=") &&
          !g_str_has_prefix (e, "XDG_RUNTIME_DIR=") &&
          !g_str_has_prefix (e, "DBUS_SYSTEM_BUS_ADDRESS=") &&
          !g_str_has_prefix (e, "DBUS_SESSION_BUS_ADDRESS="))
        {
          if (g_str_has_prefix (e, "_LD_LIBRARY_PATH="))
            e++;
          g_ptr_array_add (envp_array, g_strdup (e));
        }
    }

  xdg_runtime_dir = g_strdup_printf ("/run/user/%d", uid);
  g_ptr_array_add (envp_array, g_strdup_printf ("XDG_RUNTIME_DIR=%s", xdg_runtime_dir));

  pulse_path = g_strdup_printf ("/run/user/%d/pulse/native", uid);
  if (g_file_test (pulse_path, G_FILE_TEST_EXISTS))
    {
      g_ptr_array_add (envp_array, g_strdup_printf ("PULSE_SERVER=unix:%s", pulse_path));
      g_ptr_array_add (envp_array, g_strdup_printf ("PULSE_CLIENTCONFIG=/run/user/%d/pulse/config", uid));
    }

  session_bus_path = g_strdup_printf ("/run/user/%d/bus", uid);
  if (g_file_test (session_bus_path, G_FILE_TEST_EXISTS))
    g_ptr_array_add (envp_array, g_strdup_printf ("DBUS_SESSION_BUS_ADDRESS=unix:path=%s", session_bus_path));

  if (g_file_test ("/run/dbus/system_bus_socket", G_FILE_TEST_EXISTS))
    g_ptr_array_add (envp_array, g_strdup ("DBUS_SYSTEM_BUS_ADDRESS=unix:path=/run/dbus/system_bus_socket"));

  if (getenv ("TERM"))
    g_ptr_array_add (envp_array, g_strdup_printf ("TERM=%s", getenv ("TERM")));

  g_ptr_array_add (envp_array, NULL);

  argv_array = g_ptr_array_new_with_free_func (g_free);
  for (i = 1; i < rest_argc; i++)
    g_ptr_array_add (argv_array, g_strdup (argv[rest_argv_start + i]));
  g_ptr_array_add (argv_array, NULL);

  signal (SIGINT, SIG_IGN);
  if (!g_spawn_sync (NULL, (char **) argv_array->pdata, (char **) envp_array->pdata,
                     G_SPAWN_SEARCH_PATH_FROM_ENVP | G_SPAWN_CHILD_INHERITS_STDIN,
                     NULL, NULL,
                     NULL, NULL,
                     &status, error))
    return FALSE;

  exit (status);
}

gboolean
flatpak_complete_enter (FlatpakCompletion *completion)
{
  g_autoptr(GOptionContext) context = NULL;
  g_autoptr(GPtrArray) instances = NULL;
  int i;

  context = g_option_context_new ("");
  if (!flatpak_option_context_parse (context, options, &completion->argc, &completion->argv, FLATPAK_BUILTIN_FLAG_NO_DIR, NULL, NULL, NULL))
    return FALSE;

  switch (completion->argc)
    {
    case 0:
    case 1:
      flatpak_complete_options (completion, global_entries);
      flatpak_complete_options (completion, options);

      instances = flatpak_instance_get_all ();
      for (i = 0; i < instances->len; i++)
        {
          FlatpakInstance *instance = (FlatpakInstance *) g_ptr_array_index (instances, i);

          const char *app_name = flatpak_instance_get_app (instance);
          if (app_name)
            flatpak_complete_word (completion, "%s ", app_name);

          flatpak_complete_word (completion, "%s ", flatpak_instance_get_id (instance));
        }
      break;

    default:
      break;
    }

  return TRUE;
}

===== ./app/flatpak-builtins-uninstall.c =====
/* vi:set et sw=2 sts=2 cin cino=t0,f0,(0,{s,>2s,n-s,^-s,e-s:
 * Copyright © 2014 Red Hat, Inc
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Alexander Larsson <alexl@redhat.com>
 */

#include "config.h"

#include <locale.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

#include <glib/gi18n.h>

#include "libglnx.h"

#include "flatpak-builtins.h"
#include "flatpak-builtins-utils.h"
#include "flatpak-utils-private.h"
#include "flatpak-cli-transaction.h"
#include "flatpak-quiet-transaction.h"
#include <flatpak-dir-private.h>
#include <flatpak-installation-private.h>
#include "flatpak-error.h"

static char *opt_arch;
static gboolean opt_keep_ref;
static gboolean opt_force_remove;
static gboolean opt_no_related;
static gboolean opt_runtime;
static gboolean opt_app;
static gboolean opt_all;
static gboolean opt_yes;
static gboolean opt_unused;
static gboolean opt_delete_data;
static gboolean opt_noninteractive;

static GOptionEntry options[] = {
  { "arch", 0, 0, G_OPTION_ARG_STRING, &opt_arch, N_("Arch to uninstall"), N_("ARCH") },
  { "keep-ref", 0, 0, G_OPTION_ARG_NONE, &opt_keep_ref, N_("Keep ref in local repository"), NULL },
  { "no-related", 0, 0, G_OPTION_ARG_NONE, &opt_no_related, N_("Don't uninstall related refs"), NULL },
  { "force-remove", 0, 0, G_OPTION_ARG_NONE, &opt_force_remove, N_("Remove files even if running"), NULL },
  { "runtime", 0, 0, G_OPTION_ARG_NONE, &opt_runtime, N_("Look for runtime with the specified name"), NULL },
  { "app", 0, 0, G_OPTION_ARG_NONE, &opt_app, N_("Look for app with the specified name"), NULL },
  { "all", 0, 0, G_OPTION_ARG_NONE, &opt_all, N_("Uninstall all"), NULL },
  { "unused", 0, 0, G_OPTION_ARG_NONE, &opt_unused, N_("Uninstall unused"), NULL },
  { "delete-data", 0, 0, G_OPTION_ARG_NONE, &opt_delete_data, N_("Delete app data"), NULL },
  { "assumeyes", 'y', 0, G_OPTION_ARG_NONE, &opt_yes, N_("Automatically answer yes for all questions"), NULL },
  { "noninteractive", 0, 0, G_OPTION_ARG_NONE, &opt_noninteractive, N_("Produce minimal output and don't ask questions"), NULL },
  { NULL }
};

typedef struct
{
  FlatpakDir *dir;
  GHashTable *refs_hash;
  GHashTable *runtime_app_map;
  GHashTable *extension_app_map;
  GPtrArray  *refs;
} UninstallDir;

static UninstallDir *
uninstall_dir_new (FlatpakDir *dir)
{
  UninstallDir *udir = g_new0 (UninstallDir, 1);

  udir->dir = g_object_ref (dir);
  udir->refs = g_ptr_array_new_with_free_func ((GDestroyNotify)flatpak_decomposed_unref);
  udir->refs_hash = g_hash_table_new_full ((GHashFunc)flatpak_decomposed_hash, (GEqualFunc)flatpak_decomposed_equal, (GDestroyNotify)flatpak_decomposed_unref, NULL);

  return udir;
}

static void
uninstall_dir_free (UninstallDir *udir)
{
  g_object_unref (udir->dir);
  g_hash_table_unref (udir->refs_hash);
  g_clear_pointer (&udir->runtime_app_map, g_hash_table_unref);
  g_clear_pointer (&udir->extension_app_map, g_hash_table_unref);
  g_ptr_array_unref (udir->refs);
  g_free (udir);
}

static void
uninstall_dir_add_ref (UninstallDir *udir,
                       FlatpakDecomposed *ref)
{
  if (g_hash_table_insert (udir->refs_hash, flatpak_decomposed_ref (ref), NULL))
    g_ptr_array_add (udir->refs, flatpak_decomposed_ref (ref));
}

static void
uninstall_dir_remove_ref (UninstallDir *udir,
                          FlatpakDecomposed *ref)
{
  g_hash_table_remove (udir->refs_hash, ref);
  g_ptr_array_remove (udir->refs, ref);
}

static UninstallDir *
uninstall_dir_ensure (GHashTable *uninstall_dirs,
                      FlatpakDir *dir)
{
  UninstallDir *udir;

  udir = g_hash_table_lookup (uninstall_dirs, dir);
  if (udir == NULL)
    {
      udir = uninstall_dir_new (dir);
      g_hash_table_insert (uninstall_dirs, udir->dir, udir);
    }

  return udir;
}

static gboolean
flatpak_delete_data (gboolean    yes_opt,
                     const char *app_id,
                     GError    **error)
{
  g_autofree char *path = g_build_filename (g_get_home_dir (), ".var", "app", app_id, NULL);
  g_autoptr(GFile) file = g_file_new_for_path (path);

  if (!yes_opt &&
      !flatpak_yes_no_prompt (FALSE, _("Delete data for %s?"), app_id))
    return TRUE;

  if (g_file_query_exists (file, NULL))
    {
      if (!flatpak_rm_rf (file, NULL, error))
        return FALSE;
    }

  if (!reset_permissions_for_app (app_id, error))
    return FALSE;

  return TRUE;
}

static gboolean
confirm_runtime_removal (gboolean           yes_opt,
                         UninstallDir      *udir,
                         FlatpakDecomposed *ref)
{
  g_autoptr(GPtrArray) apps = NULL;
  g_autoptr(GError) local_error = NULL;
  g_autofree char *ref_name = NULL;
  const char *ref_branch;
  const char *on = "";
  const char *off = "";
  gboolean is_extension;

  if (flatpak_fancy_output ())
    {
      on = FLATPAK_ANSI_BOLD_ON;
      off = FLATPAK_ANSI_BOLD_OFF;
    }

  is_extension = flatpak_dir_is_runtime_extension (udir->dir, ref);
  if (is_extension)
    {
      apps = flatpak_dir_list_app_refs_with_runtime_extension (udir->dir,
                                                               &udir->runtime_app_map,
                                                               &udir->extension_app_map,
                                                               ref, NULL, &local_error);
      if (apps == NULL)
        g_info ("Unable to list apps using extension %s: %s\n",
                flatpak_decomposed_get_ref (ref), local_error->message);
    }
  else
    {
      apps = flatpak_dir_list_app_refs_with_runtime (udir->dir,
                                                     &udir->runtime_app_map,
                                                     ref, NULL, &local_error);
      if (apps == NULL)
        g_info ("Unable to list apps using runtime %s: %s\n",
                flatpak_decomposed_get_ref (ref), local_error->message);
    }

  if (apps == NULL || apps->len == 0)
    return TRUE;

  /* Exclude any apps that will be removed by the current transaction */
  for (guint i = 0; i < udir->refs->len; i++)
    {
      FlatpakDecomposed *uninstall_ref = g_ptr_array_index (udir->refs, i);
      guint j;

      if (flatpak_decomposed_is_runtime (uninstall_ref))
        continue;

      if (g_ptr_array_find_with_equal_func (apps, uninstall_ref,
                                            (GEqualFunc)flatpak_decomposed_equal, &j))
        g_ptr_array_remove_index_fast (apps, j);
    }

  if (apps->len == 0)
    return TRUE;

  ref_name = flatpak_decomposed_dup_id (ref);
  ref_branch = flatpak_decomposed_get_branch (ref);

  if (is_extension)
    g_print (_("Info: applications using the extension %s%s%s branch %s%s%s:\n"),
             on, ref_name, off, on, ref_branch, off);
  else
    g_print (_("Info: applications using the runtime %s%s%s branch %s%s%s:\n"),
             on, ref_name, off, on, ref_branch, off);

  g_print ("   ");
  for (guint i = 0; i < apps->len; i++)
    {
      FlatpakDecomposed *app_ref = g_ptr_array_index (apps, i);
      g_autofree char *id = flatpak_decomposed_dup_id (app_ref);
      if (i != 0)
        g_print (", ");
      g_print ("%s", id);
    }
  g_print ("\n");

  if (!yes_opt &&
      !flatpak_yes_no_prompt (FALSE, _("Really remove?")))
    return FALSE;

  return TRUE;
}

gboolean
flatpak_builtin_uninstall (int argc, char **argv, GCancellable *cancellable, GError **error)
{
  g_autoptr(GOptionContext) context = NULL;
  g_autoptr(GPtrArray) dirs = NULL;
  char **prefs = NULL;
  int i, j, k, n_prefs;
  const char *default_branch = NULL;
  FlatpakKinds kinds;
  g_autoptr(GHashTable) uninstall_dirs = NULL;

  context = g_option_context_new (_("[REF…] - Uninstall applications or runtimes"));
  g_option_context_set_translation_domain (context, GETTEXT_PACKAGE);

  if (!flatpak_option_context_parse (context, options, &argc, &argv,
                                     FLATPAK_BUILTIN_FLAG_ALL_DIRS | FLATPAK_BUILTIN_FLAG_OPTIONAL_REPO,
                                     &dirs, cancellable, error))
    return FALSE;

  if (argc < 2 && !opt_all && !opt_unused && !opt_delete_data)
    return usage_error (context, _("Must specify at least one REF, --unused, --all or --delete-data"), error);

  if (argc >= 2 && opt_all)
    return usage_error (context, _("Must not specify REFs when using --all"), error);

  if (argc >= 2 && opt_unused)
    return usage_error (context, _("Must not specify REFs when using --unused"), error);

  if (opt_noninteractive)
    opt_yes = TRUE; /* Implied */

  prefs = &argv[1];
  n_prefs = argc - 1;

  /* Backwards compat for old "NAME [BRANCH]" argument version */
  if (argc == 3 && flatpak_is_valid_name (argv[1], -1, NULL) && looks_like_branch (argv[2]))
    {
      default_branch = argv[2];
      n_prefs = 1;
    }

  kinds = flatpak_kinds_from_bools (opt_app, opt_runtime);
  uninstall_dirs = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, (GDestroyNotify) uninstall_dir_free);

  if (opt_all)
    {
      for (j = 0; j < dirs->len; j++)
        {
          FlatpakDir *dir = g_ptr_array_index (dirs, j);
          UninstallDir *udir;
          g_autoptr(GPtrArray) refs = NULL;

          flatpak_dir_maybe_ensure_repo (dir, NULL, NULL);
          if (flatpak_dir_get_repo (dir) == NULL)
            continue;

          udir = uninstall_dir_ensure (uninstall_dirs, dir);

          refs = flatpak_dir_list_refs (dir, FLATPAK_KINDS_APP | FLATPAK_KINDS_RUNTIME, cancellable, error);
          if (refs == NULL)
            return FALSE;

          for (k = 0; k < refs->len; k++)
            {
              FlatpakDecomposed *ref = g_ptr_array_index (refs, k);
              uninstall_dir_add_ref (udir, ref);
            }
        }
    }
  else if (opt_unused)
    {
      gboolean found_something_to_uninstall = FALSE;

      for (j = 0; j < dirs->len; j++)
        {
          FlatpakDir *dir = g_ptr_array_index (dirs, j);
          g_autoptr(FlatpakInstallation) installation = NULL;
          UninstallDir *udir;
          g_auto(GStrv) unused = NULL;
          g_autoptr(GPtrArray) pinned = NULL;

          flatpak_dir_maybe_ensure_repo (dir, NULL, NULL);
          if (flatpak_dir_get_repo (dir) == NULL)
            continue;

          installation = flatpak_installation_new_for_dir (dir, NULL, NULL);
          pinned = flatpak_installation_list_pinned_refs (installation, opt_arch, cancellable, error);
          if (pinned == NULL)
            return FALSE;

          if (pinned->len > 0)
            {
              g_print (_("\nThese runtimes in installation '%s' are pinned and won't be removed; see flatpak-pin(1):\n"),
                       flatpak_dir_get_name_cached (dir));
              for (i = 0; i < pinned->len; i++)
                {
                  FlatpakInstalledRef *rref = g_ptr_array_index (pinned, i);
                  const char *ref = flatpak_ref_format_ref_cached (FLATPAK_REF (rref));
                  g_print ("  %s\n", ref);
                }
            }

          udir = uninstall_dir_ensure (uninstall_dirs, dir);

          unused = flatpak_dir_list_unused_refs (dir, opt_arch, NULL, NULL, NULL, FLATPAK_DIR_FILTER_NONE, cancellable, error);
          if (unused == NULL)
            return FALSE;

          for (char **iter = unused; iter && *iter; iter++)
            {
              const char *ref = *iter;
              g_autoptr(FlatpakDecomposed) d = flatpak_decomposed_new_from_ref (ref, NULL);

              if (d)
                {
                  uninstall_dir_add_ref (udir, d);
                  found_something_to_uninstall = TRUE;
                }
            }

          if (udir->refs->len > 0)
            found_something_to_uninstall = TRUE;
        }

      if (!found_something_to_uninstall)
        {
          g_print (_("Nothing unused to uninstall\n"));
          return TRUE;
        }
    }
  else
    {
      for (j = 0; j < n_prefs; j++)
        {
          const char *pref = NULL;
          FlatpakKinds matched_kinds;
          g_autofree char *match_id = NULL;
          g_autofree char *match_arch = NULL;
          g_autofree char *match_branch = NULL;
          g_autoptr(GError) local_error = NULL;
          g_autoptr(GPtrArray) ref_dir_pairs = NULL;
          UninstallDir *udir = NULL;
          gboolean found_exact_name_match = FALSE;
          g_autoptr(GPtrArray) chosen_pairs = NULL;
          FindMatchingRefsFlags matching_refs_flags;

          pref = prefs[j];

          if (!flatpak_allow_fuzzy_matching (pref))
            matching_refs_flags = FIND_MATCHING_REFS_FLAGS_NONE;
          else
            matching_refs_flags = FIND_MATCHING_REFS_FLAGS_FUZZY;

          if (matching_refs_flags & FIND_MATCHING_REFS_FLAGS_FUZZY)
            {
              flatpak_split_partial_ref_arg_novalidate (pref, kinds, opt_arch, default_branch,
                                                        &matched_kinds, &match_id, &match_arch, &match_branch);

              /* We used _novalidate so that the id can be partial, but we can still validate the branch */
              if (match_branch != NULL && !flatpak_is_valid_branch (match_branch, -1, &local_error))
                return flatpak_fail_error (error, FLATPAK_ERROR_INVALID_REF,
                                           _("Invalid branch %s: %s"), match_branch, local_error->message);
            }
          else if (!flatpak_split_partial_ref_arg (pref, kinds, opt_arch, default_branch,
                                                   &matched_kinds, &match_id, &match_arch, &match_branch, error))
            {
              return FALSE;
            }

          ref_dir_pairs = g_ptr_array_new_with_free_func ((GDestroyNotify) ref_dir_pair_free);
          for (k = 0; k < dirs->len; k++)
            {
              FlatpakDir *dir = g_ptr_array_index (dirs, k);
              g_autoptr(GPtrArray)  refs = NULL;

              refs = flatpak_dir_find_installed_refs (dir, match_id, match_branch, match_arch, kinds,
                                                      matching_refs_flags, error);
              if (refs == NULL)
                return FALSE;
              else if (refs->len == 0)
                continue;

              for (int m = 0; m < refs->len; m++)
                {
                  FlatpakDecomposed *ref = g_ptr_array_index (refs, m);
                  RefDirPair *pair;

                  if (match_id != NULL && flatpak_decomposed_is_id (ref, match_id))
                    found_exact_name_match = TRUE;

                  pair = ref_dir_pair_new (ref, dir);
                  g_ptr_array_add (ref_dir_pairs, pair);
                }
            }

          if (ref_dir_pairs->len == 0)
            {
              if (n_prefs == 1)
                {
                  g_autoptr(GString) err_str = g_string_new ("");
                  g_string_append_printf (err_str, _("No installed refs found for ‘%s’"), match_id);

                  if (match_arch)
                    g_string_append_printf (err_str, _(" with arch ‘%s’"), match_arch);
                  if (match_branch)
                    g_string_append_printf (err_str, _(" with branch ‘%s’"), match_branch);

                  g_set_error_literal (error, FLATPAK_ERROR, FLATPAK_ERROR_NOT_INSTALLED,
                                       err_str->str);
                  return FALSE;
                }

              g_printerr (_("Warning: %s is not installed\n"), pref);
              continue;
            }

          /* Don't show fuzzy matches if an exact match was found in any installation */
          if (found_exact_name_match)
            {
              /* Walk through the array backwards so we can safely remove */
              for (i = ref_dir_pairs->len; i > 0; i--)
                {
                  RefDirPair *pair = g_ptr_array_index (ref_dir_pairs, i - 1);

                  if (match_id != NULL && !flatpak_decomposed_is_id (pair->ref, match_id))
                    g_ptr_array_remove_index (ref_dir_pairs, i - 1);
                }
            }

          chosen_pairs = g_ptr_array_new ();

          if (!flatpak_resolve_matching_installed_refs (opt_yes, FALSE, ref_dir_pairs, match_id, opt_noninteractive, chosen_pairs, error))
            return FALSE;

          for (i = 0; i < chosen_pairs->len; i++)
            {
              RefDirPair *pair = g_ptr_array_index (chosen_pairs, i);
              udir = uninstall_dir_ensure (uninstall_dirs, pair->dir);
              uninstall_dir_add_ref (udir, pair->ref);
            }
        }
    }

  if (n_prefs > 0 && g_hash_table_size (uninstall_dirs) == 0)
    {
      g_set_error (error, FLATPAK_ERROR, FLATPAK_ERROR_NOT_INSTALLED,
                   _("None of the specified refs are installed"));
      return FALSE;
    }

  GLNX_HASH_TABLE_FOREACH_V (uninstall_dirs, UninstallDir *, udir)
  {
    g_autoptr(FlatpakTransaction) transaction = NULL;

    if (opt_noninteractive)
      transaction = flatpak_quiet_transaction_new (udir->dir, error);
    else
      transaction = flatpak_cli_transaction_new (udir->dir, opt_yes, TRUE, opt_arch != NULL, error);
    if (transaction == NULL)
      return FALSE;

    flatpak_transaction_set_disable_prune (transaction, opt_keep_ref);
    flatpak_transaction_set_force_uninstall (transaction, opt_force_remove);
    flatpak_transaction_set_disable_related (transaction, opt_no_related);

    /* This disables the remote metadata update, since uninstall is a local-only op */
    flatpak_transaction_set_no_pull (transaction, TRUE);

    /* Walk through the array backwards so we can safely remove */
    for (i = udir->refs->len; i > 0; i--)
      {
        FlatpakDecomposed *ref = g_ptr_array_index (udir->refs, i - 1);

         /* In case it's a runtime for an installed app or an optional runtime
          * extension of an installed app, prompt the user for confirmation (in
          * the former case the transaction will error out if executed).  This
          * is limited to checking within the same installation; it won't
          * prompt for a user app depending on a system runtime.
         */
        if (!opt_force_remove && !opt_unused &&
            !confirm_runtime_removal (opt_yes, udir, ref))
          {
            uninstall_dir_remove_ref (udir, ref);
            continue;
          }

        if (!flatpak_transaction_add_uninstall (transaction, flatpak_decomposed_get_ref (ref), error))
          return FALSE;
      }

    /* These caches may no longer be valid once the transaction runs */
    g_clear_pointer (&udir->runtime_app_map, g_hash_table_unref);
    g_clear_pointer (&udir->extension_app_map, g_hash_table_unref);

    if (!flatpak_transaction_run (transaction, cancellable, error))
      {
        if (g_error_matches (*error, FLATPAK_ERROR, FLATPAK_ERROR_ABORTED))
          g_clear_error (error); /* Don't report on stderr */

        return FALSE;
      }

    if (opt_delete_data)
      {
        for (i = 0; i < udir->refs->len; i++)
          {
            FlatpakDecomposed *ref = g_ptr_array_index (udir->refs, i);
            g_autofree char *id = flatpak_decomposed_dup_id (ref);

            if (!flatpak_delete_data (opt_yes, id, error))
              return FALSE;
          }
      }
  }

  if (opt_delete_data && argc < 2)
    {
      g_autoptr(GFileEnumerator) enumerator = NULL;
      g_autofree char *path = g_build_filename (g_get_home_dir (), ".var", "app", NULL);
      g_autoptr(GFile) app_dir = g_file_new_for_path (path);
      gboolean found_data_to_delete = FALSE;

      enumerator = g_file_enumerate_children (app_dir,
                                              G_FILE_ATTRIBUTE_STANDARD_NAME "," G_FILE_ATTRIBUTE_STANDARD_TYPE,
                                              G_FILE_QUERY_INFO_NONE,
                                              cancellable, error);
      if (!enumerator)
        return FALSE;

      while (TRUE)
        {
          GFileInfo *info;
          GFile *file;
          g_autoptr(FlatpakDecomposed) ref = NULL;

          if (!g_file_enumerator_iterate (enumerator, &info, &file, cancellable, error))
            return FALSE;

          if (info == NULL)
            break;

          if (g_file_info_get_file_type (info) != G_FILE_TYPE_DIRECTORY)
            continue;

          ref = flatpak_find_current_ref (g_file_info_get_name (info), cancellable, NULL);
          if (ref)
            continue;

          found_data_to_delete = TRUE;

          if (!flatpak_delete_data (opt_yes, g_file_info_get_name (info), error))
            return FALSE;
        }

      if (!found_data_to_delete)
          g_print (_("No app data to delete\n"));
    }

  return TRUE;
}

gboolean
flatpak_complete_uninstall (FlatpakCompletion *completion)
{
  g_autoptr(GOptionContext) context = NULL;
  g_autoptr(GPtrArray) dirs = NULL;
  int i;
  FlatpakKinds kinds;

  context = g_option_context_new ("");
  if (!flatpak_option_context_parse (context, options, &completion->argc, &completion->argv,
                                     FLATPAK_BUILTIN_FLAG_ALL_DIRS | FLATPAK_BUILTIN_FLAG_OPTIONAL_REPO,
                                     &dirs, NULL, NULL))
    return FALSE;

  kinds = flatpak_kinds_from_bools (opt_app, opt_runtime);

  switch (completion->argc)
    {
    case 0:
    default: /* REF */
      flatpak_complete_options (completion, global_entries);
      flatpak_complete_options (completion, options);
      flatpak_complete_options (completion, user_entries);

      for (i = 0; i < dirs->len; i++)
        {
          FlatpakDir *dir = g_ptr_array_index (dirs, i);
          flatpak_complete_partial_ref (completion, kinds, opt_arch, dir, NULL);
        }

      break;
    }

  return TRUE;
}

===== ./app/flatpak-builtins-remote-ls.c =====
/* vi:set et sw=2 sts=2 cin cino=t0,f0,(0,{s,>2s,n-s,^-s,e-s:
 * Copyright © 2014 Red Hat, Inc
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Alexander Larsson <alexl@redhat.com>
 */

#include "config.h"

#include <locale.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

#include <glib/gi18n.h>

#include "libglnx.h"

#include "flatpak-builtins.h"
#include "flatpak-builtins-utils.h"
#include "flatpak-repo-utils-private.h"
#include "flatpak-utils-private.h"
#include "flatpak-table-printer.h"
#include "flatpak-variant-impl-private.h"

static gboolean opt_show_details;
static gboolean opt_runtime;
static gboolean opt_app;
static gboolean opt_all;
static gboolean opt_only_updates;
static gboolean opt_cached;
static gboolean opt_sideloaded;
static char *opt_arch;
static char *opt_app_runtime;
static const char **opt_cols;
static gboolean opt_json;

static GOptionEntry options[] = {
  { "show-details", 'd', 0, G_OPTION_ARG_NONE, &opt_show_details, N_("Show arches and branches"), NULL },
  { "runtime", 0, 0, G_OPTION_ARG_NONE, &opt_runtime, N_("Show only runtimes"), NULL },
  { "app", 0, 0, G_OPTION_ARG_NONE, &opt_app, N_("Show only apps"), NULL },
  { "updates", 0, 0, G_OPTION_ARG_NONE, &opt_only_updates, N_("Show only those where updates are available"), NULL },
  { "arch", 0, 0, G_OPTION_ARG_STRING, &opt_arch, N_("Limit to this arch (* for all)"), N_("ARCH") },
  { "all", 'a', 0, G_OPTION_ARG_NONE, &opt_all, N_("List all refs (including locale/debug)"), NULL },
  { "app-runtime", 0, 0, G_OPTION_ARG_STRING, &opt_app_runtime, N_("List all applications using RUNTIME"), N_("RUNTIME") },
  { "columns", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_cols, N_("What information to show"), N_("FIELD,…") },
  { "cached", 0, 0, G_OPTION_ARG_NONE, &opt_cached, N_("Use local caches even if they are stale"), NULL },
  /* Translators: A sideload is when you install from a local USB drive rather than the Internet. */
  { "sideloaded", 0, 0, G_OPTION_ARG_NONE, &opt_sideloaded, N_("Only list refs available as sideloads"), NULL },
  { "json", 'j', 0, G_OPTION_ARG_NONE, &opt_json, N_("Show output in JSON format"), NULL },
  { NULL }
};

static Column all_columns[] = {
  { "name",           N_("Name"),           N_("Show the name"),           1, FLATPAK_ELLIPSIZE_MODE_END, 1, 1 },
  { "description",    N_("Description"),    N_("Show the description"),    1, FLATPAK_ELLIPSIZE_MODE_END, 1, 0 },
  { "application",    N_("Application ID"),    N_("Show the application ID"), 1, FLATPAK_ELLIPSIZE_MODE_START, 0, 1 },
  { "version",        N_("Version"),        N_("Show the version"),        1, FLATPAK_ELLIPSIZE_MODE_NONE, 1, 1 },
  { "branch",         N_("Branch"),         N_("Show the branch"),         1, FLATPAK_ELLIPSIZE_MODE_NONE, 0, 1 },
  { "arch",           N_("Arch"),           N_("Show the architecture"),   1, FLATPAK_ELLIPSIZE_MODE_NONE, 0, 0 },
  { "origin",         N_("Origin"),         N_("Show the origin remote"),  1, FLATPAK_ELLIPSIZE_MODE_NONE, 1, 1, 1 },
  { "ref",            N_("Ref"),            N_("Show the ref"),            1, FLATPAK_ELLIPSIZE_MODE_NONE, 1, 0 },
  { "commit",         N_("Commit"),         N_("Show the active commit"),  1, FLATPAK_ELLIPSIZE_MODE_NONE, 1, 0 },
  { "runtime",        N_("Runtime"),        N_("Show the runtime"),        1, FLATPAK_ELLIPSIZE_MODE_NONE, 1, 0 },
  { "installed-size", N_("Installed size"), N_("Show the installed size"), 1, FLATPAK_ELLIPSIZE_MODE_NONE, 1, 0 },
  { "download-size",  N_("Download size"),  N_("Show the download size"),  1, FLATPAK_ELLIPSIZE_MODE_NONE, 1, 0 },
  { "options",        N_("Options"),        N_("Show options"),            1, FLATPAK_ELLIPSIZE_MODE_END, 1, 0 },
  { NULL }
};


typedef struct RemoteStateDirPair
{
  FlatpakRemoteState *state;
  FlatpakDir         *dir;
} RemoteStateDirPair;

static void
remote_state_dir_pair_free (RemoteStateDirPair *pair)
{
  flatpak_remote_state_unref (pair->state);
  g_object_unref (pair->dir);
  g_free (pair);
}

static RemoteStateDirPair *
remote_state_dir_pair_new (FlatpakDir *dir, FlatpakRemoteState *state)
{
  RemoteStateDirPair *pair = g_new (RemoteStateDirPair, 1);

  pair->state = state;
  pair->dir = g_object_ref (dir);
  return pair;
}

static char *
strip_last_element (const char *id,
                    gsize id_len)
{
  while (id_len > 0 &&
         id[id_len - 1] != '.')
    id_len--;

  if (id_len > 0)
    id_len--; /* Remove the dot too */

  return g_strndup (id, id_len);
}

static gboolean
ls_remote (GHashTable *refs_hash, const char **arches, const char *app_runtime, Column *columns, GCancellable *cancellable, GError **error)
{
  g_autoptr(FlatpakTablePrinter) printer = NULL;
  guint n_keys;
  g_autofree FlatpakDecomposed **keys = NULL;
  int i, j;
  FlatpakKinds match_kinds;
  g_autofree char *match_id = NULL;
  g_autofree char *match_arch = NULL;
  g_autofree char *match_branch = NULL;
  gboolean need_cache_data = FALSE;
  gboolean need_appstream_data = FALSE;

  printer = flatpak_table_printer_new ();

  flatpak_table_printer_set_columns (printer, columns,
                                     opt_cols == NULL && !opt_show_details);

  if (app_runtime)
    {
      need_cache_data = TRUE;
      if (!flatpak_split_partial_ref_arg (app_runtime, FLATPAK_KINDS_RUNTIME, NULL, NULL,
                                          &match_kinds, &match_id, &match_arch, &match_branch, error))
        return FALSE;
    }

  for (j = 0; columns[j].name; j++)
    {
      if (strcmp (columns[j].name, "download-size") == 0 ||
          strcmp (columns[j].name, "installed-size") == 0 ||
          strcmp (columns[j].name, "runtime") == 0)
        need_cache_data = TRUE;
      if (strcmp (columns[j].name, "name") == 0 ||
          strcmp (columns[j].name, "description") == 0 ||
          strcmp (columns[j].name, "version") == 0)
        need_appstream_data = TRUE;
    }

  GLNX_HASH_TABLE_FOREACH_KV (refs_hash, GHashTable *, refs, RemoteStateDirPair *, remote_state_dir_pair)
    {
      FlatpakDir *dir = remote_state_dir_pair->dir;
      FlatpakRemoteState *state = remote_state_dir_pair->state;
      const char *remote = state->remote_name;
      g_autoptr(AsMetadata) mdata = NULL;
      g_autoptr(GHashTable) pref_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); /* value owned by refs */
      g_autoptr(GHashTable) names = g_hash_table_new_full ((GHashFunc)flatpak_decomposed_hash, (GEqualFunc)flatpak_decomposed_equal, (GDestroyNotify)flatpak_decomposed_unref, g_free);

      GLNX_HASH_TABLE_FOREACH (refs, FlatpakDecomposed *, ref)
        {
          char *partial_ref = flatpak_make_valid_id_prefix (flatpak_decomposed_get_pref (ref));
          g_hash_table_insert (pref_hash, partial_ref, ref);
        }

      GLNX_HASH_TABLE_FOREACH_KV (refs, FlatpakDecomposed *, ref, const char *, checksum)
        {
          if (opt_only_updates)
            {
              g_autoptr(GBytes) deploy_data = flatpak_dir_get_deploy_data (dir, ref, FLATPAK_DEPLOY_VERSION_ANY, cancellable, NULL);

              if (deploy_data == NULL)
                continue;

              if (g_strcmp0 (flatpak_deploy_data_get_origin (deploy_data), remote) != 0)
                continue;

              if (g_strcmp0 (flatpak_deploy_data_get_commit (deploy_data), checksum) == 0)
                continue;
            }

          if (arches != NULL && !flatpak_decomposed_is_arches (ref, -1, arches))
            continue;

          if (flatpak_decomposed_is_runtime (ref) && !opt_runtime)
            continue;

          if (flatpak_decomposed_is_app (ref) && !opt_app)
            continue;

          if (!opt_all &&
              flatpak_decomposed_is_runtime (ref) &&
              flatpak_decomposed_id_is_subref (ref))
            {
              g_autoptr(FlatpakDecomposed) parent_ref = NULL;
              gsize id_len;
              const char *id = flatpak_decomposed_peek_id (ref, &id_len);
              g_autofree char *parent_id = strip_last_element (id, id_len);

              parent_ref = flatpak_decomposed_new_from_decomposed (ref, FLATPAK_KINDS_RUNTIME,
                                                                   parent_id, NULL, NULL, NULL);

              if (parent_ref != NULL &&
                  g_hash_table_lookup (pref_hash, flatpak_decomposed_get_pref (parent_ref)))
                continue;
            }

          if (!opt_all && opt_arch == NULL &&
              /* Hide non-primary arches if the primary arch exists */
              !flatpak_decomposed_is_arch (ref, arches[0]))
            {
              g_autoptr(FlatpakDecomposed) alt_arch = flatpak_decomposed_new_from_decomposed (ref, 0, NULL, arches[0], NULL, NULL);

              if (alt_arch && g_hash_table_lookup (refs, alt_arch))
                continue;
            }

          if (g_hash_table_lookup (names, ref) == NULL)
            g_hash_table_insert (names, flatpak_decomposed_ref (ref), g_strdup (checksum));
        }

      if (need_appstream_data)
        {
          mdata = as_metadata_new ();
          flatpak_dir_load_appstream_data (dir, remote, NULL, mdata, NULL, NULL);
        }

      keys = (FlatpakDecomposed **) g_hash_table_get_keys_as_array (names, &n_keys);
      qsort (keys, n_keys, sizeof (char *), (GCompareFunc) flatpak_decomposed_strcmp_p);

      for (i = 0; i < n_keys; i++)
        {
          FlatpakDecomposed *ref = keys[i];
          const char *ref_str = flatpak_decomposed_get_ref (ref);
          guint64 installed_size;
          guint64 download_size;
          g_autofree char *runtime = NULL;
          AsComponent *cpt = NULL;
          gboolean has_sparse_cache;
          VarMetadataRef sparse_cache;
          g_autofree char *id = flatpak_decomposed_dup_id (ref);
          g_autofree char *arch = flatpak_decomposed_dup_arch (ref);
          g_autofree char *branch = flatpak_decomposed_dup_branch (ref);

          /* The sparse cache is optional */
          has_sparse_cache = flatpak_remote_state_lookup_sparse_cache (state, ref_str, &sparse_cache, NULL);
          if (!opt_all && has_sparse_cache)
            {
              const char *eol = var_metadata_lookup_string (sparse_cache, FLATPAK_SPARSE_CACHE_KEY_ENDOFLIFE, NULL);
              const char *eol_rebase = var_metadata_lookup_string (sparse_cache, FLATPAK_SPARSE_CACHE_KEY_ENDOFLIFE_REBASE, NULL);

              if (eol != NULL || eol_rebase != NULL)
                continue;
            }

          if (need_cache_data)
            {
              g_autofree char *metadata = NULL;
              g_autoptr(GKeyFile) metakey = NULL;

              if (!flatpak_remote_state_load_data (state, ref_str,
                                                   &download_size, &installed_size, &metadata,
                                                   error))
                return FALSE;

              metakey = g_key_file_new ();
              if (g_key_file_load_from_data (metakey, metadata, -1, 0, NULL))
                runtime = g_key_file_get_string (metakey, "Application", "runtime", NULL);
            }

          if (need_appstream_data)
            cpt = metadata_find_component (mdata, ref_str);

          if (app_runtime && runtime)
            {
              g_auto(GStrv) pref = g_strsplit (runtime, "/", 3);
              if ((match_id && pref[0] && strcmp (pref[0], match_id) != 0) ||
                  (match_arch && pref[1] && strcmp (pref[1], match_arch) != 0) ||
                  (match_branch && pref[2] && strcmp (pref[2], match_branch) != 0))
                continue;
            }

          for (j = 0; columns[j].name; j++)
            {
              if (strcmp (columns[j].name, "name") == 0)
                {
                  const char *name = NULL;
                  g_autofree char *readable_id = NULL;

                  if (cpt)
                    name = as_component_get_name (cpt);

                  if (name == NULL)
                    readable_id = flatpak_decomposed_dup_readable_id (ref);

                  flatpak_table_printer_add_column (printer, name ? name : readable_id);
                }
              else if (strcmp (columns[j].name, "description") == 0)
                {
                  const char *comment = NULL;
                  if (cpt)
                      comment = as_component_get_summary (cpt);

                  flatpak_table_printer_add_column (printer, comment);
                }
              else if (strcmp (columns[j].name, "version") == 0)
                flatpak_table_printer_add_column (printer, cpt ? component_get_version_latest (cpt) : "");
              else if (strcmp (columns[j].name, "ref") == 0)
                flatpak_table_printer_add_column (printer, ref_str);
              else if (strcmp (columns[j].name, "application") == 0)
                flatpak_table_printer_add_column (printer, id);
              else if (strcmp (columns[j].name, "arch") == 0)
                flatpak_table_printer_add_column (printer, arch);
              else if (strcmp (columns[j].name, "branch") == 0)
                flatpak_table_printer_add_column (printer, branch);
              else if (strcmp (columns[j].name, "origin") == 0)
                flatpak_table_printer_add_column (printer, remote);
              else if (strcmp (columns[j].name, "commit") == 0)
                {
                  g_autofree char *value = NULL;

                  value = g_strdup ((char *) g_hash_table_lookup (names, keys[i]));
                  value[MIN (strlen (value), 12)] = 0;
                  flatpak_table_printer_add_column (printer, value);
                }
              else if (strcmp (columns[j].name, "installed-size") == 0)
                {
                  g_autofree char *installed = g_format_size (installed_size);
                  flatpak_table_printer_add_decimal_column (printer, installed);
                }
              else if (strcmp (columns[j].name, "download-size") == 0)
                {
                  g_autofree char *download = g_format_size (download_size);
                  flatpak_table_printer_add_decimal_column (printer, download);
                }
              else if (strcmp (columns[j].name, "runtime") == 0)
                {
                  flatpak_table_printer_add_column (printer, runtime);
                }
              else if (strcmp (columns[j].name, "options") == 0)
                {
                  flatpak_table_printer_add_column (printer, ""); /* Extra */
                  if (has_sparse_cache)
                    {
                      const char *eol = var_metadata_lookup_string (sparse_cache, FLATPAK_SPARSE_CACHE_KEY_ENDOFLIFE, NULL);
                      const char *eol_rebase = var_metadata_lookup_string (sparse_cache, FLATPAK_SPARSE_CACHE_KEY_ENDOFLIFE_REBASE, NULL);

                      if (eol)
                        flatpak_table_printer_append_with_comma_printf (printer, "eol=%s", eol);
                      if (eol_rebase)
                        flatpak_table_printer_append_with_comma_printf (printer, "eol-rebase=%s", eol_rebase);
                    }
                }
            }

          flatpak_table_printer_finish_row (printer);
        }
    }

  if (flatpak_table_printer_get_current_row (printer) > 0)
    {
      opt_json ? flatpak_table_printer_print_json (printer) : flatpak_table_printer_print (printer);
    }

  return TRUE;
}

gboolean
flatpak_builtin_remote_ls (int argc, char **argv, GCancellable *cancellable, GError **error)
{
  g_autoptr(GOptionContext) context = NULL;
  g_autoptr(GPtrArray) dirs = NULL;
  const char **arches = flatpak_get_arches ();
  const char *opt_arches[] = {NULL, NULL};
  gboolean has_remote;
  g_autoptr(GHashTable) refs_hash = g_hash_table_new_full (g_direct_hash, g_direct_equal, (GDestroyNotify) g_hash_table_unref, (GDestroyNotify) remote_state_dir_pair_free);
  g_autofree char *col_help = NULL;
  g_autofree Column *columns = NULL;

  context = g_option_context_new (_(" [REMOTE or URI] - Show available runtimes and applications"));
  g_option_context_set_translation_domain (context, GETTEXT_PACKAGE);
  col_help = column_help (all_columns);
  g_option_context_set_description (context, col_help);

  if (!flatpak_option_context_parse (context, options, &argc, &argv,
                                     FLATPAK_BUILTIN_FLAG_STANDARD_DIRS, &dirs, cancellable, error))
    return FALSE;

  if (!opt_app && !opt_runtime)
    {
      opt_app = TRUE;
      opt_runtime = !opt_app_runtime;
    }

  if (argc > 2)
    return usage_error (context, _("Too many arguments"), error);

  has_remote = (argc == 2);

  if (opt_arch != NULL)
    {
      if (strcmp (opt_arch, "*") == 0)
        arches = NULL;
      else
        {
          opt_arches[0] = opt_arch;
          arches = opt_arches;
        }
    }

  if (has_remote)
    {
      g_autoptr(FlatpakDir) preferred_dir = NULL;
      g_autoptr(GHashTable) refs = NULL;
      RemoteStateDirPair *remote_state_dir_pair = NULL;
      g_autoptr(FlatpakRemoteState) state = NULL;
      gboolean is_local = FALSE;

      is_local = g_str_has_prefix (argv[1], "file:");
      if (is_local)
        preferred_dir = flatpak_dir_get_system_default ();
      else
        {
          if (!flatpak_resolve_duplicate_remotes (dirs, argv[1], FALSE, &preferred_dir, cancellable, error))
            return FALSE;
        }

      state = get_remote_state (preferred_dir, argv[1], opt_cached, opt_sideloaded, opt_arches[0], NULL, cancellable, error);
      if (state == NULL)
        return FALSE;

      if (arches == NULL &&
          !ensure_remote_state_all_arches (preferred_dir, state, opt_cached, opt_sideloaded, cancellable, error))
        return FALSE;

      if (!flatpak_dir_list_remote_refs (preferred_dir, state, &refs,
                                         cancellable, error))
        return FALSE;

      remote_state_dir_pair = remote_state_dir_pair_new (preferred_dir, g_steal_pointer (&state));
      g_hash_table_insert (refs_hash, g_steal_pointer (&refs), remote_state_dir_pair);
    }
  else
    {
      int i;

      for (i = 0; i < dirs->len; i++)
        {
          FlatpakDir *dir = g_ptr_array_index (dirs, i);
          g_auto(GStrv) remotes = NULL;
          int j;

          remotes = flatpak_dir_list_remotes (dir, cancellable, error);
          if (remotes == NULL)
            return FALSE;

          for (j = 0; remotes[j] != NULL; j++)
            {
              g_autoptr(GHashTable) refs = NULL;
              RemoteStateDirPair *remote_state_dir_pair = NULL;
              const char *remote_name = remotes[j];
              g_autoptr(FlatpakRemoteState) state = NULL;

              if (flatpak_dir_get_remote_disabled (dir, remote_name))
                continue;

              state = get_remote_state (dir, remote_name, opt_cached, opt_sideloaded, opt_arches[0], NULL,
                                        cancellable, error);
              if (state == NULL)
                return FALSE;

              if (arches == NULL &&
                  !ensure_remote_state_all_arches (dir, state, opt_cached, opt_sideloaded, cancellable, error))
                return FALSE;

              if (!flatpak_dir_list_remote_refs (dir, state, &refs,
                                                 cancellable, error))
                return FALSE;

              remote_state_dir_pair = remote_state_dir_pair_new (dir, g_steal_pointer (&state));
              g_hash_table_insert (refs_hash, g_steal_pointer (&refs), remote_state_dir_pair);
            }
        }
    }

  /* show origin by default if listing multiple remotes */
  all_columns[5].def = !has_remote;

  columns = handle_column_args (all_columns, opt_show_details, opt_cols, error);
  if (columns == NULL)
    return FALSE;

  return ls_remote (refs_hash, arches, opt_app_runtime, columns, cancellable, error);
}

gboolean
flatpak_complete_remote_ls (FlatpakCompletion *completion)
{
  g_autoptr(GOptionContext) context = NULL;
  g_autoptr(GPtrArray) dirs = NULL;
  int i;

  context = g_option_context_new ("");

  if (!flatpak_option_context_parse (context, options, &completion->argc, &completion->argv,
                                     FLATPAK_BUILTIN_FLAG_STANDARD_DIRS, &dirs, NULL, NULL))
    return FALSE;

  switch (completion->argc)
    {
    case 0:
    case 1: /* REMOTE */
      flatpak_complete_options (completion, global_entries);
      flatpak_complete_options (completion, options);
      flatpak_complete_options (completion, user_entries);
      flatpak_complete_columns (completion, all_columns);

      for (i = 0; i < dirs->len; i++)
        {
          FlatpakDir *dir = g_ptr_array_index (dirs, i);
          int j;
          g_auto(GStrv) remotes = flatpak_dir_list_remotes (dir, NULL, NULL);
          if (remotes == NULL)
            return FALSE;
          for (j = 0; remotes[j] != NULL; j++)
            flatpak_complete_word (completion, "%s ", remotes[j]);
        }

      break;
    }

  return TRUE;
}

===== ./app/flatpak-table-printer.c =====
/* vi:set et sw=2 sts=2 cin cino=t0,f0,(0,{s,>2s,n-s,^-s,e-s:
 * Copyright © 2014 Red Hat, Inc
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Alexander Larsson <alexl@redhat.com>
 */

#include "config.h"

#include <glib/gi18n.h>
#include <json-glib/json-glib.h>
#include <json-glib/json-gobject.h>
#include "flatpak-table-printer.h"
#include "flatpak-tty-utils-private.h"
#include "flatpak-utils-private.h"

#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <locale.h>


typedef struct
{
  char    *text;
  int      align;
  gboolean span;
} Cell;

static void
free_cell (gpointer data)
{
  Cell *cell = data;

  g_free (cell->text);
  g_free (cell);
}

typedef struct
{
  GPtrArray *cells;
  char      *key;
} Row;

static void
free_row (gpointer data)
{
  Row *row = data;

  g_ptr_array_free (row->cells, TRUE);
  g_free (row->key);
  g_free (row);
}

typedef struct
{
  char                *title;
  gboolean             expand;
  FlatpakEllipsizeMode ellipsize;
  gboolean             skip_unique;
  char                *skip_unique_str;
  gboolean             skip;
} TableColumn;

static void
free_column (gpointer data)
{
  TableColumn *column = data;

  g_free (column->title);
  g_free (column->skip_unique_str);
  g_free (column);
}

struct FlatpakTablePrinter
{
  GPtrArray *columns;
  GPtrArray *rows;
  GHashTable *rows_ht;
  char      *key;
  GPtrArray *current;
  int        n_columns;
};

FlatpakTablePrinter *
flatpak_table_printer_new (void)
{
  FlatpakTablePrinter *printer = g_new0 (FlatpakTablePrinter, 1);

  printer->columns = g_ptr_array_new_with_free_func (free_column);
  printer->rows = g_ptr_array_new_with_free_func ((GDestroyNotify) free_row);
  printer->rows_ht = g_hash_table_new (g_str_hash, g_str_equal);
  printer->current = g_ptr_array_new_with_free_func (free_cell);

  return printer;
}

void
flatpak_table_printer_free (FlatpakTablePrinter *printer)
{
  g_ptr_array_free (printer->columns, TRUE);
  g_ptr_array_free (printer->rows, TRUE);
  g_hash_table_destroy (printer->rows_ht);
  g_ptr_array_free (printer->current, TRUE);
  g_free (printer->key);
  g_free (printer);
}

static TableColumn *
peek_table_column (FlatpakTablePrinter *printer,
                   int                  column)
{
  if (column < printer->columns->len)
    return g_ptr_array_index (printer->columns, column);

  return NULL;
}

static TableColumn *
get_table_column (FlatpakTablePrinter *printer,
                  int                  column)
{
  TableColumn *col = NULL;

  if (column < printer->columns->len)
    col = g_ptr_array_index (printer->columns, column);

  if (col == NULL)
    {
      col = g_new0 (TableColumn, 1);
      g_ptr_array_insert (printer->columns, column, col);
    }

  return col;
}

void
flatpak_table_printer_set_column_title (FlatpakTablePrinter *printer,
                                        int                  column,
                                        const char          *text)
{
  TableColumn *col = get_table_column (printer, column);

  col->title = g_strdup (text);
}

void
flatpak_table_printer_set_columns (FlatpakTablePrinter *printer,
                                   Column              *columns,
                                   gboolean             defaults)
{
  int i;

  for (i = 0; columns[i].name; i++)
    {
      flatpak_table_printer_set_column_title (printer, i, _(columns[i].title));
      flatpak_table_printer_set_column_expand (printer, i, columns[i].expand);
      flatpak_table_printer_set_column_ellipsize (printer, i, columns[i].ellipsize);
      if (defaults && columns[i].skip_unique_if_default)
        flatpak_table_printer_set_column_skip_unique (printer, i, TRUE);
    }
}

void
flatpak_table_printer_add_aligned_column (FlatpakTablePrinter *printer,
                                          const char          *text,
                                          int                  align)
{
  Cell *cell = g_new0 (Cell, 1);

  cell->text = text ? g_strdup (text) : g_strdup ("");
  cell->align = align;
  g_ptr_array_add (printer->current, cell);
}

void
flatpak_table_printer_add_span (FlatpakTablePrinter *printer,
                                const char          *text)
{
  Cell *cell = g_new0 (Cell, 1);

  cell->text = text ? g_strdup (text) : g_strdup ("");
  cell->align = -1;
  cell->span = TRUE;
  g_ptr_array_add (printer->current, cell);
}

static const char *
find_decimal_point (const char *text)
{
  struct lconv *locale_data;

  locale_data = localeconv ();
  return strstr (text, locale_data->decimal_point);
}

void
flatpak_table_printer_add_decimal_column (FlatpakTablePrinter *printer,
                                          const char          *text)
{
  const char *decimal;
  int align = -1;

  decimal = find_decimal_point (text);
  if (decimal)
    align = decimal - text;

  flatpak_table_printer_add_aligned_column (printer, text, align);
}

void
flatpak_table_printer_add_column (FlatpakTablePrinter *printer,
                                  const char          *text)
{
  flatpak_table_printer_add_aligned_column (printer, text, -1);
}

void
flatpak_table_printer_take_column (FlatpakTablePrinter *printer,
                                   char                *text)
{
  flatpak_table_printer_add_aligned_column (printer, text, -1);
  g_free (text);
}

void
flatpak_table_printer_add_column_len (FlatpakTablePrinter *printer,
                                      const char          *text,
                                      gsize                len)
{
  Cell *cell = g_new0 (Cell, 1);

  cell->text = text ? g_strndup (text, len) : g_strdup ("");
  cell->align = -1;
  g_ptr_array_add (printer->current, cell);
}

void
flatpak_table_printer_append_with_comma (FlatpakTablePrinter *printer,
                                         const char          *text)
{
  Cell *cell;
  char *new;

  g_assert (printer->current->len > 0);

  cell = g_ptr_array_index (printer->current, printer->current->len - 1);

  if (cell->text[0] != 0)
    new = g_strconcat (cell->text, ",", text, NULL);
  else
    new = g_strdup (text);

  g_free (cell->text);
  cell->text = new;
}

void
flatpak_table_printer_append_with_comma_printf (FlatpakTablePrinter *printer,
                                                const char          *format,
                                                ...)
{
  va_list var_args;
  g_autofree char *s = NULL;

  va_start (var_args, format);
  s = g_strdup_vprintf (format, var_args);
  va_end (var_args);

  flatpak_table_printer_append_with_comma (printer, s);
}

void
flatpak_table_printer_set_key (FlatpakTablePrinter *printer, const char *key)
{
  printer->key = g_strdup (key);
}

static gint
cmp_row (gconstpointer _row_a,
         gconstpointer _row_b,
         gpointer      user_data)
{
  const Row *row_a = *(const Row **) _row_a;
  const Row *row_b = *(const Row **) _row_b;
  GCompareFunc cmp = user_data;

  if (row_a == row_b || (row_a->key == NULL && row_b->key == NULL))
    return 0;
  if (row_a->key == NULL)
    return -1;
  if (row_b->key == NULL)
    return 1;

  return cmp (row_a->key, row_b->key);
}

void
flatpak_table_printer_sort (FlatpakTablePrinter *printer, GCompareFunc cmp)
{
  g_ptr_array_sort_with_data (printer->rows, cmp_row, cmp);
}

int
flatpak_table_printer_lookup_row (FlatpakTablePrinter *printer, const char *key)
{
  gpointer value;

  if (g_hash_table_lookup_extended (printer->rows_ht, key, NULL, &value))
    return GPOINTER_TO_INT(value);

  return -1;
}

void
flatpak_table_printer_finish_row (FlatpakTablePrinter *printer)
{
  Row *row;
  int row_nr = flatpak_table_printer_get_current_row (printer);

  if (printer->current->len == 0)
    return; /* Ignore empty rows */

  printer->n_columns = MAX (printer->n_columns, printer->current->len);
  row = g_new0 (Row, 1);
  row->cells = g_steal_pointer (&printer->current);
  row->key = g_steal_pointer (&printer->key);
  g_ptr_array_add (printer->rows, row);
  if (row->key)
    g_hash_table_insert (printer->rows_ht, row->key, GINT_TO_POINTER (row_nr));
  printer->current = g_ptr_array_new_with_free_func (free_cell);
}

/* Return how many terminal rows we produced (with wrapping to columns)
 * while skipping 'skip' many of them. 'skip' is updated to reflect
 * how many we skipped.
 */
static int
print_row (GString *row_s, gboolean bold, int *skip, int columns)
{
  int rows;
  const char *p, *end;
  int n_chars;

  g_strchomp (row_s->str);
  n_chars = cell_width (row_s->str);
  if (n_chars > 0)
    rows = (n_chars + columns - 1) / columns;
  else
    rows = 1;

  p = row_s->str;
  end = row_s->str + strlen (row_s->str);
  while (*skip > 0 && p <= end)
    {
      (*skip)--;
      p = cell_advance (p, columns);
    }

  if (p < end || p == row_s->str)
    {
      if (bold)
        g_print (FLATPAK_ANSI_BOLD_ON "%s" FLATPAK_ANSI_BOLD_OFF, p);
      else
        g_print ("%s", p);
    }
  g_string_truncate (row_s, 0);

  return rows;
}

static void
string_add_spaces (GString *str, int count)
{
  while (count-- > 0)
    g_string_append_c (str, ' ');
}

static gboolean
column_is_unique (FlatpakTablePrinter *printer, int col)
{
  TableColumn *column = get_table_column (printer, col);
  char *first_row = column->skip_unique_str;
  int i;

  for (i = 0; i < printer->rows->len; i++)
    {
      Row *row = g_ptr_array_index (printer->rows, i);
      if (col >= row->cells->len)
        continue;

      Cell *cell = g_ptr_array_index (row->cells, col);

      if (i == 0 && first_row == NULL)
        first_row = cell->text;
      else
        {
          if (g_strcmp0 (first_row, cell->text) != 0)
            return FALSE;
        }
    }

  return TRUE;
}

/*
 * This variant of flatpak_table_printer_print() takes a window width
 * and returns the number of rows that are generated by printing the
 * table to that width. It also takes a number of (terminal) rows
 * to skip at the beginning of the table.
 *
 * Care is taken to do the right thing if the skipping ends
 * in the middle of a wrapped table row.
 *
 * Note that unlike flatpak_table_printer_print(), this function does
 * not add a newline after the last table row.
 */
void
flatpak_table_printer_print_full (FlatpakTablePrinter *printer,
                                  int                  skip,
                                  int                  columns,
                                  int                 *table_height,
                                  int                 *table_width)
{
  g_autofree int *widths = NULL;
  g_autofree int *lwidths = NULL;
  g_autofree int *rwidths = NULL;
  g_autofree int *shrinks = NULL;
  g_autoptr(GString) row_s = g_string_new ("");
  int i, j;
  int rows = 0;
  int total_skip = skip;
  int width;
  int expand_columns;
  int shrink_columns;
  gboolean has_title;
  int expand_by, expand_extra;

  if (printer->current->len != 0)
    flatpak_table_printer_finish_row (printer);

  widths = g_new0 (int, printer->n_columns);
  lwidths = g_new0 (int, printer->n_columns);
  rwidths = g_new0 (int, printer->n_columns);
  shrinks = g_new0 (int, printer->n_columns);

  for (i = 0; i < printer->columns->len && i < printer->n_columns; i++)
    {
      TableColumn *col = g_ptr_array_index (printer->columns, i);

      if (col->skip_unique && column_is_unique (printer, i))
        col->skip = TRUE;
    }

  has_title = FALSE;
  for (i = 0; i < printer->columns->len && i < printer->n_columns; i++)
    {
      TableColumn *col = g_ptr_array_index (printer->columns, i);

      if (col->skip)
        continue;

      if (col->title)
        {
          widths[i] = MAX (widths[i], cell_width (col->title));
          has_title = TRUE;
        }
    }

  for (i = 0; i < printer->rows->len; i++)
    {
      Row *row = g_ptr_array_index (printer->rows, i);

      for (j = 0; j < row->cells->len; j++)
        {
          Cell *cell = g_ptr_array_index (row->cells, j);
          TableColumn *col = peek_table_column (printer, j);

          if (col && col->skip)
            continue;

          if (cell->span)
            width = 0;
          else
            width = cell_width (cell->text);
          widths[j] = MAX (widths[j], width);
          if (cell->align >= 0)
            {
              lwidths[j] = MAX (lwidths[j], cell->align);
              rwidths[j] = MAX (rwidths[j], width - cell->align);
            }
        }
    }

  width = printer->n_columns - 1;
  for (i = 0; i < printer->n_columns; i++)
    width += widths[i];

  expand_columns = 0;
  shrink_columns = 0;
  for (i = 0; i < printer->columns->len; i++)
    {
      TableColumn *col = g_ptr_array_index (printer->columns, i);
      if (col && col->skip)
        continue;
      if (col && col->expand)
        expand_columns++;
      if (col && col->ellipsize)
        shrink_columns++;
    }

  expand_by = 0;
  expand_extra = 0;
  if (expand_columns > 0)
    {
      int excess = CLAMP (columns - width, 0, width / 2);
      expand_by = excess / expand_columns;
      expand_extra = excess % expand_columns;
      width += excess;
    }

  if (shrink_columns > 0)
    {
      int shortfall = MAX (width - columns, 0);
      int last;
      if (shortfall > 0)
        {
          int shrinkable = 0;
          int leftover = shortfall;

          /* We're distributing the shortfall so that wider columns
           * shrink proportionally more than narrower ones, while
           * avoiding to ellipsize the titles.
           */
          for (i = 0; i < printer->columns->len && i < printer->n_columns; i++)
            {
              TableColumn *col = g_ptr_array_index (printer->columns, i);
              gboolean ellipsize = col ? col->ellipsize : FALSE;

              if (col && col->skip)
                continue;

              if (!ellipsize)
                continue;

              if (col && col->title)
                shrinkable += MAX (0, widths[i] - cell_width (col->title));
              else
                shrinkable += MAX (0, widths[i] - 5);
            }

          for (i = 0; i < printer->columns->len && i < printer->n_columns; i++)
            {
              TableColumn *col = g_ptr_array_index (printer->columns, i);
              gboolean ellipsize = col ? col->ellipsize : FALSE;

              if (col && col->skip)
                continue;

              if (ellipsize)
                {
                  int sh;
                  if (col && col->title)
                    sh = MAX (0, widths[i] - cell_width (col->title));
                  else
                    sh = MAX (0, widths[i] - 5);
                  shrinks[i] = MIN (shortfall * (sh / (double) shrinkable), widths[i]);
                  leftover -= shrinks[i];
                }
            }

          last = leftover + 1;
          while (leftover > 0 && leftover < last)
            {
              last = leftover;
              for (i = 0; i < printer->columns->len && i < printer->n_columns; i++)
                {
                  TableColumn *col = g_ptr_array_index (printer->columns, i);
                  gboolean ellipsize = col ? col->ellipsize : FALSE;

                  if (col && col->skip)
                    continue;

                  if (ellipsize && shrinks[i] < widths[i])
                    {
                      shrinks[i]++;
                      leftover--;
                    }
                  if (leftover == 0)
                    break;
                }
            }
        }

      for (i = 0; i < printer->n_columns; i++)
        width -= shrinks[i];
    }

  if (flatpak_fancy_output () && has_title)
    {
      int grow = expand_extra;
      for (i = 0; i < printer->columns->len && i < printer->n_columns; i++)
        {
          TableColumn *col = g_ptr_array_index (printer->columns, i);
          const char *title = col && col->title ? col->title : "";
          gboolean expand = col ? col->expand : FALSE;
          gboolean ellipsize = col ? col->ellipsize : FALSE;
          int len = widths[i];
          g_autofree char *freeme = NULL;

          if (col && col->skip)
            continue;

          if (expand_by > 0 && expand)
            {
              len += expand_by;
              if (grow > 0)
                {
                  len++;
                  grow--;
                }
            }

          if (shrinks[i] > 0 && ellipsize)
            {
              len -= shrinks[i];
              title = freeme = ellipsize_string (title, len);
            }

          if (i > 0)
            g_string_append_c (row_s, ' ');
          g_string_append (row_s, title);
          string_add_spaces (row_s, len - cell_width (title));
        }
      rows += print_row (row_s, TRUE, &skip, columns);
    }

  for (i = 0; i < printer->rows->len; i++)
    {
      Row *row = g_ptr_array_index (printer->rows, i);
      int grow = expand_extra;

      if (rows > total_skip)
        g_print ("\n");

      for (j = 0; j < row->cells->len; j++)
        {
          TableColumn *col = peek_table_column (printer, j);
          gboolean expand = col ? col->expand : FALSE;
          gboolean ellipsize = col ? col->ellipsize : FALSE;
          Cell *cell = g_ptr_array_index (row->cells, j);
          char *text = cell->text;
          int len = widths[j];
          g_autofree char *freeme = NULL;

          if (col && col->skip)
            continue;

          if (expand_by > 0 && expand)
            {
              len += expand_by;
              if (grow > 0)
                {
                  len++;
                  grow--;
                }
            }

          if (shrinks[j] > 0 && ellipsize)
            {
              len -= shrinks[j];
              freeme = text = ellipsize_string_full (text, len, col->ellipsize);
            }

          if (flatpak_fancy_output ())
            {
              if (j > 0)
                g_string_append_c (row_s, ' ');
              if (cell->span)
                g_string_append (row_s, cell->text);
              else if (cell->align < 0)
                {
                  g_string_append (row_s, text);
                  string_add_spaces (row_s, len - cell_width (text));
                }
              else
                {
                  string_add_spaces (row_s, lwidths[j] - cell->align);
                  g_string_append (row_s, text);
                  string_add_spaces (row_s, widths[j] - (lwidths[j] - cell->align)  - cell_width (text));
                }
            }
          else
            g_string_append_printf (row_s, "%s%s", cell->text, (j < row->cells->len - 1) ? "\t" : "");
        }
      rows += print_row (row_s, FALSE, &skip, columns);
    }

  if (table_width)
    *table_width = width;
  if (table_height)
    *table_height = rows;
}

void
flatpak_table_printer_print (FlatpakTablePrinter *printer)
{
  int rows, cols;

  flatpak_get_window_size (&rows, &cols);
  flatpak_table_printer_print_full (printer, 0, cols, NULL, NULL);
  g_print ("\n");
}

void
flatpak_table_printer_print_json (FlatpakTablePrinter *printer)
{
  g_autoptr(JsonArray) json_array = json_array_new ();
  g_autoptr(JsonNode) root_node = NULL;
  g_autofree gchar *json_string = NULL;

  for (size_t i = 0; i < printer->rows->len; i++)
    {
      g_autoptr(JsonObject) json_object = json_object_new ();
      Row *row = g_ptr_array_index (printer->rows, i);
      
      for (size_t j = 0; j < row->cells->len; j++)
        {
          Cell *cell = g_ptr_array_index (row->cells, j);
          TableColumn *col = peek_table_column (printer, j);
          const char *title = col && col->title ? col->title : "";
          g_autofree gchar *normalized_title = g_ascii_strdown (title, -1);
          g_strdelimit (normalized_title, " ", '_');
          json_object_set_string_member (json_object, normalized_title, cell->text);
        }
      
      json_array_add_object_element (json_array, g_steal_pointer (&json_object));
    }

  root_node = json_node_new (JSON_NODE_ARRAY);
  json_node_take_array (root_node, g_steal_pointer (&json_array));

  json_string = json_to_string (root_node, TRUE);
  g_print ("%s\n", json_string);
}

int
flatpak_table_printer_get_current_row (FlatpakTablePrinter *printer)
{
  return printer->rows->len;
}

static void
set_cell (FlatpakTablePrinter *printer,
          int                  r,
          int                  c,
          const char          *text,
          int                  align,
          int                  append)
{
  Row *row;
  Cell *cell;
  char *old;

  row = (Row *) g_ptr_array_index (printer->rows, r);

  g_assert (row);

  cell = (Cell *) g_ptr_array_index (row->cells, c);
  g_assert (cell);

  old = cell->text;
  if (old != NULL && append)
    {
      if (append == 2 && *old != 0)
        cell->text = g_strconcat (old, ", ", text, NULL);
      else
        cell->text = g_strconcat (old, text, NULL);
    }
  else
    cell->text = g_strdup (text);
  cell->align = align;

  g_free (old);
}

void
flatpak_table_printer_set_cell (FlatpakTablePrinter *printer,
                                int                  r,
                                int                  c,
                                const char          *text)
{
  set_cell (printer, r, c, text, -1, 0);
}

void
flatpak_table_printer_append_cell (FlatpakTablePrinter *printer,
                                   int                  r,
                                   int                  c,
                                   const char          *text)
{
  set_cell (printer, r, c, text, -1, 1);
}

void
flatpak_table_printer_append_cell_with_comma (FlatpakTablePrinter *printer,
                                              int                  r,
                                              int                  c,
                                              const char          *text)
{
  set_cell (printer, r, c, text, -1, 2);
}

void
flatpak_table_printer_append_cell_with_comma_unique (FlatpakTablePrinter *printer,
                                                     int                  r,
                                                     int                  c,
                                                     const char          *text)
{
  Row *row;
  Cell *cell;

  row = (Row *) g_ptr_array_index (printer->rows, r);
  g_assert (row);
  cell = (Cell *) g_ptr_array_index (row->cells, c);
  g_assert (cell);

  /* Look for existing text in comma separated text */
  if (cell->text != NULL && *text != 0)
    {
      gsize len = strlen (text);
      const char *match = cell->text;
      while ((match = strstr (match, text)) != NULL)
        {
          if (match[len] == 0 || match[len] == ',' )
            return; /* Already in string, do nothing */
          /* Look for next match */
          match = match + len;
        }
    }

  set_cell (printer, r, c, text, -1, 2);
}

void
flatpak_table_printer_set_decimal_cell (FlatpakTablePrinter *printer,
                                        int                  r,
                                        int                  c,
                                        const char          *text)
{
  int align = -1;
  const char *decimal = find_decimal_point (text);

  if (decimal)
    align = decimal - text;

  set_cell (printer, r, c, text, align, 0);
}

void
flatpak_table_printer_set_column_expand (FlatpakTablePrinter *printer,
                                         int                  column,
                                         gboolean             expand)
{
  TableColumn *col = get_table_column (printer, column);

  col->expand = expand;
}

void
flatpak_table_printer_set_column_ellipsize (FlatpakTablePrinter *printer,
                                            int                  column,
                                            FlatpakEllipsizeMode mode)
{
  TableColumn *col = get_table_column (printer, column);

  col->ellipsize = mode;
}

/* Specifies that the column should be skipped if all values are the same */
void
flatpak_table_printer_set_column_skip_unique (FlatpakTablePrinter *printer,
                                              int                  column,
                                              gboolean             skip_unique)
{
  TableColumn *col = get_table_column (printer, column);

  col->skip_unique = skip_unique;
}

/* This modifies set_column_skip_unique to also require that the
 * unique value of the column must be this particular string. Useful if you
 * want to e.g. skip the arch list if everything is for the primary arch, but
 * not if everything is for a non-standard arch.
 */
void
flatpak_table_printer_set_column_skip_unique_string (FlatpakTablePrinter *printer,
                                                     int                  column,
                                                     const char          *str)
{
  TableColumn *col = get_table_column (printer, column);

  g_assert (col->skip_unique_str == NULL);

  col->skip_unique_str = g_strdup (str);
}

===== ./app/flatpak-cli-transaction.c =====
/* vi:set et sw=2 sts=2 cin cino=t0,f0,(0,{s,>2s,n-s,^-s,e-s:
 * Copyright © 2018 Red Hat, Inc
 * Copyright © 2024 GNOME Foundation, Inc.
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Alexander Larsson <alexl@redhat.com>
 *       Hubert Figuière <hub@figuiere.net>
 */

#include "config.h"

#include "flatpak-cli-transaction.h"
#include "flatpak-transaction-private.h"
#include "flatpak-installation-private.h"
#include "flatpak-run-private.h"
#include "flatpak-table-printer.h"
#include "flatpak-tty-utils-private.h"
#include "flatpak-utils-private.h"
#include "flatpak-error.h"
#include <glib/gi18n.h>


struct _FlatpakCliTransaction
{
  FlatpakTransaction   parent;

  gboolean             disable_interaction;
  gboolean             stop_on_first_error;
  gboolean             non_default_arch;
  GError              *first_operation_error;

  GHashTable          *eol_actions;
  GHashTable          *runtime_app_map;
  GHashTable          *extension_app_map;

  int                  rows;
  int                  cols;
  int                  table_width;
  int                  table_height;

  int                  n_ops;
  int                  op;
  int                  op_progress;

  gboolean             installing;
  gboolean             updating;
  gboolean             uninstalling;

  int                  download_col;

  FlatpakTablePrinter *printer;
  int                  progress_row;
  char                *progress_msg;
  int                  speed_len;

  gboolean             did_interaction;
};

struct _FlatpakCliTransactionClass
{
  FlatpakTransactionClass parent_class;
};

G_DEFINE_TYPE (FlatpakCliTransaction, flatpak_cli_transaction, FLATPAK_TYPE_TRANSACTION);

static int
choose_remote_for_ref (FlatpakTransaction *transaction,
                       const char         *for_ref,
                       const char         *runtime_ref,
                       const char * const *remotes)
{
  FlatpakCliTransaction *self = FLATPAK_CLI_TRANSACTION (transaction);
  int n_remotes = g_strv_length ((char **) remotes);
  int chosen = -1;
  const char *pref;

  pref = strchr (for_ref, '/') + 1;

  self->did_interaction = TRUE;

  if (self->disable_interaction)
    {
      g_print (_("Required runtime for %s (%s) found in remote %s\n"),
               pref, runtime_ref, remotes[0]);
      chosen = 0;
    }
  else if (n_remotes == 1)
    {
      g_print (_("Required runtime for %s (%s) found in remote %s\n"),
               pref, runtime_ref, remotes[0]);
      if (flatpak_yes_no_prompt (TRUE, _("Do you want to install it?")))
        chosen = 0;
    }
  else
    {
      flatpak_format_choices ((const char **) remotes,
                              _("Required runtime for %s (%s) found in remotes:"),
                              pref, runtime_ref);
      chosen = flatpak_number_prompt (TRUE, 0, n_remotes, _("Which do you want to install (0 to abort)?"));
      chosen -= 1; /* convert from base-1 to base-0 (and -1 to abort) */
    }

  return chosen;
}

static gboolean
add_new_remote (FlatpakTransaction            *transaction,
                FlatpakTransactionRemoteReason reason,
                const char                    *from_id,
                const char                    *remote_name,
                const char                    *url)
{
  FlatpakCliTransaction *self = FLATPAK_CLI_TRANSACTION (transaction);

  self->did_interaction = TRUE;

  if (self->disable_interaction)
    {
      g_print (_("Configuring %s as new remote '%s'\n"), url, remote_name);
      return TRUE;
    }

  if (reason == FLATPAK_TRANSACTION_REMOTE_GENERIC_REPO)
    {
      if (flatpak_yes_no_prompt (TRUE, /* default to yes on Enter */
                                 _("The remote '%s', referred to by '%s' at location %s contains additional applications.\n"
                                   "Should the remote be kept for future installations?"),
                                 remote_name, from_id, url))
        return TRUE;
    }
  else if (reason == FLATPAK_TRANSACTION_REMOTE_RUNTIME_DEPS)
    {
      if (flatpak_yes_no_prompt (TRUE, /* default to yes on Enter */
                                 _("The application %s depends on runtimes from:\n  %s\n"
                                   "Configure this as new remote '%s'"),
                                 from_id, url, remote_name))
        return TRUE;
    }

  return FALSE;
}

static void
install_authenticator (FlatpakTransaction            *old_transaction,
                       const char                    *remote,
                       const char                    *ref)
{
  FlatpakCliTransaction *old_cli = FLATPAK_CLI_TRANSACTION (old_transaction);
  g_autoptr(FlatpakTransaction)  transaction2 = NULL;
  g_autoptr(GError) local_error = NULL;
  g_autoptr(FlatpakInstallation) installation = flatpak_transaction_get_installation (old_transaction);
  g_autoptr(FlatpakDir) dir = flatpak_installation_get_dir (installation, NULL);

  if (dir == NULL)
    {
      /* This should not happen */
      g_warning ("No dir in install_authenticator");
      return;
    }

  old_cli->did_interaction = TRUE;

  transaction2 = flatpak_cli_transaction_new (dir, old_cli->disable_interaction, TRUE, FALSE, &local_error);
  if (transaction2 == NULL)
    {
      g_printerr ("Unable to install authenticator: %s\n", local_error->message);
      return;
    }

  g_print ("Installing required authenticator for remote %s\n", remote);
  if (!flatpak_transaction_add_install (transaction2, remote, ref, NULL, &local_error))
    {
      if (!g_error_matches (local_error, FLATPAK_ERROR, FLATPAK_ERROR_ALREADY_INSTALLED))
        g_printerr ("Unable to install authenticator: %s\n", local_error->message);
      return;
    }

  if (!flatpak_transaction_run (transaction2, NULL, &local_error))
    {
      if (!g_error_matches (local_error, FLATPAK_ERROR, FLATPAK_ERROR_ABORTED))
        g_printerr ("Unable to install authenticator: %s\n", local_error->message);
      return;
    }

  return;
}

static gboolean
redraw (FlatpakCliTransaction *self)
{
  int top;
  int row;
  int current_row;
  int current_col;
  int skip;

  /* We may have resized and thus repositioned the cursor since last redraw */
  flatpak_get_window_size (&self->rows, &self->cols);
  if (flatpak_get_cursor_pos (&current_row, &current_col))
    {
      /* We're currently displaying the last row of the table, extept the
         very first time where the user pressed return for the prompt causing us
         to scroll down one extra row */
      top = current_row - self->table_height + 1;
      if (top > 0)
        {
          row = top;
          skip = 0;
        }
      else
        {
          row = 1;
          skip = 1 - top;
        }

      g_print (FLATPAK_ANSI_ROW_N FLATPAK_ANSI_CLEAR, row);
      // we update table_height and end_row here, since we might have added to the table
      flatpak_table_printer_print_full (self->printer, skip, self->cols,
                                        &self->table_height, &self->table_width);
      return TRUE;
    }
  return FALSE;
}

static void
set_op_progress (FlatpakCliTransaction       *self,
                 FlatpakTransactionOperation *op,
                 const char                  *progress)
{
  if (flatpak_fancy_output ())
    {
      int row = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (op), "row"));
      g_autofree char *cell = g_strdup_printf ("[%s]", progress);
      flatpak_table_printer_set_cell (self->printer, row, 1, cell);
    }
}

static void
spin_op_progress (FlatpakCliTransaction       *self,
                  FlatpakTransactionOperation *op)
{
  const char *p[] = {
    "|",
    "/",
    "—",
    "\\",
  };

  set_op_progress (self, op, p[self->op_progress++ % G_N_ELEMENTS (p)]);
}

static char *
format_duration (guint64 duration)
{
  int h, m, s;

  m = duration / 60;
  s = duration % 60;
  h = m / 60;
  m = m % 60;

  if (h > 0)
    return g_strdup_printf ("%02d:%02d:%02d", h, m, s);
  else
    return g_strdup_printf ("%02d:%02d", m, s);
}

static void
progress_changed_cb (FlatpakTransactionProgress *progress,
                     gpointer                    data)
{
  FlatpakCliTransaction *cli = data;
  FlatpakTransaction *self = FLATPAK_TRANSACTION (cli);
  g_autoptr(FlatpakTransactionOperation) op = flatpak_transaction_get_current_operation (self);
  g_autoptr(GString) str = g_string_new ("");
  int i;
  int n_full, partial;
  g_autofree char *speed = NULL;
  int bar_length;
  const char *partial_blocks[] = {
    " ",
    "▏",
    "▎",
    "▍",
    "▌",
    "▋",
    "▊",
    "▉",
  };
  const char *full_block = "█";

  guint percent = flatpak_transaction_progress_get_progress (progress);
  guint64 start_time = flatpak_transaction_progress_get_start_time (progress);
  guint64 elapsed_time = (g_get_monotonic_time () - start_time) / G_USEC_PER_SEC;
  guint64 transferred = flatpak_transaction_progress_get_bytes_transferred (progress);
  guint64 max = flatpak_transaction_operation_get_download_size (op);

  if (elapsed_time > 0)
    {
      g_autofree char *formatted_bytes_sec = g_format_size (transferred / elapsed_time);
      g_autofree char *remaining = NULL;
      if (elapsed_time > 3 && percent > 0)
        {
          guint64 total_time = elapsed_time * 100 / (double) percent;
          remaining = format_duration (total_time - elapsed_time);
        }
      /* Formatted size/remaining time in seconds */
      speed = g_strdup_printf (_("%s/s%s%s"), formatted_bytes_sec, remaining ? "  " : "", remaining ? remaining : "");
      cli->speed_len = MAX (cli->speed_len, strlen (speed) + 2);
    }

  spin_op_progress (cli, op);

  bar_length = MIN (20, cli->table_width - (strlen (cli->progress_msg) + 6 + cli->speed_len));

  n_full = (bar_length * percent) / 100;
  partial = (((bar_length * percent) % 100) * G_N_ELEMENTS (partial_blocks)) / 100;
  /* The above should guarantee this: */
  g_assert (partial >= 0);
  g_assert (partial < G_N_ELEMENTS (partial_blocks));

  g_string_append (str, cli->progress_msg);
  g_string_append (str, " ");

  if (flatpak_fancy_output ())
    g_string_append (str, FLATPAK_ANSI_FAINT_ON);

  for (i = 0; i < n_full; i++)
    g_string_append (str, full_block);

  if (i < bar_length)
    {
      g_string_append (str, partial_blocks[partial]);
      i++;
    }

  if (flatpak_fancy_output ())
    g_string_append (str, FLATPAK_ANSI_FAINT_OFF);

  for (; i < bar_length; i++)
    g_string_append (str, " ");

  g_string_append (str, " ");
  /* Download progress percentage, use the appropriate
    percent format for your language */
  g_string_append_printf (str, _("%3d%%"), percent);

  if (speed)
    g_string_append_printf (str, "  %s", speed);

  if (flatpak_fancy_output ())
    {
      flatpak_table_printer_set_cell (cli->printer, cli->progress_row, 0, str->str);
      if (flatpak_transaction_operation_get_operation_type (op) != FLATPAK_TRANSACTION_OPERATION_UNINSTALL)
        {
          g_autofree char *formatted_max = NULL;
          g_autofree char *formatted = NULL;
          g_autofree char *text = NULL;
          int row;

          // avoid "bytes"
          formatted = transferred < 1000 ? g_format_size (1000) : g_format_size (transferred);
          formatted_max = max < 1000 ? g_format_size (1000) : g_format_size (max);

          text = g_strdup_printf ("%s / %s", formatted, formatted_max);
          row = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (op), "row"));
          flatpak_table_printer_set_decimal_cell (cli->printer, row, cli->download_col, text);
        }
      if (!redraw (cli))
        g_print ("\r%s", str->str); /* redraw failed, just update the progress */
      flatpak_pty_set_progress (percent);
    }
  else
    g_print ("%s\n", str->str);
}

static void
set_progress (FlatpakCliTransaction *self,
              const char            *text)
{
  flatpak_table_printer_set_cell (self->printer, self->progress_row, 0, text);
}

static void
new_operation (FlatpakTransaction          *transaction,
               FlatpakTransactionOperation *op,
               FlatpakTransactionProgress  *progress)
{
  FlatpakCliTransaction *self = FLATPAK_CLI_TRANSACTION (transaction);
  FlatpakTransactionOperationType op_type = flatpak_transaction_operation_get_operation_type (op);
  g_autofree char *text = NULL;

  self->op++;
  self->op_progress = 0;

  switch (op_type)
    {
    case FLATPAK_TRANSACTION_OPERATION_INSTALL_BUNDLE:
    case FLATPAK_TRANSACTION_OPERATION_INSTALL:
      if (self->n_ops == 1)
        text = g_strdup (_("Installing…"));
      else
        text = g_strdup_printf (_("Installing %d/%d…"), self->op, self->n_ops);
      break;

    case FLATPAK_TRANSACTION_OPERATION_UPDATE:
      if (self->n_ops == 1)
        text = g_strdup (_("Updating…"));
      else
        text = g_strdup_printf (_("Updating %d/%d…"), self->op, self->n_ops);
      break;

    case FLATPAK_TRANSACTION_OPERATION_UNINSTALL:
      if (self->n_ops == 1)
        text = g_strdup (_("Uninstalling…"));
      else
        text = g_strdup_printf (_("Uninstalling %d/%d…"), self->op, self->n_ops);
      break;

    default:
      g_assert_not_reached ();
      break;
    }

  if (flatpak_fancy_output ())
    {
      set_progress (self, text);
      spin_op_progress (self, op);
      redraw (self);
    }
  else
    g_print ("%s\n", text);

  g_free (self->progress_msg);
  self->progress_msg = g_steal_pointer (&text);

  g_signal_connect (progress, "changed", G_CALLBACK (progress_changed_cb), self);
  flatpak_transaction_progress_set_update_frequency (progress, FLATPAK_CLI_UPDATE_INTERVAL_MS);
}

static void
operation_done (FlatpakTransaction          *transaction,
                FlatpakTransactionOperation *op,
                const char                  *commit,
                FlatpakTransactionResult     details)
{
  FlatpakCliTransaction *self = FLATPAK_CLI_TRANSACTION (transaction);
  FlatpakTransactionOperationType op_type = flatpak_transaction_operation_get_operation_type (op);

  if (op_type == FLATPAK_TRANSACTION_OPERATION_UNINSTALL)
    set_op_progress (self, op, FLATPAK_ANSI_GREEN "-" FLATPAK_ANSI_COLOR_RESET);
  else
    set_op_progress (self, op, FLATPAK_ANSI_GREEN "✓" FLATPAK_ANSI_COLOR_RESET);

  if (flatpak_fancy_output ())
    redraw (self);
}

static gboolean
operation_error (FlatpakTransaction            *transaction,
                 FlatpakTransactionOperation   *op,
                 const GError                  *error,
                 FlatpakTransactionErrorDetails detail)
{
  FlatpakCliTransaction *self = FLATPAK_CLI_TRANSACTION (transaction);
  FlatpakTransactionOperationType op_type = flatpak_transaction_operation_get_operation_type (op);
  const char *ref = flatpak_transaction_operation_get_ref (op);
  g_autoptr(FlatpakRef) rref = flatpak_ref_parse (ref, NULL);
  gboolean non_fatal = (detail & FLATPAK_TRANSACTION_ERROR_DETAILS_NON_FATAL) != 0;
  g_autofree char *text = NULL;
  const char *on = "";
  const char *off = "";

  if (flatpak_fancy_output ())
    {
      on = FLATPAK_ANSI_BOLD_ON;
      off = FLATPAK_ANSI_BOLD_OFF;
    }

  if (g_error_matches (error, FLATPAK_ERROR, FLATPAK_ERROR_SKIPPED))
    {
      set_op_progress (self, op, "⍻");
      text = g_strdup_printf (_("Info: %s was skipped"), flatpak_ref_get_name (rref));
      if (flatpak_fancy_output ())
        {
          flatpak_table_printer_set_cell (self->printer, self->progress_row, 0, text);
          self->progress_row++;
          flatpak_table_printer_add_span (self->printer, "");
          flatpak_table_printer_finish_row (self->printer);
          redraw (self);
        }
      else
        g_print ("%s\n", text);

      return TRUE;
    }

  set_op_progress (self, op, "✗");

  /* Here we go to great lengths not to split the sentences. See
   * https://wiki.gnome.org/TranslationProject/DevGuidelines/Never%20split%20sentences
   */
  if (g_error_matches (error, FLATPAK_ERROR, FLATPAK_ERROR_ALREADY_INSTALLED))
    {
      if (non_fatal)
        text = g_strdup_printf (_("Warning: %s%s%s already installed"),
                                on, flatpak_ref_get_name (rref), off);
      else
        text = g_strdup_printf (_("Error: %s%s%s already installed"),
                                on, flatpak_ref_get_name (rref), off);
    }
  else if (g_error_matches (error, FLATPAK_ERROR, FLATPAK_ERROR_NOT_INSTALLED))
    {
      if (non_fatal)
        text = g_strdup_printf (_("Warning: %s%s%s not installed"),
                                on, flatpak_ref_get_name (rref), off);
      else
        text = g_strdup_printf (_("Error: %s%s%s not installed"),
                                on, flatpak_ref_get_name (rref), off);
    }
  else if (g_error_matches (error, FLATPAK_ERROR, FLATPAK_ERROR_NEED_NEW_FLATPAK))
    {
      if (non_fatal)
        text = g_strdup_printf (_("Warning: %s%s%s needs a later flatpak version"),
                                on, flatpak_ref_get_name (rref), off);
      else
        text = g_strdup_printf (_("Error: %s%s%s needs a later flatpak version"),
                                on, flatpak_ref_get_name (rref), off);
    }
  else if (g_error_matches (error, FLATPAK_ERROR, FLATPAK_ERROR_OUT_OF_SPACE))
    {
      if (non_fatal)
        text = g_strdup (_("Warning: Not enough disk space to complete this operation"));
      else
        text = g_strdup (_("Error: Not enough disk space to complete this operation"));
    }
  else if (error)
    {
      if (non_fatal)
        text = g_strdup_printf (_("Warning: %s"), error->message);
      else
        text = g_strdup_printf (_("Error: %s"), error->message);
    }
  else
    text = g_strdup ("(internal error, please report)");

  if (!non_fatal && self->first_operation_error == NULL)
    {
      /* Here we go to great lengths not to split the sentences. See
       * https://wiki.gnome.org/TranslationProject/DevGuidelines/Never%20split%20sentences
       */
      switch (op_type)
        {
          case FLATPAK_TRANSACTION_OPERATION_INSTALL:
            g_propagate_prefixed_error (&self->first_operation_error,
                                        g_error_copy (error),
                                        _("Failed to install %s%s%s: "),
                                        on, flatpak_ref_get_name (rref), off);
            break;

          case FLATPAK_TRANSACTION_OPERATION_UPDATE:
            g_propagate_prefixed_error (&self->first_operation_error,
                                        g_error_copy (error),
                                        _("Failed to update %s%s%s: "),
                                        on, flatpak_ref_get_name (rref), off);
            break;

          case FLATPAK_TRANSACTION_OPERATION_INSTALL_BUNDLE:
            g_propagate_prefixed_error (&self->first_operation_error,
                                        g_error_copy (error),
                                        _("Failed to install bundle %s%s%s: "),
                                        on, flatpak_ref_get_name (rref), off);
            break;

          case FLATPAK_TRANSACTION_OPERATION_UNINSTALL:
            g_propagate_prefixed_error (&self->first_operation_error,
                                        g_error_copy (error),
                                        _("Failed to uninstall %s%s%s: "),
                                        on, flatpak_ref_get_name (rref), off);
            break;

          default:
            g_assert_not_reached ();
        }
    }

  /* On a fatal error, just clear the progress line. The error will be printed in main() before exiting. */
  if (!non_fatal && self->stop_on_first_error)
    {
      if (flatpak_fancy_output ())
        {
          flatpak_table_printer_set_cell (self->printer, self->progress_row, 0, "");
          redraw (self);
        }

      return FALSE;
    }

  if (flatpak_fancy_output ())
    {
      flatpak_table_printer_set_cell (self->printer, self->progress_row, 0, text);
      self->progress_row++;
      flatpak_table_printer_add_span (self->printer, "");
      flatpak_table_printer_finish_row (self->printer);
      redraw (self);
    }
  else
    g_printerr ("%s\n", text);

  return TRUE; /* Continue */
}

static gboolean
webflow_start (FlatpakTransaction *transaction,
               const char         *remote,
               const char         *url,
               GVariant           *options,
               guint               id)
{
  FlatpakCliTransaction *self = FLATPAK_CLI_TRANSACTION (transaction);
  const char *browser;
  g_autoptr(GError) local_error = NULL;
  const char *args[3] = { NULL, url, NULL };

  self->did_interaction = TRUE;

  if (!self->disable_interaction)
    {
      g_print (_("Authentication required for remote '%s'\n"), remote);
      if (!flatpak_yes_no_prompt (TRUE, _("Open browser?")))
        return FALSE;
    }

  /* Allow hard overrides with $BROWSER */
  browser = g_getenv ("BROWSER");
  if (browser != NULL)
    {
      args[0] = browser;
      if (!g_spawn_async (NULL, (char **)args, NULL, G_SPAWN_SEARCH_PATH,
                          NULL, NULL, NULL, &local_error))
        {
          g_printerr ("Failed to start browser %s: %s\n", browser, local_error->message);
          return FALSE;
        }
    }
  else
    {
      if (!g_app_info_launch_default_for_uri (url, NULL, &local_error))
        {
          g_printerr ("Failed to show url: %s\n", local_error->message);
          return FALSE;
        }
    }

  g_print ("Waiting for browser...\n");

  return TRUE;
}

static void
webflow_done (FlatpakTransaction *transaction,
              GVariant           *options,
              guint               id)
{
  g_print ("Browser done\n");
}

static gboolean
basic_auth_start (FlatpakTransaction *transaction,
                  const char         *remote,
                  const char         *realm,
                  GVariant           *options,
                  guint               id)
{
  FlatpakCliTransaction *self = FLATPAK_CLI_TRANSACTION (transaction);
  char *user, *password, *previous_error = NULL;

  if (self->disable_interaction)
    return FALSE;

  self->did_interaction = TRUE;

  if (g_variant_lookup (options, "previous-error", "&s", &previous_error))
    g_print ("%s\n", previous_error);

  g_print (_("Login required remote %s (realm %s)\n"), remote, realm);
  user = flatpak_prompt (FALSE, _("User"));
  if (user == NULL)
    return FALSE;

  password = flatpak_password_prompt (_("Password"));
  if (password == NULL)
    return FALSE;

  flatpak_transaction_complete_basic_auth (transaction, id, user, password, NULL);
  return TRUE;
}


typedef enum {
  EOL_UNDECIDED,
  EOL_IGNORE,        /* Don't do anything, we already printed a warning */
  EOL_NO_REBASE,     /* Choose to not rebase */
  EOL_REBASE,        /* Choose to rebase */
} EolAction;

static void
print_eol_info_message (FlatpakDir        *dir,
                        FlatpakDecomposed *ref,
                        const char        *ref_name,
                        const char        *rebased_to_ref,
                        const char        *reason)
{
  gboolean is_pinned = flatpak_dir_ref_is_pinned (dir, flatpak_decomposed_get_ref (ref));
  g_autofree char *ref_branch = flatpak_decomposed_dup_branch (ref);
  const char *on = "";
  const char *off = "";

  if (flatpak_fancy_output ())
    {
      on = FLATPAK_ANSI_BOLD_ON;
      off = FLATPAK_ANSI_BOLD_OFF;
    }

  /* Here we go to great lengths not to split the sentences. See
   * https://wiki.gnome.org/TranslationProject/DevGuidelines/Never%20split%20sentences
   */
  if (rebased_to_ref)
    {
      g_autoptr(FlatpakDecomposed) eolr_decomposed = NULL;
      g_autofree char *eolr_name = NULL;
      const char *eolr_branch;

      eolr_decomposed = flatpak_decomposed_new_from_ref (rebased_to_ref, NULL);

      /* These are guarantees from FlatpakTransaction */
      g_assert (eolr_decomposed != NULL);
      g_assert (flatpak_decomposed_get_kind (ref) == flatpak_decomposed_get_kind (eolr_decomposed));

      eolr_name = flatpak_decomposed_dup_id (eolr_decomposed);
      eolr_branch = flatpak_decomposed_get_branch (eolr_decomposed);

      if (is_pinned)
        {
          /* Only runtimes can be pinned */
          g_print (_("\nInfo: (pinned) runtime %s%s%s branch %s%s%s is end-of-life, in favor of %s%s%s branch %s%s%s\n"),
                   on, ref_name, off, on, ref_branch, off, on, eolr_name, off, on, eolr_branch, off);
        }
      else
        {
          if (flatpak_decomposed_is_runtime (ref))
            g_print (_("\nInfo: runtime %s%s%s branch %s%s%s is end-of-life, in favor of %s%s%s branch %s%s%s\n"),
                     on, ref_name, off, on, ref_branch, off, on, eolr_name, off, on, eolr_branch, off);
          else
            g_print (_("\nInfo: app %s%s%s branch %s%s%s is end-of-life, in favor of %s%s%s branch %s%s%s\n"),
                     on, ref_name, off, on, ref_branch, off, on, eolr_name, off, on, eolr_branch, off);
        }
    }
  else if (reason)
    {
      g_autofree char *escaped_reason = flatpak_escape_string (reason,
                                                               FLATPAK_ESCAPE_ALLOW_NEWLINES |
                                                               FLATPAK_ESCAPE_DO_NOT_QUOTE);
      if (is_pinned)
        {
          /* Only runtimes can be pinned */
          g_print (_("\nInfo: (pinned) runtime %s%s%s branch %s%s%s is end-of-life, with reason:\n"),
                   on, ref_name, off, on, ref_branch, off);
        }
      else
        {
          if (flatpak_decomposed_is_runtime (ref))
            g_print (_("\nInfo: runtime %s%s%s branch %s%s%s is end-of-life, with reason:\n"),
                     on, ref_name, off, on, ref_branch, off);
          else
            g_print (_("\nInfo: app %s%s%s branch %s%s%s is end-of-life, with reason:\n"),
                     on, ref_name, off, on, ref_branch, off);
        }
      g_print ("   %s\n", escaped_reason);
    }
}

static void
check_current_transaction_for_dependent_apps (GPtrArray          *apps,
                                              FlatpakTransaction *transaction,
                                              FlatpakDecomposed  *ref)
{
  g_autoptr(FlatpakTransactionOperation) ref_op = NULL;
  GPtrArray *related_ops;

  ref_op = flatpak_transaction_get_operation_for_ref (transaction, NULL, flatpak_decomposed_get_ref (ref), NULL);
  g_assert (ref_op != NULL);

  /* Get the related ops to find any apps that use @ref as a runtime or extension */
  related_ops = flatpak_transaction_operation_get_related_to_ops (ref_op);
  if (related_ops == NULL)
    return;

  for (int i = 0; i < related_ops->len; i++)
    {
      FlatpakTransactionOperation *related_op = g_ptr_array_index (related_ops, i);
      const char *related_op_ref = flatpak_transaction_operation_get_ref (related_op);
      g_autoptr(FlatpakDecomposed) related_op_decomposed = flatpak_decomposed_new_from_ref (related_op_ref, NULL);

      if (related_op_decomposed == NULL)
        continue;
      if (flatpak_decomposed_id_is_subref (related_op_decomposed))
        continue;

      /* Recurse in case @ref was a runtime extension. We need to check since a
       * runtime can have a runtime extension in its related ops in the
       * extra-data case, so if we recurse unconditionally it could be infinite
       * recursion.
       */
      if (flatpak_decomposed_is_runtime (related_op_decomposed))
        {
          GKeyFile *metadata = flatpak_transaction_operation_get_metadata (ref_op);
          if (g_key_file_has_group (metadata, FLATPAK_METADATA_GROUP_EXTENSION_OF))
            check_current_transaction_for_dependent_apps (apps, transaction, related_op_decomposed);
        }
      else if (!g_ptr_array_find_with_equal_func (apps, related_op_decomposed, (GEqualFunc)flatpak_decomposed_equal, NULL))
        g_ptr_array_add (apps, g_steal_pointer (&related_op_decomposed));
    }
}

static GPtrArray *
find_reverse_dep_apps (FlatpakTransaction *transaction,
                       FlatpakDir         *dir,
                       FlatpakDecomposed  *ref,
                       gboolean           *out_is_extension)
{
  FlatpakCliTransaction *self = FLATPAK_CLI_TRANSACTION (transaction);
  g_autoptr(GPtrArray) apps = NULL;
  g_autoptr(GError) local_error = NULL;

  g_assert (out_is_extension);

  *out_is_extension = flatpak_dir_is_runtime_extension (dir, ref);
  if (*out_is_extension)
    {
      /* Find apps which are using the ref as an extension directly or as an
       * extension of their runtime.
       */
      apps = flatpak_dir_list_app_refs_with_runtime_extension (dir,
                                                               &self->runtime_app_map,
                                                               &self->extension_app_map,
                                                               ref, NULL, &local_error);
      if (apps == NULL)
        {
          g_info ("Unable to list apps using extension %s: %s\n",
                  flatpak_decomposed_get_ref (ref), local_error->message);
          return NULL;
        }
    }
  else
    {
      /* Find any apps using the runtime directly */
      apps = flatpak_dir_list_app_refs_with_runtime (dir, &self->runtime_app_map, ref,
                                                     NULL, &local_error);
      if (apps == NULL)
        {
          g_info ("Unable to find apps using runtime %s: %s\n",
                  flatpak_decomposed_get_ref (ref), local_error->message);
          return NULL;
        }
    }

  /* Also check the current transaction since it's possible the EOL ref
   * and/or any app(s) that depend on it are not installed. It's also
   * possible the current transaction updates one of the apps to a
   * newer runtime but we don't handle that yet
   * (https://github.com/flatpak/flatpak/issues/4832)
   */
  check_current_transaction_for_dependent_apps (apps, transaction, ref);

  return g_steal_pointer (&apps);
}

static gboolean
end_of_lifed_with_rebase (FlatpakTransaction *transaction,
                          const char         *remote,
                          const char         *ref_str,
                          const char         *reason,
                          const char         *rebased_to_ref,
                          const char        **previous_ids)
{
  FlatpakCliTransaction *self = FLATPAK_CLI_TRANSACTION (transaction);
  g_autoptr(FlatpakDecomposed) ref = flatpak_decomposed_new_from_ref (ref_str, NULL);
  g_autofree char *name = NULL;
  EolAction action = EOL_UNDECIDED;
  EolAction old_action = EOL_UNDECIDED;
  gboolean can_rebase = rebased_to_ref != NULL && remote != NULL;
  g_autoptr(FlatpakInstallation) installation = flatpak_transaction_get_installation (transaction);
  g_autoptr(FlatpakDir) dir = flatpak_installation_get_dir (installation, NULL);

  if (ref == NULL)
    return FALSE; /* Shouldn't happen, the ref should be valid */

  name = flatpak_decomposed_dup_id (ref);

  self->did_interaction = TRUE;

  if (flatpak_decomposed_id_is_subref (ref))
    {
      GLNX_HASH_TABLE_FOREACH_KV (self->eol_actions, FlatpakDecomposed *, eoled_ref, gpointer, value)
        {
          guint old_eol_action = GPOINTER_TO_UINT (value);

          if (flatpak_decomposed_id_is_subref_of (ref, eoled_ref))
              {
                old_action = old_eol_action; /* Do the same */
                break;
              }
        }
    }

  if (old_action != EOL_UNDECIDED)
    {
      switch (old_action)
        {
        default:
        case EOL_IGNORE:
          if (!can_rebase)
            action = EOL_IGNORE;
          /* Else, ask if we want to rebase */
          break;
        case EOL_REBASE:
        case EOL_NO_REBASE:
          if (can_rebase)
            action = old_action;
          else
            action = EOL_IGNORE;
        }
    }

  if (action == EOL_UNDECIDED)
    {
      action = EOL_IGNORE;

      print_eol_info_message (dir, ref, name, rebased_to_ref, reason);

      if (flatpak_decomposed_is_runtime (ref) && !rebased_to_ref)
        {
          gboolean is_extension;
          g_autoptr(GPtrArray) apps = find_reverse_dep_apps (transaction, dir, ref, &is_extension);

          if (apps && apps->len > 0)
            {
              if (is_extension)
                g_print (_("Info: applications using this extension:\n"));
              else
                g_print (_("Info: applications using this runtime:\n"));

              g_print ("   ");
              for (guint i = 0; i < apps->len; i++)
                {
                  FlatpakDecomposed *app_ref = g_ptr_array_index (apps, i);
                  g_autofree char *id = flatpak_decomposed_dup_id (app_ref);
                  if (i != 0)
                    g_print (", ");
                  g_print ("%s", id);
                }
              g_print ("\n");
            }
        }

      if (rebased_to_ref && remote)
        {
          /* The context for this prompt is in print_eol_info_message() */
          if (self->disable_interaction ||
              flatpak_yes_no_prompt (TRUE, _("Replace?")))
            {
              if (self->disable_interaction)
                g_print (_("Updating to rebased version\n"));

              action = EOL_REBASE;
            }
          else
            action = EOL_NO_REBASE;
        }
    }
  else
    {
      g_info ("%s is end-of-life, using action from parent ref", name);
    }

  /* Cache for later comparison and reuse */
  g_hash_table_insert (self->eol_actions, flatpak_decomposed_ref (ref), GUINT_TO_POINTER (action));

  if (action == EOL_REBASE)
    {
      g_autoptr(GError) error = NULL;

      if (!flatpak_transaction_add_rebase_and_uninstall (transaction, remote, rebased_to_ref, ref_str, NULL, previous_ids, &error))
        {
          g_propagate_prefixed_error (&self->first_operation_error,
                                      g_error_copy (error),
                                      _("Failed to rebase %s to %s: "),
                                      name, rebased_to_ref);
          return FALSE;
        }

      return TRUE; /* skip install/update op of end-of-life ref */
    }
  else /* IGNORE or NO_REBASE */
    return FALSE;
}

static int
cmpstringp (const void *p1, const void *p2)
{
  return strcmp (*(char * const *) p1, *(char * const *) p2);
}

static void
append_permissions (GPtrArray  *permissions,
                    GKeyFile   *metadata,
                    GKeyFile   *old_metadata,
                    const char *group)
{
  g_auto(GStrv) options = g_key_file_get_string_list (metadata, FLATPAK_METADATA_GROUP_CONTEXT, group, NULL, NULL);
  g_auto(GStrv) old_options = NULL;
  int i;

  if (options == NULL)
    return;

  qsort (options, g_strv_length (options), sizeof (const char *), cmpstringp);

  if (old_metadata)
    old_options = g_key_file_get_string_list (old_metadata, FLATPAK_METADATA_GROUP_CONTEXT, group, NULL, NULL);

  for (i = 0; options[i] != NULL; i++)
    {
      const char *option = options[i];
      if (option[0] == '!')
        continue;

      if (old_options && g_strv_contains ((const char * const *) old_options, option))
        continue;

      if (strcmp (group, FLATPAK_METADATA_KEY_DEVICES) == 0 && strcmp (option, "all") == 0)
        option = "devices";

      g_ptr_array_add (permissions, g_strdup (option));
    }
}

static void
append_bus (GPtrArray  *talk,
            GPtrArray  *own,
            GKeyFile   *metadata,
            GKeyFile   *old_metadata,
            const char *group)
{
  g_auto(GStrv) keys = NULL;
  gsize i, keys_count;

  keys = g_key_file_get_keys (metadata, group, &keys_count, NULL);
  if (keys == NULL)
    return;

  qsort (keys, g_strv_length (keys), sizeof (const char *), cmpstringp);

  for (i = 0; i < keys_count; i++)
    {
      const char *key = keys[i];
      g_autofree char *value = g_key_file_get_string (metadata, group, key, NULL);

      if (g_strcmp0 (value, "none") == 0)
        continue;

      if (old_metadata)
        {
          g_autofree char *old_value = g_key_file_get_string (old_metadata, group, key, NULL);
          if (g_strcmp0 (old_value, value) == 0)
            continue;
        }

      if (g_strcmp0 (value, "own") == 0)
        g_ptr_array_add (own, g_strdup (key));
      else
        g_ptr_array_add (talk, g_strdup (key));
    }
}

static void
append_usb (GPtrArray *usb_array,
            GKeyFile  *metadata,
            GKeyFile  *old_metadata)
{
  gsize size = 0;
  g_auto(GStrv) hidden_devices = NULL;
  g_auto(GStrv) old_hidden_devices = NULL;
  g_auto(GStrv) old_enumerables = NULL;
  g_auto(GStrv) enumerables = NULL;

  enumerables = g_key_file_get_string_list (metadata,
                                            FLATPAK_METADATA_GROUP_USB_DEVICES,
                                            FLATPAK_METADATA_KEY_USB_ENUMERABLE_DEVICES,
                                            &size, NULL);

  if (old_metadata)
    old_enumerables = g_key_file_get_string_list (old_metadata,
                                                  FLATPAK_METADATA_GROUP_USB_DEVICES,
                                                  FLATPAK_METADATA_KEY_USB_ENUMERABLE_DEVICES,
                                                  NULL, NULL);

  for (size_t i = 0; i < size; i++)
    {
      const char *enumerable = enumerables[i];
      if (old_enumerables == NULL || !g_strv_contains ((const char * const *) old_enumerables, enumerable))
        g_ptr_array_add (usb_array, g_strdup (enumerable));
    }

  size = 0;

  hidden_devices = g_key_file_get_string_list (metadata,
                                               FLATPAK_METADATA_GROUP_USB_DEVICES,
                                               FLATPAK_METADATA_KEY_USB_HIDDEN_DEVICES,
                                               &size, NULL);

  if (old_metadata)
    old_hidden_devices = g_key_file_get_string_list (old_metadata,
                                                     FLATPAK_METADATA_GROUP_USB_DEVICES,
                                                     FLATPAK_METADATA_KEY_USB_HIDDEN_DEVICES,
                                                     NULL, NULL);

  for (size_t i = 0; i < size; i++)
    {
      const char *hidden = hidden_devices[i];
      if (old_hidden_devices == NULL || !g_strv_contains ((const char * const *) old_hidden_devices, hidden))
        g_ptr_array_add (usb_array, g_strdup_printf ("!%s", hidden));
    }
}

static void
append_tags (GPtrArray *tags_array,
             GKeyFile  *metadata,
             GKeyFile  *old_metadata)
{
  gsize i, size = 0;
  g_auto(GStrv) tags = g_key_file_get_string_list (metadata, FLATPAK_METADATA_GROUP_APPLICATION, "tags",
                                                   &size, NULL);
  g_auto(GStrv) old_tags = NULL;

  if (old_metadata)
    old_tags = g_key_file_get_string_list (old_metadata, FLATPAK_METADATA_GROUP_APPLICATION, "tags",
                                           NULL, NULL);

  for (i = 0; i < size; i++)
    {
      const char *tag = tags[i];
      if (old_tags == NULL || !g_strv_contains ((const char * const *) old_tags, tag))
        g_ptr_array_add (tags_array, g_strdup (tag));
    }
}

static void
print_perm_line (int        idx,
                 GPtrArray *items,
                 int        cols)
{
  g_autoptr(GString) res = g_string_new (NULL);
  g_autofree char *escaped_first_perm = NULL;
  int i;

  escaped_first_perm = flatpak_escape_string (items->pdata[0], FLATPAK_ESCAPE_DEFAULT);
  g_string_append_printf (res, "    [%d] %s", idx, escaped_first_perm);

  for (i = 1; i < items->len; i++)
    {
      g_autofree char *escaped = flatpak_escape_string (items->pdata[i],
                                                        FLATPAK_ESCAPE_DEFAULT);
      char *p;
      int len;

      p = strrchr (res->str, '\n');
      if (!p)
        p = res->str;

      len = (res->str + strlen (res->str)) - p;
      if (len + strlen (escaped) + 2 >= cols)
        g_string_append_printf (res, ",\n        %s", escaped);
      else
        g_string_append_printf (res, ", %s", escaped);
    }

  g_print ("%s\n", res->str);
}

static void
print_permissions (FlatpakCliTransaction *self,
                   const char            *ref,
                   GKeyFile              *metadata,
                   GKeyFile              *old_metadata)
{
  g_autoptr(FlatpakRef) rref = flatpak_ref_parse (ref, NULL);
  g_autoptr(GPtrArray) permissions = g_ptr_array_new_with_free_func (g_free);
  g_autoptr(GPtrArray) files = g_ptr_array_new_with_free_func (g_free);
  g_autoptr(GPtrArray) usb = g_ptr_array_new_with_free_func (g_free);
  g_autoptr(GPtrArray) session_bus_talk = g_ptr_array_new_with_free_func (g_free);
  g_autoptr(GPtrArray) session_bus_own = g_ptr_array_new_with_free_func (g_free);
  g_autoptr(GPtrArray) system_bus_talk = g_ptr_array_new_with_free_func (g_free);
  g_autoptr(GPtrArray) system_bus_own = g_ptr_array_new_with_free_func (g_free);
  g_autoptr(GPtrArray) tags = g_ptr_array_new_with_free_func (g_free);
  g_autoptr(FlatpakTablePrinter) printer = NULL;
  int max_permission_width;
  int n_permission_cols;
  int i, j;
  int rows, cols;
  int table_rows, table_cols;
  const char *on = "";
  const char *off = "";

  if (flatpak_fancy_output ())
    {
      on = FLATPAK_ANSI_BOLD_ON;
      off = FLATPAK_ANSI_BOLD_OFF;
    }

  if (metadata == NULL)
    return;

  /* Only apps have permissions */
  if (flatpak_ref_get_kind (rref) != FLATPAK_REF_KIND_APP)
    return;

  append_permissions (permissions, metadata, old_metadata, FLATPAK_METADATA_KEY_SHARED);
  append_permissions (permissions, metadata, old_metadata, FLATPAK_METADATA_KEY_SOCKETS);
  append_permissions (permissions, metadata, old_metadata, FLATPAK_METADATA_KEY_DEVICES);
  append_permissions (permissions, metadata, old_metadata, FLATPAK_METADATA_KEY_FEATURES);
  append_permissions (files, metadata, old_metadata, FLATPAK_METADATA_KEY_FILESYSTEMS);
  append_usb (usb, metadata, old_metadata);
  append_bus (session_bus_talk, session_bus_own,
              metadata, old_metadata, FLATPAK_METADATA_GROUP_SESSION_BUS_POLICY);
  append_bus (system_bus_talk, system_bus_own,
              metadata, old_metadata, FLATPAK_METADATA_GROUP_SYSTEM_BUS_POLICY);
  append_tags (tags, metadata, old_metadata);

  j = 1;
  if (files->len > 0)
    g_ptr_array_add (permissions, g_strdup_printf ("file access [%d]", j++));
  if (session_bus_talk->len > 0)
    g_ptr_array_add (permissions, g_strdup_printf ("dbus access [%d]", j++));
  if (session_bus_own->len > 0)
    g_ptr_array_add (permissions, g_strdup_printf ("bus ownership [%d]", j++));
  if (system_bus_talk->len > 0)
    g_ptr_array_add (permissions, g_strdup_printf ("system dbus access [%d]", j++));
  if (system_bus_own->len > 0)
    g_ptr_array_add (permissions, g_strdup_printf ("system bus ownership [%d]", j++));
  if (usb->len > 0)
    g_ptr_array_add (permissions, g_strdup_printf ("USB portal access [%d]", j++));
  if (tags->len > 0)
    g_ptr_array_add (permissions, g_strdup_printf ("tags [%d]", j++));

  /* Early exit if no (or no new) permissions */
  if (permissions->len == 0)
    return;

  g_print ("\n");

  if (old_metadata)
    g_print (_("New %s%s%s permissions:"), on, flatpak_ref_get_name (rref), off);
  else
    g_print (_("%s%s%s permissions:"), on, flatpak_ref_get_name (rref), off);

  g_print ("\n");

  flatpak_get_window_size (&rows, &cols);
  max_permission_width = 0;
  for (i = 0; i < permissions->len; i++)
    max_permission_width = MAX (max_permission_width, strlen (g_ptr_array_index (permissions, i)));

  /* At least 4 columns, but more if we're guaranteed to fit */
  n_permission_cols =  MAX (4, cols / (max_permission_width + 4));

  printer = flatpak_table_printer_new ();
  for (i = 0; i < permissions->len; i++)
    {
      char *perm = g_ptr_array_index (permissions, i);
      if (i % n_permission_cols == 0)
        {
          g_autofree char *text = NULL;

          if (i > 0)
            flatpak_table_printer_finish_row (printer);

          text = g_strdup_printf ("    %s", perm);
          flatpak_table_printer_add_column (printer, text);
        }
      else
        flatpak_table_printer_add_column (printer, perm);
    }
  flatpak_table_printer_finish_row (printer);

  for (i = 0; i < n_permission_cols; i++)
    flatpak_table_printer_set_column_expand (printer, i, TRUE);

  flatpak_table_printer_print_full (printer, 0, cols, &table_rows, &table_cols);

  g_print ("\n\n");

  j = 1;
  if (files->len > 0)
    print_perm_line (j++, files, cols);
  if (session_bus_talk->len > 0)
    print_perm_line (j++, session_bus_talk, cols);
  if (session_bus_own->len > 0)
    print_perm_line (j++, session_bus_own, cols);
  if (system_bus_talk->len > 0)
    print_perm_line (j++, system_bus_talk, cols);
  if (system_bus_own->len > 0)
    print_perm_line (j++, system_bus_own, cols);
  if (usb->len > 0)
    print_perm_line (j++, usb, cols);
  if (tags->len > 0)
    print_perm_line (j++, tags, cols);
}

static void
message_handler (const gchar   *log_domain,
                 GLogLevelFlags log_level,
                 const gchar   *message,
                 gpointer       user_data)
{
  FlatpakCliTransaction *self = FLATPAK_CLI_TRANSACTION (user_data);
  g_autofree char *text = NULL;

  text = g_strconcat (_("Warning: "), message, NULL);

  if (flatpak_fancy_output ())
    {
      flatpak_table_printer_set_cell (self->printer, self->progress_row, 0, text);
      self->progress_row++;
      flatpak_table_printer_add_span (self->printer, "");
      flatpak_table_printer_finish_row (self->printer);
      redraw (self);
    }
  else
    g_print ("%s\n", text);
}

static gboolean
transaction_ready_pre_auth (FlatpakTransaction *transaction)
{
  FlatpakCliTransaction *self = FLATPAK_CLI_TRANSACTION (transaction);
  g_autolist(FlatpakTransactionOperation) ops = flatpak_transaction_get_operations (transaction);
  GList *l;
  int i;
  FlatpakTablePrinter *printer;
  const char *op_shorthand[] = { "i", "u", "i", "r", "i" };

  /* These caches may no longer be valid once the transaction runs */
  g_clear_pointer (&self->runtime_app_map, g_hash_table_unref);
  g_clear_pointer (&self->extension_app_map, g_hash_table_unref);

  if (ops == NULL)
    return TRUE;

  self->n_ops = g_list_length (ops);

  for (l = ops; l != NULL; l = l->next)
    {
      FlatpakTransactionOperation *op = l->data;
      FlatpakTransactionOperationType type = flatpak_transaction_operation_get_operation_type (op);

      switch (type)
        {
        case FLATPAK_TRANSACTION_OPERATION_UNINSTALL:
          self->uninstalling = TRUE;
          break;

        case FLATPAK_TRANSACTION_OPERATION_INSTALL:
        case FLATPAK_TRANSACTION_OPERATION_INSTALL_BUNDLE:
          self->installing = TRUE;
          break;

        case FLATPAK_TRANSACTION_OPERATION_UPDATE:
          self->updating = TRUE;
          break;

        default:;
        }
    }

  /* first, show permissions */
  for (l = ops; l != NULL; l = l->next)
    {
      FlatpakTransactionOperation *op = l->data;
      FlatpakTransactionOperationType type = flatpak_transaction_operation_get_operation_type (op);

      if (type == FLATPAK_TRANSACTION_OPERATION_INSTALL ||
          type == FLATPAK_TRANSACTION_OPERATION_INSTALL_BUNDLE ||
          type == FLATPAK_TRANSACTION_OPERATION_UPDATE)
        {
          const char *ref = flatpak_transaction_operation_get_ref (op);
          GKeyFile *metadata = flatpak_transaction_operation_get_metadata (op);
          GKeyFile *old_metadata = flatpak_transaction_operation_get_old_metadata (op);

          print_permissions (self, ref, metadata, old_metadata);
        }
    }

  g_print ("\n");

  printer = self->printer = flatpak_table_printer_new ();
  i = 0;

  flatpak_table_printer_set_column_title (printer, i++, "   ");
  flatpak_table_printer_set_column_title (printer, i++, "   ");

  flatpak_table_printer_set_column_expand (printer, i, TRUE);
  flatpak_table_printer_set_column_title (printer, i++, _("ID"));

  flatpak_table_printer_set_column_expand (printer, i, TRUE);
  if (!self->non_default_arch)
    {
      flatpak_table_printer_set_column_skip_unique (printer, i, TRUE);
      flatpak_table_printer_set_column_skip_unique_string (printer, i, flatpak_get_arch ());
    }
  flatpak_table_printer_set_column_title (printer, i++, _("Arch"));

  flatpak_table_printer_set_column_expand (printer, i, TRUE);
  flatpak_table_printer_set_column_title (printer, i++, _("Branch"));

  flatpak_table_printer_set_column_expand (printer, i, TRUE);
  /* translators: This is short for operation, the title of a one-char column */
  flatpak_table_printer_set_column_title (printer, i++, _("Op"));

  if (self->installing || self->updating)
    {
      g_autofree char *text1 = NULL;
      g_autofree char *text2 = NULL;
      g_autofree char *text = NULL;
      int size;

      flatpak_table_printer_set_column_expand (printer, i, TRUE);
      flatpak_table_printer_set_column_title (printer, i++, _("Remote"));
      self->download_col = i;

      /* Avoid resizing the download column too much,
       * by making the title as long as typical content
       */
      text1 = g_strdup_printf ("< 999.9 kB (%s)", _("partial"));
      text2 = g_strdup_printf ("  123.4 MB / 999.9 MB");
      size = MAX (strlen (text1), strlen (text2));
      /* Translators: Download is used here as a noun */
      text = g_strdup_printf ("%-*s", size, _("Download"));
      flatpak_table_printer_set_column_title (printer, i++, text);
    }

  for (l = ops, i = 1; l != NULL; l = l->next, i++)
    {
      FlatpakTransactionOperation *op = l->data;
      FlatpakTransactionOperationType type = flatpak_transaction_operation_get_operation_type (op);
      FlatpakDecomposed *ref = flatpak_transaction_operation_get_decomposed (op);
      const char *remote = flatpak_transaction_operation_get_remote (op);
      g_autofree char *id = flatpak_decomposed_dup_id (ref);
      const char *branch = flatpak_decomposed_get_branch (ref);
      g_autofree char *arch = flatpak_decomposed_dup_arch (ref);
      g_autofree char *rownum = g_strdup_printf ("%2d.", i);

      flatpak_table_printer_add_column (printer, rownum);
      flatpak_table_printer_add_column (printer, "   ");
      flatpak_table_printer_add_column (printer, id);
      flatpak_table_printer_add_column (printer, arch);
      flatpak_table_printer_add_column (printer, branch);
      flatpak_table_printer_add_column (printer, op_shorthand[type]);

      if (type == FLATPAK_TRANSACTION_OPERATION_INSTALL ||
          type == FLATPAK_TRANSACTION_OPERATION_INSTALL_BUNDLE ||
          type == FLATPAK_TRANSACTION_OPERATION_UPDATE)
        {
          guint64 download_size;
          g_autofree char *formatted = NULL;
          g_autofree char *text = NULL;
          const char *prefix;

          download_size = flatpak_transaction_operation_get_download_size (op);
          formatted = g_format_size (download_size);

          if (download_size > 0)
            prefix = "< ";
          else
            prefix = "";

          flatpak_table_printer_add_column (printer, remote);
          if (flatpak_transaction_operation_get_subpaths (op) != NULL)
            text = g_strdup_printf ("%s%s (%s)", prefix, formatted, _("partial"));
          else
            text = g_strdup_printf ("%s%s", prefix, formatted);
          flatpak_table_printer_add_decimal_column (printer, text);
        }

      g_object_set_data (G_OBJECT (op), "row", GINT_TO_POINTER (flatpak_table_printer_get_current_row (printer)));
      flatpak_table_printer_finish_row (printer);
    }

  flatpak_get_window_size (&self->rows, &self->cols);

  g_print ("\n");

  flatpak_table_printer_print_full (printer, 0, self->cols,
                                    &self->table_height, &self->table_width);

  g_print ("\n");

  if (!self->disable_interaction)
    {
      g_autoptr(FlatpakInstallation) installation = flatpak_transaction_get_installation (transaction);
      const char *name;
      const char *id;
      gboolean ret;

      g_print ("\n");

      name = flatpak_installation_get_display_name (installation);
      id = flatpak_installation_get_id (installation);

      if (flatpak_installation_get_is_user (installation))
        ret = flatpak_yes_no_prompt (TRUE, _("Proceed with these changes to the user installation?"));
      else if (g_strcmp0 (id, SYSTEM_DIR_DEFAULT_ID) == 0)
        ret = flatpak_yes_no_prompt (TRUE, _("Proceed with these changes to the system installation?"));
      else
        ret = flatpak_yes_no_prompt (TRUE, _("Proceed with these changes to the %s?"), name);

      if (!ret)
        return FALSE;
    }
  else
    g_print ("\n\n");

  self->did_interaction = FALSE;

  return TRUE;
}

static gboolean
transaction_ready (FlatpakTransaction *transaction)
{
  FlatpakCliTransaction *self = FLATPAK_CLI_TRANSACTION (transaction);
  GList *ops = flatpak_transaction_get_operations (transaction);
  GList *l;
  FlatpakTablePrinter *printer;

  if (ops == NULL)
    return TRUE;

  printer = self->printer;

  if (self->did_interaction)
    {
      /* We did some interaction since ready_pre_auth which messes up the formatting, so re-print table */
      flatpak_table_printer_print_full (printer, 0, self->cols,
                                        &self->table_height, &self->table_width);
      g_print ("\n\n");
    }

  for (l = ops; l; l = l->next)
    {
      FlatpakTransactionOperation *op = l->data;
      set_op_progress (self, op, " ");
    }

  g_list_free_full (ops, g_object_unref);

  flatpak_table_printer_add_span (printer, "");
  flatpak_table_printer_finish_row (printer);
  flatpak_table_printer_add_span (printer, "");
  self->progress_row = flatpak_table_printer_get_current_row (printer);
  flatpak_table_printer_finish_row (printer);

  self->table_height += 3; /* 2 for the added lines and one for the newline from the user after the prompt */

  if (flatpak_fancy_output ())
    {
      flatpak_hide_cursor ();
      flatpak_enable_raw_mode ();
      redraw (self);
    }

  g_log_set_handler (G_LOG_DOMAIN, G_LOG_LEVEL_MESSAGE | G_LOG_LEVEL_WARNING, message_handler, transaction);

  return TRUE;
}

static void
flatpak_cli_transaction_finalize (GObject *object)
{
  FlatpakCliTransaction *self = FLATPAK_CLI_TRANSACTION (object);

  if (self->first_operation_error)
    g_error_free (self->first_operation_error);

  g_free (self->progress_msg);

  g_hash_table_unref (self->eol_actions);

  if (self->runtime_app_map)
    g_hash_table_unref (self->runtime_app_map);

  if (self->extension_app_map)
    g_hash_table_unref (self->extension_app_map);

  if (self->printer)
    flatpak_table_printer_free (self->printer);

  G_OBJECT_CLASS (flatpak_cli_transaction_parent_class)->finalize (object);
}

static void
flatpak_cli_transaction_init (FlatpakCliTransaction *self)
{
  self->eol_actions = g_hash_table_new_full ((GHashFunc)flatpak_decomposed_hash, (GEqualFunc)flatpak_decomposed_equal,
                                             (GDestroyNotify)flatpak_decomposed_unref, NULL);
}

static gboolean flatpak_cli_transaction_run (FlatpakTransaction *transaction,
                                             GCancellable       *cancellable,
                                             GError            **error);

static void
flatpak_cli_transaction_class_init (FlatpakCliTransactionClass *klass)
{
  GObjectClass *object_class = G_OBJECT_CLASS (klass);
  FlatpakTransactionClass *transaction_class = FLATPAK_TRANSACTION_CLASS (klass);

  object_class->finalize = flatpak_cli_transaction_finalize;
  transaction_class->add_new_remote = add_new_remote;
  transaction_class->ready = transaction_ready;
  transaction_class->ready_pre_auth = transaction_ready_pre_auth;
  transaction_class->new_operation = new_operation;
  transaction_class->operation_done = operation_done;
  transaction_class->operation_error = operation_error;
  transaction_class->choose_remote_for_ref = choose_remote_for_ref;
  transaction_class->end_of_lifed_with_rebase = end_of_lifed_with_rebase;
  transaction_class->run = flatpak_cli_transaction_run;
  transaction_class->webflow_start = webflow_start;
  transaction_class->webflow_done = webflow_done;
  transaction_class->basic_auth_start = basic_auth_start;
  transaction_class->install_authenticator = install_authenticator;
}

FlatpakTransaction *
flatpak_cli_transaction_new (FlatpakDir *dir,
                             gboolean    disable_interaction,
                             gboolean    stop_on_first_error,
                             gboolean    non_default_arch,
                             GError    **error)
{
  g_autoptr(FlatpakInstallation) installation = NULL;
  g_autoptr(FlatpakCliTransaction) self = NULL;

  installation = flatpak_installation_new_for_dir (dir, NULL, error);
  if (installation == NULL)
    return NULL;

  self = g_initable_new (FLATPAK_TYPE_CLI_TRANSACTION,
                         NULL, error,
                         "installation", installation,
                         NULL);
  if (self == NULL)
    return NULL;

  self->disable_interaction = disable_interaction;
  self->stop_on_first_error = stop_on_first_error;
  self->non_default_arch = non_default_arch;

  flatpak_transaction_set_no_interaction (FLATPAK_TRANSACTION (self), disable_interaction);
  flatpak_transaction_add_default_dependency_sources (FLATPAK_TRANSACTION (self));

  return (FlatpakTransaction *) g_steal_pointer (&self);
}

static gboolean
flatpak_cli_transaction_run (FlatpakTransaction *transaction,
                             GCancellable       *cancellable,
                             GError            **error)
{
  FlatpakCliTransaction *self = FLATPAK_CLI_TRANSACTION (transaction);
  gboolean res;

  res = FLATPAK_TRANSACTION_CLASS (flatpak_cli_transaction_parent_class)->run (transaction, cancellable, error);

  if (flatpak_fancy_output ())
    {
      flatpak_pty_clear_progress ();
      flatpak_disable_raw_mode ();
      flatpak_show_cursor ();
    }

  if (res && self->n_ops > 0)
    {
      const char *text;

      if (self->uninstalling + self->installing + self->updating > 1)
        text = _("Changes complete.");
      else if (self->uninstalling)
        text = _("Uninstall complete.");
      else if (self->installing)
        text = _("Installation complete.");
      else
        text = _("Updates complete.");

      if (flatpak_fancy_output ())
        {
          set_progress (self, text);
          redraw (self);
        }
      else
        g_print ("%s", text);

      g_print ("\n");
    }

  if (self->first_operation_error)
    {
      g_clear_error (error);

      /* We always want to return an error if there was some kind of operation error,
         as that causes the main CLI to return an error status. */

      if (self->stop_on_first_error)
        {
          /* For the install/stop_on_first_error we return the first operation error,
             as we have not yet printed it.  */

          g_propagate_error (error, g_steal_pointer (&self->first_operation_error));
          return FALSE;
        }
      else
        {
          /* For updates/!stop_on_first_error we already printed all errors so we make up
             a different one. */

          return flatpak_fail (error, _("There were one or more errors"));
        }
    }

  if (!res)
    return FALSE;

  return TRUE;
}

===== ./app/flatpak-builtins-permission-list.c =====
/* vi:set et sw=2 sts=2 cin cino=t0,f0,(0,{s,>2s,n-s,^-s,e-s:
 * Copyright © 2018 Red Hat, Inc
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Matthias Clasen <mclasen@redhat.com>
 */

#include "config.h"

#include <locale.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>

#include <glib/gi18n.h>

#include "libglnx.h"
#include "flatpak-permission-dbus-generated.h"

#include "flatpak-builtins.h"
#include "flatpak-builtins-utils.h"
#include "flatpak-table-printer.h"
#include "flatpak-utils-private.h"
#include "flatpak-run-private.h"

static gboolean opt_json;

static GOptionEntry options[] = {
  { "json", 'j', 0, G_OPTION_ARG_NONE, &opt_json, N_("Show output in JSON format"), NULL },
  { NULL }
};

static char **
get_ids_for_table (XdpDbusPermissionStore *store,
                   const char             *table)
{
  char **ids = NULL;

  xdp_dbus_permission_store_call_list_sync (store, table, &ids, NULL, NULL);

  return ids;
}

static gboolean
list_table (XdpDbusPermissionStore *store,
            const char             *table,
            const char             *id,
            FlatpakTablePrinter    *printer,
            GError                **error)
{
  const char *one_id[2];
  g_auto(GStrv) store_ids = NULL;
  char **ids;
  int i;

  if (id)
    {
      one_id[0] = id;
      one_id[1] = NULL;
      ids = (char **) one_id;
    }
  else
    {
      if (!xdp_dbus_permission_store_call_list_sync (store, table, &store_ids, NULL, error))
        return FALSE;
      ids = store_ids;
    }

  for (i = 0; ids[i]; i++)
    {
      g_autoptr(GVariant) permissions = NULL;
      g_autoptr(GVariant) data = NULL;
      g_autoptr(GVariant) d = NULL;
      g_autofree char *txt = NULL;
      GVariantIter iter;
      char *key;
      GVariantIter *val;

      if (!xdp_dbus_permission_store_call_lookup_sync (store, table, ids[i], &permissions, &data, NULL, error))
        return FALSE;

      d = g_variant_get_child_value (data, 0);
      txt = g_variant_print (d, FALSE);

      if (g_variant_iter_init (&iter, permissions) == 0)
        {
          flatpak_table_printer_add_column (printer, table);
          flatpak_table_printer_add_column (printer, ids[i]);
          flatpak_table_printer_add_column (printer, "");
          flatpak_table_printer_add_column (printer, "");
          flatpak_table_printer_add_column (printer, txt);
          flatpak_table_printer_finish_row (printer);
        }

      while (g_variant_iter_loop (&iter, "{sas}", &key, &val))
        {
          char *p;

          flatpak_table_printer_add_column (printer, table);
          flatpak_table_printer_add_column (printer, ids[i]);
          flatpak_table_printer_add_column (printer, key);
          flatpak_table_printer_add_column (printer, "");

          while (g_variant_iter_loop (val, "s", &p))
            {
              flatpak_table_printer_append_with_comma (printer, p);
            }

          flatpak_table_printer_add_column (printer, txt);
          flatpak_table_printer_finish_row (printer);
        }
    }

  return TRUE;
}

gboolean
flatpak_builtin_permission_list (int argc, char **argv,
                                 GCancellable *cancellable,
                                 GError **error)
{
  g_autoptr(GOptionContext) context = NULL;
  g_autoptr(GDBusConnection) session_bus = NULL;
  XdpDbusPermissionStore *store = NULL;
  const char *table;
  const char *id;
  g_autoptr(FlatpakTablePrinter) printer = NULL;

  context = g_option_context_new (_("[TABLE] [ID] - List permissions"));
  g_option_context_set_translation_domain (context, GETTEXT_PACKAGE);

  if (!flatpak_option_context_parse (context, options, &argc, &argv,
                                     FLATPAK_BUILTIN_FLAG_NO_DIR,
                                     NULL, cancellable, error))
    return FALSE;

  if (argc < 2)
    table = NULL;
  else
    table = argv[1];

  if (argc < 3)
    id = NULL;
  else
    id = argv[2];

  if (argc > 3)
    return usage_error (context, _("Too many arguments"), error);

  session_bus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, error);
  if (session_bus == NULL)
    return FALSE;

  store = xdp_dbus_permission_store_proxy_new_sync (session_bus, 0,
                                                    "org.freedesktop.impl.portal.PermissionStore",
                                                    "/org/freedesktop/impl/portal/PermissionStore",
                                                    NULL, error);
  if (store == NULL)
    return FALSE;

  printer = flatpak_table_printer_new ();
  int i;

  i = 0;
  flatpak_table_printer_set_column_title (printer, i++, _("Table"));
  flatpak_table_printer_set_column_title (printer, i++, _("Object"));
  flatpak_table_printer_set_column_title (printer, i++, _("App"));
  flatpak_table_printer_set_column_title (printer, i++, _("Permissions"));
  flatpak_table_printer_set_column_title (printer, i++, _("Data"));

  if (table)
    {
      if (!list_table (store, table, id, printer, error))
        return FALSE;
    }
  else
    {
      g_auto(GStrv) tables = get_permission_tables (store);

      for (i = 0; tables[i]; i++)
        {
          if (!list_table (store, tables[i], NULL, printer, error))
            return FALSE;
        }
    }

  opt_json ? flatpak_table_printer_print_json (printer) : flatpak_table_printer_print (printer);

  return TRUE;
}

gboolean
flatpak_complete_permission_list (FlatpakCompletion *completion)
{
  g_autoptr(GOptionContext) context = NULL;
  g_autoptr(GDBusConnection) session_bus = NULL;
  XdpDbusPermissionStore *store = NULL;
  int i;

  context = g_option_context_new ("");

  if (!flatpak_option_context_parse (context, options, &completion->argc, &completion->argv,
                                     FLATPAK_BUILTIN_FLAG_NO_DIR, NULL, NULL, NULL))
    return FALSE;

  session_bus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL);
  if (session_bus == NULL)
    return FALSE;

  store = xdp_dbus_permission_store_proxy_new_sync (session_bus, 0,
                                                    "org.freedesktop.impl.portal.PermissionStore",
                                                    "/org/freedesktop/impl/portal/PermissionStore",
                                                    NULL, NULL);

  if (store == NULL)
    return FALSE;

  switch (completion->argc)
    {
    case 0:
    case 1: /* TABLE */
      flatpak_complete_options (completion, global_entries);
      flatpak_complete_options (completion, options);

      {
        g_auto(GStrv) tables = get_permission_tables (store);
        for (i = 0; tables != NULL && tables[i] != NULL; i++)
          {
            flatpak_complete_word (completion, "%s ", tables[i]);
          }
      }

      break;

    case 2:
      {
        g_auto(GStrv) ids = get_ids_for_table (store, completion->argv[1]);
        for (i = 0; ids != NULL && ids[i] != NULL; i++)
          {
            flatpak_complete_word (completion, "%s ", ids[i]);
          }
      }

      break;
    }

  return TRUE;
}

===== ./app/flatpak-builtins-permission-remove.c =====
/* vi:set et sw=2 sts=2 cin cino=t0,f0,(0,{s,>2s,n-s,^-s,e-s:
 * Copyright © 2018 Red Hat, Inc
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Matthias Clasen <mclasen@redhat.com>
 */

#include "config.h"

#include <locale.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>

#include <glib/gi18n.h>

#include "libglnx.h"
#include "flatpak-permission-dbus-generated.h"

#include "flatpak-builtins.h"
#include "flatpak-builtins-utils.h"
#include "flatpak-table-printer.h"
#include "flatpak-utils-private.h"
#include "flatpak-run-private.h"

static GOptionEntry options[] = {
  { NULL }
};

static char **
get_ids_for_table (XdpDbusPermissionStore *store,
                   const char             *table)
{
  char **ids = NULL;

  xdp_dbus_permission_store_call_list_sync (store, table, &ids, NULL, NULL);

  return ids;
}

static gboolean
remove_item (XdpDbusPermissionStore *store,
             const char             *table,
             const char             *id,
             const char             *app_id,
             GError                **error)
{
  /* FIXME some portals cache their permission tables and assume that they're
   * the only writers, so they may miss these changes.
   * See https://github.com/flatpak/xdg-desktop-portal/issues/197
   */

  if (!app_id)
    {
      if (!xdp_dbus_permission_store_call_delete_sync (store, table, id, NULL, error))
        return FALSE;
    }
  else if (xdp_dbus_permission_store_get_version (store) == 2)
    {
      if (!xdp_dbus_permission_store_call_delete_permission_sync (store, table, id, app_id, NULL, error))
        return FALSE;
    }
  else
    {
      GVariant *perms = NULL;
      GVariant *data = NULL;
      GVariantBuilder builder;
      int i;

      if (!xdp_dbus_permission_store_call_lookup_sync (store, table, id, &perms, &data, NULL, error))
        return FALSE;

      g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sas}"));
      for (i = 0; perms && i < g_variant_n_children (perms); i++)
        {
          const char *key;
          GVariant *value = NULL;

          g_variant_get_child (perms, i, "{&s@as}", &key, &value);
          if (strcmp (key, app_id) != 0)
            g_variant_builder_add (&builder, "{s@as}", key, value);
        }

      if (!xdp_dbus_permission_store_call_set_sync (store, table, TRUE, id,
                                                    g_variant_builder_end (&builder),
                                                    data ? data : g_variant_new_byte (0),
                                                    NULL, error))
        return FALSE;
    }

  return TRUE;
}

gboolean
flatpak_builtin_permission_remove (int argc, char **argv,
                                   GCancellable *cancellable,
                                   GError **error)
{
  g_autoptr(GOptionContext) context = NULL;
  g_autoptr(GDBusConnection) session_bus = NULL;
  XdpDbusPermissionStore *store = NULL;
  const char *table;
  const char *id;
  const char *app_id;

  context = g_option_context_new (_("TABLE ID [APP_ID] - Remove item from permission store"));
  g_option_context_set_translation_domain (context, GETTEXT_PACKAGE);

  if (!flatpak_option_context_parse (context, options, &argc, &argv,
                                     FLATPAK_BUILTIN_FLAG_NO_DIR,
                                     NULL, cancellable, error))
    return FALSE;

  if (argc < 3)
    return usage_error (context, _("Too few arguments"), error);

  if (argc > 4)
    return usage_error (context, _("Too many arguments"), error);

  table = argv[1];
  id = argv[2];
  app_id = argv[3];

  session_bus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, error);
  if (session_bus == NULL)
    return FALSE;

  store = xdp_dbus_permission_store_proxy_new_sync (session_bus, 0,
                                                    "org.freedesktop.impl.portal.PermissionStore",
                                                    "/org/freedesktop/impl/portal/PermissionStore",
                                                    NULL, error);
  if (store == NULL)
    return FALSE;

  if (!remove_item (store, table, id, app_id, error))
    return FALSE;

  return TRUE;
}

gboolean
flatpak_complete_permission_remove (FlatpakCompletion *completion)
{
  g_autoptr(GOptionContext) context = NULL;
  g_autoptr(GDBusConnection) session_bus = NULL;
  XdpDbusPermissionStore *store = NULL;
  int i;

  context = g_option_context_new ("");

  if (!flatpak_option_context_parse (context, options, &completion->argc, &completion->argv,
                                     FLATPAK_BUILTIN_FLAG_NO_DIR, NULL, NULL, NULL))
    return FALSE;

  session_bus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL);
  if (session_bus == NULL)
    return FALSE;

  store = xdp_dbus_permission_store_proxy_new_sync (session_bus, 0,
                                                    "org.freedesktop.impl.portal.PermissionStore",
                                                    "/org/freedesktop/impl/portal/PermissionStore",
                                                    NULL, NULL);

  if (store == NULL)
    return FALSE;

  switch (completion->argc)
    {
    case 0:
    case 1: /* TABLE */
      flatpak_complete_options (completion, global_entries);
      flatpak_complete_options (completion, options);

      {
        g_auto(GStrv) tables = get_permission_tables (store);
        for (i = 0; tables != NULL && tables[i] != NULL; i++)
          {
            flatpak_complete_word (completion, "%s ", tables[i]);
          }
      }

      break;

    case 2:
      {
        g_auto(GStrv) ids = get_ids_for_table (store, completion->argv[1]);
        for (i = 0; ids != NULL && ids[i] != NULL; i++)
          {
            flatpak_complete_word (completion, "%s ", ids[i]);
          }
      }

      break;

    case 3:
      flatpak_complete_partial_ref (completion, FLATPAK_KINDS_APP, FALSE, flatpak_dir_get_user (), NULL);
      flatpak_complete_partial_ref (completion, FLATPAK_KINDS_APP, FALSE, flatpak_dir_get_system_default (), NULL);
      break;

    default:
      break;
    }

  return TRUE;
}

===== ./app/flatpak-builtins-preinstall.c =====
/* vi:set et sw=2 sts=2 cin cino=t0,f0,(0,{s,>2s,n-s,^-s,e-s:
 * Copyright © 2024 Red Hat, Inc
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Kalev Lember <klember@redhat.com>
 */

#include "config.h"

#include <locale.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

#include <glib/gi18n.h>

#include <gio/gunixinputstream.h>

#include "libglnx.h"

#include "flatpak-builtins.h"
#include "flatpak-builtins-utils.h"
#include "flatpak-transaction-private.h"
#include "flatpak-cli-transaction.h"
#include "flatpak-quiet-transaction.h"
#include "flatpak-utils-http-private.h"
#include "flatpak-utils-private.h"
#include "flatpak-error.h"
#include "flatpak-chain-input-stream-private.h"

static char **opt_sideload_repos;
static gboolean opt_no_pull;
static gboolean opt_no_deploy;
static gboolean opt_no_related;
static gboolean opt_no_deps;
static gboolean opt_no_static_deltas;
static gboolean opt_include_sdk;
static gboolean opt_include_debug;
static gboolean opt_yes;
static gboolean opt_reinstall;
static gboolean opt_noninteractive;

static GOptionEntry options[] = {
  { "no-pull", 0, 0, G_OPTION_ARG_NONE, &opt_no_pull, N_("Don't pull, only install from local cache"), NULL },
  { "no-deploy", 0, 0, G_OPTION_ARG_NONE, &opt_no_deploy, N_("Don't deploy, only download to local cache"), NULL },
  { "no-related", 0, 0, G_OPTION_ARG_NONE, &opt_no_related, N_("Don't install related refs"), NULL },
  { "no-deps", 0, 0, G_OPTION_ARG_NONE, &opt_no_deps, N_("Don't verify/install runtime dependencies"), NULL },
  { "no-static-deltas", 0, 0, G_OPTION_ARG_NONE, &opt_no_static_deltas, N_("Don't use static deltas"), NULL },
  { "include-sdk", 0, 0, G_OPTION_ARG_NONE, &opt_include_sdk, N_("Additionally install the SDK used to build the given refs") },
  { "include-debug", 0, 0, G_OPTION_ARG_NONE, &opt_include_debug, N_("Additionally install the debug info for the given refs and their dependencies") },
  { "assumeyes", 'y', 0, G_OPTION_ARG_NONE, &opt_yes, N_("Automatically answer yes for all questions"), NULL },
  { "reinstall", 0, 0, G_OPTION_ARG_NONE, &opt_reinstall, N_("Uninstall first if already installed"), NULL },
  { "noninteractive", 0, 0, G_OPTION_ARG_NONE, &opt_noninteractive, N_("Produce minimal output and don't ask questions"), NULL },
  /* Translators: A sideload is when you install from a local USB drive rather than the Internet. */
  { "sideload-repo", 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &opt_sideload_repos, N_("Use this local repo for sideloads"), N_("PATH") },
  { NULL }
};

gboolean
flatpak_builtin_preinstall (int argc, char **argv, GCancellable *cancellable, GError **error)
{
  g_autoptr(GOptionContext) context = NULL;
  g_autoptr(GPtrArray) dirs = NULL;
  g_autoptr(FlatpakDir) dir = NULL;
  g_autoptr(FlatpakTransaction) transaction = NULL;

  context = g_option_context_new (_("- Install flatpaks that are part of the operating system"));
  g_option_context_set_translation_domain (context, GETTEXT_PACKAGE);

  if (!flatpak_option_context_parse (context, options, &argc, &argv,
                                     FLATPAK_BUILTIN_FLAG_ALL_DIRS | FLATPAK_BUILTIN_FLAG_OPTIONAL_REPO,
                                     &dirs, cancellable, error))
    return FALSE;

  /* Use the default dir */
  dir = g_object_ref (g_ptr_array_index (dirs, 0));

  if (opt_noninteractive)
    opt_yes = TRUE; /* Implied */

  if (opt_noninteractive)
    transaction = flatpak_quiet_transaction_new (dir, error);
  else
    transaction = flatpak_cli_transaction_new (dir, opt_yes, TRUE, FALSE, error);
  if (transaction == NULL)
    return FALSE;

  flatpak_transaction_set_no_pull (transaction, opt_no_pull);
  flatpak_transaction_set_no_deploy (transaction, opt_no_deploy);
  flatpak_transaction_set_disable_static_deltas (transaction, opt_no_static_deltas);
  flatpak_transaction_set_disable_dependencies (transaction, opt_no_deps);
  flatpak_transaction_set_disable_related (transaction, opt_no_related);
  flatpak_transaction_set_reinstall (transaction, opt_reinstall);
  flatpak_transaction_set_auto_install_sdk (transaction, opt_include_sdk);
  flatpak_transaction_set_auto_install_debug (transaction, opt_include_debug);

  for (int i = 0; opt_sideload_repos != NULL && opt_sideload_repos[i] != NULL; i++)
    flatpak_transaction_add_sideload_repo (transaction, opt_sideload_repos[i]);

  if (!flatpak_transaction_add_sync_preinstalled (transaction, error))
    return FALSE;

  if (flatpak_transaction_is_empty (transaction))
    {
      g_print (_("Nothing to do.\n"));

      return TRUE;
    }

  if (!flatpak_transaction_run (transaction, cancellable, error))
    {
      if (g_error_matches (*error, FLATPAK_ERROR, FLATPAK_ERROR_ABORTED))
        g_clear_error (error); /* Don't report on stderr */

      return FALSE;
    }

  return TRUE;
}

gboolean
flatpak_complete_preinstall (FlatpakCompletion *completion)
{
  g_autoptr(GOptionContext) context = NULL;
  g_autoptr(GPtrArray) dirs = NULL;

  context = g_option_context_new ("");
  if (!flatpak_option_context_parse (context, options, &completion->argc, &completion->argv,
                                     FLATPAK_BUILTIN_FLAG_ONE_DIR | FLATPAK_BUILTIN_FLAG_OPTIONAL_REPO,
                                     &dirs, NULL, NULL))
    return FALSE;

  switch (completion->argc)
    {
    default: /* REF */
      flatpak_complete_options (completion, global_entries);
      flatpak_complete_options (completion, options);
      flatpak_complete_options (completion, user_entries);
      break;
    }

  return TRUE;
}

===== ./app/flatpak-polkit-agent-text-listener.h =====
#ifndef __FLATPAK_POLKIT_AGENT_TEXT_LISTENER_H
#define __FLATPAK_POLKIT_AGENT_TEXT_LISTENER_H

#define POLKIT_AGENT_I_KNOW_API_IS_SUBJECT_TO_CHANGE
#include <polkit/polkit.h>
#include <polkitagent/polkitagent.h>

G_BEGIN_DECLS

typedef struct _FlatpakPolkitAgentTextListener FlatpakPolkitAgentTextListener;

#define FLATPAK_POLKIT_AGENT_TYPE_TEXT_LISTENER          (flatpak_polkit_agent_text_listener_get_type())
#define FLATPAK_POLKIT_AGENT_TEXT_LISTENER(o)            (G_TYPE_CHECK_INSTANCE_CAST ((o), FLATPAK_POLKIT_AGENT_TYPE_TEXT_LISTENER, FlatpakPolkitAgentTextListener))
#define FLATPAK_POLKIT_AGENT_IS_TEXT_LISTENER(o)         (G_TYPE_CHECK_INSTANCE_TYPE ((o), FLATPAK_POLKIT_AGENT_TYPE_TEXT_LISTENER))

GType                flatpak_polkit_agent_text_listener_get_type (void) G_GNUC_CONST;
PolkitAgentListener *flatpak_polkit_agent_text_listener_new (GCancellable   *cancellable,
                                                             GError        **error);


G_END_DECLS

#endif /* __FLATPAK_POLKIT_AGENT_TEXT_LISTENER_H */


===== ./data/tmpfiles.d/flatpak.conf =====
# This is a systemd tmpfiles.d configuration file
R! /var/tmp/flatpak-cache-*

===== ./data/org.freedesktop.impl.portal.PermissionStore.xml =====
<!DOCTYPE node PUBLIC
"-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">

<!--
 Copyright (C) 2015 Red Hat, Inc.

 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 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.

 Author: Alexander Larsson <alexl@redhat.com>
-->

<node name="/" xmlns:doc="http://www.freedesktop.org/dbus/1.0/doc.dtd">
  <!--
      org.freedesktop.impl.portal.PermissionStore:
      @short_description: Database to store permissions

      The permission store can be used by portals to store permissions
      that sandboxed applications have to various resources, such as
      files outside the sandbox.

      Since the resources managed by portals can be varied, the permission
      store is fairly free-form: there can be multiple tables; resources are
      identified by an ID, as are applications, and permissions are stored as
      string arrays. None of these strings are interpreted by the permission
      store in any way.

      In addition, the permission store allows to associate extra data
      (in the form of a GVariant) with each resource.

      This document describes version 2 of the permission store interface.
  -->
  <interface name='org.freedesktop.impl.portal.PermissionStore'>
    <property name="version" type="u" access="read"/>

    <!--
        Lookup:
        @table: the name of the table to use
        @id: the resource ID to look up
        @permissions: map from application ID to permissions
        @data: data that is associated with the resource

        Looks up the entry for a resource in one of the tables and returns
        all associated application permissions and data.
    -->
    <method name="Lookup">
      <arg name='table' type='s' direction='in'/>
      <arg name='id' type='s' direction='in'/>
      <arg name='permissions' type='a{sas}' direction='out'/>
      <arg name='data' type='v' direction='out'/>
    </method>

    <!--
        Set:
        @table: the name of the table to use
        @create: whether to create the table if it does not exist
        @id: the resource ID to modify
        @app_permissions: map from application ID to permissions
        @data: data to associate with the resource

        Writes the entry for a resource in the given table.
    -->
    <method name="Set">
      <arg name='table' type='s' direction='in'/>
      <arg name='create' type='b' direction='in'/>
      <arg name='id' type='s' direction='in'/>
      <arg name='app_permissions' type='a{sas}' direction='in'/>
      <arg name='data' type='v' direction='in'/>
    </method>

    <!--
        Delete:
        @table: the name of the table to use
        @id: the resource ID to delete

        Removes the entry for a resource in the given table.
    -->
    <method name="Delete">
      <arg name='table' type='s' direction='in'/>
      <arg name='id' type='s' direction='in'/>
    </method>

    <!--
        SetValue:
        @table: the name of the table to use
        @create: whether to create the table if it does not exist
        @id: the resource ID to modify
        @data: data to associate with the resource

        Sets just the data for a resource in the given table.
    -->
    <method name="SetValue">
      <arg name='table' type='s' direction='in'/>
      <arg name='create' type='b' direction='in'/>
      <arg name='id' type='s' direction='in'/>
      <arg name='data' type='v' direction='in'/>
    </method>

    <!--
        SetPermission:
        @table: the name of the table to use
        @create: whether to create the table if it does not exist
        @id: the resource ID to modify
        @app: the application ID to modify
        @permissions: permissions to set

        Sets the permissions for an application and a resource
        in the given table.
    -->
    <method name="SetPermission">
      <arg name='table' type='s' direction='in'/>
      <arg name='create' type='b' direction='in'/>
      <arg name='id' type='s' direction='in'/>
      <arg name='app' type='s' direction='in'/>
      <arg name='permissions' type='as' direction='in'/>
    </method>

    <!--
        DeletePermission:
        @table: the name of the table to use
        @id: the resource ID to modify
        @app: the application ID to modify

        Removes the entry for an application and a resource
        in the given table.

        This method was added in version 2.
    -->
    <method name="DeletePermission">
      <arg name='table' type='s' direction='in'/>
      <arg name='id' type='s' direction='in'/>
      <arg name='app' type='s' direction='in'/>
    </method>

    <!--
        List:
        @table: the name of the table to use
        @ids: IDs of all resources that are present in the table

        Returns all the resources that are present in the table.
    -->
    <method name="List">
      <arg name='table' type='s' direction='in'/>
      <arg name='ids' type='as' direction='out'/>
    </method>

    <!--
        Changed:
        @table: the name of the table
        @ids: IDs of the changed resource
        @deleted: whether the resource was deleted
        @data: the data that is associated the resource
        @permissions: the permissions that are associated with the resource

        The Changed signal is emitted when the entry for a resource
        is modified or deleted. If the entry was deleted, then @data
        and @permissions contain the last values that were found in the
        database. If the entry was modified, they contain the new values.
    -->
    <signal name="Changed">
      <arg name='table' type='s' direction='out'/>
      <arg name='id' type='s' direction='out'/>
      <arg name='deleted' type='b' direction='out'/>
      <arg name='data' type='v' direction='out'/>
      <arg name='permissions' type='a{sas}' direction='out'/>
    </signal>
  </interface>

</node>

===== ./data/org.freedesktop.portal.Flatpak.xml =====
<!DOCTYPE node PUBLIC
"-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">

<!--
 Copyright (C) 2018 Red Hat, Inc.

 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 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.

 Author: Alexander Larsson <alexl@redhat.com>
-->

<node name="/" xmlns:doc="http://www.freedesktop.org/dbus/1.0/doc.dtd">
  <!--
      org.freedesktop.portal.Flatpak:
      @short_description: Flatpak portal

      The flatpak portal exposes some interactions with flatpak on the
      host to the sandbox. For example, it allows you to restart the
      applications or start a more sandboxed instance.

      This portal is available on the D-Bus session bus under the
      bus name org.freedesktop.portal.Flatpak and the object path
      /org/freedesktop/portal/Flatpak.

      This documentation describes version 8 of this interface.
  -->
  <interface name='org.freedesktop.portal.Flatpak'>
    <property name="version" type="u" access="read"/>
    <!--
        supports:

        Flags marking what optional features are available.
         The following flags values are supported:
         <variablelist>
           <varlistentry>
             <term>1 (FLATPAK_SPAWN_SUPPORT_FLAGS_EXPOSE_PIDS)</term>
             <listitem><para>
              Supports the expose sandbox pids flag of Spawn.
              If the version of this interface is 5 or later, this also
              indicates that the share sandbox pids flag is available.
             </para></listitem>
           </varlistentry>
         </variablelist>

         This was added in version 3 of this interface (available from flatpak 1.6.0 and later).
        -->
    <property name="supports" type="u" access="read"/>

    <!--
         Spawn:
         @cwd_path: the working directory for the new process
         @argv: the argv for the new process, starting with the executable to launch
         @fds: an array of file descriptors to pass to the new process
         @envs: an array of variable/value pairs for the environment of the new process
         @flags: flags
         @options: Vardict with optional further information
         @pid: the PID of the new process

         This method lets you start a new instance of your
         application, optionally enabling a tighter sandbox.

         The following flags values are supported:
         <variablelist>
           <varlistentry>
             <term>1 (FLATPAK_SPAWN_FLAGS_CLEAR_ENV)</term>
             <listitem><para>
               Clear the environment.
             </para></listitem>
           </varlistentry>
           <varlistentry>
             <term>2 (FLATPAK_SPAWN_FLAGS_LATEST_VERSION)</term>
             <listitem><para>
               Spawn the latest version of the app.
             </para></listitem>
           </varlistentry>
           <varlistentry>
             <term>4 (FLATPAK_SPAWN_FLAGS_SANDBOX)</term>
             <listitem><para>
               Spawn in a sandbox (equivalent of the sandbox option of flatpak run).
             </para></listitem>
           </varlistentry>
           <varlistentry>
             <term>8 (FLATPAK_SPAWN_FLAGS_NO_NETWORK)</term>
             <listitem><para>
               Spawn without network (equivalent of the unshare=network option of flatpak run).
             </para></listitem>
           </varlistentry>
           <varlistentry>
             <term>16 (FLATPAK_SPAWN_FLAGS_WATCH_BUS)</term>
             <listitem><para>
               Kill the sandbox when the caller disappears from the session bus.
             </para></listitem>
           </varlistentry>
           <varlistentry>
             <term>32 (FLATPAK_SPAWN_FLAGS_EXPOSE_PIDS)</term>
             <listitem><para>
               Expose the sandbox pids in the callers sandbox, only supported if using user namespaces for containers (not setuid), see the support property.
               </para><para>
               This was added in version 3 of this interface (available from flatpak 1.6.0 and later).
             </para></listitem>
           </varlistentry>
           <varlistentry>
             <term>64 (FLATPAK_SPAWN_FLAGS_NOTIFY_START)</term>
             <listitem><para>
               Emit a SpawnStarted signal once the sandboxed process has been
               fully started.
               </para><para>
               This was added in version 4 of this interface (available from flatpak 1.8.0 and later).
             </para></listitem>
           </varlistentry>
           <varlistentry>
             <term>128 (FLATPAK_SPAWN_FLAGS_SHARE_PIDS)</term>
             <listitem><para>
              Expose the sandbox process IDs in the caller's sandbox and
              the caller's process IDs in the new sandbox. Only supported
              if using user namespaces for containers (not setuid), see the
              support property.
             </para><para>
               This was added in version 5 of this interface (available from flatpak 1.10.0 and later).
             </para></listitem>
           </varlistentry>
           <varlistentry>
             <term>256 (FLATPAK_SPAWN_FLAGS_EMPTY_APP)</term>
             <listitem><para>
               Don't provide app files at <filename>/app</filename> in the
               new sandbox. Instead, <filename>/app</filename> will be an
               empty directory. This flag and the <option>app-fd</option>
               option are mutually exclusive.
             </para><para>
               As with the <option>app-fd</option> option, the caller's
               Flatpak app files and extensions will be mounted on
               <filename>/run/parent/app</filename>, with
               filenames like <filename>/run/parent/app/bin/myapp</filename>.
             </para><para>
               This was added in version 6 of this interface (available from
               flatpak 1.12.0 and later).
             </para></listitem>
           </varlistentry>
         </variablelist>

         Unknown (unsupported) flags are an error and will cause Spawn()
         to fail.

         Unknown (unsupported) options are ignored.
         The following options are supported:
         <variablelist>
           <varlistentry>
             <term>sandbox-expose as</term>
             <listitem><para>
               A list of filenames for files inside the sandbox that will be exposed
               to the new sandbox, for reading and writing. Note that absolute paths
               or subdirectories are not allowed.
             </para><para>
               The files must be in the <filename>sandbox</filename> subdirectory of
               the instance directory (i.e. <filename>~/.var/app/$APP_ID/sandbox</filename>).
             </para></listitem>
           </varlistentry>
           <varlistentry>
             <term>sandbox-expose-ro as</term>
             <listitem><para>
               A list of filenames for files inside the sandbox that will be exposed
               to the new sandbox, readonly. Note that absolute paths or subdirectories
               are not allowed.
             </para><para>
               The files must be in the <filename>sandbox</filename> subdirectory of
               the instance directory (i.e. <filename>~/.var/app/$APP_ID/sandbox</filename>).
             </para></listitem>
           </varlistentry>
           <varlistentry>
             <term>sandbox-expose-fd ah</term>
             <listitem><para>
               A list of file descriptor for files inside the sandbox that will be exposed
               to the new sandbox, for reading and writing (if the caller has write access).
               The file descriptors must be opened with O_PATH and O_NOFOLLOW and cannot be symlinks.
             </para><para>
               This was added in version 3 of this interface (available from flatpak 1.6.0 and later).
             </para></listitem>
           </varlistentry>
           <varlistentry>
             <term>sandbox-expose-fd-ro ah</term>
             <listitem><para>
               A list of file descriptor for files inside the sandbox that will be exposed
               to the new sandbox, readonly. The file descriptors must be opened with O_PATH and O_NOFOLLOW and cannot be symlinks.
             </para><para>
               This was added in version 3 of this interface (available from flatpak 1.6.0 and later).
             </para></listitem>
           </varlistentry>
           <varlistentry>
             <term>sandbox-flags u</term>
             <listitem><para>
             Flags affecting the created sandbox. The following flags values are supported:
             <variablelist>
               <varlistentry>
                 <term>1</term>
                 <listitem><para>
                   Share the display access (X11, wayland) with the caller.
                 </para></listitem>
               </varlistentry>
               <varlistentry>
                 <term>2</term>
                 <listitem><para>
                   Share the sound access (pulseaudio) with the caller.
                 </para></listitem>
               </varlistentry>
               <varlistentry>
                 <term>4</term>
                 <listitem><para>
                   Share the gpu access with the caller.
                 </para></listitem>
               </varlistentry>
               <varlistentry>
                 <term>8</term>
                 <listitem><para>
                   Allow sandbox access to (filtered) session bus.
                 </para></listitem>
               </varlistentry>
               <varlistentry>
                 <term>16</term>
                 <listitem><para>
                   Allow sandbox access to accessibility bus.
                 </para></listitem>
               </varlistentry>
               <varlistentry>
                 <term>32</term>
                 <listitem><para>
                   Allow sandbox access to input devices.
                 </para></listitem>
               </varlistentry>
               <varlistentry>
                 <term>64</term>
                 <listitem><para>
                   Allow sandbox access to USB devices.
                 </para></listitem>
               </varlistentry>
               <varlistentry>
                 <term>128</term>
                 <listitem><para>
                   Allow sandbox access to KVM.
                 </para></listitem>
               </varlistentry>
               <varlistentry>
                 <term>256</term>
                 <listitem><para>
                   Allow sandbox access to shared memory.
                 </para></listitem>
               </varlistentry>
               <varlistentry>
                 <term>512</term>
                 <listitem><para>
                   Allow sandbox access to all devices.
                 </para></listitem>
               </varlistentry>
             </variablelist>

             </para><para>
             This was added in version 3 of this interface (available from flatpak 1.6.0 and later).
             </para></listitem>
           </varlistentry>
           <varlistentry>
             <term>sandbox-a11y-own-names as</term>
             <listitem><para>
               An array of D-Bus names to be owned on the accessibility bus. The
               names must have the app id as prefix.
             </para><para>
               Only applies when `sandbox-flags` contains access to the accessibility
               bus as well.
             </para><para>
               This was added in version 7 of this interface (available from
               flatpak 1.16.0 and later).
             </para></listitem>
           </varlistentry>
           <varlistentry>
             <term>unset-env as</term>
             <listitem><para>
             A list of environment variables to unset (remove from the environment).
             </para><para>
             This was added in version 5 of this interface (available from flatpak 1.10.0 and later).
             </para></listitem>
           </varlistentry>
           <varlistentry>
             <term>usr-fd h</term>
             <listitem><para>
               A file descriptor for the directory that will be used as
               <filename>/usr</filename> in the new sandbox, instead of the
               <filename>files</filename> directory
               from the caller's Flatpak runtime.
               The new sandbox's <filename>/etc</filename> will be based
               on the <filename>etc</filename> subdirectory of the given
               directory, and compatibility symlinks in its
               root directory (<filename>/lib</filename>,
               <filename>/bin</filename> and so on) will point into the
               given directory. The caller's Flatpak runtime and its
               extensions will be mounted on
               <filename>/run/parent/usr</filename>, with filenames like
               <filename>/run/parent/usr/bin/env</filename>,
               and compatibility symlinks like
               <filename>/run/parent/bin</filename> →
               <filename>usr/bin</filename>.
             </para><para>
               The file descriptor must be opened with O_PATH and
               O_NOFOLLOW and cannot be a symlink.
             </para><para>
               This was added in version 6 of this interface (available from
               flatpak 1.12.0 and later).
             </para></listitem>
           </varlistentry>
           <varlistentry>
             <term>app-fd h</term>
             <listitem><para>
               A file descriptor for the directory that will be used as
               <filename>/app</filename> in the new sandbox, instead of the
               <filename>files</filename> directory
               from the caller's Flatpak app. The caller's Flatpak app
               files and extensions will be
               mounted on <filename>/run/parent/app</filename>, with
               filenames like <filename>/run/parent/app/bin/myapp</filename>.
             </para><para>
               This option and the
               <option>FLATPAK_SPAWN_FLAGS_EMPTY_APP</option>
               flag are mutually exclusive.
             </para><para>
               The file descriptor must be opened with O_PATH and
               O_NOFOLLOW and cannot be a symlink.
             </para><para>
               This was added in version 6 of this interface (available from
               flatpak 1.12.0 and later).
             </para></listitem>
           </varlistentry>
         </variablelist>

    -->
    <method name="Spawn">
      <annotation name="org.gtk.GDBus.C.UnixFD" value="true"/>
      <arg type='ay' name='cwd_path' direction='in'/>
      <arg type='aay' name='argv' direction='in'/>
      <arg type='a{uh}' name='fds' direction='in'/>
      <arg type='a{ss}' name='envs' direction='in'/>
      <arg type='u' name='flags' direction='in'/>
      <arg type="a{sv}" name="options" direction="in"/>
      <arg type='u' name='pid' direction='out'/>
    </method>

    <!--
        SpawnSignal:
        @pid: the PID inside the container to signal
        @signal: the signal to send (see <citerefentry><refentrytitle>signal</refentrytitle><manvolnum>7</manvolnum></citerefentry>)
        @to_process_group: whether to send the signal to the process group

        This method lets you send a Unix signal to a process
        that was started with org.freedesktop.portal.Flatpak.Spawn().
        The @pid argument here should be the PID that is returned
        by the Spawn() call: it is not necessarily valid in the caller's
        PID namespace.
      -->
    <method name="SpawnSignal">
      <arg type='u' name='pid' direction='in'/>
      <arg type='u' name='signal' direction='in'/>
      <arg type='b' name='to_process_group' direction='in'/>
    </method>

    <!--
        SpawnStarted:
        @pid: the PID of the process that has been started
        @relpid: the PID of the process relative to the current namespace.
        This is only non-zero if the expose PIDs flag (32) or the share
        PIDs flag (128) was passed to
        org.freedesktop.portal.Flatpak.Spawn(), and it may still be zero if
        the process exits before its relative PID could be read.

        Emitted when a process started by org.freedesktop.portal.Flatpak.Spawn()
        has fully started. In other words, org.freedesktop.portal.Flatpak.Spawn() returns once the sandbox
        has been started, and this signal is emitted once the process inside
        itself is started.

        Only emitted by version 4 of this interface (available from flatpak
        1.8.0 and later) and if the notify start flag (64) was passed to
        org.freedesktop.portal.Flatpak.Spawn().
    -->
    <signal name="SpawnStarted">
      <arg type='u' name='pid' direction='out'/>
      <arg type='u' name='relpid' direction='out'/>
    </signal>

    <!--
        SpawnExited:
        @pid: the PID of the process that has ended
        @exit_status: the wait status (see <citerefentry><refentrytitle>waitpid</refentrytitle><manvolnum>2</manvolnum></citerefentry>)

        Emitted when a process started by org.freedesktop.portal.Flatpak.Spawn()
        exits.
        Use g_spawn_check_exit_status(), or the macros such as
        WIFEXITED documented in
        <citerefentry><refentrytitle>waitpid</refentrytitle><manvolnum>2</manvolnum></citerefentry>,
        to interpret the @exit_status.

        This signal is not emitted for processes that were not launched
        directly by Spawn(), for example if a process launched by
        Spawn() runs foreground or background child processes.
    -->
    <signal name="SpawnExited">
      <arg type='u' name='pid' direction='out'/>
      <arg type='u' name='exit_status' direction='out'/>
    </signal>

    <!--
        CreateUpdateMonitor:
        @options: Vardict with optional further information
        @handle: Object path for the #org.freedesktop.portal.Flatpak.UpdateMonitor object

        Creates an update monitor object that will emit
        signals when an update for the caller becomes
        available, and can be used to install it.

        The handle will be of the form /org/freedesktop/portal/Flatpak/update_monitor/SENDER/TOKEN,
        where SENDER is the caller's unique name, with the initial ':' removed and
        all '.' replaced by '_', and TOKEN is a unique token that the caller can optionally provide
        with the 'handle_token' key in the options vardict.

        Currently, no other options are accepted.

        This was added in version 2 of this interface (available from flatpak 1.5.0 and later).
    -->
    <method name="CreateUpdateMonitor">
      <arg type="a{sv}" name="options" direction="in"/>
      <arg type="o" name="handle" direction="out"/>
    </method>
  </interface>

  <interface name="org.freedesktop.portal.Flatpak.UpdateMonitor">

    <!--
        Close:

        Ends the update monitoring and cancels any ongoing
        installation.
    -->
    <method name="Close">
    </method>

    <!--
        UpdateAvailable:
        @update_info: More information about the available update

        Gets emitted when a new update is available. This is only
        sent once with the same information, but can be sent many
        times if new updates appear.

        The following information may be included in the
        @update_info dictionary:
        <variablelist>
          <varlistentry>
            <term>running-commit s</term>
            <listitem><para>
              The commit of the currently running instance.
            </para></listitem>
          </varlistentry>
          <varlistentry>
            <term>local-commit s</term>
            <listitem><para>
              The commit that is currently installed. Restarting
              the application will cause this commit to be used.
            </para></listitem>
          </varlistentry>
          <varlistentry>
            <term>remote-commit s</term>
            <listitem><para>
              The commit that is available as an update from the
              remote. Updating the application will deploy this
              commit.
            </para></listitem>
          </varlistentry>
        </variablelist>
    -->
    <signal name="UpdateAvailable">
      <arg type="a{sv}" name="update_info" direction="out"/>
    </signal>

    <!--
        Update:
        @parent_window: Identifier for the application window,
          see <link linkend="parent_window">Common Conventions</link>
        @options: Vardict with optional further information

        Asks to install an update of the calling app.
        During the installation,
        #org.freedesktop.portal.Flatpak.UpdateMonitor::Progress
        signals will be emitted to communicate the status
        and progress.

        Note that updates are only allowed if the new version
        has the same permissions (or less) than the currently installed
        version. If the new version requires a new permission then the
        operation will fail with the error org.freedesktop.DBus.Error.NotSupported
        and updates has to be done with the system tools.

        Currently, no options are accepted.
    -->
    <method name="Update">
      <arg type="s" name="parent_window" direction="in"/>
      <arg type="a{sv}" name="options" direction="in"/>
    </method>

    <!--
      Progress:
      @handle: the handle of the Request
      @info: More information about the update progress

      Gets emitted to indicate progress of the installation.  It's
      undefined exactly how often this is sent, but it will be emitted
      at least once at the end with non-zero status field. For each
      successful operation in the update we're also guaranteed to send
      one (and only one) signal with progress 100.

      The following fields may be included in the info:
         <variablelist>
           <varlistentry>
             <term>n_ops u</term>
             <listitem><para>
               The number of operations that the update
               consists of.
             </para></listitem>
           </varlistentry>
           <varlistentry>
             <term>op u</term>
             <listitem><para>
               The position of the currently active
               operation.
             </para></listitem>
           </varlistentry>
           <varlistentry>
             <term>progress u</term>
             <listitem><para>
               The progress of the currently active
               operation, as a number between 0 and 100.
             </para></listitem>
           </varlistentry>
           <varlistentry>
             <term>status u</term>
             <listitem><para>
               The overall status of the update.
               <simplelist>
                 <member>0: Running</member>
                 <member>1: Empty. No update to install</member>
                 <member>2: Done</member>
                 <member>3: Failed</member>
               </simplelist>
             </para></listitem>
           </varlistentry>
           <varlistentry>
             <term>error s</term>
             <listitem><para>
               The error name, sent when status is Failed
             </para></listitem>
           </varlistentry>
           <varlistentry>
             <term>error_message s</term>
             <listitem><para>
               The error message, sent when status is Failed
             </para></listitem>
           </varlistentry>
         </variablelist>
    -->
    <signal name="Progress">
      <arg type="a{sv}" name="info" direction="out"/>
    </signal>

  </interface>

</node>

===== ./data/org.freedesktop.Flatpak.Authenticator.xml =====
<!DOCTYPE node PUBLIC
"-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">

<!--
 Copyright (C) 2015 Red Hat, Inc.

 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 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.

 Author: Alexander Larsson <alexl@redhat.com>
-->

<node name="/" xmlns:doc="http://www.freedesktop.org/dbus/1.0/doc.dtd">
  <!--
     'org.freedesktop.Flatpak.Authenticator:
      @short_description: Flatpak authenticator

      An authenticator is a dbus service that flatpak talks to in
      order to negotiate downloads of protected content. Each commit
      in the repository has a "token-type" value (either directly or
      from a default), and whenever this is non-zero flatpak assumes
      it will need to do some sort of authentication to download it.

      Each configured remote in the system has information about what
      authenticator to use for the remote, as well as some config
      options for it. The configuration contains the dbus name of the
      authenticator, which is activated on demand by dbus. This allows
      authenticators to be shipped with the system, or installed as
      flatpaks.

      The main operation that the authenticator supports is the
      RequestRefToken where you pass a set of references and the
      authenticator returns a HTTP bearer token (if any) to use for
      each ref. Flatpak will then use the returned tokens in all its
      http requests, and it is then up to the server to validate the
      tokens.

      The authenticator dbus calls are not regular dbus calls, but
      instead long running (cancellable) object implementing the
      AuthenticatorRequest interface. This is very similar to how
      org.freedesktop.portal.Request work when its used in
      xdg-desktop-portal.

      Most of the details in how the tokens look, are created and
      validated and how the token-type is interpreted is up to the
      authenticator (in combination with the actual repo server). The
      system has been designed to be very generic.

      The D-Bus interface for the authenticator is supposed to be
      available on the given bus name at the object path
      /org/freedesktop/Flatpak/Authenticator.

      This documentation describes version 1 of this interface.
  -->
  <interface name='org.freedesktop.Flatpak.Authenticator'>
    <property name="version" type="u" access="read"/>

    <!--
        RequestRefTokens:
        @handle_token: A string that will be used as the last element of the @handle. Must be a valid
              object path element. See the #org.freedesktop.Flatpak.AuthenticatorRequest documentation for
              more information about the @handle.
        @authenticator_options: Data from the xa.authenticator-options key in the configuration for the remote, it is up to the authenticator to interpret this how it wants.
        @remote: The name of the remote we're pulling from.
        @remote_uri: The uri of the remote we're pulling from.
        @refs: An array of ref that flatpak wants to pull and info about each ref.
        @options: An extensible  dict with extra options.
        @parent_window: Identifier for the application window, see <link linkend="https://flatpak.github.io/xdg-desktop-portal/portal-docs.html#parent_window">xdg-desktop-portal docs</link> for details on its format.
        @handle: Object path for the #org.freedesktop.Flatpak.AuthenticatorRequest object representing this call.

        Starts a request for resolving the tokens to use for @refs from the @remote (with uri @remote_uri).

        This is not a regular dbus call that blocks until the result is done, instead it creates
        a org.freedesktop.Flatpak.AuthenticatorRequest object representing the ongoing operation and
        returns an object path @handle to it. When the operation succeeds the Response signal is emitted
        on the request with a response status and a dict with details.

        The @refs array elements are of type (ssia{sv}) where the items are:
        <simplelist>
          <member>s: The ref being pulled</member>
          <member>s: The exact commit being pulled</member>
          <member>i: The token-type of the commit</member>
          <member>a{sv}: Extra per-ref metadata, currently only has summary.* fields which are copied from the summary per-commit metadata.</member>
        </simplelist>

        On success (response 0) the returned details should have:
        <variablelist>
          <varlistentry>
            <term>tokens a{sas}</term>
            <listitem><para>
              A list of tokens (the first element of the struct), and the refs (the second).
            </para></listitem>
          </varlistentry>
        </variablelist>

        For other response types, see the #org.freedesktop.Flatpak.AuthenticatorRequest docs.

        Exactly how the authenticator decides on what token to use is up to each implementation, but typically it needs to talk to
        some kind of network service which in turn may need interaction such as login or entering credit card details.
        This can be done in two ways:

        The authenticator can use a native ui toolkit directly (as its running in the session). To make this work well the
        flatpak client can (if its has a UI) pass in the @parent_window argument, allowing the authenticator to open its
        dialog in a way that is correctly parented.

        Alternatively, if the interaction is web-based, then rather than showing a web browser itself it can emit
        the WebFlow signal on the request object, which lets the flatpak client show a webview embedded in its ui in a
        way that works best with its user interface.

        For simple user/password authentication (such as http basic authentication systems) there is also a BasicAuth signal
        that can be used to get the user to interactively authenticate. This kind of authentication is quite limited, but
        if used it can allow nice interactive authentication even in the command line case.

        Currently used keys in the @options argument:
        <variablelist>
          <varlistentry>
            <term>xa.oci-registry-uri s</term>
            <listitem><para>
              For OCI remotes this is extracted from the summary file and contains the uri to the OCI registry that
              contains the images.
            </para></listitem>
          </varlistentry>
          <varlistentry>
            <term>no-interation b</term>
            <listitem><para>
              If true, the authenticator should not do any interaction (and fail instead if it needs to). This can be enabled by
              clients that want to run in the background.
            </para></listitem>
          </varlistentry>
        </variablelist>
    -->
    <method name="RequestRefTokens">
      <arg type='s' name='handle_token' direction='in'/>
      <arg type='a{sv}' name='authenticator_options' direction='in'/>
      <arg type='s' name='remote' direction='in'/>
      <arg type='s' name='remote_uri' direction='in'/>
      <!-- This is the ref and its token-type -->
      <arg type='a(ssia{sv})' name='refs' direction='in'/>
      <arg type='a{sv}' name='options' direction='in'/>
      <arg type='s' name='parent_window' direction='in'/>
      <arg type='o' name='handle' direction='out'/>
    </method>
  </interface>

  <!--
     'org.freedesktop.Flatpak.AuthenticatorRequest:
      @short_description: Ongoing authenticator request

      The AuthenticatorRequest interface is used by the #org.freedesktop.Flatpak.Authenticator interface. When a
      method is called, the reply includes a handle (i.e. object path)
      for a AuthenticatorRequest object, which will stay alive for the duration of the
      user interaction related to the method call.

      The authenticator indicates that a request interaction is over by
      emitting the #org.freedesktop.Flatpak.AuthenticatorRequest::Response signal on the
      Request object.

      The application can abort the interaction calling
      org.freedesktop.Flatpak.AuthenticatorRequest.Close() on the AuthenticatorRequest object.

      The object path of each request object will be of the form
       /org/freedesktop/Flatpak/Authenticator/request/SENDER/TOKEN,
      where SENDER is the callers unique name, with the initial ':' removed and
      all '.' replaced by '_', and TOKEN is a unique token that the caller provided
      with the handle_token argument. This lets applications subscribe to the
      Response signal before making the initial portal call, thereby avoiding a race condition.
  -->
  <interface name="org.freedesktop.Flatpak.AuthenticatorRequest">
    <!--
        Close:

        Closes the authenticator request to which this object refers and ends all
        related user interaction (dialogs, webflows etc).

        A Response signal with the cancelled response will be emitted if the operation
        was cancelled. There is still a possibility of a race, so the operation might succeed
        or fail before processing the close request, so there is no guarantee that the
        operation will be cancelled.
    -->
    <method name="Close">
    </method>
    <!--
        Webflow:
        @uri: The uri to show
        @options: An extensible dict with extra options.

        Emitted by the authenticator when it needs to do web-based interaction. The
        client handles this by showing the URI in a graphical web view. Typically the uri
        includes information about a final redirect to a localhost uri that will happen
        when the operation is finished allowing the authenticator to get the result of
        the operation. This is similar to how OAUTH2 webflows typically work.

        If at any point the user closes or otherwise dismisses the web view the client
        should call the org.freedesktop.Flatpak.AuthenticatorRequest.Close method to
        tell the authenticator that the operation is aborted.
    -->
    <signal name="Webflow">
      <arg type="s" name="uri"/>
      <arg type="a{sv}" name="options" direction="in"/>
    </signal>
    <!--
        WebflowDone:
        @options: An extensible dict with extra options.

        Emitted by the authenticator when the web view is done, at this point the client
        can close the WebView.
    -->
    <signal name="WebflowDone">
      <arg type="a{sv}" name="options" direction="in"/>
    </signal>
    <!--
        BasicAuth:
        @realm: String showing what the auth is for, similar to http basic auth realm.
        @options: An extensible dict with extra options.

        Emitted by the authenticator when it needs to do a simple user + password authentication.
        This is only useful for very simple authentication interaction, but this is still used (for
        instance for http basic access authentication), and for those cases this allows a nicely
        integrated UI and CLI experience.
    -->
    <signal name="BasicAuth">
      <arg type="s" name="realm"/>
      <arg type="a{sv}" name="options" direction="in"/>
    </signal>
    <!--
        BasicAuthReply:
        @user: The user
        @password: The password
        @options: An extensible dict with extra options.

        Call to finish the request started with the BasicAuth signal.
    -->
    <method name="BasicAuthReply">
      <arg type="s" name="user"/>
      <arg type="s" name="password"/>
      <arg type="a{sv}" name="options" direction="in"/>
    </method>
    <!--
        Response:
        @response: Numeric response
        @results: Vardict with results. The keys and values in the vardict depend on the request.
        Emitted when the user interaction for a portal request is over.
        The @response indicates how the user interaction ended:
            <simplelist>
              <member>0: Success, the request is carried out</member>
              <member>1: The user cancelled the interaction</member>
              <member>2: The user interaction was ended in some other way</member>
            </simplelist>
        In the case of an error (response 2) @results can contain a error-message value
        describing what went wrong.
    -->
    <signal name="Response">
      <arg type="u" name="response"/>
      <arg type="a{sv}" name="results"/>
    </signal>
  </interface>
</node>

===== ./data/meson.build =====
# Copyright 2022 Collabora Ltd.
# SPDX-License-Identifier: LGPL-2.1-or-later

install_data(
  'org.freedesktop.Flatpak.xml',
  'org.freedesktop.Flatpak.Authenticator.xml',
  'org.freedesktop.portal.Flatpak.xml',
  install_dir : get_option('datadir') / 'dbus-1' / 'interfaces',
)
install_data(
  'tmpfiles.d/flatpak.conf',
  install_dir : get_option('tmpfilesdir'),
)

===== ./data/flatpak-docker-seccomp.json =====
{
	"defaultAction": "SCMP_ACT_ERRNO",
	"archMap": [
		{
			"architecture": "SCMP_ARCH_X86_64",
			"subArchitectures": [
				"SCMP_ARCH_X86",
				"SCMP_ARCH_X32"
			]
		},
		{
			"architecture": "SCMP_ARCH_AARCH64",
			"subArchitectures": [
				"SCMP_ARCH_ARM"
			]
		},
		{
			"architecture": "SCMP_ARCH_MIPS64",
			"subArchitectures": [
				"SCMP_ARCH_MIPS",
				"SCMP_ARCH_MIPS64N32"
			]
		},
		{
			"architecture": "SCMP_ARCH_MIPS64N32",
			"subArchitectures": [
				"SCMP_ARCH_MIPS",
				"SCMP_ARCH_MIPS64"
			]
		},
		{
			"architecture": "SCMP_ARCH_MIPSEL64",
			"subArchitectures": [
				"SCMP_ARCH_MIPSEL",
				"SCMP_ARCH_MIPSEL64N32"
			]
		},
		{
			"architecture": "SCMP_ARCH_MIPSEL64N32",
			"subArchitectures": [
				"SCMP_ARCH_MIPSEL",
				"SCMP_ARCH_MIPSEL64"
			]
		},
		{
			"architecture": "SCMP_ARCH_S390X",
			"subArchitectures": [
				"SCMP_ARCH_S390"
			]
		}
	],
	"syscalls": [
		{
			"names": [
				"accept",
				"accept4",
				"access",
				"adjtimex",
				"alarm",
				"bind",
				"brk",
				"capget",
				"capset",
				"chdir",
				"chmod",
				"chown",
				"chown32",
				"clock_getres",
				"clock_gettime",
				"clock_nanosleep",
				"close",
				"connect",
				"copy_file_range",
				"creat",
				"dup",
				"dup2",
				"dup3",
				"epoll_create",
				"epoll_create1",
				"epoll_ctl",
				"epoll_ctl_old",
				"epoll_pwait",
				"epoll_wait",
				"epoll_wait_old",
				"eventfd",
				"eventfd2",
				"execve",
				"execveat",
				"exit",
				"exit_group",
				"faccessat",
				"fadvise64",
				"fadvise64_64",
				"fallocate",
				"fanotify_mark",
				"fchdir",
				"fchmod",
				"fchmodat",
				"fchown",
				"fchown32",
				"fchownat",
				"fcntl",
				"fcntl64",
				"fdatasync",
				"fgetxattr",
				"flistxattr",
				"flock",
				"fork",
				"fremovexattr",
				"fsetxattr",
				"fstat",
				"fstat64",
				"fstatat64",
				"fstatfs",
				"fstatfs64",
				"fsync",
				"ftruncate",
				"ftruncate64",
				"futex",
				"futimesat",
				"getcpu",
				"getcwd",
				"getdents",
				"getdents64",
				"getegid",
				"getegid32",
				"geteuid",
				"geteuid32",
				"getgid",
				"getgid32",
				"getgroups",
				"getgroups32",
				"getitimer",
				"getpeername",
				"getpgid",
				"getpgrp",
				"getpid",
				"getppid",
				"getpriority",
				"getrandom",
				"getresgid",
				"getresgid32",
				"getresuid",
				"getresuid32",
				"getrlimit",
				"get_robust_list",
				"getrusage",
				"getsid",
				"getsockname",
				"getsockopt",
				"get_thread_area",
				"gettid",
				"gettimeofday",
				"getuid",
				"getuid32",
				"getxattr",
				"inotify_add_watch",
				"inotify_init",
				"inotify_init1",
				"inotify_rm_watch",
				"io_cancel",
				"ioctl",
				"io_destroy",
				"io_getevents",
				"io_pgetevents",
				"ioprio_get",
				"ioprio_set",
				"io_setup",
				"io_submit",
				"ipc",
				"kill",
				"lchown",
				"lchown32",
				"lgetxattr",
				"link",
				"linkat",
				"listen",
				"listxattr",
				"llistxattr",
				"_llseek",
				"lremovexattr",
				"lseek",
				"lsetxattr",
				"lstat",
				"lstat64",
				"madvise",
				"memfd_create",
				"mincore",
				"mkdir",
				"mkdirat",
				"mknod",
				"mknodat",
				"mlock",
				"mlock2",
				"mlockall",
				"mmap",
				"mmap2",
				"mprotect",
				"mq_getsetattr",
				"mq_notify",
				"mq_open",
				"mq_timedreceive",
				"mq_timedsend",
				"mq_unlink",
				"mremap",
				"msgctl",
				"msgget",
				"msgrcv",
				"msgsnd",
				"msync",
				"munlock",
				"munlockall",
				"munmap",
				"nanosleep",
				"newfstatat",
				"_newselect",
				"open",
				"openat",
				"pause",
				"pipe",
				"pipe2",
				"poll",
				"ppoll",
				"prctl",
				"pread64",
				"preadv",
				"preadv2",
				"prlimit64",
				"pselect6",
				"pwrite64",
				"pwritev",
				"pwritev2",
				"read",
				"readahead",
				"readlink",
				"readlinkat",
				"readv",
				"recv",
				"recvfrom",
				"recvmmsg",
				"recvmsg",
				"remap_file_pages",
				"removexattr",
				"rename",
				"renameat",
				"renameat2",
				"restart_syscall",
				"rmdir",
				"rt_sigaction",
				"rt_sigpending",
				"rt_sigprocmask",
				"rt_sigqueueinfo",
				"rt_sigreturn",
				"rt_sigsuspend",
				"rt_sigtimedwait",
				"rt_tgsigqueueinfo",
				"sched_getaffinity",
				"sched_getattr",
				"sched_getparam",
				"sched_get_priority_max",
				"sched_get_priority_min",
				"sched_getscheduler",
				"sched_rr_get_interval",
				"sched_setaffinity",
				"sched_setattr",
				"sched_setparam",
				"sched_setscheduler",
				"sched_yield",
				"seccomp",
				"select",
				"semctl",
				"semget",
				"semop",
				"semtimedop",
				"send",
				"sendfile",
				"sendfile64",
				"sendmmsg",
				"sendmsg",
				"sendto",
				"setfsgid",
				"setfsgid32",
				"setfsuid",
				"setfsuid32",
				"setgid",
				"setgid32",
				"setgroups",
				"setgroups32",
				"setitimer",
				"setpgid",
				"setpriority",
				"setregid",
				"setregid32",
				"setresgid",
				"setresgid32",
				"setresuid",
				"setresuid32",
				"setreuid",
				"setreuid32",
				"setrlimit",
				"set_robust_list",
				"setsid",
				"setsockopt",
				"set_thread_area",
				"set_tid_address",
				"setuid",
				"setuid32",
				"setxattr",
				"shmat",
				"shmctl",
				"shmdt",
				"shmget",
				"shutdown",
				"sigaltstack",
				"signalfd",
				"signalfd4",
				"sigreturn",
				"socket",
				"socketcall",
				"socketpair",
				"splice",
				"stat",
				"stat64",
				"statfs",
				"statfs64",
				"statx",
				"symlink",
				"symlinkat",
				"sync",
				"sync_file_range",
				"syncfs",
				"sysinfo",
				"tee",
				"tgkill",
				"time",
				"timer_create",
				"timer_delete",
				"timerfd_create",
				"timerfd_gettime",
				"timerfd_settime",
				"timer_getoverrun",
				"timer_gettime",
				"timer_settime",
				"times",
				"tkill",
				"truncate",
				"truncate64",
				"ugetrlimit",
				"umask",
				"uname",
				"unlink",
				"unlinkat",
				"utime",
				"utimensat",
				"utimes",
				"vfork",
				"vmsplice",
				"wait4",
				"waitid",
				"waitpid",
				"write",
				"writev"
			],
			"action": "SCMP_ACT_ALLOW",
			"args": [],
			"comment": "",
			"includes": {},
			"excludes": {}
		},
		{
			"names": [
				"ptrace"
			],
			"action": "SCMP_ACT_ALLOW",
			"args": null,
			"comment": "",
			"includes": {
				"minKernel": "4.8"
			},
			"excludes": {}
		},
		{
			"names": [
				"personality"
			],
			"action": "SCMP_ACT_ALLOW",
			"args": [
				{
					"index": 0,
					"value": 0,
					"valueTwo": 0,
					"op": "SCMP_CMP_EQ"
				}
			],
			"comment": "",
			"includes": {},
			"excludes": {}
		},
		{
			"names": [
				"personality"
			],
			"action": "SCMP_ACT_ALLOW",
			"args": [
				{
					"index": 0,
					"value": 8,
					"valueTwo": 0,
					"op": "SCMP_CMP_EQ"
				}
			],
			"comment": "",
			"includes": {},
			"excludes": {}
		},
		{
			"names": [
				"personality"
			],
			"action": "SCMP_ACT_ALLOW",
			"args": [
				{
					"index": 0,
					"value": 131072,
					"valueTwo": 0,
					"op": "SCMP_CMP_EQ"
				}
			],
			"comment": "",
			"includes": {},
			"excludes": {}
		},
		{
			"names": [
				"personality"
			],
			"action": "SCMP_ACT_ALLOW",
			"args": [
				{
					"index": 0,
					"value": 131080,
					"valueTwo": 0,
					"op": "SCMP_CMP_EQ"
				}
			],
			"comment": "",
			"includes": {},
			"excludes": {}
		},
		{
			"names": [
				"personality"
			],
			"action": "SCMP_ACT_ALLOW",
			"args": [
				{
					"index": 0,
					"value": 4294967295,
					"valueTwo": 0,
					"op": "SCMP_CMP_EQ"
				}
			],
			"comment": "",
			"includes": {},
			"excludes": {}
		},
		{
			"names": [
				"sync_file_range2"
			],
			"action": "SCMP_ACT_ALLOW",
			"args": [],
			"comment": "",
			"includes": {
				"arches": [
					"ppc64le"
				]
			},
			"excludes": {}
		},
		{
			"names": [
				"arm_fadvise64_64",
				"arm_sync_file_range",
				"sync_file_range2",
				"breakpoint",
				"cacheflush",
				"set_tls"
			],
			"action": "SCMP_ACT_ALLOW",
			"args": [],
			"comment": "",
			"includes": {
				"arches": [
					"arm",
					"arm64"
				]
			},
			"excludes": {}
		},
		{
			"names": [
				"arch_prctl"
			],
			"action": "SCMP_ACT_ALLOW",
			"args": [],
			"comment": "",
			"includes": {
				"arches": [
					"amd64",
					"x32"
				]
			},
			"excludes": {}
		},
		{
			"names": [
				"modify_ldt"
			],
			"action": "SCMP_ACT_ALLOW",
			"args": [],
			"comment": "",
			"includes": {
				"arches": [
					"amd64",
					"x32",
					"x86"
				]
			},
			"excludes": {}
		},
		{
			"names": [
				"s390_pci_mmio_read",
				"s390_pci_mmio_write",
				"s390_runtime_instr"
			],
			"action": "SCMP_ACT_ALLOW",
			"args": [],
			"comment": "",
			"includes": {
				"arches": [
					"s390",
					"s390x"
				]
			},
			"excludes": {}
		},
		{
			"names": [
				"open_by_handle_at"
			],
			"action": "SCMP_ACT_ALLOW",
			"args": [],
			"comment": "",
			"includes": {
				"caps": [
					"CAP_DAC_READ_SEARCH"
				]
			},
			"excludes": {}
		},
		{
			"names": [
				"bpf",
				"clone",
				"fanotify_init",
				"lookup_dcookie",
				"mount",
				"name_to_handle_at",
				"perf_event_open",
				"quotactl",
				"setdomainname",
				"sethostname",
				"setns",
				"syslog",
				"umount",
				"umount2",
				"unshare"
			],
			"action": "SCMP_ACT_ALLOW",
			"args": [],
			"comment": "",
			"includes": {
				"caps": [
					"CAP_SYS_ADMIN"
				]
			},
			"excludes": {}
		},
		{
			"names": [
				"clone"
			],
			"action": "SCMP_ACT_ALLOW",
			"args": [
				{
					"index": 0,
					"value": 2080505856,
					"valueTwo": 0,
					"op": "SCMP_CMP_MASKED_EQ"
				}
			],
			"comment": "",
			"includes": {},
			"excludes": {
				"caps": [
					"CAP_SYS_ADMIN"
				],
				"arches": [
					"s390",
					"s390x"
				]
			}
		},
		{
			"names": [
				"clone"
			],
			"action": "SCMP_ACT_ALLOW",
			"args": [
				{
					"index": 1,
					"value": 2080505856,
					"valueTwo": 0,
					"op": "SCMP_CMP_MASKED_EQ"
				}
			],
			"comment": "s390 parameter ordering for clone is different",
			"includes": {
				"arches": [
					"s390",
					"s390x"
				]
			},
			"excludes": {
				"caps": [
					"CAP_SYS_ADMIN"
				]
			}
		},
		{
			"names": [
				"reboot"
			],
			"action": "SCMP_ACT_ALLOW",
			"args": [],
			"comment": "",
			"includes": {
				"caps": [
					"CAP_SYS_BOOT"
				]
			},
			"excludes": {}
		},
		{
			"names": [
				"chroot"
			],
			"action": "SCMP_ACT_ALLOW",
			"args": [],
			"comment": "",
			"includes": {
				"caps": [
					"CAP_SYS_CHROOT"
				]
			},
			"excludes": {}
		},
		{
			"names": [
				"delete_module",
				"init_module",
				"finit_module",
				"query_module"
			],
			"action": "SCMP_ACT_ALLOW",
			"args": [],
			"comment": "",
			"includes": {
				"caps": [
					"CAP_SYS_MODULE"
				]
			},
			"excludes": {}
		},
		{
			"names": [
				"acct"
			],
			"action": "SCMP_ACT_ALLOW",
			"args": [],
			"comment": "",
			"includes": {
				"caps": [
					"CAP_SYS_PACCT"
				]
			},
			"excludes": {}
		},
		{
			"names": [
				"kcmp",
				"process_vm_readv",
				"process_vm_writev",
				"ptrace"
			],
			"action": "SCMP_ACT_ALLOW",
			"args": [],
			"comment": "",
			"includes": {
				"caps": [
					"CAP_SYS_PTRACE"
				]
			},
			"excludes": {}
		},
		{
			"names": [
				"iopl",
				"ioperm"
			],
			"action": "SCMP_ACT_ALLOW",
			"args": [],
			"comment": "",
			"includes": {
				"caps": [
					"CAP_SYS_RAWIO"
				]
			},
			"excludes": {}
		},
		{
			"names": [
				"settimeofday",
				"stime",
				"clock_settime"
			],
			"action": "SCMP_ACT_ALLOW",
			"args": [],
			"comment": "",
			"includes": {
				"caps": [
					"CAP_SYS_TIME"
				]
			},
			"excludes": {}
		},
		{
			"names": [
				"vhangup"
			],
			"action": "SCMP_ACT_ALLOW",
			"args": [],
			"comment": "",
			"includes": {
				"caps": [
					"CAP_SYS_TTY_CONFIG"
				]
			},
			"excludes": {}
		},
		{
			"names": [
				"get_mempolicy",
				"mbind",
				"set_mempolicy"
			],
			"action": "SCMP_ACT_ALLOW",
			"args": [],
			"comment": "",
			"includes": {
				"caps": [
					"CAP_SYS_NICE"
				]
			},
			"excludes": {}
		},
		{
			"names": [
				"syslog"
			],
			"action": "SCMP_ACT_ALLOW",
			"args": [],
			"comment": "",
			"includes": {
				"caps": [
					"CAP_SYSLOG"
				]
			},
			"excludes": {}
		},
		{
			"names": [
			    "clone",
			    "mount",
			    "umount",
			    "umount2",
                            "unshare",
                            "pivot_root"
			],
			"action": "SCMP_ACT_ALLOW",
			"args": [],
			"comment": "",
			"includes": {},
			"excludes": {}
		}
	]
}

===== ./data/org.freedesktop.portal.Documents.xml =====
<!DOCTYPE node PUBLIC
"-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">

<!--
 Copyright (C) 2015 Red Hat, Inc.

 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 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.

 Author: Alexander Larsson <alexl@redhat.com>
-->

<node name="/" xmlns:doc="http://www.freedesktop.org/dbus/1.0/doc.dtd">
  <!--
      org.freedesktop.portal.Documents:
      @short_description: Document portal

      The document portal allows to make files from the outside world
      available to sandboxed applications in a controlled way.

      Exported files will be made accessible to the application via
      a fuse filesystem that gets mounted at /run/user/$UID/doc/. The
      filesystem gets mounted both outside and inside the sandbox, but
      the view inside the sandbox is restricted to just those files
      that the application is allowed to access.

      Individual files will appear at /run/user/$UID/doc/$DOC_ID/filename,
      where $DOC_ID is the ID of the file in the document store. It is
      returned by the org.freedesktop.portal.Documents.Add() and
      org.freedesktop.portal.Documents.AddNamed() calls.

      The permissions that the application has for a document store entry
      (see org.freedesktop.portal.Documents.GrantPermissions()) are reflected
      in the POSIX mode bits in the fuse filesystem.

      The D-Bus interface for the document portal is available under the
      bus name org.freedesktop.portal.Documents and the object path
      /org/freedesktop/portal/documents.
 
      This documentation describes version 3 of this interface.
  -->
  <interface name='org.freedesktop.portal.Documents'>
    <property name="version" type="u" access="read"/>

    <!--
        GetMountPoint:
        @path: the path at which the fuse filesystem is mounted

        Returns the path at which the document store fuse filesystem
        is mounted. This will typically be /run/user/$UID/doc/.
    -->
    <method name="GetMountPoint">
      <arg type='ay' name='path' direction='out'/>
    </method>

    <!--
        Add:
        @o_path_fd: open file descriptor for the file to add
        @reuse_existing: whether to reuse an existing document store entry for the file
        @persistent: whether to add the file only for this session or permanently
        @doc_id: the ID of the file in the document store

        Adds a file to the document store. The file is passed in the
        form of an open file descriptor to prove that the caller has
        access to the file.
    -->
    <method name="Add">
      <annotation name="org.gtk.GDBus.C.UnixFD" value="true"/>
      <arg type='h' name='o_path_fd' direction='in'/>
      <arg type='b' name='reuse_existing' direction='in'/>
      <arg type='b' name='persistent' direction='in'/>
      <arg type='s' name='doc_id' direction='out'/>
    </method>

    <!--
        AddNamed:
        @o_path_parent_fd: open file descriptor for the parent directory
        @filename: the basename for the file
        @reuse_existing: whether to reuse an existing document store entry for the file
        @persistent: whether to add the file only for this session or permanently
        @doc_id: the ID of the file in the document store

        Creates an entry in the document store for writing a new file.
    -->
    <method name="AddNamed">
      <annotation name="org.gtk.GDBus.C.UnixFD" value="true"/>
      <arg type='h' name='o_path_parent_fd' direction='in'/>
      <arg type='ay' name='filename' direction='in'/>
      <arg type='b' name='reuse_existing' direction='in'/>
      <arg type='b' name='persistent' direction='in'/>
      <arg type='s' name='doc_id' direction='out'/>
    </method>

    <!--
        AddFull:
        @o_path_fds: open file descriptors for the files to export
        @flags: flags, 1 == reuse_existing, 2 == persistent, 4 == as-needed-by-app
        @app_id: an application ID, or empty string
        @permissions: the permissions to grant, possible values are 'read', 'write', 'grant-permissions' and 'delete'
        @doc_ids: the IDs of the files in the document store
        @extra_info: Extra info returned

        Adds multiple files to the document store. The file is passed in the
        form of an open file descriptor to prove that the caller has
        access to the file.

        If the as-needed-by-app flag is given, files will only be added to
        the document store if the application does not already have access to them.
        For files that are not added to the document store, the doc_ids array will
        contain an empty string.

        Additionally, if app_id is specified, it will be given the permissions
        listed in GrantPermission.

        The method also returns some extra info that can be used to avoid
        multiple roundtrips. For now it only contains as "mountpoint", the
        fuse mountpoint of the document portal.

        This method was added in version 2 of the org.freedesktop.portal.Documents interface.
    -->
    <method name="AddFull">
      <annotation name="org.gtk.GDBus.C.UnixFD" value="true"/>
      <arg type='ah' name='o_path_fds' direction='in'/>
      <arg type='u' name='flags' direction='in'/>
      <arg type='s' name='app_id' direction='in'/>
      <arg type='as' name='permissions' direction='in'/>
      <arg type='as' name='doc_ids' direction='out'/>
      <arg type='a{sv}' name='extra_out' direction='out'/>
    </method>

    <!--
        AddNamedFull:
        @o_path_fds: open file descriptor for the parent directory
        @filename: the basename for the file
        @flags: flags, 1 == reuse_existing, 2 == persistent, 4 == as-needed-by-app
        @app_id: an application ID, or empty string
        @permissions: the permissions to grant, possible values are 'read', 'write', 'grant-permissions' and 'delete'
        @doc_id: the ID of the file in the document store
        @extra_info: Extra info returned

        Creates an entry in the document store for writing a new file.

        If the as-needed-by-app flag is given, file will only be added to
        the document store if the application does not already have access to it.
        For file that is not added to the document store, the doc_id will
        contain an empty string.

        Additionally, if app_id is specified, it will be given the permissions
        listed in GrantPermission.

        The method also returns some extra info that can be used to avoid
        multiple roundtrips. For now it only contains as "mountpoint", the
        fuse mountpoint of the document portal.

        This method was added in version 3 of the org.freedesktop.portal.Documents interface.
    -->
    <method name="AddNamedFull">
      <annotation name="org.gtk.GDBus.C.UnixFD" value="true"/>
      <arg type='h' name='o_path_fd' direction='in'/>
      <arg type='ay' name='filename' direction='in'/>
      <arg type='u' name='flags' direction='in'/>
      <arg type='s' name='app_id' direction='in'/>
      <arg type='as' name='permissions' direction='in'/>
      <arg type='s' name='doc_id' direction='out'/>
      <arg type='a{sv}' name='extra_out' direction='out'/>
    </method>

    <!--
        GrantPermissions:
        @doc_id: the ID of the file in the document store
        @app_id: the ID of the application to which permissions are granted
        @permissions: the permissions to grant, possible values are 'read', 'write', 'grant-permissions' and 'delete'

        Grants access permissions for a file in the document store
        to an application.

        This call is available inside the sandbox if the application
        has the 'grant-permissions' permission for the document.
    -->
    <method name="GrantPermissions">
      <arg type='s' name='doc_id' direction='in'/>
      <arg type='s' name='app_id' direction='in'/>
      <arg type='as' name='permissions' direction='in'/>
    </method>

    <!--
        RevokePermissions:
        @doc_id: the ID of the file in the document store
        @app_id: the ID of the application from which permissions are revoked
        @permissions: the permissions to revoke, possible values are 'read', 'write', 'grant-permissions' and 'delete'

        Revokes access permissions for a file in the document store
        from an application.

        This call is available inside the sandbox if the application
        has the 'grant-permissions' permission for the document.
    -->
    <method name="RevokePermissions">
      <arg type='s' name='doc_id' direction='in'/>
      <arg type='s' name='app_id' direction='in'/>
      <arg type='as' name='permissions' direction='in'/>
    </method>

    <!--
        Delete:
        @doc_id: the ID of the file in the document store

        Removes an entry from the document store. The file itself is
        not deleted.

        This call is available inside the sandbox if the application
        has the 'delete' permission for the document.
    -->
    <method name="Delete">
      <arg type='s' name='doc_id' direction='in'/>
    </method>

    <!--
        Lookup:
        @filename: a path in the host filesystem
        @doc_id: the ID of the file in the document store, or '' if the file is not in the document store

        Looks up the document ID for a file.

        This call is not available inside the sandbox.
    -->
    <method name="Lookup">
      <arg type='ay' name='filename' direction='in'/>
      <arg type='s' name='doc_id' direction='out'/>
    </method>

    <!--
        Info:
        @doc_id: the ID of the file in the document store
        @path: the path for the file in the host filesystem
        @apps: a dictionary mapping application IDs to the permissions for that application

        Gets the filesystem path and application permissions for a document store
        entry.

        This call is not available inside the sandbox.
    -->
    <method name="Info">
      <arg type='s' name='doc_id' direction='in'/>
      <arg type='ay' name='path' direction='out'/>
      <arg type='a{sas}' name='apps' direction='out'/>
    </method>

    <!--
        List:
        @app_id: an application ID, or '' to list all documents
        @docs: a dictionary mapping document IDs to their filesystem path

        Lists documents in the document store for an application (or for
        all applications).

        This call is not available inside the sandbox.
    -->
    <method name="List">
      <arg type='s' name='app_id' direction='in'/>
      <arg type='a{say}' name='docs' direction='out'/>
    </method>
  </interface>
</node>

===== ./data/org.freedesktop.Flatpak.xml =====
<!DOCTYPE node PUBLIC
"-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">

<!--
 Copyright (C) 2015 Red Hat, Inc.

 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 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.

 Author: Alexander Larsson <alexl@redhat.com>
-->

<node name="/" xmlns:doc="http://www.freedesktop.org/dbus/1.0/doc.dtd">
  <!--
      org.freedesktop.Flatpak.SessionHelper:
      @short_description: Flatpak session service

      The Flatpak session service is used by the
      <command>flatpak run</command> command
      to bridge various resources from the host system into Flatpak
      sandboxes. It is not intended to be contacted by third-party
      applications or libraries.

      This interface is provided on the D-Bus session bus by the
      well-known D-Bus name org.freedesktop.Flatpak,
      at the object path /org/freedesktop/Flatpak/SessionHelper.

      Note that the service owning the org.freedesktop.Flatpak
      well-known name also exports the
      org.freedesktop.Flatpak.Development interface. As a result,
      letting a sandboxed application contact that well-known name
      is a sandbox escape, which must only be allowed for trusted
      applications where there is not intended to be any security
      boundary between sandbox and host system.

      This documentation describes version 1 of this interface.
  -->
  <interface name='org.freedesktop.Flatpak.SessionHelper'>
    <!--
        version:

        The API version number.
        This documentation describes version 1 of this interface.
    -->
    <property name="version" type="u" access="read"/>

    <!--
        RequestSession:
        @data: Information about the new session

        Set up monitoring and resources for a
        <command>flatpak run</command> session.
        See the Flatpak source code for details.
    -->
    <method name="RequestSession">
      <arg type='a{sv}' name='data' direction='out'/>
    </method>
  </interface>

  <!--
      org.freedesktop.Flatpak.Development:
      @short_description: Flatpak development interface

      The Development interface lets any client, possibly in a sandbox if
      it has access to the session helper, spawn a process on the host,
      outside any sandbox.

      Clearly this is not something you typically want a sandboxed app to
      do: it is a sandbox escape allowing arbitrary code execution,
      and must not be allowed for applications where sandboxing is
      intended to be a security boundary.

      However, it is very useful when using Flatpak for distribution and
      choice of runtime library stack, without intending to create a
      security boundary. For instance, if an IDE like GNOME Builder is
      distributed as a trusted Flatpak app and will be used to build other
      Flatpak apps, it needs to use this facility to launch a Flatpak
      build operation inside the sandbox, because otherwise recursive
      calls to flatpak will not work.

      This interface is provided on the D-Bus session bus by the
      well-known D-Bus name org.freedesktop.Flatpak,
      at the object path /org/freedesktop/Flatpak/Development.

      This documentation describes version 1 of this interface.
  -->
  <interface name='org.freedesktop.Flatpak.Development'>
    <!--
        version:

        The API version number.
        This documentation describes version 1 of this interface.
    -->
    <property name="version" type="u" access="read"/>

    <!--
        HostCommand:
        @cwd_path: the working directory for the new process
        @argv: the argv for the new process, starting with the executable to launch
        @fds: an array of file descriptors to pass to the new process
        @envs: an array of variable/value pairs for the environment of the new process
        @flags: flags
        @pid: the PID of the new process

        This method lets trusted applications (insider or outside a
        sandbox) run arbitrary commands in the user's session, outside
        any sandbox.

        The following flags values are supported:

        <variablelist>
          <varlistentry>
            <term>1 (FLATPAK_HOST_COMMAND_FLAGS_CLEAR_ENV)</term>
            <listitem><para>
              Clear the environment.
            </para></listitem>
          </varlistentry>
          <varlistentry>
            <term>2 (FLATPAK_HOST_COMMAND_FLAGS_WATCH_BUS)</term>
            <listitem><para>
              Kill the sandbox when the caller disappears from the session bus.
            </para></listitem>
          </varlistentry>
        </variablelist>

        Unknown (unsupported) flags are an error and will cause HostCommand()
        to fail.

        Note that unlike org.freedesktop.portal.Flatpak.Spawn(), there
        is no options parameter here.
    -->
    <method name="HostCommand">
      <annotation name="org.gtk.GDBus.C.UnixFD" value="true"/>
      <arg type='ay' name='cwd_path' direction='in'/>
      <arg type='aay' name='argv' direction='in'/>
      <arg type='a{uh}' name='fds' direction='in'/>
      <arg type='a{ss}' name='envs' direction='in'/>
      <arg type='u' name='flags' direction='in'/>
      <arg type='u' name='pid' direction='out'/>
    </method>

    <!--
        HostCommandSignal:
        @pid: the process ID on the host system
        @signal: the signal to send (see <citerefentry><refentrytitle>signal</refentrytitle><manvolnum>7</manvolnum></citerefentry>)
        @to_process_group: whether to send the signal to the process group

        This method lets you send a Unix signal to a process
        that was started with org.freedesktop.Flatpak.Development.HostCommand().
        The @pid argument here must be a PID that was returned by a
        call to HostCommand() from the same sender: terminating unrelated
        processes is not allowed.
    -->
    <method name="HostCommandSignal">
      <arg type='u' name='pid' direction='in'/>
      <arg type='u' name='signal' direction='in'/>
      <arg type='b' name='to_process_group' direction='in'/>
    </method>

    <!--
        HostCommandExited:
        @pid: the PID of the process that has ended
        @exit_status: the wait status (see <citerefentry><refentrytitle>waitpid</refentrytitle><manvolnum>2</manvolnum></citerefentry>)

        Emitted when a process started by
        org.freedesktop.Flatpak.Development.HostCommand() exits.
        Use g_spawn_check_exit_status(), or the macros such as
        WIFEXITED documented in
        <citerefentry><refentrytitle>waitpid</refentrytitle><manvolnum>2</manvolnum></citerefentry>,
        to interpret the @exit_status.

        This signal is not emitted for processes that were not launched
        directly by HostCommand(), for example if a process launched by
        HostCommand() runs foreground or background child processes.
    -->
    <signal name="HostCommandExited">
      <arg type='u' name='pid' direction='out'/>
      <arg type='u' name='exit_status' direction='out'/>
    </signal>

  </interface>

  <!--
      org.freedesktop.Flatpak.SystemHelper:
      @short_description: Flatpak system service

      The Flatpak system service is used by the libflatpak library
      to manipulate Flatpak applications and runtimes that are installed
      system-wide, for example when implementing
      <command>flatpak install</command>.
      It is not intended to be contacted by third-party applications
      or libraries. See the Flatpak source code for more
      details of this interface's methods.

      This interface is provided on the D-Bus system bus by the
      well-known D-Bus name org.freedesktop.Flatpak.SystemHelper,
      at the object path /org/freedesktop/Flatpak/SystemHelper.

      The system helper runs as a privileged user at the system level,
      and receives method calls from less-privileged users.
      Authorization for method calls on this interface is mediated by
      polkit (formerly PolicyKit) using the policy configuration
      org.freedesktop.Flatpak.policy, and can be configured by
      system administrators in the same way as for any other system service
      that uses polkit.
  -->
  <interface name='org.freedesktop.Flatpak.SystemHelper'>
    <property name="version" type="u" access="read"/>

    <method name="Deploy">
      <arg type='ay' name='repo_path' direction='in'/>
      <arg type='u' name='flags' direction='in'/>
      <arg type='s' name='ref' direction='in'/>
      <arg type='s' name='origin' direction='in'/>
      <arg type='as' name='subpaths' direction='in'/>
      <arg type='as' name='previous_ids' direction='in'/>
      <arg type='s' name='installation' direction='in'/>
    </method>

    <method name="DeployAppstream">
      <arg type='ay' name='repo_path' direction='in'/>
      <arg type='u' name='flags' direction='in'/>
      <arg type='s' name='origin' direction='in'/>
      <arg type='s' name='arch' direction='in'/>
      <arg type='s' name='installation' direction='in'/>
    </method>

    <method name="Uninstall">
      <arg type='u' name='flags' direction='in'/>
      <arg type='s' name='ref' direction='in'/>
      <arg type='s' name='installation' direction='in'/>
    </method>

    <method name="InstallBundle">
      <arg type='ay' name='bundle_path' direction='in'/>
      <arg type='u' name='flags' direction='in'/>
      <arg type='s' name='remote' direction='in'/>
      <arg type='s' name='installation' direction='in'/>
      <arg type='s' name='ref' direction='out'/>
    </method>

    <method name="ConfigureRemote">
      <arg type='u' name='flags' direction='in'/>
      <arg type='s' name='remote' direction='in'/>
      <arg type='s' name='config' direction='in'/>
      <arg type='ay' name='gpg_key' direction='in'>
        <annotation name="org.gtk.GDBus.C.ForceGVariant" value="true"/>
      </arg>
      <arg type='s' name='installation' direction='in'/>
    </method>

    <method name="Configure">
      <arg type='u' name='flags' direction='in'/>
      <arg type='s' name='key' direction='in'/>
      <arg type='s' name='value' direction='in'/>
      <arg type='s' name='installation' direction='in'/>
    </method>

    <method name="UpdateRemote">
      <arg type='u' name='flags' direction='in'/>
      <arg type='s' name='remote' direction='in'/>
      <arg type='s' name='installation' direction='in'/>
      <arg type='ay' name='summary_path' direction='in'/>
      <arg type='ay' name='summary_sig_path' direction='in'/>
    </method>

    <method name="RemoveLocalRef">
      <arg type='u' name='flags' direction='in'/>
      <arg type='s' name='remote' direction='in'/>
      <arg type='s' name='ref' direction='in'/>
      <arg type='s' name='installation' direction='in'/>
    </method>

    <method name="PruneLocalRepo">
      <arg type='u' name='flags' direction='in'/>
      <arg type='s' name='installation' direction='in'/>
    </method>

    <method name="RunTriggers">
      <arg type='u' name='flags' direction='in'/>
      <arg type='s' name='installation' direction='in'/>
    </method>

    <method name="EnsureRepo">
      <arg type='u' name='flags' direction='in'/>
      <arg type='s' name='installation' direction='in'/>
    </method>

    <method name="UpdateSummary">
      <arg type='u' name='flags' direction='in'/>
      <arg type='s' name='installation' direction='in'/>
    </method>

    <method name="GenerateOciSummary">
      <arg type='u' name='flags' direction='in'/>
      <arg type='s' name='origin' direction='in'/>
      <arg type='s' name='installation' direction='in'/>
    </method>

    <method name="CancelPull">
      <arg type='u' name='flags' direction='in'/>
      <arg type='s' name='installation' direction='in'/>
      <arg type='s' name='src_dir' direction='in'/>
    </method>

    <method name="GetRevokefsFd">
      <annotation name="org.gtk.GDBus.C.UnixFD" value="true"/>
      <arg type='u' name='flags' direction='in'/>
      <arg type='s' name='installation' direction='in'/>
      <arg type='h' name='fd_index' direction='out'/>
      <arg type='s' name='src_dir' direction='out'/>
    </method>

  </interface>

</node>

===== ./data/flatpak-variants.gv =====
/* Commanly used, give a name */
type Metadata [string] variant;
type Checksum []byte;

type RefInfo {
    commit_size: uint64;
    checksum: Checksum;
    metadata: Metadata;
};

/* Note: RefMaps are sorted by ref */
type RefMap [] 'RefMapEntry {
  ref: string;
  info: RefInfo;
};

type Summary {
    ref_map: RefMap;
    metadata: Metadata;
};

type CollectionMap [sorted string] RefMap;

type Commit {
    metadata: Metadata;
    parent: Checksum;
    related: [] 'Related {
        ref: string;
        commit: Checksum;
    };
    subject: string;
    body: string;
    timestamp: bigendian uint64;
    root_contents: Checksum;
    root_metadata: Checksum;
};

type Cache [sorted string] 'CacheData {
  installed_size: bigendian uint64;
  download_size: bigendian uint64;
  metadata: string;
};

type SparseCache [sorted string] Metadata;

type CommitsCache []Checksum;

type DeployData {
 origin: string;
 commit: string;
 subpaths: []string;
 installed_size: bigendian uint64;
 metadata: Metadata;
};

type ContentRating {
 rating_type: string;
 ratings: 'Ratings [string] string;
};

type ExtraDataSize {
 n_extra_data: littleendian uint32;
 total_size: littleendian uint64;
};

type Subsummary {
  checksum: Checksum;
  history: []Checksum;
  metadata: Metadata;
};

type SummaryIndex {
 subsummaries: [sorted string]Subsummary;
 metadata: Metadata;
};

type ObjectListInfo {
 is_loose: boolean;
 packfiles: []string;
};

type ObjectName {
 checksum: string;
 objtype: uint32;
};

type ObjectNames []ObjectName;

===== ./data/org.freedesktop.systemd1.xml =====
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
<node>
 <interface name="org.freedesktop.systemd1.Manager">
  <method name="StartTransientUnit">
   <arg type="s" direction="in" name="name"/>
   <arg type="s" direction="in" name="mode"/>
   <arg type="a(sv)" direction="in" name="properties"/>
   <arg type="a(sa(sv))" direction="in" name="aux"/>
   <arg type="o" direction="out" name="job"/>
  </method>
  <signal name="JobRemoved">
   <arg type="u" name="id"/>
   <arg type="o" name="job"/>
   <arg type="s" name="unit"/>
   <arg type="s" name="result"/>
  </signal>
 </interface>
</node>

===== ./portal/flatpak-portal-app-info.h =====
/*
 * Copyright © 2018 Red Hat, Inc
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Alexander Larsson <alexl@redhat.com>
 */

#ifndef __FLATPAK_PORTAL_APP_INFO_H__
#define __FLATPAK_PORTAL_APP_INFO_H__

#include "flatpak-metadata-private.h"

GKeyFile * flatpak_invocation_lookup_app_info (GDBusMethodInvocation *invocation,
                                               GCancellable          *cancellable,
                                               GError               **error);

void flatpak_connection_track_name_owners (GDBusConnection *connection);

#endif /* __FLATPAK_PORTAL_APP_INFO_H__ */

===== ./portal/flatpak-portal.service.in =====
[Unit]
Description=flatpak portal
PartOf=graphical-session.target

[Service]
BusName=org.freedesktop.portal.Flatpak
ExecStart=@libexecdir@/flatpak-portal
Type=dbus

===== ./portal/portal-impl.h =====
/*
 * Copyright © 2016 Red Hat, Inc
 *
 * This program 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 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Alexander Larsson <alexl@redhat.com>
 *       Matthias Clasen <mclasen@redhat.com>
 */

#ifndef __PORTAL_IMPL_H__
#define __PORTAL_IMPL_H__

#include <glib.h>

typedef struct {
  char *source;
  char *dbus_name;
  char **interfaces;
  char **use_in;
  int priority;
} PortalImplementation;

void                  load_installed_portals     (gboolean opt_verbose);
PortalImplementation *find_portal_implementation (const char *interface);

#endif  /* __PORTAL_IMPL_H__ */

===== ./portal/flatpak-portal-app-info.c =====
/* vi:set et sw=2 sts=2 cin cino=t0,f0,(0,{s,>2s,n-s,^-s,e-s:
 * Copyright © 2018 Red Hat, Inc
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Alexander Larsson <alexl@redhat.com>
 */

#include "config.h"

#include <gio/gio.h>
#include "libglnx.h"
#include "flatpak-portal-app-info.h"
#include "flatpak-portal-error.h"

G_LOCK_DEFINE (app_infos);
static GHashTable *app_infos;

static void
ensure_app_infos (void)
{
  if (app_infos == NULL)
    app_infos = g_hash_table_new_full (g_str_hash, g_str_equal,
                                       g_free,
                                       (GDestroyNotify) g_key_file_unref);
}

static GKeyFile *
lookup_cached_app_info_by_sender (const char *sender)
{
  GKeyFile *keyfile = NULL;

  G_LOCK (app_infos);
  keyfile = g_hash_table_lookup (app_infos, sender);
  if (keyfile)
    g_key_file_ref (keyfile);
  G_UNLOCK (app_infos);

  return keyfile;
}

static void
invalidate_cached_app_info_by_sender (const char *sender)
{
  G_LOCK (app_infos);
  g_hash_table_remove (app_infos, sender);
  G_UNLOCK (app_infos);
}

static void
add_cached_app_info_by_sender (const char *sender, GKeyFile *keyfile)
{
  G_LOCK (app_infos);
  g_hash_table_insert (app_infos, g_strdup (sender), g_key_file_ref (keyfile));
  G_UNLOCK (app_infos);
}


/* Returns NULL on failure, keyfile with name "" if not sandboxed, and full app-info otherwise */
static GKeyFile *
parse_app_id_from_fileinfo (int pid)
{
  g_autofree char *root_path = NULL;
  glnx_autofd int root_fd = -1;
  glnx_autofd int info_fd = -1;
  struct stat stat_buf;
  g_autoptr(GError) local_error = NULL;
  g_autoptr(GMappedFile) mapped = NULL;
  g_autoptr(GKeyFile) metadata = NULL;

  root_path = g_strdup_printf ("/proc/%u/root", pid);
  if (!glnx_opendirat (AT_FDCWD, root_path, TRUE,
                       &root_fd,
                       &local_error))
    {
      /* Not able to open the root dir shouldn't happen. Probably the app died and
       * we're failing due to /proc/$pid not existing. In that case fail instead
         of treating this as privileged. */
      g_info ("Unable to open process root directory: %s", local_error->message);
      return NULL;
    }

  metadata = g_key_file_new ();

  info_fd = openat (root_fd, ".flatpak-info", O_RDONLY | O_CLOEXEC | O_NOCTTY);
  if (info_fd == -1)
    {
      if (errno == ENOENT)
        {
          /* No file => on the host */
          g_key_file_set_string (metadata, FLATPAK_METADATA_GROUP_APPLICATION,
                                 FLATPAK_METADATA_KEY_NAME, "");
          return g_steal_pointer (&metadata);
        }

      return NULL; /* Some weird error => failure */
    }

  if (fstat (info_fd, &stat_buf) != 0 || !S_ISREG (stat_buf.st_mode))
    return NULL; /* Some weird fd => failure */

  mapped = g_mapped_file_new_from_fd (info_fd, FALSE, &local_error);
  if (mapped == NULL)
    {
      g_warning ("Can't map .flatpak-info file: %s", local_error->message);
      return NULL;
    }

  if (!g_key_file_load_from_data (metadata,
                                  g_mapped_file_get_contents (mapped),
                                  g_mapped_file_get_length (mapped),
                                  G_KEY_FILE_NONE, &local_error))
    {
      g_warning ("Can't load .flatpak-info file: %s", local_error->message);
      return NULL;
    }

  return g_steal_pointer (&metadata);
}

GKeyFile *
flatpak_invocation_lookup_app_info (GDBusMethodInvocation *invocation,
                                    GCancellable          *cancellable,
                                    GError               **error)
{
  GDBusConnection *connection = g_dbus_method_invocation_get_connection (invocation);
  const gchar *sender = g_dbus_method_invocation_get_sender (invocation);
  g_autoptr(GDBusMessage) msg = NULL;
  g_autoptr(GDBusMessage) reply = NULL;
  g_autoptr(GVariantIter) iter = NULL;
  const char *key;
  GVariant *value;
  GKeyFile *keyfile;

  keyfile = lookup_cached_app_info_by_sender (sender);
  if (keyfile)
    return keyfile;

  msg = g_dbus_message_new_method_call ("org.freedesktop.DBus",
                                        "/org/freedesktop/DBus",
                                        "org.freedesktop.DBus",
                                        "GetConnectionCredentials");
  g_dbus_message_set_body (msg, g_variant_new ("(s)", sender));

  reply = g_dbus_connection_send_message_with_reply_sync (connection, msg,
                                                          G_DBUS_SEND_MESSAGE_FLAGS_NONE,
                                                          30000,
                                                          NULL,
                                                          cancellable,
                                                          error);
  if (reply == NULL)
    return NULL;

  if (g_dbus_message_get_message_type (reply) == G_DBUS_MESSAGE_TYPE_METHOD_RETURN)
    {
      GVariant *body = g_dbus_message_get_body (reply);

      g_variant_get (body, "(a{sv})", &iter);
      while (g_variant_iter_loop (iter, "{&sv}", &key, &value))
        {
          if (strcmp (key, "ProcessID") == 0)
            {
              guint32 pid = g_variant_get_uint32 (value);
              g_variant_unref (value);
              keyfile = parse_app_id_from_fileinfo (pid);
              break;
            }
        }
    }

  if (keyfile == NULL)
    {
      g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Can't find peer app id");
      return NULL;
    }

  add_cached_app_info_by_sender (sender, keyfile);

  return keyfile;
}

static void
name_owner_changed (GDBusConnection *connection,
                    const gchar     *sender_name,
                    const gchar     *object_path,
                    const gchar     *interface_name,
                    const gchar     *signal_name,
                    GVariant        *parameters,
                    gpointer         user_data)
{
  g_autofree char *name = NULL;
  g_autofree char *from = NULL;
  g_autofree char *to = NULL;

  g_variant_get (parameters, "(sss)", &name, &from, &to);

  if (name[0] == ':' &&
      strcmp (name, from) == 0 &&
      strcmp (to, "") == 0)
    {
      invalidate_cached_app_info_by_sender (name);
    }
}

void
flatpak_connection_track_name_owners (GDBusConnection *connection)
{
  ensure_app_infos ();
  g_dbus_connection_signal_subscribe (connection,
                                      "org.freedesktop.DBus",
                                      "org.freedesktop.DBus",
                                      "NameOwnerChanged",
                                      "/org/freedesktop/DBus",
                                      NULL,
                                      G_DBUS_SIGNAL_FLAGS_NONE,
                                      name_owner_changed,
                                      NULL, NULL);
}

===== ./portal/flatpak-portal.c =====
/* vi:set et sw=2 sts=2 cin cino=t0,f0,(0,{s,>2s,n-s,^-s,e-s:
 * Copyright © 2018 Red Hat, Inc
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Alexander Larsson <alexl@redhat.com>
 */

#include "config.h"

/* NOTE: This code was copied mostly as-is from xdg-desktop-portal */

#include <locale.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <signal.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/socket.h>

#include <glib-unix.h>
#include <glib/gi18n-lib.h>
#include <gio/gio.h>
#include <gio/gunixfdlist.h>
#include <gio/gunixinputstream.h>
#include <gio/gunixoutputstream.h>
#include <gio/gdesktopappinfo.h>
#include "flatpak-portal-dbus.h"
#include "flatpak-portal.h"
#include "flatpak-dir-private.h"
#include "flatpak-utils-private.h"
#include "flatpak-transaction.h"
#include "flatpak-installation-private.h"
#include "flatpak-instance-private.h"
#include "flatpak-portal-app-info.h"
#include "flatpak-portal-error.h"
#include "flatpak-utils-base-private.h"
#include "portal-impl.h"
#include "flatpak-permission-dbus.h"

/* GLib 2.47.92 was the first release to define these in gdbus-codegen */
#if !GLIB_CHECK_VERSION (2, 47, 92)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (PortalFlatpakProxy, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (PortalFlatpakSkeleton, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (PortalFlatpakUpdateMonitorProxy, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (PortalFlatpakUpdateMonitorSkeleton, g_object_unref)
#endif

#define IDLE_TIMEOUT_SECS 10 * 60

/* Should be roughly 2 seconds */
#define CHILD_STATUS_CHECK_ATTEMPTS 20

static GHashTable *client_pid_data_hash = NULL;
static GDBusConnection *session_bus = NULL;
static GNetworkMonitor *network_monitor = NULL;
static gboolean no_idle_exit = FALSE;
static guint name_owner_id = 0;
static GMainLoop *main_loop;
static PortalFlatpak *portal;
static gboolean opt_verbose;
static int opt_poll_timeout;
static gboolean opt_poll_when_metered;
static FlatpakSpawnSupportFlags supports = 0;

G_LOCK_DEFINE_STATIC (update_monitors); /* This protects the three variables below */
static GHashTable *update_monitors;
static guint update_monitors_timeout = 0;
static gboolean update_monitors_timeout_running_thread = FALSE;

/* Poll all update monitors twice an hour */
#define DEFAULT_UPDATE_POLL_TIMEOUT_SEC (30 * 60)

#define PERMISSION_TABLE "flatpak"
#define PERMISSION_ID "updates"

/* Instance IDs are 32-bit unsigned integers */
#define INSTANCE_ID_BUFFER_SIZE 16

typedef enum { UNSET, ASK, YES, NO } Permission;
typedef enum {
  PROGRESS_STATUS_RUNNING = 0,
  PROGRESS_STATUS_EMPTY   = 1,
  PROGRESS_STATUS_DONE    = 2,
  PROGRESS_STATUS_ERROR   = 3
} UpdateStatus;
static XdpDbusPermissionStore *permission_store;

typedef struct {
  GMutex lock; /* This protects the closed, running and installed state */
  gboolean closed;
  gboolean running; /* While this is set, don't close the monitor */
  gboolean installing;

  char *sender;
  char *obj_path;
  GCancellable *cancellable;

  /* Static data */
  char *name;
  char *arch;
  char *branch;
  char *commit;
  char *app_path;

  /* Last reported values, starting at the instance commit */
  char *reported_local_commit;
  char *reported_remote_commit;
} UpdateMonitorData;

static gboolean           check_all_for_updates_cb (void                       *data);
static gboolean           has_update_monitors      (void);
static UpdateMonitorData *update_monitor_get_data  (PortalFlatpakUpdateMonitor *monitor);
static gboolean           handle_close             (PortalFlatpakUpdateMonitor *monitor,
                                                    GDBusMethodInvocation      *invocation);
static gboolean           handle_update            (PortalFlatpakUpdateMonitor *monitor,
                                                    GDBusMethodInvocation      *invocation,
                                                    const char                 *arg_window,
                                                    GVariant                   *arg_options);

static void
skeleton_died_cb (gpointer data)
{
  g_info ("skeleton finalized, exiting");
  g_main_loop_quit (main_loop);
}

static gboolean
unref_skeleton_in_timeout_cb (gpointer user_data)
{
  static gboolean unreffed = FALSE;

  g_info ("unreffing portal main ref");
  if (!unreffed)
    {
      g_object_unref (portal);
      unreffed = TRUE;
    }

  return G_SOURCE_REMOVE;
}

static void
unref_skeleton_in_timeout (void)
{
  if (name_owner_id)
    g_bus_unown_name (name_owner_id);
  name_owner_id = 0;

  /* After we've lost the name or idled we drop the main ref on the helper
     so that we'll exit when it drops to zero. However, if there are
     outstanding calls these will keep the refcount up during the
     execution of them. We do the unref on a timeout to make sure
     we're completely draining the queue of (stale) requests. */
  g_timeout_add (500, unref_skeleton_in_timeout_cb, NULL);
}

static guint idle_timeout_id = 0;

static gboolean
idle_timeout_cb (gpointer user_data)
{
  if (name_owner_id &&
      g_hash_table_size (client_pid_data_hash) == 0 &&
      !has_update_monitors ())
    {
      g_info ("Idle - unowning name");
      unref_skeleton_in_timeout ();
    }

  idle_timeout_id = 0;
  return G_SOURCE_REMOVE;
}

G_LOCK_DEFINE_STATIC (idle);
static void
schedule_idle_callback (void)
{
  G_LOCK (idle);

  if (!no_idle_exit)
    {
      if (idle_timeout_id != 0)
        g_source_remove (idle_timeout_id);

      idle_timeout_id = g_timeout_add_seconds (IDLE_TIMEOUT_SECS, idle_timeout_cb, NULL);
    }

  G_UNLOCK (idle);
}

typedef struct
{
  GPid     pid;
  char    *client;
  guint    child_watch;
  gboolean watch_bus;
  gboolean expose_or_share_pids;
} PidData;

static void
pid_data_free (PidData *data)
{
  g_free (data->client);
  g_free (data);
}

static void
child_watch_died (GPid     pid,
                  gint     status,
                  gpointer user_data)
{
  PidData *pid_data = user_data;
  g_autoptr(GVariant) signal_variant = NULL;

  g_info ("Client Pid %d died", pid_data->pid);

  signal_variant = g_variant_ref_sink (g_variant_new ("(uu)", pid, status));
  g_dbus_connection_emit_signal (session_bus,
                                 pid_data->client,
                                 FLATPAK_PORTAL_PATH,
                                 FLATPAK_PORTAL_INTERFACE,
                                 "SpawnExited",
                                 signal_variant,
                                 NULL);

  /* This frees the pid_data, so be careful */
  g_hash_table_remove (client_pid_data_hash, GUINT_TO_POINTER (pid_data->pid));

  /* This might have caused us to go to idle (zero children) */
  schedule_idle_callback ();
}

typedef struct
{
  int from;
  int to;
  int final;
} FdMapEntry;

typedef struct
{
  FdMapEntry *fd_map;
  gsize       fd_map_len;
  int         instance_id_fd;
  gboolean    set_tty;
  int         tty;
  int         env_fd;
} ChildSetupData;

typedef struct
{
  guint pid;
  gchar buffer[INSTANCE_ID_BUFFER_SIZE];
} InstanceIdReadData;

typedef struct
{
  FlatpakInstance *instance;
  guint            pid;
  guint            attempt;
} BwrapinfoWatcherData;

static void
bwrapinfo_watcher_data_free (BwrapinfoWatcherData* data)
{
  g_object_unref (data->instance);
  g_free (data);
}

G_DEFINE_AUTOPTR_CLEANUP_FUNC (BwrapinfoWatcherData, bwrapinfo_watcher_data_free)

static int
get_child_pid_relative_to_parent_sandbox (int      pid,
                                          GError **error)
{
  g_autofree char *status_file_path = NULL;
  g_autoptr(GFile) status_file = NULL;
  g_autoptr(GFileInputStream) input_stream = NULL;
  g_autoptr(GDataInputStream) data_stream = NULL;
  int relative_pid = 0;

  status_file_path = g_strdup_printf ("/proc/%u/status", pid);
  status_file = g_file_new_for_path (status_file_path);

  input_stream = g_file_read (status_file, NULL, error);
  if (input_stream == NULL)
    return 0;

  data_stream = g_data_input_stream_new (G_INPUT_STREAM (input_stream));

  while (TRUE)
    {
      g_autofree char *line = g_data_input_stream_read_line_utf8 (data_stream, NULL, NULL, error);
      if (line == NULL)
        break;

      g_strchug (line);

      if (g_str_has_prefix (line, "NSpid:"))
        {
          g_auto(GStrv) fields = NULL;
          guint nfields = 0;
          char *endptr = NULL;

          fields = g_strsplit (line, "\t", -1);
          nfields = g_strv_length (fields);
          if (nfields < 3)
            {
              g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
                           "NSpid line has too few fields: %s", line);
              return 0;
            }

          /* The second to last PID namespace is the one that spawned this process */
          relative_pid = strtol (fields[nfields - 2], &endptr, 10);
          if (*endptr)
            {
              g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
                           "Invalid parent-relative PID in NSpid line: %s", line);
              return 0;
            }

          return relative_pid;
        }
    }

  if (*error == NULL)
    /* EOF was reached while reading the file */
    g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND, "NSpid not found");

  return 0;
}

static int
check_child_pid_status (void *user_data)
{
  /* Stores a sequence of the time interval to use until the child PID is checked again.
     In general from testing, bwrapinfo is never ready before 25ms have passed at minimum,
     thus 25ms is the first interval, doubling until a max interval of 100ms is reached.

     In addition, if the program is not available after 100ms for an extended period of time,
     the timeout is further increased to a full second. */
  static gint timeouts[] = {25, 50, 100};

  g_autoptr(GVariant) signal_variant = NULL;
  g_autoptr(BwrapinfoWatcherData) data = user_data;
  PidData *pid_data;
  guint pid;
  int child_pid;
  int relative_child_pid = 0;

  pid = data->pid;

  pid_data = g_hash_table_lookup (client_pid_data_hash, GUINT_TO_POINTER (pid));

  /* Process likely already exited if pid_data == NULL, so don't send the
     signal to avoid an awkward out-of-order SpawnExited -> SpawnStarted. */
  if (pid_data == NULL)
    {
      g_warning ("%u already exited, skipping SpawnStarted", pid);
      return G_SOURCE_REMOVE;
    }

  child_pid = flatpak_instance_get_child_pid (data->instance);
  if (child_pid == 0)
    {
      gint timeout;
      gboolean readd_timer = FALSE;

      if (data->attempt >= CHILD_STATUS_CHECK_ATTEMPTS)
        /* If too many attempts, use a 1 second timeout */
        timeout = 1000;
      else
        timeout = timeouts[MIN (data->attempt, G_N_ELEMENTS (timeouts) - 1)];

      g_info ("Failed to read child PID, trying again in %d ms", timeout);

      /* The timer source only needs to be re-added if the timeout has changed,
          which won't happen while staying on the 100 or 1000ms timeouts.

          This test must happen *before* the attempt counter is incremented, since the
          attempt counter represents the *current* timeout. */
      readd_timer = data->attempt <= G_N_ELEMENTS (timeouts) || data->attempt == CHILD_STATUS_CHECK_ATTEMPTS;
      data->attempt++;

      /* Make sure the data isn't destroyed */
      data = NULL;

      if (readd_timer)
        {
          g_timeout_add (timeout, check_child_pid_status, user_data);
          return G_SOURCE_REMOVE;
        }

      return G_SOURCE_CONTINUE;
    }

  /* Only send the child PID if it's exposed */
  if (pid_data->expose_or_share_pids)
    {
      g_autoptr(GError) error = NULL;
      relative_child_pid = get_child_pid_relative_to_parent_sandbox (child_pid, &error);
      if (relative_child_pid == 0)
        g_warning ("Failed to find relative PID for %d: %s", child_pid, error->message);
    }

  g_info ("Emitting SpawnStarted(%u, %d)", pid, relative_child_pid);

  signal_variant = g_variant_ref_sink (g_variant_new ("(uu)", pid, relative_child_pid));
  g_dbus_connection_emit_signal (session_bus,
                                 pid_data->client,
                                 FLATPAK_PORTAL_PATH,
                                 FLATPAK_PORTAL_INTERFACE,
                                 "SpawnStarted",
                                 signal_variant,
                                 NULL);

  return G_SOURCE_REMOVE;
}

static void
instance_id_read_finish (GObject      *source,
                         GAsyncResult *res,
                         gpointer      user_data)
{
  g_autoptr(GInputStream) stream = NULL;
  g_autofree InstanceIdReadData *data = NULL;
  g_autoptr(FlatpakInstance) instance = NULL;
  g_autoptr(GError) error = NULL;
  BwrapinfoWatcherData *watcher_data = NULL;
  gssize bytes_read;

  stream = G_INPUT_STREAM (source);
  data = (InstanceIdReadData *) user_data;

  bytes_read = g_input_stream_read_finish (stream, res, &error);
  if (bytes_read <= 0)
    {
      /* 0 means EOF, so the process could never have been started. */
      if (bytes_read == -1)
        g_warning ("Failed to read instance id: %s", error->message);

      return;
    }

  data->buffer[bytes_read] = 0;

  instance = flatpak_instance_new_for_id (data->buffer);

  watcher_data = g_new0 (BwrapinfoWatcherData, 1);
  watcher_data->instance = g_steal_pointer (&instance);
  watcher_data->pid = data->pid;

  check_child_pid_status (watcher_data);
}

static void
drop_cloexec (int fd)
{
  fcntl (fd, F_SETFD, 0);
}

static void
child_setup_func (gpointer user_data)
{
  ChildSetupData *data = (ChildSetupData *) user_data;
  FdMapEntry *fd_map = data->fd_map;
  sigset_t set;
  gsize i;

  g_fdwalk_set_cloexec (3);

  if (data->instance_id_fd != -1)
    drop_cloexec (data->instance_id_fd);

  if (data->env_fd != -1)
    drop_cloexec (data->env_fd);

  /* Unblock all signals */
  sigemptyset (&set);
  if (pthread_sigmask (SIG_SETMASK, &set, NULL) == -1)
    {
      g_warning ("Failed to unblock signals when starting child");
      return;
    }

  /* Reset the handlers for all signals to their defaults. */
  for (i = 1; i < NSIG; i++)
    {
      if (i != SIGSTOP && i != SIGKILL)
        signal (i, SIG_DFL);
    }

  for (i = 0; i < data->fd_map_len; i++)
    {
      if (fd_map[i].from != fd_map[i].to)
        {
          dup2 (fd_map[i].from, fd_map[i].to);
          close (fd_map[i].from);
        }
    }

  /* Second pass in case we needed an in-between fd value to avoid conflicts */
  for (i = 0; i < data->fd_map_len; i++)
    {
      if (fd_map[i].to != fd_map[i].final)
        {
          dup2 (fd_map[i].to, fd_map[i].final);
          close (fd_map[i].to);
        }

      /* Ensure we inherit the final fd value */
      drop_cloexec (fd_map[i].final);
    }

  /* We become our own session and process group, because it never makes sense
     to share the flatpak-session-helper dbus activated process group */
  setsid ();
  setpgid (0, 0);

  if (data->set_tty)
    {
      /* data->tty is our from fd which is closed at this point.
       * so locate the destination fd and use it for the ioctl.
       */
      for (i = 0; i < data->fd_map_len; i++)
        {
          if (fd_map[i].from == data->tty)
            {
              if (ioctl (fd_map[i].final, TIOCSCTTY, 0) == -1)
                g_info ("ioctl(%d, TIOCSCTTY, 0) failed: %s",
                        fd_map[i].final, strerror (errno));
              break;
            }
        }
    }
}

static gboolean
validate_opath_fd (int        fd,
                   gboolean   needs_writable,
                   GError   **error)
{
  int fd_flags;
  struct stat st_buf;
  struct stat real_st_buf;
  int access_mode;
  g_autofree char *path = NULL;

  /* Must be able to get fd flags */
  fd_flags = fcntl (fd, F_GETFL);
  if (fd_flags < 0)
    return glnx_throw_errno_prefix (error, "Failed to get fd flags");

  /* Must be O_PATH */
  if ((fd_flags & O_PATH) != O_PATH)
    {
      g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
                           "File descriptor is not O_PATH");
      return FALSE;
    }

  /* Must be able to fstat */
  if (fstat (fd, &st_buf) < 0)
    return glnx_throw_errno_prefix (error, "Failed to fstat");

  path = flatpak_get_path_for_fd (fd, error);
  if (path == NULL)
    return FALSE;

  /* Verify that this is the same file as the app opened.
   * Note that this is not security relevant because flatpak-run/bwrap will
   * check things and abort if something is off. We do this only for backwards
   * compatibility reasons: we need to be able to ignore the issue instead of
   * aborting the entire sandbox setup later. */
  if (stat (path, &real_st_buf) < 0 ||
      st_buf.st_dev != real_st_buf.st_dev ||
      st_buf.st_ino != real_st_buf.st_ino)
    {
      /* Different files on the inside and the outside, reject the request */
      return glnx_throw (error,
                         "different file inside and outside sandbox");
    }

  access_mode = R_OK;
  if (S_ISDIR (st_buf.st_mode))
    access_mode |= X_OK;

  if (needs_writable)
    access_mode |= W_OK;

  /* Must be able to access readable and potentially writable */
  if (faccessat (fd, "", access_mode, AT_EMPTY_PATH | AT_SYMLINK_NOFOLLOW) != 0)
    return glnx_throw_errno_prefix (error, "Bad access mode");

  return TRUE;
}

static int
fd_map_remap_fd (GArray *fd_map,
                 int    *max_fd_in_out,
                 int     fd)
{
  FdMapEntry fd_map_entry;

  /* Use a fd that hasn't been used yet. We might have to reshuffle
   * fd_map_entry.to, a bit later. */
  fd_map_entry.from = fd;
  fd_map_entry.to = ++(*max_fd_in_out);
  fd_map_entry.final = fd_map_entry.to;
  g_array_append_val (fd_map, fd_map_entry);

  return fd_map_entry.final;
}

static gboolean
handle_spawn (PortalFlatpak         *object,
              GDBusMethodInvocation *invocation,
              GUnixFDList           *fd_list,
              const gchar           *arg_cwd_path,
              const gchar *const    *arg_argv,
              GVariant              *arg_fds,
              GVariant              *arg_envs,
              guint                  arg_flags,
              GVariant              *arg_options)
{
  g_autoptr(GError) error = NULL;
  ChildSetupData child_setup_data = { NULL };
  GPid pid;
  PidData *pid_data;
  InstanceIdReadData *instance_id_read_data = NULL;
  gsize i, j, n_fds, n_envs;
  const gint *fds = NULL;
  gint fds_len = 0;
  g_autoptr(GArray) fd_map = NULL;
  g_auto(GStrv) env = NULL;
  gint32 max_fd;
  GKeyFile *app_info;
  g_autoptr(GPtrArray) flatpak_argv = g_ptr_array_new_with_free_func (g_free);
  g_autofree char *app_id = NULL;
  g_autofree char *branch = NULL;
  g_autofree char *arch = NULL;
  g_autofree char *app_commit = NULL;
  g_autofree char *runtime_ref = NULL;
  g_auto(GStrv) runtime_parts = NULL;
  g_autofree char *runtime_commit = NULL;
  g_autofree char *instance_path = NULL;
  g_autofree char *instance_id = NULL;
  g_auto(GStrv) extra_args = NULL;
  g_auto(GStrv) shares = NULL;
  g_auto(GStrv) sockets = NULL;
  g_auto(GStrv) devices = NULL;
  g_auto(GStrv) unset_env = NULL;
  g_auto(GStrv) sandbox_expose = NULL;
  g_auto(GStrv) sandbox_expose_ro = NULL;
  g_auto(GStrv) sandbox_a11y_own_names = NULL;
  g_autoptr(FlatpakInstance) instance = NULL;
  g_autoptr(GVariant) sandbox_expose_fd = NULL;
  g_autoptr(GVariant) sandbox_expose_fd_ro = NULL;
  g_autoptr(GVariant) app_fd = NULL;
  g_autoptr(GVariant) usr_fd = NULL;
  g_autoptr(GOutputStream) instance_id_out_stream = NULL;
  guint sandbox_flags = 0;
  gboolean sandboxed;
  gboolean expose_pids;
  gboolean share_pids;
  gboolean notify_start;
  gboolean devel;
  gboolean empty_app;
  g_autoptr(GString) env_string = g_string_new ("");
  const char *flatpak;
  gboolean testing = FALSE;
  g_autofree char *app_id_prefix = NULL;
  g_autoptr(GArray) owned_fds = NULL;
  g_autoptr(GArray) expose_fds = NULL;
  g_autoptr(GArray) expose_fds_ro = NULL;
  glnx_autofd int instance_sandbox_fd = -1;

  child_setup_data.instance_id_fd = -1;
  child_setup_data.env_fd = -1;

  if (fd_list != NULL)
    fds = g_unix_fd_list_peek_fds (fd_list, &fds_len);

  app_info = g_object_get_data (G_OBJECT (invocation), "app-info");
  g_assert (app_info != NULL);

  app_id = g_key_file_get_string (app_info,
                                  FLATPAK_METADATA_GROUP_APPLICATION,
                                  FLATPAK_METADATA_KEY_NAME, NULL);
  g_assert (app_id != NULL);

  g_info ("spawn() called from app: '%s'", app_id);

  if (*app_id == 0 && g_getenv ("FLATPAK_PORTAL_MOCK_FLATPAK") != NULL)
    {
      /* Pretend we had been called from an app for test purposes */
      testing = TRUE;
      g_info ("In unit tests, behaving as though app ID was com.example.App");
      g_clear_pointer (&app_id, g_free);
      app_id = g_strdup ("com.example.App");
    }

  if (*app_id == 0)
    {
      g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
                                             G_DBUS_ERROR_INVALID_ARGS,
                                             FLATPAK_PORTAL_INTERFACE ".Spawn only works in a flatpak");
      return G_DBUS_METHOD_INVOCATION_HANDLED;
    }

  if (*arg_cwd_path == 0)
    arg_cwd_path = NULL;

  if (arg_argv == NULL || *arg_argv == NULL)
    {
      g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
                                             G_DBUS_ERROR_INVALID_ARGS,
                                             "No command given");
      return G_DBUS_METHOD_INVOCATION_HANDLED;
    }

  if ((arg_flags & ~FLATPAK_SPAWN_FLAGS_ALL) != 0)
    {
      g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS,
                                             "Unsupported flags enabled: 0x%x", arg_flags & ~FLATPAK_SPAWN_FLAGS_ALL);
      return G_DBUS_METHOD_INVOCATION_HANDLED;
    }

  if (testing)
    runtime_ref = g_strdup ("runtime/com.example.Runtime/m68k/1.0");
  else
    runtime_ref = g_key_file_get_string (app_info,
                                         FLATPAK_METADATA_GROUP_APPLICATION,
                                         FLATPAK_METADATA_KEY_RUNTIME, NULL);

  if (runtime_ref == NULL)
    {
      g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS,
                                             "No runtime found");
      return G_DBUS_METHOD_INVOCATION_HANDLED;
    }

  runtime_parts = g_strsplit (runtime_ref, "/", -1);

  branch = g_key_file_get_string (app_info,
                                  FLATPAK_METADATA_GROUP_INSTANCE,
                                  FLATPAK_METADATA_KEY_BRANCH, NULL);
  instance_path = g_key_file_get_string (app_info,
                                         FLATPAK_METADATA_GROUP_INSTANCE,
                                         FLATPAK_METADATA_KEY_INSTANCE_PATH, NULL);
  arch = g_key_file_get_string (app_info,
                                FLATPAK_METADATA_GROUP_INSTANCE,
                                FLATPAK_METADATA_KEY_ARCH, NULL);
  extra_args = g_key_file_get_string_list (app_info,
                                           FLATPAK_METADATA_GROUP_INSTANCE,
                                           FLATPAK_METADATA_KEY_EXTRA_ARGS, NULL, NULL);
  app_commit = g_key_file_get_string (app_info,
                                      FLATPAK_METADATA_GROUP_INSTANCE,
                                      FLATPAK_METADATA_KEY_APP_COMMIT, NULL);
  runtime_commit = g_key_file_get_string (app_info,
                                          FLATPAK_METADATA_GROUP_INSTANCE,
                                          FLATPAK_METADATA_KEY_RUNTIME_COMMIT, NULL);
  shares = g_key_file_get_string_list (app_info, FLATPAK_METADATA_GROUP_CONTEXT,
                                       FLATPAK_METADATA_KEY_SHARED, NULL, NULL);
  sockets = g_key_file_get_string_list (app_info, FLATPAK_METADATA_GROUP_CONTEXT,
                                       FLATPAK_METADATA_KEY_SOCKETS, NULL, NULL);
  devices = g_key_file_get_string_list (app_info, FLATPAK_METADATA_GROUP_CONTEXT,
                                        FLATPAK_METADATA_KEY_DEVICES, NULL, NULL);

  devel = g_key_file_get_boolean (app_info, FLATPAK_METADATA_GROUP_INSTANCE,
                                  FLATPAK_METADATA_KEY_DEVEL, NULL);

  g_variant_lookup (arg_options, "sandbox-expose", "^as", &sandbox_expose);
  g_variant_lookup (arg_options, "sandbox-expose-ro", "^as", &sandbox_expose_ro);
  g_variant_lookup (arg_options, "sandbox-flags", "u", &sandbox_flags);
  g_variant_lookup (arg_options, "sandbox-a11y-own-names", "^as", &sandbox_a11y_own_names);
  sandbox_expose_fd = g_variant_lookup_value (arg_options, "sandbox-expose-fd", G_VARIANT_TYPE ("ah"));
  sandbox_expose_fd_ro = g_variant_lookup_value (arg_options, "sandbox-expose-fd-ro", G_VARIANT_TYPE ("ah"));
  g_variant_lookup (arg_options, "unset-env", "^as", &unset_env);
  app_fd = g_variant_lookup_value (arg_options, "app-fd", G_VARIANT_TYPE_HANDLE);
  usr_fd = g_variant_lookup_value (arg_options, "usr-fd", G_VARIANT_TYPE_HANDLE);

  if ((sandbox_flags & ~FLATPAK_SPAWN_SANDBOX_FLAGS_ALL) != 0)
    {
      g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS,
                                             "Unsupported sandbox flags enabled: 0x%x", arg_flags & ~FLATPAK_SPAWN_SANDBOX_FLAGS_ALL);
      return G_DBUS_METHOD_INVOCATION_HANDLED;
    }

  if (instance_path == NULL &&
      ((sandbox_expose != NULL && sandbox_expose[0] != NULL) ||
       (sandbox_expose_ro != NULL && sandbox_expose_ro[0] != NULL)))
    {
      g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
                                             G_DBUS_ERROR_INVALID_ARGS,
                                             "Invalid sandbox expose, caller has no instance path");
      return G_DBUS_METHOD_INVOCATION_HANDLED;
    }

  app_id_prefix = g_strdup_printf ("%s.", app_id);
  for (i = 0; sandbox_a11y_own_names != NULL && sandbox_a11y_own_names[i] != NULL; i++)
    {
      if (!(sandbox_flags & FLATPAK_SPAWN_SANDBOX_FLAGS_ALLOW_A11Y))
        {
          g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
                                                 G_DBUS_ERROR_INVALID_ARGS,
                                                 "Invalid sandbox a11y own name, accessibility disabled in the sandbox");
          return G_DBUS_METHOD_INVOCATION_HANDLED;
        }

      if (!g_str_has_prefix (sandbox_a11y_own_names[i], app_id_prefix))
        {
          g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
                                                 G_DBUS_ERROR_INVALID_ARGS,
                                                 "Invalid sandbox a11y own name: '%s' doesn't match app id", sandbox_a11y_own_names[i]);
          return G_DBUS_METHOD_INVOCATION_HANDLED;
        }
    }

  g_info ("Running spawn command %s", arg_argv[0]);

  n_fds = 0;
  if (fds != NULL)
    n_fds = g_variant_n_children (arg_fds);

  fd_map = g_array_sized_new (FALSE, FALSE, sizeof (FdMapEntry), n_fds);

  max_fd = -1;
  for (i = 0; i < n_fds; i++)
    {
      FdMapEntry fd_map_entry;
      gint32 handle, dest_fd;
      int handle_fd;

      g_variant_get_child (arg_fds, i, "{uh}", &dest_fd, &handle);

      if (handle >= fds_len || handle < 0)
        {
          g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
                                                 G_DBUS_ERROR_INVALID_ARGS,
                                                 "No file descriptor for handle %d",
                                                 handle);
          return G_DBUS_METHOD_INVOCATION_HANDLED;
        }

      handle_fd = fds[handle];

      fd_map_entry.to = dest_fd;
      fd_map_entry.from = handle_fd;
      fd_map_entry.final = fd_map_entry.to;
      g_array_append_val (fd_map, fd_map_entry);

      /* If stdin/out/err is a tty we try to set it as the controlling
         tty for the app, this way we can use this to run in a terminal. */
      if ((dest_fd == 0 || dest_fd == 1 || dest_fd == 2) &&
          !child_setup_data.set_tty &&
          isatty (handle_fd))
        {
          child_setup_data.set_tty = TRUE;
          child_setup_data.tty = handle_fd;
        }

      max_fd = MAX (max_fd, fd_map_entry.to);
      max_fd = MAX (max_fd, fd_map_entry.from);
    }

  if (testing)
    {
      instance_id = g_strdup ("11223344");
    }
  else
    {
      instance_id = g_key_file_get_string (app_info,
                                           FLATPAK_METADATA_GROUP_INSTANCE,
                                           FLATPAK_METADATA_KEY_INSTANCE_ID, NULL);
    }

  if (!instance_id)
    {
      g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
                                             G_DBUS_ERROR_INVALID_ARGS,
                                             "Caller has no instance id");
      return G_DBUS_METHOD_INVOCATION_HANDLED;
    }

  instance = flatpak_instance_new_for_id (instance_id);
  if (!instance)
    {
      g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
                                             G_DBUS_ERROR_FAILED,
                                             "Could not access caller instance");
      return G_DBUS_METHOD_INVOCATION_HANDLED;
    }

  if ((flatpak = g_getenv ("FLATPAK_PORTAL_MOCK_FLATPAK")) != NULL)
    g_ptr_array_add (flatpak_argv, g_strdup (flatpak));
  else if ((flatpak = g_getenv ("FLATPAK")) != NULL)
    g_ptr_array_add (flatpak_argv, g_strdup (flatpak));
  else
    g_ptr_array_add (flatpak_argv, g_strdup (FLATPAK_BINDIR "/flatpak"));

  g_ptr_array_add (flatpak_argv, g_strdup ("run"));

  /* If we don't clear the env, the flatpak portal service environment would
   * leak into the flatpak instance. By default we reuse the environment of
   * the calling instance by passing it as arguments after the --clear-env.
   */
  g_ptr_array_add (flatpak_argv, g_strdup ("--clear-env"));

  if (!(arg_flags & FLATPAK_SPAWN_FLAGS_CLEAR_ENV))
    {
      static const char * const mock_run_environ[] = { "FOO=bar", NULL };

      if (testing)
        env = g_strdupv ((GStrv) mock_run_environ);
      else
        env = flatpak_instance_get_run_environ (instance, &error);

      if (env == NULL)
        {
          if (g_error_matches (error, G_FILE_ERROR, G_FILE_ERROR_NOENT))
            {
              g_warning ("Environment for \"flatpak run\" was not found, "
                         "falling back to a clean environment");
            }
          else
            {
              g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
                                                     G_DBUS_ERROR_INVALID_ARGS,
                                                     "Could not load environment for \"flatpak run\": %s",
                                                     error->message);
              return G_DBUS_METHOD_INVOCATION_HANDLED;
            }
        }
      else
        {
          for (i = 0; env != NULL && env[i] != NULL; i++)
            {
              g_string_append (env_string, env[i]);
              g_string_append_c (env_string, '\0');
            }
        }
    }

  sandboxed = (arg_flags & FLATPAK_SPAWN_FLAGS_SANDBOX) != 0;

  if (sandboxed)
    {
      g_ptr_array_add (flatpak_argv, g_strdup ("--sandbox"));

      if (sandbox_flags & FLATPAK_SPAWN_SANDBOX_FLAGS_SHARE_DISPLAY)
        {
          if (sockets != NULL && g_strv_contains ((const char * const *) sockets, "wayland"))
            g_ptr_array_add (flatpak_argv, g_strdup ("--socket=wayland"));
          if (sockets != NULL && g_strv_contains ((const char * const *) sockets, "fallback-x11"))
            g_ptr_array_add (flatpak_argv, g_strdup ("--socket=fallback-x11"));
          if (sockets != NULL && g_strv_contains ((const char * const *) sockets, "x11"))
            g_ptr_array_add (flatpak_argv, g_strdup ("--socket=x11"));
          if (shares != NULL && g_strv_contains ((const char * const *) shares, "ipc") &&
              sockets != NULL && (g_strv_contains ((const char * const *) sockets, "fallback-x11") ||
                                  g_strv_contains ((const char * const *) sockets, "x11")))
            g_ptr_array_add (flatpak_argv, g_strdup ("--share=ipc"));
        }
      if (sandbox_flags & FLATPAK_SPAWN_SANDBOX_FLAGS_SHARE_SOUND)
        {
          if (sockets != NULL && g_strv_contains ((const char * const *) sockets, "pulseaudio"))
            g_ptr_array_add (flatpak_argv, g_strdup ("--socket=pulseaudio"));
        }
      if (sandbox_flags & FLATPAK_SPAWN_SANDBOX_FLAGS_SHARE_GPU)
        {
          if (devices != NULL &&
              (g_strv_contains ((const char * const *) devices, "dri") ||
               g_strv_contains ((const char * const *) devices, "all")))
            g_ptr_array_add (flatpak_argv, g_strdup ("--device=dri"));
        }
      if (sandbox_flags & FLATPAK_SPAWN_SANDBOX_FLAGS_SHARE_INPUT)
        {
          if (devices != NULL &&
              (g_strv_contains ((const char * const *) devices, "input") ||
               g_strv_contains ((const char * const *) devices, "all")))
            g_ptr_array_add (flatpak_argv, g_strdup ("--device=input"));
        }
      if (sandbox_flags & FLATPAK_SPAWN_SANDBOX_FLAGS_SHARE_USB)
        {
          if (devices != NULL &&
              (g_strv_contains ((const char * const *) devices, "usb") ||
               g_strv_contains ((const char * const *) devices, "all")))
            g_ptr_array_add (flatpak_argv, g_strdup ("--device=usb"));
        }
      if (sandbox_flags & FLATPAK_SPAWN_SANDBOX_FLAGS_SHARE_KVM)
        {
          if (devices != NULL &&
              (g_strv_contains ((const char * const *) devices, "kvm") ||
               g_strv_contains ((const char * const *) devices, "all")))
            g_ptr_array_add (flatpak_argv, g_strdup ("--device=kvm"));
        }
      if (sandbox_flags & FLATPAK_SPAWN_SANDBOX_FLAGS_SHARE_SHM)
        {
          if (devices != NULL &&
              (g_strv_contains ((const char * const *) devices, "shm")))
            g_ptr_array_add (flatpak_argv, g_strdup ("--device=shm"));
        }
      if (sandbox_flags & FLATPAK_SPAWN_SANDBOX_FLAGS_SHARE_DEVICES)
        {
          if (devices != NULL &&
              (g_strv_contains ((const char * const *) devices, "all")))
            g_ptr_array_add (flatpak_argv, g_strdup ("--device=all"));
        }
      if (sandbox_flags & FLATPAK_SPAWN_SANDBOX_FLAGS_ALLOW_DBUS)
        g_ptr_array_add (flatpak_argv, g_strdup ("--session-bus"));

      if (sandbox_flags & FLATPAK_SPAWN_SANDBOX_FLAGS_ALLOW_A11Y)
        {
          g_ptr_array_add (flatpak_argv, g_strdup ("--a11y-bus"));

          for (i = 0; sandbox_a11y_own_names != NULL && sandbox_a11y_own_names[i] != NULL; i++)
            g_ptr_array_add (flatpak_argv, g_strdup_printf ("--a11y-own-name=%s", sandbox_a11y_own_names[i]));
        }
    }
  else
    {
      for (i = 0; extra_args != NULL && extra_args[i] != NULL; i++)
        {
          if (g_str_has_prefix (extra_args[i], "--env="))
            {
              const char *var_val = extra_args[i] + strlen ("--env=");

              if (var_val[0] == '\0' || var_val[0] == '=')
                {
                  g_warning ("Environment variable in extra-args has empty name");
                  continue;
                }

              if (strchr (var_val, '=') == NULL)
                {
                  g_warning ("Environment variable in extra-args has no value");
                  continue;
                }

              g_string_append (env_string, var_val);
              g_string_append_c (env_string, '\0');
            }
          else
            {
              g_ptr_array_add (flatpak_argv, g_strdup (extra_args[i]));
            }
        }
    }

  /* Let the environment variables given by the caller override the ones
   * from extra_args. Don't add them to @env, because they are controlled
   * by our caller, which might be trying to use them to inject code into
   * flatpak(1); add them to the environment block instead.
   *
   * We don't use --env= here, so that if the values are something that
   * should not be exposed to other uids, they can remain confidential. */
  n_envs = g_variant_n_children (arg_envs);
  for (i = 0; i < n_envs; i++)
    {
      const char *var = NULL;
      const char *val = NULL;
      g_variant_get_child (arg_envs, i, "{&s&s}", &var, &val);

      if (var[0] == '\0')
        {
          g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
                                                 G_DBUS_ERROR_INVALID_ARGS,
                                                 "Environment variable cannot have empty name");
          return G_DBUS_METHOD_INVOCATION_HANDLED;
        }

      if (strchr (var, '=') != NULL)
        {
          g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
                                                 G_DBUS_ERROR_INVALID_ARGS,
                                                 "Environment variable name cannot contain '='");
          return G_DBUS_METHOD_INVOCATION_HANDLED;
        }

      g_string_append (env_string, var);
      g_string_append_c (env_string, '=');
      g_string_append (env_string, val);
      g_string_append_c (env_string, '\0');
    }

  owned_fds = g_array_new (FALSE, FALSE, sizeof (int));
  g_array_set_clear_func (owned_fds, (GDestroyNotify) glnx_close_fd);

  if (env_string->len > 0)
    {
      g_auto(GLnxTmpfile) env_tmpf  = { 0, };
      int env_fd = -1;
      int remapped_fd;

      if (!flatpak_buffer_to_sealed_memfd_or_tmpfile (&env_tmpf, "environ",
                                                      env_string->str,
                                                      env_string->len, &error))
        {
          g_dbus_method_invocation_return_gerror (invocation, error);
          return G_DBUS_METHOD_INVOCATION_HANDLED;
        }

      env_fd = g_steal_fd (&env_tmpf.fd);
      g_array_append_val (owned_fds, env_fd);

      remapped_fd = fd_map_remap_fd (fd_map, &max_fd, env_fd);

      g_ptr_array_add (flatpak_argv,
                       g_strdup_printf ("--env-fd=%d", remapped_fd));
    }

  for (i = 0; unset_env != NULL && unset_env[i] != NULL; i++)
    {
      const char *var = unset_env[i];

      if (var[0] == '\0')
        {
          g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
                                                 G_DBUS_ERROR_INVALID_ARGS,
                                                 "Environment variable cannot have empty name");
          return G_DBUS_METHOD_INVOCATION_HANDLED;
        }

      if (strchr (var, '=') != NULL)
        {
          g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
                                                 G_DBUS_ERROR_INVALID_ARGS,
                                                 "Environment variable name cannot contain '='");
          return G_DBUS_METHOD_INVOCATION_HANDLED;
        }

      g_ptr_array_add (flatpak_argv,
                       g_strdup_printf ("--unset-env=%s", var));
    }

  expose_pids = (arg_flags & FLATPAK_SPAWN_FLAGS_EXPOSE_PIDS) != 0;
  share_pids = (arg_flags & FLATPAK_SPAWN_FLAGS_SHARE_PIDS) != 0;

  if (expose_pids || share_pids)
    {
      int sender_pid1 = 0;

      if (!(supports & FLATPAK_SPAWN_SUPPORT_FLAGS_EXPOSE_PIDS))
        {
          g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
                                                 G_DBUS_ERROR_NOT_SUPPORTED,
                                                 "Expose pids not supported with setuid bwrap");
          return G_DBUS_METHOD_INVOCATION_HANDLED;
        }

      sender_pid1 = flatpak_instance_get_child_pid (instance);
      if (sender_pid1 == 0)
        {
          g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
                                                 G_DBUS_ERROR_INVALID_ARGS,
                                                 "Could not find requesting pid");
          return G_DBUS_METHOD_INVOCATION_HANDLED;
        }

      g_ptr_array_add (flatpak_argv, g_strdup_printf ("--parent-pid=%d", sender_pid1));

      if (share_pids)
        g_ptr_array_add (flatpak_argv, g_strdup ("--parent-share-pids"));
      else
        g_ptr_array_add (flatpak_argv, g_strdup ("--parent-expose-pids"));
    }

  notify_start = (arg_flags & FLATPAK_SPAWN_FLAGS_NOTIFY_START) != 0;
  if (notify_start)
    {
      int pipe_fds[2];
      if (pipe (pipe_fds) == -1)
        {
          int errsv = errno;
          g_dbus_method_invocation_return_error (invocation, G_IO_ERROR,
                                                 g_io_error_from_errno (errsv),
                                                 "Failed to create instance ID pipe: %s",
                                                 g_strerror (errsv));
          return G_DBUS_METHOD_INVOCATION_HANDLED;
        }

      GInputStream *in_stream = G_INPUT_STREAM (g_unix_input_stream_new (pipe_fds[0], TRUE));
      /* This is saved to ensure the portal's end gets closed after the exec. */
      instance_id_out_stream = G_OUTPUT_STREAM (g_unix_output_stream_new (pipe_fds[1], TRUE));

      instance_id_read_data = g_new0 (InstanceIdReadData, 1);

      g_input_stream_read_async (in_stream, instance_id_read_data->buffer,
                                 INSTANCE_ID_BUFFER_SIZE - 1, G_PRIORITY_DEFAULT, NULL,
                                 instance_id_read_finish, instance_id_read_data);

      g_ptr_array_add (flatpak_argv, g_strdup_printf ("--instance-id-fd=%d", pipe_fds[1]));
      child_setup_data.instance_id_fd = pipe_fds[1];
      max_fd = MAX(max_fd, pipe_fds[1]);
    }

  if (devel)
    g_ptr_array_add (flatpak_argv, g_strdup ("--devel"));

  /* Inherit launcher network access from launcher, unless
     NO_NETWORK set. */
  if (shares != NULL && g_strv_contains ((const char * const *) shares, "network") &&
      !(arg_flags & FLATPAK_SPAWN_FLAGS_NO_NETWORK))
    g_ptr_array_add (flatpak_argv, g_strdup ("--share=network"));
  else
    g_ptr_array_add (flatpak_argv, g_strdup ("--unshare=network"));

  expose_fds = g_array_new (FALSE, FALSE, sizeof (int));
  expose_fds_ro = g_array_new (FALSE, FALSE, sizeof (int));

  if (instance_path != NULL)
    {
      glnx_autofd int instance_fd = -1;

      instance_fd = glnx_chaseat (AT_FDCWD, instance_path,
                                  GLNX_CHASE_DEFAULT,
                                  &error);
      if (instance_fd < 0)
        {
          g_dbus_method_invocation_return_gerror (invocation, error);
          return G_DBUS_METHOD_INVOCATION_HANDLED;
        }

      if (!glnx_ensure_dir (instance_fd, "sandbox", 0700, &error))
        {
          g_warning ("Unable to create %s/sandbox: %s", instance_path, error->message);
          g_clear_error (&error);
        }

      instance_sandbox_fd = glnx_chaseat (instance_fd, "sandbox",
                                          GLNX_CHASE_RESOLVE_NO_SYMLINKS,
                                          &error);
      if (instance_sandbox_fd < 0)
        {
          g_dbus_method_invocation_return_gerror (invocation, error);
          return G_DBUS_METHOD_INVOCATION_HANDLED;
        }
    }

  for (i = 0; sandbox_expose != NULL && sandbox_expose[i] != NULL; i++)
    {
      int expose_fd;

      g_assert (instance_sandbox_fd >= 0);

      expose_fd = glnx_chaseat (instance_sandbox_fd, sandbox_expose[i],
                                GLNX_CHASE_RESOLVE_NO_SYMLINKS |
                                GLNX_CHASE_RESOLVE_BENEATH,
                                &error);
      if (expose_fd < 0)
        {
          g_dbus_method_invocation_return_gerror (invocation, error);
          return G_DBUS_METHOD_INVOCATION_HANDLED;
        }

      g_array_append_val (expose_fds, expose_fd);
      /* transfers ownership, can't g_steal_fd with g_array_append_val */
      g_array_append_val (owned_fds, expose_fd);
    }

  for (i = 0; sandbox_expose_ro != NULL && sandbox_expose_ro[i] != NULL; i++)
    {
      int expose_fd;

      g_assert (instance_sandbox_fd >= 0);

      expose_fd = glnx_chaseat (instance_sandbox_fd, sandbox_expose_ro[i],
                                GLNX_CHASE_RESOLVE_NO_SYMLINKS |
                                GLNX_CHASE_RESOLVE_BENEATH,
                                &error);
      if (expose_fd < 0)
        {
          g_dbus_method_invocation_return_gerror (invocation, error);
          return G_DBUS_METHOD_INVOCATION_HANDLED;
        }

      g_array_append_val (expose_fds_ro, expose_fd);
      /* transfers ownership, can't g_steal_fd with g_array_append_val */
      g_array_append_val (owned_fds, expose_fd);
    }

  if (sandbox_expose_fd != NULL)
    {
      gsize len = g_variant_n_children (sandbox_expose_fd);

      for (i = 0; i < len; i++)
        {
          gint32 handle;

          g_variant_get_child (sandbox_expose_fd, i, "h", &handle);
          if (handle >= fds_len || handle < 0)
            {
              g_debug ("Invalid sandbox-expose-fd handle %d", handle);
              g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
                                                     G_DBUS_ERROR_INVALID_ARGS,
                                                     "No file descriptor for handle %d",
                                                     handle);
              return G_DBUS_METHOD_INVOCATION_HANDLED;
            }

          if (validate_opath_fd (fds[handle], TRUE, &error))
            {
              g_array_append_val (expose_fds, fds[handle]);
            }
          else
            {
              g_info ("unable to validate sandbox-expose-fd %d, ignoring: %s",
                      fds[handle], error->message);
              g_clear_error (&error);
            }
        }
    }

  if (sandbox_expose_fd_ro != NULL)
    {
      gsize len = g_variant_n_children (sandbox_expose_fd_ro);

      for (i = 0; i < len; i++)
        {
          gint32 handle;

          g_variant_get_child (sandbox_expose_fd_ro, i, "h", &handle);
          if (handle >= fds_len || handle < 0)
            {
              g_debug ("Invalid sandbox-expose-ro-fd handle %d", handle);
              g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
                                                     G_DBUS_ERROR_INVALID_ARGS,
                                                     "No file descriptor for handle %d",
                                                     handle);
              return G_DBUS_METHOD_INVOCATION_HANDLED;
            }

          if (validate_opath_fd (fds[handle], FALSE, &error))
            {
              g_array_append_val (expose_fds_ro, fds[handle]);
            }
          else
            {
              g_info ("unable to validate sandbox-expose-ro-fd %d, ignoring: %s",
                      fds[handle], error->message);
              g_clear_error (&error);
            }
        }
    }

  for (i = 0; i < expose_fds->len; i++)
    {
      int remapped_fd;

      remapped_fd = fd_map_remap_fd (fd_map, &max_fd, g_array_index (expose_fds, int, i));

      g_ptr_array_add (flatpak_argv, g_strdup_printf ("--bind-fd=%d",
                                                      remapped_fd));
    }

  for (i = 0; i < expose_fds_ro->len; i++)
    {
      int remapped_fd;

      remapped_fd = fd_map_remap_fd (fd_map, &max_fd, g_array_index (expose_fds_ro, int, i));

      g_ptr_array_add (flatpak_argv, g_strdup_printf ("--ro-bind-fd=%d",
                                                      remapped_fd));
    }

  empty_app = (arg_flags & FLATPAK_SPAWN_FLAGS_EMPTY_APP) != 0;

  if (empty_app && app_fd != NULL)
    {
      g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
                                             G_DBUS_ERROR_INVALID_ARGS,
                                             "app-fd and EMPTY_APP cannot both be used");
      return G_DBUS_METHOD_INVOCATION_HANDLED;
    }

  if (app_fd != NULL)
    {
      int remapped_fd;
      gint32 handle = g_variant_get_handle (app_fd);

      if (handle >= fds_len || handle < 0)
        {
          g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
                                                 G_DBUS_ERROR_INVALID_ARGS,
                                                 "No file descriptor for handle %d",
                                                 handle);
          return G_DBUS_METHOD_INVOCATION_HANDLED;
        }

      g_assert (fds != NULL);   /* otherwise fds_len would be 0 */

      remapped_fd = fd_map_remap_fd (fd_map, &max_fd, fds[handle]);

      g_ptr_array_add (flatpak_argv, g_strdup_printf ("--app-fd=%d",
                                                      remapped_fd));
    }
  else if (empty_app)
    {
      g_ptr_array_add (flatpak_argv, g_strdup ("--app-path="));
    }

  if (usr_fd != NULL)
    {
      int remapped_fd;
      gint32 handle = g_variant_get_handle (usr_fd);

      if (handle >= fds_len || handle < 0)
        {
          g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
                                                 G_DBUS_ERROR_INVALID_ARGS,
                                                 "No file descriptor for handle %d",
                                                 handle);
          return G_DBUS_METHOD_INVOCATION_HANDLED;
        }

      g_assert (fds != NULL);   /* otherwise fds_len would be 0 */

      remapped_fd = fd_map_remap_fd (fd_map, &max_fd, fds[handle]);

      g_ptr_array_add (flatpak_argv, g_strdup_printf ("--usr-fd=%d",
                                                      remapped_fd));
    }

  g_ptr_array_add (flatpak_argv, g_strdup_printf ("--runtime=%s", runtime_parts[1]));
  g_ptr_array_add (flatpak_argv, g_strdup_printf ("--runtime-version=%s", runtime_parts[3]));

  if ((arg_flags & FLATPAK_SPAWN_FLAGS_LATEST_VERSION) == 0)
    {
      if (app_commit)
        g_ptr_array_add (flatpak_argv, g_strdup_printf ("--commit=%s", app_commit));
      if (runtime_commit)
        g_ptr_array_add (flatpak_argv, g_strdup_printf ("--runtime-commit=%s", runtime_commit));
    }

  if (arg_cwd_path != NULL)
    g_ptr_array_add (flatpak_argv, g_strdup_printf ("--cwd=%s", arg_cwd_path));

  if (arg_argv[0][0] != 0)
    g_ptr_array_add (flatpak_argv, g_strdup_printf ("--command=%s", arg_argv[0]));

  g_ptr_array_add (flatpak_argv, g_strdup_printf ("%s/%s/%s", app_id, arch ? arch : "", branch ? branch : ""));
  for (i = 1; arg_argv[i] != NULL; i++)
    g_ptr_array_add (flatpak_argv, g_strdup (arg_argv[i]));
  g_ptr_array_add (flatpak_argv, NULL);

  if (opt_verbose)
    {
      g_autoptr(GString) cmd = g_string_new ("");

      for (i = 0; flatpak_argv->pdata[i] != NULL; i++)
        {
          if (i > 0)
            g_string_append (cmd, " ");
          g_string_append (cmd, flatpak_argv->pdata[i]);
        }

      g_info ("Starting: %s\n", cmd->str);
    }

  /* We make a second pass over the fds to find if any "to" fd index
     overlaps an already in use fd (i.e. one in the "from" category
     that are allocated randomly). If a fd overlaps "to" fd then its
     a caller issue and not our fault, so we ignore that. */
  for (i = 0; i < fd_map->len; i++)
    {
      int to_fd = g_array_index (fd_map, FdMapEntry, i).to;
      gboolean conflict = FALSE;

      /* At this point we're fine with using "from" values for this
         value (because we handle to==from in the code), or values
         that are before "i" in the fd_map (because those will be
         closed at this point when dup:ing). However, we can't
         reuse a fd that is in "from" for j > i. */
      for (j = i + 1; j < fd_map->len; j++)
        {
          int from_fd = g_array_index(fd_map, FdMapEntry, j).from;
          if (from_fd == to_fd)
            {
              conflict = TRUE;
              break;
            }
        }

      if (conflict)
        g_array_index (fd_map, FdMapEntry, i).to = ++max_fd;
    }

  child_setup_data.fd_map = &g_array_index (fd_map, FdMapEntry, 0);
  child_setup_data.fd_map_len = fd_map->len;

  /* We use LEAVE_DESCRIPTORS_OPEN and close them in the child_setup
   * to work around a deadlock in GLib < 2.60 */
  if (!g_spawn_async_with_pipes (NULL,
                                 (char **) flatpak_argv->pdata,
                                 NULL,
                                 G_SPAWN_SEARCH_PATH | G_SPAWN_DO_NOT_REAP_CHILD | G_SPAWN_LEAVE_DESCRIPTORS_OPEN,
                                 child_setup_func, &child_setup_data,
                                 &pid,
                                 NULL,
                                 NULL,
                                 NULL,
                                 &error))
    {
      gint code = G_DBUS_ERROR_FAILED;
      if (g_error_matches (error, G_SPAWN_ERROR, G_SPAWN_ERROR_ACCES))
        code = G_DBUS_ERROR_ACCESS_DENIED;
      else if (g_error_matches (error, G_SPAWN_ERROR, G_SPAWN_ERROR_NOENT))
        code = G_DBUS_ERROR_FILE_NOT_FOUND;
      g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, code,
                                             "Failed to start command: %s",
                                             error->message);
      return G_DBUS_METHOD_INVOCATION_HANDLED;
    }

  if (instance_id_read_data)
    instance_id_read_data->pid = pid;

  pid_data = g_new0 (PidData, 1);
  pid_data->pid = pid;
  pid_data->client = g_strdup (g_dbus_method_invocation_get_sender (invocation));
  pid_data->watch_bus = (arg_flags & FLATPAK_SPAWN_FLAGS_WATCH_BUS) != 0;
  pid_data->expose_or_share_pids = (expose_pids || share_pids);
  pid_data->child_watch = g_child_watch_add_full (G_PRIORITY_DEFAULT,
                                                  pid,
                                                  child_watch_died,
                                                  pid_data,
                                                  NULL);

  g_info ("Client Pid is %d", pid_data->pid);

  g_hash_table_replace (client_pid_data_hash, GUINT_TO_POINTER (pid_data->pid),
                        pid_data);

  portal_flatpak_complete_spawn (object, invocation, NULL, pid);
  return G_DBUS_METHOD_INVOCATION_HANDLED;
}

static gboolean
handle_spawn_signal (PortalFlatpak         *object,
                     GDBusMethodInvocation *invocation,
                     guint                  arg_pid,
                     guint                  arg_signal,
                     gboolean               arg_to_process_group)
{
  PidData *pid_data = NULL;

  g_info ("spawn_signal(%d %d)", arg_pid, arg_signal);

  pid_data = g_hash_table_lookup (client_pid_data_hash, GUINT_TO_POINTER (arg_pid));
  if (pid_data == NULL ||
      strcmp (pid_data->client, g_dbus_method_invocation_get_sender (invocation)) != 0)
    {
      g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
                                             G_DBUS_ERROR_UNIX_PROCESS_ID_UNKNOWN,
                                             "No such pid");
      return G_DBUS_METHOD_INVOCATION_HANDLED;
    }

  g_info ("Sending signal %d to client pid %d", arg_signal, arg_pid);

  if (arg_to_process_group)
    killpg (pid_data->pid, arg_signal);
  else
    kill (pid_data->pid, arg_signal);

  portal_flatpak_complete_spawn_signal (portal, invocation);

  return G_DBUS_METHOD_INVOCATION_HANDLED;
}

static gboolean
authorize_method_handler (GDBusInterfaceSkeleton *interface,
                          GDBusMethodInvocation  *invocation,
                          gpointer                user_data)
{
  g_autoptr(GError) error = NULL;
  g_autoptr(GKeyFile) keyfile = NULL;
  g_autofree char *app_id = NULL;
  const char *required_sender;

  /* Ensure we don't idle exit */
  schedule_idle_callback ();

  required_sender = g_object_get_data (G_OBJECT (interface), "required-sender");

  if (required_sender)
    {
      const char *sender = g_dbus_method_invocation_get_sender (invocation);
      if (g_strcmp0 (required_sender, sender) != 0)
        {
          g_dbus_method_invocation_return_error (invocation,
                                                 G_DBUS_ERROR, G_DBUS_ERROR_ACCESS_DENIED,
                                                 "Client not allowed to access object");
          return FALSE;
        }
    }

  keyfile = flatpak_invocation_lookup_app_info (invocation, NULL, &error);
  if (keyfile == NULL)
    {
      g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_FAILED,
                                             "Authorization error: %s", error->message);
      return FALSE;
    }

  app_id = g_key_file_get_string (keyfile,
                                  FLATPAK_METADATA_GROUP_APPLICATION,
                                  FLATPAK_METADATA_KEY_NAME, &error);
  if (app_id == NULL)
    {
      g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_FAILED,
                                             "Authorization error: %s", error->message);
      return FALSE;
    }

  g_object_set_data_full (G_OBJECT (invocation), "app-info", g_steal_pointer (&keyfile), (GDestroyNotify) g_key_file_unref);

  return TRUE;
}

static void
register_update_monitor (PortalFlatpakUpdateMonitor *monitor,
                         const char                 *obj_path)
{
  G_LOCK (update_monitors);

  g_hash_table_insert (update_monitors, g_strdup (obj_path), g_object_ref (monitor));

  /* Trigger update timeout if needed */
  if (update_monitors_timeout == 0 && !update_monitors_timeout_running_thread)
    update_monitors_timeout = g_timeout_add_seconds (opt_poll_timeout, check_all_for_updates_cb, NULL);

  G_UNLOCK (update_monitors);
}

static void
unregister_update_monitor (const char *obj_path)
{
  G_LOCK (update_monitors);
  g_hash_table_remove (update_monitors, obj_path);
  G_UNLOCK (update_monitors);
}

static gboolean
has_update_monitors (void)
{
  gboolean res;
  G_LOCK (update_monitors);
  res = g_hash_table_size (update_monitors) > 0;
  G_UNLOCK (update_monitors);
  return res;
}

static GList *
update_monitors_get_all (const char *optional_sender)
{
  GList *list = NULL;

  G_LOCK (update_monitors);
  if (update_monitors)
    {
      GLNX_HASH_TABLE_FOREACH_V (update_monitors, PortalFlatpakUpdateMonitor *, monitor)
        {
          UpdateMonitorData *data = update_monitor_get_data (monitor);

          if (optional_sender == NULL ||
              strcmp (data->sender, optional_sender) == 0)
            list = g_list_prepend (list, g_object_ref (monitor));
        }
    }
  G_UNLOCK (update_monitors);

  return list;
}

static void
update_monitor_data_free (gpointer data)
{
  UpdateMonitorData *m = data;

  g_mutex_clear (&m->lock);

  g_free (m->sender);
  g_free (m->obj_path);
  g_object_unref (m->cancellable);

  g_free (m->name);
  g_free (m->arch);
  g_free (m->branch);
  g_free (m->commit);
  g_free (m->app_path);

  g_free (m->reported_local_commit);
  g_free (m->reported_remote_commit);

  g_free (m);
}

static UpdateMonitorData *
update_monitor_get_data (PortalFlatpakUpdateMonitor *monitor)
{
  return (UpdateMonitorData *)g_object_get_data (G_OBJECT (monitor), "update-monitor-data");
}

static PortalFlatpakUpdateMonitor *
create_update_monitor (GDBusMethodInvocation *invocation,
                       const char            *obj_path,
                       GError               **error)
{
  PortalFlatpakUpdateMonitor *monitor;
  UpdateMonitorData *m;
  g_autoptr(GKeyFile) app_info = NULL;
  g_autofree char *name = NULL;

  app_info = flatpak_invocation_lookup_app_info (invocation, NULL, error);
  if (app_info == NULL)
    return NULL;

  name = g_key_file_get_string (app_info,
                                FLATPAK_METADATA_GROUP_APPLICATION,
                                "name", NULL);
  if (name == NULL || *name == 0)
    {
      g_set_error (error, G_DBUS_ERROR, G_DBUS_ERROR_NOT_SUPPORTED,
                   "Updates only supported by flatpak apps");
      return NULL;
    }

  m = g_new0 (UpdateMonitorData, 1);

  g_mutex_init (&m->lock);
  m->obj_path = g_strdup (obj_path);
  m->sender = g_strdup (g_dbus_method_invocation_get_sender (invocation));
  m->cancellable = g_cancellable_new ();

  m->name = g_steal_pointer (&name);
  m->arch = g_key_file_get_string (app_info,
                                   FLATPAK_METADATA_GROUP_INSTANCE,
                                   "arch", NULL);
  m->branch = g_key_file_get_string (app_info,
                                     FLATPAK_METADATA_GROUP_INSTANCE,
                                     "branch", NULL);
  m->commit = g_key_file_get_string (app_info,
                                     FLATPAK_METADATA_GROUP_INSTANCE,
                                     "app-commit", NULL);
  m->app_path = g_key_file_get_string (app_info,
                                       FLATPAK_METADATA_GROUP_INSTANCE,
                                       "app-path", NULL);

  m->reported_local_commit = g_strdup (m->commit);
  m->reported_remote_commit = g_strdup (m->commit);

  monitor = portal_flatpak_update_monitor_skeleton_new ();

  g_object_set_data_full (G_OBJECT (monitor), "update-monitor-data", m, update_monitor_data_free);
  g_object_set_data_full (G_OBJECT (monitor), "required-sender", g_strdup (m->sender), g_free);

  g_info ("created UpdateMonitor for %s/%s at %s", m->name, m->branch, obj_path);

  return monitor;
}

static void
update_monitor_do_close (PortalFlatpakUpdateMonitor *monitor)
{
  UpdateMonitorData *m = update_monitor_get_data (monitor);

  g_dbus_interface_skeleton_unexport (G_DBUS_INTERFACE_SKELETON (monitor));
  unregister_update_monitor (m->obj_path);
}

/* Always called in worker thread */
static void
update_monitor_close (PortalFlatpakUpdateMonitor *monitor)
{
  UpdateMonitorData *m = update_monitor_get_data (monitor);
  gboolean do_close;

  g_mutex_lock (&m->lock);
  /* Close at most once, but not if running, if running it will be closed when that is done */
  do_close = !m->closed && !m->running;
  m->closed = TRUE;
  g_mutex_unlock (&m->lock);

  /* Always cancel though, so we can exit any running code early */
  g_cancellable_cancel (m->cancellable);

  if (do_close)
    update_monitor_do_close (monitor);
}

static GDBusConnection *
update_monitor_get_connection (PortalFlatpakUpdateMonitor *monitor)
{
  return g_dbus_interface_skeleton_get_connection (G_DBUS_INTERFACE_SKELETON (monitor));
}

static GHashTable *installation_cache = NULL;

static void
clear_installation_cache (void)
{
  if (installation_cache != NULL)
    g_hash_table_remove_all (installation_cache);
}

/* Caching lookup of Installation for a path */
static FlatpakInstallation *
lookup_installation_for_path (GFile *path, GError **error)
{
  FlatpakInstallation *installation;

  if (installation_cache == NULL)
    installation_cache = g_hash_table_new_full (g_file_hash, (GEqualFunc)g_file_equal, g_object_unref, g_object_unref);

  installation = g_hash_table_lookup (installation_cache, path);
  if (installation == NULL)
    {
      g_autoptr(FlatpakDir) dir = NULL;

      dir = flatpak_dir_get_by_path (path);
      installation = flatpak_installation_new_for_dir (dir, NULL, error);
      if (installation == NULL)
        return NULL;

      flatpak_installation_set_no_interaction (installation, TRUE);

      g_hash_table_insert (installation_cache, g_object_ref (path), installation);
    }

  return g_object_ref (installation);
}

static GFile *
update_monitor_get_installation_path (PortalFlatpakUpdateMonitor *monitor)
{
  UpdateMonitorData *m = update_monitor_get_data (monitor);
  g_autoptr(GFile) app_path = NULL;

  app_path = g_file_new_for_path (m->app_path);

  /* The app path is always 6 level deep inside the installation dir,
   * like $dir/app/org.the.app/x86_64/stable/$commit/files, so we find
   * the installation by just going up 6 parents. */
  return g_file_resolve_relative_path (app_path, "../../../../../..");
}

static void
check_for_updates (PortalFlatpakUpdateMonitor *monitor)
{
  UpdateMonitorData *m = update_monitor_get_data (monitor);
  g_autoptr(GFile) installation_path = NULL;
  g_autoptr(FlatpakInstallation) installation = NULL;
  g_autoptr(FlatpakInstalledRef) installed_ref = NULL;
  g_autoptr(FlatpakRemoteRef) remote_ref = NULL;
  const char *origin = NULL;
  const char *local_commit = NULL;
  const char *remote_commit;
  g_autoptr(GError) error = NULL;
  g_autoptr(FlatpakDir) dir = NULL;
  const char *ref;

  installation_path = update_monitor_get_installation_path (monitor);

  g_info ("Checking for updates for %s/%s/%s in %s", m->name, m->arch, m->branch, flatpak_file_get_path_cached (installation_path));

  installation = lookup_installation_for_path (installation_path, &error);
  if (installation == NULL)
    {
      g_info ("Unable to find installation for path %s: %s", flatpak_file_get_path_cached (installation_path), error->message);
      return;
    }

  installed_ref = flatpak_installation_get_installed_ref (installation,
                                                          FLATPAK_REF_KIND_APP,
                                                          m->name, m->arch, m->branch,
                                                          m->cancellable, &error);
  if (installed_ref == NULL)
    {
      g_info ("getting installed ref failed: %s", error->message);
      return; /* Never report updates for uninstalled refs */
    }

  dir = flatpak_installation_get_dir (installation, NULL);
  if (dir == NULL)
    return;

  ref = flatpak_ref_format_ref_cached (FLATPAK_REF (installed_ref));
  if (flatpak_dir_ref_is_masked (dir, ref))
    return; /* Never report updates for masked refs */

  local_commit = flatpak_ref_get_commit (FLATPAK_REF (installed_ref));

  origin = flatpak_installed_ref_get_origin (installed_ref);

  remote_ref = flatpak_installation_fetch_remote_ref_sync (installation, origin,
                                                           FLATPAK_REF_KIND_APP,
                                                           m->name, m->arch, m->branch,
                                                           m->cancellable, &error);
  if (remote_ref == NULL)
    {
      /* Probably some network issue.
       * Fall back to the local_commit to at least be able to pick up already installed updates.
       */
      g_info ("getting remote ref failed: %s", error->message);
      g_clear_error (&error);
      remote_commit = local_commit;
    }
  else
    {
      remote_commit = flatpak_ref_get_commit (FLATPAK_REF (remote_ref));
      if (remote_commit == NULL)
        {
          /* This can happen if we're offline and there is an update from an usb drive.
           * Not much we can do in terms of reporting it, but at least handle the case
           */
          g_info ("Unknown remote commit, setting to local_commit");
          remote_commit = local_commit;
        }
    }

  if (g_strcmp0 (m->reported_local_commit, local_commit) != 0 ||
      g_strcmp0 (m->reported_remote_commit, remote_commit) != 0)
    {
      GVariantBuilder builder;
      gboolean is_closed;

      g_free (m->reported_local_commit);
      m->reported_local_commit = g_strdup (local_commit);

      g_free (m->reported_remote_commit);
      m->reported_remote_commit = g_strdup (remote_commit);

      g_info ("Found update for %s/%s/%s, local: %s, remote: %s", m->name, m->arch, m->branch, local_commit, remote_commit);
      g_variant_builder_init (&builder, G_VARIANT_TYPE_VARDICT);
      g_variant_builder_add (&builder, "{sv}", "running-commit", g_variant_new_string (m->commit));
      g_variant_builder_add (&builder, "{sv}", "local-commit", g_variant_new_string (local_commit));
      g_variant_builder_add (&builder, "{sv}", "remote-commit", g_variant_new_string (remote_commit));

      /* Maybe someone closed the monitor while we were checking for updates, then drop the signal.
       * There is still a minimal race between this check and the emit where a client could call close()
       * and still see the signal though. */
      g_mutex_lock (&m->lock);
      is_closed = m->closed;
      g_mutex_unlock (&m->lock);

      if (!is_closed &&
          !g_dbus_connection_emit_signal (update_monitor_get_connection (monitor),
                                          m->sender,
                                          m->obj_path,
                                          FLATPAK_PORTAL_INTERFACE_UPDATE_MONITOR,
                                          "UpdateAvailable",
                                          g_variant_new ("(a{sv})", &builder),
                                          &error))
        {
          g_warning ("Failed to emit UpdateAvailable: %s", error->message);
          g_clear_error (&error);
        }
    }
}

static void
check_all_for_updates_in_thread_func (GTask *task,
                                      gpointer source_object,
                                      gpointer task_data,
                                      GCancellable *cancellable)
{
  GList *monitors, *l;

  monitors = update_monitors_get_all (NULL);

  for (l = monitors; l != NULL; l = l->next)
    {
      PortalFlatpakUpdateMonitor *monitor = l->data;
      UpdateMonitorData *m = update_monitor_get_data (monitor);
      gboolean was_closed = FALSE;

      g_mutex_lock (&m->lock);
      if (m->closed)
        was_closed = TRUE;
      else
        m->running = TRUE;
      g_mutex_unlock (&m->lock);

      if (!was_closed)
        {
          check_for_updates (monitor);

          g_mutex_lock (&m->lock);
          m->running = FALSE;
          if (m->closed) /* Was closed during running, do delayed close */
            update_monitor_do_close (monitor);
          g_mutex_unlock (&m->lock);
        }
    }

  g_list_free_full (monitors, g_object_unref);


/* We want to cache stuff between multiple monitors
   when a poll is scheduled, but there is no need to keep it
   long term to the next poll, the in-memory is just
   a waste of space then. */
  clear_installation_cache ();

  G_LOCK (update_monitors);
  update_monitors_timeout_running_thread = FALSE;

  if (g_hash_table_size (update_monitors) > 0)
    update_monitors_timeout = g_timeout_add_seconds (opt_poll_timeout, check_all_for_updates_cb, NULL);

  G_UNLOCK (update_monitors);
}

/* Runs on main thread */
static gboolean
check_all_for_updates_cb (void *data)
{
  g_autoptr(GTask) task = g_task_new (NULL, NULL, NULL, NULL);

  if (!opt_poll_when_metered &&
      g_network_monitor_get_network_metered (network_monitor))
    {
      g_info ("Skipping update check on metered network");

      return G_SOURCE_CONTINUE;
    }

  g_info ("Checking all update monitors");

  G_LOCK (update_monitors);
  update_monitors_timeout = 0;
  update_monitors_timeout_running_thread = TRUE;
  G_UNLOCK (update_monitors);

  g_task_run_in_thread (task, check_all_for_updates_in_thread_func);

  return G_SOURCE_REMOVE; /* This will be re-added by the thread when done */
}

/* Runs in worker thread */
static gboolean
handle_create_update_monitor (PortalFlatpak *object,
                              GDBusMethodInvocation *invocation,
                              GVariant *options)
{
  GDBusConnection *connection = g_dbus_method_invocation_get_connection (invocation);
  g_autoptr(PortalFlatpakUpdateMonitorSkeleton) monitor = NULL;
  const char *sender;
  g_autofree char *sender_escaped = NULL;
  g_autofree char *obj_path = NULL;
  g_autofree char *token = NULL;
  g_autoptr(GError) error = NULL;
  int i;

  if (!g_variant_lookup (options, "handle_token", "s", &token))
    token = g_strdup_printf ("%d", g_random_int_range (0, 1000));

  sender = g_dbus_method_invocation_get_sender (invocation);
  g_info ("handle CreateUpdateMonitor from %s", sender);

  sender_escaped = g_strdup (sender + 1);
  for (i = 0; sender_escaped[i]; i++)
    {
      if (sender_escaped[i] == '.')
        sender_escaped[i] = '_';
    }

  obj_path = g_strdup_printf ("%s/update_monitor/%s/%s",
                              FLATPAK_PORTAL_PATH,
                              sender_escaped,
                              token);

  monitor = (PortalFlatpakUpdateMonitorSkeleton *) create_update_monitor (invocation, obj_path, &error);
  if (monitor == NULL)
    {
      g_dbus_method_invocation_return_gerror (invocation, error);
      return G_DBUS_METHOD_INVOCATION_HANDLED;
    }

  g_signal_connect (monitor, "handle-close", G_CALLBACK (handle_close), NULL);
  g_signal_connect (monitor, "handle-update", G_CALLBACK (handle_update), NULL);
  g_signal_connect (monitor, "g-authorize-method", G_CALLBACK (authorize_method_handler), NULL);

  if (!g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (monitor),
                                         connection,
                                         obj_path,
                                         &error))
    {
      g_dbus_method_invocation_return_gerror (invocation, error);
      return G_DBUS_METHOD_INVOCATION_HANDLED;
    }

  register_update_monitor ((PortalFlatpakUpdateMonitor*)monitor, obj_path);

  portal_flatpak_complete_create_update_monitor (portal, invocation, obj_path);

  return G_DBUS_METHOD_INVOCATION_HANDLED;
}

/* Runs in worker thread */
static gboolean
handle_close (PortalFlatpakUpdateMonitor *monitor,
              GDBusMethodInvocation *invocation)
{
  update_monitor_close (monitor);

  g_info ("handle UpdateMonitor.Close");

  portal_flatpak_update_monitor_complete_close (monitor, invocation);

  return G_DBUS_METHOD_INVOCATION_HANDLED;
}

static void
deep_free_object_list (gpointer data)
{
  g_list_free_full ((GList *)data, g_object_unref);
}

static void
close_update_monitors_in_thread_func (GTask *task,
                                      gpointer source_object,
                                      gpointer task_data,
                                      GCancellable *cancellable)
{
  GList *list = task_data;
  GList *l;

  for (l = list; l; l = l->next)
    {
      PortalFlatpakUpdateMonitor *monitor = l->data;
      UpdateMonitorData *m = update_monitor_get_data (monitor);

      g_info ("closing monitor %s", m->obj_path);
      update_monitor_close (monitor);
    }
}

static void
close_update_monitors_for_sender (const char *sender)
{
  GList *list = update_monitors_get_all (sender);

  if (list)
    {
      g_autoptr(GTask) task = g_task_new (NULL, NULL, NULL, NULL);
      g_task_set_task_data (task, list, deep_free_object_list);

      g_info ("%s dropped off the bus, closing monitors", sender);
      g_task_run_in_thread (task, close_update_monitors_in_thread_func);
    }
}

static guint32
get_update_permission (const char *app_id)
{
  g_autoptr(GVariant) out_perms = NULL;
  g_autoptr(GVariant) out_data = NULL;
  g_autoptr(GError) error = NULL;
  guint32 ret = UNSET;

  if (permission_store == NULL)
    {
      g_info ("No portals installed, assume no permissions");
      return NO;
    }

  if (!xdp_dbus_permission_store_call_lookup_sync (permission_store,
                                                   PERMISSION_TABLE,
                                                   PERMISSION_ID,
                                                   &out_perms,
                                                   &out_data,
                                                   NULL,
                                                   &error))
    {
      g_dbus_error_strip_remote_error (error);
      g_info ("No updates permissions found: %s", error->message);
      g_clear_error (&error);
    }

  if (out_perms != NULL)
    {
      const char **perms;

      if (g_variant_lookup (out_perms, app_id, "^a&s", &perms))
        {
          if (strcmp (perms[0], "ask") == 0)
            ret = ASK;
          else if (strcmp (perms[0], "yes") == 0)
            ret = YES;
          else
            ret = NO;
        }
    }

  g_info ("Updates permissions for %s: %d", app_id, ret);

  return ret;
}

static void
set_update_permission (const char *app_id,
                       Permission permission)
{
  g_autoptr(GError) error = NULL;
  const char *permissions[2];

  if (permission == ASK)
    permissions[0] = "ask";
  else if (permission == YES)
    permissions[0] = "yes";
  else if (permission == NO)
    permissions[0] = "no";
  else
    {
      g_warning ("Wrong permission format, ignoring");
      return;
    }
  permissions[1] = NULL;

  if (!xdp_dbus_permission_store_call_set_permission_sync (permission_store,
                                                           PERMISSION_TABLE,
                                                           TRUE,
                                                           PERMISSION_ID,
                                                           app_id,
                                                           (const char * const*)permissions,
                                                           NULL,
                                                           &error))
    {
      g_dbus_error_strip_remote_error (error);
      g_info ("Error updating permission store: %s", error->message);
    }
}

static char *
get_app_display_name (const char *app_id)
{
  g_autofree char *id = NULL;
  g_autoptr(GDesktopAppInfo) info = NULL;
  const char *name = NULL;

  id = g_strconcat (app_id, ".desktop", NULL);
  info = g_desktop_app_info_new (id);
  if (info)
    {
      name = g_app_info_get_display_name (G_APP_INFO (info));
      if (name)
        return g_strdup (name);
    }

  return g_strdup (app_id);
}

static gboolean
request_update_permissions_sync (PortalFlatpakUpdateMonitor *monitor,
                                 const char *app_id,
                                 const char *window,
                                 GError **error)
{
  Permission permission;

  permission = get_update_permission (app_id);
  if (permission == UNSET || permission == ASK)
    {
      guint access_response = 2;
      PortalImplementation *access_impl;
      GVariantBuilder access_opt_builder;
      g_autofree char *app_name = NULL;
      g_autofree char *title = NULL;
      g_autoptr(GVariant) ret = NULL;

      access_impl = find_portal_implementation ("org.freedesktop.impl.portal.Access");
      if (access_impl == NULL)
        {
          g_warning ("No Access portal implementation found");
          g_set_error (error, G_DBUS_ERROR, G_DBUS_ERROR_NOT_SUPPORTED, _("No portal support found"));
          return FALSE;
        }

      g_variant_builder_init (&access_opt_builder, G_VARIANT_TYPE_VARDICT);
      g_variant_builder_add (&access_opt_builder, "{sv}",
                             "deny_label", g_variant_new_string (_("Deny")));
      g_variant_builder_add (&access_opt_builder, "{sv}",
                             "grant_label", g_variant_new_string (_("Update")));
      g_variant_builder_add (&access_opt_builder, "{sv}",
                             "icon", g_variant_new_string ("package-x-generic-symbolic"));

      app_name = get_app_display_name (app_id);
      title = g_strdup_printf (_("Update %s?"), app_name);

      ret = g_dbus_connection_call_sync (update_monitor_get_connection (monitor),
                                         access_impl->dbus_name,
                                         "/org/freedesktop/portal/desktop",
                                         "org.freedesktop.impl.portal.Access",
                                         "AccessDialog",
                                         g_variant_new ("(osssssa{sv})",
                                                        "/request/path",
                                                        app_id,
                                                        window,
                                                        title,
                                                        _("The application wants to update itself."),
                                                        _("Update access can be changed any time from the privacy settings."),
                                                        &access_opt_builder),
                                         G_VARIANT_TYPE ("(ua{sv})"),
                                         G_DBUS_CALL_FLAGS_NONE,
                                         G_MAXINT,
                                         NULL,
                                         error);
      if (ret == NULL)
        {
          g_dbus_error_strip_remote_error (*error);
          g_warning ("Failed to show access dialog: %s", (*error)->message);
          return FALSE;
        }

      g_variant_get (ret, "(ua{sv})", &access_response, NULL);

      if (permission == UNSET)
        set_update_permission (app_id, (access_response == 0) ? YES : NO);

      permission = (access_response == 0) ? YES : NO;
    }

  if (permission == NO)
    {
      g_set_error (error, G_DBUS_ERROR, G_DBUS_ERROR_ACCESS_DENIED,
                   _("Application update not allowed"));
      return FALSE;
    }

  return TRUE;
}

static void
emit_progress (PortalFlatpakUpdateMonitor *monitor,
               int op,
               int n_ops,
               int progress,
               int status,
               const char *error_name,
               const char *error_message)
{
  UpdateMonitorData *m = update_monitor_get_data (monitor);
  GDBusConnection *connection;
  GVariantBuilder builder;
  g_autoptr(GError) error = NULL;

  g_info ("%d/%d ops, progress %d, status: %d", op, n_ops, progress, status);

  g_variant_builder_init (&builder, G_VARIANT_TYPE_VARDICT);
  if (n_ops > 0)
    {
      g_variant_builder_add (&builder, "{sv}", "op", g_variant_new_uint32 (op));
      g_variant_builder_add (&builder, "{sv}", "n_ops", g_variant_new_uint32 (n_ops));
      g_variant_builder_add (&builder, "{sv}", "progress", g_variant_new_uint32 (progress));
    }

  g_variant_builder_add (&builder, "{sv}", "status", g_variant_new_uint32 (status));

  if (error_name)
    {
      g_variant_builder_add (&builder, "{sv}", "error", g_variant_new_string (error_name));
      g_variant_builder_add (&builder, "{sv}", "error_message", g_variant_new_string (error_message));
    }

  connection = update_monitor_get_connection (monitor);
  if (!g_dbus_connection_emit_signal (connection,
                                      m->sender,
                                      m->obj_path,
                                      FLATPAK_PORTAL_INTERFACE_UPDATE_MONITOR,
                                      "Progress",
                                      g_variant_new ("(a{sv})", &builder),
                                      &error))
    {
      g_warning ("Failed to emit ::progress: %s", error->message);
    }
}

static char *
get_progress_error (const GError *update_error)
{
  g_autofree gchar *name = NULL;

  name = g_dbus_error_encode_gerror (update_error);

  /* Don't return weird dbus wrapped things from the portal */
  if (g_str_has_prefix (name, "org.gtk.GDBus.UnmappedGError.Quark"))
    return g_strdup ("org.freedesktop.DBus.Error.Failed");
  return g_steal_pointer (&name);
}

static void
emit_progress_error (PortalFlatpakUpdateMonitor *monitor,
                     GError *update_error)
{
  g_autofree gchar *error_name = get_progress_error (update_error);

  emit_progress (monitor, 0, 0, 0,
                 PROGRESS_STATUS_ERROR,
                 error_name, update_error->message);
}

static void
send_variant (GVariant *v, GOutputStream *out)
{
  g_autoptr(GError) error = NULL;
  const guchar *data;
  gsize size;
  guint32 size32;

  data = g_variant_get_data (v);
  size = g_variant_get_size (v);
  size32 = size;

  if (!g_output_stream_write_all (out, &size32, 4, NULL, NULL, &error) ||
      !g_output_stream_write_all (out, data, size, NULL, NULL, &error))
    {
      g_warning ("sending to parent failed: %s", error->message);
      exit (1); // This will exit the child process and cause the parent to report an error
    }
}

static void
send_progress (GOutputStream *out,
               int op,
               int n_ops,
               int progress,
               int status,
               const GError *update_error)
{
  g_autoptr(GVariant) v = NULL;
  g_autofree gchar *error_name = NULL;

  if (update_error)
    error_name = get_progress_error (update_error);

  v = g_variant_ref_sink (g_variant_new ("(uuuuss)",
                                         op, n_ops, progress, status,
                                         error_name ? error_name : "",
                                         update_error ? update_error->message : ""));
  send_variant (v, out);
}

typedef struct {
  GOutputStream *out;
  int n_ops;
  int op;
  int progress;
  gboolean saw_first_operation;
} TransactionData;

static gboolean
transaction_ready (FlatpakTransaction *transaction,
                   TransactionData *d)
{
  g_autolist(FlatpakTransactionOperation) ops =
    flatpak_transaction_get_operations (transaction);
  int status;
  GList *l;

  d->n_ops = g_list_length (ops);
  d->op = 0;
  d->progress = 0;

  for (l = ops; l != NULL; l = l->next)
    {
      FlatpakTransactionOperation *op = l->data;
      const char *ref = flatpak_transaction_operation_get_ref (op);
      FlatpakTransactionOperationType type = flatpak_transaction_operation_get_operation_type (op);

      /* Actual app updates need to not increase permission requirements */
      if (type == FLATPAK_TRANSACTION_OPERATION_UPDATE && g_str_has_prefix (ref, "app/"))
        {
          GKeyFile *new_metadata = flatpak_transaction_operation_get_metadata (op);
          GKeyFile *old_metadata = flatpak_transaction_operation_get_old_metadata (op);
          g_autoptr(FlatpakContext) new_context = flatpak_context_new ();
          g_autoptr(FlatpakContext) old_context = flatpak_context_new ();

          if (!flatpak_context_load_metadata (new_context, new_metadata, NULL) ||
              !flatpak_context_load_metadata (old_context, old_metadata, NULL) ||
              flatpak_context_adds_permissions (old_context, new_context))
            {
              g_autoptr(GError) error = NULL;
              g_set_error (&error, G_DBUS_ERROR, G_DBUS_ERROR_NOT_SUPPORTED,
                           _("Self update not supported, new version requires new permissions"));
              send_progress (d->out,
                             d->op,  d->n_ops, d->progress,
                             PROGRESS_STATUS_ERROR,
                             error);
              return FALSE;
            }
        }
    }

  if (flatpak_transaction_is_empty (transaction))
    status = PROGRESS_STATUS_EMPTY;
  else
    status = PROGRESS_STATUS_RUNNING;

  send_progress (d->out,
                 d->op,  d->n_ops,
                 d->progress, status,
                 NULL);

  if (status == PROGRESS_STATUS_EMPTY)
    return FALSE; /* This will cause us to return an ABORTED error */

  return TRUE;
}

static void
transaction_progress_changed (FlatpakTransactionProgress *progress,
                              TransactionData *d)
{
  /* Only report 100 when really done */
  d->progress = MIN (flatpak_transaction_progress_get_progress (progress), 99);

  send_progress (d->out,
                 d->op,  d->n_ops,
                 d->progress, PROGRESS_STATUS_RUNNING,
                 NULL);
}

static void
transaction_new_operation (FlatpakTransaction *transaction,
                           FlatpakTransactionOperation *op,
                           FlatpakTransactionProgress *progress,
                           TransactionData *d)
{
  d->progress = 0;
  if (d->saw_first_operation)
    d->op++;
  else
    d->saw_first_operation = TRUE;

  send_progress (d->out,
                 d->op,  d->n_ops,
                 d->progress, PROGRESS_STATUS_RUNNING,
                 NULL);

  g_signal_connect (progress, "changed", G_CALLBACK (transaction_progress_changed), d);
}

static gboolean
transaction_operation_error  (FlatpakTransaction            *transaction,
                              FlatpakTransactionOperation   *operation,
                              const GError                  *error,
                              FlatpakTransactionErrorDetails detail,
                              TransactionData *d)
{
  gboolean non_fatal = (detail & FLATPAK_TRANSACTION_ERROR_DETAILS_NON_FATAL) != 0;

  if (non_fatal)
    return TRUE;  /* Continue */

  send_progress (d->out,
                 d->op,  d->n_ops, d->progress,
                 PROGRESS_STATUS_ERROR,
                 error);

  return FALSE; /* This will cause us to return an ABORTED error */
}


static void
transaction_operation_done (FlatpakTransaction *transaction,
                            FlatpakTransactionOperation *op,
                            const char *commit,
                            FlatpakTransactionResult result,
                            TransactionData *d)
{
  d->progress = 100;

  send_progress (d->out,
                 d->op,  d->n_ops,
                 d->progress, PROGRESS_STATUS_RUNNING,
                 NULL);
}

static void
update_child_setup_func (gpointer user_data)
{
  int *socket = user_data;

  dup2 (*socket, 3);
  g_fdwalk_set_cloexec (4);
}

/* This is the meat of the update process, its run out of process (via
   spawn) to avoid running lots of complicated code in the portal
   process and possibly long-term leaks in a long-running process. */
static int
do_update_child_process (const char *installation_path, const char *ref, int socket_fd)
{
  g_autoptr(GOutputStream) out = g_unix_output_stream_new (socket_fd, TRUE);
  g_autoptr(FlatpakInstallation) installation = NULL;
  g_autoptr(FlatpakTransaction) transaction = NULL;
  g_autoptr(GFile) f = g_file_new_for_path (installation_path);
  g_autoptr(GError) error = NULL;
  g_autoptr(FlatpakDir) dir = NULL;
  TransactionData transaction_data = { NULL };

  dir = flatpak_dir_get_by_path (f);

  if (!flatpak_dir_maybe_ensure_repo (dir, NULL, &error))
    {
      send_progress (out, 0, 0, 0,
                     PROGRESS_STATUS_ERROR, error);
      return 0;
    }

  installation = flatpak_installation_new_for_dir (dir, NULL, &error);
  if (installation)
    transaction = flatpak_transaction_new_for_installation (installation, NULL, &error);
  if (transaction == NULL)
    {
      send_progress (out, 0, 0, 0,
                     PROGRESS_STATUS_ERROR, error);
      return 0;
    }

  flatpak_transaction_add_default_dependency_sources (transaction);

  if (!flatpak_transaction_add_update (transaction, ref, NULL, NULL, &error))
    {
      send_progress (out, 0, 0, 0,
                     PROGRESS_STATUS_ERROR, error);
      return 0;
    }

  transaction_data.out = out;

  g_signal_connect (transaction, "ready", G_CALLBACK (transaction_ready), &transaction_data);
  g_signal_connect (transaction, "new-operation", G_CALLBACK (transaction_new_operation), &transaction_data);
  g_signal_connect (transaction, "operation-done", G_CALLBACK (transaction_operation_done), &transaction_data);
  g_signal_connect (transaction, "operation-error", G_CALLBACK (transaction_operation_error), &transaction_data);

  if (!flatpak_transaction_run (transaction, NULL, &error))
    {
      if (!g_error_matches (error, FLATPAK_ERROR, FLATPAK_ERROR_ABORTED)) /* If aborted we already sent error */
        send_progress (out, transaction_data.op, transaction_data.n_ops, transaction_data.progress,
                       PROGRESS_STATUS_ERROR, error);
      return 0;
    }

  send_progress (out, transaction_data.op, transaction_data.n_ops, transaction_data.progress,
                 PROGRESS_STATUS_DONE, error);

  return 0;
}

static GVariant *
read_variant (GInputStream *in,
              GCancellable *cancellable,
              GError **error)
{
  guint32 size;
  g_autofree guchar *data_owned = NULL;
  guchar *data;
  gsize bytes_read;

  if (!g_input_stream_read_all (in, &size, 4, &bytes_read, cancellable, error))
    return NULL;

  if (bytes_read != 4)
    {
      g_set_error (error, G_DBUS_ERROR, G_DBUS_ERROR_FAILED,
                   _("Update ended unexpectedly"));
      return NULL;
    }

  data_owned = g_try_malloc (size);
  data = data_owned;
  if (data == NULL)
    {
      flatpak_fail (error, "Out of memory");
      return NULL;
    }

  if (!g_input_stream_read_all (in, data, size, &bytes_read, cancellable, error))
    return NULL;

  if (bytes_read != size)
    {
      g_set_error (error, G_DBUS_ERROR, G_DBUS_ERROR_FAILED,
                   _("Update ended unexpectedly"));
      return NULL;
    }

  return g_variant_ref_sink (g_variant_new_from_data (G_VARIANT_TYPE("(uuuuss)"),
                                                      data, size, FALSE,
                                                      g_free,
                                                      g_steal_pointer (&data_owned)));
}

/* We do the actual update out of process (in do_update_child_process,
   via spawn) and just proxy the feedback here */
static gboolean
handle_update_responses (PortalFlatpakUpdateMonitor *monitor,
                         int socket_fd,
                         GError **error)
{
  g_autoptr(GInputStream) in = g_unix_input_stream_new (socket_fd, FALSE); /* Closed by parent */
  UpdateMonitorData *m = update_monitor_get_data (monitor);
  guint32 status;

  do
    {
      g_autoptr(GVariant) v = NULL;
      guint32 op;
      guint32 n_ops;
      guint32 progress;
      const char *error_name;
      const char *error_message;

      v = read_variant (in, m->cancellable, error);
      if (v == NULL)
        {
          g_info ("Reading message from child update process failed %s", (*error)->message);
          return FALSE;
        }

      g_variant_get (v, "(uuuu&s&s)",
                     &op, &n_ops, &progress, &status, &error_name, &error_message);

      emit_progress (monitor, op, n_ops, progress, status,
                     *error_name != 0 ? error_name : NULL,
                     *error_message != 0 ? error_message : NULL);
    }
  while (status == PROGRESS_STATUS_RUNNING);

  /* Don't return an received error as we emitted it already, that would cause it to be emitted twice */
  return TRUE;
}

static void
handle_update_in_thread_func (GTask *task,
                              gpointer source_object,
                              gpointer task_data,
                              GCancellable *cancellable)
{
  PortalFlatpakUpdateMonitor *monitor = source_object;
  UpdateMonitorData *m = update_monitor_get_data (monitor);
  g_autoptr(GError) error = NULL;
  const char *window;

  window = (const char *)g_object_get_data (G_OBJECT (task), "window");

  if (request_update_permissions_sync (monitor, m->name, window, &error))
    {
      g_autoptr(GFile) installation_path = update_monitor_get_installation_path (monitor);
      g_autofree char *ref = flatpak_build_app_ref (m->name, m->branch, m->arch);
      const char *argv[] = { "/proc/self/exe", "flatpak-portal", "--update", flatpak_file_get_path_cached (installation_path), ref, NULL };
      int sockets[2];
      GPid pid;

      if (socketpair (AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, sockets) != 0)
        {
          glnx_throw_errno (&error);
        }
      else
        {
          gboolean spawn_ok;

          spawn_ok = g_spawn_async (NULL, (char **)argv, NULL,
                                    G_SPAWN_FILE_AND_ARGV_ZERO |
                                    G_SPAWN_LEAVE_DESCRIPTORS_OPEN,
                                    update_child_setup_func, &sockets[1],
                                    &pid, &error);
          close (sockets[1]); // Close remote side
          if (spawn_ok)
            {
              if (!handle_update_responses (monitor, sockets[0], &error))
                {
                  if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
                    kill (pid, SIGINT);
                }
            }
          close (sockets[0]); // Close local side
        }
    }

  if (error)
    emit_progress_error (monitor, error);

  g_mutex_lock (&m->lock);
  m->installing = FALSE;
  g_mutex_unlock (&m->lock);
}

static gboolean
handle_update (PortalFlatpakUpdateMonitor *monitor,
               GDBusMethodInvocation *invocation,
               const char *arg_window,
               GVariant *arg_options)
{
  UpdateMonitorData *m = update_monitor_get_data (monitor);
  g_autoptr(GTask) task = NULL;
  gboolean already_installing = FALSE;

  g_info ("handle UpdateMonitor.Update");

  g_mutex_lock (&m->lock);
  if (m->installing)
    already_installing = TRUE;
  else
    m->installing = TRUE;
  g_mutex_unlock (&m->lock);

  if (already_installing)
    {
      g_dbus_method_invocation_return_error (invocation,
                                             G_DBUS_ERROR,
                                             G_DBUS_ERROR_FAILED,
                                             "Already installing");
      return G_DBUS_METHOD_INVOCATION_HANDLED;
    }

  task = g_task_new (monitor, NULL, NULL, NULL);
  g_object_set_data_full (G_OBJECT (task), "window", g_strdup (arg_window), g_free);
  g_task_run_in_thread (task, handle_update_in_thread_func);

  portal_flatpak_update_monitor_complete_update (monitor, invocation);

  return G_DBUS_METHOD_INVOCATION_HANDLED;
}




static void
name_owner_changed (GDBusConnection *connection,
                    const gchar     *sender_name,
                    const gchar     *object_path,
                    const gchar     *interface_name,
                    const gchar     *signal_name,
                    GVariant        *parameters,
                    gpointer         user_data)
{
  const char *name, *from, *to;

  g_variant_get (parameters, "(&s&s&s)", &name, &from, &to);

  if (name[0] == ':' &&
      strcmp (name, from) == 0 &&
      strcmp (to, "") == 0)
    {
      GHashTableIter iter;
      PidData *pid_data = NULL;
      gpointer value = NULL;
      GList *list = NULL, *l;

      g_hash_table_iter_init (&iter, client_pid_data_hash);
      while (g_hash_table_iter_next (&iter, NULL, &value))
        {
          pid_data = value;

          if (pid_data->watch_bus && g_str_equal (pid_data->client, name))
            list = g_list_prepend (list, pid_data);
        }

      for (l = list; l; l = l->next)
        {
          pid_data = l->data;
          g_info ("%s dropped off the bus, killing %d", pid_data->client, pid_data->pid);
          killpg (pid_data->pid, SIGINT);
        }

      g_list_free (list);

      close_update_monitors_for_sender (name);
    }
}

#define DBUS_NAME_DBUS "org.freedesktop.DBus"
#define DBUS_INTERFACE_DBUS DBUS_NAME_DBUS
#define DBUS_PATH_DBUS "/org/freedesktop/DBus"

static void
on_bus_acquired (GDBusConnection *connection,
                 const gchar     *name,
                 gpointer         user_data)
{
  GError *error = NULL;

  g_info ("Bus acquired, creating skeleton");

  g_dbus_connection_set_exit_on_close (connection, FALSE);

  update_monitors = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref);

  permission_store = xdp_dbus_permission_store_proxy_new_sync (connection,
                                                               G_DBUS_PROXY_FLAGS_NONE,
                                                               "org.freedesktop.impl.portal.PermissionStore",
                                                               "/org/freedesktop/impl/portal/PermissionStore",
                                                               NULL, NULL);

  portal = portal_flatpak_skeleton_new ();

  g_dbus_connection_signal_subscribe (connection,
                                      DBUS_NAME_DBUS,
                                      DBUS_INTERFACE_DBUS,
                                      "NameOwnerChanged",
                                      DBUS_PATH_DBUS,
                                      NULL,
                                      G_DBUS_SIGNAL_FLAGS_NONE,
                                      name_owner_changed,
                                      NULL, NULL);

  g_object_set_data_full (G_OBJECT (portal), "track-alive", GINT_TO_POINTER (42), skeleton_died_cb);

  portal_flatpak_set_version (PORTAL_FLATPAK (portal), 8);
  portal_flatpak_set_supports (PORTAL_FLATPAK (portal), supports);

  g_signal_connect (portal, "handle-spawn", G_CALLBACK (handle_spawn), NULL);
  g_signal_connect (portal, "handle-spawn-signal", G_CALLBACK (handle_spawn_signal), NULL);
  g_signal_connect (portal, "handle-create-update-monitor", G_CALLBACK (handle_create_update_monitor), NULL);

  g_signal_connect (portal, "g-authorize-method", G_CALLBACK (authorize_method_handler), NULL);

  if (!g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (portal),
                                         connection,
                                         FLATPAK_PORTAL_PATH,
                                         &error))
    {
      g_warning ("error: %s", error->message);
      g_error_free (error);
    }
}

static void
on_name_acquired (GDBusConnection *connection,
                  const gchar     *name,
                  gpointer         user_data)
{
  g_info ("Name acquired");
}

static void
on_name_lost (GDBusConnection *connection,
              const gchar     *name,
              gpointer         user_data)
{
  g_info ("Name lost");
  unref_skeleton_in_timeout ();
}

static void
binary_file_changed_cb (GFileMonitor     *file_monitor,
                        GFile            *file,
                        GFile            *other_file,
                        GFileMonitorEvent event_type,
                        gpointer          data)
{
  static gboolean got_it = FALSE;

  if (!got_it)
    {
      g_info ("binary file changed");
      unref_skeleton_in_timeout ();
    }

  got_it = TRUE;
}


static void
message_handler (const gchar   *log_domain,
                 GLogLevelFlags log_level,
                 const gchar   *message,
                 gpointer       user_data)
{
  /* Make this look like normal console output */
  if (log_level & (G_LOG_LEVEL_DEBUG | G_LOG_LEVEL_INFO))
    g_printerr ("F: %s\n", message);
  else
    g_printerr ("%s: %s\n", g_get_prgname (), message);
}

int
main (int    argc,
      char **argv)
{
  gchar exe_path[PATH_MAX + 1];
  ssize_t exe_path_len;
  gboolean replace;
  gboolean show_version;
  g_autoptr(GOptionContext) context = NULL;
  GBusNameOwnerFlags flags;
  g_autoptr(GError) error = NULL;
  const GOptionEntry options[] = {
    { "replace", 'r', 0, G_OPTION_ARG_NONE, &replace,  "Replace old daemon.", NULL },
    { "verbose", 'v', 0, G_OPTION_ARG_NONE, &opt_verbose,  "Enable debug output.", NULL },
    { "version", 0, 0, G_OPTION_ARG_NONE, &show_version, "Show program version.", NULL},
    { "no-idle-exit", 0, 0, G_OPTION_ARG_NONE, &no_idle_exit,  "Don't exit when idle.", NULL },
    { "poll-timeout", 0, 0, G_OPTION_ARG_INT, &opt_poll_timeout,  "Delay in seconds between polls for updates.", NULL },
    { "poll-when-metered", 0, 0, G_OPTION_ARG_NONE, &opt_poll_when_metered, "Whether to check for updates on metered networks",  NULL },
    { NULL }
  };

  setlocale (LC_ALL, "");

  g_setenv ("GIO_USE_VFS", "local", TRUE);

  g_set_prgname (argv[0]);

  g_log_set_handler (G_LOG_DOMAIN, G_LOG_LEVEL_MESSAGE, message_handler, NULL);

  if (argc >= 4 && strcmp (argv[1], "--update") == 0)
    {
      return do_update_child_process (argv[2], argv[3], 3);
    }

  context = g_option_context_new ("");

  replace = FALSE;
  opt_verbose = FALSE;
  show_version = FALSE;

  g_option_context_set_summary (context, "Flatpak portal");
  g_option_context_add_main_entries (context, options, GETTEXT_PACKAGE);

  if (!g_option_context_parse (context, &argc, &argv, &error))
    {
      g_printerr ("%s: %s", g_get_application_name (), error->message);
      g_printerr ("\n");
      g_printerr ("Try \"%s --help\" for more information.",
                  g_get_prgname ());
      g_printerr ("\n");
      g_option_context_free (context);
      return 1;
    }

  if (opt_poll_timeout == 0)
    opt_poll_timeout = DEFAULT_UPDATE_POLL_TIMEOUT_SEC;

  if (show_version)
    {
      g_print (PACKAGE_STRING "\n");
      return 0;
    }

  if (opt_verbose)
    g_log_set_handler (G_LOG_DOMAIN, G_LOG_LEVEL_INFO, message_handler, NULL);

  client_pid_data_hash = g_hash_table_new_full (NULL, NULL, NULL, (GDestroyNotify) pid_data_free);

  session_bus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error);
  if (session_bus == NULL)
    {
      g_printerr ("Can't find bus: %s\n", error->message);
      return 1;
    }

  exe_path_len = readlink ("/proc/self/exe", exe_path, sizeof (exe_path) - 1);
  if (exe_path_len > 0 && (size_t) exe_path_len < sizeof (exe_path))
    {
      exe_path[exe_path_len] = 0;
      GFileMonitor *monitor;
      g_autoptr(GFile) exe = NULL;
      g_autoptr(GError) local_error = NULL;

      exe = g_file_new_for_path (exe_path);
      monitor =  g_file_monitor_file (exe,
                                      G_FILE_MONITOR_NONE,
                                      NULL,
                                      &local_error);
      if (monitor == NULL)
        g_warning ("Failed to set watch on %s: %s", exe_path, error->message);
      else
        g_signal_connect (monitor, "changed",
                          G_CALLBACK (binary_file_changed_cb), NULL);
    }

  flatpak_connection_track_name_owners (session_bus);

  if (flatpak_bwrap_is_unprivileged ())
    supports |= FLATPAK_SPAWN_SUPPORT_FLAGS_EXPOSE_PIDS;

  flags = G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT;
  if (replace)
    flags |= G_BUS_NAME_OWNER_FLAGS_REPLACE;

  name_owner_id = g_bus_own_name (G_BUS_TYPE_SESSION,
                                  FLATPAK_PORTAL_BUS_NAME,
                                  flags,
                                  on_bus_acquired,
                                  on_name_acquired,
                                  on_name_lost,
                                  NULL,
                                  NULL);

  load_installed_portals (opt_verbose);

  /* Ensure we don't idle exit */
  schedule_idle_callback ();

  network_monitor = g_network_monitor_get_default ();

  main_loop = g_main_loop_new (NULL, FALSE);
  g_main_loop_run (main_loop);

  return 0;
}

===== ./portal/org.freedesktop.portal.Flatpak.service.in =====
[D-BUS Service]
Name=org.freedesktop.portal.Flatpak
Exec=@libexecdir@/flatpak-portal@extraargs@
SystemdService=flatpak-portal.service

===== ./portal/flatpak-portal.h =====
/*
 * Copyright © 2018 Red Hat, Inc
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Alexander Larsson <alexl@redhat.com>
 */

#ifndef __FLATPAK_PORTAL_H__
#define __FLATPAK_PORTAL_H__

#define FLATPAK_PORTAL_BUS_NAME "org.freedesktop.portal.Flatpak"
#define FLATPAK_PORTAL_PATH "/org/freedesktop/portal/Flatpak"
#define FLATPAK_PORTAL_INTERFACE FLATPAK_PORTAL_BUS_NAME
#define FLATPAK_PORTAL_INTERFACE_UPDATE_MONITOR FLATPAK_PORTAL_BUS_NAME ".UpdateMonitor"

typedef enum {
  FLATPAK_SPAWN_FLAGS_CLEAR_ENV = 1 << 0,
  FLATPAK_SPAWN_FLAGS_LATEST_VERSION = 1 << 1,
  FLATPAK_SPAWN_FLAGS_SANDBOX = 1 << 2,
  FLATPAK_SPAWN_FLAGS_NO_NETWORK = 1 << 3,
  FLATPAK_SPAWN_FLAGS_WATCH_BUS = 1 << 4,
  FLATPAK_SPAWN_FLAGS_EXPOSE_PIDS = 1 << 5,
  FLATPAK_SPAWN_FLAGS_NOTIFY_START = 1 << 6,
  FLATPAK_SPAWN_FLAGS_SHARE_PIDS = 1 << 7,
  FLATPAK_SPAWN_FLAGS_EMPTY_APP = 1 << 8,
  FLATPAK_SPAWN_FLAGS_NONE = 0
} FlatpakSpawnFlags;

typedef enum {
  FLATPAK_SPAWN_SANDBOX_FLAGS_SHARE_DISPLAY = 1 << 0,
  FLATPAK_SPAWN_SANDBOX_FLAGS_SHARE_SOUND = 1 << 1,
  FLATPAK_SPAWN_SANDBOX_FLAGS_SHARE_GPU = 1 << 2,
  FLATPAK_SPAWN_SANDBOX_FLAGS_ALLOW_DBUS = 1 << 3,
  FLATPAK_SPAWN_SANDBOX_FLAGS_ALLOW_A11Y = 1 << 4,
  FLATPAK_SPAWN_SANDBOX_FLAGS_SHARE_INPUT = 1 << 5,
  FLATPAK_SPAWN_SANDBOX_FLAGS_SHARE_USB = 1 << 6,
  FLATPAK_SPAWN_SANDBOX_FLAGS_SHARE_KVM = 1 << 7,
  FLATPAK_SPAWN_SANDBOX_FLAGS_SHARE_SHM = 1 << 8,
  FLATPAK_SPAWN_SANDBOX_FLAGS_SHARE_DEVICES = 1 << 9,
  FLATPAK_SPAWN_SANDBOX_FLAGS_NONE = 0
} FlatpakSpawnSandboxFlags;


typedef enum {
  FLATPAK_SPAWN_SUPPORT_FLAGS_EXPOSE_PIDS = 1 << 0,
  FLATPAK_SPAWN_SUPPORT_FLAGS_NONE = 0
} FlatpakSpawnSupportFlags;

/* The same flag is reused: this feature is available under the same
 * circumstances */
#define FLATPAK_SPAWN_SUPPORT_FLAGS_SHARE_PIDS FLATPAK_SPAWN_SUPPORT_FLAGS_EXPOSE_PIDS

#define FLATPAK_SPAWN_FLAGS_ALL (FLATPAK_SPAWN_FLAGS_CLEAR_ENV | \
                                 FLATPAK_SPAWN_FLAGS_LATEST_VERSION | \
                                 FLATPAK_SPAWN_FLAGS_SANDBOX | \
                                 FLATPAK_SPAWN_FLAGS_NO_NETWORK | \
                                 FLATPAK_SPAWN_FLAGS_WATCH_BUS | \
                                 FLATPAK_SPAWN_FLAGS_EXPOSE_PIDS | \
                                 FLATPAK_SPAWN_FLAGS_NOTIFY_START | \
                                 FLATPAK_SPAWN_FLAGS_SHARE_PIDS | \
                                 FLATPAK_SPAWN_FLAGS_EMPTY_APP)

#define FLATPAK_SPAWN_SANDBOX_FLAGS_ALL (FLATPAK_SPAWN_SANDBOX_FLAGS_SHARE_DISPLAY | \
                                         FLATPAK_SPAWN_SANDBOX_FLAGS_SHARE_SOUND | \
                                         FLATPAK_SPAWN_SANDBOX_FLAGS_SHARE_GPU | \
                                         FLATPAK_SPAWN_SANDBOX_FLAGS_ALLOW_DBUS | \
                                         FLATPAK_SPAWN_SANDBOX_FLAGS_ALLOW_A11Y | \
                                         FLATPAK_SPAWN_SANDBOX_FLAGS_SHARE_INPUT | \
                                         FLATPAK_SPAWN_SANDBOX_FLAGS_SHARE_USB | \
                                         FLATPAK_SPAWN_SANDBOX_FLAGS_SHARE_KVM | \
                                         FLATPAK_SPAWN_SANDBOX_FLAGS_SHARE_SHM | \
                                         FLATPAK_SPAWN_SANDBOX_FLAGS_SHARE_DEVICES)

#endif /* __FLATPAK_PORTAL_H__ */

===== ./portal/meson.build =====
# Copyright 2022 Collabora Ltd.
# SPDX-License-Identifier: LGPL-2.1-or-later

permission_gdbus = gnome.gdbus_codegen(
  'flatpak-permission-dbus',
  sources: [
    '../data/org.freedesktop.impl.portal.PermissionStore.xml',
  ],
  interface_prefix : 'org.freedesktop.impl.portal',
  namespace : 'XdpDbus',
)

portal_gdbus = gnome.gdbus_codegen(
  'flatpak-portal-dbus',
  sources: [
    '../data/org.freedesktop.portal.Flatpak.xml',
  ],
  interface_prefix : 'org.freedesktop.portal',
  namespace : 'Portal',
)

executable(
  'flatpak-portal',
  dependencies : [
    threads_dep,
    base_deps,
    json_glib_dep,
    libflatpak_common_base_dep,
    libflatpak_common_dep,
    libglnx_dep,
    libostree_dep,
  ],
  include_directories : [
    include_directories('.'),
  ],
  install : true,
  install_dir : get_option('libexecdir'),
  sources : [
    'flatpak-portal.c',
    'flatpak-portal-app-info.c',
    'portal-impl.c',
    '../common/flatpak-portal-error.c',
  ] + permission_gdbus + portal_gdbus,
)

configure_file(
  input : 'flatpak-portal.service.in',
  output : 'flatpak-portal.service',
  configuration : service_conf_data,
  install_dir : get_option('systemduserunitdir'),
)

configure_file(
  input : 'org.freedesktop.portal.Flatpak.service.in',
  output : 'org.freedesktop.portal.Flatpak.service',
  configuration : service_conf_data,
  install_dir : dbus_service_dir,
)

===== ./portal/portal-impl.c =====
/* vi:set et sw=2 sts=2 cin cino=t0,f0,(0,{s,>2s,n-s,^-s,e-s:
 * Copyright © 2016 Red Hat, Inc
 *
 * This program 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 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Alexander Larsson <alexl@redhat.com>
 *       Matthias Clasen <mclasen@redhat.com>
 */

#include "config.h"

#include "portal-impl.h"

#include <stdio.h>
#include <string.h>

#include <glib.h>
#include <gio/gio.h>

static void
portal_implementation_free (PortalImplementation *impl)
{
  g_free (impl->source);
  g_free (impl->dbus_name);
  g_strfreev (impl->interfaces);
  g_strfreev (impl->use_in);
  g_free (impl);
}

G_DEFINE_AUTOPTR_CLEANUP_FUNC(PortalImplementation, portal_implementation_free)

static GList *implementations = NULL;

static gboolean
register_portal (const char *path, gboolean opt_verbose, GError **error)
{
  g_autoptr(GKeyFile) keyfile = g_key_file_new ();
  g_autoptr(PortalImplementation) impl = g_new0 (PortalImplementation, 1);
  int i;

  g_info ("loading %s", path);

  if (!g_key_file_load_from_file (keyfile, path, G_KEY_FILE_NONE, error))
    return FALSE;

  impl->source = g_path_get_basename (path);
  impl->dbus_name = g_key_file_get_string (keyfile, "portal", "DBusName", error);
  if (impl->dbus_name == NULL)
    return FALSE;
  if (!g_dbus_is_name (impl->dbus_name))
    {
      g_set_error (error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_INVALID_VALUE,
                   "Not a valid bus name: %s", impl->dbus_name);
      return FALSE;
    }

  impl->interfaces = g_key_file_get_string_list (keyfile, "portal", "Interfaces", NULL, error);
  if (impl->interfaces == NULL)
    return FALSE;
  for (i = 0; impl->interfaces[i]; i++)
    {
      if (!g_dbus_is_interface_name (impl->interfaces[i]))
        {
          g_set_error (error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_INVALID_VALUE,
                       "Not a valid interface name: %s", impl->interfaces[i]);
          return FALSE;
        }
      if (!g_str_has_prefix (impl->interfaces[i], "org.freedesktop.impl.portal."))
        {
          g_set_error (error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_INVALID_VALUE,
                       "Not a portal backend interface: %s", impl->interfaces[i]);
          return FALSE;
        }
    }

  impl->use_in = g_key_file_get_string_list (keyfile, "portal", "UseIn", NULL, error);
  if (impl->use_in == NULL)
    return FALSE;

  if (opt_verbose)
    {
      g_autofree char *uses = g_strjoinv (", ", impl->use_in);
      g_info ("portal implementation for %s", uses);
      for (i = 0; impl->interfaces[i]; i++)
        g_info ("portal implementation supports %s", impl->interfaces[i]);
    }

  implementations = g_list_prepend (implementations, impl);
  impl = NULL;

  return TRUE;
}

static gint
sort_impl_by_name (gconstpointer a,
                   gconstpointer b)
{
  const PortalImplementation *pa = a;
  const PortalImplementation *pb = b;

  return strcmp (pa->source, pb->source);
}

void
load_installed_portals (gboolean opt_verbose)
{
  const char *portal_dir;
  g_autoptr(GFile) dir = NULL;
  g_autoptr(GFileEnumerator) enumerator = NULL;

  /* We need to override this in the tests */
  portal_dir = g_getenv ("XDG_DESKTOP_PORTAL_DIR");
  if (portal_dir == NULL)
    portal_dir = DATADIR "/xdg-desktop-portal/portals";

  g_info ("load portals from %s", portal_dir);

  dir = g_file_new_for_path (portal_dir);
  enumerator = g_file_enumerate_children (dir, G_FILE_ATTRIBUTE_STANDARD_NAME, G_FILE_QUERY_INFO_NONE, NULL, NULL);

  if (enumerator == NULL)
    return;

  while (TRUE)
    {
      g_autoptr(GFileInfo) info = g_file_enumerator_next_file (enumerator, NULL, NULL);
      g_autoptr(GFile) child = NULL;
      g_autofree char *path = NULL;
      const char *name;
      g_autoptr(GError) error = NULL;

      if (info == NULL)
        break;

      name = g_file_info_get_name (info);

      if (!g_str_has_suffix (name, ".portal"))
        continue;

      child = g_file_enumerator_get_child (enumerator, info);
      path = g_file_get_path (child);

      if (!register_portal (path, opt_verbose, &error))
        {
          g_warning ("Error loading %s: %s", path, error->message);
          continue;
        }
    }

  implementations = g_list_sort (implementations, sort_impl_by_name);
}

static gboolean
g_strv_case_contains (const gchar * const *strv,
                      const gchar         *str)
{
  for (; *strv != NULL; strv++)
    {
      if (g_ascii_strcasecmp (str, *strv) == 0)
        return TRUE;
    }

  return FALSE;
}

PortalImplementation *
find_portal_implementation (const char *interface)
{
  const char *desktops_str = g_getenv ("XDG_CURRENT_DESKTOP");
  g_auto(GStrv) desktops = NULL;
  int i;
  GList *l;

  if (desktops_str == NULL)
    desktops_str = "";

  desktops = g_strsplit (desktops_str, ":", -1);

  for (i = 0; desktops[i] != NULL; i++)
    {
     for (l = implementations; l != NULL; l = l->next)
        {
          PortalImplementation *impl = l->data;

          if (!g_strv_contains ((const char **)impl->interfaces, interface))
            continue;

          if (g_strv_case_contains ((const char **)impl->use_in, desktops[i]))
            {
              g_info ("Using %s for %s in %s", impl->source, interface, desktops[i]);
              return impl;
            }
        }
    }

  /* Fall back to *any* installed implementation */
  for (l = implementations; l != NULL; l = l->next)
    {
      PortalImplementation *impl = l->data;

      if (!g_strv_contains ((const char **)impl->interfaces, interface))
        continue;

      g_info ("Falling back to %s for %s", impl->source, interface);
      return impl;
    }

  return NULL;
}

===== ./.codespellrc =====
[codespell]
skip = node_modules,po,subprojects
ignore-regex = .*(ratatui|Affinitized|affinitized).*
ignore-words-list = nd,ot,THUR,IST,fo,hel,bu

===== ./common/flatpak-enum-types.c.template =====
/*** BEGIN file-header ***/
#include "config.h"
#include <flatpak-utils-private.h>
#include <flatpak.h>
#include <flatpak-enum-types.h>
#include <gio/gio.h>

/*** END file-header ***/

/*** BEGIN file-production ***/
/* enumerations from "@basename@" */
/*** END file-production ***/

/*** BEGIN value-header ***/
GType
@enum_name@_get_type (void)
{
  static gsize static_g_@type@_type_id = 0;

  if (g_once_init_enter (&static_g_@type@_type_id))
    {
      static const G@Type@Value values[] = {
/*** END value-header ***/

/*** BEGIN value-production ***/
        { @VALUENAME@, "@VALUENAME@", "@valuenick@" },
/*** END value-production ***/

/*** BEGIN value-tail ***/
        { 0, NULL, NULL }
      };
      GType g_define_type_id =
        g_@type@_register_static (g_intern_static_string ("@EnumName@"), values);
      g_once_init_leave (&static_g_@type@_type_id, g_define_type_id);
    }

  return static_g_@type@_type_id;
}

/*** END value-tail ***/

===== ./common/flatpak.h =====
/*
 * Copyright © 2015 Red Hat, Inc
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Alexander Larsson <alexl@redhat.com>
 */

#ifndef __FLATPAK_H__
#define __FLATPAK_H__

#define __FLATPAK_H_INSIDE__

#include <gio/gio.h>

#include <flatpak-version-macros.h>
#include <flatpak-enum-types.h>
#include <flatpak-error.h>
#include <flatpak-portal-error.h>
#include <flatpak-ref.h>
#include <flatpak-installed-ref.h>
#include <flatpak-remote-ref.h>
#include <flatpak-related-ref.h>
#include <flatpak-bundle-ref.h>
#include <flatpak-remote.h>
#include <flatpak-installation.h>
#include <flatpak-transaction.h>
#include <flatpak-instance.h>

#undef __FLATPAK_H_INSIDE__

#endif /* __FLATPAK_H__ */

===== ./common/valgrind-private.h =====
/* -*- c -*-
   ----------------------------------------------------------------

   Notice that the following BSD-style license applies to this one
   file (valgrind.h) only.  The rest of Valgrind is licensed under the
   terms of the GNU General Public License, version 2, unless
   otherwise indicated.  See the COPYING file in the source
   distribution for details.

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

   This file is part of Valgrind, a dynamic binary instrumentation
   framework.

   Copyright (C) 2000-2017 Julian Seward.  All rights reserved.

   Redistribution and use in source and binary forms, with or without
   modification, are permitted provided that the following conditions
   are met:

   1. Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.

   2. The origin of this software must not be misrepresented; you must 
      not claim that you wrote the original software.  If you use this 
      software in a product, an acknowledgment in the product 
      documentation would be appreciated but is not required.

   3. Altered source versions must be plainly marked as such, and must
      not be misrepresented as being the original software.

   4. The name of the author may not be used to endorse or promote 
      products derived from this software without specific prior written 
      permission.

   THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
   OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
   WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
   DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
   GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
   WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

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

   Notice that the above BSD-style license applies to this one file
   (valgrind.h) only.  The entire rest of Valgrind is licensed under
   the terms of the GNU General Public License, version 2.  See the
   COPYING file in the source distribution for details.

   ---------------------------------------------------------------- 
*/


/* This file is for inclusion into client (your!) code.

   You can use these macros to manipulate and query Valgrind's 
   execution inside your own programs.

   The resulting executables will still run without Valgrind, just a
   little bit more slowly than they otherwise would, but otherwise
   unchanged.  When not running on valgrind, each client request
   consumes very few (eg. 7) instructions, so the resulting performance
   loss is negligible unless you plan to execute client requests
   millions of times per second.  Nevertheless, if that is still a
   problem, you can compile with the NVALGRIND symbol defined (gcc
   -DNVALGRIND) so that client requests are not even compiled in.  */

#ifndef __VALGRIND_H
#define __VALGRIND_H


/* ------------------------------------------------------------------ */
/* VERSION NUMBER OF VALGRIND                                         */
/* ------------------------------------------------------------------ */

/* Specify Valgrind's version number, so that user code can
   conditionally compile based on our version number.  Note that these
   were introduced at version 3.6 and so do not exist in version 3.5
   or earlier.  The recommended way to use them to check for "version
   X.Y or later" is (eg)

#if defined(__VALGRIND_MAJOR__) && defined(__VALGRIND_MINOR__)   \
    && (__VALGRIND_MAJOR__ > 3                                   \
        || (__VALGRIND_MAJOR__ == 3 && __VALGRIND_MINOR__ >= 6))
*/
#define __VALGRIND_MAJOR__    3
#define __VALGRIND_MINOR__    13


#include <stdarg.h>

/* Nb: this file might be included in a file compiled with -ansi.  So
   we can't use C++ style "//" comments nor the "asm" keyword (instead
   use "__asm__"). */

/* Derive some tags indicating what the target platform is.  Note
   that in this file we're using the compiler's CPP symbols for
   identifying architectures, which are different to the ones we use
   within the rest of Valgrind.  Note, __powerpc__ is active for both
   32 and 64-bit PPC, whereas __powerpc64__ is only active for the
   latter (on Linux, that is).

   Misc note: how to find out what's predefined in gcc by default:
   gcc -Wp,-dM somefile.c
*/
#undef PLAT_x86_darwin
#undef PLAT_amd64_darwin
#undef PLAT_x86_win32
#undef PLAT_amd64_win64
#undef PLAT_x86_linux
#undef PLAT_amd64_linux
#undef PLAT_ppc32_linux
#undef PLAT_ppc64be_linux
#undef PLAT_ppc64le_linux
#undef PLAT_arm_linux
#undef PLAT_arm64_linux
#undef PLAT_s390x_linux
#undef PLAT_mips32_linux
#undef PLAT_mips64_linux
#undef PLAT_x86_solaris
#undef PLAT_amd64_solaris


#if defined(__APPLE__) && defined(__i386__)
#  define PLAT_x86_darwin 1
#elif defined(__APPLE__) && defined(__x86_64__)
#  define PLAT_amd64_darwin 1
#elif (defined(__MINGW32__) && !defined(__MINGW64__)) \
      || defined(__CYGWIN32__) \
      || (defined(_WIN32) && defined(_M_IX86))
#  define PLAT_x86_win32 1
#elif defined(__MINGW64__) \
      || (defined(_WIN64) && defined(_M_X64))
#  define PLAT_amd64_win64 1
#elif defined(__linux__) && defined(__i386__)
#  define PLAT_x86_linux 1
#elif defined(__linux__) && defined(__x86_64__) && !defined(__ILP32__)
#  define PLAT_amd64_linux 1
#elif defined(__linux__) && defined(__powerpc__) && !defined(__powerpc64__)
#  define PLAT_ppc32_linux 1
#elif defined(__linux__) && defined(__powerpc__) && defined(__powerpc64__) && _CALL_ELF != 2
/* Big Endian uses ELF version 1 */
#  define PLAT_ppc64be_linux 1
#elif defined(__linux__) && defined(__powerpc__) && defined(__powerpc64__) && _CALL_ELF == 2
/* Little Endian uses ELF version 2 */
#  define PLAT_ppc64le_linux 1
#elif defined(__linux__) && defined(__arm__) && !defined(__aarch64__)
#  define PLAT_arm_linux 1
#elif defined(__linux__) && defined(__aarch64__) && !defined(__arm__)
#  define PLAT_arm64_linux 1
#elif defined(__linux__) && defined(__s390__) && defined(__s390x__)
#  define PLAT_s390x_linux 1
#elif defined(__linux__) && defined(__mips__) && (__mips==64)
#  define PLAT_mips64_linux 1
#elif defined(__linux__) && defined(__mips__) && (__mips!=64)
#  define PLAT_mips32_linux 1
#elif defined(__sun) && defined(__i386__)
#  define PLAT_x86_solaris 1
#elif defined(__sun) && defined(__x86_64__)
#  define PLAT_amd64_solaris 1
#else
/* If we're not compiling for our target platform, don't generate
   any inline asms.  */
#  if !defined(NVALGRIND)
#    define NVALGRIND 1
#  endif
#endif


/* ------------------------------------------------------------------ */
/* ARCHITECTURE SPECIFICS for SPECIAL INSTRUCTIONS.  There is nothing */
/* in here of use to end-users -- skip to the next section.           */
/* ------------------------------------------------------------------ */

/*
 * VALGRIND_DO_CLIENT_REQUEST(): a statement that invokes a Valgrind client
 * request. Accepts both pointers and integers as arguments.
 *
 * VALGRIND_DO_CLIENT_REQUEST_STMT(): a statement that invokes a Valgrind
 * client request that does not return a value.

 * VALGRIND_DO_CLIENT_REQUEST_EXPR(): a C expression that invokes a Valgrind
 * client request and whose value equals the client request result.  Accepts
 * both pointers and integers as arguments.  Note that such calls are not
 * necessarily pure functions -- they may have side effects.
 */

#define VALGRIND_DO_CLIENT_REQUEST(_zzq_rlval, _zzq_default,            \
                                   _zzq_request, _zzq_arg1, _zzq_arg2,  \
                                   _zzq_arg3, _zzq_arg4, _zzq_arg5)     \
  do { (_zzq_rlval) = VALGRIND_DO_CLIENT_REQUEST_EXPR((_zzq_default),   \
                        (_zzq_request), (_zzq_arg1), (_zzq_arg2),       \
                        (_zzq_arg3), (_zzq_arg4), (_zzq_arg5)); } while (0)

#define VALGRIND_DO_CLIENT_REQUEST_STMT(_zzq_request, _zzq_arg1,        \
                           _zzq_arg2,  _zzq_arg3, _zzq_arg4, _zzq_arg5) \
  do { (void) VALGRIND_DO_CLIENT_REQUEST_EXPR(0,                        \
                    (_zzq_request), (_zzq_arg1), (_zzq_arg2),           \
                    (_zzq_arg3), (_zzq_arg4), (_zzq_arg5)); } while (0)

#if defined(NVALGRIND)

/* Define NVALGRIND to completely remove the Valgrind magic sequence
   from the compiled code (analogous to NDEBUG's effects on
   assert()) */
#define VALGRIND_DO_CLIENT_REQUEST_EXPR(                          \
        _zzq_default, _zzq_request,                               \
        _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5)    \
      (_zzq_default)

#else  /* ! NVALGRIND */

/* The following defines the magic code sequences which the JITter
   spots and handles magically.  Don't look too closely at them as
   they will rot your brain.

   The assembly code sequences for all architectures is in this one
   file.  This is because this file must be stand-alone, and we don't
   want to have multiple files.

   For VALGRIND_DO_CLIENT_REQUEST, we must ensure that the default
   value gets put in the return slot, so that everything works when
   this is executed not under Valgrind.  Args are passed in a memory
   block, and so there's no intrinsic limit to the number that could
   be passed, but it's currently five.
   
   The macro args are: 
      _zzq_rlval    result lvalue
      _zzq_default  default value (result returned when running on real CPU)
      _zzq_request  request code
      _zzq_arg1..5  request params

   The other two macros are used to support function wrapping, and are
   a lot simpler.  VALGRIND_GET_NR_CONTEXT returns the value of the
   guest's NRADDR pseudo-register and whatever other information is
   needed to safely run the call original from the wrapper: on
   ppc64-linux, the R2 value at the divert point is also needed.  This
   information is abstracted into a user-visible type, OrigFn.

   VALGRIND_CALL_NOREDIR_* behaves the same as the following on the
   guest, but guarantees that the branch instruction will not be
   redirected: x86: call *%eax, amd64: call *%rax, ppc32/ppc64:
   branch-and-link-to-r11.  VALGRIND_CALL_NOREDIR is just text, not a
   complete inline asm, since it needs to be combined with more magic
   inline asm stuff to be useful.
*/

/* ----------------- x86-{linux,darwin,solaris} ---------------- */

#if defined(PLAT_x86_linux)  ||  defined(PLAT_x86_darwin)  \
    ||  (defined(PLAT_x86_win32) && defined(__GNUC__)) \
    ||  defined(PLAT_x86_solaris)

typedef
   struct { 
      unsigned int nraddr; /* where's the code? */
   }
   OrigFn;

#define __SPECIAL_INSTRUCTION_PREAMBLE                            \
                     "roll $3,  %%edi ; roll $13, %%edi\n\t"      \
                     "roll $29, %%edi ; roll $19, %%edi\n\t"

#define VALGRIND_DO_CLIENT_REQUEST_EXPR(                          \
        _zzq_default, _zzq_request,                               \
        _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5)    \
  __extension__                                                   \
  ({volatile unsigned int _zzq_args[6];                           \
    volatile unsigned int _zzq_result;                            \
    _zzq_args[0] = (unsigned int)(_zzq_request);                  \
    _zzq_args[1] = (unsigned int)(_zzq_arg1);                     \
    _zzq_args[2] = (unsigned int)(_zzq_arg2);                     \
    _zzq_args[3] = (unsigned int)(_zzq_arg3);                     \
    _zzq_args[4] = (unsigned int)(_zzq_arg4);                     \
    _zzq_args[5] = (unsigned int)(_zzq_arg5);                     \
    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
                     /* %EDX = client_request ( %EAX ) */         \
                     "xchgl %%ebx,%%ebx"                          \
                     : "=d" (_zzq_result)                         \
                     : "a" (&_zzq_args[0]), "0" (_zzq_default)    \
                     : "cc", "memory"                             \
                    );                                            \
    _zzq_result;                                                  \
  })

#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval)                       \
  { volatile OrigFn* _zzq_orig = &(_zzq_rlval);                   \
    volatile unsigned int __addr;                                 \
    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
                     /* %EAX = guest_NRADDR */                    \
                     "xchgl %%ecx,%%ecx"                          \
                     : "=a" (__addr)                              \
                     :                                            \
                     : "cc", "memory"                             \
                    );                                            \
    _zzq_orig->nraddr = __addr;                                   \
  }

#define VALGRIND_CALL_NOREDIR_EAX                                 \
                     __SPECIAL_INSTRUCTION_PREAMBLE               \
                     /* call-noredir *%EAX */                     \
                     "xchgl %%edx,%%edx\n\t"

#define VALGRIND_VEX_INJECT_IR()                                 \
 do {                                                            \
    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE              \
                     "xchgl %%edi,%%edi\n\t"                     \
                     : : : "cc", "memory"                        \
                    );                                           \
 } while (0)

#endif /* PLAT_x86_linux || PLAT_x86_darwin || (PLAT_x86_win32 && __GNUC__)
          || PLAT_x86_solaris */

/* ------------------------- x86-Win32 ------------------------- */

#if defined(PLAT_x86_win32) && !defined(__GNUC__)

typedef
   struct { 
      unsigned int nraddr; /* where's the code? */
   }
   OrigFn;

#if defined(_MSC_VER)

#define __SPECIAL_INSTRUCTION_PREAMBLE                            \
                     __asm rol edi, 3  __asm rol edi, 13          \
                     __asm rol edi, 29 __asm rol edi, 19

#define VALGRIND_DO_CLIENT_REQUEST_EXPR(                          \
        _zzq_default, _zzq_request,                               \
        _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5)    \
    valgrind_do_client_request_expr((uintptr_t)(_zzq_default),    \
        (uintptr_t)(_zzq_request), (uintptr_t)(_zzq_arg1),        \
        (uintptr_t)(_zzq_arg2), (uintptr_t)(_zzq_arg3),           \
        (uintptr_t)(_zzq_arg4), (uintptr_t)(_zzq_arg5))

static __inline uintptr_t
valgrind_do_client_request_expr(uintptr_t _zzq_default, uintptr_t _zzq_request,
                                uintptr_t _zzq_arg1, uintptr_t _zzq_arg2,
                                uintptr_t _zzq_arg3, uintptr_t _zzq_arg4,
                                uintptr_t _zzq_arg5)
{
    volatile uintptr_t _zzq_args[6];
    volatile unsigned int _zzq_result;
    _zzq_args[0] = (uintptr_t)(_zzq_request);
    _zzq_args[1] = (uintptr_t)(_zzq_arg1);
    _zzq_args[2] = (uintptr_t)(_zzq_arg2);
    _zzq_args[3] = (uintptr_t)(_zzq_arg3);
    _zzq_args[4] = (uintptr_t)(_zzq_arg4);
    _zzq_args[5] = (uintptr_t)(_zzq_arg5);
    __asm { __asm lea eax, _zzq_args __asm mov edx, _zzq_default
            __SPECIAL_INSTRUCTION_PREAMBLE
            /* %EDX = client_request ( %EAX ) */
            __asm xchg ebx,ebx
            __asm mov _zzq_result, edx
    }
    return _zzq_result;
}

#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval)                       \
  { volatile OrigFn* _zzq_orig = &(_zzq_rlval);                   \
    volatile unsigned int __addr;                                 \
    __asm { __SPECIAL_INSTRUCTION_PREAMBLE                        \
            /* %EAX = guest_NRADDR */                             \
            __asm xchg ecx,ecx                                    \
            __asm mov __addr, eax                                 \
    }                                                             \
    _zzq_orig->nraddr = __addr;                                   \
  }

#define VALGRIND_CALL_NOREDIR_EAX ERROR

#define VALGRIND_VEX_INJECT_IR()                                 \
 do {                                                            \
    __asm { __SPECIAL_INSTRUCTION_PREAMBLE                       \
            __asm xchg edi,edi                                   \
    }                                                            \
 } while (0)

#else
#error Unsupported compiler.
#endif

#endif /* PLAT_x86_win32 */

/* ----------------- amd64-{linux,darwin,solaris} --------------- */

#if defined(PLAT_amd64_linux)  ||  defined(PLAT_amd64_darwin) \
    ||  defined(PLAT_amd64_solaris) \
    ||  (defined(PLAT_amd64_win64) && defined(__GNUC__))

typedef
   struct { 
      unsigned long int nraddr; /* where's the code? */
   }
   OrigFn;

#define __SPECIAL_INSTRUCTION_PREAMBLE                            \
                     "rolq $3,  %%rdi ; rolq $13, %%rdi\n\t"      \
                     "rolq $61, %%rdi ; rolq $51, %%rdi\n\t"

#define VALGRIND_DO_CLIENT_REQUEST_EXPR(                          \
        _zzq_default, _zzq_request,                               \
        _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5)    \
    __extension__                                                 \
    ({ volatile unsigned long int _zzq_args[6];                   \
    volatile unsigned long int _zzq_result;                       \
    _zzq_args[0] = (unsigned long int)(_zzq_request);             \
    _zzq_args[1] = (unsigned long int)(_zzq_arg1);                \
    _zzq_args[2] = (unsigned long int)(_zzq_arg2);                \
    _zzq_args[3] = (unsigned long int)(_zzq_arg3);                \
    _zzq_args[4] = (unsigned long int)(_zzq_arg4);                \
    _zzq_args[5] = (unsigned long int)(_zzq_arg5);                \
    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
                     /* %RDX = client_request ( %RAX ) */         \
                     "xchgq %%rbx,%%rbx"                          \
                     : "=d" (_zzq_result)                         \
                     : "a" (&_zzq_args[0]), "0" (_zzq_default)    \
                     : "cc", "memory"                             \
                    );                                            \
    _zzq_result;                                                  \
    })

#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval)                       \
  { volatile OrigFn* _zzq_orig = &(_zzq_rlval);                   \
    volatile unsigned long int __addr;                            \
    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
                     /* %RAX = guest_NRADDR */                    \
                     "xchgq %%rcx,%%rcx"                          \
                     : "=a" (__addr)                              \
                     :                                            \
                     : "cc", "memory"                             \
                    );                                            \
    _zzq_orig->nraddr = __addr;                                   \
  }

#define VALGRIND_CALL_NOREDIR_RAX                                 \
                     __SPECIAL_INSTRUCTION_PREAMBLE               \
                     /* call-noredir *%RAX */                     \
                     "xchgq %%rdx,%%rdx\n\t"

#define VALGRIND_VEX_INJECT_IR()                                 \
 do {                                                            \
    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE              \
                     "xchgq %%rdi,%%rdi\n\t"                     \
                     : : : "cc", "memory"                        \
                    );                                           \
 } while (0)

#endif /* PLAT_amd64_linux || PLAT_amd64_darwin || PLAT_amd64_solaris */

/* ------------------------- amd64-Win64 ------------------------- */

#if defined(PLAT_amd64_win64) && !defined(__GNUC__)

#error Unsupported compiler.

#endif /* PLAT_amd64_win64 */

/* ------------------------ ppc32-linux ------------------------ */

#if defined(PLAT_ppc32_linux)

typedef
   struct { 
      unsigned int nraddr; /* where's the code? */
   }
   OrigFn;

#define __SPECIAL_INSTRUCTION_PREAMBLE                            \
                    "rlwinm 0,0,3,0,31  ; rlwinm 0,0,13,0,31\n\t" \
                    "rlwinm 0,0,29,0,31 ; rlwinm 0,0,19,0,31\n\t"

#define VALGRIND_DO_CLIENT_REQUEST_EXPR(                          \
        _zzq_default, _zzq_request,                               \
        _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5)    \
                                                                  \
    __extension__                                                 \
  ({         unsigned int  _zzq_args[6];                          \
             unsigned int  _zzq_result;                           \
             unsigned int* _zzq_ptr;                              \
    _zzq_args[0] = (unsigned int)(_zzq_request);                  \
    _zzq_args[1] = (unsigned int)(_zzq_arg1);                     \
    _zzq_args[2] = (unsigned int)(_zzq_arg2);                     \
    _zzq_args[3] = (unsigned int)(_zzq_arg3);                     \
    _zzq_args[4] = (unsigned int)(_zzq_arg4);                     \
    _zzq_args[5] = (unsigned int)(_zzq_arg5);                     \
    _zzq_ptr = _zzq_args;                                         \
    __asm__ volatile("mr 3,%1\n\t" /*default*/                    \
                     "mr 4,%2\n\t" /*ptr*/                        \
                     __SPECIAL_INSTRUCTION_PREAMBLE               \
                     /* %R3 = client_request ( %R4 ) */           \
                     "or 1,1,1\n\t"                               \
                     "mr %0,3"     /*result*/                     \
                     : "=b" (_zzq_result)                         \
                     : "b" (_zzq_default), "b" (_zzq_ptr)         \
                     : "cc", "memory", "r3", "r4");               \
    _zzq_result;                                                  \
    })

#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval)                       \
  { volatile OrigFn* _zzq_orig = &(_zzq_rlval);                   \
    unsigned int __addr;                                          \
    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
                     /* %R3 = guest_NRADDR */                     \
                     "or 2,2,2\n\t"                               \
                     "mr %0,3"                                    \
                     : "=b" (__addr)                              \
                     :                                            \
                     : "cc", "memory", "r3"                       \
                    );                                            \
    _zzq_orig->nraddr = __addr;                                   \
  }

#define VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                   \
                     __SPECIAL_INSTRUCTION_PREAMBLE               \
                     /* branch-and-link-to-noredir *%R11 */       \
                     "or 3,3,3\n\t"

#define VALGRIND_VEX_INJECT_IR()                                 \
 do {                                                            \
    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE              \
                     "or 5,5,5\n\t"                              \
                    );                                           \
 } while (0)

#endif /* PLAT_ppc32_linux */

/* ------------------------ ppc64-linux ------------------------ */

#if defined(PLAT_ppc64be_linux)

typedef
   struct { 
      unsigned long int nraddr; /* where's the code? */
      unsigned long int r2;  /* what tocptr do we need? */
   }
   OrigFn;

#define __SPECIAL_INSTRUCTION_PREAMBLE                            \
                     "rotldi 0,0,3  ; rotldi 0,0,13\n\t"          \
                     "rotldi 0,0,61 ; rotldi 0,0,51\n\t"

#define VALGRIND_DO_CLIENT_REQUEST_EXPR(                          \
        _zzq_default, _zzq_request,                               \
        _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5)    \
                                                                  \
  __extension__                                                   \
  ({         unsigned long int  _zzq_args[6];                     \
             unsigned long int  _zzq_result;                      \
             unsigned long int* _zzq_ptr;                         \
    _zzq_args[0] = (unsigned long int)(_zzq_request);             \
    _zzq_args[1] = (unsigned long int)(_zzq_arg1);                \
    _zzq_args[2] = (unsigned long int)(_zzq_arg2);                \
    _zzq_args[3] = (unsigned long int)(_zzq_arg3);                \
    _zzq_args[4] = (unsigned long int)(_zzq_arg4);                \
    _zzq_args[5] = (unsigned long int)(_zzq_arg5);                \
    _zzq_ptr = _zzq_args;                                         \
    __asm__ volatile("mr 3,%1\n\t" /*default*/                    \
                     "mr 4,%2\n\t" /*ptr*/                        \
                     __SPECIAL_INSTRUCTION_PREAMBLE               \
                     /* %R3 = client_request ( %R4 ) */           \
                     "or 1,1,1\n\t"                               \
                     "mr %0,3"     /*result*/                     \
                     : "=b" (_zzq_result)                         \
                     : "b" (_zzq_default), "b" (_zzq_ptr)         \
                     : "cc", "memory", "r3", "r4");               \
    _zzq_result;                                                  \
  })

#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval)                       \
  { volatile OrigFn* _zzq_orig = &(_zzq_rlval);                   \
    unsigned long int __addr;                                     \
    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
                     /* %R3 = guest_NRADDR */                     \
                     "or 2,2,2\n\t"                               \
                     "mr %0,3"                                    \
                     : "=b" (__addr)                              \
                     :                                            \
                     : "cc", "memory", "r3"                       \
                    );                                            \
    _zzq_orig->nraddr = __addr;                                   \
    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
                     /* %R3 = guest_NRADDR_GPR2 */                \
                     "or 4,4,4\n\t"                               \
                     "mr %0,3"                                    \
                     : "=b" (__addr)                              \
                     :                                            \
                     : "cc", "memory", "r3"                       \
                    );                                            \
    _zzq_orig->r2 = __addr;                                       \
  }

#define VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                   \
                     __SPECIAL_INSTRUCTION_PREAMBLE               \
                     /* branch-and-link-to-noredir *%R11 */       \
                     "or 3,3,3\n\t"

#define VALGRIND_VEX_INJECT_IR()                                 \
 do {                                                            \
    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE              \
                     "or 5,5,5\n\t"                              \
                    );                                           \
 } while (0)

#endif /* PLAT_ppc64be_linux */

#if defined(PLAT_ppc64le_linux)

typedef
   struct {
      unsigned long int nraddr; /* where's the code? */
      unsigned long int r2;     /* what tocptr do we need? */
   }
   OrigFn;

#define __SPECIAL_INSTRUCTION_PREAMBLE                            \
                     "rotldi 0,0,3  ; rotldi 0,0,13\n\t"          \
                     "rotldi 0,0,61 ; rotldi 0,0,51\n\t"

#define VALGRIND_DO_CLIENT_REQUEST_EXPR(                          \
        _zzq_default, _zzq_request,                               \
        _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5)    \
                                                                  \
  __extension__                                                   \
  ({         unsigned long int  _zzq_args[6];                     \
             unsigned long int  _zzq_result;                      \
             unsigned long int* _zzq_ptr;                         \
    _zzq_args[0] = (unsigned long int)(_zzq_request);             \
    _zzq_args[1] = (unsigned long int)(_zzq_arg1);                \
    _zzq_args[2] = (unsigned long int)(_zzq_arg2);                \
    _zzq_args[3] = (unsigned long int)(_zzq_arg3);                \
    _zzq_args[4] = (unsigned long int)(_zzq_arg4);                \
    _zzq_args[5] = (unsigned long int)(_zzq_arg5);                \
    _zzq_ptr = _zzq_args;                                         \
    __asm__ volatile("mr 3,%1\n\t" /*default*/                    \
                     "mr 4,%2\n\t" /*ptr*/                        \
                     __SPECIAL_INSTRUCTION_PREAMBLE               \
                     /* %R3 = client_request ( %R4 ) */           \
                     "or 1,1,1\n\t"                               \
                     "mr %0,3"     /*result*/                     \
                     : "=b" (_zzq_result)                         \
                     : "b" (_zzq_default), "b" (_zzq_ptr)         \
                     : "cc", "memory", "r3", "r4");               \
    _zzq_result;                                                  \
  })

#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval)                       \
  { volatile OrigFn* _zzq_orig = &(_zzq_rlval);                   \
    unsigned long int __addr;                                     \
    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
                     /* %R3 = guest_NRADDR */                     \
                     "or 2,2,2\n\t"                               \
                     "mr %0,3"                                    \
                     : "=b" (__addr)                              \
                     :                                            \
                     : "cc", "memory", "r3"                       \
                    );                                            \
    _zzq_orig->nraddr = __addr;                                   \
    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
                     /* %R3 = guest_NRADDR_GPR2 */                \
                     "or 4,4,4\n\t"                               \
                     "mr %0,3"                                    \
                     : "=b" (__addr)                              \
                     :                                            \
                     : "cc", "memory", "r3"                       \
                    );                                            \
    _zzq_orig->r2 = __addr;                                       \
  }

#define VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R12                   \
                     __SPECIAL_INSTRUCTION_PREAMBLE               \
                     /* branch-and-link-to-noredir *%R12 */       \
                     "or 3,3,3\n\t"

#define VALGRIND_VEX_INJECT_IR()                                 \
 do {                                                            \
    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE              \
                     "or 5,5,5\n\t"                              \
                    );                                           \
 } while (0)

#endif /* PLAT_ppc64le_linux */

/* ------------------------- arm-linux ------------------------- */

#if defined(PLAT_arm_linux)

typedef
   struct { 
      unsigned int nraddr; /* where's the code? */
   }
   OrigFn;

#define __SPECIAL_INSTRUCTION_PREAMBLE                            \
            "mov r12, r12, ror #3  ; mov r12, r12, ror #13 \n\t"  \
            "mov r12, r12, ror #29 ; mov r12, r12, ror #19 \n\t"

#define VALGRIND_DO_CLIENT_REQUEST_EXPR(                          \
        _zzq_default, _zzq_request,                               \
        _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5)    \
                                                                  \
  __extension__                                                   \
  ({volatile unsigned int  _zzq_args[6];                          \
    volatile unsigned int  _zzq_result;                           \
    _zzq_args[0] = (unsigned int)(_zzq_request);                  \
    _zzq_args[1] = (unsigned int)(_zzq_arg1);                     \
    _zzq_args[2] = (unsigned int)(_zzq_arg2);                     \
    _zzq_args[3] = (unsigned int)(_zzq_arg3);                     \
    _zzq_args[4] = (unsigned int)(_zzq_arg4);                     \
    _zzq_args[5] = (unsigned int)(_zzq_arg5);                     \
    __asm__ volatile("mov r3, %1\n\t" /*default*/                 \
                     "mov r4, %2\n\t" /*ptr*/                     \
                     __SPECIAL_INSTRUCTION_PREAMBLE               \
                     /* R3 = client_request ( R4 ) */             \
                     "orr r10, r10, r10\n\t"                      \
                     "mov %0, r3"     /*result*/                  \
                     : "=r" (_zzq_result)                         \
                     : "r" (_zzq_default), "r" (&_zzq_args[0])    \
                     : "cc","memory", "r3", "r4");                \
    _zzq_result;                                                  \
  })

#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval)                       \
  { volatile OrigFn* _zzq_orig = &(_zzq_rlval);                   \
    unsigned int __addr;                                          \
    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
                     /* R3 = guest_NRADDR */                      \
                     "orr r11, r11, r11\n\t"                      \
                     "mov %0, r3"                                 \
                     : "=r" (__addr)                              \
                     :                                            \
                     : "cc", "memory", "r3"                       \
                    );                                            \
    _zzq_orig->nraddr = __addr;                                   \
  }

#define VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4                    \
                     __SPECIAL_INSTRUCTION_PREAMBLE               \
                     /* branch-and-link-to-noredir *%R4 */        \
                     "orr r12, r12, r12\n\t"

#define VALGRIND_VEX_INJECT_IR()                                 \
 do {                                                            \
    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE              \
                     "orr r9, r9, r9\n\t"                        \
                     : : : "cc", "memory"                        \
                    );                                           \
 } while (0)

#endif /* PLAT_arm_linux */

/* ------------------------ arm64-linux ------------------------- */

#if defined(PLAT_arm64_linux)

typedef
   struct { 
      unsigned long int nraddr; /* where's the code? */
   }
   OrigFn;

#define __SPECIAL_INSTRUCTION_PREAMBLE                            \
            "ror x12, x12, #3  ;  ror x12, x12, #13 \n\t"         \
            "ror x12, x12, #51 ;  ror x12, x12, #61 \n\t"

#define VALGRIND_DO_CLIENT_REQUEST_EXPR(                          \
        _zzq_default, _zzq_request,                               \
        _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5)    \
                                                                  \
  __extension__                                                   \
  ({volatile unsigned long int  _zzq_args[6];                     \
    volatile unsigned long int  _zzq_result;                      \
    _zzq_args[0] = (unsigned long int)(_zzq_request);             \
    _zzq_args[1] = (unsigned long int)(_zzq_arg1);                \
    _zzq_args[2] = (unsigned long int)(_zzq_arg2);                \
    _zzq_args[3] = (unsigned long int)(_zzq_arg3);                \
    _zzq_args[4] = (unsigned long int)(_zzq_arg4);                \
    _zzq_args[5] = (unsigned long int)(_zzq_arg5);                \
    __asm__ volatile("mov x3, %1\n\t" /*default*/                 \
                     "mov x4, %2\n\t" /*ptr*/                     \
                     __SPECIAL_INSTRUCTION_PREAMBLE               \
                     /* X3 = client_request ( X4 ) */             \
                     "orr x10, x10, x10\n\t"                      \
                     "mov %0, x3"     /*result*/                  \
                     : "=r" (_zzq_result)                         \
                     : "r" ((unsigned long int)(_zzq_default)),   \
                       "r" (&_zzq_args[0])                        \
                     : "cc","memory", "x3", "x4");                \
    _zzq_result;                                                  \
  })

#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval)                       \
  { volatile OrigFn* _zzq_orig = &(_zzq_rlval);                   \
    unsigned long int __addr;                                     \
    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
                     /* X3 = guest_NRADDR */                      \
                     "orr x11, x11, x11\n\t"                      \
                     "mov %0, x3"                                 \
                     : "=r" (__addr)                              \
                     :                                            \
                     : "cc", "memory", "x3"                       \
                    );                                            \
    _zzq_orig->nraddr = __addr;                                   \
  }

#define VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_X8                    \
                     __SPECIAL_INSTRUCTION_PREAMBLE               \
                     /* branch-and-link-to-noredir X8 */          \
                     "orr x12, x12, x12\n\t"

#define VALGRIND_VEX_INJECT_IR()                                 \
 do {                                                            \
    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE              \
                     "orr x9, x9, x9\n\t"                        \
                     : : : "cc", "memory"                        \
                    );                                           \
 } while (0)

#endif /* PLAT_arm64_linux */

/* ------------------------ s390x-linux ------------------------ */

#if defined(PLAT_s390x_linux)

typedef
  struct {
     unsigned long int nraddr; /* where's the code? */
  }
  OrigFn;

/* __SPECIAL_INSTRUCTION_PREAMBLE will be used to identify Valgrind specific
 * code. This detection is implemented in platform specific toIR.c
 * (e.g. VEX/priv/guest_s390_decoder.c).
 */
#define __SPECIAL_INSTRUCTION_PREAMBLE                           \
                     "lr 15,15\n\t"                              \
                     "lr 1,1\n\t"                                \
                     "lr 2,2\n\t"                                \
                     "lr 3,3\n\t"

#define __CLIENT_REQUEST_CODE "lr 2,2\n\t"
#define __GET_NR_CONTEXT_CODE "lr 3,3\n\t"
#define __CALL_NO_REDIR_CODE  "lr 4,4\n\t"
#define __VEX_INJECT_IR_CODE  "lr 5,5\n\t"

#define VALGRIND_DO_CLIENT_REQUEST_EXPR(                         \
       _zzq_default, _zzq_request,                               \
       _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5)    \
  __extension__                                                  \
 ({volatile unsigned long int _zzq_args[6];                      \
   volatile unsigned long int _zzq_result;                       \
   _zzq_args[0] = (unsigned long int)(_zzq_request);             \
   _zzq_args[1] = (unsigned long int)(_zzq_arg1);                \
   _zzq_args[2] = (unsigned long int)(_zzq_arg2);                \
   _zzq_args[3] = (unsigned long int)(_zzq_arg3);                \
   _zzq_args[4] = (unsigned long int)(_zzq_arg4);                \
   _zzq_args[5] = (unsigned long int)(_zzq_arg5);                \
   __asm__ volatile(/* r2 = args */                              \
                    "lgr 2,%1\n\t"                               \
                    /* r3 = default */                           \
                    "lgr 3,%2\n\t"                               \
                    __SPECIAL_INSTRUCTION_PREAMBLE               \
                    __CLIENT_REQUEST_CODE                        \
                    /* results = r3 */                           \
                    "lgr %0, 3\n\t"                              \
                    : "=d" (_zzq_result)                         \
                    : "a" (&_zzq_args[0]), "0" (_zzq_default)    \
                    : "cc", "2", "3", "memory"                   \
                   );                                            \
   _zzq_result;                                                  \
 })

#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval)                      \
 { volatile OrigFn* _zzq_orig = &(_zzq_rlval);                   \
   volatile unsigned long int __addr;                            \
   __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
                    __GET_NR_CONTEXT_CODE                        \
                    "lgr %0, 3\n\t"                              \
                    : "=a" (__addr)                              \
                    :                                            \
                    : "cc", "3", "memory"                        \
                   );                                            \
   _zzq_orig->nraddr = __addr;                                   \
 }

#define VALGRIND_CALL_NOREDIR_R1                                 \
                    __SPECIAL_INSTRUCTION_PREAMBLE               \
                    __CALL_NO_REDIR_CODE

#define VALGRIND_VEX_INJECT_IR()                                 \
 do {                                                            \
    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE              \
                     __VEX_INJECT_IR_CODE);                      \
 } while (0)

#endif /* PLAT_s390x_linux */

/* ------------------------- mips32-linux ---------------- */

#if defined(PLAT_mips32_linux)

typedef
   struct { 
      unsigned int nraddr; /* where's the code? */
   }
   OrigFn;

/* .word  0x342
 * .word  0x742
 * .word  0xC2
 * .word  0x4C2*/
#define __SPECIAL_INSTRUCTION_PREAMBLE          \
                     "srl $0, $0, 13\n\t"       \
                     "srl $0, $0, 29\n\t"       \
                     "srl $0, $0, 3\n\t"        \
                     "srl $0, $0, 19\n\t"
                    
#define VALGRIND_DO_CLIENT_REQUEST_EXPR(                          \
       _zzq_default, _zzq_request,                                \
       _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5)     \
  __extension__                                                   \
  ({ volatile unsigned int _zzq_args[6];                          \
    volatile unsigned int _zzq_result;                            \
    _zzq_args[0] = (unsigned int)(_zzq_request);                  \
    _zzq_args[1] = (unsigned int)(_zzq_arg1);                     \
    _zzq_args[2] = (unsigned int)(_zzq_arg2);                     \
    _zzq_args[3] = (unsigned int)(_zzq_arg3);                     \
    _zzq_args[4] = (unsigned int)(_zzq_arg4);                     \
    _zzq_args[5] = (unsigned int)(_zzq_arg5);                     \
        __asm__ volatile("move $11, %1\n\t" /*default*/           \
                     "move $12, %2\n\t" /*ptr*/                   \
                     __SPECIAL_INSTRUCTION_PREAMBLE               \
                     /* T3 = client_request ( T4 ) */             \
                     "or $13, $13, $13\n\t"                       \
                     "move %0, $11\n\t"     /*result*/            \
                     : "=r" (_zzq_result)                         \
                     : "r" (_zzq_default), "r" (&_zzq_args[0])    \
                     : "$11", "$12", "memory");                   \
    _zzq_result;                                                  \
  })

#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval)                       \
  { volatile OrigFn* _zzq_orig = &(_zzq_rlval);                   \
    volatile unsigned int __addr;                                 \
    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
                     /* %t9 = guest_NRADDR */                     \
                     "or $14, $14, $14\n\t"                       \
                     "move %0, $11"     /*result*/                \
                     : "=r" (__addr)                              \
                     :                                            \
                     : "$11"                                      \
                    );                                            \
    _zzq_orig->nraddr = __addr;                                   \
  }

#define VALGRIND_CALL_NOREDIR_T9                                 \
                     __SPECIAL_INSTRUCTION_PREAMBLE              \
                     /* call-noredir *%t9 */                     \
                     "or $15, $15, $15\n\t"

#define VALGRIND_VEX_INJECT_IR()                                 \
 do {                                                            \
    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE              \
                     "or $11, $11, $11\n\t"                      \
                    );                                           \
 } while (0)


#endif /* PLAT_mips32_linux */

/* ------------------------- mips64-linux ---------------- */

#if defined(PLAT_mips64_linux)

typedef
   struct {
      unsigned long nraddr; /* where's the code? */
   }
   OrigFn;

/* dsll $0,$0, 3
 * dsll $0,$0, 13
 * dsll $0,$0, 29
 * dsll $0,$0, 19*/
#define __SPECIAL_INSTRUCTION_PREAMBLE                              \
                     "dsll $0,$0, 3 ; dsll $0,$0,13\n\t"            \
                     "dsll $0,$0,29 ; dsll $0,$0,19\n\t"

#define VALGRIND_DO_CLIENT_REQUEST_EXPR(                            \
       _zzq_default, _zzq_request,                                  \
       _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5)       \
  __extension__                                                     \
  ({ volatile unsigned long int _zzq_args[6];                       \
    volatile unsigned long int _zzq_result;                         \
    _zzq_args[0] = (unsigned long int)(_zzq_request);               \
    _zzq_args[1] = (unsigned long int)(_zzq_arg1);                  \
    _zzq_args[2] = (unsigned long int)(_zzq_arg2);                  \
    _zzq_args[3] = (unsigned long int)(_zzq_arg3);                  \
    _zzq_args[4] = (unsigned long int)(_zzq_arg4);                  \
    _zzq_args[5] = (unsigned long int)(_zzq_arg5);                  \
        __asm__ volatile("move $11, %1\n\t" /*default*/             \
                         "move $12, %2\n\t" /*ptr*/                 \
                         __SPECIAL_INSTRUCTION_PREAMBLE             \
                         /* $11 = client_request ( $12 ) */         \
                         "or $13, $13, $13\n\t"                     \
                         "move %0, $11\n\t"     /*result*/          \
                         : "=r" (_zzq_result)                       \
                         : "r" (_zzq_default), "r" (&_zzq_args[0])  \
                         : "$11", "$12", "memory");                 \
    _zzq_result;                                                    \
  })

#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval)                         \
  { volatile OrigFn* _zzq_orig = &(_zzq_rlval);                     \
    volatile unsigned long int __addr;                              \
    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE                 \
                     /* $11 = guest_NRADDR */                       \
                     "or $14, $14, $14\n\t"                         \
                     "move %0, $11"     /*result*/                  \
                     : "=r" (__addr)                                \
                     :                                              \
                     : "$11");                                      \
    _zzq_orig->nraddr = __addr;                                     \
  }

#define VALGRIND_CALL_NOREDIR_T9                                    \
                     __SPECIAL_INSTRUCTION_PREAMBLE                 \
                     /* call-noredir $25 */                         \
                     "or $15, $15, $15\n\t"

#define VALGRIND_VEX_INJECT_IR()                                    \
 do {                                                               \
    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE                 \
                     "or $11, $11, $11\n\t"                         \
                    );                                              \
 } while (0)

#endif /* PLAT_mips64_linux */

/* Insert assembly code for other platforms here... */

#endif /* NVALGRIND */


/* ------------------------------------------------------------------ */
/* PLATFORM SPECIFICS for FUNCTION WRAPPING.  This is all very        */
/* ugly.  It's the least-worst tradeoff I can think of.               */
/* ------------------------------------------------------------------ */

/* This section defines magic (a.k.a appalling-hack) macros for doing
   guaranteed-no-redirection macros, so as to get from function
   wrappers to the functions they are wrapping.  The whole point is to
   construct standard call sequences, but to do the call itself with a
   special no-redirect call pseudo-instruction that the JIT
   understands and handles specially.  This section is long and
   repetitious, and I can't see a way to make it shorter.

   The naming scheme is as follows:

      CALL_FN_{W,v}_{v,W,WW,WWW,WWWW,5W,6W,7W,etc}

   'W' stands for "word" and 'v' for "void".  Hence there are
   different macros for calling arity 0, 1, 2, 3, 4, etc, functions,
   and for each, the possibility of returning a word-typed result, or
   no result.
*/

/* Use these to write the name of your wrapper.  NOTE: duplicates
   VG_WRAP_FUNCTION_Z{U,Z} in pub_tool_redir.h.  NOTE also: inserts
   the default behaviour equivalence class tag "0000" into the name.
   See pub_tool_redir.h for details -- normally you don't need to
   think about this, though. */

/* Use an extra level of macroisation so as to ensure the soname/fnname
   args are fully macro-expanded before pasting them together. */
#define VG_CONCAT4(_aa,_bb,_cc,_dd) _aa##_bb##_cc##_dd

#define I_WRAP_SONAME_FNNAME_ZU(soname,fnname)                    \
   VG_CONCAT4(_vgw00000ZU_,soname,_,fnname)

#define I_WRAP_SONAME_FNNAME_ZZ(soname,fnname)                    \
   VG_CONCAT4(_vgw00000ZZ_,soname,_,fnname)

/* Use this macro from within a wrapper function to collect the
   context (address and possibly other info) of the original function.
   Once you have that you can then use it in one of the CALL_FN_
   macros.  The type of the argument _lval is OrigFn. */
#define VALGRIND_GET_ORIG_FN(_lval)  VALGRIND_GET_NR_CONTEXT(_lval)

/* Also provide end-user facilities for function replacement, rather
   than wrapping.  A replacement function differs from a wrapper in
   that it has no way to get hold of the original function being
   called, and hence no way to call onwards to it.  In a replacement
   function, VALGRIND_GET_ORIG_FN always returns zero. */

#define I_REPLACE_SONAME_FNNAME_ZU(soname,fnname)                 \
   VG_CONCAT4(_vgr00000ZU_,soname,_,fnname)

#define I_REPLACE_SONAME_FNNAME_ZZ(soname,fnname)                 \
   VG_CONCAT4(_vgr00000ZZ_,soname,_,fnname)

/* Derivatives of the main macros below, for calling functions
   returning void. */

#define CALL_FN_v_v(fnptr)                                        \
   do { volatile unsigned long _junk;                             \
        CALL_FN_W_v(_junk,fnptr); } while (0)

#define CALL_FN_v_W(fnptr, arg1)                                  \
   do { volatile unsigned long _junk;                             \
        CALL_FN_W_W(_junk,fnptr,arg1); } while (0)

#define CALL_FN_v_WW(fnptr, arg1,arg2)                            \
   do { volatile unsigned long _junk;                             \
        CALL_FN_W_WW(_junk,fnptr,arg1,arg2); } while (0)

#define CALL_FN_v_WWW(fnptr, arg1,arg2,arg3)                      \
   do { volatile unsigned long _junk;                             \
        CALL_FN_W_WWW(_junk,fnptr,arg1,arg2,arg3); } while (0)

#define CALL_FN_v_WWWW(fnptr, arg1,arg2,arg3,arg4)                \
   do { volatile unsigned long _junk;                             \
        CALL_FN_W_WWWW(_junk,fnptr,arg1,arg2,arg3,arg4); } while (0)

#define CALL_FN_v_5W(fnptr, arg1,arg2,arg3,arg4,arg5)             \
   do { volatile unsigned long _junk;                             \
        CALL_FN_W_5W(_junk,fnptr,arg1,arg2,arg3,arg4,arg5); } while (0)

#define CALL_FN_v_6W(fnptr, arg1,arg2,arg3,arg4,arg5,arg6)        \
   do { volatile unsigned long _junk;                             \
        CALL_FN_W_6W(_junk,fnptr,arg1,arg2,arg3,arg4,arg5,arg6); } while (0)

#define CALL_FN_v_7W(fnptr, arg1,arg2,arg3,arg4,arg5,arg6,arg7)   \
   do { volatile unsigned long _junk;                             \
        CALL_FN_W_7W(_junk,fnptr,arg1,arg2,arg3,arg4,arg5,arg6,arg7); } while (0)

/* ----------------- x86-{linux,darwin,solaris} ---------------- */

#if defined(PLAT_x86_linux)  ||  defined(PLAT_x86_darwin) \
    ||  defined(PLAT_x86_solaris)

/* These regs are trashed by the hidden call.  No need to mention eax
   as gcc can already see that, plus causes gcc to bomb. */
#define __CALLER_SAVED_REGS /*"eax"*/ "ecx", "edx"

/* Macros to save and align the stack before making a function
   call and restore it afterwards as gcc may not keep the stack
   pointer aligned if it doesn't realise calls are being made
   to other functions. */

#define VALGRIND_ALIGN_STACK               \
      "movl %%esp,%%edi\n\t"               \
      "andl $0xfffffff0,%%esp\n\t"
#define VALGRIND_RESTORE_STACK             \
      "movl %%edi,%%esp\n\t"

/* These CALL_FN_ macros assume that on x86-linux, sizeof(unsigned
   long) == 4. */

#define CALL_FN_W_v(lval, orig)                                   \
   do {                                                           \
      volatile OrigFn        _orig = (orig);                      \
      volatile unsigned long _argvec[1];                          \
      volatile unsigned long _res;                                \
      _argvec[0] = (unsigned long)_orig.nraddr;                   \
      __asm__ volatile(                                           \
         VALGRIND_ALIGN_STACK                                     \
         "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
         VALGRIND_CALL_NOREDIR_EAX                                \
         VALGRIND_RESTORE_STACK                                   \
         : /*out*/   "=a" (_res)                                  \
         : /*in*/    "a" (&_argvec[0])                            \
         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi"   \
      );                                                          \
      lval = (__typeof__(lval)) _res;                             \
   } while (0)

#define CALL_FN_W_W(lval, orig, arg1)                             \
   do {                                                           \
      volatile OrigFn        _orig = (orig);                      \
      volatile unsigned long _argvec[2];                          \
      volatile unsigned long _res;                                \
      _argvec[0] = (unsigned long)_orig.nraddr;                   \
      _argvec[1] = (unsigned long)(arg1);                         \
      __asm__ volatile(                                           \
         VALGRIND_ALIGN_STACK                                     \
         "subl $12, %%esp\n\t"                                    \
         "pushl 4(%%eax)\n\t"                                     \
         "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
         VALGRIND_CALL_NOREDIR_EAX                                \
         VALGRIND_RESTORE_STACK                                   \
         : /*out*/   "=a" (_res)                                  \
         : /*in*/    "a" (&_argvec[0])                            \
         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi"   \
      );                                                          \
      lval = (__typeof__(lval)) _res;                             \
   } while (0)

#define CALL_FN_W_WW(lval, orig, arg1,arg2)                       \
   do {                                                           \
      volatile OrigFn        _orig = (orig);                      \
      volatile unsigned long _argvec[3];                          \
      volatile unsigned long _res;                                \
      _argvec[0] = (unsigned long)_orig.nraddr;                   \
      _argvec[1] = (unsigned long)(arg1);                         \
      _argvec[2] = (unsigned long)(arg2);                         \
      __asm__ volatile(                                           \
         VALGRIND_ALIGN_STACK                                     \
         "subl $8, %%esp\n\t"                                     \
         "pushl 8(%%eax)\n\t"                                     \
         "pushl 4(%%eax)\n\t"                                     \
         "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
         VALGRIND_CALL_NOREDIR_EAX                                \
         VALGRIND_RESTORE_STACK                                   \
         : /*out*/   "=a" (_res)                                  \
         : /*in*/    "a" (&_argvec[0])                            \
         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi"   \
      );                                                          \
      lval = (__typeof__(lval)) _res;                             \
   } while (0)

#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3)                 \
   do {                                                           \
      volatile OrigFn        _orig = (orig);                      \
      volatile unsigned long _argvec[4];                          \
      volatile unsigned long _res;                                \
      _argvec[0] = (unsigned long)_orig.nraddr;                   \
      _argvec[1] = (unsigned long)(arg1);                         \
      _argvec[2] = (unsigned long)(arg2);                         \
      _argvec[3] = (unsigned long)(arg3);                         \
      __asm__ volatile(                                           \
         VALGRIND_ALIGN_STACK                                     \
         "subl $4, %%esp\n\t"                                     \
         "pushl 12(%%eax)\n\t"                                    \
         "pushl 8(%%eax)\n\t"                                     \
         "pushl 4(%%eax)\n\t"                                     \
         "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
         VALGRIND_CALL_NOREDIR_EAX                                \
         VALGRIND_RESTORE_STACK                                   \
         : /*out*/   "=a" (_res)                                  \
         : /*in*/    "a" (&_argvec[0])                            \
         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi"   \
      );                                                          \
      lval = (__typeof__(lval)) _res;                             \
   } while (0)

#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4)           \
   do {                                                           \
      volatile OrigFn        _orig = (orig);                      \
      volatile unsigned long _argvec[5];                          \
      volatile unsigned long _res;                                \
      _argvec[0] = (unsigned long)_orig.nraddr;                   \
      _argvec[1] = (unsigned long)(arg1);                         \
      _argvec[2] = (unsigned long)(arg2);                         \
      _argvec[3] = (unsigned long)(arg3);                         \
      _argvec[4] = (unsigned long)(arg4);                         \
      __asm__ volatile(                                           \
         VALGRIND_ALIGN_STACK                                     \
         "pushl 16(%%eax)\n\t"                                    \
         "pushl 12(%%eax)\n\t"                                    \
         "pushl 8(%%eax)\n\t"                                     \
         "pushl 4(%%eax)\n\t"                                     \
         "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
         VALGRIND_CALL_NOREDIR_EAX                                \
         VALGRIND_RESTORE_STACK                                   \
         : /*out*/   "=a" (_res)                                  \
         : /*in*/    "a" (&_argvec[0])                            \
         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi"   \
      );                                                          \
      lval = (__typeof__(lval)) _res;                             \
   } while (0)

#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5)        \
   do {                                                           \
      volatile OrigFn        _orig = (orig);                      \
      volatile unsigned long _argvec[6];                          \
      volatile unsigned long _res;                                \
      _argvec[0] = (unsigned long)_orig.nraddr;                   \
      _argvec[1] = (unsigned long)(arg1);                         \
      _argvec[2] = (unsigned long)(arg2);                         \
      _argvec[3] = (unsigned long)(arg3);                         \
      _argvec[4] = (unsigned long)(arg4);                         \
      _argvec[5] = (unsigned long)(arg5);                         \
      __asm__ volatile(                                           \
         VALGRIND_ALIGN_STACK                                     \
         "subl $12, %%esp\n\t"                                    \
         "pushl 20(%%eax)\n\t"                                    \
         "pushl 16(%%eax)\n\t"                                    \
         "pushl 12(%%eax)\n\t"                                    \
         "pushl 8(%%eax)\n\t"                                     \
         "pushl 4(%%eax)\n\t"                                     \
         "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
         VALGRIND_CALL_NOREDIR_EAX                                \
         VALGRIND_RESTORE_STACK                                   \
         : /*out*/   "=a" (_res)                                  \
         : /*in*/    "a" (&_argvec[0])                            \
         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi"   \
      );                                                          \
      lval = (__typeof__(lval)) _res;                             \
   } while (0)

#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6)   \
   do {                                                           \
      volatile OrigFn        _orig = (orig);                      \
      volatile unsigned long _argvec[7];                          \
      volatile unsigned long _res;                                \
      _argvec[0] = (unsigned long)_orig.nraddr;                   \
      _argvec[1] = (unsigned long)(arg1);                         \
      _argvec[2] = (unsigned long)(arg2);                         \
      _argvec[3] = (unsigned long)(arg3);                         \
      _argvec[4] = (unsigned long)(arg4);                         \
      _argvec[5] = (unsigned long)(arg5);                         \
      _argvec[6] = (unsigned long)(arg6);                         \
      __asm__ volatile(                                           \
         VALGRIND_ALIGN_STACK                                     \
         "subl $8, %%esp\n\t"                                     \
         "pushl 24(%%eax)\n\t"                                    \
         "pushl 20(%%eax)\n\t"                                    \
         "pushl 16(%%eax)\n\t"                                    \
         "pushl 12(%%eax)\n\t"                                    \
         "pushl 8(%%eax)\n\t"                                     \
         "pushl 4(%%eax)\n\t"                                     \
         "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
         VALGRIND_CALL_NOREDIR_EAX                                \
         VALGRIND_RESTORE_STACK                                   \
         : /*out*/   "=a" (_res)                                  \
         : /*in*/    "a" (&_argvec[0])                            \
         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi"   \
      );                                                          \
      lval = (__typeof__(lval)) _res;                             \
   } while (0)

#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
                                 arg7)                            \
   do {                                                           \
      volatile OrigFn        _orig = (orig);                      \
      volatile unsigned long _argvec[8];                          \
      volatile unsigned long _res;                                \
      _argvec[0] = (unsigned long)_orig.nraddr;                   \
      _argvec[1] = (unsigned long)(arg1);                         \
      _argvec[2] = (unsigned long)(arg2);                         \
      _argvec[3] = (unsigned long)(arg3);                         \
      _argvec[4] = (unsigned long)(arg4);                         \
      _argvec[5] = (unsigned long)(arg5);                         \
      _argvec[6] = (unsigned long)(arg6);                         \
      _argvec[7] = (unsigned long)(arg7);                         \
      __asm__ volatile(                                           \
         VALGRIND_ALIGN_STACK                                     \
         "subl $4, %%esp\n\t"                                     \
         "pushl 28(%%eax)\n\t"                                    \
         "pushl 24(%%eax)\n\t"                                    \
         "pushl 20(%%eax)\n\t"                                    \
         "pushl 16(%%eax)\n\t"                                    \
         "pushl 12(%%eax)\n\t"                                    \
         "pushl 8(%%eax)\n\t"                                     \
         "pushl 4(%%eax)\n\t"                                     \
         "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
         VALGRIND_CALL_NOREDIR_EAX                                \
         VALGRIND_RESTORE_STACK                                   \
         : /*out*/   "=a" (_res)                                  \
         : /*in*/    "a" (&_argvec[0])                            \
         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi"   \
      );                                                          \
      lval = (__typeof__(lval)) _res;                             \
   } while (0)

#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
                                 arg7,arg8)                       \
   do {                                                           \
      volatile OrigFn        _orig = (orig);                      \
      volatile unsigned long _argvec[9];                          \
      volatile unsigned long _res;                                \
      _argvec[0] = (unsigned long)_orig.nraddr;                   \
      _argvec[1] = (unsigned long)(arg1);                         \
      _argvec[2] = (unsigned long)(arg2);                         \
      _argvec[3] = (unsigned long)(arg3);                         \
      _argvec[4] = (unsigned long)(arg4);                         \
      _argvec[5] = (unsigned long)(arg5);                         \
      _argvec[6] = (unsigned long)(arg6);                         \
      _argvec[7] = (unsigned long)(arg7);                         \
      _argvec[8] = (unsigned long)(arg8);                         \
      __asm__ volatile(                                           \
         VALGRIND_ALIGN_STACK                                     \
         "pushl 32(%%eax)\n\t"                                    \
         "pushl 28(%%eax)\n\t"                                    \
         "pushl 24(%%eax)\n\t"                                    \
         "pushl 20(%%eax)\n\t"                                    \
         "pushl 16(%%eax)\n\t"                                    \
         "pushl 12(%%eax)\n\t"                                    \
         "pushl 8(%%eax)\n\t"                                     \
         "pushl 4(%%eax)\n\t"                                     \
         "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
         VALGRIND_CALL_NOREDIR_EAX                                \
         VALGRIND_RESTORE_STACK                                   \
         : /*out*/   "=a" (_res)                                  \
         : /*in*/    "a" (&_argvec[0])                            \
         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi"   \
      );                                                          \
      lval = (__typeof__(lval)) _res;                             \
   } while (0)

#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
                                 arg7,arg8,arg9)                  \
   do {                                                           \
      volatile OrigFn        _orig = (orig);                      \
      volatile unsigned long _argvec[10];                         \
      volatile unsigned long _res;                                \
      _argvec[0] = (unsigned long)_orig.nraddr;                   \
      _argvec[1] = (unsigned long)(arg1);                         \
      _argvec[2] = (unsigned long)(arg2);                         \
      _argvec[3] = (unsigned long)(arg3);                         \
      _argvec[4] = (unsigned long)(arg4);                         \
      _argvec[5] = (unsigned long)(arg5);                         \
      _argvec[6] = (unsigned long)(arg6);                         \
      _argvec[7] = (unsigned long)(arg7);                         \
      _argvec[8] = (unsigned long)(arg8);                         \
      _argvec[9] = (unsigned long)(arg9);                         \
      __asm__ volatile(                                           \
         VALGRIND_ALIGN_STACK                                     \
         "subl $12, %%esp\n\t"                                    \
         "pushl 36(%%eax)\n\t"                                    \
         "pushl 32(%%eax)\n\t"                                    \
         "pushl 28(%%eax)\n\t"                                    \
         "pushl 24(%%eax)\n\t"                                    \
         "pushl 20(%%eax)\n\t"                                    \
         "pushl 16(%%eax)\n\t"                                    \
         "pushl 12(%%eax)\n\t"                                    \
         "pushl 8(%%eax)\n\t"                                     \
         "pushl 4(%%eax)\n\t"                                     \
         "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
         VALGRIND_CALL_NOREDIR_EAX                                \
         VALGRIND_RESTORE_STACK                                   \
         : /*out*/   "=a" (_res)                                  \
         : /*in*/    "a" (&_argvec[0])                            \
         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi"   \
      );                                                          \
      lval = (__typeof__(lval)) _res;                             \
   } while (0)

#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
                                  arg7,arg8,arg9,arg10)           \
   do {                                                           \
      volatile OrigFn        _orig = (orig);                      \
      volatile unsigned long _argvec[11];                         \
      volatile unsigned long _res;                                \
      _argvec[0] = (unsigned long)_orig.nraddr;                   \
      _argvec[1] = (unsigned long)(arg1);                         \
      _argvec[2] = (unsigned long)(arg2);                         \
      _argvec[3] = (unsigned long)(arg3);                         \
      _argvec[4] = (unsigned long)(arg4);                         \
      _argvec[5] = (unsigned long)(arg5);                         \
      _argvec[6] = (unsigned long)(arg6);                         \
      _argvec[7] = (unsigned long)(arg7);                         \
      _argvec[8] = (unsigned long)(arg8);                         \
      _argvec[9] = (unsigned long)(arg9);                         \
      _argvec[10] = (unsigned long)(arg10);                       \
      __asm__ volatile(                                           \
         VALGRIND_ALIGN_STACK                                     \
         "subl $8, %%esp\n\t"                                     \
         "pushl 40(%%eax)\n\t"                                    \
         "pushl 36(%%eax)\n\t"                                    \
         "pushl 32(%%eax)\n\t"                                    \
         "pushl 28(%%eax)\n\t"                                    \
         "pushl 24(%%eax)\n\t"                                    \
         "pushl 20(%%eax)\n\t"                                    \
         "pushl 16(%%eax)\n\t"                                    \
         "pushl 12(%%eax)\n\t"                                    \
         "pushl 8(%%eax)\n\t"                                     \
         "pushl 4(%%eax)\n\t"                                     \
         "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
         VALGRIND_CALL_NOREDIR_EAX                                \
         VALGRIND_RESTORE_STACK                                   \
         : /*out*/   "=a" (_res)                                  \
         : /*in*/    "a" (&_argvec[0])                            \
         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi"   \
      );                                                          \
      lval = (__typeof__(lval)) _res;                             \
   } while (0)

#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,       \
                                  arg6,arg7,arg8,arg9,arg10,      \
                                  arg11)                          \
   do {                                                           \
      volatile OrigFn        _orig = (orig);                      \
      volatile unsigned long _argvec[12];                         \
      volatile unsigned long _res;                                \
      _argvec[0] = (unsigned long)_orig.nraddr;                   \
      _argvec[1] = (unsigned long)(arg1);                         \
      _argvec[2] = (unsigned long)(arg2);                         \
      _argvec[3] = (unsigned long)(arg3);                         \
      _argvec[4] = (unsigned long)(arg4);                         \
      _argvec[5] = (unsigned long)(arg5);                         \
      _argvec[6] = (unsigned long)(arg6);                         \
      _argvec[7] = (unsigned long)(arg7);                         \
      _argvec[8] = (unsigned long)(arg8);                         \
      _argvec[9] = (unsigned long)(arg9);                         \
      _argvec[10] = (unsigned long)(arg10);                       \
      _argvec[11] = (unsigned long)(arg11);                       \
      __asm__ volatile(                                           \
         VALGRIND_ALIGN_STACK                                     \
         "subl $4, %%esp\n\t"                                     \
         "pushl 44(%%eax)\n\t"                                    \
         "pushl 40(%%eax)\n\t"                                    \
         "pushl 36(%%eax)\n\t"                                    \
         "pushl 32(%%eax)\n\t"                                    \
         "pushl 28(%%eax)\n\t"                                    \
         "pushl 24(%%eax)\n\t"                                    \
         "pushl 20(%%eax)\n\t"                                    \
         "pushl 16(%%eax)\n\t"                                    \
         "pushl 12(%%eax)\n\t"                                    \
         "pushl 8(%%eax)\n\t"                                     \
         "pushl 4(%%eax)\n\t"                                     \
         "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
         VALGRIND_CALL_NOREDIR_EAX                                \
         VALGRIND_RESTORE_STACK                                   \
         : /*out*/   "=a" (_res)                                  \
         : /*in*/    "a" (&_argvec[0])                            \
         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi"   \
      );                                                          \
      lval = (__typeof__(lval)) _res;                             \
   } while (0)

#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,       \
                                  arg6,arg7,arg8,arg9,arg10,      \
                                  arg11,arg12)                    \
   do {                                                           \
      volatile OrigFn        _orig = (orig);                      \
      volatile unsigned long _argvec[13];                         \
      volatile unsigned long _res;                                \
      _argvec[0] = (unsigned long)_orig.nraddr;                   \
      _argvec[1] = (unsigned long)(arg1);                         \
      _argvec[2] = (unsigned long)(arg2);                         \
      _argvec[3] = (unsigned long)(arg3);                         \
      _argvec[4] = (unsigned long)(arg4);                         \
      _argvec[5] = (unsigned long)(arg5);                         \
      _argvec[6] = (unsigned long)(arg6);                         \
      _argvec[7] = (unsigned long)(arg7);                         \
      _argvec[8] = (unsigned long)(arg8);                         \
      _argvec[9] = (unsigned long)(arg9);                         \
      _argvec[10] = (unsigned long)(arg10);                       \
      _argvec[11] = (unsigned long)(arg11);                       \
      _argvec[12] = (unsigned long)(arg12);                       \
      __asm__ volatile(                                           \
         VALGRIND_ALIGN_STACK                                     \
         "pushl 48(%%eax)\n\t"                                    \
         "pushl 44(%%eax)\n\t"                                    \
         "pushl 40(%%eax)\n\t"                                    \
         "pushl 36(%%eax)\n\t"                                    \
         "pushl 32(%%eax)\n\t"                                    \
         "pushl 28(%%eax)\n\t"                                    \
         "pushl 24(%%eax)\n\t"                                    \
         "pushl 20(%%eax)\n\t"                                    \
         "pushl 16(%%eax)\n\t"                                    \
         "pushl 12(%%eax)\n\t"                                    \
         "pushl 8(%%eax)\n\t"                                     \
         "pushl 4(%%eax)\n\t"                                     \
         "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
         VALGRIND_CALL_NOREDIR_EAX                                \
         VALGRIND_RESTORE_STACK                                   \
         : /*out*/   "=a" (_res)                                  \
         : /*in*/    "a" (&_argvec[0])                            \
         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi"   \
      );                                                          \
      lval = (__typeof__(lval)) _res;                             \
   } while (0)

#endif /* PLAT_x86_linux || PLAT_x86_darwin || PLAT_x86_solaris */

/* ---------------- amd64-{linux,darwin,solaris} --------------- */

#if defined(PLAT_amd64_linux)  ||  defined(PLAT_amd64_darwin) \
    ||  defined(PLAT_amd64_solaris)

/* ARGREGS: rdi rsi rdx rcx r8 r9 (the rest on stack in R-to-L order) */

/* These regs are trashed by the hidden call. */
#define __CALLER_SAVED_REGS /*"rax",*/ "rcx", "rdx", "rsi",       \
                            "rdi", "r8", "r9", "r10", "r11"

/* This is all pretty complex.  It's so as to make stack unwinding
   work reliably.  See bug 243270.  The basic problem is the sub and
   add of 128 of %rsp in all of the following macros.  If gcc believes
   the CFA is in %rsp, then unwinding may fail, because what's at the
   CFA is not what gcc "expected" when it constructs the CFIs for the
   places where the macros are instantiated.

   But we can't just add a CFI annotation to increase the CFA offset
   by 128, to match the sub of 128 from %rsp, because we don't know
   whether gcc has chosen %rsp as the CFA at that point, or whether it
   has chosen some other register (eg, %rbp).  In the latter case,
   adding a CFI annotation to change the CFA offset is simply wrong.

   So the solution is to get hold of the CFA using
   __builtin_dwarf_cfa(), put it in a known register, and add a
   CFI annotation to say what the register is.  We choose %rbp for
   this (perhaps perversely), because:

   (1) %rbp is already subject to unwinding.  If a new register was
       chosen then the unwinder would have to unwind it in all stack
       traces, which is expensive, and

   (2) %rbp is already subject to precise exception updates in the
       JIT.  If a new register was chosen, we'd have to have precise
       exceptions for it too, which reduces performance of the
       generated code.

   However .. one extra complication.  We can't just whack the result
   of __builtin_dwarf_cfa() into %rbp and then add %rbp to the
   list of trashed registers at the end of the inline assembly
   fragments; gcc won't allow %rbp to appear in that list.  Hence
   instead we need to stash %rbp in %r15 for the duration of the asm,
   and say that %r15 is trashed instead.  gcc seems happy to go with
   that.

   Oh .. and this all needs to be conditionalised so that it is
   unchanged from before this commit, when compiled with older gccs
   that don't support __builtin_dwarf_cfa.  Furthermore, since
   this header file is freestanding, it has to be independent of
   config.h, and so the following conditionalisation cannot depend on
   configure time checks.

   Although it's not clear from
   'defined(__GNUC__) && defined(__GCC_HAVE_DWARF2_CFI_ASM)',
   this expression excludes Darwin.
   .cfi directives in Darwin assembly appear to be completely
   different and I haven't investigated how they work.

   For even more entertainment value, note we have to use the
   completely undocumented __builtin_dwarf_cfa(), which appears to
   really compute the CFA, whereas __builtin_frame_address(0) claims
   to but actually doesn't.  See
   https://bugs.kde.org/show_bug.cgi?id=243270#c47
*/
#if defined(__GNUC__) && defined(__GCC_HAVE_DWARF2_CFI_ASM)
#  define __FRAME_POINTER                                         \
      ,"r"(__builtin_dwarf_cfa())
#  define VALGRIND_CFI_PROLOGUE                                   \
      "movq %%rbp, %%r15\n\t"                                     \
      "movq %2, %%rbp\n\t"                                        \
      ".cfi_remember_state\n\t"                                   \
      ".cfi_def_cfa rbp, 0\n\t"
#  define VALGRIND_CFI_EPILOGUE                                   \
      "movq %%r15, %%rbp\n\t"                                     \
      ".cfi_restore_state\n\t"
#else
#  define __FRAME_POINTER
#  define VALGRIND_CFI_PROLOGUE
#  define VALGRIND_CFI_EPILOGUE
#endif

/* Macros to save and align the stack before making a function
   call and restore it afterwards as gcc may not keep the stack
   pointer aligned if it doesn't realise calls are being made
   to other functions. */

#define VALGRIND_ALIGN_STACK               \
      "movq %%rsp,%%r14\n\t"               \
      "andq $0xfffffffffffffff0,%%rsp\n\t"
#define VALGRIND_RESTORE_STACK             \
      "movq %%r14,%%rsp\n\t"

/* These CALL_FN_ macros assume that on amd64-linux, sizeof(unsigned
   long) == 8. */

/* NB 9 Sept 07.  There is a nasty kludge here in all these CALL_FN_
   macros.  In order not to trash the stack redzone, we need to drop
   %rsp by 128 before the hidden call, and restore afterwards.  The
   nastiness is that it is only by luck that the stack still appears
   to be unwindable during the hidden call - since then the behaviour
   of any routine using this macro does not match what the CFI data
   says.  Sigh.

   Why is this important?  Imagine that a wrapper has a stack
   allocated local, and passes to the hidden call, a pointer to it.
   Because gcc does not know about the hidden call, it may allocate
   that local in the redzone.  Unfortunately the hidden call may then
   trash it before it comes to use it.  So we must step clear of the
   redzone, for the duration of the hidden call, to make it safe.

   Probably the same problem afflicts the other redzone-style ABIs too
   (ppc64-linux); but for those, the stack is
   self describing (none of this CFI nonsense) so at least messing
   with the stack pointer doesn't give a danger of non-unwindable
   stack. */

#define CALL_FN_W_v(lval, orig)                                        \
   do {                                                                \
      volatile OrigFn        _orig = (orig);                           \
      volatile unsigned long _argvec[1];                               \
      volatile unsigned long _res;                                     \
      _argvec[0] = (unsigned long)_orig.nraddr;                        \
      __asm__ volatile(                                                \
         VALGRIND_CFI_PROLOGUE                                         \
         VALGRIND_ALIGN_STACK                                          \
         "subq $128,%%rsp\n\t"                                         \
         "movq (%%rax), %%rax\n\t"  /* target->%rax */                 \
         VALGRIND_CALL_NOREDIR_RAX                                     \
         VALGRIND_RESTORE_STACK                                        \
         VALGRIND_CFI_EPILOGUE                                         \
         : /*out*/   "=a" (_res)                                       \
         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER                 \
         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \
      );                                                               \
      lval = (__typeof__(lval)) _res;                                  \
   } while (0)

#define CALL_FN_W_W(lval, orig, arg1)                                  \
   do {                                                                \
      volatile OrigFn        _orig = (orig);                           \
      volatile unsigned long _argvec[2];                               \
      volatile unsigned long _res;                                     \
      _argvec[0] = (unsigned long)_orig.nraddr;                        \
      _argvec[1] = (unsigned long)(arg1);                              \
      __asm__ volatile(                                                \
         VALGRIND_CFI_PROLOGUE                                         \
         VALGRIND_ALIGN_STACK                                          \
         "subq $128,%%rsp\n\t"                                         \
         "movq 8(%%rax), %%rdi\n\t"                                    \
         "movq (%%rax), %%rax\n\t"  /* target->%rax */                 \
         VALGRIND_CALL_NOREDIR_RAX                                     \
         VALGRIND_RESTORE_STACK                                        \
         VALGRIND_CFI_EPILOGUE                                         \
         : /*out*/   "=a" (_res)                                       \
         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER                 \
         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \
      );                                                               \
      lval = (__typeof__(lval)) _res;                                  \
   } while (0)

#define CALL_FN_W_WW(lval, orig, arg1,arg2)                            \
   do {                                                                \
      volatile OrigFn        _orig = (orig);                           \
      volatile unsigned long _argvec[3];                               \
      volatile unsigned long _res;                                     \
      _argvec[0] = (unsigned long)_orig.nraddr;                        \
      _argvec[1] = (unsigned long)(arg1);                              \
      _argvec[2] = (unsigned long)(arg2);                              \
      __asm__ volatile(                                                \
         VALGRIND_CFI_PROLOGUE                                         \
         VALGRIND_ALIGN_STACK                                          \
         "subq $128,%%rsp\n\t"                                         \
         "movq 16(%%rax), %%rsi\n\t"                                   \
         "movq 8(%%rax), %%rdi\n\t"                                    \
         "movq (%%rax), %%rax\n\t"  /* target->%rax */                 \
         VALGRIND_CALL_NOREDIR_RAX                                     \
         VALGRIND_RESTORE_STACK                                        \
         VALGRIND_CFI_EPILOGUE                                         \
         : /*out*/   "=a" (_res)                                       \
         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER                 \
         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \
      );                                                               \
      lval = (__typeof__(lval)) _res;                                  \
   } while (0)

#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3)                      \
   do {                                                                \
      volatile OrigFn        _orig = (orig);                           \
      volatile unsigned long _argvec[4];                               \
      volatile unsigned long _res;                                     \
      _argvec[0] = (unsigned long)_orig.nraddr;                        \
      _argvec[1] = (unsigned long)(arg1);                              \
      _argvec[2] = (unsigned long)(arg2);                              \
      _argvec[3] = (unsigned long)(arg3);                              \
      __asm__ volatile(                                                \
         VALGRIND_CFI_PROLOGUE                                         \
         VALGRIND_ALIGN_STACK                                          \
         "subq $128,%%rsp\n\t"                                         \
         "movq 24(%%rax), %%rdx\n\t"                                   \
         "movq 16(%%rax), %%rsi\n\t"                                   \
         "movq 8(%%rax), %%rdi\n\t"                                    \
         "movq (%%rax), %%rax\n\t"  /* target->%rax */                 \
         VALGRIND_CALL_NOREDIR_RAX                                     \
         VALGRIND_RESTORE_STACK                                        \
         VALGRIND_CFI_EPILOGUE                                         \
         : /*out*/   "=a" (_res)                                       \
         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER                 \
         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \
      );                                                               \
      lval = (__typeof__(lval)) _res;                                  \
   } while (0)

#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4)                \
   do {                                                                \
      volatile OrigFn        _orig = (orig);                           \
      volatile unsigned long _argvec[5];                               \
      volatile unsigned long _res;                                     \
      _argvec[0] = (unsigned long)_orig.nraddr;                        \
      _argvec[1] = (unsigned long)(arg1);                              \
      _argvec[2] = (unsigned long)(arg2);                              \
      _argvec[3] = (unsigned long)(arg3);                              \
      _argvec[4] = (unsigned long)(arg4);                              \
      __asm__ volatile(                                                \
         VALGRIND_CFI_PROLOGUE                                         \
         VALGRIND_ALIGN_STACK                                          \
         "subq $128,%%rsp\n\t"                                         \
         "movq 32(%%rax), %%rcx\n\t"                                   \
         "movq 24(%%rax), %%rdx\n\t"                                   \
         "movq 16(%%rax), %%rsi\n\t"                                   \
         "movq 8(%%rax), %%rdi\n\t"                                    \
         "movq (%%rax), %%rax\n\t"  /* target->%rax */                 \
         VALGRIND_CALL_NOREDIR_RAX                                     \
         VALGRIND_RESTORE_STACK                                        \
         VALGRIND_CFI_EPILOGUE                                         \
         : /*out*/   "=a" (_res)                                       \
         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER                 \
         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \
      );                                                               \
      lval = (__typeof__(lval)) _res;                                  \
   } while (0)

#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5)             \
   do {                                                                \
      volatile OrigFn        _orig = (orig);                           \
      volatile unsigned long _argvec[6];                               \
      volatile unsigned long _res;                                     \
      _argvec[0] = (unsigned long)_orig.nraddr;                        \
      _argvec[1] = (unsigned long)(arg1);                              \
      _argvec[2] = (unsigned long)(arg2);                              \
      _argvec[3] = (unsigned long)(arg3);                              \
      _argvec[4] = (unsigned long)(arg4);                              \
      _argvec[5] = (unsigned long)(arg5);                              \
      __asm__ volatile(                                                \
         VALGRIND_CFI_PROLOGUE                                         \
         VALGRIND_ALIGN_STACK                                          \
         "subq $128,%%rsp\n\t"                                         \
         "movq 40(%%rax), %%r8\n\t"                                    \
         "movq 32(%%rax), %%rcx\n\t"                                   \
         "movq 24(%%rax), %%rdx\n\t"                                   \
         "movq 16(%%rax), %%rsi\n\t"                                   \
         "movq 8(%%rax), %%rdi\n\t"                                    \
         "movq (%%rax), %%rax\n\t"  /* target->%rax */                 \
         VALGRIND_CALL_NOREDIR_RAX                                     \
         VALGRIND_RESTORE_STACK                                        \
         VALGRIND_CFI_EPILOGUE                                         \
         : /*out*/   "=a" (_res)                                       \
         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER                 \
         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \
      );                                                               \
      lval = (__typeof__(lval)) _res;                                  \
   } while (0)

#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6)        \
   do {                                                                \
      volatile OrigFn        _orig = (orig);                           \
      volatile unsigned long _argvec[7];                               \
      volatile unsigned long _res;                                     \
      _argvec[0] = (unsigned long)_orig.nraddr;                        \
      _argvec[1] = (unsigned long)(arg1);                              \
      _argvec[2] = (unsigned long)(arg2);                              \
      _argvec[3] = (unsigned long)(arg3);                              \
      _argvec[4] = (unsigned long)(arg4);                              \
      _argvec[5] = (unsigned long)(arg5);                              \
      _argvec[6] = (unsigned long)(arg6);                              \
      __asm__ volatile(                                                \
         VALGRIND_CFI_PROLOGUE                                         \
         VALGRIND_ALIGN_STACK                                          \
         "subq $128,%%rsp\n\t"                                         \
         "movq 48(%%rax), %%r9\n\t"                                    \
         "movq 40(%%rax), %%r8\n\t"                                    \
         "movq 32(%%rax), %%rcx\n\t"                                   \
         "movq 24(%%rax), %%rdx\n\t"                                   \
         "movq 16(%%rax), %%rsi\n\t"                                   \
         "movq 8(%%rax), %%rdi\n\t"                                    \
         "movq (%%rax), %%rax\n\t"  /* target->%rax */                 \
         VALGRIND_CALL_NOREDIR_RAX                                     \
         VALGRIND_RESTORE_STACK                                        \
         VALGRIND_CFI_EPILOGUE                                         \
         : /*out*/   "=a" (_res)                                       \
         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER                 \
         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \
      );                                                               \
      lval = (__typeof__(lval)) _res;                                  \
   } while (0)

#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,        \
                                 arg7)                                 \
   do {                                                                \
      volatile OrigFn        _orig = (orig);                           \
      volatile unsigned long _argvec[8];                               \
      volatile unsigned long _res;                                     \
      _argvec[0] = (unsigned long)_orig.nraddr;                        \
      _argvec[1] = (unsigned long)(arg1);                              \
      _argvec[2] = (unsigned long)(arg2);                              \
      _argvec[3] = (unsigned long)(arg3);                              \
      _argvec[4] = (unsigned long)(arg4);                              \
      _argvec[5] = (unsigned long)(arg5);                              \
      _argvec[6] = (unsigned long)(arg6);                              \
      _argvec[7] = (unsigned long)(arg7);                              \
      __asm__ volatile(                                                \
         VALGRIND_CFI_PROLOGUE                                         \
         VALGRIND_ALIGN_STACK                                          \
         "subq $136,%%rsp\n\t"                                         \
         "pushq 56(%%rax)\n\t"                                         \
         "movq 48(%%rax), %%r9\n\t"                                    \
         "movq 40(%%rax), %%r8\n\t"                                    \
         "movq 32(%%rax), %%rcx\n\t"                                   \
         "movq 24(%%rax), %%rdx\n\t"                                   \
         "movq 16(%%rax), %%rsi\n\t"                                   \
         "movq 8(%%rax), %%rdi\n\t"                                    \
         "movq (%%rax), %%rax\n\t"  /* target->%rax */                 \
         VALGRIND_CALL_NOREDIR_RAX                                     \
         VALGRIND_RESTORE_STACK                                        \
         VALGRIND_CFI_EPILOGUE                                         \
         : /*out*/   "=a" (_res)                                       \
         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER                 \
         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \
      );                                                               \
      lval = (__typeof__(lval)) _res;                                  \
   } while (0)

#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,        \
                                 arg7,arg8)                            \
   do {                                                                \
      volatile OrigFn        _orig = (orig);                           \
      volatile unsigned long _argvec[9];                               \
      volatile unsigned long _res;                                     \
      _argvec[0] = (unsigned long)_orig.nraddr;                        \
      _argvec[1] = (unsigned long)(arg1);                              \
      _argvec[2] = (unsigned long)(arg2);                              \
      _argvec[3] = (unsigned long)(arg3);                              \
      _argvec[4] = (unsigned long)(arg4);                              \
      _argvec[5] = (unsigned long)(arg5);                              \
      _argvec[6] = (unsigned long)(arg6);                              \
      _argvec[7] = (unsigned long)(arg7);                              \
      _argvec[8] = (unsigned long)(arg8);                              \
      __asm__ volatile(                                                \
         VALGRIND_CFI_PROLOGUE                                         \
         VALGRIND_ALIGN_STACK                                          \
         "subq $128,%%rsp\n\t"                                         \
         "pushq 64(%%rax)\n\t"                                         \
         "pushq 56(%%rax)\n\t"                                         \
         "movq 48(%%rax), %%r9\n\t"                                    \
         "movq 40(%%rax), %%r8\n\t"                                    \
         "movq 32(%%rax), %%rcx\n\t"                                   \
         "movq 24(%%rax), %%rdx\n\t"                                   \
         "movq 16(%%rax), %%rsi\n\t"                                   \
         "movq 8(%%rax), %%rdi\n\t"                                    \
         "movq (%%rax), %%rax\n\t"  /* target->%rax */                 \
         VALGRIND_CALL_NOREDIR_RAX                                     \
         VALGRIND_RESTORE_STACK                                        \
         VALGRIND_CFI_EPILOGUE                                         \
         : /*out*/   "=a" (_res)                                       \
         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER                 \
         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \
      );                                                               \
      lval = (__typeof__(lval)) _res;                                  \
   } while (0)

#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,        \
                                 arg7,arg8,arg9)                       \
   do {                                                                \
      volatile OrigFn        _orig = (orig);                           \
      volatile unsigned long _argvec[10];                              \
      volatile unsigned long _res;                                     \
      _argvec[0] = (unsigned long)_orig.nraddr;                        \
      _argvec[1] = (unsigned long)(arg1);                              \
      _argvec[2] = (unsigned long)(arg2);                              \
      _argvec[3] = (unsigned long)(arg3);                              \
      _argvec[4] = (unsigned long)(arg4);                              \
      _argvec[5] = (unsigned long)(arg5);                              \
      _argvec[6] = (unsigned long)(arg6);                              \
      _argvec[7] = (unsigned long)(arg7);                              \
      _argvec[8] = (unsigned long)(arg8);                              \
      _argvec[9] = (unsigned long)(arg9);                              \
      __asm__ volatile(                                                \
         VALGRIND_CFI_PROLOGUE                                         \
         VALGRIND_ALIGN_STACK                                          \
         "subq $136,%%rsp\n\t"                                         \
         "pushq 72(%%rax)\n\t"                                         \
         "pushq 64(%%rax)\n\t"                                         \
         "pushq 56(%%rax)\n\t"                                         \
         "movq 48(%%rax), %%r9\n\t"                                    \
         "movq 40(%%rax), %%r8\n\t"                                    \
         "movq 32(%%rax), %%rcx\n\t"                                   \
         "movq 24(%%rax), %%rdx\n\t"                                   \
         "movq 16(%%rax), %%rsi\n\t"                                   \
         "movq 8(%%rax), %%rdi\n\t"                                    \
         "movq (%%rax), %%rax\n\t"  /* target->%rax */                 \
         VALGRIND_CALL_NOREDIR_RAX                                     \
         VALGRIND_RESTORE_STACK                                        \
         VALGRIND_CFI_EPILOGUE                                         \
         : /*out*/   "=a" (_res)                                       \
         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER                 \
         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \
      );                                                               \
      lval = (__typeof__(lval)) _res;                                  \
   } while (0)

#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,       \
                                  arg7,arg8,arg9,arg10)                \
   do {                                                                \
      volatile OrigFn        _orig = (orig);                           \
      volatile unsigned long _argvec[11];                              \
      volatile unsigned long _res;                                     \
      _argvec[0] = (unsigned long)_orig.nraddr;                        \
      _argvec[1] = (unsigned long)(arg1);                              \
      _argvec[2] = (unsigned long)(arg2);                              \
      _argvec[3] = (unsigned long)(arg3);                              \
      _argvec[4] = (unsigned long)(arg4);                              \
      _argvec[5] = (unsigned long)(arg5);                              \
      _argvec[6] = (unsigned long)(arg6);                              \
      _argvec[7] = (unsigned long)(arg7);                              \
      _argvec[8] = (unsigned long)(arg8);                              \
      _argvec[9] = (unsigned long)(arg9);                              \
      _argvec[10] = (unsigned long)(arg10);                            \
      __asm__ volatile(                                                \
         VALGRIND_CFI_PROLOGUE                                         \
         VALGRIND_ALIGN_STACK                                          \
         "subq $128,%%rsp\n\t"                                         \
         "pushq 80(%%rax)\n\t"                                         \
         "pushq 72(%%rax)\n\t"                                         \
         "pushq 64(%%rax)\n\t"                                         \
         "pushq 56(%%rax)\n\t"                                         \
         "movq 48(%%rax), %%r9\n\t"                                    \
         "movq 40(%%rax), %%r8\n\t"                                    \
         "movq 32(%%rax), %%rcx\n\t"                                   \
         "movq 24(%%rax), %%rdx\n\t"                                   \
         "movq 16(%%rax), %%rsi\n\t"                                   \
         "movq 8(%%rax), %%rdi\n\t"                                    \
         "movq (%%rax), %%rax\n\t"  /* target->%rax */                 \
         VALGRIND_CALL_NOREDIR_RAX                                     \
         VALGRIND_RESTORE_STACK                                        \
         VALGRIND_CFI_EPILOGUE                                         \
         : /*out*/   "=a" (_res)                                       \
         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER                 \
         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \
      );                                                               \
      lval = (__typeof__(lval)) _res;                                  \
   } while (0)

#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,       \
                                  arg7,arg8,arg9,arg10,arg11)          \
   do {                                                                \
      volatile OrigFn        _orig = (orig);                           \
      volatile unsigned long _argvec[12];                              \
      volatile unsigned long _res;                                     \
      _argvec[0] = (unsigned long)_orig.nraddr;                        \
      _argvec[1] = (unsigned long)(arg1);                              \
      _argvec[2] = (unsigned long)(arg2);                              \
      _argvec[3] = (unsigned long)(arg3);                              \
      _argvec[4] = (unsigned long)(arg4);                              \
      _argvec[5] = (unsigned long)(arg5);                              \
      _argvec[6] = (unsigned long)(arg6);                              \
      _argvec[7] = (unsigned long)(arg7);                              \
      _argvec[8] = (unsigned long)(arg8);                              \
      _argvec[9] = (unsigned long)(arg9);                              \
      _argvec[10] = (unsigned long)(arg10);                            \
      _argvec[11] = (unsigned long)(arg11);                            \
      __asm__ volatile(                                                \
         VALGRIND_CFI_PROLOGUE                                         \
         VALGRIND_ALIGN_STACK                                          \
         "subq $136,%%rsp\n\t"                                         \
         "pushq 88(%%rax)\n\t"                                         \
         "pushq 80(%%rax)\n\t"                                         \
         "pushq 72(%%rax)\n\t"                                         \
         "pushq 64(%%rax)\n\t"                                         \
         "pushq 56(%%rax)\n\t"                                         \
         "movq 48(%%rax), %%r9\n\t"                                    \
         "movq 40(%%rax), %%r8\n\t"                                    \
         "movq 32(%%rax), %%rcx\n\t"                                   \
         "movq 24(%%rax), %%rdx\n\t"                                   \
         "movq 16(%%rax), %%rsi\n\t"                                   \
         "movq 8(%%rax), %%rdi\n\t"                                    \
         "movq (%%rax), %%rax\n\t"  /* target->%rax */                 \
         VALGRIND_CALL_NOREDIR_RAX                                     \
         VALGRIND_RESTORE_STACK                                        \
         VALGRIND_CFI_EPILOGUE                                         \
         : /*out*/   "=a" (_res)                                       \
         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER                 \
         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \
      );                                                               \
      lval = (__typeof__(lval)) _res;                                  \
   } while (0)

#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,       \
                                arg7,arg8,arg9,arg10,arg11,arg12)      \
   do {                                                                \
      volatile OrigFn        _orig = (orig);                           \
      volatile unsigned long _argvec[13];                              \
      volatile unsigned long _res;                                     \
      _argvec[0] = (unsigned long)_orig.nraddr;                        \
      _argvec[1] = (unsigned long)(arg1);                              \
      _argvec[2] = (unsigned long)(arg2);                              \
      _argvec[3] = (unsigned long)(arg3);                              \
      _argvec[4] = (unsigned long)(arg4);                              \
      _argvec[5] = (unsigned long)(arg5);                              \
      _argvec[6] = (unsigned long)(arg6);                              \
      _argvec[7] = (unsigned long)(arg7);                              \
      _argvec[8] = (unsigned long)(arg8);                              \
      _argvec[9] = (unsigned long)(arg9);                              \
      _argvec[10] = (unsigned long)(arg10);                            \
      _argvec[11] = (unsigned long)(arg11);                            \
      _argvec[12] = (unsigned long)(arg12);                            \
      __asm__ volatile(                                                \
         VALGRIND_CFI_PROLOGUE                                         \
         VALGRIND_ALIGN_STACK                                          \
         "subq $128,%%rsp\n\t"                                         \
         "pushq 96(%%rax)\n\t"                                         \
         "pushq 88(%%rax)\n\t"                                         \
         "pushq 80(%%rax)\n\t"                                         \
         "pushq 72(%%rax)\n\t"                                         \
         "pushq 64(%%rax)\n\t"                                         \
         "pushq 56(%%rax)\n\t"                                         \
         "movq 48(%%rax), %%r9\n\t"                                    \
         "movq 40(%%rax), %%r8\n\t"                                    \
         "movq 32(%%rax), %%rcx\n\t"                                   \
         "movq 24(%%rax), %%rdx\n\t"                                   \
         "movq 16(%%rax), %%rsi\n\t"                                   \
         "movq 8(%%rax), %%rdi\n\t"                                    \
         "movq (%%rax), %%rax\n\t"  /* target->%rax */                 \
         VALGRIND_CALL_NOREDIR_RAX                                     \
         VALGRIND_RESTORE_STACK                                        \
         VALGRIND_CFI_EPILOGUE                                         \
         : /*out*/   "=a" (_res)                                       \
         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER                 \
         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \
      );                                                               \
      lval = (__typeof__(lval)) _res;                                  \
   } while (0)

#endif /* PLAT_amd64_linux || PLAT_amd64_darwin || PLAT_amd64_solaris */

/* ------------------------ ppc32-linux ------------------------ */

#if defined(PLAT_ppc32_linux)

/* This is useful for finding out about the on-stack stuff:

   extern int f9  ( int,int,int,int,int,int,int,int,int );
   extern int f10 ( int,int,int,int,int,int,int,int,int,int );
   extern int f11 ( int,int,int,int,int,int,int,int,int,int,int );
   extern int f12 ( int,int,int,int,int,int,int,int,int,int,int,int );

   int g9 ( void ) {
      return f9(11,22,33,44,55,66,77,88,99);
   }
   int g10 ( void ) {
      return f10(11,22,33,44,55,66,77,88,99,110);
   }
   int g11 ( void ) {
      return f11(11,22,33,44,55,66,77,88,99,110,121);
   }
   int g12 ( void ) {
      return f12(11,22,33,44,55,66,77,88,99,110,121,132);
   }
*/

/* ARGREGS: r3 r4 r5 r6 r7 r8 r9 r10 (the rest on stack somewhere) */

/* These regs are trashed by the hidden call. */
#define __CALLER_SAVED_REGS                                       \
   "lr", "ctr", "xer",                                            \
   "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7",        \
   "r0", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10",   \
   "r11", "r12", "r13"

/* Macros to save and align the stack before making a function
   call and restore it afterwards as gcc may not keep the stack
   pointer aligned if it doesn't realise calls are being made
   to other functions. */

#define VALGRIND_ALIGN_STACK               \
      "mr 28,1\n\t"                        \
      "rlwinm 1,1,0,0,27\n\t"
#define VALGRIND_RESTORE_STACK             \
      "mr 1,28\n\t"

/* These CALL_FN_ macros assume that on ppc32-linux, 
   sizeof(unsigned long) == 4. */

#define CALL_FN_W_v(lval, orig)                                   \
   do {                                                           \
      volatile OrigFn        _orig = (orig);                      \
      volatile unsigned long _argvec[1];                          \
      volatile unsigned long _res;                                \
      _argvec[0] = (unsigned long)_orig.nraddr;                   \
      __asm__ volatile(                                           \
         VALGRIND_ALIGN_STACK                                     \
         "mr 11,%1\n\t"                                           \
         "lwz 11,0(11)\n\t"  /* target->r11 */                    \
         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
         VALGRIND_RESTORE_STACK                                   \
         "mr %0,3"                                                \
         : /*out*/   "=r" (_res)                                  \
         : /*in*/    "r" (&_argvec[0])                            \
         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
      );                                                          \
      lval = (__typeof__(lval)) _res;                             \
   } while (0)

#define CALL_FN_W_W(lval, orig, arg1)                             \
   do {                                                           \
      volatile OrigFn        _orig = (orig);                      \
      volatile unsigned long _argvec[2];                          \
      volatile unsigned long _res;                                \
      _argvec[0] = (unsigned long)_orig.nraddr;                   \
      _argvec[1] = (unsigned long)arg1;                           \
      __asm__ volatile(                                           \
         VALGRIND_ALIGN_STACK                                     \
         "mr 11,%1\n\t"                                           \
         "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
         "lwz 11,0(11)\n\t"  /* target->r11 */                    \
         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
         VALGRIND_RESTORE_STACK                                   \
         "mr %0,3"                                                \
         : /*out*/   "=r" (_res)                                  \
         : /*in*/    "r" (&_argvec[0])                            \
         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
      );                                                          \
      lval = (__typeof__(lval)) _res;                             \
   } while (0)

#define CALL_FN_W_WW(lval, orig, arg1,arg2)                       \
   do {                                                           \
      volatile OrigFn        _orig = (orig);                      \
      volatile unsigned long _argvec[3];                          \
      volatile unsigned long _res;                                \
      _argvec[0] = (unsigned long)_orig.nraddr;                   \
      _argvec[1] = (unsigned long)arg1;                           \
      _argvec[2] = (unsigned long)arg2;                           \
      __asm__ volatile(                                           \
         VALGRIND_ALIGN_STACK                                     \
         "mr 11,%1\n\t"                                           \
         "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
         "lwz 4,8(11)\n\t"                                        \
         "lwz 11,0(11)\n\t"  /* target->r11 */                    \
         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
         VALGRIND_RESTORE_STACK                                   \
         "mr %0,3"                                                \
         : /*out*/   "=r" (_res)                                  \
         : /*in*/    "r" (&_argvec[0])                            \
         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
      );                                                          \
      lval = (__typeof__(lval)) _res;                             \
   } while (0)

#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3)                 \
   do {                                                           \
      volatile OrigFn        _orig = (orig);                      \
      volatile unsigned long _argvec[4];                          \
      volatile unsigned long _res;                                \
      _argvec[0] = (unsigned long)_orig.nraddr;                   \
      _argvec[1] = (unsigned long)arg1;                           \
      _argvec[2] = (unsigned long)arg2;                           \
      _argvec[3] = (unsigned long)arg3;                           \
      __asm__ volatile(                                           \
         VALGRIND_ALIGN_STACK                                     \
         "mr 11,%1\n\t"                                           \
         "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
         "lwz 4,8(11)\n\t"                                        \
         "lwz 5,12(11)\n\t"                                       \
         "lwz 11,0(11)\n\t"  /* target->r11 */                    \
         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
         VALGRIND_RESTORE_STACK                                   \
         "mr %0,3"                                                \
         : /*out*/   "=r" (_res)                                  \
         : /*in*/    "r" (&_argvec[0])                            \
         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
      );                                                          \
      lval = (__typeof__(lval)) _res;                             \
   } while (0)

#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4)           \
   do {                                                           \
      volatile OrigFn        _orig = (orig);                      \
      volatile unsigned long _argvec[5];                          \
      volatile unsigned long _res;                                \
      _argvec[0] = (unsigned long)_orig.nraddr;                   \
      _argvec[1] = (unsigned long)arg1;                           \
      _argvec[2] = (unsigned long)arg2;                           \
      _argvec[3] = (unsigned long)arg3;                           \
      _argvec[4] = (unsigned long)arg4;                           \
      __asm__ volatile(                                           \
         VALGRIND_ALIGN_STACK                                     \
         "mr 11,%1\n\t"                                           \
         "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
         "lwz 4,8(11)\n\t"                                        \
         "lwz 5,12(11)\n\t"                                       \
         "lwz 6,16(11)\n\t"  /* arg4->r6 */                       \
         "lwz 11,0(11)\n\t"  /* target->r11 */                    \
         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
         VALGRIND_RESTORE_STACK                                   \
         "mr %0,3"                                                \
         : /*out*/   "=r" (_res)                                  \
         : /*in*/    "r" (&_argvec[0])                            \
         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
      );                                                          \
      lval = (__typeof__(lval)) _res;                             \
   } while (0)

#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5)        \
   do {                                                           \
      volatile OrigFn        _orig = (orig);                      \
      volatile unsigned long _argvec[6];                          \
      volatile unsigned long _res;                                \
      _argvec[0] = (unsigned long)_orig.nraddr;                   \
      _argvec[1] = (unsigned long)arg1;                           \
      _argvec[2] = (unsigned long)arg2;                           \
      _argvec[3] = (unsigned long)arg3;                           \
      _argvec[4] = (unsigned long)arg4;                           \
      _argvec[5] = (unsigned long)arg5;                           \
      __asm__ volatile(                                           \
         VALGRIND_ALIGN_STACK                                     \
         "mr 11,%1\n\t"                                           \
         "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
         "lwz 4,8(11)\n\t"                                        \
         "lwz 5,12(11)\n\t"                                       \
         "lwz 6,16(11)\n\t"  /* arg4->r6 */                       \
         "lwz 7,20(11)\n\t"                                       \
         "lwz 11,0(11)\n\t"  /* target->r11 */                    \
         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
         VALGRIND_RESTORE_STACK                                   \
         "mr %0,3"                                                \
         : /*out*/   "=r" (_res)                                  \
         : /*in*/    "r" (&_argvec[0])                            \
         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
      );                                                          \
      lval = (__typeof__(lval)) _res;                             \
   } while (0)

#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6)   \
   do {                                                           \
      volatile OrigFn        _orig = (orig);                      \
      volatile unsigned long _argvec[7];                          \
      volatile unsigned long _res;                                \
      _argvec[0] = (unsigned long)_orig.nraddr;                   \
      _argvec[1] = (unsigned long)arg1;                           \
      _argvec[2] = (unsigned long)arg2;                           \
      _argvec[3] = (unsigned long)arg3;                           \
      _argvec[4] = (unsigned long)arg4;                           \
      _argvec[5] = (unsigned long)arg5;                           \
      _argvec[6] = (unsigned long)arg6;                           \
      __asm__ volatile(                                           \
         VALGRIND_ALIGN_STACK                                     \
         "mr 11,%1\n\t"                                           \
         "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
         "lwz 4,8(11)\n\t"                                        \
         "lwz 5,12(11)\n\t"                                       \
         "lwz 6,16(11)\n\t"  /* arg4->r6 */                       \
         "lwz 7,20(11)\n\t"                                       \
         "lwz 8,24(11)\n\t"                                       \
         "lwz 11,0(11)\n\t"  /* target->r11 */                    \
         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
         VALGRIND_RESTORE_STACK                                   \
         "mr %0,3"                                                \
         : /*out*/   "=r" (_res)                                  \
         : /*in*/    "r" (&_argvec[0])                            \
         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
      );                                                          \
      lval = (__typeof__(lval)) _res;                             \
   } while (0)

#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
                                 arg7)                            \
   do {                                                           \
      volatile OrigFn        _orig = (orig);                      \
      volatile unsigned long _argvec[8];                          \
      volatile unsigned long _res;                                \
      _argvec[0] = (unsigned long)_orig.nraddr;                   \
      _argvec[1] = (unsigned long)arg1;                           \
      _argvec[2] = (unsigned long)arg2;                           \
      _argvec[3] = (unsigned long)arg3;                           \
      _argvec[4] = (unsigned long)arg4;                           \
      _argvec[5] = (unsigned long)arg5;                           \
      _argvec[6] = (unsigned long)arg6;                           \
      _argvec[7] = (unsigned long)arg7;                           \
      __asm__ volatile(                                           \
         VALGRIND_ALIGN_STACK                                     \
         "mr 11,%1\n\t"                                           \
         "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
         "lwz 4,8(11)\n\t"                                        \
         "lwz 5,12(11)\n\t"                                       \
         "lwz 6,16(11)\n\t"  /* arg4->r6 */                       \
         "lwz 7,20(11)\n\t"                                       \
         "lwz 8,24(11)\n\t"                                       \
         "lwz 9,28(11)\n\t"                                       \
         "lwz 11,0(11)\n\t"  /* target->r11 */                    \
         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
         VALGRIND_RESTORE_STACK                                   \
         "mr %0,3"                                                \
         : /*out*/   "=r" (_res)                                  \
         : /*in*/    "r" (&_argvec[0])                            \
         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
      );                                                          \
      lval = (__typeof__(lval)) _res;                             \
   } while (0)

#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
                                 arg7,arg8)                       \
   do {                                                           \
      volatile OrigFn        _orig = (orig);                      \
      volatile unsigned long _argvec[9];                          \
      volatile unsigned long _res;                                \
      _argvec[0] = (unsigned long)_orig.nraddr;                   \
      _argvec[1] = (unsigned long)arg1;                           \
      _argvec[2] = (unsigned long)arg2;                           \
      _argvec[3] = (unsigned long)arg3;                           \
      _argvec[4] = (unsigned long)arg4;                           \
      _argvec[5] = (unsigned long)arg5;                           \
      _argvec[6] = (unsigned long)arg6;                           \
      _argvec[7] = (unsigned long)arg7;                           \
      _argvec[8] = (unsigned long)arg8;                           \
      __asm__ volatile(                                           \
         VALGRIND_ALIGN_STACK                                     \
         "mr 11,%1\n\t"                                           \
         "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
         "lwz 4,8(11)\n\t"                                        \
         "lwz 5,12(11)\n\t"                                       \
         "lwz 6,16(11)\n\t"  /* arg4->r6 */                       \
         "lwz 7,20(11)\n\t"                                       \
         "lwz 8,24(11)\n\t"                                       \
         "lwz 9,28(11)\n\t"                                       \
         "lwz 10,32(11)\n\t" /* arg8->r10 */                      \
         "lwz 11,0(11)\n\t"  /* target->r11 */                    \
         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
         VALGRIND_RESTORE_STACK                                   \
         "mr %0,3"                                                \
         : /*out*/   "=r" (_res)                                  \
         : /*in*/    "r" (&_argvec[0])                            \
         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
      );                                                          \
      lval = (__typeof__(lval)) _res;                             \
   } while (0)

#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
                                 arg7,arg8,arg9)                  \
   do {                                                           \
      volatile OrigFn        _orig = (orig);                      \
      volatile unsigned long _argvec[10];                         \
      volatile unsigned long _res;                                \
      _argvec[0] = (unsigned long)_orig.nraddr;                   \
      _argvec[1] = (unsigned long)arg1;                           \
      _argvec[2] = (unsigned long)arg2;                           \
      _argvec[3] = (unsigned long)arg3;                           \
      _argvec[4] = (unsigned long)arg4;                           \
      _argvec[5] = (unsigned long)arg5;                           \
      _argvec[6] = (unsigned long)arg6;                           \
      _argvec[7] = (unsigned long)arg7;                           \
      _argvec[8] = (unsigned long)arg8;                           \
      _argvec[9] = (unsigned long)arg9;                           \
      __asm__ volatile(                                           \
         VALGRIND_ALIGN_STACK                                     \
         "mr 11,%1\n\t"                                           \
         "addi 1,1,-16\n\t"                                       \
         /* arg9 */                                               \
         "lwz 3,36(11)\n\t"                                       \
         "stw 3,8(1)\n\t"                                         \
         /* args1-8 */                                            \
         "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
         "lwz 4,8(11)\n\t"                                        \
         "lwz 5,12(11)\n\t"                                       \
         "lwz 6,16(11)\n\t"  /* arg4->r6 */                       \
         "lwz 7,20(11)\n\t"                                       \
         "lwz 8,24(11)\n\t"                                       \
         "lwz 9,28(11)\n\t"                                       \
         "lwz 10,32(11)\n\t" /* arg8->r10 */                      \
         "lwz 11,0(11)\n\t"  /* target->r11 */                    \
         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
         VALGRIND_RESTORE_STACK                                   \
         "mr %0,3"                                                \
         : /*out*/   "=r" (_res)                                  \
         : /*in*/    "r" (&_argvec[0])                            \
         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
      );                                                          \
      lval = (__typeof__(lval)) _res;                             \
   } while (0)

#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
                                  arg7,arg8,arg9,arg10)           \
   do {                                                           \
      volatile OrigFn        _orig = (orig);                      \
      volatile unsigned long _argvec[11];                         \
      volatile unsigned long _res;                                \
      _argvec[0] = (unsigned long)_orig.nraddr;                   \
      _argvec[1] = (unsigned long)arg1;                           \
      _argvec[2] = (unsigned long)arg2;                           \
      _argvec[3] = (unsigned long)arg3;                           \
      _argvec[4] = (unsigned long)arg4;                           \
      _argvec[5] = (unsigned long)arg5;                           \
      _argvec[6] = (unsigned long)arg6;                           \
      _argvec[7] = (unsigned long)arg7;                           \
      _argvec[8] = (unsigned long)arg8;                           \
      _argvec[9] = (unsigned long)arg9;                           \
      _argvec[10] = (unsigned long)arg10;                         \
      __asm__ volatile(                                           \
         VALGRIND_ALIGN_STACK                                     \
         "mr 11,%1\n\t"                                           \
         "addi 1,1,-16\n\t"                                       \
         /* arg10 */                                              \
         "lwz 3,40(11)\n\t"                                       \
         "stw 3,12(1)\n\t"                                        \
         /* arg9 */                                               \
         "lwz 3,36(11)\n\t"                                       \
         "stw 3,8(1)\n\t"                                         \
         /* args1-8 */                                            \
         "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
         "lwz 4,8(11)\n\t"                                        \
         "lwz 5,12(11)\n\t"                                       \
         "lwz 6,16(11)\n\t"  /* arg4->r6 */                       \
         "lwz 7,20(11)\n\t"                                       \
         "lwz 8,24(11)\n\t"                                       \
         "lwz 9,28(11)\n\t"                                       \
         "lwz 10,32(11)\n\t" /* arg8->r10 */                      \
         "lwz 11,0(11)\n\t"  /* target->r11 */                    \
         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
         VALGRIND_RESTORE_STACK                                   \
         "mr %0,3"                                                \
         : /*out*/   "=r" (_res)                                  \
         : /*in*/    "r" (&_argvec[0])                            \
         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
      );                                                          \
      lval = (__typeof__(lval)) _res;                             \
   } while (0)

#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
                                  arg7,arg8,arg9,arg10,arg11)     \
   do {                                                           \
      volatile OrigFn        _orig = (orig);                      \
      volatile unsigned long _argvec[12];                         \
      volatile unsigned long _res;                                \
      _argvec[0] = (unsigned long)_orig.nraddr;                   \
      _argvec[1] = (unsigned long)arg1;                           \
      _argvec[2] = (unsigned long)arg2;                           \
      _argvec[3] = (unsigned long)arg3;                           \
      _argvec[4] = (unsigned long)arg4;                           \
      _argvec[5] = (unsigned long)arg5;                           \
      _argvec[6] = (unsigned long)arg6;                           \
      _argvec[7] = (unsigned long)arg7;                           \
      _argvec[8] = (unsigned long)arg8;                           \
      _argvec[9] = (unsigned long)arg9;                           \
      _argvec[10] = (unsigned long)arg10;                         \
      _argvec[11] = (unsigned long)arg11;                         \
      __asm__ volatile(                                           \
         VALGRIND_ALIGN_STACK                                     \
         "mr 11,%1\n\t"                                           \
         "addi 1,1,-32\n\t"                                       \
         /* arg11 */                                              \
         "lwz 3,44(11)\n\t"                                       \
         "stw 3,16(1)\n\t"                                        \
         /* arg10 */                                              \
         "lwz 3,40(11)\n\t"                                       \
         "stw 3,12(1)\n\t"                                        \
         /* arg9 */                                               \
         "lwz 3,36(11)\n\t"                                       \
         "stw 3,8(1)\n\t"                                         \
         /* args1-8 */                                            \
         "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
         "lwz 4,8(11)\n\t"                                        \
         "lwz 5,12(11)\n\t"                                       \
         "lwz 6,16(11)\n\t"  /* arg4->r6 */                       \
         "lwz 7,20(11)\n\t"                                       \
         "lwz 8,24(11)\n\t"                                       \
         "lwz 9,28(11)\n\t"                                       \
         "lwz 10,32(11)\n\t" /* arg8->r10 */                      \
         "lwz 11,0(11)\n\t"  /* target->r11 */                    \
         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
         VALGRIND_RESTORE_STACK                                   \
         "mr %0,3"                                                \
         : /*out*/   "=r" (_res)                                  \
         : /*in*/    "r" (&_argvec[0])                            \
         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
      );                                                          \
      lval = (__typeof__(lval)) _res;                             \
   } while (0)

#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
                                arg7,arg8,arg9,arg10,arg11,arg12) \
   do {                                                           \
      volatile OrigFn        _orig = (orig);                      \
      volatile unsigned long _argvec[13];                         \
      volatile unsigned long _res;                                \
      _argvec[0] = (unsigned long)_orig.nraddr;                   \
      _argvec[1] = (unsigned long)arg1;                           \
      _argvec[2] = (unsigned long)arg2;                           \
      _argvec[3] = (unsigned long)arg3;                           \
      _argvec[4] = (unsigned long)arg4;                           \
      _argvec[5] = (unsigned long)arg5;                           \
      _argvec[6] = (unsigned long)arg6;                           \
      _argvec[7] = (unsigned long)arg7;                           \
      _argvec[8] = (unsigned long)arg8;                           \
      _argvec[9] = (unsigned long)arg9;                           \
      _argvec[10] = (unsigned long)arg10;                         \
      _argvec[11] = (unsigned long)arg11;                         \
      _argvec[12] = (unsigned long)arg12;                         \
      __asm__ volatile(                                           \
         VALGRIND_ALIGN_STACK                                     \
         "mr 11,%1\n\t"                                           \
         "addi 1,1,-32\n\t"                                       \
         /* arg12 */                                              \
         "lwz 3,48(11)\n\t"                                       \
         "stw 3,20(1)\n\t"                                        \
         /* arg11 */                                              \
         "lwz 3,44(11)\n\t"                                       \
         "stw 3,16(1)\n\t"                                        \
         /* arg10 */                                              \
         "lwz 3,40(11)\n\t"                                       \
         "stw 3,12(1)\n\t"                                        \
         /* arg9 */                                               \
         "lwz 3,36(11)\n\t"                                       \
         "stw 3,8(1)\n\t"                                         \
         /* args1-8 */                                            \
         "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
         "lwz 4,8(11)\n\t"                                        \
         "lwz 5,12(11)\n\t"                                       \
         "lwz 6,16(11)\n\t"  /* arg4->r6 */                       \
         "lwz 7,20(11)\n\t"                                       \
         "lwz 8,24(11)\n\t"                                       \
         "lwz 9,28(11)\n\t"                                       \
         "lwz 10,32(11)\n\t" /* arg8->r10 */                      \
         "lwz 11,0(11)\n\t"  /* target->r11 */                    \
         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
         VALGRIND_RESTORE_STACK                                   \
         "mr %0,3"                                                \
         : /*out*/   "=r" (_res)                                  \
         : /*in*/    "r" (&_argvec[0])                            \
         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
      );                                                          \
      lval = (__typeof__(lval)) _res;                             \
   } while (0)

#endif /* PLAT_ppc32_linux */

/* ------------------------ ppc64-linux ------------------------ */

#if defined(PLAT_ppc64be_linux)

/* ARGREGS: r3 r4 r5 r6 r7 r8 r9 r10 (the rest on stack somewhere) */

/* These regs are trashed by the hidden call. */
#define __CALLER_SAVED_REGS                                       \
   "lr", "ctr", "xer",                                            \
   "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7",        \
   "r0", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10",         \
   "r11", "r12", "r13"

/* Macros to save and align the stack before making a function
   call and restore it afterwards as gcc may not keep the stack
   pointer aligned if it doesn't realise calls are being made
   to other functions. */

#define VALGRIND_ALIGN_STACK               \
      "mr 28,1\n\t"                        \
      "rldicr 1,1,0,59\n\t"
#define VALGRIND_RESTORE_STACK             \
      "mr 1,28\n\t"

/* These CALL_FN_ macros assume that on ppc64-linux, sizeof(unsigned
   long) == 8. */

#define CALL_FN_W_v(lval, orig)                                   \
   do {                                                           \
      volatile OrigFn        _orig = (orig);                      \
      volatile unsigned long _argvec[3+0];                        \
      volatile unsigned long _res;                                \
      /* _argvec[0] holds current r2 across the call */           \
      _argvec[1] = (unsigned long)_orig.r2;                       \
      _argvec[2] = (unsigned long)_orig.nraddr;                   \
      __asm__ volatile(                                           \
         VALGRIND_ALIGN_STACK                                     \
         "mr 11,%1\n\t"                                           \
         "std 2,-16(11)\n\t"  /* save tocptr */                   \
         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
         "mr 11,%1\n\t"                                           \
         "mr %0,3\n\t"                                            \
         "ld 2,-16(11)\n\t" /* restore tocptr */                  \
         VALGRIND_RESTORE_STACK                                   \
         : /*out*/   "=r" (_res)                                  \
         : /*in*/    "r" (&_argvec[2])                            \
         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
      );                                                          \
      lval = (__typeof__(lval)) _res;                             \
   } while (0)

#define CALL_FN_W_W(lval, orig, arg1)                             \
   do {                                                           \
      volatile OrigFn        _orig = (orig);                      \
      volatile unsigned long _argvec[3+1];                        \
      volatile unsigned long _res;                                \
      /* _argvec[0] holds current r2 across the call */           \
      _argvec[1]   = (unsigned long)_orig.r2;                     \
      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
      _argvec[2+1] = (unsigned long)arg1;                         \
      __asm__ volatile(                                           \
         VALGRIND_ALIGN_STACK                                     \
         "mr 11,%1\n\t"                                           \
         "std 2,-16(11)\n\t"  /* save tocptr */                   \
         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
         "mr 11,%1\n\t"                                           \
         "mr %0,3\n\t"                                            \
         "ld 2,-16(11)\n\t" /* restore tocptr */                  \
         VALGRIND_RESTORE_STACK                                   \
         : /*out*/   "=r" (_res)                                  \
         : /*in*/    "r" (&_argvec[2])                            \
         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
      );                                                          \
      lval = (__typeof__(lval)) _res;                             \
   } while (0)

#define CALL_FN_W_WW(lval, orig, arg1,arg2)                       \
   do {                                                           \
      volatile OrigFn        _orig = (orig);                      \
      volatile unsigned long _argvec[3+2];                        \
      volatile unsigned long _res;                                \
      /* _argvec[0] holds current r2 across the call */           \
      _argvec[1]   = (unsigned long)_orig.r2;                     \
      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
      _argvec[2+1] = (unsigned long)arg1;                         \
      _argvec[2+2] = (unsigned long)arg2;                         \
      __asm__ volatile(                                           \
         VALGRIND_ALIGN_STACK                                     \
         "mr 11,%1\n\t"                                           \
         "std 2,-16(11)\n\t"  /* save tocptr */                   \
         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
         "mr 11,%1\n\t"                                           \
         "mr %0,3\n\t"                                            \
         "ld 2,-16(11)\n\t" /* restore tocptr */                  \
         VALGRIND_RESTORE_STACK                                   \
         : /*out*/   "=r" (_res)                                  \
         : /*in*/    "r" (&_argvec[2])                            \
         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
      );                                                          \
      lval = (__typeof__(lval)) _res;                             \
   } while (0)

#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3)                 \
   do {                                                           \
      volatile OrigFn        _orig = (orig);                      \
      volatile unsigned long _argvec[3+3];                        \
      volatile unsigned long _res;                                \
      /* _argvec[0] holds current r2 across the call */           \
      _argvec[1]   = (unsigned long)_orig.r2;                     \
      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
      _argvec[2+1] = (unsigned long)arg1;                         \
      _argvec[2+2] = (unsigned long)arg2;                         \
      _argvec[2+3] = (unsigned long)arg3;                         \
      __asm__ volatile(                                           \
         VALGRIND_ALIGN_STACK                                     \
         "mr 11,%1\n\t"                                           \
         "std 2,-16(11)\n\t"  /* save tocptr */                   \
         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
         "mr 11,%1\n\t"                                           \
         "mr %0,3\n\t"                                            \
         "ld 2,-16(11)\n\t" /* restore tocptr */                  \
         VALGRIND_RESTORE_STACK                                   \
         : /*out*/   "=r" (_res)                                  \
         : /*in*/    "r" (&_argvec[2])                            \
         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
      );                                                          \
      lval = (__typeof__(lval)) _res;                             \
   } while (0)

#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4)           \
   do {                                                           \
      volatile OrigFn        _orig = (orig);                      \
      volatile unsigned long _argvec[3+4];                        \
      volatile unsigned long _res;                                \
      /* _argvec[0] holds current r2 across the call */           \
      _argvec[1]   = (unsigned long)_orig.r2;                     \
      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
      _argvec[2+1] = (unsigned long)arg1;                         \
      _argvec[2+2] = (unsigned long)arg2;                         \
      _argvec[2+3] = (unsigned long)arg3;                         \
      _argvec[2+4] = (unsigned long)arg4;                         \
      __asm__ volatile(                                           \
         VALGRIND_ALIGN_STACK                                     \
         "mr 11,%1\n\t"                                           \
         "std 2,-16(11)\n\t"  /* save tocptr */                   \
         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
         "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
         "mr 11,%1\n\t"                                           \
         "mr %0,3\n\t"                                            \
         "ld 2,-16(11)\n\t" /* restore tocptr */                  \
         VALGRIND_RESTORE_STACK                                   \
         : /*out*/   "=r" (_res)                                  \
         : /*in*/    "r" (&_argvec[2])                            \
         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
      );                                                          \
      lval = (__typeof__(lval)) _res;                             \
   } while (0)

#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5)        \
   do {                                                           \
      volatile OrigFn        _orig = (orig);                      \
      volatile unsigned long _argvec[3+5];                        \
      volatile unsigned long _res;                                \
      /* _argvec[0] holds current r2 across the call */           \
      _argvec[1]   = (unsigned long)_orig.r2;                     \
      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
      _argvec[2+1] = (unsigned long)arg1;                         \
      _argvec[2+2] = (unsigned long)arg2;                         \
      _argvec[2+3] = (unsigned long)arg3;                         \
      _argvec[2+4] = (unsigned long)arg4;                         \
      _argvec[2+5] = (unsigned long)arg5;                         \
      __asm__ volatile(                                           \
         VALGRIND_ALIGN_STACK                                     \
         "mr 11,%1\n\t"                                           \
         "std 2,-16(11)\n\t"  /* save tocptr */                   \
         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
         "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
         "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
         "mr 11,%1\n\t"                                           \
         "mr %0,3\n\t"                                            \
         "ld 2,-16(11)\n\t" /* restore tocptr */                  \
         VALGRIND_RESTORE_STACK                                   \
         : /*out*/   "=r" (_res)                                  \
         : /*in*/    "r" (&_argvec[2])                            \
         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
      );                                                          \
      lval = (__typeof__(lval)) _res;                             \
   } while (0)

#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6)   \
   do {                                                           \
      volatile OrigFn        _orig = (orig);                      \
      volatile unsigned long _argvec[3+6];                        \
      volatile unsigned long _res;                                \
      /* _argvec[0] holds current r2 across the call */           \
      _argvec[1]   = (unsigned long)_orig.r2;                     \
      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
      _argvec[2+1] = (unsigned long)arg1;                         \
      _argvec[2+2] = (unsigned long)arg2;                         \
      _argvec[2+3] = (unsigned long)arg3;                         \
      _argvec[2+4] = (unsigned long)arg4;                         \
      _argvec[2+5] = (unsigned long)arg5;                         \
      _argvec[2+6] = (unsigned long)arg6;                         \
      __asm__ volatile(                                           \
         VALGRIND_ALIGN_STACK                                     \
         "mr 11,%1\n\t"                                           \
         "std 2,-16(11)\n\t"  /* save tocptr */                   \
         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
         "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
         "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
         "ld   8, 48(11)\n\t" /* arg6->r8 */                      \
         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
         "mr 11,%1\n\t"                                           \
         "mr %0,3\n\t"                                            \
         "ld 2,-16(11)\n\t" /* restore tocptr */                  \
         VALGRIND_RESTORE_STACK                                   \
         : /*out*/   "=r" (_res)                                  \
         : /*in*/    "r" (&_argvec[2])                            \
         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
      );                                                          \
      lval = (__typeof__(lval)) _res;                             \
   } while (0)

#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
                                 arg7)                            \
   do {                                                           \
      volatile OrigFn        _orig = (orig);                      \
      volatile unsigned long _argvec[3+7];                        \
      volatile unsigned long _res;                                \
      /* _argvec[0] holds current r2 across the call */           \
      _argvec[1]   = (unsigned long)_orig.r2;                     \
      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
      _argvec[2+1] = (unsigned long)arg1;                         \
      _argvec[2+2] = (unsigned long)arg2;                         \
      _argvec[2+3] = (unsigned long)arg3;                         \
      _argvec[2+4] = (unsigned long)arg4;                         \
      _argvec[2+5] = (unsigned long)arg5;                         \
      _argvec[2+6] = (unsigned long)arg6;                         \
      _argvec[2+7] = (unsigned long)arg7;                         \
      __asm__ volatile(                                           \
         VALGRIND_ALIGN_STACK                                     \
         "mr 11,%1\n\t"                                           \
         "std 2,-16(11)\n\t"  /* save tocptr */                   \
         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
         "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
         "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
         "ld   8, 48(11)\n\t" /* arg6->r8 */                      \
         "ld   9, 56(11)\n\t" /* arg7->r9 */                      \
         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
         "mr 11,%1\n\t"                                           \
         "mr %0,3\n\t"                                            \
         "ld 2,-16(11)\n\t" /* restore tocptr */                  \
         VALGRIND_RESTORE_STACK                                   \
         : /*out*/   "=r" (_res)                                  \
         : /*in*/    "r" (&_argvec[2])                            \
         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
      );                                                          \
      lval = (__typeof__(lval)) _res;                             \
   } while (0)

#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
                                 arg7,arg8)                       \
   do {                                                           \
      volatile OrigFn        _orig = (orig);                      \
      volatile unsigned long _argvec[3+8];                        \
      volatile unsigned long _res;                                \
      /* _argvec[0] holds current r2 across the call */           \
      _argvec[1]   = (unsigned long)_orig.r2;                     \
      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
      _argvec[2+1] = (unsigned long)arg1;                         \
      _argvec[2+2] = (unsigned long)arg2;                         \
      _argvec[2+3] = (unsigned long)arg3;                         \
      _argvec[2+4] = (unsigned long)arg4;                         \
      _argvec[2+5] = (unsigned long)arg5;                         \
      _argvec[2+6] = (unsigned long)arg6;                         \
      _argvec[2+7] = (unsigned long)arg7;                         \
      _argvec[2+8] = (unsigned long)arg8;                         \
      __asm__ volatile(                                           \
         VALGRIND_ALIGN_STACK                                     \
         "mr 11,%1\n\t"                                           \
         "std 2,-16(11)\n\t"  /* save tocptr */                   \
         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
         "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
         "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
         "ld   8, 48(11)\n\t" /* arg6->r8 */                      \
         "ld   9, 56(11)\n\t" /* arg7->r9 */                      \
         "ld  10, 64(11)\n\t" /* arg8->r10 */                     \
         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
         "mr 11,%1\n\t"                                           \
         "mr %0,3\n\t"                                            \
         "ld 2,-16(11)\n\t" /* restore tocptr */                  \
         VALGRIND_RESTORE_STACK                                   \
         : /*out*/   "=r" (_res)                                  \
         : /*in*/    "r" (&_argvec[2])                            \
         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
      );                                                          \
      lval = (__typeof__(lval)) _res;                             \
   } while (0)

#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
                                 arg7,arg8,arg9)                  \
   do {                                                           \
      volatile OrigFn        _orig = (orig);                      \
      volatile unsigned long _argvec[3+9];                        \
      volatile unsigned long _res;                                \
      /* _argvec[0] holds current r2 across the call */           \
      _argvec[1]   = (unsigned long)_orig.r2;                     \
      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
      _argvec[2+1] = (unsigned long)arg1;                         \
      _argvec[2+2] = (unsigned long)arg2;                         \
      _argvec[2+3] = (unsigned long)arg3;                         \
      _argvec[2+4] = (unsigned long)arg4;                         \
      _argvec[2+5] = (unsigned long)arg5;                         \
      _argvec[2+6] = (unsigned long)arg6;                         \
      _argvec[2+7] = (unsigned long)arg7;                         \
      _argvec[2+8] = (unsigned long)arg8;                         \
      _argvec[2+9] = (unsigned long)arg9;                         \
      __asm__ volatile(                                           \
         VALGRIND_ALIGN_STACK                                     \
         "mr 11,%1\n\t"                                           \
         "std 2,-16(11)\n\t"  /* save tocptr */                   \
         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
         "addi 1,1,-128\n\t"  /* expand stack frame */            \
         /* arg9 */                                               \
         "ld  3,72(11)\n\t"                                       \
         "std 3,112(1)\n\t"                                       \
         /* args1-8 */                                            \
         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
         "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
         "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
         "ld   8, 48(11)\n\t" /* arg6->r8 */                      \
         "ld   9, 56(11)\n\t" /* arg7->r9 */                      \
         "ld  10, 64(11)\n\t" /* arg8->r10 */                     \
         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
         "mr 11,%1\n\t"                                           \
         "mr %0,3\n\t"                                            \
         "ld 2,-16(11)\n\t" /* restore tocptr */                  \
         VALGRIND_RESTORE_STACK                                   \
         : /*out*/   "=r" (_res)                                  \
         : /*in*/    "r" (&_argvec[2])                            \
         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
      );                                                          \
      lval = (__typeof__(lval)) _res;                             \
   } while (0)

#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
                                  arg7,arg8,arg9,arg10)           \
   do {                                                           \
      volatile OrigFn        _orig = (orig);                      \
      volatile unsigned long _argvec[3+10];                       \
      volatile unsigned long _res;                                \
      /* _argvec[0] holds current r2 across the call */           \
      _argvec[1]   = (unsigned long)_orig.r2;                     \
      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
      _argvec[2+1] = (unsigned long)arg1;                         \
      _argvec[2+2] = (unsigned long)arg2;                         \
      _argvec[2+3] = (unsigned long)arg3;                         \
      _argvec[2+4] = (unsigned long)arg4;                         \
      _argvec[2+5] = (unsigned long)arg5;                         \
      _argvec[2+6] = (unsigned long)arg6;                         \
      _argvec[2+7] = (unsigned long)arg7;                         \
      _argvec[2+8] = (unsigned long)arg8;                         \
      _argvec[2+9] = (unsigned long)arg9;                         \
      _argvec[2+10] = (unsigned long)arg10;                       \
      __asm__ volatile(                                           \
         VALGRIND_ALIGN_STACK                                     \
         "mr 11,%1\n\t"                                           \
         "std 2,-16(11)\n\t"  /* save tocptr */                   \
         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
         "addi 1,1,-128\n\t"  /* expand stack frame */            \
         /* arg10 */                                              \
         "ld  3,80(11)\n\t"                                       \
         "std 3,120(1)\n\t"                                       \
         /* arg9 */                                               \
         "ld  3,72(11)\n\t"                                       \
         "std 3,112(1)\n\t"                                       \
         /* args1-8 */                                            \
         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
         "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
         "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
         "ld   8, 48(11)\n\t" /* arg6->r8 */                      \
         "ld   9, 56(11)\n\t" /* arg7->r9 */                      \
         "ld  10, 64(11)\n\t" /* arg8->r10 */                     \
         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
         "mr 11,%1\n\t"                                           \
         "mr %0,3\n\t"                                            \
         "ld 2,-16(11)\n\t" /* restore tocptr */                  \
         VALGRIND_RESTORE_STACK                                   \
         : /*out*/   "=r" (_res)                                  \
         : /*in*/    "r" (&_argvec[2])                            \
         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
      );                                                          \
      lval = (__typeof__(lval)) _res;                             \
   } while (0)

#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
                                  arg7,arg8,arg9,arg10,arg11)     \
   do {                                                           \
      volatile OrigFn        _orig = (orig);                      \
      volatile unsigned long _argvec[3+11];                       \
      volatile unsigned long _res;                                \
      /* _argvec[0] holds current r2 across the call */           \
      _argvec[1]   = (unsigned long)_orig.r2;                     \
      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
      _argvec[2+1] = (unsigned long)arg1;                         \
      _argvec[2+2] = (unsigned long)arg2;                         \
      _argvec[2+3] = (unsigned long)arg3;                         \
      _argvec[2+4] = (unsigned long)arg4;                         \
      _argvec[2+5] = (unsigned long)arg5;                         \
      _argvec[2+6] = (unsigned long)arg6;                         \
      _argvec[2+7] = (unsigned long)arg7;                         \
      _argvec[2+8] = (unsigned long)arg8;                         \
      _argvec[2+9] = (unsigned long)arg9;                         \
      _argvec[2+10] = (unsigned long)arg10;                       \
      _argvec[2+11] = (unsigned long)arg11;                       \
      __asm__ volatile(                                           \
         VALGRIND_ALIGN_STACK                                     \
         "mr 11,%1\n\t"                                           \
         "std 2,-16(11)\n\t"  /* save tocptr */                   \
         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
         "addi 1,1,-144\n\t"  /* expand stack frame */            \
         /* arg11 */                                              \
         "ld  3,88(11)\n\t"                                       \
         "std 3,128(1)\n\t"                                       \
         /* arg10 */                                              \
         "ld  3,80(11)\n\t"                                       \
         "std 3,120(1)\n\t"                                       \
         /* arg9 */                                               \
         "ld  3,72(11)\n\t"                                       \
         "std 3,112(1)\n\t"                                       \
         /* args1-8 */                                            \
         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
         "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
         "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
         "ld   8, 48(11)\n\t" /* arg6->r8 */                      \
         "ld   9, 56(11)\n\t" /* arg7->r9 */                      \
         "ld  10, 64(11)\n\t" /* arg8->r10 */                     \
         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
         "mr 11,%1\n\t"                                           \
         "mr %0,3\n\t"                                            \
         "ld 2,-16(11)\n\t" /* restore tocptr */                  \
         VALGRIND_RESTORE_STACK                                   \
         : /*out*/   "=r" (_res)                                  \
         : /*in*/    "r" (&_argvec[2])                            \
         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
      );                                                          \
      lval = (__typeof__(lval)) _res;                             \
   } while (0)

#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
                                arg7,arg8,arg9,arg10,arg11,arg12) \
   do {                                                           \
      volatile OrigFn        _orig = (orig);                      \
      volatile unsigned long _argvec[3+12];                       \
      volatile unsigned long _res;                                \
      /* _argvec[0] holds current r2 across the call */           \
      _argvec[1]   = (unsigned long)_orig.r2;                     \
      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
      _argvec[2+1] = (unsigned long)arg1;                         \
      _argvec[2+2] = (unsigned long)arg2;                         \
      _argvec[2+3] = (unsigned long)arg3;                         \
      _argvec[2+4] = (unsigned long)arg4;                         \
      _argvec[2+5] = (unsigned long)arg5;                         \
      _argvec[2+6] = (unsigned long)arg6;                         \
      _argvec[2+7] = (unsigned long)arg7;                         \
      _argvec[2+8] = (unsigned long)arg8;                         \
      _argvec[2+9] = (unsigned long)arg9;                         \
      _argvec[2+10] = (unsigned long)arg10;                       \
      _argvec[2+11] = (unsigned long)arg11;                       \
      _argvec[2+12] = (unsigned long)arg12;                       \
      __asm__ volatile(                                           \
         VALGRIND_ALIGN_STACK                                     \
         "mr 11,%1\n\t"                                           \
         "std 2,-16(11)\n\t"  /* save tocptr */                   \
         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
         "addi 1,1,-144\n\t"  /* expand stack frame */            \
         /* arg12 */                                              \
         "ld  3,96(11)\n\t"                                       \
         "std 3,136(1)\n\t"                                       \
         /* arg11 */                                              \
         "ld  3,88(11)\n\t"                                       \
         "std 3,128(1)\n\t"                                       \
         /* arg10 */                                              \
         "ld  3,80(11)\n\t"                                       \
         "std 3,120(1)\n\t"                                       \
         /* arg9 */                                               \
         "ld  3,72(11)\n\t"                                       \
         "std 3,112(1)\n\t"                                       \
         /* args1-8 */                                            \
         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
         "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
         "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
         "ld   8, 48(11)\n\t" /* arg6->r8 */                      \
         "ld   9, 56(11)\n\t" /* arg7->r9 */                      \
         "ld  10, 64(11)\n\t" /* arg8->r10 */                     \
         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
         "mr 11,%1\n\t"                                           \
         "mr %0,3\n\t"                                            \
         "ld 2,-16(11)\n\t" /* restore tocptr */                  \
         VALGRIND_RESTORE_STACK                                   \
         : /*out*/   "=r" (_res)                                  \
         : /*in*/    "r" (&_argvec[2])                            \
         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
      );                                                          \
      lval = (__typeof__(lval)) _res;                             \
   } while (0)

#endif /* PLAT_ppc64be_linux */

/* ------------------------- ppc64le-linux ----------------------- */
#if defined(PLAT_ppc64le_linux)

/* ARGREGS: r3 r4 r5 r6 r7 r8 r9 r10 (the rest on stack somewhere) */

/* These regs are trashed by the hidden call. */
#define __CALLER_SAVED_REGS                                       \
   "lr", "ctr", "xer",                                            \
   "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7",        \
   "r0", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10",         \
   "r11", "r12", "r13"

/* Macros to save and align the stack before making a function
   call and restore it afterwards as gcc may not keep the stack
   pointer aligned if it doesn't realise calls are being made
   to other functions. */

#define VALGRIND_ALIGN_STACK               \
      "mr 28,1\n\t"                        \
      "rldicr 1,1,0,59\n\t"
#define VALGRIND_RESTORE_STACK             \
      "mr 1,28\n\t"

/* These CALL_FN_ macros assume that on ppc64-linux, sizeof(unsigned
   long) == 8. */

#define CALL_FN_W_v(lval, orig)                                   \
   do {                                                           \
      volatile OrigFn        _orig = (orig);                      \
      volatile unsigned long _argvec[3+0];                        \
      volatile unsigned long _res;                                \
      /* _argvec[0] holds current r2 across the call */           \
      _argvec[1] = (unsigned long)_orig.r2;                       \
      _argvec[2] = (unsigned long)_orig.nraddr;                   \
      __asm__ volatile(                                           \
         VALGRIND_ALIGN_STACK                                     \
         "mr 12,%1\n\t"                                           \
         "std 2,-16(12)\n\t"  /* save tocptr */                   \
         "ld   2,-8(12)\n\t"  /* use nraddr's tocptr */           \
         "ld  12, 0(12)\n\t"  /* target->r12 */                   \
         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R12                  \
         "mr 12,%1\n\t"                                           \
         "mr %0,3\n\t"                                            \
         "ld 2,-16(12)\n\t" /* restore tocptr */                  \
         VALGRIND_RESTORE_STACK                                   \
         : /*out*/   "=r" (_res)                                  \
         : /*in*/    "r" (&_argvec[2])                            \
         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
      );                                                          \
      lval = (__typeof__(lval)) _res;                             \
   } while (0)

#define CALL_FN_W_W(lval, orig, arg1)                             \
   do {                                                           \
      volatile OrigFn        _orig = (orig);                      \
      volatile unsigned long _argvec[3+1];                        \
      volatile unsigned long _res;                                \
      /* _argvec[0] holds current r2 across the call */           \
      _argvec[1]   = (unsigned long)_orig.r2;                     \
      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
      _argvec[2+1] = (unsigned long)arg1;                         \
      __asm__ volatile(                                           \
         VALGRIND_ALIGN_STACK                                     \
         "mr 12,%1\n\t"                                           \
         "std 2,-16(12)\n\t"  /* save tocptr */                   \
         "ld   2,-8(12)\n\t"  /* use nraddr's tocptr */           \
         "ld   3, 8(12)\n\t"  /* arg1->r3 */                      \
         "ld  12, 0(12)\n\t"  /* target->r12 */                   \
         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R12                  \
         "mr 12,%1\n\t"                                           \
         "mr %0,3\n\t"                                            \
         "ld 2,-16(12)\n\t" /* restore tocptr */                  \
         VALGRIND_RESTORE_STACK                                   \
         : /*out*/   "=r" (_res)                                  \
         : /*in*/    "r" (&_argvec[2])                            \
         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
      );                                                          \
      lval = (__typeof__(lval)) _res;                             \
   } while (0)

#define CALL_FN_W_WW(lval, orig, arg1,arg2)                       \
   do {                                                           \
      volatile OrigFn        _orig = (orig);                      \
      volatile unsigned long _argvec[3+2];                        \
      volatile unsigned long _res;                                \
      /* _argvec[0] holds current r2 across the call */           \
      _argvec[1]   = (unsigned long)_orig.r2;                     \
      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
      _argvec[2+1] = (unsigned long)arg1;                         \
      _argvec[2+2] = (unsigned long)arg2;                         \
      __asm__ volatile(                                           \
         VALGRIND_ALIGN_STACK                                     \
         "mr 12,%1\n\t"                                           \
         "std 2,-16(12)\n\t"  /* save tocptr */                   \
         "ld   2,-8(12)\n\t"  /* use nraddr's tocptr */           \
         "ld   3, 8(12)\n\t"  /* arg1->r3 */                      \
         "ld   4, 16(12)\n\t" /* arg2->r4 */                      \
         "ld  12, 0(12)\n\t"  /* target->r12 */                   \
         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R12                  \
         "mr 12,%1\n\t"                                           \
         "mr %0,3\n\t"                                            \
         "ld 2,-16(12)\n\t" /* restore tocptr */                  \
         VALGRIND_RESTORE_STACK                                   \
         : /*out*/   "=r" (_res)                                  \
         : /*in*/    "r" (&_argvec[2])                            \
         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
      );                                                          \
      lval = (__typeof__(lval)) _res;                             \
   } while (0)

#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3)                 \
   do {                                                           \
      volatile OrigFn        _orig = (orig);                      \
      volatile unsigned long _argvec[3+3];                        \
      volatile unsigned long _res;                                \
      /* _argvec[0] holds current r2 across the call */           \
      _argvec[1]   = (unsigned long)_orig.r2;                     \
      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
      _argvec[2+1] = (unsigned long)arg1;                         \
      _argvec[2+2] = (unsigned long)arg2;                         \
      _argvec[2+3] = (unsigned long)arg3;                         \
      __asm__ volatile(                                           \
         VALGRIND_ALIGN_STACK                                     \
         "mr 12,%1\n\t"                                           \
         "std 2,-16(12)\n\t"  /* save tocptr */                   \
         "ld   2,-8(12)\n\t"  /* use nraddr's tocptr */           \
         "ld   3, 8(12)\n\t"  /* arg1->r3 */                      \
         "ld   4, 16(12)\n\t" /* arg2->r4 */                      \
         "ld   5, 24(12)\n\t" /* arg3->r5 */                      \
         "ld  12, 0(12)\n\t"  /* target->r12 */                   \
         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R12                  \
         "mr 12,%1\n\t"                                           \
         "mr %0,3\n\t"                                            \
         "ld 2,-16(12)\n\t" /* restore tocptr */                  \
         VALGRIND_RESTORE_STACK                                   \
         : /*out*/   "=r" (_res)                                  \
         : /*in*/    "r" (&_argvec[2])                            \
         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
      );                                                          \
      lval = (__typeof__(lval)) _res;                             \
   } while (0)

#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4)           \
   do {                                                           \
      volatile OrigFn        _orig = (orig);                      \
      volatile unsigned long _argvec[3+4];                        \
      volatile unsigned long _res;                                \
      /* _argvec[0] holds current r2 across the call */           \
      _argvec[1]   = (unsigned long)_orig.r2;                     \
      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
      _argvec[2+1] = (unsigned long)arg1;                         \
      _argvec[2+2] = (unsigned long)arg2;                         \
      _argvec[2+3] = (unsigned long)arg3;                         \
      _argvec[2+4] = (unsigned long)arg4;                         \
      __asm__ volatile(                                           \
         VALGRIND_ALIGN_STACK                                     \
         "mr 12,%1\n\t"                                           \
         "std 2,-16(12)\n\t"  /* save tocptr */                   \
         "ld   2,-8(12)\n\t"  /* use nraddr's tocptr */           \
         "ld   3, 8(12)\n\t"  /* arg1->r3 */                      \
         "ld   4, 16(12)\n\t" /* arg2->r4 */                      \
         "ld   5, 24(12)\n\t" /* arg3->r5 */                      \
         "ld   6, 32(12)\n\t" /* arg4->r6 */                      \
         "ld  12, 0(12)\n\t"  /* target->r12 */                   \
         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R12                  \
         "mr 12,%1\n\t"                                           \
         "mr %0,3\n\t"                                            \
         "ld 2,-16(12)\n\t" /* restore tocptr */                  \
         VALGRIND_RESTORE_STACK                                   \
         : /*out*/   "=r" (_res)                                  \
         : /*in*/    "r" (&_argvec[2])                            \
         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
      );                                                          \
      lval = (__typeof__(lval)) _res;                             \
   } while (0)

#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5)        \
   do {                                                           \
      volatile OrigFn        _orig = (orig);                      \
      volatile unsigned long _argvec[3+5];                        \
      volatile unsigned long _res;                                \
      /* _argvec[0] holds current r2 across the call */           \
      _argvec[1]   = (unsigned long)_orig.r2;                     \
      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
      _argvec[2+1] = (unsigned long)arg1;                         \
      _argvec[2+2] = (unsigned long)arg2;                         \
      _argvec[2+3] = (unsigned long)arg3;                         \
      _argvec[2+4] = (unsigned long)arg4;                         \
      _argvec[2+5] = (unsigned long)arg5;                         \
      __asm__ volatile(                                           \
         VALGRIND_ALIGN_STACK                                     \
         "mr 12,%1\n\t"                                           \
         "std 2,-16(12)\n\t"  /* save tocptr */                   \
         "ld   2,-8(12)\n\t"  /* use nraddr's tocptr */           \
         "ld   3, 8(12)\n\t"  /* arg1->r3 */                      \
         "ld   4, 16(12)\n\t" /* arg2->r4 */                      \
         "ld   5, 24(12)\n\t" /* arg3->r5 */                      \
         "ld   6, 32(12)\n\t" /* arg4->r6 */                      \
         "ld   7, 40(12)\n\t" /* arg5->r7 */                      \
         "ld  12, 0(12)\n\t"  /* target->r12 */                   \
         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R12                  \
         "mr 12,%1\n\t"                                           \
         "mr %0,3\n\t"                                            \
         "ld 2,-16(12)\n\t" /* restore tocptr */                  \
         VALGRIND_RESTORE_STACK                                   \
         : /*out*/   "=r" (_res)                                  \
         : /*in*/    "r" (&_argvec[2])                            \
         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
      );                                                          \
      lval = (__typeof__(lval)) _res;                             \
   } while (0)

#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6)   \
   do {                                                           \
      volatile OrigFn        _orig = (orig);                      \
      volatile unsigned long _argvec[3+6];                        \
      volatile unsigned long _res;                                \
      /* _argvec[0] holds current r2 across the call */           \
      _argvec[1]   = (unsigned long)_orig.r2;                     \
      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
      _argvec[2+1] = (unsigned long)arg1;                         \
      _argvec[2+2] = (unsigned long)arg2;                         \
      _argvec[2+3] = (unsigned long)arg3;                         \
      _argvec[2+4] = (unsigned long)arg4;                         \
      _argvec[2+5] = (unsigned long)arg5;                         \
      _argvec[2+6] = (unsigned long)arg6;                         \
      __asm__ volatile(                                           \
         VALGRIND_ALIGN_STACK                                     \
         "mr 12,%1\n\t"                                           \
         "std 2,-16(12)\n\t"  /* save tocptr */                   \
         "ld   2,-8(12)\n\t"  /* use nraddr's tocptr */           \
         "ld   3, 8(12)\n\t"  /* arg1->r3 */                      \
         "ld   4, 16(12)\n\t" /* arg2->r4 */                      \
         "ld   5, 24(12)\n\t" /* arg3->r5 */                      \
         "ld   6, 32(12)\n\t" /* arg4->r6 */                      \
         "ld   7, 40(12)\n\t" /* arg5->r7 */                      \
         "ld   8, 48(12)\n\t" /* arg6->r8 */                      \
         "ld  12, 0(12)\n\t"  /* target->r12 */                   \
         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R12                  \
         "mr 12,%1\n\t"                                           \
         "mr %0,3\n\t"                                            \
         "ld 2,-16(12)\n\t" /* restore tocptr */                  \
         VALGRIND_RESTORE_STACK                                   \
         : /*out*/   "=r" (_res)                                  \
         : /*in*/    "r" (&_argvec[2])                            \
         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
      );                                                          \
      lval = (__typeof__(lval)) _res;                             \
   } while (0)

#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
                                 arg7)                            \
   do {                                                           \
      volatile OrigFn        _orig = (orig);                      \
      volatile unsigned long _argvec[3+7];                        \
      volatile unsigned long _res;                                \
      /* _argvec[0] holds current r2 across the call */           \
      _argvec[1]   = (unsigned long)_orig.r2;                     \
      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
      _argvec[2+1] = (unsigned long)arg1;                         \
      _argvec[2+2] = (unsigned long)arg2;                         \
      _argvec[2+3] = (unsigned long)arg3;                         \
      _argvec[2+4] = (unsigned long)arg4;                         \
      _argvec[2+5] = (unsigned long)arg5;                         \
      _argvec[2+6] = (unsigned long)arg6;                         \
      _argvec[2+7] = (unsigned long)arg7;                         \
      __asm__ volatile(                                           \
         VALGRIND_ALIGN_STACK                                     \
         "mr 12,%1\n\t"                                           \
         "std 2,-16(12)\n\t"  /* save tocptr */                   \
         "ld   2,-8(12)\n\t"  /* use nraddr's tocptr */           \
         "ld   3, 8(12)\n\t"  /* arg1->r3 */                      \
         "ld   4, 16(12)\n\t" /* arg2->r4 */                      \
         "ld   5, 24(12)\n\t" /* arg3->r5 */                      \
         "ld   6, 32(12)\n\t" /* arg4->r6 */                      \
         "ld   7, 40(12)\n\t" /* arg5->r7 */                      \
         "ld   8, 48(12)\n\t" /* arg6->r8 */                      \
         "ld   9, 56(12)\n\t" /* arg7->r9 */                      \
         "ld  12, 0(12)\n\t"  /* target->r12 */                   \
         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R12                  \
         "mr 12,%1\n\t"                                           \
         "mr %0,3\n\t"                                            \
         "ld 2,-16(12)\n\t" /* restore tocptr */                  \
         VALGRIND_RESTORE_STACK                                   \
         : /*out*/   "=r" (_res)                                  \
         : /*in*/    "r" (&_argvec[2])                            \
         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
      );                                                          \
      lval = (__typeof__(lval)) _res;                             \
   } while (0)

#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
                                 arg7,arg8)                       \
   do {                                                           \
      volatile OrigFn        _orig = (orig);                      \
      volatile unsigned long _argvec[3+8];                        \
      volatile unsigned long _res;                                \
      /* _argvec[0] holds current r2 across the call */           \
      _argvec[1]   = (unsigned long)_orig.r2;                     \
      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
      _argvec[2+1] = (unsigned long)arg1;                         \
      _argvec[2+2] = (unsigned long)arg2;                         \
      _argvec[2+3] = (unsigned long)arg3;                         \
      _argvec[2+4] = (unsigned long)arg4;                         \
      _argvec[2+5] = (unsigned long)arg5;                         \
      _argvec[2+6] = (unsigned long)arg6;                         \
      _argvec[2+7] = (unsigned long)arg7;                         \
      _argvec[2+8] = (unsigned long)arg8;                         \
      __asm__ volatile(                                           \
         VALGRIND_ALIGN_STACK                                     \
         "mr 12,%1\n\t"                                           \
         "std 2,-16(12)\n\t"  /* save tocptr */                   \
         "ld   2,-8(12)\n\t"  /* use nraddr's tocptr */           \
         "ld   3, 8(12)\n\t"  /* arg1->r3 */                      \
         "ld   4, 16(12)\n\t" /* arg2->r4 */                      \
         "ld   5, 24(12)\n\t" /* arg3->r5 */                      \
         "ld   6, 32(12)\n\t" /* arg4->r6 */                      \
         "ld   7, 40(12)\n\t" /* arg5->r7 */                      \
         "ld   8, 48(12)\n\t" /* arg6->r8 */                      \
         "ld   9, 56(12)\n\t" /* arg7->r9 */                      \
         "ld  10, 64(12)\n\t" /* arg8->r10 */                     \
         "ld  12, 0(12)\n\t"  /* target->r12 */                   \
         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R12                  \
         "mr 12,%1\n\t"                                           \
         "mr %0,3\n\t"                                            \
         "ld 2,-16(12)\n\t" /* restore tocptr */                  \
         VALGRIND_RESTORE_STACK                                   \
         : /*out*/   "=r" (_res)                                  \
         : /*in*/    "r" (&_argvec[2])                            \
         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
      );                                                          \
      lval = (__typeof__(lval)) _res;                             \
   } while (0)

#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
                                 arg7,arg8,arg9)                  \
   do {                                                           \
      volatile OrigFn        _orig = (orig);                      \
      volatile unsigned long _argvec[3+9];                        \
      volatile unsigned long _res;                                \
      /* _argvec[0] holds current r2 across the call */           \
      _argvec[1]   = (unsigned long)_orig.r2;                     \
      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
      _argvec[2+1] = (unsigned long)arg1;                         \
      _argvec[2+2] = (unsigned long)arg2;                         \
      _argvec[2+3] = (unsigned long)arg3;                         \
      _argvec[2+4] = (unsigned long)arg4;                         \
      _argvec[2+5] = (unsigned long)arg5;                         \
      _argvec[2+6] = (unsigned long)arg6;                         \
      _argvec[2+7] = (unsigned long)arg7;                         \
      _argvec[2+8] = (unsigned long)arg8;                         \
      _argvec[2+9] = (unsigned long)arg9;                         \
      __asm__ volatile(                                           \
         VALGRIND_ALIGN_STACK                                     \
         "mr 12,%1\n\t"                                           \
         "std 2,-16(12)\n\t"  /* save tocptr */                   \
         "ld   2,-8(12)\n\t"  /* use nraddr's tocptr */           \
         "addi 1,1,-128\n\t"  /* expand stack frame */            \
         /* arg9 */                                               \
         "ld  3,72(12)\n\t"                                       \
         "std 3,96(1)\n\t"                                        \
         /* args1-8 */                                            \
         "ld   3, 8(12)\n\t"  /* arg1->r3 */                      \
         "ld   4, 16(12)\n\t" /* arg2->r4 */                      \
         "ld   5, 24(12)\n\t" /* arg3->r5 */                      \
         "ld   6, 32(12)\n\t" /* arg4->r6 */                      \
         "ld   7, 40(12)\n\t" /* arg5->r7 */                      \
         "ld   8, 48(12)\n\t" /* arg6->r8 */                      \
         "ld   9, 56(12)\n\t" /* arg7->r9 */                      \
         "ld  10, 64(12)\n\t" /* arg8->r10 */                     \
         "ld  12, 0(12)\n\t"  /* target->r12 */                   \
         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R12                  \
         "mr 12,%1\n\t"                                           \
         "mr %0,3\n\t"                                            \
         "ld 2,-16(12)\n\t" /* restore tocptr */                  \
         VALGRIND_RESTORE_STACK                                   \
         : /*out*/   "=r" (_res)                                  \
         : /*in*/    "r" (&_argvec[2])                            \
         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
      );                                                          \
      lval = (__typeof__(lval)) _res;                             \
   } while (0)

#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
                                  arg7,arg8,arg9,arg10)           \
   do {                                                           \
      volatile OrigFn        _orig = (orig);                      \
      volatile unsigned long _argvec[3+10];                       \
      volatile unsigned long _res;                                \
      /* _argvec[0] holds current r2 across the call */           \
      _argvec[1]   = (unsigned long)_orig.r2;                     \
      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
      _argvec[2+1] = (unsigned long)arg1;                         \
      _argvec[2+2] = (unsigned long)arg2;                         \
      _argvec[2+3] = (unsigned long)arg3;                         \
      _argvec[2+4] = (unsigned long)arg4;                         \
      _argvec[2+5] = (unsigned long)arg5;                         \
      _argvec[2+6] = (unsigned long)arg6;                         \
      _argvec[2+7] = (unsigned long)arg7;                         \
      _argvec[2+8] = (unsigned long)arg8;                         \
      _argvec[2+9] = (unsigned long)arg9;                         \
      _argvec[2+10] = (unsigned long)arg10;                       \
      __asm__ volatile(                                           \
         VALGRIND_ALIGN_STACK                                     \
         "mr 12,%1\n\t"                                           \
         "std 2,-16(12)\n\t"  /* save tocptr */                   \
         "ld   2,-8(12)\n\t"  /* use nraddr's tocptr */           \
         "addi 1,1,-128\n\t"  /* expand stack frame */            \
         /* arg10 */                                              \
         "ld  3,80(12)\n\t"                                       \
         "std 3,104(1)\n\t"                                       \
         /* arg9 */                                               \
         "ld  3,72(12)\n\t"                                       \
         "std 3,96(1)\n\t"                                        \
         /* args1-8 */                                            \
         "ld   3, 8(12)\n\t"  /* arg1->r3 */                      \
         "ld   4, 16(12)\n\t" /* arg2->r4 */                      \
         "ld   5, 24(12)\n\t" /* arg3->r5 */                      \
         "ld   6, 32(12)\n\t" /* arg4->r6 */                      \
         "ld   7, 40(12)\n\t" /* arg5->r7 */                      \
         "ld   8, 48(12)\n\t" /* arg6->r8 */                      \
         "ld   9, 56(12)\n\t" /* arg7->r9 */                      \
         "ld  10, 64(12)\n\t" /* arg8->r10 */                     \
         "ld  12, 0(12)\n\t"  /* target->r12 */                   \
         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R12                  \
         "mr 12,%1\n\t"                                           \
         "mr %0,3\n\t"                                            \
         "ld 2,-16(12)\n\t" /* restore tocptr */                  \
         VALGRIND_RESTORE_STACK                                   \
         : /*out*/   "=r" (_res)                                  \
         : /*in*/    "r" (&_argvec[2])                            \
         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
      );                                                          \
      lval = (__typeof__(lval)) _res;                             \
   } while (0)

#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
                                  arg7,arg8,arg9,arg10,arg11)     \
   do {                                                           \
      volatile OrigFn        _orig = (orig);                      \
      volatile unsigned long _argvec[3+11];                       \
      volatile unsigned long _res;                                \
      /* _argvec[0] holds current r2 across the call */           \
      _argvec[1]   = (unsigned long)_orig.r2;                     \
      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
      _argvec[2+1] = (unsigned long)arg1;                         \
      _argvec[2+2] = (unsigned long)arg2;                         \
      _argvec[2+3] = (unsigned long)arg3;                         \
      _argvec[2+4] = (unsigned long)arg4;                         \
      _argvec[2+5] = (unsigned long)arg5;                         \
      _argvec[2+6] = (unsigned long)arg6;                         \
      _argvec[2+7] = (unsigned long)arg7;                         \
      _argvec[2+8] = (unsigned long)arg8;                         \
      _argvec[2+9] = (unsigned long)arg9;                         \
      _argvec[2+10] = (unsigned long)arg10;                       \
      _argvec[2+11] = (unsigned long)arg11;                       \
      __asm__ volatile(                                           \
         VALGRIND_ALIGN_STACK                                     \
         "mr 12,%1\n\t"                                           \
         "std 2,-16(12)\n\t"  /* save tocptr */                   \
         "ld   2,-8(12)\n\t"  /* use nraddr's tocptr */           \
         "addi 1,1,-144\n\t"  /* expand stack frame */            \
         /* arg11 */                                              \
         "ld  3,88(12)\n\t"                                       \
         "std 3,112(1)\n\t"                                       \
         /* arg10 */                                              \
         "ld  3,80(12)\n\t"                                       \
         "std 3,104(1)\n\t"                                       \
         /* arg9 */                                               \
         "ld  3,72(12)\n\t"                                       \
         "std 3,96(1)\n\t"                                        \
         /* args1-8 */                                            \
         "ld   3, 8(12)\n\t"  /* arg1->r3 */                      \
         "ld   4, 16(12)\n\t" /* arg2->r4 */                      \
         "ld   5, 24(12)\n\t" /* arg3->r5 */                      \
         "ld   6, 32(12)\n\t" /* arg4->r6 */                      \
         "ld   7, 40(12)\n\t" /* arg5->r7 */                      \
         "ld   8, 48(12)\n\t" /* arg6->r8 */                      \
         "ld   9, 56(12)\n\t" /* arg7->r9 */                      \
         "ld  10, 64(12)\n\t" /* arg8->r10 */                     \
         "ld  12, 0(12)\n\t"  /* target->r12 */                   \
         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R12                  \
         "mr 12,%1\n\t"                                           \
         "mr %0,3\n\t"                                            \
         "ld 2,-16(12)\n\t" /* restore tocptr */                  \
         VALGRIND_RESTORE_STACK                                   \
         : /*out*/   "=r" (_res)                                  \
         : /*in*/    "r" (&_argvec[2])                            \
         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
      );                                                          \
      lval = (__typeof__(lval)) _res;                             \
   } while (0)

#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
                                arg7,arg8,arg9,arg10,arg11,arg12) \
   do {                                                           \
      volatile OrigFn        _orig = (orig);                      \
      volatile unsigned long _argvec[3+12];                       \
      volatile unsigned long _res;                                \
      /* _argvec[0] holds current r2 across the call */           \
      _argvec[1]   = (unsigned long)_orig.r2;                     \
      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
      _argvec[2+1] = (unsigned long)arg1;                         \
      _argvec[2+2] = (unsigned long)arg2;                         \
      _argvec[2+3] = (unsigned long)arg3;                         \
      _argvec[2+4] = (unsigned long)arg4;                         \
      _argvec[2+5] = (unsigned long)arg5;                         \
      _argvec[2+6] = (unsigned long)arg6;                         \
      _argvec[2+7] = (unsigned long)arg7;                         \
      _argvec[2+8] = (unsigned long)arg8;                         \
      _argvec[2+9] = (unsigned long)arg9;                         \
      _argvec[2+10] = (unsigned long)arg10;                       \
      _argvec[2+11] = (unsigned long)arg11;                       \
      _argvec[2+12] = (unsigned long)arg12;                       \
      __asm__ volatile(                                           \
         VALGRIND_ALIGN_STACK                                     \
         "mr 12,%1\n\t"                                           \
         "std 2,-16(12)\n\t"  /* save tocptr */                   \
         "ld   2,-8(12)\n\t"  /* use nraddr's tocptr */           \
         "addi 1,1,-144\n\t"  /* expand stack frame */            \
         /* arg12 */                                              \
         "ld  3,96(12)\n\t"                                       \
         "std 3,120(1)\n\t"                                       \
         /* arg11 */                                              \
         "ld  3,88(12)\n\t"                                       \
         "std 3,112(1)\n\t"                                       \
         /* arg10 */                                              \
         "ld  3,80(12)\n\t"                                       \
         "std 3,104(1)\n\t"                                       \
         /* arg9 */                                               \
         "ld  3,72(12)\n\t"                                       \
         "std 3,96(1)\n\t"                                        \
         /* args1-8 */                                            \
         "ld   3, 8(12)\n\t"  /* arg1->r3 */                      \
         "ld   4, 16(12)\n\t" /* arg2->r4 */                      \
         "ld   5, 24(12)\n\t" /* arg3->r5 */                      \
         "ld   6, 32(12)\n\t" /* arg4->r6 */                      \
         "ld   7, 40(12)\n\t" /* arg5->r7 */                      \
         "ld   8, 48(12)\n\t" /* arg6->r8 */                      \
         "ld   9, 56(12)\n\t" /* arg7->r9 */                      \
         "ld  10, 64(12)\n\t" /* arg8->r10 */                     \
         "ld  12, 0(12)\n\t"  /* target->r12 */                   \
         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R12                  \
         "mr 12,%1\n\t"                                           \
         "mr %0,3\n\t"                                            \
         "ld 2,-16(12)\n\t" /* restore tocptr */                  \
         VALGRIND_RESTORE_STACK                                   \
         : /*out*/   "=r" (_res)                                  \
         : /*in*/    "r" (&_argvec[2])                            \
         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
      );                                                          \
      lval = (__typeof__(lval)) _res;                             \
   } while (0)

#endif /* PLAT_ppc64le_linux */

/* ------------------------- arm-linux ------------------------- */

#if defined(PLAT_arm_linux)

/* These regs are trashed by the hidden call. */
#define __CALLER_SAVED_REGS "r0", "r1", "r2", "r3","r4", "r12", "r14"

/* Macros to save and align the stack before making a function
   call and restore it afterwards as gcc may not keep the stack
   pointer aligned if it doesn't realise calls are being made
   to other functions. */

/* This is a bit tricky.  We store the original stack pointer in r10
   as it is callee-saves.  gcc doesn't allow the use of r11 for some
   reason.  Also, we can't directly "bic" the stack pointer in thumb
   mode since r13 isn't an allowed register number in that context.
   So use r4 as a temporary, since that is about to get trashed
   anyway, just after each use of this macro.  Side effect is we need
   to be very careful about any future changes, since
   VALGRIND_ALIGN_STACK simply assumes r4 is usable. */
#define VALGRIND_ALIGN_STACK               \
      "mov r10, sp\n\t"                    \
      "mov r4,  sp\n\t"                    \
      "bic r4,  r4, #7\n\t"                \
      "mov sp,  r4\n\t"
#define VALGRIND_RESTORE_STACK             \
      "mov sp,  r10\n\t"

/* These CALL_FN_ macros assume that on arm-linux, sizeof(unsigned
   long) == 4. */

#define CALL_FN_W_v(lval, orig)                                   \
   do {                                                           \
      volatile OrigFn        _orig = (orig);                      \
      volatile unsigned long _argvec[1];                          \
      volatile unsigned long _res;                                \
      _argvec[0] = (unsigned long)_orig.nraddr;                   \
      __asm__ volatile(                                           \
         VALGRIND_ALIGN_STACK                                     \
         "ldr r4, [%1] \n\t"  /* target->r4 */                    \
         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4                   \
         VALGRIND_RESTORE_STACK                                   \
         "mov %0, r0\n"                                           \
         : /*out*/   "=r" (_res)                                  \
         : /*in*/    "0" (&_argvec[0])                            \
         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10"   \
      );                                                          \
      lval = (__typeof__(lval)) _res;                             \
   } while (0)

#define CALL_FN_W_W(lval, orig, arg1)                             \
   do {                                                           \
      volatile OrigFn        _orig = (orig);                      \
      volatile unsigned long _argvec[2];                          \
      volatile unsigned long _res;                                \
      _argvec[0] = (unsigned long)_orig.nraddr;                   \
      _argvec[1] = (unsigned long)(arg1);                         \
      __asm__ volatile(                                           \
         VALGRIND_ALIGN_STACK                                     \
         "ldr r0, [%1, #4] \n\t"                                  \
         "ldr r4, [%1] \n\t"  /* target->r4 */                    \
         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4                   \
         VALGRIND_RESTORE_STACK                                   \
         "mov %0, r0\n"                                           \
         : /*out*/   "=r" (_res)                                  \
         : /*in*/    "0" (&_argvec[0])                            \
         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10"   \
      );                                                          \
      lval = (__typeof__(lval)) _res;                             \
   } while (0)

#define CALL_FN_W_WW(lval, orig, arg1,arg2)                       \
   do {                                                           \
      volatile OrigFn        _orig = (orig);                      \
      volatile unsigned long _argvec[3];                          \
      volatile unsigned long _res;                                \
      _argvec[0] = (unsigned long)_orig.nraddr;                   \
      _argvec[1] = (unsigned long)(arg1);                         \
      _argvec[2] = (unsigned long)(arg2);                         \
      __asm__ volatile(                                           \
         VALGRIND_ALIGN_STACK                                     \
         "ldr r0, [%1, #4] \n\t"                                  \
         "ldr r1, [%1, #8] \n\t"                                  \
         "ldr r4, [%1] \n\t"  /* target->r4 */                    \
         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4                   \
         VALGRIND_RESTORE_STACK                                   \
         "mov %0, r0\n"                                           \
         : /*out*/   "=r" (_res)                                  \
         : /*in*/    "0" (&_argvec[0])                            \
         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10"   \
      );                                                          \
      lval = (__typeof__(lval)) _res;                             \
   } while (0)

#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3)                 \
   do {                                                           \
      volatile OrigFn        _orig = (orig);                      \
      volatile unsigned long _argvec[4];                          \
      volatile unsigned long _res;                                \
      _argvec[0] = (unsigned long)_orig.nraddr;                   \
      _argvec[1] = (unsigned long)(arg1);                         \
      _argvec[2] = (unsigned long)(arg2);                         \
      _argvec[3] = (unsigned long)(arg3);                         \
      __asm__ volatile(                                           \
         VALGRIND_ALIGN_STACK                                     \
         "ldr r0, [%1, #4] \n\t"                                  \
         "ldr r1, [%1, #8] \n\t"                                  \
         "ldr r2, [%1, #12] \n\t"                                 \
         "ldr r4, [%1] \n\t"  /* target->r4 */                    \
         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4                   \
         VALGRIND_RESTORE_STACK                                   \
         "mov %0, r0\n"                                           \
         : /*out*/   "=r" (_res)                                  \
         : /*in*/    "0" (&_argvec[0])                            \
         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10"   \
      );                                                          \
      lval = (__typeof__(lval)) _res;                             \
   } while (0)

#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4)           \
   do {                                                           \
      volatile OrigFn        _orig = (orig);                      \
      volatile unsigned long _argvec[5];                          \
      volatile unsigned long _res;                                \
      _argvec[0] = (unsigned long)_orig.nraddr;                   \
      _argvec[1] = (unsigned long)(arg1);                         \
      _argvec[2] = (unsigned long)(arg2);                         \
      _argvec[3] = (unsigned long)(arg3);                         \
      _argvec[4] = (unsigned long)(arg4);                         \
      __asm__ volatile(                                           \
         VALGRIND_ALIGN_STACK                                     \
         "ldr r0, [%1, #4] \n\t"                                  \
         "ldr r1, [%1, #8] \n\t"                                  \
         "ldr r2, [%1, #12] \n\t"                                 \
         "ldr r3, [%1, #16] \n\t"                                 \
         "ldr r4, [%1] \n\t"  /* target->r4 */                    \
         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4                   \
         VALGRIND_RESTORE_STACK                                   \
         "mov %0, r0"                                             \
         : /*out*/   "=r" (_res)                                  \
         : /*in*/    "0" (&_argvec[0])                            \
         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10"   \
      );                                                          \
      lval = (__typeof__(lval)) _res;                             \
   } while (0)

#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5)        \
   do {                                                           \
      volatile OrigFn        _orig = (orig);                      \
      volatile unsigned long _argvec[6];                          \
      volatile unsigned long _res;                                \
      _argvec[0] = (unsigned long)_orig.nraddr;                   \
      _argvec[1] = (unsigned long)(arg1);                         \
      _argvec[2] = (unsigned long)(arg2);                         \
      _argvec[3] = (unsigned long)(arg3);                         \
      _argvec[4] = (unsigned long)(arg4);                         \
      _argvec[5] = (unsigned long)(arg5);                         \
      __asm__ volatile(                                           \
         VALGRIND_ALIGN_STACK                                     \
         "sub sp, sp, #4 \n\t"                                    \
         "ldr r0, [%1, #20] \n\t"                                 \
         "push {r0} \n\t"                                         \
         "ldr r0, [%1, #4] \n\t"                                  \
         "ldr r1, [%1, #8] \n\t"                                  \
         "ldr r2, [%1, #12] \n\t"                                 \
         "ldr r3, [%1, #16] \n\t"                                 \
         "ldr r4, [%1] \n\t"  /* target->r4 */                    \
         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4                   \
         VALGRIND_RESTORE_STACK                                   \
         "mov %0, r0"                                             \
         : /*out*/   "=r" (_res)                                  \
         : /*in*/    "0" (&_argvec[0])                            \
         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10"   \
      );                                                          \
      lval = (__typeof__(lval)) _res;                             \
   } while (0)

#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6)   \
   do {                                                           \
      volatile OrigFn        _orig = (orig);                      \
      volatile unsigned long _argvec[7];                          \
      volatile unsigned long _res;                                \
      _argvec[0] = (unsigned long)_orig.nraddr;                   \
      _argvec[1] = (unsigned long)(arg1);                         \
      _argvec[2] = (unsigned long)(arg2);                         \
      _argvec[3] = (unsigned long)(arg3);                         \
      _argvec[4] = (unsigned long)(arg4);                         \
      _argvec[5] = (unsigned long)(arg5);                         \
      _argvec[6] = (unsigned long)(arg6);                         \
      __asm__ volatile(                                           \
         VALGRIND_ALIGN_STACK                                     \
         "ldr r0, [%1, #20] \n\t"                                 \
         "ldr r1, [%1, #24] \n\t"                                 \
         "push {r0, r1} \n\t"                                     \
         "ldr r0, [%1, #4] \n\t"                                  \
         "ldr r1, [%1, #8] \n\t"                                  \
         "ldr r2, [%1, #12] \n\t"                                 \
         "ldr r3, [%1, #16] \n\t"                                 \
         "ldr r4, [%1] \n\t"  /* target->r4 */                    \
         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4                   \
         VALGRIND_RESTORE_STACK                                   \
         "mov %0, r0"                                             \
         : /*out*/   "=r" (_res)                                  \
         : /*in*/    "0" (&_argvec[0])                            \
         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10"   \
      );                                                          \
      lval = (__typeof__(lval)) _res;                             \
   } while (0)

#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
                                 arg7)                            \
   do {                                                           \
      volatile OrigFn        _orig = (orig);                      \
      volatile unsigned long _argvec[8];                          \
      volatile unsigned long _res;                                \
      _argvec[0] = (unsigned long)_orig.nraddr;                   \
      _argvec[1] = (unsigned long)(arg1);                         \
      _argvec[2] = (unsigned long)(arg2);                         \
      _argvec[3] = (unsigned long)(arg3);                         \
      _argvec[4] = (unsigned long)(arg4);                         \
      _argvec[5] = (unsigned long)(arg5);                         \
      _argvec[6] = (unsigned long)(arg6);                         \
      _argvec[7] = (unsigned long)(arg7);                         \
      __asm__ volatile(                                           \
         VALGRIND_ALIGN_STACK                                     \
         "sub sp, sp, #4 \n\t"                                    \
         "ldr r0, [%1, #20] \n\t"                                 \
         "ldr r1, [%1, #24] \n\t"                                 \
         "ldr r2, [%1, #28] \n\t"                                 \
         "push {r0, r1, r2} \n\t"                                 \
         "ldr r0, [%1, #4] \n\t"                                  \
         "ldr r1, [%1, #8] \n\t"                                  \
         "ldr r2, [%1, #12] \n\t"                                 \
         "ldr r3, [%1, #16] \n\t"                                 \
         "ldr r4, [%1] \n\t"  /* target->r4 */                    \
         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4                   \
         VALGRIND_RESTORE_STACK                                   \
         "mov %0, r0"                                             \
         : /*out*/   "=r" (_res)                                  \
         : /*in*/    "0" (&_argvec[0])                            \
         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10"   \
      );                                                          \
      lval = (__typeof__(lval)) _res;                             \
   } while (0)

#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
                                 arg7,arg8)                       \
   do {                                                           \
      volatile OrigFn        _orig = (orig);                      \
      volatile unsigned long _argvec[9];                          \
      volatile unsigned long _res;                                \
      _argvec[0] = (unsigned long)_orig.nraddr;                   \
      _argvec[1] = (unsigned long)(arg1);                         \
      _argvec[2] = (unsigned long)(arg2);                         \
      _argvec[3] = (unsigned long)(arg3);                         \
      _argvec[4] = (unsigned long)(arg4);                         \
      _argvec[5] = (unsigned long)(arg5);                         \
      _argvec[6] = (unsigned long)(arg6);                         \
      _argvec[7] = (unsigned long)(arg7);                         \
      _argvec[8] = (unsigned long)(arg8);                         \
      __asm__ volatile(                                           \
         VALGRIND_ALIGN_STACK                                     \
         "ldr r0, [%1, #20] \n\t"                                 \
         "ldr r1, [%1, #24] \n\t"                                 \
         "ldr r2, [%1, #28] \n\t"                                 \
         "ldr r3, [%1, #32] \n\t"                                 \
         "push {r0, r1, r2, r3} \n\t"                             \
         "ldr r0, [%1, #4] \n\t"                                  \
         "ldr r1, [%1, #8] \n\t"                                  \
         "ldr r2, [%1, #12] \n\t"                                 \
         "ldr r3, [%1, #16] \n\t"                                 \
         "ldr r4, [%1] \n\t"  /* target->r4 */                    \
         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4                   \
         VALGRIND_RESTORE_STACK                                   \
         "mov %0, r0"                                             \
         : /*out*/   "=r" (_res)                                  \
         : /*in*/    "0" (&_argvec[0])                            \
         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10"   \
      );                                                          \
      lval = (__typeof__(lval)) _res;                             \
   } while (0)

#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
                                 arg7,arg8,arg9)                  \
   do {                                                           \
      volatile OrigFn        _orig = (orig);                      \
      volatile unsigned long _argvec[10];                         \
      volatile unsigned long _res;                                \
      _argvec[0] = (unsigned long)_orig.nraddr;                   \
      _argvec[1] = (unsigned long)(arg1);                         \
      _argvec[2] = (unsigned long)(arg2);                         \
      _argvec[3] = (unsigned long)(arg3);                         \
      _argvec[4] = (unsigned long)(arg4);                         \
      _argvec[5] = (unsigned long)(arg5);                         \
      _argvec[6] = (unsigned long)(arg6);                         \
      _argvec[7] = (unsigned long)(arg7);                         \
      _argvec[8] = (unsigned long)(arg8);                         \
      _argvec[9] = (unsigned long)(arg9);                         \
      __asm__ volatile(                                           \
         VALGRIND_ALIGN_STACK                                     \
         "sub sp, sp, #4 \n\t"                                    \
         "ldr r0, [%1, #20] \n\t"                                 \
         "ldr r1, [%1, #24] \n\t"                                 \
         "ldr r2, [%1, #28] \n\t"                                 \
         "ldr r3, [%1, #32] \n\t"                                 \
         "ldr r4, [%1, #36] \n\t"                                 \
         "push {r0, r1, r2, r3, r4} \n\t"                         \
         "ldr r0, [%1, #4] \n\t"                                  \
         "ldr r1, [%1, #8] \n\t"                                  \
         "ldr r2, [%1, #12] \n\t"                                 \
         "ldr r3, [%1, #16] \n\t"                                 \
         "ldr r4, [%1] \n\t"  /* target->r4 */                    \
         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4                   \
         VALGRIND_RESTORE_STACK                                   \
         "mov %0, r0"                                             \
         : /*out*/   "=r" (_res)                                  \
         : /*in*/    "0" (&_argvec[0])                            \
         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10"   \
      );                                                          \
      lval = (__typeof__(lval)) _res;                             \
   } while (0)

#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
                                  arg7,arg8,arg9,arg10)           \
   do {                                                           \
      volatile OrigFn        _orig = (orig);                      \
      volatile unsigned long _argvec[11];                         \
      volatile unsigned long _res;                                \
      _argvec[0] = (unsigned long)_orig.nraddr;                   \
      _argvec[1] = (unsigned long)(arg1);                         \
      _argvec[2] = (unsigned long)(arg2);                         \
      _argvec[3] = (unsigned long)(arg3);                         \
      _argvec[4] = (unsigned long)(arg4);                         \
      _argvec[5] = (unsigned long)(arg5);                         \
      _argvec[6] = (unsigned long)(arg6);                         \
      _argvec[7] = (unsigned long)(arg7);                         \
      _argvec[8] = (unsigned long)(arg8);                         \
      _argvec[9] = (unsigned long)(arg9);                         \
      _argvec[10] = (unsigned long)(arg10);                       \
      __asm__ volatile(                                           \
         VALGRIND_ALIGN_STACK                                     \
         "ldr r0, [%1, #40] \n\t"                                 \
         "push {r0} \n\t"                                         \
         "ldr r0, [%1, #20] \n\t"                                 \
         "ldr r1, [%1, #24] \n\t"                                 \
         "ldr r2, [%1, #28] \n\t"                                 \
         "ldr r3, [%1, #32] \n\t"                                 \
         "ldr r4, [%1, #36] \n\t"                                 \
         "push {r0, r1, r2, r3, r4} \n\t"                         \
         "ldr r0, [%1, #4] \n\t"                                  \
         "ldr r1, [%1, #8] \n\t"                                  \
         "ldr r2, [%1, #12] \n\t"                                 \
         "ldr r3, [%1, #16] \n\t"                                 \
         "ldr r4, [%1] \n\t"  /* target->r4 */                    \
         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4                   \
         VALGRIND_RESTORE_STACK                                   \
         "mov %0, r0"                                             \
         : /*out*/   "=r" (_res)                                  \
         : /*in*/    "0" (&_argvec[0])                            \
         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10"   \
      );                                                          \
      lval = (__typeof__(lval)) _res;                             \
   } while (0)

#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,       \
                                  arg6,arg7,arg8,arg9,arg10,      \
                                  arg11)                          \
   do {                                                           \
      volatile OrigFn        _orig = (orig);                      \
      volatile unsigned long _argvec[12];                         \
      volatile unsigned long _res;                                \
      _argvec[0] = (unsigned long)_orig.nraddr;                   \
      _argvec[1] = (unsigned long)(arg1);                         \
      _argvec[2] = (unsigned long)(arg2);                         \
      _argvec[3] = (unsigned long)(arg3);                         \
      _argvec[4] = (unsigned long)(arg4);                         \
      _argvec[5] = (unsigned long)(arg5);                         \
      _argvec[6] = (unsigned long)(arg6);                         \
      _argvec[7] = (unsigned long)(arg7);                         \
      _argvec[8] = (unsigned long)(arg8);                         \
      _argvec[9] = (unsigned long)(arg9);                         \
      _argvec[10] = (unsigned long)(arg10);                       \
      _argvec[11] = (unsigned long)(arg11);                       \
      __asm__ volatile(                                           \
         VALGRIND_ALIGN_STACK                                     \
         "sub sp, sp, #4 \n\t"                                    \
         "ldr r0, [%1, #40] \n\t"                                 \
         "ldr r1, [%1, #44] \n\t"                                 \
         "push {r0, r1} \n\t"                                     \
         "ldr r0, [%1, #20] \n\t"                                 \
         "ldr r1, [%1, #24] \n\t"                                 \
         "ldr r2, [%1, #28] \n\t"                                 \
         "ldr r3, [%1, #32] \n\t"                                 \
         "ldr r4, [%1, #36] \n\t"                                 \
         "push {r0, r1, r2, r3, r4} \n\t"                         \
         "ldr r0, [%1, #4] \n\t"                                  \
         "ldr r1, [%1, #8] \n\t"                                  \
         "ldr r2, [%1, #12] \n\t"                                 \
         "ldr r3, [%1, #16] \n\t"                                 \
         "ldr r4, [%1] \n\t"  /* target->r4 */                    \
         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4                   \
         VALGRIND_RESTORE_STACK                                   \
         "mov %0, r0"                                             \
         : /*out*/   "=r" (_res)                                  \
         : /*in*/    "0" (&_argvec[0])                            \
         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10"   \
      );                                                          \
      lval = (__typeof__(lval)) _res;                             \
   } while (0)

#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,       \
                                  arg6,arg7,arg8,arg9,arg10,      \
                                  arg11,arg12)                    \
   do {                                                           \
      volatile OrigFn        _orig = (orig);                      \
      volatile unsigned long _argvec[13];                         \
      volatile unsigned long _res;                                \
      _argvec[0] = (unsigned long)_orig.nraddr;                   \
      _argvec[1] = (unsigned long)(arg1);                         \
      _argvec[2] = (unsigned long)(arg2);                         \
      _argvec[3] = (unsigned long)(arg3);                         \
      _argvec[4] = (unsigned long)(arg4);                         \
      _argvec[5] = (unsigned long)(arg5);                         \
      _argvec[6] = (unsigned long)(arg6);                         \
      _argvec[7] = (unsigned long)(arg7);                         \
      _argvec[8] = (unsigned long)(arg8);                         \
      _argvec[9] = (unsigned long)(arg9);                         \
      _argvec[10] = (unsigned long)(arg10);                       \
      _argvec[11] = (unsigned long)(arg11);                       \
      _argvec[12] = (unsigned long)(arg12);                       \
      __asm__ volatile(                                           \
         VALGRIND_ALIGN_STACK                                     \
         "ldr r0, [%1, #40] \n\t"                                 \
         "ldr r1, [%1, #44] \n\t"                                 \
         "ldr r2, [%1, #48] \n\t"                                 \
         "push {r0, r1, r2} \n\t"                                 \
         "ldr r0, [%1, #20] \n\t"                                 \
         "ldr r1, [%1, #24] \n\t"                                 \
         "ldr r2, [%1, #28] \n\t"                                 \
         "ldr r3, [%1, #32] \n\t"                                 \
         "ldr r4, [%1, #36] \n\t"                                 \
         "push {r0, r1, r2, r3, r4} \n\t"                         \
         "ldr r0, [%1, #4] \n\t"                                  \
         "ldr r1, [%1, #8] \n\t"                                  \
         "ldr r2, [%1, #12] \n\t"                                 \
         "ldr r3, [%1, #16] \n\t"                                 \
         "ldr r4, [%1] \n\t"  /* target->r4 */                    \
         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4                   \
         VALGRIND_RESTORE_STACK                                   \
         "mov %0, r0"                                             \
         : /*out*/   "=r" (_res)                                  \
         : /*in*/    "0" (&_argvec[0])                            \
         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10"   \
      );                                                          \
      lval = (__typeof__(lval)) _res;                             \
   } while (0)

#endif /* PLAT_arm_linux */

/* ------------------------ arm64-linux ------------------------ */

#if defined(PLAT_arm64_linux)

/* These regs are trashed by the hidden call. */
#define __CALLER_SAVED_REGS \
     "x0", "x1", "x2", "x3","x4", "x5", "x6", "x7", "x8", "x9",   \
     "x10", "x11", "x12", "x13", "x14", "x15", "x16", "x17",      \
     "x18", "x19", "x20", "x30",                                  \
     "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9",  \
     "v10", "v11", "v12", "v13", "v14", "v15", "v16", "v17",      \
     "v18", "v19", "v20", "v21", "v22", "v23", "v24", "v25",      \
     "v26", "v27", "v28", "v29", "v30", "v31"

/* x21 is callee-saved, so we can use it to save and restore SP around
   the hidden call. */
#define VALGRIND_ALIGN_STACK               \
      "mov x21, sp\n\t"                    \
      "bic sp, x21, #15\n\t"
#define VALGRIND_RESTORE_STACK             \
      "mov sp,  x21\n\t"

/* These CALL_FN_ macros assume that on arm64-linux,
   sizeof(unsigned long) == 8. */

#define CALL_FN_W_v(lval, orig)                                   \
   do {                                                           \
      volatile OrigFn        _orig = (orig);                      \
      volatile unsigned long _argvec[1];                          \
      volatile unsigned long _res;                                \
      _argvec[0] = (unsigned long)_orig.nraddr;                   \
      __asm__ volatile(                                           \
         VALGRIND_ALIGN_STACK                                     \
         "ldr x8, [%1] \n\t"  /* target->x8 */                    \
         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_X8                   \
         VALGRIND_RESTORE_STACK                                   \
         "mov %0, x0\n"                                           \
         : /*out*/   "=r" (_res)                                  \
         : /*in*/    "0" (&_argvec[0])                            \
         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "x21"   \
      );                                                          \
      lval = (__typeof__(lval)) _res;                             \
   } while (0)

#define CALL_FN_W_W(lval, orig, arg1)                             \
   do {                                                           \
      volatile OrigFn        _orig = (orig);                      \
      volatile unsigned long _argvec[2];                          \
      volatile unsigned long _res;                                \
      _argvec[0] = (unsigned long)_orig.nraddr;                   \
      _argvec[1] = (unsigned long)(arg1);                         \
      __asm__ volatile(                                           \
         VALGRIND_ALIGN_STACK                                     \
         "ldr x0, [%1, #8] \n\t"                                  \
         "ldr x8, [%1] \n\t"  /* target->x8 */                    \
         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_X8                   \
         VALGRIND_RESTORE_STACK                                   \
         "mov %0, x0\n"                                           \
         : /*out*/   "=r" (_res)                                  \
         : /*in*/    "0" (&_argvec[0])                            \
         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "x21"   \
      );                                                          \
      lval = (__typeof__(lval)) _res;                             \
   } while (0)

#define CALL_FN_W_WW(lval, orig, arg1,arg2)                       \
   do {                                                           \
      volatile OrigFn        _orig = (orig);                      \
      volatile unsigned long _argvec[3];                          \
      volatile unsigned long _res;                                \
      _argvec[0] = (unsigned long)_orig.nraddr;                   \
      _argvec[1] = (unsigned long)(arg1);                         \
      _argvec[2] = (unsigned long)(arg2);                         \
      __asm__ volatile(                                           \
         VALGRIND_ALIGN_STACK                                     \
         "ldr x0, [%1, #8] \n\t"                                  \
         "ldr x1, [%1, #16] \n\t"                                 \
         "ldr x8, [%1] \n\t"  /* target->x8 */                    \
         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_X8                   \
         VALGRIND_RESTORE_STACK                                   \
         "mov %0, x0\n"                                           \
         : /*out*/   "=r" (_res)                                  \
         : /*in*/    "0" (&_argvec[0])                            \
         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "x21"   \
      );                                                          \
      lval = (__typeof__(lval)) _res;                             \
   } while (0)

#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3)                 \
   do {                                                           \
      volatile OrigFn        _orig = (orig);                      \
      volatile unsigned long _argvec[4];                          \
      volatile unsigned long _res;                                \
      _argvec[0] = (unsigned long)_orig.nraddr;                   \
      _argvec[1] = (unsigned long)(arg1);                         \
      _argvec[2] = (unsigned long)(arg2);                         \
      _argvec[3] = (unsigned long)(arg3);                         \
      __asm__ volatile(                                           \
         VALGRIND_ALIGN_STACK                                     \
         "ldr x0, [%1, #8] \n\t"                                  \
         "ldr x1, [%1, #16] \n\t"                                 \
         "ldr x2, [%1, #24] \n\t"                                 \
         "ldr x8, [%1] \n\t"  /* target->x8 */                    \
         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_X8                   \
         VALGRIND_RESTORE_STACK                                   \
         "mov %0, x0\n"                                           \
         : /*out*/   "=r" (_res)                                  \
         : /*in*/    "0" (&_argvec[0])                            \
         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "x21"   \
      );                                                          \
      lval = (__typeof__(lval)) _res;                             \
   } while (0)

#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4)           \
   do {                                                           \
      volatile OrigFn        _orig = (orig);                      \
      volatile unsigned long _argvec[5];                          \
      volatile unsigned long _res;                                \
      _argvec[0] = (unsigned long)_orig.nraddr;                   \
      _argvec[1] = (unsigned long)(arg1);                         \
      _argvec[2] = (unsigned long)(arg2);                         \
      _argvec[3] = (unsigned long)(arg3);                         \
      _argvec[4] = (unsigned long)(arg4);                         \
      __asm__ volatile(                                           \
         VALGRIND_ALIGN_STACK                                     \
         "ldr x0, [%1, #8] \n\t"                                  \
         "ldr x1, [%1, #16] \n\t"                                 \
         "ldr x2, [%1, #24] \n\t"                                 \
         "ldr x3, [%1, #32] \n\t"                                 \
         "ldr x8, [%1] \n\t"  /* target->x8 */                    \
         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_X8                   \
         VALGRIND_RESTORE_STACK                                   \
         "mov %0, x0"                                             \
         : /*out*/   "=r" (_res)                                  \
         : /*in*/    "0" (&_argvec[0])                            \
         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "x21"   \
      );                                                          \
      lval = (__typeof__(lval)) _res;                             \
   } while (0)

#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5)        \
   do {                                                           \
      volatile OrigFn        _orig = (orig);                      \
      volatile unsigned long _argvec[6];                          \
      volatile unsigned long _res;                                \
      _argvec[0] = (unsigned long)_orig.nraddr;                   \
      _argvec[1] = (unsigned long)(arg1);                         \
      _argvec[2] = (unsigned long)(arg2);                         \
      _argvec[3] = (unsigned long)(arg3);                         \
      _argvec[4] = (unsigned long)(arg4);                         \
      _argvec[5] = (unsigned long)(arg5);                         \
      __asm__ volatile(                                           \
         VALGRIND_ALIGN_STACK                                     \
         "ldr x0, [%1, #8] \n\t"                                  \
         "ldr x1, [%1, #16] \n\t"                                 \
         "ldr x2, [%1, #24] \n\t"                                 \
         "ldr x3, [%1, #32] \n\t"                                 \
         "ldr x4, [%1, #40] \n\t"                                 \
         "ldr x8, [%1] \n\t"  /* target->x8 */                    \
         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_X8                   \
         VALGRIND_RESTORE_STACK                                   \
         "mov %0, x0"                                             \
         : /*out*/   "=r" (_res)                                  \
         : /*in*/    "0" (&_argvec[0])                            \
         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "x21"   \
      );                                                          \
      lval = (__typeof__(lval)) _res;                             \
   } while (0)

#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6)   \
   do {                                                           \
      volatile OrigFn        _orig = (orig);                      \
      volatile unsigned long _argvec[7];                          \
      volatile unsigned long _res;                                \
      _argvec[0] = (unsigned long)_orig.nraddr;                   \
      _argvec[1] = (unsigned long)(arg1);                         \
      _argvec[2] = (unsigned long)(arg2);                         \
      _argvec[3] = (unsigned long)(arg3);                         \
      _argvec[4] = (unsigned long)(arg4);                         \
      _argvec[5] = (unsigned long)(arg5);                         \
      _argvec[6] = (unsigned long)(arg6);                         \
      __asm__ volatile(                                           \
         VALGRIND_ALIGN_STACK                                     \
         "ldr x0, [%1, #8] \n\t"                                  \
         "ldr x1, [%1, #16] \n\t"                                 \
         "ldr x2, [%1, #24] \n\t"                                 \
         "ldr x3, [%1, #32] \n\t"                                 \
         "ldr x4, [%1, #40] \n\t"                                 \
         "ldr x5, [%1, #48] \n\t"                                 \
         "ldr x8, [%1] \n\t"  /* target->x8 */                    \
         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_X8                   \
         VALGRIND_RESTORE_STACK                                   \
         "mov %0, x0"                                             \
         : /*out*/   "=r" (_res)                                  \
         : /*in*/    "0" (&_argvec[0])                            \
         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "x21"   \
      );                                                          \
      lval = (__typeof__(lval)) _res;                             \
   } while (0)

#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
                                 arg7)                            \
   do {                                                           \
      volatile OrigFn        _orig = (orig);                      \
      volatile unsigned long _argvec[8];                          \
      volatile unsigned long _res;                                \
      _argvec[0] = (unsigned long)_orig.nraddr;                   \
      _argvec[1] = (unsigned long)(arg1);                         \
      _argvec[2] = (unsigned long)(arg2);                         \
      _argvec[3] = (unsigned long)(arg3);                         \
      _argvec[4] = (unsigned long)(arg4);                         \
      _argvec[5] = (unsigned long)(arg5);                         \
      _argvec[6] = (unsigned long)(arg6);                         \
      _argvec[7] = (unsigned long)(arg7);                         \
      __asm__ volatile(                                           \
         VALGRIND_ALIGN_STACK                                     \
         "ldr x0, [%1, #8] \n\t"                                  \
         "ldr x1, [%1, #16] \n\t"                                 \
         "ldr x2, [%1, #24] \n\t"                                 \
         "ldr x3, [%1, #32] \n\t"                                 \
         "ldr x4, [%1, #40] \n\t"                                 \
         "ldr x5, [%1, #48] \n\t"                                 \
         "ldr x6, [%1, #56] \n\t"                                 \
         "ldr x8, [%1] \n\t"  /* target->x8 */                    \
         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_X8                   \
         VALGRIND_RESTORE_STACK                                   \
         "mov %0, x0"                                             \
         : /*out*/   "=r" (_res)                                  \
         : /*in*/    "0" (&_argvec[0])                            \
         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "x21"   \
      );                                                          \
      lval = (__typeof__(lval)) _res;                             \
   } while (0)

#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
                                 arg7,arg8)                       \
   do {                                                           \
      volatile OrigFn        _orig = (orig);                      \
      volatile unsigned long _argvec[9];                          \
      volatile unsigned long _res;                                \
      _argvec[0] = (unsigned long)_orig.nraddr;                   \
      _argvec[1] = (unsigned long)(arg1);                         \
      _argvec[2] = (unsigned long)(arg2);                         \
      _argvec[3] = (unsigned long)(arg3);                         \
      _argvec[4] = (unsigned long)(arg4);                         \
      _argvec[5] = (unsigned long)(arg5);                         \
      _argvec[6] = (unsigned long)(arg6);                         \
      _argvec[7] = (unsigned long)(arg7);                         \
      _argvec[8] = (unsigned long)(arg8);                         \
      __asm__ volatile(                                           \
         VALGRIND_ALIGN_STACK                                     \
         "ldr x0, [%1, #8] \n\t"                                  \
         "ldr x1, [%1, #16] \n\t"                                 \
         "ldr x2, [%1, #24] \n\t"                                 \
         "ldr x3, [%1, #32] \n\t"                                 \
         "ldr x4, [%1, #40] \n\t"                                 \
         "ldr x5, [%1, #48] \n\t"                                 \
         "ldr x6, [%1, #56] \n\t"                                 \
         "ldr x7, [%1, #64] \n\t"                                 \
         "ldr x8, [%1] \n\t"  /* target->x8 */                    \
         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_X8                   \
         VALGRIND_RESTORE_STACK                                   \
         "mov %0, x0"                                             \
         : /*out*/   "=r" (_res)                                  \
         : /*in*/    "0" (&_argvec[0])                            \
         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "x21"   \
      );                                                          \
      lval = (__typeof__(lval)) _res;                             \
   } while (0)

#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
                                 arg7,arg8,arg9)                  \
   do {                                                           \
      volatile OrigFn        _orig = (orig);                      \
      volatile unsigned long _argvec[10];                         \
      volatile unsigned long _res;                                \
      _argvec[0] = (unsigned long)_orig.nraddr;                   \
      _argvec[1] = (unsigned long)(arg1);                         \
      _argvec[2] = (unsigned long)(arg2);                         \
      _argvec[3] = (unsigned long)(arg3);                         \
      _argvec[4] = (unsigned long)(arg4);                         \
      _argvec[5] = (unsigned long)(arg5);                         \
      _argvec[6] = (unsigned long)(arg6);                         \
      _argvec[7] = (unsigned long)(arg7);                         \
      _argvec[8] = (unsigned long)(arg8);                         \
      _argvec[9] = (unsigned long)(arg9);                         \
      __asm__ volatile(                                           \
         VALGRIND_ALIGN_STACK                                     \
         "sub sp, sp, #0x20 \n\t"                                 \
         "ldr x0, [%1, #8] \n\t"                                  \
         "ldr x1, [%1, #16] \n\t"                                 \
         "ldr x2, [%1, #24] \n\t"                                 \
         "ldr x3, [%1, #32] \n\t"                                 \
         "ldr x4, [%1, #40] \n\t"                                 \
         "ldr x5, [%1, #48] \n\t"                                 \
         "ldr x6, [%1, #56] \n\t"                                 \
         "ldr x7, [%1, #64] \n\t"                                 \
         "ldr x8, [%1, #72] \n\t"                                 \
         "str x8, [sp, #0]  \n\t"                                 \
         "ldr x8, [%1] \n\t"  /* target->x8 */                    \
         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_X8                   \
         VALGRIND_RESTORE_STACK                                   \
         "mov %0, x0"                                             \
         : /*out*/   "=r" (_res)                                  \
         : /*in*/    "0" (&_argvec[0])                            \
         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "x21"   \
      );                                                          \
      lval = (__typeof__(lval)) _res;                             \
   } while (0)

#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
                                  arg7,arg8,arg9,arg10)           \
   do {                                                           \
      volatile OrigFn        _orig = (orig);                      \
      volatile unsigned long _argvec[11];                         \
      volatile unsigned long _res;                                \
      _argvec[0] = (unsigned long)_orig.nraddr;                   \
      _argvec[1] = (unsigned long)(arg1);                         \
      _argvec[2] = (unsigned long)(arg2);                         \
      _argvec[3] = (unsigned long)(arg3);                         \
      _argvec[4] = (unsigned long)(arg4);                         \
      _argvec[5] = (unsigned long)(arg5);                         \
      _argvec[6] = (unsigned long)(arg6);                         \
      _argvec[7] = (unsigned long)(arg7);                         \
      _argvec[8] = (unsigned long)(arg8);                         \
      _argvec[9] = (unsigned long)(arg9);                         \
      _argvec[10] = (unsigned long)(arg10);                       \
      __asm__ volatile(                                           \
         VALGRIND_ALIGN_STACK                                     \
         "sub sp, sp, #0x20 \n\t"                                 \
         "ldr x0, [%1, #8] \n\t"                                  \
         "ldr x1, [%1, #16] \n\t"                                 \
         "ldr x2, [%1, #24] \n\t"                                 \
         "ldr x3, [%1, #32] \n\t"                                 \
         "ldr x4, [%1, #40] \n\t"                                 \
         "ldr x5, [%1, #48] \n\t"                                 \
         "ldr x6, [%1, #56] \n\t"                                 \
         "ldr x7, [%1, #64] \n\t"                                 \
         "ldr x8, [%1, #72] \n\t"                                 \
         "str x8, [sp, #0]  \n\t"                                 \
         "ldr x8, [%1, #80] \n\t"                                 \
         "str x8, [sp, #8]  \n\t"                                 \
         "ldr x8, [%1] \n\t"  /* target->x8 */                    \
         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_X8                   \
         VALGRIND_RESTORE_STACK                                   \
         "mov %0, x0"                                             \
         : /*out*/   "=r" (_res)                                  \
         : /*in*/    "0" (&_argvec[0])                            \
         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "x21"   \
      );                                                          \
      lval = (__typeof__(lval)) _res;                             \
   } while (0)

#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
                                  arg7,arg8,arg9,arg10,arg11)     \
   do {                                                           \
      volatile OrigFn        _orig = (orig);                      \
      volatile unsigned long _argvec[12];                         \
      volatile unsigned long _res;                                \
      _argvec[0] = (unsigned long)_orig.nraddr;                   \
      _argvec[1] = (unsigned long)(arg1);                         \
      _argvec[2] = (unsigned long)(arg2);                         \
      _argvec[3] = (unsigned long)(arg3);                         \
      _argvec[4] = (unsigned long)(arg4);                         \
      _argvec[5] = (unsigned long)(arg5);                         \
      _argvec[6] = (unsigned long)(arg6);                         \
      _argvec[7] = (unsigned long)(arg7);                         \
      _argvec[8] = (unsigned long)(arg8);                         \
      _argvec[9] = (unsigned long)(arg9);                         \
      _argvec[10] = (unsigned long)(arg10);                       \
      _argvec[11] = (unsigned long)(arg11);                       \
      __asm__ volatile(                                           \
         VALGRIND_ALIGN_STACK                                     \
         "sub sp, sp, #0x30 \n\t"                                 \
         "ldr x0, [%1, #8] \n\t"                                  \
         "ldr x1, [%1, #16] \n\t"                                 \
         "ldr x2, [%1, #24] \n\t"                                 \
         "ldr x3, [%1, #32] \n\t"                                 \
         "ldr x4, [%1, #40] \n\t"                                 \
         "ldr x5, [%1, #48] \n\t"                                 \
         "ldr x6, [%1, #56] \n\t"                                 \
         "ldr x7, [%1, #64] \n\t"                                 \
         "ldr x8, [%1, #72] \n\t"                                 \
         "str x8, [sp, #0]  \n\t"                                 \
         "ldr x8, [%1, #80] \n\t"                                 \
         "str x8, [sp, #8]  \n\t"                                 \
         "ldr x8, [%1, #88] \n\t"                                 \
         "str x8, [sp, #16] \n\t"                                 \
         "ldr x8, [%1] \n\t"  /* target->x8 */                    \
         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_X8                   \
         VALGRIND_RESTORE_STACK                                   \
         "mov %0, x0"                                             \
         : /*out*/   "=r" (_res)                                  \
         : /*in*/    "0" (&_argvec[0])                            \
         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "x21"   \
      );                                                          \
      lval = (__typeof__(lval)) _res;                             \
   } while (0)

#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
                                  arg7,arg8,arg9,arg10,arg11,     \
                                  arg12)                          \
   do {                                                           \
      volatile OrigFn        _orig = (orig);                      \
      volatile unsigned long _argvec[13];                         \
      volatile unsigned long _res;                                \
      _argvec[0] = (unsigned long)_orig.nraddr;                   \
      _argvec[1] = (unsigned long)(arg1);                         \
      _argvec[2] = (unsigned long)(arg2);                         \
      _argvec[3] = (unsigned long)(arg3);                         \
      _argvec[4] = (unsigned long)(arg4);                         \
      _argvec[5] = (unsigned long)(arg5);                         \
      _argvec[6] = (unsigned long)(arg6);                         \
      _argvec[7] = (unsigned long)(arg7);                         \
      _argvec[8] = (unsigned long)(arg8);                         \
      _argvec[9] = (unsigned long)(arg9);                         \
      _argvec[10] = (unsigned long)(arg10);                       \
      _argvec[11] = (unsigned long)(arg11);                       \
      _argvec[12] = (unsigned long)(arg12);                       \
      __asm__ volatile(                                           \
         VALGRIND_ALIGN_STACK                                     \
         "sub sp, sp, #0x30 \n\t"                                 \
         "ldr x0, [%1, #8] \n\t"                                  \
         "ldr x1, [%1, #16] \n\t"                                 \
         "ldr x2, [%1, #24] \n\t"                                 \
         "ldr x3, [%1, #32] \n\t"                                 \
         "ldr x4, [%1, #40] \n\t"                                 \
         "ldr x5, [%1, #48] \n\t"                                 \
         "ldr x6, [%1, #56] \n\t"                                 \
         "ldr x7, [%1, #64] \n\t"                                 \
         "ldr x8, [%1, #72] \n\t"                                 \
         "str x8, [sp, #0]  \n\t"                                 \
         "ldr x8, [%1, #80] \n\t"                                 \
         "str x8, [sp, #8]  \n\t"                                 \
         "ldr x8, [%1, #88] \n\t"                                 \
         "str x8, [sp, #16] \n\t"                                 \
         "ldr x8, [%1, #96] \n\t"                                 \
         "str x8, [sp, #24] \n\t"                                 \
         "ldr x8, [%1] \n\t"  /* target->x8 */                    \
         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_X8                   \
         VALGRIND_RESTORE_STACK                                   \
         "mov %0, x0"                                             \
         : /*out*/   "=r" (_res)                                  \
         : /*in*/    "0" (&_argvec[0])                            \
         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "x21"   \
      );                                                          \
      lval = (__typeof__(lval)) _res;                             \
   } while (0)

#endif /* PLAT_arm64_linux */

/* ------------------------- s390x-linux ------------------------- */

#if defined(PLAT_s390x_linux)

/* Similar workaround as amd64 (see above), but we use r11 as frame
   pointer and save the old r11 in r7. r11 might be used for
   argvec, therefore we copy argvec in r1 since r1 is clobbered
   after the call anyway.  */
#if defined(__GNUC__) && defined(__GCC_HAVE_DWARF2_CFI_ASM)
#  define __FRAME_POINTER                                         \
      ,"d"(__builtin_dwarf_cfa())
#  define VALGRIND_CFI_PROLOGUE                                   \
      ".cfi_remember_state\n\t"                                   \
      "lgr 1,%1\n\t" /* copy the argvec pointer in r1 */          \
      "lgr 7,11\n\t"                                              \
      "lgr 11,%2\n\t"                                             \
      ".cfi_def_cfa r11, 0\n\t"
#  define VALGRIND_CFI_EPILOGUE                                   \
      "lgr 11, 7\n\t"                                             \
      ".cfi_restore_state\n\t"
#else
#  define __FRAME_POINTER
#  define VALGRIND_CFI_PROLOGUE                                   \
      "lgr 1,%1\n\t"
#  define VALGRIND_CFI_EPILOGUE
#endif

/* Nb: On s390 the stack pointer is properly aligned *at all times*
   according to the s390 GCC maintainer. (The ABI specification is not
   precise in this regard.) Therefore, VALGRIND_ALIGN_STACK and
   VALGRIND_RESTORE_STACK are not defined here. */

/* These regs are trashed by the hidden call. Note that we overwrite
   r14 in s390_irgen_noredir (VEX/priv/guest_s390_irgen.c) to give the
   function a proper return address. All others are ABI defined call
   clobbers. */
#define __CALLER_SAVED_REGS "0","1","2","3","4","5","14", \
                           "f0","f1","f2","f3","f4","f5","f6","f7"

/* Nb: Although r11 is modified in the asm snippets below (inside 
   VALGRIND_CFI_PROLOGUE) it is not listed in the clobber section, for
   two reasons:
   (1) r11 is restored in VALGRIND_CFI_EPILOGUE, so effectively it is not
       modified
   (2) GCC will complain that r11 cannot appear inside a clobber section,
       when compiled with -O -fno-omit-frame-pointer
 */

#define CALL_FN_W_v(lval, orig)                                  \
   do {                                                          \
      volatile OrigFn        _orig = (orig);                     \
      volatile unsigned long  _argvec[1];                        \
      volatile unsigned long _res;                               \
      _argvec[0] = (unsigned long)_orig.nraddr;                  \
      __asm__ volatile(                                          \
         VALGRIND_CFI_PROLOGUE                                   \
         "aghi 15,-160\n\t"                                      \
         "lg 1, 0(1)\n\t"  /* target->r1 */                      \
         VALGRIND_CALL_NOREDIR_R1                                \
         "lgr %0, 2\n\t"                                         \
         "aghi 15,160\n\t"                                       \
         VALGRIND_CFI_EPILOGUE                                   \
         : /*out*/   "=d" (_res)                                 \
         : /*in*/    "d" (&_argvec[0]) __FRAME_POINTER           \
         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"7"     \
      );                                                         \
      lval = (__typeof__(lval)) _res;                            \
   } while (0)

/* The call abi has the arguments in r2-r6 and stack */
#define CALL_FN_W_W(lval, orig, arg1)                            \
   do {                                                          \
      volatile OrigFn        _orig = (orig);                     \
      volatile unsigned long _argvec[2];                         \
      volatile unsigned long _res;                               \
      _argvec[0] = (unsigned long)_orig.nraddr;                  \
      _argvec[1] = (unsigned long)arg1;                          \
      __asm__ volatile(                                          \
         VALGRIND_CFI_PROLOGUE                                   \
         "aghi 15,-160\n\t"                                      \
         "lg 2, 8(1)\n\t"                                        \
         "lg 1, 0(1)\n\t"                                        \
         VALGRIND_CALL_NOREDIR_R1                                \
         "lgr %0, 2\n\t"                                         \
         "aghi 15,160\n\t"                                       \
         VALGRIND_CFI_EPILOGUE                                   \
         : /*out*/   "=d" (_res)                                 \
         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER           \
         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"7"     \
      );                                                         \
      lval = (__typeof__(lval)) _res;                            \
   } while (0)

#define CALL_FN_W_WW(lval, orig, arg1, arg2)                     \
   do {                                                          \
      volatile OrigFn        _orig = (orig);                     \
      volatile unsigned long _argvec[3];                         \
      volatile unsigned long _res;                               \
      _argvec[0] = (unsigned long)_orig.nraddr;                  \
      _argvec[1] = (unsigned long)arg1;                          \
      _argvec[2] = (unsigned long)arg2;                          \
      __asm__ volatile(                                          \
         VALGRIND_CFI_PROLOGUE                                   \
         "aghi 15,-160\n\t"                                      \
         "lg 2, 8(1)\n\t"                                        \
         "lg 3,16(1)\n\t"                                        \
         "lg 1, 0(1)\n\t"                                        \
         VALGRIND_CALL_NOREDIR_R1                                \
         "lgr %0, 2\n\t"                                         \
         "aghi 15,160\n\t"                                       \
         VALGRIND_CFI_EPILOGUE                                   \
         : /*out*/   "=d" (_res)                                 \
         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER           \
         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"7"     \
      );                                                         \
      lval = (__typeof__(lval)) _res;                            \
   } while (0)

#define CALL_FN_W_WWW(lval, orig, arg1, arg2, arg3)              \
   do {                                                          \
      volatile OrigFn        _orig = (orig);                     \
      volatile unsigned long _argvec[4];                         \
      volatile unsigned long _res;                               \
      _argvec[0] = (unsigned long)_orig.nraddr;                  \
      _argvec[1] = (unsigned long)arg1;                          \
      _argvec[2] = (unsigned long)arg2;                          \
      _argvec[3] = (unsigned long)arg3;                          \
      __asm__ volatile(                                          \
         VALGRIND_CFI_PROLOGUE                                   \
         "aghi 15,-160\n\t"                                      \
         "lg 2, 8(1)\n\t"                                        \
         "lg 3,16(1)\n\t"                                        \
         "lg 4,24(1)\n\t"                                        \
         "lg 1, 0(1)\n\t"                                        \
         VALGRIND_CALL_NOREDIR_R1                                \
         "lgr %0, 2\n\t"                                         \
         "aghi 15,160\n\t"                                       \
         VALGRIND_CFI_EPILOGUE                                   \
         : /*out*/   "=d" (_res)                                 \
         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER           \
         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"7"     \
      );                                                         \
      lval = (__typeof__(lval)) _res;                            \
   } while (0)

#define CALL_FN_W_WWWW(lval, orig, arg1, arg2, arg3, arg4)       \
   do {                                                          \
      volatile OrigFn        _orig = (orig);                     \
      volatile unsigned long _argvec[5];                         \
      volatile unsigned long _res;                               \
      _argvec[0] = (unsigned long)_orig.nraddr;                  \
      _argvec[1] = (unsigned long)arg1;                          \
      _argvec[2] = (unsigned long)arg2;                          \
      _argvec[3] = (unsigned long)arg3;                          \
      _argvec[4] = (unsigned long)arg4;                          \
      __asm__ volatile(                                          \
         VALGRIND_CFI_PROLOGUE                                   \
         "aghi 15,-160\n\t"                                      \
         "lg 2, 8(1)\n\t"                                        \
         "lg 3,16(1)\n\t"                                        \
         "lg 4,24(1)\n\t"                                        \
         "lg 5,32(1)\n\t"                                        \
         "lg 1, 0(1)\n\t"                                        \
         VALGRIND_CALL_NOREDIR_R1                                \
         "lgr %0, 2\n\t"                                         \
         "aghi 15,160\n\t"                                       \
         VALGRIND_CFI_EPILOGUE                                   \
         : /*out*/   "=d" (_res)                                 \
         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER           \
         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"7"     \
      );                                                         \
      lval = (__typeof__(lval)) _res;                            \
   } while (0)

#define CALL_FN_W_5W(lval, orig, arg1, arg2, arg3, arg4, arg5)   \
   do {                                                          \
      volatile OrigFn        _orig = (orig);                     \
      volatile unsigned long _argvec[6];                         \
      volatile unsigned long _res;                               \
      _argvec[0] = (unsigned long)_orig.nraddr;                  \
      _argvec[1] = (unsigned long)arg1;                          \
      _argvec[2] = (unsigned long)arg2;                          \
      _argvec[3] = (unsigned long)arg3;                          \
      _argvec[4] = (unsigned long)arg4;                          \
      _argvec[5] = (unsigned long)arg5;                          \
      __asm__ volatile(                                          \
         VALGRIND_CFI_PROLOGUE                                   \
         "aghi 15,-160\n\t"                                      \
         "lg 2, 8(1)\n\t"                                        \
         "lg 3,16(1)\n\t"                                        \
         "lg 4,24(1)\n\t"                                        \
         "lg 5,32(1)\n\t"                                        \
         "lg 6,40(1)\n\t"                                        \
         "lg 1, 0(1)\n\t"                                        \
         VALGRIND_CALL_NOREDIR_R1                                \
         "lgr %0, 2\n\t"                                         \
         "aghi 15,160\n\t"                                       \
         VALGRIND_CFI_EPILOGUE                                   \
         : /*out*/   "=d" (_res)                                 \
         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER           \
         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \
      );                                                         \
      lval = (__typeof__(lval)) _res;                            \
   } while (0)

#define CALL_FN_W_6W(lval, orig, arg1, arg2, arg3, arg4, arg5,   \
                     arg6)                                       \
   do {                                                          \
      volatile OrigFn        _orig = (orig);                     \
      volatile unsigned long _argvec[7];                         \
      volatile unsigned long _res;                               \
      _argvec[0] = (unsigned long)_orig.nraddr;                  \
      _argvec[1] = (unsigned long)arg1;                          \
      _argvec[2] = (unsigned long)arg2;                          \
      _argvec[3] = (unsigned long)arg3;                          \
      _argvec[4] = (unsigned long)arg4;                          \
      _argvec[5] = (unsigned long)arg5;                          \
      _argvec[6] = (unsigned long)arg6;                          \
      __asm__ volatile(                                          \
         VALGRIND_CFI_PROLOGUE                                   \
         "aghi 15,-168\n\t"                                      \
         "lg 2, 8(1)\n\t"                                        \
         "lg 3,16(1)\n\t"                                        \
         "lg 4,24(1)\n\t"                                        \
         "lg 5,32(1)\n\t"                                        \
         "lg 6,40(1)\n\t"                                        \
         "mvc 160(8,15), 48(1)\n\t"                              \
         "lg 1, 0(1)\n\t"                                        \
         VALGRIND_CALL_NOREDIR_R1                                \
         "lgr %0, 2\n\t"                                         \
         "aghi 15,168\n\t"                                       \
         VALGRIND_CFI_EPILOGUE                                   \
         : /*out*/   "=d" (_res)                                 \
         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER           \
         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \
      );                                                         \
      lval = (__typeof__(lval)) _res;                            \
   } while (0)

#define CALL_FN_W_7W(lval, orig, arg1, arg2, arg3, arg4, arg5,   \
                     arg6, arg7)                                 \
   do {                                                          \
      volatile OrigFn        _orig = (orig);                     \
      volatile unsigned long _argvec[8];                         \
      volatile unsigned long _res;                               \
      _argvec[0] = (unsigned long)_orig.nraddr;                  \
      _argvec[1] = (unsigned long)arg1;                          \
      _argvec[2] = (unsigned long)arg2;                          \
      _argvec[3] = (unsigned long)arg3;                          \
      _argvec[4] = (unsigned long)arg4;                          \
      _argvec[5] = (unsigned long)arg5;                          \
      _argvec[6] = (unsigned long)arg6;                          \
      _argvec[7] = (unsigned long)arg7;                          \
      __asm__ volatile(                                          \
         VALGRIND_CFI_PROLOGUE                                   \
         "aghi 15,-176\n\t"                                      \
         "lg 2, 8(1)\n\t"                                        \
         "lg 3,16(1)\n\t"                                        \
         "lg 4,24(1)\n\t"                                        \
         "lg 5,32(1)\n\t"                                        \
         "lg 6,40(1)\n\t"                                        \
         "mvc 160(8,15), 48(1)\n\t"                              \
         "mvc 168(8,15), 56(1)\n\t"                              \
         "lg 1, 0(1)\n\t"                                        \
         VALGRIND_CALL_NOREDIR_R1                                \
         "lgr %0, 2\n\t"                                         \
         "aghi 15,176\n\t"                                       \
         VALGRIND_CFI_EPILOGUE                                   \
         : /*out*/   "=d" (_res)                                 \
         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER           \
         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \
      );                                                         \
      lval = (__typeof__(lval)) _res;                            \
   } while (0)

#define CALL_FN_W_8W(lval, orig, arg1, arg2, arg3, arg4, arg5,   \
                     arg6, arg7 ,arg8)                           \
   do {                                                          \
      volatile OrigFn        _orig = (orig);                     \
      volatile unsigned long _argvec[9];                         \
      volatile unsigned long _res;                               \
      _argvec[0] = (unsigned long)_orig.nraddr;                  \
      _argvec[1] = (unsigned long)arg1;                          \
      _argvec[2] = (unsigned long)arg2;                          \
      _argvec[3] = (unsigned long)arg3;                          \
      _argvec[4] = (unsigned long)arg4;                          \
      _argvec[5] = (unsigned long)arg5;                          \
      _argvec[6] = (unsigned long)arg6;                          \
      _argvec[7] = (unsigned long)arg7;                          \
      _argvec[8] = (unsigned long)arg8;                          \
      __asm__ volatile(                                          \
         VALGRIND_CFI_PROLOGUE                                   \
         "aghi 15,-184\n\t"                                      \
         "lg 2, 8(1)\n\t"                                        \
         "lg 3,16(1)\n\t"                                        \
         "lg 4,24(1)\n\t"                                        \
         "lg 5,32(1)\n\t"                                        \
         "lg 6,40(1)\n\t"                                        \
         "mvc 160(8,15), 48(1)\n\t"                              \
         "mvc 168(8,15), 56(1)\n\t"                              \
         "mvc 176(8,15), 64(1)\n\t"                              \
         "lg 1, 0(1)\n\t"                                        \
         VALGRIND_CALL_NOREDIR_R1                                \
         "lgr %0, 2\n\t"                                         \
         "aghi 15,184\n\t"                                       \
         VALGRIND_CFI_EPILOGUE                                   \
         : /*out*/   "=d" (_res)                                 \
         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER           \
         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \
      );                                                         \
      lval = (__typeof__(lval)) _res;                            \
   } while (0)

#define CALL_FN_W_9W(lval, orig, arg1, arg2, arg3, arg4, arg5,   \
                     arg6, arg7 ,arg8, arg9)                     \
   do {                                                          \
      volatile OrigFn        _orig = (orig);                     \
      volatile unsigned long _argvec[10];                        \
      volatile unsigned long _res;                               \
      _argvec[0] = (unsigned long)_orig.nraddr;                  \
      _argvec[1] = (unsigned long)arg1;                          \
      _argvec[2] = (unsigned long)arg2;                          \
      _argvec[3] = (unsigned long)arg3;                          \
      _argvec[4] = (unsigned long)arg4;                          \
      _argvec[5] = (unsigned long)arg5;                          \
      _argvec[6] = (unsigned long)arg6;                          \
      _argvec[7] = (unsigned long)arg7;                          \
      _argvec[8] = (unsigned long)arg8;                          \
      _argvec[9] = (unsigned long)arg9;                          \
      __asm__ volatile(                                          \
         VALGRIND_CFI_PROLOGUE                                   \
         "aghi 15,-192\n\t"                                      \
         "lg 2, 8(1)\n\t"                                        \
         "lg 3,16(1)\n\t"                                        \
         "lg 4,24(1)\n\t"                                        \
         "lg 5,32(1)\n\t"                                        \
         "lg 6,40(1)\n\t"                                        \
         "mvc 160(8,15), 48(1)\n\t"                              \
         "mvc 168(8,15), 56(1)\n\t"                              \
         "mvc 176(8,15), 64(1)\n\t"                              \
         "mvc 184(8,15), 72(1)\n\t"                              \
         "lg 1, 0(1)\n\t"                                        \
         VALGRIND_CALL_NOREDIR_R1                                \
         "lgr %0, 2\n\t"                                         \
         "aghi 15,192\n\t"                                       \
         VALGRIND_CFI_EPILOGUE                                   \
         : /*out*/   "=d" (_res)                                 \
         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER           \
         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \
      );                                                         \
      lval = (__typeof__(lval)) _res;                            \
   } while (0)

#define CALL_FN_W_10W(lval, orig, arg1, arg2, arg3, arg4, arg5,  \
                     arg6, arg7 ,arg8, arg9, arg10)              \
   do {                                                          \
      volatile OrigFn        _orig = (orig);                     \
      volatile unsigned long _argvec[11];                        \
      volatile unsigned long _res;                               \
      _argvec[0] = (unsigned long)_orig.nraddr;                  \
      _argvec[1] = (unsigned long)arg1;                          \
      _argvec[2] = (unsigned long)arg2;                          \
      _argvec[3] = (unsigned long)arg3;                          \
      _argvec[4] = (unsigned long)arg4;                          \
      _argvec[5] = (unsigned long)arg5;                          \
      _argvec[6] = (unsigned long)arg6;                          \
      _argvec[7] = (unsigned long)arg7;                          \
      _argvec[8] = (unsigned long)arg8;                          \
      _argvec[9] = (unsigned long)arg9;                          \
      _argvec[10] = (unsigned long)arg10;                        \
      __asm__ volatile(                                          \
         VALGRIND_CFI_PROLOGUE                                   \
         "aghi 15,-200\n\t"                                      \
         "lg 2, 8(1)\n\t"                                        \
         "lg 3,16(1)\n\t"                                        \
         "lg 4,24(1)\n\t"                                        \
         "lg 5,32(1)\n\t"                                        \
         "lg 6,40(1)\n\t"                                        \
         "mvc 160(8,15), 48(1)\n\t"                              \
         "mvc 168(8,15), 56(1)\n\t"                              \
         "mvc 176(8,15), 64(1)\n\t"                              \
         "mvc 184(8,15), 72(1)\n\t"                              \
         "mvc 192(8,15), 80(1)\n\t"                              \
         "lg 1, 0(1)\n\t"                                        \
         VALGRIND_CALL_NOREDIR_R1                                \
         "lgr %0, 2\n\t"                                         \
         "aghi 15,200\n\t"                                       \
         VALGRIND_CFI_EPILOGUE                                   \
         : /*out*/   "=d" (_res)                                 \
         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER           \
         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \
      );                                                         \
      lval = (__typeof__(lval)) _res;                            \
   } while (0)

#define CALL_FN_W_11W(lval, orig, arg1, arg2, arg3, arg4, arg5,  \
                     arg6, arg7 ,arg8, arg9, arg10, arg11)       \
   do {                                                          \
      volatile OrigFn        _orig = (orig);                     \
      volatile unsigned long _argvec[12];                        \
      volatile unsigned long _res;                               \
      _argvec[0] = (unsigned long)_orig.nraddr;                  \
      _argvec[1] = (unsigned long)arg1;                          \
      _argvec[2] = (unsigned long)arg2;                          \
      _argvec[3] = (unsigned long)arg3;                          \
      _argvec[4] = (unsigned long)arg4;                          \
      _argvec[5] = (unsigned long)arg5;                          \
      _argvec[6] = (unsigned long)arg6;                          \
      _argvec[7] = (unsigned long)arg7;                          \
      _argvec[8] = (unsigned long)arg8;                          \
      _argvec[9] = (unsigned long)arg9;                          \
      _argvec[10] = (unsigned long)arg10;                        \
      _argvec[11] = (unsigned long)arg11;                        \
      __asm__ volatile(                                          \
         VALGRIND_CFI_PROLOGUE                                   \
         "aghi 15,-208\n\t"                                      \
         "lg 2, 8(1)\n\t"                                        \
         "lg 3,16(1)\n\t"                                        \
         "lg 4,24(1)\n\t"                                        \
         "lg 5,32(1)\n\t"                                        \
         "lg 6,40(1)\n\t"                                        \
         "mvc 160(8,15), 48(1)\n\t"                              \
         "mvc 168(8,15), 56(1)\n\t"                              \
         "mvc 176(8,15), 64(1)\n\t"                              \
         "mvc 184(8,15), 72(1)\n\t"                              \
         "mvc 192(8,15), 80(1)\n\t"                              \
         "mvc 200(8,15), 88(1)\n\t"                              \
         "lg 1, 0(1)\n\t"                                        \
         VALGRIND_CALL_NOREDIR_R1                                \
         "lgr %0, 2\n\t"                                         \
         "aghi 15,208\n\t"                                       \
         VALGRIND_CFI_EPILOGUE                                   \
         : /*out*/   "=d" (_res)                                 \
         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER           \
         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \
      );                                                         \
      lval = (__typeof__(lval)) _res;                            \
   } while (0)

#define CALL_FN_W_12W(lval, orig, arg1, arg2, arg3, arg4, arg5,  \
                     arg6, arg7 ,arg8, arg9, arg10, arg11, arg12)\
   do {                                                          \
      volatile OrigFn        _orig = (orig);                     \
      volatile unsigned long _argvec[13];                        \
      volatile unsigned long _res;                               \
      _argvec[0] = (unsigned long)_orig.nraddr;                  \
      _argvec[1] = (unsigned long)arg1;                          \
      _argvec[2] = (unsigned long)arg2;                          \
      _argvec[3] = (unsigned long)arg3;                          \
      _argvec[4] = (unsigned long)arg4;                          \
      _argvec[5] = (unsigned long)arg5;                          \
      _argvec[6] = (unsigned long)arg6;                          \
      _argvec[7] = (unsigned long)arg7;                          \
      _argvec[8] = (unsigned long)arg8;                          \
      _argvec[9] = (unsigned long)arg9;                          \
      _argvec[10] = (unsigned long)arg10;                        \
      _argvec[11] = (unsigned long)arg11;                        \
      _argvec[12] = (unsigned long)arg12;                        \
      __asm__ volatile(                                          \
         VALGRIND_CFI_PROLOGUE                                   \
         "aghi 15,-216\n\t"                                      \
         "lg 2, 8(1)\n\t"                                        \
         "lg 3,16(1)\n\t"                                        \
         "lg 4,24(1)\n\t"                                        \
         "lg 5,32(1)\n\t"                                        \
         "lg 6,40(1)\n\t"                                        \
         "mvc 160(8,15), 48(1)\n\t"                              \
         "mvc 168(8,15), 56(1)\n\t"                              \
         "mvc 176(8,15), 64(1)\n\t"                              \
         "mvc 184(8,15), 72(1)\n\t"                              \
         "mvc 192(8,15), 80(1)\n\t"                              \
         "mvc 200(8,15), 88(1)\n\t"                              \
         "mvc 208(8,15), 96(1)\n\t"                              \
         "lg 1, 0(1)\n\t"                                        \
         VALGRIND_CALL_NOREDIR_R1                                \
         "lgr %0, 2\n\t"                                         \
         "aghi 15,216\n\t"                                       \
         VALGRIND_CFI_EPILOGUE                                   \
         : /*out*/   "=d" (_res)                                 \
         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER           \
         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \
      );                                                         \
      lval = (__typeof__(lval)) _res;                            \
   } while (0)


#endif /* PLAT_s390x_linux */

/* ------------------------- mips32-linux ----------------------- */
 
#if defined(PLAT_mips32_linux)

/* These regs are trashed by the hidden call. */
#define __CALLER_SAVED_REGS "$2", "$3", "$4", "$5", "$6",       \
"$7", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24", \
"$25", "$31"

/* These CALL_FN_ macros assume that on mips-linux, sizeof(unsigned
   long) == 4. */

#define CALL_FN_W_v(lval, orig)                                   \
   do {                                                           \
      volatile OrigFn        _orig = (orig);                      \
      volatile unsigned long _argvec[1];                          \
      volatile unsigned long _res;                                \
      _argvec[0] = (unsigned long)_orig.nraddr;                   \
      __asm__ volatile(                                           \
         "subu $29, $29, 8 \n\t"                                  \
         "sw $28, 0($29) \n\t"                                    \
         "sw $31, 4($29) \n\t"                                    \
         "subu $29, $29, 16 \n\t"                                 \
         "lw $25, 0(%1) \n\t"  /* target->t9 */                   \
         VALGRIND_CALL_NOREDIR_T9                                 \
         "addu $29, $29, 16\n\t"                                  \
         "lw $28, 0($29) \n\t"                                    \
         "lw $31, 4($29) \n\t"                                    \
         "addu $29, $29, 8 \n\t"                                  \
         "move %0, $2\n"                                          \
         : /*out*/   "=r" (_res)                                  \
         : /*in*/    "0" (&_argvec[0])                            \
         : /*trash*/ "memory", __CALLER_SAVED_REGS                \
      );                                                          \
      lval = (__typeof__(lval)) _res;                             \
   } while (0)

#define CALL_FN_W_W(lval, orig, arg1)                             \
   do {                                                           \
      volatile OrigFn        _orig = (orig);                      \
     volatile unsigned long _argvec[2];                           \
      volatile unsigned long _res;                                \
      _argvec[0] = (unsigned long)_orig.nraddr;                   \
      _argvec[1] = (unsigned long)(arg1);                         \
      __asm__ volatile(                                           \
         "subu $29, $29, 8 \n\t"                                  \
         "sw $28, 0($29) \n\t"                                    \
         "sw $31, 4($29) \n\t"                                    \
         "subu $29, $29, 16 \n\t"                                 \
         "lw $4, 4(%1) \n\t"   /* arg1*/                          \
         "lw $25, 0(%1) \n\t"  /* target->t9 */                   \
         VALGRIND_CALL_NOREDIR_T9                                 \
         "addu $29, $29, 16 \n\t"                                 \
         "lw $28, 0($29) \n\t"                                    \
         "lw $31, 4($29) \n\t"                                    \
         "addu $29, $29, 8 \n\t"                                  \
         "move %0, $2\n"                                          \
         : /*out*/   "=r" (_res)                                  \
         : /*in*/    "0" (&_argvec[0])                            \
         : /*trash*/ "memory",  __CALLER_SAVED_REGS               \
      );                                                          \
      lval = (__typeof__(lval)) _res;                             \
   } while (0)

#define CALL_FN_W_WW(lval, orig, arg1,arg2)                       \
   do {                                                           \
      volatile OrigFn        _orig = (orig);                      \
      volatile unsigned long _argvec[3];                          \
      volatile unsigned long _res;                                \
      _argvec[0] = (unsigned long)_orig.nraddr;                   \
      _argvec[1] = (unsigned long)(arg1);                         \
      _argvec[2] = (unsigned long)(arg2);                         \
      __asm__ volatile(                                           \
         "subu $29, $29, 8 \n\t"                                  \
         "sw $28, 0($29) \n\t"                                    \
         "sw $31, 4($29) \n\t"                                    \
         "subu $29, $29, 16 \n\t"                                 \
         "lw $4, 4(%1) \n\t"                                      \
         "lw $5, 8(%1) \n\t"                                      \
         "lw $25, 0(%1) \n\t"  /* target->t9 */                   \
         VALGRIND_CALL_NOREDIR_T9                                 \
         "addu $29, $29, 16 \n\t"                                 \
         "lw $28, 0($29) \n\t"                                    \
         "lw $31, 4($29) \n\t"                                    \
         "addu $29, $29, 8 \n\t"                                  \
         "move %0, $2\n"                                          \
         : /*out*/   "=r" (_res)                                  \
         : /*in*/    "0" (&_argvec[0])                            \
         : /*trash*/ "memory", __CALLER_SAVED_REGS                \
      );                                                          \
      lval = (__typeof__(lval)) _res;                             \
   } while (0)

#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3)                 \
   do {                                                           \
      volatile OrigFn        _orig = (orig);                      \
      volatile unsigned long _argvec[4];                          \
      volatile unsigned long _res;                                \
      _argvec[0] = (unsigned long)_orig.nraddr;                   \
      _argvec[1] = (unsigned long)(arg1);                         \
      _argvec[2] = (unsigned long)(arg2);                         \
      _argvec[3] = (unsigned long)(arg3);                         \
      __asm__ volatile(                                           \
         "subu $29, $29, 8 \n\t"                                  \
         "sw $28, 0($29) \n\t"                                    \
         "sw $31, 4($29) \n\t"                                    \
         "subu $29, $29, 16 \n\t"                                 \
         "lw $4, 4(%1) \n\t"                                      \
         "lw $5, 8(%1) \n\t"                                      \
         "lw $6, 12(%1) \n\t"                                     \
         "lw $25, 0(%1) \n\t"  /* target->t9 */                   \
         VALGRIND_CALL_NOREDIR_T9                                 \
         "addu $29, $29, 16 \n\t"                                 \
         "lw $28, 0($29) \n\t"                                    \
         "lw $31, 4($29) \n\t"                                    \
         "addu $29, $29, 8 \n\t"                                  \
         "move %0, $2\n"                                          \
         : /*out*/   "=r" (_res)                                  \
         : /*in*/    "0" (&_argvec[0])                            \
         : /*trash*/ "memory", __CALLER_SAVED_REGS                \
      );                                                          \
      lval = (__typeof__(lval)) _res;                             \
   } while (0)

#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4)           \
   do {                                                           \
      volatile OrigFn        _orig = (orig);                      \
      volatile unsigned long _argvec[5];                          \
      volatile unsigned long _res;                                \
      _argvec[0] = (unsigned long)_orig.nraddr;                   \
      _argvec[1] = (unsigned long)(arg1);                         \
      _argvec[2] = (unsigned long)(arg2);                         \
      _argvec[3] = (unsigned long)(arg3);                         \
      _argvec[4] = (unsigned long)(arg4);                         \
      __asm__ volatile(                                           \
         "subu $29, $29, 8 \n\t"                                  \
         "sw $28, 0($29) \n\t"                                    \
         "sw $31, 4($29) \n\t"                                    \
         "subu $29, $29, 16 \n\t"                                 \
         "lw $4, 4(%1) \n\t"                                      \
         "lw $5, 8(%1) \n\t"                                      \
         "lw $6, 12(%1) \n\t"                                     \
         "lw $7, 16(%1) \n\t"                                     \
         "lw $25, 0(%1) \n\t"  /* target->t9 */                   \
         VALGRIND_CALL_NOREDIR_T9                                 \
         "addu $29, $29, 16 \n\t"                                 \
         "lw $28, 0($29) \n\t"                                    \
         "lw $31, 4($29) \n\t"                                    \
         "addu $29, $29, 8 \n\t"                                  \
         "move %0, $2\n"                                          \
         : /*out*/   "=r" (_res)                                  \
         : /*in*/    "0" (&_argvec[0])                            \
         : /*trash*/ "memory", __CALLER_SAVED_REGS                \
      );                                                          \
      lval = (__typeof__(lval)) _res;                             \
   } while (0)

#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5)        \
   do {                                                           \
      volatile OrigFn        _orig = (orig);                      \
      volatile unsigned long _argvec[6];                          \
      volatile unsigned long _res;                                \
      _argvec[0] = (unsigned long)_orig.nraddr;                   \
      _argvec[1] = (unsigned long)(arg1);                         \
      _argvec[2] = (unsigned long)(arg2);                         \
      _argvec[3] = (unsigned long)(arg3);                         \
      _argvec[4] = (unsigned long)(arg4);                         \
      _argvec[5] = (unsigned long)(arg5);                         \
      __asm__ volatile(                                           \
         "subu $29, $29, 8 \n\t"                                  \
         "sw $28, 0($29) \n\t"                                    \
         "sw $31, 4($29) \n\t"                                    \
         "lw $4, 20(%1) \n\t"                                     \
         "subu $29, $29, 24\n\t"                                  \
         "sw $4, 16($29) \n\t"                                    \
         "lw $4, 4(%1) \n\t"                                      \
         "lw $5, 8(%1) \n\t"                                      \
         "lw $6, 12(%1) \n\t"                                     \
         "lw $7, 16(%1) \n\t"                                     \
         "lw $25, 0(%1) \n\t"  /* target->t9 */                   \
         VALGRIND_CALL_NOREDIR_T9                                 \
         "addu $29, $29, 24 \n\t"                                 \
         "lw $28, 0($29) \n\t"                                    \
         "lw $31, 4($29) \n\t"                                    \
         "addu $29, $29, 8 \n\t"                                  \
         "move %0, $2\n"                                          \
         : /*out*/   "=r" (_res)                                  \
         : /*in*/    "0" (&_argvec[0])                            \
         : /*trash*/ "memory", __CALLER_SAVED_REGS                \
      );                                                          \
      lval = (__typeof__(lval)) _res;                             \
   } while (0)
#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6)   \
   do {                                                           \
      volatile OrigFn        _orig = (orig);                      \
      volatile unsigned long _argvec[7];                          \
      volatile unsigned long _res;                                \
      _argvec[0] = (unsigned long)_orig.nraddr;                   \
      _argvec[1] = (unsigned long)(arg1);                         \
      _argvec[2] = (unsigned long)(arg2);                         \
      _argvec[3] = (unsigned long)(arg3);                         \
      _argvec[4] = (unsigned long)(arg4);                         \
      _argvec[5] = (unsigned long)(arg5);                         \
      _argvec[6] = (unsigned long)(arg6);                         \
      __asm__ volatile(                                           \
         "subu $29, $29, 8 \n\t"                                  \
         "sw $28, 0($29) \n\t"                                    \
         "sw $31, 4($29) \n\t"                                    \
         "lw $4, 20(%1) \n\t"                                     \
         "subu $29, $29, 32\n\t"                                  \
         "sw $4, 16($29) \n\t"                                    \
         "lw $4, 24(%1) \n\t"                                     \
         "nop\n\t"                                                \
         "sw $4, 20($29) \n\t"                                    \
         "lw $4, 4(%1) \n\t"                                      \
         "lw $5, 8(%1) \n\t"                                      \
         "lw $6, 12(%1) \n\t"                                     \
         "lw $7, 16(%1) \n\t"                                     \
         "lw $25, 0(%1) \n\t"  /* target->t9 */                   \
         VALGRIND_CALL_NOREDIR_T9                                 \
         "addu $29, $29, 32 \n\t"                                 \
         "lw $28, 0($29) \n\t"                                    \
         "lw $31, 4($29) \n\t"                                    \
         "addu $29, $29, 8 \n\t"                                  \
         "move %0, $2\n"                                          \
         : /*out*/   "=r" (_res)                                  \
         : /*in*/    "0" (&_argvec[0])                            \
         : /*trash*/ "memory", __CALLER_SAVED_REGS                \
      );                                                          \
      lval = (__typeof__(lval)) _res;                             \
   } while (0)

#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
                                 arg7)                            \
   do {                                                           \
      volatile OrigFn        _orig = (orig);                      \
      volatile unsigned long _argvec[8];                          \
      volatile unsigned long _res;                                \
      _argvec[0] = (unsigned long)_orig.nraddr;                   \
      _argvec[1] = (unsigned long)(arg1);                         \
      _argvec[2] = (unsigned long)(arg2);                         \
      _argvec[3] = (unsigned long)(arg3);                         \
      _argvec[4] = (unsigned long)(arg4);                         \
      _argvec[5] = (unsigned long)(arg5);                         \
      _argvec[6] = (unsigned long)(arg6);                         \
      _argvec[7] = (unsigned long)(arg7);                         \
      __asm__ volatile(                                           \
         "subu $29, $29, 8 \n\t"                                  \
         "sw $28, 0($29) \n\t"                                    \
         "sw $31, 4($29) \n\t"                                    \
         "lw $4, 20(%1) \n\t"                                     \
         "subu $29, $29, 32\n\t"                                  \
         "sw $4, 16($29) \n\t"                                    \
         "lw $4, 24(%1) \n\t"                                     \
         "sw $4, 20($29) \n\t"                                    \
         "lw $4, 28(%1) \n\t"                                     \
         "sw $4, 24($29) \n\t"                                    \
         "lw $4, 4(%1) \n\t"                                      \
         "lw $5, 8(%1) \n\t"                                      \
         "lw $6, 12(%1) \n\t"                                     \
         "lw $7, 16(%1) \n\t"                                     \
         "lw $25, 0(%1) \n\t"  /* target->t9 */                   \
         VALGRIND_CALL_NOREDIR_T9                                 \
         "addu $29, $29, 32 \n\t"                                 \
         "lw $28, 0($29) \n\t"                                    \
         "lw $31, 4($29) \n\t"                                    \
         "addu $29, $29, 8 \n\t"                                  \
         "move %0, $2\n"                                          \
         : /*out*/   "=r" (_res)                                  \
         : /*in*/    "0" (&_argvec[0])                            \
         : /*trash*/ "memory", __CALLER_SAVED_REGS                \
      );                                                          \
      lval = (__typeof__(lval)) _res;                             \
   } while (0)

#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
                                 arg7,arg8)                       \
   do {                                                           \
      volatile OrigFn        _orig = (orig);                      \
      volatile unsigned long _argvec[9];                          \
      volatile unsigned long _res;                                \
      _argvec[0] = (unsigned long)_orig.nraddr;                   \
      _argvec[1] = (unsigned long)(arg1);                         \
      _argvec[2] = (unsigned long)(arg2);                         \
      _argvec[3] = (unsigned long)(arg3);                         \
      _argvec[4] = (unsigned long)(arg4);                         \
      _argvec[5] = (unsigned long)(arg5);                         \
      _argvec[6] = (unsigned long)(arg6);                         \
      _argvec[7] = (unsigned long)(arg7);                         \
      _argvec[8] = (unsigned long)(arg8);                         \
      __asm__ volatile(                                           \
         "subu $29, $29, 8 \n\t"                                  \
         "sw $28, 0($29) \n\t"                                    \
         "sw $31, 4($29) \n\t"                                    \
         "lw $4, 20(%1) \n\t"                                     \
         "subu $29, $29, 40\n\t"                                  \
         "sw $4, 16($29) \n\t"                                    \
         "lw $4, 24(%1) \n\t"                                     \
         "sw $4, 20($29) \n\t"                                    \
         "lw $4, 28(%1) \n\t"                                     \
         "sw $4, 24($29) \n\t"                                    \
         "lw $4, 32(%1) \n\t"                                     \
         "sw $4, 28($29) \n\t"                                    \
         "lw $4, 4(%1) \n\t"                                      \
         "lw $5, 8(%1) \n\t"                                      \
         "lw $6, 12(%1) \n\t"                                     \
         "lw $7, 16(%1) \n\t"                                     \
         "lw $25, 0(%1) \n\t"  /* target->t9 */                   \
         VALGRIND_CALL_NOREDIR_T9                                 \
         "addu $29, $29, 40 \n\t"                                 \
         "lw $28, 0($29) \n\t"                                    \
         "lw $31, 4($29) \n\t"                                    \
         "addu $29, $29, 8 \n\t"                                  \
         "move %0, $2\n"                                          \
         : /*out*/   "=r" (_res)                                  \
         : /*in*/    "0" (&_argvec[0])                            \
         : /*trash*/ "memory", __CALLER_SAVED_REGS                \
      );                                                          \
      lval = (__typeof__(lval)) _res;                             \
   } while (0)

#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
                                 arg7,arg8,arg9)                  \
   do {                                                           \
      volatile OrigFn        _orig = (orig);                      \
      volatile unsigned long _argvec[10];                         \
      volatile unsigned long _res;                                \
      _argvec[0] = (unsigned long)_orig.nraddr;                   \
      _argvec[1] = (unsigned long)(arg1);                         \
      _argvec[2] = (unsigned long)(arg2);                         \
      _argvec[3] = (unsigned long)(arg3);                         \
      _argvec[4] = (unsigned long)(arg4);                         \
      _argvec[5] = (unsigned long)(arg5);                         \
      _argvec[6] = (unsigned long)(arg6);                         \
      _argvec[7] = (unsigned long)(arg7);                         \
      _argvec[8] = (unsigned long)(arg8);                         \
      _argvec[9] = (unsigned long)(arg9);                         \
      __asm__ volatile(                                           \
         "subu $29, $29, 8 \n\t"                                  \
         "sw $28, 0($29) \n\t"                                    \
         "sw $31, 4($29) \n\t"                                    \
         "lw $4, 20(%1) \n\t"                                     \
         "subu $29, $29, 40\n\t"                                  \
         "sw $4, 16($29) \n\t"                                    \
         "lw $4, 24(%1) \n\t"                                     \
         "sw $4, 20($29) \n\t"                                    \
         "lw $4, 28(%1) \n\t"                                     \
         "sw $4, 24($29) \n\t"                                    \
         "lw $4, 32(%1) \n\t"                                     \
         "sw $4, 28($29) \n\t"                                    \
         "lw $4, 36(%1) \n\t"                                     \
         "sw $4, 32($29) \n\t"                                    \
         "lw $4, 4(%1) \n\t"                                      \
         "lw $5, 8(%1) \n\t"                                      \
         "lw $6, 12(%1) \n\t"                                     \
         "lw $7, 16(%1) \n\t"                                     \
         "lw $25, 0(%1) \n\t"  /* target->t9 */                   \
         VALGRIND_CALL_NOREDIR_T9                                 \
         "addu $29, $29, 40 \n\t"                                 \
         "lw $28, 0($29) \n\t"                                    \
         "lw $31, 4($29) \n\t"                                    \
         "addu $29, $29, 8 \n\t"                                  \
         "move %0, $2\n"                                          \
         : /*out*/   "=r" (_res)                                  \
         : /*in*/    "0" (&_argvec[0])                            \
         : /*trash*/ "memory", __CALLER_SAVED_REGS                \
      );                                                          \
      lval = (__typeof__(lval)) _res;                             \
   } while (0)

#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
                                  arg7,arg8,arg9,arg10)           \
   do {                                                           \
      volatile OrigFn        _orig = (orig);                      \
      volatile unsigned long _argvec[11];                         \
      volatile unsigned long _res;                                \
      _argvec[0] = (unsigned long)_orig.nraddr;                   \
      _argvec[1] = (unsigned long)(arg1);                         \
      _argvec[2] = (unsigned long)(arg2);                         \
      _argvec[3] = (unsigned long)(arg3);                         \
      _argvec[4] = (unsigned long)(arg4);                         \
      _argvec[5] = (unsigned long)(arg5);                         \
      _argvec[6] = (unsigned long)(arg6);                         \
      _argvec[7] = (unsigned long)(arg7);                         \
      _argvec[8] = (unsigned long)(arg8);                         \
      _argvec[9] = (unsigned long)(arg9);                         \
      _argvec[10] = (unsigned long)(arg10);                       \
      __asm__ volatile(                                           \
         "subu $29, $29, 8 \n\t"                                  \
         "sw $28, 0($29) \n\t"                                    \
         "sw $31, 4($29) \n\t"                                    \
         "lw $4, 20(%1) \n\t"                                     \
         "subu $29, $29, 48\n\t"                                  \
         "sw $4, 16($29) \n\t"                                    \
         "lw $4, 24(%1) \n\t"                                     \
         "sw $4, 20($29) \n\t"                                    \
         "lw $4, 28(%1) \n\t"                                     \
         "sw $4, 24($29) \n\t"                                    \
         "lw $4, 32(%1) \n\t"                                     \
         "sw $4, 28($29) \n\t"                                    \
         "lw $4, 36(%1) \n\t"                                     \
         "sw $4, 32($29) \n\t"                                    \
         "lw $4, 40(%1) \n\t"                                     \
         "sw $4, 36($29) \n\t"                                    \
         "lw $4, 4(%1) \n\t"                                      \
         "lw $5, 8(%1) \n\t"                                      \
         "lw $6, 12(%1) \n\t"                                     \
         "lw $7, 16(%1) \n\t"                                     \
         "lw $25, 0(%1) \n\t"  /* target->t9 */                   \
         VALGRIND_CALL_NOREDIR_T9                                 \
         "addu $29, $29, 48 \n\t"                                 \
         "lw $28, 0($29) \n\t"                                    \
         "lw $31, 4($29) \n\t"                                    \
         "addu $29, $29, 8 \n\t"                                  \
         "move %0, $2\n"                                          \
         : /*out*/   "=r" (_res)                                  \
         : /*in*/    "0" (&_argvec[0])                            \
         : /*trash*/ "memory", __CALLER_SAVED_REGS                \
      );                                                          \
      lval = (__typeof__(lval)) _res;                             \
   } while (0)

#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,       \
                                  arg6,arg7,arg8,arg9,arg10,      \
                                  arg11)                          \
   do {                                                           \
      volatile OrigFn        _orig = (orig);                      \
      volatile unsigned long _argvec[12];                         \
      volatile unsigned long _res;                                \
      _argvec[0] = (unsigned long)_orig.nraddr;                   \
      _argvec[1] = (unsigned long)(arg1);                         \
      _argvec[2] = (unsigned long)(arg2);                         \
      _argvec[3] = (unsigned long)(arg3);                         \
      _argvec[4] = (unsigned long)(arg4);                         \
      _argvec[5] = (unsigned long)(arg5);                         \
      _argvec[6] = (unsigned long)(arg6);                         \
      _argvec[7] = (unsigned long)(arg7);                         \
      _argvec[8] = (unsigned long)(arg8);                         \
      _argvec[9] = (unsigned long)(arg9);                         \
      _argvec[10] = (unsigned long)(arg10);                       \
      _argvec[11] = (unsigned long)(arg11);                       \
      __asm__ volatile(                                           \
         "subu $29, $29, 8 \n\t"                                  \
         "sw $28, 0($29) \n\t"                                    \
         "sw $31, 4($29) \n\t"                                    \
         "lw $4, 20(%1) \n\t"                                     \
         "subu $29, $29, 48\n\t"                                  \
         "sw $4, 16($29) \n\t"                                    \
         "lw $4, 24(%1) \n\t"                                     \
         "sw $4, 20($29) \n\t"                                    \
         "lw $4, 28(%1) \n\t"                                     \
         "sw $4, 24($29) \n\t"                                    \
         "lw $4, 32(%1) \n\t"                                     \
         "sw $4, 28($29) \n\t"                                    \
         "lw $4, 36(%1) \n\t"                                     \
         "sw $4, 32($29) \n\t"                                    \
         "lw $4, 40(%1) \n\t"                                     \
         "sw $4, 36($29) \n\t"                                    \
         "lw $4, 44(%1) \n\t"                                     \
         "sw $4, 40($29) \n\t"                                    \
         "lw $4, 4(%1) \n\t"                                      \
         "lw $5, 8(%1) \n\t"                                      \
         "lw $6, 12(%1) \n\t"                                     \
         "lw $7, 16(%1) \n\t"                                     \
         "lw $25, 0(%1) \n\t"  /* target->t9 */                   \
         VALGRIND_CALL_NOREDIR_T9                                 \
         "addu $29, $29, 48 \n\t"                                 \
         "lw $28, 0($29) \n\t"                                    \
         "lw $31, 4($29) \n\t"                                    \
         "addu $29, $29, 8 \n\t"                                  \
         "move %0, $2\n"                                          \
         : /*out*/   "=r" (_res)                                  \
         : /*in*/    "0" (&_argvec[0])                            \
         : /*trash*/ "memory", __CALLER_SAVED_REGS                \
      );                                                          \
      lval = (__typeof__(lval)) _res;                             \
   } while (0)

#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,       \
                                  arg6,arg7,arg8,arg9,arg10,      \
                                  arg11,arg12)                    \
   do {                                                           \
      volatile OrigFn        _orig = (orig);                      \
      volatile unsigned long _argvec[13];                         \
      volatile unsigned long _res;                                \
      _argvec[0] = (unsigned long)_orig.nraddr;                   \
      _argvec[1] = (unsigned long)(arg1);                         \
      _argvec[2] = (unsigned long)(arg2);                         \
      _argvec[3] = (unsigned long)(arg3);                         \
      _argvec[4] = (unsigned long)(arg4);                         \
      _argvec[5] = (unsigned long)(arg5);                         \
      _argvec[6] = (unsigned long)(arg6);                         \
      _argvec[7] = (unsigned long)(arg7);                         \
      _argvec[8] = (unsigned long)(arg8);                         \
      _argvec[9] = (unsigned long)(arg9);                         \
      _argvec[10] = (unsigned long)(arg10);                       \
      _argvec[11] = (unsigned long)(arg11);                       \
      _argvec[12] = (unsigned long)(arg12);                       \
      __asm__ volatile(                                           \
         "subu $29, $29, 8 \n\t"                                  \
         "sw $28, 0($29) \n\t"                                    \
         "sw $31, 4($29) \n\t"                                    \
         "lw $4, 20(%1) \n\t"                                     \
         "subu $29, $29, 56\n\t"                                  \
         "sw $4, 16($29) \n\t"                                    \
         "lw $4, 24(%1) \n\t"                                     \
         "sw $4, 20($29) \n\t"                                    \
         "lw $4, 28(%1) \n\t"                                     \
         "sw $4, 24($29) \n\t"                                    \
         "lw $4, 32(%1) \n\t"                                     \
         "sw $4, 28($29) \n\t"                                    \
         "lw $4, 36(%1) \n\t"                                     \
         "sw $4, 32($29) \n\t"                                    \
         "lw $4, 40(%1) \n\t"                                     \
         "sw $4, 36($29) \n\t"                                    \
         "lw $4, 44(%1) \n\t"                                     \
         "sw $4, 40($29) \n\t"                                    \
         "lw $4, 48(%1) \n\t"                                     \
         "sw $4, 44($29) \n\t"                                    \
         "lw $4, 4(%1) \n\t"                                      \
         "lw $5, 8(%1) \n\t"                                      \
         "lw $6, 12(%1) \n\t"                                     \
         "lw $7, 16(%1) \n\t"                                     \
         "lw $25, 0(%1) \n\t"  /* target->t9 */                   \
         VALGRIND_CALL_NOREDIR_T9                                 \
         "addu $29, $29, 56 \n\t"                                 \
         "lw $28, 0($29) \n\t"                                    \
         "lw $31, 4($29) \n\t"                                    \
         "addu $29, $29, 8 \n\t"                                  \
         "move %0, $2\n"                                          \
         : /*out*/   "=r" (_res)                                  \
         : /*in*/    "r" (&_argvec[0])                            \
         : /*trash*/ "memory", __CALLER_SAVED_REGS                \
      );                                                          \
      lval = (__typeof__(lval)) _res;                             \
   } while (0)

#endif /* PLAT_mips32_linux */

/* ------------------------- mips64-linux ------------------------- */

#if defined(PLAT_mips64_linux)

/* These regs are trashed by the hidden call. */
#define __CALLER_SAVED_REGS "$2", "$3", "$4", "$5", "$6",       \
"$7", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24", \
"$25", "$31"

/* These CALL_FN_ macros assume that on mips-linux, sizeof(unsigned
   long) == 4. */

#define CALL_FN_W_v(lval, orig)                                   \
   do {                                                           \
      volatile OrigFn        _orig = (orig);                      \
      volatile unsigned long _argvec[1];                          \
      volatile unsigned long _res;                                \
      _argvec[0] = (unsigned long)_orig.nraddr;                   \
      __asm__ volatile(                                           \
         "ld $25, 0(%1)\n\t"  /* target->t9 */                    \
         VALGRIND_CALL_NOREDIR_T9                                 \
         "move %0, $2\n"                                          \
         : /*out*/   "=r" (_res)                                  \
         : /*in*/    "0" (&_argvec[0])                            \
         : /*trash*/ "memory", __CALLER_SAVED_REGS                \
      );                                                          \
      lval = (__typeof__(lval)) _res;                             \
   } while (0)

#define CALL_FN_W_W(lval, orig, arg1)                             \
   do {                                                           \
      volatile OrigFn        _orig = (orig);                      \
      volatile unsigned long _argvec[2];                          \
      volatile unsigned long _res;                                \
      _argvec[0] = (unsigned long)_orig.nraddr;                   \
      _argvec[1] = (unsigned long)(arg1);                         \
      __asm__ volatile(                                           \
         "ld $4, 8(%1)\n\t"   /* arg1*/                           \
         "ld $25, 0(%1)\n\t"  /* target->t9 */                    \
         VALGRIND_CALL_NOREDIR_T9                                 \
         "move %0, $2\n"                                          \
         : /*out*/   "=r" (_res)                                  \
         : /*in*/    "r" (&_argvec[0])                            \
         : /*trash*/ "memory", __CALLER_SAVED_REGS                \
      );                                                          \
      lval = (__typeof__(lval)) _res;                             \
   } while (0)

#define CALL_FN_W_WW(lval, orig, arg1,arg2)                       \
   do {                                                           \
      volatile OrigFn        _orig = (orig);                      \
      volatile unsigned long _argvec[3];                          \
      volatile unsigned long _res;                                \
      _argvec[0] = (unsigned long)_orig.nraddr;                   \
      _argvec[1] = (unsigned long)(arg1);                         \
      _argvec[2] = (unsigned long)(arg2);                         \
      __asm__ volatile(                                           \
         "ld $4, 8(%1)\n\t"                                       \
         "ld $5, 16(%1)\n\t"                                      \
         "ld $25, 0(%1)\n\t"  /* target->t9 */                    \
         VALGRIND_CALL_NOREDIR_T9                                 \
         "move %0, $2\n"                                          \
         : /*out*/   "=r" (_res)                                  \
         : /*in*/    "r" (&_argvec[0])                            \
         : /*trash*/ "memory", __CALLER_SAVED_REGS                \
      );                                                          \
      lval = (__typeof__(lval)) _res;                             \
   } while (0)

#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3)                 \
   do {                                                           \
      volatile OrigFn        _orig = (orig);                      \
      volatile unsigned long _argvec[4];                          \
      volatile unsigned long _res;                                \
      _argvec[0] = (unsigned long)_orig.nraddr;                   \
      _argvec[1] = (unsigned long)(arg1);                         \
      _argvec[2] = (unsigned long)(arg2);                         \
      _argvec[3] = (unsigned long)(arg3);                         \
      __asm__ volatile(                                           \
         "ld $4, 8(%1)\n\t"                                       \
         "ld $5, 16(%1)\n\t"                                      \
         "ld $6, 24(%1)\n\t"                                      \
         "ld $25, 0(%1)\n\t"  /* target->t9 */                    \
         VALGRIND_CALL_NOREDIR_T9                                 \
         "move %0, $2\n"                                          \
         : /*out*/   "=r" (_res)                                  \
         : /*in*/    "r" (&_argvec[0])                            \
         : /*trash*/ "memory", __CALLER_SAVED_REGS                \
      );                                                          \
      lval = (__typeof__(lval)) _res;                             \
   } while (0)

#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4)           \
   do {                                                           \
      volatile OrigFn        _orig = (orig);                      \
      volatile unsigned long _argvec[5];                          \
      volatile unsigned long _res;                                \
      _argvec[0] = (unsigned long)_orig.nraddr;                   \
      _argvec[1] = (unsigned long)(arg1);                         \
      _argvec[2] = (unsigned long)(arg2);                         \
      _argvec[3] = (unsigned long)(arg3);                         \
      _argvec[4] = (unsigned long)(arg4);                         \
      __asm__ volatile(                                           \
         "ld $4, 8(%1)\n\t"                                       \
         "ld $5, 16(%1)\n\t"                                      \
         "ld $6, 24(%1)\n\t"                                      \
         "ld $7, 32(%1)\n\t"                                      \
         "ld $25, 0(%1)\n\t"  /* target->t9 */                    \
         VALGRIND_CALL_NOREDIR_T9                                 \
         "move %0, $2\n"                                          \
         : /*out*/   "=r" (_res)                                  \
         : /*in*/    "r" (&_argvec[0])                            \
         : /*trash*/ "memory", __CALLER_SAVED_REGS                \
      );                                                          \
      lval = (__typeof__(lval)) _res;                             \
   } while (0)

#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5)        \
   do {                                                           \
      volatile OrigFn        _orig = (orig);                      \
      volatile unsigned long _argvec[6];                          \
      volatile unsigned long _res;                                \
      _argvec[0] = (unsigned long)_orig.nraddr;                   \
      _argvec[1] = (unsigned long)(arg1);                         \
      _argvec[2] = (unsigned long)(arg2);                         \
      _argvec[3] = (unsigned long)(arg3);                         \
      _argvec[4] = (unsigned long)(arg4);                         \
      _argvec[5] = (unsigned long)(arg5);                         \
      __asm__ volatile(                                           \
         "ld $4, 8(%1)\n\t"                                       \
         "ld $5, 16(%1)\n\t"                                      \
         "ld $6, 24(%1)\n\t"                                      \
         "ld $7, 32(%1)\n\t"                                      \
         "ld $8, 40(%1)\n\t"                                      \
         "ld $25, 0(%1)\n\t"  /* target->t9 */                    \
         VALGRIND_CALL_NOREDIR_T9                                 \
         "move %0, $2\n"                                          \
         : /*out*/   "=r" (_res)                                  \
         : /*in*/    "r" (&_argvec[0])                            \
         : /*trash*/ "memory", __CALLER_SAVED_REGS                \
      );                                                          \
      lval = (__typeof__(lval)) _res;                             \
   } while (0)

#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6)   \
   do {                                                           \
      volatile OrigFn        _orig = (orig);                      \
      volatile unsigned long _argvec[7];                          \
      volatile unsigned long _res;                                \
      _argvec[0] = (unsigned long)_orig.nraddr;                   \
      _argvec[1] = (unsigned long)(arg1);                         \
      _argvec[2] = (unsigned long)(arg2);                         \
      _argvec[3] = (unsigned long)(arg3);                         \
      _argvec[4] = (unsigned long)(arg4);                         \
      _argvec[5] = (unsigned long)(arg5);                         \
      _argvec[6] = (unsigned long)(arg6);                         \
      __asm__ volatile(                                           \
         "ld $4, 8(%1)\n\t"                                       \
         "ld $5, 16(%1)\n\t"                                      \
         "ld $6, 24(%1)\n\t"                                      \
         "ld $7, 32(%1)\n\t"                                      \
         "ld $8, 40(%1)\n\t"                                      \
         "ld $9, 48(%1)\n\t"                                      \
         "ld $25, 0(%1)\n\t"  /* target->t9 */                    \
         VALGRIND_CALL_NOREDIR_T9                                 \
         "move %0, $2\n"                                          \
         : /*out*/   "=r" (_res)                                  \
         : /*in*/    "r" (&_argvec[0])                            \
         : /*trash*/ "memory", __CALLER_SAVED_REGS                \
      );                                                          \
      lval = (__typeof__(lval)) _res;                             \
   } while (0)

#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
                                 arg7)                            \
   do {                                                           \
      volatile OrigFn        _orig = (orig);                      \
      volatile unsigned long _argvec[8];                          \
      volatile unsigned long _res;                                \
      _argvec[0] = (unsigned long)_orig.nraddr;                   \
      _argvec[1] = (unsigned long)(arg1);                         \
      _argvec[2] = (unsigned long)(arg2);                         \
      _argvec[3] = (unsigned long)(arg3);                         \
      _argvec[4] = (unsigned long)(arg4);                         \
      _argvec[5] = (unsigned long)(arg5);                         \
      _argvec[6] = (unsigned long)(arg6);                         \
      _argvec[7] = (unsigned long)(arg7);                         \
      __asm__ volatile(                                           \
         "ld $4, 8(%1)\n\t"                                       \
         "ld $5, 16(%1)\n\t"                                      \
         "ld $6, 24(%1)\n\t"                                      \
         "ld $7, 32(%1)\n\t"                                      \
         "ld $8, 40(%1)\n\t"                                      \
         "ld $9, 48(%1)\n\t"                                      \
         "ld $10, 56(%1)\n\t"                                     \
         "ld $25, 0(%1) \n\t"  /* target->t9 */                   \
         VALGRIND_CALL_NOREDIR_T9                                 \
         "move %0, $2\n"                                          \
         : /*out*/   "=r" (_res)                                  \
         : /*in*/    "r" (&_argvec[0])                            \
         : /*trash*/ "memory", __CALLER_SAVED_REGS                \
      );                                                          \
      lval = (__typeof__(lval)) _res;                             \
   } while (0)

#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
                                 arg7,arg8)                       \
   do {                                                           \
      volatile OrigFn        _orig = (orig);                      \
      volatile unsigned long _argvec[9];                          \
      volatile unsigned long _res;                                \
      _argvec[0] = (unsigned long)_orig.nraddr;                   \
      _argvec[1] = (unsigned long)(arg1);                         \
      _argvec[2] = (unsigned long)(arg2);                         \
      _argvec[3] = (unsigned long)(arg3);                         \
      _argvec[4] = (unsigned long)(arg4);                         \
      _argvec[5] = (unsigned long)(arg5);                         \
      _argvec[6] = (unsigned long)(arg6);                         \
      _argvec[7] = (unsigned long)(arg7);                         \
      _argvec[8] = (unsigned long)(arg8);                         \
      __asm__ volatile(                                           \
         "ld $4, 8(%1)\n\t"                                       \
         "ld $5, 16(%1)\n\t"                                      \
         "ld $6, 24(%1)\n\t"                                      \
         "ld $7, 32(%1)\n\t"                                      \
         "ld $8, 40(%1)\n\t"                                      \
         "ld $9, 48(%1)\n\t"                                      \
         "ld $10, 56(%1)\n\t"                                     \
         "ld $11, 64(%1)\n\t"                                     \
         "ld $25, 0(%1) \n\t"  /* target->t9 */                   \
         VALGRIND_CALL_NOREDIR_T9                                 \
         "move %0, $2\n"                                          \
         : /*out*/   "=r" (_res)                                  \
         : /*in*/    "r" (&_argvec[0])                            \
         : /*trash*/ "memory", __CALLER_SAVED_REGS                \
      );                                                          \
      lval = (__typeof__(lval)) _res;                             \
   } while (0)

#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
                                 arg7,arg8,arg9)                  \
   do {                                                           \
      volatile OrigFn        _orig = (orig);                      \
      volatile unsigned long _argvec[10];                         \
      volatile unsigned long _res;                                \
      _argvec[0] = (unsigned long)_orig.nraddr;                   \
      _argvec[1] = (unsigned long)(arg1);                         \
      _argvec[2] = (unsigned long)(arg2);                         \
      _argvec[3] = (unsigned long)(arg3);                         \
      _argvec[4] = (unsigned long)(arg4);                         \
      _argvec[5] = (unsigned long)(arg5);                         \
      _argvec[6] = (unsigned long)(arg6);                         \
      _argvec[7] = (unsigned long)(arg7);                         \
      _argvec[8] = (unsigned long)(arg8);                         \
      _argvec[9] = (unsigned long)(arg9);                         \
      __asm__ volatile(                                           \
         "dsubu $29, $29, 8\n\t"                                  \
         "ld $4, 72(%1)\n\t"                                      \
         "sd $4, 0($29)\n\t"                                      \
         "ld $4, 8(%1)\n\t"                                       \
         "ld $5, 16(%1)\n\t"                                      \
         "ld $6, 24(%1)\n\t"                                      \
         "ld $7, 32(%1)\n\t"                                      \
         "ld $8, 40(%1)\n\t"                                      \
         "ld $9, 48(%1)\n\t"                                      \
         "ld $10, 56(%1)\n\t"                                     \
         "ld $11, 64(%1)\n\t"                                     \
         "ld $25, 0(%1)\n\t"  /* target->t9 */                    \
         VALGRIND_CALL_NOREDIR_T9                                 \
         "daddu $29, $29, 8\n\t"                                  \
         "move %0, $2\n"                                          \
         : /*out*/   "=r" (_res)                                  \
         : /*in*/    "r" (&_argvec[0])                            \
         : /*trash*/ "memory", __CALLER_SAVED_REGS                \
      );                                                          \
      lval = (__typeof__(lval)) _res;                             \
   } while (0)

#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
                                  arg7,arg8,arg9,arg10)           \
   do {                                                           \
      volatile OrigFn        _orig = (orig);                      \
      volatile unsigned long _argvec[11];                         \
      volatile unsigned long _res;                                \
      _argvec[0] = (unsigned long)_orig.nraddr;                   \
      _argvec[1] = (unsigned long)(arg1);                         \
      _argvec[2] = (unsigned long)(arg2);                         \
      _argvec[3] = (unsigned long)(arg3);                         \
      _argvec[4] = (unsigned long)(arg4);                         \
      _argvec[5] = (unsigned long)(arg5);                         \
      _argvec[6] = (unsigned long)(arg6);                         \
      _argvec[7] = (unsigned long)(arg7);                         \
      _argvec[8] = (unsigned long)(arg8);                         \
      _argvec[9] = (unsigned long)(arg9);                         \
      _argvec[10] = (unsigned long)(arg10);                       \
      __asm__ volatile(                                           \
         "dsubu $29, $29, 16\n\t"                                 \
         "ld $4, 72(%1)\n\t"                                      \
         "sd $4, 0($29)\n\t"                                      \
         "ld $4, 80(%1)\n\t"                                      \
         "sd $4, 8($29)\n\t"                                      \
         "ld $4, 8(%1)\n\t"                                       \
         "ld $5, 16(%1)\n\t"                                      \
         "ld $6, 24(%1)\n\t"                                      \
         "ld $7, 32(%1)\n\t"                                      \
         "ld $8, 40(%1)\n\t"                                      \
         "ld $9, 48(%1)\n\t"                                      \
         "ld $10, 56(%1)\n\t"                                     \
         "ld $11, 64(%1)\n\t"                                     \
         "ld $25, 0(%1)\n\t"  /* target->t9 */                    \
         VALGRIND_CALL_NOREDIR_T9                                 \
         "daddu $29, $29, 16\n\t"                                 \
         "move %0, $2\n"                                          \
         : /*out*/   "=r" (_res)                                  \
         : /*in*/    "r" (&_argvec[0])                            \
         : /*trash*/ "memory", __CALLER_SAVED_REGS                \
      );                                                          \
      lval = (__typeof__(lval)) _res;                             \
   } while (0)

#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,       \
                                  arg6,arg7,arg8,arg9,arg10,      \
                                  arg11)                          \
   do {                                                           \
      volatile OrigFn        _orig = (orig);                      \
      volatile unsigned long _argvec[12];                         \
      volatile unsigned long _res;                                \
      _argvec[0] = (unsigned long)_orig.nraddr;                   \
      _argvec[1] = (unsigned long)(arg1);                         \
      _argvec[2] = (unsigned long)(arg2);                         \
      _argvec[3] = (unsigned long)(arg3);                         \
      _argvec[4] = (unsigned long)(arg4);                         \
      _argvec[5] = (unsigned long)(arg5);                         \
      _argvec[6] = (unsigned long)(arg6);                         \
      _argvec[7] = (unsigned long)(arg7);                         \
      _argvec[8] = (unsigned long)(arg8);                         \
      _argvec[9] = (unsigned long)(arg9);                         \
      _argvec[10] = (unsigned long)(arg10);                       \
      _argvec[11] = (unsigned long)(arg11);                       \
      __asm__ volatile(                                           \
         "dsubu $29, $29, 24\n\t"                                 \
         "ld $4, 72(%1)\n\t"                                      \
         "sd $4, 0($29)\n\t"                                      \
         "ld $4, 80(%1)\n\t"                                      \
         "sd $4, 8($29)\n\t"                                      \
         "ld $4, 88(%1)\n\t"                                      \
         "sd $4, 16($29)\n\t"                                     \
         "ld $4, 8(%1)\n\t"                                       \
         "ld $5, 16(%1)\n\t"                                      \
         "ld $6, 24(%1)\n\t"                                      \
         "ld $7, 32(%1)\n\t"                                      \
         "ld $8, 40(%1)\n\t"                                      \
         "ld $9, 48(%1)\n\t"                                      \
         "ld $10, 56(%1)\n\t"                                     \
         "ld $11, 64(%1)\n\t"                                     \
         "ld $25, 0(%1)\n\t"  /* target->t9 */                    \
         VALGRIND_CALL_NOREDIR_T9                                 \
         "daddu $29, $29, 24\n\t"                                 \
         "move %0, $2\n"                                          \
         : /*out*/   "=r" (_res)                                  \
         : /*in*/    "r" (&_argvec[0])                            \
         : /*trash*/ "memory", __CALLER_SAVED_REGS                \
      );                                                          \
      lval = (__typeof__(lval)) _res;                             \
   } while (0)

#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,       \
                                  arg6,arg7,arg8,arg9,arg10,      \
                                  arg11,arg12)                    \
   do {                                                           \
      volatile OrigFn        _orig = (orig);                      \
      volatile unsigned long _argvec[13];                         \
      volatile unsigned long _res;                                \
      _argvec[0] = (unsigned long)_orig.nraddr;                   \
      _argvec[1] = (unsigned long)(arg1);                         \
      _argvec[2] = (unsigned long)(arg2);                         \
      _argvec[3] = (unsigned long)(arg3);                         \
      _argvec[4] = (unsigned long)(arg4);                         \
      _argvec[5] = (unsigned long)(arg5);                         \
      _argvec[6] = (unsigned long)(arg6);                         \
      _argvec[7] = (unsigned long)(arg7);                         \
      _argvec[8] = (unsigned long)(arg8);                         \
      _argvec[9] = (unsigned long)(arg9);                         \
      _argvec[10] = (unsigned long)(arg10);                       \
      _argvec[11] = (unsigned long)(arg11);                       \
      _argvec[12] = (unsigned long)(arg12);                       \
      __asm__ volatile(                                           \
         "dsubu $29, $29, 32\n\t"                                 \
         "ld $4, 72(%1)\n\t"                                      \
         "sd $4, 0($29)\n\t"                                      \
         "ld $4, 80(%1)\n\t"                                      \
         "sd $4, 8($29)\n\t"                                      \
         "ld $4, 88(%1)\n\t"                                      \
         "sd $4, 16($29)\n\t"                                     \
         "ld $4, 96(%1)\n\t"                                      \
         "sd $4, 24($29)\n\t"                                     \
         "ld $4, 8(%1)\n\t"                                       \
         "ld $5, 16(%1)\n\t"                                      \
         "ld $6, 24(%1)\n\t"                                      \
         "ld $7, 32(%1)\n\t"                                      \
         "ld $8, 40(%1)\n\t"                                      \
         "ld $9, 48(%1)\n\t"                                      \
         "ld $10, 56(%1)\n\t"                                     \
         "ld $11, 64(%1)\n\t"                                     \
         "ld $25, 0(%1)\n\t"  /* target->t9 */                    \
         VALGRIND_CALL_NOREDIR_T9                                 \
         "daddu $29, $29, 32\n\t"                                 \
         "move %0, $2\n"                                          \
         : /*out*/   "=r" (_res)                                  \
         : /*in*/    "r" (&_argvec[0])                            \
         : /*trash*/ "memory", __CALLER_SAVED_REGS                \
      );                                                          \
      lval = (__typeof__(lval)) _res;                             \
   } while (0)

#endif /* PLAT_mips64_linux */

/* ------------------------------------------------------------------ */
/* ARCHITECTURE INDEPENDENT MACROS for CLIENT REQUESTS.               */
/*                                                                    */
/* ------------------------------------------------------------------ */

/* Some request codes.  There are many more of these, but most are not
   exposed to end-user view.  These are the public ones, all of the
   form 0x1000 + small_number.

   Core ones are in the range 0x00000000--0x0000ffff.  The non-public
   ones start at 0x2000.
*/

/* These macros are used by tools -- they must be public, but don't
   embed them into other programs. */
#define VG_USERREQ_TOOL_BASE(a,b) \
   ((unsigned int)(((a)&0xff) << 24 | ((b)&0xff) << 16))
#define VG_IS_TOOL_USERREQ(a, b, v) \
   (VG_USERREQ_TOOL_BASE(a,b) == ((v) & 0xffff0000))

/* !! ABIWARNING !! ABIWARNING !! ABIWARNING !! ABIWARNING !! 
   This enum comprises an ABI exported by Valgrind to programs
   which use client requests.  DO NOT CHANGE THE NUMERIC VALUES OF THESE
   ENTRIES, NOR DELETE ANY -- add new ones at the end of the most
   relevant group. */
typedef
   enum { VG_USERREQ__RUNNING_ON_VALGRIND  = 0x1001,
          VG_USERREQ__DISCARD_TRANSLATIONS = 0x1002,

          /* These allow any function to be called from the simulated
             CPU but run on the real CPU.  Nb: the first arg passed to
             the function is always the ThreadId of the running
             thread!  So CLIENT_CALL0 actually requires a 1 arg
             function, etc. */
          VG_USERREQ__CLIENT_CALL0 = 0x1101,
          VG_USERREQ__CLIENT_CALL1 = 0x1102,
          VG_USERREQ__CLIENT_CALL2 = 0x1103,
          VG_USERREQ__CLIENT_CALL3 = 0x1104,

          /* Can be useful in regression testing suites -- eg. can
             send Valgrind's output to /dev/null and still count
             errors. */
          VG_USERREQ__COUNT_ERRORS = 0x1201,

          /* Allows the client program and/or gdbserver to execute a monitor
             command. */
          VG_USERREQ__GDB_MONITOR_COMMAND = 0x1202,

          /* These are useful and can be interpreted by any tool that
             tracks malloc() et al, by using vg_replace_malloc.c. */
          VG_USERREQ__MALLOCLIKE_BLOCK = 0x1301,
          VG_USERREQ__RESIZEINPLACE_BLOCK = 0x130b,
          VG_USERREQ__FREELIKE_BLOCK   = 0x1302,
          /* Memory pool support. */
          VG_USERREQ__CREATE_MEMPOOL   = 0x1303,
          VG_USERREQ__DESTROY_MEMPOOL  = 0x1304,
          VG_USERREQ__MEMPOOL_ALLOC    = 0x1305,
          VG_USERREQ__MEMPOOL_FREE     = 0x1306,
          VG_USERREQ__MEMPOOL_TRIM     = 0x1307,
          VG_USERREQ__MOVE_MEMPOOL     = 0x1308,
          VG_USERREQ__MEMPOOL_CHANGE   = 0x1309,
          VG_USERREQ__MEMPOOL_EXISTS   = 0x130a,

          /* Allow printfs to valgrind log. */
          /* The first two pass the va_list argument by value, which
             assumes it is the same size as or smaller than a UWord,
             which generally isn't the case.  Hence are deprecated.
             The second two pass the vargs by reference and so are
             immune to this problem. */
          /* both :: char* fmt, va_list vargs (DEPRECATED) */
          VG_USERREQ__PRINTF           = 0x1401,
          VG_USERREQ__PRINTF_BACKTRACE = 0x1402,
          /* both :: char* fmt, va_list* vargs */
          VG_USERREQ__PRINTF_VALIST_BY_REF = 0x1403,
          VG_USERREQ__PRINTF_BACKTRACE_VALIST_BY_REF = 0x1404,

          /* Stack support. */
          VG_USERREQ__STACK_REGISTER   = 0x1501,
          VG_USERREQ__STACK_DEREGISTER = 0x1502,
          VG_USERREQ__STACK_CHANGE     = 0x1503,

          /* Wine support */
          VG_USERREQ__LOAD_PDB_DEBUGINFO = 0x1601,

          /* Querying of debug info. */
          VG_USERREQ__MAP_IP_TO_SRCLOC = 0x1701,

          /* Disable/enable error reporting level.  Takes a single
             Word arg which is the delta to this thread's error
             disablement indicator.  Hence 1 disables or further
             disables errors, and -1 moves back towards enablement.
             Other values are not allowed. */
          VG_USERREQ__CHANGE_ERR_DISABLEMENT = 0x1801,

          /* Some requests used for Valgrind internal, such as
             self-test or self-hosting. */
          /* Initialise IR injection */
          VG_USERREQ__VEX_INIT_FOR_IRI = 0x1901,
          /* Used by Inner Valgrind to inform Outer Valgrind where to
             find the list of inner guest threads */
          VG_USERREQ__INNER_THREADS    = 0x1902
   } Vg_ClientRequest;

#if !defined(__GNUC__)
#  define __extension__ /* */
#endif


/* Returns the number of Valgrinds this code is running under.  That
   is, 0 if running natively, 1 if running under Valgrind, 2 if
   running under Valgrind which is running under another Valgrind,
   etc. */
#define RUNNING_ON_VALGRIND                                           \
    (unsigned)VALGRIND_DO_CLIENT_REQUEST_EXPR(0 /* if not */,         \
                                    VG_USERREQ__RUNNING_ON_VALGRIND,  \
                                    0, 0, 0, 0, 0)                    \


/* Discard translation of code in the range [_qzz_addr .. _qzz_addr +
   _qzz_len - 1].  Useful if you are debugging a JITter or some such,
   since it provides a way to make sure valgrind will retranslate the
   invalidated area.  Returns no value. */
#define VALGRIND_DISCARD_TRANSLATIONS(_qzz_addr,_qzz_len)              \
    VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__DISCARD_TRANSLATIONS,  \
                                    _qzz_addr, _qzz_len, 0, 0, 0)

#define VALGRIND_INNER_THREADS(_qzz_addr)                               \
   VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__INNER_THREADS,           \
                                   _qzz_addr, 0, 0, 0, 0)


/* These requests are for getting Valgrind itself to print something.
   Possibly with a backtrace.  This is a really ugly hack.  The return value
   is the number of characters printed, excluding the "**<pid>** " part at the
   start and the backtrace (if present). */

#if defined(__GNUC__) || defined(__INTEL_COMPILER) && !defined(_MSC_VER)
/* Modern GCC will optimize the static routine out if unused,
   and unused attribute will shut down warnings about it.  */
static int VALGRIND_PRINTF(const char *format, ...)
   __attribute__((format(__printf__, 1, 2), __unused__));
#endif
static int
#if defined(_MSC_VER)
__inline
#endif
VALGRIND_PRINTF(const char *format, ...)
{
#if defined(NVALGRIND)
   (void)format;
   return 0;
#else /* NVALGRIND */
#if defined(_MSC_VER) || defined(__MINGW64__)
   uintptr_t _qzz_res;
#else
   unsigned long _qzz_res;
#endif
   va_list vargs;
   va_start(vargs, format);
#if defined(_MSC_VER) || defined(__MINGW64__)
   _qzz_res = VALGRIND_DO_CLIENT_REQUEST_EXPR(0,
                              VG_USERREQ__PRINTF_VALIST_BY_REF,
                              (uintptr_t)format,
                              (uintptr_t)&vargs,
                              0, 0, 0);
#else
   _qzz_res = VALGRIND_DO_CLIENT_REQUEST_EXPR(0,
                              VG_USERREQ__PRINTF_VALIST_BY_REF,
                              (unsigned long)format,
                              (unsigned long)&vargs, 
                              0, 0, 0);
#endif
   va_end(vargs);
   return (int)_qzz_res;
#endif /* NVALGRIND */
}

#if defined(__GNUC__) || defined(__INTEL_COMPILER) && !defined(_MSC_VER)
static int VALGRIND_PRINTF_BACKTRACE(const char *format, ...)
   __attribute__((format(__printf__, 1, 2), __unused__));
#endif
static int
#if defined(_MSC_VER)
__inline
#endif
VALGRIND_PRINTF_BACKTRACE(const char *format, ...)
{
#if defined(NVALGRIND)
   (void)format;
   return 0;
#else /* NVALGRIND */
#if defined(_MSC_VER) || defined(__MINGW64__)
   uintptr_t _qzz_res;
#else
   unsigned long _qzz_res;
#endif
   va_list vargs;
   va_start(vargs, format);
#if defined(_MSC_VER) || defined(__MINGW64__)
   _qzz_res = VALGRIND_DO_CLIENT_REQUEST_EXPR(0,
                              VG_USERREQ__PRINTF_BACKTRACE_VALIST_BY_REF,
                              (uintptr_t)format,
                              (uintptr_t)&vargs,
                              0, 0, 0);
#else
   _qzz_res = VALGRIND_DO_CLIENT_REQUEST_EXPR(0,
                              VG_USERREQ__PRINTF_BACKTRACE_VALIST_BY_REF,
                              (unsigned long)format,
                              (unsigned long)&vargs, 
                              0, 0, 0);
#endif
   va_end(vargs);
   return (int)_qzz_res;
#endif /* NVALGRIND */
}


/* These requests allow control to move from the simulated CPU to the
   real CPU, calling an arbitrary function.
   
   Note that the current ThreadId is inserted as the first argument.
   So this call:

     VALGRIND_NON_SIMD_CALL2(f, arg1, arg2)

   requires f to have this signature:

     Word f(Word tid, Word arg1, Word arg2)

   where "Word" is a word-sized type.

   Note that these client requests are not entirely reliable.  For example,
   if you call a function with them that subsequently calls printf(),
   there's a high chance Valgrind will crash.  Generally, your prospects of
   these working are made higher if the called function does not refer to
   any global variables, and does not refer to any libc or other functions
   (printf et al).  Any kind of entanglement with libc or dynamic linking is
   likely to have a bad outcome, for tricky reasons which we've grappled
   with a lot in the past.
*/
#define VALGRIND_NON_SIMD_CALL0(_qyy_fn)                          \
    VALGRIND_DO_CLIENT_REQUEST_EXPR(0 /* default return */,       \
                                    VG_USERREQ__CLIENT_CALL0,     \
                                    _qyy_fn,                      \
                                    0, 0, 0, 0)

#define VALGRIND_NON_SIMD_CALL1(_qyy_fn, _qyy_arg1)                    \
    VALGRIND_DO_CLIENT_REQUEST_EXPR(0 /* default return */,            \
                                    VG_USERREQ__CLIENT_CALL1,          \
                                    _qyy_fn,                           \
                                    _qyy_arg1, 0, 0, 0)

#define VALGRIND_NON_SIMD_CALL2(_qyy_fn, _qyy_arg1, _qyy_arg2)         \
    VALGRIND_DO_CLIENT_REQUEST_EXPR(0 /* default return */,            \
                                    VG_USERREQ__CLIENT_CALL2,          \
                                    _qyy_fn,                           \
                                    _qyy_arg1, _qyy_arg2, 0, 0)

#define VALGRIND_NON_SIMD_CALL3(_qyy_fn, _qyy_arg1, _qyy_arg2, _qyy_arg3) \
    VALGRIND_DO_CLIENT_REQUEST_EXPR(0 /* default return */,             \
                                    VG_USERREQ__CLIENT_CALL3,           \
                                    _qyy_fn,                            \
                                    _qyy_arg1, _qyy_arg2,               \
                                    _qyy_arg3, 0)


/* Counts the number of errors that have been recorded by a tool.  Nb:
   the tool must record the errors with VG_(maybe_record_error)() or
   VG_(unique_error)() for them to be counted. */
#define VALGRIND_COUNT_ERRORS                                     \
    (unsigned)VALGRIND_DO_CLIENT_REQUEST_EXPR(                    \
                               0 /* default return */,            \
                               VG_USERREQ__COUNT_ERRORS,          \
                               0, 0, 0, 0, 0)

/* Several Valgrind tools (Memcheck, Massif, Helgrind, DRD) rely on knowing
   when heap blocks are allocated in order to give accurate results.  This
   happens automatically for the standard allocator functions such as
   malloc(), calloc(), realloc(), memalign(), new, new[], free(), delete,
   delete[], etc.

   But if your program uses a custom allocator, this doesn't automatically
   happen, and Valgrind will not do as well.  For example, if you allocate
   superblocks with mmap() and then allocates chunks of the superblocks, all
   Valgrind's observations will be at the mmap() level and it won't know that
   the chunks should be considered separate entities.  In Memcheck's case,
   that means you probably won't get heap block overrun detection (because
   there won't be redzones marked as unaddressable) and you definitely won't
   get any leak detection.

   The following client requests allow a custom allocator to be annotated so
   that it can be handled accurately by Valgrind.

   VALGRIND_MALLOCLIKE_BLOCK marks a region of memory as having been allocated
   by a malloc()-like function.  For Memcheck (an illustrative case), this
   does two things:

   - It records that the block has been allocated.  This means any addresses
     within the block mentioned in error messages will be
     identified as belonging to the block.  It also means that if the block
     isn't freed it will be detected by the leak checker.

   - It marks the block as being addressable and undefined (if 'is_zeroed' is
     not set), or addressable and defined (if 'is_zeroed' is set).  This
     controls how accesses to the block by the program are handled.
   
   'addr' is the start of the usable block (ie. after any
   redzone), 'sizeB' is its size.  'rzB' is the redzone size if the allocator
   can apply redzones -- these are blocks of padding at the start and end of
   each block.  Adding redzones is recommended as it makes it much more likely
   Valgrind will spot block overruns.  `is_zeroed' indicates if the memory is
   zeroed (or filled with another predictable value), as is the case for
   calloc().
   
   VALGRIND_MALLOCLIKE_BLOCK should be put immediately after the point where a
   heap block -- that will be used by the client program -- is allocated.
   It's best to put it at the outermost level of the allocator if possible;
   for example, if you have a function my_alloc() which calls
   internal_alloc(), and the client request is put inside internal_alloc(),
   stack traces relating to the heap block will contain entries for both
   my_alloc() and internal_alloc(), which is probably not what you want.

   For Memcheck users: if you use VALGRIND_MALLOCLIKE_BLOCK to carve out
   custom blocks from within a heap block, B, that has been allocated with
   malloc/calloc/new/etc, then block B will be *ignored* during leak-checking
   -- the custom blocks will take precedence.

   VALGRIND_FREELIKE_BLOCK is the partner to VALGRIND_MALLOCLIKE_BLOCK.  For
   Memcheck, it does two things:

   - It records that the block has been deallocated.  This assumes that the
     block was annotated as having been allocated via
     VALGRIND_MALLOCLIKE_BLOCK.  Otherwise, an error will be issued.

   - It marks the block as being unaddressable.

   VALGRIND_FREELIKE_BLOCK should be put immediately after the point where a
   heap block is deallocated.

   VALGRIND_RESIZEINPLACE_BLOCK informs a tool about reallocation. For
   Memcheck, it does four things:

   - It records that the size of a block has been changed.  This assumes that
     the block was annotated as having been allocated via
     VALGRIND_MALLOCLIKE_BLOCK.  Otherwise, an error will be issued.

   - If the block shrunk, it marks the freed memory as being unaddressable.

   - If the block grew, it marks the new area as undefined and defines a red
     zone past the end of the new block.

   - The V-bits of the overlap between the old and the new block are preserved.

   VALGRIND_RESIZEINPLACE_BLOCK should be put after allocation of the new block
   and before deallocation of the old block.

   In many cases, these three client requests will not be enough to get your
   allocator working well with Memcheck.  More specifically, if your allocator
   writes to freed blocks in any way then a VALGRIND_MAKE_MEM_UNDEFINED call
   will be necessary to mark the memory as addressable just before the zeroing
   occurs, otherwise you'll get a lot of invalid write errors.  For example,
   you'll need to do this if your allocator recycles freed blocks, but it
   zeroes them before handing them back out (via VALGRIND_MALLOCLIKE_BLOCK).
   Alternatively, if your allocator reuses freed blocks for allocator-internal
   data structures, VALGRIND_MAKE_MEM_UNDEFINED calls will also be necessary.

   Really, what's happening is a blurring of the lines between the client
   program and the allocator... after VALGRIND_FREELIKE_BLOCK is called, the
   memory should be considered unaddressable to the client program, but the
   allocator knows more than the rest of the client program and so may be able
   to safely access it.  Extra client requests are necessary for Valgrind to
   understand the distinction between the allocator and the rest of the
   program.

   Ignored if addr == 0.
*/
#define VALGRIND_MALLOCLIKE_BLOCK(addr, sizeB, rzB, is_zeroed)          \
    VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__MALLOCLIKE_BLOCK,       \
                                    addr, sizeB, rzB, is_zeroed, 0)

/* See the comment for VALGRIND_MALLOCLIKE_BLOCK for details.
   Ignored if addr == 0.
*/
#define VALGRIND_RESIZEINPLACE_BLOCK(addr, oldSizeB, newSizeB, rzB)     \
    VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__RESIZEINPLACE_BLOCK,    \
                                    addr, oldSizeB, newSizeB, rzB, 0)

/* See the comment for VALGRIND_MALLOCLIKE_BLOCK for details.
   Ignored if addr == 0.
*/
#define VALGRIND_FREELIKE_BLOCK(addr, rzB)                              \
    VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__FREELIKE_BLOCK,         \
                                    addr, rzB, 0, 0, 0)

/* Create a memory pool. */
#define VALGRIND_CREATE_MEMPOOL(pool, rzB, is_zeroed)             \
    VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__CREATE_MEMPOOL,   \
                                    pool, rzB, is_zeroed, 0, 0)

/* Create a memory pool with some flags specifying extended behaviour.
   When flags is zero, the behaviour is identical to VALGRIND_CREATE_MEMPOOL.
   
   The flag VALGRIND_MEMPOOL_METAPOOL specifies that the pieces of memory 
   associated with the pool using VALGRIND_MEMPOOL_ALLOC  will be used
   by the application as superblocks to dole out MALLOC_LIKE blocks using
   VALGRIND_MALLOCLIKE_BLOCK. In other words, a meta pool is a "2 levels"
   pool : first level is the blocks described by VALGRIND_MEMPOOL_ALLOC.
   The second level blocks are described using VALGRIND_MALLOCLIKE_BLOCK.
   Note that the association between the pool and the second level blocks
   is implicit : second level blocks will be located inside first level
   blocks. It is necessary to use the VALGRIND_MEMPOOL_METAPOOL flag
   for such 2 levels pools, as otherwise valgrind will detect overlapping
   memory blocks, and will abort execution (e.g. during leak search).

   Such a meta pool can also be marked as an 'auto free' pool using the flag
   VALGRIND_MEMPOOL_AUTO_FREE, which must be OR-ed together with the
   VALGRIND_MEMPOOL_METAPOOL. For an 'auto free' pool, VALGRIND_MEMPOOL_FREE
   will automatically free the second level blocks that are contained
   inside the first level block freed with VALGRIND_MEMPOOL_FREE.
   In other words, calling VALGRIND_MEMPOOL_FREE will cause implicit calls
   to VALGRIND_FREELIKE_BLOCK for all the second level blocks included
   in the first level block.
   Note: it is an error to use the VALGRIND_MEMPOOL_AUTO_FREE flag
   without the VALGRIND_MEMPOOL_METAPOOL flag.
*/
#define VALGRIND_MEMPOOL_AUTO_FREE  1
#define VALGRIND_MEMPOOL_METAPOOL   2
#define VALGRIND_CREATE_MEMPOOL_EXT(pool, rzB, is_zeroed, flags)        \
   VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__CREATE_MEMPOOL,          \
                                   pool, rzB, is_zeroed, flags, 0)

/* Destroy a memory pool. */
#define VALGRIND_DESTROY_MEMPOOL(pool)                            \
    VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__DESTROY_MEMPOOL,  \
                                    pool, 0, 0, 0, 0)

/* Associate a piece of memory with a memory pool. */
#define VALGRIND_MEMPOOL_ALLOC(pool, addr, size)                  \
    VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__MEMPOOL_ALLOC,    \
                                    pool, addr, size, 0, 0)

/* Disassociate a piece of memory from a memory pool. */
#define VALGRIND_MEMPOOL_FREE(pool, addr)                         \
    VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__MEMPOOL_FREE,     \
                                    pool, addr, 0, 0, 0)

/* Disassociate any pieces outside a particular range. */
#define VALGRIND_MEMPOOL_TRIM(pool, addr, size)                   \
    VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__MEMPOOL_TRIM,     \
                                    pool, addr, size, 0, 0)

/* Resize and/or move a piece associated with a memory pool. */
#define VALGRIND_MOVE_MEMPOOL(poolA, poolB)                       \
    VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__MOVE_MEMPOOL,     \
                                    poolA, poolB, 0, 0, 0)

/* Resize and/or move a piece associated with a memory pool. */
#define VALGRIND_MEMPOOL_CHANGE(pool, addrA, addrB, size)         \
    VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__MEMPOOL_CHANGE,   \
                                    pool, addrA, addrB, size, 0)

/* Return 1 if a mempool exists, else 0. */
#define VALGRIND_MEMPOOL_EXISTS(pool)                             \
    (unsigned)VALGRIND_DO_CLIENT_REQUEST_EXPR(0,                  \
                               VG_USERREQ__MEMPOOL_EXISTS,        \
                               pool, 0, 0, 0, 0)

/* Mark a piece of memory as being a stack. Returns a stack id.
   start is the lowest addressable stack byte, end is the highest
   addressable stack byte. */
#define VALGRIND_STACK_REGISTER(start, end)                       \
    (unsigned)VALGRIND_DO_CLIENT_REQUEST_EXPR(0,                  \
                               VG_USERREQ__STACK_REGISTER,        \
                               start, end, 0, 0, 0)

/* Unmark the piece of memory associated with a stack id as being a
   stack. */
#define VALGRIND_STACK_DEREGISTER(id)                             \
    VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__STACK_DEREGISTER, \
                                    id, 0, 0, 0, 0)

/* Change the start and end address of the stack id.
   start is the new lowest addressable stack byte, end is the new highest
   addressable stack byte. */
#define VALGRIND_STACK_CHANGE(id, start, end)                     \
    VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__STACK_CHANGE,     \
                                    id, start, end, 0, 0)

/* Load PDB debug info for Wine PE image_map. */
#define VALGRIND_LOAD_PDB_DEBUGINFO(fd, ptr, total_size, delta)     \
    VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__LOAD_PDB_DEBUGINFO, \
                                    fd, ptr, total_size, delta, 0)

/* Map a code address to a source file name and line number.  buf64
   must point to a 64-byte buffer in the caller's address space.  The
   result will be dumped in there and is guaranteed to be zero
   terminated.  If no info is found, the first byte is set to zero. */
#define VALGRIND_MAP_IP_TO_SRCLOC(addr, buf64)                    \
    (unsigned)VALGRIND_DO_CLIENT_REQUEST_EXPR(0,                  \
                               VG_USERREQ__MAP_IP_TO_SRCLOC,      \
                               addr, buf64, 0, 0, 0)

/* Disable error reporting for this thread.  Behaves in a stack like
   way, so you can safely call this multiple times provided that
   VALGRIND_ENABLE_ERROR_REPORTING is called the same number of times
   to re-enable reporting.  The first call of this macro disables
   reporting.  Subsequent calls have no effect except to increase the
   number of VALGRIND_ENABLE_ERROR_REPORTING calls needed to re-enable
   reporting.  Child threads do not inherit this setting from their
   parents -- they are always created with reporting enabled. */
#define VALGRIND_DISABLE_ERROR_REPORTING                                \
    VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__CHANGE_ERR_DISABLEMENT, \
                                    1, 0, 0, 0, 0)

/* Re-enable error reporting, as per comments on
   VALGRIND_DISABLE_ERROR_REPORTING. */
#define VALGRIND_ENABLE_ERROR_REPORTING                                 \
    VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__CHANGE_ERR_DISABLEMENT, \
                                    -1, 0, 0, 0, 0)

/* Execute a monitor command from the client program.
   If a connection is opened with GDB, the output will be sent
   according to the output mode set for vgdb.
   If no connection is opened, output will go to the log output.
   Returns 1 if command not recognised, 0 otherwise. */
#define VALGRIND_MONITOR_COMMAND(command)                               \
   VALGRIND_DO_CLIENT_REQUEST_EXPR(0, VG_USERREQ__GDB_MONITOR_COMMAND, \
                                   command, 0, 0, 0, 0)


#undef PLAT_x86_darwin
#undef PLAT_amd64_darwin
#undef PLAT_x86_win32
#undef PLAT_amd64_win64
#undef PLAT_x86_linux
#undef PLAT_amd64_linux
#undef PLAT_ppc32_linux
#undef PLAT_ppc64be_linux
#undef PLAT_ppc64le_linux
#undef PLAT_arm_linux
#undef PLAT_s390x_linux
#undef PLAT_mips32_linux
#undef PLAT_mips64_linux
#undef PLAT_x86_solaris
#undef PLAT_amd64_solaris

#endif   /* __VALGRIND_H */

===== ./common/flatpak-transaction.h =====
/*
 * Copyright © 2016 Red Hat, Inc
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Alexander Larsson <alexl@redhat.com>
 */

#if !defined(__FLATPAK_H_INSIDE__) && !defined(FLATPAK_COMPILATION)
#error "Only <flatpak.h> can be included directly."
#endif

#ifndef __FLATPAK_TRANSACTION_H__
#define __FLATPAK_TRANSACTION_H__

#include <gio/gio.h>
#include <flatpak-installation.h>

G_BEGIN_DECLS

#define FLATPAK_TYPE_TRANSACTION flatpak_transaction_get_type ()
#define FLATPAK_TYPE_TRANSACTION_PROGRESS flatpak_transaction_progress_get_type ()
#define FLATPAK_TYPE_TRANSACTION_OPERATION flatpak_transaction_operation_get_type ()

/**
 * FlatpakTransactionOperationType
 * @FLATPAK_TRANSACTION_OPERATION_INSTALL: Install a ref from a remote
 * @FLATPAK_TRANSACTION_OPERATION_UPDATE: Update an installed ref
 * @FLATPAK_TRANSACTION_OPERATION_INSTALL_BUNDLE: Install a bundle from a file
 * @FLATPAK_TRANSACTION_OPERATION_UNINSTALL: Uninstall a ref
 * @FLATPAK_TRANSACTION_OPERATION_LAST_TYPE: The (currently) last operation type
 *
 * The type of a #FlatpakTransactionOperation.
 */
typedef enum {
  FLATPAK_TRANSACTION_OPERATION_INSTALL,
  FLATPAK_TRANSACTION_OPERATION_UPDATE,
  FLATPAK_TRANSACTION_OPERATION_INSTALL_BUNDLE,
  FLATPAK_TRANSACTION_OPERATION_UNINSTALL,
  FLATPAK_TRANSACTION_OPERATION_LAST_TYPE
} FlatpakTransactionOperationType;

/**
 * FlatpakTransactionErrorDetails
 * @FLATPAK_TRANSACTION_ERROR_DETAILS_NON_FATAL: The operation failure was not fatal
 *
 * The details for #FlatpakTransaction::operation-error.
 */
typedef enum {
  FLATPAK_TRANSACTION_ERROR_DETAILS_NON_FATAL = 1 << 0,
} FlatpakTransactionErrorDetails;

/**
 * FlatpakTransactionResult
 * @FLATPAK_TRANSACTION_RESULT_NO_CHANGE: The update caused no changes
 *
 * The details for #FlatpakTransaction::operation-done.
 */
typedef enum {
  FLATPAK_TRANSACTION_RESULT_NO_CHANGE = 1 << 0,
} FlatpakTransactionResult;

/**
 * FlatpakTransactionRemoteReason
 * @FLATPAK_TRANSACTION_REMOTE_GENERIC_REPO: The remote specified in the flatpakref has other apps too
 * @FLATPAK_TRANSACTION_REMOTE_RUNTIME_DEPS: The remote has runtimes needed for the app
 *
 * The reason for #FlatpakTransaction::add-new-remote.
 */
typedef enum {
  FLATPAK_TRANSACTION_REMOTE_GENERIC_REPO,
  FLATPAK_TRANSACTION_REMOTE_RUNTIME_DEPS,
} FlatpakTransactionRemoteReason;

FLATPAK_EXTERN
G_DECLARE_FINAL_TYPE (FlatpakTransactionProgress, flatpak_transaction_progress, FLATPAK, TRANSACTION_PROGRESS, GObject)

FLATPAK_EXTERN
G_DECLARE_FINAL_TYPE (FlatpakTransactionOperation, flatpak_transaction_operation, FLATPAK, TRANSACTION_OPERATION, GObject)

FLATPAK_EXTERN
G_DECLARE_DERIVABLE_TYPE (FlatpakTransaction, flatpak_transaction, FLATPAK, TRANSACTION, GObject)

struct _FlatpakTransactionClass
{
  GObjectClass parent_class;

  void (*new_operation)        (FlatpakTransaction          *transaction,
                                FlatpakTransactionOperation *operation,
                                FlatpakTransactionProgress  *progress);
  void (*operation_done)       (FlatpakTransaction          *transaction,
                                FlatpakTransactionOperation *operation,
                                const char                  *commit,
                                FlatpakTransactionResult     details);
  gboolean (*operation_error)  (FlatpakTransaction            *transaction,
                                FlatpakTransactionOperation   *operation,
                                const GError                  *error,
                                FlatpakTransactionErrorDetails detail);
  int (*choose_remote_for_ref) (FlatpakTransaction *transaction,
                                const char         *for_ref,
                                const char         *runtime_ref,
                                const char * const *remotes);
  void (*end_of_lifed)         (FlatpakTransaction *transaction,
                                const char         *ref,
                                const char         *reason,
                                const char         *rebase);
  gboolean (*ready)            (FlatpakTransaction *transaction);

  gboolean (*add_new_remote) (FlatpakTransaction            *transaction,
                              FlatpakTransactionRemoteReason reason,
                              const char                    *from_id,
                              const char                    *remote_name,
                              const char                    *url);

  gboolean (*run)            (FlatpakTransaction *transaction,
                              GCancellable       *cancellable,
                              GError            **error);
  gboolean (*end_of_lifed_with_rebase) (FlatpakTransaction *transaction,
                                        const char         *remote,
                                        const char         *ref,
                                        const char         *reason,
                                        const char         *rebased_to_ref,
                                        const char        **previous_ids);

  gboolean (*webflow_start) (FlatpakTransaction *transaction,
                             const char         *remote,
                             const char         *url,
                             GVariant           *options,
                             guint               id);
  void (*webflow_done) (FlatpakTransaction *transaction,
                        GVariant           *options,
                        guint               id);

  gboolean (*basic_auth_start) (FlatpakTransaction *transaction,
                                const char         *remote,
                                const char         *realm,
                                GVariant           *options,
                                guint               id);
  void (*install_authenticator)   (FlatpakTransaction *transaction,
                                   const char         *remote,
                                   const char         *authenticator_ref);

  gboolean (*ready_pre_auth) (FlatpakTransaction *transaction);

  gpointer padding[3];
};

FLATPAK_EXTERN
FlatpakTransaction *flatpak_transaction_new_for_installation (FlatpakInstallation *installation,
                                                              GCancellable        *cancellable,
                                                              GError             **error);

FLATPAK_EXTERN
void        flatpak_transaction_progress_set_update_frequency (FlatpakTransactionProgress *self,
                                                               guint                       update_interval);
FLATPAK_EXTERN
char *      flatpak_transaction_progress_get_status (FlatpakTransactionProgress *self);
FLATPAK_EXTERN
gboolean    flatpak_transaction_progress_get_is_estimating (FlatpakTransactionProgress *self);
FLATPAK_EXTERN
int         flatpak_transaction_progress_get_progress (FlatpakTransactionProgress *self);
FLATPAK_EXTERN
guint64     flatpak_transaction_progress_get_bytes_transferred (FlatpakTransactionProgress *self);
FLATPAK_EXTERN
guint64     flatpak_transaction_progress_get_start_time (FlatpakTransactionProgress *self);


FLATPAK_EXTERN
FlatpakTransactionOperationType flatpak_transaction_operation_get_operation_type (FlatpakTransactionOperation *self);
FLATPAK_EXTERN
const char *                    flatpak_transaction_operation_get_ref (FlatpakTransactionOperation *self);
FLATPAK_EXTERN
GPtrArray *                     flatpak_transaction_operation_get_related_to_ops (FlatpakTransactionOperation *self);
FLATPAK_EXTERN
gboolean                        flatpak_transaction_operation_get_is_skipped (FlatpakTransactionOperation *self);
FLATPAK_EXTERN
const char *                    flatpak_transaction_operation_get_remote (FlatpakTransactionOperation *self);
FLATPAK_EXTERN
GFile *                         flatpak_transaction_operation_get_bundle_path (FlatpakTransactionOperation *self);
FLATPAK_EXTERN
const char *                    flatpak_transaction_operation_get_commit (FlatpakTransactionOperation *self);
FLATPAK_EXTERN
guint64                         flatpak_transaction_operation_get_download_size (FlatpakTransactionOperation *self);
FLATPAK_EXTERN
guint64                         flatpak_transaction_operation_get_installed_size (FlatpakTransactionOperation *self);
FLATPAK_EXTERN
GKeyFile *                      flatpak_transaction_operation_get_metadata (FlatpakTransactionOperation *self);
FLATPAK_EXTERN
GKeyFile *                      flatpak_transaction_operation_get_old_metadata (FlatpakTransactionOperation *self);
FLATPAK_EXTERN
const char * const *            flatpak_transaction_operation_get_subpaths (FlatpakTransactionOperation *self);
FLATPAK_EXTERN
gboolean                        flatpak_transaction_operation_get_requires_authentication (FlatpakTransactionOperation *self);
FLATPAK_EXTERN
const char *                    flatpak_transaction_operation_type_to_string (FlatpakTransactionOperationType kind);

FLATPAK_EXTERN
void                flatpak_transaction_set_no_pull (FlatpakTransaction *self,
                                                     gboolean            no_pull);
FLATPAK_EXTERN
gboolean            flatpak_transaction_get_no_pull (FlatpakTransaction *self);
FLATPAK_EXTERN
void                flatpak_transaction_set_no_deploy (FlatpakTransaction *self,
                                                       gboolean            no_deploy);
FLATPAK_EXTERN
gboolean            flatpak_transaction_get_no_deploy (FlatpakTransaction *self);
FLATPAK_EXTERN
void                flatpak_transaction_set_disable_static_deltas (FlatpakTransaction *self,
                                                                   gboolean            disable_static_deltas);
FLATPAK_EXTERN
void                flatpak_transaction_set_disable_prune (FlatpakTransaction *self,
                                                           gboolean            disable_prune);
FLATPAK_EXTERN
void                flatpak_transaction_set_disable_dependencies (FlatpakTransaction *self,
                                                                  gboolean            disable_dependencies);
FLATPAK_EXTERN
void                flatpak_transaction_set_disable_related (FlatpakTransaction *self,
                                                             gboolean            disable_related);
FLATPAK_EXTERN
void                flatpak_transaction_set_disable_auto_pin  (FlatpakTransaction *self,
                                                               gboolean            disable_pin);
FLATPAK_EXTERN
void                flatpak_transaction_set_reinstall (FlatpakTransaction *self,
                                                       gboolean            reinstall);
FLATPAK_EXTERN
gboolean            flatpak_transaction_get_no_interaction (FlatpakTransaction *self);
FLATPAK_EXTERN
void                flatpak_transaction_set_no_interaction (FlatpakTransaction *self,
                                                            gboolean            no_interaction);
FLATPAK_EXTERN
void                flatpak_transaction_set_force_uninstall (FlatpakTransaction *self,
                                                             gboolean            force_uninstall);
FLATPAK_EXTERN
void                flatpak_transaction_set_default_arch (FlatpakTransaction *self,
                                                          const char         *arch);
FLATPAK_EXTERN
void                flatpak_transaction_set_parent_window (FlatpakTransaction *self,
                                                           const char *parent_window);
FLATPAK_EXTERN
const char *        flatpak_transaction_get_parent_window (FlatpakTransaction *self);
FLATPAK_EXTERN
void                flatpak_transaction_set_include_unused_uninstall_ops (FlatpakTransaction *self,
                                                                          gboolean            include_unused_uninstall_ops);
FLATPAK_EXTERN
gboolean            flatpak_transaction_get_include_unused_uninstall_ops (FlatpakTransaction *self);
FLATPAK_EXTERN
void                flatpak_transaction_set_auto_install_sdk (FlatpakTransaction *self,
                                                              gboolean            auto_install_sdk);
FLATPAK_EXTERN
gboolean            flatpak_transaction_get_auto_install_sdk (FlatpakTransaction *self);
FLATPAK_EXTERN
void                flatpak_transaction_set_auto_install_debug (FlatpakTransaction *self,
                                                                gboolean            auto_install_debug);
FLATPAK_EXTERN
gboolean            flatpak_transaction_get_auto_install_debug (FlatpakTransaction *self);
FLATPAK_EXTERN
void                flatpak_transaction_add_dependency_source (FlatpakTransaction  *self,
                                                               FlatpakInstallation *installation);
FLATPAK_EXTERN
void                flatpak_transaction_add_sideload_repo (FlatpakTransaction  *self,
                                                           const char          *path);
FLATPAK_EXTERN
gboolean            flatpak_transaction_add_sideload_image_collection (FlatpakTransaction  *self,
                                                                       const char          *location,
                                                                       GCancellable        *cancellable,
                                                                       GError             **error);
FLATPAK_EXTERN
void                flatpak_transaction_add_default_dependency_sources (FlatpakTransaction *self);
FLATPAK_EXTERN
gboolean            flatpak_transaction_run (FlatpakTransaction *transaction,
                                             GCancellable       *cancellable,
                                             GError            **error);
FLATPAK_EXTERN
FlatpakTransactionOperation *flatpak_transaction_get_current_operation (FlatpakTransaction *self);
FLATPAK_EXTERN
FlatpakTransactionOperation *flatpak_transaction_get_operation_for_ref (FlatpakTransaction  *self,
                                                                        const char          *remote,
                                                                        const char          *ref,
                                                                        GError             **error);
FLATPAK_EXTERN
FlatpakInstallation *flatpak_transaction_get_installation (FlatpakTransaction *self);
FLATPAK_EXTERN
GList *flatpak_transaction_get_operations (FlatpakTransaction *self);

FLATPAK_EXTERN
void               flatpak_transaction_abort_webflow (FlatpakTransaction *self,
                                                      guint               id);
FLATPAK_EXTERN
void               flatpak_transaction_complete_basic_auth (FlatpakTransaction *self,
                                                            guint id,
                                                            const char *user,
                                                            const char *password,
                                                            GVariant *options);

FLATPAK_EXTERN
gboolean            flatpak_transaction_add_install (FlatpakTransaction *self,
                                                     const char         *remote,
                                                     const char         *ref,
                                                     const char        **subpaths,
                                                     GError            **error);
FLATPAK_EXTERN
gboolean            flatpak_transaction_add_rebase (FlatpakTransaction *self,
                                                    const char         *remote,
                                                    const char         *ref,
                                                    const char        **subpaths,
                                                    const char        **previous_ids,
                                                    GError            **error);
FLATPAK_EXTERN
gboolean            flatpak_transaction_add_rebase_and_uninstall (FlatpakTransaction  *self,
                                                                  const char          *remote,
                                                                  const char          *new_ref,
                                                                  const char          *old_ref,
                                                                  const char         **subpaths,
                                                                  const char         **previous_ids,
                                                                  GError             **error);
FLATPAK_EXTERN
gboolean            flatpak_transaction_add_install_bundle (FlatpakTransaction *self,
                                                            GFile              *file,
                                                            GBytes             *gpg_data,
                                                            GError            **error);
FLATPAK_EXTERN
gboolean            flatpak_transaction_add_install_image (FlatpakTransaction *self,
                                                           const char         *image_location,
                                                           GError            **error);
FLATPAK_EXTERN
gboolean            flatpak_transaction_add_install_flatpakref (FlatpakTransaction *self,
                                                                GBytes             *flatpakref_data,
                                                                GError            **error);
FLATPAK_EXTERN
gboolean            flatpak_transaction_add_sync_preinstalled (FlatpakTransaction *self,
                                                               GError            **error);
FLATPAK_EXTERN
gboolean            flatpak_transaction_add_update (FlatpakTransaction *self,
                                                    const char         *ref,
                                                    const char        **subpaths,
                                                    const char         *commit,
                                                    GError            **error);
FLATPAK_EXTERN
gboolean            flatpak_transaction_add_uninstall (FlatpakTransaction *self,
                                                       const char         *ref,
                                                       GError            **error);
FLATPAK_EXTERN
gboolean            flatpak_transaction_is_empty (FlatpakTransaction *self);

G_END_DECLS

#endif /* __FLATPAK_TRANSACTION_H__ */

===== ./common/flatpak-run-x11.c =====
/* vi:set et sw=2 sts=2 cin cino=t0,f0,(0,{s,>2s,n-s,^-s,e-s:
 * Copyright © 2014-2019 Red Hat, Inc
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Alexander Larsson <alexl@redhat.com>
 */

#include "config.h"
#include "flatpak-run-x11-private.h"

#include <sys/utsname.h>

#ifdef ENABLE_XAUTH
#include <X11/Xauth.h>
#endif

/* This is part of the X11 protocol, so we can safely hard-code it here */
#define FamilyInternet6 (6)

#ifdef ENABLE_XAUTH
static gboolean
auth_streq (const char *str,
            const char *au_str,
            size_t      au_len)
{
  return au_len == strlen (str) && memcmp (str, au_str, au_len) == 0;
}

static gboolean
xauth_entry_should_propagate (const Xauth *xa,
                              int          family,
                              const char  *remote_hostname,
                              const char  *local_hostname,
                              const char  *number)
{
  /* ensure entry isn't for a different type of access */
  if (family != FamilyWild && xa->family != family && xa->family != FamilyWild)
    return FALSE;

  /* ensure entry isn't for remote access, except that if remote_hostname
   * is specified, then remote access to that hostname is OK */
  if (xa->family != FamilyWild && xa->family != FamilyLocal &&
      (remote_hostname == NULL ||
       !auth_streq (remote_hostname, xa->address, xa->address_length)))
    return FALSE;

  /* ensure entry is for this machine */
  if (xa->family == FamilyLocal && !auth_streq (local_hostname, xa->address, xa->address_length))
    {
      /* OpenSUSE inherits the hostname value from DHCP without updating
       * its X11 authentication cookie. The old hostname value can still
       * be found in the environment variable XAUTHLOCALHOSTNAME.
       * For reference:
       * https://bugzilla.opensuse.org/show_bug.cgi?id=262309
       * For this reason if we have a cookie whose address is equal to the
       * variable XAUTHLOCALHOSTNAME, we still need to propagate it, but
       * we also need to change its address to `unames.nodename`.
       */
      const char *xauth_local_hostname;
      xauth_local_hostname = g_getenv ("XAUTHLOCALHOSTNAME");
      if (xauth_local_hostname == NULL)
        return FALSE;

      if (!auth_streq ((char *) xauth_local_hostname, xa->address, xa->address_length))
        return FALSE;
    }

  /* ensure entry is for this session */
  if (xa->number != NULL && !auth_streq (number, xa->number, xa->number_length))
    return FALSE;

  return TRUE;
}

static void
write_xauth (int family,
             const char *remote_host,
             const char *number,
             FILE       *output)
{
  Xauth *xa, local_xa;
  char *filename;
  FILE *f;
  struct utsname unames;

  if (uname (&unames))
    {
      g_warning ("uname failed");
      return;
    }

  filename = XauFileName ();
  f = fopen (filename, "rb");
  if (f == NULL)
    return;

  while (TRUE)
    {
      xa = XauReadAuth (f);
      if (xa == NULL)
        break;
      if (xauth_entry_should_propagate (xa, family, remote_host,
                                        unames.nodename, number))
        {
          local_xa = *xa;

          if (local_xa.family == FamilyLocal &&
              !auth_streq (unames.nodename, local_xa.address, local_xa.address_length))
            {
              /* If we decided to propagate this cookie, but its address
               * doesn't match `unames.nodename`, we need to change it or
               * inside the container it will not work.
               */
              local_xa.address = unames.nodename;
              local_xa.address_length = strlen (local_xa.address);
            }

          if (!XauWriteAuth (output, &local_xa))
            g_warning ("xauth write error");
        }

      XauDisposeAuth (xa);
    }

  fclose (f);
}
#else /* !ENABLE_XAUTH */

/* When not doing Xauth, any distinct values will do, but use the same
 * ones Xauth does so that we can refer to them in our unit test. */
#define FamilyLocal (256)
#define FamilyWild (65535)

#endif /* !ENABLE_XAUTH */

/*
 * @family: (out) (not optional):
 * @x11_socket: (out) (not optional):
 * @display_nr_out: (out) (not optional):
 */
gboolean
flatpak_run_parse_x11_display (const char  *display,
                               int         *family,
                               char       **x11_socket,
                               char       **remote_host,
                               char       **display_nr_out,
                               GError     **error)
{
  const char *colon;
  const char *display_nr;
  const char *display_nr_end;

  /* Use the last ':', not the first, to cope with [::1]:0 */
  colon = strrchr (display, ':');

  if (colon == NULL)
    return glnx_throw (error, "No colon found in DISPLAY=%s", display);

  if (!g_ascii_isdigit (colon[1]))
    return glnx_throw (error, "Colon not followed by a digit in DISPLAY=%s", display);

  display_nr = &colon[1];
  display_nr_end = display_nr;

  while (g_ascii_isdigit (*display_nr_end))
    display_nr_end++;

  *display_nr_out = g_strndup (display_nr, display_nr_end - display_nr);

  if (display == colon || g_str_has_prefix (display, "unix:"))
    {
      *family = FamilyLocal;
      *x11_socket = g_strdup_printf ("/tmp/.X11-unix/X%s", *display_nr_out);
    }
  else if (display[0] == '[' && display[colon - display - 1] == ']')
    {
      *family = FamilyInternet6;
      *remote_host = g_strndup (display + 1, colon - display - 2);
    }
  else
    {
      *family = FamilyWild;
      *remote_host = g_strndup (display, colon - display);
    }

  return TRUE;
}

void
flatpak_run_add_x11_args (FlatpakBwrap         *bwrap,
                          gboolean              allowed,
                          FlatpakContextShares  shares)
{
  g_autofree char *x11_socket = NULL;
  const char *display;
  g_autoptr(GError) local_error = NULL;

  /* Always cover /tmp/.X11-unix, that way we never see the host one in case
   * we have access to the host /tmp. If you request X access we'll put the right
   * thing in this anyway.
   *
   * We need to be a bit careful here, because there are two situations in
   * which potentially hostile processes have access to /tmp and could
   * create symlinks, which in principle could cause us to create the
   * directory and mount the tmpfs at the target of the symlink instead
   * of in the intended place:
   *
   * - With --filesystem=/tmp, it's the host /tmp - but because of the
   *   special historical status of /tmp/.X11-unix, we can assume that
   *   it is pre-created by the host system before user code gets to run.
   *
   * - When /tmp is shared between all instances of the same app ID,
   *   in principle the app has control over what's in /tmp, but in
   *   practice it can't interfere with /tmp/.X11-unix, because we do
   *   this unconditionally - therefore by the time app code runs,
   *   /tmp/.X11-unix is already a mount point, meaning the app cannot
   *   rename or delete it.
   */
  flatpak_bwrap_add_args (bwrap,
                          "--tmpfs", "/tmp/.X11-unix",
                          NULL);

  if (!allowed)
    {
      flatpak_bwrap_unset_env (bwrap, "DISPLAY");
      return;
    }

  g_info ("Allowing x11 access");

  display = g_getenv ("DISPLAY");

  if (display != NULL)
    {
      g_autofree char *remote_host = NULL;
      g_autofree char *display_nr = NULL;
      int family = -1;

      if (!flatpak_run_parse_x11_display (display, &family, &x11_socket,
                                          &remote_host, &display_nr,
                                          &local_error))
        {
          g_warning ("%s", local_error->message);
          flatpak_bwrap_unset_env (bwrap, "DISPLAY");
          return;
        }

      g_assert (display_nr != NULL);

      if (x11_socket != NULL
          && g_file_test (x11_socket, G_FILE_TEST_EXISTS))
        {
          g_assert (g_str_has_prefix (x11_socket, "/tmp/.X11-unix/X"));
          flatpak_bwrap_add_args (bwrap,
                                  "--ro-bind", x11_socket, x11_socket,
                                  NULL);
          flatpak_bwrap_set_env (bwrap, "DISPLAY", display, TRUE);
        }
      else if ((shares & FLATPAK_CONTEXT_SHARED_NETWORK) == 0)
        {
          /* If DISPLAY is for example :42 but /tmp/.X11-unix/X42
           * doesn't exist, then the only way this is going to work
           * is if the app can connect to abstract socket
           * @/tmp/.X11-unix/X42 or to TCP port localhost:6042,
           * either of which requires a shared network namespace.
           *
           * Alternatively, if DISPLAY is othermachine:23, then we
           * definitely need access to TCP port othermachine:6023. */
          if (x11_socket != NULL)
            g_warning ("X11 socket %s does not exist in filesystem.",
                       x11_socket);
          else
            g_warning ("Remote X11 display detected.");

          g_warning ("X11 access will require --share=network permission.");
        }
      else if (x11_socket != NULL)
        {
          g_warning ("X11 socket %s does not exist in filesystem, "
                     "trying to use abstract socket instead.",
                     x11_socket);
        }
      else
        {
          g_debug ("Assuming --share=network gives access to remote X11");
        }

#ifdef ENABLE_XAUTH
      g_auto(GLnxTmpfile) xauth_tmpf  = { 0, };

      if (glnx_open_anonymous_tmpfile_full (O_RDWR | O_CLOEXEC, "/tmp", &xauth_tmpf, NULL))
        {
          FILE *output = fdopen (xauth_tmpf.fd, "wb");
          if (output != NULL)
            {
              /* fd is now owned by output, steal it from the tmpfile */
              int tmp_fd = dup (g_steal_fd (&xauth_tmpf.fd));
              if (tmp_fd != -1)
                {
                  static const char dest[] = "/run/flatpak/Xauthority";

                  write_xauth (family, remote_host, display_nr, output);
                  flatpak_bwrap_add_args_data_fd (bwrap, "--ro-bind-data", tmp_fd, dest);

                  flatpak_bwrap_set_env (bwrap, "XAUTHORITY", dest, TRUE);
                }

              fclose (output);

              if (tmp_fd != -1)
                lseek (tmp_fd, 0, SEEK_SET);
            }
        }
#endif
    }
  else
    {
      flatpak_bwrap_unset_env (bwrap, "DISPLAY");
    }
}

===== ./common/flatpak-utils-base.c =====
/* vi:set et sw=2 sts=2 cin cino=t0,f0,(0,{s,>2s,n-s,^-s,e-s:
 * Copyright © 2019 Red Hat, Inc
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Alexander Larsson <alexl@redhat.com>
 */

#include "config.h"

#include "flatpak-utils-base-private.h"

#include <stdlib.h>
#include <string.h>

#include <gio/gio.h>
#include "libglnx.h"

const char *
flatpak_get_tzdir (void)
{
  const gchar *tzdir;

  tzdir = getenv ("TZDIR");
  if (tzdir)
    return tzdir;

  return "/usr/share/zoneinfo";
}

char *
flatpak_get_timezone (void)
{
  g_autofree gchar *symlink = NULL;
  gchar *etc_timezone = NULL;

  symlink = flatpak_resolve_link ("/etc/localtime", NULL);
  if (symlink != NULL)
    {
      /* Resolve relative path */
      g_autofree gchar *canonical = flatpak_canonicalize_filename (symlink);
      char *canonical_suffix;
      const gchar *tzdir = flatpak_get_tzdir ();

      /* Strip the prefix and slashes if possible. */
      if (g_str_has_prefix (canonical, tzdir))
        {
          canonical_suffix = canonical + strlen (tzdir);
          while (*canonical_suffix == '/')
            canonical_suffix++;

          return g_strdup (canonical_suffix);
        }
    }

  if (g_file_get_contents ("/etc/timezone", &etc_timezone,
                           NULL, NULL))
    {
      g_strchomp (etc_timezone);
      return etc_timezone;
    }

  /* Final fall-back is UTC */
  return g_strdup ("UTC");
}

char *
flatpak_readlink (const char *path,
                  GError    **error)
{
  return glnx_readlinkat_malloc (-1, path, NULL, error);
}

char *
flatpak_resolve_link (const char *path,
                      GError    **error)
{
  g_autofree char *link = flatpak_readlink (path, error);
  g_autofree char *dirname = NULL;

  if (link == NULL)
    return NULL;

  if (g_path_is_absolute (link))
    return g_steal_pointer (&link);

  dirname = g_path_get_dirname (path);
  return g_build_filename (dirname, link, NULL);
}

char *
flatpak_realpath (const char  *path,
                  GError     **error)
{
  struct stat stbuf;

  if (!glnx_fstatat (AT_FDCWD, path, &stbuf, AT_SYMLINK_NOFOLLOW, error))
    return NULL;

  if (S_ISLNK (stbuf.st_mode))
    {
      g_autofree char *resolved = NULL;

      resolved = flatpak_resolve_link (path, error);
      if (!resolved)
        return NULL;

      return flatpak_canonicalize_filename (resolved);
    }

  return flatpak_canonicalize_filename (path);
}

/*
 * Syntactically canonicalize a filename, similar to
 * g_canonicalize_filename() in newer GLib.
 *
 * This function does not do I/O.
 */
char *
flatpak_canonicalize_filename (const char *path)
{
  g_autoptr(GFile) file = g_file_new_for_path (path);
  return g_file_get_path (file);
}

===== ./common/flatpak.c =====
#include "config.h"

#include "flatpak-version-macros.h"

===== ./common/flatpak-utils-http.c =====
/* vi:set et sw=2 sts=2 cin cino=t0,f0,(0,{s,>2s,n-s,^-s,e-s:
 * Copyright © 2018 Red Hat, Inc
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Alexander Larsson <alexl@redhat.com>
 */

#include "config.h"

#include <gio/gio.h>
#include <glib-unix.h>
#include "flatpak-utils-http-private.h"
#include "flatpak-uri-private.h"
#include "flatpak-oci-registry-private.h"

#include <gio/gunixoutputstream.h>
#include "libglnx.h"

#include <sys/types.h>
#include <sys/xattr.h>
#include <curl/curl.h>

/* These macros came from 7.43.0, but we want to check
 * for versions a bit earlier than that (to work on CentOS 7),
 * so define them here if we're using an older version.
 */
#ifndef CURL_VERSION_BITS
#define CURL_VERSION_BITS(x,y,z) ((x)<<16|(y)<<8|z)
#endif
#ifndef CURL_AT_LEAST_VERSION
#define CURL_AT_LEAST_VERSION(x,y,z) (LIBCURL_VERSION_NUM >= CURL_VERSION_BITS(x, y, z))
#endif

#define FLATPAK_HTTP_TIMEOUT_SECS 60

/* copied from libostree */
#define DEFAULT_N_NETWORK_RETRIES 5

G_DEFINE_QUARK (flatpak_http_error, flatpak_http_error)

/* Holds information about CA and client certificates found in
 * system-wide and per-user certificate directories as documented
 * in container-certs.d(5).
 */
struct FlatpakCertificates
{
  char *ca_cert_file;
  char *client_cert_file;
  char *client_key_file;
};

/* Information about the cache status of a file.
   Encoded in an xattr on the cached file, or a file on the side if xattrs don't work.
*/
typedef struct
{
  char  *uri;
  char  *etag;
  gint64 last_modified;
  gint64 expires;
} CacheHttpData;

typedef struct
{
  GMainContext          *context;
  gboolean               done;
  GError                *error;

  /* Input args */

  FlatpakHTTPFlags       flags;
  const char            *auth;
  const char            *token;
  FlatpakCertificates   *certificates;
  FlatpakLoadUriProgress progress;
  GCancellable          *cancellable;
  gpointer               user_data;
  CacheHttpData         *cache_data;

  /* Output from the request, set even on http server errors */

  guint64               downloaded_bytes;
  int                   status;
  char                  *hdr_content_type;
  char                  *hdr_www_authenticate;
  char                  *hdr_etag;
  char                  *hdr_last_modified;
  char                  *hdr_cache_control;
  char                  *hdr_expires;
  char                  *hdr_content_encoding;

  /* Data destination */

  GOutputStream         *out; /*or */
  GString               *content; /* or */
  GLnxTmpfile           *out_tmpfile;
  int                    out_tmpfile_parent_dfd;

  /* Used during operation */

  char                   buffer[16 * 1024];
  guint64                last_progress_time;
  gboolean               store_compressed;

} LoadUriData;

static void
clear_load_uri_data_headers (LoadUriData *data)
{
  g_clear_pointer (&data->hdr_content_type, g_free);
  g_clear_pointer (&data->hdr_www_authenticate, g_free);
  g_clear_pointer (&data->hdr_etag, g_free);
  g_clear_pointer (&data->hdr_last_modified, g_free);
  g_clear_pointer (&data->hdr_cache_control, g_free);
  g_clear_pointer (&data->hdr_expires, g_free);
  g_clear_pointer (&data->hdr_content_encoding, g_free);
}

/* Reset between requests retries */
static void
reset_load_uri_data (LoadUriData *data)
{
  g_clear_error (&data->error);
  data->status = 0;
  data->downloaded_bytes = 0;
  if (data->content)
    g_string_set_size (data->content, 0);

  clear_load_uri_data_headers (data);

  if (data->out_tmpfile)
    {
      glnx_tmpfile_clear (data->out_tmpfile);
      g_clear_pointer (&data->out, g_object_unref);
    }

  /* Reset the progress */
  if (data->progress)
    data->progress (0, data->user_data);
}

/* Free allocated data at end of full repeated download */
static void
clear_load_uri_data (LoadUriData *data)
{
  if (data->content)
    {
      g_string_free (data->content, TRUE);
      data->content = NULL;
    }

  g_clear_error (&data->error);

  clear_load_uri_data_headers (data);
}

G_DEFINE_AUTO_CLEANUP_CLEAR_FUNC(LoadUriData, clear_load_uri_data)

static gboolean
check_http_status (guint status_code,
                   GError **error)
{
  GQuark domain;
  int code;

  if (status_code >= 200 && status_code < 300)
    return TRUE;

  switch (status_code)
    {
    case 304: /* Not Modified */
      domain = FLATPAK_HTTP_ERROR;
      code = FLATPAK_HTTP_ERROR_NOT_CHANGED;
      break;

    case 401: /* Unauthorized */
      domain = FLATPAK_HTTP_ERROR;
      code = FLATPAK_HTTP_ERROR_UNAUTHORIZED;
      break;

    case 403: /* Forbidden */
    case 404: /* Not found */
    case 410: /* Gone */
      domain = G_IO_ERROR;
      code = G_IO_ERROR_NOT_FOUND;
      break;

    case 408: /* Request Timeout */
      domain = G_IO_ERROR;
      code = G_IO_ERROR_TIMED_OUT;
      break;

    case 500: /* Internal Server Error */
      /* The server did return something, but it was useless to us, so that’s basically equivalent to not returning */
      domain = G_IO_ERROR;
      code = G_IO_ERROR_HOST_UNREACHABLE;
      break;

    default:
      domain = G_IO_ERROR;
      code = G_IO_ERROR_FAILED;
    }

  g_set_error (error, domain, code,
               "Server returned status %u",
               status_code);
  return FALSE;
}

FlatpakCertificates*
flatpak_get_certificates_for_uri (const char  *uri,
                                  GError     **error)
{
  g_autoptr(FlatpakCertificates) certificates = NULL;
  g_autoptr(GUri) parsed_uri = NULL;
  g_autofree char *hostport = NULL;
  const char *system_certs_d = NULL;
  g_autofree char *certs_path_str = NULL;
  g_auto(GStrv) certs_path = NULL;

  certificates = g_new0 (FlatpakCertificates, 1);

  parsed_uri = g_uri_parse (uri, G_URI_FLAGS_PARSE_RELAXED, error);
  if (!parsed_uri)
    return NULL;

  if (!g_uri_get_host (parsed_uri))
    return NULL;

  if (g_uri_get_port (parsed_uri) != -1)
    hostport = g_strdup_printf ("%s:%d", g_uri_get_host (parsed_uri), g_uri_get_port (parsed_uri));
  else
    hostport = g_strdup (g_uri_get_host (parsed_uri));

  system_certs_d = g_getenv ("FLATPAK_SYSTEM_CERTS_D");
  if (system_certs_d == NULL || system_certs_d[0] == '\0')
    system_certs_d = "/etc/containers/certs.d:/etc/docker/certs.d";

  /* containers/image hardcodes ~/.config and doesn't honor XDG_CONFIG_HOME */
  certs_path_str = g_strconcat (g_get_user_config_dir(), "/containers/certs.d:",
                                system_certs_d, NULL);
  certs_path = g_strsplit (certs_path_str, ":", -1);

  for (int i = 0; certs_path[i]; i++)
    {
      g_autoptr(GFile) certs_dir = g_file_new_for_path (certs_path[i]);
      g_autoptr(GFile) host_dir = g_file_get_child (certs_dir, hostport);
      g_autoptr(GFileEnumerator) enumerator = NULL;
      g_autoptr(GError) local_error = NULL;

      enumerator = g_file_enumerate_children (host_dir, G_FILE_ATTRIBUTE_STANDARD_NAME,
                                              G_FILE_QUERY_INFO_NONE,
                                              NULL, &local_error);
      if (enumerator == NULL)
        {
          /* This matches libpod - missing certificate directory or a permission
           * error causes the directory to be skipped; any other error is fatal
           */
          if (g_error_matches(local_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND) ||
              g_error_matches(local_error, G_IO_ERROR, G_IO_ERROR_PERMISSION_DENIED))
            {
              g_clear_error (&local_error);
              continue;
            }
          else
            {
              g_propagate_error (error, g_steal_pointer (&local_error));
              return NULL;
            }
        }

      while (TRUE)
        {
          GFile *child;
          g_autofree char *basename = NULL;

          if (!g_file_enumerator_iterate (enumerator, NULL, &child, NULL, error))
            return NULL;

          if (child == NULL)
            break;

          basename = g_file_get_basename (child);

          /* In libpod, all CA certificates are added to the CA certificate
           * database. We just use the first in readdir order.
           */
          if (g_str_has_suffix (basename, ".crt") && certificates->ca_cert_file == NULL)
            certificates->ca_cert_file = g_file_get_path (child);

          if (g_str_has_suffix (basename, ".cert"))
            {
              g_autofree char *nosuffix = g_strndup (basename, strlen (basename) - 5);
              g_autofree char *key_basename = g_strconcat (nosuffix, ".key", NULL);
              g_autoptr(GFile) key_file = g_file_get_child (host_dir, key_basename);

              if (!g_file_query_exists (key_file, NULL))
                {
                  g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
                               "missing key %s for client cert %s. "
                               "Note that CA certificates should use the extension .crt",
                               g_file_peek_path (key_file),
                               g_file_peek_path (child));
                  return NULL;
                }

              /* In libpod, all client certificates are added, and then the go TLS
               * code selects the best based on TLS negotiation. We just pick the first
               * in readdir order
               * */
              if (certificates->client_cert_file == NULL)
                {
                  certificates->client_cert_file = g_file_get_path (child);
                  certificates->client_key_file = g_file_get_path (key_file);
                }
            }

          if (g_str_has_suffix (basename, ".key"))
            {
              g_autofree char *nosuffix = g_strndup (basename, strlen (basename) - 4);
              g_autofree char *cert_basename = g_strconcat (nosuffix, ".cert", NULL);
              g_autoptr(GFile) cert_file = g_file_get_child (host_dir, cert_basename);

              if (!g_file_query_exists (cert_file, NULL))
                {
                  g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
                               "missing client certificate %s for key %s",
                               g_file_peek_path (cert_file),
                               g_file_peek_path (child));
                  return NULL;
                }
            }
        }
    }

  return g_steal_pointer (&certificates);
}

FlatpakCertificates *
flatpak_certificates_copy (FlatpakCertificates *other)
{
  FlatpakCertificates *certificates = g_new0 (FlatpakCertificates, 1);

  certificates->ca_cert_file = g_strdup (other->ca_cert_file);
  certificates->client_cert_file = g_strdup (other->client_cert_file);
  certificates->client_key_file = g_strdup (other->client_key_file);

  return certificates;
}

void
flatpak_certificates_free (FlatpakCertificates *certificates)
{
  g_clear_pointer (&certificates->ca_cert_file, g_free);
  g_clear_pointer (&certificates->client_cert_file, g_free);
  g_clear_pointer (&certificates->client_key_file, g_free);

  g_free (certificates);
}

/************************************************************************
 *                        Curl implementation                           *
 ************************************************************************/

typedef struct curl_slist auto_curl_slist;

G_DEFINE_AUTOPTR_CLEANUP_FUNC (auto_curl_slist, curl_slist_free_all)

struct FlatpakHttpSession {
  CURL *curl;
  GMutex lock;
};

static void
check_header(char **value_out,
             const char *header,
             char *buffer,
             size_t realsize)
{
  size_t hlen = strlen (header);

  if (realsize < hlen + 1)
    return;

  if (g_ascii_strncasecmp (buffer, header, hlen) != 0 ||
      buffer[hlen] != ':')
    return;

  buffer += hlen + 1;
  realsize -= hlen + 1;

  while (realsize > 0 && g_ascii_isspace (*buffer))
    {
      buffer++;
      realsize--;
    }

  while (realsize > 0 && g_ascii_isspace (buffer[realsize-1]))
    realsize--;

  g_free (*value_out); /* Use the last header */
  *value_out = g_strndup (buffer, realsize);
}

static size_t
_header_cb (char *buffer,
            size_t size,
            size_t nitems,
            void *userdata)
{
  size_t realsize = size * nitems;
  LoadUriData *data = (LoadUriData *)userdata;

  check_header(&data->hdr_content_type, "content-type", buffer, realsize);
  check_header(&data->hdr_www_authenticate, "WWW-Authenticate", buffer, realsize);

  check_header(&data->hdr_etag, "ETag", buffer, realsize);
  check_header(&data->hdr_last_modified, "Last-Modified", buffer, realsize);
  check_header(&data->hdr_cache_control, "Cache-Control", buffer, realsize);
  check_header(&data->hdr_expires, "Expires", buffer, realsize);
  check_header(&data->hdr_content_encoding, "Content-Encoding", buffer, realsize);

  return realsize;
}

static size_t
_write_cb (void *content_data,
           size_t size,
           size_t nmemb,
           void *userp)
{
  size_t realsize = size * nmemb;
  LoadUriData *data = (LoadUriData *)userp;
  gsize n_written = 0;

  /* If first write to tmpfile, initiate if needed */
  if (data->content == NULL && data->out == NULL &&
      data->out_tmpfile != NULL)
    {
      g_autoptr(GOutputStream) out = NULL;
      g_autoptr(GError) tmp_error = NULL;

      if (!glnx_open_tmpfile_linkable_at (data->out_tmpfile_parent_dfd, ".",
                                          O_WRONLY, data->out_tmpfile,
                                          &tmp_error))
        {
          g_warning ("Failed to open http tmpfile: %s\n", tmp_error->message);
          return 0; /* This short read will make curl report an error */
        }

      out = g_unix_output_stream_new (data->out_tmpfile->fd, FALSE);
      if (data->store_compressed &&
          g_strcmp0 (data->hdr_content_encoding, "gzip") != 0)
        {
          g_autoptr(GZlibCompressor) compressor = g_zlib_compressor_new (G_ZLIB_COMPRESSOR_FORMAT_GZIP, -1);
          data->out = g_converter_output_stream_new (out, G_CONVERTER (compressor));
        }
      else
        {
          data->out = g_steal_pointer (&out);
        }
    }

  /* Check for cancellation */
  if (g_cancellable_is_cancelled (data->cancellable))
    return 0; /* Returning 0 (short read) makes curl abort the transfer */

  if (data->content)
    {
      g_string_append_len (data->content, content_data, realsize);
      n_written = realsize;
    }
  else if (data->out)
    {
      /* We ignore the error here, but reporting a short read will make curl report the error */
      g_output_stream_write_all (data->out, content_data, realsize,
                                 &n_written, NULL, NULL);
    }

  data->downloaded_bytes += realsize;

  if (g_get_monotonic_time () - data->last_progress_time > 1 * G_USEC_PER_SEC)
    {
      if (data->progress)
        data->progress (data->downloaded_bytes, data->user_data);
      data->last_progress_time = g_get_monotonic_time ();
    }

  return realsize;
}

FlatpakHttpSession *
flatpak_create_http_session (const char *user_agent)
{
  FlatpakHttpSession *session = g_new0 (FlatpakHttpSession, 1);
  CURLcode rc;
  CURL *curl;

  session->curl = curl = curl_easy_init();
  g_assert (session->curl != NULL);

  g_mutex_init (&session->lock);

  curl_easy_setopt (curl, CURLOPT_USERAGENT, user_agent);
#if CURL_AT_LEAST_VERSION(7, 85, 0)
  rc = curl_easy_setopt (curl, CURLOPT_PROTOCOLS_STR, "http,https");
#else
  rc = curl_easy_setopt (curl, CURLOPT_PROTOCOLS, (long)(CURLPROTO_HTTP | CURLPROTO_HTTPS));
#endif
  g_assert (rc == CURLE_OK);

  curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);

  /* Note: curl automatically respects the http_proxy env var */

  if (g_getenv ("OSTREE_DEBUG_HTTP"))
    curl_easy_setopt (curl, CURLOPT_VERBOSE, 1L);

  /* Picked the current version in F25 as of 20170127, since
   * there are numerous HTTP/2 fixes since the original version in
   * libcurl 7.43.0.
   */
#if CURL_AT_LEAST_VERSION(7, 51, 0)
  if ((curl_version_info (CURLVERSION_NOW))->features & CURL_VERSION_HTTP2) {
    rc = curl_easy_setopt (curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_2_0);
    g_assert (rc == CURLE_OK);
  }
#endif
  /* https://github.com/curl/curl/blob/curl-7_53_0/docs/examples/http2-download.c */
#if (CURLPIPE_MULTIPLEX > 0)
  /* wait for pipe connection to confirm */
  rc = curl_easy_setopt (curl, CURLOPT_PIPEWAIT, 1L);
  g_assert (rc == CURLE_OK);
#endif

  curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, _write_cb);
  curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, _header_cb);

  /* Abort the connection if connecting to the server takes too long. This
   * timeout has no effect after a connection is established. */
  curl_easy_setopt (curl, CURLOPT_CONNECTTIMEOUT, (long)FLATPAK_HTTP_TIMEOUT_SECS);

  /* Abort the download if it’s slower than 10KB/sec for 60 seconds. An example
   * compressed summary file is 1.5MB in size, so anything slower than this rate
   * will mean it takes over 2.5 minutes to download just the summary file. */
  curl_easy_setopt(curl, CURLOPT_LOW_SPEED_TIME, (long)FLATPAK_HTTP_TIMEOUT_SECS);
  curl_easy_setopt(curl, CURLOPT_LOW_SPEED_LIMIT, 10000L);

  return session;
}

void
flatpak_http_session_free (FlatpakHttpSession* session)
{
  g_mutex_lock (&session->lock);
  curl_easy_cleanup (session->curl);
  g_mutex_unlock (&session->lock);
  g_mutex_clear (&session->lock);
  g_free (session);
}

static void
set_error_from_curl (GError        **error,
                     const char     *uri,
                     CURLcode        res,
                     GCancellable   *cancellable)
{
  GQuark domain = G_IO_ERROR;
  int code;

  switch (res)
    {
    case CURLE_WRITE_ERROR:
      /* Check if this was due to cancellation */
      if (g_cancellable_is_cancelled (cancellable))
        code = G_IO_ERROR_CANCELLED;
      else
        code = G_IO_ERROR_FAILED;
      break;
    case CURLE_COULDNT_CONNECT:
    case CURLE_COULDNT_RESOLVE_HOST:
    case CURLE_COULDNT_RESOLVE_PROXY:
      code = G_IO_ERROR_HOST_NOT_FOUND;
      break;
    case CURLE_OPERATION_TIMEDOUT:
      code = G_IO_ERROR_TIMED_OUT;
      break;
    default:
      code =  G_IO_ERROR_FAILED;
    }

  g_set_error (error, domain, code,
               "While fetching %s: [%u] %s", uri, res,
               curl_easy_strerror (res));
}

static gboolean
flatpak_download_http_uri_once (FlatpakHttpSession    *session,
                                LoadUriData           *data,
                                const char            *uri,
                                GError               **error)
{
  CURLcode res;
  g_autofree char *auth_header = NULL;
  g_autofree char *cache_header = NULL;
  g_autoptr(auto_curl_slist) header_list = NULL;
  g_autoptr(GMutexLocker) curl_lock = g_mutex_locker_new (&session->lock);
  long response;
  CURL *curl = session->curl;

  g_info ("Loading %s using curl", uri);

  curl_easy_setopt (curl, CURLOPT_URL, uri);
  curl_easy_setopt (curl, CURLOPT_WRITEDATA, (void *)data);
  curl_easy_setopt (curl, CURLOPT_HEADERDATA, (void *)data);

  if (data->certificates)
    {
      if (data->certificates->ca_cert_file)
        curl_easy_setopt (curl, CURLOPT_CAINFO, data->certificates->ca_cert_file);

      if (data->certificates->client_cert_file)
        {
          curl_easy_setopt (curl, CURLOPT_SSLCERT, data->certificates->client_cert_file);
          curl_easy_setopt (curl, CURLOPT_SSLKEY, data->certificates->client_key_file);
        }
    }

  if (data->flags & FLATPAK_HTTP_FLAGS_HEAD)
    curl_easy_setopt (curl, CURLOPT_NOBODY, 1L);
  else
    curl_easy_setopt (curl, CURLOPT_HTTPGET, 1L);

  if (data->flags & FLATPAK_HTTP_FLAGS_ACCEPT_OCI)
    header_list = curl_slist_append (header_list,
                                     "Accept: " FLATPAK_OCI_MEDIA_TYPE_IMAGE_MANIFEST ", " FLATPAK_DOCKER_MEDIA_TYPE_IMAGE_MANIFEST2 ", " FLATPAK_OCI_MEDIA_TYPE_IMAGE_INDEX);

  if (data->auth)
    auth_header = g_strdup_printf ("Authorization: Basic %s", data->auth);
  else if (data->token)
    auth_header = g_strdup_printf ("Authorization: Bearer %s", data->token);
  if (auth_header)
    header_list = curl_slist_append (header_list, auth_header);

  if (data->cache_data)
    {
      CacheHttpData *cache_data = data->cache_data;

      if (cache_data->etag && cache_data->etag[0])
        cache_header = g_strdup_printf ("If-None-Match: %s", cache_data->etag);
      else if (cache_data->last_modified != 0)
        {
          g_autoptr(GDateTime) date = g_date_time_new_from_unix_utc (cache_data->last_modified);
          g_autofree char *date_str = flatpak_format_http_date (date);
          cache_header = g_strdup_printf ("If-Modified-Since: %s", date_str);
        }
      if (cache_header)
        header_list = curl_slist_append (header_list, cache_header);
    }

  curl_easy_setopt (curl, CURLOPT_HTTPHEADER, header_list);

  if (data->flags & FLATPAK_HTTP_FLAGS_STORE_COMPRESSED)
    {
      curl_easy_setopt(curl, CURLOPT_ACCEPT_ENCODING, "gzip");
      curl_easy_setopt(curl, CURLOPT_HTTP_CONTENT_DECODING, 0L);
      data->store_compressed = TRUE;
    }
  else
    {
      /* enable all supported built-in compressions */
      curl_easy_setopt(curl, CURLOPT_ACCEPT_ENCODING, "");
      curl_easy_setopt(curl, CURLOPT_HTTP_CONTENT_DECODING, 1L);
      data->store_compressed = FALSE;
    }

  res = curl_easy_perform (session->curl);

  curl_easy_setopt (session->curl, CURLOPT_HTTPHEADER, NULL); /* Don't point to freed list */

  if (res != CURLE_OK)
    {
      set_error_from_curl (error, uri, res, data->cancellable);

      /* Make sure we clear the tmpfile stream we possible created during the request */
      if (data->out_tmpfile && data->out)
        g_clear_pointer (&data->out, g_object_unref);

      return FALSE;
    }

  if (data->out_tmpfile && data->out)
    {
      /* Flush the writes */
      if (!g_output_stream_close (data->out, data->cancellable, error))
        return FALSE;

      g_clear_pointer (&data->out, g_object_unref);
    }

  if (data->progress)
    data->progress (data->downloaded_bytes, data->user_data);

  curl_easy_getinfo (session->curl, CURLINFO_RESPONSE_CODE, &response);

  data->status = response;

  if ((data->flags & FLATPAK_HTTP_FLAGS_NOCHECK_STATUS) == 0 &&
      !check_http_status (data->status, error))
    return FALSE;

  g_info ("Received %" G_GUINT64_FORMAT " bytes", data->downloaded_bytes);

  /* This is not really needed, but the auto-pointer confuses some compilers in the CI */
  g_clear_pointer (&curl_lock, g_mutex_locker_free);

  return TRUE;
}

/* Check whether a particular operation should be retried. This is entirely
 * based on how it failed (if at all) last time, and whether the operation has
 * some retries left. The retry count is set when the operation is first
 * created, and must be decremented by the caller. (@n_retries_remaining == 0)
 * will always return %FALSE from this function.
 *
 * This code is copied from libostree's _ostree_fetcher_should_retry_request()
 */
static gboolean
flatpak_http_should_retry_request (const GError *error,
                                   guint         n_retries_remaining)
{
  if (error == NULL || n_retries_remaining == 0)
    return FALSE;

  /* Return TRUE for transient errors. */
  if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_TIMED_OUT) ||
      g_error_matches (error, G_IO_ERROR, G_IO_ERROR_HOST_NOT_FOUND) ||
      g_error_matches (error, G_IO_ERROR, G_IO_ERROR_HOST_UNREACHABLE) ||
      g_error_matches (error, G_IO_ERROR, G_IO_ERROR_PARTIAL_INPUT) ||
      g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CONNECTION_CLOSED) ||
      g_error_matches (error, G_RESOLVER_ERROR, G_RESOLVER_ERROR_NOT_FOUND) ||
      g_error_matches (error, G_RESOLVER_ERROR, G_RESOLVER_ERROR_TEMPORARY_FAILURE))
    {
      g_info ("Should retry request (remaining: %u retries), due to transient error: %s",
              n_retries_remaining, error->message);
      return TRUE;
    }

  return FALSE;
}

GBytes *
flatpak_load_uri_full (FlatpakHttpSession    *http_session,
                       const char            *uri,
                       FlatpakCertificates   *certificates,
                       FlatpakHTTPFlags       flags,
                       const char            *auth,
                       const char            *token,
                       FlatpakLoadUriProgress progress,
                       gpointer               user_data,
                       int                   *out_status,
                       char                 **out_content_type,
                       char                 **out_www_authenticate,
                       GCancellable          *cancellable,
                       GError               **error)
{
  g_auto(LoadUriData) data = { NULL };
  g_autoptr(GError) local_error = NULL;
  guint n_retries_remaining = DEFAULT_N_NETWORK_RETRIES;
  g_autoptr(GMainContextPopDefault) main_context = NULL;
  gboolean success = FALSE;

  /* Ensure we handle file: uris the same independent of backend */
  if (g_ascii_strncasecmp (uri, "file:", 5) == 0)
    {
      g_autoptr(GFile) file = g_file_new_for_uri (uri);
      gchar *contents;
      gsize len;

      if (!g_file_load_contents (file, cancellable, &contents, &len, NULL, error))
        return NULL;

      return g_bytes_new_take (g_steal_pointer (&contents), len);
    }

  main_context = flatpak_main_context_new_default ();

  data.context = main_context;
  data.progress = progress;
  data.user_data = user_data;
  data.last_progress_time = g_get_monotonic_time ();
  data.cancellable = cancellable;
  data.flags = flags;
  data.certificates = certificates;
  data.auth = auth;
  data.token = token;

  data.content = g_string_new ("");

  do
    {
      if (n_retries_remaining < DEFAULT_N_NETWORK_RETRIES)
        {
          g_clear_error (&local_error);
          reset_load_uri_data (&data);
        }

      success = flatpak_download_http_uri_once (http_session, &data, uri, &local_error);

      if (success)
        break;

      g_assert (local_error != NULL);
    }
  while (flatpak_http_should_retry_request (local_error, n_retries_remaining--));

  if (success)
    {
      if (out_content_type)
        *out_content_type = g_steal_pointer (&data.hdr_content_type);

      if (out_www_authenticate)
        *out_www_authenticate = g_steal_pointer (&data.hdr_www_authenticate);

      if (out_status)
        *out_status = data.status;

      return g_string_free_to_bytes (g_steal_pointer (&data.content));
    }

  g_assert (local_error != NULL);
  g_propagate_error (error, g_steal_pointer (&local_error));
  return NULL;
}


GBytes *
flatpak_load_uri (FlatpakHttpSession    *http_session,
                  const char            *uri,
                  FlatpakHTTPFlags       flags,
                  const char            *token,
                  FlatpakLoadUriProgress progress,
                  gpointer               user_data,
                  char                 **out_content_type,
                  GCancellable          *cancellable,
                  GError               **error)
{
  return flatpak_load_uri_full (http_session, uri, NULL, flags, NULL, token,
                                progress, user_data, NULL, out_content_type, NULL,
                                cancellable, error);
}

gboolean
flatpak_download_http_uri (FlatpakHttpSession    *http_session,
                           const char            *uri,
                           FlatpakCertificates   *certificates,
                           FlatpakHTTPFlags       flags,
                           GOutputStream         *out,
                           const char            *token,
                           FlatpakLoadUriProgress progress,
                           gpointer               user_data,
                           GCancellable          *cancellable,
                           GError               **error)
{
  g_auto(LoadUriData) data = { NULL };
  g_autoptr(GError) local_error = NULL;
  guint n_retries_remaining = DEFAULT_N_NETWORK_RETRIES;
  g_autoptr(GMainContextPopDefault) main_context = NULL;
  gboolean success = FALSE;

  main_context = flatpak_main_context_new_default ();

  data.context = main_context;
  data.progress = progress;
  data.user_data = user_data;
  data.last_progress_time = g_get_monotonic_time ();
  data.cancellable = cancellable;
  data.certificates = certificates;
  data.flags = flags;
  data.token = token;

  data.out = out;

  do
    {
      if (n_retries_remaining < DEFAULT_N_NETWORK_RETRIES)
        {
          g_clear_error (&local_error);
          reset_load_uri_data (&data);
        }

      success =  flatpak_download_http_uri_once (http_session, &data, uri, &local_error);

      if (success)
        break;

      g_assert (local_error != NULL);

      /* If the output stream has already been written to we can't retry.
       * TODO: use a range request to resume the download */
      if (data.downloaded_bytes > 0)
        break;
    }
  while (flatpak_http_should_retry_request (local_error, n_retries_remaining--));

  if (success)
    return TRUE;

  g_assert (local_error != NULL);
  g_propagate_error (error, g_steal_pointer (&local_error));
  return FALSE;
}

/************************************************************************
 *                        Cached http support                           *
 ***********************************************************************/

#define CACHE_HTTP_XATTR "user.flatpak.http"
#define CACHE_HTTP_SUFFIX ".flatpak.http"
#define CACHE_HTTP_TYPE "(sstt)"

static void
clear_cache_http_data (CacheHttpData *data,
                       gboolean       clear_uri)
{
  if (clear_uri)
    g_clear_pointer (&data->uri, g_free);
  g_clear_pointer (&data->etag, g_free);
  data->last_modified = 0;
  data->expires = 0;
}

static void
free_cache_http_data (CacheHttpData *data)
{
  clear_cache_http_data (data, TRUE);
  g_free (data);
}

G_DEFINE_AUTOPTR_CLEANUP_FUNC (CacheHttpData, free_cache_http_data)

static GBytes *
serialize_cache_http_data (CacheHttpData * data)
{
  g_autoptr(GVariant) cache_variant = NULL;

  cache_variant = g_variant_ref_sink (g_variant_new (CACHE_HTTP_TYPE,
                                                     data->uri,
                                                     data->etag ? data->etag : "",
                                                     data->last_modified,
                                                     data->expires));
  if (G_BYTE_ORDER != G_BIG_ENDIAN)
    {
      g_autoptr(GVariant) tmp_variant = cache_variant;
      cache_variant = g_variant_byteswap (tmp_variant);
    }

  return g_variant_get_data_as_bytes (cache_variant);
}

static void
deserialize_cache_http_data (CacheHttpData *data,
                             GBytes        *bytes)
{
  g_autoptr(GVariant) cache_variant = NULL;

  cache_variant = g_variant_ref_sink (g_variant_new_from_bytes (G_VARIANT_TYPE (CACHE_HTTP_TYPE),
                                                                bytes,
                                                                FALSE));
  if (G_BYTE_ORDER != G_BIG_ENDIAN)
    {
      g_autoptr(GVariant) tmp_variant = cache_variant;
      cache_variant = g_variant_byteswap (tmp_variant);
    }

  g_variant_get (cache_variant,
                 CACHE_HTTP_TYPE,
                 &data->uri,
                 &data->etag,
                 &data->last_modified,
                 &data->expires);
}

static CacheHttpData *
load_cache_http_data (int           dfd,
                      char         *name,
                      gboolean     *no_xattr,
                      GCancellable *cancellable,
                      GError      **error)
{
  g_autoptr(CacheHttpData) data = NULL;
  g_autoptr(GBytes) cache_bytes = glnx_lgetxattrat (dfd, name,
                                                    CACHE_HTTP_XATTR,
                                                    error);
  if (cache_bytes == NULL)
    {
      if (errno == ENOTSUP)
        {
          g_autofree char *cache_file = NULL;
          glnx_autofd int fd = -1;

          g_clear_error (error);
          *no_xattr = TRUE;

          cache_file = g_strconcat (name, CACHE_HTTP_SUFFIX, NULL);

          if (!glnx_openat_rdonly (dfd, cache_file, FALSE,
                                   &fd, error))
            return FALSE;

          cache_bytes = glnx_fd_readall_bytes (fd, cancellable, error);
          if (!cache_bytes)
            return NULL;
        }
      else if (errno == ENOENT || errno == ENODATA)
        {
          g_clear_error (error);
          return g_new0 (CacheHttpData, 1);
        }
      else
        {
          return NULL;
        }
    }


  data = g_new0 (CacheHttpData, 1);
  deserialize_cache_http_data (data, cache_bytes);
  return g_steal_pointer (&data);
}

static gboolean
save_cache_http_data_xattr (int      fd,
                            GBytes  *bytes,
                            GError **error)
{
  if (TEMP_FAILURE_RETRY (fsetxattr (fd, (char *) CACHE_HTTP_XATTR,
                                     g_bytes_get_data (bytes, NULL),
                                     g_bytes_get_size (bytes),
                                     0)) < 0)
    return glnx_throw_errno_prefix (error, "fsetxattr");

  return TRUE;
}

static gboolean
save_cache_http_data_fallback (int      fd,
                               GBytes  *bytes,
                               GError **error)
{
  if (glnx_loop_write (fd,
                       g_bytes_get_data (bytes, NULL),
                       g_bytes_get_size (bytes)) < 0)
    return glnx_throw_errno_prefix (error, "write");

  return TRUE;
}

static gboolean
save_cache_http_data_to_file (int           dfd,
                              char         *name,
                              GBytes       *bytes,
                              gboolean      no_xattr,
                              GCancellable *cancellable,
                              GError      **error)
{
  glnx_autofd int fd = -1;
  g_autofree char *fallback_name = NULL;

  if (!no_xattr)
    {
      if (!glnx_openat_rdonly (dfd, name, FALSE,
                               &fd, error))
        return FALSE;

      if (save_cache_http_data_xattr (fd, bytes, error))
        return TRUE;

      if (errno == ENOTSUP)
        g_clear_error (error);
      else
        return FALSE;
    }

  fallback_name = g_strconcat (name, CACHE_HTTP_SUFFIX, NULL);
  if (!glnx_file_replace_contents_at (dfd, fallback_name,
                                      g_bytes_get_data (bytes, NULL),
                                      g_bytes_get_size (bytes),
                                      0,
                                      cancellable,
                                      error))
    return FALSE;

  return TRUE;
}

static gboolean
sync_and_rename_tmpfile (GLnxTmpfile *tmpfile,
                         const char  *dest_name,
                         GError     **error)
{
  /* Filesystem paranoia: If we end up with the new metadata but not
   * the new data, then because the cache headers are in the metadata,
   * we'll never re-download.  (If we just want to avoid losing both
   * the old and new data, skipping fdatasync when the destination is
   * missing works, but it won't here.)
   *
   * This will cause a bunch of fdatasyncs when downloading the icons for
   * a large appstream the first time, would mostly be a problem with a
   * very fast internet connection and a slow spinning drive.
   * Possible solution: update in new directory without fdatasync
   * (copying in any existing cached icons to revalidate), syncfs(), then
   * atomic symlink.
   */
  if (fdatasync (tmpfile->fd) != 0)
    return glnx_throw_errno_prefix (error, "fdatasync");

  if (fchmod (tmpfile->fd, 0644) != 0)
    return glnx_throw_errno_prefix (error, "fchmod");

  if (!glnx_link_tmpfile_at (tmpfile,
                             GLNX_LINK_TMPFILE_REPLACE,
                             tmpfile->src_dfd, dest_name, error))
    return FALSE;

  return TRUE;
}

static void
set_cache_http_data_from_headers (CacheHttpData *cache_data,
                                  LoadUriData *data)
{
  const char *etag = data->hdr_etag;
  const char *last_modified = data->hdr_last_modified;
  const char *cache_control = data->hdr_cache_control;
  const char *expires = data->hdr_expires;
  gboolean expires_computed = FALSE;

  /* The original HTTP 1/1 specification only required sending the ETag header in a 304
   * response, and implied that a cache might need to save the old Cache-Control
   * values. The updated RFC 7232 from 2014 requires sending Cache-Control, ETags, and
   * Expire if they would have been sent in the original 200 response, and recommends
   * sending Last-Modified for requests without an etag. Since sending these headers was
   * apparently normal previously, for simplicity we assume the RFC 7232 behavior and start
   * from scratch for a 304 response.
   */
  clear_cache_http_data (cache_data, FALSE);

  if (etag && *etag)
    {
      cache_data->etag = g_strdup (etag);
    }
  else if (last_modified && *last_modified)
    {
      g_autoptr(GDateTime) date = flatpak_parse_http_time (last_modified);
      if (date)
        cache_data->last_modified = g_date_time_to_unix (date);
    }

  if (cache_control && *cache_control)
    {
      g_autoptr(GHashTable) params = flatpak_parse_http_header_param_list (cache_control);
      GHashTableIter iter;
      gpointer key, value;

      g_hash_table_iter_init (&iter, params);
      while (g_hash_table_iter_next (&iter, &key, &value))
        {
          if (g_strcmp0 (key, "max-age") == 0)
            {
              char *end;

              char *max_age = value;
              gint64 max_age_sec = g_ascii_strtoll (max_age,  &end, 10);
              if (*max_age != '\0' && *end == '\0')
                {
                  cache_data->expires = (g_get_real_time () / G_USEC_PER_SEC) + max_age_sec;
                  expires_computed = TRUE;
                }
            }
          else if (g_strcmp0 (key, "no-cache") == 0)
            {
              cache_data->expires = 0;
              expires_computed = TRUE;
            }
        }
    }

  if (!expires_computed && expires && *expires)
    {
      g_autoptr(GDateTime) date = flatpak_parse_http_time (expires);
      if (date)
        {
          cache_data->expires = g_date_time_to_unix (date);
          expires_computed = TRUE;
        }
    }

  if (!expires_computed)
    {
      /* If nothing implies an expires time, use 30 minutes. Browsers use
       * 0.1 * (Date - Last-Modified), but it's clearly appropriate here, and
       * better if server's send a value.
       */
      cache_data->expires = (g_get_real_time () / G_USEC_PER_SEC) + 1800;
    }
}

gboolean
flatpak_cache_http_uri (FlatpakHttpSession    *http_session,
                        const char            *uri,
                        FlatpakCertificates   *certificates,
                        FlatpakHTTPFlags       flags,
                        int                    dest_dfd,
                        const char            *dest_subpath,
                        FlatpakLoadUriProgress progress,
                        gpointer               user_data,
                        GCancellable          *cancellable,
                        GError               **error)
{
  g_auto(LoadUriData) data = { NULL };
  g_autoptr(GError) local_error = NULL;
  guint n_retries_remaining = DEFAULT_N_NETWORK_RETRIES;
  g_autoptr(CacheHttpData) cache_data = NULL;
  g_autoptr(GMainContextPopDefault) main_context = NULL;
  g_autofree char *parent_path = g_path_get_dirname (dest_subpath);
  g_autofree char *name = g_path_get_basename (dest_subpath);
  g_auto(GLnxTmpfile) out_tmpfile = { 0 };
  g_auto(GLnxTmpfile) cache_tmpfile = { 0 };
  g_autoptr(GBytes) cache_bytes = NULL;
  gboolean no_xattr = FALSE;
  glnx_autofd int cache_dfd = -1;
  gboolean success;

  if (!glnx_opendirat (dest_dfd, parent_path, TRUE, &cache_dfd, error))
    return FALSE;

  cache_data = load_cache_http_data (cache_dfd, name, &no_xattr,
                                     cancellable, error);
  if (!cache_data)
    return FALSE;

  if (g_strcmp0 (cache_data->uri, uri) != 0)
    clear_cache_http_data (cache_data, TRUE);

  if (cache_data->uri)
    {
      if (cache_data->expires > (g_get_real_time () / G_USEC_PER_SEC))
        {
          g_set_error (error, FLATPAK_HTTP_ERROR,
                       FLATPAK_HTTP_ERROR_NOT_CHANGED,
                       "Reusing cached value");
          return FALSE;
        }
    }

  if (cache_data->uri == NULL)
    cache_data->uri = g_strdup (uri);

  /* Missing from cache, or expired so must revalidate via etag/last-modified headers */

  main_context = flatpak_main_context_new_default ();

  data.context = main_context;
  data.progress = progress;
  data.user_data = user_data;
  data.last_progress_time = g_get_monotonic_time ();
  data.cancellable = cancellable;
  data.flags = flags;
  data.certificates = certificates;

  data.cache_data = cache_data;

  data.out_tmpfile = &out_tmpfile;
  data.out_tmpfile_parent_dfd = cache_dfd;

  do
    {
      if (n_retries_remaining < DEFAULT_N_NETWORK_RETRIES)
        {
          g_clear_error (&local_error);
          reset_load_uri_data (&data);
        }

      success = flatpak_download_http_uri_once (http_session, &data, uri, &local_error);

      if (success)
        break;

      g_assert (local_error != NULL);
    }
  while (flatpak_http_should_retry_request (local_error, n_retries_remaining--));

  /* Update the cache data on success or cache-valid */
  if (success || g_error_matches (local_error, FLATPAK_HTTP_ERROR, FLATPAK_HTTP_ERROR_NOT_CHANGED))
    {
      set_cache_http_data_from_headers (cache_data, &data);
      cache_bytes = serialize_cache_http_data (cache_data);
    }

  if (local_error)
    {
      if (cache_bytes)
        {
          GError *tmp_error = NULL;

          if (!save_cache_http_data_to_file (cache_dfd, name, cache_bytes, no_xattr,
                                             cancellable, &tmp_error))
            {
              g_clear_error (&local_error);
              g_propagate_error (error, tmp_error);

              return FALSE;
            }
        }

      g_propagate_error (error, g_steal_pointer (&local_error));
      return FALSE;
    }

  if (!no_xattr)
    {
      if (!save_cache_http_data_xattr (out_tmpfile.fd, cache_bytes, error))
        {
          if (errno != ENOTSUP)
            return FALSE;

          g_clear_error (error);
          no_xattr = TRUE;
        }
    }

  if (no_xattr)
    {
      if (!glnx_open_tmpfile_linkable_at (cache_dfd, ".", O_WRONLY, &cache_tmpfile, error))
        return FALSE;

      if (!save_cache_http_data_fallback (cache_tmpfile.fd, cache_bytes, error))
        return FALSE;
    }

  if (!sync_and_rename_tmpfile (&out_tmpfile, name, error))
    return FALSE;

  if (no_xattr)
    {
      g_autofree char *fallback_name = g_strconcat (name, CACHE_HTTP_SUFFIX, NULL);

      if (!sync_and_rename_tmpfile (&cache_tmpfile, fallback_name, error))
        return FALSE;
    }

  return TRUE;
}

===== ./common/flatpak-instance-private.h =====
/*
 * Copyright © 2018 Red Hat, Inc
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Matthias Clasen
 */

#ifndef __FLATPAK_INSTANCE_PRIVATE_H__
#define __FLATPAK_INSTANCE_PRIVATE_H__

#include <glib.h>

#include "flatpak-instance.h"

FlatpakInstance *flatpak_instance_new (const char *dir);
FlatpakInstance *flatpak_instance_new_for_id (const char *id);
char *flatpak_instance_get_apps_directory (void);
char *flatpak_instance_get_instances_directory (void);
char *flatpak_instance_allocate_id (char **host_dir_out,
                                    char **host_private_dir_out,
                                    int   *lock_fd_out);

gboolean flatpak_instance_claim_per_app_temp_directory (const char *app_id,
                                                        int per_app_dir_lock_fd,
                                                        int at_fd,
                                                        const char *link_path,
                                                        const char *parent,
                                                        char **path_out,
                                                        GError **error);

void flatpak_instance_iterate_all_and_gc (GPtrArray *out_instances);

gboolean flatpak_instance_ensure_per_app_dir (const char *app_id,
                                              int *lock_fd_out,
                                              char **lock_path_out,
                                              GError **error);
gboolean flatpak_instance_ensure_per_app_dev_shm (const char *app_id,
                                                  int per_app_dir_lock_fd,
                                                  char **shared_dev_shm_out,
                                                  GError **error);
gboolean flatpak_instance_ensure_per_app_tmp (const char *app_id,
                                              int per_app_dir_lock_fd,
                                              char **shared_tmp_out,
                                              GError **error);
gboolean flatpak_instance_ensure_per_app_xdg_runtime_dir (const char *app_id,
                                                          int per_app_dir_lock_fd,
                                                          char **shared_dir_out,
                                                          GError **error);

GStrv flatpak_instance_get_run_environ (FlatpakInstance *self, GError **error);


#endif /* __FLATPAK_INSTANCE_PRIVATE_H__ */

===== ./common/flatpak-remote-ref-private.h =====
/*
 * Copyright © 2015 Red Hat, Inc
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Alexander Larsson <alexl@redhat.com>
 */

#if !defined(__FLATPAK_H_INSIDE__) && !defined(FLATPAK_COMPILATION)
#error "Only <flatpak.h> can be included directly."
#endif

#ifndef __FLATPAK_REMOTE_REF_PRIVATE_H__
#define __FLATPAK_REMOTE_REF_PRIVATE_H__

#include <flatpak-remote-ref.h>
#include <flatpak-dir-private.h>

FlatpakRemoteRef *flatpak_remote_ref_new (FlatpakDecomposed *ref,
                                          const char         *commit,
                                          const char         *remote_name,
                                          const char         *collection_id,
                                          FlatpakRemoteState *remote_state);

#endif /* __FLATPAK_REMOTE_REF_PRIVATE_H__ */

===== ./common/flatpak-image-source-private.h =====
/*
 * Copyright © 2024 Red Hat, Inc
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Owen Taylor <otaylor@redhat.com>
 */

#ifndef __FLATPAK_IMAGE_SOURCE_H__
#define __FLATPAK_IMAGE_SOURCE_H__

#include <glib.h>
#include <gio/gio.h>

#include <flatpak-common-types-private.h>

#define FLATPAK_TYPE_IMAGE_SOURCE flatpak_image_source_get_type ()
G_DECLARE_FINAL_TYPE (FlatpakImageSource,
                      flatpak_image_source,
                      FLATPAK, IMAGE_SOURCE,
                      GObject)

FlatpakImageSource *flatpak_image_source_new (FlatpakOciRegistry *registry,
                                              const char         *repository,
                                              const char         *digest,
                                              GCancellable       *cancellable,
                                              GError            **error);

FlatpakImageSource *flatpak_image_source_new_local (GFile        *file,
                                                    const char   *reference,
                                                    GCancellable *cancellable,
                                                    GError      **error);
FlatpakImageSource *flatpak_image_source_new_remote (const char   *uri,
                                                     const char   *oci_repository,
                                                     const char   *digest,
                                                     const char   *token,
                                                     const char   *signature_lookaside,
                                                     GCancellable *cancellable,
                                                     GError      **error);
FlatpakImageSource *flatpak_image_source_new_for_location (const char   *location,
                                                           GCancellable *cancellable,
                                                           GError      **error);

void flatpak_image_source_set_delta_url (FlatpakImageSource *self,
                                         const char         *delta_url);

FlatpakOciRegistry *flatpak_image_source_get_registry       (FlatpakImageSource *self);
const char         *flatpak_image_source_get_oci_repository (FlatpakImageSource *self);
const char         *flatpak_image_source_get_digest         (FlatpakImageSource *self);
const char         *flatpak_image_source_get_delta_url      (FlatpakImageSource *self);
FlatpakOciManifest *flatpak_image_source_get_manifest       (FlatpakImageSource *self);
size_t              flatpak_image_source_get_manifest_size  (FlatpakImageSource *self);
FlatpakOciImage    *flatpak_image_source_get_image_config   (FlatpakImageSource *self);

const char *flatpak_image_source_get_ref              (FlatpakImageSource *self);
const char *flatpak_image_source_get_metadata         (FlatpakImageSource *self);
const char *flatpak_image_source_get_commit           (FlatpakImageSource *self);
const char *flatpak_image_source_get_parent_commit    (FlatpakImageSource *self);
guint64     flatpak_image_source_get_commit_timestamp (FlatpakImageSource *self);
const char *flatpak_image_source_get_commit_subject   (FlatpakImageSource *self);
const char *flatpak_image_source_get_commit_body      (FlatpakImageSource *self);

void flatpak_image_source_build_commit_metadata (FlatpakImageSource *self,
                                                 GVariantBuilder    *metadata_builder);

GVariant *flatpak_image_source_make_fake_commit      (FlatpakImageSource *image_source);
GVariant *flatpak_image_source_make_summary_metadata (FlatpakImageSource *self);
#endif /* __FLATPAK_IMAGE_SOURCE_H__ */

===== ./common/flatpak-remote.c =====
/* vi:set et sw=2 sts=2 cin cino=t0,f0,(0,{s,>2s,n-s,^-s,e-s:
 * Copyright © 2015 Red Hat, Inc
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Alexander Larsson <alexl@redhat.com>
 */

#include "config.h"

#include <glib/gi18n-lib.h>

#include "flatpak-utils-private.h"
#include "flatpak-remote-private.h"
#include "flatpak-remote-ref-private.h"
#include "flatpak-repo-utils-private.h"
#include "flatpak-enum-types.h"

#include <string.h>
#include <ostree.h>

#include <ostree-repo-finder-avahi.h>

/**
 * SECTION:flatpak-remote
 * @Short_description: Remote repository
 * @Title: FlatpakRemote
 *
 * A #FlatpakRemote object provides information about a remote
 * repository (or short: remote) that has been configured.
 *
 * At its most basic level, a remote has a name and the URL for
 * the repository. In addition, they provide some additional
 * information that can be useful when presenting repositories
 * in a UI, such as a title, a priority or a "don't enumerate"
 * flags.
 *
 * To obtain FlatpakRemote objects for the configured remotes
 * on a system, use flatpak_installation_list_remotes() or
 * flatpak_installation_get_remote_by_name().
 */

typedef struct _FlatpakRemotePrivate FlatpakRemotePrivate;

struct _FlatpakRemotePrivate
{
  char             *name;
  FlatpakDir       *dir;

  char             *local_url;
  char             *local_collection_id;
  char             *local_title;
  char             *local_default_branch;
  char             *local_main_ref;
  char             *local_filter;
  gboolean          local_gpg_verify;
  gboolean          local_noenumerate;
  gboolean          local_nodeps;
  gboolean          local_disabled;
  int               local_prio;
  char             *local_comment;
  char             *local_description;
  char             *local_homepage;
  char             *local_icon;
  FlatpakRemoteType type;

  guint             local_url_set            : 1;
  guint             local_collection_id_set  : 1;
  guint             local_title_set          : 1;
  guint             local_default_branch_set : 1;
  guint             local_main_ref_set       : 1;
  guint             local_filter_set         : 1;
  guint             local_gpg_verify_set     : 1;
  guint             local_noenumerate_set    : 1;
  guint             local_nodeps_set         : 1;
  guint             local_disabled_set       : 1;
  guint             local_prio_set           : 1;
  guint             local_icon_set           : 1;
  guint             local_comment_set        : 1;
  guint             local_description_set    : 1;
  guint             local_homepage_set       : 1;

  GBytes           *local_gpg_key;
};

G_DEFINE_TYPE_WITH_PRIVATE (FlatpakRemote, flatpak_remote, G_TYPE_OBJECT)

enum {
  PROP_0,

  PROP_NAME,
  PROP_TYPE,
};

static void
flatpak_remote_finalize (GObject *object)
{
  FlatpakRemote *self = FLATPAK_REMOTE (object);
  FlatpakRemotePrivate *priv = flatpak_remote_get_instance_private (self);

  g_free (priv->name);
  if (priv->dir)
    g_object_unref (priv->dir);
  if (priv->local_gpg_key)
    g_bytes_unref (priv->local_gpg_key);

  g_free (priv->local_url);
  g_free (priv->local_collection_id);
  g_free (priv->local_title);
  g_free (priv->local_default_branch);
  g_free (priv->local_main_ref);
  g_free (priv->local_filter);
  g_free (priv->local_comment);
  g_free (priv->local_description);
  g_free (priv->local_homepage);
  g_free (priv->local_icon);

  G_OBJECT_CLASS (flatpak_remote_parent_class)->finalize (object);
}

static void
flatpak_remote_set_property (GObject      *object,
                             guint         prop_id,
                             const GValue *value,
                             GParamSpec   *pspec)
{
  FlatpakRemote *self = FLATPAK_REMOTE (object);
  FlatpakRemotePrivate *priv = flatpak_remote_get_instance_private (self);

  switch (prop_id)
    {
    case PROP_NAME:
      g_clear_pointer (&priv->name, g_free);
      priv->name = g_value_dup_string (value);
      break;

    case PROP_TYPE:
      priv->type = g_value_get_enum (value);
      break;

    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
    }
}

static void
flatpak_remote_get_property (GObject    *object,
                             guint       prop_id,
                             GValue     *value,
                             GParamSpec *pspec)
{
  FlatpakRemote *self = FLATPAK_REMOTE (object);
  FlatpakRemotePrivate *priv = flatpak_remote_get_instance_private (self);

  switch (prop_id)
    {
    case PROP_NAME:
      g_value_set_string (value, priv->name);
      break;

    case PROP_TYPE:
      g_value_set_enum (value, priv->type);
      break;

    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
    }
}

static void
flatpak_remote_class_init (FlatpakRemoteClass *klass)
{
  GObjectClass *object_class = G_OBJECT_CLASS (klass);

  object_class->get_property = flatpak_remote_get_property;
  object_class->set_property = flatpak_remote_set_property;
  object_class->finalize = flatpak_remote_finalize;

  /**
   * FlatpakRemote:name:
   *
   * Name of the remote, as used in configuration files and when interfacing
   * with OSTree. This is typically human readable, but could be generated, and
   * must conform to ostree_validate_remote_name(). It should typically not be
   * presented in the UI.
   */
  g_object_class_install_property (object_class,
                                   PROP_NAME,
                                   g_param_spec_string ("name",
                                                        "Name",
                                                        "The name of the remote",
                                                        NULL,
                                                        G_PARAM_READWRITE));

  /**
   * FlatpakRemote:type:
   *
   * The type of the remote: whether it comes from static configuration files
   * (@FLATPAK_REMOTE_TYPE_STATIC) or has been dynamically found from the local
   * network or a mounted USB drive (@FLATPAK_REMOTE_TYPE_LAN,
   * @FLATPAK_REMOTE_TYPE_USB). Dynamic remotes may be added and removed over
   * time.
   *
   * Since: 0.9.8
   */
  g_object_class_install_property (object_class,
                                   PROP_TYPE,
                                   g_param_spec_enum ("type",
                                                      "Type",
                                                      "The type of the remote",
                                                      FLATPAK_TYPE_REMOTE_TYPE,
                                                      FLATPAK_REMOTE_TYPE_STATIC,
                                                      G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
}

static void
flatpak_remote_init (FlatpakRemote *self)
{
}

/**
 * flatpak_remote_get_name:
 * @self: a #FlatpakRemote
 *
 * Returns the name of the remote repository.
 *
 * Returns: (transfer none): the name
 */
const char *
flatpak_remote_get_name (FlatpakRemote *self)
{
  FlatpakRemotePrivate *priv = flatpak_remote_get_instance_private (self);

  return priv->name;
}

/**
 * flatpak_remote_get_appstream_dir:
 * @self: a #FlatpakRemote
 * @arch: (nullable): which architecture to fetch (default: current architecture)
 *
 * Returns the directory where this remote will store locally cached
 * appstream information for the specified @arch.
 *
 * Returns: (transfer full): a #GFile
 **/
GFile *
flatpak_remote_get_appstream_dir (FlatpakRemote *self,
                                  const char    *arch)
{
  FlatpakRemotePrivate *priv = flatpak_remote_get_instance_private (self);
  g_autofree char *subdir = NULL;

  if (priv->dir == NULL)
    return NULL;

  if (arch == NULL)
    arch = flatpak_get_arch ();

  if (flatpak_dir_get_remote_oci (priv->dir, priv->name))
    subdir = g_strdup_printf ("appstream/%s/%s", priv->name, arch);
  else
    subdir = g_strdup_printf ("appstream/%s/%s/active", priv->name, arch);

  return g_file_resolve_relative_path (flatpak_dir_get_path (priv->dir),
                                       subdir);
}

/**
 * flatpak_remote_get_appstream_timestamp:
 * @self: a #FlatpakRemote
 * @arch: (nullable): which architecture to fetch (default: current architecture)
 *
 * Returns the timestamp file that will be updated whenever the appstream information
 * has been updated (or tried to update) for the specified @arch.
 *
 * Returns: (transfer full): a #GFile
 **/
GFile *
flatpak_remote_get_appstream_timestamp (FlatpakRemote *self,
                                        const char    *arch)
{
  FlatpakRemotePrivate *priv = flatpak_remote_get_instance_private (self);
  g_autofree char *subdir = NULL;

  if (priv->dir == NULL)
    return NULL;

  if (arch == NULL)
    arch = flatpak_get_arch ();

  subdir = g_strdup_printf ("appstream/%s/%s/.timestamp", priv->name, arch);
  return g_file_resolve_relative_path (flatpak_dir_get_path (priv->dir),
                                       subdir);
}

/**
 * flatpak_remote_get_url:
 * @self: a #FlatpakRemote
 *
 * Returns the repository URL of this remote.
 *
 * Returns: (transfer full): the URL
 */
char *
flatpak_remote_get_url (FlatpakRemote *self)
{
  FlatpakRemotePrivate *priv = flatpak_remote_get_instance_private (self);
  char *url;

  if (priv->local_url_set)
    return g_strdup (priv->local_url);

  if (priv->dir)
    {
      OstreeRepo *repo = flatpak_dir_get_repo (priv->dir);
      if (ostree_repo_remote_get_url (repo, priv->name, &url, NULL))
        return url;
    }

  return NULL;
}

/**
 * flatpak_remote_set_url:
 * @self: a #FlatpakRemote
 * @url: The new url
 *
 * Sets the repository URL of this remote.
 *
 * Note: This is a local modification of this object, you must commit changes
 * using flatpak_installation_modify_remote() for the changes to take
 * effect.
 */
void
flatpak_remote_set_url (FlatpakRemote *self,
                        const char    *url)
{
  FlatpakRemotePrivate *priv = flatpak_remote_get_instance_private (self);

  g_free (priv->local_url);
  priv->local_url = g_strdup (url);
  priv->local_url_set = TRUE;
}

/**
 * flatpak_remote_get_collection_id:
 * @self: a #FlatpakRemote
 *
 * Returns the repository collection ID of this remote, if set.
 *
 * Returns: (transfer full) (nullable): the collection ID, or %NULL if unset
 */
char *
flatpak_remote_get_collection_id (FlatpakRemote *self)
{
  FlatpakRemotePrivate *priv = flatpak_remote_get_instance_private (self);

  if (priv->local_collection_id_set)
    return g_strdup (priv->local_collection_id);

  if (priv->dir)
    return flatpak_dir_get_remote_collection_id (priv->dir, priv->name);

  return NULL;
}

/**
 * flatpak_remote_set_collection_id:
 * @self: a #FlatpakRemote
 * @collection_id: (nullable): The new collection ID, or %NULL to unset
 *
 * Sets the repository collection ID of this remote.
 *
 * Note: This is a local modification of this object, you must commit changes
 * using flatpak_installation_modify_remote() for the changes to take
 * effect.
 */
void
flatpak_remote_set_collection_id (FlatpakRemote *self,
                                  const char    *collection_id)
{
  FlatpakRemotePrivate *priv = flatpak_remote_get_instance_private (self);

  if (collection_id != NULL && *collection_id == '\0')
    collection_id = NULL;

  g_free (priv->local_collection_id);
  priv->local_collection_id = g_strdup (collection_id);
  priv->local_collection_id_set = TRUE;
}

/**
 * flatpak_remote_get_title:
 * @self: a #FlatpakRemote
 *
 * Returns the title of the remote.
 *
 * Returns: (transfer full): the title
 */
char *
flatpak_remote_get_title (FlatpakRemote *self)
{
  FlatpakRemotePrivate *priv = flatpak_remote_get_instance_private (self);

  if (priv->local_title_set)
    return g_strdup (priv->local_title);

  if (priv->dir)
    return flatpak_dir_get_remote_title (priv->dir, priv->name);

  return NULL;
}

/**
 * flatpak_remote_set_title:
 * @self: a #FlatpakRemote
 * @title: The new title, or %NULL to unset
 *
 * Sets the repository title of this remote.
 *
 * Note: This is a local modification of this object, you must commit changes
 * using flatpak_installation_modify_remote() for the changes to take
 * effect.
 */
void
flatpak_remote_set_title (FlatpakRemote *self,
                          const char    *title)
{
  FlatpakRemotePrivate *priv = flatpak_remote_get_instance_private (self);

  g_free (priv->local_title);
  priv->local_title = g_strdup (title);
  priv->local_title_set = TRUE;
}

/**
 * flatpak_remote_get_filter:
 * @self: a #FlatpakRemote
 *
 * Returns the filter file of the remote.
 *
 * Returns: (transfer full): a pathname to a filter file
 *
 * Since: 1.4
 */
char *
flatpak_remote_get_filter (FlatpakRemote *self)
{
  FlatpakRemotePrivate *priv = flatpak_remote_get_instance_private (self);

  if (priv->local_filter_set)
    return g_strdup (priv->local_filter);

  if (priv->dir)
    return flatpak_dir_get_remote_filter (priv->dir, priv->name);

  return NULL;
}

/**
 * flatpak_remote_set_filter:
 * @self: a #FlatpakRemote
 * @filter_path: The pathname of the new filter file
 *
 * Sets a filter for this remote.
 *
 * Note: This is a local modification of this object, you must commit changes
 * using flatpak_installation_modify_remote() for the changes to take
 * effect.
 *
 * Since: 1.4
 */
void
flatpak_remote_set_filter (FlatpakRemote *self,
                           const char    *filter_path)
{
  FlatpakRemotePrivate *priv = flatpak_remote_get_instance_private (self);

  g_free (priv->local_filter);
  priv->local_filter = g_strdup (filter_path);
  priv->local_filter_set = TRUE;
}

/**
 * flatpak_remote_get_comment:
 * @self: a #FlatpakRemote
 *
 * Returns the comment of the remote.
 *
 * Returns: (transfer full): the comment
 *
 * Since: 1.4
 */
char *
flatpak_remote_get_comment (FlatpakRemote *self)
{
  FlatpakRemotePrivate *priv = flatpak_remote_get_instance_private (self);

  if (priv->local_comment_set)
    return g_strdup (priv->local_comment);

  if (priv->dir)
    return flatpak_dir_get_remote_comment (priv->dir, priv->name);

  return NULL;
}

/**
 * flatpak_remote_set_comment:
 * @self: a #FlatpakRemote
 * @comment: The new comment 
 *
 * Sets the comment of this remote.
 *
 * Note: This is a local modification of this object, you must commit changes
 * using flatpak_installation_modify_remote() for the changes to take
 * effect.
 *
 * Since: 1.4
 */
void
flatpak_remote_set_comment (FlatpakRemote *self,
                            const char    *comment)
{
  FlatpakRemotePrivate *priv = flatpak_remote_get_instance_private (self);

  g_free (priv->local_comment);
  priv->local_comment = g_strdup (comment);
  priv->local_comment_set = TRUE;
}

/**
 * flatpak_remote_get_description:
 * @self: a #FlatpakRemote
 *
 * Returns the description of the remote.
 *
 * Returns: (transfer full): the description 
 *
 * Since: 1.4
 */
char *
flatpak_remote_get_description (FlatpakRemote *self)
{
  FlatpakRemotePrivate *priv = flatpak_remote_get_instance_private (self);

  if (priv->local_description_set)
    return g_strdup (priv->local_description);

  if (priv->dir)
    return flatpak_dir_get_remote_description (priv->dir, priv->name);

  return NULL;
}

/**
 * flatpak_remote_set_description:
 * @self: a #FlatpakRemote
 * @description: The new description
 *
 * Sets the description of this remote.
 *
 * Note: This is a local modification of this object, you must commit changes
 * using flatpak_installation_modify_remote() for the changes to take
 * effect.
 *
 * Since: 1.4
 */
void
flatpak_remote_set_description (FlatpakRemote *self,
                                const char    *description)
{
  FlatpakRemotePrivate *priv = flatpak_remote_get_instance_private (self);

  g_free (priv->local_description);
  priv->local_description = g_strdup (description);
  priv->local_description_set = TRUE;
}

/**
 * flatpak_remote_get_homepage:
 * @self: a #FlatpakRemote
 *
 * Returns the homepage url of the remote.
 *
 * Returns: (transfer full): the homepage url
 *
 * Since: 1.4
 */
char *
flatpak_remote_get_homepage (FlatpakRemote *self)
{
  FlatpakRemotePrivate *priv = flatpak_remote_get_instance_private (self);

  if (priv->local_homepage_set)
    return g_strdup (priv->local_homepage);

  if (priv->dir)
    return flatpak_dir_get_remote_homepage (priv->dir, priv->name);

  return NULL;
}

/**
 * flatpak_remote_set_homepage:
 * @self: a #FlatpakRemote
 * @homepage: The new homepage
 *
 * Sets the homepage of this remote.
 *
 * Note: This is a local modification of this object, you must commit changes
 * using flatpak_installation_modify_remote() for the changes to take
 * effect.
 *
 * Since: 1.4
 */
void
flatpak_remote_set_homepage (FlatpakRemote *self,
                             const char    *homepage)
{
  FlatpakRemotePrivate *priv = flatpak_remote_get_instance_private (self);

  g_free (priv->local_homepage);
  priv->local_homepage = g_strdup (homepage);
  priv->local_homepage_set = TRUE;
}

/**
 * flatpak_remote_get_icon:
 * @self: a #FlatpakRemote
 *
 * Returns the icon url of the remote.
 *
 * Returns: (transfer full): the icon url
 *
 * Since: 1.4
 */
char *
flatpak_remote_get_icon (FlatpakRemote *self)
{
  FlatpakRemotePrivate *priv = flatpak_remote_get_instance_private (self);

  if (priv->local_icon_set)
    return g_strdup (priv->local_icon);

  if (priv->dir)
    return flatpak_dir_get_remote_icon (priv->dir, priv->name);

  return NULL;
}

/**
 * flatpak_remote_set_icon:
 * @self: a #FlatpakRemote
 * @icon: The new homepage
 *
 * Sets the homepage of this remote.
 *
 * Note: This is a local modification of this object, you must commit changes
 * using flatpak_installation_modify_remote() for the changes to take
 * effect.
 *
 * Since: 1.4
 */
void
flatpak_remote_set_icon (FlatpakRemote *self,
                         const char    *icon)
{
  FlatpakRemotePrivate *priv = flatpak_remote_get_instance_private (self);

  g_free (priv->local_icon);
  priv->local_icon = g_strdup (icon);
  priv->local_icon_set = TRUE;
}

/**
 * flatpak_remote_get_default_branch:
 * @self: a #FlatpakRemote
 *
 * Returns the default branch configured for the remote.
 *
 * Returns: (transfer full): the default branch, or %NULL
 *
 * Since: 0.6.12
 */
char *
flatpak_remote_get_default_branch (FlatpakRemote *self)
{
  FlatpakRemotePrivate *priv = flatpak_remote_get_instance_private (self);

  if (priv->local_default_branch_set)
    return g_strdup (priv->local_default_branch);

  if (priv->dir)
    return flatpak_dir_get_remote_default_branch (priv->dir, priv->name);

  return NULL;
}

/**
 * flatpak_remote_set_default_branch:
 * @self: a #FlatpakRemote
 * @default_branch: The new default_branch, or %NULL to unset
 *
 * Sets the default branch configured for this remote.
 *
 * Note: This is a local modification of this object, you must commit changes
 * using flatpak_installation_modify_remote() for the changes to take
 * effect.
 *
 * Since: 0.6.12
 */
void
flatpak_remote_set_default_branch (FlatpakRemote *self,
                                   const char    *default_branch)
{
  FlatpakRemotePrivate *priv = flatpak_remote_get_instance_private (self);

  g_free (priv->local_default_branch);
  priv->local_default_branch = g_strdup (default_branch);
  priv->local_default_branch_set = TRUE;
}

/**
 * flatpak_remote_get_main_ref:
 * @self: a #FlatpakRemote
 *
 * Returns the main ref of this remote, if set. The main ref is the ref that an
 * origin remote is created for.
 *
 * Returns: (transfer full): the main ref, or %NULL
 *
 * Since: 1.1.1
 */
char *
flatpak_remote_get_main_ref (FlatpakRemote *self)
{
  FlatpakRemotePrivate *priv = flatpak_remote_get_instance_private (self);

  if (priv->local_main_ref_set)
    return g_strdup (priv->local_main_ref);

  if (priv->dir)
    return flatpak_dir_get_remote_main_ref (priv->dir, priv->name);

  return NULL;
}

/**
 * flatpak_remote_set_main_ref:
 * @self: a #FlatpakRemote
 * @main_ref: The new main ref
 *
 * Sets the main ref of this remote. The main ref is the ref that an origin
 * remote is created for.
 *
 * Note: This is a local modification of this object, you must commit changes
 * using flatpak_installation_modify_remote() for the changes to take
 * effect.
 *
 * Since: 1.1.1
 */
void
flatpak_remote_set_main_ref (FlatpakRemote *self,
                             const char    *main_ref)
{
  FlatpakRemotePrivate *priv = flatpak_remote_get_instance_private (self);

  g_free (priv->local_main_ref);
  priv->local_main_ref = g_strdup (main_ref);
  priv->local_main_ref_set = TRUE;
}

/**
 * flatpak_remote_get_noenumerate:
 * @self: a #FlatpakRemote
 *
 * Returns whether this remote should be used to list applications.
 *
 * Returns: whether the remote is marked as "don't enumerate"
 */
gboolean
flatpak_remote_get_noenumerate (FlatpakRemote *self)
{
  FlatpakRemotePrivate *priv = flatpak_remote_get_instance_private (self);

  if (priv->local_noenumerate_set)
    return priv->local_noenumerate;

  if (priv->dir)
    return flatpak_dir_get_remote_noenumerate (priv->dir, priv->name);

  return FALSE;
}

/**
 * flatpak_remote_set_noenumerate:
 * @self: a #FlatpakRemote
 * @noenumerate: a bool
 *
 * Sets the noenumeration config of this remote. See flatpak_remote_get_noenumerate().
 *
 * Note: This is a local modification of this object, you must commit changes
 * using flatpak_installation_modify_remote() for the changes to take
 * effect.
 */
void
flatpak_remote_set_noenumerate (FlatpakRemote *self,
                                gboolean       noenumerate)
{
  FlatpakRemotePrivate *priv = flatpak_remote_get_instance_private (self);

  priv->local_noenumerate = noenumerate;
  priv->local_noenumerate_set = TRUE;
}

/**
 * flatpak_remote_get_nodeps:
 * @self: a #FlatpakRemote
 *
 * Returns whether this remote should be used to find dependencies.
 *
 * Returns: whether the remote is marked as "don't use for dependencies"
 */
gboolean
flatpak_remote_get_nodeps (FlatpakRemote *self)
{
  FlatpakRemotePrivate *priv = flatpak_remote_get_instance_private (self);

  if (priv->local_nodeps_set)
    return priv->local_nodeps;

  if (priv->dir)
    return flatpak_dir_get_remote_nodeps (priv->dir, priv->name);

  return FALSE;
}

/**
 * flatpak_remote_set_nodeps:
 * @self: a #FlatpakRemote
 * @nodeps: a bool
 *
 * Sets the nodeps config of this remote. See flatpak_remote_get_nodeps().
 *
 * Note: This is a local modification of this object, you must commit changes
 * using flatpak_installation_modify_remote() for the changes to take
 * effect.
 */
void
flatpak_remote_set_nodeps (FlatpakRemote *self,
                           gboolean       nodeps)
{
  FlatpakRemotePrivate *priv = flatpak_remote_get_instance_private (self);

  priv->local_nodeps = nodeps;
  priv->local_nodeps_set = TRUE;
}

/**
 * flatpak_remote_get_disabled:
 * @self: a #FlatpakRemote
 *
 * Returns whether this remote is disabled.
 *
 * Returns: whether the remote is marked as disabled
 */
gboolean
flatpak_remote_get_disabled (FlatpakRemote *self)
{
  FlatpakRemotePrivate *priv = flatpak_remote_get_instance_private (self);

  if (priv->local_disabled_set)
    return priv->local_disabled;

  if (priv->dir)
    return flatpak_dir_get_remote_disabled (priv->dir, priv->name);

  return FALSE;
}
/**
 * flatpak_remote_set_disabled:
 * @self: a #FlatpakRemote
 * @disabled: a bool
 *
 * Sets the disabled config of this remote. See flatpak_remote_get_disabled().
 *
 * Note: This is a local modification of this object, you must commit changes
 * using flatpak_installation_modify_remote() for the changes to take
 * effect.
 */
void
flatpak_remote_set_disabled (FlatpakRemote *self,
                             gboolean       disabled)
{
  FlatpakRemotePrivate *priv = flatpak_remote_get_instance_private (self);

  priv->local_disabled = disabled;
  priv->local_disabled_set = TRUE;
}

/**
 * flatpak_remote_get_prio:
 * @self: a #FlatpakRemote
 *
 * Returns the priority for the remote.
 *
 * Returns: the priority
 */
int
flatpak_remote_get_prio (FlatpakRemote *self)
{
  FlatpakRemotePrivate *priv = flatpak_remote_get_instance_private (self);

  if (priv->local_prio_set)
    return priv->local_prio;

  if (priv->dir)
    return flatpak_dir_get_remote_prio (priv->dir, priv->name);

  return 1;
}

/**
 * flatpak_remote_set_prio:
 * @self: a #FlatpakRemote
 * @prio: a bool
 *
 * Sets the prio config of this remote. See flatpak_remote_get_prio().
 *
 * Note: This is a local modification of this object, you must commit changes
 * using flatpak_installation_modify_remote() for the changes to take
 * effect.
 */
void
flatpak_remote_set_prio (FlatpakRemote *self,
                         int            prio)
{
  FlatpakRemotePrivate *priv = flatpak_remote_get_instance_private (self);

  priv->local_prio = prio;
  priv->local_prio_set = TRUE;
}

/**
 * flatpak_remote_get_gpg_verify:
 * @self: a #FlatpakRemote
 *
 * Returns whether GPG verification is enabled for the remote.
 *
 * Returns: whether GPG verification is enabled
 */
gboolean
flatpak_remote_get_gpg_verify (FlatpakRemote *self)
{
  FlatpakRemotePrivate *priv = flatpak_remote_get_instance_private (self);
  gboolean res;

  if (priv->local_gpg_verify_set)
    return priv->local_gpg_verify;

  if (priv->dir)
    {
      OstreeRepo *repo = flatpak_dir_get_repo (priv->dir);
      if (ostree_repo_remote_get_gpg_verify (repo, priv->name, &res, NULL))
        return res;
    }

  return FALSE;
}

/**
 * flatpak_remote_set_gpg_verify:
 * @self: a #FlatpakRemote
 * @gpg_verify: a bool
 *
 * Sets the gpg_verify config of this remote. See flatpak_remote_get_gpg_verify().
 *
 * Note: This is a local modification of this object, you must commit changes
 * using flatpak_installation_modify_remote() for the changes to take
 * effect.
 */
void
flatpak_remote_set_gpg_verify (FlatpakRemote *self,
                               gboolean       gpg_verify)
{
  FlatpakRemotePrivate *priv = flatpak_remote_get_instance_private (self);

  priv->local_gpg_verify = gpg_verify;
  priv->local_gpg_verify_set = TRUE;
}

/**
 * flatpak_remote_set_gpg_key:
 * @self: a #FlatpakRemote
 * @gpg_key: a #GBytes with gpg binary key data
 *
 * Sets the trusted gpg key for this remote.
 *
 * Note: This is a local modification of this object, you must commit changes
 * using flatpak_installation_modify_remote() for the changes to take
 * effect.
 */
void
flatpak_remote_set_gpg_key (FlatpakRemote *self,
                            GBytes        *gpg_key)
{
  FlatpakRemotePrivate *priv = flatpak_remote_get_instance_private (self);

  if (priv->local_gpg_key != NULL)
    g_bytes_unref (priv->local_gpg_key);
  priv->local_gpg_key = g_bytes_ref (gpg_key);
}

FlatpakRemote *
flatpak_remote_new_with_dir (const char *name,
                             FlatpakDir *dir)
{
  FlatpakRemotePrivate *priv;
  FlatpakRemote *self = g_object_new (FLATPAK_TYPE_REMOTE,
                                      "name", name,
                                      NULL);

  priv = flatpak_remote_get_instance_private (self);
  if (dir)
    priv->dir = g_object_ref (dir);

  return self;
}

/**
 * flatpak_remote_new:
 * @name: a name
 *
 * Returns a new remote object which can be used to configure a new remote.
 *
 * Note: This is a local configuration object, you must commit changes
 * using flatpak_installation_modify_remote() or flatpak_installation_add_remote() for the changes to take
 * effect.
 *
 * Returns: (transfer full): a new #FlatpakRemote
 **/
FlatpakRemote *
flatpak_remote_new (const char *name)
{
  return flatpak_remote_new_with_dir (name, NULL);
}


#define read_str_option(_key, _field) \
  {                                                                     \
    char *val = g_key_file_get_string (config, group, _key, NULL);      \
    if (val != NULL) {                                                  \
      priv->local_ ## _field = val;                                     \
      priv->local_ ## _field ## _set = TRUE;                            \
    }                                                                   \
  }

#define read_bool_option(_key, _field)                                  \
  if (g_key_file_has_key (config, group, _key, NULL)) {                 \
    priv->local_ ## _field = g_key_file_get_boolean (config, group, _key, NULL); \
    priv->local_ ## _field ## _set = TRUE;                              \
  }

#define read_int_option(_key, _field)                                   \
  if (g_key_file_has_key (config, group, _key, NULL)) {                 \
    priv->local_ ## _field = g_key_file_get_integer (config, group, _key, NULL); \
    priv->local_ ## _field ## _set = TRUE;                              \
  }


/**
 * flatpak_remote_new_from_file:
 * @name: a name
 * @data: The content of a flatpakrepo file
 * @error: return location for a #GError
 *
 * Returns a new pre-filled remote object which can be used to configure a new remote.
 * The fields in the remote are filled in according to the values in the
 * passed in flatpakrepo file.
 *
 * Note: This is a local configuration object, you must commit changes
 * using flatpak_installation_modify_remote()  or flatpak_installation_add_remote() for the changes to take
 * effect.
 *
 * Returns: (transfer full): a new #FlatpakRemote, or %NULL on error
 *
 * Since: 1.3.4
 **/
FlatpakRemote *
flatpak_remote_new_from_file (const char *name, GBytes *data, GError **error)
{
  FlatpakRemote *remote = flatpak_remote_new (name);
  FlatpakRemotePrivate *priv = flatpak_remote_get_instance_private (remote);
  g_autofree char *group = g_strdup_printf ("remote \"%s\"", name);
  g_autoptr(GKeyFile) keyfile = g_key_file_new ();
  g_autoptr(GKeyFile) config = NULL;
  g_autoptr(GBytes) gpg_data = NULL;

  if (!g_key_file_load_from_data (keyfile, g_bytes_get_data (data, NULL), g_bytes_get_size (data), 0, error))
    return NULL;

  config = flatpak_parse_repofile (name, FALSE, keyfile, &gpg_data, NULL, error);
  if (config == NULL)
    return NULL;

  priv->local_gpg_key = g_steal_pointer (&gpg_data);

  read_str_option("url", url);
  read_str_option("collection-id", collection_id);
  read_str_option("xa.title", title);
  read_str_option("xa.filter", filter);
  /* Canonicalize empty to null-but-is-set */
  if (priv->local_filter && priv->local_filter[0] == 0)
    g_free (g_steal_pointer (&priv->local_filter));
  read_str_option("xa.comment", comment);
  read_str_option("xa.description", description);
  read_str_option("xa.homepage", homepage);
  read_str_option("xa.icon", icon);
  read_str_option("xa.default-branch", default_branch);
  read_str_option("xa.main-ref", main_ref);

  read_bool_option("xa.gpg-verify", gpg_verify);
  read_bool_option("xa.noenumerate", noenumerate);
  read_bool_option("xa.disable", disabled);
  read_bool_option("xa.nodeps", nodeps);

  read_int_option("xa.prio", prio);

  return remote;
}

/* copied from GLib */
static gboolean
g_key_file_is_group_name (const gchar *name)
{
  gchar *p, *q;

  if (name == NULL)
    return FALSE;

  p = q = (gchar *) name;
  while (*q && *q != ']' && *q != '[' && !g_ascii_iscntrl (*q))
    q = g_utf8_find_next_char (q, NULL);

  if (*q != '\0' || q == p)
    return FALSE;

  return TRUE;
}

gboolean
flatpak_remote_commit_filter (FlatpakRemote *self,
                              FlatpakDir    *dir,
                              GCancellable  *cancellable,
                              GError       **error)
{
  FlatpakRemotePrivate *priv = flatpak_remote_get_instance_private (self);
  g_autofree char *group = g_strdup_printf ("remote \"%s\"", priv->name);

  if (priv->local_filter_set &&
      !flatpak_dir_compare_remote_filter (dir, priv->name, priv->local_filter))
    {
      g_autoptr(GKeyFile) config = ostree_repo_copy_config (flatpak_dir_get_repo (dir));

      g_key_file_set_string (config, group, "xa.filter", priv->local_filter ? priv->local_filter : "");

      if (!flatpak_dir_modify_remote (dir, priv->name, config, NULL, cancellable, error))
        return FALSE;
    }

  return TRUE;
}

static void
_key_file_set_or_unset_string (GKeyFile   *config,
                               const char *group,
                               const char *key,
                               const char *value)
{
  if (value != NULL)
    g_key_file_set_string (config, group, key, value);
  else
    g_key_file_remove_key (config, group, key, NULL);
}

gboolean
flatpak_remote_commit (FlatpakRemote *self,
                       FlatpakDir    *dir,
                       GCancellable  *cancellable,
                       GError       **error)
{
  FlatpakRemotePrivate *priv = flatpak_remote_get_instance_private (self);
  OstreeRepo *repo;
  g_autofree char *url = NULL;
  g_autoptr(GKeyFile) config = NULL;
  g_autofree char *group = g_strdup_printf ("remote \"%s\"", priv->name);

  if (priv->name[0] == '\0' ||
      !g_key_file_is_group_name (group))
    return flatpak_fail_error (error, FLATPAK_ERROR_INVALID_DATA, _("Bad remote name: %s"), priv->name);

  url = flatpak_remote_get_url (self);
  if (url == NULL || *url == 0)
    return flatpak_fail_error (error, FLATPAK_ERROR_INVALID_DATA, _("No URL specified"));

  if (priv->type != FLATPAK_REMOTE_TYPE_STATIC)
    return flatpak_fail (error, "Dynamic remote cannot be committed");

  repo = flatpak_dir_get_repo (dir);
  if (repo == NULL)
    config = g_key_file_new ();
  else
    config = ostree_repo_copy_config (repo);

  if (priv->local_url_set)
    g_key_file_set_string (config, group, "url", priv->local_url);

  if (priv->local_collection_id_set)
    _key_file_set_or_unset_string (config, group, "collection-id", priv->local_collection_id);

  if (priv->local_title_set)
    _key_file_set_or_unset_string (config, group, "xa.title", priv->local_title);

  if (priv->local_filter_set)
    g_key_file_set_string (config, group, "xa.filter", priv->local_filter ? priv->local_filter : "");

  if (priv->local_comment_set)
    g_key_file_set_string (config, group, "xa.comment", priv->local_comment);

  if (priv->local_description_set)
    g_key_file_set_string (config, group, "xa.description", priv->local_description);

  if (priv->local_homepage_set)
    g_key_file_set_string (config, group, "xa.homepage", priv->local_homepage);

  if (priv->local_icon_set)
    g_key_file_set_string (config, group, "xa.icon", priv->local_icon);

  if (priv->local_default_branch_set)
    _key_file_set_or_unset_string (config, group, "xa.default-branch", priv->local_default_branch);

  if (priv->local_main_ref_set)
    g_key_file_set_string (config, group, "xa.main-ref", priv->local_main_ref);

  if (priv->local_gpg_verify_set)
    {
      if (!priv->local_gpg_verify &&
           priv->local_collection_id_set && priv->local_collection_id != NULL)
        return flatpak_fail_error (error, FLATPAK_ERROR_INVALID_DATA,
                                   _("GPG verification must be enabled when a collection ID is set"));

      g_key_file_set_boolean (config, group, "gpg-verify", priv->local_gpg_verify);

      if (!priv->local_collection_id_set || priv->local_collection_id == NULL)
        g_key_file_set_boolean (config, group, "gpg-verify-summary", priv->local_gpg_verify);
    }

  if (priv->local_noenumerate_set)
    g_key_file_set_boolean (config, group, "xa.noenumerate", priv->local_noenumerate);

  if (priv->local_disabled_set)
    g_key_file_set_boolean (config, group, "xa.disable", priv->local_disabled);

  if (priv->local_nodeps_set)
    g_key_file_set_boolean (config, group, "xa.nodeps", priv->local_nodeps);

  if (priv->local_prio_set)
    {
      g_autofree char *prio_as_string = g_strdup_printf ("%d", priv->local_prio);
      g_key_file_set_string (config, group, "xa.prio", prio_as_string);
    }

  return flatpak_dir_modify_remote (dir, priv->name, config, priv->local_gpg_key, cancellable, error);
}

/**
 * flatpak_remote_get_remote_type:
 * @self: a #FlatpakRemote
 *
 * Get the value of #FlatpakRemote:type.
 *
 * Returns: the type of remote this is
 * Since: 0.9.8
 */
FlatpakRemoteType
flatpak_remote_get_remote_type (FlatpakRemote *self)
{
  FlatpakRemotePrivate *priv = flatpak_remote_get_instance_private (self);

  g_return_val_if_fail (FLATPAK_IS_REMOTE (self), FLATPAK_REMOTE_TYPE_STATIC);

  return priv->type;
}

===== ./common/flatpak-dir-utils-private.h =====
/*
 * Copyright © 2014 Red Hat, Inc
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 */

#pragma once

#include "libglnx.h"

#include "flatpak-ref-utils-private.h"

G_BEGIN_DECLS

typedef struct
{
  char               *id;
  char               *installed_id;
  char               *commit;
  FlatpakDecomposed *ref;
  char              *directory;
  char              *files_path;
  char              *subdir_suffix;
  char              *add_ld_path;
  char             **merge_dirs;
  int                priority;
  gboolean           needs_tmpfs;
  gboolean           is_unmaintained;
} FlatpakExtension;

void flatpak_extension_free (FlatpakExtension *extension);

FlatpakDecomposed *flatpak_find_current_ref (const char   *app_id,
                                             GCancellable *cancellable,
                                             GError      **error);
GFile *flatpak_find_deploy_dir_for_ref (FlatpakDecomposed  *ref,
                                        FlatpakDir        **dir_out,
                                        GCancellable       *cancellable,
                                        GError            **error);
GFile * flatpak_find_files_dir_for_ref (FlatpakDecomposed *ref,
                                        GCancellable      *cancellable,
                                        GError           **error);
GFile * flatpak_find_unmaintained_extension_dir_if_exists (const char   *name,
                                                           const char   *arch,
                                                           const char   *branch,
                                                           GCancellable *cancellable);
FlatpakDeploy * flatpak_find_deploy_for_ref_in (GPtrArray    *dirs,
                                                const char   *ref,
                                                const char   *commit,
                                                GCancellable *cancellable,
                                                GError      **error);
FlatpakDeploy * flatpak_find_deploy_for_ref (const char   *ref,
                                             const char   *commit,
                                             FlatpakDir   *opt_user_dir,
                                             GCancellable *cancellable,
                                             GError      **error);
char ** flatpak_list_deployed_refs (const char   *type,
                                    const char   *name_prefix,
                                    const char   *arch,
                                    const char   *branch,
                                    GCancellable *cancellable,
                                    GError      **error);
char ** flatpak_list_unmaintained_refs (const char   *name_prefix,
                                        const char   *branch,
                                        const char   *arch,
                                        GCancellable *cancellable,
                                        GError      **error);
GList *flatpak_list_extensions (GKeyFile   *metakey,
                                const char *arch,
                                const char *branch);

void flatpak_log_dir_access (FlatpakDir *dir);

G_END_DECLS

===== ./common/flatpak-utils-private.h =====
/*
 * Copyright © 2014 Red Hat, Inc
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Alexander Larsson <alexl@redhat.com>
 */

#ifndef __FLATPAK_UTILS_H__
#define __FLATPAK_UTILS_H__

#include <string.h>

#include "libglnx.h"
#include <gio/gio.h>
#include <gio/gunixfdlist.h>
#include "flatpak-error.h"
#include "flatpak-glib-backports-private.h"

#define XCONCATENATE(x, y) x ## y
#define CONCATENATE(x, y) XCONCATENATE(x, y)

#define FLATPAK_UNIQUE_NAME(base) CONCATENATE(base, __COUNTER__)

#define AUTOFS_SUPER_MAGIC 0x0187

#define FLATPAK_XA_CACHE_VERSION 2
/* version 1 added extra data download size */
/* version 2 added ot.ts timestamps (to new format) */

#define FLATPAK_XA_SUMMARY_VERSION 1
/* version 0/missing is standard ostree summary,
 * version 1 is compact format with inline cache and no deltas
 */

/* These are key names in the per-ref metadata in the summary */
#define OSTREE_COMMIT_TIMESTAMP "ostree.commit.timestamp"
#define OSTREE_COMMIT_TIMESTAMP2 "ot.ts" /* Shorter version of the above */

#define FLATPAK_SUMMARY_DIFF_HEADER "xadf"

/* https://bugzilla.gnome.org/show_bug.cgi?id=766370 */
#if !GLIB_CHECK_VERSION (2, 49, 3)
#define FLATPAK_VARIANT_BUILDER_INITIALIZER {{0, }}
#define FLATPAK_VARIANT_DICT_INITIALIZER {{0, }}
#else
#define FLATPAK_VARIANT_BUILDER_INITIALIZER {{{0, }}}
#define FLATPAK_VARIANT_DICT_INITIALIZER {{{0, }}}
#endif

/* https://github.com/GNOME/libglnx/pull/38
 * Note by using #define rather than wrapping via a static inline, we
 * don't have to re-define attributes like G_GNUC_PRINTF.
 */
#define flatpak_fail glnx_throw

gboolean flatpak_fail_error (GError     **error,
                             FlatpakError code,
                             const char  *fmt,
                             ...) G_GNUC_PRINTF (3, 4);

gint flatpak_strcmp0_ptr (gconstpointer a,
                          gconstpointer b);

/* Sometimes this is /var/run which is a symlink, causing weird issues when we pass
 * it as a path into the sandbox */
char * flatpak_get_real_xdg_runtime_dir (void);
char * flatpak_get_os_release_id (void);
char * flatpak_get_os_release_version_id (void);

gboolean  flatpak_has_path_prefix (const char *str,
                                   const char *prefix);

const char * flatpak_path_match_prefix (const char *pattern,
                                        const char *path);

const char * flatpak_get_arch (void);
const char ** flatpak_get_arches (void);
gboolean flatpak_is_linux32_arch (const char *arch);
const char *flatpak_get_compat_arch (const char *kernel_arch);
const char *flatpak_get_compat_arch_reverse (const char *compat_arch);

const char ** flatpak_get_gl_drivers (void);
gboolean flatpak_extension_matches_reason (const char *extension_id,
                                           const char *reason,
                                           gboolean    default_value);

const char * flatpak_get_bwrap (void);
gboolean flatpak_bwrap_is_unprivileged (void);

char **flatpak_strv_sort_by_length (const char * const *strv);
char **flatpak_strv_merge (char   **strv1,
                           char   **strv2);
char **flatpak_subpaths_merge (char **subpaths1,
                               char **subpaths2);

GBytes * flatpak_read_stream (GInputStream * in,
                              gboolean null_terminate,
                              GError      **error);

gboolean flatpak_bytes_save (GFile        *dest,
                             GBytes       *bytes,
                             GCancellable *cancellable,
                             GError      **error);

gboolean flatpak_variant_save (GFile        *dest,
                               GVariant     *variant,
                               GCancellable *cancellable,
                               GError      **error);

gboolean flatpak_remove_dangling_symlinks (GFile        *dir,
                                           GCancellable *cancellable,
                                           GError      **error);

gboolean flatpak_g_ptr_array_contains_string (GPtrArray  *array,
                                              const char *str);

/* Returns the first string in subset that is not in strv */
static inline const gchar *
g_strv_subset (const gchar * const *strv,
               const gchar * const *subset)
{
  int i;

  for (i = 0; subset[i]; i++)
    {
      const char *key;

      key = subset[i];
      if (!g_strv_contains (strv, key))
        return key;
    }

  return NULL;
}

static inline void
flatpak_auto_unlock_helper (GMutex **mutex)
{
  if (*mutex)
    g_mutex_unlock (*mutex);
}

static inline GMutex *
flatpak_auto_lock_helper (GMutex *mutex)
{
  if (mutex)
    g_mutex_lock (mutex);
  return mutex;
}

gboolean flatpak_switch_symlink_and_remove (const char *symlink_path,
                                            const char *target,
                                            GError    **error);

char *flatpak_keyfile_get_string_non_empty (GKeyFile *keyfile,
                                            const char *group,
                                            const char *key);

GBytes *flatpak_zlib_compress_bytes   (GBytes  *bytes,
                                       int      level,
                                       GError **error);
GBytes *flatpak_zlib_decompress_bytes (GBytes  *bytes,
                                       GError **error);

void flatpak_parse_extension_with_tag (const char *extension,
                                       char      **name,
                                       char      **tag);

gboolean flatpak_argument_needs_quoting (const char *arg);
char * flatpak_quote_argv (const char *argv[],
                           gssize      len);
gboolean flatpak_file_arg_has_suffix (const char *arg,
                                      const char *suffix);

const char *flatpak_file_get_path_cached (GFile *file);

GFile *flatpak_build_file_va (GFile  *base,
                              va_list args);
GFile *flatpak_build_file (GFile *base,
                           ...) G_GNUC_NULL_TERMINATED;

gboolean flatpak_openat_noatime (int           dfd,
                                 const char   *name,
                                 int          *ret_fd,
                                 GCancellable *cancellable,
                                 GError      **error);

typedef enum {
  FLATPAK_CP_FLAGS_NONE = 0,
  FLATPAK_CP_FLAGS_MERGE = 1 << 0,
  FLATPAK_CP_FLAGS_NO_CHOWN = 1 << 1,
  FLATPAK_CP_FLAGS_MOVE = 1 << 2,
} FlatpakCpFlags;

gboolean   flatpak_cp_a (GFile         *src,
                         GFile         *dest,
                         FlatpakCpFlags flags,
                         GCancellable  *cancellable,
                         GError       **error);

gboolean flatpak_mkdir_p (GFile        *dir,
                          GCancellable *cancellable,
                          GError      **error);

gboolean flatpak_rm_rf (GFile        *dir,
                        GCancellable *cancellable,
                        GError      **error);

gboolean flatpak_canonicalize_permissions (int         parent_dfd,
                                           const char *rel_path,
                                           int         uid,
                                           int         gid,
                                           GError    **error);

gboolean flatpak_file_rename (GFile        *from,
                              GFile        *to,
                              GCancellable *cancellable,
                              GError      **error);

gboolean flatpak_open_in_tmpdir_at (int             tmpdir_fd,
                                    int             mode,
                                    char           *tmpl,
                                    GOutputStream **out_stream,
                                    GCancellable   *cancellable,
                                    GError        **error);

gboolean flatpak_buffer_to_sealed_memfd_or_tmpfile (GLnxTmpfile *tmpf,
                                                    const char  *name,
                                                    const char  *str,
                                                    size_t       len,
                                                    GError     **error);

static inline void
flatpak_temp_dir_destroy (void *p)
{
  GFile *dir = p;

  if (dir)
    {
      flatpak_rm_rf (dir, NULL, NULL);
      g_object_unref (dir);
    }
}

typedef GFile FlatpakTempDir;
G_DEFINE_AUTOPTR_CLEANUP_FUNC (FlatpakTempDir, flatpak_temp_dir_destroy)

typedef GMainContext GMainContextPopDefault;
static inline void
flatpak_main_context_pop_default_destroy (void *p)
{
  GMainContext *main_context = p;

  if (main_context)
    {
      /* Ensure we don't leave some cleanup callbacks unhandled as we will never iterate this context again. */
      while (g_main_context_pending (main_context))
        g_main_context_iteration (main_context, TRUE);

      g_main_context_pop_thread_default (main_context);
      g_main_context_unref (main_context);
    }
}

static inline GMainContextPopDefault *
flatpak_main_context_new_default (void)
{
  GMainContext *main_context = g_main_context_new ();

  g_main_context_push_thread_default (main_context);
  return main_context;
}

G_DEFINE_AUTOPTR_CLEANUP_FUNC (GMainContextPopDefault, flatpak_main_context_pop_default_destroy)

#define AUTOLOCK(name) G_GNUC_UNUSED __attribute__((cleanup (flatpak_auto_unlock_helper))) GMutex * G_PASTE (auto_unlock, __LINE__) = flatpak_auto_lock_helper (&G_LOCK_NAME (name))

char * flatpak_filter_glob_to_regexp (const char *glob, gboolean runtime_only, GError **error);
gboolean flatpak_parse_filters (const char *data,
                                GRegex **allow_refs_out,
                                GRegex **deny_refs_out,
                                GError **error);
gboolean flatpak_filters_allow_ref (GRegex *allow_refs,
                                    GRegex *deny_refs,
                                    const char *ref);

gboolean flatpak_allocate_tmpdir (int           tmpdir_dfd,
                                  const char   *tmpdir_relpath,
                                  const char   *tmpdir_prefix,
                                  char        **tmpdir_name_out,
                                  int          *tmpdir_fd_out,
                                  GLnxLockFile *file_lock_out,
                                  gboolean     *reusing_dir_out,
                                  GCancellable *cancellable,
                                  GError      **error);

int flatpak_open_file_at (int           dfd,
                          const char   *subpath,
                          struct stat  *st_buf,
                          GCancellable *cancellable,
                          GError      **error);
GBytes *flatpak_load_file_at (int           dfd,
                              const char   *subpath,
                              GCancellable *cancellable,
                              GError      **error);

gboolean flatpak_check_required_version (const char *ref,
                                         GKeyFile   *metakey,
                                         GError    **error);

int flatpak_levenshtein_distance (const char *s,
                                  gssize      ls,
                                  const char *t,
                                  gssize      lt);

char *   flatpak_dconf_path_for_app_id (const char *app_id);
gboolean flatpak_dconf_path_is_similar (const char *path1,
                                        const char *path2);

static inline void
null_safe_g_ptr_array_unref (gpointer data)
{
  g_clear_pointer (&data, g_ptr_array_unref);
}

GStrv flatpak_parse_env_block (const char  *data,
                               gsize        length,
                               GError     **error);

int flatpak_envp_cmp (const void *p1,
                      const void *p2);

gboolean flatpak_str_is_integer (const char *s);

gboolean flatpak_uri_equal (const char *uri1,
                            const char *uri2);

typedef enum {
  FLATPAK_ESCAPE_DEFAULT        = 0,
  FLATPAK_ESCAPE_ALLOW_NEWLINES = 1 << 0,
  FLATPAK_ESCAPE_DO_NOT_QUOTE   = 1 << 1,
} FlatpakEscapeFlags;

char * flatpak_escape_string (const char        *s,
                              FlatpakEscapeFlags flags);

gboolean flatpak_validate_path_characters (const char *path,
                                           GError    **error);

gboolean running_under_sudo_root (void);

void flatpak_set_debugging (gboolean debugging);
gboolean flatpak_is_debugging (void);

int flatpak_parse_fd (const char  *fd_string,
                      GError     **error);

#ifdef INCLUDE_INTERNAL_TESTS
typedef void (*flatpak_test_fn) (void);
void flatpak_add_test (const char *path, flatpak_test_fn fn);
#define FLATPAK_INTERNAL_TEST(path, fn) \
  __attribute__((constructor)) static void       \
  FLATPAK_UNIQUE_NAME(internal_test_) (void) {   \
    flatpak_add_test (path, fn);                 \
  }
#else
#define FLATPAK_INTERNAL_TEST(path, fn)
#endif

FLATPAK_EXTERN
void flatpak_add_all_tests (void);

char * flatpak_get_path_for_fd (int      fd,
                                GError **error);

#define FLATPAK_MESSAGE_ID "c7b39b1e006b464599465e105b361485"

gboolean flatpak_set_cloexec (int fd);

int flatpak_accept_fd_argument (const char  *option_name,
                                const char  *value,
                                GError     **error);

#endif /* __FLATPAK_UTILS_H__ */

===== ./common/flatpak-common-types-private.h =====
/*
 * Copyright © 2015 Red Hat, Inc
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Alexander Larsson <alexl@redhat.com>
 */

#ifndef __FLATPAK_COMMON_TYPES_H__
#define __FLATPAK_COMMON_TYPES_H__

typedef enum {
  FLATPAK_KINDS_APP = 1 << 0,
  FLATPAK_KINDS_RUNTIME = 1 << 1,
} FlatpakKinds;

typedef enum {
  FLATPAK_RUN_FLAG_DEVEL              = (1 << 0),
  FLATPAK_RUN_FLAG_BACKGROUND         = (1 << 1),
  FLATPAK_RUN_FLAG_LOG_SESSION_BUS    = (1 << 2),
  FLATPAK_RUN_FLAG_LOG_SYSTEM_BUS     = (1 << 3),
  FLATPAK_RUN_FLAG_NO_SESSION_HELPER  = (1 << 4),
  FLATPAK_RUN_FLAG_MULTIARCH          = (1 << 5),
  FLATPAK_RUN_FLAG_WRITABLE_ETC       = (1 << 6),
  FLATPAK_RUN_FLAG_NO_SESSION_BUS_PROXY = (1 << 7),
  FLATPAK_RUN_FLAG_NO_SYSTEM_BUS_PROXY = (1 << 8),
  FLATPAK_RUN_FLAG_SET_PERSONALITY    = (1 << 9),
  FLATPAK_RUN_FLAG_FILE_FORWARDING    = (1 << 10),
  FLATPAK_RUN_FLAG_DIE_WITH_PARENT    = (1 << 11),
  FLATPAK_RUN_FLAG_LOG_A11Y_BUS       = (1 << 12),
  FLATPAK_RUN_FLAG_NO_A11Y_BUS_PROXY  = (1 << 13),
  FLATPAK_RUN_FLAG_SANDBOX            = (1 << 14),
  FLATPAK_RUN_FLAG_NO_DOCUMENTS_PORTAL = (1 << 15),
  FLATPAK_RUN_FLAG_BLUETOOTH          = (1 << 16),
  FLATPAK_RUN_FLAG_CANBUS             = (1 << 17),
  FLATPAK_RUN_FLAG_DO_NOT_REAP        = (1 << 18),
  FLATPAK_RUN_FLAG_NO_PROC            = (1 << 19),
  FLATPAK_RUN_FLAG_PARENT_EXPOSE_PIDS = (1 << 20),
  FLATPAK_RUN_FLAG_PARENT_SHARE_PIDS  = (1 << 21),
  FLATPAK_RUN_FLAG_CLEAR_ENV          = (1 << 22),
} FlatpakRunFlags;

typedef struct FlatpakDir             FlatpakDir;
typedef struct FlatpakDeploy          FlatpakDeploy;
typedef struct FlatpakImageCollection FlatpakImageCollection;
typedef struct _FlatpakImageSource    FlatpakImageSource;
typedef struct FlatpakOciRegistry     FlatpakOciRegistry;
typedef struct _FlatpakOciManifest    FlatpakOciManifest;
typedef struct _FlatpakOciImage       FlatpakOciImage;

#endif /* __FLATPAK_COMMON_TYPES_H__ */

===== ./common/flatpak-error.c =====
/* flatpak-error.c
 *
 * Copyright (C) 2015 Red Hat, Inc
 *
 * This file 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 of the
 * License, or (at your option) any later version.
 *
 * This file 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 program.  If not, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Alexander Larsson <alexl@redhat.com>
 */

#include "config.h"

#include "flatpak-error.h"

#include <gio/gio.h>

/**
 * SECTION:flatpak-error
 * @Title: Error codes
 *
 * The FlatpakError and FlatpakPortalError enumerations contain error codes
 * for some common errors.
 */

/* This is actually defined in common/flatpak-utils.c so the common code can report errors */

===== ./common/flatpak-run-wayland-private.h =====
/*
 * Copyright © 2014 Red Hat, Inc
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Alexander Larsson <alexl@redhat.com>
 */

#pragma once

#include "libglnx.h"

#include "flatpak-bwrap-private.h"
#include "flatpak-common-types-private.h"
#include "flatpak-context-private.h"

G_BEGIN_DECLS

gboolean
flatpak_run_add_wayland_args (FlatpakBwrap *bwrap,
                              const char   *app_id,
                              const char   *instance_id,
                              gboolean      allowed,
                              gboolean      inherit_wayland_socket);

gboolean
flatpak_run_has_wayland (void);

G_END_DECLS

===== ./common/flatpak-oci-registry.c =====
/* vi:set et sw=2 sts=2 cin cino=t0,f0,(0,{s,>2s,n-s,^-s,e-s:
 * Copyright © 2014-2019 Red Hat, Inc
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Alexander Larsson <alexl@redhat.com>
 */

#include "config.h"

#include <glib/gi18n-lib.h>
#include <gio/gunixoutputstream.h>
#include <gio/gunixinputstream.h>

#include "libglnx.h"

#include <archive.h>
#include <archive_entry.h>
#include "flatpak-image-source-private.h"
#include "flatpak-oci-registry-private.h"
#include "flatpak-oci-signatures-private.h"
#include "flatpak-repo-utils-private.h"
#include "flatpak-utils-base-private.h"
#include "flatpak-utils-private.h"
#include "flatpak-uri-private.h"
#include "flatpak-variant-private.h"
#include "flatpak-variant-impl-private.h"
#include "flatpak-dir-private.h"
#include "flatpak-xml-utils-private.h"
#include "flatpak-zstd-compressor-private.h"
#include "flatpak-zstd-decompressor-private.h"

#define MAX_JSON_SIZE (1024 * 1024)

typedef struct archive FlatpakAutoArchiveWrite;
G_DEFINE_AUTOPTR_CLEANUP_FUNC (FlatpakAutoArchiveWrite, archive_write_free)

typedef struct archive FlatpakAutoArchiveRead;
G_DEFINE_AUTOPTR_CLEANUP_FUNC (FlatpakAutoArchiveRead, archive_read_free)

static void flatpak_oci_registry_initable_iface_init (GInitableIface *iface);

/* A FlatpakOciRegistry represents either:
 *
 *  A local directory with a layout corresponding to the OCI image specification -
 *    we usually use this to store a single image, but it could be used for multiple
 *    images.
 *  A remote docker registry.
 *
 * This code used to support OCI image layouts on remote HTTP servers, but that's not
 * really a thing anybody does. It would be inefficient for storing large numbers of
 * images, since all versions need to be listed in index.json.
 */
struct FlatpakOciRegistry
{
  GObject  parent;

  gboolean for_write;
  gboolean valid;
  gboolean is_docker;
  char    *uri;
  GFile   *archive;
  int      tmp_dfd;
  char    *token;
  char    *signature_lookaside;

  /* Local repos */
  int dfd;
  GLnxTmpDir *tmp_dir;

  /* Remote repos */
  FlatpakHttpSession *http_session;
  GUri *base_uri;
  FlatpakCertificates *certificates;
};

typedef struct
{
  GObjectClass parent_class;
} FlatpakOciRegistryClass;

enum {
  PROP_0,

  PROP_URI,
  PROP_ARCHIVE,
  PROP_FOR_WRITE,
  PROP_TMP_DFD,
};

G_DEFINE_TYPE_WITH_CODE (FlatpakOciRegistry, flatpak_oci_registry, G_TYPE_OBJECT,
                         G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE,
                                                flatpak_oci_registry_initable_iface_init))

static void
glnx_tmpdir_free (GLnxTmpDir *tmpf)
{
  (void)glnx_tmpdir_delete (tmpf, NULL, NULL);
  g_free (tmpf);
}
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GLnxTmpDir, glnx_tmpdir_free)

static gchar *
parse_relative_uri (GUri *base_uri,
                    const char *subpath,
                    GError **error)
{
  g_autoptr(GUri) uri = NULL;

  uri = g_uri_parse_relative (base_uri, subpath, FLATPAK_HTTP_URI_FLAGS | G_URI_FLAGS_PARSE_RELAXED, error);
  if (uri == NULL)
    return NULL;

  return g_uri_to_string_partial (uri, G_URI_HIDE_PASSWORD);
}

static void
flatpak_oci_registry_finalize (GObject *object)
{
  FlatpakOciRegistry *self = FLATPAK_OCI_REGISTRY (object);

  if (self->dfd != -1)
    close (self->dfd);

  g_clear_pointer (&self->http_session, flatpak_http_session_free);
  g_clear_pointer (&self->base_uri, g_uri_unref);
  g_clear_pointer (&self->uri, g_free);
  g_clear_pointer (&self->token, g_free);
  g_clear_object (&self->archive);
  g_clear_pointer (&self->tmp_dir, glnx_tmpdir_free);
  g_clear_pointer (&self->certificates, flatpak_certificates_free);
  g_clear_pointer (&self->signature_lookaside, g_free);

  G_OBJECT_CLASS (flatpak_oci_registry_parent_class)->finalize (object);
}

static void
flatpak_oci_registry_set_property (GObject      *object,
                                   guint         prop_id,
                                   const GValue *value,
                                   GParamSpec   *pspec)
{
  FlatpakOciRegistry *self = FLATPAK_OCI_REGISTRY (object);
  const char *uri;

  switch (prop_id)
    {
    case PROP_URI:
      /* Ensure the base uri ends with a / so relative urls work */
      uri = g_value_get_string (value);
      if (uri)
        {
        if (g_str_has_suffix (uri, "/"))
          self->uri = g_strdup (uri);
        else
          self->uri = g_strconcat (uri, "/", NULL);
        }
      break;

    case PROP_ARCHIVE:
      self->archive = g_value_dup_object (value);
      break;

    case PROP_FOR_WRITE:
      self->for_write = g_value_get_boolean (value);
      break;

    case PROP_TMP_DFD:
      self->tmp_dfd = g_value_get_int (value);
      break;

    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
    }
}

static void
flatpak_oci_registry_get_property (GObject    *object,
                                   guint       prop_id,
                                   GValue     *value,
                                   GParamSpec *pspec)
{
  FlatpakOciRegistry *self = FLATPAK_OCI_REGISTRY (object);

  switch (prop_id)
    {
    case PROP_URI:
      g_value_set_string (value, self->uri);
      break;

    case PROP_ARCHIVE:
      g_value_set_object (value, self->archive);
      break;

    case PROP_FOR_WRITE:
      g_value_set_boolean (value, self->for_write);
      break;

    case PROP_TMP_DFD:
      g_value_set_int (value, self->tmp_dfd);
      break;

    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
    }
}

static void
flatpak_oci_registry_class_init (FlatpakOciRegistryClass *klass)
{
  GObjectClass *object_class = G_OBJECT_CLASS (klass);

  object_class->finalize = flatpak_oci_registry_finalize;
  object_class->get_property = flatpak_oci_registry_get_property;
  object_class->set_property = flatpak_oci_registry_set_property;

  g_object_class_install_property (object_class,
                                   PROP_URI,
                                   g_param_spec_string ("uri",
                                                        "",
                                                        "",
                                                        NULL,
                                                        G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
  g_object_class_install_property (object_class,
                                   PROP_ARCHIVE,
                                   g_param_spec_object ("archive",
                                                        "",
                                                        "",
                                                        G_TYPE_FILE,
                                                        G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
  g_object_class_install_property (object_class,
                                   PROP_TMP_DFD,
                                   g_param_spec_int ("tmp-dfd",
                                                     "",
                                                     "",
                                                     -1, G_MAXINT, -1,
                                                     G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
  g_object_class_install_property (object_class,
                                   PROP_FOR_WRITE,
                                   g_param_spec_boolean ("for-write",
                                                         "",
                                                         "",
                                                         FALSE,
                                                         G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
}

static void
flatpak_oci_registry_init (FlatpakOciRegistry *self)
{
  self->dfd = -1;
  self->tmp_dfd = -1;
}

gboolean
flatpak_oci_registry_is_local (FlatpakOciRegistry *self)
{
  return self->dfd != -1;
}

const char *
flatpak_oci_registry_get_uri (FlatpakOciRegistry *self)
{
  return self->uri;
}

void
flatpak_oci_registry_set_token (FlatpakOciRegistry *self,
                                const char *token)
{
  g_free (self->token);
  self->token = g_strdup (token);

  if (self->token)
    (void)glnx_file_replace_contents_at (self->dfd, ".token",
                                         (guchar *)self->token,
                                         strlen (self->token),
                                         0, NULL, NULL);
}

void
flatpak_oci_registry_set_signature_lookaside (FlatpakOciRegistry *self,
                                              const char         *signature_lookaside)
{
  g_set_str (&self->signature_lookaside, signature_lookaside);

  if (self->signature_lookaside != NULL)
    {
      size_t last = strlen (self->signature_lookaside) - 1;

      if (self->signature_lookaside[last] == '/')
        self->signature_lookaside[last] = '\0';
    }
}

FlatpakOciRegistry *
flatpak_oci_registry_new (const char   *uri,
                          gboolean      for_write,
                          int           tmp_dfd,
                          GCancellable *cancellable,
                          GError      **error)
{
  FlatpakOciRegistry *oci_registry;

  oci_registry = g_initable_new (FLATPAK_TYPE_OCI_REGISTRY,
                                 cancellable, error,
                                 "uri", uri,
                                 "for-write", for_write,
                                 "tmp-dfd", tmp_dfd,
                                 NULL);

  return oci_registry;
}

FlatpakOciRegistry *
flatpak_oci_registry_new_for_archive (GFile        *archive,
                                      GCancellable *cancellable,
                                      GError      **error)
{
  FlatpakOciRegistry *oci_registry;

  oci_registry = g_initable_new (FLATPAK_TYPE_OCI_REGISTRY,
                                 cancellable, error,
                                 "archive", archive,
                                 NULL);

  return oci_registry;
}

/* We just support the first http uri for now */
static char *
choose_alt_uri (GUri        *base_uri,
                const char **alt_uris)
{
  int i;

  if (alt_uris == NULL)
    return NULL;

  for (i = 0; alt_uris[i] != NULL; i++)
    {
      const char *alt_uri = alt_uris[i];
      if (g_str_has_prefix (alt_uri, "http:") || g_str_has_prefix (alt_uri, "https:"))
        return g_strdup (alt_uri);
    }

  return NULL;
}

static GBytes *
remote_load_file (FlatpakOciRegistry *self,
                  const char         *subpath,
                  const char        **alt_uris,
                  char              **out_content_type,
                  GCancellable       *cancellable,
                  GError            **error)
{
  g_autoptr(GBytes) bytes = NULL;
  g_autofree char *uri_s = NULL;

  uri_s = choose_alt_uri (self->base_uri, alt_uris);
  if (uri_s == NULL)
    {
      uri_s = parse_relative_uri (self->base_uri, subpath, error);
      if (uri_s == NULL)
        return NULL;
    }

  bytes = flatpak_load_uri_full (self->http_session,
                                 uri_s, self->certificates, FLATPAK_HTTP_FLAGS_ACCEPT_OCI,
                                 NULL, self->token,
                                 NULL, NULL, NULL, out_content_type, NULL,
                                 cancellable, error);
  if (bytes == NULL)
    return NULL;

  return g_steal_pointer (&bytes);
}

static GBytes *
flatpak_oci_registry_load_file (FlatpakOciRegistry *self,
                                const char         *subpath,
                                const char        **alt_uris,
                                char              **out_content_type,
                                GCancellable       *cancellable,
                                GError            **error)
{
  if (self->dfd != -1)
    return flatpak_load_file_at (self->dfd, subpath, cancellable, error);
  else
    return remote_load_file (self, subpath, alt_uris, out_content_type, cancellable, error);
}

static JsonNode *
parse_json (GBytes *bytes, GCancellable *cancellable, GError **error)
{
  g_autoptr(JsonParser) parser = NULL;
  JsonNode *root = NULL;

  parser = json_parser_new ();
  if (!json_parser_load_from_data (parser,
                                   g_bytes_get_data (bytes, NULL),
                                   g_bytes_get_size (bytes),
                                   error))
    return NULL;

  root = json_parser_get_root (parser);
  if (root == NULL || !JSON_NODE_HOLDS_OBJECT (root))
    {
      g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA, "Invalid json, no root object");
      return NULL;
    }

  return json_node_copy (root);
}

static gboolean
verify_oci_version (GBytes *oci_layout_bytes, gboolean *not_json, GCancellable *cancellable, GError **error)
{
  const char *version;
  g_autoptr(JsonNode) node = NULL;
  JsonObject *oci_layout;

  node = parse_json (oci_layout_bytes, cancellable, error);
  if (node == NULL)
    {
      *not_json = TRUE;
      return FALSE;
    }

  *not_json = FALSE;
  oci_layout = json_node_get_object (node);

  version = json_object_get_string_member (oci_layout, "imageLayoutVersion");
  if (version == NULL)
    {
      g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA, "Unsupported oci repo: oci-layout version missing");
      return FALSE;
    }

  if (strcmp (version, "1.0.0") != 0)
    {
      g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
                   "Unsupported existing oci-layout version %s (only 1.0.0 supported)", version);
      return FALSE;
    }

  return TRUE;
}

/*
 * Code to extract an archive such as a tarfile into a temporary directory
 *
 * Based on: https://github.com/libarchive/libarchive/wiki/Examples#A_Complete_Extractor
 *
 * We treat ARCHIVE_WARNING as fatal - while this might be too strict, it
 * will avoid surprises.
 */

static gboolean
propagate_libarchive_error (GError         **error,
                            struct archive  *a)
{
  g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
               "%s", archive_error_string (a));
  return FALSE;
}

static gboolean
copy_data (struct archive  *ar,
           struct archive  *aw,
           GError         **error)
{
  int r;
  const void *buff;
  size_t size;
  gint64 offset;

  while (TRUE)
    {
      r = archive_read_data_block (ar, &buff, &size, &offset);

      if (r == ARCHIVE_EOF)
        return TRUE;

      if (r == ARCHIVE_RETRY)
        continue;

      if (r != ARCHIVE_OK)
        return propagate_libarchive_error (error, ar);

      while (TRUE)
        {
          r = archive_write_data_block (aw, buff, size, offset);

          if (r == ARCHIVE_RETRY)
            continue;

          if (r == ARCHIVE_OK)
            break;

          return propagate_libarchive_error (error, aw);
        }
    }
}

static gboolean
unpack_archive (GFile   *archive,
                char    *destination,
                GError **error)
{
  g_autoptr(FlatpakAutoArchiveRead) a = NULL;
  g_autoptr(FlatpakAutoArchiveWrite) ext = NULL;
  g_autofree char *archive_path = NULL;
  int flags;
  int r;

  flags = 0;
  flags |= ARCHIVE_EXTRACT_SECURE_NODOTDOT;
  flags |= ARCHIVE_EXTRACT_SECURE_SYMLINKS;

  a = archive_read_new ();
  archive_read_support_format_all (a);
  archive_read_support_filter_all (a);

  ext = archive_write_disk_new ();
  archive_write_disk_set_options (ext, flags);
  archive_write_disk_set_standard_lookup (ext);

  archive_path = g_file_get_path (archive);
  r = archive_read_open_filename (a, archive_path, 10240);
  if (r != ARCHIVE_OK)
    return propagate_libarchive_error (error, a);

  while (TRUE)
    {
      g_autofree char *target_path = NULL;
      struct archive_entry *entry;

      r = archive_read_next_header (a, &entry);
      if (r == ARCHIVE_EOF)
        break;

      if (r != ARCHIVE_OK)
        return propagate_libarchive_error (error, a);

      target_path = g_build_filename (destination, archive_entry_pathname (entry), NULL);
      archive_entry_set_pathname (entry, target_path);

      r = archive_write_header (ext, entry);
      if (r != ARCHIVE_OK)
        return propagate_libarchive_error (error, ext);

      if (archive_entry_size (entry) > 0)
        {
          if (!copy_data (a, ext, error))
            return FALSE;
        }

      r = archive_write_finish_entry (ext);
      if (r != ARCHIVE_OK)
        return propagate_libarchive_error (error, ext);
    }

  r = archive_read_close (a);
  if (r != ARCHIVE_OK)
    return propagate_libarchive_error (error, a);

  r = archive_write_close (ext);
  if (r != ARCHIVE_OK)
    return propagate_libarchive_error (error, ext);

  return TRUE;
}

static const char *
get_download_tmpdir (void)
{
  /* We don't use TMPDIR because the downloaded artifacts can be
   * very big, and we want to prefer /var/tmp to /tmp.
   */
  const char *tmpdir = g_getenv ("FLATPAK_DOWNLOAD_TMPDIR");
  if (tmpdir)
    return tmpdir;

  return "/var/tmp";
}

static GLnxTmpDir *
download_tmpdir_new (GError **error)
{
  g_autoptr(GLnxTmpDir) tmp_dir = g_new0 (GLnxTmpDir, 1);
  glnx_autofd int base_dfd = -1;

  if (!glnx_opendirat (AT_FDCWD, get_download_tmpdir (), TRUE, &base_dfd, error))
    return NULL;

  if (!glnx_mkdtempat (base_dfd, "oci-XXXXXX", 0700, tmp_dir, error))
    return NULL;

  return g_steal_pointer (&tmp_dir);
}

static gboolean
flatpak_oci_registry_ensure_local (FlatpakOciRegistry *self,
                                   gboolean            for_write,
                                   GCancellable       *cancellable,
                                   GError            **error)
{
  g_autoptr(GLnxTmpDir) local_tmp_dir = NULL;
  glnx_autofd int local_dfd = -1;
  int dfd;
  g_autoptr(GError) local_error = NULL;
  g_autoptr(GBytes) oci_layout_bytes = NULL;
  g_autoptr(GBytes) token_bytes = NULL;
  gboolean not_json;

  if (self->dfd != -1)
    {
      dfd = self->dfd;
    }
  else if (self->archive)
    {
      local_tmp_dir = download_tmpdir_new (error);
      if (!local_tmp_dir)
        return FALSE;

      if (!unpack_archive (self->archive, local_tmp_dir->path, error))
        return FALSE;

      if (!glnx_opendirat (AT_FDCWD, local_tmp_dir->path,
                           TRUE, &local_dfd, error))
        return FALSE;

      dfd = local_dfd;
    }
  else
    {
      g_autoptr(GFile) dir = g_file_new_for_uri (self->uri);

      if (!glnx_opendirat (AT_FDCWD, flatpak_file_get_path_cached (dir),
                           TRUE, &local_dfd, &local_error))
        {
          if (for_write && g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
            {
              g_clear_error (&local_error);

              if (!glnx_shutil_mkdir_p_at (AT_FDCWD, flatpak_file_get_path_cached (dir), 0755, cancellable, error))
                return FALSE;

              if (!glnx_opendirat (AT_FDCWD, flatpak_file_get_path_cached (dir),
                                   TRUE, &local_dfd, error))
                return FALSE;
            }
          else
            {
              g_propagate_error (error, g_steal_pointer (&local_error));
              return FALSE;
            }
        }

      dfd = local_dfd;
    }

  if (for_write)
    {
      if (!glnx_shutil_mkdir_p_at (dfd, "blobs/sha256", 0755, cancellable, error))
        return FALSE;
    }

  oci_layout_bytes = flatpak_load_file_at (dfd, "oci-layout", cancellable, &local_error);
  if (oci_layout_bytes == NULL)
    {
      if (for_write && g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
        {
          const char *new_layout_data = "{\"imageLayoutVersion\": \"1.0.0\"}";

          g_clear_error (&local_error);

          if (!glnx_file_replace_contents_at (dfd, "oci-layout",
                                              (const guchar *) new_layout_data,
                                              strlen (new_layout_data),
                                              0,
                                              cancellable, error))
            return FALSE;
        }
      else
        {
          g_propagate_error (error, g_steal_pointer (&local_error));
          return FALSE;
        }
    }
  else if (!verify_oci_version (oci_layout_bytes, &not_json, cancellable, error))
    return FALSE;

  if (self->dfd != -1)
    {
      token_bytes = flatpak_load_file_at (self->dfd, ".token", cancellable, NULL);
      if (token_bytes != NULL)
        self->token = g_strndup (g_bytes_get_data (token_bytes, NULL), g_bytes_get_size (token_bytes));
    }

  if (self->dfd == -1)
    {
      self->dfd = g_steal_fd (&local_dfd);
      self->tmp_dir = g_steal_pointer (&local_tmp_dir);
    }

  return TRUE;
}

static gboolean
flatpak_oci_registry_ensure_remote (FlatpakOciRegistry *self,
                                    gboolean            for_write,
                                    GCancellable       *cancellable,
                                    GError            **error)
{
  g_autoptr(GUri) baseuri = NULL;
  g_autoptr(GError) local_error = NULL;

  if (for_write)
    {
      g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
                   "Writes are not supported for remote OCI registries");
      return FALSE;
    }

  self->http_session = flatpak_create_http_session (PACKAGE_STRING);
  baseuri = g_uri_parse (self->uri, FLATPAK_HTTP_URI_FLAGS | G_URI_FLAGS_PARSE_RELAXED, NULL);
  if (baseuri == NULL)
    {
      g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
                   "Invalid url %s", self->uri);
      return FALSE;
    }

  self->is_docker = TRUE;
  self->base_uri = g_steal_pointer (&baseuri);

  self->certificates = flatpak_get_certificates_for_uri (self->uri, &local_error);
  if (local_error)
    {
      g_propagate_error (error, g_steal_pointer (&local_error));
      return FALSE;
    }

  return TRUE;
}

static gboolean
flatpak_oci_registry_initable_init (GInitable    *initable,
                                    GCancellable *cancellable,
                                    GError      **error)
{
  FlatpakOciRegistry *self = FLATPAK_OCI_REGISTRY (initable);
  gboolean res;

  g_warn_if_fail (self->archive || self->uri);

  if (self->tmp_dfd == -1)
    {
      if (!glnx_opendirat (AT_FDCWD, get_download_tmpdir (), TRUE, &self->tmp_dfd, error))
        return FALSE;
    }

  if (self->archive || g_str_has_prefix (self->uri, "file:/"))
    res = flatpak_oci_registry_ensure_local (self, self->for_write, cancellable, error);
  else
    res = flatpak_oci_registry_ensure_remote (self, self->for_write, cancellable, error);

  if (!res)
    return FALSE;

  self->valid = TRUE;

  return TRUE;
}

static void
flatpak_oci_registry_initable_iface_init (GInitableIface *iface)
{
  iface->init = flatpak_oci_registry_initable_init;
}

FlatpakOciIndex *
flatpak_oci_registry_load_index (FlatpakOciRegistry *self,
                                 GCancellable       *cancellable,
                                 GError            **error)
{
  g_autoptr(GBytes) bytes = NULL;
  g_autoptr(GError) local_error = NULL;

  g_assert (self->valid);

  bytes = flatpak_oci_registry_load_file (self, "index.json", NULL, NULL, cancellable, &local_error);
  if (bytes == NULL)
    {
      g_propagate_error (error, g_steal_pointer (&local_error));
      return NULL;
    }

  return (FlatpakOciIndex *) flatpak_json_from_bytes (bytes, FLATPAK_TYPE_OCI_INDEX, error);
}

gboolean
flatpak_oci_registry_save_index (FlatpakOciRegistry *self,
                                 FlatpakOciIndex    *index,
                                 GCancellable       *cancellable,
                                 GError            **error)
{
  g_autoptr(GBytes) bytes = NULL;

  g_assert (self->valid);

  bytes = flatpak_json_to_bytes (FLATPAK_JSON (index));

  if (!glnx_file_replace_contents_at (self->dfd, "index.json",
                                      g_bytes_get_data (bytes, NULL),
                                      g_bytes_get_size (bytes),
                                      0, cancellable, error))
    return FALSE;

  return TRUE;
}

static gboolean
write_update_checksum (GOutputStream *out,
                       gconstpointer  data,
                       gsize          len,
                       gsize         *out_bytes_written,
                       GChecksum     *checksum,
                       GCancellable  *cancellable,
                       GError       **error)
{
  if (out)
    {
      if (!g_output_stream_write_all (out, data, len, out_bytes_written,
                                      cancellable, error))
        return FALSE;
    }
  else if (out_bytes_written)
    {
      *out_bytes_written = len;
    }

  if (checksum)
    g_checksum_update (checksum, data, len);

  return TRUE;
}

static gboolean
splice_update_checksum (GOutputStream *out,
                        GInputStream  *in,
                        GChecksum     *checksum,
                        GCancellable  *cancellable,
                        GError       **error)
{
  g_return_val_if_fail (out != NULL || checksum != NULL, FALSE);

  if (checksum != NULL)
    {
      gsize bytes_read, bytes_written;
      char buf[4096];
      do
        {
          if (!g_input_stream_read_all (in, buf, sizeof (buf), &bytes_read, cancellable, error))
            return FALSE;
          if (!write_update_checksum (out, buf, bytes_read, &bytes_written, checksum,
                                      cancellable, error))
            return FALSE;
        }
      while (bytes_read > 0);
    }
  else if (out != NULL)
    {
      if (g_output_stream_splice (out, in, 0, cancellable, error) < 0)
        return FALSE;
    }

  return TRUE;
}

static char *
get_digest_subpath (FlatpakOciRegistry *self,
                    const char         *repository,
                    gboolean            is_manifest,
                    gboolean            allow_tag,
                    const char         *digest,
                    GError            **error)
{
  g_autoptr(GString) s = g_string_new ("");

  if (!g_str_has_prefix (digest, "sha256:"))
    {
      if (!allow_tag)
        {
          g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
                       "Unsupported digest type %s", digest);
          return NULL;
        }

      if (!self->is_docker)
        {
          g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
                       "Tags not supported for local oci dirs");
          return NULL;
        }
    }

  if (self->is_docker)
    g_string_append (s, "v2/");

  if (repository)
    {
      g_string_append (s, repository);
      g_string_append (s, "/");
    }

  if (self->is_docker)
    {
      if (is_manifest)
        g_string_append (s, "manifests/");
      else
        g_string_append (s, "blobs/");
      g_string_append (s, digest);
    }
  else
    {
      /* As per above checks this is guaranteed to be a digest */
      g_string_append (s, "blobs/sha256/");
      g_string_append (s, digest + strlen ("sha256:"));
    }

  return g_string_free (g_steal_pointer (&s), FALSE);
}

static char *
checksum_fd (int fd, GCancellable *cancellable, GError **error)
{
  g_autoptr(GChecksum) checksum = NULL;
  g_autoptr(GInputStream) in = g_unix_input_stream_new (fd, FALSE);

  checksum = g_checksum_new (G_CHECKSUM_SHA256);

  if (!splice_update_checksum (NULL, in, checksum, cancellable, error))
    return NULL;

  return g_strdup (g_checksum_get_string (checksum));
}

int
flatpak_oci_registry_download_blob (FlatpakOciRegistry    *self,
                                    const char            *repository,
                                    gboolean               manifest,
                                    const char            *digest,
                                    const char           **alt_uris,
                                    FlatpakLoadUriProgress progress_cb,
                                    gpointer               user_data,
                                    GCancellable          *cancellable,
                                    GError               **error)
{
  g_autofree char *subpath = NULL;
  glnx_autofd int fd = -1;

  g_assert (self->valid);

  subpath = get_digest_subpath (self, repository, manifest, FALSE, digest, error);
  if (subpath == NULL)
    return -1;

  if (self->dfd != -1)
    {
      /* Local case, trust checksum */
      fd = flatpak_open_file_at (self->dfd, subpath, NULL, cancellable, error);
      if (fd == -1)
        return -1;
    }
  else
    {
      g_autofree char *uri_s = NULL;
      g_autofree char *checksum = NULL;
      g_autofree char *tmpfile_name = g_strdup_printf ("oci-layer-XXXXXX");
      g_autoptr(GOutputStream) out_stream = NULL;

      /* remote case, download and verify */

      uri_s = choose_alt_uri (self->base_uri, alt_uris);
      if (uri_s == NULL)
        {
          uri_s = parse_relative_uri (self->base_uri, subpath, error);
          if (uri_s == NULL)
            return -1;
        }

      if (!flatpak_open_in_tmpdir_at (self->tmp_dfd, 0600, tmpfile_name,
                                      &out_stream, cancellable, error))
        return -1;

      fd = flatpak_open_file_at (self->tmp_dfd, tmpfile_name, NULL, cancellable, error);
      (void) unlinkat (self->tmp_dfd, tmpfile_name, 0);

      if (fd == -1)
        return -1;

      if (!flatpak_download_http_uri (self->http_session, uri_s,
                                      self->certificates,
                                      FLATPAK_HTTP_FLAGS_ACCEPT_OCI,
                                      out_stream,
                                      self->token,
                                      progress_cb, user_data,
                                      cancellable, error))
        return -1;

      if (!g_output_stream_close (out_stream, cancellable, error))
        return -1;

      checksum = checksum_fd (fd, cancellable, error);
      if (checksum == NULL)
        return -1;

      if (strcmp (checksum, digest + strlen ("sha256:")) != 0)
        {
          g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
                       "Checksum digest did not match (%s != %s)", digest, checksum);
          return -1;
        }

      lseek (fd, 0, SEEK_SET);
    }

  return g_steal_fd (&fd);
}

gboolean
flatpak_oci_registry_mirror_blob (FlatpakOciRegistry    *self,
                                  FlatpakOciRegistry    *source_registry,
                                  const char            *repository,
                                  gboolean               manifest,
                                  const char            *digest,
                                  const char           **alt_uris,
                                  FlatpakLoadUriProgress progress_cb,
                                  gpointer               user_data,
                                  GCancellable          *cancellable,
                                  GError               **error)
{
  g_autofree char *src_subpath = NULL;
  g_autofree char *dst_subpath = NULL;
  g_auto(GLnxTmpfile) tmpf = { 0 };
  g_autoptr(GOutputStream) out_stream = NULL;
  struct stat stbuf;
  g_autofree char *checksum = NULL;

  g_assert (self->valid);

  if (!self->for_write)
    {
      g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
                   "Write not supported to registry");
      return FALSE;
    }

  src_subpath = get_digest_subpath (source_registry, repository, manifest, FALSE, digest, error);
  if (src_subpath == NULL)
    return FALSE;

  dst_subpath = get_digest_subpath (self, NULL, manifest, FALSE, digest, error);
  if (dst_subpath == NULL)
    return FALSE;

  /* Check if its already available */
  if (fstatat (self->dfd, dst_subpath, &stbuf, AT_SYMLINK_NOFOLLOW) == 0)
    return TRUE;

  if (!glnx_open_tmpfile_linkable_at (self->dfd, "blobs/sha256",
                                      O_RDWR | O_CLOEXEC | O_NOCTTY,
                                      &tmpf, error))
    return FALSE;

  if (source_registry->dfd != -1)
    {
      glnx_autofd int src_fd = -1;

      src_fd = flatpak_open_file_at (source_registry->dfd, src_subpath, NULL, cancellable, error);
      if (src_fd == -1)
        return FALSE;

      if (glnx_regfile_copy_bytes (src_fd, tmpf.fd, (off_t) -1) < 0)
        return glnx_throw_errno_prefix (error, "copyfile");
    }
  else
    {
      g_autofree char *uri_s = parse_relative_uri (source_registry->base_uri, src_subpath, error);
      if (uri_s == NULL)
        return FALSE;

      out_stream = g_unix_output_stream_new (tmpf.fd, FALSE);

      if (!flatpak_download_http_uri (source_registry->http_session,
                                      uri_s, source_registry->certificates,
                                      FLATPAK_HTTP_FLAGS_ACCEPT_OCI, out_stream,
                                      self->token,
                                      progress_cb, user_data,
                                      cancellable, error))
        return FALSE;

      if (!g_output_stream_close (out_stream, cancellable, error))
        return FALSE;
    }

  lseek (tmpf.fd, 0, SEEK_SET);

  checksum = checksum_fd (tmpf.fd, cancellable, error);
  if (checksum == NULL)
    return FALSE;

  if (strcmp (checksum, digest + strlen ("sha256:")) != 0)
    {
      g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
                   "Checksum digest did not match (%s != %s)", digest, checksum);
      return FALSE;
    }

  if (!glnx_link_tmpfile_at (&tmpf,
                             GLNX_LINK_TMPFILE_NOREPLACE_IGNORE_EXIST,
                             self->dfd, dst_subpath,
                             error))
    return FALSE;

  return TRUE;
}

static const char *
object_get_string_member_with_default (JsonNode *json,
                                       const char *member_name,
                                       const char *default_value)
{
  JsonNode *node;

  if (json == NULL || !JSON_NODE_HOLDS_OBJECT(json))
    return default_value;

  node = json_object_get_member (json_node_get_object (json), member_name);

  if (node == NULL || JSON_NODE_HOLDS_NULL (node) || JSON_NODE_TYPE (node) != JSON_NODE_VALUE)
    return default_value;

  return json_node_get_string (node);
}

static const char *
object_find_error_string (JsonNode *json)
{
  const char *error_detail = NULL;
  error_detail = object_get_string_member_with_default (json, "details", NULL);
  if (error_detail == NULL)
    error_detail = object_get_string_member_with_default (json, "message", NULL);
  if (error_detail == NULL)
    error_detail = object_get_string_member_with_default (json, "error", NULL);
  return error_detail;
}

static char *
get_token_for_www_auth (FlatpakOciRegistry *self,
                        const char    *repository,
                        const char    *www_authenticate,
                        const char    *auth,
                        GCancellable  *cancellable,
                        GError        **error)
{
  g_autoptr(GHashTable) params = NULL;
  g_autoptr(GString) args = NULL;
  const char *realm, *service, *scope, *token, *body_data;
  g_autofree char *default_scope = NULL;
  g_autoptr(GUri) auth_uri = NULL;
  g_autofree char *auth_uri_s = NULL;
  g_autoptr(GBytes) body = NULL;
  g_autoptr(JsonNode) json = NULL;
  GUri *tmp_uri;
  int http_status;

  if (g_ascii_strncasecmp (www_authenticate, "Bearer ", strlen ("Bearer ")) != 0)
    {
      flatpak_fail (error, _("Only Bearer authentication supported"));
      return NULL;
    }

  params = flatpak_parse_http_header_param_list (www_authenticate + strlen ("Bearer "));

  realm = g_hash_table_lookup (params, "realm");
  if (realm == NULL)
    {
      flatpak_fail (error, _("Only realm in authentication request"));
      return NULL;
    }

  auth_uri = g_uri_parse (realm, FLATPAK_HTTP_URI_FLAGS | G_URI_FLAGS_PARSE_RELAXED, NULL);
  if (auth_uri == NULL)
    {
      flatpak_fail (error, _("Invalid realm in authentication request"));
      return NULL;
    }

  args = g_string_new (NULL);

  service = g_hash_table_lookup (params, "service");
  if (service)
    flatpak_uri_encode_query_arg (args, "service", (char *)service);

  scope = g_hash_table_lookup (params, "scope");
  if (scope == NULL)
    scope = default_scope = g_strdup_printf("repository:%s:pull", repository);

  flatpak_uri_encode_query_arg (args, "scope", (char *)scope);

  tmp_uri = g_uri_build (g_uri_get_flags (auth_uri) | G_URI_FLAGS_ENCODED_QUERY,
                         g_uri_get_scheme (auth_uri),
                         g_uri_get_userinfo (auth_uri),
                         g_uri_get_host (auth_uri),
                         g_uri_get_port (auth_uri),
                         g_uri_get_path (auth_uri),
                         args->str,
                         g_uri_get_fragment (auth_uri));
  g_uri_unref (auth_uri);
  auth_uri = tmp_uri;
  auth_uri_s = g_uri_to_string_partial (auth_uri, G_URI_HIDE_PASSWORD);

  body = flatpak_load_uri_full (self->http_session,
                                auth_uri_s,
                                self->certificates,
                                FLATPAK_HTTP_FLAGS_NOCHECK_STATUS,
                                auth, NULL,
                                NULL, NULL,
                                &http_status, NULL, NULL,
                                cancellable, error);
  if (body == NULL)
    return NULL;

  body_data = (char *)g_bytes_get_data (body, NULL);

  if (http_status < 200 || http_status >= 300)
    {
      const char *error_detail = NULL;
      json = json_from_string (body_data, NULL);
      if (json)
        {
          error_detail = object_find_error_string (json);
          if (error_detail == NULL && JSON_NODE_HOLDS_OBJECT(json))
            {
              JsonNode *errors = json_object_get_member (json_node_get_object (json), "errors");
              if (errors && JSON_NODE_HOLDS_ARRAY (errors))
                {
                  JsonArray *array = json_node_get_array (errors);
                  for (int i = 0; i < json_array_get_length (array); i++)
                    {
                      error_detail = object_find_error_string (json_array_get_element (array, i));
                      if (error_detail != 0)
                        break;
                    }
                }
            }
        }

      if (error_detail == NULL)
        g_info ("Unhandled error body format: %s", body_data);

      if (http_status == 401 /* UNAUTHORIZED */)
        {
          if (error_detail)
            flatpak_fail_error (error, FLATPAK_ERROR_NOT_AUTHORIZED, _("Authorization failed: %s"), error_detail);
          else
            flatpak_fail_error (error, FLATPAK_ERROR_NOT_AUTHORIZED, _("Authorization failed"));
          return NULL;
        }

      flatpak_fail (error, _("Unexpected response status %d when requesting token: %s"), http_status, (char *)g_bytes_get_data (body, NULL));
      return NULL;
    }

  json = json_from_string (body_data, error);
  if (json == NULL)
    return NULL;

  token = object_get_string_member_with_default (json, "token", NULL);
  if (token == NULL)
    {
      flatpak_fail (error, _("Invalid authentication request response"));
      return NULL;
    }

  return g_strdup (token);
}

char *
flatpak_oci_registry_get_token (FlatpakOciRegistry *self,
                                const char         *repository,
                                const char         *digest,
                                const char         *basic_auth,
                                GCancellable       *cancellable,
                                GError            **error)
{
  g_autofree char *subpath = NULL;
  g_autofree char *uri_s = NULL;
  g_autofree char *www_authenticate = NULL;
  g_autofree char *token = NULL;
  g_autoptr(GBytes) body = NULL;
  int http_status;

  g_assert (self->valid);

  subpath = get_digest_subpath (self, repository, TRUE, FALSE, digest, error);
  if (subpath == NULL)
    return NULL;

  if (self->dfd != -1)
    return g_strdup (""); // No tokens for local repos

  uri_s = parse_relative_uri (self->base_uri, subpath, error);
  if (uri_s == NULL)
    return NULL;

  body = flatpak_load_uri_full (self->http_session, uri_s, self->certificates,
                                FLATPAK_HTTP_FLAGS_ACCEPT_OCI | FLATPAK_HTTP_FLAGS_HEAD | FLATPAK_HTTP_FLAGS_NOCHECK_STATUS,
                                NULL, NULL,
                                NULL, NULL,
                                &http_status, NULL, &www_authenticate,
                                cancellable, error);
  if (body == NULL)
    return NULL;

  if (http_status >= 200 && http_status < 300)
    return g_strdup ("");

  if (http_status != 401 /* UNAUTHORIZED */)
    {
      g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Unexpected response status %d from repo", http_status);
      return NULL;
    }

  /* Need www-authenticated header */
  if (www_authenticate == NULL)
    {
      g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "No WWW-Authenticate header from repo");
      return NULL;
    }

  token = get_token_for_www_auth (self, repository, www_authenticate, basic_auth, cancellable, error);
  if (token == NULL)
    return NULL;

  return g_steal_pointer (&token);
}

GBytes *
flatpak_oci_registry_load_blob (FlatpakOciRegistry *self,
                                const char         *repository,
                                gboolean            manifest,
                                const char         *digest, /* Note: Can be tag for remote registries */
                                const char        **alt_uris,
                                char              **out_content_type,
                                GCancellable       *cancellable,
                                GError            **error)
{
  g_autofree char *subpath = NULL;
  g_autoptr(GBytes) bytes = NULL;
  g_autofree char *json_checksum = NULL;

  g_assert (self->valid);

  // Note: Allow tags here, means we have to check that its a digest before verifying below
  subpath = get_digest_subpath (self, repository, manifest, TRUE, digest, error);
  if (subpath == NULL)
    return NULL;

  bytes = flatpak_oci_registry_load_file (self, subpath, alt_uris, out_content_type, cancellable, error);
  if (bytes == NULL)
    return NULL;

  json_checksum = g_compute_checksum_for_bytes (G_CHECKSUM_SHA256, bytes);

  if (g_str_has_prefix (digest, "sha256:") &&
      strcmp (json_checksum, digest + strlen ("sha256:")) != 0)
    {
      g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA,
                   "Checksum for digest %s is wrong (was %s)", digest, json_checksum);
      return NULL;
    }

  return g_steal_pointer (&bytes);
}

char *
flatpak_oci_registry_store_blob (FlatpakOciRegistry *self,
                                 GBytes             *data,
                                 GCancellable       *cancellable,
                                 GError            **error)
{
  g_autofree char *sha256 = g_compute_checksum_for_bytes (G_CHECKSUM_SHA256, data);
  g_autofree char *subpath = NULL;

  g_assert (self->valid);

  subpath = g_strdup_printf ("blobs/sha256/%s", sha256);
  if (!glnx_file_replace_contents_at (self->dfd, subpath,
                                      g_bytes_get_data (data, NULL),
                                      g_bytes_get_size (data),
                                      0, cancellable, error))
    return NULL;

  return g_strdup_printf ("sha256:%s", sha256);
}

FlatpakOciDescriptor *
flatpak_oci_registry_store_json (FlatpakOciRegistry *self,
                                 FlatpakJson        *json,
                                 GCancellable       *cancellable,
                                 GError            **error)
{
  g_autoptr(GBytes) bytes = flatpak_json_to_bytes (json);
  g_autofree char *digest = NULL;

  digest = flatpak_oci_registry_store_blob (self, bytes, cancellable, error);
  if (digest == NULL)
    return NULL;

  return flatpak_oci_descriptor_new (FLATPAK_JSON_CLASS (FLATPAK_JSON_GET_CLASS (json))->mediatype, digest, g_bytes_get_size (bytes));
}

FlatpakOciVersioned *
flatpak_oci_registry_load_versioned (FlatpakOciRegistry *self,
                                     const char         *repository,
                                     const char         *digest,
                                     const char        **alt_uris,
                                     gsize              *out_size,
                                     GCancellable       *cancellable,
                                     GError            **error)
{
  g_autoptr(GBytes) bytes = NULL;
  g_autofree char *content_type = NULL;

  g_assert (self->valid);

  bytes = flatpak_oci_registry_load_blob (self, repository, TRUE, digest, alt_uris, &content_type, cancellable, error);
  if (bytes == NULL)
    return NULL;

  if (out_size)
    *out_size = g_bytes_get_size (bytes);
  return flatpak_oci_versioned_from_json (bytes, content_type, error);
}

FlatpakOciImage *
flatpak_oci_registry_load_image_config (FlatpakOciRegistry *self,
                                        const char         *repository,
                                        const char         *digest,
                                        const char        **alt_uris,
                                        gsize              *out_size,
                                        GCancellable       *cancellable,
                                        GError            **error)
{
  g_autoptr(GBytes) bytes = NULL;

  g_assert (self->valid);

  bytes = flatpak_oci_registry_load_blob (self, repository, FALSE, digest, alt_uris, NULL, cancellable, error);
  if (bytes == NULL)
    return NULL;

  if (out_size)
    *out_size = g_bytes_get_size (bytes);
  return flatpak_oci_image_from_json (bytes, error);
}

struct FlatpakOciLayerWriter
{
  GObject             parent;

  FlatpakOciRegistry       *registry;
  FlatpakOciWriteLayerFlags flags;

  GChecksum          *uncompressed_checksum;
  GChecksum          *compressed_checksum;
  struct archive     *archive;
  GConverter         *compressor;
  guint64             uncompressed_size;
  guint64             compressed_size;
  GLnxTmpfile         tmpf;
};

typedef struct
{
  GObjectClass parent_class;
} FlatpakOciLayerWriterClass;

G_DEFINE_TYPE (FlatpakOciLayerWriter, flatpak_oci_layer_writer, G_TYPE_OBJECT)

static void
flatpak_oci_layer_writer_reset (FlatpakOciLayerWriter *self)
{
  glnx_tmpfile_clear (&self->tmpf);

  g_checksum_reset (self->uncompressed_checksum);
  g_checksum_reset (self->compressed_checksum);

  if (self->archive)
    {
      archive_write_free (self->archive);
      self->archive = NULL;
    }

  g_clear_object (&self->compressor);
}

static void
flatpak_oci_layer_writer_finalize (GObject *object)
{
  FlatpakOciLayerWriter *self = FLATPAK_OCI_LAYER_WRITER (object);

  flatpak_oci_layer_writer_reset (self);

  g_checksum_free (self->compressed_checksum);
  g_checksum_free (self->uncompressed_checksum);
  glnx_tmpfile_clear (&self->tmpf);

  g_clear_object (&self->registry);

  G_OBJECT_CLASS (flatpak_oci_layer_writer_parent_class)->finalize (object);
}

static void
flatpak_oci_layer_writer_class_init (FlatpakOciLayerWriterClass *klass)
{
  GObjectClass *object_class = G_OBJECT_CLASS (klass);

  object_class->finalize = flatpak_oci_layer_writer_finalize;
}

static void
flatpak_oci_layer_writer_init (FlatpakOciLayerWriter *self)
{
  self->uncompressed_checksum = g_checksum_new (G_CHECKSUM_SHA256);
  self->compressed_checksum = g_checksum_new (G_CHECKSUM_SHA256);
}

static int
flatpak_oci_layer_writer_open_cb (struct archive *archive,
                                  void           *client_data)
{
  return ARCHIVE_OK;
}

static gssize
flatpak_oci_layer_writer_compress (FlatpakOciLayerWriter *self,
                                   const void            *buffer,
                                   size_t                 length,
                                   gboolean               at_end)
{
  guchar compressed_buffer[8192];
  GConverterResult res;
  gsize total_bytes_read, bytes_read, bytes_written, to_write_len;
  guchar *to_write;
  g_autoptr(GError) local_error = NULL;
  GConverterFlags flags = 0;
  bytes_read = 0;

  total_bytes_read = 0;

  if (at_end)
    flags |= G_CONVERTER_INPUT_AT_END;

  do
    {
      res = g_converter_convert (self->compressor,
                                 buffer, length,
                                 compressed_buffer, sizeof (compressed_buffer),
                                 flags, &bytes_read, &bytes_written,
                                 &local_error);
      if (res == G_CONVERTER_ERROR)
        {
          archive_set_error (self->archive, EIO, "%s", local_error->message);
          return -1;
        }

      g_checksum_update (self->uncompressed_checksum, buffer, bytes_read);
      g_checksum_update (self->compressed_checksum, compressed_buffer, bytes_written);
      self->uncompressed_size += bytes_read;
      self->compressed_size += bytes_written;

      to_write_len = bytes_written;
      to_write = compressed_buffer;
      while (to_write_len > 0)
        {
          ssize_t result = write (self->tmpf.fd, to_write, to_write_len);
          if (result <= 0)
            {
              if (errno == EINTR)
                continue;
              archive_set_error (self->archive, errno, "Write error");
              return -1;
            }

          to_write_len -= result;
          to_write += result;
        }

      total_bytes_read += bytes_read;
    }
  while ((length > 0 && bytes_read == 0) || /* Repeat if we consumed nothing */
         (at_end && res != G_CONVERTER_FINISHED)); /* Or until finished if at_end */

  return total_bytes_read;
}

static ssize_t
flatpak_oci_layer_writer_write_cb (struct archive *archive,
                                   void           *client_data,
                                   const void     *buffer,
                                   size_t          length)
{
  FlatpakOciLayerWriter *self = FLATPAK_OCI_LAYER_WRITER (client_data);

  return flatpak_oci_layer_writer_compress (self, buffer, length, FALSE);
}

static int
flatpak_oci_layer_writer_close_cb (struct archive *archive,
                                   void           *client_data)
{
  FlatpakOciLayerWriter *self = FLATPAK_OCI_LAYER_WRITER (client_data);
  gssize res;
  char buffer[1] = {0};

  res = flatpak_oci_layer_writer_compress (self, &buffer, 0, TRUE);
  if (res < 0)
    return ARCHIVE_FATAL;

  return ARCHIVE_OK;
}

FlatpakOciLayerWriter *
flatpak_oci_registry_write_layer (FlatpakOciRegistry         *self,
                                  FlatpakOciWriteLayerFlags  flags,
                                  GCancellable               *cancellable,
                                  GError                    **error)
{
  g_autoptr(FlatpakOciLayerWriter) oci_layer_writer = NULL;
  g_autoptr(FlatpakAutoArchiveWrite) a = NULL;
  g_auto(GLnxTmpfile) tmpf = { 0 };

  g_assert (self->valid);

  if (!self->for_write)
    {
      g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
                   "Write not supported to registry");
      return NULL;
    }

  oci_layer_writer = g_object_new (FLATPAK_TYPE_OCI_LAYER_WRITER, NULL);
  oci_layer_writer->registry = g_object_ref (self);
  oci_layer_writer->flags = flags;

  if (!glnx_open_tmpfile_linkable_at (self->dfd,
                                      "blobs/sha256",
                                      O_WRONLY,
                                      &tmpf,
                                      error))
    return NULL;

  if (fchmod (tmpf.fd, 0644) != 0)
    {
      glnx_set_error_from_errno (error);
      return NULL;
    }

  a = archive_write_new ();
  if (archive_write_set_format_pax (a) != ARCHIVE_OK ||
      archive_write_add_filter_none (a) != ARCHIVE_OK)
    {
      propagate_libarchive_error (error, a);
      return NULL;
    }

  if (archive_write_open (a, oci_layer_writer,
                          flatpak_oci_layer_writer_open_cb,
                          flatpak_oci_layer_writer_write_cb,
                          flatpak_oci_layer_writer_close_cb) != ARCHIVE_OK)
    {
      propagate_libarchive_error (error, a);
      return NULL;
    }

  flatpak_oci_layer_writer_reset (oci_layer_writer);

  oci_layer_writer->archive = g_steal_pointer (&a);
  /* Transfer ownership of the tmpfile */
  oci_layer_writer->tmpf = tmpf;
  tmpf.initialized = 0;

  if ((flags & FLATPAK_OCI_WRITE_LAYER_FLAGS_ZSTD) != 0)
    {
      /*
       * For the Fedora Flatpak Runtime:
       *
       *  gzip -6 (default) 83s  712 MiB
       *  zlib-ng -6        38s  741 MiB (bsdtar internal)
       *  zstd -3            9s  670 MiB
       *  zstd -6           22s  627 MiB
       *  zstd -9           34s  584 MiB
       *
       * So, even -9 is 240% faster, while producing a 18% smaller result.
       */
#ifdef HAVE_ZSTD
      oci_layer_writer->compressor =
        G_CONVERTER (flatpak_zstd_compressor_new (9));
#else
      g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
                   _("Flatpak was compiled without zstd support"));
      return NULL;
#endif
    }
  else
    {
      oci_layer_writer->compressor =
        G_CONVERTER (g_zlib_compressor_new (G_ZLIB_COMPRESSOR_FORMAT_GZIP, -1));
    }

  return g_steal_pointer (&oci_layer_writer);
}

gboolean
flatpak_oci_layer_writer_close (FlatpakOciLayerWriter *self,
                                char                 **uncompressed_digest_out,
                                FlatpakOciDescriptor **res_out,
                                GCancellable          *cancellable,
                                GError               **error)
{
  g_autofree char *path = NULL;

  if (archive_write_close (self->archive) != ARCHIVE_OK)
    return propagate_libarchive_error (error, self->archive);

  path = g_strdup_printf ("blobs/sha256/%s",
                          g_checksum_get_string (self->compressed_checksum));

  if (!glnx_link_tmpfile_at (&self->tmpf,
                             GLNX_LINK_TMPFILE_REPLACE,
                             self->registry->dfd,
                             path,
                             error))
    return FALSE;

  if (uncompressed_digest_out != NULL)
    *uncompressed_digest_out = g_strdup_printf ("sha256:%s", g_checksum_get_string (self->uncompressed_checksum));
  if (res_out != NULL)
    {
      g_autofree char *digest = g_strdup_printf ("sha256:%s", g_checksum_get_string (self->compressed_checksum));
      const char *media_type;

      if ((self->flags & FLATPAK_OCI_WRITE_LAYER_FLAGS_ZSTD) != 0)
        media_type = FLATPAK_OCI_MEDIA_TYPE_IMAGE_LAYER_ZSTD;
      else
        media_type = FLATPAK_OCI_MEDIA_TYPE_IMAGE_LAYER_GZIP;

      *res_out = flatpak_oci_descriptor_new (media_type, digest, self->compressed_size);
    }

  return TRUE;
}

struct archive *
flatpak_oci_layer_writer_get_archive (FlatpakOciLayerWriter *self)
{
  return self->archive;
}

typedef struct
{
  int        fd;
  GChecksum *checksum;
  char       buffer[16 * 1024];
  gboolean   at_end;
} FlatpakArchiveReadWithChecksum;

static int
checksum_open_cb (struct archive *a, void *user_data)
{
  return ARCHIVE_OK;
}

static ssize_t
checksum_read_cb (struct archive *a, void *user_data, const void **buff)
{
  FlatpakArchiveReadWithChecksum *data = user_data;
  ssize_t bytes_read;

  *buff = &data->buffer;
  do
    bytes_read = read (data->fd, &data->buffer, sizeof (data->buffer));
  while (G_UNLIKELY (bytes_read == -1 && errno == EINTR));

  if (bytes_read <= 0)
    data->at_end = TRUE; /* Failed or eof */

  if (bytes_read < 0)
    {
      archive_set_error (a, errno, "Read error on fd %d", data->fd);
      return -1;
    }

  g_checksum_update (data->checksum, (guchar *) data->buffer, bytes_read);

  return bytes_read;
}

static int64_t
checksum_skip_cb (struct archive *a, void *user_data, int64_t request)
{
  FlatpakArchiveReadWithChecksum *data = user_data;
  int64_t old_offset, new_offset;

  if (((old_offset = lseek (data->fd, 0, SEEK_CUR)) >= 0) &&
      ((new_offset = lseek (data->fd, request, SEEK_CUR)) >= 0))
    return new_offset - old_offset;

  archive_set_error (a, errno, "Error seeking");
  return -1;
}

static int
checksum_close_cb (struct archive *a, void *user_data)
{
  FlatpakArchiveReadWithChecksum *data = user_data;

  /* Checksum to the end to ensure we got everything, even if libarchive didn't read it all */
  if (!data->at_end)
    {
      while (TRUE)
        {
          ssize_t bytes_read;
          do
            bytes_read = read (data->fd, &data->buffer, sizeof (data->buffer));
          while (G_UNLIKELY (bytes_read == -1 && errno == EINTR));

          if (bytes_read > 0)
            g_checksum_update (data->checksum, (guchar *) data->buffer, bytes_read);
          else
            break;
        }
    }

  g_free (data);

  return ARCHIVE_OK;
}

gboolean
flatpak_archive_read_open_fd_with_checksum (struct archive *a,
                                            int             fd,
                                            GChecksum      *checksum,
                                            GError        **error)
{
  FlatpakArchiveReadWithChecksum *data = g_new0 (FlatpakArchiveReadWithChecksum, 1);

  data->fd = fd;
  data->checksum = checksum;

  if (archive_read_open2 (a, data,
                          checksum_open_cb,
                          checksum_read_cb,
                          checksum_skip_cb,
                          checksum_close_cb) != ARCHIVE_OK)
    return propagate_libarchive_error (error, a);

  return TRUE;
}

enum {
      DELTA_OP_DATA = 0,
      DELTA_OP_OPEN = 1,
      DELTA_OP_COPY = 2,
      DELTA_OP_ADD_DATA = 3,
      DELTA_OP_SEEK = 4,
};

#define DELTA_HEADER "tardf1\n\0"
#define DELTA_HEADER_LEN 8

#define DELTA_BUFFER_SIZE (64*1024)

static gboolean
delta_read_byte (GInputStream   *in,
                 guint8         *out,
                 gboolean       *eof,
                 GCancellable   *cancellable,
                 GError        **error)
{
  gssize res = g_input_stream_read (in, out, 1, cancellable, error);

  if (eof)
    *eof = FALSE;

  if (res < 0)
    return FALSE;

  if (res == 0)
    {
      if (eof)
        *eof = TRUE;
      return flatpak_fail (error, _("Invalid delta file format"));
    }

  return TRUE;
}

static gboolean
delta_read_varuint (GInputStream   *in,
                    guint64        *out,
                    GCancellable   *cancellable,
                    GError        **error)
{
  guint64 res = 0;
  guint32 index = 0;
  gboolean more_data;

  do
    {
      guchar byte;
      guint64 data;

      if (!delta_read_byte (in, &byte, NULL, cancellable, error))
        return FALSE;

      data = byte & 0x7f;
      res |= data << index;
      index += 7;

      more_data = (byte & 0x80) != 0;
    }
  while (more_data);

  *out = res;
  return TRUE;
}

static gboolean
delta_copy_data (GInputStream   *in,
                 GOutputStream  *out,
                 guint64         size,
                 guchar         *buffer,
                 GCancellable   *cancellable,
                 GError        **error)
{
  while (size > 0)
    {
      gssize n_read = g_input_stream_read (in, buffer, MIN(size, DELTA_BUFFER_SIZE), cancellable, error);

      if (n_read == -1)
        return FALSE;

      if (n_read == 0)
        return flatpak_fail (error, _("Invalid delta file format"));

      if (!g_output_stream_write_all (out, buffer, n_read, NULL, cancellable, error))
        return FALSE;

      size -= n_read;
    }

  return TRUE;
}

static gboolean
delta_add_data (GInputStream   *in1,
                GInputStream   *in2,
                GOutputStream  *out,
                guint64         size,
                guchar         *buffer1,
                guchar         *buffer2,
                GCancellable   *cancellable,
                GError        **error)
{
  while (size > 0)
    {
      gssize i;
      gssize n_read = g_input_stream_read (in1, buffer1, MIN(size, DELTA_BUFFER_SIZE), cancellable, error);

      if (n_read == -1)
        return FALSE;
      if (n_read == 0)
        return flatpak_fail (error, _("Invalid delta file format"));

      if (!g_input_stream_read_all (in2, buffer2, n_read, NULL, cancellable, error))
        return FALSE;

      for (i = 0; i < n_read; i++)
        buffer1[i] = ((guint32)buffer1[i] + (guint32)buffer2[i]) & 0xff;

      if (!g_output_stream_write_all (out, buffer1, n_read, NULL, cancellable, error))
        return FALSE;

      size -= n_read;
    }

  return TRUE;
}

static guchar *
delta_read_data (GInputStream   *in,
                 guint64         size,
                 GCancellable   *cancellable,
                 GError        **error)
{
  g_autofree guchar *buf = g_malloc (size+1);

  if (!g_input_stream_read_all (in, buf, size, NULL, cancellable, error))
    return NULL;

  buf[size] = 0;
  return g_steal_pointer (&buf);
}

static char *
delta_clean_path (const char *path)
{
  g_autofree char *abs_path = NULL;
  g_autofree char *canonical_path = NULL;
  const char *rel_canonical_path = NULL;

  /* Canonicallize this as if it was absolute (to avoid ever going out of the top dir) */
  abs_path = g_strconcat ("/", path, NULL);
  canonical_path = flatpak_canonicalize_filename (abs_path);

  /* Then convert back to relative */
  rel_canonical_path = canonical_path;
  while (*rel_canonical_path == '/')
    rel_canonical_path++;
  return g_strdup (rel_canonical_path);
}

static gboolean
delta_ensure_file (GFileInputStream *content_file,
                   GError          **error)
{
  if (content_file == NULL)
    return flatpak_fail (error, _("Invalid delta file format"));
  return TRUE;
}

static GFileInputStream *
copy_stream_to_file (FlatpakOciRegistry    *self,
                     GInputStream          *in,
                     GCancellable          *cancellable,
                     GError               **error)
{
  g_autofree char *tmpfile_name = g_strdup_printf ("oci-delta-source-XXXXXX");
  g_autoptr(GOutputStream) tmp_out_stream = NULL;
  g_autofree char *proc_pid_path = NULL;
  g_autoptr(GFile) proc_pid_file = NULL;
  g_autoptr(GFileInputStream) res = NULL;

  if (!flatpak_open_in_tmpdir_at (self->tmp_dfd, 0600, tmpfile_name,
                                  &tmp_out_stream, cancellable, error))
    return NULL;

  (void) unlinkat (self->tmp_dfd, tmpfile_name, 0);

  proc_pid_path = g_strdup_printf ("/proc/self/fd/%d", g_unix_output_stream_get_fd (G_UNIX_OUTPUT_STREAM (tmp_out_stream)));
  proc_pid_file = g_file_new_for_path (proc_pid_path);
  res = g_file_read (proc_pid_file, cancellable, error);
  if (res == NULL)
    return NULL;

  if (g_output_stream_splice (tmp_out_stream, in,
                              G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET,
                              cancellable, error) < 0)
    return NULL;

  return g_steal_pointer (&res);
}

static gboolean
flatpak_oci_registry_apply_delta_stream (FlatpakOciRegistry    *self,
                                         int                    delta_fd,
                                         GFile                 *content_dir,
                                         GOutputStream         *out,
                                         GCancellable          *cancellable,
                                         GError               **error)
{
  g_autoptr(GInputStream) in_raw = g_unix_input_stream_new (delta_fd, FALSE);
  g_autoptr(GInputStream) in = NULL;
  FlatpakZstdDecompressor *zstd;
  char header[8];
  g_autofree guchar *buffer1 = g_malloc (DELTA_BUFFER_SIZE);
  g_autofree guchar *buffer2 = g_malloc (DELTA_BUFFER_SIZE);
  g_autoptr(GFileInputStream) content_file = NULL;

  if (!g_input_stream_read_all (in_raw, header, sizeof(header), NULL, cancellable, error))
    return FALSE;

  if (memcmp (header, DELTA_HEADER, DELTA_HEADER_LEN) != 0)
    return flatpak_fail (error, _("Invalid delta file format"));

  zstd = flatpak_zstd_decompressor_new ();
  in = g_converter_input_stream_new (in_raw, G_CONVERTER (zstd));
  g_object_unref (zstd);

  while (TRUE)
    {
      guint8 op;
      guint64 size;
      g_autofree char *path = NULL;
      g_autofree char *clean_path = NULL;
      g_autoptr(GError) local_error = NULL;
      gboolean eof;

      if (!delta_read_byte (in, &op, &eof, cancellable, &local_error))
        {
          if (eof)
            break;
          g_propagate_error (error, g_steal_pointer (&local_error));
          return FALSE;
        }

      if (!delta_read_varuint (in, &size, cancellable, error))
        return FALSE;

      switch (op)
        {
        case DELTA_OP_DATA:
          if (!delta_copy_data (in, out, size, buffer1, cancellable, error))
            return FALSE;
          break;

        case DELTA_OP_OPEN:
          path = (char *)delta_read_data (in, size, cancellable, error);
          if (path == NULL)
            return FALSE;
          clean_path = delta_clean_path (path);

          g_clear_object (&content_file);

          {
            g_autoptr(GFile) child = g_file_resolve_relative_path (content_dir, clean_path);
            g_autoptr(GFileInputStream) child_in = NULL;

            child_in = g_file_read (child, cancellable, error);
            if (child_in == NULL)
              return FALSE;

            /* We can't seek in the ostree repo file, so copy it to temp file */
            content_file = copy_stream_to_file (self, G_INPUT_STREAM (child_in), cancellable, error);
            if (content_file == NULL)
              return FALSE;
          }
          break;

        case DELTA_OP_COPY:
          if (!delta_ensure_file (content_file, error))
            return FALSE;
          if (!delta_copy_data (G_INPUT_STREAM (content_file), out, size, buffer1, cancellable, error))
            return FALSE;
          break;

        case DELTA_OP_ADD_DATA:
          if (!delta_ensure_file (content_file, error))
            return FALSE;
          if (!delta_add_data (G_INPUT_STREAM (content_file), in, out, size, buffer1, buffer2, cancellable, error))
            return FALSE;
          break;

        case DELTA_OP_SEEK:
          if (!delta_ensure_file (content_file, error))
            return FALSE;
          if (!g_seekable_seek (G_SEEKABLE (content_file), size, G_SEEK_SET, cancellable, error))
            return FALSE;
          break;

        default:
          return flatpak_fail (error, _("Invalid delta file format"));
        }
    }

  return TRUE;
}

int
flatpak_oci_registry_apply_delta (FlatpakOciRegistry    *self,
                                  int                    delta_fd,
                                  GFile                 *content_dir,
                                  GCancellable          *cancellable,
                                  GError               **error)
{
  g_autoptr(GOutputStream) out = NULL;
  g_autofree char *tmpfile_name = g_strdup_printf ("oci-delta-layer-XXXXXX");
  glnx_autofd int fd = -1;

  if (!flatpak_open_in_tmpdir_at (self->tmp_dfd, 0600, tmpfile_name,
                                  &out, cancellable, error))
    return -1;

  // This is the read-only version we return
  // Note: that we need to open this before we unlink it
  fd = flatpak_open_file_at (self->tmp_dfd, tmpfile_name, NULL, cancellable, error);
  (void) unlinkat (self->tmp_dfd, tmpfile_name, 0);
  if (fd == -1)
    return -1;

  if (!flatpak_oci_registry_apply_delta_stream (self, delta_fd, content_dir, out, cancellable, error))
    return -1;

  return g_steal_fd (&fd);
}

char *
flatpak_oci_registry_apply_delta_to_blob (FlatpakOciRegistry    *self,
                                          int                    delta_fd,
                                          GFile                 *content_dir,
                                          GCancellable          *cancellable,
                                          GError               **error)
{
  g_autofree char *dst_subpath = NULL;
  g_autofree char *checksum = NULL;
  g_autofree char *digest = NULL;
  g_auto(GLnxTmpfile) tmpf = { 0 };
  g_autoptr(GOutputStream) out = NULL;

  if (!glnx_open_tmpfile_linkable_at (self->dfd, "blobs/sha256",
                                      O_RDWR | O_CLOEXEC | O_NOCTTY,
                                      &tmpf, error))
    return NULL;

  out = g_unix_output_stream_new (tmpf.fd, FALSE);

  if (!flatpak_oci_registry_apply_delta_stream (self, delta_fd, content_dir, out, cancellable, error))
    return NULL;

  /* Seek to start to get checksum */
  lseek (tmpf.fd, 0, SEEK_SET);

  checksum = checksum_fd (tmpf.fd, cancellable, error);
  if (checksum == NULL)
    return FALSE;

  digest = g_strconcat ("sha256:", checksum, NULL);

  dst_subpath = get_digest_subpath (self, NULL, FALSE, FALSE, digest, error);
  if (dst_subpath == NULL)
    return FALSE;

  if (!glnx_link_tmpfile_at (&tmpf,
                             GLNX_LINK_TMPFILE_NOREPLACE_IGNORE_EXIST,
                             self->dfd, dst_subpath,
                             error))
    return FALSE;

  return g_steal_pointer (&digest);
}

FlatpakOciManifest *
flatpak_oci_registry_find_delta_manifest (FlatpakOciRegistry    *registry,
                                          const char            *oci_repository,
                                          const char            *for_digest,
                                          const char            *delta_manifest_url,
                                          GCancellable          *cancellable)
{
  g_autoptr(FlatpakOciVersioned) deltaindexv = NULL;
  FlatpakOciDescriptor *delta_desc;

#ifndef HAVE_ZSTD
  if (TRUE)
    return NULL; /* Don't find deltas if we can't apply them */
#endif

  if (delta_manifest_url != NULL)
    {
      g_autoptr(GBytes) bytes = NULL;
      g_autofree char *uri_s = parse_relative_uri (registry->base_uri, delta_manifest_url, NULL);

      if (uri_s != NULL)
        bytes = flatpak_load_uri_full (registry->http_session,
                                       uri_s, registry->certificates, FLATPAK_HTTP_FLAGS_ACCEPT_OCI,
                                       NULL, registry->token,
                                       NULL, NULL, NULL, NULL, NULL,
                                       cancellable, NULL);
      if (bytes != NULL)
        {
          g_autoptr(FlatpakOciVersioned) versioned =
            flatpak_oci_versioned_from_json (bytes, FLATPAK_OCI_MEDIA_TYPE_IMAGE_MANIFEST, NULL);

          if (versioned != NULL && G_TYPE_CHECK_INSTANCE_TYPE (versioned, FLATPAK_TYPE_OCI_MANIFEST))
            {
              g_autoptr(FlatpakOciManifest) delta_manifest = (FlatpakOciManifest *)g_steal_pointer (&versioned);

              /* We resolved using a mutable location (not via digest), so ensure its still valid for this target */
              if (delta_manifest->annotations)
                {
                  const char *target = g_hash_table_lookup (delta_manifest->annotations, "io.github.containers.delta.target");
                  if (g_strcmp0 (target, for_digest) == 0)
                    return g_steal_pointer (&delta_manifest);
                }
            }
        }
    }

  deltaindexv = flatpak_oci_registry_load_versioned (registry, oci_repository, "_deltaindex",
                                                     NULL, NULL, cancellable, NULL);
  if (deltaindexv == NULL)
    return NULL;

  if (!G_TYPE_CHECK_INSTANCE_TYPE (deltaindexv, FLATPAK_TYPE_OCI_INDEX))
    return NULL;

  delta_desc = flatpak_oci_index_find_delta_for ((FlatpakOciIndex *)deltaindexv, for_digest);
  if (delta_desc && delta_desc->digest != NULL)
    {
      const char *delta_manifest_digest = delta_desc->digest;
      g_autoptr(FlatpakOciVersioned) deltamanifest = NULL;

      deltamanifest = flatpak_oci_registry_load_versioned (registry, oci_repository, delta_manifest_digest,
                                                           (const char **)delta_desc->urls, NULL, cancellable, NULL);
      if (deltamanifest != NULL && G_TYPE_CHECK_INSTANCE_TYPE (deltamanifest, FLATPAK_TYPE_OCI_MANIFEST))
        return (FlatpakOciManifest *)g_steal_pointer (&deltamanifest);
    }

  return NULL;
}

static FlatpakOciSignatures *
remote_load_signatures (FlatpakOciRegistry *self,
                        const char         *oci_repository,
                        const char         *digest,
                        GCancellable       *cancellable,
                        GError            **error)
{
  g_autoptr(FlatpakOciSignatures) signatures = flatpak_oci_signatures_new ();
  g_autofree char *digest_algorithm = NULL;
  g_autofree char *digest_value = NULL;
  guint i;
  const char *colon;

  if (self->signature_lookaside == NULL)
    return g_steal_pointer (&signatures);

  /*
   * Look for signatures via the containers/image separate storage protocol:
   *
   * https://github.com/containers/image/blob/main/docs/signature-protocols.md
   */

  colon = strchr (digest, ':');
  if (colon == NULL)
    {
      g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
                   "can't parse digest %s", digest);
      return NULL;
    }

  digest_algorithm = g_strndup (digest, colon - digest);
  digest_value = g_strdup (colon + 1);

  for (i = 1; i < G_MAXUINT; i++)
    {
      g_autoptr(GBytes) bytes = NULL;
      g_autoptr(GError) local_error = NULL;
      g_autofree char *uri_s = NULL;

      uri_s = g_strdup_printf ("%s/%s@%s=%s/signature-%u", self->signature_lookaside,
                               oci_repository, digest_algorithm, digest_value, i);

      bytes = flatpak_load_uri (self->http_session,
                                uri_s, FLATPAK_HTTP_FLAGS_ACCEPT_OCI,
                                NULL,
                                NULL, NULL, NULL,
                                cancellable, &local_error);
      if (bytes == NULL)
        {
          if (g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
            break;
          else
            {
              g_propagate_error (error, g_steal_pointer (&local_error));
              return NULL;
            }
        }

        g_info ("Found OCI signature at %s", uri_s);
        flatpak_oci_signatures_add_signature (signatures, g_steal_pointer (&bytes));
    }

  return g_steal_pointer (&signatures);
}

static FlatpakOciSignatures *
flatpak_oci_registry_load_signatures (FlatpakOciRegistry *self,
                                      const char         *oci_repository,
                                      const char         *digest,
                                      GCancellable       *cancellable,
                                      GError            **error)
{
  if (self->dfd != -1)
    {
      g_autoptr(FlatpakOciSignatures) signatures = flatpak_oci_signatures_new ();

      if (!flatpak_oci_signatures_load_from_dfd (signatures, self->dfd, cancellable, error))
        return NULL;

      return g_steal_pointer (&signatures);
    }
  else
    return remote_load_signatures (self, oci_repository, digest, cancellable, error);
}

static const char *
get_image_metadata (FlatpakOciIndexImage *img, const char *key)
{
  if (img->labels != NULL)
    {
      const char *ref = g_hash_table_lookup (img->labels, key);
      if (ref)
        return ref;
    }
  return NULL;
}

static const char *
get_image_ref (FlatpakOciIndexImage *img)
{
  return get_image_metadata (img, "org.flatpak.ref");
}

typedef struct
{
  char                 *repository;
  FlatpakOciIndexImage *image;
} ImageInfo;

static gint
compare_image_by_ref (ImageInfo *a,
                      ImageInfo *b)
{
  const char *a_ref = get_image_ref (a->image);
  const char *b_ref = get_image_ref (b->image);

  return g_strcmp0 (a_ref, b_ref);
}

gboolean
flatpak_oci_index_ensure_cached (FlatpakHttpSession *http_session,
                                 const char         *uri,
                                 GFile              *index,
                                 char              **index_uri_out,
                                 GCancellable       *cancellable,
                                 GError            **error)
{
  g_autofree char *index_path = g_file_get_path (index);
  g_autoptr(GUri) base_uri = NULL;
  g_autoptr(GUri) query_uri = NULL;
  g_autofree char *query_uri_s = NULL;
  g_autoptr(GString) query = NULL;
  g_autoptr(GString) path = NULL;
  g_autofree char *tag = NULL;
  const char *oci_arch = NULL;
  gboolean success = FALSE;
  g_autoptr(FlatpakCertificates) certificates = NULL;
  g_autoptr(GError) local_error = NULL;
  GUri *tmp_uri;

  if (!g_str_has_prefix (uri, "oci+http:") && !g_str_has_prefix (uri, "oci+https:"))
    {
      g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
                   "OCI Index URI %s does not start with oci+http(s)://", uri);
      return FALSE;
    }

  base_uri = g_uri_parse (uri + 4, FLATPAK_HTTP_URI_FLAGS | G_URI_FLAGS_PARSE_RELAXED, NULL);
  if (base_uri == NULL)
    {
      g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
                   "Cannot parse index url %s", uri);
      return FALSE;
    }

  path = g_string_new (g_uri_get_path (base_uri));

  /* Append /index/static or /static to the path.
   */
  if (!g_str_has_suffix (path->str, "/"))
    g_string_append_c (path, '/');

  if (!g_str_has_suffix (path->str, "/index/"))
    g_string_append (path, "index/");

  g_string_append (path, "static");

  /* Replace path */
  tmp_uri = g_uri_build (g_uri_get_flags (base_uri),
                         g_uri_get_scheme (base_uri),
                         g_uri_get_userinfo (base_uri),
                         g_uri_get_host (base_uri),
                         g_uri_get_port (base_uri),
                         path->str,
                         g_uri_get_query (base_uri),
                         g_uri_get_fragment (base_uri));
  g_uri_unref (base_uri);
  base_uri = tmp_uri;

  /* The fragment of the URI defines a tag to look for; if absent
   * or empty, we use 'latest'
   */
  tag = g_strdup (g_uri_get_fragment (base_uri));
  if (tag == NULL || tag[0] == '\0')
    {
      g_clear_pointer (&tag, g_free);
      tag = g_strdup ("latest");
    }

  /* Remove fragment */
  tmp_uri = g_uri_build (g_uri_get_flags (base_uri),
                         g_uri_get_scheme (base_uri),
                         g_uri_get_userinfo (base_uri),
                         g_uri_get_host (base_uri),
                         g_uri_get_port (base_uri),
                         g_uri_get_path (base_uri),
                         g_uri_get_query (base_uri),
                         NULL);
  g_uri_unref (base_uri);
  base_uri = tmp_uri;

  oci_arch = flatpak_arch_to_oci_arch (flatpak_get_arch ());

  query = g_string_new (NULL);
  flatpak_uri_encode_query_arg (query, "label:org.flatpak.ref:exists", "1");
  flatpak_uri_encode_query_arg (query, "architecture", oci_arch);
  flatpak_uri_encode_query_arg (query, "os", "linux");
  flatpak_uri_encode_query_arg (query, "tag", tag);

  query_uri = g_uri_build (g_uri_get_flags (base_uri) | G_URI_FLAGS_ENCODED_QUERY,
                           g_uri_get_scheme (base_uri),
                           g_uri_get_userinfo (base_uri),
                           g_uri_get_host (base_uri),
                           g_uri_get_port (base_uri),
                           g_uri_get_path (base_uri),
                           query->str,
                           g_uri_get_fragment (base_uri));

  query_uri_s = g_uri_to_string_partial (query_uri, G_URI_HIDE_PASSWORD);

  certificates = flatpak_get_certificates_for_uri (query_uri_s, &local_error);
  if (local_error)
    {
      g_propagate_error (error, g_steal_pointer (&local_error));
      return FALSE;
    }

  success = flatpak_cache_http_uri (http_session,
                                    query_uri_s,
                                    certificates,
                                    FLATPAK_HTTP_FLAGS_STORE_COMPRESSED,
                                    AT_FDCWD, index_path,
                                    NULL, NULL,
                                    cancellable, &local_error);

  if (success ||
      g_error_matches (local_error, FLATPAK_HTTP_ERROR, FLATPAK_HTTP_ERROR_NOT_CHANGED))
    {
      if (index_uri_out)
        *index_uri_out = g_uri_to_string_partial (base_uri, G_URI_HIDE_PASSWORD);
    }
  else
    {
      if (index_uri_out)
        *index_uri_out = NULL;
    }

  if (!success)
    g_propagate_error (error, g_steal_pointer (&local_error));

  return success;
}

static FlatpakOciIndexResponse *
load_oci_index (GFile        *index,
                GCancellable *cancellable,
                GError      **error)
{
  g_autoptr(GFileInputStream) in = NULL;
  g_autoptr(GZlibDecompressor) decompressor = NULL;
  g_autoptr(GInputStream) converter = NULL;
  g_autoptr(GError) local_error = NULL;
  g_autoptr(FlatpakJson) json = NULL;

  in = g_file_read (index, cancellable, error);
  if (in == NULL)
    return FALSE;

  decompressor = g_zlib_decompressor_new (G_ZLIB_COMPRESSOR_FORMAT_GZIP);
  converter = g_converter_input_stream_new (G_INPUT_STREAM (in), G_CONVERTER (decompressor));

  json = flatpak_json_from_stream (G_INPUT_STREAM (converter), FLATPAK_TYPE_OCI_INDEX_RESPONSE,
                                   cancellable, error);
  if (json == NULL)
    return NULL;

  if (!g_input_stream_close (G_INPUT_STREAM (in), cancellable, &local_error))
    g_warning ("Error closing http stream: %s", local_error->message);

  return (FlatpakOciIndexResponse *) g_steal_pointer (&json);
}

static GVariant *
maybe_variant_from_base64 (const char *base64)
{
  guchar *bin;
  gsize bin_len;

  if (base64 == NULL)
    return NULL;

  bin = g_base64_decode (base64, &bin_len);
  return g_variant_ref_sink (g_variant_new_from_data (G_VARIANT_TYPE ("v"),
                                                      bin, bin_len, FALSE,
                                                      g_free, bin));
}

GVariant *
flatpak_oci_index_make_summary (GFile        *index,
                                const char   *index_uri,
                                GCancellable *cancellable,
                                GError      **error)
{
  g_autoptr(FlatpakOciIndexResponse) response = NULL;
  g_autofree char *registry_uri_s = NULL;
  int i;
  g_autoptr(GArray) images = g_array_new (FALSE, TRUE, sizeof (ImageInfo));
  g_autoptr(GVariantBuilder) refs_builder = NULL;
  g_autoptr(GVariantBuilder) additional_metadata_builder = NULL;
  g_autoptr(GVariantBuilder) ref_sparse_data_builder = NULL;
  g_autoptr(GVariantBuilder) summary_builder = NULL;
  g_autoptr(GVariant) summary = NULL;
  g_autoptr(GVariantBuilder) ref_data_builder = NULL;
  g_autoptr(GUri) uri = NULL;

  response = load_oci_index (index, cancellable, error);
  if (!response)
    return NULL;

  uri = g_uri_parse (index_uri, FLATPAK_HTTP_URI_FLAGS | G_URI_FLAGS_PARSE_RELAXED, NULL);
  registry_uri_s = parse_relative_uri (uri, response->registry, error);
  if (registry_uri_s == NULL)
    return NULL;

  for (i = 0; response->results != NULL && response->results[i] != NULL; i++)
    {
      FlatpakOciIndexRepository *r = response->results[i];
      int j;
      ImageInfo info = { r->name };

      for (j = 0; r->images != NULL && r->images[j] != NULL; j++)
        {
          info.image = r->images[j];
          g_array_append_val (images, info);
        }

      for (j = 0; r->lists != NULL && r->lists[j] != NULL; j++)
        {
          FlatpakOciIndexImageList *list =  r->lists[j];
          int k;

          for (k = 0; list->images != NULL && list->images[k] != NULL; k++)
            {
              info.image = list->images[k];
              g_array_append_val (images, info);
            }
        }
    }

  refs_builder = g_variant_builder_new (G_VARIANT_TYPE ("a(s(taya{sv}))"));
  ref_data_builder = g_variant_builder_new (G_VARIANT_TYPE ("a{s(tts)}"));
  additional_metadata_builder = g_variant_builder_new (G_VARIANT_TYPE ("a{sv}"));
  ref_sparse_data_builder = g_variant_builder_new (G_VARIANT_TYPE ("a{sa{sv}}"));

  /* The summary has to be sorted by ref */
  g_array_sort (images, (GCompareFunc) compare_image_by_ref);

  for (i = 0; i < images->len; i++)
    {
      ImageInfo *info = &g_array_index (images, ImageInfo, i);
      FlatpakOciIndexImage *image = info->image;
      const char *ref = get_image_ref (image);
      const char *fake_commit;
      guint64 installed_size = 0;
      guint64 download_size = 0;
      const char *delta_url;
      const char *installed_size_str;
      const char *download_size_str;
      const char *token_type_base64;
      const char *endoflife_base64;
      const char *endoflife_rebase_base64 = NULL;
      const char *metadata_contents = NULL;
      g_autoptr(GVariantBuilder) ref_metadata_builder = NULL;
      g_autoptr(GVariant) token_type_v = NULL;
      g_autoptr(GVariant) endoflife_v = NULL;
      g_autoptr(GVariant) endoflife_rebase_v = NULL;

      if (ref == NULL)
        continue;

      metadata_contents = get_image_metadata (image, "org.flatpak.metadata");
      if (metadata_contents == NULL && !g_str_has_prefix (ref, "appstream/"))
        continue; /* Not a flatpak, skip */

      if (!g_str_has_prefix (image->digest, "sha256:"))
        {
          g_info ("Ignoring digest type %s", image->digest);
          continue;
        }

      fake_commit = image->digest + strlen ("sha256:");

      installed_size_str = get_image_metadata (image, "org.flatpak.installed-size");
      if (installed_size_str)
        installed_size = g_ascii_strtoull (installed_size_str, NULL, 10);

      download_size_str = get_image_metadata (image, "org.flatpak.download-size");
      if (download_size_str)
        download_size = g_ascii_strtoull (download_size_str, NULL, 10);

      ref_metadata_builder = g_variant_builder_new (G_VARIANT_TYPE ("a{sv}"));

      g_variant_builder_add (ref_metadata_builder, "{sv}", "xa.oci-repository",
                             g_variant_new_string (info->repository));

      delta_url = get_image_metadata (image, "io.github.containers.DeltaUrl");
      if (delta_url)
        g_variant_builder_add (ref_metadata_builder, "{sv}", "xa.delta-url",
                               g_variant_new_string (delta_url));

      g_variant_builder_add_value (refs_builder,
                                   g_variant_new ("(s(t@ay@a{sv}))", ref,
                                                  (guint64) 0,
                                                  ostree_checksum_to_bytes_v (fake_commit),
                                                  g_variant_builder_end (ref_metadata_builder)));
      g_variant_builder_add (ref_data_builder, "{s(tts)}",
                             ref,
                             GUINT64_TO_BE (installed_size),
                             GUINT64_TO_BE (download_size),
                             metadata_contents ? metadata_contents : "");

      token_type_base64 = get_image_metadata (image, "org.flatpak.commit-metadata.xa.token-type");
      token_type_v = maybe_variant_from_base64 (token_type_base64);
      endoflife_base64 = get_image_metadata (image, "org.flatpak.commit-metadata.ostree.endoflife");
      endoflife_v = maybe_variant_from_base64 (endoflife_base64);
      endoflife_rebase_base64 = get_image_metadata (image, "org.flatpak.commit-metadata.ostree.endoflife-rebase");
      endoflife_rebase_v = maybe_variant_from_base64 (endoflife_rebase_base64);

      if (token_type_v != NULL ||
          endoflife_v != NULL ||
          endoflife_rebase_v != NULL)
        {
          g_autoptr(GVariantBuilder) sparse_builder = g_variant_builder_new (G_VARIANT_TYPE ("a{sv}"));

          if (token_type_v != NULL)
            g_variant_builder_add (sparse_builder, "{s@v}", FLATPAK_SPARSE_CACHE_KEY_TOKEN_TYPE, token_type_v);
          if (endoflife_v != NULL)
            g_variant_builder_add (sparse_builder, "{s@v}", FLATPAK_SPARSE_CACHE_KEY_ENDOFLIFE, endoflife_v);
          if (endoflife_rebase_v != NULL)
            g_variant_builder_add (sparse_builder, "{s@v}", FLATPAK_SPARSE_CACHE_KEY_ENDOFLIFE_REBASE, endoflife_rebase_v);

          g_variant_builder_add (ref_sparse_data_builder, "{s@a{sv}}",
                                 ref, g_variant_builder_end (sparse_builder));
        }
    }

  g_variant_builder_add (additional_metadata_builder, "{sv}", "xa.cache",
                         g_variant_new_variant (g_variant_builder_end (ref_data_builder)));
  g_variant_builder_add (additional_metadata_builder, "{sv}", "xa.sparse-cache",
                         g_variant_builder_end (ref_sparse_data_builder));
  g_variant_builder_add (additional_metadata_builder, "{sv}", "xa.oci-registry-uri",
                         g_variant_new_string (registry_uri_s));

  summary_builder = g_variant_builder_new (OSTREE_SUMMARY_GVARIANT_FORMAT);

  g_variant_builder_add_value (summary_builder, g_variant_builder_end (refs_builder));
  g_variant_builder_add_value (summary_builder, g_variant_builder_end (additional_metadata_builder));

  summary = g_variant_ref_sink (g_variant_builder_end (summary_builder));

  return g_steal_pointer (&summary);
}

static gboolean
add_icon_image (FlatpakHttpSession  *http_session,
                const char          *index_uri,
                FlatpakCertificates *certificates,
                int                  icons_dfd,
                GHashTable          *used_icons,
                const char          *subdir,
                const char          *id,
                const char          *icon_data,
                GCancellable        *cancellable,
                GError             **error)
{
  g_autofree char *icon_name = g_strconcat (id, ".png", NULL);
  g_autofree char *icon_path = g_build_filename (subdir, icon_name, NULL);

  /* Create the destination directory */

  if (!glnx_shutil_mkdir_p_at (icons_dfd, subdir, 0755, cancellable, error))
    return FALSE;

  if (g_str_has_prefix (icon_data, "data:"))
    {
      if (g_str_has_prefix (icon_data, "data:image/png;base64,"))
        {
          const char *base64_data = icon_data + strlen ("data:image/png;base64,");
          gsize decoded_size;
          g_autofree guint8 *decoded = g_base64_decode (base64_data, &decoded_size);

          if (!glnx_file_replace_contents_at (icons_dfd, icon_path,
                                              decoded, decoded_size,
                                              0 /* flags */, cancellable, error))
            return FALSE;

          g_hash_table_replace (used_icons, g_steal_pointer (&icon_path), GUINT_TO_POINTER (1));

          return TRUE;
        }
      else
        {
          g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
                       "Data URI for icon has an unsupported type");
          return FALSE;
        }
    }
  else
    {
      g_autoptr(GUri) base_uri = g_uri_parse (index_uri, FLATPAK_HTTP_URI_FLAGS | G_URI_FLAGS_PARSE_RELAXED, NULL);
      g_autofree char *icon_uri_s = NULL;
      g_autoptr(GError) local_error = NULL;

      icon_uri_s = parse_relative_uri (base_uri, icon_data, error);
      if (icon_uri_s == NULL)
        return FALSE;

      if (!flatpak_cache_http_uri (http_session, icon_uri_s, certificates,
                                   0 /* flags */,
                                   icons_dfd, icon_path,
                                   NULL, NULL,
                                   cancellable, &local_error) &&
          !g_error_matches (local_error, FLATPAK_HTTP_ERROR, FLATPAK_HTTP_ERROR_NOT_CHANGED))
        {
          g_propagate_error (error, g_steal_pointer (&local_error));
          return FALSE;
        }

      g_hash_table_replace (used_icons, g_steal_pointer (&icon_path), GUINT_TO_POINTER (1));

      return TRUE;
    }
}

static void
add_image_to_appstream (FlatpakHttpSession        *http_session,
                        const char                *index_uri,
                        FlatpakCertificates       *certificates,
                        FlatpakXml                *appstream_root,
                        int                        icons_dfd,
                        GHashTable                *used_icons,
                        FlatpakOciIndexRepository *repository,
                        FlatpakOciIndexImage      *image,
                        GCancellable              *cancellable)
{
  g_autoptr(GInputStream) in = NULL;
  g_autoptr(GError) error = NULL;
  g_autoptr(FlatpakXml) xml_root = NULL;
  g_auto(GStrv) ref_parts = NULL;
  const char *ref;
  const char *id = NULL;
  FlatpakXml *source_components;
  FlatpakXml *dest_components;
  FlatpakXml *component;
  FlatpakXml *prev_component;
  const char *appdata;
  int i;

  static struct
  {
    const char *label;
    const char *subdir;
  } icon_sizes[] = {
    { "org.freedesktop.appstream.icon-64", "64x64" },
    { "org.freedesktop.appstream.icon-128", "128x128" },
  };

  ref = get_image_ref (image);
  if (!ref)
    return;

  ref_parts = g_strsplit (ref, "/", -1);
  if (g_strv_length (ref_parts) != 4 ||
      (strcmp (ref_parts[0], "app") != 0 && strcmp (ref_parts[0], "runtime") != 0))
    return;

  id = ref_parts[1];

  appdata = get_image_metadata (image, "org.freedesktop.appstream.appdata");
  if (!appdata)
    return;

  in = g_memory_input_stream_new_from_data (appdata, -1, NULL);

  xml_root = flatpak_xml_parse (in, FALSE, cancellable, &error);
  if (xml_root == NULL)
    {
      g_print ("%s: Failed to parse appdata annotation: %s\n",
               repository->name,
               error->message);
      return;
    }

  if (xml_root->first_child == NULL ||
      xml_root->first_child->next_sibling != NULL ||
      g_strcmp0 (xml_root->first_child->element_name, "components") != 0)
    {
      return;
    }

  source_components = xml_root->first_child;
  dest_components = appstream_root->first_child;

  component = source_components->first_child;
  prev_component = NULL;
  while (component != NULL)
    {
      FlatpakXml *next = component->next_sibling;

      if (g_strcmp0 (component->element_name, "component") == 0)
        {
          flatpak_xml_add (dest_components,
                           flatpak_xml_unlink (component, prev_component));
        }
      else
        {
          prev_component = component;
        }

      component = next;
    }

  for (i = 0; i < G_N_ELEMENTS (icon_sizes); i++)
    {
      const char *icon_data = get_image_metadata (image, icon_sizes[i].label);
      if (icon_data)
        {
          if (!add_icon_image (http_session,
                               index_uri,
                               certificates,
                               icons_dfd,
                               used_icons,
                               icon_sizes[i].subdir, id, icon_data,
                               cancellable, &error))
            {
              g_print ("%s: Failed to add %s icon: %s\n",
                       repository->name,
                       icon_sizes[i].subdir,
                       error->message);
              g_clear_error (&error);
            }
        }
    }
}

static gboolean
clean_unused_icons_recurse (int           icons_dfd,
                            const char   *dirpath,
                            GHashTable   *used_icons,
                            gboolean     *any_found_parent,
                            GCancellable *cancellable,
                            GError      **error)
{
  g_auto(GLnxDirFdIterator) iter = { 0, };
  gboolean any_found = FALSE;

  if (!glnx_dirfd_iterator_init_at (icons_dfd,
                                    dirpath ? dirpath : ".",
                                    FALSE, &iter, error))
    return FALSE;

  while (TRUE)
    {
      struct dirent *out_dent;
      g_autofree char *subpath = NULL;

      if (!glnx_dirfd_iterator_next_dent (&iter, &out_dent, cancellable, error))
        return FALSE;

      if (out_dent == NULL)
        break;

      if (dirpath)
        subpath = g_build_filename (dirpath, out_dent->d_name, NULL);
      else
        subpath = g_strdup (out_dent->d_name);

      if (out_dent->d_type == DT_DIR)
        clean_unused_icons_recurse (icons_dfd, subpath, used_icons, &any_found, cancellable, error);
      else if (g_hash_table_lookup (used_icons, subpath) == NULL)
        {
          if (!glnx_unlinkat (icons_dfd, subpath, 0, error))
            return FALSE;
        }
      else
        any_found = TRUE;
    }

  if (any_found)
    {
      if (any_found_parent)
        *any_found_parent = TRUE;
    }
  else
    {
      if (dirpath) /* Don't remove the toplevel icons/ directory */
        if (!glnx_unlinkat (icons_dfd, dirpath, AT_REMOVEDIR, error))
          return FALSE;
    }

  return TRUE;
}

static gboolean
clean_unused_icons (int           icons_dfd,
                    GHashTable   *used_icons,
                    GCancellable *cancellable,
                    GError      **error)
{
  return clean_unused_icons_recurse (icons_dfd, NULL, used_icons, NULL, cancellable, error);
}

GBytes *
flatpak_oci_index_make_appstream (FlatpakHttpSession *http_session,
                                  GFile              *index,
                                  const char         *index_uri,
                                  const char         *arch,
                                  int                 icons_dfd,
                                  GCancellable       *cancellable,
                                  GError            **error)
{
  g_autoptr(FlatpakOciIndexResponse) response = NULL;
  g_autoptr(FlatpakXml) appstream_root = NULL;
  g_autoptr(GBytes) bytes = NULL;
  g_autoptr(GHashTable) used_icons = NULL;
  g_autoptr(FlatpakCertificates) certificates = NULL;
  g_autoptr(GError) local_error = NULL;
  int i;

  const char *oci_arch = flatpak_arch_to_oci_arch (arch);

  response = load_oci_index (index, cancellable, error);
  if (!response)
    return NULL;

  used_icons = g_hash_table_new_full (g_str_hash, g_str_equal,
                                      g_free, NULL);

  appstream_root = flatpak_appstream_xml_new ();

  certificates = flatpak_get_certificates_for_uri (index_uri, &local_error);
  if (local_error)
    {
      g_print ("Failed to load certificates for %s: %s",
               index_uri, local_error->message);
      g_clear_error (&local_error);
    }

  for (i = 0; response->results != NULL && response->results[i] != NULL; i++)
    {
      FlatpakOciIndexRepository *r = response->results[i];
      int j;

      for (j = 0; r->images != NULL && r->images[j] != NULL; j++)
        {
          FlatpakOciIndexImage *image = r->images[j];
          if (g_strcmp0 (image->architecture, oci_arch) == 0)
            add_image_to_appstream (http_session,
                                    index_uri, certificates,
                                    appstream_root, icons_dfd, used_icons,
                                    r, image,
                                    cancellable);
        }

      for (j = 0; r->lists != NULL && r->lists[j] != NULL; j++)
        {
          FlatpakOciIndexImageList *list =  r->lists[j];
          int k;

          for (k = 0; list->images != NULL && list->images[k] != NULL; k++)
            {
              FlatpakOciIndexImage *image = list->images[k];
              if (g_strcmp0 (image->architecture, oci_arch) == 0)
                add_image_to_appstream (http_session,
                                        index_uri, certificates,
                                        appstream_root, icons_dfd, used_icons,
                                        r, image,
                                        cancellable);
            }
        }
    }

  if (g_cancellable_set_error_if_cancelled (cancellable, error))
    return NULL;

  if (!flatpak_appstream_xml_root_to_data (appstream_root,
                                           &bytes, NULL, error))
    return NULL;

  if (!clean_unused_icons (icons_dfd, used_icons, cancellable, error))
    return FALSE;

  return g_steal_pointer (&bytes);
}

typedef struct
{
  FlatpakOciPullProgress progress_cb;
  gpointer               progress_user_data;
  guint64                total_size;
  guint64                previous_layers_size;
  guint32                n_layers;
  guint32                pulled_layers;
} FlatpakOciPullProgressData;

static void
oci_layer_progress (guint64  downloaded_bytes,
                    gpointer user_data)
{
  FlatpakOciPullProgressData *progress_data = user_data;

  if (progress_data->progress_cb)
    progress_data->progress_cb (progress_data->total_size, progress_data->previous_layers_size + downloaded_bytes,
                                progress_data->n_layers, progress_data->pulled_layers,
                                progress_data->progress_user_data);
}

gboolean
flatpak_mirror_image_from_oci (FlatpakOciRegistry    *dst_registry,
                               FlatpakImageSource    *image_source,
                               const char            *remote,
                               const char            *ref,
                               OstreeRepo            *repo,
                               FlatpakOciPullProgress progress_cb,
                               gpointer               progress_user_data,
                               GCancellable          *cancellable,
                               GError               **error)
{
  FlatpakOciPullProgressData progress_data = { progress_cb, progress_user_data };
  FlatpakOciRegistry *registry = flatpak_image_source_get_registry (image_source);
  const char *oci_repository = flatpak_image_source_get_oci_repository (image_source);
  const char *digest = flatpak_image_source_get_digest (image_source);
  FlatpakOciManifest *manifest = flatpak_image_source_get_manifest (image_source);
  const char *delta_url = flatpak_image_source_get_delta_url (image_source);
  FlatpakOciImage *image_config = flatpak_image_source_get_image_config (image_source);
  g_autoptr(FlatpakOciDescriptor) manifest_desc = NULL;
  g_autoptr(FlatpakOciManifest) delta_manifest = NULL;
  g_autofree char *old_checksum = NULL;
  g_autoptr(GVariant) old_commit = NULL;
  g_autoptr(GFile) old_root = NULL;
  OstreeRepoCommitState old_state = 0;
  g_autofree char *old_diffid = NULL;
  g_autoptr(FlatpakOciIndex) index = NULL;
  g_autoptr(FlatpakOciSignatures) signatures = NULL;
  int n_layers;
  int i;

  if (!flatpak_oci_registry_mirror_blob (dst_registry, registry, oci_repository, TRUE, digest, NULL, NULL, NULL, cancellable, error))
    return FALSE;

  if (!flatpak_oci_registry_mirror_blob (dst_registry, registry, oci_repository, FALSE, manifest->config.digest, (const char **)manifest->config.urls, NULL, NULL, cancellable, error))
    return FALSE;

  /* For deltas we ensure that the diffid and regular layers exists and match up */
  n_layers = flatpak_oci_manifest_get_n_layers (manifest);
  if (n_layers == 0 || n_layers != flatpak_oci_image_get_n_layers (image_config))
    return flatpak_fail (error, _("Invalid OCI image config"));

  /* Look for delta manifest, and if it exists, the current (old) commit and its recorded diffid */
  if (flatpak_repo_resolve_rev (repo, NULL, remote, ref, FALSE, &old_checksum, NULL, NULL) &&
      ostree_repo_load_commit (repo, old_checksum, &old_commit, &old_state, NULL) &&
      (old_state == OSTREE_REPO_COMMIT_STATE_NORMAL) &&
      ostree_repo_read_commit (repo, old_checksum, &old_root, NULL, NULL, NULL))
    {
      delta_manifest = flatpak_oci_registry_find_delta_manifest (registry, oci_repository, digest, delta_url, cancellable);
      if (delta_manifest)
        {
          VarMetadataRef commit_metadata = var_commit_get_metadata (var_commit_from_gvariant (old_commit));
          const char *raw_old_diffid = var_metadata_lookup_string (commit_metadata, "xa.diff-id", NULL);
          if (raw_old_diffid != NULL)
            old_diffid = g_strconcat ("sha256:", raw_old_diffid, NULL);
        }
    }

  for (i = 0; manifest->layers[i] != NULL; i++)
    {
      FlatpakOciDescriptor *layer = manifest->layers[i];
      FlatpakOciDescriptor *delta_layer = NULL;

      if (delta_manifest)
        delta_layer = flatpak_oci_manifest_find_delta_for (delta_manifest, old_diffid, image_config->rootfs.diff_ids[i]);

      if (delta_layer)
        progress_data.total_size += delta_layer->size;
      else
        progress_data.total_size += layer->size;
      progress_data.n_layers++;
    }

  if (progress_cb)
    progress_cb (progress_data.total_size, 0,
                 progress_data.n_layers, progress_data.pulled_layers,
                 progress_user_data);

  for (i = 0; manifest->layers[i] != NULL; i++)
    {
      FlatpakOciDescriptor *layer = manifest->layers[i];
      FlatpakOciDescriptor *delta_layer = NULL;

      if (delta_manifest)
        delta_layer = flatpak_oci_manifest_find_delta_for (delta_manifest, old_diffid, image_config->rootfs.diff_ids[i]);

      if (delta_layer)
        {
          g_info ("Using OCI delta %s for layer %s", delta_layer->digest, layer->digest);
          g_autofree char *delta_digest = NULL;
          glnx_autofd int delta_fd = flatpak_oci_registry_download_blob (registry, oci_repository, FALSE,
                                                                         delta_layer->digest, (const char **)delta_layer->urls,
                                                                         oci_layer_progress, &progress_data,
                                                                         cancellable, error);
          if (delta_fd == -1)
            return FALSE;

          delta_digest = flatpak_oci_registry_apply_delta_to_blob (dst_registry, delta_fd, old_root, cancellable, error);
          if (delta_digest == NULL)
            return FALSE;

          if (g_strcmp0 (delta_digest, image_config->rootfs.diff_ids[i]) != 0)
            return flatpak_fail_error (error, FLATPAK_ERROR_INVALID_DATA, _("Wrong layer checksum, expected %s, was %s"), image_config->rootfs.diff_ids[i], delta_digest);
        }
      else
        {
          if (!flatpak_oci_registry_mirror_blob (dst_registry, registry, oci_repository, FALSE, layer->digest, (const char **)layer->urls,
                                                 oci_layer_progress, &progress_data,
                                                 cancellable, error))
            return FALSE;
        }

      progress_data.pulled_layers++;
      progress_data.previous_layers_size += delta_layer ? delta_layer->size : layer->size;
    }

  index = flatpak_oci_registry_load_index (dst_registry, NULL, NULL);
  if (index == NULL)
    index = flatpak_oci_index_new ();

  manifest_desc = flatpak_oci_descriptor_new (manifest->parent.mediatype, digest,
                                              flatpak_image_source_get_manifest_size (image_source));

  flatpak_oci_index_add_manifest (index, ref, manifest_desc);

  if (!flatpak_oci_registry_save_index (dst_registry, index, cancellable, error))
    return FALSE;

  signatures = flatpak_oci_registry_load_signatures (registry, oci_repository, digest,
                                                     cancellable, error);
  if (!signatures)
    return FALSE;

  if (!flatpak_oci_signatures_save_to_dfd (signatures, dst_registry->dfd, cancellable, error))
    return FALSE;

  return TRUE;
}

char *
flatpak_pull_from_oci (OstreeRepo            *repo,
                       FlatpakImageSource    *image_source,
                       FlatpakImageSource    *opt_dst_image_source,
                       const char            *remote,
                       const char            *ref,
                       FlatpakPullFlags       flags,
                       FlatpakOciPullProgress progress_cb,
                       gpointer               progress_user_data,
                       GCancellable          *cancellable,
                       GError               **error)
{
  FlatpakOciRegistry *registry = flatpak_image_source_get_registry (image_source);
  const char *oci_repository = flatpak_image_source_get_oci_repository (image_source);
  const char *digest = flatpak_image_source_get_digest (image_source);
  FlatpakOciManifest *manifest = flatpak_image_source_get_manifest (image_source);
  const char *delta_url = flatpak_image_source_get_delta_url (image_source);
  FlatpakOciImage *image_config = flatpak_image_source_get_image_config (image_source);
  gboolean force_disable_deltas = (flags & FLATPAK_PULL_FLAGS_NO_STATIC_DELTAS) != 0;
  g_autoptr(OstreeMutableTree) archive_mtree = NULL;
  g_autoptr(GFile) archive_root = NULL;
  g_autoptr(FlatpakOciManifest) delta_manifest = NULL;
  g_autofree char *old_checksum = NULL;
  g_autoptr(GVariant) old_commit = NULL;
  g_autoptr(GFile) old_root = NULL;
  OstreeRepoCommitState old_state = 0;
  g_autofree char *old_diffid = NULL;
  g_autofree char *commit_checksum = NULL;
  const char *parent = NULL;
  const char *manifest_ref = NULL;
  g_autofree char *full_ref = NULL;
  const char *diffid;
  FlatpakOciPullProgressData progress_data = { progress_cb, progress_user_data };
  g_autoptr(GVariantBuilder) metadata_builder = g_variant_builder_new (G_VARIANT_TYPE ("a{sv}"));
  g_autoptr(GVariant) metadata = NULL;
  g_autoptr(FlatpakOciSignatures) signatures = NULL;
  FlatpakOciRegistry *dst_registry = opt_dst_image_source ?
    flatpak_image_source_get_registry (opt_dst_image_source) : registry;
  const char *dest_oci_repository = opt_dst_image_source ?
    flatpak_image_source_get_oci_repository (opt_dst_image_source) : oci_repository;
  int n_layers;
  int i;

  g_assert (g_str_has_prefix (digest, "sha256:"));

  signatures = flatpak_oci_registry_load_signatures (dst_registry,
                                                     dest_oci_repository,
                                                     digest,
                                                     cancellable, error);
  if (!signatures)
    return FALSE;

  if (!flatpak_oci_signatures_verify (signatures, repo, remote,
                                      dst_registry->uri,
                                      dest_oci_repository,
                                      digest,
                                      error))
    return FALSE;

  manifest_ref = flatpak_image_source_get_ref (image_source);
  if (manifest_ref == NULL)
    {
      flatpak_fail_error (error, FLATPAK_ERROR_INVALID_DATA, _("No ref specified for OCI image %s"), digest);
      return NULL;
    }

  if (ref == NULL)
    {
      ref = manifest_ref;
    }
  else if (g_strcmp0 (manifest_ref, ref) != 0)
    {
      flatpak_fail_error (error, FLATPAK_ERROR_INVALID_DATA, _("Wrong ref (%s) specified for OCI image %s, expected %s"), manifest_ref, digest, ref);
      return NULL;
    }

  flatpak_image_source_build_commit_metadata (image_source, metadata_builder);

  g_variant_builder_add (metadata_builder, "{s@v}", "xa.alt-id",
                         g_variant_new_variant (g_variant_new_string (digest + strlen ("sha256:"))));

  /* For deltas we ensure that the diffid and regular layers exists and match up */
  n_layers = flatpak_oci_manifest_get_n_layers (manifest);
  if (n_layers == 0 || n_layers != flatpak_oci_image_get_n_layers (image_config))
    {
      flatpak_fail (error, _("Invalid OCI image config"));
      return NULL;
    }

  /* Assuming everything looks good, we record the uncompressed checksum (the diff-id) of the last layer,
     because that is what we can read back easily from the deploy dir, and thus is easy to use for applying deltas */
  diffid = image_config->rootfs.diff_ids[n_layers-1];
  if (diffid != NULL && g_str_has_prefix (diffid, "sha256:"))
    g_variant_builder_add (metadata_builder, "{s@v}", "xa.diff-id",
                           g_variant_new_variant (g_variant_new_string (diffid + strlen ("sha256:"))));

  /* Look for delta manifest, and if it exists, the current (old) commit and its recorded diffid */
  if (!force_disable_deltas &&
      !flatpak_oci_registry_is_local (registry) &&
      flatpak_repo_resolve_rev (repo, NULL, remote, ref, FALSE, &old_checksum, NULL, NULL) &&
      ostree_repo_load_commit (repo, old_checksum, &old_commit, &old_state, NULL) &&
      (old_state == OSTREE_REPO_COMMIT_STATE_NORMAL) &&
      ostree_repo_read_commit (repo, old_checksum, &old_root, NULL, NULL, NULL))
    {
      delta_manifest = flatpak_oci_registry_find_delta_manifest (registry, oci_repository, digest, delta_url, cancellable);
      if (delta_manifest)
        {
          VarMetadataRef commit_metadata = var_commit_get_metadata (var_commit_from_gvariant (old_commit));
          const char *raw_old_diffid = var_metadata_lookup_string (commit_metadata, "xa.diff-id", NULL);
          if (raw_old_diffid != NULL)
            old_diffid = g_strconcat ("sha256:", raw_old_diffid, NULL);
        }
    }

  if (!ostree_repo_prepare_transaction (repo, NULL, cancellable, error))
    return NULL;

  /* There is no way to write a subset of the archive to a mtree, so instead
     we write all of it and then build a new mtree with the subset */
  archive_mtree = ostree_mutable_tree_new ();

  for (i = 0; manifest->layers[i] != NULL; i++)
    {
      FlatpakOciDescriptor *layer = manifest->layers[i];
      FlatpakOciDescriptor *delta_layer = NULL;

      if (delta_manifest)
        delta_layer = flatpak_oci_manifest_find_delta_for (delta_manifest, old_diffid, image_config->rootfs.diff_ids[i]);

      if (delta_layer)
        progress_data.total_size += delta_layer->size;
      else
        progress_data.total_size += layer->size;

      progress_data.n_layers++;
    }

  if (progress_cb)
    progress_cb (progress_data.total_size, 0,
                 progress_data.n_layers, progress_data.pulled_layers,
                 progress_user_data);

  for (i = 0; manifest->layers[i] != NULL; i++)
    {
      FlatpakOciDescriptor *layer = manifest->layers[i];
      FlatpakOciDescriptor *delta_layer = NULL;
      OstreeRepoImportArchiveOptions opts = { 0, };
      g_autoptr(FlatpakAutoArchiveRead) a = NULL;
      glnx_autofd int layer_fd = -1;
      glnx_autofd int blob_fd = -1;
      g_autoptr(GChecksum) checksum = g_checksum_new (G_CHECKSUM_SHA256);
      g_autoptr(GError) local_error = NULL;
      const char *layer_checksum;
      const char *expected_digest;

      if (delta_manifest)
        delta_layer = flatpak_oci_manifest_find_delta_for (delta_manifest, old_diffid, image_config->rootfs.diff_ids[i]);

      opts.autocreate_parents = TRUE;
      opts.ignore_unsupported_content = TRUE;

      if (delta_layer)
        {
          g_info ("Using OCI delta %s for layer %s", delta_layer->digest, layer->digest);
          expected_digest = image_config->rootfs.diff_ids[i]; /* The delta recreates the uncompressed tar so use that digest */
        }
      else
        {
          layer_fd = g_steal_fd (&blob_fd);
          expected_digest = layer->digest;
        }

      blob_fd = flatpak_oci_registry_download_blob (registry, oci_repository, FALSE,
                                                    delta_layer ? delta_layer->digest : layer->digest,
                                                    (const char **)(delta_layer ? delta_layer->urls : layer->urls),
                                                    oci_layer_progress, &progress_data,
                                                    cancellable, &local_error);

      if (blob_fd == -1 && delta_layer == NULL &&
          flatpak_oci_registry_is_local (registry) &&
          g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
        {
          /* Pulling regular layer from local repo and its not there, try the uncompressed version.
           * This happens when we deploy via system helper using oci deltas */
          expected_digest = image_config->rootfs.diff_ids[i];
          blob_fd = flatpak_oci_registry_download_blob (registry, oci_repository, FALSE,
                                                        image_config->rootfs.diff_ids[i], NULL,
                                                        oci_layer_progress, &progress_data,
                                                        cancellable, NULL); /* No error here, we report the first error if this fails */
        }

      if (blob_fd == -1)
        {
          g_propagate_error (error, g_steal_pointer (&local_error));
          goto error;
        }

      g_clear_error (&local_error);

      if (delta_layer)
        {
          layer_fd = flatpak_oci_registry_apply_delta (registry, blob_fd, old_root, cancellable, error);
          if (layer_fd == -1)
            goto error;
        }
      else
        {
          layer_fd = g_steal_fd (&blob_fd);
        }

      a = archive_read_new ();
#ifdef HAVE_ARCHIVE_READ_SUPPORT_FILTER_ALL
      archive_read_support_filter_all (a);
#else
      archive_read_support_compression_all (a);
#endif
      archive_read_support_format_all (a);

      if (!flatpak_archive_read_open_fd_with_checksum (a, layer_fd, checksum, error))
        goto error;

      if (!ostree_repo_import_archive_to_mtree (repo, &opts, a, archive_mtree, NULL, cancellable, error))
        goto error;

      if (archive_read_close (a) != ARCHIVE_OK)
        {
          propagate_libarchive_error (error, a);
          goto error;
        }

      layer_checksum = g_checksum_get_string (checksum);
      if (!g_str_has_prefix (expected_digest, "sha256:") ||
          strcmp (expected_digest + strlen ("sha256:"), layer_checksum) != 0)
        {
          flatpak_fail_error (error, FLATPAK_ERROR_INVALID_DATA, _("Wrong layer checksum, expected %s, was %s"), expected_digest, layer_checksum);
          goto error;
        }

      progress_data.pulled_layers++;
      progress_data.previous_layers_size += delta_layer ? delta_layer->size : layer->size;
    }

  if (!ostree_repo_write_mtree (repo, archive_mtree, &archive_root, cancellable, error))
    goto error;

  if (!ostree_repo_file_ensure_resolved ((OstreeRepoFile *) archive_root, error))
    goto error;

  metadata = g_variant_ref_sink (g_variant_builder_end (metadata_builder));
  if (!ostree_repo_write_commit_with_time (repo,
                                           parent,
                                           flatpak_image_source_get_commit_subject (image_source),
                                           flatpak_image_source_get_commit_body (image_source),
                                           metadata,
                                           OSTREE_REPO_FILE (archive_root),
                                           flatpak_image_source_get_commit_timestamp (image_source),
                                           &commit_checksum,
                                           cancellable, error))
    goto error;

  if (remote)
    full_ref = g_strdup_printf ("%s:%s", remote, ref);
  else
    full_ref = g_strdup (ref);

  /* Don’t need to set the collection ID here, since the ref is bound to a
   * collection via its remote. */
  ostree_repo_transaction_set_ref (repo, NULL, full_ref, commit_checksum);

  if (!ostree_repo_commit_transaction (repo, NULL, cancellable, error))
    return NULL;

  return g_steal_pointer (&commit_checksum);

error:

  ostree_repo_abort_transaction (repo, cancellable, NULL);
  return NULL;
}


===== ./common/flatpak-oci-signatures.c =====
/* vi:set et sw=2 sts=2 cin cino=t0,f0,(0,{s,>2s,n-s,^-s,e-s:
 * Copyright © 2014-2024 Red Hat, Inc
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Alexander Larsson <alexl@redhat.com>
 *       Owen Taylor <otaylor@redhat.com>
 */

#include "config.h"

#include <glib/gi18n-lib.h>
#include <gio/gunixoutputstream.h>

#include "libglnx.h"
#include <gpgme.h>

#include "flatpak-oci-signatures-private.h"
#include "flatpak-uri-private.h"
#include "flatpak-utils-private.h"

G_DEFINE_AUTO_CLEANUP_FREE_FUNC (gpgme_data_t, gpgme_data_release, NULL)
G_DEFINE_AUTO_CLEANUP_FREE_FUNC (gpgme_ctx_t, gpgme_release, NULL)
G_DEFINE_AUTO_CLEANUP_FREE_FUNC (gpgme_key_t, gpgme_key_unref, NULL)

gboolean
flatpak_remote_has_gpg_key (OstreeRepo   *repo,
                            const char   *remote_name)
{
  g_autoptr(GFile) keyring_file = NULL;
  g_autofree char *keyring_name = NULL;

  keyring_name = g_strdup_printf ("%s.trustedkeys.gpg", remote_name);
  keyring_file = g_file_get_child (ostree_repo_get_path (repo), keyring_name);

  return g_file_query_exists (keyring_file, NULL);
}

static void
flatpak_gpgme_error_to_gio_error (gpgme_error_t gpg_error,
                                  GError      **error)
{
  GIOErrorEnum errcode;

  /* XXX This list is incomplete.  Add cases as needed. */

  switch (gpgme_err_code (gpg_error))
    {
    /* special case - shouldn't be here */
    case GPG_ERR_NO_ERROR:
      g_return_if_reached ();

    /* special case - abort on out-of-memory */
    case GPG_ERR_ENOMEM:
      g_error ("%s: out of memory",
               gpgme_strsource (gpg_error));

    case GPG_ERR_INV_VALUE:
      errcode = G_IO_ERROR_INVALID_ARGUMENT;
      break;

    default:
      errcode = G_IO_ERROR_FAILED;
      break;
    }

  g_set_error (error, G_IO_ERROR, errcode, "%s: error code %d",
               gpgme_strsource (gpg_error), gpgme_err_code (gpg_error));
}

static gboolean
signature_is_valid (gpgme_signature_t signature)
{
  /* Mimic the way librepo tests for a valid signature, checking both
   * summary and status fields.
   *
   * - VALID summary flag means the signature is fully valid.
   * - GREEN summary flag means the signature is valid with caveats.
   * - No summary but also no error means the signature is valid but
   *   the signing key is not certified with a trusted signature.
   */
  return (signature->summary & GPGME_SIGSUM_VALID) ||
         (signature->summary & GPGME_SIGSUM_GREEN) ||
         (signature->summary == 0 && signature->status == GPG_ERR_NO_ERROR);
}

static GString *
read_gpg_buffer (gpgme_data_t buffer, GError **error)
{
  g_autoptr(GString) res = g_string_new ("");
  char buf[1024];
  int ret;

  ret = gpgme_data_seek (buffer, 0, SEEK_SET);
  if (ret)
    {
      flatpak_fail (error, "Can't seek in gpg plain text");
      return NULL;
    }
  while ((ret = gpgme_data_read (buffer, buf, sizeof (buf) - 1)) > 0)
    g_string_append_len (res, buf, ret);
  if (ret < 0)
    {
      flatpak_fail (error, "Can't read in gpg plain text");
      return NULL;
    }

  return g_steal_pointer (&res);
}

static gboolean
flatpak_gpgme_ctx_tmp_home_dir (gpgme_ctx_t   gpgme_ctx,
                                GLnxTmpDir   *tmpdir,
                                OstreeRepo   *repo,
                                const char   *remote_name,
                                GCancellable *cancellable,
                                GError      **error)
{
  g_autofree char *tmp_home_dir_pattern = NULL;
  gpgme_error_t gpg_error;
  g_autoptr(GFile) keyring_file = NULL;
  g_autofree char *keyring_name = NULL;

  g_return_val_if_fail (gpgme_ctx != NULL, FALSE);

  /* GPGME has no API for using multiple keyrings (aka, gpg --keyring),
   * so we create a temporary directory and tell GPGME to use it as the
   * home directory.  Then (optionally) create a pubring.gpg file there
   * and hand the caller an open output stream to concatenate necessary
   * keyring files. */

  tmp_home_dir_pattern = g_build_filename (g_get_tmp_dir (), "flatpak-gpg-XXXXXX", NULL);

  if (!glnx_mkdtempat (AT_FDCWD, tmp_home_dir_pattern, 0700,
                       tmpdir, error))
    return FALSE;

  /* Not documented, but gpgme_ctx_set_engine_info() accepts NULL for
   * the executable file name, which leaves the old setting unchanged. */
  gpg_error = gpgme_ctx_set_engine_info (gpgme_ctx,
                                         GPGME_PROTOCOL_OpenPGP,
                                         NULL, tmpdir->path);
  if (gpg_error != GPG_ERR_NO_ERROR)
    {
      flatpak_gpgme_error_to_gio_error (gpg_error, error);
      return FALSE;
    }

  keyring_name = g_strdup_printf ("%s.trustedkeys.gpg", remote_name);
  keyring_file = g_file_get_child (ostree_repo_get_path (repo), keyring_name);

  if (g_file_query_exists (keyring_file, NULL) &&
      !glnx_file_copy_at (AT_FDCWD, flatpak_file_get_path_cached (keyring_file), NULL,
                          tmpdir->fd, "pubring.gpg",
                          GLNX_FILE_COPY_OVERWRITE | GLNX_FILE_COPY_NOXATTRS,
                          cancellable, error))
    return FALSE;

  return TRUE;
}

/* WARNING: This verifies that the data is signed with the correct key, but
 * does not verify the payload matches what is being installed. The caller
 * must do that.
 */
static FlatpakOciSignature *
flatpak_oci_verify_signature (OstreeRepo *repo,
                              const char *remote_name,
                              GBytes     *signed_data,
                              GError    **error)
{
  gpgme_ctx_t context;
  gpgme_error_t gpg_error;
  g_auto(gpgme_data_t) signed_data_buffer = NULL;
  g_auto(gpgme_data_t) plain_buffer = NULL;
  gpgme_verify_result_t vresult;
  gpgme_signature_t sig;
  int valid_count;
  g_autoptr(GString) plain = NULL;
  g_autoptr(GBytes) plain_bytes = NULL;
  g_autoptr(FlatpakJson) json = NULL;
  g_auto(GLnxTmpDir) tmp_home_dir = { 0, };

  gpg_error = gpgme_new (&context);
  if (gpg_error != GPG_ERR_NO_ERROR)
    {
      flatpak_gpgme_error_to_gio_error (gpg_error, error);
      g_prefix_error (error, "Unable to create context: ");
      return NULL;
    }

  if (!flatpak_gpgme_ctx_tmp_home_dir (context, &tmp_home_dir, repo, remote_name, NULL, error))
    return NULL;

  gpg_error = gpgme_data_new_from_mem (&signed_data_buffer,
                                       g_bytes_get_data (signed_data, NULL),
                                       g_bytes_get_size (signed_data),
                                       0 /* do not copy */);
  if (gpg_error != GPG_ERR_NO_ERROR)
    {
      flatpak_gpgme_error_to_gio_error (gpg_error, error);
      g_prefix_error (error, "Unable to read signed data: ");
      return NULL;
    }

  gpg_error = gpgme_data_new (&plain_buffer);
  if (gpg_error != GPG_ERR_NO_ERROR)
    {
      flatpak_gpgme_error_to_gio_error (gpg_error, error);
      g_prefix_error (error, "Unable to allocate plain buffer: ");
      return NULL;
    }

  gpg_error = gpgme_op_verify (context, signed_data_buffer, NULL, plain_buffer);
  if (gpg_error != GPG_ERR_NO_ERROR)
    {
      flatpak_gpgme_error_to_gio_error (gpg_error, error);
      g_prefix_error (error, "Unable to complete signature verification: ");
      return NULL;
    }

  vresult = gpgme_op_verify_result (context);

  valid_count = 0;
  for (sig = vresult->signatures; sig != NULL; sig = sig->next)
    {
      if (signature_is_valid (sig))
        valid_count++;
    }

  if (valid_count == 0)
    {
      g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
                           "GPG signatures found, but none are in trusted keyring");
      return NULL;
    }

  plain = read_gpg_buffer (plain_buffer, error);
  if (plain == NULL)
    return NULL;
  plain_bytes = g_string_free_to_bytes (g_steal_pointer (&plain));
  json = flatpak_json_from_bytes (plain_bytes, FLATPAK_TYPE_OCI_SIGNATURE, error);
  if (json == NULL)
    return NULL;

  return (FlatpakOciSignature *) g_steal_pointer (&json);
}

struct _FlatpakOciSignatures
{
  GPtrArray *signatures;
};

FlatpakOciSignatures *
flatpak_oci_signatures_new (void)
{
  FlatpakOciSignatures *self = g_new0 (FlatpakOciSignatures, 1);

  self->signatures = g_ptr_array_new_with_free_func ((GDestroyNotify)g_bytes_unref);

  return self;
}

void
flatpak_oci_signatures_free (FlatpakOciSignatures *self)
{
  g_clear_pointer (&self->signatures, g_ptr_array_unref);
  g_free (self);
}

void
flatpak_oci_signatures_add_signature (FlatpakOciSignatures *self,
                                      GBytes               *signature)
{
  g_ptr_array_add (self->signatures, g_bytes_ref (signature));
}

gboolean
flatpak_oci_signatures_load_from_dfd (FlatpakOciSignatures *self,
                                      int                   dfd,
                                      GCancellable         *cancellable,
                                      GError              **error)
{
  for (guint i = 1; i < G_MAXUINT; i++)
    {
      g_autofree char *filename = g_strdup_printf ("signature-%u", i);
      g_autoptr(GError) local_error = NULL;
      GBytes *signature;

      signature = flatpak_load_file_at (dfd, filename, cancellable, &local_error);
      if (local_error)
        {
          if (g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
            break;

          g_propagate_error (error, g_steal_pointer (&local_error));
          return FALSE;
        }

      flatpak_oci_signatures_add_signature (self, g_steal_pointer (&signature));
    }

  return TRUE;
}

gboolean
flatpak_oci_signatures_save_to_dfd (FlatpakOciSignatures *self,
                                    int                   dfd,
                                    GCancellable         *cancellable,
                                    GError              **error)
{
  for (guint i = 0; i < self->signatures->len; i++)
    {
      g_autofree char *filename = g_strdup_printf ("signature-%u", i + 1);
      GBytes *signature = g_ptr_array_index (self->signatures, i);
      gconstpointer data;
      gsize size;

      data = g_bytes_get_data (signature, &size);

      if (!glnx_file_replace_contents_at (dfd, filename, data, size,
                                          0, cancellable, error))
        return FALSE;
    }

  return TRUE;
}

/*
 * Strip the tag and or digest off of a docker-reference. Regular expressions
 * based off of:
 *
 *   https://github.com/containers/image/tree/main/docker/reference
 *
 * For simplicity we don't do normalization - if the signature claims that it
 * matches 'ubuntu', we don't match turn that into docker.io/library/ubuntu
 * before matching against the domain and repository.
 */

#define TAG "[0-9A-Za-z_][0-9A-Za-z_-]{0,127}"
#define DIGEST "[A-Za-z][A-Za-z0-9]*(?:[-_+.][A-Za-z][A-Za-z0-9]*)*[:][[:xdigit:]]{32,}"
#define STRIP_TAG_AND_DIGEST_RE "^(.*?)(?::" TAG ")?" "(?:@" DIGEST ")?$"

static char *
reference_strip_tag_and_digest (const char *str)
{
  static gsize regex = 0;
  g_autoptr(GMatchInfo) match_info = NULL;
  gboolean matched;

  if (g_once_init_enter (&regex))
    {
      g_autoptr(GRegex) compiled = g_regex_new (STRIP_TAG_AND_DIGEST_RE,
                                                G_REGEX_DEFAULT,
                                                G_REGEX_MATCH_DEFAULT,
                                                NULL);
      g_assert (compiled);
      g_once_init_leave (&regex, (gsize) g_steal_pointer (&compiled));
    }

  matched = g_regex_match ((GRegex *) regex, str,
                           G_REGEX_MATCH_DEFAULT, &match_info);
  if (!matched)
    return NULL;

  return g_match_info_fetch (match_info, 1);
}

gboolean
flatpak_oci_signatures_verify (FlatpakOciSignatures *self,
                               OstreeRepo           *repo,
                               const char           *remote_name,
                               const char           *registry_url,
                               const char           *repository_name,
                               const char           *digest,
                               GError              **error)
{
  g_autoptr(GUri) uri = NULL;
  int port;
  g_autofree char *port_prefix = NULL;
  g_autofree char *expected_identity = NULL;

  if (!flatpak_remote_has_gpg_key (repo, remote_name))
    {
      g_info ("%s: no GPG key, skipping verification", remote_name);
      return TRUE;
    }

  uri = g_uri_parse (registry_url, FLATPAK_HTTP_URI_FLAGS | G_URI_FLAGS_PARSE_RELAXED, error);
  if (uri == NULL)
    return FALSE;

  port = g_uri_get_port (uri);
  if (port != -1 && port != 80 && port != 443)
    port_prefix = g_strdup_printf (":%d", g_uri_get_port (uri));

  expected_identity = g_strdup_printf ("%s%s/%s",
                                       g_uri_get_host (uri),
                                       port_prefix ? port_prefix : "",
                                       repository_name);

  for (guint i = 0; i < self->signatures->len; i++)
    {
      g_autoptr(FlatpakOciSignature) signature = NULL;
      g_autoptr(GError) local_error = NULL;

      signature = flatpak_oci_verify_signature (repo, remote_name,
                                                g_ptr_array_index (self->signatures, i),
                                                &local_error);

      if (signature == NULL)
        {
          g_info ("Couldn't verify signature: %s", local_error->message);
          continue;
        }

      if (signature->critical.image.digest == NULL)
        {
          g_warning ("Signature is missing digest");
          continue;
        }

      if (strcmp (signature->critical.image.digest, digest) != 0)
        {
          g_warning ("Digest in signature (%s) does not match %s",
                     signature->critical.image.digest, digest);
          continue;
        }

      if (signature->critical.identity.reference != NULL)
        {
          g_autofree char *stripped = NULL;

          stripped = reference_strip_tag_and_digest (signature->critical.identity.reference);

          if (g_strcmp0 (expected_identity, stripped) != 0)
            {
              g_info ("Identity in signature (%s) does not match %s",
                      signature->critical.identity.reference,
                      expected_identity);
              continue;
            }
        }

      g_info ("%s: found valid signature for %s@%s",
              remote_name, expected_identity, digest);
      return TRUE;
    }

  return flatpak_fail_error (error, FLATPAK_ERROR_UNTRUSTED,
                             "%s: no valid signatures for %s@%s",
                             remote_name, expected_identity, digest);
}

===== ./common/flatpak-context-private.h =====
/*
 * Copyright © 2014-2018 Red Hat, Inc
 * Copyright © 2024 GNOME Foundation, Inc.
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Alexander Larsson <alexl@redhat.com>
 *       Georges Basile Stavracas Neto <georges.stavracas@gmail.com>
 *       Hubert Figuière <hub@figuiere.net>
 */

#ifndef __FLATPAK_CONTEXT_H__
#define __FLATPAK_CONTEXT_H__

#include "libglnx.h"
#include <flatpak-common-types-private.h>
#include "flatpak-exports-private.h"
#include "flatpak-usb-private.h"

typedef enum {
  FLATPAK_SESSION_BUS,
  FLATPAK_SYSTEM_BUS,
  FLATPAK_A11Y_BUS,
} FlatpakBus;

typedef enum {
  FLATPAK_POLICY_NONE,
  FLATPAK_POLICY_SEE,
  FLATPAK_POLICY_TALK,
  FLATPAK_POLICY_OWN
} FlatpakPolicy;

typedef struct FlatpakContext FlatpakContext;

typedef enum {
  FLATPAK_CONTEXT_SHARED_NETWORK   = 1 << 0,
  FLATPAK_CONTEXT_SHARED_IPC       = 1 << 1,
} FlatpakContextShares;

typedef enum {
  FLATPAK_CONTEXT_SOCKET_X11         = 1 << 0,
  FLATPAK_CONTEXT_SOCKET_WAYLAND     = 1 << 1,
  FLATPAK_CONTEXT_SOCKET_PULSEAUDIO  = 1 << 2,
  FLATPAK_CONTEXT_SOCKET_SESSION_BUS = 1 << 3,
  FLATPAK_CONTEXT_SOCKET_SYSTEM_BUS  = 1 << 4,
  FLATPAK_CONTEXT_SOCKET_FALLBACK_X11 = 1 << 5, /* For backwards compat, not used internally */
  FLATPAK_CONTEXT_SOCKET_SSH_AUTH    = 1 << 6,
  FLATPAK_CONTEXT_SOCKET_PCSC        = 1 << 7,
  FLATPAK_CONTEXT_SOCKET_CUPS        = 1 << 8,
  FLATPAK_CONTEXT_SOCKET_GPG_AGENT   = 1 << 9,
  FLATPAK_CONTEXT_SOCKET_INHERIT_WAYLAND_SOCKET = 1 << 10,
} FlatpakContextSockets;

typedef enum {
  FLATPAK_CONTEXT_DEVICE_DRI         = 1 << 0,
  FLATPAK_CONTEXT_DEVICE_ALL         = 1 << 1,
  FLATPAK_CONTEXT_DEVICE_KVM         = 1 << 2,
  FLATPAK_CONTEXT_DEVICE_SHM         = 1 << 3,
  FLATPAK_CONTEXT_DEVICE_INPUT       = 1 << 4,
  FLATPAK_CONTEXT_DEVICE_USB         = 1 << 5,
} FlatpakContextDevices;

typedef enum {
  FLATPAK_CONTEXT_FEATURE_DEVEL        = 1 << 0,
  FLATPAK_CONTEXT_FEATURE_MULTIARCH    = 1 << 1,
  FLATPAK_CONTEXT_FEATURE_BLUETOOTH    = 1 << 2,
  FLATPAK_CONTEXT_FEATURE_CANBUS       = 1 << 3,
  FLATPAK_CONTEXT_FEATURE_PER_APP_DEV_SHM = 1 << 4,
} FlatpakContextFeatures;

typedef enum {
  FLATPAK_CONTEXT_CONDITION_TRUE          = 1 << 0,
  FLATPAK_CONTEXT_CONDITION_FALSE         = 1 << 1,
  FLATPAK_CONTEXT_CONDITION_HAS_INPUT_DEV = 1 << 2,
  FLATPAK_CONTEXT_CONDITION_HAS_USB_DEV   = 1 << 3,
  FLATPAK_CONTEXT_CONDITION_HAS_WAYLAND   = 1 << 4,
  FLATPAK_CONTEXT_CONDITION_HAS_USB_PORTAL = 1 << 5,
} FlatpakContextConditions;

struct FlatpakContext
{
  GHashTable            *shares_permissions;
  GHashTable            *socket_permissions;
  GHashTable            *device_permissions;
  GHashTable            *features_permissions;
  GHashTable            *env_vars;
  GHashTable            *persistent;
  GHashTable            *filesystems;
  GHashTable            *session_bus_policy;
  GHashTable            *system_bus_policy;
  GHashTable            *a11y_bus_policy;
  GHashTable            *generic_policy;
  GHashTable            *enumerable_usb_devices;
  GHashTable            *hidden_usb_devices;
};

/* Gets a single condition as param and returns whether the condition is true. */
typedef gboolean (*FlatpakContextConditionEvaluator) (FlatpakContextConditions condition);

extern const char *flatpak_context_sockets[];
extern const char *flatpak_context_devices[];
extern const char *flatpak_context_features[];
extern const char *flatpak_context_shares[];

gboolean       flatpak_context_parse_filesystem (const char             *filesystem_and_mode,
                                                 gboolean                negated,
                                                 char                  **filesystem_out,
                                                 FlatpakFilesystemMode  *mode_out,
                                                 GError                **error);

FlatpakContext *flatpak_context_new (void);
void           flatpak_context_free (FlatpakContext *context);
void           flatpak_context_dump (FlatpakContext *context,
                                     const char     *title);
void           flatpak_context_merge (FlatpakContext *context,
                                      FlatpakContext *other);
GOptionEntry  *flatpak_context_get_option_entries (void);
GOptionGroup  *flatpak_context_get_options (FlatpakContext *context);
gboolean       flatpak_context_load_metadata (FlatpakContext *context,
                                              GKeyFile       *metakey,
                                              GError        **error);
void           flatpak_context_save_metadata (FlatpakContext *context,
                                              gboolean        flatten,
                                              GKeyFile       *metakey);
void           flatpak_context_set_session_bus_policy (FlatpakContext *context,
                                                       const char     *name,
                                                       FlatpakPolicy   policy);
GStrv          flatpak_context_get_session_bus_policy_allowed_own_names (FlatpakContext *context);
void           flatpak_context_set_system_bus_policy (FlatpakContext *context,
                                                      const char     *name,
                                                      FlatpakPolicy   policy);
void           flatpak_context_set_a11y_bus_policy (FlatpakContext *context,
                                                    const char     *name,
                                                    FlatpakPolicy   policy);
char *         flatpak_context_devices_to_usb_list (GHashTable *devices,
                                                    gboolean hidden);
void           flatpak_context_to_args (FlatpakContext *context,
                                        GPtrArray      *args);
FlatpakRunFlags flatpak_context_features_to_run_flags (FlatpakContextFeatures features);
void           flatpak_context_add_bus_filters (FlatpakContext *context,
                                                const char     *app_id,
                                                FlatpakBus      bus,
                                                gboolean        sandboxed,
                                                FlatpakBwrap   *bwrap);

gboolean       flatpak_context_get_needs_session_bus_proxy (FlatpakContext *context);
gboolean       flatpak_context_get_needs_system_bus_proxy (FlatpakContext *context);
gboolean       flatpak_context_adds_permissions (FlatpakContext *old_context,
                                                 FlatpakContext *new_context);

void           flatpak_context_reset_permissions (FlatpakContext *context);
void           flatpak_context_reset_non_permissions (FlatpakContext *context);
void           flatpak_context_make_sandboxed (FlatpakContext *context);

FlatpakContext *flatpak_context_load_for_deploy (FlatpakDeploy *deploy,
                                                 GError       **error);

FlatpakExports *flatpak_context_get_exports (FlatpakContext *context,
                                             const char     *app_id);
FlatpakExports *flatpak_context_get_exports_full (FlatpakContext *context,
                                                  GFile          *app_id_dir,
                                                  GPtrArray      *extra_app_id_dirs,
                                                  gboolean        do_create,
                                                  gboolean        include_default_dirs,
                                                  gchar         **xdg_dirs_conf,
                                                  gboolean       *home_access_out);

void flatpak_context_append_bwrap_filesystem (FlatpakContext  *context,
                                              FlatpakBwrap    *bwrap,
                                              const char      *app_id,
                                              GFile           *app_id_dir,
                                              FlatpakExports  *exports,
                                              const char      *xdg_dirs_conf,
                                              gboolean         home_access);

gboolean flatpak_context_parse_env_block (FlatpakContext *context,
                                          const char *data,
                                          gsize length,
                                          GError **error);
gboolean flatpak_context_parse_env_fd (FlatpakContext *context,
                                       int fd,
                                       GError **error);

G_DEFINE_AUTOPTR_CLEANUP_FUNC (FlatpakContext, flatpak_context_free)

GFile *flatpak_get_user_base_dir_location (void);
GFile *flatpak_get_data_dir (const char *app_id);

gboolean flatpak_context_get_allowed_exports (FlatpakContext *context,
                                              const char     *source_path,
                                              const char     *app_id,
                                              char         ***allowed_extensions_out,
                                              char         ***allowed_prefixes_out,
                                              gboolean       *require_exact_match_out);


FlatpakContextShares flatpak_context_compute_allowed_shares (FlatpakContext                   *context,
                                                              FlatpakContextConditionEvaluator  evaluator);
FlatpakContextSockets flatpak_context_compute_allowed_sockets (FlatpakContext                   *context,
                                                               FlatpakContextConditionEvaluator  evaluator);
FlatpakContextDevices flatpak_context_compute_allowed_devices (FlatpakContext                   *context,
                                                               FlatpakContextConditionEvaluator  evaluator);
FlatpakContextFeatures flatpak_context_compute_allowed_features (FlatpakContext                   *context,
                                                                FlatpakContextConditionEvaluator  evaluator);

#endif /* __FLATPAK_CONTEXT_H__ */

===== ./common/flatpak-instance.h =====
/*
 * Copyright © 2018 Red Hat, Inc
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Matthias Clasen <mclasen@redhat.com>
 */

#if !defined(__FLATPAK_H_INSIDE__) && !defined(FLATPAK_COMPILATION)
#error "Only <flatpak.h> can be included directly."
#endif

#ifndef __FLATPAK_INSTANCE_H__
#define __FLATPAK_INSTANCE_H__

typedef struct _FlatpakInstance FlatpakInstance;

#include <glib-object.h>

G_BEGIN_DECLS

#define FLATPAK_TYPE_INSTANCE flatpak_instance_get_type ()
#define FLATPAK_INSTANCE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), FLATPAK_TYPE_INSTANCE, FlatpakInstance))
#define FLATPAK_IS_INSTANCE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), FLATPAK_TYPE_INSTANCE))

FLATPAK_EXTERN GType flatpak_instance_get_type (void);

struct _FlatpakInstance
{
  GObject parent;
};

typedef struct
{
  GObjectClass parent_class;
} FlatpakInstanceClass;


#ifdef G_DEFINE_AUTOPTR_CLEANUP_FUNC
G_DEFINE_AUTOPTR_CLEANUP_FUNC (FlatpakInstance, g_object_unref)
#endif

FLATPAK_EXTERN GPtrArray *  flatpak_instance_get_all (void);

FLATPAK_EXTERN const char * flatpak_instance_get_id (FlatpakInstance *self);
FLATPAK_EXTERN const char * flatpak_instance_get_app (FlatpakInstance *self);
FLATPAK_EXTERN const char * flatpak_instance_get_arch (FlatpakInstance *self);
FLATPAK_EXTERN const char * flatpak_instance_get_branch (FlatpakInstance *self);
FLATPAK_EXTERN const char * flatpak_instance_get_commit (FlatpakInstance *self);
FLATPAK_EXTERN const char * flatpak_instance_get_runtime (FlatpakInstance *self);
FLATPAK_EXTERN const char * flatpak_instance_get_runtime_commit (FlatpakInstance *self);
FLATPAK_EXTERN int          flatpak_instance_get_pid (FlatpakInstance *self);
FLATPAK_EXTERN int          flatpak_instance_get_child_pid (FlatpakInstance *self);
FLATPAK_EXTERN GKeyFile *   flatpak_instance_get_info (FlatpakInstance *self);

FLATPAK_EXTERN gboolean     flatpak_instance_is_running (FlatpakInstance *self);

G_END_DECLS

#endif /* __FLATPAK_INSTANCE_H__ */

===== ./common/flatpak-run-dbus-private.h =====
/*
 * Copyright © 2014 Red Hat, Inc
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Alexander Larsson <alexl@redhat.com>
 */

#pragma once

#include "libglnx.h"

#include "flatpak-bwrap-private.h"
#include "flatpak-common-types-private.h"
#include "flatpak-context-private.h"

G_BEGIN_DECLS

gboolean flatpak_run_add_session_dbus_args (FlatpakBwrap          *app_bwrap,
                                            FlatpakBwrap          *proxy_arg_bwrap,
                                            FlatpakContextSockets  sockets,
                                            FlatpakContext        *context,
                                            FlatpakRunFlags        flags,
                                            const char            *app_id);

gboolean flatpak_run_add_system_dbus_args (FlatpakBwrap          *app_bwrap,
                                           FlatpakBwrap          *proxy_arg_bwrap,
                                           FlatpakContextSockets  sockets,
                                           FlatpakContext        *context,
                                           FlatpakRunFlags        flags);

gboolean flatpak_run_add_a11y_dbus_args (FlatpakBwrap    *app_bwrap,
                                         FlatpakBwrap    *proxy_arg_bwrap,
                                         FlatpakContext  *context,
                                         FlatpakRunFlags  flags,
                                         const char      *app_id);

gboolean flatpak_run_maybe_start_dbus_proxy (FlatpakBwrap *app_bwrap,
                                             FlatpakBwrap *proxy_arg_bwrap,
                                             const char   *app_info_path,
                                             GError      **error);

G_END_DECLS

===== ./common/flatpak-usb-private.h =====
/*
 * Copyright © 2024 GNOME Foundation, Inc.
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Georges Basile Stavracas Neto <georges.stavracas@gmail.com>
 *       Hubert Figuière <hub@figuiere.net>
 */

#pragma once

#include <stdint.h>

typedef enum
{
  FLATPAK_USB_RULE_TYPE_ALL,
  FLATPAK_USB_RULE_TYPE_CLASS,
  FLATPAK_USB_RULE_TYPE_DEVICE,
  FLATPAK_USB_RULE_TYPE_VENDOR,
} UsbRuleType;

typedef enum
{
  FLATPAK_USB_RULE_CLASS_TYPE_CLASS_ONLY,
  FLATPAK_USB_RULE_CLASS_TYPE_CLASS_SUBCLASS,
} UsbDeviceClassType;

typedef struct
{
  UsbDeviceClassType type;
  uint16_t class;
  uint16_t subclass;
} UsbDeviceClass;

typedef struct
{
  uint16_t id;
} UsbProduct;

typedef struct
{
  uint16_t id;
} UsbVendor;

typedef struct
{
  UsbRuleType rule_type;

  union {
    UsbDeviceClass device_class;
    UsbProduct product;
    UsbVendor vendor;
  } d;
} FlatpakUsbRule;

typedef struct
{
  GPtrArray *rules;
} FlatpakUsbQuery;


void flatpak_usb_rule_print (FlatpakUsbRule *usb_rule,
                             GString        *string);
void flatpak_usb_rule_free (FlatpakUsbRule *usb_rule);

G_DEFINE_AUTOPTR_CLEANUP_FUNC (FlatpakUsbRule, flatpak_usb_rule_free)

FlatpakUsbQuery *flatpak_usb_query_new (void);
FlatpakUsbQuery *flatpak_usb_query_copy (const FlatpakUsbQuery *query);
void flatpak_usb_query_print (const FlatpakUsbQuery *usb_query,
                              GString               *string);
void flatpak_usb_query_free (FlatpakUsbQuery *usb_query);

G_DEFINE_AUTOPTR_CLEANUP_FUNC (FlatpakUsbQuery, flatpak_usb_query_free)

gboolean flatpak_usb_parse_usb_rule (const char      *data,
                                     FlatpakUsbRule **out_usb_rule,
                                     GError         **error);
gboolean flatpak_usb_parse_usb (const char       *data,
                                FlatpakUsbQuery **out_usb_query,
                                GError          **error);
gboolean flatpak_usb_parse_usb_list (const char  *buffer,
                                     GHashTable  *enumerable,
                                     GHashTable  *hidden,
                                     GError     **error);

===== ./common/flatpak-image-source.c =====
/* vi:set et sw=2 sts=2 cin cino=t0,f0,(0,{s,>2s,n-s,^-s,e-s:
 * Copyright © 2024 Red Hat, Inc
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Owen Taylor <otaylor@redhat.com>
 */

#include <glib/gi18n-lib.h>

#include "flatpak-docker-reference-private.h"
#include "flatpak-image-source-private.h"
#include "flatpak-oci-registry-private.h"

struct _FlatpakImageSource
{
  GObject parent;

  FlatpakOciRegistry *registry;
  char *repository;
  char *digest;
  char *delta_url;

  FlatpakOciManifest *manifest;
  size_t manifest_size;
  FlatpakOciImage *image_config;
};

G_DEFINE_TYPE (FlatpakImageSource, flatpak_image_source, G_TYPE_OBJECT)

static void
flatpak_image_source_finalize (GObject *object)
{
  FlatpakImageSource *self = FLATPAK_IMAGE_SOURCE (object);

  g_clear_object (&self->registry);
  g_clear_pointer (&self->repository, g_free);
  g_clear_pointer (&self->digest, g_free);
  g_clear_pointer (&self->delta_url, g_free);
  g_clear_object (&self->manifest);
  g_clear_object (&self->image_config);

  G_OBJECT_CLASS (flatpak_image_source_parent_class)->finalize (object);
}

static void
flatpak_image_source_class_init (FlatpakImageSourceClass *klass)
{
  GObjectClass *object_class = G_OBJECT_CLASS (klass);

  object_class->finalize = flatpak_image_source_finalize;
}

static void
flatpak_image_source_init (FlatpakImageSource *self)
{
}

FlatpakImageSource *
flatpak_image_source_new (FlatpakOciRegistry *registry,
                          const char         *repository,
                          const char         *digest,
                          GCancellable       *cancellable,
                          GError            **error)
{
  g_autoptr(FlatpakImageSource) self = NULL;
  g_autoptr(FlatpakOciVersioned) versioned = NULL;

  if (!g_str_has_prefix (digest, "sha256:"))
    {
      flatpak_fail_error (error, FLATPAK_ERROR_INVALID_DATA, _("Only sha256 image checksums are supported"));
      return NULL;
    }

  self = g_object_new (FLATPAK_TYPE_IMAGE_SOURCE, NULL);
  self->registry = g_object_ref (registry);
  self->repository = g_strdup (repository);
  self->digest = g_strdup (digest);

  versioned = flatpak_oci_registry_load_versioned (self->registry, self->repository,
                                                   self->digest, NULL, &self->manifest_size,
                                                   cancellable, error);
  if (versioned == NULL)
    return NULL;

  if (!FLATPAK_IS_OCI_MANIFEST (versioned))
    {
      flatpak_fail_error (error, FLATPAK_ERROR_INVALID_DATA, _("Image is not a manifest"));
      return NULL;
    }

  self->manifest = FLATPAK_OCI_MANIFEST (g_steal_pointer (&versioned));

  if (self->manifest->config.digest == NULL)
    {
      flatpak_fail_error (error, FLATPAK_ERROR_INVALID_DATA, _("Image is not a manifest"));
      return NULL;
    }

  self->image_config =
    flatpak_oci_registry_load_image_config (self->registry,
                                            self->repository,
                                            self->manifest->config.digest,
                                            (const char **) self->manifest->config.urls,
                                            NULL, cancellable, error);
  if (self->image_config == NULL)
    return NULL;

  if (flatpak_image_source_get_ref (self) == NULL)
    {
      flatpak_fail_error (error, FLATPAK_ERROR_INVALID_DATA, _("No org.flatpak.ref found in image"));
      return NULL;
    }

  return g_steal_pointer (&self);
}

static FlatpakImageSource *
flatpak_image_source_new_local_for_registry (FlatpakOciRegistry *registry,
                                             const char         *reference,
                                             GCancellable       *cancellable,
                                             GError            **error)
{
  g_autoptr(FlatpakOciIndex) index = NULL;
  const FlatpakOciManifestDescriptor *desc;

  index = flatpak_oci_registry_load_index (registry, cancellable, error);
  if (index == NULL)
    return NULL;

  if (reference)
    {
      desc = flatpak_oci_index_get_manifest (index, reference);
      if (desc == NULL)
        {
          flatpak_fail (error, _("Ref '%s' not found in registry"), reference);
          return NULL;
        }
    }
  else
    {
      desc = flatpak_oci_index_get_only_manifest (index);
      if (desc == NULL)
        {
          flatpak_fail (error, _("Multiple images in registry, specify a ref with --ref"));
          return NULL;
        }
    }

  return flatpak_image_source_new (registry, NULL, desc->parent.digest, cancellable, error);
}

FlatpakImageSource *
flatpak_image_source_new_local (GFile        *file,
                                const char   *reference,
                                GCancellable *cancellable,
                                GError      **error)
{
  g_autofree char *dir_uri = NULL;
  g_autoptr(FlatpakOciRegistry) registry = NULL;

  dir_uri = g_file_get_uri (file);
  registry = flatpak_oci_registry_new (dir_uri, FALSE, -1, cancellable, error);
  if (registry == NULL)
    return NULL;

  return flatpak_image_source_new_local_for_registry (registry, reference, cancellable, error);
}

FlatpakImageSource *
flatpak_image_source_new_remote (const char   *uri,
                                 const char   *oci_repository,
                                 const char   *digest,
                                 const char   *token,
                                 const char   *signature_lookaside,
                                 GCancellable *cancellable,
                                 GError      **error)
{
  g_autoptr(FlatpakOciRegistry) registry = NULL;

  registry = flatpak_oci_registry_new (uri, FALSE, -1, cancellable, error);
  if (!registry)
    return NULL;

  flatpak_oci_registry_set_token (registry, token);
  flatpak_oci_registry_set_signature_lookaside (registry, signature_lookaside);

  return flatpak_image_source_new (registry, oci_repository, digest, cancellable, error);
}

/* Parse an oci: or oci-archive: image location into a path
 * and an optional reference
 */
static void
get_path_and_reference (const char *image_location,
                        GFile     **path,
                        char      **reference)
{
  g_autofree char *path_str = NULL;
  const char *bare;
  const char *colon;

  colon = strchr (image_location, ':');
  g_assert (colon != NULL);

  bare = colon + 1;
  colon = strchr (bare, ':');

  if (colon)
     {
      path_str = g_strndup (bare, colon - bare);
      *reference = g_strdup (colon + 1);
    }
  else
    {
      path_str = g_strdup (bare);
      *reference = NULL;
    }

  *path = g_file_new_for_path (path_str);
}

FlatpakImageSource *
flatpak_image_source_new_for_location (const char   *location,
                                       GCancellable *cancellable,
                                       GError      **error)
{
  if (g_str_has_prefix (location, "oci:"))
    {
      g_autoptr(GFile) path = NULL;
      g_autofree char *reference = NULL;

      get_path_and_reference (location, &path, &reference);

      return flatpak_image_source_new_local (path, reference, cancellable, error);
    }
  else if (g_str_has_prefix (location, "oci-archive:"))
    {
      g_autoptr(FlatpakOciRegistry) registry = NULL;
      g_autoptr(GFile) path = NULL;
      g_autofree char *reference = NULL;

      get_path_and_reference (location, &path, &reference);

      registry = flatpak_oci_registry_new_for_archive (path, cancellable, error);
      if (registry == NULL)
        return NULL;

      return flatpak_image_source_new_local_for_registry (registry, reference, cancellable, error);
    }
  else if (g_str_has_prefix (location, "docker:"))
    {
      g_autoptr(FlatpakOciRegistry) registry = NULL;
      g_autoptr(FlatpakDockerReference) docker_reference = NULL;
      g_autofree char *local_digest = NULL;
      const char *repository = NULL;

      if (!g_str_has_prefix (location, "docker://"))
        {
          flatpak_fail (error, "docker: location must start docker://");
          return NULL;
        }

      docker_reference = flatpak_docker_reference_parse (location + 9, error);
      if (docker_reference == NULL)
        return NULL;

      registry = flatpak_oci_registry_new (flatpak_docker_reference_get_uri (docker_reference),
                                           FALSE, -1, cancellable, error);
      if (registry == NULL)
        return NULL;

      repository = flatpak_docker_reference_get_repository (docker_reference);

      local_digest = g_strdup (flatpak_docker_reference_get_digest (docker_reference));
      if (local_digest == NULL)
        {
          g_autoptr(GBytes) bytes = NULL;
          g_autoptr(FlatpakOciVersioned) versioned = NULL;
          const char *tag = flatpak_docker_reference_get_tag (docker_reference);

          if (tag == NULL)
            tag = "latest";

          bytes = flatpak_oci_registry_load_blob (registry, repository, TRUE, tag,
                                                  NULL, NULL, cancellable, error);
          if (!bytes)
            return NULL;

          versioned = flatpak_oci_versioned_from_json (bytes, NULL, error);
          if (!versioned)
            return NULL;

          if (FLATPAK_IS_OCI_MANIFEST (versioned))
            {
              g_autofree char *checksum = NULL;

              checksum = g_compute_checksum_for_bytes (G_CHECKSUM_SHA256, bytes);
              local_digest = g_strconcat ("sha256:", checksum, NULL);
            }
          else if (FLATPAK_IS_OCI_INDEX (versioned))
            {
              const char *oci_arch = flatpak_arch_to_oci_arch (flatpak_get_arch ());
              FlatpakOciManifestDescriptor *descriptor;

              descriptor = flatpak_oci_index_get_manifest_for_arch (FLATPAK_OCI_INDEX (versioned), oci_arch);
              if (descriptor == NULL)
                {
                  flatpak_fail_error (error, FLATPAK_ERROR_INVALID_DATA,
                                      "Can't find manifest for %s in image index", oci_arch);
                  return NULL;
                }

              local_digest = g_strdup (descriptor->parent.digest);
            }
        }

      return flatpak_image_source_new (registry, repository, local_digest, cancellable, error);
    }
  else
    {
      flatpak_fail (error, "unsupported image location: %s", location);
      return NULL;
    }
}

void
flatpak_image_source_set_delta_url (FlatpakImageSource *self,
                                    const char         *delta_url)
{
  g_free (self->delta_url);
  self->delta_url = g_strdup (delta_url);
}

const char *
flatpak_image_source_get_delta_url (FlatpakImageSource *self)
{
  return self->delta_url;
}

FlatpakOciRegistry *
flatpak_image_source_get_registry (FlatpakImageSource *self)
{
  return self->registry;
}

const char *
flatpak_image_source_get_oci_repository (FlatpakImageSource *self)
{
  return self->repository;
}

const char *
flatpak_image_source_get_digest (FlatpakImageSource *self)
{
  return self->digest;
}

FlatpakOciManifest *
flatpak_image_source_get_manifest (FlatpakImageSource *self)
{
  return self->manifest;
}

size_t
flatpak_image_source_get_manifest_size (FlatpakImageSource *self)
{
  return self->manifest_size;
}

FlatpakOciImage *
flatpak_image_source_get_image_config (FlatpakImageSource *self)
{
  return self->image_config;
}

const char *
flatpak_image_source_get_ref (FlatpakImageSource *self)
{
  GHashTable *labels = flatpak_oci_image_get_labels (self->image_config);

  return g_hash_table_lookup (labels, "org.flatpak.ref");
}

const char *
flatpak_image_source_get_metadata (FlatpakImageSource *self)
{
  GHashTable *labels = flatpak_oci_image_get_labels (self->image_config);

  return g_hash_table_lookup (labels, "org.flatpak.metadata");
}

const char *
flatpak_image_source_get_commit (FlatpakImageSource *self)
{
  GHashTable *labels = flatpak_oci_image_get_labels (self->image_config);

  return g_hash_table_lookup (labels, "org.flatpak.commit");
}

const char *
flatpak_image_source_get_parent_commit (FlatpakImageSource *self)
{
  GHashTable *labels = flatpak_oci_image_get_labels (self->image_config);

  return g_hash_table_lookup (labels, "org.flatpak.parent-commit");
}

guint64
flatpak_image_source_get_commit_timestamp (FlatpakImageSource *self)
{
  GHashTable *labels = flatpak_oci_image_get_labels (self->image_config);
  const char *oci_timestamp = g_hash_table_lookup (labels, "org.flatpak.timestamp");

  if (oci_timestamp != NULL)
    return g_ascii_strtoull (oci_timestamp, NULL, 10);
  else
    return 0;
}

const char *
flatpak_image_source_get_commit_subject (FlatpakImageSource *self)
{
  GHashTable *labels = flatpak_oci_image_get_labels (self->image_config);

  return g_hash_table_lookup (labels, "org.flatpak.subject");
}

const char *
flatpak_image_source_get_commit_body (FlatpakImageSource *self)
{
  GHashTable *labels = flatpak_oci_image_get_labels (self->image_config);

  return g_hash_table_lookup (labels, "org.flatpak.body");
}

void
flatpak_image_source_build_commit_metadata (FlatpakImageSource *self,
                                            GVariantBuilder    *metadata_builder)
{
  GHashTable *labels = flatpak_oci_image_get_labels (self->image_config);
  GHashTableIter iter;
  const char *key;
  const char *value;

  g_hash_table_iter_init (&iter, labels);
  while (g_hash_table_iter_next (&iter, (gpointer *)&key, (gpointer *)&value))
    {
      g_autoptr(GVariant) data = NULL;
      uint8_t *bin;
      size_t bin_len;

      if (!g_str_has_prefix (key, "org.flatpak.commit-metadata."))
        continue;

      key += strlen ("org.flatpak.commit-metadata.");

      bin = g_base64_decode (value, &bin_len);
      data = g_variant_ref_sink (g_variant_new_from_data (G_VARIANT_TYPE ("v"),
                                                          bin,
                                                          bin_len,
                                                          FALSE,
                                                          g_free,
                                                          bin));
      g_variant_builder_add (metadata_builder, "{s@v}", key, data);
    }
}

GVariant *
flatpak_image_source_make_fake_commit (FlatpakImageSource *self)
{
  const char *parent = NULL;
  g_autoptr(GVariantBuilder) metadata_builder = g_variant_builder_new (G_VARIANT_TYPE ("a{sv}"));
  g_autoptr(GVariant) metadata_v = NULL;

  flatpak_image_source_build_commit_metadata (self, metadata_builder);
  metadata_v = g_variant_ref_sink (g_variant_builder_end (metadata_builder));

  parent = flatpak_image_source_get_parent_commit (self);

  /* This isn't going to be exactly the same as the reconstructed one from the pull, because we don't have the contents, but its useful to get metadata */
  return
    g_variant_ref_sink (g_variant_new ("(@a{sv}@ay@a(say)sst@ay@ay)",
                                       metadata_v,
                                       parent ? ostree_checksum_to_bytes_v (parent) :  g_variant_new_from_data (G_VARIANT_TYPE ("ay"), NULL, 0, FALSE, NULL, NULL),
                                       g_variant_new_array (G_VARIANT_TYPE ("(say)"), NULL, 0),
                                       flatpak_image_source_get_commit_subject (self),
                                       flatpak_image_source_get_commit_body (self),
                                       GUINT64_TO_BE (flatpak_image_source_get_commit_timestamp (self)),
                                       ostree_checksum_to_bytes_v ("0000000000000000000000000000000000000000000000000000000000000000"),
                                       ostree_checksum_to_bytes_v ("0000000000000000000000000000000000000000000000000000000000000000")));
}

GVariant *
flatpak_image_source_make_summary_metadata (FlatpakImageSource *self)
{
  g_autoptr(GVariantBuilder) ref_metadata_builder = NULL;

  ref_metadata_builder = g_variant_builder_new (G_VARIANT_TYPE ("a{sv}"));

  if (self->repository)
    g_variant_builder_add (ref_metadata_builder, "{sv}", "xa.oci-repository",
                          g_variant_new_string (self->repository));
  if (self->delta_url)
    g_variant_builder_add (ref_metadata_builder, "{sv}", "xa.delta-url",
                           g_variant_new_string (self->delta_url));

  return g_variant_ref_sink (g_variant_builder_end (ref_metadata_builder));
}

===== ./common/flatpak-ref-utils-private.h =====
/*
 * Copyright © 2020 Red Hat, Inc
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Alexander Larsson <alexl@redhat.com>
 */

#include <flatpak-common-types-private.h>
#include <flatpak-ref.h>

#ifndef __FLATPAK_REF_UTILS_H__
#define __FLATPAK_REF_UTILS_H__

gboolean flatpak_is_valid_name (const char *string,
                                gssize      len,
                                GError    **error);
gboolean flatpak_is_valid_branch (const char *string,
                                  gssize      len,
                                  GError    **error);
gboolean flatpak_is_valid_arch (const char *string,
                                gssize      len,
                                GError    **error);
gboolean flatpak_has_name_prefix (const char *string,
                                  const char *name);
gboolean flatpak_name_matches_one_wildcard_prefix (const char         *string,
                                                   const char * const *maybe_wildcard_prefixes,
                                                   gboolean            require_exact_match);

char * flatpak_make_valid_id_prefix (const char *orig_id);
gboolean flatpak_id_has_subref_suffix (const char *id,
                                       gssize      id_len);

gboolean flatpak_is_app_runtime_or_appstream_ref (const char *ref);
char * flatpak_get_arch_for_ref (const char *ref);

FlatpakKinds flatpak_kinds_from_kind (FlatpakRefKind kind);

typedef struct _FlatpakDecomposed FlatpakDecomposed;
FlatpakDecomposed *flatpak_decomposed_new_from_ref          (const char         *ref,
                                                             GError            **error);
FlatpakDecomposed *flatpak_decomposed_new_from_col_ref      (const char         *ref,
                                                             const char         *collection_id,
                                                             GError            **error);
FlatpakDecomposed *flatpak_decomposed_new_from_refspec      (const char         *refspec,
                                                             GError            **error);
FlatpakDecomposed *flatpak_decomposed_new_from_ref_take     (char               *ref,
                                                             GError            **error);
FlatpakDecomposed *flatpak_decomposed_new_from_refspec_take (char               *refspec,
                                                             GError            **error);
FlatpakDecomposed *flatpak_decomposed_new_from_parts        (FlatpakKinds        kind,
                                                             const char         *id,
                                                             const char         *arch,
                                                             const char         *branch,
                                                             GError            **error);
FlatpakDecomposed *flatpak_decomposed_new_from_decomposed   (FlatpakDecomposed  *ref,
                                                             FlatpakKinds        opt_kind,
                                                             const char         *opt_id,
                                                             const char         *opt_arch,
                                                             const char         *opt_branch,
                                                             GError            **error);
FlatpakDecomposed *flatpak_decomposed_new_from_pref         (FlatpakKinds        kind,
                                                             const char         *pref,
                                                             GError            **error);
FlatpakDecomposed *flatpak_decomposed_ref                   (FlatpakDecomposed  *ref);
void               flatpak_decomposed_unref                 (FlatpakDecomposed  *ref);
const char *       flatpak_decomposed_get_ref               (FlatpakDecomposed  *ref);
const char *       flatpak_decomposed_get_refspec           (FlatpakDecomposed  *ref);
char *             flatpak_decomposed_dup_ref               (FlatpakDecomposed  *ref);
char *             flatpak_decomposed_dup_refspec           (FlatpakDecomposed  *ref);
char *             flatpak_decomposed_dup_remote            (FlatpakDecomposed  *ref);
const char *       flatpak_decomposed_get_collection_id     (FlatpakDecomposed  *ref);
char *             flatpak_decomposed_dup_collection_id     (FlatpakDecomposed  *ref);
gboolean           flatpak_decomposed_equal                 (FlatpakDecomposed  *ref_a,
                                                             FlatpakDecomposed  *ref_b);
gboolean           flatpak_decomposed_equal_except_branch   (FlatpakDecomposed  *ref_a,
                                                             FlatpakDecomposed  *ref_b);
gboolean           flatpak_decomposed_equal_except_arch     (FlatpakDecomposed  *ref_a,
                                                             FlatpakDecomposed  *ref_b);
gint               flatpak_decomposed_strcmp                (FlatpakDecomposed  *ref_a,
                                                             FlatpakDecomposed  *ref_b);
gint               flatpak_decomposed_strcmp_p              (FlatpakDecomposed **ref_a,
                                                             FlatpakDecomposed **ref_b);
guint              flatpak_decomposed_hash                  (FlatpakDecomposed  *ref);
gboolean           flatpak_decomposed_is_app                (FlatpakDecomposed  *ref);
gboolean           flatpak_decomposed_is_runtime            (FlatpakDecomposed  *ref);
FlatpakKinds       flatpak_decomposed_get_kinds             (FlatpakDecomposed  *ref);
FlatpakRefKind     flatpak_decomposed_get_kind              (FlatpakDecomposed  *ref);
const char *       flatpak_decomposed_get_kind_str          (FlatpakDecomposed  *ref);
const char *       flatpak_decomposed_get_kind_metadata_group(FlatpakDecomposed  *ref);
const char *       flatpak_decomposed_get_pref              (FlatpakDecomposed  *ref);
char *             flatpak_decomposed_dup_pref              (FlatpakDecomposed  *ref);
const char *       flatpak_decomposed_peek_id               (FlatpakDecomposed  *ref,
                                                             gsize              *out_len);
char *             flatpak_decomposed_dup_id                (FlatpakDecomposed  *ref);
char *             flatpak_decomposed_dup_readable_id       (FlatpakDecomposed  *ref);
gboolean           flatpak_decomposed_is_id                 (FlatpakDecomposed  *ref,
                                                             const char         *id);
gboolean           flatpak_decomposed_id_has_suffix         (FlatpakDecomposed  *ref,
                                                             const char         *suffix);
gboolean           flatpak_decomposed_id_has_prefix         (FlatpakDecomposed  *ref,
                                                             const char         *prefix);
gboolean           flatpak_decomposed_is_id_fuzzy           (FlatpakDecomposed  *ref,
                                                             const char         *id);
gboolean           flatpak_decomposed_id_is_subref          (FlatpakDecomposed  *ref);
gboolean           flatpak_decomposed_id_is_subref_of       (FlatpakDecomposed  *ref,
                                                             FlatpakDecomposed  *parent_ref);
const char *       flatpak_decomposed_peek_arch             (FlatpakDecomposed  *ref,
                                                             gsize              *out_len);
char *             flatpak_decomposed_dup_arch              (FlatpakDecomposed  *ref);
gboolean           flatpak_decomposed_is_arch               (FlatpakDecomposed  *ref,
                                                             const char         *arch);
gboolean           flatpak_decomposed_is_arches             (FlatpakDecomposed  *ref,
                                                             gssize              len,
                                                             const char        **arches);
const char *       flatpak_decomposed_peek_branch           (FlatpakDecomposed  *ref,
                                                             gsize              *out_len);
const char *       flatpak_decomposed_get_branch            (FlatpakDecomposed  *ref);
char *             flatpak_decomposed_dup_branch            (FlatpakDecomposed  *ref);
gboolean           flatpak_decomposed_is_branch             (FlatpakDecomposed  *ref,
                                                             const char         *branch);

G_DEFINE_AUTOPTR_CLEANUP_FUNC (FlatpakDecomposed, flatpak_decomposed_unref)

FlatpakKinds flatpak_kinds_from_bools (gboolean app,
                                       gboolean runtime);

gboolean flatpak_split_partial_ref_arg (const char   *partial_ref,
                                        FlatpakKinds  default_kinds,
                                        const char   *default_arch,
                                        const char   *default_branch,
                                        FlatpakKinds *out_kinds,
                                        char        **out_id,
                                        char        **out_arch,
                                        char        **out_branch,
                                        GError      **error);
gboolean flatpak_split_partial_ref_arg_novalidate (const char   *partial_ref,
                                                   FlatpakKinds  default_kinds,
                                                   const char   *default_arch,
                                                   const char   *default_branch,
                                                   FlatpakKinds *out_kinds,
                                                   char        **out_id,
                                                   char        **out_arch,
                                                   char        **out_branch);

int flatpak_compare_ref (const char *ref1,
                         const char *ref2);

char * flatpak_build_untyped_ref (const char *runtime,
                                  const char *branch,
                                  const char *arch);
char * flatpak_build_runtime_ref (const char *runtime,
                                  const char *branch,
                                  const char *arch);
char * flatpak_build_app_ref (const char *app,
                              const char *branch,
                              const char *arch);


#endif /* __FLATPAK_REF_UTILS_H__ */

===== ./common/flatpak-glib-backports-private.h =====
/*
 * Copyright 2013 Allison Karlitskaya
 * Copyright 2013 Collabora Ltd.
 * Copyright 2016 Canonical Ltd.
 * Copyright 2017-2018 Endless OS Foundation LLC
 * Copyright 2019 Red Hat, Inc
 * SPDX-License-Identifier: LGPL-2.1-or-later
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 */

#pragma once

#include "libglnx.h"

#include <glib.h>
#include <gio/gio.h>
#include <gio/gunixfdlist.h>

/* Please sort this file by the GLib version where it originated,
 * oldest first. */

G_BEGIN_DECLS

#if !GLIB_CHECK_VERSION (2, 40, 0)
static inline gboolean
g_key_file_save_to_file (GKeyFile    *key_file,
                         const gchar *filename,
                         GError     **error)
{
  gchar *contents;
  gboolean success;
  gsize length;

  g_return_val_if_fail (key_file != NULL, FALSE);
  g_return_val_if_fail (filename != NULL, FALSE);
  g_return_val_if_fail (error == NULL || *error == NULL, FALSE);

  contents = g_key_file_to_data (key_file, &length, NULL);
  g_assert (contents != NULL);

  success = g_file_set_contents (filename, contents, length, error);
  g_free (contents);

  return success;
}
#endif

#if !GLIB_CHECK_VERSION (2, 43, 4)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (GUnixFDList, g_object_unref)
#endif

#if !GLIB_CHECK_VERSION (2, 54, 0)
static inline gboolean
g_ptr_array_find_with_equal_func (GPtrArray     *haystack,
                                  gconstpointer  needle,
                                  GEqualFunc     equal_func,
                                  guint         *index_)
{
  guint i;

  g_return_val_if_fail (haystack != NULL, FALSE);

  if (equal_func == NULL)
    equal_func = g_direct_equal;

  for (i = 0; i < haystack->len; i++)
    {
      if (equal_func (g_ptr_array_index (haystack, i), needle))
        {
          if (index_ != NULL)
            *index_ = i;
          return TRUE;
        }
    }

  return FALSE;
}

/* We're non-specific about the error behaviour, so this is good enough */
#define G_NUMBER_PARSER_ERROR (G_IO_ERROR)
#define G_NUMBER_PARSER_ERROR_INVALID (G_IO_ERROR_INVALID_ARGUMENT)
#define G_NUMBER_PARSER_ERROR_OUT_OF_BOUNDS (G_IO_ERROR_INVALID_ARGUMENT)
#define GNumberParserError (GIOErrorEnum)

gboolean g_ascii_string_to_unsigned (const gchar *str,
                                     guint        base,
                                     guint64      min,
                                     guint64      max,
                                     guint64     *out_num,
                                     GError     **error);
#endif

#if !GLIB_CHECK_VERSION (2, 56, 0)
typedef void (* GClearHandleFunc) (guint handle_id);

static inline void
g_clear_handle_id (guint            *tag_ptr,
                   GClearHandleFunc  clear_func)
{
  guint _handle_id;

  _handle_id = *tag_ptr;
  if (_handle_id > 0)
    {
      *tag_ptr = 0;
      clear_func (_handle_id);
    }
}

GDateTime *flatpak_g_date_time_new_from_iso8601 (const gchar *text,
                                                 GTimeZone   *default_tz);

static inline GDateTime *
g_date_time_new_from_iso8601 (const gchar *text, GTimeZone *default_tz)
{
  return flatpak_g_date_time_new_from_iso8601 (text, default_tz);
}
#endif

#if !GLIB_CHECK_VERSION (2, 58, 0)
/* This is a reimplementation rather than a backport, and is a little less
 * efficient than the real g_hash_table_steal_extended(), since it can't
 * see into GHashTable internals */
static inline gboolean
g_hash_table_steal_extended (GHashTable    *hash_table,
                             gconstpointer  lookup_key,
                             gpointer      *stolen_key,
                             gpointer      *stolen_value)
{
  if (g_hash_table_lookup_extended (hash_table, lookup_key, stolen_key, stolen_value))
    {
      g_hash_table_steal (hash_table, lookup_key);
      return TRUE;
    }
  else
      return FALSE;
}
#endif

#if !GLIB_CHECK_VERSION (2, 58, 0)
const gchar * const *g_get_language_names_with_category (const gchar *category_name);
#endif

#if !GLIB_CHECK_VERSION (2, 62, 0)
void g_ptr_array_extend (GPtrArray        *array_to_extend,
                         GPtrArray        *array,
                         GCopyFunc         func,
                         gpointer          user_data);
#endif

#if !GLIB_CHECK_VERSION (2, 68, 0)
guint g_string_replace (GString     *string,
                        const gchar *find,
                        const gchar *replace,
                        guint        limit);
#endif

#ifndef G_DBUS_METHOD_INVOCATION_HANDLED    /* GLib < 2.68 */
# define G_DBUS_METHOD_INVOCATION_HANDLED TRUE
# define G_DBUS_METHOD_INVOCATION_UNHANDLED FALSE
#endif

#if !GLIB_CHECK_VERSION (2, 76, 0)
/* All this code is backported directly from 2.84.1 */
static inline gboolean
g_set_str (char       **str_pointer,
           const char  *new_str)
{
  char *copy;

  if (*str_pointer == new_str ||
      (*str_pointer && new_str && strcmp (*str_pointer, new_str) == 0))
    return FALSE;

  copy = g_strdup (new_str);
  g_free (*str_pointer);
  *str_pointer = copy;

  return TRUE;
}
#endif /* GLIB_CHECK_VERSION (2, 76, 0) */

G_END_DECLS

===== ./common/flatpak-run-pulseaudio-private.h =====
/*
 * Copyright © 2014 Red Hat, Inc
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Alexander Larsson <alexl@redhat.com>
 */

#pragma once

#include "libglnx.h"

#include "flatpak-bwrap-private.h"
#include "flatpak-common-types-private.h"
#include "flatpak-context-private.h"

G_BEGIN_DECLS

void flatpak_run_add_pulseaudio_args (FlatpakBwrap         *bwrap,
                                      FlatpakContextShares  shares);

G_END_DECLS

===== ./common/flatpak-bundle-ref.c =====
/* vi:set et sw=2 sts=2 cin cino=t0,f0,(0,{s,>2s,n-s,^-s,e-s:
 * Copyright © 2015 Red Hat, Inc
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Alexander Larsson <alexl@redhat.com>
 */

#include "config.h"

#include <string.h>

#include "flatpak-repo-utils-private.h"
#include "flatpak-utils-private.h"
#include "flatpak-bundle-ref.h"
#include "flatpak-enum-types.h"

/**
 * SECTION:flatpak-bundle-ref
 * @Title: FlatpakBundleRef
 * @Short_description: Application bundle reference
 *
 * A FlatpakBundleRef refers to a single-file bundle containing an
 * application or runtime.
 */

typedef struct _FlatpakBundleRefPrivate FlatpakBundleRefPrivate;

struct _FlatpakBundleRefPrivate
{
  GFile  *file;
  char   *origin;
  char   *runtime_repo;
  GBytes *metadata;
  GBytes *appstream;
  GBytes *icon_64;
  GBytes *icon_128;
  guint64 installed_size;
};

G_DEFINE_TYPE_WITH_PRIVATE (FlatpakBundleRef, flatpak_bundle_ref, FLATPAK_TYPE_REF)

enum {
  PROP_0,

  PROP_FILE,
};

static void
flatpak_bundle_ref_finalize (GObject *object)
{
  FlatpakBundleRef *self = FLATPAK_BUNDLE_REF (object);
  FlatpakBundleRefPrivate *priv = flatpak_bundle_ref_get_instance_private (self);

  g_clear_object (&priv->file);

  g_bytes_unref (priv->metadata);
  g_bytes_unref (priv->appstream);
  g_bytes_unref (priv->icon_64);
  g_bytes_unref (priv->icon_128);
  g_free (priv->origin);
  g_free (priv->runtime_repo);

  G_OBJECT_CLASS (flatpak_bundle_ref_parent_class)->finalize (object);
}

static void
flatpak_bundle_ref_set_property (GObject      *object,
                                 guint         prop_id,
                                 const GValue *value,
                                 GParamSpec   *pspec)
{
  FlatpakBundleRef *self = FLATPAK_BUNDLE_REF (object);
  FlatpakBundleRefPrivate *priv = flatpak_bundle_ref_get_instance_private (self);

  switch (prop_id)
    {
    case PROP_FILE:
      g_set_object (&priv->file, g_value_get_object (value));
      break;

    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
    }
}

static void
flatpak_bundle_ref_get_property (GObject    *object,
                                 guint       prop_id,
                                 GValue     *value,
                                 GParamSpec *pspec)
{
  FlatpakBundleRef *self = FLATPAK_BUNDLE_REF (object);
  FlatpakBundleRefPrivate *priv = flatpak_bundle_ref_get_instance_private (self);

  switch (prop_id)
    {
    case PROP_FILE:
      g_value_set_object (value, priv->file);
      break;

    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
    }
}

static void
flatpak_bundle_ref_class_init (FlatpakBundleRefClass *klass)
{
  GObjectClass *object_class = G_OBJECT_CLASS (klass);

  object_class->get_property = flatpak_bundle_ref_get_property;
  object_class->set_property = flatpak_bundle_ref_set_property;
  object_class->finalize = flatpak_bundle_ref_finalize;

  /**
   * FlatpakBundleRef:file:
   *
   * The bundle file that this ref refers to.
   */
  g_object_class_install_property (object_class,
                                   PROP_FILE,
                                   g_param_spec_object ("file",
                                                        "",
                                                        "",
                                                        G_TYPE_FILE,
                                                        G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
}

static void
flatpak_bundle_ref_init (FlatpakBundleRef *self)
{
}

/**
 * flatpak_bundle_ref_get_file:
 * @self: a #FlatpakBundleRef
 *
 * Get the file this bundle is stored in.
 *
 * Returns: (transfer full) : an #GFile
 */
GFile *
flatpak_bundle_ref_get_file (FlatpakBundleRef *self)
{
  FlatpakBundleRefPrivate *priv = flatpak_bundle_ref_get_instance_private (self);

  return g_object_ref (priv->file);
}

/**
 * flatpak_bundle_ref_get_metadata:
 * @self: a #FlatpakBundleRef
 *
 * Get the metadata for the app/runtime
 *
 * Returns: (transfer full) : an #GBytes with the metadata contents, or %NULL
 */
GBytes *
flatpak_bundle_ref_get_metadata (FlatpakBundleRef *self)
{
  FlatpakBundleRefPrivate *priv = flatpak_bundle_ref_get_instance_private (self);

  if (priv->metadata)
    return g_bytes_ref (priv->metadata);
  return NULL;
}

/**
 * flatpak_bundle_ref_get_appstream:
 * @self: a #FlatpakBundleRef
 *
 * Get the compressed appstream for the app/runtime
 *
 * Returns: (transfer full) : an #GBytes with the appstream contents, or %NULL
 */
GBytes *
flatpak_bundle_ref_get_appstream (FlatpakBundleRef *self)
{
  FlatpakBundleRefPrivate *priv = flatpak_bundle_ref_get_instance_private (self);

  if (priv->appstream)
    return g_bytes_ref (priv->appstream);
  return NULL;
}

/**
 * flatpak_bundle_ref_get_icon:
 * @self: a #FlatpakBundleRef
 * @size: 64 or 128
 *
 * Get the icon png data for the app/runtime
 *
 * Returns: (transfer full) : an #GBytes with png contents
 */
GBytes *
flatpak_bundle_ref_get_icon (FlatpakBundleRef *self,
                             int               size)
{
  FlatpakBundleRefPrivate *priv = flatpak_bundle_ref_get_instance_private (self);

  if (size == 64 && priv->icon_64)
    return g_bytes_ref (priv->icon_64);

  if (size == 128 && priv->icon_128)
    return g_bytes_ref (priv->icon_128);

  return NULL;
}

/**
 * flatpak_bundle_ref_get_origin:
 * @self: a #FlatpakBundleRef
 *
 * Get the origin url stored in the bundle
 *
 * Returns: (transfer full) : an url string, or %NULL
 */
char *
flatpak_bundle_ref_get_origin (FlatpakBundleRef *self)
{
  FlatpakBundleRefPrivate *priv = flatpak_bundle_ref_get_instance_private (self);

  return g_strdup (priv->origin);
}


/**
 * flatpak_bundle_ref_get_runtime_repo_url:
 * @self: a #FlatpakBundleRef
 *
 * Get the runtime flatpakrepo url stored in the bundle (if any)
 *
 * Returns: (transfer full) : an url string, or %NULL
 *
 * Since: 0.8.0
 */
char *
flatpak_bundle_ref_get_runtime_repo_url (FlatpakBundleRef *self)
{
  FlatpakBundleRefPrivate *priv = flatpak_bundle_ref_get_instance_private (self);

  return g_strdup (priv->runtime_repo);
}

/**
 * flatpak_bundle_ref_get_installed_size:
 * @self: a FlatpakBundleRef
 *
 * Returns the installed size for the bundle.
 *
 * Returns: the installed size
 */
guint64
flatpak_bundle_ref_get_installed_size (FlatpakBundleRef *self)
{
  FlatpakBundleRefPrivate *priv = flatpak_bundle_ref_get_instance_private (self);

  return priv->installed_size;
}

/**
 * flatpak_bundle_ref_new:
 * @file: a #GFile
 * @error: (allow-none): return location for an error
 *
 * Creates a new bundle ref for the given file.
 *
 * Returns: a new bundle ref.
 */
FlatpakBundleRef *
flatpak_bundle_ref_new (GFile   *file,
                        GError **error)
{
  FlatpakRefKind kind;
  FlatpakBundleRefPrivate *priv;
  FlatpakBundleRef *ref;
  g_autoptr(GVariant) metadata = NULL;
  g_autofree char *commit = NULL;
  g_autofree char *id = NULL;
  g_autofree char *arch = NULL;
  g_autofree char *branch = NULL;
  g_autoptr(FlatpakDecomposed) full_ref = NULL;
  g_autofree char *origin = NULL;
  g_autofree char *runtime_repo = NULL;
  g_autofree char *metadata_contents = NULL;
  g_autoptr(GVariant) appstream = NULL;
  g_autoptr(GVariant) icon_64 = NULL;
  g_autoptr(GVariant) icon_128 = NULL;
  guint64 installed_size;
  g_autofree char *collection_id = NULL;

  metadata = flatpak_bundle_load (file, &commit, &full_ref, &origin, &runtime_repo, &metadata_contents, &installed_size,
                                  NULL, &collection_id, error);
  if (metadata == NULL)
    return NULL;

  kind = flatpak_decomposed_get_kind (full_ref);
  id = flatpak_decomposed_dup_id (full_ref);
  arch = flatpak_decomposed_dup_arch (full_ref);
  branch = flatpak_decomposed_dup_branch (full_ref);

  ref = g_object_new (FLATPAK_TYPE_BUNDLE_REF,
                      "kind", kind,
                      "name", id,
                      "arch", arch,
                      "branch", branch,
                      "commit", commit,
                      "file", file,
                      "collection-id", collection_id,
                      NULL);
  priv = flatpak_bundle_ref_get_instance_private (ref);

  if (metadata_contents)
    priv->metadata = g_bytes_new_take (metadata_contents,
                                       strlen (metadata_contents));
  metadata_contents = NULL; /* Stolen */

  appstream = g_variant_lookup_value (metadata, "appdata", G_VARIANT_TYPE_BYTESTRING);
  if (appstream)
    priv->appstream = g_variant_get_data_as_bytes (appstream);

  icon_64 = g_variant_lookup_value (metadata, "icon-64", G_VARIANT_TYPE_BYTESTRING);
  if (icon_64)
    priv->icon_64 = g_variant_get_data_as_bytes (icon_64);

  icon_128 = g_variant_lookup_value (metadata, "icon-128", G_VARIANT_TYPE_BYTESTRING);
  if (icon_128)
    priv->icon_128 = g_variant_get_data_as_bytes (icon_128);

  priv->installed_size = installed_size;

  priv->origin = g_steal_pointer (&origin);
  priv->runtime_repo = g_steal_pointer (&runtime_repo);

  return ref;
}

===== ./common/flatpak-installed-ref.h =====
/*
 * Copyright © 2015 Red Hat, Inc
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Alexander Larsson <alexl@redhat.com>
 */

#if !defined(__FLATPAK_H_INSIDE__) && !defined(FLATPAK_COMPILATION)
#error "Only <flatpak.h> can be included directly."
#endif

#ifndef __FLATPAK_INSTALLED_REF_H__
#define __FLATPAK_INSTALLED_REF_H__

typedef struct _FlatpakInstalledRef FlatpakInstalledRef;

#include <gio/gio.h>
#include <flatpak-ref.h>

G_BEGIN_DECLS

#define FLATPAK_TYPE_INSTALLED_REF flatpak_installed_ref_get_type ()
#define FLATPAK_INSTALLED_REF(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), FLATPAK_TYPE_INSTALLED_REF, FlatpakInstalledRef))
#define FLATPAK_IS_INSTALLED_REF(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), FLATPAK_TYPE_INSTALLED_REF))

FLATPAK_EXTERN GType flatpak_installed_ref_get_type (void);

struct _FlatpakInstalledRef
{
  FlatpakRef parent;
};

typedef struct
{
  FlatpakRefClass parent_class;
} FlatpakInstalledRefClass;

#ifdef G_DEFINE_AUTOPTR_CLEANUP_FUNC
G_DEFINE_AUTOPTR_CLEANUP_FUNC (FlatpakInstalledRef, g_object_unref)
#endif

FLATPAK_EXTERN const char  *flatpak_installed_ref_get_origin (FlatpakInstalledRef  * self);
FLATPAK_EXTERN const char * const *flatpak_installed_ref_get_subpaths (FlatpakInstalledRef *self);
FLATPAK_EXTERN guint64      flatpak_installed_ref_get_installed_size (FlatpakInstalledRef *self);
FLATPAK_EXTERN const char  *flatpak_installed_ref_get_deploy_dir (FlatpakInstalledRef *self);
FLATPAK_EXTERN const char  *flatpak_installed_ref_get_latest_commit (FlatpakInstalledRef *self);
FLATPAK_EXTERN const char  *flatpak_installed_ref_get_appdata_name (FlatpakInstalledRef *self);
FLATPAK_EXTERN const char  *flatpak_installed_ref_get_appdata_summary (FlatpakInstalledRef *self);
FLATPAK_EXTERN const char  *flatpak_installed_ref_get_appdata_version (FlatpakInstalledRef *self);
FLATPAK_EXTERN const char  *flatpak_installed_ref_get_appdata_license (FlatpakInstalledRef *self);
FLATPAK_EXTERN const char  *flatpak_installed_ref_get_appdata_content_rating_type (FlatpakInstalledRef *self);
FLATPAK_EXTERN GHashTable  *flatpak_installed_ref_get_appdata_content_rating (FlatpakInstalledRef *self);
FLATPAK_EXTERN gboolean     flatpak_installed_ref_get_is_current (FlatpakInstalledRef *self);
FLATPAK_EXTERN GBytes      *flatpak_installed_ref_load_metadata (FlatpakInstalledRef *self,
                                                                 GCancellable        *cancellable,
                                                                 GError             **error);
FLATPAK_EXTERN GBytes      *flatpak_installed_ref_load_appdata (FlatpakInstalledRef *self,
                                                                GCancellable        *cancellable,
                                                                GError             **error);
FLATPAK_EXTERN const char * flatpak_installed_ref_get_eol (FlatpakInstalledRef *self);
FLATPAK_EXTERN const char * flatpak_installed_ref_get_eol_rebase (FlatpakInstalledRef *self);

G_END_DECLS

#endif /* __FLATPAK_INSTALLED_REF_H__ */

===== ./common/flatpak-image-collection.c =====
/* vi:set et sw=2 sts=2 cin cino=t0,f0,(0,{s,>2s,n-s,^-s,e-s:
 * Copyright © 2024 Red Hat, Inc
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Owen Taylor <otaylor@redhat.com>
 */

#include <glib/gi18n-lib.h>

#include "flatpak-image-collection-private.h"
#include "flatpak-oci-registry-private.h"

struct FlatpakImageCollection
{
  GObject parent;

  GPtrArray *sources;
};

typedef struct
{
  GObjectClass parent_class;
} FlatpakImageCollectionClass;

G_DEFINE_TYPE (FlatpakImageCollection, flatpak_image_collection, G_TYPE_OBJECT)


static void
flatpak_image_collection_finalize (GObject *object)
{
  FlatpakImageCollection *self = FLATPAK_IMAGE_COLLECTION (object);

  g_ptr_array_free (self->sources, TRUE);

  G_OBJECT_CLASS (flatpak_image_collection_parent_class)->finalize (object);
}

static void
flatpak_image_collection_class_init (FlatpakImageCollectionClass *klass)
{
  GObjectClass *object_class = G_OBJECT_CLASS (klass);

  object_class->finalize = flatpak_image_collection_finalize;
}

static void
flatpak_image_collection_init (FlatpakImageCollection *self)
{
  self->sources = g_ptr_array_new_with_free_func ((GDestroyNotify)g_object_unref);
}

FlatpakImageCollection *
flatpak_image_collection_new (const char   *location,
                              GCancellable *cancellable,
                              GError      **error)
{
  g_autoptr(FlatpakImageCollection) self = NULL;
  g_autoptr(FlatpakOciRegistry) registry = NULL;
  g_autoptr(FlatpakOciIndex) index = NULL;
  gsize i;

  self = g_object_new (FLATPAK_TYPE_IMAGE_COLLECTION, NULL);

  if (g_str_has_prefix (location, "oci:"))
    {
      g_autoptr(GFile) dir = g_file_new_for_path (location + 4);
      g_autofree char *uri = g_file_get_uri (dir);

      registry = flatpak_oci_registry_new (uri, FALSE, -1, cancellable, error);
      if (registry == NULL)
        return NULL;
    }
  else if (g_str_has_prefix (location, "oci-archive:"))
    {
      g_autoptr(GFile) file = g_file_new_for_path (location + 12);
      registry = flatpak_oci_registry_new_for_archive (file, cancellable, error);
      if (registry == NULL)
        return NULL;
    }
  else
    {
      flatpak_fail (error, "Can't parse image collection location %s", location);
      return NULL;
    }

  index = flatpak_oci_registry_load_index (registry, cancellable, error);
  if (index == NULL)
    return NULL;

  for (i = 0; index->manifests[i] != NULL; i++)
    {
      g_autoptr(GError) local_error = NULL;
      FlatpakOciManifestDescriptor *descriptor = index->manifests[i];
      g_autoptr(FlatpakImageSource) image_source = flatpak_image_source_new (registry, NULL,
                                                                             descriptor->parent.digest,
                                                                             cancellable, &local_error);
      if (image_source == NULL)
        {
          g_info ("Can't load manifest in image collection: %s", local_error->message);
          continue;
        }

      g_ptr_array_add (self->sources, g_steal_pointer (&image_source));
    }

  return g_steal_pointer (&self);
}

FlatpakImageSource *
flatpak_image_collection_lookup_ref (FlatpakImageCollection *self,
                                     const char             *ref)
{
  for (guint i = 0; i < self->sources->len; i++)
    {
      FlatpakImageSource *source = g_ptr_array_index (self->sources, i);
      if (strcmp (flatpak_image_source_get_ref (source), ref) == 0)
        return g_object_ref (source);
    }

  return NULL;
}

FlatpakImageSource *
flatpak_image_collection_lookup_digest (FlatpakImageCollection *self,
                                        const char             *digest)
{
  for (guint i = 0; i < self->sources->len; i++)
    {
      FlatpakImageSource *source = g_ptr_array_index (self->sources, i);
      if (strcmp (flatpak_image_source_get_digest (source), digest) == 0)
        return g_object_ref (source);
    }

  return NULL;
}

GPtrArray *
flatpak_image_collection_get_sources (FlatpakImageCollection *self)
{
  return g_ptr_array_ref (self->sources);
}

===== ./common/flatpak-dir.c =====
/* vi:set et sw=2 sts=2 cin cino=t0,f0,(0,{s,>2s,n-s,^-s,e-s:
 *
 * Copyright © 2014-2019 Red Hat, Inc
 * Copyright © 2017 Endless Mobile, Inc.
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Alexander Larsson <alexl@redhat.com>
 *       Philip Withnall <withnall@endlessm.com>
 *       Matthew Leeds <matthew.leeds@endlessm.com>
 */

#include "config.h"

#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <sys/file.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <utime.h>

#include <glib/gi18n-lib.h>
#include <glib/gstdio.h>

#include <libxml/parser.h>
#include <libxml/tree.h>

#include <gio/gio.h>
#include <gio/gunixsocketaddress.h>
#include <ostree.h>

#ifdef USE_SYSTEM_HELPER
#include <polkit/polkit.h>
#endif

#include "flatpak-appdata-private.h"
#include "flatpak-dir-private.h"
#include "flatpak-dir-utils-private.h"
#include "flatpak-error.h"
#include "flatpak-locale-utils-private.h"
#include "flatpak-image-collection-private.h"
#include "flatpak-image-source-private.h"
#include "flatpak-oci-registry-private.h"
#include "flatpak-ref.h"
#include "flatpak-repo-utils-private.h"
#include "flatpak-run-private.h"
#include "flatpak-utils-base-private.h"
#include "flatpak-variant-private.h"
#include "flatpak-variant-impl-private.h"
#include "flatpak-xml-utils-private.h"
#include "libglnx.h"
#include "system-helper/flatpak-system-helper.h"

#ifdef HAVE_LIBMALCONTENT
#include <libmalcontent/malcontent.h>
#include "flatpak-parental-controls-private.h"
#endif

#ifdef HAVE_LIBSYSTEMD
#define SD_JOURNAL_SUPPRESS_LOCATION
#include <systemd/sd-journal.h>
#endif

#define NO_SYSTEM_HELPER ((FlatpakSystemHelper *) (gpointer) 1)

#define SUMMARY_CACHE_TIMEOUT_SEC (60 * 5)
#define FILTER_MTIME_CHECK_TIMEOUT_MSEC 500

#define SYSCONF_INSTALLATIONS_DIR "installations.d"
#define SYSCONF_INSTALLATIONS_FILE_EXT ".conf"

#define FLATPAK_REMOTES_DIR "remotes.d"
#define FLATPAK_REMOTES_FILE_EXT ".flatpakrepo"

#define FLATPAK_PREINSTALL_DIR "preinstall.d"
#define FLATPAK_PREINSTALL_FILE_EXT ".preinstall"

#define FLATPAK_PREINSTALL_GROUP_PREFIX "Flatpak Preinstall "
#define FLATPAK_PREINSTALL_IS_RUNTIME_KEY "IsRuntime"
#define FLATPAK_PREINSTALL_NAME_KEY "Name"
#define FLATPAK_PREINSTALL_BRANCH_KEY "Branch"
#define FLATPAK_PREINSTALL_COLLECTION_ID_KEY "CollectionID"
#define FLATPAK_PREINSTALL_INSTALL_KEY "Install"

#define SIDELOAD_REPOS_DIR_NAME "sideload-repos"

#define FLATPAK_TRIGGERS_DIR "triggers"

#ifdef USE_SYSTEM_HELPER
/* This uses a weird Auto prefix to avoid conflicts with later added polkit types.
 */
typedef PolkitAuthority           AutoPolkitAuthority;
typedef PolkitAuthorizationResult AutoPolkitAuthorizationResult;
typedef PolkitDetails             AutoPolkitDetails;
typedef PolkitSubject             AutoPolkitSubject;

G_DEFINE_AUTOPTR_CLEANUP_FUNC (AutoPolkitAuthority, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (AutoPolkitAuthorizationResult, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (AutoPolkitDetails, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (AutoPolkitSubject, g_object_unref)
#endif

static FlatpakOciRegistry *flatpak_dir_create_system_child_oci_registry (FlatpakDir   *self,
                                                                         GLnxLockFile *file_lock,
                                                                         const char   *token,
                                                                         GError      **error);

static OstreeRepo * flatpak_dir_create_child_repo (FlatpakDir   *self,
                                                   GFile        *cache_dir,
                                                   GLnxLockFile *file_lock,
                                                   const char   *optional_commit,
                                                   GError      **error);
static OstreeRepo * flatpak_dir_create_system_child_repo (FlatpakDir   *self,
                                                          GLnxLockFile *file_lock,
                                                          const char   *optional_commit,
                                                          GError      **error);

static gboolean flatpak_dir_mirror_oci (FlatpakDir          *self,
                                        FlatpakOciRegistry  *dst_registry,
                                        FlatpakRemoteState  *state,
                                        const char          *ref,
                                        const char          *opt_rev,
                                        FlatpakImageSource  *opt_image_source,
                                        const char          *token,
                                        FlatpakProgress     *progress,
                                        GCancellable        *cancellable,
                                        GError             **error);

static gboolean flatpak_dir_remote_fetch_summary (FlatpakDir   *self,
                                                  const char   *name,
                                                  gboolean      only_cached,
                                                  GBytes      **out_summary,
                                                  GBytes      **out_summary_sig,
                                                  GCancellable *cancellable,
                                                  GError      **error);

static gboolean flatpak_dir_remote_fetch_summary_index (FlatpakDir   *self,
                                                        const char   *name_or_uri,
                                                        gboolean      only_cached,
                                                        GBytes      **out_index,
                                                        GBytes      **out_index_sig,
                                                        GCancellable *cancellable,
                                                        GError      **error);

static gboolean flatpak_dir_remote_fetch_indexed_summary (FlatpakDir   *self,
                                                          const char   *name_or_uri,
                                                          const char   *arch,
                                                          GVariant     *subsummary_info_v,
                                                          gboolean      only_cached,
                                                          GBytes      **out_summary,
                                                          GCancellable *cancellable,
                                                          GError      **error);

static gboolean flatpak_dir_gc_cached_digested_summaries (FlatpakDir   *self,
                                                          const char   *remote_name,
                                                          const char   *dont_prune_file,
                                                          GCancellable *cancellable,
                                                          GError      **error);

static gboolean flatpak_dir_cleanup_remote_for_url_change (FlatpakDir   *self,
                                                           const char   *remote_name,
                                                           const char   *url,
                                                           GCancellable *cancellable,
                                                           GError      **error);

static gboolean flatpak_dir_lookup_remote_filter (FlatpakDir *self,
                                                  const char *name,
                                                  gboolean    force_load,
                                                  char      **checksum_out,
                                                  GRegex    **allow_regex,
                                                  GRegex    **deny_regex,
                                                  GError **error);

static char *flatpak_dir_get_remote_signature_lookaside (FlatpakDir *self,
                                                         const char *remote_name);

static void ensure_http_session (FlatpakDir *self);

static void flatpak_dir_log (FlatpakDir *self,
                             const char *file,
                             int         line,
                             const char *func,
                             const char *source,
                             const char *change,
                             const char *remote,
                             const char *ref,
                             const char *commit,
                             const char *old_commit,
                             const char *url,
                             const char *format,
                             ...) G_GNUC_PRINTF (12, 13);

#define flatpak_dir_log(self, change, remote, ref, commit, old_commit, url, format, ...) \
  (flatpak_dir_log) (self, __FILE__, __LINE__, __FUNCTION__, \
                     NULL, change, remote, ref, commit, old_commit, url, format, __VA_ARGS__)

static GBytes *upgrade_deploy_data (GBytes             *deploy_data,
                                    GFile              *deploy_dir,
                                    FlatpakDecomposed  *ref,
                                    OstreeRepo         *repo,
                                    GCancellable       *cancellable,
                                    GError            **error);

typedef struct
{
  GBytes *bytes;
  GBytes *bytes_sig;
  char   *name;
  char   *url;
  guint64 time;
} CachedSummary;

typedef struct
{
  char                 *id;
  char                 *display_name;
  gint                  priority;
  FlatpakDirStorageType storage_type;
} DirExtraData;

typedef struct {
  GFile *path;
  GTimeVal mtime;
  guint64 last_mtime_check;
  char *checksum;
  GRegex *allow;
  GRegex *deny;
} RemoteFilter;

struct FlatpakDir
{
  GObject          parent;

  gboolean         user;
  GFile           *basedir;
  DirExtraData    *extra_data;
  OstreeRepo      *repo;
  GFile           *cache_dir;
  gboolean         no_system_helper;
  gboolean         no_interaction;
  PolkitSubject   *subject;

  GDBusConnection *system_helper_bus;

  GHashTable      *summary_cache;

  GHashTable      *remote_filters;

  /* Config cache, protected by config_cache lock */
  GRegex          *masked;
  GRegex          *pinned;

  FlatpakHttpSession *http_session;
};

G_LOCK_DEFINE_STATIC (config_cache);

typedef struct
{
  GObjectClass parent_class;
} FlatpakDirClass;

struct FlatpakDeploy
{
  GObject            parent;

  FlatpakDecomposed *ref;
  GFile             *dir;
  GKeyFile          *metadata;
  FlatpakContext    *system_overrides;
  FlatpakContext    *user_overrides;
  FlatpakContext    *system_app_overrides;
  FlatpakContext    *user_app_overrides;
  OstreeRepo        *repo;
};

typedef struct
{
  GObjectClass parent_class;
} FlatpakDeployClass;

G_DEFINE_TYPE (FlatpakDir, flatpak_dir, G_TYPE_OBJECT)
G_DEFINE_TYPE (FlatpakDeploy, flatpak_deploy, G_TYPE_OBJECT)

enum {
  PROP_0,

  PROP_USER,
  PROP_PATH
};

#define OSTREE_GIO_FAST_QUERYINFO ("standard::name,standard::type,standard::size,standard::is-symlink,standard::symlink-target," \
                                   "unix::device,unix::inode,unix::mode,unix::uid,unix::gid,unix::rdev")

static const char *
get_config_dir_location (void)
{
  static gsize path = 0;

  if (g_once_init_enter (&path))
    {
      gsize setup_value = 0;
      const char *config_dir = g_getenv ("FLATPAK_CONFIG_DIR");
      if (config_dir != NULL)
        setup_value = (gsize) config_dir;
      else
        setup_value = (gsize) FLATPAK_CONFIGDIR;
      g_once_init_leave (&path, setup_value);
    }

  return (const char *) path;
}

static const char *
get_data_dir_location (void)
{
  static gsize path = 0;

  if (g_once_init_enter (&path))
    {
      gsize setup_value = 0;
      const char *data_dir = g_getenv ("FLATPAK_DATA_DIR");
      if (data_dir != NULL)
        setup_value = (gsize) data_dir;
      else
        setup_value = (gsize) FLATPAK_DATADIR;
      g_once_init_leave (&path, setup_value);
    }

  return (const char *) path;
}

static const char *
get_run_dir_location (void)
{
  static gsize path = 0;

  if (g_once_init_enter (&path))
    {
      gsize setup_value = 0;
      /* Note: $FLATPAK_RUN_DIR should only be set in the unit tests. At
       * runtime, /run/flatpak is assumed by
       * flatpak-create-sideload-symlinks.sh
       */
      const char *config_dir = g_getenv ("FLATPAK_RUN_DIR");
      if (config_dir != NULL)
        setup_value = (gsize) config_dir;
      else
        setup_value = (gsize) "/run/flatpak";
      g_once_init_leave (&path, setup_value);
    }

  return (const char *) path;
}

static void
flatpak_sideload_state_free (FlatpakSideloadState *sideload_state)
{
  g_object_unref (sideload_state->repo);
  g_variant_unref (sideload_state->summary);
  g_free (sideload_state);
}

static void
variant_maybe_unref (GVariant *variant)
{
  if (variant)
    g_variant_unref (variant);
}

static FlatpakRemoteState *
flatpak_remote_state_new (void)
{
  FlatpakRemoteState *state = g_new0 (FlatpakRemoteState, 1);

  state->refcount = 1;
  state->sideload_repos = g_ptr_array_new_with_free_func ((GDestroyNotify)flatpak_sideload_state_free);
  state->sideload_image_collections = g_ptr_array_new_with_free_func ((GDestroyNotify)g_object_unref);
  state->subsummaries = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify)variant_maybe_unref);
  return state;
}

FlatpakRemoteState *
flatpak_remote_state_ref (FlatpakRemoteState *remote_state)
{
  g_assert (remote_state->refcount > 0);
  remote_state->refcount++;
  return remote_state;
}

void
flatpak_remote_state_unref (FlatpakRemoteState *remote_state)
{
  g_assert (remote_state->refcount > 0);
  remote_state->refcount--;

  if (remote_state->refcount == 0)
    {
      g_free (remote_state->remote_name);
      g_free (remote_state->collection_id);
      g_clear_pointer (&remote_state->index, g_variant_unref);
      g_clear_pointer (&remote_state->index_ht, g_hash_table_unref);
      g_clear_pointer (&remote_state->index_sig_bytes, g_bytes_unref);
      g_clear_pointer (&remote_state->subsummaries, g_hash_table_unref);
      g_clear_pointer (&remote_state->summary, g_variant_unref);
      g_clear_pointer (&remote_state->summary_bytes, g_bytes_unref);
      g_clear_pointer (&remote_state->summary_sig_bytes, g_bytes_unref);
      g_clear_error (&remote_state->summary_fetch_error);
      g_clear_pointer (&remote_state->allow_refs, g_regex_unref);
      g_clear_pointer (&remote_state->deny_refs, g_regex_unref);
      g_clear_pointer (&remote_state->sideload_repos, g_ptr_array_unref);
      g_clear_pointer (&remote_state->sideload_image_collections, g_ptr_array_unref);

      g_free (remote_state);
    }
}

static gboolean
_validate_summary_for_collection_id (GVariant    *summary_v,
                                     const char  *collection_id,
                                     GError     **error)
{
  VarSummaryRef summary;
  summary = var_summary_from_gvariant (summary_v);

  if (!flatpak_summary_find_ref_map (summary, collection_id, NULL))
    return flatpak_fail_error (error, FLATPAK_ERROR_INVALID_DATA,
                               _("Configured collection ID ‘%s’ not in summary file"), collection_id);

  return TRUE;
}

static void
flatpak_remote_state_add_sideload_repo (FlatpakRemoteState *self,
                                        GFile *dir)
{
  g_autoptr(GFile) summary_path = NULL;
  g_autoptr(GMappedFile) mfile = NULL;
  g_autoptr(OstreeRepo) sideload_repo = NULL;

  /* Sideloading only works if collection id is set */
  if (self->collection_id == NULL)
    return;

  summary_path = g_file_get_child (dir, "summary");
  sideload_repo = ostree_repo_new (dir);

  mfile = g_mapped_file_new (flatpak_file_get_path_cached (summary_path), FALSE, NULL);
  if (mfile != NULL && ostree_repo_open (sideload_repo, NULL, NULL))
    {
      g_autoptr(GError) local_error = NULL;
      g_autoptr(GBytes) summary_bytes = g_mapped_file_get_bytes (mfile);
      FlatpakSideloadState *ss = g_new0 (FlatpakSideloadState, 1);

      ss->repo = g_steal_pointer (&sideload_repo);
      ss->summary = g_variant_ref_sink (g_variant_new_from_bytes (OSTREE_SUMMARY_GVARIANT_FORMAT, summary_bytes, TRUE));

      if (!_validate_summary_for_collection_id (ss->summary, self->collection_id, &local_error))
        {
          /* We expect to hit this code path when the repo is providing things
           * from other remotes
           */
          g_info ("Sideload repo at path %s not valid for remote %s: %s",
                  flatpak_file_get_path_cached (dir), self->remote_name, local_error->message);
          flatpak_sideload_state_free (ss);
        }
      else
        {
          g_ptr_array_add (self->sideload_repos, ss);
          g_info ("Using sideloaded repo %s for remote %s", flatpak_file_get_path_cached (dir), self->remote_name);
        }
    }
}

void
flatpak_remote_state_add_sideload_image_collection (FlatpakRemoteState     *self,
                                                    FlatpakImageCollection *image_collection)
{
  g_ptr_array_add (self->sideload_image_collections, g_object_ref (image_collection));
}

static void add_sideload_subdirs (GPtrArray *res,
                                  GFile     *parent,
                                  gboolean   recurse);

static void
add_sideload_create_usb_subdirs (GPtrArray *res,
                                 GFile     *parent)
{
  g_autoptr(GFile) ostree_repo_subpath = NULL;
  g_autoptr(GFile) dot_ostree_repo_subpath = NULL;
  g_autoptr(GFile) dot_ostree_repo_d_subpath = NULL;
  g_autoptr(OstreeRepo) ostree_repo_subpath_repo = NULL;
  g_autoptr(OstreeRepo) dot_ostree_repo_subpath_repo = NULL;

  /* This path is not used by "flatpak create-usb" but it's a standard location
   * recognized by libostree; see the man page ostree create-usb(1)
   */
  ostree_repo_subpath = g_file_resolve_relative_path (parent, "ostree/repo");
  ostree_repo_subpath_repo = ostree_repo_new (ostree_repo_subpath);
  if (ostree_repo_open (ostree_repo_subpath_repo, NULL, NULL))
    g_ptr_array_add (res, g_object_ref (ostree_repo_subpath));

  /* These paths are used by "flatpak create-usb" */
  dot_ostree_repo_subpath = g_file_resolve_relative_path (parent, ".ostree/repo");
  dot_ostree_repo_subpath_repo = ostree_repo_new (dot_ostree_repo_subpath);
  if (ostree_repo_open (dot_ostree_repo_subpath_repo, NULL, NULL))
    g_ptr_array_add (res, g_object_ref (dot_ostree_repo_subpath));

  dot_ostree_repo_d_subpath = g_file_resolve_relative_path (parent, ".ostree/repos.d");
  add_sideload_subdirs (res, dot_ostree_repo_d_subpath, FALSE);
}

static void
add_sideload_subdirs (GPtrArray *res,
                      GFile     *parent,
                      gboolean   recurse)
{
  g_autoptr(GFileEnumerator) dir_enum = NULL;

  dir_enum = g_file_enumerate_children (parent,
                                        G_FILE_ATTRIBUTE_STANDARD_NAME ","
                                        G_FILE_ATTRIBUTE_STANDARD_TYPE,
                                        G_FILE_QUERY_INFO_NONE,
                                        NULL, NULL);
  if (dir_enum == NULL)
    return;

  while (TRUE)
    {
      GFileInfo *info;
      GFile *path;

      if (!g_file_enumerator_iterate (dir_enum, &info, &path, NULL, NULL) ||
          info == NULL)
        break;

      /* Here we support either a plain repo or, if @recurse is TRUE, the root
       * directory of a USB created with "flatpak create-usb"
       */
      if (g_file_info_get_file_type (info) == G_FILE_TYPE_DIRECTORY)
        {
          g_autoptr(OstreeRepo) repo = ostree_repo_new (path);

          if (ostree_repo_open (repo, NULL, NULL))
            g_ptr_array_add (res, g_object_ref (path));
          else if (recurse)
            add_sideload_create_usb_subdirs (res, path);
        }
    }
}

void
flatpak_remote_state_add_sideload_dir (FlatpakRemoteState *self,
                                       GFile              *dir)
{
  g_autoptr(GPtrArray) sideload_paths = g_ptr_array_new_with_free_func (g_object_unref);

  /* The directory could be a repo */
  flatpak_remote_state_add_sideload_repo (self, dir);

  /* Or it could be a directory with repos in well-known subdirectories */
  add_sideload_create_usb_subdirs (sideload_paths, dir);
  for (int i = 0; i < sideload_paths->len; i++)
    flatpak_remote_state_add_sideload_repo (self, g_ptr_array_index (sideload_paths, i));
}

gboolean
flatpak_remote_state_ensure_summary (FlatpakRemoteState *self,
                                     GError            **error)
{
  if (self->index == NULL && self->summary == NULL)
    return flatpak_fail_error (error, FLATPAK_ERROR_INVALID_DATA, _("Unable to load summary from remote %s: %s"), self->remote_name,
                               self->summary_fetch_error != NULL ? self->summary_fetch_error->message : "unknown error");

  return TRUE;
}

gboolean
flatpak_remote_state_ensure_subsummary (FlatpakRemoteState *self,
                                        FlatpakDir         *dir,
                                        const char         *arch,
                                        gboolean            only_cached,
                                        GCancellable       *cancellable,
                                        GError            **error)
{
  GVariant *subsummary;
  const char *alt_arch;
  GVariant *subsummary_info_v;

  g_autoptr(GBytes) bytes = NULL;

  g_return_val_if_fail (arch != NULL, FALSE);

  if (self->summary != NULL)
    return TRUE; /* We have them all anyway */

  if (self->index == NULL)
    return TRUE; /* Don't fail unnecessarily in e.g. the sideload case */

  if (g_hash_table_contains (self->subsummaries, arch))
    return TRUE;

  /* If i.e. we already loaded x86_64 subsummary (which has i386 refs),
   * don't load i386 one */
  alt_arch = flatpak_get_compat_arch_reverse (arch);
  if (alt_arch != NULL &&
      g_hash_table_contains (self->subsummaries, alt_arch))
    return TRUE;

  subsummary_info_v = g_hash_table_lookup (self->index_ht, arch);
  if (subsummary_info_v == NULL)
    return TRUE; /* No refs for this arch */

  if (!flatpak_dir_remote_fetch_indexed_summary (dir, self->remote_name, arch, subsummary_info_v, only_cached,
                                                 &bytes, cancellable, error))
    return FALSE;

  subsummary = g_variant_ref_sink (g_variant_new_from_bytes (OSTREE_SUMMARY_GVARIANT_FORMAT, bytes, FALSE));
  g_hash_table_insert (self->subsummaries, g_strdup (arch), subsummary);

  return TRUE;
}

gboolean
flatpak_remote_state_ensure_subsummary_all_arches (FlatpakRemoteState *self,
                                                   FlatpakDir         *dir,
                                                   gboolean            only_cached,
                                                   GCancellable       *cancellable,
                                                   GError            **error)
{
  if (self->index_ht == NULL)
    return TRUE; /* No subsummaries, got all arches anyway */

  GLNX_HASH_TABLE_FOREACH (self->index_ht, const char *, arch)
    {
      g_autoptr(GError) local_error = NULL;

      if (!flatpak_remote_state_ensure_subsummary (self, dir, arch, only_cached, cancellable, &local_error))
        {
          /* Don't error on non-cached subsummaries */
          if (only_cached && g_error_matches (local_error, FLATPAK_ERROR, FLATPAK_ERROR_NOT_CACHED))
            continue;

          g_propagate_error (error, g_steal_pointer (&local_error));
          return FALSE;
        }
    }

  return TRUE;
}


gboolean
flatpak_remote_state_allow_ref (FlatpakRemoteState *self,
                                const char *ref)
{
  return flatpak_filters_allow_ref (self->allow_refs, self->deny_refs, ref);
}


static guint64
get_timestamp_from_ref_info (VarRefInfoRef info)
{
  VarMetadataRef metadata = var_ref_info_get_metadata (info);
  return GUINT64_FROM_BE(var_metadata_lookup_uint64 (metadata, OSTREE_COMMIT_TIMESTAMP, 0));
 }


void
flatpak_remote_state_lookup_sideload_checksum (FlatpakRemoteState   *self,
                                               char                 *checksum,
                                               GFile               **out_sideload_path,
                                               FlatpakImageSource  **out_image_source)
{
  if (out_sideload_path)
    *out_sideload_path = NULL;
  if (out_image_source)
    *out_image_source = NULL;

  if (self->is_oci && out_image_source)
    {
      g_autofree char *digest = g_strconcat ("sha256:", checksum, NULL);

      for (int i = 0; i < self->sideload_image_collections->len; i++)
        {
          FlatpakImageCollection *collection = g_ptr_array_index (self->sideload_image_collections, i);
          g_autoptr(FlatpakImageSource) image_source = flatpak_image_collection_lookup_digest (collection, digest);
          if (image_source)
            {
              *out_image_source = g_steal_pointer (&image_source);
              return;
            }
        }
    }
  else if (!self->is_oci && out_sideload_path)
    {
      for (int i = 0; i < self->sideload_repos->len; i++)
        {
          FlatpakSideloadState *ss = g_ptr_array_index (self->sideload_repos, i);
          OstreeRepoCommitState commit_state;

          if (ostree_repo_load_commit (ss->repo, checksum, NULL, &commit_state, NULL) &&
              commit_state == OSTREE_REPO_COMMIT_STATE_NORMAL)
            {
              *out_sideload_path = g_object_ref (ostree_repo_get_path (ss->repo));
              return;
            }
        }
    }
}

static gboolean
flatpak_remote_state_resolve_sideloaded_ref_repos (FlatpakRemoteState    *self,
                                                   const char            *ref,
                                                   char                 **out_checksum,
                                                   guint64               *out_timestamp,
                                                   VarRefInfoRef         *out_info,
                                                   FlatpakSideloadState **out_sideload_state,
                                                   GError               **error)
{
  g_autofree char *latest_checksum = NULL;
  guint64 latest_timestamp = 0;
  FlatpakSideloadState *latest_ss = NULL;
  VarRefInfoRef latest_sideload_info;

  for (int i = 0; i < self->sideload_repos->len; i++)
    {
      FlatpakSideloadState *ss = g_ptr_array_index (self->sideload_repos, i);
      g_autofree char *sideload_checksum = NULL;
      VarRefInfoRef sideload_info;

      if (flatpak_summary_lookup_ref (ss->summary, self->collection_id, ref, &sideload_checksum, &sideload_info))
        {
          guint64 timestamp = get_timestamp_from_ref_info (sideload_info);

          if (latest_checksum == 0 || latest_timestamp < timestamp)
            {
              g_free (latest_checksum);
              latest_checksum = g_steal_pointer (&sideload_checksum);
              latest_timestamp = timestamp;
              latest_sideload_info = sideload_info;
              latest_ss = ss;
            }
        }
    }

  if (latest_checksum == NULL)
    return flatpak_fail_error (error, FLATPAK_ERROR_REF_NOT_FOUND,
                               _("No such ref '%s' in remote %s"),
                               ref, self->remote_name);

  if (out_checksum)
    *out_checksum = g_steal_pointer (&latest_checksum);
  if (out_timestamp)
    *out_timestamp = latest_timestamp;
  if (out_info)
    *out_info = latest_sideload_info;
  if (out_sideload_state)
    *out_sideload_state = latest_ss;

  return TRUE;
}

static gboolean
flatpak_remote_state_resolve_sideloaded_ref_images (FlatpakRemoteState  *self,
                                                    const char          *ref,
                                                    char               **out_checksum,
                                                    guint64             *out_timestamp,
                                                    VarRefInfoRef       *out_info,
                                                    FlatpakImageSource **out_image_source,
                                                    GError             **error)
{
  g_autoptr(FlatpakImageSource) image_source = NULL;

  for (int i = 0; i < self->sideload_image_collections->len; i++)
    {
      FlatpakImageCollection *collection = g_ptr_array_index (self->sideload_image_collections, i);
      image_source = flatpak_image_collection_lookup_ref (collection, ref);
      if (image_source)
        break;
    }

  if (image_source == NULL)
    return flatpak_fail_error (error, FLATPAK_ERROR_REF_NOT_FOUND,
                               _("No such ref '%s' in remote %s"),
                               ref, self->remote_name);

  if (out_checksum)
    {
      const char *digest = flatpak_image_source_get_digest (image_source);
      g_assert (g_str_has_prefix (digest, "sha256:"));
      *out_checksum = g_strdup (digest + 7);
    }

  if (out_timestamp)
    *out_timestamp = flatpak_image_source_get_commit_timestamp (image_source);

  if (out_image_source)
    *out_image_source = g_steal_pointer (&image_source);

  return TRUE;
}

static gboolean
flatpak_remote_state_resolve_sideloaded_ref (FlatpakRemoteState    *self,
                                             const char            *ref,
                                             char                 **out_checksum,
                                             guint64               *out_timestamp,
                                             VarRefInfoRef         *out_info,
                                             FlatpakSideloadState **out_sideload_state,
                                             FlatpakImageSource   **out_image_source,
                                             GError               **error)
{
  if (out_sideload_state)
    *out_sideload_state = NULL;
  if (out_image_source)
    *out_image_source = NULL;

  if (self->is_oci)
    return flatpak_remote_state_resolve_sideloaded_ref_images (self, ref, out_checksum, out_timestamp, out_info,
                                                               out_image_source, error);
  else
    return flatpak_remote_state_resolve_sideloaded_ref_repos (self, ref, out_checksum, out_timestamp, out_info,
                                                               out_sideload_state, error);

}

static GVariant *
get_summary_for_ref (FlatpakRemoteState *self,
                     const char *ref)
{
  GVariant *summary = NULL;

  if (self->index != NULL)
    {
      g_autofree char * arch = flatpak_get_arch_for_ref (ref);

      if (arch != NULL)
        summary = g_hash_table_lookup (self->subsummaries, arch);

      if (summary == NULL && arch != NULL)
        {
          const char *non_compat_arch = flatpak_get_compat_arch_reverse (arch);

          if (non_compat_arch != NULL)
            summary = g_hash_table_lookup (self->subsummaries, non_compat_arch);
        }
    }
  else
    summary = self->summary;

  return summary;
}

/* Returns TRUE if the ref is found in the summary or cache.
 * out_checksum and out_variant are only set when the ref is found.
 *
 * NOTE: The _internal() variant has the odd constraint that *out_info is only
 * valid if *out_image_source is NULL.
 */
static gboolean
flatpak_remote_state_lookup_ref_internal (FlatpakRemoteState  *self,
                                          const char          *ref,
                                          char               **out_checksum,
                                          guint64             *out_timestamp,
                                          VarRefInfoRef       *out_info,
                                          GFile              **out_sideload_path,
                                          FlatpakImageSource **out_image_source,
                                          GError             **error)
{
  g_assert (out_info == NULL || out_image_source != NULL);

  if (!flatpak_remote_state_allow_ref (self, ref))
    {
      return flatpak_fail_error (error, FLATPAK_ERROR_REF_NOT_FOUND,
                                 _("No entry for %s in remote %s summary flatpak cache"),
                                 ref, self->remote_name);
    }

  /* If there is a summary we use it for metadata and for latest. We may later install from a sideloaded source though */
  if (self->summary != NULL || self->index != NULL)
    {
      VarRefInfoRef info;
      g_autofree char *checksum = NULL;
      GVariant *summary;

      summary = get_summary_for_ref (self, ref);
      if (summary == NULL ||
          !flatpak_summary_lookup_ref (summary, NULL, ref, &checksum, &info))
        return flatpak_fail_error (error, FLATPAK_ERROR_REF_NOT_FOUND,
                                   _("No such ref '%s' in remote %s"),
                                   ref, self->remote_name);

      /* Even if its available in the summary we want to install it from a sideload repo if available */
      flatpak_remote_state_lookup_sideload_checksum (self, checksum, out_sideload_path, out_image_source);

      if (out_info)
        *out_info = info;
      if (out_checksum)
        *out_checksum = g_steal_pointer (&checksum);
      if (out_timestamp)
        *out_timestamp = get_timestamp_from_ref_info (info);
    }
  else
    {
      FlatpakSideloadState *ss = NULL;
      g_autoptr(GFile) found_sideload_path = NULL;

      if (!flatpak_remote_state_resolve_sideloaded_ref (self, ref, out_checksum, out_timestamp, out_info, &ss, out_image_source, error))
        return FALSE;

      if (ss)
        found_sideload_path = g_object_ref (ostree_repo_get_path (ss->repo));

      if (out_sideload_path)
        *out_sideload_path = g_steal_pointer (&found_sideload_path);
    }

  return TRUE;
}

/* Returns TRUE if the ref is found in the summary or cache.
 * out parameters are only set if the ref is found.
 */
gboolean
flatpak_remote_state_lookup_ref (FlatpakRemoteState  *self,
                                 const char          *ref,
                                 char               **out_checksum,
                                 guint64             *out_timestamp,
                                 GVariant           **out_summary_metadata,
                                 GFile              **out_sideload_path,
                                 FlatpakImageSource **out_image_source,
                                 GError             **error)
{
  VarRefInfoRef info;
  g_autoptr(FlatpakImageSource) image_source = NULL;

  if (!flatpak_remote_state_lookup_ref_internal (self, ref,
                                                 out_checksum,
                                                 out_timestamp,
                                                 &info,
                                                 out_sideload_path,
                                                 &image_source,
                                                 error))
    return FALSE;

  if (out_summary_metadata)
    {
      *out_summary_metadata = image_source ?
        flatpak_image_source_make_summary_metadata (image_source) :
        var_metadata_dup_to_gvariant (var_ref_info_get_metadata (info));
    }

  if (out_image_source)
    *out_image_source = g_steal_pointer (&image_source);

  return TRUE;
}

GPtrArray *
flatpak_remote_state_match_subrefs (FlatpakRemoteState *self,
                                    FlatpakDecomposed *ref)
{
  GVariant *summary;

  if (self->summary == NULL && self->index == NULL)
    {
      g_info ("flatpak_remote_state_match_subrefs with no summary");
      return g_ptr_array_new_with_free_func ((GDestroyNotify)flatpak_decomposed_unref);
    }

  summary = get_summary_for_ref (self, flatpak_decomposed_get_ref (ref));
  if (summary == NULL)
    return g_ptr_array_new_with_free_func ((GDestroyNotify)flatpak_decomposed_unref);

  return flatpak_summary_match_subrefs (summary, NULL, ref);
}

static VarMetadataRef
flatpak_remote_state_get_main_metadata (FlatpakRemoteState *self)
{
  VarSummaryRef summary;
  VarSummaryIndexRef index;
  VarMetadataRef meta;

  if (self->index)
    {
      index = var_summary_index_from_gvariant (self->index);
      meta = var_summary_index_get_metadata (index);
    }
  else if (self->summary)
    {
      summary = var_summary_from_gvariant (self->summary);
      meta = var_summary_get_metadata (summary);
    }
  else
    g_assert_not_reached ();

  return meta;
}


/* 0 if not specified */
static guint32
flatpak_remote_state_get_cache_version (FlatpakRemoteState *self)
{
  VarMetadataRef meta;

  if (!flatpak_remote_state_ensure_summary (self, NULL))
    return 0;

  meta = flatpak_remote_state_get_main_metadata (self);
  return GUINT32_FROM_LE (var_metadata_lookup_uint32 (meta, "xa.cache-version", 0));
}

gboolean
flatpak_remote_state_lookup_cache (FlatpakRemoteState *self,
                                   const char         *ref,
                                   guint64            *out_download_size,
                                   guint64            *out_installed_size,
                                   const char        **out_metadata,
                                   GError            **error)
{
  VarCacheDataRef cache_data;
  VarMetadataRef meta;
  VarSummaryRef summary;
  guint32 summary_version;
  GVariant *summary_v;

  if (!flatpak_remote_state_ensure_summary (self, error))
    return FALSE;

  summary_v = get_summary_for_ref (self, ref);
  if (summary_v == NULL)
    return flatpak_fail_error (error, FLATPAK_ERROR_REF_NOT_FOUND,
                               _("No entry for %s in remote %s summary flatpak cache"),
                               ref, self->remote_name);


  summary = var_summary_from_gvariant (summary_v);
  meta = var_summary_get_metadata (summary);

  summary_version = GUINT32_FROM_LE (var_metadata_lookup_uint32 (meta, "xa.summary-version", 0));

  if (summary_version == 0)
    {
      VarCacheRef cache;
      gsize pos;
      VarVariantRef cache_vv;
      VarVariantRef cache_v;

      if (!var_metadata_lookup (meta, "xa.cache", NULL, &cache_vv))
        {
          flatpak_fail_error (error, FLATPAK_ERROR_INVALID_DATA, _("No summary or Flatpak cache available for remote %s"),
                              self->remote_name);
          return FALSE;
        }

      /* For stupid historical reasons the xa.cache is double-wrapped in a variant */
      cache_v = var_variant_from_variant (cache_vv);
      cache = var_cache_from_variant (cache_v);

      if (!var_cache_lookup (cache, ref, &pos, &cache_data))
        return flatpak_fail_error (error, FLATPAK_ERROR_REF_NOT_FOUND,
                                   _("No entry for %s in remote %s summary flatpak cache"),
                                   ref, self->remote_name);
    }
  else if (summary_version == 1)
    {
      VarRefMapRef ref_map = var_summary_get_ref_map (summary);
      VarRefInfoRef info;
      VarMetadataRef commit_metadata;
      VarVariantRef cache_data_v;

      if (!flatpak_var_ref_map_lookup_ref (ref_map, ref, &info))
        return flatpak_fail_error (error, FLATPAK_ERROR_REF_NOT_FOUND,
                                   _("No entry for %s in remote %s summary flatpak cache"),
                                   ref, self->remote_name);

      commit_metadata = var_ref_info_get_metadata (info);
      if (!var_metadata_lookup (commit_metadata, "xa.data", NULL, &cache_data_v))
        return flatpak_fail_error (error, FLATPAK_ERROR_INVALID_DATA, _("Missing xa.data in summary for remote %s"),
                                   self->remote_name);
      cache_data = var_cache_data_from_variant (cache_data_v);
    }
  else
    {
      flatpak_fail_error (error, FLATPAK_ERROR_INVALID_DATA, _("Unsupported summary version %d for remote %s"),
                          summary_version, self->remote_name);
      return FALSE;
    }

  if (out_installed_size)
    *out_installed_size = var_cache_data_get_installed_size (cache_data);

  if (out_download_size)
    *out_download_size = var_cache_data_get_download_size (cache_data);

  if (out_metadata)
    *out_metadata = var_cache_data_get_metadata (cache_data);

  return TRUE;
}

gboolean
flatpak_remote_state_load_data (FlatpakRemoteState *self,
                                const char         *ref,
                                guint64            *out_download_size,
                                guint64            *out_installed_size,
                                char              **out_metadata,
                                GError            **error)
{
  if (self->summary || self->index)
    {
      const char *metadata = NULL;
      if (!flatpak_remote_state_lookup_cache (self, ref, out_download_size, out_installed_size, &metadata, error))
        return FALSE;

      if (out_metadata)
        *out_metadata = g_strdup (metadata);
    }
  else
    {
      /* Look up from sideload */
      g_autofree char *checksum = NULL;
      guint64 timestamp;
      FlatpakSideloadState *ss = NULL;
      g_autoptr(FlatpakImageSource) image_source = NULL;
      g_autoptr(GVariant) commit_data = NULL;
      g_autoptr(GVariant) commit_metadata = NULL;
      const char *xa_metadata = NULL;
      guint64 download_size = 0;
      guint64 installed_size = 0;

      /* Use sideload refs if any */

      if (!flatpak_remote_state_resolve_sideloaded_ref (self, ref, &checksum, &timestamp,
                                                        NULL, &ss, &image_source, error))
        return FALSE;

      if (image_source)
        {
          g_autoptr(GVariantBuilder) metadata_builder = g_variant_builder_new (G_VARIANT_TYPE ("a{sv}"));
          flatpak_image_source_build_commit_metadata (image_source, metadata_builder);
          commit_metadata = g_variant_builder_end (metadata_builder);
        }
      else
        {
          if (!ostree_repo_load_commit (ss->repo, checksum, &commit_data, NULL, error))
            return FALSE;

          commit_metadata = g_variant_get_child_value (commit_data, 0);
        }

      g_variant_lookup (commit_metadata, "xa.metadata", "&s", &xa_metadata);
      if (xa_metadata == NULL)
        return flatpak_fail (error, "No xa.metadata in sideload commit %s ref %s", checksum, ref);

      if (g_variant_lookup (commit_metadata, "xa.download-size", "t", &download_size))
        download_size = GUINT64_FROM_BE (download_size);
      if (g_variant_lookup (commit_metadata, "xa.installed-size", "t", &installed_size))
        installed_size = GUINT64_FROM_BE (installed_size);

      if (out_installed_size)
        *out_installed_size = installed_size;

      if (out_download_size)
        *out_download_size = download_size;

      if (out_metadata)
        *out_metadata = g_strdup (xa_metadata);
    }
  return TRUE;
}

static char *
lookup_oci_registry_uri_from_summary (GVariant *summary,
                                      GError  **error)
{
  g_autoptr(GVariant) extensions = g_variant_get_child_value (summary, 1);
  g_autofree char *registry_uri = NULL;

  if (!g_variant_lookup (extensions, "xa.oci-registry-uri", "s", &registry_uri))
    {
      flatpak_fail_error (error, FLATPAK_ERROR_INVALID_DATA, _("Remote OCI index has no registry uri"));
      return NULL;
    }

  return g_steal_pointer (&registry_uri);
}

static FlatpakImageSource *
flatpak_remote_state_new_image_source (FlatpakRemoteState  *self,
                                       FlatpakDir          *dir,
                                       const char          *oci_repository,
                                       const char          *digest,
                                       const char          *token,
                                       GCancellable        *cancellable,
                                       GError             **error)
{
  g_autofree char *registry_uri = NULL;
  g_autoptr(FlatpakImageSource) image_source = NULL;
  g_autofree char *signature_lookaside = NULL;

  if (!flatpak_remote_state_ensure_summary (self, error))
    return NULL;

  registry_uri = lookup_oci_registry_uri_from_summary (self->summary, error);
  if (registry_uri == NULL)
    return NULL;

  signature_lookaside = flatpak_dir_get_remote_signature_lookaside (dir, self->remote_name);

  image_source = flatpak_image_source_new_remote (registry_uri,
                                                  oci_repository,
                                                  digest,
                                                  token,
                                                  signature_lookaside,
                                                  NULL, error);
  if (image_source == NULL)
    return NULL;

  return g_steal_pointer (&image_source);
}

FlatpakImageSource *
flatpak_remote_state_fetch_image_source (FlatpakRemoteState *self,
                                         FlatpakDir         *dir,
                                         const char         *ref,
                                         const char         *opt_rev,
                                         const char         *token,
                                         GCancellable       *cancellable,
                                         GError            **error)
{
  g_autoptr(FlatpakImageSource) image_source = NULL;
  g_autofree char *latest_rev = NULL;
  VarRefInfoRef latest_rev_info;

  /* We extract the rev info from the latest, even if we don't use the latest digest, assuming refs don't move */
  if (!flatpak_remote_state_lookup_ref_internal (self, ref, &latest_rev, NULL, &latest_rev_info, NULL, &image_source, error))
    return NULL;

  if (latest_rev == NULL)
    {
      flatpak_fail_error (error, FLATPAK_ERROR_REF_NOT_FOUND,
                          _("Couldn't find ref %s in remote %s"),
                          ref, self->remote_name);
      return NULL;
    }

  if (image_source == NULL)
    {
      VarMetadataRef metadata;
      g_autofree char *oci_digest = NULL;
      const char *oci_repository = NULL;
      const char *delta_url = NULL;
      const char *source_ref = NULL;

      metadata = var_ref_info_get_metadata (latest_rev_info);
      oci_repository = var_metadata_lookup_string (metadata, "xa.oci-repository", NULL);
      delta_url = var_metadata_lookup_string (metadata, "xa.delta-url", NULL);

      oci_digest = g_strconcat ("sha256:", opt_rev ? opt_rev : latest_rev, NULL);

      image_source = flatpak_remote_state_new_image_source (self, dir, oci_repository, oci_digest, token, cancellable, error);
      if (image_source == NULL)
        return NULL;

      source_ref = flatpak_image_source_get_ref (image_source);
      if (g_strcmp0 (source_ref, ref) != 0)
        {
          flatpak_fail_error (error, FLATPAK_ERROR_INVALID_DATA,
                              _("Commit has no requested ref ‘%s’ in ref binding metadata (found: ‘%s’)"),
                              ref, source_ref ?: "");
          return NULL;
        }

      flatpak_image_source_set_delta_url (image_source, delta_url);
    }

  return g_steal_pointer (&image_source);
}


static GVariant *
flatpak_remote_state_fetch_commit_object_oci (FlatpakRemoteState *self,
                                              FlatpakDir   *dir,
                                              const char   *ref,
                                              const char   *checksum,
                                              const char   *token,
                                              GCancellable *cancellable,
                                              GError      **error)
{
  g_autoptr(FlatpakImageSource) image_source = NULL;

  image_source = flatpak_remote_state_fetch_image_source (self, dir, ref, checksum, token, cancellable, error);
  if (image_source == NULL)
    return NULL;

  return flatpak_image_source_make_fake_commit (image_source);
}

static GVariant *
flatpak_remote_state_fetch_commit_object (FlatpakRemoteState *self,
                                          FlatpakDir   *dir,
                                          const char   *ref,
                                          const char   *checksum,
                                          const char   *token,
                                          GCancellable *cancellable,
                                          GError      **error)
{
  g_autofree char *base_url = NULL;
  g_autofree char *object_url = NULL;
  g_autofree char *part1 = NULL;
  g_autofree char *part2 = NULL;
  g_autoptr(GBytes) bytes = NULL;
  g_autoptr(GVariant) commit_data = NULL;
  g_autoptr(GVariant) commit_metadata = NULL;

  if (!ostree_repo_remote_get_url (dir->repo, self->remote_name, &base_url, error))
    return NULL;

  ensure_http_session (dir);

  part1 = g_strndup (checksum, 2);
  part2 = g_strdup_printf ("%s.commit", checksum + 2);

  object_url = g_build_filename (base_url, "objects", part1, part2, NULL);

  bytes = flatpak_load_uri (dir->http_session, object_url, 0, token,
                            NULL, NULL, NULL,
                            cancellable, error);
  if (bytes == NULL)
    return NULL;

  commit_data = g_variant_ref_sink (g_variant_new_from_bytes (OSTREE_COMMIT_GVARIANT_FORMAT,
                                                              bytes, FALSE));

  /* We downloaded this without validating the signature, so we do some basic verification
     of it. However, the signature will be checked when the download is done, and the final
     metadata is compared to what we got here, so its pretty ok to use it for resolving
     the transaction op. However, we do some basic checks. */
  if (!ostree_validate_structureof_commit (commit_data, error))
    return NULL;

  commit_metadata = g_variant_get_child_value (commit_data, 0);
  if (ref != NULL)
    {
      const char *xa_ref = NULL;
      const char *collection_binding = NULL;
      g_autofree const char **commit_refs = NULL;

      if ((g_variant_lookup (commit_metadata, "xa.ref", "&s", &xa_ref) &&
           g_strcmp0 (xa_ref, ref) != 0) ||
          (g_variant_lookup (commit_metadata, OSTREE_COMMIT_META_KEY_REF_BINDING, "^a&s", &commit_refs) &&
           !g_strv_contains ((const char * const *) commit_refs, ref)))
        {
          const char *xa_ref_v[] = { xa_ref, NULL };
          g_auto(GStrv) found = NULL;
          g_autofree char *found_s = NULL;

          found = flatpak_strv_merge ((char **) xa_ref_v, (char **) commit_refs);
          found_s = g_strjoinv (", ", (char **) found);

          flatpak_fail_error (error, FLATPAK_ERROR_INVALID_DATA,
                              _("Commit has no requested ref ‘%s’ in ref binding metadata (found: ‘%s’)"),
                              ref, found_s);
          return NULL;
        }

      /* Check that the locally configured collection ID is correct by looking
       * for it in the commit metadata */
      if (self->collection_id != NULL &&
          (!g_variant_lookup (commit_metadata, OSTREE_COMMIT_META_KEY_COLLECTION_BINDING, "&s", &collection_binding) ||
           g_strcmp0 (self->collection_id, collection_binding) != 0))
        {
          g_autoptr(GVariantIter) collection_refs_iter = NULL;
          gboolean found_in_collection_refs_binding = FALSE;
          /* Note: the OSTREE_COMMIT_META_... define for this is not yet merged
           * in https://github.com/ostreedev/ostree/pull/1805 */
          if (g_variant_lookup (commit_metadata, "ostree.collection-refs-binding", "a(ss)", &collection_refs_iter))
            {
              const gchar *crb_collection_id, *crb_ref_name;
              while (g_variant_iter_loop (collection_refs_iter, "(&s&s)", &crb_collection_id, &crb_ref_name))
                {
                  if (g_strcmp0 (self->collection_id, crb_collection_id) == 0 &&
                      g_strcmp0 (ref, crb_ref_name) == 0)
                    {
                      found_in_collection_refs_binding = TRUE;
                      break;
                    }
                }
            }

          if (!found_in_collection_refs_binding)
            {
              flatpak_fail_error (error, FLATPAK_ERROR_INVALID_DATA,
                                  _("Configured collection ID ‘%s’ not in binding metadata"),
                                  self->collection_id);
              return NULL;
            }
        }
    }

  return g_steal_pointer (&commit_data);
}


/* Tries to load the specified commit object that we resolved from
   this remote.  This either comes from the already available local
   repo, or from one of the sideloading repos, and if not available we
   download it from the actual remote. */
GVariant *
flatpak_remote_state_load_ref_commit (FlatpakRemoteState *self,
                                      FlatpakDir         *dir,
                                      const char         *ref,
                                      const char         *opt_commit,
                                      const char         *token,
                                      char              **out_commit,
                                      GCancellable       *cancellable,
                                      GError            **error)
{
  g_autoptr(GVariant) commit_data = NULL;
  g_autofree char *commit = NULL;

  if (opt_commit == NULL)
    {
      if (!flatpak_remote_state_lookup_ref (self, ref, &commit, NULL, NULL, NULL, NULL, error))
        return NULL;

      if (commit == NULL)
        {
          flatpak_fail_error (error, FLATPAK_ERROR_REF_NOT_FOUND,
                              _("Couldn't find latest checksum for ref %s in remote %s"),
                              ref, self->remote_name);
          return NULL;
        }
    }
  else
    commit = g_strdup (opt_commit);

  /* First try local availability */
  if (ostree_repo_load_commit (dir->repo, commit, &commit_data, NULL, NULL))
    goto out;

  if (self->is_oci)
    {
      g_autoptr(FlatpakImageSource) image_source;

      flatpak_remote_state_lookup_sideload_checksum (self, commit, NULL, &image_source);
      if (image_source)
        {
          commit_data = flatpak_image_source_make_fake_commit (image_source);
          goto out;
        }
    }
  else
    {
      for (int i = 0; i < self->sideload_repos->len; i++)
        {
          FlatpakSideloadState *ss = g_ptr_array_index (self->sideload_repos, i);

          if (ostree_repo_load_commit (ss->repo, commit, &commit_data, NULL, NULL))
            goto out;
        }
    }

  if (flatpak_dir_get_remote_oci (dir, self->remote_name))
    commit_data = flatpak_remote_state_fetch_commit_object_oci (self, dir, ref, commit, token,
                                                                cancellable, error);
  else
    commit_data = flatpak_remote_state_fetch_commit_object (self, dir, ref, commit, token,
                                                            cancellable, error);

out:
  if (out_commit)
    *out_commit = g_steal_pointer (&commit);

  return g_steal_pointer (&commit_data);
}


gboolean
flatpak_remote_state_lookup_sparse_cache (FlatpakRemoteState *self,
                                          const char         *ref,
                                          VarMetadataRef     *out_metadata,
                                          GError            **error)
{
  VarSummaryRef summary;
  VarMetadataRef meta;
  VarVariantRef sparse_cache_v;
  guint32 summary_version;
  GVariant *summary_v;

  if (!flatpak_remote_state_ensure_summary (self, error))
    return FALSE;

  summary_v = get_summary_for_ref (self, ref);
  if (summary_v == NULL)
    return flatpak_fail_error (error, FLATPAK_ERROR_REF_NOT_FOUND,
                               _("No entry for %s in remote %s summary flatpak sparse cache"),
                               ref, self->remote_name);

  summary = var_summary_from_gvariant (summary_v);
  meta = var_summary_get_metadata (summary);

  summary_version = GUINT32_FROM_LE (var_metadata_lookup_uint32 (meta, "xa.summary-version", 0));

  if (summary_version == 0)
    {
      if (var_metadata_lookup (meta, "xa.sparse-cache", NULL, &sparse_cache_v))
        {
          VarSparseCacheRef sparse_cache = var_sparse_cache_from_variant (sparse_cache_v);
          if (var_sparse_cache_lookup (sparse_cache, ref, NULL, out_metadata))
            return TRUE;
        }
    }
  else if (summary_version == 1)
    {
      VarRefMapRef ref_map = var_summary_get_ref_map (summary);
      VarRefInfoRef info;

      if (flatpak_var_ref_map_lookup_ref (ref_map, ref, &info))
        {
          *out_metadata = var_ref_info_get_metadata (info);
          return TRUE;
        }
    }
  else
    {
      flatpak_fail_error (error, FLATPAK_ERROR_INVALID_DATA, _("Unsupported summary version %d for remote %s"),
                          summary_version, self->remote_name);
      return FALSE;
    }

  return flatpak_fail_error (error, FLATPAK_ERROR_REF_NOT_FOUND,
                             _("No entry for %s in remote %s summary flatpak sparse cache"),
                             ref, self->remote_name);
}

static DirExtraData *
dir_extra_data_new (const char           *id,
                    const char           *display_name,
                    gint                  priority,
                    FlatpakDirStorageType type)
{
  DirExtraData *dir_extra_data = g_new0 (DirExtraData, 1);

  dir_extra_data->id = g_strdup (id);
  dir_extra_data->display_name = g_strdup (display_name);
  dir_extra_data->priority = priority;
  dir_extra_data->storage_type = type;

  return dir_extra_data;
}

static DirExtraData *
dir_extra_data_clone (DirExtraData *extra_data)
{
  if (extra_data != NULL)
    return dir_extra_data_new (extra_data->id,
                               extra_data->display_name,
                               extra_data->priority,
                               extra_data->storage_type);
  return NULL;
}

static void
dir_extra_data_free (DirExtraData *dir_extra_data)
{
  g_free (dir_extra_data->id);
  g_free (dir_extra_data->display_name);
  g_free (dir_extra_data);
}

G_DEFINE_AUTOPTR_CLEANUP_FUNC (DirExtraData, dir_extra_data_free);

static GVariant *
variant_new_ay_bytes (GBytes *bytes)
{
  gsize size;
  gconstpointer data;

  data = g_bytes_get_data (bytes, &size);
  g_bytes_ref (bytes);
  return g_variant_ref_sink (g_variant_new_from_data (G_VARIANT_TYPE ("ay"), data, size,
                                                      TRUE, (GDestroyNotify) g_bytes_unref, bytes));
}

static void
flatpak_deploy_finalize (GObject *object)
{
  FlatpakDeploy *self = FLATPAK_DEPLOY (object);

  g_clear_pointer (&self->ref, flatpak_decomposed_unref);
  g_clear_object (&self->dir);
  g_clear_pointer (&self->metadata, g_key_file_unref);
  g_clear_pointer (&self->system_overrides, flatpak_context_free);
  g_clear_pointer (&self->user_overrides, flatpak_context_free);
  g_clear_pointer (&self->system_app_overrides, flatpak_context_free);
  g_clear_pointer (&self->user_app_overrides, flatpak_context_free);
  g_clear_object (&self->repo);

  G_OBJECT_CLASS (flatpak_deploy_parent_class)->finalize (object);
}

static void
flatpak_deploy_class_init (FlatpakDeployClass *klass)
{
  GObjectClass *object_class = G_OBJECT_CLASS (klass);

  object_class->finalize = flatpak_deploy_finalize;
}

static void
flatpak_deploy_init (FlatpakDeploy *self)
{
}

GFile *
flatpak_deploy_get_dir (FlatpakDeploy *deploy)
{
  return g_object_ref (deploy->dir);
}

GBytes *
flatpak_load_deploy_data (GFile             *deploy_dir,
                          FlatpakDecomposed *ref,
                          OstreeRepo        *repo,
                          int                required_version,
                          GCancellable      *cancellable,
                          GError           **error)
{
  g_autoptr(GFile) data_file = NULL;
  g_autoptr(GBytes) deploy_data = NULL;
  gchar *contents;
  gsize len;

  data_file = g_file_get_child (deploy_dir, "deploy");

  if (!g_file_load_contents (data_file, cancellable, &contents, &len, NULL, error))
    return NULL;

  deploy_data = g_bytes_new_take (contents, len);

  if (flatpak_deploy_data_get_version (deploy_data) < required_version)
    return upgrade_deploy_data (deploy_data, deploy_dir, ref, repo, cancellable, error);

  return g_steal_pointer (&deploy_data);
}


GBytes *
flatpak_deploy_get_deploy_data (FlatpakDeploy *deploy,
                                int            required_version,
                                GCancellable  *cancellable,
                                GError       **error)
{
  return flatpak_load_deploy_data (deploy->dir,
                                   deploy->ref,
                                   deploy->repo,
                                   required_version,
                                   cancellable,
                                   error);
}

GFile *
flatpak_deploy_get_files (FlatpakDeploy *deploy)
{
  return g_file_get_child (deploy->dir, "files");
}

FlatpakContext *
flatpak_deploy_get_overrides (FlatpakDeploy *deploy)
{
  FlatpakContext *overrides = flatpak_context_new ();

  if (deploy->system_overrides)
    {
      flatpak_context_dump (deploy->system_overrides,
                            "System-wide overrides for all apps");
      flatpak_context_merge (overrides, deploy->system_overrides);
    }
  else
    {
      g_debug ("No system-wide overrides for all apps");
    }

  if (deploy->system_app_overrides)
    {
      flatpak_context_dump (deploy->system_app_overrides,
                            "System-wide overrides for specified app");
      flatpak_context_merge (overrides, deploy->system_app_overrides);
    }
  else
    {
      g_debug ("No system-wide per-app overrides for specified app");
    }

  if (deploy->user_overrides)
    {
      flatpak_context_dump (deploy->user_overrides,
                            "Per-user overrides for all apps");
      flatpak_context_merge (overrides, deploy->user_overrides);
    }
  else
    {
      g_debug ("No per-user overrides for all apps");
    }

  if (deploy->user_app_overrides)
    {
      flatpak_context_dump (deploy->user_app_overrides,
                            "Per-user overrides for specified app");
      flatpak_context_merge (overrides, deploy->user_app_overrides);
    }
  else
    {
      g_debug ("No per-user overrides for specified app");
    }

  return overrides;
}

GKeyFile *
flatpak_deploy_get_metadata (FlatpakDeploy *deploy)
{
  return g_key_file_ref (deploy->metadata);
}

static FlatpakDeploy *
flatpak_deploy_new (GFile             *dir,
                    FlatpakDecomposed *ref,
                    GKeyFile          *metadata,
                    OstreeRepo        *repo)
{
  FlatpakDeploy *deploy;

  deploy = g_object_new (FLATPAK_TYPE_DEPLOY, NULL);
  deploy->ref = flatpak_decomposed_ref (ref);
  deploy->dir = g_object_ref (dir);
  deploy->metadata = g_key_file_ref (metadata);
  deploy->repo = g_object_ref (repo);

  return deploy;
}

GFile *
flatpak_get_system_default_base_dir_location (void)
{
  static gsize file = 0;

  if (g_once_init_enter (&file))
    {
      gsize setup_value = 0;
      const char *path;
      const char *system_dir = g_getenv ("FLATPAK_SYSTEM_DIR");
      if (system_dir != NULL && *system_dir != 0)
        path = system_dir;
      else
        path = FLATPAK_SYSTEMDIR;

      setup_value = (gsize) g_file_new_for_path (path);

      g_once_init_leave (&file, setup_value);
    }

  return g_object_ref ((GFile *) file);
}

static FlatpakDirStorageType
parse_storage_type (const char *type_string)
{
  if (type_string != NULL)
    {
      g_autofree char *type_low = NULL;

      type_low = g_ascii_strdown (type_string, -1);
      if (g_strcmp0 (type_low, "network") == 0)
        return FLATPAK_DIR_STORAGE_TYPE_NETWORK;

      if (g_strcmp0 (type_low, "mmc") == 0)
        return FLATPAK_DIR_STORAGE_TYPE_MMC;

      if (g_strcmp0 (type_low, "sdcard") == 0)
        return FLATPAK_DIR_STORAGE_TYPE_SDCARD;

      if (g_strcmp0 (type_low, "hardisk") == 0)
        return FLATPAK_DIR_STORAGE_TYPE_HARD_DISK;
    }

  return FLATPAK_DIR_STORAGE_TYPE_DEFAULT;
}

static gboolean
has_system_location (GPtrArray  *locations,
                     const char *id)
{
  int i;

  for (i = 0; i < locations->len; i++)
    {
      GFile *path = g_ptr_array_index (locations, i);
      DirExtraData *extra_data = g_object_get_data (G_OBJECT (path), "extra-data");
      if (extra_data != NULL && g_strcmp0 (extra_data->id, id) == 0)
        return TRUE;
    }

  return FALSE;
}

static void
append_new_system_location (GPtrArray            *locations,
                            GFile                *location,
                            const char           *id,
                            const char           *display_name,
                            FlatpakDirStorageType storage_type,
                            gint                  priority)
{
  DirExtraData *extra_data = NULL;

  extra_data = dir_extra_data_new (id, display_name, priority, storage_type);
  g_object_set_data_full (G_OBJECT (location), "extra-data", extra_data,
                          (GDestroyNotify) dir_extra_data_free);

  g_ptr_array_add (locations, location);
}

static gboolean
is_good_installation_id (const char *id)
{
  if (strcmp (id, "") == 0 ||
      strcmp (id, "user") == 0 ||
      strcmp (id, SYSTEM_DIR_DEFAULT_ID) == 0 ||
      strcmp (id, "system") == 0)
    return FALSE;

  if (!g_str_is_ascii (id) ||
      strpbrk (id, " /\n"))
    return FALSE;

  if (strlen (id) > 80)
    return FALSE;

  return TRUE;
}

static gboolean
append_locations_from_config_file (GPtrArray    *locations,
                                   const char   *file_path,
                                   GCancellable *cancellable,
                                   GError      **error)
{
  g_autoptr(GKeyFile) keyfile = NULL;
  g_auto(GStrv) groups = NULL;
  g_autoptr(GError) my_error = NULL;
  gboolean ret = FALSE;
  gsize n_groups;
  int i;

  keyfile = g_key_file_new ();

  if (!g_key_file_load_from_file (keyfile, file_path, G_KEY_FILE_NONE, &my_error))
    {
      g_info ("Could not get list of system installations from '%s': %s", file_path, my_error->message);
      g_propagate_error (error, g_steal_pointer (&my_error));
      goto out;
    }

  /* One configuration file might define more than one installation */
  groups = g_key_file_get_groups (keyfile, &n_groups);
  for (i = 0; i < n_groups; i++)
    {
      g_autofree char *id = NULL;
      g_autofree char *path = NULL;
      size_t len;

      if (!g_str_has_prefix (groups[i], "Installation \""))
        {
          if (g_str_has_prefix (groups[i], "Installation "))
            g_warning ("Installation without quotes (%s). Ignoring", groups[i]);
          continue;
        }

      id = g_strdup (&groups[i][14]);
      if (!g_str_has_suffix (id, "\""))
        {
          g_warning ("While reading '%s': Installation without closing quote (%s). Ignoring", file_path, groups[i]);
          continue;
        }

      len = strlen (id);
      if (len > 0)
        id[len - 1] = '\0';

      if (!is_good_installation_id (id))
        {
          g_warning ("While reading '%s': Bad installation ID '%s'. Ignoring", file_path, id);
          continue;
        }

      if (has_system_location (locations, id))
        {
          g_warning ("While reading '%s': Duplicate installation ID '%s'. Ignoring", file_path, id);
          continue;
        }

      path = g_key_file_get_string (keyfile, groups[i], "Path", &my_error);
      if (path == NULL)
        {
          g_info ("While reading '%s': Unable to get path for installation '%s': %s", file_path, id, my_error->message);
          g_propagate_error (error, g_steal_pointer (&my_error));
          goto out;
        }
      else
        {
          GFile *location = NULL;
          g_autofree char *display_name = NULL;
          g_autofree char *priority = NULL;
          g_autofree char *storage_type = NULL;
          gint64 priority_val = 0;

          display_name = g_key_file_get_string (keyfile, groups[i], "DisplayName", NULL);
          priority = g_key_file_get_string (keyfile, groups[i], "Priority", NULL);
          storage_type = g_key_file_get_string (keyfile, groups[i], "StorageType", NULL);

          if (priority != NULL)
            priority_val = g_ascii_strtoll (priority, NULL, 10);

          location = g_file_new_for_path (path);
          append_new_system_location (locations, location, id, display_name,
                                      parse_storage_type (storage_type),
                                      priority_val);
        }
    }

  ret = TRUE;

out:
  return ret;
}

static gint
system_locations_compare_func (gconstpointer location_a, gconstpointer location_b)
{
  const GFile *location_object_a = *(const GFile **) location_a;
  const GFile *location_object_b = *(const GFile **) location_b;
  DirExtraData *extra_data_a = NULL;
  DirExtraData *extra_data_b = NULL;
  gint prio_a = 0;
  gint prio_b = 0;

  extra_data_a = g_object_get_data (G_OBJECT (location_object_a), "extra-data");
  prio_a = (extra_data_a != NULL) ? extra_data_a->priority : 0;

  extra_data_b = g_object_get_data (G_OBJECT (location_object_b), "extra-data");
  prio_b = (extra_data_b != NULL) ? extra_data_b->priority : 0;

  return prio_b - prio_a;
}

static GPtrArray *
system_locations_from_configuration (GCancellable *cancellable,
                                     GError      **error)
{
  g_autoptr(GPtrArray) locations = NULL;
  g_autoptr(GFile) conf_dir = NULL;
  g_autoptr(GFileEnumerator) dir_enum = NULL;
  g_autoptr(GError) my_error = NULL;
  g_autofree char *config_dir = NULL;

  locations = g_ptr_array_new_with_free_func (g_object_unref);
  config_dir = g_strdup_printf ("%s/%s",
                                get_config_dir_location (),
                                SYSCONF_INSTALLATIONS_DIR);

  if (!g_file_test (config_dir, G_FILE_TEST_IS_DIR))
    {
      g_info ("No installations directory in %s. Skipping", config_dir);
      goto out;
    }

  conf_dir = g_file_new_for_path (config_dir);
  dir_enum = g_file_enumerate_children (conf_dir,
                                        G_FILE_ATTRIBUTE_STANDARD_NAME "," G_FILE_ATTRIBUTE_STANDARD_TYPE,
                                        G_FILE_QUERY_INFO_NONE,
                                        cancellable, &my_error);
  if (my_error != NULL)
    {
      g_info ("Unexpected error retrieving extra installations in %s: %s",
              config_dir, my_error->message);
      g_propagate_error (error, g_steal_pointer (&my_error));
      goto out;
    }

  while (TRUE)
    {
      GFileInfo *file_info;
      GFile *path;
      const char *name;
      guint32 type;

      if (!g_file_enumerator_iterate (dir_enum, &file_info, &path,
                                      cancellable, &my_error))
        {
          g_info ("Unexpected error reading file in %s: %s",
                  config_dir, my_error->message);
          g_propagate_error (error, g_steal_pointer (&my_error));
          goto out;
        }

      if (file_info == NULL)
        break;

      name = g_file_info_get_attribute_byte_string (file_info, "standard::name");
      type = g_file_info_get_attribute_uint32 (file_info, "standard::type");

      if (type == G_FILE_TYPE_REGULAR && g_str_has_suffix (name, SYSCONF_INSTALLATIONS_FILE_EXT))
        {
          g_autofree char *path_str = g_file_get_path (path);
          if (!append_locations_from_config_file (locations, path_str, cancellable, error))
            goto out;
        }
    }

out:
  return g_steal_pointer (&locations);
}

static GPtrArray *
get_system_locations (GCancellable *cancellable,
                      GError      **error)
{
  g_autoptr(GPtrArray) locations = NULL;

  /* This will always return a GPtrArray, being an empty one
   * if no additional system installations have been configured.
   */
  locations = system_locations_from_configuration (cancellable, error);

  /* Only fill the details of the default directory if not overridden. */
  if (!has_system_location (locations, SYSTEM_DIR_DEFAULT_ID))
    {
      append_new_system_location (locations,
                                  flatpak_get_system_default_base_dir_location (),
                                  SYSTEM_DIR_DEFAULT_ID,
                                  SYSTEM_DIR_DEFAULT_DISPLAY_NAME,
                                  SYSTEM_DIR_DEFAULT_STORAGE_TYPE,
                                  SYSTEM_DIR_DEFAULT_PRIORITY);
    }

  /* Store the list of system locations sorted according to priorities */
  g_ptr_array_sort (locations, system_locations_compare_func);

  return g_steal_pointer (&locations);
}

typedef struct
{
  char *name;
  char *branch;
  gboolean is_runtime;
  char *collection_id;
  gboolean install;
} PreinstallConfig;

static PreinstallConfig *
preinstall_config_new (const char *name)
{
  PreinstallConfig *config = g_new0 (PreinstallConfig, 1);

  config->name = g_strdup (name);
  config->branch = g_strdup ("master");
  config->install = TRUE;

  return config;
}

static void
preinstall_config_free (PreinstallConfig *config)
{
  g_clear_pointer (&config->name, g_free);
  g_clear_pointer (&config->branch, g_free);
  g_clear_pointer (&config->collection_id, g_free);
  g_free (config);
}

G_DEFINE_AUTOPTR_CLEANUP_FUNC (PreinstallConfig, preinstall_config_free)

static void
flatpak_preinstall_config_free (FlatpakPreinstallConfig *preinstall)
{
  g_clear_pointer (&preinstall->ref, flatpak_decomposed_unref);
  g_clear_pointer (&preinstall->collection_id, g_free);
  g_free (preinstall);
}

G_DEFINE_AUTOPTR_CLEANUP_FUNC (FlatpakPreinstallConfig, flatpak_preinstall_config_free)

static void
flatpak_parse_preinstall_config_file (GKeyFile   *keyfile,
                                      GHashTable *configs)
{
  g_auto(GStrv) groups = NULL;

  groups = g_key_file_get_groups (keyfile, NULL);

  for (int i = 0; groups[i] != NULL; i++)
    {
      const char *group_name = groups[i];
      const char *name;
      g_autoptr(PreinstallConfig) config = NULL;
      g_autoptr(GError) local_error = NULL;
      g_autofree char *owned_name = NULL;
      g_autofree char *branch = NULL;
      gboolean is_runtime = FALSE;
      g_autofree char *collection_id = NULL;
      gboolean install = TRUE;

      if (!g_str_has_prefix (group_name, FLATPAK_PREINSTALL_GROUP_PREFIX) ||
          *(group_name + strlen (FLATPAK_PREINSTALL_GROUP_PREFIX)) == '\0')
        {
          g_info ("Skipping unknown group %s", group_name);
          continue;
        }

      name = group_name + strlen (FLATPAK_PREINSTALL_GROUP_PREFIX);

      if (!g_hash_table_steal_extended (configs, name,
                                        (gpointer *)&owned_name,
                                        (gpointer *)&config))
        {
          config = preinstall_config_new (name);
          owned_name = g_strdup (name);
        }

      branch = g_key_file_get_string (keyfile,
                                      group_name,
                                      FLATPAK_PREINSTALL_BRANCH_KEY,
                                      NULL);
      if (branch)
        {
          if (*branch == '\0')
            g_clear_pointer (&branch, g_free);

          g_set_str (&config->branch, branch);
        }

      is_runtime = g_key_file_get_boolean (keyfile,
                                           group_name,
                                           FLATPAK_PREINSTALL_IS_RUNTIME_KEY,
                                           &local_error);
      if (!local_error)
        {
          config->is_runtime = is_runtime;
        }
      else if (!g_error_matches (local_error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_KEY_NOT_FOUND))
        {
          g_info ("Invalid file format, %s is not a boolean",
                  FLATPAK_PREINSTALL_IS_RUNTIME_KEY);
        }
      g_clear_error (&local_error);

      collection_id = g_key_file_get_string (keyfile,
                                             group_name,
                                             FLATPAK_PREINSTALL_COLLECTION_ID_KEY,
                                             NULL);
      if (collection_id)
        {
          if (*collection_id == '\0')
            g_clear_pointer (&collection_id, g_free);

          g_set_str (&config->collection_id, collection_id);
        }

      install = g_key_file_get_boolean (keyfile,
                                        group_name,
                                        FLATPAK_PREINSTALL_INSTALL_KEY,
                                        &local_error);
      if (!local_error)
        {
          config->install = install;
        }
      else if (!g_error_matches (local_error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_KEY_NOT_FOUND))
        {
          g_info ("Invalid file format, %s is not a boolean",
                  FLATPAK_PREINSTALL_INSTALL_KEY);
        }
      g_clear_error (&local_error);

      g_hash_table_insert (configs,
                           g_steal_pointer (&owned_name),
                           g_steal_pointer (&config));
    }
}

typedef struct
{
  char *name;
  GFile *file;
} PreinstallConfigFile;

static gint
preinstall_config_file_sort (gconstpointer a,
                             gconstpointer b)
{
  const PreinstallConfigFile *ca = a;
  const PreinstallConfigFile *cb = b;

  return g_strcmp0 (ca->name, cb->name);
}

static void
preinstall_config_file_free (PreinstallConfigFile *preinstall_config_file)
{
  g_clear_pointer (&preinstall_config_file->name, g_free);
  g_clear_object (&preinstall_config_file->file);
  g_free (preinstall_config_file);
}

G_DEFINE_AUTOPTR_CLEANUP_FUNC (PreinstallConfigFile, preinstall_config_file_free);

static gboolean
scan_preinstall_config_files (const char    *config_dir,
                              GHashTable    *configs,
                              GCancellable  *cancellable,
                              GError       **error)
{
  g_autoptr(GFile) conf_dir = NULL;
  g_autoptr(GFileEnumerator) dir_enum = NULL;
  g_autoptr(GPtrArray) config_files = NULL;
  g_autoptr(GError) local_error = NULL;

  if (!g_file_test (config_dir, G_FILE_TEST_IS_DIR))
    {
      g_info ("Skipping missing preinstall config directory %s", config_dir);
      return TRUE;
    }

  conf_dir = g_file_new_for_path (config_dir);
  dir_enum = g_file_enumerate_children (conf_dir,
                                        G_FILE_ATTRIBUTE_STANDARD_NAME "," G_FILE_ATTRIBUTE_STANDARD_TYPE,
                                        G_FILE_QUERY_INFO_NONE,
                                        cancellable,
                                        &local_error);
  if (local_error != NULL)
    {
      g_info ("Unexpected error retrieving preinstalls from %s: %s",
              config_dir,
              local_error->message);

      g_propagate_error (error, g_steal_pointer (&local_error));
      return FALSE;
    }

  config_files = g_ptr_array_new_with_free_func ((GDestroyNotify)preinstall_config_file_free);

  while (TRUE)
    {
      GFileInfo *file_info;
      GFile *path;
      const char *name;
      guint32 type;
      g_autoptr(PreinstallConfigFile) config_file = NULL;

      if (!g_file_enumerator_iterate (dir_enum,
                                      &file_info,
                                      &path,
                                      cancellable,
                                      &local_error))
        {
          g_info ("Unexpected error reading file in %s: %s",
                  config_dir,
                  local_error->message);

          g_propagate_error (error, g_steal_pointer (&local_error));
          return FALSE;
        }

      if (file_info == NULL)
        break;

      name = g_file_info_get_name (file_info);
      type = g_file_info_get_file_type (file_info);

      if (type != G_FILE_TYPE_REGULAR ||
          !g_str_has_suffix (name, FLATPAK_PREINSTALL_FILE_EXT))
        continue;

      config_file = g_new0 (PreinstallConfigFile, 1);
      config_file->name = g_strdup (name);
      config_file->file = g_object_ref (path);
      g_ptr_array_add (config_files, g_steal_pointer (&config_file));
    }

  g_ptr_array_sort (config_files, preinstall_config_file_sort);

  for (int i = 0; i < config_files->len; i++)
    {
      PreinstallConfigFile *config_file = g_ptr_array_index (config_files, i);
      g_autofree char *path = NULL;
      g_autoptr(GKeyFile) keyfile = NULL;
      g_autoptr(GError) load_error = NULL;

      path = g_file_get_path (config_file->file);

      g_info ("Parsing config file %s", path);

      keyfile = g_key_file_new ();

      if (!g_key_file_load_from_file (keyfile, path, G_KEY_FILE_NONE, &load_error))
        g_info ("Parsing config file %s failed: %s", path, load_error->message);

      flatpak_parse_preinstall_config_file (keyfile, configs);
    }

  return TRUE;
}

GPtrArray *
flatpak_get_preinstall_config (const char    *default_arch,
                               GCancellable  *cancellable,
                               GError       **error)
{
  g_autoptr(GHashTable) configs = NULL;
  g_autoptr(GPtrArray) preinstalls = NULL;
  g_autofree char *config_dir = NULL;
  g_autofree char *data_dir = NULL;
  GHashTableIter iter;
  PreinstallConfig *config;

  configs = g_hash_table_new_full (g_str_hash, g_str_equal,
                                   g_free, (GDestroyNotify)preinstall_config_free);

  /* scan directories in reverse priority order */
  data_dir = g_build_filename (get_data_dir_location (), FLATPAK_PREINSTALL_DIR, NULL);
  if (!scan_preinstall_config_files (data_dir, configs, cancellable, error))
    return NULL;

  config_dir = g_build_filename (get_config_dir_location (), FLATPAK_PREINSTALL_DIR, NULL);
  if (!scan_preinstall_config_files (config_dir, configs, cancellable, error))
    return NULL;

  preinstalls = g_ptr_array_new_with_free_func ((GDestroyNotify)flatpak_preinstall_config_free);

  g_hash_table_iter_init (&iter, configs);
  while (g_hash_table_iter_next (&iter, NULL, (gpointer *)&config))
    {
      g_autoptr(FlatpakPreinstallConfig) preinstall = NULL;
      g_autoptr(FlatpakDecomposed) ref = NULL;
      g_autoptr(GError) local_error = NULL;

      if (!config->install)
        {
          g_info ("Skipping preinstall of %s because it is configured to not install",
                  config->name);
          continue;
        }

      ref = flatpak_decomposed_new_from_parts (config->is_runtime ?
                                                 FLATPAK_KINDS_RUNTIME :
                                                 FLATPAK_KINDS_APP,
                                               config->name,
                                               default_arch,
                                               config->branch,
                                               &local_error);
      if (ref == NULL)
        {
          g_info ("Skipping preinstall of %s because of problems in the configuration: %s",
                  config->name,
                  local_error->message);
          continue;
        }

      preinstall = g_new0 (FlatpakPreinstallConfig, 1);
      preinstall->ref = g_steal_pointer (&ref);
      preinstall->collection_id = g_strdup (config->collection_id);

      g_info ("Found preinstall ref %s",
              flatpak_decomposed_get_ref (preinstall->ref));

      g_ptr_array_add (preinstalls, g_steal_pointer (&preinstall));
    }

  return g_steal_pointer (&preinstalls);
}

static gboolean
flatpak_is_ref_in_list (FlatpakDecomposed *needle,
                        GPtrArray         *refs)
{
  for (size_t i = 0; i < refs->len; i++)
    {
      FlatpakDecomposed *ref = g_ptr_array_index (refs, i);

      if (flatpak_decomposed_equal (ref, needle))
        return TRUE;
    }

  return FALSE;
}

gboolean
flatpak_dir_uninitialized_mark_preinstalled (FlatpakDir       *self,
                                             const GPtrArray  *preinstall_config,
                                             GError          **error)
{
  g_autoptr(GPtrArray) installed_refs = NULL;
  g_autofree char *existing_preinstalls = NULL;
  g_autoptr(GError) local_error = NULL;

  existing_preinstalls = flatpak_dir_get_config (self,
                                                 "preinstalled",
                                                 &local_error);

  if (existing_preinstalls != NULL)
    return TRUE;

  if (!g_error_matches (local_error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_KEY_NOT_FOUND))
    {
      g_propagate_error (error, g_steal_pointer (&local_error));
      return FALSE;
    }

  g_clear_error (&local_error);

  installed_refs = flatpak_dir_list_refs (self, FLATPAK_KINDS_RUNTIME | FLATPAK_KINDS_APP,
                                          NULL, error);
  if (installed_refs == NULL)
    return FALSE;

  for (int i = 0; i < preinstall_config->len; i++)
    {
      const FlatpakPreinstallConfig *config = g_ptr_array_index (preinstall_config, i);
      GError **append_error = local_error == NULL ? &local_error : NULL;

      if (!flatpak_is_ref_in_list (config->ref, installed_refs))
        continue;

      flatpak_dir_config_append_pattern (self,
                                         "preinstalled",
                                         flatpak_decomposed_get_ref (config->ref),
                                         FALSE,
                                         NULL,
                                         append_error);
    }

  if (local_error)
    {
      g_propagate_error (error, g_steal_pointer (&local_error));
      return FALSE;
    }

  return TRUE;
}

GPtrArray *
flatpak_get_system_base_dir_locations (GCancellable *cancellable,
                                       GError      **error)
{
  static gsize initialized = 0;
  static GPtrArray *array = NULL;

  if (g_once_init_enter (&initialized))
    {
      array = get_system_locations (cancellable, error);
      g_once_init_leave (&initialized, 1);
    }

  return array;
}

GFile *
flatpak_get_user_base_dir_location (void)
{
  static gsize file = 0;

  if (g_once_init_enter (&file))
    {
      gsize setup_value = 0;
      const char *path;
      g_autofree char *free_me = NULL;
      const char *user_dir = g_getenv ("FLATPAK_USER_DIR");
      if (user_dir != NULL && *user_dir != 0)
        path = user_dir;
      else
        path = free_me = g_build_filename (g_get_user_data_dir (), "flatpak", NULL);

      setup_value = (gsize) g_file_new_for_path (path);

      g_once_init_leave (&file, setup_value);
    }

  return g_object_ref ((GFile *) file);
}

static gboolean
validate_commit_metadata (GVariant   *commit_data,
                          const char *ref,
                          const char *required_metadata,
                          gsize       required_metadata_size,
                          GError   **error)
{
  g_autoptr(GVariant) commit_metadata = NULL;
  g_autoptr(GVariant) xa_metadata_v = NULL;
  const char *xa_metadata = NULL;
  gsize xa_metadata_size = 0;

  commit_metadata = g_variant_get_child_value (commit_data, 0);

  if (commit_metadata != NULL)
    {
      xa_metadata_v = g_variant_lookup_value (commit_metadata,
                                              "xa.metadata",
                                              G_VARIANT_TYPE_STRING);
      if (xa_metadata_v)
        xa_metadata = g_variant_get_string (xa_metadata_v, &xa_metadata_size);
    }

  if (xa_metadata == NULL ||
      xa_metadata_size != required_metadata_size ||
      memcmp (xa_metadata, required_metadata, xa_metadata_size) != 0)
    {
      g_set_error (error, G_IO_ERROR, G_IO_ERROR_PERMISSION_DENIED,
                   _("Commit metadata for %s not matching expected metadata"), ref);
      return FALSE;
    }

  return TRUE;
}

/* This is a cache directory similar to ~/.cache/flatpak/system-cache,
 * but in /var/tmp. This is useful for things like the system child
 * repos, because it is more likely to be on the same filesystem as
 * the system repo (thus increasing chances for e.g. reflink copying),
 * and avoids filling the users homedirectory with temporary data.
 *
 * In order to reuse this between instances we create a symlink
 * in /run to it and verify it before use.
 */
static GFile *
flatpak_ensure_system_user_cache_dir_location (GError **error)
{
  g_autofree char *path = NULL;
  g_autofree char *symlink_path = NULL;
  struct stat st_buf;
  const char *custom_path = g_getenv ("FLATPAK_SYSTEM_CACHE_DIR");

  if (custom_path != NULL && *custom_path != 0)
    {
      if (g_mkdir_with_parents (custom_path, 0755) != 0)
        {
          glnx_set_error_from_errno (error);
          return NULL;
        }

      return g_file_new_for_path (custom_path);
    }

  symlink_path = g_build_filename (g_get_user_runtime_dir (), ".flatpak-cache", NULL);
  path = flatpak_readlink (symlink_path, NULL);

  if (stat (path, &st_buf) == 0 &&
      /* Must be owned by us */
      st_buf.st_uid == getuid () &&
      /* and not writeable by others, but readable */
      (st_buf.st_mode & 0777) == 0755)
    return g_file_new_for_path (path);

  g_clear_pointer (&path, g_free);

  path = g_strdup ("/var/tmp/flatpak-cache-XXXXXX");

  if (g_mkdtemp_full (path, 0755) == NULL)
    {
      flatpak_fail (error, "Can't create temporary directory");
      return NULL;
    }

  unlink (symlink_path);
  if (symlink (path, symlink_path) != 0)
    {
      glnx_set_error_from_errno (error);
      return NULL;
    }

  return g_file_new_for_path (path);
}

static GFile *
flatpak_get_user_cache_dir_location (void)
{
  g_autoptr(GFile) base_dir = g_file_new_for_path (g_get_user_cache_dir ());

  return g_file_resolve_relative_path (base_dir, "flatpak/system-cache");
}

static GFile *
flatpak_ensure_user_cache_dir_location (GError **error)
{
  g_autoptr(GFile) cache_dir = NULL;
  g_autofree char *cache_path = NULL;

  cache_dir = flatpak_get_user_cache_dir_location ();
  cache_path = g_file_get_path (cache_dir);

  if (g_mkdir_with_parents (cache_path, 0755) != 0)
    {
      glnx_set_error_from_errno (error);
      return NULL;
    }

  return g_steal_pointer (&cache_dir);
}

static char *
flatpak_dir_get_os_info (FlatpakDir *self)
{
  g_autofree char *os_report_config = NULL;
  g_autofree char *os_id = NULL;
  g_autofree char *os_version = NULL;

  os_report_config = flatpak_dir_get_config (self, "report-os-info", NULL);

  if (g_strcmp0 (os_report_config, "false") == 0)
    return NULL;

  os_id = flatpak_get_os_release_id ();
  os_version = flatpak_get_os_release_version_id ();

  return g_strdup_printf ("%s;%s;%s", os_id, os_version, flatpak_get_arch ());
}

static GFile *
flatpak_dir_get_oci_cache_file (FlatpakDir *self,
                                const char *remote,
                                const char *suffix,
                                GError    **error)
{
  g_autoptr(GFile) oci_dir = NULL;
  g_autofree char *filename = NULL;

  oci_dir = g_file_get_child (flatpak_dir_get_path (self), "oci");
  if (g_mkdir_with_parents (flatpak_file_get_path_cached (oci_dir), 0755) != 0)
    {
      glnx_set_error_from_errno (error);
      return NULL;
    }

  filename = g_strconcat (remote, suffix, NULL);
  return g_file_get_child (oci_dir, filename);
}

static GFile *
flatpak_dir_get_oci_index_location (FlatpakDir *self,
                                    const char *remote,
                                    GError    **error)
{
  return flatpak_dir_get_oci_cache_file (self, remote, ".index.gz", error);
}

static GFile *
flatpak_dir_get_oci_summary_location (FlatpakDir *self,
                                      const char *remote,
                                      GError    **error)
{
  return flatpak_dir_get_oci_cache_file (self, remote, ".summary", error);
}

static gboolean
flatpak_dir_remove_oci_file (FlatpakDir   *self,
                             const char   *remote,
                             const char   *suffix,
                             GCancellable *cancellable,
                             GError      **error)
{
  g_autoptr(GFile) file = flatpak_dir_get_oci_cache_file (self, remote, suffix, error);
  g_autoptr(GError) local_error = NULL;

  if (file == NULL)
    return FALSE;

  if (!g_file_delete (file, cancellable, &local_error) &&
      !g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
    {
      g_propagate_error (error, g_steal_pointer (&local_error));
      return FALSE;
    }

  return TRUE;
}

static gboolean
flatpak_dir_remove_oci_files (FlatpakDir   *self,
                              const char   *remote,
                              GCancellable *cancellable,
                              GError      **error)
{
  if (!flatpak_dir_remove_oci_file (self, remote, ".index.gz", cancellable, error) ||
      !flatpak_dir_remove_oci_file (self, remote, ".summary", cancellable, error))
    return FALSE;

  return TRUE;
}

static gchar *
flatpak_dir_revokefs_fuse_create_mountpoint (FlatpakDecomposed *ref,
                                             GError           **error)
{
  g_autoptr(GFile) cache_dir = NULL;
  g_autofree gchar *cache_dir_path = NULL;
  g_autofree gchar *mnt_dir = NULL;
  g_autofree gchar *id = NULL;
  g_autofree gchar *mountpoint = NULL;

  cache_dir = flatpak_ensure_system_user_cache_dir_location (error);
  if (cache_dir == NULL)
    return NULL;

  id = flatpak_decomposed_dup_id (ref);
  cache_dir_path = g_file_get_path (cache_dir);
  mnt_dir = g_strdup_printf ("%s-XXXXXX", id);
  mountpoint = g_mkdtemp_full (g_build_filename (cache_dir_path, mnt_dir, NULL), 0755);
  if (mountpoint == NULL)
    {
      glnx_set_error_from_errno (error);
      return NULL;
    }

  return g_steal_pointer (&mountpoint);
}

static gboolean
flatpak_dir_revokefs_fuse_unmount (OstreeRepo **repo,
                                  GLnxLockFile *lockfile,
                                  const gchar *mnt_dir,
                                  GError **error)
{
  g_autoptr(GSubprocess) fusermount = NULL;

  /* Clear references to child_repo as not to leave any open fds. This is needed for
   * a clean umount operation.
   */
  g_clear_pointer (repo, g_object_unref);
  glnx_release_lock_file (lockfile);

  fusermount = g_subprocess_new (G_SUBPROCESS_FLAGS_NONE,
                                 error,
                                 FUSERMOUNT, "-u", "-z", mnt_dir, NULL);
  if (g_subprocess_wait_check (fusermount, NULL, error))
    {
      g_autoptr(GFile) mnt_dir_file = g_file_new_for_path (mnt_dir);
      g_autoptr(GError) tmp_error = NULL;

      if (!flatpak_rm_rf (mnt_dir_file, NULL, &tmp_error))
        g_warning ("Unable to remove mountpoint directory %s: %s", mnt_dir, tmp_error->message);

      return TRUE;
    }

  return FALSE;
}

static gboolean
flatpak_dir_use_system_helper (FlatpakDir *self,
                               const char *installing_from_remote)
{
#ifdef USE_SYSTEM_HELPER
  if (self->no_system_helper || self->user || getuid () == 0)
    return FALSE;

  /* OCI doesn't do signatures atm, so we can't use the system helper for this */
  if (installing_from_remote != NULL && flatpak_dir_get_remote_oci (self, installing_from_remote))
    return FALSE;

  return TRUE;
#else
  return FALSE;
#endif
}

static GVariant *
flatpak_dir_system_helper_call (FlatpakDir         *self,
                                const gchar        *method_name,
                                GVariant           *parameters,
                                const GVariantType *reply_type,
                                GUnixFDList       **out_fd_list,
                                GCancellable       *cancellable,
                                GError            **error)
{
  GVariant *res;

  if (g_once_init_enter (&self->system_helper_bus))
    {
      const char *on_session = g_getenv ("FLATPAK_SYSTEM_HELPER_ON_SESSION");
      GDBusConnection *system_helper_bus =
        g_bus_get_sync (on_session != NULL ? G_BUS_TYPE_SESSION : G_BUS_TYPE_SYSTEM,
                        cancellable, NULL);

      /* To ensure reverse mapping */
      flatpak_error_quark ();

      g_once_init_leave (&self->system_helper_bus, system_helper_bus ? system_helper_bus : (gpointer) 1 );
    }

  if (self->system_helper_bus == (gpointer) 1)
    {
      flatpak_fail (error, _("Unable to connect to system bus"));
      return NULL;
    }

  g_info ("Calling system helper: %s", method_name);
  res = g_dbus_connection_call_with_unix_fd_list_sync (self->system_helper_bus,
                                                       FLATPAK_SYSTEM_HELPER_BUS_NAME,
                                                       FLATPAK_SYSTEM_HELPER_PATH,
                                                       FLATPAK_SYSTEM_HELPER_INTERFACE,
                                                       method_name,
                                                       parameters,
                                                       reply_type,
                                                       G_DBUS_CALL_FLAGS_NONE, G_MAXINT,
                                                       NULL, out_fd_list,
                                                       cancellable,
                                                       error);

 if (res == NULL && error)
    g_dbus_error_strip_remote_error (*error);

  return res;
}

static gboolean
flatpak_dir_system_helper_call_deploy (FlatpakDir         *self,
                                       const gchar        *arg_repo_path,
                                       guint               arg_flags,
                                       const gchar        *arg_ref,
                                       const gchar        *arg_origin,
                                       const gchar *const *arg_subpaths,
                                       const gchar *const *arg_previous_ids,
                                       const gchar        *arg_installation,
                                       GCancellable       *cancellable,
                                       GError            **error)
{
  const char *empty[] = { NULL };

  if (arg_subpaths == NULL)
    arg_subpaths = empty;
  if (arg_previous_ids == NULL)
    arg_previous_ids = empty;

  if (flatpak_dir_get_no_interaction (self))
    arg_flags |= FLATPAK_HELPER_DEPLOY_FLAGS_NO_INTERACTION;

  g_autoptr(GVariant) ret =
    flatpak_dir_system_helper_call (self, "Deploy",
                                    g_variant_new ("(^ayuss^as^ass)",
                                                   arg_repo_path,
                                                   arg_flags,
                                                   arg_ref,
                                                   arg_origin,
                                                   arg_subpaths,
                                                   arg_previous_ids,
                                                   arg_installation),
                                    G_VARIANT_TYPE ("()"), NULL,
                                    cancellable, error);
  return ret != NULL;
}

static gboolean
flatpak_dir_system_helper_call_deploy_appstream (FlatpakDir   *self,
                                                 const gchar  *arg_repo_path,
                                                 guint         arg_flags,
                                                 const gchar  *arg_origin,
                                                 const gchar  *arg_arch,
                                                 const gchar  *arg_installation,
                                                 GCancellable *cancellable,
                                                 GError      **error)
{
  if (flatpak_dir_get_no_interaction (self))
    arg_flags |= FLATPAK_HELPER_DEPLOY_APPSTREAM_FLAGS_NO_INTERACTION;

  g_autoptr(GVariant) ret =
    flatpak_dir_system_helper_call (self, "DeployAppstream",
                                    g_variant_new ("(^ayusss)",
                                                   arg_repo_path,
                                                   arg_flags,
                                                   arg_origin,
                                                   arg_arch,
                                                   arg_installation),
                                    G_VARIANT_TYPE ("()"), NULL,
                                    cancellable, error);
  return ret != NULL;
}

static gboolean
flatpak_dir_system_helper_call_uninstall (FlatpakDir   *self,
                                          guint         arg_flags,
                                          const gchar  *arg_ref,
                                          const gchar  *arg_installation,
                                          GCancellable *cancellable,
                                          GError      **error)
{
  if (flatpak_dir_get_no_interaction (self))
    arg_flags |= FLATPAK_HELPER_UNINSTALL_FLAGS_NO_INTERACTION;

  g_autoptr(GVariant) ret =
    flatpak_dir_system_helper_call (self, "Uninstall",
                                    g_variant_new ("(uss)",
                                                   arg_flags,
                                                   arg_ref,
                                                   arg_installation),
                                    G_VARIANT_TYPE ("()"), NULL,
                                    cancellable, error);
  return ret != NULL;
}

static gboolean
flatpak_dir_system_helper_call_install_bundle (FlatpakDir   *self,
                                               const gchar  *arg_bundle_path,
                                               guint         arg_flags,
                                               const gchar  *arg_remote,
                                               const gchar  *arg_installation,
                                               gchar       **out_ref,
                                               GCancellable *cancellable,
                                               GError      **error)
{
  if (flatpak_dir_get_no_interaction (self))
    arg_flags |= FLATPAK_HELPER_INSTALL_BUNDLE_FLAGS_NO_INTERACTION;

  g_autoptr(GVariant) ret =
    flatpak_dir_system_helper_call (self, "InstallBundle",
                                    g_variant_new ("(^ayuss)",
                                                   arg_bundle_path,
                                                   arg_flags,
                                                   arg_remote,
                                                   arg_installation),
                                    G_VARIANT_TYPE ("(s)"), NULL,
                                    cancellable, error);
  if (ret == NULL)
    return FALSE;

  g_variant_get (ret, "(s)", out_ref);
  return TRUE;
}

static gboolean
flatpak_dir_system_helper_call_configure_remote (FlatpakDir   *self,
                                                 guint         arg_flags,
                                                 const gchar  *arg_remote,
                                                 const gchar  *arg_config,
                                                 GVariant     *arg_gpg_key,
                                                 const gchar  *arg_installation,
                                                 GCancellable *cancellable,
                                                 GError      **error)
{
  if (flatpak_dir_get_no_interaction (self))
    arg_flags |= FLATPAK_HELPER_CONFIGURE_REMOTE_FLAGS_NO_INTERACTION;

  g_autoptr(GVariant) ret =
    flatpak_dir_system_helper_call (self, "ConfigureRemote",
                                    g_variant_new ("(uss@ays)",
                                                   arg_flags,
                                                   arg_remote,
                                                   arg_config,
                                                   arg_gpg_key,
                                                   arg_installation),
                                    G_VARIANT_TYPE ("()"), NULL,
                                    cancellable,
                                    error);
  return ret != NULL;
}

static gboolean
flatpak_dir_system_helper_call_configure (FlatpakDir   *self,
                                          guint         arg_flags,
                                          const gchar  *arg_key,
                                          const gchar  *arg_value,
                                          const gchar  *arg_installation,
                                          GCancellable *cancellable,
                                          GError      **error)
{
  if (flatpak_dir_get_no_interaction (self))
    arg_flags |= FLATPAK_HELPER_CONFIGURE_FLAGS_NO_INTERACTION;

  g_autoptr(GVariant) ret =
    flatpak_dir_system_helper_call (self, "Configure",
                                    g_variant_new ("(usss)",
                                                   arg_flags,
                                                   arg_key,
                                                   arg_value,
                                                   arg_installation),
                                    G_VARIANT_TYPE ("()"), NULL,
                                    cancellable, error);
  return ret != NULL;
}

static gboolean
flatpak_dir_system_helper_call_update_remote (FlatpakDir   *self,
                                              guint         arg_flags,
                                              const gchar  *arg_remote,
                                              const gchar  *arg_installation,
                                              const gchar  *arg_summary_path,
                                              const gchar  *arg_summary_sig_path,
                                              GCancellable *cancellable,
                                              GError      **error)
{
  if (flatpak_dir_get_no_interaction (self))
    arg_flags |= FLATPAK_HELPER_UPDATE_REMOTE_FLAGS_NO_INTERACTION;

  g_autoptr(GVariant) ret =
    flatpak_dir_system_helper_call (self, "UpdateRemote",
                                    g_variant_new ("(uss^ay^ay)",
                                                   arg_flags,
                                                   arg_remote,
                                                   arg_installation,
                                                   arg_summary_path,
                                                   arg_summary_sig_path),
                                    G_VARIANT_TYPE ("()"), NULL,
                                    cancellable, error);
  return ret != NULL;
}

static gboolean
flatpak_dir_system_helper_call_remove_local_ref (FlatpakDir   *self,
                                                 guint         arg_flags,
                                                 const gchar  *arg_remote,
                                                 const gchar  *arg_ref,
                                                 const gchar  *arg_installation,
                                                 GCancellable *cancellable,
                                                 GError      **error)
{
  if (flatpak_dir_get_no_interaction (self))
    arg_flags |= FLATPAK_HELPER_REMOVE_LOCAL_REF_FLAGS_NO_INTERACTION;

  g_autoptr(GVariant) ret =
    flatpak_dir_system_helper_call (self, "RemoveLocalRef",
                                    g_variant_new ("(usss)",
                                                   arg_flags,
                                                   arg_remote,
                                                   arg_ref,
                                                   arg_installation),
                                    G_VARIANT_TYPE ("()"), NULL,
                                    cancellable, error);
  return ret != NULL;
}

static gboolean
flatpak_dir_system_helper_call_prune_local_repo (FlatpakDir   *self,
                                                 guint         arg_flags,
                                                 const gchar  *arg_installation,
                                                 GCancellable *cancellable,
                                                 GError      **error)
{
  if (flatpak_dir_get_no_interaction (self))
    arg_flags |= FLATPAK_HELPER_PRUNE_LOCAL_REPO_FLAGS_NO_INTERACTION;

  g_autoptr(GVariant) ret =
    flatpak_dir_system_helper_call (self, "PruneLocalRepo",
                                    g_variant_new ("(us)",
                                                   arg_flags,
                                                   arg_installation),
                                    G_VARIANT_TYPE ("()"), NULL,
                                    cancellable, error);
  return ret != NULL;
}

static gboolean
flatpak_dir_system_helper_call_run_triggers (FlatpakDir   *self,
                                             guint         arg_flags,
                                             const gchar  *arg_installation,
                                             GCancellable *cancellable,
                                             GError      **error)
{
  if (flatpak_dir_get_no_interaction (self))
    arg_flags |= FLATPAK_HELPER_RUN_TRIGGERS_FLAGS_NO_INTERACTION;

  g_autoptr(GVariant) ret =
    flatpak_dir_system_helper_call (self, "RunTriggers",
                                    g_variant_new ("(us)",
                                                   arg_flags,
                                                   arg_installation),
                                    G_VARIANT_TYPE ("()"), NULL,
                                    cancellable, error);
  return ret != NULL;
}

static gboolean
flatpak_dir_system_helper_call_ensure_repo (FlatpakDir   *self,
                                            guint         arg_flags,
                                            const gchar  *arg_installation,
                                            GCancellable *cancellable,
                                            GError      **error)
{
  if (flatpak_dir_get_no_interaction (self))
    arg_flags |= FLATPAK_HELPER_ENSURE_REPO_FLAGS_NO_INTERACTION;

  g_autoptr(GVariant) ret =
    flatpak_dir_system_helper_call (self, "EnsureRepo",
                                    g_variant_new ("(us)",
                                                   arg_flags,
                                                   arg_installation),
                                    G_VARIANT_TYPE ("()"), NULL,
                                    cancellable, error);
  return ret != NULL;
}

static gboolean
flatpak_dir_system_helper_call_cancel_pull (FlatpakDir    *self,
                                            guint          arg_flags,
                                            const gchar   *arg_installation,
                                            const gchar   *arg_src_dir,
                                            GCancellable  *cancellable,
                                            GError       **error)
{
  if (flatpak_dir_get_no_interaction (self))
    arg_flags |= FLATPAK_HELPER_CANCEL_PULL_FLAGS_NO_INTERACTION;

  g_info ("Calling system helper: CancelPull");

  g_autoptr(GVariant) ret =
    flatpak_dir_system_helper_call (self, "CancelPull",
                                    g_variant_new ("(uss)",
                                                   arg_flags,
                                                   arg_installation,
                                                   arg_src_dir),
                                    NULL, NULL,
                                    cancellable, error);

   return ret != NULL;
}

static gboolean
flatpak_dir_system_helper_call_get_revokefs_fd (FlatpakDir   *self,
                                                guint         arg_flags,
                                                const gchar  *arg_installation,
                                                gint         *out_socket,
                                                gchar       **out_src_dir,
                                                GCancellable *cancellable,
                                                GError      **error)
{
  g_autoptr(GUnixFDList) out_fd_list = NULL;
  gint fd = -1;
  gint fd_index = -1;

  if (flatpak_dir_get_no_interaction (self))
    arg_flags |= FLATPAK_HELPER_GET_REVOKEFS_FD_FLAGS_NO_INTERACTION;

  g_info ("Calling system helper: GetRevokefsFd");

  g_autoptr(GVariant) ret =
    flatpak_dir_system_helper_call (self, "GetRevokefsFd",
                                    g_variant_new ("(us)",
                                                   arg_flags,
                                                   arg_installation),
                                    G_VARIANT_TYPE ("(hs)"),
                                    &out_fd_list,
                                    cancellable, error);

  if (ret == NULL)
    return FALSE;

  g_variant_get (ret, "(hs)", &fd_index, out_src_dir);
  fd  = g_unix_fd_list_get (out_fd_list, fd_index, error);
  if (fd == -1)
    return FALSE;

  *out_socket = fd;

  return TRUE;
}

static gboolean
flatpak_dir_system_helper_call_update_summary (FlatpakDir   *self,
                                               guint         arg_flags,
                                               const gchar  *arg_installation,
                                               GCancellable *cancellable,
                                               GError      **error)
{
  if (flatpak_dir_get_no_interaction (self))
    arg_flags |= FLATPAK_HELPER_UPDATE_SUMMARY_FLAGS_NO_INTERACTION;

  g_autoptr(GVariant) ret =
    flatpak_dir_system_helper_call (self, "UpdateSummary",
                                    g_variant_new ("(us)",
                                                   arg_flags,
                                                   arg_installation),
                                    G_VARIANT_TYPE ("()"), NULL,
                                    cancellable, error);
  return ret != NULL;
}

static gboolean
flatpak_dir_system_helper_call_generate_oci_summary (FlatpakDir   *self,
                                                     guint         arg_flags,
                                                     const gchar  *arg_origin,
                                                     const gchar  *arg_installation,
                                                     GCancellable *cancellable,
                                                     GError      **error)
{
  if (flatpak_dir_get_no_interaction (self))
    arg_flags |= FLATPAK_HELPER_GENERATE_OCI_SUMMARY_FLAGS_NO_INTERACTION;

  g_autoptr(GVariant) ret =
    flatpak_dir_system_helper_call (self, "GenerateOciSummary",
                                    g_variant_new ("(uss)",
                                                   arg_flags,
                                                   arg_origin,
                                                   arg_installation),
                                    G_VARIANT_TYPE ("()"), NULL,
                                    cancellable, error);
  return ret != NULL;
}

static void
flatpak_dir_finalize (GObject *object)
{
  FlatpakDir *self = FLATPAK_DIR (object);

  g_clear_object (&self->repo);
  g_clear_object (&self->cache_dir);
  g_clear_object (&self->basedir);
  g_clear_pointer (&self->extra_data, dir_extra_data_free);

  if (self->system_helper_bus != (gpointer) 1)
    g_clear_object (&self->system_helper_bus);

  g_clear_pointer (&self->http_session, flatpak_http_session_free);
  g_clear_pointer (&self->summary_cache, g_hash_table_unref);
  g_clear_pointer (&self->remote_filters, g_hash_table_unref);
  g_clear_pointer (&self->masked, g_regex_unref);
  g_clear_pointer (&self->pinned, g_regex_unref);
  g_clear_object (&self->subject);

  G_OBJECT_CLASS (flatpak_dir_parent_class)->finalize (object);
}

static void
flatpak_dir_set_property (GObject      *object,
                          guint         prop_id,
                          const GValue *value,
                          GParamSpec   *pspec)
{
  FlatpakDir *self = FLATPAK_DIR (object);

  switch (prop_id)
    {
    case PROP_PATH:
      /* Canonicalize */
      self->basedir = g_file_new_for_path (flatpak_file_get_path_cached (g_value_get_object (value)));
      break;

    case PROP_USER:
      self->user = g_value_get_boolean (value);
      break;

    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
    }
}

static void
flatpak_dir_get_property (GObject    *object,
                          guint       prop_id,
                          GValue     *value,
                          GParamSpec *pspec)
{
  FlatpakDir *self = FLATPAK_DIR (object);

  switch (prop_id)
    {
    case PROP_PATH:
      g_value_set_object (value, self->basedir);
      break;

    case PROP_USER:
      g_value_set_boolean (value, self->user);
      break;

    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
    }
}

static void
flatpak_dir_class_init (FlatpakDirClass *klass)
{
  GObjectClass *object_class = G_OBJECT_CLASS (klass);

  object_class->get_property = flatpak_dir_get_property;
  object_class->set_property = flatpak_dir_set_property;
  object_class->finalize = flatpak_dir_finalize;

  g_object_class_install_property (object_class,
                                   PROP_USER,
                                   g_param_spec_boolean ("user",
                                                         "",
                                                         "",
                                                         FALSE,
                                                         G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
  g_object_class_install_property (object_class,
                                   PROP_PATH,
                                   g_param_spec_object ("path",
                                                        "",
                                                        "",
                                                        G_TYPE_FILE,
                                                        G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
}

static void
flatpak_dir_init (FlatpakDir *self)
{
  /* Work around possible deadlock due to: https://bugzilla.gnome.org/show_bug.cgi?id=674885 */
  g_type_ensure (G_TYPE_UNIX_SOCKET_ADDRESS);

  /* Optional data that needs initialization */
  self->extra_data = NULL;
}

gboolean
flatpak_dir_is_user (FlatpakDir *self)
{
  return self->user;
}

void
flatpak_dir_set_no_system_helper (FlatpakDir *self,
                                  gboolean    no_system_helper)
{
  self->no_system_helper = no_system_helper;
}

void
flatpak_dir_set_no_interaction (FlatpakDir *self,
                                gboolean    no_interaction)
{
  self->no_interaction = no_interaction;
}

gboolean
flatpak_dir_get_no_interaction (FlatpakDir *self)
{
  return self->no_interaction;
}

GFile *
flatpak_dir_get_path (FlatpakDir *self)
{
  return self->basedir;
}

GFile *
flatpak_dir_get_changed_path (FlatpakDir *self)
{
  return g_file_get_child (self->basedir, ".changed");
}

const char *
flatpak_dir_get_id (FlatpakDir *self)
{
  if (self->user)
    return "user";

  if (self->extra_data != NULL)
    return self->extra_data->id;

  return NULL;
}

char *
flatpak_dir_get_name (FlatpakDir *self)
{
  const char *id = NULL;

  if (self->user)
    return g_strdup ("user");

  id = flatpak_dir_get_id (self);
  if (id != NULL && g_strcmp0 (id, SYSTEM_DIR_DEFAULT_ID) != 0)
    return g_strdup_printf ("system (%s)", id);

  return g_strdup ("system");
}

const char *
flatpak_dir_get_name_cached (FlatpakDir *self)
{
  char *name;

  name = g_object_get_data (G_OBJECT (self), "cached-name");
  if (!name)
    {
      name = flatpak_dir_get_name (self),
      g_object_set_data_full (G_OBJECT (self), "cached-name", name, g_free);
    }

  return (const char *) name;
}

char *
flatpak_dir_get_display_name (FlatpakDir *self)
{
  if (self->user)
    return g_strdup (_("User installation"));

  if (self->extra_data != NULL && g_strcmp0 (self->extra_data->id, SYSTEM_DIR_DEFAULT_ID) != 0)
    {
      if (self->extra_data->display_name)
        return g_strdup (self->extra_data->display_name);

      return g_strdup_printf (_("System (%s) installation"), self->extra_data->id);
    }

  return g_strdup (SYSTEM_DIR_DEFAULT_DISPLAY_NAME);
}

gint
flatpak_dir_get_priority (FlatpakDir *self)
{
  if (self->extra_data != NULL)
    return self->extra_data->priority;

  return 0;
}

FlatpakDirStorageType
flatpak_dir_get_storage_type (FlatpakDir *self)
{
  if (self->extra_data != NULL)
    return self->extra_data->storage_type;

  return FLATPAK_DIR_STORAGE_TYPE_DEFAULT;
}

char *
flatpak_dir_load_override (FlatpakDir *self,
                           const char *app_id,
                           gsize      *length,
                           GFile     **file_out,
                           GError    **error)
{
  g_autoptr(GFile) override_dir = NULL;
  g_autoptr(GFile) file = NULL;
  char *metadata_contents;

  override_dir = g_file_get_child (self->basedir, "overrides");

  if (app_id)
    file = g_file_get_child (override_dir, app_id);
  else
    file = g_file_get_child (override_dir, "global");

  if (!g_file_load_contents (file, NULL,
                             &metadata_contents, length, NULL, NULL))
    {
      g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND,
                   _("No overrides found for %s"), app_id);
      return NULL;
    }

  if (file_out != NULL)
    *file_out = g_object_ref (file);

  return metadata_contents;
}

GKeyFile *
flatpak_load_override_keyfile (const char *app_id, gboolean user, GError **error)
{
  g_autofree char *metadata_contents = NULL;
  gsize metadata_size;
  g_autoptr(GFile) file = NULL;
  g_autoptr(GKeyFile) metakey = g_key_file_new ();
  g_autoptr(FlatpakDir) dir = NULL;

  dir = user ? flatpak_dir_get_user () : flatpak_dir_get_system_default ();

  metadata_contents = flatpak_dir_load_override (dir, app_id, &metadata_size, &file, error);
  if (metadata_contents == NULL)
    return NULL;

  if (!g_key_file_load_from_data (metakey,
                                  metadata_contents,
                                  metadata_size,
                                  0, error))
    return glnx_prefix_error_null (error, "%s", flatpak_file_get_path_cached (file));

  return g_steal_pointer (&metakey);
}

FlatpakContext *
flatpak_load_override_file (const char *app_id, gboolean user, GError **error)
{
  g_autoptr(FlatpakContext) overrides = flatpak_context_new ();
  g_autoptr(GKeyFile) metakey = NULL;
  g_autoptr(GError) my_error = NULL;

  metakey = flatpak_load_override_keyfile (app_id, user, &my_error);
  if (metakey == NULL)
    {
      if (!g_error_matches (my_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
        {
          g_propagate_error (error, g_steal_pointer (&my_error));
          return NULL;
        }
    }
  else
    {
      if (!flatpak_context_load_metadata (overrides, metakey, error))
        return NULL;
    }

  return g_steal_pointer (&overrides);
}

gboolean
flatpak_save_override_keyfile (GKeyFile   *metakey,
                               const char *app_id,
                               gboolean    user,
                               GError    **error)
{
  g_autoptr(GFile) base_dir = NULL;
  g_autoptr(GFile) override_dir = NULL;
  g_autoptr(GFile) file = NULL;
  g_autofree char *filename = NULL;
  g_autofree char *parent = NULL;

  if (user)
    base_dir = flatpak_get_user_base_dir_location ();
  else
    base_dir = flatpak_get_system_default_base_dir_location ();

  override_dir = g_file_get_child (base_dir, "overrides");

  if (app_id)
    file = g_file_get_child (override_dir, app_id);
  else
    file = g_file_get_child (override_dir, "global");

  filename = g_file_get_path (file);
  parent = g_path_get_dirname (filename);
  if (g_mkdir_with_parents (parent, 0755))
    {
      glnx_set_error_from_errno (error);
      return FALSE;
    }

  return g_key_file_save_to_file (metakey, filename, error);
}

gboolean
flatpak_remove_override_keyfile (const char *app_id,
                                 gboolean    user,
                                 GError    **error)
{
  g_autoptr(GFile) base_dir = NULL;
  g_autoptr(GFile) override_dir = NULL;
  g_autoptr(GFile) file = NULL;
  g_autoptr(GError) local_error = NULL;

  if (user)
    base_dir = flatpak_get_user_base_dir_location ();
  else
    base_dir = flatpak_get_system_default_base_dir_location ();

  override_dir = g_file_get_child (base_dir, "overrides");

  if (app_id)
    file = g_file_get_child (override_dir, app_id);
  else
    file = g_file_get_child (override_dir, "global");

  if (!g_file_delete (file, NULL, &local_error) &&
      !g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
    {
      g_propagate_error (error, g_steal_pointer (&local_error));
      return FALSE;
    }

  return TRUE;
}

/* Note: passing a checksum only works here for non-sub-set deploys, not
   e.g. a partial locale install, because it will not find the real
   deploy directory. This is ok for now, because checksum is only
   currently passed from flatpak_installation_launch() when launching
   a particular version of an app, which is not used for locales. */
FlatpakDeploy *
flatpak_dir_load_deployed (FlatpakDir        *self,
                           FlatpakDecomposed *ref,
                           const char        *checksum,
                           GCancellable      *cancellable,
                           GError           **error)
{
  g_autoptr(GFile) deploy_dir = NULL;
  g_autoptr(GKeyFile) metakey = NULL;
  g_autoptr(GFile) metadata = NULL;
  g_autofree char *metadata_contents = NULL;
  FlatpakDeploy *deploy;
  gsize metadata_size;

  deploy_dir = flatpak_dir_get_if_deployed (self, ref, checksum, cancellable);
  if (deploy_dir == NULL)
    {
      if (checksum == NULL)
        g_set_error (error, FLATPAK_ERROR, FLATPAK_ERROR_NOT_INSTALLED,
                     _("%s not installed"), flatpak_decomposed_get_ref (ref));
      else
        g_set_error (error, FLATPAK_ERROR, FLATPAK_ERROR_NOT_INSTALLED,
                     _("%s (commit %s) not installed"), flatpak_decomposed_get_ref (ref), checksum);
      return NULL;
    }

  if (!flatpak_dir_ensure_repo (self, cancellable, error))
    return NULL;

  metadata = g_file_get_child (deploy_dir, "metadata");
  if (!g_file_load_contents (metadata, cancellable, &metadata_contents, &metadata_size, NULL, error))
    return NULL;

  metakey = g_key_file_new ();
  if (!g_key_file_load_from_data (metakey, metadata_contents, metadata_size, 0, error))
    return glnx_prefix_error_null (error, "%s", flatpak_file_get_path_cached (metadata));

  deploy = flatpak_deploy_new (deploy_dir, ref, metakey, self->repo);

  /* Only load system global overrides for system installed apps */
  if (!self->user)
    {
      deploy->system_overrides = flatpak_load_override_file (NULL, FALSE, error);
      if (deploy->system_overrides == NULL)
        return NULL;
    }

  /* Always load user global overrides */
  deploy->user_overrides = flatpak_load_override_file (NULL, TRUE, error);
  if (deploy->user_overrides == NULL)
    return NULL;

  /* Only apps have app overrides */
  if (flatpak_decomposed_is_app (ref))
    {
      g_autofree char *id = flatpak_decomposed_dup_id (ref);

      /* Only load system overrides for system installed apps */
      if (!self->user)
        {
          deploy->system_app_overrides = flatpak_load_override_file (id, FALSE, error);
          if (deploy->system_app_overrides == NULL)
            return NULL;
        }

      /* Always load user overrides */
      deploy->user_app_overrides = flatpak_load_override_file (id, TRUE, error);
      if (deploy->user_app_overrides == NULL)
        return NULL;
    }

  return deploy;
}

GFile *
flatpak_dir_get_deploy_dir (FlatpakDir *self,
                            FlatpakDecomposed *ref)
{
  return g_file_resolve_relative_path (self->basedir, flatpak_decomposed_get_ref (ref));
}

char *
flatpak_dir_get_deploy_subdir (FlatpakDir          *self,
                               const char          *checksum,
                               const char * const * subpaths)
{
  if (subpaths == NULL || *subpaths == NULL)
    return g_strdup (checksum);
  else
    {
      GString *str = g_string_new (checksum);
      int i;
      for (i = 0; subpaths[i] != NULL; i++)
        {
          const char *s = subpaths[i];
          g_string_append_c (str, '-');
          while (*s)
            {
              if (*s != '/')
                g_string_append_c (str, *s);
              s++;
            }
        }
      return g_string_free (str, FALSE);
    }
}

GFile *
flatpak_dir_get_unmaintained_extension_dir (FlatpakDir *self,
                                            const char *name,
                                            const char *arch,
                                            const char *branch)
{
  g_autofree char *unmaintained_ref = NULL;

  unmaintained_ref = g_build_filename ("extension", name, arch, branch, NULL);
  return g_file_resolve_relative_path (self->basedir, unmaintained_ref);
}

GFile *
flatpak_dir_get_exports_dir (FlatpakDir *self)
{
  return g_file_get_child (self->basedir, "exports");
}

GFile *
flatpak_dir_get_removed_dir (FlatpakDir *self)
{
  return g_file_get_child (self->basedir, ".removed");
}

GFile *
flatpak_dir_get_sideload_repos_dir (FlatpakDir *self)
{
  return g_file_get_child (self->basedir, SIDELOAD_REPOS_DIR_NAME);
}

GFile *
flatpak_dir_get_runtime_sideload_repos_dir (FlatpakDir *self)
{
  g_autoptr(GFile) base = g_file_new_for_path (get_run_dir_location ());
  return g_file_get_child (base, SIDELOAD_REPOS_DIR_NAME);
}

OstreeRepo *
flatpak_dir_get_repo (FlatpakDir *self)
{
  return self->repo;
}


/* This is an exclusive per flatpak installation file lock that is taken
 * whenever any config in the directory outside the repo is to be changed. For
 * instance deployments, overrides or active commit changes.
 *
 * For concurrency protection of the actual repository we rely on ostree
 * to do the right thing.
 */
gboolean
flatpak_dir_lock (FlatpakDir   *self,
                  GLnxLockFile *lockfile,
                  GCancellable *cancellable,
                  GError      **error)
{
  g_autoptr(GFile) lock_file = g_file_get_child (flatpak_dir_get_path (self), "lock");
  g_autofree char *lock_path = g_file_get_path (lock_file);

  return glnx_make_lock_file (AT_FDCWD, lock_path, LOCK_EX, lockfile, error);
}


/* This is an lock that protects the repo itself. Any operation that
 * relies on objects not disappearing from the repo need to hold this
 * in a non-exclusive mode, while anything that can remove objects
 * (i.e. prune) need to take it in exclusive mode.
 *
 * The following operations depends on objects not disappearing:
 *  * pull into a staging directory (pre-existing objects are not downloaded)
 *  * moving a staging directory into the repo (no ref keeps the object alive during copy)
 *  * Deploying a ref (a parallel update + prune could cause objects to be removed)
 *
 * In practice this means we hold a shared lock during deploy and
 * pull, and an excusive lock during prune.
 */
gboolean
flatpak_dir_repo_lock (FlatpakDir   *self,
                       GLnxLockFile *lockfile,
                       int           operation,
                       GCancellable *cancellable,
                       GError      **error)
{
  g_autoptr(GFile) lock_file = g_file_get_child (flatpak_dir_get_path (self), "repo-lock");
  g_autofree char *lock_path = g_file_get_path (lock_file);

  return glnx_make_lock_file (AT_FDCWD, lock_path, operation, lockfile, error);
}

const char *
flatpak_deploy_data_get_origin (GBytes *deploy_data)
{
  VarDeployDataRef ref = var_deploy_data_from_bytes (deploy_data);
  return var_deploy_data_get_origin (ref);
}

const char *
flatpak_deploy_data_get_commit (GBytes *deploy_data)
{
  VarDeployDataRef ref = var_deploy_data_from_bytes (deploy_data);
  return var_deploy_data_get_commit (ref);
}

gint32
flatpak_deploy_data_get_version (GBytes *deploy_data)
{
  VarDeployDataRef ref = var_deploy_data_from_bytes (deploy_data);
  VarMetadataRef metadata = var_deploy_data_get_metadata (ref);

  return var_metadata_lookup_int32 (metadata, "deploy-version", 0);
}

/* Note: This will return 0 if this is unset, which happens on deloy data updates, so ensure we handle that in all callers */
guint64
flatpak_deploy_data_get_timestamp (GBytes *deploy_data)
{
  VarDeployDataRef ref = var_deploy_data_from_bytes (deploy_data);
  VarMetadataRef metadata = var_deploy_data_get_metadata (ref);

  return var_metadata_lookup_uint64 (metadata, "timestamp", 0);
}

static const char *
flatpak_deploy_data_get_string (GBytes *deploy_data, const char *key)
{
  VarDeployDataRef ref = var_deploy_data_from_bytes (deploy_data);
  VarMetadataRef metadata = var_deploy_data_get_metadata (ref);

  return var_metadata_lookup_string (metadata, key, NULL);
}

static const char *
flatpak_deploy_data_get_localed_string (GBytes *deploy_data, const char *key)
{
  VarDeployDataRef ref = var_deploy_data_from_bytes (deploy_data);
  VarMetadataRef metadata = var_deploy_data_get_metadata (ref);
  const char * const * languages = g_get_language_names ();
  int i;

  for (i = 0; languages[i]; ++i)
    {
      g_autofree char *localed_key = NULL;
      VarVariantRef value_v;

      if (strcmp (languages[i], "C") == 0)
        localed_key = g_strdup (key);
      else
        localed_key = g_strdup_printf ("%s@%s", key, languages[i]);

      if (var_metadata_lookup (metadata, localed_key, NULL,  &value_v) &&
          var_variant_is_type (value_v, G_VARIANT_TYPE_STRING))
        return var_variant_get_string (value_v);
    }

  return NULL;
}

const char *
flatpak_deploy_data_get_alt_id (GBytes *deploy_data)
{
  return flatpak_deploy_data_get_string (deploy_data, "alt-id");
}

const char *
flatpak_deploy_data_get_eol (GBytes *deploy_data)
{
  return flatpak_deploy_data_get_string (deploy_data, "eol");
}

const char *
flatpak_deploy_data_get_eol_rebase (GBytes *deploy_data)
{
  return flatpak_deploy_data_get_string (deploy_data, "eolr");
}

/*<private>
 * flatpak_deploy_data_get_previous_ids:
 *
 * Returns: (array length=length zero-terminated=1) (transfer container): an array of constant strings
 **/
const char **
flatpak_deploy_data_get_previous_ids (GBytes *deploy_data, gsize *length)
{
  VarDeployDataRef ref = var_deploy_data_from_bytes (deploy_data);
  VarMetadataRef metadata = var_deploy_data_get_metadata (ref);
  VarVariantRef previous_ids_v;

  if (var_metadata_lookup (metadata, "previous-ids", NULL,  &previous_ids_v))
    return var_arrayofstring_to_strv (var_arrayofstring_from_variant (previous_ids_v), length);

  if (length != NULL)
    *length = 0;

  return NULL;
}

const char *
flatpak_deploy_data_get_runtime (GBytes *deploy_data)
{
  return flatpak_deploy_data_get_string (deploy_data, "runtime");
}

const char *
flatpak_deploy_data_get_extension_of (GBytes *deploy_data)
{
  return flatpak_deploy_data_get_string (deploy_data, "extension-of");
}

const char *
flatpak_deploy_data_get_appdata_name (GBytes *deploy_data)
{
  return flatpak_deploy_data_get_localed_string (deploy_data, "appdata-name");
}

const char *
flatpak_deploy_data_get_appdata_summary (GBytes *deploy_data)
{
  return flatpak_deploy_data_get_localed_string (deploy_data, "appdata-summary");
}

const char *
flatpak_deploy_data_get_appdata_version (GBytes *deploy_data)
{
  return flatpak_deploy_data_get_string (deploy_data, "appdata-version");
}

const char *
flatpak_deploy_data_get_appdata_license (GBytes *deploy_data)
{
  return flatpak_deploy_data_get_string (deploy_data, "appdata-license");
}

const char *
flatpak_deploy_data_get_appdata_content_rating_type (GBytes *deploy_data)
{
  VarDeployDataRef ref = var_deploy_data_from_bytes (deploy_data);
  VarMetadataRef metadata = var_deploy_data_get_metadata (ref);
  VarVariantRef rating_v;

  if (var_metadata_lookup (metadata, "appdata-content-rating", NULL,  &rating_v))
    {
      VarContentRatingRef rating = var_content_rating_from_variant (rating_v);
      return var_content_rating_get_rating_type (rating);
    }

  return NULL;
}

GHashTable *  /* (transfer container) (nullable) */
flatpak_deploy_data_get_appdata_content_rating (GBytes *deploy_data)
{
  VarDeployDataRef ref = var_deploy_data_from_bytes (deploy_data);
  VarMetadataRef metadata = var_deploy_data_get_metadata (ref);
  VarVariantRef rating_v;
  g_autoptr(GHashTable) content_rating = NULL;

  if (var_metadata_lookup (metadata, "appdata-content-rating", NULL,  &rating_v))
    {
      VarContentRatingRef rating = var_content_rating_from_variant (rating_v);
      VarRatingsRef ratings = var_content_rating_get_ratings (rating);
      gsize len, i;

      content_rating = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, NULL);

      len = var_ratings_get_length (ratings);
      for (i = 0; i < len; i++)
        {
          VarRatingsEntryRef entry = var_ratings_get_at (ratings, i);

          g_hash_table_insert (content_rating,
                               (gpointer) g_intern_string (var_ratings_entry_get_key (entry)),
                               (gpointer) g_intern_string (var_ratings_entry_get_value (entry)));
        }
    }

  return g_steal_pointer (&content_rating);
}

/*<private>
 * flatpak_deploy_data_get_subpaths:
 *
 * Returns: (array zero-terminated=1) (transfer container): an array of constant strings
 **/
const char **
flatpak_deploy_data_get_subpaths (GBytes *deploy_data)
{
  VarDeployDataRef ref = var_deploy_data_from_bytes (deploy_data);
  return var_arrayofstring_to_strv (var_deploy_data_get_subpaths (ref), NULL);
}

gboolean
flatpak_deploy_data_has_subpaths (GBytes *deploy_data)
{
  VarDeployDataRef ref = var_deploy_data_from_bytes (deploy_data);
  VarArrayofstringRef subpaths = var_deploy_data_get_subpaths (ref);

  return var_arrayofstring_get_length (subpaths) != 0;
}

guint64
flatpak_deploy_data_get_installed_size (GBytes *deploy_data)
{
  VarDeployDataRef ref = var_deploy_data_from_bytes (deploy_data);
  return var_deploy_data_get_installed_size (ref);
}

static char *
read_appdata_xml_from_deploy_dir (GFile *deploy_dir, const char *id)
{
  g_autoptr(GFile) appdata_file = NULL;
  g_autofree char *appdata_name = NULL;
  g_autoptr(GFileInputStream) appdata_in = NULL;
  gsize size;

  appdata_name = g_strconcat (id, ".xml.gz", NULL);
  appdata_file  = flatpak_build_file (deploy_dir, "files/share/app-info/xmls", appdata_name, NULL);

  appdata_in = g_file_read (appdata_file, NULL, NULL);
  if (appdata_in)
    {
      g_autoptr(GZlibDecompressor) decompressor = g_zlib_decompressor_new (G_ZLIB_COMPRESSOR_FORMAT_GZIP);
      g_autoptr(GInputStream) converter = g_converter_input_stream_new (G_INPUT_STREAM (appdata_in), G_CONVERTER (decompressor));
      g_autoptr(GBytes) appdata_xml = NULL;

      appdata_xml = flatpak_read_stream (converter, TRUE, NULL);
      if (appdata_xml)
        return g_bytes_unref_to_data (g_steal_pointer (&appdata_xml), &size);
    }

  return NULL;
}

static void
add_locale_metadata_string (GVariantDict *metadata_dict,
                            const char   *keyname,
                            GHashTable   *values)
{
  if (values == NULL)
    return;

  GLNX_HASH_TABLE_FOREACH_KV (values, const char *, locale, const char *, value)
  {
    const char *key;
    g_autofree char *key_free = NULL;

    if (strcmp (locale, "C") == 0)
      key = keyname;
    else
      {
        key_free = g_strdup_printf ("%s@%s", keyname, locale);
        key = key_free;
      }

    g_variant_dict_insert_value (metadata_dict, key,
                                 g_variant_new_string (value));
  }
}

/* Convert @content_rating_type and @content_rating to a floating #GVariant of
 * type `(sa{ss})`. */
static GVariant *
appdata_content_rating_to_variant (const char *content_rating_type,
                                   GHashTable *content_rating)
{
  g_autoptr(GVariantBuilder) builder = g_variant_builder_new (G_VARIANT_TYPE ("(sa{ss})"));
  GHashTableIter iter;
  gpointer key, value;

  g_variant_builder_add (builder, "s", content_rating_type);
  g_variant_builder_open (builder, G_VARIANT_TYPE ("a{ss}"));

  g_hash_table_iter_init (&iter, content_rating);

  while (g_hash_table_iter_next (&iter, &key, &value))
    {
      const char *id = key, *val = value;
      g_variant_builder_add (builder, "{ss}", id, val);
    }

  g_variant_builder_close (builder);

  return g_variant_builder_end (builder);
}

static void
add_appdata_to_deploy_data (GVariantDict *metadata_dict,
                            GFile        *deploy_dir,
                            const char   *id)
{
  g_autofree char *appdata_xml = NULL;
  g_autoptr(GHashTable) names = NULL;
  g_autoptr(GHashTable) comments = NULL;
  g_autofree char *version = NULL;
  g_autofree char *license = NULL;
  g_autofree char *content_rating_type = NULL;
  g_autoptr(GHashTable) content_rating = NULL;

  appdata_xml = read_appdata_xml_from_deploy_dir (deploy_dir, id);
  if (appdata_xml == NULL)
    return;

  if (flatpak_parse_appdata (appdata_xml, id, &names, &comments, &version, &license,
                             &content_rating_type, &content_rating))
    {
      add_locale_metadata_string (metadata_dict, "appdata-name", names);
      add_locale_metadata_string (metadata_dict, "appdata-summary", comments);
      if (version)
        g_variant_dict_insert_value (metadata_dict, "appdata-version",
                                     g_variant_new_string (version));
      if (license)
        g_variant_dict_insert_value (metadata_dict, "appdata-license",
                                     g_variant_new_string (license));
      if (content_rating_type != NULL && content_rating != NULL)
        g_variant_dict_insert_value (metadata_dict, "appdata-content-rating",
                                     appdata_content_rating_to_variant (content_rating_type, content_rating));
    }
}

static void
add_commit_metadata_to_deploy_data (GVariantDict *metadata_dict,
                                    GVariant     *commit_metadata)
{
  const char *alt_id = NULL;
  const char *eol = NULL;
  const char *eol_rebase = NULL;

  g_variant_lookup (commit_metadata, "xa.alt-id", "&s", &alt_id);
  g_variant_lookup (commit_metadata, OSTREE_COMMIT_META_KEY_ENDOFLIFE, "&s", &eol);
  g_variant_lookup (commit_metadata, OSTREE_COMMIT_META_KEY_ENDOFLIFE_REBASE, "&s", &eol_rebase);

  if (alt_id)
    g_variant_dict_insert_value (metadata_dict, "alt-id",
                                 g_variant_new_string (alt_id));
  if (eol)
    g_variant_dict_insert_value (metadata_dict, "eol",
                                 g_variant_new_string (eol));
  if (eol_rebase)
    g_variant_dict_insert_value (metadata_dict, "eolr",
                                 g_variant_new_string (eol_rebase));
}

static void
add_metadata_to_deploy_data (GVariantDict *metadata_dict,
                             GKeyFile     *keyfile)
{
  g_autofree char *application_runtime = NULL;
  g_autofree char *extension_of = NULL;

  application_runtime = g_key_file_get_string (keyfile,
                                               FLATPAK_METADATA_GROUP_APPLICATION,
                                               FLATPAK_METADATA_KEY_RUNTIME, NULL);
  extension_of = g_key_file_get_string (keyfile,
                                        FLATPAK_METADATA_GROUP_EXTENSION_OF,
                                        FLATPAK_METADATA_KEY_REF, NULL);

  if (application_runtime)
    g_variant_dict_insert_value (metadata_dict, "runtime",
                                 g_variant_new_string (application_runtime));
  if (extension_of)
    g_variant_dict_insert_value (metadata_dict, "extension-of",
                                 g_variant_new_string (extension_of));
}

static GBytes *
flatpak_dir_new_deploy_data (FlatpakDir         *self,
                             GFile              *deploy_dir,
                             GVariant           *commit_data,
                             GVariant           *commit_metadata,
                             GKeyFile           *metadata,
                             const char         *id,
                             const char         *origin,
                             const char         *commit,
                             char              **subpaths,
                             guint64             installed_size,
                             const char * const *previous_ids)
{
  char *empty_subpaths[] = {NULL};
  g_auto(GVariantDict) metadata_dict = FLATPAK_VARIANT_DICT_INITIALIZER;
  g_autoptr(GVariant) res = NULL;

  g_variant_dict_init (&metadata_dict, NULL);
  g_variant_dict_insert_value (&metadata_dict, "deploy-version",
                               g_variant_new_int32 (FLATPAK_DEPLOY_VERSION_CURRENT));
  g_variant_dict_insert_value (&metadata_dict, "timestamp",
                               g_variant_new_uint64 (ostree_commit_get_timestamp (commit_data)));

  if (previous_ids)
    g_variant_dict_insert_value (&metadata_dict, "previous-ids",
                                 g_variant_new_strv (previous_ids, -1));

  add_commit_metadata_to_deploy_data (&metadata_dict, commit_metadata);
  add_metadata_to_deploy_data (&metadata_dict, metadata);
  add_appdata_to_deploy_data (&metadata_dict, deploy_dir, id);

  res = g_variant_ref_sink (g_variant_new ("(ss^ast@a{sv})",
                                           origin,
                                           commit,
                                           subpaths ? subpaths : empty_subpaths,
                                           GUINT64_TO_BE (installed_size),
                                           g_variant_dict_end (&metadata_dict)));
  return g_variant_get_data_as_bytes (res);
}

static GBytes *
upgrade_deploy_data (GBytes             *deploy_data,
                     GFile              *deploy_dir,
                     FlatpakDecomposed  *ref,
                     OstreeRepo         *repo,
                     GCancellable       *cancellable,
                     GError            **error)
{
  VarDeployDataRef deploy_ref = var_deploy_data_from_bytes (deploy_data);
  g_autoptr(GVariant) metadata = g_variant_ref_sink (var_metadata_peek_as_gvariant (var_deploy_data_get_metadata (deploy_ref)));
  g_auto(GVariantDict) metadata_dict = FLATPAK_VARIANT_DICT_INITIALIZER;
  g_autofree const char **subpaths = NULL;
  g_autoptr(GVariant) res = NULL;
  int i, n, old_version;

  g_variant_dict_init (&metadata_dict, NULL);
  g_variant_dict_insert_value (&metadata_dict, "deploy-version",
                               g_variant_new_int32 (FLATPAK_DEPLOY_VERSION_CURRENT));

  /* Copy all metadata except version from old */
  n = g_variant_n_children (metadata);
  for (i = 0; i < n; i++)
    {
      const char *key;
      g_autoptr(GVariant) value = NULL;

      g_variant_get_child (metadata, i, "{&s@v}", &key, &value);
      if (strcmp (key, "deploy-version") == 0)
        continue;
      g_variant_dict_insert_value (&metadata_dict, key, value);
    }

  old_version = flatpak_deploy_data_get_version (deploy_data);
  if (old_version < 1)
    {
      g_autofree char *id = flatpak_decomposed_dup_id (ref);
      add_appdata_to_deploy_data (&metadata_dict, deploy_dir, id);
    }

  if (old_version < 3)
    {
      /* We don't know what timestamp to use here, use 0 and special case that for update checks */
      g_variant_dict_insert_value (&metadata_dict, "timestamp",
                                   g_variant_new_uint64 (0));
    }

  /* Deploy versions older than 4 might have some of the below fields, but it's
   * not guaranteed if the deploy was first created with an old Flatpak version
   */
  if (old_version < 4)
    {
      const char *commit;
      g_autoptr(GVariant) commit_data = NULL;
      g_autoptr(GVariant) commit_metadata = NULL;
      g_autoptr(GKeyFile) keyfile = NULL;
      g_autoptr(GFile) metadata_file = NULL;
      g_autofree char *metadata_contents = NULL;
      gsize metadata_size = 0;
      g_autofree char *id = flatpak_decomposed_dup_id (ref);

      /* Add fields from commit metadata to deploy */
      commit = flatpak_deploy_data_get_commit (deploy_data);
      if (!ostree_repo_load_commit (repo, commit, &commit_data, NULL, error))
        return NULL;
      commit_metadata = g_variant_get_child_value (commit_data, 0);
      add_commit_metadata_to_deploy_data (&metadata_dict, commit_metadata);

      /* Add fields from metadata file to deploy */
      keyfile = g_key_file_new ();
      metadata_file = g_file_resolve_relative_path (deploy_dir, "metadata");
      if (!g_file_load_contents (metadata_file, cancellable,
                                 &metadata_contents, &metadata_size, NULL, error))
        return NULL;
      if (!g_key_file_load_from_data (keyfile, metadata_contents, metadata_size, 0, error))
        return glnx_prefix_error_null (error, "%s", flatpak_file_get_path_cached (metadata_file));
      add_metadata_to_deploy_data (&metadata_dict, keyfile);

      /* Add fields from appdata to deploy, since appdata-content-rating wasn't
       * added when upgrading from version 2 as it should have been
       */
      if (old_version >= 1)
        add_appdata_to_deploy_data (&metadata_dict, deploy_dir, id);
    }

  subpaths = flatpak_deploy_data_get_subpaths (deploy_data);
  res = g_variant_ref_sink (g_variant_new ("(ss^ast@a{sv})",
                                           flatpak_deploy_data_get_origin (deploy_data),
                                           flatpak_deploy_data_get_commit (deploy_data),
                                           subpaths,
                                           GUINT64_TO_BE (flatpak_deploy_data_get_installed_size (deploy_data)),
                                           g_variant_dict_end (&metadata_dict)));
  return g_variant_get_data_as_bytes (res);
}

GBytes *
flatpak_dir_get_deploy_data (FlatpakDir        *self,
                             FlatpakDecomposed *ref,
                             int                required_version,
                             GCancellable      *cancellable,
                             GError           **error)
{
  g_autoptr(GFile) deploy_dir = NULL;

  deploy_dir = flatpak_dir_get_if_deployed (self, ref, NULL, cancellable);
  if (deploy_dir == NULL)
    {
      g_set_error (error, FLATPAK_ERROR, FLATPAK_ERROR_NOT_INSTALLED,
                   _("%s not installed"), flatpak_decomposed_get_ref (ref));
      return NULL;
    }

  if (!flatpak_dir_ensure_repo (self, cancellable, error))
    return NULL;

  return flatpak_load_deploy_data (deploy_dir,
                                   ref,
                                   self->repo,
                                   required_version,
                                   cancellable,
                                   error);
}

char *
flatpak_dir_get_origin (FlatpakDir        *self,
                        FlatpakDecomposed *ref,
                        GCancellable      *cancellable,
                        GError           **error)
{
  g_autoptr(GBytes) deploy_data = NULL;

  deploy_data = flatpak_dir_get_deploy_data (self, ref, FLATPAK_DEPLOY_VERSION_ANY,
                                             cancellable, error);
  if (deploy_data == NULL)
    return NULL;

  return g_strdup (flatpak_deploy_data_get_origin (deploy_data));
}

gboolean
flatpak_dir_ensure_path (FlatpakDir   *self,
                         GCancellable *cancellable,
                         GError      **error)
{
  /* In the system case, we use default perms */
  if (!self->user)
    return flatpak_mkdir_p (self->basedir, cancellable, error);
  else
    {
      /* First make the parent */
      g_autoptr(GFile) parent = g_file_get_parent (self->basedir);
      if (!flatpak_mkdir_p (parent, cancellable, error))
        return FALSE;
      glnx_autofd int parent_dfd = -1;
      if (!glnx_opendirat (AT_FDCWD, flatpak_file_get_path_cached (parent), TRUE,
                           &parent_dfd, error))
        return FALSE;
      g_autofree char *name = g_file_get_basename (self->basedir);
      /* Use 0700 in the user case to neuter any suid or world-writable
       * bits that happen to be in content; see
       * https://github.com/flatpak/flatpak/pull/837
       */
      if (mkdirat (parent_dfd, name, 0700) < 0)
        {
          if (errno == EEXIST)
            {
              /* And fix up any existing installs that had too-wide perms */
              struct stat stbuf;
              if (fstatat (parent_dfd, name, &stbuf, 0) < 0)
                return glnx_throw_errno_prefix (error, "fstatat");
              if (stbuf.st_mode & S_IXOTH)
                {
                  if (fchmodat (parent_dfd, name, 0700, 0) < 0)
                    return glnx_throw_errno_prefix (error, "fchmodat");
                }
            }
          else
            return glnx_throw_errno_prefix (error, "mkdirat");
        }

      return TRUE;
    }
}

gboolean
flatpak_dir_migrate_config (FlatpakDir   *self,
                            gboolean     *changed,
                            GCancellable *cancellable,
                            GError      **error)
{
  g_auto(GStrv) remotes = NULL;
  g_autoptr(GKeyFile) config = NULL;
  int i;

  if (changed != NULL)
    *changed = FALSE;

  /* Only do anything if it exists */
  if (!flatpak_dir_maybe_ensure_repo (self, NULL, NULL))
    return TRUE;

  remotes = flatpak_dir_list_remotes (self, cancellable, NULL);
  if (remotes == NULL)
    return TRUE;

  /* Enable gpg-verify-summary for all remotes with a collection id *and* gpg-verify set, because
   * we want to use summary verification, but older versions of collection-id didn't work with it */
  for (i = 0; remotes != NULL && remotes[i] != NULL; i++)
    {
      g_autofree char *remote_collection_id = NULL;
      const char *remote = remotes[i];
      gboolean gpg_verify_summary;
      gboolean gpg_verify;

      if (flatpak_dir_get_remote_disabled (self, remote))
        continue;

      remote_collection_id = flatpak_dir_get_remote_collection_id (self, remotes[i]);
      if (remote_collection_id == NULL)
        continue;

      if (!ostree_repo_remote_get_gpg_verify_summary (self->repo, remote, &gpg_verify_summary, NULL))
        continue;

      if (!ostree_repo_remote_get_gpg_verify (self->repo, remote, &gpg_verify, NULL))
        continue;

      if (gpg_verify && !gpg_verify_summary)
        {
          g_autofree char *group = g_strdup_printf ("remote \"%s\"", remote);
          if (config == NULL)
            config = ostree_repo_copy_config (flatpak_dir_get_repo (self));

          g_info ("Migrating remote '%s' to gpg-verify-summary", remote);
          g_key_file_set_boolean (config, group, "gpg-verify-summary", TRUE);
        }
    }

  if (config != NULL)
    {
      if (flatpak_dir_use_system_helper (self, NULL))
        {
          g_autoptr(GError) local_error = NULL;
          const char *installation = flatpak_dir_get_id (self);

          if (!flatpak_dir_system_helper_call_ensure_repo (self,
                                                           FLATPAK_HELPER_ENSURE_REPO_FLAGS_NONE,
                                                           installation ? installation : "",
                                                           NULL, &local_error))
            g_info ("Failed to migrate system config: %s", local_error->message);
        }
      else
        {
          if (!ostree_repo_write_config (self->repo, config, error))
            return FALSE;
        }

      if (changed != NULL)
        *changed = TRUE;
    }

  return TRUE;
}

/* Warning: This is not threadsafe, don't use in libflatpak */
gboolean
flatpak_dir_recreate_repo (FlatpakDir   *self,
                           GCancellable *cancellable,
                           GError      **error)
{
  gboolean res;
  OstreeRepo *old_repo = g_steal_pointer (&self->repo);

  /* This is also set by ensure repo, so clear it too */
  g_clear_object (&self->cache_dir);

  res = flatpak_dir_ensure_repo (self, cancellable, error);
  g_clear_object (&old_repo);

  G_LOCK (config_cache);

  g_clear_pointer (&self->masked, g_regex_unref);
  g_clear_pointer (&self->pinned, g_regex_unref);

  G_UNLOCK (config_cache);

  return res;
}

static void
copy_remote_config (GKeyFile *config,
                    GKeyFile *group_config,
                    const char *remote_name)
{
  g_auto(GStrv) keys = NULL;
  g_autofree char *group = g_strdup_printf ("remote \"%s\"", remote_name);
  int i;

  g_key_file_remove_group (config, group, NULL);

  keys = g_key_file_get_keys (group_config, group, NULL, NULL);
  if (keys == NULL)
    return;

  for (i = 0; keys[i] != NULL; i++)
    {
      g_autofree gchar *value = g_key_file_get_value (group_config, group, keys[i], NULL);
      if (value &&
          /* Canonicalize empty filter to unset */
          (strcmp (keys[i], "xa.filter") != 0 ||
           *value != 0))
        g_key_file_set_value (config, group, keys[i], value);
    }
}

static void
_flatpak_dir_scan_new_flatpakrepos (const char          *dir_str,
                                    GHashTable         **flatpakrepos,
                                    const char * const  *remotes)
{
  g_autoptr(GFile) dir = NULL;
  g_autoptr(GFileEnumerator) dir_enum = NULL;

  g_return_if_fail (dir_str != NULL);
  g_return_if_fail (flatpakrepos != NULL);

  dir = g_file_new_for_path (dir_str);
  dir_enum = g_file_enumerate_children (dir,
                                        G_FILE_ATTRIBUTE_STANDARD_NAME "," G_FILE_ATTRIBUTE_STANDARD_TYPE,
                                        G_FILE_QUERY_INFO_NONE,
                                        NULL, NULL);
  if (dir_enum == NULL)
    return;

  while (TRUE)
    {
      GFileInfo *file_info;
      const char *name;
      guint32 type;
      g_autoptr(GError) local_error = NULL;

      if (!g_file_enumerator_iterate (dir_enum, &file_info, NULL,
                                      NULL, &local_error))
        {
          g_info ("Unexpected error reading file in %s: %s",
                  dir_str, local_error->message);
          break;
        }

      if (file_info == NULL)
        break;

      name = g_file_info_get_name (file_info);
      type = g_file_info_get_file_type (file_info);

      if (type == G_FILE_TYPE_REGULAR && g_str_has_suffix (name, FLATPAK_REMOTES_FILE_EXT))
        {
          g_autofree char *remote_name = g_strndup (name, strlen (name) - strlen (FLATPAK_REMOTES_FILE_EXT));

          if (remotes && g_strv_contains (remotes, remote_name))
            continue;

          if (*flatpakrepos == NULL)
            *flatpakrepos = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref);

          g_hash_table_insert (*flatpakrepos, g_steal_pointer (&remote_name), g_file_enumerator_get_child (dir_enum, file_info));
        }
    }
}

static GHashTable *
_flatpak_dir_find_new_flatpakrepos (FlatpakDir *self, OstreeRepo *repo)
{
  g_autoptr(GHashTable) flatpakrepos = NULL;
  g_autofree char *config_dir_str = NULL;
  g_autofree char *os_config_dir_str = NULL;
  g_auto(GStrv) ostree_remotes = NULL;
  g_auto(GStrv) applied_remotes = NULL;
  g_autoptr(GPtrArray) remotes = NULL;

  g_assert (repo != NULL);

  /* Predefined remotes only applies for the default system installation */
  if (self->user ||
      (self->extra_data &&
       g_strcmp0 (self->extra_data->id, SYSTEM_DIR_DEFAULT_ID) != 0))
    return NULL;

  ostree_remotes = ostree_repo_remote_list (repo, NULL);
  applied_remotes = g_key_file_get_string_list (ostree_repo_get_config (repo),
                                                "core", "xa.applied-remotes", NULL, NULL);
  remotes = g_ptr_array_new ();
  for (int i = 0; ostree_remotes && ostree_remotes[i]; i++)
    g_ptr_array_add (remotes, ostree_remotes[i]);
  for (int i = 0; applied_remotes && applied_remotes[i]; i++)
    g_ptr_array_add (remotes, applied_remotes[i]);
  g_ptr_array_add (remotes, NULL);

  config_dir_str = g_build_filename (get_config_dir_location (), FLATPAK_REMOTES_DIR, NULL);
  _flatpak_dir_scan_new_flatpakrepos (config_dir_str,
                                      &flatpakrepos,
                                      (const char * const *) remotes->pdata);

  os_config_dir_str = g_build_filename (get_data_dir_location (), FLATPAK_REMOTES_DIR, NULL);
  _flatpak_dir_scan_new_flatpakrepos (os_config_dir_str,
                                      &flatpakrepos,
                                      (const char * const *) remotes->pdata);

  return g_steal_pointer (&flatpakrepos);
}

static gboolean
apply_new_flatpakrepo (const char *remote_name,
                       GFile      *file,
                       OstreeRepo *repo,
                       GError    **error)
{
  g_autoptr(GBytes) gpg_data = NULL;
  g_autoptr(GKeyFile) group_config = NULL;
  g_autoptr(GKeyFile) keyfile = g_key_file_new ();
  g_autoptr(GError) local_error = NULL;
  g_autoptr(GKeyFile) old_config = NULL;
  g_autoptr(GKeyFile) new_config = NULL;
  g_auto(GStrv) old_applied_remotes = NULL;
  g_autoptr(GPtrArray) new_applied_remotes = NULL;
  int i;
  gboolean res = FALSE;

  if (!g_key_file_load_from_file (keyfile, flatpak_file_get_path_cached (file), 0, &local_error))
    {
      flatpak_fail (error, _("Can't load file %s: %s\n"), flatpak_file_get_path_cached (file), local_error->message);
      return FALSE;
    }

  group_config = flatpak_parse_repofile (remote_name, FALSE, keyfile, &gpg_data, NULL, &local_error);
  if (group_config == NULL)
    {
      flatpak_fail (error, _("Error parsing system flatpakrepo file for %s: %s"), remote_name, local_error->message);
      return FALSE;
    }

  old_config = ostree_repo_copy_config (repo);
  new_config = ostree_repo_copy_config (repo);

  old_applied_remotes = g_key_file_get_string_list (new_config, "core", "xa.applied-remotes", NULL, NULL);

  copy_remote_config (new_config, group_config, remote_name);

  new_applied_remotes = g_ptr_array_new_with_free_func (g_free);
  for (i = 0; old_applied_remotes != NULL && old_applied_remotes[i] != NULL; i++)
    g_ptr_array_add (new_applied_remotes, g_strdup (old_applied_remotes[i]));

  g_ptr_array_add (new_applied_remotes, g_strdup (remote_name));

  g_key_file_set_string_list (new_config, "core", "xa.applied-remotes",
                              (const char * const *) new_applied_remotes->pdata, new_applied_remotes->len);

  if (!ostree_repo_write_config (repo, new_config, error))
    goto out;

  if (!ostree_repo_reload_config (repo, NULL, error))
    goto out;

  if (gpg_data != NULL)
    {
      g_autoptr(GInputStream) input_stream = g_memory_input_stream_new_from_bytes (gpg_data);
      guint imported = 0;

      if (!ostree_repo_remote_gpg_import (repo, remote_name, input_stream,
                                          NULL, &imported, NULL, error))
        goto out;

      g_info ("Imported %u GPG key%s to remote \"%s\"", imported, (imported == 1) ? "" : "s", remote_name);
    }

  res = TRUE;
out:
  if (!res)
    {
      /* Roll back the changes. Ideally they would be atomic, because if the
       * program terminates before we roll back, we end up in a broken state */
      ostree_repo_write_config (repo, old_config, NULL);
      ostree_repo_reload_config (repo, NULL, NULL);
    }
  return res;
}

static gboolean
system_helper_maybe_ensure_repo (FlatpakDir *self,
                                 FlatpakHelperEnsureRepoFlags flags,
                                 gboolean allow_empty,
                                 GCancellable *cancellable,
                                 GError **error)
{
  g_autoptr(GError) local_error = NULL;
  const char *installation = flatpak_dir_get_id (self);

  if (!flatpak_dir_system_helper_call_ensure_repo (self,
                                                   flags,
                                                   installation ? installation : "",
                                                   cancellable, &local_error))
    {
      if (allow_empty)
        return TRUE;

      g_propagate_error (error, g_steal_pointer (&local_error));
      return FALSE;
    }

  return TRUE;
}

static gboolean
ensure_repo_opened (OstreeRepo *repo,
                    GCancellable *cancellable,
                    GError **error)
{
  if (!ostree_repo_open (repo, cancellable, error))
    {
      g_autofree char *repopath = NULL;

      repopath = g_file_get_path (ostree_repo_get_path (repo));
      g_prefix_error (error, _("While opening repository %s: "), repopath);
      return FALSE;
    }

  return TRUE;
}

static gboolean
_flatpak_dir_ensure_repo (FlatpakDir   *self,
                          gboolean      allow_empty,
                          GCancellable *cancellable,
                          GError      **error)
{
  g_autoptr(GFile) repodir = NULL;
  g_autoptr(OstreeRepo) repo = NULL;
  g_autoptr(GError) my_error = NULL;
  g_autoptr(GFile) cache_dir = NULL;
  g_autoptr(GHashTable) flatpakrepos = NULL;
  FlatpakHelperEnsureRepoFlags ensure_flags = FLATPAK_HELPER_ENSURE_REPO_FLAGS_NONE;

  if (self->repo != NULL)
    return TRUE;

  /* Don't trigger polkit prompts if we are just doing this opportunistically */
  if (allow_empty)
    ensure_flags |= FLATPAK_HELPER_ENSURE_REPO_FLAGS_NO_INTERACTION;

  if (!g_file_query_exists (self->basedir, cancellable))
    {
      if (flatpak_dir_use_system_helper (self, NULL))
        {
          if (!system_helper_maybe_ensure_repo (self, ensure_flags, allow_empty, cancellable, error))
            return FALSE;
        }
      else
        {
          g_autoptr(GError) local_error = NULL;
          if (!flatpak_dir_ensure_path (self, cancellable, &local_error))
            {
              if (allow_empty)
                return TRUE;

              g_propagate_error (error, g_steal_pointer (&local_error));
              return FALSE;
            }
        }
    }

  repodir = g_file_get_child (self->basedir, "repo");

  repo = ostree_repo_new (repodir);

  if (!g_file_query_exists (repodir, cancellable))
    {
      /* We always use bare-user-only these days, except old installations
         that still user bare-user */
      OstreeRepoMode mode = OSTREE_REPO_MODE_BARE_USER_ONLY;

      if (flatpak_dir_use_system_helper (self, NULL))
        {
          g_autoptr(GError) local_error = NULL;

          if (!system_helper_maybe_ensure_repo (self, ensure_flags, allow_empty, cancellable, error))
            return FALSE;

          if (!ensure_repo_opened (repo, cancellable, &local_error))
            {
              if (allow_empty)
                return TRUE;

              g_propagate_error (error, g_steal_pointer (&local_error));
              return FALSE;
            }
        }
      else
        {
          if (!ostree_repo_create (repo, mode, cancellable, &my_error))
            {
              const char *repo_path = flatpak_file_get_path_cached (repodir);

              flatpak_rm_rf (repodir, cancellable, NULL);

              if (allow_empty)
                return TRUE;

              /* As of 2022, the error message from libostree is not the most helpful:
               * Creating repo: mkdirat: Permission denied
               * If the repository path is in the error message, assume this
               * has been fixed. If not, add it. */
              if (strstr (my_error->message, repo_path) != NULL)
                g_propagate_error (error, g_steal_pointer (&my_error));
              else
                g_set_error (error, my_error->domain, my_error->code,
                             "Unable to create repository at %s (%s)",
                             repo_path, my_error->message);

              return FALSE;
            }

          /* Create .changed file early to avoid polling non-existing file in monitor */
          if (!flatpak_dir_mark_changed (self, &my_error))
            {
              g_warning ("Error marking directory as changed: %s", my_error->message);
              g_clear_error (&my_error);
            }
        }
    }
  else
    {
      if (!ensure_repo_opened (repo, cancellable, error))
        return FALSE;
    }

  /* In the system-helper case we're directly using the global repo, and we can't write any
   * caches for summaries there, so we need to set a custom dir for this. Note, as per #3303
   * this has to be called after ostree_repo_open() in order to the custom cachedir being
   * overridden if the system dir is writable (like in the testsuite).
   */
  if (flatpak_dir_use_system_helper (self, NULL))
    {
      g_autofree char *cache_path = NULL;

      cache_dir = flatpak_ensure_user_cache_dir_location (error);
      if (cache_dir == NULL)
        return FALSE;

      cache_path = g_file_get_path (cache_dir);
      if (!ostree_repo_set_cache_dir (repo,
                                      AT_FDCWD, cache_path,
                                      cancellable, error))
        return FALSE;
    }

  /* Earlier flatpak used to reset min-free-space-percent to 0 every time, but now we
   * favor min-free-space-size instead of it (See below).
   */
  if (!flatpak_dir_use_system_helper (self, NULL))
    {
      GKeyFile *orig_config = NULL;
      g_autoptr(GKeyFile) new_config = NULL;
      g_autofree char *orig_min_free_space_percent = NULL;
      g_autofree char *orig_min_free_space_size = NULL;
      const char *min_free_space_size = "500MB";
      guint64 min_free_space_percent_int;

      orig_config = ostree_repo_get_config (repo);
      orig_min_free_space_percent = g_key_file_get_value (orig_config, "core", "min-free-space-percent", NULL);
      orig_min_free_space_size = g_key_file_get_value (orig_config, "core", "min-free-space-size", NULL);

      if (orig_min_free_space_size == NULL)
        new_config = ostree_repo_copy_config (repo);

      /* Scrap previously written min-free-space-percent=0 and replace it with min-free-space-size */
      if (orig_min_free_space_size == NULL &&
          orig_min_free_space_percent != NULL &&
          g_ascii_string_to_unsigned (orig_min_free_space_percent, 10,
                                      0, G_MAXUINT64,
                                      &min_free_space_percent_int, &my_error))
        {
          if (min_free_space_percent_int == 0)
            {
              g_key_file_remove_key (new_config, "core", "min-free-space-percent", NULL);
              g_key_file_set_string (new_config, "core", "min-free-space-size", min_free_space_size);
            }
        }
      else if (my_error != NULL)
        {
          g_propagate_error (error, g_steal_pointer (&my_error));
          return FALSE;
        }

      if (orig_min_free_space_size == NULL &&
          orig_min_free_space_percent == NULL)
        g_key_file_set_string (new_config, "core", "min-free-space-size", min_free_space_size);

      if (new_config != NULL)
        {
          if (!ostree_repo_write_config (repo, new_config, error))
            return FALSE;

          if (!ostree_repo_reload_config (repo, cancellable, error))
            return FALSE;
        }
    }

  flatpakrepos = _flatpak_dir_find_new_flatpakrepos (self, repo);
  if (flatpakrepos)
    {
      if (flatpak_dir_use_system_helper (self, NULL))
        {
          if (!system_helper_maybe_ensure_repo (self, ensure_flags, allow_empty, cancellable, error))
            return FALSE;

          if (!ostree_repo_reload_config (repo, cancellable, error))
            return FALSE;
        }
      else
        {
          GLNX_HASH_TABLE_FOREACH_KV (flatpakrepos, const char *, remote_name, GFile *, file)
            {
              if (!apply_new_flatpakrepo (remote_name, file, repo, error))
                return FALSE;
            }
        }
    }


  if (cache_dir == NULL)
    cache_dir = g_file_get_child (repodir, "tmp/cache");

  /* Make sure we didn't reenter weirdly */
  g_assert (self->repo == NULL);
  self->repo = g_object_ref (repo);
  self->cache_dir = g_object_ref (cache_dir);

  return TRUE;
}

gboolean
flatpak_dir_ensure_repo (FlatpakDir   *self,
                         GCancellable *cancellable,
                         GError      **error)
{
  return _flatpak_dir_ensure_repo (self, FALSE, cancellable, error);
}

gboolean
flatpak_dir_maybe_ensure_repo (FlatpakDir   *self,
                               GCancellable *cancellable,
                               GError      **error)
{
  return _flatpak_dir_ensure_repo (self, TRUE, cancellable, error);
}

static gboolean
_flatpak_dir_reload_config (FlatpakDir   *self,
                            GCancellable *cancellable,
                            GError      **error)
{
  if (self->repo)
    {
      if (!ostree_repo_reload_config (self->repo, cancellable, error))
        return FALSE;
    }

  /* Clear cached stuff from repo config */
  G_LOCK (config_cache);

  g_clear_pointer (&self->masked, g_regex_unref);
  g_clear_pointer (&self->pinned, g_regex_unref);

  G_UNLOCK (config_cache);
  return TRUE;
}

char *
flatpak_dir_get_config (FlatpakDir *self,
                        const char *key,
                        GError    **error)
{
  GKeyFile *config;
  g_autofree char *ostree_key = NULL;

  if (!flatpak_dir_maybe_ensure_repo (self, NULL, error))
    return NULL;

  if (self->repo == NULL)
    {
      g_set_error (error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_KEY_NOT_FOUND,
                   _("The config key %s is not set"), key);
      return NULL;
    }

  config = ostree_repo_get_config (self->repo);
  ostree_key = g_strconcat ("xa.", key, NULL);

  return g_key_file_get_string (config, "core", ostree_key, error);
}

GPtrArray *
flatpak_dir_get_config_patterns (FlatpakDir *dir, const char *key)
{
  g_autoptr(GPtrArray) patterns = NULL;
  g_autofree char *key_value = NULL;
  int i;

  patterns = g_ptr_array_new_with_free_func (g_free);

  key_value = flatpak_dir_get_config (dir, key, NULL);
  if (key_value)
    {
      g_auto(GStrv) oldv = g_strsplit (key_value, ";", -1);

      for (i = 0; oldv[i] != NULL; i++)
        {
          const char *old = oldv[i];

          if (*old != 0 && !flatpak_g_ptr_array_contains_string (patterns, old))
            g_ptr_array_add (patterns, g_strdup (old));
        }
    }

  return g_steal_pointer (&patterns);
}

gboolean
flatpak_dir_set_config (FlatpakDir *self,
                        const char *key,
                        const char *value,
                        GError    **error)
{
  g_autoptr(GKeyFile) config = NULL;
  g_autofree char *ostree_key = NULL;

  if (!flatpak_dir_ensure_repo (self, NULL, error))
    return FALSE;

  config = ostree_repo_copy_config (self->repo);
  ostree_key = g_strconcat ("xa.", key, NULL);

  if (flatpak_dir_use_system_helper (self, NULL))
    {
      FlatpakHelperConfigureFlags flags = 0;
      const char *installation = flatpak_dir_get_id (self);

      if (value == NULL)
        {
          flags |= FLATPAK_HELPER_CONFIGURE_FLAGS_UNSET;
          value = "";
        }

      if (!flatpak_dir_system_helper_call_configure (self,
                                                     flags, key, value,
                                                     installation ? installation : "",
                                                     NULL, error))
        return FALSE;

      if (!_flatpak_dir_reload_config (self, NULL, error))
        return FALSE;

      return TRUE;
    }

  if (value == NULL)
    g_key_file_remove_key (config, "core", ostree_key, NULL);
  else
    g_key_file_set_value (config, "core", ostree_key, value);

  if (!ostree_repo_write_config (self->repo, config, error))
    return FALSE;

  if (!_flatpak_dir_reload_config (self, NULL, error))
    return FALSE;

  return TRUE;
}

gboolean
flatpak_dir_config_append_pattern (FlatpakDir *self,
                                   const char *key,
                                   const char *pattern,
                                   gboolean    runtime_only,
                                   gboolean   *out_already_present,
                                   GError    **error)
{
  g_autoptr(GPtrArray) patterns = flatpak_dir_get_config_patterns (self, key);
  g_autofree char *regexp = NULL;
  gboolean already_present;
  g_autofree char *merged_patterns = NULL;

  regexp = flatpak_filter_glob_to_regexp (pattern, runtime_only, error);
  if (regexp == NULL)
    return FALSE;

  if (!(already_present = flatpak_g_ptr_array_contains_string (patterns, pattern)))
    g_ptr_array_add (patterns, g_strdup (pattern));

  if (out_already_present)
    *out_already_present = already_present;

  g_ptr_array_sort (patterns, flatpak_strcmp0_ptr);

  g_ptr_array_add (patterns, NULL);
  merged_patterns = g_strjoinv (";", (char **)patterns->pdata);

  return flatpak_dir_set_config (self, key, merged_patterns, error);
}

gboolean
flatpak_dir_config_remove_pattern (FlatpakDir *self,
                                   const char *key,
                                   const char *pattern,
                                   GError    **error)
{
  g_autoptr(GPtrArray) patterns = flatpak_dir_get_config_patterns (self, key);
  g_autofree char *merged_patterns = NULL;
  int j;

  for (j = 0; j < patterns->len; j++)
    {
      if (strcmp (g_ptr_array_index (patterns, j), pattern) == 0)
        break;
    }

  if (j == patterns->len)
    return flatpak_fail (error, _("No current %s pattern matching %s"), key, pattern);
  else
    g_ptr_array_remove_index (patterns, j);

  g_ptr_array_add (patterns, NULL);
  merged_patterns = g_strjoinv (";", (char **)patterns->pdata);

  return flatpak_dir_set_config (self, key, merged_patterns, error);
}

gboolean
flatpak_dir_mark_changed (FlatpakDir *self,
                          GError    **error)
{
  g_autoptr(GFile) changed_file = NULL;
  g_autofree char * changed_path = NULL;

  changed_file = flatpak_dir_get_changed_path (self);
  changed_path = g_file_get_path (changed_file);

  if (!g_utime (changed_path, NULL))
    return TRUE;

  if (errno != ENOENT)
    return glnx_throw_errno (error);

  if (!g_file_replace_contents (changed_file, "", 0, NULL, FALSE,
                                G_FILE_CREATE_NONE, NULL, NULL, error))
    return FALSE;

  return TRUE;
}

gboolean
flatpak_dir_remove_appstream (FlatpakDir   *self,
                              const char   *remote,
                              GCancellable *cancellable,
                              GError      **error)
{
  g_autoptr(GFile) appstream_dir = NULL;
  g_autoptr(GFile) remote_dir = NULL;

  if (!flatpak_dir_ensure_repo (self, cancellable, error))
    return FALSE;

  appstream_dir = g_file_get_child (flatpak_dir_get_path (self), "appstream");
  remote_dir = g_file_get_child (appstream_dir, remote);

  if (g_file_query_exists (remote_dir, cancellable) &&
      !flatpak_rm_rf (remote_dir, cancellable, error))
    return FALSE;

  return TRUE;
}

#define SECS_PER_MINUTE (60)
#define SECS_PER_HOUR   (60 * SECS_PER_MINUTE)
#define SECS_PER_DAY    (24 * SECS_PER_HOUR)

/* This looks for old temporary files created by previous versions of
   flatpak_dir_deploy_appstream(). These are all either directories
   starting with a dot, or symlinks starting with a dot. Such temp
   files if found can be from a concurrent deploy, so we only remove
   any such files older than a day to avoid races.
*/
static void
remove_old_appstream_tmpdirs (GFile *dir)
{
  g_auto(GLnxDirFdIterator) dir_iter = { 0 };
  time_t now = time (NULL);

  if (!glnx_dirfd_iterator_init_at (AT_FDCWD, flatpak_file_get_path_cached (dir),
                                    FALSE, &dir_iter, NULL))
    return;

  while (TRUE)
    {
      struct stat stbuf;
      struct dirent *dent;
      g_autoptr(GFile) tmp = NULL;

      if (!glnx_dirfd_iterator_next_dent_ensure_dtype (&dir_iter, &dent, NULL, NULL))
        break;

      if (dent == NULL)
        break;

      /* We ignore non-dotfiles and .timestamps as they are not tempfiles */
      if (dent->d_name[0] != '.' ||
          strcmp (dent->d_name, ".timestamp") == 0)
        continue;

      /* Check for right types and names */
      if (dent->d_type == DT_DIR)
        {
          if (strlen (dent->d_name) != 72 ||
              dent->d_name[65] != '-')
            continue;
        }
      else if (dent->d_type == DT_LNK)
        {
          if (!g_str_has_prefix (dent->d_name, ".active-"))
            continue;
        }
      else
        continue;

      /* Check that the file is at least a day old to avoid races */
      if (!glnx_fstatat (dir_iter.fd, dent->d_name, &stbuf, AT_SYMLINK_NOFOLLOW, NULL))
        continue;

      if (stbuf.st_mtime >= now ||
          now - stbuf.st_mtime < SECS_PER_DAY)
        continue;

      tmp = g_file_get_child (dir, dent->d_name);

      /* We ignore errors here, no need to worry anyone */
      g_info ("Deleting stale appstream deploy tmpdir %s", flatpak_file_get_path_cached (tmp));
      (void)flatpak_rm_rf (tmp, NULL, NULL);
    }
}

/* Like the function above, this looks for old temporary directories created by
 * previous versions of flatpak_dir_deploy().
 * These are all directories starting with a dot. Such directories can be from a
 * concurrent deploy, so we only remove directories older than a day to avoid
 * races.
*/
static void
remove_old_deploy_tmpdirs (GFile *dir)
{
  g_auto(GLnxDirFdIterator) dir_iter = { 0 };
  time_t now = time (NULL);

  if (!glnx_dirfd_iterator_init_at (AT_FDCWD, flatpak_file_get_path_cached (dir),
                                    FALSE, &dir_iter, NULL))
    return;

  while (TRUE)
    {
      struct stat stbuf;
      struct dirent *dent;
      g_autoptr(GFile) tmp = NULL;

      if (!glnx_dirfd_iterator_next_dent_ensure_dtype (&dir_iter, &dent, NULL, NULL))
        break;

      if (dent == NULL)
        break;

      /* We ignore non-dotfiles and .timestamps as they are not tempfiles */
      if (dent->d_name[0] != '.' ||
          strcmp (dent->d_name, ".timestamp") == 0)
        continue;

      /* Check for right types and names. The format we’re looking for is:
       * .[0-9a-f]{64}-[0-9A-Z]{6} */
      if (dent->d_type == DT_DIR)
        {
          if (strlen (dent->d_name) != 72 ||
              dent->d_name[65] != '-')
            continue;
        }
      else
        continue;

      /* Check that the file is at least a day old to avoid races */
      if (!glnx_fstatat (dir_iter.fd, dent->d_name, &stbuf, AT_SYMLINK_NOFOLLOW, NULL))
        continue;

      if (stbuf.st_mtime >= now ||
          now - stbuf.st_mtime < SECS_PER_DAY)
        continue;

      tmp = g_file_get_child (dir, dent->d_name);

      /* We ignore errors here, no need to worry anyone */
      g_info ("Deleting stale deploy tmpdir %s", flatpak_file_get_path_cached (tmp));
      (void)flatpak_rm_rf (tmp, NULL, NULL);
    }
}

gboolean
flatpak_dir_deploy_appstream (FlatpakDir   *self,
                              const char   *remote,
                              const char   *arch,
                              gboolean     *out_changed,
                              GCancellable *cancellable,
                              GError      **error)
{
  g_autoptr(GFile) appstream_dir = NULL;
  g_autoptr(GFile) remote_dir = NULL;
  g_autoptr(GFile) arch_dir = NULL;
  g_autoptr(GFile) checkout_dir = NULL;
  g_autoptr(GFile) real_checkout_dir = NULL;
  g_autoptr(GFile) timestamp_file = NULL;
  g_autofree char *arch_path = NULL;
  gboolean checkout_exists;
  const char *old_dir = NULL;
  g_autofree char *new_checksum = NULL;
  g_autoptr(GFile) active_link = NULL;
  g_autofree char *branch = NULL;
  g_autoptr(GFile) old_checkout_dir = NULL;
  g_autoptr(GFile) active_tmp_link = NULL;
  g_autoptr(GError) tmp_error = NULL;
  g_autofree char *new_dir = NULL;
  OstreeRepoCheckoutAtOptions options = { 0, };
  glnx_autofd int dfd = -1;
  g_autoptr(GFileInfo) file_info = NULL;
  g_autofree char *tmpname = g_strdup (".active-XXXXXX");
  g_auto(GLnxLockFile) lock = { 0, };
  gboolean do_compress = FALSE;
  gboolean do_uncompress = TRUE;
  g_autofree char *filter_checksum = NULL;
  g_autoptr(GRegex) allow_refs = NULL;
  g_autoptr(GRegex) deny_refs = NULL;
  g_autofree char *subset = NULL;
  g_auto(GLnxTmpDir) tmpdir = { 0, };
  g_autoptr(FlatpakTempDir) tmplink = NULL;

  /* Keep a shared repo lock to avoid prunes removing objects we're relying on
   * while we do the checkout. This could happen if the ref changes after we
   * read its current value for the checkout. */
  if (!flatpak_dir_repo_lock (self, &lock, LOCK_SH, cancellable, error))
    return FALSE;

  if (!flatpak_dir_lookup_remote_filter (self, remote, TRUE, &filter_checksum, &allow_refs, &deny_refs, error))
    return FALSE;

  appstream_dir = g_file_get_child (flatpak_dir_get_path (self), "appstream");
  remote_dir = g_file_get_child (appstream_dir, remote);
  arch_dir = g_file_get_child (remote_dir, arch);
  active_link = g_file_get_child (arch_dir, "active");
  timestamp_file = g_file_get_child (arch_dir, ".timestamp");

  arch_path = g_file_get_path (arch_dir);
  if (g_mkdir_with_parents (arch_path, 0755) != 0)
    {
      glnx_set_error_from_errno (error);
      return FALSE;
    }

  if (!glnx_opendirat (AT_FDCWD, arch_path, TRUE, &dfd, error))
    return FALSE;

  old_dir = NULL;
  file_info = g_file_query_info (active_link, OSTREE_GIO_FAST_QUERYINFO,
                                 G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
                                 cancellable, NULL);
  if (file_info != NULL)
    old_dir =  g_file_info_get_symlink_target (file_info);

  subset = flatpak_dir_get_remote_subset (self, remote);

  if (subset)
    branch = g_strdup_printf ("appstream2/%s-%s", subset, arch);
  else
    branch = g_strdup_printf ("appstream2/%s", arch);

  if (!flatpak_repo_resolve_rev (self->repo, NULL, remote, branch, TRUE,
                                 &new_checksum, cancellable, error))
    return FALSE;

  if (new_checksum == NULL && subset == NULL)
    {
      /* Fall back to old branch (only exist on non-subsets) */
      g_clear_pointer (&branch, g_free);
      branch = g_strdup_printf ("appstream/%s", arch);
      if (!flatpak_repo_resolve_rev (self->repo, NULL, remote, branch, TRUE,
                                     &new_checksum, cancellable, error))
        return FALSE;
      do_compress = FALSE;
      do_uncompress = TRUE;
    }
  else
    {
      do_compress = TRUE;
      do_uncompress = FALSE;
    }

  if (new_checksum == NULL)
    return flatpak_fail_error (error, FLATPAK_ERROR_INVALID_DATA, _("No appstream commit to deploy"));

  if (filter_checksum)
    new_dir = g_strconcat (new_checksum, "-", filter_checksum, NULL);
  else
    new_dir = g_strdup (new_checksum);

  real_checkout_dir = g_file_get_child (arch_dir, new_dir);
  checkout_exists = g_file_query_exists (real_checkout_dir, NULL);

  if (old_dir != NULL && new_dir != NULL &&
      strcmp (old_dir, new_dir) == 0 &&
      checkout_exists)
    {
      if (!g_file_replace_contents (timestamp_file, "", 0, NULL, FALSE,
                                    G_FILE_CREATE_REPLACE_DESTINATION, NULL, NULL, error))
        return FALSE;

      if (out_changed)
        *out_changed = FALSE;

      return TRUE; /* No changes, don't checkout */
    }

  {
    g_autofree char *template = g_strdup_printf (".%s-XXXXXX", new_dir);
    g_autoptr(GFile) tmp_dir_template = g_file_get_child (arch_dir, template);

    if (!glnx_mkdtempat (AT_FDCWD, flatpak_file_get_path_cached (tmp_dir_template), 0755,
                         &tmpdir, error))
      return FALSE;
  }

  checkout_dir = g_file_new_for_path (tmpdir.path);

  options.mode = OSTREE_REPO_CHECKOUT_MODE_USER;
  options.overwrite_mode = OSTREE_REPO_CHECKOUT_OVERWRITE_UNION_FILES;
  options.enable_fsync = FALSE; /* We checkout to a temp dir and sync before moving it in place */
  options.bareuseronly_dirs = TRUE; /* https://github.com/ostreedev/ostree/pull/927 */

  if (!ostree_repo_checkout_at (self->repo, &options,
                                AT_FDCWD, tmpdir.path, new_checksum,
                                cancellable, error))
    return FALSE;

  /* Old appstream format don't have uncompressed file, so we uncompress it */
  if (do_uncompress)
    {
      g_autoptr(GFile) appstream_xml = g_file_get_child (checkout_dir, "appstream.xml");
      g_autoptr(GFile) appstream_gz_xml = g_file_get_child (checkout_dir, "appstream.xml.gz");
      g_autoptr(GOutputStream) out2 = NULL;
      g_autoptr(GFileOutputStream) out = NULL;
      g_autoptr(GFileInputStream) in = NULL;

      in = g_file_read (appstream_gz_xml, NULL, NULL);
      if (in)
        {
          g_autoptr(GZlibDecompressor) decompressor = g_zlib_decompressor_new (G_ZLIB_COMPRESSOR_FORMAT_GZIP);
          out = g_file_replace (appstream_xml, NULL, FALSE, G_FILE_CREATE_REPLACE_DESTINATION,
                                NULL, error);
          if (out == NULL)
            return FALSE;

          out2 = g_converter_output_stream_new (G_OUTPUT_STREAM (out), G_CONVERTER (decompressor));
          if (g_output_stream_splice (out2, G_INPUT_STREAM (in), G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE | G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET,
                                      NULL, error) < 0)
            return FALSE;
        }
    }

  if (deny_refs)
    {
      g_autoptr(GFile) appstream_xml = g_file_get_child (checkout_dir, "appstream.xml");
      g_autoptr(GFileInputStream) in = NULL;

      /* We need some ref filtering, so parse the xml */

      in = g_file_read (appstream_xml, NULL, NULL);
      if (in)
        {
          g_autoptr(FlatpakXml) appstream = NULL;
          g_autoptr(GBytes) content = NULL;

          appstream = flatpak_xml_parse (G_INPUT_STREAM (in), FALSE, cancellable, error);
          if (appstream == NULL)
            return FALSE;

          flatpak_appstream_xml_filter (appstream, allow_refs, deny_refs);

          if (!flatpak_appstream_xml_root_to_data (appstream, &content, NULL, error))
            return FALSE;

          if (!g_file_replace_contents  (appstream_xml,
                                         g_bytes_get_data (content, NULL), g_bytes_get_size (content),
                                         NULL, FALSE, G_FILE_CREATE_REPLACE_DESTINATION, NULL,
                                         cancellable, error))
            return FALSE;
        }

      do_compress = TRUE; /* We need to recompress this */
    }

  /* New appstream format don't have compressed file, so we compress it */
  if (do_compress)
    {
      g_autoptr(GFile) appstream_xml = g_file_get_child (checkout_dir, "appstream.xml");
      g_autoptr(GFile) appstream_gz_xml = g_file_get_child (checkout_dir, "appstream.xml.gz");
      g_autoptr(GZlibCompressor) compressor = NULL;
      g_autoptr(GOutputStream) out2 = NULL;
      g_autoptr(GFileOutputStream) out = NULL;
      g_autoptr(GFileInputStream) in = NULL;

      in = g_file_read (appstream_xml, NULL, NULL);
      if (in)
        {
          compressor = g_zlib_compressor_new (G_ZLIB_COMPRESSOR_FORMAT_GZIP, -1);
          out = g_file_replace (appstream_gz_xml, NULL, FALSE, G_FILE_CREATE_REPLACE_DESTINATION,
                                NULL, error);
          if (out == NULL)
            return FALSE;

          out2 = g_converter_output_stream_new (G_OUTPUT_STREAM (out), G_CONVERTER (compressor));
          if (g_output_stream_splice (out2, G_INPUT_STREAM (in), G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE | G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET,
                                      NULL, error) < 0)
            return FALSE;
        }
    }

  glnx_gen_temp_name (tmpname);
  active_tmp_link = g_file_get_child (arch_dir, tmpname);

  if (!g_file_make_symbolic_link (active_tmp_link, new_dir, cancellable, error))
    return FALSE;

   /* This is a link, not a dir, but it will remove the same way on destroy */
  tmplink = g_object_ref (active_tmp_link);

  if (syncfs (dfd) != 0)
    {
      glnx_set_error_from_errno (error);
      return FALSE;
    }

  /* By now the checkout to the temporary directory is on disk, as is the temporary
     symlink pointing to the final target. */

  if (!g_file_move (checkout_dir, real_checkout_dir, G_FILE_COPY_NO_FALLBACK_FOR_MOVE,
                    cancellable, NULL, NULL, error))
    return FALSE;

  /* Don't delete tmpdir now that it's moved */
  glnx_tmpdir_unset (&tmpdir);

  if (syncfs (dfd) != 0)
    {
      glnx_set_error_from_errno (error);
      return FALSE;
    }

  if (!flatpak_file_rename (active_tmp_link,
                            active_link,
                            cancellable, error))
    return FALSE;

  /* Don't delete tmplink now that it's moved */
  g_object_unref (g_steal_pointer (&tmplink));

  if (old_dir != NULL &&
      g_strcmp0 (old_dir, new_dir) != 0)
    {
      old_checkout_dir = g_file_get_child (arch_dir, old_dir);
      if (!flatpak_rm_rf (old_checkout_dir, cancellable, &tmp_error))
        g_warning ("Unable to remove old appstream checkout: %s", tmp_error->message);
    }

  if (!g_file_replace_contents (timestamp_file, "", 0, NULL, FALSE,
                                G_FILE_CREATE_REPLACE_DESTINATION, NULL, NULL, error))
    return FALSE;

  /* If we added a new checkout, touch the toplevel dir to tell people that they need
     to re-scan */
  if (!checkout_exists)
    {
      g_autofree char *appstream_dir_path = g_file_get_path (appstream_dir);
      utime (appstream_dir_path, NULL);
    }

  /* There used to be an bug here where temporary files where not removed, which could use
   * quite a lot of space over time, so we check for these and remove them. */
  remove_old_appstream_tmpdirs (arch_dir);

  if (out_changed)
    *out_changed = TRUE;

  return TRUE;
}

static gboolean repo_get_remote_collection_id (OstreeRepo *repo,
                                               const char *remote_name,
                                               char      **collection_id_out,
                                               GError    **error);


gboolean
flatpak_dir_find_latest_rev (FlatpakDir               *self,
                             FlatpakRemoteState       *state,
                             const char               *ref,
                             const char               *checksum_or_latest,
                             char                    **out_rev,
                             guint64                  *out_timestamp,
                             GFile                   **out_sideload_path,
                             FlatpakImageSource      **out_image_source,
                             GCancellable             *cancellable,
                             GError                  **error)
{
  g_autofree char *latest_rev = NULL;

  g_return_val_if_fail (out_rev != NULL, FALSE);

  if (!flatpak_remote_state_lookup_ref (state, ref, &latest_rev, out_timestamp, NULL, out_sideload_path, out_image_source, error))
    return FALSE;
  if (latest_rev == NULL)
    return flatpak_fail_error (error, FLATPAK_ERROR_REF_NOT_FOUND,
                               _("Couldn't find latest checksum for ref %s in remote %s"),
                               ref, state->remote_name);

  if (out_rev != NULL)
    *out_rev = g_steal_pointer (&latest_rev);

  return TRUE;
}

static gboolean
get_mtime (GFile        *file,
           GTimeVal     *result,
           GCancellable *cancellable,
           GError      **error)
{
  g_autoptr(GFileInfo) info = g_file_query_info (file,
                                                 G_FILE_ATTRIBUTE_TIME_MODIFIED,
                                                 G_FILE_QUERY_INFO_NONE,
                                                 cancellable, error);
  if (info)
    {
      g_file_info_get_modification_time (info, result);
      return TRUE;
    }
  else
    {
      return FALSE;
    }
}

static gboolean
check_destination_mtime (GFile        *src,
                         GFile        *dest,
                         GCancellable *cancellable)
{
  GTimeVal src_mtime;
  GTimeVal dest_mtime;

  return get_mtime (src, &src_mtime, cancellable, NULL) &&
         get_mtime (dest, &dest_mtime, cancellable, NULL) &&
         (src_mtime.tv_sec < dest_mtime.tv_sec ||
          (src_mtime.tv_sec == dest_mtime.tv_sec && src_mtime.tv_usec < dest_mtime.tv_usec));
}

static GFile *
flatpak_dir_update_oci_index (FlatpakDir   *self,
                              const char   *remote,
                              char        **index_uri_out,
                              GCancellable *cancellable,
                              GError      **error)
{
  g_autoptr(GError) local_error = NULL;
  g_autoptr(GFile) index_cache = NULL;
  g_autofree char *oci_uri = NULL;

  index_cache = flatpak_dir_get_oci_index_location (self, remote, error);
  if (index_cache == NULL)
    return NULL;

  ensure_http_session (self);

  if (!ostree_repo_remote_get_url (self->repo,
                                   remote,
                                   &oci_uri,
                                   error))
    return NULL;

  if (!flatpak_oci_index_ensure_cached (self->http_session, oci_uri,
                                        index_cache, index_uri_out,
                                        cancellable, &local_error))
    {
      if (!g_error_matches (local_error, FLATPAK_HTTP_ERROR, FLATPAK_HTTP_ERROR_NOT_CHANGED))
        {
          g_propagate_error (error, g_steal_pointer (&local_error));
          return NULL;
        }

      g_clear_error (&local_error);
    }

  return g_steal_pointer (&index_cache);
}

static gboolean
replace_contents_compressed (GFile        *dest,
                             GBytes       *contents,
                             GCancellable *cancellable,
                             GError      **error)
{
  g_autoptr(GZlibCompressor) compressor = NULL;
  g_autoptr(GFileOutputStream) out = NULL;
  g_autoptr(GOutputStream) out2 = NULL;

  compressor = g_zlib_compressor_new (G_ZLIB_COMPRESSOR_FORMAT_GZIP, -1);
  out = g_file_replace (dest, NULL, FALSE, G_FILE_CREATE_REPLACE_DESTINATION,
                        NULL, error);
  out2 = g_converter_output_stream_new (G_OUTPUT_STREAM (out), G_CONVERTER (compressor));
  if (out == NULL)
    return FALSE;

  if (!g_output_stream_write_all (out2,
                                  g_bytes_get_data (contents, NULL),
                                  g_bytes_get_size (contents),
                                  NULL,
                                  cancellable, error))
    return FALSE;

  if (!g_output_stream_close (out2, cancellable, error))
    return FALSE;

  return TRUE;
}

static gboolean
flatpak_dir_update_appstream_oci (FlatpakDir          *self,
                                  const char          *remote,
                                  const char          *arch,
                                  gboolean            *out_changed,
                                  FlatpakProgress     *progress,
                                  GCancellable        *cancellable,
                                  GError             **error)
{
  g_autoptr(GFile) arch_dir = NULL;
  g_autoptr(GFile) lock_file = NULL;
  g_auto(GLnxLockFile) lock = { 0, };
  g_autoptr(GFile) index_cache = NULL;
  g_autofree char *index_uri = NULL;
  g_autoptr(GFile) timestamp_file = NULL;
  g_autoptr(GFile) icons_dir = NULL;
  glnx_autofd int icons_dfd = -1;
  g_autoptr(GBytes) appstream = NULL;
  g_autoptr(GFile) new_appstream_file = NULL;

  arch_dir = flatpak_build_file (flatpak_dir_get_path (self),
                                 "appstream", remote, arch, NULL);
  if (g_mkdir_with_parents (flatpak_file_get_path_cached (arch_dir), 0755) != 0)
    {
      glnx_set_error_from_errno (error);
      return FALSE;
    }

  lock_file = g_file_get_child (arch_dir, "lock");
  if (!glnx_make_lock_file (AT_FDCWD, flatpak_file_get_path_cached (lock_file),
                            LOCK_EX, &lock, error))
    return FALSE;

  index_cache = flatpak_dir_update_oci_index (self, remote, &index_uri, cancellable, error);
  if (index_cache == NULL)
    return FALSE;

  timestamp_file = g_file_get_child (arch_dir, ".timestamp");
  if (check_destination_mtime (index_cache, timestamp_file, cancellable))
    return TRUE;

  icons_dir = g_file_get_child (arch_dir, "icons");
  if (g_mkdir_with_parents (flatpak_file_get_path_cached (icons_dir), 0755) != 0)
    {
      glnx_set_error_from_errno (error);
      return FALSE;
    }

  if (!glnx_opendirat (AT_FDCWD, flatpak_file_get_path_cached (icons_dir),
                       FALSE, &icons_dfd, error))
    return FALSE;

  ensure_http_session (self);

  appstream = flatpak_oci_index_make_appstream (self->http_session,
                                                index_cache,
                                                index_uri,
                                                arch,
                                                icons_dfd,
                                                cancellable,
                                                error);
  if (appstream == NULL)
    return FALSE;

  new_appstream_file = g_file_get_child (arch_dir, "appstream.xml.gz");
  if (!replace_contents_compressed (new_appstream_file, appstream, cancellable, error))
    return FALSE;

  if (!g_file_replace_contents (timestamp_file, "", 0, NULL, FALSE,
                                G_FILE_CREATE_REPLACE_DESTINATION, NULL, NULL, error))
    return FALSE;

  if (out_changed)
    *out_changed = TRUE;

  return TRUE;
}

gboolean
flatpak_dir_update_appstream (FlatpakDir          *self,
                              const char          *remote,
                              const char          *arch,
                              gboolean            *out_changed,
                              FlatpakProgress     *progress,
                              GCancellable        *cancellable,
                              GError             **error)
{
  g_autofree char *new_branch = NULL;
  g_autofree char *old_branch = NULL;
  const char *used_branch = NULL;
  g_autofree char *new_checksum = NULL;
  g_autoptr(GError) first_error = NULL;
  g_autoptr(GError) second_error = NULL;
  g_autoptr(FlatpakRemoteState) state = NULL;
  g_autofree char *appstream_commit = NULL;
  g_autofree char *subset = NULL;
  g_autoptr(GFile) appstream_sideload_path = NULL;
  const char *installation;
  gboolean is_oci;

  if (out_changed)
    *out_changed = FALSE;

  if (arch == NULL)
    arch = flatpak_get_arch ();

  subset = flatpak_dir_get_remote_subset (self, remote);

  if (subset)
    {
      new_branch = g_strdup_printf ("appstream2/%s-%s", subset, arch);
      old_branch = g_strdup_printf ("appstream/%s-%s", subset, arch);
    }
  else
    {
      new_branch = g_strdup_printf ("appstream2/%s", arch);
      old_branch = g_strdup_printf ("appstream/%s", arch);
    }

  is_oci = flatpak_dir_get_remote_oci (self, remote);

  state = flatpak_dir_get_remote_state_optional (self, remote, FALSE, cancellable, error);
  if (state == NULL)
    return FALSE;

  used_branch = new_branch;
  if (!is_oci)
    {
      if (!flatpak_dir_find_latest_rev (self, state, used_branch, NULL, &appstream_commit, NULL, &appstream_sideload_path, NULL, cancellable, &first_error))
        {
          used_branch = old_branch;
          if (!flatpak_dir_find_latest_rev (self, state, used_branch, NULL, &appstream_commit, NULL, &appstream_sideload_path, NULL, cancellable, &second_error))
            {
              g_prefix_error (&first_error, "Error updating appstream2: ");
              g_prefix_error (&second_error, "Error updating appstream: ");
              g_propagate_prefixed_error (error, g_steal_pointer (&second_error), "%s; ", first_error->message);
              return FALSE;
            }
        }
    }

  if (flatpak_dir_use_system_helper (self, NULL))
    {
      g_auto(GLnxLockFile) child_repo_lock = { 0, };
      g_autofree char *url = NULL;
      g_autoptr(GFile) child_repo_file = NULL;
      g_autofree char *child_repo_path = NULL;
      gboolean gpg_verify_summary;
      gboolean gpg_verify;

      if (!ostree_repo_remote_get_url (self->repo,
                                       state->remote_name,
                                       &url,
                                       error))
        return FALSE;

      if (!ostree_repo_remote_get_gpg_verify_summary (self->repo, state->remote_name,
                                                      &gpg_verify_summary, error))
        return FALSE;

      if (!ostree_repo_remote_get_gpg_verify (self->repo, state->remote_name,
                                              &gpg_verify, error))
        return FALSE;

      if (is_oci)
        {
          /* In the OCI case, we just ask the system helper do the network i/o, since
           * there is no way to verify the index validity without actually downloading it.
           * While we try to avoid network i/o as root, there's no hard line where doing
           * network i/o as root is much worse than parsing the results of network i/o
           * as root. A trusted, but unprivileged helper could be used to do the download
           * if necessary.
           */
        }
      else if (!gpg_verify_summary || !gpg_verify)
        {
          /* The remote is not gpg verified, so we don't want to allow installation via
             a download in the home directory, as there is no way to verify you're not
             injecting anything into the remote. However, in the case of a remote
             configured to a local filesystem we can just let the system helper do
             the installation, as it can then avoid network i/o and be certain the
             data comes from the right place.  */
          if (!g_str_has_prefix (url, "file:"))
            return flatpak_fail_error (error, FLATPAK_ERROR_UNTRUSTED, _("Can't pull from untrusted non-gpg verified remote"));
        }
      else
        {
          g_autoptr(OstreeRepo) child_repo = flatpak_dir_create_system_child_repo (self, &child_repo_lock, NULL, error);
          if (child_repo == NULL)
            return FALSE;

          if (!flatpak_dir_pull (self, state, used_branch, appstream_commit, NULL, appstream_sideload_path, NULL, NULL, NULL,
                                 child_repo, FLATPAK_PULL_FLAGS_NONE, 0,
                                 progress, cancellable, error))
            {
              g_prefix_error (&first_error, "Error updating appstream: ");
              return FALSE;
            }

          if (!flatpak_repo_resolve_rev (child_repo, NULL, remote, used_branch, TRUE,
                                         &new_checksum, cancellable, error))
            return FALSE;

          child_repo_file = g_object_ref (ostree_repo_get_path (child_repo));
        }

      if (child_repo_file)
        child_repo_path = g_file_get_path (child_repo_file);

      installation = flatpak_dir_get_id (self);

      if (!flatpak_dir_system_helper_call_deploy_appstream (self,
                                                            child_repo_path ? child_repo_path : "",
                                                            FLATPAK_HELPER_DEPLOY_APPSTREAM_FLAGS_NONE,
                                                            remote,
                                                            arch,
                                                            installation ? installation : "",
                                                            cancellable,
                                                            error))
        return FALSE;

      if (child_repo_file)
        (void) flatpak_rm_rf (child_repo_file, NULL, NULL);

      return TRUE;
    }

  if (is_oci)
    {
      return flatpak_dir_update_appstream_oci (self, remote, arch,
                                               out_changed, progress, cancellable,
                                               error);
    }


  if (!flatpak_dir_pull (self, state, used_branch, appstream_commit, NULL, appstream_sideload_path, NULL, NULL, NULL, NULL,
                         FLATPAK_PULL_FLAGS_NONE, OSTREE_REPO_PULL_FLAGS_NONE, progress,
                         cancellable, error))
    {
      g_prefix_error (&first_error, "Error updating appstream: ");
      return FALSE;
    }

  if (!flatpak_repo_resolve_rev (self->repo, NULL, remote, used_branch, TRUE,
                                 &new_checksum, cancellable, error))
    return FALSE;

  return flatpak_dir_deploy_appstream (self,
                                       remote,
                                       arch,
                                       out_changed,
                                       cancellable,
                                       error);
}

/* Get the configured collection-id for @remote_name, squashing empty strings into
 * %NULL. Return %TRUE if the ID was fetched successfully, or if it was unset or
 * empty. */
static gboolean
repo_get_remote_collection_id (OstreeRepo *repo,
                               const char *remote_name,
                               char      **collection_id_out,
                               GError    **error)
{
  if (collection_id_out != NULL)
    {
      if (!ostree_repo_get_remote_option (repo, remote_name, "collection-id",
                                          NULL, collection_id_out, error))
        return FALSE;
      if (*collection_id_out != NULL && **collection_id_out == '\0')
        g_clear_pointer (collection_id_out, g_free);
    }

  return TRUE;
}

/* Get options for the OSTree pull operation which can be shared between
 * collection-based and normal pulls. Update @builder in place. */
static void
get_common_pull_options (GVariantBuilder     *builder,
                         FlatpakRemoteState  *state,
                         const char          *ref_to_fetch,
                         const char          *token,
                         const gchar * const *dirs_to_pull,
                         const char          *current_local_checksum,
                         gboolean             force_disable_deltas,
                         OstreeRepoPullFlags  flags,
                         FlatpakProgress     *progress,
                         FlatpakDir          *dir)
{
  guint32 update_interval = 0;
  GVariantBuilder hdr_builder;

  if (state->summary_bytes && state->summary_sig_bytes)
    {
      g_variant_builder_add (builder, "{s@v}", "summary-bytes",
                             g_variant_new_variant (g_variant_new_from_bytes (G_VARIANT_TYPE ("ay"), state->summary_bytes, TRUE)));
      g_variant_builder_add (builder, "{s@v}", "summary-sig-bytes",
                             g_variant_new_variant (g_variant_new_from_bytes (G_VARIANT_TYPE ("ay"), state->summary_sig_bytes, TRUE)));
    }

  if (dirs_to_pull)
    {
      g_variant_builder_add (builder, "{s@v}", "subdirs",
                             g_variant_new_variant (g_variant_new_strv ((const char * const *) dirs_to_pull, -1)));
      force_disable_deltas = TRUE;
    }

  if (force_disable_deltas)
    {
      g_variant_builder_add (builder, "{s@v}", "disable-static-deltas",
                             g_variant_new_variant (g_variant_new_boolean (TRUE)));
    }

  g_variant_builder_add (builder, "{s@v}", "inherit-transaction",
                         g_variant_new_variant (g_variant_new_boolean (TRUE)));

  g_variant_builder_add (builder, "{s@v}", "flags",
                         g_variant_new_variant (g_variant_new_int32 (flags)));


  g_variant_builder_init (&hdr_builder, G_VARIANT_TYPE ("a(ss)"));
  g_variant_builder_add (&hdr_builder, "(ss)", "Flatpak-Ref", ref_to_fetch);
  if (token)
    {
      g_autofree char *bearer_token = g_strdup_printf ("Bearer %s", token);
      g_variant_builder_add (&hdr_builder, "(ss)", "Authorization", bearer_token);
    }
  if (current_local_checksum)
    g_variant_builder_add (&hdr_builder, "(ss)", "Flatpak-Upgrade-From", current_local_checksum);

  {
    g_autofree char *os_info = flatpak_dir_get_os_info (dir);
    if (os_info)
      g_variant_builder_add (&hdr_builder, "(ss)", "Flatpak-Os-Info", os_info);
  }

  g_variant_builder_add (builder, "{s@v}", "http-headers",
                         g_variant_new_variant (g_variant_builder_end (&hdr_builder)));
  g_variant_builder_add (builder, "{s@v}", "append-user-agent",
                         g_variant_new_variant (g_variant_new_string ("flatpak/" PACKAGE_VERSION)));

  update_interval = flatpak_progress_get_update_interval (progress);

  g_variant_builder_add (builder, "{s@v}", "update-frequency",
                         g_variant_new_variant (g_variant_new_uint32 (update_interval)));
}

static gboolean
translate_ostree_repo_pull_errors (GError **error)
{
  if (*error)
    {
      if (strstr ((*error)->message, "min-free-space-size") ||
          strstr ((*error)->message, "min-free-space-percent"))
        {
          (*error)->domain = FLATPAK_ERROR;
          (*error)->code = FLATPAK_ERROR_OUT_OF_SPACE;
        }
    }

  return FALSE;
}

static gboolean
repo_pull (OstreeRepo                           *self,
           FlatpakRemoteState                   *state,
           const char                          **dirs_to_pull,
           const char                           *ref_to_fetch,
           const char                           *rev_to_fetch,
           GFile                                *sideload_repo,
           const char                           *token,
           FlatpakPullFlags                      flatpak_flags,
           OstreeRepoPullFlags                   flags,
           FlatpakProgress                      *progress,
           FlatpakDir                           *dir,
           GCancellable                         *cancellable,
           GError                              **error)
{
  gboolean force_disable_deltas = (flatpak_flags & FLATPAK_PULL_FLAGS_NO_STATIC_DELTAS) != 0;
  g_autofree char *current_checksum = NULL;
  g_autoptr(GVariant) old_commit = NULL;
  g_autoptr(GVariant) new_commit = NULL;
  const char *revs_to_fetch[2];
  g_autoptr(GError) dummy_error = NULL;
  GVariantBuilder builder;
  g_autoptr(GVariant) options = NULL;
  const char *refs_to_fetch[2];
  g_autofree char *sideload_url = NULL;

  g_return_val_if_fail (ref_to_fetch != NULL, FALSE);
  g_return_val_if_fail (rev_to_fetch != NULL, FALSE);

  /* The ostree fetcher asserts if error is NULL */
  if (error == NULL)
    error = &dummy_error;

  /* We always want this on for every type of pull */
  flags |= OSTREE_REPO_PULL_FLAGS_BAREUSERONLY_FILES;

  if (!flatpak_repo_resolve_rev (self, NULL, state->remote_name, ref_to_fetch, TRUE,
                                 &current_checksum, cancellable, error))
    return FALSE;

  /* The remote tracking ref may be absent (e.g. the remote was removed and
   * re-added, the app was installed from a bundle, or the ref was deleted by
   * ostree-prune/flatpak-repair).  Fall back to the deploy/ ref that flatpak
   * always writes on every successful deploy so that Flatpak-Upgrade-From is
   * still sent correctly on the next update. */
  if (current_checksum == NULL && dir != NULL)
    {
      g_autofree char *deploy_ref = g_strconcat ("deploy/", ref_to_fetch, NULL);
      flatpak_repo_resolve_rev (self, NULL, NULL, deploy_ref, TRUE,
                                &current_checksum, cancellable, NULL);
    }

  if (current_checksum != NULL &&
      !ostree_repo_load_commit (self, current_checksum, &old_commit, NULL, error))
    return FALSE;

  /* Pull options */
  g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sv}"));
  get_common_pull_options (&builder, state, ref_to_fetch, token, dirs_to_pull, current_checksum,
                           force_disable_deltas, flags, progress, dir);

  if (sideload_repo)
    {
      GVariantBuilder colref_builder;

      sideload_url = g_file_get_uri (sideload_repo);

      g_info ("Sideloading %s from %s in pull", ref_to_fetch, sideload_url);

      g_assert (state->collection_id != NULL);

      g_variant_builder_init (&colref_builder, G_VARIANT_TYPE ("a(sss)"));
      g_variant_builder_add (&colref_builder, "(sss)", state->collection_id, ref_to_fetch, rev_to_fetch);

      g_variant_builder_add (&builder, "{s@v}", "collection-refs",
                             g_variant_new_variant (g_variant_builder_end (&colref_builder)));
      g_variant_builder_add (&builder, "{s@v}", "override-remote-name",
                             g_variant_new_variant (g_variant_new_string (state->remote_name)));
    }
  else
    {
      refs_to_fetch[0] = ref_to_fetch;
      refs_to_fetch[1] = NULL;
      g_variant_builder_add (&builder, "{s@v}", "refs",
                             g_variant_new_variant (g_variant_new_strv ((const char * const *) refs_to_fetch, -1)));

      revs_to_fetch[0] = rev_to_fetch;
      revs_to_fetch[1] = NULL;
      g_variant_builder_add (&builder, "{s@v}", "override-commit-ids",
                             g_variant_new_variant (g_variant_new_strv ((const char * const *) revs_to_fetch, -1)));


      if (state->sideload_repos->len > 0)
        {
          GVariantBuilder localcache_repos_builder;

          g_variant_builder_init (&localcache_repos_builder, G_VARIANT_TYPE ("as"));
          for (int i = 0; i < state->sideload_repos->len; i++)
            {
              FlatpakSideloadState *ss = g_ptr_array_index (state->sideload_repos, i);
              GFile *sideload_path = ostree_repo_get_path (ss->repo);

              g_variant_builder_add (&localcache_repos_builder, "s",
                                     flatpak_file_get_path_cached (sideload_path));
            }
          g_variant_builder_add (&builder, "{s@v}", "localcache-repos",
                                 g_variant_new_variant (g_variant_builder_end (&localcache_repos_builder)));
        }
    }

  options = g_variant_ref_sink (g_variant_builder_end (&builder));

  {
    g_auto(FlatpakMainContext) context = FLATKPAK_MAIN_CONTEXT_INIT;
    flatpak_progress_init_main_context (progress, &context);

    if (!ostree_repo_pull_with_options (self,
                                        sideload_url ? sideload_url : state->remote_name,
                                        options, context.ostree_progress, cancellable, error))
      return translate_ostree_repo_pull_errors (error);
  }

  if (old_commit &&
      (flatpak_flags & FLATPAK_PULL_FLAGS_ALLOW_DOWNGRADE) == 0)
    {
      guint64 old_timestamp;
      guint64 new_timestamp;

      if (!ostree_repo_load_commit (self, rev_to_fetch, &new_commit, NULL, error))
        return FALSE;

      old_timestamp = ostree_commit_get_timestamp (old_commit);
      new_timestamp = ostree_commit_get_timestamp (new_commit);

      if (new_timestamp < old_timestamp)
        return flatpak_fail_error (error, FLATPAK_ERROR_DOWNGRADE, "Update is older than current version");
    }

  return TRUE;
}

static void
ensure_http_session (FlatpakDir *self)
{
  if (g_once_init_enter (&self->http_session))
    {
      FlatpakHttpSession *http_session;

      http_session = flatpak_create_http_session (PACKAGE_STRING);

      g_once_init_leave (&self->http_session, http_session);
    }
}

static void
extra_data_progress_report (guint64  downloaded_bytes,
                            gpointer user_data)
{
  FlatpakProgress *progress = FLATPAK_PROGRESS (user_data);

  flatpak_progress_update_extra_data (progress, downloaded_bytes);
}

static void
compute_extra_data_download_size (GVariant *extra_data_sources,
                                  guint64  *out_n_extra_data,
                                  guint64  *out_total_download_size)
{
  guint64 i;
  guint64 n_extra_data = 0;
  guint64 total_download_size = 0;

  if (extra_data_sources != NULL)
    {
      n_extra_data = g_variant_n_children (extra_data_sources);
      for (i = 0; i < n_extra_data; i++)
        {
          guint64 download_size;
          flatpak_repo_parse_extra_data_sources (extra_data_sources, i,
                                                 NULL,
                                                 &download_size,
                                                 NULL,
                                                 NULL,
                                                 NULL);
          total_download_size += download_size;
        }
    }

  *out_n_extra_data = n_extra_data;
  *out_total_download_size = total_download_size;
}

static gboolean
flatpak_dir_setup_extra_data (FlatpakDir                           *self,
                              FlatpakRemoteState                   *state,
                              OstreeRepo                           *repo,
                              const char                           *ref,
                              const char                           *rev,
                              const char                           *token,
                              FlatpakPullFlags                      flatpak_flags,
                              FlatpakProgress                      *progress,
                              GCancellable                         *cancellable,
                              GError                              **error)
{
  guint64 n_extra_data = 0;
  guint64 total_download_size = 0;

  /* ostree-metadata and appstreams never have extra data, so ignore those */
  if (g_str_has_prefix (ref, "app/") || g_str_has_prefix (ref, "runtime/"))
    {
      g_autofree char *summary_checksum = NULL;
      GVariant *summary;

      /* Version 1 added extra data details, so we can rely on it
       * either being in the sparse cache or no extra data.  However,
       * it only applies to the commit the summary contains, so verify
       * that too.
       */
      summary = get_summary_for_ref (state, ref);
      if (summary != NULL &&
          flatpak_summary_lookup_ref (summary, NULL, ref, &summary_checksum, NULL) &&
          g_strcmp0 (rev, summary_checksum) == 0 &&
          flatpak_remote_state_get_cache_version (state) >= 1)
        {
          VarMetadataRef metadata;
          VarVariantRef res;

          if (flatpak_remote_state_lookup_sparse_cache (state, ref, &metadata, NULL) &&
              var_metadata_lookup (metadata, FLATPAK_SPARSE_CACHE_KEY_EXTRA_DATA_SIZE, NULL, &res) &&
              var_variant_is_type (res, VAR_EXTRA_DATA_SIZE_TYPEFORMAT))
            {
              VarExtraDataSizeRef eds = var_extra_data_size_from_variant (res);
              n_extra_data = var_extra_data_size_get_n_extra_data (eds);
              total_download_size = var_extra_data_size_get_total_size (eds);
            }
        }
      else
        {
          /* No summary/cache or old cache version, download commit and get size from there */
          g_autoptr(GVariant) commitv = NULL;
          g_autoptr(GVariant) extra_data_sources = NULL;

          commitv = flatpak_remote_state_load_ref_commit (state, self, ref, rev,
                                                          token, NULL, cancellable, error);
          if (commitv == NULL)
            return FALSE;

          extra_data_sources = flatpak_commit_get_extra_data_sources (commitv, NULL);
          compute_extra_data_download_size (extra_data_sources, &n_extra_data, &total_download_size);
        }
    }

  if (n_extra_data > 0 &&
      (flatpak_flags & FLATPAK_PULL_FLAGS_DOWNLOAD_EXTRA_DATA) == 0)
    return flatpak_fail_error (error, FLATPAK_ERROR_UNTRUSTED, _("Extra data not supported for non-gpg-verified local system installs"));

  flatpak_progress_init_extra_data (progress, n_extra_data, total_download_size);

  return TRUE;
}

static gboolean
flatpak_dir_pull_extra_data_to_bytes (FlatpakDir       *self,
                                      GVariant         *extra_data_sources,
                                      int               extra_data_index,
                                      FlatpakProgress  *progress,
                                      GBytes          **bytes_out,
                                      const char      **name_out,
                                      GCancellable     *cancellable,
                                      GError          **error)
{
  const char *name = NULL;
  guint64 download_size;
  guint64 installed_size;
  const guchar *expected_sha256_bytes;
  const char *uri = NULL;
  g_autofree char *expected_sha256 = NULL;
  g_autofree char *actual_sha256 = NULL;
  g_autoptr(GBytes) bytes = NULL;
  g_autoptr(GFile) extra_local_file = NULL;
  g_autoptr(GFile) base_dir = NULL;

  flatpak_repo_parse_extra_data_sources (extra_data_sources,
                                         extra_data_index,
                                         &name,
                                         &download_size,
                                         &installed_size,
                                         &expected_sha256_bytes,
                                         &uri);

  if (expected_sha256_bytes == NULL)
    {
      return flatpak_fail_error (error, FLATPAK_ERROR_INVALID_DATA,
                                 _("Invalid checksum for extra data uri %s"),
                                 uri);
    }

  expected_sha256 = ostree_checksum_from_bytes (expected_sha256_bytes);

  if (name == NULL || *name == '\0')
    {
      return flatpak_fail_error (error, FLATPAK_ERROR_INVALID_DATA,
                                 _("Empty name for extra data uri %s"), uri);
    }

  /* Don't allow file uris here as that could read local files based on remote data */
  if (!g_str_has_prefix (uri, "http:") &&
      !g_str_has_prefix (uri, "https:"))
    {
      return flatpak_fail_error (error, FLATPAK_ERROR_INVALID_DATA,
                                 _("Unsupported extra data uri %s"), uri);
    }

  /* TODO: Download to disk to support resumed downloads on error */

  base_dir = flatpak_get_user_base_dir_location ();
  extra_local_file = flatpak_build_file (base_dir,
                                         "extra-data",
                                         expected_sha256,
                                         name,
                                         NULL);

  if (g_file_query_exists (extra_local_file, cancellable))
    {
      gsize extra_local_size;
      g_autofree char *extra_local_contents = NULL;
      g_autoptr(GError) local_error = NULL;

      g_info ("Loading extra-data from local file %s",
              flatpak_file_get_path_cached (extra_local_file));

      if (!g_file_load_contents (extra_local_file,
                                 cancellable,
                                 &extra_local_contents,
                                 &extra_local_size,
                                 NULL,
                                 &local_error))
        {
          return flatpak_fail_error (error, FLATPAK_ERROR_INVALID_DATA,
                                     _("Failed to load local extra-data %s: %s"),
                                     flatpak_file_get_path_cached (extra_local_file),
                                     local_error->message);
        }

      if (extra_local_size != download_size)
        {
          return flatpak_fail_error (error, FLATPAK_ERROR_INVALID_DATA,
                                     _("Wrong size for extra-data %s"),
                                     flatpak_file_get_path_cached (extra_local_file));
        }

      bytes = g_bytes_new (extra_local_contents, extra_local_size);
    }
  else
    {
      ensure_http_session (self);
      bytes = flatpak_load_uri (self->http_session,
                                uri,
                                0, NULL,
                                extra_data_progress_report,
                                progress,
                                NULL,
                                cancellable, error);

      if (bytes == NULL)
        {
          g_prefix_error (error, _("While downloading %s: "), uri);
          return FALSE;
        }
    }

  g_assert (bytes != NULL);

  if (g_bytes_get_size (bytes) != download_size)
    {
      return flatpak_fail_error (error, FLATPAK_ERROR_INVALID_DATA,
                                 _("Wrong size for extra data %s"), uri);
    }

  flatpak_progress_complete_extra_data_download (progress, download_size);

  actual_sha256 = g_compute_checksum_for_bytes (G_CHECKSUM_SHA256, bytes);
  if (strcmp (actual_sha256, expected_sha256) != 0)
    {
      return flatpak_fail_error (error, FLATPAK_ERROR_INVALID_DATA,
                                 _("Invalid checksum for extra data %s"), uri);
    }

  if (bytes_out)
    *bytes_out = g_steal_pointer (&bytes);
  if (name_out)
    *name_out = name;
  return TRUE;
}

static gboolean
flatpak_dir_pull_extra_data (FlatpakDir       *self,
                             GVariant         *extra_data_sources,
                             FlatpakProgress  *progress,
                             GPtrArray        *extra_data_out,
                             GPtrArray        *names_out,
                             GCancellable     *cancellable,
                             GError          **error)
{
  gsize n_extra_data;

  n_extra_data = g_variant_n_children (extra_data_sources);
  if (n_extra_data == 0)
    return TRUE;

  /* Other fields were already set in flatpak_dir_setup_extra_data() */
  flatpak_progress_start_extra_data (progress);

  for (size_t i = 0; i < n_extra_data; i++)
    {
      g_autoptr(GBytes) bytes = NULL;
      const char *name = NULL;

      if (!flatpak_dir_pull_extra_data_to_bytes (self,
                                                 extra_data_sources,
                                                 i,
                                                 progress,
                                                 &bytes,
                                                 &name,
                                                 cancellable,
                                                 error))
        {
          flatpak_progress_reset_extra_data (progress);
          return FALSE;
        }

      if (extra_data_out)
        g_ptr_array_add (extra_data_out, g_steal_pointer (&bytes));
      if (names_out)
        g_ptr_array_add (names_out, g_strdup (name));
    }

  flatpak_progress_reset_extra_data (progress);

  return TRUE;
}

static gboolean
flatpak_dir_pull_ostree_extra_data (FlatpakDir        *self,
                                    OstreeRepo        *repo,
                                    const char        *repository,
                                    const char        *ref,
                                    const char        *rev,
                                    FlatpakPullFlags   flatpak_flags,
                                    FlatpakProgress   *progress,
                                    GCancellable      *cancellable,
                                    GError           **error)
{
  g_autoptr(GVariant) extra_data_sources = NULL;
  g_autoptr(GPtrArray) extra_data = NULL;
  g_autoptr(GPtrArray) names = NULL;
  g_autoptr(GVariantBuilder) extra_data_builder = NULL;
  g_autoptr(GVariant) detached_metadata = NULL;
  g_auto(GVariantDict) new_metadata_dict = FLATPAK_VARIANT_DICT_INITIALIZER;
  g_autoptr(GVariant) new_detached_metadata = NULL;

  extra_data_sources = flatpak_repo_get_extra_data_sources (repo, rev,
                                                            cancellable, NULL);
  if (extra_data_sources == NULL)
    return TRUE;

  if ((flatpak_flags & FLATPAK_PULL_FLAGS_DOWNLOAD_EXTRA_DATA) == 0)
    {
      return flatpak_fail_error (error, FLATPAK_ERROR_UNTRUSTED,
                                 _("Extra data not supported for non-gpg-verified local system installs"));
    }

  extra_data = g_ptr_array_new_with_free_func ((GDestroyNotify) g_bytes_unref);
  names = g_ptr_array_new_with_free_func (g_free);

  if (!flatpak_dir_pull_extra_data (self,
                                    extra_data_sources,
                                    progress,
                                    extra_data,
                                    names,
                                    cancellable,
                                    error))
    return FALSE;

  extra_data_builder = g_variant_builder_new (G_VARIANT_TYPE ("a(ayay)"));

  for (size_t i = 0; i < extra_data->len; i++)
    {
      GBytes *bytes = g_ptr_array_index (extra_data, i);
      const char *name = g_ptr_array_index (names, i);

      g_variant_builder_add (extra_data_builder,
                             "(^ay@ay)",
                             name,
                             g_variant_new_from_bytes (G_VARIANT_TYPE ("ay"),
                                                       bytes, TRUE));
    }

  if (!ostree_repo_read_commit_detached_metadata (repo, rev, &detached_metadata,
                                                  cancellable, error))
    return FALSE;

  g_variant_dict_init (&new_metadata_dict, detached_metadata);
  g_variant_dict_insert_value (&new_metadata_dict, "xa.extra-data",
                               g_variant_builder_end (extra_data_builder));
  new_detached_metadata = g_variant_ref_sink (g_variant_dict_end (&new_metadata_dict));

  /* There is a commitmeta size limit when pulling, so we have to side-load it
     when installing in the system repo */
  if (flatpak_flags & FLATPAK_PULL_FLAGS_SIDELOAD_EXTRA_DATA)
    {
      int dfd;
      g_autoptr(GVariant) normalized = NULL;
      gsize normalized_size;
      const guint8 *data;
      g_autofree char *filename = NULL;

      dfd =  ostree_repo_get_dfd (repo);
      normalized = g_variant_get_normal_form (new_detached_metadata);
      normalized_size = g_variant_get_size (normalized);
      data = g_variant_get_data (normalized);
      filename = g_strconcat (rev, ".commitmeta", NULL);

      if (!glnx_file_replace_contents_at (dfd, filename,
                                          data, normalized_size,
                                          0, cancellable, error))
        {
          g_prefix_error (error, "Unable to write sideloaded detached metadata: ");
          return FALSE;
        }
    }
  else
    {
      if (!ostree_repo_write_commit_detached_metadata (repo, rev,
                                                       new_detached_metadata,
                                                       cancellable, error))
        return FALSE;
    }

  return TRUE;
}

/* Extra-data usually is downloaded on the user side into an ostree repo.
 * For system installs, a temporary ostree repo is used on the user side
 * and then imported on the system side. This doesn't work for OCI images
 * because importing the image into an ostree repo makes it impossible for
 * the system side to verify the data.
 *
 * So instead, the OCI image is first mirrored into a local OCI repo and
 * then gets imported on the system side, which can verify the image from
 * the index by the digest.
 */
static gboolean
flatpak_dir_mirror_oci_extra_data (FlatpakDir          *self,
                                   FlatpakOciRegistry  *dst_registry,
                                   FlatpakImageSource  *image_source,
                                   FlatpakProgress     *progress,
                                   GCancellable        *cancellable,
                                   GError             **error)
{
  g_autoptr(GVariantBuilder) metadata_builder =
    g_variant_builder_new (G_VARIANT_TYPE ("a{sv}"));
  g_autoptr(GVariant) commit_metadata = NULL;
  g_autoptr(GVariant) extra_data_sources = NULL;
  g_autoptr(GPtrArray) extra_data = NULL;

  flatpak_image_source_build_commit_metadata (image_source, metadata_builder);
  commit_metadata = g_variant_ref_sink (g_variant_builder_end (metadata_builder));
  extra_data_sources = g_variant_lookup_value (commit_metadata,
                                               "xa.extra-data-sources",
                                               G_VARIANT_TYPE ("a(ayttays)"));
  if (extra_data_sources == NULL)
    return TRUE;

  {
    guint64 n_extra_data = 0;
    guint64 total_download_size = 0;

    compute_extra_data_download_size (extra_data_sources,
                                      &n_extra_data,
                                      &total_download_size);
    flatpak_progress_init_extra_data (progress,
                                      n_extra_data,
                                      total_download_size);
  }

  extra_data = g_ptr_array_new_with_free_func ((GDestroyNotify) g_bytes_unref);

  if (!flatpak_dir_pull_extra_data (self,
                                    extra_data_sources,
                                    progress,
                                    extra_data,
                                    NULL,
                                    cancellable,
                                    error))
    return FALSE;

  for (size_t i = 0; i < extra_data->len; i++)
    {
      GBytes *bytes = g_ptr_array_index (extra_data, i);
      g_autofree char *rev = NULL;

      rev = flatpak_oci_registry_store_blob (dst_registry,
                                             bytes,
                                             cancellable,
                                             error);
      if (rev == NULL)
        return FALSE;
    }

  return TRUE;
}

gboolean
flatpak_dir_pull_oci_extra_data (OstreeRepo              *repo,
                                 FlatpakImageSource      *image_source,
                                 const char              *rev,
                                 GCancellable            *cancellable,
                                 GError                 **error)
{
  g_autoptr(GVariant) extra_data_sources = NULL;
  g_autoptr(GVariant) detached_metadata = NULL;
  g_autoptr(GVariantBuilder) extra_data_builder = NULL;
  g_auto(GVariantDict) new_metadata_dict = FLATPAK_VARIANT_DICT_INITIALIZER;
  g_autoptr(GVariant) new_detached_metadata = NULL;
  size_t n_extra_data;
  FlatpakOciRegistry *registry = flatpak_image_source_get_registry (image_source);
  const char *repository = flatpak_image_source_get_oci_repository (image_source);

  extra_data_sources = flatpak_repo_get_extra_data_sources (repo, rev,
                                                            cancellable, NULL);
  if (extra_data_sources == NULL)
    return TRUE;

  n_extra_data = g_variant_n_children (extra_data_sources);
  if (n_extra_data == 0)
    return TRUE;

  extra_data_builder = g_variant_builder_new (G_VARIANT_TYPE ("a(ayay)"));

  for (size_t i = 0; i < n_extra_data; i++)
    {
      const char *name = NULL;
      const char *uri = NULL;
      const guchar *expected_sha256_bytes;
      g_autofree char *expected_sha256 = NULL;
      g_autofree char *digest = NULL;
      g_autoptr(GBytes) bytes = NULL;

      flatpak_repo_parse_extra_data_sources (extra_data_sources,
                                             i,
                                             &name,
                                             NULL,
                                             NULL,
                                             &expected_sha256_bytes,
                                             &uri);

      if (expected_sha256_bytes == NULL)
        {
          return flatpak_fail_error (error, FLATPAK_ERROR_INVALID_DATA,
                                     _("Invalid checksum for extra data uri %s"),
                                     uri);
        }

      expected_sha256 = ostree_checksum_from_bytes (expected_sha256_bytes);
      digest = g_strdup_printf ("sha256:%s", expected_sha256);

      bytes = flatpak_oci_registry_load_blob (registry,
                                              repository,
                                              FALSE,
                                              digest,
                                              NULL,
                                              NULL,
                                              cancellable,
                                              error);
      if (!bytes)
        return FALSE;

      g_variant_builder_add (extra_data_builder,
                             "(^ay@ay)",
                             name,
                             g_variant_new_from_bytes (G_VARIANT_TYPE ("ay"),
                                                       bytes, TRUE));
    }

  if (!ostree_repo_read_commit_detached_metadata (repo, rev, &detached_metadata,
                                                  cancellable, error))
    return FALSE;

  g_variant_dict_init (&new_metadata_dict, detached_metadata);
  g_variant_dict_insert_value (&new_metadata_dict, "xa.extra-data",
                               g_variant_builder_end (extra_data_builder));
  new_detached_metadata = g_variant_ref_sink (g_variant_dict_end (&new_metadata_dict));

  if (!ostree_repo_write_commit_detached_metadata (repo, rev,
                                                   new_detached_metadata,
                                                   cancellable, error))
    return FALSE;

  return TRUE;
}

static void
oci_pull_progress_cb (guint64 total_size, guint64 pulled_size,
                      guint32 n_layers, guint32 pulled_layers,
                      gpointer data)
{
  FlatpakProgress *progress = data;

  flatpak_progress_update_oci_pull (progress, total_size, pulled_size, n_layers, pulled_layers);
}

static gboolean
flatpak_dir_mirror_oci (FlatpakDir          *self,
                        FlatpakOciRegistry  *dst_registry,
                        FlatpakRemoteState  *state,
                        const char          *ref,
                        const char          *opt_rev,
                        FlatpakImageSource  *opt_image_source,
                        const char          *token,
                        FlatpakProgress     *progress,
                        GCancellable        *cancellable,
                        GError             **error)
{
  g_autoptr(FlatpakImageSource) image_source = NULL;
  gboolean res;

  if (opt_image_source)
    image_source = g_object_ref (opt_image_source);

  if (!image_source)
    {
      image_source = flatpak_remote_state_fetch_image_source (state, self,
                                                              ref, opt_rev, token,
                                                              cancellable, error);
      if (image_source == NULL)
        return FALSE;
    }

  flatpak_progress_start_oci_pull (progress);

  g_info ("Mirroring OCI image %s", flatpak_image_source_get_digest (image_source));

  res = flatpak_mirror_image_from_oci (dst_registry, image_source, state->remote_name, ref, self->repo, oci_pull_progress_cb,
                                       progress, cancellable, error);
  if (!res)
    return FALSE;

  if (!flatpak_dir_mirror_oci_extra_data (self,
                                          dst_registry,
                                          image_source,
                                          progress,
                                          cancellable,
                                          error))
    return FALSE;

  return TRUE;
}

static gboolean
flatpak_dir_pull_oci (FlatpakDir          *self,
                      FlatpakRemoteState  *state,
                      const char          *ref,
                      const char          *opt_rev,
                      FlatpakImageSource  *opt_image_source,
                      OstreeRepo          *repo,
                      FlatpakPullFlags     flatpak_flags,
                      OstreeRepoPullFlags  flags,
                      const char          *token,
                      FlatpakProgress     *progress,
                      GCancellable        *cancellable,
                      GError             **error)
{
  g_autoptr(FlatpakImageSource) image_source = NULL;
  FlatpakOciRegistry *registry = NULL;
  const char *oci_digest = NULL;
  g_autofree char *checksum = NULL;
  g_autofree char *latest_alt_commit = NULL;
  G_GNUC_UNUSED g_autofree char *latest_commit =
    flatpak_dir_read_latest (self, state->remote_name, ref, &latest_alt_commit, cancellable, NULL);
  g_autofree char *name = NULL;

  if (opt_image_source)
    image_source = g_object_ref (opt_image_source);

  if (!image_source)
    {
      image_source = flatpak_remote_state_fetch_image_source (state, self,
                                                              ref, opt_rev, token,
                                                              cancellable, error);
      if (image_source == NULL)
        return FALSE;
    }

  oci_digest = flatpak_image_source_get_digest (image_source);

  /* Short circuit if we've already got this commit */
  if (latest_alt_commit != NULL && strcmp (oci_digest + strlen ("sha256:"), latest_alt_commit) == 0)
    return TRUE;

  if (repo == NULL)
    repo = self->repo;

  flatpak_progress_start_oci_pull (progress);

  g_info ("Pulling OCI image %s", oci_digest);

  checksum = flatpak_pull_from_oci (repo, image_source, NULL,
                                    state->remote_name, ref, flatpak_flags, oci_pull_progress_cb, progress, cancellable, error);

  if (checksum == NULL)
    return FALSE;

  g_info ("Imported OCI image as checksum %s", checksum);

  if (!flatpak_dir_setup_extra_data (self, state, repo,
                                     ref, checksum, token,
                                     flatpak_flags,
                                     progress,
                                     cancellable,
                                     error))
    return FALSE;

  if (!flatpak_dir_pull_ostree_extra_data (self, repo,
                                           state->remote_name,
                                           ref, checksum,
                                           flatpak_flags,
                                           progress,
                                           cancellable,
                                           error))
    return FALSE;

  if (repo == self->repo)
    name = flatpak_dir_get_name (self);
  else
    {
      GFile *file = ostree_repo_get_path (repo);
      name = g_file_get_path (file);
    }

  registry = flatpak_image_source_get_registry (image_source);
  (flatpak_dir_log) (self, __FILE__, __LINE__, __FUNCTION__, name,
                     "pull oci", flatpak_oci_registry_get_uri (registry), ref, NULL, NULL, NULL,
                     "Pulled %s from %s", ref, flatpak_oci_registry_get_uri (registry));

  return TRUE;
}

gboolean
flatpak_dir_pull (FlatpakDir                           *self,
                  FlatpakRemoteState                   *state,
                  const char                           *ref,
                  const char                           *opt_rev,
                  const char                          **subpaths,
                  GFile                                *sideload_repo,
                  FlatpakImageSource                   *opt_image_source,
                  GBytes                               *require_metadata,
                  const char                           *token,
                  OstreeRepo                           *repo,
                  FlatpakPullFlags                      flatpak_flags,
                  OstreeRepoPullFlags                   flags,
                  FlatpakProgress                      *progress,
                  GCancellable                         *cancellable,
                  GError                              **error)
{
  gboolean ret = FALSE;
  gboolean have_commit = FALSE;
  g_autofree char *rev = NULL;
  g_autofree char *url = NULL;
  g_autoptr(GPtrArray) subdirs_arg = NULL;
  g_auto(GLnxLockFile) lock = { 0, };
  g_autofree char *name = NULL;
  g_autofree char *current_checksum = NULL;

  if (!flatpak_dir_ensure_repo (self, cancellable, error))
    return FALSE;

  /* Keep a shared repo lock to avoid prunes removing objects we're relying on
   * while we do the pull. There are two cases we protect against. 1) objects we
   * need but that we already decided are locally available could be removed,
   * and 2) during the transaction commit objects that don't yet have a ref to
   * them could be considered unreachable.
   */
  if (repo == NULL && !flatpak_dir_repo_lock (self, &lock, LOCK_SH, cancellable, error))
    return FALSE;

  if (opt_image_source || flatpak_dir_get_remote_oci (self, state->remote_name))
    return flatpak_dir_pull_oci (self, state, ref, opt_rev, opt_image_source, repo, flatpak_flags,
                                 flags, token, progress, cancellable, error);

  if (!ostree_repo_remote_get_url (self->repo,
                                   state->remote_name,
                                   &url,
                                   error))
    return FALSE;

  if (*url == 0)
    return TRUE; /* Empty url, silently disables updates */

  /* We get the rev ahead of time so that we know it for looking up e.g. extra-data
     and to make sure we're atomically using a single rev if we happen to do multiple
     pulls (e.g. with subpaths) */
  if (opt_rev != NULL)
    {
      rev = g_strdup (opt_rev);
    }
  else if (!flatpak_remote_state_lookup_ref (state, ref, &rev, NULL, NULL, NULL, NULL, error))
    {
      g_assert (error == NULL || *error != NULL);
      return FALSE;
    }

  g_info ("%s: Using commit %s for pull of ref %s from remote %s%s%s",
          G_STRFUNC, rev, ref, state->remote_name,
          sideload_repo ? "sideloaded from " : "",
          sideload_repo ? flatpak_file_get_path_cached (sideload_repo) : ""
          );

  if (repo == NULL)
    repo = self->repo;

  /* Past this we must use goto out, so we clean up console and
     abort the transaction on error */

  if (subpaths != NULL && subpaths[0] != NULL)
    {
      subdirs_arg = g_ptr_array_new_with_free_func (g_free);
      int i;
      g_ptr_array_add (subdirs_arg, g_strdup ("/metadata"));
      for (i = 0; subpaths[i] != NULL; i++)
        g_ptr_array_add (subdirs_arg,
                         g_build_filename ("/files", subpaths[i], NULL));
      g_ptr_array_add (subdirs_arg, NULL);
    }

  /* Setup extra data information before starting to pull, so we can have precise
   * progress reports */
  if (!flatpak_dir_setup_extra_data (self, state, repo,
                                     ref, rev, token,
                                     flatpak_flags,
                                     progress,
                                     cancellable,
                                     error))
    goto out;

  /* Work around a libostree bug where the pull may succeed but the pulled
   * commit will be incomplete by preemptively marking the commit partial.
   * Note this has to be done before ostree_repo_prepare_transaction() so we
   * aren't checking the staging dir for the commit.
   * https://github.com/flatpak/flatpak/issues/3479
   * https://github.com/ostreedev/ostree/pull/2549
   */
  {
    g_autoptr(GError) local_error = NULL;

    if (!ostree_repo_has_object (repo, OSTREE_OBJECT_TYPE_COMMIT, rev, &have_commit, NULL, &local_error))
      g_warning ("Encountered error checking for commit object %s: %s", rev, local_error->message);
    else if (!have_commit &&
             !ostree_repo_mark_commit_partial (repo, rev, TRUE, &local_error))
      g_warning ("Encountered error marking commit partial: %s: %s", rev, local_error->message);
  }

  if (!ostree_repo_prepare_transaction (repo, NULL, cancellable, error))
    goto out;

  flatpak_repo_resolve_rev (repo, NULL, state->remote_name, ref, TRUE,
                            &current_checksum, NULL, NULL);

  if (!repo_pull (repo, state,
                  subdirs_arg ? (const char **) subdirs_arg->pdata : NULL,
                  ref, rev, sideload_repo, token, flatpak_flags, flags,
                  progress, self,
                  cancellable, error))
    {
      g_prefix_error (error, _("While pulling %s from remote %s: "), ref, state->remote_name);
      goto out;
    }


  if (require_metadata)
    {
      g_autoptr(GVariant) commit_data = NULL;
      if (!ostree_repo_load_commit (repo, rev, &commit_data, NULL, error) ||
          !validate_commit_metadata (commit_data,
                                     ref,
                                     (const char *)g_bytes_get_data (require_metadata, NULL),
                                     g_bytes_get_size (require_metadata),
                                     error))
        goto out;
    }

  if (!flatpak_dir_pull_ostree_extra_data (self, repo,
                                           state->remote_name,
                                           ref, rev,
                                           flatpak_flags,
                                           progress,
                                           cancellable,
                                           error))
    goto out;


  if (!ostree_repo_commit_transaction (repo, NULL, cancellable, error))
    goto out;

  ret = TRUE;

  if (repo == self->repo)
    name = flatpak_dir_get_name (self);
  else
    {
      GFile *file = ostree_repo_get_path (repo);
      name = g_file_get_path (file);
    }

  (flatpak_dir_log) (self, __FILE__, __LINE__, __FUNCTION__, name,
                     "pull", state->remote_name, ref, rev, current_checksum, NULL,
                     "Pulled %s from %s", ref, state->remote_name);

out:
  if (!ret)
    {
      ostree_repo_abort_transaction (repo, cancellable, NULL);
      g_assert (error == NULL || *error != NULL);
    }

  return ret;
}

static gboolean
repo_pull_local_untrusted (FlatpakDir          *self,
                           OstreeRepo          *repo,
                           const char          *remote_name,
                           const char          *url,
                           const char         **dirs_to_pull,
                           const char          *ref,
                           const char          *checksum,
                           FlatpakProgress     *progress,
                           GCancellable        *cancellable,
                           GError             **error)
{
  /* The latter flag was introduced in https://github.com/ostreedev/ostree/pull/926 */
  const OstreeRepoPullFlags flags = OSTREE_REPO_PULL_FLAGS_UNTRUSTED | OSTREE_REPO_PULL_FLAGS_BAREUSERONLY_FILES;
  GVariantBuilder builder;
  g_autoptr(GVariant) options = NULL;
  gboolean res;
  g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sv}"));
  const char *refs[2] = { NULL, NULL };
  const char *commits[2] = { NULL, NULL };
  g_autoptr(GError) dummy_error = NULL;
  g_auto(FlatpakMainContext) context = FLATKPAK_MAIN_CONTEXT_INIT;

  /* The ostree fetcher asserts if error is NULL */
  if (error == NULL)
    error = &dummy_error;

  refs[0] = ref;
  commits[0] = checksum;

  g_variant_builder_add (&builder, "{s@v}", "refs",
                         g_variant_new_variant (g_variant_new_strv ((const char * const *) refs, -1)));
  g_variant_builder_add (&builder, "{s@v}", "override-commit-ids",
                         g_variant_new_variant (g_variant_new_strv ((const char * const *) commits, -1)));

  g_variant_builder_add (&builder, "{s@v}", "flags",
                         g_variant_new_variant (g_variant_new_int32 (flags)));
  g_variant_builder_add (&builder, "{s@v}", "override-remote-name",
                         g_variant_new_variant (g_variant_new_string (remote_name)));
  g_variant_builder_add (&builder, "{s@v}", "gpg-verify",
                         g_variant_new_variant (g_variant_new_boolean (TRUE)));
  g_variant_builder_add (&builder, "{s@v}", "gpg-verify-summary",
                         g_variant_new_variant (g_variant_new_boolean (FALSE)));
  g_variant_builder_add (&builder, "{s@v}", "inherit-transaction",
                         g_variant_new_variant (g_variant_new_boolean (TRUE)));
  g_variant_builder_add (&builder, "{s@v}", "update-frequency",
                         g_variant_new_variant (g_variant_new_uint32 (FLATPAK_DEFAULT_UPDATE_INTERVAL_MS)));

  if (dirs_to_pull)
    {
      g_variant_builder_add (&builder, "{s@v}", "subdirs",
                             g_variant_new_variant (g_variant_new_strv ((const char * const *) dirs_to_pull, -1)));
      g_variant_builder_add (&builder, "{s@v}", "disable-static-deltas",
                             g_variant_new_variant (g_variant_new_boolean (TRUE)));
    }

  options = g_variant_ref_sink (g_variant_builder_end (&builder));

  flatpak_progress_init_main_context (progress, &context);
  res = ostree_repo_pull_with_options (repo, url, options,
                                       context.ostree_progress, cancellable, error);
  if (!res)
    translate_ostree_repo_pull_errors (error);

  return res;
}

gboolean
flatpak_dir_pull_untrusted_local (FlatpakDir          *self,
                                  const char          *src_path,
                                  const char          *remote_name,
                                  const char          *ref,
                                  const char         **subpaths,
                                  FlatpakProgress     *progress,
                                  GCancellable        *cancellable,
                                  GError             **error)
{
  g_autoptr(GFile) path_file = g_file_new_for_path (src_path);
  g_autofree char *url = g_file_get_uri (path_file);
  g_autofree char *checksum = NULL;
  g_autofree char *current_checksum = NULL;
  gboolean gpg_verify_summary;
  gboolean gpg_verify;
  g_autoptr(OstreeGpgVerifyResult) gpg_result = NULL;
  g_autoptr(GVariant) old_commit = NULL;
  g_autoptr(OstreeRepo) src_repo = NULL;
  g_autoptr(GVariant) new_commit = NULL;
  g_autoptr(GVariant) new_commit_metadata = NULL;
  g_autoptr(GVariant) extra_data_sources = NULL;
  g_autoptr(GPtrArray) subdirs_arg = NULL;
  g_auto(GLnxLockFile) lock = { 0, };
  gboolean ret = FALSE;
  g_autofree const char **ref_bindings = NULL;

  if (!flatpak_dir_ensure_repo (self, cancellable, error))
    return FALSE;

  /* Keep a shared repo lock to avoid prunes removing objects we're relying on
   * while we do the pull. There are two cases we protect against. 1) objects we
   * need but that we already decided are locally available could be removed,
   * and 2) during the transaction commit objects that don't yet have a ref to
   * them could be considered unreachable.
   */
  if (!flatpak_dir_repo_lock (self, &lock, LOCK_SH, cancellable, error))
    return FALSE;

  if (!ostree_repo_remote_get_gpg_verify_summary (self->repo, remote_name,
                                                  &gpg_verify_summary, error))
    return FALSE;

  if (!ostree_repo_remote_get_gpg_verify (self->repo, remote_name,
                                          &gpg_verify, error))
    return FALSE;

  /* This was verified in the client, but lets do it here too */
  if (!gpg_verify_summary || !gpg_verify)
    return flatpak_fail_error (error, FLATPAK_ERROR_UNTRUSTED, _("Can't pull from untrusted non-gpg verified remote"));

  if (!flatpak_repo_resolve_rev (self->repo, NULL, remote_name, ref, TRUE,
                                 &current_checksum, NULL, error))
    return FALSE;

  if (current_checksum != NULL &&
      !ostree_repo_load_commit (self->repo, current_checksum, &old_commit, NULL, error))
    return FALSE;

  src_repo = ostree_repo_new (path_file);
  if (!ostree_repo_open (src_repo, cancellable, error))
    return FALSE;

  if (!flatpak_repo_resolve_rev (src_repo, NULL, remote_name, ref, FALSE, &checksum, NULL, error))
    return FALSE;

  if (gpg_verify)
    {
      gpg_result = ostree_repo_verify_commit_for_remote (src_repo, checksum, remote_name, cancellable, error);
      if (gpg_result == NULL)
        return FALSE;

      if (ostree_gpg_verify_result_count_valid (gpg_result) == 0)
        return flatpak_fail_error (error, FLATPAK_ERROR_UNTRUSTED, _("GPG signatures found, but none are in trusted keyring"));
    }

  g_clear_object (&gpg_result);

  if (!ostree_repo_load_commit (src_repo, checksum, &new_commit, NULL, error))
    return FALSE;

  /* Here we check that there is actually a ref binding, otherwise we
     could allow installing a ref as another app, because both would
     pass gpg validation. Note that ostree pull actually also verifies
     the ref-bindings, but only if they exist. We could do only the
     ref-binding existence check, but if we got something weird might as
     well stop handling it early. */

  new_commit_metadata = g_variant_get_child_value (new_commit, 0);
  if (!g_variant_lookup (new_commit_metadata, OSTREE_COMMIT_META_KEY_REF_BINDING, "^a&s", &ref_bindings))
    return flatpak_fail_error (error, FLATPAK_ERROR_INVALID_DATA, _("Commit for ‘%s’ has no ref binding"),  ref);

  if (!g_strv_contains ((const char *const *) ref_bindings, ref))
    {
      g_autofree char *as_string = g_strjoinv (", ", (char **)ref_bindings);
      return flatpak_fail_error (error, FLATPAK_ERROR_INVALID_DATA, _("Commit for ‘%s’ is not in expected bound refs: %s"),  ref, as_string);
    }

  if (old_commit)
    {
      guint64 old_timestamp;
      guint64 new_timestamp;

      old_timestamp = ostree_commit_get_timestamp (old_commit);
      new_timestamp = ostree_commit_get_timestamp (new_commit);

      if (new_timestamp < old_timestamp)
        return flatpak_fail_error (error, FLATPAK_ERROR_DOWNGRADE, "Not allowed to downgrade %s (old_commit: %s/%" G_GINT64_FORMAT " new_commit: %s/%" G_GINT64_FORMAT ")",
                                   ref, current_checksum, old_timestamp, checksum, new_timestamp);
    }

  if (subpaths != NULL && subpaths[0] != NULL)
    {
      subdirs_arg = g_ptr_array_new_with_free_func (g_free);
      int i;
      g_ptr_array_add (subdirs_arg, g_strdup ("/metadata"));
      for (i = 0; subpaths[i] != NULL; i++)
        g_ptr_array_add (subdirs_arg,
                         g_build_filename ("/files", subpaths[i], NULL));
      g_ptr_array_add (subdirs_arg, NULL);
    }

  if (!ostree_repo_prepare_transaction (self->repo, NULL, cancellable, error))
    goto out;

  /* Past this we must use goto out, so we abort the transaction on error */

  if (!repo_pull_local_untrusted (self, self->repo, remote_name, url,
                                  subdirs_arg ? (const char **) subdirs_arg->pdata : NULL,
                                  ref, checksum, progress,
                                  cancellable, error))
    {
      g_prefix_error (error, _("While pulling %s from remote %s: "), ref, remote_name);
      goto out;
    }

  /* Get the out of bands extra-data required due to an ostree pull
     commitmeta size limit */
  extra_data_sources = flatpak_commit_get_extra_data_sources (new_commit, NULL);
  if (extra_data_sources)
    {
      GFile *dir = ostree_repo_get_path (src_repo);
      g_autoptr(GFile) file = NULL;
      g_autofree char *filename = NULL;
      g_autofree char *commitmeta = NULL;
      gsize commitmeta_size;
      g_autoptr(GVariant) new_metadata = NULL;

      filename = g_strconcat (checksum, ".commitmeta", NULL);
      file = g_file_get_child (dir, filename);
      if (!g_file_load_contents (file, cancellable,
                                 &commitmeta, &commitmeta_size,
                                 NULL, error))
        goto out;

      new_metadata = g_variant_ref_sink (g_variant_new_from_data (G_VARIANT_TYPE ("a{sv}"),
                                                                  commitmeta, commitmeta_size,
                                                                  FALSE,
                                                                  g_free, commitmeta));
      g_steal_pointer (&commitmeta); /* steal into the variant */

      if (!ostree_repo_write_commit_detached_metadata (self->repo, checksum, new_metadata, cancellable, error))
        goto out;
    }

  if (!ostree_repo_commit_transaction (self->repo, NULL, cancellable, error))
    goto out;

  ret = TRUE;

  flatpak_dir_log (self, "pull local", src_path, ref, checksum, current_checksum, NULL,
                   "Pulled %s from %s", ref, src_path);
out:
  if (!ret)
    ostree_repo_abort_transaction (self->repo, cancellable, NULL);

  return ret;
}

FlatpakDecomposed *
flatpak_dir_current_ref (FlatpakDir   *self,
                         const char   *name,
                         GCancellable *cancellable)
{
  g_autoptr(GFile) base = NULL;
  g_autoptr(GFile) dir = NULL;
  g_autoptr(GFile) current_link = NULL;
  g_autoptr(GFileInfo) file_info = NULL;
  FlatpakDecomposed *decomposed;
  char *ref;

  base = g_file_get_child (flatpak_dir_get_path (self), "app");
  dir = g_file_get_child (base, name);

  current_link = g_file_get_child (dir, "current");

  file_info = g_file_query_info (current_link, OSTREE_GIO_FAST_QUERYINFO,
                                 G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
                                 cancellable, NULL);
  if (file_info == NULL)
    return NULL;

  ref = g_strconcat ("app/", name, "/", g_file_info_get_symlink_target (file_info), NULL);
  decomposed = flatpak_decomposed_new_from_ref_take (ref, NULL);
  if (decomposed == NULL)
    g_free (ref);

  return decomposed;
}

gboolean
flatpak_dir_drop_current_ref (FlatpakDir   *self,
                              const char   *name,
                              GCancellable *cancellable,
                              GError      **error)
{
  g_autoptr(GFile) base = NULL;
  g_autoptr(GFile) dir = NULL;
  g_autoptr(GFile) current_link = NULL;
  g_autoptr(GPtrArray) refs = NULL;
  g_autoptr(FlatpakDecomposed) current_ref = NULL;
  FlatpakDecomposed *other_ref = NULL;

  current_ref = flatpak_dir_current_ref (self, name, cancellable);
  if (current_ref)
    {
      refs = flatpak_dir_list_refs_for_name (self, FLATPAK_KINDS_APP, name, cancellable, NULL);
      if (refs)
        {
          for (int i = 0; i < refs->len; i++)
            {
              FlatpakDecomposed *ref = g_ptr_array_index (refs, i);
              if (!flatpak_decomposed_equal (ref, current_ref))
                {
                  other_ref = ref;
                  break;
                }
            }
        }
    }

  base = g_file_get_child (flatpak_dir_get_path (self), "app");
  dir = g_file_get_child (base, name);

  current_link = g_file_get_child (dir, "current");
  if (!g_file_delete (current_link, cancellable, error))
    return FALSE;

  if (other_ref)
    {
      if (!flatpak_dir_make_current_ref (self, other_ref, cancellable, error))
        return FALSE;
    }

  return TRUE;
}

gboolean
flatpak_dir_make_current_ref (FlatpakDir        *self,
                              FlatpakDecomposed *ref,
                              GCancellable      *cancellable,
                              GError           **error)
{
  g_autoptr(GError) local_error = NULL;
  g_autoptr(GFile) base = NULL;
  g_autoptr(GFile) dir = NULL;
  g_autoptr(GFile) current_link = NULL;
  g_autofree char *id = NULL;
  const char *rest;

  if (!flatpak_decomposed_is_app (ref))
    return flatpak_fail (error, _("Only applications can be made current"));

  base = g_file_get_child (flatpak_dir_get_path (self), flatpak_decomposed_get_kind_str (ref));

  id = flatpak_decomposed_dup_id (ref);
  dir = g_file_get_child (base, id);

  current_link = g_file_get_child (dir, "current");

  if (!g_file_delete (current_link, cancellable, &local_error) &&
      !g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
    {
      g_propagate_error (error, g_steal_pointer (&local_error));
      return FALSE;
    }

  rest = flatpak_decomposed_peek_arch (ref, NULL);
  if (!g_file_make_symbolic_link (current_link, rest, cancellable, error))
    return FALSE;

  return TRUE;
}

static gboolean
_flatpak_dir_list_refs_for_name (FlatpakDir   *self,
                                 GFile        *base_dir,
                                 FlatpakKinds kind,
                                 const char   *name,
                                 GPtrArray    *refs,
                                 GCancellable *cancellable,
                                 GError      **error)
{
  g_autoptr(GFile) dir = NULL;
  g_autoptr(GFileEnumerator) dir_enum = NULL;
  g_autoptr(GFileInfo) child_info = NULL;
  GError *temp_error = NULL;

  g_assert (kind == FLATPAK_KINDS_RUNTIME || kind == FLATPAK_KINDS_APP);

  dir = g_file_get_child (base_dir, name);

  if (!g_file_query_exists (dir, cancellable))
    return TRUE;

  dir_enum = g_file_enumerate_children (dir, OSTREE_GIO_FAST_QUERYINFO,
                                        G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
                                        cancellable, error);
  if (!dir_enum)
    return FALSE;

  while ((child_info = g_file_enumerator_next_file (dir_enum, cancellable, &temp_error)))
    {
      g_autoptr(GFile) child = NULL;
      g_autoptr(GFileEnumerator) dir_enum2 = NULL;
      g_autoptr(GFileInfo) child_info2 = NULL;
      const char *arch;

      arch = g_file_info_get_name (child_info);

      if (g_file_info_get_file_type (child_info) != G_FILE_TYPE_DIRECTORY ||
          strcmp (arch, "data") == 0 /* There used to be a data dir here, lets ignore it */)
        {
          g_clear_object (&child_info);
          continue;
        }

      child = g_file_get_child (dir, arch);
      g_clear_object (&dir_enum2);
      dir_enum2 = g_file_enumerate_children (child, OSTREE_GIO_FAST_QUERYINFO,
                                             G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
                                             cancellable, error);
      if (!dir_enum2)
        return FALSE;

      while ((child_info2 = g_file_enumerator_next_file (dir_enum2, cancellable, &temp_error)))
        {
          const char *branch = g_file_info_get_name (child_info2);

          if (g_file_info_get_file_type (child_info2) == G_FILE_TYPE_DIRECTORY)
            {
              g_autoptr(GFile) deploy = flatpak_build_file (child, branch, "active/deploy", NULL);

              if (g_file_query_exists (deploy, NULL))
                {
                  FlatpakDecomposed *ref = flatpak_decomposed_new_from_parts (kind, name, arch, branch, NULL);
                  if (ref)
                    g_ptr_array_add (refs, ref);
                }
            }

          g_clear_object (&child_info2);
        }

      if (temp_error != NULL)
        {
          g_propagate_error (error, temp_error);
          return FALSE;
        }

      g_clear_object (&child_info);
    }

  if (temp_error != NULL)
    {
      g_propagate_error (error, temp_error);
      return FALSE;
    }

  return TRUE;
}

GPtrArray *
flatpak_dir_list_refs_for_name (FlatpakDir   *self,
                                FlatpakKinds kinds,
                                const char   *name,
                                GCancellable *cancellable,
                                GError      **error)
{
  g_autoptr(GPtrArray) refs = NULL;

  refs = g_ptr_array_new_with_free_func ((GDestroyNotify)flatpak_decomposed_unref);

  if ((kinds & FLATPAK_KINDS_APP) != 0)
    {
      g_autoptr(GFile) base = g_file_get_child (flatpak_dir_get_path (self), "app");

      if (!_flatpak_dir_list_refs_for_name (self, base, FLATPAK_KINDS_APP, name, refs, cancellable, error))
        return NULL;
    }

  if ((kinds & FLATPAK_KINDS_RUNTIME) != 0)
    {
      g_autoptr(GFile) base = g_file_get_child (flatpak_dir_get_path (self), "runtime");

      if (!_flatpak_dir_list_refs_for_name (self, base, FLATPAK_KINDS_RUNTIME, name, refs, cancellable, error))
        return NULL;
    }

  g_ptr_array_sort (refs, (GCompareFunc)flatpak_decomposed_strcmp_p);

  return g_steal_pointer (&refs);
}

GPtrArray *
flatpak_dir_list_refs (FlatpakDir   *self,
                       FlatpakKinds kinds,
                       GCancellable *cancellable,
                       GError      **error)
{
  g_autoptr(GPtrArray) refs = NULL;

  refs = g_ptr_array_new_with_free_func ((GDestroyNotify)flatpak_decomposed_unref);

  if (kinds & FLATPAK_KINDS_APP)
    {
      g_autoptr(GFile) base = NULL;
      g_autoptr(GFileEnumerator) dir_enum = NULL;
      g_autoptr(GFileInfo) child_info = NULL;
      GError *temp_error = NULL;

      base = g_file_get_child (flatpak_dir_get_path (self), "app");

      if (g_file_query_exists (base, cancellable))
        {
          dir_enum = g_file_enumerate_children (base, OSTREE_GIO_FAST_QUERYINFO,
                                                G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
                                                cancellable, error);
          if (!dir_enum)
            return NULL;

          while ((child_info = g_file_enumerator_next_file (dir_enum, cancellable, &temp_error)))
            {
              const char *name = g_file_info_get_name (child_info);

              if (g_file_info_get_file_type (child_info) != G_FILE_TYPE_DIRECTORY)
                {
                  g_clear_object (&child_info);
                  continue;
                }

              if (!_flatpak_dir_list_refs_for_name (self, base, FLATPAK_KINDS_APP, name, refs, cancellable, error))
                return NULL;

              g_clear_object (&child_info);
            }

          if (temp_error != NULL)
            {
              g_propagate_error (error, temp_error);
              return NULL;
            }
        }
    }

  if (kinds & FLATPAK_KINDS_RUNTIME)
    {
      g_autoptr(GFile) base = NULL;
      g_autoptr(GFileEnumerator) dir_enum = NULL;
      g_autoptr(GFileInfo) child_info = NULL;
      GError *temp_error = NULL;

      base = g_file_get_child (flatpak_dir_get_path (self), "runtime");

      if (g_file_query_exists (base, cancellable))
        {
          dir_enum = g_file_enumerate_children (base, OSTREE_GIO_FAST_QUERYINFO,
                                                G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
                                                cancellable, error);
          if (!dir_enum)
            return NULL;

          while ((child_info = g_file_enumerator_next_file (dir_enum, cancellable, &temp_error)))
            {
              const char *name = g_file_info_get_name (child_info);

              if (g_file_info_get_file_type (child_info) != G_FILE_TYPE_DIRECTORY)
                {
                  g_clear_object (&child_info);
                  continue;
                }

              if (!_flatpak_dir_list_refs_for_name (self, base, FLATPAK_KINDS_RUNTIME, name, refs, cancellable, error))
                return NULL;

              g_clear_object (&child_info);
            }

          if (temp_error != NULL)
            {
              g_propagate_error (error, temp_error);
              return NULL;
            }
        }
    }

  g_ptr_array_sort (refs, (GCompareFunc)flatpak_decomposed_strcmp_p);

  return g_steal_pointer (&refs);
}

gboolean
flatpak_dir_is_runtime_extension (FlatpakDir        *self,
                                  FlatpakDecomposed *ref)
{
  g_autoptr(GBytes) ext_deploy_data = NULL;

  if (!flatpak_decomposed_is_runtime (ref))
    return FALSE;

  /* deploy v4 guarantees extension-of info */
  ext_deploy_data = flatpak_dir_get_deploy_data (self, ref, 4, NULL, NULL);
  if (ext_deploy_data && flatpak_deploy_data_get_extension_of (ext_deploy_data) != NULL)
    return TRUE;

  return FALSE;
}

static GHashTable *
flatpak_dir_get_runtime_app_map (FlatpakDir        *self,
                                 GCancellable      *cancellable,
                                 GError           **error)
{
  g_autoptr(GHashTable) runtime_app_map = g_hash_table_new_full ((GHashFunc)flatpak_decomposed_hash,
                                                                 (GEqualFunc)flatpak_decomposed_equal,
                                                                 (GDestroyNotify)flatpak_decomposed_unref,
                                                                 (GDestroyNotify)g_ptr_array_unref);
  g_autoptr(GPtrArray) app_refs = NULL;

  app_refs = flatpak_dir_list_refs (self, FLATPAK_KINDS_APP, cancellable, error);
  if (app_refs == NULL)
    return NULL;

  for (guint i = 0; i < app_refs->len; i++)
    {
      FlatpakDecomposed *app_ref = g_ptr_array_index (app_refs, i);
      /* deploy v4 guarantees runtime info */
      g_autoptr(GBytes) app_deploy_data = flatpak_dir_get_deploy_data (self, app_ref, 4, NULL, NULL);
      g_autoptr(FlatpakDecomposed) runtime_decomposed = NULL;
      g_autoptr(GPtrArray) runtime_apps = NULL;
      const char *runtime_pref;

      if (app_deploy_data == NULL)
        continue;

      runtime_pref = flatpak_deploy_data_get_runtime (app_deploy_data);
      runtime_decomposed = flatpak_decomposed_new_from_pref (FLATPAK_KINDS_RUNTIME, runtime_pref, error);
      if (runtime_decomposed == NULL)
        return NULL;

      runtime_apps = g_hash_table_lookup (runtime_app_map, runtime_decomposed);
      if (runtime_apps == NULL)
        {
          runtime_apps = g_ptr_array_new_with_free_func ((GDestroyNotify)flatpak_decomposed_unref);
          g_hash_table_insert (runtime_app_map, flatpak_decomposed_ref (runtime_decomposed), g_ptr_array_ref (runtime_apps));
        }
      else
        g_ptr_array_ref (runtime_apps);

      g_ptr_array_add (runtime_apps, flatpak_decomposed_ref (app_ref));
    }

  return g_steal_pointer (&runtime_app_map);
}

GPtrArray *
flatpak_dir_list_app_refs_with_runtime (FlatpakDir         *self,
                                        GHashTable        **runtime_app_map,
                                        FlatpakDecomposed  *runtime_ref,
                                        GCancellable       *cancellable,
                                        GError            **error)
{
  GPtrArray *apps;

  g_assert (runtime_app_map != NULL);

  if (*runtime_app_map == NULL)
    *runtime_app_map = flatpak_dir_get_runtime_app_map (self, cancellable, error);

  if (*runtime_app_map == NULL)
    return NULL;

  apps = g_hash_table_lookup (*runtime_app_map, runtime_ref);
  if (apps == NULL) /* unused runtime */
    return g_ptr_array_new_with_free_func ((GDestroyNotify)flatpak_decomposed_unref);

  return g_ptr_array_ref (apps);
}

static GHashTable *
flatpak_dir_get_extension_app_map (FlatpakDir    *self,
                                   GHashTable    *runtime_app_map,
                                   GCancellable  *cancellable,
                                   GError       **error)
{
  g_autoptr(GHashTable) extension_app_map = g_hash_table_new_full ((GHashFunc)flatpak_decomposed_hash,
                                                                   (GEqualFunc)flatpak_decomposed_equal,
                                                                   (GDestroyNotify)flatpak_decomposed_unref,
                                                                   (GDestroyNotify)g_ptr_array_unref);
  g_autoptr(GPtrArray) all_refs = NULL;

  g_assert (runtime_app_map != NULL);

  all_refs = flatpak_dir_list_refs (self, FLATPAK_KINDS_RUNTIME | FLATPAK_KINDS_APP, NULL, NULL);
  for (guint i = 0; all_refs != NULL && i < all_refs->len; i++)
    {
      FlatpakDecomposed *ref = g_ptr_array_index (all_refs, i);
      g_autoptr(GPtrArray) related = NULL;
      GPtrArray *runtime_apps = NULL;

      if (flatpak_decomposed_id_is_subref (ref))
        continue;

      if (flatpak_decomposed_is_runtime (ref))
        {
          runtime_apps = g_hash_table_lookup (runtime_app_map, ref);
          if (runtime_apps == NULL)
            continue;
        }

      related = flatpak_dir_find_local_related (self, ref, NULL, TRUE, cancellable, error);
      if (related == NULL)
        return NULL;

      for (guint j = 0; j < related->len; j++)
        {
          FlatpakRelated *rel = g_ptr_array_index (related, j);
          g_autoptr(GPtrArray) extension_apps = g_hash_table_lookup (extension_app_map, rel->ref);
          if (extension_apps == NULL)
            {
              extension_apps = g_ptr_array_new_with_free_func ((GDestroyNotify)flatpak_decomposed_unref);
              g_hash_table_insert (extension_app_map, flatpak_decomposed_ref (rel->ref), g_ptr_array_ref (extension_apps));
            }
          else
            g_ptr_array_ref (extension_apps);

          if (flatpak_decomposed_is_runtime (ref))
            {
              g_assert (runtime_apps);
              for (guint k = 0; runtime_apps && k < runtime_apps->len; k++)
                g_ptr_array_add (extension_apps, flatpak_decomposed_ref (g_ptr_array_index (runtime_apps, k)));
            }
          else
            g_ptr_array_add (extension_apps, flatpak_decomposed_ref (ref));
        }
    }

  return g_steal_pointer (&extension_app_map);
}

GPtrArray *
flatpak_dir_list_app_refs_with_runtime_extension (FlatpakDir        *self,
                                                  GHashTable        **runtime_app_map,
                                                  GHashTable        **extension_app_map,
                                                  FlatpakDecomposed  *runtime_ext_ref,
                                                  GCancellable       *cancellable,
                                                  GError            **error)
{
  GPtrArray *apps;

  g_assert (runtime_app_map != NULL);
  g_assert (extension_app_map != NULL);

  if (*runtime_app_map == NULL)
    *runtime_app_map = flatpak_dir_get_runtime_app_map (self, cancellable, error);

  if (*runtime_app_map == NULL)
    return NULL;

  if (*extension_app_map == NULL)
    *extension_app_map = flatpak_dir_get_extension_app_map (self, *runtime_app_map, cancellable, error);

  if (*extension_app_map == NULL)
    return NULL;

  apps = g_hash_table_lookup (*extension_app_map, runtime_ext_ref);
  if (apps == NULL) /* unused extension */
    return g_ptr_array_new_with_free_func ((GDestroyNotify)flatpak_decomposed_unref);

  return g_ptr_array_ref (apps);
}

GVariant *
flatpak_dir_read_latest_commit (FlatpakDir        *self,
                                const char        *remote,
                                FlatpakDecomposed *ref,
                                char             **out_checksum,
                                GCancellable      *cancellable,
                                GError           **error)
{
  g_autofree char *res = NULL;
  g_autoptr(GVariant) commit_data = NULL;

  if (!flatpak_repo_resolve_rev (self->repo, NULL, remote, flatpak_decomposed_get_ref (ref), FALSE,
                                 &res, cancellable, error))
    return NULL;

  if (!ostree_repo_load_commit (self->repo, res, &commit_data, NULL, error))
    return NULL;

  if (out_checksum)
    *out_checksum = g_steal_pointer (&res);

  return g_steal_pointer (&commit_data);
}


char *
flatpak_dir_read_latest (FlatpakDir   *self,
                         const char   *remote,
                         const char   *ref,
                         char        **out_alt_id,
                         GCancellable *cancellable,
                         GError      **error)
{
  g_autofree char *alt_id = NULL;
  g_autofree char *res = NULL;

  if (!flatpak_repo_resolve_rev (self->repo, NULL, remote, ref, FALSE,
                                 &res, cancellable, error))
    return NULL;

  if (out_alt_id)
    {
      g_autoptr(GVariant) commit_data = NULL;
      g_autoptr(GVariant) commit_metadata = NULL;

      if (!ostree_repo_load_commit (self->repo, res, &commit_data, NULL, error))
        return NULL;

      commit_metadata = g_variant_get_child_value (commit_data, 0);
      g_variant_lookup (commit_metadata, "xa.alt-id", "s", &alt_id);

      *out_alt_id = g_steal_pointer (&alt_id);
    }

  return g_steal_pointer (&res);
}

char *
flatpak_dir_read_active (FlatpakDir        *self,
                         FlatpakDecomposed *ref,
                         GCancellable      *cancellable)
{
  g_autoptr(GFile) deploy_base = NULL;
  g_autoptr(GFile) active_link = NULL;
  g_autoptr(GFileInfo) file_info = NULL;

  deploy_base = flatpak_dir_get_deploy_dir (self, ref);
  active_link = g_file_get_child (deploy_base, "active");

  file_info = g_file_query_info (active_link, OSTREE_GIO_FAST_QUERYINFO,
                                 G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
                                 cancellable, NULL);
  if (file_info == NULL)
    return NULL;

  return g_strdup (g_file_info_get_symlink_target (file_info));
}

gboolean
flatpak_dir_set_active (FlatpakDir        *self,
                        FlatpakDecomposed *ref,
                        const char        *active_id,
                        GCancellable      *cancellable,
                        GError           **error)
{
  gboolean ret = FALSE;
  g_autoptr(GFile) deploy_base = NULL;
  g_autoptr(GFile) active_tmp_link = NULL;
  g_autoptr(GFile) active_link = NULL;
  g_autoptr(GError) my_error = NULL;
  g_autofree char *tmpname = g_strdup (".active-XXXXXX");

  deploy_base = flatpak_dir_get_deploy_dir (self, ref);
  active_link = g_file_get_child (deploy_base, "active");

  if (active_id != NULL)
    {
      glnx_gen_temp_name (tmpname);
      active_tmp_link = g_file_get_child (deploy_base, tmpname);
      if (!g_file_make_symbolic_link (active_tmp_link, active_id, cancellable, error))
        goto out;

      if (!flatpak_file_rename (active_tmp_link,
                                active_link,
                                cancellable, error))
        goto out;
    }
  else
    {
      if (!g_file_delete (active_link, cancellable, &my_error) &&
          !g_error_matches (my_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
        {
          g_propagate_error (error, my_error);
          my_error = NULL;
          goto out;
        }
    }

  ret = TRUE;
out:
  return ret;
}

static void
maybe_reload_dbus_config (GCancellable *cancellable)
{
  g_autoptr(GDBusConnection) session_bus = NULL;
  g_autoptr(GVariant) ret = NULL;

  session_bus = g_bus_get_sync (G_BUS_TYPE_SESSION, cancellable, NULL);
  if (!session_bus)
    return;

  ret = g_dbus_connection_call_sync (session_bus,
                                     "org.freedesktop.DBus",
                                     "/org/freedesktop/DBus",
                                     "org.freedesktop.DBus",
                                     "ReloadConfig",
                                     NULL,
                                     NULL,
                                     G_DBUS_CALL_FLAGS_NONE,
                                     2000,
                                     cancellable,
                                     NULL);
}

gboolean
flatpak_dir_run_triggers (FlatpakDir   *self,
                          GCancellable *cancellable,
                          GError      **error)
{
  gboolean ret = FALSE;
  g_autoptr(GFileEnumerator) dir_enum = NULL;
  g_autoptr(GFileInfo) child_info = NULL;
  g_autoptr(GFile) triggersdir = NULL;
  GError *temp_error = NULL;
  g_autofree char *triggerspath = NULL;

  maybe_reload_dbus_config (cancellable);

  if (flatpak_dir_use_system_helper (self, NULL))
    {
      const char *installation = flatpak_dir_get_id (self);

      if (!flatpak_dir_system_helper_call_run_triggers (self,
                                                        FLATPAK_HELPER_RUN_TRIGGERS_FLAGS_NONE,
                                                        installation ? installation : "",
                                                        cancellable,
                                                        error))
        return FALSE;

      return TRUE;
    }

  triggerspath = g_strdup (g_getenv ("FLATPAK_TRIGGERSDIR"));
  if (triggerspath == NULL)
    triggerspath = g_build_filename (get_data_dir_location (), FLATPAK_TRIGGERS_DIR, NULL);

  g_info ("running triggers from %s", triggerspath);

  triggersdir = g_file_new_for_path (triggerspath);

  dir_enum = g_file_enumerate_children (triggersdir, "standard::type,standard::name",
                                        0, cancellable, error);
  if (!dir_enum)
    goto out;

  while ((child_info = g_file_enumerator_next_file (dir_enum, cancellable, &temp_error)) != NULL)
    {
      g_autoptr(GFile) child = NULL;
      const char *name;
      GError *trigger_error = NULL;

      name = g_file_info_get_name (child_info);

      child = g_file_get_child (triggersdir, name);

      if (g_file_info_get_file_type (child_info) == G_FILE_TYPE_REGULAR &&
          g_str_has_suffix (name, ".trigger"))
        {
          /* We need to canonicalize the basedir, because if has a symlink
             somewhere the bind mount will be on the target of that, not
             at that exact path. */
          g_autofree char *basedir_orig = g_file_get_path (self->basedir);
          g_autofree char *basedir = realpath (basedir_orig, NULL);
          g_autoptr(FlatpakBwrap) bwrap = NULL;
          g_autofree char *commandline = NULL;

          g_info ("running trigger %s", name);

          bwrap = flatpak_bwrap_new (NULL);

#ifndef DISABLE_SANDBOXED_TRIGGERS
          flatpak_bwrap_add_arg (bwrap, flatpak_get_bwrap ());
          flatpak_bwrap_add_args (bwrap,
                                  "--unshare-ipc",
                                  "--unshare-net",
                                  "--unshare-pid",
                                  "--ro-bind", "/", "/",
                                  "--proc", "/proc",
                                  "--dev", "/dev",
                                  "--bind", basedir, basedir,
                                  "--",
                                  NULL);
#endif
          flatpak_bwrap_add_args (bwrap,
                                  flatpak_file_get_path_cached (child),
                                  basedir,
                                  NULL);
          flatpak_bwrap_finish (bwrap);

          commandline = flatpak_quote_argv ((const char **) bwrap->argv->pdata, -1);
          g_info ("Running '%s'", commandline);

          /* We use LEAVE_DESCRIPTORS_OPEN and close them in the child_setup
           * to work around a deadlock in GLib < 2.60 */
          if (!g_spawn_sync ("/",
                             (char **) bwrap->argv->pdata,
                             NULL,
                             G_SPAWN_SEARCH_PATH | G_SPAWN_LEAVE_DESCRIPTORS_OPEN,
                             flatpak_bwrap_child_setup_cb, bwrap->fds,
                             NULL, NULL,
                             NULL, &trigger_error))
            {
              g_warning ("Error running trigger %s: %s", name, trigger_error->message);
              g_clear_error (&trigger_error);
            }
        }

      g_clear_object (&child_info);
    }

  if (temp_error != NULL)
    {
      g_propagate_error (error, temp_error);
      goto out;
    }

  ret = TRUE;
out:
  return ret;
}

static gboolean
read_fd (int          fd,
         struct stat *stat_buf,
         gchar      **contents,
         gsize       *length,
         GError     **error)
{
  gchar *buf;
  gsize bytes_read;
  gsize size;
  gsize alloc_size;

  size = stat_buf->st_size;

  alloc_size = size + 1;
  buf = g_try_malloc (alloc_size);

  if (buf == NULL)
    {
      g_set_error_literal (error, G_FILE_ERROR, G_FILE_ERROR_NOMEM,
                           _("Not enough memory"));
      return FALSE;
    }

  bytes_read = 0;
  while (bytes_read < size)
    {
      gssize rc;

      rc = read (fd, buf + bytes_read, size - bytes_read);

      if (rc < 0)
        {
          if (errno != EINTR)
            {
              int save_errno = errno;

              g_free (buf);
              g_set_error_literal (error, G_FILE_ERROR, g_file_error_from_errno (save_errno),
                                   _("Failed to read from exported file"));
              return FALSE;
            }
        }
      else if (rc == 0)
        {
          break;
        }
      else
        {
          bytes_read += rc;
        }
    }

  buf[bytes_read] = '\0';

  if (length)
    *length = bytes_read;

  *contents = buf;

  return TRUE;
}

/* This is conservative, but lets us avoid escaping most
   regular Exec= lines, which is nice as that can sometimes
   cause problems for apps launching desktop files. */
static gboolean
need_quotes (const char *str)
{
  const char *p;

  for (p = str; *p; p++)
    {
      if (!g_ascii_isalnum (*p) &&
          strchr ("-_%.=:/@", *p) == NULL)
        return TRUE;
    }

  return FALSE;
}

static char *
maybe_quote (const char *str)
{
  if (need_quotes (str))
    return g_shell_quote (str);
  return g_strdup (str);
}

typedef enum {
  INI_FILE_TYPE_SEARCH_PROVIDER = 1,
} ExportedIniFileType;

static gboolean
export_ini_file (int                 parent_fd,
                 const char         *name,
                 ExportedIniFileType ini_type,
                 struct stat        *stat_buf,
                 char              **target,
                 GCancellable       *cancellable,
                 GError            **error)
{
  glnx_autofd int desktop_fd = -1;
  g_autofree char *tmpfile_name = g_strdup_printf ("export-ini-XXXXXX");
  g_autoptr(GOutputStream) out_stream = NULL;
  g_autofree gchar *data = NULL;
  gsize data_len;
  g_autofree gchar *new_data = NULL;
  gsize new_data_len;
  g_autoptr(GKeyFile) keyfile = NULL;

  if (!flatpak_openat_noatime (parent_fd, name, &desktop_fd, cancellable, error) ||
      !read_fd (desktop_fd, stat_buf, &data, &data_len, error))
    return FALSE;

  keyfile = g_key_file_new ();
  if (!g_key_file_load_from_data (keyfile, data, data_len, G_KEY_FILE_KEEP_TRANSLATIONS, error))
    return FALSE;

  if (ini_type == INI_FILE_TYPE_SEARCH_PROVIDER)
    g_key_file_set_boolean (keyfile, "Shell Search Provider", "DefaultDisabled", TRUE);

  new_data = g_key_file_to_data (keyfile, &new_data_len, error);
  if (new_data == NULL)
    return FALSE;

  if (!flatpak_open_in_tmpdir_at (parent_fd, 0755, tmpfile_name, &out_stream, cancellable, error) ||
      !g_output_stream_write_all (out_stream, new_data, new_data_len, NULL, cancellable, error) ||
      !g_output_stream_close (out_stream, cancellable, error))
    return FALSE;

  if (target)
    *target = g_steal_pointer (&tmpfile_name);

  return TRUE;
}

static inline void
xml_autoptr_cleanup_generic_free (void *p)
{
  void **pp = (void **) p;

  if (*pp)
    xmlFree (*pp);
}


#define xml_autofree _GLIB_CLEANUP (xml_autoptr_cleanup_generic_free)

/* This verifies the basic layout of the files, then it removes
 * any magic matches, and makes all glob matches have a very low
 * priority (weight = 5). This should make it pretty safe to
 * export mime types, because the should not override the system
 * ones in any weird ways. */
static gboolean
rewrite_mime_xml (xmlDoc *doc)
{
  xmlNode *root_element = xmlDocGetRootElement (doc);
  xmlNode *top_node = NULL;

  for (top_node = root_element; top_node; top_node = top_node->next)
    {
      xmlNode *mime_node = NULL;
      if (top_node->type != XML_ELEMENT_NODE)
        continue;

      if (strcmp ((char *) top_node->name, "mime-info") != 0)
        return FALSE;

      for (mime_node = top_node->children; mime_node; mime_node = mime_node->next)
        {
          xmlNode *sub_node = NULL;
          xmlNode *next_sub_node = NULL;

          if (mime_node->type != XML_ELEMENT_NODE)
            continue;

          if (strcmp ((char *) mime_node->name, "mime-type") != 0)
            return FALSE;

          for (sub_node = mime_node->children; sub_node; sub_node = next_sub_node)
            {
              next_sub_node = sub_node->next;

              if (sub_node->type != XML_ELEMENT_NODE)
                continue;

              if (strcmp ((char *) sub_node->name, "magic") == 0)
                {
                  g_warning ("Removing magic mime rule from exports");
                  xmlUnlinkNode (sub_node);
                  xmlFreeNode (sub_node);
                }
              else if (strcmp ((char *) sub_node->name, "glob") == 0)
                {
                  xmlSetProp (sub_node,
                              (const xmlChar *) "weight",
                              (const xmlChar *) "5");
                }
            }
        }
    }

  return TRUE;
}

static gboolean
export_mime_file (int           parent_fd,
                  const char   *name,
                  struct stat  *stat_buf,
                  char        **target,
                  GCancellable *cancellable,
                  GError      **error)
{
  glnx_autofd int desktop_fd = -1;
  g_autofree char *tmpfile_name = g_strdup_printf ("export-mime-XXXXXX");
  g_autoptr(GOutputStream) out_stream = NULL;
  g_autofree gchar *data = NULL;
  gsize data_len;
  xmlDoc *doc = NULL;
  xml_autofree xmlChar *xmlbuff = NULL;
  int buffersize;

  if (!flatpak_openat_noatime (parent_fd, name, &desktop_fd, cancellable, error) ||
      !read_fd (desktop_fd, stat_buf, &data, &data_len, error))
    return FALSE;

  doc = xmlReadMemory (data, data_len, NULL, NULL,  0);
  if (doc == NULL)
    return flatpak_fail_error (error, FLATPAK_ERROR_EXPORT_FAILED, _("Error reading mimetype xml file"));

  if (!rewrite_mime_xml (doc))
    {
      xmlFreeDoc (doc);
      return flatpak_fail_error (error, FLATPAK_ERROR_EXPORT_FAILED, _("Invalid mimetype xml file"));
    }

  xmlDocDumpFormatMemory (doc, &xmlbuff, &buffersize, 1);
  xmlFreeDoc (doc);

  if (!flatpak_open_in_tmpdir_at (parent_fd, 0755, tmpfile_name, &out_stream, cancellable, error) ||
      !g_output_stream_write_all (out_stream, xmlbuff, buffersize, NULL, cancellable, error) ||
      !g_output_stream_close (out_stream, cancellable, error))
    return FALSE;

  if (target)
    *target = g_steal_pointer (&tmpfile_name);

  return TRUE;
}

static char *
format_flatpak_run_args_from_run_opts (GStrv flatpak_run_args)
{
  GString *str;
  GStrv iter = flatpak_run_args;

  if (flatpak_run_args == NULL)
    return NULL;

  str = g_string_new ("");
  for (; *iter != NULL; ++iter)
    {
      if (g_strcmp0 (*iter, "no-a11y-bus") == 0)
        g_string_append_printf (str, " --no-a11y-bus");
      else if (g_strcmp0 (*iter, "no-documents-portal") == 0)
        g_string_append_printf (str, " --no-documents-portal");
    }

  return g_string_free (str, FALSE);
}

static gboolean
export_desktop_file (const char         *app,
                     const char         *branch,
                     const char         *arch,
                     GKeyFile           *metadata,
                     const char * const *previous_ids,
                     int                 parent_fd,
                     const char         *name,
                     struct stat        *stat_buf,
                     char              **target,
                     GCancellable       *cancellable,
                     GError            **error)
{
  glnx_autofd int desktop_fd = -1;
  g_autofree char *tmpfile_name = g_strdup_printf ("export-desktop-XXXXXX");
  g_autoptr(GOutputStream) out_stream = NULL;
  g_autofree gchar *data = NULL;
  gsize data_len;
  g_autofree gchar *new_data = NULL;
  gsize new_data_len;
  g_autoptr(GKeyFile) keyfile = NULL;
  g_auto(GStrv) groups = NULL;
  g_autofree char *escaped_app = maybe_quote (app);
  g_autofree char *escaped_branch = maybe_quote (branch);
  g_autofree char *escaped_arch = maybe_quote (arch);
  int i;
  const char *flatpak;

  if (!flatpak_openat_noatime (parent_fd, name, &desktop_fd, cancellable, error))
    return FALSE;

  if (!read_fd (desktop_fd, stat_buf, &data, &data_len, error))
    return FALSE;

  keyfile = g_key_file_new ();
  if (!g_key_file_load_from_data (keyfile, data, data_len, G_KEY_FILE_KEEP_TRANSLATIONS, error))
    return FALSE;

  if (g_str_has_suffix (name, ".service"))
    {
      g_autofree gchar *dbus_name = NULL;
      g_autofree gchar *expected_dbus_name = g_strndup (name, strlen (name) - strlen (".service"));

      dbus_name = g_key_file_get_string (keyfile, "D-BUS Service", "Name", NULL);

      if (dbus_name == NULL || strcmp (dbus_name, expected_dbus_name) != 0)
        {
          return flatpak_fail_error (error, FLATPAK_ERROR_EXPORT_FAILED,
                                     _("D-Bus service file '%s' has wrong name"), name);
        }
    }

  if (g_str_has_suffix (name, ".desktop"))
    {
      gsize length;
      g_auto(GStrv) tags = g_key_file_get_string_list (metadata,
                                                       "Application",
                                                       "tags", &length,
                                                       NULL);

      if (tags != NULL)
        {
          g_key_file_set_string_list (keyfile,
                                      G_KEY_FILE_DESKTOP_GROUP,
                                      "X-Flatpak-Tags",
                                      (const char * const *) tags, length);
        }

      /* Add a marker so consumers can easily find out that this launches a sandbox */
      g_key_file_set_string (keyfile, G_KEY_FILE_DESKTOP_GROUP, "X-Flatpak", app);

      /* Disable krunner dbusplugins by default, so that flatpak applications cannot
       * unintentionally grab sensitive search data.
       */
      if (g_key_file_get_boolean (keyfile, G_KEY_FILE_DESKTOP_GROUP,
                               "X-KDE-PluginInfo-EnabledByDefault", NULL))
        {
          g_key_file_set_boolean (keyfile, G_KEY_FILE_DESKTOP_GROUP, "X-KDE-PluginInfo-EnabledByDefault", FALSE);
        }

      /* If the app has been renamed, add its old .desktop filename to
       * X-Flatpak-RenamedFrom in the new .desktop file, taking care not to
       * introduce duplicates.
       */
      if (previous_ids != NULL)
        {
          const char *X_FLATPAK_RENAMED_FROM = "X-Flatpak-RenamedFrom";
          g_auto(GStrv) renamed_from = g_key_file_get_string_list (keyfile,
                                                                   G_KEY_FILE_DESKTOP_GROUP,
                                                                   X_FLATPAK_RENAMED_FROM,
                                                                   NULL, NULL);
          g_autoptr(GPtrArray) merged = g_ptr_array_new_with_free_func (g_free);
          g_autoptr(GHashTable) seen = g_hash_table_new (g_str_hash, g_str_equal);
          const char *new_suffix;

          for (i = 0; renamed_from != NULL && renamed_from[i] != NULL; i++)
            {
              if (!g_hash_table_contains (seen, renamed_from[i]))
                {
                  gchar *copy = g_strdup (renamed_from[i]);
                  g_hash_table_insert (seen, copy, copy);
                  g_ptr_array_add (merged, g_steal_pointer (&copy));
                }
            }

          /* If an app was renamed from com.example.Foo to net.example.Bar, and
           * the new version exports net.example.Bar-suffix.desktop, we assume the
           * old version exported com.example.Foo-suffix.desktop.
           *
           * This assertion is true because
           * flatpak_name_matches_one_wildcard_prefix() is called on all
           * exported files before we get here.
           */
          g_assert (g_str_has_prefix (name, app));
          /* ".desktop" for the "main" desktop file; something like
           * "-suffix.desktop" for extra ones.
           */
          new_suffix = name + strlen (app);

          for (i = 0; previous_ids[i] != NULL; i++)
            {
              g_autofree gchar *previous_desktop = g_strconcat (previous_ids[i], new_suffix, NULL);
              if (!g_hash_table_contains (seen, previous_desktop))
                {
                  g_hash_table_insert (seen, previous_desktop, previous_desktop);
                  g_ptr_array_add (merged, g_steal_pointer (&previous_desktop));
                }
            }

          if (merged->len > 0)
            {
              g_ptr_array_add (merged, NULL);
              g_key_file_set_string_list (keyfile,
                                          G_KEY_FILE_DESKTOP_GROUP,
                                          X_FLATPAK_RENAMED_FROM,
                                          (const char * const *) merged->pdata,
                                          merged->len - 1);
            }
        }
    }

  groups = g_key_file_get_groups (keyfile, NULL);

  for (i = 0; groups[i] != NULL; i++)
    {
      gint old_argc;
      g_auto(GStrv) old_argv = NULL;
      g_autofree gchar *old_exec = NULL;
      g_autoptr(GString) new_exec = NULL;
      g_auto(GStrv) flatpak_run_opts = g_key_file_get_string_list (keyfile, groups[i], "X-Flatpak-RunOptions", NULL, NULL);
      g_autofree char *flatpak_run_args = format_flatpak_run_args_from_run_opts (flatpak_run_opts);

      g_key_file_remove_key (keyfile, groups[i], "X-Flatpak-RunOptions", NULL);
      g_key_file_remove_key (keyfile, groups[i], "TryExec", NULL);

      /* Remove this to make sure nothing tries to execute it outside the sandbox*/
      g_key_file_remove_key (keyfile, groups[i], "X-GNOME-Bugzilla-ExtraInfoScript", NULL);

      new_exec = g_string_new ("");
      if ((flatpak = g_getenv ("FLATPAK_BINARY")) == NULL)
        flatpak = FLATPAK_BINDIR "/flatpak";

      g_string_append_printf (new_exec,
                              "%s run --branch=%s --arch=%s",
                              flatpak,
                              escaped_branch,
                              escaped_arch);

      if (flatpak_run_args != NULL)
        g_string_append_printf (new_exec, "%s", flatpak_run_args);

      old_exec = g_key_file_get_string (keyfile, groups[i], "Exec", NULL);
      if (old_exec && g_shell_parse_argv (old_exec, &old_argc, &old_argv, NULL) && old_argc >= 1)
        {
          int j;
          g_autofree char *command = maybe_quote (old_argv[0]);

          g_string_append_printf (new_exec, " --command=%s", command);

          for (j = 1; j < old_argc; j++)
            {
              if (strcasecmp (old_argv[j], "%f") == 0 ||
                  strcasecmp (old_argv[j], "%u") == 0)
                {
                  g_string_append (new_exec, " --file-forwarding");
                  break;
                }
            }

          g_string_append (new_exec, " ");
          g_string_append (new_exec, escaped_app);

          for (j = 1; j < old_argc; j++)
            {
              g_autofree char *arg = maybe_quote (old_argv[j]);

              if (strcasecmp (arg, "%f") == 0)
                g_string_append_printf (new_exec, " @@ %s @@", arg);
              else if (strcasecmp (arg, "%u") == 0)
                g_string_append_printf (new_exec, " @@u %s @@", arg);
              else if (g_str_has_prefix (arg, "@@"))
                {
                  flatpak_fail_error (error, FLATPAK_ERROR_EXPORT_FAILED,
                                     _("Invalid Exec argument %s"), arg);
                  return FALSE;
                }
              else
                g_string_append_printf (new_exec, " %s", arg);
            }
        }
      else
        {
          g_string_append (new_exec, " ");
          g_string_append (new_exec, escaped_app);
        }

      g_key_file_set_string (keyfile, groups[i], G_KEY_FILE_DESKTOP_KEY_EXEC, new_exec->str);
    }

  new_data = g_key_file_to_data (keyfile, &new_data_len, error);
  if (new_data == NULL)
    return FALSE;

  if (!flatpak_open_in_tmpdir_at (parent_fd, 0755, tmpfile_name, &out_stream, cancellable, error))
    return FALSE;

  if (!g_output_stream_write_all (out_stream, new_data, new_data_len, NULL, cancellable, error))
    return FALSE;

  if (!g_output_stream_close (out_stream, cancellable, error))
    return FALSE;

  if (target)
    *target = g_steal_pointer (&tmpfile_name);

  return TRUE;
}

static gboolean
rewrite_export_dir (const char         *app,
                    const char         *branch,
                    const char         *arch,
                    GKeyFile           *metadata,
                    const char * const *previous_ids,
                    FlatpakContext     *context,
                    int                 source_parent_fd,
                    const char         *source_name,
                    const char         *source_path,
                    GCancellable       *cancellable,
                    GError            **error)
{
  gboolean ret = FALSE;
  g_auto(GLnxDirFdIterator) source_iter = {0};
  g_autoptr(GHashTable) visited_children = NULL;
  struct dirent *dent;
  gboolean exports_allowed = FALSE;
  g_auto(GStrv) allowed_prefixes = NULL;
  g_auto(GStrv) allowed_extensions = NULL;
  gboolean require_exact_match = FALSE;

  if (!glnx_dirfd_iterator_init_at (source_parent_fd, source_name, FALSE, &source_iter, error))
    goto out;

  exports_allowed = flatpak_context_get_allowed_exports (context, source_path, app,
                                                         &allowed_extensions, &allowed_prefixes, &require_exact_match);

  visited_children = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);

  while (TRUE)
    {
      struct stat stbuf;

      if (!glnx_dirfd_iterator_next_dent (&source_iter, &dent, cancellable, error))
        goto out;

      if (dent == NULL)
        break;

      if (g_hash_table_contains (visited_children, dent->d_name))
        continue;

      /* Avoid processing the same file again if it was re-created during an export */
      g_hash_table_insert (visited_children, g_strdup (dent->d_name), GINT_TO_POINTER (1));

      if (fstatat (source_iter.fd, dent->d_name, &stbuf, AT_SYMLINK_NOFOLLOW) == -1)
        {
          if (errno == ENOENT)
            {
              continue;
            }
          else
            {
              glnx_set_error_from_errno (error);
              goto out;
            }
        }

      if (S_ISDIR (stbuf.st_mode))
        {
          g_autofree char *path = g_build_filename (source_path, dent->d_name, NULL);

          if (!rewrite_export_dir (app, branch, arch, metadata, previous_ids, context,
                                   source_iter.fd, dent->d_name,
                                   path, cancellable, error))
            goto out;
        }
      else if (S_ISREG (stbuf.st_mode) && exports_allowed)
        {
          g_autofree gchar *name_without_extension = NULL;
          g_autofree gchar *new_name = NULL;
          int i;

          for (i = 0; allowed_extensions[i] != NULL; i++)
            {
              if (g_str_has_suffix (dent->d_name, allowed_extensions[i]))
                break;
            }

          if (allowed_extensions[i] == NULL)
            {
              g_warning ("Invalid extension for %s in app %s, removing.", dent->d_name, app);
              if (unlinkat (source_iter.fd, dent->d_name, 0) != 0 && errno != ENOENT)
                {
                  glnx_set_error_from_errno (error);
                  goto out;
                }
              continue;
            }

          name_without_extension = g_strndup (dent->d_name, strlen (dent->d_name) - strlen (allowed_extensions[i]));

          if (!flatpak_name_matches_one_wildcard_prefix (name_without_extension, (const char * const *) allowed_prefixes, require_exact_match))
            {
              g_warning ("Non-prefixed filename %s in app %s, removing.", dent->d_name, app);
              if (unlinkat (source_iter.fd, dent->d_name, 0) != 0 && errno != ENOENT)
                {
                  glnx_set_error_from_errno (error);
                  goto out;
                }
            }

          if (g_str_has_suffix (dent->d_name, ".desktop") ||
              g_str_has_suffix (dent->d_name, ".service"))
            {
              if (!export_desktop_file (app, branch, arch, metadata, previous_ids,
                                        source_iter.fd, dent->d_name, &stbuf, &new_name, cancellable, error))
                goto out;
            }

          if (strcmp (source_name, "search-providers") == 0 &&
              g_str_has_suffix (dent->d_name, ".ini"))
            {
              if (!export_ini_file (source_iter.fd, dent->d_name, INI_FILE_TYPE_SEARCH_PROVIDER,
                                    &stbuf, &new_name, cancellable, error))
                goto out;
            }

          if (strcmp (source_name, "packages") == 0 &&
              g_str_has_suffix (dent->d_name, ".xml"))
            {
              if (!export_mime_file (source_iter.fd, dent->d_name,
                                     &stbuf, &new_name, cancellable, error))
                goto out;
            }

          if (new_name)
            {
              g_hash_table_insert (visited_children, g_strdup (new_name), GINT_TO_POINTER (1));

              if (renameat (source_iter.fd, new_name, source_iter.fd, dent->d_name) != 0)
                {
                  glnx_set_error_from_errno (error);
                  goto out;
                }
            }
        }
      else
        {
          g_warning ("Not exporting file %s of unsupported type.", dent->d_name);
          if (unlinkat (source_iter.fd, dent->d_name, 0) != 0 && errno != ENOENT)
            {
              glnx_set_error_from_errno (error);
              goto out;
            }
        }
    }

  ret = TRUE;
out:

  return ret;
}

static gboolean
flatpak_rewrite_export_dir (const char         *app,
                            const char         *branch,
                            const char         *arch,
                            GKeyFile           *metadata,
                            const char * const *previous_ids,
                            GFile              *source,
                            GCancellable       *cancellable,
                            GError            **error)
{
  gboolean ret = FALSE;
  g_autoptr(GFile) parent = g_file_get_parent (source);
  glnx_autofd int parentfd = -1;
  g_autofree char *name = g_file_get_basename (source);

  /* Start with a source path of "" - we don't care about
   * the "export" component and we want to start path traversal
   * relative to it. */
  const char *source_path = "";
  g_autoptr(FlatpakContext) context = flatpak_context_new ();

  if (!flatpak_context_load_metadata (context, metadata, error))
    return FALSE;

  if (!glnx_opendirat (AT_FDCWD,
                       flatpak_file_get_path_cached (parent),
                       TRUE,
                       &parentfd,
                       error))
    return FALSE;

  /* The fds are closed by this call */
  if (!rewrite_export_dir (app, branch, arch, metadata, previous_ids, context,
                           parentfd, name, source_path,
                           cancellable, error))
    goto out;

  ret = TRUE;

out:
  return ret;
}


static gboolean
export_dir (int           source_parent_fd,
            const char   *source_name,
            const char   *source_symlink_prefix,
            const char   *source_relpath,
            int           destination_parent_fd,
            const char   *destination_name,
            GCancellable *cancellable,
            GError      **error)
{
  gboolean ret = FALSE;
  int res;
  g_auto(GLnxDirFdIterator) source_iter = {0};
  glnx_autofd int destination_dfd = -1;
  struct dirent *dent;

  if (!glnx_dirfd_iterator_init_at (source_parent_fd, source_name, FALSE, &source_iter, error))
    goto out;

  do
    res = mkdirat (destination_parent_fd, destination_name, 0755);
  while (G_UNLIKELY (res == -1 && errno == EINTR));
  if (res == -1)
    {
      if (errno != EEXIST)
        {
          glnx_set_error_from_errno (error);
          goto out;
        }
    }

  if (!glnx_opendirat (destination_parent_fd, destination_name, TRUE,
                       &destination_dfd, error))
    goto out;

  while (TRUE)
    {
      struct stat stbuf;

      if (!glnx_dirfd_iterator_next_dent (&source_iter, &dent, cancellable, error))
        goto out;

      if (dent == NULL)
        break;

      if (fstatat (source_iter.fd, dent->d_name, &stbuf, AT_SYMLINK_NOFOLLOW) == -1)
        {
          if (errno == ENOENT)
            {
              continue;
            }
          else
            {
              glnx_set_error_from_errno (error);
              goto out;
            }
        }

      if (S_ISDIR (stbuf.st_mode))
        {
          g_autofree gchar *child_symlink_prefix = g_build_filename ("..", source_symlink_prefix, dent->d_name, NULL);
          g_autofree gchar *child_relpath = g_strconcat (source_relpath, dent->d_name, "/", NULL);

          if (!export_dir (source_iter.fd, dent->d_name, child_symlink_prefix, child_relpath, destination_dfd, dent->d_name,
                           cancellable, error))
            goto out;
        }
      else if (S_ISREG (stbuf.st_mode))
        {
          g_autofree char *symlink_name = g_strdup (".export-symlink-XXXXXX");
          g_autofree gchar *target = NULL;

          target = g_build_filename (source_symlink_prefix, dent->d_name, NULL);

          for (int count = 0; count < 100; count++)
            {
              glnx_gen_temp_name (symlink_name);

              if (symlinkat (target, destination_dfd, symlink_name) != 0)
                {
                  if (errno == EEXIST)
                    continue;

                  glnx_set_error_from_errno (error);
                  goto out;
                }

              if (renameat (destination_dfd, symlink_name, destination_dfd, dent->d_name) != 0)
                {
                  glnx_set_error_from_errno (error);
                  goto out;
                }

              break;
            }
        }
    }

  ret = TRUE;
out:

  return ret;
}

static gboolean
flatpak_export_dir (GFile        *source,
                    GFile        *destination,
                    const char   *symlink_prefix,
                    GCancellable *cancellable,
                    GError      **error)
{
  const char *exported_subdirs[] = {
    "share/applications",                  "../..",
    "share/icons",                         "../..",
    "share/dbus-1/services",               "../../..",
    "share/gnome-shell/search-providers",  "../../..",
    "share/krunner/dbusplugins",           "../../..",
    "share/mime/packages",                 "../../..",
    "share/metainfo",                      "../..",
    "share/metainfo/releases",             "../../..",
    "bin",                                 "..",
  };
  int i;

  for (i = 0; i < G_N_ELEMENTS (exported_subdirs); i = i + 2)
    {
      /* The fds are closed by this call */
      g_autoptr(GFile) sub_source = g_file_resolve_relative_path (source, exported_subdirs[i]);
      g_autoptr(GFile) sub_destination = g_file_resolve_relative_path (destination, exported_subdirs[i]);
      g_autofree char *sub_symlink_prefix = g_build_filename (exported_subdirs[i + 1], symlink_prefix, exported_subdirs[i], NULL);

      if (!g_file_query_exists (sub_source, cancellable))
        continue;

      if (!flatpak_mkdir_p (sub_destination, cancellable, error))
        return FALSE;

      if (!export_dir (AT_FDCWD, flatpak_file_get_path_cached (sub_source), sub_symlink_prefix, "",
                       AT_FDCWD, flatpak_file_get_path_cached (sub_destination),
                       cancellable, error))
        return FALSE;
    }

  return TRUE;
}

gboolean
flatpak_dir_update_exports (FlatpakDir   *self,
                            const char   *changed_app,
                            GCancellable *cancellable,
                            GError      **error)
{
  gboolean ret = FALSE;
  g_autoptr(GFile) exports = NULL;
  g_autoptr(FlatpakDecomposed) current_ref = NULL;
  g_autofree char *active_id = NULL;
  g_autofree char *symlink_prefix = NULL;

  exports = flatpak_dir_get_exports_dir (self);

  if (!flatpak_mkdir_p (exports, cancellable, error))
    goto out;

  if (changed_app &&
      (current_ref = flatpak_dir_current_ref (self, changed_app, cancellable)) &&
      (active_id = flatpak_dir_read_active (self, current_ref, cancellable)))
    {
      g_autoptr(GFile) deploy_base = NULL;
      g_autoptr(GFile) active = NULL;
      g_autoptr(GFile) export = NULL;

      deploy_base = flatpak_dir_get_deploy_dir (self, current_ref);
      active = g_file_get_child (deploy_base, active_id);
      export = g_file_get_child (active, "export");

      if (g_file_query_exists (export, cancellable))
        {
          symlink_prefix = g_build_filename ("..", "app", changed_app, "current", "active", "export", NULL);
          if (!flatpak_export_dir (export, exports,
                                   symlink_prefix,
                                   cancellable,
                                   error))
            goto out;
        }
    }

  if (!flatpak_remove_dangling_symlinks (exports, cancellable, error))
    goto out;

  ret = TRUE;

out:
  return ret;
}

static gboolean
extract_extra_data (FlatpakDir   *self,
                    const char   *checksum,
                    GFile        *extradir,
                    gboolean     *created_extra_data,
                    GCancellable *cancellable,
                    GError      **error)
{
  g_autoptr(GVariant) detached_metadata = NULL;
  g_autoptr(GVariant) extra_data = NULL;
  g_autoptr(GVariant) extra_data_sources = NULL;
  g_autoptr(GError) local_error = NULL;
  gsize i, n_extra_data = 0;
  gsize n_extra_data_sources;

  extra_data_sources = flatpak_repo_get_extra_data_sources (self->repo, checksum,
                                                            cancellable, &local_error);
  if (extra_data_sources == NULL)
    {
      /* This should protect us against potential errors at the OSTree level
         (e.g. ostree_repo_load_variant), so that we don't report success. */
      if (!g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
        {
          g_propagate_error (error, g_steal_pointer (&local_error));
          return FALSE;
        }

      return TRUE;
    }

  n_extra_data_sources = g_variant_n_children (extra_data_sources);
  if (n_extra_data_sources == 0)
    return TRUE;

  g_info ("extracting extra data to %s", flatpak_file_get_path_cached (extradir));

  if (!ostree_repo_read_commit_detached_metadata (self->repo, checksum, &detached_metadata,
                                                  cancellable, error))
    {
      g_prefix_error (error, _("While getting detached metadata: "));
      return FALSE;
    }

  if (detached_metadata == NULL)
    return flatpak_fail_error (error, FLATPAK_ERROR_INVALID_DATA, _("Extra data missing in detached metadata"));

  extra_data = g_variant_lookup_value (detached_metadata, "xa.extra-data",
                                       G_VARIANT_TYPE ("a(ayay)"));
  if (extra_data == NULL)
    return flatpak_fail_error (error, FLATPAK_ERROR_INVALID_DATA, _("Extra data missing in detached metadata"));

  n_extra_data = g_variant_n_children (extra_data);
  if (n_extra_data < n_extra_data_sources)
    return flatpak_fail_error (error, FLATPAK_ERROR_INVALID_DATA, _("Extra data missing in detached metadata"));

  if (!flatpak_mkdir_p (extradir, cancellable, error))
    {
      g_prefix_error (error, _("While creating extradir: "));
      return FALSE;
    }

  for (i = 0; i < n_extra_data_sources; i++)
    {
      g_autofree char *extra_data_sha256 = NULL;
      const guchar *extra_data_sha256_bytes;
      const char *extra_data_source_name = NULL;
      guint64 download_size;
      gboolean found;
      int j;

      flatpak_repo_parse_extra_data_sources (extra_data_sources, i,
                                             &extra_data_source_name,
                                             &download_size,
                                             NULL,
                                             &extra_data_sha256_bytes,
                                             NULL);

      if (extra_data_sha256_bytes == NULL)
        return flatpak_fail_error (error, FLATPAK_ERROR_INVALID_DATA, _("Invalid checksum for extra data"));

      extra_data_sha256 = ostree_checksum_from_bytes (extra_data_sha256_bytes);

      /* We need to verify the data in the commitmeta again, because the only signed
         thing is the commit, which has the source info. We could have accidentally
         picked up some other commitmeta stuff from the remote, or via the untrusted
         local-pull of the system helper. */
      found = FALSE;
      for (j = 0; j < n_extra_data; j++)
        {
          g_autoptr(GVariant) content = NULL;
          g_autoptr(GFile) dest = NULL;
          g_autofree char *sha256 = NULL;
          const char *extra_data_name = NULL;
          const guchar *data;
          gsize len;

          g_variant_get_child (extra_data, j, "(^&ay@ay)",
                               &extra_data_name,
                               &content);

          if (strcmp (extra_data_source_name, extra_data_name) != 0)
            continue;

          data = g_variant_get_data (content);
          len = g_variant_get_size (content);

          if (len != download_size)
            return flatpak_fail_error (error, FLATPAK_ERROR_INVALID_DATA, _("Wrong size for extra data"));

          sha256 = g_compute_checksum_for_data (G_CHECKSUM_SHA256, data, len);
          if (strcmp (sha256, extra_data_sha256) != 0)
            return flatpak_fail_error (error, FLATPAK_ERROR_INVALID_DATA, _("Invalid checksum for extra data"));

          dest = g_file_get_child (extradir, extra_data_name);
          if (!g_file_replace_contents (dest,
                                        g_variant_get_data (content),
                                        g_variant_get_size (content),
                                        NULL, FALSE, G_FILE_CREATE_REPLACE_DESTINATION,
                                        NULL, cancellable, error))
            {
              g_prefix_error (error, _("While writing extra data file '%s': "), extra_data_name);
              return FALSE;
            }
          found = TRUE;
        }

      if (!found)
        return flatpak_fail_error (error, FLATPAK_ERROR_INVALID_DATA,
                                   _("Extra data %s missing in detached metadata"),
                                   extra_data_source_name);
    }

  *created_extra_data = TRUE;

  return TRUE;
}

static gboolean
apply_extra_data (FlatpakDir   *self,
                  GFile        *checkoutdir,
                  GCancellable *cancellable,
                  GError      **error)
{
  g_autoptr(GFile) metadata = NULL;
  g_autofree char *metadata_contents = NULL;
  gsize metadata_size;
  g_autoptr(GKeyFile) metakey = NULL;
  g_autofree char *id = NULL;
  g_autofree char *runtime_pref = NULL;
  g_autoptr(FlatpakDecomposed) runtime_ref = NULL;
  g_autoptr(FlatpakDeploy) runtime_deploy = NULL;
  g_autoptr(FlatpakBwrap) bwrap = NULL;
  g_autoptr(GFile) app_files = NULL;
  g_autoptr(GFile) apply_extra_file = NULL;
  g_autoptr(GFile) app_export_file = NULL;
  g_autoptr(GFile) extra_export_file = NULL;
  g_autoptr(GFile) extra_files = NULL;
  g_autoptr(GFile) runtime_files = NULL;
  g_autoptr(FlatpakContext) app_context = NULL;
  g_auto(GStrv) minimal_envp = NULL;
  g_autofree char *runtime_arch = NULL;
  int exit_status;
  const char *group = FLATPAK_METADATA_GROUP_APPLICATION;
  g_autoptr(GError) local_error = NULL;
  FlatpakRunFlags run_flags;

  apply_extra_file = g_file_resolve_relative_path (checkoutdir, "files/bin/apply_extra");
  if (!g_file_query_exists (apply_extra_file, cancellable))
    return TRUE;

  metadata = g_file_get_child (checkoutdir, "metadata");

  if (!g_file_load_contents (metadata, cancellable, &metadata_contents, &metadata_size, NULL, error))
    return FALSE;

  metakey = g_key_file_new ();
  if (!g_key_file_load_from_data (metakey, metadata_contents, metadata_size, 0, error))
    return FALSE;

  id = g_key_file_get_string (metakey, group, FLATPAK_METADATA_KEY_NAME,
                              &local_error);
  if (id == NULL)
    {
      group = FLATPAK_METADATA_GROUP_RUNTIME;
      id = g_key_file_get_string (metakey, group, FLATPAK_METADATA_KEY_NAME,
                                  NULL);
      if (id == NULL)
        {
          g_propagate_error (error, g_steal_pointer (&local_error));
          return FALSE;
        }
      g_clear_error (&local_error);
    }

  runtime_pref = g_key_file_get_string (metakey, group,
                                        FLATPAK_METADATA_KEY_RUNTIME, NULL);
  if (runtime_pref == NULL)
    runtime_pref = g_key_file_get_string (metakey, FLATPAK_METADATA_GROUP_EXTENSION_OF,
                                          FLATPAK_METADATA_KEY_RUNTIME, NULL);
  if (runtime_pref == NULL)
    {
      g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
                   _("Unable to get runtime key from metadata"));
      return FALSE;
    }

  runtime_ref = flatpak_decomposed_new_from_pref (FLATPAK_KINDS_RUNTIME, runtime_pref, error);
  if (runtime_ref == NULL)
    return FALSE;
  runtime_arch = flatpak_decomposed_dup_arch (runtime_ref);

  if (!g_key_file_get_boolean (metakey, FLATPAK_METADATA_GROUP_EXTRA_DATA,
                               FLATPAK_METADATA_KEY_NO_RUNTIME, NULL))
    {
      /* We pass in self here so that we ensure that we find the runtime in case it only
         exists in this installation (which might be custom) */
      /* TODO: This is a circular dependency between flatpak-dir (which
       * deals with a single installation) and flatpak-dir-utils (which
       * deals with all the installations on the system). */
      runtime_deploy = flatpak_find_deploy_for_ref (flatpak_decomposed_get_ref (runtime_ref), NULL, self, cancellable, error);
      if (runtime_deploy == NULL)
        return FALSE;
      runtime_files = flatpak_deploy_get_files (runtime_deploy);
    }

  app_files = g_file_get_child (checkoutdir, "files");
  app_export_file = g_file_get_child (checkoutdir, "export");
  extra_files = g_file_get_child (app_files, "extra");
  extra_export_file = g_file_get_child (extra_files, "export");

  minimal_envp = flatpak_run_get_minimal_env (FALSE, FALSE);
  bwrap = flatpak_bwrap_new (minimal_envp);
  flatpak_bwrap_add_args (bwrap, flatpak_get_bwrap (), NULL);

  if (runtime_files)
    flatpak_bwrap_add_args (bwrap,
                            "--ro-bind", flatpak_file_get_path_cached (runtime_files), "/usr",
                            "--lock-file", "/usr/.ref",
                            NULL);

  flatpak_bwrap_add_args (bwrap,
                          "--ro-bind", flatpak_file_get_path_cached (app_files), "/app",
                          "--bind", flatpak_file_get_path_cached (extra_files), "/app/extra",
                          "--chdir", "/app/extra",
                          /* We run as root in the system-helper case, so drop all caps */
                          "--cap-drop", "ALL",
                          NULL);

  /* Run flags which equal flatpak run --sandbox */
  run_flags = (FLATPAK_RUN_FLAG_SANDBOX |
               FLATPAK_RUN_FLAG_NO_SESSION_HELPER |
               FLATPAK_RUN_FLAG_NO_SESSION_BUS_PROXY |
               FLATPAK_RUN_FLAG_NO_SYSTEM_BUS_PROXY |
               FLATPAK_RUN_FLAG_NO_A11Y_BUS_PROXY);

  /* Might need multiarch in apply_extra (see e.g. #3742).
   * Should be pretty safe in this limited context. */
  run_flags |= FLATPAK_RUN_FLAG_MULTIARCH;

  /* This sandbox is run as root and /proc/self/exe can sometimes be used to
   * access outside files (see cd21428).
   * Disable /proc entirely in this context. */
  run_flags |= FLATPAK_RUN_FLAG_NO_PROC;

  glnx_autofd int usr_fd = -1;

  if (runtime_files != NULL)
    {
      usr_fd = open (flatpak_file_get_path_cached (runtime_files),
                     O_PATH | O_CLOEXEC | O_NOFOLLOW);
      if (usr_fd < 0)
        return glnx_throw_errno_prefix (error, "Failed to open runtime files");
    }

  if (!flatpak_run_setup_base_argv (bwrap, usr_fd, NULL, runtime_arch,
                                    run_flags, error))
    return FALSE;

  app_context = flatpak_context_new ();

  if (!flatpak_run_add_environment_args (bwrap, NULL, run_flags, id,
                                         app_context, 0, 0, 0, 0,
                                         NULL, NULL, -1,
                                         NULL, NULL, cancellable, error))
    return FALSE;

  flatpak_bwrap_populate_runtime_dir (bwrap, NULL);

  flatpak_bwrap_envp_to_args (bwrap);

  flatpak_bwrap_add_args (bwrap, "--", "/app/bin/apply_extra", NULL);

  flatpak_bwrap_finish (bwrap);

  g_info ("Running /app/bin/apply_extra ");

  /* We run the sandbox without caps, but it can still create files owned by itself with
   * arbitrary permissions, including setuid myself. This is extra risky in the case where
   * this runs as root in the system helper case. We canonicalize the permissions at the
   * end, but to avoid non-canonical permissions leaking out before then we make the
   * toplevel dir only accessible to the user */
  if (chmod (flatpak_file_get_path_cached (extra_files), 0700) != 0)
    {
      glnx_set_error_from_errno (error);
      return FALSE;
    }

  if (!g_spawn_sync (NULL,
                     (char **) bwrap->argv->pdata,
                     bwrap->envp,
                     G_SPAWN_SEARCH_PATH,
                     flatpak_bwrap_child_setup_inherit_fds_cb, bwrap->fds,
                     NULL, NULL,
                     &exit_status,
                     error))
    return FALSE;

  if (!flatpak_canonicalize_permissions (AT_FDCWD, flatpak_file_get_path_cached (extra_files),
                                         getuid () == 0 ? 0 : -1,
                                         getuid () == 0 ? 0 : -1,
                                         error))
    return FALSE;

  if (exit_status != 0)
    {
      g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
                   _("apply_extra script failed, exit status %d"), exit_status);
      return FALSE;
    }

  if (g_file_query_exists (extra_export_file, cancellable))
    {
      if (!flatpak_mkdir_p (app_export_file, cancellable, error))
        return FALSE;
      if (!flatpak_cp_a (extra_export_file,
                         app_export_file,
                         FLATPAK_CP_FLAGS_MERGE,
                         cancellable, error))
        return FALSE;
    }

  return TRUE;
}

/* Check the user’s parental controls allow installation of @ref by looking at
 * its cached @deploy_data, which contains its content rating as extracted from
 * its AppData when it was originally downloaded. That’s compared to the
 * parental controls policy loaded from the #MctManager.
 *
 * If @ref should not be installed, an error is returned. */
static gboolean
flatpak_dir_check_parental_controls (FlatpakDir    *self,
                                     const char    *ref,
                                     GBytes        *deploy_data,
                                     const char    *action_id,
                                     GCancellable  *cancellable,
                                     GError       **error)
{
#ifdef HAVE_LIBMALCONTENT
#ifdef USE_SYSTEM_HELPER
  g_autoptr(GError) local_error = NULL;
  const char *on_session = g_getenv ("FLATPAK_SYSTEM_HELPER_ON_SESSION");
  g_autoptr(GDBusConnection) dbus_connection = NULL;
  g_autoptr(MctManager) manager = NULL;
  g_autoptr(MctAppFilter) app_filter = NULL;
  const char *content_rating_type;
  g_autoptr(GHashTable) content_rating = NULL;
  g_autoptr(AutoPolkitAuthority) authority = NULL;
  g_autoptr(AutoPolkitSubject) subject = NULL;
  gint subject_uid;
  g_autoptr(AutoPolkitAuthorizationResult) result = NULL;
  gboolean authorized;
  gboolean repo_installation_allowed, app_is_appropriate;
  PolkitCheckAuthorizationFlags polkit_flags;
  MctManagerGetValueFlags manager_flags;

  /* Assume that root is allowed to install any ref and shouldn't have any
   * parental controls restrictions applied to them. Note that this branch
   * must not be taken if this code is running within the system-helper, as that
   * runs as root but on behalf of another process. */
  if (!self->subject && getuid () == 0)
    {
      g_info ("Skipping parental controls check for %s due to running as root", ref);
      return TRUE;
    }

  /* The ostree-metadata and appstream/ branches should not have any parental
   * controls restrictions. Similarly, for the moment, there is no point in
   * restricting runtimes. */
  if (!g_str_has_prefix (ref, "app/"))
    return TRUE;

  g_info ("Getting parental controls details for %s from %s",
           ref, flatpak_deploy_data_get_origin (deploy_data));

  if (on_session != NULL)
    {
      /* FIXME: Instead of skipping the parental controls check in the test
       * environment, make a mock service for it.
       * https://github.com/flatpak/flatpak/issues/2993 */
      g_info ("Skipping parental controls check for %s since the "
              "system bus is unavailable in the test environment", ref);
      return TRUE;
    }

  dbus_connection = g_bus_get_sync (G_BUS_TYPE_SYSTEM, cancellable, &local_error);
  if (dbus_connection == NULL)
    {
      /* Since the checks below allow access when malcontent or
       * accounts-service aren't available on the bus, this whole routine can
       * be trivially bypassed by setting DBUS_SYSTEM_BUS_ADDRESS to a
       * temporary dbus-daemon. Not being able to connect to the system bus is
       * basically equivalent.
       */
      g_debug ("Skipping parental controls check for %s since D-Bus system "
               "bus connection failed: %s",
               ref,
               local_error ? local_error->message : "unknown reason");
      return TRUE;
    }

  if (self->subject)
    {
      g_autoptr(AutoPolkitSubject) process_subject = NULL;

      subject = g_object_ref (self->subject);
      /* This internally uses dbus GetConnectionCredentials which ensures we
       * get the right UID. We should *not* use it for authorization via the
       * PID though! */
      process_subject =
        polkit_system_bus_name_get_process_sync (POLKIT_SYSTEM_BUS_NAME (subject),
                                                 cancellable, NULL);
      subject_uid = polkit_unix_process_get_uid (POLKIT_UNIX_PROCESS (process_subject));
    }
  else
    {
      subject_uid = getuid ();
      subject = polkit_unix_process_new_for_owner (getpid (), 0, subject_uid);
    }

  if (subject_uid == -1)
    {
      g_set_error_literal (error, G_DBUS_ERROR, G_DBUS_ERROR_AUTH_FAILED,
                           "Failed to get subject UID");
      return FALSE;
    }

  g_assert (subject != NULL);

  manager = mct_manager_new (dbus_connection);
  manager_flags = MCT_MANAGER_GET_VALUE_FLAGS_NONE;
  if (!flatpak_dir_get_no_interaction (self))
    manager_flags |= MCT_MANAGER_GET_VALUE_FLAGS_INTERACTIVE;
  app_filter = mct_manager_get_app_filter (manager, subject_uid,
                                           manager_flags,
                                           cancellable, &local_error);
  if (g_error_matches (local_error, MCT_MANAGER_ERROR, MCT_MANAGER_ERROR_DISABLED))
    {
      g_info ("Skipping parental controls check for %s since parental "
              "controls are disabled globally", ref);
      return TRUE;
    }
  else if (g_error_matches (local_error, G_DBUS_ERROR, G_DBUS_ERROR_SERVICE_UNKNOWN) ||
           g_error_matches (local_error, G_DBUS_ERROR, G_DBUS_ERROR_NAME_HAS_NO_OWNER))
    {
      g_info ("Skipping parental controls check for %s since a required "
              "service was not found", ref);
      return TRUE;
    }
  else if (local_error != NULL)
    {
      g_propagate_error (error, g_steal_pointer (&local_error));
      return FALSE;
    }

  /* Check the content rating against the parental controls. If the app is
   * allowed to be installed, return so immediately. */
  repo_installation_allowed = ((self->user && mct_app_filter_is_user_installation_allowed (app_filter)) ||
                               (!self->user && mct_app_filter_is_system_installation_allowed (app_filter)));

  content_rating_type = flatpak_deploy_data_get_appdata_content_rating_type (deploy_data);
  content_rating = flatpak_deploy_data_get_appdata_content_rating (deploy_data);
  app_is_appropriate = flatpak_oars_check_rating (content_rating, content_rating_type,
                                                  app_filter);

  if (repo_installation_allowed && app_is_appropriate)
    {
      g_info ("Parental controls policy satisfied for %s", ref);
      return TRUE;
    }

  /* Otherwise, check polkit to see if the admin is going to allow the user to
   * override their parental controls policy. We can’t pass any details to this
   * polkit check, since it could be run by the user or by the system helper,
   * and non-root users can’t pass details to polkit checks. */
  authority = polkit_authority_get_sync (NULL, error);
  if (authority == NULL)
    return FALSE;

  polkit_flags = POLKIT_CHECK_AUTHORIZATION_FLAGS_NONE;
  if (!flatpak_dir_get_no_interaction (self))
    polkit_flags |= POLKIT_CHECK_AUTHORIZATION_FLAGS_ALLOW_USER_INTERACTION;
  result = polkit_authority_check_authorization_sync (authority, subject,
                                                      action_id,
                                                      NULL,
                                                      polkit_flags,
                                                      cancellable, error);
  if (result == NULL)
    return FALSE;

  authorized = polkit_authorization_result_get_is_authorized (result);

  if (!authorized)
    return flatpak_fail_error (error, FLATPAK_ERROR_PERMISSION_DENIED,
                               /* Translators: The placeholder is for an app ref. */
                               _("Installing %s is not allowed by the policy set by your administrator"),
                               ref);

  g_info ("Parental controls policy overridden by polkit for %s", ref);
#endif  /* USE_SYSTEM_HELPER */
#endif  /* HAVE_LIBMALCONTENT */

  return TRUE;
}

/* We create a deploy ref for the currently deployed version of all refs to avoid
   deployed commits being pruned when e.g. we pull --no-deploy. */
static gboolean
flatpak_dir_update_deploy_ref (FlatpakDir *self,
                               const char *ref,
                               const char *checksum,
                               GError    **error)
{
  g_autofree char *deploy_ref = g_strconcat ("deploy/", ref, NULL);

  if (!ostree_repo_set_ref_immediate (self->repo, NULL, deploy_ref, checksum, NULL, error))
    return FALSE;

  return TRUE;
}

gboolean
flatpak_dir_deploy (FlatpakDir          *self,
                    const char          *origin,
                    FlatpakDecomposed   *ref,
                    const char          *checksum_or_latest,
                    const char * const * subpaths,
                    const char * const * previous_ids,
                    const char          *parental_controls_action_id,
                    GCancellable        *cancellable,
                    GError             **error)
{
  g_autofree char *resolved_ref = NULL;
  g_autofree char *ref_id = NULL;
  g_autoptr(GFile) root = NULL;
  g_autoptr(GFile) deploy_base = NULL;
  glnx_autofd int deploy_base_dfd = -1;
  g_autoptr(GFile) checkoutdir = NULL;
  g_autoptr(GFile) bindir = NULL;
  g_autofree char *checkoutdirpath = NULL;
  const char *checkoutdir_basename;
  g_autoptr(GFile) real_checkoutdir = NULL;
  g_autoptr(GFile) dotref = NULL;
  g_autoptr(GFile) files_etc = NULL;
  g_autoptr(GFile) deploy_data_file = NULL;
  g_autoptr(GVariant) commit_data = NULL;
  g_autoptr(GBytes) deploy_data = NULL;
  g_autoptr(GFile) export = NULL;
  g_autoptr(GFile) extradir = NULL;
  g_autoptr(GKeyFile) keyfile = NULL;
  guint64 installed_size = 0;
  OstreeRepoCheckoutAtOptions options = { 0, };
  const char *checksum;
  glnx_autofd int checkoutdir_dfd = -1;
  const char *xa_ref = NULL;
  g_autofree char *checkout_basename = NULL;
  gboolean created_extra_data = FALSE;
  g_autoptr(GVariant) commit_metadata = NULL;
  g_auto(GLnxLockFile) lock = { 0, };
  g_autoptr(GFile) metadata_file = NULL;
  g_autofree char *metadata_contents = NULL;
  gsize metadata_size = 0;
  const char *flatpak;
  g_auto(GLnxTmpDir) tmp_dir_handle = { 0, };

  if (!flatpak_dir_ensure_repo (self, cancellable, error))
    return FALSE;

  ref_id = flatpak_decomposed_dup_id (ref);

  /* Keep a shared repo lock to avoid prunes removing objects we're relying on
   * while we do the checkout. This could happen if the ref changes after we
   * read its current value for the checkout. */
  if (!flatpak_dir_repo_lock (self, &lock, LOCK_SH, cancellable, error))
    return FALSE;

  deploy_base = flatpak_dir_get_deploy_dir (self, ref);

  if (!glnx_opendirat (AT_FDCWD, flatpak_file_get_path_cached (deploy_base), TRUE, &deploy_base_dfd, error))
    return FALSE;

  /* There used to be a bug here where temporary files beneath @deploy_base were not removed,
   * which could use quite a lot of space over time, so we check for these and remove them.
   * We only do so for the current app to avoid every deploy operation iterating over
   * every app directory and all their immediate descendents. That would be a bit much I/O. */
  remove_old_deploy_tmpdirs (deploy_base);

  if (checksum_or_latest == NULL)
    {
      g_info ("No checksum specified, getting tip of %s from origin %s", flatpak_decomposed_get_ref (ref), origin);

      resolved_ref = flatpak_dir_read_latest (self, origin, flatpak_decomposed_get_ref (ref), NULL, cancellable, error);
      if (resolved_ref == NULL)
        {
          g_prefix_error (error, _("While trying to resolve ref %s: "), flatpak_decomposed_get_ref (ref));
          return FALSE;
        }

      checksum = resolved_ref;
      g_info ("tip resolved to: %s", checksum);
    }
  else
    {
      checksum = checksum_or_latest;
      g_info ("Looking for checksum %s in local repo", checksum);
      if (!ostree_repo_read_commit (self->repo, checksum, NULL, NULL, cancellable, NULL))
        return flatpak_fail_error (error, FLATPAK_ERROR_INVALID_DATA, _("%s is not available"), flatpak_decomposed_get_ref (ref));
    }

  if (!ostree_repo_load_commit (self->repo, checksum, &commit_data, NULL, error))
    return FALSE;

  commit_metadata = g_variant_get_child_value (commit_data, 0);
  checkout_basename = flatpak_dir_get_deploy_subdir (self, checksum, subpaths);

  real_checkoutdir = g_file_get_child (deploy_base, checkout_basename);
  if (g_file_query_exists (real_checkoutdir, cancellable))
    return flatpak_fail_error (error, FLATPAK_ERROR_ALREADY_INSTALLED,
                               _("%s commit %s already installed"), flatpak_decomposed_get_ref (ref), checksum);

  g_autofree char *template = g_strdup_printf (".%s-XXXXXX", checkout_basename);

  if (!glnx_mkdtempat (deploy_base_dfd, template, 0755, &tmp_dir_handle, NULL))
    {
      g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
                           _("Can't create deploy directory"));
      return FALSE;
    }

  checkoutdir = g_file_get_child (deploy_base, tmp_dir_handle.path);

  if (!ostree_repo_read_commit (self->repo, checksum, &root, NULL, cancellable, error))
    {
      g_prefix_error (error, _("Failed to read commit %s: "), checksum);
      return FALSE;
    }

  if (!flatpak_repo_collect_sizes (self->repo, root, &installed_size, NULL, cancellable, error))
    return FALSE;

  options.mode = OSTREE_REPO_CHECKOUT_MODE_USER;
  options.overwrite_mode = OSTREE_REPO_CHECKOUT_OVERWRITE_UNION_FILES;
  options.enable_fsync = FALSE; /* We checkout to a temp dir and sync before moving it in place */
  options.bareuseronly_dirs = TRUE; /* https://github.com/ostreedev/ostree/pull/927 */
  checkoutdirpath = g_file_get_path (checkoutdir);
  checkoutdir_basename = tmp_dir_handle.path;  /* so checkoutdirpath = deploy_base_dfd / checkoutdir_basename */

  if (subpaths == NULL || *subpaths == NULL)
    {
      if (!ostree_repo_checkout_at (self->repo, &options,
                                    deploy_base_dfd, checkoutdir_basename,
                                    checksum,
                                    cancellable, error))
        {
          g_prefix_error (error, _("While trying to checkout %s into %s: "), checksum, checkoutdirpath);
          return FALSE;
        }
    }
  else
    {
      g_autoptr(GFile) files = g_file_get_child (checkoutdir, "files");
      int i;

      if (!g_file_make_directory_with_parents (files, cancellable, error))
        return FALSE;

      options.subpath = "metadata";

      if (!ostree_repo_checkout_at (self->repo, &options,
                                    deploy_base_dfd, checkoutdir_basename,
                                    checksum,
                                    cancellable, error))
        {
          g_prefix_error (error, _("While trying to checkout metadata subpath: "));
          return FALSE;
        }

      for (i = 0; subpaths[i] != NULL; i++)
        {
          g_autofree char *subpath = g_build_filename ("files", subpaths[i], NULL);
          g_autofree char *dstpath = g_build_filename (checkoutdirpath, "/files", subpaths[i], NULL);
          g_autofree char *dstpath_parent = g_path_get_dirname (dstpath);
          g_autofree char *dstpath_relative_to_deploy_base = g_build_filename (checkoutdir_basename, "/files", subpaths[i], NULL);
          g_autoptr(GFile) child = NULL;

          child = g_file_resolve_relative_path (root, subpath);

          if (!g_file_query_exists (child, cancellable))
            {
              g_info ("subpath %s not in tree", subpaths[i]);
              continue;
            }

          if (g_mkdir_with_parents (dstpath_parent, 0755))
            {
              glnx_set_error_from_errno (error);
              return FALSE;
            }

          options.subpath = subpath;
          if (!ostree_repo_checkout_at (self->repo, &options,
                                        deploy_base_dfd, dstpath_relative_to_deploy_base,
                                        checksum,
                                        cancellable, error))
            {
              g_prefix_error (error, _("While trying to checkout subpath ‘%s’: "), subpath);
              return FALSE;
            }
        }
    }

  /* Extract any extra data */
  extradir = g_file_resolve_relative_path (checkoutdir, "files/extra");
  if (!flatpak_rm_rf (extradir, cancellable, error))
    {
      g_prefix_error (error, _("While trying to remove existing extra dir: "));
      return FALSE;
    }

  if (!extract_extra_data (self, checksum, extradir, &created_extra_data, cancellable, error))
    return FALSE;

  if (created_extra_data)
    {
      if (!apply_extra_data (self, checkoutdir, cancellable, error))
        {
          g_prefix_error (error, _("While trying to apply extra data: "));
          return FALSE;
        }
    }

  g_variant_lookup (commit_metadata, "xa.ref", "&s", &xa_ref);
  if (xa_ref != NULL)
    {
      gboolean gpg_verify_summary;

      if (!ostree_repo_remote_get_gpg_verify_summary (self->repo, origin, &gpg_verify_summary, error))
        return FALSE;

      if (gpg_verify_summary)
        {
          /* If we're using signed summaries, then the security is really due to the signatures on
           * the summary, and the xa.ref is not needed for security. In particular, endless are
           * currently using one single commit on multiple branches to handle devel/stable promotion.
           * So, to support this we report branch discrepancies as a warning, rather than as an error.
           * See https://github.com/flatpak/flatpak/pull/1013 for more discussion.
           */
          FlatpakDecomposed *checkout_ref = ref;
          g_autoptr(FlatpakDecomposed) commit_ref = NULL;

          commit_ref = flatpak_decomposed_new_from_ref (xa_ref, error);
          if (commit_ref == NULL)
            {
              g_prefix_error (error, _("Invalid commit ref %s: "), xa_ref);
              return FALSE;
            }

          /* Fatal if kind/name/arch don't match. Warn for branch mismatch. */
          if (!flatpak_decomposed_equal_except_branch (checkout_ref, commit_ref))
            {
              g_set_error (error, G_IO_ERROR, G_IO_ERROR_PERMISSION_DENIED,
                           _("Deployed ref %s does not match commit (%s)"),
                           flatpak_decomposed_get_ref (ref), xa_ref);
              return FALSE;
            }

          if (strcmp (flatpak_decomposed_get_branch (checkout_ref), flatpak_decomposed_get_branch (commit_ref)) != 0)
            g_warning (_("Deployed ref %s branch does not match commit (%s)"),
                       flatpak_decomposed_get_ref (ref), xa_ref);
        }
      else if (strcmp (flatpak_decomposed_get_ref (ref), xa_ref) != 0)
        {
          g_set_error (error, G_IO_ERROR, G_IO_ERROR_PERMISSION_DENIED,
                       _("Deployed ref %s does not match commit (%s)"), flatpak_decomposed_get_ref (ref), xa_ref);
          return FALSE;
        }
    }

  keyfile = g_key_file_new ();
  metadata_file = g_file_resolve_relative_path (checkoutdir, "metadata");
  if (g_file_load_contents (metadata_file, NULL,
                            &metadata_contents,
                            &metadata_size, NULL, NULL))
    {
      if (!g_key_file_load_from_data (keyfile,
                                      metadata_contents,
                                      metadata_size,
                                      0, error))
        return FALSE;

      if (!flatpak_check_required_version (flatpak_decomposed_get_ref (ref), keyfile, error))
        return FALSE;
    }

  /* Check the metadata in the commit to make sure it matches the actual
   * deployed metadata, in case we relied on the one in the commit for
   * a decision
   */
  if (!validate_commit_metadata (commit_data, flatpak_decomposed_get_ref (ref),
                                 metadata_contents, metadata_size, error))
    return FALSE;

  dotref = g_file_resolve_relative_path (checkoutdir, "files/.ref");
  if (!g_file_replace_contents (dotref, "", 0, NULL, FALSE,
                                G_FILE_CREATE_REPLACE_DESTINATION, NULL, cancellable, error))
    return FALSE;

  export = g_file_get_child (checkoutdir, "export");

  /* Never export any binaries bundled with the app */
  bindir = g_file_get_child (export, "bin");
  if (!flatpak_rm_rf (bindir, cancellable, error))
    return FALSE;

  if (flatpak_decomposed_is_runtime (ref))
    {
      /* Ensure that various files exist as regular files in /usr/etc, as we
         want to bind-mount over them */
      files_etc = g_file_resolve_relative_path (checkoutdir, "files/etc");
      if (g_file_query_exists (files_etc, cancellable))
        {
          static const char * const etcfiles[] = {"passwd", "group", "machine-id" };
          g_autoptr(GFile) etc_resolve_conf = g_file_get_child (files_etc, "resolv.conf");
          int i;
          for (i = 0; i < G_N_ELEMENTS (etcfiles); i++)
            {
              g_autoptr(GFile) etc_file = g_file_get_child (files_etc, etcfiles[i]);
              GFileType type;

              type = g_file_query_file_type (etc_file, G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
                                             cancellable);
              if (type == G_FILE_TYPE_REGULAR)
                continue;

              if (type != G_FILE_TYPE_UNKNOWN)
                {
                  /* Already exists, but not regular, probably symlink. Remove it */
                  if (!g_file_delete (etc_file, cancellable, error))
                    return FALSE;
                }

              if (!g_file_replace_contents (etc_file, "", 0, NULL, FALSE,
                                            G_FILE_CREATE_REPLACE_DESTINATION,
                                            NULL, cancellable, error))
                return FALSE;
            }

          if (g_file_query_exists (etc_resolve_conf, cancellable) &&
              !g_file_delete (etc_resolve_conf, cancellable, error))
            return FALSE;

          if (!g_file_make_symbolic_link (etc_resolve_conf,
                                          "/run/host/monitor/resolv.conf",
                                          cancellable, error))
            return FALSE;
        }

      /* Runtime should never export anything */
      if (!flatpak_rm_rf (export, cancellable, error))
        return FALSE;
    }
  else /* is app */
    {
      g_autofree char *ref_arch = flatpak_decomposed_dup_arch (ref);
      g_autofree char *ref_branch = flatpak_decomposed_dup_branch (ref);
      g_autoptr(GFile) wrapper = g_file_get_child (bindir, ref_id);
      g_autofree char *escaped_app = maybe_quote (ref_id);
      g_autofree char *escaped_branch = maybe_quote (ref_branch);
      g_autofree char *escaped_arch = maybe_quote (ref_arch);
      g_autofree char *bin_data = NULL;
      int r;

      if (!flatpak_mkdir_p (bindir, cancellable, error))
        return FALSE;

      if (!flatpak_rewrite_export_dir (ref_id, ref_branch, ref_arch,
                                       keyfile, previous_ids, export,
                                       cancellable,
                                       error))
        return FALSE;
      if ((flatpak = g_getenv ("FLATPAK_BINARY")) == NULL)
        flatpak = FLATPAK_BINDIR "/flatpak";

      bin_data = g_strdup_printf ("#!/bin/sh\nexec %s run --branch=%s --arch=%s %s \"$@\"\n",
                                  flatpak, escaped_branch, escaped_arch, escaped_app);
      if (!g_file_replace_contents (wrapper, bin_data, strlen (bin_data), NULL, FALSE,
                                    G_FILE_CREATE_REPLACE_DESTINATION, NULL, cancellable, error))
        return FALSE;

      do
        r = fchmodat (AT_FDCWD, flatpak_file_get_path_cached (wrapper), 0755, 0);
      while (G_UNLIKELY (r == -1 && errno == EINTR));
      if (r == -1)
        return glnx_throw_errno_prefix (error, "fchmodat");
    }

  deploy_data = flatpak_dir_new_deploy_data (self,
                                             checkoutdir,
                                             commit_data,
                                             commit_metadata,
                                             keyfile,
                                             ref_id,
                                             origin,
                                             checksum,
                                             (char **) subpaths,
                                             installed_size,
                                             previous_ids);

  /* Check the app is actually allowed to be used by this user. This can block
   * on getting authorisation. */
  if (!flatpak_dir_check_parental_controls (self, flatpak_decomposed_get_ref (ref),
                                            deploy_data, parental_controls_action_id,
                                            cancellable, error))
    return FALSE;

  deploy_data_file = g_file_get_child (checkoutdir, "deploy");
  if (!flatpak_bytes_save (deploy_data_file, deploy_data, cancellable, error))
    return FALSE;

  if (!glnx_opendirat (deploy_base_dfd, checkoutdir_basename, TRUE, &checkoutdir_dfd, error))
    return FALSE;

  if (syncfs (checkoutdir_dfd) != 0)
    {
      glnx_set_error_from_errno (error);
      return FALSE;
    }

  if (!g_file_move (checkoutdir, real_checkoutdir, G_FILE_COPY_NO_FALLBACK_FOR_MOVE,
                    cancellable, NULL, NULL, error))
    return FALSE;

  glnx_tmpdir_unset (&tmp_dir_handle);

  if (!flatpak_dir_set_active (self, ref, checkout_basename, cancellable, error))
    return FALSE;

  if (!flatpak_dir_update_deploy_ref (self, flatpak_decomposed_get_ref (ref), checksum, error))
    return FALSE;

  return TRUE;
}

/* -origin remotes are deleted when the last ref referring to it is undeployed */
void
flatpak_dir_prune_origin_remote (FlatpakDir *self,
                                 const char *remote)
{
  if (remote != NULL &&
      g_str_has_suffix (remote, "-origin") &&
      flatpak_dir_get_remote_noenumerate (self, remote) &&
      !flatpak_dir_remote_has_deploys (self, remote))
    {
      if (flatpak_dir_use_system_helper (self, NULL))
        {
          const char *installation = flatpak_dir_get_id (self);
          g_autoptr(GVariant) gpg_data_v = NULL;

          gpg_data_v = g_variant_ref_sink (g_variant_new_from_data (G_VARIANT_TYPE ("ay"), "", 0, TRUE, NULL, NULL));

          flatpak_dir_system_helper_call_configure_remote (self,
                                                           FLATPAK_HELPER_CONFIGURE_FLAGS_NONE,
                                                           remote,
                                                           "",
                                                           gpg_data_v,
                                                           installation ? installation : "",
                                                           NULL, NULL);
        }
      else
        flatpak_dir_remove_remote (self, FALSE, remote, NULL, NULL);
    }
}

gboolean
flatpak_dir_deploy_install (FlatpakDir        *self,
                            FlatpakDecomposed *ref,
                            const char        *origin,
                            const char       **subpaths,
                            const char       **previous_ids,
                            gboolean           reinstall,
                            gboolean           pin_on_deploy,
                            gboolean           update_preinstalled_on_deploy,
                            GCancellable      *cancellable,
                            GError           **error)
{
  g_auto(GLnxLockFile) lock = { 0, };
  g_autoptr(GFile) deploy_base = NULL;
  g_autoptr(GFile) old_deploy_dir = NULL;
  gboolean created_deploy_base = FALSE;
  gboolean ret = FALSE;
  g_autoptr(GError) local_error = NULL;
  g_autofree char *remove_ref_from_remote = NULL;
  g_autofree char *commit = NULL;
  g_autofree char *old_active = NULL;

  if (!flatpak_dir_lock (self, &lock,
                         cancellable, error))
    goto out;

  old_deploy_dir = flatpak_dir_get_if_deployed (self, ref, NULL, cancellable);
  if (old_deploy_dir != NULL)
    {
      old_active = flatpak_dir_read_active (self, ref, cancellable);

      if (reinstall)
        {
          g_autoptr(GBytes) old_deploy = NULL;
          const char *old_origin;

          old_deploy = flatpak_load_deploy_data (old_deploy_dir, ref, self->repo, FLATPAK_DEPLOY_VERSION_ANY, cancellable, error);
          if (old_deploy == NULL)
            goto out;

          /* If the old install was from a different remote, remove the ref */
          old_origin = flatpak_deploy_data_get_origin (old_deploy);
          if (strcmp (old_origin, origin) != 0)
            remove_ref_from_remote = g_strdup (old_origin);

          g_info ("Removing old deployment for reinstall");
          if (!flatpak_dir_undeploy (self, ref, old_active,
                                     TRUE, FALSE,
                                     cancellable, error))
            goto out;
        }
      else
        {
          g_autofree char *id = flatpak_decomposed_dup_id (ref);
          g_autofree char *branch = flatpak_decomposed_dup_branch (ref);
          g_set_error (error, FLATPAK_ERROR, FLATPAK_ERROR_ALREADY_INSTALLED,
                       _("%s branch %s already installed"), id, branch);
          goto out;
        }
    }

  deploy_base = flatpak_dir_get_deploy_dir (self, ref);
  if (!g_file_make_directory_with_parents (deploy_base, cancellable, &local_error))
    {
      if (!g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_EXISTS))
        {
          g_propagate_error (error, g_steal_pointer (&local_error));
          goto out;
        }
    }

  /* After we create the deploy base we must goto out on errors */
  created_deploy_base = TRUE;

  if (!flatpak_dir_deploy (self, origin, ref, NULL, (const char * const *) subpaths,
                           previous_ids,
                           "org.freedesktop.Flatpak.override-parental-controls",
                           cancellable, error))
    goto out;

  if (flatpak_decomposed_is_app (ref))
    {
      g_autofree char *id = flatpak_decomposed_dup_id (ref);

      if (!flatpak_dir_make_current_ref (self, ref, cancellable, error))
        goto out;

      if (!flatpak_dir_update_exports (self, id, cancellable, error))
        goto out;
    }

  /* Remove old ref if the reinstalled was from a different remote */
  if (remove_ref_from_remote != NULL)
    {
      if (!flatpak_dir_remove_ref (self, remove_ref_from_remote, flatpak_decomposed_get_ref (ref), cancellable, error))
        goto out;

      flatpak_dir_prune_origin_remote (self, remove_ref_from_remote);
    }

  /* Release lock before doing possibly slow prune */
  glnx_release_lock_file (&lock);

  flatpak_dir_cleanup_removed (self, cancellable, NULL);

  if (!flatpak_dir_mark_changed (self, error))
    goto out;

  /* Pin runtimes that are installed explicitly rather than pulled as
   * dependencies so they are not automatically removed. */
  if (pin_on_deploy &&
      !flatpak_dir_config_append_pattern (self, "pinned",
                                          flatpak_decomposed_get_ref (ref),
                                          TRUE, NULL, error))
    goto out;

  /* Save preinstalled refs to keep the data on what is user installed and what
   * is automatically installed. */
  if (update_preinstalled_on_deploy &&
      !flatpak_dir_config_append_pattern (self, "preinstalled",
                                          flatpak_decomposed_get_ref (ref),
                                          FALSE, NULL, error))
    goto out;

  ret = TRUE;

  commit = flatpak_dir_read_active (self, ref, cancellable);
  flatpak_dir_log (self, "deploy install", origin, flatpak_decomposed_get_ref (ref), commit, old_active, NULL,
                   "Installed %s from %s", flatpak_decomposed_get_ref (ref), origin);

out:
  if (created_deploy_base && !ret)
    flatpak_rm_rf (deploy_base, cancellable, NULL);

  return ret;
}


gboolean
flatpak_dir_deploy_update (FlatpakDir        *self,
                           FlatpakDecomposed *ref,
                           const char        *checksum_or_latest,
                           const char       **opt_subpaths,
                           const char       **opt_previous_ids,
                           GCancellable      *cancellable,
                           GError           **error)
{
  g_autoptr(GBytes) old_deploy_data = NULL;
  g_auto(GLnxLockFile) lock = { 0, };
  g_autofree const char **old_subpaths = NULL;
  g_autofree char *old_active = NULL;
  const char *old_origin;
  g_autofree char *commit = NULL;
  g_autofree const char **previous_ids = NULL;
  g_auto(GStrv) previous_ids_owned = NULL;

  if (!flatpak_dir_lock (self, &lock,
                         cancellable, error))
    return FALSE;

  old_deploy_data = flatpak_dir_get_deploy_data (self, ref,
                                                 FLATPAK_DEPLOY_VERSION_ANY,
                                                 cancellable, error);
  if (old_deploy_data == NULL)
    return FALSE;

  old_active = flatpak_dir_read_active (self, ref, cancellable);

  old_origin = flatpak_deploy_data_get_origin (old_deploy_data);
  old_subpaths = flatpak_deploy_data_get_subpaths (old_deploy_data);

  previous_ids = flatpak_deploy_data_get_previous_ids (old_deploy_data, NULL);
  if (opt_previous_ids)
    {
      previous_ids_owned = flatpak_strv_merge ((char **) previous_ids, (char **) opt_previous_ids);
      g_clear_pointer (&previous_ids, g_free);
    }
  else
    previous_ids_owned = g_strdupv ((char **) previous_ids);

  if (!flatpak_dir_deploy (self,
                           old_origin,
                           ref,
                           checksum_or_latest,
                           opt_subpaths ? opt_subpaths : old_subpaths,
                           (const char * const *) previous_ids_owned,
                           "org.freedesktop.Flatpak.override-parental-controls-update",
                           cancellable, error))
    return FALSE;

  if (old_active &&
      !flatpak_dir_undeploy (self, ref, old_active,
                             TRUE, FALSE,
                             cancellable, error))
    return FALSE;

  if (flatpak_decomposed_is_app (ref))
    {
      g_autofree char *id = flatpak_decomposed_dup_id (ref);

      if (!flatpak_dir_update_exports (self, id, cancellable, error))
        return FALSE;
    }

  /* Release lock before doing possibly slow prune */
  glnx_release_lock_file (&lock);

  if (!flatpak_dir_mark_changed (self, error))
    return FALSE;

  flatpak_dir_cleanup_removed (self, cancellable, NULL);

  commit = flatpak_dir_read_active (self, ref, cancellable);
  flatpak_dir_log (self, "deploy update", old_origin, flatpak_decomposed_get_ref (ref), commit, old_active, NULL,
                   "Updated %s from %s", flatpak_decomposed_get_ref (ref), old_origin);

  return TRUE;
}

static void
rewrite_one_dynamic_launcher (const char *portal_desktop_dir,
                              const char *portal_icon_dir,
                              const char *desktop_name,
                              const char *old_app_id,
                              const char *new_app_id)
{
  g_autoptr(GKeyFile) old_key_file = NULL;
  g_autoptr(GKeyFile) new_key_file = NULL;
  g_autoptr(GFile) link_file = NULL;
  g_autoptr(GFile) new_link_file = NULL;
  g_autoptr(GString) data_string = NULL;
  g_autoptr(GError) local_error = NULL;
  g_autofree char *old_data = NULL;
  g_autofree char *desktop_path = NULL;
  g_autofree char *new_desktop_path = NULL;
  g_autofree char *icon_path = NULL;
  g_autofree char *relative_path = NULL;
  g_autofree char *new_desktop = NULL;
  const gchar *desktop_suffix;

  g_assert (g_str_has_suffix (desktop_name, ".desktop"));
  g_assert (g_str_has_prefix (desktop_name, old_app_id));

  desktop_path = g_build_filename (portal_desktop_dir,
                                   desktop_name, NULL);
  old_key_file = g_key_file_new ();
  if (!g_key_file_load_from_file (old_key_file, desktop_path,
                                  G_KEY_FILE_KEEP_COMMENTS | G_KEY_FILE_KEEP_TRANSLATIONS,
                                  &local_error))
    {
      g_warning ("Error encountered loading key file %s: %s", desktop_path, local_error->message);
      return;
    }
  if (!g_key_file_has_key (old_key_file, G_KEY_FILE_DESKTOP_GROUP, "X-Flatpak", NULL))
    {
      g_info ("Ignoring non-Flatpak dynamic launcher: %s", desktop_path);
      return;
    }

  /* Fix paths in desktop file with a find-and-replace. The portal handled
   * quoting the app ID in the Exec line for us.
   */
  old_data = g_key_file_to_data (old_key_file, NULL, NULL);
  data_string = g_string_new ((const char *)old_data);
  g_string_replace (data_string, old_app_id, new_app_id, 0);
  new_key_file = g_key_file_new ();
  if (!g_key_file_load_from_data (new_key_file, data_string->str, -1,
                                  G_KEY_FILE_KEEP_COMMENTS | G_KEY_FILE_KEEP_TRANSLATIONS,
                                  &local_error))
    {
      g_warning ("Cannot load desktop file %s after rewrite: %s", desktop_path, local_error->message);
      g_warning ("Key file contents:\n%s\n", (const char *)data_string->str);
      return;
    }

  /* Write it out at the new path */
  desktop_suffix = desktop_name + strlen (old_app_id);
  new_desktop = g_strconcat (new_app_id, desktop_suffix, NULL);
  new_desktop_path = g_build_filename (portal_desktop_dir, new_desktop, NULL);
  if (!g_key_file_save_to_file (new_key_file, new_desktop_path, &local_error))
    {
      g_warning ("Couldn't rewrite desktop file from %s to %s: %s",
                 desktop_path, new_desktop_path, local_error->message);
      return;
    }

  /* Fix symlink */
  link_file = g_file_new_build_filename (g_get_user_data_dir (), "applications", desktop_name, NULL);
  relative_path = g_build_filename ("..", "xdg-desktop-portal", "applications", new_desktop, NULL);
  if (!g_file_delete (link_file, NULL, &local_error) &&
      !g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
    {
      g_info ("Unable to delete desktop file link %s: %s", desktop_name, local_error->message);
      g_clear_error (&local_error);
    }

  new_link_file = g_file_new_build_filename (g_get_user_data_dir (), "applications", new_desktop, NULL);
  if (!g_file_make_symbolic_link (new_link_file, relative_path, NULL, &local_error))
    {
      g_warning ("Unable to rename desktop file link %s -> %s: %s",
                 desktop_name, new_desktop, local_error->message);
      return;
    }

  /* Delete the old desktop file */
  unlink (desktop_path);

  /* And rename the icon */
  icon_path = g_key_file_get_string (old_key_file, G_KEY_FILE_DESKTOP_GROUP, "Icon", NULL);
  if (g_str_has_prefix (icon_path, portal_icon_dir))
    {
      g_autoptr(GFile) icon_file = NULL;
      g_autofree char *icon_basename = NULL;
      g_autofree char *new_icon = NULL;
      gchar *icon_suffix;

      icon_file = g_file_new_for_path (icon_path);
      icon_basename = g_path_get_basename (icon_path);
      if (g_str_has_prefix (icon_basename, old_app_id))
        {
          icon_suffix = icon_basename + strlen (old_app_id);
          new_icon = g_strconcat (new_app_id, icon_suffix, NULL);
          if (!g_file_set_display_name (icon_file, new_icon, NULL, &local_error))
            {
              g_warning ("Unable to rename icon file %s -> %s: %s", icon_basename, new_icon,
                         local_error->message);
              g_clear_error (&local_error);
            }
        }
    }
}

static void
rewrite_dynamic_launchers (FlatpakDecomposed   *ref,
                           const char * const * previous_ids)

{
  g_autoptr(GFile) portal_desktop_dir = NULL;
  g_autofree char *portal_icon_path = NULL;
  g_autofree char *app_id = NULL;
  g_autoptr(GFileEnumerator) dir_enum = NULL;
  g_autoptr(GError) local_error = NULL;

  if (!flatpak_decomposed_is_app (ref))
    return;

  app_id = flatpak_decomposed_dup_id (ref);

  /* Rename any dynamic launchers written by xdg-desktop-portal. The
   * portal has its own code for renaming launchers on session start but we
   * need to do it here as well so the launchers are correct in both cases:
   * (1) the app rename transaction is being executed by the same user that
   * has the launchers, or (2) the app is installed system-wide and another
   * user has launchers.
   */
  if (previous_ids != NULL)
    {
      portal_desktop_dir = g_file_new_build_filename (g_get_user_data_dir (),
                                                      "xdg-desktop-portal",
                                                      "applications", NULL);
      portal_icon_path = g_build_filename (g_get_user_data_dir (),
                                           "xdg-desktop-portal", "icons", NULL);
      dir_enum = g_file_enumerate_children (portal_desktop_dir,
                                            G_FILE_ATTRIBUTE_STANDARD_NAME,
                                            G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
                                            NULL, &local_error);
    }
  if (dir_enum == NULL)
    {
      if (local_error && !g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
        {
          g_warning ("Failed to enumerate portal desktop dir %s: %s",
                     flatpak_file_get_path_cached (portal_desktop_dir),
                     local_error->message);
        }
      g_clear_error (&local_error);
    }
  else
    {
      g_autoptr(GFileInfo) child_info = NULL;
      g_auto(GStrv) previous_ids_sorted = NULL;

      /* Sort by decreasing length so we get the longest prefix below */
      previous_ids_sorted = flatpak_strv_sort_by_length (previous_ids);

      while ((child_info = g_file_enumerator_next_file (dir_enum, NULL, &local_error)) != NULL)
        {
          const char *desktop_name;
          int i;

          desktop_name = g_file_info_get_name (child_info);
          if (!g_str_has_suffix (desktop_name, ".desktop"))
            continue;

          for (i = 0; previous_ids_sorted[i] != NULL; i++)
            {
              if (g_str_has_prefix (desktop_name, previous_ids_sorted[i]))
                {
                  rewrite_one_dynamic_launcher (flatpak_file_get_path_cached (portal_desktop_dir),
                                                portal_icon_path, desktop_name,
                                                previous_ids_sorted[i], app_id);
                  break;
                }
            }
        }
      if (local_error)
        {
          g_warning ("Failed to enumerate portal desktop dir %s: %s",
                     flatpak_file_get_path_cached (portal_desktop_dir),
                     local_error->message);
        }
    }
}

static FlatpakOciRegistry *
flatpak_dir_create_system_child_oci_registry (FlatpakDir   *self,
                                              GLnxLockFile *file_lock,
                                              const char   *token,
                                              GError      **error)
{
  g_autoptr(GFile) cache_dir = NULL;
  g_autoptr(GFile) repo_dir = NULL;
  g_autofree char *repo_url = NULL;
  g_autofree char *tmpdir_name = NULL;
  g_autoptr(FlatpakOciRegistry) new_registry = NULL;

  g_assert (!self->user);

  if (!flatpak_dir_ensure_repo (self, NULL, error))
    return NULL;

  cache_dir = flatpak_ensure_system_user_cache_dir_location (error);
  if (cache_dir == NULL)
    return NULL;

  if (!flatpak_allocate_tmpdir (AT_FDCWD,
                                flatpak_file_get_path_cached (cache_dir),
                                "child-oci-", &tmpdir_name,
                                NULL,
                                file_lock,
                                NULL,
                                NULL, error))
    return NULL;

  repo_dir = g_file_get_child (cache_dir, tmpdir_name);
  repo_url = g_file_get_uri (repo_dir);

  new_registry = flatpak_oci_registry_new (repo_url, TRUE, -1,
                                           NULL, error);
  if (new_registry == NULL)
    return NULL;

  flatpak_oci_registry_set_token (new_registry, token);

  return g_steal_pointer (&new_registry);
}

static OstreeRepo *
flatpak_dir_create_child_repo (FlatpakDir   *self,
                               GFile        *cache_dir,
                               GLnxLockFile *file_lock,
                               const char   *optional_commit,
                               GError      **error)
{
  g_autoptr(GFile) repo_dir = NULL;
  g_autoptr(GFile) repo_dir_config = NULL;
  g_autoptr(OstreeRepo) repo = NULL;
  g_autofree char *tmpdir_name = NULL;
  g_autoptr(OstreeRepo) new_repo = NULL;
  g_autoptr(GKeyFile) config = NULL;
  g_autofree char *current_mode = NULL;
  GKeyFile *orig_config = NULL;
  g_autofree char *orig_min_free_space_percent = NULL;
  g_autofree char *orig_min_free_space_size = NULL;

  /* We use bare-user-only here now, which means we don't need xattrs
   * for the child repo. This only works as long as the pulled repo
   * is valid in a bare-user-only repo, i.e. doesn't have xattrs or
   * weird permissions, because then the pull into the system repo
   * would complain that the checksum was wrong. However, by now all
   * flatpak builds are likely to be valid, so this is fine.
   */
  OstreeRepoMode mode = OSTREE_REPO_MODE_BARE_USER_ONLY;
  const char *mode_str = "bare-user-only";

  if (!flatpak_dir_ensure_repo (self, NULL, error))
    return NULL;

  orig_config = ostree_repo_get_config (self->repo);

  if (!flatpak_allocate_tmpdir (AT_FDCWD,
                                flatpak_file_get_path_cached (cache_dir),
                                "repo-", &tmpdir_name,
                                NULL,
                                file_lock,
                                NULL,
                                NULL, error))
    return NULL;

  repo_dir = g_file_get_child (cache_dir, tmpdir_name);

  new_repo = ostree_repo_new (repo_dir);

  repo_dir_config = g_file_get_child (repo_dir, "config");
  if (!g_file_query_exists (repo_dir_config, NULL))
    {
      if (!ostree_repo_create (new_repo, mode, NULL, error))
        return NULL;
    }
  else
    {
      /* Try to open, but on failure, re-create */
      if (!ostree_repo_open (new_repo, NULL, NULL))
        {
          flatpak_rm_rf (repo_dir, NULL, NULL);
          if (!ostree_repo_create (new_repo, mode, NULL, error))
            return NULL;
        }
    }

  config = ostree_repo_copy_config (new_repo);

  /* Verify that the mode is the expected one; if it isn't, recreate the repo */
  current_mode = g_key_file_get_string (config, "core", "mode", NULL);
  if (current_mode == NULL || g_strcmp0 (current_mode, mode_str) != 0)
    {
      flatpak_rm_rf (repo_dir, NULL, NULL);

      /* Re-initialize the object because its dir's contents have been deleted (and it
       * holds internal references to them) */
      g_object_unref (new_repo);
      new_repo = ostree_repo_new (repo_dir);

      if (!ostree_repo_create (new_repo, mode, NULL, error))
        return NULL;

      /* Reload the repo config */
      g_key_file_free (config);
      config = ostree_repo_copy_config (new_repo);
    }

  /* Ensure the config is updated */
  g_key_file_set_string (config, "core", "parent",
                         flatpak_file_get_path_cached (ostree_repo_get_path (self->repo)));

  /* Copy the min space percent value so it affects the temporary repo too */
  orig_min_free_space_percent = g_key_file_get_value (orig_config, "core", "min-free-space-percent", NULL);
  if (orig_min_free_space_percent)
    g_key_file_set_value (config, "core", "min-free-space-percent", orig_min_free_space_percent);

  /* Copy the min space size value so it affects the temporary repo too */
  orig_min_free_space_size = g_key_file_get_value (orig_config, "core", "min-free-space-size", NULL);
  if (orig_min_free_space_size)
    g_key_file_set_value (config, "core", "min-free-space-size", orig_min_free_space_size);

  if (!ostree_repo_write_config (new_repo, config, error))
    return NULL;

  /* We need to reopen to apply the parent config */
  repo = ostree_repo_new (repo_dir);

  if (!ostree_repo_open (repo, NULL, error))
    return NULL;

  /* We don't need to sync the child repos, they are never used for stable storage, and we
     verify + fsync when importing to stable storage */
  ostree_repo_set_disable_fsync (repo, TRUE);

  g_autoptr(GFile) user_cache_dir = flatpak_ensure_user_cache_dir_location (error);
  if (user_cache_dir == NULL)
    return FALSE;

  if (!ostree_repo_set_cache_dir (repo, AT_FDCWD,
                                  flatpak_file_get_path_cached (user_cache_dir),
                                  NULL, error))
    return FALSE;

  /* Create a commitpartial in the child repo if needed to ensure we download everything, because
     any commitpartial state in the parent will not otherwise be inherited */
  if (optional_commit)
    {
      g_autofree char *commitpartial_basename = g_strconcat (optional_commit, ".commitpartial", NULL);
      g_autoptr(GFile) orig_commitpartial =
        flatpak_build_file (ostree_repo_get_path (self->repo),
                            "state", commitpartial_basename, NULL);
      if (g_file_query_exists (orig_commitpartial, NULL))
        {
          g_autoptr(GFile) commitpartial =
            flatpak_build_file (ostree_repo_get_path (repo),
                                "state", commitpartial_basename, NULL);
          g_file_replace_contents (commitpartial, "", 0, NULL, FALSE, G_FILE_CREATE_REPLACE_DESTINATION, NULL, NULL, NULL);
        }
    }
  return g_steal_pointer (&repo);
}

static OstreeRepo *
flatpak_dir_create_system_child_repo (FlatpakDir   *self,
                                      GLnxLockFile *file_lock,
                                      const char   *optional_commit,
                                      GError      **error)
{
  g_autoptr(GFile) cache_dir = NULL;

  g_assert (!self->user);

  cache_dir = flatpak_ensure_system_user_cache_dir_location (error);
  if (cache_dir == NULL)
    return NULL;

  return flatpak_dir_create_child_repo (self, cache_dir, file_lock, optional_commit, error);
}

static gboolean
flatpak_dir_setup_revokefs_fuse_mount (FlatpakDir    *self,
                                       FlatpakDecomposed *ref,
                                       const gchar   *installation,
                                       gchar        **out_src_dir,
                                       gchar        **out_mnt_dir,
                                       GCancellable  *cancellable)
{
  g_autoptr (GError) local_error = NULL;
  g_autofree gchar *src_dir_tmp = NULL;
  g_autofree gchar *mnt_dir_tmp = NULL;
  gint socket = -1;
  gboolean res = FALSE;
  const char *revokefs_fuse_bin = LIBEXECDIR "/revokefs-fuse";

  if (g_getenv ("FLATPAK_REVOKEFS_FUSE"))
    revokefs_fuse_bin = g_getenv ("FLATPAK_REVOKEFS_FUSE");

  if (!flatpak_dir_system_helper_call_get_revokefs_fd (self,
                                                       FLATPAK_HELPER_GET_REVOKEFS_FD_FLAGS_NONE,
                                                       installation ? installation : "",
                                                       &socket,
                                                       &src_dir_tmp,
                                                       cancellable,
                                                       &local_error))
    {
      if (g_error_matches (local_error, G_DBUS_ERROR, G_DBUS_ERROR_NOT_SUPPORTED))
        g_info ("revokefs-fuse not supported on your installation: %s", local_error->message);
      else
        g_warning ("Failed to get revokefs-fuse socket from system-helper: %s", local_error->message);

      goto out;
    }
  else
    {
      g_autoptr(GSubprocess) revokefs_fuse = NULL;
      g_autoptr(GSubprocessLauncher) launcher = NULL;
      g_autofree gchar *client_uid = NULL;

      mnt_dir_tmp = flatpak_dir_revokefs_fuse_create_mountpoint (ref, &local_error);
      if (mnt_dir_tmp == NULL)
        {
          g_warning ("Failed to create a mountpoint for revokefs-fuse: %s", local_error->message);
          close (socket);
          goto out;
        }

      client_uid = g_strdup_printf ("uid=%d", getuid ());
      launcher = g_subprocess_launcher_new (G_SUBPROCESS_FLAGS_NONE);
      g_subprocess_launcher_take_fd (launcher, socket, 3);
      revokefs_fuse = g_subprocess_launcher_spawn (launcher,
                                                   &local_error,
                                                   revokefs_fuse_bin, "-o", client_uid, "--socket=3",
                                                   src_dir_tmp, mnt_dir_tmp, NULL);
      if (revokefs_fuse == NULL ||
          !g_subprocess_wait_check (revokefs_fuse, NULL, &local_error))
        {
          g_warning ("Error spawning revokefs-fuse: %s", local_error->message);
          close (socket);
          goto out;
        }
    }

  res = TRUE;

out:
  /* It is unconventional to steal these values on error. However, it depends on where
   * this function failed. If we are able to spawn the revokefs backend (src_dir_tmp
   * is non-NULL) but failed to create mountpoint or spawning revokefs-fuse here,
   * we  still need the src_dir_tmp value to cleanup the revokefs backend properly
   * through the system-helper's CancelPull(). Hence, always stealing values can tell
   * the caller under what circumstances this function failed and cleanup accordingly. */
  *out_mnt_dir = g_steal_pointer (&mnt_dir_tmp);
  *out_src_dir = g_steal_pointer (&src_dir_tmp);

  return res;
}

static void
flatpak_dir_unmount_and_cancel_pull (FlatpakDir    *self,
                                     guint          arg_flags,
                                     GCancellable  *cancellable,
                                     OstreeRepo   **repo,
                                     GLnxLockFile  *lockfile,
                                     const char    *mnt_dir,
                                     const char    *src_dir)
{
  const char *installation = flatpak_dir_get_id (self);
  g_autoptr(GError) error = NULL;

  if (mnt_dir &&
      !flatpak_dir_revokefs_fuse_unmount (repo, lockfile, mnt_dir, &error))
    g_warning ("Could not unmount revokefs-fuse filesystem at %s: %s", mnt_dir, error->message);

  g_clear_error (&error);

  if (src_dir &&
      !flatpak_dir_system_helper_call_cancel_pull (self,
                                                   arg_flags,
                                                   installation ? installation : "",
                                                   src_dir, cancellable, &error))
    g_warning ("Error cancelling ongoing pull at %s: %s", src_dir, error->message);
}

gboolean
flatpak_dir_install (FlatpakDir          *self,
                     gboolean             no_pull,
                     gboolean             no_deploy,
                     gboolean             no_static_deltas,
                     gboolean             reinstall,
                     gboolean             app_hint,
                     gboolean             pin_on_deploy,
                     gboolean             update_preinstalled_on_deploy,
                     FlatpakRemoteState  *state,
                     FlatpakDecomposed   *ref,
                     const char          *opt_commit,
                     const char         **opt_subpaths,
                     const char         **opt_previous_ids,
                     GFile               *sideload_repo,
                     FlatpakImageSource  *opt_image_source,
                     GBytes              *require_metadata,
                     const char          *token,
                     FlatpakProgress     *progress,
                     GCancellable        *cancellable,
                     GError             **error)
{
  FlatpakPullFlags flatpak_flags;

  flatpak_flags = FLATPAK_PULL_FLAGS_DOWNLOAD_EXTRA_DATA;
  if (no_static_deltas)
    flatpak_flags |= FLATPAK_PULL_FLAGS_NO_STATIC_DELTAS;

  if (flatpak_dir_use_system_helper (self, NULL))
    {
      g_autoptr(OstreeRepo) child_repo = NULL;
      g_auto(GLnxLockFile) child_repo_lock = { 0, };
      const char *installation = flatpak_dir_get_id (self);
      const char *empty_subpaths[] = {NULL};
      const char **subpaths;
      g_autofree char *child_repo_path = NULL;
      FlatpakHelperDeployFlags helper_flags = 0;
      g_autofree char *url = NULL;
      gboolean gpg_verify_summary;
      gboolean gpg_verify;
      gboolean is_oci;
      gboolean is_revokefs_pull = FALSE;

      if (opt_subpaths)
        subpaths = opt_subpaths;
      else
        subpaths = empty_subpaths;

      if (!ostree_repo_remote_get_url (self->repo,
                                       state->remote_name,
                                       &url,
                                       error))
        return FALSE;

      if (!ostree_repo_remote_get_gpg_verify_summary (self->repo, state->remote_name,
                                                      &gpg_verify_summary, error))
        return FALSE;

      if (!ostree_repo_remote_get_gpg_verify (self->repo, state->remote_name,
                                              &gpg_verify, error))
        return FALSE;

      is_oci = flatpak_dir_get_remote_oci (self, state->remote_name);
      if (no_pull)
        {
          /* Do nothing */
        }
      else if (is_oci)
        {
          g_autoptr(FlatpakOciRegistry) registry = NULL;
          g_autoptr(GFile) registry_file = NULL;

          registry = flatpak_dir_create_system_child_oci_registry (self, &child_repo_lock, token, error);
          if (registry == NULL)
            return FALSE;

          registry_file = g_file_new_for_uri (flatpak_oci_registry_get_uri (registry));

          child_repo_path = g_file_get_path (registry_file);

          if (!flatpak_dir_mirror_oci (self, registry, state, flatpak_decomposed_get_ref (ref),
                                       opt_commit, opt_image_source, token, progress, cancellable, error))
            return FALSE;
        }
      else if (!gpg_verify_summary || !gpg_verify)
        {
          /* The remote is not gpg verified, so we don't want to allow installation via
             a download in the home directory, as there is no way to verify you're not
             injecting anything into the remote. However, in the case of a remote
             configured to a local filesystem we can just let the system helper do
             the installation, as it can then avoid network i/o and be certain the
             data comes from the right place. */
          if (g_str_has_prefix (url, "file:"))
            helper_flags |= FLATPAK_HELPER_DEPLOY_FLAGS_LOCAL_PULL;
          else
            return flatpak_fail_error (error, FLATPAK_ERROR_UNTRUSTED, _("Can't pull from untrusted non-gpg verified remote"));
        }
      else
        {
          /* For system pulls, the pull has to be made in a child repo first,
             which is then pulled into the system's one. The pull from child
             repo into the system repo can occur in one of the two following ways:
                1) Hard-link the child repo into system's one.
                2) Copy and verify each object from the child repo to the system's one.

             2) poses the problem of using double disk-space which might fail the
             installation of very big applications. For e.g. at endless, the encyclopedia app
             is about ~6GB, hence ~12GB of free disk-space is required to get it installed.

             For 1), we need to make sure that we address all the security concerns that
             might escalate during the pull from a remote into child repo and subsequently,
             hard-linking it into the (root-owned)system repo. This is taken care of by a
             special FUSE process(revokefs-fuse) which guards all the writes made to the
             child repo and ensures that no file descriptors remain open to the child repo
             before the hard-linkable pull is made into the system's repo.
             More details about the security issues dealt here are present at
             https://github.com/flatpak/flatpak/wiki/Noncopying-system-app-installation

             In case we fail to apply pull approach 1), the pull automatically fallbacks to use 2). */
          g_autofree gchar *src_dir = NULL;
          g_autofree gchar *mnt_dir = NULL;
          g_autoptr(GError) local_error = NULL;

          if (!flatpak_dir_setup_revokefs_fuse_mount (self,
                                                      ref,
                                                      installation,
                                                      &src_dir, &mnt_dir,
                                                      cancellable))
            {
              flatpak_dir_unmount_and_cancel_pull (self, FLATPAK_HELPER_CANCEL_PULL_FLAGS_NONE,
                                                   cancellable,
                                                   &child_repo, &child_repo_lock,
                                                   mnt_dir, src_dir);
            }
          else
            {
              g_autofree gchar *repo_basename = NULL;
              g_autoptr(GFile) mnt_dir_file = NULL;

              mnt_dir_file = g_file_new_for_path (mnt_dir);
              child_repo = flatpak_dir_create_child_repo (self, mnt_dir_file, &child_repo_lock, opt_commit, &local_error);
              if (child_repo == NULL)
                {
                  g_warning ("Cannot create repo on revokefs mountpoint %s: %s", mnt_dir, local_error->message);
                  flatpak_dir_unmount_and_cancel_pull (self,
                                                       FLATPAK_HELPER_CANCEL_PULL_FLAGS_NONE,
                                                       cancellable,
                                                       &child_repo, &child_repo_lock,
                                                       mnt_dir, src_dir);
                  g_clear_error (&local_error);
                }
              else
                {
                  repo_basename = g_file_get_basename (ostree_repo_get_path (child_repo));
                  child_repo_path = g_build_filename (src_dir, repo_basename, NULL);
                  is_revokefs_pull = TRUE;
                }
            }

          /* Fallback if revokefs-fuse setup does not succeed. This makes the pull
           * temporarily use double disk-space. */
          if (!is_revokefs_pull)
            {
             /* We're pulling from a remote source, we do the network mirroring pull as a
                user and hand back the resulting data to the system-helper, that trusts us
                due to the GPG signatures in the repo */
              child_repo = flatpak_dir_create_system_child_repo (self, &child_repo_lock, NULL, error);
              if (child_repo == NULL)
                return FALSE;
              else
                child_repo_path = g_file_get_path (ostree_repo_get_path (child_repo));
            }

          flatpak_flags |= FLATPAK_PULL_FLAGS_SIDELOAD_EXTRA_DATA;

          if (!flatpak_dir_pull (self, state, flatpak_decomposed_get_ref (ref), opt_commit, subpaths, sideload_repo, NULL, require_metadata, token,
                                 child_repo,
                                 flatpak_flags,
                                 0,
                                 progress, cancellable, error))
            {
              if (is_revokefs_pull)
                {
                  flatpak_dir_unmount_and_cancel_pull (self,
                                                       FLATPAK_HELPER_CANCEL_PULL_FLAGS_PRESERVE_PULL,
                                                       cancellable,
                                                       &child_repo, &child_repo_lock,
                                                       mnt_dir, src_dir);
                }

              return FALSE;
            }

          g_assert (child_repo_path != NULL);

          if (is_revokefs_pull &&
              !flatpak_dir_revokefs_fuse_unmount (&child_repo, &child_repo_lock, mnt_dir, &local_error))
            {
              g_propagate_prefixed_error (error, g_steal_pointer (&local_error),
                      _("Could not unmount revokefs-fuse filesystem at %s: "), mnt_dir);

              if (src_dir &&
                  !flatpak_dir_system_helper_call_cancel_pull (self,
                                                               FLATPAK_HELPER_CANCEL_PULL_FLAGS_PRESERVE_PULL,
                                                               installation ? installation : "",
                                                               src_dir, cancellable, &local_error))
                g_warning ("Error cancelling ongoing pull at %s: %s", src_dir, local_error->message);
              return FALSE;
            }
        }

      if (no_deploy)
        helper_flags |= FLATPAK_HELPER_DEPLOY_FLAGS_NO_DEPLOY;

      if (reinstall)
        helper_flags |= FLATPAK_HELPER_DEPLOY_FLAGS_REINSTALL;

      if (app_hint)
        helper_flags |= FLATPAK_HELPER_DEPLOY_FLAGS_APP_HINT;

      if (pin_on_deploy)
        helper_flags |= FLATPAK_HELPER_DEPLOY_FLAGS_UPDATE_PINNED;

      if (update_preinstalled_on_deploy)
        helper_flags |= FLATPAK_HELPER_DEPLOY_FLAGS_UPDATE_PREINSTALLED;

      helper_flags |= FLATPAK_HELPER_DEPLOY_FLAGS_INSTALL_HINT;

      if (!flatpak_dir_system_helper_call_deploy (self,
                                                  child_repo_path ? child_repo_path : "",
                                                  helper_flags, flatpak_decomposed_get_ref (ref), state->remote_name,
                                                  (const char * const *) subpaths,
                                                  (const char * const *) opt_previous_ids,
                                                  installation ? installation : "",
                                                  cancellable,
                                                  error))
        return FALSE;

      if (child_repo_path && !is_revokefs_pull)
        (void) glnx_shutil_rm_rf_at (AT_FDCWD, child_repo_path, NULL, NULL);

      /* In case the app is being renamed, rewrite any launchers made by
       * xdg-desktop-portal. This has to be done as the user so can't be in the
       * system helper.
       */
      if (opt_previous_ids)
        rewrite_dynamic_launchers (ref, opt_previous_ids);

      return TRUE;
    }

  if (!no_pull)
    {
      if (!flatpak_dir_pull (self, state, flatpak_decomposed_get_ref (ref), opt_commit, opt_subpaths,
                             sideload_repo, opt_image_source, require_metadata, token, NULL,
                             flatpak_flags, OSTREE_REPO_PULL_FLAGS_NONE,
                             progress, cancellable, error))
        return FALSE;
    }

  if (!no_deploy)
    {
      if (!flatpak_dir_deploy_install (self, ref, state->remote_name, opt_subpaths,
                                       opt_previous_ids, reinstall, pin_on_deploy,
                                       update_preinstalled_on_deploy,
                                       cancellable, error))
        return FALSE;

      /* In case the app is being renamed, rewrite any launchers made by
       * xdg-desktop-portal.
       */
      if (opt_previous_ids)
        rewrite_dynamic_launchers (ref, opt_previous_ids);
    }

  return TRUE;
}

char *
flatpak_dir_ensure_bundle_remote (FlatpakDir         *self,
                                  GFile              *file,
                                  GBytes             *extra_gpg_data,
                                  FlatpakDecomposed **out_ref,
                                  char              **out_checksum,
                                  char              **out_metadata,
                                  gboolean           *out_created_remote,
                                  GCancellable       *cancellable,
                                  GError            **error)
{
  g_autoptr(FlatpakDecomposed) ref = NULL;
  gboolean created_remote = FALSE;
  g_autoptr(GBytes) deploy_data = NULL;
  g_autoptr(GVariant) metadata = NULL;
  g_autofree char *origin = NULL;
  g_autofree char *fp_metadata = NULL;
  g_autofree char *basename = NULL;
  g_autoptr(GBytes) included_gpg_data = NULL;
  GBytes *gpg_data = NULL;
  g_autofree char *to_checksum = NULL;
  g_autofree char *remote = NULL;
  g_autofree char *collection_id = NULL;

  if (!flatpak_dir_ensure_repo (self, cancellable, error))
    return NULL;

  metadata = flatpak_bundle_load (file, &to_checksum,
                                  &ref,
                                  &origin,
                                  NULL, &fp_metadata, NULL,
                                  &included_gpg_data,
                                  &collection_id,
                                  error);
  if (metadata == NULL)
    return NULL;

  /* If we rely on metadata (to e.g. print permissions), check it exists before creating the remote */
  if (out_metadata && fp_metadata == NULL)
    {
      flatpak_fail_error (error, FLATPAK_ERROR_INVALID_DATA, "No metadata in bundle header");
      return NULL;
    }

  gpg_data = extra_gpg_data ? extra_gpg_data : included_gpg_data;

  deploy_data = flatpak_dir_get_deploy_data (self, ref, FLATPAK_DEPLOY_VERSION_ANY, cancellable, NULL);
  if (deploy_data != NULL)
    {
      remote = g_strdup (flatpak_deploy_data_get_origin (deploy_data));

      /* We need to import any gpg keys because otherwise the pull will fail */
      if (gpg_data != NULL)
        {
          g_autoptr(GKeyFile) new_config = NULL;

          new_config = ostree_repo_copy_config (flatpak_dir_get_repo (self));

          if (!flatpak_dir_modify_remote (self, remote, new_config,
                                          gpg_data, cancellable, error))
            return NULL;
        }
    }
  else
    {
      g_autofree char *id = flatpak_decomposed_dup_id (ref);
      /* Add a remote for later updates */
      basename = g_file_get_basename (file);
      remote = flatpak_dir_create_origin_remote (self,
                                                 origin,
                                                 id,
                                                 basename,
                                                 flatpak_decomposed_get_ref (ref),
                                                 gpg_data,
                                                 collection_id,
                                                 &created_remote,
                                                 cancellable,
                                                 error);
      if (remote == NULL)
        return NULL;
    }

  if (out_created_remote)
    *out_created_remote = created_remote;

  if (out_ref)
    *out_ref = g_steal_pointer (&ref);

  if (out_checksum)
    *out_checksum = g_steal_pointer (&to_checksum);

  if (out_metadata)
    *out_metadata = g_steal_pointer (&fp_metadata);


  return g_steal_pointer (&remote);
}

/* If core.add-remotes-config-dir is set for this repository (which is
 * not a common configuration, but it is possible), we will fail to modify
 * remote configuration when using a combination of
 * ostree_repo_remote_[add|change]() and ostree_repo_write_config() due to
 * adding remote config in /etc/flatpak/remotes.d and also in
 * /ostree/repo/config. Avoid that.
 *
 * FIXME: See https://github.com/flatpak/flatpak/issues/1665. In future, we
 * should just write the remote config to the correct place, factoring
 * core.add-remotes-config-dir in. */
static gboolean
flatpak_dir_check_add_remotes_config_dir (FlatpakDir *self,
                                          GError    **error)
{
  g_autoptr(GError) local_error = NULL;
  gboolean val;
  GKeyFile *config;

  if (!flatpak_dir_maybe_ensure_repo (self, NULL, error))
    return FALSE;

  if (self->repo == NULL)
    return TRUE;

  config = ostree_repo_get_config (self->repo);

  if (config == NULL)
    return TRUE;

  val = g_key_file_get_boolean (config, "core", "add-remotes-config-dir", &local_error);

  if (local_error != NULL)
    {
      if (g_error_matches (local_error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_KEY_NOT_FOUND))
        {
          g_clear_error (&local_error);
          val = ostree_repo_is_system (self->repo);
        }
      else
        {
          g_propagate_error (error, g_steal_pointer (&local_error));
          return FALSE;
        }
    }

  if (!val)
    return TRUE;

  return flatpak_fail (error,
                       "Can’t update remote configuration on a repository with "
                       "core.add-remotes-config-dir=true");
}

gboolean
flatpak_dir_install_bundle (FlatpakDir         *self,
                            gboolean            reinstall,
                            GFile              *file,
                            const char         *remote,
                            FlatpakDecomposed **out_ref,
                            GCancellable       *cancellable,
                            GError            **error)
{
  g_autofree char *ref_str = NULL;
  g_autoptr(FlatpakDecomposed) ref = NULL;
  g_autoptr(GBytes) deploy_data = NULL;
  g_autoptr(GVariant) metadata = NULL;
  g_autofree char *origin = NULL;
  g_autofree char *to_checksum = NULL;
  gboolean gpg_verify;
  FlatpakHelperInstallBundleFlags install_flags = FLATPAK_HELPER_INSTALL_BUNDLE_FLAGS_NONE;

  if (!flatpak_dir_check_add_remotes_config_dir (self, error))
    return FALSE;

  if (flatpak_dir_use_system_helper (self, NULL))
    {
      const char *installation = flatpak_dir_get_id (self);

      if (reinstall)
        install_flags |= FLATPAK_HELPER_INSTALL_BUNDLE_FLAGS_REINSTALL;

      if (!flatpak_dir_system_helper_call_install_bundle (self,
                                                          flatpak_file_get_path_cached (file),
                                                          install_flags,
                                                          remote,
                                                          installation ? installation : "",
                                                          &ref_str,
                                                          cancellable,
                                                          error))
        return FALSE;


      ref = flatpak_decomposed_new_from_ref (ref_str, error);
      if (ref == NULL)
        return FALSE;

      if (out_ref)
        *out_ref = g_steal_pointer (&ref);

      return TRUE;
    }

  if (!flatpak_dir_ensure_repo (self, cancellable, error))
    return FALSE;

  metadata = flatpak_bundle_load (file, &to_checksum,
                                  &ref,
                                  &origin,
                                  NULL, NULL,
                                  NULL, NULL, NULL,
                                  error);
  if (metadata == NULL)
    return FALSE;

  deploy_data = flatpak_dir_get_deploy_data (self, ref, FLATPAK_DEPLOY_VERSION_ANY, cancellable, NULL);
  if (deploy_data != NULL)
    {
      if (strcmp (flatpak_deploy_data_get_commit (deploy_data), to_checksum) == 0)
        {
          if (reinstall)
            {
              g_clear_pointer (&deploy_data, g_bytes_unref);
            }
          else
            {
              g_autofree char *id = flatpak_decomposed_dup_id (ref);
              g_set_error (error, FLATPAK_ERROR, FLATPAK_ERROR_ALREADY_INSTALLED,
                           _("This version of %s is already installed"), id);
              return FALSE;
            }
        }
      else if (strcmp (remote, flatpak_deploy_data_get_origin (deploy_data)) != 0)
        {
          if (reinstall)
            {
              g_clear_pointer (&deploy_data, g_bytes_unref);
            }
          else
            {
              g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
                           _("Can't change remote during bundle install"));
              return FALSE;
            }
        }
    }

  if (!ostree_repo_remote_get_gpg_verify (self->repo, remote,
                                          &gpg_verify, error))
    return FALSE;

  if (!flatpak_pull_from_bundle (self->repo,
                                 file,
                                 remote,
                                 flatpak_decomposed_get_ref (ref),
                                 gpg_verify,
                                 cancellable,
                                 error))
    return FALSE;

  if (deploy_data != NULL)
    {
      g_autofree char *group = g_strdup_printf ("remote \"%s\"", remote);
      g_autofree char *old_url = NULL;
      g_autoptr(GKeyFile) new_config = NULL;
      g_autoptr(GError) local_error = NULL;

      /* The pull succeeded, and this is an update. So, we need to update the repo config
         if anything changed */
      if (!ostree_repo_remote_get_url (self->repo,
                                       remote,
                                       &old_url,
                                       &local_error))
        {
          g_debug ("Unable to get the URL for remote %s: %s", remote, local_error->message);
          g_clear_error (&local_error);
        }

      if (origin != NULL &&
          (old_url == NULL || strcmp (old_url, origin) != 0))
        {
          if (new_config == NULL)
            new_config = ostree_repo_copy_config (self->repo);

          g_key_file_set_value (new_config, group, "url", origin);
        }

      if (new_config)
        {
          if (!flatpak_dir_cleanup_remote_for_url_change (self, remote,
                                                          origin, cancellable, error))
            return FALSE;

          if (!ostree_repo_write_config (self->repo, new_config, error))
            return FALSE;
        }
    }

  if (deploy_data)
    {
      if (!flatpak_dir_deploy_update (self, ref, NULL, NULL, NULL, cancellable, error))
        return FALSE;
    }
  else
    {
      if (!flatpak_dir_deploy_install (self, ref, remote, NULL, NULL, reinstall, FALSE, FALSE, cancellable, error))
        return FALSE;
    }

  if (out_ref)
    *out_ref = g_steal_pointer (&ref);

  return TRUE;
}

static gboolean
_g_strv_equal0 (const char * const *a, const char * const *b)
{
  if (a == NULL && b == NULL)
    return TRUE;

  if (a == NULL || b == NULL)
    return FALSE;

  return g_strv_equal (a, b);
}

gboolean
flatpak_dir_needs_update_for_commit_and_subpaths (FlatpakDir        *self,
                                                  const char        *remote,
                                                  FlatpakDecomposed *ref,
                                                  const char        *target_commit,
                                                  const char       **opt_subpaths)
{
  g_autoptr(GBytes) deploy_data = NULL;
  g_autofree const char **old_subpaths = NULL;
  const char **subpaths;
  g_autofree char *url = NULL;
  const char *installed_commit;
  const char *installed_alt_id;
  const char *extension_of;

  g_assert (target_commit != NULL);

  /* Never update from disabled remotes */
  if (!ostree_repo_remote_get_url (self->repo, remote, &url, NULL))
    return FALSE;

  if (*url == 0)
    return FALSE;

  /* deploy v4 guarantees alt-id/extension-of info */
  deploy_data = flatpak_dir_get_deploy_data (self, ref, 4, NULL, NULL);
  if (deploy_data != NULL)
    old_subpaths = flatpak_deploy_data_get_subpaths (deploy_data);
  else
    old_subpaths = g_new0 (const char *, 1); /* Empty strv == all subpaths*/

  if (opt_subpaths)
    subpaths = opt_subpaths;
  else
    subpaths = old_subpaths;

  /* Not deployed => need update */
  if (deploy_data == NULL)
    return TRUE;

  /* If masked, don't update */
  if (flatpak_dir_ref_is_masked (self, flatpak_decomposed_get_ref (ref)))
    return FALSE;

  extension_of = flatpak_deploy_data_get_extension_of (deploy_data);
  /* If the main ref is masked, don't update extensions of it (like .Locale or .Debug) */
  if (extension_of && flatpak_dir_ref_is_masked (self, extension_of))
    return FALSE;

  installed_commit = flatpak_deploy_data_get_commit (deploy_data);
  installed_alt_id = flatpak_deploy_data_get_alt_id (deploy_data);

  /* Different target commit than deployed => update */
  if (g_strcmp0 (target_commit, installed_commit) != 0 &&
      g_strcmp0 (target_commit, installed_alt_id) != 0)
    return TRUE;

  /* target commit is the same as current, but maybe something else that is different? */

  /* Same commit, but different subpaths => update */
  if (!_g_strv_equal0 (subpaths, old_subpaths))
    return TRUE;

  /* Same subpaths and commit, no need to update */
  return FALSE;
}

/* This is called by the old-school non-transaction flatpak_installation_update, so doesn't do a lot. */
char *
flatpak_dir_check_for_update (FlatpakDir               *self,
                              FlatpakRemoteState       *state,
                              FlatpakDecomposed        *ref,
                              const char               *checksum_or_latest,
                              const char              **opt_subpaths,
                              gboolean                  no_pull,
                              GCancellable             *cancellable,
                              GError                  **error)
{
  g_autofree char *latest_rev = NULL;
  const char *target_rev = NULL;

  if (no_pull)
    {
      if (!flatpak_repo_resolve_rev (self->repo, NULL, state->remote_name,
                                     flatpak_decomposed_get_ref (ref), FALSE, &latest_rev, NULL, NULL))
        {
          g_set_error (error, FLATPAK_ERROR, FLATPAK_ERROR_ALREADY_INSTALLED,
                       _("%s already installed"), flatpak_decomposed_get_ref (ref));
          return NULL; /* No update, because nothing to update to */
        }
    }
  else
    {
      if (!flatpak_dir_find_latest_rev (self, state, flatpak_decomposed_get_ref (ref), checksum_or_latest, &latest_rev,
                                        NULL, NULL, NULL, cancellable, error))
        return NULL;
    }

  if (checksum_or_latest != NULL)
    target_rev = checksum_or_latest;
  else
    target_rev = latest_rev;

  if (flatpak_dir_needs_update_for_commit_and_subpaths (self, state->remote_name, ref, target_rev, opt_subpaths))
    return g_strdup (target_rev);

  g_set_error (error, FLATPAK_ERROR, FLATPAK_ERROR_ALREADY_INSTALLED,
               _("%s commit %s already installed"), flatpak_decomposed_get_ref (ref), target_rev);
  return NULL;
}

gboolean
flatpak_dir_update (FlatpakDir                           *self,
                    gboolean                              no_pull,
                    gboolean                              no_deploy,
                    gboolean                              no_static_deltas,
                    gboolean                              allow_downgrade,
                    gboolean                              app_hint,
                    gboolean                              install_hint,
                    FlatpakRemoteState                   *state,
                    FlatpakDecomposed                    *ref,
                    const char                           *commit,
                    const char                          **opt_subpaths,
                    const char                          **opt_previous_ids,
                    GFile                                *sideload_repo,
                    FlatpakImageSource                   *opt_image_source,
                    GBytes                               *require_metadata,
                    const char                           *token,
                    FlatpakProgress                      *progress,
                    GCancellable                         *cancellable,
                    GError                              **error)
{
  g_autoptr(GBytes) deploy_data = NULL;
  const char **subpaths = NULL;
  const char *empty_subpaths[] = {NULL};
  g_autofree char *url = NULL;
  FlatpakPullFlags flatpak_flags;
  g_autofree const char **old_subpaths = NULL;
  gboolean is_oci;

  /* This is calculated in check_for_update */
  g_assert (commit != NULL);

  flatpak_flags = FLATPAK_PULL_FLAGS_DOWNLOAD_EXTRA_DATA;
  if (allow_downgrade)
    flatpak_flags |= FLATPAK_PULL_FLAGS_ALLOW_DOWNGRADE;
  if (no_static_deltas)
    flatpak_flags |= FLATPAK_PULL_FLAGS_NO_STATIC_DELTAS;

  deploy_data = flatpak_dir_get_deploy_data (self, ref, FLATPAK_DEPLOY_VERSION_ANY,
                                             cancellable, NULL);

  if (deploy_data != NULL)
    old_subpaths = flatpak_deploy_data_get_subpaths (deploy_data);

  if (opt_subpaths)
    subpaths = opt_subpaths;
  else if (old_subpaths)
    subpaths = old_subpaths;
  else
    subpaths = empty_subpaths;

  if (!ostree_repo_remote_get_url (self->repo, state->remote_name, &url, error))
    return FALSE;

  if (*url == 0)
    return TRUE; /* Empty URL => disabled */

  is_oci = flatpak_dir_get_remote_oci (self, state->remote_name);

  if (flatpak_dir_use_system_helper (self, NULL))
    {
      const char *installation = flatpak_dir_get_id (self);
      g_autoptr(OstreeRepo) child_repo = NULL;
      g_auto(GLnxLockFile) child_repo_lock = { 0, };
      g_autofree char *child_repo_path = NULL;
      FlatpakHelperDeployFlags helper_flags = 0;
      gboolean gpg_verify_summary;
      gboolean gpg_verify;
      gboolean is_revokefs_pull = FALSE;

      if (allow_downgrade)
        return flatpak_fail_error (error, FLATPAK_ERROR_DOWNGRADE,
                                   _("Can't update to a specific commit without root permissions"));

      helper_flags = FLATPAK_HELPER_DEPLOY_FLAGS_UPDATE;

      if (!ostree_repo_remote_get_gpg_verify_summary (self->repo, state->remote_name,
                                                      &gpg_verify_summary, error))
        return FALSE;

      if (!ostree_repo_remote_get_gpg_verify (self->repo, state->remote_name,
                                              &gpg_verify, error))
        return FALSE;

      if (no_pull)
        {
          /* Nothing to do here */
        }
      else if (is_oci)
        {
          g_autoptr(FlatpakOciRegistry) registry = NULL;
          g_autoptr(GFile) registry_file = NULL;

          registry = flatpak_dir_create_system_child_oci_registry (self, &child_repo_lock, token, error);
          if (registry == NULL)
            return FALSE;

          registry_file = g_file_new_for_uri (flatpak_oci_registry_get_uri (registry));

          child_repo_path = g_file_get_path (registry_file);

          if (!flatpak_dir_mirror_oci (self, registry, state, flatpak_decomposed_get_ref (ref),
                                       commit, opt_image_source, token, progress, cancellable, error))
            return FALSE;
        }
      else if (!gpg_verify_summary || !gpg_verify)
        {
          /* The remote is not gpg verified, so we don't want to allow installation via
             a download in the home directory, as there is no way to verify you're not
             injecting anything into the remote. However, in the case of a remote
             configured to a local filesystem we can just let the system helper do
             the installation, as it can then avoid network i/o and be certain the
             data comes from the right place.

             If @collection_id is non-%NULL, we can verify the refs in commit
             metadata, so don’t need to verify the summary. */
          if (g_str_has_prefix (url, "file:"))
            helper_flags |= FLATPAK_HELPER_DEPLOY_FLAGS_LOCAL_PULL;
          else
            return flatpak_fail_error (error, FLATPAK_ERROR_UNTRUSTED, _("Can't pull from untrusted non-gpg verified remote"));
        }
      else
        {
          /* First try to update using revokefs-fuse codepath. If it fails, try to update using a
           * temporary child-repo. Read flatpak_dir_install for more details on using revokefs-fuse */
          g_autofree gchar *src_dir = NULL;
          g_autofree gchar *mnt_dir = NULL;
          g_autoptr(GError) local_error = NULL;

          if (!flatpak_dir_setup_revokefs_fuse_mount (self,
                                                      ref,
                                                      installation,
                                                      &src_dir, &mnt_dir,
                                                      cancellable))
            {
              flatpak_dir_unmount_and_cancel_pull (self, FLATPAK_HELPER_CANCEL_PULL_FLAGS_NONE,
                                                   cancellable,
                                                   &child_repo, &child_repo_lock,
                                                   mnt_dir, src_dir);
            }
          else
            {
              g_autofree gchar *repo_basename = NULL;
              g_autoptr(GFile) mnt_dir_file = NULL;

              mnt_dir_file = g_file_new_for_path (mnt_dir);
              child_repo = flatpak_dir_create_child_repo (self, mnt_dir_file, &child_repo_lock, commit, &local_error);
              if (child_repo == NULL)
                {
                  g_warning ("Cannot create repo on revokefs mountpoint %s: %s", mnt_dir, local_error->message);
                  flatpak_dir_unmount_and_cancel_pull (self,
                                                       FLATPAK_HELPER_CANCEL_PULL_FLAGS_NONE,
                                                       cancellable,
                                                       &child_repo, &child_repo_lock,
                                                       mnt_dir, src_dir);
                  g_clear_error (&local_error);
                }
              else
                {
                  repo_basename = g_file_get_basename (ostree_repo_get_path (child_repo));
                  child_repo_path = g_build_filename (src_dir, repo_basename, NULL);
                  is_revokefs_pull = TRUE;
                }
            }

          /* Fallback if revokefs-fuse setup does not succeed. This makes the pull
           * temporarily use double disk-space. */
          if (!is_revokefs_pull)
            {
              /* We're pulling from a remote source, we do the network mirroring pull as a
                 user and hand back the resulting data to the system-helper, that trusts us
                 due to the GPG signatures in the repo */

              child_repo = flatpak_dir_create_system_child_repo (self, &child_repo_lock, commit, error);
              if (child_repo == NULL)
                return FALSE;
              else
                child_repo_path = g_file_get_path (ostree_repo_get_path (child_repo));
            }

          flatpak_flags |= FLATPAK_PULL_FLAGS_SIDELOAD_EXTRA_DATA;
          if (!flatpak_dir_pull (self, state, flatpak_decomposed_get_ref (ref),
                                 commit, subpaths, sideload_repo, NULL, require_metadata, token,
                                 child_repo,
                                 flatpak_flags, 0,
                                 progress, cancellable, error))
            {
              if (is_revokefs_pull)
                {
                  flatpak_dir_unmount_and_cancel_pull (self,
                                                       FLATPAK_HELPER_CANCEL_PULL_FLAGS_PRESERVE_PULL,
                                                       cancellable,
                                                       &child_repo, &child_repo_lock,
                                                       mnt_dir, src_dir);
                }

              return FALSE;
            }

          g_assert (child_repo_path != NULL);

          if (is_revokefs_pull &&
              !flatpak_dir_revokefs_fuse_unmount (&child_repo, &child_repo_lock, mnt_dir, &local_error))
            {
              g_warning ("Could not unmount revokefs-fuse filesystem at %s: %s", mnt_dir, local_error->message);
              flatpak_dir_unmount_and_cancel_pull (self,
                                                   FLATPAK_HELPER_CANCEL_PULL_FLAGS_PRESERVE_PULL,
                                                   cancellable,
                                                   &child_repo, &child_repo_lock,
                                                   mnt_dir, src_dir);
              return FALSE;
            }
        }

      if (no_deploy)
        helper_flags |= FLATPAK_HELPER_DEPLOY_FLAGS_NO_DEPLOY;

      if (app_hint)
        helper_flags |= FLATPAK_HELPER_DEPLOY_FLAGS_APP_HINT;

      if (install_hint)
        helper_flags |= FLATPAK_HELPER_DEPLOY_FLAGS_INSTALL_HINT;

      if (!flatpak_dir_system_helper_call_deploy (self,
                                                  child_repo_path ? child_repo_path : "",
                                                  helper_flags, flatpak_decomposed_get_ref (ref), state->remote_name,
                                                  subpaths, opt_previous_ids,
                                                  installation ? installation : "",
                                                  cancellable,
                                                  error))
        return FALSE;

      if (child_repo_path && !is_revokefs_pull)
        (void) glnx_shutil_rm_rf_at (AT_FDCWD, child_repo_path, NULL, NULL);

      /* In case the app is being renamed, rewrite any launchers made by
       * xdg-desktop-portal. This has to be done as the user so can't be in the
       * system helper.
       */
      if (opt_previous_ids)
        rewrite_dynamic_launchers (ref, opt_previous_ids);

      return TRUE;
    }

  if (!no_pull)
    {
      if (!flatpak_dir_pull (self, state, flatpak_decomposed_get_ref (ref),
                             commit, subpaths, sideload_repo, opt_image_source, require_metadata, token,
                             NULL, flatpak_flags, OSTREE_REPO_PULL_FLAGS_NONE,
                             progress, cancellable, error))
        return FALSE;

      /* Take this opportunity to clean up refs/mirrors/ since a prune will happen
       * after this update operation. See
       * https://github.com/flatpak/flatpak/issues/3222
       * Note: For the system-helper case we do this in handle_deploy()
       */
      if (!flatpak_dir_delete_mirror_refs (self, FALSE, cancellable, error))
        return FALSE;
    }

  if (!no_deploy)
    {
      if (!flatpak_dir_deploy_update (self, ref,
                                      /* We don't know the local commit id in the OCI case, and
                                         we only support one version anyway */
                                      is_oci ? NULL : commit,
                                      subpaths, opt_previous_ids,
                                      cancellable, error))
        return FALSE;

      /* In case the app is being renamed, rewrite any launchers made by
       * xdg-desktop-portal.
       */
      if (opt_previous_ids)
        rewrite_dynamic_launchers (ref, opt_previous_ids);
    }

  return TRUE;
}

gboolean
flatpak_dir_uninstall (FlatpakDir                 *self,
                       FlatpakDecomposed          *ref,
                       FlatpakHelperUninstallFlags flags,
                       GCancellable               *cancellable,
                       GError                    **error)
{
  const char *repository;
  g_autoptr(FlatpakDecomposed) current_ref = NULL;
  gboolean was_deployed;
  g_autofree char *name = NULL;
  g_autofree char *old_active = NULL;
  g_auto(GLnxLockFile) lock = { 0, };
  g_autoptr(GBytes) deploy_data = NULL;
  gboolean keep_ref = flags & FLATPAK_HELPER_UNINSTALL_FLAGS_KEEP_REF;
  gboolean force_remove = flags & FLATPAK_HELPER_UNINSTALL_FLAGS_FORCE_REMOVE;
  gboolean update_preinstalled = flags & FLATPAK_HELPER_UNINSTALL_FLAGS_UPDATE_PREINSTALLED;

  name = flatpak_decomposed_dup_id (ref);

  if (flatpak_dir_use_system_helper (self, NULL))
    {
      const char *installation = flatpak_dir_get_id (self);

      if (!flatpak_dir_system_helper_call_uninstall (self,
                                                     flags, flatpak_decomposed_get_ref (ref),
                                                     installation ? installation : "",
                                                     cancellable, error))
        return FALSE;

      return TRUE;
    }

  if (!flatpak_dir_lock (self, &lock,
                         cancellable, error))
    return FALSE;

  deploy_data = flatpak_dir_get_deploy_data (self, ref, FLATPAK_DEPLOY_VERSION_ANY,
                                             cancellable, error);
  if (deploy_data == NULL)
    return FALSE;

  /* Note: the origin remote usually exists but it's not guaranteed (the user
   * could have run remote-delete --force) */
  repository = flatpak_deploy_data_get_origin (deploy_data);
  if (repository == NULL)
    return FALSE;

  if (flatpak_decomposed_is_runtime (ref) && !force_remove)
    {
      g_autoptr(GHashTable) runtime_app_map = NULL;
      g_autoptr(GPtrArray) blocking = NULL;

      /* Look for apps that need this runtime */
      blocking = flatpak_dir_list_app_refs_with_runtime (self, &runtime_app_map, ref, cancellable, error);
      if (blocking == NULL)
        return FALSE;

      if (blocking->len > 0)
        {
          g_autoptr(GString) joined = g_string_new ("");
          for (int i = 0; i < blocking->len; i++)
            {
              FlatpakDecomposed *blocking_ref = g_ptr_array_index (blocking, i);
              g_autofree char *id = flatpak_decomposed_dup_id (blocking_ref);
              if (i != 0)
                g_string_append (joined, ", ");
              g_string_append (joined, id);
            }

          return flatpak_fail_error (error, FLATPAK_ERROR_RUNTIME_USED,
                                     _("Can't remove %s, it is needed for: %s"), flatpak_decomposed_get_pref (ref), joined->str);
        }
    }

  old_active = g_strdup (flatpak_deploy_data_get_commit (deploy_data));

  g_info ("dropping active ref");
  if (!flatpak_dir_set_active (self, ref, NULL, cancellable, error))
    return FALSE;

  if (flatpak_decomposed_is_app (ref))
    {
      current_ref = flatpak_dir_current_ref (self, name, cancellable);
      if (current_ref != NULL &&
          flatpak_decomposed_equal (ref, current_ref))
        {
          g_info ("dropping current ref");
          if (!flatpak_dir_drop_current_ref (self, name, cancellable, error))
            return FALSE;
        }
    }

  if (!flatpak_dir_update_deploy_ref (self, flatpak_decomposed_get_ref (ref), NULL, error))
    return FALSE;

  if (!flatpak_dir_undeploy_all (self, ref, force_remove, &was_deployed, cancellable, error))
    return FALSE;

  if (!keep_ref &&
      !flatpak_dir_remove_ref (self, repository, flatpak_decomposed_get_ref (ref), cancellable, error))
    return FALSE;

  /* Take this opportunity to clean up refs/mirrors/ since a prune will happen
   * after this uninstall operation. See
   * https://github.com/flatpak/flatpak/issues/3222
   */
  if (!flatpak_dir_delete_mirror_refs (self, FALSE, cancellable, error))
    return FALSE;

  if (flatpak_decomposed_is_app (ref) &&
      !flatpak_dir_update_exports (self, name, cancellable, error))
    return FALSE;

  glnx_release_lock_file (&lock);

  flatpak_dir_prune_origin_remote (self, repository);

  flatpak_dir_cleanup_removed (self, cancellable, NULL);

  if (!flatpak_dir_mark_changed (self, error))
    return FALSE;

  if (update_preinstalled &&
      !flatpak_dir_config_remove_pattern (self, "preinstalled", flatpak_decomposed_get_ref (ref), error))
    return FALSE;

  if (!was_deployed)
    {
      const char *branch = flatpak_decomposed_get_branch (ref);
      g_set_error (error, FLATPAK_ERROR, FLATPAK_ERROR_NOT_INSTALLED,
                   _("%s branch %s is not installed"), name, branch);
      return FALSE;
    }

  flatpak_dir_log (self, "uninstall", NULL, flatpak_decomposed_get_ref (ref), NULL, old_active, NULL,
                   "Uninstalled %s", flatpak_decomposed_get_ref (ref));

  return TRUE;
}

gboolean
flatpak_dir_collect_deployed_refs (FlatpakDir   *self,
                                   const char   *type,
                                   const char   *name_prefix,
                                   const char   *arch,
                                   const char   *branch,
                                   GHashTable   *hash,
                                   GCancellable *cancellable,
                                   GError      **error)
{
  gboolean ret = FALSE;
  g_autoptr(GFile) dir = NULL;
  g_autoptr(GFileEnumerator) dir_enum = NULL;
  g_autoptr(GFileInfo) child_info = NULL;
  GError *temp_error = NULL;
  FlatpakKinds kind;

  if (strcmp (type, "app") == 0)
    kind = FLATPAK_KINDS_APP;
  else
    kind = FLATPAK_KINDS_RUNTIME;

  dir = g_file_get_child (self->basedir, type);
  if (!g_file_query_exists (dir, cancellable))
    return TRUE;

  dir_enum = g_file_enumerate_children (dir, OSTREE_GIO_FAST_QUERYINFO,
                                        G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
                                        cancellable,
                                        error);
  if (!dir_enum)
    goto out;

  while ((child_info = g_file_enumerator_next_file (dir_enum, cancellable, &temp_error)) != NULL)
    {
      const char *name = g_file_info_get_name (child_info);

      if (g_file_info_get_file_type (child_info) == G_FILE_TYPE_DIRECTORY &&
          name[0] != '.' && (name_prefix == NULL || g_str_has_prefix (name, name_prefix)))
        {
          g_autoptr(GFile) child1 = g_file_get_child (dir, name);
          g_autoptr(GFile) child2 = g_file_get_child (child1, arch);
          g_autoptr(GFile) child3 = g_file_get_child (child2, branch);
          g_autoptr(GFile) active = g_file_get_child (child3, "active");

          if (g_file_query_exists (active, cancellable))
            {
              FlatpakDecomposed *ref = flatpak_decomposed_new_from_parts (kind, name, arch, branch, NULL);
              if (ref)
                g_hash_table_add (hash, ref);
            }
        }

      g_clear_object (&child_info);
    }

  if (temp_error != NULL)
    {
      g_propagate_error (error, temp_error);
      goto out;
    }

  ret = TRUE;
out:
  return ret;
}

gboolean
flatpak_dir_collect_unmaintained_refs (FlatpakDir   *self,
                                       const char   *name_prefix,
                                       const char   *arch,
                                       const char   *branch,
                                       GHashTable   *hash,
                                       GCancellable *cancellable,
                                       GError      **error)
{
  gboolean ret = FALSE;
  g_autoptr(GFile) unmaintained_dir = NULL;
  g_autoptr(GFileEnumerator) unmaintained_dir_enum = NULL;
  g_autoptr(GFileInfo) child_info = NULL;
  GError *temp_error = NULL;

  unmaintained_dir = g_file_get_child (self->basedir, "extension");
  if (!g_file_query_exists (unmaintained_dir, cancellable))
    return TRUE;

  unmaintained_dir_enum = g_file_enumerate_children (unmaintained_dir, G_FILE_ATTRIBUTE_STANDARD_NAME,
                                                     G_FILE_QUERY_INFO_NONE,
                                                     cancellable,
                                                     error);
  if (!unmaintained_dir_enum)
    goto out;

  while ((child_info = g_file_enumerator_next_file (unmaintained_dir_enum, cancellable, &temp_error)) != NULL)
    {
      const char *name = g_file_info_get_name (child_info);

      if (g_file_info_get_file_type (child_info) == G_FILE_TYPE_DIRECTORY &&
          name[0] != '.' && (name_prefix == NULL || g_str_has_prefix (name, name_prefix)))
        {
          g_autoptr(GFile) child1 = g_file_get_child (unmaintained_dir, name);
          g_autoptr(GFile) child2 = g_file_get_child (child1, arch);
          g_autoptr(GFile) child3 = g_file_get_child (child2, branch);

          if (g_file_query_exists (child3, cancellable))
            g_hash_table_add (hash, g_strdup (name));
        }

      g_clear_object (&child_info);
    }

  if (temp_error != NULL)
    {
      g_propagate_error (error, temp_error);
      goto out;
    }

  ret = TRUE;
out:
  return ret;
}

gboolean
flatpak_dir_list_deployed (FlatpakDir        *self,
                           FlatpakDecomposed *ref,
                           char            ***deployed_ids,
                           GCancellable      *cancellable,
                           GError           **error)
{
  gboolean ret = FALSE;
  g_autoptr(GFile) deploy_base = NULL;
  g_autoptr(GPtrArray) ids = NULL;
  GError *temp_error = NULL;
  g_autoptr(GFileEnumerator) dir_enum = NULL;
  g_autoptr(GFile) child = NULL;
  g_autoptr(GFileInfo) child_info = NULL;
  g_autoptr(GError) my_error = NULL;

  deploy_base = flatpak_dir_get_deploy_dir (self, ref);

  ids = g_ptr_array_new_with_free_func (g_free);

  dir_enum = g_file_enumerate_children (deploy_base, OSTREE_GIO_FAST_QUERYINFO,
                                        G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
                                        cancellable,
                                        &my_error);
  if (!dir_enum)
    {
      if (g_error_matches (my_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
        ret = TRUE; /* Success, but empty */
      else
        g_propagate_error (error, g_steal_pointer (&my_error));
      goto out;
    }

  while ((child_info = g_file_enumerator_next_file (dir_enum, cancellable, &temp_error)) != NULL)
    {
      const char *name;

      name = g_file_info_get_name (child_info);

      g_clear_object (&child);
      child = g_file_get_child (deploy_base, name);

      if (g_file_info_get_file_type (child_info) == G_FILE_TYPE_DIRECTORY &&
          name[0] != '.' &&
          strlen (name) == 64)
        g_ptr_array_add (ids, g_strdup (name));

      g_clear_object (&child_info);
    }

  if (temp_error != NULL)
    {
      g_propagate_error (error, temp_error);
      goto out;
    }

  ret = TRUE;

out:
  if (ret)
    {
      g_ptr_array_add (ids, NULL);
      *deployed_ids = (char **) g_ptr_array_free (g_steal_pointer (&ids), FALSE);
    }

  return ret;
}

static gboolean
dir_is_locked (GFile *dir)
{
  glnx_autofd int ref_fd = -1;
  struct flock lock = {0};
  g_autoptr(GFile) reffile = NULL;

  reffile = g_file_resolve_relative_path (dir, "files/.ref");

  ref_fd = open (flatpak_file_get_path_cached (reffile), O_RDWR | O_CLOEXEC);
  if (ref_fd != -1)
    {
      lock.l_type = F_WRLCK;
      lock.l_whence = SEEK_SET;
      lock.l_start = 0;
      lock.l_len = 0;

      if (fcntl (ref_fd, F_GETLK, &lock) == 0)
        return lock.l_type != F_UNLCK;
    }

  return FALSE;
}

gboolean
flatpak_dir_undeploy (FlatpakDir        *self,
                      FlatpakDecomposed *ref,
                      const char        *active_id,
                      gboolean           is_update,
                      gboolean           force_remove,
                      GCancellable      *cancellable,
                      GError           **error)
{
  g_autoptr(GFile) deploy_base = NULL;
  g_autoptr(GFile) checkoutdir = NULL;
  g_autoptr(GFile) removed_subdir = NULL;
  g_autoptr(GFile) removed_dir = NULL;
  g_autofree char *id = NULL;
  g_autofree char *dirname = NULL;
  g_autofree char *current_active = NULL;
  g_autoptr(GFile) change_file = NULL;
  g_autoptr(GError) child_error = NULL;
  int i, retry;

  g_assert (ref != NULL);
  g_assert (active_id != NULL);

  deploy_base = flatpak_dir_get_deploy_dir (self, ref);

  checkoutdir = g_file_get_child (deploy_base, active_id);
  if (!g_file_query_exists (checkoutdir, cancellable))
    {
      g_set_error (error, FLATPAK_ERROR, FLATPAK_ERROR_NOT_INSTALLED,
                   _("%s commit %s not installed"),
                   flatpak_decomposed_get_ref (ref), active_id);
      return FALSE;
    }

  if (!flatpak_dir_ensure_repo (self, cancellable, error))
    return FALSE;

  current_active = flatpak_dir_read_active (self, ref, cancellable);
  if (current_active != NULL && strcmp (current_active, active_id) == 0)
    {
      g_auto(GStrv) deployed_ids = NULL;
      const char *some_deployment;

      /* We're removing the active deployment, start by repointing that
         to another deployment if one exists */

      if (!flatpak_dir_list_deployed (self, ref,
                                      &deployed_ids,
                                      cancellable, error))
        return FALSE;

      some_deployment = NULL;
      for (i = 0; deployed_ids[i] != NULL; i++)
        {
          if (strcmp (deployed_ids[i], active_id) == 0)
            continue;

          some_deployment = deployed_ids[i];
          break;
        }

      if (!flatpak_dir_set_active (self, ref, some_deployment, cancellable, error))
        return FALSE;
    }

  removed_dir = flatpak_dir_get_removed_dir (self);
  if (!flatpak_mkdir_p (removed_dir, cancellable, error))
    return FALSE;

  id = flatpak_decomposed_dup_id (ref);
  dirname = g_strdup_printf ("%s-%s", id, active_id);

  removed_subdir = g_file_get_child (removed_dir, dirname);

  retry = 0;
  while (TRUE)
    {
      g_autoptr(GError) local_error = NULL;
      g_autoptr(GFile) tmpdir = NULL;
      g_autofree char *tmpname = NULL;

      if (flatpak_file_rename (checkoutdir,
                               removed_subdir,
                               cancellable, &local_error))
        break;

      if (!g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_EXISTS) || retry >= 10)
        {
          g_propagate_error (error, g_steal_pointer (&local_error));
          return FALSE;
        }

      retry++;

      /* Destination already existed, move that aside, as we want to use the exact
       * removed dirname for the latest undeployed version */

      tmpname = g_strdup_printf ("%s-XXXXXX", dirname);
      glnx_gen_temp_name (tmpname);
      tmpdir = g_file_get_child (removed_dir, tmpname);

      if (!flatpak_file_rename (removed_subdir,
                                tmpdir,
                                cancellable, error))
        return FALSE;
    }


  if (is_update)
    change_file = g_file_resolve_relative_path (removed_subdir, "files/.updated");
  else
    change_file = g_file_resolve_relative_path (removed_subdir, "files/.removed");

  if (!g_file_replace_contents (change_file, "", 0, NULL, FALSE,
                                G_FILE_CREATE_REPLACE_DESTINATION, NULL, NULL, &child_error))
    {
      g_autofree gchar *path = g_file_get_path (change_file);
      g_warning ("Unable to clear %s: %s", path, child_error->message);
      g_clear_error (&child_error);
    }

  if (force_remove || !dir_is_locked (removed_subdir))
    {
      g_autoptr(GError) tmp_error = NULL;

      if (!flatpak_rm_rf (removed_subdir, cancellable, &tmp_error))
        g_warning ("Unable to remove old checkout: %s", tmp_error->message);
    }

  return TRUE;
}

gboolean
flatpak_dir_undeploy_all (FlatpakDir        *self,
                          FlatpakDecomposed *ref,
                          gboolean           force_remove,
                          gboolean          *was_deployed_out,
                          GCancellable      *cancellable,
                          GError           **error)
{
  g_auto(GStrv) deployed = NULL;
  g_autoptr(GFile) deploy_base = NULL;
  g_autoptr(GFile) arch_dir = NULL;
  g_autoptr(GFile) top_dir = NULL;
  GError *temp_error = NULL;
  int i;
  gboolean was_deployed;

  if (!flatpak_dir_list_deployed (self, ref, &deployed, cancellable, error))
    return FALSE;

  for (i = 0; deployed[i] != NULL; i++)
    {
      g_info ("undeploying %s", deployed[i]);
      if (!flatpak_dir_undeploy (self, ref, deployed[i], FALSE, force_remove, cancellable, error))
        return FALSE;
    }

  deploy_base = flatpak_dir_get_deploy_dir (self, ref);
  was_deployed = g_file_query_exists (deploy_base, cancellable);
  if (was_deployed)
    {
      g_info ("removing deploy base");
      if (!flatpak_rm_rf (deploy_base, cancellable, error))
        return FALSE;
    }

  g_info ("cleaning up empty directories");
  arch_dir = g_file_get_parent (deploy_base);
  if (g_file_query_exists (arch_dir, cancellable) &&
      !g_file_delete (arch_dir, cancellable, &temp_error))
    {
      if (!g_error_matches (temp_error, G_IO_ERROR, G_IO_ERROR_NOT_EMPTY))
        {
          g_propagate_error (error, temp_error);
          return FALSE;
        }
      g_clear_error (&temp_error);
    }

  top_dir = g_file_get_parent (arch_dir);
  if (g_file_query_exists (top_dir, cancellable) &&
      !g_file_delete (top_dir, cancellable, &temp_error))
    {
      if (!g_error_matches (temp_error, G_IO_ERROR, G_IO_ERROR_NOT_EMPTY))
        {
          g_propagate_error (error, temp_error);
          return FALSE;
        }
      g_clear_error (&temp_error);
    }

  if (was_deployed_out)
    *was_deployed_out = was_deployed;

  return TRUE;
}

/**
 * flatpak_dir_remove_ref:
 * @self: a #FlatpakDir
 * @remote_name: the name of the remote
 * @ref: the flatpak ref to remove
 * @cancellable: (nullable) (optional): a #GCancellable
 * @error: a #GError
 *
 * Remove the flatpak ref given by @remote_name:@ref from the underlying
 * OSTree repo. Attempting to remove a ref that is currently deployed
 * is an error, you need to uninstall the flatpak first. Note that this does
 * not remove the objects bound to @ref from the disk, you will need to
 * call flatpak_dir_prune() to do that.
 *
 * Returns: %TRUE if removing the ref succeeded, %FALSE otherwise.
 */
gboolean
flatpak_dir_remove_ref (FlatpakDir        *self,
                        const char        *remote_name,
                        const char        *ref, /* NOTE: Not necessarily a app/runtime ref */
                        GCancellable      *cancellable,
                        GError           **error)
{
  if (flatpak_dir_use_system_helper (self, NULL))
    {
      const char *installation = flatpak_dir_get_id (self);

      if (!flatpak_dir_system_helper_call_remove_local_ref (self,
                                                            FLATPAK_HELPER_REMOVE_LOCAL_REF_FLAGS_NONE,
                                                            remote_name,
                                                            ref,
                                                            installation ? installation : "",
                                                            cancellable,
                                                            error))
        return FALSE;

      return TRUE;
    }

  if (!ostree_repo_set_ref_immediate (self->repo,
                                      remote_name,
                                      ref,
                                      NULL,
                                      cancellable,
                                      error))
    return FALSE;

  return TRUE;
}

gboolean
flatpak_dir_cleanup_removed (FlatpakDir   *self,
                             GCancellable *cancellable,
                             GError      **error)
{
  gboolean ret = FALSE;
  g_autoptr(GFile) removed_dir = NULL;
  g_autoptr(GFileEnumerator) dir_enum = NULL;
  g_autoptr(GFileInfo) child_info = NULL;
  GError *temp_error = NULL;

  removed_dir = flatpak_dir_get_removed_dir (self);
  if (!g_file_query_exists (removed_dir, cancellable))
    return TRUE;

  dir_enum = g_file_enumerate_children (removed_dir, OSTREE_GIO_FAST_QUERYINFO,
                                        G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
                                        cancellable,
                                        error);
  if (!dir_enum)
    goto out;

  while ((child_info = g_file_enumerator_next_file (dir_enum, cancellable, &temp_error)) != NULL)
    {
      const char *name = g_file_info_get_name (child_info);
      g_autoptr(GFile) child = g_file_get_child (removed_dir, name);

      if (g_file_info_get_file_type (child_info) == G_FILE_TYPE_DIRECTORY &&
          !dir_is_locked (child))
        {
          g_autoptr(GError) tmp_error = NULL;
          if (!flatpak_rm_rf (child, cancellable, &tmp_error))
            g_warning ("Unable to remove old checkout: %s", tmp_error->message);
        }

      g_clear_object (&child_info);
    }

  if (temp_error != NULL)
    {
      g_propagate_error (error, temp_error);
      goto out;
    }

  ret = TRUE;
out:
  return ret;
}

gboolean
flatpak_dir_prune (FlatpakDir   *self,
                   GCancellable *cancellable,
                   GError      **error)
{
  gboolean ret = FALSE;
  gint objects_total, objects_pruned;
  guint64 pruned_object_size_total;
  g_autofree char *formatted_freed_size = NULL;
  g_autoptr(GError) local_error = NULL;
  g_autoptr(GError) lock_error = NULL;
  g_auto(GLnxLockFile) lock = { 0, };

  if (error == NULL)
    error = &local_error;

  if (flatpak_dir_use_system_helper (self, NULL))
    {
      const char *installation = flatpak_dir_get_id (self);

      if (!flatpak_dir_system_helper_call_prune_local_repo (self,
                                                            FLATPAK_HELPER_PRUNE_LOCAL_REPO_FLAGS_NONE,
                                                            installation ? installation : "",
                                                            cancellable,
                                                            error))
        return FALSE;

      return TRUE;
    }

  if (!flatpak_dir_ensure_repo (self, cancellable, error))
    goto out;

  /* This could remove objects, so take an exclusive repo lock */
  if (!flatpak_dir_repo_lock (self, &lock, LOCK_EX | LOCK_NB, cancellable, &lock_error))
    {
      /* If we can't get an exclusive lock, don't block for a long time. Eventually
         the shared lock operation is released and we will do a prune then */
      if (g_error_matches (lock_error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK))
        {
          g_info ("Skipping prune due to in progress operation");
          return TRUE;
        }

      g_propagate_error (error, g_steal_pointer (&lock_error));
      return FALSE;
    }

  g_info ("Pruning repo");
  if (!ostree_repo_prune (self->repo,
                          OSTREE_REPO_PRUNE_FLAGS_REFS_ONLY,
                          0,
                          &objects_total,
                          &objects_pruned,
                          &pruned_object_size_total,
                          cancellable, error))
    goto out;

  formatted_freed_size = g_format_size_full (pruned_object_size_total, 0);
  g_info ("Pruned %d/%d objects, size %s", objects_total, objects_pruned, formatted_freed_size);

  ret = TRUE;

out:

  /* There was an issue in ostree where for local pulls we don't get a .commitpartial (now fixed),
     which caused errors when pruning. We print these here, but don't stop processing. */
  if (local_error != NULL)
    g_print (_("Pruning repo failed: %s"), local_error->message);

  return ret;
}

gboolean
flatpak_dir_update_summary (FlatpakDir   *self,
                            gboolean      delete,
                            GCancellable *cancellable,
                            GError      **error)
{
  if (flatpak_dir_use_system_helper (self, NULL))
    {
      const char *installation = flatpak_dir_get_id (self);

      return flatpak_dir_system_helper_call_update_summary (self,
                                                            delete ? FLATPAK_HELPER_UPDATE_SUMMARY_FLAGS_DELETE
                                                                   : FLATPAK_HELPER_UPDATE_SUMMARY_FLAGS_NONE,
                                                            installation ? installation : "",
                                                            cancellable,
                                                            error);
    }

  if (!flatpak_dir_ensure_repo (self, cancellable, error))
    return FALSE;

  if (delete)
    {
      g_autoptr(GError) local_error = NULL;
      g_autoptr(GFile) summary_file = NULL;

      g_info ("Deleting summary");

      summary_file = g_file_get_child (ostree_repo_get_path (self->repo), "summary");

      if (!g_file_delete (summary_file, cancellable, &local_error) &&
          !g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
        {
          g_propagate_error (error, g_steal_pointer (&local_error));
          return FALSE;
        }
      return TRUE;
    }
  else
    {
      g_auto(GLnxLockFile) lock = { 0, };

      g_info ("Updating summary");

      /* Keep a shared repo lock to avoid prunes removing objects we're relying on
       * while generating the summary. */
      if (!flatpak_dir_repo_lock (self, &lock, LOCK_SH, cancellable, error))
        return FALSE;

      return ostree_repo_regenerate_summary (self->repo, NULL, cancellable, error);
    }
}

GFile *
flatpak_dir_get_if_deployed (FlatpakDir        *self,
                             FlatpakDecomposed *ref,
                             const char        *checksum,
                             GCancellable      *cancellable)
{
  g_autoptr(GFile) deploy_base = NULL;
  g_autoptr(GFile) deploy_dir = NULL;

  deploy_base = flatpak_dir_get_deploy_dir (self, ref);

  if (checksum != NULL)
    {
      deploy_dir = g_file_get_child (deploy_base, checksum);
    }
  else
    {
      g_autoptr(GFile) active_link = g_file_get_child (deploy_base, "active");
      g_autoptr(GFileInfo) info = NULL;
      const char *target;

      info = g_file_query_info (active_link,
                                G_FILE_ATTRIBUTE_STANDARD_TYPE "," G_FILE_ATTRIBUTE_STANDARD_SYMLINK_TARGET,
                                G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
                                NULL,
                                NULL);
      if (info == NULL)
        return NULL;

      target = g_file_info_get_symlink_target (info);
      if (target == NULL)
        return NULL;

      deploy_dir = g_file_get_child (deploy_base, target);
    }

  if (g_file_query_file_type (deploy_dir, G_FILE_QUERY_INFO_NONE, cancellable) == G_FILE_TYPE_DIRECTORY)
    return g_steal_pointer (&deploy_dir);

  /* Maybe it was removed but is still living? */
  if (checksum != NULL)
    {
      g_autoptr(GFile) removed_dir = flatpak_dir_get_removed_dir (self);
      g_autoptr(GFile) removed_deploy_dir = NULL;
      g_autofree char *id = flatpak_decomposed_dup_id (ref);
      g_autofree char *dirname = NULL;

      dirname = g_strdup_printf ("%s-%s", id, checksum);
      removed_deploy_dir = g_file_get_child (removed_dir, dirname);

      if (g_file_query_file_type (removed_deploy_dir, G_FILE_QUERY_INFO_NONE, cancellable) == G_FILE_TYPE_DIRECTORY)
        return g_steal_pointer (&removed_deploy_dir);
    }

  return NULL;
}

GFile *
flatpak_dir_get_unmaintained_extension_dir_if_exists (FlatpakDir   *self,
                                                      const char   *name,
                                                      const char   *arch,
                                                      const char   *branch,
                                                      GCancellable *cancellable)
{
  g_autoptr(GFile) extension_dir = NULL;
  g_autoptr(GFileInfo) extension_dir_info = NULL;

  extension_dir = flatpak_dir_get_unmaintained_extension_dir (self, name, arch, branch);

  extension_dir_info = g_file_query_info (extension_dir,
                                          G_FILE_ATTRIBUTE_STANDARD_SYMLINK_TARGET "," G_FILE_ATTRIBUTE_STANDARD_IS_SYMLINK,
                                          G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
                                          cancellable,
                                          NULL);
  if (extension_dir_info == NULL)
    return NULL;

  if (g_file_info_get_is_symlink (extension_dir_info))
    return g_file_new_for_path (g_file_info_get_symlink_target (extension_dir_info));
  else
    return g_steal_pointer (&extension_dir);
}

static void
remote_filter_free (RemoteFilter *remote_filter)
{
  g_free (remote_filter->checksum);
  g_object_unref (remote_filter->path);
  if (remote_filter->allow)
    g_regex_unref (remote_filter->allow);
  if (remote_filter->deny)
    g_regex_unref (remote_filter->deny);

  g_free (remote_filter);
}


static RemoteFilter *
remote_filter_load (GFile *path, GError **error)
{
  RemoteFilter *filter;
  g_autofree char *data = NULL;
  gsize data_size;
  GTimeVal mtime;
  g_autoptr(GRegex) allow_refs = NULL;
  g_autoptr(GRegex) deny_refs = NULL;

  /* Save mtime before loading to avoid races */
  if (!get_mtime (path, &mtime, NULL, error))
    {
      glnx_prefix_error (error, _("Failed to load filter '%s'"), flatpak_file_get_path_cached (path));
      return NULL;
    }

  if (!g_file_load_contents (path, NULL, &data, &data_size, NULL, error))
    {
      glnx_prefix_error (error, _("Failed to load filter '%s'"), flatpak_file_get_path_cached (path));
      return NULL;
    }

  if (!flatpak_parse_filters (data, &allow_refs, &deny_refs, error))
    {
      glnx_prefix_error (error, _("Failed to parse filter '%s'"), flatpak_file_get_path_cached (path));
      return NULL;
    }

  filter = g_new0 (RemoteFilter, 1);
  filter->checksum = g_compute_checksum_for_data (G_CHECKSUM_SHA256, (guchar *)data, data_size);
  filter->path = g_object_ref (path);
  filter->mtime = mtime;
  filter->last_mtime_check = g_get_monotonic_time ();
  filter->allow = g_steal_pointer (&allow_refs);
  filter->deny = g_steal_pointer (&deny_refs);

  return filter;
}

G_LOCK_DEFINE_STATIC (filters);

static gboolean
flatpak_dir_lookup_remote_filter (FlatpakDir *self,
                                  const char *name,
                                  gboolean    force_load,
                                  char      **checksum_out,
                                  GRegex    **allow_regex,
                                  GRegex    **deny_regex,
                                  GError **error)
{
  RemoteFilter *filter = NULL;
  g_autofree char *filter_path = NULL;
  gboolean handled_fallback = FALSE;
  g_autoptr(GFile) filter_file = NULL;

  if (checksum_out)
    *checksum_out = NULL;
  *allow_regex = NULL;
  *deny_regex = NULL;

  filter_path = flatpak_dir_get_remote_filter (self, name);

  if (filter_path == NULL)
    return TRUE;

  filter_file = g_file_new_for_path (filter_path);

  G_LOCK (filters);

  if (self->remote_filters == NULL)
    self->remote_filters = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) remote_filter_free);

  filter = g_hash_table_lookup (self->remote_filters, name);
  if (filter)
    {
      guint64 now = g_get_monotonic_time ();
      GTimeVal mtime;

      if (g_file_equal (filter->path, filter_file) != 0)
        filter = NULL; /* New path, reload */
      else if ((now - filter->last_mtime_check) > (1000 * (FILTER_MTIME_CHECK_TIMEOUT_MSEC)))
        {
          /* Fall back to backup copy if remote filter disappears */
          handled_fallback = TRUE;
          if (!g_file_query_exists (filter_file, NULL))
            {
              g_autofree char *basename = g_strconcat (name, ".filter", NULL);
              g_object_unref (filter_file);
              filter_file = flatpak_build_file (self->basedir, "repo", basename, NULL);
            }

          filter->last_mtime_check = now;
          if (!get_mtime (filter_file, &mtime, NULL, NULL) ||
              mtime.tv_sec != filter->mtime.tv_sec ||
              mtime.tv_usec != filter->mtime.tv_usec)
            filter = NULL; /* Different mtime, reload */
        }
    }

  if (filter)
    {
      if (checksum_out)
        *checksum_out = g_strdup (filter->checksum);
      if (filter->allow)
        *allow_regex = g_regex_ref (filter->allow);
      if (filter->deny)
        *deny_regex = g_regex_ref (filter->deny);
    }

  G_UNLOCK (filters);

  if (filter) /* This is outside the lock, but we already copied the returned data, and we're not dereferencing filter */
    return TRUE;

  /* Fall back to backup copy if remote filter disappears */
  if (!handled_fallback && !g_file_query_exists (filter_file, NULL))
    {
      g_autofree char *basename = g_strconcat (name, ".filter", NULL);
      g_object_unref (filter_file);
      filter_file = flatpak_build_file (self->basedir, "repo", basename, NULL);
    }

  filter = remote_filter_load (filter_file, error);
  if (filter == NULL)
    return FALSE;

  if (checksum_out)
    *checksum_out = g_strdup (filter->checksum);
  if (filter->allow)
    *allow_regex = g_regex_ref (filter->allow);
  if (filter->deny)
    *deny_regex = g_regex_ref (filter->deny);

  G_LOCK (filters);
  g_hash_table_replace (self->remote_filters, g_strdup (name), filter);
  G_UNLOCK (filters);

  return TRUE;
}

G_LOCK_DEFINE_STATIC (cache);

/* FIXME: Move all this caching into libostree. */
static void
cached_summary_free (CachedSummary *summary)
{
  g_bytes_unref (summary->bytes);
  if (summary->bytes_sig)
    g_bytes_unref (summary->bytes_sig);
  g_free (summary->name);
  g_free (summary->url);
  g_free (summary);
}

static CachedSummary *
cached_summary_new (GBytes     *bytes,
                    GBytes     *bytes_sig,
                    const char *name,
                    const char *url)
{
  CachedSummary *summary = g_new0 (CachedSummary, 1);

  summary->bytes = g_bytes_ref (bytes);
  if (bytes_sig)
    summary->bytes_sig = g_bytes_ref (bytes_sig);
  summary->url = g_strdup (url);
  summary->name = g_strdup (name);
  summary->time = g_get_monotonic_time ();
  return summary;
}

static gboolean
flatpak_dir_lookup_cached_summary (FlatpakDir *self,
                                   GBytes    **bytes_out,
                                   GBytes    **bytes_sig_out,
                                   const char *name,
                                   const char *url)
{
  CachedSummary *summary;
  gboolean res = FALSE;

  G_LOCK (cache);

  if (self->summary_cache == NULL)
    self->summary_cache = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, (GDestroyNotify) cached_summary_free);

  summary = g_hash_table_lookup (self->summary_cache, name);
  if (summary)
    {
      guint64 now = g_get_monotonic_time ();
      if ((now - summary->time) / G_USEC_PER_SEC < SUMMARY_CACHE_TIMEOUT_SEC &&
          strcmp (url, summary->url) == 0)
        {
          /* g_info ("Using cached summary for remote %s", name); */
          *bytes_out = g_bytes_ref (summary->bytes);
          if (bytes_sig_out)
            {
              if (summary->bytes_sig)
                *bytes_sig_out = g_bytes_ref (summary->bytes_sig);
              else
                *bytes_sig_out = NULL;
            }
          res = TRUE;

          /* Bump the cache expiry time */
          summary->time = now;
        }
      else
        {
          /* Timed out or URL has changed; remove the entry */
          g_hash_table_remove (self->summary_cache, name);
          res = FALSE;
        }
    }

  G_UNLOCK (cache);

  return res;
}

static void
flatpak_dir_cache_summary (FlatpakDir *self,
                           GBytes     *bytes,
                           GBytes     *bytes_sig,
                           const char *name,
                           const char *url)
{
  CachedSummary *summary;

  /* No sense caching the summary if there isn't one */
  if (!bytes)
    return;

  G_LOCK (cache);

  /* This was already initialized in the cache-miss lookup */
  g_assert (self->summary_cache != NULL);

  summary = cached_summary_new (bytes, bytes_sig, name, url);
  g_hash_table_replace (self->summary_cache, summary->name, summary);

  G_UNLOCK (cache);
}

gboolean
flatpak_dir_remote_make_oci_summary (FlatpakDir   *self,
                                     const char   *remote,
                                     gboolean      only_cached,
                                     GBytes      **out_summary,
                                     GCancellable *cancellable,
                                     GError      **error)
{
  g_autoptr(GVariant) summary = NULL;
  g_autoptr(GFile) index_cache = NULL;
  g_autofree char *index_uri = NULL;
  g_autoptr(GFile) summary_cache = NULL;
  g_autoptr(GError) local_error = NULL;
  g_autoptr(GMappedFile) mfile = NULL;
  g_autoptr(GBytes) cache_bytes = NULL;
  g_autoptr(GBytes) summary_bytes = NULL;

  if (flatpak_dir_use_system_helper (self, NULL))
    {
      const char *installation = flatpak_dir_get_id (self);
      FlatpakHelperGenerateOciSummaryFlags flags = FLATPAK_HELPER_GENERATE_OCI_SUMMARY_FLAGS_NONE;

      if (only_cached)
        flags |= FLATPAK_HELPER_GENERATE_OCI_SUMMARY_FLAGS_ONLY_CACHED;

      if (!flatpak_dir_system_helper_call_generate_oci_summary (self,
                                                                flags,
                                                                remote,
                                                                installation ? installation : "",
                                                                cancellable, error))
        return FALSE;

      summary_cache = flatpak_dir_get_oci_summary_location (self, remote, error);
      if (summary_cache == NULL)
        return FALSE;
    }
  else
    {
      index_cache = flatpak_dir_update_oci_index (self, remote, &index_uri, cancellable, error);
      if (index_cache == NULL)
        return FALSE;

      summary_cache = flatpak_dir_get_oci_summary_location (self, remote, error);
      if (summary_cache == NULL)
        return FALSE;

      if (!only_cached && !check_destination_mtime (index_cache, summary_cache, cancellable))
        {
          summary = flatpak_oci_index_make_summary (index_cache, index_uri, cancellable, &local_error);
          if (summary == NULL)
            {
              g_propagate_error (error, g_steal_pointer (&local_error));
              return FALSE;
            }

          summary_bytes = g_variant_get_data_as_bytes (summary);

          if (!g_file_replace_contents (summary_cache,
                                        g_bytes_get_data (summary_bytes, NULL),
                                        g_bytes_get_size (summary_bytes),
                                        NULL, FALSE, 0, NULL, cancellable, error))
            {
              g_prefix_error (error, _("Failed to write summary cache: "));
              return FALSE;
            }

          if (out_summary)
            *out_summary = g_steal_pointer (&summary_bytes);
          return TRUE;
        }
    }

  if (out_summary)
    {
      mfile = g_mapped_file_new (flatpak_file_get_path_cached (summary_cache), FALSE, error);
      if (mfile == NULL)
        {
          if (only_cached)
            {
              g_clear_error (error);
              g_set_error (error, FLATPAK_ERROR, FLATPAK_ERROR_NOT_CACHED,
                           _("No oci summary cached for remote '%s'"), remote);
            }

          return FALSE;
        }

      cache_bytes = g_mapped_file_get_bytes (mfile);
      *out_summary = g_steal_pointer (&cache_bytes);
    }

  return TRUE;
}

typedef struct {
  char *filename;
  gint64 mtime;
} CachedSummaryData;

static void
cached_summary_data_free (CachedSummaryData *data)
{
  g_free (data->filename);
  g_free (data);
}

static gboolean
flatpak_dir_gc_cached_digested_summaries (FlatpakDir   *self,
                                          const char   *remote_name,
                                          const char   *dont_prune_file,
                                          GCancellable *cancellable,
                                          GError      **error)
{
  g_autoptr(GHashTable) cached_data_for_arch = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify)cached_summary_data_free);
  g_autoptr(GFile) cache_dir = flatpak_build_file (self->cache_dir, "summaries", NULL);
  g_auto(GLnxDirFdIterator) iter = {0};
  struct dirent *dent;
  g_autoptr(GError) local_error = NULL;

  if (!glnx_dirfd_iterator_init_at (AT_FDCWD, flatpak_file_get_path_cached (cache_dir), FALSE, &iter, &local_error))
    {
      if (g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
        return TRUE;

      g_propagate_error (error, g_steal_pointer (&local_error));
      return FALSE;
    }

  g_autofree char *prefix = g_strconcat (remote_name, "-", NULL);

  while (TRUE)
    {
      struct stat stbuf;
      const char *arch_start, *arch_end;
      g_autofree char *arch = NULL;

      if (!glnx_dirfd_iterator_next_dent_ensure_dtype (&iter, &dent, cancellable, error))
        return FALSE;

      if (dent == NULL)
        break;

      /* Cached are regular file named "${remote-name}-${arch}-${sha256}.sub", ignore anything else */
      if (dent->d_type != DT_REG ||
          !g_str_has_prefix (dent->d_name, prefix) ||
          !g_str_has_suffix (dent->d_name, ".sub"))
        continue;

      arch_start = dent->d_name + strlen (prefix);
      arch_end = strchr (arch_start, '-');
      if (arch_end == NULL)
        continue;

      /* Keep the latest subsummary for each remote-name + arch so we can use it for deltas */
      if (fstatat (iter.fd, dent->d_name, &stbuf, AT_SYMLINK_NOFOLLOW) == -1)
        {
          glnx_set_error_from_errno (error);
          return FALSE;
        }

      arch = g_strndup (arch_start, arch_end - arch_start);

      CachedSummaryData *old_data = g_hash_table_lookup (cached_data_for_arch, arch);
      if (old_data == NULL || stbuf.st_mtime > old_data->mtime)
        {
          CachedSummaryData *new_data;

          if (old_data &&
              strcmp (dont_prune_file, old_data->filename) != 0 &&
              unlinkat (iter.fd, old_data->filename, 0) != 0)
            {
              glnx_set_error_from_errno (error);
              return FALSE;
            }

          new_data = g_new0 (CachedSummaryData, 1);
          new_data->filename = g_strdup (dent->d_name);
          new_data->mtime = stbuf.st_mtime;
          g_hash_table_insert (cached_data_for_arch, g_steal_pointer (&arch), new_data);
        }
      else /* stbuf.st_mtime <= old_data->mtime */
        {
          if (stbuf.st_mtime < old_data->mtime &&
              strcmp (dont_prune_file, dent->d_name) != 0 &&
              unlinkat (iter.fd, dent->d_name, 0) != 0)
            {
              glnx_set_error_from_errno (error);
              return FALSE;
            }
        }
    }

  return TRUE;
}

static gboolean
_flatpak_dir_remote_clear_cached_summary (FlatpakDir   *self,
                                          const char   *remote,
                                          const char   *extension,
                                          GCancellable *cancellable,
                                          GError      **error)
{
  g_autoptr(GFile) cache_dir = flatpak_build_file (self->cache_dir, "summaries", NULL);
  g_autofree char *filename = g_strconcat (remote, extension, NULL);
  g_autoptr(GFile) file = flatpak_build_file (cache_dir, filename, NULL);
  g_autoptr(GError) local_error = NULL;

  if (!g_file_delete (file, NULL, &local_error) &&
      !g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
    {
      g_propagate_error (error, g_steal_pointer (&local_error));
      return FALSE;
    }

  return TRUE;
}

static gboolean
flatpak_dir_remote_clear_cached_summary (FlatpakDir   *self,
                                         const char   *remote,
                                         GCancellable *cancellable,
                                         GError      **error)
{
  g_info ("Clearing cached summaries for remote %s", remote);
  if (!_flatpak_dir_remote_clear_cached_summary (self, remote, NULL, cancellable, error))
    return FALSE;
  if (!_flatpak_dir_remote_clear_cached_summary (self, remote, ".sig", cancellable, error))
    return FALSE;
  if (!_flatpak_dir_remote_clear_cached_summary (self, remote, ".idx", cancellable, error))
    return FALSE;
  if (!_flatpak_dir_remote_clear_cached_summary (self, remote, ".idx.sig", cancellable, error))
    return FALSE;
  return TRUE;
}


static gboolean
flatpak_dir_remote_save_cached_summary (FlatpakDir   *self,
                                        const char   *basename,
                                        const char   *main_ext,
                                        const char   *sig_ext,
                                        GBytes       *main,
                                        GBytes       *sig,
                                        GCancellable *cancellable,
                                        GError      **error)
{
  g_autofree char *main_file_name = g_strconcat (basename, main_ext, NULL);
  g_autofree char *sig_file_name = g_strconcat (basename, sig_ext, NULL);
  g_autoptr(GFile) cache_dir = flatpak_build_file (self->cache_dir, "summaries", NULL);
  g_autoptr(GFile) main_cache_file = flatpak_build_file (cache_dir, main_file_name, NULL);
  g_autoptr(GFile) sig_cache_file = flatpak_build_file (cache_dir, sig_file_name, NULL);
  g_autoptr(GError) local_error = NULL;

  if (!flatpak_mkdir_p (cache_dir, cancellable, error))
    return FALSE;

  if (!g_file_replace_contents (main_cache_file, g_bytes_get_data (main, NULL), g_bytes_get_size (main), NULL, FALSE,
                                G_FILE_CREATE_REPLACE_DESTINATION, NULL, cancellable, error))
    return FALSE;

  if (sig_ext)
    {
      if (sig)
        {
          if (!g_file_replace_contents (sig_cache_file, g_bytes_get_data (sig, NULL), g_bytes_get_size (sig), NULL, FALSE,
                                        G_FILE_CREATE_REPLACE_DESTINATION, NULL, cancellable, error))
            return FALSE;
        }
      else
        {
          if (!g_file_delete (sig_cache_file, NULL, &local_error) &&
              !g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
            {
              g_propagate_error (error, g_steal_pointer (&local_error));
              return FALSE;
            }
        }
    }

  return TRUE;
}

static gboolean
flatpak_dir_remote_load_cached_summary (FlatpakDir   *self,
                                        const char   *basename,
                                        const char   *checksum,
                                        const char   *main_ext,
                                        const char   *sig_ext,
                                        GBytes      **out_main,
                                        GBytes      **out_sig,
                                        GCancellable *cancellable,
                                        GError      **error)
{
  g_autofree char *main_file_name = g_strconcat (basename, main_ext, NULL);
  g_autofree char *sig_file_name = g_strconcat (basename, sig_ext, NULL);
  g_autoptr(GFile) main_cache_file = flatpak_build_file (self->cache_dir, "summaries", main_file_name, NULL);
  g_autoptr(GFile) sig_cache_file = flatpak_build_file (self->cache_dir, "summaries", sig_file_name, NULL);
  g_autoptr(GMappedFile) mfile = NULL;
  g_autoptr(GMappedFile) sig_mfile = NULL;
  g_autoptr(GBytes) mfile_bytes = NULL;
  g_autofree char *sha256 = NULL;

  mfile = g_mapped_file_new (flatpak_file_get_path_cached (main_cache_file), FALSE, NULL);
  if (mfile == NULL)
    {
      g_set_error (error, FLATPAK_ERROR, FLATPAK_ERROR_NOT_CACHED,
                   _("No cached summary for remote '%s'"), basename);
      return FALSE;
    }

  if (out_sig)
    sig_mfile = g_mapped_file_new (flatpak_file_get_path_cached (sig_cache_file), FALSE, NULL);

  mfile_bytes = g_mapped_file_get_bytes (mfile);

  /* The checksum would've already been verified before the file was written,
   * but check again in case something went wrong during disk I/O. This is
   * especially important since the variant-schema-compiler code assumes the
   * GVariant data is well formed and asserts otherwise.
   */
  if (checksum != NULL)
    {
      sha256 = g_compute_checksum_for_bytes (G_CHECKSUM_SHA256, mfile_bytes);
      if (strcmp (sha256, checksum) != 0)
        {
          g_autoptr(GError) local_error = NULL;

          if (!g_file_delete (main_cache_file, NULL, &local_error) &&
              !g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
            {
              g_autofree char *path = g_file_get_path (main_cache_file);
              g_info ("Unable to delete file %s: %s", path, local_error->message);
              g_clear_error (&local_error);
            }

          if (sig_ext)
            {
              if (!g_file_delete (sig_cache_file, NULL, &local_error) &&
                  !g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
                {
                  g_autofree char *path = g_file_get_path (sig_cache_file);
                  g_info ("Unable to delete file %s: %s", path, local_error->message);
                  g_clear_error (&local_error);
                }
            }

          return flatpak_fail_error (error, FLATPAK_ERROR_INVALID_DATA,
                                     _("Invalid checksum for indexed summary %s read from %s"),
                                     checksum, flatpak_file_get_path_cached (main_cache_file));
        }
    }

  *out_main = g_steal_pointer (&mfile_bytes);
  if (sig_mfile)
    *out_sig = g_mapped_file_get_bytes (sig_mfile);

  return TRUE;
}

static gboolean
flatpak_dir_remote_fetch_summary (FlatpakDir   *self,
                                  const char   *name_or_uri,
                                  gboolean      only_cached,
                                  GBytes      **out_summary,
                                  GBytes      **out_summary_sig,
                                  GCancellable *cancellable,
                                  GError      **error)
{
  g_autofree char *url = NULL;
  gboolean is_local;
  g_autoptr(GError) local_error = NULL;
  g_autoptr(GBytes) summary = NULL;
  g_autoptr(GBytes) summary_sig = NULL;

  if (!ostree_repo_remote_get_url (self->repo, name_or_uri, &url, error))
    return FALSE;

  if (!g_str_has_prefix (name_or_uri, "file:") && flatpak_dir_get_remote_disabled (self, name_or_uri))
    {
      g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA,
                   "Can't fetch summary from disabled remote ‘%s’", name_or_uri);
      return FALSE;
    }

  is_local = g_str_has_prefix (url, "file:");

  /* Seems ostree asserts if this is NULL */
  if (error == NULL)
    error = &local_error;

  if (flatpak_dir_get_remote_oci (self, name_or_uri))
    {
      if (!flatpak_dir_remote_make_oci_summary (self, name_or_uri,
                                                only_cached,
                                                &summary,
                                                cancellable,
                                                error))
        return FALSE;
    }
  else
    {
      if (only_cached)
        {
          if (!flatpak_dir_remote_load_cached_summary (self, name_or_uri, NULL, NULL, ".sig",
                                                       &summary, &summary_sig, cancellable, error))
            return FALSE;
          g_info ("Loaded summary from cache for remote ‘%s’", name_or_uri);
        }
      else
        {
          g_info ("Fetching summary file for remote ‘%s’", name_or_uri);
          if (!ostree_repo_remote_fetch_summary (self->repo, name_or_uri,
                                                 &summary, &summary_sig,
                                                 cancellable,
                                                 error))
            return FALSE;
        }
    }

  if (summary == NULL)
    return flatpak_fail_error (error, FLATPAK_ERROR_INVALID_DATA, _("Remote listing for %s not available; server has no summary file. Check the URL passed to remote-add was valid."), name_or_uri);

  if (!is_local && !only_cached)
    {
      g_autofree char *cache_key = g_strconcat ("summary-", name_or_uri, NULL);
      flatpak_dir_cache_summary (self, summary, summary_sig, cache_key, url);
    }

  *out_summary = g_steal_pointer (&summary);
  if (out_summary_sig)
    *out_summary_sig = g_steal_pointer (&summary_sig);

  return TRUE;
}

static gboolean
remote_verify_signature (OstreeRepo *repo,
                         const char *remote_name,
                         GBytes *data,
                         GBytes *sig_file,
                         GCancellable *cancellable,
                         GError **error)
{
  g_autoptr(GVariant) signatures_variant = NULL;
  g_autoptr(GVariant) signaturedata = NULL;
  g_autoptr (GBytes) signatures = NULL;
  g_autoptr(GByteArray) buffer = NULL;
  g_autoptr(OstreeGpgVerifyResult) verify_result = NULL;
  GVariantIter iter;
  GVariant *child;

  signatures_variant = g_variant_new_from_bytes (OSTREE_SUMMARY_SIG_GVARIANT_FORMAT,
                                                 sig_file, FALSE);
  signaturedata = g_variant_lookup_value (signatures_variant, "ostree.gpgsigs", G_VARIANT_TYPE ("aay"));
  if (signaturedata == NULL)
    {
      g_set_error_literal (error, OSTREE_GPG_ERROR, OSTREE_GPG_ERROR_NO_SIGNATURE,
                           "GPG verification enabled, but no signatures found (use gpg-verify=false in remote config to disable)");
      return FALSE;
    }

  buffer = g_byte_array_new ();
  g_variant_iter_init (&iter, signaturedata);
  while ((child = g_variant_iter_next_value (&iter)) != NULL)
    {
      g_byte_array_append (buffer,
                           g_variant_get_data (child),
                           g_variant_get_size (child));
      g_variant_unref (child);
    }
  signatures = g_byte_array_free_to_bytes (g_steal_pointer (&buffer));

  verify_result = ostree_repo_gpg_verify_data (repo,
                                               remote_name,
                                               data,
                                               signatures,
                                               NULL, NULL,
                                               cancellable, error);
  if (!ostree_gpg_verify_result_require_valid_signature (verify_result, error))
    return FALSE;

  return TRUE;
}

static GBytes *
load_uri_with_fallback (FlatpakHttpSession    *http_session,
                        const char            *uri,
                        const char            *uri2,
                        FlatpakHTTPFlags       flags,
                        const char            *token,
                        GCancellable          *cancellable,
                        GError               **error)
{
  g_autoptr(GError) local_error = NULL;
  GBytes *res;

  res = flatpak_load_uri (http_session, uri, flags, token,
                          NULL, NULL, NULL,
                          cancellable, &local_error);
  if (res)
    return res;

  if (!g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
    {
      g_propagate_error (error, g_steal_pointer (&local_error));
      return NULL;
    }

  return flatpak_load_uri (http_session, uri2, flags, token,
                           NULL, NULL, NULL,
                           cancellable, error);
}

static gboolean
flatpak_dir_remote_fetch_summary_index (FlatpakDir   *self,
                                        const char   *name_or_uri,
                                        gboolean      only_cached,
                                        GBytes      **out_index,
                                        GBytes      **out_index_sig,
                                        GCancellable *cancellable,
                                        GError      **error)
{
  g_autofree char *url = NULL;
  gboolean is_local;
  g_autoptr(GError) local_error = NULL;
  g_autoptr(GError) cache_error = NULL;
  g_autoptr(GBytes) cached_index = NULL;
  g_autoptr(GBytes) cached_index_sig = NULL;
  g_autoptr(GBytes) index = NULL;
  g_autoptr(GBytes) index_sig = NULL;
  gboolean gpg_verify_summary;

  ensure_http_session (self);

  if (!ostree_repo_remote_get_url (self->repo, name_or_uri, &url, error))
    return FALSE;

  if (!ostree_repo_remote_get_gpg_verify_summary (self->repo, name_or_uri, &gpg_verify_summary, NULL))
    return FALSE;

  if (!g_str_has_prefix (name_or_uri, "file:") && flatpak_dir_get_remote_disabled (self, name_or_uri))
    {
      g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA,
                   "Can't fetch summary from disabled remote ‘%s’", name_or_uri);
      return FALSE;
    }

  if (flatpak_dir_get_remote_oci (self, name_or_uri))
    {
      g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND,
                   "No index in OCI remote ‘%s’", name_or_uri);
      return FALSE;
    }

  is_local = g_str_has_prefix (url, "file:");

  /* Seems ostree asserts if this is NULL */
  if (error == NULL)
    error = &local_error;

  flatpak_dir_remote_load_cached_summary (self, name_or_uri, NULL, ".idx", ".idx.sig",
                                          &cached_index, &cached_index_sig, cancellable, &cache_error);

  if (only_cached)
    {
      if (cached_index == NULL)
        {
          g_propagate_error (error, g_steal_pointer (&cache_error));
          return FALSE;
        }
      g_info ("Loaded summary index from cache for remote ‘%s’", name_or_uri);

      index = g_steal_pointer (&cached_index);
      if (gpg_verify_summary)
        index_sig = g_steal_pointer (&cached_index_sig);
    }
  else
    {
      g_autofree char *index_url = g_build_filename (url, "summary.idx", NULL);
      g_autoptr(GBytes) dl_index = NULL;
      gboolean used_download = FALSE;

      g_info ("Fetching summary index file for remote ‘%s’", name_or_uri);

      dl_index = flatpak_load_uri (self->http_session, index_url, 0, NULL,
                                   NULL, NULL, NULL,
                                   cancellable, error);
      if (dl_index == NULL)
        return FALSE;

      /* If the downloaded index is the same as the cached one we need not re-download or
       * re-verify, just use the cache (which we verified before) */
      if (cached_index != NULL && g_bytes_equal (cached_index, dl_index))
        {
          index = g_steal_pointer (&cached_index);
          if (gpg_verify_summary)
            index_sig = g_steal_pointer (&cached_index_sig);
        }
      else
        {
          index = g_steal_pointer (&dl_index);
          used_download = TRUE;
        }

      if (gpg_verify_summary && index_sig == NULL)
        {
          g_autofree char *index_digest = g_compute_checksum_for_bytes (G_CHECKSUM_SHA256, index);
          g_autofree char *index_sig_filename = g_strconcat (index_digest, ".idx.sig", NULL);
          g_autofree char *index_sig_url = g_build_filename (url, "summaries", index_sig_filename, NULL);
          g_autofree char *index_sig_url2 = g_build_filename (url, "summary.idx.sig", NULL);
          g_autoptr(GError) dl_sig_error = NULL;
          g_autoptr (GBytes) dl_index_sig = NULL;

          dl_index_sig = load_uri_with_fallback (self->http_session, index_sig_url, index_sig_url2, 0, NULL,
                                                 cancellable, &dl_sig_error);
          if (dl_index_sig == NULL)
            {
              if (g_error_matches (dl_sig_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
                g_set_error (error, OSTREE_GPG_ERROR, OSTREE_GPG_ERROR_NO_SIGNATURE,
                             "GPG verification enabled, but no summary signatures found (use gpg-verify-summary=false in remote config to disable)");
              else
                g_propagate_error (error, g_steal_pointer (&dl_sig_error));

              return FALSE;
            }

          if (!remote_verify_signature (self->repo, name_or_uri,
                                        index, dl_index_sig,
                                        cancellable, error))
            return FALSE;

          index_sig = g_steal_pointer (&dl_index_sig);
          used_download = TRUE;
        }

      g_assert (index != NULL);
      if (gpg_verify_summary)
        g_assert (index_sig != NULL);

      /* Update cache on disk if we downloaded anything, but never cache for file: repos */
      if (used_download && !is_local &&
          !flatpak_dir_remote_save_cached_summary (self, name_or_uri, ".idx", ".idx.sig",
                                                   index, index_sig, cancellable, error))
        return FALSE;
    }

  /* Cache in memory */
  if (!is_local && !only_cached)
    {
      g_autofree char *cache_key = g_strconcat ("index-", name_or_uri, NULL);
      flatpak_dir_cache_summary (self, index, index_sig, cache_key, url);
    }

  *out_index = g_steal_pointer (&index);
  if (out_index_sig)
    *out_index_sig = g_steal_pointer (&index_sig);

  return TRUE;
}

static gboolean
flatpak_dir_remote_fetch_indexed_summary (FlatpakDir   *self,
                                          const char   *name_or_uri,
                                          const char   *arch,
                                          GVariant     *subsummary_info_v,
                                          gboolean      only_cached,
                                          GBytes      **out_summary,
                                          GCancellable *cancellable,
                                          GError      **error)
{
  g_autofree char *url = NULL;
  gboolean is_local;
  g_autoptr(GError) cache_error = NULL;
  g_autoptr(GBytes) summary_z = NULL;
  g_autoptr(GBytes) summary = NULL;
  g_autofree char *sha256 = NULL;
  VarSubsummaryRef subsummary_info;
  gsize checksum_bytes_len;
  const guchar *checksum_bytes;
  g_autofree char *checksum = NULL;
  g_autofree char *cache_name = NULL;

  ensure_http_session (self);

  if (!ostree_repo_remote_get_url (self->repo, name_or_uri, &url, error))
    return FALSE;

  if (!g_str_has_prefix (name_or_uri, "file:") && flatpak_dir_get_remote_disabled (self, name_or_uri))
    {
      g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA,
                   "Can't fetch summary from disabled remote ‘%s’", name_or_uri);
      return FALSE;
    }

  subsummary_info = var_subsummary_from_gvariant (subsummary_info_v);
  checksum_bytes = var_subsummary_peek_checksum (subsummary_info, &checksum_bytes_len);
  g_assert (checksum_bytes_len == OSTREE_SHA256_DIGEST_LEN); /* We verified this when scanning index */
  checksum = ostree_checksum_from_bytes (checksum_bytes);

  is_local = g_str_has_prefix (url, "file:");

  /* No in-memory caching for local files */
  if (!is_local)
    {
      if (flatpak_dir_lookup_cached_summary (self, out_summary, NULL, checksum, url))
        return TRUE;
    }

  cache_name = g_strconcat (name_or_uri, "-", arch, "-", checksum, NULL);

  /* First look for an on-disk cache */
  if (!flatpak_dir_remote_load_cached_summary (self, cache_name, checksum, ".sub", NULL,
                                               &summary, NULL, cancellable, &cache_error))
    {
      g_autofree char *old_checksum = NULL;
      g_autoptr(GBytes) old_summary = NULL;

      /* Else fetch it */
      if (only_cached)
        {
          g_propagate_error (error, g_steal_pointer (&cache_error));
          return FALSE;
        }

      /* Warn if the on-disk cache is corrupt; perhaps the write was interrupted? */
      if (g_error_matches (cache_error, FLATPAK_ERROR, FLATPAK_ERROR_INVALID_DATA))
        g_warning ("%s", cache_error->message);

      /* Look for first applicable deltas */
      VarArrayofChecksumRef history = var_subsummary_get_history (subsummary_info);
      gsize history_len = var_arrayof_checksum_get_length (history);
      for (gsize i = 0; i < history_len; i++)
        {
          VarChecksumRef old = var_arrayof_checksum_get_at (history, i);
          g_autofree char *old_cache_name = NULL;

          if (var_checksum_get_length (old) != OSTREE_SHA256_DIGEST_LEN)
            continue;

          old_checksum = ostree_checksum_from_bytes (var_checksum_peek (old));
          old_cache_name = g_strconcat (name_or_uri, "-", arch, "-", old_checksum, NULL);
          if (flatpak_dir_remote_load_cached_summary (self, old_cache_name, old_checksum, ".sub", NULL,
                                                      &old_summary, NULL, cancellable, NULL))
            break;

          g_clear_pointer (&old_checksum, g_free);
        }

      if (old_summary)
        {
          g_autoptr(GError) delta_error = NULL;

          g_autofree char *delta_filename = g_strconcat (old_checksum, "-", checksum, ".delta", NULL);
          g_autofree char *delta_url = g_build_filename (url, "summaries", delta_filename, NULL);

          g_info ("Fetching indexed summary delta %s for remote ‘%s’", delta_filename, name_or_uri);

          g_autoptr(GBytes) delta = flatpak_load_uri (self->http_session, delta_url, 0, NULL,
                                                      NULL, NULL, NULL,
                                                      cancellable, &delta_error);
          if (delta == NULL)
            g_info ("Failed to load delta, falling back: %s", delta_error->message);
          else
            {
              g_autoptr(GBytes) applied = flatpak_summary_apply_diff (old_summary, delta, &delta_error);

              if (applied == NULL)
                g_warning ("Failed to apply delta, falling back: %s", delta_error->message);
              else
                {
                  sha256 = g_compute_checksum_for_bytes (G_CHECKSUM_SHA256, applied);
                  if (strcmp (sha256, checksum) != 0)
                    g_warning ("Applying delta gave wrong checksum, falling back");
                  else
                    summary = g_steal_pointer (&applied);
                }
            }
        }

      if (summary == NULL)
        {
          g_autofree char *filename = g_strconcat (checksum, ".gz", NULL);
          g_info ("Fetching indexed summary file %s for remote ‘%s’", filename, name_or_uri);
          g_autofree char *subsummary_url = g_build_filename (url, "summaries", filename, NULL);
          summary_z = flatpak_load_uri (self->http_session, subsummary_url, 0, NULL,
                                        NULL, NULL, NULL,
                                        cancellable, error);
          if (summary_z == NULL)
            return FALSE;

          summary = flatpak_zlib_decompress_bytes (summary_z, error);
          if (summary == NULL)
            return FALSE;

          g_free (sha256);
          sha256 = g_compute_checksum_for_bytes (G_CHECKSUM_SHA256, summary);
          if (strcmp (sha256, checksum) != 0)
            return flatpak_fail_error (error, FLATPAK_ERROR_INVALID_DATA, _("Invalid checksum for indexed summary %s for remote '%s'"), checksum, name_or_uri);
        }

      /* Save to disk */
      if (!is_local)
        {
          if (!flatpak_dir_remote_save_cached_summary (self, cache_name, ".sub", NULL,
                                                       summary, NULL,
                                                       cancellable, error))
            return FALSE;

          if (!flatpak_dir_gc_cached_digested_summaries (self, name_or_uri, cache_name,
                                                         cancellable, error))
            return FALSE;
        }
    }
  else
    g_info ("Loaded indexed summary file %s from cache for remote ‘%s’", checksum, name_or_uri);

  /* Cache in memory */
  if (!is_local && !only_cached)
    flatpak_dir_cache_summary (self, summary, NULL, checksum, url);

  *out_summary = g_steal_pointer (&summary);

  return TRUE;
}

static FlatpakRemoteState *
_flatpak_dir_get_remote_state (FlatpakDir   *self,
                               const char   *remote_or_uri,
                               gboolean      optional,
                               gboolean      local_only,
                               gboolean      only_cached,
                               gboolean      opt_summary_is_index,
                               GBytes       *opt_summary,
                               GBytes       *opt_summary_sig,
                               GCancellable *cancellable,
                               GError      **error)
{
  g_autoptr(FlatpakRemoteState) state = flatpak_remote_state_new ();
  g_autoptr(GPtrArray) sideload_paths = NULL;
  g_autofree char *url = NULL;
  g_autoptr(GError) my_error = NULL;
  gboolean is_local;
  gboolean got_summary = FALSE;
  const char *arch = flatpak_get_default_arch ();
  g_autoptr(GBytes) index_bytes = NULL;
  g_autoptr(GBytes) index_sig_bytes = NULL;
  g_autoptr(GBytes) summary_bytes = NULL;
  g_autoptr(GBytes) summary_sig_bytes = NULL;

  if (error == NULL)
    error = &my_error;

  if (!flatpak_dir_ensure_repo (self, cancellable, error))
    return NULL;

  state->remote_name = g_strdup (remote_or_uri);
  state->is_file_uri = is_local = g_str_has_prefix (remote_or_uri, "file:");
  if (!is_local)
    {
      if (!flatpak_dir_has_remote (self, remote_or_uri, error))
        return NULL;
      if (!repo_get_remote_collection_id (self->repo, remote_or_uri, &state->collection_id, error))
        return NULL;
      if (!flatpak_dir_lookup_remote_filter (self, remote_or_uri, FALSE, NULL, &state->allow_refs, &state->deny_refs, error))
        return NULL;
      if (!ostree_repo_remote_get_url (self->repo, remote_or_uri, &url, error))
        return NULL;

      state->is_oci = flatpak_dir_get_remote_oci (self, remote_or_uri);
      state->default_token_type = flatpak_dir_get_remote_default_token_type (self, remote_or_uri);
    }

  sideload_paths = flatpak_dir_get_sideload_repo_paths (self);
  for (int i = 0; i < sideload_paths->len; i++)
    flatpak_remote_state_add_sideload_repo (state, g_ptr_array_index (sideload_paths, i));

  if (local_only)
    {
      flatpak_fail (&state->summary_fetch_error, "Internal error, local_only state");
      return g_steal_pointer (&state);
    }

  if (opt_summary)
    {
      if (opt_summary_sig)
        {
          /* If specified, must be valid signature */
          g_autoptr(OstreeGpgVerifyResult) gpg_result =
            ostree_repo_verify_summary (self->repo,
                                        state->remote_name,
                                        opt_summary,
                                        opt_summary_sig,
                                        NULL, error);
          if (gpg_result == NULL ||
              !ostree_gpg_verify_result_require_valid_signature (gpg_result, error))
            return NULL;
        }

      if (opt_summary_is_index)
        {
          if (opt_summary_sig)
            index_sig_bytes = g_bytes_ref (opt_summary_sig);
          index_bytes = g_bytes_ref (opt_summary);
        }
      else
        {
          if (opt_summary_sig)
            summary_sig_bytes = g_bytes_ref (opt_summary_sig);
          summary_bytes = g_bytes_ref (opt_summary);
        }

      got_summary = TRUE;
    }

  /* First try the memory cache. Note: No in-memory caching for local files. */
  if (!is_local)
    {
      if (!got_summary)
        {
          g_autofree char *index_cache_key = g_strconcat ("index-", remote_or_uri, NULL);
          if (flatpak_dir_lookup_cached_summary (self, &index_bytes, &index_sig_bytes, index_cache_key, url))
            got_summary = TRUE;
        }

      if (!got_summary)
        {
          g_autofree char *summary_cache_key = g_strconcat ("summary-", remote_or_uri, NULL);
          if (flatpak_dir_lookup_cached_summary (self, &summary_bytes, &summary_sig_bytes, summary_cache_key, url))
            got_summary = TRUE;
        }
    }

  /* Then look for an indexed summary on disk/network */
  if (!got_summary)
    {
      g_autoptr(GError) local_error = NULL;

      if (flatpak_dir_remote_fetch_summary_index (self, remote_or_uri, only_cached, &index_bytes, &index_sig_bytes,
                                                  cancellable, &local_error))
        {
          got_summary = TRUE;
        }
      else
        {
          if (!g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND) &&
              !g_error_matches (local_error, FLATPAK_ERROR, FLATPAK_ERROR_NOT_CACHED))
            {
              /* We got an error other than not-found, assume we're indexed but there is some network error */
              got_summary = TRUE;
              if (optional && !g_cancellable_is_cancelled (cancellable))
                {
                  g_info ("Failed to download optional summary index: %s", local_error->message);
                  state->summary_fetch_error = g_steal_pointer (&local_error);
                }
              else
                {
                  g_propagate_error (error, g_steal_pointer (&local_error));
                  return NULL;
                }
            }
        }
    }

  if (!got_summary)
    {
      /* No index, fall back to full summary */
      g_autoptr(GError) local_error = NULL;

      if (flatpak_dir_remote_fetch_summary (self, remote_or_uri, only_cached, &summary_bytes, &summary_sig_bytes,
                                            cancellable, &local_error))
        {
          got_summary = TRUE;
        }
      else
        {
          if (optional && !g_cancellable_is_cancelled (cancellable))
            {
              g_info ("Failed to download optional summary: %s", local_error->message);
              state->summary_fetch_error = g_steal_pointer (&local_error);
            }
          else
            {
              g_propagate_error (error, g_steal_pointer (&local_error));
              return NULL;
            }
        }
    }

  if (index_bytes)
    {
      state->index = g_variant_ref_sink (g_variant_new_from_bytes (FLATPAK_SUMMARY_INDEX_GVARIANT_FORMAT,
                                                                   index_bytes, FALSE));
      state->index_sig_bytes = g_steal_pointer (&index_sig_bytes);
    }
  else if (summary_bytes)
    {
      state->summary = g_variant_ref_sink (g_variant_new_from_bytes (OSTREE_SUMMARY_GVARIANT_FORMAT,
                                                                     summary_bytes, FALSE));
      state->summary_bytes = g_steal_pointer (&summary_bytes);
      state->summary_sig_bytes = g_steal_pointer (&summary_sig_bytes);
    }

  if (state->index)
    {
      g_autofree char *require_subset = flatpak_dir_get_remote_subset (self, state->remote_name);
      VarSummaryIndexRef index = var_summary_index_from_gvariant (state->index);
      VarSummaryIndexSubsummariesRef subsummaries = var_summary_index_get_subsummaries (index);
      gsize n_subsummaries = var_summary_index_subsummaries_get_length (subsummaries);

      state->index_ht = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify)g_variant_unref);

      for (gsize i = 0; i < n_subsummaries; i++)
        {
          VarSummaryIndexSubsummariesEntryRef entry = var_summary_index_subsummaries_get_at (subsummaries, i);
          const char *name = var_summary_index_subsummaries_entry_get_key (entry);
          VarSubsummaryRef subsummary = var_summary_index_subsummaries_entry_get_value (entry);
          gsize checksum_bytes_len;
          const char *dash, *subsummary_arch;

          dash = strchr (name, '-');
          subsummary_arch = dash == NULL ? name : dash + 1;

          if (dash == NULL) /* No subset */
            {
              if (require_subset != NULL)
                continue;
            }
          else /* Subset */
            {
              if (require_subset == NULL)
                continue;
              else
                {
                  g_autofree char *subset = g_strndup (name, dash - name);
                  if (strcmp (require_subset, subset) != 0)
                    continue;
                }
            }

          var_subsummary_peek_checksum (subsummary, &checksum_bytes_len);
          if (G_UNLIKELY (checksum_bytes_len != OSTREE_SHA256_DIGEST_LEN))
            {
              g_info ("Invalid checksum for digested summary, not using cache");
              continue;
            }

          g_hash_table_insert (state->index_ht, g_strdup (subsummary_arch), var_subsummary_to_owned_gvariant (subsummary, state->index));
        }

      /* Always load default (or specified) arch subsummary. Further arches can be manually loaded with flatpak_remote_state_ensure_subsummary. */
      if (opt_summary == NULL &&
          !flatpak_remote_state_ensure_subsummary (state, self, arch, only_cached, cancellable, error))
        return NULL;
    }

  /* For OCI remotes, the collection ID is local configuration only:
   * In the future we could add it to the index format.
   */
  if (state->collection_id != NULL &&
      state->summary != NULL &&
      !(flatpak_dir_get_remote_oci (self, state->remote_name) ||
        _validate_summary_for_collection_id (state->summary, state->collection_id, error)))
    return NULL;

  if (flatpak_dir_get_remote_oci (self, remote_or_uri))
    {
      state->default_token_type = 1;
    }

  if (state->summary != NULL || state->index != NULL) /* In the optional case we might not have a summary */
    {
      VarMetadataRef meta = flatpak_remote_state_get_main_metadata (state);
      VarVariantRef res;

      if (var_metadata_lookup (meta, "xa.default-token-type", NULL, &res) &&
          var_variant_is_type (res, G_VARIANT_TYPE_INT32))
        state->default_token_type = GINT32_FROM_LE (var_variant_get_int32 (res));
    }

  return g_steal_pointer (&state);
}

FlatpakRemoteState *
flatpak_dir_get_remote_state (FlatpakDir   *self,
                              const char   *remote,
                              gboolean      only_cached,
                              GCancellable *cancellable,
                              GError      **error)
{
  return _flatpak_dir_get_remote_state (self, remote, FALSE, FALSE, only_cached, FALSE, NULL, NULL, cancellable, error);
}

/* This is an alternative way to get the state where the summary is
 * from elsewhere. It is mainly used by the system-helper where the
 * summary is from the user-mode part which downloaded an update
 *
 * It will verify the summary if a signature is passed in, but not
 * otherwise.
 **/
FlatpakRemoteState *
flatpak_dir_get_remote_state_for_summary (FlatpakDir   *self,
                                          const char   *remote,
                                          GBytes       *opt_summary,
                                          GBytes       *opt_summary_sig,
                                          GCancellable *cancellable,
                                          GError      **error)
{
  return _flatpak_dir_get_remote_state (self, remote, FALSE, FALSE, FALSE, FALSE, opt_summary, opt_summary_sig, cancellable, error);
}

FlatpakRemoteState *
flatpak_dir_get_remote_state_for_index (FlatpakDir   *self,
                                        const char   *remote,
                                        GBytes       *opt_index,
                                        GBytes       *opt_index_sig,
                                        GCancellable *cancellable,
                                        GError      **error)
{
  return _flatpak_dir_get_remote_state (self, remote, FALSE, FALSE, FALSE, TRUE, opt_index, opt_index_sig, cancellable, error);
}

/* This is an alternative way to get the remote state that doesn't
 * error out if the summary or metadata is not available.
 * For example, we want to be able to update an app even when
 * we can't talk to the main repo, but there is a local (p2p/sdcard)
 * source for apps, and we want to be able to deploy a ref without pulling it,
 * e.g. because we are installing with FLATPAK_INSTALL_FLAGS_NO_PULL, and we
 * already pulled it out of band beforehand.
 */
FlatpakRemoteState *
flatpak_dir_get_remote_state_optional (FlatpakDir   *self,
                                       const char   *remote,
                                       gboolean      only_cached,
                                       GCancellable *cancellable,
                                       GError      **error)
{
  return _flatpak_dir_get_remote_state (self, remote, TRUE, FALSE, only_cached, FALSE, NULL, NULL, cancellable, error);
}


/* This doesn't do any i/o at all, just keeps track of the local details like
   remote and collection-id. Useful when doing no-pull operations */
FlatpakRemoteState *
flatpak_dir_get_remote_state_local_only (FlatpakDir   *self,
                                         const char   *remote,
                                         GCancellable *cancellable,
                                         GError      **error)
{
  return _flatpak_dir_get_remote_state (self, remote, TRUE, TRUE, FALSE, FALSE, NULL, NULL, cancellable, error);
}

static void
populate_hash_table_from_refs_map (GHashTable         *ret_all_refs,
                                   GHashTable         *ref_timestamps,
                                   VarRefMapRef        ref_map,
                                   const char         *opt_collection_id,
                                   FlatpakRemoteState *state)
{
  gsize len, i;

  len = var_ref_map_get_length (ref_map);
  for (i = 0; i < len; i++)
    {
      VarRefMapEntryRef entry = var_ref_map_get_at (ref_map, i);
      const char *ref_name = var_ref_map_entry_get_ref (entry);
      const guint8 *csum_bytes;
      gsize csum_len;
      VarRefInfoRef info;
      guint64 *new_timestamp = NULL;
      g_autoptr(FlatpakDecomposed) decomposed = NULL;

      if (!flatpak_remote_state_allow_ref (state, ref_name))
        continue;

      info = var_ref_map_entry_get_info (entry);

      csum_bytes = var_ref_info_peek_checksum (info, &csum_len);
      if (csum_len != OSTREE_SHA256_DIGEST_LEN)
        continue;

      decomposed = flatpak_decomposed_new_from_col_ref (ref_name, opt_collection_id, NULL);
      if (decomposed == NULL)
        continue;

      if (ref_timestamps)
        {
          guint64 timestamp = get_timestamp_from_ref_info (info);
          gpointer value;

          if (g_hash_table_lookup_extended (ref_timestamps, ref_name, NULL, &value))
            {
              guint64 *old_timestamp = value;
              if (*old_timestamp >= timestamp)
                continue; /* New timestamp is older, skip this commit */
            }

          new_timestamp = g_memdup2 (&timestamp, sizeof (guint64));
        }

      g_hash_table_replace (ret_all_refs, g_steal_pointer (&decomposed), ostree_checksum_from_bytes (csum_bytes));
      if (new_timestamp)
        g_hash_table_replace (ref_timestamps, g_strdup (ref_name), new_timestamp);
    }
}


static void
populate_hash_table_from_image_collection (GHashTable             *ret_all_refs,
                                           GHashTable             *ref_timestamps,
                                           FlatpakImageCollection *image_collection,
                                           const char             *opt_collection_id,
                                           FlatpakRemoteState     *state)
{
  g_autoptr(GPtrArray) sources = flatpak_image_collection_get_sources (image_collection);

  for (guint i = 0; i < sources->len; i++)
    {
      FlatpakImageSource *image_source = g_ptr_array_index (sources, i);
      const char *ref_name = flatpak_image_source_get_ref (image_source);
      const char *digest = flatpak_image_source_get_digest (image_source);
      const char *checksum;
      guint64 *new_timestamp = NULL;
      g_autoptr(FlatpakDecomposed) decomposed = NULL;

      if (!flatpak_remote_state_allow_ref (state, ref_name))
        continue;

      g_assert (g_str_has_prefix (digest, "sha256:"));
      checksum = digest + 7;

      decomposed = flatpak_decomposed_new_from_col_ref (ref_name, opt_collection_id, NULL);
      if (decomposed == NULL)
        continue;

      if (ref_timestamps)
        {
          guint64 timestamp = flatpak_image_source_get_commit_timestamp (image_source);
          gpointer value;

          if (g_hash_table_lookup_extended (ref_timestamps, ref_name, NULL, &value))
            {
              guint64 *old_timestamp = value;
              if (*old_timestamp >= timestamp)
                continue; /* New timestamp is older, skip this commit */
            }

          new_timestamp = g_memdup2 (&timestamp, sizeof (guint64));
        }

      g_hash_table_replace (ret_all_refs, g_steal_pointer (&decomposed), g_strdup (checksum));
      if (new_timestamp)
        g_hash_table_replace (ref_timestamps, g_strdup (ref_name), new_timestamp);
    }
}


/* This tries to list all available remote refs but also tries to keep
 * working when offline, so it looks in sideloaded repos. Also it uses
 * in-memory cached summaries which ostree doesn't. */
gboolean
flatpak_dir_list_all_remote_refs (FlatpakDir         *self,
                                  FlatpakRemoteState *state,
                                  GHashTable        **out_all_refs,
                                  GCancellable       *cancellable,
                                  GError            **error)
{
  g_autoptr(GHashTable) ret_all_refs = NULL;
  VarSummaryRef summary;
  VarMetadataRef exts;
  VarRefMapRef ref_map;
  VarVariantRef v;

  /* This is  ref->commit */
  ret_all_refs = g_hash_table_new_full ((GHashFunc)flatpak_decomposed_hash, (GEqualFunc)flatpak_decomposed_equal, (GDestroyNotify)flatpak_decomposed_unref, g_free);

  if (state->index != NULL)
    {
      /* We're online, so report only the refs from the summary */
      GLNX_HASH_TABLE_FOREACH_KV (state->subsummaries, const char *, arch, GVariant *, subsummary)
        {
          summary = var_summary_from_gvariant (subsummary);
          ref_map = var_summary_get_ref_map (summary);

          /* NOTE: collection id is NULL here not state->collection_id, see the
           * note on flatpak_decomposed_get_collection_id()
           */
          populate_hash_table_from_refs_map (ret_all_refs, NULL, ref_map, NULL /* collection id */, state);
        }
    }
  else if (state->summary != NULL)
    {
      /* We're online, so report only the refs from the summary */
      const char *main_collection_id = NULL;

      summary = var_summary_from_gvariant (state->summary);

      exts = var_summary_get_metadata (summary);

      if (state->is_file_uri)
        {
          /* This is a local repo, generally this means we gave a file: uri to a sideload repo so
           * we can enumerate it. We special case this by also adding all the collection_ref maps,
           * with collection_id set on the decomposed refs and setting the right collection id for
           * the main ref_map.
           */
          main_collection_id = var_metadata_lookup_string (exts, "ostree.summary.collection-id", NULL);
          if (var_metadata_lookup (exts, "ostree.summary.collection-map", NULL, &v))
            {
              VarCollectionMapRef map = var_collection_map_from_variant (v);

              gsize len = var_collection_map_get_length (map);
              for (gsize i = 0; i < len; i++)
                {
                  VarCollectionMapEntryRef entry = var_collection_map_get_at (map, i);
                  const char *collection_id = var_collection_map_entry_get_key (entry);
                  ref_map = var_collection_map_entry_get_value (entry);

                  populate_hash_table_from_refs_map (ret_all_refs, NULL, ref_map, collection_id, state);
                }
            }
        }

      /* refs that match the main collection-id,
         NOTE: We only set collection id if this is a file: uri remote */
      ref_map = var_summary_get_ref_map (summary);
      populate_hash_table_from_refs_map (ret_all_refs, NULL, ref_map, main_collection_id, state);
    }
  else
    {
      g_autoptr(GHashTable) ref_mtimes = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);

      /* No main summary, add just all sideloded refs, with the latest version of each checksum */

      if (state->collection_id)
        {
          for (int i = 0; i < state->sideload_repos->len; i++)
            {
              FlatpakSideloadState *ss = g_ptr_array_index (state->sideload_repos, i);

              summary = var_summary_from_gvariant (ss->summary);
              exts = var_summary_get_metadata (summary);

              if (var_metadata_lookup (exts, "ostree.summary.collection-map", NULL, &v))
                {
                  VarCollectionMapRef map = var_collection_map_from_variant (v);

                  if (var_collection_map_lookup (map, state->collection_id, NULL, &ref_map))
                    populate_hash_table_from_refs_map (ret_all_refs, ref_mtimes, ref_map, NULL, state);
                }
            }
        }

      if (state->is_oci)
        {
          for (int i = 0; i < state->sideload_image_collections->len; i++)
            {
              FlatpakImageCollection *collection = g_ptr_array_index (state->sideload_image_collections, i);
              populate_hash_table_from_image_collection (ret_all_refs, ref_mtimes, collection, NULL, state);
            }
        }
    }

  /* If no sideloaded refs, might as well return the summary error if set */
  if (g_hash_table_size (ret_all_refs) == 0 &&
      !flatpak_remote_state_ensure_summary (state, error))
    return FALSE;

  *out_all_refs = g_steal_pointer (&ret_all_refs);

  return TRUE;
}

static GPtrArray *
find_matching_refs (GHashTable           *refs,
                    const char           *opt_name,
                    const char           *opt_branch,
                    const char           *opt_default_branch,
                    const char          **valid_arches, /* NULL => any arch */
                    const char           *opt_default_arch,
                    FlatpakKinds          kinds,
                    FindMatchingRefsFlags flags,
                    GError              **error)
{
  g_autoptr(GPtrArray) matched_refs = NULL;
  g_autoptr(GError) local_error = NULL;
  gboolean found_exact_name_match = FALSE;
  gboolean found_default_branch_match = FALSE;
  gboolean found_default_arch_match = FALSE;

  if (opt_name && !(flags & FIND_MATCHING_REFS_FLAGS_FUZZY) &&
      !flatpak_is_valid_name (opt_name, -1, &local_error))
    {
      flatpak_fail_error (error, FLATPAK_ERROR_INVALID_REF, _("'%s' is not a valid name: %s"), opt_name, local_error->message);
      return NULL;
    }

  if (opt_branch && !flatpak_is_valid_branch (opt_branch, -1, &local_error))
    {
      flatpak_fail_error (error, FLATPAK_ERROR_INVALID_REF, _("'%s' is not a valid branch name: %s"), opt_branch, local_error->message);
      return NULL;
    }

  matched_refs = g_ptr_array_new_with_free_func ((GDestroyNotify)flatpak_decomposed_unref);

  GLNX_HASH_TABLE_FOREACH (refs, FlatpakDecomposed *, ref)
    {
      if ((flatpak_decomposed_get_kinds (ref) & kinds) == 0)
        continue;

      if (opt_name)
        {
          if ((flags & FIND_MATCHING_REFS_FLAGS_FUZZY) && !flatpak_decomposed_id_is_subref (ref))
            {
              if (!flatpak_decomposed_is_id_fuzzy (ref, opt_name))
                continue;
            }
          else
            {
              if (!flatpak_decomposed_is_id (ref, opt_name))
                continue;
           }
        }

      if (valid_arches != NULL &&
          !flatpak_decomposed_is_arches (ref, -1, valid_arches))
        continue;

      if (opt_branch != NULL && !flatpak_decomposed_is_branch (ref, opt_branch))
        continue;

      if (opt_name != NULL && flatpak_decomposed_is_id (ref, opt_name))
        found_exact_name_match = TRUE;

      if (opt_default_arch != NULL && flatpak_decomposed_is_arch (ref, opt_default_arch))
        found_default_arch_match = TRUE;

      if (opt_default_branch != NULL && flatpak_decomposed_is_branch (ref, opt_default_branch))
        found_default_branch_match = TRUE;

      g_ptr_array_add (matched_refs, flatpak_decomposed_ref (ref));
    }

  /* Don't show fuzzy matches if we found at least one exact name match, and
   * enforce the default arch/branch */
  if (found_exact_name_match || found_default_arch_match || found_default_branch_match)
    {
      guint i;

      /* Walk through the array backwards so we can safely remove */
      for (i = matched_refs->len; i > 0; i--)
        {
          FlatpakDecomposed *matched_ref = g_ptr_array_index (matched_refs, i - 1);

          if (found_exact_name_match && !flatpak_decomposed_is_id (matched_ref, opt_name))
            g_ptr_array_remove_index (matched_refs, i - 1);
          else if (found_default_arch_match && !flatpak_decomposed_is_arch (matched_ref, opt_default_arch))
            g_ptr_array_remove_index (matched_refs, i - 1);
          else if (found_default_branch_match && !flatpak_decomposed_is_branch (matched_ref, opt_default_branch))
            g_ptr_array_remove_index (matched_refs, i - 1);
        }
    }

  return g_steal_pointer (&matched_refs);
}

static GPtrArray *
get_refs_for_arch (GPtrArray *refs, const char *arch)
{
  g_autoptr(GPtrArray) arched_refs = g_ptr_array_new_with_free_func ((GDestroyNotify)flatpak_decomposed_unref);

  for (int i = 0; i < refs->len; i++)
    {
      FlatpakDecomposed *ref = g_ptr_array_index (refs, i);
      if (flatpak_decomposed_is_arch (ref, arch))
        g_ptr_array_add (arched_refs, flatpak_decomposed_ref (ref));
    }

  return g_steal_pointer (&arched_refs);
}

static gpointer
fail_multiple_refs (GError    **error,
                    const char *name,
                    GPtrArray  *refs)
{
  g_autoptr(GString) err = g_string_new ("");

  g_string_printf (err, _("Multiple branches available for %s, you must specify one of: "), name);
  g_ptr_array_sort (refs, flatpak_strcmp0_ptr);

  for (int i = 0; i < refs->len; i++)
    {
      FlatpakDecomposed *ref = g_ptr_array_index (refs, i);
      if (i != 0)
        g_string_append (err, ", ");

      g_string_append (err, flatpak_decomposed_get_pref (ref));
    }
  flatpak_fail (error, "%s", err->str);

  return NULL;
}

static FlatpakDecomposed *
find_matching_ref (GHashTable  *refs,
                   const char  *name,
                   const char  *opt_branch,
                   const char  *opt_default_branch,
                   const char **valid_arches, /* NULL => any arch */
                   const char  *opt_default_arch,
                   FlatpakKinds kinds,
                   GError     **error)
{
  g_autoptr(GPtrArray) matched_refs = NULL;

  matched_refs = find_matching_refs (refs,
                                     name,
                                     opt_branch,
                                     opt_default_branch,
                                     valid_arches,
                                     opt_default_arch,
                                     kinds,
                                     FIND_MATCHING_REFS_FLAGS_NONE,
                                     error);
  if (matched_refs == NULL)
    return NULL;

  if (valid_arches != NULL)
    {
      /* Filter by valid, arch. We stop at the first arch (in prio order) that has a match */
      for (int i = 0; valid_arches[i] != NULL; i++)
        {
          const char *arch = valid_arches[i];

          g_autoptr(GPtrArray) arched_refs = get_refs_for_arch (matched_refs, arch);

          if (arched_refs->len == 1)
            return flatpak_decomposed_ref (g_ptr_array_index (arched_refs, 0));

          if (arched_refs->len > 1)
            return fail_multiple_refs (error, name, arched_refs);
        }
    }
  else
    {
      if (matched_refs->len == 1)
        return flatpak_decomposed_ref (g_ptr_array_index (matched_refs, 0));

      if (matched_refs->len > 1)
        return fail_multiple_refs (error, name, matched_refs);
    }

  g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND,
               _("Nothing matches %s"), name);
  return NULL;
}

char *
flatpak_dir_get_remote_collection_id (FlatpakDir *self,
                                      const char *remote_name)
{
  char *collection_id = NULL;

  if (!flatpak_dir_ensure_repo (self, NULL, NULL))
    return NULL;

  repo_get_remote_collection_id (self->repo, remote_name, &collection_id, NULL);

  return collection_id;
}

/* This tries to find all available refs based on the specified name/arch/branch
 * triplet from  a remote. If arch is not specified, matches only on compatible arches.
*/
GPtrArray *
flatpak_dir_find_remote_refs (FlatpakDir           *self,
                              FlatpakRemoteState   *state,
                              const char           *name,
                              const char           *opt_branch,
                              const char           *opt_default_branch,
                              const char           *opt_arch,
                              const char           *opt_default_arch,
                              FlatpakKinds          kinds,
                              FindMatchingRefsFlags flags,
                              GCancellable         *cancellable,
                              GError              **error)
{
  g_autoptr(GHashTable) remote_refs = NULL;
  g_autoptr(GPtrArray) matched_refs = NULL;
  const char **valid_arches = flatpak_get_arches ();
  const char *opt_arches[] = {opt_arch, NULL};

  if (opt_arch != NULL)
    valid_arches = opt_arches;

  if (!flatpak_dir_list_all_remote_refs (self, state,
                                         &remote_refs, cancellable, error))
    return NULL;

  matched_refs = find_matching_refs (remote_refs,
                                     name,
                                     opt_branch,
                                     opt_default_branch,
                                     valid_arches,
                                     opt_default_arch,
                                     kinds,
                                     flags,
                                     error);
  if (matched_refs == NULL)
    return NULL;

  /* If we can't match anything and we had an error downloading (offline?), report that as its more helpful */
  if (matched_refs->len == 0 && state->summary_fetch_error)
    {
      g_propagate_error (error, g_error_copy (state->summary_fetch_error));
      return NULL;
    }

  return g_steal_pointer (&matched_refs);
}

static FlatpakDecomposed *
find_ref_for_refs_set (GHashTable   *refs,
                       const char   *name,
                       const char   *opt_branch,
                       const char   *opt_default_branch,
                       const char   *opt_arch,
                       FlatpakKinds  kinds,
                       GError      **error)
{
  const char **valid_arches = flatpak_get_arches ();
  const char *opt_arches[] = {opt_arch, NULL};

  if (opt_arch != NULL)
    valid_arches = opt_arches;

  g_autoptr(GError) my_error = NULL;
  g_autoptr(FlatpakDecomposed) ref = find_matching_ref (refs,
                                                        name,
                                                        opt_branch,
                                                        opt_default_branch,
                                                        valid_arches,
                                                        NULL,
                                                        kinds,
                                                        &my_error);
  if (ref == NULL)
    {
      if (g_error_matches (my_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
        g_clear_error (&my_error);
      else
        {
          g_propagate_error (error, g_steal_pointer (&my_error));
          return NULL;
        }
    }
  else
    {
      return g_steal_pointer (&ref);
    }

  g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND,
               _("Can't find ref %s%s%s%s%s"), name,
               (opt_arch != NULL || opt_branch != NULL) ? "/" : "",
               opt_arch ? opt_arch : "",
               opt_branch ? "/" : "",
               opt_branch ? opt_branch : "");

  return NULL;
}

/* This tries to find a single ref based on the specified name/arch/branch
 * triplet from  a remote. If arch is not specified, matches only on compatible arches.
*/
FlatpakDecomposed *
flatpak_dir_find_remote_ref (FlatpakDir   *self,
                             FlatpakRemoteState *state,
                             const char   *name,
                             const char   *opt_branch,
                             const char   *opt_default_branch,
                             const char   *opt_arch,
                             FlatpakKinds  kinds,
                             GCancellable *cancellable,
                             GError      **error)
{
  g_autoptr(FlatpakDecomposed) remote_ref = NULL;
  g_autoptr(GHashTable) remote_refs = NULL;
  g_autoptr(GError) my_error = NULL;

  /* Avoid work if the entire ref was specified */
  if (opt_branch != NULL && opt_arch != NULL && (kinds == FLATPAK_KINDS_APP || kinds == FLATPAK_KINDS_RUNTIME))
    return flatpak_decomposed_new_from_parts (kinds, name, opt_arch, opt_branch, error);

  if (!flatpak_dir_list_all_remote_refs (self, state,
                                         &remote_refs, cancellable, error))
    return NULL;

  remote_ref = find_ref_for_refs_set (remote_refs, name, opt_branch,
                                      opt_default_branch, opt_arch,
                                      kinds,  &my_error);
  if (!remote_ref)
    {
      if (g_error_matches (my_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
        {
          g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND,
                       _("Error searching remote %s: %s"),
                       state->remote_name,
                       my_error->message);
          return NULL;
        }
      else
        {
          g_propagate_error (error, g_steal_pointer (&my_error));
          return NULL;
        }
    }

  return g_steal_pointer (&remote_ref);
}

static GHashTable *
refspecs_decompose_steal (GHashTable *refspecs)
{
  g_autoptr(GHashTable) refs = NULL;
  GHashTableIter iter;
  gpointer key, value;

  refs = g_hash_table_new_full ((GHashFunc)flatpak_decomposed_hash, (GEqualFunc)flatpak_decomposed_equal,
                                (GDestroyNotify)flatpak_decomposed_unref, g_free);

  g_hash_table_iter_init (&iter, refspecs);
  while (g_hash_table_iter_next (&iter, &key, &value))
    {
      char *checksum = value;
      char *refspec = key;
      FlatpakDecomposed *decomposed;

      g_hash_table_iter_steal (&iter);

      decomposed = flatpak_decomposed_new_from_refspec_take (refspec, NULL);
      if (decomposed)
        {
          g_hash_table_insert (refs, decomposed, checksum);
        }
      else
        {
          g_free (checksum);
          g_free (refspec);
        }
    }

  return g_steal_pointer (&refs);
}

GPtrArray *
flatpak_dir_find_local_refs (FlatpakDir           *self,
                             const char           *remote,
                             const char           *name,
                             const char           *opt_branch,
                             const char           *opt_default_branch,
                             const char           *opt_arch,
                             const char           *opt_default_arch,
                             FlatpakKinds          kinds,
                             FindMatchingRefsFlags flags,
                             GCancellable         *cancellable,
                             GError              **error)
{
  g_autoptr(GHashTable) local_refs = NULL;
  g_autoptr(GHashTable) local_refspecs = NULL;
  g_autoptr(GError) my_error = NULL;
  g_autofree char *refspec_prefix = g_strconcat (remote, ":.", NULL);
  g_autoptr(GPtrArray) matched_refs = NULL;
  const char **valid_arches = flatpak_get_arches ();
  const char *opt_arches[] = {opt_arch, NULL};

  if (opt_arch != NULL)
    valid_arches = opt_arches;

  if (!flatpak_dir_ensure_repo (self, NULL, error))
    return NULL;

  if (!ostree_repo_list_refs (self->repo,
                              refspec_prefix,
                              &local_refspecs, cancellable, error))
    return NULL;

  local_refs = refspecs_decompose_steal (local_refspecs);

  matched_refs = find_matching_refs (local_refs,
                                     name,
                                     opt_branch,
                                     opt_default_branch,
                                     valid_arches,
                                     opt_default_arch,
                                     kinds,
                                     flags,
                                     &my_error);
  if (matched_refs == NULL)
    {
      if (g_error_matches (my_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
        {
          g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND,
                       _("Error searching local repository: %s"),
                       my_error->message);
          return NULL;
        }
      else
        {
          g_propagate_error (error, g_steal_pointer (&my_error));
          return NULL;
        }
    }

  return g_steal_pointer (&matched_refs);
}

static GHashTable *
flatpak_dir_get_all_installed_refs (FlatpakDir  *self,
                                    FlatpakKinds kinds,
                                    GError     **error)
{
  g_autoptr(GHashTable) local_refs = NULL;

  if (!flatpak_dir_maybe_ensure_repo (self, NULL, error))
    return NULL;

  local_refs = g_hash_table_new_full ((GHashFunc)flatpak_decomposed_hash, (GEqualFunc)flatpak_decomposed_equal, (GDestroyNotify)flatpak_decomposed_unref, NULL);
  if (kinds & FLATPAK_KINDS_APP)
    {
      g_autoptr(GPtrArray) app_refs = flatpak_dir_list_refs (self, FLATPAK_KINDS_APP, NULL, error);
      if (app_refs == NULL)
        return NULL;

      for (int i = 0; i < app_refs->len; i++)
        {
          FlatpakDecomposed *app_ref = g_ptr_array_index (app_refs, i);
          g_hash_table_add (local_refs, flatpak_decomposed_ref (app_ref));
        }
    }
  if (kinds & FLATPAK_KINDS_RUNTIME)
    {
      g_autoptr(GPtrArray) runtime_refs = flatpak_dir_list_refs (self, FLATPAK_KINDS_RUNTIME, NULL, error);
      if (runtime_refs == NULL)
        return NULL;

      for (int i = 0; i < runtime_refs->len; i++)
        {
          FlatpakDecomposed *runtime_ref = g_ptr_array_index (runtime_refs, i);
          g_hash_table_add (local_refs, flatpak_decomposed_ref (runtime_ref));
        }
    }

  return g_steal_pointer (&local_refs);
}

/* This tries to find a all installed refs based on the specified name/arch/branch
 * triplet. Matches on all arches.
*/
GPtrArray *
flatpak_dir_find_installed_refs (FlatpakDir           *self,
                                 const char           *opt_name,
                                 const char           *opt_branch,
                                 const char           *opt_arch,
                                 FlatpakKinds          kinds,
                                 FindMatchingRefsFlags flags,
                                 GError              **error)
{
  g_autoptr(GHashTable) local_refs = NULL;
  g_autoptr(GPtrArray) matched_refs = NULL;
  const char **valid_arches = NULL; /* List all installed arches if unspecified */
  const char *opt_arches[] = {opt_arch, NULL};

  if (opt_arch != NULL)
    valid_arches = opt_arches;

  local_refs = flatpak_dir_get_all_installed_refs (self, kinds, error);
  if (local_refs == NULL)
    return NULL;

  matched_refs = find_matching_refs (local_refs,
                                     opt_name,
                                     opt_branch,
                                     NULL, /* default branch */
                                     valid_arches,
                                     NULL, /* default arch */
                                     kinds,
                                     flags,
                                     error);
  if (matched_refs == NULL)
    return NULL;

  return g_steal_pointer (&matched_refs);
}

/* This tries to find a single ref based on the specified name/arch/branch
 * triplet. This matches on all (installed) arches, but defaults to the primary
 * arch if that is installed. Otherwise, ambiguity is an error.
*/
FlatpakDecomposed *
flatpak_dir_find_installed_ref (FlatpakDir   *self,
                                const char   *opt_name,
                                const char   *opt_branch,
                                const char   *opt_arch,
                                FlatpakKinds  kinds,
                                GError      **error)
{
  g_autoptr(FlatpakDecomposed) local_ref = NULL;
  g_autoptr(GHashTable) local_refs = NULL;
  g_autoptr(GError) my_error = NULL;
  const char **valid_arches = NULL; /* All are valid unless specified in opt_arch */
  const char *default_arch = flatpak_get_arch ();
  const char *opt_arches[] = {opt_arch, NULL};

  if (opt_arch != NULL)
    valid_arches = opt_arches;

  local_refs = flatpak_dir_get_all_installed_refs (self, kinds, error);
  if (local_refs == NULL)
    return NULL;

  local_ref = find_matching_ref (local_refs, opt_name, opt_branch, NULL,
                                 valid_arches, default_arch,
                                 kinds, &my_error);
  if (local_ref == NULL)
    {
      if (g_error_matches (my_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
        g_clear_error (&my_error);
      else
        {
          g_propagate_error (error, g_steal_pointer (&my_error));
          return NULL;
        }
    }
  else
    {
      return g_steal_pointer (&local_ref);
    }

  g_set_error (error, FLATPAK_ERROR, FLATPAK_ERROR_NOT_INSTALLED,
               _("%s/%s/%s not installed"),
               opt_name ? opt_name : "*unspecified*",
               opt_arch ? opt_arch : "*unspecified*",
               opt_branch ? opt_branch : "*unspecified*");
  return NULL;
}

/* Given a list of decomposed refs in local_refspecs, remove any refs that have already
 * been deployed and return a new GPtrArray containing only the undeployed
 * refs. This is used by flatpak_dir_cleanup_undeployed_refs to determine
 * which undeployed refs need to be removed from the local repository.
 *
 * Returns: (transfer-full): A #GPtrArray
 */
static GPtrArray *
filter_out_deployed_refs (FlatpakDir *self,
                          GPtrArray  *local_refspecs,
                          GError    **error)
{
  g_autoptr(GPtrArray) undeployed_refs = g_ptr_array_new_full (local_refspecs->len, (GDestroyNotify)flatpak_decomposed_unref);
  gsize i;

  for (i = 0; i < local_refspecs->len; ++i)
    {
      FlatpakDecomposed *ref = g_ptr_array_index (local_refspecs, i);
      g_autoptr(GBytes) deploy_data = NULL;

      deploy_data = flatpak_dir_get_deploy_data (self, ref, FLATPAK_DEPLOY_VERSION_ANY, NULL, NULL);

      if (!deploy_data)
        g_ptr_array_add (undeployed_refs, flatpak_decomposed_ref (ref));
    }

  return g_steal_pointer (&undeployed_refs);
}

/**
 * flatpak_dir_cleanup_undeployed_refs:
 * @self: a #FlatpakDir
 * @cancellable: (nullable) (optional): a #GCancellable
 * @error: a #GError
 *
 * Find all flatpak refs in the local repository which have not been deployed
 * in the dir and remove them from the repository. You might want to call this
 * function if you pulled refs into the dir but then decided that you did
 * not want to deploy them for some reason. Note that this does not prune
 * objects bound to the cleaned up refs from the underlying OSTree repository,
 * you should consider using flatpak_dir_prune() to do that.
 *
 * Since: 0.10.0
 * Returns: %TRUE if cleaning up the refs succeeded, %FALSE otherwise
 */
gboolean
flatpak_dir_cleanup_undeployed_refs (FlatpakDir   *self,
                                     GCancellable *cancellable,
                                     GError      **error)
{
  g_autoptr(GHashTable) local_refspecs = NULL;
  g_autoptr(GHashTable) local_refs = NULL;
  g_autoptr(GPtrArray)  local_flatpak_refspecs = NULL;
  g_autoptr(GPtrArray) undeployed_refs = NULL;
  gsize i = 0;

  if (!ostree_repo_list_refs (self->repo, NULL, &local_refspecs, cancellable, error))
    return FALSE;

  local_refs = refspecs_decompose_steal (local_refspecs);

  local_flatpak_refspecs = find_matching_refs (local_refs,
                                               NULL, NULL, NULL, NULL, NULL,
                                               FLATPAK_KINDS_APP |
                                               FLATPAK_KINDS_RUNTIME,
                                               0, error);

  if (!local_flatpak_refspecs)
    return FALSE;

  undeployed_refs = filter_out_deployed_refs (self, local_flatpak_refspecs, error);

  if (!undeployed_refs)
    return FALSE;

  for (; i < undeployed_refs->len; ++i)
    {
      FlatpakDecomposed *ref = g_ptr_array_index (undeployed_refs, i);
      g_autofree gchar *remote = flatpak_decomposed_dup_remote (ref);

      if (!flatpak_dir_remove_ref (self, remote, flatpak_decomposed_get_ref (ref), cancellable, error))
        return FALSE;
    }

  return TRUE;
}

static FlatpakDir *
flatpak_dir_new_full (GFile *path, gboolean user, DirExtraData *extra_data)
{
  FlatpakDir *dir = g_object_new (FLATPAK_TYPE_DIR, "path", path, "user", user, NULL);

  if (extra_data != NULL)
    dir->extra_data = dir_extra_data_clone (extra_data);

  return dir;
}

FlatpakDir *
flatpak_dir_new (GFile *path, gboolean user)
{
  /* We are only interested on extra data for system-wide installations, in which
     case we use _new_full() directly, so here we just call it passing NULL */
  return flatpak_dir_new_full (path, user, NULL);
}

FlatpakDir *
flatpak_dir_clone (FlatpakDir *self)
{
  FlatpakDir *clone;

  clone = flatpak_dir_new_full (self->basedir, self->user, self->extra_data);

  flatpak_dir_set_no_system_helper (clone, self->no_system_helper);
  flatpak_dir_set_no_interaction (clone, self->no_interaction);

  return clone;
}

FlatpakDir *
flatpak_dir_get_system_default (void)
{
  g_autoptr(GFile) path = flatpak_get_system_default_base_dir_location ();
  g_autoptr(DirExtraData) extra_data = dir_extra_data_new (SYSTEM_DIR_DEFAULT_ID,
                                                           SYSTEM_DIR_DEFAULT_DISPLAY_NAME,
                                                           SYSTEM_DIR_DEFAULT_PRIORITY,
                                                           SYSTEM_DIR_DEFAULT_STORAGE_TYPE);
  return flatpak_dir_new_full (path, FALSE, extra_data);
}

/* This figures out if it is a user or system dir automatically */
FlatpakDir *
flatpak_dir_get_by_path (GFile *path)
{
  GPtrArray *locations = flatpak_get_system_base_dir_locations (NULL, NULL);
  int i;

  if (locations)
    {
      for (i = 0; i < locations->len; i++)
        {
          GFile *system_path = g_ptr_array_index (locations, i);

          if (g_file_equal (system_path, path))
            {
              DirExtraData *extra_data = g_object_get_data (G_OBJECT (path), "extra-data");
              return flatpak_dir_new_full (path, FALSE, extra_data);
            }
        }
    }

  /* If its not configured as a system installation it will not have
     an installation id and we can't use the system helper, so assume
     user (and fail later with permission issues if its not owned by
     the caller) */

  return flatpak_dir_new (path, TRUE);
}

FlatpakDir *
flatpak_dir_get_system_by_id (const char   *id,
                              GCancellable *cancellable,
                              GError      **error)
{
  g_autoptr(GError) local_error = NULL;
  GPtrArray *locations = NULL;
  FlatpakDir *ret = NULL;
  int i;

  if (id == NULL || g_strcmp0 (id, SYSTEM_DIR_DEFAULT_ID) == 0)
    return flatpak_dir_get_system_default ();

  /* An error in flatpak_get_system_base_dir_locations() will still return
   * return an empty array with the GError set, but we want to return NULL.
   */
  locations = flatpak_get_system_base_dir_locations (cancellable, &local_error);
  if (local_error != NULL)
    {
      g_propagate_error (error, g_steal_pointer (&local_error));
      return NULL;
    }

  for (i = 0; i < locations->len; i++)
    {
      GFile *path = g_ptr_array_index (locations, i);
      DirExtraData *extra_data = g_object_get_data (G_OBJECT (path), "extra-data");
      if (extra_data != NULL && g_strcmp0 (extra_data->id, id) == 0)
        {
          ret = flatpak_dir_new_full (path, FALSE, extra_data);
          break;
        }
    }

  if (ret == NULL)
    {
      g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND,
                   _("Could not find installation %s"), id);
    }

  return ret;
}

GPtrArray *
flatpak_dir_get_system_list (GCancellable *cancellable,
                             GError      **error)
{
  g_autoptr(GPtrArray) result = NULL;
  g_autoptr(GError) local_error = NULL;
  GPtrArray *locations = NULL;
  int i;

  /* An error in flatpak_get_system_base_dir_locations() will still return
   * return an empty array with the GError set, but we want to return NULL.
   */
  locations = flatpak_get_system_base_dir_locations (cancellable, &local_error);
  if (local_error != NULL)
    {
      g_propagate_error (error, g_steal_pointer (&local_error));
      return NULL;
    }

  result = g_ptr_array_new_with_free_func (g_object_unref);
  for (i = 0; i < locations->len; i++)
    {
      GFile *path = g_ptr_array_index (locations, i);
      DirExtraData *extra_data = g_object_get_data (G_OBJECT (path), "extra-data");
      g_ptr_array_add (result, flatpak_dir_new_full (path, FALSE, extra_data));
    }

  return g_steal_pointer (&result);
}

FlatpakDir *
flatpak_dir_get_user (void)
{
  g_autoptr(GFile) path = flatpak_get_user_base_dir_location ();
  return flatpak_dir_new (path, TRUE);
}

static char *
get_group (const char *remote_name)
{
  return g_strdup_printf ("remote \"%s\"", remote_name);
}

static GKeyFile *
flatpak_dir_get_repo_config (FlatpakDir *self)
{
  if (!flatpak_dir_ensure_repo (self, NULL, NULL))
    return NULL;

  return ostree_repo_get_config (self->repo);
}

char **
flatpak_dir_list_remote_config_keys (FlatpakDir *self,
                                     const char *remote_name)
{
  GKeyFile *config = flatpak_dir_get_repo_config (self);
  g_autofree char *group = get_group (remote_name);

  if (config)
    return g_key_file_get_keys (config, group, NULL, NULL);

  return NULL;
}

GPtrArray *
flatpak_dir_get_sideload_repo_paths (FlatpakDir *self)
{
  g_autoptr(GFile) sideload_repos_dir = flatpak_dir_get_sideload_repos_dir (self);
  g_autoptr(GFile) runtime_sideload_repos_dir = flatpak_dir_get_runtime_sideload_repos_dir (self);
  g_autoptr(GPtrArray) res = g_ptr_array_new_with_free_func (g_object_unref);

  add_sideload_subdirs (res, sideload_repos_dir, TRUE);
  add_sideload_subdirs (res, runtime_sideload_repos_dir, TRUE);

  return g_steal_pointer (&res);
}


char *
flatpak_dir_get_remote_title (FlatpakDir *self,
                              const char *remote_name)
{
  GKeyFile *config = flatpak_dir_get_repo_config (self);
  g_autofree char *group = get_group (remote_name);

  if (config)
    return g_key_file_get_string (config, group, "xa.title", NULL);

  return NULL;
}

static const char *
canonical_filter (const char *filter)
{
  /* Canonicalize "no filter", to NULL (empty means the same) */
  if (filter && *filter == 0)
    return NULL;
  return filter;
}

gboolean
flatpak_dir_compare_remote_filter (FlatpakDir *self,
                                   const char *remote_name,
                                   const char *filter)
{
  g_autofree char *current_filter = flatpak_dir_get_remote_filter (self, remote_name);

  return g_strcmp0 (current_filter, canonical_filter (filter)) == 0;
}

/* returns the canonical form */
char *
flatpak_dir_get_remote_filter (FlatpakDir *self,
                               const char *remote_name)
{
  GKeyFile *config = flatpak_dir_get_repo_config (self);
  g_autofree char *group = get_group (remote_name);

  if (config)
    {
      g_autofree char *filter = g_key_file_get_string (config, group, "xa.filter", NULL);

      if (filter && *filter != 0)
        return g_steal_pointer (&filter);
    }

  return NULL;
}

char *
flatpak_dir_get_remote_comment (FlatpakDir *self,
                                const char *remote_name)
{
  GKeyFile *config = flatpak_dir_get_repo_config (self);
  g_autofree char *group = get_group (remote_name);

  if (config)
    return g_key_file_get_string (config, group, "xa.comment", NULL);

  return NULL;
}

char *
flatpak_dir_get_remote_description (FlatpakDir *self,
                                    const char *remote_name)
{
  GKeyFile *config = flatpak_dir_get_repo_config (self);
  g_autofree char *group = get_group (remote_name);

  if (config)
    return g_key_file_get_string (config, group, "xa.description", NULL);

  return NULL;
}

char *
flatpak_dir_get_remote_homepage (FlatpakDir *self,
                                 const char *remote_name)
{
  GKeyFile *config = flatpak_dir_get_repo_config (self);
  g_autofree char *group = get_group (remote_name);

  if (config)
    return g_key_file_get_string (config, group, "xa.homepage", NULL);

  return NULL;
}

char *
flatpak_dir_get_remote_icon (FlatpakDir *self,
                             const char *remote_name)
{
  GKeyFile *config = flatpak_dir_get_repo_config (self);
  g_autofree char *group = get_group (remote_name);

  if (config)
    return g_key_file_get_string (config, group, "xa.icon", NULL);

  return NULL;
}

gboolean
flatpak_dir_get_remote_oci (FlatpakDir *self,
                            const char *remote_name)
{
  g_autofree char *url = NULL;

  if (!flatpak_dir_ensure_repo (self, NULL, NULL))
    return FALSE;

  if (!ostree_repo_remote_get_url (self->repo, remote_name, &url, NULL))
    return FALSE;

  return url && g_str_has_prefix (url, "oci+");
}

gint32
flatpak_dir_get_remote_default_token_type (FlatpakDir *self,
                                           const char *remote_name)
{
  GKeyFile *config = flatpak_dir_get_repo_config (self);
  g_autofree char *group = get_group (remote_name);

  if (config)
    return (gint32)g_key_file_get_integer (config, group, "xa.default-token-type", NULL);

  return 0;
}

char *
flatpak_dir_get_remote_main_ref (FlatpakDir *self,
                                 const char *remote_name)
{
  GKeyFile *config = flatpak_dir_get_repo_config (self);
  g_autofree char *group = get_group (remote_name);

  if (config)
    return g_key_file_get_string (config, group, "xa.main-ref", NULL);

  return NULL;
}

char *
flatpak_dir_get_remote_default_branch (FlatpakDir *self,
                                       const char *remote_name)
{
  GKeyFile *config = flatpak_dir_get_repo_config (self);
  g_autofree char *group = get_group (remote_name);

  if (config)
    return g_key_file_get_string (config, group, "xa.default-branch", NULL);

  return NULL;
}

int
flatpak_dir_get_remote_prio (FlatpakDir *self,
                             const char *remote_name)
{
  GKeyFile *config = flatpak_dir_get_repo_config (self);
  g_autofree char *group = get_group (remote_name);

  if (config && g_key_file_has_key (config, group, "xa.prio", NULL))
    return g_key_file_get_integer (config, group, "xa.prio", NULL);

  return 1;
}

gboolean
flatpak_dir_get_remote_noenumerate (FlatpakDir *self,
                                    const char *remote_name)
{
  GKeyFile *config = flatpak_dir_get_repo_config (self);
  g_autofree char *group = get_group (remote_name);

  if (config)
    return g_key_file_get_boolean (config, group, "xa.noenumerate", NULL);

  return TRUE;
}

gboolean
flatpak_dir_get_remote_nodeps (FlatpakDir *self,
                               const char *remote_name)
{
  GKeyFile *config = flatpak_dir_get_repo_config (self);
  g_autofree char *group = get_group (remote_name);

  if (config)
    return g_key_file_get_boolean (config, group, "xa.nodeps", NULL);

  return TRUE;
}

char *
flatpak_dir_get_remote_subset (FlatpakDir *self,
                               const char *remote_name)
{
  GKeyFile *config = flatpak_dir_get_repo_config (self);
  g_autofree char *group = get_group (remote_name);
  g_autofree char *subset = NULL;

  if (config == NULL)
    return NULL;

  subset = g_key_file_get_string (config, group, "xa.subset", NULL);
  if (subset == NULL || *subset == 0)
    return NULL;

  return g_steal_pointer (&subset);
}

gboolean
flatpak_dir_get_remote_disabled (FlatpakDir *self,
                                 const char *remote_name)
{
  GKeyFile *config = flatpak_dir_get_repo_config (self);
  g_autofree char *group = get_group (remote_name);

  if (config &&
      g_key_file_get_boolean (config, group, "xa.disable", NULL))
    return TRUE;

  if (self->repo)
    {
      g_autoptr(GError) error = NULL;
      g_autofree char *url = NULL;

      if (!ostree_repo_remote_get_url (self->repo, remote_name, &url, &error))
        {
          g_debug ("Unable to get the URL for remote %s: %s", remote_name, error->message);
          return FALSE;
        }

      if (*url == 0)
        return TRUE; /* Empty URL => disabled */
    }

  return FALSE;
}

static char *
flatpak_dir_get_remote_signature_lookaside (FlatpakDir *self,
                                            const char *remote_name)
{
  GKeyFile *config = flatpak_dir_get_repo_config (self);
  g_autofree char *group = get_group (remote_name);
  g_autofree char *signature_lookaside = NULL;

  signature_lookaside = g_key_file_get_string (config, group, "xa.signature-lookaside", NULL);
  if (signature_lookaside == NULL || *signature_lookaside == '\0')
    return NULL;

  return g_steal_pointer (&signature_lookaside);
}

static char *
flatpak_dir_get_remote_install_authenticator_name (FlatpakDir *self,
                                                   const char *remote_name)
{
  GKeyFile *config = flatpak_dir_get_repo_config (self);
  g_autofree char *group = get_group (remote_name);

  if (config == NULL ||
      !g_key_file_get_boolean (config, group, "xa.authenticator-install", NULL))
    return NULL;

  return g_key_file_get_string (config, group, "xa.authenticator-name", NULL);
}

gboolean
flatpak_dir_remote_has_deploys (FlatpakDir *self,
                                const char *remote)
{
  g_autoptr(GHashTable) refs = NULL;
  GHashTableIter hash_iter;
  gpointer key;

  refs = flatpak_dir_get_all_installed_refs (self, FLATPAK_KINDS_APP | FLATPAK_KINDS_RUNTIME, NULL);
  if (refs == NULL)
    return FALSE;

  g_hash_table_iter_init (&hash_iter, refs);
  while (g_hash_table_iter_next (&hash_iter, &key, NULL))
    {
      FlatpakDecomposed *ref = key;
      g_autofree char *origin = flatpak_dir_get_origin (self, ref, NULL, NULL);

      if (strcmp (remote, origin) == 0)
        return TRUE;
    }

  return FALSE;
}

static gint
cmp_remote (gconstpointer a,
            gconstpointer b,
            gpointer      user_data)
{
  FlatpakDir *self = user_data;
  const char *a_name = *(const char **) a;
  const char *b_name = *(const char **) b;
  int prio_a, prio_b;

  prio_a = flatpak_dir_get_remote_prio (self, a_name);
  prio_b = flatpak_dir_get_remote_prio (self, b_name);

  if (prio_b != prio_a)
    return prio_b - prio_a;

  /* Ensure we have a well-defined order for same prio */
  return strcmp (a_name, b_name);
}

static gboolean
origin_remote_matches (OstreeRepo *repo,
                       const char *remote_name,
                       const char *url,
                       const char *main_ref,
                       gboolean    gpg_verify)
{
  g_autofree char *real_url = NULL;
  g_autofree char *real_main_ref = NULL;
  gboolean noenumerate;
  gboolean real_gpg_verify;

  /* Must match url */
  if (url == NULL)
    return FALSE;

  if (!ostree_repo_remote_get_url (repo, remote_name, &real_url, NULL))
    return FALSE;

  if (g_strcmp0 (url, real_url) != 0)
    return FALSE;

  /* Must be noenumerate */
  if (!ostree_repo_get_remote_boolean_option (repo, remote_name,
                                              "xa.noenumerate",
                                              FALSE, &noenumerate,
                                              NULL) ||
      !noenumerate)
    return FALSE;

  /* Must match gpg-verify
   * NOTE: We assume if all else matches the actual gpg key matches too. */
  if (!ostree_repo_get_remote_boolean_option (repo, remote_name,
                                              "gpg-verify",
                                              FALSE, &real_gpg_verify,
                                              NULL) ||
      real_gpg_verify != gpg_verify)
    return FALSE;

  /* Must match main-ref */
  if (ostree_repo_get_remote_option (repo, remote_name,
                                     "xa.main-ref",
                                     NULL, &real_main_ref,
                                     NULL) &&
      g_strcmp0 (main_ref, real_main_ref) != 0)
    return FALSE;

  return TRUE;
}

static char *
create_origin_remote_config (OstreeRepo *repo,
                             const char *url,
                             const char *id,
                             const char *title,
                             const char *main_ref,
                             gboolean    gpg_verify,
                             const char *collection_id,
                             GKeyFile  **new_config)
{
  g_autofree char *remote = NULL;
  g_auto(GStrv) remotes = NULL;
  int version = 0;
  g_autofree char *group = NULL;
  g_autofree char *prefix = NULL;
  const char *last_dot;

  remotes = ostree_repo_remote_list (repo, NULL);

  last_dot = strrchr (id, '.');
  prefix = g_ascii_strdown (last_dot ? last_dot + 1 : id, -1);

  do
    {
      g_autofree char *name = NULL;
      if (version == 0)
        name = g_strdup_printf ("%s-origin", prefix);
      else
        name = g_strdup_printf ("%s%d-origin", prefix, version);
      version++;

      if (origin_remote_matches (repo, name, url, main_ref, gpg_verify))
        return g_steal_pointer (&name);

      if (remotes == NULL ||
          !g_strv_contains ((const char * const *) remotes, name))
        remote = g_steal_pointer (&name);
    }
  while (remote == NULL);

  group = g_strdup_printf ("remote \"%s\"", remote);

  *new_config = g_key_file_new ();

  g_key_file_set_string (*new_config, group, "url", url ? url : "");
  if (title)
    g_key_file_set_string (*new_config, group, "xa.title", title);
  g_key_file_set_string (*new_config, group, "xa.noenumerate", "true");
  g_key_file_set_string (*new_config, group, "xa.prio", "0");
  g_key_file_set_string (*new_config, group, "gpg-verify-summary", gpg_verify ? "true" : "false");
  g_key_file_set_string (*new_config, group, "gpg-verify", gpg_verify ? "true" : "false");
  if (main_ref)
    g_key_file_set_string (*new_config, group, "xa.main-ref", main_ref);

  if (collection_id)
    g_key_file_set_string (*new_config, group, "collection-id", collection_id);

  return g_steal_pointer (&remote);
}

char *
flatpak_dir_create_origin_remote (FlatpakDir   *self,
                                  const char   *url,
                                  const char   *id,
                                  const char   *title,
                                  const char   *main_ref,
                                  GBytes       *gpg_data,
                                  const char   *collection_id,
                                  gboolean     *changed_config,
                                  GCancellable *cancellable,
                                  GError      **error)
{
  g_autoptr(GKeyFile) new_config = NULL;
  g_autofree char *remote = NULL;

  remote = create_origin_remote_config (self->repo, url, id, title, main_ref, gpg_data != NULL, collection_id, &new_config);

  if (new_config &&
      !flatpak_dir_modify_remote (self, remote, new_config,
                                  gpg_data, cancellable, error))
    return NULL;

  if (new_config && !_flatpak_dir_reload_config (self, cancellable, error))
    return FALSE;

  if (changed_config)
    *changed_config = (new_config != NULL);

  return g_steal_pointer (&remote);
}

static gboolean
parse_ref_file (GKeyFile *keyfile,
                char    **name_out,
                char    **branch_out,
                char    **url_out,
                GBytes  **gpg_data_out,
                gboolean *is_runtime_out,
                char    **collection_id_out,
                GError  **error)
{
  g_autofree char *url = NULL;
  g_autofree char *name = NULL;
  g_autofree char *branch = NULL;
  g_autofree char *version = NULL;
  g_autoptr(GBytes) gpg_data = NULL;
  gboolean is_runtime = FALSE;
  g_autofree char *collection_id = NULL;
  g_autofree char *str = NULL;

  *name_out = NULL;
  *branch_out = NULL;
  *url_out = NULL;
  *gpg_data_out = NULL;
  *is_runtime_out = FALSE;
  *collection_id_out = NULL;

  if (!g_key_file_has_group (keyfile, FLATPAK_REF_GROUP))
    return flatpak_fail_error (error, FLATPAK_ERROR_INVALID_DATA, _("Invalid file format, no %s group"), FLATPAK_REF_GROUP);

  version = g_key_file_get_string (keyfile, FLATPAK_REF_GROUP,
                                   FLATPAK_REF_VERSION_KEY, NULL);
  if (version != NULL && strcmp (version, "1") != 0)
    return flatpak_fail_error (error, FLATPAK_ERROR_INVALID_DATA, _("Invalid version %s, only 1 supported"), version);

  url = g_key_file_get_string (keyfile, FLATPAK_REF_GROUP,
                               FLATPAK_REF_URL_KEY, NULL);
  if (url == NULL)
    return flatpak_fail_error (error, FLATPAK_ERROR_INVALID_DATA, _("Invalid file format, no %s specified"), FLATPAK_REF_URL_KEY);

  name = g_key_file_get_string (keyfile, FLATPAK_REF_GROUP,
                                FLATPAK_REF_NAME_KEY, NULL);
  if (name == NULL)
    return flatpak_fail_error (error, FLATPAK_ERROR_INVALID_DATA, _("Invalid file format, no %s specified"), FLATPAK_REF_NAME_KEY);

  branch = g_key_file_get_string (keyfile, FLATPAK_REF_GROUP,
                                  FLATPAK_REF_BRANCH_KEY, NULL);
  if (branch == NULL)
    branch = g_strdup ("master");

  is_runtime = g_key_file_get_boolean (keyfile, FLATPAK_REF_GROUP,
                                       FLATPAK_REF_IS_RUNTIME_KEY, NULL);

  str = g_key_file_get_string (keyfile, FLATPAK_REF_GROUP,
                               FLATPAK_REF_GPGKEY_KEY, NULL);
  if (str != NULL)
    {
      g_autofree guchar *decoded = NULL;
      gsize decoded_len;

      str = g_strstrip (str);
      decoded = g_base64_decode (str, &decoded_len);
      if (decoded_len < 10) /* Check some minimal size so we don't get crap */
        return flatpak_fail_error (error, FLATPAK_ERROR_INVALID_DATA, _("Invalid file format, gpg key invalid"));

      gpg_data = g_bytes_new_take (g_steal_pointer (&decoded), decoded_len);
    }

  /* We have a hierarchy of keys for setting the collection ID, which all have
   * the same effect. The only difference is which versions of Flatpak support
   * them, and therefore what P2P implementation is enabled by them:
   * DeploySideloadCollectionID: supported by Flatpak >= 1.12.8 (1.7.1
   *   introduced sideload support but this key was added late)
   * DeployCollectionID: supported by Flatpak >= 1.0.6
   * CollectionID: supported by Flatpak >= 0.9.8
   */
  collection_id = flatpak_keyfile_get_string_non_empty (keyfile, FLATPAK_REF_GROUP,
                                                        FLATPAK_REF_DEPLOY_SIDELOAD_COLLECTION_ID_KEY);

  if (collection_id == NULL)
    {
      collection_id = flatpak_keyfile_get_string_non_empty (keyfile, FLATPAK_REF_GROUP,
                                                            FLATPAK_REF_DEPLOY_COLLECTION_ID_KEY);
    }
  if (collection_id == NULL)
    {
      collection_id = flatpak_keyfile_get_string_non_empty (keyfile, FLATPAK_REF_GROUP,
                                                            FLATPAK_REF_COLLECTION_ID_KEY);
    }

  if (collection_id != NULL && gpg_data == NULL)
    return flatpak_fail_error (error, FLATPAK_ERROR_INVALID_DATA, _("Collection ID requires GPG key to be provided"));

  *name_out = g_steal_pointer (&name);
  *branch_out = g_steal_pointer (&branch);
  *url_out = g_steal_pointer (&url);
  *gpg_data_out = g_steal_pointer (&gpg_data);
  *is_runtime_out = is_runtime;
  *collection_id_out = g_steal_pointer (&collection_id);

  return TRUE;
}

gboolean
flatpak_dir_create_remote_for_ref_file (FlatpakDir         *self,
                                        GKeyFile           *keyfile,
                                        const char         *default_arch,
                                        char              **remote_name_out,
                                        char              **collection_id_out,
                                        FlatpakDecomposed **ref_out,
                                        GError            **error)
{
  g_autoptr(GBytes) gpg_data = NULL;
  g_autofree char *name = NULL;
  g_autofree char *branch = NULL;
  g_autofree char *url = NULL;
  g_autofree char *remote = NULL;
  gboolean is_runtime = FALSE;
  g_autofree char *collection_id = NULL;
  g_autoptr(GFile) deploy_dir = NULL;
  g_autoptr(FlatpakDecomposed) ref = NULL;

  if (!parse_ref_file (keyfile, &name, &branch, &url, &gpg_data, &is_runtime, &collection_id, error))
    return FALSE;

  ref = flatpak_decomposed_new_from_parts (is_runtime ? FLATPAK_KINDS_RUNTIME : FLATPAK_KINDS_APP,
                                           name, default_arch, branch, error);
  if (ref == NULL)
    return FALSE;

  deploy_dir = flatpak_dir_get_if_deployed (self, ref, NULL, NULL);
  if (deploy_dir != NULL)
    {
      g_set_error (error, FLATPAK_ERROR, FLATPAK_ERROR_ALREADY_INSTALLED,
                   is_runtime ? _("Runtime %s, branch %s is already installed") :
                   _("App %s, branch %s is already installed"),
                   name, branch);
      return FALSE;
    }

  /* First try to reuse existing remote */
  remote = flatpak_dir_find_remote_by_uri (self, url);

  if (remote == NULL)
    {
      /* title is NULL because the title from the ref file is the title of the app not the remote */
      remote = flatpak_dir_create_origin_remote (self, url, name, NULL, flatpak_decomposed_get_ref (ref),
                                                 gpg_data, collection_id, NULL, NULL, error);
      if (remote == NULL)
        return FALSE;
    }

  if (collection_id_out != NULL)
    *collection_id_out = g_steal_pointer (&collection_id);

  *remote_name_out = g_steal_pointer (&remote);
  *ref_out = g_steal_pointer (&ref);
  return TRUE;
}

/* This tries to find a pre-configured remote for the specified uri.
 *
 *  We consider non-OCI URLs equal even if one lacks a trailing slash.
 */
char *
flatpak_dir_find_remote_by_uri (FlatpakDir *self,
                                const char *uri)
{
  g_auto(GStrv) remotes = NULL;

  g_return_val_if_fail (self != NULL, NULL);
  g_return_val_if_fail (uri != NULL, NULL);

  if (!flatpak_dir_ensure_repo (self, NULL, NULL))
    return NULL;

  remotes = flatpak_dir_list_enumerated_remotes (self, NULL, NULL);
  if (remotes)
    {
      int i;

      for (i = 0; remotes != NULL && remotes[i] != NULL; i++)
        {
          const char *remote = remotes[i];
          g_autofree char *remote_uri = NULL;

          if (!ostree_repo_remote_get_url (self->repo,
                                           remote,
                                           &remote_uri,
                                           NULL))
            continue;

          if (flatpak_uri_equal (uri, remote_uri))
            return g_strdup (remote);
        }
    }

  return NULL;
}

gboolean
flatpak_dir_has_remote (FlatpakDir *self,
                        const char *remote_name,
                        GError    **error)
{
  GKeyFile *config = NULL;
  g_autofree char *group = g_strdup_printf ("remote \"%s\"", remote_name);

  if (flatpak_dir_maybe_ensure_repo (self, NULL, NULL) &&
      self->repo != NULL)
    {
      config = ostree_repo_get_config (self->repo);
      if (config && g_key_file_has_group (config, group))
        return TRUE;
    }

  return flatpak_fail_error (error, FLATPAK_ERROR_REMOTE_NOT_FOUND,
                             "Remote \"%s\" not found", remote_name);
}


char **
flatpak_dir_list_remotes (FlatpakDir   *self,
                          GCancellable *cancellable,
                          GError      **error)
{
  char **res = NULL;

  if (!flatpak_dir_maybe_ensure_repo (self, cancellable, error))
    return NULL;

  if (self->repo)
    res = ostree_repo_remote_list (self->repo, NULL);

  if (res == NULL)
    res = g_new0 (char *, 1); /* Return empty array, not error */

  qsort_r (res, g_strv_length (res), sizeof (char *), cmp_remote, self);

  return res;
}

char **
flatpak_dir_list_enumerated_remotes (FlatpakDir   *self,
                                     GCancellable *cancellable,
                                     GError      **error)
{
  g_autoptr(GPtrArray) res = g_ptr_array_new_with_free_func (g_free);
  g_auto(GStrv) remotes = NULL;
  int i;

  remotes = flatpak_dir_list_remotes (self, cancellable, error);
  if (remotes == NULL)
    return NULL;

  for (i = 0; remotes != NULL && remotes[i] != NULL; i++)
    {
      const char *remote = remotes[i];

      if (flatpak_dir_get_remote_disabled (self, remote))
        continue;

      if (flatpak_dir_get_remote_noenumerate (self, remote))
        continue;

      g_ptr_array_add (res, g_strdup (remote));
    }

  g_ptr_array_add (res, NULL);
  return (char **) g_ptr_array_free (g_steal_pointer (&res), FALSE);
}

char **
flatpak_dir_list_dependency_remotes (FlatpakDir   *self,
                                     GCancellable *cancellable,
                                     GError      **error)
{
  g_autoptr(GPtrArray) res = g_ptr_array_new_with_free_func (g_free);
  g_auto(GStrv) remotes = NULL;
  int i;

  remotes = flatpak_dir_list_remotes (self, cancellable, error);
  if (remotes == NULL)
    return NULL;

  for (i = 0; remotes != NULL && remotes[i] != NULL; i++)
    {
      const char *remote = remotes[i];

      if (flatpak_dir_get_remote_disabled (self, remote))
        continue;

      if (flatpak_dir_get_remote_noenumerate (self, remote))
        continue;

      if (flatpak_dir_get_remote_nodeps (self, remote))
        continue;

      g_ptr_array_add (res, g_strdup (remote));
    }

  g_ptr_array_add (res, NULL);
  return (char **) g_ptr_array_free (g_steal_pointer (&res), FALSE);
}

gboolean
flatpak_dir_remove_remote (FlatpakDir   *self,
                           gboolean      force_remove,
                           const char   *remote_name,
                           GCancellable *cancellable,
                           GError      **error)
{
  g_autofree char *prefix = NULL;
  g_autoptr(GHashTable) refs = NULL;
  GHashTableIter hash_iter;
  gpointer key;
  g_autofree char *url = NULL;
  g_autoptr(GError) local_error = NULL;

  if (flatpak_dir_use_system_helper (self, NULL))
    {
      g_autoptr(GVariant) gpg_data_v = NULL;
      FlatpakHelperConfigureRemoteFlags flags = 0;
      const char *installation = flatpak_dir_get_id (self);

      gpg_data_v = g_variant_ref_sink (g_variant_new_from_data (G_VARIANT_TYPE ("ay"), "", 0, TRUE, NULL, NULL));

      if (force_remove)
        flags |= FLATPAK_HELPER_CONFIGURE_REMOTE_FLAGS_FORCE_REMOVE;

      if (!flatpak_dir_system_helper_call_configure_remote (self,
                                                            flags, remote_name,
                                                            "",
                                                            gpg_data_v,
                                                            installation ? installation : "",
                                                            cancellable, error))
        return FALSE;

      return TRUE;
    }

  if (!flatpak_dir_ensure_repo (self, cancellable, error))
    return FALSE;

  if (!ostree_repo_list_refs (self->repo,
                              NULL,
                              &refs,
                              cancellable, error))
    return FALSE;

  prefix = g_strdup_printf ("%s:", remote_name);

  if (!force_remove)
    {
      g_hash_table_iter_init (&hash_iter, refs);
      while (g_hash_table_iter_next (&hash_iter, &key, NULL))
        {
          const char *refspec = key;

          if (!g_str_has_prefix (refspec, prefix))
            continue;

          g_autoptr(FlatpakDecomposed) ref = flatpak_decomposed_new_from_refspec (refspec, NULL);
          if (ref == NULL)
            continue;

          g_autofree char *origin = flatpak_dir_get_origin (self, ref, cancellable, NULL);
          if (g_strcmp0 (origin, remote_name) == 0)
            return flatpak_fail_error (error, FLATPAK_ERROR_REMOTE_USED,
                                       _("Can't remove remote '%s' with installed ref %s (at least)"),
                                       remote_name, flatpak_decomposed_get_ref (ref));
        }
    }

  /* Remove all refs */
  g_hash_table_iter_init (&hash_iter, refs);
  while (g_hash_table_iter_next (&hash_iter, &key, NULL))
    {
      const char *refspec = key;

      if (g_str_has_prefix (refspec, prefix) &&
          !flatpak_dir_remove_ref (self, remote_name, refspec + strlen (prefix), cancellable, error))
        return FALSE;
    }

  if (!flatpak_dir_remove_appstream (self, remote_name,
                                     cancellable, error))
    return FALSE;

  if (flatpak_dir_get_remote_oci (self, remote_name) &&
      !flatpak_dir_remove_oci_files (self, remote_name,
                                     cancellable, error))
    return FALSE;

  if (!ostree_repo_remote_get_url (self->repo, remote_name, &url, &local_error))
    {
      g_debug ("Unable to get the URL for remote %s: %s", remote_name, local_error->message);
      g_clear_error (&local_error);
    }

  if (!ostree_repo_remote_change (self->repo, NULL,
                                  OSTREE_REPO_REMOTE_CHANGE_DELETE,
                                  remote_name, NULL,
                                  NULL,
                                  cancellable, error))
    return FALSE;

  if (!flatpak_dir_mark_changed (self, error))
    return FALSE;

  flatpak_dir_log (self, "remove remote",
                   remote_name, NULL, NULL, NULL, url,
                   "Removed remote %s", remote_name);

  return TRUE;
}

static gboolean
flatpak_dir_cleanup_remote_for_url_change (FlatpakDir   *self,
                                           const char   *remote_name,
                                           const char   *url,
                                           GCancellable *cancellable,
                                           GError      **error)
{
  g_autofree char *old_url = NULL;

  /* We store things a bit differently for OCI and non-OCI remotes,
   * so when changing from one to the other, we need to clean up cached
   * files.
   */
  if (ostree_repo_remote_get_url (self->repo,
                                  remote_name,
                                  &old_url,
                                  NULL))
    {
      gboolean was_oci = g_str_has_prefix (old_url, "oci+");
      gboolean will_be_oci = g_str_has_prefix (url, "oci+");

      if (was_oci != will_be_oci)
        {
          if (!flatpak_dir_remove_appstream (self, remote_name,
                                             cancellable, error))
            return FALSE;
        }

      if (was_oci && !will_be_oci)
        {
          if (!flatpak_dir_remove_oci_files (self, remote_name,
                                             cancellable, error))
            return FALSE;
        }
    }

  return TRUE;
}

gboolean
flatpak_dir_modify_remote (FlatpakDir   *self,
                           const char   *remote_name,
                           GKeyFile     *config,
                           GBytes       *gpg_data,
                           GCancellable *cancellable,
                           GError      **error)
{
  g_autofree char *group = g_strdup_printf ("remote \"%s\"", remote_name);
  g_autofree char *url = NULL;
  g_autofree char *metalink = NULL;
  g_autoptr(GKeyFile) old_config = NULL;
  g_autoptr(GKeyFile) new_config = NULL;
  g_autofree gchar *filter_path = NULL;
  gboolean has_remote;
  gboolean res = FALSE;

  if (strchr (remote_name, '/') != NULL)
    return flatpak_fail_error (error, FLATPAK_ERROR_REMOTE_NOT_FOUND, _("Invalid character '/' in remote name: %s"),
                               remote_name);

  has_remote = flatpak_dir_has_remote (self, remote_name, NULL);

  if (!g_key_file_has_group (config, group))
    return flatpak_fail_error (error, FLATPAK_ERROR_INVALID_DATA, _("No configuration for remote %s specified"),
                               remote_name);

  if (!flatpak_dir_check_add_remotes_config_dir (self, error))
    return FALSE;

  if (flatpak_dir_use_system_helper (self, NULL))
    {
      g_autofree char *config_data = g_key_file_to_data (config, NULL, NULL);
      g_autoptr(GVariant) gpg_data_v = NULL;
      const char *installation = flatpak_dir_get_id (self);

      if (gpg_data != NULL)
        gpg_data_v = variant_new_ay_bytes (gpg_data);
      else
        gpg_data_v = g_variant_ref_sink (g_variant_new_from_data (G_VARIANT_TYPE ("ay"), "", 0, TRUE, NULL, NULL));

      if (!flatpak_dir_system_helper_call_configure_remote (self,
                                                            0, remote_name,
                                                            config_data,
                                                            gpg_data_v,
                                                            installation ? installation : "",
                                                            cancellable, error))
        return FALSE;

      /* If we e.g. changed url or gpg config the cached summary may be invalid */
      if (!flatpak_dir_remote_clear_cached_summary (self, remote_name, cancellable, error))
        return FALSE;

      return TRUE;
    }

  metalink = g_key_file_get_string (config, group, "metalink", NULL);
  if (metalink != NULL && *metalink != 0)
    url = g_strconcat ("metalink=", metalink, NULL);
  else
    url = g_key_file_get_string (config, group, "url", NULL);

  /* No url => disabled */
  if (url == NULL)
    url = g_strdup ("");

  if (!flatpak_dir_cleanup_remote_for_url_change (self, remote_name, url, cancellable, error))
    return FALSE;

  old_config = ostree_repo_copy_config (self->repo);

  /* Add it if its not there yet */
  if (!ostree_repo_remote_change (self->repo, NULL,
                                  OSTREE_REPO_REMOTE_CHANGE_ADD_IF_NOT_EXISTS,
                                  remote_name,
                                  url, NULL, cancellable, error))
    return FALSE;

  new_config = ostree_repo_copy_config (self->repo);

  copy_remote_config (new_config, config, remote_name);

  if (!ostree_repo_write_config (self->repo, new_config, error))
    goto out;

  filter_path = g_key_file_get_value (new_config, group, "xa.filter", NULL);
  if (filter_path && *filter_path && g_file_test (filter_path, G_FILE_TEST_EXISTS))
    {
      /* Make a backup filter copy in case it goes away later */
      g_autofree char *filter_name = g_strconcat (remote_name, ".filter", NULL);
      g_autoptr(GFile) filter_file = g_file_new_for_path (filter_path);
      g_autoptr(GFile) filter_copy = flatpak_build_file (self->basedir, "repo", filter_name, NULL);
      g_autoptr(GError) local_error = NULL;
      g_autofree char *backup_data = NULL;
      gsize backup_data_size;

      if (g_file_load_contents (filter_file, cancellable, &backup_data, &backup_data_size, NULL, &local_error))
        {
          g_autofree char *backup_data_copy =
            g_strdup_printf ("# backup copy of %s, do not edit!\n%s", filter_path, backup_data);

          if (!g_file_replace_contents (filter_copy, backup_data_copy, strlen (backup_data_copy),
                                        NULL, FALSE, G_FILE_CREATE_REPLACE_DESTINATION, NULL, cancellable, &local_error))
            g_info ("Failed to save backup copy of filter file %s: %s\n", filter_path, local_error->message);
        }
      else
        {
          g_info ("Failed to read filter %s file while making a backup copy: %s\n", filter_path, local_error->message);
        }
    }

  /* If we e.g. changed url or gpg config the cached summary may be invalid */
  if (!flatpak_dir_remote_clear_cached_summary (self, remote_name, cancellable, error))
    goto out;

  if (gpg_data != NULL)
    {
      g_autoptr(GInputStream) input_stream = g_memory_input_stream_new_from_bytes (gpg_data);
      guint imported = 0;

      if (!ostree_repo_remote_gpg_import (self->repo, remote_name, input_stream,
                                          NULL, &imported, cancellable, error))
        goto out;

      /* XXX If we ever add internationalization, use ngettext() here. */
      g_info ("Imported %u GPG key%s to remote \"%s\"",
              imported, (imported == 1) ? "" : "s", remote_name);
    }

  {
    g_autoptr(GError) local_error = NULL;

    if (!flatpak_dir_mark_changed (self, &local_error))
      g_warning ("Failed to mark dir as changed: %s", local_error->message);
  }

  if (has_remote)
    flatpak_dir_log (self, "modify remote", remote_name, NULL, NULL, NULL, url,
                     "Modified remote %s to %s", remote_name, url);
  else
    flatpak_dir_log (self, "add remote", remote_name, NULL, NULL, NULL, url,
                     "Added remote %s to %s", remote_name, url);

  res = TRUE;
out:
  if (!res)
    {
      /* Roll back the changes. Ideally they would be atomic, because if the
       * program terminates before we roll back, we end up in a broken state */
      ostree_repo_write_config (self->repo, old_config, NULL);
      ostree_repo_reload_config (self->repo, NULL, NULL);
    }
  return res;
}

gboolean
flatpak_dir_list_remote_refs (FlatpakDir         *self,
                              FlatpakRemoteState *state,
                              GHashTable        **refs,
                              GCancellable       *cancellable,
                              GError            **error)
{
  g_autoptr(GError) my_error = NULL;

  if (error == NULL)
    error = &my_error;

  if (!flatpak_dir_list_all_remote_refs (self, state, refs,
                                         cancellable, error))
    return FALSE;

  if (flatpak_dir_get_remote_noenumerate (self, state->remote_name))
    {
      g_autoptr(GHashTable) decomposed_local_refs =
        g_hash_table_new_full ((GHashFunc)flatpak_decomposed_hash, (GEqualFunc)flatpak_decomposed_equal, (GDestroyNotify)flatpak_decomposed_unref, NULL);
      g_autoptr(GHashTable) local_refs = NULL;
      g_autoptr(FlatpakDecomposed) decomposed_main_ref = NULL;
      GHashTableIter hash_iter;
      gpointer key;
      g_autofree char *refspec_prefix = g_strconcat (state->remote_name, ":.", NULL);
      g_autofree char *remote_main_ref = NULL;

      /* For noenumerate remotes, only return data for already locally
       * available refs, or the ref set as xa.main-ref on the remote, or
       * extensions of that main ref */

      if (!ostree_repo_list_refs (self->repo, refspec_prefix, &local_refs,
                                  cancellable, error))
        return FALSE;

      g_hash_table_iter_init (&hash_iter, local_refs);
      while (g_hash_table_iter_next (&hash_iter, &key, NULL))
        {
          const char *refspec = key;
          g_autofree char *ref = NULL;
          g_autoptr(FlatpakDecomposed) d = NULL;

          if (!ostree_parse_refspec (refspec, NULL, &ref, error))
            return FALSE;

          d = flatpak_decomposed_new_from_ref (ref, NULL);
          if (d)
            g_hash_table_insert (decomposed_local_refs, g_steal_pointer (&d), NULL);
        }

      remote_main_ref = flatpak_dir_get_remote_main_ref (self, state->remote_name);
      if (remote_main_ref != NULL && *remote_main_ref != '\0')
        decomposed_main_ref = flatpak_decomposed_new_from_col_ref (remote_main_ref, state->collection_id, NULL);

      /* Then we remove all remote refs not in the local refs set, not the main
       * ref, and not an extension of the main ref */
      GLNX_HASH_TABLE_FOREACH_IT (*refs, it, FlatpakDecomposed *, d, void *, v)
        {
          if (g_hash_table_contains (decomposed_local_refs, d))
            continue;

          if (decomposed_main_ref != NULL)
            {
              g_autofree char *main_ref_id = NULL;
              g_autofree char *main_ref_prefix = NULL;

              if (flatpak_decomposed_equal (decomposed_main_ref, d))
                continue;

              main_ref_id = flatpak_decomposed_dup_id (decomposed_main_ref);
              main_ref_prefix = g_strconcat (main_ref_id, ".", NULL);
              if (flatpak_decomposed_id_has_prefix (d, main_ref_prefix))
                continue;
            }

          g_hash_table_iter_remove (&it);
      }
    }

  return TRUE;
}

static gboolean
strv_contains_prefix (const gchar * const *strv,
                      const gchar         *str)
{
  g_return_val_if_fail (strv != NULL, FALSE);
  g_return_val_if_fail (str != NULL, FALSE);

  for (; *strv != NULL; strv++)
    {
      if (g_str_has_prefix (str, *strv))
        return TRUE;
    }

  return FALSE;
}

gboolean
flatpak_dir_update_remote_configuration_for_state (FlatpakDir         *self,
                                                   FlatpakRemoteState *remote_state,
                                                   gboolean            dry_run,
                                                   gboolean           *has_changed_out,
                                                   GCancellable       *cancellable,
                                                   GError            **error)
{
  /* We only support those configuration parameters that can
     be set in the server when building the repo (see the
     flatpak_repo_set_* () family of functions) */
  static const char *const supported_params[] = {
    "xa.title",
    "xa.comment",
    "xa.description",
    "xa.homepage",
    "xa.icon",
    "xa.default-branch",
    "xa.gpg-keys",
    "xa.redirect-url",
    "xa.authenticator-name",
    "xa.authenticator-install",
    OSTREE_META_KEY_DEPLOY_COLLECTION_ID,
    "xa.deploy-collection-id", /* This is a new version only supported in post p2p flatpak (1.7) */
    NULL
  };
  static const char *const supported_param_prefixes[] = {
    "xa.authenticator-options.",
    NULL
  };
  g_autoptr(GPtrArray) updated_params = NULL;
  g_autoptr(GVariant) metadata = NULL;
  GVariantIter iter;
  g_autoptr(GBytes) gpg_keys = NULL;

  updated_params = g_ptr_array_new_with_free_func (g_free);

  if (!flatpak_remote_state_ensure_summary (remote_state, error))
    return FALSE;

  if (remote_state->index)
    metadata = g_variant_get_child_value (remote_state->index, 1);
  else
    metadata = g_variant_get_child_value (remote_state->summary, 1);

  g_variant_iter_init (&iter, metadata);
  if (g_variant_iter_n_children (&iter) > 0)
    {
      GVariant *value_var = NULL;
      char *key = NULL;

      while (g_variant_iter_next (&iter, "{sv}", &key, &value_var))
        {
          if (g_strv_contains (supported_params, key) ||
              strv_contains_prefix (supported_param_prefixes, key))
            {
              if (strcmp (key, "xa.gpg-keys") == 0)
                {
                  if (g_variant_is_of_type (value_var, G_VARIANT_TYPE_BYTESTRING))
                    {
                      const guchar *gpg_data = g_variant_get_data (value_var);
                      gsize gpg_size = g_variant_get_size (value_var);
                      g_autofree gchar *gpg_data_checksum = g_compute_checksum_for_data (G_CHECKSUM_SHA256, gpg_data, gpg_size);

                      gpg_keys = g_bytes_new (gpg_data, gpg_size);

                      /* We store the hash so that we can detect when things changed or not
                         instead of re-importing the key over-and-over */
                      g_ptr_array_add (updated_params, g_strdup ("xa.gpg-keys-hash"));
                      g_ptr_array_add (updated_params, g_steal_pointer (&gpg_data_checksum));
                    }
                }
              else if (g_variant_is_of_type (value_var, G_VARIANT_TYPE_STRING))
                {
                  const char *value = g_variant_get_string (value_var, NULL);
                  if (value != NULL && *value != 0)
                    {
                      if (strcmp (key, "xa.redirect-url") == 0)
                        g_ptr_array_add (updated_params, g_strdup ("url"));
                      else if (strcmp (key, OSTREE_META_KEY_DEPLOY_COLLECTION_ID) == 0)
                        g_ptr_array_add (updated_params, g_strdup ("collection-id"));
                      else if (strcmp (key, "xa.deploy-collection-id") == 0)
                        g_ptr_array_add (updated_params, g_strdup ("collection-id"));
                      else
                        g_ptr_array_add (updated_params, g_strdup (key));
                      g_ptr_array_add (updated_params, g_strdup (value));
                    }
                }
              else if (g_variant_is_of_type (value_var, G_VARIANT_TYPE_BOOLEAN))
                {
                  gboolean value = g_variant_get_boolean (value_var);
                  g_ptr_array_add (updated_params, g_strdup (key));
                  if (value)
                    g_ptr_array_add (updated_params, g_strdup ("true"));
                  else
                    g_ptr_array_add (updated_params, g_strdup ("false"));
                }
            }

          g_variant_unref (value_var);
          g_free (key);
        }
    }

  if (updated_params->len > 0)
    {
      g_autoptr(GKeyFile) config = NULL;
      g_autofree char *group = NULL;
      gboolean has_changed = FALSE;
      int i;

      config = ostree_repo_copy_config (flatpak_dir_get_repo (self));
      group = g_strdup_printf ("remote \"%s\"", remote_state->remote_name);

      i = 0;
      while (i < (updated_params->len - 1))
        {
          /* This array should have an even number of elements with
             keys in the odd positions and values on even ones. */
          const char *key = g_ptr_array_index (updated_params, i);
          const char *new_val = g_ptr_array_index (updated_params, i + 1);
          g_autofree char *current_val = NULL;
          g_autofree char *is_set_key = g_strconcat (key, "-is-set", NULL);
          gboolean is_set = FALSE;

          is_set = g_key_file_get_boolean (config, group, is_set_key, NULL);
          if (!is_set)
            {
              current_val = g_key_file_get_string (config, group, key, NULL);
              if ((!g_str_equal (key, "collection-id") &&
                   g_strcmp0 (current_val, new_val) != 0) ||
                  (g_str_equal (key, "collection-id") &&
                   (current_val == NULL || *current_val == '\0') &&
                   new_val != NULL && *new_val != '\0'))
                {
                  has_changed = TRUE;
                  g_key_file_set_string (config, group, key, new_val);
                }
            }

          i += 2;
        }

      if (has_changed_out)
        *has_changed_out = has_changed;

      if (dry_run || !has_changed)
        return TRUE;

      /* Update the local remote configuration with the updated info. */
      if (!flatpak_dir_modify_remote (self, remote_state->remote_name, config, gpg_keys, cancellable, error))
        return FALSE;
    }

  return TRUE;
}

gboolean
flatpak_dir_update_remote_configuration (FlatpakDir   *self,
                                         const char   *remote,
                                         FlatpakRemoteState *optional_remote_state,
                                         gboolean     *updated_out,
                                         GCancellable *cancellable,
                                         GError      **error)
{
  gboolean is_oci;
  g_autoptr(FlatpakRemoteState) local_state = NULL;
  FlatpakRemoteState *state;
  gboolean has_changed = FALSE;

  /* Initialize if we exit early */
  if (updated_out)
    *updated_out = FALSE;

  if (flatpak_dir_get_remote_disabled (self, remote))
    return TRUE;

  is_oci = flatpak_dir_get_remote_oci (self, remote);
  if (is_oci)
    return TRUE;

  if (optional_remote_state)
    state = optional_remote_state;
  else
    {
      local_state = flatpak_dir_get_remote_state (self, remote, FALSE, cancellable, error);
      if (local_state == NULL)
        return FALSE;
      state = local_state;
    }

  if (flatpak_dir_use_system_helper (self, NULL))
    {
      gboolean gpg_verify_summary;
      gboolean gpg_verify;

      if (!ostree_repo_remote_get_gpg_verify_summary (self->repo, remote, &gpg_verify_summary, error))
        return FALSE;

      if (!ostree_repo_remote_get_gpg_verify (self->repo, remote, &gpg_verify, error))
        return FALSE;

      if (!gpg_verify_summary || !gpg_verify)
        {
          g_info ("Ignoring automatic updates for system-helper remotes without gpg signatures");
          return TRUE;
        }

      if ((state->summary != NULL && state->summary_sig_bytes == NULL) ||
          (state->index != NULL && state->index_sig_bytes == NULL))
        {
          g_info ("Can't update remote configuration as user, no GPG signature");
          return TRUE;
        }

      if (!flatpak_dir_update_remote_configuration_for_state (self, state, TRUE, &has_changed, cancellable, error))
        return FALSE;

      if (has_changed)
        {
          g_autoptr(GBytes) bytes = g_variant_get_data_as_bytes (state->index ? state->index : state->summary);
          GBytes *sig_bytes = state->index ? state->index_sig_bytes : state->summary_sig_bytes;
          glnx_autofd int summary_fd = -1;
          g_autofree char *summary_path = NULL;
          glnx_autofd int summary_sig_fd = -1;
          g_autofree char *summary_sig_path = NULL;
          const char *installation;
          FlatpakHelperUpdateRemoteFlags flags = 0;

          if (state->index)
            flags |= FLATPAK_HELPER_UPDATE_REMOTE_FLAGS_SUMMARY_IS_INDEX;

          summary_fd = g_file_open_tmp ("remote-summary.XXXXXX", &summary_path, error);
          if (summary_fd == -1)
            return FALSE;
          if (glnx_loop_write (summary_fd, g_bytes_get_data (bytes, NULL), g_bytes_get_size (bytes)) < 0)
            return glnx_throw_errno (error);

          if (sig_bytes != NULL)
            {
              summary_sig_fd = g_file_open_tmp ("remote-summary-sig.XXXXXX", &summary_sig_path, error);
              if (summary_sig_fd == -1)
                return FALSE;
              if (glnx_loop_write (summary_sig_fd, g_bytes_get_data (sig_bytes, NULL), g_bytes_get_size (sig_bytes)) < 0)
                return glnx_throw_errno (error);
            }

          installation = flatpak_dir_get_id (self);

          if (!flatpak_dir_system_helper_call_update_remote (self, flags, remote,
                                                             installation ? installation : "",
                                                             summary_path, summary_sig_path ? summary_sig_path : "",
                                                             cancellable, error))
            return FALSE;

          unlink (summary_path);
          if (summary_sig_path)
            unlink (summary_sig_path);


          if (!flatpak_dir_remote_clear_cached_summary (self, remote, cancellable, error))
            return FALSE;

        }

      if (updated_out)
        *updated_out = has_changed;

      return TRUE;
    }

  if (!flatpak_dir_update_remote_configuration_for_state (self, state, FALSE, &has_changed, cancellable, error))
    return FALSE;

  if (has_changed &&
      !flatpak_dir_remote_clear_cached_summary (self, remote, cancellable, error))
    return FALSE;

  if (updated_out)
    *updated_out = has_changed;

  return TRUE;
}

void
flatpak_related_free (FlatpakRelated *self)
{
  g_free (self->remote);
  flatpak_decomposed_unref (self->ref);
  g_free (self->commit);
  g_strfreev (self->subpaths);
  g_free (self);
}

static void
add_related (FlatpakDir        *self,
             GPtrArray         *related,
             const char        *remote,
             const char        *extension,
             FlatpakDecomposed *extension_ref,
             const char        *checksum,
             gboolean           no_autodownload,
             const char        *download_if,
             const char        *autoprune_unless,
             gboolean           autodelete,
             gboolean           locale_subset)
{
  g_autoptr(GBytes) deploy_data = NULL;
  g_autofree const char **old_subpaths = NULL;
  g_autofree const char *id = NULL;
  g_autofree const char *arch = NULL;
  g_autofree const char *branch = NULL;
  g_auto(GStrv) extra_subpaths = NULL;
  g_auto(GStrv) subpaths = NULL;
  FlatpakRelated *rel;
  gboolean download;
  gboolean delete = autodelete;
  gboolean auto_prune = FALSE;
  g_autoptr(GFile) unmaintained_path = NULL;

  deploy_data = flatpak_dir_get_deploy_data (self, extension_ref, FLATPAK_DEPLOY_VERSION_ANY, NULL, NULL);

  id = flatpak_decomposed_dup_id (extension_ref);
  arch = flatpak_decomposed_dup_arch (extension_ref);
  branch = flatpak_decomposed_dup_branch (extension_ref);

  if (deploy_data)
    {
      old_subpaths = flatpak_deploy_data_get_subpaths (deploy_data);
      /* If the extension is installed already, its origin overrides the remote
       * that would otherwise be used */
      remote = flatpak_deploy_data_get_origin (deploy_data);
    }

  /* Only respect no-autodownload/download-if for uninstalled refs, we
     always want to update if you manually installed something */
  download =
    flatpak_extension_matches_reason (id, download_if, !no_autodownload) ||
    deploy_data != NULL;

  /* Automatic branch following: if this extension wouldn't normally be
   * auto-downloaded, still download it if there's already an installed branch
   * of the same extension for this arch. This handles the case where an app
   * updates its extension version requirement. */
  if (!download)
    {
      g_autoptr(GPtrArray) installed_branches =
        flatpak_dir_list_refs_for_name (self, FLATPAK_KINDS_RUNTIME, id, NULL, NULL);

      for (size_t i = 0; installed_branches && i < installed_branches->len; i++)
        {
          FlatpakDecomposed *installed_ref = g_ptr_array_index (installed_branches, i);
          if (flatpak_decomposed_is_arch (installed_ref, arch))
            {
              download = TRUE;
              break;
            }
        }
    }

  if (!flatpak_extension_matches_reason (id, autoprune_unless, TRUE))
    auto_prune = TRUE;

  /* Don't download if there is an unmaintained extension already installed */
  /* TODO: This is a circular dependency between flatpak-dir (which
   * deals with a single installation) and flatpak-dir-utils (which
   * deals with all the installations on the system). */
  unmaintained_path =
    flatpak_find_unmaintained_extension_dir_if_exists (id, arch, branch, NULL);
  if (unmaintained_path != NULL && deploy_data == NULL)
    {
      g_info ("Skipping related extension ‘%s’ because it is already "
              "installed as an unmaintained extension in ‘%s’.",
              id, flatpak_file_get_path_cached (unmaintained_path));
      download = FALSE;
    }

  if (g_str_has_suffix (extension, ".Debug"))
    {
      /* debug files only updated if already installed */
      if (deploy_data == NULL)
        download = FALSE;

      /* Always remove debug */
      delete = TRUE;
    }

  if (g_str_has_suffix (extension, ".Locale"))
    locale_subset = TRUE;

  if (locale_subset)
    {
      extra_subpaths = flatpak_dir_get_locale_subpaths (self);

      /* Always remove locale */
      delete = TRUE;
    }

  subpaths = flatpak_subpaths_merge ((char **) old_subpaths, extra_subpaths);

  rel = g_new0 (FlatpakRelated, 1);
  rel->remote = g_strdup (remote);
  rel->ref = flatpak_decomposed_ref (extension_ref);
  rel->commit = g_strdup (checksum);
  rel->subpaths = g_steal_pointer (&subpaths);
  rel->download = download;
  rel->delete = delete;
  rel->auto_prune = auto_prune;

  g_ptr_array_add (related, rel);
}

static GRegex *
flatpak_dir_get_mask_regexp (FlatpakDir *self)
{
  GRegex *res = NULL;

  G_LOCK (config_cache);

  if (self->masked == NULL)
    {
      g_autofree char *masked = NULL;

      masked = flatpak_dir_get_config (self, "masked", NULL);
      if (masked)
        {
          g_auto(GStrv) patterns = g_strsplit (masked, ";", -1);
          g_autoptr(GString) deny_regexp = g_string_new ("^(");
          int i;

          for (i = 0; patterns[i] != NULL; i++)
            {
              const char *pattern = patterns[i];

              if (*pattern != 0)
                {
                  g_autofree char *regexp = NULL;

                  regexp = flatpak_filter_glob_to_regexp (pattern, FALSE, NULL);
                  if (regexp)
                    {
                      if (i != 0)
                        g_string_append (deny_regexp, "|");
                      g_string_append (deny_regexp, regexp);
                    }
                }
            }

          g_string_append (deny_regexp, ")$");
          self->masked = g_regex_new (deny_regexp->str, G_REGEX_DOLLAR_ENDONLY|G_REGEX_RAW|G_REGEX_OPTIMIZE, G_REGEX_MATCH_ANCHORED, NULL);
        }
    }

  if (self->masked)
    res = g_regex_ref (self->masked);

  G_UNLOCK (config_cache);

  return res;
}

gboolean
flatpak_dir_ref_is_masked (FlatpakDir *self,
                           const char *ref)
{
  g_autoptr(GRegex) masked = flatpak_dir_get_mask_regexp (self);

  return !flatpak_filters_allow_ref (NULL, masked, ref);
}

static GRegex *
flatpak_dir_get_pin_regexp (FlatpakDir *self)
{
  GRegex *res = NULL;

  G_LOCK (config_cache);

  if (self->pinned == NULL)
    {
      g_autofree char *pinned = NULL;

      pinned = flatpak_dir_get_config (self, "pinned", NULL);
      if (pinned)
        {
          g_auto(GStrv) patterns = g_strsplit (pinned, ";", -1);
          g_autoptr(GString) deny_regexp = g_string_new ("^(");
          int i;

          for (i = 0; patterns[i] != NULL; i++)
            {
              const char *pattern = patterns[i];

              if (*pattern != 0)
                {
                  g_autofree char *regexp = NULL;

                  regexp = flatpak_filter_glob_to_regexp (pattern,
                                                          TRUE, /* only match runtimes */
                                                          NULL);
                  if (regexp)
                    {
                      if (i != 0)
                        g_string_append (deny_regexp, "|");
                      g_string_append (deny_regexp, regexp);
                    }
                }
            }

          g_string_append (deny_regexp, ")$");
          self->pinned = g_regex_new (deny_regexp->str, G_REGEX_DOLLAR_ENDONLY|G_REGEX_RAW|G_REGEX_OPTIMIZE, G_REGEX_MATCH_ANCHORED, NULL);
        }
    }

  if (self->pinned)
    res = g_regex_ref (self->pinned);

  G_UNLOCK (config_cache);

  return res;
}

gboolean
flatpak_dir_ref_is_pinned (FlatpakDir *self,
                           const char *ref)
{
  g_autoptr(GRegex) pinned = flatpak_dir_get_pin_regexp (self);

  return !flatpak_filters_allow_ref (NULL, pinned, ref);
}

GPtrArray *
flatpak_dir_find_remote_related_for_metadata (FlatpakDir         *self,
                                              FlatpakRemoteState *state,
                                              FlatpakDecomposed  *ref,
                                              GKeyFile           *metakey,
                                              GCancellable       *cancellable,
                                              GError            **error)
{
  int i;
  g_autoptr(GPtrArray) related = g_ptr_array_new_with_free_func ((GDestroyNotify) flatpak_related_free);
  g_autofree char *url = NULL;
  g_auto(GStrv) groups = NULL;
  g_autoptr(GRegex) masked = NULL;
  g_autofree char *ref_arch = flatpak_decomposed_dup_arch (ref);
  g_autofree char *ref_branch = flatpak_decomposed_dup_branch (ref);

  if (!ostree_repo_remote_get_url (self->repo,
                                   state->remote_name,
                                   &url,
                                   error))
    return NULL;

  if (*url == 0)
    return g_steal_pointer (&related);  /* Empty url, silently disables updates */

  masked = flatpak_dir_get_mask_regexp (self);

  groups = g_key_file_get_groups (metakey, NULL);
  for (i = 0; groups[i] != NULL; i++)
    {
      char *tagged_extension;

      if (g_str_has_prefix (groups[i], FLATPAK_METADATA_GROUP_PREFIX_EXTENSION) &&
          *(tagged_extension = (groups[i] + strlen (FLATPAK_METADATA_GROUP_PREFIX_EXTENSION))) != 0)
        {
          g_autofree char *extension = NULL;
          g_autofree char *version = g_key_file_get_string (metakey, groups[i],
                                                            FLATPAK_METADATA_KEY_VERSION, NULL);
          g_auto(GStrv) versions = g_key_file_get_string_list (metakey, groups[i],
                                                               FLATPAK_METADATA_KEY_VERSIONS,
                                                               NULL, NULL);
          gboolean subdirectories = g_key_file_get_boolean (metakey, groups[i],
                                                            FLATPAK_METADATA_KEY_SUBDIRECTORIES, NULL);
          gboolean no_autodownload = g_key_file_get_boolean (metakey, groups[i],
                                                             FLATPAK_METADATA_KEY_NO_AUTODOWNLOAD, NULL);
          g_autofree char *download_if = g_key_file_get_string (metakey, groups[i],
                                                                FLATPAK_METADATA_KEY_DOWNLOAD_IF, NULL);
          g_autofree char *autoprune_unless = g_key_file_get_string (metakey, groups[i],
                                                                     FLATPAK_METADATA_KEY_AUTOPRUNE_UNLESS, NULL);
          gboolean autodelete = g_key_file_get_boolean (metakey, groups[i],
                                                        FLATPAK_METADATA_KEY_AUTODELETE, NULL);
          gboolean locale_subset = g_key_file_get_boolean (metakey, groups[i],
                                                           FLATPAK_METADATA_KEY_LOCALE_SUBSET, NULL);
          const char *default_branches[] = { NULL, NULL};
          const char **branches;
          int branch_i;

          /* Parse actual extension name */
          flatpak_parse_extension_with_tag (tagged_extension, &extension, NULL);

          if (versions)
            branches = (const char **) versions;
          else
            {
              if (version)
                default_branches[0] = version;
              else
                default_branches[0] = ref_branch;
              branches = default_branches;
            }

          for (branch_i = 0; branches[branch_i] != NULL; branch_i++)
            {
              g_autoptr(FlatpakDecomposed) extension_ref = NULL;
              g_autofree char *checksum = NULL;
              const char *branch = branches[branch_i];

              extension_ref = flatpak_decomposed_new_from_parts (FLATPAK_KINDS_RUNTIME,
                                                                 extension, ref_arch, branch, NULL);
              if (extension_ref == NULL)
                continue;

              if (flatpak_remote_state_lookup_ref (state, flatpak_decomposed_get_ref (extension_ref), &checksum, NULL, NULL, NULL, NULL, NULL))
                {
                  if (flatpak_filters_allow_ref (NULL, masked, flatpak_decomposed_get_ref (extension_ref)))
                    add_related (self, related, state->remote_name, extension, extension_ref, checksum,
                                 no_autodownload, download_if, autoprune_unless, autodelete, locale_subset);
                }
              else if (subdirectories)
                {
                  g_autoptr(GPtrArray) subref_refs = flatpak_remote_state_match_subrefs (state, extension_ref);
                  for (int j = 0; j < subref_refs->len; j++)
                    {
                      FlatpakDecomposed *subref_ref = g_ptr_array_index (subref_refs, j);
                      g_autofree char *subref_checksum = NULL;

                      if (flatpak_remote_state_lookup_ref (state, flatpak_decomposed_get_ref (subref_ref),
                                                           &subref_checksum, NULL, NULL, NULL, NULL, NULL) &&
                          flatpak_filters_allow_ref (NULL, masked,  flatpak_decomposed_get_ref (subref_ref)))
                        add_related (self, related, state->remote_name, extension, subref_ref, subref_checksum,
                                     no_autodownload, download_if, autoprune_unless, autodelete, locale_subset);
                    }
                }
            }
        }
    }

  return g_steal_pointer (&related);
}

GPtrArray *
flatpak_dir_find_remote_related (FlatpakDir         *self,
                                 FlatpakRemoteState *state,
                                 FlatpakDecomposed  *ref,
                                 gboolean            use_installed_metadata,
                                 GCancellable       *cancellable,
                                 GError            **error)
{
  g_autofree char *metadata = NULL;
  g_autoptr(GKeyFile) metakey = g_key_file_new ();
  g_autoptr(GPtrArray) related = g_ptr_array_new_with_free_func ((GDestroyNotify) flatpak_related_free);
  g_autofree char *url = NULL;

  if (!flatpak_dir_ensure_repo (self, cancellable, error))
    return NULL;

  if (!ostree_repo_remote_get_url (self->repo,
                                   state->remote_name,
                                   &url,
                                   error))
    return NULL;

  if (*url == 0)
    return g_steal_pointer (&related);  /* Empty url, silently disables updates */

  if (use_installed_metadata)
    {
      g_autoptr(GFile) deploy_dir = NULL;
      g_autoptr(GBytes) deploy_data = NULL;
      g_autoptr(GFile) metadata_file = NULL;

      deploy_dir = flatpak_dir_get_if_deployed (self, ref, NULL, cancellable);
      if (deploy_dir == NULL)
        {
          g_set_error (error, FLATPAK_ERROR, FLATPAK_ERROR_NOT_INSTALLED,
                       _("%s not installed"), flatpak_decomposed_get_ref (ref));
          return NULL;
        }

      deploy_data = flatpak_load_deploy_data (deploy_dir, ref, self->repo, FLATPAK_DEPLOY_VERSION_ANY, cancellable, error);
      if (deploy_data == NULL)
        return NULL;

      metadata_file = g_file_get_child (deploy_dir, "metadata");
      if (!g_file_load_contents (metadata_file, cancellable, &metadata, NULL, NULL, NULL))
        {
          g_info ("No metadata in local deploy");
          /* No metadata => no related, but no error */
        }
    }
  else
    flatpak_remote_state_load_data (state, flatpak_decomposed_get_ref (ref),
                                    NULL, NULL, &metadata,
                                    NULL);

  if (metadata != NULL &&
      g_key_file_load_from_data (metakey, metadata, -1, 0, NULL))
    {
      g_ptr_array_unref (related);
      related = flatpak_dir_find_remote_related_for_metadata (self, state, ref, metakey, cancellable, error);
    }

  return g_steal_pointer (&related);
}

static GHashTable *
local_match_prefix (FlatpakDir        *self,
                    FlatpakDecomposed *extension_ref,
                    const char        *remote,
                    GHashTable        *decomposed_to_search)
{
  GHashTable *matches = g_hash_table_new_full ((GHashFunc)flatpak_decomposed_hash,
                                               (GEqualFunc)flatpak_decomposed_equal,
                                               (GDestroyNotify)flatpak_decomposed_unref,
                                               NULL);
  g_autofree char *id = NULL;
  g_autofree char *arch = NULL;
  g_autofree char *branch = NULL;
  g_autofree char *id_prefix = NULL;

  id = flatpak_decomposed_dup_id (extension_ref);
  arch = flatpak_decomposed_dup_arch (extension_ref);
  branch = flatpak_decomposed_dup_branch (extension_ref);

  id_prefix = g_strconcat (id, ".", NULL);

  if (decomposed_to_search)
    {
      GHashTableIter hash_iter;
      gpointer key;

      g_hash_table_iter_init (&hash_iter, decomposed_to_search);
      while (g_hash_table_iter_next (&hash_iter, &key, NULL))
        {
          FlatpakDecomposed *to_test = key;

          if (flatpak_decomposed_get_kind (extension_ref) != flatpak_decomposed_get_kind (to_test))
            continue;

          /* Must match type, arch, branch */
          if (!flatpak_decomposed_is_arch (to_test, arch) ||
              !flatpak_decomposed_is_branch (to_test, branch))
            continue;

          /* But only prefix of id */
          if (!flatpak_decomposed_id_has_prefix (to_test, id_prefix))
            continue;

          g_hash_table_add (matches, flatpak_decomposed_ref (to_test));
        }
    }

  /* Also check deploys. In case remote-delete --force is run, we can end up
   * with a deploy without a corresponding ref in the repo. */
  flatpak_dir_collect_deployed_refs (self, flatpak_decomposed_get_kind_str (extension_ref),
                                     id_prefix, arch, branch, matches, NULL, NULL);

  return matches;
}

/* Finds all the locally installed ref related to ref, if remote_name is set it is limited to refs from that remote */
GPtrArray *
flatpak_dir_find_local_related_for_metadata (FlatpakDir        *self,
                                             FlatpakDecomposed *ref,
                                             const char        *remote_name, /* nullable */
                                             GKeyFile          *metakey,
                                             GCancellable      *cancellable,
                                             GError           **error)
{
  int i;
  g_autoptr(GPtrArray) related = g_ptr_array_new_with_free_func ((GDestroyNotify) flatpak_related_free);
  g_autoptr(GHashTable) all_decomposed_for_remote = NULL;
  g_auto(GStrv) groups = NULL;
  g_autofree char *ref_arch = flatpak_decomposed_dup_arch (ref);
  g_autofree char *ref_branch = flatpak_decomposed_dup_branch (ref);

  if (!flatpak_dir_ensure_repo (self, cancellable, error))
    return NULL;

  groups = g_key_file_get_groups (metakey, NULL);
  for (i = 0; groups[i] != NULL; i++)
    {
      char *tagged_extension;

      if (g_str_has_prefix (groups[i], FLATPAK_METADATA_GROUP_PREFIX_EXTENSION) &&
          *(tagged_extension = (groups[i] + strlen (FLATPAK_METADATA_GROUP_PREFIX_EXTENSION))) != 0)
        {
          g_autofree char *extension = NULL;
          g_autofree char *version = g_key_file_get_string (metakey, groups[i],
                                                            FLATPAK_METADATA_KEY_VERSION, NULL);
          g_auto(GStrv) versions = g_key_file_get_string_list (metakey, groups[i],
                                                               FLATPAK_METADATA_KEY_VERSIONS,
                                                               NULL, NULL);
          gboolean subdirectories = g_key_file_get_boolean (metakey, groups[i],
                                                            FLATPAK_METADATA_KEY_SUBDIRECTORIES, NULL);
          gboolean no_autodownload = g_key_file_get_boolean (metakey, groups[i],
                                                             FLATPAK_METADATA_KEY_NO_AUTODOWNLOAD, NULL);
          g_autofree char *download_if = g_key_file_get_string (metakey, groups[i],
                                                                FLATPAK_METADATA_KEY_DOWNLOAD_IF, NULL);
          g_autofree char *autoprune_unless = g_key_file_get_string (metakey, groups[i],
                                                                     FLATPAK_METADATA_KEY_AUTOPRUNE_UNLESS, NULL);
          gboolean autodelete = g_key_file_get_boolean (metakey, groups[i],
                                                        FLATPAK_METADATA_KEY_AUTODELETE, NULL);
          gboolean locale_subset = g_key_file_get_boolean (metakey, groups[i],
                                                           FLATPAK_METADATA_KEY_LOCALE_SUBSET, NULL);
          const char *default_branches[] = { NULL, NULL};
          const char **branches;
          int branch_i;

          /* Parse actual extension name */
          flatpak_parse_extension_with_tag (tagged_extension, &extension, NULL);

          if (versions)
            branches = (const char **) versions;
          else
            {
              if (version)
                default_branches[0] = version;
              else
                default_branches[0] = ref_branch;
              branches = default_branches;
            }

          for (branch_i = 0; branches[branch_i] != NULL; branch_i++)
            {
              g_autoptr(FlatpakDecomposed) extension_ref = NULL;
              g_autofree char *checksum = NULL;
              g_autoptr(GBytes) deploy_data = NULL;
              const char *branch = branches[branch_i];

              extension_ref = flatpak_decomposed_new_from_parts (FLATPAK_KINDS_RUNTIME,
                                                                 extension, ref_arch, branch, NULL);
              if (extension_ref == NULL)
                continue;

              if (remote_name != NULL &&
                  flatpak_repo_resolve_rev (self->repo,
                                            NULL,
                                            remote_name,
                                            flatpak_decomposed_get_ref (extension_ref),
                                            FALSE,
                                            &checksum,
                                            NULL,
                                            NULL))
                {
                  add_related (self, related, remote_name, extension, extension_ref,
                               checksum, no_autodownload, download_if, autoprune_unless, autodelete, locale_subset);
                }
              else if ((deploy_data = flatpak_dir_get_deploy_data (self, extension_ref,
                                                                   FLATPAK_DEPLOY_VERSION_ANY,
                                                                   NULL, NULL)) != NULL &&
                       (remote_name == NULL || g_strcmp0 (flatpak_deploy_data_get_origin (deploy_data), remote_name) == 0))
                {
                  /* Here we're including extensions that are deployed but might
                   * not have a ref in the repo, as happens with remote-delete
                   * --force
                   */
                  checksum = g_strdup (flatpak_deploy_data_get_commit (deploy_data));
                  add_related (self, related,
                               flatpak_deploy_data_get_origin (deploy_data),
                               extension, extension_ref, checksum,
                               no_autodownload, download_if, autoprune_unless, autodelete, locale_subset);
                }
              else if (subdirectories)
                {
                  g_autoptr(GHashTable) matches = NULL;

                  if (!all_decomposed_for_remote)
                    {
                      g_autoptr(GHashTable) refs = NULL;
                      g_autofree char *list_prefix = NULL;
                      if (remote_name != NULL)
                        list_prefix = g_strdup_printf ("%s:", remote_name);

                      if (ostree_repo_list_refs (self->repo, list_prefix, &refs, NULL, NULL))
                        {
                          GHashTableIter iter;
                          gpointer key;

                          all_decomposed_for_remote = g_hash_table_new_full (
                            (GHashFunc)flatpak_decomposed_hash,
                            (GEqualFunc)flatpak_decomposed_equal,
                            (GDestroyNotify)flatpak_decomposed_unref,
                            NULL);

                          g_hash_table_iter_init (&iter, refs);
                          while (g_hash_table_iter_next (&iter, &key, NULL))
                            {
                              const char *refspec = key;
                              g_autoptr(FlatpakDecomposed) decomposed = NULL;

                              decomposed = flatpak_decomposed_new_from_refspec (refspec, NULL);
                              if (decomposed != NULL)
                                g_hash_table_add (all_decomposed_for_remote, g_steal_pointer (&decomposed));
                            }
                        }
                    }

                  matches = local_match_prefix (self, extension_ref, remote_name, all_decomposed_for_remote);
                  GLNX_HASH_TABLE_FOREACH (matches, FlatpakDecomposed *, match)
                    {
                      g_autofree char *match_checksum = NULL;
                      g_autoptr(GBytes) match_deploy_data = NULL;

                      if (remote_name != NULL &&
                          flatpak_repo_resolve_rev (self->repo,
                                                    NULL,
                                                    remote_name,
                                                    flatpak_decomposed_get_ref (match),
                                                    FALSE,
                                                    &match_checksum,
                                                    NULL,
                                                    NULL))
                        {
                          add_related (self, related, remote_name, extension, match, match_checksum,
                                       no_autodownload, download_if, autoprune_unless, autodelete, locale_subset);
                        }
                      else if ((match_deploy_data = flatpak_dir_get_deploy_data (self, match,
                                                                                 FLATPAK_DEPLOY_VERSION_ANY,
                                                                                 NULL, NULL)) != NULL &&
                               (remote_name == NULL || g_strcmp0 (flatpak_deploy_data_get_origin (match_deploy_data), remote_name) == 0))
                        {
                          /* Here again we're including extensions that are deployed but might
                           * not have a ref in the repo
                           */
                          match_checksum = g_strdup (flatpak_deploy_data_get_commit (match_deploy_data));
                          add_related (self, related,
                                       flatpak_deploy_data_get_origin (match_deploy_data),
                                       extension, match, match_checksum,
                                       no_autodownload, download_if, autoprune_unless, autodelete, locale_subset);
                        }
                    }
                }
            }
        }
    }

  return g_steal_pointer (&related);
}


GPtrArray *
flatpak_dir_find_local_related (FlatpakDir        *self,
                                FlatpakDecomposed *ref,
                                const char        *remote_name,
                                gboolean           deployed,
                                GCancellable      *cancellable,
                                GError           **error)
{
  g_autoptr(GFile) deploy_dir = NULL;
  g_autoptr(GBytes) deploy_data = NULL;
  g_autoptr(GFile) metadata = NULL;
  g_autofree char *metadata_contents = NULL;
  g_autoptr(GKeyFile) metakey = g_key_file_new ();
  g_autoptr(GPtrArray) related = NULL;

  if (!flatpak_dir_ensure_repo (self, cancellable, error))
    return NULL;

  if (deployed)
    {
      deploy_dir = flatpak_dir_get_if_deployed (self, ref, NULL, cancellable);
      if (deploy_dir == NULL)
        {
          g_set_error (error, FLATPAK_ERROR, FLATPAK_ERROR_NOT_INSTALLED,
                       _("%s not installed"), flatpak_decomposed_get_ref (ref));
          return NULL;
        }

      deploy_data = flatpak_load_deploy_data (deploy_dir, ref, self->repo, FLATPAK_DEPLOY_VERSION_ANY, cancellable, error);
      if (deploy_data == NULL)
        return NULL;

      if (flatpak_deploy_data_get_extension_of (deploy_data) == NULL)
        {
          metadata = g_file_get_child (deploy_dir, "metadata");
          if (!g_file_load_contents (metadata, cancellable, &metadata_contents, NULL, NULL, NULL))
            {
              g_info ("No metadata in local deploy");
              /* No metadata => no related, but no error */
            }
        }
    }
  else
    {
      g_autofree char *checksum = NULL;
      g_autoptr(GVariant) commit_data = flatpak_dir_read_latest_commit (self, remote_name, ref, &checksum, NULL, NULL);
      if (commit_data)
        {
          g_autoptr(GVariant) commit_metadata = g_variant_get_child_value (commit_data, 0);
          g_variant_lookup (commit_metadata, "xa.metadata", "s", &metadata_contents);
          if (metadata_contents == NULL)
            g_info ("No xa.metadata in local commit %s ref %s", checksum, flatpak_decomposed_get_ref (ref));
        }
    }

  if (metadata_contents &&
      g_key_file_load_from_data (metakey, metadata_contents, -1, 0, NULL))
    related = flatpak_dir_find_local_related_for_metadata (self, ref, remote_name, metakey, cancellable, error);
  else
    related = g_ptr_array_new_with_free_func ((GDestroyNotify) flatpak_related_free);

  return g_steal_pointer (&related);
}

FlatpakDecomposed *
flatpak_dir_get_remote_auto_install_authenticator_ref (FlatpakDir         *self,
                                                        const char         *remote_name)
{
  g_autofree char *authenticator_name = NULL;
  g_autoptr(FlatpakDecomposed) ref = NULL;

  authenticator_name = flatpak_dir_get_remote_install_authenticator_name (self, remote_name);
  if (authenticator_name != NULL)
    {
      g_autoptr(GError) local_error = NULL;
      ref = flatpak_decomposed_new_from_parts (FLATPAK_KINDS_APP, authenticator_name, flatpak_get_arch (), "autoinstall", &local_error);
      if (ref == NULL)
        g_info ("Invalid authenticator ref: %s\n", local_error->message);
    }

  return g_steal_pointer (&ref);
}

static int
cmpstringp (const void *p1, const void *p2)
{
  return strcmp (*(char * const *) p1, *(char * const *) p2);
}

static char **
sort_strv (char **strv)
{
  qsort (strv, g_strv_length (strv), sizeof (const char *), cmpstringp);
  return strv;
}

static char **
flatpak_dir_get_config_strv (FlatpakDir *self, char *key)
{
  GKeyFile *config = flatpak_dir_get_repo_config (self);
  g_auto(GStrv) lang = NULL;

  if (config)
    {
      if (g_key_file_has_key (config, "core", key, NULL))
        {
          lang = g_key_file_get_string_list (config, "core", key, NULL, NULL);
          return g_steal_pointer (&lang);
        }
    }
  return NULL;
}

char **
flatpak_dir_get_default_locales (FlatpakDir *self)
{
  g_auto(GStrv) extra_languages = NULL;
  const GPtrArray *langs;

  extra_languages = flatpak_dir_get_config_strv (self, "xa.extra-languages");

  if (flatpak_dir_is_user (self))
    {
      g_auto(GStrv) locale_langs = flatpak_get_current_locale_langs ();
      g_auto(GStrv) merged = NULL;

      langs = flatpak_get_user_locales ();
      merged = flatpak_strv_merge (extra_languages, (char **) langs->pdata);

      return sort_strv (flatpak_strv_merge (merged, locale_langs));
    }

  /* Then get the system default locales */
  langs = flatpak_get_system_locales ();

  return sort_strv (flatpak_strv_merge (extra_languages, (char **) langs->pdata));
}

char **
flatpak_dir_get_default_locale_languages (FlatpakDir *self)
{
  g_auto(GStrv) extra_languages = NULL;
  const GPtrArray *langs;
  int i;

  extra_languages = flatpak_dir_get_config_strv (self, "xa.extra-languages");
  for (i = 0; extra_languages != NULL && extra_languages[i] != NULL; i++)
    {
      /* Strip the locale, modifier or codeset, if present. */
      gchar *match = strpbrk (extra_languages[i], "._@");
      if (match != NULL)
        *match = '\0';
    }

  if (flatpak_dir_is_user (self))
    {
      g_auto(GStrv) locale_langs = flatpak_get_current_locale_langs ();
      g_auto(GStrv) merged = NULL;

      langs = flatpak_get_user_locales ();
      merged = flatpak_strv_merge (extra_languages, (char **) langs->pdata);

      return sort_strv (flatpak_strv_merge (merged, locale_langs));
    }

  /* Then get the system default locales */
  langs = flatpak_get_system_locales ();

  return sort_strv (flatpak_strv_merge (extra_languages, (char **) langs->pdata));
}

char **
flatpak_dir_get_locales (FlatpakDir *self)
{
  char **langs = NULL;

  /* Fetch the list of languages specified by xa.languages - if this key is empty,
   * this would mean that all languages are accepted. You can read the man for the
   * flatpak-config section for more info.
   */
  langs = flatpak_dir_get_config_strv (self, "xa.languages");
  if (langs)
    return sort_strv (langs);

  return flatpak_dir_get_default_locales (self);
}


char **
flatpak_dir_get_locale_languages (FlatpakDir *self)
{
  char **langs = NULL;

  /* Fetch the list of languages specified by xa.languages - if this key is empty,
   * this would mean that all languages are accepted. You can read the man for the
   * flatpak-config section for more info.
   */
  langs = flatpak_dir_get_config_strv (self, "xa.languages");
  if (langs)
    return sort_strv (langs);

  return flatpak_dir_get_default_locale_languages (self);
}

char **
flatpak_dir_get_locale_subpaths (FlatpakDir *self)
{
  char **subpaths = flatpak_dir_get_locale_languages (self);
  int i;

  /* Convert languages to paths */
  for (i = 0; subpaths[i] != NULL; i++)
    {
      char *lang = subpaths[i];
      /* For backwards compat with old xa.languages we support the configuration having slashes already */
      if (*lang != '/')
        {
          subpaths[i] = g_strconcat ("/", lang, NULL);
          g_free (lang);
        }
    }
  return subpaths;
}

void
flatpak_dir_set_subject (FlatpakDir    *self,
                         PolkitSubject *subject)
{
  g_set_object (&self->subject, subject);
}

static void
  (flatpak_dir_log) (FlatpakDir * self,
                     const char *file,
                     int line,
                     const char *func,
                     const char *source, /* overrides self->name */
                     const char *change,
                     const char *remote,
                     const char *ref,
                     const char *commit,
                     const char *old_commit,
                     const char *url,
                     const char *format,
                     ...)
{
#ifdef HAVE_LIBSYSTEMD
  const char *installation;
  g_autofree char *subject = NULL;
  char message[1024];
  int len;
  va_list args;

  installation = source ? source : flatpak_dir_get_name_cached (self);
#ifdef USE_SYSTEM_HELPER
  subject = self->subject ? polkit_subject_to_string (self->subject) : g_strdup ("(none)");
#else
  subject = g_strdup ("(none)");
#endif

  len = g_snprintf (message, sizeof (message), "%s: ", installation);

  va_start (args, format);
  g_vsnprintf (message + len, sizeof (message) - len, format, args);
  va_end (args);

  /* See systemd.journal-fields(7) for the meaning of the
   * standard fields we use, in particular OBJECT_PID
   */
  sd_journal_send ("MESSAGE_ID=" FLATPAK_MESSAGE_ID,
                   "PRIORITY=5",
                   "SUBJECT=%s", subject,
                   "CODE_FILE=%s", file,
                   "CODE_LINE=%d", line,
                   "CODE_FUNC=%s", func,
                   "MESSAGE=%s", message,
                   /* custom fields below */
                   "FLATPAK_VERSION=" PACKAGE_VERSION,
                   "INSTALLATION=%s", installation,
                   "OPERATION=%s", change,
                   "REMOTE=%s", remote ? remote : "",
                   "REF=%s", ref ? ref : "",
                   "COMMIT=%s", commit ? commit : "",
                   "OLD_COMMIT=%s", old_commit ? old_commit : "",
                   "URL=%s", url ? url : "",
                   NULL);
#endif
}

/* Delete refs that are in refs/mirrors/ rather than refs/remotes/ to prevent
 * disk space from leaking. See https://github.com/flatpak/flatpak/issues/3222
 * The caller is responsible for ensuring that @dir has a repo, and for pruning
 * the repo after calling this function to actually free the disk space.
 */
gboolean
flatpak_dir_delete_mirror_refs (FlatpakDir    *self,
                                gboolean       dry_run,
                                GCancellable  *cancellable,
                                GError       **error)
{
  g_autoptr(GHashTable) collection_refs = NULL;  /* (element-type OstreeCollectionRef utf8) */
  g_autoptr(GPtrArray) ignore_collections = g_ptr_array_new_with_free_func (g_free); /* (element-type utf8) */
  g_auto(GStrv) remotes = NULL;
  const char *repo_collection_id;
  OstreeRepo *repo;
  int i;

  /* Generally a flatpak repo should not have its own collection ID set, but
   * check just in case flatpak is being run on a server for some reason. When
   * a repo has a collection ID set, its own refs from refs/heads/ will be
   * listed by the ostree_repo_list_collection_refs() call below, and we need
   * to be sure not to delete them. There would be no reason to install from a
   * server to itself, so we don't expect refs matching repo_collection_id to
   * be in refs/mirrors/.
   */
  repo = flatpak_dir_get_repo (self);
  repo_collection_id = ostree_repo_get_collection_id (repo);
  if (repo_collection_id != NULL)
    g_ptr_array_add (ignore_collections, g_strdup (repo_collection_id));

  /* Check also for any disabled remotes and ignore any associated
   * collection-refs; in the case of Endless this would be the remote used for
   * OS updates which Flatpak shouldn't touch.
   */
  remotes = ostree_repo_remote_list (repo, NULL);
  for (i = 0; remotes != NULL && remotes[i] != NULL; i++)
    {
      g_autofree char *remote_collection_id = NULL;

      if (!flatpak_dir_get_remote_disabled (self, remotes[i]))
        continue;
      remote_collection_id = flatpak_dir_get_remote_collection_id (self, remotes[i]);
      if (remote_collection_id != NULL)
        g_ptr_array_add (ignore_collections, g_steal_pointer (&remote_collection_id));
    }
  g_ptr_array_add (ignore_collections, NULL);

  if (!ostree_repo_list_collection_refs (repo, NULL, &collection_refs,
                                         OSTREE_REPO_LIST_REFS_EXT_EXCLUDE_REMOTES,
                                         cancellable, error))
    return FALSE;

  /* Now delete any collection-refs which are in refs/mirrors/, were created by
   * Flatpak, and don't belong to a disabled remote.
   */
  GLNX_HASH_TABLE_FOREACH (collection_refs, const OstreeCollectionRef *, c_r)
    {
      if (g_strv_contains ((const char * const *)ignore_collections->pdata, c_r->collection_id))
        {
          g_info ("Ignoring collection-ref (%s, %s) since its remote is disabled or it matches the repo collection ID",
                  c_r->collection_id, c_r->ref_name);
          continue;
        }

      /* Only delete refs which Flatpak created; the repo may have other
       * users. We could check only for refs that come from configured
       * remotes, but that would not cover the case of if a remote was
       * deleted.
       */
      if (flatpak_is_app_runtime_or_appstream_ref (c_r->ref_name) ||
          g_strcmp0 (c_r->ref_name, OSTREE_REPO_METADATA_REF) == 0)
        {
          if (dry_run)
            g_print (_("Skipping deletion of mirror ref (%s, %s)…\n"), c_r->collection_id, c_r->ref_name);
          else
            {
              if (!ostree_repo_set_collection_ref_immediate (repo, c_r, NULL, cancellable, error))
                return FALSE;
            }
        }
    }

  return TRUE;
}


static gboolean
dir_get_metadata (FlatpakDir        *dir,
                  FlatpakDecomposed *ref,
                  GKeyFile         **out_metakey)
{
  g_autoptr(GFile) deploy_dir = NULL;
  g_autoptr(GKeyFile) metakey = NULL;
  g_autoptr(GFile) metadata = NULL;
  g_autofree char *metadata_contents = NULL;
  gsize metadata_size;

  deploy_dir = flatpak_dir_get_if_deployed (dir, ref, NULL, NULL);
  if (deploy_dir == NULL)
    return FALSE;

  metadata = g_file_get_child (deploy_dir, "metadata");
  if (!g_file_load_contents (metadata, NULL, &metadata_contents, &metadata_size, NULL, NULL))
    return FALSE;

  metakey = g_key_file_new ();
  if (!g_key_file_load_from_data (metakey, metadata_contents, metadata_size, 0, NULL))
    return FALSE;

  *out_metakey = g_steal_pointer (&metakey);

  return TRUE;
}

static gboolean
maybe_get_metakey (FlatpakDir        *dir,
                   FlatpakDir        *shadowing_dir,
                   FlatpakDecomposed *ref,
                   GHashTable        *metadata_injection,
                   GKeyFile         **out_metakey,
                   gboolean          *out_ref_is_shadowed,
                   char             **out_dir_name)
{
  if (shadowing_dir &&
      dir_get_metadata (shadowing_dir, ref, out_metakey))
    {
      *out_ref_is_shadowed = TRUE;
      *out_dir_name = g_strdup_printf (" (%s)", flatpak_dir_get_name_cached (shadowing_dir));
      return TRUE;
    }

  if (metadata_injection != NULL)
    {
      GKeyFile *injected_metakey = g_hash_table_lookup (metadata_injection, flatpak_decomposed_get_ref (ref));
      if (injected_metakey != NULL)
        {
          *out_ref_is_shadowed = FALSE;
          *out_metakey = g_key_file_ref (injected_metakey);
          *out_dir_name = g_strdup ("");
          return TRUE;
        }
    }

  if (dir_get_metadata (dir, ref, out_metakey))
    {
      *out_ref_is_shadowed = FALSE;
      *out_dir_name = g_strdup_printf (" (%s)", flatpak_dir_get_name_cached (dir));
      return TRUE;
    }

  return FALSE;
}

static void
queue_ref_for_analysis (FlatpakDecomposed *ref,
                        const char *arch,
                        GHashTable *analyzed_refs,
                        GQueue     *refs_to_analyze)
{
  if (arch != NULL && !flatpak_decomposed_is_arch (ref, arch))
    return;

  if (g_hash_table_lookup (analyzed_refs, ref) != NULL)
    return;

  g_hash_table_add (analyzed_refs, flatpak_decomposed_ref (ref));
  g_queue_push_tail (refs_to_analyze, ref); /* owned by analyzed_refs */
}

/* This traverses from all the "root" refs and into for any recursive dependencies in @self
 * that they use. In the regular case we just consider the @self installation,
 * but we can also handle the case where another directory "shadows" self. For example
 * we might be looking for used refs in the "system" dir, and the "user" dir is
 * shadowing it, meaning that if a ref is installed in the user dir it is considered used
 * from there instead of @self. So, analyzed refs from @shadowing_dir are *not* put
 * in @used_ref (although their dependencies may).
 *
 * Notes:
 *  The "root" refs come from @shadowing_dir if not %NULL and @self otherwise.
 *  refs_to_exclude, and metadata_injection both only affect @self, not @shadowing_dir
 */
static GHashTable *
find_used_refs (FlatpakDir         *self,
                FlatpakDir         *shadowing_dir, /* nullable */
                const char         *arch,
                GHashTable         *metadata_injection,
                GHashTable         *refs_to_exclude,
                GHashTable         *used_refs, /* This is filled in */
                GHashTable         *autopruned_refs, /* This is filled in */
                GCancellable       *cancellable,
                GError            **error)
{
  g_autoptr(GPtrArray) root_app_refs = NULL;
  g_autoptr(GPtrArray) root_runtime_refs = NULL;
  g_autoptr(GHashTable) analyzed_refs = NULL;
  g_autoptr(GQueue) refs_to_analyze = NULL;
  FlatpakDir *root_ref_dir;
  FlatpakDecomposed *ref_to_analyze;

  refs_to_analyze = g_queue_new ();
  analyzed_refs = g_hash_table_new_full ((GHashFunc)flatpak_decomposed_hash, (GEqualFunc)flatpak_decomposed_equal, (GDestroyNotify)flatpak_decomposed_unref, NULL);

  if (shadowing_dir)
    root_ref_dir = shadowing_dir;
  else
    root_ref_dir = self;

  root_app_refs = flatpak_dir_list_refs (root_ref_dir, FLATPAK_KINDS_APP, cancellable, error);
  if (root_app_refs == NULL)
    return NULL;

  for (int i = 0; i < root_app_refs->len; i++)
    {
      FlatpakDecomposed *root_app_ref = g_ptr_array_index (root_app_refs, i);
      queue_ref_for_analysis (root_app_ref, arch, analyzed_refs, refs_to_analyze);
    }

  root_runtime_refs = flatpak_dir_list_refs (root_ref_dir, FLATPAK_KINDS_RUNTIME, cancellable, error);
  if (root_runtime_refs == NULL)
    return NULL;

  for (int i = 0; i < root_runtime_refs->len; i++)
    {
      FlatpakDecomposed *root_runtime_ref = g_ptr_array_index (root_runtime_refs, i);
      /* Consider all shadow dir runtimes as roots because we don't really do full analysis for shadowing_dir.
       * For example a system installed app could end up using the user version of a runtime, which in turn
       * uses a system gl extension.
       *
       * However, for non-shadowed runtime refs, only pinned ones are roots */
      if (root_ref_dir == shadowing_dir)
        {
          queue_ref_for_analysis (root_runtime_ref, arch, analyzed_refs, refs_to_analyze);
        }
      else if (flatpak_dir_ref_is_pinned (root_ref_dir, flatpak_decomposed_get_ref (root_runtime_ref)))
        {
          g_debug ("%s: Treating %s as used since it's pinned",
                   G_STRFUNC, flatpak_decomposed_get_ref (root_runtime_ref));
          queue_ref_for_analysis (root_runtime_ref, arch, analyzed_refs, refs_to_analyze);
        }
    }

  /* Any injected refs are considered used, because this is used by transaction
   * to emulate installing a new ref, and we never want the new ref:s dependencies
   * seem unused. */
  if (metadata_injection)
    {
      GLNX_HASH_TABLE_FOREACH (metadata_injection, const char *, injected_ref)
        {
          g_autoptr(FlatpakDecomposed) injected = flatpak_decomposed_new_from_ref (injected_ref, NULL);
          if (injected)
            {
              g_debug ("%s: Treating %s as used during unused refs analysis",
                       G_STRFUNC, flatpak_decomposed_get_ref (injected));
              queue_ref_for_analysis (injected, arch, analyzed_refs, refs_to_analyze);
            }
        }
    }

  while ((ref_to_analyze = g_queue_pop_head (refs_to_analyze)) != NULL)
    {
      g_autoptr(GKeyFile) metakey = NULL;
      gboolean ref_is_shadowed;
      gboolean is_app;
      g_autoptr(GPtrArray) related = NULL;
      g_autofree char *sdk = NULL;
      g_autofree char *dir_name = NULL;

      if (!maybe_get_metakey (self, shadowing_dir, ref_to_analyze, metadata_injection,
                              &metakey, &ref_is_shadowed, &dir_name))
        continue; /* Something used something we could not find, that is fine and happens for instance with sdk dependencies */

      if (!ref_is_shadowed)
        {
          /* Mark the analyzed ref used as it wasn't shadowed */
          if (!g_hash_table_contains (used_refs, ref_to_analyze))
            g_hash_table_add (used_refs, flatpak_decomposed_ref (ref_to_analyze));

          /* For excluded refs we mark them as used (above) so that they don't get listed as
           * unused, but we don't analyze them for any dependencies. Note that refs_to_exclude only
           * affects the base dir, so does not affect shadowed refs */
          if (refs_to_exclude != NULL && g_hash_table_contains (refs_to_exclude, ref_to_analyze))
            {
              g_debug ("%s: Treating %s as uninstalled during unused refs analysis",
                       G_STRFUNC, flatpak_decomposed_get_ref (ref_to_analyze));
              continue;
            }
        }

      /************************************************
       * Find all dependencies and queue for analysis *
       ***********************************************/

      is_app = flatpak_decomposed_is_app (ref_to_analyze);

      /* App directly depends on its runtime */
      if (is_app)
        {
          g_autofree char *runtime = g_key_file_get_string (metakey, "Application", "runtime", NULL);
          if (runtime)
            {
              g_autoptr(FlatpakDecomposed) runtime_ref = flatpak_decomposed_new_from_pref (FLATPAK_KINDS_RUNTIME, runtime, NULL);
              if (runtime_ref && !flatpak_decomposed_equal (runtime_ref, ref_to_analyze))
                {
                  g_debug ("%s: Considering runtime %s used by app %s%s",
                           G_STRFUNC, flatpak_decomposed_get_ref (runtime_ref),
                           flatpak_decomposed_get_ref (ref_to_analyze), dir_name);
                  queue_ref_for_analysis (runtime_ref, arch, analyzed_refs, refs_to_analyze);
                }
            }
        }

      /* Both apps and runtimes directly depends on its sdk, to avoid suddenly
       * uninstalling something you use to develop the app */
      sdk = g_key_file_get_string (metakey, is_app ? "Application" : "Runtime", "sdk", NULL);
      if (sdk)
        {
          g_autoptr(FlatpakDecomposed) sdk_ref = flatpak_decomposed_new_from_pref (FLATPAK_KINDS_RUNTIME, sdk, NULL);
          if (sdk_ref && !flatpak_decomposed_equal (sdk_ref, ref_to_analyze))
            {
              g_debug ("%s: Considering sdk %s used by %s%s",
                       G_STRFUNC, flatpak_decomposed_get_ref (sdk_ref),
                       flatpak_decomposed_get_ref (ref_to_analyze), dir_name);
              queue_ref_for_analysis (sdk_ref, arch, analyzed_refs, refs_to_analyze);
            }
        }

      /* Extensions with extra data, that are not specially marked NoRuntime needs the runtime at install.
       * Lets keep it around to not re-download it next update */
      if (!is_app &&
          g_key_file_has_group (metakey, "Extra Data") &&
          !g_key_file_get_boolean (metakey, "Extra Data", "NoRuntime", NULL))
        {
          g_autofree char *extension_runtime_ref = g_key_file_get_string (metakey, "ExtensionOf", "runtime", NULL);
          if (extension_runtime_ref != NULL)
            {
              g_autoptr(FlatpakDecomposed) d = flatpak_decomposed_new_from_ref (extension_runtime_ref, NULL);
              if (d)
                {
                  g_debug ("%s: Considering runtime %s used by extra-data %s%s",
                           G_STRFUNC, flatpak_decomposed_get_ref (d),
                           flatpak_decomposed_get_ref (ref_to_analyze), dir_name);
                  queue_ref_for_analysis (d, arch, analyzed_refs, refs_to_analyze);
                }
            }
        }

      /* We pass NULL for remote-name here, because we want to consider related refs from all remotes */
      related = flatpak_dir_find_local_related_for_metadata (self, ref_to_analyze,
                                                             NULL, metakey, NULL, NULL);
      for (int i = 0; related != NULL && i < related->len; i++)
        {
          FlatpakRelated *rel = g_ptr_array_index (related, i);

          if (!rel->auto_prune)
            {
              g_debug ("%s: Considering related ref %s used by %s%s",
                       G_STRFUNC, flatpak_decomposed_get_ref (rel->ref),
                       flatpak_decomposed_get_ref (ref_to_analyze), dir_name);
              queue_ref_for_analysis (rel->ref, arch, analyzed_refs, refs_to_analyze);
            }
          else
            {
              g_hash_table_add (autopruned_refs, flatpak_decomposed_ref (rel->ref));
            }
        }
    }

  return g_steal_pointer (&used_refs);
}

/* See the documentation for
 * flatpak_installation_list_unused_refs_with_options().
 * The returned pointer array is transfer full. */
char **
flatpak_dir_list_unused_refs (FlatpakDir            *self,
                              const char            *arch,
                              GHashTable            *metadata_injection,
                              GHashTable            *eol_injection,
                              const char * const    *refs_to_exclude,
                              FlatpakDirFilterFlags  filter_flags,
                              GCancellable          *cancellable,
                              GError               **error)
{
  g_autoptr(GHashTable) used_refs = NULL;
  g_autoptr(GHashTable) autoprune_refs = NULL;
  g_autoptr(GHashTable) excluded_refs_ht = NULL;
  g_autoptr(GPtrArray) refs =  NULL;
  g_autoptr(GPtrArray) runtime_refs = NULL;
  gboolean filter_by_eol = (filter_flags & FLATPAK_DIR_FILTER_EOL) != 0;
  gboolean filter_by_autoprune = (filter_flags & FLATPAK_DIR_FILTER_AUTOPRUNE) != 0;

  /* Convert refs_to_exclude to hashtable for fast repeated lookups */
  if (refs_to_exclude)
    {
      excluded_refs_ht = g_hash_table_new_full ((GHashFunc)flatpak_decomposed_hash, (GEqualFunc)flatpak_decomposed_equal, (GDestroyNotify)flatpak_decomposed_unref, NULL);
      for (int i = 0; refs_to_exclude[i] != NULL; i++)
        {
          const char *ref_to_exclude = refs_to_exclude[i];
          g_autoptr(FlatpakDecomposed) d = flatpak_decomposed_new_from_ref (ref_to_exclude, NULL);
          if (d)
            g_hash_table_add (excluded_refs_ht, flatpak_decomposed_ref (d));
        }
    }

  used_refs = g_hash_table_new_full ((GHashFunc)flatpak_decomposed_hash, (GEqualFunc)flatpak_decomposed_equal, (GDestroyNotify)flatpak_decomposed_unref, NULL);
  autoprune_refs = g_hash_table_new_full ((GHashFunc)flatpak_decomposed_hash, (GEqualFunc)flatpak_decomposed_equal, (GDestroyNotify)flatpak_decomposed_unref, NULL);

  g_info ("Checking installation ‘%s’ %s%s",
          flatpak_dir_get_name_cached (self),
          filter_by_eol ? "for EOL unused refs" : "for unused refs",
          filter_by_autoprune ? " and autoprunes" : "");
  if (!find_used_refs (self, NULL, arch, metadata_injection, excluded_refs_ht,
                       used_refs, autoprune_refs, cancellable, error))
    return NULL;

  /* If @self is a system installation, also check the per-user installation
   * for any apps there using runtimes in the system installation or runtimes
   * there with sdks or extensions in the system installation. Only do so if
   * the per-user installation exists; it wouldn't make sense to create it here
   * if not.
   */
  if (!flatpak_dir_is_user (self))
    {
      g_autoptr(FlatpakDir) user_dir = flatpak_dir_get_user ();
      g_autoptr(GError) local_error = NULL;

      g_info ("Checking installation ‘%s’ by checking for dependent refs in ‘%s’",
              flatpak_dir_get_name_cached (self), flatpak_dir_get_name_cached (user_dir));
      if (!find_used_refs (self, user_dir, arch, metadata_injection, excluded_refs_ht,
                           used_refs, autoprune_refs, cancellable, &local_error))
        {
          /* We may get permission denied if the process is sandboxed with
           * systemd's ProtectHome=
           */
          if (!g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND) &&
              !g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_PERMISSION_DENIED))
            {
              g_propagate_error (error, g_steal_pointer (&local_error));
              return NULL;
            }
        }
    }

  runtime_refs = flatpak_dir_list_refs (self, FLATPAK_KINDS_RUNTIME, cancellable, error);
  if (runtime_refs == NULL)
    return NULL;

  refs = g_ptr_array_new_with_free_func (g_free);

  for (int i = 0; i < runtime_refs->len; i++)
    {
      FlatpakDecomposed *ref = g_ptr_array_index (runtime_refs, i);

      if (g_hash_table_contains (used_refs, ref))
        continue;

      if (arch != NULL && !flatpak_decomposed_is_arch (ref, arch))
        continue;

      if (filter_flags)
        {
          gboolean is_eol = FALSE;
          gboolean is_autopruned = g_hash_table_contains (autoprune_refs, ref);

          if (eol_injection && g_hash_table_contains (eol_injection, flatpak_decomposed_get_ref (ref)))
            {
              is_eol = GPOINTER_TO_INT (g_hash_table_lookup (eol_injection, ref));
            }
          else
            {
              g_autoptr(GBytes) deploy_data = NULL;

              /* deploy v4 guarantees eol/eolr info */
              deploy_data = flatpak_dir_get_deploy_data (self, ref, 4,
                                                         cancellable, NULL);
              is_eol = deploy_data != NULL &&
                (flatpak_deploy_data_get_eol (deploy_data) != NULL ||
                 flatpak_deploy_data_get_eol_rebase (deploy_data));
            }

          if (!((is_autopruned && filter_by_autoprune) || (is_eol && filter_by_eol)))
            {
              g_debug ("%s: Ref %s (%s) not %s, so excluding from unused refs",
                       G_STRFUNC, flatpak_decomposed_get_ref (ref),
                       flatpak_dir_get_name_cached (self),
                       (!is_eol && filter_by_eol) ? "end-of-life" : "autopruned");
              continue;
            }
        }

      g_info ("%s: Ref %s (%s) is %s",
              G_STRFUNC, flatpak_decomposed_get_ref (ref),
              flatpak_dir_get_name_cached (self),
              filter_by_eol ? "EOL and unused" : "unused");
      g_ptr_array_add (refs, flatpak_decomposed_dup_ref (ref));
    }

  g_ptr_array_add (refs, NULL);
  return (char **)g_ptr_array_free (g_steal_pointer (&refs), FALSE);
}

===== ./common/flatpak-docker-reference-private.h =====
#ifndef __FLATPAK_DOCKER_REFERENCE_H__
#define __FLATPAK_DOCKER_REFERENCE_H__

#include <glib.h>

typedef struct _FlatpakDockerReference FlatpakDockerReference;

FlatpakDockerReference *flatpak_docker_reference_parse (const char *reference_str,
                                                        GError    **error);

const char *flatpak_docker_reference_get_uri        (FlatpakDockerReference *reference);
const char *flatpak_docker_reference_get_repository (FlatpakDockerReference *reference);
const char *flatpak_docker_reference_get_tag        (FlatpakDockerReference *reference);
const char *flatpak_docker_reference_get_digest     (FlatpakDockerReference *reference);

void flatpak_docker_reference_free (FlatpakDockerReference *reference);

G_DEFINE_AUTOPTR_CLEANUP_FUNC(FlatpakDockerReference, flatpak_docker_reference_free);

#endif /* __FLATPAK_DOCKER_REFERENCE_H__ */

===== ./common/flatpak-prune.c =====
/* vi:set et sw=2 sts=2 cin cino=t0,f0,(0,{s,>2s,n-s,^-s,e-s:
 * Copyright © 2021 Red Hat, Inc
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Alexander Larsson <alexl@redhat.com>
 */

#include "config.h"

#include <glib/gi18n-lib.h>

#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/file.h>

#include "flatpak-error.h"
#include "flatpak-prune-private.h"
#include "flatpak-variant-private.h"
#include "flatpak-variant-impl-private.h"
#include "libglnx.h"
#include "valgrind-private.h"

/* This is a custom implementation of ostree-prune that caches the
 * traversal for better performance on larger repos. It also merges the list-object
 * and prune operation to avoid allocating a lot of memory for the list of all
 * objects in the repo.
 *
 * Locking strategy:
 *
 * Ostree supports three kinds of approaches to handling parallel access to
 * the repo.
 *
 * EXCLUSIVE LOCK:
 *  All global operations that modify the repo state take an exclusive lock on the
 *  repo which means no other repo-modifying operation is allowed in parallel. This
 *  is currently only done for pruning and summary generation. Prune for instance
 *  is global; it traverses from a set of root commits and assumes that everything
 *  that isn't reachable can be deleted, which is not compatible with adding a
 *  new commit that doesn't have a root commit yet.
 *  NOTE: Whenever objects are deleted we always hold an exclusive lock.
 *
 * SHARED LOCKS:
 *  Operations that do local modifications take a shared lock. This means we can
 *  have multiple such operations in parallel with each other, but not in parallel
 *  with an exclusive lock. The typical operation that does this is the commit.
 *  During a commit we don't add to the transaction objects that already exist
 *  in the repo, so we rely on them not disappearing because then when we finally
 *  move the new objects into the repo that would produce a repo that has a broken
 *  object reference. There is nothing that prohibits two parallel commits to the
 *  same branch, and doing that could cause one of the commits to be lost in the
 *  branch history. However, the repo as a whole will always end up valid.
 *
 * NOTHING:
 *  Operations that are purely read-only and can either succeed or
 *  not as a whole do nothing to protect against parallelism. Typical examples
 *  are checkouts or pulls from a remote client. If such an operation is started
 *  nothing protects the repo from removing (by e.g. prune) objects from the repo
 *  that will be necessary to complete the operation. However, such an issue will
 *  be detected by the operation.
 *
 * Given the above the standard approach for locking during prune should be to take
 * an exclusive lock during the entire operation. However, the initial scan of the
 * reachable objects of a repo can take a very long time, and blocking any new
 * commits during this is not a great idea. So, to avoid this the prune operation
 * does two scans of the reachable commits. One with a shared lock and then again
 * with an exclusive lock. The second scan will be faster because it can ignore
 * all the commits we scanned with the shared lock held, meaning we spend less
 * time with an exclusive lock (during which no new commits can be added to the repo).
 *
 * Upgrading the shared lock to an exclusive lock is deadlock prune, as two prune
 * operations could be holding the shared lock and both blocking forever to get the
 * exclusive lock, so we release the lock between the phases. This means there is
 * a small chance that some objects were deleted between the two phases. However, that
 * will only cause the prune operation to over-estimate what objects are reachable, so
 * it can never cause it to delete reachable objects.
 */

static gboolean
ot_dfd_iter_init_allow_noent (int dfd,
                              const char *path,
                              GLnxDirFdIterator *dfd_iter,
                              gboolean *out_exists,
                              GError **error)
{
  glnx_autofd int fd = glnx_opendirat_with_errno (dfd, path, TRUE);
  if (fd < 0)
    {
      if (errno != ENOENT)
        return glnx_throw_errno_prefix (error, "opendirat");
      *out_exists = FALSE;
      return TRUE;
    }
  if (!glnx_dirfd_iterator_init_take_fd (&fd, dfd_iter, error))
    return FALSE;
  *out_exists = TRUE;
  return TRUE;
}

/* Object name helpers */

static guint
_ostree_object_name_hash (gconstpointer a)
{
  VarObjectNameRef ref = var_object_name_from_gvariant ((GVariant *)a);

  return g_str_hash (var_object_name_get_checksum (ref)) + (guint)var_object_name_get_objtype (ref);
}

static gboolean
_ostree_object_name_equal (gconstpointer a,
                           gconstpointer b)
{
  VarObjectNameRef ref_a = var_object_name_from_gvariant ((GVariant *)a);
  VarObjectNameRef ref_b = var_object_name_from_gvariant ((GVariant *)a);

  return
    g_str_equal (var_object_name_get_checksum (ref_a), var_object_name_get_checksum (ref_b)) &&
    var_object_name_get_objtype (ref_a) == var_object_name_get_objtype (ref_b);
}

static GHashTable *
reachable_commits_new (void)
{
  return g_hash_table_new_full (_ostree_object_name_hash, _ostree_object_name_equal,
                                NULL, (GDestroyNotify)g_variant_unref);
}

/* Wrapper to handle flock vs OFD locking based on GLnxLockFile */
static gboolean
do_repo_lock (int fd,
              int flags)
{
  int res;

#ifdef F_OFD_SETLK
  struct flock fl = {
    .l_type = (flags & ~LOCK_NB) == LOCK_EX ? F_WRLCK : F_RDLCK,
    .l_whence = SEEK_SET,
    .l_start = 0,
    .l_len = 0,
  };

  res = TEMP_FAILURE_RETRY (fcntl (fd, (flags & LOCK_NB) ? F_OFD_SETLK : F_OFD_SETLKW, &fl));
#else
  res = -1;
  errno = EINVAL;
#endif

  /* Fallback to flock when OFD locks not available */
  if (res < 0)
    {
      if (errno == EINVAL)
        res = TEMP_FAILURE_RETRY (flock (fd, flags));
      if (res < 0)
        return FALSE;
    }

  return TRUE;
}

static gboolean
get_repo_lock (OstreeRepo          *repo,
               int                  flags,
               int                 *out_lock_fd,
               GCancellable        *cancellable,
               GError             **error)
{
  glnx_autofd int lock_fd = -1;

  /* This re-implements a simpler (non-stacking) version of the ostree repo lock, as
     the API for that is not yet available. When it is (see https://github.com/ostreedev/ostree/pull/2341)
     this should be removed.
     Note: This also doesn't respect the locking config options, it always locks and it always blocks.
  */

  lock_fd = TEMP_FAILURE_RETRY (openat (ostree_repo_get_dfd (repo), ".lock",
                                        O_CREAT | O_RDWR | O_CLOEXEC, 0660));
  if (lock_fd < 0)
    return glnx_throw_errno_prefix (error,
                                    "Opening lock file %s/.lock failed",
                                    flatpak_file_get_path_cached (ostree_repo_get_path (repo)));

  if (!do_repo_lock (lock_fd, flags))
    return glnx_throw_errno_prefix (error, "Locking repo failed (%s)", (flags & LOCK_EX) != 0 ? "exclusive" : "shared");

  *out_lock_fd = g_steal_fd (&lock_fd);
  return TRUE;
}

#define _LOOSE_PATH_MAX (256)

static inline void
get_extra_commitmeta_path (const char *commit,
                           char *path_buf,
                           gsize path_buf_len)
{
  snprintf (path_buf, path_buf_len,
            "objects/%c%c/%s.commitmeta2",
            commit[0], commit[1], commit + 2);
}

static gboolean
load_extra_commitmeta (OstreeRepo       *repo,
                       const char       *commit,
                       GVariant        **out_variant,
                       GCancellable     *cancellable,
                       GError          **error)
{
  char loose_path_buf[_LOOSE_PATH_MAX];
  glnx_autofd int fd = -1;
  g_autoptr(GVariant) ret_variant = NULL;
  g_autoptr(GError) temp_error = NULL;

  get_extra_commitmeta_path (commit, loose_path_buf, sizeof (loose_path_buf));

  if (!glnx_openat_rdonly (ostree_repo_get_dfd (repo), loose_path_buf, FALSE, &fd, &temp_error) &&
      !g_error_matches (temp_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
    {
      g_propagate_error (error, temp_error);
      return FALSE;
    }

  if (fd != -1)
    {
      g_autoptr(GBytes) content = glnx_fd_readall_bytes (fd, cancellable, error);
      if (!content)
        return FALSE;
      ret_variant = g_variant_ref_sink (g_variant_new_from_bytes (G_VARIANT_TYPE ("a{sv}"), content, TRUE));
    }

  *out_variant = g_steal_pointer (&ret_variant);
  return TRUE;
}

static gboolean
save_extra_commitmeta (OstreeRepo       *repo,
                       const char       *commit,
                       GVariant         *variant,
                       GCancellable     *cancellable,
                       GError          **error)
{
  char loose_path_buf[_LOOSE_PATH_MAX];

  get_extra_commitmeta_path (commit, loose_path_buf, sizeof (loose_path_buf));

  if (!glnx_file_replace_contents_at (ostree_repo_get_dfd (repo), loose_path_buf,
                                      g_variant_get_data (variant),
                                      g_variant_get_size (variant),
                                      GLNX_FILE_REPLACE_DATASYNC_NEW,
                                      cancellable, error))
    return FALSE;

  return TRUE;
}

static gboolean
remove_extra_commitmeta (OstreeRepo       *repo,
                         const char       *commit,
                         GCancellable     *cancellable,
                         GError          **error)
{
  char loose_path_buf[_LOOSE_PATH_MAX];

  get_extra_commitmeta_path (commit, loose_path_buf, sizeof (loose_path_buf));

  /* Ignore errors */
  (void) unlinkat (ostree_repo_get_dfd (repo), loose_path_buf, 0);

  return TRUE;
}



/* Traverse parent commits starting at commit_checksum, and
 * up to maxdepth parents (-1 for unlimited).
 *
 * This doesn't do any locking, so need something else to have an exclusive lock
 * on the repo to avoid races with other processes modifying the repo.
 */
static gboolean
traverse_commit_parents_unlocked (OstreeRepo      *repo,
                                  const char      *commit_checksum,
                                  int              maxdepth,
                                  GHashTable      *inout_checksums,
                                  GCancellable    *cancellable,
                                  GError         **error)
{
  g_autofree char *tmp_checksum = NULL;

  while (TRUE)
    {
      g_autoptr(GVariant) commit = NULL;

      if (!ostree_repo_load_variant_if_exists (repo, OSTREE_OBJECT_TYPE_COMMIT,
                                               commit_checksum, &commit,
                                               error))
        return FALSE;

      /* Just return if the parent isn't found; we do expect most
       * people to have partial repositories.
       */
      if (commit == NULL)
        break;

      g_hash_table_add (inout_checksums, g_strdup (commit_checksum));

      gboolean recurse = FALSE;
      if (maxdepth == -1 || maxdepth > 0)
        {
          g_free (tmp_checksum);
          tmp_checksum = ostree_commit_get_parent (commit);
          if (tmp_checksum)
            {
              commit_checksum = tmp_checksum;
              if (maxdepth > 0)
                maxdepth -= 1;
              recurse = TRUE;
            }
        }
      if (!recurse)
        break;
    }

  return TRUE;
}

/* We need to keep track of possibly a lot of object names (flathub has > 16 million objects atm),
 * so the list of reachable objectnames need to be very compact. To handle this we use a fixed
 * size array to reference the object names. The first 32 bytes is the checksum in raw form and
 * the final byte is the object type.
 */

#define FLATPAK_OSTREE_OBJECT_NAME_LEN (32 + 1)
typedef guint8 FlatpakOstreeObjectName[FLATPAK_OSTREE_OBJECT_NAME_LEN];

#define FLATPAK_OSTREE_OBJECT_NAME_ELEMENT_TYPE "(yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy)" /* 32 + 1 bytes, is a fixed type */

static void
flatpak_ostree_object_name_serialize (FlatpakOstreeObjectName *name,
                                      const char *checksum,
                                      OstreeObjectType objtype)
{
  ostree_checksum_inplace_to_bytes (checksum, &(*name)[0]);
  g_assert (objtype < 255);
  (*name)[32] = (guint8) objtype;
}

static gint
flatpak_ostree_name_compare (const FlatpakOstreeObjectName *name_a,
                             const FlatpakOstreeObjectName *name_b)
{
  return memcmp (name_a, name_b, sizeof (FlatpakOstreeObjectName));
}

static guint
flatpak_ostree_object_name_hash (gconstpointer a)
{
  const FlatpakOstreeObjectName *name = a;
  const guint8 *data = &(*name)[0];

  /* The checksum is essentially all random, so any 4 bytes of it should
     be a good hash value. However, we avoid using the first ones, because
     those are the ones that will be first compared on a hash collision,
     so if they were always the same that would waste 4 comparisons. */
  return
    ((guint32) data[32]) |
    ((guint32) data[31]) << 8 |
    ((guint32) data[30]) << 16 |
    ((guint32) data[29]) << 24;
}

static gboolean
flatpak_ostree_object_name_equal (gconstpointer a,
                                  gconstpointer b)
{
  const FlatpakOstreeObjectName *name_a = a;
  const FlatpakOstreeObjectName *name_b = b;

  return flatpak_ostree_name_compare (name_a, name_b) == 0;
}

/* This is a container for allocating FlatpakOstreeObjectNames in chunks without relocations so
 * that the resulting pointers are stable and can be stored in e.g. a hashtable.
 * Storing the names in chunks like this means we avoid fragmentation and overhead related to
 * each individual name which is important as we can have millions of object names in a repo.
 */

#define BAG_CHUNK_SIZE 1985 /* nr of objects per chunk in bag, makes chunk fit in 64k with some spare for overhead */
typedef struct {
  FlatpakOstreeObjectName *current_chunk; /* Null if non started */
  gsize current_chunk_used; /* number of used objects in current chunk */
  GSList *chunks; /* List of allocated chunks */
  GHashTable *hash; /* (element-type FlatpakOstreeObjectName) */
} FlatpakOstreeObjectNameBag;

static FlatpakOstreeObjectNameBag *
object_name_bag_new (void)
{
  FlatpakOstreeObjectNameBag *bag = g_new0 (FlatpakOstreeObjectNameBag, 1);

  bag->hash = g_hash_table_new_full (flatpak_ostree_object_name_hash, flatpak_ostree_object_name_equal,
                                     NULL, NULL);

  return bag;
}

static void
object_name_bag_free (FlatpakOstreeObjectNameBag *bag)
{
  g_hash_table_unref (bag->hash);
  g_slist_free_full (bag->chunks, g_free);
  g_free (bag);
}

G_DEFINE_AUTOPTR_CLEANUP_FUNC (FlatpakOstreeObjectNameBag, object_name_bag_free)

static gboolean
object_name_bag_contains (FlatpakOstreeObjectNameBag *bag,
                          const FlatpakOstreeObjectName *name)
{
  return g_hash_table_contains (bag->hash, name);
}

static void
object_name_bag_insert (FlatpakOstreeObjectNameBag *bag,
                        const FlatpakOstreeObjectName *name)
{
  FlatpakOstreeObjectName *res;

  if (g_hash_table_contains (bag->hash, name))
    return;

  if (bag->current_chunk == NULL)
    {
      bag->current_chunk = g_new (FlatpakOstreeObjectName, BAG_CHUNK_SIZE);
      bag->current_chunk_used = 0;
      bag->chunks = g_slist_prepend (bag->chunks, bag->current_chunk);
    }

  res = &bag->current_chunk[bag->current_chunk_used++];
  memcpy (res, name, sizeof (FlatpakOstreeObjectName));

  if (bag->current_chunk_used == BAG_CHUNK_SIZE)
    bag->current_chunk = NULL; /* Need new chunk */

  g_hash_table_add (bag->hash, res);
}

/* Find all reachable commit objects starting from any ref in the repo
 * optionally limiting the number of parent commits.
 *
 * This doesn't do any locking, so need something else to have an exclusive lock
 * on the repo to avoid races with other processes modifying the repo.
 */
static gboolean
traverse_reachable_refs_unlocked (OstreeRepo                  *repo,
                                  guint                        depth,
                                  FlatpakOstreeObjectNameBag  *reachable,
                                  GCancellable                *cancellable,
                                  GError                     **error)
{
  g_autoptr(GHashTable) all_refs = NULL;  /* (element-type utf8 utf8) */
  g_autoptr(GHashTable) all_collection_refs = NULL;  /* (element-type OstreeChecksumRef utf8) */
  g_autoptr(GHashTable) checksums = NULL;  /* (element-type const char *) */

  checksums = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);

  /* Get all commits up to depth from the regular refs */
  if (!ostree_repo_list_refs (repo, NULL, &all_refs,
                              cancellable, error))
    return FALSE;

  GLNX_HASH_TABLE_FOREACH_V (all_refs, const char*, checksum)
    {
      if (!traverse_commit_parents_unlocked (repo, checksum, depth, checksums, cancellable, error))
        return FALSE;
    }

  /* Get all commits up to depth from the collection refs */
  if (!ostree_repo_list_collection_refs (repo, NULL, &all_collection_refs,
                                         OSTREE_REPO_LIST_REFS_EXT_EXCLUDE_REMOTES, cancellable, error))
    return FALSE;

  GLNX_HASH_TABLE_FOREACH_V (all_collection_refs, const char*, checksum)
    {
      if (!traverse_commit_parents_unlocked (repo, checksum, depth, checksums, cancellable, error))
        return FALSE;
    }

  /* Find reachable objects from each commit checksum */
  GLNX_HASH_TABLE_FOREACH_V (checksums, const char*, checksum)
    {
      g_autoptr(GVariant) extra_commitmeta = NULL;
      g_autoptr(GVariant) commit_reachable = NULL;
      FlatpakOstreeObjectName commit_name;

      /* Early bail-out if we already scanned this commit in the first phase (or via some other branch) */
      flatpak_ostree_object_name_serialize (&commit_name, checksum, OSTREE_OBJECT_TYPE_COMMIT);
      if (object_name_bag_contains (reachable, &commit_name))
        continue;

      g_debug ("Finding objects to keep for commit %s", checksum);

      if (!load_extra_commitmeta (repo, checksum, &extra_commitmeta, cancellable, error))
        return FALSE;

      if (extra_commitmeta)
        commit_reachable = g_variant_lookup_value (extra_commitmeta, "xa.reachable", G_VARIANT_TYPE ("a" FLATPAK_OSTREE_OBJECT_NAME_ELEMENT_TYPE));

      if (commit_reachable == NULL)
        {
          g_autoptr(GHashTable) commit_reachable_ht = reachable_commits_new ();
          g_autoptr(GVariant) new_extra_commitmeta = NULL;
          g_autofree FlatpakOstreeObjectName *commit_reachable_raw = NULL;
          FlatpakOstreeObjectName *next_commit_reachable_raw;
          g_auto(GVariantDict) extra_commitmeta_builder = FLATPAK_VARIANT_BUILDER_INITIALIZER;
          OstreeRepoCommitState commitstate = 0;
          g_autoptr(GError) local_error = NULL;

          if (!ostree_repo_load_commit (repo, checksum, NULL, &commitstate, &local_error) &&
              !g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
            {
              g_propagate_error (error, g_steal_pointer (&local_error));
              return FALSE;
            }

          if (!ostree_repo_traverse_commit_union (repo, checksum, 0, commit_reachable_ht,
                                                  cancellable, error))
            return FALSE;

          commit_reachable_raw = g_new (FlatpakOstreeObjectName, g_hash_table_size (commit_reachable_ht));

          next_commit_reachable_raw = &commit_reachable_raw[0];
          GLNX_HASH_TABLE_FOREACH_V (commit_reachable_ht, GVariant *, reachable_commit)
            {
              VarObjectNameRef ref = var_object_name_from_gvariant ((GVariant *)reachable_commit);

              flatpak_ostree_object_name_serialize (next_commit_reachable_raw,
                                                    var_object_name_get_checksum (ref),
                                                    var_object_name_get_objtype (ref));
              next_commit_reachable_raw++;
            }

          commit_reachable = g_variant_ref_sink (g_variant_new_fixed_array (G_VARIANT_TYPE (FLATPAK_OSTREE_OBJECT_NAME_ELEMENT_TYPE),
                                                                            commit_reachable_raw,
                                                                            g_hash_table_size (commit_reachable_ht),
                                                                            sizeof(FlatpakOstreeObjectName)));

          /* Don't save the reachable set for later reuse if the commit is partial, as it may not be complete */
          if ((commitstate & OSTREE_REPO_COMMIT_STATE_PARTIAL) == 0)
            {
              g_variant_dict_init (&extra_commitmeta_builder, extra_commitmeta);
              g_variant_dict_insert_value (&extra_commitmeta_builder, "xa.reachable", commit_reachable);

              new_extra_commitmeta = g_variant_ref_sink (g_variant_dict_end (&extra_commitmeta_builder));
              if (!save_extra_commitmeta (repo, checksum, new_extra_commitmeta, cancellable, error))
                return FALSE;
            }
        }

      {
        gsize n_reachable, i;
        const FlatpakOstreeObjectName *reachable_objects =
          g_variant_get_fixed_array (commit_reachable, &n_reachable,
                                     sizeof(FlatpakOstreeObjectName));

        for (i = 0; i < n_reachable; i++)
          object_name_bag_insert (reachable, &reachable_objects[i]);
      }
    }

  return TRUE;
}

typedef struct {
  OstreeRepo *repo;
  FlatpakOstreeObjectNameBag *reachable;
  gboolean dont_prune;
  guint n_reachable;
  guint n_unreachable;
  guint64 freed_bytes;
} OtPruneData;

static gboolean
prune_loose_object (OtPruneData          *data,
                    const char           *checksum,
                    OstreeObjectType      objtype,
                    GCancellable         *cancellable,
                    GError              **error)
{
  guint64 storage_size = 0;

  g_debug ("Pruning unneeded object %s.%s", checksum,
           ostree_object_type_to_string (objtype));

  if (!ostree_repo_query_object_storage_size (data->repo, objtype, checksum,
                                              &storage_size, cancellable, error))
    return FALSE;

  data->freed_bytes += storage_size;
  data->n_unreachable++;

  if (!data->dont_prune)
    {
      if (objtype == OSTREE_OBJECT_TYPE_COMMIT)
        {
          if (!remove_extra_commitmeta (data->repo, checksum, cancellable, error))
            return FALSE;

          if (!ostree_repo_mark_commit_partial (data->repo, checksum, FALSE, error))
            return FALSE;
        }

      if (!ostree_repo_delete_object (data->repo, objtype, checksum,
                                      cancellable, error))
        return FALSE;
    }

  return TRUE;
}

static gboolean
prune_unreachable_loose_objects_at (OstreeRepo             *self,
                                    OtPruneData            *data,
                                    int                     dfd,
                                    const char             *prefix,
                                    GCancellable           *cancellable,
                                    GError                **error)
{

  g_auto(GLnxDirFdIterator) dfd_iter = { 0, };
  gboolean exists;
  if (!ot_dfd_iter_init_allow_noent (dfd, prefix, &dfd_iter, &exists, error))
    return FALSE;
  /* Note early return */
  if (!exists)
    return TRUE;

  while (TRUE)
    {
      struct dirent *dent;
      FlatpakOstreeObjectName key;

      if (!glnx_dirfd_iterator_next_dent (&dfd_iter, &dent, cancellable, error))
        return FALSE;
      if (dent == NULL)
        break;

      const char *name = dent->d_name;
      if (strcmp (name, ".") == 0 ||
          strcmp (name, "..") == 0)
        continue;

      const char *dot = strrchr (name, '.');
      if (!dot)
        continue;

      OstreeObjectType objtype;

      if (strcmp (dot, ".filez") == 0)
        objtype = OSTREE_OBJECT_TYPE_FILE;
      else if (strcmp (dot, ".dirtree") == 0)
        objtype = OSTREE_OBJECT_TYPE_DIR_TREE;
      else if (strcmp (dot, ".dirmeta") == 0)
        objtype = OSTREE_OBJECT_TYPE_DIR_META;
      else if (strcmp (dot, ".commit") == 0)
        objtype = OSTREE_OBJECT_TYPE_COMMIT;
      else /* No need to handle payload links, they don't happen in archive repos and we call the ostree prune for all other repos */
        continue;

      if ((dot - name) != 62)
        continue;

      char buf[OSTREE_SHA256_STRING_LEN+1];

      memcpy (buf, prefix+8, 2);
      memcpy (buf + 2, name, 62);
      buf[sizeof(buf)-1] = '\0';

      flatpak_ostree_object_name_serialize (&key, buf, objtype);
      if (object_name_bag_contains (data->reachable, &key))
        {
          data->n_reachable++;
          continue;
        }

      if (!prune_loose_object (data, buf, objtype, cancellable, error))
        return FALSE;
    }

  return TRUE;
}

static gboolean
prune_unreachable_loose_objects (OstreeRepo                  *self,
                                 OtPruneData                 *data,
                                 GCancellable                *cancellable,
                                 GError                     **error)
{
 static const gchar hexchars[] = "0123456789abcdef";
 int dfd = ostree_repo_get_dfd (self);

 g_return_val_if_fail (error == NULL || *error == NULL, FALSE);

 for (guint c = 0; c < 256; c++)
   {
     char buf[] = "objects/XX";
     buf[8] = hexchars[c >> 4];
     buf[9] = hexchars[c & 0xF];

     if (!prune_unreachable_loose_objects_at (self, data, dfd, buf, cancellable, error))
       return FALSE;
   }

 return TRUE;
}

gboolean
flatpak_repo_prune (OstreeRepo    *repo,
                    int            depth,
                    gboolean       dry_run,
                    int           *out_objects_total,
                    int           *out_objects_pruned,
                    guint64       *out_pruned_object_size_total,
                    GCancellable  *cancellable,
                    GError       **error)
{
  g_autoptr(FlatpakOstreeObjectNameBag) reachable = object_name_bag_new ();
  OtPruneData data = { 0, };
  g_autoptr(GTimer) timer = NULL;

  /* This version only handles archive repos, if called for something else call ostree */
  if (ostree_repo_get_mode (repo) != OSTREE_REPO_MODE_ARCHIVE)
    {
      OstreeRepoPruneFlags flags = OSTREE_REPO_PRUNE_FLAGS_REFS_ONLY;
      if (dry_run)
        flags |= OSTREE_REPO_PRUNE_FLAGS_NO_PRUNE;

      return ostree_repo_prune (repo, flags, depth,
                                out_objects_total, out_objects_pruned, out_pruned_object_size_total,
                                cancellable, error);
    }

  {
    /* shared lock in this region, see locking strategy above */
    glnx_autofd int lock_fd = -1;

    if (!get_repo_lock (repo, LOCK_SH, &lock_fd, cancellable, error))
      return FALSE;

    timer = g_timer_new ();
    g_info ("Finding reachable objects, unlocked (depth=%d)", depth);
    g_timer_start (timer);

    if (!traverse_reachable_refs_unlocked (repo, depth, reachable, cancellable, error))
      return FALSE;

    g_timer_stop (timer);
    g_info ("Elapsed time: %.1f sec",  g_timer_elapsed (timer, NULL));
    g_clear_pointer (&timer, g_timer_destroy);
  }

  if (!dry_run)
    {
      /* exclusive lock in this region, see locking strategy above */
      glnx_autofd int lock_fd = -1;

      if (!get_repo_lock (repo, LOCK_EX, &lock_fd, cancellable, error))
        return FALSE;

      timer = g_timer_new ();
      g_info ("Finding reachable objects, locked (depth=%d)", depth);
      g_timer_start (timer);

      if (!traverse_reachable_refs_unlocked (repo, depth, reachable, cancellable, error))
        return FALSE;

      data.repo = repo;
      data.reachable = reachable;
      data.dont_prune = dry_run;

      g_timer_stop (timer);
      g_info ("Elapsed time: %.1f sec",  g_timer_elapsed (timer, NULL));

      {
        g_info ("Pruning unreachable objects");
        g_timer_start (timer);

        if (!prune_unreachable_loose_objects (repo, &data, cancellable, error))
          return FALSE;

        g_timer_stop (timer);
        g_info ("Elapsed time: %.1f sec",  g_timer_elapsed (timer, NULL));
      }
    }

  /* Prune static deltas outside lock to avoid conflict with its exclusive lock */
  if (!dry_run)
    {
      g_info ("Pruning static deltas");
      g_timer_start (timer);

      if (!ostree_repo_prune_static_deltas (repo, NULL, cancellable, error))
        return FALSE;

      g_timer_stop (timer);
      g_info ("Elapsed time: %.1f sec",  g_timer_elapsed (timer, NULL));
    }

  *out_objects_total = data.n_reachable + data.n_unreachable;
  *out_objects_pruned = data.n_unreachable;
  *out_pruned_object_size_total = data.freed_bytes;
  return TRUE;
}


===== ./common/flatpak-installation.h =====
/*
 * Copyright © 2015 Red Hat, Inc
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Alexander Larsson <alexl@redhat.com>
 */

#if !defined(__FLATPAK_H_INSIDE__) && !defined(FLATPAK_COMPILATION)
#error "Only <flatpak.h> can be included directly."
#endif

#ifndef __FLATPAK_INSTALLATION_H__
#define __FLATPAK_INSTALLATION_H__

typedef struct _FlatpakInstallation FlatpakInstallation;

#include <gio/gio.h>
#include <flatpak-installed-ref.h>
#include <flatpak-instance.h>
#include <flatpak-remote.h>

G_BEGIN_DECLS

#define FLATPAK_TYPE_INSTALLATION flatpak_installation_get_type ()
#define FLATPAK_INSTALLATION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), FLATPAK_TYPE_INSTALLATION, FlatpakInstallation))
#define FLATPAK_IS_INSTALLATION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), FLATPAK_TYPE_INSTALLATION))

FLATPAK_EXTERN GType flatpak_installation_get_type (void);

struct _FlatpakInstallation
{
  GObject parent;
};

typedef struct
{
  GObjectClass parent_class;
} FlatpakInstallationClass;

/**
 * FlatpakUpdateFlags:
 * @FLATPAK_UPDATE_FLAGS_NONE: Fetch remote builds and install the latest one (default)
 * @FLATPAK_UPDATE_FLAGS_NO_DEPLOY: Don't install any new builds that might be fetched
 * @FLATPAK_UPDATE_FLAGS_NO_PULL: Don't try to fetch new builds from the remote repo
 * @FLATPAK_UPDATE_FLAGS_NO_STATIC_DELTAS: Don't use static deltas when pulling
 * @FLATPAK_UPDATE_FLAGS_NO_PRUNE: Don't prune the local OSTree repository after updating (Since: 0.11.8)
 * @FLATPAK_UPDATE_FLAGS_NO_TRIGGERS: Don't call triggers after updating. If used,
 * the caller must later call flatpak_installation_run_triggers() to update
 * the exported files. (Since: 1.0.3)
 *
 * Flags to alter the behavior of flatpak_installation_update().
 */
typedef enum {
  FLATPAK_UPDATE_FLAGS_NONE             = 0,
  FLATPAK_UPDATE_FLAGS_NO_DEPLOY        = (1 << 0),
  FLATPAK_UPDATE_FLAGS_NO_PULL          = (1 << 1),
  FLATPAK_UPDATE_FLAGS_NO_STATIC_DELTAS = (1 << 2),
  FLATPAK_UPDATE_FLAGS_NO_PRUNE         = (1 << 3),
  FLATPAK_UPDATE_FLAGS_NO_TRIGGERS      = (1 << 4),
} FlatpakUpdateFlags;

/**
 * FlatpakInstallFlags:
 * @FLATPAK_INSTALL_FLAGS_NONE: Default
 * @FLATPAK_INSTALL_FLAGS_NO_STATIC_DELTAS: Don't use static deltas when pulling
 * @FLATPAK_INSTALL_FLAGS_NO_DEPLOY: Don't install any new builds that might be fetched
 * @FLATPAK_INSTALL_FLAGS_NO_PULL: Don't try to fetch new builds from the remote repo
 * @FLATPAK_INSTALL_FLAGS_NO_TRIGGERS: Don't call triggers after installing. If used,
 * the caller must later call flatpak_installation_run_triggers() to update
 * the exported files. (Since: 1.0.3)
 *
 * Flags to alter the behavior of flatpak_installation_install_full().
 */
typedef enum {
  FLATPAK_INSTALL_FLAGS_NONE             = 0,
  FLATPAK_INSTALL_FLAGS_NO_STATIC_DELTAS = (1 << 0),
  FLATPAK_INSTALL_FLAGS_NO_DEPLOY        = (1 << 2),
  FLATPAK_INSTALL_FLAGS_NO_PULL          = (1 << 3),
  FLATPAK_INSTALL_FLAGS_NO_TRIGGERS      = (1 << 4),
} FlatpakInstallFlags;

/**
 * FlatpakUninstallFlags:
 * @FLATPAK_UNINSTALL_FLAGS_NONE: Default
 * @FLATPAK_UNINSTALL_FLAGS_NO_PRUNE: Don't prune the local OSTree repository after uninstalling
 * @FLATPAK_UNINSTALL_FLAGS_NO_TRIGGERS: Don't call triggers after uninstalling. If used,
 * the caller must later call flatpak_installation_run_triggers() to update
 * the exported file. (Since: 1.0.3)
 *
 * Flags to alter the behavior of flatpak_installation_uninstall_full().
 *
 * Since: 0.11.8
 */
typedef enum {
  FLATPAK_UNINSTALL_FLAGS_NONE            = 0,
  FLATPAK_UNINSTALL_FLAGS_NO_PRUNE        = (1 << 0),
  FLATPAK_UNINSTALL_FLAGS_NO_TRIGGERS     = (1 << 1),
} FlatpakUninstallFlags;

/**
 * FlatpakLaunchFlags:
 * @FLATPAK_LAUNCH_FLAGS_NONE: Default
 * @FLATPAK_LAUNCH_FLAGS_DO_NOT_REAP: Do not reap the child. Use this if you want to wait
 * for the child with g_child_watch_add(). (Since: 1.1)
 *
 * Flags to alter the behavior of flatpak_installation_launch_full().
 */
typedef enum {
  FLATPAK_LAUNCH_FLAGS_NONE        = 0,
  FLATPAK_LAUNCH_FLAGS_DO_NOT_REAP = (1 << 0),
} FlatpakLaunchFlags;

/**
 * FlatpakQueryFlags:
 * @FLATPAK_QUERY_FLAGS_NONE: Default
 * @FLATPAK_QUERY_FLAGS_ONLY_CACHED: Don't do any network i/o, but only return cached data.
 * This can return stale data, or a #FLATPAK_ERROR_NOT_CACHED error, however it is a
 * lot more efficient if you're doing many requests.
 * @FLATPAK_QUERY_FLAGS_ONLY_SIDELOADED: Only list refs available from sideload
 * repos; see flatpak(1). (Since: 1.7)
 * @FLATPAK_QUERY_FLAGS_ALL_ARCHES: Include refs from all arches, not just the primary ones. (Since: 1.11.2)
 *
 * Flags to alter the behavior of e.g flatpak_installation_list_remote_refs_sync_full().
 *
 * Since: 1.3.3
 */
typedef enum {
  FLATPAK_QUERY_FLAGS_NONE        = 0,
  FLATPAK_QUERY_FLAGS_ONLY_CACHED = (1 << 0),
  FLATPAK_QUERY_FLAGS_ONLY_SIDELOADED = (1 << 1),
  FLATPAK_QUERY_FLAGS_ALL_ARCHES = (1 << 2),
} FlatpakQueryFlags;

/**
 * FlatpakStorageType:
 * @FLATPAK_STORAGE_TYPE_DEFAULT: default
 * @FLATPAK_STORAGE_TYPE_HARD_DISK: installation is on a hard disk
 * @FLATPAK_STORAGE_TYPE_SDCARD: installation is on a SD card
 * @FLATPAK_STORAGE_TYPE_MMC: installation is on an MMC
 * @FLATPAK_STORAGE_TYPE_NETWORK: installation is on the network
 *
 * Information about the storage of an installation.
 *
 * Since: 0.6.15
 */
typedef enum {
  FLATPAK_STORAGE_TYPE_DEFAULT = 0,
  FLATPAK_STORAGE_TYPE_HARD_DISK,
  FLATPAK_STORAGE_TYPE_SDCARD,
  FLATPAK_STORAGE_TYPE_MMC,
  FLATPAK_STORAGE_TYPE_NETWORK,
} FlatpakStorageType;


#ifdef G_DEFINE_AUTOPTR_CLEANUP_FUNC
G_DEFINE_AUTOPTR_CLEANUP_FUNC (FlatpakInstallation, g_object_unref)
#endif

FLATPAK_EXTERN const char  *flatpak_get_default_arch (void);

FLATPAK_EXTERN const char *const *flatpak_get_supported_arches (void);

FLATPAK_EXTERN GPtrArray *flatpak_get_system_installations (GCancellable *cancellable,
                                                            GError      **error);
FLATPAK_EXTERN FlatpakInstallation *flatpak_installation_new_system (GCancellable *cancellable,
                                                                     GError      **error);
FLATPAK_EXTERN FlatpakInstallation *flatpak_installation_new_system_with_id (const char   *id,
                                                                             GCancellable *cancellable,
                                                                             GError      **error);
FLATPAK_EXTERN FlatpakInstallation *flatpak_installation_new_user (GCancellable *cancellable,
                                                                   GError      **error);
FLATPAK_EXTERN FlatpakInstallation *flatpak_installation_new_for_path (GFile        *path,
                                                                       gboolean      user,
                                                                       GCancellable *cancellable,
                                                                       GError      **error);
FLATPAK_EXTERN void flatpak_installation_set_no_interaction (FlatpakInstallation *self,
                                                             gboolean             no_interaction);
FLATPAK_EXTERN gboolean flatpak_installation_get_no_interaction (FlatpakInstallation *self);

/**
 * FlatpakProgressCallback:
 * @status: A status string, suitable for display
 * @progress: percentage of completion
 * @estimating: whether @progress is just an estimate
 * @user_data: User data passed to the caller
 *
 * The progress callback is called repeatedly during long-running operations
 * such as installations or updates, and can be used to update progress information
 * in a user interface.
 *
 * The callback occurs in the thread-default context of the caller.
 */
typedef void (*FlatpakProgressCallback)(const char *status,
                                        guint       progress,
                                        gboolean    estimating,
                                        gpointer    user_data);

FLATPAK_EXTERN gboolean             flatpak_installation_drop_caches (FlatpakInstallation *self,
                                                                      GCancellable        *cancellable,
                                                                      GError             **error);
FLATPAK_EXTERN gboolean             flatpak_installation_get_is_user (FlatpakInstallation *self);
FLATPAK_EXTERN GFile               *flatpak_installation_get_path (FlatpakInstallation *self);
FLATPAK_EXTERN const char          *flatpak_installation_get_id (FlatpakInstallation *self);
FLATPAK_EXTERN const char          *flatpak_installation_get_display_name (FlatpakInstallation *self);
FLATPAK_EXTERN gint                 flatpak_installation_get_priority (FlatpakInstallation *self);
FLATPAK_EXTERN FlatpakStorageType   flatpak_installation_get_storage_type (FlatpakInstallation *self);
FLATPAK_EXTERN gboolean             flatpak_installation_launch (FlatpakInstallation *self,
                                                                 const char          *name,
                                                                 const char          *arch,
                                                                 const char          *branch,
                                                                 const char          *commit,
                                                                 GCancellable        *cancellable,
                                                                 GError             **error);
FLATPAK_EXTERN gboolean             flatpak_installation_launch_full (FlatpakInstallation *self,
                                                                      FlatpakLaunchFlags   flags,
                                                                      const char          *name,
                                                                      const char          *arch,
                                                                      const char          *branch,
                                                                      const char          *commit,
                                                                      FlatpakInstance    **instance_out,
                                                                      GCancellable        *cancellable,
                                                                      GError             **error);
FLATPAK_EXTERN GFileMonitor        *flatpak_installation_create_monitor (FlatpakInstallation *self,
                                                                         GCancellable        *cancellable,
                                                                         GError             **error);
FLATPAK_EXTERN guint64              flatpak_installation_get_timestamp (FlatpakInstallation *self);
FLATPAK_EXTERN GPtrArray           *flatpak_installation_list_installed_refs (FlatpakInstallation *self,
                                                                              GCancellable        *cancellable,
                                                                              GError             **error);
FLATPAK_EXTERN GPtrArray           *flatpak_installation_list_installed_refs_by_kind (FlatpakInstallation *self,
                                                                                      FlatpakRefKind       kind,
                                                                                      GCancellable        *cancellable,
                                                                                      GError             **error);
FLATPAK_EXTERN GPtrArray           *flatpak_installation_list_installed_refs_for_update (FlatpakInstallation *self,
                                                                                         GCancellable        *cancellable,
                                                                                         GError             **error);
FLATPAK_EXTERN GPtrArray           *flatpak_installation_list_unused_refs (FlatpakInstallation *self,
                                                                           const char          *arch,
                                                                           GCancellable        *cancellable,
                                                                           GError             **error);
FLATPAK_EXTERN GPtrArray           *flatpak_installation_list_unused_refs_with_options (FlatpakInstallation *self,
                                                                                        const char          *arch,
                                                                                        GHashTable          *metadata_injection,
                                                                                        GVariant            *options,
                                                                                        GCancellable        *cancellable,
                                                                                        GError             **error);
FLATPAK_EXTERN GPtrArray           *flatpak_installation_list_pinned_refs (FlatpakInstallation *self,
                                                                           const char          *arch,
                                                                           GCancellable        *cancellable,
                                                                           GError             **error);
FLATPAK_EXTERN FlatpakInstalledRef * flatpak_installation_get_installed_ref (FlatpakInstallation *self,
                                                                             FlatpakRefKind       kind,
                                                                             const char          *name,
                                                                             const char          *arch,
                                                                             const char          *branch,
                                                                             GCancellable        *cancellable,
                                                                             GError             **error);
FLATPAK_EXTERN FlatpakInstalledRef * flatpak_installation_get_current_installed_app (FlatpakInstallation *self,
                                                                                     const char          *name,
                                                                                     GCancellable        *cancellable,
                                                                                     GError             **error);

FLATPAK_EXTERN GPtrArray           *flatpak_installation_list_remotes (FlatpakInstallation *self,
                                                                       GCancellable        *cancellable,
                                                                       GError             **error);
FLATPAK_EXTERN GPtrArray           *flatpak_installation_list_remotes_by_type (FlatpakInstallation    *self,
                                                                               const FlatpakRemoteType types[],
                                                                               gsize                   num_types,
                                                                               GCancellable           *cancellable,
                                                                               GError                **error);
FLATPAK_EXTERN FlatpakRemote        *flatpak_installation_get_remote_by_name (FlatpakInstallation *self,
                                                                              const gchar         *name,
                                                                              GCancellable        *cancellable,
                                                                              GError             **error);
FLATPAK_EXTERN gboolean              flatpak_installation_add_remote (FlatpakInstallation *self,
                                                                      FlatpakRemote       *remote,
                                                                      gboolean             if_needed,
                                                                      GCancellable        *cancellable,
                                                                      GError             **error);
FLATPAK_EXTERN gboolean              flatpak_installation_modify_remote (FlatpakInstallation *self,
                                                                         FlatpakRemote       *remote,
                                                                         GCancellable        *cancellable,
                                                                         GError             **error);
FLATPAK_EXTERN gboolean              flatpak_installation_remove_remote (FlatpakInstallation *self,
                                                                         const char          *name,
                                                                         GCancellable        *cancellable,
                                                                         GError             **error);
FLATPAK_EXTERN gboolean              flatpak_installation_update_remote_sync (FlatpakInstallation *self,
                                                                              const char          *name,
                                                                              GCancellable        *cancellable,
                                                                              GError             **error);
FLATPAK_EXTERN gboolean              flatpak_installation_set_config_sync (FlatpakInstallation *self,
                                                                           const char          *key,
                                                                           const char          *value,
                                                                           GCancellable        *cancellable,
                                                                           GError             **error);
FLATPAK_EXTERN gboolean              flatpak_installation_get_min_free_space_bytes (FlatpakInstallation *self,
                                                                                    guint64             *out_bytes,
                                                                                    GError             **error);
FLATPAK_EXTERN char *                flatpak_installation_get_config (FlatpakInstallation *self,
                                                                      const char          *key,
                                                                      GCancellable        *cancellable,
                                                                      GError             **error);
FLATPAK_EXTERN char **               flatpak_installation_get_default_languages (FlatpakInstallation  *self,
                                                                                 GError              **error);
FLATPAK_EXTERN char **               flatpak_installation_get_default_locales (FlatpakInstallation  *self,
                                                                               GError              **error);
FLATPAK_EXTERN char *              flatpak_installation_load_app_overrides (FlatpakInstallation *self,
                                                                            const char          *app_id,
                                                                            GCancellable        *cancellable,
                                                                            GError             **error);
G_GNUC_DEPRECATED_FOR(flatpak_transaction_add_install)
FLATPAK_EXTERN FlatpakInstalledRef * flatpak_installation_install (FlatpakInstallation    *self,
                                                                   const char             *remote_name,
                                                                   FlatpakRefKind          kind,
                                                                   const char             *name,
                                                                   const char             *arch,
                                                                   const char             *branch,
                                                                   FlatpakProgressCallback progress,
                                                                   gpointer                progress_data,
                                                                   GCancellable           *cancellable,
                                                                   GError                **error);
G_GNUC_DEPRECATED_FOR(flatpak_transaction_add_install)
FLATPAK_EXTERN FlatpakInstalledRef * flatpak_installation_install_full (FlatpakInstallation    *self,
                                                                        FlatpakInstallFlags     flags,
                                                                        const char             *remote_name,
                                                                        FlatpakRefKind          kind,
                                                                        const char             *name,
                                                                        const char             *arch,
                                                                        const char             *branch,
                                                                        const char * const     *subpaths,
                                                                        FlatpakProgressCallback progress,
                                                                        gpointer                progress_data,
                                                                        GCancellable           *cancellable,
                                                                        GError                **error);
G_GNUC_DEPRECATED_FOR(flatpak_transaction_add_update)
FLATPAK_EXTERN FlatpakInstalledRef * flatpak_installation_update (FlatpakInstallation    *self,
                                                                  FlatpakUpdateFlags      flags,
                                                                  FlatpakRefKind          kind,
                                                                  const char             *name,
                                                                  const char             *arch,
                                                                  const char             *branch,
                                                                  FlatpakProgressCallback progress,
                                                                  gpointer                progress_data,
                                                                  GCancellable           *cancellable,
                                                                  GError                **error);
G_GNUC_DEPRECATED_FOR(flatpak_transaction_add_update)
FLATPAK_EXTERN FlatpakInstalledRef * flatpak_installation_update_full (FlatpakInstallation    *self,
                                                                       FlatpakUpdateFlags      flags,
                                                                       FlatpakRefKind          kind,
                                                                       const char             *name,
                                                                       const char             *arch,
                                                                       const char             *branch,
                                                                       const char * const     *subpaths,
                                                                       FlatpakProgressCallback progress,
                                                                       gpointer                progress_data,
                                                                       GCancellable           *cancellable,
                                                                       GError                **error);
G_GNUC_DEPRECATED_FOR(flatpak_transaction_add_install_bundle)
FLATPAK_EXTERN FlatpakInstalledRef * flatpak_installation_install_bundle (FlatpakInstallation    *self,
                                                                          GFile                  *file,
                                                                          FlatpakProgressCallback progress,
                                                                          gpointer                progress_data,
                                                                          GCancellable           *cancellable,
                                                                          GError                **error);
G_GNUC_DEPRECATED_FOR(flatpak_transaction_add_install_flatpakref)
FLATPAK_EXTERN FlatpakRemoteRef *   flatpak_installation_install_ref_file (FlatpakInstallation *self,
                                                                           GBytes              *ref_file_data,
                                                                           GCancellable        *cancellable,
                                                                           GError             **error);
G_GNUC_DEPRECATED_FOR(flatpak_transaction_add_uninstall)
FLATPAK_EXTERN gboolean             flatpak_installation_uninstall (FlatpakInstallation    *self,
                                                                    FlatpakRefKind          kind,
                                                                    const char             *name,
                                                                    const char             *arch,
                                                                    const char             *branch,
                                                                    FlatpakProgressCallback progress,
                                                                    gpointer                progress_data,
                                                                    GCancellable           *cancellable,
                                                                    GError                **error);

G_GNUC_DEPRECATED_FOR(flatpak_transaction_add_uninstall)
FLATPAK_EXTERN gboolean             flatpak_installation_uninstall_full (FlatpakInstallation    *self,
                                                                         FlatpakUninstallFlags   flags,
                                                                         FlatpakRefKind          kind,
                                                                         const char             *name,
                                                                         const char             *arch,
                                                                         const char             *branch,
                                                                         FlatpakProgressCallback progress,
                                                                         gpointer                progress_data,
                                                                         GCancellable           *cancellable,
                                                                         GError                **error);

FLATPAK_EXTERN gboolean          flatpak_installation_fetch_remote_size_sync (FlatpakInstallation *self,
                                                                              const char          *remote_name,
                                                                              FlatpakRef          *ref,
                                                                              guint64             *download_size,
                                                                              guint64             *installed_size,
                                                                              GCancellable        *cancellable,
                                                                              GError             **error);
FLATPAK_EXTERN GBytes        *   flatpak_installation_fetch_remote_metadata_sync (FlatpakInstallation *self,
                                                                                  const char          *remote_name,
                                                                                  FlatpakRef          *ref,
                                                                                  GCancellable        *cancellable,
                                                                                  GError             **error);
FLATPAK_EXTERN GPtrArray    *    flatpak_installation_list_remote_refs_sync (FlatpakInstallation *self,
                                                                             const char          *remote_or_uri,
                                                                             GCancellable        *cancellable,
                                                                             GError             **error);
FLATPAK_EXTERN GPtrArray    *    flatpak_installation_list_remote_refs_sync_full (FlatpakInstallation *self,
                                                                                  const char          *remote_or_uri,
                                                                                  FlatpakQueryFlags    flags,
                                                                                  GCancellable        *cancellable,
                                                                                  GError             **error);
FLATPAK_EXTERN FlatpakRemoteRef  *flatpak_installation_fetch_remote_ref_sync (FlatpakInstallation *self,
                                                                              const char          *remote_name,
                                                                              FlatpakRefKind       kind,
                                                                              const char          *name,
                                                                              const char          *arch,
                                                                              const char          *branch,
                                                                              GCancellable        *cancellable,
                                                                              GError             **error);
FLATPAK_EXTERN FlatpakRemoteRef  *flatpak_installation_fetch_remote_ref_sync_full (FlatpakInstallation *self,
                                                                                   const char          *remote_name,
                                                                                   FlatpakRefKind       kind,
                                                                                   const char          *name,
                                                                                   const char          *arch,
                                                                                   const char          *branch,
                                                                                   FlatpakQueryFlags    flags,
                                                                                   GCancellable        *cancellable,
                                                                                   GError             **error);
FLATPAK_EXTERN gboolean          flatpak_installation_update_appstream_sync (FlatpakInstallation *self,
                                                                             const char          *remote_name,
                                                                             const char          *arch,
                                                                             gboolean            *out_changed,
                                                                             GCancellable        *cancellable,
                                                                             GError             **error);
FLATPAK_EXTERN gboolean          flatpak_installation_update_appstream_full_sync (FlatpakInstallation    *self,
                                                                                  const char             *remote_name,
                                                                                  const char             *arch,
                                                                                  FlatpakProgressCallback progress,
                                                                                  gpointer                progress_data,
                                                                                  gboolean               *out_changed,
                                                                                  GCancellable           *cancellable,
                                                                                  GError                **error);
FLATPAK_EXTERN GPtrArray    *    flatpak_installation_list_remote_related_refs_sync (FlatpakInstallation *self,
                                                                                     const char          *remote_name,
                                                                                     const char          *ref,
                                                                                     GCancellable        *cancellable,
                                                                                     GError             **error);
FLATPAK_EXTERN GPtrArray    *    flatpak_installation_list_remote_related_refs_for_installed_sync (FlatpakInstallation *self,
                                                                                                   const char          *remote_name,
                                                                                                   const char          *ref,
                                                                                                   GCancellable        *cancellable,
                                                                                                   GError             **error);
FLATPAK_EXTERN GPtrArray    *    flatpak_installation_list_installed_related_refs_sync (FlatpakInstallation *self,
                                                                                        const char          *remote_name,
                                                                                        const char          *ref,
                                                                                        GCancellable        *cancellable,
                                                                                        GError             **error);

FLATPAK_EXTERN gboolean          flatpak_installation_remove_local_ref_sync (FlatpakInstallation *self,
                                                                             const char          *remote_name,
                                                                             const char          *ref,
                                                                             GCancellable        *cancellable,
                                                                             GError             **error);
FLATPAK_EXTERN gboolean          flatpak_installation_cleanup_local_refs_sync (FlatpakInstallation *self,
                                                                               GCancellable        *cancellable,
                                                                               GError             **error);
FLATPAK_EXTERN gboolean          flatpak_installation_prune_local_repo (FlatpakInstallation *self,
                                                                        GCancellable        *cancellable,
                                                                        GError             **error);
FLATPAK_EXTERN gboolean          flatpak_installation_run_triggers (FlatpakInstallation *self,
                                                                    GCancellable        *cancellable,
                                                                    GError             **error);

G_END_DECLS

#endif /* __FLATPAK_INSTALLATION_H__ */

===== ./common/flatpak-json-oci-private.h =====
/*
 * Copyright © 2016 Red Hat, Inc
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Alexander Larsson <alexl@redhat.com>
 */

#ifndef __FLATPAK_JSON_OCI_H__
#define __FLATPAK_JSON_OCI_H__

#include "flatpak-json-private.h"

G_BEGIN_DECLS

#define FLATPAK_OCI_MEDIA_TYPE_DESCRIPTOR "application/vnd.oci.descriptor.v1+json"
#define FLATPAK_OCI_MEDIA_TYPE_IMAGE_MANIFEST "application/vnd.oci.image.manifest.v1+json"
#define FLATPAK_DOCKER_MEDIA_TYPE_IMAGE_MANIFEST2 "application/vnd.docker.distribution.manifest.v2+json"
#define FLATPAK_OCI_MEDIA_TYPE_IMAGE_INDEX "application/vnd.oci.image.index.v1+json"
#define FLATPAK_OCI_MEDIA_TYPE_IMAGE_LAYER_GZIP "application/vnd.oci.image.layer.v1.tar+gzip"
#define FLATPAK_OCI_MEDIA_TYPE_IMAGE_LAYER_ZSTD "application/vnd.oci.image.layer.v1.tar+zstd"
#define FLATPAK_OCI_MEDIA_TYPE_IMAGE_CONFIG "application/vnd.oci.image.config.v1+json"
#define FLATPAK_DOCKER_MEDIA_TYPE_IMAGE_IMAGE_CONFIG "application/vnd.docker.container.image.v1+json"

#define FLATPAK_OCI_SIGNATURE_TYPE_FLATPAK "flatpak oci image signature"

const char * flatpak_arch_to_oci_arch (const char *flatpak_arch);
void flatpak_oci_export_labels (GHashTable *source,
                                GHashTable *dest);
void flatpak_oci_copy_labels (GHashTable *source,
                              GHashTable *dest);

typedef struct
{
  char       *mediatype;
  char       *digest;
  gint64      size;
  char      **urls;
  GHashTable *annotations;
} FlatpakOciDescriptor;

FlatpakOciDescriptor *flatpak_oci_descriptor_new (const char *mediatype,
                                                  const char *digest,
                                                  gint64      size);
void flatpak_oci_descriptor_copy (FlatpakOciDescriptor *source,
                                  FlatpakOciDescriptor *dest);
void flatpak_oci_descriptor_destroy (FlatpakOciDescriptor *self);
void flatpak_oci_descriptor_free (FlatpakOciDescriptor *self);

G_DEFINE_AUTOPTR_CLEANUP_FUNC (FlatpakOciDescriptor, flatpak_oci_descriptor_free)

typedef struct
{
  char  *architecture;
  char  *os;
  char  *os_version;
  char **os_features;
  char  *variant;
  char **features;
} FlatpakOciManifestPlatform;

typedef struct
{
  FlatpakOciDescriptor       parent;
  FlatpakOciManifestPlatform platform;
} FlatpakOciManifestDescriptor;

FlatpakOciManifestDescriptor * flatpak_oci_manifest_descriptor_new (void);
const char * flatpak_oci_manifest_descriptor_get_ref (FlatpakOciManifestDescriptor *m);
void flatpak_oci_manifest_descriptor_destroy (FlatpakOciManifestDescriptor *self);
void flatpak_oci_manifest_descriptor_free (FlatpakOciManifestDescriptor *self);


#define FLATPAK_TYPE_OCI_VERSIONED flatpak_oci_versioned_get_type ()
G_DECLARE_FINAL_TYPE (FlatpakOciVersioned, flatpak_oci_versioned, FLATPAK_OCI, VERSIONED, FlatpakJson)

struct _FlatpakOciVersioned
{
  FlatpakJson parent;

  int         version;
  char       *mediatype;
};

struct _FlatpakOciVersionedClass
{
  FlatpakJsonClass parent_class;
};

FlatpakOciVersioned *flatpak_oci_versioned_from_json (GBytes     *bytes,
                                                      const char *content_type,
                                                      GError    **error);
const char *         flatpak_oci_versioned_get_mediatype (FlatpakOciVersioned *self);
gint64               flatpak_oci_versioned_get_version (FlatpakOciVersioned *self);

#define FLATPAK_TYPE_OCI_MANIFEST flatpak_oci_manifest_get_type ()
G_DECLARE_FINAL_TYPE (FlatpakOciManifest, flatpak_oci_manifest, FLATPAK, OCI_MANIFEST, FlatpakOciVersioned)

struct _FlatpakOciManifest
{
  FlatpakOciVersioned    parent;

  FlatpakOciDescriptor   config;
  FlatpakOciDescriptor **layers;
  GHashTable            *annotations;
};

struct _FlatpakOciManifestClass
{
  FlatpakOciVersionedClass parent_class;
};


FlatpakOciManifest *flatpak_oci_manifest_new (void);
void                flatpak_oci_manifest_set_config (FlatpakOciManifest   *self,
                                                     FlatpakOciDescriptor *desc);
void                flatpak_oci_manifest_set_layers (FlatpakOciManifest    *self,
                                                     FlatpakOciDescriptor **descs);
void                flatpak_oci_manifest_set_layer (FlatpakOciManifest   *self,
                                                    FlatpakOciDescriptor *desc);
int                 flatpak_oci_manifest_get_n_layers (FlatpakOciManifest *self);
const char *        flatpak_oci_manifest_get_layer_digest (FlatpakOciManifest *self,
                                                           int                 i);
GHashTable *        flatpak_oci_manifest_get_annotations (FlatpakOciManifest *self);

/* Only useful for delta manifest */
FlatpakOciDescriptor *flatpak_oci_manifest_find_delta_for (FlatpakOciManifest *deltamanifest,
                                                           const char         *from_diffid,
                                                           const char         *to_diffid);


#define FLATPAK_TYPE_OCI_INDEX flatpak_oci_index_get_type ()
G_DECLARE_FINAL_TYPE (FlatpakOciIndex, flatpak_oci_index, FLATPAK, OCI_INDEX, FlatpakOciVersioned)

struct _FlatpakOciIndex
{
  FlatpakOciVersioned            parent;

  FlatpakOciManifestDescriptor **manifests;
  GHashTable                    *annotations;
};

struct _FlatpakOciIndexClass
{
  FlatpakOciVersionedClass parent_class;
};

FlatpakOciIndex *             flatpak_oci_index_new (void);
void                          flatpak_oci_index_add_manifest (FlatpakOciIndex      *self,
                                                              const char           *ref,
                                                              FlatpakOciDescriptor *desc);
gboolean                      flatpak_oci_index_remove_manifest (FlatpakOciIndex *self,
                                                                 const char      *ref);
FlatpakOciManifestDescriptor *flatpak_oci_index_get_manifest (FlatpakOciIndex *self,
                                                              const char      *ref);
FlatpakOciManifestDescriptor *flatpak_oci_index_get_only_manifest (FlatpakOciIndex *self);
FlatpakOciManifestDescriptor *flatpak_oci_index_get_manifest_for_arch (FlatpakOciIndex *self,
                                                                       const char      *oci_arch);

int                           flatpak_oci_index_get_n_manifests (FlatpakOciIndex *self);
/* Only useful for delta index */
FlatpakOciDescriptor *flatpak_oci_index_find_delta_for (FlatpakOciIndex *delta_index,
                                                        const char      *for_digest);


#define FLATPAK_TYPE_OCI_IMAGE flatpak_oci_image_get_type ()
G_DECLARE_FINAL_TYPE (FlatpakOciImage, flatpak_oci_image, FLATPAK, OCI_IMAGE, FlatpakJson)

typedef struct
{
  char  *type;
  char **diff_ids;
} FlatpakOciImageRootfs;

typedef struct
{
  char       *user;
  char       *working_dir;
  gint64      memory;
  gint64      memory_swap;
  gint64      cpu_shares;
  char      **env;
  char      **cmd;
  char      **entrypoint;
  char      **exposed_ports;
  char      **volumes;
  GHashTable *labels;
} FlatpakOciImageConfig;

typedef struct
{
  char    *created;
  char    *created_by;
  char    *author;
  char    *comment;
  gboolean empty_layer;
} FlatpakOciImageHistory;

struct _FlatpakOciImage
{
  FlatpakJson              parent;

  char                    *created;
  char                    *author;
  char                    *architecture;
  char                    *os;
  FlatpakOciImageRootfs    rootfs;
  FlatpakOciImageConfig    config;
  FlatpakOciImageHistory **history;
};

struct _FlatpakOciImageClass
{
  FlatpakJsonClass parent_class;
};

FlatpakOciImage *flatpak_oci_image_new (void);
void             flatpak_oci_image_set_created (FlatpakOciImage *image,
                                                const char      *created);
void             flatpak_oci_image_set_architecture (FlatpakOciImage *image,
                                                     const char      *arch);
void             flatpak_oci_image_set_os (FlatpakOciImage *image,
                                           const char      *os);
void             flatpak_oci_image_set_layers (FlatpakOciImage *image,
                                               const char     **layers);
int              flatpak_oci_image_get_n_layers (FlatpakOciImage *image);
void             flatpak_oci_image_set_layer (FlatpakOciImage *image,
                                              const char      *layer);
GHashTable *     flatpak_oci_image_get_labels (FlatpakOciImage *self);
int              flatpak_oci_image_add_history (FlatpakOciImage *image);

FlatpakOciImage * flatpak_oci_image_from_json (GBytes *bytes,
                                               GError **error);

void flatpak_oci_add_labels_for_commit (GHashTable *labels,
                                        const char *ref,
                                        const char *commit,
                                        GVariant   *commit_data);

/* FlatpakOciSignature is a "simple signature" as defined:
 * https://github.com/containers/image/blob/main/docs/containers-signature.5.md
 */

#define FLATPAK_TYPE_OCI_SIGNATURE flatpak_oci_signature_get_type ()
G_DECLARE_FINAL_TYPE (FlatpakOciSignature, flatpak_oci_signature, FLATPAK, OCI_SIGNATURE, FlatpakJson)

typedef struct
{
  char *digest;
} FlatpakOciSignatureCriticalImage;

typedef struct
{
  char *reference;
} FlatpakOciSignatureCriticalIdentity;

typedef struct
{
  char                               *type;
  FlatpakOciSignatureCriticalImage    image;
  FlatpakOciSignatureCriticalIdentity identity;
} FlatpakOciSignatureCritical;

typedef struct
{
  char  *creator;
  gint64 timestamp;
} FlatpakOciSignatureOptional;

struct _FlatpakOciSignature
{
  FlatpakJson                 parent;

  FlatpakOciSignatureCritical critical;
  FlatpakOciSignatureOptional optional;
};

struct _FlatpakOciSignatureClass
{
  FlatpakJsonClass parent_class;
};


#define FLATPAK_TYPE_OCI_INDEX_RESPONSE flatpak_oci_index_response_get_type ()
G_DECLARE_FINAL_TYPE (FlatpakOciIndexResponse, flatpak_oci_index_response, FLATPAK, OCI_INDEX_RESPONSE, FlatpakJson)

typedef struct
{
  char       *digest;
  char       *mediatype;
  char       *os;
  char       *architecture;
  GHashTable *annotations;
  GHashTable *labels;
  char      **tags;
} FlatpakOciIndexImage;

typedef struct
{
  char                  *digest;
  char                  *mediatype;
  char                 **tags;
  FlatpakOciIndexImage **images;
} FlatpakOciIndexImageList;

typedef struct
{
  char                      *name;
  FlatpakOciIndexImage     **images;
  FlatpakOciIndexImageList **lists;
} FlatpakOciIndexRepository;

struct _FlatpakOciIndexResponse
{
  FlatpakJson                 parent;

  char                       *registry;
  FlatpakOciIndexRepository **results;
};

struct _FlatpakOciIndexResponseClass
{
  FlatpakJsonClass parent_class;
};

#endif /* __FLATPAK_JSON_OCI_H__ */

===== ./common/flatpak-repo-utils.c =====
/* vi:set et sw=2 sts=2 cin cino=t0,f0,(0,{s,>2s,n-s,^-s,e-s:
 * Copyright © 1995-1998 Free Software Foundation, Inc.
 * Copyright © 2014-2019 Red Hat, Inc
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Alexander Larsson <alexl@redhat.com>
 */

#include "config.h"
#include "flatpak-repo-utils-private.h"

#include <gio/gunixinputstream.h>

#include <glib/gi18n-lib.h>

#include "flatpak-utils-private.h"
#include "flatpak-variant-private.h"
#include "flatpak-variant-impl-private.h"
#include "flatpak-xml-utils-private.h"

gboolean
flatpak_repo_set_title (OstreeRepo *repo,
                        const char *title,
                        GError    **error)
{
  g_autoptr(GKeyFile) config = NULL;

  config = ostree_repo_copy_config (repo);

  if (title)
    g_key_file_set_string (config, "flatpak", "title", title);
  else
    g_key_file_remove_key (config, "flatpak", "title", NULL);

  if (!ostree_repo_write_config (repo, config, error))
    return FALSE;

  return TRUE;
}

gboolean
flatpak_repo_set_comment (OstreeRepo *repo,
                          const char *comment,
                          GError    **error)
{
  g_autoptr(GKeyFile) config = NULL;

  config = ostree_repo_copy_config (repo);

  if (comment)
    g_key_file_set_string (config, "flatpak", "comment", comment);
  else
    g_key_file_remove_key (config, "flatpak", "comment", NULL);

  if (!ostree_repo_write_config (repo, config, error))
    return FALSE;

  return TRUE;
}

gboolean
flatpak_repo_set_description (OstreeRepo *repo,
                              const char *description,
                              GError    **error)
{
  g_autoptr(GKeyFile) config = NULL;

  config = ostree_repo_copy_config (repo);

  if (description)
    g_key_file_set_string (config, "flatpak", "description", description);
  else
    g_key_file_remove_key (config, "flatpak", "description", NULL);

  if (!ostree_repo_write_config (repo, config, error))
    return FALSE;

  return TRUE;
}


gboolean
flatpak_repo_set_icon (OstreeRepo *repo,
                       const char *icon,
                       GError    **error)
{
  g_autoptr(GKeyFile) config = NULL;

  config = ostree_repo_copy_config (repo);

  if (icon)
    g_key_file_set_string (config, "flatpak", "icon", icon);
  else
    g_key_file_remove_key (config, "flatpak", "icon", NULL);

  if (!ostree_repo_write_config (repo, config, error))
    return FALSE;

  return TRUE;
}

gboolean
flatpak_repo_set_homepage (OstreeRepo *repo,
                           const char *homepage,
                           GError    **error)
{
  g_autoptr(GKeyFile) config = NULL;

  config = ostree_repo_copy_config (repo);

  if (homepage)
    g_key_file_set_string (config, "flatpak", "homepage", homepage);
  else
    g_key_file_remove_key (config, "flatpak", "homepage", NULL);

  if (!ostree_repo_write_config (repo, config, error))
    return FALSE;

  return TRUE;
}

gboolean
flatpak_repo_set_redirect_url (OstreeRepo *repo,
                               const char *redirect_url,
                               GError    **error)
{
  g_autoptr(GKeyFile) config = NULL;

  config = ostree_repo_copy_config (repo);

  if (redirect_url)
    g_key_file_set_string (config, "flatpak", "redirect-url", redirect_url);
  else
    g_key_file_remove_key (config, "flatpak", "redirect-url", NULL);

  if (!ostree_repo_write_config (repo, config, error))
    return FALSE;

  return TRUE;
}

gboolean
flatpak_repo_set_authenticator_name (OstreeRepo *repo,
                                     const char *authenticator_name,
                                     GError    **error)
{
  g_autoptr(GKeyFile) config = NULL;

  config = ostree_repo_copy_config (repo);

  if (authenticator_name)
    g_key_file_set_string (config, "flatpak", "authenticator-name", authenticator_name);
  else
    g_key_file_remove_key (config, "flatpak", "authenticator-name", NULL);

  if (!ostree_repo_write_config (repo, config, error))
    return FALSE;

  return TRUE;
}

gboolean
flatpak_repo_set_authenticator_install (OstreeRepo *repo,
                                        gboolean authenticator_install,
                                        GError    **error)
{
  g_autoptr(GKeyFile) config = NULL;

  config = ostree_repo_copy_config (repo);

  g_key_file_set_boolean (config, "flatpak", "authenticator-install", authenticator_install);

  if (!ostree_repo_write_config (repo, config, error))
    return FALSE;

  return TRUE;
}

gboolean
flatpak_repo_set_authenticator_option (OstreeRepo *repo,
                                       const char *key,
                                       const char *value,
                                       GError    **error)
{
  g_autoptr(GKeyFile) config = NULL;
  g_autofree char *full_key = g_strdup_printf ("authenticator-options.%s", key);

  config = ostree_repo_copy_config (repo);

  if (value)
    g_key_file_set_string (config, "flatpak", full_key, value);
  else
    g_key_file_remove_key (config, "flatpak", full_key, NULL);

  if (!ostree_repo_write_config (repo, config, error))
    return FALSE;

  return TRUE;
}

gboolean
flatpak_repo_set_deploy_collection_id (OstreeRepo *repo,
                                       gboolean    deploy_collection_id,
                                       GError    **error)
{
  g_autoptr(GKeyFile) config = NULL;

  config = ostree_repo_copy_config (repo);
  g_key_file_set_boolean (config, "flatpak", "deploy-collection-id", deploy_collection_id);
  return ostree_repo_write_config (repo, config, error);
}

gboolean
flatpak_repo_set_deploy_sideload_collection_id (OstreeRepo *repo,
                                           gboolean    deploy_collection_id,
                                           GError    **error)
{
  g_autoptr(GKeyFile) config = NULL;

  config = ostree_repo_copy_config (repo);
  g_key_file_set_boolean (config, "flatpak", "deploy-sideload-collection-id", deploy_collection_id);
  return ostree_repo_write_config (repo, config, error);
}

gboolean
flatpak_repo_set_gpg_keys (OstreeRepo *repo,
                           GBytes     *bytes,
                           GError    **error)
{
  g_autoptr(GKeyFile) config = NULL;
  g_autofree char *value_base64 = NULL;

  config = ostree_repo_copy_config (repo);

  value_base64 = g_base64_encode (g_bytes_get_data (bytes, NULL), g_bytes_get_size (bytes));

  g_key_file_set_string (config, "flatpak", "gpg-keys", value_base64);

  if (!ostree_repo_write_config (repo, config, error))
    return FALSE;

  return TRUE;
}

gboolean
flatpak_repo_set_default_branch (OstreeRepo *repo,
                                 const char *branch,
                                 GError    **error)
{
  g_autoptr(GKeyFile) config = NULL;

  config = ostree_repo_copy_config (repo);

  if (branch)
    g_key_file_set_string (config, "flatpak", "default-branch", branch);
  else
    g_key_file_remove_key (config, "flatpak", "default-branch", NULL);

  if (!ostree_repo_write_config (repo, config, error))
    return FALSE;

  return TRUE;
}

gboolean
flatpak_repo_set_collection_id (OstreeRepo *repo,
                                const char *collection_id,
                                GError    **error)
{
  g_autoptr(GKeyFile) config = NULL;

  if (!ostree_repo_set_collection_id (repo, collection_id, error))
    return FALSE;

  config = ostree_repo_copy_config (repo);
  if (!ostree_repo_write_config (repo, config, error))
    return FALSE;

  return TRUE;
}

gboolean
flatpak_repo_set_summary_history_length (OstreeRepo *repo,
                                         guint       length,
                                         GError    **error)
{
  g_autoptr(GKeyFile) config = NULL;

  config = ostree_repo_copy_config (repo);

  if (length)
    g_key_file_set_integer (config, "flatpak", "summary-history-length", length);
  else
    g_key_file_remove_key (config, "flatpak", "summary-history-length", NULL);

  if (!ostree_repo_write_config (repo, config, error))
    return FALSE;

  return TRUE;
}

guint
flatpak_repo_get_summary_history_length (OstreeRepo *repo)
{
  GKeyFile *config = ostree_repo_get_config (repo);
  int length;

  length = g_key_file_get_integer (config, "flatpak", "sumary-history-length", NULL);

  if (length <= 0)
    return FLATPAK_SUMMARY_HISTORY_LENGTH_DEFAULT;

  return length;
}

GVariant *
flatpak_commit_get_extra_data_sources (GVariant *commitv,
                                       GError  **error)
{
  g_autoptr(GVariant) commit_metadata = NULL;
  g_autoptr(GVariant) extra_data_sources = NULL;

  commit_metadata = g_variant_get_child_value (commitv, 0);
  extra_data_sources = g_variant_lookup_value (commit_metadata,
                                               "xa.extra-data-sources",
                                               G_VARIANT_TYPE ("a(ayttays)"));

  if (extra_data_sources == NULL)
    {
      g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND,
                   _("No extra data sources"));
      return NULL;
    }

  return g_steal_pointer (&extra_data_sources);
}

GVariant *
flatpak_repo_get_extra_data_sources (OstreeRepo   *repo,
                                     const char   *rev,
                                     GCancellable *cancellable,
                                     GError      **error)
{
  g_autoptr(GVariant) commitv = NULL;

  if (!ostree_repo_load_variant (repo,
                                 OSTREE_OBJECT_TYPE_COMMIT,
                                 rev, &commitv, error))
    return NULL;

  return flatpak_commit_get_extra_data_sources (commitv, error);
}

void
flatpak_repo_parse_extra_data_sources (GVariant      *extra_data_sources,
                                       int            index,
                                       const char   **name,
                                       guint64       *download_size,
                                       guint64       *installed_size,
                                       const guchar **sha256,
                                       const char   **uri)
{
  g_autoptr(GVariant) sha256_v = NULL;
  g_variant_get_child (extra_data_sources, index, "(^&aytt@ay&s)",
                       name,
                       download_size,
                       installed_size,
                       &sha256_v,
                       uri);

  if (download_size)
    *download_size = GUINT64_FROM_BE (*download_size);

  if (installed_size)
    *installed_size = GUINT64_FROM_BE (*installed_size);

  if (sha256)
    *sha256 = ostree_checksum_bytes_peek (sha256_v);
}

#define OSTREE_GIO_FAST_QUERYINFO ("standard::name,standard::type,standard::size,standard::is-symlink,standard::symlink-target," \
                                   "unix::device,unix::inode,unix::mode,unix::uid,unix::gid,unix::rdev")

static gboolean
_flatpak_repo_collect_sizes (OstreeRepo   *repo,
                             GFile        *file,
                             GFileInfo    *file_info,
                             guint64      *installed_size,
                             guint64      *download_size,
                             GCancellable *cancellable,
                             GError      **error)
{
  g_autoptr(GFileEnumerator) dir_enum = NULL;
  GFileInfo *child_info_tmp;
  g_autoptr(GError) temp_error = NULL;

  if (file_info != NULL && g_file_info_get_file_type (file_info) == G_FILE_TYPE_REGULAR)
    {
      const char *checksum = ostree_repo_file_get_checksum (OSTREE_REPO_FILE (file));
      guint64 obj_size;
      guint64 file_size = g_file_info_get_size (file_info);

      if (installed_size)
        *installed_size += ((file_size + 511) / 512) * 512;

      if (download_size)
        {
          g_autoptr(GInputStream) input = NULL;
          GInputStream *base_input;
          g_autoptr(GError) local_error = NULL;

          if (!ostree_repo_query_object_storage_size (repo,
                                                      OSTREE_OBJECT_TYPE_FILE, checksum,
                                                      &obj_size, cancellable, &local_error))
            {
              int fd;
              struct stat stbuf;

              /* Ostree does not look at the staging directory when querying storage
                 size, so may return a NOT_FOUND error here. We work around this
                 by loading the object and walking back until we find the original
                 fd which we can fstat(). */
              if (!g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
                return FALSE;

              if (!ostree_repo_load_file (repo, checksum,  &input, NULL, NULL, NULL, error))
                return FALSE;

              base_input = input;
              while (G_IS_FILTER_INPUT_STREAM (base_input))
                base_input = g_filter_input_stream_get_base_stream (G_FILTER_INPUT_STREAM (base_input));

              if (!G_IS_UNIX_INPUT_STREAM (base_input))
                return flatpak_fail (error, "Unable to find size of commit %s, not an unix stream", checksum);

              fd = g_unix_input_stream_get_fd (G_UNIX_INPUT_STREAM (base_input));

              if (fstat (fd, &stbuf) != 0)
                return glnx_throw_errno_prefix (error, "Can't find commit size: ");

              obj_size = stbuf.st_size;
            }

          *download_size += obj_size;
        }
    }

  if (file_info == NULL || g_file_info_get_file_type (file_info) == G_FILE_TYPE_DIRECTORY)
    {
      dir_enum = g_file_enumerate_children (file, OSTREE_GIO_FAST_QUERYINFO,
                                            G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
                                            cancellable, error);
      if (!dir_enum)
        return FALSE;


      while ((child_info_tmp = g_file_enumerator_next_file (dir_enum, cancellable, &temp_error)))
        {
          g_autoptr(GFileInfo) child_info = child_info_tmp;
          const char *name = g_file_info_get_name (child_info);
          g_autoptr(GFile) child = g_file_get_child (file, name);

          if (!_flatpak_repo_collect_sizes (repo, child, child_info, installed_size, download_size, cancellable, error))
            return FALSE;
        }
    }

  return TRUE;
}

gboolean
flatpak_repo_collect_sizes (OstreeRepo   *repo,
                            GFile        *root,
                            guint64      *installed_size,
                            guint64      *download_size,
                            GCancellable *cancellable,
                            GError      **error)
{
  /* Initialize the sums */
  if (installed_size)
    *installed_size = 0;
  if (download_size)
    *download_size = 0;
  return _flatpak_repo_collect_sizes (repo, root, NULL, installed_size, download_size, cancellable, error);
}

static void
flatpak_repo_collect_extra_data_sizes (OstreeRepo *repo,
                                       const char *rev,
                                       guint64    *installed_size,
                                       guint64    *download_size)
{
  g_autoptr(GVariant) extra_data_sources = NULL;
  gsize n_extra_data;
  int i;

  extra_data_sources = flatpak_repo_get_extra_data_sources (repo, rev, NULL, NULL);
  if (extra_data_sources == NULL)
    return;

  n_extra_data = g_variant_n_children (extra_data_sources);
  if (n_extra_data == 0)
    return;

  for (i = 0; i < n_extra_data; i++)
    {
      guint64 extra_download_size;
      guint64 extra_installed_size;

      flatpak_repo_parse_extra_data_sources (extra_data_sources, i,
                                             NULL,
                                             &extra_download_size,
                                             &extra_installed_size,
                                             NULL, NULL);
      if (installed_size)
        *installed_size += extra_installed_size;
      if (download_size)
        *download_size += extra_download_size;
    }
}

/* Loads the old compat summary file from a local repo */
GVariant *
flatpak_repo_load_summary (OstreeRepo *repo,
                           GError    **error)
{
  glnx_autofd int fd = -1;
  g_autoptr(GMappedFile) mfile = NULL;
  g_autoptr(GBytes) bytes = NULL;

  fd = openat (ostree_repo_get_dfd (repo), "summary", O_RDONLY | O_CLOEXEC);
  if (fd < 0)
    {
      glnx_set_error_from_errno (error);
      return NULL;
    }

  mfile = g_mapped_file_new_from_fd (fd, FALSE, error);
  if (!mfile)
    return NULL;

  bytes = g_mapped_file_get_bytes (mfile);

  return g_variant_ref_sink (g_variant_new_from_bytes (OSTREE_SUMMARY_GVARIANT_FORMAT, bytes, TRUE));
}

GVariant *
flatpak_repo_load_summary_index (OstreeRepo *repo,
                                 GError    **error)
{
  glnx_autofd int fd = -1;
  g_autoptr(GMappedFile) mfile = NULL;
  g_autoptr(GBytes) bytes = NULL;

  fd = openat (ostree_repo_get_dfd (repo), "summary.idx", O_RDONLY | O_CLOEXEC);
  if (fd < 0)
    {
      glnx_set_error_from_errno (error);
      return NULL;
    }

  mfile = g_mapped_file_new_from_fd (fd, FALSE, error);
  if (!mfile)
    return NULL;

  bytes = g_mapped_file_get_bytes (mfile);

  return g_variant_ref_sink (g_variant_new_from_bytes (FLATPAK_SUMMARY_INDEX_GVARIANT_FORMAT, bytes, TRUE));
}

static gboolean
flatpak_repo_save_compat_summary (OstreeRepo   *repo,
                                  GVariant     *summary,
                                  time_t       *out_old_sig_mtime,
                                  GCancellable *cancellable,
                                  GError      **error)
{
  int repo_dfd = ostree_repo_get_dfd (repo);
  struct stat stbuf;
  time_t old_sig_mtime = 0;
  GLnxFileReplaceFlags flags;

  flags = GLNX_FILE_REPLACE_INCREASING_MTIME;
  if (ostree_repo_get_disable_fsync (repo))
    flags |= GLNX_FILE_REPLACE_NODATASYNC;
  else
    flags |= GLNX_FILE_REPLACE_DATASYNC_NEW;

  if (!glnx_file_replace_contents_at (repo_dfd, "summary",
                                      g_variant_get_data (summary),
                                      g_variant_get_size (summary),
                                      flags,
                                      cancellable, error))
    return FALSE;

  if (fstatat (repo_dfd, "summary.sig", &stbuf, AT_SYMLINK_NOFOLLOW) == 0)
    old_sig_mtime = stbuf.st_mtime;

  if (unlinkat (repo_dfd, "summary.sig", 0) != 0 &&
      G_UNLIKELY (errno != ENOENT))
    {
      glnx_set_error_from_errno (error);
      return FALSE;
    }

  *out_old_sig_mtime = old_sig_mtime;
  return TRUE;
}

static gboolean
flatpak_repo_save_summary_index (OstreeRepo   *repo,
                                 GVariant     *index,
                                 const char   *index_digest,
                                 GBytes       *index_sig,
                                 GCancellable *cancellable,
                                 GError      **error)
{
  int repo_dfd = ostree_repo_get_dfd (repo);
  GLnxFileReplaceFlags  flags;

  if (index == NULL)
    {
      if (unlinkat (repo_dfd, "summary.idx", 0) != 0 &&
          G_UNLIKELY (errno != ENOENT))
        {
          glnx_set_error_from_errno (error);
          return FALSE;
        }
      if (unlinkat (repo_dfd, "summary.idx.sig", 0) != 0 &&
          G_UNLIKELY (errno != ENOENT))
        {
          glnx_set_error_from_errno (error);
          return FALSE;
        }

      return TRUE;
    }

  flags = GLNX_FILE_REPLACE_INCREASING_MTIME;
  if (ostree_repo_get_disable_fsync (repo))
    flags |= GLNX_FILE_REPLACE_NODATASYNC;
  else
    flags |= GLNX_FILE_REPLACE_DATASYNC_NEW;

  if (index_sig)
    {
      g_autofree char *path = g_strconcat ("summaries/", index_digest, ".idx.sig", NULL);

      if (!glnx_shutil_mkdir_p_at (repo_dfd, "summaries",
                                   0775, cancellable, error))
        return FALSE;

      if (!glnx_file_replace_contents_at (repo_dfd, path,
                                          g_bytes_get_data (index_sig, NULL),
                                          g_bytes_get_size (index_sig),
                                          flags,
                                          cancellable, error))
        return FALSE;
    }

  if (!glnx_file_replace_contents_at (repo_dfd, "summary.idx",
                                      g_variant_get_data (index),
                                      g_variant_get_size (index),
                                      flags,
                                      cancellable, error))
    return FALSE;

  /* Update the non-indexed summary.idx.sig file that was introduced in 1.9.1 but
   * was made unnecessary in 1.9.3. Lets keep it for a while until everyone updates
   */
  if (index_sig)
    {
      if (!glnx_file_replace_contents_at (repo_dfd, "summary.idx.sig",
                                          g_bytes_get_data (index_sig, NULL),
                                          g_bytes_get_size (index_sig),
                                          flags,
                                          cancellable, error))
        return FALSE;
    }
  else
    {
      if (unlinkat (repo_dfd, "summary.idx.sig", 0) != 0 &&
          G_UNLIKELY (errno != ENOENT))
        {
          glnx_set_error_from_errno (error);
          return FALSE;
        }
    }

  return TRUE;
}

GVariant *
flatpak_repo_load_digested_summary (OstreeRepo *repo,
                                   const char *digest,
                                   GError    **error)
{
  glnx_autofd int fd = -1;
  g_autoptr(GMappedFile) mfile = NULL;
  g_autoptr(GBytes) bytes = NULL;
  g_autoptr(GBytes) compressed_bytes = NULL;
  g_autofree char *path = NULL;
  g_autofree char *filename = NULL;

  filename = g_strconcat (digest, ".gz", NULL);
  path = g_build_filename ("summaries", filename, NULL);

  fd = openat (ostree_repo_get_dfd (repo), path, O_RDONLY | O_CLOEXEC);
  if (fd < 0)
    {
      glnx_set_error_from_errno (error);
      return NULL;
    }

  mfile = g_mapped_file_new_from_fd (fd, FALSE, error);
  if (!mfile)
    return NULL;

  compressed_bytes = g_mapped_file_get_bytes (mfile);
  bytes = flatpak_zlib_decompress_bytes (compressed_bytes, error);
  if (bytes == NULL)
    return NULL;

  return g_variant_ref_sink (g_variant_new_from_bytes (OSTREE_SUMMARY_GVARIANT_FORMAT, bytes, TRUE));
}

static char *
flatpak_repo_save_digested_summary (OstreeRepo   *repo,
                                    const char   *name,
                                    GVariant     *summary,
                                    GCancellable *cancellable,
                                    GError      **error)
{
  int repo_dfd = ostree_repo_get_dfd (repo);
  g_autofree char *digest = NULL;
  g_autofree char *filename = NULL;
  g_autofree char *path = NULL;
  g_autoptr(GBytes) data = NULL;
  g_autoptr(GBytes) compressed_data = NULL;
  struct stat stbuf;

  if (!glnx_shutil_mkdir_p_at (repo_dfd, "summaries",
                               0775,
                               cancellable,
                               error))
    return NULL;

  digest = g_compute_checksum_for_data (G_CHECKSUM_SHA256,
                                        g_variant_get_data (summary),
                                        g_variant_get_size (summary));
  filename = g_strconcat (digest, ".gz", NULL);

  path = g_build_filename ("summaries", filename, NULL);

  /* Check for pre-existing (non-truncated) copy and avoid re-writing it */
  if (fstatat (repo_dfd, path, &stbuf, 0) == 0 &&
      stbuf.st_size != 0)
    {
      g_info ("Reusing digested summary at %s for %s", path, name);
      return g_steal_pointer (&digest);
    }

  data = g_variant_get_data_as_bytes (summary);
  compressed_data = flatpak_zlib_compress_bytes (data, -1, error);
  if (compressed_data == NULL)
    return NULL;

  if (!glnx_file_replace_contents_at (repo_dfd, path,
                                      g_bytes_get_data (compressed_data, NULL),
                                      g_bytes_get_size (compressed_data),
                                      ostree_repo_get_disable_fsync (repo) ? GLNX_FILE_REPLACE_NODATASYNC : GLNX_FILE_REPLACE_DATASYNC_NEW,
                                      cancellable, error))
    return NULL;

  g_info ("Wrote digested summary at %s for %s", path, name);
  return g_steal_pointer (&digest);
}

static gboolean
flatpak_repo_save_digested_summary_delta (OstreeRepo   *repo,
                                          const char   *from_digest,
                                          const char   *to_digest,
                                          GBytes       *delta,
                                          GCancellable *cancellable,
                                          GError      **error)
{
  int repo_dfd = ostree_repo_get_dfd (repo);
  g_autofree char *path = NULL;
  g_autofree char *filename = g_strconcat (from_digest, "-", to_digest, ".delta", NULL);
  struct stat stbuf;

  if (!glnx_shutil_mkdir_p_at (repo_dfd, "summaries",
                               0775,
                               cancellable,
                               error))
    return FALSE;

  path = g_build_filename ("summaries", filename, NULL);

  /* Check for pre-existing copy of same size and avoid re-writing it */
  if (fstatat (repo_dfd, path, &stbuf, 0) == 0 &&
      stbuf.st_size == g_bytes_get_size (delta))
    {
      g_info ("Reusing digested summary-diff for %s", filename);
      return TRUE;
    }

  if (!glnx_file_replace_contents_at (repo_dfd, path,
                                      g_bytes_get_data (delta, NULL),
                                      g_bytes_get_size (delta),
                                      ostree_repo_get_disable_fsync (repo) ? GLNX_FILE_REPLACE_NODATASYNC : GLNX_FILE_REPLACE_DATASYNC_NEW,
                                      cancellable, error))
    return FALSE;

  g_info ("Wrote digested summary delta at %s", path);
  return TRUE;
}

typedef struct
{
  guint64    installed_size;
  guint64    download_size;
  char      *metadata_contents;
  GPtrArray *subsets;
  GVariant  *sparse_data;
  gsize      commit_size;
  guint64    commit_timestamp;
} CommitData;

static void
commit_data_free (gpointer data)
{
  CommitData *rev_data = data;

  if (rev_data->subsets)
    g_ptr_array_unref (rev_data->subsets);
  g_free (rev_data->metadata_contents);
  if (rev_data->sparse_data)
    g_variant_unref (rev_data->sparse_data);
  g_free (rev_data);
}

G_DEFINE_AUTOPTR_CLEANUP_FUNC (CommitData, commit_data_free);

static GHashTable *
commit_data_cache_new (void)
{
  return g_hash_table_new_full (g_str_hash, g_str_equal, g_free, commit_data_free);
}

static GHashTable *
populate_commit_data_cache (OstreeRepo *repo,
                            GVariant *index_v)
{

  VarSummaryIndexRef index = var_summary_index_from_gvariant (index_v);
  VarMetadataRef index_metadata = var_summary_index_get_metadata (index);
  VarSummaryIndexSubsummariesRef subsummaries = var_summary_index_get_subsummaries (index);
  gsize n_subsummaries = var_summary_index_subsummaries_get_length (subsummaries);
  guint32 cache_version;
  g_autoptr(GHashTable) commit_data_cache = commit_data_cache_new ();

  cache_version = GUINT32_FROM_LE (var_metadata_lookup_uint32 (index_metadata, "xa.cache-version", 0));
  if (cache_version < FLATPAK_XA_CACHE_VERSION)
    {
      /* Need to re-index to get all data */
      g_info ("Old summary cache version %d, not using cache", cache_version);
      return NULL;
    }

  for (gsize i = 0; i < n_subsummaries; i++)
    {
      VarSummaryIndexSubsummariesEntryRef entry = var_summary_index_subsummaries_get_at (subsummaries, i);
      const char *name = var_summary_index_subsummaries_entry_get_key (entry);
      const char *s;
      g_autofree char *subset = NULL;
      VarSubsummaryRef subsummary = var_summary_index_subsummaries_entry_get_value (entry);
      gsize checksum_bytes_len;
      const guchar *checksum_bytes;
      g_autofree char *digest = NULL;
      g_autoptr(GVariant) summary_v = NULL;
      VarSummaryRef summary;
      VarRefMapRef ref_map;
      gsize n_refs;

      checksum_bytes = var_subsummary_peek_checksum (subsummary, &checksum_bytes_len);
      if (G_UNLIKELY (checksum_bytes_len != OSTREE_SHA256_DIGEST_LEN))
        {
          g_info ("Invalid checksum for digested summary, not using cache");
          return NULL;
        }
      digest = ostree_checksum_from_bytes (checksum_bytes);

      s = strrchr (name, '-');
      if (s != NULL)
        subset = g_strndup (name, s - name);
      else
        subset = g_strdup ("");

      summary_v = flatpak_repo_load_digested_summary (repo, digest, NULL);
      if (summary_v == NULL)
        {
          g_info ("Failed to load digested summary %s, not using cache", digest);
          return NULL;
        }

      /* Note that all summaries referred to by the index is in new format */
      summary = var_summary_from_gvariant (summary_v);
      ref_map = var_summary_get_ref_map (summary);
      n_refs = var_ref_map_get_length (ref_map);
      for (gsize j = 0; j < n_refs; j++)
        {
          VarRefMapEntryRef e = var_ref_map_get_at (ref_map, j);
          const char *ref = var_ref_map_entry_get_ref (e);
          VarRefInfoRef info = var_ref_map_entry_get_info (e);
          VarMetadataRef commit_metadata = var_ref_info_get_metadata (info);
          guint64 commit_size = var_ref_info_get_commit_size (info);
          const guchar *commit_bytes;
          gsize commit_bytes_len;
          g_autofree char *rev = NULL;
          CommitData *rev_data;
          VarVariantRef xa_data_v;
          VarCacheDataRef xa_data;

          if (!flatpak_is_app_runtime_or_appstream_ref (ref))
            continue;

          commit_bytes = var_ref_info_peek_checksum (info, &commit_bytes_len);
          if (G_UNLIKELY (commit_bytes_len != OSTREE_SHA256_DIGEST_LEN))
            continue;

          if (!var_metadata_lookup (commit_metadata, "xa.data", NULL, &xa_data_v) ||
              !var_variant_is_type (xa_data_v, G_VARIANT_TYPE ("(tts)")))
            {
              g_info ("Missing xa.data for ref %s, not using cache", ref);
              return NULL;
            }

          xa_data = var_cache_data_from_variant (xa_data_v);

          rev = ostree_checksum_from_bytes (commit_bytes);
          rev_data = g_hash_table_lookup (commit_data_cache, rev);
          if (rev_data == NULL)
            {
              g_auto(GVariantBuilder) sparse_builder = FLATPAK_VARIANT_BUILDER_INITIALIZER;
              g_variant_builder_init (&sparse_builder, G_VARIANT_TYPE_VARDICT);
              gboolean has_sparse = FALSE;

              rev_data = g_new0 (CommitData, 1);
              rev_data->installed_size = var_cache_data_get_installed_size (xa_data);
              rev_data->download_size = var_cache_data_get_download_size (xa_data);
              rev_data->metadata_contents = g_strdup (var_cache_data_get_metadata (xa_data));
              rev_data->commit_size = commit_size;
              rev_data->commit_timestamp = GUINT64_FROM_BE (var_metadata_lookup_uint64 (commit_metadata, OSTREE_COMMIT_TIMESTAMP2, 0));

              /* Get sparse data */
              gsize len = var_metadata_get_length (commit_metadata);
              for (gsize k = 0; k < len; k++)
                {
                  VarMetadataEntryRef m = var_metadata_get_at (commit_metadata, k);
                  const char *m_key = var_metadata_entry_get_key (m);
                  if (!g_str_has_prefix (m_key, "ot.") &&
                      !g_str_has_prefix (m_key, "ostree.") &&
                      strcmp (m_key, "xa.data") != 0)
                    {
                      VarVariantRef v = var_metadata_entry_get_value (m);
                      g_autoptr(GVariant) vv = g_variant_ref_sink (var_variant_dup_to_gvariant (v));
                      g_autoptr(GVariant) child = g_variant_get_child_value (vv, 0);
                      g_variant_builder_add (&sparse_builder, "{sv}", m_key, child);
                      has_sparse = TRUE;
                    }
                }

              if (has_sparse)
                rev_data->sparse_data = g_variant_ref_sink (g_variant_builder_end (&sparse_builder));

              g_hash_table_insert (commit_data_cache, g_strdup (rev), (CommitData *)rev_data);
            }

          if (*subset != 0)
            {
              if (rev_data->subsets == NULL)
                rev_data->subsets = g_ptr_array_new_with_free_func (g_free);

              if (!flatpak_g_ptr_array_contains_string (rev_data->subsets, subset))
                g_ptr_array_add (rev_data->subsets, g_strdup (subset));
            }
        }
    }

  return g_steal_pointer (&commit_data_cache);
}

static CommitData *
read_commit_data (OstreeRepo   *repo,
                  const char   *ref,
                  const char   *rev,
                  GCancellable *cancellable,
                  GError      **error)
{
  g_autoptr(GFile) root = NULL;
  g_autoptr(GFile) metadata = NULL;
  guint64 installed_size = 0;
  guint64 download_size = 0;
  g_autofree char *metadata_contents = NULL;
  g_autofree char *commit = NULL;
  g_autoptr(GVariant) commit_v = NULL;
  g_autoptr(GVariant) commit_metadata = NULL;
  g_autoptr(GPtrArray) subsets = NULL;
  CommitData *rev_data;
  const char *eol = NULL;
  const char *eol_rebase = NULL;
  int token_type = -1;
  g_autoptr(GVariant) extra_data_sources = NULL;
  guint32 n_extra_data = 0;
  guint64 total_extra_data_download_size = 0;
  g_autoptr(GVariantIter) subsets_iter = NULL;

  if (!ostree_repo_read_commit (repo, rev, &root, &commit, NULL, error))
    return NULL;

  if (!ostree_repo_load_commit (repo, commit, &commit_v, NULL, error))
    return NULL;

  commit_metadata = g_variant_get_child_value (commit_v, 0);
  if (!g_variant_lookup (commit_metadata, "xa.metadata", "s", &metadata_contents))
    {
      metadata = g_file_get_child (root, "metadata");
      if (!g_file_load_contents (metadata, cancellable, &metadata_contents, NULL, NULL, NULL))
        metadata_contents = g_strdup ("");
    }

  if (g_variant_lookup (commit_metadata, "xa.installed-size", "t", &installed_size) &&
      g_variant_lookup (commit_metadata, "xa.download-size", "t", &download_size))
    {
      installed_size = GUINT64_FROM_BE (installed_size);
      download_size = GUINT64_FROM_BE (download_size);
    }
  else
    {
      if (!flatpak_repo_collect_sizes (repo, root, &installed_size, &download_size, cancellable, error))
        return NULL;
    }

  if (g_variant_lookup (commit_metadata, "xa.subsets", "as", &subsets_iter))
    {
      const char *subset;
      subsets = g_ptr_array_new_with_free_func (g_free);
      while (g_variant_iter_next (subsets_iter, "&s", &subset))
        g_ptr_array_add (subsets, g_strdup (subset));
    }

  flatpak_repo_collect_extra_data_sizes (repo, rev, &installed_size, &download_size);

  rev_data = g_new0 (CommitData, 1);
  rev_data->installed_size = installed_size;
  rev_data->download_size = download_size;
  rev_data->metadata_contents = g_steal_pointer (&metadata_contents);
  rev_data->subsets = g_steal_pointer (&subsets);
  rev_data->commit_size = g_variant_get_size (commit_v);
  rev_data->commit_timestamp = ostree_commit_get_timestamp (commit_v);

  g_variant_lookup (commit_metadata, OSTREE_COMMIT_META_KEY_ENDOFLIFE, "&s", &eol);
  g_variant_lookup (commit_metadata, OSTREE_COMMIT_META_KEY_ENDOFLIFE_REBASE, "&s", &eol_rebase);
  if (g_variant_lookup (commit_metadata, "xa.token-type", "i", &token_type))
    token_type = GINT32_FROM_LE(token_type);

  extra_data_sources = flatpak_commit_get_extra_data_sources (commit_v, NULL);
  if (extra_data_sources)
    {
      n_extra_data = g_variant_n_children (extra_data_sources);
      for (int i = 0; i < n_extra_data; i++)
        {
          guint64 extra_download_size;
          flatpak_repo_parse_extra_data_sources (extra_data_sources, i,
                                                 NULL,
                                                 &extra_download_size,
                                                 NULL,
                                                 NULL,
                                                 NULL);
          total_extra_data_download_size += extra_download_size;
        }
    }

  if (eol || eol_rebase || token_type >= 0 || n_extra_data > 0)
    {
      g_auto(GVariantBuilder) sparse_builder = FLATPAK_VARIANT_BUILDER_INITIALIZER;
      g_variant_builder_init (&sparse_builder, G_VARIANT_TYPE_VARDICT);
      if (eol)
        g_variant_builder_add (&sparse_builder, "{sv}", FLATPAK_SPARSE_CACHE_KEY_ENDOFLIFE, g_variant_new_string (eol));
      if (eol_rebase)
        g_variant_builder_add (&sparse_builder, "{sv}", FLATPAK_SPARSE_CACHE_KEY_ENDOFLIFE_REBASE, g_variant_new_string (eol_rebase));
      if (token_type >= 0)
        g_variant_builder_add (&sparse_builder, "{sv}", FLATPAK_SPARSE_CACHE_KEY_TOKEN_TYPE, g_variant_new_int32 (GINT32_TO_LE(token_type)));
      if (n_extra_data > 0)
        g_variant_builder_add (&sparse_builder, "{sv}", FLATPAK_SPARSE_CACHE_KEY_EXTRA_DATA_SIZE,
                               g_variant_new ("(ut)", GUINT32_TO_LE(n_extra_data), GUINT64_TO_LE(total_extra_data_download_size)));

      rev_data->sparse_data = g_variant_ref_sink (g_variant_builder_end (&sparse_builder));
    }

  return rev_data;
}

static void
_ostree_parse_delta_name (const char *delta_name,
                          char      **out_from,
                          char      **out_to)
{
  g_auto(GStrv) parts = g_strsplit (delta_name, "-", 2);

  if (parts[0] && parts[1])
    {
      *out_from = g_steal_pointer (&parts[0]);
      *out_to = g_steal_pointer (&parts[1]);
    }
  else
    {
      *out_from = NULL;
      *out_to = g_steal_pointer (&parts[0]);
    }
}

static GString *
static_delta_path_base (const char *dir,
                        const char *from,
                        const char *to)
{
  guint8 csum_to[OSTREE_SHA256_DIGEST_LEN];
  char to_b64[44];
  guint8 csum_to_copy[OSTREE_SHA256_DIGEST_LEN];
  GString *ret = g_string_new (dir);

  ostree_checksum_inplace_to_bytes (to, csum_to);
  ostree_checksum_b64_inplace_from_bytes (csum_to, to_b64);
  ostree_checksum_b64_inplace_to_bytes (to_b64, csum_to_copy);

  g_assert (memcmp (csum_to, csum_to_copy, OSTREE_SHA256_DIGEST_LEN) == 0);

  if (from != NULL)
    {
      guint8 csum_from[OSTREE_SHA256_DIGEST_LEN];
      char from_b64[44];

      ostree_checksum_inplace_to_bytes (from, csum_from);
      ostree_checksum_b64_inplace_from_bytes (csum_from, from_b64);

      g_string_append_c (ret, from_b64[0]);
      g_string_append_c (ret, from_b64[1]);
      g_string_append_c (ret, '/');
      g_string_append (ret, from_b64 + 2);
      g_string_append_c (ret, '-');
    }

  g_string_append_c (ret, to_b64[0]);
  g_string_append_c (ret, to_b64[1]);
  if (from == NULL)
    g_string_append_c (ret, '/');
  g_string_append (ret, to_b64 + 2);

  return ret;
}

static char *
_ostree_get_relative_static_delta_path (const char *from,
                                        const char *to,
                                        const char *target)
{
  GString *ret = static_delta_path_base ("deltas/", from, to);

  if (target != NULL)
    {
      g_string_append_c (ret, '/');
      g_string_append (ret, target);
    }

  return g_string_free (ret, FALSE);
}

static char *
_ostree_get_relative_static_delta_superblock_path (const char        *from,
                                                   const char        *to)
{
  return _ostree_get_relative_static_delta_path (from, to, "superblock");
}

static GVariant *
_ostree_repo_static_delta_superblock_digest (OstreeRepo    *repo,
                                             const char    *from,
                                             const char    *to,
                                             GCancellable  *cancellable,
                                             GError       **error)
{
  g_autofree char *superblock = _ostree_get_relative_static_delta_superblock_path ((from && from[0]) ? from : NULL, to);
  glnx_autofd int fd = -1;
  guint8 digest[OSTREE_SHA256_DIGEST_LEN];
  gsize len;
  gpointer data = NULL;

  if (!glnx_openat_rdonly (ostree_repo_get_dfd (repo), superblock, TRUE, &fd, error))
    return NULL;

  g_autoptr(GBytes) superblock_content = glnx_fd_readall_bytes (fd, cancellable, error);
  if (!superblock_content)
    return NULL;

  g_autoptr(GChecksum) checksum = g_checksum_new (G_CHECKSUM_SHA256);
  g_checksum_update (checksum, g_bytes_get_data (superblock_content, NULL), g_bytes_get_size (superblock_content));
  len = sizeof digest;
  g_checksum_get_digest (checksum, digest, &len);

  data = g_memdup2 (digest, len);
  return g_variant_new_from_data (G_VARIANT_TYPE ("ay"),
                                  data, len,
                                  FALSE, g_free, data);
}

typedef enum {
  DIFF_OP_KIND_RESUSE_OLD,
  DIFF_OP_KIND_SKIP_OLD,
  DIFF_OP_KIND_DATA,
} DiffOpKind;

typedef struct {
  DiffOpKind kind;
  gsize size;
} DiffOp;

typedef struct {
  const guchar *old_data;
  const guchar *new_data;

  GArray *ops;
  GArray *data;

  gsize last_old_offset;
  gsize last_new_offset;
} DiffData;

static gsize
match_bytes_at_start (const guchar *data1,
                      gsize data1_len,
                      const guchar *data2,
                      gsize data2_len)
{
  gsize len = 0;
  gsize max_len = MIN (data1_len, data2_len);

  while (len < max_len)
    {
      if (*data1 != *data2)
        break;
      data1++;
      data2++;
      len++;
    }
  return len;
}

static gsize
match_bytes_at_end (const guchar *data1,
                    gsize data1_len,
                    const guchar *data2,
                    gsize data2_len)
{
  gsize len = 0;
  gsize max_len = MIN (data1_len, data2_len);

  data1 += data1_len - 1;
  data2 += data2_len - 1;

  while (len < max_len)
    {
      if (*data1 != *data2)
        break;
      data1--;
      data2--;
      len++;
    }
  return len;
}

static DiffOp *
diff_ensure_op (DiffData *data,
                DiffOpKind kind)
{
  if (data->ops->len == 0 ||
      g_array_index (data->ops, DiffOp, data->ops->len-1).kind != kind)
    {
      DiffOp op = {kind, 0};
      g_array_append_val (data->ops, op);
    }

  return &g_array_index (data->ops, DiffOp, data->ops->len-1);
}

static void
diff_emit_reuse (DiffData *data,
                 gsize size)
{
  DiffOp *op;

  if (size == 0)
    return;

  op = diff_ensure_op (data, DIFF_OP_KIND_RESUSE_OLD);
  op->size += size;
}

static void
diff_emit_skip (DiffData *data,
                gsize size)
{
  DiffOp *op;

  if (size == 0)
    return;

  op = diff_ensure_op (data, DIFF_OP_KIND_SKIP_OLD);
  op->size += size;
}

static void
diff_emit_data (DiffData *data,
                gsize size,
                const guchar *new_data)
{
  DiffOp *op;

  if (size == 0)
    return;

  op = diff_ensure_op (data, DIFF_OP_KIND_DATA);
  op->size += size;

  g_array_append_vals (data->data, new_data, size);
}

static GBytes *
diff_encode (DiffData *data, GError **error)
{
  g_autoptr(GOutputStream) mem = g_memory_output_stream_new_resizable ();
  g_autoptr(GDataOutputStream) out = g_data_output_stream_new (mem);
  gsize ops_count = 0;

  g_data_output_stream_set_byte_order (out, G_DATA_STREAM_BYTE_ORDER_LITTLE_ENDIAN);

  /* Header */
  if (!g_output_stream_write_all (G_OUTPUT_STREAM (out),
                                  FLATPAK_SUMMARY_DIFF_HEADER, 4,
                                  NULL, NULL, error))
    return NULL;

  /* Write the ops count placeholder */
  if (!g_data_output_stream_put_uint32 (out, 0, NULL, error))
    return NULL;

  for (gsize i = 0; i < data->ops->len; i++)
    {
      DiffOp *op = &g_array_index (data->ops, DiffOp, i);
      gsize size = op->size;

      while (size > 0)
        {
          /* We leave a nibble at the top for the op */
          guint32 opdata = (guint64)size & 0x0fffffff;
          size -= opdata;

          opdata = opdata | ((0xf & op->kind) << 28);

          if (!g_data_output_stream_put_uint32 (out, opdata, NULL, error))
            return NULL;
          ops_count++;
        }
    }

  /* Then add the data */
  if (data->data->len > 0 &&
      !g_output_stream_write_all (G_OUTPUT_STREAM (out),
                                  data->data->data, data->data->len,
                                  NULL, NULL, error))
    return NULL;

  /* Back-patch in the ops count */
  if (!g_seekable_seek (G_SEEKABLE(out), 4, G_SEEK_SET, NULL, error))
    return NULL;

  if (!g_data_output_stream_put_uint32 (out, ops_count, NULL, error))
    return NULL;

  if (!g_output_stream_close (G_OUTPUT_STREAM (out), NULL, error))
    return NULL;

  return g_memory_output_stream_steal_as_bytes (G_MEMORY_OUTPUT_STREAM (mem));
}

static void
diff_consume_block2 (DiffData *data,
                     gsize consume_old_offset,
                     gsize consume_old_size,
                     gsize produce_new_offset,
                     gsize produce_new_size)
{
  /* We consumed $consume_old_size bytes from $consume_old_offset to
     produce $produce_new_size bytes at $produce_new_size */

  /* First we copy old data for any matching prefix of the block */

  gsize prefix_len = match_bytes_at_start (data->old_data + consume_old_offset, consume_old_size,
                                           data->new_data + produce_new_offset, produce_new_size);
  diff_emit_reuse (data, prefix_len);

  consume_old_size -= prefix_len;
  consume_old_offset += prefix_len;

  produce_new_size -= prefix_len;
  produce_new_offset += prefix_len;

  /* Then we find the matching suffix for the rest */
  gsize suffix_len = match_bytes_at_end (data->old_data + consume_old_offset, consume_old_size,
                                         data->new_data + produce_new_offset, produce_new_size);

  /* Skip source data until suffix match */
  diff_emit_skip (data, consume_old_size - suffix_len);

  /* Copy new data until suffix match */
  diff_emit_data (data, produce_new_size - suffix_len, data->new_data + produce_new_offset);

  diff_emit_reuse (data, suffix_len);
}

static void
diff_consume_block (DiffData *data,
                    gssize consume_old_offset,
                    gsize consume_old_size,
                    gssize produce_new_offset,
                    gsize produce_new_size)
{
  if (consume_old_offset == -1)
    consume_old_offset = data->last_old_offset;
  if (produce_new_offset == -1)
    produce_new_offset = data->last_new_offset;

  /* We consumed $consume_old_size bytes from $consume_old_offset to
   * produce $produce_new_size bytes at $produce_new_size, however
   * while the emitted blocks are in order they may not cover the
   * every byte, so we emit the inbetwen blocks separately. */

  if (consume_old_offset != data->last_old_offset ||
      produce_new_offset != data->last_new_offset)
    diff_consume_block2 (data,
                         data->last_old_offset, consume_old_offset - data->last_old_offset ,
                         data->last_new_offset, produce_new_offset - data->last_new_offset);

  diff_consume_block2 (data,
                       consume_old_offset, consume_old_size,
                       produce_new_offset, produce_new_size);

  data->last_old_offset = consume_old_offset + consume_old_size;
  data->last_new_offset = produce_new_offset + produce_new_size;
}

GBytes *
flatpak_summary_apply_diff (GBytes *old,
                            GBytes *diff,
                            GError **error)
{
  g_autoptr(GBytes) uncompressed = NULL;
  const guchar *diffdata;
  gsize diff_size;
  guint32 *ops;
  guint32 n_ops;
  gsize data_offset;
  gsize data_size;
  const guchar *data;
  const guchar *old_data = g_bytes_get_data (old, NULL);
  gsize old_size = g_bytes_get_size (old);
  g_autoptr(GByteArray) res = g_byte_array_new ();

  uncompressed = flatpak_zlib_decompress_bytes (diff, error);
  if (uncompressed == NULL)
    {
      g_prefix_error (error, "Invalid summary diff: ");
      return NULL;
    }

  diffdata = g_bytes_get_data (uncompressed, NULL);
  diff_size = g_bytes_get_size (uncompressed);

  if (diff_size < 8 ||
      memcmp (diffdata, FLATPAK_SUMMARY_DIFF_HEADER, 4) != 0)
    {
      flatpak_fail (error, "Invalid summary diff");
      return NULL;
    }

  n_ops = GUINT32_FROM_LE (*(guint32 *)(diffdata+4));
  ops = (guint32 *)(diffdata+8);

  data_offset = 4 + 4 + 4 * n_ops;

  /* All ops must fit in diff, and avoid wrapping the multiply */
  if (data_offset > diff_size ||
      (data_offset - 4 - 4) / 4 != n_ops)
    {
      flatpak_fail (error, "Invalid summary diff");
      return NULL;
    }

  data = diffdata + data_offset;
  data_size = diff_size - data_offset;

  for (gsize i = 0; i < n_ops; i++)
    {
      guint32 opdata = GUINT32_FROM_LE (ops[i]);
      guint32 kind = (opdata & 0xf0000000) >> 28;
      guint32 size = opdata & 0x0fffffff;

      switch (kind)
        {
        case DIFF_OP_KIND_RESUSE_OLD:
          if (size > old_size)
            {
              flatpak_fail (error, "Invalid summary diff");
              return NULL;
            }
          g_byte_array_append (res, old_data, size);
          old_data += size;
          old_size -= size;
          break;
        case DIFF_OP_KIND_SKIP_OLD:
          if (size > old_size)
            {
              flatpak_fail (error, "Invalid summary diff");
              return NULL;
            }
          old_data += size;
          old_size -= size;
          break;
        case DIFF_OP_KIND_DATA:
          if (size > data_size)
            {
              flatpak_fail (error, "Invalid summary diff");
              return NULL;
            }
          g_byte_array_append (res, data, size);
          data += size;
          data_size -= size;
          break;
        default:
          flatpak_fail (error, "Invalid summary diff");
          return NULL;
        }
    }

  return g_byte_array_free_to_bytes (g_steal_pointer (&res));
}


static GBytes *
flatpak_summary_generate_diff (GVariant *old_v,
                               GVariant *new_v,
                               GError **error)
{
  VarSummaryRef new, old;
  VarRefMapRef new_refs, old_refs;
  gsize new_len, old_len;
  int new_i, old_i;
  g_autoptr(GArray) ops = g_array_new (FALSE, TRUE, sizeof (DiffOp));
  g_autoptr(GArray) data_bytes = g_array_new (FALSE, TRUE, 1);
  g_autoptr(GBytes) diff_uncompressed = NULL;
  g_autoptr(GBytes) diff_compressed = NULL;
  DiffData data = {
    g_variant_get_data (old_v),
    g_variant_get_data (new_v),
    ops,
    data_bytes,
  };

  new = var_summary_from_gvariant (new_v);
  old = var_summary_from_gvariant (old_v);

  new_refs = var_summary_get_ref_map (new);
  old_refs = var_summary_get_ref_map (old);

  new_len = var_ref_map_get_length (new_refs);
  old_len = var_ref_map_get_length (old_refs);

  new_i = old_i = 0;
  while (new_i < new_len && old_i < old_len)
    {
      VarRefMapEntryRef new_entry = var_ref_map_get_at (new_refs, new_i);
      const char *new_ref = var_ref_map_entry_get_ref (new_entry);

      VarRefMapEntryRef old_entry = var_ref_map_get_at (old_refs, old_i);
      const char *old_ref = var_ref_map_entry_get_ref (old_entry);

      int cmp = strcmp (new_ref, old_ref);
      if (cmp == 0)
        {
          /* same ref */
          diff_consume_block (&data,
                              (const guchar *)old_entry.base - (const guchar *)old.base, old_entry.size,
                              (const guchar *)new_entry.base - (const guchar *)new.base, new_entry.size);
          old_i++;
          new_i++;
        }
      else if (cmp < 0)
        {
          /* new added */
          diff_consume_block (&data,
                              -1, 0,
                              (const guchar *)new_entry.base - (const guchar *)new.base, new_entry.size);
          new_i++;
        }
      else
        {
          /* old removed */
          diff_consume_block (&data,
                              (const guchar *)old_entry.base - (const guchar *)old.base, old_entry.size,
                              -1, 0);
          old_i++;
        }
    }

  /* Flush till the end */
  diff_consume_block2 (&data,
                       data.last_old_offset, old.size - data.last_old_offset,
                       data.last_new_offset, new.size - data.last_new_offset);

  diff_uncompressed = diff_encode (&data, error);
  if (diff_uncompressed == NULL)
    return NULL;

  diff_compressed = flatpak_zlib_compress_bytes (diff_uncompressed, 9, error);
  if (diff_compressed == NULL)
    return NULL;

#ifdef VALIDATE_DIFF
  {
    g_autoptr(GError) apply_error = NULL;
    g_autoptr(GBytes) old_bytes = g_variant_get_data_as_bytes (old_v);
    g_autoptr(GBytes) new_bytes = g_variant_get_data_as_bytes (new_v);
    g_autoptr(GBytes) applied = flatpak_summary_apply_diff (old_bytes, diff_compressed, &apply_error);
    g_assert (applied != NULL);
    g_assert (g_bytes_equal (applied, new_bytes));
  }
#endif

  return g_steal_pointer (&diff_compressed);
}

static void
variant_dict_merge (GVariantDict *dict,
                    GVariant *to_merge)
{
  GVariantIter iter;
  gchar *key;
  GVariant *value;

  if (to_merge)
    {
      g_variant_iter_init (&iter, to_merge);
      while (g_variant_iter_next (&iter, "{sv}", &key, &value))
        {
          g_variant_dict_insert_value (dict, key, value);
          g_variant_unref (value);
          g_free (key);
        }
    }
}

static void
add_summary_metadata (OstreeRepo   *repo,
                      GVariantBuilder *metadata_builder)
{
  GKeyFile *config;
  g_autofree char *title = NULL;
  g_autofree char *comment = NULL;
  g_autofree char *description = NULL;
  g_autofree char *homepage = NULL;
  g_autofree char *icon = NULL;
  g_autofree char *redirect_url = NULL;
  g_autofree char *default_branch = NULL;
  g_autofree char *remote_mode_str = NULL;
  g_autofree char *authenticator_name = NULL;
  g_autofree char *gpg_keys = NULL;
  g_auto(GStrv) config_keys = NULL;
  int authenticator_install = -1;
  const char *collection_id;
  gboolean deploy_collection_id = FALSE;
  gboolean deploy_sideload_collection_id = FALSE;
  gboolean tombstone_commits = FALSE;

  config = ostree_repo_get_config (repo);

  if (config)
    {
      remote_mode_str = g_key_file_get_string (config, "core", "mode", NULL);
      tombstone_commits = g_key_file_get_boolean (config, "core", "tombstone-commits", NULL);

      title = g_key_file_get_string (config, "flatpak", "title", NULL);
      comment = g_key_file_get_string (config, "flatpak", "comment", NULL);
      description = g_key_file_get_string (config, "flatpak", "description", NULL);
      homepage = g_key_file_get_string (config, "flatpak", "homepage", NULL);
      icon = g_key_file_get_string (config, "flatpak", "icon", NULL);
      default_branch = g_key_file_get_string (config, "flatpak", "default-branch", NULL);
      gpg_keys = g_key_file_get_string (config, "flatpak", "gpg-keys", NULL);
      redirect_url = g_key_file_get_string (config, "flatpak", "redirect-url", NULL);
      deploy_sideload_collection_id = g_key_file_get_boolean (config, "flatpak", "deploy-sideload-collection-id", NULL);
      deploy_collection_id = g_key_file_get_boolean (config, "flatpak", "deploy-collection-id", NULL);
      authenticator_name = g_key_file_get_string (config, "flatpak", "authenticator-name", NULL);
      if (g_key_file_has_key (config, "flatpak", "authenticator-install", NULL))
        authenticator_install = g_key_file_get_boolean (config, "flatpak", "authenticator-install", NULL);

      config_keys = g_key_file_get_keys (config, "flatpak", NULL, NULL);
    }

  collection_id = ostree_repo_get_collection_id (repo);

  g_variant_builder_add (metadata_builder, "{sv}", "ostree.summary.mode",
                         g_variant_new_string (remote_mode_str ? remote_mode_str : "bare"));
  g_variant_builder_add (metadata_builder, "{sv}", "ostree.summary.tombstone-commits",
                         g_variant_new_boolean (tombstone_commits));
  g_variant_builder_add (metadata_builder, "{sv}", "ostree.summary.indexed-deltas",
                         g_variant_new_boolean (TRUE));
  g_variant_builder_add (metadata_builder, "{sv}", "ostree.summary.last-modified",
                         g_variant_new_uint64 (GUINT64_TO_BE (g_get_real_time () / G_USEC_PER_SEC)));

  if (collection_id)
    g_variant_builder_add (metadata_builder, "{sv}", "ostree.summary.collection-id",
                           g_variant_new_string (collection_id));

  if (title)
    g_variant_builder_add (metadata_builder, "{sv}", "xa.title",
                           g_variant_new_string (title));

  if (comment)
    g_variant_builder_add (metadata_builder, "{sv}", "xa.comment",
                           g_variant_new_string (comment));

  if (description)
    g_variant_builder_add (metadata_builder, "{sv}", "xa.description",
                           g_variant_new_string (description));

  if (homepage)
    g_variant_builder_add (metadata_builder, "{sv}", "xa.homepage",
                           g_variant_new_string (homepage));

  if (icon)
    g_variant_builder_add (metadata_builder, "{sv}", "xa.icon",
                           g_variant_new_string (icon));

  if (redirect_url)
    g_variant_builder_add (metadata_builder, "{sv}", "xa.redirect-url",
                           g_variant_new_string (redirect_url));

  if (default_branch)
    g_variant_builder_add (metadata_builder, "{sv}", "xa.default-branch",
                           g_variant_new_string (default_branch));

  if (deploy_collection_id && collection_id != NULL)
    g_variant_builder_add (metadata_builder, "{sv}", OSTREE_META_KEY_DEPLOY_COLLECTION_ID,
                           g_variant_new_string (collection_id));
  else if (deploy_sideload_collection_id && collection_id != NULL)
    g_variant_builder_add (metadata_builder, "{sv}", "xa.deploy-collection-id",
                           g_variant_new_string (collection_id));
  else if (deploy_collection_id)
    g_info ("Ignoring deploy-collection-id=true because no collection ID is set.");

  if (authenticator_name)
    g_variant_builder_add (metadata_builder, "{sv}", "xa.authenticator-name",
                           g_variant_new_string (authenticator_name));

  if (authenticator_install != -1)
    g_variant_builder_add (metadata_builder, "{sv}", "xa.authenticator-install",
                           g_variant_new_boolean (authenticator_install));

  g_variant_builder_add (metadata_builder, "{sv}", "xa.cache-version",
                         g_variant_new_uint32 (GUINT32_TO_LE (FLATPAK_XA_CACHE_VERSION)));

  if (config_keys != NULL)
    {
      for (int i = 0; config_keys[i] != NULL; i++)
        {
          const char *key = config_keys[i];
          g_autofree char *xa_key = NULL;
          g_autofree char *value = NULL;

          if (!g_str_has_prefix (key, "authenticator-options."))
            continue;

          value = g_key_file_get_string (config, "flatpak", key, NULL);
          if (value == NULL)
            continue;

          xa_key = g_strconcat ("xa.", key, NULL);
          g_variant_builder_add (metadata_builder, "{sv}", xa_key,
                                 g_variant_new_string (value));
        }
    }

  if (gpg_keys)
    {
      guchar *decoded;
      gsize decoded_len;

      gpg_keys = g_strstrip (gpg_keys);
      decoded = g_base64_decode (gpg_keys, &decoded_len);

      g_variant_builder_add (metadata_builder, "{sv}", "xa.gpg-keys",
                             g_variant_new_from_data (G_VARIANT_TYPE ("ay"), decoded, decoded_len,
                                                      TRUE, (GDestroyNotify) g_free, decoded));
    }
}

static char *
appstream_ref_get_subset (const char *ref)
{
  if (!g_str_has_prefix (ref, "appstream2/"))
    return NULL;

  const char *rest = ref + strlen ("appstream2/");
  const char *dash = strrchr (rest, '-');
  if (dash == NULL)
    return NULL;

  return g_strndup (rest, dash - rest);
}

static GVariant *
generate_summary (OstreeRepo   *repo,
                  gboolean      compat_format,
                  GHashTable   *refs,
                  GHashTable   *commit_data_cache,
                  GPtrArray    *delta_names,
                  const char   *subset,
                  const char  **summary_arches,
                  GCancellable *cancellable,
                  GError      **error)
{
  g_autoptr(GVariantBuilder) metadata_builder = g_variant_builder_new (G_VARIANT_TYPE_VARDICT);
  g_autoptr(GVariantBuilder) ref_data_builder = g_variant_builder_new (G_VARIANT_TYPE ("a{s(tts)}"));
  g_autoptr(GVariantBuilder) ref_sparse_data_builder = g_variant_builder_new (G_VARIANT_TYPE ("a{sa{sv}}"));
  g_autoptr(GVariantBuilder) refs_builder = g_variant_builder_new (G_VARIANT_TYPE ("a(s(taya{sv}))"));
  g_autoptr(GVariantBuilder) summary_builder = g_variant_builder_new (OSTREE_SUMMARY_GVARIANT_FORMAT);
  g_autoptr(GHashTable) summary_arches_ht = NULL;
  g_autoptr(GHashTable) commits = NULL;
  g_autoptr(GList) ordered_keys = NULL;
  GList *l = NULL;

  /* In the new format this goes in the summary index instead */
  if (compat_format)
    add_summary_metadata (repo, metadata_builder);

  ordered_keys = g_hash_table_get_keys (refs);
  ordered_keys = g_list_sort (ordered_keys, (GCompareFunc) strcmp);

  if (summary_arches)
    {
      summary_arches_ht = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, NULL);
      for (int i = 0; summary_arches[i] != NULL; i++)
        {
          const char *arch = summary_arches[i];

          g_hash_table_add (summary_arches_ht, (char *)arch);
        }
    }

  /* Compute which commits to keep */
  commits = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, NULL); /* strings owned by ref */
  for (l = ordered_keys; l; l = l->next)
    {
      const char *ref = l->data;
      const char *rev = g_hash_table_lookup (refs, ref);
      g_autofree char *arch = NULL;
      const CommitData *rev_data = NULL;

      if (summary_arches)
        {
          /* NOTE: Non-arched (unknown) refs get into all summary versions */
          arch = flatpak_get_arch_for_ref (ref);
          if (arch != NULL && !g_hash_table_contains (summary_arches_ht, arch))
            continue; /* Filter this ref by arch */
        }

      rev_data = g_hash_table_lookup (commit_data_cache, rev);
      if (*subset != 0)
        {
          /* Subset summaries keep the appstream2/$subset-$arch, and have no appstream/ compat branch */

          if (g_str_has_prefix (ref, "appstream/"))
            {
              continue; /* No compat branch in subsets */
            }
          else if (g_str_has_prefix (ref, "appstream2/"))
            {
              g_autofree char *ref_subset = appstream_ref_get_subset (ref);
              if (ref_subset == NULL)
                continue; /* Non-subset, ignore */

              if (strcmp (subset, ref_subset) != 0)
                continue; /* Different subset, ignore */

              /* Otherwise, keep */
            }
          else if (rev_data)
            {
              if (rev_data->subsets == NULL ||
                  !flatpak_g_ptr_array_contains_string (rev_data->subsets, subset))
                continue; /* Ref is not in this subset */
            }
        }
      else
        {
          /* non-subset, keep everything but subset appstream refs */

          g_autofree char *ref_subset = appstream_ref_get_subset (ref);
          if (ref_subset != NULL)
            continue; /* Subset appstream ref, ignore */
        }

      g_hash_table_add (commits, (char *)rev);
    }

  /* Create refs list, metadata and sparse_data */
  for (l = ordered_keys; l; l = l->next)
    {
      const char *ref = l->data;
      const char *rev = g_hash_table_lookup (refs, ref);
      const CommitData *rev_data = NULL;
      g_auto(GVariantDict) commit_metadata_builder = FLATPAK_VARIANT_BUILDER_INITIALIZER;
      guint64 commit_size;
      guint64 commit_timestamp;

      if (!g_hash_table_contains (commits, rev))
        continue; /* Filter out commit (by arch & subset) */

      if (flatpak_is_app_runtime_or_appstream_ref (ref))
        rev_data = g_hash_table_lookup (commit_data_cache, rev);

      if (rev_data != NULL)
        {
          commit_size = rev_data->commit_size;
          commit_timestamp = rev_data->commit_timestamp;
        }
      else
        {
          g_autoptr(GVariant) commit_obj = NULL;
          if (!ostree_repo_load_variant (repo, OSTREE_OBJECT_TYPE_COMMIT, rev, &commit_obj, error))
            return NULL;
          commit_size = g_variant_get_size (commit_obj);
          commit_timestamp = ostree_commit_get_timestamp (commit_obj);
        }

      g_variant_dict_init (&commit_metadata_builder, NULL);
      if (!compat_format && rev_data)
        {
          g_variant_dict_insert (&commit_metadata_builder, "xa.data", "(tts)",
                                 GUINT64_TO_BE (rev_data->installed_size),
                                 GUINT64_TO_BE (rev_data->download_size),
                                 rev_data->metadata_contents);
          variant_dict_merge (&commit_metadata_builder, rev_data->sparse_data);
        }

      /* For the new format summary we use a shorter name for the timestamp to save space */
      g_variant_dict_insert_value (&commit_metadata_builder,
                                   compat_format ? OSTREE_COMMIT_TIMESTAMP  : OSTREE_COMMIT_TIMESTAMP2,
                                   g_variant_new_uint64 (GUINT64_TO_BE (commit_timestamp)));

      g_variant_builder_add_value (refs_builder,
                                   g_variant_new ("(s(t@ay@a{sv}))", ref,
                                                  commit_size,
                                                  ostree_checksum_to_bytes_v (rev),
                                                  g_variant_dict_end (&commit_metadata_builder)));

      if (compat_format && rev_data)
        {
          g_variant_builder_add (ref_data_builder, "{s(tts)}",
                                 ref,
                                 GUINT64_TO_BE (rev_data->installed_size),
                                 GUINT64_TO_BE (rev_data->download_size),
                                 rev_data->metadata_contents);
          if (rev_data->sparse_data)
            g_variant_builder_add (ref_sparse_data_builder, "{s@a{sv}}",
                                   ref, rev_data->sparse_data);
        }
    }

  if (delta_names)
    {
      g_auto(GVariantDict) deltas_builder = FLATPAK_VARIANT_BUILDER_INITIALIZER;

      g_variant_dict_init (&deltas_builder, NULL);
      for (guint i = 0; i < delta_names->len; i++)
        {
          g_autofree char *from = NULL;
          g_autofree char *to = NULL;
          GVariant *digest;

          _ostree_parse_delta_name (delta_names->pdata[i], &from, &to);

          /* Only keep deltas going to a ref that is in the summary
           * (i.e. not arch filtered or random) */
          if (!g_hash_table_contains (commits, to))
            continue;

          digest = _ostree_repo_static_delta_superblock_digest (repo,
                                                                (from && from[0]) ? from : NULL,
                                                                to, cancellable, error);
          if (digest == NULL)
            return FALSE;

          g_variant_dict_insert_value (&deltas_builder, delta_names->pdata[i], digest);
        }

      if (delta_names->len > 0)
        g_variant_builder_add (metadata_builder, "{sv}", "ostree.static-deltas", g_variant_dict_end (&deltas_builder));
    }

  if (compat_format)
    {
      /* Note: xa.cache doesn’t need to support collection IDs for the refs listed
       * in it, because the xa.cache metadata is stored on the ostree-metadata ref,
       * which is itself strongly bound to a collection ID — so that collection ID
       * is bound to all the refs in xa.cache. If a client is using the xa.cache
       * data from a summary file (rather than an ostree-metadata branch), they are
       * too old to care about collection IDs anyway. */
      g_variant_builder_add (metadata_builder, "{sv}", "xa.cache",
                             g_variant_new_variant (g_variant_builder_end (ref_data_builder)));
      g_variant_builder_add (metadata_builder, "{sv}", "xa.sparse-cache",
                             g_variant_builder_end (ref_sparse_data_builder));
    }
  else
    {
      g_variant_builder_add (metadata_builder, "{sv}", "xa.summary-version",
                             g_variant_new_uint32 (GUINT32_TO_LE (FLATPAK_XA_SUMMARY_VERSION)));
    }

  g_variant_builder_add_value (summary_builder, g_variant_builder_end (refs_builder));
  g_variant_builder_add_value (summary_builder, g_variant_builder_end (metadata_builder));

  return g_variant_ref_sink (g_variant_builder_end (summary_builder));
}

static GVariant *
read_digested_summary (OstreeRepo   *repo,
                       const char   *digest,
                       GHashTable   *digested_summary_cache,
                       GCancellable *cancellable,
                       GError      **error)
{
  GVariant *cached;
  g_autoptr(GVariant) loaded = NULL;

  cached = g_hash_table_lookup (digested_summary_cache, digest);
  if (cached)
    return g_variant_ref (cached);

  loaded = flatpak_repo_load_digested_summary (repo, digest, error);
  if (loaded == NULL)
    return NULL;

  g_hash_table_insert (digested_summary_cache, g_strdup (digest), g_variant_ref (loaded));

  return g_steal_pointer (&loaded);
}

static gboolean
add_to_history (OstreeRepo      *repo,
                GVariantBuilder *history_builder,
                VarChecksumRef   old_digest_vv,
                GVariant        *current_digest_v,
                GVariant        *current_content,
                GHashTable      *digested_summary_cache,
                guint           *history_len,
                guint            max_history_length,
                GCancellable    *cancellable,
                GError         **error)
{
  g_autoptr(GVariant) old_digest_v = g_variant_ref_sink (var_checksum_dup_to_gvariant (old_digest_vv));
  g_autofree char *old_digest = NULL;
  g_autoptr(GVariant) old_content = NULL;
  g_autofree char *current_digest = NULL;
  g_autoptr(GBytes) subsummary_diff = NULL;

  /* Limit history length */
  if (*history_len >= max_history_length)
    return TRUE;

  /* Avoid repeats in the history (in case nothing changed in subsummary) */
  if (g_variant_equal (old_digest_v, current_digest_v))
    return TRUE;

  old_digest = ostree_checksum_from_bytes_v (old_digest_v);
  old_content = read_digested_summary (repo, old_digest, digested_summary_cache, cancellable, NULL);
  if  (old_content == NULL)
    return TRUE; /* Only add parents that still exist */

  subsummary_diff = flatpak_summary_generate_diff (old_content, current_content, error);
  if  (subsummary_diff == NULL)
    return FALSE;

  current_digest = ostree_checksum_from_bytes_v (current_digest_v);

  if (!flatpak_repo_save_digested_summary_delta (repo, old_digest, current_digest,
                                                 subsummary_diff, cancellable, error))
    return FALSE;

  *history_len += 1;
  g_variant_builder_add_value (history_builder, old_digest_v);

  return TRUE;
}

static GVariant *
generate_summary_index (OstreeRepo   *repo,
                        GVariant     *old_index_v,
                        GHashTable   *summaries,
                        GHashTable   *digested_summaries,
                        GHashTable   *digested_summary_cache,
                        const char  **gpg_key_ids,
                        const char   *gpg_homedir,
                        GCancellable *cancellable,
                        GError      **error)
{
  g_autoptr(GVariantBuilder) metadata_builder = g_variant_builder_new (G_VARIANT_TYPE_VARDICT);
  g_autoptr(GVariantBuilder) subsummary_builder = g_variant_builder_new (G_VARIANT_TYPE ("a{s(ayaaya{sv})}"));
  g_autoptr(GVariantBuilder) index_builder = g_variant_builder_new (FLATPAK_SUMMARY_INDEX_GVARIANT_FORMAT);
  g_autoptr(GVariant) index = NULL;
  g_autoptr(GList) ordered_summaries = NULL;
  guint max_history_length = flatpak_repo_get_summary_history_length (repo);
  GList *l;

  add_summary_metadata (repo, metadata_builder);

  ordered_summaries = g_hash_table_get_keys (summaries);
  ordered_summaries = g_list_sort (ordered_summaries, (GCompareFunc) strcmp);
  for (l = ordered_summaries; l; l = l->next)
    {
      g_auto(GVariantDict) subsummary_metadata_builder = FLATPAK_VARIANT_BUILDER_INITIALIZER;
      const char *subsummary = l->data;
      const char *digest = g_hash_table_lookup (summaries, subsummary);
      g_autoptr(GVariant) digest_v = g_variant_ref_sink (ostree_checksum_to_bytes_v (digest));
      g_autoptr(GVariantBuilder) history_builder = g_variant_builder_new (G_VARIANT_TYPE ("aay"));
      g_autoptr(GVariant) subsummary_content = NULL;

      subsummary_content = read_digested_summary (repo, digest, digested_summary_cache, cancellable, error);
      if  (subsummary_content == NULL)
        return NULL;  /* This really should always be there as we're supposed to index it */

      if (old_index_v)
        {
          VarSummaryIndexRef old_index = var_summary_index_from_gvariant (old_index_v);
          VarSummaryIndexSubsummariesRef old_subsummaries = var_summary_index_get_subsummaries (old_index);
          VarSubsummaryRef old_subsummary;
          guint history_len = 0;

          if (var_summary_index_subsummaries_lookup (old_subsummaries, subsummary, NULL, &old_subsummary))
            {
              VarChecksumRef parent = var_subsummary_get_checksum (old_subsummary);

              /* Add current as first in history */
              if (!add_to_history (repo, history_builder, parent, digest_v, subsummary_content, digested_summary_cache,
                                   &history_len, max_history_length, cancellable, error))
                return FALSE;

              /* Add previous history */
              VarArrayofChecksumRef history = var_subsummary_get_history (old_subsummary);
              gsize len = var_arrayof_checksum_get_length (history);
              for (gsize i = 0; i < len; i++)
                {
                  VarChecksumRef c = var_arrayof_checksum_get_at (history, i);
                  if (!add_to_history (repo, history_builder, c, digest_v, subsummary_content, digested_summary_cache,
                                       &history_len, max_history_length, cancellable, error))
                    return FALSE;
                }
            }
        }

      g_variant_dict_init (&subsummary_metadata_builder, NULL);
      g_variant_builder_add (subsummary_builder, "{s(@ay@aay@a{sv})}",
                             subsummary,
                             digest_v,
                             g_variant_builder_end (history_builder),
                             g_variant_dict_end (&subsummary_metadata_builder));
    }

  g_variant_builder_add_value (index_builder, g_variant_builder_end (subsummary_builder));
  g_variant_builder_add_value (index_builder, g_variant_builder_end (metadata_builder));

  index = g_variant_ref_sink (g_variant_builder_end (index_builder));

  return g_steal_pointer (&index);
}

static gboolean
flatpak_repo_gc_digested_summaries (OstreeRepo *repo,
                                    const char *index_digest,           /* The digest of the current (new) index (if any) */
                                    const char *old_index_digest,       /* The digest of the previous index (if any) */
                                    GHashTable *digested_summaries,     /* generated */
                                    GHashTable *digested_summary_cache, /* generated + referenced */
                                    GCancellable *cancellable,
                                    GError **error)
{
  g_auto(GLnxDirFdIterator) iter = {0};
  int repo_fd = ostree_repo_get_dfd (repo);
  struct dirent *dent;
  const char *ext;
  g_autoptr(GError) local_error = NULL;

  if (!glnx_dirfd_iterator_init_at (repo_fd, "summaries", FALSE, &iter, &local_error))
    {
      if (g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
        return TRUE;

      g_propagate_error (error, g_steal_pointer (&local_error));
      return FALSE;
    }

  while (TRUE)
    {
      gboolean remove = FALSE;

      if (!glnx_dirfd_iterator_next_dent_ensure_dtype (&iter, &dent, cancellable, error))
        return FALSE;

      if (dent == NULL)
        break;

      if (dent->d_type != DT_REG)
        continue;

      /* Keep it if its an unexpected type */
      ext = strchr (dent->d_name, '.');
      if (ext != NULL)
        {
          if (strcmp (ext, ".gz") == 0 && strlen (dent->d_name) == 64 + 3)
            {
              g_autofree char *sha256 = g_strndup (dent->d_name, 64);

              /* Keep all the referenced summaries */
              if (g_hash_table_contains (digested_summary_cache, sha256))
                {
                  g_info ("Keeping referenced summary %s", dent->d_name);
                  continue;
                }
              /* Remove rest */
              remove = TRUE;
            }
          else if (strcmp (ext, ".delta") == 0)
            {
              const char *dash = strchr (dent->d_name, '-');
              if (dash != NULL && dash < ext && (ext - dash) == 1 + 64)
                {
                  g_autofree char *to_sha256 = g_strndup (dash + 1, 64);

                  /* Only keep deltas going to a generated summary */
                  if (g_hash_table_contains (digested_summaries, to_sha256))
                    {
                      g_info ("Keeping delta to generated summary %s", dent->d_name);
                      continue;
                    }
                  /* Remove rest */
                  remove = TRUE;
                }
            }
          else if (strcmp (ext, ".idx.sig") == 0)
            {
              g_autofree char *digest = g_strndup (dent->d_name, strlen (dent->d_name) - strlen (".idx.sig"));

              if (g_strcmp0 (digest, index_digest) == 0)
                continue; /* Always keep current */

              if (g_strcmp0 (digest, old_index_digest) == 0)
                continue; /* Always keep previous one, to avoid some races */

              /* Remove the rest */
              remove = TRUE;
            }
        }

      if (remove)
        {
          g_info ("Removing old digested summary file %s", dent->d_name);
          if (unlinkat (iter.fd, dent->d_name, 0) != 0)
            {
              glnx_set_error_from_errno (error);
              return FALSE;
            }
        }
      else
        g_info ("Keeping unexpected summary file %s", dent->d_name);
    }

  return TRUE;
}

/* Update the metadata in the summary file for @repo, and then re-sign the file.
 * If the repo has a collection ID set, additionally store the metadata on a
 * contentless commit in a well-known branch, which is the preferred way of
 * broadcasting per-repo metadata (putting it in the summary file is deprecated,
 * but kept for backwards compatibility).
 *
 * Note that there are two keys for the collection ID: collection-id, and
 * ostree.deploy-collection-id. If a client does not currently have a
 * collection ID configured for this remote, it will *only* update its
 * configuration from ostree.deploy-collection-id.  This allows phased
 * deployment of collection-based repositories. Clients will only update their
 * configuration from an unset to a set collection ID once (otherwise the
 * security properties of collection IDs are broken). */
gboolean
flatpak_repo_update (OstreeRepo   *repo,
                     FlatpakRepoUpdateFlags flags,
                     const char  **gpg_key_ids,
                     const char   *gpg_homedir,
                     GCancellable *cancellable,
                     GError      **error)
{
  g_autoptr(GHashTable) commit_data_cache = NULL;
  g_autoptr(GVariant) compat_summary = NULL;
  g_autoptr(GVariant) summary_index = NULL;
  g_autoptr(GVariant) old_index = NULL;
  g_autoptr(GPtrArray) delta_names = NULL;
  g_auto(GStrv) summary_arches = NULL;
  g_autoptr(GHashTable) refs = NULL;
  g_autoptr(GHashTable) arches = NULL;
  g_autoptr(GHashTable) subsets = NULL;
  g_autoptr(GHashTable) summaries = NULL;
  g_autoptr(GHashTable) digested_summaries = NULL;
  g_autoptr(GHashTable) digested_summary_cache = NULL;
  g_autoptr(GBytes) index_sig = NULL;
  time_t old_compat_sig_mtime;
  GKeyFile *config;
  gboolean disable_index = (flags & FLATPAK_REPO_UPDATE_FLAG_DISABLE_INDEX) != 0;
  g_autofree char *index_digest = NULL;
  g_autofree char *old_index_digest = NULL;

  config = ostree_repo_get_config (repo);

  if (!ostree_repo_list_refs_ext (repo, NULL, &refs,
                                  OSTREE_REPO_LIST_REFS_EXT_EXCLUDE_REMOTES | OSTREE_REPO_LIST_REFS_EXT_EXCLUDE_MIRRORS,
                                  cancellable, error))
    return FALSE;

  old_index = flatpak_repo_load_summary_index (repo, NULL);
  if (old_index)
    commit_data_cache = populate_commit_data_cache (repo, old_index);

  if (commit_data_cache == NULL) /* No index or failed to load it */
    commit_data_cache = commit_data_cache_new ();

  if (!ostree_repo_list_static_delta_names (repo, &delta_names, cancellable, error))
    return FALSE;

  if (config)
    summary_arches = g_key_file_get_string_list (config, "flatpak", "summary-arches", NULL, NULL);

  summaries = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
  /* These are the ones we generated */
  digested_summaries = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify)g_variant_unref);
  /* These are the ones generated or references */
  digested_summary_cache = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify)g_variant_unref);

  arches = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
  subsets = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
  g_hash_table_add (subsets, g_strdup ("")); /* Always have everything subset */

  GLNX_HASH_TABLE_FOREACH_KV (refs, const char *, ref, const char *, rev)
    {
      g_autofree char *arch = flatpak_get_arch_for_ref (ref);
      CommitData *rev_data = NULL;

      if (arch != NULL &&
          !g_hash_table_contains (arches, arch))
        g_hash_table_add (arches, g_steal_pointer (&arch));

      /* Add CommitData for flatpak refs that we didn't already pre-populate */
      if (flatpak_is_app_runtime_or_appstream_ref (ref))
        {
          rev_data = g_hash_table_lookup (commit_data_cache, rev);
          if (rev_data == NULL)
            {
              rev_data = read_commit_data (repo, ref, rev, cancellable, error);
              if (rev_data == NULL)
                return FALSE;

              g_hash_table_insert (commit_data_cache, g_strdup (rev), (CommitData *)rev_data);
            }

          for (int i = 0; rev_data->subsets != NULL && i < rev_data->subsets->len; i++)
            {
              const char *subset = g_ptr_array_index (rev_data->subsets, i);
              if (!g_hash_table_contains (subsets, subset))
                g_hash_table_add (subsets, g_strdup (subset));
            }
        }
    }

  compat_summary = generate_summary (repo, TRUE, refs, commit_data_cache, delta_names,
                                     "", (const char **)summary_arches,
                                     cancellable, error);
  if (compat_summary == NULL)
    return FALSE;

  if (!disable_index)
    {
      GLNX_HASH_TABLE_FOREACH (subsets, const char *, subset)
        {
          GLNX_HASH_TABLE_FOREACH (arches, const char *, arch)
            {
              const char *arch_v[] = { arch, NULL };
              g_autofree char *name = NULL;
              g_autofree char *digest = NULL;

              if (*subset == 0)
                name = g_strdup (arch);
              else
                name = g_strconcat (subset, "-", arch, NULL);

              g_autoptr(GVariant) arch_summary = generate_summary (repo, FALSE, refs, commit_data_cache, NULL, subset, arch_v,
                                                                   cancellable, error);
              if (arch_summary == NULL)
                return FALSE;

              digest = flatpak_repo_save_digested_summary (repo, name, arch_summary, cancellable, error);
              if (digest == NULL)
                return FALSE;

              g_hash_table_insert (digested_summaries, g_strdup (digest), g_variant_ref (arch_summary));
              /* Prime summary cache with generated summaries */
              g_hash_table_insert (digested_summary_cache, g_strdup (digest), g_variant_ref (arch_summary));
              g_hash_table_insert (summaries, g_steal_pointer (&name), g_steal_pointer (&digest));
            }
        }

      summary_index = generate_summary_index (repo, old_index, summaries, digested_summaries, digested_summary_cache,
                                              gpg_key_ids, gpg_homedir,
                                              cancellable, error);
      if (summary_index == NULL)
        return FALSE;
    }

  if (!ostree_repo_static_delta_reindex (repo, 0, NULL, cancellable, error))
    return FALSE;

  if (summary_index && gpg_key_ids)
    {
      g_autoptr(GBytes) index_bytes = g_variant_get_data_as_bytes (summary_index);

      if (!ostree_repo_gpg_sign_data (repo, index_bytes,
                                      NULL,
                                      gpg_key_ids,
                                      gpg_homedir,
                                      &index_sig,
                                      cancellable,
                                      error))
        return FALSE;
    }

  if (summary_index)
    index_digest = g_compute_checksum_for_data (G_CHECKSUM_SHA256,
                                                g_variant_get_data (summary_index),
                                                g_variant_get_size (summary_index));
  if (old_index)
    old_index_digest = g_compute_checksum_for_data (G_CHECKSUM_SHA256,
                                                    g_variant_get_data (old_index),
                                                    g_variant_get_size (old_index));

  /* Release the memory-mapped summary index file before replacing it,
     to avoid failure on filesystems like cifs */
  g_clear_pointer (&old_index, g_variant_unref);

  if (!flatpak_repo_save_summary_index (repo, summary_index, index_digest, index_sig, cancellable, error))
    return FALSE;

  if (!flatpak_repo_save_compat_summary (repo, compat_summary, &old_compat_sig_mtime, cancellable, error))
    return FALSE;

  if (gpg_key_ids)
    {
      if (!ostree_repo_add_gpg_signature_summary (repo,
                                                  gpg_key_ids,
                                                  gpg_homedir,
                                                  cancellable,
                                                  error))
        return FALSE;


      if (old_compat_sig_mtime != 0)
        {
          int repo_dfd = ostree_repo_get_dfd (repo);
          struct stat stbuf;

          /* Ensure we increase (in sec precision) */
          if (fstatat (repo_dfd, "summary.sig", &stbuf, AT_SYMLINK_NOFOLLOW) == 0 &&
              stbuf.st_mtime <= old_compat_sig_mtime)
            {
              struct timespec ts[2] = { {0, UTIME_OMIT}, {old_compat_sig_mtime + 1, 0} };
              (void) utimensat (repo_dfd, "summary.sig", ts, AT_SYMLINK_NOFOLLOW);
            }
        }
    }

  if (!disable_index &&
      !flatpak_repo_gc_digested_summaries (repo, index_digest, old_index_digest, digested_summaries, digested_summary_cache, cancellable, error))
    return FALSE;

  return TRUE;
}

/* Wrapper that uses ostree_repo_resolve_collection_ref() and on failure falls
 * back to using ostree_repo_resolve_rev() for backwards compatibility. This
 * means we support refs/heads/, refs/remotes/, and refs/mirrors/. */
gboolean
flatpak_repo_resolve_rev (OstreeRepo    *repo,
                          const char    *collection_id, /* nullable */
                          const char    *remote_name, /* nullable */
                          const char    *ref_name,
                          gboolean       allow_noent,
                          char         **out_rev,
                          GCancellable  *cancellable,
                          GError       **error)
{
  g_autoptr(GError) local_error = NULL;

  if (collection_id != NULL)
    {
      /* Do a version check to ensure we have these:
       * https://github.com/ostreedev/ostree/pull/1821
       * https://github.com/ostreedev/ostree/pull/1825 */
#if OSTREE_CHECK_VERSION (2019, 2)
      const OstreeCollectionRef c_r =
        {
          .collection_id = (char *) collection_id,
          .ref_name = (char *) ref_name,
        };
      OstreeRepoResolveRevExtFlags flags = remote_name == NULL ?
                                           OSTREE_REPO_RESOLVE_REV_EXT_LOCAL_ONLY :
                                           OSTREE_REPO_RESOLVE_REV_EXT_NONE;
      if (ostree_repo_resolve_collection_ref (repo, &c_r,
                                              allow_noent,
                                              flags,
                                              out_rev,
                                              cancellable, NULL))
        return TRUE;
#endif
    }

  /* There may be several remotes with the same branch (if we for
   * instance changed the origin) so prepend the current origin to
   * make sure we get the right one */
  if (remote_name != NULL)
    {
      g_autofree char *refspec = g_strdup_printf ("%s:%s", remote_name, ref_name);
      ostree_repo_resolve_rev (repo, refspec, allow_noent, out_rev, &local_error);
    }
  else
    ostree_repo_resolve_rev_ext (repo, ref_name, allow_noent,
                                 OSTREE_REPO_RESOLVE_REV_EXT_NONE, out_rev, &local_error);

  if (local_error != NULL)
    {
      if (g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
        flatpak_fail_error (error, FLATPAK_ERROR_REF_NOT_FOUND, "%s", local_error->message);
      else
        g_propagate_error (error, g_steal_pointer (&local_error));

      return FALSE;
    }

  return TRUE;
}

/* This special cases the ref lookup which by doing a
   bsearch since the array is sorted */
gboolean
flatpak_var_ref_map_lookup_ref (VarRefMapRef   ref_map,
                                const char    *ref,
                                VarRefInfoRef *out_info)
{
  gsize imax, imin;
  gsize imid;
  gsize n;

  g_return_val_if_fail (out_info != NULL, FALSE);

  n = var_ref_map_get_length (ref_map);
  if (n == 0)
    return FALSE;

  imax = n - 1;
  imin = 0;
  while (imax >= imin)
    {
      VarRefMapEntryRef entry;
      const char *cur;
      int cmp;

      imid = (imin + imax) / 2;

      entry = var_ref_map_get_at (ref_map, imid);
      cur = var_ref_map_entry_get_ref (entry);

      cmp = strcmp (cur, ref);
      if (cmp < 0)
        {
          imin = imid + 1;
        }
      else if (cmp > 0)
        {
          if (imid == 0)
            break;
          imax = imid - 1;
        }
      else
        {
          *out_info = var_ref_map_entry_get_info (entry);
          return TRUE;
        }
    }

  return FALSE;
}

/* Find the list of refs which belong to the given @collection_id in @summary.
 * If @collection_id is %NULL, the main refs list from the summary will be
 * returned. If @collection_id doesn’t match any collection IDs in the summary
 * file, %FALSE will be returned. */
gboolean
flatpak_summary_find_ref_map (VarSummaryRef summary,
                              const char *collection_id,
                              VarRefMapRef *refs_out)
{
  VarMetadataRef metadata = var_summary_get_metadata (summary);
  const char *summary_collection_id;

  summary_collection_id = var_metadata_lookup_string (metadata, "ostree.summary.collection-id", NULL);

  if (collection_id == NULL || g_strcmp0 (collection_id, summary_collection_id) == 0)
    {
      if (refs_out)
        *refs_out = var_summary_get_ref_map (summary);
      return TRUE;
    }
  else if (collection_id != NULL)
    {
      VarVariantRef collection_map_v;
      if (var_metadata_lookup (metadata, "ostree.summary.collection-map", NULL, &collection_map_v))
        {
          VarCollectionMapRef collection_map = var_collection_map_from_variant (collection_map_v);
          return var_collection_map_lookup (collection_map, collection_id, NULL, refs_out);
        }
    }

  return FALSE;
}

/* This matches all refs from @collection_id that have ref, followed by '.'  as prefix */
GPtrArray *
flatpak_summary_match_subrefs (GVariant          *summary_v,
                               const char        *collection_id,
                               FlatpakDecomposed *ref)
{
  GPtrArray *res = g_ptr_array_new_with_free_func ((GDestroyNotify)flatpak_decomposed_unref);
  gsize n, i;
  g_autofree char *parts_prefix = NULL;
  g_autofree char *ref_prefix = NULL;
  g_autofree char *ref_suffix = NULL;
  VarSummaryRef summary;
  VarRefMapRef ref_map;

  summary = var_summary_from_gvariant (summary_v);

  /* Work out which refs list to use, based on the @collection_id. */
  if (flatpak_summary_find_ref_map (summary, collection_id, &ref_map))
    {
      /* Match against the refs. */
      g_autofree char *id = flatpak_decomposed_dup_id (ref);
      g_autofree char *arch = flatpak_decomposed_dup_arch (ref);
      g_autofree char *branch = flatpak_decomposed_dup_branch (ref);
      parts_prefix = g_strconcat (id, ".", NULL);

      ref_prefix = g_strconcat (flatpak_decomposed_get_kind_str (ref), "/", NULL);
      ref_suffix = g_strconcat ("/", arch, "/", branch, NULL);

      n = var_ref_map_get_length (ref_map);
      for (i = 0; i < n; i++)
        {
          VarRefMapEntryRef entry = var_ref_map_get_at (ref_map, i);
          const char *cur;
          const char *id_start;
          const char *id_suffix;
          const char *id_end;

          cur = var_ref_map_entry_get_ref (entry);

          /* Must match type */
          if (!g_str_has_prefix (cur, ref_prefix))
            continue;

          /* Must match arch & branch */
          if (!g_str_has_suffix (cur, ref_suffix))
            continue;

          id_start = strchr (cur, '/');
          if (id_start == NULL)
            continue;
          id_start += 1;

          id_end = strchr (id_start, '/');
          if (id_end == NULL)
            continue;

          /* But only prefix of id */
          if (!g_str_has_prefix (id_start, parts_prefix))
            continue;

          /* And no dots (we want to install prefix.$ID, but not prefix.$ID.Sources) */
          id_suffix = id_start + strlen (parts_prefix);
          if (memchr (id_suffix, '.', id_end - id_suffix) != NULL)
            continue;

          FlatpakDecomposed *d = flatpak_decomposed_new_from_ref (cur, NULL);
          if (d)
            g_ptr_array_add (res, d);
        }
    }

  return g_steal_pointer (&res);
}

gboolean
flatpak_summary_lookup_ref (GVariant      *summary_v,
                            const char    *collection_id,
                            const char    *ref,
                            char         **out_checksum,
                            VarRefInfoRef *out_info)
{
  VarSummaryRef summary;
  VarRefMapRef ref_map;
  VarRefInfoRef info;
  const guchar *checksum_bytes;
  gsize checksum_bytes_len;

  summary = var_summary_from_gvariant (summary_v);

  /* Work out which refs list to use, based on the @collection_id. */
  if (!flatpak_summary_find_ref_map (summary, collection_id, &ref_map))
    return FALSE;

  if (!flatpak_var_ref_map_lookup_ref (ref_map, ref, &info))
    return FALSE;

  checksum_bytes = var_ref_info_peek_checksum (info, &checksum_bytes_len);
  if (G_UNLIKELY (checksum_bytes_len != OSTREE_SHA256_DIGEST_LEN))
    return FALSE;

  if (out_checksum)
    *out_checksum = ostree_checksum_from_bytes (checksum_bytes);

  if (out_info)
    *out_info = info;

  return TRUE;
}

GKeyFile *
flatpak_parse_repofile (const char   *remote_name,
                        gboolean      from_ref,
                        GKeyFile     *keyfile,
                        GBytes      **gpg_data_out,
                        GCancellable *cancellable,
                        GError      **error)
{
  g_autoptr(GBytes) gpg_data = NULL;
  g_autofree char *uri = NULL;
  g_autofree char *title = NULL;
  g_autofree char *gpg_key = NULL;
  g_autofree char *signature_lookaside = NULL;
  g_autofree char *collection_id = NULL;
  g_autofree char *default_branch = NULL;
  g_autofree char *comment = NULL;
  g_autofree char *description = NULL;
  g_autofree char *icon = NULL;
  g_autofree char *homepage = NULL;
  g_autofree char *filter = NULL;
  g_autofree char *subset = NULL;
  g_autofree char *authenticator_name = NULL;
  gboolean nodeps;
  const char *source_group;
  g_autofree char *version = NULL;

  if (from_ref)
    source_group = FLATPAK_REF_GROUP;
  else
    source_group = FLATPAK_REPO_GROUP;

  GKeyFile *config = g_key_file_new ();
  g_autofree char *group = g_strdup_printf ("remote \"%s\"", remote_name);

  if (!g_key_file_has_group (keyfile, source_group))
    {
      flatpak_fail_error (error, FLATPAK_ERROR_INVALID_DATA, _("Invalid %s: Missing group ‘%s’"),
                          from_ref ? ".flatpakref" : ".flatpakrepo", source_group);
      return NULL;
    }

  uri = g_key_file_get_string (keyfile, source_group,
                               FLATPAK_REPO_URL_KEY, NULL);
  if (uri == NULL)
    {
      flatpak_fail_error (error, FLATPAK_ERROR_INVALID_DATA, _("Invalid %s: Missing key ‘%s’"),
                          from_ref ? ".flatpakref" : ".flatpakrepo", FLATPAK_REPO_URL_KEY);
      return NULL;
    }

  version = g_key_file_get_string (keyfile, FLATPAK_REPO_GROUP,
                                   FLATPAK_REPO_VERSION_KEY, NULL);
  if (version != NULL && strcmp (version, "1") != 0)
    {
      flatpak_fail_error (error, FLATPAK_ERROR_INVALID_DATA,
                          _("Invalid version %s, only 1 supported"), version);
      return NULL;
    }

  g_key_file_set_string (config, group, "url", uri);

  subset = g_key_file_get_locale_string (keyfile, source_group,
                                         FLATPAK_REPO_SUBSET_KEY, NULL, NULL);
  if (subset != NULL)
    g_key_file_set_string (config, group, "xa.subset", subset);

  /* Don't use the title from flatpakref files; that's the title of the app */
  if (!from_ref)
    title = g_key_file_get_locale_string (keyfile, FLATPAK_REPO_GROUP,
                                          FLATPAK_REPO_TITLE_KEY, NULL, NULL);
  if (title != NULL)
    g_key_file_set_string (config, group, "xa.title", title);

  default_branch = g_key_file_get_locale_string (keyfile, source_group,
                                                 FLATPAK_REPO_DEFAULT_BRANCH_KEY, NULL, NULL);
  if (default_branch != NULL)
    g_key_file_set_string (config, group, "xa.default-branch", default_branch);

  nodeps = g_key_file_get_boolean (keyfile, source_group,
                                   FLATPAK_REPO_NODEPS_KEY, NULL);
  if (nodeps)
    g_key_file_set_boolean (config, group, "xa.nodeps", TRUE);

  gpg_key = g_key_file_get_string (keyfile, source_group,
                                   FLATPAK_REPO_GPGKEY_KEY, NULL);
  if (gpg_key != NULL)
    {
      guchar *decoded;
      gsize decoded_len;

      gpg_key = g_strstrip (gpg_key);
      decoded = g_base64_decode (gpg_key, &decoded_len);
      if (decoded_len < 10) /* Check some minimal size so we don't get crap */
        {
          g_free (decoded);
          flatpak_fail_error (error, FLATPAK_ERROR_INVALID_DATA, _("Invalid gpg key"));
          return NULL;
        }

      gpg_data = g_bytes_new_take (decoded, decoded_len);
      g_key_file_set_boolean (config, group, "gpg-verify", TRUE);
    }
  else
    {
      g_key_file_set_boolean (config, group, "gpg-verify", FALSE);
    }

  signature_lookaside = g_key_file_get_string (keyfile, source_group,
                                               FLATPAK_REPO_SIGNATURE_LOOKASIDE_KEY, NULL);
  if (signature_lookaside != NULL)
    g_key_file_set_string (config, group, "xa.signature-lookaside", signature_lookaside);

  /* We have a hierarchy of keys for setting the collection ID, which all have
   * the same effect. The only difference is which versions of Flatpak support
   * them, and therefore what P2P implementation is enabled by them:
   * DeploySideloadCollectionID: supported by Flatpak >= 1.12.8 (1.7.1
   *   introduced sideload support but this key was added late)
   * DeployCollectionID: supported by Flatpak >= 1.0.6 (but fully supported in
   *   >= 1.2.0)
   * CollectionID: supported by Flatpak >= 0.9.8
   */
  collection_id = flatpak_keyfile_get_string_non_empty (keyfile, source_group,
                                                        FLATPAK_REPO_DEPLOY_SIDELOAD_COLLECTION_ID_KEY);
  if (collection_id == NULL)
    collection_id = flatpak_keyfile_get_string_non_empty (keyfile, source_group,
                                                          FLATPAK_REPO_DEPLOY_COLLECTION_ID_KEY);
  if (collection_id == NULL)
    collection_id = flatpak_keyfile_get_string_non_empty (keyfile, source_group,
                                                          FLATPAK_REPO_COLLECTION_ID_KEY);
  if (collection_id != NULL)
    {
      /* We don't support signatures for OCI remotes, but Collection ID's are
       * still useful for preinstallation.
       */
      if (gpg_key == NULL && !g_str_has_prefix (uri, "oci+"))
        {
          flatpak_fail_error (error, FLATPAK_ERROR_INVALID_DATA, _("Collection ID requires GPG key to be provided"));
          return NULL;
        }

      g_key_file_set_string (config, group, "collection-id", collection_id);
    }

  g_key_file_set_boolean (config, group, "gpg-verify-summary",
                          (gpg_key != NULL));

  authenticator_name = g_key_file_get_string (keyfile, FLATPAK_REPO_GROUP,
                                              FLATPAK_REPO_AUTHENTICATOR_NAME_KEY, NULL);
  if (authenticator_name)
    g_key_file_set_string (config, group, "xa.authenticator-name", authenticator_name);

  if (g_key_file_has_key (keyfile, FLATPAK_REPO_GROUP, FLATPAK_REPO_AUTHENTICATOR_INSTALL_KEY, NULL))
    {
      gboolean authenticator_install = g_key_file_get_boolean (keyfile, FLATPAK_REPO_GROUP,
                                                               FLATPAK_REPO_AUTHENTICATOR_INSTALL_KEY, NULL);
      g_key_file_set_boolean (config, group, "xa.authenticator-install", authenticator_install);
    }

  comment = g_key_file_get_string (keyfile, FLATPAK_REPO_GROUP,
                                   FLATPAK_REPO_COMMENT_KEY, NULL);
  if (comment)
    g_key_file_set_string (config, group, "xa.comment", comment);

  description = g_key_file_get_string (keyfile, FLATPAK_REPO_GROUP,
                                       FLATPAK_REPO_DESCRIPTION_KEY, NULL);
  if (description)
    g_key_file_set_string (config, group, "xa.description", description);

  icon = g_key_file_get_string (keyfile, FLATPAK_REPO_GROUP,
                                FLATPAK_REPO_ICON_KEY, NULL);
  if (icon)
    g_key_file_set_string (config, group, "xa.icon", icon);

  homepage  = g_key_file_get_string (keyfile, FLATPAK_REPO_GROUP,
                                     FLATPAK_REPO_HOMEPAGE_KEY, NULL);
  if (homepage)
    g_key_file_set_string (config, group, "xa.homepage", homepage);

  filter = g_key_file_get_string (keyfile, FLATPAK_REPO_GROUP,
                                   FLATPAK_REPO_FILTER_KEY, NULL);
  if (filter)
    g_key_file_set_string (config, group, "xa.filter", filter);
  else
    g_key_file_set_string (config, group, "xa.filter", ""); /* Default to override any pre-existing filters */

  *gpg_data_out = g_steal_pointer (&gpg_data);

  return g_steal_pointer (&config);
}

gboolean
flatpak_mtree_create_dir (OstreeRepo         *repo,
                          OstreeMutableTree  *parent,
                          const char         *name,
                          OstreeMutableTree **dir_out,
                          GError            **error)
{
  g_autoptr(OstreeMutableTree) dir = NULL;

  if (!ostree_mutable_tree_ensure_dir (parent, name, &dir, error))
    return FALSE;

  if (!flatpak_mtree_ensure_dir_metadata (repo, dir, NULL, error))
    return FALSE;

  *dir_out = g_steal_pointer (&dir);
  return TRUE;
}

gboolean
flatpak_mtree_create_symlink (OstreeRepo         *repo,
                              OstreeMutableTree  *parent,
                              const char         *filename,
                              const char         *target,
                              GError            **error)
{
  g_autoptr(GFileInfo) file_info = g_file_info_new ();
  g_autoptr(GInputStream) content_stream = NULL;
  g_autofree guchar *raw_checksum = NULL;
  g_autofree char *checksum = NULL;
  guint64 length;

  g_file_info_set_name (file_info, filename);
  g_file_info_set_file_type (file_info, G_FILE_TYPE_SYMBOLIC_LINK);
  g_file_info_set_size (file_info, 0);
  g_file_info_set_attribute_uint32 (file_info, "unix::uid", 0);
  g_file_info_set_attribute_uint32 (file_info, "unix::gid", 0);
  g_file_info_set_attribute_uint32 (file_info, "unix::mode", S_IFLNK | 0777);

  g_file_info_set_attribute_boolean (file_info, "standard::is-symlink", TRUE);
  g_file_info_set_attribute_byte_string (file_info, "standard::symlink-target", target);

  if (!ostree_raw_file_to_content_stream (NULL, file_info, NULL,
                                          &content_stream, &length,
                                          NULL, error))
    return FALSE;

  if (!ostree_repo_write_content (repo, NULL, content_stream, length,
                                  &raw_checksum, NULL, error))
    return FALSE;

  checksum = ostree_checksum_from_bytes (raw_checksum);

  if (!ostree_mutable_tree_replace_file (parent, filename, checksum, error))
    return FALSE;

  return TRUE;
}

gboolean
flatpak_mtree_add_file_from_bytes (OstreeRepo *repo,
                                   GBytes *bytes,
                                   OstreeMutableTree *parent,
                                   const char *filename,
                                   GCancellable *cancellable,
                                   GError      **error)
{
  g_autoptr(GFileInfo) info = g_file_info_new ();
  g_autoptr(GInputStream) memstream = NULL;
  g_autoptr(GInputStream) content_stream = NULL;
  g_autofree guchar *raw_checksum = NULL;
  g_autofree char *checksum = NULL;
  guint64 length;

  g_file_info_set_attribute_uint32 (info, "standard::type", G_FILE_TYPE_REGULAR);
  g_file_info_set_attribute_uint64 (info, "standard::size", g_bytes_get_size (bytes));
  g_file_info_set_attribute_uint32 (info, "unix::uid", 0);
  g_file_info_set_attribute_uint32 (info, "unix::gid", 0);
  g_file_info_set_attribute_uint32 (info, "unix::mode", S_IFREG | 0644);

  memstream = g_memory_input_stream_new_from_bytes (bytes);

  if (!ostree_raw_file_to_content_stream (memstream, info, NULL,
                                          &content_stream, &length,
                                          cancellable, error))
    return FALSE;

  if (!ostree_repo_write_content (repo, NULL, content_stream, length,
                                  &raw_checksum, cancellable, error))
    return FALSE;

  checksum = ostree_checksum_from_bytes (raw_checksum);

  if (!ostree_mutable_tree_replace_file (parent, filename, checksum, error))
    return FALSE;

  return TRUE;
}

gboolean
flatpak_mtree_ensure_dir_metadata (OstreeRepo        *repo,
                                   OstreeMutableTree *mtree,
                                   GCancellable      *cancellable,
                                   GError           **error)
{
  g_autoptr(GVariant) dirmeta = NULL;
  g_autoptr(GFileInfo) file_info = g_file_info_new ();
  g_autofree guchar *csum = NULL;
  g_autofree char *checksum = NULL;

  g_file_info_set_name (file_info, "/");
  g_file_info_set_file_type (file_info, G_FILE_TYPE_DIRECTORY);
  g_file_info_set_attribute_uint32 (file_info, "unix::uid", 0);
  g_file_info_set_attribute_uint32 (file_info, "unix::gid", 0);
  g_file_info_set_attribute_uint32 (file_info, "unix::mode", 040755);

  dirmeta = ostree_create_directory_metadata (file_info, NULL);
  if (!ostree_repo_write_metadata (repo, OSTREE_OBJECT_TYPE_DIR_META, NULL,
                                   dirmeta, &csum, cancellable, error))
    return FALSE;

  checksum = ostree_checksum_from_bytes (csum);
  ostree_mutable_tree_set_metadata_checksum (mtree, checksum);

  return TRUE;
}

static gboolean
copy_icon (const char        *id,
           GFile             *icons_dir,
           OstreeRepo        *repo,
           OstreeMutableTree *size_mtree,
           const char        *size,
           GError           **error)
{
  g_autofree char *icon_name = g_strconcat (id, ".png", NULL);
  g_autoptr(GFile) size_dir = g_file_get_child (icons_dir, size);
  g_autoptr(GFile) icon_file = g_file_get_child (size_dir, icon_name);
  const char *checksum;

  if (!ostree_repo_file_ensure_resolved (OSTREE_REPO_FILE(icon_file), NULL))
    {
      g_info ("No icon at size %s for %s", size, id);
      return TRUE;
    }

  checksum = ostree_repo_file_get_checksum (OSTREE_REPO_FILE(icon_file));
  if (!ostree_mutable_tree_replace_file (size_mtree, icon_name, checksum, error))
    return FALSE;

  return TRUE;
}

static gboolean
extract_appstream (OstreeRepo        *repo,
                   FlatpakXml        *appstream_root,
                   FlatpakDecomposed *ref,
                   const char        *id,
                   OstreeMutableTree *size1_mtree,
                   OstreeMutableTree *size2_mtree,
                   GCancellable       *cancellable,
                   GError            **error)
{
  g_autoptr(GFile) root = NULL;
  g_autoptr(GFile) app_info_dir = NULL;
  g_autoptr(GFile) xmls_dir = NULL;
  g_autoptr(GFile) icons_dir = NULL;
  g_autoptr(GFile) appstream_file = NULL;
  g_autoptr(GFile) metadata = NULL;
  g_autofree char *appstream_basename = NULL;
  g_autoptr(GInputStream) in = NULL;
  g_autoptr(FlatpakXml) xml_root = NULL;
  g_autoptr(GKeyFile) keyfile = NULL;

  if (!ostree_repo_read_commit (repo, flatpak_decomposed_get_ref (ref), &root, NULL, NULL, error))
    return FALSE;

  keyfile = g_key_file_new ();
  metadata = g_file_get_child (root, "metadata");
  if (g_file_query_exists (metadata, cancellable))
    {
      g_autofree char *content = NULL;
      gsize len;

      if (!g_file_load_contents (metadata, cancellable, &content, &len, NULL, error))
        return FALSE;

      if (!g_key_file_load_from_data (keyfile, content, len, G_KEY_FILE_NONE, error))
        return FALSE;
    }

  app_info_dir = g_file_resolve_relative_path (root, "files/share/app-info");

  xmls_dir = g_file_resolve_relative_path (app_info_dir, "xmls");
  icons_dir = g_file_resolve_relative_path (app_info_dir, "icons/flatpak");

  appstream_basename = g_strconcat (id, ".xml.gz", NULL);
  appstream_file = g_file_get_child (xmls_dir, appstream_basename);

  in = (GInputStream *) g_file_read (appstream_file, cancellable, error);
  if (!in)
    return FALSE;

  xml_root = flatpak_xml_parse (in, TRUE, cancellable, error);
  if (xml_root == NULL)
    return FALSE;

  if (flatpak_appstream_xml_migrate (xml_root, appstream_root,
                                     flatpak_decomposed_get_ref (ref), id, keyfile))
    {
      g_autoptr(GError) my_error = NULL;
      FlatpakXml *components = appstream_root->first_child;
      FlatpakXml *component = components->first_child;

      while (component != NULL)
        {
          FlatpakXml *component_id, *component_id_text_node;
          g_autofree char *component_id_text = NULL;
          char *component_id_suffix;

          if (g_strcmp0 (component->element_name, "component") != 0)
            {
              component = component->next_sibling;
              continue;
            }

          component_id = flatpak_xml_find (component, "id", NULL);
          component_id_text_node = flatpak_xml_find (component_id, NULL, NULL);

          component_id_text = g_strstrip (g_strdup (component_id_text_node->text));

          /* We're looking for a component that matches the app-id (id), but it
             may have some further elements (separated by dot) and can also have
             ".desktop" at the end which we need to strip out. Further complicating
             things, some actual app ids ends in .desktop, such as org.telegram.desktop. */

          component_id_suffix = component_id_text + strlen (id); /* Don't deref before we check for prefix match! */
          if (!g_str_has_prefix (component_id_text, id) ||
              (component_id_suffix[0] != 0 && component_id_suffix[0] != '.'))
            {
              component = component->next_sibling;
              continue;
            }

          if (!copy_icon (component_id_text, icons_dir, repo, size1_mtree, "64x64", &my_error))
            {
              g_print (_("Error copying 64x64 icon for component %s: %s\n"), component_id_text, my_error->message);
              g_clear_error (&my_error);
            }

          if (!copy_icon (component_id_text, icons_dir, repo, size2_mtree, "128x128", &my_error))
             {
               g_print (_("Error copying 128x128 icon for component %s: %s\n"), component_id_text, my_error->message);
               g_clear_error (&my_error);
             }


          /* We might match other prefixes, so keep on going */
          component = component->next_sibling;
        }
    }

  return TRUE;
}

/* This is similar to ostree_repo_list_refs(), but returns only valid flatpak
 * refs, as FlatpakDecomposed. */
static GHashTable *
flatpak_repo_list_flatpak_refs (OstreeRepo   *repo,
                                GCancellable *cancellable,
                                GError      **error)
{
  g_autoptr(GHashTable) refspecs = NULL;
  g_autoptr(GHashTable) refs = NULL;
  GHashTableIter iter;
  gpointer key, value;

  if (!ostree_repo_list_refs_ext (repo, NULL, &refspecs,
                                  OSTREE_REPO_LIST_REFS_EXT_EXCLUDE_REMOTES | OSTREE_REPO_LIST_REFS_EXT_EXCLUDE_MIRRORS,
                                  cancellable, error))
    return NULL;

  refs = g_hash_table_new_full ((GHashFunc)flatpak_decomposed_hash, (GEqualFunc)flatpak_decomposed_equal, (GDestroyNotify)flatpak_decomposed_unref, g_free);

  g_hash_table_iter_init (&iter, refspecs);
  while (g_hash_table_iter_next (&iter, &key, &value))
    {
      const char *refstr = key;
      const char *checksum = value;
      FlatpakDecomposed *ref = NULL;

      ref = flatpak_decomposed_new_from_ref_take ((char *)refstr, NULL);
      if (ref)
        {
          g_hash_table_iter_steal (&iter);
          g_hash_table_insert (refs, ref, (char *)checksum);
        }
    }

  return g_steal_pointer (&refs);
}

static gboolean
_flatpak_repo_generate_appstream (OstreeRepo   *repo,
                                  const char  **gpg_key_ids,
                                  const char   *gpg_homedir,
                                  FlatpakDecomposed **all_refs_keys,
                                  guint         n_keys,
                                  GHashTable   *all_commits,
                                  const char   *arch,
                                  const char   *subset,
                                  guint64       timestamp,
                                  GCancellable *cancellable,
                                  GError      **error)
{
  g_autoptr(FlatpakXml) appstream_root = NULL;
  g_autoptr(GBytes) xml_data = NULL;
  g_autoptr(GBytes) xml_gz_data = NULL;
  g_autoptr(OstreeMutableTree) mtree = ostree_mutable_tree_new ();
  g_autoptr(OstreeMutableTree) icons_mtree = NULL;
  g_autoptr(OstreeMutableTree) icons_flatpak_mtree = NULL;
  g_autoptr(OstreeMutableTree) size1_mtree = NULL;
  g_autoptr(OstreeMutableTree) size2_mtree = NULL;
  const char *compat_arch;
  compat_arch = flatpak_get_compat_arch (arch);
  const char *branch_names[] = { "appstream", "appstream2" };
  const char *collection_id;

  if (subset != NULL && *subset != 0)
    g_info ("Generating appstream for %s, subset %s", arch, subset);
  else
    g_info ("Generating appstream for %s", arch);

  collection_id = ostree_repo_get_collection_id (repo);

  if (!flatpak_mtree_ensure_dir_metadata (repo, mtree, cancellable, error))
    return FALSE;

  if (!flatpak_mtree_create_dir (repo, mtree, "icons", &icons_mtree, error))
    return FALSE;

  if (!flatpak_mtree_create_dir (repo, icons_mtree, "64x64", &size1_mtree, error))
    return FALSE;

  if (!flatpak_mtree_create_dir (repo, icons_mtree, "128x128", &size2_mtree, error))
    return FALSE;

  /* For compatibility with libappstream we create a $origin ("flatpak") subdirectory with symlinks
   * to the size directories thus matching the standard merged appstream layout if we assume the
   * appstream has origin=flatpak, which flatpak-builder creates.
   *
   * See https://github.com/ximion/appstream/pull/224 for details.
   */
  if (!flatpak_mtree_create_dir (repo, icons_mtree, "flatpak", &icons_flatpak_mtree, error))
    return FALSE;
  if (!flatpak_mtree_create_symlink (repo, icons_flatpak_mtree, "64x64", "../64x64", error))
    return FALSE;
  if (!flatpak_mtree_create_symlink (repo, icons_flatpak_mtree, "128x128", "../128x128", error))
    return FALSE;

  appstream_root = flatpak_appstream_xml_new ();

  for (int i = 0; i < n_keys; i++)
    {
      FlatpakDecomposed *ref = all_refs_keys[i];
      GVariant *commit_v = NULL;
      VarMetadataRef commit_metadata;
      g_autoptr(GError) my_error = NULL;
      g_autofree char *id = NULL;

      if (!flatpak_decomposed_is_arch (ref, arch))
        {
          g_autoptr(FlatpakDecomposed) main_ref = NULL;

          /* Include refs that don't match the main arch (e.g. x86_64), if they match
             the compat arch (e.g. i386) and the main arch version is not in the repo */
          if (compat_arch != NULL && flatpak_decomposed_is_arch (ref, compat_arch))
            main_ref = flatpak_decomposed_new_from_decomposed (ref, 0, NULL, compat_arch, NULL, NULL);

          if (main_ref == NULL ||
              g_hash_table_lookup (all_commits, main_ref))
            continue;
        }

      commit_v = g_hash_table_lookup (all_commits, ref);
      g_assert (commit_v != NULL);

      commit_metadata = var_commit_get_metadata (var_commit_from_gvariant (commit_v));
      if (var_metadata_lookup (commit_metadata, OSTREE_COMMIT_META_KEY_ENDOFLIFE, NULL, NULL) ||
          var_metadata_lookup (commit_metadata, OSTREE_COMMIT_META_KEY_ENDOFLIFE_REBASE, NULL, NULL))
        {
          g_info (_("%s is end-of-life, ignoring for appstream"), flatpak_decomposed_get_ref (ref));
          continue;
        }

      if (*subset != 0)
        {
          VarVariantRef xa_subsets_v;
          gboolean in_subset = FALSE;

          if (var_metadata_lookup (commit_metadata, "xa.subsets", NULL, &xa_subsets_v))
            {
              VarArrayofstringRef xa_subsets = var_arrayofstring_from_variant (xa_subsets_v);
              gsize len = var_arrayofstring_get_length (xa_subsets);

              for (gsize j = 0; j < len; j++)
                {
                  const char *xa_subset = var_arrayofstring_get_at (xa_subsets, j);
                  if (strcmp (subset, xa_subset) == 0)
                    {
                      in_subset = TRUE;
                      break;
                    }
                }
            }

          if (!in_subset)
            continue;
        }

      id = flatpak_decomposed_dup_id (ref);
      if (!extract_appstream (repo, appstream_root,
                              ref, id, size1_mtree, size2_mtree,
                              cancellable, &my_error))
        {
          if (flatpak_decomposed_is_app (ref))
            g_print (_("No appstream data for %s: %s\n"), flatpak_decomposed_get_ref (ref), my_error->message);
          continue;
        }
    }

  if (!flatpak_appstream_xml_root_to_data (appstream_root, &xml_data, &xml_gz_data, error))
    return FALSE;

  for (int i = 0; i < G_N_ELEMENTS (branch_names); i++)
    {
      gboolean skip_commit = FALSE;
      const char *branch_prefix = branch_names[i];
      g_autoptr(GFile) root = NULL;
      g_autofree char *branch = NULL;
      g_autofree char *parent = NULL;
      g_autofree char *commit_checksum = NULL;

      if (*subset != 0 && i == 0)
        continue; /* No old-style branch for subsets */

      if (*subset != 0)
        branch = g_strdup_printf ("%s/%s-%s", branch_prefix, subset, arch);
      else
        branch = g_strdup_printf ("%s/%s", branch_prefix, arch);

      if (!flatpak_repo_resolve_rev (repo, collection_id, NULL, branch, TRUE,
                                     &parent, cancellable, error))
        return FALSE;

      if (i == 0)
        {
          if (!flatpak_mtree_add_file_from_bytes (repo, xml_gz_data, mtree, "appstream.xml.gz", cancellable, error))
            return FALSE;
        }
      else
        {
          if (!ostree_mutable_tree_remove (mtree, "appstream.xml.gz", TRUE, error))
            return FALSE;

          if (!flatpak_mtree_add_file_from_bytes (repo, xml_data, mtree, "appstream.xml", cancellable, error))
            return FALSE;
        }

      if (!ostree_repo_write_mtree (repo, mtree, &root, cancellable, error))
        return FALSE;

      /* No need to commit if nothing changed */
      if (parent)
        {
          g_autoptr(GFile) parent_root = NULL;

          if (!ostree_repo_read_commit (repo, parent, &parent_root, NULL, cancellable, error))
            return FALSE;

          if (g_file_equal (root, parent_root))
            {
              skip_commit = TRUE;
              g_info ("Not updating %s, no change", branch);
            }
        }

      if (!skip_commit)
        {
          g_autoptr(GVariantDict) metadata_dict = NULL;
          g_autoptr(GVariant) metadata = NULL;

          /* Add bindings to the metadata. Do this even if P2P support is not
           * enabled, as it might be enable for other flatpak builds. */
          metadata_dict = g_variant_dict_new (NULL);
          g_variant_dict_insert (metadata_dict, "ostree.collection-binding",
                                 "s", (collection_id != NULL) ? collection_id : "");
          g_variant_dict_insert_value (metadata_dict, "ostree.ref-binding",
                                       g_variant_new_strv ((const gchar * const *) &branch, 1));
          metadata = g_variant_ref_sink (g_variant_dict_end (metadata_dict));

          if (timestamp > 0)
            {
              if (!ostree_repo_write_commit_with_time (repo, parent, "Update", NULL, metadata,
                                                       OSTREE_REPO_FILE (root),
                                                       timestamp,
                                                       &commit_checksum,
                                                       cancellable, error))
                return FALSE;
            }
          else
            {
              if (!ostree_repo_write_commit (repo, parent, "Update", NULL, metadata,
                                             OSTREE_REPO_FILE (root),
                                             &commit_checksum, cancellable, error))
                return FALSE;
            }

          if (gpg_key_ids)
            {
              for (int j = 0; gpg_key_ids[j] != NULL; j++)
                {
                  const char *keyid = gpg_key_ids[j];

                  if (!ostree_repo_sign_commit (repo,
                                                commit_checksum,
                                                keyid,
                                                gpg_homedir,
                                                cancellable,
                                                error))
                    return FALSE;
                }
            }

          g_info ("Creating appstream branch %s", branch);
          if (collection_id != NULL)
            {
              const OstreeCollectionRef collection_ref = { (char *) collection_id, branch };
              ostree_repo_transaction_set_collection_ref (repo, &collection_ref, commit_checksum);
            }
          else
            {
              ostree_repo_transaction_set_ref (repo, NULL, branch, commit_checksum);
            }
        }
    }

  return TRUE;
}

gboolean
flatpak_repo_generate_appstream (OstreeRepo   *repo,
                                 const char  **gpg_key_ids,
                                 const char   *gpg_homedir,
                                 guint64       timestamp,
                                 GCancellable *cancellable,
                                 GError      **error)
{
  g_autoptr(GHashTable) all_refs = NULL;
  g_autoptr(GHashTable) all_commits = NULL;
  g_autofree FlatpakDecomposed **all_refs_keys = NULL;
  guint n_keys;
  g_autoptr(GPtrArray) arches = NULL;  /* (element-type utf8 utf8) */
  g_autoptr(GPtrArray) subsets = NULL;  /* (element-type utf8 utf8) */
  g_autoptr(FlatpakRepoTransaction) transaction = NULL;
  OstreeRepoTransactionStats stats;

  arches = g_ptr_array_new_with_free_func (g_free);
  subsets = g_ptr_array_new_with_free_func (g_free);

  g_ptr_array_add (subsets, g_strdup (""));

  all_refs = flatpak_repo_list_flatpak_refs (repo, cancellable, error);
  if (all_refs == NULL)
    return FALSE;

  all_commits = g_hash_table_new_full ((GHashFunc)flatpak_decomposed_hash, (GEqualFunc)flatpak_decomposed_equal, (GDestroyNotify)flatpak_decomposed_unref, (GDestroyNotify)g_variant_unref);

  GLNX_HASH_TABLE_FOREACH_KV (all_refs, FlatpakDecomposed *, ref, const char *, commit)
    {
      VarMetadataRef commit_metadata;
      VarVariantRef xa_subsets_v;
      const char *reverse_compat_arch;
      char *new_arch = NULL;
      g_autoptr(GVariant) commit_v = NULL;

      if (!ostree_repo_load_variant (repo, OSTREE_OBJECT_TYPE_COMMIT, commit, &commit_v, NULL))
        {
          g_warning ("Couldn't load commit %s (ref %s)", commit, flatpak_decomposed_get_ref (ref));
          continue;
        }

      g_hash_table_insert (all_commits, flatpak_decomposed_ref (ref), g_variant_ref (commit_v));

      /* Compute list of subsets */
      commit_metadata = var_commit_get_metadata (var_commit_from_gvariant (commit_v));
      if (var_metadata_lookup (commit_metadata, "xa.subsets", NULL, &xa_subsets_v))
        {
          VarArrayofstringRef xa_subsets = var_arrayofstring_from_variant (xa_subsets_v);
          gsize len = var_arrayofstring_get_length (xa_subsets);
          for (gsize j = 0; j < len; j++)
            {
              const char *subset = var_arrayofstring_get_at (xa_subsets, j);

              if (!flatpak_g_ptr_array_contains_string (subsets, subset))
                g_ptr_array_add (subsets, g_strdup (subset));
            }
        }

      /* Compute list of arches */
      if (!flatpak_decomposed_is_arches (ref, arches->len, (const char **) arches->pdata))
        {
          new_arch = flatpak_decomposed_dup_arch (ref);
          g_ptr_array_add (arches, new_arch);

          /* If repo contains e.g. i386, also generated x86-64 appdata */
          reverse_compat_arch = flatpak_get_compat_arch_reverse (new_arch);
          if (reverse_compat_arch != NULL &&
              !flatpak_g_ptr_array_contains_string (arches, reverse_compat_arch))
            g_ptr_array_add (arches, g_strdup (reverse_compat_arch));
        }
    }

  g_ptr_array_sort (subsets, flatpak_strcmp0_ptr);
  g_ptr_array_sort (arches, flatpak_strcmp0_ptr);

  all_refs_keys = (FlatpakDecomposed **) g_hash_table_get_keys_as_array (all_refs, &n_keys);

  /* Sort refs so that appdata order is stable for e.g. deltas */
  qsort (all_refs_keys, n_keys, sizeof (FlatpakDecomposed *),
         (GCompareFunc) flatpak_decomposed_strcmp_p);

  transaction = flatpak_repo_transaction_start (repo, cancellable, error);
  if (transaction == NULL)
    return FALSE;

  for (int l = 0; l < subsets->len; l++)
    {
      const char *subset = g_ptr_array_index (subsets, l);

      for (int k = 0; k < arches->len; k++)
        {
          const char *arch = g_ptr_array_index (arches, k);

          if (!_flatpak_repo_generate_appstream (repo,
                                                 gpg_key_ids,
                                                 gpg_homedir,
                                                 all_refs_keys,
                                                 n_keys,
                                                 all_commits,
                                                 arch,
                                                 subset,
                                                 timestamp,
                                                 cancellable,
                                                 error))
            return FALSE;
        }
    }

  if (!ostree_repo_commit_transaction (repo, &stats, cancellable, error))
    return FALSE;

  return TRUE;
}

#define OSTREE_STATIC_DELTA_META_ENTRY_FORMAT "(uayttay)"
#define OSTREE_STATIC_DELTA_FALLBACK_FORMAT "(yaytt)"
#define OSTREE_STATIC_DELTA_SUPERBLOCK_FORMAT "(a{sv}tayay" OSTREE_COMMIT_GVARIANT_STRING "aya" OSTREE_STATIC_DELTA_META_ENTRY_FORMAT "a" OSTREE_STATIC_DELTA_FALLBACK_FORMAT ")"

static inline guint64
maybe_swap_endian_u64 (gboolean swap,
                       guint64  v)
{
  if (!swap)
    return v;
  return GUINT64_SWAP_LE_BE (v);
}

static guint64
flatpak_bundle_get_installed_size (GVariant *bundle, gboolean byte_swap)
{
  guint64 total_usize = 0;
  g_autoptr(GVariant) meta_entries = NULL;
  guint i, n_parts;

  g_variant_get_child (bundle, 6, "@a" OSTREE_STATIC_DELTA_META_ENTRY_FORMAT, &meta_entries);
  n_parts = g_variant_n_children (meta_entries);

  for (i = 0; i < n_parts; i++)
    {
      guint32 version;
      guint64 size, usize;
      g_autoptr(GVariant) objects = NULL;

      g_variant_get_child (meta_entries, i, "(u@aytt@ay)",
                           &version, NULL, &size, &usize, &objects);

      total_usize += maybe_swap_endian_u64 (byte_swap, usize);
    }

  return total_usize;
}

GVariant *
flatpak_bundle_load (GFile              *file,
                     char              **commit,
                     FlatpakDecomposed **ref,
                     char              **origin,
                     char              **runtime_repo,
                     char              **app_metadata,
                     guint64            *installed_size,
                     GBytes            **gpg_keys,
                     char              **collection_id,
                     GError             **error)
{
  g_autoptr(GVariant) delta = NULL;
  g_autoptr(GVariant) metadata = NULL;
  g_autoptr(GBytes) bytes = NULL;
  g_autoptr(GBytes) copy = NULL;
  g_autoptr(GVariant) to_csum_v = NULL;

  guint8 endianness_char;
  gboolean byte_swap = FALSE;

  GMappedFile *mfile = g_mapped_file_new (flatpak_file_get_path_cached (file), FALSE, error);

  if (mfile == NULL)
    return NULL;

  bytes = g_mapped_file_get_bytes (mfile);
  g_mapped_file_unref (mfile);

  delta = g_variant_new_from_bytes (G_VARIANT_TYPE (OSTREE_STATIC_DELTA_SUPERBLOCK_FORMAT), bytes, FALSE);
  g_variant_ref_sink (delta);

  to_csum_v = g_variant_get_child_value (delta, 3);
  if (!ostree_validate_structureof_csum_v (to_csum_v, error))
    return NULL;

  metadata = g_variant_get_child_value (delta, 0);

  if (g_variant_lookup (metadata, "ostree.endianness", "y", &endianness_char))
    {
      int file_byte_order = G_BYTE_ORDER;
      switch (endianness_char)
        {
        case 'l':
          file_byte_order = G_LITTLE_ENDIAN;
          break;

        case 'B':
          file_byte_order = G_BIG_ENDIAN;
          break;

        default:
          break;
        }
      byte_swap = (G_BYTE_ORDER != file_byte_order);
    }

  if (commit)
    *commit = ostree_checksum_from_bytes_v (to_csum_v);

  if (installed_size)
    *installed_size = flatpak_bundle_get_installed_size (delta, byte_swap);

  if (ref != NULL)
    {
      FlatpakDecomposed *the_ref = NULL;
      g_autofree char *ref_str = NULL;

      if (!g_variant_lookup (metadata, "ref", "s", &ref_str))
        {
          flatpak_fail_error (error, FLATPAK_ERROR_INVALID_DATA, _("Invalid bundle, no ref in metadata"));
          return NULL;
        }

      the_ref = flatpak_decomposed_new_from_ref (ref_str, error);
      if (the_ref == NULL)
        return NULL;

      g_clear_pointer (ref, flatpak_decomposed_unref);
      *ref = the_ref;
    }

  if (origin != NULL)
    {
      if (!g_variant_lookup (metadata, "origin", "s", origin))
        *origin = NULL;
    }

  if (runtime_repo != NULL)
    {
      if (!g_variant_lookup (metadata, "runtime-repo", "s", runtime_repo))
        *runtime_repo = NULL;
    }

  if (collection_id != NULL)
    {
      if (!g_variant_lookup (metadata, "collection-id", "s", collection_id))
        {
          *collection_id = NULL;
        }
      else if (**collection_id == '\0')
        {
          g_free (*collection_id);
          *collection_id = NULL;
        }
    }

  if (app_metadata != NULL)
    {
      if (!g_variant_lookup (metadata, "metadata", "s", app_metadata))
        *app_metadata = NULL;
    }

  if (gpg_keys != NULL)
    {
      g_autoptr(GVariant) gpg_value = g_variant_lookup_value (metadata, "gpg-keys",
                                                              G_VARIANT_TYPE ("ay"));
      if (gpg_value)
        {
          gsize n_elements;
          const char *data = g_variant_get_fixed_array (gpg_value, &n_elements, 1);
          *gpg_keys = g_bytes_new (data, n_elements);
        }
      else
        {
          *gpg_keys = NULL;
        }
    }

  /* Make a copy of the data so we can return it after freeing the file */
  copy = g_bytes_new (g_variant_get_data (metadata),
                      g_variant_get_size (metadata));
  return g_variant_ref_sink (g_variant_new_from_bytes (g_variant_get_type (metadata),
                                                       copy,
                                                       FALSE));
}

gboolean
flatpak_pull_from_bundle (OstreeRepo   *repo,
                          GFile        *file,
                          const char   *remote,
                          const char   *ref,
                          gboolean      require_gpg_signature,
                          GCancellable *cancellable,
                          GError      **error)
{
  gsize metadata_size = 0;
  g_autofree char *metadata_contents = NULL;
  g_autofree char *to_checksum = NULL;
  g_autoptr(GFile) root = NULL;
  g_autoptr(GFile) metadata_file = NULL;
  g_autoptr(GInputStream) in = NULL;
  g_autoptr(OstreeGpgVerifyResult) gpg_result = NULL;
  g_autoptr(GError) my_error = NULL;
  g_autoptr(GVariant) metadata = NULL;
  gboolean metadata_valid;
  g_autofree char *remote_collection_id = NULL;
  g_autofree char *collection_id = NULL;

  metadata = flatpak_bundle_load (file, &to_checksum, NULL, NULL, NULL, &metadata_contents, NULL, NULL, &collection_id, error);
  if (metadata == NULL)
    return FALSE;

  if (metadata_contents != NULL)
    metadata_size = strlen (metadata_contents);

  if (!remote || !ostree_repo_get_remote_option (repo, remote, "collection-id", NULL,
                                                 &remote_collection_id, NULL))
    remote_collection_id = NULL;

  if (remote_collection_id != NULL && collection_id != NULL &&
      strcmp (remote_collection_id, collection_id) != 0)
    return flatpak_fail_error (error, FLATPAK_ERROR_INVALID_DATA, _("Collection ‘%s’ of bundle doesn’t match collection ‘%s’ of remote"),
                               collection_id, remote_collection_id);

  if (!ostree_repo_prepare_transaction (repo, NULL, cancellable, error))
    return FALSE;

  /* Don’t need to set the collection ID here, since the remote binds this ref to the collection. */
  ostree_repo_transaction_set_ref (repo, remote, ref, to_checksum);

  if (!ostree_repo_static_delta_execute_offline (repo,
                                                 file,
                                                 FALSE,
                                                 cancellable,
                                                 error))
    return FALSE;

  gpg_result = ostree_repo_verify_commit_ext (repo, to_checksum,
                                              NULL, NULL, cancellable, &my_error);
  if (gpg_result == NULL)
    {
      /* no gpg signature, we ignore this *if* there is no gpg key
       * specified in the bundle or by the user */
      if (g_error_matches (my_error, OSTREE_GPG_ERROR, OSTREE_GPG_ERROR_NO_SIGNATURE) &&
          !require_gpg_signature)
        {
          g_clear_error (&my_error);
        }
      else
        {
          g_propagate_error (error, g_steal_pointer (&my_error));
          return FALSE;
        }
    }
  else
    {
      /* If there is no valid gpg signature we fail, unless there is no gpg
         key specified (on the command line or in the file) because then we
         trust the source bundle. */
      if (ostree_gpg_verify_result_count_valid (gpg_result) == 0  &&
          require_gpg_signature)
        return flatpak_fail_error (error, FLATPAK_ERROR_UNTRUSTED, _("GPG signatures found, but none are in trusted keyring"));
    }

  if (!ostree_repo_read_commit (repo, to_checksum, &root, NULL, NULL, error))
    return FALSE;

  if (!ostree_repo_commit_transaction (repo, NULL, cancellable, error))
    return FALSE;

  /* We ensure that the actual installed metadata matches the one in the
     header, because you may have made decisions on whether to install it or not
     based on that data. */
  metadata_file = g_file_resolve_relative_path (root, "metadata");
  in = (GInputStream *) g_file_read (metadata_file, cancellable, NULL);
  if (in != NULL)
    {
      g_autoptr(GMemoryOutputStream) data_stream = (GMemoryOutputStream *) g_memory_output_stream_new_resizable ();

      if (g_output_stream_splice (G_OUTPUT_STREAM (data_stream), in,
                                  G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE,
                                  cancellable, error) < 0)
        return FALSE;

      metadata_valid =
        metadata_contents != NULL &&
        metadata_size == g_memory_output_stream_get_data_size (data_stream) &&
        memcmp (metadata_contents, g_memory_output_stream_get_data (data_stream), metadata_size) == 0;
    }
  else
    {
      metadata_valid = (metadata_contents == NULL);
    }

  if (!metadata_valid)
    {
      /* Immediately remove this broken commit */
      ostree_repo_set_ref_immediate (repo, remote, ref, NULL, cancellable, error);
      return flatpak_fail_error (error, FLATPAK_ERROR_INVALID_DATA, _("Metadata in header and app are inconsistent"));
    }

  return TRUE;
}

===== ./common/flatpak-docker-reference.c =====
/* vi:set et sw=2 sts=2 cin cino=t0,f0,(0,{s,>2s,n-s,^-s,e-s:
 * Copyright © 2024 Red Hat, Inc
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Owen Taylor <otaylor@redhat.com>
 */

#include "flatpak-docker-reference-private.h"
#include "flatpak-utils-private.h"

struct _FlatpakDockerReference
{
    char *uri;
    char *repository;
    char *tag;
    char *digest;
};

/*
 * Parsing here is loosely based off:
 *
 *   https://github.com/containers/image/tree/main/docker/reference
 *
 * The major simplification is that we require a domain component, and
 * don't have any default domain. This removes ambiguity between domains and paths
 * and makes parsing much simpler. We also don't normalize single component
 * paths (e.g. ubuntu => library/ubuntu.)
 */

#define TAG "[0-9A-Za-z_][0-9A-Za-z_-]{0,127}"
#define DIGEST "[A-Za-z][A-Za-z0-9]*(?:[-_+.][A-Za-z][A-Za-z0-9]*)*[:][[:xdigit:]]{32,}"
#define REMAINDER_TAG_AND_DIGEST_RE "^(.*?)(:" TAG ")?" "(@" DIGEST ")?$"

static GRegex *
get_remainder_tag_and_digest_regex (void)
{
  static gsize regex = 0;

  if (g_once_init_enter (&regex))
    {
      g_autoptr(GRegex) compiled = g_regex_new (REMAINDER_TAG_AND_DIGEST_RE,
                                                G_REGEX_DEFAULT,
                                                G_REGEX_MATCH_DEFAULT,
                                                NULL);
      g_once_init_leave (&regex, (gsize)g_steal_pointer (&compiled));
    }

  return (GRegex *)regex;
}

FlatpakDockerReference *
flatpak_docker_reference_parse (const char *reference_str,
                                GError    **error)
{
  g_autoptr(FlatpakDockerReference) reference = g_new0 (FlatpakDockerReference, 1);
  GRegex *regex = get_remainder_tag_and_digest_regex ();
  g_autoptr(GMatchInfo) match_info = NULL;
  g_autofree char *tag_match = NULL;
  g_autofree char *digest_match = NULL;
  g_autofree char *remainder = NULL;
  g_autofree char *domain = NULL;
  gboolean matched;
  const char *slash;

  matched = g_regex_match (regex, reference_str, G_REGEX_MATCH_DEFAULT, &match_info);
  g_assert (matched);

  tag_match = g_match_info_fetch (match_info, 2);
  if (tag_match[0] == '\0')
    reference->tag = NULL;
  else
    reference->tag = g_strdup (tag_match + 1);

  digest_match = g_match_info_fetch (match_info, 3);
  if (digest_match[0] == '\0')
    reference->digest = NULL;
  else
    reference->digest = g_strdup (digest_match + 1);

  remainder = g_match_info_fetch (match_info, 1);
  slash = strchr (remainder, '/');
  if (slash == NULL || slash == reference_str || *slash == '\0')
    {
      flatpak_fail(error, "Can't parse %s into <domain>/<repository>", remainder);
      return NULL;
    }

  domain = g_strndup (remainder, slash - remainder);
  reference->uri = g_strconcat ("https://", domain, NULL);
  reference->repository = g_strdup (slash + 1);

  return g_steal_pointer (&reference);
}

const char *
flatpak_docker_reference_get_uri (FlatpakDockerReference *reference)
{
  return reference->uri;
}

const char *
flatpak_docker_reference_get_repository (FlatpakDockerReference *reference)
{
  return reference->repository;
}

const char *
flatpak_docker_reference_get_tag (FlatpakDockerReference *reference)
{
  return reference->tag;
}

const char *
flatpak_docker_reference_get_digest (FlatpakDockerReference *reference)
{
  return reference->digest;
}

void
flatpak_docker_reference_free (FlatpakDockerReference *reference)
{
  g_clear_pointer (&reference->uri, g_free);
  g_clear_pointer (&reference->repository, g_free);
  g_clear_pointer (&reference->tag, g_free);
  g_clear_pointer (&reference->digest, g_free);
  g_free (reference);
}

===== ./common/flatpak-auth-private.h =====
/*
 * Copyright © 2019 Red Hat, Inc
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Alexander Larsson <alexl@redhat.com>
 */

#ifndef __FLATPAK_AUTH_H__
#define __FLATPAK_AUTH_H__

#include <flatpak-common-types-private.h>
#include "flatpak-dbus-generated.h"

#define FLATPAK_AUTHENTICATOR_OBJECT_PATH "/org/freedesktop/Flatpak/Authenticator"
#define FLATPAK_AUTHENTICATOR_REQUEST_OBJECT_PATH_PREFIX "/org/freedesktop/Flatpak/Authenticator/request/"

#define FLATPAK_REMOTE_CONFIG_AUTHENTICATOR_NAME "xa.authenticator-name"
#define FLATPAK_REMOTE_CONFIG_AUTHENTICATOR_OPTIONS_PREFIX "xa.authenticator-options."

enum {
      FLATPAK_AUTH_RESPONSE_OK,
      FLATPAK_AUTH_RESPONSE_CANCELLED,
      FLATPAK_AUTH_RESPONSE_ERROR,
};

typedef FlatpakAuthenticator AutoFlatpakAuthenticator;
G_DEFINE_AUTOPTR_CLEANUP_FUNC (AutoFlatpakAuthenticator, g_object_unref)

typedef FlatpakAuthenticatorRequest AutoFlatpakAuthenticatorRequest;
G_DEFINE_AUTOPTR_CLEANUP_FUNC (AutoFlatpakAuthenticatorRequest, g_object_unref)

FlatpakAuthenticator *       flatpak_auth_new_for_remote            (FlatpakDir                   *dir,
                                                                     const char                   *remote,
                                                                     GCancellable                 *cancellable,
                                                                     GError                      **error);
FlatpakAuthenticatorRequest *flatpak_auth_create_request            (FlatpakAuthenticator         *authenticator,
                                                                     GCancellable                 *cancellable,
                                                                     GError                      **error);
gboolean                     flatpak_auth_request_ref_tokens        (FlatpakAuthenticator         *authenticator,
                                                                     FlatpakAuthenticatorRequest  *request,
                                                                     const char                   *remote,
                                                                     const char                   *remote_uri,
                                                                     GVariant                     *refs,
                                                                     GVariant                     *options,
                                                                     const char                   *parent_window,
                                                                     GCancellable                 *cancellable,
                                                                     GError                      **error);
char *                       flatpak_auth_create_request_path       (const char                   *peer,
                                                                     const char                   *token,
                                                                     GError                      **error);

#endif /* __FLATPAK_AUTH_H__ */

===== ./common/flatpak-dir-utils.c =====
/* vi:set et sw=2 sts=2 cin cino=t0,f0,(0,{s,>2s,n-s,^-s,e-s:
 * Copyright © 1995-1998 Free Software Foundation, Inc.
 * Copyright © 2014-2019 Red Hat, Inc
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 */

#include "config.h"
#include "flatpak-dir-utils-private.h"

#include <glib/gi18n-lib.h>

#include "flatpak-dir-private.h"
#include "flatpak-metadata-private.h"
#include "flatpak-utils-private.h"

char **
flatpak_list_deployed_refs (const char   *type,
                            const char   *name_prefix,
                            const char   *arch,
                            const char   *branch,
                            GCancellable *cancellable,
                            GError      **error)
{
  gchar **ret = NULL;
  g_autoptr(GPtrArray) names = NULL;
  g_autoptr(GHashTable) hash = NULL;
  g_autoptr(FlatpakDir) user_dir = NULL;
  g_autoptr(GPtrArray) system_dirs = NULL;
  int i;

  hash = g_hash_table_new_full ((GHashFunc)flatpak_decomposed_hash, (GEqualFunc)flatpak_decomposed_equal, (GDestroyNotify)flatpak_decomposed_unref, NULL);

  user_dir = flatpak_dir_get_user ();
  system_dirs = flatpak_dir_get_system_list (cancellable, error);
  if (system_dirs == NULL)
    goto out;

  if (!flatpak_dir_collect_deployed_refs (user_dir, type, name_prefix,
                                          arch, branch, hash, cancellable,
                                          error))
    goto out;

  for (i = 0; i < system_dirs->len; i++)
    {
      FlatpakDir *system_dir = g_ptr_array_index (system_dirs, i);
      if (!flatpak_dir_collect_deployed_refs (system_dir, type, name_prefix,
                                              arch, branch, hash, cancellable,
                                              error))
        goto out;
    }

  names = g_ptr_array_new ();

  GLNX_HASH_TABLE_FOREACH (hash, FlatpakDecomposed *, ref)
    {
      g_ptr_array_add (names, flatpak_decomposed_dup_id (ref));
    }

  g_ptr_array_sort (names, flatpak_strcmp0_ptr);
  g_ptr_array_add (names, NULL);

  ret = (char **) g_ptr_array_free (names, FALSE);
  names = NULL;

out:
  return ret;
}

char **
flatpak_list_unmaintained_refs (const char   *name_prefix,
                                const char   *arch,
                                const char   *branch,
                                GCancellable *cancellable,
                                GError      **error)
{
  gchar **ret = NULL;
  g_autoptr(GPtrArray) names = NULL;
  g_autoptr(GHashTable) hash = NULL;
  g_autoptr(FlatpakDir) user_dir = NULL;
  const char *key;
  GHashTableIter iter;
  g_autoptr(GPtrArray) system_dirs = NULL;
  int i;

  hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);

  user_dir = flatpak_dir_get_user ();

  if (!flatpak_dir_collect_unmaintained_refs (user_dir, name_prefix,
                                              arch, branch, hash, cancellable,
                                              error))
    return NULL;

  system_dirs = flatpak_dir_get_system_list (cancellable, error);
  if (system_dirs == NULL)
    return NULL;

  for (i = 0; i < system_dirs->len; i++)
    {
      FlatpakDir *system_dir = g_ptr_array_index (system_dirs, i);

      if (!flatpak_dir_collect_unmaintained_refs (system_dir, name_prefix,
                                                  arch, branch, hash, cancellable,
                                                  error))
        return NULL;
    }

  names = g_ptr_array_new ();
  g_hash_table_iter_init (&iter, hash);
  while (g_hash_table_iter_next (&iter, (gpointer *) &key, NULL))
    g_ptr_array_add (names, g_strdup (key));

  g_ptr_array_sort (names, flatpak_strcmp0_ptr);
  g_ptr_array_add (names, NULL);

  ret = (char **) g_ptr_array_free (names, FALSE);
  names = NULL;

  return ret;
}

GFile *
flatpak_find_deploy_dir_for_ref (FlatpakDecomposed *ref,
                                 FlatpakDir       **dir_out,
                                 GCancellable      *cancellable,
                                 GError           **error)
{
  g_autoptr(FlatpakDir) user_dir = NULL;
  g_autoptr(GPtrArray) system_dirs = NULL;
  FlatpakDir *dir = NULL;
  g_autoptr(GFile) deploy = NULL;

  user_dir = flatpak_dir_get_user ();
  system_dirs = flatpak_dir_get_system_list (cancellable, error);
  if (system_dirs == NULL)
    return NULL;

  dir = user_dir;
  deploy = flatpak_dir_get_if_deployed (dir, ref, NULL, cancellable);
  if (deploy == NULL)
    {
      int i;
      for (i = 0; deploy == NULL && i < system_dirs->len; i++)
        {
          dir = g_ptr_array_index (system_dirs, i);
          deploy = flatpak_dir_get_if_deployed (dir, ref, NULL, cancellable);
          if (deploy != NULL)
            break;
        }
    }

  if (deploy == NULL)
    {
      flatpak_fail_error (error, FLATPAK_ERROR_NOT_INSTALLED, _("%s not installed"), flatpak_decomposed_get_ref (ref));
      return NULL;
    }

  if (dir_out)
    *dir_out = g_object_ref (dir);
  return g_steal_pointer (&deploy);
}

GFile *
flatpak_find_files_dir_for_ref (FlatpakDecomposed *ref,
                                GCancellable      *cancellable,
                                GError           **error)
{
  g_autoptr(GFile) deploy = NULL;

  deploy = flatpak_find_deploy_dir_for_ref (ref, NULL, cancellable, error);
  if (deploy == NULL)
    return NULL;

  return g_file_get_child (deploy, "files");
}

GFile *
flatpak_find_unmaintained_extension_dir_if_exists (const char   *name,
                                                   const char   *arch,
                                                   const char   *branch,
                                                   GCancellable *cancellable)
{
  g_autoptr(FlatpakDir) user_dir = NULL;
  g_autoptr(GFile) extension_dir = NULL;
  g_autoptr(GError) local_error = NULL;

  user_dir = flatpak_dir_get_user ();

  extension_dir = flatpak_dir_get_unmaintained_extension_dir_if_exists (user_dir, name, arch, branch, cancellable);
  if (extension_dir == NULL)
    {
      g_autoptr(GPtrArray) system_dirs = NULL;
      int i;

      system_dirs = flatpak_dir_get_system_list (cancellable, &local_error);
      if (system_dirs == NULL)
        {
          g_warning ("Could not get the system installations: %s", local_error->message);
          return NULL;
        }

      for (i = 0; i < system_dirs->len; i++)
        {
          FlatpakDir *system_dir = g_ptr_array_index (system_dirs, i);
          extension_dir = flatpak_dir_get_unmaintained_extension_dir_if_exists (system_dir, name, arch, branch, cancellable);
          if (extension_dir != NULL)
            break;
        }
    }

  if (extension_dir == NULL)
    return NULL;

  return g_steal_pointer (&extension_dir);
}

FlatpakDecomposed *
flatpak_find_current_ref (const char   *app_id,
                          GCancellable *cancellable,
                          GError      **error)
{
  g_autoptr(FlatpakDecomposed) current_ref = NULL;
  g_autoptr(FlatpakDir) user_dir = flatpak_dir_get_user ();
  int i;

  current_ref = flatpak_dir_current_ref (user_dir, app_id, NULL);
  if (current_ref == NULL)
    {
      g_autoptr(GPtrArray) system_dirs = NULL;

      system_dirs = flatpak_dir_get_system_list (cancellable, error);
      if (system_dirs == NULL)
        return FALSE;

      for (i = 0; i < system_dirs->len; i++)
        {
          FlatpakDir *dir = g_ptr_array_index (system_dirs, i);
          current_ref = flatpak_dir_current_ref (dir, app_id, cancellable);
          if (current_ref != NULL)
            break;
        }
    }

  if (current_ref)
    return g_steal_pointer (&current_ref);

  flatpak_fail_error (error, FLATPAK_ERROR_NOT_INSTALLED, _("%s not installed"), app_id);
  return NULL;
}

FlatpakDeploy *
flatpak_find_deploy_for_ref_in (GPtrArray    *dirs,
                                const char   *ref_str,
                                const char   *commit,
                                GCancellable *cancellable,
                                GError      **error)
{
  FlatpakDeploy *deploy = NULL;
  int i;
  g_autoptr(GError) my_error = NULL;

  g_autoptr(FlatpakDecomposed) ref = flatpak_decomposed_new_from_ref (ref_str, error);
  if (ref == NULL)
    return NULL;

  for (i = 0; deploy == NULL && i < dirs->len; i++)
    {
      FlatpakDir *dir = g_ptr_array_index (dirs, i);

      flatpak_log_dir_access (dir);
      g_clear_error (&my_error);
      deploy = flatpak_dir_load_deployed (dir, ref, commit, cancellable, &my_error);
    }

  if (deploy == NULL)
    g_propagate_error (error, g_steal_pointer (&my_error));

  return deploy;
}

FlatpakDeploy *
flatpak_find_deploy_for_ref (const char   *ref,
                             const char   *commit,
                             FlatpakDir   *opt_user_dir,
                             GCancellable *cancellable,
                             GError      **error)
{
  g_autoptr(GPtrArray) dirs = NULL;

  dirs = flatpak_dir_get_system_list (cancellable, error);
  if (dirs == NULL)
    return NULL;

  /* If an custom dir was passed, use that instead of the user dir.
   * This is used when running apply-extra-data where if the target
   * is a custom installation location the regular user one may not
   * have the (possibly just installed in this transaction) runtime.
   */
  if (opt_user_dir)
    g_ptr_array_insert (dirs, 0, g_object_ref (opt_user_dir));
  else
    g_ptr_array_insert (dirs, 0, flatpak_dir_get_user ());

  return flatpak_find_deploy_for_ref_in (dirs, ref, commit, cancellable, error);
}

void
flatpak_extension_free (FlatpakExtension *extension)
{
  g_free (extension->id);
  g_free (extension->installed_id);
  g_free (extension->commit);
  flatpak_decomposed_unref (extension->ref);
  g_free (extension->directory);
  g_free (extension->files_path);
  g_free (extension->add_ld_path);
  g_free (extension->subdir_suffix);
  g_strfreev (extension->merge_dirs);
  g_free (extension);
}

static int
flatpak_extension_compare (gconstpointer _a,
                           gconstpointer _b)
{
  const FlatpakExtension *a = _a;
  const FlatpakExtension *b = _b;

  return b->priority - a->priority;
}

static FlatpakExtension *
flatpak_extension_new (const char        *id,
                       const char        *extension,
                       FlatpakDecomposed *ref,
                       const char        *directory,
                       const char        *add_ld_path,
                       const char        *subdir_suffix,
                       char             **merge_dirs,
                       GFile             *files,
                       GFile             *deploy_dir,
                       gboolean           is_unmaintained,
                       OstreeRepo        *repo)
{
  FlatpakExtension *ext = g_new0 (FlatpakExtension, 1);
  g_autoptr(GBytes) deploy_data = NULL;

  ext->id = g_strdup (id);
  ext->installed_id = g_strdup (extension);
  ext->ref = flatpak_decomposed_ref (ref);
  ext->directory = g_strdup (directory);
  ext->files_path = g_file_get_path (files);
  ext->add_ld_path = g_strdup (add_ld_path);
  ext->subdir_suffix = g_strdup (subdir_suffix);
  ext->merge_dirs = g_strdupv (merge_dirs);
  ext->is_unmaintained = is_unmaintained;

  /* Unmaintained extensions won't have a deploy or commit; see
   * https://github.com/flatpak/flatpak/issues/167 */
  if (deploy_dir && !is_unmaintained)
    {
      deploy_data = flatpak_load_deploy_data (deploy_dir, ref, repo, FLATPAK_DEPLOY_VERSION_ANY, NULL, NULL);
      if (deploy_data)
        ext->commit = g_strdup (flatpak_deploy_data_get_commit (deploy_data));
    }

  if (is_unmaintained)
    ext->priority = 1000;
  else
    {
      g_autoptr(GKeyFile) keyfile = g_key_file_new ();
      g_autofree char *metadata_path = g_build_filename (ext->files_path, "../metadata", NULL);

      if (g_key_file_load_from_file (keyfile, metadata_path, G_KEY_FILE_NONE, NULL))
        ext->priority = g_key_file_get_integer (keyfile,
                                                FLATPAK_METADATA_GROUP_EXTENSION_OF,
                                                FLATPAK_METADATA_KEY_PRIORITY,
                                                NULL);
    }

  return ext;
}

static GList *
add_extension (GKeyFile   *metakey,
               const char *group,
               const char *extension,
               const char *arch,
               const char *branch,
               GList      *res)
{
  FlatpakExtension *ext;
  g_autofree char *directory = g_key_file_get_string (metakey, group,
                                                      FLATPAK_METADATA_KEY_DIRECTORY,
                                                      NULL);
  g_autofree char *add_ld_path = g_key_file_get_string (metakey, group,
                                                        FLATPAK_METADATA_KEY_ADD_LD_PATH,
                                                        NULL);
  g_auto(GStrv) merge_dirs = g_key_file_get_string_list (metakey, group,
                                                         FLATPAK_METADATA_KEY_MERGE_DIRS,
                                                         NULL, NULL);
  g_autofree char *enable_if = g_key_file_get_string (metakey, group,
                                                      FLATPAK_METADATA_KEY_ENABLE_IF,
                                                      NULL);
  g_autofree char *subdir_suffix = g_key_file_get_string (metakey, group,
                                                          FLATPAK_METADATA_KEY_SUBDIRECTORY_SUFFIX,
                                                          NULL);
  g_autoptr(FlatpakDecomposed) ref = NULL;
  gboolean is_unmaintained = FALSE;
  g_autoptr(GFile) files = NULL;
  g_autoptr(GFile) deploy_dir = NULL;
  g_autoptr(FlatpakDir) dir = NULL;

  if (directory == NULL)
    return res;

  ref = flatpak_decomposed_new_from_parts (FLATPAK_KINDS_RUNTIME, extension, arch, branch, NULL);
  if (ref == NULL)
    return res;

  files = flatpak_find_unmaintained_extension_dir_if_exists (extension, arch, branch, NULL);

  if (files == NULL)
    {
      deploy_dir = flatpak_find_deploy_dir_for_ref (ref, &dir, NULL, NULL);
      if (deploy_dir)
        files = g_file_get_child (deploy_dir, "files");
    }
  else
    is_unmaintained = TRUE;

  /* Prefer a full extension (org.freedesktop.Locale) over subdirectory ones (org.freedesktop.Locale.sv) */
  if (files != NULL)
    {
      if (flatpak_extension_matches_reason (extension, enable_if, TRUE))
        {
          ext = flatpak_extension_new (extension, extension, ref, directory,
                                       add_ld_path, subdir_suffix, merge_dirs,
                                       files, deploy_dir, is_unmaintained,
                                       is_unmaintained ? NULL : flatpak_dir_get_repo (dir));
          res = g_list_prepend (res, ext);
        }
    }
  else if (g_key_file_get_boolean (metakey, group,
                                   FLATPAK_METADATA_KEY_SUBDIRECTORIES, NULL))
    {
      g_autofree char *prefix = g_strconcat (extension, ".", NULL);
      g_auto(GStrv) ids = NULL;
      g_auto(GStrv) unmaintained_refs = NULL;
      int j;

      ids = flatpak_list_deployed_refs ("runtime", prefix, arch, branch,
                                        NULL, NULL);
      for (j = 0; ids != NULL && ids[j] != NULL; j++)
        {
          const char *id = ids[j];
          g_autofree char *extended_dir = g_build_filename (directory, id + strlen (prefix), NULL);
          g_autoptr(FlatpakDecomposed) dir_ref = NULL;
          g_autoptr(GFile) subdir_deploy_dir = NULL;
          g_autoptr(GFile) subdir_files = NULL;
          g_autoptr(FlatpakDir) subdir_dir = NULL;

          dir_ref = flatpak_decomposed_new_from_parts (FLATPAK_KINDS_RUNTIME, id, arch, branch, NULL);
          if (dir_ref == NULL)
            continue;

          subdir_deploy_dir = flatpak_find_deploy_dir_for_ref (dir_ref, &subdir_dir, NULL, NULL);
          if (subdir_deploy_dir)
            subdir_files = g_file_get_child (subdir_deploy_dir, "files");

          if (subdir_files && flatpak_extension_matches_reason (id, enable_if, TRUE))
            {
              ext = flatpak_extension_new (extension, id, dir_ref, extended_dir,
                                           add_ld_path, subdir_suffix, merge_dirs,
                                           subdir_files, subdir_deploy_dir, FALSE,
                                           flatpak_dir_get_repo (subdir_dir));
              ext->needs_tmpfs = TRUE;
              res = g_list_prepend (res, ext);
            }
        }

      unmaintained_refs = flatpak_list_unmaintained_refs (prefix, arch, branch,
                                                          NULL, NULL);
      for (j = 0; unmaintained_refs != NULL && unmaintained_refs[j] != NULL; j++)
        {
          g_autofree char *extended_dir = g_build_filename (directory, unmaintained_refs[j] + strlen (prefix), NULL);
          g_autoptr(FlatpakDecomposed) dir_ref = NULL;
          g_autoptr(GFile) subdir_files = flatpak_find_unmaintained_extension_dir_if_exists (unmaintained_refs[j], arch, branch, NULL);

          dir_ref = flatpak_decomposed_new_from_parts (FLATPAK_KINDS_RUNTIME, unmaintained_refs[j], arch, branch, NULL);
          if (dir_ref == NULL)
            continue;

          if (subdir_files && flatpak_extension_matches_reason (unmaintained_refs[j], enable_if, TRUE))
            {
              ext = flatpak_extension_new (extension, unmaintained_refs[j], dir_ref,
                                           extended_dir, add_ld_path, subdir_suffix,
                                           merge_dirs, subdir_files, NULL, TRUE, NULL);
              ext->needs_tmpfs = TRUE;
              res = g_list_prepend (res, ext);
            }
        }
    }

  return res;
}

GList *
flatpak_list_extensions (GKeyFile   *metakey,
                         const char *arch,
                         const char *default_branch)
{
  g_auto(GStrv) groups = NULL;
  int i, j;
  GList *res;

  res = NULL;

  if (arch == NULL)
    arch = flatpak_get_arch ();

  groups = g_key_file_get_groups (metakey, NULL);
  for (i = 0; groups[i] != NULL; i++)
    {
      char *extension;

      if (g_str_has_prefix (groups[i], FLATPAK_METADATA_GROUP_PREFIX_EXTENSION) &&
          *(extension = (groups[i] + strlen (FLATPAK_METADATA_GROUP_PREFIX_EXTENSION))) != 0)
        {
          g_autofree char *version = g_key_file_get_string (metakey, groups[i],
                                                            FLATPAK_METADATA_KEY_VERSION,
                                                            NULL);
          g_auto(GStrv) versions = g_key_file_get_string_list (metakey, groups[i],
                                                               FLATPAK_METADATA_KEY_VERSIONS,
                                                               NULL, NULL);
          g_autofree char *name = NULL;
          const char *default_branches[] = { default_branch, NULL};
          const char **branches;

          flatpak_parse_extension_with_tag (extension, &name, NULL);

          if (versions)
            branches = (const char **) versions;
          else
            {
              if (version)
                default_branches[0] = version;
              branches = default_branches;
            }

          for (j = 0; branches[j] != NULL; j++)
            res = add_extension (metakey, groups[i], name, arch, branches[j], res);
        }
    }

  return g_list_sort (g_list_reverse (res), flatpak_extension_compare);
}

void
flatpak_log_dir_access (FlatpakDir *dir)
{
  if (dir != NULL)
    {
      GFile *dir_path = NULL;
      g_autofree char *dir_path_str = NULL;
      g_autofree char *dir_name = NULL;

      dir_path = flatpak_dir_get_path (dir);
      if (dir_path != NULL)
        dir_path_str = g_file_get_path (dir_path);
      dir_name = flatpak_dir_get_name (dir);
      g_info ("Opening %s flatpak installation at path %s", dir_name, dir_path_str);
    }
}

===== ./common/flatpak-bwrap-private.h =====
/*
 * Copyright © 2014-2018 Red Hat, Inc
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Alexander Larsson <alexl@redhat.com>
 */

#ifndef __FLATPAK_BWRAP_H__
#define __FLATPAK_BWRAP_H__

typedef struct
{
  GPtrArray *argv;
  GArray    *noinherit_fds; /* Just keep these open while the bwrap lives */
  GArray    *fds;
  GStrv      envp;
  GPtrArray *runtime_dir_members;
  int        sync_fds[2];
} FlatpakBwrap;

extern char *flatpak_bwrap_empty_env[1];

FlatpakBwrap *flatpak_bwrap_new (char **env);
void          flatpak_bwrap_free (FlatpakBwrap *bwrap);
void          flatpak_bwrap_set_env (FlatpakBwrap *bwrap,
                                     const char   *variable,
                                     const char   *value,
                                     gboolean      overwrite);
gboolean      flatpak_bwrap_is_empty (FlatpakBwrap *bwrap);
void          flatpak_bwrap_finish (FlatpakBwrap *bwrap);
void          flatpak_bwrap_unset_env (FlatpakBwrap *bwrap,
                                       const char   *variable);
void          flatpak_bwrap_add_arg (FlatpakBwrap *bwrap,
                                     const char   *arg);
void          flatpak_bwrap_take_arg (FlatpakBwrap *bwrap,
                                      char         *arg);
void          flatpak_bwrap_add_noinherit_fd (FlatpakBwrap *bwrap,
                                              int           fd);
void          flatpak_bwrap_add_fd (FlatpakBwrap *bwrap,
                                    int           fd);
void          flatpak_bwrap_add_args (FlatpakBwrap *bwrap,
                                      ...) G_GNUC_NULL_TERMINATED;
void          flatpak_bwrap_add_arg_printf (FlatpakBwrap *bwrap,
                                            const char   *format,
                                            ...) G_GNUC_PRINTF (2, 3);
void          flatpak_bwrap_append_argsv (FlatpakBwrap *bwrap,
                                          char        **args,
                                          int           len);
void          flatpak_bwrap_append_bwrap (FlatpakBwrap *bwrap,
                                          FlatpakBwrap *other);       /* Steals the fds */
void          flatpak_bwrap_append_args (FlatpakBwrap *bwrap,
                                         GPtrArray    *other_array);
gboolean      flatpak_bwrap_add_args_data_fd_dup (FlatpakBwrap  *bwrap,
                                                  const char    *op,
                                                  int            fd,
                                                  const char    *path_optional,
                                                  GError       **error);
void          flatpak_bwrap_add_args_data_fd (FlatpakBwrap *bwrap,
                                              const char   *op,
                                              int           fd,
                                              const char   *path_optional);
gboolean      flatpak_bwrap_add_args_data (FlatpakBwrap *bwrap,
                                           const char   *name,
                                           const char   *content,
                                           gssize        content_size,
                                           const char   *path,
                                           GError      **error);
void          flatpak_bwrap_add_bind_arg (FlatpakBwrap *bwrap,
                                          const char   *type,
                                          const char   *src,
                                          const char   *dest);
void          flatpak_bwrap_sort_envp (FlatpakBwrap *bwrap);
void          flatpak_bwrap_envp_to_args (FlatpakBwrap *bwrap);
gboolean      flatpak_bwrap_bundle_args (FlatpakBwrap *bwrap,
                                         int           start,
                                         int           end,
                                         gboolean      one_arg,
                                         GError      **error);
void          flatpak_bwrap_add_runtime_dir_member (FlatpakBwrap *bwrap,
                                                    const char *name);
void          flatpak_bwrap_populate_runtime_dir (FlatpakBwrap *bwrap,
                                                  const char *shared_xdg_runtime_dir);

void          flatpak_bwrap_child_setup_cb (gpointer user_data);
void          flatpak_bwrap_child_setup_inherit_fds_cb (gpointer user_data);
void          flatpak_bwrap_child_setup (GArray *fd_array,
                                         gboolean close_fd_workaround);

int           flatpak_bwrap_add_sync_fd (FlatpakBwrap *bwrap);

G_DEFINE_AUTOPTR_CLEANUP_FUNC (FlatpakBwrap, flatpak_bwrap_free)


#endif /* __FLATPAK_BWRAP_H__ */

===== ./common/flatpak-parental-controls-private.h =====
/*
 * Copyright © 2018 Endless Mobile, Inc.
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Philip Withnall <withnall@endlessm.com>
 */

#if !defined(__FLATPAK_H_INSIDE__) && !defined(FLATPAK_COMPILATION)
#error "Only <flatpak.h> can be included directly."
#endif

#ifndef __FLATPAK_PARENTAL_CONTROLS_PRIVATE_H__
#define __FLATPAK_PARENTAL_CONTROLS_PRIVATE_H__

#include <libmalcontent/app-filter.h>
#include <glib.h>

gboolean flatpak_oars_check_rating (GHashTable   *content_rating,
                                    const gchar  *content_rating_type,
                                    MctAppFilter *filter);

#endif /* __FLATPAK_PARENTAL_CONTROLS_PRIVATE_H__ */

===== ./common/flatpak-chain-input-stream-private.h =====
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
 *
 * Copyright (C) 2011 Colin Walters <walters@verbum.org>
 *
 * 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., 59 Temple Place, Suite 330,
 * Boston, MA 02111-1307, USA.
 *
 */

#pragma once

#ifndef __GI_SCANNER__

#include <gio/gio.h>

G_BEGIN_DECLS

#define FLATPAK_TYPE_CHAIN_INPUT_STREAM (flatpak_chain_input_stream_get_type ())
#define FLATPAK_CHAIN_INPUT_STREAM(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), FLATPAK_TYPE_CHAIN_INPUT_STREAM, FlatpakChainInputStream))
#define FLATPAK_CHAIN_INPUT_STREAM_CLASS(k)     (G_TYPE_CHECK_CLASS_CAST ((k), FLATPAK_TYPE_CHAIN_INPUT_STREAM, FlatpakChainInputStreamClass))
#define FLATPAK_IS_CHAIN_INPUT_STREAM(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), FLATPAK_TYPE_CHAIN_INPUT_STREAM))
#define FLATPAK_IS_CHAIN_INPUT_STREAM_CLASS(k)  (G_TYPE_CHECK_CLASS_TYPE ((k), FLATPAK_TYPE_CHAIN_INPUT_STREAM))
#define FLATPAK_CHAIN_INPUT_STREAM_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), FLATPAK_TYPE_CHAIN_INPUT_STREAM, FlatpakChainInputStreamClass))

typedef struct _FlatpakChainInputStream        FlatpakChainInputStream;
typedef struct _FlatpakChainInputStreamClass   FlatpakChainInputStreamClass;
typedef struct _FlatpakChainInputStreamPrivate FlatpakChainInputStreamPrivate;

struct _FlatpakChainInputStream
{
  GInputStream parent_instance;
};

struct _FlatpakChainInputStreamClass
{
  GInputStreamClass parent_class;

  /*< private >*/
  /* Padding for future expansion */
  void (*_g_reserved1) (void);
  void (*_g_reserved2) (void);
  void (*_g_reserved3) (void);
  void (*_g_reserved4) (void);
  void (*_g_reserved5) (void);
};

GType          flatpak_chain_input_stream_get_type (void) G_GNUC_CONST;

FlatpakChainInputStream * flatpak_chain_input_stream_new (GPtrArray *streams);

G_END_DECLS

#endif

===== ./common/flatpak-installation-private.h =====
/*
 * Copyright © 2018 Red Hat, Inc
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Alexander Larsson <alexl@redhat.com>
 */

#ifndef __FLATPAK_INSTALLATION_PRIVATE_H__
#define __FLATPAK_INSTALLATION_PRIVATE_H__

#include "flatpak-installation.h"

#include "flatpak-dir-private.h"

FlatpakDir *flatpak_installation_clone_dir_noensure (FlatpakInstallation *self);

FlatpakDir *flatpak_installation_get_dir  (FlatpakInstallation *self,
                                           GError             **error);
FlatpakDir *flatpak_installation_clone_dir (FlatpakInstallation *self,
                                            GCancellable        *cancellable,
                                            GError             **error);

FlatpakInstallation *flatpak_installation_new_for_dir (FlatpakDir   *dir,
                                                       GCancellable *cancellable,
                                                       GError      **error);

#endif /* __FLATPAK_INSTALLATION_PRIVATE_H__ */

===== ./common/flatpak-oci-signatures-private.h =====
#ifndef __FLATPAK_OCI_SIGNATURES_H__
#define __FLATPAK_OCI_SIGNATURES_H__

#include "flatpak-json-oci-private.h"

#include <glib.h>
#include <gio/gio.h>
#include <ostree.h>

typedef struct _FlatpakOciSignatures FlatpakOciSignatures;

gboolean flatpak_remote_has_gpg_key (OstreeRepo   *repo,
                                     const char   *remote_name);

FlatpakOciSignatures *flatpak_oci_signatures_new (void);

void flatpak_oci_signatures_free (FlatpakOciSignatures *self);

void flatpak_oci_signatures_add_signature (FlatpakOciSignatures *self,
                                           GBytes               *signature);

gboolean flatpak_oci_signatures_load_from_dfd (FlatpakOciSignatures *self,
                                               int                   dfd,
                                               GCancellable         *cancellable,
                                               GError              **error);

gboolean flatpak_oci_signatures_save_to_dfd (FlatpakOciSignatures *self,
                                             int                   dfd,
                                             GCancellable         *cancellable,
                                             GError              **error);
gboolean flatpak_oci_signatures_verify (FlatpakOciSignatures *self,
                                        OstreeRepo           *repo,
                                        const char           *remote_name,
                                        const char           *registry_url,
                                        const char           *repository_name,
                                        const char           *digest,
                                        GError              **error);

G_DEFINE_AUTOPTR_CLEANUP_FUNC(FlatpakOciSignatures, flatpak_oci_signatures_free)

#endif /* __FLATPAK_OCI_SIGNATURES_H__ */

===== ./common/flatpak-run-private.h =====
/*
 * Copyright © 2014 Red Hat, Inc
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Alexander Larsson <alexl@redhat.com>
 */

#ifndef __FLATPAK_RUN_H__
#define __FLATPAK_RUN_H__

#include "libglnx.h"
#include "flatpak-common-types-private.h"
#include "flatpak-context-private.h"
#include "flatpak-bwrap-private.h"
#include "flatpak-metadata-private.h"
#include "flatpak-ref-utils-private.h"
#include "flatpak-utils-private.h"
#include "flatpak-exports-private.h"

#define FLATPAK_RUN_APP_DEPLOY_APP_ORIGINAL (-2)
#define FLATPAK_RUN_APP_DEPLOY_APP_EMPTY (-3)

#define FLATPAK_RUN_APP_DEPLOY_USR_ORIGINAL (-2)

gboolean flatpak_run_in_transient_unit (const char *app_id,
                                        const char *instance_id,
                                        GError    **error);

void     flatpak_run_extend_ld_path       (FlatpakBwrap       *bwrap,
                                           const char         *prepend,
                                           const char         *append);
gboolean flatpak_run_add_extension_args   (FlatpakBwrap       *bwrap,
                                           GKeyFile           *metakey,
                                           FlatpakDecomposed  *ref,
                                           gboolean            use_ld_so_cache,
                                           const char         *target_path,
                                           char              **extensions_out,
                                           char              **ld_path_out,
                                           GCancellable       *cancellable,
                                           GError            **error);
gboolean flatpak_run_add_environment_args (FlatpakBwrap           *bwrap,
                                           const char             *app_info_path,
                                           FlatpakRunFlags         flags,
                                           const char             *app_id,
                                           FlatpakContext         *context,
                                           FlatpakContextShares    shares,
                                           FlatpakContextDevices   devices,
                                           FlatpakContextSockets   sockets,
                                           FlatpakContextFeatures  features,
                                           GFile                  *app_id_dir,
                                           GPtrArray              *previous_app_id_dirs,
                                           int                     per_app_dir_lock_fd,
                                           const char             *instance_id,
                                           FlatpakExports        **exports_out,
                                           GCancellable           *cancellable,
                                           GError                **error);
char **  flatpak_run_get_minimal_env (gboolean devel,
                                      gboolean use_ld_so_cache);
void     flatpak_run_apply_env_default (FlatpakBwrap *bwrap,
                                        gboolean      use_ld_so_cache);
void      flatpak_run_apply_env_vars (FlatpakBwrap   *bwrap,
                                      FlatpakContext *context);
FlatpakContext *flatpak_app_compute_permissions (GKeyFile *app_metadata,
                                                 GKeyFile *runtime_metadata,
                                                 GError  **error);
gboolean flatpak_ensure_data_dir (GFile        *app_id_dir,
                                  GCancellable *cancellable,
                                  GError      **error);

gboolean flatpak_run_setup_base_argv (FlatpakBwrap   *bwrap,
                                      int             runtime_fd,
                                      GFile          *app_id_dir,
                                      const char     *arch,
                                      FlatpakRunFlags flags,
                                      GError        **error);
gboolean flatpak_run_add_app_info_args (FlatpakBwrap           *bwrap,
                                        GFile                  *app_files,
                                        GFile                  *original_app_files,
                                        GBytes                 *app_deploy_data,
                                        const char             *app_extensions,
                                        GFile                  *runtime_files,
                                        GFile                  *original_runtime_files,
                                        GBytes                 *runtime_deploy_data,
                                        const char             *runtime_extensions,
                                        const char             *app_id,
                                        const char             *app_branch,
                                        FlatpakDecomposed      *runtime_ref,
                                        GFile                  *app_id_dir,
                                        FlatpakContext         *final_app_context,
                                        FlatpakContext         *cmdline_context,
                                        FlatpakContextSockets   sockets,
                                        gboolean                sandbox,
                                        gboolean                build,
                                        gboolean                devel,
                                        char                  **app_info_path_out,
                                        int                     instance_id_fd,
                                        char                  **host_instance_id_host_dir_out,
                                        char                  **host_instance_id_host_private_dir_out,
                                        char                  **instance_id_out,
                                        GError                **error);

gboolean flatpak_run_app (FlatpakDecomposed   *app_ref,
                          FlatpakDeploy       *app_deploy,
                          int                  custom_app_fd,
                          FlatpakContext      *extra_context,
                          const char          *custom_runtime,
                          const char          *custom_runtime_version,
                          const char          *custom_runtime_commit,
                          int                  custom_usr_fd,
                          int                  parent_pid,
                          FlatpakRunFlags      flags,
                          const char          *cwd,
                          const char          *custom_command,
                          char                *args[],
                          int                  n_args,
                          int                  instance_id_fd,
                          const char * const  *run_environ,
                          char               **instance_dir_out,
                          GArray              *bind_fds,
                          GArray              *ro_bind_fds,
                          GCancellable        *cancellable,
                          GError             **error);


FlatpakContextShares flatpak_run_compute_allowed_shares (FlatpakContext *context);
FlatpakContextDevices flatpak_run_compute_allowed_devices (FlatpakContext *context);
FlatpakContextSockets flatpak_run_compute_allowed_sockets (FlatpakContext *context);
FlatpakContextFeatures flatpak_run_compute_allowed_features (FlatpakContext *context);

#endif /* __FLATPAK_RUN_H__ */

===== ./common/flatpak-zstd-decompressor.c =====
#include "config.h"

#include "flatpak-zstd-decompressor-private.h"

#include <errno.h>
#include <string.h>
#ifdef HAVE_ZSTD
#include <zstd.h>
#endif

static void flatpak_zstd_decompressor_iface_init  (GConverterIface *iface);

struct _FlatpakZstdDecompressor
{
  GObject parent_instance;

#ifdef HAVE_ZSTD
  ZSTD_DStream *dstream;
#endif
};

G_DEFINE_TYPE_WITH_CODE (FlatpakZstdDecompressor, flatpak_zstd_decompressor, G_TYPE_OBJECT,
                         G_IMPLEMENT_INTERFACE (G_TYPE_CONVERTER,
                                                flatpak_zstd_decompressor_iface_init))

static void
flatpak_zstd_decompressor_finalize (GObject *object)
{
#ifdef HAVE_ZSTD
  FlatpakZstdDecompressor *decompressor;

  decompressor = FLATPAK_ZSTD_DECOMPRESSOR (object);

  ZSTD_freeDStream (decompressor->dstream);
#endif

  G_OBJECT_CLASS (flatpak_zstd_decompressor_parent_class)->finalize (object);
}

static void
flatpak_zstd_decompressor_init (FlatpakZstdDecompressor *decompressor)
{
#ifdef HAVE_ZSTD
  decompressor->dstream = ZSTD_createDStream ();
#endif
}

static void
flatpak_zstd_decompressor_class_init (FlatpakZstdDecompressorClass *klass)
{
  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);

  gobject_class->finalize = flatpak_zstd_decompressor_finalize;
}

FlatpakZstdDecompressor *
flatpak_zstd_decompressor_new (void)
{
  FlatpakZstdDecompressor *decompressor;

  decompressor = g_object_new (FLATPAK_TYPE_ZSTD_DECOMPRESSOR, NULL);

  return decompressor;
}

static void
flatpak_zstd_decompressor_reset (GConverter *converter)
{
#ifdef HAVE_ZSTD
  FlatpakZstdDecompressor *decompressor = FLATPAK_ZSTD_DECOMPRESSOR (converter);

  ZSTD_initDStream (decompressor->dstream);
#endif
}

static GConverterResult
flatpak_zstd_decompressor_convert (GConverter *converter,
                                   const void *inbuf,
                                   gsize       inbuf_size,
                                   void       *outbuf,
                                   gsize       outbuf_size,
                                   GConverterFlags flags,
                                   gsize      *bytes_read,
                                   gsize      *bytes_written,
                                   GError    **error)
{
#ifdef HAVE_ZSTD
  FlatpakZstdDecompressor *decompressor;
  ZSTD_inBuffer input = { inbuf, inbuf_size, 0 };
  ZSTD_outBuffer output = {outbuf, outbuf_size, 0 };
  size_t res;

  decompressor = FLATPAK_ZSTD_DECOMPRESSOR (converter);

  if (decompressor->dstream == NULL)
    {
      g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
                           "Failed to initialize libzstd");
      return G_CONVERTER_ERROR;
    }

  res = ZSTD_decompressStream(decompressor->dstream, &output , &input);
  if (ZSTD_isError (res))
    {
      g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA,
                   "Zstd decompression error: %s", ZSTD_getErrorName (res));
      return G_CONVERTER_ERROR;
    }

  *bytes_read = input.pos;
  *bytes_written = output.pos;

  if (res == 0)
    return G_CONVERTER_FINISHED;

  if (input.pos == 0 && output.pos == 0)
    {
      /* Did nothing, need more input? */
      if (flags & G_CONVERTER_INPUT_AT_END)
        g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA, "Zstd failed");
      else
        g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_PARTIAL_INPUT, "Need more zstd data");

      return G_CONVERTER_ERROR;
    }

  return G_CONVERTER_CONVERTED;

#else
  g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
                       "libzstd not available");
  return G_CONVERTER_ERROR;
#endif
}

static void
flatpak_zstd_decompressor_iface_init (GConverterIface *iface)
{
  iface->convert = flatpak_zstd_decompressor_convert;
  iface->reset = flatpak_zstd_decompressor_reset;
}

===== ./common/flatpak-json-private.h =====
/*
 * Copyright © 2016 Red Hat, Inc
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Alexander Larsson <alexl@redhat.com>
 */

#ifndef __FLATPAK_JSON_H__
#define __FLATPAK_JSON_H__

#include <json-glib/json-glib.h>

G_BEGIN_DECLS

#define FLATPAK_TYPE_JSON flatpak_json_get_type ()

typedef struct _FlatpakJsonProp FlatpakJsonProp;

typedef enum {
  FLATPAK_JSON_PROP_TYPE_PARENT,
  FLATPAK_JSON_PROP_TYPE_INT64,
  FLATPAK_JSON_PROP_TYPE_BOOL,
  FLATPAK_JSON_PROP_TYPE_STRING,
  FLATPAK_JSON_PROP_TYPE_STRUCT,
  FLATPAK_JSON_PROP_TYPE_STRUCTV,
  FLATPAK_JSON_PROP_TYPE_STRV,
  FLATPAK_JSON_PROP_TYPE_STRMAP,
  FLATPAK_JSON_PROP_TYPE_BOOLMAP,
} FlatpakJsonPropType;

typedef enum {
  FLATPAK_JSON_PROP_FLAGS_NONE = 0,
  FLATPAK_JSON_PROP_FLAGS_OPTIONAL = 1 << 0,
  FLATPAK_JSON_PROP_FLAGS_STRICT = 1 << 1,
  FLATPAK_JSON_PROP_FLAGS_MANDATORY = 1 << 2,
} FlatpakJsonPropFlags;


struct _FlatpakJsonProp
{
  const char          *name;
  gsize                offset;
  FlatpakJsonPropType  type;
  gpointer             type_data;
  gpointer             type_data2;
  FlatpakJsonPropFlags flags;
};

#define FLATPAK_JSON_STRING_PROP(_struct, _field, _name) \
  { _name, G_STRUCT_OFFSET (_struct, _field), FLATPAK_JSON_PROP_TYPE_STRING }
#define FLATPAK_JSON_MANDATORY_STRING_PROP(_struct, _field, _name) \
  { _name, G_STRUCT_OFFSET (_struct, _field), FLATPAK_JSON_PROP_TYPE_STRING, 0, 0, FLATPAK_JSON_PROP_FLAGS_MANDATORY }
#define FLATPAK_JSON_INT64_PROP(_struct, _field, _name) \
  { _name, G_STRUCT_OFFSET (_struct, _field), FLATPAK_JSON_PROP_TYPE_INT64 }
#define FLATPAK_JSON_BOOL_PROP(_struct, _field, _name) \
  { _name, G_STRUCT_OFFSET (_struct, _field), FLATPAK_JSON_PROP_TYPE_BOOL }
#define FLATPAK_JSON_STRV_PROP(_struct, _field, _name) \
  { _name, G_STRUCT_OFFSET (_struct, _field), FLATPAK_JSON_PROP_TYPE_STRV }
#define FLATPAK_JSON_MANDATORY_STRV_PROP(_struct, _field, _name) \
  { _name, G_STRUCT_OFFSET (_struct, _field), FLATPAK_JSON_PROP_TYPE_STRV, 0, 0, FLATPAK_JSON_PROP_FLAGS_MANDATORY }
#define FLATPAK_JSON_STRMAP_PROP(_struct, _field, _name) \
  { _name, G_STRUCT_OFFSET (_struct, _field), FLATPAK_JSON_PROP_TYPE_STRMAP }
#define FLATPAK_JSON_BOOLMAP_PROP(_struct, _field, _name) \
  { _name, G_STRUCT_OFFSET (_struct, _field), FLATPAK_JSON_PROP_TYPE_BOOLMAP }
#define FLATPAK_JSON_STRUCT_PROP(_struct, _field, _name, _props) \
  { _name, G_STRUCT_OFFSET (_struct, _field), FLATPAK_JSON_PROP_TYPE_STRUCT, (gpointer) _props}
#define FLATPAK_JSON_OPT_STRUCT_PROP(_struct, _field, _name, _props) \
  { _name, G_STRUCT_OFFSET (_struct, _field), FLATPAK_JSON_PROP_TYPE_STRUCT, (gpointer) _props, 0, FLATPAK_JSON_PROP_FLAGS_OPTIONAL}
#define FLATPAK_JSON_STRICT_STRUCT_PROP(_struct, _field, _name, _props) \
  { _name, G_STRUCT_OFFSET (_struct, _field), FLATPAK_JSON_PROP_TYPE_STRUCT, (gpointer) _props, 0, FLATPAK_JSON_PROP_FLAGS_STRICT}
#define FLATPAK_JSON_MANDATORY_STRICT_STRUCT_PROP(_struct, _field, _name, _props) \
  { _name, G_STRUCT_OFFSET (_struct, _field), FLATPAK_JSON_PROP_TYPE_STRUCT, (gpointer) _props, 0, FLATPAK_JSON_PROP_FLAGS_STRICT | FLATPAK_JSON_PROP_FLAGS_MANDATORY}
#define FLATPAK_JSON_PARENT_PROP(_struct, _field, _props) \
  { "parent", G_STRUCT_OFFSET (_struct, _field), FLATPAK_JSON_PROP_TYPE_PARENT, (gpointer) _props}
#define FLATPAK_JSON_STRUCTV_PROP(_struct, _field, _name, _props) \
  { _name, G_STRUCT_OFFSET (_struct, _field), FLATPAK_JSON_PROP_TYPE_STRUCTV, (gpointer) _props, (gpointer) sizeof (**((_struct *) 0)->_field) }
#define FLATPAK_JSON_MANDATORY_STRUCTV_PROP(_struct, _field, _name, _props) \
  { _name, G_STRUCT_OFFSET (_struct, _field), FLATPAK_JSON_PROP_TYPE_STRUCTV, (gpointer) _props, (gpointer) sizeof (**((_struct *) 0)->_field), FLATPAK_JSON_PROP_FLAGS_MANDATORY}
#define FLATPAK_JSON_LAST_PROP { NULL }

G_DECLARE_DERIVABLE_TYPE (FlatpakJson, flatpak_json, FLATPAK, JSON, GObject)

struct _FlatpakJsonClass
{
  GObjectClass     parent_class;

  FlatpakJsonProp *props;
  const char      *mediatype;
};

FlatpakJson *flatpak_json_from_node (JsonNode *node,
                                     GType     type,
                                     GError  **error);
JsonNode   *flatpak_json_to_node (FlatpakJson *self);
FlatpakJson *flatpak_json_from_bytes (GBytes  *bytes,
                                      GType    type,
                                      GError **error);
FlatpakJson *flatpak_json_from_stream (GInputStream *stream,
                                       GType         type,
                                       GCancellable *cancellable,
                                       GError      **error);
GBytes     *flatpak_json_to_bytes (FlatpakJson *self);

G_END_DECLS

#endif /* __FLATPAK_JSON_H__ */

===== ./common/flatpak-instance.c =====
/* vi:set et sw=2 sts=2 cin cino=t0,f0,(0,{s,>2s,n-s,^-s,e-s:
 * Copyright © 2018 Red Hat, Inc
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Matthias Clasen <mclasen@redhat.com>
 */

#include "config.h"

#include <fcntl.h>
#include <unistd.h>

#include "flatpak-json-backports-private.h"
#include "flatpak-metadata-private.h"
#include "flatpak-utils-base-private.h"
#include "flatpak-utils-private.h"
#include "flatpak-instance.h"
#include "flatpak-instance-private.h"
#include "flatpak-enum-types.h"

#include <glib/gi18n-lib.h>

/**
 * SECTION:flatpak-instance
 * @Title: FlatpakInstance
 * @Short_description: Information about a running sandbox
 *
 * A FlatpakInstance refers to a running sandbox, and contains
 * some basic information about the sandbox setup, such as the
 * application and runtime used inside the sandbox.
 *
 * Importantly, it also gives access to the PID of the main
 * processes in the sandbox.
 *
 * One way to obtain FlatpakInstances is to use flatpak_instance_get_all().
 * Another way is to use flatpak_installation_launch_full().
 *
 * Note that process lifecycle tracking is fundamentally racy.
 * You have to be prepared for the sandbox and the processes
 * represented by a FlatpakInstance to not be around anymore.
 *
 * The FlatpakInstance api was added in Flatpak 1.1.
 */

typedef struct _FlatpakInstancePrivate FlatpakInstancePrivate;

struct _FlatpakInstancePrivate
{
  char     *id;
  char     *dir;
  char     *private_dir;

  GKeyFile *info;
  char     *app;
  char     *arch;
  char     *branch;
  char     *commit;
  char     *runtime;
  char     *runtime_commit;

  int       pid;
  int       child_pid;
};

G_DEFINE_TYPE_WITH_PRIVATE (FlatpakInstance, flatpak_instance, G_TYPE_OBJECT)

static void
flatpak_instance_finalize (GObject *object)
{
  FlatpakInstance *self = FLATPAK_INSTANCE (object);
  FlatpakInstancePrivate *priv = flatpak_instance_get_instance_private (self);

  g_free (priv->id);
  g_free (priv->dir);
  g_free (priv->private_dir);
  g_free (priv->app);
  g_free (priv->arch);
  g_free (priv->branch);
  g_free (priv->commit);
  g_free (priv->runtime);
  g_free (priv->runtime_commit);

  if (priv->info)
    g_key_file_unref (priv->info);

  G_OBJECT_CLASS (flatpak_instance_parent_class)->finalize (object);
}

static void
flatpak_instance_class_init (FlatpakInstanceClass *klass)
{
  GObjectClass *object_class = G_OBJECT_CLASS (klass);

  object_class->finalize = flatpak_instance_finalize;
}

static void
flatpak_instance_init (FlatpakInstance *self)
{
}

/**
 * flatpak_instance_get_id:
 * @self: a #FlatpakInstance
 *
 * Gets the instance ID. The ID is used by Flatpak for bookkeeping
 * purposes and has no further relevance.
 *
 * Returns: the instance ID
 *
 * Since: 1.1
 */
const char *
flatpak_instance_get_id (FlatpakInstance *self)
{
  FlatpakInstancePrivate *priv = flatpak_instance_get_instance_private (self);

  return priv->id;
}

/**
 * flatpak_instance_get_app:
 * @self: a #FlatpakInstance
 *
 * Gets the application ID of the application running in the instance.
 *
 * Note that this may return %NULL for sandboxes that don't have an application.
 *
 * Returns: (nullable): the application ID or %NULL
 *
 * Since: 1.1
 */
const char *
flatpak_instance_get_app (FlatpakInstance *self)
{
  FlatpakInstancePrivate *priv = flatpak_instance_get_instance_private (self);

  return priv->app;
}

/**
 * flatpak_instance_get_arch:
 * @self: a #FlatpakInstance
 *
 * Gets the architecture of the application running in the instance.
 *
 * Returns: the architecture
 *
 * Since: 1.1
 */
const char *
flatpak_instance_get_arch (FlatpakInstance *self)
{
  FlatpakInstancePrivate *priv = flatpak_instance_get_instance_private (self);

  return priv->arch;
}

/**
 * flatpak_instance_get_branch:
 * @self: a #FlatpakInstance
 *
 * Gets the branch of the application running in the instance.
 *
 * Returns: the architecture
 *
 * Since: 1.1
 */
const char *
flatpak_instance_get_branch (FlatpakInstance *self)
{
  FlatpakInstancePrivate *priv = flatpak_instance_get_instance_private (self);

  return priv->branch;
}

/**
 * flatpak_instance_get_commit:
 * @self: a #FlatpakInstance
 *
 * Gets the commit of the application running in the instance.
 *
 * Returns: the commit
 *
 * Since: 1.1
 */
const char *
flatpak_instance_get_commit (FlatpakInstance *self)
{
  FlatpakInstancePrivate *priv = flatpak_instance_get_instance_private (self);

  return priv->commit;
}

/**
 * flatpak_instance_get_runtime:
 * @self: a #FlatpakInstance
 *
 * Gets the ref of the runtime used in the instance.
 *
 * Returns: the runtime ref
 *
 * Since: 1.1
 */
const char *
flatpak_instance_get_runtime (FlatpakInstance *self)
{
  FlatpakInstancePrivate *priv = flatpak_instance_get_instance_private (self);

  return priv->runtime;
}

/**
 * flatpak_instance_get_runtime_commit:
 * @self: a #FlatpakInstance
 *
 * Gets the commit of the runtime used in the instance.
 *
 * Returns: the runtime commit
 *
 * Since: 1.1
 */
const char *
flatpak_instance_get_runtime_commit (FlatpakInstance *self)
{
  FlatpakInstancePrivate *priv = flatpak_instance_get_instance_private (self);

  return priv->runtime_commit;
}

/**
 * flatpak_instance_get_pid:
 * @self: a #FlatpakInstance
 *
 * Gets the PID of the outermost process in the sandbox. This is not the
 * application process itself, but a bubblewrap 'babysitter' process.
 *
 * See flatpak_instance_get_child_pid().
 *
 * Returns: the outermost process PID
 *
 * Since: 1.1
 */
int
flatpak_instance_get_pid (FlatpakInstance *self)
{
  FlatpakInstancePrivate *priv = flatpak_instance_get_instance_private (self);

  return priv->pid;
}

static int get_child_pid (const char *dir);

/**
 * flatpak_instance_get_child_pid:
 * @self: a #FlatpakInstance
 *
 * Gets the PID of the application process in the sandbox.
 *
 * See flatpak_instance_get_pid().
 *
 * Note that this function may return 0 immediately after launching
 * a sandbox, for a short amount of time.
 *
 * Returns: the application process PID
 *
 * Since: 1.1
 */
int
flatpak_instance_get_child_pid (FlatpakInstance *self)
{
  FlatpakInstancePrivate *priv = flatpak_instance_get_instance_private (self);

  if (priv->child_pid == 0)
    priv->child_pid = get_child_pid (priv->dir);

  return priv->child_pid;
}

/**
 * flatpak_instance_get_info:
 * @self: a #FlatpakInstance
 *
 * Gets a keyfile that holds information about the running sandbox.
 *
 * This file is available as /.flatpak-info inside the sandbox as well.
 *
 * The most important data in the keyfile is available with separate getters,
 * but there may be more information in the keyfile.
 *
 * Returns: the flatpak-info keyfile
 *
 * Since: 1.1
 */
GKeyFile *
flatpak_instance_get_info (FlatpakInstance *self)
{
  FlatpakInstancePrivate *priv = flatpak_instance_get_instance_private (self);

  return priv->info;
}

GStrv
flatpak_instance_get_run_environ (FlatpakInstance *self, GError **error)
{
  FlatpakInstancePrivate *priv = flatpak_instance_get_instance_private (self);
  g_autofree char *file = NULL;
  g_autofree char *environ_data = NULL;
  gsize environ_size;
  g_auto(GStrv) env_vars = NULL;

  file = g_build_filename (priv->private_dir, "run-environ", NULL);

  if (!g_file_get_contents (file, &environ_data, &environ_size, error))
    return NULL;

  env_vars = flatpak_parse_env_block (environ_data, environ_size, error);
  if (env_vars == NULL)
    return NULL;

  return g_steal_pointer (&env_vars);
}

static GKeyFile *
get_instance_info (const char *dir)
{
  g_autofree char *file = NULL;
  g_autoptr(GKeyFile) key_file = NULL;
  g_autoptr(GError) error = NULL;

  file = g_build_filename (dir, "info", NULL);

  key_file = g_key_file_new ();
  if (!g_key_file_load_from_file (key_file, file, G_KEY_FILE_NONE, &error))
    {
      g_info ("Failed to load instance info file '%s': %s", file, error->message);
      return NULL;
    }

  return g_steal_pointer (&key_file);
}

static int
get_child_pid (const char *dir)
{
  g_autofree char *file = NULL;
  g_autofree char *contents = NULL;
  gsize length;
  g_autoptr(GError) error = NULL;
  g_autoptr(JsonParser) parser = NULL;
  JsonNode *node;
  JsonObject *obj;

  file = g_build_filename (dir, "bwrapinfo.json", NULL);

  if (!g_file_get_contents (file, &contents, &length, &error))
    {
      g_info ("Failed to load bwrapinfo.json file '%s': %s", file, error->message);
      return 0;
    }

  parser = json_parser_new ();
  if (!json_parser_load_from_data (parser, contents, length, &error))
    {
      g_info ("Failed to parse bwrapinfo.json file '%s': %s", file, error->message);
      return 0;
    }

  node = json_parser_get_root (parser);
  if (!node)
    {
      g_info ("Failed to parse bwrapinfo.json file '%s': %s", file, "empty");
      return 0;
    }

  obj = json_node_get_object (node);

  return json_object_get_int_member (obj, "child-pid");
}

static int
get_pid (const char *dir)
{
  g_autofree char *file = NULL;
  g_autofree char *contents = NULL;
  g_autoptr(GError) error = NULL;

  file = g_build_filename (dir, "pid", NULL);

  if (!g_file_get_contents (file, &contents, NULL, &error))
    {
      g_info ("Failed to load pid file '%s': %s", file, error->message);
      return 0;
    }

  return (int) g_ascii_strtoll (contents, NULL, 10);
}

FlatpakInstance *
flatpak_instance_new (const char *dir)
{
  FlatpakInstance *self = g_object_new (flatpak_instance_get_type (), NULL);
  FlatpakInstancePrivate *priv = flatpak_instance_get_instance_private (self);

  priv->dir = g_strdup (dir);
  priv->private_dir = g_strdup_printf ("%s-private", dir);
  priv->id = g_path_get_basename (dir);

  priv->pid = get_pid (priv->dir);
  priv->child_pid = get_child_pid (priv->dir);
  priv->info = get_instance_info (priv->dir);

  if (priv->info)
    {
      if (g_key_file_has_group (priv->info, FLATPAK_METADATA_GROUP_APPLICATION))
        {
          priv->app = g_key_file_get_string (priv->info,
                                             FLATPAK_METADATA_GROUP_APPLICATION, FLATPAK_METADATA_KEY_NAME, NULL);
          priv->runtime = g_key_file_get_string (priv->info,
                                                 FLATPAK_METADATA_GROUP_APPLICATION, FLATPAK_METADATA_KEY_RUNTIME, NULL);
        }
      else
        {
          priv->runtime = g_key_file_get_string (priv->info,
                                                 FLATPAK_METADATA_GROUP_RUNTIME, FLATPAK_METADATA_KEY_RUNTIME, NULL);
        }

      priv->arch = g_key_file_get_string (priv->info,
                                          FLATPAK_METADATA_GROUP_INSTANCE, FLATPAK_METADATA_KEY_ARCH, NULL);
      priv->branch = g_key_file_get_string (priv->info,
                                            FLATPAK_METADATA_GROUP_INSTANCE, FLATPAK_METADATA_KEY_BRANCH, NULL);
      priv->commit = g_key_file_get_string (priv->info,
                                            FLATPAK_METADATA_GROUP_INSTANCE, FLATPAK_METADATA_KEY_APP_COMMIT, NULL);
      priv->runtime_commit = g_key_file_get_string (priv->info,
                                                    FLATPAK_METADATA_GROUP_INSTANCE, FLATPAK_METADATA_KEY_RUNTIME_COMMIT, NULL);
    }

  return self;
}

/*
 * Return the directory in which we create a numbered subdirectory per
 * instance.
 *
 * This directory is not shared with Flatpak apps, and we rely on this
 * for the sandbox boundary.
 *
 * This is currently the same as the
 * flatpak_instance_get_apps_directory(). We can distinguish between
 * instance IDs and app-IDs because instances are integers, and app-IDs
 * always contain at least one dot.
 */
char *
flatpak_instance_get_instances_directory (void)
{
  g_autofree char *user_runtime_dir = flatpak_get_real_xdg_runtime_dir ();

  return g_build_filename (user_runtime_dir, ".flatpak", NULL);
}

/*
 * Return the directory in which we create a subdirectory per
 * concurrently running Flatpak app-ID to store app-specific data that
 * is common to all instances of the same app.
 *
 * This directory is not shared with Flatpak apps, and we rely on this
 * for the sandbox boundary.
 *
 * This is currently the same as the
 * flatpak_instance_get_instances_directory(). We can distinguish between
 * instance IDs and app-IDs because instances are integers, and app-IDs
 * always contain at least one dot.
 */
char *
flatpak_instance_get_apps_directory (void)
{
  return flatpak_instance_get_instances_directory ();
}

/*
 * @app_id: $FLATPAK_ID
 * @lock_fd_out: (out) (not optional): Used to return a lock on the
 *  per-app directories
 * @lock_path_out: (out) (not optional): Used to return the path to the
 *  lock file, suitable for bind-mounting into the container
 *
 * Create a per-app directory and take out a lock on it.
 */
gboolean
flatpak_instance_ensure_per_app_dir (const char *app_id,
                                     int *lock_fd_out,
                                     char **lock_path_out,
                                     GError **error)
{
  glnx_autofd int lock_fd = -1;
  g_autofree char *lock_path = NULL;
  g_autofree char *per_app_parent = NULL;
  g_autofree char *per_app_dir = NULL;
  struct flock non_exclusive_lock =
  {
    .l_type = F_RDLCK,
    .l_whence = SEEK_SET,
    .l_start = 0,
    .l_len = 0
  };

  g_return_val_if_fail (app_id != NULL, FALSE);
  g_return_val_if_fail (lock_fd_out != NULL, FALSE);
  g_return_val_if_fail (*lock_fd_out == -1, FALSE);
  g_return_val_if_fail (lock_path_out != NULL, FALSE);
  g_return_val_if_fail (*lock_path_out == NULL, FALSE);
  g_return_val_if_fail (error == NULL || *error == NULL, FALSE);

  per_app_parent = flatpak_instance_get_apps_directory ();
  per_app_dir = g_build_filename (per_app_parent, app_id, NULL);
  lock_path = g_build_filename (per_app_dir, ".ref", NULL);

  if (g_mkdir_with_parents (per_app_dir, 0700) != 0)
    return glnx_throw_errno_prefix (error,
                                    _("Unable to create directory %s"),
                                    per_app_dir);

  /* Take a file lock inside the shared directory, and hold it during
   * setup and in bwrap. We never delete the directory itself, or the
   * lock file that it contains (that would defeat the locking scheme).
   * Anyone cleaning up other members of per_app_dir must first verify
   * that it contains the lock file .ref, and take out an exclusive lock
   * on it. */
  lock_fd = open (lock_path, O_RDWR | O_CREAT | O_CLOEXEC, 0600);

  /* As with the per-instance directories, there's a race here, because
   * we can't atomically open and lock the lockfile. We work around
   * that by only doing GC if the lockfile is "old".
   *
   * If we can't get the lock immediately, that'll be because some other
   * process is trying to carry out garbage-collection, so we wait
   * for it to finish. */
  if (lock_fd < 0 ||
      fcntl (lock_fd, F_SETLKW, &non_exclusive_lock) != 0)
    return glnx_throw_errno_prefix (error,
                                    _("Unable to lock %s"),
                                    lock_path);

  *lock_fd_out = g_steal_fd (&lock_fd);
  *lock_path_out = g_steal_pointer (&lock_path);
  return TRUE;
}

/*
 * @app_id: $FLATPAK_ID
 * @per_app_dir_lock_fd: Used to prove that we have already taken out
 *  a per-app non-exclusive lock to stop this directory from being
 *  garbage-collected
 * @shared_tmp: (out) (not optional): Used to return the path to the
 *  shared /dev/shm
 *
 * Create the per-app /dev/shm.
 */
gboolean
flatpak_instance_ensure_per_app_dev_shm (const char *app_id,
                                         int per_app_dir_lock_fd,
                                         char **shared_dev_shm_out,
                                         GError **error)
{
  /* This function is actually generic, since we might well want to
   * offload other directories in the same way - but the only directory
   * we do this for right now is /dev/shm. */
  static const char link_name[] = "dev-shm";
  static const char parent[] = "/dev/shm";
  g_autofree gchar *flag_file = NULL;
  g_autofree gchar *path = NULL;
  g_autofree gchar *per_app_parent = NULL;
  g_autofree gchar *per_app_dir = NULL;
  glnx_autofd int flag_fd = -1;
  glnx_autofd int per_app_dir_fd = -1;

  g_return_val_if_fail (app_id != NULL, FALSE);
  g_return_val_if_fail (per_app_dir_lock_fd >= 0, FALSE);
  g_return_val_if_fail (shared_dev_shm_out != NULL, FALSE);
  g_return_val_if_fail (*shared_dev_shm_out == NULL, FALSE);
  g_return_val_if_fail (error == NULL || *error == NULL, FALSE);

  per_app_parent = flatpak_instance_get_apps_directory ();

  per_app_dir = g_build_filename (per_app_parent, app_id, NULL);
  if (!glnx_opendirat (AT_FDCWD, per_app_dir, TRUE,
                       &per_app_dir_fd,
                       error))
    return FALSE;

  /* If there's an existing symlink to a suitable directory, we can
   * reuse it (carefully). This gives us the sharing we wanted between
   * multiple instances of the same app, and between app and subsandbox. */
  if (flatpak_instance_claim_per_app_temp_directory (app_id,
                                                     per_app_dir_lock_fd,
                                                     per_app_dir_fd,
                                                     link_name,
                                                     parent,
                                                     &path,
                                                     NULL))
    {
      *shared_dev_shm_out = g_steal_pointer (&path);
      return TRUE;
    }

  /* Otherwise create a new directory in @parent, and make @link_name
   * a symlink to it. */

  /* /dev/shm/flatpak-$FLATPAK_ID-XXXXXX */
  path = g_strdup_printf ("%s/flatpak-%s-XXXXXX", parent, app_id);

  if (g_mkdtemp (path) == NULL)
    return glnx_throw_errno_prefix (error,
                                    _("Unable to create temporary directory in %s"),
                                    parent);

  /* This marks this directory as an expendable temp directory, and is
   * inspired by the use of .testtmp in libostree. */
  flag_file = g_build_filename (path, ".flatpak-tmpdir", NULL);
  flag_fd = openat (AT_FDCWD, flag_file,
                    O_RDONLY | O_CREAT | O_EXCL | O_CLOEXEC | O_NOFOLLOW | O_NOCTTY,
                    0600);

  if (flag_fd < 0)
    return glnx_throw_errno_prefix (error,
                                    _("Unable to create file %s"),
                                    path);

  /* Replace the symlink */
  if ((unlinkat (per_app_dir_fd, link_name, 0) < 0 && errno != ENOENT) ||
      symlinkat (path, per_app_dir_fd, link_name) < 0)
    return glnx_throw_errno_prefix (error,
                                    _("Unable to update symbolic link %s/%s"),
                                    per_app_dir, link_name);

  *shared_dev_shm_out = g_steal_pointer (&path);
  return TRUE;
}

/*
 * @app_id: $FLATPAK_ID
 * @per_app_dir_lock_fd: Used to prove that we have already taken out
 *  a per-app non-exclusive lock to stop this directory from being
 *  garbage-collected
 * @shared_tmp: (out) (not optional) (not nullable): Used to return
 *  the path to the shared /tmp
 *
 * Create the per-app /tmp.
 */
gboolean
flatpak_instance_ensure_per_app_tmp (const char *app_id,
                                     int per_app_dir_lock_fd,
                                     char **shared_tmp_out,
                                     GError **error)
{
  g_autofree char *per_app_parent = NULL;
  g_autofree char *shared_tmp = NULL;

  g_return_val_if_fail (app_id != NULL, FALSE);
  g_return_val_if_fail (shared_tmp_out != NULL, FALSE);
  g_return_val_if_fail (*shared_tmp_out == NULL, FALSE);
  g_return_val_if_fail (error == NULL || *error == NULL, FALSE);

  /* We don't actually do anything with this, we just pass it in here as
   * proof that we already set up the directory that contains the lock
   * file for per-app things, to force us to get the sequence right */
  g_return_val_if_fail (per_app_dir_lock_fd >= 0, FALSE);

  per_app_parent = flatpak_instance_get_apps_directory ();
  shared_tmp = g_build_filename (per_app_parent, app_id, "tmp", NULL);

  if (g_mkdir_with_parents (shared_tmp, 0700) != 0)
    return glnx_throw_errno_prefix (error,
                                    _("Unable to create directory %s"),
                                    shared_tmp);

  *shared_tmp_out = g_steal_pointer (&shared_tmp);
  return TRUE;
}

/*
 * @app_id: $FLATPAK_ID
 * @per_app_dir_lock_fd: Used to prove that we have already taken out
 *  a per-app non-exclusive lock to stop this directory from being
 *  garbage-collected
 * @shared_dir_out: (out) (not optional) (not nullable): Used to return
 *  the path to the shared $XDG_RUNTIME_DIR
 *
 * Create a per-app $XDG_RUNTIME_DIR.
 */
gboolean
flatpak_instance_ensure_per_app_xdg_runtime_dir (const char *app_id,
                                                 int per_app_dir_lock_fd,
                                                 char **shared_dir_out,
                                                 GError **error)
{
  g_autofree char *per_app_parent = NULL;
  g_autofree char *shared_dir = NULL;

  g_return_val_if_fail (app_id != NULL, FALSE);
  g_return_val_if_fail (shared_dir_out != NULL, FALSE);
  g_return_val_if_fail (*shared_dir_out == NULL, FALSE);
  g_return_val_if_fail (error == NULL || *error == NULL, FALSE);

  /* We don't actually do anything with this, we just pass it in here as
   * proof that we already set up the directory that contains the lock
   * file for per-app things, to force us to get the sequence right */
  g_return_val_if_fail (per_app_dir_lock_fd >= 0, FALSE);

  per_app_parent = flatpak_instance_get_apps_directory ();
  shared_dir = g_build_filename (per_app_parent, app_id, "xdg-run", NULL);

  if (g_mkdir_with_parents (shared_dir, 0700) != 0)
    return glnx_throw_errno_prefix (error,
                                    _("Unable to create directory %s"),
                                    shared_dir);

  *shared_dir_out = g_steal_pointer (&shared_dir);
  return TRUE;
}

static int
flatpak_instance_create_lock_file (const char *instance_dir)
{
  g_autofree char *lock_file = g_build_filename (instance_dir, ".ref", NULL);
  glnx_autofd int lock_fd = -1;
  struct flock l = {
    .l_type = F_RDLCK,
    .l_whence = SEEK_SET,
    .l_start = 0,
    .l_len = 0
  };

  /* Take a file lock inside the dir, hold that during setup
   * and in bwrap. Anyone trying to clean up unused directories
   * need to first verify that there is a .ref file and take a
   * write lock on .ref to ensure it is not in use.
   */
  lock_fd = open (lock_file, O_RDWR | O_CREAT | O_CLOEXEC, 0644);
  /* There is a tiny race here between the open creating the file and the lock succeeding.
     We work around that by only gc:ing "old" .ref files */
  if (lock_fd == -1 || fcntl (lock_fd, F_SETLK, &l) != 0)
    return -1;

  return g_steal_fd (&lock_fd);
}

/*
 * @host_dir_out: (not optional): used to return the directory on the host
 *  system representing this instance
 * @lock_fd_out: (not optional): used to return a non-exclusive (read) lock
 *  on the lockdirectory on the host-file
 */
char *
flatpak_instance_allocate_id (char **host_dir_out,
                              char **host_private_dir_out,
                              int   *lock_fd_out)
{
  g_autofree char *base_dir = flatpak_instance_get_instances_directory ();
  int count;

  g_return_val_if_fail (host_dir_out != NULL, NULL);
  g_return_val_if_fail (*host_dir_out == NULL, NULL);
  g_return_val_if_fail (host_private_dir_out != NULL, NULL);
  g_return_val_if_fail (*host_private_dir_out == NULL, NULL);
  g_return_val_if_fail (lock_fd_out != NULL, NULL);
  g_return_val_if_fail (*lock_fd_out == -1, NULL);

  if (g_mkdir_with_parents (base_dir, 0755) != 0)
    return NULL;

  flatpak_instance_iterate_all_and_gc (NULL);

  for (count = 0; count < 1000; count++)
    {
      g_autofree char *instance_id = NULL;
      g_autofree char *instance_dir = NULL;
      g_autofree char *instance_private_dir = NULL;
      glnx_autofd int lock_fd = -1;

      instance_id = g_strdup_printf ("%u", g_random_int ());

      instance_dir = g_build_filename (base_dir, instance_id, NULL);
      instance_private_dir = g_strdup_printf ("%s-private", instance_dir);

      /* We use an atomic mkdir to ensure the instance id is unique */
      if (mkdir (instance_dir, 0755) != 0)
        continue;

      lock_fd = flatpak_instance_create_lock_file (instance_dir);
      if (lock_fd == -1)
        continue;

      if (mkdir (instance_private_dir, 0700) != 0)
        {
          g_warning ("Could not create private instance directory '%s': %s",
                     instance_private_dir, g_strerror (errno));
          continue;
        }

      *lock_fd_out = g_steal_fd (&lock_fd);
      g_info ("Allocated instance id %s", instance_id);
      *host_dir_out = g_steal_pointer (&instance_dir);
      *host_private_dir_out = g_steal_pointer (&instance_private_dir);
      return g_steal_pointer (&instance_id);
    }

  return NULL;
}

FlatpakInstance *
flatpak_instance_new_for_id (const char *id)
{
  g_autofree char *base_dir = flatpak_instance_get_instances_directory ();
  g_autofree char *dir = NULL;

  dir = g_build_filename (base_dir, id, NULL);
  return flatpak_instance_new (dir);
}

/*
 * flatpak_instance_claim_per_app_temp_directory:
 * @app_id: $FLATPAK_ID
 * @per_app_dir_lock_fd: Lock representing shared or exclusive access
 *  to directories created for @app_id
 * @at_fd: Directory in which to look up @link_path
 * @link_path: Path of a symbolic link to a subdirectory of @parent
 * @parent: The directory in which we created the temporary directory,
 *  such as /dev/shm or /tmp
 * @path_out: (out) (not optional): Return the path to the directory
 *  referenced by @link_path
 *
 * Try to take control of an existing per-app temporary directory
 * referenced by @link_path, either for reuse or for deletion.
 * Return %TRUE if we can.
 *
 * This is currently only used for /dev/shm, but it's designed to be
 * equally usable for other non-user-owned directories like /tmp.
 *
 * We have to be careful here, because @link_path might be left over
 * from a previous boot, and it probably points into a directory like
 * /dev/shm or /tmp, where an attacker might recreate our directories,
 * for example as symbolic links to somewhere they control. As a result,
 * this function is security-sensitive, and needs to follow a policy of
 * failing when an unexpected situation is detected.
 *
 * @error is not normally user-visible, and is mostly present to support
 * debugging and unit testing.
 *
 * Returns: %TRUE if @link_path points to a suitable directory,
 *  or %FALSE with @error set if it does not.
 */
gboolean
flatpak_instance_claim_per_app_temp_directory (const char *app_id,
                                               int per_app_dir_lock_fd,
                                               int at_fd,
                                               const char *link_path,
                                               const char *parent,
                                               char **path_out,
                                               GError **error)
{
  g_autofree char *reuse_path = NULL;
  glnx_autofd int dfd = -1;
  glnx_autofd int flag_fd = -1;
  struct stat statbuf;
  const char *slash;
  const char *rest;

  at_fd = glnx_dirfd_canonicalize (at_fd);

  g_return_val_if_fail (app_id != NULL, FALSE);
  g_return_val_if_fail (per_app_dir_lock_fd >= 0, FALSE);
  g_return_val_if_fail (at_fd == AT_FDCWD || at_fd >= 0, FALSE);
  g_return_val_if_fail (link_path != NULL, FALSE);
  g_return_val_if_fail (parent != NULL, FALSE);
  g_return_val_if_fail (path_out != NULL, FALSE);
  g_return_val_if_fail (*path_out == NULL, FALSE);
  g_return_val_if_fail (error == NULL || *error == NULL, FALSE);

  reuse_path = glnx_readlinkat_malloc (at_fd, link_path, NULL, error);

  if (reuse_path == NULL)
    return FALSE;

  /* If we're going to use it as /dev/shm, the directory on the
   * host should match /dev/shm/flatpak-$FLATPAK_ID-XXXXXX */
  if (!g_str_has_prefix (reuse_path, parent))
    return glnx_throw (error, "%s does not start with %s",
                       reuse_path, parent);

  /* /flatpak-$FLATPAK_ID-XXXXXX */
  slash = reuse_path + strlen (parent);

  if (*slash != '/')
    return glnx_throw (error, "%s does not start with %s/",
                       reuse_path, parent);

  /* flatpak-$FLATPAK_ID-XXXXXX */
  rest = slash + 1;

  if (!g_str_has_prefix (rest, "flatpak-"))
    return glnx_throw (error, "%s does not start with %s/flatpak-",
                       reuse_path, parent);

  if (strchr (rest, '/') != NULL)
    return glnx_throw (error, "%s has too many directory separators",
                       reuse_path);

  if (!g_str_has_prefix (rest + strlen ("flatpak-"), app_id))
    return glnx_throw (error, "%s does not start with %s/flatpak-%s",
                       reuse_path, parent, app_id);

  if (rest[strlen ("flatpak-") + strlen (app_id)] != '-')
    return glnx_throw (error, "%s does not start with %s/flatpak-%s-",
                       reuse_path, parent, app_id);

  /* Avoid symlink attacks by not following symlinks */
  if (!glnx_opendirat (AT_FDCWD, reuse_path, FALSE,
                       &dfd,
                       error))
    return FALSE;

  if (fstat (dfd, &statbuf) < 0)
    return glnx_throw_errno_prefix (error, "fstat %s", reuse_path);

  /* We certainly don't want to reuse someone else's directory */
  if (statbuf.st_uid != geteuid ())
    return glnx_throw (error, "%s does not belong to this user", reuse_path);

  flag_fd = openat (dfd, ".flatpak-tmpdir",
                    O_RDONLY | O_CLOEXEC | O_NOFOLLOW | O_NOCTTY);

  /* If we can't open the flag file, the most likely reason is that it
   * isn't a directory that we created */
  if (flag_fd < 0)
    return glnx_throw_errno_prefix (error, "opening flag file %s/.flatpak-tmpdir",
                                    reuse_path);

  *path_out = g_steal_pointer (&reuse_path);
  return TRUE;
}

/*
 * The @error is not intended to be user-facing, and is there for
 * testing/debugging.
 */
static gboolean
flatpak_instance_gc_per_app_dirs (const char *instance_id,
                                  GError **error)
{
  g_autofree char *per_instance_parent = NULL;
  g_autofree char *per_app_parent = NULL;
  g_autofree char *app_id = NULL;
  g_autofree char *instance_dir = NULL;
  g_autofree char *per_app_dir = NULL;
  glnx_autofd int per_app_dir_fd = -1;
  glnx_autofd int per_app_dir_lock_fd = -1;
  g_autoptr(GError) local_error = NULL;
  g_autoptr(GKeyFile) key_file = NULL;
  struct flock exclusive_lock =
  {
    .l_type = F_WRLCK,
    .l_whence = SEEK_SET,
    .l_start = 0,
   .l_len = 0,
  };
  struct stat statbuf;

  per_instance_parent = flatpak_instance_get_instances_directory ();
  per_app_parent = flatpak_instance_get_apps_directory ();

  instance_dir = g_build_filename (per_instance_parent, instance_id, NULL);
  key_file = get_instance_info (instance_dir);

  if (key_file == NULL)
    return glnx_throw (error, "Unable to load keyfile %s/info", instance_dir);

  if (g_key_file_has_group (key_file, FLATPAK_METADATA_GROUP_APPLICATION))
    app_id = g_key_file_get_string (key_file,
                                    FLATPAK_METADATA_GROUP_APPLICATION,
                                    FLATPAK_METADATA_KEY_NAME, error);
  else
    app_id = g_key_file_get_string (key_file,
                                    FLATPAK_METADATA_GROUP_RUNTIME,
                                    FLATPAK_METADATA_KEY_RUNTIME, error);

  if (app_id == NULL)
    {
      g_prefix_error (error, "%s/info: ", instance_dir);
      return FALSE;
    }

  /* Take an exclusive lock so we don't race with other instances */

  per_app_dir = g_build_filename (per_app_parent, app_id, NULL);
  if (!glnx_opendirat (AT_FDCWD, per_app_dir, TRUE,
                       &per_app_dir_fd,
                       error))
    return FALSE;

  per_app_dir_lock_fd = openat (per_app_dir_fd, ".ref",
                                O_RDWR | O_CREAT | O_CLOEXEC, 0600);

  if (per_app_dir_lock_fd < 0)
    return glnx_throw_errno_prefix (error, "open %s/.ref", per_app_dir);

  /* We don't wait for the lock: we're just doing GC opportunistically.
   * If at least one instance is running, then we'll fail to get the
   * exclusive lock. */
  if (fcntl (per_app_dir_lock_fd, F_SETLK, &exclusive_lock) < 0)
    return glnx_throw_errno_prefix (error, "lock %s/.ref", per_app_dir);

  if (fstat (per_app_dir_lock_fd, &statbuf) < 0)
    return glnx_throw_errno_prefix (error, "fstat %s/.ref", per_app_dir);

  /* Only gc if created at least 3 secs ago, to work around the equivalent
   * of the race mentioned in flatpak_instance_allocate_id() */
  if (statbuf.st_mtime + 3 >= time (NULL))
    return glnx_throw (error, "lock file too recent, avoiding race condition");

  g_info ("Cleaning up per-app-ID state for %s", app_id);

  /* /dev/shm is offloaded onto the host's /dev/shm to get consistent
   * free space behaviour and make sure it's actually in RAM. It could
   * contain relatively large files, so we clean it up.
   *
   * In principle this could be used for other directories such as /tmp,
   * in a loop over an array of paths (hence this indentation), but we
   * only do this for /dev/shm right now. */
  do
    {
      g_autofree char *path = NULL;

      /* /dev/shm is an attacker-controlled namespace, so we need to be
       * careful what directories we will delete. We have to assume
       * that attackers will create malicious symlinks in /dev/shm to
       * try to trick us into opening or deleting the wrong files. */
      if (flatpak_instance_claim_per_app_temp_directory (app_id,
                                                         per_app_dir_lock_fd,
                                                         per_app_dir_fd,
                                                         "dev-shm",
                                                         "/dev/shm",
                                                         &path,
                                                         &local_error))
        {
          g_assert (g_str_has_prefix (path, "/dev/shm/"));

          if (unlinkat (per_app_dir_fd, "dev-shm", 0) != 0)
            g_info ("Unable to clean up %s/%s: %s",
                    per_app_dir, "dev-shm", g_strerror (errno));

          if (!glnx_shutil_rm_rf_at (AT_FDCWD, path, NULL, &local_error))
            {
              g_info ("Unable to clean up %s: %s",
                      path, local_error->message);
              g_clear_error (&local_error);
            }
        }
      else if (unlinkat (per_app_dir_fd, "dev-shm", 0) < 0 && errno == ENOENT)
        {
          /* ignore, the symlink wasn't even there anyway */
          g_clear_error (&local_error);
        }
      else
        {
          g_info ("%s/%s no longer points to the expected directory and "
                  "was removed: %s",
                  per_app_dir, "dev-shm", local_error->message);
          g_clear_error (&local_error);
        }
    }
  while (0);

  /* We currently allocate the app's /tmp directly in the per-app directory
   * on the host's XDG_RUNTIME_DIR, instead of offloading it into /tmp
   * in a way that's analogous to /dev/shm, so we expect tmp to be a directory
   * and not a symlink. If it's a symlink, we'll just unlink it. */
  if (!glnx_shutil_rm_rf_at (per_app_dir_fd, "tmp", NULL, &local_error))
    {
      g_info ("Unable to clean up %s/tmp: %s", per_app_dir,
              local_error->message);
      g_clear_error (&local_error);
    }

  /* Deliberately don't clean up the .ref lock file or the directory itself.
   * If we did that, we'd defeat our locking scheme, because a concurrent
   * process could open the .ref file just before we unlink it. */
  return TRUE;
}

void
flatpak_instance_iterate_all_and_gc (GPtrArray *out_instances)
{
  g_autofree char *base_dir = flatpak_instance_get_instances_directory ();
  g_auto(GLnxDirFdIterator) iter = { 0 };
  struct dirent *dent;

  /* Clean up unused instances */
  if (!glnx_dirfd_iterator_init_at (AT_FDCWD, base_dir, FALSE, &iter, NULL))
    return;

  while (TRUE)
    {
      if (!glnx_dirfd_iterator_next_dent_ensure_dtype (&iter, &dent, NULL, NULL))
        break;

      if (dent == NULL)
        break;

      if (!flatpak_str_is_integer (dent->d_name))
        continue;

      if (dent->d_type == DT_DIR)
        {
          const char *instance_id = dent->d_name;
          g_autofree char *ref_file = g_strconcat (instance_id, "/.ref", NULL);
          struct stat statbuf;
          struct flock l = {
            .l_type = F_WRLCK,
            .l_whence = SEEK_SET,
            .l_start = 0,
            .l_len = 0
          };
          glnx_autofd int lock_fd = openat (iter.fd, ref_file, O_RDWR | O_CLOEXEC);
          if (lock_fd != -1 &&
              fstat (lock_fd, &statbuf) == 0 &&
              /* Only gc if created at least 3 secs ago, to work around race mentioned in
               * flatpak_instance_allocate_id() */
              statbuf.st_mtime + 3 < time (NULL) &&
              fcntl (lock_fd, F_GETLK, &l) == 0 &&
              l.l_type == F_UNLCK)
            {
              g_autoptr(GError) local_error = NULL;
              g_autofree char *instance_id_private = g_strdup_printf ("%s-private", instance_id);

              /* The instance is not used, remove it */
              g_info ("Cleaning up unused container id %s", instance_id);

              if (!flatpak_instance_gc_per_app_dirs (instance_id, &local_error))
                g_debug ("Not cleaning up per-app dir: %s", local_error->message);

              glnx_shutil_rm_rf_at (iter.fd, instance_id_private, NULL, NULL);
              glnx_shutil_rm_rf_at (iter.fd, instance_id, NULL, NULL);
              continue;
            }

          if (out_instances != NULL)
            g_ptr_array_add (out_instances, flatpak_instance_new_for_id (dent->d_name));
        }
    }
}

/**
 * flatpak_instance_get_all:
 *
 * Gets FlatpakInstance objects for all running sandboxes in the current session.
 *
 * Returns: (transfer full) (element-type FlatpakInstance): a #GPtrArray of
 *   #FlatpakInstance objects
 *
 * Since: 1.1
 */
GPtrArray *
flatpak_instance_get_all (void)
{
  g_autoptr(GPtrArray) instances = NULL;

  instances = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref);
  flatpak_instance_iterate_all_and_gc (instances);

  return g_steal_pointer (&instances);
}

/**
 * flatpak_instance_is_running:
 * @self: a #FlatpakInstance
 *
 * Finds out if the sandbox represented by @self is still running.
 *
 * Returns: %TRUE if the sandbox is still running
 */
gboolean
flatpak_instance_is_running (FlatpakInstance *self)
{
  FlatpakInstancePrivate *priv = flatpak_instance_get_instance_private (self);

  if (kill (priv->pid, 0) == 0)
    return TRUE;

  return FALSE;
}

===== ./common/flatpak-context.c =====
/* vi:set et sw=2 sts=2 cin cino=t0,f0,(0,{s,>2s,n-s,^-s,e-s:
 * Copyright © 2014-2018 Red Hat, Inc
 * Copyright © 2024 GNOME Foundation, Inc.
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Alexander Larsson <alexl@redhat.com>
 *       Georges Basile Stavracas Neto <georges.stavracas@gmail.com>
 *       Hubert Figuière <hub@figuiere.net>
 */

#include "config.h"
#include "flatpak-context-private.h"

#include <string.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/utsname.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <sys/personality.h>
#include <grp.h>
#include <unistd.h>
#include <gio/gunixfdlist.h>

#include <glib/gi18n-lib.h>

#include <gio/gio.h>
#include "libglnx.h"

#include "flatpak-error.h"
#include "flatpak-metadata-private.h"
#include "flatpak-usb-private.h"
#include "flatpak-utils-base-private.h"
#include "flatpak-utils-private.h"

/* Same order as enum */
const char *flatpak_context_shares[] = {
  "network",
  "ipc",
  NULL
};

/* Same order as enum */
const char *flatpak_context_sockets[] = {
  "x11",
  "wayland",
  "pulseaudio",
  "session-bus",
  "system-bus",
  "fallback-x11",
  "ssh-auth",
  "pcsc",
  "cups",
  "gpg-agent",
  "inherit-wayland-socket",
  NULL
};

const char *flatpak_context_devices[] = {
  "dri",
  "all",
  "kvm",
  "shm",
  "input",
  "usb",
  NULL
};

const char *flatpak_context_features[] = {
  "devel",
  "multiarch",
  "bluetooth",
  "canbus",
  "per-app-dev-shm",
  NULL
};

const char *flatpak_context_special_filesystems[] = {
  "home",
  "host",
  "host-etc",
  "host-os",
  "host-reset",
  "host-root",
  NULL
};

const char *flatpak_context_conditions[] = {
  "true",
  "false",
  "has-input-device",
  "has-usb-device",
  "has-wayland",
  "has-usb-portal",
  NULL
};

FlatpakContextConditions flatpak_context_true_conditions =
  FLATPAK_CONTEXT_CONDITION_TRUE |
  FLATPAK_CONTEXT_CONDITION_HAS_INPUT_DEV |
  FLATPAK_CONTEXT_CONDITION_HAS_USB_DEV;

static const char *parse_negated (const char *option, gboolean *negated);
static guint32 flatpak_context_bitmask_from_string (const char *name, const char **names);

typedef struct FlatpakPermission FlatpakPermission;

struct FlatpakPermission {
  /* Is the permission unconditionally allowed */
  gboolean allowed;
  /* When layering, reset all permissions below */
  gboolean reset;
  /* Assumes allowed is false */
  GPtrArray *conditionals;

  /* Only used during deserialization */
  gboolean disallow_if_conditional;
  gboolean disallow_if_conditional_original_reset;
  GPtrArray *disallow_if_conditional_original_conditionals;
};


static FlatpakPermission *
flatpak_permission_new (void)
{
  FlatpakPermission *permission;

  permission = g_slice_new0 (FlatpakPermission);
  permission->conditionals = g_ptr_array_new_with_free_func (g_free);
  permission->disallow_if_conditional_original_conditionals =
    g_ptr_array_new_with_free_func (g_free);

  return permission;
};

static void
flatpak_permission_free (FlatpakPermission *permission)
{
  g_ptr_array_free (permission->conditionals, TRUE);
  g_ptr_array_free (permission->disallow_if_conditional_original_conditionals,
                    TRUE);
  g_slice_free (FlatpakPermission, permission);
}

G_DEFINE_AUTOPTR_CLEANUP_FUNC (FlatpakPermission, flatpak_permission_free)

static FlatpakPermission *
flatpak_permission_dup (FlatpakPermission *permission)
{
  FlatpakPermission *copy = NULL;

  copy = flatpak_permission_new ();

  if (!permission)
    return copy;

  copy->allowed = permission->allowed;
  copy->reset = permission->reset;

  for (size_t i = 0; i < permission->conditionals->len; i++) {
    const char *condition = permission->conditionals->pdata[i];

    g_ptr_array_add (copy->conditionals, g_strdup (condition));
  }

  return copy;
}

static void
flatpak_permission_set_not_allowed (FlatpakPermission *permission)
{
  permission->allowed = FALSE;
  permission->reset = TRUE;
  g_ptr_array_set_size (permission->conditionals, 0);
}

static void
flatpak_permission_set_allowed (FlatpakPermission *permission)
{
  permission->allowed = TRUE;
  /* We reset even when allowed, because lower layer conditionals being added
   * at merge would make this non-conditional layer conditional. */
  permission->reset = TRUE;
  g_ptr_array_set_size (permission->conditionals, 0);
}

static void
flatpak_permission_set_allowed_if (FlatpakPermission *permission,
                                   const char        *condition)
{
  /* If we are already unconditionally allowed, don't add useless conditionals */
  if (permission->allowed)
    return;

  /* Check if its already there */
  if (g_ptr_array_find_with_equal_func (permission->conditionals,
                                        condition,
                                        g_str_equal, NULL))
    return;

  g_ptr_array_add (permission->conditionals, g_strdup (condition));
  g_ptr_array_sort (permission->conditionals, flatpak_strcmp0_ptr);
}

static void
flatpak_permission_serialize (FlatpakPermission *permission,
                              const char        *name,
                              GPtrArray         *res,
                              gboolean           flatten)
{
  if (permission->allowed)
    {
      /* Completely allowed */

      g_ptr_array_add (res, g_strdup (name));
      g_assert (permission->conditionals->len == 0);
      /* A non-conditional add always implies reset, so no need to serialize that */
    }
  else if (permission->conditionals->len > 0)
    {
      /* Partially allowed */

      if (permission->reset && !flatten)
        g_ptr_array_add (res, g_strdup_printf ("!%s", name));

      /* As backwards compat for pre-conditional flatpaks we unconditionally
       * add this first. New versions will ignore this if there are
       * any conditionals.
       * Note: This may result in both "!foo" and "foo", but that
       * is fine as the "foo" is last and wins for older flatpaks.
       */
      g_ptr_array_add (res, g_strdup (name));

      for (size_t i = 0; i < permission->conditionals->len; i++)
        {
          const char *conditional = permission->conditionals->pdata[i];

          g_ptr_array_add (res, g_strdup_printf ("if:%s:%s", name, conditional));
        }
    }
  else
    {
      /* Completely disallowed */

      if (!flatten)
        g_ptr_array_add (res, g_strdup_printf ("!%s", name));
    }
}

static void
flatpak_permission_to_args (FlatpakPermission *permission,
                            const char        *argname,
                            const char        *noargname,
                            const char        *name,
                            GPtrArray         *args)
{
  if (permission->allowed)
    {
      /* Completely allowed */

      g_ptr_array_add (args, g_strdup_printf ("--%s=%s", argname, name));
    }
  else if (permission->conditionals->len > 0)
    {
      /* Partially allowed */

      if (permission->reset)
        g_ptr_array_add (args, g_strdup_printf ("--%s=%s", noargname, name));

      for (size_t i = 0; i < permission->conditionals->len; i++)
        {
          const char *conditional = permission->conditionals->pdata[i];

          g_ptr_array_add (args, g_strdup_printf ("--%s-if=%s:%s",
                                                  argname, name, conditional));
        }
    }
  else
    {
      /* Completely disallowed */

      g_ptr_array_add (args, g_strdup_printf ("--no%s=%s", argname, name));
    }
}

static void
flatpak_permission_deserialize (FlatpakPermission *permission,
                                gboolean           negated,
                                const char        *maybe_condition)
{
  /* This can't use the flatpak_permission_set_ helpers, because we
   * have to be wary of the backward compat non-conditional permission
   * in case conditionals are used. */

  if (maybe_condition == NULL)
    {
      /* Non-conditional option, these are always before conditionals,
       * but if non-negated could be backwards compat for later conditional. */
      if (negated)
        {
          permission->allowed = FALSE;
          permission->reset = TRUE;
        }
      else
        {
          GPtrArray *tmp;

          /* Allow us to revert this if it is a backwards compat */
          permission->disallow_if_conditional = TRUE;
          permission->disallow_if_conditional_original_reset = permission->reset;
          tmp = permission->conditionals;
          permission->conditionals =
            permission->disallow_if_conditional_original_conditionals;
          permission->disallow_if_conditional_original_conditionals = tmp;

          permission->allowed = TRUE;
          permission->reset = TRUE;
        }
    }
  else
    {
      /* Conditional option */
      if (permission->disallow_if_conditional)
        {
          GPtrArray *tmp;

          /* Previous allow was a backward compat, revert it */
          permission->allowed = FALSE;
          permission->reset = permission->disallow_if_conditional_original_reset;
          permission->disallow_if_conditional = FALSE;
          tmp = permission->disallow_if_conditional_original_conditionals;
          permission->disallow_if_conditional_original_conditionals =
            permission->conditionals;
          permission->conditionals = tmp;
          g_ptr_array_set_size (
            permission->disallow_if_conditional_original_conditionals, 0);
        }

      g_ptr_array_add (permission->conditionals, g_strdup (maybe_condition));
      g_ptr_array_sort (permission->conditionals, flatpak_strcmp0_ptr);
    }
}

static void
flatpak_permission_merge (FlatpakPermission *permission,
                          FlatpakPermission *other_permission)
{
  if (other_permission->reset)
    {
      permission->reset = TRUE;
      g_ptr_array_set_size (permission->conditionals, 0);
    }

  permission->allowed = other_permission->allowed;

  for (size_t i = 0; i < other_permission->conditionals->len; i++)
    {
      const char *conditional = other_permission->conditionals->pdata[i];

      /* Check if its already there */
      if (g_ptr_array_find_with_equal_func (permission->conditionals,
                                            conditional,
                                            g_str_equal, NULL))
        return;

      g_ptr_array_add (permission->conditionals, g_strdup (conditional));
    }

  g_ptr_array_sort (permission->conditionals, flatpak_strcmp0_ptr);

  /* Internal consistency check */
  if (permission->allowed)
    g_assert (permission->conditionals->len == 0);
}

static gboolean
flatpak_permission_compute_allowed (FlatpakPermission                *permission,
                                    FlatpakContextConditionEvaluator  evaluator)
{
  if (permission->allowed)
    return TRUE;

  for (size_t i = 0; i < permission->conditionals->len; i++)
    {
      const char *conditional = permission->conditionals->pdata[i];
      gboolean negated;
      const char *condition_str;
      guint32 condition;

      condition_str = parse_negated (conditional, &negated);
      condition =
        flatpak_context_bitmask_from_string (condition_str,
                                             flatpak_context_conditions);

      /* If condition is 0 it means this version of flatpak doesn't know
       * about the condition and it cannot be satisfied. */
      if (condition == 0)
        continue;

      /* Conditions which are always true in this version of flatpak */
      if ((condition & flatpak_context_true_conditions) && !negated)
        return TRUE;

      /* Conditions which need runtime evaluation */
      if (evaluator && evaluator (condition) == !negated)
        return TRUE;
   }

  /* No condition evaluated to TRUE, so disable the thing */
  return FALSE;
}

static gboolean
flatpak_permission_adds_permissions (FlatpakPermission *old,
                                     FlatpakPermission *new)
{
  size_t i = 0, j = 0;

  if (old->allowed)
    return FALSE;

  if (new->allowed)
    return TRUE;

  if (new->conditionals->len > old->conditionals->len)
    return TRUE;

  while (TRUE)
    {
      const char *old_cond = old->conditionals->pdata[i];
      const char *new_cond = new->conditionals->pdata[j];
      int res;

      if (old_cond == NULL)
        return new_cond != NULL;

      if (new_cond == NULL)
        return FALSE;

      res = strcmp (old_cond, new_cond);
      if (res == 0) /* Same conditional */
        {
          i++;
          j++;
        }
      else if (res < 0) /* Old conditional was removed */
        {
          i++;
        }
      else /* new conditional */
        {
          return FALSE;
        }
    }

  return FALSE;
}

static GHashTable *
flatpak_permissions_new (void)
{
  return g_hash_table_new_full (g_str_hash, g_str_equal,
                                (GDestroyNotify) g_free,
                                (GDestroyNotify) flatpak_permission_free);
}

static GHashTable *
flatpak_permissions_dup (GHashTable *old)
{
  GHashTable *new;
  const char *name;
  FlatpakPermission *old_permission;
  GHashTableIter iter;

  new = flatpak_permissions_new ();

  g_hash_table_iter_init (&iter, old);
  while (g_hash_table_iter_next (&iter,
                                 (gpointer *) &name,
                                 (gpointer *) &old_permission))
    {
      g_hash_table_insert (new,
                           g_strdup (name),
                           flatpak_permission_dup (old_permission));
    }

  return new;
}

static FlatpakPermission *
flatpak_permissions_ensure (GHashTable *permissions,
                            const char *name)
{
  FlatpakPermission *permission = g_hash_table_lookup (permissions, name);

  if (permission == NULL)
    {
      permission = flatpak_permission_new ();
      g_hash_table_insert (permissions, g_strdup (name), permission);
    }

  return permission;
}

static void
flatpak_permissions_set_not_allowed (GHashTable *permissions,
                                     const char *name)
{
  flatpak_permission_set_not_allowed (flatpak_permissions_ensure (permissions,
                                                                  name));
}

static void
flatpak_permissions_set_allowed (GHashTable *permissions,
                                 const char *name)
{
  flatpak_permission_set_allowed (flatpak_permissions_ensure (permissions,
                                                              name));
}

static void
flatpak_permissions_set_allowed_if (GHashTable *permissions,
                                    const char *name,
                                    const char *condition)
{
  flatpak_permission_set_allowed_if (flatpak_permissions_ensure (permissions,
                                                                 name),
                                      condition);
}

static gboolean
flatpak_permissions_allows_unconditionally (GHashTable *permissions,
                                            const char *name)
{
  FlatpakPermission *permission = g_hash_table_lookup (permissions, name);

  if (permission)
    return permission->allowed;

  return FALSE;
}

static void
flatpak_permissions_to_args (GHashTable *permissions,
                             const char *argname,
                             const char *noargname,
                             GPtrArray  *args)
{
  g_autoptr(GList) ordered_keys = NULL;

  ordered_keys = g_hash_table_get_keys (permissions);
  ordered_keys = g_list_sort (ordered_keys, (GCompareFunc) strcmp);

  for (GList *l = ordered_keys; l != NULL; l = l->next)
    {
      const char *name = l->data;
      FlatpakPermission *permission = g_hash_table_lookup (permissions, name);

      flatpak_permission_to_args (permission, argname, noargname, name, args);
    }
}

static char **
flatpak_permissions_to_strv (GHashTable *permissions,
                             gboolean    flatten)
{
  g_autoptr(GList) ordered_keys = NULL;
  g_autoptr(GPtrArray) res = g_ptr_array_new ();

  ordered_keys = g_hash_table_get_keys (permissions);
  ordered_keys = g_list_sort (ordered_keys, (GCompareFunc) strcmp);

  for (GList *l = ordered_keys; l != NULL; l = l->next)
    {
      const char *name = l->data;
      FlatpakPermission *permission = g_hash_table_lookup (permissions, name);

      flatpak_permission_serialize (permission, name, res, flatten);
    }

  g_ptr_array_add (res, NULL);
  return (char **)g_ptr_array_free (g_steal_pointer (&res), FALSE);
}

static guint32
flatpak_permissions_compute_allowed (GHashTable                        *permissions,
                                     const char                       **names,
                                     FlatpakContextConditionEvaluator   evaluator)
{
  guint32 bitmask = 0;

  for (size_t i = 0; names[i] != NULL; i++)
    {
      const char *name = names[i];
      FlatpakPermission *permission = g_hash_table_lookup (permissions, name);

      if (permission &&
          flatpak_permission_compute_allowed (permission, evaluator))
        bitmask |= 1 << i;
    }

  return bitmask;
}

static gboolean
flatpak_permissions_from_strv (GHashTable  *permissions,
                               const char **strv,
                               GError     **error)
{
  for (size_t i = 0; strv[i] != NULL; i++)
    {
      g_auto(GStrv) tokens = g_strsplit (strv[i], ":", 3);
      const char *name = NULL;
      gboolean negated = FALSE;
      const char *condition = NULL;
      FlatpakPermission *permission;

      if (strcmp (tokens[0], "if") == 0)
        {
          if (g_strv_length (tokens) != 3)
            {
              g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_FAILED,
                           _("Invalid permission syntax: %s"), strv[i]);
              return FALSE;
            }

          name = tokens[1];
          condition = tokens[2];
        }
      else
        {
          if (g_strv_length (tokens) != 1)
            {
              g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_FAILED,
                           _("Invalid permission syntax: %s"), strv[i]);
              return FALSE;
            }

          name = parse_negated (tokens[0], &negated);
        }

      permission = flatpak_permissions_ensure (permissions, name);
      flatpak_permission_deserialize (permission, negated, condition);
    }

  return TRUE;
}

static void
flatpak_permissions_merge (GHashTable *permissions,
                           GHashTable *other)
{
  const char *name;
  FlatpakPermission *other_permission;
  GHashTableIter iter;
  FlatpakPermission *x11;

  /* If we reset the x11 conditionals, the fallback-x11 permission also must go
   * because it is a conditional. */
  x11 = g_hash_table_lookup (other, "x11");
  if (x11 && x11->reset)
    g_hash_table_remove (permissions, "fallback-x11");

  g_hash_table_iter_init (&iter, other);
  while (g_hash_table_iter_next (&iter,
                                 (gpointer *) &name,
                                 (gpointer *) &other_permission))
    {
      FlatpakPermission *permission = g_hash_table_lookup (permissions, name);

      if (permission)
        {
          flatpak_permission_merge (permission, other_permission);
        }
      else
        {
          g_hash_table_insert (permissions,
                               g_strdup (name),
                               flatpak_permission_dup (other_permission));
        }
    }
}

static gboolean
flatpak_permissions_adds_permissions (GHashTable *old,
                                      GHashTable *new)
{
  const char *name;
  FlatpakPermission *new_permission;
  GHashTableIter iter;

  g_hash_table_iter_init (&iter, new);
  while (g_hash_table_iter_next (&iter,
                                 (gpointer *) &name,
                                 (gpointer *) &new_permission))
    {
      FlatpakPermission *old_permission = g_hash_table_lookup (old, name);

      if (old_permission)
        {
          if (flatpak_permission_adds_permissions (old_permission,
                                                   new_permission))
            return TRUE;
        }
      else
        {
          if (new_permission->allowed ||
              new_permission->conditionals->len > 0)
            return TRUE; /* new is completely new permission */
        }
    }

  return FALSE;
}

#ifdef INCLUDE_INTERNAL_TESTS
static void flatpak_permissions_test_basic (void)
{
  /* This is in canonical form, so must be kept sorted by name */
  const char *perms_strv[] =
    {
      /* Regular unconditional allowed (resets) */
      "allowed",

      /* conditional allowed with two conditions (doesn't reset) */
      "cond1", /* backwards compat */
      "if:cond1:check1",
      "if:cond1:check2",

      /* conditional allowed with one conditions (doesn't reset) */
      "cond2", /* backwards compat */
      "if:cond2:check3",

      /* conditional allowed (resets) */
      "!cond3", /* reset */
      "cond3", /* backwards compat */
      "if:cond3:check3",

      /* Regular unconditional disallowed (resets) */
      "!disallowed",

      NULL,
    };

  const char *perms_args[] =
    {
      "--socket=allowed",

      "--socket-if=cond1:check1",
      "--socket-if=cond1:check2",

      "--socket-if=cond2:check3",

      /* conditional allowed (resets) */
      "--nosocket=cond3",
      "--socket-if=cond3:check3",

      /* Regular unconditional disallowed (resets) */
      "--nosocket=disallowed",

      NULL,
    };

  GError *error = NULL;

  /* Test parsing */
  g_autoptr(GHashTable) perms = flatpak_permissions_new ();
  gboolean ok = flatpak_permissions_from_strv (perms, perms_strv, &error);
  g_assert_true(ok);
  g_assert_no_error(error);
  g_assert_nonnull(perms);

  g_assert_cmpint(g_hash_table_size (perms), ==, 5);

  FlatpakPermission *allowed = g_hash_table_lookup (perms, "allowed");
  g_assert_nonnull(allowed);
  g_assert_true(allowed->allowed);
  g_assert_true(allowed->reset);
  g_assert(allowed->conditionals->len == 0);

  FlatpakPermission *disallowed = g_hash_table_lookup (perms, "disallowed");
  g_assert_nonnull(disallowed);
  g_assert_false(disallowed->allowed);
  g_assert_true(disallowed->reset);
  g_assert(disallowed->conditionals->len == 0);

  FlatpakPermission *cond1 = g_hash_table_lookup (perms, "cond1");
  g_assert_nonnull(cond1);
  g_assert_false(cond1->allowed);
  g_assert_false(cond1->reset);
  g_assert(cond1->conditionals->len == 2);
  g_assert_cmpstr(cond1->conditionals->pdata[0], ==, "check1");
  g_assert_cmpstr(cond1->conditionals->pdata[1], ==, "check2");

  FlatpakPermission *cond2 = g_hash_table_lookup (perms, "cond2");
  g_assert_nonnull(cond2);
  g_assert_false(cond2->allowed);
  g_assert_false(cond2->reset);
  g_assert(cond2->conditionals->len == 1);
  g_assert_cmpstr(cond2->conditionals->pdata[0], ==, "check3");

  FlatpakPermission *cond3 = g_hash_table_lookup (perms, "cond3");
  g_assert_nonnull(cond3);
  g_assert_false(cond3->allowed);
  g_assert_true(cond3->reset);
  g_assert(cond3->conditionals->len == 1);
  g_assert_cmpstr(cond3->conditionals->pdata[0], ==, "check3");

  /* Test roundtrip */
  g_auto(GStrv) new_strv = flatpak_permissions_to_strv (perms, FALSE);
  g_assert_cmpstrv (perms_strv, new_strv);

  g_autoptr(GPtrArray) args = g_ptr_array_new_with_free_func (g_free);
  flatpak_permissions_to_args (perms, "socket", "nosocket", args);
  g_ptr_array_add(args, NULL);
  g_assert_cmpstrv (perms_args, args->pdata);

  /* Test copy */
  g_autoptr(FlatpakPermission) cond1_copy = flatpak_permission_dup(cond1);
  g_assert_nonnull(cond1_copy);
  g_assert_false(cond1_copy->allowed);
  g_assert_false(cond1_copy->reset);
  g_assert(cond1_copy->conditionals->len == 2);
  g_assert_cmpstr(cond1_copy->conditionals->pdata[0], ==, "check1");
  g_assert_cmpstr(cond1_copy->conditionals->pdata[1], ==, "check2");

  /* Test setters: */
  {
    g_autoptr(FlatpakPermission) copy = flatpak_permission_dup(cond1);
    flatpak_permission_set_allowed (copy);
    g_assert_true (copy->allowed);
    g_assert_true (copy->reset);
    g_assert(copy->conditionals->len == 0);
  }

  {
    g_autoptr(FlatpakPermission) copy = flatpak_permission_dup(cond1);
    flatpak_permission_set_not_allowed (copy);
    g_assert_false (copy->allowed);
    g_assert_true (copy->reset);
    g_assert(copy->conditionals->len == 0);
  }

  {
    g_autoptr(FlatpakPermission) copy = flatpak_permission_dup(cond1);
    flatpak_permission_set_allowed_if (copy, "check0");
    g_assert_false (copy->allowed);
    g_assert_false (copy->reset);
    g_assert(copy->conditionals->len == 3);
    g_assert_cmpstr(copy->conditionals->pdata[0], ==, "check0");
    g_assert_cmpstr(copy->conditionals->pdata[1], ==, "check1");
    g_assert_cmpstr(copy->conditionals->pdata[2], ==, "check2");
  }

  /* Test merge */
  {
    g_autoptr(FlatpakPermission) copy = flatpak_permission_dup(cond1);
    flatpak_permission_merge (copy, allowed);
    g_assert_true (copy->allowed);
    g_assert_true (copy->reset);
    g_assert(copy->conditionals->len == 0);
  }
  {
    g_autoptr(FlatpakPermission) copy = flatpak_permission_dup(cond1);
    flatpak_permission_merge (copy, disallowed);
    g_assert_false (copy->allowed);
    g_assert_true (copy->reset);
    g_assert(copy->conditionals->len == 0);
  }
  {
    /* Merge from non-reset conditional */
    g_autoptr(FlatpakPermission) copy = flatpak_permission_dup(cond1);
    flatpak_permission_merge (copy, cond2);
    g_assert_false (copy->allowed);
    g_assert_false (copy->reset);
    g_assert(copy->conditionals->len == 3);
  }
  {
    /* Merge from reset conditional */
    g_autoptr(FlatpakPermission) copy = flatpak_permission_dup(cond1);
    flatpak_permission_merge (copy, cond3);
    g_assert_false (copy->allowed);
    g_assert_true (copy->reset);
    g_assert(copy->conditionals->len == 1);
  }
}

static void flatpak_permissions_test_backwards_compat (void)
{
  {
    /* Deserialize if:wayland:foo;wayland
     * The last wayland makes it unconditional. */
    g_autoptr(FlatpakPermission) perm = flatpak_permission_new ();

    flatpak_permission_deserialize (perm, FALSE, "foo");
    flatpak_permission_deserialize (perm, FALSE, NULL);
    g_assert_true (perm->allowed);
    g_assert_true (perm->reset);
    g_assert_cmpint (perm->conditionals->len, ==, 0);
  }

  {
    /* Deserialize wayland;if:wayland:foo;wayland
     * Should be the same as the one above. The first wayland is just for
     * backwards compat. */
    g_autoptr(FlatpakPermission) perm = flatpak_permission_new ();

    flatpak_permission_deserialize (perm, FALSE, NULL);
    flatpak_permission_deserialize (perm, FALSE, "foo");
    flatpak_permission_deserialize (perm, FALSE, NULL);
    g_assert_true (perm->allowed);
    g_assert_true (perm->reset);
    g_assert_cmpint (perm->conditionals->len, ==, 0);
  }

  {
    /* Deserialize if:wayland:foo;wayland;if:wayland:bar
     * Now the wayland is before a conditional, so it acts as backwards
     * compat. */
    g_autoptr(FlatpakPermission) perm = flatpak_permission_new ();

    flatpak_permission_deserialize (perm, FALSE, "foo");
    flatpak_permission_deserialize (perm, FALSE, NULL);
    flatpak_permission_deserialize (perm, FALSE, "bar");
    g_assert_false (perm->allowed);
    g_assert_false (perm->reset);
    g_assert_cmpint (perm->conditionals->len, ==, 2);
    g_assert_cmpstr (perm->conditionals->pdata[0], ==, "bar");
    g_assert_cmpstr (perm->conditionals->pdata[1], ==, "foo");
  }
}

static void flatpak_permissions_test_fallback_x11 (void)
{
  g_autoptr(GHashTable) perms = NULL;
  g_autoptr(GHashTable) res_perms = NULL;

  {
    FlatpakPermission *fallback_x11;
    FlatpakPermission *wayland;
    g_autoptr(GError) error = NULL;
    gboolean ok;

    perms = flatpak_permissions_new ();
    ok = flatpak_permissions_from_strv (perms,
                                        (const char * []) {
                                          "fallback-x11",
                                          "wayland",
                                          NULL,
                                        },
                                        &error);
    g_assert_true (ok);
    g_assert_no_error (error);
    g_assert_nonnull (perms);

    g_assert_cmpint (g_hash_table_size (perms), ==, 2);

    fallback_x11 = g_hash_table_lookup (perms, "fallback-x11");
    g_assert_nonnull (fallback_x11);
    g_assert_true (fallback_x11->allowed);
    wayland = g_hash_table_lookup (perms, "wayland");
    g_assert_nonnull (wayland);
    g_assert_true (wayland->allowed);
  }

  /* If we only add a conditional, we don't reset fallback-x11 */
  {
    g_autoptr(GHashTable) perms2 = NULL;
    FlatpakPermission *x11;
    FlatpakPermission *fallback_x11;
    FlatpakPermission *wayland;
    g_autoptr(GError) error = NULL;
    gboolean ok;

    res_perms = flatpak_permissions_dup (perms);

    perms2 = flatpak_permissions_new ();
    ok = flatpak_permissions_from_strv (perms2,
                                        (const char * []) {
                                          "if:x11:foo",
                                          NULL,
                                        },
                                        &error);
    g_assert_true (ok);
    g_assert_no_error (error);
    g_assert_nonnull (perms2);

    g_assert_cmpint (g_hash_table_size (perms2), ==, 1);

    x11 = g_hash_table_lookup (perms2, "x11");
    g_assert_nonnull (x11);
    g_assert_false (x11->allowed);
    g_assert_false (x11->reset);
    g_assert_cmpint (x11->conditionals->len, ==, 1);
    g_assert_cmpstr (x11->conditionals->pdata[0], ==, "foo");

    flatpak_permissions_merge (res_perms, perms2);

    g_assert_cmpint (g_hash_table_size (res_perms), ==, 3);

    x11 = g_hash_table_lookup (res_perms, "x11");
    g_assert_nonnull (x11);
    g_assert_false (x11->allowed);
    g_assert_false (x11->reset);
    g_assert_cmpint (x11->conditionals->len, ==, 1);
    g_assert_cmpstr (x11->conditionals->pdata[0], ==, "foo");

    fallback_x11 = g_hash_table_lookup (res_perms, "fallback-x11");
    g_assert_nonnull (fallback_x11);
    g_assert_true (fallback_x11->allowed);

    wayland = g_hash_table_lookup (res_perms, "wayland");
    g_assert_nonnull (wayland);
    g_assert_true (wayland->allowed);
  }

  /* If we set x11, we reset conditionals *and* fallback-x11 */
  {
    g_autoptr(GHashTable) perms2 = NULL;
    FlatpakPermission *x11;
    FlatpakPermission *wayland;
    g_autoptr(GError) error = NULL;
    gboolean ok;

    res_perms = flatpak_permissions_dup (perms);

    perms2 = flatpak_permissions_new ();
    ok = flatpak_permissions_from_strv (perms2,
                                        (const char * []) {
                                          "x11",
                                          NULL,
                                        },
                                        &error);
    g_assert_true (ok);
    g_assert_no_error (error);
    g_assert_nonnull (perms2);

    g_assert_cmpint (g_hash_table_size (perms2), ==, 1);

    x11 = g_hash_table_lookup (perms2, "x11");
    g_assert_nonnull (x11);
    g_assert_true (x11->allowed);
    g_assert_true (x11->reset);

    flatpak_permissions_merge (res_perms, perms2);

    g_assert_cmpint (g_hash_table_size (res_perms), ==, 2);

    x11 = g_hash_table_lookup (res_perms, "x11");
    g_assert_nonnull (x11);
    g_assert_true (x11->allowed);

    wayland = g_hash_table_lookup (res_perms, "wayland");
    g_assert_nonnull (wayland);
    g_assert_true (wayland->allowed);
  }

  /* Only add a conditional and nosocket fallback-x11, gives nosocket fallback-x11 */
  {
    g_autoptr(GHashTable) perms2 = NULL;
    FlatpakPermission *x11;
    FlatpakPermission *fallback_x11;
    FlatpakPermission *wayland;
    g_autoptr(GError) error = NULL;
    gboolean ok;

    res_perms = flatpak_permissions_dup (perms);

    perms2 = flatpak_permissions_new ();
    ok = flatpak_permissions_from_strv (perms2,
                                        (const char * []) {
                                          "if:x11:foo",
                                          "!fallback-x11",
                                          NULL,
                                        },
                                        &error);
    g_assert_true (ok);
    g_assert_no_error (error);
    g_assert_nonnull (perms2);

    g_assert_cmpint (g_hash_table_size (perms2), ==, 2);

    x11 = g_hash_table_lookup (perms2, "x11");
    g_assert_nonnull (x11);
    g_assert_false (x11->allowed);
    g_assert_false (x11->reset);
    g_assert_cmpint (x11->conditionals->len, ==, 1);
    g_assert_cmpstr (x11->conditionals->pdata[0], ==, "foo");

    fallback_x11 = g_hash_table_lookup (perms2, "fallback-x11");
    g_assert_nonnull (fallback_x11);
    g_assert_false (fallback_x11->allowed);

    flatpak_permissions_merge (res_perms, perms2);

    g_assert_cmpint (g_hash_table_size (res_perms), ==, 3);

    x11 = g_hash_table_lookup (res_perms, "x11");
    g_assert_nonnull (x11);
    g_assert_false (x11->allowed);
    g_assert_false (x11->reset);
    g_assert_cmpint (x11->conditionals->len, ==, 1);
    g_assert_cmpstr (x11->conditionals->pdata[0], ==, "foo");

    fallback_x11 = g_hash_table_lookup (res_perms, "fallback-x11");
    g_assert_nonnull (fallback_x11);
    g_assert_false (fallback_x11->allowed);

    wayland = g_hash_table_lookup (res_perms, "wayland");
    g_assert_nonnull (wayland);
    g_assert_true (wayland->allowed);
  }
}

FLATPAK_INTERNAL_TEST("/context/permissions/basic",
                      flatpak_permissions_test_basic);
FLATPAK_INTERNAL_TEST("/context/permissions/backwards-compat",
                      flatpak_permissions_test_backwards_compat);
FLATPAK_INTERNAL_TEST("/context/permissions/fallback-x11",
                      flatpak_permissions_test_fallback_x11);

#endif /* INCLUDE_INTERNAL_TESTS */

FlatpakContext *
flatpak_context_new (void)
{
  FlatpakContext *context;

  context = g_slice_new0 (FlatpakContext);
  context->env_vars = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
  context->persistent = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
  /* filename or special filesystem name => FlatpakFilesystemMode */
  context->filesystems = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
  context->session_bus_policy = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
  context->system_bus_policy = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
  context->a11y_bus_policy = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
  context->generic_policy = g_hash_table_new_full (g_str_hash, g_str_equal,
                                                   g_free, (GDestroyNotify) g_strfreev);
  context->enumerable_usb_devices = g_hash_table_new_full (g_str_hash, g_str_equal,
                                                           g_free, (GDestroyNotify) flatpak_usb_query_free);
  context->hidden_usb_devices = g_hash_table_new_full (g_str_hash, g_str_equal,
                                                       g_free, (GDestroyNotify) flatpak_usb_query_free);
  context->shares_permissions = flatpak_permissions_new ();
  context->socket_permissions = flatpak_permissions_new ();
  context->device_permissions = flatpak_permissions_new ();
  context->features_permissions = flatpak_permissions_new ();

  return context;
}

void
flatpak_context_free (FlatpakContext *context)
{
  g_hash_table_destroy (context->env_vars);
  g_hash_table_destroy (context->persistent);
  g_hash_table_destroy (context->filesystems);
  g_hash_table_destroy (context->session_bus_policy);
  g_hash_table_destroy (context->system_bus_policy);
  g_hash_table_destroy (context->a11y_bus_policy);
  g_hash_table_destroy (context->generic_policy);
  g_hash_table_destroy (context->enumerable_usb_devices);
  g_hash_table_destroy (context->hidden_usb_devices);
  g_hash_table_destroy (context->shares_permissions);
  g_hash_table_destroy (context->device_permissions);
  g_hash_table_destroy (context->socket_permissions);
  g_hash_table_destroy (context->features_permissions);
  g_slice_free (FlatpakContext, context);
}

static guint32
flatpak_context_bitmask_from_string (const char *name, const char **names)
{
  guint32 i;

  for (i = 0; names[i] != NULL; i++)
    {
      if (strcmp (names[i], name) == 0)
        return 1 << i;
    }

  return 0;
}

static FlatpakContextShares
flatpak_context_share_from_string (const char *string, GError **error)
{
  FlatpakContextShares shares = flatpak_context_bitmask_from_string (string, flatpak_context_shares);

  if (shares == 0)
    {
      g_autofree char *values = g_strjoinv (", ", (char **) flatpak_context_shares);
      g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_FAILED,
                   _("Unknown share type %s, valid types are: %s"), string, values);
    }

  return shares;
}

static FlatpakPolicy
flatpak_policy_from_string (const char *string, GError **error)
{
  const char *policies[] = { "none", "see", "talk", "own", NULL };
  int i;
  g_autofree char *values = NULL;

  for (i = 0; policies[i]; i++)
    {
      if (strcmp (string, policies[i]) == 0)
        return i;
    }

  values = g_strjoinv (", ", (char **) policies);
  g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_FAILED,
               _("Unknown policy type %s, valid types are: %s"), string, values);

  return -1;
}

static const char *
flatpak_policy_to_string (FlatpakPolicy policy)
{
  if (policy == FLATPAK_POLICY_SEE)
    return "see";
  if (policy == FLATPAK_POLICY_TALK)
    return "talk";
  if (policy == FLATPAK_POLICY_OWN)
    return "own";

  return "none";
}

static gboolean
flatpak_verify_dbus_name (const char *name, GError **error)
{
  const char *name_part;
  g_autofree char *tmp = NULL;

  if (g_str_has_suffix (name, ".*"))
    {
      tmp = g_strndup (name, strlen (name) - 2);
      name_part = tmp;
    }
  else
    {
      name_part = name;
    }

  if (g_dbus_is_name (name_part) && !g_dbus_is_unique_name (name_part))
    return TRUE;

  g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_FAILED,
               _("Invalid dbus name %s"), name);
  return FALSE;
}

static FlatpakContextSockets
flatpak_context_socket_from_string (const char *string, GError **error)
{
  FlatpakContextSockets sockets = flatpak_context_bitmask_from_string (string, flatpak_context_sockets);

  if (sockets == 0)
    {
      g_autofree char *values = g_strjoinv (", ", (char **) flatpak_context_sockets);
      g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_FAILED,
                   _("Unknown socket type %s, valid types are: %s"), string, values);
    }

  return sockets;
}

static FlatpakContextDevices
flatpak_context_device_from_string (const char *string, GError **error)
{
  FlatpakContextDevices devices = flatpak_context_bitmask_from_string (string, flatpak_context_devices);

  if (devices == 0)
    {
      g_autofree char *values = g_strjoinv (", ", (char **) flatpak_context_devices);
      g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_FAILED,
                   _("Unknown device type %s, valid types are: %s"), string, values);
    }
  return devices;
}

static FlatpakContextFeatures
flatpak_context_feature_from_string (const char *string, GError **error)
{
  FlatpakContextFeatures feature = flatpak_context_bitmask_from_string (string, flatpak_context_features);

  if (feature == 0)
    {
      g_autofree char *values = g_strjoinv (", ", (char **) flatpak_context_features);
      g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_FAILED,
                   _("Unknown feature type %s, valid types are: %s"), string, values);
    }

  return feature;
}

static void
flatpak_context_set_env_var (FlatpakContext *context,
                             const char     *name,
                             const char     *value)
{
  g_hash_table_insert (context->env_vars, g_strdup (name), g_strdup (value));
}

void
flatpak_context_set_session_bus_policy (FlatpakContext *context,
                                        const char     *name,
                                        FlatpakPolicy   policy)
{
  g_hash_table_insert (context->session_bus_policy, g_strdup (name), GINT_TO_POINTER (policy));
}

void
flatpak_context_set_a11y_bus_policy (FlatpakContext *context,
                                     const char     *name,
                                     FlatpakPolicy   policy)
{
  g_hash_table_insert (context->a11y_bus_policy, g_strdup (name), GINT_TO_POINTER (policy));
}

GStrv
flatpak_context_get_session_bus_policy_allowed_own_names (FlatpakContext *context)
{
  GHashTableIter iter;
  gpointer key, value;
  g_autoptr(GPtrArray) names = g_ptr_array_new_with_free_func (g_free);

  g_hash_table_iter_init (&iter, context->session_bus_policy);
  while (g_hash_table_iter_next (&iter, &key, &value))
    if (GPOINTER_TO_INT (value) == FLATPAK_POLICY_OWN)
      g_ptr_array_add (names, g_strdup (key));

  g_ptr_array_add (names, NULL);
  return (GStrv) g_ptr_array_free (g_steal_pointer (&names), FALSE);
}

void
flatpak_context_set_system_bus_policy (FlatpakContext *context,
                                       const char     *name,
                                       FlatpakPolicy   policy)
{
  g_hash_table_insert (context->system_bus_policy, g_strdup (name), GINT_TO_POINTER (policy));
}

static void
flatpak_context_apply_generic_policy (FlatpakContext *context,
                                      const char     *key,
                                      const char     *value)
{
  GPtrArray *new = g_ptr_array_new ();
  const char **old_v;
  int i;

  g_assert (strchr (key, '.') != NULL);

  old_v = g_hash_table_lookup (context->generic_policy, key);
  for (i = 0; old_v != NULL && old_v[i] != NULL; i++)
    {
      const char *old = old_v[i];
      const char *cmp1 = old;
      const char *cmp2 = value;
      if (*cmp1 == '!')
        cmp1++;
      if (*cmp2 == '!')
        cmp2++;
      if (strcmp (cmp1, cmp2) != 0)
        g_ptr_array_add (new, g_strdup (old));
    }

  g_ptr_array_add (new, g_strdup (value));
  g_ptr_array_add (new, NULL);

  g_hash_table_insert (context->generic_policy, g_strdup (key),
                       g_ptr_array_free (new, FALSE));
}

static void
flatpak_context_add_query_to (GHashTable            *queries,
                              const FlatpakUsbQuery *usb_query)
{
  g_autoptr(FlatpakUsbQuery) copy = NULL;
  g_autoptr(GString) string = NULL;

  g_assert (queries != NULL);
  g_assert (usb_query != NULL && usb_query->rules != NULL);

  copy = flatpak_usb_query_copy (usb_query);

  string = g_string_new (NULL);
  flatpak_usb_query_print (usb_query, string);

  g_hash_table_insert (queries,
                       g_strdup (string->str),
                       g_steal_pointer (&copy));
}

static void
flatpak_context_add_usb_query (FlatpakContext        *context,
                               const FlatpakUsbQuery *usb_query)
{
  flatpak_context_add_query_to (context->enumerable_usb_devices, usb_query);
}

static void
flatpak_context_add_nousb_query (FlatpakContext        *context,
                                 const FlatpakUsbQuery *usb_query)
{
  flatpak_context_add_query_to (context->hidden_usb_devices, usb_query);
}

static gboolean
flatpak_context_add_usb_list (FlatpakContext *context,
                              const char     *list,
                              GError        **error)
{
  return flatpak_usb_parse_usb_list (list, context->enumerable_usb_devices,
                                     context->hidden_usb_devices, error);
}

static gboolean
flatpak_context_add_usb_list_from_file (FlatpakContext *context,
                                        const char     *path,
                                        GError        **error)
{
  g_autofree char *contents = NULL;

  if (!flatpak_validate_path_characters (path, error))
    return FALSE;

  if (!g_file_get_contents (path, &contents, NULL, error))
    return FALSE;

  return flatpak_usb_parse_usb_list (contents, context->enumerable_usb_devices,
                                     context->hidden_usb_devices, error);
}

static gboolean
flatpak_context_set_persistent (FlatpakContext *context,
                                const char     *path,
                                GError        **error)
{
  if (!flatpak_validate_path_characters (path, error))
    return FALSE;

  g_hash_table_insert (context->persistent, g_strdup (path), GINT_TO_POINTER (1));
  return TRUE;
}

static gboolean
get_xdg_dir_from_prefix (const char  *prefix,
                         const char **where,
                         const char **dir)
{
  if (strcmp (prefix, "xdg-data") == 0)
    {
      if (where)
        *where = "data";
      if (dir)
        *dir = g_get_user_data_dir ();
      return TRUE;
    }
  if (strcmp (prefix, "xdg-cache") == 0)
    {
      if (where)
        *where = "cache";
      if (dir)
        *dir = g_get_user_cache_dir ();
      return TRUE;
    }
  if (strcmp (prefix, "xdg-config") == 0)
    {
      if (where)
        *where = "config";
      if (dir)
        *dir = g_get_user_config_dir ();
      return TRUE;
    }
  return FALSE;
}

/* This looks only in the xdg dirs (config, cache, data), not the user
   definable ones */
static char *
get_xdg_dir_from_string (const char  *filesystem,
                         const char **suffix,
                         const char **where)
{
  const char *slash;
  const char *rest;
  g_autofree char *prefix = NULL;
  const char *dir = NULL;
  gsize len;

  slash = strchr (filesystem, '/');

  if (slash)
    len = slash - filesystem;
  else
    len = strlen (filesystem);

  rest = filesystem + len;
  while (*rest == '/')
    rest++;

  if (suffix != NULL)
    *suffix = rest;

  prefix = g_strndup (filesystem, len);

  if (get_xdg_dir_from_prefix (prefix, where, &dir))
    return g_build_filename (dir, rest, NULL);

  return NULL;
}

static gboolean
get_xdg_user_dir_from_string (const char  *filesystem,
                              const char **config_key,
                              const char **suffix,
                              char **dir)
{
  const char *slash;
  const char *rest;
  g_autofree char *prefix = NULL;
  gsize len;
  const char *dir_out = NULL;

  slash = strchr (filesystem, '/');

  if (slash)
    len = slash - filesystem;
  else
    len = strlen (filesystem);

  rest = filesystem + len;
  while (*rest == '/')
    rest++;

  if (suffix)
    *suffix = rest;

  prefix = g_strndup (filesystem, len);

  if (strcmp (prefix, "xdg-desktop") == 0)
    {
      if (config_key)
        *config_key = "XDG_DESKTOP_DIR";
      if (dir)
        *dir = g_strdup (g_get_user_special_dir (G_USER_DIRECTORY_DESKTOP));
      return TRUE;
    }
  if (strcmp (prefix, "xdg-documents") == 0)
    {
      if (config_key)
        *config_key = "XDG_DOCUMENTS_DIR";
      if (dir)
        *dir = g_strdup (g_get_user_special_dir (G_USER_DIRECTORY_DOCUMENTS));
      return TRUE;
    }
  if (strcmp (prefix, "xdg-download") == 0)
    {
      if (config_key)
        *config_key = "XDG_DOWNLOAD_DIR";
      if (dir)
        *dir = g_strdup (g_get_user_special_dir (G_USER_DIRECTORY_DOWNLOAD));
      return TRUE;
    }
  if (strcmp (prefix, "xdg-music") == 0)
    {
      if (config_key)
        *config_key = "XDG_MUSIC_DIR";
      if (dir)
        *dir = g_strdup (g_get_user_special_dir (G_USER_DIRECTORY_MUSIC));
      return TRUE;
    }
  if (strcmp (prefix, "xdg-pictures") == 0)
    {
      if (config_key)
        *config_key = "XDG_PICTURES_DIR";
      if (dir)
        *dir = g_strdup (g_get_user_special_dir (G_USER_DIRECTORY_PICTURES));
      return TRUE;
    }
  if (strcmp (prefix, "xdg-public-share") == 0)
    {
      if (config_key)
        *config_key = "XDG_PUBLICSHARE_DIR";
      if (dir)
        *dir = g_strdup (g_get_user_special_dir (G_USER_DIRECTORY_PUBLIC_SHARE));
      return TRUE;
    }
  if (strcmp (prefix, "xdg-templates") == 0)
    {
      if (config_key)
        *config_key = "XDG_TEMPLATES_DIR";
      if (dir)
        *dir = g_strdup (g_get_user_special_dir (G_USER_DIRECTORY_TEMPLATES));
      return TRUE;
    }
  if (strcmp (prefix, "xdg-videos") == 0)
    {
      if (config_key)
        *config_key = "XDG_VIDEOS_DIR";
      if (dir)
        *dir = g_strdup (g_get_user_special_dir (G_USER_DIRECTORY_VIDEOS));
      return TRUE;
    }
  if (get_xdg_dir_from_prefix (prefix, NULL, &dir_out))
    {
      if (config_key)
        *config_key = NULL;
      if (dir)
        *dir = g_strdup (dir_out);
      return TRUE;
    }
  /* Don't support xdg-run without suffix, because that doesn't work */
  if (strcmp (prefix, "xdg-run") == 0 &&
      *rest != 0)
    {
      if (config_key)
        *config_key = NULL;
      if (dir)
        *dir = flatpak_get_real_xdg_runtime_dir ();
      return TRUE;
    }

  return FALSE;
}

static char *
unparse_filesystem_flags (const char           *path,
                          FlatpakFilesystemMode mode)
{
  g_autoptr(GString) s = g_string_new ("");
  const char *p;

  for (p = path; *p != 0; p++)
    {
      if (*p == ':')
        g_string_append (s, "\\:");
      else if (*p == '\\')
        g_string_append (s, "\\\\");
      else
        g_string_append_c (s, *p);
    }

  switch (mode)
    {
    case FLATPAK_FILESYSTEM_MODE_READ_ONLY:
      g_string_append (s, ":ro");
      break;

    case FLATPAK_FILESYSTEM_MODE_CREATE:
      g_string_append (s, ":create");
      break;

    case FLATPAK_FILESYSTEM_MODE_READ_WRITE:
      break;

    case FLATPAK_FILESYSTEM_MODE_NONE:
      g_string_insert_c (s, 0, '!');

      if (g_str_has_suffix (s->str, "-reset"))
        {
          g_string_truncate (s, s->len - 6);
          g_string_append (s, ":reset");
        }
      break;

    default:
      g_warning ("Unexpected filesystem mode %d", mode);
      break;
    }

  return g_string_free (g_steal_pointer (&s), FALSE);
}

static char *
parse_filesystem_flags (const char            *filesystem,
                        gboolean               negated,
                        FlatpakFilesystemMode *mode_out,
                        GError               **error)
{
  g_autoptr(GString) s = g_string_new ("");
  const char *p, *suffix;
  FlatpakFilesystemMode mode;
  gboolean reset = FALSE;

  p = filesystem;
  while (*p != 0 && *p != ':')
    {
      if (*p == '\\')
        {
          p++;
          if (*p != 0)
            g_string_append_c (s, *p++);
        }
      else
        g_string_append_c (s, *p++);
    }

  if (negated)
    mode = FLATPAK_FILESYSTEM_MODE_NONE;
  else
    mode = FLATPAK_FILESYSTEM_MODE_READ_WRITE;

  if (g_str_equal (s->str, "host-reset"))
    {
      reset = TRUE;

      if (!negated)
        {
          g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_FAILED,
                       "Filesystem token \"%s\" is only applicable for --nofilesystem",
                       s->str);
          return NULL;
        }

      if (*p != '\0')
        {
          g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_FAILED,
                       "Filesystem token \"%s\" cannot be used with a suffix",
                       s->str);
          return NULL;
        }
    }

  if (*p == ':')
    {
      suffix = p + 1;

      if (strcmp (suffix, "ro") == 0)
        mode = FLATPAK_FILESYSTEM_MODE_READ_ONLY;
      else if (strcmp (suffix, "rw") == 0)
        mode = FLATPAK_FILESYSTEM_MODE_READ_WRITE;
      else if (strcmp (suffix, "create") == 0)
        mode = FLATPAK_FILESYSTEM_MODE_CREATE;
      else if (strcmp (suffix, "reset") == 0)
        reset = TRUE;
      else if (*suffix != 0)
        g_warning ("Unexpected filesystem suffix %s, ignoring", suffix);

      if (negated && mode != FLATPAK_FILESYSTEM_MODE_NONE)
        {
          g_warning ("Filesystem suffix \"%s\" is not applicable for --nofilesystem",
                     suffix);
          mode = FLATPAK_FILESYSTEM_MODE_NONE;
        }

      if (reset)
        {
          if (!negated)
            {
              g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_FAILED,
                           "Filesystem suffix \"%s\" only applies to --nofilesystem",
                           suffix);
              return NULL;
            }

          if (!g_str_equal (s->str, "host"))
            {
              g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_FAILED,
                           "Filesystem suffix \"%s\" can only be applied to "
                           "--nofilesystem=host",
                           suffix);
              return NULL;
            }

          /* We internally handle host:reset (etc) as host-reset, only exposing it as a flag in the public
             part to allow it to be ignored (with a warning) for old flatpak versions */
          g_string_append (s, "-reset");
        }
    }

  /* Postcondition check: the code above should make some results
   * impossible */
  if (negated)
    {
      g_assert (mode == FLATPAK_FILESYSTEM_MODE_NONE);
    }
  else
    {
      g_assert (mode > FLATPAK_FILESYSTEM_MODE_NONE);
      /* This flag is only applicable to --nofilesystem */
      g_assert (!reset);
    }

  /* Postcondition check: filesystem token is host-reset iff reset flag
   * was found */
  if (reset)
    g_assert (g_str_equal (s->str, "host-reset"));
  else
    g_assert (!g_str_equal (s->str, "host-reset"));

  if (mode_out)
    *mode_out = mode;

  return g_string_free (g_steal_pointer (&s), FALSE);
}

gboolean
flatpak_context_parse_filesystem (const char             *filesystem_and_mode,
                                  gboolean                negated,
                                  char                  **filesystem_out,
                                  FlatpakFilesystemMode  *mode_out,
                                  GError                **error)
{
  g_autofree char *filesystem = NULL;
  char *slash;

  if (!flatpak_validate_path_characters (filesystem_and_mode, error))
    return FALSE;

  filesystem = parse_filesystem_flags (filesystem_and_mode, negated, mode_out, error);
  if (filesystem == NULL)
    return FALSE;

  /* Forbid /../ in paths */
  if (g_str_has_suffix (filesystem, "/..") ||
      strstr (filesystem, "/../") != NULL)
    {
      g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE,
                   _("Filesystem location \"%s\" contains \"..\""),
                   filesystem);
      return FALSE;
    }

  slash = strchr (filesystem, '/');

  if (slash != NULL)
    {
      /* Convert "//" and "/./" to "/" */
      for (; slash != NULL; slash = strchr (slash + 1, '/'))
        {
          while (TRUE)
            {
              if (slash[1] == '/')
                memmove (slash + 1, slash + 2, strlen (slash + 2) + 1);
              else if (slash[1] == '.' && slash[2] == '/')
                memmove (slash + 1, slash + 3, strlen (slash + 3) + 1);
              else
                break;
            }
        }

      /* Eliminate trailing "/." or "/". */
      while (TRUE)
        {
          slash = strrchr (filesystem, '/');

          if (slash != NULL &&
              ((slash != filesystem && slash[1] == '\0') ||
               (slash[1] == '.' && slash[2] == '\0')))
            *slash = '\0';
          else
            break;
        }

      if (filesystem[0] == '/' && filesystem[1] == '\0')
        {
          /* We don't allow --filesystem=/ as equivalent to host, because
           * it doesn't do what you'd think: --filesystem=host mounts some
           * host directories in /run/host, not in the root. */
          g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE,
                       _("--filesystem=/ is not available, "
                         "use --filesystem=host for a similar result"));
          return FALSE;
        }
    }

  if (g_strv_contains (flatpak_context_special_filesystems, filesystem) ||
      get_xdg_user_dir_from_string (filesystem, NULL, NULL, NULL) ||
      g_str_has_prefix (filesystem, "~/") ||
      g_str_has_prefix (filesystem, "/"))
    {
      if (filesystem_out != NULL)
        *filesystem_out = g_steal_pointer (&filesystem);

      return TRUE;
    }

  if (strcmp (filesystem, "~") == 0)
    {
      if (filesystem_out != NULL)
        *filesystem_out = g_strdup ("home");

      return TRUE;
    }

  if (g_str_has_prefix (filesystem, "home/"))
    {
      if (filesystem_out != NULL)
        *filesystem_out = g_strconcat ("~/", filesystem + 5, NULL);

      return TRUE;
    }

  g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_FAILED,
               _("Unknown filesystem location %s, valid locations are: host, host-os, host-etc, host-root, home, xdg-*[/…], ~/dir, /dir"), filesystem);
  return FALSE;
}

static void
flatpak_context_take_filesystem (FlatpakContext        *context,
                                 char                  *fs,
                                 FlatpakFilesystemMode  mode)
{
  /* Special case: --nofilesystem=host-reset implies --nofilesystem=host.
   * --filesystem=host-reset (or host:reset) is not allowed. */
  if (g_str_equal (fs, "host-reset"))
    {
      g_return_if_fail (mode == FLATPAK_FILESYSTEM_MODE_NONE);
      g_hash_table_insert (context->filesystems, g_strdup ("host"), GINT_TO_POINTER (mode));
    }

  g_hash_table_insert (context->filesystems, fs, GINT_TO_POINTER (mode));
}

void
flatpak_context_merge (FlatpakContext *context,
                       FlatpakContext *other)
{
  GHashTableIter iter;
  gpointer key, value;

  flatpak_permissions_merge (context->shares_permissions,
                             other->shares_permissions);
  flatpak_permissions_merge (context->socket_permissions,
                             other->socket_permissions);
  flatpak_permissions_merge (context->device_permissions,
                             other->device_permissions);
  flatpak_permissions_merge (context->features_permissions,
                             other->features_permissions);

  g_hash_table_iter_init (&iter, other->env_vars);
  while (g_hash_table_iter_next (&iter, &key, &value))
    g_hash_table_insert (context->env_vars, g_strdup (key), g_strdup (value));

  g_hash_table_iter_init (&iter, other->persistent);
  while (g_hash_table_iter_next (&iter, &key, &value))
    g_hash_table_insert (context->persistent, g_strdup (key), value);

  /* We first handle host:reset, as it overrides all other keys from the parent */
  if (g_hash_table_lookup_extended (other->filesystems, "host-reset", NULL, &value))
    {
      g_warn_if_fail (GPOINTER_TO_INT (value) == FLATPAK_FILESYSTEM_MODE_NONE);
      g_hash_table_remove_all (context->filesystems);
    }

  /* Then set the new ones, which includes propagating host:reset. */
  g_hash_table_iter_init (&iter, other->filesystems);
  while (g_hash_table_iter_next (&iter, &key, &value))
    g_hash_table_insert (context->filesystems, g_strdup (key), value);

  g_hash_table_iter_init (&iter, other->session_bus_policy);
  while (g_hash_table_iter_next (&iter, &key, &value))
    g_hash_table_insert (context->session_bus_policy, g_strdup (key), value);

  g_hash_table_iter_init (&iter, other->system_bus_policy);
  while (g_hash_table_iter_next (&iter, &key, &value))
    g_hash_table_insert (context->system_bus_policy, g_strdup (key), value);

  g_hash_table_iter_init (&iter, other->a11y_bus_policy);
  while (g_hash_table_iter_next (&iter, &key, &value))
    g_hash_table_insert (context->a11y_bus_policy, g_strdup (key), value);

  g_hash_table_iter_init (&iter, other->generic_policy);
  while (g_hash_table_iter_next (&iter, &key, &value))
    {
      const char **policy_values = (const char **) value;
      int i;

      for (i = 0; policy_values[i] != NULL; i++)
        flatpak_context_apply_generic_policy (context, (char *) key, policy_values[i]);
    }

  g_hash_table_iter_init (&iter, other->enumerable_usb_devices);
  while (g_hash_table_iter_next (&iter, NULL, &value))
    flatpak_context_add_usb_query (context, value);

  g_hash_table_iter_init (&iter, other->hidden_usb_devices);
  while (g_hash_table_iter_next (&iter, NULL, &value))
    flatpak_context_add_nousb_query (context, value);
}

static gboolean
parse_if_option (const char  *option_name,
                 const char  *value,
                 char       **name_out,
                 char       **condition_out,
                 GError     **error)
{
  g_auto(GStrv) tokens = g_strsplit (value, ":", 2);

  if (g_strv_length (tokens) != 2)
    {
      g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_FAILED,
                   _("Invalid syntax for %s: %s"), option_name, value);
      return FALSE;
    }

  *name_out = g_strdup (tokens[0]);
  *condition_out = g_strdup (tokens[1]);
  return TRUE;
}

static gboolean
option_share_cb (const gchar *option_name,
                 const gchar *value,
                 gpointer     data,
                 GError     **error)
{
  FlatpakContext *context = data;
  FlatpakContextShares share;

  share = flatpak_context_share_from_string (value, error);
  if (share == 0)
    return FALSE;

  flatpak_permissions_set_allowed (context->shares_permissions, value);

  return TRUE;
}

static gboolean
option_unshare_cb (const gchar *option_name,
                   const gchar *value,
                   gpointer     data,
                   GError     **error)
{
  FlatpakContext *context = data;
  FlatpakContextShares share;

  share = flatpak_context_share_from_string (value, error);
  if (share == 0)
    return FALSE;

  flatpak_permissions_set_not_allowed (context->shares_permissions, value);

  return TRUE;
}

static gboolean
option_share_if_cb (const gchar  *option_name,
                    const gchar  *value,
                    gpointer      data,
                    GError      **error)
{
  FlatpakContext *context = data;
  g_autofree char *name = NULL;
  g_autofree char *condition = NULL;
  FlatpakContextShares share;

  if (!parse_if_option (option_name, value, &name, &condition, error))
    return FALSE;

  share = flatpak_context_share_from_string (name, error);
  if (share == 0)
    return FALSE;

  flatpak_permissions_set_allowed_if (context->shares_permissions,
                                      name, condition);
  return TRUE;
}

static gboolean
option_socket_cb (const gchar *option_name,
                  const gchar *value,
                  gpointer     data,
                  GError     **error)
{
  FlatpakContext *context = data;
  FlatpakContextSockets socket;

  socket = flatpak_context_socket_from_string (value, error);
  if (socket == 0)
    return FALSE;

  flatpak_permissions_set_allowed (context->socket_permissions,
                                   value);

  return TRUE;
}

static gboolean
option_nosocket_cb (const gchar *option_name,
                    const gchar *value,
                    gpointer     data,
                    GError     **error)
{
  FlatpakContext *context = data;
  FlatpakContextSockets socket;

  socket = flatpak_context_socket_from_string (value, error);
  if (socket == 0)
    return FALSE;

  flatpak_permissions_set_not_allowed (context->socket_permissions,
                                       value);

  return TRUE;
}

static gboolean
option_socket_if_cb (const gchar  *option_name,
                     const gchar  *value,
                     gpointer      data,
                     GError      **error)
{
  FlatpakContext *context = data;
  g_autofree char *name = NULL;
  g_autofree char *condition = NULL;
  FlatpakContextSockets socket;

  if (!parse_if_option (option_name, value, &name, &condition, error))
    return FALSE;

  socket = flatpak_context_socket_from_string (name, error);
  if (socket == 0)
    return FALSE;

  if (socket == FLATPAK_CONTEXT_SOCKET_FALLBACK_X11)
    {
      g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_FAILED,
                   _("fallback-x11 can not be conditional"));
      return FALSE;
    }

  flatpak_permissions_set_allowed_if (context->socket_permissions,
                                      name, condition);
  return TRUE;
}

static gboolean
option_device_cb (const gchar *option_name,
                  const gchar *value,
                  gpointer     data,
                  GError     **error)
{
  FlatpakContext *context = data;
  FlatpakContextDevices device;

  device = flatpak_context_device_from_string (value, error);
  if (device == 0)
    return FALSE;

  flatpak_permissions_set_allowed (context->device_permissions,
                                   value);

  return TRUE;
}

static gboolean
option_nodevice_cb (const gchar *option_name,
                    const gchar *value,
                    gpointer     data,
                    GError     **error)
{
  FlatpakContext *context = data;
  FlatpakContextDevices device;

  device = flatpak_context_device_from_string (value, error);
  if (device == 0)
    return FALSE;

  flatpak_permissions_set_not_allowed (context->device_permissions,
                                       value);

  return TRUE;
}

static gboolean
option_device_if_cb (const gchar  *option_name,
                     const gchar  *value,
                     gpointer      data,
                     GError      **error)
{
  FlatpakContext *context = data;
  g_autofree char *name = NULL;
  g_autofree char *condition = NULL;
  FlatpakContextDevices device;

  if (!parse_if_option (option_name, value, &name, &condition, error))
    return FALSE;

  device = flatpak_context_device_from_string (name, error);
  if (device == 0)
    return FALSE;

  flatpak_permissions_set_allowed_if (context->device_permissions,
                                      name, condition);
  return TRUE;
}

static gboolean
option_allow_cb (const gchar *option_name,
                 const gchar *value,
                 gpointer     data,
                 GError     **error)
{
  FlatpakContext *context = data;
  FlatpakContextFeatures feature;

  feature = flatpak_context_feature_from_string (value, error);
  if (feature == 0)
    return FALSE;

  flatpak_permissions_set_allowed (context->features_permissions, value);

  return TRUE;
}

static gboolean
option_disallow_cb (const gchar *option_name,
                    const gchar *value,
                    gpointer     data,
                    GError     **error)
{
  FlatpakContext *context = data;
  FlatpakContextFeatures feature;

  feature = flatpak_context_feature_from_string (value, error);
  if (feature == 0)
    return FALSE;

  flatpak_permissions_set_not_allowed (context->features_permissions, value);

  return TRUE;
}

static gboolean
option_allow_if_cb (const gchar  *option_name,
                    const gchar  *value,
                    gpointer      data,
                    GError      **error)
{
  FlatpakContext *context = data;
  g_autofree char *name = NULL;
  g_autofree char *condition = NULL;
  FlatpakContextFeatures feature;

  if (!parse_if_option (option_name, value, &name, &condition, error))
    return FALSE;

  feature = flatpak_context_feature_from_string (name, error);
  if (feature == 0)
    return FALSE;

  flatpak_permissions_set_allowed_if (context->features_permissions,
                                      name, condition);
  return TRUE;
}

static gboolean
option_filesystem_cb (const gchar *option_name,
                      const gchar *value,
                      gpointer     data,
                      GError     **error)
{
  FlatpakContext *context = data;
  g_autofree char *fs = NULL;
  FlatpakFilesystemMode mode;

  if (!flatpak_context_parse_filesystem (value, FALSE, &fs, &mode, error))
    return FALSE;

  flatpak_context_take_filesystem (context, g_steal_pointer (&fs), mode);
  return TRUE;
}

static gboolean
option_nofilesystem_cb (const gchar *option_name,
                        const gchar *value,
                        gpointer     data,
                        GError     **error)
{
  FlatpakContext *context = data;
  g_autofree char *fs = NULL;
  FlatpakFilesystemMode mode;

  if (!flatpak_context_parse_filesystem (value, TRUE, &fs, &mode, error))
    return FALSE;

  flatpak_context_take_filesystem (context, g_steal_pointer (&fs),
                                   FLATPAK_FILESYSTEM_MODE_NONE);
  return TRUE;
}

static gboolean
option_env_cb (const gchar *option_name,
               const gchar *value,
               gpointer     data,
               GError     **error)
{
  FlatpakContext *context = data;
  g_auto(GStrv) split = g_strsplit (value, "=", 2);

  if (split == NULL || split[0] == NULL || split[0][0] == 0 || split[1] == NULL)
    {
      g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_FAILED,
                   _("Invalid env format %s"), value);
      return FALSE;
    }

  flatpak_context_set_env_var (context, split[0], split[1]);
  return TRUE;
}

gboolean
flatpak_context_parse_env_block (FlatpakContext *context,
                                 const char *data,
                                 gsize length,
                                 GError **error)
{
  g_auto(GStrv) env_vars = NULL;
  int i;

  env_vars = flatpak_parse_env_block (data, length, error);
  if (env_vars == NULL)
    return FALSE;

  for (i = 0; env_vars[i] != NULL; i++)
    {
      g_auto(GStrv) split = g_strsplit (env_vars[i], "=", 2);

      g_assert (g_strv_length (split) == 2);
      g_assert (split[0][0] != '\0');

      flatpak_context_set_env_var (context,
                                   split[0], split[1]);
    }

  return TRUE;
}

gboolean
flatpak_context_parse_env_fd (FlatpakContext *context,
                              int fd,
                              GError **error)
{
  g_autoptr(GBytes) env_block = NULL;
  const char *data;
  gsize len;

  env_block = glnx_fd_readall_bytes (fd, NULL, error);

  if (env_block == NULL)
    return FALSE;

  data = g_bytes_get_data (env_block, &len);
  return flatpak_context_parse_env_block (context, data, len, error);
}

static gboolean
option_env_fd_cb (const gchar *option_name,
                  const gchar *value,
                  gpointer     data,
                  GError     **error)
{
  FlatpakContext *context = data;
  glnx_autofd int fd = -1;

  fd = flatpak_accept_fd_argument (option_name, value, error);

  if (fd < 0)
    return FALSE;

  return flatpak_context_parse_env_fd (context, fd, error);
}

static gboolean
option_unset_env_cb (const gchar *option_name,
                     const gchar *value,
                     gpointer     data,
                     GError     **error)
{
  FlatpakContext *context = data;

  if (strchr (value, '=') != NULL)
    {
      g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_FAILED,
                   _("Environment variable name must not contain '=': %s"), value);
      return FALSE;
    }

  flatpak_context_set_env_var (context, value, NULL);
  return TRUE;
}

static gboolean
option_own_name_cb (const gchar *option_name,
                    const gchar *value,
                    gpointer     data,
                    GError     **error)
{
  FlatpakContext *context = data;

  if (!flatpak_verify_dbus_name (value, error))
    return FALSE;

  flatpak_context_set_session_bus_policy (context, value, FLATPAK_POLICY_OWN);
  return TRUE;
}

static gboolean
option_a11y_own_name_cb (const gchar  *option_name,
                         const gchar  *value,
                         gpointer      data,
                         GError      **error)
{
  FlatpakContext *context = data;

  if (!flatpak_verify_dbus_name (value, error))
    return FALSE;

  flatpak_context_set_a11y_bus_policy (context, value, FLATPAK_POLICY_OWN);
  return TRUE;
}

static gboolean
option_talk_name_cb (const gchar *option_name,
                     const gchar *value,
                     gpointer     data,
                     GError     **error)
{
  FlatpakContext *context = data;

  if (!flatpak_verify_dbus_name (value, error))
    return FALSE;

  flatpak_context_set_session_bus_policy (context, value, FLATPAK_POLICY_TALK);
  return TRUE;
}

static gboolean
option_no_talk_name_cb (const gchar *option_name,
                        const gchar *value,
                        gpointer     data,
                        GError     **error)
{
  FlatpakContext *context = data;

  if (!flatpak_verify_dbus_name (value, error))
    return FALSE;

  flatpak_context_set_session_bus_policy (context, value, FLATPAK_POLICY_NONE);
  return TRUE;
}

static gboolean
option_system_own_name_cb (const gchar *option_name,
                           const gchar *value,
                           gpointer     data,
                           GError     **error)
{
  FlatpakContext *context = data;

  if (!flatpak_verify_dbus_name (value, error))
    return FALSE;

  flatpak_context_set_system_bus_policy (context, value, FLATPAK_POLICY_OWN);
  return TRUE;
}

static gboolean
option_system_talk_name_cb (const gchar *option_name,
                            const gchar *value,
                            gpointer     data,
                            GError     **error)
{
  FlatpakContext *context = data;

  if (!flatpak_verify_dbus_name (value, error))
    return FALSE;

  flatpak_context_set_system_bus_policy (context, value, FLATPAK_POLICY_TALK);
  return TRUE;
}

static gboolean
option_system_no_talk_name_cb (const gchar *option_name,
                               const gchar *value,
                               gpointer     data,
                               GError     **error)
{
  FlatpakContext *context = data;

  if (!flatpak_verify_dbus_name (value, error))
    return FALSE;

  flatpak_context_set_system_bus_policy (context, value, FLATPAK_POLICY_NONE);
  return TRUE;
}

static gboolean
option_add_generic_policy_cb (const gchar *option_name,
                              const gchar *value,
                              gpointer     data,
                              GError     **error)
{
  FlatpakContext *context = data;
  const char *t;
  g_autofree char *key = NULL;
  const char *policy_value;

  t = strchr (value, '=');
  if (t == NULL)
    {
      g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE,
                   _("--add-policy arguments must be in the form SUBSYSTEM.KEY=VALUE"));
      return FALSE;
    }
  policy_value = t + 1;
  key = g_strndup (value, t - value);
  if (strchr (key, '.') == NULL)
    {
      g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE,
                   _("--add-policy arguments must be in the form SUBSYSTEM.KEY=VALUE"));
      return FALSE;
    }

  if (policy_value[0] == '!')
    {
      g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE,
                   _("--add-policy values can't start with \"!\""));
      return FALSE;
    }

  flatpak_context_apply_generic_policy (context, key, policy_value);

  return TRUE;
}

static gboolean
option_remove_generic_policy_cb (const gchar *option_name,
                                 const gchar *value,
                                 gpointer     data,
                                 GError     **error)
{
  FlatpakContext *context = data;
  const char *t;
  g_autofree char *key = NULL;
  const char *policy_value;
  g_autofree char *extended_value = NULL;

  t = strchr (value, '=');
  if (t == NULL)
    {
      g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE,
                   _("--remove-policy arguments must be in the form SUBSYSTEM.KEY=VALUE"));
      return FALSE;
    }
  policy_value = t + 1;
  key = g_strndup (value, t - value);
  if (strchr (key, '.') == NULL)
    {
      g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE,
                   _("--remove-policy arguments must be in the form SUBSYSTEM.KEY=VALUE"));
      return FALSE;
    }

  if (policy_value[0] == '!')
    {
      g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE,
                   _("--remove-policy values can't start with \"!\""));
      return FALSE;
    }

  extended_value = g_strconcat ("!", policy_value, NULL);

  flatpak_context_apply_generic_policy (context, key, extended_value);

  return TRUE;
}

static gboolean
option_usb_cb (const char  *option_name,
               const char  *value,
               gpointer     data,
               GError     **error)
{
  g_autoptr(FlatpakUsbQuery) usb_query = NULL;
  FlatpakContext *context = data;

  if (!flatpak_usb_parse_usb (value, &usb_query, error))
    return FALSE;

  flatpak_context_add_usb_query (context, usb_query);
  return TRUE;
}

static gboolean
option_nousb_cb (const char  *option_name,
		 const char  *value,
		 gpointer     data,
		 GError     **error)
{
  g_autoptr(FlatpakUsbQuery) usb_query = NULL;
  FlatpakContext *context = data;

  if (!flatpak_usb_parse_usb (value, &usb_query, error))
    return FALSE;

  flatpak_context_add_nousb_query (context, usb_query);
  return TRUE;
}

static gboolean
option_usb_list_file_cb (const char  *option_name,
                         const char  *value,
                         gpointer     data,
                         GError     **error)
{
  return flatpak_context_add_usb_list_from_file (data, value, error);
}

static gboolean
option_usb_list_cb (const char  *option_name,
                    const char  *value,
                    gpointer     data,
                    GError     **error)
{
  return flatpak_context_add_usb_list (data, value, error);
}

static gboolean
option_persist_cb (const char *option_name,
                   const char *value,
                   gpointer     data,
                   GError     **error)
{
  FlatpakContext *context = data;

  return flatpak_context_set_persistent (context, value, error);
}

static gboolean option_no_desktop_deprecated;

static GOptionEntry context_options[] = {
  { "share", 0, G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_CALLBACK, &option_share_cb, N_("Share with host"), N_("SHARE") },
  { "unshare", 0, G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_CALLBACK, &option_unshare_cb, N_("Unshare with host"), N_("SHARE") },
  { "share-if", 0, G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_CALLBACK, &option_share_if_cb, N_("Require conditions to be met for a subsystem to get shared"), N_("SHARE:CONDITION") },
  { "socket", 0, G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_CALLBACK, &option_socket_cb, N_("Expose socket to app"), N_("SOCKET") },
  { "nosocket", 0, G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_CALLBACK, &option_nosocket_cb, N_("Don't expose socket to app"), N_("SOCKET") },
  { "socket-if", 0, G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_CALLBACK, &option_socket_if_cb, N_("Require conditions to be met for a socket to get exposed"), N_("SOCKET:CONDITION") },
  { "device", 0, G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_CALLBACK, &option_device_cb, N_("Expose device to app"), N_("DEVICE") },
  { "nodevice", 0, G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_CALLBACK, &option_nodevice_cb, N_("Don't expose device to app"), N_("DEVICE") },
  { "device-if", 0, G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_CALLBACK, &option_device_if_cb, N_("Require conditions to be met for a device to get exposed"), N_("DEVICE:CONDITION") },
  { "allow", 0, G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_CALLBACK, &option_allow_cb, N_("Allow feature"), N_("FEATURE") },
  { "disallow", 0, G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_CALLBACK, &option_disallow_cb, N_("Don't allow feature"), N_("FEATURE") },
  { "allow-if", 0, G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_CALLBACK, &option_allow_if_cb, N_("Require conditions to be met for a feature to get allowed"), N_("FEATURE:CONDITION") },
  { "filesystem", 0, G_OPTION_FLAG_IN_MAIN | G_OPTION_FLAG_FILENAME, G_OPTION_ARG_CALLBACK, &option_filesystem_cb, N_("Expose filesystem to app (:ro for read-only)"), N_("FILESYSTEM[:ro]") },
  { "nofilesystem", 0, G_OPTION_FLAG_IN_MAIN | G_OPTION_FLAG_FILENAME, G_OPTION_ARG_CALLBACK, &option_nofilesystem_cb, N_("Don't expose filesystem to app"), N_("FILESYSTEM") },
  { "env", 0, G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_CALLBACK, &option_env_cb, N_("Set environment variable"), N_("VAR=VALUE") },
  { "env-fd", 0, G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_CALLBACK, &option_env_fd_cb, N_("Read environment variables in env -0 format from FD"), N_("FD") },
  { "unset-env", 0, G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_CALLBACK, &option_unset_env_cb, N_("Remove variable from environment"), N_("VAR") },
  { "own-name", 0, G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_CALLBACK, &option_own_name_cb, N_("Allow app to own name on the session bus"), N_("DBUS_NAME") },
  { "talk-name", 0, G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_CALLBACK, &option_talk_name_cb, N_("Allow app to talk to name on the session bus"), N_("DBUS_NAME") },
  { "no-talk-name", 0, G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_CALLBACK, &option_no_talk_name_cb, N_("Don't allow app to talk to name on the session bus"), N_("DBUS_NAME") },
  { "system-own-name", 0, G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_CALLBACK, &option_system_own_name_cb, N_("Allow app to own name on the system bus"), N_("DBUS_NAME") },
  { "system-talk-name", 0, G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_CALLBACK, &option_system_talk_name_cb, N_("Allow app to talk to name on the system bus"), N_("DBUS_NAME") },
  { "system-no-talk-name", 0, G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_CALLBACK, &option_system_no_talk_name_cb, N_("Don't allow app to talk to name on the system bus"), N_("DBUS_NAME") },
  { "a11y-own-name", 0, G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_CALLBACK, &option_a11y_own_name_cb, N_("Allow app to own name on the a11y bus"), N_("DBUS_NAME") },
  { "add-policy", 0, G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_CALLBACK, &option_add_generic_policy_cb, N_("Add generic policy option"), N_("SUBSYSTEM.KEY=VALUE") },
  { "remove-policy", 0, G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_CALLBACK, &option_remove_generic_policy_cb, N_("Remove generic policy option"), N_("SUBSYSTEM.KEY=VALUE") },
  { "usb", 0, G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_CALLBACK, &option_usb_cb, N_("Add USB device to enumerables"), N_("VENDOR_ID:PRODUCT_ID") },
  { "nousb", 0, G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_CALLBACK, &option_nousb_cb, N_("Add USB device to hidden list"), N_("VENDOR_ID:PRODUCT_ID") },
  { "usb-list", 0, G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_CALLBACK, &option_usb_list_cb, N_("A list of USB devices that are enumerable"), N_("LIST") },
  { "usb-list-file", 0, G_OPTION_FLAG_IN_MAIN | G_OPTION_FLAG_FILENAME, G_OPTION_ARG_CALLBACK, &option_usb_list_file_cb, N_("File containing a list of USB devices to make enumerable"), N_("FILENAME") },
  { "persist", 0, G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_CALLBACK, &option_persist_cb, N_("Persist home directory subpath"), N_("FILENAME") },
  /* This is not needed/used anymore, so hidden, but we accept it for backwards compat */
  { "no-desktop", 0, G_OPTION_FLAG_IN_MAIN |  G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_NONE, &option_no_desktop_deprecated, N_("Don't require a running session (no cgroups creation)"), NULL },
  { NULL }
};

GOptionEntry *
flatpak_context_get_option_entries (void)
{
  return context_options;
}

GOptionGroup  *
flatpak_context_get_options (FlatpakContext *context)
{
  GOptionGroup *group;

  group = g_option_group_new ("environment",
                              "Runtime Environment",
                              "Runtime Environment",
                              context,
                              NULL);
  g_option_group_set_translation_domain (group, GETTEXT_PACKAGE);

  g_option_group_add_entries (group, context_options);

  return group;
}

static const char *
parse_negated (const char *option, gboolean *negated)
{
  if (option[0] == '!')
    {
      option++;
      *negated = TRUE;
    }
  else
    {
      *negated = FALSE;
    }
  return option;
}

/*
 * Merge the FLATPAK_METADATA_GROUP_CONTEXT,
 * FLATPAK_METADATA_GROUP_SESSION_BUS_POLICY,
 * FLATPAK_METADATA_GROUP_SYSTEM_BUS_POLICY and
 * FLATPAK_METADATA_GROUP_ENVIRONMENT groups, and all groups starting
 * with FLATPAK_METADATA_GROUP_PREFIX_POLICY, from metakey into context.
 *
 * This is a merge, not a replace!
 */
gboolean
flatpak_context_load_metadata (FlatpakContext *context,
                               GKeyFile       *metakey,
                               GError        **error)
{
  gboolean remove;
  g_auto(GStrv) groups = NULL;
  gsize i;

  if (g_key_file_has_key (metakey, FLATPAK_METADATA_GROUP_CONTEXT, FLATPAK_METADATA_KEY_SHARED, NULL))
    {
      g_auto(GStrv) shares = g_key_file_get_string_list (metakey, FLATPAK_METADATA_GROUP_CONTEXT,
                                                         FLATPAK_METADATA_KEY_SHARED, NULL, error);
      if (shares == NULL)
        return FALSE;

      if (!flatpak_permissions_from_strv (context->shares_permissions, (const char **)shares, error))
        return FALSE;
    }

  if (g_key_file_has_key (metakey, FLATPAK_METADATA_GROUP_CONTEXT, FLATPAK_METADATA_KEY_SOCKETS, NULL))
    {
      g_auto(GStrv) sockets = g_key_file_get_string_list (metakey, FLATPAK_METADATA_GROUP_CONTEXT,
                                                          FLATPAK_METADATA_KEY_SOCKETS, NULL, error);
      if (sockets == NULL)
        return FALSE;

      if (!flatpak_permissions_from_strv (context->socket_permissions, (const char **)sockets, error))
        return FALSE;
    }

  if (g_key_file_has_key (metakey, FLATPAK_METADATA_GROUP_CONTEXT, FLATPAK_METADATA_KEY_DEVICES, NULL))
    {
      g_auto(GStrv) devices = g_key_file_get_string_list (metakey, FLATPAK_METADATA_GROUP_CONTEXT,
                                                          FLATPAK_METADATA_KEY_DEVICES, NULL, error);
      if (devices == NULL)
        return FALSE;

      if (!flatpak_permissions_from_strv (context->device_permissions, (const char **)devices, error))
        return FALSE;
    }

  if (g_key_file_has_key (metakey, FLATPAK_METADATA_GROUP_CONTEXT, FLATPAK_METADATA_KEY_FEATURES, NULL))
    {
      g_auto(GStrv) features = g_key_file_get_string_list (metakey, FLATPAK_METADATA_GROUP_CONTEXT,
                                                           FLATPAK_METADATA_KEY_FEATURES, NULL, error);
      if (features == NULL)
        return FALSE;

      if (!flatpak_permissions_from_strv (context->features_permissions, (const char **)features, error))
        return FALSE;
    }

  if (g_key_file_has_key (metakey, FLATPAK_METADATA_GROUP_CONTEXT, FLATPAK_METADATA_KEY_FILESYSTEMS, NULL))
    {
      g_auto(GStrv) filesystems = g_key_file_get_string_list (metakey, FLATPAK_METADATA_GROUP_CONTEXT,
                                                              FLATPAK_METADATA_KEY_FILESYSTEMS, NULL, error);
      if (filesystems == NULL)
        return FALSE;

      for (i = 0; filesystems[i] != NULL; i++)
        {
          const char *fs = parse_negated (filesystems[i], &remove);
          g_autofree char *filesystem = NULL;
          g_autoptr(GError) local_error = NULL;
          FlatpakFilesystemMode mode;

          if (!flatpak_context_parse_filesystem (fs, remove,
                                                 &filesystem, &mode, &local_error))
            {
              if (g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA))
                {
                  /* Invalid characters, so just hard-fail. */
                  g_propagate_error (error, g_steal_pointer (&local_error));
                  return FALSE;
                }
              else
                {
                  g_info ("Unknown filesystem type %s", filesystems[i]);
                  g_clear_error (&local_error);
                }
            }
          else
            {
              g_assert (mode == FLATPAK_FILESYSTEM_MODE_NONE || !remove);
              flatpak_context_take_filesystem (context, g_steal_pointer (&filesystem), mode);
            }
        }
    }

  if (g_key_file_has_key (metakey, FLATPAK_METADATA_GROUP_CONTEXT, FLATPAK_METADATA_KEY_PERSISTENT, NULL))
    {
      g_auto(GStrv) persistent = g_key_file_get_string_list (metakey, FLATPAK_METADATA_GROUP_CONTEXT,
                                                             FLATPAK_METADATA_KEY_PERSISTENT, NULL, error);
      if (persistent == NULL)
        return FALSE;

      for (i = 0; persistent[i] != NULL; i++)
        if (!flatpak_context_set_persistent (context, persistent[i], error))
          return FALSE;
    }

  if (g_key_file_has_group (metakey, FLATPAK_METADATA_GROUP_SESSION_BUS_POLICY))
    {
      g_auto(GStrv) keys = NULL;
      gsize keys_count;

      keys = g_key_file_get_keys (metakey, FLATPAK_METADATA_GROUP_SESSION_BUS_POLICY, &keys_count, NULL);
      for (i = 0; i < keys_count; i++)
        {
          const char *key = keys[i];
          g_autofree char *value = g_key_file_get_string (metakey, FLATPAK_METADATA_GROUP_SESSION_BUS_POLICY, key, NULL);
          FlatpakPolicy policy;

          if (!flatpak_verify_dbus_name (key, error))
            return FALSE;

          policy = flatpak_policy_from_string (value, NULL);
          if ((int) policy != -1)
            flatpak_context_set_session_bus_policy (context, key, policy);
        }
    }

  if (g_key_file_has_group (metakey, FLATPAK_METADATA_GROUP_SYSTEM_BUS_POLICY))
    {
      g_auto(GStrv) keys = NULL;
      gsize keys_count;

      keys = g_key_file_get_keys (metakey, FLATPAK_METADATA_GROUP_SYSTEM_BUS_POLICY, &keys_count, NULL);
      for (i = 0; i < keys_count; i++)
        {
          const char *key = keys[i];
          g_autofree char *value = g_key_file_get_string (metakey, FLATPAK_METADATA_GROUP_SYSTEM_BUS_POLICY, key, NULL);
          FlatpakPolicy policy;

          if (!flatpak_verify_dbus_name (key, error))
            return FALSE;

          policy = flatpak_policy_from_string (value, NULL);
          if ((int) policy != -1)
            flatpak_context_set_system_bus_policy (context, key, policy);
        }
    }

  if (g_key_file_has_group (metakey, FLATPAK_METADATA_GROUP_ENVIRONMENT))
    {
      g_auto(GStrv) keys = NULL;
      gsize keys_count;

      keys = g_key_file_get_keys (metakey, FLATPAK_METADATA_GROUP_ENVIRONMENT, &keys_count, NULL);
      for (i = 0; i < keys_count; i++)
        {
          const char *key = keys[i];
          g_autofree char *value = g_key_file_get_string (metakey, FLATPAK_METADATA_GROUP_ENVIRONMENT, key, NULL);

          flatpak_context_set_env_var (context, key, value);
        }
    }

  /* unset-environment is higher precedence than Environment, so that
   * we can put unset keys in both places. Old versions of Flatpak will
   * interpret the empty string as unset; new versions will obey
   * unset-environment. */
  if (g_key_file_has_key (metakey, FLATPAK_METADATA_GROUP_CONTEXT, FLATPAK_METADATA_KEY_UNSET_ENVIRONMENT, NULL))
    {
      g_auto(GStrv) vars = NULL;
      gsize vars_count;

      vars = g_key_file_get_string_list (metakey, FLATPAK_METADATA_GROUP_CONTEXT,
                                         FLATPAK_METADATA_KEY_UNSET_ENVIRONMENT,
                                         &vars_count, error);

      if (vars == NULL)
        return FALSE;

      for (i = 0; i < vars_count; i++)
        {
          const char *var = vars[i];

          flatpak_context_set_env_var (context, var, NULL);
        }
    }

  groups = g_key_file_get_groups (metakey, NULL);
  for (i = 0; groups[i] != NULL; i++)
    {
      const char *group = groups[i];
      const char *subsystem;
      int j;

      if (g_str_has_prefix (group, FLATPAK_METADATA_GROUP_PREFIX_POLICY))
        {
          g_auto(GStrv) keys = NULL;
          subsystem = group + strlen (FLATPAK_METADATA_GROUP_PREFIX_POLICY);
          keys = g_key_file_get_keys (metakey, group, NULL, NULL);
          for (j = 0; keys != NULL && keys[j] != NULL; j++)
            {
              const char *key = keys[j];
              g_autofree char *policy_key = g_strdup_printf ("%s.%s", subsystem, key);
              g_auto(GStrv) values = NULL;
              int k;

              values = g_key_file_get_string_list (metakey, group, key, NULL, NULL);
              for (k = 0; values != NULL && values[k] != NULL; k++)
                flatpak_context_apply_generic_policy (context, policy_key,
                                                      values[k]);
            }
        }
    }

  if (g_key_file_has_key (metakey, FLATPAK_METADATA_GROUP_USB_DEVICES, FLATPAK_METADATA_KEY_USB_ENUMERABLE_DEVICES, NULL))
    {
      g_auto(GStrv) values = NULL;
      size_t count;

      values = g_key_file_get_string_list (metakey, FLATPAK_METADATA_GROUP_USB_DEVICES,
                                           FLATPAK_METADATA_KEY_USB_ENUMERABLE_DEVICES,
                                           &count, error);

      if (!values)
        return FALSE;

      for (i = 0; i < count; i++)
        {
          g_autoptr(FlatpakUsbQuery) usb_query = NULL;

          if (!flatpak_usb_parse_usb (values[i], &usb_query, error))
            return FALSE;

          flatpak_context_add_usb_query (context, usb_query);
        }
    }

  if (g_key_file_has_key (metakey, FLATPAK_METADATA_GROUP_USB_DEVICES, FLATPAK_METADATA_KEY_USB_HIDDEN_DEVICES, NULL))
    {
      g_auto(GStrv) values = NULL;
      size_t count;

      values = g_key_file_get_string_list (metakey, FLATPAK_METADATA_GROUP_USB_DEVICES,
                                           FLATPAK_METADATA_KEY_USB_HIDDEN_DEVICES,
                                           &count, error);

      if (!values)
        return FALSE;

      for (i = 0; i < count; i++)
        {
          g_autoptr(FlatpakUsbQuery) usb_query = NULL;

          if (!flatpak_usb_parse_usb (values[i], &usb_query, error))
            return FALSE;

          flatpak_context_add_nousb_query (context, usb_query);
        }
    }

  return TRUE;
}

static void
flatpak_context_save_usb_devices (GHashTable *devices, GKeyFile *keyfile, const char *key)
{
  GHashTableIter iter;
  gpointer value;

  if (g_hash_table_size (devices) > 0)
    {
      g_autoptr(GPtrArray) usb_devices = g_ptr_array_new ();

      g_hash_table_iter_init (&iter, devices);
      while (g_hash_table_iter_next (&iter, &value, NULL))
        g_ptr_array_add (usb_devices, (char *) value);

      if (usb_devices->len > 0)
        {
          g_key_file_set_string_list (keyfile,
                                      FLATPAK_METADATA_GROUP_USB_DEVICES,
                                      key,
                                      (const char * const *) usb_devices->pdata,
                                      usb_devices->len);
        }
    }
}

/*
 * Save the FLATPAK_METADATA_GROUP_CONTEXT,
 * FLATPAK_METADATA_GROUP_SESSION_BUS_POLICY,
 * FLATPAK_METADATA_GROUP_SYSTEM_BUS_POLICY and
 * FLATPAK_METADATA_GROUP_ENVIRONMENT groups, and all groups starting
 * with FLATPAK_METADATA_GROUP_PREFIX_POLICY, into metakey
 */
void
flatpak_context_save_metadata (FlatpakContext *context,
                               gboolean        flatten,
                               GKeyFile       *metakey)
{
  g_auto(GStrv) shared = NULL;
  g_auto(GStrv) sockets = NULL;
  g_auto(GStrv) devices = NULL;
  g_auto(GStrv) features = NULL;
  g_autoptr(GPtrArray) unset_env = NULL;
  GHashTableIter iter;
  gpointer key, value;
  g_auto(GStrv) groups = NULL;
  int i;

  shared = flatpak_permissions_to_strv (context->shares_permissions, flatten);
  sockets = flatpak_permissions_to_strv (context->socket_permissions, flatten);
  devices = flatpak_permissions_to_strv (context->device_permissions, flatten);
  features = flatpak_permissions_to_strv (context->features_permissions, flatten);

  if (shared[0] != NULL)
    {
      g_key_file_set_string_list (metakey,
                                  FLATPAK_METADATA_GROUP_CONTEXT,
                                  FLATPAK_METADATA_KEY_SHARED,
                                  (const char * const *) shared, g_strv_length (shared));
    }
  else
    {
      g_key_file_remove_key (metakey,
                             FLATPAK_METADATA_GROUP_CONTEXT,
                             FLATPAK_METADATA_KEY_SHARED,
                             NULL);
    }

  if (sockets[0] != NULL)
    {
      g_key_file_set_string_list (metakey,
                                  FLATPAK_METADATA_GROUP_CONTEXT,
                                  FLATPAK_METADATA_KEY_SOCKETS,
                                  (const char * const *) sockets, g_strv_length (sockets));
    }
  else
    {
      g_key_file_remove_key (metakey,
                             FLATPAK_METADATA_GROUP_CONTEXT,
                             FLATPAK_METADATA_KEY_SOCKETS,
                             NULL);
    }

  if (devices[0] != NULL)
    {
      g_key_file_set_string_list (metakey,
                                  FLATPAK_METADATA_GROUP_CONTEXT,
                                  FLATPAK_METADATA_KEY_DEVICES,
                                  (const char * const *) devices, g_strv_length (devices));
    }
  else
    {
      g_key_file_remove_key (metakey,
                             FLATPAK_METADATA_GROUP_CONTEXT,
                             FLATPAK_METADATA_KEY_DEVICES,
                             NULL);
    }

  if (features[0] != NULL)
    {
      g_key_file_set_string_list (metakey,
                                  FLATPAK_METADATA_GROUP_CONTEXT,
                                  FLATPAK_METADATA_KEY_FEATURES,
                                  (const char * const *) features, g_strv_length (features));
    }
  else
    {
      g_key_file_remove_key (metakey,
                             FLATPAK_METADATA_GROUP_CONTEXT,
                             FLATPAK_METADATA_KEY_FEATURES,
                             NULL);
    }

  if (g_hash_table_size (context->filesystems) > 0)
    {
      g_autoptr(GPtrArray) array = g_ptr_array_new_with_free_func (g_free);

      /* Serialize host-reset first, because order can matter in
       * corner cases. */
      if (g_hash_table_lookup_extended (context->filesystems, "host-reset",
                                        NULL, &value))
        {
          g_warn_if_fail (GPOINTER_TO_INT (value) == FLATPAK_FILESYSTEM_MODE_NONE);
          if (!flatten)
            g_ptr_array_add (array, g_strdup ("!host:reset"));
        }

      g_hash_table_iter_init (&iter, context->filesystems);
      while (g_hash_table_iter_next (&iter, &key, &value))
        {
          FlatpakFilesystemMode mode = GPOINTER_TO_INT (value);

          if (flatten && mode == FLATPAK_FILESYSTEM_MODE_NONE)
            continue;

          /* We already did this */
          if (g_str_equal (key, "host-reset"))
            continue;

          g_ptr_array_add (array, unparse_filesystem_flags (key, mode));
        }

      g_key_file_set_string_list (metakey,
                                  FLATPAK_METADATA_GROUP_CONTEXT,
                                  FLATPAK_METADATA_KEY_FILESYSTEMS,
                                  (const char * const *) array->pdata, array->len);
    }
  else
    {
      g_key_file_remove_key (metakey,
                             FLATPAK_METADATA_GROUP_CONTEXT,
                             FLATPAK_METADATA_KEY_FILESYSTEMS,
                             NULL);
    }

  if (g_hash_table_size (context->persistent) > 0)
    {
      g_autofree char **keys = (char **) g_hash_table_get_keys_as_array (context->persistent, NULL);

      g_key_file_set_string_list (metakey,
                                  FLATPAK_METADATA_GROUP_CONTEXT,
                                  FLATPAK_METADATA_KEY_PERSISTENT,
                                  (const char * const *) keys, g_strv_length (keys));
    }
  else
    {
      g_key_file_remove_key (metakey,
                             FLATPAK_METADATA_GROUP_CONTEXT,
                             FLATPAK_METADATA_KEY_PERSISTENT,
                             NULL);
    }

  g_key_file_remove_group (metakey, FLATPAK_METADATA_GROUP_SESSION_BUS_POLICY, NULL);
  g_hash_table_iter_init (&iter, context->session_bus_policy);
  while (g_hash_table_iter_next (&iter, &key, &value))
    {
      FlatpakPolicy policy = GPOINTER_TO_INT (value);

      if (flatten && (policy == 0))
        continue;

      g_key_file_set_string (metakey,
                             FLATPAK_METADATA_GROUP_SESSION_BUS_POLICY,
                             (char *) key, flatpak_policy_to_string (policy));
    }

  g_key_file_remove_group (metakey, FLATPAK_METADATA_GROUP_SYSTEM_BUS_POLICY, NULL);
  g_hash_table_iter_init (&iter, context->system_bus_policy);
  while (g_hash_table_iter_next (&iter, &key, &value))
    {
      FlatpakPolicy policy = GPOINTER_TO_INT (value);

      if (flatten && (policy == 0))
        continue;

      g_key_file_set_string (metakey,
                             FLATPAK_METADATA_GROUP_SYSTEM_BUS_POLICY,
                             (char *) key, flatpak_policy_to_string (policy));
    }

  g_key_file_remove_group (metakey, FLATPAK_METADATA_GROUP_A11Y_BUS_POLICY, NULL);
  g_hash_table_iter_init (&iter, context->a11y_bus_policy);
  while (g_hash_table_iter_next (&iter, &key, &value))
    {
      FlatpakPolicy policy = GPOINTER_TO_INT (value);

      if (flatten && (policy == 0))
        continue;

      g_key_file_set_string (metakey,
                             FLATPAK_METADATA_GROUP_A11Y_BUS_POLICY,
                             (char *) key, flatpak_policy_to_string (policy));
    }

  /* Elements are borrowed from context->env_vars */
  unset_env = g_ptr_array_new ();

  g_key_file_remove_group (metakey, FLATPAK_METADATA_GROUP_ENVIRONMENT, NULL);
  g_hash_table_iter_init (&iter, context->env_vars);
  while (g_hash_table_iter_next (&iter, &key, &value))
    {
      if (value != NULL)
        {
          g_key_file_set_string (metakey,
                                 FLATPAK_METADATA_GROUP_ENVIRONMENT,
                                 (char *) key, (char *) value);
        }
      else
        {
          /* In older versions of Flatpak, [Environment] FOO=
           * was interpreted as unsetting - so let's do both. */
          g_key_file_set_string (metakey,
                                 FLATPAK_METADATA_GROUP_ENVIRONMENT,
                                 (char *) key, "");
          g_ptr_array_add (unset_env, key);
        }
    }

  if (unset_env->len > 0)
    {
      g_ptr_array_add (unset_env, NULL);
      g_key_file_set_string_list (metakey, FLATPAK_METADATA_GROUP_CONTEXT,
                                  FLATPAK_METADATA_KEY_UNSET_ENVIRONMENT,
                                  (const char * const *) unset_env->pdata,
                                  unset_env->len - 1);
    }
  else
    {
      g_key_file_remove_key (metakey, FLATPAK_METADATA_GROUP_CONTEXT,
                             FLATPAK_METADATA_KEY_UNSET_ENVIRONMENT, NULL);
    }

  groups = g_key_file_get_groups (metakey, NULL);
  for (i = 0; groups[i] != NULL; i++)
    {
      const char *group = groups[i];
      if (g_str_has_prefix (group, FLATPAK_METADATA_GROUP_PREFIX_POLICY))
        g_key_file_remove_group (metakey, group, NULL);
    }

  g_hash_table_iter_init (&iter, context->generic_policy);
  while (g_hash_table_iter_next (&iter, &key, &value))
    {
      g_auto(GStrv) parts = g_strsplit ((const char *) key, ".", 2);
      g_autofree char *group = NULL;
      g_assert (parts[1] != NULL);
      const char **policy_values = (const char **) value;
      g_autoptr(GPtrArray) new = g_ptr_array_new ();

      for (i = 0; policy_values[i] != NULL; i++)
        {
          const char *policy_value = policy_values[i];

          if (!flatten || policy_value[0] != '!')
            g_ptr_array_add (new, (char *) policy_value);
        }

      if (new->len > 0)
        {
          group = g_strconcat (FLATPAK_METADATA_GROUP_PREFIX_POLICY,
                               parts[0], NULL);
          g_key_file_set_string_list (metakey, group, parts[1],
                                      (const char * const *) new->pdata,
                                      new->len);
        }
    }

  g_key_file_remove_group (metakey, FLATPAK_METADATA_GROUP_USB_DEVICES, NULL);
  flatpak_context_save_usb_devices (context->enumerable_usb_devices, metakey,
                                    FLATPAK_METADATA_KEY_USB_ENUMERABLE_DEVICES);
  flatpak_context_save_usb_devices (context->hidden_usb_devices, metakey,
                                    FLATPAK_METADATA_KEY_USB_HIDDEN_DEVICES);
}

gboolean
flatpak_context_get_needs_session_bus_proxy (FlatpakContext *context)
{
  return g_hash_table_size (context->session_bus_policy) > 0;
}

gboolean
flatpak_context_get_needs_system_bus_proxy (FlatpakContext *context)
{
  return g_hash_table_size (context->system_bus_policy) > 0;
}

static gboolean
adds_bus_policy (GHashTable *old, GHashTable *new)
{
  GLNX_HASH_TABLE_FOREACH_KV (new, const char *, name, gpointer, _new_policy)
    {
      int new_policy = GPOINTER_TO_INT (_new_policy);
      int old_policy = GPOINTER_TO_INT (g_hash_table_lookup (old, name));
      if (new_policy > old_policy)
        return TRUE;
    }

  return FALSE;
}

static gboolean
adds_generic_policy (GHashTable *old, GHashTable *new)
{
  GLNX_HASH_TABLE_FOREACH_KV (new, const char *, key, GPtrArray *, new_values)
    {
      GPtrArray *old_values = g_hash_table_lookup (old, key);
      int i;

      if (new_values == NULL || new_values->len == 0)
        continue;

      if (old_values == NULL || old_values->len == 0)
        return TRUE;

      for (i = 0; i < new_values->len; i++)
        {
          const char *new_value = g_ptr_array_index (new_values, i);

          if (!flatpak_g_ptr_array_contains_string (old_values, new_value))
            return TRUE;
        }
    }

  return FALSE;
}

static gboolean
adds_filesystem_access (GHashTable *old, GHashTable *new)
{
  FlatpakFilesystemMode old_host_mode = GPOINTER_TO_INT (g_hash_table_lookup (old, "host"));

  GLNX_HASH_TABLE_FOREACH_KV (new, const char *, location, gpointer, _new_mode)
    {
      FlatpakFilesystemMode new_mode = GPOINTER_TO_INT (_new_mode);
      FlatpakFilesystemMode old_mode = GPOINTER_TO_INT (g_hash_table_lookup (old, location));

      /* Allow more limited access to the same thing */
      if (new_mode <= old_mode)
        continue;

      /* Allow more limited access if we used to have access to everything */
     if (new_mode <= old_host_mode)
        continue;

     /* For the remainder we have to be pessimistic, for instance even
        if we have home access we can't allow adding access to ~/foo,
        because foo might be a symlink outside home which didn't work
        before but would work with an explicit access to that
        particular file. */

      return TRUE;
    }

  return FALSE;
}

static gboolean
adds_usb_device (FlatpakContext *old, FlatpakContext *new)
{
  GHashTableIter iter;
  gpointer value;

  /* Does it add new devices to the allowlist? */
  g_hash_table_iter_init (&iter, new->enumerable_usb_devices);
  while (g_hash_table_iter_next (&iter, &value, NULL))
    {
      if (!g_hash_table_contains (old->enumerable_usb_devices, value))
        return TRUE;
    }

  /* Does it remove devices from the blocklist? */
  g_hash_table_iter_init (&iter, old->hidden_usb_devices);
  while (g_hash_table_iter_next (&iter, &value, NULL))
    {
      if (!g_hash_table_contains (new->hidden_usb_devices, value))
        return TRUE;
    }

  return FALSE;
}

gboolean
flatpak_context_adds_permissions (FlatpakContext *old,
                                  FlatpakContext *new)
{
  g_autoptr(GHashTable) old_features_permissions = NULL;
  g_autoptr(GHashTable) old_socket_permissions = NULL;

  old_features_permissions = flatpak_permissions_dup (old->features_permissions);
  /* We allow upgrade to multiarch, that is really not a huge problem.
   * Similarly, having sensible semantics for /dev/shm is
   * not a security concern. */
  flatpak_permissions_set_allowed (old_features_permissions, "multiarch");
  flatpak_permissions_set_allowed (old_features_permissions, "per-app-dev-shm");

  old_socket_permissions = flatpak_permissions_dup (old->socket_permissions);
  /* If we used to allow X11, also allow new fallback X11,
     as that is actually less permissions */
  if (flatpak_permissions_allows_unconditionally (old_socket_permissions, "x11"))
    flatpak_permissions_set_allowed (old_socket_permissions, "fallback-x11");

  if (flatpak_permissions_adds_permissions (old->shares_permissions,
                                            new->shares_permissions))
      return TRUE;

  if (flatpak_permissions_adds_permissions (old_socket_permissions,
                                            new->socket_permissions))
      return TRUE;

  if (flatpak_permissions_adds_permissions (old->device_permissions,
                                            new->device_permissions))
    return TRUE;

  if (flatpak_permissions_adds_permissions (old_features_permissions,
                                            new->features_permissions))
      return TRUE;

  if (adds_bus_policy (old->session_bus_policy, new->session_bus_policy))
    return TRUE;

  if (adds_bus_policy (old->system_bus_policy, new->system_bus_policy))
    return TRUE;

  if (adds_bus_policy (old->a11y_bus_policy, new->a11y_bus_policy))
    return TRUE;

  if (adds_generic_policy (old->generic_policy, new->generic_policy))
    return TRUE;

  if (adds_filesystem_access (old->filesystems, new->filesystems))
    return TRUE;

  if (adds_usb_device (old, new))
    return TRUE;

  return FALSE;
}

char *
flatpak_context_devices_to_usb_list (GHashTable *devices,
                                     gboolean    hidden)
{
  GString *list = g_string_new (NULL);
  GHashTableIter iter;
  gpointer value;

  g_hash_table_iter_init (&iter, devices);
  while (g_hash_table_iter_next (&iter, &value, NULL))
    {
      if (hidden)
        g_string_append_printf (list, "!%s;", (const char *) value);
      else
        g_string_append_printf (list, "%s;", (const char *) value);
    }

  return g_string_free (list, FALSE);
}

void
flatpak_context_to_args (FlatpakContext *context,
                         GPtrArray      *args)
{
  GHashTableIter iter;
  gpointer key, value;
  char *usb_list = NULL;

  flatpak_permissions_to_args (context->features_permissions,
                               "allow", "disallow", args);
  flatpak_permissions_to_args (context->shares_permissions,
                               "share", "unshare", args);
  flatpak_permissions_to_args (context->device_permissions,
                               "device", "nodevice", args);
  flatpak_permissions_to_args (context->socket_permissions,
                               "socket", "nosocket", args);

  g_hash_table_iter_init (&iter, context->env_vars);
  while (g_hash_table_iter_next (&iter, &key, &value))
    {
      if (value != NULL)
        g_ptr_array_add (args, g_strdup_printf ("--env=%s=%s", (char *) key, (char *) value));
      else
        g_ptr_array_add (args, g_strdup_printf ("--unset-env=%s", (char *) key));
    }

  g_hash_table_iter_init (&iter, context->persistent);
  while (g_hash_table_iter_next (&iter, &key, &value))
    g_ptr_array_add (args, g_strdup_printf ("--persist=%s", (char *) key));

  g_hash_table_iter_init (&iter, context->session_bus_policy);
  while (g_hash_table_iter_next (&iter, &key, &value))
    {
      const char *name = key;
      FlatpakPolicy policy = GPOINTER_TO_INT (value);

      g_ptr_array_add (args, g_strdup_printf ("--%s-name=%s", flatpak_policy_to_string (policy), name));
    }

  g_hash_table_iter_init (&iter, context->system_bus_policy);
  while (g_hash_table_iter_next (&iter, &key, &value))
    {
      const char *name = key;
      FlatpakPolicy policy = GPOINTER_TO_INT (value);

      g_ptr_array_add (args, g_strdup_printf ("--system-%s-name=%s", flatpak_policy_to_string (policy), name));
    }

  /* Serialize host-reset first, because order can matter in
   * corner cases. */
  if (g_hash_table_lookup_extended (context->filesystems, "host-reset",
                                    NULL, &value))
    {
      g_warn_if_fail (GPOINTER_TO_INT (value) == FLATPAK_FILESYSTEM_MODE_NONE);
      g_ptr_array_add (args, g_strdup ("--nofilesystem=host:reset"));
    }

  g_hash_table_iter_init (&iter, context->filesystems);
  while (g_hash_table_iter_next (&iter, &key, &value))
    {
      g_autofree char *fs = NULL;
      FlatpakFilesystemMode mode = GPOINTER_TO_INT (value);

      /* We already did this */
      if (g_str_equal (key, "host-reset"))
        continue;

      fs = unparse_filesystem_flags (key, mode);

      if (mode != FLATPAK_FILESYSTEM_MODE_NONE)
        {
          g_ptr_array_add (args, g_strdup_printf ("--filesystem=%s", fs));
        }
      else
        {
          g_assert (fs[0] == '!');
          g_ptr_array_add (args, g_strdup_printf ("--nofilesystem=%s", &fs[1]));
        }
    }

  usb_list = flatpak_context_devices_to_usb_list (context->enumerable_usb_devices, FALSE);
  g_ptr_array_add (args, g_strdup_printf ("--usb-list=%s", usb_list));
  g_free (usb_list);

  usb_list = flatpak_context_devices_to_usb_list (context->hidden_usb_devices, TRUE);
  g_ptr_array_add (args, g_strdup_printf ("--usb-list=%s", usb_list));
  g_free (usb_list);
}

void
flatpak_context_add_bus_filters (FlatpakContext *context,
                                 const char     *app_id,
                                 FlatpakBus      bus,
                                 gboolean        sandboxed,
                                 FlatpakBwrap   *bwrap)
{
  GHashTable *ht;
  GHashTableIter iter;
  gpointer key, value;

  flatpak_bwrap_add_arg (bwrap, "--filter");

  switch (bus)
    {
    case FLATPAK_SESSION_BUS:
      if (app_id)
        {
          if (!sandboxed)
            {
              flatpak_bwrap_add_arg_printf (bwrap, "--own=%s.*", app_id);
              flatpak_bwrap_add_arg_printf (bwrap, "--own=org.mpris.MediaPlayer2.%s.*", app_id);
            }
          else
            {
              flatpak_bwrap_add_arg_printf (bwrap, "--own=%s.Sandboxed.*", app_id);
              flatpak_bwrap_add_arg_printf (bwrap, "--own=org.mpris.MediaPlayer2.%s.Sandboxed.*", app_id);
            }
        }
      ht = context->session_bus_policy;
      break;

    case FLATPAK_SYSTEM_BUS:
      ht = context->system_bus_policy;
      break;

    case FLATPAK_A11Y_BUS:
      ht = context->a11y_bus_policy;
      break;

    default:
      g_assert_not_reached ();
   }

  g_hash_table_iter_init (&iter, ht);
  while (g_hash_table_iter_next (&iter, &key, &value))
    {
      FlatpakPolicy policy = GPOINTER_TO_INT (value);

      if (policy > 0)
        flatpak_bwrap_add_arg_printf (bwrap, "--%s=%s",
                                      flatpak_policy_to_string (policy),
                                      (char *) key);
    }
}

void
flatpak_context_reset_non_permissions (FlatpakContext *context)
{
  g_hash_table_remove_all (context->env_vars);
}

void
flatpak_context_reset_permissions (FlatpakContext *context)
{
  g_hash_table_remove_all (context->shares_permissions);
  g_hash_table_remove_all (context->socket_permissions);
  g_hash_table_remove_all (context->device_permissions);
  g_hash_table_remove_all (context->features_permissions);
  g_hash_table_remove_all (context->persistent);
  g_hash_table_remove_all (context->filesystems);
  g_hash_table_remove_all (context->session_bus_policy);
  g_hash_table_remove_all (context->system_bus_policy);
  g_hash_table_remove_all (context->a11y_bus_policy);
  g_hash_table_remove_all (context->generic_policy);
}

void
flatpak_context_make_sandboxed (FlatpakContext *context)
{
  /* We drop almost everything from the app permission, except
   * multiarch which is inherited, to make sure app code keeps
   * running. */
  g_autoptr(FlatpakPermission) multiarch =
    flatpak_permission_dup (g_hash_table_lookup (context->features_permissions,
                                                 "multiarch"));

  g_hash_table_remove_all (context->shares_permissions);
  g_hash_table_remove_all (context->socket_permissions);
  g_hash_table_remove_all (context->device_permissions);
  g_hash_table_remove_all (context->features_permissions);

  if (multiarch)
    {
      g_hash_table_insert (context->features_permissions,
                           g_strdup ("multiarch"),
                           g_steal_pointer (&multiarch));
    }

  g_hash_table_remove_all (context->persistent);
  g_hash_table_remove_all (context->filesystems);
  g_hash_table_remove_all (context->session_bus_policy);
  g_hash_table_remove_all (context->system_bus_policy);
  g_hash_table_remove_all (context->a11y_bus_policy);
  g_hash_table_remove_all (context->generic_policy);
}

const char *dont_mount_in_root[] = {
  ".",
  "..",
  "app",
  "bin",
  "boot",
  "dev",
  "efi",
  "etc",
  "lib",
  "lib32",
  "lib64",
  "proc",
  "root",
  "run",
  "sbin",
  "sys",
  "tmp",
  "usr",
  "var",
  NULL
};

static void
log_cannot_export_error (FlatpakFilesystemMode  mode,
                         const char            *path,
                         const GError          *error)
{
  GLogLevelFlags level = G_LOG_LEVEL_MESSAGE;

  /* By default we don't show a log message if the reason we are not sharing
   * something with the sandbox is simply "it doesn't exist" (or something
   * very close): otherwise it would be very noisy to launch apps that
   * opportunistically share things they might benefit from, like Steam
   * having access to $XDG_RUNTIME_DIR/app/com.discordapp.Discord if it
   * happens to exist. */
  if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
    level = G_LOG_LEVEL_INFO;
  /* Some callers specifically suppress warnings for particular errors
   * by setting this code. */
  else if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_FAILED_HANDLED))
    level = G_LOG_LEVEL_INFO;

  switch (mode)
    {
      case FLATPAK_FILESYSTEM_MODE_NONE:
        g_log (G_LOG_DOMAIN, level, _("Not replacing \"%s\" with tmpfs: %s"),
               path, error->message);
        break;

      case FLATPAK_FILESYSTEM_MODE_CREATE:
      case FLATPAK_FILESYSTEM_MODE_READ_ONLY:
      case FLATPAK_FILESYSTEM_MODE_READ_WRITE:
        g_log (G_LOG_DOMAIN, level,
               _("Not sharing \"%s\" with sandbox: %s"),
               path, error->message);
        break;
    }
}

static void
flatpak_context_export (FlatpakContext *context,
                        FlatpakExports *exports,
                        GFile          *app_id_dir,
                        GPtrArray       *extra_app_id_dirs,
                        gboolean        do_create,
                        gchar         **xdg_dirs_conf_out,
                        gboolean       *home_access_out)
{
  gboolean home_access = FALSE;
  g_autoptr(GString) xdg_dirs_conf = NULL;
  FlatpakFilesystemMode fs_mode, os_mode, etc_mode, root_mode, home_mode;
  GHashTableIter iter;
  gpointer key, value;
  g_autoptr(GError) local_error = NULL;

  if (xdg_dirs_conf_out != NULL)
    xdg_dirs_conf = g_string_new ("");

  fs_mode = GPOINTER_TO_INT (g_hash_table_lookup (context->filesystems, "host"));
  if (fs_mode != FLATPAK_FILESYSTEM_MODE_NONE)
    {
      DIR *dir;
      struct dirent *dirent;

      g_info ("Allowing host-fs access");
      home_access = TRUE;

      /* Bind mount most dirs in / into the new root */
      dir = opendir ("/");
      if (dir != NULL)
        {
          while ((dirent = readdir (dir)))
            {
              g_autofree char *path = NULL;

              if (g_strv_contains (dont_mount_in_root, dirent->d_name))
                continue;

              path = g_build_filename ("/", dirent->d_name, NULL);

              if (!flatpak_exports_add_path_expose (exports, fs_mode, path, &local_error))
                {
                  /* Failure to share something like /lib32 because it's
                   * actually a symlink to /usr/lib32 is less of a problem
                   * here than it would be for an explicit
                   * --filesystem=/lib32, so the warning that would normally
                   * be produced in that situation is downgraded to a
                   * debug message. */
                  if (g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_NOT_MOUNTABLE_FILE))
                    local_error->code = G_IO_ERROR_FAILED_HANDLED;

                  log_cannot_export_error (fs_mode, path, local_error);
                  g_clear_error (&local_error);
                }
            }
          closedir (dir);
        }

      if (!flatpak_exports_add_path_expose (exports, fs_mode, "/run/media", &local_error))
        {
          log_cannot_export_error (fs_mode, "/run/media", local_error);
          g_clear_error (&local_error);
        }
    }

  os_mode = MAX (GPOINTER_TO_INT (g_hash_table_lookup (context->filesystems, "host-os")),
                 fs_mode);

  if (os_mode != FLATPAK_FILESYSTEM_MODE_NONE)
    flatpak_exports_add_host_os_expose (exports, os_mode);

  etc_mode = MAX (GPOINTER_TO_INT (g_hash_table_lookup (context->filesystems, "host-etc")),
                  fs_mode);

  if (etc_mode != FLATPAK_FILESYSTEM_MODE_NONE)
    flatpak_exports_add_host_etc_expose (exports, etc_mode);

  root_mode = MAX (GPOINTER_TO_INT (g_hash_table_lookup (context->filesystems, "host-root")),
                   fs_mode);

  if (root_mode != FLATPAK_FILESYSTEM_MODE_NONE)
    flatpak_exports_add_host_root_expose (exports, root_mode);

  home_mode = GPOINTER_TO_INT (g_hash_table_lookup (context->filesystems, "home"));
  if (home_mode != FLATPAK_FILESYSTEM_MODE_NONE)
    {
      g_info ("Allowing homedir access");
      home_access = TRUE;

      if (!flatpak_exports_add_path_expose (exports, MAX (home_mode, fs_mode), g_get_home_dir (), &local_error))
        {
          /* Even if the error is one that we would normally silence, like
           * the path not existing, it seems reasonable to make more of a fuss
           * about the home directory not existing or otherwise being unusable,
           * so this is intentionally not using cannot_export() */
          g_warning (_("Not allowing home directory access: %s"),
                     local_error->message);
          g_clear_error (&local_error);
        }
    }

  g_hash_table_iter_init (&iter, context->filesystems);
  while (g_hash_table_iter_next (&iter, &key, &value))
    {
      const char *filesystem = key;
      FlatpakFilesystemMode mode = GPOINTER_TO_INT (value);

      if (g_strv_contains (flatpak_context_special_filesystems, filesystem))
        continue;

      if (g_str_has_prefix (filesystem, "xdg-"))
        {
          g_autofree char *path = NULL;
          const char *rest = NULL;
          const char *config_key = NULL;
          g_autofree char *subpath = NULL;
          g_autofree char *canonical_path = NULL;
          g_autofree char *canonical_home = NULL;

          if (!get_xdg_user_dir_from_string (filesystem, &config_key, &rest, &path))
            {
              g_warning ("Unsupported xdg dir %s", filesystem);
              continue;
            }

          if (path == NULL)
            continue; /* Unconfigured, ignore */

          canonical_path = flatpak_canonicalize_filename (path);
          canonical_home = flatpak_canonicalize_filename (g_get_home_dir ());

          if (strcmp (canonical_path, canonical_home) == 0)
            {
              /* xdg-user-dirs sets disabled dirs to $HOME, and its in general not a good
                 idea to set full access to $HOME other than explicitly, so we ignore
                 these */
              g_info ("Xdg dir %s is $HOME (i.e. disabled), ignoring", filesystem);
              continue;
            }

          subpath = g_build_filename (path, rest, NULL);

          if (mode == FLATPAK_FILESYSTEM_MODE_CREATE && do_create)
            {
              if (g_mkdir_with_parents (subpath, 0755) != 0)
                g_info ("Unable to create directory %s", subpath);
            }

          if (g_file_test (subpath, G_FILE_TEST_EXISTS))
            {
              if (config_key && xdg_dirs_conf)
                g_string_append_printf (xdg_dirs_conf, "%s=\"%s\"\n",
                                        config_key, path);

              if (!flatpak_exports_add_path_expose_or_hide (exports, mode, subpath, &local_error))
                {
                  log_cannot_export_error (mode, subpath, local_error);
                  g_clear_error (&local_error);
                }
            }
        }
      else if (g_str_has_prefix (filesystem, "~/"))
        {
          g_autofree char *path = NULL;

          path = g_build_filename (g_get_home_dir (), filesystem + 2, NULL);

          if (mode == FLATPAK_FILESYSTEM_MODE_CREATE && do_create)
            {
              if (g_mkdir_with_parents (path, 0755) != 0)
                g_info ("Unable to create directory %s", path);
            }

          if (!flatpak_exports_add_path_expose_or_hide (exports, mode, path, &local_error))
            {
              log_cannot_export_error (mode, path, local_error);
              g_clear_error (&local_error);
            }
        }
      else if (g_str_has_prefix (filesystem, "/"))
        {
          if (mode == FLATPAK_FILESYSTEM_MODE_CREATE && do_create)
            {
              if (g_mkdir_with_parents (filesystem, 0755) != 0)
                g_info ("Unable to create directory %s", filesystem);
            }

          if (!flatpak_exports_add_path_expose_or_hide (exports, mode, filesystem, &local_error))
            {
              log_cannot_export_error (mode, filesystem, local_error);
              g_clear_error (&local_error);
            }
        }
      else
        {
          g_warning ("Unexpected filesystem arg %s", filesystem);
        }
    }

  if (app_id_dir)
    {
      g_autoptr(GFile) apps_dir = g_file_get_parent (app_id_dir);
      int i;
      /* Hide the .var/app dir by default (unless explicitly made visible) */
      if (!flatpak_exports_add_path_tmpfs (exports,
                                           flatpak_file_get_path_cached (apps_dir),
                                           &local_error))
        {
          log_cannot_export_error (FLATPAK_FILESYSTEM_MODE_NONE,
                                   flatpak_file_get_path_cached (apps_dir),
                                   local_error);
          g_clear_error (&local_error);
        }

      /* But let the app write to the per-app dir in it */
      if (!flatpak_exports_add_path_expose (exports, FLATPAK_FILESYSTEM_MODE_READ_WRITE,
                                            flatpak_file_get_path_cached (app_id_dir),
                                            &local_error))
        {
          log_cannot_export_error (FLATPAK_FILESYSTEM_MODE_READ_WRITE,
                                   flatpak_file_get_path_cached (apps_dir),
                                   local_error);
          g_clear_error (&local_error);
        }

      if (extra_app_id_dirs != NULL)
        {
          for (i = 0; i < extra_app_id_dirs->len; i++)
            {
              GFile *extra_app_id_dir = g_ptr_array_index (extra_app_id_dirs, i);
              if (!flatpak_exports_add_path_expose (exports,
                                                    FLATPAK_FILESYSTEM_MODE_READ_WRITE,
                                                    flatpak_file_get_path_cached (extra_app_id_dir),
                                                    &local_error))
                {
                  log_cannot_export_error (FLATPAK_FILESYSTEM_MODE_READ_WRITE,
                                           flatpak_file_get_path_cached (extra_app_id_dir),
                                           local_error);
                  g_clear_error (&local_error);
                }
            }
        }
    }

  if (home_access_out != NULL)
    *home_access_out = home_access;

  if (xdg_dirs_conf_out != NULL)
    {
      g_assert (xdg_dirs_conf != NULL);
      *xdg_dirs_conf_out = g_string_free (g_steal_pointer (&xdg_dirs_conf), FALSE);
    }
}

GFile *
flatpak_get_data_dir (const char *app_id)
{
  g_autoptr(GFile) home = g_file_new_for_path (g_get_home_dir ());
  g_autoptr(GFile) var_app = g_file_resolve_relative_path (home, ".var/app");

  return g_file_get_child (var_app, app_id);
}

FlatpakExports *
flatpak_context_get_exports (FlatpakContext *context,
                             const char     *app_id)
{
  g_autoptr(GFile) app_id_dir = flatpak_get_data_dir (app_id);

  return flatpak_context_get_exports_full (context,
                                           app_id_dir, NULL,
                                           FALSE, FALSE, NULL, NULL);
}

FlatpakRunFlags
flatpak_context_features_to_run_flags (FlatpakContextFeatures features)
{
  FlatpakRunFlags flags = 0;

  if (features & FLATPAK_CONTEXT_FEATURE_DEVEL)
    flags |= FLATPAK_RUN_FLAG_DEVEL;

  if (features & FLATPAK_CONTEXT_FEATURE_MULTIARCH)
    flags |= FLATPAK_RUN_FLAG_MULTIARCH;

  if (features & FLATPAK_CONTEXT_FEATURE_BLUETOOTH)
    flags |= FLATPAK_RUN_FLAG_BLUETOOTH;

  if (features & FLATPAK_CONTEXT_FEATURE_CANBUS)
    flags |= FLATPAK_RUN_FLAG_CANBUS;

  return flags;
}

FlatpakExports *
flatpak_context_get_exports_full (FlatpakContext *context,
                                  GFile          *app_id_dir,
                                  GPtrArray      *extra_app_id_dirs,
                                  gboolean        do_create,
                                  gboolean        include_default_dirs,
                                  gchar         **xdg_dirs_conf_out,
                                  gboolean       *home_access_out)
{
  g_autoptr(FlatpakExports) exports = flatpak_exports_new ();

  flatpak_context_export (context, exports,
                          app_id_dir, extra_app_id_dirs,
                          do_create, xdg_dirs_conf_out, home_access_out);

  if (include_default_dirs)
    {
      g_autoptr(GFile) user_flatpak_dir = NULL;
      g_autoptr(GError) local_error = NULL;

      /* Hide the flatpak dir by default (unless explicitly made visible) */
      user_flatpak_dir = flatpak_get_user_base_dir_location ();
      if (!flatpak_exports_add_path_tmpfs (exports,
                                           flatpak_file_get_path_cached (user_flatpak_dir),
                                           &local_error))
        {
          log_cannot_export_error (FLATPAK_FILESYSTEM_MODE_NONE,
                                   flatpak_file_get_path_cached (user_flatpak_dir),
                                   local_error);
          g_clear_error (&local_error);
        }

      /* Ensure we always have a homedir */
      if (!flatpak_exports_add_path_dir (exports, g_get_home_dir (), &local_error))
        {
          g_warning (_("Unable to provide a temporary home directory in the sandbox: %s"),
                     local_error->message);
          g_clear_error (&local_error);
        }
    }

  return g_steal_pointer (&exports);
}

static void
flatpak_context_apply_env_appid (FlatpakBwrap *bwrap,
                                 GFile        *app_dir)
{
  g_autoptr(GFile) app_dir_data = NULL;
  g_autoptr(GFile) app_dir_config = NULL;
  g_autoptr(GFile) app_dir_cache = NULL;
  g_autoptr(GFile) app_dir_state = NULL;

  app_dir_data = g_file_get_child (app_dir, "data");
  app_dir_config = g_file_get_child (app_dir, "config");
  app_dir_cache = g_file_get_child (app_dir, "cache");
  /* Yes, this is inconsistent with data, config and cache. However, using
   * this path lets apps provide backwards-compatibility with older Flatpak
   * versions by using `--persist=.local/state --unset-env=XDG_STATE_DIR`. */
  app_dir_state = g_file_get_child (app_dir, ".local/state");
  flatpak_bwrap_set_env (bwrap, "XDG_DATA_HOME", flatpak_file_get_path_cached (app_dir_data), TRUE);
  flatpak_bwrap_set_env (bwrap, "XDG_CONFIG_HOME", flatpak_file_get_path_cached (app_dir_config), TRUE);
  flatpak_bwrap_set_env (bwrap, "XDG_CACHE_HOME", flatpak_file_get_path_cached (app_dir_cache), TRUE);
  flatpak_bwrap_set_env (bwrap, "XDG_STATE_HOME", flatpak_file_get_path_cached (app_dir_state), TRUE);

  if (g_getenv ("XDG_DATA_HOME"))
    flatpak_bwrap_set_env (bwrap, "HOST_XDG_DATA_HOME", g_getenv ("XDG_DATA_HOME"), TRUE);
  if (g_getenv ("XDG_CONFIG_HOME"))
    flatpak_bwrap_set_env (bwrap, "HOST_XDG_CONFIG_HOME", g_getenv ("XDG_CONFIG_HOME"), TRUE);
  if (g_getenv ("XDG_CACHE_HOME"))
    flatpak_bwrap_set_env (bwrap, "HOST_XDG_CACHE_HOME", g_getenv ("XDG_CACHE_HOME"), TRUE);
  if (g_getenv ("XDG_STATE_HOME"))
    flatpak_bwrap_set_env (bwrap, "HOST_XDG_STATE_HOME", g_getenv ("XDG_STATE_HOME"), TRUE);
}

/* This creates zero or more directories unders base_fd+basedir, each
 * being guaranteed to either exist and be a directory (no symlinks)
 * or be created as a directory. The last directory is opened
 * and the fd is returned.
 */
static gboolean
mkdir_p_open_nofollow_at (int          base_fd,
                          const char  *basedir,
                          int          mode,
                          const char  *subdir,
                          int         *out_fd,
                          GError     **error)
{
  glnx_autofd int parent_fd = -1;

  if (g_path_is_absolute (subdir))
    {
      const char *skipped_prefix = subdir;

      while (*skipped_prefix == '/')
        skipped_prefix++;

      g_warning ("--persist=\"%s\" is deprecated, treating it as --persist=\"%s\"", subdir, skipped_prefix);
      subdir = skipped_prefix;
    }

  g_autofree char *subdir_dirname = g_path_get_dirname (subdir);

  if (strcmp (subdir_dirname, ".") == 0)
    {
      /* It is ok to open basedir with follow=true */
      if (!glnx_opendirat (base_fd, basedir, TRUE, &parent_fd, error))
        return FALSE;
    }
  else if (strcmp (subdir_dirname, "..") == 0)
    {
      return glnx_throw (error, "'..' not supported in --persist paths");
    }
  else
    {
      if (!mkdir_p_open_nofollow_at (base_fd, basedir, mode,
                                     subdir_dirname, &parent_fd, error))
        return FALSE;
    }

  g_autofree char *subdir_basename = g_path_get_basename (subdir);

  if (strcmp (subdir_basename, ".") == 0)
    {
      *out_fd = glnx_steal_fd (&parent_fd);
      return TRUE;
    }
  else if (strcmp (subdir_basename, "..") == 0)
    {
      return glnx_throw (error, "'..' not supported in --persist paths");
    }

  if (!glnx_shutil_mkdir_p_at (parent_fd, subdir_basename, mode, NULL, error))
    return FALSE;

  int fd = openat (parent_fd, subdir_basename, O_PATH | O_NONBLOCK | O_DIRECTORY | O_CLOEXEC | O_NOCTTY | O_NOFOLLOW);
  if (fd == -1)
    {
      int saved_errno = errno;
      struct stat stat_buf;

      /* If it's a symbolic link, that could be a user trying to offload
       * large data to another filesystem, but it could equally well be
       * a malicious or compromised app trying to exploit GHSA-7hgv-f2j8-xw87.
       * Produce a clearer error message in this case.
       * Unfortunately the errno we get in this case is ENOTDIR, so we have
       * to ask again to find out whether it's really a symlink. */
      if (saved_errno == ENOTDIR &&
          fstatat (parent_fd, subdir_basename, &stat_buf, AT_SYMLINK_NOFOLLOW) == 0 &&
          S_ISLNK (stat_buf.st_mode))
        return glnx_throw (error, "Symbolic link \"%s\" not allowed to avoid sandbox escape", subdir_basename);

      return glnx_throw_errno_prefix (error, "openat(%s)", subdir_basename);
    }

  *out_fd = fd;
  return TRUE;
}

void
flatpak_context_append_bwrap_filesystem (FlatpakContext  *context,
                                         FlatpakBwrap    *bwrap,
                                         const char      *app_id,
                                         GFile           *app_id_dir,
                                         FlatpakExports  *exports,
                                         const char      *xdg_dirs_conf,
                                         gboolean         home_access)
{
  GHashTableIter iter;
  gpointer key, value;

  if (app_id_dir != NULL)
    flatpak_context_apply_env_appid (bwrap, app_id_dir);

  if (!home_access)
    {
      /* Enable persistent mapping only if no access to real home dir */

      g_hash_table_iter_init (&iter, context->persistent);
      while (g_hash_table_iter_next (&iter, &key, NULL))
        {
          const char *persist = key;
          g_autofree char *appdir = g_build_filename (g_get_home_dir (), ".var/app", app_id, NULL);
          g_autofree char *dest = g_build_filename (g_get_home_dir (), persist, NULL);
          g_autoptr(GError) local_error = NULL;

          if (g_mkdir_with_parents (appdir, 0755) != 0)
            {
              g_warning ("Unable to create directory %s", appdir);
              continue;
            }

          /* Don't follow symlinks from the persist directory, as it is under user control */
          glnx_autofd int src_fd = -1;
          if (!mkdir_p_open_nofollow_at (AT_FDCWD, appdir, 0755,
                                         persist, &src_fd,
                                         &local_error))
            {
              g_warning ("Failed to create persist path %s: %s", persist, local_error->message);
              continue;
            }

          g_autofree char *src_via_proc = g_strdup_printf ("%d", src_fd);

          flatpak_bwrap_add_fd (bwrap, g_steal_fd (&src_fd));
          flatpak_bwrap_add_bind_arg (bwrap, "--bind-fd", src_via_proc, dest);
        }
    }

  if (app_id_dir != NULL)
    {
      g_autofree char *user_runtime_dir = flatpak_get_real_xdg_runtime_dir ();
      g_autofree char *run_user_app_dst = g_strdup_printf ("/run/flatpak/app/%s", app_id);
      g_autofree char *run_user_app_src = g_build_filename (user_runtime_dir, "app", app_id, NULL);

      if (glnx_shutil_mkdir_p_at (AT_FDCWD,
                                  run_user_app_src,
                                  0700,
                                  NULL,
                                  NULL))
        flatpak_bwrap_add_args (bwrap,
                                "--bind", run_user_app_src, run_user_app_dst,
                                NULL);

      /* Later, we'll make $XDG_RUNTIME_DIR/app a symlink to /run/flatpak/app */
      flatpak_bwrap_add_runtime_dir_member (bwrap, "app");
    }

  /* This actually outputs the args for the hide/expose operations
   * in the exports */
  flatpak_exports_append_bwrap_args (exports, bwrap);

  /* Special case subdirectories of the cache, config and data xdg
   * dirs.  If these are accessible explicitly, then we bind-mount
   * these in the app-id dir. This allows applications to explicitly
   * opt out of keeping some config/cache/data in the app-specific
   * directory.
   */
  if (app_id_dir)
    {
      g_hash_table_iter_init (&iter, context->filesystems);
      while (g_hash_table_iter_next (&iter, &key, &value))
        {
          const char *filesystem = key;
          FlatpakFilesystemMode mode = GPOINTER_TO_INT (value);
          g_autofree char *xdg_path = NULL;
          const char *rest, *where;

          xdg_path = get_xdg_dir_from_string (filesystem, &rest, &where);

          if (xdg_path != NULL && *rest != 0 &&
              mode >= FLATPAK_FILESYSTEM_MODE_READ_ONLY)
            {
              g_autoptr(GFile) app_version = g_file_get_child (app_id_dir, where);
              g_autoptr(GFile) app_version_subdir = g_file_resolve_relative_path (app_version, rest);

              if (g_file_test (xdg_path, G_FILE_TEST_IS_DIR) ||
                  g_file_test (xdg_path, G_FILE_TEST_IS_REGULAR))
                {
                  g_autofree char *xdg_path_in_app = g_file_get_path (app_version_subdir);
                  flatpak_bwrap_add_bind_arg (bwrap,
                                              mode == FLATPAK_FILESYSTEM_MODE_READ_ONLY ? "--ro-bind" : "--bind",
                                              xdg_path, xdg_path_in_app);
                }
            }
        }
    }

  if (home_access && app_id_dir != NULL)
    {
      g_autofree char *src_path = g_build_filename (g_get_user_config_dir (),
                                                    "user-dirs.dirs",
                                                    NULL);
      g_autofree char *path = g_build_filename (flatpak_file_get_path_cached (app_id_dir),
                                                "config/user-dirs.dirs", NULL);
      if (g_file_test (src_path, G_FILE_TEST_EXISTS))
        flatpak_bwrap_add_bind_arg (bwrap, "--ro-bind", src_path, path);
    }
  else if (xdg_dirs_conf != NULL && xdg_dirs_conf[0] != '\0' && app_id_dir != NULL)
    {
      g_autofree char *path =
        g_build_filename (flatpak_file_get_path_cached (app_id_dir),
                          "config/user-dirs.dirs", NULL);

      flatpak_bwrap_add_args_data (bwrap, "xdg-config-dirs",
                                   xdg_dirs_conf, strlen (xdg_dirs_conf), path, NULL);
    }
}

gboolean
flatpak_context_get_allowed_exports (FlatpakContext *context,
                                     const char     *source_path,
                                     const char     *app_id,
                                     char         ***allowed_extensions_out,
                                     char         ***allowed_prefixes_out,
                                     gboolean       *require_exact_match_out)
{
  g_autoptr(GPtrArray) allowed_extensions = g_ptr_array_new_with_free_func (g_free);
  g_autoptr(GPtrArray) allowed_prefixes = g_ptr_array_new_with_free_func (g_free);
  gboolean require_exact_match = FALSE;

  g_ptr_array_add (allowed_prefixes, g_strdup_printf ("%s.*", app_id));

  if (strcmp (source_path, "share/applications") == 0)
    {
      g_ptr_array_add (allowed_extensions, g_strdup (".desktop"));
    }
  else if (flatpak_has_path_prefix (source_path, "share/icons"))
    {
      g_ptr_array_add (allowed_extensions, g_strdup (".svgz"));
      g_ptr_array_add (allowed_extensions, g_strdup (".png"));
      g_ptr_array_add (allowed_extensions, g_strdup (".svg"));
      g_ptr_array_add (allowed_extensions, g_strdup (".ico"));
    }
  else if (strcmp (source_path, "share/dbus-1/services") == 0)
    {
      g_auto(GStrv) owned_dbus_names =  flatpak_context_get_session_bus_policy_allowed_own_names (context);

      g_ptr_array_add (allowed_extensions, g_strdup (".service"));

      for (GStrv iter = owned_dbus_names; *iter != NULL; ++iter)
        g_ptr_array_add (allowed_prefixes, g_strdup (*iter));

      /* We need an exact match with no extra garbage, because the filename refers to busnames
       * and we can *only* match exactly these */
      require_exact_match = TRUE;
    }
  else if (strcmp (source_path, "share/gnome-shell/search-providers") == 0)
    {
      g_ptr_array_add (allowed_extensions, g_strdup (".ini"));
    }
  else if (strcmp (source_path, "share/krunner/dbusplugins") == 0)
    {
      g_ptr_array_add (allowed_extensions, g_strdup (".desktop"));
    }
  else if (strcmp (source_path, "share/mime/packages") == 0)
    {
      g_ptr_array_add (allowed_extensions, g_strdup (".xml"));
    }
  else if (strcmp (source_path, "share/metainfo") == 0 ||
           strcmp (source_path, "share/appdata") == 0)
    {
      g_ptr_array_add (allowed_extensions, g_strdup (".xml"));
    }
  else if (strcmp (source_path, "share/metainfo/releases") == 0)
    {
      g_ptr_array_add (allowed_extensions, g_strdup (".releases.xml"));
    }
  else
    return FALSE;

  g_ptr_array_add (allowed_extensions, NULL);
  g_ptr_array_add (allowed_prefixes, NULL);

  if (allowed_extensions_out)
    *allowed_extensions_out = (char **) g_ptr_array_free (g_steal_pointer (&allowed_extensions), FALSE);

  if (allowed_prefixes_out)
    *allowed_prefixes_out = (char **) g_ptr_array_free (g_steal_pointer (&allowed_prefixes), FALSE);

  if (require_exact_match_out)
    *require_exact_match_out = require_exact_match;

  return TRUE;
}

void
flatpak_context_dump (FlatpakContext *context,
                      const char     *title)
{
  if (flatpak_is_debugging ())
    {
      g_autoptr(GError) local_error = NULL;
      g_autoptr(GKeyFile) metakey = NULL;
      g_autofree char *data = NULL;
      char *saveptr = NULL;
      const char *line;

      metakey = g_key_file_new ();
      flatpak_context_save_metadata (context, FALSE, metakey);

      data = g_key_file_to_data (metakey, NULL, &local_error);

      if (data == NULL)
        {
          g_debug ("%s: (unable to serialize: %s)",
                   title, local_error->message);
          return;
        }

      g_debug ("%s:", title);

      for (line = strtok_r (data, "\n", &saveptr);
           line != NULL;
           line = strtok_r (NULL, "\n", &saveptr))
        g_debug ("\t%s", line);

      g_debug ("\t#");
    }
}

FlatpakContextShares
flatpak_context_compute_allowed_shares (FlatpakContext                   *context,
                                        FlatpakContextConditionEvaluator  evaluator)
{
  return flatpak_permissions_compute_allowed (context->shares_permissions,
                                              flatpak_context_shares,
                                              evaluator);
}

FlatpakContextSockets
flatpak_context_compute_allowed_sockets (FlatpakContext                   *context,
                                         FlatpakContextConditionEvaluator  evaluator)
{
  g_autoptr(GHashTable) permissions =
    g_hash_table_new_similar (context->socket_permissions);
  GHashTableIter iter;
  gpointer key, value;
  FlatpakPermission *fallback_x11;

  g_hash_table_iter_init (&iter, context->socket_permissions);
  while (g_hash_table_iter_next (&iter, &key, &value))
    g_hash_table_insert (permissions, g_strdup (key), flatpak_permission_dup (value));

  fallback_x11 = g_hash_table_lookup (context->socket_permissions, "fallback-x11");
  if (fallback_x11 && fallback_x11->allowed)
    {
      FlatpakPermission *x11 = flatpak_permissions_ensure (permissions, "x11");

      x11->allowed = FALSE;
      flatpak_permission_set_allowed_if (x11, "!has-wayland");
    }
  g_hash_table_remove (permissions, "fallback-x11");

  return flatpak_permissions_compute_allowed (permissions,
                                              flatpak_context_sockets,
                                              evaluator);
}

FlatpakContextDevices
flatpak_context_compute_allowed_devices (FlatpakContext                   *context,
                                         FlatpakContextConditionEvaluator  evaluator)
{
  return flatpak_permissions_compute_allowed (context->device_permissions,
                                              flatpak_context_devices,
                                              evaluator);
}


FlatpakContextFeatures
flatpak_context_compute_allowed_features (FlatpakContext                   *context,
                                          FlatpakContextConditionEvaluator  evaluator)
{
  return flatpak_permissions_compute_allowed (context->features_permissions,
                                              flatpak_context_features,
                                              evaluator);
}

===== ./common/flatpak-version-macros.h.in =====
/*
 * Copyright © 2015 Red Hat, Inc
 *
 * This program 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 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Alexander Larsson <alexl@redhat.com>
 */

#if !defined (__FLATPAK_H_INSIDE__) && !defined (FLATPAK_COMPILATION)
#error "Only <flatpak.h> can be included directly."
#endif

#ifndef __FLATPAK_VERSION_MACROS_H__
#define __FLATPAK_VERSION_MACROS_H__


/**
 * FLATPAK_MAJOR_VERSION:
 *
 * The major version.
 */
#define FLATPAK_MAJOR_VERSION (@FLATPAK_MAJOR_VERSION@)

/**
 * FLATPAK_MINOR_VERSION:
 *
 * The minor version.
 */
#define FLATPAK_MINOR_VERSION (@FLATPAK_MINOR_VERSION@)

/**
 * FLATPAK_MICRO_VERSION:
 *
 * The micro version.
 */
#define FLATPAK_MICRO_VERSION (@FLATPAK_MICRO_VERSION@)

/**
 * FLATPAK_CHECK_VERSION:
 * @major: major version to compare against
 * @minor: minor version to compare against
 * @micro: micro version to compare against
 *
 * Check that the current version is at least @major.@minor.@micro.
 */
#define FLATPAK_CHECK_VERSION(major,minor,micro)        \
    (FLATPAK_MAJOR_VERSION > (major) || \
     (FLATPAK_MAJOR_VERSION == (major) && FLATPAK_MINOR_VERSION > (minor)) || \
     (FLATPAK_MAJOR_VERSION == (major) && FLATPAK_MINOR_VERSION == (minor) && \
      FLATPAK_MICRO_VERSION >= (micro)))

#ifndef FLATPAK_EXTERN
#define FLATPAK_EXTERN extern
#endif

/**
 * SECTION:flatpak-version-macros
 * @Title: Version information
 *
 * These macros can be used to check the library version in use.
 */

#endif /* __FLATPAK_VERSION_MACROS_H__ */

===== ./common/flatpak-portal-error.c =====
/* flatpak-error.c
 *
 * Copyright (C) 2015 Red Hat, Inc
 *
 * This file 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 of the
 * License, or (at your option) any later version.
 *
 * This file 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 program.  If not, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Alexander Larsson <alexl@redhat.com>
 */

#include "config.h"

#include "flatpak-portal-error.h"

#include <gio/gio.h>

static const GDBusErrorEntry flatpak_error_entries[] = {
  {FLATPAK_PORTAL_ERROR_FAILED,                           "org.freedesktop.portal.Error.Failed"},
  {FLATPAK_PORTAL_ERROR_INVALID_ARGUMENT,                 "org.freedesktop.portal.Error.InvalidArgument"},
  {FLATPAK_PORTAL_ERROR_NOT_FOUND,                        "org.freedesktop.portal.Error.NotFound"},
  {FLATPAK_PORTAL_ERROR_EXISTS,                           "org.freedesktop.portal.Error.Exists"},
  {FLATPAK_PORTAL_ERROR_NOT_ALLOWED,                      "org.freedesktop.portal.Error.NotAllowed"},
  {FLATPAK_PORTAL_ERROR_CANCELLED,                        "org.freedesktop.portal.Error.Cancelled"},
  {FLATPAK_PORTAL_ERROR_WINDOW_DESTROYED,                 "org.freedesktop.portal.Error.WindowDestroyed"},
};

GQuark
flatpak_portal_error_quark (void)
{
  static volatile gsize quark_volatile = 0;

  g_dbus_error_register_error_domain ("flatpak-portal-error-quark",
                                      &quark_volatile,
                                      flatpak_error_entries,
                                      G_N_ELEMENTS (flatpak_error_entries));
  return (GQuark) quark_volatile;
}

===== ./common/flatpak-transaction.c =====
/* vi:set et sw=2 sts=2 cin cino=t0,f0,(0,{s,>2s,n-s,^-s,e-s:
 * Copyright © 2016 Red Hat, Inc
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Alexander Larsson <alexl@redhat.com>
 */

#include "config.h"

#include <stdio.h>
#include <glib/gi18n-lib.h>

#include "flatpak-auth-private.h"
#include "flatpak-dir-private.h"
#include "flatpak-error.h"
#include "flatpak-image-collection-private.h"
#include "flatpak-image-source-private.h"
#include "flatpak-installation-private.h"
#include "flatpak-oci-registry-private.h"
#include "flatpak-progress-private.h"
#include "flatpak-repo-utils-private.h"
#include "flatpak-transaction-private.h"
#include "flatpak-utils-http-private.h"
#include "flatpak-utils-private.h"
#include "flatpak-uri-private.h"
#include "flatpak-variant-impl-private.h"

/**
 * SECTION:flatpak-transaction
 * @Title: FlatpakTransaction
 * @Short_description: Transaction information
 *
 * FlatpakTransaction is an object representing an install/update/uninstall
 * transaction. You create an object like this using flatpak_transaction_new_for_installation()
 * and then you add all the operations (installs, updates, etc) you wish to do. Then
 * you start the transaction with flatpak_transaction_run() which will resolve all kinds
 * of dependencies and report progress and status while downloading and installing these.
 *
 * The dependency resolution that is the first step of executing a transaction can
 * be influenced by flatpak_transaction_set_disable_dependencies(),
 * flatpak_transaction_set_disable_related(), flatpak_transaction_add_dependency_source()
 * and flatpak_transaction_add_default_dependency_sources().
 *
 * The underlying operations that get orchestrated by a FlatpakTransaction are: pulling
 * new data from remote repositories, deploying newer applications or runtimes and pruning
 * old deployments. Which of these operations are carried out can be controlled with
 * flatpak_transaction_set_no_pull(), flatpak_transaction_set_no_deploy() and
 * flatpak_transaction_set_disable_prune().
 *
 * A transaction is a blocking operation, and all signals are emitted in the same thread.
 * This means you should either handle the signals directly (say, by doing blocking console
 * interaction, or by just returning without interaction), or run the operation in a separate
 * thread and do your own forwarding to the GUI thread.
 *
 * Despite the name, a FlatpakTransaction is more like a batch operation than a transaction
 * in the database sense. Individual operations are carried out sequentially, and are atomic.
 * They become visible to the system as they are completed. When an error occurs, already
 * completed operations are not rolled back.
 *
 * For each operation that is executed during a transaction, you first get a
 * #FlatpakTransaction::new-operation signal, followed by either a
 * #FlatpakTransaction::operation-done or #FlatpakTransaction::operation-error.

 * The FlatpakTransaction API is threadsafe in the sense that it is safe to run two
 * transactions at the same time, in different threads (or processes).
 *
 * Note: Transactions (or any other install/update operation) to a
 * system installation rely on the ability to create files that are readable
 * by other users. Some users set a umask that prohibits this. Unfortunately
 * there is no good way to work around this in a threadsafe, local way, so
 * such setups will break by default. The flatpak commandline app works
 * around this by calling umask(022) in the early setup, and it is recommended
 * that other apps using libflatpak do this too.
 */

/* This is an internal-only element of FlatpakTransactionOperationType */
#define FLATPAK_TRANSACTION_OPERATION_INSTALL_OR_UPDATE FLATPAK_TRANSACTION_OPERATION_LAST_TYPE + 1

enum {
  RUNTIME_UPDATE,
  RUNTIME_INSTALL,
  APP_UPDATE,
  APP_INSTALL
};

struct _FlatpakTransactionOperation
{
  GObject                         parent;

  char                           *remote;
  FlatpakDecomposed              *ref;
  /* NULL means unspecified (normally keep whatever was there before), [] means force everything */
  char                          **subpaths;
  char                          **previous_ids;
  char                           *commit;
  FlatpakImageSource             *image_source;
  GFile                          *bundle;
  GBytes                         *external_metadata;
  FlatpakTransactionOperationType kind;
  gboolean                        non_fatal;
  gboolean                        failed;
  gboolean                        skip;
  gboolean                        update_only_deploy;
  gboolean                        pin_on_deploy;
  gboolean                        update_preinstalled_on_deploy;

  gboolean                        resolved;
  char                           *resolved_commit;
  GFile                          *resolved_sideload_path;
  FlatpakImageSource             *resolved_image_source;
  GBytes                         *resolved_metadata;
  GKeyFile                       *resolved_metakey;
  GBytes                         *resolved_old_metadata;
  GKeyFile                       *resolved_old_metakey;
  char                           *resolved_token;
  gboolean                        requested_token; /* TRUE if we requested a token. value in resolved_token, but may be NULL if token not needed. */
  guint64                         download_size;
  guint64                         installed_size;
  char                           *eol;
  char                           *eol_rebase;
  gint32                          token_type;
  GVariant                       *summary_metadata; /* Additional metadatafield for commit from summary */
  int                             run_after_count;
  int                             run_after_prio; /* Higher => run later (when it becomes runnable). Used to run related ops (runtime extensions) before deps (apps using the runtime) */
  GList                          *run_before_ops;
  gboolean                        run_last;  /* Run this after all the other apps that are not run_last */
  FlatpakTransactionOperation    *fail_if_op_fails; /* main app/runtime for related extensions, runtime for apps, install/update for uninstalls of eol-rebase apps */
  /* main app/runtime for related extensions, app for runtimes; could be multiple
   * related-to-ops if this op is for a runtime which is needed by multiple apps
   * in the transaction: */
  GPtrArray                      *related_to_ops;  /* (element-type FlatpakTransactionOperation) (nullable) */
};

typedef struct _BundleData
{
  GFile  *file;
  GBytes *gpg_data;
} BundleData;

typedef struct _ImageData
{
  char *image_location;
} ImageData;

typedef struct {
  FlatpakTransaction *transaction;
  const char *remote;
  FlatpakAuthenticatorRequest *request;
  gboolean done;
  guint response;
  GVariant *results;
} RequestData;

typedef struct _FlatpakTransactionPrivate
{
  GObject                      parent;

  FlatpakInstallation         *installation;
  FlatpakDir                  *dir;
  GHashTable                  *last_op_for_ref;
  GHashTable                  *remote_states; /* (element-type utf8 FlatpakRemoteState) */
  GPtrArray                   *extra_dependency_dirs;
  GPtrArray                   *extra_sideload_repos;
  GPtrArray                   *sideload_image_collections;
  GList                       *ops;
  GPtrArray                   *added_origin_remotes;

  GList                       *flatpakrefs; /* GKeyFiles */
  GList                       *bundles; /* BundleData */
  GList                       *images; /* ImageData */

  guint                        next_request_id;
  guint                        active_request_id;
  RequestData                 *active_request;

  FlatpakTransactionOperation *current_op;

  char                        *parent_window;
  gboolean                     no_pull;
  gboolean                     no_deploy;
  gboolean                     disable_auto_pin;
  gboolean                     disable_static_deltas;
  gboolean                     disable_prune;
  gboolean                     disable_deps;
  gboolean                     disable_related;
  gboolean                     reinstall;
  gboolean                     force_uninstall;
  gboolean                     can_run;
  gboolean                     include_unused_uninstall_ops;
  gboolean                     auto_install_sdk;
  gboolean                     auto_install_debug;
  char                        *default_arch;
  guint                        max_op;

  gboolean                     needs_resolve;
  gboolean                     needs_tokens;
} FlatpakTransactionPrivate;

enum {
  NEW_OPERATION,
  OPERATION_DONE,
  OPERATION_ERROR,
  CHOOSE_REMOTE_FOR_REF,
  END_OF_LIFED,
  END_OF_LIFED_WITH_REBASE,
  READY,
  READY_PRE_AUTH,
  ADD_NEW_REMOTE,
  WEBFLOW_START,
  WEBFLOW_DONE,
  BASIC_AUTH_START,
  INSTALL_AUTHENTICATOR,
  LAST_SIGNAL
};

typedef enum {
  PROP_INSTALLATION = 1,
  PROP_NO_INTERACTION,
} FlatpakTransactionProperty;

struct _FlatpakTransactionProgress
{
  GObject              parent;

  FlatpakProgress     *progress_obj;
};

enum {
  CHANGED,
  LAST_PROGRESS_SIGNAL
};

static gboolean op_may_need_token (FlatpakTransactionOperation *op);

static void flatpak_transaction_normalize_ops (FlatpakTransaction *self);
static gboolean request_required_tokens (FlatpakTransaction *self,
                                         const char         *optional_remote,
                                         GCancellable       *cancellable,
                                         GError            **error);


static BundleData *
bundle_data_new (GFile  *file,
                 GBytes *gpg_data)
{
  BundleData *data = g_new0 (BundleData, 1);

  data->file = g_object_ref (file);
  if (gpg_data)
    data->gpg_data = g_bytes_ref (gpg_data);

  return data;
}

static void
bundle_data_free (BundleData *data)
{
  g_clear_object (&data->file);
  g_clear_object (&data->gpg_data);
  g_free (data);
}

static ImageData *
image_data_new (const char *image_location)
{
  ImageData *data = g_new0 (ImageData, 1);

  data->image_location = g_strdup (image_location);

  return data;
}

static void
image_data_free (ImageData *data)
{
  g_clear_pointer (&data->image_location, g_free);
  g_free (data);
}

static guint progress_signals[LAST_SIGNAL] = { 0 };

/**
 * SECTION:flatpak-transaction-progress
 * @Title: FlatpakTransactionProgress
 * @Short_description: Progress of an operation
 *
 * FlatpakTransactionProgress is an object that represents the progress
 * of a single operation in a transaction. You obtain a FlatpakTransactionProgress
 * with the #FlatpakTransaction::new-operation signal.
 */

G_DEFINE_TYPE (FlatpakTransactionProgress, flatpak_transaction_progress, G_TYPE_OBJECT)

/**
 * flatpak_transaction_progress_set_update_frequency:
 * @self: a #FlatpakTransactionProgress
 * @update_interval: the update interval, in milliseconds
 *
 * Sets how often progress should be updated.
 */
void
flatpak_transaction_progress_set_update_frequency (FlatpakTransactionProgress *self,
                                                   guint                       update_interval)
{
  flatpak_progress_set_update_interval (self->progress_obj, update_interval);
}

/**
 * flatpak_transaction_progress_get_status:
 * @self: a #FlatpakTransactionProgress
 *
 * Gets the current status string
 *
 * Returns: (transfer full): the current status
 */
char *
flatpak_transaction_progress_get_status (FlatpakTransactionProgress *self)
{
  return g_strdup (flatpak_progress_get_status (self->progress_obj));
}

/**
 * flatpak_transaction_progress_get_is_estimating:
 * @self: a #FlatpakTransactionProgress
 *
 * Gets whether the progress is currently estimating
 *
 * Returns: whether we're estimating
 */
gboolean
flatpak_transaction_progress_get_is_estimating (FlatpakTransactionProgress *self)
{
  return flatpak_progress_get_estimating (self->progress_obj);
}

/**
 * flatpak_transaction_progress_get_progress:
 * @self: a #FlatpakTransactionProgress
 *
 * Gets the current progress.
 *
 * Returns: the current progress, as an integer between 0 and 100
 */
int
flatpak_transaction_progress_get_progress (FlatpakTransactionProgress *self)
{
  return flatpak_progress_get_progress (self->progress_obj);
}

/**
 * flatpak_transaction_progress_get_bytes_transferred:
 * @self: a #FlatpakTransactionProgress
 *
 * Gets the number of bytes that have been transferred.
 *
 * Returns: the number of bytes transferred
 * Since: 1.1.2
 */
guint64
flatpak_transaction_progress_get_bytes_transferred (FlatpakTransactionProgress *self)
{
  guint64 bytes_transferred, transferred_extra_data_bytes;

  bytes_transferred = flatpak_progress_get_bytes_transferred (self->progress_obj);
  transferred_extra_data_bytes = flatpak_progress_get_transferred_extra_data_bytes (self->progress_obj);

  return bytes_transferred + transferred_extra_data_bytes;
}

/**
 * flatpak_transaction_progress_get_start_time:
 * @self: a #FlatpakTransactionProgress
 *
 * Gets the time at which this operation has started, as monotonic time.
 *
 * Returns: the start time
 * Since: 1.1.2
 */
guint64
flatpak_transaction_progress_get_start_time (FlatpakTransactionProgress *self)
{
  return flatpak_progress_get_start_time (self->progress_obj);
}

static void
flatpak_transaction_progress_finalize (GObject *object)
{
  FlatpakTransactionProgress *self = (FlatpakTransactionProgress *) object;

  g_object_unref (self->progress_obj);

  G_OBJECT_CLASS (flatpak_transaction_progress_parent_class)->finalize (object);
}

static void
flatpak_transaction_progress_class_init (FlatpakTransactionProgressClass *klass)
{
  GObjectClass *object_class = G_OBJECT_CLASS (klass);

  object_class->finalize = flatpak_transaction_progress_finalize;

  /**
   * FlatpakTransactionProgress::changed:
   * @object: A #FlatpakTransactionProgress
   *
   * Emitted when some detail of the progress object changes, you can call the various methods to get the current status.
   */
  progress_signals[CHANGED] =
    g_signal_new ("changed",
                  G_TYPE_FROM_CLASS (object_class),
                  G_SIGNAL_RUN_LAST,
                  0,
                  NULL, NULL,
                  NULL,
                  G_TYPE_NONE, 0);
}

static void
got_progress_cb (const char *status,
                 guint       progress,
                 gboolean    estimating,
                 gpointer    user_data)
{
  FlatpakTransactionProgress *p = user_data;

  if (!flatpak_progress_is_done (p->progress_obj))
    g_signal_emit (p, progress_signals[CHANGED], 0);
}

static void
flatpak_transaction_progress_init (FlatpakTransactionProgress *self)
{
  self->progress_obj = flatpak_progress_new (got_progress_cb, self);
}

static void
flatpak_transaction_progress_done (FlatpakTransactionProgress *self)
{
  flatpak_progress_done (self->progress_obj);
}

static FlatpakTransactionProgress *
flatpak_transaction_progress_new (void)
{
  return g_object_new (FLATPAK_TYPE_TRANSACTION_PROGRESS, NULL);
}

static guint signals[LAST_SIGNAL] = { 0 };

static void initable_iface_init (GInitableIface *initable_iface);

G_DEFINE_TYPE_WITH_CODE (FlatpakTransaction, flatpak_transaction, G_TYPE_OBJECT,
                         G_ADD_PRIVATE (FlatpakTransaction)
                         G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, initable_iface_init))

static gboolean
transaction_is_local_only (FlatpakTransaction             *self,
                           FlatpakTransactionOperationType kind)
{
  FlatpakTransactionPrivate *priv = flatpak_transaction_get_instance_private (self);

  return priv->no_pull || kind == FLATPAK_TRANSACTION_OPERATION_UNINSTALL;
}

static gboolean
remote_name_is_file (const char *remote_name)
{
  return remote_name != NULL &&
         g_str_has_prefix (remote_name, "file://");
}

/**
 * flatpak_transaction_add_dependency_source:
 * @self: a #FlatpakTransaction
 * @installation: a #FlatpakInstallation
 *
 * Adds an extra installation as a source for application dependencies.
 * This means that applications can be installed in this transaction relying
 * on runtimes from this additional installation (whereas it would normally
 * install required runtimes that are not installed in the installation
 * the transaction works on).
 *
 * Also see flatpak_transaction_add_default_dependency_sources().
 */
void
flatpak_transaction_add_dependency_source (FlatpakTransaction  *self,
                                           FlatpakInstallation *installation)
{
  FlatpakTransactionPrivate *priv = flatpak_transaction_get_instance_private (self);

  g_ptr_array_add (priv->extra_dependency_dirs,
                   flatpak_installation_clone_dir_noensure (installation));
}

/**
 * flatpak_transaction_add_sideload_repo:
 * @self: a #FlatpakTransaction
 * @path: a path to a local flatpak repository
 *
 * Adds an extra local ostree repo as source for installation. This is
 * equivalent to using the sideload-repos directories (see flatpak(1)), but can
 * be done dynamically. Any path added here is used in addition to ones in
 * those directories.
 *
 * Since: 1.7.1
 */
void
flatpak_transaction_add_sideload_repo (FlatpakTransaction  *self,
                                       const char          *path)
{
  FlatpakTransactionPrivate *priv = flatpak_transaction_get_instance_private (self);

  g_ptr_array_add (priv->extra_sideload_repos,
                   g_strdup (path));
}

/**
 * flatpak_transaction_add_sideload_image_collection:
 * @self: a #FlatpakTransaction
 * @location: source of images for installation
 *
 * Adds a set of images to be used as source for installation. This is similar
 * to flatpak_transaction_add_sideload_repo(), but the Flatpaks are stored
 * as OCI images rather than ostree commits, and the images are used for
 * all OCI remotes without regard to collection ID.
 *
 * Currently @location should be either 'oci:<path>' or 'oci-archive:<path>'.
 * Additional schemes may be added in the future.
 *
 * Since: 1.7.1
 */
gboolean
flatpak_transaction_add_sideload_image_collection (FlatpakTransaction  *self,
                                                   const char          *location,
                                                   GCancellable        *cancellable,
                                                   GError             **error)
{
  FlatpakTransactionPrivate *priv = flatpak_transaction_get_instance_private (self);
  g_autoptr(FlatpakImageCollection) collection = NULL;

  collection = flatpak_image_collection_new (location, cancellable, error);
  if (collection == NULL)
    return FALSE;

  g_ptr_array_add (priv->sideload_image_collections, g_steal_pointer (&collection));
  return TRUE;
}

/**
 * flatpak_transaction_add_default_dependency_sources:
 * @self: a #FlatpakTransaction
 *
 * Similar to flatpak_transaction_add_dependency_source(), but adds
 * all the default installations, which means all the defined system-wide
 * (but not per-user) installations.
 */
void
flatpak_transaction_add_default_dependency_sources (FlatpakTransaction *self)
{
  FlatpakTransactionPrivate *priv = flatpak_transaction_get_instance_private (self);
  g_autoptr(GPtrArray) system_dirs = NULL;
  GFile *path = flatpak_dir_get_path (priv->dir);
  int i;

  system_dirs = flatpak_dir_get_system_list (NULL, NULL);
  if (system_dirs == NULL)
    return;

  for (i = 0; i < system_dirs->len; i++)
    {
      FlatpakDir *system_dir = g_ptr_array_index (system_dirs, i);
      GFile *system_path = flatpak_dir_get_path (system_dir);

      if (g_file_equal (path, system_path))
        continue;

      g_ptr_array_add (priv->extra_dependency_dirs, g_object_ref (system_dir));
    }
}

/* Check if the ref is in the dir, or in the extra dependency source dir, in case its a
 * user-dir or another system-wide installation. We want to avoid depending
 * on user-installed things when installing to the system dir.
 */
static gboolean
ref_is_installed (FlatpakTransaction *self,
                  FlatpakDecomposed *ref)
{
  FlatpakTransactionPrivate *priv = flatpak_transaction_get_instance_private (self);
  g_autoptr(GFile) deploy_dir = NULL;
  FlatpakDir *dir = priv->dir;
  int i;

  deploy_dir = flatpak_dir_get_if_deployed (dir, ref, NULL, NULL);
  if (deploy_dir != NULL)
    return TRUE;

  for (i = 0; i < priv->extra_dependency_dirs->len; i++)
    {
      FlatpakDir *dependency_dir = g_ptr_array_index (priv->extra_dependency_dirs, i);

      deploy_dir = flatpak_dir_get_if_deployed (dependency_dir, ref, NULL, NULL);
      if (deploy_dir != NULL)
        return TRUE;
    }

  return FALSE;
}

static gboolean
dir_ref_is_installed (FlatpakDir *dir, FlatpakDecomposed *ref, char **remote_out, GBytes **deploy_data_out)
{
  g_autoptr(GBytes) deploy_data = NULL;

  deploy_data = flatpak_dir_get_deploy_data (dir, ref, FLATPAK_DEPLOY_VERSION_ANY, NULL, NULL);
  if (deploy_data == NULL)
    return FALSE;

  if (remote_out)
    *remote_out = g_strdup (flatpak_deploy_data_get_origin (deploy_data));

  if (deploy_data_out)
    *deploy_data_out = g_bytes_ref (deploy_data);

  return TRUE;
}

/**
 * SECTION:flatpak-transaction-operation
 * @Title: FlatpakTransactionOperation
 * @Short_description: Operation in a transaction
 *
 * FlatpakTransactionOperation is an object that represents a single operation
 * in a transaction. You receive a FlatpakTransactionOperation object with the
 * #FlatpakTransaction::new-operation signal.
 */

G_DEFINE_TYPE (FlatpakTransactionOperation, flatpak_transaction_operation, G_TYPE_OBJECT)

static void
flatpak_transaction_operation_finalize (GObject *object)
{
  FlatpakTransactionOperation *self = (FlatpakTransactionOperation *) object;

  g_clear_pointer (&self->remote, g_free);
  g_clear_pointer (&self->ref, flatpak_decomposed_unref);
  g_clear_pointer (&self->commit, g_free);
  g_clear_pointer (&self->subpaths, g_strfreev);
  g_clear_object (&self->bundle);
  g_clear_pointer (&self->eol, g_free);
  g_clear_pointer (&self->eol_rebase, g_free);
  g_clear_pointer (&self->previous_ids, g_strfreev);
  g_clear_pointer (&self->external_metadata, g_bytes_unref);
  g_clear_pointer (&self->resolved_commit, g_free);
  g_clear_object (&self->resolved_sideload_path);
  g_clear_pointer (&self->resolved_metadata, g_bytes_unref);
  g_clear_pointer (&self->resolved_metakey, g_key_file_unref);
  g_clear_pointer (&self->resolved_old_metadata, g_bytes_unref);
  g_clear_pointer (&self->resolved_old_metakey, g_key_file_unref);
  g_clear_pointer (&self->resolved_token, g_free);
  g_clear_pointer (&self->run_before_ops, g_list_free);
  g_clear_pointer (&self->related_to_ops, g_ptr_array_unref);
  g_clear_pointer (&self->summary_metadata, g_variant_unref);
  g_clear_object (&self->image_source);
  g_clear_object (&self->resolved_image_source);

  G_OBJECT_CLASS (flatpak_transaction_operation_parent_class)->finalize (object);
}

static void
flatpak_transaction_operation_class_init (FlatpakTransactionOperationClass *klass)
{
  GObjectClass *object_class = G_OBJECT_CLASS (klass);

  object_class->finalize = flatpak_transaction_operation_finalize;
}

static void
flatpak_transaction_operation_init (FlatpakTransactionOperation *self)
{
}

static FlatpakTransactionOperation *
flatpak_transaction_operation_new (const char                     *remote,
                                   FlatpakDecomposed              *ref,
                                   const char                    **subpaths,
                                   const char                    **previous_ids,
                                   const char                     *commit,
                                   GFile                          *bundle,
                                   FlatpakTransactionOperationType kind,
                                   gboolean                        pin_on_deploy,
                                   gboolean                        update_preinstalled_on_deploy)
{
  FlatpakTransactionOperation *self;

  self = g_object_new (FLATPAK_TYPE_TRANSACTION_OPERATION, NULL);

  self->remote = g_strdup (remote);
  self->ref = flatpak_decomposed_ref (ref);
  self->subpaths = g_strdupv ((char **) subpaths);
  self->previous_ids = g_strdupv ((char **) previous_ids);
  self->commit = g_strdup (commit);
  if (bundle)
    self->bundle = g_object_ref (bundle);
  self->kind = kind;
  self->pin_on_deploy = pin_on_deploy;
  self->update_preinstalled_on_deploy = update_preinstalled_on_deploy;

  return self;
}

/**
 * flatpak_transaction_operation_get_operation_type:
 * @self: a #FlatpakTransactionOperation
 *
 * Gets the type of the operation.
 *
 * Returns: the type of operation, as #FlatpakTransactionOperationType
 */
FlatpakTransactionOperationType
flatpak_transaction_operation_get_operation_type (FlatpakTransactionOperation *self)
{
  return self->kind;
}

/**
 * flatpak_transaction_operation_get_ref:
 * @self: a #FlatpakTransactionOperation
 *
 * Gets the ref that the operation applies to.
 *
 * Returns: (transfer none): the ref
 */
const char *
flatpak_transaction_operation_get_ref (FlatpakTransactionOperation *self)
{
  return flatpak_decomposed_get_ref (self->ref);
}

FlatpakDecomposed *
flatpak_transaction_operation_get_decomposed (FlatpakTransactionOperation *self)
{
  return self->ref;
}

/**
 * flatpak_transaction_operation_get_related_to_ops:
 * @self: a #FlatpakTransactionOperation
 *
 * Gets the operation(s) which caused this operation to be added to the
 * transaction. In the case of a runtime, it's the app(s) whose runtime it is,
 * and/or a runtime extension in the special case of an extra-data extension
 * that doesn't define the "NoRuntime" key. In the case of a related ref such
 * as an extension, it's the main app or runtime. In the case of a main app or
 * something added to the transaction by e.g. flatpak_transaction_add_install()
 * and which is not otherwise needed, %NULL or an empty array will be returned.
 *
 * Note that an op will be returned even if it’s marked as to be skipped when
 * the transaction is run. Check that using
 * flatpak_transaction_operation_get_is_skipped().
 *
 * Elements in the returned array are only safe to access while the parent
 * #FlatpakTransaction is alive.
 *
 * Returns: (transfer none) (element-type FlatpakTransactionOperation) (nullable): the
 *   #FlatpakTransactionOperations this one is related to (may be %NULL or an
 *   empty array, which are equivalent)
 * Since: 1.7.3
 */
GPtrArray *
flatpak_transaction_operation_get_related_to_ops (FlatpakTransactionOperation *self)
{
  return self->related_to_ops;
}

static void
flatpak_transaction_operation_add_related_to_op (FlatpakTransactionOperation *op,
                                                 FlatpakTransactionOperation *related_op)
{
  if (op->related_to_ops == NULL)
    op->related_to_ops = g_ptr_array_new ();
  g_ptr_array_add (op->related_to_ops, related_op);
}

/**
 * flatpak_transaction_operation_get_is_skipped:
 * @self: a #FlatpakTransactionOperation
 *
 * Gets whether this operation will be skipped when the transaction is run.
 * Operations are skipped in some transaction situations, for example when an
 * app has reached end of life and needs a rebase, or when it would have been
 * updated but no update is available. By default, skipped
 * operations are not returned by flatpak_transaction_get_operations() — but
 * they can be accessed by traversing the operation graph using
 * flatpak_transaction_operation_get_related_to_ops().
 *
 * Returns: %TRUE if the operation has been marked as to skip, %FALSE otherwise
 * Since: 1.7.3
 */
gboolean
flatpak_transaction_operation_get_is_skipped (FlatpakTransactionOperation *self)
{
  return self->skip;
}

/**
 * flatpak_transaction_operation_get_remote:
 * @self: a #FlatpakTransactionOperation
 *
 * Gets the remote that the operation applies to.
 *
 * Returns: (transfer none): the remote
 */
const char *
flatpak_transaction_operation_get_remote (FlatpakTransactionOperation *self)
{
  return self->remote;
}

/**
 * flatpak_transaction_operation_type_to_string:
 * @kind: a #FlatpakTransactionOperationType
 *
 * Converts the operation type to a string.
 *
 * Returns: (transfer none): a string representing @kind
 */
const char *
flatpak_transaction_operation_type_to_string (FlatpakTransactionOperationType kind)
{
  if (kind == FLATPAK_TRANSACTION_OPERATION_INSTALL)
    return "install";
  if (kind == FLATPAK_TRANSACTION_OPERATION_UPDATE)
    return "update";
  if (kind == FLATPAK_TRANSACTION_OPERATION_INSTALL_BUNDLE)
    return "install-bundle";
  if (kind == FLATPAK_TRANSACTION_OPERATION_UNINSTALL)
    return "uninstall";
  return NULL;
}

/**
 * flatpak_transaction_operation_get_bundle_path:
 * @self: a #FlatpakTransactionOperation
 *
 * Gets the path to the bundle.
 *
 * Returns: (transfer none): the bundle #GFile or %NULL
 */
GFile *
flatpak_transaction_operation_get_bundle_path (FlatpakTransactionOperation *self)
{
  return self->bundle;
}

/**
 * flatpak_transaction_operation_get_commit:
 * @self: a #FlatpakTransactionOperation
 *
 * Gets the commit ID for the operation.
 *
 * This information is available when the transaction is resolved,
 * i.e. when #FlatpakTransaction::ready is emitted.
 *
 * Returns: (transfer none): the commit ID
 */
const char *
flatpak_transaction_operation_get_commit (FlatpakTransactionOperation *self)
{
  return self->resolved_commit;
}

/**
 * flatpak_transaction_operation_get_download_size:
 * @self: a #flatpakTransactionOperation
 *
 * Gets the maximum download size for the operation.
 *
 * Note that this does not include the size of dependencies, and
 * the actual download may be smaller, if some of the data is already
 * available locally.
 *
 * For uninstall operations, this returns 0.
 *
 * This information is available when the transaction is resolved,
 * i.e. when #FlatpakTransaction::ready is emitted.
 *
 * Returns: the download size, in bytes
 * Since: 1.1.2
 */
guint64
flatpak_transaction_operation_get_download_size (FlatpakTransactionOperation *self)
{
  return self->download_size;
}

/**
 * flatpak_transaction_operation_get_installed_size:
 * @self: a #flatpakTransactionOperation
 *
 * Gets the installed size for the operation.
 *
 * Note that even for a new install, the extra space required on
 * disk may be smaller than this number, if some of the data is already
 * available locally.
 *
 * For uninstall operations, this returns 0.
 *
 * This information is available when the transaction is resolved,
 * i.e. when #FlatpakTransaction::ready is emitted.
 *
 * Returns: the installed size, in bytes
 * Since: 1.1.2
 */
guint64
flatpak_transaction_operation_get_installed_size (FlatpakTransactionOperation *self)
{
  return self->installed_size;
}

/**
 * flatpak_transaction_operation_get_metadata:
 * @self: a #FlatpakTransactionOperation
 *
 * Gets the metadata that will be applicable when the
 * operation is done.
 *
 * This can be compared to the current metadata returned
 * by flatpak_transaction_operation_get_old_metadata()
 * to find new required permissions and similar changes.
 *
 * This information is available when the transaction is resolved,
 * i.e. when #FlatpakTransaction::ready is emitted.
 *
 * Returns: (transfer none): the metadata #GKeyFile
 */
GKeyFile *
flatpak_transaction_operation_get_metadata (FlatpakTransactionOperation *self)
{
  return self->resolved_metakey;
}

/**
 * flatpak_transaction_operation_get_old_metadata:
 * @self: a #FlatpakTransactionOperation
 *
 * Gets the metadata current metadata for the ref that @self works on.
 * Also see flatpak_transaction_operation_get_metadata().
 *
 * This information is available when the transaction is resolved,
 * i.e. when #FlatpakTransaction::ready is emitted.
 *
 * Returns: (transfer none): the old metadata #GKeyFile
 */
GKeyFile *
flatpak_transaction_operation_get_old_metadata (FlatpakTransactionOperation *self)
{
  return self->resolved_old_metakey;
}

/**
 * flatpak_transaction_operation_get_subpaths:
 * @self: a #FlatpakTransactionOperation
 *
 * Gets the set of subpaths that will be pulled from this ref.
 *
 * Some refs are only partially installed, such as translations. These
 * are subset by the toplevel directory (typically by translation name).
 * The subset to install can be specified at install time, but is otherwise
 * decided based on configurations and things like the current locale and
 * how the app was previously installed.
 *
 * If there is no subsetting active, this will always return %NULL
 * (even though some other APIs also take an empty string to mean no
 * subsetting).
 *
 * This information is available when the transaction is resolved,
 * i.e. when #FlatpakTransaction::ready is emitted.
 *
 * Returns: (transfer none): the set of subpaths that will be pulled, or %NULL if no subsetting.
 * Since: 1.9.1
 */
const char * const *
flatpak_transaction_operation_get_subpaths (FlatpakTransactionOperation *self)
{
  if (self->subpaths == NULL || self->subpaths[0] == NULL)
    return NULL;

  return (const char * const *) self->subpaths;
}


/**
 * flatpak_transaction_operation_get_requires_authentication:
 * @self: a #FlatpakTransactionOperation
 *
 * Gets whether the given operation will require authentication to acquire
 * needed tokens. See also the documentation for
 * #FlatpakTransaction::ready-pre-auth.
 *
 * Returns: whether @self requires authentication
 * Since: 1.9.1
 */
gboolean
flatpak_transaction_operation_get_requires_authentication (FlatpakTransactionOperation *self)
{
  return
    op_may_need_token (self) &&
    self->token_type != 0 &&
    !self->requested_token;
}

/**
 * flatpak_transaction_is_empty:
 * @self: a #FlatpakTransaction
 *
 * Returns whether the transaction contains any non-skipped operations.
 *
 * Returns: %TRUE if the transaction is empty
 */
gboolean
flatpak_transaction_is_empty (FlatpakTransaction *self)
{
  FlatpakTransactionPrivate *priv = flatpak_transaction_get_instance_private (self);
  GList *l;

  for (l = priv->ops; l; l = l->next)
    {
      FlatpakTransactionOperation *op = l->data;

      if (!op->skip)
        return FALSE;
    }

  return TRUE;
}

static void
flatpak_transaction_finalize (GObject *object)
{
  FlatpakTransaction *self = (FlatpakTransaction *) object;
  FlatpakTransactionPrivate *priv = flatpak_transaction_get_instance_private (self);

  g_clear_object (&priv->installation);

  g_free (priv->parent_window);
  g_list_free_full (priv->flatpakrefs, (GDestroyNotify) g_key_file_unref);
  g_list_free_full (priv->bundles, (GDestroyNotify) bundle_data_free);
  g_list_free_full (priv->images, (GDestroyNotify) image_data_free);
  g_free (priv->default_arch);
  g_hash_table_unref (priv->last_op_for_ref);
  g_hash_table_unref (priv->remote_states);
  g_list_free_full (priv->ops, (GDestroyNotify) g_object_unref);
  g_clear_object (&priv->dir);

  g_ptr_array_unref (priv->added_origin_remotes);

  g_ptr_array_free (priv->extra_dependency_dirs, TRUE);
  g_ptr_array_free (priv->extra_sideload_repos, TRUE);
  g_ptr_array_free (priv->sideload_image_collections, TRUE);

  G_OBJECT_CLASS (flatpak_transaction_parent_class)->finalize (object);
}

static void
flatpak_transaction_set_property (GObject      *object,
                                  guint         prop_id,
                                  const GValue *value,
                                  GParamSpec   *pspec)
{
  FlatpakTransaction *self = FLATPAK_TRANSACTION (object);
  FlatpakTransactionPrivate *priv = flatpak_transaction_get_instance_private (self);

  switch ((FlatpakTransactionProperty) prop_id)
    {
    case PROP_INSTALLATION:
      g_clear_object (&priv->installation);
      priv->installation = g_value_dup_object (value);
      break;

    case PROP_NO_INTERACTION:
      flatpak_transaction_set_no_interaction (self, g_value_get_boolean (value));
      break;

    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
    }
}

static gboolean
signal_accumulator_false_abort (GSignalInvocationHint *ihint,
                                GValue                *return_accu,
                                const GValue          *handler_return,
                                gpointer               dummy)
{
  gboolean continue_emission;
  gboolean signal_continue;

  signal_continue = g_value_get_boolean (handler_return);
  g_value_set_boolean (return_accu, signal_continue);
  continue_emission = signal_continue;

  return continue_emission;
}

static void
flatpak_transaction_get_property (GObject    *object,
                                  guint       prop_id,
                                  GValue     *value,
                                  GParamSpec *pspec)
{
  FlatpakTransaction *self = FLATPAK_TRANSACTION (object);
  FlatpakTransactionPrivate *priv = flatpak_transaction_get_instance_private (self);

  switch ((FlatpakTransactionProperty) prop_id)
    {
    case PROP_INSTALLATION:
      g_value_set_object (value, priv->installation);
      break;

    case PROP_NO_INTERACTION:
      g_value_set_boolean (value, flatpak_transaction_get_no_interaction (self));
      break;

    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
    }
}

static gboolean
flatpak_transaction_ready (FlatpakTransaction *transaction)
{
  return TRUE;
}

static gboolean
flatpak_transaction_ready_pre_auth (FlatpakTransaction *transaction)
{
  return TRUE;
}

static gboolean
flatpak_transaction_add_new_remote (FlatpakTransaction            *transaction,
                                    FlatpakTransactionRemoteReason reason,
                                    const char                    *from_id,
                                    const char                    *suggested_remote_name,
                                    const char                    *url)
{
  return FALSE;
}

static void
flatpak_transaction_install_authenticator  (FlatpakTransaction *transaction,
                                            const char         *remote,
                                            const char         *authenticator_ref)
{
}

static gboolean flatpak_transaction_real_run (FlatpakTransaction *transaction,
                                              GCancellable       *cancellable,
                                              GError            **error);

static void
flatpak_transaction_class_init (FlatpakTransactionClass *klass)
{
  GObjectClass *object_class = G_OBJECT_CLASS (klass);

  klass->ready = flatpak_transaction_ready;
  klass->ready_pre_auth = flatpak_transaction_ready_pre_auth;
  klass->add_new_remote = flatpak_transaction_add_new_remote;
  klass->install_authenticator = flatpak_transaction_install_authenticator;
  klass->run = flatpak_transaction_real_run;
  object_class->finalize = flatpak_transaction_finalize;
  object_class->get_property = flatpak_transaction_get_property;
  object_class->set_property = flatpak_transaction_set_property;

  /**
   * FlatpakTransaction:installation:
   *
   * The installation that the transaction operates on.
   */
  g_object_class_install_property (object_class,
                                   PROP_INSTALLATION,
                                   g_param_spec_object ("installation",
                                                        "Installation",
                                                        "The installation instance",
                                                        FLATPAK_TYPE_INSTALLATION,
                                                        G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));

  /**
   * FlatpakTransaction:no-interaction:
   *
   * %TRUE if the transaction is not interactive, %FALSE otherwise.
   *
   * See flatpak_transaction_set_no_interaction().
   *
   * Since: 1.13.0
   */
  g_object_class_install_property (object_class,
                                   PROP_NO_INTERACTION,
                                   g_param_spec_boolean ("no-interaction",
                                                         "No Interaction",
                                                         "The installation instance",
                                                         FALSE,
                                                         G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_EXPLICIT_NOTIFY));

  /**
   * FlatpakTransaction::new-operation:
   * @object: A #FlatpakTransaction
   * @operation: The new #FlatpakTransactionOperation
   * @progress: A #FlatpakTransactionProgress for @operation
   *
   * The ::new-operation signal gets emitted during the execution of
   * the transaction when a new operation is beginning.
   */
  signals[NEW_OPERATION] =
    g_signal_new ("new-operation",
                  G_TYPE_FROM_CLASS (object_class),
                  G_SIGNAL_RUN_LAST,
                  G_STRUCT_OFFSET (FlatpakTransactionClass, new_operation),
                  NULL, NULL,
                  NULL,
                  G_TYPE_NONE, 2, FLATPAK_TYPE_TRANSACTION_OPERATION, FLATPAK_TYPE_TRANSACTION_PROGRESS);

  /**
   * FlatpakTransaction::operation-error:
   * @object: A #FlatpakTransaction
   * @operation: The #FlatpakTransactionOperation which failed
   * @error: A #GError
   * @details: (type FlatpakTransactionErrorDetails): A #FlatpakTransactionErrorDetails with details about the error
   *
   * The ::operation-error signal gets emitted when an error occurs during the
   * execution of the transaction.
   *
   * Returns: the %TRUE to continue transaction, %FALSE to stop
   */
  signals[OPERATION_ERROR] =
    g_signal_new ("operation-error",
                  G_TYPE_FROM_CLASS (object_class),
                  G_SIGNAL_RUN_LAST,
                  G_STRUCT_OFFSET (FlatpakTransactionClass, operation_error),
                  NULL, NULL,
                  NULL,
                  G_TYPE_BOOLEAN, 3, FLATPAK_TYPE_TRANSACTION_OPERATION, G_TYPE_ERROR, G_TYPE_INT);

  /**
   * FlatpakTransaction::operation-done:
   * @object: A #FlatpakTransaction
   * @operation: The #FlatpakTransactionOperation which finished
   * @commit: (nullable): The commit
   * @result: (type FlatpakTransactionResult): A #FlatpakTransactionResult giving details about the result
   *
   * The ::operation-done signal gets emitted during the execution of
   * the transaction when an operation is finished.
   */
  signals[OPERATION_DONE] =
    g_signal_new ("operation-done",
                  G_TYPE_FROM_CLASS (object_class),
                  G_SIGNAL_RUN_LAST,
                  G_STRUCT_OFFSET (FlatpakTransactionClass, operation_done),
                  NULL, NULL,
                  NULL,
                  G_TYPE_NONE, 3, FLATPAK_TYPE_TRANSACTION_OPERATION, G_TYPE_STRING, G_TYPE_INT);

  /**
   * FlatpakTransaction::choose-remote-for-ref:
   * @object: A #FlatpakTransaction
   * @for_ref: The ref we are installing
   * @runtime_ref: The ref we are looking for
   * @remotes: the remotes that has the ref, sorted in prio order
   *
   * The ::choose-remote-for-ref signal gets emitted when a
   * remote needs to be selected during the execution of the transaction.
   *
   * Returns: the index of the remote to use, or -1 to not pick one (and fail)
   */
  signals[CHOOSE_REMOTE_FOR_REF] =
    g_signal_new ("choose-remote-for-ref",
                  G_TYPE_FROM_CLASS (object_class),
                  G_SIGNAL_RUN_LAST,
                  G_STRUCT_OFFSET (FlatpakTransactionClass, choose_remote_for_ref),
                  NULL, NULL,
                  NULL,
                  G_TYPE_INT, 3, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRV);

  /**
   * FlatpakTransaction::end-of-lifed:
   * @object: A #FlatpakTransaction
   * @ref: The ref we are installing
   * @reason: The eol reason, or %NULL
   * @rebase: The new name, if rebased, or %NULL
   *
   * The ::end-of-lifed signal gets emitted when a ref is found to
   * be marked as end-of-life during the execution of the transaction.
   */
  signals[END_OF_LIFED] =
    g_signal_new ("end-of-lifed",
                  G_TYPE_FROM_CLASS (object_class),
                  G_SIGNAL_RUN_LAST,
                  G_STRUCT_OFFSET (FlatpakTransactionClass, end_of_lifed),
                  NULL, NULL,
                  NULL,
                  G_TYPE_NONE, 3, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);

  /**
   * FlatpakTransaction::end-of-lifed-with-rebase:
   * @object: A #FlatpakTransaction
   * @remote: The remote for the ref we are processing
   * @ref: The ref we are processing
   * @reason: The eol reason, or %NULL
   * @rebased_to_ref: The new name, if rebased, or %NULL
   * @previous_ids: The previous names for the rebased ref (if any), including the one from @ref
   *
   * The ::end-of-lifed-with-rebase signal gets emitted when a ref is found
   * to be marked as end-of-life before the transaction begins. Unlike
   * #FlatpakTransaction::end-of-lifed, this signal allows for the
   * transaction to be modified in order to e.g. install the rebased
   * ref.
   *
   * If the caller wants to install the rebased ref, they should call
   * flatpak_transaction_add_rebase_and_uninstall() on @rebased_to_ref and @ref,
   * and return %TRUE. Otherwise %FALSE may be returned.
   *
   * Returns: %TRUE if the operation on this end-of-lifed ref should
   * be skipped (e.g. because the rebased ref has been added to the
   * transaction), %FALSE if it should remain.
   *
   * Since: 1.3.2
   */
  signals[END_OF_LIFED_WITH_REBASE] =
    g_signal_new ("end-of-lifed-with-rebase",
                  G_TYPE_FROM_CLASS (object_class),
                  G_SIGNAL_RUN_LAST,
                  G_STRUCT_OFFSET (FlatpakTransactionClass, end_of_lifed_with_rebase),
                  NULL, NULL,
                  NULL,
                  G_TYPE_BOOLEAN, 5, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRV);

  /**
   * FlatpakTransaction::ready:
   * @object: A #FlatpakTransaction
   *
   * The ::ready signal is emitted when all the refs involved in the operation
   * have been resolved to commits, and the required authentication for all ops is gotten.
   * At this point flatpak_transaction_get_operations() will return all the operations
   * that will be executed as part of the transaction.
   *
   * Returns: %TRUE to carry on with the transaction, %FALSE to abort
   */
  signals[READY] =
    g_signal_new ("ready",
                  G_TYPE_FROM_CLASS (object_class),
                  G_SIGNAL_RUN_LAST,
                  G_STRUCT_OFFSET (FlatpakTransactionClass, ready),
                  signal_accumulator_false_abort, NULL,
                  NULL,
                  G_TYPE_BOOLEAN, 0);

  /**
   * FlatpakTransaction::ready-pre-auth:
   * @object: A #FlatpakTransaction
   *
   * The ::ready-pre-auth signal is emitted when all the refs involved in the
   * transaction have been resolved to commits, but we might not necessarily
   * have asked for authentication for all their required operations. This is
   * very similar to the ::ready signal, and you can choose which one (or both)
   * to use depending on how you want to handle authentication in your user
   * interface.
   *
   * At this point flatpak_transaction_get_operations() will return all the
   * operations that will be executed as part of the transaction. You can call
   * flatpak_transaction_operation_get_requires_authentication() to see which
   * will require authentication.
   *
   * Returns: %TRUE to carry on with the transaction, %FALSE to abort
   *
   * Since: 1.9.1
   */
  signals[READY_PRE_AUTH] =
    g_signal_new ("ready-pre-auth",
                  G_TYPE_FROM_CLASS (object_class),
                  G_SIGNAL_RUN_LAST,
                  G_STRUCT_OFFSET (FlatpakTransactionClass, ready_pre_auth),
                  signal_accumulator_false_abort, NULL,
                  NULL,
                  G_TYPE_BOOLEAN, 0);

  /**
   * FlatpakTransaction::add-new-remote:
   * @object: A #FlatpakTransaction
   * @reason: (type FlatpakTransactionRemoteReason): A #FlatpakTransactionRemoteReason for this suggestion
   * @from_id: The id of the app/runtime
   * @suggested_remote_name: The suggested remote name
   * @url: The repo url
   *
   * The ::add-new-remote signal gets emitted if, as part of the transaction,
   * it is required or recommended that a new remote is added, for the reason
   * described in @reason.
   *
   * Returns: %TRUE to add the remote
   */
  signals[ADD_NEW_REMOTE] =
    g_signal_new ("add-new-remote",
                  G_TYPE_FROM_CLASS (object_class),
                  G_SIGNAL_RUN_LAST,
                  G_STRUCT_OFFSET (FlatpakTransactionClass, add_new_remote),
                  g_signal_accumulator_first_wins, NULL,
                  NULL,
                  G_TYPE_BOOLEAN, 4, G_TYPE_INT, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);

  /**
   * FlatpakTransaction::install-authenticator:
   * @object: A #FlatpakTransaction
   * @remote: The remote name
   * @authenticator_ref: The ref for the authenticator
   *
   * The ::install-authenticator signal gets emitted if, as part of
   * resolving the transaction, we need to use an authenticator, but the authentication
   * is not installed, but is available to be installed from the ref.
   *
   * The application can handle this signal, and if so create another transaction
   * to install the authenticator.
   *
   * The default handler does nothing, and if the authenticator is not installed when
   * the signal handler fails the transaction will error out.
   *
   * Since: 1.8.0
   */
  signals[INSTALL_AUTHENTICATOR] =
    g_signal_new ("install-authenticator",
                  G_TYPE_FROM_CLASS (object_class),
                  G_SIGNAL_RUN_LAST,
                  G_STRUCT_OFFSET (FlatpakTransactionClass, install_authenticator),
                  NULL, NULL,
                  NULL,
                  G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_STRING);

  /**
   * FlatpakTransaction::webflow-start:
   * @object: A #FlatpakTransaction
   * @remote: The remote we're authenticating with
   * @url: The url to show
   * @options: Extra options, currently unused
   * @id: The id of the operation, can be used to cancel it
   *
   * The ::webflow-start signal gets emitted when some kind of user
   * authentication is needed during the operation. If the caller handles this
   * it should show the url in a webbrowser and return %TRUE. This will
   * eventually cause the webbrowser to finish the authentication operation and
   * operation will continue, as signaled by the webflow-done being emitted.
   *
   * If the client does not support webflow then return %FALSE from this signal
   * (or don't implement it). This will abort the authentication and likely
   * result in the transaction failing (unless the authentication was somehow
   * optional).
   *
   * During the time between webflow-start and webflow-done the client can call
   * flatpak_transaction_abort_webflow() to manually abort the authentication.
   * This is useful if the user aborted the authentication operation some way,
   * like e.g. closing the browser window.
   *
   * Since: 1.5.1
   */
  signals[WEBFLOW_START] =
    g_signal_new ("webflow-start",
                  G_TYPE_FROM_CLASS (object_class),
                  G_SIGNAL_RUN_LAST,
                  G_STRUCT_OFFSET (FlatpakTransactionClass, webflow_start),
                  NULL, NULL,
                  NULL,
                  G_TYPE_BOOLEAN, 4, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_VARIANT, G_TYPE_INT);
  /**
   * FlatpakTransaction::webflow-done:
   * @object: A #FlatpakTransaction
   * @options: Extra options, currently unused
   * @id: The id of the operation
   *
   * The ::webflow-done signal gets emitted when the authentication
   * finished the webflow, independent of the reason and results.  If
   * you for were showing a web-browser window it can now be closed.
   *
   * Since: 1.5.1
   */
  signals[WEBFLOW_DONE] =
    g_signal_new ("webflow-done",
                  G_TYPE_FROM_CLASS (object_class),
                  G_SIGNAL_RUN_LAST,
                  G_STRUCT_OFFSET (FlatpakTransactionClass, webflow_done),
                  NULL, NULL,
                  NULL,
                  G_TYPE_NONE, 2, G_TYPE_VARIANT, G_TYPE_INT);
  /**
   * FlatpakTransaction::basic-auth-start:
   * @object: A #FlatpakTransaction
   * @remote: The remote we're authenticating with
   * @realm: The url to show
   * @options: Extra options, currently unused
   * @id: The id of the operation, can be used to finish it
   *
   * The ::basic-auth-start signal gets emitted when a basic user/password
   * authentication is needed during the operation. If the caller handles this
   * it should ask the user for the user and password and return %TRUE. Once
   * the information is gathered call flatpak_transaction_complete_basic_auth()
   * with it.
   *
   * If the client does not support basic auth then return %FALSE from this signal
   * (or don't implement it). This will abort the authentication and likely
   * result in the transaction failing (unless the authentication was somehow
   * optional).
   *
   * Since: 1.5.2
   */
  signals[BASIC_AUTH_START] =
    g_signal_new ("basic-auth-start",
                  G_TYPE_FROM_CLASS (object_class),
                  G_SIGNAL_RUN_LAST,
                  G_STRUCT_OFFSET (FlatpakTransactionClass, basic_auth_start),
                  NULL, NULL,
                  NULL,
                  G_TYPE_BOOLEAN, 4, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_VARIANT, G_TYPE_INT);

}

static void
flatpak_transaction_init (FlatpakTransaction *self)
{
  FlatpakTransactionPrivate *priv = flatpak_transaction_get_instance_private (self);

  priv->last_op_for_ref = g_hash_table_new_full ((GHashFunc)flatpak_decomposed_hash, (GEqualFunc)flatpak_decomposed_equal, (GDestroyNotify) flatpak_decomposed_unref, NULL);
  priv->remote_states = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, (GDestroyNotify) flatpak_remote_state_unref);
  priv->added_origin_remotes = g_ptr_array_new_with_free_func (g_free);
  priv->extra_dependency_dirs = g_ptr_array_new_with_free_func (g_object_unref);
  priv->extra_sideload_repos = g_ptr_array_new_with_free_func (g_free);
  priv->sideload_image_collections = g_ptr_array_new_with_free_func (g_object_unref);
  priv->can_run = TRUE;
}


static gboolean
initable_init (GInitable    *initable,
               GCancellable *cancellable,
               GError      **error)
{
  FlatpakTransaction *self = FLATPAK_TRANSACTION (initable);
  FlatpakTransactionPrivate *priv = flatpak_transaction_get_instance_private (self);
  g_autoptr(FlatpakDir) dir = NULL;

  if (priv->installation == NULL)
    return flatpak_fail (error, "No installation specified");

  dir = flatpak_installation_clone_dir (priv->installation, cancellable, error);
  if (dir == NULL)
    return FALSE;

  priv->dir = g_steal_pointer (&dir);

  return TRUE;
}

static void
initable_iface_init (GInitableIface *initable_iface)
{
  initable_iface->init = initable_init;
}

/**
 * flatpak_transaction_new_for_installation:
 * @installation: a #FlatpakInstallation
 * @cancellable: (nullable): a #GCancellable
 * @error: return location for a #GError
 *
 * Creates a new #FlatpakTransaction object that can be used to do installation
 * and updates of multiple refs, as well as their dependencies, in a single
 * operation. Set the options you want on the transaction and add the
 * refs you want to install/update, then start the transaction with
 * flatpak_transaction_run ().
 *
 * Returns: (transfer full): a #FlatpakTransaction, or %NULL on failure.
 */
FlatpakTransaction *
flatpak_transaction_new_for_installation (FlatpakInstallation *installation,
                                          GCancellable        *cancellable,
                                          GError             **error)
{
  return g_initable_new (FLATPAK_TYPE_TRANSACTION,
                         cancellable, error,
                         "installation", installation,
                         NULL);
}

/**
 * flatpak_transaction_set_no_pull:
 * @self: a #FlatpakTransaction
 * @no_pull: whether to avoid pulls
 *
 * Sets whether the transaction should operate only on locally
 * available data.
 */
void
flatpak_transaction_set_no_pull (FlatpakTransaction *self,
                                 gboolean            no_pull)
{
  FlatpakTransactionPrivate *priv = flatpak_transaction_get_instance_private (self);

  priv->no_pull = no_pull;
}

/**
 * flatpak_transaction_get_no_pull:
 * @self: a #FlatpakTransaction
 *
 * Gets whether the transaction should operate only on locally
 * available data.
 *
 * Returns: %TRUE if no_pull is set, %FALSE otherwise
 *
 * Since: 1.5.1
 */
gboolean
flatpak_transaction_get_no_pull (FlatpakTransaction *self)
{
  FlatpakTransactionPrivate *priv = flatpak_transaction_get_instance_private (self);

  return priv->no_pull;
}

/**
 * flatpak_transaction_set_parent_window:
 * @self: a #FlatpakTransaction
 * @parent_window: whether to avoid pulls
 *
 * Sets the parent window (if any) to use for any UI show by this transaction.
 * This is used by authenticators if they need to interact with the user during
 * authentication.
 *
 * The format of this string depends on the display system in use, and is the
 * same as used by xdg-desktop-portal.
 *
 * On X11 it should be of the form x11:$xid where $xid is the hex
 * version of the X11 window ID.
 *
 * On wayland is should be wayland:$handle where handle is gotten by
 * using the export call of the xdg-foreign-unstable wayland extension.
 *
 * Since: 1.5.1
 */
void
flatpak_transaction_set_parent_window (FlatpakTransaction *self,
                                       const char *parent_window)
{
  FlatpakTransactionPrivate *priv = flatpak_transaction_get_instance_private (self);

  g_free (priv->parent_window);
  priv->parent_window = g_strdup (parent_window);
}

/**
 * flatpak_transaction_get_parent_window:
 * @self: a #FlatpakTransaction
 *
 * Gets the parent window set for this transaction, or %NULL if unset. See
 * flatpak_transaction_get_parent_window().
 *
 * Returns: (transfer none): a window name, or %NULL
 *
 * Since: 1.5.1
 */
const char *
flatpak_transaction_get_parent_window (FlatpakTransaction *self)
{
  FlatpakTransactionPrivate *priv = flatpak_transaction_get_instance_private (self);

  return priv->parent_window;
}

/**
 * flatpak_transaction_set_no_deploy:
 * @self: a #FlatpakTransaction
 * @no_deploy: whether to avoid deploying
 *
 * Sets whether the transaction should download updates, but
 * not deploy them.
 */
void
flatpak_transaction_set_no_deploy (FlatpakTransaction *self,
                                   gboolean            no_deploy)
{
  FlatpakTransactionPrivate *priv = flatpak_transaction_get_instance_private (self);

  priv->no_deploy = no_deploy;
}

/**
 * flatpak_transaction_get_no_deploy:
 * @self: a #FlatpakTransaction
 *
 * Gets whether the transaction is only downloading updates,
 * and not deploying them.
 *
 * Returns: %TRUE if no_deploy is set, %FALSE otherwise
 *
 * Since: 1.5.1
 */
gboolean
flatpak_transaction_get_no_deploy (FlatpakTransaction *self)
{
  FlatpakTransactionPrivate *priv = flatpak_transaction_get_instance_private (self);

  return priv->no_deploy;
}

/**
 * flatpak_transaction_set_disable_static_deltas:
 * @self: a #FlatpakTransaction
 * @disable_static_deltas: whether to avoid static deltas
 *
 * Sets whether the transaction should avoid using static
 * deltas when pulling.
 */
void
flatpak_transaction_set_disable_static_deltas (FlatpakTransaction *self,
                                               gboolean            disable_static_deltas)
{
  FlatpakTransactionPrivate *priv = flatpak_transaction_get_instance_private (self);

  priv->disable_static_deltas = disable_static_deltas;
}

/**
 * flatpak_transaction_set_disable_prune:
 * @self: a #FlatpakTransaction
 * @disable_prune: whether to avoid pruning
 *
 * Sets whether the transaction should avoid pruning the local OSTree
 * repository after updating.
 */
void
flatpak_transaction_set_disable_prune (FlatpakTransaction *self,
                                       gboolean            disable_prune)
{
  FlatpakTransactionPrivate *priv = flatpak_transaction_get_instance_private (self);

  priv->disable_prune = disable_prune;
}

/**
 * flatpak_transaction_set_disable_auto_pin:
 * @self: a #FlatpakTransaction
 * @disable_pin: whether to disable auto-pinning
 *
 * Normally the transaction pins any explicit installations so they will not
 * be automatically removed. But this can be disabled if you don't want this
 * behaviour.
 *
 * Since: 1.9.1
 */
void
flatpak_transaction_set_disable_auto_pin  (FlatpakTransaction *self,
                                           gboolean            disable_pin)
{
  FlatpakTransactionPrivate *priv = flatpak_transaction_get_instance_private (self);

  priv->disable_auto_pin = disable_pin;
}

/**
 * flatpak_transaction_set_disable_dependencies:
 * @self: a #FlatpakTransaction
 * @disable_dependencies: whether to disable runtime dependencies
 *
 * Sets whether the transaction should ignore runtime dependencies
 * when resolving operations for applications.
 */
void
flatpak_transaction_set_disable_dependencies (FlatpakTransaction *self,
                                              gboolean            disable_dependencies)
{
  FlatpakTransactionPrivate *priv = flatpak_transaction_get_instance_private (self);

  priv->disable_deps = disable_dependencies;
}

/**
 * flatpak_transaction_set_disable_related:
 * @self: a #FlatpakTransaction
 * @disable_related: whether to avoid adding related refs
 *
 * Sets whether the transaction should avoid adding related refs
 * when resolving operations. Related refs are extensions that are
 * suggested by apps, such as locales.
 */
void
flatpak_transaction_set_disable_related (FlatpakTransaction *self,
                                         gboolean            disable_related)
{
  FlatpakTransactionPrivate *priv = flatpak_transaction_get_instance_private (self);

  priv->disable_related = disable_related;
}

/**
 * flatpak_transaction_set_reinstall:
 * @self: a #FlatpakTransaction
 * @reinstall: whether to reinstall refs
 *
 * Sets whether the transaction should uninstall first if a
 * ref is already installed.
 */
void
flatpak_transaction_set_reinstall (FlatpakTransaction *self,
                                   gboolean            reinstall)
{
  FlatpakTransactionPrivate *priv = flatpak_transaction_get_instance_private (self);

  priv->reinstall = reinstall;
}

/**
 * flatpak_transaction_get_no_interaction:
 * @self: a #FlatpakTransaction
 *
 * Gets whether the transaction is interactive. See
 * flatpak_transaction_set_no_interaction().
 *
 * Returns: %TRUE if the transaction is not interactive, %FALSE otherwise
 * Since: 1.13.0
 */
gboolean
flatpak_transaction_get_no_interaction (FlatpakTransaction *self)
{
  FlatpakTransactionPrivate *priv = flatpak_transaction_get_instance_private (self);

  return flatpak_dir_get_no_interaction (priv->dir);
}

/**
 * flatpak_transaction_set_no_interaction:
 * @self: a #FlatpakTransaction
 * @no_interaction: Whether to disallow interactive authorization for operations
 *
 * This method can be used to prevent interactive authorization dialogs to appear
 * for operations on @self. This is useful for background operations that are not
 * directly triggered by a user action.
 *
 * By default, the setting from the parent #FlatpakInstallation is used.
 *
 * Since: 1.7.3
 */
void
flatpak_transaction_set_no_interaction (FlatpakTransaction *self,
                                        gboolean            no_interaction)
{
  FlatpakTransactionPrivate *priv = flatpak_transaction_get_instance_private (self);

  if (no_interaction == flatpak_transaction_get_no_interaction (self))
    return;

  flatpak_dir_set_no_interaction (priv->dir, no_interaction);
  g_object_notify (G_OBJECT (self), "no-interaction");
}

/**
 * flatpak_transaction_set_force_uninstall:
 * @self: a #FlatpakTransaction
 * @force_uninstall: whether to force-uninstall refs
 *
 * Sets whether the transaction should uninstall files even
 * if they're used by a running application.
 */
void
flatpak_transaction_set_force_uninstall (FlatpakTransaction *self,
                                         gboolean            force_uninstall)
{
  FlatpakTransactionPrivate *priv = flatpak_transaction_get_instance_private (self);

  priv->force_uninstall = force_uninstall;
}

/**
 * flatpak_transaction_set_default_arch:
 * @self: a #FlatpakTransaction
 * @arch: the arch to make default
 *
 * Sets the architecture to default to where it is unspecified.
 */
void
flatpak_transaction_set_default_arch (FlatpakTransaction *self,
                                      const char         *arch)
{
  FlatpakTransactionPrivate *priv = flatpak_transaction_get_instance_private (self);

  g_free (priv->default_arch);
  priv->default_arch = g_strdup (arch);
}

/**
 * flatpak_transaction_set_include_unused_uninstall_ops:
 * @self: a #FlatpakTransaction
 * @include_unused_uninstall_ops: whether to include unused uninstall ops
 *
 * When this is set to %TRUE, Flatpak will add uninstall operations to the
 * transaction for each runtime it considers unused. This is used by the
 * "update" CLI command to garbage collect runtimes and free disk space.
 *
 * No guarantees are made about the exact heuristic used; e.g. only end-of-life
 * unused runtimes may be uninstalled with this set. To see the full list of
 * unused runtimes in an installation, use
 * flatpak_installation_list_unused_refs().
 *
 * Since: 1.9.1
 */
void
flatpak_transaction_set_include_unused_uninstall_ops (FlatpakTransaction *self,
                                                      gboolean            include_unused_uninstall_ops)
{
  FlatpakTransactionPrivate *priv = flatpak_transaction_get_instance_private (self);

  priv->include_unused_uninstall_ops = include_unused_uninstall_ops;
}

/**
 * flatpak_transaction_get_include_unused_uninstall_ops:
 * @self: a #FlatpakTransaction
 *
 * Gets the value set by
 * flatpak_transaction_set_include_unused_uninstall_ops().
 *
 * Returns: %TRUE if include_unused_uninstall_ops is set, %FALSE otherwise
 *
 * Since: 1.9.1
 */
gboolean
flatpak_transaction_get_include_unused_uninstall_ops (FlatpakTransaction *self)
{
  FlatpakTransactionPrivate *priv = flatpak_transaction_get_instance_private (self);

  return priv->include_unused_uninstall_ops;
}

/**
 * flatpak_transaction_set_auto_install_sdk:
 * @self: a #FlatpakTransaction
 * @auto_install_sdk: whether to auto install SDKs for apps
 *
 * When this is set to %TRUE, Flatpak will automatically install the SDK for
 * each app currently being installed or updated. Does nothing if an uninstall
 * is taking place.
 *
 * Since: 1.13.3
 */
void
flatpak_transaction_set_auto_install_sdk (FlatpakTransaction *self,
                                          gboolean            auto_install_sdk)
{
  FlatpakTransactionPrivate *priv = flatpak_transaction_get_instance_private (self);

  priv->auto_install_sdk = auto_install_sdk;
}

/**
 * flatpak_transaction_get_auto_install_sdk:
 * @self: a #FlatpakTransaction
 *
 * Gets the value set by
 * flatpak_transaction_set_auto_install_sdk().
 *
 * Returns: %TRUE if auto_install_sdk is set, %FALSE otherwise
 *
 * Since: 1.13.3
 */
gboolean
flatpak_transaction_get_auto_install_sdk (FlatpakTransaction *self)
{
  FlatpakTransactionPrivate *priv = flatpak_transaction_get_instance_private (self);

  return priv->auto_install_sdk;
}

/**
 * flatpak_transaction_set_auto_install_debug:
 * @self: a #FlatpakTransaction
 * @auto_install_debug: whether to auto install debug info for apps
 *
 * When this is set to %TRUE, Flatpak will automatically install the debug info
 * for each app currently being installed or updated, as well as its
 * dependencies. Does nothing if an uninstall is taking place.
 *
 * Since: 1.13.3
 */
void
flatpak_transaction_set_auto_install_debug (FlatpakTransaction *self,
                                            gboolean            auto_install_debug)
{
  FlatpakTransactionPrivate *priv = flatpak_transaction_get_instance_private (self);

  priv->auto_install_debug = auto_install_debug;
}

/**
 * flatpak_transaction_get_auto_install_debug:
 * @self: a #FlatpakTransaction
 *
 * Gets the value set by
 * flatpak_transaction_set_auto_install_debug().
 *
 * Returns: %TRUE if auto_install_debug is set, %FALSE otherwise
 *
 * Since: 1.13.3
 */
gboolean
flatpak_transaction_get_auto_install_debug (FlatpakTransaction *self)
{
  FlatpakTransactionPrivate *priv = flatpak_transaction_get_instance_private (self);

  return priv->auto_install_debug;
}

static FlatpakTransactionOperation *
flatpak_transaction_get_last_op_for_ref (FlatpakTransaction *self,
                                         FlatpakDecomposed *ref)
{
  FlatpakTransactionPrivate *priv = flatpak_transaction_get_instance_private (self);
  FlatpakTransactionOperation *op;

  op = g_hash_table_lookup (priv->last_op_for_ref, ref);

  return op;
}

static char *
subpaths_to_string (const char **subpaths)
{
  GString *s = NULL;
  int i;

  if (subpaths == NULL)
    return g_strdup ("[$old]");

  if (*subpaths == 0)
    return g_strdup ("[*]");

  s = g_string_new ("[");
  for (i = 0; subpaths[i] != NULL; i++)
    {
      if (i != 0)
        g_string_append (s, ", ");
      g_string_append (s, subpaths[i]);
    }
  g_string_append (s, "]");

  return g_string_free (s, FALSE);
}

static const char *
kind_to_str (FlatpakTransactionOperationType kind)
{
  switch ((int) kind)
    {
    case FLATPAK_TRANSACTION_OPERATION_INSTALL:
      return "install";

    case FLATPAK_TRANSACTION_OPERATION_UPDATE:
      return "update";

    case FLATPAK_TRANSACTION_OPERATION_INSTALL_OR_UPDATE:
      return "install/update";

    case FLATPAK_TRANSACTION_OPERATION_INSTALL_BUNDLE:
      return "install bundle";

    case FLATPAK_TRANSACTION_OPERATION_UNINSTALL:
      return "uninstall";

    case FLATPAK_TRANSACTION_OPERATION_LAST_TYPE:
    default:
      return "unknown";
    }
}

FlatpakRemoteState *
flatpak_transaction_ensure_remote_state (FlatpakTransaction             *self,
                                         FlatpakTransactionOperationType kind,
                                         const char                     *remote,
                                         const char                     *opt_arch,
                                         GError                        **error)
{
  FlatpakTransactionPrivate *priv = flatpak_transaction_get_instance_private (self);
  g_autoptr(FlatpakRemoteState) state = NULL;
  FlatpakRemoteState *cached_state;

  /* We don't cache local-only states, as we might later need the same state with non-local state */
  if (transaction_is_local_only (self, kind))
    return flatpak_dir_get_remote_state_local_only (priv->dir, remote, NULL, error);

  cached_state = g_hash_table_lookup (priv->remote_states, remote);
  if (cached_state)
    state = flatpak_remote_state_ref (cached_state);
  else
    {
      state = flatpak_dir_get_remote_state_optional (priv->dir, remote, FALSE, NULL, error);
      if (state == NULL)
        return NULL;

      g_hash_table_insert (priv->remote_states, state->remote_name, flatpak_remote_state_ref (state));

      for (int i = 0; i < priv->extra_sideload_repos->len; i++)
        {
          const char *path = g_ptr_array_index (priv->extra_sideload_repos, i);
          g_autoptr(GFile) f = g_file_new_for_path (path);
          flatpak_remote_state_add_sideload_dir (state, f);
        }

      for (int i = 0; i < priv->sideload_image_collections->len; i++)
        {
          FlatpakImageCollection *collection = g_ptr_array_index (priv->sideload_image_collections, i);
          flatpak_remote_state_add_sideload_image_collection (state, collection);
        }

    }

  if (opt_arch != NULL &&
      !flatpak_remote_state_ensure_subsummary (state, priv->dir, opt_arch, FALSE, NULL, error))
    return FALSE;

  return g_steal_pointer (&state);
}

static gboolean
kind_compatible (FlatpakTransactionOperationType a,
                 FlatpakTransactionOperationType b,
                 gboolean                        b_is_rebase)
{
  if (a == b)
    return TRUE;

  if (a == FLATPAK_TRANSACTION_OPERATION_INSTALL_OR_UPDATE &&
      (b == FLATPAK_TRANSACTION_OPERATION_INSTALL ||
       b == FLATPAK_TRANSACTION_OPERATION_UPDATE))
    return TRUE;

  if (b == FLATPAK_TRANSACTION_OPERATION_INSTALL_OR_UPDATE &&
      (a == FLATPAK_TRANSACTION_OPERATION_INSTALL ||
       a == FLATPAK_TRANSACTION_OPERATION_UPDATE))
    return TRUE;

  /* If b is a rebase, the only reason it exists is so that the ref's previous-ids can be
     updated. Therefore, it can be folded into any other install or update operation. */
  if (b_is_rebase &&
      (a == FLATPAK_TRANSACTION_OPERATION_INSTALL ||
       a == FLATPAK_TRANSACTION_OPERATION_UPDATE ||
       a == FLATPAK_TRANSACTION_OPERATION_INSTALL_OR_UPDATE))
    return TRUE;

  return FALSE;
}

static FlatpakTransactionOperation *
flatpak_transaction_add_op (FlatpakTransaction             *self,
                            const char                     *remote,
                            FlatpakDecomposed              *ref,
                            const char                    **subpaths,
                            const char                    **previous_ids,
                            const char                     *commit,
                            GFile                          *bundle,
                            FlatpakTransactionOperationType kind,
                            gboolean                        pin_on_deploy,
                            gboolean                        update_preinstalled_on_deploy)
{
  FlatpakTransactionPrivate *priv = flatpak_transaction_get_instance_private (self);
  FlatpakTransactionOperation *op;
  g_autofree char *subpaths_str = NULL;

  subpaths_str = subpaths_to_string (subpaths);
  g_info ("Transaction: %s %s:%s%s%s%s",
          kind_to_str (kind), remote, flatpak_decomposed_get_ref (ref),
          commit != NULL ? "@" : "",
          commit != NULL ? commit : "",
          subpaths_str);

  op = flatpak_transaction_get_last_op_for_ref (self, ref);
  /* If previous_ids is given, then this is a rebase operation. */
  if (op != NULL && kind_compatible (kind, op->kind, previous_ids != NULL))
    {
      g_auto(GStrv) old_subpaths = NULL;
      g_auto(GStrv) old_previous_ids = NULL;

      old_subpaths = op->subpaths;
      op->subpaths = flatpak_subpaths_merge (old_subpaths, (char **) subpaths);

      old_previous_ids = op->previous_ids;
      op->previous_ids = flatpak_strv_merge (old_previous_ids, (char **) previous_ids);

      return op;
    }

  op = flatpak_transaction_operation_new (remote, ref, subpaths, previous_ids,
                                          commit, bundle, kind, pin_on_deploy,
                                          update_preinstalled_on_deploy);
  g_hash_table_insert (priv->last_op_for_ref, flatpak_decomposed_ref (ref), op);

  priv->ops = g_list_prepend (priv->ops, op);

  priv->needs_resolve = TRUE;

  return op;
}

static void
run_operation_before (FlatpakTransactionOperation *op,
                      FlatpakTransactionOperation *before_this,
                      int                          prio)
{
  if (op == before_this)
    return; /* Don't cause unnecessary loops */
  op->run_before_ops = g_list_prepend (op->run_before_ops, before_this);
  before_this->run_after_count++;
  before_this->run_after_prio = MAX (before_this->run_after_prio, prio);
}

static void
run_operation_last (FlatpakTransactionOperation *op)
{
  op->run_last = TRUE;
}

static gboolean
op_get_related (FlatpakTransaction           *self,
                FlatpakTransactionOperation  *op,
                GPtrArray                   **out_related,
                GError                      **error)
{
  FlatpakTransactionPrivate *priv = flatpak_transaction_get_instance_private (self);
  g_autoptr(FlatpakRemoteState) state = NULL;
  g_autoptr(GPtrArray) related = NULL;
  g_autoptr(GError) related_error = NULL;

  if (op->kind != FLATPAK_TRANSACTION_OPERATION_UNINSTALL)
    {
      state = flatpak_transaction_ensure_remote_state (self, op->kind, op->remote, NULL, error);
      if (state == NULL)
        return FALSE;
    }

  if (op->resolved_metakey == NULL)
    {
      g_info ("no resolved metadata for related to %s", flatpak_decomposed_get_ref (op->ref));
      return TRUE;
    }

  if (transaction_is_local_only (self, op->kind))
    related = flatpak_dir_find_local_related_for_metadata (priv->dir, op->ref,
                                                           NULL, /* remote could differ from op->remote */
                                                           op->resolved_metakey,
                                                           NULL, &related_error);
  else
    related = flatpak_dir_find_remote_related_for_metadata (priv->dir, state, op->ref,
                                                            op->resolved_metakey, NULL, &related_error);

  if (related_error != NULL)
    g_message (_("Warning: Problem looking for related refs: %s"), related_error->message);

  if (out_related)
    *out_related = g_steal_pointer (&related);

  return TRUE;
}

static gboolean
add_related (FlatpakTransaction          *self,
             FlatpakTransactionOperation *op,
             GError                     **error)
{
  FlatpakTransactionPrivate *priv = flatpak_transaction_get_instance_private (self);
  g_autoptr(GPtrArray) related = NULL;
  int i;

  if (priv->disable_related)
    return TRUE;

  if (!op_get_related (self, op, &related, error))
    return FALSE;

  if (related == NULL)
    return TRUE;

  if (op->kind == FLATPAK_TRANSACTION_OPERATION_UNINSTALL)
    {
      for (i = 0; i < related->len; i++)
        {
          FlatpakRelated *rel = g_ptr_array_index (related, i);
          FlatpakTransactionOperation *related_op;

          if (!rel->delete)
            continue;

          if (priv->no_deploy)
            {
              g_info ("Skipping uninstallation of %s for no deploy transaction",
                      flatpak_decomposed_get_ref (rel->ref));
              continue;
            }

          related_op = flatpak_transaction_add_op (self, rel->remote, rel->ref,
                                                   NULL, NULL, NULL, NULL,
                                                   FLATPAK_TRANSACTION_OPERATION_UNINSTALL,
                                                   FALSE, FALSE);
          related_op->non_fatal = TRUE;
          related_op->fail_if_op_fails = op;
          flatpak_transaction_operation_add_related_to_op (related_op, op);
          run_operation_before (op, related_op, 1);
        }
    }
  else /* install or update */
    {
      for (i = 0; i < related->len; i++)
        {
          FlatpakRelated *rel = g_ptr_array_index (related, i);
          FlatpakTransactionOperation *related_op;
          gboolean download = rel->download;

          if (!download)
            {
              g_autofree char *id = flatpak_decomposed_dup_id (rel->ref);
              if (priv->auto_install_debug && g_str_has_suffix (id, ".Debug"))
                download = TRUE;
            }

          if (!download)
            continue;

          related_op = flatpak_transaction_add_op (self, rel->remote, rel->ref,
                                                   (const char **) rel->subpaths,
                                                   NULL, NULL, NULL,
                                                   FLATPAK_TRANSACTION_OPERATION_INSTALL_OR_UPDATE,
                                                   FALSE, FALSE);
          related_op->non_fatal = TRUE;
          related_op->fail_if_op_fails = op;
          flatpak_transaction_operation_add_related_to_op (related_op, op);
          run_operation_before (related_op, op, 1);
        }
    }

  return TRUE;
}

typedef struct {
  FlatpakDir *dir;
  const char *prioritized_remote;
} RemoteSortData;

static gint
cmp_remote_with_prioritized (gconstpointer a,
                             gconstpointer b,
                             gpointer      user_data)
{
  RemoteSortData *rsd = user_data;
  FlatpakDir *self = rsd->dir;
  const char *a_name = *(const char **) a;
  const char *b_name = *(const char **) b;
  int prio_a, prio_b;

  prio_a = flatpak_dir_get_remote_prio (self, a_name);
  prio_b = flatpak_dir_get_remote_prio (self, b_name);

  /* Here we are assuming the array is already sorted by cmp_remote() and only
   * putting a particular remote at the top of its priority level */
  if (prio_b != prio_a)
    return prio_b - prio_a;
  else
    {
      if (strcmp (a_name, rsd->prioritized_remote) == 0)
        return -1;
      if (strcmp (b_name, rsd->prioritized_remote) == 0)
        return 1;
    }

  return 0;
}

static char **
search_for_dependency (FlatpakTransaction  *self,
                       char               **remotes,
                       FlatpakDecomposed   *runtime_ref,
                       GCancellable        *cancellable,
                       GError             **error)
{
  g_autoptr(GPtrArray) found = g_ptr_array_new_with_free_func (g_free);
  int i;
  g_autofree char *arch = flatpak_decomposed_dup_arch (runtime_ref);

  for (i = 0; remotes != NULL && remotes[i] != NULL; i++)
    {
      const char *remote = remotes[i];
      g_autoptr(GError) local_error = NULL;
      g_autoptr(FlatpakRemoteState) state = NULL;

      state = flatpak_transaction_ensure_remote_state (self, FLATPAK_TRANSACTION_OPERATION_INSTALL, remote, arch, &local_error);
      if (state == NULL)
        {
          g_info ("Can't get state for remote %s, ignoring: %s", remote, local_error->message);
          continue;
        }

      if (flatpak_remote_state_lookup_ref (state, flatpak_decomposed_get_ref (runtime_ref), NULL, NULL, NULL, NULL, NULL, NULL))
        g_ptr_array_add (found, g_strdup (remote));
    }

  g_ptr_array_add (found, NULL);

  return (char **) g_ptr_array_free (g_steal_pointer (&found), FALSE);
}

static char **
search_for_local_dependency (FlatpakTransaction *self,
                             char              **remotes,
                             FlatpakDecomposed  *runtime_ref,
                             GCancellable       *cancellable,
                             GError            **error)
{
  FlatpakTransactionPrivate *priv = flatpak_transaction_get_instance_private (self);
  g_autoptr(GPtrArray) found = g_ptr_array_new_with_free_func (g_free);
  int i;

  for (i = 0; remotes != NULL && remotes[i] != NULL; i++)
    {
      const char *remote = remotes[i];
      g_autofree char *commit = NULL;

      commit = flatpak_dir_read_latest (priv->dir, remote, flatpak_decomposed_get_ref (runtime_ref), NULL, NULL, NULL);
      if (commit != NULL)
        g_ptr_array_add (found, g_strdup (remote));
    }

  g_ptr_array_add (found, NULL);

  return (char **) g_ptr_array_free (g_steal_pointer (&found), FALSE);
}

static char *
find_runtime_remote (FlatpakTransaction             *self,
                     FlatpakDecomposed              *app_ref,
                     const char                     *app_remote,
                     FlatpakDecomposed              *runtime_ref,
                     FlatpakTransactionOperationType source_kind,
                     GCancellable                   *cancellable,
                     GError                        **error)
{
  FlatpakTransactionPrivate *priv = flatpak_transaction_get_instance_private (self);
  g_auto(GStrv) all_remotes = NULL;
  g_auto(GStrv) found_remotes = NULL;
  const char *app_pref;
  const char *runtime_pref;
  RemoteSortData rsd = { NULL };
  int res = -1;

  all_remotes = flatpak_dir_list_dependency_remotes (priv->dir, cancellable, error);
  if (all_remotes == NULL)
    return NULL;

  /* Put @app_remote before the others at its priority level */
  rsd.dir = priv->dir;
  rsd.prioritized_remote = app_remote;
  qsort_r (all_remotes, g_strv_length (all_remotes), sizeof (char *),
           cmp_remote_with_prioritized, &rsd);

  app_pref = flatpak_decomposed_get_pref (app_ref);
  runtime_pref = flatpak_decomposed_get_pref (runtime_ref);

  /* Here we are passing along app_remote so it gets priority */
  if (transaction_is_local_only (self, source_kind))
    found_remotes = search_for_local_dependency (self, all_remotes, runtime_ref, NULL, NULL);
  else
    found_remotes = search_for_dependency (self, all_remotes, runtime_ref, NULL, NULL);

  if (found_remotes == NULL || *found_remotes == NULL)
    {
      flatpak_fail_error (error, FLATPAK_ERROR_RUNTIME_NOT_FOUND,
                          _("The application %s requires the runtime %s which was not found"),
                          app_pref, runtime_pref);
      return NULL;
    }

  /* In the no-pull case, if only one local ref is available, assume that is the one because
     the user chose it interactively when pulling */
  if (priv->no_pull && g_strv_length (found_remotes) == 1)
    res = 0;
  else
    g_signal_emit (self, signals[CHOOSE_REMOTE_FOR_REF], 0, flatpak_decomposed_get_ref (app_ref), flatpak_decomposed_get_ref (runtime_ref), found_remotes, &res);

  if (res >= 0 && res < g_strv_length (found_remotes))
    return g_strdup (found_remotes[res]);

  flatpak_fail_error (error, FLATPAK_ERROR_RUNTIME_NOT_FOUND,
                      _("The application %s requires the runtime %s which is not installed"),
                      app_pref, runtime_pref);
  return NULL;
}

static FlatpakDecomposed *
op_get_runtime_ref (FlatpakTransactionOperation *op)
{
  g_autofree char *runtime_pref = NULL;
  FlatpakDecomposed *decomposed;

  if (!op->resolved_metakey)
    return NULL;

  /* Generally only app needs runtimes dependencies, not dependencies because you don't run extensions directly.
     However if the extension has extra data (and doesn't define NoRuntime) its also needed so we can run the
     apply-extra script. */
  if (flatpak_decomposed_is_app (op->ref))
    runtime_pref = g_key_file_get_string (op->resolved_metakey, "Application", "runtime", NULL);
  else if (g_key_file_has_group (op->resolved_metakey, "Extra Data") &&
           !g_key_file_get_boolean (op->resolved_metakey, "Extra Data", "NoRuntime", NULL))
    runtime_pref = g_key_file_get_string (op->resolved_metakey, "ExtensionOf", "runtime", NULL);

  if (runtime_pref == NULL)
    return NULL;

  decomposed = flatpak_decomposed_new_from_pref (FLATPAK_KINDS_RUNTIME, runtime_pref, NULL);
  if (decomposed == NULL)
    g_info ("Invalid runtime ref %s in metadata", runtime_pref);

  return decomposed;
}

static FlatpakDecomposed *
op_get_sdk_ref (FlatpakTransactionOperation *op)
{
  g_autofree char *sdk_pref = NULL;
  FlatpakDecomposed *decomposed;

  if (!op->resolved_metakey || !flatpak_decomposed_is_app (op->ref))
    return NULL;

  sdk_pref = g_key_file_get_string (op->resolved_metakey, "Application", "sdk", NULL);
  if (sdk_pref == NULL)
    return NULL;

  decomposed = flatpak_decomposed_new_from_pref (FLATPAK_KINDS_RUNTIME, sdk_pref, NULL);
  if (decomposed == NULL)
    g_info ("Invalid runtime ref %s in metadata", sdk_pref);

  return decomposed;
}

static gboolean
add_new_dep_op (FlatpakTransaction           *self,
                FlatpakTransactionOperation  *op,
                FlatpakDecomposed            *dep_ref,
                FlatpakTransactionOperation **dep_op,
                GError                      **error)
{
  FlatpakTransactionPrivate *priv = flatpak_transaction_get_instance_private (self);
  g_autofree char *dep_remote = NULL;

  if (!ref_is_installed (self, dep_ref))
    {
      g_info ("Installing dependency %s of %s", flatpak_decomposed_get_pref (dep_ref),
              flatpak_decomposed_get_pref (op->ref));
      dep_remote = find_runtime_remote (self, op->ref, op->remote, dep_ref, op->kind, NULL, error);
      if (dep_remote == NULL)
        return FALSE;

      *dep_op = flatpak_transaction_add_op (self, dep_remote, dep_ref, NULL, NULL, NULL, NULL,
                                            FLATPAK_TRANSACTION_OPERATION_INSTALL_OR_UPDATE, FALSE, FALSE);
    }
  else
    {
      /* Update if in same dir */
      if (dir_ref_is_installed (priv->dir, dep_ref, &dep_remote, NULL))
        {
          g_info ("Updating dependency %s of %s", flatpak_decomposed_get_pref (dep_ref),
                  flatpak_decomposed_get_pref (op->ref));
          *dep_op = flatpak_transaction_add_op (self, dep_remote, dep_ref, NULL, NULL, NULL, NULL,
                                                FLATPAK_TRANSACTION_OPERATION_UPDATE, FALSE, FALSE);
          (*dep_op)->non_fatal = TRUE;
        }
    }

  return TRUE;
}

static gboolean
add_deps (FlatpakTransaction          *self,
          FlatpakTransactionOperation *op,
          GError                     **error)
{
  FlatpakTransactionPrivate *priv = flatpak_transaction_get_instance_private (self);
  g_autoptr(FlatpakDecomposed) runtime_ref = NULL;
  FlatpakTransactionOperation *runtime_op = NULL;

  if (!op->resolved_metakey)
    return TRUE;

  runtime_ref = op_get_runtime_ref (op);
  if (runtime_ref == NULL)
    return TRUE;

  runtime_op = flatpak_transaction_get_last_op_for_ref (self, runtime_ref);

  if (op->kind == FLATPAK_TRANSACTION_OPERATION_UNINSTALL)
    {
      /* If the runtime this app uses is already to be uninstalled, then this uninstall must happen before
         the runtime is uninstalled */
      if (runtime_op && runtime_op->kind == FLATPAK_TRANSACTION_OPERATION_UNINSTALL)
        run_operation_before (op, runtime_op, 1);

      return TRUE;
    }

  if (priv->disable_deps)
    return TRUE;

  if (runtime_op == NULL)
    {
      if (!add_new_dep_op (self, op, runtime_ref, &runtime_op, error))
        return FALSE;
    }

  /* Install/Update the runtime before the app */
  if (runtime_op)
    {
      if (runtime_op->kind == FLATPAK_TRANSACTION_OPERATION_UNINSTALL)
        return flatpak_fail_error (error, FLATPAK_ERROR_RUNTIME_USED,
                                   _("Can't uninstall %s which is needed by %s"),
                                   flatpak_decomposed_get_pref (runtime_op->ref), flatpak_decomposed_get_pref (op->ref));

      op->fail_if_op_fails = runtime_op;
      flatpak_transaction_operation_add_related_to_op (runtime_op, op);
      run_operation_before (runtime_op, op, 2);
    }

  if (priv->auto_install_sdk)
    {
      g_autoptr(FlatpakDecomposed) sdk_ref = NULL;

      sdk_ref = op_get_sdk_ref (op);
      if (sdk_ref != NULL)
        {
          FlatpakTransactionOperation *sdk_op = flatpak_transaction_get_last_op_for_ref (self, sdk_ref);
          if (sdk_op == NULL)
            {
              if (!add_new_dep_op (self, op, sdk_ref, &sdk_op, error))
                return FALSE;
            }

          if (sdk_op && sdk_op->kind != FLATPAK_TRANSACTION_OPERATION_UNINSTALL)
            {
              flatpak_transaction_operation_add_related_to_op (sdk_op, op);
              run_operation_before (sdk_op, op, 2);
            }
        }
    }

  return TRUE;
}

/* @out_op may return %NULL even when this function returns %TRUE. It’s (transfer none). */
static gboolean
flatpak_transaction_add_ref (FlatpakTransaction             *self,
                             const char                     *remote,
                             FlatpakDecomposed              *ref,
                             const char                    **subpaths,
                             const char                    **previous_ids,
                             const char                     *commit,
                             FlatpakTransactionOperationType kind,
                             GFile                          *bundle,
                             FlatpakImageSource             *image_source,
                             const char                     *external_metadata,
                             gboolean                        pin_on_deploy,
                             gboolean                        update_preinstalled_on_deploy,
                             FlatpakTransactionOperation   **out_op,
                             GError                        **error)
{
  FlatpakTransactionPrivate *priv = flatpak_transaction_get_instance_private (self);
  g_autofree char *origin = NULL;
  g_auto(GStrv) new_subpaths = NULL;
  const char *pref;
  g_autofree char *origin_remote = NULL;
  g_autoptr(FlatpakRemoteState) state = NULL;
  FlatpakTransactionOperation *op;

  if (out_op != NULL)
    *out_op = NULL;

  if (remote_name_is_file (remote))
    {
      gboolean changed_config;
      g_autofree char *id = flatpak_decomposed_dup_id (ref);
      origin_remote = flatpak_dir_create_origin_remote (priv->dir,
                                                        remote, /* uri */
                                                        id,
                                                        "Local repo",
                                                        flatpak_decomposed_get_ref (ref),
                                                        NULL,
                                                        NULL,
                                                        &changed_config,
                                                        NULL, error);
      if (origin_remote == NULL)
        return FALSE;

      /* Reload changed configuration */
      if (changed_config)
        flatpak_installation_drop_caches (priv->installation, NULL, NULL);

      g_ptr_array_add (priv->added_origin_remotes, g_strdup (origin_remote));

      remote = origin_remote;
    }

  pref = flatpak_decomposed_get_pref (ref);

  /* install or update */
  if (kind == FLATPAK_TRANSACTION_OPERATION_UPDATE)
    {
      g_autoptr(GBytes) deploy_data = NULL;

      if (!dir_ref_is_installed (priv->dir, ref, &origin, &deploy_data))
        return flatpak_fail_error (error, FLATPAK_ERROR_NOT_INSTALLED,
                                   _("%s not installed"), pref);

      if (flatpak_dir_get_remote_disabled (priv->dir, origin))
        {
          g_info (_("Remote %s disabled, ignoring %s update"), origin, pref);
          return TRUE;
        }
      remote = origin;

      if (subpaths == NULL)
        {
          g_autofree const char **old_subpaths = flatpak_deploy_data_get_subpaths (deploy_data);

          /* As stated in the documentation for flatpak_transaction_add_update(),
           * for locale extensions we merge existing subpaths with the set of
           * configured languages, to match the behavior of add_related().
           */
          if (flatpak_decomposed_id_has_suffix (ref, ".Locale"))
            {
              g_auto(GStrv) extra_subpaths = flatpak_dir_get_locale_subpaths (priv->dir);
              new_subpaths = flatpak_subpaths_merge ((char **)old_subpaths, extra_subpaths);
            }
          else
            {
              /* Otherwise we resolve to the current subpaths here so we can know in operation-done what subpaths will be pulled */
              new_subpaths = g_strdupv ((char **)old_subpaths);
            }
          subpaths = (const char **)new_subpaths;
        }
    }
  else if (kind == FLATPAK_TRANSACTION_OPERATION_INSTALL)
    {
      if (!priv->reinstall &&
          dir_ref_is_installed (priv->dir, ref, &origin, NULL))
        {
          if (g_strcmp0 (remote, origin) == 0)
            return flatpak_fail_error (error, FLATPAK_ERROR_ALREADY_INSTALLED,
                                       _("%s is already installed"), pref);
          else
            return flatpak_fail_error (error, FLATPAK_ERROR_DIFFERENT_REMOTE,
                                       _("%s is already installed from remote %s"),
                                       pref, origin);
        }
    }
  else if (kind == FLATPAK_TRANSACTION_OPERATION_UNINSTALL)
    {
      /* Skip uninstall for no deploy transactions. */
      if (priv->no_deploy)
        {
          g_info ("Skipping uninstallation of %s for no deploy transaction", pref);
          return TRUE;
        }

      if (!dir_ref_is_installed (priv->dir, ref, &origin, NULL))
        return flatpak_fail_error (error, FLATPAK_ERROR_NOT_INSTALLED,
                                   _("%s not installed"), pref);

      remote = origin;
    }

  /* This should have been passed in or found out above */
  g_assert (remote != NULL);

  /* We don't need remote state for an uninstall, and we don't want a missing
   * remote to be fatal */
  if (kind != FLATPAK_TRANSACTION_OPERATION_UNINSTALL)
    {
      g_autofree char *arch = flatpak_decomposed_dup_arch (ref);

      state = flatpak_transaction_ensure_remote_state (self, kind, remote, arch, error);
      if (state == NULL)
        return FALSE;
    }

  op = flatpak_transaction_add_op (self, remote, ref, subpaths, previous_ids,
                                   commit, bundle, kind, pin_on_deploy,
                                   update_preinstalled_on_deploy);

  if (image_source)
    op->image_source = g_object_ref (image_source);

  if (external_metadata)
    op->external_metadata = g_bytes_new (external_metadata, strlen (external_metadata));

  if (out_op != NULL)
    *out_op = op;

  return TRUE;
}

/**
 * flatpak_transaction_add_install:
 * @self: a #FlatpakTransaction
 * @remote: the name of the remote
 * @ref: the ref
 * @subpaths: (nullable) (array zero-terminated=1): subpaths to install, or the
 *  empty list or %NULL to pull all subpaths
 * @error: return location for a #GError
 *
 * Adds installing the given ref to this transaction.
 *
 * The @remote can either be a configured remote of the installation,
 * or a file:// uri pointing at a local repository to install from,
 * in which case an origin remote is created.
 *
 * Returns: %TRUE on success; %FALSE with @error set on failure.
 */
gboolean
flatpak_transaction_add_install (FlatpakTransaction *self,
                                 const char         *remote,
                                 const char         *ref,
                                 const char        **subpaths,
                                 GError            **error)
{
  FlatpakTransactionPrivate *priv = flatpak_transaction_get_instance_private (self);
  g_autoptr(FlatpakDecomposed) decomposed = NULL;
  const char *all_paths[] = { NULL };
  gboolean pin_on_deploy;

  g_return_val_if_fail (ref != NULL, FALSE);
  g_return_val_if_fail (remote != NULL, FALSE);

  decomposed = flatpak_decomposed_new_from_ref (ref, error);
  if (decomposed == NULL)
    return FALSE;

  /* If we install with no special args pull all subpaths */
  if (subpaths == NULL)
    subpaths = all_paths;

  pin_on_deploy = flatpak_decomposed_is_runtime (decomposed) && !priv->disable_auto_pin;

  if (!flatpak_transaction_add_ref (self, remote, decomposed, subpaths, NULL, NULL,
                                    FLATPAK_TRANSACTION_OPERATION_INSTALL,
                                    NULL, NULL, NULL, pin_on_deploy, FALSE, NULL, error))
    return FALSE;

  return TRUE;
}

/**
 * flatpak_transaction_add_rebase:
 * @self: a #FlatpakTransaction
 * @remote: the name of the remote
 * @ref: the ref
 * @subpaths: (nullable): the subpaths to include, or %NULL to install the complete ref
 * @previous_ids: (nullable) (array zero-terminated=1): Previous ids to add to the
 *     given ref. These should simply be the ids, not the full ref names (e.g. org.foo.Bar,
 *     not org.foo.Bar/x86_64/master).
 * @error: return location for a #GError
 *
 * Adds updating the @previous_ids of the given ref to this transaction, via either
 * installing the @ref if it was not already present or updating it. This will
 * treat @ref as the result of following an eol-rebase, and data migration from
 * the refs in @previous_ids will be set up.
 *
 * If you want to rebase the ref and uninstall the old version of it, consider
 * using flatpak_transaction_add_rebase_and_uninstall() instead. It will add
 * appropriate dependencies between the rebase and uninstall operations.
 *
 * See flatpak_transaction_add_install() for a description of @remote.
 *
 * Returns: %TRUE on success; %FALSE with @error set on failure.
 * Since: 1.3.3.
 */
gboolean
flatpak_transaction_add_rebase (FlatpakTransaction *self,
                                const char         *remote,
                                const char         *ref,
                                const char        **subpaths,
                                const char        **previous_ids,
                                GError            **error)
{
  FlatpakTransactionPrivate *priv = flatpak_transaction_get_instance_private (self);
  const char *all_paths[] = { NULL };
  g_autoptr(FlatpakDecomposed) decomposed = NULL;
  g_autofree char *installed_origin = NULL;

  g_return_val_if_fail (ref != NULL, FALSE);
  g_return_val_if_fail (remote != NULL, FALSE);
  /* flatpak_transaction_add_rebase without previous_ids doesn't make sense */
  g_return_val_if_fail (previous_ids != NULL, FALSE);

  decomposed = flatpak_decomposed_new_from_ref (ref, error);
  if (decomposed == NULL)
    return FALSE;

  /* If we install with no special args pull all subpaths */
  if (subpaths == NULL)
    subpaths = all_paths;

  if (dir_ref_is_installed (priv->dir, decomposed, &installed_origin, NULL))
    remote = installed_origin;

  return flatpak_transaction_add_ref (self, remote, decomposed, subpaths, previous_ids, NULL,
                                      FLATPAK_TRANSACTION_OPERATION_INSTALL_OR_UPDATE,
                                      NULL, NULL, NULL, FALSE, FALSE, NULL, error);
}

/**
 * flatpak_transaction_add_rebase_and_uninstall:
 * @self: a #FlatpakTransaction
 * @remote: the name of the remote
 * @new_ref: the ref to rebase to
 * @old_ref: the ref to uninstall
 * @subpaths: (nullable): the subpaths to include, or %NULL to install the complete ref
 * @previous_ids: (nullable) (array zero-terminated=1): Previous ids to add to the
 *     given ref. These should simply be the ids, not the full ref names (e.g. org.foo.Bar,
 *     not org.foo.Bar/x86_64/master).
 * @error: return location for a #GError
 *
 * Adds updating the @previous_ids of the given @new_ref to this transaction,
 * via either installing the @new_ref if it was not already present or updating
 * it. This will treat @new_ref as the result of following an eol-rebase, and
 * data migration from the refs in @previous_ids will be set up.
 *
 * Also adds an operation to uninstall @old_ref to this transaction. This
 * operation will only be run if the operation to install/update @new_ref
 * succeeds.
 *
 * If @old_ref is not already installed (which can happen if requesting to
 * install an EOLed app, rather than update one which is already installed), the
 * uninstall operation will silently not be added, and this function will behave
 * similarly to flatpak_transaction_add_rebase().
 *
 * See flatpak_transaction_add_install() for a description of @remote.
 *
 * Returns: %TRUE on success; %FALSE with @error set on failure.
 * Since: 1.15.4
 */
gboolean
flatpak_transaction_add_rebase_and_uninstall (FlatpakTransaction  *self,
                                              const char          *remote,
                                              const char          *new_ref,
                                              const char          *old_ref,
                                              const char         **subpaths,
                                              const char         **previous_ids,
                                              GError             **error)
{
  FlatpakTransactionPrivate *priv = flatpak_transaction_get_instance_private (self);
  const char *all_paths[] = { NULL };
  g_autoptr(FlatpakDecomposed) old_decomposed = NULL;
  g_autoptr(FlatpakDecomposed) new_decomposed = NULL;
  g_autofree char *installed_origin = NULL;
  g_autoptr(GError) local_error = NULL;
  FlatpakTransactionOperation *rebase_op = NULL, *uninstall_op = NULL;

  g_return_val_if_fail (new_ref != NULL, FALSE);
  g_return_val_if_fail (old_ref != NULL, FALSE);
  g_return_val_if_fail (remote != NULL, FALSE);
  /* flatpak_transaction_add_rebase_and_uninstall() without previous_ids doesn't make sense */
  g_return_val_if_fail (previous_ids != NULL, FALSE);

  new_decomposed = flatpak_decomposed_new_from_ref (new_ref, error);
  if (new_decomposed == NULL)
    return FALSE;

  old_decomposed = flatpak_decomposed_new_from_ref (old_ref, error);
  if (old_decomposed == NULL)
    return FALSE;

  /* If we install with no special args pull all subpaths */
  if (subpaths == NULL)
    subpaths = all_paths;

  if (dir_ref_is_installed (priv->dir, new_decomposed, &installed_origin, NULL))
    remote = installed_origin;

  /* Add the install/update and uninstall ops. */
  if (!flatpak_transaction_add_ref (self, remote, new_decomposed, subpaths,
                                    previous_ids, NULL,
                                    FLATPAK_TRANSACTION_OPERATION_INSTALL_OR_UPDATE,
                                    NULL, NULL, NULL, FALSE, FALSE, &rebase_op, error))
    return FALSE;

  if (!flatpak_transaction_add_ref (self, NULL, old_decomposed, NULL, NULL, NULL,
                                    FLATPAK_TRANSACTION_OPERATION_UNINSTALL,
                                    NULL, NULL, NULL, FALSE, FALSE, &uninstall_op, &local_error))
    {
      /* If the user is trying to install an eol-rebased app from scratch, the
       * @old_ref can’t be uninstalled because it’s not installed already.
       * Silently ignore that. */
      if (!g_error_matches (local_error, FLATPAK_ERROR, FLATPAK_ERROR_NOT_INSTALLED))
        {
          g_propagate_error (error, g_steal_pointer (&local_error));
          return FALSE;
        }
      g_clear_error (&local_error);
    }

  /* Link the ops together so that the install/update is done first, and if
   * that fails then the uninstall is skipped. @uninstall_op might be %NULL even
   * if the flatpak_transaction_add_ref() call succeeded above, as this might be
   * a no-deploy transaction. */
  if (uninstall_op != NULL)
    {
      uninstall_op->non_fatal = TRUE;
      uninstall_op->fail_if_op_fails = rebase_op;
      flatpak_transaction_operation_add_related_to_op (uninstall_op, rebase_op);
      run_operation_before (rebase_op, uninstall_op, 1);
    }

  return TRUE;
}

/**
 * flatpak_transaction_add_install_bundle:
 * @self: a #FlatpakTransaction
 * @file: a #GFile that is an flatpak bundle
 * @gpg_data: (nullable): GPG key with which to check bundle signatures, or
 *  %NULL to use the key embedded in the bundle (if any)
 * @error: return location for a #GError
 *
 * Adds installing the given bundle to this transaction.
 *
 * Returns: %TRUE on success; %FALSE with @error set on failure.
 */
gboolean
flatpak_transaction_add_install_bundle (FlatpakTransaction *self,
                                        GFile              *file,
                                        GBytes             *gpg_data,
                                        GError            **error)
{
  FlatpakTransactionPrivate *priv = flatpak_transaction_get_instance_private (self);

  priv->bundles = g_list_append (priv->bundles, bundle_data_new (file, gpg_data));

  return TRUE;
}

/**
 * flatpak_transaction_add_install_image:
 * @self: a #FlatpakTransaction
 * @image_location: (nullable): location string to install from.
 * @error: return location for a #GError
 *
 * Install a Flatpak from a container image. The image is specified
 *
 * If the reference from the image was previously installed, then
 * that remote will be used as the remote for the newly installed image. If the
 * reference was not previously installed, then a remote will be created for the
 * reference.
 *
 * @image_location is specified in containers-transports(5) form. Only a subset
 * of transports are supported: oci:, oci-archive:, and docker:.
 *
 * Returns: %TRUE on success; %FALSE with @error set on failure.
 */
gboolean
flatpak_transaction_add_install_image (FlatpakTransaction *self,
                                       const char         *image_location,
                                       GError            **error)
{
  FlatpakTransactionPrivate *priv = flatpak_transaction_get_instance_private (self);

  priv->images = g_list_append (priv->images, image_data_new (image_location));

  return TRUE;
}

/**
 * flatpak_transaction_add_install_flatpakref:
 * @self: a #FlatpakTransaction
 * @flatpakref_data: data from a flatpakref file
 * @error: return location for a #GError
 *
 * Adds installing the given flatpakref to this transaction.
 *
 * Returns: %TRUE on success; %FALSE with @error set on failure.
 */
gboolean
flatpak_transaction_add_install_flatpakref (FlatpakTransaction *self,
                                            GBytes             *flatpakref_data,
                                            GError            **error)
{
  FlatpakTransactionPrivate *priv = flatpak_transaction_get_instance_private (self);
  g_autoptr(GKeyFile) keyfile = g_key_file_new ();
  g_autoptr(GError) local_error = NULL;

  g_return_val_if_fail (flatpakref_data != NULL, FALSE);

  if (!g_key_file_load_from_data (keyfile, g_bytes_get_data (flatpakref_data, NULL),
                                  g_bytes_get_size (flatpakref_data),
                                  0, &local_error))
    return flatpak_fail_error (error, FLATPAK_ERROR_INVALID_DATA, _("Invalid .flatpakref: %s"), local_error->message);

  priv->flatpakrefs = g_list_append (priv->flatpakrefs, g_steal_pointer (&keyfile));

  return TRUE;
}

/**
 * flatpak_transaction_add_sync_preinstalled:
 * @self: a #FlatpakTransaction
 * @error: return location for a #GError
 *
 * Adds preinstall operations to this transaction. This can involve both
 * installing and removing refs, based on /etc/preinstall.d contents and what
 * the system had preinstalled before.
 *
 * Returns: %TRUE on success; %FALSE with @error set on failure.
 */
gboolean
flatpak_transaction_add_sync_preinstalled (FlatpakTransaction *self,
                                           GError            **error)
{
  FlatpakTransactionPrivate *priv = flatpak_transaction_get_instance_private (self);
  g_autoptr(GPtrArray) install_refs = g_ptr_array_new_with_free_func (g_free);
  g_autoptr(GPtrArray) preinstalled_refs = NULL;
  g_auto(GStrv) remotes = NULL;
  g_autoptr(GPtrArray) configs = NULL;

  remotes = flatpak_dir_list_remotes (priv->dir, NULL, error);
  if (remotes == NULL)
    return FALSE;

  configs = flatpak_get_preinstall_config (priv->default_arch, NULL, error);
  if (configs == NULL)
    return FALSE;

  /* If the system has not had any apps pre-installed (i.e. the key in the
   * config is missing) we mark all installed apps we would pre-install as
   * pre-installed. This makes sure we will uninstall them when the config says
   * that they no longer should be installed. */
  if (!flatpak_dir_uninitialized_mark_preinstalled (priv->dir, configs, NULL))
    g_message (_("Warning: Could not mark already installed apps as preinstalled"));

  preinstalled_refs = flatpak_dir_get_config_patterns (priv->dir, "preinstalled");

  /* Find preinstalls that should get installed */
  for (int i = 0; i < configs->len; i++)
    {
      const FlatpakPreinstallConfig *config = g_ptr_array_index (configs, i);

      /* Store for later */
      g_ptr_array_add (install_refs, flatpak_decomposed_dup_ref (config->ref));

      /* Skip over if it's listed as previously preinstalled - it's now under
       * user's control and we no longer install it again, even if the user
       * manually removes it. */
      if (!priv->reinstall &&
          flatpak_g_ptr_array_contains_string (preinstalled_refs,
                                               flatpak_decomposed_get_ref (config->ref)))
        {
          g_info ("Preinstall ref %s is marked as already preinstalled; skipping",
                  flatpak_decomposed_get_ref (config->ref));
          continue;
        }

      for (int j = 0; remotes[j] != NULL; j++)
        {
          const char *remote = remotes[j];
          g_autoptr(FlatpakRemoteState) state = NULL;
          g_autofree char *remote_collection_id = NULL;
          g_autoptr(GError) local_error = NULL;

          if (flatpak_dir_get_remote_disabled (priv->dir, remote))
            continue;

          remote_collection_id = flatpak_dir_get_remote_collection_id (priv->dir,
                                                                       remote);

          if (config->collection_id != NULL &&
              g_strcmp0 (remote_collection_id, config->collection_id) != 0)
            continue;

          state = flatpak_transaction_ensure_remote_state (self,
                                                           FLATPAK_TRANSACTION_OPERATION_INSTALL,
                                                           remote,
                                                           priv->default_arch,
                                                           &local_error);
          if (state == NULL)
            {
              g_warning ("Checking if preinstall ref %s is in remote %s failed: %s",
                         flatpak_decomposed_get_ref (config->ref),
                         remote,
                         local_error->message);
              continue;
            }

          if (!flatpak_remote_state_lookup_ref (state,
                                                flatpak_decomposed_get_ref (config->ref),
                                                NULL, NULL, NULL, NULL, NULL, NULL))
            continue;

          g_info ("Adding preinstall of %s from remote %s",
                  flatpak_decomposed_get_ref (config->ref),
                  remote);

          if (!flatpak_transaction_add_ref (self, remote, config->ref, NULL, NULL, NULL,
                                            FLATPAK_TRANSACTION_OPERATION_INSTALL,
                                            NULL, NULL, NULL, FALSE, TRUE, NULL,
                                            &local_error))
            {
              g_info ("Failed to add preinstall ref %s: %s",
                      flatpak_decomposed_get_ref (config->ref),
                      local_error->message);
            }
        }
    }

  /* Find previously preinstalled refs that are no longer in the preinstall
   * list and should now get uninstalled */
  for (int i = 0; i < preinstalled_refs->len; i++)
    {
      const char *ref = g_ptr_array_index (preinstalled_refs, i);

      /* No longer in the preinstall.d list, so uninstall */
      if (!flatpak_g_ptr_array_contains_string (install_refs, ref))
        {
          g_autoptr(GError) local_error = NULL;
          g_autoptr(FlatpakDecomposed) decomposed = NULL;

          decomposed = flatpak_decomposed_new_from_ref (ref, error);
          if (decomposed == NULL)
            return FALSE;

          g_info ("Preinstalled ref %s is no longer listed as wanted in preinstall.d config; uninstalling",
                  flatpak_decomposed_get_ref (decomposed));

          if (!flatpak_transaction_add_ref (self, NULL, decomposed, NULL, NULL, NULL,
                                            FLATPAK_TRANSACTION_OPERATION_UNINSTALL,
                                            NULL, NULL, NULL, FALSE, TRUE, NULL,
                                            &local_error))
            {
              if (!g_error_matches (local_error, FLATPAK_ERROR, FLATPAK_ERROR_NOT_INSTALLED))
                {
                  g_propagate_error (error, g_steal_pointer (&local_error));
                  return FALSE;
                }
              g_clear_error (&local_error);
            }
        }
    }

  return TRUE;
}

/**
 * flatpak_transaction_add_update:
 * @self: a #FlatpakTransaction
 * @ref: the ref
 * @subpaths: (nullable) (array zero-terminated=1): subpaths to install; %NULL
 *  to use the current set plus the set of configured languages, or
 *  `{ NULL }` or `{ "", NULL }` to pull all subpaths.
 * @commit: (nullable): the commit to update to, or %NULL to use the latest
 * @error: return location for a #GError
 *
 * Adds updating the given ref to this transaction.
 *
 * Returns: %TRUE on success; %FALSE with @error set on failure.
 */
gboolean
flatpak_transaction_add_update (FlatpakTransaction *self,
                                const char         *ref,
                                const char        **subpaths,
                                const char         *commit,
                                GError            **error)
{
  const char *all_paths[] = { NULL };
  g_autoptr(FlatpakDecomposed) decomposed = NULL;

  g_return_val_if_fail (ref != NULL, FALSE);

  /* If specify an empty subpath, that means all subpaths */
  if (subpaths != NULL && subpaths[0] != NULL && subpaths[0][0] == 0)
    subpaths = all_paths;

  decomposed = flatpak_decomposed_new_from_ref (ref, error);
  if (decomposed == NULL)
    return FALSE;

  /* Note: we implement the merge when subpaths == NULL in flatpak_transaction_add_ref() */
  return flatpak_transaction_add_ref (self, NULL, decomposed, subpaths, NULL, commit, FLATPAK_TRANSACTION_OPERATION_UPDATE, NULL, NULL, NULL, FALSE, FALSE, NULL, error);
}

/**
 * flatpak_transaction_add_uninstall:
 * @self: a #FlatpakTransaction
 * @ref: the ref
 * @error: return location for a #GError
 *
 * Adds uninstalling the given ref to this transaction. If the transaction is
 * set to not deploy updates, the request is ignored.
 *
 * Returns: %TRUE on success; %FALSE with @error set on failure.
 */
gboolean
flatpak_transaction_add_uninstall (FlatpakTransaction *self,
                                   const char         *ref,
                                   GError            **error)
{
  g_autoptr(FlatpakDecomposed) decomposed = NULL;

  g_return_val_if_fail (ref != NULL, FALSE);

  decomposed = flatpak_decomposed_new_from_ref (ref, error);
  if (decomposed == NULL)
    return FALSE;

  return flatpak_transaction_add_ref (self, NULL, decomposed, NULL, NULL, NULL, FLATPAK_TRANSACTION_OPERATION_UNINSTALL, NULL, NULL, NULL, FALSE, FALSE, NULL, error);
}

static gboolean
flatpak_transaction_update_metadata (FlatpakTransaction *self,
                                     GCancellable       *cancellable,
                                     GError            **error)
{
  FlatpakTransactionPrivate *priv = flatpak_transaction_get_instance_private (self);
  g_auto(GStrv) remotes = NULL;
  int i;
  GList *l;
  gboolean some_updated = FALSE;
  g_autoptr(GHashTable) ht = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
  gboolean local_only = TRUE;

  /* Collect all dir+remotes used in this transaction */

  if (!flatpak_dir_migrate_config (priv->dir, &some_updated, cancellable, error))
    return FALSE;

  for (l = priv->ops; l != NULL; l = l->next)
    {
      FlatpakTransactionOperation *op = l->data;
      if (!g_hash_table_contains (ht, op->remote))
        g_hash_table_add (ht, g_strdup (op->remote));
      local_only = local_only && transaction_is_local_only (self, op->kind);
    }
  remotes = (char **) g_hash_table_get_keys_as_array (ht, NULL);
  g_hash_table_steal_all (ht); /* Move ownership to remotes */

  /* Bail early if the entire transaction is local-only, as in that case we
   * don’t need updated metadata. */
  if (local_only)
    return TRUE;

  /* Update metadata for said remotes */
  for (i = 0; remotes[i] != NULL; i++)
    {
      char *remote = remotes[i];
      gboolean updated = FALSE;
      g_autoptr(GError) my_error = NULL;
      g_autoptr(FlatpakRemoteState) state = flatpak_transaction_ensure_remote_state (self, FLATPAK_TRANSACTION_OPERATION_UPDATE, remote, NULL, NULL);

      g_info ("Looking for remote metadata updates for %s", remote);
      if (!flatpak_dir_update_remote_configuration (priv->dir, remote, state, &updated, cancellable, &my_error))
        g_info (_("Error updating remote metadata for '%s': %s"), remote, my_error->message);

      if (updated)
        {
          g_info ("Got updated metadata for %s", remote);
          some_updated = TRUE;
        }
    }

  if (some_updated)
    {
      /* Reload changed configuration */
      if (!flatpak_dir_recreate_repo (priv->dir, cancellable, error))
        return FALSE;

      flatpak_installation_drop_caches (priv->installation, NULL, NULL);

      /* These are potentially out of date now */
      g_hash_table_remove_all (priv->remote_states);
    }

  return TRUE;
}

static gboolean
flatpak_transaction_add_auto_install (FlatpakTransaction *self,
                                      GCancellable       *cancellable,
                                      GError            **error)
{
  FlatpakTransactionPrivate *priv = flatpak_transaction_get_instance_private (self);
  g_auto(GStrv) remotes = NULL;

  remotes = flatpak_dir_list_remotes (priv->dir, cancellable, error);
  if (remotes == NULL)
    return FALSE;

  /* Auto-add auto-download apps that are not already installed.
   * Try to avoid doing network i/o until we know its needed, as this
   * iterates over all configured remotes.
   */
  for (int i = 0; remotes[i] != NULL; i++)
    {
      char *remote = remotes[i];
      g_autoptr(FlatpakDecomposed) auto_install_ref = NULL;

      if (flatpak_dir_get_remote_disabled (priv->dir, remote))
        continue;

      auto_install_ref = flatpak_dir_get_remote_auto_install_authenticator_ref (priv->dir, remote);
      if (auto_install_ref != NULL)
        {
          g_autoptr(GError) local_error = NULL;
          g_autoptr(GFile) deploy = NULL;

          deploy = flatpak_dir_get_if_deployed (priv->dir, auto_install_ref, NULL, cancellable);
          if (deploy == NULL)
            {
              g_autoptr(FlatpakRemoteState) state = flatpak_transaction_ensure_remote_state (self, FLATPAK_TRANSACTION_OPERATION_UPDATE, remote, NULL, NULL);

              if (state != NULL &&
                  flatpak_remote_state_lookup_ref (state, flatpak_decomposed_get_ref (auto_install_ref), NULL, NULL, NULL, NULL, NULL, NULL))
                {
                  g_info ("Auto adding install of %s from remote %s", flatpak_decomposed_get_ref (auto_install_ref), remote);

                  if (!flatpak_transaction_add_ref (self, remote, auto_install_ref, NULL, NULL, NULL,
                                                    FLATPAK_TRANSACTION_OPERATION_INSTALL_OR_UPDATE,
                                                    NULL, NULL, NULL, FALSE, FALSE, NULL,
                                                    &local_error))
                    g_info ("Failed to add auto-install ref %s: %s", flatpak_decomposed_get_ref (auto_install_ref),
                             local_error->message);
                }
            }
        }
    }

  return TRUE;
}

static void
emit_new_op (FlatpakTransaction *self, FlatpakTransactionOperation *op, FlatpakTransactionProgress *progress)
{
  g_signal_emit (self, signals[NEW_OPERATION], 0, op, progress);
}

static void
emit_op_done (FlatpakTransaction          *self,
              FlatpakTransactionOperation *op,
              FlatpakTransactionResult     details)
{
  FlatpakTransactionPrivate *priv = flatpak_transaction_get_instance_private (self);
  g_autofree char *commit = NULL;

  if (priv->no_deploy)
    commit = flatpak_dir_read_latest (priv->dir, op->remote, flatpak_decomposed_get_ref (op->ref), NULL, NULL, NULL);
  else
    {
      g_autoptr(GBytes) deploy_data = flatpak_dir_get_deploy_data (priv->dir, op->ref, FLATPAK_DEPLOY_VERSION_ANY, NULL, NULL);
      if (deploy_data)
        commit = g_strdup (flatpak_deploy_data_get_commit (deploy_data));
    }

  g_signal_emit (self, signals[OPERATION_DONE], 0, op, commit, details);
}

static GBytes *
load_deployed_metadata (FlatpakTransaction *self, FlatpakDecomposed *ref, char **out_commit, char **out_remote)
{
  FlatpakTransactionPrivate *priv = flatpak_transaction_get_instance_private (self);
  g_autoptr(GFile) deploy_dir = NULL;
  g_autoptr(GFile) metadata_file = NULL;
  g_autofree char *metadata_contents = NULL;
  gsize metadata_contents_length;

  deploy_dir = flatpak_dir_get_if_deployed (priv->dir, ref, NULL, NULL);
  if (deploy_dir == NULL)
    return NULL;

  if (out_commit || out_remote)
    {
      g_autoptr(GBytes) deploy_data = NULL;
      deploy_data = flatpak_load_deploy_data (deploy_dir, ref,
                                              flatpak_dir_get_repo (priv->dir),
                                              FLATPAK_DEPLOY_VERSION_ANY, NULL, NULL);
      if (deploy_data == NULL)
        return NULL;

      if (out_commit)
        *out_commit = g_strdup (flatpak_deploy_data_get_commit (deploy_data));
      if (out_remote)
        *out_remote = g_strdup (flatpak_deploy_data_get_origin (deploy_data));
    }

  metadata_file = g_file_get_child (deploy_dir, "metadata");

  if (!g_file_load_contents (metadata_file, NULL, &metadata_contents, &metadata_contents_length, NULL, NULL))
    {
      g_info ("No metadata in local deploy of %s", flatpak_decomposed_get_ref (ref));
      return NULL;
    }

  return g_bytes_new_take (g_steal_pointer (&metadata_contents), metadata_contents_length);
}

static void
emit_eol_and_maybe_skip (FlatpakTransaction          *self,
                         FlatpakTransactionOperation *op)
{
  g_autofree char *id = NULL;
  const char *previous_ids[] = { NULL, NULL };

  if (op->skip || (!op->eol && !op->eol_rebase) ||
      op->kind == FLATPAK_TRANSACTION_OPERATION_UNINSTALL)
    return;

  id = flatpak_decomposed_dup_id (op->ref);
  previous_ids[0] = id;

  g_signal_emit (self, signals[END_OF_LIFED_WITH_REBASE], 0, op->remote, flatpak_decomposed_get_ref (op->ref), op->eol, op->eol_rebase, previous_ids, &op->skip);
}

static gboolean
mark_op_resolved (FlatpakTransactionOperation *op,
                  const char                  *commit,
                  GFile                       *sideload_path,
                  FlatpakImageSource          *image_source,
                  GBytes                      *metadata,
                  GBytes                      *old_metadata,
                  GError                     **error)
{
  g_info ("marking op %s:%s resolved to %s", kind_to_str (op->kind), flatpak_decomposed_get_ref (op->ref), commit ? commit : "-");

  g_assert (op != NULL);

  g_assert (commit != NULL || image_source != NULL);

  op->resolved = TRUE;

  if (op->resolved_commit != commit)
    {
      g_free (op->resolved_commit); /* This is already set if we retry resolving to get a token, so free first */
      op->resolved_commit = g_strdup (commit);
    }

  if (sideload_path)
    op->resolved_sideload_path = g_object_ref (sideload_path);

  if (image_source)
    op->resolved_image_source = g_object_ref (image_source);

  if (metadata)
    {
      g_autoptr(GKeyFile) metakey = g_key_file_new ();
      if (!g_key_file_load_from_bytes (metakey, metadata, G_KEY_FILE_NONE, NULL))
        return flatpak_fail_error (error, FLATPAK_ERROR_INVALID_DATA,
                                   "Metadata for %s is invalid", flatpak_decomposed_get_ref (op->ref));

      op->resolved_metadata = g_bytes_ref (metadata);
      op->resolved_metakey = g_steal_pointer (&metakey);
    }
  if (old_metadata)
    {
      g_autoptr(GKeyFile) metakey = g_key_file_new ();
      if (g_key_file_load_from_bytes (metakey, old_metadata, G_KEY_FILE_NONE, NULL))
        {
          op->resolved_old_metadata = g_bytes_ref (old_metadata);
          op->resolved_old_metakey = g_steal_pointer (&metakey);
        }
      else
        {
          /* This shouldn't happen, but a NULL old metadata is safe (all permissions are considered new) */
          g_message ("Warning: Failed to parse old metadata for %s\n", flatpak_decomposed_get_ref (op->ref));
        }
    }

  return TRUE;
}

static gboolean
resolve_op_end (FlatpakTransaction *self,
                FlatpakTransactionOperation *op,
                const char *checksum,
                GFile *sideload_path,
                FlatpakImageSource *image_source,
                GBytes *metadata_bytes,
                GError **error)
{
  g_autoptr(GBytes) old_metadata_bytes = NULL;

  old_metadata_bytes = load_deployed_metadata (self, op->ref, NULL, NULL);
  if (!mark_op_resolved (op, checksum, sideload_path, image_source, metadata_bytes, old_metadata_bytes, error))
    return FALSE;
  emit_eol_and_maybe_skip (self, op);
  return TRUE;
 }


static gboolean
resolve_op_from_commit (FlatpakTransaction *self,
                        FlatpakTransactionOperation *op,
                        const char *checksum,
                        GFile *sideload_path,
                        FlatpakImageSource *image_source,
                        GVariant *commit_data,
                        GError **error)
{
  g_autoptr(GBytes) metadata_bytes = NULL;
  g_autoptr(GVariant) commit_metadata = NULL;
  const char *xa_metadata = NULL;
  guint64 download_size = 0;
  guint64 installed_size = 0;

  commit_metadata = g_variant_get_child_value (commit_data, 0);
  g_variant_lookup (commit_metadata, "xa.metadata", "&s", &xa_metadata);
  if (xa_metadata == NULL)
    return flatpak_fail_error (error, FLATPAK_ERROR_INVALID_DATA,
                               "No xa.metadata in local commit %s ref %s",
                               checksum, flatpak_decomposed_get_ref (op->ref));

  metadata_bytes = g_bytes_new (xa_metadata, strlen (xa_metadata));

  if (g_variant_lookup (commit_metadata, "xa.download-size", "t", &download_size))
    op->download_size = GUINT64_FROM_BE (download_size);
  if (g_variant_lookup (commit_metadata, "xa.installed-size", "t", &installed_size))
    op->installed_size = GUINT64_FROM_BE (installed_size);

  g_variant_lookup (commit_metadata, OSTREE_COMMIT_META_KEY_ENDOFLIFE, "s", &op->eol);
  g_variant_lookup (commit_metadata, OSTREE_COMMIT_META_KEY_ENDOFLIFE_REBASE, "s", &op->eol_rebase);

  if (op->eol_rebase)
    {
      g_autoptr(FlatpakDecomposed) eolr_decomposed = NULL;
      eolr_decomposed = flatpak_decomposed_new_from_ref (op->eol_rebase, error);
      if (!eolr_decomposed)
        return FALSE;
      if (flatpak_decomposed_get_kind (op->ref) != flatpak_decomposed_get_kind (eolr_decomposed))
        return flatpak_fail_error (error, FLATPAK_ERROR_INVALID_DATA,
                                   "end-of-life-rebase on commit %s has the wrong type (%s -> %s)",
                                   checksum, flatpak_decomposed_get_ref (op->ref),
                                   flatpak_decomposed_get_ref (eolr_decomposed));
    }

  return resolve_op_end (self, op, checksum, sideload_path, image_source, metadata_bytes, error);
}

/* NOTE: In case of non-available summary this returns FALSE with a
 * NULL error, but for other error cases it will be set.
 */
static gboolean
try_resolve_op_from_metadata (FlatpakTransaction *self,
                              FlatpakTransactionOperation *op,
                              const char *checksum,
                              GFile *sideload_path,
                              FlatpakImageSource *image_source,
                              FlatpakRemoteState *state,
                              GError **error)
{
  g_autoptr(GBytes) metadata_bytes = NULL;
  guint64 download_size = 0;
  guint64 installed_size = 0;
  const char *metadata = NULL;
  VarMetadataRef sparse_cache;
  g_autofree char *summary_checksum = NULL;

  /* Ref has to match the actual commit in the summary */
  if ((state->summary == NULL && state->index == NULL) ||
      !flatpak_remote_state_lookup_ref (state, flatpak_decomposed_get_ref (op->ref),
                                        &summary_checksum, NULL, NULL, NULL, NULL, NULL) ||
      strcmp (summary_checksum, checksum) != 0)
    return FALSE;

  /* And, we must have the actual cached data in the summary */
  if (!flatpak_remote_state_lookup_cache (state, flatpak_decomposed_get_ref (op->ref),
                                          &download_size, &installed_size, &metadata, NULL))
      return FALSE;

  metadata_bytes = g_bytes_new (metadata, strlen (metadata));

  flatpak_remote_state_lookup_ref (state, flatpak_decomposed_get_ref (op->ref),
                                   NULL, NULL, &op->summary_metadata, NULL, NULL, NULL);

  op->installed_size = installed_size;
  op->download_size = download_size;

  op->token_type = state->default_token_type;

  if (flatpak_remote_state_lookup_sparse_cache (state, flatpak_decomposed_get_ref (op->ref), &sparse_cache, NULL))
    {
      op->eol = g_strdup (var_metadata_lookup_string (sparse_cache, FLATPAK_SPARSE_CACHE_KEY_ENDOFLIFE, NULL));
      op->eol_rebase = g_strdup (var_metadata_lookup_string (sparse_cache, FLATPAK_SPARSE_CACHE_KEY_ENDOFLIFE_REBASE, NULL));
      op->token_type = GINT32_FROM_LE (var_metadata_lookup_int32 (sparse_cache, FLATPAK_SPARSE_CACHE_KEY_TOKEN_TYPE, op->token_type));

      if (op->eol_rebase)
        {
          g_autoptr(FlatpakDecomposed) eolr_decomposed = NULL;
          eolr_decomposed = flatpak_decomposed_new_from_ref (op->eol_rebase, error);
          if (!eolr_decomposed)
            return FALSE;
          if (flatpak_decomposed_get_kind (op->ref) != flatpak_decomposed_get_kind (eolr_decomposed))
            return flatpak_fail_error (error, FLATPAK_ERROR_INVALID_DATA,
                                       "end-of-life-rebase on commit %s has the wrong type (%s -> %s)",
                                       checksum, flatpak_decomposed_get_ref (op->ref),
                                       flatpak_decomposed_get_ref (eolr_decomposed));
        }
    }

  return resolve_op_end (self, op, checksum, sideload_path, NULL, metadata_bytes, error);
}

static gboolean
op_may_need_token (FlatpakTransactionOperation *op)
{
  return
    !op->skip &&
    !op->update_only_deploy &&
    (op->kind == FLATPAK_TRANSACTION_OPERATION_INSTALL ||
     op->kind == FLATPAK_TRANSACTION_OPERATION_UPDATE  ||
     op->kind == FLATPAK_TRANSACTION_OPERATION_INSTALL_OR_UPDATE);
}

/* Resolving an operation means figuring out the target commit
   checksum and the metadata for that commit, so that we can handle
   dependencies from it, and verify versions. */
static gboolean
resolve_ops (FlatpakTransaction *self,
             GCancellable       *cancellable,
             GError            **error)
{
  FlatpakTransactionPrivate *priv = flatpak_transaction_get_instance_private (self);
  GList *l;

  for (l = priv->ops; l != NULL; l = l->next)
    {
      FlatpakTransactionOperation *op = l->data;
      g_autoptr(FlatpakRemoteState) state = NULL;
      g_autofree char *checksum = NULL;
      g_autoptr(GBytes) metadata_bytes = NULL;

      if (op->resolved)
        continue;

      if (op->skip)
        {
          /* We're not yet resolved, but marked skip anyway, this can happen if during
           * request_required_tokens() we were normalized away even though not fully resolved.
           * For example we got the checksum but need to auth to get the commit, but the
           * checksum we got was the version already installed.
           */
          g_assert (op->resolved_commit != NULL);
          if (!mark_op_resolved (op, op->resolved_commit, NULL, NULL, NULL, NULL, error))
            return FALSE;
          continue;
        }

      if (op->kind == FLATPAK_TRANSACTION_OPERATION_UNINSTALL)
        {
          /* We resolve to the deployed metadata, because we need it to uninstall related ops */

          metadata_bytes = load_deployed_metadata (self, op->ref, &checksum, NULL);
          if (metadata_bytes == NULL)
            {
              op->skip = TRUE;
              continue;
            }
          if (!mark_op_resolved (op, checksum, NULL, NULL, metadata_bytes, NULL, error))
            return FALSE;
          continue;
        }

      if (op->kind == FLATPAK_TRANSACTION_OPERATION_INSTALL_BUNDLE)
        {
          g_assert (op->commit != NULL);
          if (!mark_op_resolved (op, op->commit, NULL, NULL, op->external_metadata, NULL, error))
            return FALSE;
          continue;
        }

      /* op->kind is INSTALL or UPDATE */

      if (flatpak_decomposed_is_app (op->ref))
        {
          if (op->kind == FLATPAK_TRANSACTION_OPERATION_INSTALL)
            priv->max_op = APP_INSTALL;
          else
            priv->max_op = MAX (priv->max_op, APP_UPDATE);
        }
      else if (flatpak_decomposed_is_runtime (op->ref))
        {
          if (op->kind == FLATPAK_TRANSACTION_OPERATION_INSTALL)
            priv->max_op = MAX (priv->max_op, RUNTIME_INSTALL);
        }

      state = flatpak_transaction_ensure_remote_state (self, op->kind, op->remote, NULL, error);
      if (state == NULL)
        return FALSE;

      if (op->image_source)
        {
          if (!mark_op_resolved (op, NULL, NULL, op->image_source, op->external_metadata, NULL, error))
            return FALSE;
        }
      /* Should we use local state */
      else if (transaction_is_local_only (self, op->kind))
        {
          g_autoptr(GVariant) commit_data = flatpak_dir_read_latest_commit (priv->dir, op->remote, op->ref,
                                                                            &checksum, NULL, error);
          if (commit_data == NULL)
            return FALSE;

          if (!resolve_op_from_commit (self, op, checksum, NULL, NULL, commit_data, error))
            return FALSE;
        }
      else
        {
          g_autoptr(GError) local_error = NULL;
          g_autoptr(GFile) sideload_path = NULL;
          g_autoptr(FlatpakImageSource) image_source = NULL;

          if (op->commit != NULL)
            {
              checksum = g_strdup (op->commit);
              /* Check if this is available offline and if so, use that */
              flatpak_remote_state_lookup_sideload_checksum (state, op->commit, &sideload_path, &image_source);
            }
          else
            {
              g_autofree char *latest_checksum = NULL;
              g_autoptr(GFile) latest_sideload_path = NULL;
              g_autoptr(FlatpakImageSource) latest_image_source = NULL;
              g_autofree char *local_checksum = NULL;
              guint64 latest_timestamp;
              g_autoptr(GVariant) local_commit_data = flatpak_dir_read_latest_commit (priv->dir, op->remote, op->ref,
                                                                                      &local_checksum, NULL, NULL);

              if (flatpak_dir_find_latest_rev (priv->dir, state, flatpak_decomposed_get_ref (op->ref), op->commit,
                                               &latest_checksum, &latest_timestamp, &latest_sideload_path, &latest_image_source,
                                               cancellable, &local_error))
                {
                  /* If we found the latest in a sideload repo, it may be older that what is locally available, check timestamps.
                   * Note: If the timestamps are equal (timestamp granularity issue), assume we want to update */
                  if ((latest_sideload_path != NULL || latest_image_source != NULL) &&
                      local_commit_data && latest_timestamp != 0 &&
                      ostree_commit_get_timestamp (local_commit_data) > latest_timestamp)
                    {
                      g_info ("Installed commit %s newer than sideloaded %s, ignoring", local_checksum, latest_checksum);
                      checksum = g_steal_pointer (&local_checksum);
                    }
                  else
                    {
                      /* Otherwise, use whatever we found */
                      checksum = g_steal_pointer (&latest_checksum);
                      sideload_path = g_steal_pointer (&latest_sideload_path);
                      image_source = g_steal_pointer (&latest_image_source);
                    }
                }
              else
                {
                  /* Ref not available in the remote (maybe offline), resolve to local version if installed */
                  if (local_commit_data == NULL)
                    {
                      g_propagate_error (error, g_steal_pointer (&local_error));
                      return FALSE;
                    }

                  g_message (_("Warning: Treating remote fetch error as non-fatal since %s is already installed: %s"),
                             flatpak_decomposed_get_ref (op->ref), local_error->message);
                  g_clear_error (&local_error);

                  checksum = g_steal_pointer (&local_checksum);
                }
            }

          /* First try to resolve via metadata (if remote is available and its metadata matches the commit version) */
          if (!try_resolve_op_from_metadata (self, op, checksum, sideload_path, image_source, state, &local_error))
            {
              if (local_error)
                {
                  /* Actual error, not just missing from summary */
                  g_propagate_error (error, g_steal_pointer (&local_error));
                  return FALSE;
                }

              /* Missing from summary, try to load the commit object.
               * Note, we don't have a token here, so this will not work for authenticated apps.
               * We handle this by catching the 401 http status and retrying. */
              g_autoptr(GVariant) commit_data = NULL;

              /* OCI needs this to get the oci repository for the ref to request the token, so lets always set it here */
              if (op->summary_metadata == NULL)
                flatpak_remote_state_lookup_ref (state, flatpak_decomposed_get_ref (op->ref),
                                                  NULL, NULL, &op->summary_metadata, NULL, NULL, NULL);

              commit_data = flatpak_remote_state_load_ref_commit (state, priv->dir,
                                                                  flatpak_decomposed_get_ref (op->ref),
                                                                  checksum, /* initially NULL */ op->resolved_token,
                                                                  NULL, NULL, &local_error);
              if (commit_data == NULL)
                {
                  if (g_error_matches (local_error, FLATPAK_HTTP_ERROR, FLATPAK_HTTP_ERROR_UNAUTHORIZED) && !op->requested_token)
                    {

                      g_info ("Unauthorized access during resolve by commit of %s, retrying with token", flatpak_decomposed_get_ref (op->ref));
                      priv->needs_resolve = TRUE;
                      priv->needs_tokens = TRUE;

                      /* Token type maxint32 means we don't know the type */
                      op->token_type = G_MAXINT32;
                      op->resolved_commit = g_strdup (checksum);

                      g_clear_error (&local_error);
                      continue;
                    }
                  g_propagate_error (error, g_steal_pointer (&local_error));
                  return FALSE;
                }

              if (!resolve_op_from_commit (self, op, checksum, sideload_path, image_source, commit_data, error))
                return FALSE;
            }
        }
    }

  return TRUE;
}

static gboolean
resolve_all_ops (FlatpakTransaction *self,
                 GCancellable       *cancellable,
                 GError            **error)
{
  FlatpakTransactionPrivate *priv = flatpak_transaction_get_instance_private (self);

  while (priv->needs_resolve)
    {
      priv->needs_resolve = FALSE;
      priv->needs_tokens = FALSE;
      if (!resolve_ops (self, cancellable, error))
        return FALSE;

      /* We might need tokens early, if reading individual commits needs it,
       * otherwise we try to delay to bunch the requests */
      if (priv->needs_tokens)
        {
          if (!request_required_tokens (self, NULL, cancellable, error))
            return FALSE;
        }
    }

  return TRUE;
}

static void
request_tokens_response (FlatpakAuthenticatorRequest *object,
                         guint response,
                         GVariant *results,
                         RequestData *data)
{
  FlatpakTransaction *transaction = data->transaction;
  FlatpakTransactionPrivate *priv = flatpak_transaction_get_instance_private (transaction);

  if (data->done)
    return; /* Don't respond twice */

  g_assert (priv->active_request_id == 0); /* It should have reported done */

  data->response = response;
  data->results = g_variant_ref (results);
  data->done = TRUE;
  g_main_context_wakeup (g_main_context_get_thread_default ());
}

static void
request_tokens_webflow (FlatpakAuthenticatorRequest *object,
                        const gchar *arg_uri,
                        GVariant *options,
                        RequestData *data)
{
  g_autoptr(FlatpakTransaction) transaction = g_object_ref (data->transaction);
  FlatpakTransactionPrivate *priv = flatpak_transaction_get_instance_private (transaction);
  gboolean retval = FALSE;

  if (data->done)
    return; /* Don't respond twice */

  g_assert (priv->active_request_id == 0);
  priv->active_request_id = ++priv->next_request_id;

  g_info ("Webflow start %s", arg_uri);
  g_signal_emit (transaction, signals[WEBFLOW_START], 0, data->remote, arg_uri, options, priv->active_request_id, &retval);
  if (!retval)
    {
      g_autoptr(GError) local_error = NULL;

      priv->active_request_id = 0;

      /* We didn't handle the uri, cancel the auth op. */
      if (!flatpak_authenticator_request_call_close_sync (data->request, NULL, &local_error))
        g_info ("Failed to close auth request: %s", local_error->message);
    }
}

static void
request_tokens_webflow_done (FlatpakAuthenticatorRequest *object,
                             GVariant *options,
                             RequestData *data)
{
  g_autoptr(FlatpakTransaction) transaction = g_object_ref (data->transaction);
  FlatpakTransactionPrivate *priv = flatpak_transaction_get_instance_private (transaction);
  guint id;

  if (data->done)
    return; /* Don't respond twice */

  g_assert (priv->active_request_id != 0);
  id = priv->active_request_id;
  priv->active_request_id = 0;

  g_info ("Webflow done");
  g_signal_emit (transaction, signals[WEBFLOW_DONE], 0, options, id);
}

static void
request_tokens_basic_auth (FlatpakAuthenticatorRequest *object,
                           const gchar *arg_realm,
                           GVariant *options,
                           RequestData *data)
{
  g_autoptr(FlatpakTransaction) transaction = g_object_ref (data->transaction);
  FlatpakTransactionPrivate *priv = flatpak_transaction_get_instance_private (transaction);
  gboolean retval = FALSE;

  if (data->done)
    return; /* Don't respond twice */

  g_assert (priv->active_request_id == 0);
  priv->active_request_id = ++priv->next_request_id;

  g_info ("BasicAuth start %s", arg_realm);
  g_signal_emit (transaction, signals[BASIC_AUTH_START], 0, data->remote, arg_realm, options, priv->active_request_id, &retval);
  if (!retval)
    {
      g_autoptr(GError) local_error = NULL;

      priv->active_request_id = 0;

      /* We didn't handle the request, cancel the auth op. */
      if (!flatpak_authenticator_request_call_close_sync (data->request, NULL, &local_error))
        g_info ("Failed to close auth request: %s", local_error->message);
    }

}

/**
 * flatpak_transaction_abort_webflow:
 * @self: a #FlatpakTransaction
 * @id: The webflow id, as passed into the webflow-start signal
 *
 * Cancel an ongoing webflow authentication request. This can be call
 * in the time between #FlatpakTransaction::webflow-start returned
 * %TRUE, and #FlatpakTransaction::webflow-done is emitted. It will
 * cancel the ongoing authentication operation.
 *
 * This is useful for example if you're showing an authentication
 * window with a browser, but the user closed it before it was finished.
 *
 * Since: 1.5.1
 */
void
flatpak_transaction_abort_webflow (FlatpakTransaction *self,
                                   guint id)
{
  FlatpakTransactionPrivate *priv = flatpak_transaction_get_instance_private (self);
  g_autoptr(GError) local_error = NULL;

  if (priv->active_request_id == id)
    {
      RequestData *data = priv->active_request;

      g_assert (data != NULL);
      priv->active_request_id = 0;

      if (!data->done)
        {
          if (!flatpak_authenticator_request_call_close_sync (data->request, NULL, &local_error))
            g_info ("Failed to close auth request: %s", local_error->message);
        }
    }
}

/**
 * flatpak_transaction_complete_basic_auth:
 * @self: a #FlatpakTransaction
 * @id: The webflow id, as passed into the webflow-start signal
 * @user: The user name, or %NULL if aborting request
 * @password: The password
 * @options: Extra a{sv] variant with options (or %NULL), currently unused.
 *
 * Finishes (or aborts) an ongoing basic auth request.
 *
 * Since: 1.5.2
 */
void
flatpak_transaction_complete_basic_auth (FlatpakTransaction *self,
                                         guint id,
                                         const char *user,
                                         const char *password,
                                         GVariant *options)
{
  FlatpakTransactionPrivate *priv = flatpak_transaction_get_instance_private (self);
  g_autoptr(GError) local_error = NULL;
  g_autoptr(GVariant) default_options = NULL;

  if (options == NULL)
    {
      default_options = g_variant_ref_sink (g_variant_new_array (G_VARIANT_TYPE ("{sv}"), NULL, 0));
      options = default_options;
    }

  if (priv->active_request_id == id)
    {
      RequestData *data = priv->active_request;

      g_assert (data != NULL);
      priv->active_request_id = 0;

      if (user == NULL)
        {
          if (!flatpak_authenticator_request_call_close_sync (data->request, NULL, &local_error))
            g_info ("Failed to abort basic auth request: %s", local_error->message);
        }
      else
        {
          if (!flatpak_authenticator_request_call_basic_auth_reply_sync (data->request,
                                                                         user, password,
                                                                         options,
                                                                         NULL, &local_error))
            g_info ("Failed to reply to basic auth request: %s", local_error->message);
        }
    }
}

static void
copy_summary_data (GVariantBuilder *builder, GVariant *summary, const char *key)
{
  g_autoptr(GVariant) extensions = g_variant_get_child_value (summary, 1);
  g_autoptr(GVariant) value = NULL;

  value = g_variant_lookup_value (extensions, key, NULL);
  if (value)
    g_variant_builder_add (builder, "{s@v}", key, g_variant_new_variant (value));
}


static gboolean
request_tokens_for_remote (FlatpakTransaction *self,
                           const char         *remote,
                           GList              *ops,
                           GCancellable       *cancellable,
                           GError            **error)
{
  FlatpakTransactionPrivate *priv = flatpak_transaction_get_instance_private (self);
  g_autoptr(GString) refs_as_str = g_string_new ("");
  GList *l;
  g_autoptr(AutoFlatpakAuthenticatorRequest) request = NULL;
  g_autoptr(AutoFlatpakAuthenticator) authenticator = NULL;
  g_autoptr(GMainContextPopDefault) context = NULL;
  RequestData data = { self, remote };
  g_autoptr(GVariant) tokens = NULL;
  g_autoptr(GVariant) results = NULL;
  g_autoptr(GVariant) refs = NULL;
  GVariantBuilder refs_builder;
  g_autofree char *remote_url = NULL;
  g_autoptr(GVariantBuilder) extra_builder = NULL;
  FlatpakRemoteState *state;
  g_autoptr(FlatpakDecomposed) auto_install_ref = NULL;

  auto_install_ref = flatpak_dir_get_remote_auto_install_authenticator_ref (priv->dir, remote);
  if (auto_install_ref != NULL)
    {
      g_autoptr(GFile) deploy = NULL;
      deploy = flatpak_dir_get_if_deployed (priv->dir, auto_install_ref, NULL, cancellable);
      if (deploy == NULL)
        {
          g_signal_emit (self, signals[INSTALL_AUTHENTICATOR], 0,
                         remote, flatpak_decomposed_get_ref (auto_install_ref));
          deploy = flatpak_dir_get_if_deployed (priv->dir, auto_install_ref, NULL, cancellable);
        }
      if (deploy == NULL)
        return flatpak_fail (error, _("No authenticator installed for remote '%s'"), remote);
    }

  if (!ostree_repo_remote_get_url (flatpak_dir_get_repo (priv->dir), remote, &remote_url, error))
    return FALSE;

  g_variant_builder_init (&refs_builder, G_VARIANT_TYPE ("a(ssia{sv})"));

  for (l = ops; l != NULL; l = l->next)
    {
      FlatpakTransactionOperation *op = l->data;
      g_autoptr(GVariantBuilder) metadata_builder = g_variant_builder_new (G_VARIANT_TYPE ("a{sv}"));

      if (op->summary_metadata)
        {
          const int n = g_variant_n_children (op->summary_metadata);
          for (int i = 0; i < n; i++)
            {
              const char *key;
              g_autofree char *new_key = NULL;
              g_autoptr(GVariant) value = NULL;

              g_variant_get_child (op->summary_metadata, i, "{&s@v}", &key, &value);

              new_key = g_strconcat ("summary.", key, NULL);
              g_variant_builder_add (metadata_builder, "{s@v}", new_key, value);
            }
        }

      g_variant_builder_add (&refs_builder, "(ssi@a{sv})", flatpak_decomposed_get_ref (op->ref),
                             op->resolved_commit ? op->resolved_commit : "", (gint32)op->token_type, g_variant_builder_end (metadata_builder));
      g_string_append_printf (refs_as_str, "(%s, %s %d)", flatpak_decomposed_get_ref (op->ref),
                              op->resolved_commit ? op->resolved_commit : "", op->token_type);
      if (l->next != NULL)
        g_string_append (refs_as_str, ", ");
    }

  g_info ("Requesting tokens for remote %s: %s", remote, refs_as_str->str);
  refs = g_variant_ref_sink (g_variant_builder_end (&refs_builder));

  extra_builder = g_variant_builder_new (G_VARIANT_TYPE ("a{sv}"));

  state = g_hash_table_lookup (priv->remote_states, remote);
  if (state && state->summary)
    {
      copy_summary_data (extra_builder, state->summary, "xa.oci-registry-uri");
    }

  if (flatpak_dir_get_no_interaction (priv->dir))
    g_variant_builder_add (extra_builder, "{sv}", "no-interaction", g_variant_new_boolean (TRUE));

  context = flatpak_main_context_new_default ();

  authenticator = flatpak_auth_new_for_remote (priv->dir, remote, cancellable, error);
  if (authenticator == NULL)
    return FALSE;

  request = flatpak_auth_create_request (authenticator, cancellable, error);
  if (request == NULL)
    return FALSE;

  g_signal_connect (request, "webflow", (GCallback)request_tokens_webflow, &data);
  g_signal_connect (request, "webflow-done", (GCallback)request_tokens_webflow_done, &data);
  g_signal_connect (request, "response", (GCallback)request_tokens_response, &data);
  g_signal_connect (request, "basic-auth", (GCallback)request_tokens_basic_auth, &data);

  priv->active_request = &data;

  data.request = request;
  if (!flatpak_auth_request_ref_tokens (authenticator, request, remote, remote_url, refs, g_variant_builder_end (extra_builder),
                                        priv->parent_window, cancellable, error))
    return FALSE;

  while (!data.done)
    g_main_context_iteration (context, TRUE);

  g_assert (priv->active_request_id == 0); /* No outstanding requests */
  priv->active_request = NULL;

  results = data.results; /* Make sure it's freed as needed */

  {
    g_autofree char *results_str = results != NULL ? g_variant_print (results, FALSE) : g_strdup ("NULL");
    g_info ("Response from request_tokens: %d - %s\n", data.response, results_str);
  }

  if (data.response == FLATPAK_AUTH_RESPONSE_CANCELLED)
    {
      g_set_error (error, G_IO_ERROR, G_IO_ERROR_CANCELLED,
                   "User cancelled authentication request");
      return FALSE;
    }

  if (data.response != FLATPAK_AUTH_RESPONSE_OK)
    {
      const char *error_message;
      gint32 error_code;

      if (!g_variant_lookup (results, "error-message", "&s", &error_message))
        error_message = NULL;

      if (g_variant_lookup (results, "error-code", "i", &error_code) && error_code != -1)
        {
          if (error_message)
            return flatpak_fail_error (error, error_code, _("Failed to get tokens for ref: %s"), error_message);
          else
            return flatpak_fail_error (error, error_code, _("Failed to get tokens for ref"));
        }
      else
        {
          if (error_message)
            return flatpak_fail (error, _("Failed to get tokens for ref: %s"), error_message);
          else
            return flatpak_fail (error, _("Failed to get tokens for ref"));
        }
    }

  tokens = g_variant_lookup_value (results, "tokens", G_VARIANT_TYPE ("a{sas}"));
  if (tokens == NULL)
    return flatpak_fail (error, "Authenticator didn't send requested tokens");

  for (l = ops; l != NULL; l = l->next)
    {
      FlatpakTransactionOperation *op = l->data;
      GVariantIter iter;
      const char *token = NULL;
      const char *token_for_refs;
      g_autofree const char **refs_strv;

      g_variant_iter_init (&iter, tokens);
      while (g_variant_iter_next (&iter, "{&s^a&s}", &token_for_refs, &refs_strv))
        {
          if (g_strv_contains (refs_strv, flatpak_decomposed_get_ref (op->ref)))
            {
              token = token_for_refs;
              break;
            }
          g_clear_pointer (&refs_strv, g_free);
        }

      if (token == NULL)
        return flatpak_fail (error, "Authenticator didn't send tokens for ref");

      /* Allow sending empty tokens to mean no token needed */

      op->resolved_token = *token == 0 ? NULL : g_strdup (token);
      op->requested_token = TRUE;
    }

  return TRUE;
}

static gboolean
request_required_tokens (FlatpakTransaction *self,
                         const char         *optional_remote, /* else all remotes */
                         GCancellable       *cancellable,
                         GError            **error)
{
  FlatpakTransactionPrivate *priv = flatpak_transaction_get_instance_private (self);
  GList *l;
  g_autoptr(GHashTable) need_token_ht = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, (GDestroyNotify) g_list_free); /* remote name -> list of op */

  /* Ensure all ops so far ar normalized so we don't request authentication for no-op updates */
  flatpak_transaction_normalize_ops (self);

  for (l = priv->ops; l != NULL; l = l->next)
    {
      FlatpakTransactionOperation *op = l->data;
      GList *old;

      if (!flatpak_transaction_operation_get_requires_authentication (op))
        continue;

      if (optional_remote != NULL && g_strcmp0 (op->remote, optional_remote) != 0)
        continue;

      old = g_hash_table_lookup (need_token_ht, op->remote);
      if (old == NULL)
        g_hash_table_insert (need_token_ht, op->remote, g_list_append (NULL, op));
      else
        old = g_list_append (old, op);
    }

  GLNX_HASH_TABLE_FOREACH_KV(need_token_ht, const char *, remote, GList *, remote_ops)
    {
      if (!request_tokens_for_remote (self, remote, remote_ops, cancellable, error))
        return FALSE;
    }

  return TRUE;
}

static int
compare_op_ref (FlatpakTransactionOperation *a, FlatpakTransactionOperation *b)
{
  const char *aa = flatpak_decomposed_get_pref (a->ref);
  const char *bb = flatpak_decomposed_get_pref (b->ref);

  if (a->run_last != b->run_last)
    {
      if (a->run_last)
        return 1;
      return -1;
    }

  return g_strcmp0 (aa, bb);
}

static int
compare_op_prio (FlatpakTransactionOperation *a, FlatpakTransactionOperation *b)
{
  return b->run_after_prio - a->run_after_prio;
}

static void
sort_ops (FlatpakTransaction *self)
{
  FlatpakTransactionPrivate *priv = flatpak_transaction_get_instance_private (self);
  GList *sorted = NULL;
  GList *remaining;
  GList *runnable = NULL;
  GList *l, *next;

  remaining = priv->ops;
  priv->ops = NULL;

  /* First mark runnable all jobs that depend on nothing.
     Note that this essentially reverses the original list, so these
     are in the same order as specified */
  for (l = remaining; l != NULL; l = next)
    {
      FlatpakTransactionOperation *op = l->data;
      next = l->next;

      if (op->run_after_count == 0)
        {
          remaining = g_list_remove_link (remaining, l);
          runnable = g_list_concat (l, runnable);
        }
    }

  /* If no other order, start in alphabetical ref-order */
  runnable = g_list_sort (runnable, (GCompareFunc) compare_op_ref);

  while (runnable)
    {
      GList *run = runnable;
      FlatpakTransactionOperation *run_op = run->data;

      /* Put the first runnable on the sorted list */
      runnable = g_list_remove_link (runnable, run);
      sorted = g_list_concat (run, sorted); /* prepends, so reverse at the end */

      /* Then greedily run ops that become runnable, in run_after_prio order, so that
         related ops are run before dependencies */
      run_op->run_before_ops = g_list_sort (run_op->run_before_ops, (GCompareFunc) compare_op_prio);
      for (l = run_op->run_before_ops; l != NULL; l = l->next)
        {
          FlatpakTransactionOperation *after_op = l->data;
          after_op->run_after_count--;
          if (after_op->run_after_count == 0)
            {
              GList *after_l = g_list_find (remaining, after_op);
              g_assert (after_l != NULL);
              remaining = g_list_remove_link (remaining, after_l);
              runnable = g_list_concat (after_l, runnable);
            }
        }
    }

  if (remaining != NULL)
    {
      g_warning ("ops remaining after sort, maybe there is a dependency loop?");
      sorted = g_list_concat (remaining, sorted);
    }

  priv->ops = g_list_reverse (sorted);
}

/**
 * flatpak_transaction_get_operations:
 * @self: a #FlatpakTransaction
 *
 * Gets the list of operations. Skipped operations are not included. The order
 * of the list is the order in which the operations are executed.
 *
 * Returns: (transfer full) (element-type FlatpakTransactionOperation): a #GList of operations
 */
GList *
flatpak_transaction_get_operations (FlatpakTransaction *self)
{
  FlatpakTransactionPrivate *priv = flatpak_transaction_get_instance_private (self);
  GList *l;
  GList *non_skipped = NULL;

  non_skipped = NULL;
  for (l = priv->ops; l != NULL; l = l->next)
    {
      FlatpakTransactionOperation *op = l->data;
      if (!op->skip)
        non_skipped = g_list_prepend (non_skipped, g_object_ref (op));
    }
  return g_list_reverse (non_skipped);
}

/**
 * flatpak_transaction_get_current_operation:
 * @self: a #FlatpakTransaction
 *
 * Gets the current operation.
 *
 * Returns: (transfer full): the current #FlatpakTransactionOperation
 */
FlatpakTransactionOperation *
flatpak_transaction_get_current_operation (FlatpakTransaction *self)
{
  FlatpakTransactionPrivate *priv = flatpak_transaction_get_instance_private (self);

  if (priv->current_op)
    return g_object_ref (priv->current_op);

  return NULL;
}

/**
 * flatpak_transaction_get_operation_for_ref:
 * @self: a #FlatpakTransaction
 * @remote: (nullable): a remote name
 * @ref: a ref
 * @error: return location for an error
 *
 * Gets the operation for @ref, if any match. If @remote is non-%NULL, only an
 * operation for that remote will be returned. If remote is %NULL and the
 * transaction has more than one operation for @ref from different remotes, an
 * error will be returned.
 *
 * Returns: (transfer full): the #FlatpakTransactionOperation for @ref, or
 *   %NULL with @error set
 * Since: 1.13.3
 */
FlatpakTransactionOperation *
flatpak_transaction_get_operation_for_ref (FlatpakTransaction *self,
                                           const char         *remote,
                                           const char         *ref,
                                           GError            **error)
{
  FlatpakTransactionPrivate *priv = flatpak_transaction_get_instance_private (self);
  g_autoptr(FlatpakDecomposed) decomposed_ref = NULL;
  g_autoptr(FlatpakTransactionOperation) matching_op = NULL;
  GList *l;

  g_return_val_if_fail (ref != NULL, NULL);

  decomposed_ref = flatpak_decomposed_new_from_ref (ref, error);
  if (decomposed_ref == NULL)
    return NULL;

  for (l = priv->ops; l != NULL; l = l->next)
    {
      FlatpakTransactionOperation *op = l->data;

      if (remote != NULL && g_strcmp0 (remote, op->remote) != 0)
        continue;

      if (flatpak_decomposed_equal (op->ref, decomposed_ref))
        {
          if (matching_op == NULL)
            matching_op = g_object_ref (op);
          else
            {
              flatpak_fail_error (error, FLATPAK_ERROR_INVALID_DATA,
                                  _("Ref %s from %s matches more than one transaction operation"),
                                  ref, remote ? remote : _("any remote"));
              return NULL;
            }
        }
    }

  if (matching_op == NULL)
    {
      flatpak_fail_error (error, FLATPAK_ERROR_REF_NOT_FOUND,
                          _("No transaction operation found for ref %s from %s"),
                          ref, remote ? remote : _("any remote"));
      return NULL;
    }

  return g_steal_pointer (&matching_op);
}

/**
 * flatpak_transaction_get_installation:
 * @self: a #FlatpakTransactionOperation
 *
 * Gets the installation this transaction was created for.
 *
 * Returns: (transfer full): a #FlatpakInstallation
 */
FlatpakInstallation *
flatpak_transaction_get_installation (FlatpakTransaction *self)
{
  FlatpakTransactionPrivate *priv = flatpak_transaction_get_instance_private (self);

  return g_object_ref (priv->installation);
}

static gboolean
remote_is_already_configured (FlatpakTransaction *self,
                              const char         *url)
{
  FlatpakTransactionPrivate *priv = flatpak_transaction_get_instance_private (self);
  g_autofree char *old_remote = NULL;

  old_remote = flatpak_dir_find_remote_by_uri (priv->dir, url);

  /* Note: we don't check priv->extra_dependency_dirs because the transaction
   * can only operate on one installation so any install/update ops need to
   * have a remote there. */

  return old_remote != NULL;
}

static gboolean
handle_suggested_remote_name (FlatpakTransaction *self,
                              GKeyFile *keyfile,
                              GKeyFile *runtime_repo_keyfile, /* nullable */
                              GError **error)
{
  FlatpakTransactionPrivate *priv = flatpak_transaction_get_instance_private (self);
  g_autofree char *suggested_name = NULL;
  g_autofree char *name = NULL;
  g_autofree char *url = NULL;
  g_autoptr(GKeyFile) config = NULL;
  g_autoptr(GBytes) gpg_key = NULL;
  gboolean res;

  suggested_name = g_key_file_get_string (keyfile, FLATPAK_REF_GROUP,
                                          FLATPAK_REF_SUGGEST_REMOTE_NAME_KEY, NULL);
  if (suggested_name == NULL)
    return TRUE;

  name = g_key_file_get_string (keyfile, FLATPAK_REF_GROUP, FLATPAK_REF_NAME_KEY, NULL);
  if (name == NULL)
    return TRUE;

  url = g_key_file_get_string (keyfile, FLATPAK_REF_GROUP, FLATPAK_REF_URL_KEY, NULL);
  if (url == NULL)
    return TRUE;

  if (remote_is_already_configured (self, url))
    return TRUE;

  /* The name is already used, ignore */
  if (ostree_repo_remote_get_url (flatpak_dir_get_repo (priv->dir), suggested_name, NULL, NULL))
    return TRUE;

  res = FALSE;
  g_signal_emit (self, signals[ADD_NEW_REMOTE], 0, FLATPAK_TRANSACTION_REMOTE_GENERIC_REPO,
                 name, suggested_name, url, &res);
  if (res)
    {
      g_autofree char *runtime_repo_url = NULL;

      /* In case the runtime repo is the same repo, use its title, comment,
       * description, etc. since flatpakref files don't have those fields. */
      runtime_repo_url = g_key_file_get_string (runtime_repo_keyfile, FLATPAK_REPO_GROUP, FLATPAK_REPO_URL_KEY, NULL);
      if (runtime_repo_url != NULL && flatpak_uri_equal (runtime_repo_url, url))
        config = flatpak_parse_repofile (suggested_name, FALSE, runtime_repo_keyfile, &gpg_key, NULL, error);
      else
        config = flatpak_parse_repofile (suggested_name, TRUE, keyfile, &gpg_key, NULL, error);

      if (config == NULL)
        return FALSE;

      if (!flatpak_dir_modify_remote (priv->dir, suggested_name, config, gpg_key, NULL, error))
        return FALSE;

      if (!flatpak_dir_recreate_repo (priv->dir, NULL, error))
        return FALSE;

      flatpak_installation_drop_caches (priv->installation, NULL, NULL);
    }

  return TRUE;
}

static gboolean
load_flatpakrepo_file (FlatpakTransaction *self,
                       const char         *dep_url,
                       GKeyFile          **out_keyfile,
                       GCancellable       *cancellable,
                       GError            **error)
{
  FlatpakTransactionPrivate *priv = flatpak_transaction_get_instance_private (self);
  g_autoptr(GBytes) dep_data = NULL;
  g_autoptr(GKeyFile) dep_keyfile = g_key_file_new ();
  g_autoptr(GError) local_error = NULL;
  g_autoptr(FlatpakHttpSession) http_session = NULL;

  if (priv->disable_deps)
    return TRUE;

  if (!g_str_has_prefix (dep_url, "http:") &&
      !g_str_has_prefix (dep_url, "https:") &&
      !g_str_has_prefix (dep_url, "file:"))
    return flatpak_fail_error (error, FLATPAK_ERROR_INVALID_DATA, _("Flatpakrepo URL %s not file, HTTP or HTTPS"), dep_url);

  http_session = flatpak_create_http_session (PACKAGE_STRING);
  dep_data = flatpak_load_uri (http_session, dep_url, 0, NULL, NULL, NULL, NULL, cancellable, error);
  if (dep_data == NULL)
    {
      g_prefix_error (error, _("Can't load dependent file %s: "), dep_url);
      return FALSE;
    }

  if (!g_key_file_load_from_data (dep_keyfile,
                                  g_bytes_get_data (dep_data, NULL),
                                  g_bytes_get_size (dep_data),
                                  0, &local_error))
    return flatpak_fail_error (error, FLATPAK_ERROR_INVALID_DATA, _("Invalid .flatpakrepo: %s"), local_error->message);

  if (out_keyfile)
    *out_keyfile = g_steal_pointer (&dep_keyfile);

  return TRUE;
}

static gboolean
handle_runtime_repo_deps (FlatpakTransaction *self,
                          const char         *id,
                          const char         *dep_url,
                          GKeyFile           *dep_keyfile,
                          GCancellable       *cancellable,
                          GError            **error)
{
  FlatpakTransactionPrivate *priv = flatpak_transaction_get_instance_private (self);
  g_autofree char *runtime_url = NULL;
  g_autofree char *new_remote = NULL;
  g_autofree char *basename = NULL;
  g_autoptr(GUri) uri = NULL;
  g_auto(GStrv) remotes = NULL;
  g_autoptr(GKeyFile) config = NULL;
  g_autoptr(GBytes) gpg_key = NULL;
  g_autofree char *group = NULL;
  char *t;
  int i;
  gboolean res;

  if (priv->disable_deps)
    return TRUE;

  g_assert (dep_keyfile != NULL);

  uri = g_uri_parse (dep_url, FLATPAK_HTTP_URI_FLAGS | G_URI_FLAGS_PARSE_RELAXED, NULL);
  basename = g_path_get_basename (g_uri_get_path (uri));
  /* Strip suffix */
  t = strchr (basename, '.');
  if (t != NULL)
    *t = 0;

  /* Find a free remote name */
  remotes = flatpak_dir_list_remotes (priv->dir, NULL, NULL);
  i = 0;
  do
    {
      g_clear_pointer (&new_remote, g_free);

      if (i == 0)
        new_remote = g_strdup (basename);
      else
        new_remote = g_strdup_printf ("%s-%d", basename, i);
      i++;
    }
  while (remotes != NULL && g_strv_contains ((const char * const *) remotes, new_remote));

  config = flatpak_parse_repofile (new_remote, FALSE, dep_keyfile, &gpg_key, NULL, error);
  if (config == NULL)
    {
      g_prefix_error (error, "Can't parse dependent file %s: ", dep_url);
      return FALSE;
    }

  /* See if it already exists */
  group = g_strdup_printf ("remote \"%s\"", new_remote);
  runtime_url = g_key_file_get_string (config, group, "url", NULL);
  g_assert (runtime_url != NULL);

  if (remote_is_already_configured (self, runtime_url))
    return TRUE;

  res = FALSE;
  g_signal_emit (self, signals[ADD_NEW_REMOTE], 0, FLATPAK_TRANSACTION_REMOTE_RUNTIME_DEPS,
                 id, new_remote, runtime_url, &res);
  if (res)
    {
      if (!flatpak_dir_modify_remote (priv->dir, new_remote, config, gpg_key, NULL, error))
        return FALSE;

      if (!flatpak_dir_recreate_repo (priv->dir, NULL, error))
        return FALSE;

      flatpak_installation_drop_caches (priv->installation, NULL, NULL);
    }

  return TRUE;
}

static gboolean
handle_runtime_repo_deps_from_keyfile (FlatpakTransaction *self,
                                       GKeyFile           *flatpakref_keyfile,
                                       const char         *runtime_repo_url,
                                       GKeyFile           *runtime_repo_keyfile,
                                       GCancellable       *cancellable,
                                       GError            **error)
{
  FlatpakTransactionPrivate *priv = flatpak_transaction_get_instance_private (self);
  g_autofree char *name = NULL;

  if (priv->disable_deps)
    return TRUE;

  name = g_key_file_get_string (flatpakref_keyfile, FLATPAK_REF_GROUP, FLATPAK_REF_NAME_KEY, NULL);
  if (name == NULL)
    return TRUE;

  return handle_runtime_repo_deps (self, name, runtime_repo_url, runtime_repo_keyfile, cancellable, error);
}

static gboolean
flatpak_transaction_resolve_flatpakrefs (FlatpakTransaction *self,
                                         GCancellable       *cancellable,
                                         GError            **error)
{
  FlatpakTransactionPrivate *priv = flatpak_transaction_get_instance_private (self);
  GList *l;

  for (l = priv->flatpakrefs; l != NULL; l = l->next)
    {
      GKeyFile *flatpakref = l->data;
      g_autofree char *remote = NULL;
      g_autofree char *runtime_repo_url = NULL;
      g_autoptr(FlatpakDecomposed) ref = NULL;
      g_autoptr(GKeyFile) runtime_repo_keyfile = NULL;

      if (!priv->disable_deps)
        {
          runtime_repo_url = g_key_file_get_string (flatpakref, FLATPAK_REF_GROUP,
                                                    FLATPAK_REF_RUNTIME_REPO_KEY, NULL);
          if (runtime_repo_url == NULL)
            g_warning ("Flatpakref file does not contain a %s", FLATPAK_REF_RUNTIME_REPO_KEY);
          else if (!load_flatpakrepo_file (self, runtime_repo_url, &runtime_repo_keyfile, cancellable, error))
            return FALSE;
        }

      /* Handle SuggestRemoteName before the runtime deps, because they might
       * be the same. Pass in the RuntimeRepo keyfile so its metadata can be
       * used in that case. */
      if (!handle_suggested_remote_name (self, flatpakref, runtime_repo_keyfile, error))
        return FALSE;

      if (runtime_repo_keyfile != NULL &&
          !handle_runtime_repo_deps_from_keyfile (self, flatpakref,
                                                  runtime_repo_url, runtime_repo_keyfile,
                                                  cancellable, error))
        return FALSE;

      if (!flatpak_dir_create_remote_for_ref_file (priv->dir, flatpakref, priv->default_arch,
                                                   &remote, NULL, &ref, error))
        return FALSE;

      /* Need to pick up the new config, in case it was applied in the system helper. */
      if (!flatpak_dir_recreate_repo (priv->dir, NULL, error))
        return FALSE;

      flatpak_installation_drop_caches (priv->installation, NULL, NULL);

      if (!flatpak_transaction_add_install (self, remote, flatpak_decomposed_get_ref (ref), NULL, error))
        return FALSE;
    }

  return TRUE;
}

static gboolean
handle_runtime_repo_deps_from_bundle (FlatpakTransaction *self,
                                      GFile              *file,
                                      GCancellable       *cancellable,
                                      GError            **error)
{
  FlatpakTransactionPrivate *priv = flatpak_transaction_get_instance_private (self);
  g_autofree char *dep_url = NULL;
  g_autoptr(FlatpakDecomposed) ref = NULL;
  g_autoptr(GVariant) metadata = NULL;
  g_autoptr(GKeyFile) runtime_repo_keyfile = NULL;
  g_autofree char *id = NULL;

  if (priv->disable_deps)
    return TRUE;

  metadata = flatpak_bundle_load (file,
                                  NULL,
                                  &ref,
                                  NULL,
                                  &dep_url,
                                  NULL,
                                  NULL,
                                  NULL,
                                  NULL,
                                  NULL);

  if (metadata == NULL || dep_url == NULL || ref == NULL)
    return TRUE;

  id = flatpak_decomposed_dup_id (ref);

  if (!load_flatpakrepo_file (self, dep_url, &runtime_repo_keyfile, cancellable, error))
    return FALSE;

  return handle_runtime_repo_deps (self, id, dep_url, runtime_repo_keyfile, cancellable, error);
}

static gboolean
flatpak_transaction_resolve_bundles (FlatpakTransaction *self,
                                     GCancellable       *cancellable,
                                     GError            **error)
{
  FlatpakTransactionPrivate *priv = flatpak_transaction_get_instance_private (self);
  GList *l;

  for (l = priv->bundles; l != NULL; l = l->next)
    {
      BundleData *data = l->data;
      g_autofree char *remote = NULL;
      g_autofree char *commit = NULL;
      g_autofree char *metadata = NULL;
      g_autoptr(FlatpakDecomposed) ref = NULL;
      gboolean created_remote;

      if (!handle_runtime_repo_deps_from_bundle (self, data->file, cancellable, error))
        return FALSE;

      if (!flatpak_dir_ensure_repo (priv->dir, cancellable, error))
        return FALSE;

      remote = flatpak_dir_ensure_bundle_remote (priv->dir, data->file, data->gpg_data,
                                                 &ref, &commit, &metadata, &created_remote,
                                                 NULL, error);
      if (remote == NULL)
        return FALSE;

      if (created_remote)
        flatpak_installation_drop_caches (priv->installation, NULL, NULL);

      if (!flatpak_transaction_add_ref (self, remote, ref, NULL, NULL, commit,
                                        FLATPAK_TRANSACTION_OPERATION_INSTALL_BUNDLE,
                                        data->file, NULL, metadata, FALSE, FALSE, NULL, error))
        return FALSE;
    }

  return TRUE;
}

static gboolean
flatpak_transaction_resolve_images (FlatpakTransaction *self,
                                    GCancellable       *cancellable,
                                    GError            **error)
{
  FlatpakTransactionPrivate *priv = flatpak_transaction_get_instance_private (self);
  GList *l;

  for (l = priv->images; l != NULL; l = l->next)
    {
      ImageData *data = l->data;
      g_autoptr(FlatpakImageSource) image_source = NULL;
      g_autofree char *remote = NULL;
      g_autoptr(FlatpakDecomposed) ref = NULL;
      const char *ref_label;
      const char *metadata_label;
      FlatpakTransactionOperation *op;
      g_autoptr(GBytes) deploy_data = NULL;

      image_source = flatpak_image_source_new_for_location (data->image_location,
                                                            cancellable, error);
      if (!image_source)
        return FALSE;

      ref_label = flatpak_image_source_get_ref (image_source);
      ref = flatpak_decomposed_new_from_ref (ref_label, error);
      if (ref == NULL)
        {
          g_prefix_error (error, "Cannot parse org.flatpak.ref label: ");
          return FALSE;
        }

      metadata_label = flatpak_image_source_get_metadata (image_source);
      if (metadata_label == NULL)
        return flatpak_fail_error (error, FLATPAK_ERROR_INVALID_DATA,
                                   "Image does not have org.flatpak.metadata label");

      deploy_data = flatpak_dir_get_deploy_data (priv->dir, ref, FLATPAK_DEPLOY_VERSION_ANY, cancellable, NULL);
      if (deploy_data != NULL)
        remote = g_strdup (flatpak_deploy_data_get_origin (deploy_data));

      if (remote == NULL)
        {
          gboolean created_remote;
          g_autofree char *id = flatpak_decomposed_dup_id (ref);

          remote = flatpak_dir_create_origin_remote (priv->dir, NULL /* url */, id,
                                                     NULL /* title */, ref_label,
                                                     NULL /* gpg_data */, NULL /* collection_id */,
                                                     &created_remote,
                                                     cancellable, error);
          if (!remote)
            return FALSE;

          if (created_remote)
            flatpak_installation_drop_caches (priv->installation, NULL, NULL);
        }

      if (!flatpak_transaction_add_ref (self, remote, ref, NULL, NULL, NULL,
                                        FLATPAK_TRANSACTION_OPERATION_INSTALL,
                                        NULL, image_source, metadata_label, FALSE, FALSE,
                                        &op, error))
        return FALSE;
    }

  return TRUE;
}

/**
 * flatpak_transaction_run:
 * @transaction: a #FlatpakTransaction
 * @cancellable: (nullable): a #GCancellable
 * @error: return location for an error
 *
 * Executes the transaction.
 *
 * During the course of the execution, various signals will get emitted.
 * The FlatpakTransaction::choose-remote-for-ref  and
 * #FlatpakTransaction::add-new-remote signals may get emitted while
 * resolving operations. #FlatpakTransaction::ready is emitted when
 * the transaction has been fully resolved, and #FlatpakTransaction::new-operation
 * and #FlatpakTransaction::operation-done are emitted while the operations
 * are carried out. If an error occurs at any point during the execution,
 * #FlatpakTransaction::operation-error is emitted.
 *
 * Note that this call blocks until the transaction is done.
 *
 * Returns: %TRUE on success, %FALSE if an error occurred
 */
gboolean
flatpak_transaction_run (FlatpakTransaction *transaction,
                         GCancellable       *cancellable,
                         GError            **error)
{
  return FLATPAK_TRANSACTION_GET_CLASS (transaction)->run (transaction, cancellable, error);
}

static gboolean
_run_op_kind (FlatpakTransaction           *self,
              FlatpakTransactionOperation  *op,
              FlatpakRemoteState           *remote_state, /* nullable */
              gboolean                     *out_needs_prune,
              gboolean                     *out_needs_triggers,
              gboolean                     *out_needs_cache_drop,
              GCancellable                 *cancellable,
              GError                      **error)
{
  FlatpakTransactionPrivate *priv = flatpak_transaction_get_instance_private (self);
  gboolean res = TRUE;

  g_return_val_if_fail (remote_state != NULL || op->kind == FLATPAK_TRANSACTION_OPERATION_UNINSTALL, FALSE);

  if (op->kind == FLATPAK_TRANSACTION_OPERATION_INSTALL)
    {
      g_autoptr(FlatpakTransactionProgress) progress = flatpak_transaction_progress_new ();
      FlatpakTransactionResult result_details = 0;
      g_autoptr(GError) local_error = NULL;

      emit_new_op (self, op, progress);

      g_assert (op->resolved_commit != NULL || op->resolved_image_source != NULL); /* We resolved this before */

      if (op->resolved_metakey && !flatpak_check_required_version (flatpak_decomposed_get_ref (op->ref),
                                                                   op->resolved_metakey, &local_error))
        res = FALSE;
      else
        res = flatpak_dir_install (priv->dir,
                                   priv->no_pull,
                                   priv->no_deploy,
                                   priv->disable_static_deltas,
                                   priv->reinstall,
                                   priv->max_op >= APP_UPDATE,
                                   op->pin_on_deploy,
                                   op->update_preinstalled_on_deploy,
                                   remote_state, op->ref,
                                   op->resolved_commit,
                                   (const char **) op->subpaths,
                                   (const char **) op->previous_ids,
                                   op->resolved_sideload_path,
                                   op->resolved_image_source,
                                   op->resolved_metadata,
                                   op->resolved_token,
                                   progress->progress_obj,
                                   cancellable, &local_error);

      flatpak_transaction_progress_done (progress);

      /* Handle noop-installs (maybe we raced, or this was installed in install-authenticator)
       * We do initial checks and fail with already installed in add_ref() for other cases. */
      if (!res && g_error_matches (local_error, FLATPAK_ERROR, FLATPAK_ERROR_ALREADY_INSTALLED))
        {
          res = TRUE;
          g_clear_error (&local_error);

          result_details |= FLATPAK_TRANSACTION_RESULT_NO_CHANGE;
        }
      else if (!res)
        {
          g_propagate_error (error, g_steal_pointer (&local_error));
        }

      if (res)
        {
          emit_op_done (self, op, result_details);

          /* Normally we don't need to prune after install, because it makes no old objects
             stale. However if we reinstall, that is not true. */
          if (!priv->no_pull && priv->reinstall)
            *out_needs_prune = TRUE;

          if (flatpak_decomposed_is_app (op->ref))
            *out_needs_triggers = TRUE;

          if (op->pin_on_deploy|| op->update_preinstalled_on_deploy)
            *out_needs_cache_drop = TRUE;
        }
    }
  else if (op->kind == FLATPAK_TRANSACTION_OPERATION_UPDATE)
    {
      g_assert (op->resolved_commit != NULL); /* We resolved this before */

      if (flatpak_dir_needs_update_for_commit_and_subpaths (priv->dir, op->remote, op->ref,
                                                            op->resolved_commit, (const char **) op->subpaths))
        {
          g_autoptr(FlatpakTransactionProgress) progress = flatpak_transaction_progress_new ();
          FlatpakTransactionResult result_details = 0;
          g_autoptr(GError) local_error = NULL;

          emit_new_op (self, op, progress);

          if (op->resolved_metakey && !flatpak_check_required_version (flatpak_decomposed_get_ref (op->ref),
                                                                       op->resolved_metakey, &local_error))
            res = FALSE;
          else if (op->update_only_deploy)
            res = flatpak_dir_deploy_update (priv->dir, op->ref,
                                             op->resolved_commit,
                                             (const char **) op->subpaths,
                                             (const char **) op->previous_ids,
                                             cancellable, &local_error);
          else
            res = flatpak_dir_update (priv->dir,
                                      priv->no_pull,
                                      priv->no_deploy,
                                      priv->disable_static_deltas,
                                      op->commit != NULL, /* Allow downgrade if we specify commit */
                                      priv->max_op >= APP_UPDATE,
                                      priv->max_op == APP_INSTALL || priv->max_op == RUNTIME_INSTALL,
                                      remote_state,
                                      op->ref,
                                      op->resolved_commit,
                                      (const char **) op->subpaths,
                                      (const char **) op->previous_ids,
                                      op->resolved_sideload_path,
                                      op->resolved_image_source,
                                      op->resolved_metadata,
                                      op->resolved_token,
                                      progress->progress_obj,
                                      cancellable, &local_error);
          flatpak_transaction_progress_done (progress);

          /* Handle noop-updates */
          if (!res && g_error_matches (local_error, FLATPAK_ERROR, FLATPAK_ERROR_ALREADY_INSTALLED))
            {
              res = TRUE;
              g_clear_error (&local_error);

              result_details |= FLATPAK_TRANSACTION_RESULT_NO_CHANGE;
            }
          else if (!res)
            {
              g_propagate_error (error, g_steal_pointer (&local_error));
            }

          if (res)
            {
              emit_op_done (self, op, result_details);

              if (!priv->no_pull)
                *out_needs_prune = TRUE;

              if (flatpak_decomposed_is_app (op->ref))
                *out_needs_triggers = TRUE;
            }
        }
      else
        g_info ("%s need no update", flatpak_decomposed_get_ref (op->ref));
    }
  else if (op->kind == FLATPAK_TRANSACTION_OPERATION_INSTALL_BUNDLE)
    {
      g_autoptr(FlatpakTransactionProgress) progress = flatpak_transaction_progress_new ();
      emit_new_op (self, op, progress);
      if (op->resolved_metakey && !flatpak_check_required_version (flatpak_decomposed_get_ref (op->ref),
                                                                   op->resolved_metakey, error))
        res = FALSE;
      else
        res = flatpak_dir_install_bundle (priv->dir, priv->reinstall, op->bundle,
                                          op->remote, NULL,
                                          cancellable, error);
      flatpak_transaction_progress_done (progress);

      if (res)
        {
          emit_op_done (self, op, 0);
          *out_needs_prune = TRUE;
          *out_needs_triggers = TRUE;
        }
    }
  else if (op->kind == FLATPAK_TRANSACTION_OPERATION_UNINSTALL)
    {
      g_autoptr(FlatpakTransactionProgress) progress = flatpak_transaction_progress_new ();
      FlatpakHelperUninstallFlags flags = 0;

      if (priv->disable_prune)
        flags |= FLATPAK_HELPER_UNINSTALL_FLAGS_KEEP_REF;

      if (priv->force_uninstall)
        flags |= FLATPAK_HELPER_UNINSTALL_FLAGS_FORCE_REMOVE;

      if (op->update_preinstalled_on_deploy)
        flags |= FLATPAK_HELPER_UNINSTALL_FLAGS_UPDATE_PREINSTALLED;

      emit_new_op (self, op, progress);

      res = flatpak_dir_uninstall (priv->dir, op->ref, flags,
                                   cancellable, error);

      flatpak_transaction_progress_done (progress);

      if (res)
        {
          emit_op_done (self, op, 0);
          *out_needs_prune = TRUE;

          if (flatpak_decomposed_is_app (op->ref))
            *out_needs_triggers = TRUE;
        }
    }
  else
    g_assert_not_reached ();

  return res;
}

/* Ensure the operation kind is normalized and not no-op */
static void
flatpak_transaction_normalize_ops (FlatpakTransaction *self)
{
  FlatpakTransactionPrivate *priv = flatpak_transaction_get_instance_private (self);
  GList *l, *next;

  for (l = priv->ops; l != NULL; l = next)
    {
      FlatpakTransactionOperation *op = l->data;
      next = l->next;

      if (op->kind == FLATPAK_TRANSACTION_OPERATION_INSTALL_OR_UPDATE)
        {
          g_autoptr(GBytes) deploy_data = NULL;

          if (dir_ref_is_installed (priv->dir, op->ref, NULL, &deploy_data))
            {
              /* The remote should have already been set to the installed ref
               * origin so that the resolved commit definitely exists there */
              g_assert (g_strcmp0 (op->remote, flatpak_deploy_data_get_origin (deploy_data)) == 0);

              op->kind = FLATPAK_TRANSACTION_OPERATION_UPDATE;
            }
          else
            op->kind = FLATPAK_TRANSACTION_OPERATION_INSTALL;
        }

      if (op->kind == FLATPAK_TRANSACTION_OPERATION_UPDATE &&
          !flatpak_dir_needs_update_for_commit_and_subpaths (priv->dir, op->remote, op->ref,
                                                             op->resolved_commit, (const char **) op->subpaths))
        {
          /* If this is a rebase, then at minimum a redeploy needs to happen */
          if (op->previous_ids)
            op->update_only_deploy = TRUE;
          else
            op->skip = TRUE;
        }
    }
}

static gboolean
add_uninstall_unused_ops (FlatpakTransaction  *self,
                          GCancellable        *cancellable,
                          GError             **error)
{
  FlatpakTransactionPrivate *priv = flatpak_transaction_get_instance_private (self);
  g_autoptr(GHashTable) metadata_injection = NULL;
  g_autoptr(GHashTable) eol_injection = NULL;
  g_autoptr(GPtrArray) to_be_excluded = NULL;
  g_auto(GStrv) old_unused_refs = NULL;
  g_auto(GStrv) unused_refs = NULL;
  const char * const *to_be_excluded_strv = NULL;
  GList *l, *next;
  int i;

  if (priv->disable_deps)
    return TRUE;

  if (!priv->include_unused_uninstall_ops)
    {
      old_unused_refs = flatpak_dir_list_unused_refs (priv->dir,
                                                      NULL, /* arch */
                                                      NULL, /* metadata_injection */
                                                      NULL, /* eol_injection */
                                                      NULL, /* exclude_refs */
                                                      FLATPAK_DIR_FILTER_EOL | FLATPAK_DIR_FILTER_AUTOPRUNE,
                                                      cancellable, error);
      if (old_unused_refs == NULL)
        return FALSE;
    }

  /* This is a mapping from refs to #GKeyFile metadata objects, for each ref
   * being installed or updated by the transaction. This will allows us to
   * calculate what dependencies will be used after those operations are
   * executed. For example an app update may drop an extension point and
   * thereby make an installed extension become unused. */
  metadata_injection = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, NULL);

  eol_injection = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, NULL);

  /* This is the set of runtimes and apps scheduled for uninstallation and
   * which are therefore excluded when calculating used refs. */
  to_be_excluded = g_ptr_array_new ();

  for (l = priv->ops; l != NULL; l = next)
    {
      FlatpakTransactionOperation *op = l->data;
      FlatpakTransactionOperationType op_type = flatpak_transaction_operation_get_operation_type (op);

      next = l->next;

      if (op->skip)
        continue;

      g_assert (op_type == FLATPAK_TRANSACTION_OPERATION_UNINSTALL ||
                op_type == FLATPAK_TRANSACTION_OPERATION_INSTALL ||
                op_type == FLATPAK_TRANSACTION_OPERATION_INSTALL_BUNDLE ||
                op_type == FLATPAK_TRANSACTION_OPERATION_UPDATE);

      if (op_type == FLATPAK_TRANSACTION_OPERATION_UNINSTALL)
        g_ptr_array_add (to_be_excluded, (char *)flatpak_decomposed_get_ref (op->ref));
      else
        {
          if (op->resolved_metakey)
            g_hash_table_insert (metadata_injection, (char *)flatpak_decomposed_get_ref (op->ref), op->resolved_metakey);
          g_hash_table_insert (eol_injection, (char *)flatpak_decomposed_get_ref (op->ref),
                               GINT_TO_POINTER (op->eol != NULL || op->eol_rebase != NULL));
        }
    }

  if (to_be_excluded->len > 0)
    {
      g_ptr_array_add (to_be_excluded, NULL);
      to_be_excluded_strv = (const char * const *) to_be_excluded->pdata;
    }

  /* These are the refs that will be unused & eol after the transaction */
  unused_refs = flatpak_dir_list_unused_refs (priv->dir,
                                              NULL, /* arch */
                                              metadata_injection,
                                              eol_injection,
                                              to_be_excluded_strv,
                                              FLATPAK_DIR_FILTER_EOL | FLATPAK_DIR_FILTER_AUTOPRUNE,
                                              cancellable, error);
  if (unused_refs == NULL)
    return FALSE;

  /* Schedule each unused runtime to be uninstalled */
  for (i = 0; unused_refs[i] != NULL; i++)
    {
      FlatpakTransactionOperation *uninstall_op;
      const char *unused_ref_str = unused_refs[i];
      g_autoptr(FlatpakDecomposed) unused_ref = flatpak_decomposed_new_from_ref (unused_ref_str, NULL);
      g_autofree char *origin = NULL;

      if (unused_ref == NULL)
        continue;

      /* Don't uninstall refs that were already unused before the transaction (unless include_unused_uninstall_ops is set) */
      if (old_unused_refs &&
          g_strv_contains ((const char * const*)old_unused_refs, flatpak_decomposed_get_ref (unused_ref)))
        continue;

      origin = flatpak_dir_get_origin (priv->dir, unused_ref, NULL, NULL);
      if (origin)
        {
          if (priv->no_deploy)
            {
              g_info ("Skipping uninstallation of %s for no deploy transaction",
                      unused_ref_str);
              continue;
            }

          /* These get added last and have no dependencies, so will run last */
          uninstall_op = flatpak_transaction_add_op (self, origin, unused_ref,
                                                     NULL, NULL, NULL, NULL,
                                                     FLATPAK_TRANSACTION_OPERATION_UNINSTALL,
                                                     FALSE, FALSE);
          run_operation_last (uninstall_op);
        }
    }

  return TRUE;
}

static gboolean
flatpak_transaction_real_run (FlatpakTransaction *self,
                              GCancellable       *cancellable,
                              GError            **error)
{
  FlatpakTransactionPrivate *priv = flatpak_transaction_get_instance_private (self);
  GList *l;
  gboolean succeeded = TRUE;
  gboolean needs_prune = FALSE;
  gboolean needs_triggers = FALSE;
  gboolean needs_cache_drop = FALSE;
  gboolean ready_res = FALSE;
  int i;

  if (!priv->can_run)
    return flatpak_fail (error, _("Transaction already executed"));

  priv->can_run = FALSE;

  priv->current_op = NULL;

  if (flatpak_dir_is_user (priv->dir) && getuid () == 0)
    {
      struct stat st_buf;
      g_autofree char *dir_path = NULL;

      /* Check that it's not root's own user installation */
      dir_path = g_file_get_path (flatpak_dir_get_path (priv->dir));
      if (stat (dir_path, &st_buf) == 0 && st_buf.st_uid != 0)
        return flatpak_fail_error (error, FLATPAK_ERROR_WRONG_USER,
                                   _("Refusing to operate on a user installation as root! "
                                     "This can lead to incorrect file ownership and permission errors."));
    }

  if (!priv->no_pull &&
      !flatpak_transaction_update_metadata (self, cancellable, error))
    {
      g_assert (error == NULL || *error != NULL);
      return FALSE;
    }

  if (!flatpak_transaction_add_auto_install (self, cancellable, error))
    {
      g_assert (error == NULL || *error != NULL);
      return FALSE;
    }

  if (!flatpak_transaction_resolve_flatpakrefs (self, cancellable, error))
    {
      g_assert (error == NULL || *error != NULL);
      return FALSE;
    }

  if (!flatpak_transaction_resolve_bundles (self, cancellable, error))
    {
      g_assert (error == NULL || *error != NULL);
      return FALSE;
    }

  if (!flatpak_transaction_resolve_images (self, cancellable, error))
    {
      g_assert (error == NULL || *error != NULL);
      return FALSE;
    }

  /* Resolve initial ops */
  if (!resolve_all_ops (self, cancellable, error))
    {
      g_assert (error == NULL || *error != NULL);
      return FALSE;
    }

  /* Add all app -> runtime dependencies */
  for (l = priv->ops; l != NULL; l = l->next)
    {
      FlatpakTransactionOperation *op = l->data;

      if (!op->skip && !add_deps (self, op, error))
        {
          g_assert (error == NULL || *error != NULL);
          return FALSE;
        }
    }

  /* Resolve new ops */
  if (!resolve_all_ops (self, cancellable, error))
    {
      g_assert (error == NULL || *error != NULL);
      return FALSE;
    }

  /* Add all related extensions */
  for (l = priv->ops; l != NULL; l = l->next)
    {
      FlatpakTransactionOperation *op = l->data;

      if (!op->skip && !add_related (self, op, error))
        {
          g_assert (error == NULL || *error != NULL);
          return FALSE;
        }
    }

  /* Resolve new ops */
  if (!resolve_all_ops (self, cancellable, error))
    {
      g_assert (error == NULL || *error != NULL);
      return FALSE;
    }

  /* Ensure the operation kind is normalized and not no-op */
  flatpak_transaction_normalize_ops (self);

  /* Add uninstall ops for things that are made unused by this transaction (and
   * which match a heuristic). We don't need to do another round of
   * resolve_all_ops() since uninstalls don't require that.
   */
  if (!add_uninstall_unused_ops (self, cancellable, error))
    {
      g_assert (error == NULL || *error != NULL);
      return FALSE;
    }

  sort_ops (self);

  ready_res = FALSE;
  g_signal_emit (self, signals[READY_PRE_AUTH], 0, &ready_res);
  if (!ready_res)
    return flatpak_fail_error (error, FLATPAK_ERROR_ABORTED, _("Aborted by user"));

  /* Ensure we have all required tokens; we do this after all resolves if
   * possible to bunch requests. */
  if (!request_required_tokens (self, NULL, cancellable, error))
    {
      g_assert (error == NULL || *error != NULL);
      return FALSE;
    }

  ready_res = FALSE;
  g_signal_emit (self, signals[READY], 0, &ready_res);
  if (!ready_res)
    return flatpak_fail_error (error, FLATPAK_ERROR_ABORTED, _("Aborted by user"));

  for (l = priv->ops; l != NULL; l = l->next)
    {
      FlatpakTransactionOperation *op = l->data;
      g_autoptr(GError) local_error = NULL;
      gboolean res = TRUE;
      const char *pref;
      g_autoptr(FlatpakRemoteState) state = NULL;

      if (op->skip)
        continue;

      priv->current_op = op;

      pref = flatpak_decomposed_get_pref (op->ref);

      if (op->fail_if_op_fails && (op->fail_if_op_fails->failed) &&
          /* Allow installing an app if the runtime failed to update (i.e. is installed) because
           * the app should still run, and otherwise you could never install the app until the runtime
           * remote is fixed. */
          !(op->fail_if_op_fails->kind == FLATPAK_TRANSACTION_OPERATION_UPDATE &&
            flatpak_decomposed_is_app (op->ref)))
        {
          flatpak_fail_error (&local_error, FLATPAK_ERROR_SKIPPED,
                              _("Skipping %s due to previous error"), pref);
          res = FALSE;
        }
      else if (op->kind != FLATPAK_TRANSACTION_OPERATION_UNINSTALL &&
               (state = flatpak_transaction_ensure_remote_state (self, op->kind, op->remote, NULL, &local_error)) == NULL)
        {
          res = FALSE;
        }

      /* Here we execute the operation in a helper function */
      if (res && !_run_op_kind (self, op, state,
                                &needs_prune, &needs_triggers, &needs_cache_drop,
                                cancellable, &local_error))
        res = FALSE;

      if (res)
        {
          g_autoptr(GBytes) deploy_data = NULL;
          /* deploy v4 guarantees eol/eolr info */
          deploy_data = flatpak_dir_get_deploy_data (priv->dir, op->ref, 4, NULL, NULL);

          if (deploy_data)
            {
              const char *eol =  flatpak_deploy_data_get_eol (deploy_data);
              const char *eol_rebase = flatpak_deploy_data_get_eol_rebase (deploy_data);

              if (eol || eol_rebase)
                g_signal_emit (self, signals[END_OF_LIFED], 0,
                               flatpak_decomposed_get_ref (op->ref), eol, eol_rebase);
            }
        }

      if (!res)
        {
          gboolean do_cont = FALSE;
          FlatpakTransactionErrorDetails error_details = 0;

          op->failed = TRUE;

          if (op->non_fatal)
            error_details |= FLATPAK_TRANSACTION_ERROR_DETAILS_NON_FATAL;

          g_signal_emit (self, signals[OPERATION_ERROR], 0, op,
                         local_error, error_details,
                         &do_cont);

          if (!do_cont)
            {
              if (g_cancellable_set_error_if_cancelled (cancellable, error))
                {
                  succeeded = FALSE;
                  break;
                }

              flatpak_fail_error (error, FLATPAK_ERROR_ABORTED, _("Aborted due to failure (%s)"), local_error->message);
              succeeded = FALSE;
              break;
            }
        }
    }
  priv->current_op = NULL;

  if (needs_triggers)
    flatpak_dir_run_triggers (priv->dir, cancellable, NULL);

  if (needs_prune && !priv->disable_prune)
    flatpak_dir_prune (priv->dir, cancellable, NULL);

  for (i = 0; i < priv->added_origin_remotes->len; i++)
    flatpak_dir_prune_origin_remote (priv->dir, g_ptr_array_index (priv->added_origin_remotes, i));

  /* Reload config in case it changed via system helper */
  if (needs_cache_drop || priv->added_origin_remotes->len > 0)
    flatpak_installation_drop_caches (priv->installation, NULL, NULL);

  return succeeded;
}

===== ./common/flatpak-installation.c =====
/* vi:set et sw=2 sts=2 cin cino=t0,f0,(0,{s,>2s,n-s,^-s,e-s:
 * Copyright © 2015 Red Hat, Inc
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Alexander Larsson <alexl@redhat.com>
 */

#include "config.h"

#include <glib/gi18n-lib.h>

#include <string.h>

#include <ostree.h>
#include <ostree-repo-finder-avahi.h>

#include "flatpak-dir-private.h"
#include "flatpak-enum-types.h"
#include "flatpak-error.h"
#include "flatpak-installation-private.h"
#include "flatpak-installation.h"
#include "flatpak-installed-ref-private.h"
#include "flatpak-instance-private.h"
#include "flatpak-related-ref-private.h"
#include "flatpak-progress-private.h"
#include "flatpak-remote-private.h"
#include "flatpak-remote-ref-private.h"
#include "flatpak-run-private.h"
#include "flatpak-transaction-private.h"
#include "flatpak-utils-private.h"

/**
 * SECTION:flatpak-installation
 * @Title: FlatpakInstallation
 * @Short_description: Installation information
 * @See_also: FlatpakTransaction
 *
 * FlatpakInstallation is the toplevel object that software installers
 * should use to operate on an flatpak applications.
 *
 * An FlatpakInstallation object provides information about an installation
 * location for flatpak applications. Typical installation locations are either
 * system-wide (in $prefix/var/lib/flatpak) or per-user (in ~/.local/share/flatpak).
 *
 * FlatpakInstallation can list configured remotes as well as installed application
 * and runtime references (in short: refs), and it can add, remove and modify remotes.
 *
 * FlatpakInstallation can also run, install, update and uninstall applications and
 * runtimes, but #FlatpakTransaction is a better, high-level API for these tasks.
 *
 * To get a list of all configured installations, use flatpak_get_system_installations(),
 * together with flatpak_installation_new_user().
 *
 * The FlatpakInstallation API is threadsafe in the sense that it is safe to run two
 * operations at the same time, in different threads (or processes).
 */

typedef struct _FlatpakInstallationPrivate FlatpakInstallationPrivate;

G_LOCK_DEFINE_STATIC (dir);

struct _FlatpakInstallationPrivate
{
  /* All raw access to this should be protected by the dir lock. The FlatpakDir object is mostly
     threadsafe (apart from pull transactions being a singleton on it), however we replace it during
     flatpak_installation_drop_caches(), so every user needs to keep its own reference alive until
     done. */
  FlatpakDir *dir_unlocked;
  char       *display_name;
};

G_DEFINE_TYPE_WITH_PRIVATE (FlatpakInstallation, flatpak_installation, G_TYPE_OBJECT)

enum {
  PROP_0,
};

static void
flatpak_installation_finalize (GObject *object)
{
  FlatpakInstallation *self = FLATPAK_INSTALLATION (object);
  FlatpakInstallationPrivate *priv = flatpak_installation_get_instance_private (self);

  g_object_unref (priv->dir_unlocked);
  g_free (priv->display_name);

  G_OBJECT_CLASS (flatpak_installation_parent_class)->finalize (object);
}

static void
flatpak_installation_class_init (FlatpakInstallationClass *klass)
{
  GObjectClass *object_class = G_OBJECT_CLASS (klass);

  object_class->finalize = flatpak_installation_finalize;
}

static void
flatpak_installation_init (FlatpakInstallation *self)
{
}

static FlatpakInstallation *
flatpak_installation_new_steal_dir (FlatpakDir   *dir,
                                    GCancellable *cancellable,
                                    GError      **error)
{
  FlatpakInstallation *self;
  FlatpakInstallationPrivate *priv;

  if (!flatpak_dir_maybe_ensure_repo (dir, NULL, error))
    {
      g_object_unref (dir);
      return NULL;
    }

  self = g_object_new (FLATPAK_TYPE_INSTALLATION, NULL);
  priv = flatpak_installation_get_instance_private (self);

  priv->dir_unlocked = dir;

  return self;
}

FlatpakInstallation *
flatpak_installation_new_for_dir (FlatpakDir   *dir,
                                  GCancellable *cancellable,
                                  GError      **error)
{
  return flatpak_installation_new_steal_dir (g_object_ref (dir),
                                             cancellable,
                                             error);
}

/**
 * flatpak_installation_set_no_interaction:
 * @self: a #FlatpakInstallation
 * @no_interaction: Whether to disallow interactive authorization for operations
 *
 * This method can be used to prevent interactive authorization dialogs to appear
 * for operations on @self. This is useful for background operations that are not
 * directly triggered by a user action.
 *
 * By default, interaction is allowed.
 *
 * Since: 1.1.1
 */
void
flatpak_installation_set_no_interaction (FlatpakInstallation *self,
                                         gboolean             no_interaction)
{
  FlatpakInstallationPrivate *priv = flatpak_installation_get_instance_private (self);

  flatpak_dir_set_no_interaction (priv->dir_unlocked, no_interaction);
}

/**
 * flatpak_installation_get_no_interaction:
 * @self: a #FlatpakTransaction
 *
 * Returns the value set with flatpak_installation_set_no_interaction().
 *
 * Returns: %TRUE if interactive authorization dialogs are not allowed
 *
 * Since: 1.1.1
 */
gboolean
flatpak_installation_get_no_interaction (FlatpakInstallation *self)
{
  FlatpakInstallationPrivate *priv = flatpak_installation_get_instance_private (self);

  return flatpak_dir_get_no_interaction (priv->dir_unlocked);
}

/**
 * flatpak_get_default_arch:
 *
 * Returns the canonical name for the arch of the current machine.
 *
 * Returns: an arch string
 */
const char  *
flatpak_get_default_arch (void)
{
  return flatpak_get_arch ();
}

/**
 * flatpak_get_supported_arches:
 *
 * Returns the canonical names for the arches that are supported (i.e. can run)
 * on the current machine, in order of priority (default is first).
 *
 * Returns: a zero terminated array of arch strings
 */
const char * const *
flatpak_get_supported_arches (void)
{
  return (const char * const *) flatpak_get_arches ();
}

/**
 * flatpak_get_system_installations:
 * @cancellable: (nullable): a #GCancellable
 * @error: return location for a #GError
 *
 * Lists the system installations according to the current configuration and current
 * availability (e.g. doesn't return a configured installation if not reachable).
 *
 * Returns: (transfer container) (element-type FlatpakInstallation): a GPtrArray of
 *   #FlatpakInstallation instances
 *
 * Since: 0.8
 */
GPtrArray *
flatpak_get_system_installations (GCancellable *cancellable,
                                  GError      **error)
{
  g_autoptr(GPtrArray) system_dirs = NULL;
  g_autoptr(GPtrArray) installs = NULL;
  GPtrArray *ret = NULL;
  int i;

  system_dirs = flatpak_dir_get_system_list (cancellable, error);
  if (system_dirs == NULL)
    goto out;

  installs = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref);
  for (i = 0; i < system_dirs->len; i++)
    {
      g_autoptr(GError) local_error = NULL;
      FlatpakDir *install_dir = g_ptr_array_index (system_dirs, i);
      g_autoptr(FlatpakInstallation) installation = NULL;

      installation = flatpak_installation_new_for_dir (install_dir,
                                                       cancellable,
                                                       &local_error);
      if (installation != NULL)
        g_ptr_array_add (installs, g_steal_pointer (&installation));
      else
        {
          /* Warn about the problem and continue without listing this installation. */
          g_autofree char *dir_name = flatpak_dir_get_name (install_dir);
          g_warning ("Unable to create FlatpakInstallation for %s: %s",
                     dir_name, local_error->message);
        }
    }

  if (installs->len == 0)
    {
      g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND,
                   "No system installations found");
    }

  ret = g_steal_pointer (&installs);

out:
  return ret;
}

/**
 * flatpak_installation_new_system:
 * @cancellable: (nullable): a #GCancellable
 * @error: return location for a #GError
 *
 * Creates a new #FlatpakInstallation for the default system-wide installation.
 *
 * Returns: (transfer full): a new #FlatpakInstallation
 */
FlatpakInstallation *
flatpak_installation_new_system (GCancellable *cancellable,
                                 GError      **error)
{
  return flatpak_installation_new_steal_dir (flatpak_dir_get_system_default (), cancellable, error);
}

/**
 * flatpak_installation_new_system_with_id:
 * @id: (nullable): the ID of the system-wide installation
 * @cancellable: (nullable): a #GCancellable
 * @error: return location for a #GError
 *
 * Creates a new #FlatpakInstallation for the system-wide installation @id.
 *
 * Returns: (transfer full): a new #FlatpakInstallation
 *
 * Since: 0.8
 */
FlatpakInstallation *
flatpak_installation_new_system_with_id (const char   *id,
                                         GCancellable *cancellable,
                                         GError      **error)
{
  g_autoptr(FlatpakDir) install_dir = NULL;
  g_autoptr(FlatpakInstallation) installation = NULL;
  g_autoptr(GError) local_error = NULL;

  install_dir = flatpak_dir_get_system_by_id (id, cancellable, error);
  if (install_dir == NULL)
    return NULL;

  installation = flatpak_installation_new_for_dir (install_dir,
                                                   cancellable,
                                                   &local_error);
  if (installation == NULL)
    {
      g_info ("Error creating Flatpak installation: %s", local_error->message);
      g_propagate_error (error, g_steal_pointer (&local_error));
    }

  g_info ("Found Flatpak installation for '%s'", id);
  return g_steal_pointer (&installation);
}

/**
 * flatpak_installation_new_user:
 * @cancellable: (nullable): a #GCancellable
 * @error: return location for a #GError
 *
 * Creates a new #FlatpakInstallation for the per-user installation.
 *
 * Returns: (transfer full): a new #FlatpakInstallation
 */
FlatpakInstallation *
flatpak_installation_new_user (GCancellable *cancellable,
                               GError      **error)
{
  return flatpak_installation_new_steal_dir (flatpak_dir_get_user (), cancellable, error);
}

/**
 * flatpak_installation_new_for_path:
 * @path: a #GFile
 * @user: whether this is a user-specific location
 * @cancellable: (nullable): a #GCancellable
 * @error: return location for a #GError
 *
 * Creates a new #FlatpakInstallation for the installation at the given @path.
 *
 * Returns: (transfer full): a new #FlatpakInstallation
 */
FlatpakInstallation *
flatpak_installation_new_for_path (GFile *path, gboolean user,
                                   GCancellable *cancellable,
                                   GError **error)
{
  return flatpak_installation_new_steal_dir (flatpak_dir_new (path, user), cancellable, error);
}

static FlatpakDir *
_flatpak_installation_get_dir (FlatpakInstallation *self, gboolean ensure_repo, GError **error)
{
  FlatpakInstallationPrivate *priv = flatpak_installation_get_instance_private (self);
  FlatpakDir *dir;

  G_LOCK (dir);

  if (ensure_repo && flatpak_dir_get_repo (priv->dir_unlocked) == NULL)
    {
      if (!flatpak_dir_ensure_repo (priv->dir_unlocked, NULL, error))
        {
          dir = NULL;
          goto out;
        }
    }

  dir = g_object_ref (priv->dir_unlocked);

out:
  G_UNLOCK (dir);
  return dir;
}

FlatpakDir *
flatpak_installation_get_dir (FlatpakInstallation *self, GError **error)
{
  return _flatpak_installation_get_dir (self, TRUE, error);
}

static FlatpakDir *
flatpak_installation_get_dir_maybe_no_repo (FlatpakInstallation *self)
{
  return _flatpak_installation_get_dir (self, FALSE, NULL);
}

FlatpakDir *
flatpak_installation_clone_dir_noensure (FlatpakInstallation *self)
{
  g_autoptr(FlatpakDir) dir_clone = NULL;
  g_autoptr(FlatpakDir) dir = NULL;

  dir = flatpak_installation_get_dir_maybe_no_repo (self);

  /* Pull, prune, etc are not threadsafe, so we work on a copy */
  dir_clone = flatpak_dir_clone (dir);

  return g_steal_pointer (&dir_clone);
}

FlatpakDir *
flatpak_installation_clone_dir (FlatpakInstallation *self,
                                GCancellable        *cancellable,
                                GError             **error)
{
  g_autoptr(FlatpakDir) dir_clone = NULL;
  g_autoptr(FlatpakDir) dir = NULL;

  dir = flatpak_installation_get_dir (self, error);
  if (dir == NULL)
    return NULL;

  /* Pull, prune, etc are not threadsafe, so we work on a copy */
  dir_clone = flatpak_dir_clone (dir);
  if (!flatpak_dir_ensure_repo (dir_clone, cancellable, error))
    return NULL;

  return g_steal_pointer (&dir_clone);
}

/**
 * flatpak_installation_drop_caches:
 * @self: a #FlatpakInstallation
 * @cancellable: (nullable): a #GCancellable
 * @error: return location for a #GError
 *
 * Drops all internal (in-memory) caches. For instance, this may be needed to pick up new or changed
 * remotes configured outside this installation instance.
 *
 * Returns: %TRUE on success, %FALSE on error
 */
gboolean
flatpak_installation_drop_caches (FlatpakInstallation *self,
                                  GCancellable        *cancellable,
                                  GError             **error)
{
  FlatpakInstallationPrivate *priv = flatpak_installation_get_instance_private (self);
  FlatpakDir *clone, *old;
  gboolean res = FALSE;

  G_LOCK (dir);

  old = priv->dir_unlocked;
  clone = flatpak_dir_clone (priv->dir_unlocked);

  if (flatpak_dir_maybe_ensure_repo (clone, cancellable, error))
    {
      priv->dir_unlocked = clone;
      g_object_unref (old);
      res = TRUE;
    }

  G_UNLOCK (dir);

  return res;
}

/**
 * flatpak_installation_get_is_user:
 * @self: a #FlatpakInstallation
 *
 * Returns whether the installation is for a user-specific location.
 *
 * Returns: %TRUE if @self is a per-user installation
 */
gboolean
flatpak_installation_get_is_user (FlatpakInstallation *self)
{
  g_autoptr(FlatpakDir) dir = flatpak_installation_get_dir_maybe_no_repo (self);

  return flatpak_dir_is_user (dir);
}

/**
 * flatpak_installation_get_path:
 * @self: a #FlatpakInstallation
 *
 * Returns the installation location for @self.
 *
 * Returns: (transfer full): an #GFile
 */
GFile *
flatpak_installation_get_path (FlatpakInstallation *self)
{
  g_autoptr(FlatpakDir) dir = flatpak_installation_get_dir_maybe_no_repo (self);

  return g_object_ref (flatpak_dir_get_path (dir));
}

/**
 * flatpak_installation_get_id:
 * @self: a #FlatpakInstallation
 *
 * Returns the ID of the installation for @self.
 *
 * The ID for the default system installation is "default".
 * The ID for the user installation is "user".
 *
 * Returns: (transfer none): a string with the installation's ID
 *
 * Since: 0.8
 */
const char *
flatpak_installation_get_id (FlatpakInstallation *self)
{
  g_autoptr(FlatpakDir) dir = flatpak_installation_get_dir_maybe_no_repo (self);

  return flatpak_dir_get_id (dir);
}

/**
 * flatpak_installation_get_display_name:
 * @self: a #FlatpakInstallation
 *
 * Returns the display name of the installation for @self.
 *
 * Note that this function may return %NULL if the installation
 * does not have a display name.
 *
 * Returns: (transfer none): a string with the installation's display name
 *
 * Since: 0.8
 */
const char *
flatpak_installation_get_display_name (FlatpakInstallation *self)
{
  FlatpakInstallationPrivate *priv = flatpak_installation_get_instance_private (self);
  g_autoptr(FlatpakDir) dir = flatpak_installation_get_dir_maybe_no_repo (self);

  if (priv->display_name == NULL)
    priv->display_name = flatpak_dir_get_display_name (dir);

  return (const char *) priv->display_name;
}

/**
 * flatpak_installation_get_priority:
 * @self: a #FlatpakInstallation
 *
 * Returns the numeric priority of the installation for @self.
 *
 * Returns: an integer with the configured priority value
 *
 * Since: 0.8
 */
gint
flatpak_installation_get_priority (FlatpakInstallation *self)
{
  g_autoptr(FlatpakDir) dir = flatpak_installation_get_dir_maybe_no_repo (self);

  return flatpak_dir_get_priority (dir);
}

/**
 * flatpak_installation_get_storage_type:
 * @self: a #FlatpakInstallation
 *
 * Returns the type of storage of the installation for @self.
 *
 * Returns: a #FlatpakStorageType
 *
 * Since: 0.8
 */FlatpakStorageType
flatpak_installation_get_storage_type (FlatpakInstallation *self)
{
  g_autoptr(FlatpakDir) dir = flatpak_installation_get_dir_maybe_no_repo (self);

  switch (flatpak_dir_get_storage_type (dir))
    {
    case FLATPAK_DIR_STORAGE_TYPE_HARD_DISK:
      return FLATPAK_STORAGE_TYPE_HARD_DISK;

    case FLATPAK_DIR_STORAGE_TYPE_SDCARD:
      return FLATPAK_STORAGE_TYPE_SDCARD;

    case FLATPAK_DIR_STORAGE_TYPE_MMC:
      return FLATPAK_STORAGE_TYPE_MMC;

    case FLATPAK_DIR_STORAGE_TYPE_NETWORK:
      return FLATPAK_STORAGE_TYPE_NETWORK;

    default:
      return FLATPAK_STORAGE_TYPE_DEFAULT;
    }

  return FLATPAK_STORAGE_TYPE_DEFAULT;
}

/**
 * flatpak_installation_launch:
 * @self: a #FlatpakInstallation
 * @name: name of the app to launch
 * @arch: (nullable): which architecture to launch (default: current architecture)
 * @branch: (nullable): which branch of the application (default: "master")
 * @commit: (nullable): the commit of @branch to launch
 * @cancellable: (nullable): a #GCancellable
 * @error: return location for a #GError
 *
 * Launch an installed application.
 *
 * You can use flatpak_installation_get_installed_ref() or
 * flatpak_installation_get_current_installed_app() to find out what builds
 * are available, in order to get a value for @commit.
 *
 * Returns: %TRUE, unless an error occurred
 */
gboolean
flatpak_installation_launch (FlatpakInstallation *self,
                             const char          *name,
                             const char          *arch,
                             const char          *branch,
                             const char          *commit,
                             GCancellable        *cancellable,
                             GError             **error)
{
  return flatpak_installation_launch_full (self,
                                           FLATPAK_LAUNCH_FLAGS_NONE,
                                           name, arch, branch, commit,
                                           NULL,
                                           cancellable, error);
}

/**
 * flatpak_installation_launch_full:
 * @self: a #FlatpakInstallation
 * @flags: set of #FlatpakLaunchFlags
 * @name: name of the app to launch
 * @arch: (nullable): which architecture to launch (default: current architecture)
 * @branch: (nullable): which branch of the application (default: "master")
 * @commit: (nullable): the commit of @branch to launch
 * @instance_out: (nullable): return location for a #FlatpakInstance
 * @cancellable: (nullable): a #GCancellable
 * @error: return location for a #GError
 *
 * Launch an installed application.
 *
 * You can use flatpak_installation_get_installed_ref() or
 * flatpak_installation_get_current_installed_app() to find out what builds
 * are available, in order to get a value for @commit.
 *
 * Compared to flatpak_installation_launch(), this function returns a #FlatpakInstance
 * that can be used to get information about the running instance. You can also use
 * it to wait for the instance to be done with g_child_watch_add() if you pass the
 * #FLATPAK_LAUNCH_FLAGS_DO_NOT_REAP flag.
 *
 * Returns: %TRUE, unless an error occurred
 *
 * Since: 1.1
 */
gboolean
flatpak_installation_launch_full (FlatpakInstallation *self,
                                  FlatpakLaunchFlags   flags,
                                  const char          *name,
                                  const char          *arch,
                                  const char          *branch,
                                  const char          *commit,
                                  FlatpakInstance    **instance_out,
                                  GCancellable        *cancellable,
                                  GError             **error)
{
  g_auto(GStrv) run_environ = NULL;
  g_autoptr(FlatpakDir) dir = NULL;
  g_autoptr(FlatpakDeploy) app_deploy = NULL;
  g_autoptr(FlatpakDecomposed) app_ref = NULL;
  g_autofree char *instance_dir = NULL;
  FlatpakRunFlags run_flags;

  run_environ = g_get_environ ();

  dir = flatpak_installation_get_dir (self, error);
  if (dir == NULL)
    return FALSE;

  app_ref = flatpak_decomposed_new_from_parts (FLATPAK_KINDS_APP, name, arch, branch, error);
  if (app_ref == NULL)
    return FALSE;

  app_deploy =
    flatpak_dir_load_deployed (dir, app_ref,
                               commit,
                               cancellable, error);
  if (app_deploy == NULL)
    return FALSE;

  run_flags = FLATPAK_RUN_FLAG_BACKGROUND;
  if (flags & FLATPAK_LAUNCH_FLAGS_DO_NOT_REAP)
    run_flags |= FLATPAK_RUN_FLAG_DO_NOT_REAP;

  if (!flatpak_run_app (app_ref,
                        app_deploy,
                        FLATPAK_RUN_APP_DEPLOY_APP_ORIGINAL,
                        NULL,
                        NULL, NULL, NULL,
                        FLATPAK_RUN_APP_DEPLOY_USR_ORIGINAL,
                        0,
                        run_flags,
                        NULL,
                        NULL,
                        NULL, 0, -1,
                        (const char * const *) run_environ,
                        &instance_dir,
                        NULL, NULL,
                        cancellable, error))
    return FALSE;

  if (instance_out)
    *instance_out = flatpak_instance_new (instance_dir);

  return TRUE;
}


static FlatpakInstalledRef *
get_ref (FlatpakDir        *dir,
         FlatpakDecomposed *ref,
         GCancellable      *cancellable,
         GError            **error)
{
  const char *origin = NULL;
  const char *commit = NULL;
  const char *alt_id = NULL;
  g_autofree char *latest_alt_id = NULL;
  g_autoptr(GFile) deploy_dir = NULL;
  g_autoptr(GFile) deploy_subdir = NULL;
  g_autofree char *deploy_path = NULL;
  g_autofree char *latest_commit = NULL;
  g_autofree char *deploy_subdirname = NULL;
  g_autoptr(GBytes) deploy_data = NULL;
  g_autofree const char **subpaths = NULL;
  g_autofree char *collection_id = NULL;
  g_autoptr(GHashTable) content_rating = NULL;
  gboolean is_current = FALSE;
  guint64 installed_size = 0;

  deploy_data = flatpak_dir_get_deploy_data (dir, ref, FLATPAK_DEPLOY_VERSION_CURRENT, cancellable, error);
  if (deploy_data == NULL)
    return NULL;
  origin = flatpak_deploy_data_get_origin (deploy_data);
  commit = flatpak_deploy_data_get_commit (deploy_data);
  alt_id = flatpak_deploy_data_get_alt_id (deploy_data);
  subpaths = flatpak_deploy_data_get_subpaths (deploy_data);
  installed_size = flatpak_deploy_data_get_installed_size (deploy_data);

  deploy_dir = flatpak_dir_get_deploy_dir (dir, ref);
  deploy_subdirname = flatpak_dir_get_deploy_subdir (dir, commit, subpaths);
  deploy_subdir = g_file_get_child (deploy_dir, deploy_subdirname);
  deploy_path = g_file_get_path (deploy_subdir);

  if (flatpak_decomposed_is_app (ref))
    {
      g_autofree char *id = flatpak_decomposed_dup_id (ref);
      g_autoptr(FlatpakDecomposed) current = flatpak_dir_current_ref (dir, id, cancellable);
      if (current && flatpak_decomposed_equal (ref, current))
        is_current = TRUE;
    }

  latest_commit = flatpak_dir_read_latest (dir, origin, flatpak_decomposed_get_ref (ref), &latest_alt_id, NULL, NULL);

  collection_id = flatpak_dir_get_remote_collection_id (dir, origin);
  content_rating = flatpak_deploy_data_get_appdata_content_rating (deploy_data);

  return flatpak_installed_ref_new (ref,
                                    alt_id ? alt_id : commit,
                                    latest_alt_id ? latest_alt_id : latest_commit,
                                    origin, collection_id, subpaths,
                                    deploy_path,
                                    installed_size,
                                    is_current,
                                    flatpak_deploy_data_get_eol (deploy_data),
                                    flatpak_deploy_data_get_eol_rebase (deploy_data),
                                    flatpak_deploy_data_get_appdata_name (deploy_data),
                                    flatpak_deploy_data_get_appdata_summary (deploy_data),
                                    flatpak_deploy_data_get_appdata_version (deploy_data),
                                    flatpak_deploy_data_get_appdata_license (deploy_data),
                                    flatpak_deploy_data_get_appdata_content_rating_type (deploy_data),
                                    content_rating);
}

/**
 * flatpak_installation_get_installed_ref:
 * @self: a #FlatpakInstallation
 * @kind: whether this is an app or runtime
 * @name: name of the app/runtime to fetch
 * @arch: (nullable): which architecture to fetch (default: current architecture)
 * @branch: (nullable): which branch to fetch (default: "master")
 * @cancellable: (nullable): a #GCancellable
 * @error: return location for a #GError
 *
 * Returns information about an installed ref, such as the available builds,
 * its size, location, etc.
 *
 * Returns: (transfer full): an #FlatpakInstalledRef, or %NULL if an error occurred
 */
FlatpakInstalledRef *
flatpak_installation_get_installed_ref (FlatpakInstallation *self,
                                        FlatpakRefKind       kind,
                                        const char          *name,
                                        const char          *arch,
                                        const char          *branch,
                                        GCancellable        *cancellable,
                                        GError             **error)
{
  g_autoptr(FlatpakDir) dir = NULL;
  g_autoptr(GFile) deploy = NULL;
  g_autoptr(FlatpakDecomposed) ref = NULL;

  dir = flatpak_installation_get_dir (self, error);
  if (dir == NULL)
    return NULL;

  if (arch == NULL)
    arch = flatpak_get_arch ();

  ref = flatpak_decomposed_new_from_parts (flatpak_kinds_from_kind (kind), name, arch, branch, error);
  if (ref == NULL)
    return NULL;

  deploy = flatpak_dir_get_if_deployed (dir, ref, NULL, cancellable);
  if (deploy == NULL)
    {
      flatpak_fail_error (error, FLATPAK_ERROR_NOT_INSTALLED,
                          _("Ref %s not installed"), flatpak_decomposed_get_ref (ref));
      return NULL;
    }

  return get_ref (dir, ref, cancellable, error);
}

/**
 * flatpak_installation_get_current_installed_app:
 * @self: a #FlatpakInstallation
 * @name: the name of the app
 * @cancellable: (nullable): a #GCancellable
 * @error: return location for a #GError
 *
 * Get the last build of reference @name that was installed with
 * flatpak_installation_install(), or %NULL if the reference has
 * never been installed locally.
 *
 * Returns: (transfer full): an #FlatpakInstalledRef
 */
FlatpakInstalledRef *
flatpak_installation_get_current_installed_app (FlatpakInstallation *self,
                                                const char          *name,
                                                GCancellable        *cancellable,
                                                GError             **error)
{
  g_autoptr(FlatpakDir) dir = NULL;
  g_autoptr(GFile) deploy = NULL;
  g_autoptr(FlatpakDecomposed) current = NULL;

  dir = flatpak_installation_get_dir (self, error);
  if (dir == NULL)
    return NULL;

  current = flatpak_dir_current_ref (dir, name, cancellable);
  if (current)
    deploy = flatpak_dir_get_if_deployed (dir, current, NULL, cancellable);

  if (deploy == NULL)
    {
      flatpak_fail_error (error, FLATPAK_ERROR_NOT_INSTALLED,
                          _("App %s not installed"), name);
      return NULL;
    }

  return get_ref (dir, current, cancellable, error);
}

/**
 * flatpak_installation_list_installed_refs:
 * @self: a #FlatpakInstallation
 * @cancellable: (nullable): a #GCancellable
 * @error: return location for a #GError
 *
 * Lists the installed references.
 *
 * Returns: (transfer container) (element-type FlatpakInstalledRef): a GPtrArray of
 *   #FlatpakInstalledRef instances
 */
GPtrArray *
flatpak_installation_list_installed_refs (FlatpakInstallation *self,
                                          GCancellable        *cancellable,
                                          GError             **error)
{
  g_autoptr(FlatpakDir) dir = flatpak_installation_get_dir_maybe_no_repo (self);
  g_autoptr(GPtrArray) decomposed_app = NULL;
  g_autoptr(GPtrArray) decomposed_runtime = NULL;
  g_autoptr(GPtrArray) refs = g_ptr_array_new_with_free_func (g_object_unref);
  int i;

  decomposed_app = flatpak_dir_list_refs (dir, FLATPAK_KINDS_APP,
                                          cancellable, error);
  if (decomposed_app == NULL)
    return NULL;

  for (i = 0; i < decomposed_app->len; i++)
    {
      g_autoptr(GError) local_error = NULL;
      FlatpakDecomposed *decomposed = g_ptr_array_index (decomposed_app, i);
      FlatpakInstalledRef *ref = get_ref (dir, decomposed, cancellable, &local_error);
      if (ref != NULL)
        g_ptr_array_add (refs, ref);
      else
        g_warning ("Unexpected failure getting ref for %s: %s", flatpak_decomposed_get_ref (decomposed), local_error->message);
    }

  decomposed_runtime = flatpak_dir_list_refs (dir,FLATPAK_KINDS_RUNTIME,
                                              cancellable, error);
  if (decomposed_runtime == NULL)
    return NULL;

  for (i = 0; i < decomposed_runtime->len; i++)
    {
      g_autoptr(GError) local_error = NULL;
      FlatpakDecomposed *decomposed = g_ptr_array_index (decomposed_runtime, i);
      FlatpakInstalledRef *ref = get_ref (dir, decomposed, cancellable, &local_error);
      if (ref != NULL)
        g_ptr_array_add (refs, ref);
      else
        g_warning ("Unexpected failure getting ref for %s: %s", flatpak_decomposed_get_ref (decomposed), local_error->message);
    }

  return g_steal_pointer (&refs);
}

/**
 * flatpak_installation_list_installed_refs_by_kind:
 * @self: a #FlatpakInstallation
 * @kind: the kind of installation
 * @cancellable: (nullable): a #GCancellable
 * @error: return location for a #GError
 *
 * Lists the installed references of a specific kind.
 *
 * Returns: (transfer container) (element-type FlatpakInstalledRef): a GPtrArray of
 *   #FlatpakInstalledRef instances
 */
GPtrArray *
flatpak_installation_list_installed_refs_by_kind (FlatpakInstallation *self,
                                                  FlatpakRefKind       kind,
                                                  GCancellable        *cancellable,
                                                  GError             **error)
{
  g_autoptr(FlatpakDir) dir = flatpak_installation_get_dir_maybe_no_repo (self);
  g_autoptr(GPtrArray) all_decomposed = NULL;
  g_autoptr(GPtrArray) refs = g_ptr_array_new_with_free_func (g_object_unref);
  int i;

  all_decomposed = flatpak_dir_list_refs (dir, flatpak_kinds_from_kind (kind),
                                          cancellable, error);
  if (all_decomposed == NULL)
    return NULL;

  for (i = 0; i < all_decomposed->len; i++)
    {
      FlatpakDecomposed *decomposed = g_ptr_array_index (all_decomposed, i);
      g_autoptr(GError) local_error = NULL;
      FlatpakInstalledRef *ref = get_ref (dir, decomposed, cancellable, &local_error);
      if (ref != NULL)
        g_ptr_array_add (refs, ref);
      else
        g_warning ("Unexpected failure getting ref for %s: %s", flatpak_decomposed_get_ref (decomposed), local_error->message);
    }

  return g_steal_pointer (&refs);
}

static gboolean
end_of_lifed_with_rebase (FlatpakTransaction *transaction,
                          const char         *remote,
                          const char         *ref,
                          const char         *reason,
                          const char         *rebased_to_ref,
                          const char        **previous_ids,
                          GPtrArray         **eol_rebase_refs)
{
  if (rebased_to_ref == NULL || remote == NULL)
    return FALSE;

  /* No need to call flatpak_transaction_add_rebase_and_uninstall() here since
   * we only care about what needs an update
   */
  g_ptr_array_add (*eol_rebase_refs, g_strdup (ref));
  return TRUE;
}

static gboolean
transaction_ready (FlatpakTransaction  *transaction,
                   GHashTable         **related_to_ops)
{
  GList *ops = flatpak_transaction_get_operations (transaction);

  for (GList *l = ops; l != NULL; l = l->next)
    {
      FlatpakTransactionOperation *op = l->data;
      GPtrArray *op_related_to_ops = flatpak_transaction_operation_get_related_to_ops (op);  /* (element-type FlatpakTransactionOperation) */
      FlatpakTransactionOperationType type = flatpak_transaction_operation_get_operation_type (op);

      /* There may be an uninstall op if a runtime will now be considered
       * unused after the updates
       */
      if (type == FLATPAK_TRANSACTION_OPERATION_UNINSTALL)
        {
          const char *ref = flatpak_transaction_operation_get_ref (op);
          g_info ("Update transaction wants to uninstall %s", ref);
          continue;
        }

      g_hash_table_insert (*related_to_ops,
                           g_object_ref (op),
                           op_related_to_ops ? g_ptr_array_ref (op_related_to_ops) : NULL);
    }

  g_list_free_full (ops, g_object_unref);

  /* Abort the transaction; we only wanted to know what it would do */
  return FALSE;
}

static gint
installed_ref_compare (gconstpointer _iref_a,
                       gconstpointer _iref_b)
{
  const FlatpakInstalledRef *iref_a = *(const FlatpakInstalledRef **)_iref_a;
  const FlatpakInstalledRef *iref_b = *(const FlatpakInstalledRef **)_iref_b;
  const char *ref_a = flatpak_ref_format_ref_cached (FLATPAK_REF (iref_a));
  const char *ref_b = flatpak_ref_format_ref_cached (FLATPAK_REF (iref_b));

  return strcmp (ref_a, ref_b);
}

/**
 * flatpak_installation_list_installed_refs_for_update:
 * @self: a #FlatpakInstallation
 * @cancellable: (nullable): a #GCancellable
 * @error: return location for a #GError
 *
 * Lists the installed apps and runtimes that have an update available, either
 * from the configured remote or locally available but not deployed (see
 * flatpak_transaction_set_no_deploy()).
 *
 * This also checks if any of #FlatpakInstalledRef has a missing #FlatpakRelatedRef
 * (which has `should-download` set to %TRUE) or runtime. If so, it adds the
 * ref to the returning #GPtrArray to pull in the #FlatpakRelatedRef or runtime
 * again via an update operation in #FlatpakTransaction.
 *
 * In case more than one app needs an update of the same runtime or extension,
 * this function will return all of those apps.
 *
 * Returns: (transfer container) (element-type FlatpakInstalledRef): a GPtrArray of
 *   #FlatpakInstalledRef instances, or %NULL on error
 */
GPtrArray *
flatpak_installation_list_installed_refs_for_update (FlatpakInstallation *self,
                                                     GCancellable        *cancellable,
                                                     GError             **error)
{
  g_autoptr(GPtrArray) installed_refs = NULL; /* (element-type FlatpakInstalledRef) */
  g_autoptr(GHashTable) installed_refs_hash = NULL; /* (element-type utf8 FlatpakInstalledRef) */
  g_autoptr(GPtrArray) installed_refs_for_update = NULL; /* (element-type FlatpakInstalledRef) */
  g_autoptr(GHashTable) installed_refs_for_update_set = NULL; /* (element-type utf8) */
  g_autoptr(GHashTable) related_to_ops = NULL; /* (element-type FlatpakTransactionOperation GPtrArray<FlatpakTransactionOperation>) */
  g_autoptr(GPtrArray) eol_rebase_refs = NULL; /* (element-type utf8) */
  g_autoptr(FlatpakTransaction) transaction = NULL;
  g_autoptr(GError) local_error = NULL;

  installed_refs = flatpak_installation_list_installed_refs (self, cancellable, error);
  if (installed_refs == NULL)
    return NULL;

  /* Here we use a FlatpakTransaction to determine what needs updating, and
   * abort it before actually doing the updates. This ensures we are consistent
   * with the CLI update command.
   */
  transaction = flatpak_transaction_new_for_installation (self, cancellable, error);
  if (transaction == NULL)
    return NULL;

  /* CLI transactions set this. */
  flatpak_transaction_add_default_dependency_sources (transaction);

  installed_refs_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);

  for (guint i = 0; i < installed_refs->len; i++)
    {
      FlatpakInstalledRef *installed_ref = g_ptr_array_index (installed_refs, i);
      const char *ref = flatpak_ref_format_ref_cached (FLATPAK_REF (installed_ref));

      /* This hash table will be used later for efficient search */
      g_hash_table_insert (installed_refs_hash, g_strdup (ref), installed_ref);

      if (flatpak_transaction_add_update (transaction, ref, NULL, NULL, &local_error))
        continue;

      if (g_error_matches (local_error, FLATPAK_ERROR, FLATPAK_ERROR_REMOTE_NOT_FOUND))
        {
          g_info ("%s: Unable to update %s: %s", G_STRFUNC, ref, local_error->message);
          g_clear_error (&local_error);
        }
      else
        {
          g_propagate_error (error, g_steal_pointer (&local_error));
          return NULL;
        }
    }

  eol_rebase_refs = g_ptr_array_new_with_free_func (g_free);
  related_to_ops = g_hash_table_new_full (g_direct_hash, g_direct_equal, g_object_unref, null_safe_g_ptr_array_unref);

  g_signal_connect (transaction, "end-of-lifed-with-rebase", G_CALLBACK (end_of_lifed_with_rebase), &eol_rebase_refs);
  g_signal_connect (transaction, "ready-pre-auth", G_CALLBACK (transaction_ready), &related_to_ops);

  flatpak_transaction_run (transaction, cancellable, &local_error);
  g_assert (local_error != NULL);
  if (!g_error_matches (local_error, FLATPAK_ERROR, FLATPAK_ERROR_ABORTED))
    {
      g_propagate_error (error, g_steal_pointer (&local_error));
      return NULL;
    }
  g_clear_error (&local_error);

  installed_refs_for_update = g_ptr_array_new_with_free_func (g_object_unref);
  installed_refs_for_update_set = g_hash_table_new (g_str_hash, g_str_equal);

  /* For each ref that would be affected by the transaction, if it is
   * installed, add it to the list to be returned and otherwise add the ref
   * that caused it be added. We need to cover all of the following cases:
   * 1. For an app or runtime that has an update available, add it to the list
   *    (including a locale extension which needs more subpaths downloaded).
   * 2. For an app or extension that has a missing runtime, add the
   *    app/extension to the list.
   * 3. For an app that's missing a "should-download" related ref, add the app
   *    to the list.
   */
  GLNX_HASH_TABLE_FOREACH_KV (related_to_ops,
                              FlatpakTransactionOperation *, op,
                              GPtrArray *, op_related_to_ops)
    {
      const char *op_ref = flatpak_transaction_operation_get_ref (op);
      FlatpakInstalledRef *installed_ref;

      /* Here we use the existing installed_refs_hash instead of get_ref()
       * since staying in memory should be more efficient than disk I/O
       */
      installed_ref = g_hash_table_lookup (installed_refs_hash, op_ref);
      if (installed_ref != NULL)
        {
          if (!g_hash_table_contains (installed_refs_for_update_set, op_ref))
            {
              g_hash_table_add (installed_refs_for_update_set, (char *)op_ref);
              g_info ("%s: Installed ref %s needs update", G_STRFUNC, op_ref);
              g_ptr_array_add (installed_refs_for_update,
                               g_object_ref (installed_ref));
            }
        }
      else
        {
          for (gsize i = 0; op_related_to_ops != NULL && i < op_related_to_ops->len; i++)
            {
              FlatpakTransactionOperation *related_to_op = g_ptr_array_index (op_related_to_ops, i);

              const char *related_op_ref = flatpak_transaction_operation_get_ref (related_to_op);
              if (!g_hash_table_contains (installed_refs_for_update_set, related_op_ref))
                {
                  installed_ref = g_hash_table_lookup (installed_refs_hash, related_op_ref);
                  if (installed_ref != NULL)
                    {
                      g_hash_table_add (installed_refs_for_update_set, (char *)related_op_ref);
                      g_info ("%s: Installed ref %s needs update", G_STRFUNC, related_op_ref);
                      g_ptr_array_add (installed_refs_for_update,
                                       g_object_ref (installed_ref));
                    }
                }
            }
        }

      /* Note: installed_ref could be NULL if for example op is installing a
       * related ref of a missing runtime.
       */
    }

  /* Also handle any renames since those won't be in related_to_ops */
  for (guint i = 0; i < eol_rebase_refs->len; i++)
    {
      const char *rebased_ref = g_ptr_array_index (eol_rebase_refs, i);
      FlatpakInstalledRef *installed_ref = g_hash_table_lookup (installed_refs_hash, rebased_ref);
      if (installed_ref != NULL)
        {
          if (!g_hash_table_contains (installed_refs_for_update_set, rebased_ref))
            {
              g_hash_table_add (installed_refs_for_update_set, (char *)rebased_ref);
              g_info ("%s: Installed ref %s needs update", G_STRFUNC, rebased_ref);
              g_ptr_array_add (installed_refs_for_update,
                               g_object_ref (installed_ref));
            }
        }
    }

  /* Remove non-determinism for the sake of the unit tests */
  g_ptr_array_sort (installed_refs_for_update, installed_ref_compare);

  return g_steal_pointer (&installed_refs_for_update);
}

/* Find all USB and LAN repositories which share the same collection ID as
 * @remote_name, and add a #FlatpakRemote to @remotes for each of them. The caller
 * must initialise @remotes. Returns %TRUE without modifying @remotes if the
 * given remote doesn’t have a collection ID configured or if the @dir doesn’t
 * have a repo.
 *
 * FIXME: If this were async, the parallelisation could be handled in the caller. */

/**
 * flatpak_installation_list_remotes_by_type:
 * @self: a #FlatpakInstallation
 * @types: (array length=num_types): an array of #FlatpakRemoteType
 * @num_types: the number of types provided in @types
 * @cancellable: (nullable): a #GCancellable
 * @error: return location for a #GError
 *
 * Lists only the remotes whose type is included in the @types argument.
 *
 * Since flatpak 1.7 this will never return any types except FLATPAK_REMOTE_TYPE_STATIC.
 * Equivalent functionality to FLATPAK_REMOTE_TYPE_USB can be had by listing remote refs
 * with FLATPAK_QUERY_FLAGS_ONLY_SIDELOADED.
 *
 * Returns: (transfer container) (element-type FlatpakRemote): a GPtrArray of
 *   #FlatpakRemote instances
 */
GPtrArray *
flatpak_installation_list_remotes_by_type (FlatpakInstallation     *self,
                                           const FlatpakRemoteType *types,
                                           gsize                    num_types,
                                           GCancellable            *cancellable,
                                           GError                 **error)
{
  g_autoptr(FlatpakDir) dir = flatpak_installation_get_dir_maybe_no_repo (self);
  g_autoptr(FlatpakDir) dir_clone = NULL;
  g_auto(GStrv) remote_names = NULL;
  g_autoptr(GPtrArray) remotes = g_ptr_array_new_with_free_func (g_object_unref);
  const guint NUM_FLATPAK_REMOTE_TYPES = 3;
  gboolean types_filter[NUM_FLATPAK_REMOTE_TYPES];
  gsize i;

  remote_names = flatpak_dir_list_remotes (dir, cancellable, error);
  if (remote_names == NULL)
    return NULL;

  /* We clone the dir here to make sure we re-read the latest ostree repo config, in case
     it has local changes */
  dir_clone = flatpak_dir_clone (dir);
  if (!flatpak_dir_maybe_ensure_repo (dir_clone, cancellable, error))
    return NULL;

  /* If NULL or an empty array of types is passed then we list all types */
  for (i = 0; i < NUM_FLATPAK_REMOTE_TYPES; ++i)
    {
      if (types != NULL && num_types != 0)
        types_filter[i] = FALSE;
      else
        types_filter[i] = TRUE;
    }

  for (i = 0; i < num_types; ++i)
    {
      g_return_val_if_fail (types[i] < NUM_FLATPAK_REMOTE_TYPES, NULL);
      types_filter[types[i]] = TRUE;
    }

  for (i = 0; remote_names[i] != NULL; ++i)
    {
      /* These days we only support static remotes */
      if (types_filter[FLATPAK_REMOTE_TYPE_STATIC])
        g_ptr_array_add (remotes, flatpak_remote_new_with_dir (remote_names[i],
                                                               dir_clone));
    }

  return g_steal_pointer (&remotes);
}

/**
 * flatpak_installation_list_remotes:
 * @self: a #FlatpakInstallation
 * @cancellable: (nullable): a #GCancellable
 * @error: return location for a #GError
 *
 * Lists the static remotes, in priority (highest first) order. For same
 * priority, an earlier added remote comes before a later added one.
 *
 * Returns: (transfer container) (element-type FlatpakRemote): a GPtrArray of
 *   #FlatpakRemote instances
 */
GPtrArray *
flatpak_installation_list_remotes (FlatpakInstallation *self,
                                   GCancellable        *cancellable,
                                   GError             **error)
{
  const FlatpakRemoteType types[] = { FLATPAK_REMOTE_TYPE_STATIC };

  return flatpak_installation_list_remotes_by_type (self, types, 1, cancellable, error);
}

/**
 * flatpak_installation_modify_remote:
 * @self: a #FlatpakInstallation
 * @remote: the modified #FlatpakRemote
 * @cancellable: (nullable): a #GCancellable
 * @error: return location for a #GError
 *
 * Saves changes in the @remote object.
 *
 * Returns: %TRUE if the modifications have been committed successfully
 */
gboolean
flatpak_installation_modify_remote (FlatpakInstallation *self,
                                    FlatpakRemote       *remote,
                                    GCancellable        *cancellable,
                                    GError             **error)
{
  g_autoptr(FlatpakDir) dir = flatpak_installation_get_dir_maybe_no_repo (self);
  g_autoptr(FlatpakDir) dir_clone = NULL;

  /* We clone the dir here to make sure we re-read the latest ostree repo config, in case
     it has local changes */
  dir_clone = flatpak_dir_clone (dir);
  if (!flatpak_dir_maybe_ensure_repo (dir_clone, cancellable, error))
    return FALSE;

  if (!flatpak_remote_commit (remote, dir_clone, cancellable, error))
    return FALSE;

  /* Make sure we pick up the new config */
  flatpak_installation_drop_caches (self, NULL, NULL);

  return TRUE;
}


/**
 * flatpak_installation_add_remote:
 * @self: a #FlatpakInstallation
 * @remote: the new #FlatpakRemote
 * @if_needed: if %TRUE, only add if it doesn't exists
 * @cancellable: (nullable): a #GCancellable
 * @error: return location for a #GError
 *
 * Adds a new @remote object to the set of remotes. This is similar
 * to flatpak_installation_modify_remote() for non-existing remote
 * names. However, if the named remote already exists then instead of
 * modifying it it fails with %FLATPAK_ERROR_ALREADY_INSTALLED, or if
 * @if_needed is true it silently succeeds without doing anything.
 *
 * As an exception to the last, if the local config has a filter defined,
 * but the new remote unsets the filter (for example, it comes from an
 * unfiltered .flatpakref via flatpak_remote_new_from_file()) the the local
 * remote filter gets reset. This is to allow the setup where there is a
 * default setup of a filtered remote, yet you can still use the standard
 * flatpakref file to get the full contents without getting two remotes.
 *
 * Returns: %TRUE if the modifications have been committed successfully
 * Since: 1.3.4
 */
gboolean
flatpak_installation_add_remote (FlatpakInstallation *self,
                                 FlatpakRemote       *remote,
                                 gboolean             if_needed,
                                 GCancellable        *cancellable,
                                 GError             **error)
{
  g_autoptr(FlatpakDir) dir = flatpak_installation_get_dir_maybe_no_repo (self);
  g_autoptr(FlatpakDir) dir_clone = NULL;

  /* We clone the dir here to make sure we re-read the latest ostree repo config, in case
     it has local changes */
  dir_clone = flatpak_dir_clone (dir);
  if (!flatpak_dir_maybe_ensure_repo (dir_clone, cancellable, error))
    return FALSE;

  if (flatpak_dir_has_remote (dir, flatpak_remote_get_name (remote), NULL))
    {
      if (!if_needed)
        return flatpak_fail_error (error, FLATPAK_ERROR_ALREADY_INSTALLED, _("Remote '%s' already exists"), flatpak_remote_get_name (remote));

      if (!flatpak_remote_commit_filter (remote, dir_clone, cancellable, error))
        return FALSE;

      return TRUE;
    }

  if (!flatpak_remote_commit (remote, dir_clone, cancellable, error))
    return FALSE;

  /* Make sure we pick up the new config */
  flatpak_installation_drop_caches (self, NULL, NULL);

  return TRUE;
}


/**
 * flatpak_installation_remove_remote:
 * @self: a #FlatpakInstallation
 * @name: the name of the remote to remove
 * @cancellable: (nullable): a #GCancellable
 * @error: return location for a #GError
 *
 * Removes the remote with the given name from the installation.
 *
 * Returns: %TRUE if the remote has been removed successfully
 */
gboolean
flatpak_installation_remove_remote (FlatpakInstallation *self,
                                    const char          *name,
                                    GCancellable        *cancellable,
                                    GError             **error)
{
  g_autoptr(FlatpakDir) dir = NULL;
  g_autoptr(FlatpakDir) dir_clone = NULL;

  dir = flatpak_installation_get_dir (self, error);
  if (dir == NULL)
    return FALSE;

  /* We clone the dir here to make sure we re-read the latest ostree repo config, in case
     it has local changes */
  dir_clone = flatpak_dir_clone (dir);
  if (!flatpak_dir_ensure_repo (dir_clone, cancellable, error))
    return FALSE;

  if (!flatpak_dir_remove_remote (dir, FALSE, name,
                                  cancellable, error))
    return FALSE;

  /* Make sure we pick up the new config */
  flatpak_installation_drop_caches (self, NULL, NULL);

  return TRUE;
}

/**
 * flatpak_installation_set_config_sync:
 * @self: a #FlatpakInstallation
 * @key: the name of the key to set
 * @value: the new value, or %NULL to unset
 * @cancellable: (nullable): a #GCancellable
 * @error: return location for a #GError
 *
 * Set a global configuration option for the installation, currently
 * the only supported keys are `languages`, which is a semicolon-separated
 * list of language codes like `"sv;en;pl"`, or `""` to mean all languages,
 * and `extra-languages`, which is a semicolon-separated list of locale
 * identifiers like `"en;en_DK;zh_HK.big5hkscs;uz_UZ.utf8@cyrillic"`.
 *
 * Returns: %TRUE if the option was set correctly
 */
gboolean
flatpak_installation_set_config_sync (FlatpakInstallation *self,
                                      const char          *key,
                                      const char          *value,
                                      GCancellable        *cancellable,
                                      GError             **error)
{
  g_autoptr(FlatpakDir) dir = NULL;
  g_autoptr(FlatpakDir) dir_clone = NULL;

  dir = flatpak_installation_get_dir (self, error);
  if (dir == NULL)
    return FALSE;

  /* We clone the dir here to make sure we re-read the latest ostree repo config, in case
     it has local changes */
  dir_clone = flatpak_dir_clone (dir);
  if (!flatpak_dir_ensure_repo (dir_clone, cancellable, error))
    return FALSE;

  if (!flatpak_dir_set_config (dir, key, value, error))
    return FALSE;

  /* Make sure we pick up the new config */
  flatpak_installation_drop_caches (self, NULL, NULL);

  return TRUE;
}

/**
 * flatpak_installation_get_config:
 * @self: a #FlatpakInstallation
 * @key: the name of the key to get
 * @cancellable: (nullable): a #GCancellable
 * @error: return location for a #GError
 *
 * Get a global configuration option for the installation, see
 * flatpak_installation_set_config_sync() for supported keys.
 *
 * Returns: The (newly allocated) value, or %NULL on error (%G_KEY_FILE_ERROR_KEY_NOT_FOUND error if key is not set)
 */
char *
flatpak_installation_get_config (FlatpakInstallation *self,
                                 const char          *key,
                                 GCancellable        *cancellable,
                                 GError             **error)
{
  g_autoptr(FlatpakDir) dir = NULL;

  dir = flatpak_installation_get_dir (self, error);
  if (dir == NULL)
    return NULL;

  return flatpak_dir_get_config (dir, key, error);
}

/**
 * flatpak_installation_get_default_languages:
 * @self: a #FlatpakInstallation
 * @error: return location for a #GError
 *
 * Get the default languages used by the installation to decide which
 * subpaths to install of locale extensions. This list may also be used
 * by frontends like GNOME Software to decide which language-specific apps
 * to display. An empty array means that all languages should be installed.
 *
 * Returns: (array zero-terminated=1) (element-type utf8) (transfer full):
 *   A possibly empty array of strings, or %NULL on error.
 * Since: 1.5.0
 */
char **
flatpak_installation_get_default_languages (FlatpakInstallation  *self,
                                            GError              **error)
{
  g_autoptr(FlatpakDir) dir = NULL;

  dir = flatpak_installation_get_dir (self, error);
  if (dir == NULL)
    return NULL;

  return flatpak_dir_get_locale_languages (dir);
}

/**
 * flatpak_installation_get_default_locales:
 * @self: a #FlatpakInstallation
 * @error: return location for a #GError
 *
 * Like flatpak_installation_get_default_languages() but includes territory
 * information (e.g. `en_US` rather than `en`) which may be included in the
 * `extra-languages` configuration.
 *
 * Strings returned by this function are in the format specified by
 * [`setlocale()`](man:setlocale): `language[_territory][.codeset][@modifier]`.
 *
 * Returns: (array zero-terminated=1) (element-type utf8) (transfer full):
 *   A possibly empty array of locale strings, or %NULL on error.
 * Since: 1.5.1
 */
char **
flatpak_installation_get_default_locales (FlatpakInstallation  *self,
                                          GError              **error)
{
  g_autoptr(FlatpakDir) dir = NULL;

  dir = flatpak_installation_get_dir (self, error);
  if (dir == NULL)
    return NULL;

  return flatpak_dir_get_locales (dir);
}

/**
 * flatpak_installation_get_min_free_space_bytes:
 * @self: a #FlatpakInstallation
 * @out_bytes: (out): Location to store the result
 * @error: Return location for a #GError
 *
 * Returns the min-free-space config value from the OSTree repository of this installation.
 *
 * Applications can use this value, together with information about the available
 * disk space and the size of pending updates or installs, to estimate whether a
 * pull operation will fail due to running out of disk space.
 *
 * Returns: %TRUE on success, or %FALSE on error.
 * Since: 1.1
 */
gboolean
flatpak_installation_get_min_free_space_bytes (FlatpakInstallation *self,
                                               guint64             *out_bytes,
                                               GError             **error)
{
  g_autoptr(FlatpakDir) dir = NULL;
  g_autoptr(FlatpakDir) dir_clone = NULL;

  dir = flatpak_installation_get_dir (self, NULL);
  if (dir == NULL)
    return FALSE;

  /* We clone the dir here to make sure we re-read the latest ostree repo config, in case
     it has local changes */
  dir_clone = flatpak_dir_clone (dir);
  if (!flatpak_dir_ensure_repo (dir_clone, NULL, error))
    return FALSE;

  return ostree_repo_get_min_free_space_bytes (flatpak_dir_get_repo (dir_clone), out_bytes, error);
}

/**
 * flatpak_installation_update_remote_sync:
 * @self: a #FlatpakInstallation
 * @name: the name of the remote to update
 * @cancellable: (nullable): a #GCancellable
 * @error: return location for a #GError
 *
 * Updates the local configuration of a remote repository by fetching
 * the related information from the summary file in the remote OSTree
 * repository and committing the changes to the local installation.
 *
 * Returns: %TRUE if the remote has been updated successfully
 *
 * Since: 0.6.13
 */
gboolean
flatpak_installation_update_remote_sync (FlatpakInstallation *self,
                                         const char          *name,
                                         GCancellable        *cancellable,
                                         GError             **error)
{
  g_autoptr(FlatpakDir) dir = NULL;
  g_autoptr(FlatpakDir) dir_clone = NULL;

  dir = flatpak_installation_get_dir (self, error);
  if (dir == NULL)
    return FALSE;

  /* We clone the dir here to make sure we re-read the latest ostree repo config, in case
     it has local changes */
  dir_clone = flatpak_dir_clone (dir);
  if (!flatpak_dir_ensure_repo (dir_clone, cancellable, error))
    return FALSE;

  if (!flatpak_dir_update_remote_configuration (dir, name, NULL, NULL, cancellable, error))
    return FALSE;

  /* Make sure we pick up the new config */
  flatpak_installation_drop_caches (self, NULL, NULL);

  return TRUE;
}

/**
 * flatpak_installation_get_remote_by_name:
 * @self: a #FlatpakInstallation
 * @name: a remote name
 * @cancellable: (nullable): a #GCancellable
 * @error: return location for a #GError
 *
 * Looks up a remote by name.
 *
 * Returns: (transfer full): a #FlatpakRemote instance, or %NULL with @error
 *   set
 */
FlatpakRemote *
flatpak_installation_get_remote_by_name (FlatpakInstallation *self,
                                         const gchar         *name,
                                         GCancellable        *cancellable,
                                         GError             **error)
{
  g_autoptr(FlatpakDir) dir = flatpak_installation_get_dir_maybe_no_repo (self);
  g_autoptr(FlatpakDir) dir_clone = NULL;

  if (!flatpak_dir_has_remote (dir, name, error))
    return NULL;

  /* We clone the dir here to make sure we re-read the latest ostree repo config, in case
     it has local changes */
  dir_clone = flatpak_dir_clone (dir);
  if (!flatpak_dir_ensure_repo (dir_clone, cancellable, error))
    return NULL;

  return flatpak_remote_new_with_dir (name, dir_clone);
}

/**
 * flatpak_installation_load_app_overrides:
 * @self: a #FlatpakInstallation
 * @app_id: an application id
 * @cancellable: (nullable): a #GCancellable
 * @error: return location for a #GError
 *
 * Loads the metadata overrides file for an application.
 *
 * Returns: (transfer full): the contents of the overrides files,
 *    or %NULL if an error occurred
 */
char *
flatpak_installation_load_app_overrides (FlatpakInstallation *self,
                                         const char          *app_id,
                                         GCancellable        *cancellable,
                                         GError             **error)
{
  g_autoptr(FlatpakDir) dir = NULL;
  char *metadata_contents;
  gsize metadata_size;

  dir = flatpak_installation_get_dir (self, error);
  if (dir == NULL)
    return NULL;

  metadata_contents = flatpak_dir_load_override (dir, app_id, &metadata_size, NULL, error);
  if (metadata_contents == NULL)
    return NULL;

  return metadata_contents;
}

/**
 * flatpak_installation_install_bundle:
 * @self: a #FlatpakInstallation
 * @file: a #GFile that is an flatpak bundle
 * @progress: (scope call) (closure progress_data) (nullable): progress callback
 * @progress_data: (nullable): user data passed to @progress
 * @cancellable: (nullable): a #GCancellable
 * @error: return location for a #GError
 *
 * This is an old deprecated function, you should use
 * #FlatpakTransaction and flatpak_transaction_add_install_bundle()
 * instead. It has a lot more interesting features.
 *
 * Install an application or runtime from an flatpak bundle file.
 * See flatpak-build-bundle(1) for how to create bundles.
 *
 * Returns: (transfer full): The ref for the newly installed app or %NULL on failure
 * Deprecated: 1.7.0: Use flatpak_transaction_add_install_bundle() instead.
 */
FlatpakInstalledRef *
flatpak_installation_install_bundle (FlatpakInstallation    *self,
                                     GFile                  *file,
                                     FlatpakProgressCallback progress,
                                     gpointer                progress_data,
                                     GCancellable           *cancellable,
                                     GError                **error)
{
  g_autoptr(FlatpakDir) dir = NULL;
  g_autoptr(FlatpakDir) dir_clone = NULL;
  g_autoptr(FlatpakDecomposed) ref = NULL;
  g_autofree char *remote = NULL;
  FlatpakInstalledRef *result = NULL;
  gboolean created_remote;

  dir = flatpak_installation_get_dir (self, error);
  if (dir == NULL)
    return NULL;

  remote = flatpak_dir_ensure_bundle_remote (dir, file, NULL, &ref, NULL, NULL, &created_remote, cancellable, error);
  if (remote == NULL)
    return NULL;

  /* Make sure we pick up the new config */
  if (created_remote)
    flatpak_installation_drop_caches (self, NULL, NULL);

  /* Pull, prune, etc are not threadsafe, so we work on a copy */
  dir_clone = flatpak_dir_clone (dir);
  if (!flatpak_dir_ensure_repo (dir_clone, cancellable, error))
    return NULL;

  if (!flatpak_dir_install_bundle (dir_clone, FALSE, file, remote, NULL,
                                   cancellable, error))
    return NULL;

  if (flatpak_decomposed_is_app (ref))
    flatpak_dir_run_triggers (dir_clone, cancellable, NULL);

  result = get_ref (dir, ref, cancellable, error);
  if (result == NULL)
    return NULL;

  return result;
}

/**
 * flatpak_installation_install_ref_file:
 * @self: a #FlatpakInstallation
 * @ref_file_data: The ref file contents
 * @cancellable: (nullable): a #GCancellable
 * @error: return location for a #GError
 *
 * This is an old deprecated function, you should use
 * #FlatpakTransaction and flatpak_transaction_add_install_flatpakref()
 * instead. It has a lot more interesting features.
 *
 * Creates a remote based on the passed in .flatpakref file contents
 * in @ref_file_data and returns the #FlatpakRemoteRef that can be used
 * to install it.
 *
 * Note, the #FlatpakRemoteRef will not have the commit field set, or other details, to
 * avoid unnecessary roundtrips. If you need that you have to resolve it
 * explicitly with flatpak_installation_fetch_remote_ref_sync ().
 *
 * Returns: (transfer full): a #FlatpakRemoteRef if the remote has been added successfully, %NULL
 * on error.
 *
 * Since: 0.6.10
 * Deprecated: 1.7.0: Use flatpak_transaction_add_install_flatpakref() instead.
 */
FlatpakRemoteRef *
flatpak_installation_install_ref_file (FlatpakInstallation *self,
                                       GBytes              *ref_file_data,
                                       GCancellable        *cancellable,
                                       GError             **error)
{
  g_autoptr(FlatpakDir) dir = NULL;
  g_autofree char *remote = NULL;
  g_autoptr(FlatpakDecomposed) ref = NULL;
  g_autofree char *collection_id = NULL;
  g_autoptr(GKeyFile) keyfile = g_key_file_new ();

  dir = flatpak_installation_get_dir (self, error);
  if (dir == NULL)
    return NULL;

  if (!g_key_file_load_from_data (keyfile, g_bytes_get_data (ref_file_data, NULL),
                                  g_bytes_get_size (ref_file_data),
                                  0, error))
    return FALSE;

  if (!flatpak_dir_create_remote_for_ref_file (dir, keyfile, NULL, &remote, &collection_id, &ref, error))
    return NULL;

  if (!flatpak_installation_drop_caches (self, cancellable, error))
    return NULL;

  return flatpak_remote_ref_new (ref, NULL, remote, collection_id, NULL);
}

/**
 * flatpak_installation_install_full:
 * @self: a #FlatpakInstallation
 * @flags: set of #FlatpakInstallFlags flag
 * @remote_name: name of the remote to use
 * @kind: what this ref contains (an #FlatpakRefKind)
 * @name: name of the app/runtime to fetch
 * @arch: (nullable): which architecture to fetch (default: current architecture)
 * @branch: (nullable): which branch to fetch (default: 'master')
 * @subpaths: (nullable) (array zero-terminated=1): A list of subpaths to fetch, or %NULL for everything
 * @progress: (scope call) (closure progress_data) (nullable): progress callback
 * @progress_data: (nullable): user data passed to @progress
 * @cancellable: (nullable): a #GCancellable
 * @error: return location for a #GError
 *
 * This is an old deprecated function, you should use
 * #FlatpakTransaction and flatpak_transaction_add_install()
 * instead. It has a lot more interesting features.
 *
 * Install a new application or runtime.
 *
 * Note that this function was originally written to always return a
 * #FlatpakInstalledRef. Since 0.9.13, passing
 * FLATPAK_INSTALL_FLAGS_NO_DEPLOY will only pull refs into the local flatpak
 * repository without deploying them, however this function will
 * be unable to provide information on the installed ref, so
 * FLATPAK_ERROR_ONLY_PULLED will be set and the caller must respond
 * accordingly.
 *
 * Returns: (transfer full): The ref for the newly installed app or %NULL on failure
 * Deprecated: 1.7.0: Use flatpak_transaction_add_install() instead.
 */
FlatpakInstalledRef *
flatpak_installation_install_full (FlatpakInstallation    *self,
                                   FlatpakInstallFlags     flags,
                                   const char             *remote_name,
                                   FlatpakRefKind          kind,
                                   const char             *name,
                                   const char             *arch,
                                   const char             *branch,
                                   const char * const     *subpaths,
                                   FlatpakProgressCallback progress_cb,
                                   gpointer                progress_data,
                                   GCancellable           *cancellable,
                                   GError                **error)
{
  g_autoptr(FlatpakDir) dir = NULL;
  g_autoptr(FlatpakDecomposed) ref = NULL;
  g_autoptr(FlatpakDir) dir_clone = NULL;
  g_autoptr(FlatpakProgress) progress = NULL;
  g_autoptr(GFile) deploy_dir = NULL;
  g_autoptr(FlatpakRemoteState) state = NULL;

  dir = flatpak_installation_get_dir (self, error);
  if (dir == NULL)
    return NULL;

  ref = flatpak_decomposed_new_from_parts (flatpak_kinds_from_kind (kind), name, arch, branch, error);
  if (ref == NULL)
    return NULL;

  deploy_dir = flatpak_dir_get_if_deployed (dir, ref, NULL, cancellable);
  if (deploy_dir != NULL)
    {
      flatpak_fail_error (error, FLATPAK_ERROR_ALREADY_INSTALLED,
                          _("%s branch %s already installed"), name, branch ? branch : "master");
      return NULL;
    }

  state = flatpak_dir_get_remote_state_optional (dir, remote_name, FALSE, cancellable, error);
  if (state == NULL)
    return NULL;

  /* Pull, prune, etc are not threadsafe, so we work on a copy */
  dir_clone = flatpak_dir_clone (dir);
  if (!flatpak_dir_ensure_repo (dir_clone, cancellable, error))
    return NULL;

  if (progress_cb)
      progress = flatpak_progress_new (progress_cb, progress_data);

  if (!flatpak_dir_install (dir_clone,
                            (flags & FLATPAK_INSTALL_FLAGS_NO_PULL) != 0,
                            (flags & FLATPAK_INSTALL_FLAGS_NO_DEPLOY) != 0,
                            (flags & FLATPAK_INSTALL_FLAGS_NO_STATIC_DELTAS) != 0,
                            FALSE, FALSE, FALSE, FALSE, state,
                            ref, NULL, (const char **) subpaths, NULL, NULL, NULL, NULL, NULL,
                            progress, cancellable, error))
    return NULL;

  if (!(flags & FLATPAK_INSTALL_FLAGS_NO_TRIGGERS) &&
      flatpak_decomposed_is_app (ref))
    flatpak_dir_run_triggers (dir_clone, cancellable, NULL);

  /* Note that if the caller sets FLATPAK_INSTALL_FLAGS_NO_DEPLOY we must
   * always return an error, as explained above. Otherwise get_ref will
   * always return an error. */
  if ((flags & FLATPAK_INSTALL_FLAGS_NO_DEPLOY) != 0)
    {
      flatpak_fail_error (error, FLATPAK_ERROR_ONLY_PULLED,
                          _("As requested, %s was only pulled, but not installed"), name);
      return NULL;
    }

  return get_ref (dir, ref, cancellable, error);
}

/**
 * flatpak_installation_install:
 * @self: a #FlatpakInstallation
 * @remote_name: name of the remote to use
 * @kind: what this ref contains (an #FlatpakRefKind)
 * @name: name of the app/runtime to fetch
 * @arch: (nullable): which architecture to fetch (default: current architecture)
 * @branch: (nullable): which branch to fetch (default: 'master')
 * @progress: (scope call) (closure progress_data) (nullable): progress callback
 * @progress_data: (nullable): user data passed to @progress
 * @cancellable: (nullable): a #GCancellable
 * @error: return location for a #GError
 *
 * This is an old deprecated function, you should use
 * #FlatpakTransaction and flatpak_transaction_add_install()
 * instead. It has a lot more interesting features.
 *
 * Install a new application or runtime.
 *
 * Note that this function was originally written to always return a
 * #FlatpakInstalledRef. Since 0.9.13, passing
 * FLATPAK_INSTALL_FLAGS_NO_DEPLOY will only pull refs into the local flatpak
 * repository without deploying them, however this function will
 * be unable to provide information on the installed ref, so
 * FLATPAK_ERROR_ONLY_PULLED will be set and the caller must respond
 * accordingly.
 *
 * Returns: (transfer full): The ref for the newly installed app or %NULL on failure
 * Deprecated: 1.7.0: Use flatpak_transaction_add_install() instead.
 */
FlatpakInstalledRef *
flatpak_installation_install (FlatpakInstallation    *self,
                              const char             *remote_name,
                              FlatpakRefKind          kind,
                              const char             *name,
                              const char             *arch,
                              const char             *branch,
                              FlatpakProgressCallback progress,
                              gpointer                progress_data,
                              GCancellable           *cancellable,
                              GError                **error)
{
  G_GNUC_BEGIN_IGNORE_DEPRECATIONS
  return flatpak_installation_install_full (self, FLATPAK_INSTALL_FLAGS_NONE,
                                            remote_name, kind, name, arch, branch,
                                            NULL, progress, progress_data,
                                            cancellable, error);
  G_GNUC_END_IGNORE_DEPRECATIONS
}

/**
 * flatpak_installation_update_full:
 * @self: a #FlatpakInstallation
 * @flags: set of #FlatpakUpdateFlags flag
 * @kind: whether this is an app or runtime
 * @name: name of the app or runtime to update
 * @arch: (nullable): architecture of the app or runtime to update (default: current architecture)
 * @branch: (nullable): name of the branch of the app or runtime to update (default: master)
 * @subpaths: (nullable) (array zero-terminated=1): A list of subpaths to fetch, or %NULL for everything
 * @progress: (scope call) (closure progress_data) (nullable): the callback
 * @progress_data: (nullable): user data passed to @progress
 * @cancellable: (nullable): a #GCancellable
 * @error: return location for a #GError
 *
 * This is an old deprecated function, you should use
 * #FlatpakTransaction and flatpak_transaction_add_update()
 * instead. It has a lot more interesting features.
 *
 * Update an application or runtime.
 *
 * If the specified package is not installed, then %FLATPAK_ERROR_NOT_INSTALLED
 * will be thrown.
 *
 * If no updates could be found on the remote end and the package is
 * already up to date, then %FLATPAK_ERROR_ALREADY_INSTALLED will be thrown.
 *
 * Returns: (transfer full): The ref for the newly updated app or %NULL on failure
 * Deprecated: 1.7.0: Use flatpak_transaction_add_update() instead.
 */
FlatpakInstalledRef *
flatpak_installation_update_full (FlatpakInstallation    *self,
                                  FlatpakUpdateFlags      flags,
                                  FlatpakRefKind          kind,
                                  const char             *name,
                                  const char             *arch,
                                  const char             *branch,
                                  const char * const     *subpaths,
                                  FlatpakProgressCallback progress_cb,
                                  gpointer                progress_data,
                                  GCancellable           *cancellable,
                                  GError                **error)
{
  g_autoptr(FlatpakDir) dir = NULL;
  g_autoptr(FlatpakDecomposed) ref = NULL;
  g_autoptr(GFile) deploy_dir = NULL;
  g_autoptr(FlatpakDir) dir_clone = NULL;
  g_autoptr(FlatpakProgress) progress = NULL;
  g_autofree char *remote_name = NULL;
  FlatpakInstalledRef *result = NULL;
  g_autofree char *target_commit = NULL;
  g_autoptr(FlatpakRemoteState) state = NULL;

  dir = flatpak_installation_get_dir (self, error);
  if (dir == NULL)
    return NULL;

  ref = flatpak_decomposed_new_from_parts (flatpak_kinds_from_kind (kind), name, arch, branch, error);
  if (ref == NULL)
    return NULL;

  deploy_dir = flatpak_dir_get_if_deployed (dir, ref, NULL, cancellable);
  if (deploy_dir == NULL)
    {
      flatpak_fail_error (error, FLATPAK_ERROR_NOT_INSTALLED,
                          _("%s branch %s is not installed"), name, flatpak_decomposed_get_branch (ref));
      return NULL;
    }

  remote_name = flatpak_dir_get_origin (dir, ref, cancellable, error);
  if (remote_name == NULL)
    return NULL;

  state = flatpak_dir_get_remote_state_optional (dir, remote_name, FALSE, cancellable, error);
  if (state == NULL)
    return NULL;

  target_commit = flatpak_dir_check_for_update (dir, state, ref, NULL,
                                                (const char **) subpaths,
                                                (flags & FLATPAK_UPDATE_FLAGS_NO_PULL) != 0,
                                                cancellable, error);
  if (target_commit == NULL)
    return NULL;

  /* Pull, prune, etc are not threadsafe, so we work on a copy */
  dir_clone = flatpak_dir_clone (dir);
  if (!flatpak_dir_ensure_repo (dir_clone, cancellable, error))
    return NULL;

  if (progress_cb)
    progress = flatpak_progress_new (progress_cb, progress_data);

  if (!flatpak_dir_update (dir_clone,
                           (flags & FLATPAK_UPDATE_FLAGS_NO_PULL) != 0,
                           (flags & FLATPAK_UPDATE_FLAGS_NO_DEPLOY) != 0,
                           (flags & FLATPAK_UPDATE_FLAGS_NO_STATIC_DELTAS) != 0,
                           FALSE, FALSE, FALSE, state,
                           ref, target_commit,
                           (const char **) subpaths, NULL, NULL, NULL, NULL, NULL,
                           progress, cancellable, error))
    return NULL;

  if (!(flags & FLATPAK_UPDATE_FLAGS_NO_TRIGGERS) &&
      flatpak_decomposed_is_app (ref))
    flatpak_dir_run_triggers (dir_clone, cancellable, NULL);

  result = get_ref (dir, ref, cancellable, error);
  if (result == NULL)
    return NULL;

  /* We don't get prunable objects if not pulling or if NO_PRUNE is passed */
  if (!(flags & FLATPAK_UPDATE_FLAGS_NO_PULL) && !(flags & FLATPAK_UPDATE_FLAGS_NO_PRUNE))
    flatpak_dir_prune (dir_clone, cancellable, NULL);

  return result;
}

/**
 * flatpak_installation_update:
 * @self: a #FlatpakInstallation
 * @flags: set of #FlatpakUpdateFlags flag
 * @kind: whether this is an app or runtime
 * @name: name of the app or runtime to update
 * @arch: (nullable): architecture of the app or runtime to update (default: current architecture)
 * @branch: (nullable): name of the branch of the app or runtime to update (default: master)
 * @progress: (scope call) (closure progress_data) (nullable): the callback
 * @progress_data: (nullable): user data passed to @progress
 * @cancellable: (nullable): a #GCancellable
 * @error: return location for a #GError
 *
 * This is an old deprecated function, you should use
 * #FlatpakTransaction and flatpak_transaction_add_update()
 * instead. It has a lot more interesting features.
 *
 * Update an application or runtime.
 *
 * If the specified package is not installed, then %FLATPAK_ERROR_NOT_INSTALLED
 * will be thrown.
 *
 * If no updates could be found on the remote end and the package is
 * already up to date, then %FLATPAK_ERROR_ALREADY_INSTALLED will be thrown.
 *
 * Returns: (transfer full): The ref for the newly updated app or %NULL on failure
 * Deprecated: 1.7.0: Use flatpak_transaction_add_update() instead.
 */
FlatpakInstalledRef *
flatpak_installation_update (FlatpakInstallation    *self,
                             FlatpakUpdateFlags      flags,
                             FlatpakRefKind          kind,
                             const char             *name,
                             const char             *arch,
                             const char             *branch,
                             FlatpakProgressCallback progress,
                             gpointer                progress_data,
                             GCancellable           *cancellable,
                             GError                **error)
{
  G_GNUC_BEGIN_IGNORE_DEPRECATIONS
  return flatpak_installation_update_full (self, flags, kind, name, arch,
                                           branch, NULL, progress, progress_data,
                                           cancellable, error);
  G_GNUC_END_IGNORE_DEPRECATIONS
}

/**
 * flatpak_installation_uninstall:
 * @self: a #FlatpakInstallation
 * @kind: what this ref contains (an #FlatpakRefKind)
 * @name: name of the app or runtime to uninstall
 * @arch: (nullable): architecture of the app or runtime to uninstall; if
 *  %NULL, flatpak_get_default_arch() is assumed
 * @branch: (nullable): name of the branch of the app or runtime to uninstall;
 *  if %NULL, `master` is assumed
 * @progress: (scope call) (closure progress_data) (nullable): the callback
 * @progress_data: (nullable): user data passed to @progress
 * @cancellable: (nullable): a #GCancellable
 * @error: return location for a #GError
 *
 * This is an old deprecated function, you should use
 * #FlatpakTransaction and flatpak_transaction_add_uninstall()
 * instead. It has a lot more interesting features.
 *
 * Uninstall an application or runtime.
 *
 * Returns: %TRUE on success
 * Deprecated: 1.7.0: Use flatpak_transaction_add_uninstall() instead.
 */
FLATPAK_EXTERN gboolean
flatpak_installation_uninstall (FlatpakInstallation    *self,
                                FlatpakRefKind          kind,
                                const char             *name,
                                const char             *arch,
                                const char             *branch,
                                FlatpakProgressCallback progress,
                                gpointer                progress_data,
                                GCancellable           *cancellable,
                                GError                **error)
{
  G_GNUC_BEGIN_IGNORE_DEPRECATIONS
  return flatpak_installation_uninstall_full (self, FLATPAK_UNINSTALL_FLAGS_NONE,
                                              kind, name, arch, branch,
                                              progress, progress_data,
                                              cancellable, error);
  G_GNUC_END_IGNORE_DEPRECATIONS
}

/**
 * flatpak_installation_uninstall_full:
 * @self: a #FlatpakInstallation
 * @flags: set of #FlatpakUninstallFlags flags
 * @kind: what this ref contains (an #FlatpakRefKind)
 * @name: name of the app or runtime to uninstall
 * @arch: (nullable): architecture of the app or runtime to uninstall; if
 *  %NULL, flatpak_get_default_arch() is assumed
 * @branch: (nullable): name of the branch of the app or runtime to uninstall;
 *  if %NULL, `master` is assumed
 * @progress: (scope call) (closure progress_data) (nullable): the callback
 * @progress_data: (nullable): user data passed to @progress
 * @cancellable: (nullable): a #GCancellable
 * @error: return location for a #GError
 *
 * This is an old deprecated function, you should use
 * #FlatpakTransaction and flatpak_transaction_add_uninstall()
 * instead. It has a lot more interesting features.
 *
 * Uninstall an application or runtime.
 *
 * Returns: %TRUE on success
 *
 * Since: 0.11.8
 * Deprecated: 1.7.0: Use flatpak_transaction_add_uninstall() instead.
 */
gboolean
flatpak_installation_uninstall_full (FlatpakInstallation    *self,
                                     FlatpakUninstallFlags   flags,
                                     FlatpakRefKind          kind,
                                     const char             *name,
                                     const char             *arch,
                                     const char             *branch,
                                     FlatpakProgressCallback progress,
                                     gpointer                progress_data,
                                     GCancellable           *cancellable,
                                     GError                **error)
{
  g_autoptr(FlatpakDir) dir = NULL;
  g_autoptr(FlatpakDecomposed) ref = NULL;
  g_autoptr(FlatpakDir) dir_clone = NULL;

  dir = flatpak_installation_get_dir (self, error);
  if (dir == NULL)
    return FALSE;

  ref = flatpak_decomposed_new_from_parts (flatpak_kinds_from_kind (kind), name, arch, branch, error);
  if (ref == NULL)
    return FALSE;

  /* prune, etc are not threadsafe, so we work on a copy */
  dir_clone = flatpak_dir_clone (dir);
  if (!flatpak_dir_ensure_repo (dir_clone, cancellable, error))
    return FALSE;

  if (!flatpak_dir_uninstall (dir_clone, ref, FLATPAK_HELPER_UNINSTALL_FLAGS_NONE,
                              cancellable, error))
    return FALSE;

  if (!(flags & FLATPAK_UNINSTALL_FLAGS_NO_TRIGGERS) &&
      flatpak_decomposed_is_app (ref))
    flatpak_dir_run_triggers (dir_clone, cancellable, NULL);

  if (!(flags & FLATPAK_UNINSTALL_FLAGS_NO_PRUNE))
    flatpak_dir_prune (dir_clone, cancellable, NULL);

  return TRUE;
}

/**
 * flatpak_installation_fetch_remote_size_sync:
 * @self: a #FlatpakInstallation
 * @remote_name: the name of the remote
 * @ref: the ref
 * @download_size: (out): return location for the (maximum) download size
 * @installed_size: (out): return location for the installed size
 * @cancellable: (nullable): a #GCancellable
 * @error: return location for a #GError
 *
 * Gets information about the maximum amount of data that needs to be transferred
 * to pull the ref from a remote repository, and about the amount of
 * local disk space that is required to check out this commit.
 *
 * Note that if there are locally available data that are in the ref, which is common
 * for instance if you're doing an update then the real download size may be smaller
 * than what is returned here.
 *
 * NOTE: Since 0.11.4 this information is accessible in FlatpakRemoteRef, so this
 * function is not very useful anymore.
 *
 * Returns: %TRUE, unless an error occurred
 */
gboolean
flatpak_installation_fetch_remote_size_sync (FlatpakInstallation *self,
                                             const char          *remote_name,
                                             FlatpakRef          *ref,
                                             guint64             *download_size,
                                             guint64             *installed_size,
                                             GCancellable        *cancellable,
                                             GError             **error)
{
  g_autoptr(FlatpakDir) dir = NULL;
  g_autoptr(FlatpakRemoteState) state = NULL;
  const char *full_ref = flatpak_ref_format_ref_cached (ref);

  dir = flatpak_installation_get_dir (self, error);
  if (dir == NULL)
    return FALSE;

  state = flatpak_dir_get_remote_state_optional (dir, remote_name, FALSE, cancellable, error);
  if (state == NULL)
    return FALSE;

  return flatpak_remote_state_load_data (state, full_ref,
                                         download_size, installed_size, NULL,
                                         error);
}

/**
 * flatpak_installation_fetch_remote_metadata_sync:
 * @self: a #FlatpakInstallation
 * @remote_name: the name of the remote
 * @ref: the ref
 * @cancellable: (nullable): a #GCancellable
 * @error: return location for a #GError
 *
 * Obtains the metadata file from a commit.
 *
 * NOTE: Since 0.11.4 this information is accessible in FlatpakRemoteRef, so this
 * function is not very useful anymore.
 *
 * Returns: (transfer full): a #GBytes containing the flatpak metadata file,
 *   or %NULL if an error occurred
 */
GBytes *
flatpak_installation_fetch_remote_metadata_sync (FlatpakInstallation *self,
                                                 const char          *remote_name,
                                                 FlatpakRef          *ref,
                                                 GCancellable        *cancellable,
                                                 GError             **error)
{
  g_autoptr(FlatpakDir) dir = NULL;
  g_autoptr(FlatpakRemoteState) state = NULL;
  const char *full_ref = flatpak_ref_format_ref_cached (ref);
  g_autofree char *res = NULL;
  gsize len;

  dir = flatpak_installation_get_dir (self, error);
  if (dir == NULL)
    return NULL;

  state = flatpak_dir_get_remote_state_optional (dir, remote_name, FALSE, cancellable, error);
  if (state == NULL)
    return FALSE;

  if (!flatpak_remote_state_load_data (state, full_ref,
                                       NULL, NULL, &res,
                                       error))
    return NULL;

  len = strlen (res);
  return g_bytes_new_take (g_steal_pointer (&res), len);
}

/**
 * flatpak_installation_list_remote_refs_sync:
 * @self: a #FlatpakInstallation
 * @remote_or_uri: the name or URI of the remote
 * @cancellable: (nullable): a #GCancellable
 * @error: return location for a #GError
 *
 * Lists all the applications and runtimes in a remote.
 *
 * Returns: (transfer container) (element-type FlatpakRemoteRef): a GPtrArray of
 *   #FlatpakRemoteRef instances
 */
GPtrArray *
flatpak_installation_list_remote_refs_sync (FlatpakInstallation *self,
                                            const char          *remote_or_uri,
                                            GCancellable        *cancellable,
                                            GError             **error)
{
  return flatpak_installation_list_remote_refs_sync_full (self, remote_or_uri, 0, cancellable, error);
}

/**
 * flatpak_installation_list_remote_refs_sync_full:
 * @self: a #FlatpakInstallation
 * @remote_or_uri: the name or URI of the remote
 * @flags: set of #FlatpakQueryFlags
 * @cancellable: (nullable): a #GCancellable
 * @error: return location for a #GError
 *
 * Lists all the applications and runtimes in a remote.
 *
 * Returns: (transfer container) (element-type FlatpakRemoteRef): a GPtrArray of
 *   #FlatpakRemoteRef instances
 *
 * Since: 1.3.3
 */
GPtrArray *
flatpak_installation_list_remote_refs_sync_full (FlatpakInstallation *self,
                                                 const char          *remote_or_uri,
                                                 FlatpakQueryFlags    flags,
                                                 GCancellable        *cancellable,
                                                 GError             **error)
{
  g_autoptr(FlatpakDir) dir = NULL;
  g_autoptr(GPtrArray) refs = g_ptr_array_new_with_free_func (g_object_unref);
  g_autoptr(FlatpakRemoteState) state = NULL;
  g_autoptr(GHashTable) ht = NULL;
  g_autoptr(GError) local_error = NULL;
  GHashTableIter iter;
  gpointer key;
  gpointer value;
  gboolean only_sideloaded = (flags & FLATPAK_QUERY_FLAGS_ONLY_SIDELOADED) != 0;
  gboolean only_cached = (flags & FLATPAK_QUERY_FLAGS_ONLY_CACHED) != 0;
  gboolean all_arches = (flags & FLATPAK_QUERY_FLAGS_ALL_ARCHES) != 0;

  dir = flatpak_installation_get_dir (self, error);
  if (dir == NULL)
    return NULL;

  if (only_sideloaded)
    {
      state = flatpak_dir_get_remote_state_local_only (dir, remote_or_uri, cancellable, error);
      if (state == NULL)
        return NULL;
    }
  else
    {
      state = flatpak_dir_get_remote_state (dir, remote_or_uri, only_cached, cancellable, error);
      if (state == NULL)
        return NULL;

      if (all_arches &&
          !flatpak_remote_state_ensure_subsummary_all_arches (state, dir, only_cached, cancellable, error))
        return NULL;
    }

  if (!flatpak_dir_list_remote_refs (dir, state, &ht,
                                     cancellable, &local_error))
    {
      if (only_sideloaded)
        {
          /* Just return no sideloaded refs rather than a summary download failed error if there are none */
          return g_steal_pointer (&refs);
        }
      else
        {
          g_propagate_error (error, g_steal_pointer (&local_error));
          return NULL;
        }
    }

  g_hash_table_iter_init (&iter, ht);
  while (g_hash_table_iter_next (&iter, &key, &value))
    {
      FlatpakDecomposed *decomposed = key;
      const gchar *ref_commit = value;
      FlatpakRemoteRef *ref;

      ref = flatpak_remote_ref_new (decomposed, ref_commit, remote_or_uri, state->collection_id, state);

      if (ref)
        g_ptr_array_add (refs, ref);
    }

  return g_steal_pointer (&refs);
}

/**
 * flatpak_installation_fetch_remote_ref_sync:
 * @self: a #FlatpakInstallation
 * @remote_name: the name of the remote
 * @kind: what this ref contains (an #FlatpakRefKind)
 * @name: name of the app/runtime to fetch
 * @arch: (nullable): which architecture to fetch (default: current architecture)
 * @branch: (nullable): which branch to fetch (default: 'master')
 * @cancellable: (nullable): a #GCancellable
 * @error: return location for a #GError
 *
 * Gets the current remote branch of a ref in the remote.
 *
 * Returns: (transfer full): a #FlatpakRemoteRef instance, or %NULL
 */
FlatpakRemoteRef *
flatpak_installation_fetch_remote_ref_sync (FlatpakInstallation *self,
                                            const char          *remote_name,
                                            FlatpakRefKind       kind,
                                            const char          *name,
                                            const char          *arch,
                                            const char          *branch,
                                            GCancellable        *cancellable,
                                            GError             **error)
{
  return flatpak_installation_fetch_remote_ref_sync_full (self, remote_name,
                                                          kind, name, arch, branch, 0,
                                                          cancellable, error);
}

/**
 * flatpak_installation_fetch_remote_ref_sync_full:
 * @self: a #FlatpakInstallation
 * @remote_name: the name of the remote
 * @kind: what this ref contains (an #FlatpakRefKind)
 * @name: name of the app/runtime to fetch
 * @arch: (nullable): which architecture to fetch (default: current architecture)
 * @branch: (nullable): which branch to fetch (default: 'master')
 * @flags: set of #FlatpakQueryFlags
 * @cancellable: (nullable): a #GCancellable
 * @error: return location for a #GError
 *
 * Gets the current remote branch of a ref in the remote.
 *
 * Returns: (transfer full): a #FlatpakRemoteRef instance, or %NULL
 *
 * Since: 1.3.3
 */
FlatpakRemoteRef *
flatpak_installation_fetch_remote_ref_sync_full (FlatpakInstallation *self,
                                                 const char          *remote_name,
                                                 FlatpakRefKind       kind,
                                                 const char          *name,
                                                 const char          *arch,
                                                 const char          *branch,
                                                 FlatpakQueryFlags    flags,
                                                 GCancellable        *cancellable,
                                                 GError             **error)
{
  g_autoptr(FlatpakDir) dir = NULL;
  g_autoptr(GHashTable) ht = NULL;
  g_autoptr(FlatpakRemoteState) state = NULL;
  g_autoptr(FlatpakDecomposed) ref = NULL;
  const char *checksum;

  dir = flatpak_installation_get_dir (self, error);
  if (dir == NULL)
    return NULL;

  ref = flatpak_decomposed_new_from_parts (flatpak_kinds_from_kind (kind), name, arch, branch, error);
  if (ref == NULL)
    return NULL;

  if (flags & FLATPAK_QUERY_FLAGS_ONLY_SIDELOADED)
    state = flatpak_dir_get_remote_state_local_only (dir, remote_name, cancellable, error);
  else
    state = flatpak_dir_get_remote_state (dir, remote_name, (flags & FLATPAK_QUERY_FLAGS_ONLY_CACHED) != 0, cancellable, error);
  if (state == NULL)
    return NULL;

  if (!flatpak_dir_list_remote_refs (dir, state, &ht,
                                     cancellable, error))
    return NULL;

  checksum = g_hash_table_lookup (ht, ref);

  if (checksum != NULL)
    return flatpak_remote_ref_new (ref, checksum, remote_name, state->collection_id, state);

  g_set_error (error, FLATPAK_ERROR, FLATPAK_ERROR_REF_NOT_FOUND,
               "Reference %s doesn't exist in remote %s",
               flatpak_decomposed_get_ref (ref), remote_name);
  return NULL;
}

/**
 * flatpak_installation_update_appstream_sync:
 * @self: a #FlatpakInstallation
 * @remote_name: the name of the remote
 * @arch: (nullable): Architecture to update, or %NULL for the local machine arch
 * @out_changed: (nullable): Set to %TRUE if the contents of the appstream changed, %FALSE if nothing changed
 * @cancellable: (nullable): a #GCancellable
 * @error: return location for a #GError
 *
 * Updates the local copy of appstream for @remote_name for the specified @arch.
 * If you need progress feedback, use flatpak_installation_update_appstream_full_sync().
 *
 * Returns: %TRUE on success, or %FALSE on error
 */
gboolean
flatpak_installation_update_appstream_sync (FlatpakInstallation *self,
                                            const char          *remote_name,
                                            const char          *arch,
                                            gboolean            *out_changed,
                                            GCancellable        *cancellable,
                                            GError             **error)
{
  return flatpak_installation_update_appstream_full_sync (self, remote_name, arch,
                                                          NULL, NULL, out_changed,
                                                          cancellable, error);
}

/**
 * flatpak_installation_update_appstream_full_sync:
 * @self: a #FlatpakInstallation
 * @remote_name: the name of the remote
 * @arch: (nullable): Architecture to update, or %NULL for the local machine arch
 * @progress: (scope call) (closure progress_data) (nullable): progress callback
 * @progress_data: (nullable): user data passed to @progress
 * @out_changed: (nullable): Set to %TRUE if the contents of the appstream changed, %FALSE if nothing changed
 * @cancellable: (nullable): a #GCancellable
 * @error: return location for a #GError
 *
 * Updates the local copy of appstream for @remote_name for the specified @arch.
 *
 * Returns: %TRUE on success, or %FALSE on error
 */
gboolean
flatpak_installation_update_appstream_full_sync (FlatpakInstallation    *self,
                                                 const char             *remote_name,
                                                 const char             *arch,
                                                 FlatpakProgressCallback progress_cb,
                                                 gpointer                progress_data,
                                                 gboolean               *out_changed,
                                                 GCancellable           *cancellable,
                                                 GError                **error)
{
  g_autoptr(FlatpakDir) dir = NULL;
  g_autoptr(FlatpakDir) dir_clone = NULL;
  g_autoptr(FlatpakProgress) progress = NULL;

  dir = flatpak_installation_get_dir (self, error);
  if (dir == NULL)
    return FALSE;

  /* Pull, prune, etc are not threadsafe, so we work on a copy */
  dir_clone = flatpak_dir_clone (dir);
  if (!flatpak_dir_ensure_repo (dir_clone, cancellable, error))
    return FALSE;

  if (progress_cb)
    progress = flatpak_progress_new (progress_cb, progress_data);

  return flatpak_dir_update_appstream (dir_clone,
                                       remote_name,
                                       arch,
                                       out_changed,
                                       progress,
                                       cancellable,
                                       error);
}


/**
 * flatpak_installation_create_monitor:
 * @self: a #FlatpakInstallation
 * @cancellable: (nullable): a #GCancellable
 * @error: return location for a #GError
 *
 * Gets monitor object for the installation. The returned file monitor will
 * emit the #GFileMonitor::changed signal whenever an application or runtime
 * was installed, uninstalled or updated.
 *
 * Returns: (transfer full): a new #GFileMonitor instance, or %NULL on error
 */
GFileMonitor *
flatpak_installation_create_monitor (FlatpakInstallation *self,
                                     GCancellable        *cancellable,
                                     GError             **error)
{
  g_autoptr(FlatpakDir) dir = flatpak_installation_get_dir_maybe_no_repo (self);
  g_autoptr(GFile) path = NULL;

  path = flatpak_dir_get_changed_path (dir);

  return g_file_monitor_file (path, G_FILE_MONITOR_NONE,
                              cancellable, error);
}

/**
 * flatpak_installation_get_timestamp:
 * @self: a #FlatpakInstallation
 *
 * Gets the modification time of the installation, based on the file monitored by
 * flatpak_installation_create_monitor(). This can be used to detect when
 * applications or runtimes have been installed, uninstalled, or updated, or when
 * remotes have been added, removed, or modified, to aid cache invalidation.
 *
 * Returns: the modification time (seconds since the Unix epoch) of the
 *   installation configuration, or %G_MAXUINT64 if unavailable
 *
 * Since: 1.18.0
 */
guint64
flatpak_installation_get_timestamp (FlatpakInstallation *self)
{
  g_autoptr(FlatpakDir) dir = NULL;
  g_autoptr(GFile) changed_file = NULL;
  g_autoptr(GFileInfo) info = NULL;

  dir = flatpak_installation_get_dir_maybe_no_repo (self);
  changed_file = flatpak_dir_get_changed_path (dir);

  info = g_file_query_info (changed_file,
                            G_FILE_ATTRIBUTE_TIME_MODIFIED,
                            G_FILE_QUERY_INFO_NONE,
                            NULL,
                            NULL);
  if (info == NULL)
    return G_MAXUINT64;

  return g_file_info_get_attribute_uint64 (info, G_FILE_ATTRIBUTE_TIME_MODIFIED);
}


/**
 * flatpak_installation_list_remote_related_refs_sync:
 * @self: a #FlatpakInstallation
 * @remote_name: the name of the remote
 * @ref: the ref
 * @cancellable: (nullable): a #GCancellable
 * @error: return location for a #GError
 *
 * Lists all the available refs on @remote_name that are related to
 * @ref, and the subpaths to use. These are things that are
 * interesting to install, update, or uninstall together with
 * @ref. For instance, locale data or debug information.
 *
 * The returned list contains all available related refs, but not
 * every one should always be installed. For example,
 * flatpak_related_ref_should_download() returns %TRUE if the
 * reference should be installed/updated with the app, and
 * flatpak_related_ref_should_delete() returns %TRUE if it
 * should be uninstalled with the main ref.
 *
 * The commit property of each #FlatpakRelatedRef is not guaranteed to be
 * non-%NULL.
 *
 * Returns: (transfer container) (element-type FlatpakRelatedRef): a GPtrArray of
 *   #FlatpakRelatedRef instances
 *
 * Since: 0.6.7
 */
GPtrArray *
flatpak_installation_list_remote_related_refs_sync (FlatpakInstallation *self,
                                                    const char          *remote_name,
                                                    const char          *ref,
                                                    GCancellable        *cancellable,
                                                    GError             **error)
{
  g_autoptr(FlatpakDir) dir = NULL;
  g_autoptr(GPtrArray) related = NULL;
  g_autoptr(GPtrArray) refs = g_ptr_array_new_with_free_func (g_object_unref);
  g_autoptr(FlatpakRemoteState) state = NULL;
  g_autoptr(FlatpakDecomposed) decomposed = NULL;
  int i;

  dir = flatpak_installation_get_dir (self, error);
  if (dir == NULL)
    return NULL;

  decomposed = flatpak_decomposed_new_from_ref (ref, error);
  if (decomposed == NULL)
    return NULL;

  state = flatpak_dir_get_remote_state_optional (dir, remote_name, FALSE, cancellable, error);
  if (state == NULL)
    return NULL;

  related = flatpak_dir_find_remote_related (dir, state, decomposed, FALSE,
                                             cancellable, error);
  if (related == NULL)
    return NULL;

  for (i = 0; i < related->len; i++)
    {
      FlatpakRelated *rel = g_ptr_array_index (related, i);
      FlatpakRelatedRef *rel_ref;

      rel_ref = flatpak_related_ref_new (flatpak_decomposed_get_ref (rel->ref), rel->commit,
                                         rel->subpaths, rel->download, rel->delete);

      if (rel_ref)
        g_ptr_array_add (refs, rel_ref);
    }

  return g_steal_pointer (&refs);
}

/**
 * flatpak_installation_list_installed_related_refs_sync:
 * @self: a #FlatpakInstallation
 * @remote_name: the name of the remote providing @ref
 * @ref: the ref
 * @cancellable: (nullable): a #GCancellable
 * @error: return location for a #GError
 *
 * Lists all the locally installed refs that are related to @ref. These are
 * things that are interesting to install, update, or uninstall together with
 * @ref. For instance, locale data or debug information.
 *
 * Note that while the related refs are usually installed from the same remote
 * as @ref (@remote_name), it is possible they were installed from another
 * remote.
 *
 * This function is similar to flatpak_installation_list_remote_related_refs_sync,
 * but instead of looking at what is available on the remote, it only looks
 * at the locally installed refs. This is useful for instance when you're
 * looking for related refs to uninstall, or when you're planning to use
 * FLATPAK_UPDATE_FLAGS_NO_PULL to install previously pulled refs.
 *
 * Returns: (transfer container) (element-type FlatpakRelatedRef): a GPtrArray of
 *   #FlatpakRelatedRef instances
 *
 * Since: 0.6.7
 */
GPtrArray *
flatpak_installation_list_installed_related_refs_sync (FlatpakInstallation *self,
                                                       const char          *remote_name,
                                                       const char          *ref,
                                                       GCancellable        *cancellable,
                                                       GError             **error)
{
  g_autoptr(FlatpakDir) dir = NULL;
  g_autoptr(GPtrArray) related = NULL;
  g_autoptr(GPtrArray) refs = g_ptr_array_new_with_free_func (g_object_unref);
  g_autoptr(FlatpakDecomposed) decomposed = NULL;
  int i;

  dir = flatpak_installation_get_dir (self, error);
  if (dir == NULL)
    return NULL;

  decomposed = flatpak_decomposed_new_from_ref (ref, error);
  if (decomposed == NULL)
    return NULL;

  related = flatpak_dir_find_local_related (dir, decomposed, remote_name, TRUE,
                                            cancellable, error);
  if (related == NULL)
    return NULL;

  for (i = 0; i < related->len; i++)
    {
      FlatpakRelated *rel = g_ptr_array_index (related, i);
      FlatpakRelatedRef *rel_ref;

      rel_ref = flatpak_related_ref_new (flatpak_decomposed_get_ref (rel->ref), rel->commit,
                                         rel->subpaths, rel->download, rel->delete);

      if (rel_ref)
        g_ptr_array_add (refs, rel_ref);
    }

  return g_steal_pointer (&refs);
}

/**
 * flatpak_installation_list_remote_related_refs_for_installed_sync:
 * @self: a #FlatpakInstallation
 * @remote_name: the name of the remote
 * @ref: the ref
 * @cancellable: (nullable): a #GCancellable
 * @error: return location for a #GError
 *
 * Lists all the available refs on @remote_name that are related to @ref, and
 * which are appropriate for the installed version of @ref. For example if the
 * installed version of org.videolan.VLC has a related ref of
 * org.videolan.VLC.Plugin.bdj//3-19.08 and the remote version of VLC has a
 * related ref of org.videolan.VLC.Plugin.bdj//3-20.08, this function will only
 * return the 3-19.08 branch.
 *
 * See also the related functions
 * flatpak_installation_list_remote_related_refs_sync() and
 * flatpak_installation_list_installed_related_refs_sync().
 *
 * The returned list contains all available related refs, but not
 * every one should always be installed. For example,
 * flatpak_related_ref_should_download() returns %TRUE if the
 * reference should be installed/updated with the app, and
 * flatpak_related_ref_should_delete() returns %TRUE if it
 * should be uninstalled with the main ref.
 *
 * The commit property of each #FlatpakRelatedRef is not guaranteed to be
 * non-%NULL.
 *
 * Returns: (transfer container) (element-type FlatpakRelatedRef): a GPtrArray of
 *   #FlatpakRelatedRef instances
 *
 * Since: 1.11.1
 */
GPtrArray *
flatpak_installation_list_remote_related_refs_for_installed_sync (FlatpakInstallation *self,
                                                                  const char          *remote_name,
                                                                  const char          *ref,
                                                                  GCancellable        *cancellable,
                                                                  GError             **error)
{
  g_autoptr(FlatpakDir) dir = NULL;
  g_autoptr(GPtrArray) related = NULL;
  g_autoptr(GPtrArray) refs = g_ptr_array_new_with_free_func (g_object_unref);
  g_autoptr(FlatpakRemoteState) state = NULL;
  g_autoptr(FlatpakDecomposed) decomposed = NULL;
  int i;

  dir = flatpak_installation_get_dir (self, error);
  if (dir == NULL)
    return NULL;

  decomposed = flatpak_decomposed_new_from_ref (ref, error);
  if (decomposed == NULL)
    return NULL;

  state = flatpak_dir_get_remote_state_optional (dir, remote_name, FALSE, cancellable, error);
  if (state == NULL)
    return NULL;

  related = flatpak_dir_find_remote_related (dir, state, decomposed,
                                             TRUE, /* use_installed_metadata */
                                             cancellable, error);
  if (related == NULL)
    return NULL;

  for (i = 0; i < related->len; i++)
    {
      FlatpakRelated *rel = g_ptr_array_index (related, i);
      FlatpakRelatedRef *rel_ref;

      rel_ref = flatpak_related_ref_new (flatpak_decomposed_get_ref (rel->ref), rel->commit,
                                         rel->subpaths, rel->download, rel->delete);

      if (rel_ref)
        g_ptr_array_add (refs, rel_ref);
    }

  return g_steal_pointer (&refs);
}

/**
 * flatpak_installation_remove_local_ref_sync:
 * @self: a #FlatpakInstallation
 * @remote_name: the name of the remote
 * @ref: the ref
 * @cancellable: (nullable): a #GCancellable
 * @error: return location for a #GError
 *
 * Remove the OSTree ref given by @remote_name:@ref from the local flatpak
 * repository. The next time the underlying OSTree repo is pruned, objects
 * which were attached to that ref will be removed. This is useful if you
 * pulled a flatpak ref using flatpak_installation_install_full() and
 * specified %FLATPAK_INSTALL_FLAGS_NO_DEPLOY but then decided not to
 * deploy the ref later on and want to remove the local ref to prevent it
 * from taking up disk space. Note that this will not remove the objects
 * referred to by @ref from the underlying OSTree repo, you should use
 * flatpak_installation_prune_local_repo() to do that.
 *
 * Since: 0.10.0
 * Returns: %TRUE on success
 */
gboolean
flatpak_installation_remove_local_ref_sync (FlatpakInstallation *self,
                                            const char          *remote_name,
                                            const char          *ref,
                                            GCancellable        *cancellable,
                                            GError             **error)
{
  g_autoptr(FlatpakDir) dir = NULL;

  dir = flatpak_installation_get_dir (self, error);
  if (dir == NULL)
    return FALSE;

  return flatpak_dir_remove_ref (dir, remote_name, ref, cancellable, error);
}

/**
 * flatpak_installation_cleanup_local_refs_sync:
 * @self: a #FlatpakInstallation
 * @cancellable: (nullable): a #GCancellable
 * @error: return location for a #GError
 *
 * Remove all OSTree refs from the local flatpak repository which are not
 * in a deployed state. The next time the underlying OSTree repo is pruned,
 * objects which were attached to that ref will be removed. This is useful if
 * you pulled a flatpak refs using flatpak_installation_install_full() and
 * specified %FLATPAK_INSTALL_FLAGS_NO_DEPLOY but then decided not to
 * deploy the refs later on and want to remove the local refs to prevent them
 * from taking up disk space. Note that this will not remove the objects
 * referred to by @ref from the underlying OSTree repo, you should use
 * flatpak_installation_prune_local_repo() to do that.
 *
 * Since: 0.10.0
 * Returns: %TRUE on success
 */
gboolean
flatpak_installation_cleanup_local_refs_sync (FlatpakInstallation *self,
                                              GCancellable        *cancellable,
                                              GError             **error)
{
  g_autoptr(FlatpakDir) dir = NULL;

  dir = flatpak_installation_get_dir (self, error);
  if (dir == NULL)
    return FALSE;

  return flatpak_dir_cleanup_undeployed_refs (dir, cancellable, error);
}

/**
 * flatpak_installation_prune_local_repo:
 * @self: a #FlatpakInstallation
 * @cancellable: (nullable): a #GCancellable
 * @error: return location for a #GError
 *
 * Remove all orphaned OSTree objects from the underlying OSTree repo in
 * @self.
 *
 * Since: 0.10.0
 * Returns: %TRUE on success
 */
gboolean
flatpak_installation_prune_local_repo (FlatpakInstallation *self,
                                       GCancellable        *cancellable,
                                       GError             **error)
{
  g_autoptr(FlatpakDir) dir = NULL;

  dir = flatpak_installation_get_dir (self, error);
  if (dir == NULL)
    return FALSE;

  return flatpak_dir_prune (dir, cancellable, error);
}

/**
 * flatpak_installation_run_triggers:
 * @self: a #FlatpakInstallation
 * @cancellable: (nullable): a #GCancellable
 * @error: return location for a #GError
 *
 * Run the trigger commands to update the files exported by the apps in
 * @self. Should be used after one or more app install, upgrade or
 * uninstall operations with the %FLATPAK_INSTALL_FLAGS_NO_TRIGGERS,
 * %FLATPAK_UPDATE_FLAGS_NO_TRIGGERS or %FLATPAK_UNINSTALL_FLAGS_NO_TRIGGERS
 * flags set.
 *
 * Since: 1.0.3
 * Returns: %TRUE on success
 */
gboolean
flatpak_installation_run_triggers (FlatpakInstallation *self,
                                   GCancellable        *cancellable,
                                   GError             **error)
{
  g_autoptr(FlatpakDir) dir = NULL;

  dir = flatpak_installation_get_dir (self, error);
  if (dir == NULL)
    return FALSE;

  return flatpak_dir_run_triggers (dir, cancellable, error);
}

/**
 * flatpak_installation_list_unused_refs:
 * @self: a #FlatpakInstallation
 * @arch: (nullable): if non-%NULL, the architecture of refs to collect
 * @cancellable: (nullable): a #GCancellable
 * @error: return location for a #GError
 *
 * Lists the installed references that are not 'used'.
 *
 * A reference is used if it is either an application,
 * or the runtime or sdk of a used ref, or an extension of a used ref.
 * Pinned runtimes are also considered used; see flatpak-pin(1) and
 * flatpak_installation_list_pinned_refs().
 *
 * Returns: (transfer container) (element-type FlatpakInstalledRef): a GPtrArray of
 *   #FlatpakInstalledRef instances
 *
 * Since: 1.1.2
 */
GPtrArray *
flatpak_installation_list_unused_refs (FlatpakInstallation *self,
                                       const char          *arch,
                                       GCancellable        *cancellable,
                                       GError             **error)
{
  return flatpak_installation_list_unused_refs_with_options (self, arch, NULL, NULL, cancellable, error);
}

/**
 * flatpak_installation_list_unused_refs_with_options:
 * @self: a #FlatpakInstallation
 * @arch: (nullable): if non-%NULL, the architecture of refs to collect
 * @metadata_injection: (nullable): if non-%NULL, a #GHashTable mapping refs to
 *                                  #GKeyFile objects, which when available will
 *                                  be used instead of installed metadata
 * @options: (nullable): if non-%NULL, a GVariant a{sv} with an extensible set
 *                       of options
 * @cancellable: (nullable): a #GCancellable
 * @error: return location for a #GError
 *
 * Like flatpak_installation_list_unused_refs() but supports an extensible set
 * of options as well as an @metadata_injection parameter. The following are
 * currently defined:
 *
 *   * exclude-refs (as): Act as if these refs are not installed even if they
 *       are when determining the set of unused refs
 *   * filter-by-eol (b): Return refs as unused if they are End-Of-Life.
 *       Note that if this option is combined with other filters then non-EOL refs may also be returned.
 *   * filter-by-autoprune (b): Return refs as unused if they should be autopruned.
 *       Note that if this option is combined with other filters then non-autoprune refs may also be returned.

 * Returns: (transfer container) (element-type FlatpakInstalledRef): a GPtrArray of
 *   #FlatpakInstalledRef instances
 *
 * Since: 1.9.1
 */
GPtrArray *
flatpak_installation_list_unused_refs_with_options (FlatpakInstallation *self,
                                                    const char          *arch,
                                                    GHashTable          *metadata_injection,
                                                    GVariant            *options,
                                                    GCancellable        *cancellable,
                                                    GError             **error)
{
  g_autoptr(FlatpakDir) dir = NULL;
  g_autoptr(GPtrArray) refs =  NULL;
  g_auto(GStrv) refs_strv = NULL;
  g_autofree char **refs_to_exclude = NULL;
  gboolean filter_by_eol = FALSE;
  gboolean filter_by_autoprune = FALSE;
  FlatpakDirFilterFlags filter_flags = FLATPAK_DIR_FILTER_NONE;

  if (options)
    {
      (void) g_variant_lookup (options, "exclude-refs", "^a&s", &refs_to_exclude);
      (void) g_variant_lookup (options, "filter-by-eol", "b", &filter_by_eol);
      (void) g_variant_lookup (options, "filter-by-autoprune", "b", &filter_by_autoprune);
    }

  dir = flatpak_installation_get_dir (self, error);
  if (dir == NULL)
    return NULL;

  if (filter_by_eol)
    filter_flags |= FLATPAK_DIR_FILTER_EOL;
  if (filter_by_autoprune)
    filter_flags |= FLATPAK_DIR_FILTER_AUTOPRUNE;

  refs_strv = flatpak_dir_list_unused_refs (dir, arch, metadata_injection, NULL,
                                            (const char * const *)refs_to_exclude,
                                            filter_flags,
                                            cancellable, error);
  if (refs_strv == NULL)
    return NULL;

  refs = g_ptr_array_new_with_free_func (g_object_unref);
  for (char **iter = refs_strv; iter && *iter; iter++)
    {
      g_autoptr(GError) local_error = NULL;
      FlatpakInstalledRef *ref = NULL;
      g_autoptr(FlatpakDecomposed) decomposed = NULL;

      decomposed = flatpak_decomposed_new_from_ref (*iter, &local_error);
      if (decomposed == NULL)
        {
          g_warning ("Unexpected failure parsing ref %s: %s", *iter, local_error->message);
          continue;
        }

      ref = get_ref (dir, decomposed, cancellable, &local_error);
      if (ref == NULL)
        {
          g_warning ("Unexpected failure getting ref for %s: %s",
                     flatpak_decomposed_get_ref (decomposed),
                     local_error->message);
          continue;
        }

      g_ptr_array_add (refs, ref);
    }

  return g_steal_pointer (&refs);
}

/**
 * flatpak_installation_list_pinned_refs:
 * @self: a #FlatpakInstallation
 * @arch: (nullable): if non-%NULL, the architecture of refs to collect
 * @cancellable: (nullable): a #GCancellable
 * @error: return location for a #GError
 *
 * Lists the installed references that are pinned, meaning they will not be
 * returned by flatpak_installation_list_unused_refs() and won't be removed
 * unless explicitly specified for removal.
 *
 * Refs appear here either because they have been pinned automatically by
 * Flatpak or because the user pinned them; see flatpak-pin(1).
 *
 * Returns: (transfer container) (element-type FlatpakInstalledRef): a GPtrArray of
 *   #FlatpakInstalledRef instances
 *
 * Since: 1.9.1
 */
GPtrArray *
flatpak_installation_list_pinned_refs (FlatpakInstallation *self,
                                       const char          *arch,
                                       GCancellable        *cancellable,
                                       GError             **error)
{
  g_autoptr(FlatpakDir) dir = NULL;
  g_autoptr(GPtrArray) refs =  NULL;
  g_autoptr(GPtrArray) runtime_refs = NULL;
  int i;

  dir = flatpak_installation_get_dir (self, error);
  if (dir == NULL)
    return NULL;

  runtime_refs = flatpak_dir_list_refs (dir, FLATPAK_KINDS_RUNTIME,
                                        cancellable, error);
  if (runtime_refs == NULL)
    return NULL;

  refs = g_ptr_array_new_with_free_func (g_object_unref);

  for (i = 0; i < runtime_refs->len; i++)
    {
      FlatpakDecomposed *decomposed = g_ptr_array_index (runtime_refs, i);

      if (arch != NULL && !flatpak_decomposed_is_arch (decomposed, arch))
        continue;

      if (flatpak_dir_ref_is_pinned (dir, flatpak_decomposed_get_ref (decomposed)))
        {
          g_autoptr(GError) local_error = NULL;
          FlatpakInstalledRef *ref = get_ref (dir, decomposed, cancellable, &local_error);
          if (ref != NULL)
            g_ptr_array_add (refs, ref);
          else
            g_warning ("Unexpected failure getting ref for %s: %s", flatpak_decomposed_get_ref (decomposed), local_error->message);
        }
    }

  return g_steal_pointer (&refs);
}

===== ./common/flatpak-run-cups-private.h =====
/*
 * Copyright © 2014 Red Hat, Inc
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Alexander Larsson <alexl@redhat.com>
 */

#pragma once

#include "libglnx.h"

#include "flatpak-bwrap-private.h"
#include "flatpak-common-types-private.h"

G_BEGIN_DECLS

void flatpak_run_add_cups_args (FlatpakBwrap *bwrap);

G_END_DECLS

===== ./common/flatpak-prune-private.h =====
/*
 * Copyright © 2021 Red Hat, Inc
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Alexander Larsson <alexl@redhat.com>
 */

#ifndef __FLATPAK_PRUNE_H__
#define __FLATPAK_PRUNE_H__

#include <ostree.h>

#include "flatpak-utils-private.h"

gboolean flatpak_repo_prune  (OstreeRepo    *repo,
                              int            depth,
                              gboolean       dry_run,
                              int           *out_objects_total,
                              int           *out_objects_pruned,
                              guint64       *out_pruned_object_size_total,
                              GCancellable  *cancellable,
                              GError       **error);

#endif /* __FLATPAK_PRUNE_H__ */

===== ./common/flatpak-utils-http-private.h =====
/*
 * Copyright © 2014 Red Hat, Inc
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Alexander Larsson <alexl@redhat.com>
 */

#ifndef __FLATPAK_UTILS_HTTP_H__
#define __FLATPAK_UTILS_HTTP_H__

#include <string.h>

typedef enum {
  FLATPAK_HTTP_ERROR_NOT_CHANGED = 0,
  FLATPAK_HTTP_ERROR_UNAUTHORIZED = 1,
} FlatpakHttpErrorEnum;

#define FLATPAK_HTTP_ERROR flatpak_http_error_quark ()

GQuark flatpak_http_error_quark (void);

typedef struct FlatpakHttpSession FlatpakHttpSession;

FlatpakHttpSession* flatpak_create_http_session (const char *user_agent);
void flatpak_http_session_free (FlatpakHttpSession* http_session);

G_DEFINE_AUTOPTR_CLEANUP_FUNC(FlatpakHttpSession, flatpak_http_session_free)

typedef struct FlatpakCertificates FlatpakCertificates;

FlatpakCertificates* flatpak_get_certificates_for_uri (const char *uri,
                                                       GError    **error);
FlatpakCertificates * flatpak_certificates_copy (FlatpakCertificates *other);
void flatpak_certificates_free (FlatpakCertificates *certificates);

G_DEFINE_AUTOPTR_CLEANUP_FUNC(FlatpakCertificates, flatpak_certificates_free)

typedef enum {
  FLATPAK_HTTP_FLAGS_NONE = 0,
  FLATPAK_HTTP_FLAGS_ACCEPT_OCI = 1 << 0,
  FLATPAK_HTTP_FLAGS_STORE_COMPRESSED = 1 << 1,
  FLATPAK_HTTP_FLAGS_NOCHECK_STATUS = 1 << 2,
  FLATPAK_HTTP_FLAGS_HEAD = 1 << 3,
} FlatpakHTTPFlags;

typedef void (*FlatpakLoadUriProgress) (guint64  downloaded_bytes,
                                        gpointer user_data);

GBytes * flatpak_load_uri_full (FlatpakHttpSession    *http_session,
                                const char            *uri,
                                FlatpakCertificates   *certificates,
                                FlatpakHTTPFlags       flags,
                                const char            *auth,
                                const char            *token,
                                FlatpakLoadUriProgress progress,
                                gpointer               user_data,
                                int                   *out_status,
                                char                 **out_content_type,
                                char                 **out_www_authenticate,
                                GCancellable          *cancellable,
                                GError               **error);
GBytes * flatpak_load_uri (FlatpakHttpSession    *http_session,
                           const char            *uri,
                           FlatpakHTTPFlags       flags,
                           const char            *token,
                           FlatpakLoadUriProgress progress,
                           gpointer               user_data,
                           char                 **out_content_type,
                           GCancellable          *cancellable,
                           GError               **error);
gboolean flatpak_download_http_uri (FlatpakHttpSession    *http_session,
                                    const char            *uri,
                                    FlatpakCertificates   *certificates,
                                    FlatpakHTTPFlags       flags,
                                    GOutputStream         *out,
                                    const char            *token,
                                    FlatpakLoadUriProgress progress,
                                    gpointer               user_data,
                                    GCancellable          *cancellable,
                                    GError               **error);
gboolean flatpak_cache_http_uri (FlatpakHttpSession    *http_session,
                                 const char            *uri,
                                 FlatpakCertificates   *certificates,
                                 FlatpakHTTPFlags       flags,
                                 int                    dest_dfd,
                                 const char            *dest_subpath,
                                 FlatpakLoadUriProgress progress,
                                 gpointer               user_data,
                                 GCancellable          *cancellable,
                                 GError               **error);

#endif /* __FLATPAK_UTILS_HTTP_H__ */

===== ./common/flatpak-dir-private.h =====
/*
 * Copyright © 2014 Red Hat, Inc
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Alexander Larsson <alexl@redhat.com>
 */

#ifndef __FLATPAK_DIR_H__
#define __FLATPAK_DIR_H__

#include <ostree.h>

#include "flatpak-common-types-private.h"
#include "flatpak-context-private.h"
#include "flatpak-progress-private.h"
#include "flatpak-variant-private.h"
#include "flatpak-ref-utils-private.h"
#include "libglnx.h"

/* Version history:
 * The version field was added in flatpak 1.2, anything before is 0.
 *
 * Version 1 added appdata-name/summary/version/license
 * Version 2 added extension-of/appdata-content-rating
 * Version 3 added timestamp
 * Version 4 guarantees that alt-id/eol/eolr/runtime/extension-of/appdata-content-rating
 *           are present if in the commit metadata or metadata file or appdata
 */
#define FLATPAK_DEPLOY_VERSION_CURRENT 4
#define FLATPAK_DEPLOY_VERSION_ANY 0

#define FLATPAK_TYPE_DIR flatpak_dir_get_type ()
#define FLATPAK_DIR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), FLATPAK_TYPE_DIR, FlatpakDir))
#define FLATPAK_IS_DIR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), FLATPAK_TYPE_DIR))

#define SYSTEM_DIR_DEFAULT_ID "default"
#define SYSTEM_DIR_DEFAULT_DISPLAY_NAME _("Default system installation")
#define SYSTEM_DIR_DEFAULT_STORAGE_TYPE FLATPAK_DIR_STORAGE_TYPE_DEFAULT
#define SYSTEM_DIR_DEFAULT_PRIORITY 0

#define FLATPAK_TYPE_DEPLOY flatpak_deploy_get_type ()
#define FLATPAK_DEPLOY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), FLATPAK_TYPE_DEPLOY, FlatpakDeploy))
#define FLATPAK_IS_DEPLOY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), FLATPAK_TYPE_DEPLOY))

GType flatpak_dir_get_type (void);
GType flatpak_deploy_get_type (void);

#define FLATPAK_CLI_UPDATE_INTERVAL_MS 300

typedef struct _PolkitSubject PolkitSubject;

typedef struct
{
  FlatpakDecomposed *ref;
  char              *remote;
  char              *commit;
  char             **subpaths;
  gboolean           download;
  gboolean           delete;
  gboolean           auto_prune;
} FlatpakRelated;

void         flatpak_related_free (FlatpakRelated *related);

typedef struct {
  OstreeRepo *repo;
  GVariant   *summary;
} FlatpakSideloadState;

/* The remote state represent the state of the remote at a particular
   time, including the summary file and the metadata (which may be from
   the summary or from a branch. We create this once per highlevel operation
   to avoid looking up the summary multiple times, but also to avoid races
   if it happened to change in the middle of the operation */
typedef struct
{
  char     *remote_name;
  gboolean  is_file_uri;
  gboolean  is_oci;
  char     *collection_id;

  /* New format summary */

  GVariant   *index;
  GBytes     *index_sig_bytes;
  GHashTable *index_ht; /* Arch -> subsummary digest (filtered by subsystem) */
  GHashTable *subsummaries; /* digest -> GVariant */

  /* Compat summary */
  GVariant *summary;
  GBytes   *summary_bytes;
  GBytes   *summary_sig_bytes;
  GError   *summary_fetch_error;

  GRegex   *allow_refs;
  GRegex   *deny_refs;
  int       refcount;
  gint32    default_token_type;
  GPtrArray *sideload_repos;
  GPtrArray *sideload_image_collections;
} FlatpakRemoteState;

FlatpakRemoteState *flatpak_remote_state_ref (FlatpakRemoteState *remote_state);
void flatpak_remote_state_unref (FlatpakRemoteState *remote_state);
gboolean flatpak_remote_state_ensure_summary (FlatpakRemoteState *self,
                                              GError            **error);
gboolean flatpak_remote_state_ensure_subsummary (FlatpakRemoteState *self,
                                                 FlatpakDir         *dir,
                                                 const char         *arch,
                                                 gboolean            only_cached,
                                                 GCancellable       *cancellable,
                                                 GError            **error);
gboolean flatpak_remote_state_ensure_subsummary_all_arches (FlatpakRemoteState *self,
                                                            FlatpakDir         *dir,
                                                            gboolean            only_cached,
                                                            GCancellable       *cancellable,
                                                            GError            **error);
gboolean flatpak_remote_state_allow_ref (FlatpakRemoteState *self,
                                         const char *ref);
gboolean flatpak_remote_state_lookup_ref (FlatpakRemoteState  *self,
                                          const char          *ref,
                                          char               **out_checksum,
                                          guint64             *out_timestamp,
                                          GVariant           **out_summary_metadata,
                                          GFile              **out_sideload_path,
                                          FlatpakImageSource **out_image_Source,
                                          GError             **error);
GPtrArray *flatpak_remote_state_match_subrefs (FlatpakRemoteState *self,
                                               FlatpakDecomposed *ref);
void flatpak_remote_state_lookup_sideload_checksum (FlatpakRemoteState  *self,
                                                    char                *checksum,
                                                    GFile              **out_sideload_path,
                                                    FlatpakImageSource **out_image_source);
gboolean flatpak_remote_state_lookup_cache (FlatpakRemoteState *self,
                                            const char         *ref,
                                            guint64            *download_size,
                                            guint64            *installed_size,
                                            const char        **metadata,
                                            GError            **error);
gboolean flatpak_remote_state_load_data (FlatpakRemoteState *self,
                                         const char         *ref,
                                         guint64            *out_download_size,
                                         guint64            *out_installed_size,
                                         char              **out_metadata,
                                         GError            **error);
gboolean flatpak_remote_state_lookup_sparse_cache (FlatpakRemoteState *self,
                                                   const char         *ref,
                                                   VarMetadataRef     *out_metadata,
                                                   GError            **error);
GVariant *flatpak_remote_state_load_ref_commit (FlatpakRemoteState *self,
                                                FlatpakDir         *dir,
                                                const char         *ref,
                                                const char         *opt_commit,
                                                const char         *token,
                                                char              **out_commit,
                                                GCancellable       *cancellable,
                                                GError            **error);
void flatpak_remote_state_add_sideload_dir (FlatpakRemoteState *self,
                                            GFile              *path);
void flatpak_remote_state_add_sideload_image_collection (FlatpakRemoteState     *self,
                                                         FlatpakImageCollection *image_collection);
FlatpakImageSource * flatpak_remote_state_fetch_image_source (FlatpakRemoteState  *self,
                                                              FlatpakDir          *dir,
                                                              const char          *ref,
                                                              const char          *opt_rev,
                                                              const char          *token,
                                                              GCancellable        *cancellable,
                                                              GError             **error);


G_DEFINE_AUTOPTR_CLEANUP_FUNC (FlatpakDir, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (FlatpakDeploy, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (FlatpakRelated, flatpak_related_free)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (FlatpakRemoteState, flatpak_remote_state_unref)

typedef enum {
  FLATPAK_HELPER_DEPLOY_FLAGS_NONE = 0,
  FLATPAK_HELPER_DEPLOY_FLAGS_UPDATE = 1 << 0,
  FLATPAK_HELPER_DEPLOY_FLAGS_NO_DEPLOY = 1 << 1,
  FLATPAK_HELPER_DEPLOY_FLAGS_LOCAL_PULL = 1 << 2,
  FLATPAK_HELPER_DEPLOY_FLAGS_REINSTALL = 1 << 3,
  FLATPAK_HELPER_DEPLOY_FLAGS_NO_INTERACTION = 1 << 4,
  FLATPAK_HELPER_DEPLOY_FLAGS_APP_HINT = 1 << 5,
  FLATPAK_HELPER_DEPLOY_FLAGS_INSTALL_HINT = 1 << 6,
  FLATPAK_HELPER_DEPLOY_FLAGS_UPDATE_PINNED = 1 << 7,
  FLATPAK_HELPER_DEPLOY_FLAGS_UPDATE_PREINSTALLED = 1 << 8,
} FlatpakHelperDeployFlags;

#define FLATPAK_HELPER_DEPLOY_FLAGS_ALL (FLATPAK_HELPER_DEPLOY_FLAGS_UPDATE | \
                                         FLATPAK_HELPER_DEPLOY_FLAGS_NO_DEPLOY | \
                                         FLATPAK_HELPER_DEPLOY_FLAGS_LOCAL_PULL | \
                                         FLATPAK_HELPER_DEPLOY_FLAGS_REINSTALL | \
                                         FLATPAK_HELPER_DEPLOY_FLAGS_NO_INTERACTION | \
                                         FLATPAK_HELPER_DEPLOY_FLAGS_APP_HINT | \
                                         FLATPAK_HELPER_DEPLOY_FLAGS_INSTALL_HINT | \
                                         FLATPAK_HELPER_DEPLOY_FLAGS_UPDATE_PINNED | \
                                         FLATPAK_HELPER_DEPLOY_FLAGS_UPDATE_PREINSTALLED)

typedef enum {
  FLATPAK_HELPER_UNINSTALL_FLAGS_NONE = 0,
  FLATPAK_HELPER_UNINSTALL_FLAGS_KEEP_REF = 1 << 0,
  FLATPAK_HELPER_UNINSTALL_FLAGS_FORCE_REMOVE = 1 << 1,
  FLATPAK_HELPER_UNINSTALL_FLAGS_NO_INTERACTION = 1 << 2,
  FLATPAK_HELPER_UNINSTALL_FLAGS_UPDATE_PREINSTALLED = 1 << 3,
} FlatpakHelperUninstallFlags;

#define FLATPAK_HELPER_UNINSTALL_FLAGS_ALL (FLATPAK_HELPER_UNINSTALL_FLAGS_KEEP_REF | \
                                            FLATPAK_HELPER_UNINSTALL_FLAGS_FORCE_REMOVE | \
                                            FLATPAK_HELPER_UNINSTALL_FLAGS_NO_INTERACTION | \
                                            FLATPAK_HELPER_UNINSTALL_FLAGS_UPDATE_PREINSTALLED)

typedef enum {
  FLATPAK_HELPER_CONFIGURE_REMOTE_FLAGS_NONE = 0,
  FLATPAK_HELPER_CONFIGURE_REMOTE_FLAGS_FORCE_REMOVE = 1 << 0,
  FLATPAK_HELPER_CONFIGURE_REMOTE_FLAGS_NO_INTERACTION = 1 << 1,
} FlatpakHelperConfigureRemoteFlags;

#define FLATPAK_HELPER_CONFIGURE_REMOTE_FLAGS_ALL (FLATPAK_HELPER_CONFIGURE_REMOTE_FLAGS_FORCE_REMOVE | \
                                                   FLATPAK_HELPER_CONFIGURE_REMOTE_FLAGS_NO_INTERACTION)

typedef enum {
  FLATPAK_HELPER_CONFIGURE_FLAGS_NONE = 0,
  FLATPAK_HELPER_CONFIGURE_FLAGS_UNSET = 1 << 0,
  FLATPAK_HELPER_CONFIGURE_FLAGS_NO_INTERACTION = 1 << 1,
} FlatpakHelperConfigureFlags;

#define FLATPAK_HELPER_CONFIGURE_FLAGS_ALL (FLATPAK_HELPER_CONFIGURE_FLAGS_UNSET | \
                                            FLATPAK_HELPER_CONFIGURE_FLAGS_NO_INTERACTION)

typedef enum {
  FLATPAK_HELPER_UPDATE_REMOTE_FLAGS_NONE = 0,
  FLATPAK_HELPER_UPDATE_REMOTE_FLAGS_NO_INTERACTION = 1 << 0,
  FLATPAK_HELPER_UPDATE_REMOTE_FLAGS_SUMMARY_IS_INDEX = 1 << 1,
} FlatpakHelperUpdateRemoteFlags;

#define FLATPAK_HELPER_UPDATE_REMOTE_FLAGS_ALL (FLATPAK_HELPER_UPDATE_REMOTE_FLAGS_NO_INTERACTION | \
                                                FLATPAK_HELPER_UPDATE_REMOTE_FLAGS_SUMMARY_IS_INDEX)

typedef enum {
  FLATPAK_HELPER_GET_REVOKEFS_FD_FLAGS_NONE = 0,
  FLATPAK_HELPER_GET_REVOKEFS_FD_FLAGS_NO_INTERACTION = 1 << 0,
} FlatpakHelperGetRevokefsFdFlags;

#define FLATPAK_HELPER_GET_REVOKEFS_FD_FLAGS_ALL (FLATPAK_HELPER_GET_REVOKEFS_FD_FLAGS_NO_INTERACTION)

typedef enum {
  FLATPAK_HELPER_INSTALL_BUNDLE_FLAGS_NONE = 0,
  FLATPAK_HELPER_INSTALL_BUNDLE_FLAGS_NO_INTERACTION = 1 << 0,
  FLATPAK_HELPER_INSTALL_BUNDLE_FLAGS_REINSTALL = 1 << 1,
} FlatpakHelperInstallBundleFlags;

#define FLATPAK_HELPER_INSTALL_BUNDLE_FLAGS_ALL (FLATPAK_HELPER_INSTALL_BUNDLE_FLAGS_NO_INTERACTION | \
                                                 FLATPAK_HELPER_INSTALL_BUNDLE_FLAGS_REINSTALL)

typedef enum {
  FLATPAK_HELPER_DEPLOY_APPSTREAM_FLAGS_NONE = 0,
  FLATPAK_HELPER_DEPLOY_APPSTREAM_FLAGS_NO_INTERACTION = 1 << 0,
} FlatpakHelperDeployAppstreamFlags;

#define FLATPAK_HELPER_DEPLOY_APPSTREAM_FLAGS_ALL (FLATPAK_HELPER_DEPLOY_APPSTREAM_FLAGS_NO_INTERACTION)

typedef enum {
  FLATPAK_HELPER_REMOVE_LOCAL_REF_FLAGS_NONE = 0,
  FLATPAK_HELPER_REMOVE_LOCAL_REF_FLAGS_NO_INTERACTION = 1 << 0,
} FlatpakHelperRemoveLocalRefFlags;

#define FLATPAK_HELPER_REMOVE_LOCAL_REF_FLAGS_ALL (FLATPAK_HELPER_REMOVE_LOCAL_REF_FLAGS_NO_INTERACTION)

typedef enum {
  FLATPAK_HELPER_PRUNE_LOCAL_REPO_FLAGS_NONE = 0,
  FLATPAK_HELPER_PRUNE_LOCAL_REPO_FLAGS_NO_INTERACTION = 1 << 0,
} FlatpakHelperPruneLocalRepoFlags;

#define FLATPAK_HELPER_PRUNE_LOCAL_REPO_FLAGS_ALL (FLATPAK_HELPER_PRUNE_LOCAL_REPO_FLAGS_NO_INTERACTION)

typedef enum {
  FLATPAK_HELPER_RUN_TRIGGERS_FLAGS_NONE = 0,
  FLATPAK_HELPER_RUN_TRIGGERS_FLAGS_NO_INTERACTION = 1 << 0,
} FlatpakHelperRunTriggersFlags;

#define FLATPAK_HELPER_RUN_TRIGGERS_FLAGS_ALL (FLATPAK_HELPER_RUN_TRIGGERS_FLAGS_NO_INTERACTION)

typedef enum {
  FLATPAK_HELPER_CANCEL_PULL_FLAGS_NONE = 0,
  FLATPAK_HELPER_CANCEL_PULL_FLAGS_PRESERVE_PULL = 1 << 0,
  FLATPAK_HELPER_CANCEL_PULL_FLAGS_NO_INTERACTION = 1 << 1,
} FlatpakHelperCancelPullFlags;

#define FLATPAK_HELPER_CANCEL_PULL_FLAGS_ALL (FLATPAK_HELPER_CANCEL_PULL_FLAGS_PRESERVE_PULL |\
                                              FLATPAK_HELPER_CANCEL_PULL_FLAGS_NO_INTERACTION)

typedef enum {
  FLATPAK_HELPER_ENSURE_REPO_FLAGS_NONE = 0,
  FLATPAK_HELPER_ENSURE_REPO_FLAGS_NO_INTERACTION = 1 << 0,
} FlatpakHelperEnsureRepoFlags;

#define FLATPAK_HELPER_ENSURE_REPO_FLAGS_ALL (FLATPAK_HELPER_ENSURE_REPO_FLAGS_NO_INTERACTION)

typedef enum {
  FLATPAK_HELPER_UPDATE_SUMMARY_FLAGS_NONE = 0,
  FLATPAK_HELPER_UPDATE_SUMMARY_FLAGS_NO_INTERACTION = 1 << 0,
  FLATPAK_HELPER_UPDATE_SUMMARY_FLAGS_DELETE = 1 << 1,
} FlatpakHelperUpdateSummaryFlags;

#define FLATPAK_HELPER_UPDATE_SUMMARY_FLAGS_ALL (FLATPAK_HELPER_UPDATE_SUMMARY_FLAGS_NO_INTERACTION |\
                                                 FLATPAK_HELPER_UPDATE_SUMMARY_FLAGS_DELETE)

typedef enum {
  FLATPAK_HELPER_GENERATE_OCI_SUMMARY_FLAGS_NONE = 0,
  FLATPAK_HELPER_GENERATE_OCI_SUMMARY_FLAGS_NO_INTERACTION = 1 << 0,
  FLATPAK_HELPER_GENERATE_OCI_SUMMARY_FLAGS_ONLY_CACHED = 1 << 1,
} FlatpakHelperGenerateOciSummaryFlags;

#define FLATPAK_HELPER_GENERATE_OCI_SUMMARY_FLAGS_ALL (FLATPAK_HELPER_GENERATE_OCI_SUMMARY_FLAGS_NO_INTERACTION |\
                                                       FLATPAK_HELPER_GENERATE_OCI_SUMMARY_FLAGS_ONLY_CACHED)

typedef enum {
  FLATPAK_PULL_FLAGS_NONE = 0,
  FLATPAK_PULL_FLAGS_DOWNLOAD_EXTRA_DATA = 1 << 0,
  FLATPAK_PULL_FLAGS_SIDELOAD_EXTRA_DATA = 1 << 1,
  FLATPAK_PULL_FLAGS_ALLOW_DOWNGRADE = 1 << 2,
  FLATPAK_PULL_FLAGS_NO_STATIC_DELTAS = 1 << 3,
} FlatpakPullFlags;

typedef enum {
  FLATPAK_DIR_STORAGE_TYPE_DEFAULT = 0,
  FLATPAK_DIR_STORAGE_TYPE_HARD_DISK,
  FLATPAK_DIR_STORAGE_TYPE_SDCARD,
  FLATPAK_DIR_STORAGE_TYPE_MMC,
  FLATPAK_DIR_STORAGE_TYPE_NETWORK,
} FlatpakDirStorageType;

typedef enum {
  FLATPAK_DIR_FILTER_NONE = 0,
  FLATPAK_DIR_FILTER_EOL = 1 << 0,
  FLATPAK_DIR_FILTER_AUTOPRUNE = 1 << 1,
} FlatpakDirFilterFlags;

typedef enum {
  FIND_MATCHING_REFS_FLAGS_NONE = 0,
  FIND_MATCHING_REFS_FLAGS_FUZZY = (1 << 0),
} FindMatchingRefsFlags;

GQuark       flatpak_dir_error_quark (void);

/**
 * FLATPAK_DEPLOY_DATA_GVARIANT_FORMAT:
 *
 * s - origin
 * s - commit
 * as - subpaths
 * t - installed size
 * a{sv} - Metadata
 */
#define FLATPAK_DEPLOY_DATA_GVARIANT_STRING "(ssasta{sv})"
#define FLATPAK_DEPLOY_DATA_GVARIANT_FORMAT G_VARIANT_TYPE (FLATPAK_DEPLOY_DATA_GVARIANT_STRING)

GPtrArray *flatpak_get_system_base_dir_locations        (GCancellable  *cancellable,
                                                         GError       **error);
GFile *    flatpak_get_system_default_base_dir_location (void);

GKeyFile *      flatpak_load_override_keyfile   (const char  *app_id,
                                                 gboolean     user,
                                                 GError     **error);
FlatpakContext *flatpak_load_override_file      (const char  *app_id,
                                                 gboolean     user,
                                                 GError     **error);
gboolean        flatpak_save_override_keyfile   (GKeyFile    *metakey,
                                                 const char  *app_id,
                                                 gboolean     user,
                                                 GError     **error);
gboolean        flatpak_remove_override_keyfile (const char  *app_id,
                                                 gboolean     user,
                                                 GError     **error);

typedef struct
{
  FlatpakDecomposed *ref;
  char *collection_id;
} FlatpakPreinstallConfig;

GPtrArray * flatpak_get_preinstall_config (const char    *default_arch,
                                           GCancellable  *cancellable,
                                           GError       **error);
gboolean flatpak_dir_uninitialized_mark_preinstalled (FlatpakDir       *self,
                                                      const GPtrArray  *preinstall_config,
                                                      GError          **error);

int          flatpak_deploy_data_get_version                     (GBytes *deploy_data);
const char * flatpak_deploy_data_get_origin                      (GBytes *deploy_data);
const char * flatpak_deploy_data_get_commit                      (GBytes *deploy_data);
const char * flatpak_deploy_data_get_appdata_content_rating_type (GBytes *deploy_data);
GHashTable * flatpak_deploy_data_get_appdata_content_rating      (GBytes *deploy_data);
const char **flatpak_deploy_data_get_subpaths                    (GBytes *deploy_data);
gboolean     flatpak_deploy_data_has_subpaths                    (GBytes *deploy_data);
guint64      flatpak_deploy_data_get_installed_size              (GBytes *deploy_data);
guint64      flatpak_deploy_data_get_timestamp                   (GBytes *deploy_data);
const char * flatpak_deploy_data_get_alt_id                      (GBytes *deploy_data);
const char * flatpak_deploy_data_get_eol                         (GBytes *deploy_data);
const char * flatpak_deploy_data_get_eol_rebase                  (GBytes *deploy_data);
const char * flatpak_deploy_data_get_runtime                     (GBytes *deploy_data);
const char * flatpak_deploy_data_get_extension_of                (GBytes *deploy_data);
const char * flatpak_deploy_data_get_appdata_name                (GBytes *deploy_data);
const char * flatpak_deploy_data_get_appdata_summary             (GBytes *deploy_data);
const char * flatpak_deploy_data_get_appdata_version             (GBytes *deploy_data);
const char * flatpak_deploy_data_get_appdata_license             (GBytes *deploy_data);
const char **flatpak_deploy_data_get_previous_ids                (GBytes *deploy_data,
                                                                  gsize  *length);

GFile *         flatpak_deploy_get_dir         (FlatpakDeploy      *deploy);
GBytes *        flatpak_load_deploy_data       (GFile              *deploy_dir,
                                                FlatpakDecomposed  *ref,
                                                OstreeRepo         *repo,
                                                int                 required_version,
                                                GCancellable       *cancellable,
                                                GError            **error);
GBytes *        flatpak_deploy_get_deploy_data (FlatpakDeploy      *deploy,
                                                int                 required_version,
                                                GCancellable       *cancellable,
                                                GError            **error);
GFile *         flatpak_deploy_get_files       (FlatpakDeploy      *deploy);
FlatpakContext *flatpak_deploy_get_overrides   (FlatpakDeploy      *deploy);
GKeyFile *      flatpak_deploy_get_metadata    (FlatpakDeploy      *deploy);

FlatpakDir *          flatpak_dir_new                                       (GFile                         *basedir,
                                                                             gboolean                       user);
FlatpakDir *          flatpak_dir_clone                                     (FlatpakDir                    *self);
FlatpakDir  *         flatpak_dir_get_user                                  (void);
FlatpakDir  *         flatpak_dir_get_system_default                        (void);
GPtrArray   *         flatpak_dir_get_system_list                           (GCancellable                  *cancellable,
                                                                             GError                       **error);
FlatpakDir  *         flatpak_dir_get_system_by_id                          (const char                    *id,
                                                                             GCancellable                  *cancellable,
                                                                             GError                       **error);
FlatpakDir *          flatpak_dir_get_by_path                               (GFile                         *path);
gboolean              flatpak_dir_is_user                                   (FlatpakDir                    *self);
void                  flatpak_dir_set_no_system_helper                      (FlatpakDir                    *self,
                                                                             gboolean                       no_system_helper);
void                  flatpak_dir_set_no_interaction                        (FlatpakDir                    *self,
                                                                             gboolean                       no_interaction);
gboolean              flatpak_dir_get_no_interaction                        (FlatpakDir                    *self);
GFile *               flatpak_dir_get_path                                  (FlatpakDir                    *self);
GFile *               flatpak_dir_get_changed_path                          (FlatpakDir                    *self);
const char *          flatpak_dir_get_id                                    (FlatpakDir                    *self);
char       *          flatpak_dir_get_display_name                          (FlatpakDir                    *self);
char *                flatpak_dir_get_name                                  (FlatpakDir                    *self);
const char *          flatpak_dir_get_name_cached                           (FlatpakDir                    *self);
gint                  flatpak_dir_get_priority                              (FlatpakDir                    *self);
FlatpakDirStorageType flatpak_dir_get_storage_type                          (FlatpakDir                    *self);
GFile *               flatpak_dir_get_deploy_dir                            (FlatpakDir                    *self,
                                                                             FlatpakDecomposed             *ref);
char *                flatpak_dir_get_deploy_subdir                         (FlatpakDir                    *self,
                                                                             const char                    *checksum,
                                                                             const char * const            *subpaths);
GFile *               flatpak_dir_get_unmaintained_extension_dir            (FlatpakDir                    *self,
                                                                             const char                    *name,
                                                                             const char                    *arch,
                                                                             const char                    *branch);
GBytes *              flatpak_dir_get_deploy_data                           (FlatpakDir                    *dir,
                                                                             FlatpakDecomposed             *ref,
                                                                             int                            required_version,
                                                                             GCancellable                  *cancellable,
                                                                             GError                       **error);
char *                flatpak_dir_get_origin                                (FlatpakDir                    *self,
                                                                             FlatpakDecomposed             *ref,
                                                                             GCancellable                  *cancellable,
                                                                             GError                       **error);
GFile *               flatpak_dir_get_exports_dir                           (FlatpakDir                    *self);
GFile *               flatpak_dir_get_removed_dir                           (FlatpakDir                    *self);
GFile *               flatpak_dir_get_sideload_repos_dir                    (FlatpakDir                    *self);
GFile *               flatpak_dir_get_runtime_sideload_repos_dir            (FlatpakDir                    *self);
GFile *               flatpak_dir_get_if_deployed                           (FlatpakDir                    *self,
                                                                             FlatpakDecomposed             *ref,
                                                                             const char                    *checksum,
                                                                             GCancellable                  *cancellable);
GFile *               flatpak_dir_get_unmaintained_extension_dir_if_exists  (FlatpakDir                    *self,
                                                                             const char                    *name,
                                                                             const char                    *arch,
                                                                             const char                    *branch,
                                                                             GCancellable                  *cancellable);
gboolean              flatpak_dir_ref_is_masked                             (FlatpakDir                    *self,
                                                                             const char                    *ref);
gboolean              flatpak_dir_ref_is_pinned                             (FlatpakDir                    *self,
                                                                             const char                    *ref);
FlatpakDecomposed *   flatpak_dir_find_remote_ref                           (FlatpakDir                    *self,
                                                                             FlatpakRemoteState            *state,
                                                                             const char                    *name,
                                                                             const char                    *opt_branch,
                                                                             const char                    *opt_default_branch,
                                                                             const char                    *opt_arch,
                                                                             FlatpakKinds                   kinds,
                                                                             GCancellable                  *cancellable,
                                                                             GError                       **error);
GPtrArray *           flatpak_dir_find_remote_refs                          (FlatpakDir                    *self,
                                                                             FlatpakRemoteState            *state,
                                                                             const char                    *name,
                                                                             const char                    *opt_branch,
                                                                             const char                    *opt_default_branch,
                                                                             const char                    *opt_arch,
                                                                             const char                    *opt_default_arch,
                                                                             FlatpakKinds                   kinds,
                                                                             FindMatchingRefsFlags          flags,
                                                                             GCancellable                  *cancellable,
                                                                             GError                       **error);
GPtrArray *           flatpak_dir_find_local_refs                           (FlatpakDir                    *self,
                                                                             const char                    *remote,
                                                                             const char                    *name,
                                                                             const char                    *opt_branch,
                                                                             const char                    *opt_default_branch,
                                                                             const char                    *opt_arch,
                                                                             const char                    *opt_default_arch,
                                                                             FlatpakKinds                   kinds,
                                                                             FindMatchingRefsFlags          flags,
                                                                             GCancellable                  *cancellable,
                                                                             GError                       **error);
FlatpakDecomposed *   flatpak_dir_find_installed_ref                        (FlatpakDir                    *self,
                                                                             const char                    *opt_name,
                                                                             const char                    *opt_branch,
                                                                             const char                    *opt_arch,
                                                                             FlatpakKinds                   kinds,
                                                                             GError                       **error);
GPtrArray *           flatpak_dir_find_installed_refs                       (FlatpakDir                    *self,
                                                                             const char                    *opt_name,
                                                                             const char                    *opt_branch,
                                                                             const char                    *opt_arch,
                                                                             FlatpakKinds                   kinds,
                                                                             FindMatchingRefsFlags          flags,
                                                                             GError                       **error);
FlatpakDeploy *       flatpak_dir_load_deployed                             (FlatpakDir                    *self,
                                                                             FlatpakDecomposed             *ref,
                                                                             const char                    *checksum,
                                                                             GCancellable                  *cancellable,
                                                                             GError                       **error);
char *                flatpak_dir_load_override                             (FlatpakDir                    *dir,
                                                                             const char                    *app_id,
                                                                             gsize                         *length,
                                                                             GFile                        **file_out,
                                                                             GError                       **error);
OstreeRepo *          flatpak_dir_get_repo                                  (FlatpakDir                    *self);
gboolean              flatpak_dir_ensure_path                               (FlatpakDir                    *self,
                                                                             GCancellable                  *cancellable,
                                                                             GError                       **error);
gboolean              flatpak_dir_use_child_repo                            (FlatpakDir                    *self);
gboolean              flatpak_dir_ensure_system_child_repo                  (FlatpakDir                    *self,
                                                                             GError                       **error);
gboolean              flatpak_dir_recreate_repo                             (FlatpakDir                    *self,
                                                                             GCancellable                  *cancellable,
                                                                             GError                       **error);
gboolean              flatpak_dir_ensure_repo                               (FlatpakDir                    *self,
                                                                             GCancellable                  *cancellable,
                                                                             GError                       **error);
gboolean              flatpak_dir_maybe_ensure_repo                         (FlatpakDir                    *self,
                                                                             GCancellable                  *cancellable,
                                                                             GError                       **error);
char *                flatpak_dir_get_config                                (FlatpakDir                    *self,
                                                                             const char                    *key,
                                                                             GError                       **error);
GPtrArray *           flatpak_dir_get_config_patterns                       (FlatpakDir                    *self,
                                                                             const char                    *key);
gboolean              flatpak_dir_set_config                                (FlatpakDir                    *self,
                                                                             const char                    *key,
                                                                             const char                    *value,
                                                                             GError                       **error);
gboolean              flatpak_dir_config_append_pattern                     (FlatpakDir                    *self,
                                                                             const char                    *key,
                                                                             const char                    *pattern,
                                                                             gboolean                       runtime_only,
                                                                             gboolean                      *out_already_present,
                                                                             GError                       **error);
gboolean              flatpak_dir_config_remove_pattern                     (FlatpakDir                    *self,
                                                                             const char                    *key,
                                                                             const char                    *pattern,
                                                                             GError                       **error);
gboolean              flatpak_dir_mark_changed                              (FlatpakDir                    *self,
                                                                             GError                       **error);
gboolean              flatpak_dir_remove_appstream                          (FlatpakDir                    *self,
                                                                             const char                    *remote,
                                                                             GCancellable                  *cancellable,
                                                                             GError                       **error);
gboolean              flatpak_dir_deploy_appstream                          (FlatpakDir                    *self,
                                                                             const char                    *remote,
                                                                             const char                    *arch,
                                                                             gboolean                      *out_changed,
                                                                             GCancellable                  *cancellable,
                                                                             GError                       **error);
gboolean              flatpak_dir_update_appstream                          (FlatpakDir                    *self,
                                                                             const char                    *remote,
                                                                             const char                    *arch,
                                                                             gboolean                      *out_changed,
                                                                             FlatpakProgress               *progress,
                                                                             GCancellable                  *cancellable,
                                                                             GError                       **error);
gboolean              flatpak_dir_pull                                      (FlatpakDir                    *self,
                                                                             FlatpakRemoteState            *state,
                                                                             const char                    *ref,
                                                                             const char                    *opt_rev,
                                                                             const char                   **subpaths,
                                                                             GFile                         *sideload_repo,
                                                                             FlatpakImageSource            *opt_image_source,
                                                                             GBytes                        *require_metadata,
                                                                             const char                    *token,
                                                                             OstreeRepo                    *repo,
                                                                             FlatpakPullFlags               flatpak_flags,
                                                                             OstreeRepoPullFlags            flags,
                                                                             FlatpakProgress               *progress,
                                                                             GCancellable                  *cancellable,
                                                                             GError                       **error);
gboolean              flatpak_dir_pull_untrusted_local                      (FlatpakDir                    *self,
                                                                             const char                    *src_path,
                                                                             const char                    *remote_name,
                                                                             const char                    *ref,
                                                                             const char                   **subpaths,
                                                                             FlatpakProgress               *progress,
                                                                             GCancellable                  *cancellable,
                                                                             GError                       **error);
GPtrArray *           flatpak_dir_list_refs_for_name                        (FlatpakDir                    *self,
                                                                             FlatpakKinds                   kind,
                                                                             const char                    *name,
                                                                             GCancellable                  *cancellable,
                                                                             GError                       **error);
GPtrArray *           flatpak_dir_list_refs                                 (FlatpakDir                    *self,
                                                                             FlatpakKinds                   kinds,
                                                                             GCancellable                  *cancellable,
                                                                             GError                       **error);
gboolean              flatpak_dir_is_runtime_extension                      (FlatpakDir                    *self,
                                                                             FlatpakDecomposed             *ref);
GPtrArray *           flatpak_dir_list_app_refs_with_runtime                (FlatpakDir                    *self,
                                                                             GHashTable                   **runtime_app_map,
                                                                             FlatpakDecomposed             *runtime_ref,
                                                                             GCancellable                  *cancellable,
                                                                             GError                       **error);
GPtrArray *           flatpak_dir_list_app_refs_with_runtime_extension      (FlatpakDir                    *self,
                                                                             GHashTable                   **runtime_app_map,
                                                                             GHashTable                   **extension_app_map,
                                                                             FlatpakDecomposed             *runtime_ext_ref,
                                                                             GCancellable                  *cancellable,
                                                                             GError                       **error);
GVariant *            flatpak_dir_read_latest_commit                        (FlatpakDir                    *self,
                                                                             const char                    *remote,
                                                                             FlatpakDecomposed             *ref,
                                                                             char                         **out_checksum,
                                                                             GCancellable                  *cancellable,
                                                                             GError                       **error);
char *                flatpak_dir_read_latest                               (FlatpakDir                    *self,
                                                                             const char                    *remote,
                                                                             const char                    *ref,
                                                                             char                         **out_alt_id,
                                                                             GCancellable                  *cancellable,
                                                                             GError                       **error);
char *                flatpak_dir_read_active                               (FlatpakDir                    *self,
                                                                             FlatpakDecomposed             *ref,
                                                                             GCancellable                  *cancellable);
gboolean              flatpak_dir_set_active                                (FlatpakDir                    *self,
                                                                             FlatpakDecomposed             *ref,
                                                                             const char                    *checksum,
                                                                             GCancellable                  *cancellable,
                                                                             GError                       **error);
FlatpakDecomposed *   flatpak_dir_current_ref                               (FlatpakDir                    *self,
                                                                             const char                    *name,
                                                                             GCancellable                  *cancellable);
gboolean              flatpak_dir_drop_current_ref                          (FlatpakDir                    *self,
                                                                             const char                    *name,
                                                                             GCancellable                  *cancellable,
                                                                             GError                       **error);
gboolean              flatpak_dir_make_current_ref                          (FlatpakDir                    *self,
                                                                             FlatpakDecomposed             *ref,
                                                                             GCancellable                  *cancellable,
                                                                             GError                       **error);
gboolean              flatpak_dir_list_deployed                             (FlatpakDir                    *self,
                                                                             FlatpakDecomposed             *ref,
                                                                             char                        ***deployed_checksums,
                                                                             GCancellable                  *cancellable,
                                                                             GError                       **error);
gboolean              flatpak_dir_lock                                      (FlatpakDir                    *self,
                                                                             GLnxLockFile                  *lockfile,
                                                                             GCancellable                  *cancellable,
                                                                             GError                       **error);
gboolean              flatpak_dir_repo_lock                                 (FlatpakDir                    *self,
                                                                             GLnxLockFile                  *lockfile,
                                                                             gboolean                       exclusive,
                                                                             GCancellable                  *cancellable,
                                                                             GError                       **error);
gboolean              flatpak_dir_deploy                                    (FlatpakDir                    *self,
                                                                             const char                    *origin,
                                                                             FlatpakDecomposed             *ref,
                                                                             const char                    *checksum_or_latest,
                                                                             const char * const            *subpaths,
                                                                             const char * const            *previous_ids,
                                                                             const char                    *parental_controls_action_id,
                                                                             GCancellable                  *cancellable,
                                                                             GError                       **error);
gboolean              flatpak_dir_deploy_update                             (FlatpakDir                    *self,
                                                                             FlatpakDecomposed             *ref,
                                                                             const char                    *checksum,
                                                                             const char                   **opt_subpaths,
                                                                             const char                   **opt_previous_ids,
                                                                             GCancellable                  *cancellable,
                                                                             GError                       **error);
gboolean              flatpak_dir_deploy_install                            (FlatpakDir                    *self,
                                                                             FlatpakDecomposed             *ref,
                                                                             const char                    *origin,
                                                                             const char                   **subpaths,
                                                                             const char                   **previous_ids,
                                                                             gboolean                       reinstall,
                                                                             gboolean                       pin_on_deploy,
                                                                             gboolean                       update_preinstalled_on_deploy,
                                                                             GCancellable                  *cancellable,
                                                                             GError                       **error);
gboolean              flatpak_dir_install                                   (FlatpakDir                    *self,
                                                                             gboolean                       no_pull,
                                                                             gboolean                       no_deploy,
                                                                             gboolean                       no_static_deltas,
                                                                             gboolean                       reinstall,
                                                                             gboolean                       app_hint,
                                                                             gboolean                       pin_on_deploy,
                                                                             gboolean                       update_preinstalled_on_deploy,
                                                                             FlatpakRemoteState            *state,
                                                                             FlatpakDecomposed             *ref,
                                                                             const char                    *opt_commit,
                                                                             const char                   **subpaths,
                                                                             const char                   **previous_ids,
                                                                             GFile                         *sideload_repo,
                                                                             FlatpakImageSource            *opt_image_source,
                                                                             GBytes                        *require_metadata,
                                                                             const char                    *token,
                                                                             FlatpakProgress               *progress,
                                                                             GCancellable                  *cancellable,
                                                                             GError                       **error);
char *                flatpak_dir_ensure_bundle_remote                      (FlatpakDir                    *self,
                                                                             GFile                         *file,
                                                                             GBytes                        *extra_gpg_data,
                                                                             FlatpakDecomposed            **out_ref,
                                                                             char                         **out_commit,
                                                                             char                         **out_metadata,
                                                                             gboolean                      *out_created_remote,
                                                                             GCancellable                  *cancellable,
                                                                             GError                       **error);
gboolean              flatpak_dir_install_bundle                            (FlatpakDir                    *self,
                                                                             gboolean                       reinstall,
                                                                             GFile                         *file,
                                                                             const char                    *remote,
                                                                             FlatpakDecomposed            **out_ref,
                                                                             GCancellable                  *cancellable,
                                                                             GError                       **error);
gboolean              flatpak_dir_needs_update_for_commit_and_subpaths      (FlatpakDir                    *self,
                                                                             const char                    *remote,
                                                                             FlatpakDecomposed             *ref,
                                                                             const char                    *target_commit,
                                                                             const char                   **opt_subpaths);
char *                flatpak_dir_check_for_update                          (FlatpakDir                    *self,
                                                                             FlatpakRemoteState            *state,
                                                                             FlatpakDecomposed             *ref,
                                                                             const char                    *checksum_or_latest,
                                                                             const char                   **opt_subpaths,
                                                                             gboolean                       no_pull,
                                                                             GCancellable                  *cancellable,
                                                                             GError                       **error);
gboolean              flatpak_dir_update                                    (FlatpakDir                    *self,
                                                                             gboolean                       no_pull,
                                                                             gboolean                       no_deploy,
                                                                             gboolean                       no_static_deltas,
                                                                             gboolean                       allow_downgrade,
                                                                             gboolean                       app_hint,
                                                                             gboolean                       install_hint,
                                                                             FlatpakRemoteState            *state,
                                                                             FlatpakDecomposed             *ref,
                                                                             const char                    *checksum_or_latest,
                                                                             const char                   **opt_subpaths,
                                                                             const char                   **opt_previous_ids,
                                                                             GFile                         *sideload_repo,
                                                                             FlatpakImageSource            *opt_image_source,
                                                                             GBytes                        *require_metadata,
                                                                             const char                    *token,
                                                                             FlatpakProgress               *progress,
                                                                             GCancellable                  *cancellable,
                                                                             GError                       **error);
gboolean              flatpak_dir_uninstall                                 (FlatpakDir                    *self,
                                                                             FlatpakDecomposed             *ref,
                                                                             FlatpakHelperUninstallFlags    flags,
                                                                             GCancellable                  *cancellable,
                                                                             GError                       **error);
gboolean              flatpak_dir_undeploy                                  (FlatpakDir                    *self,
                                                                             FlatpakDecomposed             *ref,
                                                                             const char                    *checksum,
                                                                             gboolean                       is_update,
                                                                             gboolean                       force_remove,
                                                                             GCancellable                  *cancellable,
                                                                             GError                       **error);
gboolean              flatpak_dir_undeploy_all                              (FlatpakDir                    *self,
                                                                             FlatpakDecomposed             *ref,
                                                                             gboolean                       force_remove,
                                                                             gboolean                      *was_deployed_out,
                                                                             GCancellable                  *cancellable,
                                                                             GError                       **error);
gboolean              flatpak_dir_remove_ref                                (FlatpakDir                    *self,
                                                                             const char                    *remote_name,
                                                                             const char                    *ref,
                                                                             GCancellable                  *cancellable,
                                                                             GError                       **error);
gboolean              flatpak_dir_update_exports                            (FlatpakDir                    *self,
                                                                             const char                    *app,
                                                                             GCancellable                  *cancellable,
                                                                             GError                       **error);
gboolean              flatpak_dir_prune                                     (FlatpakDir                    *self,
                                                                             GCancellable                  *cancellable,
                                                                             GError                       **error);
gboolean              flatpak_dir_run_triggers                              (FlatpakDir                    *self,
                                                                             GCancellable                  *cancellable,
                                                                             GError                       **error);
gboolean              flatpak_dir_update_summary                            (FlatpakDir                    *self,
                                                                             gboolean                       delete,
                                                                             GCancellable                  *cancellable,
                                                                             GError                       **error);
gboolean              flatpak_dir_cleanup_removed                           (FlatpakDir                    *self,
                                                                             GCancellable                  *cancellable,
                                                                             GError                       **error);
gboolean              flatpak_dir_cleanup_undeployed_refs                   (FlatpakDir                    *self,
                                                                             GCancellable                  *cancellable,
                                                                             GError                       **error);
gboolean              flatpak_dir_collect_deployed_refs                     (FlatpakDir                    *self,
                                                                             const char                    *type,
                                                                             const char                    *name_prefix,
                                                                             const char                    *arch,
                                                                             const char                    *branch,
                                                                             GHashTable                    *hash,
                                                                             GCancellable                  *cancellable,
                                                                             GError                       **error);
gboolean              flatpak_dir_collect_unmaintained_refs                 (FlatpakDir                    *self,
                                                                             const char                    *name_prefix,
                                                                             const char                    *arch,
                                                                             const char                    *branch,
                                                                             GHashTable                    *hash,
                                                                             GCancellable                  *cancellable,
                                                                             GError                       **error);
gboolean              flatpak_dir_remote_has_deploys                        (FlatpakDir                    *self,
                                                                             const char                    *remote);
char      *           flatpak_dir_create_origin_remote                      (FlatpakDir                    *self,
                                                                             const char                    *url,
                                                                             const char                    *id,
                                                                             const char                    *title,
                                                                             const char                    *main_ref,
                                                                             GBytes                        *gpg_data,
                                                                             const char                    *collection_id,
                                                                             gboolean                      *changed_config,
                                                                             GCancellable                  *cancellable,
                                                                             GError                       **error);
void                  flatpak_dir_prune_origin_remote                       (FlatpakDir                    *self,
                                                                             const char                    *remote);
gboolean              flatpak_dir_create_remote_for_ref_file                (FlatpakDir                    *self,
                                                                             GKeyFile                      *keyfile,
                                                                             const char                    *default_arch,
                                                                             char                         **remote_name_out,
                                                                             char                         **collection_id_out,
                                                                             FlatpakDecomposed            **ref_out,
                                                                             GError                       **error);
gboolean              flatpak_dir_create_suggested_remote_for_ref_file      (FlatpakDir                    *self,
                                                                             GBytes                        *data,
                                                                             GError                       **error);
char      *           flatpak_dir_find_remote_by_uri                        (FlatpakDir                    *self,
                                                                             const char                    *uri);
gboolean              flatpak_dir_has_remote                                (FlatpakDir                    *self,
                                                                             const char                    *remote_name,
                                                                             GError                       **error);
char     **           flatpak_dir_list_remotes                              (FlatpakDir                    *self,
                                                                             GCancellable                  *cancellable,
                                                                             GError                       **error);
char     **           flatpak_dir_list_enumerated_remotes                   (FlatpakDir                    *self,
                                                                             GCancellable                  *cancellable,
                                                                             GError                       **error);
char     **           flatpak_dir_list_dependency_remotes                   (FlatpakDir                    *self,
                                                                             GCancellable                  *cancellable,
                                                                             GError                       **error);
gboolean              flatpak_dir_modify_remote                             (FlatpakDir                    *self,
                                                                             const char                    *remote_name,
                                                                             GKeyFile                      *config,
                                                                             GBytes                        *gpg_data,
                                                                             GCancellable                  *cancellable,
                                                                             GError                       **error);
gboolean              flatpak_dir_remove_remote                             (FlatpakDir                    *self,
                                                                             gboolean                       force_remove,
                                                                             const char                    *remote_name,
                                                                             GCancellable                  *cancellable,
                                                                             GError                       **error);
GPtrArray *           flatpak_dir_get_sideload_repo_paths                   (FlatpakDir                    *self);
char **               flatpak_dir_list_remote_config_keys                   (FlatpakDir                    *self,
                                                                             const char                    *remote_name);
char      *           flatpak_dir_get_remote_title                          (FlatpakDir                    *self,
                                                                             const char                    *remote_name);
char      *           flatpak_dir_get_remote_comment                        (FlatpakDir                    *self,
                                                                             const char                    *remote_name);
char      *           flatpak_dir_get_remote_description                    (FlatpakDir                    *self,
                                                                             const char                    *remote_name);
gint32                flatpak_dir_get_remote_default_token_type             (FlatpakDir                    *self,
                                                                             const char                    *remote_name);
char      *           flatpak_dir_get_remote_homepage                       (FlatpakDir                    *self,
                                                                             const char                    *remote_name);
char      *           flatpak_dir_get_remote_icon                           (FlatpakDir                    *self,
                                                                             const char                    *remote_name);
char      *           flatpak_dir_get_remote_collection_id                  (FlatpakDir                    *self,
                                                                             const char                    *remote_name);
char      *           flatpak_dir_get_remote_main_ref                       (FlatpakDir                    *self,
                                                                             const char                    *remote_name);
gboolean              flatpak_dir_get_remote_oci                            (FlatpakDir                    *self,
                                                                             const char                    *remote_name);
char      *           flatpak_dir_get_remote_default_branch                 (FlatpakDir                    *self,
                                                                             const char                    *remote_name);
int                   flatpak_dir_get_remote_prio                           (FlatpakDir                    *self,
                                                                             const char                    *remote_name);
gboolean              flatpak_dir_get_remote_noenumerate                    (FlatpakDir                    *self,
                                                                             const char                    *remote_name);
gboolean              flatpak_dir_get_remote_nodeps                         (FlatpakDir                    *self,
                                                                             const char                    *remote_name);
char      *           flatpak_dir_get_remote_filter                         (FlatpakDir                    *self,
                                                                             const char                    *remote_name);
char      *           flatpak_dir_get_remote_subset                         (FlatpakDir                    *self,
                                                                             const char                    *remote_name);
gboolean              flatpak_dir_compare_remote_filter                     (FlatpakDir                    *self,
                                                                             const char                    *remote_name,
                                                                             const char                    *filter);
gboolean              flatpak_dir_get_remote_disabled                       (FlatpakDir                    *self,
                                                                             const char                    *remote_name);
gboolean              flatpak_dir_list_remote_refs                          (FlatpakDir                    *self,
                                                                             FlatpakRemoteState            *state,
                                                                             GHashTable                   **refs,
                                                                             GCancellable                  *cancellable,
                                                                             GError                       **error);
gboolean              flatpak_dir_list_all_remote_refs                      (FlatpakDir                    *self,
                                                                             FlatpakRemoteState            *state,
                                                                             GHashTable                   **out_all_refs,
                                                                             GCancellable                  *cancellable,
                                                                             GError                       **error);
gboolean              flatpak_dir_update_remote_configuration               (FlatpakDir                    *self,
                                                                             const char                    *remote,
                                                                             FlatpakRemoteState            *optional_remote_state,
                                                                             gboolean                      *changed_out,
                                                                             GCancellable                  *cancellable,
                                                                             GError                       **error);
gboolean              flatpak_dir_update_remote_configuration_for_state     (FlatpakDir                    *self,
                                                                             FlatpakRemoteState            *remote_state,
                                                                             gboolean                       dry_run,
                                                                             gboolean                      *has_changed_out,
                                                                             GCancellable                  *cancellable,
                                                                             GError                       **error);
FlatpakRemoteState *  flatpak_dir_get_remote_state                          (FlatpakDir                    *self,
                                                                             const char                    *remote,
                                                                             gboolean                       only_cached,
                                                                             GCancellable                  *cancellable,
                                                                             GError                       **error);
FlatpakRemoteState *  flatpak_dir_get_remote_state_for_summary              (FlatpakDir                    *self,
                                                                             const char                    *remote,
                                                                             GBytes                        *opt_summary,
                                                                             GBytes                        *opt_summary_sig,
                                                                             GCancellable                  *cancellable,
                                                                             GError                       **error);
FlatpakRemoteState *  flatpak_dir_get_remote_state_for_index                (FlatpakDir                    *self,
                                                                             const char                    *remote,
                                                                             GBytes                        *opt_index,
                                                                             GBytes                        *opt_index_sig,
                                                                             GCancellable                  *cancellable,
                                                                             GError                       **error);
gboolean              flatpak_dir_migrate_config                            (FlatpakDir                    *self,
                                                                             gboolean                      *changed,
                                                                             GCancellable                  *cancellable,
                                                                             GError                       **error);
gboolean              flatpak_dir_remote_make_oci_summary                   (FlatpakDir                    *self,
                                                                             const char                    *remote,
                                                                             gboolean                       only_cached,
                                                                             GBytes                       **out_summary,
                                                                             GCancellable                  *cancellable,
                                                                             GError                       **error);
FlatpakRemoteState *  flatpak_dir_get_remote_state_optional                 (FlatpakDir                    *self,
                                                                             const char                    *remote,
                                                                             gboolean                       only_cached,
                                                                             GCancellable                  *cancellable,
                                                                             GError                       **error);
FlatpakRemoteState *  flatpak_dir_get_remote_state_local_only               (FlatpakDir                    *self,
                                                                             const char                    *remote,
                                                                             GCancellable                  *cancellable,
                                                                             GError                       **error);
GPtrArray *           flatpak_dir_find_remote_related_for_metadata          (FlatpakDir                    *self,
                                                                             FlatpakRemoteState            *state,
                                                                             FlatpakDecomposed             *ref,
                                                                             GKeyFile                      *metakey,
                                                                             GCancellable                  *cancellable,
                                                                             GError                       **error);
GPtrArray *           flatpak_dir_find_remote_related                       (FlatpakDir                    *dir,
                                                                             FlatpakRemoteState            *state,
                                                                             FlatpakDecomposed             *ref,
                                                                             gboolean                       use_installed_metadata,
                                                                             GCancellable                  *cancellable,
                                                                             GError                       **error);
GPtrArray *           flatpak_dir_find_local_related_for_metadata           (FlatpakDir                    *self,
                                                                             FlatpakDecomposed             *ref,
                                                                             const char                    *remote_name,
                                                                             GKeyFile                      *metakey,
                                                                             GCancellable                  *cancellable,
                                                                             GError                       **error);
GPtrArray *           flatpak_dir_find_local_related                        (FlatpakDir                    *self,
                                                                             FlatpakDecomposed             *ref,
                                                                             const char                    *remote_name,
                                                                             gboolean                       deployed,
                                                                             GCancellable                  *cancellable,
                                                                             GError                       **error);
gboolean              flatpak_dir_find_latest_rev                           (FlatpakDir                    *self,
                                                                             FlatpakRemoteState            *state,
                                                                             const char                    *ref,
                                                                             const char                    *checksum_or_latest,
                                                                             char                         **out_rev,
                                                                             guint64                       *out_timestamp,
                                                                             GFile                        **out_sideload_path,
                                                                             FlatpakImageSource           **out_image_source,
                                                                             GCancellable                  *cancellable,
                                                                             GError                       **error);
FlatpakDecomposed *   flatpak_dir_get_remote_auto_install_authenticator_ref (FlatpakDir                    *self,
                                                                             const char                    *remote_name);
char **               flatpak_dir_get_default_locales                       (FlatpakDir                    *self);
char **               flatpak_dir_get_default_locale_languages              (FlatpakDir                    *self);
char **               flatpak_dir_get_locales                               (FlatpakDir                    *self);
char **               flatpak_dir_get_locale_languages                      (FlatpakDir                    *self);
char **               flatpak_dir_get_locale_subpaths                       (FlatpakDir                    *self);
void                  flatpak_dir_set_subject                               (FlatpakDir                    *self,
                                                                             PolkitSubject                 *subject);
gboolean              flatpak_dir_delete_mirror_refs                        (FlatpakDir                    *self,
                                                                             gboolean                       dry_run,
                                                                             GCancellable                  *cancellable,
                                                                             GError                       **error);
char **               flatpak_dir_list_unused_refs                          (FlatpakDir                    *self,
                                                                             const char                    *arch,
                                                                             GHashTable                    *metadata_injection,
                                                                             GHashTable                    *eol_injection,
                                                                             const char * const            *refs_to_exclude,
                                                                             FlatpakDirFilterFlags          filter_flags,
                                                                             GCancellable                  *cancellable,
                                                                             GError                       **error);
gboolean              flatpak_dir_pull_oci_extra_data                       (OstreeRepo              *repo,
                                                                             FlatpakImageSource      *image_source,
                                                                             const char              *rev,
                                                                             GCancellable            *cancellable,
                                                                             GError                 **error);

#endif /* __FLATPAK_DIR_H__ */

===== ./common/flatpak-uri-private.h =====
/*
 * Copyright © 2022 Red Hat, Inc
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Alexander Larsson <alexl@redhat.com>
 */

#ifndef __FLATPAK_URI_PRIVATE_H__
#define __FLATPAK_URI_PRIVATE_H__

#include <string.h>

#include "flatpak-utils-private.h"

/* This file is mainly a backport of GUri for older versions of glib, and some helpers around it */

void        flatpak_uri_encode_query_arg         (GString    *query,
                                                  const char *key,
                                                  const char *value);
GHashTable *flatpak_parse_http_header_param_list (const char *header);
GDateTime * flatpak_parse_http_time              (const char *date_string);
char *      flatpak_format_http_date             (GDateTime  *date);

/* Same as SOUP_HTTP_URI_FLAGS, means all possible flags for http uris */
#if GLIB_CHECK_VERSION (2, 68, 0) || !GLIB_CHECK_VERSION (2, 66, 0)
#define FLATPAK_HTTP_URI_FLAGS (G_URI_FLAGS_HAS_PASSWORD | G_URI_FLAGS_ENCODED_PATH | G_URI_FLAGS_ENCODED_QUERY | G_URI_FLAGS_ENCODED_FRAGMENT | G_URI_FLAGS_SCHEME_NORMALIZE)
#else
/* GLib 2.66 didn't support scheme-based normalization */
#define FLATPAK_HTTP_URI_FLAGS (G_URI_FLAGS_HAS_PASSWORD | G_URI_FLAGS_ENCODED_PATH | G_URI_FLAGS_ENCODED_QUERY | G_URI_FLAGS_ENCODED_FRAGMENT)
#endif

#if !GLIB_CHECK_VERSION (2, 66, 0)

typedef enum {
  G_URI_FLAGS_NONE            = 0,
  G_URI_FLAGS_PARSE_RELAXED   = 1 << 0,
  G_URI_FLAGS_HAS_PASSWORD    = 1 << 1,
  G_URI_FLAGS_HAS_AUTH_PARAMS = 1 << 2,
  G_URI_FLAGS_ENCODED         = 1 << 3,
  G_URI_FLAGS_NON_DNS         = 1 << 4,
  G_URI_FLAGS_ENCODED_QUERY   = 1 << 5,
  G_URI_FLAGS_ENCODED_PATH    = 1 << 6,
  G_URI_FLAGS_ENCODED_FRAGMENT = 1 << 7,
  G_URI_FLAGS_SCHEME_NORMALIZE = 1 << 8,
} GUriFlags;

typedef enum {
  G_URI_HIDE_NONE        = 0,
  G_URI_HIDE_USERINFO    = 1 << 0,
  G_URI_HIDE_PASSWORD    = 1 << 1,
  G_URI_HIDE_AUTH_PARAMS = 1 << 2,
  G_URI_HIDE_QUERY       = 1 << 3,
  G_URI_HIDE_FRAGMENT    = 1 << 4,
} GUriHideFlags;

typedef struct _GUri GUri;

GUri *       flatpak_g_uri_ref               (GUri           *uri);
void         flatpak_g_uri_unref             (GUri           *uri);
GUri *       flatpak_g_uri_parse             (const gchar    *uri_string,
                                              GUriFlags       flags,
                                              GError        **error);
GUri *       flatpak_g_uri_parse_relative    (GUri           *base_uri,
                                              const gchar    *uri_ref,
                                              GUriFlags       flags,
                                              GError        **error);
char *       flatpak_g_uri_to_string_partial (GUri           *uri,
                                              GUriHideFlags   flags);
GUri *       flatpak_g_uri_build             (GUriFlags       flags,
                                              const gchar    *scheme,
                                              const gchar    *userinfo,
                                              const gchar    *host,
                                              gint            port,
                                              const gchar    *path,
                                              const gchar    *query,
                                              const gchar    *fragment);
const gchar *flatpak_g_uri_get_scheme        (GUri           *uri);
const gchar *flatpak_g_uri_get_userinfo      (GUri           *uri);
const gchar *flatpak_g_uri_get_user          (GUri           *uri);
const gchar *flatpak_g_uri_get_password      (GUri           *uri);
const gchar *flatpak_g_uri_get_auth_params   (GUri           *uri);
const gchar *flatpak_g_uri_get_host          (GUri           *uri);
gint         flatpak_g_uri_get_port          (GUri           *uri);
const gchar *flatpak_g_uri_get_path          (GUri           *uri);
const gchar *flatpak_g_uri_get_query         (GUri           *uri);
const gchar *flatpak_g_uri_get_fragment      (GUri           *uri);
GUriFlags    flatpak_g_uri_get_flags         (GUri           *uri);

G_DEFINE_AUTOPTR_CLEANUP_FUNC(GUri, flatpak_g_uri_unref)

#define g_uri_ref flatpak_g_uri_ref
#define g_uri_unref flatpak_g_uri_unref
#define g_uri_parse flatpak_g_uri_parse
#define g_uri_parse_relative flatpak_g_uri_parse_relative
#define g_uri_to_string_partial flatpak_g_uri_to_string_partial
#define g_uri_build flatpak_g_uri_build
#define g_uri_get_scheme flatpak_g_uri_get_scheme
#define g_uri_get_userinfo flatpak_g_uri_get_userinfo
#define g_uri_get_user flatpak_g_uri_get_user
#define g_uri_get_password flatpak_g_uri_get_password
#define g_uri_get_auth_params flatpak_g_uri_get_auth_params
#define g_uri_get_host flatpak_g_uri_get_host
#define g_uri_get_port flatpak_g_uri_get_port
#define g_uri_get_path flatpak_g_uri_get_path
#define g_uri_get_query flatpak_g_uri_get_query
#define g_uri_get_fragment flatpak_g_uri_get_fragment
#define g_uri_get_flags flatpak_g_uri_get_flags

#endif


#endif /* __FLATPAK_URI_PRIVATE_H__ */

===== ./common/flatpak-appdata-private.h =====
/*
 * Copyright © 2019 Red Hat, Inc
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Matthias Clasen <mclasen@redhat.com>
 */

#ifndef __FLATPAK_APPDATA_PRIVATE_H__
#define __FLATPAK_APPDATA_PRIVATE_H__

#include <glib.h>

gboolean flatpak_parse_appdata (const char  *appdata,
                                const char  *app_id,
                                GHashTable **names,
                                GHashTable **comments,
                                char       **version,
                                char       **license,
                                char       **content_rating_type,
                                GHashTable **content_rating);

#endif /* __FLATPAK_APPDATA_PRIVATE_H__ */

===== ./common/flatpak-auth.c =====
/* vi:set et sw=2 sts=2 cin cino=t0,f0,(0,{s,>2s,n-s,^-s,e-s:
 * Copyright © 2019 Red Hat, Inc
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Alexander Larsson <alexl@redhat.com>
 */

#include "config.h"

#include <glib/gi18n-lib.h>

#include "flatpak-dir-private.h"
#include "flatpak-auth-private.h"
#include "flatpak-utils-private.h"

FlatpakAuthenticator *
flatpak_auth_new_for_remote (FlatpakDir *dir,
                             const char *remote,
                             GCancellable *cancellable,
                             GError **error)
{
  g_autofree char *name = NULL;
  g_autoptr(AutoFlatpakAuthenticator) authenticator = NULL;
  g_autoptr(GVariant) auth_options = NULL;
  g_auto(GStrv) keys = NULL;
  g_autoptr(GVariantBuilder) auth_options_builder = g_variant_builder_new (G_VARIANT_TYPE ("a{sv}"));
  OstreeRepo *repo;
  int i;

  if (!flatpak_dir_ensure_repo (dir, cancellable, error))
    return FALSE;

  repo = flatpak_dir_get_repo (dir);
  if (repo != NULL)
    {
      if (!ostree_repo_get_remote_option (repo, remote, FLATPAK_REMOTE_CONFIG_AUTHENTICATOR_NAME, NULL, &name, error))
        return NULL;
    }

  if (name == NULL && flatpak_dir_get_remote_oci (dir, remote))
    name = g_strdup ("org.flatpak.Authenticator.Oci");

  if (name == NULL || *name == 0 /* or if no repo */)
    {
      flatpak_fail (error, _("No authenticator configured for remote `%s`"), remote);
      return NULL;
    }

  keys = flatpak_dir_list_remote_config_keys (dir, remote);

  for (i = 0; keys != NULL && keys[i] != NULL; i++)
    {
      const char *key = keys[i];
      const char *key_suffix;
      g_autofree char *value = NULL;

      if (!g_str_has_prefix (key, FLATPAK_REMOTE_CONFIG_AUTHENTICATOR_OPTIONS_PREFIX))
        continue;

      key_suffix = key + strlen(FLATPAK_REMOTE_CONFIG_AUTHENTICATOR_OPTIONS_PREFIX);
      if (key_suffix[0] == 0)
        continue;

      if (!ostree_repo_get_remote_option (repo, remote, key, NULL, &value, error))
        return NULL;

      g_variant_builder_add (auth_options_builder, "{sv}", key_suffix, g_variant_new_string(value));
    }

  auth_options = g_variant_ref_sink (g_variant_builder_end (auth_options_builder));

  authenticator = flatpak_authenticator_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION,
                                                                G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES | G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS,
                                                                name,
                                                                FLATPAK_AUTHENTICATOR_OBJECT_PATH,
                                                                cancellable, error);
  if (authenticator == NULL)
    return NULL;

  g_object_set_data_full (G_OBJECT (authenticator), "authenticator-options", g_steal_pointer (&auth_options), (GDestroyNotify)g_variant_unref);
  return g_steal_pointer (&authenticator);
}

char *
flatpak_auth_create_request_path (const char *peer,
                                  const char *token,
                                  GError **error)
{
  g_autofree gchar *escaped_peer = NULL;
  int i;

  for (i = 0; token[i]; i++)
    {
      if (!g_ascii_isalnum (token[i]) && token[i] != '_')
        {
          flatpak_fail (error, "Invalid token %s", token);
          return NULL;
        }
    }

  escaped_peer = g_strdup (peer + 1);
  for (i = 0; escaped_peer[i]; i++)
    if (escaped_peer[i] == '.')
      escaped_peer[i] = '_';

  return g_strconcat (FLATPAK_AUTHENTICATOR_REQUEST_OBJECT_PATH_PREFIX, escaped_peer, "/", token, NULL);
}

FlatpakAuthenticatorRequest *
flatpak_auth_create_request (FlatpakAuthenticator *authenticator,
                             GCancellable *cancellable,
                             GError **error)
{
  static int next_token = 0;
  g_autofree char *request_path = NULL;
  GDBusConnection *bus;
  FlatpakAuthenticatorRequest *request;
  g_autofree char *token = NULL;

  token = g_strdup_printf ("%d", ++next_token);
  bus = g_dbus_proxy_get_connection (G_DBUS_PROXY (authenticator));

  request_path = flatpak_auth_create_request_path (g_dbus_connection_get_unique_name (bus), token, error);
  if (request_path == NULL)
    return NULL;

  request = flatpak_authenticator_request_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION,
                                                                  G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES,
                                                                  g_dbus_proxy_get_name (G_DBUS_PROXY (authenticator)),
                                                                  request_path,
                                                                  cancellable, error);
  if (request == NULL)
    return NULL;

  return request;
}

gboolean
flatpak_auth_request_ref_tokens (FlatpakAuthenticator *authenticator,
                                 FlatpakAuthenticatorRequest *request,
                                 const char *remote,
                                 const char *remote_uri,
                                 GVariant *refs,
                                 GVariant *options,
                                 const char *parent_window,
                                 GCancellable *cancellable,
                                 GError **error)
{
  const char *token;
  GVariant *auth_options;
  g_autofree char *handle = NULL;

  token = strrchr (g_dbus_proxy_get_object_path (G_DBUS_PROXY (request)), '/') + 1;

  auth_options = g_object_get_data (G_OBJECT (authenticator), "authenticator-options");

  if (!flatpak_authenticator_call_request_ref_tokens_sync (authenticator, token, auth_options, remote, remote_uri, refs, options,
                                                           parent_window ? parent_window : "",
                                                           &handle, cancellable, error))
    return FALSE;

  if (strcmp (g_dbus_proxy_get_object_path (G_DBUS_PROXY (request)), handle) !=0)
    {
      /* This shouldn't happen, as it would be a broken authenticator, but lets validate it */
      flatpak_fail (error, "Authenticator returned wrong handle");
      return FALSE;
    }

  return TRUE;
}

===== ./common/meson.build =====
# Copyright 2022 Collabora Ltd.
# SPDX-License-Identifier: LGPL-2.1-or-later

public_headers = [
  'flatpak-bundle-ref.h',
  'flatpak-error.h',
  'flatpak-installation.h',
  'flatpak-installed-ref.h',
  'flatpak-instance.h',
  'flatpak-portal-error.h',
  'flatpak-ref.h',
  'flatpak-related-ref.h',
  'flatpak-remote-ref.h',
  'flatpak-remote.h',
  'flatpak-transaction.h',
  'flatpak.h',
]

install_headers(
  public_headers,
  subdir : 'flatpak',
)

flatpak_version_macros = configure_file(
  input : 'flatpak-version-macros.h.in',
  output : 'flatpak-version-macros.h',
  configuration : {
    'FLATPAK_MAJOR_VERSION' : flatpak_major_version,
    'FLATPAK_MINOR_VERSION' : flatpak_minor_version,
    'FLATPAK_MICRO_VERSION' : flatpak_micro_version,
  },
  install_dir : get_option('includedir') / 'flatpak',
)

# TODO: After the Autotools build system is removed, we can probably
# switch this to gnome.mkenums_simple, but it's easier to keep them
# consistent if we use the same templates
enums = gnome.mkenums(
  'flatpak-enum-types',
  c_template : 'flatpak-enum-types.c.template',
  h_template : 'flatpak-enum-types.h.template',
  install_dir : get_option('includedir') / 'flatpak',
  install_header : true,
  sources : public_headers,
)

flatpak_gdbus = gnome.gdbus_codegen(
  'flatpak-dbus-generated',
  sources : [
    '../data/org.freedesktop.Flatpak.xml',
    '../data/org.freedesktop.Flatpak.Authenticator.xml',
  ],
  interface_prefix : 'org.freedesktop.Flatpak.',
  namespace : 'Flatpak',
)

flatpak_document_gdbus = gnome.gdbus_codegen(
  'flatpak-document-dbus-generated',
  sources: [
    '../data/org.freedesktop.portal.Documents.xml',
  ],
  interface_prefix : 'org.freedesktop.portal.',
  namespace : 'XdpDbus',
)

systemd_gdbus = gnome.gdbus_codegen(
  'flatpak-systemd-dbus-generated',
  sources: [
    '../data/org.freedesktop.systemd1.xml',
  ],
  interface_prefix : 'org.freedesktop.systemd1.',
  namespace : 'Systemd',
)

variant_schema_compiler_command = [
  global_source_root / 'subprojects' / 'variant-schema-compiler' / 'variant-schema-compiler',
]

if get_option('internal_checks')
  variant_schema_compiler_command += ['--internal-validation']
endif

variant_schema_compiler_command += [
  '--outfile', '@OUTPUT0@',
  '--outfile-header', '@OUTPUT1@',
  '--prefix', 'var',
  '@INPUT@',
]

flatpak_variant = custom_target(
  'flatpak-variant-private.h',
  input : [
    '../data/flatpak-variants.gv',
  ],
  output : [
    'flatpak-variant-impl-private.h',
    'flatpak-variant-private.h',
  ],
  build_by_default : true,
  command : variant_schema_compiler_command,
)

libflatpak_common_base_deps = base_deps + [libglnx_dep]

libflatpak_common_base_sources = [
  'flatpak-utils-base.c',
  'flatpak-utils-base-private.h',
] + flatpak_gdbus + flatpak_document_gdbus

built_headers = [
  enums[1],
  flatpak_version_macros,
  flatpak_gdbus[1],
  flatpak_document_gdbus[1],
  systemd_gdbus[1],
  flatpak_variant[1],
]

libflatpak_common_deps = [
  base_deps,
  dconf_dep,
  gpgme_dep,
  json_glib_dep,
  libarchive_dep,
  libcurl_dep,
  libglnx_dep,
  libostree_dep,
  libseccomp_dep,
  libsystemd_dep,
  libxml_dep,
  libzstd_dep,
  malcontent_dep,
  polkit_agent_dep,
  xau_dep,
]
built_sources = []

if build_wayland_security_context
  wayland_scanner_prog = find_program(wayland_scanner.get_variable(pkgconfig: 'wayland_scanner'))
  wayland_protocols_dir = wayland_protocols.get_variable(pkgconfig: 'pkgdatadir')
  wl_security_context_xml = wayland_protocols_dir / 'staging/security-context/security-context-v1.xml'
  wl_security_context = [
    custom_target(
      'security-context-v1-protocol.c',
      input : wl_security_context_xml,
      output : 'security-context-v1-protocol.c',
      command : [wayland_scanner_prog, 'private-code', '@INPUT@', '@OUTPUT@'],
    ),
    custom_target(
      'security-context-v1-protocol.h',
      input : wl_security_context_xml,
      output : 'security-context-v1-protocol.h',
      command : [wayland_scanner_prog, 'client-header', '@INPUT@', '@OUTPUT@'],
    ),
  ]

  libflatpak_common_deps += [wayland_client]
  built_sources += [wl_security_context]
  built_headers += [wl_security_context[1]]
endif

libflatpak_common_base = static_library(
  'flatpak-common-base',
  dependencies : libflatpak_common_base_deps,
  gnu_symbol_visibility : 'hidden',
  include_directories : [common_include_directories],
  install : false,
  sources : libflatpak_common_base_sources,
)
libflatpak_common_base_dep = declare_dependency(
  dependencies : base_deps + [libglnx_dep],
  include_directories : [common_include_directories],
  link_with : [
    libflatpak_common_base,
  ],
  sources : built_headers,
)

sources = [
  'flatpak-appdata.c',
  'flatpak-auth.c',
  'flatpak-bundle-ref.c',
  'flatpak-bwrap.c',
  'flatpak-chain-input-stream.c',
  'flatpak-context.c',
  'flatpak-dir.c',
  'flatpak-dir-utils.c',
  'flatpak-docker-reference.c',
  'flatpak-error.c',
  'flatpak-exports.c',
  'flatpak-glib-backports.c',
  'flatpak-image-collection.c',
  'flatpak-image-source.c',
  'flatpak-installation.c',
  'flatpak-installed-ref.c',
  'flatpak-instance.c',
  'flatpak-json-oci.c',
  'flatpak-json.c',
  'flatpak-locale-utils.c',
  'flatpak-oci-registry.c',
  'flatpak-oci-signatures.c',
  'flatpak-portal-error.c',
  'flatpak-progress.c',
  'flatpak-prune.c',
  'flatpak-ref-utils.c',
  'flatpak-ref.c',
  'flatpak-related-ref.c',
  'flatpak-remote-ref.c',
  'flatpak-remote.c',
  'flatpak-repo-utils.c',
  'flatpak-run.c',
  'flatpak-run-cups.c',
  'flatpak-run-dbus.c',
  'flatpak-run-pulseaudio.c',
  'flatpak-run-sockets.c',
  'flatpak-run-wayland.c',
  'flatpak-run-x11.c',
  'flatpak-transaction.c',
  'flatpak-utils-http.c',
  'flatpak-utils.c',
  'flatpak-uri.c',
  'flatpak-usb.c',
  'flatpak-xml-utils.c',
  'flatpak-zstd-compressor.c',
  'flatpak-zstd-decompressor.c',
]

if malcontent_dep.found()
  sources += ['flatpak-parental-controls.c']
endif

libflatpak_common = static_library(
  'flatpak-common',
  dependencies : [libflatpak_common_base_dep] + libflatpak_common_deps,
  gnu_symbol_visibility : 'hidden',
  include_directories : [common_include_directories],
  install : false,
  sources : enums + public_headers + sources + built_sources + systemd_gdbus + [
    flatpak_variant[0],
    flatpak_variant[1],
  ],
)
libflatpak_common_dep = declare_dependency(
  dependencies : [
    base_deps,
    libflatpak_common_base_dep,
    libglnx_dep,
  ],
  include_directories : [common_include_directories],
  link_with : [
    libflatpak_common,
  ],
  sources : built_headers,
)

libflatpak = library(
  'flatpak',
  'flatpak.c',
  gnu_symbol_visibility : 'hidden',
  include_directories : [common_include_directories],
  install : true,
  link_args : ['-Wl,--export-dynamic'],
  link_whole : [
    libflatpak_common_base,
    libflatpak_common,
  ],
  soversion : '0',
  version : '0.@0@.0'.format(flatpak_binary_age),
)
libflatpak_dep = declare_dependency(
  dependencies : libflatpak_common_deps,
  include_directories : [common_include_directories],
  link_with : [
    libflatpak,
  ],
  sources : built_headers,
)

test_libflatpak = executable(
  'test-libflatpak',
  'test-lib.c',
  dependencies : base_deps + [libglnx_dep, libflatpak_dep],
  install : false,
)

if gir_dep.found()
  gnome.generate_gir(
    libflatpak,
    export_packages : 'flatpak',
    extra_args : [
      '-DFLATPAK_EXTERN=__attribute__((visibility("default"))) extern',
      '-DFLATPAK_COMPILATION=1',
      '--warn-all',
    ],
    header : 'flatpak.h',
    identifier_prefix : 'Flatpak',
    includes : ['GObject-2.0', 'Gio-2.0'],
    install : true,
    namespace : 'Flatpak',
    nsversion : '1.0',
    sources : [
      enums,
      flatpak_version_macros,
      public_headers,
      sources,
    ],
    symbol_prefix : 'flatpak',
  )
endif

===== ./common/flatpak-utils.c =====
/* vi:set et sw=2 sts=2 cin cino=t0,f0,(0,{s,>2s,n-s,^-s,e-s:
 * Copyright © 1995-1998 Free Software Foundation, Inc.
 * Copyright © 2014-2019 Red Hat, Inc
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Alexander Larsson <alexl@redhat.com>
 */

#include "config.h"

#include <glib/gi18n-lib.h>

#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/file.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/utsname.h>
#include <sys/ioctl.h>
#include <termios.h>

#include <glib.h>
#include <gio/gunixoutputstream.h>

#include "flatpak-error.h"
#include "flatpak-utils-base-private.h"
#include "flatpak-utils-private.h"
#include "libglnx.h"
#include "valgrind-private.h"

/* This is also here so the common code can report these errors to the lib */
static const GDBusErrorEntry flatpak_error_entries[] = {
  {FLATPAK_ERROR_ALREADY_INSTALLED,     "org.freedesktop.Flatpak.Error.AlreadyInstalled"},
  {FLATPAK_ERROR_NOT_INSTALLED,         "org.freedesktop.Flatpak.Error.NotInstalled"},
  {FLATPAK_ERROR_ONLY_PULLED,           "org.freedesktop.Flatpak.Error.OnlyPulled"}, /* Since: 1.0 */
  {FLATPAK_ERROR_DIFFERENT_REMOTE,      "org.freedesktop.Flatpak.Error.DifferentRemote"}, /* Since: 1.0 */
  {FLATPAK_ERROR_ABORTED,               "org.freedesktop.Flatpak.Error.Aborted"}, /* Since: 1.0 */
  {FLATPAK_ERROR_SKIPPED,               "org.freedesktop.Flatpak.Error.Skipped"}, /* Since: 1.0 */
  {FLATPAK_ERROR_NEED_NEW_FLATPAK,      "org.freedesktop.Flatpak.Error.NeedNewFlatpak"}, /* Since: 1.0 */
  {FLATPAK_ERROR_REMOTE_NOT_FOUND,      "org.freedesktop.Flatpak.Error.RemoteNotFound"}, /* Since: 1.0 */
  {FLATPAK_ERROR_RUNTIME_NOT_FOUND,     "org.freedesktop.Flatpak.Error.RuntimeNotFound"}, /* Since: 1.0 */
  {FLATPAK_ERROR_DOWNGRADE,             "org.freedesktop.Flatpak.Error.Downgrade"}, /* Since: 1.0 */
  {FLATPAK_ERROR_INVALID_REF,           "org.freedesktop.Flatpak.Error.InvalidRef"}, /* Since: 1.0.3 */
  {FLATPAK_ERROR_INVALID_DATA,          "org.freedesktop.Flatpak.Error.InvalidData"}, /* Since: 1.0.3 */
  {FLATPAK_ERROR_UNTRUSTED,             "org.freedesktop.Flatpak.Error.Untrusted"}, /* Since: 1.0.3 */
  {FLATPAK_ERROR_SETUP_FAILED,          "org.freedesktop.Flatpak.Error.SetupFailed"}, /* Since: 1.0.3 */
  {FLATPAK_ERROR_EXPORT_FAILED,         "org.freedesktop.Flatpak.Error.ExportFailed"}, /* Since: 1.0.3 */
  {FLATPAK_ERROR_REMOTE_USED,           "org.freedesktop.Flatpak.Error.RemoteUsed"}, /* Since: 1.0.3 */
  {FLATPAK_ERROR_RUNTIME_USED,          "org.freedesktop.Flatpak.Error.RuntimeUsed"}, /* Since: 1.0.3 */
  {FLATPAK_ERROR_INVALID_NAME,          "org.freedesktop.Flatpak.Error.InvalidName"}, /* Since: 1.0.3 */
  {FLATPAK_ERROR_OUT_OF_SPACE,          "org.freedesktop.Flatpak.Error.OutOfSpace"}, /* Since: 1.2.0 */
  {FLATPAK_ERROR_WRONG_USER,            "org.freedesktop.Flatpak.Error.WrongUser"}, /* Since: 1.2.0 */
  {FLATPAK_ERROR_NOT_CACHED,            "org.freedesktop.Flatpak.Error.NotCached"}, /* Since: 1.3.3 */
  {FLATPAK_ERROR_REF_NOT_FOUND,         "org.freedesktop.Flatpak.Error.RefNotFound"}, /* Since: 1.4.0 */
  {FLATPAK_ERROR_PERMISSION_DENIED,     "org.freedesktop.Flatpak.Error.PermissionDenied"}, /* Since: 1.5.1 */
  {FLATPAK_ERROR_AUTHENTICATION_FAILED, "org.freedesktop.Flatpak.Error.AuthenticationFailed"}, /* Since: 1.7.3 */
  {FLATPAK_ERROR_NOT_AUTHORIZED,        "org.freedesktop.Flatpak.Error.NotAuthorized"}, /* Since: 1.7.3 */
};

GQuark
flatpak_error_quark (void)
{
  static volatile gsize quark_volatile = 0;

  g_dbus_error_register_error_domain ("flatpak-error-quark",
                                      &quark_volatile,
                                      flatpak_error_entries,
                                      G_N_ELEMENTS (flatpak_error_entries));
  return (GQuark) quark_volatile;
}

gboolean
flatpak_fail_error (GError **error, FlatpakError code, const char *fmt, ...)
{
  if (error == NULL)
    return FALSE;

  va_list args;
  va_start (args, fmt);
  GError *new = g_error_new_valist (FLATPAK_ERROR, code, fmt, args);
  va_end (args);
  g_propagate_error (error, g_steal_pointer (&new));
  return FALSE;
}

GBytes *
flatpak_zlib_compress_bytes (GBytes *bytes,
                             int level,
                             GError **error)
{
  g_autoptr(GZlibCompressor) compressor = NULL;
  g_autoptr(GOutputStream) out = NULL;
  g_autoptr(GOutputStream) mem = NULL;

  mem = g_memory_output_stream_new_resizable ();

  compressor = g_zlib_compressor_new (G_ZLIB_COMPRESSOR_FORMAT_GZIP, level);
  out = g_converter_output_stream_new (mem, G_CONVERTER (compressor));

  if (!g_output_stream_write_all (out, g_bytes_get_data (bytes, NULL), g_bytes_get_size (bytes),
                                  NULL, NULL, error))
    return NULL;

  if (!g_output_stream_close (out, NULL, error))
    return NULL;

  return g_memory_output_stream_steal_as_bytes (G_MEMORY_OUTPUT_STREAM (mem));
}

GBytes *
flatpak_zlib_decompress_bytes (GBytes *bytes,
                               GError **error)
{
  g_autoptr(GZlibDecompressor) decompressor = NULL;
  g_autoptr(GOutputStream) out = NULL;
  g_autoptr(GOutputStream) mem = NULL;

  mem = g_memory_output_stream_new_resizable ();

  decompressor = g_zlib_decompressor_new (G_ZLIB_COMPRESSOR_FORMAT_GZIP);
  out = g_converter_output_stream_new (mem, G_CONVERTER (decompressor));

  if (!g_output_stream_write_all (out, g_bytes_get_data (bytes, NULL), g_bytes_get_size (bytes),
                                  NULL, NULL, error))
    return NULL;

  if (!g_output_stream_close (out, NULL, error))
    return NULL;

  return g_memory_output_stream_steal_as_bytes (G_MEMORY_OUTPUT_STREAM (mem));
}

GBytes *
flatpak_read_stream (GInputStream *in,
                     gboolean      null_terminate,
                     GError      **error)
{
  g_autoptr(GOutputStream) mem_stream = NULL;

  mem_stream = g_memory_output_stream_new_resizable ();
  if (g_output_stream_splice (mem_stream, in,
                              0, NULL, error) < 0)
    return NULL;

  if (null_terminate)
    {
      if (!g_output_stream_write (G_OUTPUT_STREAM (mem_stream), "\0", 1, NULL, error))
        return NULL;
    }

  if (!g_output_stream_close (G_OUTPUT_STREAM (mem_stream), NULL, error))
    return NULL;

  return g_memory_output_stream_steal_as_bytes (G_MEMORY_OUTPUT_STREAM (mem_stream));
}

gint
flatpak_strcmp0_ptr (gconstpointer a,
                     gconstpointer b)
{
  return g_strcmp0 (*(char * const *) a, *(char * const *) b);
}

/* Sometimes this is /var/run which is a symlink, causing weird issues when we pass
 * it as a path into the sandbox */
char *
flatpak_get_real_xdg_runtime_dir (void)
{
  return realpath (g_get_user_runtime_dir (), NULL);
}

/* Compares if str has a specific path prefix. This differs
   from a regular prefix in two ways. First of all there may
   be multiple slashes separating the path elements, and
   secondly, if a prefix is matched that has to be en entire
   path element. For instance /a/prefix matches /a/prefix/foo/bar,
   but not /a/prefixfoo/bar. */
gboolean
flatpak_has_path_prefix (const char *str,
                         const char *prefix)
{
  while (TRUE)
    {
      /* Skip consecutive slashes to reach next path
         element */
      while (*str == '/')
        str++;
      while (*prefix == '/')
        prefix++;

      /* No more prefix path elements? Done! */
      if (*prefix == 0)
        return TRUE;

      /* Compare path element */
      while (*prefix != 0 && *prefix != '/')
        {
          if (*str != *prefix)
            return FALSE;
          str++;
          prefix++;
        }

      /* Matched prefix path element,
         must be entire str path element */
      if (*str != '/' && *str != 0)
        return FALSE;
    }
}

/* Returns end of matching path prefix, or NULL if no match */
const char *
flatpak_path_match_prefix (const char *pattern,
                           const char *string)
{
  char c, test;
  const char *tmp;

  while (*pattern == '/')
    pattern++;

  while (*string == '/')
    string++;

  while (TRUE)
    {
      switch (c = *pattern++)
        {
        case 0:
          if (*string == '/' || *string == 0)
            return string;
          return NULL;

        case '?':
          if (*string == '/' || *string == 0)
            return NULL;
          string++;
          break;

        case '*':
          c = *pattern;

          while (c == '*')
            c = *++pattern;

          /* special case * at end */
          if (c == 0)
            {
              tmp = strchr (string, '/');
              if (tmp != NULL)
                return tmp;
              return string + strlen (string);
            }
          else if (c == '/')
            {
              string = strchr (string, '/');
              if (string == NULL)
                return NULL;
              break;
            }

          while ((test = *string) != 0)
            {
              tmp = flatpak_path_match_prefix (pattern, string);
              if (tmp != NULL)
                return tmp;
              if (test == '/')
                break;
              string++;
            }
          return NULL;

        default:
          if (c != *string)
            return NULL;
          string++;
          break;
        }
    }
  return NULL; /* Should not be reached */
}

static const char *
flatpak_get_kernel_arch (void)
{
  static struct utsname buf;
  static const char *arch = NULL;
  char *m;

  if (arch != NULL)
    return arch;

  if (uname (&buf))
    {
      arch = "unknown";
      return arch;
    }

  /* By default, just pass on machine, good enough for most arches */
  arch = buf.machine;

  /* Override for some arches */

  m = buf.machine;
  /* i?86 */
  if (strlen (m) == 4 && m[0] == 'i' && m[2] == '8'  && m[3] == '6')
    {
      arch = "i386";
    }
  else if (g_str_has_prefix (m, "arm"))
    {
      if (g_str_has_suffix (m, "b"))
        arch = "armeb";
      else
        arch = "arm";
    }
  else if (strcmp (m, "mips") == 0)
    {
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
      arch = "mipsel";
#endif
    }
  else if (strcmp (m, "mips64") == 0)
    {
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
      arch = "mips64el";
#endif
    }

  return arch;
}

/* This maps the kernel-reported uname to a single string representing
 * the cpu family, in the sense that all members of this family would
 * be able to understand and link to a binary file with such cpu
 * opcodes. That doesn't necessarily mean that all members of the
 * family can run all opcodes, for instance for modern 32bit intel we
 * report "i386", even though they support instructions that the
 * original i386 cpu cannot run. Still, such an executable would
 * at least try to execute a 386, whereas an arm binary would not.
 */
const char *
flatpak_get_arch (void)
{
  /* Avoid using uname on multiarch machines, because uname reports the kernels
   * arch, and that may be different from userspace. If e.g. the kernel is 64bit and
   * the userspace is 32bit we want to use 32bit by default. So, we take the current build
   * arch as the default. */
#if defined(__i386__)
  return "i386";
#elif defined(__x86_64__)
  return "x86_64";
#elif defined(__aarch64__)
  return "aarch64";
#elif defined(__arm__)
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
  return "arm";
#else
  return "armeb";
#endif
#else
  return flatpak_get_kernel_arch ();
#endif
}

gboolean
flatpak_is_linux32_arch (const char *arch)
{
  const char *kernel_arch = flatpak_get_kernel_arch ();

  if (strcmp (kernel_arch, "x86_64") == 0 &&
      strcmp (arch, "i386") == 0)
    return TRUE;

  if (strcmp (kernel_arch, "aarch64") == 0 &&
      strcmp (arch, "arm") == 0)
    return TRUE;

  return FALSE;
}

static struct
{
  const char *kernel_arch;
  const char *compat_arch;
} compat_arches[] = {
  { "x86_64", "i386" },
  { "aarch64", "arm" },
};

const char *
flatpak_get_compat_arch (const char *kernel_arch)
{
  int i;

  /* Also add all other arches that are compatible with the kernel arch */
  for (i = 0; i < G_N_ELEMENTS (compat_arches); i++)
    {
      if (strcmp (compat_arches[i].kernel_arch, kernel_arch) == 0)
        return compat_arches[i].compat_arch;
    }

  return NULL;
}

const char *
flatpak_get_compat_arch_reverse (const char *compat_arch)
{
  int i;

  /* Also add all other arches that are compatible with the kernel arch */
  for (i = 0; i < G_N_ELEMENTS (compat_arches); i++)
    {
      if (strcmp (compat_arches[i].compat_arch, compat_arch) == 0)
        return compat_arches[i].kernel_arch;
    }

  return NULL;
}

/* Get all compatible arches for this host in order of priority */
const char **
flatpak_get_arches (void)
{
  static gsize arches = 0;

  if (g_once_init_enter (&arches))
    {
      gsize new_arches = 0;
      const char *main_arch = flatpak_get_arch ();
      const char *kernel_arch = flatpak_get_kernel_arch ();
      const char *compat_arch;
      GPtrArray *array = g_ptr_array_new ();

      /* This is the userspace arch, i.e. the one flatpak itself was
         build for. It's always first. */
      g_ptr_array_add (array, (char *) main_arch);

      compat_arch = flatpak_get_compat_arch (kernel_arch);
      if (g_strcmp0 (compat_arch, main_arch) != 0)
        g_ptr_array_add (array, (char *) compat_arch);

      g_ptr_array_add (array, NULL);
      new_arches = (gsize) g_ptr_array_free (array, FALSE);

      g_once_init_leave (&arches, new_arches);
    }

  return (const char **) arches;
}

static char *
get_os_release_value (const char *key,
                      const char *default_value)
{
  const char *file = "/etc/os-release";
  g_autofree char *contents = NULL;
  g_autoptr(GKeyFile) keyfile = g_key_file_new ();
  g_autoptr(GString) str = NULL;
  g_autofree char *value = NULL;
  g_autofree char *unquoted = NULL;

  if (!g_file_test (file, G_FILE_TEST_EXISTS))
    file = "/usr/lib/os-release";

  if (!g_file_get_contents (file, &contents, NULL, NULL))
    return g_strdup (default_value);

  str = g_string_new (contents);
  g_string_prepend (str, "[os-release]\n");

  if (!g_key_file_load_from_data (keyfile, str->str, -1, G_KEY_FILE_NONE, NULL))
    return g_strdup (default_value);

  value = flatpak_keyfile_get_string_non_empty (keyfile, "os-release", key);
  unquoted = value ? g_shell_unquote (value, NULL) : NULL;

  if (!unquoted)
    return g_strdup (default_value);

  return g_steal_pointer (&unquoted);
}

char *
flatpak_get_os_release_id (void)
{
  return get_os_release_value ("ID", "linux");
}

char *
flatpak_get_os_release_version_id (void)
{
  return get_os_release_value ("VERSION_ID", "unknown");
}

const char **
flatpak_get_gl_drivers (void)
{
  static gsize drivers = 0;

  if (g_once_init_enter (&drivers))
    {
      gsize new_drivers;
      char **new_drivers_c = 0;
      const char *env = g_getenv ("FLATPAK_GL_DRIVERS");
      if (env != NULL && *env != 0)
        new_drivers_c = g_strsplit (env, ":", -1);
      else
        {
          g_autofree char *nvidia_version = NULL;
          char *dot;
          GPtrArray *array = g_ptr_array_new ();

          if (g_file_get_contents ("/sys/module/nvidia/version",
                                   &nvidia_version, NULL, NULL))
            {
              g_strstrip (nvidia_version);
              /* Convert dots to dashes */
              while ((dot = strchr (nvidia_version, '.')) != NULL)
                *dot = '-';
              g_ptr_array_add (array, g_strconcat ("nvidia-", nvidia_version, NULL));
            }

          g_ptr_array_add (array, (char *) "default");
          g_ptr_array_add (array, (char *) "host");

          g_ptr_array_add (array, NULL);
          new_drivers_c = (char **) g_ptr_array_free (array, FALSE);
        }

      new_drivers = (gsize) new_drivers_c;
      g_once_init_leave (&drivers, new_drivers);
    }

  return (const char **) drivers;
}

static gboolean
flatpak_get_have_intel_gpu (void)
{
  static int have_intel = -1;

  if (have_intel == -1)
    have_intel = g_file_test ("/sys/module/i915", G_FILE_TEST_EXISTS) || g_file_test ("/sys/module/xe", G_FILE_TEST_EXISTS);

  return have_intel;
}

static GHashTable *
load_kernel_module_list (void)
{
  GHashTable *modules = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
  g_autofree char *modules_data = NULL;
  g_autoptr(GError) error = NULL;
  char *start, *end;

  if (!g_file_get_contents ("/proc/modules", &modules_data, NULL, &error))
    {
      g_info ("Failed to read /proc/modules: %s", error->message);
      return modules;
    }

  /* /proc/modules is a table of modules.
   * Columns are split by spaces and rows by newlines.
   * The first column is the name. */
  start = modules_data;
  while (TRUE)
    {
      end = strchr (start, ' ');
      if (end == NULL)
        break;

      g_hash_table_add (modules, g_strndup (start, (end - start)));

      start = strchr (end, '\n');
      if (start == NULL)
        break;

      start++;
    }

  return modules;
}

static gboolean
flatpak_get_have_kernel_module (const char *module_name)
{
  static GHashTable *kernel_modules = NULL;

  if (g_once_init_enter (&kernel_modules))
    g_once_init_leave (&kernel_modules, load_kernel_module_list ());

  return g_hash_table_contains (kernel_modules, module_name);
}

static const char *
flatpak_get_gtk_theme (void)
{
  static char *gtk_theme;

  if (g_once_init_enter (&gtk_theme))
    {
      /* The schema may not be installed so check first */
      GSettingsSchemaSource *source = g_settings_schema_source_get_default ();
      g_autoptr(GSettingsSchema) schema = NULL;

      if (source == NULL)
        g_once_init_leave (&gtk_theme, g_strdup (""));
      else
        {
          schema = g_settings_schema_source_lookup (source,
                                                    "org.gnome.desktop.interface", TRUE);

          if (schema == NULL)
            g_once_init_leave (&gtk_theme, g_strdup (""));
          else
            {
              /* GSettings is used to store the theme if you use Wayland or GNOME.
               * TODO: Check XSettings Net/ThemeName for other desktops.
               * We don't care about any other method (like settings.ini) because they
               *   aren't passed through the sandbox anyway. */
              g_autoptr(GSettings) settings = g_settings_new ("org.gnome.desktop.interface");
              g_once_init_leave (&gtk_theme, g_settings_get_string (settings, "gtk-theme"));
            }
        }
    }

  return (const char *) gtk_theme;
}

const char *
flatpak_get_bwrap (void)
{
  const char *e = g_getenv ("FLATPAK_BWRAP");

  if (e != NULL)
    return e;
  return HELPER;
}

gboolean
flatpak_bwrap_is_unprivileged (void)
{
  g_autofree char *path = g_find_program_in_path (flatpak_get_bwrap ());
  struct stat st;

  /* Various features are supported only if bwrap exists and is not setuid */
  return
    path != NULL &&
    stat (path, &st) == 0 &&
    (st.st_mode & S_ISUID) == 0;
}

static char *
line_get_word (char **line)
{
  char *word = NULL;

  while (g_ascii_isspace (**line))
    (*line)++;

  if (**line == 0)
    return NULL;

  word = *line;

  while (**line && !g_ascii_isspace (**line))
    (*line)++;

  if (**line)
    {
      **line = 0;
      (*line)++;
    }

  return word;
}

char *
flatpak_filter_glob_to_regexp (const char  *glob,
                               gboolean     runtime_only,
                               GError     **error)
{
  g_autoptr(GString) regexp = g_string_new ("");
  int parts = 1;
  gboolean empty_part;

  if (g_str_has_prefix (glob, "app/"))
    {
      if (runtime_only)
        {
          flatpak_fail_error (error, FLATPAK_ERROR_INVALID_DATA, _("Glob can't match apps"));
          return NULL;
        }
      else
        {
          glob += strlen ("app/");
          g_string_append (regexp, "app/");
        }
    }
  else if (g_str_has_prefix (glob, "runtime/"))
    {
      glob += strlen ("runtime/");
      g_string_append (regexp, "runtime/");
    }
  else
    {
      if (runtime_only)
        g_string_append (regexp, "runtime/");
      else
        g_string_append (regexp, "(app|runtime)/");
    }

  /* We really need an id part, the rest is optional */
  if (*glob == 0)
    {
      flatpak_fail_error (error, FLATPAK_ERROR_INVALID_DATA, _("Empty glob"));
      return NULL;
    }

  empty_part = TRUE;
  while (*glob != 0)
    {
      char c = *glob;
      glob++;

      if (c == '/')
        {
          if (empty_part)
            g_string_append (regexp, "[.\\-_a-zA-Z0-9]*");
          empty_part = TRUE;
          parts++;
          g_string_append (regexp, "/");
          if (parts > 3)
            {
              flatpak_fail_error (error, FLATPAK_ERROR_INVALID_DATA, _("Too many segments in glob"));
              return NULL;
            }
        }
      else if (c == '*')
        {
          empty_part = FALSE;
         g_string_append (regexp, "[.\\-_a-zA-Z0-9]*");
        }
      else if (c == '.')
        {
          empty_part = FALSE;
          g_string_append (regexp, "\\.");
        }
      else if (g_ascii_isalnum (c) || c == '-' || c == '_')
        {
          empty_part = FALSE;
          g_string_append_c (regexp, c);
        }
      else
        {
          flatpak_fail_error (error, FLATPAK_ERROR_INVALID_DATA, _("Invalid glob character '%c'"), c);
          return NULL;
        }
    }

  while (parts < 3)
    {
      parts++;
      g_string_append (regexp, "/[.\\-_a-zA-Z0-9]*");
    }

  return g_string_free (g_steal_pointer (&regexp), FALSE);
}

gboolean
flatpak_parse_filters (const char *data,
                       GRegex **allow_refs_out,
                       GRegex **deny_refs_out,
                       GError **error)
{
  g_auto(GStrv) lines = NULL;
  int i;
  g_autoptr(GString) allow_regexp = g_string_new ("^(");
  g_autoptr(GString) deny_regexp = g_string_new ("^(");
  gboolean has_allow = FALSE;
  gboolean has_deny = FALSE;
  g_autoptr(GRegex) allow_refs = NULL;
  g_autoptr(GRegex) deny_refs = NULL;

  lines = g_strsplit (data, "\n", -1);
  for (i = 0; lines[i] != NULL; i++)
    {
      char *line = lines[i];
      char *comment, *command;

      /* Ignore shell-style comments */
      comment = strchr (line, '#');
      if (comment != NULL)
        *comment = 0;

      command = line_get_word (&line);
      /* Ignore empty lines */
      if (command == NULL)
        continue;

      if (strcmp (command, "allow") == 0 || strcmp (command, "deny") == 0)
        {
          char *glob, *next;
          g_autofree char *ref_regexp = NULL;
          GString *command_regexp;
          gboolean *has_type = NULL;

          glob = line_get_word (&line);
          if (glob == NULL)
            return flatpak_fail_error (error, FLATPAK_ERROR_INVALID_DATA, _("Missing glob on line %d"), i + 1);

          next = line_get_word (&line);
          if (next != NULL)
            return flatpak_fail_error (error, FLATPAK_ERROR_INVALID_DATA, _("Trailing text on line %d"), i + 1);

          ref_regexp = flatpak_filter_glob_to_regexp (glob, FALSE, error);
          if (ref_regexp == NULL)
            return glnx_prefix_error (error, _("on line %d"), i + 1);

          if (strcmp (command, "allow") == 0)
            {
              command_regexp = allow_regexp;
              has_type = &has_allow;
            }
          else
            {
              command_regexp = deny_regexp;
              has_type = &has_deny;
            }

          if (*has_type)
            g_string_append (command_regexp, "|");
          else
            *has_type = TRUE;

          g_string_append (command_regexp, ref_regexp);
        }
      else
        {
          return flatpak_fail_error (error, FLATPAK_ERROR_INVALID_DATA, _("Unexpected word '%s' on line %d"), command, i + 1);
        }
    }

  g_string_append (allow_regexp, ")$");
  g_string_append (deny_regexp, ")$");

  if (allow_regexp)
    {
      allow_refs = g_regex_new (allow_regexp->str, G_REGEX_DOLLAR_ENDONLY|G_REGEX_RAW|G_REGEX_OPTIMIZE, G_REGEX_MATCH_ANCHORED, error);
      if (allow_refs == NULL)
        return FALSE;
    }

  if (deny_regexp)
    {
      deny_refs = g_regex_new (deny_regexp->str, G_REGEX_DOLLAR_ENDONLY|G_REGEX_RAW|G_REGEX_OPTIMIZE, G_REGEX_MATCH_ANCHORED, error);
      if (deny_refs == NULL)
        return FALSE;
    }

  *allow_refs_out = g_steal_pointer (&allow_refs);
  *deny_refs_out = g_steal_pointer (&deny_refs);

  return TRUE;
}

gboolean
flatpak_filters_allow_ref (GRegex *allow_refs,
                           GRegex *deny_refs,
                           const char *ref)
{
  if (deny_refs == NULL)
    return TRUE; /* All refs are allowed by default */

  if (!g_regex_match (deny_refs, ref, G_REGEX_MATCH_ANCHORED, NULL))
    return TRUE; /* Not denied */

  if (allow_refs &&  g_regex_match (allow_refs, ref, G_REGEX_MATCH_ANCHORED, NULL))
    return TRUE; /* Explicitly allowed */

  return FALSE;
}

static gboolean
remove_dangling_symlinks (int           parent_fd,
                          const char   *name,
                          GCancellable *cancellable,
                          GError      **error)
{
  gboolean ret = FALSE;
  struct dirent *dent;
  g_auto(GLnxDirFdIterator) iter = { 0 };

  if (!glnx_dirfd_iterator_init_at (parent_fd, name, FALSE, &iter, error))
    goto out;

  while (TRUE)
    {
      if (!glnx_dirfd_iterator_next_dent_ensure_dtype (&iter, &dent, cancellable, error))
        goto out;

      if (dent == NULL)
        break;

      if (dent->d_type == DT_DIR)
        {
          if (!remove_dangling_symlinks (iter.fd, dent->d_name, cancellable, error))
            goto out;
        }
      else if (dent->d_type == DT_LNK)
        {
          struct stat stbuf;
          if (fstatat (iter.fd, dent->d_name, &stbuf, 0) != 0 && errno == ENOENT)
            {
              if (unlinkat (iter.fd, dent->d_name, 0) != 0)
                {
                  glnx_set_error_from_errno (error);
                  goto out;
                }
            }
        }
    }

  ret = TRUE;
out:

  return ret;
}

gboolean
flatpak_remove_dangling_symlinks (GFile        *dir,
                                  GCancellable *cancellable,
                                  GError      **error)
{
  gboolean ret = FALSE;

  /* The fd is closed by this call */
  if (!remove_dangling_symlinks (AT_FDCWD, flatpak_file_get_path_cached (dir),
                                 cancellable, error))
    goto out;

  ret = TRUE;

out:
  return ret;
}

static gboolean
flatpak_str_is_alphanumeric (const char *arg)
{
  while (*arg != '\0')
    {
      char c = *arg;

      if (!g_ascii_isalnum (c))
        return FALSE;

      arg++;
    }

  return TRUE;
}

/* This atomically replaces a symlink with a new value, removing the
 * existing symlink target, if it exstis and is different from
 * @target. This is atomic in the sense that we're guaranteed to
 * remove any existing symlink target (once), independent of how many
 * processes do the same operation in parallele. However, it is still
 * possible that we remove the old and then fail to create the new
 * symlink for some reason, ending up with neither the old or the new
 * target. That is fine if the reason for the symlink is keeping a
 * cache though.
 * The target shall only be a file in the same directory as the symlink, and
 * shall only contain the characters a-zA-Z0-9. This is so that the target of
 * the symlink that gets removed is in the same directory as the link.
 */
gboolean
flatpak_switch_symlink_and_remove (const char *symlink_path,
                                   const char *target,
                                   GError    **error)
{
  g_autofree char *symlink_dir = g_path_get_dirname (symlink_path);
  int try;

  for (try = 0; try < 100; try++)
    {
      g_autofree char *tmp_path = NULL;
      int fd;

      /* Try to atomically create the symlink */
      if (TEMP_FAILURE_RETRY (symlink (target, symlink_path)) == 0)
        return TRUE;

      if (errno != EEXIST)
        {
          /* Unexpected failure, bail */
          glnx_set_error_from_errno (error);
          return FALSE;
        }

      /* The symlink existed, move it to a temporary name atomically, and remove target
         if that succeeded. */
      tmp_path = g_build_filename (symlink_dir, ".switched-symlink-XXXXXX", NULL);

      fd = g_mkstemp_full (tmp_path, O_RDWR, 0644);
      if (fd == -1)
        {
          glnx_set_error_from_errno (error);
          return FALSE;
        }
      close (fd);

      if (TEMP_FAILURE_RETRY (rename (symlink_path, tmp_path)) == 0)
        {
          /* The move succeeded, now we can remove the old target */
          g_autofree char *old_target = flatpak_readlink (tmp_path, error);
          if (old_target == NULL)
            return FALSE;

          /* Don't remove old file if its the same as the new one */
          if (strcmp (old_target, target) != 0)
            {
              if (flatpak_str_is_alphanumeric (old_target))
                {
                  g_autofree char *old_target_path = NULL;

                  old_target_path = g_build_filename (symlink_dir, old_target, NULL);
                  unlink (old_target_path);
                }
              else
                {
                  g_warning ("Refusing to delete old link target %s", old_target);
                }
            }
        }
      else if (errno != ENOENT)
        {
          glnx_set_error_from_errno (error);
          unlink (tmp_path);
          return -1;
        }
      unlink (tmp_path);

      /* An old target was removed, try again */
    }

  return flatpak_fail (error, "flatpak_switch_symlink_and_remove looped too many times");
}

gboolean
flatpak_argument_needs_quoting (const char *arg)
{
  if (*arg == '\0')
    return TRUE;

  while (*arg != 0)
    {
      char c = *arg;
      if (!g_ascii_isalnum (c) &&
          !(c == '-' || c == '/' || c == '~' ||
            c == ':' || c == '.' || c == '_' ||
            c == '=' || c == '@'))
        return TRUE;
      arg++;
    }
  return FALSE;
}

char *
flatpak_quote_argv (const char *argv[],
                    gssize      len)
{
  GString *res = g_string_new ("");
  int i;

  if (len == -1)
    len = g_strv_length ((char **) argv);

  for (i = 0; i < len; i++)
    {
      if (i != 0)
        g_string_append_c (res, ' ');

      if (flatpak_argument_needs_quoting (argv[i]))
        {
          g_autofree char *quoted = g_shell_quote (argv[i]);
          g_string_append (res, quoted);
        }
      else
        g_string_append (res, argv[i]);
    }

  return g_string_free (res, FALSE);
}

/* This is useful, because it handles escaped characters in uris, and ? arguments at the end of the uri */
gboolean
flatpak_file_arg_has_suffix (const char *arg, const char *suffix)
{
  g_autoptr(GFile) file = g_file_new_for_commandline_arg (arg);
  g_autofree char *basename = g_file_get_basename (file);

  return g_str_has_suffix (basename, suffix);
}

GFile *
flatpak_build_file_va (GFile  *base,
                       va_list args)
{
  g_autoptr(GFile) res = g_object_ref (base);
  const gchar *arg;

  while ((arg = va_arg (args, const gchar *)))
    {
      g_autoptr(GFile) child = g_file_resolve_relative_path (res, arg);
      g_set_object (&res, child);
    }

  return g_steal_pointer (&res);
}

GFile *
flatpak_build_file (GFile *base, ...)
{
  GFile *res;
  va_list args;

  va_start (args, base);
  res = flatpak_build_file_va (base, args);
  va_end (args);

  return res;
}

const char *
flatpak_file_get_path_cached (GFile *file)
{
  const char *path;
  static GQuark _file_path_quark = 0;

  if (G_UNLIKELY (_file_path_quark == 0))
    _file_path_quark = g_quark_from_static_string ("flatpak-file-path");

  do
    {
      path = g_object_get_qdata ((GObject *) file, _file_path_quark);
      if (path == NULL)
        {
          g_autofree char *new_path = NULL;
          new_path = g_file_get_path (file);
          if (new_path == NULL)
            return NULL;

          if (g_object_replace_qdata ((GObject *) file, _file_path_quark,
                                      NULL, new_path, g_free, NULL))
            path = g_steal_pointer (&new_path);
        }
    }
  while (path == NULL);

  return path;
}

gboolean
flatpak_openat_noatime (int           dfd,
                        const char   *name,
                        int          *ret_fd,
                        GCancellable *cancellable,
                        GError      **error)
{
  int fd;
  int flags = O_RDONLY | O_CLOEXEC;

#ifdef O_NOATIME
  do
    fd = openat (dfd, name, flags | O_NOATIME, 0);
  while (G_UNLIKELY (fd == -1 && errno == EINTR));
  /* Only the owner or superuser may use O_NOATIME; so we may get
   * EPERM.  EINVAL may happen if the kernel is really old...
   */
  if (fd == -1 && (errno == EPERM || errno == EINVAL))
#endif
  do
    fd = openat (dfd, name, flags, 0);
  while (G_UNLIKELY (fd == -1 && errno == EINTR));

  if (fd == -1)
    {
      glnx_set_error_from_errno (error);
      return FALSE;
    }
  else
    {
      *ret_fd = fd;
      return TRUE;
    }
}

gboolean
flatpak_cp_a (GFile         *src,
              GFile         *dest,
              FlatpakCpFlags flags,
              GCancellable  *cancellable,
              GError       **error)
{
  gboolean ret = FALSE;
  GFileEnumerator *enumerator = NULL;
  GFileInfo *src_info = NULL;
  GFile *dest_child = NULL;
  int dest_dfd = -1;
  gboolean merge = (flags & FLATPAK_CP_FLAGS_MERGE) != 0;
  gboolean no_chown = (flags & FLATPAK_CP_FLAGS_NO_CHOWN) != 0;
  gboolean move = (flags & FLATPAK_CP_FLAGS_MOVE) != 0;
  g_autoptr(GFileInfo) child_info = NULL;
  GError *temp_error = NULL;
  int r;

  enumerator = g_file_enumerate_children (src, "standard::type,standard::name,unix::uid,unix::gid,unix::mode",
                                          G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
                                          cancellable, error);
  if (!enumerator)
    goto out;

  src_info = g_file_query_info (src, "standard::name,unix::mode,unix::uid,unix::gid," \
                                     "time::modified,time::modified-usec,time::access,time::access-usec",
                                G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
                                cancellable, error);
  if (!src_info)
    goto out;

  do
    r = mkdir (flatpak_file_get_path_cached (dest), 0755);
  while (G_UNLIKELY (r == -1 && errno == EINTR));
  if (r == -1 &&
      (!merge || errno != EEXIST))
    {
      glnx_set_error_from_errno (error);
      goto out;
    }

  if (!glnx_opendirat (AT_FDCWD, flatpak_file_get_path_cached (dest), TRUE,
                       &dest_dfd, error))
    goto out;

  if (!no_chown)
    {
      do
        r = fchown (dest_dfd,
                    g_file_info_get_attribute_uint32 (src_info, "unix::uid"),
                    g_file_info_get_attribute_uint32 (src_info, "unix::gid"));
      while (G_UNLIKELY (r == -1 && errno == EINTR));
      if (r == -1)
        {
          glnx_set_error_from_errno (error);
          goto out;
        }
    }

  do
    r = fchmod (dest_dfd, g_file_info_get_attribute_uint32 (src_info, "unix::mode"));
  while (G_UNLIKELY (r == -1 && errno == EINTR));

  if (dest_dfd != -1)
    {
      (void) close (dest_dfd);
      dest_dfd = -1;
    }

  while ((child_info = g_file_enumerator_next_file (enumerator, cancellable, &temp_error)))
    {
      const char *name = g_file_info_get_name (child_info);
      g_autoptr(GFile) src_child = g_file_get_child (src, name);

      if (dest_child)
        g_object_unref (dest_child);
      dest_child = g_file_get_child (dest, name);

      if (g_file_info_get_file_type (child_info) == G_FILE_TYPE_DIRECTORY)
        {
          if (!flatpak_cp_a (src_child, dest_child, flags,
                             cancellable, error))
            goto out;
        }
      else
        {
          (void) unlink (flatpak_file_get_path_cached (dest_child));
          GFileCopyFlags copyflags = G_FILE_COPY_OVERWRITE | G_FILE_COPY_NOFOLLOW_SYMLINKS;
          if (!no_chown)
            copyflags |= G_FILE_COPY_ALL_METADATA;
          if (move)
            {
              if (!g_file_move (src_child, dest_child, copyflags,
                                cancellable, NULL, NULL, error))
                goto out;
            }
          else
            {
              if (!g_file_copy (src_child, dest_child, copyflags,
                                cancellable, NULL, NULL, error))
                goto out;
            }
        }

      g_clear_object (&child_info);
    }

  if (temp_error != NULL)
    {
      g_propagate_error (error, temp_error);
      goto out;
    }

  if (move &&
      !g_file_delete (src, NULL, error))
    goto out;

  ret = TRUE;
out:
  if (dest_dfd != -1)
    (void) close (dest_dfd);
  g_clear_object (&src_info);
  g_clear_object (&enumerator);
  g_clear_object (&dest_child);
  return ret;
}

static gboolean
_flatpak_canonicalize_permissions (int         parent_dfd,
                                   const char *rel_path,
                                   gboolean    toplevel,
                                   int         uid,
                                   int         gid,
                                   GError    **error)
{
  struct stat stbuf;
  gboolean res = TRUE;

  /* Note, in order to not leave non-canonical things around in case
   * of error, this continues after errors, but returns the first
   * error. */

  if (TEMP_FAILURE_RETRY (fstatat (parent_dfd, rel_path, &stbuf, AT_SYMLINK_NOFOLLOW)) != 0)
    {
      glnx_set_error_from_errno (error);
      return FALSE;
    }

  if ((uid != -1 && uid != stbuf.st_uid) || (gid != -1 && gid != stbuf.st_gid))
    {
      if (TEMP_FAILURE_RETRY (fchownat (parent_dfd, rel_path, uid, gid, AT_SYMLINK_NOFOLLOW)) != 0)
        {
          glnx_set_error_from_errno (error);
          return FALSE;
        }

      /* Re-read st_mode for new owner */
      if (TEMP_FAILURE_RETRY (fstatat (parent_dfd, rel_path, &stbuf, AT_SYMLINK_NOFOLLOW)) != 0)
        {
          glnx_set_error_from_errno (error);
          return FALSE;
        }
    }

  if (S_ISDIR (stbuf.st_mode))
    {
      g_auto(GLnxDirFdIterator) dfd_iter = { 0, };

      /* For the toplevel we set to 0700 so we can modify it, but not
         expose any non-canonical files to any other user, then we set
         it to 0755 afterwards. */
      if (fchmodat (parent_dfd, rel_path, toplevel ? 0700 : 0755, 0) != 0)
        {
          glnx_set_error_from_errno (error);
          error = NULL;
          res = FALSE;
        }

      if (glnx_dirfd_iterator_init_at (parent_dfd, rel_path, FALSE, &dfd_iter, NULL))
        {
          while (TRUE)
            {
              struct dirent *dent;

              if (!glnx_dirfd_iterator_next_dent (&dfd_iter, &dent, NULL, NULL) || dent == NULL)
                break;

              if (!_flatpak_canonicalize_permissions (dfd_iter.fd, dent->d_name, FALSE, uid, gid, error))
                {
                  error = NULL;
                  res = FALSE;
                }
            }
        }

      if (toplevel &&
          fchmodat (parent_dfd, rel_path, 0755, 0) != 0)
        {
          glnx_set_error_from_errno (error);
          error = NULL;
          res = FALSE;
        }

      return res;
    }
  else if (S_ISREG (stbuf.st_mode))
    {
      mode_t mode;

      /* If use can execute, make executable by all */
      if (stbuf.st_mode & S_IXUSR)
        mode = 0755;
      else /* otherwise executable by none */
        mode = 0644;

      if (fchmodat (parent_dfd, rel_path, mode, 0) != 0)
        {
          glnx_set_error_from_errno (error);
          res = FALSE;
        }
    }
  else if (S_ISLNK (stbuf.st_mode))
    {
      /* symlinks have no permissions */
    }
  else
    {
      /* some weird non-canonical type, lets delete it */
      if (unlinkat (parent_dfd, rel_path, 0) != 0)
        {
          glnx_set_error_from_errno (error);
          res = FALSE;
        }
    }

  return res;
}

/* Canonicalizes files to the same permissions as bare-user-only checkouts */
gboolean
flatpak_canonicalize_permissions (int         parent_dfd,
                                  const char *rel_path,
                                  int         uid,
                                  int         gid,
                                  GError    **error)
{
  return _flatpak_canonicalize_permissions (parent_dfd, rel_path, TRUE, uid, gid, error);
}

/* Make a directory, and its parent. Don't error if it already exists.
 * If you want a failure mode with EEXIST, use g_file_make_directory_with_parents. */
gboolean
flatpak_mkdir_p (GFile        *dir,
                 GCancellable *cancellable,
                 GError      **error)
{
  return glnx_shutil_mkdir_p_at (AT_FDCWD,
                                 flatpak_file_get_path_cached (dir),
                                 0777,
                                 cancellable,
                                 error);
}

gboolean
flatpak_rm_rf (GFile        *dir,
               GCancellable *cancellable,
               GError      **error)
{
  return glnx_shutil_rm_rf_at (AT_FDCWD,
                               flatpak_file_get_path_cached (dir),
                               cancellable, error);
}

gboolean
flatpak_file_rename (GFile        *from,
                     GFile        *to,
                     GCancellable *cancellable,
                     GError      **error)
{
  if (g_cancellable_set_error_if_cancelled (cancellable, error))
    return FALSE;

  if (rename (flatpak_file_get_path_cached (from),
              flatpak_file_get_path_cached (to)) < 0)
    {
      glnx_set_error_from_errno (error);
      return FALSE;
    }

  return TRUE;
}

/* If memfd_create() is available, generate a sealed memfd with contents of
 * @str. Otherwise use an O_TMPFILE @tmpf in anonymous mode, write @str to
 * @tmpf, and lseek() back to the start. See also similar uses in e.g.
 * rpm-ostree for running dracut.
 */
gboolean
flatpak_buffer_to_sealed_memfd_or_tmpfile (GLnxTmpfile *tmpf,
                                           const char  *name,
                                           const char  *str,
                                           size_t       len,
                                           GError     **error)
{
  if (len == -1)
    len = strlen (str);
  glnx_autofd int memfd = memfd_create (name, MFD_CLOEXEC | MFD_ALLOW_SEALING);
  int fd; /* Unowned */
  if (memfd != -1)
    {
      fd = memfd;
    }
  else
    {
      /* We use an anonymous fd (i.e. O_EXCL) since we don't want
       * the target container to potentially be able to re-link it.
       */
      if (!G_IN_SET (errno, ENOSYS, EOPNOTSUPP))
        return glnx_throw_errno_prefix (error, "memfd_create");
      if (!glnx_open_anonymous_tmpfile (O_RDWR | O_CLOEXEC, tmpf, error))
        return FALSE;
      fd = tmpf->fd;
    }
  if (ftruncate (fd, len) < 0)
    return glnx_throw_errno_prefix (error, "ftruncate");
  if (glnx_loop_write (fd, str, len) < 0)
    return glnx_throw_errno_prefix (error, "write");
  if (lseek (fd, 0, SEEK_SET) < 0)
    return glnx_throw_errno_prefix (error, "lseek");
  if (memfd != -1)
    {
      /* Valgrind doesn't currently handle G_ADD_SEALS, so lets not seal when debugging... */
      if ((!RUNNING_ON_VALGRIND) &&
          fcntl (memfd, F_ADD_SEALS, F_SEAL_SHRINK | F_SEAL_GROW | F_SEAL_WRITE | F_SEAL_SEAL) < 0)
        return glnx_throw_errno_prefix (error, "fcntl(F_ADD_SEALS)");
      /* The other values can stay default */
      tmpf->fd = g_steal_fd (&memfd);
      tmpf->initialized = TRUE;
    }
  return TRUE;
}

gboolean
flatpak_open_in_tmpdir_at (int             tmpdir_fd,
                           int             mode,
                           char           *tmpl,
                           GOutputStream **out_stream,
                           GCancellable   *cancellable,
                           GError        **error)
{
  const int max_attempts = 128;
  int i;
  int fd;

  /* 128 attempts seems reasonable... */
  for (i = 0; i < max_attempts; i++)
    {
      glnx_gen_temp_name (tmpl);

      do
        fd = openat (tmpdir_fd, tmpl, O_WRONLY | O_CREAT | O_EXCL, mode);
      while (fd == -1 && errno == EINTR);
      if (fd < 0 && errno != EEXIST)
        {
          glnx_set_error_from_errno (error);
          return FALSE;
        }
      else if (fd != -1)
        break;
    }
  if (i == max_attempts)
    {
      g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
                   "Exhausted attempts to open temporary file");
      return FALSE;
    }

  if (out_stream)
    *out_stream = g_unix_output_stream_new (fd, TRUE);
  else
    (void) close (fd);

  return TRUE;
}

gboolean
flatpak_bytes_save (GFile        *dest,
                    GBytes       *bytes,
                    GCancellable *cancellable,
                    GError      **error)
{
  g_autoptr(GOutputStream) out = NULL;

  out = (GOutputStream *) g_file_replace (dest, NULL, FALSE,
                                          G_FILE_CREATE_REPLACE_DESTINATION,
                                          cancellable, error);
  if (out == NULL)
    return FALSE;

  if (!g_output_stream_write_all (out,
                                  g_bytes_get_data (bytes, NULL),
                                  g_bytes_get_size (bytes),
                                  NULL,
                                  cancellable,
                                  error))
    return FALSE;

  if (!g_output_stream_close (out, cancellable, error))
    return FALSE;

  return TRUE;
}

gboolean
flatpak_variant_save (GFile        *dest,
                      GVariant     *variant,
                      GCancellable *cancellable,
                      GError      **error)
{
  g_autoptr(GOutputStream) out = NULL;
  gsize bytes_written;

  out = (GOutputStream *) g_file_replace (dest, NULL, FALSE,
                                          G_FILE_CREATE_REPLACE_DESTINATION,
                                          cancellable, error);
  if (out == NULL)
    return FALSE;

  if (!g_output_stream_write_all (out,
                                  g_variant_get_data (variant),
                                  g_variant_get_size (variant),
                                  &bytes_written,
                                  cancellable,
                                  error))
    return FALSE;

  if (!g_output_stream_close (out, cancellable, error))
    return FALSE;

  return TRUE;
}

char *
flatpak_keyfile_get_string_non_empty (GKeyFile   *keyfile,
                                      const char *group,
                                      const char *key)
{
  g_autofree char *value = NULL;

  value = g_key_file_get_string (keyfile, group, key, NULL);
  if (value != NULL && *value == '\0')
    g_clear_pointer (&value, g_free);

  return g_steal_pointer (&value);
}

gboolean
flatpak_extension_matches_reason (const char *extension_id,
                                  const char *reasons,
                                  gboolean    default_value)
{
  const char *extension_basename;
  g_auto(GStrv) reason_list = NULL;
  size_t i;

  if (reasons == NULL || *reasons == 0)
    return default_value;

  extension_basename = strrchr (extension_id, '.');
  if (extension_basename == NULL)
    return FALSE;
  extension_basename += 1;

  reason_list = g_strsplit (reasons, ";", -1);

  for (i = 0; reason_list[i]; ++i)
    {
      const char *reason = reason_list[i];

      if (strcmp (reason, "active-gl-driver") == 0)
        {
          /* handled below */
          const char **gl_drivers = flatpak_get_gl_drivers ();
          size_t j;

          for (j = 0; gl_drivers[j]; j++)
            {
              if (strcmp (gl_drivers[j], extension_basename) == 0)
                return TRUE;
            }
        }
      else if (strcmp (reason, "active-gtk-theme") == 0)
        {
          const char *gtk_theme = flatpak_get_gtk_theme ();
          if (strcmp (gtk_theme, extension_basename) == 0)
            return TRUE;
        }
      else if (strcmp (reason, "have-intel-gpu") == 0)
        {
          /* Used for Intel VAAPI driver extension */
          if (flatpak_get_have_intel_gpu ())
            return TRUE;
        }
      else if (g_str_has_prefix (reason, "have-kernel-module-"))
        {
          const char *module_name = reason + strlen ("have-kernel-module-");

          if (flatpak_get_have_kernel_module (module_name))
            return TRUE;
        }
      else if (g_str_has_prefix (reason, "on-xdg-desktop-"))
        {
          const char *desktop_name = reason + strlen ("on-xdg-desktop-");
          const char *current_desktop_var = g_getenv ("XDG_CURRENT_DESKTOP");
          g_auto(GStrv) current_desktop_names = NULL;
          size_t j;

          if (!current_desktop_var)
            continue;

          current_desktop_names = g_strsplit (current_desktop_var, ":", -1);

          for (j = 0; current_desktop_names[j]; ++j)
            {
              if (g_ascii_strcasecmp (desktop_name, current_desktop_names[j]) == 0)
                return TRUE;
            }
        }
    }

  return FALSE;
}

void
flatpak_parse_extension_with_tag (const char *extension,
                                  char      **name,
                                  char      **tag)
{
  const char *tag_chr = strchr (extension, '@');

  if (tag_chr)
    {
      if (name != NULL)
        *name = g_strndup (extension, tag_chr - extension);

      /* Everything after the @ */
      if (tag != NULL)
        *tag = g_strdup (tag_chr + 1);

      return;
    }

  if (name != NULL)
    *name = g_strdup (extension);

  if (tag != NULL)
    *tag = NULL;
}

/* This allocates and locks a subdir of the tmp dir, using an existing
 * one with the same prefix if it is not in use already. */
gboolean
flatpak_allocate_tmpdir (int           tmpdir_dfd,
                         const char   *tmpdir_relpath,
                         const char   *tmpdir_prefix,
                         char        **tmpdir_name_out,
                         int          *tmpdir_fd_out,
                         GLnxLockFile *file_lock_out,
                         gboolean     *reusing_dir_out,
                         GCancellable *cancellable,
                         GError      **error)
{
  gboolean reusing_dir = FALSE;
  g_autofree char *tmpdir_name = NULL;
  glnx_autofd int tmpdir_fd = -1;
  g_auto(GLnxDirFdIterator) dfd_iter = { 0, };

  /* Look for existing tmpdir (with same prefix) to reuse */
  if (!glnx_dirfd_iterator_init_at (tmpdir_dfd, tmpdir_relpath ? tmpdir_relpath : ".", FALSE, &dfd_iter, error))
    return FALSE;

  while (tmpdir_name == NULL)
    {
      struct dirent *dent;
      glnx_autofd int existing_tmpdir_fd = -1;
      g_autoptr(GError) local_error = NULL;
      g_autofree char *lock_name = NULL;

      if (!glnx_dirfd_iterator_next_dent (&dfd_iter, &dent, cancellable, error))
        return FALSE;

      if (dent == NULL)
        break;

      if (!g_str_has_prefix (dent->d_name, tmpdir_prefix))
        continue;

      /* Quickly skip non-dirs, if unknown we ignore ENOTDIR when opening instead */
      if (dent->d_type != DT_UNKNOWN &&
          dent->d_type != DT_DIR)
        continue;

      if (!glnx_opendirat (dfd_iter.fd, dent->d_name, FALSE,
                           &existing_tmpdir_fd, &local_error))
        {
          if (g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_NOT_DIRECTORY))
            {
              continue;
            }
          else
            {
              g_propagate_error (error, g_steal_pointer (&local_error));
              return FALSE;
            }
        }

      lock_name = g_strconcat (dent->d_name, "-lock", NULL);

      /* We put the lock outside the dir, so we can hold the lock
       * until the directory is fully removed */
      if (!glnx_make_lock_file (dfd_iter.fd, lock_name, LOCK_EX | LOCK_NB,
                                file_lock_out, &local_error))
        {
          if (g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK))
            {
              continue;
            }
          else
            {
              g_propagate_error (error, g_steal_pointer (&local_error));
              return FALSE;
            }
        }

      /* Touch the reused directory so that we don't accidentally
       *   remove it due to being old when cleaning up the tmpdir
       */
      (void) futimens (existing_tmpdir_fd, NULL);

      /* We found an existing tmpdir which we managed to lock */
      tmpdir_name = g_strdup (dent->d_name);
      tmpdir_fd = g_steal_fd (&existing_tmpdir_fd);
      reusing_dir = TRUE;
    }

  while (tmpdir_name == NULL)
    {
      g_autofree char *tmpdir_name_template = g_strconcat (tmpdir_prefix, "XXXXXX", NULL);
      g_autoptr(GError) local_error = NULL;
      g_autofree char *lock_name = NULL;
      g_auto(GLnxTmpDir) new_tmpdir = { 0, };
      /* No existing tmpdir found, create a new */

      if (!glnx_mkdtempat (dfd_iter.fd, tmpdir_name_template, 0777,
                           &new_tmpdir, error))
        return FALSE;

      lock_name = g_strconcat (new_tmpdir.path, "-lock", NULL);

      /* Note, at this point we can race with another process that picks up this
       * new directory. If that happens we need to retry, making a new directory. */
      if (!glnx_make_lock_file (dfd_iter.fd, lock_name, LOCK_EX | LOCK_NB,
                                file_lock_out, &local_error))
        {
          if (g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK))
            {
              glnx_tmpdir_unset (&new_tmpdir); /* Don't delete */
              continue;
            }
          else
            {
              g_propagate_error (error, g_steal_pointer (&local_error));
              return FALSE;
            }
        }

      tmpdir_name = g_strdup (new_tmpdir.path);
      tmpdir_fd = dup (new_tmpdir.fd);
      glnx_tmpdir_unset (&new_tmpdir); /* Don't delete */
    }

  if (tmpdir_name_out)
    *tmpdir_name_out = g_steal_pointer (&tmpdir_name);

  if (tmpdir_fd_out)
    *tmpdir_fd_out = g_steal_fd (&tmpdir_fd);

  if (reusing_dir_out)
    *reusing_dir_out = reusing_dir;

  return TRUE;
}

/* Carefully opens a file from a base directory and subpath,
 * making sure that its not a symlink, pipe, etc.
 */
int
flatpak_open_file_at (int           dfd,
                      const char   *subpath,
                      struct stat  *st_buf,
                      GCancellable *cancellable,
                      GError      **error)
{
  glnx_autofd int fd = -1;
  struct stat tmp_st_buf;

  do
    fd = openat (dfd, subpath, O_NOFOLLOW | O_RDONLY | O_NONBLOCK | O_CLOEXEC | O_NOCTTY);
  while (G_UNLIKELY (fd == -1 && errno == EINTR));
  if (fd == -1)
    {
      glnx_set_error_from_errno (error);
      return -1;
    }

  if (st_buf == NULL)
    st_buf = &tmp_st_buf;

  if (fstat (fd, st_buf) != 0)
    {
      glnx_set_error_from_errno (error);
      return -1;
    }

  if (!S_ISREG (st_buf->st_mode))
    {
      g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
                   "Non-regular file not allowed at %s", subpath);
      return -1;
    }

  return g_steal_fd (&fd);
}

/* Carefully gets the content of a file from a base directory and
 * subpath, making sure that its not a symlink.
 */
GBytes *
flatpak_load_file_at (int           dfd,
                      const char   *subpath,
                      GCancellable *cancellable,
                      GError      **error)
{
  glnx_autofd int fd = -1;
  GBytes *bytes;

  fd = flatpak_open_file_at (dfd, subpath, NULL, cancellable, error);
  if (fd == -1)
    return NULL;

  bytes = glnx_fd_readall_bytes (fd, cancellable, error);
  if (bytes == NULL)
    return NULL;

  return bytes;
}

static gint
string_length_compare_func (gconstpointer a,
                            gconstpointer b)
{
  return strlen (*(char * const *) a) - strlen (*(char * const *) b);
}

/* Sort a string array by decreasing length */
char **
flatpak_strv_sort_by_length (const char * const *strv)
{
  GPtrArray *array;
  int i;

  if (strv == NULL)
    return NULL;

  /* Combine both */
  array = g_ptr_array_new ();

  for (i = 0; strv[i] != NULL; i++)
    g_ptr_array_add (array, g_strdup (strv[i]));

  g_ptr_array_sort (array, string_length_compare_func);

  g_ptr_array_add (array, NULL);
  return (char **) g_ptr_array_free (array, FALSE);
}

char **
flatpak_strv_merge (char   **strv1,
                    char   **strv2)
{
  GPtrArray *array;
  int i;

  /* Maybe either (or both) is unspecified */
  if (strv1 == NULL)
    return g_strdupv (strv2);
  if (strv2 == NULL)
    return g_strdupv (strv1);

  /* Combine both */
  array = g_ptr_array_new ();

  for (i = 0; strv1[i] != NULL; i++)
    {
      if (!flatpak_g_ptr_array_contains_string (array, strv1[i]))
        g_ptr_array_add (array, g_strdup (strv1[i]));
    }

  for (i = 0; strv2[i] != NULL; i++)
    {
      if (!flatpak_g_ptr_array_contains_string (array, strv2[i]))
        g_ptr_array_add (array, g_strdup (strv2[i]));
    }

  g_ptr_array_add (array, NULL);
  return (char **) g_ptr_array_free (array, FALSE);
}

/* In this NULL means don't care about these paths, while
   an empty array means match anything */
char **
flatpak_subpaths_merge (char **subpaths1,
                        char **subpaths2)
{
  char **res;

  if (subpaths1 != NULL && subpaths1[0] == NULL)
    return g_strdupv (subpaths1);
  if (subpaths2 != NULL && subpaths2[0] == NULL)
    return g_strdupv (subpaths2);

  res = flatpak_strv_merge (subpaths1, subpaths2);
  if (res)
    qsort (res, g_strv_length (res), sizeof (const char *), flatpak_strcmp0_ptr);

  return res;
}

gboolean
flatpak_g_ptr_array_contains_string (GPtrArray *array, const char *str)
{
  int i;

  for (i = 0; i < array->len; i++)
    {
      if (strcmp (g_ptr_array_index (array, i), str) == 0)
        return TRUE;
    }
  return FALSE;
}

gboolean
flatpak_check_required_version (const char *ref,
                                GKeyFile   *metakey,
                                GError    **error)
{
  g_auto(GStrv) required_versions = NULL;
  const char *group;
  int max_required_major = 0, max_required_minor = 0;
  const char *max_required_version = "0.0";
  int i;

  if (g_str_has_prefix (ref, "app/"))
    group = "Application";
  else
    group = "Runtime";

  /* We handle handle multiple version requirements here. Each requirement must
   * be in the form major.minor.micro, and if the flatpak version matches the
   * major.minor part, t must be equal or later in the micro. If the major.minor part
   * doesn't exactly match any of the specified requirements it must be larger
   * than the maximum specified requirement.
   *
   * For example, specifying
   *   required-flatpak=1.6.2;1.4.2;1.0.2;
   * would allow flatpak versions:
   *  1.7.0, 1.6.2, 1.6.3, 1.4.2, 1.4.3, 1.0.2, 1.0.3
   * but not:
   *  1.6.1, 1.4.1 or 1.2.100.
   *
   * The goal here is to be able to specify a version (like 1.6.2 above) where a feature
   * was introduced, but also allow backports of said feature to earlier version series.
   *
   * Earlier versions that only support specifying one version will only look at the first
   * element in the list, so put the largest version first.
   */
  required_versions = g_key_file_get_string_list (metakey, group, "required-flatpak", NULL, NULL);
  if (required_versions == 0 || required_versions[0] == NULL)
    return TRUE;

  for (i = 0; required_versions[i] != NULL; i++)
    {
      int required_major, required_minor, required_micro;
      const char *required_version = required_versions[i];

      if (sscanf (required_version, "%d.%d.%d", &required_major, &required_minor, &required_micro) != 3)
        return flatpak_fail_error (error, FLATPAK_ERROR_INVALID_DATA,
                                   _("Invalid require-flatpak argument %s"), required_version);
      else
        {
          /* If flatpak is in the same major.minor series as the requirement, do a micro check */
          if (required_major == PACKAGE_MAJOR_VERSION && required_minor == PACKAGE_MINOR_VERSION)
            {
              if (required_micro <= PACKAGE_MICRO_VERSION)
                return TRUE;
              else
                return flatpak_fail_error (error, FLATPAK_ERROR_NEED_NEW_FLATPAK,
                                           _("%s needs a later flatpak version (%s)"),
                                           ref, required_version);
            }

          /* Otherwise, keep track of the largest major.minor that is required */
          if ((required_major > max_required_major) ||
              (required_major == max_required_major &&
               required_minor > max_required_minor))
            {
              max_required_major = required_major;
              max_required_minor = required_minor;
              max_required_version = required_version;
            }
        }
    }

  if (max_required_major > PACKAGE_MAJOR_VERSION ||
      (max_required_major == PACKAGE_MAJOR_VERSION && max_required_minor > PACKAGE_MINOR_VERSION))
    return flatpak_fail_error (error, FLATPAK_ERROR_NEED_NEW_FLATPAK,
                               _("%s needs a later flatpak version (%s)"),
                               ref, max_required_version);

  return TRUE;
}

static int
dist (const char *s, int ls, const char *t, int lt, int i, int j, int *d)
{
  int x, y;

  if (d[i * (lt + 1) + j] >= 0)
    return d[i * (lt + 1) + j];

  if (i == ls)
    x = lt - j;
  else if (j == lt)
    x = ls - i;
  else if (s[i] == t[j])
    x = dist (s, ls, t, lt, i + 1, j + 1, d);
  else
    {
      x = dist (s, ls, t, lt, i + 1, j + 1, d);
      y = dist (s, ls, t, lt, i, j + 1, d);
      if (y < x)
        x = y;
      y = dist (s, ls, t, lt, i + 1, j, d);
      if (y < x)
        x = y;
      x++;
    }

  d[i * (lt + 1) + j] = x;

  return x;
}

int
flatpak_levenshtein_distance (const char *s,
                              gssize ls,
                              const char *t,
                              gssize lt)
{
  int i, j;
  int *d;

  if (ls < 0)
    ls = strlen (s);

  if (lt < 0)
    lt = strlen (t);

  d = alloca (sizeof (int) * (ls + 1) * (lt + 1));

  for (i = 0; i <= ls; i++)
    for (j = 0; j <= lt; j++)
      d[i * (lt + 1) + j] = -1;

  return dist (s, ls, t, lt, 0, 0, d);
}

/* Convert an app id to a dconf path in the obvious way.
 */
char *
flatpak_dconf_path_for_app_id (const char *app_id)
{
  GString *s;
  const char *p;

  s = g_string_new ("");

  g_string_append_c (s, '/');
  for (p = app_id; *p; p++)
    {
      if (*p == '.')
        g_string_append_c (s, '/');
      else
        g_string_append_c (s, *p);
    }
  g_string_append_c (s, '/');

  return g_string_free (s, FALSE);
}

/* Check if two dconf paths are 'similar enough', which
 * for now is defined as equal except case differences
 * and -/_
 */
gboolean
flatpak_dconf_path_is_similar (const char *path1,
                               const char *path2)
{
  int i1, i2;
  int num_components = -1;

  for (i1 = i2 = 0; path1[i1] != '\0'; i1++, i2++)
    {
      if (path2[i2] == '\0')
        break;

      if (isupper(path2[i2]) &&
          (path1[i1] == '-' || path1[i1] == '_'))
        {
          i1++;
          if (path1[i1] == '\0')
            break;
        }

      if (isupper(path1[i1]) &&
          (path2[i2] == '-' || path2[i2] == '_'))
        {
          i2++;
          if (path2[i2] == '\0')
            break;
        }

      if (tolower (path1[i1]) == tolower (path2[i2]))
        {
          if (path1[i1] == '/')
            num_components++;
          continue;
        }

      if ((path1[i1] == '-' || path1[i1] == '_') &&
          (path2[i2] == '-' || path2[i2] == '_'))
        continue;

      break;
    }

  /* Skip over any versioning if we have at least a TLD and
   * domain name, so 2 components */
  /* We need at least TLD, and domain name, so 2 components */
  if (num_components >= 2)
    {
      while (isdigit (path1[i1]))
        i1++;
      while (isdigit (path2[i2]))
        i2++;
    }

  if (path1[i1] != path2[i2])
    return FALSE;

  /* Both strings finished? */
  if (path1[i1] == '\0')
    return TRUE;

  /* Maybe a trailing slash in both strings */
  if (path1[i1] == '/')
    {
      i1++;
      i2++;
    }

  if (path1[i1] != path2[i2])
    return FALSE;

  return (path1[i1] == '\0');
}

GStrv
flatpak_parse_env_block (const char  *data,
                         gsize        length,
                         GError     **error)
{
  g_autoptr(GPtrArray) env_vars = g_ptr_array_new_with_free_func (g_free);
  const char *p = data;
  gsize remaining = length;

  /* env_block might not be \0-terminated */
  while (remaining > 0)
    {
      size_t len = strnlen (p, remaining);
      const char *equals;

      g_assert (len <= remaining);

      equals = memchr (p, '=', len);

      if (equals == NULL || equals == p)
        return glnx_null_throw (error,
                                "Environment variable must be in the form VARIABLE=VALUE, not %.*s", (int) len, p);

      g_ptr_array_add (env_vars,
                       g_strndup (p, len));

      p += len;
      remaining -= len;

      if (remaining > 0)
        {
          g_assert (*p == '\0');
          p += 1;
          remaining -= 1;
        }
    }

  g_ptr_array_add (env_vars, NULL);

  return (GStrv) g_ptr_array_free (g_steal_pointer (&env_vars), FALSE);
}

/**
 * flatpak_envp_cmp:
 * @p1: a `const char * const *`
 * @p2: a `const char * const *`
 *
 * Compare two environment variables, given as pointers to pointers
 * to the actual `KEY=value` string.
 *
 * In particular this is suitable for sorting a #GStrv using `qsort`.
 *
 * Returns: negative, 0 or positive if `*p1` compares before, equal to
 *  or after `*p2`
 */
int
flatpak_envp_cmp (const void *p1,
                  const void *p2)
{
  const char * const * s1 = p1;
  const char * const * s2 = p2;
  size_t l1 = strlen (*s1);
  size_t l2 = strlen (*s2);
  size_t min;
  const char *tmp;
  int ret;

  tmp = strchr (*s1, '=');

  if (tmp != NULL)
    l1 = tmp - *s1;

  tmp = strchr (*s2, '=');

  if (tmp != NULL)
    l2 = tmp - *s2;

  min = MIN (l1, l2);
  ret = strncmp (*s1, *s2, min);

  /* If they differ before the first '=' (if any) in either s1 or s2,
   * then they are certainly different */
  if (ret != 0)
    return ret;

  ret = strcmp (*s1, *s2);

  /* If they do not differ at all, then they are equal */
  if (ret == 0)
    return ret;

  /* FOO < FOO=..., and FOO < FOOBAR */
  if ((*s1)[min] == '\0')
    return -1;

  /* FOO=... > FOO, and FOOBAR > FOO */
  if ((*s2)[min] == '\0')
    return 1;

  /* FOO= < FOOBAR */
  if ((*s1)[min] == '=' && (*s2)[min] != '=')
    return -1;

  /* FOOBAR > FOO= */
  if ((*s2)[min] == '=' && (*s1)[min] != '=')
    return 1;

  /* Fall back to plain string comparison */
  return ret;
}

/*
 * Return %TRUE if @s consists of one or more digits.
 * This is the same as Python bytes.isdigit().
 */
gboolean
flatpak_str_is_integer (const char *s)
{
  if (s == NULL || *s == '\0')
    return FALSE;

  for (; *s != '\0'; s++)
    {
      if (!g_ascii_isdigit (*s))
        return FALSE;
    }

  return TRUE;
}

gboolean
flatpak_uri_equal (const char *uri1,
                   const char *uri2)
{
  g_autofree char *uri1_norm = NULL;
  g_autofree char *uri2_norm = NULL;
  gsize uri1_len = strlen (uri1);
  gsize uri2_len = strlen (uri2);

  /* URIs handled by libostree are equivalent with or without a trailing slash,
   * but this isn't otherwise guaranteed to be the case.
   */
  if (g_str_has_prefix (uri1, "oci+") || g_str_has_prefix (uri2, "oci+"))
    return g_strcmp0 (uri1, uri2) == 0;

  if (g_str_has_suffix (uri1, "/"))
    uri1_norm = g_strndup (uri1, uri1_len - 1);
  else
    uri1_norm = g_strdup (uri1);

  if (g_str_has_suffix (uri2, "/"))
    uri2_norm = g_strndup (uri2, uri2_len - 1);
  else
    uri2_norm = g_strdup (uri2);

  return g_strcmp0 (uri1_norm, uri2_norm) == 0;
}

static gboolean
is_char_safe (gunichar c)
{
  return g_unichar_isgraph (c) || c == ' ';
}

static gboolean
should_hex_escape (gunichar           c,
                   FlatpakEscapeFlags flags)
{
  if ((flags & FLATPAK_ESCAPE_ALLOW_NEWLINES) && c == '\n')
    return FALSE;

  return !is_char_safe (c);
}

static void
append_hex_escaped_character (GString *result,
                              gunichar c)
{
  if (c <= 0xFF)
    g_string_append_printf (result, "\\x%02X", c);
  else if (c <= 0xFFFF)
    g_string_append_printf (result, "\\u%04X", c);
  else
    g_string_append_printf (result, "\\U%08X", c);
}

static char *
escape_character (gunichar c)
{
  g_autoptr(GString) res = g_string_new ("");
  append_hex_escaped_character (res, c);
  return g_string_free (g_steal_pointer (&res), FALSE);
}

char *
flatpak_escape_string (const char        *s,
                       FlatpakEscapeFlags flags)
{
  g_autoptr(GString) res = g_string_new ("");
  gboolean did_escape = FALSE;

  while (*s)
    {
      gunichar c = g_utf8_get_char_validated (s, -1);
      if (c == (gunichar)-2 || c == (gunichar)-1)
        {
          /* Need to convert to unsigned first, to avoid negative chars becoming
             huge gunichars. */
          append_hex_escaped_character (res, (unsigned char)*s++);
          did_escape = TRUE;
          continue;
        }
      else if (should_hex_escape (c, flags))
        {
          append_hex_escaped_character (res, c);
          did_escape = TRUE;
        }
      else if (c == '\\' || (!(flags & FLATPAK_ESCAPE_DO_NOT_QUOTE) && c == '\''))
        {
          g_string_append_printf (res, "\\%c", (char) c);
          did_escape = TRUE;
        }
      else
        g_string_append_unichar (res, c);

      s = g_utf8_find_next_char (s, NULL);
    }

  if (did_escape && !(flags & FLATPAK_ESCAPE_DO_NOT_QUOTE))
    {
      g_string_prepend_c (res, '\'');
      g_string_append_c (res, '\'');
    }

  return g_string_free (g_steal_pointer (&res), FALSE);
}

gboolean
flatpak_validate_path_characters (const char *path,
                                  GError    **error)
{
  while (*path)
    {
      gunichar c = g_utf8_get_char_validated (path, -1);
      if (c == (gunichar)-1 || c == (gunichar)-2)
        {
          /* Need to convert to unsigned first, to avoid negative chars becoming
             huge gunichars. */
          g_autofree char *escaped_char = escape_character ((unsigned char)*path);
          g_autofree char *escaped = flatpak_escape_string (path, FLATPAK_ESCAPE_DEFAULT);
          g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA,
                       "Non-UTF8 byte %s in path %s", escaped_char, escaped);
          return FALSE;
        }
      else if (!is_char_safe (c))
        {
          g_autofree char *escaped_char = escape_character (c);
          g_autofree char *escaped = flatpak_escape_string (path, FLATPAK_ESCAPE_DEFAULT);
          g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA,
                       "Non-graphical character %s in path %s", escaped_char, escaped);
          return FALSE;
        }

      path = g_utf8_find_next_char (path, NULL);
    }

  return TRUE;
}

gboolean
running_under_sudo_root (void)
{
  const char *sudo_command_env = g_getenv ("SUDO_COMMAND");
  g_auto(GStrv) split_command = NULL;

  if (!sudo_command_env)
    return FALSE;

  /* SUDO_COMMAND could be a value like `/usr/bin/flatpak run foo` */
  split_command = g_strsplit (sudo_command_env, " ", 2);
  /* Check if sudo was used to run as root instead of non-root users
   * using -u or -g for example. */
  if (g_str_has_suffix (split_command[0], "flatpak") && geteuid () == 0)
    return TRUE;

  return FALSE;
}

static gboolean is_debugging = FALSE;

void
flatpak_set_debugging (gboolean debugging)
{
  is_debugging = debugging;
}

gboolean
flatpak_is_debugging (void)
{
#if GLIB_CHECK_VERSION (2, 68, 0)
  if (!g_log_writer_default_would_drop (G_LOG_LEVEL_DEBUG, G_LOG_DOMAIN))
    return TRUE;
#endif

  return is_debugging;
}

int
flatpak_parse_fd (const char  *fd_string,
                  GError     **error)
{
  guint64 parsed;
  char *endptr;
  int fd;
  struct stat stbuf;

  parsed = g_ascii_strtoull (fd_string, &endptr, 10);

  if (endptr == NULL || *endptr != '\0' || parsed > G_MAXINT)
    return glnx_fd_throw (error, "Not a valid file descriptor: %s", fd_string);

  fd = (int) parsed;

  if (!glnx_fstat (fd, &stbuf, NULL))
    return glnx_fd_throw (error, "Not an open file descriptor: %d", fd);

  return fd;
}

#ifdef INCLUDE_INTERNAL_TESTS
static GList *flatpak_test_paths = NULL;
static GList *flatpak_test_fns = NULL;

void flatpak_add_test (const char *path, flatpak_test_fn fn)
{
  flatpak_test_paths = g_list_prepend (flatpak_test_paths, (void *)path);
  flatpak_test_fns = g_list_prepend (flatpak_test_fns, fn);
}
#endif

void flatpak_add_all_tests (void)
{
#ifdef INCLUDE_INTERNAL_TESTS
  for (GList *l1 = flatpak_test_paths, *l2 = flatpak_test_fns; l1 != NULL; l1 = l1->next, l2 = l2->next) {
    g_test_add_func (l1->data, l2->data);
  }
#endif
}

/* Sets errno on failure. */
gboolean
flatpak_set_cloexec (int fd)
{
  int flags = fcntl (fd, F_GETFD);

  if (flags == -1)
    return FALSE;

  flags |= FD_CLOEXEC;

  if (fcntl (fd, F_SETFD, flags) < 0)
    return FALSE;

  return TRUE;
}

/*
 * flatpak_accept_fd_argument:
 * @option_name: Name of a command-line option such as `--env-fd`
 * @value: Value of the command-line option
 *
 * Parse a command-line argument whose value is a file descriptor to be
 * used internally by Flatpak.
 *
 * The file descriptor must be 3 or higher (cannot be stdin, stdout
 * or stderr).
 *
 * The file descriptor is set to be close-on-execute (CLOEXEC).
 * If child processes are meant to inherit it, the caller must clear the
 * close-on-execute flag, or duplicate the fd.
 *
 * Returns: A file descriptor to be closed by the caller, or -1 on error
 */
int
flatpak_accept_fd_argument (const char  *option_name,
                            const char  *value,
                            GError     **error)
{
  glnx_autofd int fd = -1;

  fd = flatpak_parse_fd (value, error);

  if (fd < 0)
    {
      g_prefix_error (error, "%s: ", option_name);
      return -1;
    }

  if (fd < 3)
    {
      /* We don't want to close stdin, stdout or stderr */
      fd = -1;
      return glnx_fd_throw (error,
                            "%s: Cannot use reserved file descriptor 0, 1 or 2",
                            option_name);
    }

  if (!flatpak_set_cloexec (fd))
    return glnx_fd_throw_errno_prefix (error, "%s", option_name);

  return g_steal_fd (&fd);
}

/*
 * Attempt to discover the filesystem path corresponding to @fd.
 *
 * If @fd points to an existing file, return the absolute path of that
 * file in the environment where it was opened. Note that this is not
 * necessarily a valid path in the current namespace, if it was
 * transferred via fd-passing from a process in a different filesystem
 * namespace.
 *
 * If @fd points to a deleted file, or to a socket, fifo, memfd or similar
 * non-filesystem object, set an error and return %NULL.
 *
 * Returns: (type filename) (transfer full) (nullable):
 */
char *
flatpak_get_path_for_fd (int        fd,
                         GError   **error)
{
  g_autofree char *proc_path = NULL;
  g_autofree char *path = NULL;

  proc_path = g_strdup_printf ("/proc/self/fd/%d", fd);
  path = glnx_readlinkat_malloc (AT_FDCWD, proc_path, NULL, error);
  if (path == NULL)
    return NULL;

  /* All normal paths start with /, but some weird things
     don't, such as socket:[27345] or anon_inode:[eventfd].
     We don't support any of these */
  if (path[0] != '/')
    {
      return glnx_null_throw (error, "%s resolves to non-absolute path %s",
                              proc_path, path);
    }

  /* File descriptors to actually deleted files have " (deleted)"
     appended to them. This also happens to some fake fd types
     like shmem which are "/<name> (deleted)". All such
     files are considered invalid. Unfortunately this also
     matches files with filenames that actually end in " (deleted)",
     but there is not much to do about this. */
  if (g_str_has_suffix (path, " (deleted)"))
    {
      return glnx_null_throw (error, "%s resolves to deleted path %s",
                              proc_path, path);
    }

  return g_steal_pointer (&path);
}

===== ./common/flatpak-run-sockets-private.h =====
/*
 * Copyright © 2014 Red Hat, Inc
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Alexander Larsson <alexl@redhat.com>
 */

#pragma once

#include "libglnx.h"

#include "flatpak-bwrap-private.h"
#include "flatpak-common-types-private.h"
#include "flatpak-context-private.h"

G_BEGIN_DECLS

void flatpak_run_add_socket_args_environment (FlatpakBwrap          *bwrap,
                                              FlatpakContextShares   shares,
                                              FlatpakContextSockets  sockets,
                                              const char            *app_id,
                                              const char            *instance_id);
void flatpak_run_add_socket_args_late        (FlatpakBwrap          *bwrap,
                                              FlatpakContextShares   shares);

G_END_DECLS

===== ./common/flatpak-progress.c =====
/* vi:set et sw=2 sts=2 cin cino=t0,f0,(0,{s,>2s,n-s,^-s,e-s:
 * Copyright © 2019 Endless Mobile, Inc
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Philip Chimento <philip@endlessm.com>
 */

#include "config.h"

#include <glib-object.h>
#include <glib/gi18n-lib.h>

#include "flatpak-progress-private.h"

static OstreeAsyncProgress *flatpak_progress_issue_ostree_progress (FlatpakProgress *self);
static void flatpak_progress_revoke_ostree_progress (FlatpakProgress     *self,
                                                     OstreeAsyncProgress *ostree_progress);

void
flatpak_main_context_wait (FlatpakMainContext *self,
                           gpointer           *watch_location)
{
  while (*watch_location == NULL)
    g_main_context_iteration (self->context, TRUE);
}

void
flatpak_main_context_finish (FlatpakMainContext *self)
{
  if (self->context == NULL)
    return;

  /* Ensure we don't leave some cleanup callbacks unhandled as we will never iterate this context again. */
  while (g_main_context_pending (self->context))
    g_main_context_iteration (self->context, TRUE);

  if (self->flatpak_progress)
    flatpak_progress_revoke_ostree_progress (self->flatpak_progress, self->ostree_progress);
  else
    g_object_unref (self->ostree_progress);

  g_main_context_pop_thread_default (self->context);
  g_main_context_unref (self->context);
}

void
flatpak_progress_init_main_context (FlatpakProgress    *maybe_progress,
                                    FlatpakMainContext *context)
{
  context->context = g_main_context_new ();
  g_main_context_push_thread_default (context->context);

  context->flatpak_progress = maybe_progress;
  if (maybe_progress)
    context->ostree_progress = flatpak_progress_issue_ostree_progress (maybe_progress);
  else
    context->ostree_progress = ostree_async_progress_new ();
}

struct _FlatpakProgress
{
  GObject parent;

  /* Callback */
  FlatpakProgressCallback callback;
  gpointer                user_data;

  char                   *status;

  /* Extra data information */

  guint64 start_time_extra_data;
  guint64 outstanding_extra_data;
  guint64 total_extra_data;
  guint64 transferred_extra_data_bytes;
  guint64 total_extra_data_bytes;    /* the sum of all extra data file sizes (in bytes) */
  guint64 extra_data_previous_dl;

  /* OCI pull information */
  char   *ostree_status;    /* only sent by OSTree when the pull ends (with or without an error) */
  guint64 start_time;
  guint64 bytes_transferred;    /* every and all transferred data (in bytes) */
  guint64 fetched_delta_part_size;    /* the size (in bytes) of already fetched static deltas */
  guint64 total_delta_part_size;    /* the total size (in bytes) of static deltas */
  guint64 total_delta_part_usize;
  guint   outstanding_fetches;    /* missing fetches (metadata + content + deltas) */
  guint   outstanding_writes;    /* all missing writes (sum of outstanding content, metadata and delta writes) */
  guint   fetched;    /* sum of content + metadata fetches */
  guint   requested;    /* sum of requested content + metadata fetches */
  guint   scanning;
  guint   scanned_metadata;
  guint   outstanding_metadata_fetches;    /* missing metadata-only fetches */
  guint   metadata_fetched;    /* the number of fetched metadata objects */
  guint   fetched_delta_parts;
  guint   total_delta_parts;
  guint   fetched_delta_fallbacks;
  guint   total_delta_fallbacks;
  guint   total_delta_superblocks;

  /* Self-progress-reporting fields, not from OSTree */
  guint   progress;
  guint   last_total;

  guint32 update_interval;

  /* Flags */
  guint downloading_extra_data : 1;   /* whether extra-data files are being downloaded or not */
  guint caught_error           : 1;
  guint estimating             : 1;
  guint last_was_metadata      : 1;
  guint done                   : 1;
  guint reported_overflow      : 1;
};

G_DEFINE_TYPE (FlatpakProgress, flatpak_progress, G_TYPE_OBJECT);

static void
flatpak_progress_finalize (GObject *object)
{
  FlatpakProgress *self = FLATPAK_PROGRESS (object);

  g_clear_pointer (&self->status, g_free);
  g_clear_pointer (&self->ostree_status, g_free);

  G_OBJECT_CLASS (flatpak_progress_parent_class)->finalize (object);
}

static void
flatpak_progress_class_init (FlatpakProgressClass *klass)
{
  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
  gobject_class->finalize = flatpak_progress_finalize;
}

static void
flatpak_progress_init (FlatpakProgress *self)
{
  self->status = g_strdup ("Initializing");
  self->ostree_status = g_strdup ("");
  self->estimating = TRUE;
  self->last_was_metadata = TRUE;
  self->update_interval = FLATPAK_DEFAULT_UPDATE_INTERVAL_MS;
}

FlatpakProgress *
flatpak_progress_new (FlatpakProgressCallback callback,
                      gpointer                user_data)
{
  FlatpakProgress *retval;

  retval = g_object_new (FLATPAK_TYPE_PROGRESS, NULL);
  retval->callback = callback;
  retval->user_data = user_data;

  return retval;
}

static inline guint
get_write_progress (guint outstanding_writes)
{
  return outstanding_writes > 0 ? (guint) (3 / (gdouble) outstanding_writes) : 3;
}

static void
update_status_progress_and_estimating (FlatpakProgress *self)
{
  GString *buf;
  guint64 total = 0;
  guint64 elapsed_time;
  guint new_progress = 0;
  gboolean estimating = FALSE;
  guint64 total_transferred;
  gboolean last_was_metadata = self->last_was_metadata;
  g_autofree gchar *formatted_bytes_total_transferred = NULL;

  /* We get some extra calls before we've really started due to the initialization of the
     extra data, so ignore those */
  if (self->requested == 0)
    {
      return;
    }

  buf = g_string_new ("");

  /* The heuristic here goes as follows:
   *  - While fetching metadata, grow up to 5%
   *  - Download goes up to 97%
   *  - Writing objects adds the last 3%
   */

  elapsed_time = (g_get_monotonic_time () - self->start_time) / G_USEC_PER_SEC;

  /* When we receive the status, it means that the ostree pull operation is
   * finished. We only have to be careful about the extra-data fields. */
  if (*self->ostree_status && self->total_extra_data_bytes == 0)
    {
      g_string_append (buf, self->ostree_status);
      new_progress = 100;
      goto out;
    }

  total_transferred = self->bytes_transferred + self->transferred_extra_data_bytes;
  formatted_bytes_total_transferred =  g_format_size_full (total_transferred, 0);

  self->last_was_metadata = FALSE;

  if (self->total_delta_parts == 0 &&
      (self->outstanding_metadata_fetches > 0 || last_was_metadata)  &&
      self->metadata_fetched < 20)
    {
      /* We need to hit two callbacks with no metadata outstanding, because
         sometimes we get called when we just handled a metadata, but did
         not yet process it and add more metadata */
      if (self->outstanding_metadata_fetches > 0)
        self->last_was_metadata = TRUE;

      /* At this point we don't really know how much data there is, so we have to make a guess.
       * Since its really hard to figure out early how much data there is we report 1% until
       * all objects are scanned. */

      estimating = TRUE;

      g_string_append_printf (buf, _("Downloading metadata: %u/(estimating) %s"),
                              self->fetched, formatted_bytes_total_transferred);

      /* Go up to 5% until the metadata is all fetched */
      new_progress = 0;
      if (self->requested > 0)
        new_progress = self->fetched * 5 / self->requested;
    }
  else
    {
      if (self->total_delta_parts > 0)
        {
          g_autofree gchar *formatted_bytes_total = NULL;

          /* We're only using deltas, so we can ignore regular objects
           * and get perfect sizes.
           *
           * fetched_delta_part_size is the total size of all the
           * delta parts and fallback objects that were already
           * available at the start and need not be downloaded.
           */
          total = self->total_delta_part_size - self->fetched_delta_part_size + self->total_extra_data_bytes;
          formatted_bytes_total = g_format_size_full (total, 0);

          g_string_append_printf (buf, _("Downloading: %s/%s"),
                                  formatted_bytes_total_transferred,
                                  formatted_bytes_total);
        }
      else
        {
          /* Non-deltas, so we can't know anything other than object
             counts, except the additional extra data which we know
             the byte size of. To be able to compare them with the
             extra data we use the average object size to estimate a
             total size. */
          double average_object_size = 1;
          if (self->fetched > 0)
            average_object_size = self->bytes_transferred / (double) self->fetched;

          total = average_object_size * self->requested + self->total_extra_data_bytes;

          if (self->downloading_extra_data)
            {
              g_autofree gchar *formatted_bytes_total = g_format_size_full (total, 0);
              g_string_append_printf (buf, _("Downloading extra data: %s/%s"),
                                      formatted_bytes_total_transferred,
                                      formatted_bytes_total);
            }
          else
            g_string_append_printf (buf, _("Downloading files: %d/%d %s"),
                                    self->fetched, self->requested, formatted_bytes_total_transferred);
        }

      /* The download progress goes up to 97% */
      if (total > 0)
        {
          new_progress = 5 + ((total_transferred / (gdouble) total) * 92);
        }
      else
        {
          new_progress = 97;
        }

      /* And the writing of the objects adds 3% to the progress */
      new_progress += get_write_progress (self->outstanding_writes);
    }

  if (elapsed_time > 0) // Ignore first second
    {
      g_autofree gchar *formatted_bytes_sec = g_format_size (total_transferred / elapsed_time);
      g_string_append_printf (buf, " (%s/s)", formatted_bytes_sec);
    }

out:
  if (new_progress < self->progress && self->last_total == total)
    new_progress = self->progress;
  self->last_total = total;

  if (new_progress > 100)
    {
      if (!self->reported_overflow)
        g_info ("Unexpectedly got > 100%% progress, limiting");
      self->reported_overflow = TRUE;
      new_progress = 100;
    }

  g_free (self->status);
  self->status = g_string_free (buf, FALSE);
  self->progress = new_progress;
  self->estimating = estimating;
}

void
flatpak_progress_init_extra_data (FlatpakProgress *self,
                                  guint64          n_extra_data,
                                  guint64          total_download_size)
{
  if (self == NULL)
    return;

  self->outstanding_extra_data = n_extra_data;
  self->total_extra_data = n_extra_data;
  self->transferred_extra_data_bytes = 0;
  self->total_extra_data_bytes = total_download_size;
  self->downloading_extra_data = FALSE;
  self->progress = 0;
  update_status_progress_and_estimating (self);
}

void
flatpak_progress_start_extra_data (FlatpakProgress *self)
{
  if (self == NULL)
    return;

  g_assert (self->outstanding_extra_data > 0);

  self->start_time_extra_data = g_get_monotonic_time ();
  self->downloading_extra_data = TRUE;
  update_status_progress_and_estimating (self);
}

void
flatpak_progress_reset_extra_data (FlatpakProgress *self)
{
  if (self == NULL)
    return;

  self->downloading_extra_data = FALSE;
  update_status_progress_and_estimating (self);
}

void
flatpak_progress_update_extra_data (FlatpakProgress *self,
                                    guint64          downloaded_bytes)
{
  if (self == NULL)
    return;

  self->transferred_extra_data_bytes = self->extra_data_previous_dl + downloaded_bytes;
  update_status_progress_and_estimating (self);

  self->callback (self->status, self->progress, self->estimating, self->user_data);
}

void
flatpak_progress_complete_extra_data_download (FlatpakProgress *self,
                                               guint64          download_size)
{
  if (self == NULL)
    return;

  g_assert (self->outstanding_extra_data > 0);

  self->extra_data_previous_dl += download_size;
  self->outstanding_extra_data--;
  update_status_progress_and_estimating (self);
}

void
flatpak_progress_start_oci_pull (FlatpakProgress *self)
{
  if (self == NULL)
    return;

  self->start_time = g_get_monotonic_time () - 2;
  self->outstanding_fetches = 0;
  self->outstanding_writes = 0;
  self->fetched = 0;
  self->requested = 0;
  self->scanning = 0;
  self->scanned_metadata = 0;
  self->bytes_transferred = 0;
  self->outstanding_metadata_fetches = 0;
  self->metadata_fetched = 0;
  self->outstanding_extra_data = 0;
  self->total_extra_data = 0;
  self->total_extra_data_bytes = 0;
  self->downloading_extra_data = FALSE;
  self->fetched_delta_parts = 0;
  self->total_delta_parts = 0;
  self->fetched_delta_fallbacks = 0;
  self->total_delta_fallbacks = 0;
  self->fetched_delta_part_size = 0;
  self->total_delta_part_size = 0;
  self->total_delta_part_usize = 0;
  self->total_delta_superblocks = 0;
  self->caught_error = FALSE;
  update_status_progress_and_estimating (self);
}

void
flatpak_progress_update_oci_pull (FlatpakProgress *self,
                                  guint64          total_size,
                                  guint64          pulled_size,
                                  guint32          n_layers,
                                  guint32          pulled_layers)
{
  if (self == NULL)
    return;

  self->requested = n_layers; /* Need to set this to trigger start of progress reporting, see update_status_progress_and_estimating() */
  self->outstanding_fetches = n_layers - pulled_layers;
  self->fetched_delta_parts = pulled_layers;
  self->total_delta_parts = n_layers;
  self->fetched_delta_fallbacks = 0;
  self->total_delta_fallbacks = 0;
  self->bytes_transferred = pulled_size;
  self->total_delta_part_size = total_size;
  self->total_delta_part_usize = total_size;
  self->total_delta_superblocks = 0;
  update_status_progress_and_estimating (self);

  self->callback (self->status, self->progress, self->estimating, self->user_data);
}

guint32
flatpak_progress_get_update_interval (FlatpakProgress *self)
{
  if (self == NULL)
    return FLATPAK_DEFAULT_UPDATE_INTERVAL_MS;
  return self->update_interval;
}

void
flatpak_progress_set_update_interval (FlatpakProgress *self,
                                      guint32          interval)
{
  self->update_interval = interval;
}

guint64
flatpak_progress_get_bytes_transferred (FlatpakProgress *self)
{
  return self->bytes_transferred;
}

guint64
flatpak_progress_get_transferred_extra_data_bytes (FlatpakProgress *self)
{
  return self->transferred_extra_data_bytes;
}

guint64
flatpak_progress_get_start_time (FlatpakProgress *self)
{
  return self->start_time;
}

const char *
flatpak_progress_get_status (FlatpakProgress *self)
{
  return self->status;
}

int
flatpak_progress_get_progress (FlatpakProgress *self)
{
  return self->progress;
}

gboolean
flatpak_progress_get_estimating (FlatpakProgress *self)
{
  return self->estimating;
}

static void
copy_ostree_progress_state (OstreeAsyncProgress *ostree_progress,
                            FlatpakProgress     *self)
{
  gboolean downloading_extra_data, caught_error;

  g_clear_pointer (&self->ostree_status, g_free);

  ostree_async_progress_get (ostree_progress,
                             "start-time-extra-data", "t", &self->start_time_extra_data,
                             "outstanding-extra-data", "t", &self->outstanding_extra_data,
                             "total-extra-data", "t", &self->total_extra_data,
                             "transferred-extra-data-bytes", "t", &self->transferred_extra_data_bytes,
                             "total-extra-data-bytes", "t", &self->total_extra_data_bytes,
                             "status", "s", &self->ostree_status,
                             "start-time", "t", &self->start_time,
                             "bytes-transferred", "t", &self->bytes_transferred,
                             "fetched-delta-part-size", "t", &self->fetched_delta_part_size,
                             "total-delta-part-size", "t", &self->total_delta_part_size,
                             "total-delta-part-usize", "t", &self->total_delta_part_usize,
                             "outstanding-fetches", "u", &self->outstanding_fetches,
                             "outstanding-writes", "u", &self->outstanding_writes,
                             "fetched", "u", &self->fetched,
                             "requested", "u", &self->requested,
                             "scanning", "u", &self->scanning,
                             "scanned-metadata", "u", &self->scanned_metadata,
                             "outstanding-metadata-fetches", "u", &self->outstanding_metadata_fetches,
                             "metadata-fetched", "u", &self->metadata_fetched,
                             "fetched-delta-parts", "u", &self->fetched_delta_parts,
                             "total-delta-parts", "u", &self->total_delta_parts,
                             "fetched-delta-fallbacks", "u", &self->fetched_delta_fallbacks,
                             "total-delta-fallbacks", "u", &self->total_delta_fallbacks,
                             "total-delta-superblocks", "u", &self->total_delta_superblocks,
                             "downloading-extra-data", "u", &downloading_extra_data,
                             "caught-error", "b", &caught_error,
                             NULL);
  /* Bitfield members */
  self->downloading_extra_data = downloading_extra_data;
  self->caught_error = caught_error;

  update_status_progress_and_estimating (self);
}

static void
invoke_callback (OstreeAsyncProgress *ostree_progress,
                 FlatpakProgress     *progress)
{
  copy_ostree_progress_state (ostree_progress, progress);
  progress->callback (progress->status, progress->progress, progress->estimating, progress->user_data);
}

static OstreeAsyncProgress *
flatpak_progress_issue_ostree_progress (FlatpakProgress *self)
{
  OstreeAsyncProgress *ostree_progress = ostree_async_progress_new ();
  ostree_async_progress_set (ostree_progress,
                             "start-time-extra-data", "t", self->start_time_extra_data,
                             "outstanding-extra-data", "t", self->outstanding_extra_data,
                             "total-extra-data", "t", self->total_extra_data,
                             "transferred-extra-data-bytes", "t", self->transferred_extra_data_bytes,
                             "total-extra-data-bytes", "t", self->total_extra_data_bytes,
                             "status", "s", self->ostree_status,
                             "start-time", "t", self->start_time,
                             "bytes-transferred", "t", self->bytes_transferred,
                             "fetched-delta-part-size", "t", self->fetched_delta_part_size,
                             "total-delta-part-size", "t", self->total_delta_part_size,
                             "total-delta-part-usize", "t", self->total_delta_part_usize,
                             "outstanding-fetches", "u", self->outstanding_fetches,
                             "outstanding-writes", "u", self->outstanding_writes,
                             "fetched", "u", self->fetched,
                             "requested", "u", self->requested,
                             "scanning", "u", self->scanning,
                             "scanned-metadata", "u", self->scanned_metadata,
                             "outstanding-metadata-fetches", "u", self->outstanding_metadata_fetches,
                             "metadata-fetched", "u", self->metadata_fetched,
                             "fetched-delta-parts", "u", self->fetched_delta_parts,
                             "total-delta-parts", "u", self->total_delta_parts,
                             "fetched-delta-fallbacks", "u", self->fetched_delta_fallbacks,
                             "total-delta-fallbacks", "u", self->total_delta_fallbacks,
                             "total-delta-superblocks", "u", self->total_delta_superblocks,
                             "downloading-extra-data", "u", (guint) self->downloading_extra_data,
                             "caught-error", "b", self->caught_error,
                             NULL);
  g_signal_connect (ostree_progress, "changed", G_CALLBACK (invoke_callback), self);

  return ostree_progress;
}

static void
flatpak_progress_revoke_ostree_progress (FlatpakProgress     *self,
                                         OstreeAsyncProgress *ostree_progress)
{
  ostree_async_progress_finish (ostree_progress);
  copy_ostree_progress_state (ostree_progress, self);
  g_object_unref (ostree_progress);
}

gboolean
flatpak_progress_is_done (FlatpakProgress *self)
{
  return self->done;
}

void
flatpak_progress_done (FlatpakProgress *self)
{
  self->done = TRUE;
}

===== ./common/flatpak-bwrap.c =====
/* vi:set et sw=2 sts=2 cin cino=t0,f0,(0,{s,>2s,n-s,^-s,e-s:
 * Copyright © 2014-2018 Red Hat, Inc
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Alexander Larsson <alexl@redhat.com>
 */

#include "config.h"

#include <string.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/utsname.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <sys/personality.h>
#include <grp.h>
#include <unistd.h>
#include <gio/gunixfdlist.h>

#include <glib/gi18n-lib.h>

#include <glib-unix.h>
#include <gio/gio.h>
#include "libglnx.h"

#include "flatpak-bwrap-private.h"
#include "flatpak-utils-private.h"
#include "flatpak-utils-base-private.h"

char *flatpak_bwrap_empty_env[] = { NULL };

FlatpakBwrap *
flatpak_bwrap_new (char **env)
{
  FlatpakBwrap *bwrap = g_new0 (FlatpakBwrap, 1);

  bwrap->argv = g_ptr_array_new_with_free_func (g_free);
  bwrap->noinherit_fds = g_array_new (FALSE, TRUE, sizeof (int));
  g_array_set_clear_func (bwrap->noinherit_fds, (GDestroyNotify) glnx_close_fd);
  bwrap->fds = g_array_new (FALSE, TRUE, sizeof (int));
  g_array_set_clear_func (bwrap->fds, (GDestroyNotify) glnx_close_fd);

  if (env)
    bwrap->envp = g_strdupv (env);
  else
    bwrap->envp = g_get_environ ();

  bwrap->sync_fds[0] = -1;
  bwrap->sync_fds[1] = -1;

  return bwrap;
}

void
flatpak_bwrap_free (FlatpakBwrap *bwrap)
{
  g_ptr_array_unref (bwrap->argv);
  g_array_unref (bwrap->noinherit_fds);
  g_array_unref (bwrap->fds);
  g_strfreev (bwrap->envp);
  g_clear_pointer (&bwrap->runtime_dir_members, g_ptr_array_unref);
  g_free (bwrap);
}

gboolean
flatpak_bwrap_is_empty (FlatpakBwrap *bwrap)
{
  return bwrap->argv->len == 0;
}

void
flatpak_bwrap_set_env (FlatpakBwrap *bwrap,
                       const char   *variable,
                       const char   *value,
                       gboolean      overwrite)
{
  bwrap->envp = g_environ_setenv (bwrap->envp, variable, value, overwrite);
}

void
flatpak_bwrap_unset_env (FlatpakBwrap *bwrap,
                         const char   *variable)
{
  bwrap->envp = g_environ_unsetenv (bwrap->envp, variable);
}

void
flatpak_bwrap_add_arg (FlatpakBwrap *bwrap, const char *arg)
{
  g_ptr_array_add (bwrap->argv, g_strdup (arg));
}

/*
 * flatpak_bwrap_take_arg:
 * @arg: (transfer full): Take ownership of this argument
 *
 * Add @arg to @bwrap's argv, taking ownership of the pointer.
 */
void
flatpak_bwrap_take_arg (FlatpakBwrap *bwrap, char *arg)
{
  g_ptr_array_add (bwrap->argv, arg);
}

void
flatpak_bwrap_finish (FlatpakBwrap *bwrap)
{
  g_ptr_array_add (bwrap->argv, NULL);
}

void
flatpak_bwrap_add_noinherit_fd (FlatpakBwrap *bwrap,
                                int           fd)
{
  g_array_append_val (bwrap->noinherit_fds, fd);
}

void
flatpak_bwrap_add_fd (FlatpakBwrap *bwrap,
                      int           fd)
{
  g_array_append_val (bwrap->fds, fd);
}

gboolean
flatpak_bwrap_add_args_data_fd_dup (FlatpakBwrap  *bwrap,
                                    const char    *op,
                                    int            fd,
                                    const char    *path_optional,
                                    GError       **error)
{
  glnx_autofd int fd_dup = -1;

  fd_dup = fcntl (fd, F_DUPFD_CLOEXEC, 3);
  if (fd_dup < 0)
    return glnx_throw_errno_prefix (error, "Failed to dup fd %d", fd);

  flatpak_bwrap_add_args_data_fd (bwrap,
                                  op,
                                  g_steal_fd (&fd_dup),
                                  path_optional);
  return TRUE;
}

void
flatpak_bwrap_add_arg_printf (FlatpakBwrap *bwrap, const char *format, ...)
{
  va_list args;

  va_start (args, format);
  g_ptr_array_add (bwrap->argv, g_strdup_vprintf (format, args));
  va_end (args);
}
void
flatpak_bwrap_add_args (FlatpakBwrap *bwrap, ...)
{
  va_list args;
  const gchar *arg;

  va_start (args, bwrap);
  while ((arg = va_arg (args, const gchar *)))
    flatpak_bwrap_add_arg (bwrap, arg);
  va_end (args);
}

void
flatpak_bwrap_append_argsv (FlatpakBwrap *bwrap,
                            char        **args,
                            int           len)
{
  int i;

  if (len < 0)
    len = g_strv_length (args);

  for (i = 0; i < len; i++)
    g_ptr_array_add (bwrap->argv, g_strdup (args[i]));
}

void
flatpak_bwrap_append_args (FlatpakBwrap *bwrap,
                           GPtrArray    *other_array)
{
  flatpak_bwrap_append_argsv (bwrap,
                              (char **) other_array->pdata,
                              other_array->len);
}

static int *
flatpak_bwrap_steal_fds (FlatpakBwrap *bwrap,
                         gsize        *len_out)
{
  gsize len = bwrap->fds->len;
  int *res = (int *) g_array_free (bwrap->fds, FALSE);

  bwrap->fds = g_array_new (FALSE, TRUE, sizeof (int));
  *len_out = len;
  return res;
}

void
flatpak_bwrap_append_bwrap (FlatpakBwrap *bwrap,
                            FlatpakBwrap *other)
{
  g_autofree int *fds = NULL;
  gsize n_fds, i;

  fds = flatpak_bwrap_steal_fds (other, &n_fds);
  for (i = 0; i < n_fds; i++)
    flatpak_bwrap_add_fd (bwrap, fds[i]);

  flatpak_bwrap_append_argsv (bwrap,
                              (char **) other->argv->pdata,
                              other->argv->len);

  for (i = 0; other->envp[i] != NULL; i++)
    {
      char *key_val = other->envp[i];
      char *eq = strchr (key_val, '=');
      if (eq)
        {
          g_autofree char *key = g_strndup (key_val, eq - key_val);
          flatpak_bwrap_set_env (bwrap,
                                 key, eq + 1, TRUE);
        }
    }

  if (other->runtime_dir_members != NULL)
    {
      if (bwrap->runtime_dir_members == NULL)
        bwrap->runtime_dir_members = g_ptr_array_new_with_free_func (g_free);

      for (i = 0; i < other->runtime_dir_members->len; i++)
        g_ptr_array_add (bwrap->runtime_dir_members,
                         g_strdup (g_ptr_array_index (other->runtime_dir_members, i)));
    }
}

void
flatpak_bwrap_add_args_data_fd (FlatpakBwrap *bwrap,
                                const char   *op,
                                int           fd,
                                const char   *path_optional)
{
  g_autofree char *fd_str = g_strdup_printf ("%d", fd);

  flatpak_bwrap_add_fd (bwrap, fd);
  flatpak_bwrap_add_args (bwrap,
                          op, fd_str, path_optional,
                          NULL);
}


/* Given a buffer @content of size @content_size, generate a fd (memfd if available)
 * of the data.  The @name parameter is used by memfd_create() as a debugging aid;
 * it has no semantic meaning.  The bwrap command line will inject it into the target
 * container as @path.
 */
gboolean
flatpak_bwrap_add_args_data (FlatpakBwrap *bwrap,
                             const char   *name,
                             const char   *content,
                             gssize        content_size,
                             const char   *path,
                             GError      **error)
{
  g_auto(GLnxTmpfile) args_tmpf  = { 0, };

  if (!flatpak_buffer_to_sealed_memfd_or_tmpfile (&args_tmpf, name, content, content_size, error))
    return FALSE;

  flatpak_bwrap_add_args_data_fd (bwrap, "--ro-bind-data", g_steal_fd (&args_tmpf.fd), path);
  return TRUE;
}

/* This resolves the target here rather than in bwrap, because it may
 * not resolve in bwrap setup due to absolute symlinks conflicting
 * with /newroot root. For example, dest could be inside
 * ~/.var/app/XXX where XXX is an absolute symlink.  However, in the
 * usecases here the destination file often doesn't exist, so we
 * only resolve the directory part.
 */
void
flatpak_bwrap_add_bind_arg (FlatpakBwrap *bwrap,
                            const char   *type,
                            const char   *src,
                            const char   *dest)
{
  g_autofree char *dest_dirname = g_path_get_dirname (dest);
  g_autofree char *dest_dirname_real = realpath (dest_dirname, NULL);

  if (dest_dirname_real)
    {
      g_autofree char *dest_basename = g_path_get_basename (dest);
      g_autofree char *dest_real = g_build_filename (dest_dirname_real, dest_basename, NULL);
      flatpak_bwrap_add_args (bwrap, type, src, dest_real, NULL);
    }
}

/*
 * Sort bwrap->envp. This has no practical effect, but it's easier to
 * see what is going on in a large environment block if the variables
 * are sorted.
 */
void
flatpak_bwrap_sort_envp (FlatpakBwrap *bwrap)
{
  if (bwrap->envp != NULL)
    {
      qsort (bwrap->envp, g_strv_length (bwrap->envp), sizeof (char *),
             flatpak_envp_cmp);
    }
}

/*
 * Convert bwrap->envp into a series of --setenv arguments for bwrap(1),
 * assumed to be applied to an empty environment. Reset envp to be an
 * empty environment.
 */
void
flatpak_bwrap_envp_to_args (FlatpakBwrap *bwrap)
{
  gsize i;

  for (i = 0; bwrap->envp[i] != NULL; i++)
    {
      char *key_val = bwrap->envp[i];
      char *eq = strchr (key_val, '=');

      if (eq)
        {
          flatpak_bwrap_add_arg (bwrap, "--setenv");
          flatpak_bwrap_take_arg (bwrap, g_strndup (key_val, eq - key_val));
          flatpak_bwrap_add_arg (bwrap, eq + 1);
        }
      else
        {
          g_warn_if_reached ();
        }
    }

  g_strfreev (g_steal_pointer (&bwrap->envp));
  bwrap->envp = g_strdupv (flatpak_bwrap_empty_env);
}

gboolean
flatpak_bwrap_bundle_args (FlatpakBwrap *bwrap,
                           int           start,
                           int           end,
                           gboolean      one_arg,
                           GError      **error)
{
  g_autofree gchar *data = NULL;
  gchar *ptr;
  gint i;
  gsize data_len = 0;
  int fd;
  g_auto(GLnxTmpfile) args_tmpf  = { 0, };

  if (end == -1)
    end = bwrap->argv->len;

  for (i = start; i < end; i++)
    data_len +=  strlen (bwrap->argv->pdata[i]) + 1;

  data = g_new (gchar, data_len);
  ptr = data;
  for (i = start; i < end; i++)
    ptr = g_stpcpy (ptr, bwrap->argv->pdata[i]) + 1;

  if (!flatpak_buffer_to_sealed_memfd_or_tmpfile (&args_tmpf, "bwrap-args", data, data_len, error))
    return FALSE;

  fd = g_steal_fd (&args_tmpf.fd);

  g_debug ("bwrap --args %d = ...", fd);

  for (i = start; i < end; i++)
    {
      if (flatpak_argument_needs_quoting (bwrap->argv->pdata[i]))
        {
          g_autofree char *quoted = g_shell_quote (bwrap->argv->pdata[i]);

          g_debug ("    %s", quoted);
        }
      else
        {
          g_debug ("    %s", (const char *) bwrap->argv->pdata[i]);
        }
    }

  flatpak_bwrap_add_fd (bwrap, fd);
  g_ptr_array_remove_range (bwrap->argv, start, end - start);
  if (one_arg)
    {
      g_ptr_array_insert (bwrap->argv, start, g_strdup_printf ("--args=%d", fd));
    }
  else
    {
      g_ptr_array_insert (bwrap->argv, start, g_strdup ("--args"));
      g_ptr_array_insert (bwrap->argv, start + 1, g_strdup_printf ("%d", fd));
    }

  return TRUE;
}

/*
 * Remember that we need to arrange for $XDG_RUNTIME_DIR/$name to be
 * a symlink to /run/flatpak/$name.
 */
void
flatpak_bwrap_add_runtime_dir_member (FlatpakBwrap *bwrap,
                                      const char *name)
{
  if (bwrap->runtime_dir_members == NULL)
    bwrap->runtime_dir_members = g_ptr_array_new_with_free_func (g_free);

  g_ptr_array_add (bwrap->runtime_dir_members, g_strdup (name));
}

static void
expect_symlink (const char *host_path,
                const char *target)
{
  /* This shouldn't fail in practice, so there's not much point in
   * translating the warning */
  if (symlink (target, host_path) < 0 && errno != EEXIST)
    {
      g_warning ("Unable to create symlink at %s: %s",
                 host_path, g_strerror (errno));
    }
  else
    {
      g_autoptr(GError) local_error = NULL;
      g_autofree char *got = glnx_readlinkat_malloc (AT_FDCWD,
                                                     host_path,
                                                     NULL,
                                                     &local_error);

      if (got == NULL)
        g_warning ("%s is not a symlink to \"%s\" as expected: %s",
                   host_path, target, local_error->message);
      else if (strcmp (got, target) != 0)
        g_warning ("%s is a symlink to \"%s\", not \"%s\" as expected",
                   host_path, got, target);
    }
}

void
flatpak_bwrap_populate_runtime_dir (FlatpakBwrap *bwrap,
                                    const char *shared_xdg_runtime_dir)
{
  if (shared_xdg_runtime_dir != NULL)
    {
      g_autofree char *host_path = g_build_filename (shared_xdg_runtime_dir,
                                                     "flatpak-info", NULL);

      expect_symlink (host_path, "../../../.flatpak-info");
    }
  else
    {
      flatpak_bwrap_add_arg (bwrap, "--symlink");
      flatpak_bwrap_add_arg (bwrap, "../../../.flatpak-info");
      flatpak_bwrap_add_arg_printf (bwrap, "/run/user/%d/flatpak-info", getuid ());
    }

  if (bwrap->runtime_dir_members != NULL)
    {
      gsize i;

      for (i = 0; i < bwrap->runtime_dir_members->len; i++)
        {
          const char *member = g_ptr_array_index (bwrap->runtime_dir_members, i);
          g_autofree char *target = g_strdup_printf ("../../flatpak/%s", member);

          if (shared_xdg_runtime_dir != NULL)
            {
              g_autofree char *host_path = g_build_filename (shared_xdg_runtime_dir,
                                                             member, NULL);

              expect_symlink (host_path, target);
            }
          else
            {
              flatpak_bwrap_add_arg (bwrap, "--symlink");
              flatpak_bwrap_add_arg (bwrap, target);
              flatpak_bwrap_add_arg_printf (bwrap, "/run/user/%d/%s", getuid (), member);
            }
        }
    }
}

void
flatpak_bwrap_child_setup (GArray *fd_array,
                           gboolean close_fd_workaround)
{
  int i;

  /* There is a dead-lock in glib versions before 2.60 when it closes
   * the fds. See:  https://gitlab.gnome.org/GNOME/glib/merge_requests/490
   * This was hitting the test-suite a lot, so we work around it by using
   * the G_SPAWN_LEAVE_DESCRIPTORS_OPEN/G_SUBPROCESS_FLAGS_INHERIT_FDS flag
   * and setting CLOEXEC ourselves.
   */
  if (close_fd_workaround)
    g_fdwalk_set_cloexec (3);

  /* If no fd_array was specified, don't care. */
  if (fd_array == NULL)
    return;

  /* Otherwise, mark not - close-on-exec all the fds in the array */
  for (i = 0; i < fd_array->len; i++)
    {
      int fd = g_array_index (fd_array, int, i);

      /* We also seek all fds to the start, because this lets
         us use the same fd_array multiple times */
      if (lseek (fd, 0, SEEK_SET) < 0)
        {
          /* Ignore the error, not all fds are seekable
           * (for example pipes and O_PATH fds are not) */
        }

      fcntl (fd, F_SETFD, 0);
    }
}

/* Unset FD_CLOEXEC on the array of fds passed in @user_data */
void
flatpak_bwrap_child_setup_cb (gpointer user_data)
{
  GArray *fd_array = user_data;

  flatpak_bwrap_child_setup (fd_array, TRUE);
}

/* Unset FD_CLOEXEC on the array of fds passed in @user_data,
 * but do not set FD_CLOEXEC on all other fds */
void
flatpak_bwrap_child_setup_inherit_fds_cb (gpointer user_data)
{
  GArray *fd_array = user_data;

  flatpak_bwrap_child_setup (fd_array, FALSE);
}

/* Add a --sync-fd argument for bwrap(1). Returns the write end of the pipe on
 * success, or -1 on error. */
int
flatpak_bwrap_add_sync_fd (FlatpakBwrap *bwrap)
{
  /* --sync-fd is only allowed once */
  if (bwrap->sync_fds[1] >= 0)
    return bwrap->sync_fds[1];

  if (pipe2 (bwrap->sync_fds, O_CLOEXEC) < 0)
    return -1;

  flatpak_bwrap_add_args_data_fd (bwrap, "--sync-fd", bwrap->sync_fds[0], NULL);
  return bwrap->sync_fds[1];
}

===== ./common/flatpak-oci-registry-private.h =====
/*
 * Copyright © 2014-2019 Red Hat, Inc
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Alexander Larsson <alexl@redhat.com>
 */

#ifndef __FLATPAK_OCI_REGISTRY_H__
#define __FLATPAK_OCI_REGISTRY_H__

#include "libglnx.h"

#include <glib.h>
#include <gio/gio.h>
#include "flatpak-dir-private.h"
#include "flatpak-json-oci-private.h"
#include "flatpak-utils-http-private.h"
#include "flatpak-utils-private.h"

struct archive;

#define FLATPAK_TYPE_OCI_REGISTRY flatpak_oci_registry_get_type ()
#define FLATPAK_OCI_REGISTRY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), FLATPAK_TYPE_OCI_REGISTRY, FlatpakOciRegistry))
#define FLATPAK_IS_OCI_REGISTRY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), FLATPAK_TYPE_OCI_REGISTRY))

GType flatpak_oci_registry_get_type (void);

G_DEFINE_AUTOPTR_CLEANUP_FUNC (FlatpakOciRegistry, g_object_unref)

#define FLATPAK_TYPE_OCI_LAYER_WRITER flatpak_oci_layer_writer_get_type ()
#define FLATPAK_OCI_LAYER_WRITER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), FLATPAK_TYPE_OCI_LAYER_WRITER, FlatpakOciLayerWriter))
#define FLATPAK_IS_OCI_LAYER_WRITER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), FLATPAK_TYPE_OCI_LAYER_WRITER))

GType flatpak_oci_layer_writer_get_type (void);

typedef struct FlatpakOciLayerWriter FlatpakOciLayerWriter;

G_DEFINE_AUTOPTR_CLEANUP_FUNC (FlatpakOciLayerWriter, g_object_unref)


FlatpakOciRegistry  *  flatpak_oci_registry_new (const char    *uri,
                                                 gboolean       for_write,
                                                 int            tmp_dfd,
                                                 GCancellable  *cancellable,
                                                 GError       **error);
FlatpakOciRegistry *   flatpak_oci_registry_new_for_archive (GFile        *archive,
                                                             GCancellable *cancellable,
                                                             GError      **error);
void                   flatpak_oci_registry_set_token (FlatpakOciRegistry *self,
                                                       const char *token);
void                   flatpak_oci_registry_set_signature_lookaside (FlatpakOciRegistry *self,
                                                                     const char         *signature_lookaside);
gboolean               flatpak_oci_registry_is_local (FlatpakOciRegistry *self);
const char          *  flatpak_oci_registry_get_uri (FlatpakOciRegistry *self);
FlatpakOciIndex     *  flatpak_oci_registry_load_index (FlatpakOciRegistry *self,
                                                        GCancellable       *cancellable,
                                                        GError            **error);
gboolean               flatpak_oci_registry_save_index (FlatpakOciRegistry *self,
                                                        FlatpakOciIndex    *index,
                                                        GCancellable       *cancellable,
                                                        GError            **error);
int                    flatpak_oci_registry_download_blob (FlatpakOciRegistry    *self,
                                                           const char            *repository,
                                                           gboolean               manifest,
                                                           const char            *digest,
                                                           const char           **alt_uris,
                                                           FlatpakLoadUriProgress progress_cb,
                                                           gpointer               user_data,
                                                           GCancellable          *cancellable,
                                                           GError               **error);
char *                 flatpak_oci_registry_get_token (FlatpakOciRegistry *self,
                                                       const char         *repository,
                                                       const char         *digest,
                                                       const char         *basic_auth,
                                                       GCancellable       *cancellable,
                                                       GError            **error);
GBytes             *   flatpak_oci_registry_load_blob (FlatpakOciRegistry *self,
                                                       const char         *repository,
                                                       gboolean            manifest,
                                                       const char         *digest,
                                                       const char        **alt_uris,
                                                       char              **out_content_type,
                                                       GCancellable       *cancellable,
                                                       GError            **error);
char *                 flatpak_oci_registry_store_blob (FlatpakOciRegistry *self,
                                                        GBytes             *data,
                                                        GCancellable       *cancellable,
                                                        GError            **error);
gboolean               flatpak_oci_registry_mirror_blob (FlatpakOciRegistry    *self,
                                                         FlatpakOciRegistry    *source_registry,
                                                         const char            *repository,
                                                         gboolean               manifest,
                                                         const char            *digest,
                                                         const char          **alt_uris,
                                                         FlatpakLoadUriProgress progress_cb,
                                                         gpointer               user_data,
                                                         GCancellable          *cancellable,
                                                         GError               **error);
FlatpakOciDescriptor * flatpak_oci_registry_store_json (FlatpakOciRegistry *self,
                                                        FlatpakJson        *json,
                                                        GCancellable       *cancellable,
                                                        GError            **error);
FlatpakOciVersioned *  flatpak_oci_registry_load_versioned (FlatpakOciRegistry *self,
                                                            const char         *repository,
                                                            const char         *digest,
                                                            const char        **alt_uris,
                                                            gsize              *out_size,
                                                            GCancellable       *cancellable,
                                                            GError            **error);
FlatpakOciImage *      flatpak_oci_registry_load_image_config (FlatpakOciRegistry *self,
                                                               const char         *repository,
                                                               const char         *digest,
                                                               const char        **alt_uris,
                                                               gsize              *out_size,
                                                               GCancellable       *cancellable,
                                                               GError            **error);

typedef enum {
  FLATPAK_OCI_WRITE_LAYER_FLAGS_NONE = 0,
  FLATPAK_OCI_WRITE_LAYER_FLAGS_ZSTD = 1 << 0,
} FlatpakOciWriteLayerFlags;

FlatpakOciLayerWriter *flatpak_oci_registry_write_layer (FlatpakOciRegistry        *self,
                                                         FlatpakOciWriteLayerFlags  flags,
                                                         GCancellable              *cancellable,
                                                         GError                   **error);

int                     flatpak_oci_registry_apply_delta (FlatpakOciRegistry    *self,
                                                          int                    delta_fd,
                                                          GFile                 *content_dir,
                                                          GCancellable          *cancellable,
                                                          GError               **error);
char *                  flatpak_oci_registry_apply_delta_to_blob (FlatpakOciRegistry    *self,
                                                                  int                    delta_fd,
                                                                  GFile                 *content_dir,
                                                                  GCancellable          *cancellable,
                                                                  GError               **error);
FlatpakOciManifest *   flatpak_oci_registry_find_delta_manifest (FlatpakOciRegistry    *registry,
                                                                 const char            *oci_repository,
                                                                 const char            *for_digest,
                                                                 const char            *delta_manifest_uri,
                                                                 GCancellable          *cancellable);

struct archive *flatpak_oci_layer_writer_get_archive (FlatpakOciLayerWriter *self);
gboolean        flatpak_oci_layer_writer_close (FlatpakOciLayerWriter *self,
                                                char                 **uncompressed_digest_out,
                                                FlatpakOciDescriptor **res_out,
                                                GCancellable          *cancellable,
                                                GError               **error);

gboolean flatpak_archive_read_open_fd_with_checksum (struct archive *a,
                                                     int             fd,
                                                     GChecksum      *checksum,
                                                     GError        **error);

gboolean flatpak_oci_index_ensure_cached (FlatpakHttpSession  *http_session,
                                          const char          *uri,
                                          GFile               *index,
                                          char               **index_uri_out,
                                          GCancellable        *cancellable,
                                          GError             **error);

GVariant *flatpak_oci_index_make_summary (GFile        *index,
                                          const char   *index_uri,
                                          GCancellable *cancellable,
                                          GError      **error);

GBytes *flatpak_oci_index_make_appstream (FlatpakHttpSession  *http_session,
                                          GFile               *index,
                                          const char          *index_uri,
                                          const char          *arch,
                                          int                  icons_dfd,
                                          GCancellable        *cancellable,
                                          GError             **error);

typedef void (*FlatpakOciPullProgress) (guint64  total_size,
                                        guint64  pulled_size,
                                        guint32  n_layers,
                                        guint32  pulled_layers,
                                        gpointer data);

char * flatpak_pull_from_oci (OstreeRepo            *repo,
                              FlatpakImageSource    *image_source,
                              FlatpakImageSource    *opt_dst_image_source,
                              const char            *remote,
                              const char            *ref,
                              FlatpakPullFlags       flags,
                              FlatpakOciPullProgress progress_cb,
                              gpointer               progress_data,
                              GCancellable          *cancellable,
                              GError               **error);

gboolean flatpak_mirror_image_from_oci (FlatpakOciRegistry    *dst_registry,
                                        FlatpakImageSource    *image_source,
                                        const char            *remote,
                                        const char            *ref,
                                        OstreeRepo            *repo,
                                        FlatpakOciPullProgress progress_cb,
                                        gpointer               progress_data,
                                        GCancellable          *cancellable,
                                        GError               **error);

#endif /* __FLATPAK_OCI_REGISTRY_H__ */

===== ./common/flatpak-error.h =====
/* flatpak-error.c
 *
 * Copyright (C) 2015 Red Hat, Inc
 *
 * This file 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 of the
 * License, or (at your option) any later version.
 *
 * This file 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 program.  If not, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Alexander Larsson <alexl@redhat.com>
 */

#ifndef FLATPAK_ERROR_H
#define FLATPAK_ERROR_H

#if !defined(__FLATPAK_H_INSIDE__) && !defined(FLATPAK_COMPILATION)
#error "Only <flatpak.h> can be included directly."
#endif

#include <glib.h>

G_BEGIN_DECLS

/* NOTE: If you add an error code below, also update the list in common/flatpak-utils.c */
/**
 * FlatpakError:
 * @FLATPAK_ERROR_ALREADY_INSTALLED: App/runtime/remote is already installed
 * @FLATPAK_ERROR_NOT_INSTALLED: App/runtime is not installed
 * @FLATPAK_ERROR_ONLY_PULLED: App/runtime was only pulled into the local
 *                             repository but not installed.
 * @FLATPAK_ERROR_DIFFERENT_REMOTE: The App/Runtime is already installed, but from a different remote.
 * @FLATPAK_ERROR_ABORTED: The transaction was aborted (returned %TRUE in operation-error signal).
 * @FLATPAK_ERROR_SKIPPED: The App/Runtime install was skipped due to earlier errors.
 * @FLATPAK_ERROR_NEED_NEW_FLATPAK: The App/Runtime needs a more recent version of flatpak.
 * @FLATPAK_ERROR_REMOTE_NOT_FOUND: The specified remote was not found.
 * @FLATPAK_ERROR_RUNTIME_NOT_FOUND: A runtime needed for the app was not found.
 * @FLATPAK_ERROR_DOWNGRADE: The pulled commit is a downgrade, and a downgrade wasn't
 *                           specifically allowed. (Since: 1.0)
 * @FLATPAK_ERROR_INVALID_REF: A ref could not be parsed. (Since: 1.0.3)
 * @FLATPAK_ERROR_INVALID_DATA: Invalid data. (Since: 1.0.3)
 * @FLATPAK_ERROR_UNTRUSTED: Missing GPG key or signature. (Since: 1.0.3)
 * @FLATPAK_ERROR_SETUP_FAILED: Sandbox setup failed. (Since: 1.0.3)
 * @FLATPAK_ERROR_EXPORT_FAILED: Exporting data failed. (Since: 1.0.3)
 * @FLATPAK_ERROR_REMOTE_USED: Remote can't be uninstalled. (Since: 1.0.3)
 * @FLATPAK_ERROR_RUNTIME_USED: Runtime can't be uninstalled. (Since: 1.0.3)
 * @FLATPAK_ERROR_INVALID_NAME: Application, runtime or remote name is invalid. (Since: 1.0.3)
 * @FLATPAK_ERROR_OUT_OF_SPACE: More disk space needed. (Since: 1.2.0)
 * @FLATPAK_ERROR_WRONG_USER: An operation is being attempted by the wrong user (such as
 *                            root operating on a user installation). (Since: 1.2.0)
 * @FLATPAK_ERROR_NOT_CACHED: Cached data was requested, but it was not available. (Since: 1.4.0)
 * @FLATPAK_ERROR_REF_NOT_FOUND: The specified ref was not found. (Since: 1.4.0)
 * @FLATPAK_ERROR_PERMISSION_DENIED: An operation was not allowed by the administrative policy.
 *                                   For example, an app is not allowed to be installed due
 *                                   to not complying with the parental controls policy. (Since: 1.5.1)
 * @FLATPAK_ERROR_AUTHENTICATION_FAILED: An authentication operation failed, for example, no
 *                                       correct password was supplied. (Since: 1.7.3)
 * @FLATPAK_ERROR_NOT_AUTHORIZED: An operation tried to access a ref, or information about it that it
 *                                was not authorized. For example, when successfully authenticating with a
 *                                server but the user doesn't have permissions for a private ref. (Since: 1.7.3)
 *
 * Error codes for library functions.
 */
typedef enum {
  FLATPAK_ERROR_ALREADY_INSTALLED,
  FLATPAK_ERROR_NOT_INSTALLED,
  FLATPAK_ERROR_ONLY_PULLED,
  FLATPAK_ERROR_DIFFERENT_REMOTE,
  FLATPAK_ERROR_ABORTED,
  FLATPAK_ERROR_SKIPPED,
  FLATPAK_ERROR_NEED_NEW_FLATPAK,
  FLATPAK_ERROR_REMOTE_NOT_FOUND,
  FLATPAK_ERROR_RUNTIME_NOT_FOUND,
  FLATPAK_ERROR_DOWNGRADE,
  FLATPAK_ERROR_INVALID_REF,
  FLATPAK_ERROR_INVALID_DATA,
  FLATPAK_ERROR_UNTRUSTED,
  FLATPAK_ERROR_SETUP_FAILED,
  FLATPAK_ERROR_EXPORT_FAILED,
  FLATPAK_ERROR_REMOTE_USED,
  FLATPAK_ERROR_RUNTIME_USED,
  FLATPAK_ERROR_INVALID_NAME,
  FLATPAK_ERROR_OUT_OF_SPACE,
  FLATPAK_ERROR_WRONG_USER,
  FLATPAK_ERROR_NOT_CACHED,
  FLATPAK_ERROR_REF_NOT_FOUND,
  FLATPAK_ERROR_PERMISSION_DENIED,
  FLATPAK_ERROR_AUTHENTICATION_FAILED,
  FLATPAK_ERROR_NOT_AUTHORIZED,
} FlatpakError;

/**
 * FLATPAK_ERROR:
 *
 * The error domain for #FlatpakError errors.
 */
#define FLATPAK_ERROR flatpak_error_quark ()

FLATPAK_EXTERN GQuark  flatpak_error_quark (void);

G_END_DECLS

#endif /* FLATPAK_ERROR_H */

===== ./common/flatpak-locale-utils.c =====
/* vi:set et sw=2 sts=2 cin cino=t0,f0,(0,{s,>2s,n-s,^-s,e-s:
 * Copyright © 2014-2019 Red Hat, Inc
 * Copyright © 2017 Endless Mobile, Inc.
 * Copyright © 2023 Collabora Ltd.
 * SPDX-License-Identifier: LGPL-2.1-or-later
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Alexander Larsson <alexl@redhat.com>
 *       Philip Withnall <withnall@endlessm.com>
 *       Matthew Leeds <matthew.leeds@endlessm.com>
 */

#include "config.h"
#include "flatpak-locale-utils-private.h"

#include <glib.h>
#include "libglnx.h"

#include "flatpak-utils-private.h"

const char * const *
flatpak_get_locale_categories (void)
{
  /* See locale(7) for these categories */
  static const char * const categories[] = {
    "LANG", "LC_ALL", "LC_MESSAGES", "LC_ADDRESS", "LC_COLLATE", "LC_CTYPE",
    "LC_IDENTIFICATION", "LC_MONETARY", "LC_MEASUREMENT", "LC_NAME", "LC_NUMERIC",
    "LC_PAPER", "LC_TELEPHONE", "LC_TIME",
    NULL
  };

  return categories;
}

char *
flatpak_get_lang_from_locale (const char *locale)
{
  g_autofree char *lang = g_strdup (locale);
  char *c;

  c = strchr (lang, '@');
  if (c != NULL)
    *c = 0;
  c = strchr (lang, '_');
  if (c != NULL)
    *c = 0;
  c = strchr (lang, '.');
  if (c != NULL)
    *c = 0;

  if (strcmp (lang, "C") == 0)
    return NULL;

  return g_steal_pointer (&lang);
}

char **
flatpak_get_current_locale_langs (void)
{
  const char * const *categories = flatpak_get_locale_categories ();
  GPtrArray *langs = g_ptr_array_new ();
  int i;

  for (; categories != NULL && *categories != NULL; categories++)
    {
      const gchar * const *locales = g_get_language_names_with_category (*categories);

      for (i = 0; locales[i] != NULL; i++)
        {
          g_autofree char *lang = flatpak_get_lang_from_locale (locales[i]);
          if (lang != NULL && !flatpak_g_ptr_array_contains_string (langs, lang))
            g_ptr_array_add (langs, g_steal_pointer (&lang));
        }
    }

  g_ptr_array_sort (langs, flatpak_strcmp0_ptr);
  g_ptr_array_add (langs, NULL);

  return (char **) g_ptr_array_free (langs, FALSE);
}

GDBusProxy *
flatpak_locale_get_localed_dbus_proxy (void)
{
  const char *localed_bus_name = "org.freedesktop.locale1";
  const char *localed_object_path = "/org/freedesktop/locale1";
  const char *localed_interface_name = localed_bus_name;

  return g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
                                        G_DBUS_PROXY_FLAGS_NONE,
                                        NULL,
                                        localed_bus_name,
                                        localed_object_path,
                                        localed_interface_name,
                                        NULL,
                                        NULL);
}

void
flatpak_get_locale_langs_from_localed_dbus (GDBusProxy *proxy, GPtrArray *langs)
{
  g_autoptr(GVariant) locale_variant = NULL;
  g_autofree const gchar **strv = NULL;
  gsize i, j;

  locale_variant = g_dbus_proxy_get_cached_property (proxy, "Locale");
  if (locale_variant == NULL)
    return;

  strv = g_variant_get_strv (locale_variant, NULL);

  for (i = 0; strv[i]; i++)
    {
      const gchar *locale = NULL;
      g_autofree char *lang = NULL;

      const char * const *categories = flatpak_get_locale_categories ();

      for (j = 0; categories[j]; j++)
        {
          g_autofree char *prefix = g_strdup_printf ("%s=", categories[j]);
          if (g_str_has_prefix (strv[i], prefix))
            {
              locale = strv[i] + strlen (prefix);
              break;
            }
        }

      if (locale == NULL || strcmp (locale, "") == 0)
        continue;

      lang = flatpak_get_lang_from_locale (locale);
      if (lang != NULL && !flatpak_g_ptr_array_contains_string (langs, lang))
        g_ptr_array_add (langs, g_steal_pointer (&lang));
    }
}

GDBusProxy *
flatpak_locale_get_accounts_dbus_proxy (void)
{
  const char *accounts_bus_name = "org.freedesktop.Accounts";
  const char *accounts_object_path = "/org/freedesktop/Accounts";
  const char *accounts_interface_name = accounts_bus_name;

  return g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
                                        G_DBUS_PROXY_FLAGS_NONE,
                                        NULL,
                                        accounts_bus_name,
                                        accounts_object_path,
                                        accounts_interface_name,
                                        NULL,
                                        NULL);
}

gboolean
flatpak_get_all_langs_from_accounts_dbus (GDBusProxy *proxy, GPtrArray *langs)
{
  g_auto(GStrv) all_langs = NULL;
  int i;
  g_autoptr(GVariant) ret = NULL;
  g_autoptr(GError) error = NULL;

  ret = g_dbus_proxy_call_sync (G_DBUS_PROXY (proxy),
                                "GetUsersLanguages",
                                g_variant_new ("()"),
                                G_DBUS_CALL_FLAGS_NONE,
                                -1,
                                NULL,
                                &error);
  if (!ret)
    {
      g_debug ("Failed to get languages for all users: %s", error->message);
      return FALSE;
    }

  g_variant_get (ret,
                 "(^as)",
                 &all_langs);

  if (all_langs != NULL)
    {
      for (i = 0; all_langs[i] != NULL; i++)
        {
          g_autofree char *lang = NULL;
            lang = flatpak_get_lang_from_locale (all_langs[i]);
            if (lang != NULL && !flatpak_g_ptr_array_contains_string (langs, lang))
              g_ptr_array_add (langs, g_steal_pointer (&lang));
        }
    }

  return TRUE;
}

void
flatpak_get_locale_langs_from_accounts_dbus (GDBusProxy *proxy, GPtrArray *langs)
{
  const char *accounts_bus_name = "org.freedesktop.Accounts";
  const char *accounts_interface_name = "org.freedesktop.Accounts.User";
  g_auto(GStrv) object_paths = NULL;
  int i;
  g_autoptr(GVariant) ret = NULL;

  ret = g_dbus_proxy_call_sync (G_DBUS_PROXY (proxy),
                                "ListCachedUsers",
                                g_variant_new ("()"),
                                G_DBUS_CALL_FLAGS_NONE,
                                -1,
                                NULL,
                                NULL);
  if (ret != NULL)
    g_variant_get (ret,
                   "(^ao)",
                   &object_paths);

  if (object_paths != NULL)
    {
      for (i = 0; object_paths[i] != NULL; i++)
        {
          g_autoptr(GDBusProxy) accounts_proxy = NULL;
          g_autoptr(GVariant) value = NULL;

          accounts_proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
                                                          G_DBUS_PROXY_FLAGS_NONE,
                                                          NULL,
                                                          accounts_bus_name,
                                                          object_paths[i],
                                                          accounts_interface_name,
                                                          NULL,
                                                          NULL);

          if (accounts_proxy)
            {
              value = g_dbus_proxy_get_cached_property (accounts_proxy, "Language");
              if (value != NULL)
                {
                  const char *locale = g_variant_get_string (value, NULL);
                  g_autofree char *lang = NULL;

                  if (strcmp (locale, "") == 0)
                    continue; /* This user wants the system default locale */

                  lang = flatpak_get_lang_from_locale (locale);
                  if (lang != NULL && !flatpak_g_ptr_array_contains_string (langs, lang))
                    g_ptr_array_add (langs, g_steal_pointer (&lang));
                }
            }
        }
    }
}

void
flatpak_get_locale_langs_from_accounts_dbus_for_user (GDBusProxy *proxy, GPtrArray *langs, guint uid)
{
  const char *accounts_bus_name = "org.freedesktop.Accounts";
  const char *accounts_interface_name = "org.freedesktop.Accounts.User";
  g_autofree char *object_path = NULL;
  g_autoptr(GVariant) ret = NULL;

  ret = g_dbus_proxy_call_sync (G_DBUS_PROXY (proxy),
                                "FindUserById",
                                g_variant_new ("(x)", uid),
                                G_DBUS_CALL_FLAGS_NONE,
                                -1,
                                NULL,
                                NULL);
  if (ret != NULL)
    g_variant_get (ret, "(o)", &object_path);

  if (object_path != NULL)
    {
      g_autoptr(GDBusProxy) accounts_proxy = NULL;
      g_autoptr(GVariant) value = NULL;

      accounts_proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
                                                      G_DBUS_PROXY_FLAGS_NONE,
                                                      NULL,
                                                      accounts_bus_name,
                                                      object_path,
                                                      accounts_interface_name,
                                                      NULL,
                                                      NULL);
      if (!accounts_proxy)
        return;

      value = g_dbus_proxy_get_cached_property (accounts_proxy, "Languages");
      if (value != NULL)
        {
          g_autofree const char **locales = g_variant_get_strv (value, NULL);
          guint i;

          for (i = 0; locales != NULL && locales[i] != NULL; i++)
            {
              g_autofree char *lang = NULL;
              lang = flatpak_get_lang_from_locale (locales[i]);
              if (lang != NULL && !flatpak_g_ptr_array_contains_string (langs, lang))
                g_ptr_array_add (langs, g_steal_pointer (&lang));
            }
        }
      else
        {
          value = g_dbus_proxy_get_cached_property (accounts_proxy, "Language");
          if (value != NULL)
            {
              const char *locale = g_variant_get_string (value, NULL);
              g_autofree char *lang = NULL;

              if (strcmp (locale, "") != 0)
                {
                  lang = flatpak_get_lang_from_locale (locale);
                  if (lang != NULL && !flatpak_g_ptr_array_contains_string (langs, lang))
                    g_ptr_array_add (langs, g_steal_pointer (&lang));
                }
            }
        }
    }
}

const GPtrArray *
flatpak_get_system_locales (void)
{
  static GPtrArray *cached = NULL;

  if (g_once_init_enter (&cached))
    {
      GPtrArray *langs = g_ptr_array_new_with_free_func (g_free);
      g_autoptr(GDBusProxy) accounts_proxy = NULL;
      g_autoptr(GDBusProxy) localed_proxy = NULL;

      /* Get the system default locales */
      localed_proxy = flatpak_locale_get_localed_dbus_proxy ();
      if (localed_proxy != NULL)
        flatpak_get_locale_langs_from_localed_dbus (localed_proxy, langs);

      /* Add user account languages from AccountsService */
      accounts_proxy = flatpak_locale_get_accounts_dbus_proxy ();
      if (accounts_proxy != NULL)
        if (!flatpak_get_all_langs_from_accounts_dbus (accounts_proxy, langs))
          /* If AccountsService is too old for GetUsersLanguages, fall back
           * to retrieving languages for each user account */
          flatpak_get_locale_langs_from_accounts_dbus (accounts_proxy, langs);

      g_ptr_array_add (langs, NULL);

      g_once_init_leave (&cached, langs);
    }

  return (const GPtrArray *)cached;
}

const GPtrArray *
flatpak_get_user_locales (void)
{
  static GPtrArray *cached = NULL;

  if (g_once_init_enter (&cached))
    {
      GPtrArray *langs = g_ptr_array_new_with_free_func (g_free);
      g_autoptr(GDBusProxy) accounts_proxy = NULL;

      accounts_proxy = flatpak_locale_get_accounts_dbus_proxy ();

      if (accounts_proxy != NULL)
        flatpak_get_locale_langs_from_accounts_dbus_for_user (accounts_proxy, langs, getuid ());

      g_ptr_array_add (langs, NULL);

      g_once_init_leave (&cached, langs);
    }

  return (const GPtrArray *)cached;
}

===== ./common/flatpak-ref.c =====
/* vi:set et sw=2 sts=2 cin cino=t0,f0,(0,{s,>2s,n-s,^-s,e-s:
 * Copyright © 2015 Red Hat, Inc
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Alexander Larsson <alexl@redhat.com>
 */

#include "config.h"

#include "flatpak-utils-private.h"
#include "flatpak-ref.h"
#include "flatpak-ref-utils-private.h"
#include "flatpak-enum-types.h"

/**
 * SECTION:flatpak-ref
 * @Title: FlatpakRef
 * @Short_description: Application reference
 *
 * Currently Flatpak manages two types of binary artifacts: applications, and
 * runtimes. Applications contain a program that desktop users can run, while
 * runtimes contain only libraries and data. An FlatpakRef object (or short: ref)
 * can refer to either of these.
 *
 * Both applications and runtimes are identified by a 4-tuple of strings: kind,
 * name, arch and branch, e.g. app/org.gnome.evince/x86_64/master. The functions
 * flatpak_ref_parse() and flatpak_ref_format_ref() can be used to convert
 * FlatpakRef objects into this string representation and back.
 *
 * Note that the identifiers must be unique within a repo (e.g. Flathub) based
 * only on the name, arch, and branch 3-tuple, without regard to the kind. In
 * other words if app/org.gnome.evince/x86_64/master exists,
 * runtime/org.gnome.evince/x86_64/master must not exist. This requirement is
 * not enforced by libflatpak but is enforced by GNOME Software's use of
 * libappstream, since Appstream IDs are assumed to be unique.
 *
 * FlatpakRef objects are immutable and can be passed freely between threads.
 *
 * To uniquely identify a particular version of an application or runtime, you
 * need a commit.
 *
 * The subclasses #FlatpakInstalledRef and #FlatpakRemoteRef provide more information
 * for artifacts that are locally installed or available from a remote repository.
 */
typedef struct _FlatpakRefPrivate FlatpakRefPrivate;

struct _FlatpakRefPrivate
{
  char          *name;
  char          *arch;
  char          *branch;
  char          *commit;
  FlatpakRefKind kind;
  char          *collection_id;
  char          *cached_full_ref;
};

G_DEFINE_TYPE_WITH_PRIVATE (FlatpakRef, flatpak_ref, G_TYPE_OBJECT)

enum {
  PROP_0,

  PROP_NAME,
  PROP_ARCH,
  PROP_BRANCH,
  PROP_COMMIT,
  PROP_KIND,
  PROP_COLLECTION_ID,
};

static void
flatpak_ref_finalize (GObject *object)
{
  FlatpakRef *self = FLATPAK_REF (object);
  FlatpakRefPrivate *priv = flatpak_ref_get_instance_private (self);

  g_free (priv->name);
  g_free (priv->arch);
  g_free (priv->branch);
  g_free (priv->commit);
  g_free (priv->collection_id);
  g_free ((char *)g_atomic_pointer_get (&priv->cached_full_ref));

  G_OBJECT_CLASS (flatpak_ref_parent_class)->finalize (object);
}

/* These support setting e.g. the arch from referencing a ref.
 * i.e. it would get "x86_64/master" as an argument. */
static char *
value_dup_ref_part (const GValue *value)
{
  const char *part = value->data[0].v_pointer;
  const char *slash;

  slash = strchr (part, '/');

  if (slash)
    return g_strndup (part, slash - part);

  return g_strdup (part);
}

static void
flatpak_ref_set_property (GObject      *object,
                          guint         prop_id,
                          const GValue *value,
                          GParamSpec   *pspec)
{
  FlatpakRef *self = FLATPAK_REF (object);
  FlatpakRefPrivate *priv = flatpak_ref_get_instance_private (self);

  switch (prop_id)
    {
    case PROP_NAME:
      g_assert (priv->name == NULL); /* Construct-only */
      priv->name = value_dup_ref_part (value);
      break;

    case PROP_ARCH:
      g_assert (priv->arch == NULL); /* Construct-only */
      priv->arch = value_dup_ref_part (value);
      break;

    case PROP_BRANCH:
      g_assert (priv->branch == NULL); /* Construct-only */
      priv->branch = value_dup_ref_part (value);
      break;

    case PROP_COMMIT:
      g_assert (priv->commit == NULL); /* Construct-only */
      priv->commit = g_value_dup_string (value);
      break;

    case PROP_KIND:
      priv->kind = g_value_get_enum (value);
      break;

    case PROP_COLLECTION_ID:
      g_assert (priv->collection_id == NULL); /* Construct-only */
      priv->collection_id = g_value_dup_string (value);
      break;

    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
    }
}

static void
flatpak_ref_get_property (GObject    *object,
                          guint       prop_id,
                          GValue     *value,
                          GParamSpec *pspec)
{
  FlatpakRef *self = FLATPAK_REF (object);
  FlatpakRefPrivate *priv = flatpak_ref_get_instance_private (self);

  switch (prop_id)
    {
    case PROP_NAME:
      g_value_set_string (value, priv->name);
      break;

    case PROP_ARCH:
      g_value_set_string (value, priv->arch);
      break;

    case PROP_BRANCH:
      g_value_set_string (value, priv->branch);
      break;

    case PROP_COMMIT:
      g_value_set_string (value, priv->commit);
      break;

    case PROP_KIND:
      g_value_set_enum (value, priv->kind);
      break;

    case PROP_COLLECTION_ID:
      g_value_set_string (value, priv->collection_id);
      break;

    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
    }
}

static void
flatpak_ref_class_init (FlatpakRefClass *klass)
{
  GObjectClass *object_class = G_OBJECT_CLASS (klass);

  object_class->get_property = flatpak_ref_get_property;
  object_class->set_property = flatpak_ref_set_property;
  object_class->finalize = flatpak_ref_finalize;

  g_object_class_install_property (object_class,
                                   PROP_NAME,
                                   g_param_spec_string ("name",
                                                        "Name",
                                                        "The name of the application or runtime",
                                                        NULL,
                                                        G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (object_class,
                                   PROP_ARCH,
                                   g_param_spec_string ("arch",
                                                        "Architecture",
                                                        "The architecture of the application or runtime",
                                                        NULL,
                                                        G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (object_class,
                                   PROP_BRANCH,
                                   g_param_spec_string ("branch",
                                                        "Branch",
                                                        "The branch of the application or runtime",
                                                        NULL,
                                                        G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (object_class,
                                   PROP_COMMIT,
                                   g_param_spec_string ("commit",
                                                        "Commit",
                                                        "The commit",
                                                        NULL,
                                                        G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (object_class,
                                   PROP_KIND,
                                   g_param_spec_enum ("kind",
                                                      "Kind",
                                                      "The kind of artifact",
                                                      FLATPAK_TYPE_REF_KIND,
                                                      FLATPAK_REF_KIND_APP,
                                                      G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (object_class,
                                   PROP_COLLECTION_ID,
                                   g_param_spec_string ("collection-id",
                                                        "Collection ID",
                                                        "The collection ID",
                                                        NULL,
                                                        G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
}

static void
flatpak_ref_init (FlatpakRef *self)
{
  FlatpakRefPrivate *priv = flatpak_ref_get_instance_private (self);

  priv->kind = FLATPAK_REF_KIND_APP;
}

/**
 * flatpak_ref_get_name:
 * @self: a #FlatpakRef
 *
 * Gets the name of the ref.
 *
 * Returns: (transfer none): the name
 */
const char *
flatpak_ref_get_name (FlatpakRef *self)
{
  FlatpakRefPrivate *priv = flatpak_ref_get_instance_private (self);

  return priv->name;
}

/**
 * flatpak_ref_get_arch:
 * @self: a #FlatpakRef
 *
 * Gets the arch or the ref.
 *
 * Returns: (transfer none): the arch
 */
const char *
flatpak_ref_get_arch (FlatpakRef *self)
{
  FlatpakRefPrivate *priv = flatpak_ref_get_instance_private (self);

  return priv->arch;
}

/**
 * flatpak_ref_get_branch:
 * @self: a #FlatpakRef
 *
 * Gets the branch of the ref.
 *
 * Returns: (transfer none): the branch
 */
const char *
flatpak_ref_get_branch (FlatpakRef *self)
{
  FlatpakRefPrivate *priv = flatpak_ref_get_instance_private (self);

  return priv->branch;
}

/**
 * flatpak_ref_get_commit:
 * @self: a #FlatpakRef
 *
 * Gets the commit of the ref.
 *
 * Returns: (transfer none): the commit
 */
const char *
flatpak_ref_get_commit (FlatpakRef *self)
{
  FlatpakRefPrivate *priv = flatpak_ref_get_instance_private (self);

  return priv->commit;
}

/**
 * flatpak_ref_get_kind:
 * @self: a #FlatpakRef
 *
 * Gets the kind of artifact that this ref refers to.
 *
 * Returns: the kind of artifact
 */
FlatpakRefKind
flatpak_ref_get_kind (FlatpakRef *self)
{
  FlatpakRefPrivate *priv = flatpak_ref_get_instance_private (self);

  return priv->kind;
}

/**
 * flatpak_ref_format_ref:
 * @self: a #FlatpakRef
 *
 * Convert an FlatpakRef object into a string representation that
 * can be parsed by flatpak_ref_parse().
 *
 * Returns: (transfer full): string representation
 */
char *
flatpak_ref_format_ref (FlatpakRef *self)
{
  FlatpakRefPrivate *priv = flatpak_ref_get_instance_private (self);

  if (priv->kind == FLATPAK_REF_KIND_APP)
    return flatpak_build_app_ref (priv->name,
                                  priv->branch,
                                  priv->arch);
  else
    return flatpak_build_runtime_ref (priv->name,
                                      priv->branch,
                                      priv->arch);
}

/**
 * flatpak_ref_format_ref_cached:
 * @self: a #FlatpakRef
 *
 * Like flatpak_ref_format_ref() but this returns the same string each time
 * it's called rather than allocating a new one.
 *
 * Returns: (transfer none): string representation
 *
 * Since: 1.9.1
 */
const char *
flatpak_ref_format_ref_cached (FlatpakRef *self)
{
  FlatpakRefPrivate *priv = flatpak_ref_get_instance_private (self);
  const char *full_ref;
  char *full_ref_new;

  full_ref = (const char *)g_atomic_pointer_get (&priv->cached_full_ref);
  if (full_ref == NULL)
    {
      full_ref_new = flatpak_ref_format_ref (self);
      if (!g_atomic_pointer_compare_and_exchange ((void**) &priv->cached_full_ref, NULL, full_ref_new))
        g_free (full_ref_new); /* Raced with someone, free our version */

      full_ref = (const char *)g_atomic_pointer_get (&priv->cached_full_ref); /* Now guaranteed to be non-NULL */
    }

  return full_ref;
}

/**
 * flatpak_ref_parse:
 * @ref: A string ref name, such as "app/org.test.App/x86_64/master"
 * @error: return location for a #GError
 *
 * Tries to parse a full ref name and return a #FlatpakRef (without a
 * commit set) or fail if the ref is invalid somehow.
 *
 * Returns: (transfer full): an #FlatpakRef, or %NULL
 */
FlatpakRef *
flatpak_ref_parse (const char *ref, GError **error)
{
  g_autoptr(FlatpakDecomposed) decomposed = NULL;

  decomposed = flatpak_decomposed_new_from_ref (ref, error);
  if (decomposed == NULL)
    return NULL;

  return FLATPAK_REF (g_object_new (FLATPAK_TYPE_REF,
                                    "kind", flatpak_decomposed_get_kind (decomposed),
                                    "name", flatpak_decomposed_peek_id (decomposed, NULL),
                                    "arch", flatpak_decomposed_peek_arch (decomposed, NULL),
                                    "branch", flatpak_decomposed_peek_branch (decomposed, NULL),
                                    NULL));
}

/**
 * flatpak_ref_get_collection_id:
 * @self: a #FlatpakRef
 *
 * Gets the collection ID of the ref.
 *
 * Returns: (transfer none): the collection ID
 */
const char *
flatpak_ref_get_collection_id (FlatpakRef *self)
{
  FlatpakRefPrivate *priv = flatpak_ref_get_instance_private (self);

  return priv->collection_id;
}

===== ./common/flatpak-remote-private.h =====
/*
 * Copyright © 2015 Red Hat, Inc
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Alexander Larsson <alexl@redhat.com>
 */

#if !defined(__FLATPAK_H_INSIDE__) && !defined(FLATPAK_COMPILATION)
#error "Only <flatpak.h> can be included directly."
#endif

#ifndef __FLATPAK_REMOTE_PRIVATE_H__
#define __FLATPAK_REMOTE_PRIVATE_H__

#include <flatpak-remote.h>
#include <flatpak-dir-private.h>
#include <ostree.h>

FlatpakRemote *flatpak_remote_new_with_dir (const char *name,
                                            FlatpakDir *dir);

gboolean flatpak_remote_commit (FlatpakRemote *self,
                                FlatpakDir    *dir,
                                GCancellable  *cancellable,
                                GError       **error);
gboolean flatpak_remote_commit_filter (FlatpakRemote *self,
                                       FlatpakDir    *dir,
                                       GCancellable  *cancellable,
                                       GError       **error);

#endif /* __FLATPAK_REMOTE_PRIVATE_H__ */

===== ./common/flatpak-related-ref-private.h =====
/*
 * Copyright © 2015 Red Hat, Inc
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Alexander Larsson <alexl@redhat.com>
 */

#if !defined(__FLATPAK_H_INSIDE__) && !defined(FLATPAK_COMPILATION)
#error "Only <flatpak.h> can be included directly."
#endif

#ifndef __FLATPAK_RELATED_REF_PRIVATE_H__
#define __FLATPAK_RELATED_REF_PRIVATE_H__

#include <flatpak-related-ref.h>
#include <flatpak-dir-private.h>

FlatpakRelatedRef *flatpak_related_ref_new (const char  *full_ref,
                                            const char  *commit,
                                            char       **subpaths,
                                            gboolean download,
                                            gboolean     delete);

#endif /* __FLATPAK_RELATED_REF_PRIVATE_H__ */

===== ./common/flatpak-remote-ref.h =====
/*
 * Copyright © 2015 Red Hat, Inc
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Alexander Larsson <alexl@redhat.com>
 */

#if !defined(__FLATPAK_H_INSIDE__) && !defined(FLATPAK_COMPILATION)
#error "Only <flatpak.h> can be included directly."
#endif

#ifndef __FLATPAK_REMOTE_REF_H__
#define __FLATPAK_REMOTE_REF_H__

typedef struct _FlatpakRemoteRef FlatpakRemoteRef;

#include <gio/gio.h>
#include <flatpak-ref.h>

G_BEGIN_DECLS

#define FLATPAK_TYPE_REMOTE_REF flatpak_remote_ref_get_type ()
#define FLATPAK_REMOTE_REF(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), FLATPAK_TYPE_REMOTE_REF, FlatpakRemoteRef))
#define FLATPAK_IS_REMOTE_REF(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), FLATPAK_TYPE_REMOTE_REF))

FLATPAK_EXTERN GType flatpak_remote_ref_get_type (void);

struct _FlatpakRemoteRef
{
  FlatpakRef parent;
};

typedef struct
{
  FlatpakRefClass parent_class;
} FlatpakRemoteRefClass;

FLATPAK_EXTERN const char * flatpak_remote_ref_get_remote_name (FlatpakRemoteRef *self);
FLATPAK_EXTERN guint64      flatpak_remote_ref_get_installed_size (FlatpakRemoteRef *self);
FLATPAK_EXTERN guint64      flatpak_remote_ref_get_download_size (FlatpakRemoteRef *self);
FLATPAK_EXTERN GBytes *     flatpak_remote_ref_get_metadata (FlatpakRemoteRef *self);
FLATPAK_EXTERN const char * flatpak_remote_ref_get_eol (FlatpakRemoteRef *self);
FLATPAK_EXTERN const char * flatpak_remote_ref_get_eol_rebase (FlatpakRemoteRef *self);

#ifdef G_DEFINE_AUTOPTR_CLEANUP_FUNC
G_DEFINE_AUTOPTR_CLEANUP_FUNC (FlatpakRemoteRef, g_object_unref)
#endif

G_END_DECLS

#endif /* __FLATPAK_REMOTE_REF_H__ */

===== ./common/flatpak-ref-utils.c =====
/* vi:set et sw=2 sts=2 cin cino=t0,f0,(0,{s,>2s,n-s,^-s,e-s:
 * Copyright © 2014-2020 Red Hat, Inc
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Alexander Larsson <alexl@redhat.com>
 */

#include "config.h"

#include <glib/gi18n-lib.h>

#include <string.h>
#include <stdlib.h>

#include <glib.h>
#include "flatpak-ref-utils-private.h"

#include <ostree.h>

#include "flatpak-error.h"
#include "flatpak-metadata-private.h"
#include "flatpak-utils-private.h"

FlatpakKinds
flatpak_kinds_from_kind (FlatpakRefKind kind)
{
  if (kind == FLATPAK_REF_KIND_RUNTIME)
    return FLATPAK_KINDS_RUNTIME;
  return FLATPAK_KINDS_APP;
}

static gboolean
is_valid_initial_name_character (gint c, gboolean allow_dash)
{
  return
    (c >= 'A' && c <= 'Z') ||
    (c >= 'a' && c <= 'z') ||
    (c == '_') || (allow_dash && c == '-');
}

static gboolean
is_valid_name_character (gint c, gboolean allow_dash)
{
  return
    is_valid_initial_name_character (c, allow_dash) ||
    (c >= '0' && c <= '9');
}

static const char *
find_last_char (const char *str, gsize len, int c)
{
  const char *p = str + len - 1;
  while (p >= str)
    {
      if (*p == c)
        return p;
      p--;
    }
  return NULL;
}

/**
 * flatpak_is_valid_name:
 * @string: The string to check
 * @len: The string length, or -1 for null-terminated
 * @error: Return location for an error
 *
 * Checks if @string is a valid application name.
 *
 * App names are composed of 3 or more elements separated by a period
 * ('.') character. All elements must contain at least one character.
 *
 * Each element must only contain the ASCII characters
 * "[A-Z][a-z][0-9]_-". Elements may not begin with a digit.
 * Additionally "-" is only allowed in the last element.
 *
 * App names must not begin with a '.' (period) character.
 *
 * App names must not exceed 255 characters in length.
 *
 * The above means that any app name is also a valid DBus well known
 * bus name, but not all DBus names are valid app names. The difference are:
 * 1) DBus name elements may contain '-' in the non-last element.
 * 2) DBus names require only two elements
 *
 * Returns: %TRUE if valid, %FALSE otherwise.
 */
gboolean
flatpak_is_valid_name (const char *string,
                       gssize      len,
                       GError    **error)
{
  gboolean ret;
  const gchar *s;
  const gchar *end;
  const gchar *last_dot;
  int dot_count;
  gboolean last_element;

  g_return_val_if_fail (string != NULL, FALSE);

  ret = FALSE;

  if (len < 0)
    len = strlen (string);
  if (G_UNLIKELY (len == 0))
    {
      flatpak_fail_error (error, FLATPAK_ERROR_INVALID_NAME,
                          _("Name can't be empty"));
      goto out;
    }

  if (G_UNLIKELY (len > 255))
    {
      flatpak_fail_error (error, FLATPAK_ERROR_INVALID_NAME,
                          _("Name can't be longer than 255 characters"));
      goto out;
    }

  end = string + len;

  last_dot = find_last_char (string, len, '.');
  last_element = FALSE;

  s = string;
  if (G_UNLIKELY (*s == '.'))
    {
      flatpak_fail_error (error, FLATPAK_ERROR_INVALID_NAME,
                          _("Name can't start with a period"));
      goto out;
    }
  else if (G_UNLIKELY (!is_valid_initial_name_character (*s, last_element)))
    {
      flatpak_fail_error (error, FLATPAK_ERROR_INVALID_NAME,
                          _("Name can't start with %c"), *s);
      goto out;
    }

  s += 1;
  dot_count = 0;
  while (s != end)
    {
      if (*s == '.')
        {
          if (s == last_dot)
            last_element = TRUE;
          s += 1;
          if (G_UNLIKELY (s == end))
            {
              flatpak_fail_error (error, FLATPAK_ERROR_INVALID_NAME,
                                  _("Name can't end with a period"));
              goto out;
            }
          if (!is_valid_initial_name_character (*s, last_element))
            {
              if (*s == '-')
                flatpak_fail_error (error, FLATPAK_ERROR_INVALID_NAME,
                                    _("Only last name segment can contain -"));
              else
                flatpak_fail_error (error, FLATPAK_ERROR_INVALID_NAME,
                                    _("Name segment can't start with %c"), *s);
              goto out;
            }
          dot_count++;
        }
      else if (G_UNLIKELY (!is_valid_name_character (*s, last_element)))
        {
          if (*s == '-')
            flatpak_fail_error (error, FLATPAK_ERROR_INVALID_NAME,
                                _("Only last name segment can contain -"));
          else
            flatpak_fail_error (error, FLATPAK_ERROR_INVALID_NAME,
                                _("Name can't contain %c"), *s);
          goto out;
        }
      s += 1;
    }

  if (G_UNLIKELY (dot_count < 2))
    {
      flatpak_fail_error (error, FLATPAK_ERROR_INVALID_NAME,
                          _("Names must contain at least 2 periods"));
      goto out;
    }

  ret = TRUE;

out:
  return ret;
}

gboolean
flatpak_has_name_prefix (const char *string,
                         const char *name)
{
  const char *rest;

  if (!g_str_has_prefix (string, name))
    return FALSE;

  rest = string + strlen (name);
  return
    *rest == 0 ||
    *rest == '.' ||
    !is_valid_name_character (*rest, FALSE);
}


gboolean
flatpak_name_matches_one_wildcard_prefix (const char         *name,
                                          const char * const *wildcarded_prefixes,
                                          gboolean            require_exact_match)
{
  const char * const *iter = wildcarded_prefixes;
  const char *remainder;
  gsize longest_match_len = 0;

  /* Find longest valid match */
  for (; *iter != NULL; ++iter)
    {
      const char *prefix = *iter;
      gsize prefix_len = strlen (prefix);
      gsize match_len;
      gboolean has_wildcard = FALSE;
      const char *end_of_match;

      if (g_str_has_suffix (prefix, ".*"))
        {
          has_wildcard = TRUE;
          prefix_len -= 2;
        }

      if (strncmp (name, prefix, prefix_len) != 0)
        continue;

      end_of_match = name + prefix_len;

      if (has_wildcard &&
          end_of_match[0] == '.' &&
          is_valid_initial_name_character (end_of_match[1], TRUE))
        {
          end_of_match += 2;
          while (*end_of_match != 0 &&
                 (is_valid_name_character (*end_of_match, TRUE) ||
                  (end_of_match[0] == '.' &&
                   is_valid_initial_name_character (end_of_match[1], TRUE))))
            end_of_match++;
        }

      match_len = end_of_match - name;

      if (match_len > longest_match_len)
        longest_match_len = match_len;
    }

  if (longest_match_len == 0)
    return FALSE;

  if (require_exact_match)
    return name[longest_match_len] == 0;

  /* non-exact matches can be exact, or can be followed by characters that would make
   * not be part of the last element in the matched prefix, due to being invalid or
   * a new element. As a special case we explicitly disallow dash here, even though
   * it iss typically allowed in the final element of a name, this allows you too sloppily
   * match org.the.App with org.the.App-symbolic[.png] or org.the.App-settings[.desktop].
   */
  remainder = name + longest_match_len;
  return
    *remainder == 0 ||
    *remainder == '.' ||
    !is_valid_name_character (*remainder, FALSE);
}


static gboolean
is_valid_arch_character (char c)
{
  return
    (c >= 'A' && c <= 'Z') ||
    (c >= 'a' && c <= 'z') ||
    (c >= '0' && c <= '9') ||
    (c == '_');
}

gboolean
flatpak_is_valid_arch (const char *string,
                       gssize      len,
                       GError    **error)
{
  const gchar *end;

  if (len < 0)
    len = strlen (string);

  if (G_UNLIKELY (len == 0))
    {
      flatpak_fail_error (error, FLATPAK_ERROR_INVALID_NAME,
                          _("Arch can't be empty"));
      return FALSE;
    }

  end = string + len;

  while (string != end)
    {
      if (G_UNLIKELY (!is_valid_arch_character (*string)))
        {
          flatpak_fail_error (error, FLATPAK_ERROR_INVALID_NAME,
                              _("Arch can't contain %c"), *string);
          return FALSE;
        }
      string += 1;
    }

  return TRUE;
}


static gboolean
is_valid_initial_branch_character (gint c)
{
  return
    (c >= '0' && c <= '9') ||
    (c >= 'A' && c <= 'Z') ||
    (c >= 'a' && c <= 'z') ||
    (c == '_') ||
    (c == '-');
}

static gboolean
is_valid_branch_character (gint c)
{
  return
    is_valid_initial_branch_character (c) ||
    (c == '.');
}

/**
 * flatpak_is_valid_branch:
 * @string: The string to check
 * @len: The string length, or -1 for null-terminated
 * @error: return location for an error
 *
 * Checks if @string is a valid branch name.
 *
 * Branch names must only contain the ASCII characters
 * "[A-Z][a-z][0-9]_-.".
 * Branch names may not begin with a period.
 * Branch names must contain at least one character.
 *
 * Returns: %TRUE if valid, %FALSE otherwise.
 */
gboolean
flatpak_is_valid_branch (const char *string,
                         gssize      len,
                         GError    **error)
{
  gboolean ret;
  const gchar *s;
  const gchar *end;

  g_return_val_if_fail (string != NULL, FALSE);

  ret = FALSE;

  if (len < 0)
    len = strlen (string);
  if (G_UNLIKELY (len == 0))
    {
      flatpak_fail_error (error, FLATPAK_ERROR_INVALID_NAME,
                          _("Branch can't be empty"));
      goto out;
    }

  end = string + len;

  s = string;
  if (G_UNLIKELY (!is_valid_initial_branch_character (*s)))
    {
      flatpak_fail_error (error, FLATPAK_ERROR_INVALID_NAME,
                          _("Branch can't start with %c"), *s);
      goto out;
    }

  s += 1;
  while (s != end)
    {
      if (G_UNLIKELY (!is_valid_branch_character (*s)))
        {
          flatpak_fail_error (error, FLATPAK_ERROR_INVALID_NAME,
                              _("Branch can't contain %c"), *s);
          goto out;
        }
      s += 1;
    }

  ret = TRUE;

out:
  return ret;
}


/* Dashes are only valid in the last part of the app id, so
   we replace them with underscore so we can suffix the id */
char *
flatpak_make_valid_id_prefix (const char *orig_id)
{
  char *id, *t;

  id = g_strdup (orig_id);
  t = id;
  while (*t != 0 && *t != '/')
    {
      if (*t == '-')
        *t = '_';

      t++;
    }

  return id;
}

static gboolean
str_has_suffix (const gchar *str,
                gsize        str_len,
                const gchar *suffix)
{
  gsize suffix_len;

  suffix_len = strlen (suffix);
  if (str_len < suffix_len)
    return FALSE;

  return strncmp (str + str_len - suffix_len, suffix, suffix_len) == 0;
}


gboolean
flatpak_id_has_subref_suffix (const char *id,
                              gssize id_len)
{
  if (id_len < 0)
    id_len = strlen (id);

  return
    str_has_suffix (id, id_len, ".Locale") ||
    str_has_suffix (id, id_len, ".Debug") ||
    str_has_suffix (id, id_len, ".Sources");
}


static gboolean
str_has_prefix (const gchar *str,
                gsize        str_len,
                const gchar *prefix)
{
  gsize prefix_len;

  prefix_len = strlen (prefix);
  if (str_len < prefix_len)
    return FALSE;

  return strncmp (str, prefix, prefix_len) == 0;
}

static const char *
skip_segment (const char *s)
{
  const char *slash;

  slash = strchr (s, '/');
  if (slash)
    return slash + 1;
  return s + strlen (s);
}

static int
compare_segment (const char *s1, const char *s2)
{
  gint c1, c2;

  while (*s1 && *s1 != '/' &&
         *s2 && *s2 != '/')
    {
      c1 = *s1;
      c2 = *s2;
      if (c1 != c2)
        return c1 - c2;
      s1++;
      s2++;
    }

  c1 = *s1;
  if (c1 == '/')
    c1 = 0;
  c2 = *s2;
  if (c2 == '/')
    c2 = 0;

  return c1 - c2;
}

int
flatpak_compare_ref (const char *ref1, const char *ref2)
{
  int res;
  int i;

  /* Skip first element and do per-segment compares for rest */
  for (i = 0; i < 3; i++)
    {
      ref1 = skip_segment (ref1);
      ref2 = skip_segment (ref2);

      res = compare_segment (ref1, ref2);
      if (res != 0)
        return res;
    }
  return 0;
}

struct _FlatpakDecomposed {
  int ref_count;
  guint16 ref_offset;
  guint16 id_offset;
  guint16 arch_offset;
  guint16 branch_offset;
  char *data;

  /* This is only used when we're directly manipulating sideload repos, by giving
   * a file:// uri as the remote name. Typically we don't really care about collection ids
   * internally in flatpak as we use refs tied to a remote. */
  char *collection_id;
};

static gboolean
is_valid_initial_remote_name_character (gint c)
{
  return
    (c >= 'A' && c <= 'Z') ||
    (c >= 'a' && c <= 'z') ||
    (c >= '0' && c <= '9') ||
    (c == '_');
}

static gboolean
is_valid_remote_name_character (gint c)
{
  return
    is_valid_initial_remote_name_character (c) ||
    c == '-' ||
    c == '.';
}

static gboolean
is_valid_remote_name (const char *remote,
                      gsize len)
{
  const char *end;

  if (len == 0)
    return FALSE;

  end = remote + len;

  if (!is_valid_initial_remote_name_character (*remote++))
    return FALSE;

  while (remote < end)
    {
      char c = *remote++;
      if (!is_valid_remote_name_character (c))
        return FALSE;
    }

  return TRUE;
}


static FlatpakDecomposed *
_flatpak_decomposed_new (char            *ref,
                         gboolean         allow_refspec,
                         gboolean         take,
                         GError         **error)
{
  g_autoptr(GError) local_error = NULL;
  const char *p;
  const char *slash;
  gsize ref_offset;
  gsize id_offset;
  gsize arch_offset;
  gsize branch_offset;
  gsize len;
  FlatpakDecomposed *decomposed;

  /* We want to use uint16 to store offset, so fail on uselessly large refs */
  len = strlen (ref);
  if (len > 0xffff)
    {
      flatpak_fail_error (error, FLATPAK_ERROR_INVALID_REF, _("Ref too long"));
      return NULL;
    }

  p = ref;
  if (allow_refspec)
    {
      const char *colon = strchr (p, ':');
      if (colon != NULL)
        {
          if (!is_valid_remote_name (ref, colon - ref))
            {
              flatpak_fail_error (error, FLATPAK_ERROR_INVALID_REF, _("Invalid remote name"));
              return NULL;
            }
          p = colon + 1;
        }
    }
  ref_offset = p - ref;

  if (g_str_has_prefix (p, "app/"))
    p += strlen ("app/");
  else if (g_str_has_prefix (p, "runtime/"))
    p += strlen ("runtime/");
  else
    {
      flatpak_fail_error (error, FLATPAK_ERROR_INVALID_REF, _("%s is not application or runtime"), ref);
      return NULL;
    }

  id_offset = p - ref;

  slash = strchr (p, '/');
  if (slash == NULL)
    {
      flatpak_fail_error (error, FLATPAK_ERROR_INVALID_REF, _("Wrong number of components in %s"), ref);
      return NULL;
    }

  if (!flatpak_is_valid_name (p, slash - p, &local_error))
    {
      flatpak_fail_error (error, FLATPAK_ERROR_INVALID_REF, _("Invalid name %.*s: %s"), (int)(slash - p), p, local_error->message);
      return NULL;
    }

  p = slash + 1;

  arch_offset = p - ref;

  slash = strchr (p, '/');
  if (slash == NULL)
    {
      flatpak_fail_error (error, FLATPAK_ERROR_INVALID_REF, _("Wrong number of components in %s"), ref);
      return NULL;
    }

  if (!flatpak_is_valid_arch (p, slash - p, &local_error))
    {
      flatpak_fail_error (error, FLATPAK_ERROR_INVALID_REF, _("Invalid arch: %.*s: %s"), (int)(slash - p), p, local_error->message);
      return NULL;
    }

  p = slash + 1;
  branch_offset = p - ref;

  slash = strchr (p, '/');
  if (slash != NULL)
    {
      flatpak_fail_error (error, FLATPAK_ERROR_INVALID_REF, _("Wrong number of components in %s"), ref);
      return NULL;
    }

  if (!flatpak_is_valid_branch (p, -1, &local_error))
    {
      flatpak_fail_error (error, FLATPAK_ERROR_INVALID_REF, _("Invalid branch %s: %s"), p, local_error->message);
      return NULL;
    }

  if (take)
    {
      decomposed = g_malloc (sizeof (FlatpakDecomposed));
      decomposed->data = ref;
    }
  else
    {
      char *inline_data;

      /* Store the dup:ed ref inline */
      decomposed = g_malloc (sizeof (FlatpakDecomposed) + strlen (ref) + 1);
      inline_data = (char *)decomposed + sizeof (FlatpakDecomposed);

      strcpy (inline_data, ref);
      decomposed->data = inline_data;
    }
  decomposed->ref_count = 1;
  decomposed->collection_id = NULL;
  decomposed->ref_offset = (guint16)ref_offset;
  decomposed->id_offset = (guint16)id_offset;
  decomposed->arch_offset = (guint16)arch_offset;
  decomposed->branch_offset = (guint16)branch_offset;

  return decomposed;
}

FlatpakDecomposed *
flatpak_decomposed_new_from_ref (const char         *ref,
                                 GError            **error)
{
  return _flatpak_decomposed_new ((char *)ref, FALSE, FALSE, error);
}

FlatpakDecomposed *
flatpak_decomposed_new_from_refspec (const char         *refspec,
                                     GError            **error)
{
  return _flatpak_decomposed_new ((char *)refspec, TRUE, FALSE, error);
}

FlatpakDecomposed *
flatpak_decomposed_new_from_ref_take (char         *ref,
                                      GError      **error)
{
  return _flatpak_decomposed_new (ref, FALSE, TRUE, error);
}

FlatpakDecomposed *
flatpak_decomposed_new_from_refspec_take (char         *refspec,
                                          GError       **error)
{
  return _flatpak_decomposed_new (refspec, TRUE, TRUE, error);
}

FlatpakDecomposed *
flatpak_decomposed_new_from_col_ref      (const char         *ref,
                                          const char         *collection_id,
                                          GError            **error)
{
  g_autoptr(FlatpakDecomposed) decomposed = NULL;

  if (collection_id != NULL &&
      !ostree_validate_collection_id (collection_id, error))
    return FALSE;

  decomposed = flatpak_decomposed_new_from_ref (ref, error);
  if (decomposed == NULL)
    return FALSE;

  decomposed->collection_id = g_strdup (collection_id);

  return g_steal_pointer (&decomposed);
}

static FlatpakDecomposed *
_flatpak_decomposed_new_from_decomposed (FlatpakDecomposed  *old,
                                         FlatpakKinds        opt_kind,
                                         const char         *opt_id,
                                         gssize              opt_id_len,
                                         const char         *opt_arch,
                                         gssize              opt_arch_len,
                                         const char         *opt_branch,
                                         gssize              opt_branch_len,
                                         GError            **error)
{
  FlatpakDecomposed *decomposed;
  g_autoptr(GError) local_error = NULL;
  char *inline_data;
  const char *kind_str;
  gsize kind_len;
  gsize id_len;
  gsize arch_len;
  gsize branch_len;
  gsize ref_len;
  char *ref;
  gsize offset;

  if (old == NULL)
    {
      g_assert (opt_kind != 0);
      g_assert (opt_id != NULL);
      g_assert (opt_arch != NULL);
      g_assert (opt_branch != NULL);
    }

  if (opt_kind == 0)
    kind_str = flatpak_decomposed_get_kind_str (old);
  else if (opt_kind == FLATPAK_KINDS_APP)
    kind_str = "app";
  else
    kind_str = "runtime";

  kind_len = strlen (kind_str);

  if (opt_id)
    {
      if (opt_id_len == -1)
        id_len = strlen (opt_id);
      else
        id_len = opt_id_len;

      if (!flatpak_is_valid_name (opt_id, id_len, &local_error))
        {
          flatpak_fail_error (error, FLATPAK_ERROR_INVALID_REF, _("Invalid name %s: %s"), opt_id, local_error->message);
          return NULL;
        }
    }
  else
    {
      opt_id = flatpak_decomposed_peek_id (old, &id_len);
    }

  if (opt_arch)
    {
      if (opt_arch_len == -1)
        arch_len = strlen (opt_arch);
      else
        arch_len = opt_arch_len;

      if (!flatpak_is_valid_arch (opt_arch, arch_len, &local_error))
        {
          flatpak_fail_error (error, FLATPAK_ERROR_INVALID_REF, _("Invalid arch: %s: %s"), opt_arch, local_error->message);
          return NULL;
        }

    }
  else
    {
      opt_arch = flatpak_decomposed_peek_arch (old, &arch_len);
    }

  if (opt_branch)
    {
      if (opt_branch_len == -1)
        branch_len = strlen (opt_branch);
      else
        branch_len = opt_branch_len;

      if (!flatpak_is_valid_branch (opt_branch, branch_len, &local_error))
        {
          flatpak_fail_error (error, FLATPAK_ERROR_INVALID_REF, _("Invalid branch: %s: %s"), opt_branch, local_error->message);
          return NULL;
        }
    }
  else
    {
      opt_branch = flatpak_decomposed_peek_branch (old, &branch_len);
    }

  ref_len = kind_len + 1 + id_len + 1 + arch_len + 1 + branch_len;
  if (ref_len > 0xffff)
    {
      flatpak_fail_error (error, FLATPAK_ERROR_INVALID_REF, _("Ref too long"));
      return NULL;
    }

  /* Store the ref inline */
  decomposed = g_malloc (sizeof (FlatpakDecomposed) + ref_len + 1);
  inline_data = (char *)decomposed + sizeof (FlatpakDecomposed);

  decomposed->ref_count = 1;
  decomposed->data = inline_data;
  decomposed->collection_id = NULL;

  ref = inline_data;
  offset = 0;

  decomposed->ref_offset = (guint16)offset;
  memcpy (ref + offset, kind_str, kind_len);
  offset += kind_len;

  memcpy (ref + offset, "/", 1);
  offset += 1;

  decomposed->id_offset = (guint16)offset;
  memcpy (ref + offset, opt_id, id_len);
  offset += id_len;

  memcpy (ref + offset, "/", 1);
  offset += 1;

  decomposed->arch_offset = (guint16)offset;
  memcpy (ref + offset, opt_arch, arch_len);
  offset += arch_len;

  memcpy (ref + offset, "/", 1);
  offset += 1;

  decomposed->branch_offset = (guint16)offset;
  memcpy (ref + offset, opt_branch, branch_len);
  offset += branch_len;

  g_assert (offset == ref_len);
  *(ref + offset) = 0;

  return decomposed;
}

FlatpakDecomposed *
flatpak_decomposed_new_from_decomposed (FlatpakDecomposed  *old,
                                        FlatpakKinds        opt_kind,
                                        const char         *opt_id,
                                        const char         *opt_arch,
                                        const char         *opt_branch,
                                        GError            **error)
{
  return _flatpak_decomposed_new_from_decomposed (old, opt_kind,
                                                  opt_id, -1,
                                                  opt_arch, -1,
                                                  opt_branch, -1,
                                                  error);
}

FlatpakDecomposed *
flatpak_decomposed_new_from_parts (FlatpakKinds        kind,
                                   const char         *id,
                                   const char         *arch,
                                   const char         *branch,
                                   GError            **error)
{
  g_assert (kind == FLATPAK_KINDS_APP || kind == FLATPAK_KINDS_RUNTIME);
  g_assert (id != NULL);

  if (branch == NULL)
    branch = "master";

  if (arch == NULL)
    arch = flatpak_get_arch ();

  return flatpak_decomposed_new_from_decomposed (NULL, kind, id, arch, branch, error);
}

FlatpakDecomposed *
flatpak_decomposed_new_from_pref (FlatpakKinds        kind,
                                  const char         *pref,
                                  GError            **error)
{
  const char *slash;
  const char *id;
  const char *arch;
  const char *branch;

  g_assert (kind == FLATPAK_KINDS_APP || kind == FLATPAK_KINDS_RUNTIME);
  g_assert (pref != NULL);

  id = pref;
  slash = strchr (id, '/');
  if (slash == NULL)
    {
      flatpak_fail_error (error, FLATPAK_ERROR_INVALID_REF, _("Wrong number of components in partial ref %s"), pref);
      return NULL;
    }

  arch = slash + 1;
  slash = strchr (arch, '/');
  if (slash == NULL)
    {
      flatpak_fail_error (error, FLATPAK_ERROR_INVALID_REF, _("Wrong number of components in partial ref %s"), pref);
      return NULL;
    }

  branch = slash + 1;
  slash = strchr (branch, '/');
  if (slash != NULL)
    {
      flatpak_fail_error (error, FLATPAK_ERROR_INVALID_REF, _("Wrong number of components in partial ref %s"), pref);
      return NULL;
    }

  return _flatpak_decomposed_new_from_decomposed (NULL, kind,
                                                  id, arch - id - 1,
                                                  arch, branch - arch - 1,
                                                  branch, -1,
                                                  error);
}

FlatpakDecomposed *
flatpak_decomposed_ref (FlatpakDecomposed  *ref)
{
  g_atomic_int_inc (&ref->ref_count);
  return ref;
}

void
flatpak_decomposed_unref (FlatpakDecomposed  *ref)
{
  if (g_atomic_int_dec_and_test (&ref->ref_count))
    {
      char *inline_data = (char *)ref + sizeof (FlatpakDecomposed);
      if (ref->data != inline_data)
        g_free (ref->data);
      g_free (ref->collection_id);
      g_free (ref);
    }
}

const char *
flatpak_decomposed_get_ref (FlatpakDecomposed  *ref)
{
  return (const char *)&ref->data[ref->ref_offset];
}

char *
flatpak_decomposed_dup_ref (FlatpakDecomposed  *ref)
{
  return g_strdup (flatpak_decomposed_get_ref (ref));
}

const char *
flatpak_decomposed_get_refspec (FlatpakDecomposed  *ref)
{
  return (const char *)&ref->data[0];
}

char *
flatpak_decomposed_dup_refspec (FlatpakDecomposed  *ref)
{
  return g_strdup (flatpak_decomposed_get_refspec (ref));
}

char *
flatpak_decomposed_dup_remote (FlatpakDecomposed  *ref)
{
  if (ref->ref_offset == 0)
    return NULL;

  return g_strndup (ref->data, ref->ref_offset - 1);
}

/* Note: These are always NULL for regular refs, as they generally
 * tied to a remote and uses the collection_id from that.
 * The only case this is set is if we enumerate a remote
 * of the form `file:///path/to/repo`, as we don't then know
 * which remote name it is from.
 */
const char *
flatpak_decomposed_get_collection_id (FlatpakDecomposed  *ref)
{
  return ref->collection_id;
}

/* Note: These are always NULL for regular refs, as they generally
 * tied to a remote and uses the collection_id from that.
 * The only case this is set is if we enumerate a remote
 * of the form `file:///path/to/repo`, as we don't then know
 * which remote name it is from.
 */
char *
flatpak_decomposed_dup_collection_id (FlatpakDecomposed  *ref)
{
  return g_strdup (ref->collection_id);
}

gboolean
flatpak_decomposed_equal (FlatpakDecomposed  *ref_a,
                          FlatpakDecomposed  *ref_b)
{
  return strcmp (ref_a->data, ref_b->data) == 0 &&
    g_strcmp0 (ref_a->collection_id, ref_b->collection_id) == 0;
}

gint
flatpak_decomposed_strcmp (FlatpakDecomposed  *ref_a,
                           FlatpakDecomposed  *ref_b)
{
  int res = strcmp (ref_a->data, ref_b->data);
  if (res != 0)
    return res;

  return g_strcmp0 (ref_a->collection_id, ref_b->collection_id);
}

gint
flatpak_decomposed_strcmp_p (FlatpakDecomposed  **ref_a,
                             FlatpakDecomposed  **ref_b)
{
  return flatpak_decomposed_strcmp (*ref_a, *ref_b);
}

gboolean
flatpak_decomposed_equal_except_branch (FlatpakDecomposed  *ref_a,
                                        FlatpakDecomposed  *ref_b)
{
  return
    ref_a->branch_offset == ref_b->branch_offset &&
    strncmp (ref_a->data, ref_b->data, ref_a->branch_offset) == 0 &&
    g_strcmp0 (ref_a->collection_id, ref_b->collection_id) == 0;
}

gboolean
flatpak_decomposed_equal_except_arch (FlatpakDecomposed  *ref_a,
                                      FlatpakDecomposed  *ref_b)
{
  return
    ref_a->arch_offset == ref_b->arch_offset &&
    strncmp (ref_a->data, ref_b->data, ref_a->arch_offset) == 0 &&
    strcmp (&ref_a->data[ref_a->branch_offset], &ref_b->data[ref_b->branch_offset]) == 0 &&
    g_strcmp0 (ref_a->collection_id, ref_b->collection_id) == 0;
}

guint
flatpak_decomposed_hash (FlatpakDecomposed  *ref)
{
  guint h = g_str_hash (ref->data);

  if (ref->collection_id)
    h |= g_str_hash (ref->collection_id);

  return h;
}

gboolean
flatpak_decomposed_is_app (FlatpakDecomposed  *ref)
{
  const char *r = flatpak_decomposed_get_ref (ref);
  return r[0] == 'a';
}

gboolean
flatpak_decomposed_is_runtime (FlatpakDecomposed  *ref)
{
  const char *r = flatpak_decomposed_get_ref (ref);
  return r[0] == 'r';
}

FlatpakKinds
flatpak_decomposed_get_kinds (FlatpakDecomposed  *ref)
{
  if (flatpak_decomposed_is_app (ref))
    return FLATPAK_KINDS_APP;
  else
    return FLATPAK_KINDS_RUNTIME;
}

FlatpakRefKind
flatpak_decomposed_get_kind (FlatpakDecomposed  *ref)
{
  if (flatpak_decomposed_is_app (ref))
    return FLATPAK_REF_KIND_APP;
  else
    return FLATPAK_REF_KIND_RUNTIME;
}

const char *
flatpak_decomposed_get_kind_str (FlatpakDecomposed  *ref)
{
  if (flatpak_decomposed_is_app (ref))
    return "app";
  else
    return "runtime";
}

const char *
flatpak_decomposed_get_kind_metadata_group (FlatpakDecomposed  *ref)
{
  if (flatpak_decomposed_is_app (ref))
    return FLATPAK_METADATA_GROUP_APPLICATION;
  else
    return FLATPAK_METADATA_GROUP_RUNTIME;
}

/* A slashed string ends at '/' instead of nul */
static gboolean
slashed_str_equal (const char *slashed_str, const char *str)
{
  char c;
  while ((c = *str) != 0)
    {
      char s_c = *slashed_str;
      if (s_c == '/')
        return FALSE; /* slashed_str stopped early */

      if (s_c != c)
        return FALSE; /* slashed_str not same */

      str++;
      slashed_str++;
    }

  if (*slashed_str != '/') /* str stopped early */
    return FALSE;

  return TRUE;
}

/* These are for refs, so ascii case only */
static gboolean
slashed_str_strcasestr (const char *haystack,
                        gsize haystack_len,
                        const char *needle)
{
  gssize needle_len = strlen (needle);

  if (needle_len > haystack_len)
    return FALSE;

  if (needle_len == 0)
    return TRUE;

  for (gssize i = 0; i <= haystack_len - needle_len; i++)
    {
      if (g_ascii_strncasecmp (haystack + i, needle, needle_len) == 0)
        return TRUE;
    }

  return FALSE;
}

const char *
flatpak_decomposed_get_pref (FlatpakDecomposed  *ref)
{
  return &ref->data[ref->id_offset];
}

char *
flatpak_decomposed_dup_pref (FlatpakDecomposed  *ref)
{
  return g_strdup (flatpak_decomposed_get_pref (ref));
}

const char *
flatpak_decomposed_peek_id (FlatpakDecomposed  *ref,
                            gsize              *out_len)
{
  if (out_len)
    *out_len = ref->arch_offset - ref->id_offset - 1;
  return &ref->data[ref->id_offset];
}

char *
flatpak_decomposed_dup_id (FlatpakDecomposed  *ref)
{
  gsize len;
  const char *ref_id = flatpak_decomposed_peek_id (ref, &len);

  return g_strndup (ref_id, len);
}

char *
flatpak_decomposed_dup_readable_id (FlatpakDecomposed  *ref)
{
  gsize len;
  const char *ref_id = flatpak_decomposed_peek_id (ref, &len);
  const char *start;
  gboolean is_debug, is_sources, is_locale, is_docs, is_sdk, is_platform, is_baseapp;
  GString *s;

  is_debug = str_has_suffix (ref_id, len, ".Debug");
  if (is_debug)
    len -= strlen (".Debug");

  is_sources = str_has_suffix (ref_id, len, ".Sources");
  if (is_sources)
    len -= strlen (".Sources");

  is_locale = str_has_suffix (ref_id, len, ".Locale");
  if (is_locale)
    len -= strlen (".Locale");

  is_docs = str_has_suffix (ref_id, len, ".Docs");
  if (is_docs)
    len -= strlen (".Docs");

  is_baseapp = str_has_suffix (ref_id, len, ".BaseApp");
  if (is_baseapp)
    len -= strlen (".BaseApp");

  is_platform = str_has_suffix (ref_id, len, ".Platform");
  if (is_platform)
    len -= strlen (".Platform");

  is_sdk = str_has_suffix (ref_id, len, ".Sdk");
  if (is_sdk)
    len -= strlen (".Sdk");

  start = ref_id + len;

  while (start > ref_id && start[-1] != '.')
    start--;

  len -= (start - ref_id);

  s = g_string_new ("");
  g_string_append_len (s, start, len);
  if (is_sdk)
    g_string_append (s, _(" development platform"));
  if (is_platform)
    g_string_append (s, _(" platform"));
  if (is_baseapp)
    g_string_append (s, _(" application base"));

  if (is_debug)
    g_string_append (s, _(" debug symbols"));
  if (is_sources)
    g_string_append (s, _(" sourcecode"));
  if (is_locale)
    g_string_append (s, _(" translations"));
  if (is_docs)
    g_string_append (s, _(" docs"));

  return g_string_free (s, FALSE);
}

gboolean
flatpak_decomposed_is_id (FlatpakDecomposed  *ref,
                          const char         *id)
{
  const char *ref_id = flatpak_decomposed_peek_id (ref, NULL);

  return slashed_str_equal (ref_id, id);
}

gboolean
flatpak_decomposed_id_has_suffix (FlatpakDecomposed  *ref,
                                  const char         *suffix)
{
  gsize id_len;
  const char *ref_id = flatpak_decomposed_peek_id (ref, &id_len);
  return str_has_suffix (ref_id, id_len, suffix);
}

gboolean
flatpak_decomposed_id_has_prefix (FlatpakDecomposed  *ref,
                                  const char         *prefix)
{
  gsize id_len;
  const char *ref_id = flatpak_decomposed_peek_id (ref, &id_len);
  return str_has_prefix (ref_id, id_len, prefix);
}


/* See if the given id looks similar to this ref. The
 * Levenshtein distance constant was chosen pretty arbitrarily. */
gboolean
flatpak_decomposed_is_id_fuzzy (FlatpakDecomposed  *ref,
                                const char         *id)
{
  gsize ref_id_len;
  const char *ref_id = flatpak_decomposed_peek_id (ref, &ref_id_len);

  if (slashed_str_strcasestr (ref_id, ref_id_len, id))
    return TRUE;

  return flatpak_levenshtein_distance (id, -1, ref_id, ref_id_len) <= 2;
}

gboolean
flatpak_decomposed_id_is_subref (FlatpakDecomposed  *ref)
{
  gsize ref_id_len;
  const char *ref_id = flatpak_decomposed_peek_id (ref, &ref_id_len);

  if (!flatpak_decomposed_is_runtime (ref))
    return FALSE;

  return flatpak_id_has_subref_suffix (ref_id, ref_id_len);
}

gboolean
flatpak_decomposed_id_is_subref_of (FlatpakDecomposed  *ref,
                                    FlatpakDecomposed  *parent_ref)
{
  gsize ref_id_len;
  const char *ref_id = flatpak_decomposed_peek_id (ref, &ref_id_len);
  gsize parent_id_len;
  const char *parent_id = flatpak_decomposed_peek_id (parent_ref, &parent_id_len);

  /* All subrefs are runtimes, even for apps */
  if (!flatpak_decomposed_is_runtime (ref))
    return FALSE;

  if (!flatpak_id_has_subref_suffix (ref_id, ref_id_len))
    return FALSE;

  /* Guaranteed to have a dot in it from the above check, so strip last element  */
  while (ref_id[ref_id_len-1] != '.')
    ref_id_len--;
  ref_id_len--; /* And strip dot */

  /* Any dashes in the last element of parent_id got converted to
     underscores to make it a valid prefix, so custom compare here. */

  if (ref_id_len != parent_id_len)
    return FALSE;

  for (int i = 0; i < ref_id_len; i++)
    {
      char c = parent_id[i];
      if (c == '-')
        c = '_';

      if (c != ref_id[i])
        return FALSE;
    }

  /* Check the rest of the ref */
  return strcmp (flatpak_decomposed_peek_arch (ref, NULL),
                 flatpak_decomposed_peek_arch (parent_ref, NULL)) == 0;
}


const char *
flatpak_decomposed_peek_arch (FlatpakDecomposed  *ref,
                              gsize *out_len)
{
  if (out_len)
    *out_len = ref->branch_offset - ref->arch_offset - 1;
  return &ref->data[ref->arch_offset];
}

char *
flatpak_decomposed_dup_arch (FlatpakDecomposed  *ref)
{
  gsize len;
  const char *ref_arch = flatpak_decomposed_peek_arch (ref, &len);

  return g_strndup (ref_arch, len);
}

gboolean
flatpak_decomposed_is_arch (FlatpakDecomposed  *ref,
                            const char         *arch)
{
  const char *ref_arch = flatpak_decomposed_peek_arch (ref, NULL);

  return slashed_str_equal (ref_arch, arch);
}

gboolean
flatpak_decomposed_is_arches (FlatpakDecomposed  *ref,
                              gssize              len,
                              const char        **arches)
{
  const char *ref_arch = flatpak_decomposed_peek_arch (ref, NULL);

  if (len < 0)
    {
      len = 0;
      while (arches[len] != NULL)
        len++;
    }

  for (int i = 0; i < len; i++)
    {
      if (slashed_str_equal (ref_arch, arches[i]))
        return TRUE;
    }

  return FALSE;
}

/* We can add a getter for this, because the branch is last so guaranteed to be null-terminated */
const char *
flatpak_decomposed_get_branch (FlatpakDecomposed  *ref)
{
  return &ref->data[ref->branch_offset];
}

const char *
flatpak_decomposed_peek_branch (FlatpakDecomposed  *ref,
                                gsize              *out_len)
{
  const char *branch = flatpak_decomposed_get_branch (ref);
  if (out_len)
    *out_len = strlen (branch);
  return branch;
}

char *
flatpak_decomposed_dup_branch (FlatpakDecomposed  *ref)
{
  const char *ref_branch = flatpak_decomposed_peek_branch (ref, NULL);

  return g_strdup (ref_branch);
}

gboolean
flatpak_decomposed_is_branch (FlatpakDecomposed  *ref,
                              const char         *branch)
{
  const char *ref_branch = flatpak_decomposed_get_branch (ref);

  return strcmp (ref_branch, branch) == 0;
}

static const char *
next_element (const char **partial_ref)
{
  const char *slash;
  const char *end;

  slash = (const char *) strchr (*partial_ref, '/');
  if (slash != NULL)
    {
      end = slash;
      *partial_ref = slash + 1;
    }
  else
    {
      end = *partial_ref + strlen (*partial_ref);
      *partial_ref = end;
    }

  return end;
}

FlatpakKinds
flatpak_kinds_from_bools (gboolean app, gboolean runtime)
{
  FlatpakKinds kinds = 0;

  if (app)
    kinds |= FLATPAK_KINDS_APP;

  if (runtime)
    kinds |= FLATPAK_KINDS_RUNTIME;

  if (kinds == 0)
    kinds = FLATPAK_KINDS_APP | FLATPAK_KINDS_RUNTIME;

  return kinds;
}

static gboolean
_flatpak_split_partial_ref_arg (const char   *partial_ref,
                                gboolean      validate,
                                FlatpakKinds  default_kinds,
                                const char   *default_arch,
                                const char   *default_branch,
                                FlatpakKinds *out_kinds,
                                char        **out_id,
                                char        **out_arch,
                                char        **out_branch,
                                GError      **error)
{
  const char *id_start = NULL;
  const char *id_end = NULL;
  g_autofree char *id = NULL;
  const char *arch_start = NULL;
  const char *arch_end = NULL;
  g_autofree char *arch = NULL;
  const char *branch_start = NULL;
  const char *branch_end = NULL;
  g_autofree char *branch = NULL;
  g_autoptr(GError) local_error = NULL;
  FlatpakKinds kinds = 0;

  if (g_str_has_prefix (partial_ref, "app/"))
    {
      partial_ref += strlen ("app/");
      kinds = FLATPAK_KINDS_APP;
    }
  else if (g_str_has_prefix (partial_ref, "runtime/"))
    {
      partial_ref += strlen ("runtime/");
      kinds = FLATPAK_KINDS_RUNTIME;
    }
  else
    kinds = default_kinds;

  id_start = partial_ref;
  id_end = next_element (&partial_ref);
  id = g_strndup (id_start, id_end - id_start);

  if (validate && !flatpak_is_valid_name (id, -1, &local_error))
    return flatpak_fail_error (error, FLATPAK_ERROR_INVALID_REF, _("Invalid id %s: %s"), id, local_error->message);

  arch_start = partial_ref;
  arch_end = next_element (&partial_ref);
  if (arch_end != arch_start)
    arch = g_strndup (arch_start, arch_end - arch_start);
  else
    arch = g_strdup (default_arch);

  branch_start = partial_ref;
  branch_end = next_element (&partial_ref);
  if (branch_end != branch_start)
    branch = g_strndup (branch_start, branch_end - branch_start);
  else
    branch = g_strdup (default_branch);

  if (validate && branch != NULL && !flatpak_is_valid_branch (branch, -1, &local_error))
    return flatpak_fail_error (error, FLATPAK_ERROR_INVALID_REF, _("Invalid branch %s: %s"), branch, local_error->message);

  if (out_kinds)
    *out_kinds = kinds;
  if (out_id != NULL)
    *out_id = g_steal_pointer (&id);
  if (out_arch != NULL)
    *out_arch = g_steal_pointer (&arch);
  if (out_branch != NULL)
    *out_branch = g_steal_pointer (&branch);

  return TRUE;
}

gboolean
flatpak_split_partial_ref_arg (const char   *partial_ref,
                               FlatpakKinds  default_kinds,
                               const char   *default_arch,
                               const char   *default_branch,
                               FlatpakKinds *out_kinds,
                               char        **out_id,
                               char        **out_arch,
                               char        **out_branch,
                               GError      **error)
{
  return _flatpak_split_partial_ref_arg (partial_ref,
                                         TRUE,
                                         default_kinds,
                                         default_arch,
                                         default_branch,
                                         out_kinds,
                                         out_id,
                                         out_arch,
                                         out_branch,
                                         error);
}

gboolean
flatpak_split_partial_ref_arg_novalidate (const char   *partial_ref,
                                          FlatpakKinds  default_kinds,
                                          const char   *default_arch,
                                          const char   *default_branch,
                                          FlatpakKinds *out_kinds,
                                          char        **out_id,
                                          char        **out_arch,
                                          char        **out_branch)
{
  return _flatpak_split_partial_ref_arg (partial_ref,
                                         FALSE,
                                         default_kinds,
                                         default_arch,
                                         default_branch,
                                         out_kinds,
                                         out_id,
                                         out_arch,
                                         out_branch,
                                         NULL);
}

char *
flatpak_build_untyped_ref (const char *runtime,
                           const char *branch,
                           const char *arch)
{
  if (arch == NULL)
    arch = flatpak_get_arch ();

  return g_build_filename (runtime, arch, branch, NULL);
}

char *
flatpak_build_runtime_ref (const char *runtime,
                           const char *branch,
                           const char *arch)
{
  if (branch == NULL)
    branch = "master";

  if (arch == NULL)
    arch = flatpak_get_arch ();

  return g_build_filename ("runtime", runtime, arch, branch, NULL);
}

char *
flatpak_build_app_ref (const char *app,
                       const char *branch,
                       const char *arch)
{
  if (branch == NULL)
    branch = "master";

  if (arch == NULL)
    arch = flatpak_get_arch ();

  return g_build_filename ("app", app, arch, branch, NULL);
}

gboolean
flatpak_is_app_runtime_or_appstream_ref (const char *ref)
{
  return
    g_str_has_prefix (ref, "appstream/") ||
    g_str_has_prefix (ref, "appstream2/") ||
    g_str_has_prefix (ref, "app/") ||
    g_str_has_prefix (ref, "runtime/");
}

char *
flatpak_get_arch_for_ref (const char *ref)
{
  if (g_str_has_prefix (ref, "appstream/") ||
      g_str_has_prefix (ref, "appstream2/"))
    {
      const char *rest = strchr (ref, '/') + 1; /* Guaranteed to exist per above check */
      const char *dash = strrchr (rest, '-'); /*  Subset appstream refs are appstream2/$subset-$arch */
      if (dash != NULL)
        rest = dash + 1;
      return g_strdup (rest);
    }
    else if (g_str_has_prefix (ref, "app/") ||
      g_str_has_prefix (ref, "runtime/"))
    {
      const char *slash;
      const char *arch;

      slash = strchr (ref, '/') + 1; /* Guaranteed to exist per above check */
      slash = strchr (slash, '/'); /* Skip id */
      if (slash == NULL)
        return NULL;
      arch = slash + 1;

      slash = strchr (arch, '/'); /* skip to end arch */
      if (slash == NULL)
        return NULL;

      return g_strndup (arch, slash - arch);
    }

  return NULL;
}

===== ./common/flatpak-installed-ref-private.h =====
/*
 * Copyright © 2015 Red Hat, Inc
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Alexander Larsson <alexl@redhat.com>
 */

#if !defined(__FLATPAK_H_INSIDE__) && !defined(FLATPAK_COMPILATION)
#error "Only <flatpak.h> can be included directly."
#endif

#ifndef __FLATPAK_INSTALLED_REF_PRIVATE_H__
#define __FLATPAK_INSTALLED_REF_PRIVATE_H__

#include <flatpak-installed-ref.h>
#include <flatpak-dir-private.h>

FlatpakInstalledRef *flatpak_installed_ref_new (FlatpakDecomposed *ref,
                                                const char  *commit,
                                                const char  *latest_commit,
                                                const char  *origin,
                                                const char  *collection_id,
                                                const char **subpaths,
                                                const char  *deploy_dir,
                                                guint64      installed_size,
                                                gboolean     current,
                                                const char  *eol,
                                                const char  *eol_rebase,
                                                const char  *appdata_name,
                                                const char  *appdata_summary,
                                                const char  *appdata_version,
                                                const char  *appdata_license,
                                                const char  *appdata_content_rating_type,
                                                GHashTable  *appdata_content_rating);

#endif /* __FLATPAK_INSTALLED_REF_PRIVATE_H__ */

===== ./common/flatpak-metadata-private.h =====
/*
 * Copyright 2014 Red Hat, Inc
 * SPDX-License-Identifier: LGPL-2.1-or-later
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 */

#pragma once

#include "libglnx.h"

#include <glib.h>

G_BEGIN_DECLS

/* See flatpak-metadata(5) */

#define FLATPAK_METADATA_GROUP_APPLICATION "Application"
#define FLATPAK_METADATA_GROUP_RUNTIME "Runtime"
#define FLATPAK_METADATA_KEY_COMMAND "command"
#define FLATPAK_METADATA_KEY_NAME "name"
#define FLATPAK_METADATA_KEY_REQUIRED_FLATPAK "required-flatpak"
#define FLATPAK_METADATA_KEY_RUNTIME "runtime"
#define FLATPAK_METADATA_KEY_SDK "sdk"
#define FLATPAK_METADATA_KEY_TAGS "tags"

#define FLATPAK_METADATA_GROUP_CONTEXT "Context"
#define FLATPAK_METADATA_KEY_SHARED "shared"
#define FLATPAK_METADATA_KEY_SOCKETS "sockets"
#define FLATPAK_METADATA_KEY_FILESYSTEMS "filesystems"
#define FLATPAK_METADATA_KEY_PERSISTENT "persistent"
#define FLATPAK_METADATA_KEY_DEVICES "devices"
#define FLATPAK_METADATA_KEY_FEATURES "features"
#define FLATPAK_METADATA_KEY_UNSET_ENVIRONMENT "unset-environment"

#define FLATPAK_METADATA_GROUP_INSTANCE "Instance"
#define FLATPAK_METADATA_KEY_INSTANCE_PATH "instance-path"
#define FLATPAK_METADATA_KEY_INSTANCE_ID "instance-id"
#define FLATPAK_METADATA_KEY_ORIGINAL_APP_PATH "original-app-path"
#define FLATPAK_METADATA_KEY_APP_PATH "app-path"
#define FLATPAK_METADATA_KEY_APP_COMMIT "app-commit"
#define FLATPAK_METADATA_KEY_APP_EXTENSIONS "app-extensions"
#define FLATPAK_METADATA_KEY_ARCH "arch"
#define FLATPAK_METADATA_KEY_BRANCH "branch"
#define FLATPAK_METADATA_KEY_FLATPAK_VERSION "flatpak-version"
#define FLATPAK_METADATA_KEY_ORIGINAL_RUNTIME_PATH "original-runtime-path"
#define FLATPAK_METADATA_KEY_RUNTIME_PATH "runtime-path"
#define FLATPAK_METADATA_KEY_RUNTIME_COMMIT "runtime-commit"
#define FLATPAK_METADATA_KEY_RUNTIME_EXTENSIONS "runtime-extensions"
#define FLATPAK_METADATA_KEY_SESSION_BUS_PROXY "session-bus-proxy"
#define FLATPAK_METADATA_KEY_SYSTEM_BUS_PROXY "system-bus-proxy"
#define FLATPAK_METADATA_KEY_EXTRA_ARGS "extra-args"
#define FLATPAK_METADATA_KEY_SANDBOX "sandbox"
#define FLATPAK_METADATA_KEY_BUILD "build"
#define FLATPAK_METADATA_KEY_DEVEL "devel"

#define FLATPAK_METADATA_GROUP_SESSION_BUS_POLICY "Session Bus Policy"
#define FLATPAK_METADATA_GROUP_SYSTEM_BUS_POLICY "System Bus Policy"
#define FLATPAK_METADATA_GROUP_A11Y_BUS_POLICY "Accessibility Bus Policy"
#define FLATPAK_METADATA_GROUP_PREFIX_POLICY "Policy "
#define FLATPAK_METADATA_GROUP_ENVIRONMENT "Environment"

#define FLATPAK_METADATA_GROUP_PREFIX_EXTENSION "Extension "
#define FLATPAK_METADATA_KEY_ADD_LD_PATH "add-ld-path"
#define FLATPAK_METADATA_KEY_AUTODELETE "autodelete"
#define FLATPAK_METADATA_KEY_DIRECTORY "directory"
#define FLATPAK_METADATA_KEY_DOWNLOAD_IF "download-if"
#define FLATPAK_METADATA_KEY_ENABLE_IF "enable-if"
#define FLATPAK_METADATA_KEY_AUTOPRUNE_UNLESS "autoprune-unless"
#define FLATPAK_METADATA_KEY_MERGE_DIRS "merge-dirs"
#define FLATPAK_METADATA_KEY_NO_AUTODOWNLOAD "no-autodownload"
#define FLATPAK_METADATA_KEY_SUBDIRECTORIES "subdirectories"
#define FLATPAK_METADATA_KEY_SUBDIRECTORY_SUFFIX "subdirectory-suffix"
#define FLATPAK_METADATA_KEY_LOCALE_SUBSET "locale-subset"
#define FLATPAK_METADATA_KEY_VERSION "version"
#define FLATPAK_METADATA_KEY_VERSIONS "versions"

#define FLATPAK_METADATA_KEY_COLLECTION_ID "collection-id"

#define FLATPAK_METADATA_GROUP_EXTRA_DATA "Extra Data"
#define FLATPAK_METADATA_KEY_EXTRA_DATA_CHECKSUM "checksum"
#define FLATPAK_METADATA_KEY_EXTRA_DATA_INSTALLED_SIZE "installed-size"
#define FLATPAK_METADATA_KEY_EXTRA_DATA_NAME "name"
#define FLATPAK_METADATA_KEY_EXTRA_DATA_SIZE "size"
#define FLATPAK_METADATA_KEY_EXTRA_DATA_URI "uri"
#define FLATPAK_METADATA_KEY_NO_RUNTIME "NoRuntime"

#define FLATPAK_METADATA_GROUP_EXTENSION_OF "ExtensionOf"
#define FLATPAK_METADATA_KEY_PRIORITY "priority"
#define FLATPAK_METADATA_KEY_REF "ref"
#define FLATPAK_METADATA_KEY_TAG "tag"

#define FLATPAK_METADATA_GROUP_DCONF "X-DConf"
#define FLATPAK_METADATA_KEY_DCONF_PATHS "paths"
#define FLATPAK_METADATA_KEY_DCONF_MIGRATE_PATH "migrate-path"

#define FLATPAK_METADATA_GROUP_USB_DEVICES "USB Devices"
#define FLATPAK_METADATA_KEY_USB_ENUMERABLE_DEVICES "enumerable-devices"
#define FLATPAK_METADATA_KEY_USB_HIDDEN_DEVICES "hidden-devices"

G_END_DECLS

===== ./common/flatpak-exports.c =====
/* vi:set et sw=2 sts=2 cin cino=t0,f0,(0,{s,>2s,n-s,^-s,e-s:
 * Copyright © 2014-2019 Red Hat, Inc
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Alexander Larsson <alexl@redhat.com>
 */

#include "config.h"

#include <string.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/utsname.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <sys/vfs.h>
#include <sys/personality.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <grp.h>
#include <unistd.h>
#include <gio/gunixfdlist.h>

#include <glib/gi18n-lib.h>

#include <gio/gio.h>
#include "libglnx.h"

#include "flatpak-exports-private.h"
#include "flatpak-metadata-private.h"
#include "flatpak-utils-base-private.h"
#include "flatpak-utils-private.h"
#include "flatpak-error.h"

static const char * const abs_usrmerged_dirs[] =
{
  "/bin",
  "/lib",
  "/lib32",
  "/lib64",
  "/sbin",
  NULL
};
const char * const *flatpak_abs_usrmerged_dirs = abs_usrmerged_dirs;

/* We don't want to export paths pointing into these, because they are readonly
   (so we can't create mountpoints there) and don't match what's on the host anyway.
   flatpak_abs_usrmerged_dirs get the same treatment without having to be listed
   here. */
const char *dont_export_in[] = {
  "/.flatpak-info",
  "/app",
  "/dev",
  "/etc",
  "/proc",
  "/run/flatpak",
  "/run/host",
  "/usr",
  NULL
};

static char *
make_relative (const char *base, const char *path)
{
  GString *s = g_string_new ("");

  while (*base != 0)
    {
      while (*base == '/')
        base++;

      if (*base != 0)
        g_string_append (s, "../");

      while (*base != '/' && *base != 0)
        base++;
    }

  while (*path == '/')
    path++;

  g_string_append (s, path);

  return g_string_free (s, FALSE);
}

#define FAKE_MODE_DIR -1 /* Ensure a dir, either on tmpfs or mapped parent */
#define FAKE_MODE_TMPFS FLATPAK_FILESYSTEM_MODE_NONE
#define FAKE_MODE_SYMLINK G_MAXINT

static inline gboolean
is_export_mode (int mode)
{
  return ((mode >= FLATPAK_FILESYSTEM_MODE_NONE
           && mode <= FLATPAK_FILESYSTEM_MODE_LAST)
          || mode == FAKE_MODE_DIR
          || mode == FAKE_MODE_SYMLINK);
}

static inline const char *
export_mode_to_verb (int mode)
{
  switch (mode)
    {
      case FAKE_MODE_DIR:
        return "ensure existence of directory";

      case FAKE_MODE_SYMLINK:
        return "create symbolic link";

      default:
        break;
    }

  switch ((FlatpakFilesystemMode) mode)
    {
      case FLATPAK_FILESYSTEM_MODE_READ_ONLY:
        return "export read-only";

      case FLATPAK_FILESYSTEM_MODE_CREATE:
        return "create and export read/write";

      case FLATPAK_FILESYSTEM_MODE_READ_WRITE:
        return "export read/write";

      case FLATPAK_FILESYSTEM_MODE_NONE:
        return "replace with tmpfs";

      default:
        return "[use unknown/invalid mode?]";
    }
}

typedef struct
{
  char *path;
  gint  mode;
} ExportedPath;

struct _FlatpakExports
{
  GHashTable           *hash;
  FlatpakFilesystemMode host_etc;
  FlatpakFilesystemMode host_os;
  int                   host_fd;
  FlatpakFilesystemMode host_root;
  FlatpakExportsTestFlags test_flags;
};

/*
 * When populating /run/host, pretend @fd was the root of the host
 * filesystem.
 */
void
flatpak_exports_take_host_fd (FlatpakExports *exports,
                              int fd)
{
  glnx_close_fd (&exports->host_fd);

  if (fd >= 0)
    exports->host_fd = fd;
}

void
flatpak_exports_set_test_flags (FlatpakExports *exports,
                                FlatpakExportsTestFlags flags)
{
  exports->test_flags = flags;
}

static gboolean
flatpak_exports_stat_in_host (FlatpakExports *exports,
                              const char *abs_path,
                              struct stat *buf,
                              int flags,
                              GError **error)
{
  g_return_val_if_fail (abs_path[0] == '/', FALSE);

  if (exports->host_fd >= 0)
    {
      /* If abs_path is "/usr", then stat "usr" relative to host_fd.
       * As a special case, if abs_path is "/", stat host_fd itself,
       * due to the use of AT_EMPTY_PATH.
       *
       * This won't work if ${host_fd}/${abs_path} contains symlinks
       * that are absolute or otherwise escape from the mock root,
       * so be careful not to do that in unit tests. */
      return glnx_fstatat (exports->host_fd, &abs_path[1], buf,
                           AT_EMPTY_PATH | flags,
                           error);
    }

  return glnx_fstatat (AT_FDCWD, abs_path, buf, flags, error);
}

static gchar *
flatpak_exports_readlink_in_host (FlatpakExports *exports,
                                  const char *abs_path,
                                  GError **error)
{
  g_return_val_if_fail (abs_path[0] == '/', FALSE);

  /* Similar to flatpak_exports_stat_in_host, this assumes the mock root
   * doesn't contain symlinks that escape from the mock root. */
  if (exports->host_fd >= 0)
    return glnx_readlinkat_malloc (exports->host_fd, &abs_path[1],
                                   NULL, error);

  return glnx_readlinkat_malloc (AT_FDCWD, abs_path, NULL, error);
}

/* path must be absolute, but this is not checked because assertions
 * are not async-signal-safe. */
static int
flatpak_exports_open_in_host_async_signal_safe (FlatpakExports *exports,
                                                const char *abs_path,
                                                int flags)
{
  flags |= O_CLOEXEC;

  if (exports->host_fd >= 0)
    {
      /* Similar to flatpak_exports_stat_in_host, this assumes the mock root
       * doesn't contain symlinks that escape from the mock root. */
      return openat (exports->host_fd, &abs_path[1],
                     flags);
    }

  return openat (AT_FDCWD, abs_path, flags);
}

static int
flatpak_exports_open_in_host (FlatpakExports *exports,
                              const char *abs_path,
                              int flags)
{
  g_return_val_if_fail (abs_path[0] == '/', -1);
  return flatpak_exports_open_in_host_async_signal_safe (exports, abs_path, flags);
}

static char *
flatpak_exports_resolve_link_in_host (FlatpakExports *exports,
                                      const char *abs_path,
                                      GError **error)
{
  g_return_val_if_fail (abs_path[0] == '/', FALSE);

  if (exports->host_fd >= 0)
    {
      g_autofree char *fd_path = g_strdup_printf ("/proc/self/fd/%d/",
                                                  exports->host_fd);
      g_autofree char *real_path = g_strdup_printf ("%s%s", fd_path, &abs_path[1]);
      g_autofree char *resolved = flatpak_resolve_link (real_path, error);

      if (resolved == NULL)
        return NULL;

      if (!g_str_has_prefix (resolved, fd_path))
        return glnx_null_throw (error, "Symbolic link escapes from mock root");

      return g_strdup (resolved + strlen (fd_path) - 1);
    }

  return flatpak_resolve_link (abs_path, error);
}

static void
exported_path_free (ExportedPath *exported_path)
{
  g_free (exported_path->path);
  g_free (exported_path);
}

FlatpakExports *
flatpak_exports_new (void)
{
  FlatpakExports *exports = g_new0 (FlatpakExports, 1);

  exports->hash = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, (GFreeFunc) exported_path_free);
  exports->host_fd = -1;
  return exports;
}

void
flatpak_exports_free (FlatpakExports *exports)
{
  glnx_close_fd (&exports->host_fd);
  g_hash_table_destroy (exports->hash);
  g_free (exports);
}

/* Returns TRUE if the location of this export
   is not visible due to parents being exported */
static gboolean
path_parent_is_mapped (const char **keys,
                       guint        n_keys,
                       GHashTable  *hash_table,
                       const char  *path)
{
  guint i;
  gboolean is_mapped = FALSE;

  /* The keys are sorted so shorter (i.e. parents) are first */
  for (i = 0; i < n_keys; i++)
    {
      const char *mounted_path = keys[i];
      ExportedPath *ep = g_hash_table_lookup (hash_table, mounted_path);

      g_assert (is_export_mode (ep->mode));

      if (flatpak_has_path_prefix (path, mounted_path) &&
          (strcmp (path, mounted_path) != 0))
        {
          /* FAKE_MODE_DIR has same mapped value as parent */
          if (ep->mode == FAKE_MODE_DIR)
            continue;

          is_mapped = ep->mode != FAKE_MODE_TMPFS;
        }
    }

  return is_mapped;
}

static gboolean
path_is_mapped (const char **keys,
                guint        n_keys,
                GHashTable  *hash_table,
                const char  *path,
                gboolean    *is_readonly_out)
{
  guint i;
  gboolean is_mapped = FALSE;
  gboolean is_readonly = FALSE;

  /* The keys are sorted so shorter (i.e. parents) are first */
  for (i = 0; i < n_keys; i++)
    {
      const char *mounted_path = keys[i];
      ExportedPath *ep = g_hash_table_lookup (hash_table, mounted_path);

      g_assert (is_export_mode (ep->mode));

      if (flatpak_has_path_prefix (path, mounted_path))
        {
          /* FAKE_MODE_DIR has same mapped value as parent */
          if (ep->mode == FAKE_MODE_DIR)
            continue;

          if (ep->mode == FAKE_MODE_SYMLINK)
            is_mapped = strcmp (path, mounted_path) == 0;
          else
            is_mapped = ep->mode != FAKE_MODE_TMPFS;

          if (is_mapped)
            is_readonly = ep->mode == FLATPAK_FILESYSTEM_MODE_READ_ONLY;
          else
            is_readonly = FALSE;
        }
    }

  *is_readonly_out = is_readonly;
  return is_mapped;
}

static gint
compare_eps (const ExportedPath *a,
             const ExportedPath *b)
{
  return g_strcmp0 (a->path, b->path);
}

/* This differs from g_file_test (path, G_FILE_TEST_IS_DIR) which
   returns true if the path is a symlink to a dir */
static gboolean
path_is_dir (FlatpakExports *exports,
             const char *path)
{
  struct stat s;

  if (!flatpak_exports_stat_in_host (exports, path, &s, AT_SYMLINK_NOFOLLOW, NULL))
    return FALSE;

  return S_ISDIR (s.st_mode);
}

static gboolean
path_is_symlink (FlatpakExports *exports,
                 const char *path)
{
  struct stat s;

  if (!flatpak_exports_stat_in_host (exports, path, &s, AT_SYMLINK_NOFOLLOW, NULL))
    return FALSE;

  return S_ISLNK (s.st_mode);
}

/*
 * @name: A file or directory below /etc
 * @test: How we test whether it is suitable
 *
 * The paths in /etc that are required if we want to make use of the
 * host /usr (and /lib, and so on).
 */
typedef struct
{
  const char *name;
  int ifmt;
} LibsNeedEtc;

static const LibsNeedEtc libs_need_etc[] =
{
  /* glibc */
  { "ld.so.cache", S_IFREG },
  /* Used for executables and a few libraries on e.g. Debian */
  { "alternatives", S_IFDIR }
};

void
flatpak_exports_append_bwrap_args (FlatpakExports *exports,
                                   FlatpakBwrap   *bwrap)
{
  guint n_keys;
  g_autofree const char **keys = (const char **) g_hash_table_get_keys_as_array (exports->hash, &n_keys);
  g_autoptr(GList) eps = NULL;
  GList *l;
  struct stat buf;

  eps = g_hash_table_get_values (exports->hash);
  eps = g_list_sort (eps, (GCompareFunc) compare_eps);

  qsort (keys, n_keys, sizeof (char *), flatpak_strcmp0_ptr);

  g_debug ("Converting FlatpakExports to bwrap arguments...");

  for (l = eps; l != NULL; l = l->next)
    {
      ExportedPath *ep = l->data;
      const char *path = ep->path;

      g_assert (is_export_mode (ep->mode));

      if (ep->mode == FAKE_MODE_SYMLINK)
        {
          g_debug ("\"%s\" is meant to be a symlink", path);

          if (path_parent_is_mapped (keys, n_keys, exports->hash, path))
            {
              g_debug ("Not creating \"%s\" as symlink because its parent is "
                       "already mapped", path);
            }
          else
            {
              g_autofree char *resolved = flatpak_exports_resolve_link_in_host (exports,
                                                                                path,
                                                                                 NULL);
              if (resolved)
                {
                  g_autofree char *parent = g_path_get_dirname (path);
                  g_autofree char *relative = make_relative (parent, resolved);

                  g_debug ("Resolved \"%s\" to \"%s\" in host", path, resolved);
                  g_debug ("Creating \"%s\" -> \"%s\" in sandbox", path, relative);
                  flatpak_bwrap_add_args (bwrap, "--symlink", relative, path,  NULL);
                }
              else
                {
                  g_debug ("Unable to resolve \"%s\" in host, skipping", path);
                }
            }
        }
      else if (ep->mode == FAKE_MODE_TMPFS)
        {
          g_debug ("\"%s\" is meant to be a tmpfs or empty directory", path);

          /* Mount a tmpfs to hide the subdirectory, but only if there
             is a pre-existing dir we can mount the path on. */
          if (path_is_dir (exports, path))
            {
              if (!path_parent_is_mapped (keys, n_keys, exports->hash, path))
                /* If the parent is not mapped, it will be a tmpfs, no need to mount another one */
                {
                  g_debug ("Parent of \"%s\" is not mapped, creating empty directory", path);
                  flatpak_bwrap_add_args (bwrap, "--dir", path, NULL);
                }
              else
                {
                  g_debug ("Parent of \"%s\" is mapped, creating tmpfs to shadow it", path);
                  flatpak_bwrap_add_args (bwrap, "--tmpfs", path, NULL);
                }
            }
          else
            {
              g_debug ("Not a directory, skipping: \"%s\"", path);
            }
        }
      else if (ep->mode == FAKE_MODE_DIR)
        {
          g_debug ("\"%s\" is meant to be a directory", path);

          if (path_is_dir (exports, path))
            {
              g_debug ("Ensuring \"%s\" is created as a directory", path);
              flatpak_bwrap_add_args (bwrap, "--dir", path, NULL);
            }
          else
            {
              g_debug ("Not a directory, skipping: \"%s\"", path);
            }
        }
      else
        {
          g_debug ("\"%s\" is meant to be shared (ro or rw) with the container",
                   path);
          flatpak_bwrap_add_args (bwrap,
                                  (ep->mode == FLATPAK_FILESYSTEM_MODE_READ_ONLY) ? "--ro-bind" : "--bind",
                                  path, path, NULL);
        }
    }

  g_assert (exports->host_os >= FLATPAK_FILESYSTEM_MODE_NONE);
  g_assert (exports->host_os <= FLATPAK_FILESYSTEM_MODE_LAST);

  if (exports->host_os != FLATPAK_FILESYSTEM_MODE_NONE)
    {
      const char *os_bind_mode = "--bind";
      int i;

      if (exports->host_os == FLATPAK_FILESYSTEM_MODE_READ_ONLY)
        os_bind_mode = "--ro-bind";

      if (flatpak_exports_stat_in_host (exports, "/usr", &buf, 0, NULL) &&
          S_ISDIR (buf.st_mode))
        flatpak_bwrap_add_args (bwrap,
                                os_bind_mode, "/usr", "/run/host/usr", NULL);

      /* /usr/local points to ../var/usrlocal on ostree systems,
	 so bind-mount that too. */
      if (flatpak_exports_stat_in_host (exports, "/var/usrlocal", &buf, 0, NULL) &&
	    S_ISDIR (buf.st_mode))
        flatpak_bwrap_add_args (bwrap,
                                os_bind_mode, "/var/usrlocal", "/run/host/var/usrlocal", NULL);

      for (i = 0; flatpak_abs_usrmerged_dirs[i] != NULL; i++)
        {
          const char *subdir = flatpak_abs_usrmerged_dirs[i];
          g_autofree char *target = NULL;
          g_autofree char *run_host_subdir = NULL;

          g_assert (subdir[0] == '/');
          /* e.g. /run/host/lib32 */
          run_host_subdir = g_strconcat ("/run/host", subdir, NULL);
          target = flatpak_exports_readlink_in_host (exports, subdir, NULL);

          if (target != NULL &&
              g_str_has_prefix (target, "usr/"))
            {
              /* e.g. /lib32 is a relative symlink to usr/lib32, or
               * on Arch Linux, /lib64 is a relative symlink to usr/lib;
               * keep it relative */
              flatpak_bwrap_add_args (bwrap,
                                      "--symlink", target, run_host_subdir,
                                      NULL);
            }
          else if (target != NULL &&
                   g_str_has_prefix (target, "/usr/"))
            {
              /* e.g. /lib32 is an absolute symlink to /usr/lib32; make
               * it a relative symlink to usr/lib32 instead by skipping
               * the '/' */
              flatpak_bwrap_add_args (bwrap,
                                      "--symlink", target + 1, run_host_subdir,
                                      NULL);
            }
          else if (flatpak_exports_stat_in_host (exports, subdir, &buf, 0, NULL) &&
                   S_ISDIR (buf.st_mode))
            {
              /* e.g. /lib32 is a symlink to /opt/compat/ia32/lib,
               * or is a plain directory because the host OS has not
               * undergone the /usr merge; bind-mount the directory instead */
              flatpak_bwrap_add_args (bwrap,
                                      os_bind_mode, subdir, run_host_subdir,
                                      NULL);
            }
        }

      if (exports->host_etc == FLATPAK_FILESYSTEM_MODE_NONE)
        {
          /* We are exposing the host /usr (and friends) but not the
           * host /etc. Additionally expose just enough of /etc to make
           * things that want to read /usr work as expected.
           *
           * (If exports->host_etc is nonzero, we'll do this as part of
           * /etc instead.) */

          for (i = 0; i < G_N_ELEMENTS (libs_need_etc); i++)
            {
              const LibsNeedEtc *item = &libs_need_etc[i];
              g_autofree gchar *host_path = g_strconcat ("/etc/", item->name, NULL);

              if (flatpak_exports_stat_in_host (exports, host_path,
                                                &buf, 0, NULL) &&
                  (buf.st_mode & S_IFMT) == item->ifmt)
                {
                  g_autofree gchar *run_host_path = g_strconcat ("/run/host/etc/", item->name, NULL);

                  flatpak_bwrap_add_args (bwrap,
                                          os_bind_mode, host_path, run_host_path,
                                          NULL);
                }
            }
        }
    }

  g_assert (exports->host_etc >= FLATPAK_FILESYSTEM_MODE_NONE);
  g_assert (exports->host_etc <= FLATPAK_FILESYSTEM_MODE_LAST);

  if (exports->host_etc != FLATPAK_FILESYSTEM_MODE_NONE)
    {
      const char *etc_bind_mode = "--bind";

      if (exports->host_etc == FLATPAK_FILESYSTEM_MODE_READ_ONLY)
        etc_bind_mode = "--ro-bind";

      if (flatpak_exports_stat_in_host (exports, "/etc", &buf, 0, NULL) &&
          S_ISDIR (buf.st_mode))
        flatpak_bwrap_add_args (bwrap,
                                etc_bind_mode, "/etc", "/run/host/etc", NULL);
    }

  g_assert (exports->host_root >= FLATPAK_FILESYSTEM_MODE_NONE);
  g_assert (exports->host_root <= FLATPAK_FILESYSTEM_MODE_LAST);

  if (exports->host_root != FLATPAK_FILESYSTEM_MODE_NONE)
    {
      const char *root_bind_mode = "--bind";

      if (exports->host_root == FLATPAK_FILESYSTEM_MODE_READ_ONLY)
        root_bind_mode = "--ro-bind";

      flatpak_bwrap_add_args (bwrap,
                              root_bind_mode, "/", "/run/host/root", NULL);
    }

  /* As per the os-release specification https://www.freedesktop.org/software/systemd/man/os-release.html
   * always read-only bind-mount /etc/os-release if it exists, or /usr/lib/os-release as a fallback from
   * the host into the application's /run/host */
  if (flatpak_exports_stat_in_host (exports, "/etc/os-release", &buf, 0, NULL))
    flatpak_bwrap_add_args (bwrap, "--ro-bind", "/etc/os-release", "/run/host/os-release", NULL);
  else if (flatpak_exports_stat_in_host (exports, "/usr/lib/os-release", &buf, 0, NULL))
    flatpak_bwrap_add_args (bwrap, "--ro-bind", "/usr/lib/os-release", "/run/host/os-release", NULL);
}

/* Returns FLATPAK_FILESYSTEM_MODE_NONE if not visible */
FlatpakFilesystemMode
flatpak_exports_path_get_mode (FlatpakExports *exports,
                               const char     *path)
{
  guint n_keys;
  g_autofree const char **keys = (const char **) g_hash_table_get_keys_as_array (exports->hash, &n_keys);
  g_autofree char *canonical = NULL;
  gboolean is_readonly = FALSE;
  g_auto(GStrv) parts = NULL;
  int i;
  g_autoptr(GString) path_builder = g_string_new ("");
  struct stat st;

  qsort (keys, n_keys, sizeof (char *), flatpak_strcmp0_ptr);

  /* Syntactic canonicalization only, no need to use host_fd */
  path = canonical = flatpak_canonicalize_filename (path);

  parts = g_strsplit (path + 1, "/", -1);

  /* A path is visible in the sandbox if no parent
   * path element that is mapped in the sandbox is
   * a symlink, and the final element is mapped.
   * If any parent is a symlink we resolve that and
   * continue with that instead.
   */
  for (i = 0; parts[i] != NULL; i++)
    {
      g_string_append (path_builder, "/");
      g_string_append (path_builder, parts[i]);

      if (path_is_mapped (keys, n_keys, exports->hash, path_builder->str, &is_readonly))
        {
          g_autoptr(GError) stat_error = NULL;

          if (!flatpak_exports_stat_in_host (exports, path_builder->str, &st, AT_SYMLINK_NOFOLLOW, &stat_error))
            {
              if (g_error_matches (stat_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND) &&
                  parts[i + 1] == NULL &&
                  !is_readonly)
                {
                  /* Last element was mapped but isn't there, this is
                   * OK (used for the save case) if we the parent is
                   * mapped and writable, as the app can then create
                   * the file here.
                   */
                  break;
                }

              return FLATPAK_FILESYSTEM_MODE_NONE;
            }

          if (S_ISLNK (st.st_mode))
            {
              g_autofree char *resolved = flatpak_exports_resolve_link_in_host (exports,
                                                                                path_builder->str,
                                                                                NULL);
              g_autoptr(GString) path2_builder = NULL;
              int j;

              if (resolved == NULL)
                return FLATPAK_FILESYSTEM_MODE_NONE;

              path2_builder = g_string_new (resolved);

              for (j = i + 1; parts[j] != NULL; j++)
                {
                  g_string_append (path2_builder, "/");
                  g_string_append (path2_builder, parts[j]);
                }

              return flatpak_exports_path_get_mode (exports, path2_builder->str);
            }
        }
      else if (parts[i + 1] == NULL)
        return FLATPAK_FILESYSTEM_MODE_NONE; /* Last part was not mapped */
    }

  if (is_readonly)
    return FLATPAK_FILESYSTEM_MODE_READ_ONLY;

  return FLATPAK_FILESYSTEM_MODE_READ_WRITE;
}

gboolean
flatpak_exports_path_is_visible (FlatpakExports *exports,
                                 const char     *path)
{
  return flatpak_exports_path_get_mode (exports, path) > FLATPAK_FILESYSTEM_MODE_NONE;
}

static gboolean
never_export_as_symlink (const char *path)
{
  /* Don't export {/var,}/tmp as a symlink even if it is on the host, because
     that will fail with the pre-existing directory we created for it,
     and anyway, it being a symlink is not useful in the sandbox */
  if (strcmp (path, "/tmp") == 0 || strcmp (path, "/var/tmp") == 0)
    return TRUE;

  return FALSE;
}

static void
do_export_path (FlatpakExports *exports,
                const char     *path,
                gint            mode)
{
  ExportedPath *old_ep = g_hash_table_lookup (exports->hash, path);
  ExportedPath *ep;

  g_return_if_fail (is_export_mode (mode));

  ep = g_new0 (ExportedPath, 1);
  ep->path = g_strdup (path);

  if (old_ep != NULL)
    {
      if (old_ep->mode < mode)
        {
          g_debug ("Increasing export mode from \"%s\" to \"%s\": %s",
                   export_mode_to_verb (old_ep->mode),
                   export_mode_to_verb (mode),
                   path);
          ep->mode = mode;
        }
      else
        {
          g_debug ("Not changing export mode from \"%s\" to \"%s\": %s",
                   export_mode_to_verb (old_ep->mode),
                   export_mode_to_verb (mode),
                   path);
          ep->mode = old_ep->mode;
        }
    }
  else
    {
      g_debug ("Will %s: %s", export_mode_to_verb (mode), path);
      ep->mode = mode;
    }

  g_hash_table_replace (exports->hash, ep->path, ep);
}

/* AUTOFS mounts are tricky, as using them as a source in a bind mount
 * causes the mount to trigger, which can take a long time (or forever)
 * waiting for a device or network mount. We try to open the directory
 * but time out after a while, ignoring the mount. Unfortunately we
 * have to mess with forks and stuff to be able to handle the timeout.
 */
static gboolean
check_if_autofs_works (FlatpakExports *exports,
                       const char *path)
{
  int selfpipe[2];
  struct timeval timeout;
  pid_t pid;
  fd_set rfds;
  int res;
  int wstatus;

  g_return_val_if_fail (path[0] == '/', FALSE);

  if (pipe2 (selfpipe, O_CLOEXEC) == -1)
    return FALSE;

  fcntl (selfpipe[0], F_SETFL, fcntl (selfpipe[0], F_GETFL) | O_NONBLOCK);
  fcntl (selfpipe[1], F_SETFL, fcntl (selfpipe[1], F_GETFL) | O_NONBLOCK);

  pid = fork ();
  if (pid == -1)
    {
      close (selfpipe[0]);
      close (selfpipe[1]);
      return FALSE;
    }

  if (pid == 0)
    {
      /* Note: open, close and _exit are signal-async-safe, so it is ok to call in the child after fork */

      close (selfpipe[0]); /* Close unused read end */

      int dir_fd = flatpak_exports_open_in_host_async_signal_safe (exports,
                                                                   path,
                                                                   O_RDONLY | O_NONBLOCK | O_DIRECTORY);
      _exit (dir_fd == -1 ? 1 : 0);
    }

  /* Parent */
  close (selfpipe[1]);  /* Close unused write end */

  /* 200 msec timeout*/
  timeout.tv_sec = 0;
  timeout.tv_usec = 200 * 1000;

  FD_ZERO (&rfds);
  FD_SET (selfpipe[0], &rfds);
  res = select (selfpipe[0] + 1, &rfds, NULL, NULL, &timeout);

  close (selfpipe[0]);

  if (res == -1 /* Error */ || res == 0) /* Timeout */
    {
      /* Kill, but then waitpid to avoid zombie */
      kill (pid, SIGKILL);
    }

  if (waitpid (pid, &wstatus, 0) != pid)
    return FALSE;

  if (res == -1 /* Error */ || res == 0) /* Timeout */
    return FALSE;

  if (!WIFEXITED (wstatus) || WEXITSTATUS (wstatus) != 0)
    return FALSE;

  if (G_UNLIKELY (exports->test_flags & FLATPAK_EXPORTS_TEST_FLAGS_AUTOFS))
    {
      if (strcmp (path, "/broken-autofs") == 0)
        return FALSE;
    }

  return TRUE;
}

/* We use level to avoid infinite recursion.
 *
 * Note that some of the errors produced by this function are "real errors"
 * and should show up as a user-visible warning, but others are relatively
 * uninteresting, and in general none are actually fatal: we prefer to
 * continue with fewer paths exposed rather than failing to run. */
static gboolean
_exports_path_expose (FlatpakExports *exports,
                      int             mode,
                      const char     *path,
                      int             level,
                      GError        **error)
{
  g_autofree char *canonical = NULL;
  struct stat st;
  struct statfs stfs;
  char *slash;
  int i;
  glnx_autofd int o_path_fd = -1;

  g_return_val_if_fail (is_export_mode (mode), FALSE);

  g_debug ("Trying to %s: %s", export_mode_to_verb (mode), path);

  if (level > 40) /* 40 is the current kernel ELOOP check */
    {
      g_set_error (error, G_IO_ERROR, G_IO_ERROR_TOO_MANY_LINKS,
                   "%s", g_strerror (ELOOP));
      return FALSE;
    }

  if (!g_path_is_absolute (path))
    {
      g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_FILENAME,
                   _("An absolute path is required"));
      return FALSE;
    }

  /* Check if it exists at all */
  o_path_fd = flatpak_exports_open_in_host (exports, path, O_PATH | O_NOFOLLOW);

  if (o_path_fd == -1)
    {
      int saved_errno = errno;

      /* Intentionally using G_IO_ERROR_NOT_FOUND even if errno is
       * something different, so callers can suppress the warning in this
       * relatively likely and uninteresting case: we don't particularly
       * care whether this is happening as a result of ENOENT or EACCES
       * or any other reason. */
      g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND,
                   _("Unable to open path \"%s\": %s"),
                   path, g_strerror (saved_errno));
      return FALSE;
    }

  if (fstat (o_path_fd, &st) != 0)
    return glnx_throw (error,
                       _("Unable to get file type of \"%s\": %s"),
                       path, g_strerror (errno));

  /* Don't expose weird things */
  if (!(S_ISDIR (st.st_mode) ||
        S_ISREG (st.st_mode) ||
        S_ISLNK (st.st_mode) ||
        S_ISSOCK (st.st_mode)))
    return glnx_throw (error,
                       _("File \"%s\" has unsupported type 0o%o"),
                       path, st.st_mode & S_IFMT);

  /* O_PATH + fstatfs is the magic that we need to statfs without automounting the target */
  if (fstatfs (o_path_fd, &stfs) != 0)
    return glnx_throw (error,
                       _("Unable to get filesystem information for \"%s\": %s"),
                       path, g_strerror (errno));

  if (stfs.f_type == AUTOFS_SUPER_MAGIC ||
      (G_UNLIKELY (exports->test_flags & FLATPAK_EXPORTS_TEST_FLAGS_AUTOFS) &&
       S_ISDIR (st.st_mode)))
    {
      if (!check_if_autofs_works (exports, path))
        {
          g_set_error (error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK,
                       _("Ignoring blocking autofs path \"%s\""), path);
          return FALSE;
        }
    }

  /* Syntactic canonicalization only, no need to use host_fd */
  path = canonical = flatpak_canonicalize_filename (path);

  for (i = 0; dont_export_in[i] != NULL; i++)
    {
      /* Don't expose files in non-mounted dirs like /app or /usr, as
         they are not the same as on the host, and we generally can't
         create the parents for them anyway */
      if (flatpak_has_path_prefix (path, dont_export_in[i]))
        {
          g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_MOUNTABLE_FILE,
                       _("Path \"%s\" is reserved by Flatpak"),
                       dont_export_in[i]);
          return FALSE;
        }

      /* Also don't expose directories that are a parent of a directory
       * that is "owned" by the sandboxing framework. For example, because
       * Flatpak controls /run/host and /run/flatpak, we cannot allow
       * --filesystem=/run, which would prevent us from creating the
       * contents of /run/host and /run/flatpak. */
      if (flatpak_has_path_prefix (dont_export_in[i], path))
        {
          g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_MOUNTABLE_FILE,
                       _("Path \"%s\" is reserved by Flatpak"),
                       dont_export_in[i]);
          return FALSE;
        }
    }

  for (i = 0; flatpak_abs_usrmerged_dirs[i] != NULL; i++)
    {
      /* Same as /usr, but for the directories that get merged into /usr.
       * Keep the translatable string here the same as the one above */
      if (flatpak_has_path_prefix (path, flatpak_abs_usrmerged_dirs[i]))
        {
          g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_MOUNTABLE_FILE,
                       _("Path \"%s\" is reserved by Flatpak"),
                       flatpak_abs_usrmerged_dirs[i]);
          return FALSE;
        }
    }

  /* Handle any symlinks prior to the target itself. This includes path itself,
     because we expose the target of the symlink. */
  slash = canonical;
  do
    {
      slash = strchr (slash + 1, '/');
      if (slash)
        *slash = 0;

      if (!path_is_symlink (exports, path))
        {
          g_debug ("%s is not a symlink", path);
        }
      else if (never_export_as_symlink (path))
        {
          g_debug ("%s is a symlink, but we avoid exporting it as such", path);
        }
      else
        {
          g_autoptr(GError) local_error = NULL;
          g_autofree char *resolved = flatpak_exports_resolve_link_in_host (exports, path, &local_error);
          g_autofree char *new_target = NULL;

          if (resolved)
            {
              g_debug ("%s is a symlink, resolved to %s", path, resolved);

              if (slash)
                new_target = g_build_filename (resolved, slash + 1, NULL);
              else
                new_target = g_strdup (resolved);

              g_debug ("Trying to export the target instead: %s", new_target);

              if (_exports_path_expose (exports, mode, new_target, level + 1, &local_error))
                {
                  do_export_path (exports, path, FAKE_MODE_SYMLINK);
                  return TRUE;
                }

              g_debug ("Could not export target %s, so ignoring %s",
                       new_target, path);
              g_propagate_error (error, g_steal_pointer (&local_error));
              return FALSE;
            }
          else
            {
              g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND,
                           _("Unable to resolve symbolic link \"%s\": %s"),
                           path, local_error->message);
              return FALSE;
            }
        }

      if (slash)
        *slash = '/';
    }
  while (slash != NULL);

  do_export_path (exports, path, mode);
  return TRUE;
}

gboolean
flatpak_exports_add_path_expose (FlatpakExports         *exports,
                                 FlatpakFilesystemMode   mode,
                                 const char             *path,
                                 GError                **error)
{
  g_return_val_if_fail (mode > FLATPAK_FILESYSTEM_MODE_NONE, FALSE);
  g_return_val_if_fail (mode <= FLATPAK_FILESYSTEM_MODE_LAST, FALSE);
  return _exports_path_expose (exports, mode, path, 0, error);
}

gboolean
flatpak_exports_add_path_tmpfs (FlatpakExports  *exports,
                                const char      *path,
                                GError         **error)
{
  return _exports_path_expose (exports, FAKE_MODE_TMPFS, path, 0, error);
}

gboolean
flatpak_exports_add_path_expose_or_hide (FlatpakExports        *exports,
                                         FlatpakFilesystemMode  mode,
                                         const char            *path,
                                         GError               **error)
{
  g_return_val_if_fail (mode >= FLATPAK_FILESYSTEM_MODE_NONE, FALSE);
  g_return_val_if_fail (mode <= FLATPAK_FILESYSTEM_MODE_LAST, FALSE);

  if (mode == FLATPAK_FILESYSTEM_MODE_NONE)
    return flatpak_exports_add_path_tmpfs (exports, path, error);
  else
    return flatpak_exports_add_path_expose (exports, mode, path, error);
}

gboolean
flatpak_exports_add_path_dir (FlatpakExports  *exports,
                              const char      *path,
                              GError         **error)
{
  return _exports_path_expose (exports, FAKE_MODE_DIR, path, 0, error);
}

void
flatpak_exports_add_host_etc_expose (FlatpakExports       *exports,
                                     FlatpakFilesystemMode mode)
{
  g_return_if_fail (mode > FLATPAK_FILESYSTEM_MODE_NONE);
  g_return_if_fail (mode <= FLATPAK_FILESYSTEM_MODE_LAST);

  exports->host_etc = mode;
}

void
flatpak_exports_add_host_os_expose (FlatpakExports       *exports,
                                    FlatpakFilesystemMode mode)
{
  g_return_if_fail (mode > FLATPAK_FILESYSTEM_MODE_NONE);
  g_return_if_fail (mode <= FLATPAK_FILESYSTEM_MODE_LAST);

  exports->host_os = mode;
}

void
flatpak_exports_add_host_root_expose (FlatpakExports       *exports,
                                      FlatpakFilesystemMode mode)
{
  g_return_if_fail (mode > FLATPAK_FILESYSTEM_MODE_NONE);
  g_return_if_fail (mode <= FLATPAK_FILESYSTEM_MODE_LAST);

  exports->host_root = mode;
}

===== ./common/flatpak-run-pulseaudio.c =====
/* vi:set et sw=2 sts=2 cin cino=t0,f0,(0,{s,>2s,n-s,^-s,e-s:
 * Copyright © 2014-2019 Red Hat, Inc
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Alexander Larsson <alexl@redhat.com>
 */

#include "config.h"
#include "flatpak-run-pulseaudio-private.h"

#include "flatpak-utils-private.h"

/* Try to find a default server from a pulseaudio configuration file */
static char *
flatpak_run_get_pulseaudio_server_user_config (const char *path)
{
  g_autoptr(GFile) file = g_file_new_for_path (path);
  g_autoptr(GError) my_error = NULL;
  g_autoptr(GFileInputStream) input_stream = NULL;
  g_autoptr(GDataInputStream) data_stream = NULL;
  size_t len;

  input_stream = g_file_read (file, NULL, &my_error);
  if (my_error)
    {
      g_info ("Pulseaudio user configuration file '%s': %s", path, my_error->message);
      return NULL;
    }

  data_stream = g_data_input_stream_new (G_INPUT_STREAM (input_stream));

  while (TRUE)
    {
      g_autofree char *line = g_data_input_stream_read_line (data_stream, &len, NULL, NULL);
      if (line == NULL)
        break;

      g_strchug (line);

      if ((*line  == '\0') || (*line == ';') || (*line == '#'))
        continue;

      if (g_str_has_prefix (line, ".include "))
        {
          g_autofree char *rec_path = g_strdup (line + 9);
          g_strstrip (rec_path);
          char *found = flatpak_run_get_pulseaudio_server_user_config (rec_path);
          if (found)
            return found;
        }
      else if (g_str_has_prefix (line, "["))
        {
          return NULL;
        }
      else
        {
          g_auto(GStrv) tokens = g_strsplit (line, "=", 2);

          if ((tokens[0] != NULL) && (tokens[1] != NULL))
            {
              g_strchomp (tokens[0]);
              if (strcmp ("default-server", tokens[0]) == 0)
                {
                  g_strstrip (tokens[1]);
                  g_info ("Found pulseaudio socket from configuration file '%s': %s", path, tokens[1]);
                  return g_strdup (tokens[1]);
                }
            }
        }
    }

  return NULL;
}

static char *
flatpak_run_get_pulseaudio_server (void)
{
  const char * pulse_clientconfig;
  char *pulse_server;
  g_autofree char *pulse_user_config = NULL;

  pulse_server = g_strdup (g_getenv ("PULSE_SERVER"));
  if (pulse_server)
    return pulse_server;

  pulse_clientconfig = g_getenv ("PULSE_CLIENTCONFIG");
  if (pulse_clientconfig)
    return flatpak_run_get_pulseaudio_server_user_config (pulse_clientconfig);

  pulse_user_config = g_build_filename (g_get_user_config_dir (), "pulse/client.conf", NULL);
  pulse_server = flatpak_run_get_pulseaudio_server_user_config (pulse_user_config);
  if (pulse_server)
    return pulse_server;

  pulse_server = flatpak_run_get_pulseaudio_server_user_config ("/etc/pulse/client.conf");
  if (pulse_server)
    return pulse_server;

  return NULL;
}

/*
 * Parse a PulseAudio server string, as documented on
 * https://www.freedesktop.org/wiki/Software/PulseAudio/Documentation/User/ServerStrings/.
 * Returns the first supported server address, or NULL if none are supported,
 * or NULL with @remote set if @value points to a remote server.
 */
static char *
flatpak_run_parse_pulse_server (const char *value,
                                gboolean   *remote)
{
  g_auto(GStrv) servers = g_strsplit (value, " ", 0);
  gsize i;

  for (i = 0; servers[i] != NULL; i++)
    {
      const char *server = servers[i];
      if (g_str_has_prefix (server, "{"))
        {
          /*
           * TODO: compare the value within {} to the local hostname and D-Bus machine ID,
           * and skip if it matches neither.
           */
          const char * closing = strstr (server, "}");
          if (closing == NULL)
            continue;
          server = closing + 1;
        }

      if (g_str_has_prefix (server, "unix:"))
        return g_strdup (server + 5);
      if (server[0] == '/')
        return g_strdup (server);

      if (g_str_has_prefix (server, "tcp:"))
        {
          *remote = TRUE;
          return NULL;
        }
    }

  return NULL;
}

/*
 * Get the machine ID as used by PulseAudio. This is the systemd/D-Bus
 * machine ID, or failing that, the hostname.
 */
static char *
flatpak_run_get_pulse_machine_id (void)
{
  static const char * const machine_ids[] =
  {
    "/etc/machine-id",
    "/var/lib/dbus/machine-id",
  };
  gsize i;

  for (i = 0; i < G_N_ELEMENTS (machine_ids); i++)
    {
      g_autofree char *ret = NULL;

      if (g_file_get_contents (machine_ids[i], &ret, NULL, NULL))
        {
          gsize j;

          g_strstrip (ret);

          for (j = 0; ret[j] != '\0'; j++)
            {
              if (!g_ascii_isxdigit (ret[j]))
                break;
            }

          if (ret[0] != '\0' && ret[j] == '\0')
            return g_steal_pointer (&ret);
        }
    }

  return g_strdup (g_get_host_name ());
}

/*
 * Get the directory used by PulseAudio for its configuration.
 */
static char *
flatpak_run_get_pulse_home (void)
{
  /* Legacy path ~/.pulse is tried first, for compatibility */
  {
    const char *parent = g_get_home_dir ();
    g_autofree char *ret = g_build_filename (parent, ".pulse", NULL);

    if (g_file_test (ret, G_FILE_TEST_IS_DIR))
      return g_steal_pointer (&ret);
  }

  /* The more modern path, usually ~/.config/pulse */
  {
    const char *parent = g_get_user_config_dir ();
    /* Usually ~/.config/pulse */
    g_autofree char *ret = g_build_filename (parent, "pulse", NULL);

    if (g_file_test (ret, G_FILE_TEST_IS_DIR))
      return g_steal_pointer (&ret);
  }

  return NULL;
}

/*
 * Get the runtime directory used by PulseAudio for its socket.
 */
static char *
flatpak_run_get_pulse_runtime_dir (void)
{
  const char *val = NULL;

  val = g_getenv ("PULSE_RUNTIME_PATH");

  if (val != NULL)
    return realpath (val, NULL);

  {
    const char *user_runtime_dir = g_get_user_runtime_dir ();

    if (user_runtime_dir != NULL)
      {
        g_autofree char *dir = g_build_filename (user_runtime_dir, "pulse", NULL);

        if (g_file_test (dir, G_FILE_TEST_IS_DIR))
          return realpath (dir, NULL);
      }
  }

  {
    g_autofree char *pulse_home = flatpak_run_get_pulse_home ();
    g_autofree char *machine_id = flatpak_run_get_pulse_machine_id ();

    if (pulse_home != NULL && machine_id != NULL)
      {
        /* This is usually a symlink, but we take its realpath() anyway */
        g_autofree char *dir = g_strdup_printf ("%s/%s-runtime", pulse_home, machine_id);

        if (g_file_test (dir, G_FILE_TEST_IS_DIR))
          return realpath (dir, NULL);
      }
  }

  return NULL;
}

void
flatpak_run_add_pulseaudio_args (FlatpakBwrap         *bwrap,
                                 FlatpakContextShares  shares)
{
  g_autofree char *pulseaudio_server = flatpak_run_get_pulseaudio_server ();
  g_autofree char *pulseaudio_socket = NULL;
  g_autofree char *pulse_runtime_dir = flatpak_run_get_pulse_runtime_dir ();
  gboolean remote = FALSE;

  if (pulseaudio_server)
    pulseaudio_socket = flatpak_run_parse_pulse_server (pulseaudio_server,
                                                        &remote);

  if (pulseaudio_socket == NULL && !remote)
    {
      pulseaudio_socket = g_build_filename (pulse_runtime_dir, "native", NULL);

      if (!g_file_test (pulseaudio_socket, G_FILE_TEST_EXISTS))
        g_clear_pointer (&pulseaudio_socket, g_free);
    }

  if (pulseaudio_socket == NULL && !remote)
    {
      pulseaudio_socket = realpath ("/var/run/pulse/native", NULL);

      if (pulseaudio_socket && !g_file_test (pulseaudio_socket, G_FILE_TEST_EXISTS))
        g_clear_pointer (&pulseaudio_socket, g_free);
    }

  flatpak_bwrap_unset_env (bwrap, "PULSE_SERVER");

  if (remote)
    {
      if ((shares & FLATPAK_CONTEXT_SHARED_NETWORK) == 0)
        {
          g_warning ("Remote PulseAudio server configured.");
          g_warning ("PulseAudio access will require --share=network permission.");
        }

      g_info ("Using remote PulseAudio server \"%s\"", pulseaudio_server);
      flatpak_bwrap_set_env (bwrap, "PULSE_SERVER", pulseaudio_server, TRUE);
    }
  else if (pulseaudio_socket && g_file_test (pulseaudio_socket, G_FILE_TEST_EXISTS))
    {
      static const char sandbox_socket_path[] = "/run/flatpak/pulse/native";
      static const char pulse_server[] = "unix:/run/flatpak/pulse/native";
      static const char config_path[] = "/run/flatpak/pulse/config";
      gboolean share_shm = FALSE; /* TODO: When do we add this? */
      g_autofree char *client_config = g_strdup_printf ("enable-shm=%s\n", share_shm ? "yes" : "no");

      /* FIXME - error handling */
      if (!flatpak_bwrap_add_args_data (bwrap, "pulseaudio", client_config, -1, config_path, NULL))
        return;

      flatpak_bwrap_add_args (bwrap,
                              "--ro-bind", pulseaudio_socket, sandbox_socket_path,
                              NULL);

      flatpak_bwrap_set_env (bwrap, "PULSE_SERVER", pulse_server, TRUE);
      flatpak_bwrap_set_env (bwrap, "PULSE_CLIENTCONFIG", config_path, TRUE);
      flatpak_bwrap_add_runtime_dir_member (bwrap, "pulse");
    }
  else
    g_info ("Could not find pulseaudio socket");

  /* Also allow ALSA access. This was added in 1.8, and is not ideally named. However,
   * since the practical permission of ALSA and PulseAudio are essentially the same, and
   * since we don't want to add more permissions for something we plan to replace with
   * portals/pipewire going forward we reinterpret pulseaudio to also mean ALSA.
   */
  if (!remote && g_file_test ("/dev/snd", G_FILE_TEST_IS_DIR))
    flatpak_bwrap_add_args (bwrap, "--dev-bind", "/dev/snd", "/dev/snd", NULL);
}

===== ./common/flatpak-run-x11-private.h =====
/*
 * Copyright © 2014 Red Hat, Inc
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Alexander Larsson <alexl@redhat.com>
 */

#pragma once

#include "libglnx.h"

#include "flatpak-bwrap-private.h"
#include "flatpak-common-types-private.h"
#include "flatpak-context-private.h"

G_BEGIN_DECLS

void flatpak_run_add_x11_args (FlatpakBwrap         *bwrap,
                               gboolean              allowed,
                               FlatpakContextShares  shares);

gboolean flatpak_run_parse_x11_display (const char  *display,
                                        int         *family,
                                        char       **x11_socket,
                                        char       **remote_host,
                                        char       **original_display_nr,
                                        GError     **error);

G_END_DECLS

===== ./common/flatpak-exports-private.h =====
/*
 * Copyright © 2014-2018 Red Hat, Inc
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Alexander Larsson <alexl@redhat.com>
 */

#ifndef __FLATPAK_EXPORTS_H__
#define __FLATPAK_EXPORTS_H__

#include "libglnx.h"
#include "flatpak-bwrap-private.h"

/* In numerical order of more privs */
typedef enum {
  FLATPAK_FILESYSTEM_MODE_NONE         = 0,
  FLATPAK_FILESYSTEM_MODE_READ_ONLY    = 1,
  FLATPAK_FILESYSTEM_MODE_READ_WRITE   = 2,
  FLATPAK_FILESYSTEM_MODE_CREATE       = 3,
  FLATPAK_FILESYSTEM_MODE_LAST         = FLATPAK_FILESYSTEM_MODE_CREATE
} FlatpakFilesystemMode;

typedef struct _FlatpakExports FlatpakExports;

void flatpak_exports_free (FlatpakExports *exports);
FlatpakExports *flatpak_exports_new (void);
void flatpak_exports_append_bwrap_args (FlatpakExports *exports,
                                        FlatpakBwrap   *bwrap);
void flatpak_exports_add_host_etc_expose (FlatpakExports       *exports,
                                          FlatpakFilesystemMode mode);
void flatpak_exports_add_host_os_expose (FlatpakExports       *exports,
                                         FlatpakFilesystemMode mode);
void flatpak_exports_add_host_root_expose (FlatpakExports       *exports,
                                           FlatpakFilesystemMode mode);
gboolean flatpak_exports_add_path_expose (FlatpakExports         *exports,
                                          FlatpakFilesystemMode   mode,
                                          const char             *path,
                                          GError                **error);
gboolean flatpak_exports_add_path_tmpfs (FlatpakExports  *exports,
                                         const char      *path,
                                         GError         **error);
gboolean flatpak_exports_add_path_expose_or_hide (FlatpakExports         *exports,
                                                  FlatpakFilesystemMode   mode,
                                                  const char             *path,
                                                  GError                **error);
gboolean flatpak_exports_add_path_dir (FlatpakExports  *exports,
                                       const char      *path,
                                       GError         **error);

gboolean flatpak_exports_path_is_visible (FlatpakExports *exports,
                                          const char     *path);
FlatpakFilesystemMode flatpak_exports_path_get_mode (FlatpakExports *exports,
                                                     const char     *path);

G_DEFINE_AUTOPTR_CLEANUP_FUNC (FlatpakExports, flatpak_exports_free);

/*
 * FlatpakExportsTestFlags:
 * @FLATPAK_EXPORTS_TEST_FLAGS_AUTOFS: Pretend everything is an autofs.
 *
 * Flags used to provide mock behaviour during unit testing.
 */
typedef enum
{
  FLATPAK_EXPORTS_TEST_FLAGS_AUTOFS = (1 << 0),
  FLATPAK_EXPORTS_TEST_FLAGS_NONE = 0
} FlatpakExportsTestFlags;

void flatpak_exports_take_host_fd (FlatpakExports *exports,
                                   int             fd);
void flatpak_exports_set_test_flags (FlatpakExports *exports,
                                     FlatpakExportsTestFlags flags);

extern const char * const *flatpak_abs_usrmerged_dirs;

#endif /* __FLATPAK_EXPORTS_H__ */

===== ./common/flatpak-run-sockets.c =====
/* vi:set et sw=2 sts=2 cin cino=t0,f0,(0,{s,>2s,n-s,^-s,e-s:
 * Copyright © 2014-2019 Red Hat, Inc
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Alexander Larsson <alexl@redhat.com>
 */

#include "config.h"
#include "flatpak-run-sockets-private.h"

/* Setup for simple sockets that only need one function goes in this file.
 * Setup for more complicated sockets should go in its own file. */

#include "flatpak-run-cups-private.h"
#include "flatpak-run-pulseaudio-private.h"
#include "flatpak-run-wayland-private.h"
#include "flatpak-run-x11-private.h"
#include "flatpak-utils-private.h"

static void
flatpak_run_add_gssproxy_args (FlatpakBwrap *bwrap)
{
  /* We only expose the gssproxy user service. The gssproxy system service is
   * not intended to be exposed to sandboxed environments.
   */
  g_autofree char *gssproxy_host_dir = g_build_filename (g_get_user_runtime_dir (), "gssproxy", NULL);
  const char *gssproxy_sandboxed_dir = "/run/flatpak/gssproxy/";

  if (g_file_test (gssproxy_host_dir, G_FILE_TEST_EXISTS))
    flatpak_bwrap_add_args (bwrap, "--ro-bind", gssproxy_host_dir, gssproxy_sandboxed_dir, NULL);
}

static void
flatpak_run_add_resolved_args (FlatpakBwrap *bwrap)
{
  const char *resolved_socket = "/run/systemd/resolve/io.systemd.Resolve";

  if (g_file_test (resolved_socket, G_FILE_TEST_EXISTS))
    flatpak_bwrap_add_args (bwrap, "--bind", resolved_socket, resolved_socket, NULL);
}

static void
flatpak_run_add_journal_args (FlatpakBwrap *bwrap)
{
  g_autofree char *journal_socket_socket = g_strdup ("/run/systemd/journal/socket");
  g_autofree char *journal_stdout_socket = g_strdup ("/run/systemd/journal/stdout");

  if (g_file_test (journal_socket_socket, G_FILE_TEST_EXISTS))
    {
      flatpak_bwrap_add_args (bwrap,
                              "--ro-bind", journal_socket_socket, journal_socket_socket,
                              NULL);
    }
  if (g_file_test (journal_stdout_socket, G_FILE_TEST_EXISTS))
    {
      flatpak_bwrap_add_args (bwrap,
                              "--ro-bind", journal_stdout_socket, journal_stdout_socket,
                              NULL);
    }
}

static void
flatpak_run_add_pcsc_args (FlatpakBwrap *bwrap)
{
  const char * pcsc_socket;
  const char * sandbox_pcsc_socket = "/run/pcscd/pcscd.comm";

  pcsc_socket = g_getenv ("PCSCLITE_CSOCK_NAME");
  if (pcsc_socket)
    {
      if (!g_file_test (pcsc_socket, G_FILE_TEST_EXISTS))
        {
          flatpak_bwrap_unset_env (bwrap, "PCSCLITE_CSOCK_NAME");
          return;
        }
    }
  else
    {
      pcsc_socket = "/run/pcscd/pcscd.comm";
      if (!g_file_test (pcsc_socket, G_FILE_TEST_EXISTS))
        return;
    }

  flatpak_bwrap_add_args (bwrap,
                          "--ro-bind", pcsc_socket, sandbox_pcsc_socket,
                          NULL);
  flatpak_bwrap_set_env (bwrap, "PCSCLITE_CSOCK_NAME", sandbox_pcsc_socket, TRUE);
}

static void
flatpak_run_add_gpg_agent_args (FlatpakBwrap *bwrap)
{
  const char * agent_socket;
  g_autofree char * sandbox_agent_socket = NULL;
  g_autoptr(GError) gpgconf_error = NULL;
  g_autoptr(GSubprocess) process = NULL;
  GInputStream *base_stream = NULL;
  g_autoptr(GDataInputStream) data_stream = NULL;

  process = g_subprocess_new (G_SUBPROCESS_FLAGS_STDOUT_PIPE,
                    &gpgconf_error,
                    "gpgconf", "--list-dir", "agent-socket", NULL);

  if (gpgconf_error)
    {
      g_info ("GPG-Agent directories: %s", gpgconf_error->message);
      return;
    }

  base_stream = g_subprocess_get_stdout_pipe (process);
  data_stream = g_data_input_stream_new (base_stream);

  agent_socket = g_data_input_stream_read_line (data_stream,
                                                NULL, NULL,
                                                &gpgconf_error);

  if (!agent_socket || gpgconf_error)
    {
      g_info ("GPG-Agent directories: %s", gpgconf_error->message);
      return;
    }

  sandbox_agent_socket = g_strdup_printf ("/run/user/%d/gnupg/S.gpg-agent", getuid ());

  flatpak_bwrap_add_args (bwrap,
                          "--ro-bind-try", agent_socket, sandbox_agent_socket,
                          NULL);
}

static void
flatpak_run_add_ssh_args (FlatpakBwrap *bwrap)
{
  static const char sandbox_auth_socket[] = "/run/flatpak/ssh-auth";
  const char * auth_socket;

  auth_socket = g_getenv ("SSH_AUTH_SOCK");

  if (!auth_socket)
    return; /* ssh agent not present */

  if (!g_file_test (auth_socket, G_FILE_TEST_EXISTS))
    {
      /* Let's clean it up, so that the application will not try to connect */
      flatpak_bwrap_unset_env (bwrap, "SSH_AUTH_SOCK");
      return;
    }

  flatpak_bwrap_add_args (bwrap,
                          "--ro-bind", auth_socket, sandbox_auth_socket,
                          NULL);
  flatpak_bwrap_set_env (bwrap, "SSH_AUTH_SOCK", sandbox_auth_socket, TRUE);
}

/*
 * Expose sockets that are available for `flatpak build`, apply_extra, and
 * `flatpak run`, except for D-Bus which is handled separately due to its
 * use of a proxy.
 */
void
flatpak_run_add_socket_args_environment (FlatpakBwrap         *bwrap,
                                         FlatpakContextShares  shares,
                                         FlatpakContextSockets sockets,
                                         const char           *app_id,
                                         const char           *instance_id)
{
  gboolean allow_wayland;
  gboolean inherit_wayland_socket;
  gboolean allow_x11;

  allow_wayland = (sockets & FLATPAK_CONTEXT_SOCKET_WAYLAND) != 0;
  inherit_wayland_socket = (sockets & FLATPAK_CONTEXT_SOCKET_INHERIT_WAYLAND_SOCKET) != 0;
  flatpak_run_add_wayland_args (bwrap,
                                app_id, instance_id,
                                allow_wayland,
                                inherit_wayland_socket);

  allow_x11 = (sockets & FLATPAK_CONTEXT_SOCKET_X11) != 0;
  flatpak_run_add_x11_args (bwrap, allow_x11, shares);

  if (sockets & FLATPAK_CONTEXT_SOCKET_SSH_AUTH)
    {
      flatpak_run_add_ssh_args (bwrap);
    }

  if (sockets & FLATPAK_CONTEXT_SOCKET_PULSEAUDIO)
    {
      g_info ("Allowing pulseaudio access");
      flatpak_run_add_pulseaudio_args (bwrap, shares);
    }

  if (sockets & FLATPAK_CONTEXT_SOCKET_PCSC)
    {
      flatpak_run_add_pcsc_args (bwrap);
    }

  if (sockets & FLATPAK_CONTEXT_SOCKET_CUPS)
    {
      flatpak_run_add_cups_args (bwrap);
    }

  if (sockets & FLATPAK_CONTEXT_SOCKET_GPG_AGENT)
    {
      flatpak_run_add_gpg_agent_args (bwrap);
    }
}

/*
 * Expose sockets that are available for `flatpak run` only.
 */
void
flatpak_run_add_socket_args_late (FlatpakBwrap *bwrap,
                                  FlatpakContextShares shares)
{
  if ((shares & FLATPAK_CONTEXT_SHARED_NETWORK) != 0)
    {
      flatpak_run_add_gssproxy_args (bwrap);
      flatpak_run_add_resolved_args (bwrap);
    }

  flatpak_run_add_journal_args (bwrap);
}

===== ./common/flatpak-run-dbus.c =====
/* vi:set et sw=2 sts=2 cin cino=t0,f0,(0,{s,>2s,n-s,^-s,e-s:
 * Copyright © 2014-2019 Red Hat, Inc
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Alexander Larsson <alexl@redhat.com>
 */

#include "config.h"
#include "flatpak-run-dbus-private.h"

#include <glib/gi18n-lib.h>

#include <sys/vfs.h>

#include "flatpak-utils-private.h"

/* This wraps the argv in a bwrap call, primary to allow the
   command to be run with a proper /.flatpak-info with data
   taken from app_info_path */
static gboolean
add_bwrap_wrapper (FlatpakBwrap *bwrap,
                   const char   *app_info_path,
                   GError      **error)
{
  glnx_autofd int app_info_fd = -1;
  g_auto(GLnxDirFdIterator) dir_iter = { 0 };
  struct dirent *dent;
  g_autofree char *user_runtime_dir = flatpak_get_real_xdg_runtime_dir ();
  g_autofree char *proxy_socket_dir = g_build_filename (user_runtime_dir, ".dbus-proxy/", NULL);

  app_info_fd = open (app_info_path, O_RDONLY | O_CLOEXEC);
  if (app_info_fd == -1)
    return glnx_throw_errno_prefix (error, _("Failed to open app info file"));

  if (!glnx_dirfd_iterator_init_at (AT_FDCWD, "/", FALSE, &dir_iter, error))
    return FALSE;

  flatpak_bwrap_add_arg (bwrap, flatpak_get_bwrap ());

  while (TRUE)
    {
      glnx_autofd int o_path_fd = -1;
      struct statfs stfs;

      if (!glnx_dirfd_iterator_next_dent_ensure_dtype (&dir_iter, &dent, NULL, error))
        return FALSE;

      if (dent == NULL)
        break;

      if (strcmp (dent->d_name, ".flatpak-info") == 0)
        continue;

      /* O_PATH + fstatfs is the magic that we need to statfs without automounting the target */
      o_path_fd = openat (dir_iter.fd, dent->d_name, O_PATH | O_NOFOLLOW | O_CLOEXEC);
      if (o_path_fd == -1 || fstatfs (o_path_fd, &stfs) != 0 || stfs.f_type == AUTOFS_SUPER_MAGIC)
        continue; /* AUTOFS mounts are risky and can cause us to block (see issue #1633), so ignore it. Its unlikely the proxy needs such a directory. */

      if (dent->d_type == DT_DIR)
        {
          if (strcmp (dent->d_name, "tmp") == 0 ||
              strcmp (dent->d_name, "var") == 0 ||
              strcmp (dent->d_name, "run") == 0)
            flatpak_bwrap_add_arg (bwrap, "--bind");
          else
            flatpak_bwrap_add_arg (bwrap, "--ro-bind");

          flatpak_bwrap_add_arg_printf (bwrap, "/%s", dent->d_name);
          flatpak_bwrap_add_arg_printf (bwrap, "/%s", dent->d_name);
        }
      else if (dent->d_type == DT_LNK)
        {
          g_autofree gchar *target = NULL;

          target = glnx_readlinkat_malloc (dir_iter.fd, dent->d_name,
                                           NULL, error);
          if (target == NULL)
            return FALSE;
          flatpak_bwrap_add_args (bwrap, "--symlink", target, NULL);
          flatpak_bwrap_add_arg_printf (bwrap, "/%s", dent->d_name);
        }
    }

  flatpak_bwrap_add_args (bwrap, "--bind", proxy_socket_dir, proxy_socket_dir, NULL);

  /* This is a file rather than a bind mount, because it will then
     not be unmounted from the namespace when the namespace dies. */
  flatpak_bwrap_add_args (bwrap, "--perms", "0600", NULL);
  flatpak_bwrap_add_args_data_fd (bwrap, "--file", g_steal_fd (&app_info_fd), "/.flatpak-info");

  if (!flatpak_bwrap_bundle_args (bwrap, 1, -1, FALSE, error))
    return FALSE;

  /* End of options: the next argument will be the executable name */
  flatpak_bwrap_add_arg (bwrap, "--");

  return TRUE;
}

gboolean
flatpak_run_maybe_start_dbus_proxy (FlatpakBwrap *app_bwrap,
                                    FlatpakBwrap *proxy_arg_bwrap,
                                    const char   *app_info_path,
                                    GError      **error)
{
  char x = 'x';
  const char *proxy;
  g_autofree char *commandline = NULL;
  g_autoptr(FlatpakBwrap) proxy_bwrap = NULL;
  int proxy_start_index;
  int sync_fd;

  if (flatpak_bwrap_is_empty (proxy_arg_bwrap))
    {
      g_debug ("D-Bus proxy not needed");
      return TRUE;
    }

  proxy_bwrap = flatpak_bwrap_new (NULL);

  if (!add_bwrap_wrapper (proxy_bwrap, app_info_path, error))
    return FALSE;

  proxy = g_getenv ("FLATPAK_DBUSPROXY");
  if (proxy == NULL)
    proxy = DBUSPROXY;

  flatpak_bwrap_add_arg (proxy_bwrap, proxy);

  proxy_start_index = proxy_bwrap->argv->len;

  sync_fd = flatpak_bwrap_add_sync_fd (app_bwrap);
  if (sync_fd < 0)
    {
      g_set_error_literal (error, G_IO_ERROR, g_io_error_from_errno (errno),
                           _("Unable to create sync pipe"));
      return FALSE;
    }

  flatpak_bwrap_add_fd (proxy_bwrap, sync_fd);
  flatpak_bwrap_add_arg_printf (proxy_bwrap, "--fd=%d", sync_fd);

  /* Note: This steals the fds from proxy_arg_bwrap */
  flatpak_bwrap_append_bwrap (proxy_bwrap, proxy_arg_bwrap);

  if (!flatpak_bwrap_bundle_args (proxy_bwrap, proxy_start_index, -1, TRUE, error))
    return FALSE;

  flatpak_bwrap_finish (proxy_bwrap);

  commandline = flatpak_quote_argv ((const char **) proxy_bwrap->argv->pdata, -1);
  g_info ("Running '%s'", commandline);

  /* We use LEAVE_DESCRIPTORS_OPEN and close them in the child_setup
   * to work around a deadlock in GLib < 2.60 */
  if (!g_spawn_async (NULL,
                      (char **) proxy_bwrap->argv->pdata,
                      NULL,
                      G_SPAWN_SEARCH_PATH | G_SPAWN_LEAVE_DESCRIPTORS_OPEN,
                      flatpak_bwrap_child_setup_cb, proxy_bwrap->fds,
                      NULL, error))
    return FALSE;

  /* The write end can be closed now, otherwise the read below will hang of xdg-dbus-proxy
     fails to start. */
  g_clear_pointer (&proxy_bwrap, flatpak_bwrap_free);

  /* Sync with proxy, i.e. wait until its listening on the sockets */
  if (read (app_bwrap->sync_fds[0], &x, 1) != 1)
    {
      g_set_error_literal (error, G_IO_ERROR, g_io_error_from_errno (errno),
                           _("Failed to sync with dbus proxy"));
      return FALSE;
    }

  return TRUE;
}

static char *
extract_unix_path_from_dbus_address (const char *address)
{
  const char *path, *path_end;

  if (address == NULL)
    return NULL;

  if (!g_str_has_prefix (address, "unix:"))
    return NULL;

  path = strstr (address, "path=");
  if (path == NULL)
    return NULL;
  path += strlen ("path=");
  path_end = path;
  while (*path_end != 0 && *path_end != ',')
    path_end++;

  return g_strndup (path, path_end - path);
}

static char *
create_proxy_socket (const char *template)
{
  g_autofree char *user_runtime_dir = flatpak_get_real_xdg_runtime_dir ();
  g_autofree char *proxy_socket_dir = g_build_filename (user_runtime_dir, ".dbus-proxy", NULL);
  g_autofree char *proxy_socket = g_build_filename (proxy_socket_dir, template, NULL);
  int fd;

  if (!glnx_shutil_mkdir_p_at (AT_FDCWD, proxy_socket_dir, 0755, NULL, NULL))
    return NULL;

  fd = g_mkstemp (proxy_socket);
  if (fd == -1)
    return NULL;

  close (fd);

  return g_steal_pointer (&proxy_socket);
}

gboolean
flatpak_run_add_session_dbus_args (FlatpakBwrap          *app_bwrap,
                                   FlatpakBwrap          *proxy_arg_bwrap,
                                   FlatpakContextSockets  sockets,
                                   FlatpakContext        *context,
                                   FlatpakRunFlags        flags,
                                   const char            *app_id)
{
  static const char sandbox_socket_path[] = "/run/flatpak/bus";
  static const char sandbox_dbus_address[] = "unix:path=/run/flatpak/bus";
  gboolean unrestricted, no_proxy;
  const char *dbus_address = g_getenv ("DBUS_SESSION_BUS_ADDRESS");
  g_autofree char *dbus_session_socket = NULL;

  unrestricted = (sockets & FLATPAK_CONTEXT_SOCKET_SESSION_BUS) != 0;

  if (dbus_address != NULL)
    {
      dbus_session_socket = extract_unix_path_from_dbus_address (dbus_address);
    }
  else
    {
      g_autofree char *user_runtime_dir = flatpak_get_real_xdg_runtime_dir ();
      struct stat statbuf;

      dbus_session_socket = g_build_filename (user_runtime_dir, "bus", NULL);

      if (stat (dbus_session_socket, &statbuf) < 0
          || (statbuf.st_mode & S_IFMT) != S_IFSOCK
          || statbuf.st_uid != getuid ())
        return FALSE;
    }

  if (unrestricted)
    g_info ("Allowing session-dbus access");

  no_proxy = (flags & FLATPAK_RUN_FLAG_NO_SESSION_BUS_PROXY) != 0;

  if (dbus_session_socket != NULL && unrestricted)
    {
      flatpak_bwrap_add_args (app_bwrap,
                              "--ro-bind", dbus_session_socket, sandbox_socket_path,
                              NULL);
      flatpak_bwrap_set_env (app_bwrap, "DBUS_SESSION_BUS_ADDRESS", sandbox_dbus_address, TRUE);
      flatpak_bwrap_add_runtime_dir_member (app_bwrap, "bus");

      return TRUE;
    }
  else if (!no_proxy && dbus_address != NULL)
    {
      g_autofree char *proxy_socket = create_proxy_socket ("session-bus-proxy-XXXXXX");

      if (proxy_socket == NULL)
        return FALSE;

      flatpak_bwrap_add_args (proxy_arg_bwrap, dbus_address, proxy_socket, NULL);

      if (!unrestricted)
        {
          flatpak_context_add_bus_filters (context, app_id, FLATPAK_SESSION_BUS, flags & FLATPAK_RUN_FLAG_SANDBOX, proxy_arg_bwrap);

          /* Allow calling any interface+method on all portals, but only receive broadcasts under /org/desktop/portal */
          flatpak_bwrap_add_arg (proxy_arg_bwrap,
                                 "--call=org.freedesktop.portal.*=*");
          flatpak_bwrap_add_arg (proxy_arg_bwrap,
                                 "--broadcast=org.freedesktop.portal.*=@/org/freedesktop/portal/*");
        }

      if ((flags & FLATPAK_RUN_FLAG_LOG_SESSION_BUS) != 0)
        flatpak_bwrap_add_args (proxy_arg_bwrap, "--log", NULL);

      flatpak_bwrap_add_args (app_bwrap,
                              "--ro-bind", proxy_socket, sandbox_socket_path,
                              NULL);
      flatpak_bwrap_set_env (app_bwrap, "DBUS_SESSION_BUS_ADDRESS", sandbox_dbus_address, TRUE);
      flatpak_bwrap_add_runtime_dir_member (app_bwrap, "bus");

      return TRUE;
    }

  return FALSE;
}

gboolean
flatpak_run_add_system_dbus_args (FlatpakBwrap          *app_bwrap,
                                  FlatpakBwrap          *proxy_arg_bwrap,
                                  FlatpakContextSockets  sockets,
                                  FlatpakContext        *context,
                                  FlatpakRunFlags        flags)
{
  gboolean unrestricted, no_proxy;
  const char *dbus_address = g_getenv ("DBUS_SYSTEM_BUS_ADDRESS");
  g_autofree char *real_dbus_address = NULL;
  g_autofree char *dbus_system_socket = NULL;

  unrestricted = (sockets & FLATPAK_CONTEXT_SOCKET_SYSTEM_BUS) != 0;
  if (unrestricted)
    g_info ("Allowing system-dbus access");

  no_proxy = (flags & FLATPAK_RUN_FLAG_NO_SYSTEM_BUS_PROXY) != 0;

  if (dbus_address != NULL)
    dbus_system_socket = extract_unix_path_from_dbus_address (dbus_address);
  else if (g_file_test ("/var/run/dbus/system_bus_socket", G_FILE_TEST_EXISTS))
    dbus_system_socket = g_strdup ("/var/run/dbus/system_bus_socket");

  if (dbus_system_socket != NULL && unrestricted)
    {
      flatpak_bwrap_add_args (app_bwrap,
                              "--ro-bind", dbus_system_socket, "/run/dbus/system_bus_socket",
                              NULL);
      flatpak_bwrap_set_env (app_bwrap, "DBUS_SYSTEM_BUS_ADDRESS", "unix:path=/run/dbus/system_bus_socket", TRUE);

      return TRUE;
    }
  else if (!no_proxy && flatpak_context_get_needs_system_bus_proxy (context))
    {
      g_autofree char *proxy_socket = create_proxy_socket ("system-bus-proxy-XXXXXX");

      if (proxy_socket == NULL)
        return FALSE;

      if (dbus_address)
        real_dbus_address = g_strdup (dbus_address);
      else
        real_dbus_address = g_strdup_printf ("unix:path=%s", dbus_system_socket);

      flatpak_bwrap_add_args (proxy_arg_bwrap, real_dbus_address, proxy_socket, NULL);

      if (!unrestricted)
        flatpak_context_add_bus_filters (context, NULL, FLATPAK_SYSTEM_BUS, flags & FLATPAK_RUN_FLAG_SANDBOX, proxy_arg_bwrap);

      if ((flags & FLATPAK_RUN_FLAG_LOG_SYSTEM_BUS) != 0)
        flatpak_bwrap_add_args (proxy_arg_bwrap, "--log", NULL);

      flatpak_bwrap_add_args (app_bwrap,
                              "--ro-bind", proxy_socket, "/run/dbus/system_bus_socket",
                              NULL);
      flatpak_bwrap_set_env (app_bwrap, "DBUS_SYSTEM_BUS_ADDRESS", "unix:path=/run/dbus/system_bus_socket", TRUE);

      return TRUE;
    }
  return FALSE;
}

gboolean
flatpak_run_add_a11y_dbus_args (FlatpakBwrap    *app_bwrap,
                                FlatpakBwrap    *proxy_arg_bwrap,
                                FlatpakContext  *context,
                                FlatpakRunFlags  flags,
                                const char      *app_id)
{
  static const char sandbox_socket_path[] = "/run/flatpak/at-spi-bus";
  static const char sandbox_dbus_address[] = "unix:path=/run/flatpak/at-spi-bus";
  g_autoptr(GDBusConnection) session_bus = NULL;
  g_autofree char *a11y_address = NULL;
  g_autoptr(GError) local_error = NULL;
  g_autoptr(GDBusMessage) reply = NULL;
  g_autoptr(GDBusMessage) msg = NULL;
  g_autofree char *proxy_socket = NULL;
  gboolean sandboxed;
  const char *value;

  if ((flags & FLATPAK_RUN_FLAG_NO_A11Y_BUS_PROXY) != 0)
    return FALSE;

  session_bus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL);
  if (session_bus == NULL)
    return FALSE;

  value = g_getenv ("AT_SPI_BUS_ADDRESS");

  if (value != NULL && value[0] != '\0')
    {
      a11y_address = g_strdup (value);
      g_debug ("Retrieved AT-SPI bus address \"%s\" from environment",
               a11y_address);
    }

  /* To have an accurate emulation of AT-SPI's behaviour, ideally we would
   * also query the AT_SPI_BUS atom on the root window if a11y_address is
   * still NULL here, but that would require a libX11 dependency, and
   * isn't done when running under native Wayland anyway. */

  if (a11y_address == NULL)
    {
      msg = g_dbus_message_new_method_call ("org.a11y.Bus", "/org/a11y/bus", "org.a11y.Bus", "GetAddress");
      g_dbus_message_set_body (msg, g_variant_new ("()"));
      reply =
        g_dbus_connection_send_message_with_reply_sync (session_bus, msg,
                                                        G_DBUS_SEND_MESSAGE_FLAGS_NONE,
                                                        30000,
                                                        NULL,
                                                        NULL,
                                                        NULL);
      if (reply)
        {
          if (g_dbus_message_to_gerror (reply, &local_error))
            {
              if (!g_error_matches (local_error, G_DBUS_ERROR, G_DBUS_ERROR_SERVICE_UNKNOWN))
                g_message ("Can't find a11y bus: %s", local_error->message);
            }
          else
            {
              g_variant_get (g_dbus_message_get_body (reply),
                             "(s)", &a11y_address);
              g_debug ("Retrieved AT-SPI bus address \"%s\" from session bus",
                       a11y_address);
            }
        }
    }

  if (!a11y_address)
    return FALSE;

  proxy_socket = create_proxy_socket ("a11y-bus-proxy-XXXXXX");
  if (proxy_socket == NULL)
    return FALSE;

  flatpak_bwrap_add_args (proxy_arg_bwrap,
                          a11y_address,
                          proxy_socket, "--filter", "--sloppy-names",
                          "--broadcast=org.a11y.atspi.Registry.EventListenerRegistered=@/org/a11y/atspi/registry",
                          "--broadcast=org.a11y.atspi.Registry.EventListenerDeregistered=@/org/a11y/atspi/registry",
                          "--call=org.a11y.atspi.Registry=org.a11y.atspi.Socket.Embed@/org/a11y/atspi/accessible/root",
                          "--call=org.a11y.atspi.Registry=org.a11y.atspi.Socket.Unembed@/org/a11y/atspi/accessible/root",
                          "--call=org.a11y.atspi.Registry=org.a11y.atspi.Registry.GetRegisteredEvents@/org/a11y/atspi/registry",
                          "--call=org.a11y.atspi.Registry=org.a11y.atspi.DeviceEventController.GetKeystrokeListeners@/org/a11y/atspi/registry/deviceeventcontroller",
                          "--call=org.a11y.atspi.Registry=org.a11y.atspi.DeviceEventController.GetDeviceEventListeners@/org/a11y/atspi/registry/deviceeventcontroller",
                          "--call=org.a11y.atspi.Registry=org.a11y.atspi.DeviceEventController.NotifyListenersSync@/org/a11y/atspi/registry/deviceeventcontroller",
                          "--call=org.a11y.atspi.Registry=org.a11y.atspi.DeviceEventController.NotifyListenersAsync@/org/a11y/atspi/registry/deviceeventcontroller",
                          NULL);

  sandboxed = flags & FLATPAK_RUN_FLAG_SANDBOX;

  flatpak_context_add_bus_filters (context, app_id, FLATPAK_A11Y_BUS, sandboxed, proxy_arg_bwrap);

  /* Allow the main sandbox instance call org.a11y.atspi.Socket.Embedded() on
   * well-known names of the subsandboxes' objects on the a11y bus.
   */
  if (!sandboxed)
    flatpak_bwrap_add_arg_printf (proxy_arg_bwrap, "--call=%s.Sandboxed.*=org.a11y.atspi.Socket.Embedded", app_id);

  if ((flags & FLATPAK_RUN_FLAG_LOG_A11Y_BUS) != 0)
    flatpak_bwrap_add_args (proxy_arg_bwrap, "--log", NULL);

  flatpak_bwrap_add_args (app_bwrap,
                          "--ro-bind", proxy_socket, sandbox_socket_path,
                          NULL);
  flatpak_bwrap_set_env (app_bwrap, "AT_SPI_BUS_ADDRESS", sandbox_dbus_address, TRUE);

  return TRUE;
}

===== ./common/flatpak-uri.c =====
/* vi:set et sw=2 sts=2 cin cino=t0,f0,(0,{s,>2s,n-s,^-s,e-s:
 * Copyright © 1995-1998 Free Software Foundation, Inc.
 * Copyright © 2014-2019 Red Hat, Inc
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Alexander Larsson <alexl@redhat.com>
 */

#include "config.h"

#include <glib/gi18n-lib.h>

#include "flatpak-uri-private.h"

#if !GLIB_CHECK_VERSION (2, 66, 0)

struct _GUri {
  gchar     *scheme;
  gchar     *userinfo;
  gchar     *host;
  gint       port;
  gchar     *path;
  gchar     *query;
  gchar     *fragment;

  gchar     *user;
  gchar     *password;
  gchar     *auth_params;

  GUriFlags  flags;
  int ref_count;
};

GUri *
flatpak_g_uri_ref (GUri *uri)
{
  g_return_val_if_fail (uri != NULL, NULL);
  g_atomic_int_inc (&uri->ref_count);
  return uri;
}

void
flatpak_g_uri_unref (GUri *uri)
{
  g_return_if_fail (uri != NULL);

  if (g_atomic_int_dec_and_test (&uri->ref_count))
    {
      g_free (uri->scheme);
      g_free (uri->userinfo);
      g_free (uri->host);
      g_free (uri->path);
      g_free (uri->query);
      g_free (uri->fragment);
      g_free (uri->user);
      g_free (uri->password);
      g_free (uri->auth_params);
      g_free (uri);
    }
}

static gboolean
flatpak_g_uri_char_is_unreserved (gchar ch)
{
  if (g_ascii_isalnum (ch))
    return TRUE;
  return ch == '-' || ch == '.' || ch == '_' || ch == '~';
}

#define XDIGIT(c) ((c) <= '9' ? (c) - '0' : ((c) & 0x4F) - 'A' + 10)
#define HEXCHAR(s) ((XDIGIT (s[1]) << 4) + XDIGIT (s[2]))

static gssize
uri_decoder (gchar       **out,
             const gchar  *illegal_chars,
             const gchar  *start,
             gsize         length,
             gboolean      just_normalize,
             gboolean      www_form,
             GUriFlags     flags,
             GError      **error)
{
  gchar c;
  GString *decoded;
  const gchar *invalid, *s, *end;
  gssize len;

  if (!(flags & G_URI_FLAGS_ENCODED))
    just_normalize = FALSE;

  decoded = g_string_sized_new (length + 1);
  for (s = start, end = s + length; s < end; s++)
    {
      if (*s == '%')
        {
          if (s + 2 >= end ||
              !g_ascii_isxdigit (s[1]) ||
              !g_ascii_isxdigit (s[2]))
            {
              /* % followed by non-hex or the end of the string; this is an error */
              if (!(flags & G_URI_FLAGS_PARSE_RELAXED))
                {
                  g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
                                       /* xgettext: no-c-format */
                                       _("Invalid %-encoding in URI"));
                  g_string_free (decoded, TRUE);
                  return -1;
                }

              /* In non-strict mode, just let it through; we *don't*
               * fix it to "%25", since that might change the way that
               * the URI's owner would interpret it.
               */
              g_string_append_c (decoded, *s);
              continue;
            }

          c = HEXCHAR (s);
          if (illegal_chars && strchr (illegal_chars, c))
            {
              g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
                                   _("Illegal character in URI"));
              g_string_free (decoded, TRUE);
              return -1;
            }
          if (just_normalize && !flatpak_g_uri_char_is_unreserved (c))
            {
              /* Leave the % sequence there but normalize it. */
              g_string_append_c (decoded, *s);
              g_string_append_c (decoded, g_ascii_toupper (s[1]));
              g_string_append_c (decoded, g_ascii_toupper (s[2]));
              s += 2;
            }
          else
            {
              g_string_append_c (decoded, c);
              s += 2;
            }
        }
      else if (www_form && *s == '+')
        g_string_append_c (decoded, ' ');
      /* Normalize any illegal characters. */
      else if (just_normalize && (!g_ascii_isgraph (*s)))
        g_string_append_printf (decoded, "%%%02X", (guchar)*s);
      else
        g_string_append_c (decoded, *s);
    }

  len = decoded->len;
  g_assert (len >= 0);

  if (!(flags & G_URI_FLAGS_ENCODED) &&
      !g_utf8_validate (decoded->str, len, &invalid))
    {
      g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
                           _("Non-UTF-8 characters in URI"));
      g_string_free (decoded, TRUE);
      return -1;
    }

  if (out)
    *out = g_string_free (decoded, FALSE);
  else
    g_string_free (decoded, TRUE);

  return len;
}

static gboolean
uri_decode (gchar       **out,
            const gchar  *illegal_chars,
            const gchar  *start,
            gsize         length,
            gboolean      www_form,
            GUriFlags     flags,
            GError      **error)
{
  return uri_decoder (out, illegal_chars, start, length, FALSE, www_form, flags,
                      error) != -1;
}

static gboolean
uri_normalize (gchar       **out,
               const gchar  *start,
               gsize         length,
               GUriFlags     flags,
               GError      **error)
{
  return uri_decoder (out, NULL, start, length, TRUE, FALSE, flags,
                      error) != -1;
}

static gboolean
parse_ip_literal (const gchar  *start,
                  gsize         length,
                  GUriFlags     flags,
                  gchar       **out,
                  GError      **error)
{
  gchar *pct, *zone_id = NULL;
  gchar *addr = NULL;
  gsize addr_length = 0;
  gsize zone_id_length = 0;
  gchar *decoded_zone_id = NULL;

  if (start[length - 1] != ']')
    goto bad_ipv6_literal;

  /* Drop the square brackets */
  addr = g_strndup (start + 1, length - 2);
  addr_length = length - 2;

  /* If there's an IPv6 scope ID, split out the zone. */
  pct = strchr (addr, '%');
  if (pct != NULL)
    {
      *pct = '\0';

      if (addr_length - (pct - addr) >= 4 &&
          *(pct + 1) == '2' && *(pct + 2) == '5')
        {
          zone_id = pct + 3;
          zone_id_length = addr_length - (zone_id - addr);
        }
      else if (flags & G_URI_FLAGS_PARSE_RELAXED &&
               addr_length - (pct - addr) >= 2)
        {
          zone_id = pct + 1;
          zone_id_length = addr_length - (zone_id - addr);
        }
      else
        goto bad_ipv6_literal;

      g_assert (zone_id_length >= 1);
    }

  /* addr must be an IPv6 address */
  if (!g_hostname_is_ip_address (addr) || !strchr (addr, ':'))
    goto bad_ipv6_literal;

  /* Zone ID must be valid. It can contain %-encoded characters. */
  if (zone_id != NULL &&
      !uri_decode (&decoded_zone_id, NULL, zone_id, zone_id_length, FALSE,
                   flags, NULL))
    goto bad_ipv6_literal;

  /* Success */
  if (out != NULL && decoded_zone_id != NULL)
    *out = g_strconcat (addr, "%", decoded_zone_id, NULL);
  else if (out != NULL)
    *out = g_steal_pointer (&addr);

  g_free (addr);
  g_free (decoded_zone_id);

  return TRUE;

bad_ipv6_literal:
  g_free (addr);
  g_free (decoded_zone_id);
  g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
               _("Invalid IPv6 address ‘%.*s’ in URI"),
               (gint)length, start);

  return FALSE;
}

static gboolean
parse_host (const gchar  *start,
            gsize         length,
            GUriFlags     flags,
            gchar       **out,
            GError      **error)
{
  gchar *decoded = NULL, *host;
  gchar *addr = NULL;

  if (*start == '[')
    {
      if (!parse_ip_literal (start, length, flags, &host, error))
        return FALSE;
      goto ok;
    }

  if (g_ascii_isdigit (*start))
    {
      addr = g_strndup (start, length);
      if (g_hostname_is_ip_address (addr))
        {
          host = addr;
          goto ok;
        }
      g_free (addr);
    }

  if (flags & G_URI_FLAGS_NON_DNS)
    {
      if (!uri_normalize (&decoded, start, length, flags,
                          error))
        return FALSE;
      host = g_steal_pointer (&decoded);
      goto ok;
    }

  flags &= ~G_URI_FLAGS_ENCODED;
  if (!uri_decode (&decoded, NULL, start, length, FALSE, flags,
                   error))
    return FALSE;

  /* You're not allowed to %-encode an IP address, so if it wasn't
   * one before, it better not be one now.
   */
  if (g_hostname_is_ip_address (decoded))
    {
      g_free (decoded);
      g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
                   _("Illegal encoded IP address ‘%.*s’ in URI"),
                   (gint)length, start);
      return FALSE;
    }

  if (g_hostname_is_non_ascii (decoded))
    {
      host = g_hostname_to_ascii (decoded);
      if (host == NULL)
        {
          g_free (decoded);
          g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
                       _("Illegal internationalized hostname ‘%.*s’ in URI"),
                       (gint) length, start);
          return FALSE;
        }
    }
  else
    {
      host = g_steal_pointer (&decoded);
    }

 ok:
  if (out)
    *out = g_steal_pointer (&host);
  g_free (host);
  g_free (decoded);

  return TRUE;
}

static gboolean
parse_port (const gchar  *start,
            gsize         length,
            gint         *out,
            GError      **error)
{
  gchar *end;
  gulong parsed_port;

  /* strtoul() allows leading + or -, so we have to check this first. */
  if (!g_ascii_isdigit (*start))
    {
      g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
                   _("Could not parse port ‘%.*s’ in URI"),
                   (gint)length, start);
      return FALSE;
    }

  /* We know that *(start + length) is either '\0' or a non-numeric
   * character, so strtoul() won't scan beyond it.
   */
  parsed_port = strtoul (start, &end, 10);
  if (end != start + length)
    {
      g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
                   _("Could not parse port ‘%.*s’ in URI"),
                   (gint)length, start);
      return FALSE;
    }
  else if (parsed_port > 65535)
    {
      g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
                   _("Port ‘%.*s’ in URI is out of range"),
                   (gint)length, start);
      return FALSE;
    }

  if (out)
    *out = parsed_port;
  return TRUE;
}

static gboolean
parse_userinfo (const gchar  *start,
                gsize         length,
                GUriFlags     flags,
                gchar       **user,
                gchar       **password,
                gchar       **auth_params,
                GError      **error)
{
  const gchar *user_end = NULL, *password_end = NULL, *auth_params_end;

  auth_params_end = start + length;
  if (flags & G_URI_FLAGS_HAS_AUTH_PARAMS)
    password_end = memchr (start, ';', auth_params_end - start);
  if (!password_end)
    password_end = auth_params_end;
  if (flags & G_URI_FLAGS_HAS_PASSWORD)
    user_end = memchr (start, ':', password_end - start);
  if (!user_end)
    user_end = password_end;

  if (!uri_normalize (user, start, user_end - start, flags,
                      error))
    return FALSE;

  if (*user_end == ':')
    {
      start = user_end + 1;
      if (!uri_normalize (password, start, password_end - start, flags,
                          error))
        {
          if (user)
            g_clear_pointer (user, g_free);
          return FALSE;
        }
    }
  else if (password)
    *password = NULL;

  if (*password_end == ';')
    {
      start = password_end + 1;
      if (!uri_normalize (auth_params, start, auth_params_end - start, flags,
                          error))
        {
          if (user)
            g_clear_pointer (user, g_free);
          if (password)
            g_clear_pointer (password, g_free);
          return FALSE;
        }
    }
  else if (auth_params)
    *auth_params = NULL;

  return TRUE;
}

static gchar *
uri_cleanup (const gchar *uri_string)
{
  GString *copy;
  const gchar *end;

  /* Skip leading whitespace */
  while (g_ascii_isspace (*uri_string))
    uri_string++;

  /* Ignore trailing whitespace */
  end = uri_string + strlen (uri_string);
  while (end > uri_string && g_ascii_isspace (*(end - 1)))
    end--;

  /* Copy the rest, encoding unencoded spaces and stripping other whitespace */
  copy = g_string_sized_new (end - uri_string);
  while (uri_string < end)
    {
      if (*uri_string == ' ')
        g_string_append (copy, "%20");
      else if (g_ascii_isspace (*uri_string))
        ;
      else
        g_string_append_c (copy, *uri_string);
      uri_string++;
    }

  return g_string_free (copy, FALSE);
}

static gboolean
should_normalize_empty_path (const char *scheme)
{
  const char * const schemes[] = { "https", "http", "wss", "ws" };
  gsize i;
  for (i = 0; i < G_N_ELEMENTS (schemes); ++i)
    {
      if (!strcmp (schemes[i], scheme))
        return TRUE;
    }
  return FALSE;
}

static int
normalize_port (const char *scheme,
                int         port)
{
  const char *default_schemes[3] = { NULL };
  int i;

  switch (port)
    {
    case 21:
      default_schemes[0] = "ftp";
      break;
    case 80:
      default_schemes[0] = "http";
      default_schemes[1] = "ws";
      break;
    case 443:
      default_schemes[0] = "https";
      default_schemes[1] = "wss";
      break;
    default:
      break;
    }

  for (i = 0; default_schemes[i]; ++i)
    {
      if (!strcmp (scheme, default_schemes[i]))
        return -1;
    }

  return port;
}

static int
default_scheme_port (const char *scheme)
{
  if (strcmp (scheme, "http") == 0 || strcmp (scheme, "ws") == 0)
    return 80;

  if (strcmp (scheme, "https") == 0 || strcmp (scheme, "wss") == 0)
    return 443;

  if (strcmp (scheme, "ftp") == 0)
    return 21;

  return -1;
}

static gboolean
flatpak_g_uri_split_internal (const gchar  *uri_string,
                      GUriFlags     flags,
                      gchar       **scheme,
                      gchar       **userinfo,
                      gchar       **user,
                      gchar       **password,
                      gchar       **auth_params,
                      gchar       **host,
                      gint         *port,
                      gchar       **path,
                      gchar       **query,
                      gchar       **fragment,
                      GError      **error)
{
  const gchar *end, *colon, *at, *path_start, *semi, *question;
  const gchar *p, *bracket, *hostend;
  gchar *cleaned_uri_string = NULL;
  gchar *normalized_scheme = NULL;

  if (scheme)
    *scheme = NULL;
  if (userinfo)
    *userinfo = NULL;
  if (user)
    *user = NULL;
  if (password)
    *password = NULL;
  if (auth_params)
    *auth_params = NULL;
  if (host)
    *host = NULL;
  if (port)
    *port = -1;
  if (path)
    *path = NULL;
  if (query)
    *query = NULL;
  if (fragment)
    *fragment = NULL;

  if ((flags & G_URI_FLAGS_PARSE_RELAXED) && strpbrk (uri_string, " \t\n\r"))
    {
      cleaned_uri_string = uri_cleanup (uri_string);
      uri_string = cleaned_uri_string;
    }

  /* Find scheme */
  p = uri_string;
  while (*p && (g_ascii_isalpha (*p) ||
               (p > uri_string && (g_ascii_isdigit (*p) ||
                                   *p == '.' || *p == '+' || *p == '-'))))
    p++;

  if (p > uri_string && *p == ':')
    {
      normalized_scheme = g_ascii_strdown (uri_string, p - uri_string);
      if (scheme)
        *scheme = g_steal_pointer (&normalized_scheme);
      p++;
    }
  else
    {
      if (scheme)
        *scheme = NULL;
      p = uri_string;
    }

  /* Check for authority */
  if (strncmp (p, "//", 2) == 0)
    {
      p += 2;

      path_start = p + strcspn (p, "/?#");
      at = memchr (p, '@', path_start - p);
      if (at)
        {
          if (flags & G_URI_FLAGS_PARSE_RELAXED)
            {
              gchar *next_at;

              /* Any "@"s in the userinfo must be %-encoded, but
               * people get this wrong sometimes. Since "@"s in the
               * hostname are unlikely (and also wrong anyway), assume
               * that if there are extra "@"s, they belong in the
               * userinfo.
               */
              do
                {
                  next_at = memchr (at + 1, '@', path_start - (at + 1));
                  if (next_at)
                    at = next_at;
                }
              while (next_at);
            }

          if (user || password || auth_params ||
              (flags & (G_URI_FLAGS_HAS_PASSWORD|G_URI_FLAGS_HAS_AUTH_PARAMS)))
            {
              if (!parse_userinfo (p, at - p, flags,
                                   user, password, auth_params,
                                   error))
                goto fail;
            }

          if (!uri_normalize (userinfo, p, at - p, flags,
                              error))
            goto fail;

          p = at + 1;
        }

      if (flags & G_URI_FLAGS_PARSE_RELAXED)
        {
          semi = strchr (p, ';');
          if (semi && semi < path_start)
            {
              /* Technically, semicolons are allowed in the "host"
               * production, but no one ever does this, and some
               * schemes mistakenly use semicolon as a delimiter
               * marking the start of the path. We have to check this
               * after checking for userinfo though, because a
               * semicolon before the "@" must be part of the
               * userinfo.
               */
              path_start = semi;
            }
        }

      /* Find host and port. The host may be a bracket-delimited IPv6
       * address, in which case the colon delimiting the port must come
       * (immediately) after the close bracket.
       */
      if (*p == '[')
        {
          bracket = memchr (p, ']', path_start - p);
          if (bracket && *(bracket + 1) == ':')
            colon = bracket + 1;
          else
            colon = NULL;
        }
      else
        colon = memchr (p, ':', path_start - p);

      hostend = colon ? colon : path_start;
      if (!parse_host (p, hostend - p, flags, host, error))
        goto fail;

      if (colon && colon != path_start - 1)
        {
          p = colon + 1;
          if (!parse_port (p, path_start - p, port, error))
            goto fail;
        }

      p = path_start;
    }

  /* Find fragment. */
  end = p + strcspn (p, "#");
  if (*end == '#')
    {
      if (!uri_normalize (fragment, end + 1, strlen (end + 1),
                          flags | (flags & G_URI_FLAGS_ENCODED_FRAGMENT ? G_URI_FLAGS_ENCODED : 0),
                          error))
        goto fail;
    }

  /* Find query */
  question = memchr (p, '?', end - p);
  if (question)
    {
      if (!uri_normalize (query, question + 1, end - (question + 1),
                          flags | (flags & G_URI_FLAGS_ENCODED_QUERY ? G_URI_FLAGS_ENCODED : 0),
                          error))
        goto fail;
      end = question;
    }

  if (!uri_normalize (path, p, end - p,
                      flags | (flags & G_URI_FLAGS_ENCODED_PATH ? G_URI_FLAGS_ENCODED : 0),
                      error))
    goto fail;

  /* Scheme-based normalization */
  if (flags & G_URI_FLAGS_SCHEME_NORMALIZE && ((scheme && *scheme) || normalized_scheme))
    {
      const char *scheme_str = scheme && *scheme ? *scheme : normalized_scheme;

      if (should_normalize_empty_path (scheme_str) && path && !**path)
        {
          g_free (*path);
          *path = g_strdup ("/");
        }

      if (port && *port == -1)
        *port = default_scheme_port (scheme_str);
    }

  g_free (normalized_scheme);
  g_free (cleaned_uri_string);
  return TRUE;

 fail:
  if (scheme)
    g_clear_pointer (scheme, g_free);
  if (userinfo)
    g_clear_pointer (userinfo, g_free);
  if (host)
    g_clear_pointer (host, g_free);
  if (port)
    *port = -1;
  if (path)
    g_clear_pointer (path, g_free);
  if (query)
    g_clear_pointer (query, g_free);
  if (fragment)
    g_clear_pointer (fragment, g_free);

  g_free (normalized_scheme);
  g_free (cleaned_uri_string);
  return FALSE;
}


/* Implements the "Remove Dot Segments" algorithm from section 5.2.4 of
 * RFC 3986.
 *
 * See https://tools.ietf.org/html/rfc3986#section-5.2.4
 */
static void
remove_dot_segments (gchar *path)
{
  /* The output can be written to the same buffer that the input
   * is read from, as the output pointer is only ever increased
   * when the input pointer is increased as well, and the input
   * pointer is never decreased. */
  gchar *input = path;
  gchar *output = path;

  if (!*path)
    return;

  while (*input)
    {
      /*  A.  If the input buffer begins with a prefix of "../" or "./",
       *      then remove that prefix from the input buffer; otherwise,
       */
      if (strncmp (input, "../", 3) == 0)
        input += 3;
      else if (strncmp (input, "./", 2) == 0)
        input += 2;

      /*  B.  if the input buffer begins with a prefix of "/./" or "/.",
       *      where "." is a complete path segment, then replace that
       *      prefix with "/" in the input buffer; otherwise,
       */
      else if (strncmp (input, "/./", 3) == 0)
        input += 2;
      else if (strcmp (input, "/.") == 0)
        input[1] = '\0';

      /*  C.  if the input buffer begins with a prefix of "/../" or "/..",
       *      where ".." is a complete path segment, then replace that
       *      prefix with "/" in the input buffer and remove the last
       *      segment and its preceding "/" (if any) from the output
       *      buffer; otherwise,
       */
      else if (strncmp (input, "/../", 4) == 0)
        {
          input += 3;
          if (output > path)
            {
              do
                {
                  output--;
                }
              while (*output != '/' && output > path);
            }
        }
      else if (strcmp (input, "/..") == 0)
        {
          input[1] = '\0';
          if (output > path)
            {
              do
                 {
                   output--;
                 }
              while (*output != '/' && output > path);
            }
        }

      /*  D.  if the input buffer consists only of "." or "..", then remove
       *      that from the input buffer; otherwise,
       */
      else if (strcmp (input, "..") == 0 || strcmp (input, ".") == 0)
        input[0] = '\0';

      /*  E.  move the first path segment in the input buffer to the end of
       *      the output buffer, including the initial "/" character (if
       *      any) and any subsequent characters up to, but not including,
       *      the next "/" character or the end of the input buffer.
       */
      else
        {
          *output++ = *input++;
          while (*input && *input != '/')
            *output++ = *input++;
        }
    }
  *output = '\0';
}

GUri *
flatpak_g_uri_parse (const gchar  *uri_string,
             GUriFlags     flags,
             GError      **error)
{
  g_return_val_if_fail (uri_string != NULL, NULL);
  g_return_val_if_fail (error == NULL || *error == NULL, NULL);

  return flatpak_g_uri_parse_relative (NULL, uri_string, flags, error);
}

GUri *
flatpak_g_uri_parse_relative (GUri         *base_uri,
                      const gchar  *uri_ref,
                      GUriFlags     flags,
                      GError      **error)
{
  GUri *uri = NULL;

  g_return_val_if_fail (uri_ref != NULL, NULL);
  g_return_val_if_fail (error == NULL || *error == NULL, NULL);
  g_return_val_if_fail (base_uri == NULL || base_uri->scheme != NULL, NULL);

  /* Use GUri struct to construct the return value: there is no guarantee it is
   * actually correct within the function body. */
  uri = g_new0 (GUri, 1);
  uri->ref_count = 1;
  uri->flags = flags;

  if (!flatpak_g_uri_split_internal (uri_ref, flags,
                             &uri->scheme, &uri->userinfo,
                             &uri->user, &uri->password, &uri->auth_params,
                             &uri->host, &uri->port,
                             &uri->path, &uri->query, &uri->fragment,
                             error))
    {
      flatpak_g_uri_unref (uri);
      return NULL;
    }

  if (!uri->scheme && !base_uri)
    {
      g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
                           _("URI is not absolute, and no base URI was provided"));
      flatpak_g_uri_unref (uri);
      return NULL;
    }

  if (base_uri)
    {
      /* This is section 5.2.2 of RFC 3986, except that we're doing
       * it in place in @uri rather than copying from R to T.
       *
       * See https://tools.ietf.org/html/rfc3986#section-5.2.2
       */
      if (uri->scheme)
        remove_dot_segments (uri->path);
      else
        {
          uri->scheme = g_strdup (base_uri->scheme);
          if (uri->host)
            remove_dot_segments (uri->path);
          else
            {
              if (!*uri->path)
                {
                  g_free (uri->path);
                  uri->path = g_strdup (base_uri->path);
                  if (!uri->query)
                    uri->query = g_strdup (base_uri->query);
                }
              else
                {
                  if (*uri->path == '/')
                    remove_dot_segments (uri->path);
                  else
                    {
                      gchar *newpath, *last;

                      last = strrchr (base_uri->path, '/');
                      if (last)
                        {
                          newpath = g_strdup_printf ("%.*s/%s",
                                                     (gint)(last - base_uri->path),
                                                     base_uri->path,
                                                     uri->path);
                        }
                      else
                        newpath = g_strdup_printf ("/%s", uri->path);

                      g_free (uri->path);
                      uri->path = g_steal_pointer (&newpath);

                      remove_dot_segments (uri->path);
                    }
                }

              uri->userinfo = g_strdup (base_uri->userinfo);
              uri->user = g_strdup (base_uri->user);
              uri->password = g_strdup (base_uri->password);
              uri->auth_params = g_strdup (base_uri->auth_params);
              uri->host = g_strdup (base_uri->host);
              uri->port = base_uri->port;
            }
        }

      /* Scheme normalization couldn't have been done earlier
       * as the relative URI may not have had a scheme */
      if (flags & G_URI_FLAGS_SCHEME_NORMALIZE)
        {
          if (should_normalize_empty_path (uri->scheme) && !*uri->path)
            {
              g_free (uri->path);
              uri->path = g_strdup ("/");
            }

          uri->port = normalize_port (uri->scheme, uri->port);
        }
    }
  else
    {
      remove_dot_segments (uri->path);
    }

  return g_steal_pointer (&uri);
}

/* userinfo as a whole can contain sub-delims + ":", but split-out
 * user can't contain ":" or ";", and split-out password can't contain
 * ";".
 */
#define USERINFO_ALLOWED_CHARS G_URI_RESERVED_CHARS_ALLOWED_IN_USERINFO
#define USER_ALLOWED_CHARS "!$&'()*+,="
#define PASSWORD_ALLOWED_CHARS "!$&'()*+,=:"
#define AUTH_PARAMS_ALLOWED_CHARS USERINFO_ALLOWED_CHARS
#define IP_ADDR_ALLOWED_CHARS ":"
#define HOST_ALLOWED_CHARS G_URI_RESERVED_CHARS_SUBCOMPONENT_DELIMITERS
#define PATH_ALLOWED_CHARS G_URI_RESERVED_CHARS_ALLOWED_IN_PATH
#define QUERY_ALLOWED_CHARS G_URI_RESERVED_CHARS_ALLOWED_IN_PATH "?"
#define FRAGMENT_ALLOWED_CHARS G_URI_RESERVED_CHARS_ALLOWED_IN_PATH "?"

static gchar *
flatpak_g_uri_join_internal (GUriFlags    flags,
                     const gchar *scheme,
                     gboolean     userinfo,
                     const gchar *user,
                     const gchar *password,
                     const gchar *auth_params,
                     const gchar *host,
                     gint         port,
                     const gchar *path,
                     const gchar *query,
                     const gchar *fragment)
{
  gboolean encoded = (flags & G_URI_FLAGS_ENCODED);
  GString *str;
  char *normalized_scheme = NULL;

  /* Restrictions on path prefixes. See:
   * https://tools.ietf.org/html/rfc3986#section-3
   */
  g_return_val_if_fail (path != NULL, NULL);
  g_return_val_if_fail (host == NULL || (path[0] == '\0' || path[0] == '/'), NULL);
  g_return_val_if_fail (host != NULL || (path[0] != '/' || path[1] != '/'), NULL);

  str = g_string_new (scheme);
  if (scheme)
    g_string_append_c (str, ':');

  if (flags & G_URI_FLAGS_SCHEME_NORMALIZE && scheme && ((host && port != -1) || path[0] == '\0'))
    normalized_scheme = g_ascii_strdown (scheme, -1);

  if (host)
    {
      g_string_append (str, "//");

      if (user)
        {
          if (encoded)
            g_string_append (str, user);
          else
            {
              if (userinfo)
                g_string_append_uri_escaped (str, user, USERINFO_ALLOWED_CHARS, TRUE);
              else
                /* Encode ':' and ';' regardless of whether we have a
                 * password or auth params, since it may be parsed later
                 * under the assumption that it does.
                 */
                g_string_append_uri_escaped (str, user, USER_ALLOWED_CHARS, TRUE);
            }

          if (password)
            {
              g_string_append_c (str, ':');
              if (encoded)
                g_string_append (str, password);
              else
                g_string_append_uri_escaped (str, password,
                                             PASSWORD_ALLOWED_CHARS, TRUE);
            }

          if (auth_params)
            {
              g_string_append_c (str, ';');
              if (encoded)
                g_string_append (str, auth_params);
              else
                g_string_append_uri_escaped (str, auth_params,
                                             AUTH_PARAMS_ALLOWED_CHARS, TRUE);
            }

          g_string_append_c (str, '@');
        }

      if (strchr (host, ':') && g_hostname_is_ip_address (host))
        {
          g_string_append_c (str, '[');
          if (encoded)
            g_string_append (str, host);
          else
            g_string_append_uri_escaped (str, host, IP_ADDR_ALLOWED_CHARS, TRUE);
          g_string_append_c (str, ']');
        }
      else
        {
          if (encoded)
            g_string_append (str, host);
          else
            g_string_append_uri_escaped (str, host, HOST_ALLOWED_CHARS, TRUE);
        }

      if (port != -1 && (!normalized_scheme || normalize_port (normalized_scheme, port) != -1))
        g_string_append_printf (str, ":%d", port);
    }

  if (path[0] == '\0' && normalized_scheme && should_normalize_empty_path (normalized_scheme))
    g_string_append (str, "/");
  else if (encoded || flags & G_URI_FLAGS_ENCODED_PATH)
    g_string_append (str, path);
  else
    g_string_append_uri_escaped (str, path, PATH_ALLOWED_CHARS, TRUE);

  g_free (normalized_scheme);

  if (query)
    {
      g_string_append_c (str, '?');
      if (encoded || flags & G_URI_FLAGS_ENCODED_QUERY)
        g_string_append (str, query);
      else
        g_string_append_uri_escaped (str, query, QUERY_ALLOWED_CHARS, TRUE);
    }
  if (fragment)
    {
      g_string_append_c (str, '#');
      if (encoded || flags & G_URI_FLAGS_ENCODED_FRAGMENT)
        g_string_append (str, fragment);
      else
        g_string_append_uri_escaped (str, fragment, FRAGMENT_ALLOWED_CHARS, TRUE);
    }

  return g_string_free (str, FALSE);
}

static gchar *
flatpak_g_uri_join (GUriFlags    flags,
            const gchar *scheme,
            const gchar *userinfo,
            const gchar *host,
            gint         port,
            const gchar *path,
            const gchar *query,
            const gchar *fragment)
{
  g_return_val_if_fail (port >= -1 && port <= 65535, NULL);
  g_return_val_if_fail (path != NULL, NULL);

  return flatpak_g_uri_join_internal (flags,
                              scheme,
                              TRUE, userinfo, NULL, NULL,
                              host,
                              port,
                              path,
                              query,
                              fragment);
}

static gchar *
flatpak_g_uri_join_with_user (GUriFlags    flags,
                      const gchar *scheme,
                      const gchar *user,
                      const gchar *password,
                      const gchar *auth_params,
                      const gchar *host,
                      gint         port,
                      const gchar *path,
                      const gchar *query,
                      const gchar *fragment)
{
  g_return_val_if_fail (port >= -1 && port <= 65535, NULL);
  g_return_val_if_fail (path != NULL, NULL);

  return flatpak_g_uri_join_internal (flags,
                              scheme,
                              FALSE, user, password, auth_params,
                              host,
                              port,
                              path,
                              query,
                              fragment);
}

GUri *
flatpak_g_uri_build (GUriFlags    flags,
             const gchar *scheme,
             const gchar *userinfo,
             const gchar *host,
             gint         port,
             const gchar *path,
             const gchar *query,
             const gchar *fragment)
{
  GUri *uri;

  g_return_val_if_fail (scheme != NULL, NULL);
  g_return_val_if_fail (port >= -1 && port <= 65535, NULL);
  g_return_val_if_fail (path != NULL, NULL);

  uri = g_new0 (GUri, 1);
  uri->ref_count = 1;
  uri->flags = flags;
  uri->scheme = g_ascii_strdown (scheme, -1);
  uri->userinfo = g_strdup (userinfo);
  uri->host = g_strdup (host);
  uri->port = port;
  uri->path = g_strdup (path);
  uri->query = g_strdup (query);
  uri->fragment = g_strdup (fragment);

  return g_steal_pointer (&uri);
}

gchar *
flatpak_g_uri_to_string_partial (GUri          *uri,
                         GUriHideFlags  flags)
{
  gboolean hide_user = (flags & G_URI_HIDE_USERINFO);
  gboolean hide_password = (flags & (G_URI_HIDE_USERINFO | G_URI_HIDE_PASSWORD));
  gboolean hide_auth_params = (flags & (G_URI_HIDE_USERINFO | G_URI_HIDE_AUTH_PARAMS));
  gboolean hide_query = (flags & G_URI_HIDE_QUERY);
  gboolean hide_fragment = (flags & G_URI_HIDE_FRAGMENT);

  g_return_val_if_fail (uri != NULL, NULL);

  if (uri->flags & (G_URI_FLAGS_HAS_PASSWORD | G_URI_FLAGS_HAS_AUTH_PARAMS))
    {
      return flatpak_g_uri_join_with_user (uri->flags,
                                   uri->scheme,
                                   hide_user ? NULL : uri->user,
                                   hide_password ? NULL : uri->password,
                                   hide_auth_params ? NULL : uri->auth_params,
                                   uri->host,
                                   uri->port,
                                   uri->path,
                                   hide_query ? NULL : uri->query,
                                   hide_fragment ? NULL : uri->fragment);
    }

  return flatpak_g_uri_join (uri->flags,
                     uri->scheme,
                     hide_user ? NULL : uri->userinfo,
                     uri->host,
                     uri->port,
                     uri->path,
                     hide_query ? NULL : uri->query,
                     hide_fragment ? NULL : uri->fragment);
}

const gchar *
flatpak_g_uri_get_scheme (GUri *uri)
{
  g_return_val_if_fail (uri != NULL, NULL);

  return uri->scheme;
}

const gchar *
flatpak_g_uri_get_userinfo (GUri *uri)
{
  g_return_val_if_fail (uri != NULL, NULL);

  return uri->userinfo;
}

const gchar *
flatpak_g_uri_get_user (GUri *uri)
{
  g_return_val_if_fail (uri != NULL, NULL);

  return uri->user;
}

const gchar *
flatpak_g_uri_get_password (GUri *uri)
{
  g_return_val_if_fail (uri != NULL, NULL);

  return uri->password;
}

const gchar *
flatpak_g_uri_get_auth_params (GUri *uri)
{
  g_return_val_if_fail (uri != NULL, NULL);

  return uri->auth_params;
}

const gchar *
flatpak_g_uri_get_host (GUri *uri)
{
  g_return_val_if_fail (uri != NULL, NULL);

  return uri->host;
}

gint
flatpak_g_uri_get_port (GUri *uri)
{
  g_return_val_if_fail (uri != NULL, -1);

  if (uri->port == -1 && uri->flags & G_URI_FLAGS_SCHEME_NORMALIZE)
    return default_scheme_port (uri->scheme);

  return uri->port;
}

const gchar *
flatpak_g_uri_get_path (GUri *uri)
{
  g_return_val_if_fail (uri != NULL, NULL);

  return uri->path;
}

const gchar *
flatpak_g_uri_get_query (GUri *uri)
{
  g_return_val_if_fail (uri != NULL, NULL);

  return uri->query;
}

const gchar *
flatpak_g_uri_get_fragment (GUri *uri)
{
  g_return_val_if_fail (uri != NULL, NULL);

  return uri->fragment;
}

GUriFlags
flatpak_g_uri_get_flags (GUri *uri)
{
  g_return_val_if_fail (uri != NULL, G_URI_FLAGS_NONE);

  return uri->flags;
}

#endif /* GLIB_CHECK_VERSION (2, 66, 0) */


static void
append_form_encoded (GString *str, const char *in)
{
  const unsigned char *s = (const unsigned char *)in;

  while (*s)
    {
      if (*s == ' ')
        {
          g_string_append_c (str, '+');
          s++;
        }
      else if (!g_ascii_isalnum (*s) && (*s != '-') && (*s != '_')
               && (*s != '.'))
        g_string_append_printf (str, "%%%02X", (int)*s++);
      else
        g_string_append_c (str, *s++);
    }
}

void
flatpak_uri_encode_query_arg (GString *str,
                              const char *key,
                              const char *value)
{
  if (str->len)
    g_string_append_c (str, '&');
  append_form_encoded (str, key);

  g_string_append_c (str, '=');
  append_form_encoded (str, value);
}


/* This is a simplified copy of soup_header_parse_param_list() to avoid a soup dependency */

static const char *
skip_lws (const char *s)
{
  while (g_ascii_isspace (*s))
    s++;
  return s;
}

static const char *
unskip_lws (const char *s, const char *start)
{
  while (s > start && g_ascii_isspace (*(s - 1)))
    s--;
  return s;
}

static const char *
skip_delims (const char *s, char delim)
{
  /* The grammar allows for multiple delimiters */
  while (g_ascii_isspace (*s) || *s == delim)
    s++;
  return s;
}

static const char *
skip_item (const char *s, char delim)
{
  gboolean quoted = FALSE;
  const char *start = s;

  /* A list item ends at the last non-whitespace character
   * before a delimiter which is not inside a quoted-string. Or
   * at the end of the string.
   */

  while (*s)
    {
      if (*s == '"')
        quoted = !quoted;
      else if (quoted)
        {
          if (*s == '\\' && *(s + 1))
            s++;
        }
      else
        {
          if (*s == delim)
            break;
        }
      s++;
    }

  return unskip_lws (s, start);
}

static GSList *
parse_list (const char *header, char delim)
{
  GSList *list = NULL;
  const char *end;

  header = skip_delims (header, delim);
  while (*header)
    {
      end = skip_item (header, delim);
      list = g_slist_prepend (list, g_strndup (header, end - header));
      header = skip_delims (end, delim);
    }

  return g_slist_reverse (list);
}

static void
decode_quoted_string (char *quoted_string)
{
  char *src, *dst;

  src = quoted_string + 1;
  dst = quoted_string;
  while (*src && *src != '"')
    {
      if (*src == '\\' && *(src + 1))
        src++;
      *dst++ = *src++;
    }
  *dst = '\0';
}

GHashTable *
flatpak_parse_http_header_param_list (const char *header)
{
  GHashTable *params;
  GSList *list, *iter;
  char *eq, *name_end, *value;

  params = g_hash_table_new_full (g_str_hash,
                                  g_str_equal,
                                  g_free, g_free);

  list = parse_list (header, ',');
  for (iter = list; iter; iter = iter->next)
    {
      g_autofree char *item = iter->data;

      eq = strchr (item, '=');
      if (eq)
        {
          name_end = (char *)unskip_lws (eq, item);
          if (name_end == item)
            continue;

          *name_end = '\0';

          value = (char *)skip_lws (eq + 1);
          if (*value == '"')
            decode_quoted_string (value);
        }
      else
        value = NULL;

      g_autofree char *key =  g_ascii_strdown (item, -1);
      if (!g_hash_table_contains (params, key))
        g_hash_table_replace (params, g_steal_pointer (&key), g_strdup (value));
    }

  g_slist_free (list);
  return params;
}

/* Do not internationalize */
static const char *const months[] = {
  "Jan", "Feb", "Mar", "Apr", "May", "Jun",
  "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
};

/* Do not internationalize */
static const char *const days[] = {
  "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
};

char *
flatpak_format_http_date (GDateTime *date)
{
  g_autoptr(GDateTime) utcdate = g_date_time_to_utc (date);
  g_autofree char *date_format = NULL;

  /* "Sun, 06 Nov 1994 08:49:37 GMT" */

  date_format = g_strdup_printf ("%s, %%d %s %%Y %%T GMT",
                                 days[g_date_time_get_day_of_week (utcdate) - 1],
                                 months[g_date_time_get_month (utcdate) - 1]);

  return g_date_time_format (utcdate, (const char*)date_format);
}


static inline gboolean
parse_day (int *day, const char **date_string)
{
  char *end;

  *day = strtoul (*date_string, &end, 10);
  if (end == (char *)*date_string)
    return FALSE;

  while (*end == ' ' || *end == '-')
    end++;
  *date_string = end;
  return TRUE;
}

static inline gboolean
parse_month (int *month, const char **date_string)
{
  int i;

  for (i = 0; i < G_N_ELEMENTS (months); i++)
    {
      if (!g_ascii_strncasecmp (*date_string, months[i], 3))
        {
          *month = i + 1;
          *date_string += 3;
          while (**date_string == ' ' || **date_string == '-')
            (*date_string)++;
          return TRUE;
        }
    }

  return FALSE;
}

static inline gboolean
parse_year (int *year, const char **date_string)
{
  char *end;

  *year = strtoul (*date_string, &end, 10);
  if (end == (char *)*date_string)
    return FALSE;

  if (end == (char *)*date_string + 2) {
    if (*year < 70)
      *year += 2000;
    else
      *year += 1900;
  } else if (end == (char *)*date_string + 3)
    *year += 1900;

  while (*end == ' ' || *end == '-')
    end++;
  *date_string = end;

  return TRUE;
}

static inline gboolean
parse_time (int *hour, int *minute, int *second, const char **date_string)
{
  char *p, *end;

  *hour = strtoul (*date_string, &end, 10);
  if (end == (char *)*date_string || *end++ != ':')
    return FALSE;
  p = end;
  *minute = strtoul (p, &end, 10);
  if (end == p || *end++ != ':')
    return FALSE;
  p = end;
  *second = strtoul (p, &end, 10);
  if (end == p)
    return FALSE;
  p = end;

  while (*p == ' ')
    p++;
  *date_string = p;

  return TRUE;
}

static inline GTimeZone *
time_zone_new_offset (gint32 offset)
{
#if GLIB_CHECK_VERSION (2, 58, 0)
  return g_time_zone_new_offset (offset);
#else
  g_autofree char *id = NULL;
  gint hours, minutes;
  gint seconds = offset;
  GTimeZone *tz;
  char sign = '+';

  if (seconds == 0)
    return g_time_zone_new_utc ();

  if (seconds < 0)
    {
      seconds = -seconds;
      sign = '-';
    }

  hours = seconds / 3600;
  seconds = seconds % 3600;
  minutes = seconds / 60;
  seconds = seconds % 60;

  id = g_strdup_printf ("%c%02d:%02d:%02d", sign, hours, minutes, seconds);
  tz = g_time_zone_new (id);
  /* If this assertion fails, we'll log a critical but still return tz,
   * which is documented to be UTC if the time zone could not be parsed */
  g_return_val_if_fail (g_time_zone_get_offset (tz, 0) == offset, tz);
  return tz;
#endif
}

static inline gboolean
parse_timezone (GTimeZone **timezone_out, const char **date_string)
{
  gint32 offset_minutes;
  gboolean utc;

  if (!**date_string)
    {
      utc = FALSE;
      offset_minutes = 0;
    }
  else if (**date_string == '+' || **date_string == '-')
    {
      gulong val;
      int sign = (**date_string == '+') ? 1 : -1;
      val = strtoul (*date_string + 1, (char **)date_string, 10);
      if (**date_string == ':')
        val = 60 * val + strtoul (*date_string + 1, (char **)date_string, 10);
      else
        val =  60 * (val / 100) + (val % 100);
      offset_minutes = sign * val;
      utc = (sign == -1) && !val;
    }
  else if (**date_string == 'Z')
    {
      offset_minutes = 0;
      utc = TRUE;
      (*date_string)++;
    }
  else if (!strcmp (*date_string, "GMT") ||
           !strcmp (*date_string, "UTC"))
    {
      offset_minutes = 0;
      utc = TRUE;
      (*date_string) += 3;
    }
  else if (strchr ("ECMP", **date_string) &&
           ((*date_string)[1] == 'D' || (*date_string)[1] == 'S') &&
           (*date_string)[2] == 'T') {
    offset_minutes = -60 * (5 * strcspn ("ECMP", *date_string));
    if ((*date_string)[1] == 'D')
      offset_minutes += 60;
    utc = FALSE;
  }
  else
    return FALSE;

  if (utc)
    *timezone_out = g_time_zone_new_utc ();
  else
    *timezone_out = time_zone_new_offset (offset_minutes * 60);

  return TRUE;
}

GDateTime *
flatpak_parse_http_time (const char *date_string)
{
  int month, day, year, hour, minute, second;
  g_autoptr(GTimeZone) tz = NULL;

  g_return_val_if_fail (date_string != NULL, NULL);

  while (g_ascii_isspace (*date_string))
    date_string++;

  /* If it starts with a word, it must be a weekday, which we skip */
  if (g_ascii_isalpha (*date_string))
    {
      while (g_ascii_isalpha (*date_string))
        date_string++;
      if (*date_string == ',')
        date_string++;
      while (g_ascii_isspace (*date_string))
        date_string++;
    }

  /* If there's now another word, this must be an asctime-date */
  if (g_ascii_isalpha (*date_string))
    {
      /* (Sun) Nov  6 08:49:37 1994 */
      if (!parse_month (&month, &date_string) ||
          !parse_day (&day, &date_string) ||
          !parse_time (&hour, &minute, &second, &date_string) ||
          !parse_year (&year, &date_string))
        return NULL;

      /* There shouldn't be a timezone, but check anyway */
      parse_timezone (&tz, &date_string);
    }
  else
    {
      /* Non-asctime date, so some variation of
       * (Sun,) 06 Nov 1994 08:49:37 GMT
       */
      if (!parse_day (&day, &date_string) ||
          !parse_month (&month, &date_string) ||
          !parse_year (&year, &date_string) ||
          !parse_time (&hour, &minute, &second, &date_string))
        return NULL;

      /* This time there *should* be a timezone, but we
       * survive if there isn't.
       */
      parse_timezone (&tz, &date_string);
    }

  if (!tz)
    tz = g_time_zone_new_utc ();

  return g_date_time_new (tz, year, month, day, hour, minute, second);
}

===== ./common/flatpak-related-ref.h =====
/*
 * Copyright © 2015 Red Hat, Inc
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Alexander Larsson <alexl@redhat.com>
 */

#if !defined(__FLATPAK_H_INSIDE__) && !defined(FLATPAK_COMPILATION)
#error "Only <flatpak.h> can be included directly."
#endif

#ifndef __FLATPAK_RELATED_REF_H__
#define __FLATPAK_RELATED_REF_H__

typedef struct _FlatpakRelatedRef FlatpakRelatedRef;

#include <gio/gio.h>
#include <flatpak-ref.h>

G_BEGIN_DECLS

#define FLATPAK_TYPE_RELATED_REF flatpak_related_ref_get_type ()
#define FLATPAK_RELATED_REF(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), FLATPAK_TYPE_RELATED_REF, FlatpakRelatedRef))
#define FLATPAK_IS_RELATED_REF(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), FLATPAK_TYPE_RELATED_REF))

FLATPAK_EXTERN GType flatpak_related_ref_get_type (void);

struct _FlatpakRelatedRef
{
  FlatpakRef parent;
};

typedef struct
{
  FlatpakRefClass parent_class;
} FlatpakRelatedRefClass;

#ifdef G_DEFINE_AUTOPTR_CLEANUP_FUNC
G_DEFINE_AUTOPTR_CLEANUP_FUNC (FlatpakRelatedRef, g_object_unref)
#endif

FLATPAK_EXTERN const char * const *flatpak_related_ref_get_subpaths (FlatpakRelatedRef * self);
FLATPAK_EXTERN gboolean     flatpak_related_ref_should_download (FlatpakRelatedRef *self);
FLATPAK_EXTERN gboolean     flatpak_related_ref_should_delete (FlatpakRelatedRef *self);
FLATPAK_EXTERN gboolean     flatpak_related_ref_should_autoprune (FlatpakRelatedRef *self);

G_END_DECLS

#endif /* __FLATPAK_RELATED_REF_H__ */

===== ./common/flatpak-ref.h =====
/*
 * Copyright © 2015 Red Hat, Inc
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Alexander Larsson <alexl@redhat.com>
 */

#if !defined(__FLATPAK_H_INSIDE__) && !defined(FLATPAK_COMPILATION)
#error "Only <flatpak.h> can be included directly."
#endif

#ifndef __FLATPAK_REF_H__
#define __FLATPAK_REF_H__

typedef struct _FlatpakRef FlatpakRef;

#include <glib-object.h>

G_BEGIN_DECLS

#define FLATPAK_TYPE_REF flatpak_ref_get_type ()
#define FLATPAK_REF(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), FLATPAK_TYPE_REF, FlatpakRef))
#define FLATPAK_IS_REF(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), FLATPAK_TYPE_REF))

FLATPAK_EXTERN GType flatpak_ref_get_type (void);

struct _FlatpakRef
{
  GObject parent;
};

typedef struct
{
  GObjectClass parent_class;
} FlatpakRefClass;


#ifdef G_DEFINE_AUTOPTR_CLEANUP_FUNC
G_DEFINE_AUTOPTR_CLEANUP_FUNC (FlatpakRef, g_object_unref)
#endif

/**
 * FlatpakRefKind:
 * @FLATPAK_REF_KIND_APP: An application
 * @FLATPAK_REF_KIND_RUNTIME: A runtime that applications can use.
 *
 * The kind of artifact that a FlatpakRef refers to.
 */
typedef enum {
  FLATPAK_REF_KIND_APP,
  FLATPAK_REF_KIND_RUNTIME,
} FlatpakRefKind;

FLATPAK_EXTERN const char *  flatpak_ref_get_name (FlatpakRef *self);
FLATPAK_EXTERN const char *  flatpak_ref_get_arch (FlatpakRef *self);
FLATPAK_EXTERN const char *  flatpak_ref_get_branch (FlatpakRef *self);
FLATPAK_EXTERN const char *  flatpak_ref_get_commit (FlatpakRef *self);
FLATPAK_EXTERN FlatpakRefKind flatpak_ref_get_kind (FlatpakRef *self);
FLATPAK_EXTERN char *        flatpak_ref_format_ref (FlatpakRef *self);
FLATPAK_EXTERN const char *   flatpak_ref_format_ref_cached (FlatpakRef *self);
FLATPAK_EXTERN FlatpakRef *   flatpak_ref_parse (const char *ref,
                                                 GError    **error);
FLATPAK_EXTERN const char *   flatpak_ref_get_collection_id (FlatpakRef *self);

G_END_DECLS

#endif /* __FLATPAK_REF_H__ */

===== ./common/flatpak-json-oci.c =====
/* vi:set et sw=2 sts=2 cin cino=t0,f0,(0,{s,>2s,n-s,^-s,e-s:
 * Copyright (C) 2015 Red Hat, Inc
 *
 * This file 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 of the
 * License, or (at your option) any later version.
 *
 * This file 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 program.  If not, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Alexander Larsson <alexl@redhat.com>
 */

#include "config.h"
#include "string.h"

#include "flatpak-json-oci-private.h"

#include <ostree.h>

#include "flatpak-utils-private.h"
#include "libglnx.h"

const char *
flatpak_arch_to_oci_arch (const char *flatpak_arch)
{
  if (strcmp (flatpak_arch, "x86_64") == 0)
    return "amd64";
  if (strcmp (flatpak_arch, "aarch64") == 0)
    return "arm64";
  if (strcmp (flatpak_arch, "i386") == 0)
    return "386";
  return flatpak_arch;
}

FlatpakOciDescriptor *
flatpak_oci_descriptor_new (const char *mediatype,
                            const char *digest,
                            gint64      size)
{
  FlatpakOciDescriptor *desc = g_new0 (FlatpakOciDescriptor, 1);

  desc->mediatype = g_strdup (mediatype);
  desc->digest = g_strdup (digest);
  desc->size = size;
  desc->annotations = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);

  return desc;
}

void
flatpak_oci_descriptor_copy (FlatpakOciDescriptor *source,
                             FlatpakOciDescriptor *dest)
{
  flatpak_oci_descriptor_destroy (dest);

  dest->mediatype = g_strdup (source->mediatype);
  dest->digest = g_strdup (source->digest);
  dest->size = source->size;
  dest->urls = g_strdupv ((char **) source->urls);
  dest->annotations = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
  if (source->annotations)
    flatpak_oci_copy_labels (source->annotations, dest->annotations);
}

void
flatpak_oci_descriptor_destroy (FlatpakOciDescriptor *self)
{
  g_free (self->mediatype);
  g_free (self->digest);
  g_strfreev (self->urls);
  if (self->annotations)
    g_hash_table_destroy (self->annotations);
}

void
flatpak_oci_descriptor_free (FlatpakOciDescriptor *self)
{
  flatpak_oci_descriptor_destroy (self);
  g_free (self);
}

static FlatpakJsonProp flatpak_oci_descriptor_props[] = {
  FLATPAK_JSON_STRING_PROP (FlatpakOciDescriptor, mediatype, "mediaType"),
  FLATPAK_JSON_STRING_PROP (FlatpakOciDescriptor, digest, "digest"),
  FLATPAK_JSON_INT64_PROP (FlatpakOciDescriptor, size, "size"),
  FLATPAK_JSON_STRV_PROP (FlatpakOciDescriptor, urls, "urls"),
  FLATPAK_JSON_STRMAP_PROP (FlatpakOciDescriptor, annotations, "annotations"),
  FLATPAK_JSON_LAST_PROP
};

static void
flatpak_oci_manifest_platform_destroy (FlatpakOciManifestPlatform *self)
{
  g_free (self->architecture);
  g_free (self->os);
  g_free (self->os_version);
  g_strfreev (self->os_features);
  g_free (self->variant);
  g_strfreev (self->features);
}

FlatpakOciManifestDescriptor *
flatpak_oci_manifest_descriptor_new (void)
{
  return g_new0 (FlatpakOciManifestDescriptor, 1);
}

void
flatpak_oci_manifest_descriptor_destroy (FlatpakOciManifestDescriptor *self)
{
  flatpak_oci_manifest_platform_destroy (&self->platform);
  flatpak_oci_descriptor_destroy (&self->parent);
}

void
flatpak_oci_manifest_descriptor_free (FlatpakOciManifestDescriptor *self)
{
  flatpak_oci_manifest_descriptor_destroy (self);
  g_free (self);
}

static FlatpakJsonProp flatpak_oci_manifest_platform_props[] = {
  FLATPAK_JSON_STRING_PROP (FlatpakOciManifestPlatform, architecture, "architecture"),
  FLATPAK_JSON_STRING_PROP (FlatpakOciManifestPlatform, os, "os"),
  FLATPAK_JSON_STRING_PROP (FlatpakOciManifestPlatform, os_version, "os.version"),
  FLATPAK_JSON_STRING_PROP (FlatpakOciManifestPlatform, variant, "variant"),
  FLATPAK_JSON_STRV_PROP (FlatpakOciManifestPlatform, os_features, "os.features"),
  FLATPAK_JSON_STRV_PROP (FlatpakOciManifestPlatform, features, "features"),
  FLATPAK_JSON_LAST_PROP
};
static FlatpakJsonProp flatpak_oci_manifest_descriptor_props[] = {
  FLATPAK_JSON_PARENT_PROP (FlatpakOciManifestDescriptor, parent, flatpak_oci_descriptor_props),
  FLATPAK_JSON_OPT_STRUCT_PROP (FlatpakOciManifestDescriptor, platform, "platform", flatpak_oci_manifest_platform_props),
  FLATPAK_JSON_LAST_PROP
};


G_DEFINE_TYPE (FlatpakOciVersioned, flatpak_oci_versioned, FLATPAK_TYPE_JSON);

static void
flatpak_oci_versioned_finalize (GObject *object)
{
  FlatpakOciVersioned *self = FLATPAK_OCI_VERSIONED (object);

  g_free (self->mediatype);

  G_OBJECT_CLASS (flatpak_oci_versioned_parent_class)->finalize (object);
}

static void
flatpak_oci_versioned_class_init (FlatpakOciVersionedClass *klass)
{
  GObjectClass *object_class = G_OBJECT_CLASS (klass);
  FlatpakJsonClass *json_class = FLATPAK_JSON_CLASS (klass);
  static FlatpakJsonProp props[] = {
    FLATPAK_JSON_INT64_PROP (FlatpakOciVersioned, version, "schemaVersion"),
    FLATPAK_JSON_STRING_PROP (FlatpakOciVersioned, mediatype, "mediaType"),
    FLATPAK_JSON_LAST_PROP
  };

  object_class->finalize = flatpak_oci_versioned_finalize;
  json_class->props = props;
}

static void
flatpak_oci_versioned_init (FlatpakOciVersioned *self)
{
}

FlatpakOciVersioned *
flatpak_oci_versioned_from_json (GBytes *bytes,
                                 const char *content_type,
                                 GError **error)
{
  g_autoptr(JsonParser) parser = NULL;
  JsonNode *root = NULL;
  const gchar *mediatype = NULL;
  JsonObject *object;

  parser = json_parser_new ();
  if (!json_parser_load_from_data (parser,
                                   g_bytes_get_data (bytes, NULL),
                                   g_bytes_get_size (bytes),
                                   error))
    return NULL;

  root = json_parser_get_root (parser);
  object = json_node_get_object (root);

  if (json_object_has_member (object, "mediaType"))
    mediatype = json_object_get_string_member (object, "mediaType");
  else
    mediatype = content_type;

  if (mediatype == NULL)
    {
      g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
                   "Versioned object lacks mediatype");
      return NULL;
    }

  /* The docker v2 image manifest is similar enough that we can just load it, it does not have the annotation field though */
  if (strcmp (mediatype, FLATPAK_OCI_MEDIA_TYPE_IMAGE_MANIFEST) == 0 ||
      strcmp (mediatype, FLATPAK_DOCKER_MEDIA_TYPE_IMAGE_MANIFEST2) == 0)
    return (FlatpakOciVersioned *) flatpak_json_from_node (root, FLATPAK_TYPE_OCI_MANIFEST, error);

  if (strcmp (mediatype, FLATPAK_OCI_MEDIA_TYPE_IMAGE_INDEX) == 0)
    return (FlatpakOciVersioned *) flatpak_json_from_node (root, FLATPAK_TYPE_OCI_INDEX, error);

  g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
               "Unsupported media type %s", mediatype);
  return NULL;
}

FlatpakOciImage *
flatpak_oci_image_from_json (GBytes *bytes,
                             GError **error)
{
  g_autoptr(JsonParser) parser = NULL;
  JsonNode *root = NULL;

  parser = json_parser_new ();
  if (!json_parser_load_from_data (parser,
                                   g_bytes_get_data (bytes, NULL),
                                   g_bytes_get_size (bytes),
                                   error))
    return NULL;

  root = json_parser_get_root (parser);

  return (FlatpakOciImage *) flatpak_json_from_node (root, FLATPAK_TYPE_OCI_IMAGE, error);
}


const char *
flatpak_oci_versioned_get_mediatype (FlatpakOciVersioned *self)
{
  return self->mediatype;
}

gint64
flatpak_oci_versioned_get_version (FlatpakOciVersioned *self)
{
  return self->version;
}

G_DEFINE_TYPE (FlatpakOciManifest, flatpak_oci_manifest, FLATPAK_TYPE_OCI_VERSIONED);

static void
flatpak_oci_manifest_finalize (GObject *object)
{
  FlatpakOciManifest *self = (FlatpakOciManifest *) object;
  int i;

  for (i = 0; self->layers != NULL && self->layers[i] != NULL; i++)
    flatpak_oci_descriptor_free (self->layers[i]);
  g_free (self->layers);
  flatpak_oci_descriptor_destroy (&self->config);
  if (self->annotations)
    g_hash_table_destroy (self->annotations);

  G_OBJECT_CLASS (flatpak_oci_manifest_parent_class)->finalize (object);
}

static void
flatpak_oci_manifest_class_init (FlatpakOciManifestClass *klass)
{
  GObjectClass *object_class = G_OBJECT_CLASS (klass);
  FlatpakJsonClass *json_class = FLATPAK_JSON_CLASS (klass);
  static FlatpakJsonProp props[] = {
    FLATPAK_JSON_STRUCT_PROP (FlatpakOciManifest, config, "config", flatpak_oci_descriptor_props),
    FLATPAK_JSON_STRUCTV_PROP (FlatpakOciManifest, layers, "layers", flatpak_oci_descriptor_props),
    FLATPAK_JSON_STRMAP_PROP (FlatpakOciManifest, annotations, "annotations"),
    FLATPAK_JSON_LAST_PROP
  };

  object_class->finalize = flatpak_oci_manifest_finalize;
  json_class->props = props;
  json_class->mediatype = FLATPAK_OCI_MEDIA_TYPE_IMAGE_MANIFEST;
}

static void
flatpak_oci_manifest_init (FlatpakOciManifest *self)
{
}

FlatpakOciManifest *
flatpak_oci_manifest_new (void)
{
  FlatpakOciManifest *manifest;

  manifest = g_object_new (FLATPAK_TYPE_OCI_MANIFEST, NULL);
  manifest->parent.version = 2;
  manifest->parent.mediatype = g_strdup (FLATPAK_OCI_MEDIA_TYPE_IMAGE_MANIFEST);

  manifest->annotations = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);

  return manifest;
}

void
flatpak_oci_manifest_set_config (FlatpakOciManifest   *self,
                                 FlatpakOciDescriptor *desc)
{
  g_free (self->config.mediatype);
  self->config.mediatype = g_strdup (desc->mediatype);
  g_free (self->config.digest);
  self->config.digest = g_strdup (desc->digest);
  self->config.size = desc->size;
}

static int
ptrv_count (gpointer *ptrs)
{
  int count;

  for (count = 0; ptrs != NULL && ptrs[count] != NULL; count++)
    ;

  return count;
}

void
flatpak_oci_manifest_set_layer (FlatpakOciManifest   *self,
                                FlatpakOciDescriptor *desc)
{
  FlatpakOciDescriptor *descs[2] = { desc, NULL };

  flatpak_oci_manifest_set_layers (self, descs);
}

void
flatpak_oci_manifest_set_layers (FlatpakOciManifest    *self,
                                 FlatpakOciDescriptor **descs)
{
  int i, count;

  for (i = 0; self->layers != NULL && self->layers[i] != NULL; i++)
    flatpak_oci_descriptor_free (self->layers[i]);
  g_free (self->layers);

  count = ptrv_count ((gpointer *) descs);

  self->layers = g_new0 (FlatpakOciDescriptor *, count + 1);
  for (i = 0; i < count; i++)
    {
      self->layers[i] = g_new0 (FlatpakOciDescriptor, 1);
      self->layers[i]->mediatype = g_strdup (descs[i]->mediatype);
      self->layers[i]->digest = g_strdup (descs[i]->digest);
      self->layers[i]->size = descs[i]->size;
    }
}

int
flatpak_oci_manifest_get_n_layers (FlatpakOciManifest *self)
{
  return ptrv_count ((gpointer *) self->layers);
}

const char *
flatpak_oci_manifest_get_layer_digest (FlatpakOciManifest *self,
                                       int                 i)
{
  return self->layers[i]->digest;
}

GHashTable *
flatpak_oci_manifest_get_annotations (FlatpakOciManifest *self)
{
  return self->annotations;
}

FlatpakOciDescriptor *
flatpak_oci_manifest_find_delta_for (FlatpakOciManifest *delta_manifest,
                                     const char         *from_diffid,
                                     const char         *to_diffid)
{
  int i;

  if (from_diffid == NULL || to_diffid == NULL)
    return NULL;

  for (i = 0; delta_manifest->layers != NULL && delta_manifest->layers[i] != NULL; i++)
    {
      FlatpakOciDescriptor *layer = delta_manifest->layers[i];
      const char *layer_from = NULL, *layer_to = NULL;

      if (layer->annotations != NULL)
        {
          layer_from = g_hash_table_lookup (layer->annotations, "io.github.containers.delta.from");
          layer_to = g_hash_table_lookup (layer->annotations, "io.github.containers.delta.to");

          if (g_strcmp0 (layer_from, from_diffid) == 0 &&
              g_strcmp0 (layer_to, to_diffid) == 0)
            return layer;
        }
    }

  return NULL;
}


G_DEFINE_TYPE (FlatpakOciIndex, flatpak_oci_index, FLATPAK_TYPE_OCI_VERSIONED);

static void
flatpak_oci_index_finalize (GObject *object)
{
  FlatpakOciIndex *self = (FlatpakOciIndex *) object;
  int i;

  for (i = 0; self->manifests != NULL && self->manifests[i] != NULL; i++)
    flatpak_oci_manifest_descriptor_free (self->manifests[i]);
  g_free (self->manifests);

  if (self->annotations)
    g_hash_table_destroy (self->annotations);

  G_OBJECT_CLASS (flatpak_oci_index_parent_class)->finalize (object);
}


static void
flatpak_oci_index_class_init (FlatpakOciIndexClass *klass)
{
  GObjectClass *object_class = G_OBJECT_CLASS (klass);
  FlatpakJsonClass *json_class = FLATPAK_JSON_CLASS (klass);
  static FlatpakJsonProp props[] = {
    FLATPAK_JSON_STRUCTV_PROP (FlatpakOciIndex, manifests, "manifests", flatpak_oci_manifest_descriptor_props),
    FLATPAK_JSON_STRMAP_PROP (FlatpakOciIndex, annotations, "annotations"),
    FLATPAK_JSON_LAST_PROP
  };

  object_class->finalize = flatpak_oci_index_finalize;
  json_class->props = props;
  json_class->mediatype = FLATPAK_OCI_MEDIA_TYPE_IMAGE_INDEX;
}

static void
flatpak_oci_index_init (FlatpakOciIndex *self)
{
}

FlatpakOciIndex *
flatpak_oci_index_new (void)
{
  FlatpakOciIndex *index;

  index = g_object_new (FLATPAK_TYPE_OCI_INDEX, NULL);

  index->parent.version = 2;
  index->parent.mediatype = g_strdup (FLATPAK_OCI_MEDIA_TYPE_IMAGE_INDEX);
  index->annotations = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);

  return index;
}

static FlatpakOciManifestDescriptor *
manifest_desc_for_desc (FlatpakOciDescriptor *src_descriptor, const char *ref)
{
  FlatpakOciManifestDescriptor *desc;

  desc = flatpak_oci_manifest_descriptor_new ();
  flatpak_oci_descriptor_copy (src_descriptor, &desc->parent);

  g_hash_table_replace (desc->parent.annotations,
                        g_strdup ("org.opencontainers.image.ref.name"),
                        g_strdup (ref));
  return desc;
}

int
flatpak_oci_index_get_n_manifests (FlatpakOciIndex *self)
{
  return ptrv_count ((gpointer *) self->manifests);
}

void
flatpak_oci_index_add_manifest (FlatpakOciIndex      *self,
                                const char           *ref,
                                FlatpakOciDescriptor *desc)
{
  FlatpakOciManifestDescriptor *m;
  int count;

  if (ref != NULL)
    flatpak_oci_index_remove_manifest (self, ref);

  count = flatpak_oci_index_get_n_manifests (self);

  m = manifest_desc_for_desc (desc, ref);
  self->manifests = g_renew (FlatpakOciManifestDescriptor *, self->manifests, count + 2);
  self->manifests[count] = m;
  self->manifests[count + 1] = NULL;
}

const char *
flatpak_oci_manifest_descriptor_get_ref (FlatpakOciManifestDescriptor *m)
{
  if (m->parent.mediatype == NULL ||
      (strcmp (m->parent.mediatype, FLATPAK_OCI_MEDIA_TYPE_IMAGE_MANIFEST) != 0 &&
       strcmp (m->parent.mediatype, FLATPAK_DOCKER_MEDIA_TYPE_IMAGE_MANIFEST2) != 0))
    return NULL;

  if (m->parent.annotations == NULL)
    return NULL;

  return g_hash_table_lookup (m->parent.annotations, "org.opencontainers.image.ref.name");
}

static int
index_find_ref (FlatpakOciIndex *self,
                const char      *ref)
{
  int i;

  if (self->manifests == NULL)
    return -1;

  for (i = 0; self->manifests[i] != NULL; i++)
    {
      const char *m_ref = flatpak_oci_manifest_descriptor_get_ref (self->manifests[i]);

      if (m_ref == NULL)
        continue;

      if (strcmp (ref, m_ref) == 0)
        return i;
    }

  return -1;
}

FlatpakOciManifestDescriptor *
flatpak_oci_index_get_manifest (FlatpakOciIndex *self,
                                const char      *ref)
{
  int i = index_find_ref (self, ref);

  if (i >= 0)
    return self->manifests[i];

  return NULL;
}

FlatpakOciManifestDescriptor *
flatpak_oci_index_get_only_manifest (FlatpakOciIndex *self)
{
  FlatpakOciManifestDescriptor *manifest = NULL;

  if (self->manifests == NULL)
    return NULL;

  for (size_t i = 0; self->manifests[i] != NULL; i++)
    {
      FlatpakOciManifestDescriptor *m = self->manifests[i];

      if (m->parent.mediatype == NULL ||
          (strcmp (m->parent.mediatype, FLATPAK_OCI_MEDIA_TYPE_IMAGE_MANIFEST) != 0 &&
           strcmp (m->parent.mediatype, FLATPAK_DOCKER_MEDIA_TYPE_IMAGE_MANIFEST2) != 0))
        continue;

      /* multiple manifests */
      if (manifest != NULL)
        return NULL;

      manifest = m;
    }

  return manifest;
}

FlatpakOciManifestDescriptor *
flatpak_oci_index_get_manifest_for_arch (FlatpakOciIndex *self,
                                         const char      *oci_arch)
{
  int i, found = -1;

  if (self->manifests == NULL)
    return NULL;

  for (i = 0; self->manifests[i] != NULL; i++)
    {
      if (strcmp (self->manifests[i]->platform.architecture, oci_arch) == 0)
        return self->manifests[i];
    }

  if (found >= 0)
    return self->manifests[found];

  return NULL;
}

gboolean
flatpak_oci_index_remove_manifest (FlatpakOciIndex *self,
                                   const char      *ref)
{
  int i = index_find_ref (self, ref);

  if (i < 0)
    return FALSE;

  flatpak_oci_manifest_descriptor_free (self->manifests[i]);

  for (; self->manifests[i] != NULL; i++)
    self->manifests[i] = self->manifests[i + 1];

  return TRUE;
}

FlatpakOciDescriptor *
flatpak_oci_index_find_delta_for (FlatpakOciIndex *delta_index,
                                  const char      *for_digest)
{
  int i;

  if (delta_index->manifests == NULL)
    return NULL;

  for (i = 0; delta_index->manifests[i] != NULL; i++)
    {
      FlatpakOciManifestDescriptor *d = delta_index->manifests[i];
      const char *target;

      if (d->parent.annotations == NULL)
        continue;

      target = g_hash_table_lookup (d->parent.annotations, "io.github.containers.delta.target");
      if (g_strcmp0 (target, for_digest) == 0)
        return &d->parent;
    }

  return NULL;
}

G_DEFINE_TYPE (FlatpakOciImage, flatpak_oci_image, FLATPAK_TYPE_JSON);

static void
flatpak_oci_image_rootfs_destroy (FlatpakOciImageRootfs *self)
{
  g_free (self->type);
  g_strfreev (self->diff_ids);
}

static void
flatpak_oci_image_config_destroy (FlatpakOciImageConfig *self)
{
  g_free (self->user);
  g_free (self->working_dir);
  g_strfreev (self->env);
  g_strfreev (self->cmd);
  g_strfreev (self->entrypoint);
  g_strfreev (self->exposed_ports);
  g_strfreev (self->volumes);
  if (self->labels)
    g_hash_table_destroy (self->labels);
}

static void
flatpak_oci_image_history_free (FlatpakOciImageHistory *self)
{
  g_free (self->created);
  g_free (self->created_by);
  g_free (self->author);
  g_free (self->comment);
  g_free (self);
}

static void
flatpak_oci_image_finalize (GObject *object)
{
  FlatpakOciImage *self = (FlatpakOciImage *) object;
  int i;

  g_free (self->created);
  g_free (self->author);
  g_free (self->architecture);
  g_free (self->os);
  flatpak_oci_image_rootfs_destroy (&self->rootfs);
  flatpak_oci_image_config_destroy (&self->config);

  for (i = 0; self->history != NULL && self->history[i] != NULL; i++)
    flatpak_oci_image_history_free (self->history[i]);
  g_free (self->history);

  G_OBJECT_CLASS (flatpak_oci_image_parent_class)->finalize (object);
}

static void
flatpak_oci_image_class_init (FlatpakOciImageClass *klass)
{
  GObjectClass *object_class = G_OBJECT_CLASS (klass);
  FlatpakJsonClass *json_class = FLATPAK_JSON_CLASS (klass);
  static FlatpakJsonProp config_props[] = {
    FLATPAK_JSON_STRING_PROP (FlatpakOciImageConfig, user, "User"),
    FLATPAK_JSON_INT64_PROP (FlatpakOciImageConfig, memory, "Memory"),
    FLATPAK_JSON_INT64_PROP (FlatpakOciImageConfig, memory_swap, "MemorySwap"),
    FLATPAK_JSON_INT64_PROP (FlatpakOciImageConfig, cpu_shares, "CpuShares"),
    FLATPAK_JSON_BOOLMAP_PROP (FlatpakOciImageConfig, exposed_ports, "ExposedPorts"),
    FLATPAK_JSON_STRV_PROP (FlatpakOciImageConfig, env, "Env"),
    FLATPAK_JSON_STRV_PROP (FlatpakOciImageConfig, entrypoint, "Entrypoint"),
    FLATPAK_JSON_STRV_PROP (FlatpakOciImageConfig, cmd, "Cmd"),
    FLATPAK_JSON_BOOLMAP_PROP (FlatpakOciImageConfig, volumes, "Volumes"),
    FLATPAK_JSON_STRING_PROP (FlatpakOciImageConfig, working_dir, "WorkingDir"),
    FLATPAK_JSON_STRMAP_PROP (FlatpakOciImageConfig, labels, "Labels"),
    FLATPAK_JSON_LAST_PROP
  };
  static FlatpakJsonProp rootfs_props[] = {
    FLATPAK_JSON_STRING_PROP (FlatpakOciImageRootfs, type, "type"),
    FLATPAK_JSON_STRV_PROP (FlatpakOciImageRootfs, diff_ids, "diff_ids"),
    FLATPAK_JSON_LAST_PROP
  };
  static FlatpakJsonProp history_props[] = {
    FLATPAK_JSON_STRING_PROP (FlatpakOciImageHistory, created, "created"),
    FLATPAK_JSON_STRING_PROP (FlatpakOciImageHistory, created_by, "created_by"),
    FLATPAK_JSON_STRING_PROP (FlatpakOciImageHistory, author, "author"),
    FLATPAK_JSON_STRING_PROP (FlatpakOciImageHistory, comment, "comment"),
    FLATPAK_JSON_BOOL_PROP (FlatpakOciImageHistory, empty_layer, "empty_layer"),
    FLATPAK_JSON_LAST_PROP
  };
  static FlatpakJsonProp props[] = {
    FLATPAK_JSON_STRING_PROP (FlatpakOciImage, created, "created"),
    FLATPAK_JSON_STRING_PROP (FlatpakOciImage, author, "author"),
    FLATPAK_JSON_STRING_PROP (FlatpakOciImage, architecture, "architecture"),
    FLATPAK_JSON_STRING_PROP (FlatpakOciImage, os, "os"),
    FLATPAK_JSON_STRUCT_PROP (FlatpakOciImage, config, "config", config_props),
    FLATPAK_JSON_STRUCT_PROP (FlatpakOciImage, rootfs, "rootfs", rootfs_props),
    FLATPAK_JSON_STRUCTV_PROP (FlatpakOciImage, history, "history", history_props),
    FLATPAK_JSON_LAST_PROP
  };

  object_class->finalize = flatpak_oci_image_finalize;
  json_class->props = props;
  json_class->mediatype = FLATPAK_OCI_MEDIA_TYPE_IMAGE_CONFIG;
}

static void
flatpak_oci_image_init (FlatpakOciImage *self)
{
}

FlatpakOciImage *
flatpak_oci_image_new (void)
{
  FlatpakOciImage *image;
  GTimeVal stamp;

  stamp.tv_sec = time (NULL);
  stamp.tv_usec = 0;

  image = g_object_new (FLATPAK_TYPE_OCI_IMAGE, NULL);

  /* Some default values */
  image->created = g_time_val_to_iso8601 (&stamp);
  image->architecture = g_strdup ("arm64");
  image->os = g_strdup ("linux");

  image->rootfs.type = g_strdup ("layers");
  image->rootfs.diff_ids = g_new0 (char *, 1);

  return image;
}

void
flatpak_oci_image_set_created (FlatpakOciImage *image,
                               const char      *created)
{
  g_free (image->created);
  image->created = g_strdup (created);
}

void
flatpak_oci_image_set_architecture (FlatpakOciImage *image,
                                    const char      *arch)
{
  g_free (image->architecture);
  image->architecture = g_strdup (arch);
}

void
flatpak_oci_image_set_os (FlatpakOciImage *image,
                          const char      *os)
{
  g_free (image->os);
  image->os = g_strdup (os);
}

void
flatpak_oci_image_set_layers (FlatpakOciImage *image,
                              const char     **layers)
{
  g_strfreev (image->rootfs.diff_ids);
  image->rootfs.diff_ids = g_strdupv ((char **) layers);
}

int
flatpak_oci_image_get_n_layers (FlatpakOciImage *image)
{
  return ptrv_count ((gpointer *) image->rootfs.diff_ids);
}

GHashTable *
flatpak_oci_image_get_labels (FlatpakOciImage *self)
{
  if (self->config.labels == NULL)
    self->config.labels = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
  return self->config.labels;
}

void
flatpak_oci_image_set_layer (FlatpakOciImage *image,
                             const char      *layer)
{
  const char *layers[] = {layer, NULL};

  flatpak_oci_image_set_layers (image, layers);
}

void
flatpak_oci_export_labels (GHashTable *source,
                           GHashTable *dest)
{
  const char *keys[] = {
    "org.flatpak.ref",
    "org.flatpak.installed-size",
    "org.flatpak.download-size",
    "org.flatpak.metadata",
  };
  int i;

  if (source == NULL)
    return;

  for (i = 0; i < G_N_ELEMENTS (keys); i++)
    {
      const char *key = keys[i];
      const char *value = g_hash_table_lookup (source, key);
      if (value)
        g_hash_table_replace (dest,
                              g_strdup (key),
                              g_strdup (value));
    }
}

void
flatpak_oci_copy_labels (GHashTable *source,
                         GHashTable *dest)
{
  GHashTableIter iter;
  gpointer key, value;

  g_hash_table_iter_init (&iter, source);
  while (g_hash_table_iter_next (&iter, &key, &value))
    g_hash_table_replace (dest,
                          g_strdup ((char *) key),
                          g_strdup ((char *) value));
}

int
flatpak_oci_image_add_history (FlatpakOciImage *image)
{
  FlatpakOciImageHistory **old;
  int i, index, old_len;

  old = image->history;

  for (old_len = 0; old != NULL && old[old_len] != NULL; old_len++)
    ;

  image->history = g_new0 (FlatpakOciImageHistory *, old_len + 2);
  for (i = 0; i < old_len; i++)
    image->history[i] = old[i];

  index = i;

  image->history[i++] = g_new0 (FlatpakOciImageHistory, 1);
  image->history[i++] = NULL;

  g_free (old);

  return index;
}

static void
add_label (GHashTable *labels, const char *key, const char *value)
{
  g_hash_table_replace (labels,
                        g_strdup (key),
                        g_strdup (value));
}

void
flatpak_oci_add_labels_for_commit (GHashTable *labels,
                                   const char *ref,
                                   const char *commit,
                                   GVariant   *commit_data)
{
  if (ref)
    add_label (labels, "org.flatpak.ref", ref);

  if (commit)
    add_label (labels, "org.flatpak.commit", commit);

  if (commit_data)
    {
      g_autofree char *parent = NULL;
      g_autofree char *subject = NULL;
      g_autofree char *body = NULL;
      g_autofree char *timestamp = NULL;
      g_autoptr(GVariant) metadata = NULL;
      int i;

      parent = ostree_commit_get_parent (commit_data);
      if (parent)
        add_label (labels, "org.flatpak.parent-commit", parent);

      metadata = g_variant_get_child_value (commit_data, 0);
      for (i = 0; i < g_variant_n_children (metadata); i++)
        {
          g_autoptr(GVariant) elm = g_variant_get_child_value (metadata, i);
          g_autoptr(GVariant) value = g_variant_get_child_value (elm, 1);
          g_autofree char *key = NULL;
          g_autofree char *full_key = NULL;
          g_autofree char *value_base64 = NULL;

          g_variant_get_child (elm, 0, "s", &key);
          full_key = g_strdup_printf ("org.flatpak.commit-metadata.%s", key);

          value_base64 = g_base64_encode (g_variant_get_data (value), g_variant_get_size (value));
          add_label (labels, full_key, value_base64);
        }

      timestamp = g_strdup_printf ("%"G_GUINT64_FORMAT, ostree_commit_get_timestamp (commit_data));
      add_label (labels, "org.flatpak.timestamp", timestamp);

      g_variant_get_child (commit_data, 3, "s", &subject);
      add_label (labels, "org.flatpak.subject", subject);

      g_variant_get_child (commit_data, 4, "s", &body);
      add_label (labels, "org.flatpak.body", body);
    }
}


G_DEFINE_TYPE (FlatpakOciSignature, flatpak_oci_signature, FLATPAK_TYPE_JSON);

static void
flatpak_oci_signature_critical_destroy (FlatpakOciSignatureCritical *self)
{
  g_free (self->type);
  g_free (self->image.digest);
  g_free (self->identity.reference);
}

static void
flatpak_oci_signature_optional_destroy (FlatpakOciSignatureOptional *self)
{
  g_free (self->creator);
}

static void
flatpak_oci_signature_finalize (GObject *object)
{
  FlatpakOciSignature *self = (FlatpakOciSignature *) object;

  flatpak_oci_signature_critical_destroy (&self->critical);
  flatpak_oci_signature_optional_destroy (&self->optional);

  G_OBJECT_CLASS (flatpak_oci_signature_parent_class)->finalize (object);
}

static void
flatpak_oci_signature_class_init (FlatpakOciSignatureClass *klass)
{
  GObjectClass *object_class = G_OBJECT_CLASS (klass);
  FlatpakJsonClass *json_class = FLATPAK_JSON_CLASS (klass);
  static FlatpakJsonProp image_props[] = {
    FLATPAK_JSON_MANDATORY_STRING_PROP (FlatpakOciSignatureCriticalImage, digest, "docker-manifest-digest"),
    FLATPAK_JSON_LAST_PROP
  };
  static FlatpakJsonProp identity_props[] = {
    FLATPAK_JSON_MANDATORY_STRING_PROP (FlatpakOciSignatureCriticalIdentity, reference, "docker-reference"),
    FLATPAK_JSON_LAST_PROP
  };
  static FlatpakJsonProp critical_props[] = {
    FLATPAK_JSON_MANDATORY_STRING_PROP (FlatpakOciSignatureCritical, type, "type"),
    FLATPAK_JSON_MANDATORY_STRICT_STRUCT_PROP (FlatpakOciSignatureCritical, image, "image", image_props),
    FLATPAK_JSON_MANDATORY_STRICT_STRUCT_PROP (FlatpakOciSignatureCritical, identity, "identity", identity_props),
    FLATPAK_JSON_LAST_PROP
  };
  static FlatpakJsonProp optional_props[] = {
    FLATPAK_JSON_STRING_PROP (FlatpakOciSignatureOptional, creator, "creator"),
    FLATPAK_JSON_INT64_PROP (FlatpakOciSignatureOptional, timestamp, "timestamp"),
    FLATPAK_JSON_LAST_PROP
  };
  static FlatpakJsonProp props[] = {
    FLATPAK_JSON_MANDATORY_STRICT_STRUCT_PROP (FlatpakOciSignature, critical, "critical", critical_props),
    FLATPAK_JSON_STRUCT_PROP (FlatpakOciSignature, optional, "optional", optional_props),
    FLATPAK_JSON_LAST_PROP
  };

  object_class->finalize = flatpak_oci_signature_finalize;
  json_class->props = props;
}

static void
flatpak_oci_signature_init (FlatpakOciSignature *self)
{
}

G_DEFINE_TYPE (FlatpakOciIndexResponse, flatpak_oci_index_response, FLATPAK_TYPE_JSON);

static void
flatpak_oci_index_image_free (FlatpakOciIndexImage *self)
{
  g_free (self->digest);
  g_free (self->mediatype);
  g_free (self->os);
  g_free (self->architecture);
  g_strfreev (self->tags);
  if (self->annotations)
    g_hash_table_destroy (self->annotations);
  if (self->labels)
    g_hash_table_destroy (self->labels);
  g_free (self);
}

static void
flatpak_oci_index_image_list_free (FlatpakOciIndexImageList *self)
{
  int i;

  g_free (self->digest);
  g_free (self->mediatype);
  g_strfreev (self->tags);
  for (i = 0; self->images != NULL && self->images[i] != NULL; i++)
    flatpak_oci_index_image_free (self->images[i]);
  g_free (self->images);
  g_free (self);
}

static void
flatpak_oci_index_repository_free (FlatpakOciIndexRepository *self)
{
  int i;

  g_free (self->name);
  for (i = 0; self->images != NULL && self->images[i] != NULL; i++)
    flatpak_oci_index_image_free (self->images[i]);
  g_free (self->images);

  for (i = 0; self->lists != NULL && self->lists[i] != NULL; i++)
    flatpak_oci_index_image_list_free (self->lists[i]);
  g_free (self->lists);

  g_free (self);
}

static void
flatpak_oci_index_response_finalize (GObject *object)
{
  FlatpakOciIndexResponse *self = (FlatpakOciIndexResponse *) object;
  int i;

  g_free (self->registry);
  for (i = 0; self->results != NULL && self->results[i] != NULL; i++)
    flatpak_oci_index_repository_free (self->results[i]);
  g_free (self->results);

  G_OBJECT_CLASS (flatpak_oci_index_response_parent_class)->finalize (object);
}

static void
flatpak_oci_index_response_class_init (FlatpakOciIndexResponseClass *klass)
{
  GObjectClass *object_class = G_OBJECT_CLASS (klass);
  FlatpakJsonClass *json_class = FLATPAK_JSON_CLASS (klass);
  static FlatpakJsonProp image_props[] = {
    FLATPAK_JSON_MANDATORY_STRING_PROP (FlatpakOciIndexImage, digest, "Digest"),
    FLATPAK_JSON_MANDATORY_STRING_PROP (FlatpakOciIndexImage, mediatype, "MediaType"),
    FLATPAK_JSON_MANDATORY_STRING_PROP (FlatpakOciIndexImage, os, "OS"),
    FLATPAK_JSON_MANDATORY_STRING_PROP (FlatpakOciIndexImage, architecture, "Architecture"),
    FLATPAK_JSON_STRMAP_PROP (FlatpakOciIndexImage, annotations, "Annotations"),
    FLATPAK_JSON_STRMAP_PROP (FlatpakOciIndexImage, labels, "Labels"),
    FLATPAK_JSON_STRV_PROP (FlatpakOciIndexImage, tags, "Tags"),
    FLATPAK_JSON_LAST_PROP
  };
  static FlatpakJsonProp lists_props[] = {
    FLATPAK_JSON_MANDATORY_STRING_PROP (FlatpakOciIndexImageList, digest, "Digest"),
    FLATPAK_JSON_MANDATORY_STRUCTV_PROP (FlatpakOciIndexImageList, images, "Images", image_props),
    FLATPAK_JSON_MANDATORY_STRING_PROP (FlatpakOciIndexImageList, mediatype, "MediaType"),
    FLATPAK_JSON_STRV_PROP (FlatpakOciIndexImageList, tags, "Tags"),
    FLATPAK_JSON_LAST_PROP
  };
  static FlatpakJsonProp results_props[] = {
    FLATPAK_JSON_MANDATORY_STRING_PROP (FlatpakOciIndexRepository, name, "Name"),
    FLATPAK_JSON_MANDATORY_STRUCTV_PROP (FlatpakOciIndexRepository, images, "Images", image_props),
    FLATPAK_JSON_STRUCTV_PROP (FlatpakOciIndexRepository, lists, "Lists", lists_props),
    FLATPAK_JSON_LAST_PROP
  };
  static FlatpakJsonProp props[] = {
    FLATPAK_JSON_MANDATORY_STRING_PROP (FlatpakOciIndexResponse, registry, "Registry"),
    FLATPAK_JSON_MANDATORY_STRUCTV_PROP (FlatpakOciIndexResponse, results, "Results", results_props),
    FLATPAK_JSON_LAST_PROP
  };

  object_class->finalize = flatpak_oci_index_response_finalize;
  json_class->props = props;
}

static void
flatpak_oci_index_response_init (FlatpakOciIndexResponse *self)
{
}

===== ./common/flatpak-parental-controls.c =====
/* vi:set et sw=2 sts=2 cin cino=t0,f0,(0,{s,>2s,n-s,^-s,e-s:
 * Copyright © 2018 Endless Mobile, Inc.
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Philip Withnall <withnall@endlessm.com>
 */

#include "config.h"

#include <glib.h>
#include <gio/gio.h>
#include <libmalcontent/app-filter.h>

#include "flatpak-parental-controls-private.h"

/*
 * See https://www.freedesktop.org/software/appstream/docs/chap-Metadata.html#tag-content_rating
 * for details of the appstream content rating specification.
 *
 * See https://hughsie.github.io/oars/ for details of OARS. Specifically,
 * https://github.com/hughsie/oars/tree/master/specification/.
 */

/* Convert an appstream <content_attribute/> value to #MctAppFilterOarsValue.
 * https://www.freedesktop.org/software/appstream/docs/chap-Metadata.html#tag-content_rating
 */
static MctAppFilterOarsValue
app_filter_oars_value_from_appdata (const gchar *appdata_value)
{
  g_return_val_if_fail (appdata_value != NULL, MCT_APP_FILTER_OARS_VALUE_UNKNOWN);

  if (g_str_equal (appdata_value, "intense"))
    return MCT_APP_FILTER_OARS_VALUE_INTENSE;
  else if (g_str_equal (appdata_value, "moderate"))
    return MCT_APP_FILTER_OARS_VALUE_MODERATE;
  else if (g_str_equal (appdata_value, "mild"))
    return MCT_APP_FILTER_OARS_VALUE_MILD;
  else if (g_str_equal (appdata_value, "none"))
    return MCT_APP_FILTER_OARS_VALUE_NONE;
  else if (g_str_equal (appdata_value, "unknown"))
    return MCT_APP_FILTER_OARS_VALUE_UNKNOWN;
  else
    return MCT_APP_FILTER_OARS_VALUE_UNKNOWN;
}

static const gchar *
app_filter_oars_value_to_string (MctAppFilterOarsValue oars_value)
{
  switch (oars_value)
    {
    case MCT_APP_FILTER_OARS_VALUE_UNKNOWN: return "unknown";
    case MCT_APP_FILTER_OARS_VALUE_INTENSE: return "intense";
    case MCT_APP_FILTER_OARS_VALUE_MODERATE: return "moderate";
    case MCT_APP_FILTER_OARS_VALUE_MILD: return "mild";
    case MCT_APP_FILTER_OARS_VALUE_NONE: return "none";
    default: return "unknown";
    }
}

/**
 * flatpak_oars_check_rating:
 * @content_rating: (nullable) (transfer none): OARS ratings for the app,
 *    or %NULL if none are known
 * @content_rating_type: (nullable): scheme used in @content_rating, such as
 *    `oars-1.0` or `oars-1.1`, or %NULL if @content_rating is %NULL
 * @filter: user’s parental controls settings
 *
 * Check whether the OARS rating in @content_rating is as, or less, extreme than
 * the user’s preferences in @filter. If so (i.e. if the app is suitable for
 * this user to use), return %TRUE; otherwise return %FALSE.
 *
 * @content_rating may be %NULL if no OARS ratings are provided for the app. If
 * so, we have to assume the most restrictive ratings.
 *
 * Returns: %TRUE if the app is safe to install, %FALSE otherwise
 */
gboolean
flatpak_oars_check_rating (GHashTable   *content_rating,
                           const gchar  *content_rating_type,
                           MctAppFilter *filter)
{
  const gchar * const supported_rating_types[] = { "oars-1.0", "oars-1.1", NULL };
  g_autofree const gchar **oars_sections = mct_app_filter_get_oars_sections (filter);
  MctAppFilterOarsValue default_rating_value;

  if (content_rating_type != NULL &&
      !g_strv_contains (supported_rating_types, content_rating_type))
    return FALSE;

  /* If the app has a <content_rating/> element, even if it has no OARS sections
   * in it, use a default value of `none` for any missing sections. Otherwise,
   * if the app has no <content_rating/> element, use `unknown`. */
  if (content_rating != NULL)
    default_rating_value = MCT_APP_FILTER_OARS_VALUE_NONE;
  else
    default_rating_value = MCT_APP_FILTER_OARS_VALUE_UNKNOWN;

  for (gsize i = 0; oars_sections[i] != NULL; i++)
    {
      MctAppFilterOarsValue rating_value;
      MctAppFilterOarsValue filter_value = mct_app_filter_get_oars_value (filter,
                                                                          oars_sections[i]);
      const gchar *appdata_value = NULL;

      if (content_rating != NULL)
        appdata_value = g_hash_table_lookup (content_rating, oars_sections[i]);

      if (appdata_value != NULL)
        rating_value = app_filter_oars_value_from_appdata (appdata_value);
      else
        rating_value = default_rating_value;

      if (filter_value < rating_value ||
          (rating_value == MCT_APP_FILTER_OARS_VALUE_UNKNOWN &&
           filter_value != MCT_APP_FILTER_OARS_VALUE_UNKNOWN) ||
          (rating_value != MCT_APP_FILTER_OARS_VALUE_UNKNOWN &&
           filter_value == MCT_APP_FILTER_OARS_VALUE_UNKNOWN))
        {
          g_info ("%s: Comparing rating ‘%s’: app has ‘%s’ but policy has ‘%s’ unknown: OARS check failed",
                  G_STRFUNC, oars_sections[i],
                  app_filter_oars_value_to_string (rating_value),
                  app_filter_oars_value_to_string (filter_value));
          return FALSE;
        }
    }

  return TRUE;
}

===== ./common/flatpak-utils-base-private.h =====
/*
 * Copyright © 2019 Red Hat, Inc
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Alexander Larsson <alexl@redhat.com>
 */

#ifndef __FLATPAK_UTILS_BASE_H__
#define __FLATPAK_UTILS_BASE_H__

#include <glib.h>
#include <gio/gio.h>

#ifndef G_DBUS_METHOD_INVOCATION_HANDLED
# define G_DBUS_METHOD_INVOCATION_HANDLED TRUE
# define G_DBUS_METHOD_INVOCATION_UNHANDLED FALSE
#endif

const char * flatpak_get_tzdir (void);

char * flatpak_get_timezone (void);

char * flatpak_readlink (const char *path,
                         GError    **error);
char * flatpak_resolve_link (const char *path,
                             GError    **error);
char * flatpak_realpath (const char  *path,
                         GError     **error);
char * flatpak_canonicalize_filename (const char *path);

#endif /* __FLATPAK_UTILS_BASE_H__ */

===== ./common/flatpak-zstd-decompressor-private.h =====
#ifndef __FLATPAK_ZSTD_DECOMPRESSOR_H__
#define __FLATPAK_ZSTD_DECOMPRESSOR_H__

#include <gio/gio.h>

G_BEGIN_DECLS

#define FLATPAK_TYPE_ZSTD_DECOMPRESSOR flatpak_zstd_decompressor_get_type ()
G_DECLARE_FINAL_TYPE (FlatpakZstdDecompressor,
                      flatpak_zstd_decompressor,
                      FLATPAK, ZSTD_DECOMPRESSOR,
                      GObject)

FlatpakZstdDecompressor *flatpak_zstd_decompressor_new (void);

G_END_DECLS

#endif /* __FLATPAK_ZSTD_DECOMPRESSOR_H__ */

===== ./common/flatpak-json-backports-private.h =====
/*
 * Copyright © 2014-2016 Red Hat, Inc
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 */

#pragma once

#include <json-glib/json-glib.h>

G_BEGIN_DECLS

#if !JSON_CHECK_VERSION (1, 1, 2)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (JsonArray, json_array_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (JsonBuilder, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (JsonGenerator, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (JsonNode, json_node_free)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (JsonObject, json_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (JsonParser, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (JsonPath, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (JsonReader, g_object_unref)
#endif

G_END_DECLS

===== ./common/flatpak-chain-input-stream.c =====
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
 *
 * Copyright (C) 2011 Colin Walters <walters@verbum.org>
 *
 * 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., 59 Temple Place, Suite 330,
 * Boston, MA 02111-1307, USA.
 */

#include "config.h"

#include "flatpak-chain-input-stream-private.h"

enum {
  PROP_0,
  PROP_STREAMS
};

struct _FlatpakChainInputStreamPrivate
{
  GPtrArray *streams;
  guint      index;
};

G_DEFINE_TYPE_WITH_PRIVATE (FlatpakChainInputStream, flatpak_chain_input_stream, G_TYPE_INPUT_STREAM)


static void     flatpak_chain_input_stream_set_property (GObject      *object,
                                                         guint         prop_id,
                                                         const GValue *value,
                                                         GParamSpec   *pspec);
static void     flatpak_chain_input_stream_get_property (GObject    *object,
                                                         guint       prop_id,
                                                         GValue     *value,
                                                         GParamSpec *pspec);
static void     flatpak_chain_input_stream_finalize (GObject *object);
static gssize   flatpak_chain_input_stream_read (GInputStream *stream,
                                                 void         *buffer,
                                                 gsize         count,
                                                 GCancellable *cancellable,
                                                 GError      **error);
static gboolean flatpak_chain_input_stream_close (GInputStream *stream,
                                                  GCancellable *cancellable,
                                                  GError      **error);

static void
flatpak_chain_input_stream_class_init (FlatpakChainInputStreamClass *klass)
{
  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
  GInputStreamClass *stream_class = G_INPUT_STREAM_CLASS (klass);

  gobject_class->get_property = flatpak_chain_input_stream_get_property;
  gobject_class->set_property = flatpak_chain_input_stream_set_property;
  gobject_class->finalize     = flatpak_chain_input_stream_finalize;

  stream_class->read_fn = flatpak_chain_input_stream_read;
  stream_class->close_fn = flatpak_chain_input_stream_close;

  /*
   * FlatpakChainInputStream:streams: (element-type GInputStream)
   *
   * Chain of input streams read in order.
   */
  g_object_class_install_property (gobject_class,
                                   PROP_STREAMS,
                                   g_param_spec_pointer ("streams",
                                                         "", "",
                                                         G_PARAM_READWRITE |
                                                         G_PARAM_CONSTRUCT_ONLY |
                                                         G_PARAM_STATIC_STRINGS));
}

static void
flatpak_chain_input_stream_set_property (GObject      *object,
                                         guint         prop_id,
                                         const GValue *value,
                                         GParamSpec   *pspec)
{
  FlatpakChainInputStream *self;
  FlatpakChainInputStreamPrivate *priv;

  self = FLATPAK_CHAIN_INPUT_STREAM (object);
  priv = flatpak_chain_input_stream_get_instance_private (self);

  switch (prop_id)
    {
    case PROP_STREAMS:
      priv->streams = g_ptr_array_ref (g_value_get_pointer (value));
      break;

    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
    }
}

static void
flatpak_chain_input_stream_get_property (GObject    *object,
                                         guint       prop_id,
                                         GValue     *value,
                                         GParamSpec *pspec)
{
  FlatpakChainInputStream *self;
  FlatpakChainInputStreamPrivate *priv;

  self = FLATPAK_CHAIN_INPUT_STREAM (object);
  priv = flatpak_chain_input_stream_get_instance_private (self);

  switch (prop_id)
    {
    case PROP_STREAMS:
      g_value_set_pointer (value, priv->streams);
      break;

    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
    }
}

static void
flatpak_chain_input_stream_finalize (GObject *object)
{
  FlatpakChainInputStream *stream;
  FlatpakChainInputStreamPrivate *priv;

  stream = (FlatpakChainInputStream *) (object);
  priv = flatpak_chain_input_stream_get_instance_private (stream);

  g_ptr_array_unref (priv->streams);

  G_OBJECT_CLASS (flatpak_chain_input_stream_parent_class)->finalize (object);
}

static void
flatpak_chain_input_stream_init (FlatpakChainInputStream *self)
{
}

FlatpakChainInputStream *
flatpak_chain_input_stream_new (GPtrArray *streams)
{
  FlatpakChainInputStream *stream;

  stream = g_object_new (FLATPAK_TYPE_CHAIN_INPUT_STREAM,
                         "streams", streams,
                         NULL);

  return (FlatpakChainInputStream *) (stream);
}

static gssize
flatpak_chain_input_stream_read (GInputStream *stream,
                                 void         *buffer,
                                 gsize         count,
                                 GCancellable *cancellable,
                                 GError      **error)
{
  FlatpakChainInputStream *self = (FlatpakChainInputStream *) stream;
  FlatpakChainInputStreamPrivate *priv = flatpak_chain_input_stream_get_instance_private (self);
  GInputStream *child;
  gssize res = -1;

  if (g_cancellable_set_error_if_cancelled (cancellable, error))
    return -1;

  if (priv->index >= priv->streams->len)
    return 0;

  res = 0;
  while (res == 0 && priv->index < priv->streams->len)
    {
      child = priv->streams->pdata[priv->index];
      res = g_input_stream_read (child,
                                 buffer,
                                 count,
                                 cancellable,
                                 error);
      if (res == 0)
        priv->index++;
    }

  return res;
}

static gboolean
flatpak_chain_input_stream_close (GInputStream *stream,
                                  GCancellable *cancellable,
                                  GError      **error)
{
  gboolean ret = FALSE;
  FlatpakChainInputStream *self = (gpointer) stream;
  FlatpakChainInputStreamPrivate *priv = flatpak_chain_input_stream_get_instance_private (self);
  guint i;

  for (i = 0; i < priv->streams->len; i++)
    {
      GInputStream *child = priv->streams->pdata[i];
      if (!g_input_stream_close (child, cancellable, error))
        goto out;
    }

  ret = TRUE;
out:
  return ret;
}

===== ./common/flatpak-enum-types.h.template =====
/*** BEGIN file-header ***/
#ifndef __FLATPAK_ENUM_TYPES_H__
#define __FLATPAK_ENUM_TYPES_H__

#include <glib-object.h>

G_BEGIN_DECLS
/*** END file-header ***/

/*** BEGIN file-production ***/

/* enumerations from "@basename@" */
/*** END file-production ***/

/*** BEGIN value-header ***/
FLATPAK_EXTERN GType @enum_name@_get_type (void) G_GNUC_CONST;
#define @ENUMPREFIX@_TYPE_@ENUMSHORT@ (@enum_name@_get_type ())
/*** END value-header ***/

/*** BEGIN file-tail ***/
G_END_DECLS

#endif /* __GIO_ENUM_TYPES_H__ */
/*** END file-tail ***/

===== ./common/flatpak-image-collection-private.h =====
/*
 * Copyright © 2024 Red Hat, Inc
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Owen Taylor <otaylor@redhat.com>
 */

#ifndef __FLATPAK_IMAGE_COLLECTION_H__
#define __FLATPAK_IMAGE_COLLECTION_H__

#include <glib.h>
#include <gio/gio.h>

#include <flatpak-common-types-private.h>
#include <flatpak-image-source-private.h>

#define FLATPAK_TYPE_IMAGE_COLLECTION flatpak_image_collection_get_type ()
#define FLATPAK_IMAGE_COLLECTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), FLATPAK_TYPE_IMAGE_COLLECTION, FlatpakImageCollection))
#define FLATPAK_IS_IMAGE_COLLECTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), FLATPAK_TYPE_IMAGE_COLLECTION))

GType flatpak_image_collection_get_type (void);

G_DEFINE_AUTOPTR_CLEANUP_FUNC (FlatpakImageCollection, g_object_unref)


FlatpakImageCollection *flatpak_image_collection_new (const char   *location,
                                                      GCancellable *cancellable,
                                                      GError      **error);

FlatpakImageSource *flatpak_image_collection_lookup_ref (FlatpakImageCollection *self,
                                                         const char             *ref);
FlatpakImageSource *flatpak_image_collection_lookup_digest (FlatpakImageCollection *self,
                                                            const char             *digest);

GPtrArray *flatpak_image_collection_get_sources (FlatpakImageCollection *self);

#endif /* __FLATPAK_IMAGE_COLLECTION_H__ */

===== ./common/flatpak-zstd-compressor-private.h =====
/* Copyright (C) 2023 Red Hat, Inc.
 *
 * SPDX-License-Identifier: LGPL-2.1-or-later
 *
 * 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, see <http://www.gnu.org/licenses/>.
 *
 * Based on gzlibcompressor.h:
 *     Author: Alexander Larsson <alexl@redhat.com>
 * Author: Owen Taylor <otaylor@redhat.com>
 */

#ifndef __FLATPAK_ZSTD_COMPRESSOR_H__
#define __FLATPAK_ZSTD_COMPRESSOR_H__

#include <gio/gio.h>

G_BEGIN_DECLS

#define FLATPAK_TYPE_ZSTD_COMPRESSOR flatpak_zstd_compressor_get_type ()
G_DECLARE_FINAL_TYPE (FlatpakZstdCompressor,
                      flatpak_zstd_compressor,
                      FLATPAK, ZSTD_COMPRESSOR,
                      GObject)

FlatpakZstdCompressor *flatpak_zstd_compressor_new (int level);

G_END_DECLS

#endif /* __FLATPAK_ZSTD_COMPRESSOR_H__ */

===== ./common/flatpak-remote-ref.c =====
/* vi:set et sw=2 sts=2 cin cino=t0,f0,(0,{s,>2s,n-s,^-s,e-s:
 * Copyright © 2015 Red Hat, Inc
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Alexander Larsson <alexl@redhat.com>
 */

#include "config.h"

#include <string.h>

#include "flatpak-utils-private.h"
#include "flatpak-remote-ref-private.h"
#include "flatpak-remote-ref.h"
#include "flatpak-repo-utils-private.h"
#include "flatpak-enum-types.h"
#include "flatpak-variant-impl-private.h"

/**
 * SECTION:flatpak-remote-ref
 * @Title: FlatpakRemoteRef
 * @Short_description: Remote application reference
 *
 * A FlatpakRemoteRef provides information about an application or runtime
 * (in short: ref) that is available from a remote repository.
 */
typedef struct _FlatpakRemoteRefPrivate FlatpakRemoteRefPrivate;

struct _FlatpakRemoteRefPrivate
{
  char   *remote_name;
  guint64 installed_size;
  guint64 download_size;
  GBytes *metadata;
  char   *eol;
  char   *eol_rebase;
};

G_DEFINE_TYPE_WITH_PRIVATE (FlatpakRemoteRef, flatpak_remote_ref, FLATPAK_TYPE_REF)

enum {
  PROP_0,

  PROP_REMOTE_NAME,
  PROP_INSTALLED_SIZE,
  PROP_DOWNLOAD_SIZE,
  PROP_METADATA,
  PROP_EOL,
  PROP_EOL_REBASE,
};

static void
flatpak_remote_ref_finalize (GObject *object)
{
  FlatpakRemoteRef *self = FLATPAK_REMOTE_REF (object);
  FlatpakRemoteRefPrivate *priv = flatpak_remote_ref_get_instance_private (self);

  g_free (priv->remote_name);
  g_free (priv->eol);
  g_free (priv->eol_rebase);
  g_clear_pointer (&priv->metadata, g_bytes_unref);

  G_OBJECT_CLASS (flatpak_remote_ref_parent_class)->finalize (object);
}

static void
flatpak_remote_ref_set_property (GObject      *object,
                                 guint         prop_id,
                                 const GValue *value,
                                 GParamSpec   *pspec)
{
  FlatpakRemoteRef *self = FLATPAK_REMOTE_REF (object);
  FlatpakRemoteRefPrivate *priv = flatpak_remote_ref_get_instance_private (self);

  switch (prop_id)
    {
    case PROP_REMOTE_NAME:
      g_clear_pointer (&priv->remote_name, g_free);
      priv->remote_name = g_value_dup_string (value);
      break;

    case PROP_INSTALLED_SIZE:
      priv->installed_size = g_value_get_uint64 (value);
      break;

    case PROP_DOWNLOAD_SIZE:
      priv->download_size = g_value_get_uint64 (value);
      break;

    case PROP_METADATA:
      g_clear_pointer (&priv->metadata, g_bytes_unref);
      priv->metadata = g_value_get_boxed (value) ? g_bytes_ref (g_value_get_boxed (value)) : NULL;
      break;

    case PROP_EOL:
      g_clear_pointer (&priv->eol, g_free);
      priv->eol = g_value_dup_string (value);
      break;

    case PROP_EOL_REBASE:
      g_clear_pointer (&priv->eol_rebase, g_free);
      priv->eol_rebase = g_value_dup_string (value);
      break;

    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
    }
}

static void
flatpak_remote_ref_get_property (GObject    *object,
                                 guint       prop_id,
                                 GValue     *value,
                                 GParamSpec *pspec)
{
  FlatpakRemoteRef *self = FLATPAK_REMOTE_REF (object);
  FlatpakRemoteRefPrivate *priv = flatpak_remote_ref_get_instance_private (self);

  switch (prop_id)
    {
    case PROP_REMOTE_NAME:
      g_value_set_string (value, priv->remote_name);
      break;

    case PROP_INSTALLED_SIZE:
      g_value_set_uint64 (value, priv->installed_size);
      break;

    case PROP_DOWNLOAD_SIZE:
      g_value_set_uint64 (value, priv->installed_size);
      break;

    case PROP_METADATA:
      g_value_set_boxed (value, priv->metadata);
      break;

    case PROP_EOL:
      g_value_set_string (value, priv->eol);
      break;

    case PROP_EOL_REBASE:
      g_value_set_string (value, priv->eol_rebase);
      break;

    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
    }
}

static void
flatpak_remote_ref_class_init (FlatpakRemoteRefClass *klass)
{
  GObjectClass *object_class = G_OBJECT_CLASS (klass);

  object_class->get_property = flatpak_remote_ref_get_property;
  object_class->set_property = flatpak_remote_ref_set_property;
  object_class->finalize = flatpak_remote_ref_finalize;

  g_object_class_install_property (object_class,
                                   PROP_REMOTE_NAME,
                                   g_param_spec_string ("remote-name",
                                                        "Remote Name",
                                                        "The name of the remote",
                                                        NULL,
                                                        G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (object_class,
                                   PROP_INSTALLED_SIZE,
                                   g_param_spec_uint64 ("installed-size",
                                                        "Installed Size",
                                                        "The installed size of the application",
                                                        0, G_MAXUINT64, 0,
                                                        G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (object_class,
                                   PROP_DOWNLOAD_SIZE,
                                   g_param_spec_uint64 ("download-size",
                                                        "Download Size",
                                                        "The download size of the application",
                                                        0, G_MAXUINT64, 0,
                                                        G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (object_class,
                                   PROP_METADATA,
                                   g_param_spec_boxed ("metadata",
                                                       "Metadata",
                                                       "The metadata info for the application",
                                                       G_TYPE_BYTES,
                                                       G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (object_class,
                                   PROP_EOL,
                                   g_param_spec_string ("end-of-life",
                                                        "End of life",
                                                        "The reason for the ref to be end of life",
                                                        NULL,
                                                        G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (object_class,
                                   PROP_EOL_REBASE,
                                   g_param_spec_string ("end-of-life-rebase",
                                                        "End of life rebase",
                                                        "The new ref for the end of lifeed ref",
                                                        NULL,
                                                        G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
}

static void
flatpak_remote_ref_init (FlatpakRemoteRef *self)
{
}

/**
 * flatpak_remote_ref_get_remote_name:
 * @self: a #FlatpakRemoteRef
 *
 * Gets the remote name of the ref.
 *
 * Returns: (transfer none): the remote name
 */
const char *
flatpak_remote_ref_get_remote_name (FlatpakRemoteRef *self)
{
  FlatpakRemoteRefPrivate *priv = flatpak_remote_ref_get_instance_private (self);

  return priv->remote_name;
}

/**
 * flatpak_remote_ref_get_installed_size:
 * @self: a #FlatpakRemoteRef
 *
 * Returns the installed size of the ref.
 *
 * Returns: the installed size
 */
guint64
flatpak_remote_ref_get_installed_size (FlatpakRemoteRef *self)
{
  FlatpakRemoteRefPrivate *priv = flatpak_remote_ref_get_instance_private (self);

  return priv->installed_size;
}

/**
 * flatpak_remote_ref_get_download_size:
 * @self: a #FlatpakRemoteRef
 *
 * Returns the download size of the ref.
 *
 * Returns: the download size
 */
guint64
flatpak_remote_ref_get_download_size (FlatpakRemoteRef *self)
{
  FlatpakRemoteRefPrivate *priv = flatpak_remote_ref_get_instance_private (self);

  return priv->download_size;
}

/**
 * flatpak_remote_ref_get_metadata:
 * @self: a #FlatpakRemoteRef
 *
 * Returns the app metadata from the metadata cache of the ref.
 *
 * Returns: (transfer none) (nullable): a #GBytes with the metadata file
 * contents or %NULL
 */
GBytes *
flatpak_remote_ref_get_metadata (FlatpakRemoteRef *self)
{
  FlatpakRemoteRefPrivate *priv = flatpak_remote_ref_get_instance_private (self);

  return priv->metadata;
}

/**
 * flatpak_remote_ref_get_eol:
 * @self: a #FlatpakRemoteRef
 *
 * Returns the end-of-life reason string, or %NULL if the
 * ref is not end-of-lifed.
 *
 * Returns: (transfer none): the end-of-life reason or %NULL
 */
const char *
flatpak_remote_ref_get_eol (FlatpakRemoteRef *self)
{
  FlatpakRemoteRefPrivate *priv = flatpak_remote_ref_get_instance_private (self);

  return priv->eol;
}

/**
 * flatpak_remote_ref_get_eol_rebase:
 * @self: a #FlatpakRemoteRef
 *
 * Returns the end-of-life rebased ref, or %NULL if the
 * ref is not end-of-lifed.
 *
 * Returns: (transfer none): the end-of-life rebased ref or %NULL
 */
const char *
flatpak_remote_ref_get_eol_rebase (FlatpakRemoteRef *self)
{
  FlatpakRemoteRefPrivate *priv = flatpak_remote_ref_get_instance_private (self);

  return priv->eol_rebase;
}

FlatpakRemoteRef *
flatpak_remote_ref_new (FlatpakDecomposed   *decomposed,
                        const char          *commit,
                        const char          *remote_name,
                        const char          *collection_id,
                        FlatpakRemoteState  *state)
{
  guint64 download_size = 0, installed_size = 0;
  g_autofree char *metadata = NULL;
  g_autoptr(GBytes) metadata_bytes = NULL;
  VarMetadataRef sparse_cache;
  const char *eol = NULL;
  const char *eol_rebase = NULL;
  FlatpakRemoteRef *ref;

  if (collection_id == NULL)
    collection_id = flatpak_decomposed_get_collection_id (decomposed);

  if (state &&
      !flatpak_remote_state_load_data (state, flatpak_decomposed_get_ref (decomposed),
                                       &download_size, &installed_size, &metadata,
                                       NULL))
    {
      g_info ("Can't find metadata for ref %s", flatpak_decomposed_get_ref (decomposed));
    }

  if (metadata)
    {
      metadata_bytes = g_bytes_new_take (metadata, strlen (metadata));
      metadata = NULL; /* steal */
    }

  if (state &&
      flatpak_remote_state_lookup_sparse_cache (state, flatpak_decomposed_get_ref (decomposed), &sparse_cache, NULL))
    {
      eol = var_metadata_lookup_string (sparse_cache, FLATPAK_SPARSE_CACHE_KEY_ENDOFLIFE, NULL);
      eol_rebase = var_metadata_lookup_string (sparse_cache, FLATPAK_SPARSE_CACHE_KEY_ENDOFLIFE_REBASE, NULL);
    }

  ref = g_object_new (FLATPAK_TYPE_REMOTE_REF,
                      "kind", flatpak_decomposed_get_kind (decomposed),
                      "name", flatpak_decomposed_peek_id (decomposed, NULL),
                      "arch", flatpak_decomposed_peek_arch (decomposed, NULL),
                      "branch", flatpak_decomposed_peek_branch (decomposed, NULL),
                      "commit", commit,
                      "remote-name", remote_name,
                      "collection-id", collection_id,
                      "installed-size", installed_size,
                      "download-size", download_size,
                      "metadata", metadata_bytes,
                      "end-of-life", eol,
                      "end-of-life-rebase", eol_rebase,
                      NULL);

  return ref;
}

===== ./common/flatpak-run-wayland.c =====
/* vi:set et sw=2 sts=2 cin cino=t0,f0,(0,{s,>2s,n-s,^-s,e-s:
 * Copyright © 2014-2019 Red Hat, Inc
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Alexander Larsson <alexl@redhat.com>
 */

#include "config.h"
#include "flatpak-run-wayland-private.h"

#ifdef ENABLE_WAYLAND_SECURITY_CONTEXT
#include <sys/socket.h>
#include <sys/un.h>
#include <wayland-client.h>
#include "security-context-v1-protocol.h"
#endif

#include "flatpak-utils-private.h"

static const char *
get_wayland_display_name (void)
{
  const char *wayland_display;

  wayland_display = g_getenv ("WAYLAND_DISPLAY");
  if (!wayland_display)
    wayland_display = "wayland-0";

  return wayland_display;
}

static char *
get_wayland_socket_path (const char *wayland_display)
{
  g_autofree char *user_runtime_dir = flatpak_get_real_xdg_runtime_dir ();

  if (wayland_display[0] == '/')
    return g_strdup (wayland_display);

  return g_build_filename (user_runtime_dir, wayland_display, NULL);
}

static int
get_wayland_socket_fd (void)
{
  const char *wayland_socket_fd;
  guint64 fd;

  wayland_socket_fd = g_getenv ("WAYLAND_SOCKET");
  if (!wayland_socket_fd)
    return -1;

  if (!g_ascii_string_to_unsigned (wayland_socket_fd, 10, 0, INT_MAX, &fd, NULL))
    return -1;

  return (int) fd;
}

gboolean
flatpak_run_has_wayland (void)
{
  const char *wayland_display;
  g_autofree char *wayland_socket = NULL;
  struct stat statbuf;

  wayland_display = get_wayland_display_name ();
  wayland_socket = get_wayland_socket_path (wayland_display);

  if (stat (wayland_socket, &statbuf) == 0 &&
      (statbuf.st_mode & S_IFMT) == S_IFSOCK)
    return TRUE;

  if (get_wayland_socket_fd () >= 0)
    return TRUE;

  return FALSE;
}

#ifdef ENABLE_WAYLAND_SECURITY_CONTEXT

static void registry_handle_global (void *data, struct wl_registry *registry,
                                    uint32_t name, const char *interface,
                                    uint32_t version)
{
  struct wp_security_context_manager_v1 **out = data;

  if (strcmp (interface, wp_security_context_manager_v1_interface.name) == 0)
    {
      *out = wl_registry_bind (registry, name,
                               &wp_security_context_manager_v1_interface, 1);
    }
}

static void registry_handle_global_remove (void *data,
                                           struct wl_registry *registry,
                                           uint32_t name)
{
  /* no-op */
}

static const struct wl_registry_listener registry_listener = {
  .global = registry_handle_global,
  .global_remove = registry_handle_global_remove,
};

/* Similar to wl_display_connect (), but does not use WAYLAND_SOCKET,
 * which can only be used once, and also does not unset environment
 * variables, which would not be thread-safe. */
static struct wl_display *
connect_to_wayland_display (const char *wayland_display)
{
  struct sockaddr_un sockaddr = {0};
  g_autofree char *socket_path = NULL;
  glnx_autofd int fd = -1;

  socket_path = get_wayland_socket_path (wayland_display);
  fd = socket (AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0);
  if (fd < 0)
    return NULL;

  sockaddr.sun_family = AF_UNIX;
  snprintf (sockaddr.sun_path, sizeof (sockaddr.sun_path), "%s", socket_path);
  if (connect (fd, (struct sockaddr *) &sockaddr, sizeof (sockaddr)) < 0)
    return NULL;

  return wl_display_connect_to_fd (g_steal_fd (&fd));
}

static char *
create_wl_socket (char *template)
{
  g_autofree char *user_runtime_dir = flatpak_get_real_xdg_runtime_dir ();
  g_autofree char *proxy_socket_dir = g_build_filename (user_runtime_dir, ".flatpak/wl", NULL);
  g_autofree char *proxy_socket = g_build_filename (proxy_socket_dir, template, NULL);
  int fd;

  if (!glnx_shutil_mkdir_p_at (AT_FDCWD, proxy_socket_dir, 0755, NULL, NULL))
    return NULL;

  fd = g_mkstemp (proxy_socket);
  if (fd == -1)
    return NULL;

  close (fd);

  return g_steal_pointer (&proxy_socket);
}

static gboolean
flatpak_run_create_wayland_security_context (FlatpakBwrap *bwrap,
                                             const char   *app_id,
                                             const char   *instance_id,
                                             const char   *wayland_display,
                                             gboolean     *available_out,
                                             gchar       **socket_path_out)
{
  gboolean res = FALSE;
  struct wl_display *display;
  struct wl_registry *registry;
  struct wp_security_context_manager_v1 *security_context_manager = NULL;
  struct wp_security_context_v1 *security_context;
  struct sockaddr_un sockaddr = {0};
  g_autofree char *socket_path = NULL;
  int listen_fd = -1, sync_fd, ret;

  *available_out = TRUE;
  *socket_path_out = NULL;

  /* We don't use wl_display_connect () here, for two reasons:
   * 1. It would unsetenv ("WAYLAND_SOCKET"), which is not thread-safe.
   * 2. If the compositor has set WAYLAND_SOCKET to a special, higher-privileged
   *    socket, the application should be able to get those privileges for its first
   *    connection; but that fd can only be used once, so having flatpak itself
   *    do that first connection would defeat that mechanism.
   *
   * We still set up a security context for the second and subsequent connections
   * to Wayland from within the sandbox.
   */
  display = connect_to_wayland_display (wayland_display);
  if (!display)
    return FALSE;

  registry = wl_display_get_registry (display);
  wl_registry_add_listener (registry, &registry_listener,
                            &security_context_manager);
  ret = wl_display_roundtrip (display);
  wl_registry_destroy (registry);
  if (ret < 0)
    goto out;

  if (!security_context_manager)
    {
      g_debug ("Wayland display does not support security_context_manager_v1");
      *available_out = FALSE;
      goto out;
    }

  socket_path = create_wl_socket ("wayland-XXXXXX");
  if (!socket_path)
    goto out;

  unlink (socket_path);

  listen_fd = socket (AF_UNIX, SOCK_STREAM, 0);
  if (listen_fd < 0)
    goto out;

  sockaddr.sun_family = AF_UNIX;
  snprintf (sockaddr.sun_path, sizeof(sockaddr.sun_path), "%s", socket_path);
  if (bind (listen_fd, (struct sockaddr *) &sockaddr, sizeof (sockaddr)) != 0)
    goto out;

  if (listen (listen_fd, 0) != 0)
    goto out;

  sync_fd = flatpak_bwrap_add_sync_fd (bwrap);
  if (sync_fd < 0)
    goto out;

  security_context = wp_security_context_manager_v1_create_listener (security_context_manager,
                                                                     listen_fd,
                                                                     sync_fd);
  wp_security_context_v1_set_sandbox_engine (security_context, "org.flatpak");
  wp_security_context_v1_set_app_id (security_context, app_id);
  wp_security_context_v1_set_instance_id (security_context, instance_id);
  wp_security_context_v1_commit (security_context);
  wp_security_context_v1_destroy (security_context);
  if (wl_display_roundtrip (display) < 0)
    goto out;

  *socket_path_out = g_steal_pointer (&socket_path);
  res = TRUE;

out:
  if (listen_fd >= 0)
    close (listen_fd);
  if (security_context_manager)
    wp_security_context_manager_v1_destroy (security_context_manager);
  wl_display_disconnect (display);
  return res;
}

#endif /* ENABLE_WAYLAND_SECURITY_CONTEXT */

/**
 * flatpak_run_add_wayland_args:
 *
 * Returns: %TRUE if a Wayland socket was found.
 */
gboolean
flatpak_run_add_wayland_args (FlatpakBwrap *bwrap,
                              const char   *app_id,
                              const char   *instance_id,
                              gboolean      allowed,
                              gboolean      inherit_wayland_socket)
{
  const char *wayland_display;
  g_autofree char *wayland_socket = NULL;
  g_autofree char *sandbox_wayland_socket = NULL;
  gboolean res = FALSE;
  struct stat statbuf;
  int fd;
#ifdef ENABLE_WAYLAND_SECURITY_CONTEXT
  gboolean security_context_available = FALSE;
#endif

  if (!allowed)
    {
      flatpak_bwrap_unset_env (bwrap, "WAYLAND_DISPLAY");
      flatpak_bwrap_unset_env (bwrap, "WAYLAND_SOCKET");
      return FALSE;
    }

  g_info ("Allowing wayland access");

  g_assert (app_id && instance_id);

  wayland_display = get_wayland_display_name ();

#ifdef ENABLE_WAYLAND_SECURITY_CONTEXT
  if (flatpak_run_create_wayland_security_context (bwrap, app_id, instance_id,
                                                   wayland_display,
                                                   &security_context_available,
                                                   &wayland_socket))
    {
      g_debug ("Created Wayland socket with security context: %s",
               wayland_socket);
      g_assert (security_context_available);
    }
  /* If security-context is available but we failed to set it up, bail out */
  else if (security_context_available)
    {
      g_debug ("Failed to set up Wayland security context");
      return FALSE;
    }
  else
#endif /* ENABLE_WAYLAND_SECURITY_CONTEXT */
    {
      g_debug ("Using ordinary Wayland socket, without security context");
      wayland_socket = get_wayland_socket_path (wayland_display);
    }

  if (!g_str_has_prefix (wayland_display, "wayland-") ||
      strchr (wayland_display, '/') != NULL)
    {
      g_debug ("Not preserving WAYLAND_DISPLAY=\"%s\"", wayland_display);
      wayland_display = "wayland-0";
      flatpak_bwrap_set_env (bwrap, "WAYLAND_DISPLAY", wayland_display, TRUE);
    }

  sandbox_wayland_socket = g_strdup_printf ("/run/flatpak/%s", wayland_display);

  if (stat (wayland_socket, &statbuf) == 0 &&
      (statbuf.st_mode & S_IFMT) == S_IFSOCK)
    {
      res = TRUE;
      flatpak_bwrap_add_args (bwrap,
                              "--ro-bind", wayland_socket, sandbox_wayland_socket,
                              NULL);
      flatpak_bwrap_add_runtime_dir_member (bwrap, wayland_display);
    }

  /* If inherit-wayland-socket is not set, unset WAYLAND_SOCKET unconditionally
   * without checking the validity of the value of WAYLAND_SOCKET. */
  if (!inherit_wayland_socket)
    flatpak_bwrap_unset_env (bwrap, "WAYLAND_SOCKET");

  fd = get_wayland_socket_fd ();
  if (fd >= 0)
    {
      if (inherit_wayland_socket)
        {
          flatpak_bwrap_add_fd (bwrap, fd);
        }
      else
        {
          /* Make sure the fd is close-on-execute so it won't be inherited by the
           * application. We do this in preference to closing it, because if this function
           * was somehow called twice, and the same fd number was reused for an
           * unrelated purpose, we don't want to close the unrelated fd the
           * second time. */
          fcntl (fd, F_SETFD, FD_CLOEXEC);
        }
    }

  return res;
}

===== ./common/flatpak-remote.h =====
/*
 * Copyright © 2015 Red Hat, Inc
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Alexander Larsson <alexl@redhat.com>
 */

#if !defined(__FLATPAK_H_INSIDE__) && !defined(FLATPAK_COMPILATION)
#error "Only <flatpak.h> can be included directly."
#endif

#ifndef __FLATPAK_REMOTE_H__
#define __FLATPAK_REMOTE_H__

/**
 * FlatpakRemoteType:
 * @FLATPAK_REMOTE_TYPE_STATIC: Statically configured remote
 * @FLATPAK_REMOTE_TYPE_USB: Dynamically detected local pathname remote
 * @FLATPAK_REMOTE_TYPE_LAN: Dynamically detected network remote
 *
 * Different types of @FlatpakRemote.
 */
typedef enum {
  FLATPAK_REMOTE_TYPE_STATIC,
  FLATPAK_REMOTE_TYPE_USB,
  FLATPAK_REMOTE_TYPE_LAN,
} FlatpakRemoteType;

typedef struct _FlatpakRemote FlatpakRemote;

#include <gio/gio.h>
#include <flatpak-remote-ref.h>

G_BEGIN_DECLS

#define FLATPAK_TYPE_REMOTE flatpak_remote_get_type ()
#define FLATPAK_REMOTE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), FLATPAK_TYPE_REMOTE, FlatpakRemote))
#define FLATPAK_IS_REMOTE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), FLATPAK_TYPE_REMOTE))

FLATPAK_EXTERN GType flatpak_remote_get_type (void);

struct _FlatpakRemote
{
  GObject parent;
};

typedef struct
{
  GObjectClass parent_class;
} FlatpakRemoteClass;

#ifdef G_DEFINE_AUTOPTR_CLEANUP_FUNC
G_DEFINE_AUTOPTR_CLEANUP_FUNC (FlatpakRemote, g_object_unref)
#endif

FLATPAK_EXTERN FlatpakRemote * flatpak_remote_new (const char    *name);
FLATPAK_EXTERN FlatpakRemote * flatpak_remote_new_from_file (const char *name,
                                                             GBytes     *data,
                                                             GError **error);

FLATPAK_EXTERN const char *  flatpak_remote_get_name (FlatpakRemote *self);
FLATPAK_EXTERN GFile *       flatpak_remote_get_appstream_dir (FlatpakRemote *self,
                                                               const char    *arch);
FLATPAK_EXTERN GFile *       flatpak_remote_get_appstream_timestamp (FlatpakRemote *self,
                                                                     const char    *arch);
FLATPAK_EXTERN char *        flatpak_remote_get_url (FlatpakRemote *self);
FLATPAK_EXTERN void          flatpak_remote_set_url (FlatpakRemote *self,
                                                     const char    *url);
FLATPAK_EXTERN char *        flatpak_remote_get_collection_id (FlatpakRemote *self);
FLATPAK_EXTERN void          flatpak_remote_set_collection_id (FlatpakRemote *self,
                                                               const char    *collection_id);
FLATPAK_EXTERN char *        flatpak_remote_get_title (FlatpakRemote *self);
FLATPAK_EXTERN void          flatpak_remote_set_title (FlatpakRemote *self,
                                                       const char    *title);
FLATPAK_EXTERN char *        flatpak_remote_get_comment (FlatpakRemote *self);
FLATPAK_EXTERN void          flatpak_remote_set_comment (FlatpakRemote *self,
                                                         const char    *comment);
FLATPAK_EXTERN char *        flatpak_remote_get_description (FlatpakRemote *self);
FLATPAK_EXTERN void          flatpak_remote_set_description (FlatpakRemote *self,
                                                             const char    *description);
FLATPAK_EXTERN char *        flatpak_remote_get_homepage (FlatpakRemote *self);
FLATPAK_EXTERN void          flatpak_remote_set_homepage (FlatpakRemote *self,
                                                          const char    *homepage);
FLATPAK_EXTERN char *        flatpak_remote_get_icon (FlatpakRemote *self);
FLATPAK_EXTERN void          flatpak_remote_set_icon (FlatpakRemote *self,
                                                      const char    *icon);
FLATPAK_EXTERN char *        flatpak_remote_get_default_branch (FlatpakRemote *self);
FLATPAK_EXTERN void          flatpak_remote_set_default_branch (FlatpakRemote *self,
                                                                const char    *default_branch);
FLATPAK_EXTERN char *        flatpak_remote_get_main_ref (FlatpakRemote *self);
FLATPAK_EXTERN void          flatpak_remote_set_main_ref (FlatpakRemote *self,
                                                          const char    *main_ref);
FLATPAK_EXTERN gboolean      flatpak_remote_get_gpg_verify (FlatpakRemote *self);
FLATPAK_EXTERN void          flatpak_remote_set_gpg_verify (FlatpakRemote *self,
                                                            gboolean       gpg_verify);
FLATPAK_EXTERN void          flatpak_remote_set_gpg_key (FlatpakRemote *self,
                                                         GBytes        *gpg_key);
FLATPAK_EXTERN gboolean      flatpak_remote_get_noenumerate (FlatpakRemote *self);
FLATPAK_EXTERN void          flatpak_remote_set_noenumerate (FlatpakRemote *self,
                                                             gboolean       noenumerate);
FLATPAK_EXTERN gboolean      flatpak_remote_get_nodeps (FlatpakRemote *self);
FLATPAK_EXTERN void          flatpak_remote_set_nodeps (FlatpakRemote *self,
                                                        gboolean       nodeps);
FLATPAK_EXTERN gboolean      flatpak_remote_get_disabled (FlatpakRemote *self);
FLATPAK_EXTERN void          flatpak_remote_set_disabled (FlatpakRemote *self,
                                                          gboolean       disabled);
FLATPAK_EXTERN int           flatpak_remote_get_prio (FlatpakRemote *self);
FLATPAK_EXTERN void          flatpak_remote_set_prio (FlatpakRemote *self,
                                                      int            prio);
FLATPAK_EXTERN char *        flatpak_remote_get_filter (FlatpakRemote *self);
FLATPAK_EXTERN void          flatpak_remote_set_filter (FlatpakRemote *self,
                                                        const char    *filter_path);

FLATPAK_EXTERN FlatpakRemoteType flatpak_remote_get_remote_type (FlatpakRemote *self);

G_END_DECLS

#endif /* __FLATPAK_REMOTE_H__ */

===== ./common/flatpak-zstd-compressor.c =====
/* GIO - GLib Input, Output and Streaming Library
 *
 * Copyright (C) 2023 Red Hat, Inc.
 *
 * SPDX-License-Identifier: LGPL-2.1-or-later
 *
 * 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, see <http://www.gnu.org/licenses/>.
 *
 * Based on gzlibcompressor.h:
 *     Author: Alexander Larsson <alexl@redhat.com>
 * Author: Owen Taylor <otaylor@redhat.com>
 */

#include "config.h"

#include "flatpak-zstd-compressor-private.h"

#include <errno.h>
#include <string.h>
#ifdef HAVE_ZSTD
#include <zstd.h>
#endif

struct _FlatpakZstdCompressor
{
  GObject parent_instance;

  int level;
#ifdef HAVE_ZSTD
  ZSTD_CStream *cstream;
#endif
};

static void flatpak_zstd_compressor_iface_init (GConverterIface *iface);

G_DEFINE_TYPE_WITH_CODE (FlatpakZstdCompressor,
                         flatpak_zstd_compressor,
                         G_TYPE_OBJECT,
			 G_IMPLEMENT_INTERFACE (G_TYPE_CONVERTER,
						flatpak_zstd_compressor_iface_init))

static GConverterResult
flatpak_zstd_compressor_convert (GConverter *converter,
                                 const void *inbuf,
                                 gsize       inbuf_size,
                                 void       *outbuf,
                                 gsize       outbuf_size,
                                 GConverterFlags flags,
                                 gsize      *bytes_read,
                                 gsize      *bytes_written,
                                 GError    **error)
{
#ifdef HAVE_ZSTD
  FlatpakZstdCompressor *compressor = FLATPAK_ZSTD_COMPRESSOR (converter);
  ZSTD_inBuffer input = { inbuf, inbuf_size, 0 };
  ZSTD_outBuffer output = {outbuf, outbuf_size, 0 };
  ZSTD_EndDirective end_op;
  size_t res;

  end_op = ZSTD_e_continue;
  if (flags & G_CONVERTER_INPUT_AT_END)
    end_op = ZSTD_e_end;
  else if (flags & G_CONVERTER_FLUSH)
    end_op = ZSTD_e_flush;

  res = ZSTD_compressStream2 (compressor->cstream, &output, &input, end_op);
  if (ZSTD_isError (res))
    {
      g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA,
                   "Zstd compression error: %s", ZSTD_getErrorName (res));
      return G_CONVERTER_ERROR;
    }

  *bytes_read = input.pos;
  *bytes_written = output.pos;

  if (flags & G_CONVERTER_INPUT_AT_END && res == 0)
    return G_CONVERTER_FINISHED;

  /* We should make some progress */
  g_assert (input.pos != 0 || output.pos != 0);
  return G_CONVERTER_CONVERTED;

#else
  g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
                       "libzstd not available");
  return G_CONVERTER_ERROR;
#endif
}

static void
flatpak_zstd_compressor_reset (GConverter *converter)
{
#ifdef HAVE_ZSTD
  FlatpakZstdCompressor *compressor = FLATPAK_ZSTD_COMPRESSOR (converter);

  ZSTD_initCStream(compressor->cstream, compressor->level);
#endif
}

static void
flatpak_zstd_compressor_iface_init (GConverterIface *iface)
{
  iface->convert = flatpak_zstd_compressor_convert;
  iface->reset = flatpak_zstd_compressor_reset;
}

static void
flatpak_zstd_compressor_finalize (GObject *object)
{
#ifdef HAVE_ZSTD
  FlatpakZstdCompressor *compressor = FLATPAK_ZSTD_COMPRESSOR (object);

  ZSTD_freeCStream (compressor->cstream);
#endif

  G_OBJECT_CLASS (flatpak_zstd_compressor_parent_class)->finalize (object);
}

static void
flatpak_zstd_compressor_class_init (FlatpakZstdCompressorClass *klass)
{
  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);

  gobject_class->finalize = flatpak_zstd_compressor_finalize;
}

static void
flatpak_zstd_compressor_init (FlatpakZstdCompressor *compressor)
{
}

FlatpakZstdCompressor *
flatpak_zstd_compressor_new (int level)
{
  FlatpakZstdCompressor *compressor;

  compressor = g_object_new (FLATPAK_TYPE_ZSTD_COMPRESSOR, NULL);

#ifdef HAVE_ZSTD
  compressor->level = level < 0 ? ZSTD_CLEVEL_DEFAULT : level;

  compressor->cstream = ZSTD_createCStream ();
  if (!compressor->cstream)
    g_error ("FlatpakZstdCompressor: Not enough memory for zstd use");

  flatpak_zstd_compressor_reset (G_CONVERTER (compressor));
#endif
  return compressor;
}

===== ./common/flatpak-appdata.c =====
/* vi:set et sw=2 sts=2 cin cino=t0,f0,(0,{s,>2s,n-s,^-s,e-s:
 * Copyright © 2019 Red Hat, Inc
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Matthias Clasen <mclasen@redhat.com>
 */

#include "config.h"

#include "flatpak-appdata-private.h"
#include "flatpak-utils-private.h"
#include <gio/gio.h>
#include <stdio.h>

typedef struct
{
  char *id;
  GHashTable *names;
  GHashTable *comments;
  char       *version;
  char       *license;
  char       *content_rating_type;
  GHashTable *content_rating;  /* (element-type interned-utf8 interned-utf8) */
} Component;

typedef struct
{
  GPtrArray *components;
  GString   *text;
  gboolean   in_text;
  gboolean   in_component;
  gboolean   in_content_rating;
  gboolean   in_developer;
  char      *lang;
  guint64    timestamp;
  const char *id;  /* interned */
} ParserData;

static void
component_free (gpointer data)
{
  Component *component = data;

  g_hash_table_unref (component->names);
  g_hash_table_unref (component->comments);
  g_free (component->id);
  g_free (component->version);
  g_free (component->license);
  g_free (component->content_rating_type);
  g_clear_pointer (&component->content_rating, g_hash_table_unref);

  g_free (component);
}

static Component *
component_new (void)
{
  Component *component = g_new0 (Component, 1);

  component->names = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
  component->comments = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);

  return component;
}

static void
parser_data_free (ParserData *data)
{
  g_ptr_array_unref (data->components);
  g_string_free (data->text, TRUE);
  g_free (data->lang);

  g_free (data);
}

G_DEFINE_AUTOPTR_CLEANUP_FUNC (ParserData, parser_data_free)

static ParserData *
parser_data_new (void)
{
  ParserData *data = g_new0 (ParserData, 1);

  data->components = g_ptr_array_new_with_free_func (component_free);
  data->text = g_string_new ("");

  return data;
}

static void
start_element (GMarkupParseContext *context,
               const char          *element_name,
               const char         **attribute_names,
               const char         **attribute_values,
               gpointer             user_data,
               GError             **error)
{
  ParserData *data = user_data;

  g_assert (data->text->len == 0);
  g_assert (data->lang == NULL);

  if (g_str_equal (element_name, "component"))
    {
      g_ptr_array_add (data->components, component_new ());
    }
  else if (g_str_equal (element_name, "id"))
    {
      data->in_text = TRUE;
    }
  else if ((!data->in_developer && g_str_equal (element_name, "name")) ||
           g_str_equal (element_name, "summary"))
    {
      const char *lang = NULL;

      if (g_markup_collect_attributes (element_name,
                                       attribute_names,
                                       attribute_values,
                                       error,
                                       G_MARKUP_COLLECT_STRING | G_MARKUP_COLLECT_OPTIONAL, "xml:lang", &lang,
                                       G_MARKUP_COLLECT_INVALID))
        {
          if (lang)
            data->lang = g_strdup (lang);
          else
            data->lang = g_strdup ("C");
          data->in_text = TRUE;
        }
    }
  else if (g_str_equal (element_name, "project_license"))
    {
      data->in_text = TRUE;
    }
  else if (g_str_equal (element_name, "release"))
    {
      const char *timestamp;
      const char *date;
      const char *version;
      Component *component = NULL;

      g_assert (data->components->len > 0);

      component = g_ptr_array_index (data->components, data->components->len - 1);

      if (g_markup_collect_attributes (element_name,
                                       attribute_names,
                                       attribute_values,
                                       error,
                                       G_MARKUP_COLLECT_STRING, "version", &version,
                                       G_MARKUP_COLLECT_STRING | G_MARKUP_COLLECT_OPTIONAL, "timestamp", &timestamp,
                                       G_MARKUP_COLLECT_STRING | G_MARKUP_COLLECT_OPTIONAL, "date", &date,
                                       G_MARKUP_COLLECT_STRING | G_MARKUP_COLLECT_OPTIONAL, "date_eol", NULL,
                                       G_MARKUP_COLLECT_STRING | G_MARKUP_COLLECT_OPTIONAL, "urgency", NULL,
                                       G_MARKUP_COLLECT_STRING | G_MARKUP_COLLECT_OPTIONAL, "type", NULL,
                                       G_MARKUP_COLLECT_INVALID))
        {
          guint64 ts = 0;

          if (timestamp)
            ts = g_ascii_strtoull (timestamp, NULL, 10);
          else if (date)
            {
              g_autoptr(GTimeZone) tz = g_time_zone_new_utc ();
              g_autoptr(GDateTime) dt = g_date_time_new_from_iso8601 (date, tz);
              if (!dt)
                {
                  int d, m, y;

                  if (sscanf (date, "%u-%u-%u", &d, &m, &y) == 3)
                    dt = g_date_time_new_utc (d, m, y, 0, 0, 0);
                }
              if (dt)
                ts = g_date_time_to_unix (dt);
            }
          else
            g_warning ("Ignoring release element without timestamp or date");

          if (ts > data->timestamp)
            {
              data->timestamp = ts;
              g_free (component->version);
              component->version = g_strdup (version);
            }
        }
    }
  else if (g_str_equal (element_name, "content_rating"))
    {
      /* https://www.freedesktop.org/software/appstream/docs/chap-Metadata.html#tag-content_rating */
      Component *component = NULL;

      g_assert (data->components->len > 0);

      component = g_ptr_array_index (data->components, data->components->len - 1);

      if (component->content_rating == NULL)
        {
          const gchar *type = NULL;

          if (g_markup_collect_attributes (element_name,
                                                 attribute_names,
                                                 attribute_values,
                                                 error,
                                                 G_MARKUP_COLLECT_STRING, "type", &type,
                                                 G_MARKUP_COLLECT_INVALID))
            {
              component->content_rating_type = g_strdup (type);
              component->content_rating = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, NULL);
              data->in_content_rating = TRUE;
            }
          else
            {
              g_warning ("Ignoring content rating missing type attribute");
            }
        }
      else
        {
          g_warning ("Ignoring duplicate content rating");
        }
    }
  else if (data->in_content_rating && g_str_equal (element_name, "content_attribute"))
    {
      /* https://www.freedesktop.org/software/appstream/docs/chap-Metadata.html#tag-content_rating */
      Component *component = NULL;
      const gchar *id = NULL;

      g_assert (data->components->len > 0);

      component = g_ptr_array_index (data->components, data->components->len - 1);
      g_assert (component->content_rating != NULL);

      if (g_markup_collect_attributes (element_name,
                                       attribute_names,
                                       attribute_values,
                                       error,
                                       G_MARKUP_COLLECT_STRING, "id", &id,
                                       G_MARKUP_COLLECT_INVALID))
        {
          /* FIXME: We use interned strings here (for keys and, below, for
           * values) as the set of OARS keys and values is small and bounded.
           * In future (once we can depend on GLib 2.58), we could switch to
           * using #GRefString to avoid expanding the interned string hash
           * table. */
          data->id = g_intern_string (id);
          data->in_text = TRUE;
        }
      else
        {
          g_warning ("Ignoring content attribute missing id attribute");
        }
    }
  else if (g_str_equal (element_name, "developer"))
    {
      data->in_developer = TRUE;
    }
}

static void
end_element (GMarkupParseContext *context,
             const char          *element_name,
             gpointer             user_data,
             GError             **error)
{
  ParserData *data = user_data;
  g_autofree char *text = NULL;
  Component *component = NULL;
  const char *parent = NULL;
  const GSList *elements;

  elements = g_markup_parse_context_get_element_stack (context);
  if (elements->next)
    parent = (const char *) elements->next->data;

  g_assert (data->components->len > 0);

  component = g_ptr_array_index (data->components, data->components->len - 1);

  if (data->in_text)
    {
      text = g_strdup (data->text->str);
      g_string_truncate (data->text, 0);
      data->in_text = FALSE;
    }

  /* avoid picking up <id> elements from e.g. <provides> */
  if (g_str_equal (element_name, "id"))
    {
      g_assert (parent != NULL);
      if (g_str_equal (parent, "component"))
        component->id = g_steal_pointer (&text);
    }
  else if (!data->in_developer && g_str_equal (element_name, "name"))
    {
      g_hash_table_insert (component->names, g_steal_pointer (&data->lang), g_steal_pointer (&text));
    }
  else if (g_str_equal (element_name, "summary"))
    {
      g_hash_table_insert (component->comments, g_steal_pointer (&data->lang), g_steal_pointer (&text));
    }
  else if (g_str_equal (element_name, "project_license"))
    {
      component->license = g_steal_pointer (&text);
    }
  else if (g_str_equal (element_name, "content_rating"))
    {
      data->in_content_rating = FALSE;
    }
  else if (data->in_content_rating && g_str_equal (element_name, "content_attribute"))
    {
      /* https://www.freedesktop.org/software/appstream/docs/chap-Metadata.html#tag-content_rating */
      g_assert (component->content_rating != NULL);
      g_hash_table_insert (component->content_rating, (gpointer) data->id, (gpointer) g_intern_string (text));
    }
  else if (g_str_equal (element_name, "developer"))
    {
      data->in_developer = FALSE;
    }
}

static void
text (GMarkupParseContext *context,
      const char          *text,
      gsize                text_len,
      gpointer             user_data,
      GError             **error)
{
  ParserData *data = user_data;

  if (data->in_text)
    g_string_append_len (data->text, text, text_len);
}

gboolean
flatpak_parse_appdata (const char  *appdata_xml,
                       const char  *app_id,
                       GHashTable **names,
                       GHashTable **comments,
                       char       **version,
                       char       **license,
                       char       **content_rating_type,
                       GHashTable **content_rating)
{
  g_autoptr(GMarkupParseContext) context = NULL;
  GMarkupParser parser = {
    start_element,
    end_element,
    text,
    NULL,
    NULL
  };
  g_autoptr(ParserData) data = parser_data_new ();
  g_autoptr(GError) error = NULL;
  int i;
  g_autofree char *legacy_id = NULL;

  context = g_markup_parse_context_new (&parser, G_MARKUP_TREAT_CDATA_AS_TEXT, data, NULL);

  if (!g_markup_parse_context_parse (context, appdata_xml, -1, &error))
    {
      g_warning ("Failed to parse appdata: %s", error->message);
      return FALSE;
    }

  legacy_id = g_strconcat (app_id, ".desktop", NULL);

  for (i = 0; i < data->components->len; i++)
    {
      Component *component = g_ptr_array_index (data->components, i);

      if (g_str_equal (component->id, app_id) ||
          g_str_equal (component->id, legacy_id))
        {
          *names = g_hash_table_ref (component->names);
          *comments = g_hash_table_ref (component->comments);
          *version = g_steal_pointer (&component->version);
          *license = g_steal_pointer (&component->license);
          if (content_rating_type != NULL)
            *content_rating_type = g_steal_pointer (&component->content_rating_type);
          if (content_rating != NULL)
            *content_rating = g_steal_pointer (&component->content_rating);
          return TRUE;
        }
    }

  g_warning ("No matching appdata for %s", app_id);
  return FALSE;
}

===== ./common/flatpak-run-cups.c =====
/* vi:set et sw=2 sts=2 cin cino=t0,f0,(0,{s,>2s,n-s,^-s,e-s:
 * Copyright © 2014-2019 Red Hat, Inc
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Alexander Larsson <alexl@redhat.com>
 */

#include "config.h"
#include "flatpak-run-cups-private.h"

#include "flatpak-utils-private.h"

static gboolean
flatpak_run_cups_check_server_is_socket (const char *server)
{
  if (g_str_has_prefix (server, "/") && strstr (server, ":") == NULL)
    return TRUE;

  return FALSE;
}

/* Try to find a default server from a cups configuration file */
static char *
flatpak_run_get_cups_server_name_config (const char *path)
{
  g_autoptr(GFile) file = g_file_new_for_path (path);
  g_autoptr(GError) my_error = NULL;
  g_autoptr(GFileInputStream) input_stream = NULL;
  g_autoptr(GDataInputStream) data_stream = NULL;
  size_t len;

  input_stream = g_file_read (file, NULL, &my_error);
  if (my_error)
    {
      g_info ("CUPS configuration file '%s': %s", path, my_error->message);
      return NULL;
    }

  data_stream = g_data_input_stream_new (G_INPUT_STREAM (input_stream));

  while (TRUE)
    {
      g_autofree char *line = g_data_input_stream_read_line (data_stream, &len, NULL, NULL);
      if (line == NULL)
        break;

      g_strchug (line);

      if ((*line  == '\0') || (*line == '#'))
        continue;

      g_auto(GStrv) tokens = g_strsplit (line, " ", 2);

      if ((tokens[0] != NULL) && (tokens[1] != NULL))
        {
          if (strcmp ("ServerName", tokens[0]) == 0)
            {
              g_strchug (tokens[1]);

              if (flatpak_run_cups_check_server_is_socket (tokens[1]))
                return g_strdup (tokens[1]);
            }
        }
    }

    return NULL;
}

static char *
flatpak_run_get_cups_server_name (void)
{
  g_autofree char * cups_server = NULL;
  g_autofree char * cups_config_path = NULL;

  /* TODO
   * we don't currently support cups servers located on the network, if such
   * server is detected, we simply ignore it and in the worst case we fallback
   * to the default socket
   */
  cups_server = g_strdup (g_getenv ("CUPS_SERVER"));
  if (cups_server && flatpak_run_cups_check_server_is_socket (cups_server))
    return g_steal_pointer (&cups_server);
  g_clear_pointer (&cups_server, g_free);

  cups_config_path = g_build_filename (g_get_home_dir (), ".cups/client.conf", NULL);
  cups_server = flatpak_run_get_cups_server_name_config (cups_config_path);
  if (cups_server && flatpak_run_cups_check_server_is_socket (cups_server))
    return g_steal_pointer (&cups_server);
  g_clear_pointer (&cups_server, g_free);

  cups_server = flatpak_run_get_cups_server_name_config ("/etc/cups/client.conf");
  if (cups_server && flatpak_run_cups_check_server_is_socket (cups_server))
    return g_steal_pointer (&cups_server);

  // Fallback to default socket
  return g_strdup ("/var/run/cups/cups.sock");
}

void
flatpak_run_add_cups_args (FlatpakBwrap *bwrap)
{
  g_autofree char * sandbox_server_name = g_strdup ("/var/run/cups/cups.sock");
  g_autofree char * cups_server_name = flatpak_run_get_cups_server_name ();

  if (!g_file_test (cups_server_name, G_FILE_TEST_EXISTS))
    {
      g_info ("Could not find CUPS server");
      return;
    }

  flatpak_bwrap_add_args (bwrap,
                          "--ro-bind", cups_server_name, sandbox_server_name,
                          NULL);
}

===== ./common/test-lib.c =====
#include "config.h"

#include "libglnx.h"

#include <flatpak.h>
#include <gio/gunixoutputstream.h>


static void
progress_cb (const char *status,
             guint       progress,
             gboolean    estimating,
             gpointer    user_data)
{
  g_print ("status: %s, progress: %d estimating: %d, user_data: %p\n", status, progress, estimating, user_data);
}

static gboolean
monitor_callback (GFileMonitor    * monitor,
                  GFile           * child,
                  GFile           * other_file,
                  GFileMonitorEvent eflags)
{
  g_print ("Database changed\n");
  return TRUE;
}

int
main (int argc, char *argv[])
{
  FlatpakInstallation *installation;
  FlatpakInstalledRef *app1;
  FlatpakInstalledRef *app2;
  FlatpakRemoteRef *remote_ref;
  g_autoptr(GPtrArray) remotes = NULL;
  g_autoptr(GError) error = NULL;
  int i, j, k;

  installation = flatpak_installation_new_user (NULL, &error);
  if (installation == NULL)
    {
      g_print ("error: %s\n", error->message);
      return 1;
    }

  if (0)
    {
      const char *list[] = { "gnome-apps", "app/org.gnome.iagno/x86_64/stable",
                             "gnome", "runtime/org.gnome.Sdk/x86_64/3.20" };

      for (j = 0; j < G_N_ELEMENTS (list); j += 2)
        {
          g_print ("looking for related to ref: %s\n", list[j + 1]);

          for (k = 0; k < 2; k++)
            {
              g_autoptr(GError) local_error = NULL;
              g_autoptr(GPtrArray) related = NULL;


              if (k == 0)
                related = flatpak_installation_list_remote_related_refs_sync (installation,
                                                                              list[j],
                                                                              list[j + 1],
                                                                              NULL,
                                                                              &local_error);
              else
                related = flatpak_installation_list_installed_related_refs_sync (installation,
                                                                                 list[j],
                                                                                 list[j + 1],
                                                                                 NULL,
                                                                                 &local_error);

              if (related == NULL)
                {
                  g_warning ("Error: %s", local_error->message);
                  continue;
                }

              g_print ("%s related:\n", (k == 0) ? "remote" : "local");
              for (i = 0; i < related->len; i++)
                {
                  FlatpakRelatedRef *rel = g_ptr_array_index (related, i);
                  const char * const *subpaths = flatpak_related_ref_get_subpaths (rel);
                  g_autofree char *subpaths_str = NULL;

                  if (subpaths)
                    {
                      g_autofree char *subpaths_joined = g_strjoinv (",", (char **) subpaths);
                      subpaths_str = g_strdup_printf (" subpaths: %s", subpaths_joined);
                    }
                  else
                    subpaths_str = g_strdup ("");
                  g_print ("%d %s %s %s %s dl:%d del:%d%s\n",
                           flatpak_ref_get_kind (FLATPAK_REF (rel)),
                           flatpak_ref_get_name (FLATPAK_REF (rel)),
                           flatpak_ref_get_arch (FLATPAK_REF (rel)),
                           flatpak_ref_get_branch (FLATPAK_REF (rel)),
                           flatpak_ref_get_commit (FLATPAK_REF (rel)),
                           flatpak_related_ref_should_download (rel),
                           flatpak_related_ref_should_delete (rel),
                           subpaths_str);
                }
            }
        }

      return 0;
    }

  if (argc == 4)
    {
      GFileMonitor * monitor = flatpak_installation_create_monitor (installation, NULL, NULL);
      GMainLoop *main_loop;

      g_signal_connect (monitor, "changed", (GCallback) monitor_callback, NULL);
      main_loop = g_main_loop_new (NULL, FALSE);
      g_main_loop_run (main_loop);
    }

  if (argc == 3)
    {
      G_GNUC_BEGIN_IGNORE_DEPRECATIONS
      app1 = flatpak_installation_install (installation,
                                           argv[1],
                                           FLATPAK_REF_KIND_APP,
                                           argv[2],
                                           NULL, NULL,
                                           progress_cb, (gpointer) 0xdeadbeef,
                                           NULL, &error);
      G_GNUC_END_IGNORE_DEPRECATIONS
      if (app1 == NULL)
        g_print ("Error: %s\n", error->message);
      else
        g_print ("Installed %s: %s\n", argv[2],
                 flatpak_ref_get_commit (FLATPAK_REF (app1)));

      return 0;
    }

  if (argc == 2)
    {
      G_GNUC_BEGIN_IGNORE_DEPRECATIONS
      app1 = flatpak_installation_update (installation,
                                          FLATPAK_UPDATE_FLAGS_NONE,
                                          FLATPAK_REF_KIND_APP,
                                          argv[1],
                                          NULL, NULL,
                                          progress_cb, (gpointer) 0xdeadbeef,
                                          NULL, &error);
      G_GNUC_END_IGNORE_DEPRECATIONS
      if (app1 == NULL)
        g_print ("Error: %s\n", error->message);
      else
        g_print ("Updated %s: %s\n", argv[1],
                 flatpak_ref_get_commit (FLATPAK_REF (app1)));

      return 0;
    }

  g_print ("\n**** Loading bundle\n");
  {
    g_autoptr(GFile) f = g_file_new_for_commandline_arg ("tests/hello.pak");
    g_autoptr(FlatpakBundleRef) bundle = flatpak_bundle_ref_new (f, &error);
    if (bundle == NULL)
      {
        g_print ("Error loading bundle: %s\n", error->message);
        g_clear_error (&error);
      }
    else
      {
        g_autofree char *path = g_file_get_path (flatpak_bundle_ref_get_file (bundle));
        g_autoptr(GBytes) metadata = flatpak_bundle_ref_get_metadata (bundle);
        g_autoptr(GBytes) appdata = flatpak_bundle_ref_get_appstream (bundle);
        g_print ("%d %s %s %s %s %s %"G_GUINT64_FORMAT "\n%s\n",
                 flatpak_ref_get_kind (FLATPAK_REF (bundle)),
                 flatpak_ref_get_name (FLATPAK_REF (bundle)),
                 flatpak_ref_get_arch (FLATPAK_REF (bundle)),
                 flatpak_ref_get_branch (FLATPAK_REF (bundle)),
                 flatpak_ref_get_commit (FLATPAK_REF (bundle)),
                 path,
                 flatpak_bundle_ref_get_installed_size (bundle),
                 (char *) g_bytes_get_data (metadata, NULL));

        if (appdata != NULL)
          {
            g_autoptr(GZlibDecompressor) decompressor = NULL;
            g_autoptr(GOutputStream) out2 = NULL;
            g_autoptr(GOutputStream) out = NULL;

            out = g_unix_output_stream_new (1, FALSE);
            decompressor = g_zlib_decompressor_new (G_ZLIB_COMPRESSOR_FORMAT_GZIP);
            out2 = g_converter_output_stream_new (out, G_CONVERTER (decompressor));

            if (!g_output_stream_write_all (out2,
                                            g_bytes_get_data (appdata, NULL),
                                            g_bytes_get_size (appdata),
                                            NULL, NULL, &error))
              {
                g_print ("Error decompressing appdata: %s\n", error->message);
                g_clear_error (&error);
              }
          }
      }
  }

  g_print ("\n**** Checking for updates\n");
  {
    g_autoptr(GPtrArray) updates =
      flatpak_installation_list_installed_refs_for_update (installation,
                                                           NULL, &error);

    if (updates == NULL)
      {
        g_print ("check for updates error: %s\n", error->message);
        g_clear_error (&error);
      }
    else
      {
        for (i = 0; i < updates->len; i++)
          {
            FlatpakInstalledRef *ref = g_ptr_array_index (updates, i);
            g_print ("%d %s %s %s %s %s %s %s %d %"G_GUINT64_FORMAT "\n",
                     flatpak_ref_get_kind (FLATPAK_REF (ref)),
                     flatpak_ref_get_name (FLATPAK_REF (ref)),
                     flatpak_ref_get_arch (FLATPAK_REF (ref)),
                     flatpak_ref_get_branch (FLATPAK_REF (ref)),
                     flatpak_ref_get_commit (FLATPAK_REF (ref)),
                     flatpak_installed_ref_get_latest_commit (ref),
                     flatpak_installed_ref_get_origin (ref),
                     flatpak_installed_ref_get_deploy_dir (ref),
                     flatpak_installed_ref_get_is_current (ref),
                     flatpak_installed_ref_get_installed_size (ref));
          }
      }
  }

  g_print ("\n**** Listing all installed refs\n");
  {
    g_autoptr(GPtrArray) refs = NULL;

    refs = flatpak_installation_list_installed_refs (installation,
                                                     NULL, NULL);

    for (i = 0; i < refs->len; i++)
      {
        FlatpakInstalledRef *ref = g_ptr_array_index (refs, i);
        g_print ("%d %s %s %s %s %s %s %s %d %"G_GUINT64_FORMAT "\n",
                 flatpak_ref_get_kind (FLATPAK_REF (ref)),
                 flatpak_ref_get_name (FLATPAK_REF (ref)),
                 flatpak_ref_get_arch (FLATPAK_REF (ref)),
                 flatpak_ref_get_branch (FLATPAK_REF (ref)),
                 flatpak_ref_get_commit (FLATPAK_REF (ref)),
                 flatpak_installed_ref_get_latest_commit (ref),
                 flatpak_installed_ref_get_origin (ref),
                 flatpak_installed_ref_get_deploy_dir (ref),
                 flatpak_installed_ref_get_is_current (ref),
                 flatpak_installed_ref_get_installed_size (ref));
      }
  }

  g_print ("**** Listing all installed apps\n");
  {
    g_autoptr(GPtrArray) apps = NULL;

    apps = flatpak_installation_list_installed_refs_by_kind (installation,
                                                             FLATPAK_REF_KIND_APP,
                                                             NULL, NULL);

    for (i = 0; i < apps->len; i++)
      {
        FlatpakInstalledRef *app = g_ptr_array_index (apps, i);

        g_print ("%d %s %s %s %s %s %s %s %d %"G_GUINT64_FORMAT "\n",
                 flatpak_ref_get_kind (FLATPAK_REF (app)),
                 flatpak_ref_get_name (FLATPAK_REF (app)),
                 flatpak_ref_get_arch (FLATPAK_REF (app)),
                 flatpak_ref_get_branch (FLATPAK_REF (app)),
                 flatpak_ref_get_commit (FLATPAK_REF (app)),
                 flatpak_installed_ref_get_latest_commit (app),
                 flatpak_installed_ref_get_origin (app),
                 flatpak_installed_ref_get_deploy_dir (app),
                 flatpak_installed_ref_get_is_current (app),
                 flatpak_installed_ref_get_installed_size (app));
        g_print ("metadata:\n%s\n", (char *) g_bytes_get_data (flatpak_installed_ref_load_metadata (app, NULL, NULL), NULL));
      }
  }

  g_print ("\n**** Listing all installed runtimes\n");
  {
    g_autoptr(GPtrArray) runtimes = NULL;

    runtimes = flatpak_installation_list_installed_refs_by_kind (installation,
                                                                 FLATPAK_REF_KIND_RUNTIME,
                                                                 NULL, NULL);

    for (i = 0; i < runtimes->len; i++)
      {
        FlatpakInstalledRef *runtime = g_ptr_array_index (runtimes, i);
        g_print ("%d %s %s %s %s %s %s %d\n",
                 flatpak_ref_get_kind (FLATPAK_REF (runtime)),
                 flatpak_ref_get_name (FLATPAK_REF (runtime)),
                 flatpak_ref_get_arch (FLATPAK_REF (runtime)),
                 flatpak_ref_get_branch (FLATPAK_REF (runtime)),
                 flatpak_ref_get_commit (FLATPAK_REF (runtime)),
                 flatpak_installed_ref_get_origin (runtime),
                 flatpak_installed_ref_get_deploy_dir (runtime),
                 flatpak_installed_ref_get_is_current (runtime));
      }
  }

  g_print ("\n**** Getting installed gedit master\n");
  app1 = flatpak_installation_get_installed_ref (installation,
                                                 FLATPAK_REF_KIND_APP,
                                                 "org.gnome.gedit",
                                                 NULL, "master", NULL, NULL);
  if (app1)
    {
      g_print ("gedit master: %d %s %s %s %s %s %s %d\n",
               flatpak_ref_get_kind (FLATPAK_REF (app1)),
               flatpak_ref_get_name (FLATPAK_REF (app1)),
               flatpak_ref_get_arch (FLATPAK_REF (app1)),
               flatpak_ref_get_branch (FLATPAK_REF (app1)),
               flatpak_ref_get_commit (FLATPAK_REF (app1)),
               flatpak_installed_ref_get_origin (app1),
               flatpak_installed_ref_get_deploy_dir (app1),
               flatpak_installed_ref_get_is_current (app1));
    }
  if (!flatpak_installation_launch (installation,
                                    "org.gnome.gedit",
                                    NULL, NULL, NULL,
                                    NULL, &error))
    {
      g_print ("launch gedit error: %s\n", error->message);
      g_clear_error (&error);
    }

  g_print ("\n**** Getting current installed gedit\n");
  app2 = flatpak_installation_get_current_installed_app (installation,
                                                         "org.gnome.gedit",
                                                         NULL, NULL);
  if (app2)
    {
      g_print ("gedit current: %d %s %s %s %s %s %s %d\n",
               flatpak_ref_get_kind (FLATPAK_REF (app2)),
               flatpak_ref_get_name (FLATPAK_REF (app2)),
               flatpak_ref_get_arch (FLATPAK_REF (app2)),
               flatpak_ref_get_branch (FLATPAK_REF (app2)),
               flatpak_ref_get_commit (FLATPAK_REF (app2)),
               flatpak_installed_ref_get_origin (app2),
               flatpak_installed_ref_get_deploy_dir (app2),
               flatpak_installed_ref_get_is_current (app2));
    }


  g_print ("\n**** Listing remotes\n");
  remotes = flatpak_installation_list_remotes (installation,
                                               NULL, NULL);

  for (i = 0; i < remotes->len; i++)
    {
      FlatpakRemote *remote = g_ptr_array_index (remotes, i);
      g_autoptr(GPtrArray) refs = NULL;
      const char *collection_id = NULL;

      collection_id = flatpak_remote_get_collection_id (remote);

      g_print ("\nRemote: %s %u %d %s %s %s %s %d %d %s\n",
               flatpak_remote_get_name (remote),
               flatpak_remote_get_remote_type (remote),
               flatpak_remote_get_prio (remote),
               flatpak_remote_get_url (remote),
               collection_id,
               flatpak_remote_get_title (remote),
               flatpak_remote_get_default_branch (remote),
               flatpak_remote_get_gpg_verify (remote),
               flatpak_remote_get_noenumerate (remote),
               g_file_get_path (flatpak_remote_get_appstream_dir (remote, NULL)));

      g_print ("\n**** Listing remote refs on %s\n", flatpak_remote_get_name (remote));
      refs = flatpak_installation_list_remote_refs_sync (installation, flatpak_remote_get_name (remote),
                                                         NULL, NULL);
      if (refs)
        {
          for (j = 0; j < refs->len; j++)
            {
              FlatpakRemoteRef *ref = g_ptr_array_index (refs, j);
              g_print ("%d %s %s %s %s %s\n",
                       flatpak_ref_get_kind (FLATPAK_REF (ref)),
                       flatpak_ref_get_name (FLATPAK_REF (ref)),
                       flatpak_ref_get_arch (FLATPAK_REF (ref)),
                       flatpak_ref_get_branch (FLATPAK_REF (ref)),
                       flatpak_ref_get_commit (FLATPAK_REF (ref)),
                       flatpak_remote_ref_get_remote_name (ref));

              if (j == 0)
                {
                  guint64 download_size;
                  guint64 installed_size;

                  if (!flatpak_installation_fetch_remote_size_sync (installation,
                                                                    flatpak_remote_get_name (remote),
                                                                    FLATPAK_REF (ref),
                                                                    &download_size,
                                                                    &installed_size,
                                                                    NULL, &error))
                    {
                      g_print ("error fetching sizes: %s\n", error->message);
                      g_clear_error (&error);
                    }
                  else
                    {
                      g_print ("Download size: %"G_GUINT64_FORMAT " Installed size: %"G_GUINT64_FORMAT "\n",
                               download_size, installed_size);
                    }
                }
            }
        }

      g_print ("\n**** Getting remote platform 3.20 on %s\n", flatpak_remote_get_name (remote));
      error = NULL;
      remote_ref = flatpak_installation_fetch_remote_ref_sync (installation, flatpak_remote_get_name (remote),
                                                               FLATPAK_REF_KIND_RUNTIME,
                                                               "org.gnome.Platform", NULL, "3.20",
                                                               NULL, &error);
      if (remote_ref)
        {
          GBytes *metadata;

          g_print ("%d %s %s %s %s %s\n",
                   flatpak_ref_get_kind (FLATPAK_REF (remote_ref)),
                   flatpak_ref_get_name (FLATPAK_REF (remote_ref)),
                   flatpak_ref_get_arch (FLATPAK_REF (remote_ref)),
                   flatpak_ref_get_branch (FLATPAK_REF (remote_ref)),
                   flatpak_ref_get_commit (FLATPAK_REF (remote_ref)),
                   flatpak_remote_ref_get_remote_name (remote_ref));

          metadata = flatpak_installation_fetch_remote_metadata_sync (installation, flatpak_remote_get_name (remote),
                                                                      FLATPAK_REF (remote_ref), NULL, &error);
          if (metadata)
            {
              g_print ("metadata: %s\n", (char *) g_bytes_get_data (metadata, NULL));
            }
          else
            {
              g_print ("fetch error\n");
              g_print ("error: %s\n", error->message);
              g_clear_error (&error);
            }
        }
      else
        {
          g_print ("error: %s\n", error->message);
          g_clear_error (&error);
        }
    }
  return 0;
}

===== ./common/flatpak-installed-ref.c =====
/* vi:set et sw=2 sts=2 cin cino=t0,f0,(0,{s,>2s,n-s,^-s,e-s:
 * Copyright © 2015 Red Hat, Inc
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Alexander Larsson <alexl@redhat.com>
 */

#include "config.h"

#include <string.h>

#include "flatpak-utils-private.h"
#include "flatpak-installed-ref.h"
#include "flatpak-installed-ref-private.h"
#include "flatpak-enum-types.h"

/**
 * SECTION:flatpak-installed-ref
 * @Title: FlatpakInstalledRef
 * @Short_description: Installed application reference
 *
 * A FlatpakInstalledRef provides information about an installed
 * application or runtime (in short: ref), such as the available
 * builds, its size, location, etc.
 */

typedef struct _FlatpakInstalledRefPrivate FlatpakInstalledRefPrivate;

struct _FlatpakInstalledRefPrivate
{
  gboolean is_current;
  char    *origin;
  char    *latest_commit;
  char    *deploy_dir;
  char   **subpaths;
  guint64  installed_size;
  char    *eol;
  char    *eol_rebase;
  char    *appdata_name;
  char    *appdata_summary;
  char    *appdata_version;
  char    *appdata_license;
  char    *appdata_content_rating_type;
  GHashTable *appdata_content_rating;  /* (element-type interned-utf8 interned-utf8) */
};

G_DEFINE_TYPE_WITH_PRIVATE (FlatpakInstalledRef, flatpak_installed_ref, FLATPAK_TYPE_REF)

enum {
  PROP_0,

  PROP_IS_CURRENT,
  PROP_ORIGIN,
  PROP_LATEST_COMMIT,
  PROP_DEPLOY_DIR,
  PROP_INSTALLED_SIZE,
  PROP_SUBPATHS,
  PROP_EOL,
  PROP_EOL_REBASE,
  PROP_APPDATA_NAME,
  PROP_APPDATA_SUMMARY,
  PROP_APPDATA_VERSION,
  PROP_APPDATA_LICENSE,
  PROP_APPDATA_CONTENT_RATING_TYPE,
  PROP_APPDATA_CONTENT_RATING,
};

static void
flatpak_installed_ref_finalize (GObject *object)
{
  FlatpakInstalledRef *self = FLATPAK_INSTALLED_REF (object);
  FlatpakInstalledRefPrivate *priv = flatpak_installed_ref_get_instance_private (self);

  g_free (priv->origin);
  g_free (priv->latest_commit);
  g_free (priv->deploy_dir);
  g_strfreev (priv->subpaths);
  g_free (priv->eol);
  g_free (priv->eol_rebase);
  g_free (priv->appdata_name);
  g_free (priv->appdata_summary);
  g_free (priv->appdata_version);
  g_free (priv->appdata_license);
  g_free (priv->appdata_content_rating_type);
  g_clear_pointer (&priv->appdata_content_rating, g_hash_table_unref);

  G_OBJECT_CLASS (flatpak_installed_ref_parent_class)->finalize (object);
}

static void
flatpak_installed_ref_set_property (GObject      *object,
                                    guint         prop_id,
                                    const GValue *value,
                                    GParamSpec   *pspec)
{
  FlatpakInstalledRef *self = FLATPAK_INSTALLED_REF (object);
  FlatpakInstalledRefPrivate *priv = flatpak_installed_ref_get_instance_private (self);

  switch (prop_id)
    {
    case PROP_IS_CURRENT:
      priv->is_current = g_value_get_boolean (value);
      break;

    case PROP_INSTALLED_SIZE:
      priv->installed_size = g_value_get_uint64 (value);
      break;

    case PROP_ORIGIN:
      g_clear_pointer (&priv->origin, g_free);
      priv->origin = g_value_dup_string (value);
      break;

    case PROP_LATEST_COMMIT:
      g_clear_pointer (&priv->latest_commit, g_free);
      priv->latest_commit = g_value_dup_string (value);
      break;

    case PROP_DEPLOY_DIR:
      g_clear_pointer (&priv->deploy_dir, g_free);
      priv->deploy_dir = g_value_dup_string (value);
      break;

    case PROP_SUBPATHS:
      g_clear_pointer (&priv->subpaths, g_strfreev);
      priv->subpaths = g_strdupv (g_value_get_boxed (value));
      break;

    case PROP_EOL:
      g_clear_pointer (&priv->eol, g_free);
      priv->eol = g_value_dup_string (value);
      break;

    case PROP_EOL_REBASE:
      g_clear_pointer (&priv->eol_rebase, g_free);
      priv->eol_rebase = g_value_dup_string (value);
      break;

    case PROP_APPDATA_NAME:
      g_clear_pointer (&priv->appdata_name, g_free);
      priv->appdata_name = g_value_dup_string (value);
      break;

    case PROP_APPDATA_SUMMARY:
      g_clear_pointer (&priv->appdata_summary, g_free);
      priv->appdata_summary = g_value_dup_string (value);
      break;

    case PROP_APPDATA_VERSION:
      g_clear_pointer (&priv->appdata_version, g_free);
      priv->appdata_version = g_value_dup_string (value);
      break;

    case PROP_APPDATA_LICENSE:
      g_clear_pointer (&priv->appdata_license, g_free);
      priv->appdata_license = g_value_dup_string (value);
      break;

    case PROP_APPDATA_CONTENT_RATING_TYPE:
      g_clear_pointer (&priv->appdata_content_rating_type, g_free);
      priv->appdata_content_rating_type = g_value_dup_string (value);
      break;

    case PROP_APPDATA_CONTENT_RATING:
      g_clear_pointer (&priv->appdata_content_rating, g_hash_table_unref);
      priv->appdata_content_rating = g_value_dup_boxed (value);
      break;

    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
    }
}

static void
flatpak_installed_ref_get_property (GObject    *object,
                                    guint       prop_id,
                                    GValue     *value,
                                    GParamSpec *pspec)
{
  FlatpakInstalledRef *self = FLATPAK_INSTALLED_REF (object);
  FlatpakInstalledRefPrivate *priv = flatpak_installed_ref_get_instance_private (self);

  switch (prop_id)
    {
    case PROP_IS_CURRENT:
      g_value_set_boolean (value, priv->is_current);
      break;

    case PROP_INSTALLED_SIZE:
      g_value_set_uint64 (value, priv->installed_size);
      break;

    case PROP_ORIGIN:
      g_value_set_string (value, priv->origin);
      break;

    case PROP_LATEST_COMMIT:
      g_value_set_string (value, priv->latest_commit);
      break;

    case PROP_DEPLOY_DIR:
      g_value_set_string (value, priv->deploy_dir);
      break;

    case PROP_SUBPATHS:
      g_value_set_boxed (value, priv->subpaths);
      break;

    case PROP_EOL:
      g_value_set_string (value, priv->eol);
      break;

    case PROP_EOL_REBASE:
      g_value_set_string (value, priv->eol_rebase);
      break;

    case PROP_APPDATA_NAME:
      g_value_set_string (value, priv->appdata_name);
      break;

    case PROP_APPDATA_SUMMARY:
      g_value_set_string (value, priv->appdata_summary);
      break;

    case PROP_APPDATA_VERSION:
      g_value_set_string (value, priv->appdata_version);
      break;

    case PROP_APPDATA_LICENSE:
      g_value_set_string (value, priv->appdata_license);
      break;

    case PROP_APPDATA_CONTENT_RATING_TYPE:
      g_value_set_string (value, priv->appdata_content_rating_type);
      break;

    case PROP_APPDATA_CONTENT_RATING:
      g_value_set_boxed (value, priv->appdata_content_rating);
      break;

    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
    }
}

static void
flatpak_installed_ref_class_init (FlatpakInstalledRefClass *klass)
{
  GObjectClass *object_class = G_OBJECT_CLASS (klass);

  object_class->get_property = flatpak_installed_ref_get_property;
  object_class->set_property = flatpak_installed_ref_set_property;
  object_class->finalize = flatpak_installed_ref_finalize;

  g_object_class_install_property (object_class,
                                   PROP_IS_CURRENT,
                                   g_param_spec_boolean ("is-current",
                                                         "Is Current",
                                                         "Whether the application is current",
                                                         FALSE,
                                                         G_PARAM_READWRITE));
  g_object_class_install_property (object_class,
                                   PROP_INSTALLED_SIZE,
                                   g_param_spec_uint64 ("installed-size",
                                                        "Installed Size",
                                                        "The installed size of the application",
                                                        0, G_MAXUINT64, 0,
                                                        G_PARAM_READWRITE));
  g_object_class_install_property (object_class,
                                   PROP_ORIGIN,
                                   g_param_spec_string ("origin",
                                                        "Origin",
                                                        "The origin",
                                                        NULL,
                                                        G_PARAM_READWRITE));
  g_object_class_install_property (object_class,
                                   PROP_LATEST_COMMIT,
                                   g_param_spec_string ("latest-commit",
                                                        "Latest Commit",
                                                        "The latest commit",
                                                        NULL,
                                                        G_PARAM_READWRITE));
  g_object_class_install_property (object_class,
                                   PROP_DEPLOY_DIR,
                                   g_param_spec_string ("deploy-dir",
                                                        "Deploy Dir",
                                                        "Where the application is installed",
                                                        NULL,
                                                        G_PARAM_READWRITE));
  g_object_class_install_property (object_class,
                                   PROP_SUBPATHS,
                                   g_param_spec_boxed ("subpaths",
                                                       "Subpaths",
                                                       "The subpaths for a partially installed ref",
                                                       G_TYPE_STRV,
                                                       G_PARAM_READWRITE));
  g_object_class_install_property (object_class,
                                   PROP_EOL,
                                   g_param_spec_string ("end-of-life",
                                                        "End of life",
                                                        "The reason for the ref to be end of life",
                                                        NULL,
                                                        G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (object_class,
                                   PROP_EOL_REBASE,
                                   g_param_spec_string ("end-of-life-rebase",
                                                        "End of life rebase",
                                                        "The new ref for the end-of-lifed ref",
                                                        NULL,
                                                        G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (object_class,
                                   PROP_APPDATA_NAME,
                                   g_param_spec_string ("appdata-name",
                                                        "Appdata Name",
                                                        "The localized name field from the appdata",
                                                        NULL,
                                                        G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (object_class,
                                   PROP_APPDATA_SUMMARY,
                                   g_param_spec_string ("appdata-summary",
                                                        "Appdata Summary",
                                                        "The localized summary field from the appdata",
                                                        NULL,
                                                        G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (object_class,
                                   PROP_APPDATA_VERSION,
                                   g_param_spec_string ("appdata-version",
                                                        "Appdata Version",
                                                        "The default version field from the appdata",
                                                        NULL,
                                                        G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (object_class,
                                   PROP_APPDATA_LICENSE,
                                   g_param_spec_string ("appdata-license",
                                                        "Appdata License",
                                                        "The license from the appdata",
                                                        NULL,
                                                        G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (object_class,
                                   PROP_APPDATA_CONTENT_RATING_TYPE,
                                   g_param_spec_string ("appdata-content-rating-type",
                                                        "Appdata Content Rating Type",
                                                        "The type of the content rating data from the appdata",
                                                        NULL,
                                                        G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (object_class,
                                   PROP_APPDATA_CONTENT_RATING,
                                   g_param_spec_boxed ("appdata-content-rating",
                                                       "Appdata Content Rating",
                                                       "The content rating data from the appdata",
                                                       G_TYPE_HASH_TABLE,
                                                       G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
}

static void
flatpak_installed_ref_init (FlatpakInstalledRef *self)
{
}

/**
 * flatpak_installed_ref_get_origin:
 * @self: a #FlatpakInstalledRef
 *
 * Gets the origin of the ref.
 *
 * Returns: (transfer none): the origin
 */
const char *
flatpak_installed_ref_get_origin (FlatpakInstalledRef *self)
{
  FlatpakInstalledRefPrivate *priv = flatpak_installed_ref_get_instance_private (self);

  return priv->origin;
}

/**
 * flatpak_installed_ref_get_latest_commit:
 * @self: a #FlatpakInstalledRef
 *
 * Gets the latest commit of the ref.
 *
 * Returns: (transfer none) (nullable): the latest commit
 */
const char *
flatpak_installed_ref_get_latest_commit (FlatpakInstalledRef *self)
{
  FlatpakInstalledRefPrivate *priv = flatpak_installed_ref_get_instance_private (self);

  return priv->latest_commit;
}

/**
 * flatpak_installed_ref_get_deploy_dir:
 * @self: a #FlatpakInstalledRef
 *
 * Gets the deploy dir of the ref.
 *
 * Returns: (transfer none): the deploy dir
 */
const char *
flatpak_installed_ref_get_deploy_dir (FlatpakInstalledRef *self)
{
  FlatpakInstalledRefPrivate *priv = flatpak_installed_ref_get_instance_private (self);

  return priv->deploy_dir;
}

/**
 * flatpak_installed_ref_get_is_current:
 * @self: a #FlatpakInstalledRef
 *
 * Returns whether the ref is current.
 *
 * Returns: %TRUE if the ref is current
 */
gboolean
flatpak_installed_ref_get_is_current (FlatpakInstalledRef *self)
{
  FlatpakInstalledRefPrivate *priv = flatpak_installed_ref_get_instance_private (self);

  return priv->is_current;
}

/**
 * flatpak_installed_ref_get_subpaths:
 * @self: a #FlatpakInstalledRef
 *
 * Returns the subpaths that are installed, or %NULL if all files installed.
 *
 * Returns: (transfer none): A strv, or %NULL
 */
const char * const *
flatpak_installed_ref_get_subpaths (FlatpakInstalledRef *self)
{
  FlatpakInstalledRefPrivate *priv = flatpak_installed_ref_get_instance_private (self);

  return (const char * const *) priv->subpaths;
}

/**
 * flatpak_installed_ref_get_installed_size:
 * @self: a #FlatpakInstalledRef
 *
 * Returns the installed size of the ref.
 *
 * Returns: the installed size
 */
guint64
flatpak_installed_ref_get_installed_size (FlatpakInstalledRef *self)
{
  FlatpakInstalledRefPrivate *priv = flatpak_installed_ref_get_instance_private (self);

  return priv->installed_size;
}

/**
 * flatpak_installed_ref_load_metadata:
 * @self: a #FlatpakInstalledRef
 * @cancellable: (nullable): a #GCancellable
 * @error: a return location for a #GError
 *
 * Loads the metadata file for this ref.
 *
 * Returns: (transfer full): a #GBytes containing the metadata file,
 *     or %NULL if an error occurred
 */
GBytes *
flatpak_installed_ref_load_metadata (FlatpakInstalledRef *self,
                                     GCancellable        *cancellable,
                                     GError             **error)
{
  FlatpakInstalledRefPrivate *priv = flatpak_installed_ref_get_instance_private (self);
  g_autofree char *path = NULL;
  char *metadata;
  gsize length;

  if (priv->deploy_dir == NULL)
    {
      g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND,
                   "Unknown deploy directory");
      return NULL;
    }

  path = g_build_filename (priv->deploy_dir, "metadata", NULL);
  if (!g_file_get_contents (path, &metadata, &length, error))
    return NULL;

  return g_bytes_new_take (metadata, length);
}

/**
 * flatpak_installed_ref_load_appdata:
 * @self: a #FlatpakInstalledRef
 * @cancellable: (nullable): a #GCancellable
 * @error: a return location for a #GError
 *
 * Loads the compressed xml appdata for this ref (if it exists).
 *
 * Returns: (transfer full): a #GBytes containing the compressed appdata file,
 *     or %NULL if an error occurred
 *
 * Since: 1.1.2
 */
GBytes *
flatpak_installed_ref_load_appdata (FlatpakInstalledRef *self,
                                    GCancellable        *cancellable,
                                    GError             **error)
{
  FlatpakInstalledRefPrivate *priv = flatpak_installed_ref_get_instance_private (self);
  char *data;
  gsize length;
  g_autofree char *path = NULL;
  g_autofree char *appdata_name = NULL;

  if (priv->deploy_dir == NULL)
    {
      g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND,
                   "Unknown deploy directory");
      return NULL;
    }

  appdata_name = g_strconcat (flatpak_ref_get_name (FLATPAK_REF (self)), ".xml.gz", NULL);
  path = g_build_filename (priv->deploy_dir, "files/share/app-info/xmls", appdata_name, NULL);

  if (!g_file_get_contents (path, &data, &length, error))
    return NULL;

  return g_bytes_new_take (data, length);
}

/**
 * flatpak_installed_ref_get_eol:
 * @self: a #FlatpakInstalledRef
 *
 * Returns the end-of-life reason string, or %NULL if the
 * ref is not end-of-lifed.
 *
 * Returns: (transfer none): the end-of-life reason or %NULL
 */
const char *
flatpak_installed_ref_get_eol (FlatpakInstalledRef *self)
{
  FlatpakInstalledRefPrivate *priv = flatpak_installed_ref_get_instance_private (self);

  return priv->eol;
}

/**
 * flatpak_installed_ref_get_eol_rebase:
 * @self: a #FlatpakInstalledRef
 *
 * Returns the end-of-life rebased ref, or %NULL if the
 * ref is not end-of-lifed.
 *
 * Returns: (transfer none): the end-of-life rebased ref or %NULL
 */
const char *
flatpak_installed_ref_get_eol_rebase (FlatpakInstalledRef *self)
{
  FlatpakInstalledRefPrivate *priv = flatpak_installed_ref_get_instance_private (self);

  return priv->eol_rebase;
}

/**
 * flatpak_installed_ref_get_appdata_name:
 * @self: a #FlatpakInstalledRef
 *
 * Returns the name field from the appdata.
 *
 * The returned string is localized.
 *
 * Returns: (transfer none): the name or %NULL
 *
 * Since: 1.1.2
 */
const char *
flatpak_installed_ref_get_appdata_name (FlatpakInstalledRef *self)
{
  FlatpakInstalledRefPrivate *priv = flatpak_installed_ref_get_instance_private (self);

  return priv->appdata_name;
}

/**
 * flatpak_installed_ref_get_appdata_summary:
 * @self: a #FlatpakInstalledRef
 *
 * Returns the summary field from the appdata.
 *
 * The returned string is localized.
 *
 * Returns: (transfer none): the summary or %NULL
 *
 * Since: 1.1.2
 */
const char *
flatpak_installed_ref_get_appdata_summary (FlatpakInstalledRef *self)
{
  FlatpakInstalledRefPrivate *priv = flatpak_installed_ref_get_instance_private (self);

  return priv->appdata_summary;
}

/**
 * flatpak_installed_ref_get_appdata_version:
 * @self: a #FlatpakInstalledRef
 *
 * Returns the default version field from the appdata.
 *
 * Returns: (transfer none): the version or %NULL
 *
 * Since: 1.1.2
 */
const char *
flatpak_installed_ref_get_appdata_version (FlatpakInstalledRef *self)
{
  FlatpakInstalledRefPrivate *priv = flatpak_installed_ref_get_instance_private (self);

  return priv->appdata_version;
}

/**
 * flatpak_installed_ref_get_appdata_license:
 * @self: a #FlatpakInstalledRef
 *
 * Returns the license field from the appdata.
 *
 * Returns: (transfer none): the license or %NULL
 *
 * Since: 1.1.2
 */
const char *
flatpak_installed_ref_get_appdata_license (FlatpakInstalledRef *self)
{
  FlatpakInstalledRefPrivate *priv = flatpak_installed_ref_get_instance_private (self);

  return priv->appdata_license;
}

/**
 * flatpak_installed_ref_get_appdata_content_rating_type:
 * @self: a #FlatpakInstalledRef
 *
 * Returns the content rating type from the appdata. For example, `oars-1.0` or
 * `oars-1.1`.
 *
 * Returns: (transfer none) (nullable): the content rating type or %NULL
 *
 * Since: 1.4.2
 */
const char *
flatpak_installed_ref_get_appdata_content_rating_type (FlatpakInstalledRef *self)
{
  FlatpakInstalledRefPrivate *priv = flatpak_installed_ref_get_instance_private (self);

  return priv->appdata_content_rating_type;
}

/**
 * flatpak_installed_ref_get_appdata_content_rating:
 * @self: a #FlatpakInstalledRef
 *
 * Returns the content rating field from the appdata. This is a potentially
 * empty mapping of content rating attribute IDs to values, to be interpreted
 * by the semantics of the content rating type (see
 * flatpak_installed_ref_get_appdata_content_rating_type()).
 *
 * Returns: (transfer none) (nullable) (element-type utf8 utf8): the content
 * rating or %NULL
 *
 * Since: 1.4.2
 */
GHashTable *
flatpak_installed_ref_get_appdata_content_rating (FlatpakInstalledRef *self)
{
  FlatpakInstalledRefPrivate *priv = flatpak_installed_ref_get_instance_private (self);

  return priv->appdata_content_rating;
}

FlatpakInstalledRef *
flatpak_installed_ref_new (FlatpakDecomposed *decomposed,
                           const char  *commit,
                           const char  *latest_commit,
                           const char  *origin,
                           const char  *collection_id,
                           const char **subpaths,
                           const char  *deploy_dir,
                           guint64      installed_size,
                           gboolean     is_current,
                           const char  *eol,
                           const char  *eol_rebase,
                           const char  *appdata_name,
                           const char  *appdata_summary,
                           const char  *appdata_version,
                           const char  *appdata_license,
                           const char  *appdata_content_rating_type,
                           GHashTable  *appdata_content_rating)
{
  FlatpakInstalledRef *ref;

  /* Canonicalize the "no subpaths" case */
  if (subpaths && *subpaths == NULL)
    subpaths = NULL;

  ref = g_object_new (FLATPAK_TYPE_INSTALLED_REF,
                      "kind", flatpak_decomposed_get_kind (decomposed),
                      "name", flatpak_decomposed_peek_id (decomposed, NULL),
                      "arch", flatpak_decomposed_peek_arch (decomposed, NULL),
                      "branch", flatpak_decomposed_peek_branch (decomposed, NULL),
                      "commit", commit,
                      "latest-commit", latest_commit,
                      "origin", origin,
                      "collection-id", collection_id,
                      "subpaths", subpaths,
                      "is-current", is_current,
                      "installed-size", installed_size,
                      "deploy-dir", deploy_dir,
                      "end-of-life", eol,
                      "end-of-life-rebase", eol_rebase,
                      "appdata-name", appdata_name,
                      "appdata-summary", appdata_summary,
                      "appdata-version", appdata_version,
                      "appdata-license", appdata_license,
                      "appdata-content-rating-type", appdata_content_rating_type,
                      "appdata-content-rating", appdata_content_rating,
                      NULL);

  return ref;
}

===== ./common/flatpak-glib-backports.c =====
/* vi:set et sw=2 sts=2 cin cino=t0,f0,(0,{s,>2s,n-s,^-s,e-s:
 * Copyright 1995-1998 Free Software Foundation, Inc.
 * Copyright 2004 Hidetoshi Tajima
 * Copyright 2004-2010 Christian Persch
 * Copyright 2004-2019 Red Hat, Inc
 * Copyright 2016-2018 Canonical Ltd.
 * Copyright 2019 Endless OS Foundation LLC
 * Copyright 2019 Emmanuel Fleury
 * Copyright 2021 Joshua Lee
 * SPDX-License-Identifier: LGPL-2.1-or-later
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 */

#include "config.h"
#include "flatpak-glib-backports-private.h"

#include <glib/gi18n-lib.h>

/* Please sort this file by the GLib version where it originated,
 * oldest first. */

#if !GLIB_CHECK_VERSION (2, 54, 0)
/* All this code is backported directly from GLib 2.76.2 */
static gboolean
str_has_sign (const gchar *str)
{
  return str[0] == '-' || str[0] == '+';
}

static gboolean
str_has_hex_prefix (const gchar *str)
{
  return str[0] == '0' && g_ascii_tolower (str[1]) == 'x';
}

gboolean
g_ascii_string_to_unsigned (const gchar *str,
                            guint        base,
                            guint64      min,
                            guint64      max,
                            guint64     *out_num,
                            GError     **error)
{
  guint64 number;
  const gchar *end_ptr = NULL;
  gint saved_errno = 0;

  g_return_val_if_fail (str != NULL, FALSE);
  g_return_val_if_fail (base >= 2 && base <= 36, FALSE);
  g_return_val_if_fail (min <= max, FALSE);
  g_return_val_if_fail (error == NULL || *error == NULL, FALSE);

  if (str[0] == '\0')
    {
      g_set_error_literal (error,
                           G_NUMBER_PARSER_ERROR, G_NUMBER_PARSER_ERROR_INVALID,
                           _("Empty string is not a number"));
      return FALSE;
    }

  errno = 0;
  number = g_ascii_strtoull (str, (gchar **)&end_ptr, base);
  saved_errno = errno;

  if (/* We do not allow leading whitespace, but g_ascii_strtoull
       * accepts it and just skips it, so we need to check for it
       * ourselves.
       */
      g_ascii_isspace (str[0]) ||
      /* Unsigned number should have no sign.
       */
      str_has_sign (str) ||
      /* We don't support hexadecimal numbers prefixed with 0x or
       * 0X.
       */
      (base == 16 && str_has_hex_prefix (str)) ||
      (saved_errno != 0 && saved_errno != ERANGE) ||
      end_ptr == NULL ||
      *end_ptr != '\0')
    {
      g_set_error (error,
                   G_NUMBER_PARSER_ERROR, G_NUMBER_PARSER_ERROR_INVALID,
                   _("“%s” is not an unsigned number"), str);
      return FALSE;
    }
  if (saved_errno == ERANGE || number < min || number > max)
    {
      gchar *min_str = g_strdup_printf ("%" G_GUINT64_FORMAT, min);
      gchar *max_str = g_strdup_printf ("%" G_GUINT64_FORMAT, max);

      g_set_error (error,
                   G_NUMBER_PARSER_ERROR, G_NUMBER_PARSER_ERROR_OUT_OF_BOUNDS,
                   _("Number “%s” is out of bounds [%s, %s]"),
                   str, min_str, max_str);
      g_free (min_str);
      g_free (max_str);
      return FALSE;
    }
  if (out_num != NULL)
    *out_num = number;
  return TRUE;
}
#endif

#if !GLIB_CHECK_VERSION (2, 56, 0)
/* All this code is backported directly from GLib 2.76.2 except where noted */

static void
g_date_time_get_week_number (GDateTime *datetime,
                             gint      *week_number,
                             gint      *day_of_week,
                             gint      *day_of_year)
{
  gint a, b, c, d, e, f, g, n, s, month = -1, day = -1, year = -1;

  g_date_time_get_ymd (datetime, &year, &month, &day);

  if (month <= 2)
    {
      a = g_date_time_get_year (datetime) - 1;
      b = (a / 4) - (a / 100) + (a / 400);
      c = ((a - 1) / 4) - ((a - 1) / 100) + ((a - 1) / 400);
      s = b - c;
      e = 0;
      f = day - 1 + (31 * (month - 1));
    }
  else
    {
      a = year;
      b = (a / 4) - (a / 100) + (a / 400);
      c = ((a - 1) / 4) - ((a - 1) / 100) + ((a - 1) / 400);
      s = b - c;
      e = s + 1;
      f = day + (((153 * (month - 3)) + 2) / 5) + 58 + s;
    }

  g = (a + b) % 7;
  d = (f + g - e) % 7;
  n = f + 3 - d;

  if (week_number)
    {
      if (n < 0)
        *week_number = 53 - ((g - s) / 5);
      else if (n > 364 + s)
        *week_number = 1;
      else
        *week_number = (n / 7) + 1;
    }

  if (day_of_week)
    *day_of_week = d + 1;

  if (day_of_year)
    *day_of_year = f + 1;
}

#define GREGORIAN_LEAP(y)    ((((y) % 4) == 0) && (!((((y) % 100) == 0) && (((y) % 400) != 0))))

/* Parse integers in the form d (week days), dd (hours etc), ddd (ordinal days) or dddd (years) */
static gboolean
get_iso8601_int (const gchar *text, gsize length, gint *value)
{
  gsize i;
  guint v = 0;

  if (length < 1 || length > 4)
    return FALSE;

  for (i = 0; i < length; i++)
    {
      const gchar c = text[i];
      if (c < '0' || c > '9')
        return FALSE;
      v = v * 10 + (c - '0');
    }

  *value = v;
  return TRUE;
}

/* Parse seconds in the form ss or ss.sss (variable length decimal) */
static gboolean
get_iso8601_seconds (const gchar *text, gsize length, gdouble *value)
{
  gsize i;
  guint64 divisor = 1, v = 0;

  if (length < 2)
    return FALSE;

  for (i = 0; i < 2; i++)
    {
      const gchar c = text[i];
      if (c < '0' || c > '9')
        return FALSE;
      v = v * 10 + (c - '0');
    }

  if (length > 2 && !(text[i] == '.' || text[i] == ','))
    return FALSE;

  /* Ignore leap seconds, see g_date_time_new_from_iso8601() */
  if (v >= 60.0 && v <= 61.0)
    v = 59.0;

  i++;
  if (i == length)
    return FALSE;

  for (; i < length; i++)
    {
      const gchar c = text[i];
      if (c < '0' || c > '9' ||
          v > (G_MAXUINT64 - (c - '0')) / 10 ||
          divisor > G_MAXUINT64 / 10)
        return FALSE;
      v = v * 10 + (c - '0');
      divisor *= 10;
    }

  *value = (gdouble) v / divisor;
  return TRUE;
}

static GDateTime *
g_date_time_new_ordinal (GTimeZone *tz, gint year, gint ordinal_day, gint hour, gint minute, gdouble seconds)
{
  GDateTime *dt;

  if (ordinal_day < 1 || ordinal_day > (GREGORIAN_LEAP (year) ? 366 : 365))
    return NULL;

  dt = g_date_time_new (tz, year, 1, 1, hour, minute, seconds);
  if (dt == NULL)
    return NULL;
  dt->days += ordinal_day - 1;

  return dt;
}

static GDateTime *
g_date_time_new_week (GTimeZone *tz, gint year, gint week, gint week_day, gint hour, gint minute, gdouble seconds)
{
  gint64 p;
  gint max_week, jan4_week_day, ordinal_day;
  GDateTime *dt;

  p = (year * 365 + (year / 4) - (year / 100) + (year / 400)) % 7;
  max_week = p == 4 ? 53 : 52;

  if (week < 1 || week > max_week || week_day < 1 || week_day > 7)
    return NULL;

  dt = g_date_time_new (tz, year, 1, 4, 0, 0, 0);
  if (dt == NULL)
    return NULL;
  g_date_time_get_week_number (dt, NULL, &jan4_week_day, NULL);
  g_date_time_unref (dt);

  ordinal_day = (week * 7) + week_day - (jan4_week_day + 3);
  if (ordinal_day < 0)
    {
      year--;
      ordinal_day += GREGORIAN_LEAP (year) ? 366 : 365;
    }
  else if (ordinal_day > (GREGORIAN_LEAP (year) ? 366 : 365))
    {
      ordinal_day -= (GREGORIAN_LEAP (year) ? 366 : 365);
      year++;
    }

  return g_date_time_new_ordinal (tz, year, ordinal_day, hour, minute, seconds);
}

static GDateTime *
parse_iso8601_date (const gchar *text, gsize length,
                    gint hour, gint minute, gdouble seconds, GTimeZone *tz)
{
  /* YYYY-MM-DD */
  if (length == 10 && text[4] == '-' && text[7] == '-')
    {
      int year, month, day;
      if (!get_iso8601_int (text, 4, &year) ||
          !get_iso8601_int (text + 5, 2, &month) ||
          !get_iso8601_int (text + 8, 2, &day))
        return NULL;
      return g_date_time_new (tz, year, month, day, hour, minute, seconds);
    }
  /* YYYY-DDD */
  else if (length == 8 && text[4] == '-')
    {
      gint year, ordinal_day;
      if (!get_iso8601_int (text, 4, &year) ||
          !get_iso8601_int (text + 5, 3, &ordinal_day))
        return NULL;
      return g_date_time_new_ordinal (tz, year, ordinal_day, hour, minute, seconds);
    }
  /* YYYY-Www-D */
  else if (length == 10 && text[4] == '-' && text[5] == 'W' && text[8] == '-')
    {
      gint year, week, week_day;
      if (!get_iso8601_int (text, 4, &year) ||
          !get_iso8601_int (text + 6, 2, &week) ||
          !get_iso8601_int (text + 9, 1, &week_day))
        return NULL;
      return g_date_time_new_week (tz, year, week, week_day, hour, minute, seconds);
    }
  /* YYYYWwwD */
  else if (length == 8 && text[4] == 'W')
    {
      gint year, week, week_day;
      if (!get_iso8601_int (text, 4, &year) ||
          !get_iso8601_int (text + 5, 2, &week) ||
          !get_iso8601_int (text + 7, 1, &week_day))
        return NULL;
      return g_date_time_new_week (tz, year, week, week_day, hour, minute, seconds);
    }
  /* YYYYMMDD */
  else if (length == 8)
    {
      int year, month, day;
      if (!get_iso8601_int (text, 4, &year) ||
          !get_iso8601_int (text + 4, 2, &month) ||
          !get_iso8601_int (text + 6, 2, &day))
        return NULL;
      return g_date_time_new (tz, year, month, day, hour, minute, seconds);
    }
  /* YYYYDDD */
  else if (length == 7)
    {
      gint year, ordinal_day;
      if (!get_iso8601_int (text, 4, &year) ||
          !get_iso8601_int (text + 4, 3, &ordinal_day))
        return NULL;
      return g_date_time_new_ordinal (tz, year, ordinal_day, hour, minute, seconds);
    }
  else
    return FALSE;
}

static GTimeZone *
parse_iso8601_timezone (const gchar *text, gsize length, gssize *tz_offset)
{
  gint i, tz_length, offset_hours, offset_minutes;
  gint offset_sign = 1;
  GTimeZone *tz;

  /* UTC uses Z suffix  */
  if (length > 0 && text[length - 1] == 'Z')
    {
      *tz_offset = length - 1;
      return g_time_zone_new_utc ();
    }

  /* Look for '+' or '-' of offset */
  for (i = length - 1; i >= 0; i--)
    if (text[i] == '+' || text[i] == '-')
      {
        offset_sign = text[i] == '-' ? -1 : 1;
        break;
      }
  if (i < 0)
    return NULL;
  tz_length = length - i;

  /* +hh:mm or -hh:mm */
  if (tz_length == 6 && text[i+3] == ':')
    {
      if (!get_iso8601_int (text + i + 1, 2, &offset_hours) ||
          !get_iso8601_int (text + i + 4, 2, &offset_minutes))
        return NULL;
    }
  /* +hhmm or -hhmm */
  else if (tz_length == 5)
    {
      if (!get_iso8601_int (text + i + 1, 2, &offset_hours) ||
          !get_iso8601_int (text + i + 3, 2, &offset_minutes))
        return NULL;
    }
  /* +hh or -hh */
  else if (tz_length == 3)
    {
      if (!get_iso8601_int (text + i + 1, 2, &offset_hours))
        return NULL;
      offset_minutes = 0;
    }
  else
    return NULL;

  *tz_offset = i;
  /* BACKPORT DIFFERENCE: GLib uses g_time_zone_new_identifier() but that
   * was new in 2.68, so stick to the deprecated g_time_zone_new(), which
   * returns UTC on error */
  tz = g_time_zone_new (text + i);

  /* Double-check that the GTimeZone matches our interpretation of the timezone.
   * This can fail because our interpretation is less strict than (for example)
   * parse_time() in gtimezone.c, which restricts the range of the parsed
   * integers. */
  if (tz == NULL || g_time_zone_get_offset (tz, 0) != offset_sign * (offset_hours * 3600 + offset_minutes * 60))
    {
      g_clear_pointer (&tz, g_time_zone_unref);
      return NULL;
    }

  return tz;
}

static gboolean
parse_iso8601_time (const gchar *text, gsize length,
                    gint *hour, gint *minute, gdouble *seconds, GTimeZone **tz)
{
  gssize tz_offset = -1;

  /* Check for timezone suffix */
  *tz = parse_iso8601_timezone (text, length, &tz_offset);
  if (tz_offset >= 0)
    length = tz_offset;

  /* hh:mm:ss(.sss) */
  if (length >= 8 && text[2] == ':' && text[5] == ':')
    {
      return get_iso8601_int (text, 2, hour) &&
             get_iso8601_int (text + 3, 2, minute) &&
             get_iso8601_seconds (text + 6, length - 6, seconds);
    }
  /* hhmmss(.sss) */
  else if (length >= 6)
    {
      return get_iso8601_int (text, 2, hour) &&
             get_iso8601_int (text + 2, 2, minute) &&
             get_iso8601_seconds (text + 4, length - 4, seconds);
    }
  else
    return FALSE;
}

GDateTime *
flatpak_g_date_time_new_from_iso8601 (const gchar *text, GTimeZone *default_tz)
{
  gint length, date_length = -1;
  gint hour = 0, minute = 0;
  gdouble seconds = 0.0;
  GTimeZone *tz = NULL;
  GDateTime *datetime = NULL;

  g_return_val_if_fail (text != NULL, NULL);

  /* Count length of string and find date / time separator ('T', 't', or ' ') */
  for (length = 0; text[length] != '\0'; length++)
    {
      if (date_length < 0 && (text[length] == 'T' || text[length] == 't' || text[length] == ' '))
        date_length = length;
    }

  if (date_length < 0)
    return NULL;

  if (!parse_iso8601_time (text + date_length + 1, length - (date_length + 1),
                           &hour, &minute, &seconds, &tz))
    goto out;
  if (tz == NULL && default_tz == NULL)
    return NULL;

  datetime = parse_iso8601_date (text, date_length, hour, minute, seconds, tz ? tz : default_tz);

out:
    if (tz != NULL)
      g_time_zone_unref (tz);
    return datetime;
}
#endif

#if !GLIB_CHECK_VERSION (2, 58, 0)
/* All this code is backported directly from GLib 2.76.2 except where noted */

typedef struct _GLanguageNamesCache GLanguageNamesCache;

struct _GLanguageNamesCache {
  gchar *languages;
  gchar **language_names;
};

static void
language_names_cache_free (gpointer data)
{
  GLanguageNamesCache *cache = data;
  g_free (cache->languages);
  g_strfreev (cache->language_names);
  g_free (cache);
}

/* read an alias file for the locales */
static void
read_aliases (const gchar *file,
              GHashTable  *alias_table)
{
  FILE *fp;
  char buf[256];

  fp = fopen (file, "re");
  if (!fp)
    return;
  while (fgets (buf, 256, fp))
    {
      char *p, *q;

      g_strstrip (buf);

      /* Line is a comment */
      if ((buf[0] == '#') || (buf[0] == '\0'))
        continue;

      /* Reads first column */
      for (p = buf, q = NULL; *p; p++) {
        if ((*p == '\t') || (*p == ' ') || (*p == ':')) {
          *p = '\0';
          q = p+1;
          while ((*q == '\t') || (*q == ' ')) {
            q++;
          }
          break;
        }
      }
      /* The line only had one column */
      if (!q || *q == '\0')
        continue;

      /* Read second column */
      for (p = q; *p; p++) {
        if ((*p == '\t') || (*p == ' ')) {
          *p = '\0';
          break;
        }
      }

      /* Add to alias table if necessary */
      if (!g_hash_table_lookup (alias_table, buf)) {
        g_hash_table_insert (alias_table, g_strdup (buf), g_strdup (q));
      }
    }
  fclose (fp);
}

static char *
unalias_lang (char *lang)
{
#ifndef G_OS_WIN32
  static GHashTable *alias_table = NULL;
  char *p;
  int i;

  if (g_once_init_enter (&alias_table))
    {
      GHashTable *table = g_hash_table_new (g_str_hash, g_str_equal);
      read_aliases ("/usr/share/locale/locale.alias", table);
      g_once_init_leave (&alias_table, table);
    }

  i = 0;
  while ((p = g_hash_table_lookup (alias_table, lang)) && (strcmp (p, lang) != 0))
    {
      lang = p;
      if (i++ == 30)
        {
          static gboolean said_before = FALSE;
          if (!said_before)
            g_warning ("Too many alias levels for a locale, "
                       "may indicate a loop");
          said_before = TRUE;
          return lang;
        }
    }
#endif
  return lang;
}

/* Mask for components of locale spec. The ordering here is from
 * least significant to most significant
 */
enum
{
  COMPONENT_CODESET =   1 << 0,
  COMPONENT_TERRITORY = 1 << 1,
  COMPONENT_MODIFIER =  1 << 2
};

/* Break an X/Open style locale specification into components
 */
static guint
explode_locale (const gchar *locale,
                gchar      **language,
                gchar      **territory,
                gchar      **codeset,
                gchar      **modifier)
{
  const gchar *uscore_pos;
  const gchar *at_pos;
  const gchar *dot_pos;

  guint mask = 0;

  uscore_pos = strchr (locale, '_');
  dot_pos = strchr (uscore_pos ? uscore_pos : locale, '.');
  at_pos = strchr (dot_pos ? dot_pos : (uscore_pos ? uscore_pos : locale), '@');

  if (at_pos)
    {
      mask |= COMPONENT_MODIFIER;
      *modifier = g_strdup (at_pos);
    }
  else
    at_pos = locale + strlen (locale);

  if (dot_pos)
    {
      mask |= COMPONENT_CODESET;
      *codeset = g_strndup (dot_pos, at_pos - dot_pos);
    }
  else
    dot_pos = at_pos;

  if (uscore_pos)
    {
      mask |= COMPONENT_TERRITORY;
      *territory = g_strndup (uscore_pos, dot_pos - uscore_pos);
    }
  else
    uscore_pos = dot_pos;

  *language = g_strndup (locale, uscore_pos - locale);

  return mask;
}

/*
 * Compute all interesting variants for a given locale name -
 * by stripping off different components of the value.
 *
 * For simplicity, we assume that the locale is in
 * X/Open format: language[_territory][.codeset][@modifier]
 *
 * TODO: Extend this to handle the CEN format (see the GNUlibc docs)
 *       as well. We could just copy the code from glibc wholesale
 *       but it is big, ugly, and complicated, so I'm reluctant
 *       to do so when this should handle 99% of the time...
 */
static void
append_locale_variants (GPtrArray *array,
                        const gchar *locale)
{
  gchar *language = NULL;
  gchar *territory = NULL;
  gchar *codeset = NULL;
  gchar *modifier = NULL;

  guint mask;
  guint i, j;

  g_return_if_fail (locale != NULL);

  mask = explode_locale (locale, &language, &territory, &codeset, &modifier);

  /* Iterate through all possible combinations, from least attractive
   * to most attractive.
   */
  for (j = 0; j <= mask; ++j)
    {
      i = mask - j;

      if ((i & ~mask) == 0)
        {
          gchar *val = g_strconcat (language,
                                    (i & COMPONENT_TERRITORY) ? territory : "",
                                    (i & COMPONENT_CODESET) ? codeset : "",
                                    (i & COMPONENT_MODIFIER) ? modifier : "",
                                    NULL);
          g_ptr_array_add (array, val);
        }
    }

  g_free (language);
  if (mask & COMPONENT_CODESET)
    g_free (codeset);
  if (mask & COMPONENT_TERRITORY)
    g_free (territory);
  if (mask & COMPONENT_MODIFIER)
    g_free (modifier);
}

/* The following is (partly) taken from the gettext package.
   Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc.  */

static const gchar *
guess_category_value (const gchar *category_name)
{
  const gchar *retval;

  /* The highest priority value is the 'LANGUAGE' environment
     variable.  This is a GNU extension.  */
  retval = g_getenv ("LANGUAGE");
  if ((retval != NULL) && (retval[0] != '\0'))
    return retval;

  /* 'LANGUAGE' is not set.  So we have to proceed with the POSIX
     methods of looking to 'LC_ALL', 'LC_xxx', and 'LANG'.  On some
     systems this can be done by the 'setlocale' function itself.  */

  /* Setting of LC_ALL overwrites all other.  */
  retval = g_getenv ("LC_ALL");
  if ((retval != NULL) && (retval[0] != '\0'))
    return retval;

  /* Next comes the name of the desired category.  */
  retval = g_getenv (category_name);
  if ((retval != NULL) && (retval[0] != '\0'))
    return retval;

  /* Last possibility is the LANG environment variable.  */
  retval = g_getenv ("LANG");
  if ((retval != NULL) && (retval[0] != '\0'))
    return retval;

#ifdef G_PLATFORM_WIN32
  /* g_win32_getlocale() first checks for LC_ALL, LC_MESSAGES and
   * LANG, which we already did above. Oh well. The main point of
   * calling g_win32_getlocale() is to get the thread's locale as used
   * by Windows and the Microsoft C runtime (in the "English_United
   * States" format) translated into the Unixish format.
   */
  {
    char *locale = g_win32_getlocale ();
    retval = g_intern_string (locale);
    g_free (locale);
    return retval;
  }
#endif

  return NULL;
}

const gchar * const *
g_get_language_names_with_category (const gchar *category_name)
{
  static GPrivate cache_private = G_PRIVATE_INIT ((void (*)(gpointer)) g_hash_table_unref);
  GHashTable *cache = g_private_get (&cache_private);
  const gchar *languages;
  GLanguageNamesCache *name_cache;

  g_return_val_if_fail (category_name != NULL, NULL);

  if (!cache)
    {
      cache = g_hash_table_new_full (g_str_hash, g_str_equal,
                                     g_free, language_names_cache_free);
      g_private_set (&cache_private, cache);
    }

  languages = guess_category_value (category_name);
  if (!languages)
    languages = "C";

  name_cache = (GLanguageNamesCache *) g_hash_table_lookup (cache, category_name);
  if (!(name_cache && name_cache->languages &&
        strcmp (name_cache->languages, languages) == 0))
    {
      GPtrArray *array;
      gchar **alist, **a;

      g_hash_table_remove (cache, category_name);

      array = g_ptr_array_sized_new (8);

      alist = g_strsplit (languages, ":", 0);
      for (a = alist; *a; a++)
        append_locale_variants (array, unalias_lang (*a));
      g_strfreev (alist);
      g_ptr_array_add (array, g_strdup ("C"));
      g_ptr_array_add (array, NULL);

      name_cache = g_new0 (GLanguageNamesCache, 1);
      name_cache->languages = g_strdup (languages);
      name_cache->language_names = (gchar **) g_ptr_array_free (array, FALSE);
      g_hash_table_insert (cache, g_strdup (category_name), name_cache);
    }

  return (const gchar * const *) name_cache->language_names;
}
#endif

#if !GLIB_CHECK_VERSION (2, 62, 0)
/* This is a reimplementation, not a backport: the version in GLib makes
 * use of GPtrArray internals */
void
g_ptr_array_extend (GPtrArray  *array_to_extend,
                    GPtrArray  *array,
                    GCopyFunc   func,
                    gpointer    user_data)
{
  for (gsize i = 0; i < array->len; i++)
    {
      if (func)
        g_ptr_array_add (array_to_extend, func (g_ptr_array_index (array, i), user_data));
      else
        g_ptr_array_add (array_to_extend, g_ptr_array_index (array, i));
    }
}
#endif

#if !GLIB_CHECK_VERSION (2, 68, 0)
/* All this code is backported directly from GLib 2.76.2 */
guint
g_string_replace (GString     *string,
                  const gchar *find,
                  const gchar *replace,
                  guint        limit)
{
  gsize f_len, r_len, pos;
  gchar *cur, *next;
  guint n = 0;

  g_return_val_if_fail (string != NULL, 0);
  g_return_val_if_fail (find != NULL, 0);
  g_return_val_if_fail (replace != NULL, 0);

  f_len = strlen (find);
  r_len = strlen (replace);
  cur = string->str;

  while ((next = strstr (cur, find)) != NULL)
    {
      pos = next - string->str;
      g_string_erase (string, pos, f_len);
      g_string_insert (string, pos, replace);
      cur = string->str + pos + r_len;
      n++;
      /* Only match the empty string once at any given position, to
       * avoid infinite loops */
      if (f_len == 0)
        {
          if (cur[0] == '\0')
            break;
          else
            cur++;
        }
      if (n == limit)
        break;
    }

  return n;
}

#endif /* GLIB_CHECK_VERSION (2, 68, 0) */

===== ./common/flatpak-related-ref.c =====
/* vi:set et sw=2 sts=2 cin cino=t0,f0,(0,{s,>2s,n-s,^-s,e-s:
 * Copyright © 2015 Red Hat, Inc
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Alexander Larsson <alexl@redhat.com>
 */

#include "config.h"

#include <string.h>

#include "flatpak-utils-private.h"
#include "flatpak-related-ref.h"
#include "flatpak-related-ref-private.h"
#include "flatpak-enum-types.h"

/**
 * SECTION:flatpak-related-ref
 * @Title: FlatpakRelatedRef
 * @Short_description: Related application reference
 *
 * A FlatpakRelatedRef provides information about a ref that is related
 * to another ref. For instance, the local extension ref of an app.
 *
 * Since: 0.6.7
 */

typedef struct _FlatpakRelatedRefPrivate FlatpakRelatedRefPrivate;

struct _FlatpakRelatedRefPrivate
{
  char   **subpaths;
  gboolean download;
  gboolean delete;
  gboolean autoprune;
};

G_DEFINE_TYPE_WITH_PRIVATE (FlatpakRelatedRef, flatpak_related_ref, FLATPAK_TYPE_REF)

enum {
  PROP_0,

  PROP_SUBPATHS,
  PROP_SHOULD_DOWNLOAD,
  PROP_SHOULD_DELETE,
  PROP_SHOULD_AUTOPRUNE,
};

static void
flatpak_related_ref_finalize (GObject *object)
{
  FlatpakRelatedRef *self = FLATPAK_RELATED_REF (object);
  FlatpakRelatedRefPrivate *priv = flatpak_related_ref_get_instance_private (self);

  g_strfreev (priv->subpaths);

  G_OBJECT_CLASS (flatpak_related_ref_parent_class)->finalize (object);
}

static void
flatpak_related_ref_set_property (GObject      *object,
                                  guint         prop_id,
                                  const GValue *value,
                                  GParamSpec   *pspec)
{
  FlatpakRelatedRef *self = FLATPAK_RELATED_REF (object);
  FlatpakRelatedRefPrivate *priv = flatpak_related_ref_get_instance_private (self);

  switch (prop_id)
    {
    case PROP_SHOULD_DOWNLOAD:
      priv->download = g_value_get_boolean (value);
      break;

    case PROP_SHOULD_DELETE:
      priv->delete = g_value_get_boolean (value);
      break;

    case PROP_SHOULD_AUTOPRUNE:
      priv->autoprune = g_value_get_boolean (value);
      break;

    case PROP_SUBPATHS:
      g_clear_pointer (&priv->subpaths, g_strfreev);
      priv->subpaths = g_strdupv (g_value_get_boxed (value));
      break;

    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
    }
}

static void
flatpak_related_ref_get_property (GObject    *object,
                                  guint       prop_id,
                                  GValue     *value,
                                  GParamSpec *pspec)
{
  FlatpakRelatedRef *self = FLATPAK_RELATED_REF (object);
  FlatpakRelatedRefPrivate *priv = flatpak_related_ref_get_instance_private (self);

  switch (prop_id)
    {
    case PROP_SHOULD_DOWNLOAD:
      g_value_set_boolean (value, priv->download);
      break;

    case PROP_SHOULD_DELETE:
      g_value_set_boolean (value, priv->delete);
      break;

    case PROP_SHOULD_AUTOPRUNE:
      g_value_set_boolean (value, priv->autoprune);
      break;

    case PROP_SUBPATHS:
      g_value_set_boxed (value, priv->subpaths);
      break;

    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
    }
}

static void
flatpak_related_ref_class_init (FlatpakRelatedRefClass *klass)
{
  GObjectClass *object_class = G_OBJECT_CLASS (klass);

  object_class->get_property = flatpak_related_ref_get_property;
  object_class->set_property = flatpak_related_ref_set_property;
  object_class->finalize = flatpak_related_ref_finalize;

  g_object_class_install_property (object_class,
                                   PROP_SHOULD_DOWNLOAD,
                                   g_param_spec_boolean ("should-download",
                                                         "Should download",
                                                         "Whether to auto-download the ref with the main ref",
                                                         FALSE,
                                                         G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (object_class,
                                   PROP_SHOULD_DELETE,
                                   g_param_spec_boolean ("should-delete",
                                                         "Should delete",
                                                         "Whether to auto-delete the ref with the main ref",
                                                         FALSE,
                                                         G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (object_class,
                                   PROP_SHOULD_AUTOPRUNE,
                                   g_param_spec_boolean ("should-autoprune",
                                                         "Should autoprune",
                                                         "Whether to delete when pruning unused refs",
                                                         FALSE,
                                                         G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (object_class,
                                   PROP_SUBPATHS,
                                   g_param_spec_boxed ("subpaths",
                                                       "Subpaths",
                                                       "The subpaths for a partially installed ref",
                                                       G_TYPE_STRV,
                                                       G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
}

static void
flatpak_related_ref_init (FlatpakRelatedRef *self)
{
}

/**
 * flatpak_related_ref_should_download:
 * @self: a #FlatpakRelatedRef
 *
 * Returns whether to auto-download the ref with the main ref.
 *
 * Returns: %TRUE if the ref should be downloaded with the main ref.
 *
 * Since: 0.6.7
 */
gboolean
flatpak_related_ref_should_download (FlatpakRelatedRef *self)
{
  FlatpakRelatedRefPrivate *priv = flatpak_related_ref_get_instance_private (self);

  return priv->download;
}

/**
 * flatpak_related_ref_should_delete:
 * @self: a #FlatpakRelatedRef
 *
 * Returns whether to auto-delete the ref with the main ref.
 *
 * Returns: %TRUE if the ref should be deleted with the main ref.
 *
 * Since: 0.6.7
 */
gboolean
flatpak_related_ref_should_delete (FlatpakRelatedRef *self)
{
  FlatpakRelatedRefPrivate *priv = flatpak_related_ref_get_instance_private (self);

  return priv->delete;
}

/**
 * flatpak_related_ref_should_autoprune:
 * @self: a #FlatpakRelatedRef
 *
 * Returns whether to delete when pruning unused refs.
 *
 * Returns: %TRUE if the ref should be considered unused when pruning.
 *
 * Since: 0.11.8
 */
gboolean
flatpak_related_ref_should_autoprune (FlatpakRelatedRef *self)
{
  FlatpakRelatedRefPrivate *priv = flatpak_related_ref_get_instance_private (self);

  return priv->autoprune;
}

/**
 * flatpak_related_ref_get_subpaths:
 * @self: a #FlatpakRelatedRef
 *
 * Returns the subpaths that should be installed/updated for the ref.
 * This returns %NULL if all files should be installed.
 *
 * Returns: (transfer none): A strv, or %NULL
 *
 * Since: 0.6.7
 */
const char * const *
flatpak_related_ref_get_subpaths (FlatpakRelatedRef *self)
{
  FlatpakRelatedRefPrivate *priv = flatpak_related_ref_get_instance_private (self);

  return (const char * const *) priv->subpaths;
}

/**
 * flatpak_related_ref_new:
 * @full_ref: a full ref to refer to
 * @commit: (nullable): a commit ID to refer to
 * @subpaths: (nullable): a nul-terminated array of subpaths
 * @download: whether to auto-download the ref with the main ref
 * @delete: whether to auto-delete the ref with the main ref
 *
 * Creates a new FlatpakRelatedRef object.
 *
 * Returns: a new ref
 */
FlatpakRelatedRef *
flatpak_related_ref_new (const char *full_ref,
                         const char *commit,
                         char      **subpaths,
                         gboolean    download,
                         gboolean    delete)
{
  FlatpakRefKind kind = FLATPAK_REF_KIND_APP;
  FlatpakRelatedRef *ref;
  g_auto(GStrv) parts = NULL;

  parts = g_strsplit (full_ref, "/", -1);

  if (strcmp (parts[0], "app") != 0)
    kind = FLATPAK_REF_KIND_RUNTIME;

  /* Canonicalize the "no subpaths" case */
  if (subpaths && *subpaths == NULL)
    subpaths = NULL;

  ref = g_object_new (FLATPAK_TYPE_RELATED_REF,
                      "kind", kind,
                      "name", parts[1],
                      "arch", parts[2],
                      "branch", parts[3],
                      "commit", commit,
                      "subpaths", subpaths,
                      "should-download", download,
                      "should-delete", delete,
                      NULL);

  return ref;
}

===== ./common/flatpak-locale-utils-private.h =====
/*
 * Copyright © 2014 Red Hat, Inc
 * Copyright © 2023 Collabora Ltd.
 * SPDX-License-Identifier: LGPL-2.1-or-later
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Alexander Larsson <alexl@redhat.com>
 */

#pragma once

#include <gio/gio.h>

const char * const *flatpak_get_locale_categories (void);
char *flatpak_get_lang_from_locale (const char *locale);
char **flatpak_get_current_locale_langs (void);
const GPtrArray *flatpak_get_system_locales (void);
const GPtrArray *flatpak_get_user_locales (void);

/* Only for regression tests, should not be used directly */
GDBusProxy *flatpak_locale_get_localed_dbus_proxy (void);
void flatpak_get_locale_langs_from_localed_dbus (GDBusProxy *proxy,
                                                 GPtrArray  *langs);
GDBusProxy *flatpak_locale_get_accounts_dbus_proxy (void);
gboolean flatpak_get_all_langs_from_accounts_dbus (GDBusProxy *proxy,
                                                   GPtrArray  *langs);
void flatpak_get_locale_langs_from_accounts_dbus (GDBusProxy *proxy,
                                                  GPtrArray  *langs);
void flatpak_get_locale_langs_from_accounts_dbus_for_user (GDBusProxy *proxy,
                                                           GPtrArray  *langs,
                                                           guint uid);

===== ./common/flatpak-run.c =====
/* vi:set et sw=2 sts=2 cin cino=t0,f0,(0,{s,>2s,n-s,^-s,e-s:
 * Copyright © 2014-2019 Red Hat, Inc
 * Copyright © 2024 GNOME Foundation, Inc.
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Alexander Larsson <alexl@redhat.com>
 *       Hubert Figuière <hub@figuiere.net>
 */

#include "config.h"

#include <string.h>
#include <ctype.h>
#include <fcntl.h>
#include <gio/gdesktopappinfo.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/utsname.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <sys/vfs.h>
#include <sys/wait.h>
#include <sys/personality.h>
#include <grp.h>
#include <unistd.h>
#include <gio/gunixfdlist.h>
#ifdef HAVE_DCONF
#include <dconf/dconf.h>
#endif
#ifdef HAVE_LIBMALCONTENT
#include <libmalcontent/malcontent.h>
#endif

#include "flatpak-syscalls-private.h"

#ifdef ENABLE_SECCOMP
#include <seccomp.h>
#endif

#include <glib/gi18n-lib.h>

#include <gio/gio.h>
#include "libglnx.h"

#include "flatpak-dbus-generated.h"
#include "flatpak-run-dbus-private.h"
#include "flatpak-run-private.h"
#include "flatpak-run-sockets-private.h"
#include "flatpak-run-wayland-private.h"
#include "flatpak-utils-base-private.h"
#include "flatpak-dir-private.h"
#include "flatpak-dir-utils-private.h"
#include "flatpak-instance-private.h"
#include "flatpak-systemd-dbus-generated.h"
#include "flatpak-document-dbus-generated.h"
#include "flatpak-error.h"
#include "session-helper/flatpak-session-helper.h"

#define DEFAULT_SHELL "/bin/sh"

typedef FlatpakSessionHelper AutoFlatpakSessionHelper;
G_DEFINE_AUTOPTR_CLEANUP_FUNC (AutoFlatpakSessionHelper, g_object_unref)

typedef XdpDbusDocuments AutoXdpDbusDocuments;
G_DEFINE_AUTOPTR_CLEANUP_FUNC (AutoXdpDbusDocuments, g_object_unref)

/* flags enum for org.freedesktop.portal.Documents.AddFull */
typedef enum {
  DOCUMENT_ADD_FLAGS_REUSE_EXISTING             = (1 << 0),
  DOCUMENT_ADD_FLAGS_PERSISTENT                 = (1 << 1),
  DOCUMENT_ADD_FLAGS_AS_NEEDED_BY_APP           = (1 << 2),
  DOCUMENT_ADD_FLAGS_DIRECTORY                  = (1 << 3),

  DOCUMENT_ADD_FLAGS_FLAGS_ALL                  = ((1 << 4) - 1)
} DocumentAddFullFlags;

static int
flatpak_extension_compare_by_path (gconstpointer _a,
                                   gconstpointer _b)
{
  const FlatpakExtension *a = _a;
  const FlatpakExtension *b = _b;

  return g_strcmp0 (a->directory, b->directory);
}

void
flatpak_run_extend_ld_path (FlatpakBwrap *bwrap,
                            const char *prepend,
                            const char *append)
{
  g_autoptr(GString) ld_library_path = g_string_new (g_environ_getenv (bwrap->envp, "LD_LIBRARY_PATH"));

  if (prepend != NULL && *prepend != '\0')
    {
      if (ld_library_path->len > 0)
        g_string_prepend (ld_library_path, ":");

      g_string_prepend (ld_library_path, prepend);
    }

  if (append != NULL && *append != '\0')
    {
      if (ld_library_path->len > 0)
        g_string_append (ld_library_path, ":");

      g_string_append (ld_library_path, append);
    }

  flatpak_bwrap_set_env (bwrap, "LD_LIBRARY_PATH", ld_library_path->str, TRUE);
}

gboolean
flatpak_run_add_extension_args (FlatpakBwrap      *bwrap,
                                GKeyFile          *metakey,
                                FlatpakDecomposed *ref,
                                gboolean           use_ld_so_cache,
                                const char        *target_path,
                                char             **extensions_out,
                                char             **ld_path_out,
                                GCancellable      *cancellable,
                                GError           **error)
{
  g_autoptr(GString) used_extensions = g_string_new ("");
  GList *extensions, *path_sorted_extensions, *l;
  g_autoptr(GString) ld_library_path = g_string_new ("");
  int count = 0;
  g_autoptr(GHashTable) mounted_tmpfs =
    g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
  g_autoptr(GHashTable) created_symlink =
    g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
  g_autofree char *arch = flatpak_decomposed_dup_arch (ref);
  const char *branch = flatpak_decomposed_get_branch (ref);

  g_return_val_if_fail (target_path != NULL, FALSE);

  extensions = flatpak_list_extensions (metakey, arch, branch);

  /* First we apply all the bindings, they are sorted alphabetically in order for parent directory
     to be mounted before child directories */
  path_sorted_extensions = g_list_copy (extensions);
  path_sorted_extensions = g_list_sort (path_sorted_extensions, flatpak_extension_compare_by_path);

  for (l = path_sorted_extensions; l != NULL; l = l->next)
    {
      FlatpakExtension *ext = l->data;
      g_autofree char *directory = g_build_filename (target_path, ext->directory, NULL);
      g_autofree char *full_directory = g_build_filename (directory, ext->subdir_suffix, NULL);
      g_autofree char *ref_file = g_build_filename (full_directory, ".ref", NULL);
      g_autofree char *real_ref = g_build_filename (ext->files_path, ext->directory, ".ref", NULL);

      if (ext->needs_tmpfs)
        {
          g_autofree char *parent = g_path_get_dirname (directory);

          if (!g_hash_table_contains (mounted_tmpfs, parent))
            {
              flatpak_bwrap_add_args (bwrap,
                                      "--tmpfs", parent,
                                      NULL);
              g_hash_table_add (mounted_tmpfs, g_steal_pointer (&parent));
            }
        }

      flatpak_bwrap_add_args (bwrap,
                              "--ro-bind", ext->files_path, full_directory,
                              NULL);

      if (g_file_test (real_ref, G_FILE_TEST_EXISTS))
        flatpak_bwrap_add_args (bwrap,
                                "--lock-file", ref_file,
                                NULL);
    }

  g_list_free (path_sorted_extensions);

  /* Then apply library directories and file merging, in extension prio order */

  for (l = extensions; l != NULL; l = l->next)
    {
      FlatpakExtension *ext = l->data;
      g_autofree char *directory = g_build_filename (target_path, ext->directory, NULL);
      g_autofree char *full_directory = g_build_filename (directory, ext->subdir_suffix, NULL);
      int i;

      if (used_extensions->len > 0)
        g_string_append (used_extensions, ";");
      g_string_append (used_extensions, ext->installed_id);
      g_string_append (used_extensions, "=");
      if (ext->commit != NULL)
        g_string_append (used_extensions, ext->commit);
      else
        g_string_append (used_extensions, "local");

      if (ext->add_ld_path)
        {
          g_autofree char *ld_path = g_build_filename (full_directory, ext->add_ld_path, NULL);

          if (use_ld_so_cache)
            {
              g_autofree char *contents = g_strconcat (ld_path, "\n", NULL);
              /* We prepend app or runtime and a counter in order to get the include order correct for the conf files */
              g_autofree char *ld_so_conf_file = g_strdup_printf ("%s-%03d-%s.conf", flatpak_decomposed_get_kind_str (ref), ++count, ext->installed_id);
              g_autofree char *ld_so_conf_file_path = g_build_filename ("/run/flatpak/ld.so.conf.d", ld_so_conf_file, NULL);

              if (!flatpak_bwrap_add_args_data (bwrap, "ld-so-conf",
                                                contents, -1, ld_so_conf_file_path, error))
                return FALSE;
            }
          else
            {
              if (ld_library_path->len != 0)
                g_string_append (ld_library_path, ":");
              g_string_append (ld_library_path, ld_path);
            }
        }

      for (i = 0; ext->merge_dirs != NULL && ext->merge_dirs[i] != NULL; i++)
        {
          g_autofree char *parent = g_path_get_dirname (directory);
          g_autofree char *merge_dir = g_build_filename (parent, ext->merge_dirs[i], NULL);
          g_autofree char *source_dir = g_build_filename (ext->files_path, ext->merge_dirs[i], NULL);
          g_auto(GLnxDirFdIterator) source_iter = { 0 };
          struct dirent *dent;

          if (glnx_dirfd_iterator_init_at (AT_FDCWD, source_dir, TRUE, &source_iter, NULL))
            {
              while (glnx_dirfd_iterator_next_dent (&source_iter, &dent, NULL, NULL) && dent != NULL)
                {
                  g_autofree char *symlink_path = g_build_filename (merge_dir, dent->d_name, NULL);
                  /* Only create the first, because extensions are listed in prio order */
                  if (!g_hash_table_contains (created_symlink, symlink_path))
                    {
                      g_autofree char *symlink = g_build_filename (directory, ext->merge_dirs[i], dent->d_name, NULL);
                      flatpak_bwrap_add_args (bwrap,
                                              "--symlink", symlink, symlink_path,
                                              NULL);
                      g_hash_table_add (created_symlink, g_steal_pointer (&symlink_path));
                    }
                }
            }
        }
    }

  g_list_free_full (extensions, (GDestroyNotify) flatpak_extension_free);

  if (extensions_out)
    *extensions_out = g_string_free (g_steal_pointer (&used_extensions), FALSE);

  if (ld_path_out)
    *ld_path_out = g_string_free (g_steal_pointer (&ld_library_path), FALSE);

  return TRUE;
}

static gboolean
check_usb_portal (void)
{
  g_autoptr(GDBusConnection) bus = NULL;
  g_autoptr(GVariant) ret = NULL;
  g_autoptr(GError) error = NULL;

  bus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL);
  if (!bus)
    return FALSE;

  ret = g_dbus_connection_call_sync (bus,
                                     "org.freedesktop.portal.Desktop",
                                     "/org/freedesktop/portal/desktop",
                                     "org.freedesktop.DBus.Properties",
                                     "Get",
                                     g_variant_new ("(ss)",
                                                    "org.freedesktop.portal.Usb",
                                                    "version"),
                                     G_VARIANT_TYPE ("(v)"),
                                     G_DBUS_CALL_FLAGS_NONE,
                                     -1,
                                     NULL,
                                     &error);
  if (ret)
    return TRUE;

  if (!g_error_matches (error, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS) &&
      !g_error_matches (error, G_DBUS_ERROR, G_DBUS_ERROR_SERVICE_UNKNOWN) &&
      !g_error_matches (error, G_DBUS_ERROR, G_DBUS_ERROR_NAME_HAS_NO_OWNER))
    g_warning ("Querying availability of USB Portal failed: %s", error->message);

  return FALSE;
}

static gboolean
flatpak_run_has_usb_portal (void)
{
  static gsize usb_portal_once = 0;
  enum {
    HAS_USB_PORTAL_TRUE = 1,
    HAS_USB_PORTAL_FALSE = 2
  };

  if (g_once_init_enter (&usb_portal_once))
    {
      g_once_init_leave (&usb_portal_once, check_usb_portal () ?
                                           HAS_USB_PORTAL_TRUE :
                                           HAS_USB_PORTAL_FALSE);
    }

  return usb_portal_once == HAS_USB_PORTAL_TRUE;
}

static gboolean
flatpak_run_evaluate_conditions (FlatpakContextConditions condition)
{
  switch (condition)
    {
    case FLATPAK_CONTEXT_CONDITION_HAS_WAYLAND:
      return flatpak_run_has_wayland ();
    case FLATPAK_CONTEXT_CONDITION_HAS_USB_PORTAL:
      return flatpak_run_has_usb_portal ();
    default:
      return FALSE;
    }
}

/*
 * @per_app_dir_lock_fd: If >= 0, make use of per-app directories in
 *  the host's XDG_RUNTIME_DIR to share /tmp between instances.
 */
gboolean
flatpak_run_add_environment_args (FlatpakBwrap           *bwrap,
                                  const char             *app_info_path,
                                  FlatpakRunFlags         flags,
                                  const char             *app_id,
                                  FlatpakContext         *context,
                                  FlatpakContextShares    shares,
                                  FlatpakContextDevices   devices,
                                  FlatpakContextSockets   sockets,
                                  FlatpakContextFeatures  features,
                                  GFile                  *app_id_dir,
                                  GPtrArray              *previous_app_id_dirs,
                                  int                     per_app_dir_lock_fd,
                                  const char             *instance_id,
                                  FlatpakExports        **exports_out,
                                  GCancellable           *cancellable,
                                  GError                **error)
{
  g_autoptr(GError) my_error = NULL;
  g_autoptr(FlatpakExports) exports = NULL;
  g_autoptr(FlatpakBwrap) proxy_arg_bwrap = flatpak_bwrap_new (flatpak_bwrap_empty_env);
  g_autofree char *xdg_dirs_conf = NULL;
  gboolean home_access = FALSE;
  gboolean sandboxed = (flags & FLATPAK_RUN_FLAG_SANDBOX) != 0;

  if ((shares & FLATPAK_CONTEXT_SHARED_IPC) == 0)
    {
      g_info ("Disallowing ipc access");
      flatpak_bwrap_add_args (bwrap, "--unshare-ipc", NULL);
    }

  if ((shares & FLATPAK_CONTEXT_SHARED_NETWORK) == 0)
    {
      g_info ("Disallowing network access");
      flatpak_bwrap_add_args (bwrap, "--unshare-net", NULL);
    }

  if (devices & FLATPAK_CONTEXT_DEVICE_ALL)
    {
      flatpak_bwrap_add_args (bwrap,
                              "--dev-bind", "/dev", "/dev",
                              NULL);
      /* Don't expose the host /dev/shm, just the device nodes, unless explicitly allowed */
      if (g_file_test ("/dev/shm", G_FILE_TEST_IS_DIR))
        {
          if (devices & FLATPAK_CONTEXT_DEVICE_SHM)
            {
              /* Don't do anything special: include shm in the
               * shared /dev. The host and all sandboxes and subsandboxes
               * all share /dev/shm */
            }
          else if ((features & FLATPAK_CONTEXT_FEATURE_PER_APP_DEV_SHM)
                   && per_app_dir_lock_fd >= 0)
            {
              g_autofree char *shared_dev_shm = NULL;

              /* The host and the original sandbox have separate /dev/shm,
               * but we want other instances to be able to share /dev/shm with
               * the first sandbox (except for subsandboxes run with
               * flatpak-spawn --sandbox, which will have their own). */
              if (!flatpak_instance_ensure_per_app_dev_shm (app_id,
                                                            per_app_dir_lock_fd,
                                                            &shared_dev_shm,
                                                            error))
                return FALSE;

              flatpak_bwrap_add_args (bwrap,
                                      "--bind", shared_dev_shm, "/dev/shm",
                                      NULL);
            }
          else
            {
              /* The host, the original sandbox and each subsandbox
               * each have a separate /dev/shm. */
              flatpak_bwrap_add_args (bwrap,
                                      "--tmpfs", "/dev/shm",
                                      NULL);
            }
        }
      else if (g_file_test ("/dev/shm", G_FILE_TEST_IS_SYMLINK))
        {
          g_autofree char *link = flatpak_readlink ("/dev/shm", NULL);

          /* On debian (with sysv init) the host /dev/shm is a symlink to /run/shm, so we can't
             mount on top of it. */
          if (g_strcmp0 (link, "/run/shm") == 0)
            {
              if (devices & FLATPAK_CONTEXT_DEVICE_SHM &&
                  g_file_test ("/run/shm", G_FILE_TEST_IS_DIR))
                {
                  flatpak_bwrap_add_args (bwrap,
                                          "--bind", "/run/shm", "/run/shm",
                                          NULL);
                }
              else if ((features & FLATPAK_CONTEXT_FEATURE_PER_APP_DEV_SHM)
                       && per_app_dir_lock_fd >= 0)
                {
                  g_autofree char *shared_dev_shm = NULL;

                  /* The host and the original sandbox have separate /dev/shm,
                   * but we want other instances to be able to share /dev/shm,
                   * except for flatpak-spawn --subsandbox. */
                  if (!flatpak_instance_ensure_per_app_dev_shm (app_id,
                                                                per_app_dir_lock_fd,
                                                                &shared_dev_shm,
                                                                error))
                    return FALSE;

                  flatpak_bwrap_add_args (bwrap,
                                          "--bind", shared_dev_shm, "/run/shm",
                                          NULL);
                }
              else
                {
                  flatpak_bwrap_add_args (bwrap,
                                          "--dir", "/run/shm",
                                          NULL);
                }
            }
          else
            g_warning ("Unexpected /dev/shm symlink %s", link);
        }
    }
  else
    {
      flatpak_bwrap_add_args (bwrap,
                              "--dev", "/dev",
                              NULL);

      flatpak_bwrap_add_args (bwrap, "--dev-bind-try", "/dev/ntsync", "/dev/ntsync", NULL);

      if (devices & FLATPAK_CONTEXT_DEVICE_USB)
        {
          g_info ("Allowing USB device access.");

          if (g_file_test ("/dev/bus/usb", G_FILE_TEST_IS_DIR))
              flatpak_bwrap_add_args (bwrap, "--dev-bind", "/dev/bus/usb", "/dev/bus/usb", NULL);
        }

      if (devices & FLATPAK_CONTEXT_DEVICE_DRI)
        {
          g_info ("Allowing dri access");
          int i;
          static const char * const dri_devices[] = {
            "/dev/dri",
            "/dev/udmabuf",
            /* mali */
            "/dev/mali",
            "/dev/mali0",
            "/dev/umplock",
            /* nvidia */
            "/dev/nvidiactl",
            "/dev/nvidia-modeset",
            /* nvidia OpenCL/CUDA */
            "/dev/nvidia-uvm",
            "/dev/nvidia-uvm-tools",
            /* AMD ROCm/OpenCL */
            "/dev/kfd",
          };

          for (i = 0; i < G_N_ELEMENTS (dri_devices); i++)
            {
              if (g_file_test (dri_devices[i], G_FILE_TEST_EXISTS))
                flatpak_bwrap_add_args (bwrap, "--dev-bind", dri_devices[i], dri_devices[i], NULL);
            }

          /* Each Nvidia card gets its own device.
             This is a fairly arbitrary limit but ASUS sells mining boards supporting 20 in theory. */
          char nvidia_dev[14]; /* /dev/nvidia plus up to 2 digits */
          for (i = 0; i < 20; i++)
            {
              g_snprintf (nvidia_dev, sizeof (nvidia_dev), "/dev/nvidia%d", i);
              if (g_file_test (nvidia_dev, G_FILE_TEST_EXISTS))
                flatpak_bwrap_add_args (bwrap, "--dev-bind", nvidia_dev, nvidia_dev, NULL);
            }
        }

      if (devices & FLATPAK_CONTEXT_DEVICE_INPUT)
        {
          g_info ("Allowing input device access. Note: raw and virtual input currently require --device=all");

          if (g_file_test ("/dev/input", G_FILE_TEST_IS_DIR))
              flatpak_bwrap_add_args (bwrap, "--dev-bind", "/dev/input", "/dev/input", NULL);
        }

      if (devices & FLATPAK_CONTEXT_DEVICE_KVM)
        {
          g_info ("Allowing kvm access");
          if (g_file_test ("/dev/kvm", G_FILE_TEST_EXISTS))
            flatpak_bwrap_add_args (bwrap, "--dev-bind", "/dev/kvm", "/dev/kvm", NULL);
        }

      if (devices & FLATPAK_CONTEXT_DEVICE_SHM)
        {
          /* This is a symlink to /run/shm on debian, so bind to real target */
          g_autofree char *real_dev_shm = realpath ("/dev/shm", NULL);

          g_info ("Allowing /dev/shm access (as %s)", real_dev_shm);
          if (real_dev_shm != NULL)
              flatpak_bwrap_add_args (bwrap, "--bind", real_dev_shm, "/dev/shm", NULL);
        }
      else if ((features & FLATPAK_CONTEXT_FEATURE_PER_APP_DEV_SHM)
               && per_app_dir_lock_fd >= 0)
        {
          g_autofree char *shared_dev_shm = NULL;

          if (!flatpak_instance_ensure_per_app_dev_shm (app_id,
                                                        per_app_dir_lock_fd,
                                                        &shared_dev_shm,
                                                        error))
            return FALSE;

          flatpak_bwrap_add_args (bwrap,
                                  "--bind", shared_dev_shm, "/dev/shm",
                                  NULL);
        }
    }

  exports = flatpak_context_get_exports_full (context,
                                              app_id_dir, previous_app_id_dirs,
                                              TRUE, TRUE,
                                              &xdg_dirs_conf, &home_access);

  if (flatpak_exports_path_is_visible (exports, "/tmp"))
    {
      /* The original sandbox and any subsandboxes are both already
       * going to share /tmp with the host, so by transitivity they will
       * also share it with each other, and with all other instances. */
    }
  else if (per_app_dir_lock_fd >= 0 && !sandboxed)
    {
      g_autofree char *shared_tmp = NULL;

      /* The host and the original sandbox have separate /tmp,
       * but we want other instances to be able to share /tmp with the
       * first sandbox, unless they were created by
       * flatpak-spawn --sandbox.
       *
       * In apply_extra and `flatpak build`, per_app_dir_lock_fd is
       * negative and we skip this. */
      if (!flatpak_instance_ensure_per_app_tmp (app_id,
                                                per_app_dir_lock_fd,
                                                &shared_tmp,
                                                error))
        return FALSE;

      flatpak_bwrap_add_args (bwrap,
                              "--bind", shared_tmp, "/tmp",
                              NULL);
    }

  flatpak_context_append_bwrap_filesystem (context, bwrap, app_id, app_id_dir,
                                           exports, xdg_dirs_conf, home_access);

  flatpak_run_add_socket_args_environment (bwrap, shares, sockets, app_id, instance_id);
  flatpak_run_add_session_dbus_args (bwrap, proxy_arg_bwrap, sockets, context, flags, app_id);
  flatpak_run_add_system_dbus_args (bwrap, proxy_arg_bwrap, sockets, context, flags);
  flatpak_run_add_a11y_dbus_args (bwrap, proxy_arg_bwrap, context, flags, app_id);

  /* Must run this before spawning the dbus proxy, to ensure it
     ends up in the app cgroup */
  if (instance_id)
    {
      if (!flatpak_run_in_transient_unit (app_id, instance_id, &my_error))
        {
          /* We still run along even if we don't get a cgroup, as nothing
             really depends on it. Its just nice to have */
          g_info ("Failed to run in transient scope: %s", my_error->message);
          g_clear_error (&my_error);
        }
    }

  if (!flatpak_run_maybe_start_dbus_proxy (bwrap, proxy_arg_bwrap,
                                           app_info_path, error))
    return FALSE;

  if (exports_out)
    *exports_out = g_steal_pointer (&exports);

  return TRUE;
}

typedef struct
{
  const char *env;
  const char *val;
} ExportData;

static const ExportData default_exports[] = {
  {"PATH", "/app/bin:/usr/bin"},
  /* We always want to unset LD variables to avoid inheriting weird
   * dependencies from the host. But if not using ld.so.cache LD_LIBRARY_PATH
   is later set. */
  {"LD_LIBRARY_PATH", NULL},
  {"LD_PRELOAD", NULL},
  {"LD_AUDIT", NULL},

  {"XDG_CONFIG_DIRS", "/app/etc/xdg:/etc/xdg"},
  {"XDG_DATA_DIRS", "/app/share:/usr/share"},
  {"SHELL", "/bin/sh"},
  /* Unset temporary file paths as they may not exist in the sandbox */
  {"TEMP", NULL},
  {"TEMPDIR", NULL},
  {"TMP", NULL},
  {"TMPDIR", NULL},
  /* We always use /run/user/UID, even if the user's XDG_RUNTIME_DIR
   * outside the sandbox is somewhere else. Don't allow a different
   * setting from outside the sandbox to overwrite this. */
  {"XDG_RUNTIME_DIR", NULL},
  /* Ensure our container environment variable takes precedence over the one
   * set by a container manager. */
  {"container", NULL},
  /* We always make the zoneinfo available at /usr/share/zoneinfo even if it
   * is somewhere else outside of the sandbox. */
  {"TZDIR", NULL},

  /* Some env vars are common enough and will affect the sandbox badly
     if set on the host. We clear these always. If updating this list,
     also update the list in flatpak-run.xml. */
  {"PYTHONPATH", NULL},
  {"PYTHONPYCACHEPREFIX", NULL},
  {"PERLLIB", NULL},
  {"PERL5LIB", NULL},
  {"XCURSOR_PATH", NULL},
  {"GST_PLUGIN_PATH_1_0", NULL},
  {"GST_REGISTRY", NULL},
  {"GST_REGISTRY_1_0", NULL},
  {"GST_PLUGIN_PATH", NULL},
  {"GST_PLUGIN_SYSTEM_PATH", NULL},
  {"GST_PLUGIN_SCANNER", NULL},
  {"GST_PLUGIN_SCANNER_1_0", NULL},
  {"GST_PLUGIN_SYSTEM_PATH_1_0", NULL},
  {"GST_PRESET_PATH", NULL},
  {"GST_PTP_HELPER", NULL},
  {"GST_PTP_HELPER_1_0", NULL},
  {"GST_INSTALL_PLUGINS_HELPER", NULL},
  {"KRB5CCNAME", NULL},
  {"XKB_CONFIG_ROOT", NULL},
  {"GIO_EXTRA_MODULES", NULL},
  {"GDK_BACKEND", NULL},
  {"VK_ADD_DRIVER_FILES", NULL},
  {"VK_ADD_LAYER_PATH", NULL},
  {"VK_DRIVER_FILES", NULL},
  {"VK_ICD_FILENAMES", NULL},
  {"VK_LAYER_PATH", NULL},
  {"__EGL_EXTERNAL_PLATFORM_CONFIG_DIRS", NULL},
  {"__EGL_EXTERNAL_PLATFORM_CONFIG_FILENAMES", NULL},
  {"__EGL_VENDOR_LIBRARY_DIRS", NULL},
  {"__EGL_VENDOR_LIBRARY_FILENAMES", NULL},
};

static const ExportData no_ld_so_cache_exports[] = {
  {"LD_LIBRARY_PATH", "/app/lib"},
};

static const ExportData devel_exports[] = {
  {"ACLOCAL_PATH", "/app/share/aclocal"},
  {"C_INCLUDE_PATH", "/app/include"},
  {"CPLUS_INCLUDE_PATH", "/app/include"},
  {"LDFLAGS", "-L/app/lib "},
  {"PKG_CONFIG_PATH", "/app/lib/pkgconfig:/app/share/pkgconfig:/usr/lib/pkgconfig:/usr/share/pkgconfig"},
  {"LC_ALL", "en_US.utf8"},
};

static void
add_exports (GPtrArray        *env_array,
             const ExportData *exports,
             gsize             n_exports)
{
  int i;

  for (i = 0; i < n_exports; i++)
    {
      if (exports[i].val)
        g_ptr_array_add (env_array, g_strdup_printf ("%s=%s", exports[i].env, exports[i].val));
    }
}

char **
flatpak_run_get_minimal_env (gboolean devel, gboolean use_ld_so_cache)
{
  GPtrArray *env_array;
  static const char * const copy[] = {
    "PWD",
    "GDMSESSION",
    "XDG_CURRENT_DESKTOP",
    "XDG_SESSION_DESKTOP",
    "DESKTOP_SESSION",
    "EMAIL_ADDRESS",
    "HOME",
    "HOSTNAME",
    "LOGNAME",
    "REAL_NAME",
    "TERM",
    "USER",
    "USERNAME",
  };
  static const char * const copy_nodevel[] = {
    "LANG",
    "LANGUAGE",
    "LC_ALL",
    "LC_ADDRESS",
    "LC_COLLATE",
    "LC_CTYPE",
    "LC_IDENTIFICATION",
    "LC_MEASUREMENT",
    "LC_MESSAGES",
    "LC_MONETARY",
    "LC_NAME",
    "LC_NUMERIC",
    "LC_PAPER",
    "LC_TELEPHONE",
    "LC_TIME",
  };
  int i;

  env_array = g_ptr_array_new_with_free_func (g_free);

  add_exports (env_array, default_exports, G_N_ELEMENTS (default_exports));

  if (!use_ld_so_cache)
    add_exports (env_array, no_ld_so_cache_exports, G_N_ELEMENTS (no_ld_so_cache_exports));

  if (devel)
    add_exports (env_array, devel_exports, G_N_ELEMENTS (devel_exports));

  for (i = 0; i < G_N_ELEMENTS (copy); i++)
    {
      const char *current = g_getenv (copy[i]);
      if (current)
        g_ptr_array_add (env_array, g_strdup_printf ("%s=%s", copy[i], current));
    }

  if (!devel)
    {
      for (i = 0; i < G_N_ELEMENTS (copy_nodevel); i++)
        {
          const char *current = g_getenv (copy_nodevel[i]);
          if (current)
            g_ptr_array_add (env_array, g_strdup_printf ("%s=%s", copy_nodevel[i], current));
        }
    }

  g_ptr_array_add (env_array, NULL);
  return (char **) g_ptr_array_free (env_array, FALSE);
}

static char **
apply_exports (char            **envp,
               const ExportData *exports,
               gsize             n_exports)
{
  int i;

  for (i = 0; i < n_exports; i++)
    {
      const char *value = exports[i].val;

      if (value)
        envp = g_environ_setenv (envp, exports[i].env, value, TRUE);
      else
        envp = g_environ_unsetenv (envp, exports[i].env);
    }

  return envp;
}

static void
flatpak_run_apply_env_clear (FlatpakBwrap *bwrap, gboolean clear_env)
{
  if (!clear_env)
    return;

  flatpak_bwrap_add_args (bwrap, "--clearenv", NULL);
}

void
flatpak_run_apply_env_default (FlatpakBwrap *bwrap, gboolean use_ld_so_cache)
{
  bwrap->envp = apply_exports (bwrap->envp, default_exports, G_N_ELEMENTS (default_exports));

  if (!use_ld_so_cache)
    bwrap->envp = apply_exports (bwrap->envp, no_ld_so_cache_exports, G_N_ELEMENTS (no_ld_so_cache_exports));
}

static void
flatpak_run_apply_env_prompt (FlatpakBwrap *bwrap, const char *app_id)
{
  /* A custom shell prompt. FLATPAK_ID is always set.
   * PS1 can be overwritten by runtime metadata or by --env overrides
   */
  flatpak_bwrap_set_env (bwrap, "FLATPAK_ID", app_id, TRUE);
  flatpak_bwrap_set_env (bwrap, "PS1", "[📦 $FLATPAK_ID \\W]\\$ ", FALSE);
}

void
flatpak_run_apply_env_vars (FlatpakBwrap *bwrap, FlatpakContext *context)
{
  GHashTableIter iter;
  gpointer key, value;

  g_hash_table_iter_init (&iter, context->env_vars);
  while (g_hash_table_iter_next (&iter, &key, &value))
    {
      const char *var = key;
      const char *val = value;

      if (val)
        flatpak_bwrap_set_env (bwrap, var, val, TRUE);
      else
        flatpak_bwrap_unset_env (bwrap, var);
    }
}

gboolean
flatpak_ensure_data_dir (GFile        *app_id_dir,
                         GCancellable *cancellable,
                         GError      **error)
{
  g_autoptr(GFile) data_dir = g_file_get_child (app_id_dir, "data");
  g_autoptr(GFile) cache_dir = g_file_get_child (app_id_dir, "cache");
  g_autoptr(GFile) fontconfig_cache_dir = g_file_get_child (cache_dir, "fontconfig");
  g_autoptr(GFile) tmp_dir = g_file_get_child (cache_dir, "tmp");
  g_autoptr(GFile) config_dir = g_file_get_child (app_id_dir, "config");
  g_autoptr(GFile) state_dir = g_file_get_child (app_id_dir, ".local/state");

  if (!flatpak_mkdir_p (data_dir, cancellable, error))
    return FALSE;

  if (!flatpak_mkdir_p (cache_dir, cancellable, error))
    return FALSE;

  if (!flatpak_mkdir_p (fontconfig_cache_dir, cancellable, error))
    return FALSE;

  if (!flatpak_mkdir_p (tmp_dir, cancellable, error))
    return FALSE;

  if (!flatpak_mkdir_p (config_dir, cancellable, error))
    return FALSE;

  if (!flatpak_mkdir_p (state_dir, cancellable, error))
    return FALSE;

  return TRUE;
}

struct JobData
{
  char      *job;
  GMainLoop *main_loop;
};

static void
job_removed_cb (SystemdManager *manager,
                guint32         id,
                char           *job,
                char           *unit,
                char           *result,
                struct JobData *data)
{
  if (strcmp (job, data->job) == 0)
    g_main_loop_quit (data->main_loop);
}

static gchar *
systemd_unit_name_escape (const gchar *in)
{
  /* Adapted from systemd source */
  GString * const str = g_string_sized_new (strlen (in));

  for (; *in; in++)
    {
      if (g_ascii_isalnum (*in) || *in == ':' || *in == '_' || *in == '.')
        g_string_append_c (str, *in);
      else
        g_string_append_printf (str, "\\x%02x", *in);
    }
  return g_string_free (str, FALSE);
}

gboolean
flatpak_run_in_transient_unit (const char  *app_id,
                               const char  *instance_id,
                               GError     **error)
{
  g_autoptr(GDBusConnection) conn = NULL;
  g_autofree char *path = NULL;
  g_autofree char *address = NULL;
  g_autofree char *name = NULL;
  g_autofree char *app_id_escaped = NULL;
  g_autofree char *instance_id_escaped = NULL;
  g_autofree char *job = NULL;
  SystemdManager *manager = NULL;
  GVariantBuilder builder;
  GVariant *properties = NULL;
  GVariant *aux = NULL;
  guint32 pid;
  GMainLoop *main_loop = NULL;
  struct JobData data;
  gboolean res = FALSE;
  g_autoptr(GMainContextPopDefault) main_context = NULL;

  g_return_val_if_fail (app_id != NULL, FALSE);
  g_return_val_if_fail (instance_id != NULL, FALSE);

  path = g_strdup_printf ("/run/user/%d/systemd/private", getuid ());

  if (!g_file_test (path, G_FILE_TEST_EXISTS))
    return flatpak_fail_error (error, FLATPAK_ERROR_SETUP_FAILED,
                               _("No systemd user session available, cgroups not available"));

  main_context = flatpak_main_context_new_default ();
  main_loop = g_main_loop_new (main_context, FALSE);

  address = g_strconcat ("unix:path=", path, NULL);

  conn = g_dbus_connection_new_for_address_sync (address,
                                                 G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT,
                                                 NULL,
                                                 NULL, error);
  if (!conn)
    goto out;

  manager = systemd_manager_proxy_new_sync (conn,
                                            G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES,
                                            NULL,
                                            "/org/freedesktop/systemd1",
                                            NULL, error);
  if (!manager)
    goto out;

  app_id_escaped = systemd_unit_name_escape (app_id);
  instance_id_escaped = systemd_unit_name_escape (instance_id);
  name = g_strdup_printf ("app-flatpak-%s-%s.scope",
                          app_id_escaped,
                          instance_id_escaped);

  g_variant_builder_init (&builder, G_VARIANT_TYPE ("a(sv)"));

  pid = getpid ();
  g_variant_builder_add (&builder, "(sv)",
                         "PIDs",
                         g_variant_new_fixed_array (G_VARIANT_TYPE ("u"),
                                                    &pid, 1, sizeof (guint32)));

  properties = g_variant_builder_end (&builder);

  aux = g_variant_new_array (G_VARIANT_TYPE ("(sa(sv))"), NULL, 0);

  if (!systemd_manager_call_start_transient_unit_sync (manager,
                                                       name,
                                                       "fail",
                                                       properties,
                                                       aux,
                                                       &job,
                                                       NULL,
                                                       error))
    goto out;

  data.job = job;
  data.main_loop = main_loop;
  g_signal_connect (manager, "job-removed", G_CALLBACK (job_removed_cb), &data);

  g_main_loop_run (main_loop);

  res = TRUE;

out:
  if (main_loop)
    g_main_loop_unref (main_loop);
  if (manager)
    g_object_unref (manager);

  return res;
}

static void
add_font_path_args (FlatpakBwrap *bwrap)
{
  g_autoptr(GString) xml_snippet = g_string_new ("");
  gchar *path_build_tmp = NULL;
  g_autoptr(GFile) user_font1 = NULL;
  g_autoptr(GFile) user_font2 = NULL;
  g_autoptr(GFile) user_font_cache = NULL;
  g_auto(GStrv) system_cache_dirs = NULL;
  gboolean found_cache = FALSE;
  int i;


  g_string_append (xml_snippet,
                   "<?xml version=\"1.0\"?>\n"
                   "<!DOCTYPE fontconfig SYSTEM \"urn:fontconfig:fonts.dtd\">\n"
                   "<fontconfig>\n");

  if (g_file_test (SYSTEM_FONTS_DIR, G_FILE_TEST_EXISTS))
    {
      flatpak_bwrap_add_args (bwrap,
                              "--ro-bind", SYSTEM_FONTS_DIR, "/run/host/fonts",
                              NULL);
      g_string_append_printf (xml_snippet,
                              "\t<remap-dir as-path=\"%s\">/run/host/fonts</remap-dir>\n",
                              SYSTEM_FONTS_DIR);
    }

  if (g_file_test ("/usr/local/share/fonts", G_FILE_TEST_EXISTS))
    {
      flatpak_bwrap_add_args (bwrap,
                              "--ro-bind", "/usr/local/share/fonts", "/run/host/local-fonts",
                              NULL);
      g_string_append_printf (xml_snippet,
                              "\t<remap-dir as-path=\"%s\">/run/host/local-fonts</remap-dir>\n",
                              "/usr/local/share/fonts");
    }

  system_cache_dirs = g_strsplit (SYSTEM_FONT_CACHE_DIRS, ":", 0);
  for (i = 0; system_cache_dirs[i] != NULL; i++)
    {
      if (g_file_test (system_cache_dirs[i], G_FILE_TEST_EXISTS))
        {
          flatpak_bwrap_add_args (bwrap,
                                  "--ro-bind", system_cache_dirs[i], "/run/host/fonts-cache",
                                  NULL);
          found_cache = TRUE;
          break;
        }
    }

  if (!found_cache)
    {
      /* We ensure these directories are never writable, or fontconfig
         will use them to write the default cache */
      flatpak_bwrap_add_args (bwrap,
                              "--tmpfs", "/run/host/fonts-cache",
                              "--remount-ro", "/run/host/fonts-cache",
                              NULL);
    }

  path_build_tmp = g_build_filename (g_get_user_data_dir (), "fonts", NULL);
  user_font1 = g_file_new_for_path (path_build_tmp);
  g_clear_pointer (&path_build_tmp, g_free);

  path_build_tmp = g_build_filename (g_get_home_dir (), ".fonts", NULL);
  user_font2 = g_file_new_for_path (path_build_tmp);
  g_clear_pointer (&path_build_tmp, g_free);

  if (g_file_query_exists (user_font1, NULL))
    {
      flatpak_bwrap_add_args (bwrap,
                              "--ro-bind", flatpak_file_get_path_cached (user_font1), "/run/host/user-fonts",
                              NULL);
      g_string_append_printf (xml_snippet,
                              "\t<remap-dir as-path=\"%s\">/run/host/user-fonts</remap-dir>\n",
                              flatpak_file_get_path_cached (user_font1));
    }
  else if (g_file_query_exists (user_font2, NULL))
    {
      flatpak_bwrap_add_args (bwrap,
                              "--ro-bind", flatpak_file_get_path_cached (user_font2), "/run/host/user-fonts",
                              NULL);
      g_string_append_printf (xml_snippet,
                              "\t<remap-dir as-path=\"%s\">/run/host/user-fonts</remap-dir>\n",
                              flatpak_file_get_path_cached (user_font2));
    }

  path_build_tmp = g_build_filename (g_get_user_cache_dir (), "fontconfig", NULL);
  user_font_cache = g_file_new_for_path (path_build_tmp);
  g_clear_pointer (&path_build_tmp, g_free);

  if (g_file_query_exists (user_font_cache, NULL))
    {
      flatpak_bwrap_add_args (bwrap,
                              "--ro-bind", flatpak_file_get_path_cached (user_font_cache), "/run/host/user-fonts-cache",
                              NULL);
    }
  else
    {
      /* We ensure these directories are never writable, or fontconfig
         will use them to write the default cache */
      flatpak_bwrap_add_args (bwrap,
                              "--tmpfs", "/run/host/user-fonts-cache",
                              "--remount-ro", "/run/host/user-fonts-cache",
                              NULL);
    }

  g_string_append (xml_snippet,
                   "</fontconfig>\n");

  if (!flatpak_bwrap_add_args_data (bwrap, "font-dirs.xml", xml_snippet->str, xml_snippet->len, "/run/host/font-dirs.xml", NULL))
    g_warning ("Unable to add fontconfig data snippet");
}

static void
add_icon_path_args (FlatpakBwrap *bwrap)
{
  g_autofree gchar *user_icons_path = NULL;
  g_autoptr(GFile) user_icons = NULL;

  if (g_file_test ("/usr/share/icons", G_FILE_TEST_IS_DIR))
    {
      flatpak_bwrap_add_args (bwrap,
                              "--ro-bind", "/usr/share/icons", "/run/host/share/icons",
                              NULL);
    }

  user_icons_path = g_build_filename (g_get_user_data_dir (), "icons", NULL);
  user_icons = g_file_new_for_path (user_icons_path);
  if (g_file_query_exists (user_icons, NULL))
    {
      flatpak_bwrap_add_args (bwrap,
                              "--ro-bind", flatpak_file_get_path_cached (user_icons), "/run/host/user-share/icons",
                              NULL);
    }
}

FlatpakContext *
flatpak_app_compute_permissions (GKeyFile *app_metadata,
                                 GKeyFile *runtime_metadata,
                                 GError  **error)
{
  g_autoptr(FlatpakContext) app_context = NULL;

  app_context = flatpak_context_new ();

  if (runtime_metadata != NULL)
    {
      if (!flatpak_context_load_metadata (app_context, runtime_metadata, error))
        return NULL;

      /* Don't inherit any permissions from the runtime, only things like env vars. */
      flatpak_context_reset_permissions (app_context);

      flatpak_context_dump (app_context, "Metadata from runtime");
    }

  if (app_metadata != NULL &&
      !flatpak_context_load_metadata (app_context, app_metadata, error))
    return NULL;

  flatpak_context_dump (app_context, "Metadata from app manifest");
  return g_steal_pointer (&app_context);
}

#ifdef HAVE_DCONF

static void
add_dconf_key_to_keyfile (GKeyFile      *keyfile,
                          DConfClient   *client,
                          const char    *key,
                          DConfReadFlags flags)
{
  g_autofree char *group = g_path_get_dirname (key);
  g_autofree char *k = g_path_get_basename (key);
  GVariant *value = dconf_client_read_full (client, key, flags, NULL);

  if (value)
    {
      g_autofree char *val = g_variant_print (value, TRUE);
      g_key_file_set_value (keyfile, group + 1, k, val);
    }
}

static void
add_dconf_dir_to_keyfile (GKeyFile      *keyfile,
                          DConfClient   *client,
                          const char    *dir,
                          DConfReadFlags flags)
{
  g_auto(GStrv) keys = NULL;
  int i;

  keys = dconf_client_list (client, dir, NULL);
  for (i = 0; keys[i]; i++)
    {
      g_autofree char *k = g_strconcat (dir, keys[i], NULL);
      if (dconf_is_dir (k, NULL))
        add_dconf_dir_to_keyfile (keyfile, client, k, flags);
      else if (dconf_is_key (k, NULL))
        add_dconf_key_to_keyfile (keyfile, client, k, flags);
    }
}

static void
add_dconf_locks_to_list (GString     *s,
                         DConfClient *client,
                         const char  *dir)
{
  g_auto(GStrv) locks = NULL;
  int i;

  locks = dconf_client_list_locks (client, dir, NULL);
  for (i = 0; locks[i]; i++)
    {
      g_string_append (s, locks[i]);
      g_string_append_c (s, '\n');
    }
}

#endif /* HAVE_DCONF */

static void
get_dconf_data (const char  *app_id,
                const char **paths,
                const char  *migrate_path,
                char       **defaults,
                gsize       *defaults_size,
                char       **values,
                gsize       *values_size,
                char       **locks,
                gsize       *locks_size)
{
#ifdef HAVE_DCONF
  DConfClient *client = NULL;
  g_autofree char *prefix = NULL;
#endif
  g_autoptr(GKeyFile) defaults_data = NULL;
  g_autoptr(GKeyFile) values_data = NULL;
  g_autoptr(GString) locks_data = NULL;

  defaults_data = g_key_file_new ();
  values_data = g_key_file_new ();
  locks_data = g_string_new ("");

#ifdef HAVE_DCONF

  client = dconf_client_new ();

  prefix = flatpak_dconf_path_for_app_id (app_id);

  if (migrate_path)
    {
      g_info ("Add values in dir '%s', prefix is '%s'", migrate_path, prefix);
      if (flatpak_dconf_path_is_similar (migrate_path, prefix))
        add_dconf_dir_to_keyfile (values_data, client, migrate_path, DCONF_READ_USER_VALUE);
      else
        g_warning ("Ignoring D-Conf migrate-path setting %s", migrate_path);
    }

  g_info ("Add defaults in dir %s", prefix);
  add_dconf_dir_to_keyfile (defaults_data, client, prefix, DCONF_READ_DEFAULT_VALUE);

  g_info ("Add locks in dir %s", prefix);
  add_dconf_locks_to_list (locks_data, client, prefix);

  /* We allow extra paths for defaults and locks, but not for user values */
  if (paths)
    {
      int i;
      for (i = 0; paths[i]; i++)
        {
          if (dconf_is_dir (paths[i], NULL))
            {
              g_info ("Add defaults in dir %s", paths[i]);
              add_dconf_dir_to_keyfile (defaults_data, client, paths[i], DCONF_READ_DEFAULT_VALUE);

              g_info ("Add locks in dir %s", paths[i]);
              add_dconf_locks_to_list (locks_data, client, paths[i]);
            }
          else if (dconf_is_key (paths[i], NULL))
            {
              g_info ("Add individual key %s", paths[i]);
              add_dconf_key_to_keyfile (defaults_data, client, paths[i], DCONF_READ_DEFAULT_VALUE);
              add_dconf_key_to_keyfile (values_data, client, paths[i], DCONF_READ_USER_VALUE);
            }
          else
            {
              g_warning ("Ignoring settings path '%s': neither dir nor key", paths[i]);
            }
        }
    }
#endif

  *defaults = g_key_file_to_data (defaults_data, defaults_size, NULL);
  *values = g_key_file_to_data (values_data, values_size, NULL);
  *locks_size = locks_data->len;
  *locks = g_string_free (g_steal_pointer (&locks_data), FALSE);

#ifdef HAVE_DCONF
  g_object_unref (client);
#endif
}

static gboolean
flatpak_run_add_dconf_args (FlatpakBwrap *bwrap,
                            const char   *app_id,
                            GKeyFile     *metakey,
                            GError      **error)
{
  g_auto(GStrv) paths = NULL;
  g_autofree char *migrate_path = NULL;
  g_autofree char *defaults = NULL;
  g_autofree char *values = NULL;
  g_autofree char *locks = NULL;
  gsize defaults_size;
  gsize values_size;
  gsize locks_size;

  if (metakey)
    {
      paths = g_key_file_get_string_list (metakey,
                                          FLATPAK_METADATA_GROUP_DCONF,
                                          FLATPAK_METADATA_KEY_DCONF_PATHS,
                                          NULL, NULL);
      migrate_path = g_key_file_get_string (metakey,
                                            FLATPAK_METADATA_GROUP_DCONF,
                                            FLATPAK_METADATA_KEY_DCONF_MIGRATE_PATH,
                                            NULL);
    }

  get_dconf_data (app_id,
                  (const char **) paths,
                  migrate_path,
                  &defaults, &defaults_size,
                  &values, &values_size,
                  &locks, &locks_size);

  if (defaults_size != 0 &&
      !flatpak_bwrap_add_args_data (bwrap,
                                    "dconf-defaults",
                                    defaults, defaults_size,
                                    "/etc/glib-2.0/settings/defaults",
                                    error))
    return FALSE;

  if (locks_size != 0 &&
      !flatpak_bwrap_add_args_data (bwrap,
                                    "dconf-locks",
                                    locks, locks_size,
                                    "/etc/glib-2.0/settings/locks",
                                    error))
    return FALSE;

  /* We do a one-time conversion of existing dconf settings to a keyfile.
   * Only do that once the app stops requesting dconf access.
   */
  if (migrate_path)
    {
      g_autofree char *filename = NULL;

      filename = g_build_filename (g_get_home_dir (),
                                   ".var/app", app_id,
                                   "config/glib-2.0/settings/keyfile",
                                   NULL);

      g_info ("writing D-Conf values to %s", filename);

      if (values_size != 0 && !g_file_test (filename, G_FILE_TEST_EXISTS))
        {
          g_autofree char *dir = g_path_get_dirname (filename);

          if (g_mkdir_with_parents (dir, 0700) == -1)
            {
              g_warning ("failed creating dirs for %s", filename);
              return FALSE;
            }

          if (!g_file_set_contents (filename, values, values_size, error))
            {
              g_warning ("failed writing %s", filename);
              return FALSE;
            }
        }
    }

  return TRUE;
}

static gboolean
flatpak_run_save_environ (const char * const  *run_environ,
                          const char          *dir,
                          GCancellable        *cancellable,
                          GError             **error)
{
  g_autoptr(GByteArray) buffer = g_byte_array_new ();
  int i;
  glnx_autofd int dir_fd = -1;

  g_assert (run_environ != NULL);

  for (i = 0; run_environ[i] != NULL; i++)
    {
      gsize size = strlen (run_environ[i]) + 1;

      g_byte_array_append (buffer,
                           (const guint8 *) run_environ[i],
                           size);
    }

  if (!glnx_opendirat (AT_FDCWD, dir, TRUE,
                       &dir_fd,
                       error))
    return FALSE;

  if (!glnx_file_replace_contents_with_perms_at (dir_fd, "run-environ",
                                                 buffer->data, buffer->len,
                                                 (mode_t) 0400,
                                                 (uid_t) -1, (gid_t) -1,
                                                 0,
                                                 cancellable, error))
    return FALSE;

  return TRUE;
}

gboolean
flatpak_run_add_app_info_args (FlatpakBwrap           *bwrap,
                               GFile                  *app_files,
                               GFile                  *original_app_files,
                               GBytes                 *app_deploy_data,
                               const char             *app_extensions,
                               GFile                  *runtime_files,
                               GFile                  *original_runtime_files,
                               GBytes                 *runtime_deploy_data,
                               const char             *runtime_extensions,
                               const char             *app_id,
                               const char             *app_branch,
                               FlatpakDecomposed      *runtime_ref,
                               GFile                  *app_id_dir,
                               FlatpakContext         *final_app_context,
                               FlatpakContext         *cmdline_context,
                               FlatpakContextSockets   sockets,
                               gboolean                sandbox,
                               gboolean                build,
                               gboolean                devel,
                               char                  **app_info_path_out,
                               int                     instance_id_fd_arg,
                               char                  **instance_id_host_dir_out,
                               char                  **instance_id_host_private_dir_out,
                               char                  **instance_id_out,
                               GError                **error)
{
  g_autofree char *info_path = NULL;
  g_autofree char *bwrapinfo_path = NULL;
  glnx_autofd int fd1 = -1;
  glnx_autofd int fd2 = -1;
  glnx_autofd int fd3 = -1;
  int info_fd;
  glnx_autofd int instance_id_fd = instance_id_fd_arg;
  g_autoptr(GKeyFile) keyfile = NULL;
  g_autofree char *runtime_path = NULL;
  const char *group;
  g_autofree char *instance_id = NULL;
  glnx_autofd int lock_fd = -1;
  g_autofree char *instance_id_host_dir = NULL;
  g_autofree char *instance_id_host_private_dir = NULL;
  g_autofree char *instance_id_sandbox_dir = NULL;
  g_autofree char *instance_id_lock_file = NULL;
  g_autofree char *arch = flatpak_decomposed_dup_arch (runtime_ref);

  g_return_val_if_fail (app_id != NULL, FALSE);

  instance_id = flatpak_instance_allocate_id (&instance_id_host_dir,
                                              &instance_id_host_private_dir,
                                              &lock_fd);
  if (instance_id == NULL)
    return flatpak_fail_error (error, FLATPAK_ERROR_SETUP_FAILED, _("Unable to allocate instance id"));

  instance_id_sandbox_dir = g_strdup_printf ("/run/flatpak/.flatpak/%s", instance_id);
  instance_id_lock_file = g_build_filename (instance_id_sandbox_dir, ".ref", NULL);

  flatpak_bwrap_add_args (bwrap,
                          "--ro-bind",
                          instance_id_host_dir,
                          instance_id_sandbox_dir,
                          "--lock-file",
                          instance_id_lock_file,
                          NULL);
  flatpak_bwrap_add_runtime_dir_member (bwrap, ".flatpak");
  /* Keep the .ref lock held until we've started bwrap to avoid races */
  flatpak_bwrap_add_noinherit_fd (bwrap, g_steal_fd (&lock_fd));

  info_path = g_build_filename (instance_id_host_dir, "info", NULL);

  keyfile = g_key_file_new ();

  if (original_app_files)
    group = FLATPAK_METADATA_GROUP_APPLICATION;
  else
    group = FLATPAK_METADATA_GROUP_RUNTIME;

  g_key_file_set_string (keyfile, group, FLATPAK_METADATA_KEY_NAME, app_id);
  g_key_file_set_string (keyfile, group, FLATPAK_METADATA_KEY_RUNTIME,
                         flatpak_decomposed_get_ref (runtime_ref));

  g_key_file_set_string (keyfile, FLATPAK_METADATA_GROUP_INSTANCE,
                         FLATPAK_METADATA_KEY_INSTANCE_ID, instance_id);
  if (app_id_dir)
    {
      g_autofree char *instance_path = g_file_get_path (app_id_dir);
      g_key_file_set_string (keyfile, FLATPAK_METADATA_GROUP_INSTANCE,
                             FLATPAK_METADATA_KEY_INSTANCE_PATH, instance_path);
    }

  if (app_files)
    {
      g_autofree char *app_path = g_file_get_path (app_files);
      g_key_file_set_string (keyfile, FLATPAK_METADATA_GROUP_INSTANCE,
                             FLATPAK_METADATA_KEY_APP_PATH, app_path);
    }

  if (original_app_files != NULL && original_app_files != app_files)
    {
      g_autofree char *app_path = g_file_get_path (original_app_files);
      g_key_file_set_string (keyfile, FLATPAK_METADATA_GROUP_INSTANCE,
                             FLATPAK_METADATA_KEY_ORIGINAL_APP_PATH, app_path);
    }

  if (app_deploy_data)
    g_key_file_set_string (keyfile, FLATPAK_METADATA_GROUP_INSTANCE,
                           FLATPAK_METADATA_KEY_APP_COMMIT, flatpak_deploy_data_get_commit (app_deploy_data));
  if (app_extensions && *app_extensions != 0)
    g_key_file_set_string (keyfile, FLATPAK_METADATA_GROUP_INSTANCE,
                           FLATPAK_METADATA_KEY_APP_EXTENSIONS, app_extensions);
  runtime_path = g_file_get_path (runtime_files);
  g_key_file_set_string (keyfile, FLATPAK_METADATA_GROUP_INSTANCE,
                         FLATPAK_METADATA_KEY_RUNTIME_PATH, runtime_path);

  if (runtime_files != original_runtime_files)
    {
      g_autofree char *path = g_file_get_path (original_runtime_files);
      g_key_file_set_string (keyfile, FLATPAK_METADATA_GROUP_INSTANCE,
                             FLATPAK_METADATA_KEY_ORIGINAL_RUNTIME_PATH, path);
    }

  if (runtime_deploy_data)
    g_key_file_set_string (keyfile, FLATPAK_METADATA_GROUP_INSTANCE,
                           FLATPAK_METADATA_KEY_RUNTIME_COMMIT, flatpak_deploy_data_get_commit (runtime_deploy_data));
  if (runtime_extensions && *runtime_extensions != 0)
    g_key_file_set_string (keyfile, FLATPAK_METADATA_GROUP_INSTANCE,
                           FLATPAK_METADATA_KEY_RUNTIME_EXTENSIONS, runtime_extensions);
  if (app_branch != NULL)
    g_key_file_set_string (keyfile, FLATPAK_METADATA_GROUP_INSTANCE,
                           FLATPAK_METADATA_KEY_BRANCH, app_branch);
  g_key_file_set_string (keyfile, FLATPAK_METADATA_GROUP_INSTANCE,
                         FLATPAK_METADATA_KEY_ARCH, arch);

  g_key_file_set_string (keyfile, FLATPAK_METADATA_GROUP_INSTANCE,
                         FLATPAK_METADATA_KEY_FLATPAK_VERSION, PACKAGE_VERSION);

  if ((sockets & FLATPAK_CONTEXT_SOCKET_SESSION_BUS) == 0)
    g_key_file_set_boolean (keyfile, FLATPAK_METADATA_GROUP_INSTANCE,
                            FLATPAK_METADATA_KEY_SESSION_BUS_PROXY, TRUE);

  if ((sockets & FLATPAK_CONTEXT_SOCKET_SYSTEM_BUS) == 0)
    g_key_file_set_boolean (keyfile, FLATPAK_METADATA_GROUP_INSTANCE,
                            FLATPAK_METADATA_KEY_SYSTEM_BUS_PROXY, TRUE);

  if (sandbox)
    g_key_file_set_boolean (keyfile, FLATPAK_METADATA_GROUP_INSTANCE,
                            FLATPAK_METADATA_KEY_SANDBOX, TRUE);
  if (build)
    g_key_file_set_boolean (keyfile, FLATPAK_METADATA_GROUP_INSTANCE,
                            FLATPAK_METADATA_KEY_BUILD, TRUE);
  if (devel)
    g_key_file_set_boolean (keyfile, FLATPAK_METADATA_GROUP_INSTANCE,
                            FLATPAK_METADATA_KEY_DEVEL, TRUE);

  if (cmdline_context)
    {
      g_autoptr(GPtrArray) cmdline_args = g_ptr_array_new_with_free_func (g_free);
      flatpak_context_to_args (cmdline_context, cmdline_args);
      if (cmdline_args->len > 0)
        {
          g_key_file_set_string_list (keyfile, FLATPAK_METADATA_GROUP_INSTANCE,
                                      FLATPAK_METADATA_KEY_EXTRA_ARGS,
                                      (const char * const *) cmdline_args->pdata,
                                      cmdline_args->len);
        }
    }

  flatpak_context_save_metadata (final_app_context, TRUE, keyfile);

  if (!g_key_file_save_to_file (keyfile, info_path, error))
    return FALSE;

  /* We want to create a file on /.flatpak-info that the app cannot modify, which
     we do by creating a read-only bind mount. This way one can openat()
     /proc/$pid/root, and if that succeeds use openat via that to find the
     unfakable .flatpak-info file. However, there is a tiny race in that if
     you manage to open /proc/$pid/root, but then the pid dies, then
     every mount but the root is unmounted in the namespace, so the
     .flatpak-info will be empty. We fix this by first creating a real file
     with the real info in, then bind-mounting on top of that, the same info.
     This way even if the bind-mount is unmounted we can find the real data.
   */

  fd1 = info_fd = open (info_path, O_RDONLY);
  if (fd1 == -1)
    {
      int errsv = errno;
      g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errsv),
                   _("Failed to open flatpak-info file: %s"), g_strerror (errsv));
      return FALSE;
    }

  fd2 = open (info_path, O_RDONLY);
  if (fd2 == -1)
    {
      int errsv = errno;
      g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errsv),
                   _("Failed to open flatpak-info file: %s"), g_strerror (errsv));
      return FALSE;
    }

  flatpak_bwrap_add_args (bwrap, "--perms", "0600", NULL);
  flatpak_bwrap_add_args_data_fd (bwrap,
                                  "--file", g_steal_fd (&fd1), "/.flatpak-info");
  flatpak_bwrap_add_args_data_fd (bwrap,
                                  "--ro-bind-data", g_steal_fd (&fd2), "/.flatpak-info");

  /* Tell the application that it's running under Flatpak in a generic way. */
  flatpak_bwrap_add_args (bwrap,
                          "--setenv", "container", "flatpak",
                          NULL);
  if (!flatpak_bwrap_add_args_data (bwrap,
                                    "container-manager",
                                    "flatpak\n", -1,
                                    "/run/host/container-manager",
                                    error))
    return FALSE;

  bwrapinfo_path = g_build_filename (instance_id_host_dir, "bwrapinfo.json", NULL);
  fd3 = open (bwrapinfo_path, O_RDWR | O_CREAT, 0644);
  if (fd3 == -1)
    {
      int errsv = errno;
      g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errsv),
                   _("Failed to open bwrapinfo.json file: %s"), g_strerror (errsv));
      return FALSE;
    }

  /* NOTE: It is important that this takes place after bwrapinfo.json is created,
     otherwise start notifications in the portal may not work. */
  if (instance_id_fd != -1)
    {
      gsize instance_id_position = 0;
      gsize instance_id_size = strlen (instance_id);

      while (instance_id_size > 0)
        {
          gssize bytes_written = write (instance_id_fd, instance_id + instance_id_position, instance_id_size);
          if (G_UNLIKELY (bytes_written <= 0))
            {
              int errsv = bytes_written == -1 ? errno : ENOSPC;
              if (errsv == EINTR)
                continue;

              g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errsv),
                           _("Failed to write to instance id fd: %s"), g_strerror (errsv));
              return FALSE;
            }

          instance_id_position += bytes_written;
          instance_id_size -= bytes_written;
        }

      /* explicitly close this as soon as we're done to notify the other side */
      g_clear_fd (&instance_id_fd, NULL);
    }

  flatpak_bwrap_add_args_data_fd (bwrap, "--info-fd", g_steal_fd (&fd3), NULL);

  if (app_info_path_out != NULL)
    *app_info_path_out = g_strdup_printf ("/proc/self/fd/%d", info_fd);

  if (instance_id_host_dir_out != NULL)
    *instance_id_host_dir_out = g_steal_pointer (&instance_id_host_dir);

  if (instance_id_host_private_dir_out != NULL)
    *instance_id_host_private_dir_out = g_steal_pointer (&instance_id_host_private_dir);

  if (instance_id_out != NULL)
    *instance_id_out = g_steal_pointer (&instance_id);

  return TRUE;
}

/*
 * @runtime_fd: the /usr for the runtime, or -1 if running with no runtime,
 *  perhaps to unpack extra-data
 */
static void
add_tzdata_args (FlatpakBwrap *bwrap,
                 int           runtime_fd)
{
  g_autofree char *raw_timezone = NULL;
  g_autofree char *timezone_content = NULL;
  g_autofree char *localtime_content = NULL;
  const char *tzdir;
  glnx_autofd int tzdir_fd = -1;
  glnx_autofd int zoneinfo_fd = -1;
  g_autoptr(GError) error = NULL;

  g_return_if_fail (runtime_fd >= -1);

  raw_timezone = flatpak_get_timezone ();
  timezone_content = g_strdup_printf ("%s\n", raw_timezone);
  localtime_content = g_strconcat ("../usr/share/zoneinfo/", raw_timezone, NULL);

  tzdir = flatpak_get_tzdir ();

  tzdir_fd = glnx_chaseat (AT_FDCWD, tzdir, GLNX_CHASE_MUST_BE_DIRECTORY, NULL);

  if (runtime_fd >= 0)
    zoneinfo_fd = glnx_chaseat (runtime_fd, "share/zoneinfo",
                                GLNX_CHASE_RESOLVE_BENEATH |
                                GLNX_CHASE_MUST_BE_DIRECTORY,
                                NULL);

  /* Check for host /usr/share/zoneinfo */
  if (tzdir_fd >= 0 && zoneinfo_fd >= 0)
    {
      /* Here we assume the host timezone file exist in the host data */
      flatpak_bwrap_add_args (bwrap,
                              "--ro-bind", tzdir, "/usr/share/zoneinfo",
                              "--symlink", localtime_content, "/etc/localtime",
                              NULL);
    }
  else if (runtime_fd >= 0)
    {
      g_autofree char *runtime_zoneinfo = NULL;
      glnx_autofd int runtime_zoneinfo_fd = -1;

      runtime_zoneinfo = g_strconcat ("share/zoneinfo/", raw_timezone, NULL);

      /* Check for runtime /usr/share/zoneinfo */
      runtime_zoneinfo_fd = glnx_chaseat (runtime_fd, runtime_zoneinfo,
                                          GLNX_CHASE_RESOLVE_BENEATH |
                                          GLNX_CHASE_MUST_BE_REGULAR,
                                          NULL);
      if (runtime_zoneinfo_fd >= 0)
        {
          flatpak_bwrap_add_args (bwrap,
                                  "--symlink", localtime_content, "/etc/localtime",
                                  NULL);
        }
    }

  flatpak_bwrap_add_args_data (bwrap, "timezone",
                               timezone_content, -1, "/etc/timezone",
                               NULL);
}

static void
add_monitor_path_args (gboolean      use_session_helper,
                       FlatpakBwrap *bwrap)
{
  g_autoptr(AutoFlatpakSessionHelper) session_helper = NULL;
  g_autofree char *monitor_path = NULL;
  g_autofree char *pkcs11_socket_path = NULL;
  g_autoptr(GVariant) session_data = NULL;

  if (use_session_helper)
    {
      session_helper =
        flatpak_session_helper_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION,
                                                       G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES | G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS,
                                                       FLATPAK_SESSION_HELPER_BUS_NAME,
                                                       FLATPAK_SESSION_HELPER_PATH,
                                                       NULL, NULL);
    }

  if (session_helper &&
      flatpak_session_helper_call_request_session_sync (session_helper,
                                                        &session_data,
                                                        NULL, NULL))
    {
      if (g_variant_lookup (session_data, "path", "s", &monitor_path))
        flatpak_bwrap_add_args (bwrap,
                                "--ro-bind", monitor_path, "/run/host/monitor",
                                "--symlink", "/run/host/monitor/resolv.conf", "/etc/resolv.conf",
                                "--symlink", "/run/host/monitor/host.conf", "/etc/host.conf",
                                "--symlink", "/run/host/monitor/hosts", "/etc/hosts",
                                "--symlink", "/run/host/monitor/gai.conf", "/etc/gai.conf",
                                NULL);

      if (g_variant_lookup (session_data, "pkcs11-socket", "s", &pkcs11_socket_path))
        {
          static const char sandbox_pkcs11_socket_path[] = "/run/flatpak/p11-kit/pkcs11";
          const char *trusted_module_contents =
            "# This overrides the runtime p11-kit-trusted module with a client one talking to the trust module on the host\n"
            "module: p11-kit-client.so\n";

          if (flatpak_bwrap_add_args_data (bwrap, "p11-kit-trust.module",
                                           trusted_module_contents, -1,
                                           "/etc/pkcs11/modules/p11-kit-trust.module", NULL))
            {
              flatpak_bwrap_add_args (bwrap,
                                      "--ro-bind", pkcs11_socket_path, sandbox_pkcs11_socket_path,
                                      NULL);
              flatpak_bwrap_unset_env (bwrap, "P11_KIT_SERVER_ADDRESS");
              flatpak_bwrap_add_runtime_dir_member (bwrap, "p11-kit");
            }
        }
    }
  else
    {
      if (g_file_test ("/etc/resolv.conf", G_FILE_TEST_EXISTS))
        flatpak_bwrap_add_args (bwrap,
                                "--ro-bind", "/etc/resolv.conf", "/etc/resolv.conf",
                                NULL);
      if (g_file_test ("/etc/host.conf", G_FILE_TEST_EXISTS))
        flatpak_bwrap_add_args (bwrap,
                                "--ro-bind", "/etc/host.conf", "/etc/host.conf",
                                NULL);
      if (g_file_test ("/etc/hosts", G_FILE_TEST_EXISTS))
        flatpak_bwrap_add_args (bwrap,
                                "--ro-bind", "/etc/hosts", "/etc/hosts",
                                NULL);
      if (g_file_test ("/etc/gai.conf", G_FILE_TEST_EXISTS))
        flatpak_bwrap_add_args (bwrap,
                                "--ro-bind", "/etc/gai.conf", "/etc/gai.conf",
                                NULL);
    }
}

static void
add_document_portal_args (FlatpakBwrap *bwrap,
                          const char   *app_id,
                          char        **out_mount_path)
{
  g_autoptr(GDBusConnection) session_bus = NULL;
  g_autofree char *doc_mount_path = NULL;

  session_bus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL);
  if (session_bus)
    {
      g_autoptr(GError) local_error = NULL;
      g_autoptr(GDBusMessage) reply = NULL;
      g_autoptr(GDBusMessage) msg =
        g_dbus_message_new_method_call ("org.freedesktop.portal.Documents",
                                        "/org/freedesktop/portal/documents",
                                        "org.freedesktop.portal.Documents",
                                        "GetMountPoint");
      g_dbus_message_set_body (msg, g_variant_new ("()"));
      reply =
        g_dbus_connection_send_message_with_reply_sync (session_bus, msg,
                                                        G_DBUS_SEND_MESSAGE_FLAGS_NONE,
                                                        30000,
                                                        NULL,
                                                        NULL,
                                                        NULL);
      if (reply)
        {
          if (g_dbus_message_to_gerror (reply, &local_error))
            {
              if (g_error_matches (local_error, G_DBUS_ERROR, G_DBUS_ERROR_SERVICE_UNKNOWN))
                g_info ("Document portal not available, not mounting /run/flatpak/doc");
              else
                g_message ("Can't get document portal: %s", local_error->message);
            }
          else
            {
              static const char dst_path[] = "/run/flatpak/doc";
              g_autofree char *src_path = NULL;
              g_variant_get (g_dbus_message_get_body (reply),
                             "(^ay)", &doc_mount_path);

              src_path = g_strdup_printf ("%s/by-app/%s",
                                          doc_mount_path, app_id);
              flatpak_bwrap_add_args (bwrap, "--bind", src_path, dst_path, NULL);
              flatpak_bwrap_add_runtime_dir_member (bwrap, "doc");
            }
        }
    }

  *out_mount_path = g_steal_pointer (&doc_mount_path);
}

#ifdef ENABLE_SECCOMP
static const uint32_t seccomp_x86_64_extra_arches[] = { SCMP_ARCH_X86, 0, };

#ifdef SCMP_ARCH_AARCH64
static const uint32_t seccomp_aarch64_extra_arches[] = { SCMP_ARCH_ARM, 0 };
#endif

/*
 * @negative_errno: Result code as returned by libseccomp functions
 *
 * Translate a libseccomp error code into an error message. libseccomp
 * mostly returns negative `errno` values such as `-ENOMEM`, but some
 * standard `errno` values are used for non-standard purposes where their
 * `strerror()` would be misleading.
 *
 * Returns: a string version of @negative_errno if possible
 */
static const char *
flatpak_seccomp_strerror (int negative_errno)
{
  g_return_val_if_fail (negative_errno < 0, "Non-negative error value from libseccomp?");
  g_return_val_if_fail (negative_errno > INT_MIN, "Out of range error value from libseccomp?");

  switch (negative_errno)
    {
      case -EDOM:
        return "Architecture specific failure";

      case -EFAULT:
        return "Internal libseccomp failure (unknown syscall?)";

      case -ECANCELED:
        return "System failure beyond the control of libseccomp";
    }

  /* e.g. -ENOMEM: the result of strerror() is good enough */
  return g_strerror (-negative_errno);
}

static inline void
cleanup_seccomp (void *p)
{
  scmp_filter_ctx *pp = (scmp_filter_ctx *) p;

  if (*pp)
    seccomp_release (*pp);
}

static gboolean
setup_seccomp (FlatpakBwrap   *bwrap,
               const char     *arch,
               gulong          allowed_personality,
               FlatpakRunFlags run_flags,
               GError        **error)
{
  gboolean multiarch = (run_flags & FLATPAK_RUN_FLAG_MULTIARCH) != 0;
  gboolean devel = (run_flags & FLATPAK_RUN_FLAG_DEVEL) != 0;

  __attribute__((cleanup (cleanup_seccomp))) scmp_filter_ctx seccomp = NULL;

  /**** BEGIN NOTE ON CODE SHARING
   *
   * This code was originally part of the obsolete linux-user-chroot project,
   * which was itself heavily influenced by Sandstorm's seccomp filters.
   * Nowadays, the canonical upstream location for this code is Flatpak:
   *
   *   https://github.com/flatpak/flatpak/blob/main/common/flatpak-run.c
   *
   * Here is a list of projects that have directly copied Flatpak's sandbox
   * filters. These projects aim to exactly or almost exactly match what Flatpak
   * is doing, so we almost always need to update them whenever the code here is
   * touched:
   *
   *   https://github.com/WebKit/WebKit/blob/main/Source/WebKit/UIProcess/Launcher/glib/BubblewrapLauncher.cpp
   *   https://gitlab.gnome.org/GNOME/gnome-desktop/-/blob/master/libgnome-desktop/gnome-desktop-thumbnail-script.c
   *
   * (We perhaps ought to split this code out of Flatpak into a subproject, to
   * make code sharing easier and reduce the need for manual copy/pasting.)
   *
   **** END NOTE ON CODE SHARING
   */
  struct
  {
    int                  scall;
    int                  errnum;
    struct scmp_arg_cmp *arg;
  } syscall_blocklist[] = {
    /* Block dmesg */
    {SCMP_SYS (syslog), EPERM},
    /* Useless old syscall */
    {SCMP_SYS (uselib), EPERM},
    /* Don't allow disabling accounting */
    {SCMP_SYS (acct), EPERM},
    /* Don't allow reading current quota use */
    {SCMP_SYS (quotactl), EPERM},

    /* Don't allow access to the kernel keyring */
    {SCMP_SYS (add_key), EPERM},
    {SCMP_SYS (keyctl), EPERM},
    {SCMP_SYS (request_key), EPERM},

    /* Scary VM/NUMA ops */
    {SCMP_SYS (move_pages), EPERM},
    {SCMP_SYS (mbind), EPERM},
    {SCMP_SYS (get_mempolicy), EPERM},
    {SCMP_SYS (set_mempolicy), EPERM},
    {SCMP_SYS (migrate_pages), EPERM},

    /* Don't allow subnamespace setups: */
    {SCMP_SYS (unshare), EPERM},
    {SCMP_SYS (setns), EPERM},
    {SCMP_SYS (mount), EPERM},
    {SCMP_SYS (umount), EPERM},
    {SCMP_SYS (umount2), EPERM},
    {SCMP_SYS (pivot_root), EPERM},
    {SCMP_SYS (chroot), EPERM},
#if defined(__s390__) || defined(__s390x__) || defined(__CRIS__)
    /* Architectures with CONFIG_CLONE_BACKWARDS2: the child stack
     * and flags arguments are reversed so the flags come second */
    {SCMP_SYS (clone), EPERM, &SCMP_A1 (SCMP_CMP_MASKED_EQ, CLONE_NEWUSER, CLONE_NEWUSER)},
#else
    /* Normally the flags come first */
    {SCMP_SYS (clone), EPERM, &SCMP_A0 (SCMP_CMP_MASKED_EQ, CLONE_NEWUSER, CLONE_NEWUSER)},
#endif

    /* Don't allow faking input to the controlling tty (CVE-2017-5226) */
    {SCMP_SYS (ioctl), EPERM, &SCMP_A1 (SCMP_CMP_MASKED_EQ, 0xFFFFFFFFu, (int) TIOCSTI)},
    /* In the unlikely event that the controlling tty is a Linux virtual
     * console (/dev/tty2 or similar), copy/paste operations have an effect
     * similar to TIOCSTI (CVE-2023-28100) */
    {SCMP_SYS (ioctl), EPERM, &SCMP_A1 (SCMP_CMP_MASKED_EQ, 0xFFFFFFFFu, (int) TIOCLINUX)},

    /* seccomp can't look into clone3()'s struct clone_args to check whether
     * the flags are OK, so we have no choice but to block clone3().
     * Return ENOSYS so user-space will fall back to clone().
     * (CVE-2021-41133; see also https://github.com/moby/moby/commit/9f6b562d) */
    {SCMP_SYS (clone3), ENOSYS},

    /* New mount manipulation APIs can also change our VFS. There's no
     * legitimate reason to do these in the sandbox, so block all of them
     * rather than thinking about which ones might be dangerous.
     * (CVE-2021-41133) */
    {SCMP_SYS (open_tree), ENOSYS},
    {SCMP_SYS (move_mount), ENOSYS},
    {SCMP_SYS (fsopen), ENOSYS},
    {SCMP_SYS (fsconfig), ENOSYS},
    {SCMP_SYS (fsmount), ENOSYS},
    {SCMP_SYS (fspick), ENOSYS},
    {SCMP_SYS (mount_setattr), ENOSYS},
  };

  struct
  {
    int                  scall;
    int                  errnum;
    struct scmp_arg_cmp *arg;
  } syscall_nondevel_blocklist[] = {
    /* Profiling operations; we expect these to be done by tools from outside
     * the sandbox.  In particular perf has been the source of many CVEs.
     */
    {SCMP_SYS (perf_event_open), EPERM},
    /* Don't allow you to switch to bsd emulation or whatnot */
    {SCMP_SYS (personality), EPERM, &SCMP_A0 (SCMP_CMP_NE, allowed_personality)},
    {SCMP_SYS (ptrace), EPERM}
  };
  /* Blocklist all but unix, inet, inet6 and netlink */
  struct
  {
    int             family;
    FlatpakRunFlags flags_mask;
  } socket_family_allowlist[] = {
    /* NOTE: Keep in numerical order */
    { AF_UNSPEC, 0 },
    { AF_LOCAL, 0 },
    { AF_INET, 0 },
    { AF_INET6, 0 },
    { AF_NETLINK, 0 },
    { AF_CAN, FLATPAK_RUN_FLAG_CANBUS },
    { AF_BLUETOOTH, FLATPAK_RUN_FLAG_BLUETOOTH },
  };
  int last_allowed_family;
  int i, r;
  g_auto(GLnxTmpfile) seccomp_tmpf  = { 0, };

  seccomp = seccomp_init (SCMP_ACT_ALLOW);
  if (!seccomp)
    return flatpak_fail_error (error, FLATPAK_ERROR_SETUP_FAILED, _("Initialize seccomp failed"));

  if (arch != NULL)
    {
      uint32_t arch_id = 0;
      const uint32_t *extra_arches = NULL;

      if (strcmp (arch, "i386") == 0)
        {
          arch_id = SCMP_ARCH_X86;
        }
      else if (strcmp (arch, "x86_64") == 0)
        {
          arch_id = SCMP_ARCH_X86_64;
          extra_arches = seccomp_x86_64_extra_arches;
        }
      else if (strcmp (arch, "arm") == 0)
        {
          arch_id = SCMP_ARCH_ARM;
        }
#ifdef SCMP_ARCH_AARCH64
      else if (strcmp (arch, "aarch64") == 0)
        {
          arch_id = SCMP_ARCH_AARCH64;
          extra_arches = seccomp_aarch64_extra_arches;
        }
#endif

      /* We only really need to handle arches on multiarch systems.
       * If only one arch is supported the default is fine */
      if (arch_id != 0)
        {
          /* This *adds* the target arch, instead of replacing the
             native one. This is not ideal, because we'd like to only
             allow the target arch, but we can't really disallow the
             native arch at this point, because then bubblewrap
             couldn't continue running. */
          r = seccomp_arch_add (seccomp, arch_id);
          if (r < 0 && r != -EEXIST)
            return flatpak_fail_error (error, FLATPAK_ERROR_SETUP_FAILED, _("Failed to add architecture to seccomp filter: %s"), flatpak_seccomp_strerror (r));

          if (multiarch && extra_arches != NULL)
            {
              for (i = 0; extra_arches[i] != 0; i++)
                {
                  r = seccomp_arch_add (seccomp, extra_arches[i]);
                  if (r < 0 && r != -EEXIST)
                    return flatpak_fail_error (error, FLATPAK_ERROR_SETUP_FAILED, _("Failed to add multiarch architecture to seccomp filter: %s"), flatpak_seccomp_strerror (r));
                }
            }
        }
    }

  /* TODO: Should we filter the kernel keyring syscalls in some way?
   * We do want them to be used by desktop apps, but they could also perhaps
   * leak system stuff or secrets from other apps.
   */

  for (i = 0; i < G_N_ELEMENTS (syscall_blocklist); i++)
    {
      int scall = syscall_blocklist[i].scall;
      int errnum = syscall_blocklist[i].errnum;

      g_return_val_if_fail (errnum == EPERM || errnum == ENOSYS, FALSE);

      if (syscall_blocklist[i].arg)
        r = seccomp_rule_add (seccomp, SCMP_ACT_ERRNO (errnum), scall, 1, *syscall_blocklist[i].arg);
      else
        r = seccomp_rule_add (seccomp, SCMP_ACT_ERRNO (errnum), scall, 0);

      /* EFAULT means "internal libseccomp error", but in practice we get
       * this for syscall numbers added via flatpak-syscalls-private.h
       * when trying to filter them on a non-native architecture, because
       * libseccomp cannot map the syscall number to a name and back to a
       * number for the non-native architecture. */
      if (r == -EFAULT)
        g_debug ("Unable to block syscall %d: syscall not known to libseccomp?",
                 scall);
      else if (r < 0)
        return flatpak_fail_error (error, FLATPAK_ERROR_SETUP_FAILED, _("Failed to block syscall %d: %s"), scall, flatpak_seccomp_strerror (r));
    }

  if (!multiarch)
    {
      /* modify_ldt is a historic source of interesting information leaks,
       * so it's disabled as a hardening measure.
       * However, it is required to run old 16-bit applications
       * as well as some Wine patches, so it's allowed in multiarch. */
      int scall = SCMP_SYS (modify_ldt);
      r = seccomp_rule_add (seccomp, SCMP_ACT_ERRNO (EPERM), scall, 0);

      /* See above for the meaning of EFAULT. */
      if (r == -EFAULT)
        g_debug ("Unable to block syscall %d: syscall not known to libseccomp?",
                 scall);
      else if (r < 0)
        return flatpak_fail_error (error, FLATPAK_ERROR_SETUP_FAILED, _("Failed to block syscall %d: %s"), scall, flatpak_seccomp_strerror (r));
    }

  if (!devel)
    {
      for (i = 0; i < G_N_ELEMENTS (syscall_nondevel_blocklist); i++)
        {
          int scall = syscall_nondevel_blocklist[i].scall;
          int errnum = syscall_nondevel_blocklist[i].errnum;

          g_return_val_if_fail (errnum == EPERM || errnum == ENOSYS, FALSE);

          if (syscall_nondevel_blocklist[i].arg)
            r = seccomp_rule_add (seccomp, SCMP_ACT_ERRNO (errnum), scall, 1, *syscall_nondevel_blocklist[i].arg);
          else
            r = seccomp_rule_add (seccomp, SCMP_ACT_ERRNO (errnum), scall, 0);

          /* See above for the meaning of EFAULT. */
          if (r == -EFAULT)
            g_debug ("Unable to block syscall %d: syscall not known to libseccomp?",
                     scall);
          else if (r < 0)
            return flatpak_fail_error (error, FLATPAK_ERROR_SETUP_FAILED, _("Failed to block syscall %d: %s"), scall, flatpak_seccomp_strerror (r));
        }
    }

  /* Socket filtering doesn't work on e.g. i386, so ignore failures here
   * However, we need to user seccomp_rule_add_exact to avoid libseccomp doing
   * something else: https://github.com/seccomp/libseccomp/issues/8 */
  last_allowed_family = -1;
  for (i = 0; i < G_N_ELEMENTS (socket_family_allowlist); i++)
    {
      int family = socket_family_allowlist[i].family;
      int disallowed;

      if (socket_family_allowlist[i].flags_mask != 0 &&
          (socket_family_allowlist[i].flags_mask & run_flags) != socket_family_allowlist[i].flags_mask)
        continue;

      for (disallowed = last_allowed_family + 1; disallowed < family; disallowed++)
        {
          /* Blocklist the in-between valid families */
          seccomp_rule_add_exact (seccomp, SCMP_ACT_ERRNO (EAFNOSUPPORT), SCMP_SYS (socket), 1, SCMP_A0 (SCMP_CMP_EQ, disallowed));
        }
      last_allowed_family = family;
    }
  /* Blocklist the rest */
  seccomp_rule_add_exact (seccomp, SCMP_ACT_ERRNO (EAFNOSUPPORT), SCMP_SYS (socket), 1, SCMP_A0 (SCMP_CMP_GE, last_allowed_family + 1));

  if (!glnx_open_anonymous_tmpfile_full (O_RDWR | O_CLOEXEC, "/tmp", &seccomp_tmpf, error))
    return FALSE;

  r = seccomp_export_bpf (seccomp, seccomp_tmpf.fd);

  if (r != 0)
    return flatpak_fail_error (error, FLATPAK_ERROR_SETUP_FAILED, _("Failed to export bpf: %s"), flatpak_seccomp_strerror (r));

  lseek (seccomp_tmpf.fd, 0, SEEK_SET);

  flatpak_bwrap_add_args_data_fd (bwrap,
                                  "--seccomp", g_steal_fd (&seccomp_tmpf.fd), NULL);

  return TRUE;
}
#endif

/*
 * @runtime_fd: the /usr for the runtime, or -1 if running with no runtime,
 *  perhaps to unpack extra-data
 */
static void
flatpak_run_setup_usr_links (FlatpakBwrap *bwrap,
                             int          runtime_fd,
                             const char   *sysroot)
{
  int i;

  g_return_if_fail (runtime_fd >= -1);

  if (runtime_fd < 0)
    return;

  for (i = 0; flatpak_abs_usrmerged_dirs[i] != NULL; i++)
    {
      const char *subdir = flatpak_abs_usrmerged_dirs[i];
      glnx_autofd int runtime_subdir_fd = -1;
      g_autoptr(GError) local_error = NULL;

      g_assert (subdir[0] == '/');

      /* Skip the '/' when using as a subdirectory of the runtime */
      runtime_subdir_fd = glnx_chaseat (runtime_fd, subdir + 1,
                                        GLNX_CHASE_RESOLVE_BENEATH |
                                        GLNX_CHASE_NOFOLLOW,
                                        &local_error);

      if (runtime_subdir_fd < 0 &&
          !g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
        {
          g_warning ("Checking for usrmerged dir %s failed: %s",
                     subdir, local_error->message);
        }
      else if (runtime_subdir_fd < 0)
        {
          g_info ("%s does not exist in runtime", subdir);
        }
      else
        {
          g_autofree char *link = g_strconcat ("usr", subdir, NULL);
          g_autofree char *create = NULL;

          if (sysroot != NULL)
            create = g_strconcat (sysroot, subdir, NULL);
          else
            create = g_strdup (subdir);

          flatpak_bwrap_add_args (bwrap,
                                  "--symlink", link, create,
                                  NULL);
        }
    }
}

/* Directories in /sys to share with the sandbox if accessible. */
static const char *const sysfs_dirs[] =
{
  "/sys/block",
  "/sys/bus",
  "/sys/class",
  "/sys/dev",
  "/sys/devices"
};

/*
 * @runtime_fd: the /usr for the runtime, or -1 if running with no runtime,
 *  perhaps to unpack extra-data
 */
gboolean
flatpak_run_setup_base_argv (FlatpakBwrap   *bwrap,
                             int             runtime_fd,
                             GFile          *app_id_dir,
                             const char     *arch,
                             FlatpakRunFlags flags,
                             GError        **error)
{
  g_autofree char *run_dir = NULL;
  g_autofree char *passwd_contents = NULL;
  g_autoptr(GString) group_contents = NULL;
  const char *pkcs11_conf_contents = NULL;
  struct group *g;
  gulong pers;
  gid_t gid = getgid ();
  gboolean parent_expose_pids = (flags & FLATPAK_RUN_FLAG_PARENT_EXPOSE_PIDS) != 0;
  gboolean parent_share_pids = (flags & FLATPAK_RUN_FLAG_PARENT_SHARE_PIDS) != 0;
  gboolean bwrap_unprivileged = flatpak_bwrap_is_unprivileged ();
  gsize i;

  g_return_val_if_fail (runtime_fd >= -1, FALSE);

  /* Disable recursive userns for all flatpak processes, as we need this
   * to guarantee that the sandbox can't restructure the filesystem.
   * Allowing to change e.g. /.flatpak-info would allow sandbox escape
   * via portals.
   *
   * This is also done via seccomp, but here we do it using userns
   * unsharing in combination with max_user_namespaces.
   *
   * If bwrap is setuid, then --disable-userns will not work, which
   * makes the seccomp filter security-critical.
   */
  if (bwrap_unprivileged)
    {
      if (parent_expose_pids || parent_share_pids)
        {
          /* If we're joining an existing sandbox's user and process
           * namespaces, then it should already have creation of
           * nested user namespaces disabled. */
          flatpak_bwrap_add_arg (bwrap, "--assert-userns-disabled");
        }
      else
        {
          /* This is a new sandbox, so we need to disable creation of
           * nested user namespaces. */
          flatpak_bwrap_add_arg (bwrap, "--unshare-user");
          flatpak_bwrap_add_arg (bwrap, "--disable-userns");
        }
    }

  run_dir = g_strdup_printf ("/run/user/%d", getuid ());

  passwd_contents = g_strdup_printf ("%s:x:%d:%d:%s:%s:%s\n"
                                     "nfsnobody:x:65534:65534:Unmapped user:/:/sbin/nologin\n",
                                     g_get_user_name (),
                                     getuid (), gid,
                                     g_get_real_name (),
                                     g_get_home_dir (),
                                     DEFAULT_SHELL);

  group_contents = g_string_new ("");
  g = getgrgid (gid);
  /* if NULL, the primary group is not known outside the container, so
   * it might as well stay unknown inside the container... */
  if (g != NULL)
    g_string_append_printf (group_contents, "%s:x:%d:%s\n",
                            g->gr_name, gid, g_get_user_name ());
  g_string_append (group_contents, "nfsnobody:x:65534:\n");

  pkcs11_conf_contents =
    "# Disable user pkcs11 config, because the host modules don't work in the runtime\n"
    "user-config: none\n";

  if ((flags & FLATPAK_RUN_FLAG_NO_PROC) == 0)
    flatpak_bwrap_add_args (bwrap,
                            "--proc", "/proc",
                            NULL);

  if (!(flags & FLATPAK_RUN_FLAG_PARENT_SHARE_PIDS))
    flatpak_bwrap_add_arg (bwrap, "--unshare-pid");

  flatpak_bwrap_add_args (bwrap,
                          "--dir", "/tmp",
                          "--dir", "/var/tmp",
                          "--dir", "/run/host",
                          "--perms", "0700", "--dir", run_dir,
                          "--setenv", "XDG_RUNTIME_DIR", run_dir,
                          "--symlink", "../run", "/var/run",
                          "--ro-bind-try", "/proc/self/ns/user", "/run/.userns",
                          /* glib uses this like /etc/timezone */
                          "--symlink", "/etc/timezone", "/var/db/zoneinfo",
                          NULL);

  for (i = 0; i < G_N_ELEMENTS (sysfs_dirs); i++)
    {
      const char *dir = sysfs_dirs[i];

      if (access (dir, R_OK|X_OK) == 0)
        flatpak_bwrap_add_args (bwrap, "--ro-bind", dir, dir, NULL);
      else
        g_info ("Not sharing %s with sandbox: %s", dir, g_strerror (errno));
    }

  if (flags & FLATPAK_RUN_FLAG_DIE_WITH_PARENT)
    flatpak_bwrap_add_args (bwrap,
                            "--die-with-parent",
                            NULL);

  if (flags & FLATPAK_RUN_FLAG_WRITABLE_ETC)
    flatpak_bwrap_add_args (bwrap,
                            "--dir", "/usr/etc",
                            "--symlink", "usr/etc", "/etc",
                            NULL);

  if (!flatpak_bwrap_add_args_data (bwrap, "passwd", passwd_contents, -1, "/etc/passwd", error))
    return FALSE;

  if (!flatpak_bwrap_add_args_data (bwrap, "group", group_contents->str, -1, "/etc/group", error))
    return FALSE;

  if (!flatpak_bwrap_add_args_data (bwrap, "pkcs11.conf", pkcs11_conf_contents, -1, "/etc/pkcs11/pkcs11.conf", error))
    return FALSE;

  if (g_file_test ("/etc/machine-id", G_FILE_TEST_EXISTS))
    flatpak_bwrap_add_args (bwrap, "--ro-bind", "/etc/machine-id", "/etc/machine-id", NULL);
  else if (g_file_test ("/var/lib/dbus/machine-id", G_FILE_TEST_EXISTS))
    flatpak_bwrap_add_args (bwrap, "--ro-bind", "/var/lib/dbus/machine-id", "/etc/machine-id", NULL);

  if (runtime_fd >= 0
      && (flags & FLATPAK_RUN_FLAG_WRITABLE_ETC) == 0)
    {
      g_auto(GLnxDirFdIterator) dfd_iter = { 0, };
      struct dirent *dent;
      gboolean inited;
      g_autoptr(GError) local_error = NULL;

      inited = glnx_dirfd_iterator_init_at (runtime_fd, "etc", FALSE, &dfd_iter, &local_error);
      if (!inited && !g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
        {
          g_propagate_error (error, g_steal_pointer (&local_error));
          return FALSE;
        }

      while (inited)
        {
          g_autofree char *dest = NULL;
          glnx_autofd int src_fd = -1;
          struct stat statbuf;

          if (!glnx_dirfd_iterator_next_dent_ensure_dtype (&dfd_iter, &dent, NULL, NULL) || dent == NULL)
            break;

          if (strcmp (dent->d_name, "passwd") == 0 ||
              strcmp (dent->d_name, "group") == 0 ||
              strcmp (dent->d_name, "machine-id") == 0 ||
              strcmp (dent->d_name, "resolv.conf") == 0 ||
              strcmp (dent->d_name, "host.conf") == 0 ||
              strcmp (dent->d_name, "hosts") == 0 ||
              strcmp (dent->d_name, "gai.conf") == 0 ||
              strcmp (dent->d_name, "localtime") == 0 ||
              strcmp (dent->d_name, "timezone") == 0 ||
              strcmp (dent->d_name, "pkcs11") == 0)
            continue;

          dest = g_build_filename ("/etc", dent->d_name, NULL);

          src_fd = glnx_chaseat (dfd_iter.fd, dent->d_name,
                                 GLNX_CHASE_NOFOLLOW |
                                 GLNX_CHASE_RESOLVE_BENEATH,
                                 error);
          if (src_fd < 0)
            return FALSE;

          if (!glnx_fstat (src_fd, &statbuf, error))
            return FALSE;

          if (S_ISLNK (statbuf.st_mode))
            {
              g_autofree char *target = NULL;

              target = glnx_readlinkat_malloc (dfd_iter.fd, dent->d_name,
                                               NULL, error);
              if (target == NULL)
                return FALSE;

              flatpak_bwrap_add_args (bwrap, "--symlink", target, dest, NULL);
            }
          else if (src_fd >= 0)
            {
              flatpak_bwrap_add_args_data_fd (bwrap,
                                              "--ro-bind-fd",
                                              g_steal_fd (&src_fd),
                                              dest);
            }
        }
    }

  if (app_id_dir != NULL)
    {
      g_autoptr(GFile) app_cache_dir = g_file_get_child (app_id_dir, "cache");
      g_autoptr(GFile) app_tmp_dir = g_file_get_child (app_cache_dir, "tmp");
      g_autoptr(GFile) app_data_dir = g_file_get_child (app_id_dir, "data");
      g_autoptr(GFile) app_config_dir = g_file_get_child (app_id_dir, "config");

      flatpak_bwrap_add_args (bwrap,
                              /* These are nice to have as a fixed path */
                              "--bind", flatpak_file_get_path_cached (app_cache_dir), "/var/cache",
                              "--bind", flatpak_file_get_path_cached (app_data_dir), "/var/data",
                              "--bind", flatpak_file_get_path_cached (app_config_dir), "/var/config",
                              "--bind", flatpak_file_get_path_cached (app_tmp_dir), "/var/tmp",
                              NULL);
    }

  flatpak_run_setup_usr_links (bwrap, runtime_fd, NULL);

  add_tzdata_args (bwrap, runtime_fd);

  pers = PER_LINUX;

  if ((flags & FLATPAK_RUN_FLAG_SET_PERSONALITY) &&
      flatpak_is_linux32_arch (arch))
    {
      g_info ("Setting personality linux32");
      pers = PER_LINUX32;
    }

  /* Always set the personallity, and clear all weird flags */
  personality (pers);

#ifdef ENABLE_SECCOMP
  if (!setup_seccomp (bwrap, arch, pers, flags, error))
    return FALSE;
#endif

  if ((flags & FLATPAK_RUN_FLAG_WRITABLE_ETC) == 0)
    add_monitor_path_args ((flags & FLATPAK_RUN_FLAG_NO_SESSION_HELPER) == 0, bwrap);

  return TRUE;
}

static gboolean
forward_file (XdpDbusDocuments *documents,
              const char       *app_id,
              const char       *file,
              char            **out_doc_id,
              GError          **error)
{
  int fd, fd_id;
  struct stat stbuf;
  guint portal_version;
  gboolean is_dir = FALSE;
  g_autofree char *doc_id = NULL;
  g_autoptr(GUnixFDList) fd_list = NULL;
  const char *perms[] = { "read", "write", NULL };

  fd = open (file, O_PATH | O_CLOEXEC);
  if (fd == -1)
    return flatpak_fail (error, _("Failed to open ‘%s’"), file);

  fd_list = g_unix_fd_list_new ();
  fd_id = g_unix_fd_list_append (fd_list, fd, error);
  if (fstat (fd, &stbuf) == 0 && S_ISDIR (stbuf.st_mode))
    is_dir = TRUE;
  close (fd);

  portal_version = xdp_dbus_documents_get_version (documents);
  if (portal_version < 4 && is_dir)
      return flatpak_fail (error, _("Directory forwarding needs version 4 of the document portal (have version %d)"), portal_version);

  if (portal_version >= 2)
    {
      guint flags = DOCUMENT_ADD_FLAGS_REUSE_EXISTING;
      g_auto(GStrv) doc_ids = NULL;

      if (is_dir)
        flags |= DOCUMENT_ADD_FLAGS_DIRECTORY;

      if (!xdp_dbus_documents_call_add_full_sync (documents,
                                                  g_variant_new_fixed_array (G_VARIANT_TYPE_HANDLE, &fd_id, 1, sizeof (gint32)),
                                                  flags,
                                                  app_id,
                                                  perms,
                                                  fd_list,
                                                  &doc_ids,
                                                  NULL,
                                                  NULL,
                                                  NULL,
                                                  error))
        {
          if (error)
            g_dbus_error_strip_remote_error (*error);
          return FALSE;
        }

      /* doc_ids should have value when xdp_dbus_documents_call_add_full_sync succeeds. */
      g_assert (doc_ids && doc_ids[0]);
      doc_id = g_strdup (doc_ids[0]);
    }
  else
    {
      /* Fallback to plain org.freedesktop.portal.Documents.Add and
         org.freedesktop.portal.Documents.GrantPermissions if interface version is older.
         This does not support directory export. */
      if (!xdp_dbus_documents_call_add_sync (documents,
                                             g_variant_new ("h", fd_id),
                                             TRUE, /* reuse */
                                             FALSE, /* not persistent */
                                             fd_list,
                                             &doc_id,
                                             NULL,
                                             NULL,
                                             error))
        {
          if (error)
            g_dbus_error_strip_remote_error (*error);
          return FALSE;
        }

      if (!xdp_dbus_documents_call_grant_permissions_sync (documents,
                                                           doc_id,
                                                           app_id,
                                                           perms,
                                                           NULL,
                                                           error))
        {
          if (error)
            g_dbus_error_strip_remote_error (*error);
          return FALSE;
        }
    }

  *out_doc_id = g_steal_pointer (&doc_id);

  return TRUE;
}

static gboolean
add_rest_args (FlatpakBwrap   *bwrap,
               const char     *app_id,
               FlatpakExports *exports,
               gboolean        file_forwarding,
               const char     *doc_mount_path,
               char           *args[],
               int             n_args,
               GError        **error)
{
  g_autoptr(AutoXdpDbusDocuments) documents = NULL;
  gboolean forwarding = FALSE;
  gboolean forwarding_uri = FALSE;
  gboolean can_forward = TRUE;
  int i;

  if (file_forwarding && doc_mount_path == NULL)
    {
      g_message ("Can't get document portal mount path");
      can_forward = FALSE;
    }
  else if (file_forwarding)
    {
      g_autoptr(GError) local_error = NULL;

      documents = xdp_dbus_documents_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION, 0,
                                                             "org.freedesktop.portal.Documents",
                                                             "/org/freedesktop/portal/documents",
                                                             NULL,
                                                             &local_error);
      if (documents == NULL)
        {
          g_message ("Can't get document portal: %s", local_error->message);
          can_forward = FALSE;
        }
    }

  for (i = 0; i < n_args; i++)
    {
      g_autoptr(GFile) file = NULL;

      if (file_forwarding &&
          (strcmp (args[i], "@@") == 0 ||
           strcmp (args[i], "@@u") == 0))
        {
          forwarding_uri = strcmp (args[i], "@@u") == 0;
          forwarding = !forwarding;
          continue;
        }

      if (can_forward && forwarding)
        {
          if (forwarding_uri)
            {
              if (g_str_has_prefix (args[i], "file:"))
                file = g_file_new_for_uri (args[i]);
              else if (G_IS_DIR_SEPARATOR (args[i][0]))
                file = g_file_new_for_path (args[i]);
            }
          else
            file = g_file_new_for_path (args[i]);
        }

      if (file && !flatpak_exports_path_is_visible (exports,
                                                    flatpak_file_get_path_cached (file)))
        {
          g_autofree char *doc_id = NULL;
          g_autofree char *basename = NULL;
          g_autofree char *doc_path = NULL;
          if (!forward_file (documents, app_id, flatpak_file_get_path_cached (file),
                             &doc_id, error))
            return FALSE;

          basename = g_file_get_basename (file);
          doc_path = g_build_filename (doc_mount_path, doc_id, basename, NULL);

          if (forwarding_uri)
            {
              g_autofree char *path = doc_path;
              doc_path = g_filename_to_uri (path, NULL, NULL);
              /* This should never fail */
              g_assert (doc_path != NULL);
            }

          g_info ("Forwarding file '%s' as '%s' to %s", args[i], doc_path, app_id);
          flatpak_bwrap_add_arg (bwrap, doc_path);
        }
      else
        flatpak_bwrap_add_arg (bwrap, args[i]);
    }

  return TRUE;
}

FlatpakContext *
flatpak_context_load_for_deploy (FlatpakDeploy *deploy,
                                 GError       **error)
{
  g_autoptr(FlatpakContext) context = NULL;
  g_autoptr(FlatpakContext) overrides = NULL;
  g_autoptr(GKeyFile) metakey = NULL;

  metakey = flatpak_deploy_get_metadata (deploy);
  context = flatpak_app_compute_permissions (metakey, NULL, error);
  if (context == NULL)
    return NULL;

  overrides = flatpak_deploy_get_overrides (deploy);
  flatpak_context_merge (context, overrides);

  return g_steal_pointer (&context);
}

static char *
calculate_ld_cache_checksum (GBytes   *app_deploy_data,
                             GBytes   *runtime_deploy_data,
                             const char *app_extensions,
                             const char *runtime_extensions)
{
  g_autoptr(GChecksum) ld_so_checksum = g_checksum_new (G_CHECKSUM_SHA256);
  if (app_deploy_data)
    g_checksum_update (ld_so_checksum, (guchar *) flatpak_deploy_data_get_commit (app_deploy_data), -1);
  g_checksum_update (ld_so_checksum, (guchar *) flatpak_deploy_data_get_commit (runtime_deploy_data), -1);
  if (app_extensions)
    g_checksum_update (ld_so_checksum, (guchar *) app_extensions, -1);
  if (runtime_extensions)
    g_checksum_update (ld_so_checksum, (guchar *) runtime_extensions, -1);

  return g_strdup (g_checksum_get_string (ld_so_checksum));
}

static gboolean
add_ld_so_conf (FlatpakBwrap *bwrap,
                GError      **error)
{
  const char *contents =
    "include /run/flatpak/ld.so.conf.d/app-*.conf\n"
    "include /app/etc/ld.so.conf\n"
    "/app/lib\n"
    "include /run/flatpak/ld.so.conf.d/runtime-*.conf\n";

  return flatpak_bwrap_add_args_data (bwrap, "ld-so-conf",
                                      contents, -1, "/etc/ld.so.conf", error);
}

static int
regenerate_ld_cache (GPtrArray    *base_argv_array,
                     GArray       *base_fd_array,
                     GFile        *app_id_dir,
                     const char   *checksum,
                     int           runtime_fd,
                     gboolean      generate_ld_so_conf,
                     GCancellable *cancellable,
                     GError      **error)
{
  g_autoptr(FlatpakBwrap) bwrap = NULL;
  g_autoptr(GArray) combined_fd_array = NULL;
  g_autoptr(GFile) ld_so_cache = NULL;
  g_autoptr(GFile) ld_so_cache_tmp = NULL;
  g_autofree char *sandbox_cache_path = NULL;
  g_autofree char *tmp_basename = NULL;
  g_auto(GStrv) minimal_envp = NULL;
  g_autofree char *commandline = NULL;
  int exit_status;
  glnx_autofd int ld_so_fd = -1;
  g_autoptr(GFile) ld_so_dir = NULL;

  if (app_id_dir)
    ld_so_dir = g_file_get_child (app_id_dir, ".ld.so");
  else
    {
      g_autoptr(GFile) base_dir = g_file_new_for_path (g_get_user_cache_dir ());
      ld_so_dir = g_file_resolve_relative_path (base_dir, "flatpak/ld.so");
    }

  ld_so_cache = g_file_get_child (ld_so_dir, checksum);
  ld_so_fd = open (flatpak_file_get_path_cached (ld_so_cache), O_RDONLY);
  if (ld_so_fd >= 0)
    return g_steal_fd (&ld_so_fd);

  g_info ("Regenerating ld.so.cache %s", flatpak_file_get_path_cached (ld_so_cache));

  if (!flatpak_mkdir_p (ld_so_dir, cancellable, error))
    return FALSE;

  minimal_envp = flatpak_run_get_minimal_env (FALSE, FALSE);
  bwrap = flatpak_bwrap_new (minimal_envp);

  flatpak_bwrap_append_args (bwrap, base_argv_array);

  flatpak_run_setup_usr_links (bwrap, runtime_fd, NULL);

  if (generate_ld_so_conf)
    {
      if (!add_ld_so_conf (bwrap, error))
        return -1;
    }
  else
    flatpak_bwrap_add_args (bwrap,
                            "--symlink", "../usr/etc/ld.so.conf", "/etc/ld.so.conf",
                            NULL);

  tmp_basename = g_strconcat (checksum, ".XXXXXX", NULL);
  glnx_gen_temp_name (tmp_basename);

  sandbox_cache_path = g_build_filename ("/run/ld-so-cache-dir", tmp_basename, NULL);
  ld_so_cache_tmp = g_file_get_child (ld_so_dir, tmp_basename);

  flatpak_bwrap_add_args (bwrap,
                          "--unshare-pid",
                          "--unshare-ipc",
                          "--unshare-net",
                          "--proc", "/proc",
                          "--dev", "/dev",
                          "--bind", flatpak_file_get_path_cached (ld_so_dir), "/run/ld-so-cache-dir",
                          NULL);
  flatpak_bwrap_sort_envp (bwrap);
  flatpak_bwrap_envp_to_args (bwrap);

  if (!flatpak_bwrap_bundle_args (bwrap, 1, -1, FALSE, error))
    return -1;

  flatpak_bwrap_add_args (bwrap,
                          "ldconfig", "-X", "-C", sandbox_cache_path, NULL);

  flatpak_bwrap_finish (bwrap);

  commandline = flatpak_quote_argv ((const char **) bwrap->argv->pdata, -1);
  g_info ("Running: '%s'", commandline);

  combined_fd_array = g_array_new (FALSE, TRUE, sizeof (int));
  g_array_append_vals (combined_fd_array, base_fd_array->data, base_fd_array->len);
  g_array_append_vals (combined_fd_array, bwrap->fds->data, bwrap->fds->len);

  /* We use LEAVE_DESCRIPTORS_OPEN and close them in the child_setup
   * to work around a deadlock in GLib < 2.60 */
  if (!g_spawn_sync (NULL,
                     (char **) bwrap->argv->pdata,
                     bwrap->envp,
                     G_SPAWN_SEARCH_PATH | G_SPAWN_LEAVE_DESCRIPTORS_OPEN,
                     flatpak_bwrap_child_setup_cb, combined_fd_array,
                     NULL, NULL,
                     &exit_status,
                     error))
    return -1;

  if (!WIFEXITED (exit_status) || WEXITSTATUS (exit_status) != 0)
    {
      flatpak_fail_error (error, FLATPAK_ERROR_SETUP_FAILED,
                          _("ldconfig failed, exit status %d"), exit_status);
      return -1;
    }

  ld_so_fd = open (flatpak_file_get_path_cached (ld_so_cache_tmp), O_RDONLY);
  if (ld_so_fd < 0)
    {
      flatpak_fail_error (error, FLATPAK_ERROR_SETUP_FAILED, _("Can't open generated ld.so.cache"));
      return -1;
    }

  if (app_id_dir == NULL)
    {
      /* For runs without an app id dir we always regenerate the ld.so.cache */
      unlink (flatpak_file_get_path_cached (ld_so_cache_tmp));
    }
  else
    {
      g_autoptr(GFile) active = g_file_get_child (ld_so_dir, "active");

      /* For app-dirs we keep one checksum alive, by pointing the active symlink to it */

      /* Rename to known name, possibly overwriting existing ref if race */
      if (rename (flatpak_file_get_path_cached (ld_so_cache_tmp), flatpak_file_get_path_cached (ld_so_cache)) == -1)
        {
          glnx_set_error_from_errno (error);
          return -1;
        }

      if (!flatpak_switch_symlink_and_remove (flatpak_file_get_path_cached (active),
                                              checksum, error))
        return -1;
    }

  return g_steal_fd (&ld_so_fd);
}

/* Check that this user is actually allowed to run this app. When running
 * from the gnome-initial-setup session, an app filter might not be available. */
static gboolean
check_parental_controls (FlatpakDecomposed *app_ref,
                         FlatpakDeploy     *deploy,
                         GCancellable      *cancellable,
                         GError           **error)
{
#ifdef HAVE_LIBMALCONTENT
  g_autoptr(MctManager) manager = NULL;
  g_autoptr(MctAppFilter) app_filter = NULL;
  g_autoptr(GDBusConnection) system_bus = NULL;
  g_autoptr(GError) local_error = NULL;
  g_autoptr(GDesktopAppInfo) app_info = NULL;
  gboolean allowed = FALSE;

  system_bus = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &local_error);
  if (system_bus == NULL)
    {
      /* Since the checks below allow access when malcontent or
       * accounts-service aren't available on the bus, this whole routine can
       * be trivially bypassed by setting DBUS_SYSTEM_BUS_ADDRESS to a
       * temporary dbus-daemon. Not being able to connect to the system bus is
       * basically equivalent.
       */
      g_debug ("Skipping parental controls check for %s since D-Bus system "
               "bus connection failed: %s",
               flatpak_decomposed_get_ref (app_ref),
               local_error ? local_error->message : "unknown reason");
      return TRUE;
    }

  manager = mct_manager_new (system_bus);
  app_filter = mct_manager_get_app_filter (manager, getuid (),
                                           MCT_MANAGER_GET_VALUE_FLAGS_INTERACTIVE,
                                           cancellable, &local_error);
  if (g_error_matches (local_error, MCT_MANAGER_ERROR, MCT_MANAGER_ERROR_DISABLED))
    {
      g_info ("Skipping parental controls check for %s since parental "
              "controls are disabled globally", flatpak_decomposed_get_ref (app_ref));
      return TRUE;
    }
  else if (g_error_matches (local_error, G_DBUS_ERROR, G_DBUS_ERROR_SERVICE_UNKNOWN) ||
           g_error_matches (local_error, G_DBUS_ERROR, G_DBUS_ERROR_NAME_HAS_NO_OWNER))
    {
      g_info ("Skipping parental controls check for %s since a required "
              "service was not found", flatpak_decomposed_get_ref (app_ref));
      return TRUE;
    }
  else if (local_error != NULL)
    {
      g_propagate_error (error, g_steal_pointer (&local_error));
      return FALSE;
    }

  /* Always filter by app ID. Additionally, filter by app info (which runs
   * multiple checks, including whether the app ID, executable path and
   * content types are allowed) if available. If the flatpak contains
   * multiple .desktop files, we use the main one. The app ID check is
   * always done, as the binary executed by `flatpak run` isn’t necessarily
   * extracted from a .desktop file. */
  allowed = mct_app_filter_is_flatpak_ref_allowed (app_filter, flatpak_decomposed_get_ref (app_ref));

  /* Look up the app’s main .desktop file. */
  if (deploy != NULL && allowed)
    {
      g_autoptr(GFile) deploy_dir = NULL;
      const char *deploy_path;
      g_autofree char *desktop_file_name = NULL;
      g_autofree char *desktop_file_path = NULL;
      g_autofree char *app_id = flatpak_decomposed_dup_id (app_ref);

      deploy_dir = flatpak_deploy_get_dir (deploy);
      deploy_path = flatpak_file_get_path_cached (deploy_dir);

      desktop_file_name = g_strconcat (app_id, ".desktop", NULL);
      desktop_file_path = g_build_path (G_DIR_SEPARATOR_S,
                                        deploy_path,
                                        "export",
                                        "share",
                                        "applications",
                                        desktop_file_name,
                                        NULL);
      app_info = g_desktop_app_info_new_from_filename (desktop_file_path);
    }

  if (app_info != NULL)
    allowed = allowed && mct_app_filter_is_appinfo_allowed (app_filter,
                                                            G_APP_INFO (app_info));

  if (!allowed)
    return flatpak_fail_error (error, FLATPAK_ERROR_PERMISSION_DENIED,
                               /* Translators: The placeholder is for an app ref. */
                               _("Running %s is not allowed by the policy set by your administrator"),
                               flatpak_decomposed_get_ref (app_ref));
#endif  /* HAVE_LIBMALCONTENT */

  return TRUE;
}

static int
open_namespace_fd_if_needed (const char *path,
                             const char *other_path) {
  struct stat s, other_s;

  if (stat (path, &s) != 0)
    return -1; /* No such namespace, ignore */

  if (stat (other_path, &other_s) != 0)
    return -1; /* No such namespace, ignore */

  /* setns calls fail if the process is already in the desired namespace, hence the
     check here to ensure the namespaces are different. */
  if (s.st_ino != other_s.st_ino)
    return open (path, O_RDONLY|O_CLOEXEC);

  return -1;
}

FlatpakContextShares
flatpak_run_compute_allowed_shares (FlatpakContext *context)
{
  return flatpak_context_compute_allowed_shares (context,
                                                 flatpak_run_evaluate_conditions);
}

FlatpakContextDevices
flatpak_run_compute_allowed_devices (FlatpakContext *context)
{
  return flatpak_context_compute_allowed_devices (context,
                                                  flatpak_run_evaluate_conditions);
}

FlatpakContextSockets
flatpak_run_compute_allowed_sockets (FlatpakContext *context)
{
  return flatpak_context_compute_allowed_sockets (context,
                                                  flatpak_run_evaluate_conditions);
}

FlatpakContextFeatures
flatpak_run_compute_allowed_features (FlatpakContext *context)
{
  return flatpak_context_compute_allowed_features (context,
                                                   flatpak_run_evaluate_conditions);
}

gboolean
flatpak_run_app (FlatpakDecomposed   *app_ref,
                 FlatpakDeploy       *app_deploy,
                 int                  custom_app_fd,
                 FlatpakContext      *extra_context,
                 const char          *custom_runtime,
                 const char          *custom_runtime_version,
                 const char          *custom_runtime_commit,
                 int                  custom_runtime_fd,
                 int                  parent_pid,
                 FlatpakRunFlags      flags,
                 const char          *cwd,
                 const char          *custom_command,
                 char                *args[],
                 int                  n_args,
                 int                  instance_id_fd,
                 const char * const  *run_environ,
                 char               **instance_dir_out,
                 GArray              *bind_fds,
                 GArray              *ro_bind_fds,
                 GCancellable        *cancellable,
                 GError             **error)
{
  g_autoptr(FlatpakDeploy) runtime_deploy = NULL;
  g_autoptr(GBytes) runtime_deploy_data = NULL;
  g_autoptr(GBytes) app_deploy_data = NULL;
  g_autoptr(GFile) app_id_dir = NULL;
  g_autoptr(GFile) real_app_id_dir = NULL;
  g_autofree char *default_runtime_pref = NULL;
  g_autoptr(FlatpakDecomposed) default_runtime = NULL;
  g_autofree char *default_command = NULL;
  g_autoptr(GKeyFile) metakey = NULL;
  g_autoptr(GKeyFile) runtime_metakey = NULL;
  g_autoptr(FlatpakBwrap) bwrap = NULL;
  const char *command = "/bin/sh";
  g_autoptr(GError) my_error = NULL;
  g_autoptr(FlatpakDecomposed) runtime_ref = NULL;
  int i;
  g_autoptr(GPtrArray) previous_app_id_dirs = NULL;
  g_autofree char *app_id = NULL;
  g_autofree char *app_arch = NULL;
  g_autofree char *app_info_path = NULL;
  g_autofree char *app_ld_path = NULL;
  g_autofree char *instance_id_host_dir = NULL;
  g_autofree char *instance_id_host_private_dir = NULL;
  g_autofree char *instance_id = NULL;
  g_autoptr(FlatpakContext) app_context = NULL;
  g_autoptr(FlatpakContext) overrides = NULL;
  g_autoptr(FlatpakExports) exports = NULL;
  g_autofree char *commandline = NULL;
  g_autofree char *doc_mount_path = NULL;
  g_autofree char *app_extensions = NULL;
  g_autofree char *runtime_extensions = NULL;
  g_autofree char *runtime_ld_path = NULL;
  g_autofree char *checksum = NULL;
  glnx_autofd int per_app_dir_lock_fd = -1;
  g_autofree char *per_app_dir_lock_path = NULL;
  g_autofree char *shared_xdg_runtime_dir = NULL;
  int ld_so_fd = -1;
  gboolean generate_ld_so_conf = TRUE;
  gboolean use_ld_so_cache = TRUE;
  gboolean sandboxed = (flags & FLATPAK_RUN_FLAG_SANDBOX) != 0;
  gboolean parent_expose_pids = (flags & FLATPAK_RUN_FLAG_PARENT_EXPOSE_PIDS) != 0;
  gboolean parent_share_pids = (flags & FLATPAK_RUN_FLAG_PARENT_SHARE_PIDS) != 0;
  FlatpakContextShares shares;
  FlatpakContextDevices devices;
  FlatpakContextSockets sockets;
  FlatpakContextFeatures features;
  glnx_autofd int original_runtime_fd = -1;
  g_autoptr(GFile) original_runtime_files = NULL;
  g_autoptr(GFile) custom_runtime_files = NULL;
  /* borrows from either original_runtime_fd or custom_runtime_fd */
  int runtime_fd = -1;
  /* borrows from either original_runtime_files or custom_runtime_files */
  GFile *runtime_files = NULL;
  const char *original_runtime_target_path = NULL;
  glnx_autofd int original_app_fd = -1;
  g_autoptr(GFile) original_app_files = NULL;
  g_autoptr(GFile) custom_app_files = NULL;
  /* borrows from either original_app_fd or custom_app_fd */
  int app_fd = -1;
  /* borrows from either original_app_files or custom_app_files */
  GFile *app_files = NULL;
  const char *original_app_target_path = NULL;

  g_assert (run_environ != NULL);

  g_return_val_if_fail (app_ref != NULL, FALSE);

  g_return_val_if_fail (custom_app_fd == FLATPAK_RUN_APP_DEPLOY_APP_ORIGINAL ||
                        custom_app_fd == FLATPAK_RUN_APP_DEPLOY_APP_EMPTY ||
                        custom_app_fd >= 0,
                        FALSE);

  g_return_val_if_fail (custom_runtime_fd == FLATPAK_RUN_APP_DEPLOY_USR_ORIGINAL ||
                        custom_runtime_fd >= 0,
                        FALSE);

  /* This check exists to stop accidental usage of `sudo flatpak run`
     and is not to prevent running as root.
   */
  if (running_under_sudo_root ())
    return flatpak_fail_error (error, FLATPAK_ERROR,
                               _("\"flatpak run\" is not intended to be run as `sudo flatpak run`. "
                                 "Use `sudo -i` or `su -l` instead and invoke \"flatpak run\" from "
                                 "inside the new shell."));

  app_id = flatpak_decomposed_dup_id (app_ref);
  g_return_val_if_fail (app_id != NULL, FALSE);
  app_arch = flatpak_decomposed_dup_arch (app_ref);
  g_return_val_if_fail (app_arch != NULL, FALSE);

  /* Check the user is allowed to run this flatpak. */
  if (!check_parental_controls (app_ref, app_deploy, cancellable, error))
    return FALSE;

  /* Construct the bwrap context. */
  bwrap = flatpak_bwrap_new (NULL);
  flatpak_bwrap_add_arg (bwrap, flatpak_get_bwrap ());

  if (app_deploy == NULL)
    {
      g_assert (flatpak_decomposed_is_runtime (app_ref));
      default_runtime_pref = flatpak_decomposed_dup_pref (app_ref);
    }
  else
    {
      const gchar *key;

      app_deploy_data = flatpak_deploy_get_deploy_data (app_deploy, FLATPAK_DEPLOY_VERSION_ANY, cancellable, error);
      if (app_deploy_data == NULL)
        return FALSE;

      if ((flags & FLATPAK_RUN_FLAG_DEVEL) != 0)
        key = FLATPAK_METADATA_KEY_SDK;
      else
        key = FLATPAK_METADATA_KEY_RUNTIME;

      metakey = flatpak_deploy_get_metadata (app_deploy);
      default_runtime_pref = g_key_file_get_string (metakey,
                                                    FLATPAK_METADATA_GROUP_APPLICATION,
                                                    key, &my_error);
      if (my_error)
        {
          g_propagate_error (error, g_steal_pointer (&my_error));
          return FALSE;
        }
    }

  default_runtime = flatpak_decomposed_new_from_pref (FLATPAK_KINDS_RUNTIME, default_runtime_pref, error);
  if (default_runtime == NULL)
    return FALSE;

  if (custom_runtime != NULL || custom_runtime_version != NULL)
    {
      g_auto(GStrv) custom_runtime_parts = NULL;
      const char *custom_runtime_id = NULL;
      const char *custom_runtime_arch = NULL;

      if (custom_runtime)
        {
          custom_runtime_parts = g_strsplit (custom_runtime, "/", 0);
          for (i = 0; i < 3 && custom_runtime_parts[i] != NULL; i++)
            {
              if (strlen (custom_runtime_parts[i]) > 0)
                {
                  if (i == 0)
                    custom_runtime_id = custom_runtime_parts[i];
                  if (i == 1)
                    custom_runtime_arch = custom_runtime_parts[i];

                  if (i == 2 && custom_runtime_version == NULL)
                    custom_runtime_version = custom_runtime_parts[i];
                }
            }
        }

      runtime_ref = flatpak_decomposed_new_from_decomposed (default_runtime,
                                                            FLATPAK_KINDS_RUNTIME,
                                                            custom_runtime_id,
                                                            custom_runtime_arch,
                                                            custom_runtime_version,
                                                            error);
      if (runtime_ref == NULL)
        return FALSE;
    }
  else
    runtime_ref = flatpak_decomposed_ref (default_runtime);

  runtime_deploy = flatpak_find_deploy_for_ref (flatpak_decomposed_get_ref (runtime_ref), custom_runtime_commit, NULL, cancellable, error);
  if (runtime_deploy == NULL)
    return FALSE;

  runtime_deploy_data = flatpak_deploy_get_deploy_data (runtime_deploy, FLATPAK_DEPLOY_VERSION_ANY, cancellable, error);
  if (runtime_deploy_data == NULL)
    return FALSE;

  runtime_metakey = flatpak_deploy_get_metadata (runtime_deploy);

  app_context = flatpak_app_compute_permissions (metakey, runtime_metakey, error);
  if (app_context == NULL)
    return FALSE;

  if (app_deploy != NULL)
    {
      overrides = flatpak_deploy_get_overrides (app_deploy);
      flatpak_context_merge (app_context, overrides);
    }

  if (sandboxed)
    {
      flatpak_context_make_sandboxed (app_context);
      flatpak_context_dump (app_context, "After making sandboxed");
    }

  if (extra_context)
    {
      flatpak_context_dump (extra_context, "Command-line overrides");
      flatpak_context_merge (app_context, extra_context);
    }

  flatpak_context_dump (app_context, "Final context");

  shares = flatpak_run_compute_allowed_shares (app_context);
  devices = flatpak_run_compute_allowed_devices (app_context);
  sockets = flatpak_run_compute_allowed_sockets (app_context);
  features = flatpak_run_compute_allowed_features (app_context);

  original_runtime_files = flatpak_deploy_get_files (runtime_deploy);
  original_runtime_fd = open (flatpak_file_get_path_cached (original_runtime_files),
                              O_PATH | O_CLOEXEC);
  if (original_runtime_fd < 0)
    return glnx_throw_errno_prefix (error, "Failed to open original runtime");

  if (custom_runtime_fd >= 0)
    {
      g_autofree char *path = NULL;

      path = flatpak_get_path_for_fd (custom_runtime_fd, &my_error);
      if (path == NULL)
        {
          return flatpak_fail_error (error, FLATPAK_ERROR,
                                     "Cannot convert custom usr fd to path: %s",
                                     my_error->message);
        }

      custom_runtime_files = g_file_new_for_path (path);

      original_runtime_target_path = "/run/parent/usr";
      runtime_fd = custom_runtime_fd;
      runtime_files = custom_runtime_files;
    }
  else if (custom_runtime_fd == FLATPAK_RUN_APP_DEPLOY_USR_ORIGINAL)
    {
      original_runtime_target_path = "/usr";
      runtime_fd = original_runtime_fd;
      runtime_files = original_runtime_files;
    }
  else
    {
      g_assert_not_reached ();
    }

  if (app_deploy != NULL)
    {
      g_autofree const char **previous_ids = NULL;
      gsize len = 0;
      gboolean do_migrate;

      original_app_files = flatpak_deploy_get_files (app_deploy);
      original_app_fd = open (flatpak_file_get_path_cached (original_app_files),
                              O_PATH | O_CLOEXEC | O_NOFOLLOW);
      if (original_app_fd < 0)
        return glnx_throw_errno_prefix (error, "Failed to open original runtime");

      real_app_id_dir = flatpak_get_data_dir (app_id);

      previous_app_id_dirs = g_ptr_array_new_with_free_func (g_object_unref);
      previous_ids = flatpak_deploy_data_get_previous_ids (app_deploy_data, &len);

      do_migrate = !g_file_query_exists (real_app_id_dir, cancellable);

      /* When migrating, find most recent old existing source and rename that to
       * the new name.
       *
       * We ignore other names than that. For more recent names that don't exist
       * we never ran them so nothing will even reference them. For older names
       * either they were not used, or they were used but then the more recent
       * name was used and a symlink to it was created.
       *
       * This means we may end up with a chain of symlinks: oldest -> old -> current.
       * This is unfortunate but not really a problem, but for robustness reasons we
       * don't want to mess with user files unnecessary. For example, the app dir could
       * actually be a symlink for other reasons. Imagine for instance that you want to put the
       * steam games somewhere else so you leave the app dir as a symlink to /mnt/steam.
       */
      for (i = len - 1; i >= 0; i--)
        {
          g_autoptr(GFile) previous_app_id_dir = NULL;
          g_autoptr(GFileInfo) previous_app_id_dir_info = NULL;
          g_autoptr(GError) local_error = NULL;

          previous_app_id_dir = flatpak_get_data_dir (previous_ids[i]);
          previous_app_id_dir_info = g_file_query_info (previous_app_id_dir,
                                                        G_FILE_ATTRIBUTE_STANDARD_IS_SYMLINK ","
                                                        G_FILE_ATTRIBUTE_STANDARD_SYMLINK_TARGET,
                                                        G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
                                                        cancellable,
                                                        &local_error);
          /* Warn about the migration failures, but don't make them fatal, then you can never run the app */
          if (previous_app_id_dir_info == NULL)
            {
              if  (!g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND) && do_migrate)
                {
                  g_warning (_("Failed to migrate from %s: %s"), flatpak_file_get_path_cached (previous_app_id_dir),
                             local_error->message);
                  do_migrate = FALSE; /* Don't migrate older things, they are likely symlinks to the thing that we failed on */
                }

              g_clear_error (&local_error);
              continue;
            }

          if (do_migrate)
            {
              do_migrate = FALSE; /* Don't migrate older things, they are likely symlinks to this dir */

              /* Don't migrate a symlink pointing to the new data dir. It was likely left over
               * from a previous migration and would end up pointing to itself */
              if (g_file_info_get_is_symlink (previous_app_id_dir_info) &&
                  g_strcmp0 (g_file_info_get_symlink_target (previous_app_id_dir_info), app_id) == 0)
                break;

              if (!flatpak_file_rename (previous_app_id_dir, real_app_id_dir, cancellable, &local_error))
                {
                  g_warning (_("Failed to migrate old app data directory %s to new name %s: %s"),
                             flatpak_file_get_path_cached (previous_app_id_dir), app_id,
                             local_error->message);
                }
              else
                {
                  /* Leave a symlink in place of the old data dir */
                  if (!g_file_make_symbolic_link (previous_app_id_dir, app_id, cancellable, &local_error))
                    {
                      g_warning (_("Failed to create symlink while migrating %s: %s"),
                                 flatpak_file_get_path_cached (previous_app_id_dir),
                                 local_error->message);
                    }
                }
            }

          /* Give app access to this old dir */
          g_ptr_array_add (previous_app_id_dirs, g_steal_pointer (&previous_app_id_dir));
        }

      if (!flatpak_ensure_data_dir (real_app_id_dir, cancellable, error))
        return FALSE;

      if (!sandboxed)
        app_id_dir = g_object_ref (real_app_id_dir);
    }

  if (custom_app_fd >= 0)
    {
      g_autofree char *path = NULL;

      path = flatpak_get_path_for_fd (custom_app_fd, error);
      if (path == NULL)
        return glnx_prefix_error (error, "Cannot convert custom app fd to path");

      custom_app_files = g_file_new_for_path (path);

      original_app_target_path = "/run/parent/app";
      app_fd = custom_app_fd;
      app_files = custom_app_files;
    }
  else if (custom_app_fd == FLATPAK_RUN_APP_DEPLOY_APP_ORIGINAL)
    {
      original_app_target_path = "/app";
      app_fd = original_app_fd;
      app_files = original_app_files;
    }
  else if (custom_app_fd == FLATPAK_RUN_APP_DEPLOY_APP_EMPTY)
    {
      original_app_target_path = "/run/parent/app";
      app_fd = -1;
      app_files = NULL;
    }
  else
    {
      g_assert_not_reached ();
    }

  /* We can't use the ld.so cache if we are using a custom /usr or /app,
   * because we don't have a unique ID for the /usr or /app, so we can't
   * do cache-invalidation correctly. The caller can either build their
   * own ld.so.cache before supplying us with the runtime, or supply
   * their own LD_LIBRARY_PATH. */
  if (runtime_fd == custom_runtime_fd || app_fd == custom_app_fd)
    {
      use_ld_so_cache = FALSE;
    }
  else
    {
      glnx_autofd int ldconfig_fd = -1;

      ldconfig_fd = glnx_chaseat (runtime_fd, "bin/ldconfig",
                                  GLNX_CHASE_RESOLVE_BENEATH |
                                  GLNX_CHASE_MUST_BE_REGULAR,
                                  &my_error);
      if (ldconfig_fd < 0)
        {
          use_ld_so_cache = FALSE;
          g_debug ("bin/ldconfig not found in runtime: %s", my_error->message);
        }

      g_clear_error (&my_error);
    }

  flatpak_run_apply_env_clear (bwrap, !!(flags & FLATPAK_RUN_FLAG_CLEAR_ENV));
  flatpak_run_apply_env_default (bwrap, use_ld_so_cache);
  flatpak_run_apply_env_vars (bwrap, app_context);
  flatpak_run_apply_env_prompt (bwrap, app_id);

  if (real_app_id_dir)
    {
      g_autoptr(GFile) sandbox_dir = g_file_get_child (real_app_id_dir, "sandbox");
      flatpak_bwrap_set_env (bwrap, "FLATPAK_SANDBOX_DIR", flatpak_file_get_path_cached (sandbox_dir), TRUE);
    }

  if (!flatpak_bwrap_add_args_data_fd_dup (bwrap,
                                           "--ro-bind-fd", runtime_fd, "/usr",
                                           error))
    return FALSE;

  {
    glnx_autofd int runtime_ref_fd = -1;

    runtime_ref_fd = glnx_chaseat (runtime_fd, ".ref",
                                   GLNX_CHASE_RESOLVE_BENEATH |
                                   GLNX_CHASE_MUST_BE_REGULAR,
                                   NULL);
    if (runtime_ref_fd >= 0)
      {
        flatpak_bwrap_add_args (bwrap,
                                "--lock-file", "/usr/.ref",
                                NULL);
      }
  }

  if (runtime_fd == custom_runtime_fd)
    {
      glnx_autofd int original_runtime_ref_fd = -1;
      glnx_autofd int original_runtime_etc_fd = -1;

      /* Put the real Flatpak runtime in /run/parent, so that the
       * replacement /usr can have symlinks into /run/parent in order
       * to use the Flatpak runtime's graphics drivers etc. if desired */
      if (!flatpak_bwrap_add_args_data_fd_dup (bwrap,
                                               "--ro-bind-fd",
                                               original_runtime_fd,
                                               "/run/parent/usr",
                                               error))
        return FALSE;

      original_runtime_ref_fd = glnx_chaseat (original_runtime_fd, ".ref",
                                              GLNX_CHASE_RESOLVE_BENEATH |
                                              GLNX_CHASE_MUST_BE_REGULAR,
                                              NULL);
      if (original_runtime_ref_fd >= 0)
        {
          flatpak_bwrap_add_args (bwrap,
                                  "--lock-file", "/run/parent/usr/.ref",
                                  NULL);
        }

      original_runtime_etc_fd = glnx_chaseat (original_runtime_fd, "etc",
                                              GLNX_CHASE_RESOLVE_BENEATH |
                                              GLNX_CHASE_MUST_BE_REGULAR,
                                              NULL);
      if (original_runtime_etc_fd >= 0)
        {
          flatpak_bwrap_add_args (bwrap,
                                  "--symlink", "usr/etc", "/run/parent/etc",
                                  NULL);
        }

      flatpak_run_setup_usr_links (bwrap, original_runtime_fd,
                                   "/run/parent");
    }

  if (app_fd >= 0)
    {
      glnx_autofd int app_ref_fd = -1;

      if (!flatpak_bwrap_add_args_data_fd_dup (bwrap,
                                               "--ro-bind-fd", app_fd, "/app",
                                               error))
        return FALSE;

      app_ref_fd = glnx_chaseat (app_fd, ".ref",
                                 GLNX_CHASE_RESOLVE_BENEATH |
                                 GLNX_CHASE_MUST_BE_REGULAR,
                                 NULL);
      if (app_ref_fd >= 0)
        {
          flatpak_bwrap_add_args (bwrap,
                                  "--lock-file", "/app/.ref",
                                  NULL);
        }
    }
  else
    {
      flatpak_bwrap_add_args (bwrap,
                              "--dir", "/app",
                              NULL);
    }

  if (original_app_fd >= 0 && original_app_fd != app_fd)
    {
      /* Put the real Flatpak app in /run/parent/app */
      flatpak_bwrap_add_args (bwrap,
                              "--ro-bind",
                              flatpak_file_get_path_cached (original_app_files),
                              "/run/parent/app",
                              "--lock-file", "/run/parent/app/.ref",
                              NULL);
    }

  if (metakey != NULL &&
      !flatpak_run_add_extension_args (bwrap, metakey, app_ref,
                                       use_ld_so_cache, original_app_target_path,
                                       &app_extensions, &app_ld_path,
                                       cancellable, error))
    return FALSE;

  if (!flatpak_run_add_extension_args (bwrap, runtime_metakey, runtime_ref,
                                       use_ld_so_cache, original_runtime_target_path,
                                       &runtime_extensions, &runtime_ld_path,
                                       cancellable, error))
    return FALSE;

  if (runtime_fd == original_runtime_fd)
    flatpak_run_extend_ld_path (bwrap, NULL, runtime_ld_path);

  if (app_fd == original_app_fd)
    flatpak_run_extend_ld_path (bwrap, app_ld_path, NULL);

  {
    glnx_autofd int ld_so_conf_fd = -1;
    struct glnx_statx stx;

    ld_so_conf_fd = glnx_chase_and_statxat (runtime_fd, "etc/ld.so.conf",
                                            GLNX_CHASE_RESOLVE_BENEATH |
                                            GLNX_CHASE_MUST_BE_REGULAR,
                                            GLNX_STATX_SIZE,
                                            &stx, NULL);
    if (ld_so_conf_fd < 0 ||
        !(stx.stx_mask & GLNX_STATX_SIZE) ||
        stx.stx_size != 0)
      generate_ld_so_conf = FALSE;
  }

  /* At this point we have the minimal argv set up, with just the app, runtime and extensions.
     We can reuse this to generate the ld.so.cache (if needed) */
  if (use_ld_so_cache)
    {
      checksum = calculate_ld_cache_checksum (app_deploy_data, runtime_deploy_data,
                                              app_extensions, runtime_extensions);
      ld_so_fd = regenerate_ld_cache (bwrap->argv,
                                      bwrap->fds,
                                      app_id_dir,
                                      checksum,
                                      runtime_fd,
                                      generate_ld_so_conf,
                                      cancellable, error);
      if (ld_so_fd == -1)
        return FALSE;
      flatpak_bwrap_add_fd (bwrap, ld_so_fd);
    }

  flags |= flatpak_context_features_to_run_flags (features);

  if (!flatpak_run_setup_base_argv (bwrap, runtime_fd, app_id_dir, app_arch, flags, error))
    return FALSE;

  if (generate_ld_so_conf)
    {
      if (!add_ld_so_conf (bwrap, error))
        return FALSE;
    }

  if (ld_so_fd != -1)
    {
      /* Don't add to fd_array, its already there */
      flatpak_bwrap_add_arg (bwrap, "--ro-bind-data");
      flatpak_bwrap_add_arg_printf (bwrap, "%d", ld_so_fd);
      flatpak_bwrap_add_arg (bwrap, "/etc/ld.so.cache");
    }

  if (!flatpak_run_add_app_info_args (bwrap,
                                      app_files, original_app_files, app_deploy_data, app_extensions,
                                      runtime_files, original_runtime_files, runtime_deploy_data, runtime_extensions,
                                      app_id, flatpak_decomposed_get_branch (app_ref),
                                      runtime_ref, app_id_dir,
                                      app_context, extra_context, sockets,
                                      sandboxed, FALSE, flags & FLATPAK_RUN_FLAG_DEVEL,
                                      &app_info_path,
                                      g_steal_fd (&instance_id_fd),
                                      &instance_id_host_dir, &instance_id_host_private_dir,
                                      &instance_id, error))
    return FALSE;

  if (!flatpak_run_save_environ (run_environ,
                                 instance_id_host_private_dir,
                                 cancellable,
                                 error))
    return FALSE;

  if (!sandboxed)
    {
      if (!flatpak_instance_ensure_per_app_dir (app_id,
                                                &per_app_dir_lock_fd,
                                                &per_app_dir_lock_path,
                                                error))
        return FALSE;

      if (!flatpak_instance_ensure_per_app_xdg_runtime_dir (app_id,
                                                            per_app_dir_lock_fd,
                                                            &shared_xdg_runtime_dir,
                                                            error))
        return FALSE;

      flatpak_bwrap_add_arg (bwrap, "--bind");
      flatpak_bwrap_add_arg (bwrap, shared_xdg_runtime_dir);
      flatpak_bwrap_add_arg_printf (bwrap, "/run/user/%d", getuid ());
    }

  if (!flatpak_run_add_dconf_args (bwrap, app_id, metakey, error))
    return FALSE;

  if (!sandboxed && !(flags & FLATPAK_RUN_FLAG_NO_DOCUMENTS_PORTAL))
    add_document_portal_args (bwrap, app_id, &doc_mount_path);

  if (!flatpak_run_add_environment_args (bwrap, app_info_path, flags,
                                         app_id, app_context,
                                         shares, devices, sockets, features,
                                         app_id_dir, previous_app_id_dirs,
                                         per_app_dir_lock_fd, instance_id,
                                         &exports, cancellable, error))
    return FALSE;

  if (per_app_dir_lock_path != NULL)
    {
      static const char lock[] = "/run/flatpak/per-app-dirs-ref";

      flatpak_bwrap_add_args (bwrap,
                              "--ro-bind", per_app_dir_lock_path, lock,
                              "--lock-file", lock,
                              NULL);
    }

  flatpak_run_add_socket_args_late (bwrap, shares);
  add_font_path_args (bwrap);
  add_icon_path_args (bwrap);

  flatpak_bwrap_add_args (bwrap,
                          /* Not in base, because we don't want this for flatpak build */
                          "--symlink", "/app/lib/debug/source", "/run/build",
                          "--symlink", "/usr/lib/debug/source", "/run/build-runtime",
                          NULL);

  for (i = 0; bind_fds && i < bind_fds->len; i++)
    {
      int fd = g_array_index (bind_fds, int, i);
      g_autofree char *path = NULL;

      /* We get the path the fd refers to, to determine to mount point
       * destination inside the sandbox */
      path = flatpak_get_path_for_fd (fd, error);
      if (!path)
        return FALSE;

      if (!flatpak_bwrap_add_args_data_fd_dup (bwrap,
                                               "--bind-fd", fd, path,
                                               error))
        return FALSE;
    }

  for (i = 0; ro_bind_fds && i < ro_bind_fds->len; i++)
    {
      int fd = g_array_index (ro_bind_fds, int, i);
      g_autofree char *path = NULL;

      /* We get the path the fd refers to, to determine to mount point
       * destination inside the sandbox */
      path = flatpak_get_path_for_fd (fd, error);
      if (!path)
        return FALSE;

      if (!flatpak_bwrap_add_args_data_fd_dup (bwrap,
                                               "--ro-bind-fd", fd, path,
                                               error))
        return FALSE;
    }

  if (cwd)
    flatpak_bwrap_add_args (bwrap, "--chdir", cwd, NULL);

  if (parent_expose_pids || parent_share_pids)
    {
      g_autofree char *userns_path = NULL;
      g_autofree char *pidns_path = NULL;
      g_autofree char *userns2_path = NULL;
      int userns_fd, userns2_fd, pidns_fd;

      if (parent_pid == 0)
        return flatpak_fail (error, "No parent pid specified");

      userns_path = g_strdup_printf ("/proc/%d/root/run/.userns", parent_pid);

      userns_fd = open_namespace_fd_if_needed (userns_path, "/proc/self/ns/user");
      if (userns_fd != -1)
        {
          flatpak_bwrap_add_args_data_fd (bwrap, "--userns", userns_fd, NULL);

          userns2_path = g_strdup_printf ("/proc/%d/ns/user", parent_pid);
          userns2_fd = open_namespace_fd_if_needed (userns2_path, userns_path);
          if (userns2_fd != -1)
            flatpak_bwrap_add_args_data_fd (bwrap, "--userns2", userns2_fd, NULL);
        }

      pidns_path = g_strdup_printf ("/proc/%d/ns/pid", parent_pid);
      pidns_fd = open (pidns_path, O_RDONLY|O_CLOEXEC);
      if (pidns_fd != -1)
        flatpak_bwrap_add_args_data_fd (bwrap, "--pidns", pidns_fd, NULL);
    }

  flatpak_bwrap_populate_runtime_dir (bwrap, shared_xdg_runtime_dir);

  if (custom_command)
    {
      command = custom_command;
    }
  else if (metakey)
    {
      default_command = g_key_file_get_string (metakey,
                                               FLATPAK_METADATA_GROUP_APPLICATION,
                                               FLATPAK_METADATA_KEY_COMMAND,
                                               &my_error);
      if (my_error)
        {
          g_propagate_error (error, g_steal_pointer (&my_error));
          return FALSE;
        }
      command = default_command;
    }

  flatpak_bwrap_sort_envp (bwrap);
  flatpak_bwrap_envp_to_args (bwrap);

  if (!flatpak_bwrap_bundle_args (bwrap, 1, -1, FALSE, error))
    return FALSE;

  flatpak_bwrap_add_args (bwrap, "--", command, NULL);

  if (!add_rest_args (bwrap, app_id,
                      exports, (flags & FLATPAK_RUN_FLAG_FILE_FORWARDING) != 0,
                      doc_mount_path,
                      args, n_args, error))
    return FALSE;

  /* Hold onto the lock until we execute bwrap */
  flatpak_bwrap_add_noinherit_fd (bwrap, g_steal_fd (&per_app_dir_lock_fd));

  flatpak_bwrap_finish (bwrap);

  commandline = flatpak_quote_argv ((const char **) bwrap->argv->pdata, -1);
  g_info ("Running '%s'", commandline);

  if ((flags & (FLATPAK_RUN_FLAG_BACKGROUND)) != 0 ||
      g_getenv ("FLATPAK_TEST_COVERAGE") != NULL)
    {
      GPid child_pid;
      char pid_str[64];
      g_autofree char *pid_path = NULL;
      GSpawnFlags spawn_flags;
      GSpawnChildSetupFunc child_setup;

      spawn_flags = G_SPAWN_SEARCH_PATH;
      if (flags & FLATPAK_RUN_FLAG_DO_NOT_REAP ||
          (flags & FLATPAK_RUN_FLAG_BACKGROUND) == 0)
        spawn_flags |= G_SPAWN_DO_NOT_REAP_CHILD;

      if (flags & FLATPAK_RUN_FLAG_BACKGROUND)
        child_setup = flatpak_bwrap_child_setup_cb;
      else
        child_setup = flatpak_bwrap_child_setup_inherit_fds_cb;

      /* Even in the case where we want them closed, we use
       * LEAVE_DESCRIPTORS_OPEN and close them in the child_setup
       * to work around a deadlock in GLib < 2.60 */
      spawn_flags |= G_SPAWN_LEAVE_DESCRIPTORS_OPEN;

      /* flatpak_bwrap_envp_to_args() moved the environment variables to
       * be set into --setenv instructions in argv, so the environment
       * in which the bwrap command runs must be empty. */
      g_assert (bwrap->envp != NULL);
      g_assert (bwrap->envp[0] == NULL);

      if (!g_spawn_async (NULL,
                          (char **) bwrap->argv->pdata,
                          bwrap->envp,
                          spawn_flags,
                          child_setup, bwrap->fds,
                          &child_pid,
                          error))
        return FALSE;

      g_snprintf (pid_str, sizeof (pid_str), "%d", child_pid);
      pid_path = g_build_filename (instance_id_host_dir, "pid", NULL);
      g_file_set_contents (pid_path, pid_str, -1, NULL);

      if ((flags & (FLATPAK_RUN_FLAG_BACKGROUND)) == 0)
        {
          int wait_status;

          if (waitpid (child_pid, &wait_status, 0) != child_pid)
            return glnx_throw_errno_prefix (error, "Failed to wait for child process");

          if (WIFEXITED (wait_status))
            exit (WEXITSTATUS (wait_status));

          if (WIFSIGNALED (wait_status))
            exit (128 + WTERMSIG (wait_status));

          return glnx_throw (error, "Unknown wait status from waitpid(): %d", wait_status);
        }
    }
  else
    {
      char pid_str[64];
      g_autofree char *pid_path = NULL;

      g_snprintf (pid_str, sizeof (pid_str), "%d", getpid ());
      pid_path = g_build_filename (instance_id_host_dir, "pid", NULL);
      g_file_set_contents (pid_path, pid_str, -1, NULL);

      /* Ensure we unset O_CLOEXEC for marked fds and rewind fds as needed.
       * Note that this does not close fds that are not already marked O_CLOEXEC, because
       * we do want to allow inheriting fds into flatpak run. */
      flatpak_bwrap_child_setup (bwrap->fds, FALSE);

      /* flatpak_bwrap_envp_to_args() moved the environment variables to
       * be set into --setenv instructions in argv, so the environment
       * in which the bwrap command runs must be empty. */
      g_assert (bwrap->envp != NULL);
      g_assert (bwrap->envp[0] == NULL);

      if (execvpe (flatpak_get_bwrap (), (char **) bwrap->argv->pdata, bwrap->envp) == -1)
        {
          g_set_error_literal (error, G_IO_ERROR, g_io_error_from_errno (errno),
                               _("Unable to start app"));
          return FALSE;
        }
      /* Not actually reached... */
    }

  if (instance_dir_out)
    *instance_dir_out = g_steal_pointer (&instance_id_host_dir);

  return TRUE;
}

===== ./common/flatpak-json.c =====
/* vi:set et sw=2 sts=2 cin cino=t0,f0,(0,{s,>2s,n-s,^-s,e-s:
 * Copyright (C) 2015 Red Hat, Inc
 *
 * This file 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 of the
 * License, or (at your option) any later version.
 *
 * This file 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 program.  If not, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Alexander Larsson <alexl@redhat.com>
 */

#include "config.h"
#include "string.h"

#include "flatpak-json-private.h"
#include "flatpak-utils-private.h"
#include "libglnx.h"

G_DEFINE_TYPE (FlatpakJson, flatpak_json, G_TYPE_OBJECT);

static void
flatpak_json_finalize (GObject *object)
{
  G_OBJECT_CLASS (flatpak_json_parent_class)->finalize (object);
}

static void
flatpak_json_class_init (FlatpakJsonClass *klass)
{
  GObjectClass *object_class = G_OBJECT_CLASS (klass);

  object_class->finalize = flatpak_json_finalize;
}

static void
flatpak_json_init (FlatpakJson *self)
{
}

static gboolean
demarshal (JsonNode            *parent_node,
           const char          *name,
           gpointer             dest,
           FlatpakJsonPropType  type,
           gpointer             type_data,
           gpointer             type_data2,
           FlatpakJsonPropFlags flags,
           GError             **error)
{
  JsonObject *parent_object;
  JsonNode *node;

  if (type != FLATPAK_JSON_PROP_TYPE_PARENT)
    {
      parent_object = json_node_get_object (parent_node);
      node = json_object_get_member (parent_object, name);

      if (node == NULL && (flags & FLATPAK_JSON_PROP_FLAGS_MANDATORY) != 0)
        {
          g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
                       "No value for mandatory property %s", name);
          return FALSE;
        }
    }
  else
    node = parent_node;

  if (node == NULL || JSON_NODE_TYPE (node) == JSON_NODE_NULL)
    return TRUE;

  switch (type)
    {
    case FLATPAK_JSON_PROP_TYPE_STRING:
      if (!JSON_NODE_HOLDS_VALUE (node) ||
          json_node_get_value_type (node) != G_TYPE_STRING)
        {
          g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
                       "Expecting string for property %s", name);
          return FALSE;
        }
      *(char **) dest = g_strdup (json_node_get_string (node));
      break;

    case FLATPAK_JSON_PROP_TYPE_INT64:
      if (!JSON_NODE_HOLDS_VALUE (node) ||
          json_node_get_value_type (node) != G_TYPE_INT64)
        {
          g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
                       "Expecting int64 for property %s", name);
          return FALSE;
        }
      *(gint64 *) dest = json_node_get_int (node);
      break;

    case FLATPAK_JSON_PROP_TYPE_BOOL:
      if (!JSON_NODE_HOLDS_VALUE (node) ||
          json_node_get_value_type (node) != G_TYPE_BOOLEAN)
        {
          g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
                       "Expecting bool for property %s", name);
          return FALSE;
        }
      *(gboolean *) dest = json_node_get_boolean (node);
      break;

    case FLATPAK_JSON_PROP_TYPE_STRV:
      if (!JSON_NODE_HOLDS_ARRAY (node))
        {
          g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
                       "Expecting array for property %s", name);
          return FALSE;
        }
      {
        JsonArray *array = json_node_get_array (node);
        guint i, array_len = json_array_get_length (array);
        g_autoptr(GPtrArray) str_array = g_ptr_array_sized_new (array_len + 1);

        for (i = 0; i < array_len; i++)
          {
            JsonNode *val = json_array_get_element (array, i);

            if (JSON_NODE_TYPE (val) != JSON_NODE_VALUE)
              continue;

            if (json_node_get_string (val) != NULL)
              g_ptr_array_add (str_array, (gpointer) g_strdup (json_node_get_string (val)));
          }

        g_ptr_array_add (str_array, NULL);
        *(char ***) dest = (char **) g_ptr_array_free (g_steal_pointer (&str_array), FALSE);
      }

      break;

    case FLATPAK_JSON_PROP_TYPE_PARENT:
    case FLATPAK_JSON_PROP_TYPE_STRUCT:
      if (!JSON_NODE_HOLDS_OBJECT (node))
        {
          g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
                       "Expecting object for property %s", name);
          return FALSE;
        }
      {
        FlatpakJsonProp *struct_props = type_data;
        int i;

        if ((struct_props->flags & FLATPAK_JSON_PROP_FLAGS_STRICT) != 0)
          {
            JsonObject *object = json_node_get_object (node);
            g_autoptr(GList) members = json_object_get_members (object);
            GList *l;

            /* Verify that all members are known properties if strict flag is set */
            for (l = members; l != NULL; l = l->next)
              {
                const char *member_name = l->data;
                for (i = 0; struct_props[i].name != NULL; i++)
                  {
                    if (strcmp (struct_props[i].name, member_name) == 0)
                      break;
                  }
                if (struct_props[i].name == NULL)
                  return flatpak_fail (error, "Unknown property named %s", member_name);
              }
          }

        for (i = 0; struct_props[i].name != NULL; i++)
          {
            if (!demarshal (node, struct_props[i].name,
                            G_STRUCT_MEMBER_P (dest, struct_props[i].offset),
                            struct_props[i].type, struct_props[i].type_data, struct_props[i].type_data2,
                            struct_props[i].flags, error))
              return FALSE;
          }
      }
      break;

    case FLATPAK_JSON_PROP_TYPE_STRUCTV:
      if (!JSON_NODE_HOLDS_ARRAY (node))
        {
          g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
                       "Expecting array for property %s", name);
          return FALSE;
        }
      {
        JsonArray *array = json_node_get_array (node);
        guint array_len = json_array_get_length (array);
        FlatpakJsonProp *struct_props = type_data;
        g_autoptr(GPtrArray) obj_array = g_ptr_array_sized_new (array_len + 1);
        int i, j;
        gboolean res = TRUE;

        for (j = 0; res && j < array_len; j++)
          {
            JsonNode *val = json_array_get_element (array, j);
            gpointer new_element;

            if (!JSON_NODE_HOLDS_OBJECT (val))
              {
                g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
                             "Expecting object element for property %s", name);
                res = FALSE;
                break;
              }

            new_element = g_malloc0 ((gsize) type_data2);
            g_ptr_array_add (obj_array, new_element);

            for (i = 0; struct_props[i].name != NULL; i++)
              {
                if (!demarshal (val, struct_props[i].name,
                                G_STRUCT_MEMBER_P (new_element, struct_props[i].offset),
                                struct_props[i].type, struct_props[i].type_data, struct_props[i].type_data2,
                                struct_props[i].flags, error))
                  {
                    res = FALSE;
                    break;
                  }
              }
          }

        /* NULL terminate */
        g_ptr_array_add (obj_array, NULL);

        /* We always set the array, even if it is partial, because we don't know how
           to free what we demarshalled so far */
        *(gpointer *) dest = (gpointer *) g_ptr_array_free (g_steal_pointer (&obj_array), FALSE);
        return res;
      }
      break;

    case FLATPAK_JSON_PROP_TYPE_STRMAP:
      if (!JSON_NODE_HOLDS_OBJECT (node))
        {
          g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
                       "Expecting object for property %s", name);
          return FALSE;
        }
      {
        g_autoptr(GHashTable) h = NULL;
        JsonObject *object = json_node_get_object (node);
        g_autoptr(GList) members = NULL;
        GList *l;

        h = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);

        members = json_object_get_members (object);
        for (l = members; l != NULL; l = l->next)
          {
            const char *member_name = l->data;
            JsonNode *val;
            const char *val_str;

            val = json_object_get_member (object, member_name);
            val_str = json_node_get_string (val);
            if (val_str == NULL)
              {
                g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
                             "Wrong type for string member %s", member_name);
                return FALSE;
              }

            g_hash_table_insert (h, g_strdup (member_name), g_strdup (val_str));
          }

        *(GHashTable **) dest = g_steal_pointer (&h);
      }
      break;

    case FLATPAK_JSON_PROP_TYPE_BOOLMAP:
      if (!JSON_NODE_HOLDS_OBJECT (node))
        {
          g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
                       "Expecting object for property %s", name);
          return FALSE;
        }
      {
        JsonObject *object = json_node_get_object (node);
        g_autoptr(GPtrArray) res = g_ptr_array_new_with_free_func (g_free);
        g_autoptr(GList) members = NULL;
        GList *l;

        members = json_object_get_members (object);
        for (l = members; l != NULL; l = l->next)
          {
            const char *member_name = l->data;

            g_ptr_array_add (res, g_strdup (member_name));
          }

        g_ptr_array_add (res, NULL);

        *(char ***) dest =  (char **) g_ptr_array_free (g_steal_pointer (&res), FALSE);
      }
      break;

    default:
      g_assert_not_reached ();
    }

  return TRUE;
}

FlatpakJson *
flatpak_json_from_node (JsonNode *node, GType type, GError **error)
{
  g_autoptr(FlatpakJson) json = NULL;
  FlatpakJsonProp *props = NULL;
  gpointer class;
  int i;

  /* We should handle these before we get here */
  g_assert (node != NULL);
  g_assert (JSON_NODE_TYPE (node) != JSON_NODE_NULL);

  if (JSON_NODE_TYPE (node) != JSON_NODE_OBJECT)
    {
      g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
                   "Expecting a JSON object, but the node is of type `%s'",
                   json_node_type_name (node));
      return NULL;
    }

  json = g_object_new (type, NULL);

  class = FLATPAK_JSON_GET_CLASS (json);
  while (FLATPAK_JSON_CLASS (class)->props != NULL)
    {
      props = FLATPAK_JSON_CLASS (class)->props;
      for (i = 0; props[i].name != NULL; i++)
        {
          if (!demarshal (node, props[i].name,
                          G_STRUCT_MEMBER_P (json, props[i].offset),
                          props[i].type, props[i].type_data, props[i].type_data2,
                          props[i].flags, error))
            return NULL;
        }
      class = g_type_class_peek_parent (class);
    }

  return g_steal_pointer (&json);
}

FlatpakJson *
flatpak_json_from_bytes (GBytes  *bytes,
                         GType    type,
                         GError **error)
{
  g_autoptr(JsonParser) parser = NULL;
  JsonNode *root = NULL;

  parser = json_parser_new ();
  if (!json_parser_load_from_data (parser,
                                   g_bytes_get_data (bytes, NULL),
                                   g_bytes_get_size (bytes),
                                   error))
    return NULL;

  root = json_parser_get_root (parser);

  return flatpak_json_from_node (root, type, error);
}

FlatpakJson *
flatpak_json_from_stream (GInputStream *stream,
                          GType         type,
                          GCancellable *cancellable,
                          GError      **error)
{
  g_autoptr(JsonParser) parser = NULL;
  JsonNode *root = NULL;

  parser = json_parser_new ();
  if (!json_parser_load_from_stream (parser,
                                     stream,
                                     cancellable,
                                     error))
    return NULL;

  root = json_parser_get_root (parser);

  return flatpak_json_from_node (root, type, error);
}

static JsonNode *
marshal (JsonObject          *parent,
         const char          *name,
         gpointer             src,
         FlatpakJsonPropType  type,
         gpointer             type_data,
         FlatpakJsonPropFlags flags)
{
  JsonNode *retval = NULL;

  switch (type)
    {
    case FLATPAK_JSON_PROP_TYPE_STRING:
      {
        const char *str = *(const char **) src;
        if (str != NULL)
          retval = json_node_init_string (json_node_alloc (), str);
        break;
      }

    case FLATPAK_JSON_PROP_TYPE_INT64:
      {
        retval = json_node_init_int (json_node_alloc (), *(gint64 *) src);
        break;
      }

    case FLATPAK_JSON_PROP_TYPE_BOOL:
      {
        gboolean val = *(gboolean *) src;
        if (val)
          retval = json_node_init_boolean (json_node_alloc (), val);
        break;
      }

    case FLATPAK_JSON_PROP_TYPE_STRV:
      {
        char **strv = *(char ***) src;
        int i;
        JsonArray *array;

        if (strv != NULL && strv[0] != NULL)
          {
            array = json_array_sized_new (g_strv_length (strv));
            for (i = 0; strv[i] != NULL; i++)
              {
                JsonNode *str = json_node_new (JSON_NODE_VALUE);

                json_node_set_string (str, strv[i]);
                json_array_add_element (array, str);
              }

            retval = json_node_init_array (json_node_alloc (), array);
            json_array_unref (array);
          }
        break;
      }

    case FLATPAK_JSON_PROP_TYPE_PARENT:
    case FLATPAK_JSON_PROP_TYPE_STRUCT:
      {
        FlatpakJsonProp *struct_props = type_data;
        JsonObject *obj;
        int i;
        gboolean empty = TRUE;

        if (type == FLATPAK_JSON_PROP_TYPE_PARENT)
          obj = parent;
        else
          obj = json_object_new ();

        for (i = 0; struct_props[i].name != NULL; i++)
          {
            JsonNode *val = marshal (obj, struct_props[i].name,
                                     G_STRUCT_MEMBER_P (src, struct_props[i].offset),
                                     struct_props[i].type, struct_props[i].type_data, struct_props[i].flags);

            if (val == NULL)
              continue;

            empty = FALSE;
            json_object_set_member (obj, struct_props[i].name, val);
          }

        if (type != FLATPAK_JSON_PROP_TYPE_PARENT)
          {
            if (!empty || (flags & FLATPAK_JSON_PROP_FLAGS_OPTIONAL) == 0)
              {
                retval = json_node_new (JSON_NODE_OBJECT);
                json_node_take_object (retval, obj);
              }
            else
              json_object_unref (obj);
          }
        break;
      }

    case FLATPAK_JSON_PROP_TYPE_STRUCTV:
      {
        FlatpakJsonProp *struct_props = type_data;
        gpointer *structv = *(gpointer **) src;
        int i, j;
        JsonArray *array;

        if (structv != NULL && structv[0] != NULL)
          {
            array = json_array_new ();
            for (j = 0; structv[j] != NULL; j++)
              {
                JsonObject *obj = json_object_new ();
                JsonNode *node;

                for (i = 0; struct_props[i].name != NULL; i++)
                  {
                    JsonNode *val = marshal (obj, struct_props[i].name,
                                             G_STRUCT_MEMBER_P (structv[j], struct_props[i].offset),
                                             struct_props[i].type, struct_props[i].type_data, struct_props[i].flags);

                    if (val == NULL)
                      continue;

                    json_object_set_member (obj, struct_props[i].name, val);
                  }

                node = json_node_new (JSON_NODE_OBJECT);
                json_node_take_object (node, obj);
                json_array_add_element (array, node);
              }

            retval = json_node_init_array (json_node_alloc (), array);
            json_array_unref (array);
          }

        break;
      }

    case FLATPAK_JSON_PROP_TYPE_STRMAP:
      {
        GHashTable *map = *(GHashTable **) src;

        if (map != NULL && g_hash_table_size (map) > 0)
          {
            GHashTableIter iter;
            gpointer _key, _value;
            JsonObject *object;

            object = json_object_new ();

            g_hash_table_iter_init (&iter, map);
            while (g_hash_table_iter_next (&iter, &_key, &_value))
              {
                const char *key = _key;
                const char *value = _value;
                if (value != NULL)
                  {
                    JsonNode *str = json_node_new (JSON_NODE_VALUE);

                    json_node_set_string (str, value);
                    json_object_set_member (object, key, str);
                  }
              }

            retval = json_node_init_object (json_node_alloc (), object);
            json_object_unref (object);
          }
        break;
      }

    case FLATPAK_JSON_PROP_TYPE_BOOLMAP:
      {
        char **map = *(char ***) src;

        if (map != NULL && map[0] != NULL)
          {
            JsonObject *object;
            int i;

            object = json_object_new ();

            for (i = 0; map[i] != NULL; i++)
              {
                const char *element = map[i];
                JsonObject *empty_o = json_object_new ();
                JsonNode *empty = json_node_init_object (json_node_alloc (), empty_o);
                json_object_unref (empty_o);

                json_object_set_member (object, element, empty);
              }

            retval = json_node_init_object (json_node_alloc (), object);
            json_object_unref (object);
          }
        break;
      }

    default:
      g_assert_not_reached ();
    }

  return retval;
}

static void
marshal_props_for_class (FlatpakJson      *self,
                         FlatpakJsonClass *class,
                         JsonObject       *obj)
{
  FlatpakJsonProp *props = NULL;
  int i;
  gpointer parent_class;

  parent_class = g_type_class_peek_parent (class);

  if (FLATPAK_JSON_CLASS (parent_class)->props != NULL)
    marshal_props_for_class (self,
                             FLATPAK_JSON_CLASS (parent_class),
                             obj);

  props = FLATPAK_JSON_CLASS (class)->props;
  for (i = 0; props[i].name != NULL; i++)
    {
      JsonNode *val = marshal (obj, props[i].name,
                               G_STRUCT_MEMBER_P (self, props[i].offset),
                               props[i].type, props[i].type_data, props[i].flags);

      if (val == NULL)
        continue;

      json_object_set_member (obj, props[i].name, val);
    }
}

JsonNode *
flatpak_json_to_node (FlatpakJson *self)
{
  JsonNode *retval;
  JsonObject *obj;
  gpointer class;

  if (self == NULL)
    return json_node_new (JSON_NODE_NULL);

  obj = json_object_new ();

  class = FLATPAK_JSON_GET_CLASS (self);
  marshal_props_for_class (self, FLATPAK_JSON_CLASS (class), obj);

  retval = json_node_new (JSON_NODE_OBJECT);
  json_node_take_object (retval, obj);

  return retval;
}

GBytes *
flatpak_json_to_bytes (FlatpakJson *self)
{
  g_autoptr(JsonNode) node = NULL;
  g_autoptr(JsonGenerator) generator = NULL;
  char *str;

  node = flatpak_json_to_node (FLATPAK_JSON (self));

  generator = json_generator_new ();
  json_generator_set_pretty (generator, TRUE);
  json_generator_set_root (generator, node);

  str = json_generator_to_data (generator, NULL);
  return g_bytes_new_take (str, strlen (str));
}

===== ./common/flatpak-portal-error.h =====
/* flatpak-portal-error.c
 *
 * Copyright (C) 2015 Red Hat, Inc
 *
 * This file 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 of the
 * License, or (at your option) any later version.
 *
 * This file 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 program.  If not, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Alexander Larsson <alexl@redhat.com>
 */

#ifndef FLATPAK_PORTAL_ERROR_H
#define FLATPAK_PORTAL_ERROR_H

#if !defined(__FLATPAK_H_INSIDE__) && !defined(FLATPAK_COMPILATION)
#error "Only <flatpak.h> can be included directly."
#endif

#include <glib.h>

G_BEGIN_DECLS

/**
 * FlatpakPortalError:
 * @FLATPAK_PORTAL_ERROR_FAILED: General portal failure
 * @FLATPAK_PORTAL_ERROR_INVALID_ARGUMENT: An argument was invalid
 * @FLATPAK_PORTAL_ERROR_NOT_FOUND: The object was not found
 * @FLATPAK_PORTAL_ERROR_EXISTS: The object already exists
 * @FLATPAK_PORTAL_ERROR_NOT_ALLOWED: The call was not allowed
 * @FLATPAK_PORTAL_ERROR_CANCELLED: The call was cancelled by the user
 * @FLATPAK_PORTAL_ERROR_WINDOW_DESTROYED: The window was destroyed by the user
 *
 * Error codes returned by portal calls.
 */
typedef enum {
  FLATPAK_PORTAL_ERROR_FAILED     = 0,
  FLATPAK_PORTAL_ERROR_INVALID_ARGUMENT,
  FLATPAK_PORTAL_ERROR_NOT_FOUND,
  FLATPAK_PORTAL_ERROR_EXISTS,
  FLATPAK_PORTAL_ERROR_NOT_ALLOWED,
  FLATPAK_PORTAL_ERROR_CANCELLED,
  FLATPAK_PORTAL_ERROR_WINDOW_DESTROYED,
} FlatpakPortalError;


/**
 * FLATPAK_PORTAL_ERROR:
 *
 * The error domain for #FlatpakPortalError errors.
 */
#define FLATPAK_PORTAL_ERROR flatpak_portal_error_quark ()

FLATPAK_EXTERN GQuark  flatpak_portal_error_quark (void);

G_END_DECLS

#endif /* FLATPAK_PORTAL_ERROR_H */

===== ./common/flatpak-progress-private.h =====
/*
 * Copyright © 2019 Endless Mobile, Inc
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Philip Chimento <philip@endlessm.com>
 */

#ifndef FLATPAK_PROGRESS_H
#define FLATPAK_PROGRESS_H

#include <glib-object.h>
#include <ostree.h>

#include "flatpak-installation.h"

#define FLATPAK_TYPE_PROGRESS flatpak_progress_get_type ()

G_DECLARE_FINAL_TYPE (FlatpakProgress, flatpak_progress, FLATPAK, PROGRESS, GObject);

#define FLATKPAK_MAIN_CONTEXT_INIT {NULL}
#define FLATPAK_DEFAULT_UPDATE_INTERVAL_MS 100

struct _FlatpakMainContext {
  GMainContext        *context;
  FlatpakProgress     *flatpak_progress;
  OstreeAsyncProgress *ostree_progress;
};
typedef struct _FlatpakMainContext FlatpakMainContext;

void flatpak_main_context_wait (FlatpakMainContext *self,
                                gpointer           *watch_location);
void flatpak_main_context_finish (FlatpakMainContext *self);

G_DEFINE_AUTO_CLEANUP_CLEAR_FUNC (FlatpakMainContext, flatpak_main_context_finish);

FlatpakProgress *flatpak_progress_new (FlatpakProgressCallback callback,
                                       gpointer                user_data);

void flatpak_progress_init_extra_data (FlatpakProgress *self,
                                       guint64          n_extra_data,
                                       guint64          total_download_size);
gboolean flatpak_progress_get_extra_data_initialized (FlatpakProgress *self);
void flatpak_progress_start_extra_data (FlatpakProgress *self);
void flatpak_progress_reset_extra_data (FlatpakProgress *self);
void flatpak_progress_update_extra_data (FlatpakProgress *self,
                                         guint64          downloaded_bytes);
void flatpak_progress_complete_extra_data_download (FlatpakProgress *self,
                                                    guint64          download_size);

void flatpak_progress_start_oci_pull (FlatpakProgress *self);
void flatpak_progress_update_oci_pull (FlatpakProgress *self,
                                       guint64          total_size,
                                       guint64          pulled_size,
                                       guint32          n_layers,
                                       guint32          pulled_layers);

guint32 flatpak_progress_get_update_interval (FlatpakProgress *self);
void flatpak_progress_set_update_interval (FlatpakProgress *self,
                                           guint32          interval);

guint64 flatpak_progress_get_bytes_transferred (FlatpakProgress *self);
guint64 flatpak_progress_get_transferred_extra_data_bytes (FlatpakProgress *self);
guint64 flatpak_progress_get_start_time (FlatpakProgress *self);
const char *flatpak_progress_get_status (FlatpakProgress *self);
int flatpak_progress_get_progress (FlatpakProgress *self);
gboolean flatpak_progress_get_estimating (FlatpakProgress *self);

gboolean flatpak_progress_is_done (FlatpakProgress *self);
void flatpak_progress_done (FlatpakProgress *self);

void flatpak_progress_init_main_context (FlatpakProgress *maybe_progress,
                                         FlatpakMainContext *context);

#endif  /* FLATPAK_PROGRESS_H */

===== ./common/flatpak-repo-utils-private.h =====
/*
 * Copyright © 2014 Red Hat, Inc
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Alexander Larsson <alexl@redhat.com>
 */

#pragma once

#include "libglnx.h"

#include <ostree.h>

#include "flatpak-ref-utils-private.h"
#include "flatpak-variant-private.h"

/**
 * FLATPAK_SUMMARY_INDEX_GVARIANT_FORMAT:
 *
 * dict
 *   s: subset name
 *  ->
 *   ay - checksum of subsummary
 *   aay - previous subsummary checksums
 *   a{sv} - per subset metadata
 * a{sv} - metadata

 */
#define FLATPAK_SUMMARY_INDEX_GVARIANT_STRING "(a{s(ayaaya{sv})}a{sv})"
#define FLATPAK_SUMMARY_INDEX_GVARIANT_FORMAT G_VARIANT_TYPE (FLATPAK_SUMMARY_INDEX_GVARIANT_STRING)

#define FLATPAK_REF_GROUP "Flatpak Ref"
#define FLATPAK_REF_VERSION_KEY "Version"
#define FLATPAK_REF_URL_KEY "Url"
#define FLATPAK_REF_RUNTIME_REPO_KEY "RuntimeRepo"
#define FLATPAK_REF_SUGGEST_REMOTE_NAME_KEY "SuggestRemoteName"
#define FLATPAK_REF_TITLE_KEY "Title"
#define FLATPAK_REF_GPGKEY_KEY "GPGKey"
#define FLATPAK_REF_IS_RUNTIME_KEY "IsRuntime"
#define FLATPAK_REF_NAME_KEY "Name"
#define FLATPAK_REF_BRANCH_KEY "Branch"
#define FLATPAK_REF_COLLECTION_ID_KEY "CollectionID"
#define FLATPAK_REF_DEPLOY_COLLECTION_ID_KEY "DeployCollectionID"
#define FLATPAK_REF_DEPLOY_SIDELOAD_COLLECTION_ID_KEY "DeploySideloadCollectionID"

#define FLATPAK_REPO_GROUP "Flatpak Repo"
#define FLATPAK_REPO_VERSION_KEY "Version"
#define FLATPAK_REPO_URL_KEY "Url"
#define FLATPAK_REPO_SUBSET_KEY "Subset"
#define FLATPAK_REPO_TITLE_KEY "Title"
#define FLATPAK_REPO_DEFAULT_BRANCH_KEY "DefaultBranch"
#define FLATPAK_REPO_GPGKEY_KEY "GPGKey"
#define FLATPAK_REPO_SIGNATURE_LOOKASIDE_KEY "SignatureLookaside"
#define FLATPAK_REPO_NODEPS_KEY "NoDeps"
#define FLATPAK_REPO_COMMENT_KEY "Comment"
#define FLATPAK_REPO_DESCRIPTION_KEY "Description"
#define FLATPAK_REPO_HOMEPAGE_KEY "Homepage"
#define FLATPAK_REPO_ICON_KEY "Icon"
#define FLATPAK_REPO_FILTER_KEY "Filter"
#define FLATPAK_REPO_AUTHENTICATOR_NAME_KEY "AuthenticatorName"
#define FLATPAK_REPO_AUTHENTICATOR_INSTALL_KEY "AuthenticatorInstall"

#define FLATPAK_REPO_COLLECTION_ID_KEY "CollectionID"
#define FLATPAK_REPO_DEPLOY_COLLECTION_ID_KEY "DeployCollectionID"
#define FLATPAK_REPO_DEPLOY_SIDELOAD_COLLECTION_ID_KEY "DeploySideloadCollectionID"

#define FLATPAK_SPARSE_CACHE_KEY_ENDOFLIFE "eol"
#define FLATPAK_SPARSE_CACHE_KEY_ENDOFLIFE_REBASE "eolr"
#define FLATPAK_SPARSE_CACHE_KEY_TOKEN_TYPE "tokt"
#define FLATPAK_SPARSE_CACHE_KEY_EXTRA_DATA_SIZE "eds"

#define FLATPAK_SUMMARY_HISTORY_LENGTH_DEFAULT 16

gboolean flatpak_repo_set_title (OstreeRepo *repo,
                                 const char *title,
                                 GError    **error);
gboolean flatpak_repo_set_comment (OstreeRepo *repo,
                                   const char *comment,
                                   GError    **error);
gboolean flatpak_repo_set_description (OstreeRepo *repo,
                                       const char *description,
                                       GError    **error);
gboolean flatpak_repo_set_icon (OstreeRepo *repo,
                                const char *icon,
                                GError    **error);
gboolean flatpak_repo_set_homepage (OstreeRepo *repo,
                                    const char *homepage,
                                    GError    **error);
gboolean flatpak_repo_set_redirect_url (OstreeRepo *repo,
                                        const char *redirect_url,
                                        GError    **error);
gboolean flatpak_repo_set_authenticator_name (OstreeRepo *repo,
                                              const char *authenticator_name,
                                              GError    **error);
gboolean flatpak_repo_set_authenticator_install (OstreeRepo *repo,
                                                 gboolean authenticator_install,
                                                 GError    **error);
gboolean flatpak_repo_set_authenticator_option (OstreeRepo *repo,
                                                const char *key,
                                                const char *value,
                                                GError    **error);
gboolean flatpak_repo_set_default_branch (OstreeRepo *repo,
                                          const char *branch,
                                          GError    **error);
gboolean flatpak_repo_set_collection_id (OstreeRepo *repo,
                                         const char *collection_id,
                                         GError    **error);
gboolean flatpak_repo_set_deploy_collection_id (OstreeRepo *repo,
                                                gboolean    deploy_collection_id,
                                                GError    **error);
gboolean flatpak_repo_set_deploy_sideload_collection_id (OstreeRepo *repo,
                                                         gboolean    deploy_collection_id,
                                                         GError    **error);
gboolean flatpak_repo_set_summary_history_length (OstreeRepo *repo,
                                                  guint       length,
                                                  GError    **error);
guint    flatpak_repo_get_summary_history_length (OstreeRepo *repo);
gboolean flatpak_repo_set_gpg_keys (OstreeRepo *repo,
                                    GBytes     *bytes,
                                    GError    **error);

gboolean flatpak_repo_collect_sizes (OstreeRepo   *repo,
                                     GFile        *root,
                                     guint64      *installed_size,
                                     guint64      *download_size,
                                     GCancellable *cancellable,
                                     GError      **error);
GVariant *flatpak_commit_get_extra_data_sources (GVariant *commitv,
                                                 GError  **error);
GVariant *flatpak_repo_get_extra_data_sources (OstreeRepo   *repo,
                                               const char   *rev,
                                               GCancellable *cancellable,
                                               GError      **error);
void flatpak_repo_parse_extra_data_sources (GVariant      *extra_data_sources,
                                            int            index,
                                            const char   **name,
                                            guint64       *download_size,
                                            guint64       *installed_size,
                                            const guchar **sha256,
                                            const char   **uri);
GVariant *flatpak_repo_load_summary (OstreeRepo *repo,
                                     GError    **error);
GVariant *flatpak_repo_load_summary_index (OstreeRepo *repo,
                                           GError    **error);
GVariant *flatpak_repo_load_digested_summary (OstreeRepo *repo,
                                              const char *digest,
                                              GError    **error);

GBytes *flatpak_summary_apply_diff (GBytes *old,
                                    GBytes *diff,
                                    GError **error);

typedef enum
{
  FLATPAK_REPO_UPDATE_FLAG_NONE = 0,
  FLATPAK_REPO_UPDATE_FLAG_DISABLE_INDEX = 1 << 0,
} FlatpakRepoUpdateFlags;

gboolean flatpak_repo_update (OstreeRepo            *repo,
                              FlatpakRepoUpdateFlags flags,
                              const char           **gpg_key_ids,
                              const char            *gpg_homedir,
                              GCancellable          *cancellable,
                              GError               **error);

GPtrArray *flatpak_summary_match_subrefs (GVariant   *summary,
                                          const char *collection_id,
                                          FlatpakDecomposed *ref);
gboolean flatpak_summary_lookup_ref (GVariant      *summary,
                                     const char    *collection_id,
                                     const char    *ref,
                                     char         **out_checksum,
                                     VarRefInfoRef *out_info);
gboolean flatpak_summary_find_ref_map (VarSummaryRef  summary,
                                       const char    *collection_id,
                                       VarRefMapRef  *refs_out);
gboolean flatpak_var_ref_map_lookup_ref (VarRefMapRef   ref_map,
                                         const char    *ref,
                                         VarRefInfoRef *out_info);

GKeyFile * flatpak_parse_repofile (const char   *remote_name,
                                   gboolean      from_ref,
                                   GKeyFile     *keyfile,
                                   GBytes      **gpg_data_out,
                                   GCancellable *cancellable,
                                   GError      **error);

gboolean flatpak_mtree_ensure_dir_metadata (OstreeRepo        *repo,
                                            OstreeMutableTree *mtree,
                                            GCancellable      *cancellable,
                                            GError           **error);
gboolean flatpak_mtree_create_symlink (OstreeRepo         *repo,
                                       OstreeMutableTree  *parent,
                                       const char         *name,
                                       const char         *target,
                                       GError            **error);
gboolean flatpak_mtree_add_file_from_bytes (OstreeRepo *repo,
                                            GBytes *bytes,
                                            OstreeMutableTree *parent,
                                            const char *filename,
                                            GCancellable *cancellable,
                                            GError      **error);
gboolean flatpak_mtree_create_dir (OstreeRepo         *repo,
                                   OstreeMutableTree  *parent,
                                   const char         *name,
                                   OstreeMutableTree **dir_out,
                                   GError            **error);

gboolean   flatpak_repo_generate_appstream (OstreeRepo   *repo,
                                            const char  **gpg_key_ids,
                                            const char   *gpg_homedir,
                                            guint64       timestamp,
                                            GCancellable *cancellable,
                                            GError      **error);

gboolean flatpak_repo_resolve_rev (OstreeRepo    *repo,
                                   const char    *collection_id, /* nullable */
                                   const char    *remote_name, /* nullable */
                                   const char    *ref_name,
                                   gboolean       allow_noent,
                                   char         **out_rev,
                                   GCancellable  *cancellable,
                                   GError       **error);

gboolean flatpak_pull_from_bundle (OstreeRepo   *repo,
                                   GFile        *file,
                                   const char   *remote,
                                   const char   *ref,
                                   gboolean      require_gpg_signature,
                                   GCancellable *cancellable,
                                   GError      **error);

GVariant *flatpak_bundle_load (GFile              *file,
                               char              **commit,
                               FlatpakDecomposed **ref,
                               char              **origin,
                               char              **runtime_repo,
                               char              **app_metadata,
                               guint64            *installed_size,
                               GBytes            **gpg_keys,
                               char              **collection_id,
                               GError            **error);

static inline void
flatpak_ostree_progress_finish (OstreeAsyncProgress *progress)
{
  if (progress != NULL)
    {
      ostree_async_progress_finish (progress);
      g_object_unref (progress);
    }
}

typedef OstreeAsyncProgress OstreeAsyncProgressFinish;
G_DEFINE_AUTOPTR_CLEANUP_FUNC (OstreeAsyncProgressFinish, flatpak_ostree_progress_finish);

typedef OstreeRepo FlatpakRepoTransaction;

static inline void
flatpak_repo_transaction_cleanup (void *p)
{
  OstreeRepo *repo = p;

  if (repo)
    {
      g_autoptr(GError) error = NULL;
      if (!ostree_repo_abort_transaction (repo, NULL, &error))
        g_warning ("Error aborting ostree transaction: %s", error->message);
      g_object_unref (repo);
    }
}

static inline FlatpakRepoTransaction *
flatpak_repo_transaction_start (OstreeRepo   *repo,
                                GCancellable *cancellable,
                                GError      **error)
{
  if (!ostree_repo_prepare_transaction (repo, NULL, cancellable, error))
    return NULL;
  return (FlatpakRepoTransaction *) g_object_ref (repo);
}
G_DEFINE_AUTOPTR_CLEANUP_FUNC (FlatpakRepoTransaction, flatpak_repo_transaction_cleanup)

===== ./common/flatpak-transaction-private.h =====
/*
 * Copyright © 2018 Red Hat, Inc
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Alexander Larsson <alexl@redhat.com>
 */

#ifndef __FLATPAK_TRANSACTION_PRIVATE_H__
#define __FLATPAK_TRANSACTION_PRIVATE_H__

#include "flatpak-transaction.h"
#include "flatpak-ref-utils-private.h"

FlatpakRemoteState *flatpak_transaction_ensure_remote_state (FlatpakTransaction             *self,
                                                             FlatpakTransactionOperationType kind,
                                                             const char                     *remote,
                                                             const char                     *opt_arch,
                                                             GError                        **error);

FlatpakDecomposed * flatpak_transaction_operation_get_decomposed (FlatpakTransactionOperation *self);

#include "flatpak-dir-private.h"

#endif /* __FLATPAK_TRANSACTION_PRIVATE_H__ */

===== ./common/flatpak-xml-utils-private.h =====
/*
 * Copyright © 2014 Red Hat, Inc
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 */

#pragma once

#include "libglnx.h"

typedef struct FlatpakXml FlatpakXml;

struct FlatpakXml
{
  gchar      *element_name; /* NULL == text */
  char      **attribute_names;
  char      **attribute_values;
  char       *text;
  FlatpakXml *parent;
  FlatpakXml *first_child;
  FlatpakXml *last_child;
  FlatpakXml *next_sibling;
};

void       flatpak_xml_add (FlatpakXml *parent,
                            FlatpakXml *node);
void       flatpak_xml_free (FlatpakXml *node);
FlatpakXml *flatpak_xml_parse (GInputStream * in,
                               gboolean compressed,
                               GCancellable *cancellable,
                               GError      **error);
FlatpakXml *flatpak_xml_unlink (FlatpakXml *node,
                                FlatpakXml *prev_sibling);
FlatpakXml *flatpak_xml_find (FlatpakXml  *node,
                              const char  *type,
                              FlatpakXml **prev_child_out);

G_DEFINE_AUTOPTR_CLEANUP_FUNC (FlatpakXml, flatpak_xml_free);

FlatpakXml *flatpak_appstream_xml_new (void);
gboolean   flatpak_appstream_xml_migrate (FlatpakXml *source,
                                          FlatpakXml *dest,
                                          const char *ref,
                                          const char *id,
                                          GKeyFile   *metadata);
gboolean flatpak_appstream_xml_root_to_data (FlatpakXml *appstream_root,
                                             GBytes    **uncompressed,
                                             GBytes    **compressed,
                                             GError    **error);
void flatpak_appstream_xml_filter (FlatpakXml *appstream,
                                   GRegex *allow_refs,
                                   GRegex *deny_refs);

===== ./common/flatpak-xml-utils.c =====
/* vi:set et sw=2 sts=2 cin cino=t0,f0,(0,{s,>2s,n-s,^-s,e-s:
 * Copyright © 1995-1998 Free Software Foundation, Inc.
 * Copyright © 2014-2019 Red Hat, Inc
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Alexander Larsson <alexl@redhat.com>
 */

#include "config.h"
#include "flatpak-xml-utils-private.h"

#include "flatpak-run-private.h"
#include "flatpak-utils-private.h"

typedef struct
{
  FlatpakXml *current;
} XmlData;

static FlatpakXml *
flatpak_xml_new (const gchar *element_name)
{
  FlatpakXml *node = g_new0 (FlatpakXml, 1);

  node->element_name = g_strdup (element_name);
  return node;
}

static FlatpakXml *
flatpak_xml_new_text (const gchar *text)
{
  FlatpakXml *node = g_new0 (FlatpakXml, 1);

  node->text = g_strdup (text);
  return node;
}

void
flatpak_xml_add (FlatpakXml *parent, FlatpakXml *node)
{
  node->parent = parent;

  if (parent->first_child == NULL)
    parent->first_child = node;
  else
    parent->last_child->next_sibling = node;
  parent->last_child = node;
}

static void
xml_start_element (GMarkupParseContext *context,
                   const gchar         *element_name,
                   const gchar        **attribute_names,
                   const gchar        **attribute_values,
                   gpointer             user_data,
                   GError             **error)
{
  XmlData *data = user_data;
  FlatpakXml *node;

  node = flatpak_xml_new (element_name);
  node->attribute_names = g_strdupv ((char **) attribute_names);
  node->attribute_values = g_strdupv ((char **) attribute_values);

  flatpak_xml_add (data->current, node);
  data->current = node;
}

static void
xml_end_element (GMarkupParseContext *context,
                 const gchar         *element_name,
                 gpointer             user_data,
                 GError             **error)
{
  XmlData *data = user_data;

  data->current = data->current->parent;
}

static void
xml_text (GMarkupParseContext *context,
          const gchar         *text,
          gsize                text_len,
          gpointer             user_data,
          GError             **error)
{
  XmlData *data = user_data;
  FlatpakXml *node;

  node = flatpak_xml_new (NULL);
  node->text = g_strndup (text, text_len);
  flatpak_xml_add (data->current, node);
}

static void
xml_passthrough (GMarkupParseContext *context,
                 const gchar         *passthrough_text,
                 gsize                text_len,
                 gpointer             user_data,
                 GError             **error)
{
}

static GMarkupParser xml_parser = {
  xml_start_element,
  xml_end_element,
  xml_text,
  xml_passthrough,
  NULL
};

void
flatpak_xml_free (FlatpakXml *node)
{
  FlatpakXml *child;

  if (node == NULL)
    return;

  child = node->first_child;
  while (child != NULL)
    {
      FlatpakXml *next = child->next_sibling;
      flatpak_xml_free (child);
      child = next;
    }

  g_free (node->element_name);
  g_free (node->text);
  g_strfreev (node->attribute_names);
  g_strfreev (node->attribute_values);
  g_free (node);
}


static void
flatpak_xml_to_string (FlatpakXml *node, GString *res)
{
  int i;
  FlatpakXml *child;

  if (node->parent == NULL)
    g_string_append (res, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");

  if (node->element_name)
    {
      if (node->parent != NULL)
        {
          g_string_append (res, "<");
          g_string_append (res, node->element_name);
          if (node->attribute_names)
            {
              for (i = 0; node->attribute_names[i] != NULL; i++)
                {
                  g_string_append_printf (res, " %s=\"%s\"",
                                          node->attribute_names[i],
                                          node->attribute_values[i]);
                }
            }
          if (node->first_child == NULL)
            g_string_append (res, "/>");
          else
            g_string_append (res, ">");
        }

      child = node->first_child;
      while (child != NULL)
        {
          flatpak_xml_to_string (child, res);
          child = child->next_sibling;
        }
      if (node->parent != NULL)
        {
          if (node->first_child != NULL)
            g_string_append_printf (res, "</%s>", node->element_name);
        }
    }
  else if (node->text)
    {
      g_autofree char *escaped = g_markup_escape_text (node->text, -1);
      g_string_append (res, escaped);
    }
}

FlatpakXml *
flatpak_xml_unlink (FlatpakXml *node,
                    FlatpakXml *prev_sibling)
{
  FlatpakXml *parent = node->parent;

  if (parent == NULL)
    return node;

  if (parent->first_child == node)
    parent->first_child = node->next_sibling;

  if (parent->last_child == node)
    parent->last_child = prev_sibling;

  if (prev_sibling)
    prev_sibling->next_sibling = node->next_sibling;

  node->parent = NULL;
  node->next_sibling = NULL;

  return node;
}

FlatpakXml *
flatpak_xml_find (FlatpakXml  *node,
                  const char  *type,
                  FlatpakXml **prev_child_out)
{
  FlatpakXml *child = NULL;
  FlatpakXml *prev_child = NULL;

  child = node->first_child;
  prev_child = NULL;
  while (child != NULL)
    {
      FlatpakXml *next = child->next_sibling;

      if (g_strcmp0 (child->element_name, type) == 0)
        {
          if (prev_child_out)
            *prev_child_out = prev_child;
          return child;
        }

      prev_child = child;
      child = next;
    }

  return NULL;
}


FlatpakXml *
flatpak_xml_parse (GInputStream *in,
                   gboolean      compressed,
                   GCancellable *cancellable,
                   GError      **error)
{
  g_autoptr(GInputStream) real_in = NULL;
  g_autoptr(FlatpakXml) xml_root = NULL;
  XmlData data = { 0 };
  char buffer[32 * 1024];
  gssize len;
  g_autoptr(GMarkupParseContext) ctx = NULL;

  if (compressed)
    {
      g_autoptr(GZlibDecompressor) decompressor = NULL;
      decompressor = g_zlib_decompressor_new (G_ZLIB_COMPRESSOR_FORMAT_GZIP);
      real_in = g_converter_input_stream_new (in, G_CONVERTER (decompressor));
    }
  else
    {
      real_in = g_object_ref (in);
    }

  xml_root = flatpak_xml_new ("root");
  data.current = xml_root;

  ctx = g_markup_parse_context_new (&xml_parser,
                                    G_MARKUP_PREFIX_ERROR_POSITION,
                                    &data,
                                    NULL);

  while ((len = g_input_stream_read (real_in, buffer, sizeof (buffer),
                                     cancellable, error)) > 0)
    {
      if (!g_markup_parse_context_parse (ctx, buffer, len, error))
        return NULL;
    }

  if (len < 0)
    return NULL;

  return g_steal_pointer (&xml_root);
}

FlatpakXml *
flatpak_appstream_xml_new (void)
{
  FlatpakXml *appstream_root = NULL;
  FlatpakXml *appstream_components;

  appstream_root = flatpak_xml_new ("root");
  appstream_components = flatpak_xml_new ("components");
  flatpak_xml_add (appstream_root, appstream_components);
  flatpak_xml_add (appstream_components, flatpak_xml_new_text ("\n  "));

  appstream_components->attribute_names = g_new0 (char *, 3);
  appstream_components->attribute_values = g_new0 (char *, 3);
  appstream_components->attribute_names[0] = g_strdup ("version");
  appstream_components->attribute_values[0] = g_strdup ("0.8");
  appstream_components->attribute_names[1] = g_strdup ("origin");
  appstream_components->attribute_values[1] = g_strdup ("flatpak");

  return appstream_root;
}

gboolean
flatpak_appstream_xml_root_to_data (FlatpakXml *appstream_root,
                                    GBytes    **uncompressed,
                                    GBytes    **compressed,
                                    GError    **error)
{
  g_autoptr(GString) xml = NULL;
  g_autoptr(GZlibCompressor) compressor = NULL;
  g_autoptr(GOutputStream) out2 = NULL;
  g_autoptr(GOutputStream) out = NULL;

  flatpak_xml_add (appstream_root->first_child, flatpak_xml_new_text ("\n"));

  xml = g_string_new ("");
  flatpak_xml_to_string (appstream_root, xml);

  if (compressed)
    {
      compressor = g_zlib_compressor_new (G_ZLIB_COMPRESSOR_FORMAT_GZIP, -1);
      out = g_memory_output_stream_new_resizable ();
      out2 = g_converter_output_stream_new (out, G_CONVERTER (compressor));
      if (!g_output_stream_write_all (out2, xml->str, xml->len,
                                      NULL, NULL, error))
        return FALSE;
      if (!g_output_stream_close (out2, NULL, error))
        return FALSE;
    }

  if (uncompressed)
    *uncompressed = g_string_free_to_bytes (g_steal_pointer (&xml));

  if (compressed)
    *compressed = g_memory_output_stream_steal_as_bytes (G_MEMORY_OUTPUT_STREAM (out));

  return TRUE;
}

void
flatpak_appstream_xml_filter (FlatpakXml *appstream,
                              GRegex *allow_refs,
                              GRegex *deny_refs)
{
  FlatpakXml *components;
  FlatpakXml *component;
  FlatpakXml *prev_component, *old;

  for (components = appstream->first_child;
       components != NULL;
       components = components->next_sibling)
    {
      if (g_strcmp0 (components->element_name, "components") != 0)
        continue;


      prev_component = NULL;
      component = components->first_child;
      while (component != NULL)
        {
          FlatpakXml *bundle;
          gboolean allow = FALSE;

          if (g_strcmp0 (component->element_name, "component") == 0)
            {
              bundle = flatpak_xml_find (component, "bundle", NULL);
              if (bundle && bundle->first_child && bundle->first_child->text)
                allow = flatpak_filters_allow_ref (allow_refs, deny_refs, bundle->first_child->text);
            }

          if (allow)
            {
              prev_component = component;
              component = component->next_sibling;
            }
          else
            {
              old = component;

              /* prev_component is same as before */
              component = component->next_sibling;

              flatpak_xml_unlink (old, prev_component);
              flatpak_xml_free (old);
            }
        }
    }
}

static gboolean
validate_component (FlatpakXml *component,
                    const char *ref,
                    const char *id,
                    char      **tags,
                    const char *runtime,
                    const char *sdk)
{
  FlatpakXml *bundle, *text, *prev, *id_node, *id_text_node, *metadata, *value;
  g_autofree char *id_text = NULL;
  int i;

  if (g_strcmp0 (component->element_name, "component") != 0)
    return FALSE;

  id_node = flatpak_xml_find (component, "id", NULL);
  if (id_node == NULL)
    return FALSE;

  id_text_node = flatpak_xml_find (id_node, NULL, NULL);
  if (id_text_node == NULL || id_text_node->text == NULL)
    return FALSE;

  id_text = g_strstrip (g_strdup (id_text_node->text));

  /* Drop .desktop file suffix (unless the actual app id ends with .desktop) */
  if (g_str_has_suffix (id_text, ".desktop") &&
      !g_str_has_suffix (id, ".desktop"))
    id_text[strlen (id_text) - strlen (".desktop")] = 0;

  if (!g_str_has_prefix (id_text, id))
    {
      g_warning ("Invalid id %s", id_text);
      return FALSE;
    }

  while ((bundle = flatpak_xml_find (component, "bundle", &prev)) != NULL)
    flatpak_xml_free (flatpak_xml_unlink (bundle, prev));

  bundle = flatpak_xml_new ("bundle");
  bundle->attribute_names = g_new0 (char *, 2 * 4);
  bundle->attribute_values = g_new0 (char *, 2 * 4);
  bundle->attribute_names[0] = g_strdup ("type");
  bundle->attribute_values[0] = g_strdup ("flatpak");

  i = 1;
  if (runtime && !g_str_has_prefix (runtime, "runtime/"))
    {
      bundle->attribute_names[i] = g_strdup ("runtime");
      bundle->attribute_values[i] = g_strdup (runtime);
      i++;
    }

  if (sdk)
    {
      bundle->attribute_names[i] = g_strdup ("sdk");
      bundle->attribute_values[i] = g_strdup (sdk);
      i++;
    }

  text = flatpak_xml_new (NULL);
  text->text = g_strdup (ref);
  flatpak_xml_add (bundle, text);

  flatpak_xml_add (component, flatpak_xml_new_text ("  "));
  flatpak_xml_add (component, bundle);
  flatpak_xml_add (component, flatpak_xml_new_text ("\n  "));

  if (tags != NULL && tags[0] != NULL)
    {
      metadata = flatpak_xml_find (component, "metadata", NULL);
      if (metadata == NULL)
        {
          metadata = flatpak_xml_new ("metadata");
          metadata->attribute_names = g_new0 (char *, 1);
          metadata->attribute_values = g_new0 (char *, 1);

          flatpak_xml_add (component, flatpak_xml_new_text ("  "));
          flatpak_xml_add (component, metadata);
          flatpak_xml_add (component, flatpak_xml_new_text ("\n  "));
        }

      value = flatpak_xml_new ("value");
      value->attribute_names = g_new0 (char *, 2);
      value->attribute_values = g_new0 (char *, 2);
      value->attribute_names[0] = g_strdup ("key");
      value->attribute_values[0] = g_strdup ("X-Flatpak-Tags");
      flatpak_xml_add (metadata, flatpak_xml_new_text ("\n       "));
      flatpak_xml_add (metadata, value);
      flatpak_xml_add (metadata, flatpak_xml_new_text ("\n    "));

      text = flatpak_xml_new (NULL);
      text->text = g_strjoinv (",", tags);
      flatpak_xml_add (value, text);
    }

  return TRUE;
}

gboolean
flatpak_appstream_xml_migrate (FlatpakXml *source,
                               FlatpakXml *dest,
                               const char *ref,
                               const char *id,
                               GKeyFile   *metadata)
{
  FlatpakXml *source_components;
  FlatpakXml *dest_components;
  FlatpakXml *component;
  FlatpakXml *prev_component;
  gboolean migrated = FALSE;
  g_auto(GStrv) tags = NULL;
  g_autofree const char *runtime = NULL;
  g_autofree const char *sdk = NULL;
  const char *group;

  if (source->first_child == NULL ||
      source->first_child->next_sibling != NULL ||
      g_strcmp0 (source->first_child->element_name, "components") != 0)
    return FALSE;

  if (g_str_has_prefix (ref, "app/"))
    group = FLATPAK_METADATA_GROUP_APPLICATION;
  else
    group = FLATPAK_METADATA_GROUP_RUNTIME;

  tags = g_key_file_get_string_list (metadata, group, FLATPAK_METADATA_KEY_TAGS,
                                     NULL, NULL);
  runtime = g_key_file_get_string (metadata, group,
                                   FLATPAK_METADATA_KEY_RUNTIME, NULL);
  sdk = g_key_file_get_string (metadata, group, FLATPAK_METADATA_KEY_SDK, NULL);

  source_components = source->first_child;
  dest_components = dest->first_child;

  component = source_components->first_child;
  prev_component = NULL;
  while (component != NULL)
    {
      FlatpakXml *next = component->next_sibling;

      if (validate_component (component, ref, id, tags, runtime, sdk))
        {
          flatpak_xml_add (dest_components,
                           flatpak_xml_unlink (component, prev_component));
          migrated = TRUE;
        }
      else
        {
          prev_component = component;
        }

      component = next;
    }

  return migrated;
}

===== ./common/flatpak-bundle-ref.h =====
/*
 * Copyright © 2015 Red Hat, Inc
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Alexander Larsson <alexl@redhat.com>
 */

#if !defined(__FLATPAK_H_INSIDE__) && !defined(FLATPAK_COMPILATION)
#error "Only <flatpak.h> can be included directly."
#endif

#ifndef __FLATPAK_BUNDLE_REF_H__
#define __FLATPAK_BUNDLE_REF_H__

typedef struct _FlatpakBundleRef FlatpakBundleRef;

#include <gio/gio.h>
#include <flatpak-ref.h>

G_BEGIN_DECLS

#define FLATPAK_TYPE_BUNDLE_REF flatpak_bundle_ref_get_type ()
#define FLATPAK_BUNDLE_REF(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), FLATPAK_TYPE_BUNDLE_REF, FlatpakBundleRef))
#define FLATPAK_IS_BUNDLE_REF(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), FLATPAK_TYPE_BUNDLE_REF))

FLATPAK_EXTERN GType flatpak_bundle_ref_get_type (void);

struct _FlatpakBundleRef
{
  FlatpakRef parent;
};

typedef struct
{
  FlatpakRefClass parent_class;
} FlatpakBundleRefClass;

FLATPAK_EXTERN FlatpakBundleRef *flatpak_bundle_ref_new (GFile   *file,
                                                         GError **error);
FLATPAK_EXTERN GFile           *flatpak_bundle_ref_get_file (FlatpakBundleRef *self);
FLATPAK_EXTERN GBytes          *flatpak_bundle_ref_get_metadata (FlatpakBundleRef *self);
FLATPAK_EXTERN GBytes          *flatpak_bundle_ref_get_appstream (FlatpakBundleRef *self);
FLATPAK_EXTERN GBytes          *flatpak_bundle_ref_get_icon (FlatpakBundleRef *self,
                                                             int               size);
FLATPAK_EXTERN char            *flatpak_bundle_ref_get_origin (FlatpakBundleRef *self);
FLATPAK_EXTERN guint64          flatpak_bundle_ref_get_installed_size (FlatpakBundleRef *self);
FLATPAK_EXTERN char            *flatpak_bundle_ref_get_runtime_repo_url (FlatpakBundleRef *self);


#ifdef G_DEFINE_AUTOPTR_CLEANUP_FUNC
G_DEFINE_AUTOPTR_CLEANUP_FUNC (FlatpakBundleRef, g_object_unref)
#endif

G_END_DECLS

#endif /* __FLATPAK_BUNDLE_REF_H__ */

===== ./common/flatpak-usb.c =====
/* vi:set et sw=2 sts=2 cin cino=t0,f0,(0,{s,>2s,n-s,^-s,e-s:
 * Copyright © 2024 GNOME Foundation, Inc.
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Georges Basile Stavracas Neto <georges.stavracas@gmail.com>
 *       Hubert Figuière <hub@figuiere.net>
 */

#include <glib.h>
#include <glib/gi18n-lib.h>
#include <gio/gio.h>
#include "libglnx.h"

#include "flatpak-usb-private.h"

void
flatpak_usb_rule_free (FlatpakUsbRule *usb_rule)
{
  g_clear_pointer (&usb_rule, g_free);
}

void
flatpak_usb_query_free (FlatpakUsbQuery *usb_query)
{
  if (!usb_query)
    return;

  g_clear_pointer (&usb_query->rules, g_ptr_array_unref);
  g_clear_pointer (&usb_query, g_free);
}

static gboolean
validate_hex_uint16 (const char *value,
                     size_t      expected_length,
                     uint16_t   *out_value)
{
  size_t len;
  char *end;
  long n;

  g_return_val_if_fail (value != NULL, FALSE);
  g_return_val_if_fail (expected_length > 0 && expected_length <= 4, FALSE);

  len = strlen (value);
  if (len != expected_length)
    return FALSE;

  n = strtol (value, &end, 16);

  if (end - value != len)
    return FALSE;

  if (n < 0 || n > UINT16_MAX)
    return FALSE;

  if (out_value)
    *out_value = n;

  return TRUE;
}

static gboolean
parse_all_usb_rule (FlatpakUsbRule  *dest,
                    GStrv            data,
                    GError         **error)
{
  if (g_strv_length (data) != 1)
    {
      g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE,
                   _("USB device query 'all' must not have data"));
      return FALSE;
    }

  dest->rule_type = FLATPAK_USB_RULE_TYPE_ALL;
  return TRUE;
}

static gboolean
parse_cls_usb_rule (FlatpakUsbRule  *dest,
                    GStrv            data,
                    GError         **error)
{
  const char *subclass;
  const char *class;

  if (g_strv_length (data) < 3)
    {
      g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE,
                   _("USB query rule 'cls' must be in the form CLASS:SUBCLASS or CLASS:*"));
      return FALSE;
    }

  class = data[1];
  subclass = data[2];

  if (!validate_hex_uint16 (class, 2, &dest->d.device_class.class))
    {
      g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE, _("Invalid USB class"));
      return FALSE;
    }

  if (g_strcmp0 (subclass, "*") == 0)
    {
      dest->d.device_class.type = FLATPAK_USB_RULE_CLASS_TYPE_CLASS_ONLY;
    }
  else if (validate_hex_uint16 (subclass, 2, &dest->d.device_class.subclass))
    {
      dest->d.device_class.type = FLATPAK_USB_RULE_CLASS_TYPE_CLASS_SUBCLASS;
    }
  else
    {
      g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE, _("Invalid USB subclass"));
      return FALSE;
    }

  dest->rule_type = FLATPAK_USB_RULE_TYPE_CLASS;
  return TRUE;
}

static gboolean
parse_dev_usb_rule (FlatpakUsbRule  *dest,
                    GStrv            data,
                    GError         **error)
{
  if (g_strv_length (data) != 2)
    {
      g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE,
                   _("USB query rule 'dev' must have a valid 4-digit hexadecimal product id"));
      return FALSE;
    }

  if (!validate_hex_uint16 (data[1], 4, &dest->d.product.id))
    {
      g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE,
                   _("USB query rule 'dev' must have a valid 4-digit hexadecimal product id"));
      return FALSE;
    }

  dest->rule_type = FLATPAK_USB_RULE_TYPE_DEVICE;
  return TRUE;
}

static gboolean
parse_vnd_usb_rule (FlatpakUsbRule  *dest,
                    GStrv            data,
                    GError         **error)
{
  if (g_strv_length (data) != 2)
    {
      g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE,
                   _("USB query rule 'vnd' must have a valid 4-digit hexadecimal vendor id"));
      return FALSE;
    }

  if (!validate_hex_uint16 (data[1], 4, &dest->d.product.id))
    {
      g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE,
                   _("USB query rule 'vnd' must have a valid 4-digit hexadecimal vendor id"));
      return FALSE;
    }

  dest->rule_type = FLATPAK_USB_RULE_TYPE_VENDOR;
  return TRUE;
}

static const struct {
  const char *name;
  gboolean (*parse) (FlatpakUsbRule  *dest,
                     GStrv            data,
                     GError         **error);
} rule_parsers[] = {
  { "all", parse_all_usb_rule },
  { "cls", parse_cls_usb_rule },
  { "dev", parse_dev_usb_rule },
  { "vnd", parse_vnd_usb_rule },
};

gboolean
flatpak_usb_parse_usb_rule (const char      *data,
			FlatpakUsbRule **out_usb_rule,
			GError         **error)
{
  g_autoptr(FlatpakUsbRule) usb_rule = NULL;
  g_auto(GStrv) split = NULL;
  gboolean parsed = FALSE;

  split = g_strsplit (data, ":", 0);

  if (!split || g_strv_length (split) > 3)
    {
      g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE,
                   _("USB device queries must be in the form TYPE:DATA"));
      return FALSE;
    }

  usb_rule = g_new0 (FlatpakUsbRule, 1);

  for (size_t i = 0; i < G_N_ELEMENTS (rule_parsers); i++)
    {
      if (g_strcmp0 (rule_parsers[i].name, split[0]))
	continue;

      if (!rule_parsers[i].parse (usb_rule, split, error))
	return FALSE;

      parsed = TRUE;
    }

  if (!parsed)
    {
      g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE,
                   _("Unknown USB query rule %s"), split[0]);
      return FALSE;
    }

  if (out_usb_rule)
    *out_usb_rule = g_steal_pointer (&usb_rule);

  return TRUE;
}

gboolean
flatpak_usb_parse_usb (const char       *data,
		   FlatpakUsbQuery **out_usb_query,
		   GError          **error)
{
  g_autoptr(FlatpakUsbQuery) usb_query = NULL;
  g_autoptr(GHashTable) rule_types = NULL;
  g_auto(GStrv) split = NULL;

  split = g_strsplit (data, "+", 0);

  if (!*split)
    {
      g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE, _("Empty USB query"));
      return FALSE;
    }

  usb_query = flatpak_usb_query_new ();

  for (size_t i = 0; split[i] != NULL; i++)
    {
      g_autoptr(FlatpakUsbRule) usb_rule = NULL;
      const char *rule = split[i];

      if (!flatpak_usb_parse_usb_rule (rule, &usb_rule, error))
        return FALSE;

      g_ptr_array_add (usb_query->rules, g_steal_pointer (&usb_rule));
    }

  g_assert (usb_query->rules->len > 0);

  rule_types = g_hash_table_new (g_direct_hash, g_direct_equal);
  for (size_t i = 0; i < usb_query->rules->len; i++)
    {
      FlatpakUsbRule *usb_rule = g_ptr_array_index (usb_query->rules, i);
      if (!g_hash_table_add (rule_types, GINT_TO_POINTER (usb_rule->rule_type)))
        {
          g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE,
                       _("Multiple USB query rules of the same type is not supported"));
          return FALSE;
        }
    }

  if (g_hash_table_contains (rule_types, GINT_TO_POINTER (FLATPAK_USB_RULE_TYPE_ALL)) &&
      g_hash_table_size (rule_types) > 1)
    {
      g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE,
                   _("'all' must not contain extra query rules"));
      return FALSE;
    }

  if (g_hash_table_contains (rule_types, GINT_TO_POINTER (FLATPAK_USB_RULE_TYPE_DEVICE)) &&
      !g_hash_table_contains (rule_types, GINT_TO_POINTER (FLATPAK_USB_RULE_TYPE_VENDOR)))
    {
      g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE,
                   _("USB queries with 'dev' must also specify vendors"));
      return FALSE;
    }

  if (out_usb_query)
    *out_usb_query = g_steal_pointer (&usb_query);

  return TRUE;
}

gboolean
flatpak_usb_parse_usb_list (const char     *buffer,
                            GHashTable     *enumerable,
                            GHashTable     *hidden,
                            GError        **error)
{
  char *aux = NULL;
  g_autoptr(FlatpakUsbQuery) usb_query = NULL;
  g_autoptr(GInputStream) stream = NULL;
  g_autoptr(GDataInputStream) buffered = NULL;
  g_autoptr(GError) local_error = NULL;

  stream = g_memory_input_stream_new_from_data (buffer, -1, NULL);
  if (!stream)
    return FALSE;

  buffered = g_data_input_stream_new (G_INPUT_STREAM (stream));

  while ((aux = g_data_input_stream_read_line (buffered, NULL, NULL, &local_error)))
    {
      g_autofree char *line = g_steal_pointer (&aux);
      g_auto(GStrv) split = NULL;
      gboolean blocking = FALSE;

      if (line[0] == '#')
        continue;

      split = g_strsplit (line, ";", 0);
      if (!split || !*split)
        continue;

      for (size_t i = 0; split[i] != NULL; i++)
        {
          const char *item = split[i];

          blocking = item[0] == '!';
          if (blocking)
            item++;

          if (flatpak_usb_parse_usb (item, &usb_query, NULL))
            {
              GString *string = g_string_new (NULL);
              flatpak_usb_query_print (usb_query, string);

              if (blocking)
	        {
                  g_hash_table_insert (hidden,
                                       g_string_free (string, FALSE),
                                       g_steal_pointer (&usb_query));
                }
              else
                {
                  g_hash_table_insert (enumerable,
                                       g_string_free (string, FALSE),
                                       g_steal_pointer (&usb_query));
                }
            }
        }
    }

  g_input_stream_close (G_INPUT_STREAM (buffered), NULL, error);
  g_input_stream_close (G_INPUT_STREAM (stream), NULL, error);

  if (local_error)
    {
      g_propagate_error (error, g_steal_pointer (&local_error));
      return FALSE;
    }

  return TRUE;
}

void
flatpak_usb_rule_print (FlatpakUsbRule *usb_rule,
                        GString        *string)
{
  g_return_if_fail (usb_rule != NULL);
  g_assert (string != NULL);

  switch (usb_rule->rule_type)
    {
    case FLATPAK_USB_RULE_TYPE_ALL:
      g_string_append (string, "all");
      break;

    case FLATPAK_USB_RULE_TYPE_CLASS:
      g_string_append (string, "cls:");
      if (usb_rule->d.device_class.type == FLATPAK_USB_RULE_CLASS_TYPE_CLASS_ONLY)
        g_string_append_printf (string, "%02x:*", usb_rule->d.device_class.class);
      else if (usb_rule->d.device_class.type == FLATPAK_USB_RULE_CLASS_TYPE_CLASS_SUBCLASS)
        g_string_append_printf (string, "%02x:%02x", usb_rule->d.device_class.class, usb_rule->d.device_class.subclass);
      else
        g_assert_not_reached ();
      break;

    case FLATPAK_USB_RULE_TYPE_DEVICE:
      g_string_append_printf (string, "dev:%04x", usb_rule->d.product.id);
      break;

    case FLATPAK_USB_RULE_TYPE_VENDOR:
      g_string_append_printf (string, "vnd:%04x", usb_rule->d.vendor.id);
      break;

    default:
      g_assert_not_reached ();
    }
}

FlatpakUsbQuery *
flatpak_usb_query_new (void)
{
  g_autoptr(FlatpakUsbQuery) usb_query = NULL;

  usb_query = g_new0 (FlatpakUsbQuery, 1);
  usb_query->rules = g_ptr_array_new_with_free_func ((GDestroyNotify) flatpak_usb_rule_free);

  return g_steal_pointer (&usb_query);
}

FlatpakUsbQuery *
flatpak_usb_query_copy (const FlatpakUsbQuery *query)
{
  FlatpakUsbQuery *copy = flatpak_usb_query_new ();

  for (size_t i = 0; i < query->rules->len; i++)
    {
      FlatpakUsbRule *usb_rule = g_ptr_array_index (query->rules, i);
      g_ptr_array_add (copy->rules, g_memdup2 (usb_rule, sizeof (FlatpakUsbRule)));
    }
  return copy;
}

void
flatpak_usb_query_print (const FlatpakUsbQuery *usb_query,
                         GString               *string)
{
  g_assert (usb_query != NULL && usb_query->rules != NULL);
  g_assert (string != NULL);

  for (size_t i = 0; i < usb_query->rules->len; i++)
    {
      FlatpakUsbRule *usb_rule = g_ptr_array_index (usb_query->rules, i);

      if (i > 0)
        g_string_append_c (string, '+');

      flatpak_usb_rule_print (usb_rule, string);
    }
}

===== ./common/flatpak-syscalls-private.h =====
/*
 * Copyright 2021 Collabora Ltd.
 * SPDX-License-Identifier: LGPL-2.1-or-later
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 */

#pragma once

#include <sys/syscall.h>

#if defined(_MIPS_SIM)
# if _MIPS_SIM == _MIPS_SIM_ABI32
#   define FLATPAK_MISSING_SYSCALL_BASE 4000
# elif _MIPS_SIM == _MIPS_SIM_ABI64
#   define FLATPAK_MISSING_SYSCALL_BASE 5000
# elif _MIPS_SIM == _MIPS_SIM_NABI32
#   define FLATPAK_MISSING_SYSCALL_BASE 6000
# else
#   error "Unknown MIPS ABI"
# endif
#endif

#if defined(__ia64__)
# define FLATPAK_MISSING_SYSCALL_BASE 1024
#endif

#if defined(__alpha__)
# define FLATPAK_MISSING_SYSCALL_BASE 110
#endif

#if defined(__x86_64__) && defined(__ILP32__)
# define FLATPAK_MISSING_SYSCALL_BASE 0x40000000
#endif

/*
 * FLATPAK_MISSING_SYSCALL_BASE:
 *
 * Number to add to the syscall numbers of recently-added syscalls
 * to get the appropriate syscall for the current ABI.
 */
#ifndef FLATPAK_MISSING_SYSCALL_BASE
# define FLATPAK_MISSING_SYSCALL_BASE 0
#endif

#ifndef __NR_open_tree
# define __NR_open_tree (FLATPAK_MISSING_SYSCALL_BASE + 428)
#endif
#ifndef __SNR_open_tree
# define __SNR_open_tree __NR_open_tree
#endif

#ifndef __NR_move_mount
# define __NR_move_mount (FLATPAK_MISSING_SYSCALL_BASE + 429)
#endif
#ifndef __SNR_move_mount
# define __SNR_move_mount __NR_move_mount
#endif

#ifndef __NR_fsopen
# define __NR_fsopen (FLATPAK_MISSING_SYSCALL_BASE + 430)
#endif
#ifndef __SNR_fsopen
# define __SNR_fsopen __NR_fsopen
#endif

#ifndef __NR_fsconfig
# define __NR_fsconfig (FLATPAK_MISSING_SYSCALL_BASE + 431)
#endif
#ifndef __SNR_fsconfig
# define __SNR_fsconfig __NR_fsconfig
#endif

#ifndef __NR_fsmount
# define __NR_fsmount (FLATPAK_MISSING_SYSCALL_BASE + 432)
#endif
#ifndef __SNR_fsmount
# define __SNR_fsmount __NR_fsmount
#endif

#ifndef __NR_fspick
# define __NR_fspick (FLATPAK_MISSING_SYSCALL_BASE + 433)
#endif
#ifndef __SNR_fspick
# define __SNR_fspick __NR_fspick
#endif

#ifndef __NR_pidfd_open
# define __NR_pidfd_open (FLATPAK_MISSING_SYSCALL_BASE + 434)
#endif
#ifndef __SNR_pidfd_open
# define __SNR_pidfd_open __NR_pidfd_open
#endif

#ifndef __NR_clone3
# define __NR_clone3 (FLATPAK_MISSING_SYSCALL_BASE + 435)
#endif
#ifndef __SNR_clone3
# define __SNR_clone3 __NR_clone3
#endif

#ifndef __NR_close_range
# define __NR_close_range (FLATPAK_MISSING_SYSCALL_BASE + 436)
#endif
#ifndef __SNR_close_range
# define __SNR_close_range __NR_close_range
#endif

#ifndef __NR_openat2
# define __NR_openat2 (FLATPAK_MISSING_SYSCALL_BASE + 437)
#endif
#ifndef __SNR_openat2
# define __SNR_openat2 __NR_openat2
#endif

#ifndef __NR_pidfd_getfd
# define __NR_pidfd_getfd (FLATPAK_MISSING_SYSCALL_BASE + 438)
#endif
#ifndef __SNR_pidfd_getfd
# define __SNR_pidfd_getfd __NR_pidfd_getfd
#endif

#ifndef __NR_faccessat2
# define __NR_faccessat2 (FLATPAK_MISSING_SYSCALL_BASE + 439)
#endif
#ifndef __SNR_faccessat2
# define __SNR_faccessat2 __NR_faccessat2
#endif

#ifndef __NR_process_madvise
# define __NR_process_madvise (FLATPAK_MISSING_SYSCALL_BASE + 440)
#endif
#ifndef __SNR_process_madvise
# define __SNR_process_madvise __NR_process_madvise
#endif

#ifndef __NR_epoll_pwait2
# define __NR_epoll_pwait2 (FLATPAK_MISSING_SYSCALL_BASE + 441)
#endif
#ifndef __SNR_epoll_pwait2
# define __SNR_epoll_pwait2 __NR_epoll_pwait2
#endif

#ifndef __NR_mount_setattr
# define __NR_mount_setattr (FLATPAK_MISSING_SYSCALL_BASE + 442)
#endif
#ifndef __SNR_mount_setattr
# define __SNR_mount_setattr __NR_mount_setattr
#endif

#ifndef __NR_quotactl_fd
# define __NR_quotactl_fd (FLATPAK_MISSING_SYSCALL_BASE + 443)
#endif
#ifndef __SNR_quotactl_fd
# define __SNR_quotactl_fd __NR_quotactl_fd
#endif

#ifndef __NR_landlock_create_ruleset
# define __NR_landlock_create_ruleset (FLATPAK_MISSING_SYSCALL_BASE + 444)
#endif
#ifndef __SNR_landlock_create_ruleset
# define __SNR_landlock_create_ruleset __NR_landlock_create_ruleset
#endif

#ifndef __NR_landlock_add_rule
# define __NR_landlock_add_rule (FLATPAK_MISSING_SYSCALL_BASE + 445)
#endif
#ifndef __SNR_landlock_add_rule
# define __SNR_landlock_add_rule __NR_landlock_add_rule
#endif

#ifndef __NR_landlock_restrict_self
# define __NR_landlock_restrict_self (FLATPAK_MISSING_SYSCALL_BASE + 446)
#endif
#ifndef __SNR_landlock_restrict_self
# define __SNR_landlock_restrict_self __NR_landlock_restrict_self
#endif

#ifndef __NR_memfd_secret
# define __NR_memfd_secret (FLATPAK_MISSING_SYSCALL_BASE + 447)
#endif
#ifndef __SNR_memfd_secret
# define __SNR_memfd_secret __NR_memfd_secret
#endif

/* Last updated: Linux 5.14, syscall numbers < 448 */

===== ./doc/flatpak-ps.xml =====
<?xml version='1.0'?> <!--*-nxml-*-->
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
    "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">

<refentry id="flatpak-ps">

    <refentryinfo>
        <title>flatpak ps</title>
        <productname>flatpak</productname>

        <authorgroup>
            <author>
                <contrib>Developer</contrib>
                <firstname>Matthias</firstname>
                <surname>Clasen</surname>
                <email>mclasen@redhat.com</email>
            </author>
        </authorgroup>
    </refentryinfo>

    <refmeta>
        <refentrytitle>flatpak ps</refentrytitle>
        <manvolnum>1</manvolnum>
    </refmeta>

    <refnamediv>
        <refname>flatpak-ps</refname>
        <refpurpose>Enumerate running instances</refpurpose>
    </refnamediv>

    <refsynopsisdiv>
            <cmdsynopsis>
                <command>flatpak ps</command>
                <arg choice="opt" rep="repeat">OPTION</arg>
            </cmdsynopsis>
    </refsynopsisdiv>

    <refsect1>
        <title>Description</title>

        <para>
          Lists useful information about running Flatpak instances.
        </para>
        <para>
          To see full details of a running instance, you can open the file
          <filename>/run/user/$UID/.flatpak/$INSTANCE/info</filename>, where <replaceable>$INSTANCE</replaceable> is the instance
          ID reported by flatpak ps.
        </para>

    </refsect1>

    <refsect1>
        <title>Options</title>

        <para>The following options are understood:</para>

        <variablelist>
            <varlistentry>
                <term><option>-h</option></term>
                <term><option>--help</option></term>

                <listitem><para>
                    Show help options and exit.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>-v</option></term>
                <term><option>--verbose</option></term>

                <listitem><para>
                    Print debug information during command processing.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--ostree-verbose</option></term>

                <listitem><para>
                    Print OSTree debug information during command processing.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--columns=FIELD,…</option></term>

                <listitem><para>
                    Specify what information to show about each instance. You can
                    list multiple fields, or use this option multiple times.
                </para><para>
                    Append :s[tart], :m[iddle], :e[nd] or :f[ull] to column
                    names to change ellipsization.
                </para></listitem>
            </varlistentry>

        </variablelist>
    </refsect1>

    <refsect1>
        <title>Fields</title>

        <para>The following fields are understood by the <option>--columns</option> option:</para>

        <variablelist>
            <varlistentry>
                <term>instance</term>

                <listitem><para>
                    Show the instance ID
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term>application</term>

                <listitem><para>
                    Show the application ID
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term>arch</term>

                <listitem><para>
                    Show the architecture
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term>branch</term>

                <listitem><para>
                    Show the application branch
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term>commit</term>

                <listitem><para>
                    Show the application commit
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term>runtime</term>

                <listitem><para>
                    Show the runtime ID
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term>runtime-branch</term>

                <listitem><para>
                    Show the runtime branch
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term>runtime-commit</term>

                <listitem><para>
                    Show the runtime commit
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term>pid</term>

                <listitem><para>
                    Show the PID of the wrapper process
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term>child-pid</term>

                <listitem><para>
                    Show the PID of the sandbox process
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term>active</term>

                <listitem><para>
                    Show whether the app is active (i.e. has an active window)
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term>background</term>

                <listitem><para>
                    Show whether the app is in the background (with no open windows)
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term>all</term>

                <listitem><para>
                    Show all columns
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term>help</term>

                <listitem><para>
                    Show the list of available columns
                </para></listitem>
            </varlistentry>
        </variablelist>

        <para>
          Note that field names can be abbreviated to a unique prefix.
        </para>

    </refsect1>

    <refsect1>
        <title>Examples</title>

        <para>
            <command>$ flatpak ps --columns=application,pid,runtime,runtime-branch</command>
        </para>

    </refsect1>

    <refsect1>
        <title>See also</title>

        <para>
            <citerefentry><refentrytitle>flatpak</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
            <citerefentry><refentrytitle>flatpak-run</refentrytitle><manvolnum>1</manvolnum></citerefentry>
        </para>

    </refsect1>

</refentry>

===== ./doc/flatpak-remote.xml =====
<?xml version='1.0'?> <!--*-nxml-*-->
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
    "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">

<refentry id="flatpak-remote">

    <refentryinfo>
        <title>flatpak remote</title>
        <productname>flatpak</productname>

        <authorgroup>
            <author>
                <contrib>Developer</contrib>
                <firstname>Alexander</firstname>
                <surname>Larsson</surname>
                <email>alexl@redhat.com</email>
            </author>
        </authorgroup>
    </refentryinfo>

    <refmeta>
        <refentrytitle>flatpak remote</refentrytitle>
        <manvolnum>5</manvolnum>
    </refmeta>

    <refnamediv>
        <refname>flatpak-remote</refname>
        <refpurpose>Configuration for a remote</refpurpose>
    </refnamediv>

    <refsect1>
        <title>Description</title>

        <para>
            Flatpak stores information about configured remotes for an installation location in
            <filename>$installation/repo/config</filename>. For example, the remotes for the
            default system-wide installation are in
            <filename>$prefix/var/lib/flatpak/repo/config</filename>, and the remotes for the
            per-user installation are in <filename>$HOME/.local/share/flatpak/repo/config</filename>.
       </para>

       <para>
            Normally, it is not necessary to edit remote config files directly, the
            <command>flatpak remote-modify</command> command should be used to change properties of remotes.
       </para>

       <para>
            System-wide remotes can be statically preconfigured by dropping
            <citerefentry><refentrytitle>flatpakrepo</refentrytitle><manvolnum>5</manvolnum></citerefentry>
            files into <filename>/usr/share/flatpak/remotes.d/</filename> and
            <filename>/etc/flatpak/remotes.d/</filename>. Ifa file with
            the same name exists in both, the file under
            <filename>/etc</filename> will take precedence.
       </para>

    </refsect1>

    <refsect1>
        <title>File format</title>

        <para>
            The remote config file format is using the same .ini file format that is used for systemd
            unit files or application .desktop files.
        </para>

        <refsect2>
            <title>[remote …]</title>
            <para>
                All the configuration for the the remote with name NAME is contained in the
                [remote "NAME"] group.
            </para>
            <para>
                The following keys are recognized by OSTree, among others:
            </para>
            <variablelist>
                <varlistentry>
                    <term><option>url</option> (string)</term>
                    <listitem><para>
                      The url for the remote. An URL of the form oci+https:// or oci+http://
                      is a Flatpak extension that indicates that the remote is not an ostree
                      repository, but is rather an URL to an index of OCI images that are stored
                      within a container image registry.
                    </para>
                    <para>
                      For OCI remotes, client and CA certificates are read from
                      <filename>/etc/containers/certs.d</filename> and
                      <filename>~/.config/containers/certs.d</filename> as documented in
                      <citerefentry><refentrytitle>containers-certs.d</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
                    </para></listitem>
                </varlistentry>
                <varlistentry>
                    <term><option>gpg-verify</option> (boolean)</term>
                    <listitem><para>Whether to use GPG verification for content from this remote.</para></listitem>
                </varlistentry>
                <varlistentry>
                    <term><option>gpg-verify-summary</option> (boolean)</term>
                    <listitem>
                        <para>Whether to use GPG verification for the summary of this remote.</para>
                        <para>This is ignored if <option>collection-id</option> is set, as refs are verified in commit metadata in that case. Enabling <option>gpg-verify-summary</option> would break peer to peer distribution of refs.</para>
                    </listitem>
                </varlistentry>
                <varlistentry>
                    <term><option>collection-id</option> (string)</term>
                    <listitem><para>The globally unique identifier for the upstream collection repository, to allow mirrors to be grouped.</para></listitem>
                </varlistentry>
            </variablelist>
            <para>
                All flatpak-specific keys have a xa. prefix:
            </para>
            <variablelist>
                <varlistentry>
                    <term><option>xa.disable</option> (boolean)</term>
                    <listitem><para>Whether the remote is disabled. Defaults to false.</para></listitem>
                </varlistentry>
                <varlistentry>
                    <term><option>xa.prio</option> (integer)</term>
                    <listitem><para>The priority for the remote. This is used when listing remotes, and when
                    searching them for the runtime needed by an app. The remote providing the app is
                    searched for its runtime before others with equal priority. Defaults to 1.</para></listitem>
                </varlistentry>
                <varlistentry>
                    <term><option>xa.noenumerate</option> (boolean)</term>
                    <listitem><para>Whether this remote should be ignored when presenting available apps/runtimes,
                    or when searching for a runtime dependency. Defaults to false.</para></listitem>
                </varlistentry>
                <varlistentry>
                    <term><option>xa.nodeps</option> (boolean)</term>
                    <listitem><para>Whether this remote should be excluded when searching for dependencies. Defaults to false.</para></listitem>
                </varlistentry>
                <varlistentry>
                    <term><option>xa.title</option> (string)</term>
                    <listitem><para>An optional title to use when presenting this remote in a UI.</para></listitem>
                </varlistentry>
                <varlistentry>
                    <term><option>xa.title-is-set</option> (boolean)</term>
                    <listitem><para>This key is set to true if <option>xa.title</option> has been explicitly set.</para></listitem>
                </varlistentry>
                <varlistentry>
                    <term><option>xa.comment</option> (string)</term>
                    <listitem><para>An optional single-line comment to use when presenting this remote in a UI.</para></listitem>
                </varlistentry>
                <varlistentry>
                    <term><option>xa.comment-is-set</option> (boolean)</term>
                    <listitem><para>This key is set to true if <option>xa.comment</option> has been explicitly set.</para></listitem>
                </varlistentry>
                <varlistentry>
                    <term><option>xa.description</option> (string)</term>
                    <listitem><para>An optional full-paragraph of text to use when presenting this remote in a UI.</para></listitem>
                </varlistentry>
                <varlistentry>
                    <term><option>xa.description-is-set</option> (boolean)</term>
                    <listitem><para>This key is set to true if <option>xa.description</option> has been explicitly set.</para></listitem>
                </varlistentry>
                <varlistentry>
                    <term><option>xa.homepage</option> (string)</term>
                    <listitem><para>An optional URL that points to a website for this repository to use when presenting this remote in a UI.</para></listitem>
                </varlistentry>
                <varlistentry>
                    <term><option>xa.homepage-is-set</option> (boolean)</term>
                    <listitem><para>This key is set to true if <option>xa.homepage</option> has been explicitly set.</para></listitem>
                </varlistentry>
                <varlistentry>
                    <term><option>xa.icon</option> (string)</term>
                    <listitem><para>An optional URL that points to an icon for this repository to use when presenting this remote in a UI.</para></listitem>
                </varlistentry>
                <varlistentry>
                    <term><option>xa.icon-is-set</option> (boolean)</term>
                    <listitem><para>This key is set to true if <option>xa.icon</option> has been explicitly set.</para></listitem>
                </varlistentry>
                <varlistentry>
                    <term><option>xa.default-branch</option> (string)</term>
                    <listitem><para>The default branch to use when installing from this remote.</para></listitem>
                </varlistentry>
                <varlistentry>
                    <term><option>xa.default-branch-is-set</option> (boolean)</term>
                    <listitem><para>This key is set to true if <option>xa.default-branch</option> has been explicitly set.</para></listitem>
                </varlistentry>
                <varlistentry>
                    <term><option>xa.main-ref</option> (string)</term>
                    <listitem><para>The main reference served by this remote. This is used for origin remotes of applications installed via a flatpakref file.</para></listitem>
                </varlistentry>
                <varlistentry>
                    <term><option>xa.signature-lookaside</option> (string)</term>
                    <listitem><para>URL to load signatures from (OCI remotes only),
                    using the <ulink url="https://github.com/containers/image/blob/main/docs/signature-protocols.md">
                    containers/image separate storage mechanism.</ulink>
                    </para></listitem>
                </varlistentry>
            </variablelist>
        </refsect2>
    </refsect1>

    <refsect1>
        <title>Examples</title>

<programlisting>
[remote "gnome-nightly-apps"]
gpg-verify=true
gpg-verify-summary=true
url=https://sdk.gnome.org/nightly/repo-apps/
xa.title=GNOME Applications
</programlisting>

<programlisting>
[remote "flathub"]
gpg-verify=true
gpg-verify-summary=false
collection-id=org.flathub.Stable
url=https://dl.flathub.org/repo/
xa.title=Flathub
</programlisting>

    </refsect1>

    <refsect1>
        <title>See also</title>

        <para>
            <citerefentry><refentrytitle>flatpak-remote-modify</refentrytitle><manvolnum>1</manvolnum></citerefentry>
        </para>

    </refsect1>

</refentry>

===== ./doc/flatpak-uninstall.xml =====
<?xml version='1.0'?> <!--*-nxml-*-->
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
    "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">

<refentry id="flatpak-uninstall">

    <refentryinfo>
        <title>flatpak uninstall</title>
        <productname>flatpak</productname>

        <authorgroup>
            <author>
                <contrib>Developer</contrib>
                <firstname>Alexander</firstname>
                <surname>Larsson</surname>
                <email>alexl@redhat.com</email>
            </author>
        </authorgroup>
    </refentryinfo>

    <refmeta>
        <refentrytitle>flatpak uninstall</refentrytitle>
        <manvolnum>1</manvolnum>
    </refmeta>

    <refnamediv>
        <refname>flatpak-uninstall</refname>
        <refpurpose>Uninstall an application or runtime</refpurpose>
    </refnamediv>

    <refsynopsisdiv>
            <cmdsynopsis>
                <command>flatpak uninstall</command>
                <arg choice="opt" rep="repeat">OPTION</arg>
                <arg choice="opt" rep="repeat">REF</arg>
            </cmdsynopsis>
    </refsynopsisdiv>

    <refsect1>
        <title>Description</title>

        <para>
            Uninstalls an application or runtime. <arg choice="plain">REF</arg> is a reference to the
            application or runtime to uninstall.
        </para>
        <para>
            Each <arg choice="plain">REF</arg> argument is a full or partial identifier in the
            flatpak ref format, which looks like "(app|runtime)/ID/ARCH/BRANCH". All elements
            except ID are optional and can be left out, including the slashes,
            so most of the time you need only specify ID. Any part left out will be matched
            against what is installed, and if there are multiple matches you will be prompted
            to choose between them. You will also be prompted if <arg choice="plain">REF</arg>
            doesn't match any installed ref exactly but is similar (e.g. "gedit" is similar to
            "org.gnome.gedit"), but this fuzzy matching behavior is disabled if
            <arg choice="plain">REF</arg> contains any slashes or periods.
        </para>
        <para>
            By default this looks for both installed apps and runtimes with the given
            <arg choice="plain">REF</arg>, but you can limit this by using the <option>--app</option>
            or <option>--runtime</option> option, or by supplying the initial element in the <arg choice="plain">REF</arg>.
        </para>
        <para>
            Normally, this command removes the ref for this application/runtime from the
            local OSTree repository and purges any objects that are no longer
            needed to free up disk space. If the same application is later
            reinstalled, the objects will be pulled from the remote repository
            again. The <option>--keep-ref</option> option can be used to prevent this.
        </para>
        <para>
            When <option>--delete-data</option> is specified while removing an app, its
            data directory in <filename>~/.var/app</filename> and any permissions it might
            have are removed. When <option>--delete-data</option> is used without a
            <arg choice="plain">REF</arg>, all 'unowned' app data is removed.
        </para>
        <para>
            Unless overridden with the <option>--system</option>, <option>--user</option>, or <option>--installation</option>
            options, this command searches both the system-wide installation
            and the per-user one for <arg choice="plain">REF</arg> and errors
            out if it exists in more than one.
        </para>

    </refsect1>

    <refsect1>
        <title>Options</title>

        <para>The following options are understood:</para>

        <variablelist>
            <varlistentry>
                <term><option>-h</option></term>
                <term><option>--help</option></term>

                <listitem><para>
                    Show help options and exit.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--keep-ref</option></term>

                <listitem><para>
                    Keep the ref for the application and the objects belonging to it
                    in the local repository.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>-u</option></term>
                <term><option>--user</option></term>

                <listitem><para>
                    Uninstalls from a per-user installation.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--system</option></term>

                <listitem><para>
                    Uninstalls from the default system-wide installation.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--installation=NAME</option></term>

                <listitem><para>
                    Uninstalls from a system-wide installation specified by
                    <arg choice="plain">NAME</arg> among those defined in
                    <filename>/etc/flatpak/installations.d/</filename>.  Using
                    <option>--installation=default</option> is
                    equivalent to using <option>--system</option>.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--arch=ARCH</option></term>

                <listitem><para>
                    The architecture to uninstall, instead of the architecture of
                    the host system. See <command>flatpak --supported-arches</command>
                    for architectures supported by the host.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--all</option></term>
                <listitem><para>
                    Remove all refs on the system.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--unused</option></term>
                <listitem><para>
                    Remove unused refs on the system.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>-y</option></term>
                <term><option>--assumeyes</option></term>
                <listitem><para>
                    Automatically answer yes to all questions. This is useful for automation.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--noninteractive</option></term>
                <listitem><para>
                    Produce minimal output and avoid most questions. This is suitable for use in
                    non-interactive situations, e.g. in a build script.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--app</option></term>

                <listitem><para>
                    Only look for an app with the given name.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--runtime</option></term>

                <listitem><para>
                    Only look for a runtime with the given name.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--no-related</option></term>

                <listitem><para>
                    Don't uninstall related extensions, such as the locale data.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--force-remove</option></term>
                <listitem><para>
                    Remove files even if they're in use by a running application.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--delete-data</option></term>
                <listitem><para>
                    Remove app data in <filename>~/.var/app</filename> and in
                    the permission store.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>-v</option></term>
                <term><option>--verbose</option></term>

                <listitem><para>
                    Print debug information during command processing.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--ostree-verbose</option></term>

                <listitem><para>
                    Print OSTree debug information during command processing.
                </para></listitem>
            </varlistentry>
        </variablelist>
    </refsect1>

    <refsect1>
        <title>Examples</title>

        <para>
            <command>$ flatpak --user uninstall org.gnome.gedit</command>
        </para>

    </refsect1>

</refentry>

===== ./doc/flatpak-summaries.txt =====
Since version 1.9.1 flatpak uses custom format for repo summaries, in
order to keep the sizes of summary files down, both for transfer and
on-disk storage. The core format is still an OSTree summary file, but
there are some differences both in how it is used and what it
contains.

Flatpak still generates the old summary file for backwards compatibility. However
the summary-arches option in the [flatpak] group of the repo config can limit
which arches has refs put into the compatibility summary.

In addition flatpak generates a set of new summaries for named subsets
of the refs in the repo, as well as a summary index that refers to
these.  By default there are one subset for each architecture (each
architecture subset also includes refs of compat arches, such as i386
for x86-64). In addition, any commit that has a `xa.subsets` key (of
type `as`) will generate extra summaries named `$subset-$arch` in the
index in addition to the normal ones named `$arch`.

The summary index is a GVariant of type `(a{s(ayaaya{sv})}a{sv})`.
The first is an array of information for each sub-summary containing:
the subsummary name, the sha256 checksum and an array of checksums for
previous versions of the subsummary and an extensible metadata dict.
The second part is a toplevel extensible metadata dict, which is used
similarly to the toplevel dict in the summary. In fact, it contains
many of the the same global keys that previously were in the summary
dict (and which no longer are in the sub-summary dicts), such as
repo title, icon, url updates, etc.

The index is stored in the file `summary.idx` and in addition there is
a GPG signature of this in the `summary.idx.sig` file. The
subsummaries are stored in the `summaries` subdirectory and are named
`$digest.gz". These contain gzip-compressed ostree summary files (with
the sha256 checksum being of the *uncompressed* data).

Flatpak stores up to `[flatpak].summary-history-length` (default 16)
old versions of the sub-summaries and generates deltas between these
and the current version, named `$from-$to.delta" which are very simple
binary diffs that clients can use to efficiently update from older
versions of the summaries.

The sub-summary files don't contain any delta information, instead
relying on the delta-index support in OSTree 2020.8. They also don't
contain any timestamps in the per-ref dict, as these are quite large
and not currently used by flatpak. The format of the flatpak metadata
caching in the summary is also different. Instead of using separate
`xa.cache` and `xa.sparse-cache` the same information is now stored
in the regular per-ref metadata dict in the summary.

On the client side flatpak keeps a cache of the current summary index
(named `$remote.idx` and `$remote.idx.sig`), as well as one subsummary
per remote and arch (named $remote-$arch-$digest.sub`). Only the
subsummary with the most recent mtime is kept.

===== ./doc/flatpak-build-update-repo.xml =====
<?xml version='1.0'?> <!--*-nxml-*-->
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
    "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">

<refentry id="flatpak-build-update-repo">

    <refentryinfo>
        <title>flatpak build-update-repo</title>
        <productname>flatpak</productname>

        <authorgroup>
            <author>
                <contrib>Developer</contrib>
                <firstname>Alexander</firstname>
                <surname>Larsson</surname>
                <email>alexl@redhat.com</email>
            </author>
        </authorgroup>
    </refentryinfo>

    <refmeta>
        <refentrytitle>flatpak build-update-repo</refentrytitle>
        <manvolnum>1</manvolnum>
    </refmeta>

    <refnamediv>
        <refname>flatpak-build-update-repo</refname>
        <refpurpose>Create a repository from a build directory</refpurpose>
    </refnamediv>

    <refsynopsisdiv>
            <cmdsynopsis>
                <command>flatpak build-update-repo</command>
                <arg choice="opt" rep="repeat">OPTION</arg>
                <arg choice="plain">LOCATION</arg>
            </cmdsynopsis>
    </refsynopsisdiv>

    <refsect1>
        <title>Description</title>

        <para>
            Updates repository metadata for the repository at
            <arg choice="plain">LOCATION</arg>. This command generates
            an OSTree summary file that lists the contents of the repository.
            The summary is used by flatpak remote-ls and other commands
            to display the contents of remote repositories.
        </para>
        <para>
            After this command, <arg choice="plain">LOCATION</arg> can be
            used as the repository location for flatpak remote-add, either by
            exporting it over http, or directly with a file: url.
        </para>
    </refsect1>

    <refsect1>
        <title>Options</title>

        <para>The following options are understood:</para>

        <variablelist>
            <varlistentry>
                <term><option>-h</option></term>
                <term><option>--help</option></term>

                <listitem><para>
                    Show help options and exit.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--redirect-url=URL</option></term>

                <listitem><para>
                    Redirect this repo to a new URL.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--title=TITLE</option></term>

                <listitem><para>
                    A title for the repository, e.g. for display in a UI.
                    The title is stored in the repository summary.
                </para></listitem>
            </varlistentry>

             <varlistentry>
                <term><option>--comment=COMMENT</option></term>

                <listitem><para>
                    A single-line comment for the remote, e.g. for display in a UI.
                    The comment is stored in the repository summary.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--description=DESCRIPTION</option></term>

                <listitem><para>
                    A full-paragraph description for the remote, e.g. for display in a UI.
                    The description is stored in the repository summary.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--homepage=URL</option></term>

                <listitem><para>
                    URL for a website for the remote, e.g. for display in a UI.
                    The url is stored in the repository summary.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--icon=URL</option></term>

                <listitem><para>
                    URL for an icon for the remote, e.g. for display in a UI.
                    The url is stored in the repository summary.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--default-branch=BRANCH</option></term>

                <listitem><para>
                    A default branch for the repository, mainly for use in a UI.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--gpg-import=FILE</option></term>

                <listitem><para>
                    Import a new default GPG public key from the
                    given file.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--collection-id=COLLECTION-ID</option></term>

                <listitem><para>
                    The globally unique identifier of the remote repository, to
                    allow mirrors to be grouped. This must be set to a globally
                    unique reverse DNS string if the repository is to be made
                    publicly available. If a collection ID is already set on an
                    existing repository, this will update it. If not specified,
                    the existing collection ID will be left unchanged.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--deploy-collection-id</option></term>

                <listitem><para>
                    Deploy the collection ID (set using <option>--collection-id</option>)
                    in the static remote configuration for all clients. This is
                    irrevocable once published in a repository. Use it to decide
                    when to roll out a collection ID to users of an existing repository.
                    If constructing a new repository which has a collection ID,
                    you should typically always pass this option.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--deploy-sideload-collection-id</option></term>

                <listitem><para>
                    This is similar to --deploy-collection-id, but it only applies the
                    deploy to clients newer than flatpak 1.7 which supports the new form
                    of sideloads.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--gpg-sign=KEYID</option></term>

                <listitem><para>
                    Sign the commit with this GPG key.
                    This option can be used multiple times.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--gpg-homedir=PATH</option></term>

                <listitem><para>
                    GPG Homedir to use when looking for keyrings
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--generate-static-deltas</option></term>

                <listitem><para>
                  Generate static deltas for all references. This generates from-empty and
                  delta static files that allow for faster download.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--static-delta-jobs=NUM-JOBS</option></term>

                <listitem><para>
                  Limit the number of parallel jobs creating static deltas. The default is the number of cpus.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--static-delta-ignore-ref=PATTERN</option></term>

                <listitem><para>
                  Don't generate deltas for runtime or application id matching this pattern. For instance,
                  --static-delta-ignore-ref=*.Sources means there will not be any deltas for source refs.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--prune</option></term>

                <listitem><para>
                    Remove unreferenced objects in repo.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--prune-depth</option></term>

                <listitem><para>
                    Only keep at most this number of old versions for any particular ref. Default is -1 which means infinite.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>-v</option></term>
                <term><option>--verbose</option></term>

                <listitem><para>
                    Print debug information during command processing.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--ostree-verbose</option></term>

                <listitem><para>
                    Print OSTree debug information during command processing.
                </para></listitem>
            </varlistentry>
        </variablelist>
    </refsect1>

    <refsect1>
        <title>See also</title>

        <para>
            <citerefentry><refentrytitle>ostree</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
            <citerefentry><refentrytitle>flatpak</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
            <citerefentry><refentrytitle>flatpak-remote-ls</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
            <citerefentry><refentrytitle>flatpak-build-export</refentrytitle><manvolnum>1</manvolnum></citerefentry>
        </para>

    </refsect1>

</refentry>

===== ./doc/flatpak-config.xml =====
<?xml version='1.0'?> <!--*-nxml-*-->
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
    "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">

<refentry id="flatpak-config">

    <refentryinfo>
        <title>flatpak config</title>
        <productname>flatpak</productname>

        <authorgroup>
            <author>
                <contrib>Developer</contrib>
                <firstname>Alexander</firstname>
                <surname>Larsson</surname>
                <email>alexl@redhat.com</email>
            </author>
        </authorgroup>
    </refentryinfo>

    <refmeta>
        <refentrytitle>flatpak config</refentrytitle>
        <manvolnum>1</manvolnum>
    </refmeta>

    <refnamediv>
        <refname>flatpak-config</refname>
        <refpurpose>Manage configuration</refpurpose>
    </refnamediv>

    <refsynopsisdiv>
            <cmdsynopsis>
                <command>flatpak config</command>
                <arg choice="opt" rep="repeat">OPTION</arg>
            </cmdsynopsis>
            <cmdsynopsis>
                <command>flatpak config</command>
                <arg choice="opt" rep="repeat">OPTION</arg>
                <arg choice="plain">--set</arg>
                <arg choice="plain">KEY</arg>
                <arg choice="plain">VALUE</arg>
            </cmdsynopsis>
            <cmdsynopsis>
                <command>flatpak config</command>
                <arg choice="opt" rep="repeat">OPTION</arg>
                <arg choice="plain">--unset|--get</arg>
                <arg choice="plain">KEY</arg>
            </cmdsynopsis>
    </refsynopsisdiv>

    <refsect1>
        <title>Description</title>

        <para>
            The flatpak config command shows or modifies the configuration of a flatpak installation.
            The following keys are supported:
        </para>
        <variablelist>
            <varlistentry>
                <term><varname>languages</varname></term>
                <listitem><para>
                   The languages that are included when installing Locale extensions.
                   The value is a semicolon-separated list of two-letter language codes,
                   or one of the special values <literal>*</literal> or <literal>*all*</literal>. If this key is unset, flatpak
                   defaults to including the <varname>extra-languages</varname> key and the current locale.
                </para></listitem>
            </varlistentry>
            <varlistentry>
                <term><varname>extra-languages</varname></term>
                <listitem><para>
                   This key is used when languages is not set, and it defines extra locale
                   extensions on top of the system configured languages. The value is a
                   semicolon-separated list of locale identifiers
                   (language, optional locale, optional codeset, optional modifier) as documented by
                   <citerefentry><refentrytitle>setlocale</refentrytitle><manvolnum>3</manvolnum></citerefentry>
                   (for example, <literal>en;en_DK;zh_HK.big5hkscs;uz_UZ.utf8@cyrillic</literal>).
                </para></listitem>
            </varlistentry>
            <varlistentry>
                <term><varname>report-os-info</varname></term>
                <listitem><para>
                   If this key is set to <literal>false</literal> or the <filename>no-report-os-info</filename>
                   file exists at <envar>FLATPAK_CONFIG_DIR</envar> Flatpak will not report the OS name,
                   version, and architecture from <filename>/etc/os-release</filename> to the Flatpak
                   remote via the <literal>Flatpak-Os-Info</literal> HTTP header when pulling objects.
                   The default value of the key if unset is <literal>true</literal>.
                </para></listitem>
            </varlistentry>
        </variablelist>

        <para>
            For configuration of individual remotes, see
            <citerefentry><refentrytitle>flatpak-remote-modify</refentrytitle><manvolnum>1</manvolnum></citerefentry>.
            For configuration of individual applications, see
            <citerefentry><refentrytitle>flatpak-override</refentrytitle><manvolnum>1</manvolnum></citerefentry>.
        </para>

    </refsect1>

    <refsect1>
        <title>Options</title>

        <para>The following options are understood:</para>

        <variablelist>
            <varlistentry>
                <term><option>-h</option></term>
                <term><option>--help</option></term>

                <listitem><para>
                    Show help options and exit.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--list</option></term>

                <listitem><para>
                    Print all keys and their values.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--set</option></term>

                <listitem><para>
                    Set key <arg choice="plain">KEY</arg> to <arg choice="plain">VALUE</arg>.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--unset</option></term>

                <listitem><para>
                    Unset key <arg choice="plain">KEY</arg>.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--get</option></term>

                <listitem><para>
                  Print value of <arg choice="plain">KEY</arg>.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>-u</option></term>
                <term><option>--user</option></term>

                <listitem><para>
                    Configure per-user installation.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--system</option></term>

                <listitem><para>
                    Configure system-wide installation.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--installation=NAME</option></term>

                <listitem><para>
                    Configure the system-wide installation
                    specified by <arg choice="plain">NAME</arg> among those defined in
                    <filename>/etc/flatpak/installations.d/</filename>. Using
                    <option>--installation=default</option> is equivalent to using
                    <option>--system</option>.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>-v</option></term>
                <term><option>--verbose</option></term>

                <listitem><para>
                    Print debug information during command processing.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--ostree-verbose</option></term>

                <listitem><para>
                    Print OSTree debug information during command processing.
                </para></listitem>
            </varlistentry>
        </variablelist>
    </refsect1>

    <refsect1>
        <title>Examples</title>

        <para>
            <command>$ flatpak config --set languages "sv;en;fi"</command>
        </para>

    </refsect1>

    <refsect1>
        <title>See also</title>

        <para>
            <citerefentry><refentrytitle>flatpak</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
            <citerefentry><refentrytitle>flatpak-remote-modify</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
            <citerefentry><refentrytitle>flatpak-override</refentrytitle><manvolnum>1</manvolnum></citerefentry>
        </para>

    </refsect1>

</refentry>

===== ./doc/flatpak-mask.xml =====
<?xml version='1.0'?> <!--*-nxml-*-->
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
    "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">

<refentry id="flatpak-mask">

    <refentryinfo>
        <title>flatpak mask</title>
        <productname>flatpak</productname>

        <authorgroup>
            <author>
                <contrib>Developer</contrib>
                <firstname>Alexander</firstname>
                <surname>Larsson</surname>
                <email>alexl@redhat.com</email>
            </author>
        </authorgroup>
    </refentryinfo>

    <refmeta>
        <refentrytitle>flatpak mask</refentrytitle>
        <manvolnum>1</manvolnum>
    </refmeta>

    <refnamediv>
        <refname>flatpak-mask</refname>
        <refpurpose>Mask out updates and automatic installation</refpurpose>
    </refnamediv>

    <refsynopsisdiv>
            <cmdsynopsis>
                <command>flatpak mask</command>
                <arg choice="opt" rep="repeat">OPTION</arg>
                <arg choice="plain" rep="repeat">PATTERN</arg>
            </cmdsynopsis>
    </refsynopsisdiv>

    <refsect1>
        <title>Description</title>

        <para>
          Flatpak maintains a list of patterns that define which refs are masked.
          A masked ref will never be updated or automatically installed (for example a
          masked extension marked auto-download will not be downloaded). You can still
          manually install such refs, but once they are installed the version will be pinned.
        </para>
        <para>
          The patterns are just a partial ref, with the * character matching anything
          within that part of the ref. Here are some example patterns:
<programlisting>
org.some.App
org.some.App//unstable
app/org.domain.*
org.some.App/arm
</programlisting>
        </para>
        <para>
          To list the current set of masks, run this command without any patterns.
        </para>
    </refsect1>

    <refsect1>
        <title>Options</title>

        <para>The following options are understood:</para>

        <variablelist>
            <varlistentry>
                <term><option>-h</option></term>
                <term><option>--help</option></term>

                <listitem><para>
                    Show help options and exit.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--remove</option></term>

                <listitem><para>
                  Instead of adding the patterns, remove matching patterns.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>-u</option></term>
                <term><option>--user</option></term>

                <listitem><para>
                    Mask refs in a per-user installation.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--system</option></term>

                <listitem><para>
                    Mask refs in the default system-wide installation.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--installation=NAME</option></term>

                <listitem><para>
                    Mask refs in a system-wide installation
                    specified by <arg choice="plain">NAME</arg> among those defined in
                    <filename>/etc/flatpak/installations.d/</filename>. Using
                    <option>--installation=default</option> is equivalent to using
                    <option>--system</option>.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>-v</option></term>
                <term><option>--verbose</option></term>

                <listitem><para>
                    Print debug information during command processing.
                </para></listitem>
            </varlistentry>
        </variablelist>
    </refsect1>

    <refsect1>
        <title>Examples</title>

        <para>
            <command>$ flatpak mask</command>
        </para>
        <para>
            <command>$ flatpak mask org.broken.App</command>
        </para>
        <para>
            <command>$ flatpak mask --remove org.broken.App</command>
        </para>

    </refsect1>

    <refsect1>
        <title>See also</title>

        <para>
            <citerefentry><refentrytitle>flatpak</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
            <citerefentry><refentrytitle>flatpak-update</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
        </para>

    </refsect1>

</refentry>

===== ./doc/flatpak-install.xml =====
<?xml version='1.0'?> <!--*-nxml-*-->
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
    "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">

<refentry id="flatpak-install">

    <refentryinfo>
        <title>flatpak install</title>
        <productname>flatpak</productname>

        <authorgroup>
            <author>
                <contrib>Developer</contrib>
                <firstname>Alexander</firstname>
                <surname>Larsson</surname>
                <email>alexl@redhat.com</email>
            </author>
        </authorgroup>
    </refentryinfo>

    <refmeta>
        <refentrytitle>flatpak install</refentrytitle>
        <manvolnum>1</manvolnum>
    </refmeta>

    <refnamediv>
        <refname>flatpak-install</refname>
        <refpurpose>Install an application or runtime</refpurpose>
    </refnamediv>

    <refsynopsisdiv>
            <cmdsynopsis>
                <command>flatpak install</command>
                <arg choice="opt" rep="repeat">OPTION</arg>
                <arg choice="opt">REMOTE</arg>
                <arg choice="plain" rep="repeat">REF</arg>
            </cmdsynopsis>
            <cmdsynopsis>
                <command>flatpak install</command>
                <arg choice="opt" rep="repeat">OPTION</arg>
                <arg choice="opt">--from|--bundle|--image</arg>
                <arg choice="plain">LOCATION</arg>
            </cmdsynopsis>
    </refsynopsisdiv>

    <refsect1>
        <title>Description</title>

        <para>
          Installs an application or runtime. The primary way to
          install is to specify a <arg choice="plain">REMOTE</arg>
          name as the source and one or more <arg choice="plain">REF</arg>s to specify the
          application or runtime to install. If <arg choice="plain">REMOTE</arg> is omitted,
          the configured remotes are searched for the first <arg choice="plain">REF</arg>
          and the user is asked to confirm the resulting choice.
        </para>
        <para>
          Each <arg choice="plain">REF</arg> argument is a full or partial identifier in the
          flatpak ref format, which looks like "(app|runtime)/ID/ARCH/BRANCH".
          All elements except ID are optional and can be left out, including the slashes,
          so most of the time you need only specify ID. Any part left out will be matched
          against what is in the remote, and if there are multiple matches you will be
          prompted to choose one of them. You will also be prompted with choices if
          <arg choice="plain">REF</arg> doesn't match anything in the remote exactly but is
          similar to one or more refs in the remote (e.g. "devhelp" is similar to
          "org.gnome.Devhelp"), but this fuzzy matching behavior is disabled if
          <arg choice="plain">REF</arg> contains any slashes or periods.
        </para>
        <para>
          By default this looks for both apps and runtimes with the given
          <arg choice="plain">REF</arg> in the specified <arg choice="plain">REMOTE</arg>,
          but you can limit this by using the <option>--app</option> or <option>--runtime</option>
          option, or by supplying the initial element in the <arg choice="plain">REF</arg>.
        </para>
        <para>
          If <arg choice="plain">REMOTE</arg> is a uri or a path (absolute or relative starting
          with ./) to a local repository, then that repository will be used as the source, and
          a temporary remote will be created for the lifetime of the <arg choice="plain">REF</arg>.
        </para>
        <para>
          If the specified <arg choice="plain">REMOTE</arg> has a collection ID configured on it,
          Flatpak will search the <filename>sideload-repos</filename> directories configured
          either with the <option>--sideload-repo</option> option, or on a per-installation or
          system-wide basis (see
          <citerefentry><refentrytitle>flatpak</refentrytitle><manvolnum>1</manvolnum></citerefentry>).
        </para>
        <para>
          For OCI remotes, sideload repositories can also be specified as
          <option>--sideload-repo=oci:PATH</option> or <option>--sideload-repo=oci-archive:PATH</option>,
          where path points to an OCI image layout or archive of an OCI image layout.
          (See <citerefentry><refentrytitle>containers-transports</refentrytitle><manvolnum>5</manvolnum></citerefentry>.)
          When specified in this fashion, the images found in the image layout are available for all OCI remotes,
          without regard to collection ID. For this reason, there is no directory equivalent -
          it can only be specified on the command line.
        </para>
        <para>
          The alternative form of the command (with <option>--from</option>, <option>--bundle</option>,
          or <option>--image</option>) allows to install directly from a source. The source can be a
          <filename>.flatpak</filename> single-file bundle, <filename>.flatpakref</filename>
          application description, or a reference to an OCI image. The options are optional if the
          first argument has the expected filename extension or prefix.
        </para>
        <para>
          Note that flatpak allows to have multiple branches of an application and runtimes
          installed and used at the same time. However, only one version of an application
          can be current, meaning its exported files (for instance desktop files and icons)
          are visible to the host. The last installed version is made current by default, but
          this can manually changed with flatpak make-current.
        </para>
        <para>
          Unless overridden with the <option>--user</option> or the <option>--installation</option>
          option, this command installs the application or runtime in the default system-wide
          installation.
        </para>

    </refsect1>

    <refsect1>
        <title>Options</title>

        <para>The following options are understood:</para>

        <variablelist>
            <varlistentry>
                <term><option>-h</option></term>
                <term><option>--help</option></term>

                <listitem><para>
                    Show help options and exit.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--bundle</option></term>

                <listitem><para>
                  Treat <arg choice="plain">LOCATION</arg> as a single-bundle file.
                  This is assumed if the argument ends with <filename>.flatpak</filename>.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--from</option></term>

                <listitem><para>
                  Treat <arg choice="plain">LOCATION</arg> as an application description file.
                  This is assumed if the argument ends with <filename>.flatpakref</filename>.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--image</option></term>
                <listitem><para>
                  Treat <arg choice="plain">LOCATION</arg> as the location of a Flatpak in
                  OCI image format. <arg choice="plan>">LOCATION</arg> is in the format of
                  <citerefentry><refentrytitle>containers-transports</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
                  Supported schemes are <literal>docker://</literal>, <literal>oci:</literal>,
                  and <literal>oci-archive:</literal>. This is assumed if the argument starts
                  with one of these schemes.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--reinstall</option></term>

                <listitem><para>
                  Uninstall first if already installed.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>-u</option></term>
                <term><option>--user</option></term>

                <listitem><para>
                    Install the application or runtime in a per-user installation.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--system</option></term>

                <listitem><para>
                    Install the application or runtime in the default system-wide installation.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--installation=NAME</option></term>

                <listitem><para>
                    Install the application or runtime in a system-wide installation
                    specified by <arg choice="plain">NAME</arg> among those defined in
                    <filename>/etc/flatpak/installations.d/</filename>. Using
                    <option>--installation=default</option> is equivalent to using
                    <option>--system</option>.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--arch=ARCH</option></term>

                <listitem><para>
                    The default architecture to install for, if not given explicitly in
                    the <arg choice="plain">REF</arg>. See <command>flatpak --supported-arches</command>
                    for architectures supported by the host.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--subpath=PATH</option></term>

                <listitem><para>
                  Install only a subpath of <arg choice="plain">REF</arg>. This is mainly used to
                  install a subset of locales. This can be added multiple times to install multiple
                  subpaths.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--gpg-file=FILE</option></term>

                <listitem><para>
                  Check bundle signatures with GPG key from <arg choice="plain">FILE</arg> (- for stdin).
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--no-deploy</option></term>

                <listitem><para>
                    Download the latest version, but don't deploy it.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--no-pull</option></term>

                <listitem><para>
                    Don't download the latest version, deploy whatever is locally available.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--no-related</option></term>

                <listitem><para>
                    Don't download related extensions, such as the locale data.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--no-deps</option></term>

                <listitem><para>
                    Don't verify runtime dependencies when installing.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--or-update</option></term>
                <listitem><para>
                  Normally install just ignores things that are already installed (printing a warning), but if
                  --or-update is specified it silently turns it into an update operation instead.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--app</option></term>

                <listitem><para>
                    Assume that all <arg choice="plain">REF</arg>s are apps if not explicitly specified.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--runtime</option></term>
                <listitem><para>
                    Assume that all <arg choice="plain">REF</arg>s are runtimes if not explicitly specified.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--sideload-repo=PATH</option></term>

                <listitem><para>
                    Adds an extra local ostree repo as a source for installation. This is equivalent
                    to using the <filename>sideload-repos</filename> directories (see
                    <citerefentry><refentrytitle>flatpak</refentrytitle><manvolnum>1</manvolnum></citerefentry>),
                    but can be done on a per-command basis. Any path added here is used in addition
                    to ones in those directories.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--include-sdk</option></term>

                <listitem><para>
                  For each app being installed, also installs the SDK that was used to build it.
                  Implies <option>--or-update</option>; incompatible with <option>--no-deps</option>.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--include-debug</option></term>

                <listitem><para>
                  For each ref being installed, as well as all dependencies, also installs its
                  debug info. Implies <option>--or-update</option>; incompatible with
                  <option>--no-deps</option>.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>-y</option></term>
                <term><option>--assumeyes</option></term>
                <listitem><para>
                    Automatically answer yes to all questions (or pick the most prioritized answer). This is useful for automation.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--noninteractive</option></term>
                <listitem><para>
                    Produce minimal output and avoid most questions. This is suitable for use in
                    non-interactive situations, e.g. in a build script.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>-v</option></term>
                <term><option>--verbose</option></term>

                <listitem><para>
                    Print debug information during command processing.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--ostree-verbose</option></term>

                <listitem><para>
                    Print OSTree debug information during command processing.
                </para></listitem>
            </varlistentry>
        </variablelist>
    </refsect1>

    <refsect1>
        <title>Examples</title>

        <para>
            <command>$ flatpak install gedit</command>
        </para>
        <para>
            <command>$ flatpak install flathub org.gnome.gedit</command>
        </para>
        <para>
            <command>$ flatpak --installation=default install flathub org.gnome.gedit</command>
        </para>
        <para>
            <command>$ flatpak --user install flathub org.gnome.gedit//3.30</command>
        </para>
        <para>
            <command>$ flatpak --user install https://flathub.org/repo/appstream/org.gnome.gedit.flatpakref</command>
        </para>
        <para>
            <command>$ flatpak --system install org.gnome.gedit.flatpakref</command>
        </para>

    </refsect1>

    <refsect1>
        <title>See also</title>

        <para>
            <citerefentry><refentrytitle>flatpak</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
            <citerefentry><refentrytitle>flatpak-update</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
            <citerefentry><refentrytitle>flatpak-list</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
            <citerefentry><refentrytitle>flatpak-build-bundle</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
            <citerefentry><refentrytitle>flatpakref</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
            <citerefentry><refentrytitle>flatpak-make-current</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
            <citerefentry><refentrytitle>ostree-find-remotes</refentrytitle><manvolnum>1</manvolnum></citerefentry>
        </para>

    </refsect1>

</refentry>

===== ./doc/flatpak-list.xml =====
<?xml version='1.0'?> <!--*-nxml-*-->
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
    "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">

<refentry id="flatpak-list">

    <refentryinfo>
        <title>flatpak list</title>
        <productname>flatpak</productname>

        <authorgroup>
            <author>
                <contrib>Developer</contrib>
                <firstname>Alexander</firstname>
                <surname>Larsson</surname>
                <email>alexl@redhat.com</email>
            </author>
        </authorgroup>
    </refentryinfo>

    <refmeta>
        <refentrytitle>flatpak list</refentrytitle>
        <manvolnum>1</manvolnum>
    </refmeta>

    <refnamediv>
        <refname>flatpak-list</refname>
        <refpurpose>List installed applications and/or runtimes</refpurpose>
    </refnamediv>

    <refsynopsisdiv>
            <cmdsynopsis>
                <command>flatpak list</command>
                <arg choice="opt" rep="repeat">OPTION</arg>
            </cmdsynopsis>
    </refsynopsisdiv>

    <refsect1>
        <title>Description</title>

        <para>
            Lists the names of the installed applications and runtimes.
        </para>
        <para>
            By default, both apps and runtimes are shown, but you can
            change this by using the <option>--app</option> or
            <option>--runtime</option> options.
        </para>
        <para>
            By default, both per-user and system-wide installations are shown.
            Use the <option>--user</option>, <option>--installation</option> or
            <option>--system</option> options to change this.
        </para>
        <para>
            The list command can also be used to find installed apps that
            use a certain runtime, with the <option>--app-runtime</option> option.
        </para>

    </refsect1>

    <refsect1>
        <title>Options</title>

        <para>The following options are understood:</para>

        <variablelist>
            <varlistentry>
                <term><option>-h</option></term>
                <term><option>--help</option></term>

                <listitem><para>
                    Show help options and exit.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>-u</option></term>
                <term><option>--user</option></term>

                <listitem><para>
                    List per-user installations.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--system</option></term>

                <listitem><para>
                    List the default system-wide installations.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--installation=NAME</option></term>

                <listitem><para>
                    List a system-wide installation specified by <arg choice="plain">NAME</arg>
                    among those defined in <filename>/etc/flatpak/installations.d/</filename>.
                    Using <option>--installation=default</option> is equivalent to using
                    <option>--system</option>.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--arch=ARCH</option></term>

                <listitem><para>
                    List apps/runtimes for this architecture. See <command>flatpak --supported-arches</command>
                    for architectures supported by the host.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>-d</option></term>
                <term><option>--show-details</option></term>

                <listitem><para>
                    Show origin, sizes and other extra information.
                    Equivalent to <option>--columns=all</option>.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--app</option></term>

                <listitem><para>
                    List applications.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--runtime</option></term>

                <listitem><para>
                    List runtimes.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--all</option></term>
                <term><option>-a</option></term>

                <listitem><para>
                    List all installed runtimes, including locale and debug extensions. These are hidden by default.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--app-runtime=RUNTIME</option></term>

                <listitem><para>
                    List applications that use the given runtime.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>-v</option></term>
                <term><option>--verbose</option></term>

                <listitem><para>
                    Print debug information during command processing.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--ostree-verbose</option></term>

                <listitem><para>
                    Print OSTree debug information during command processing.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--columns=FIELD,…</option></term>

                <listitem><para>
                    Specify what information to show about each ref. You can
                    list multiple fields, or use this option multiple times.
                </para><para>
                    Append :s[tart], :m[iddle], :e[nd] or :f[ull] to column
                    names to change ellipsization.
                </para></listitem>
            </varlistentry>

        </variablelist>
    </refsect1>

   <refsect1>
        <title>Fields</title>

        <para>The following fields are understood by the <option>--columns</option> option:</para>

        <variablelist>
            <varlistentry>
                <term>name</term>

                <listitem><para>
                    Show the name
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term>description</term>

                <listitem><para>
                    Show the description
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term>application</term>

                <listitem><para>
                    Show the application or runtime ID
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term>arch</term>

                <listitem><para>
                    Show the architecture
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term>branch</term>

                <listitem><para>
                    Show the branch
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term>runtime</term>

                <listitem><para>
                    Show the used runtime
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term>version</term>

                <listitem><para>
                    Show the version
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term>ref</term>

                <listitem><para>
                    Show the ref
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term>origin</term>

                <listitem><para>
                    Show the origin remote
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term>installation</term>

                <listitem><para>
                    Show the installation
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term>active</term>

                <listitem><para>
                    Show the active commit
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term>latest</term>

                <listitem><para>
                    Show the latest commit
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term>size</term>

                <listitem><para>
                    Show the installed size
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term>options</term>

                <listitem><para>
                    Show options
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term>all</term>

                <listitem><para>
                    Show all columns
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term>help</term>

                <listitem><para>
                    Show the list of available columns
                </para></listitem>
            </varlistentry>
        </variablelist>

        <para>
          Note that field names can be abbreviated to a unique prefix.
        </para>

    </refsect1>

    <refsect1>
        <title>Examples</title>

        <para>
            <command>$ flatpak --user --columns=app list</command>
        </para>
<programlisting>
<command>Application</command>
org.gnome.Builder
org.freedesktop.glxgears
org.gnome.MyApp
org.gnome.gedit
</programlisting>

    </refsect1>

    <refsect1>
        <title>See also</title>

        <para>
            <citerefentry><refentrytitle>flatpak</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
            <citerefentry><refentrytitle>flatpak-install</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
            <citerefentry><refentrytitle>flatpak-update</refentrytitle><manvolnum>1</manvolnum></citerefentry>
        </para>

    </refsect1>

</refentry>

===== ./doc/flatpak-documents.xml =====
<?xml version='1.0'?> <!--*-nxml-*-->
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
    "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">

<refentry id="flatpak-documents">

    <refentryinfo>
        <title>flatpak documents</title>
        <productname>flatpak</productname>

        <authorgroup>
            <author>
                <contrib>Developer</contrib>
                <firstname>Alexander</firstname>
                <surname>Larsson</surname>
                <email>alexl@redhat.com</email>
            </author>
        </authorgroup>
    </refentryinfo>

    <refmeta>
        <refentrytitle>flatpak documents</refentrytitle>
        <manvolnum>1</manvolnum>
    </refmeta>

    <refnamediv>
        <refname>flatpak-documents</refname>
        <refpurpose>List exported files</refpurpose>
    </refnamediv>

    <refsynopsisdiv>
            <cmdsynopsis>
                <command>flatpak documents</command>
                <arg choice="opt" rep="repeat">OPTION</arg>
                <arg choice="opt">APPID</arg>
            </cmdsynopsis>
    </refsynopsisdiv>

    <refsect1>
        <title>Description</title>

        <para>
            Lists exported files, with their document id and the
            full path to their origin. If an <arg choice="plain">APPID</arg> is specified,
            only the files exported to this app are listed.
        </para>

    </refsect1>

    <refsect1>
        <title>Options</title>

        <para>The following options are understood:</para>

        <variablelist>
            <varlistentry>
                <term><option>-h</option></term>
                <term><option>--help</option></term>

                <listitem><para>
                    Show help options and exit.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>-v</option></term>
                <term><option>--verbose</option></term>

                <listitem><para>
                    Print debug information during command processing.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--ostree-verbose</option></term>

                <listitem><para>
                    Print OSTree debug information during command processing.
                </para></listitem>
            </varlistentry>
        </variablelist>
    </refsect1>

    <refsect1>
        <title>See also</title>

        <para>
            <citerefentry><refentrytitle>flatpak</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
            <citerefentry><refentrytitle>flatpak-document-export</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
            <citerefentry><refentrytitle>flatpak-document-unexport</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
            <citerefentry><refentrytitle>flatpak-document-info</refentrytitle><manvolnum>1</manvolnum></citerefentry>
        </para>

    </refsect1>

</refentry>

===== ./doc/flatpak-permissions.xml =====
<?xml version='1.0'?> <!--*-nxml-*-->
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
    "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">

<refentry id="flatpak-permissions">

    <refentryinfo>
        <title>flatpak permissions</title>
        <productname>flatpak</productname>

        <authorgroup>
            <author>
                <contrib>Developer</contrib>
                <firstname>Matthias</firstname>
                <surname>Clasen</surname>
                <email>mclasen@redhat.com</email>
            </author>
        </authorgroup>
    </refentryinfo>

    <refmeta>
        <refentrytitle>flatpak permissions</refentrytitle>
        <manvolnum>1</manvolnum>
    </refmeta>

    <refnamediv>
        <refname>flatpak-permissions</refname>
        <refpurpose>List permissions</refpurpose>
    </refnamediv>

    <refsynopsisdiv>
            <cmdsynopsis>
                <command>flatpak permissions</command>
                <arg choice="opt" rep="repeat">OPTION</arg>
                <arg choice="opt">TABLE</arg>
                <arg choice="opt">ID</arg>
            </cmdsynopsis>
    </refsynopsisdiv>

    <refsect1>
        <title>Description</title>

        <para>
          Lists dynamic permissions which are stored in the Flatpak
          permission store.
        </para>

        <para>
          When called without arguments, lists all
          the entries in all permission store tables. When called
          with one argument, lists all the entries in the named
          table. When called with two arguments, lists the entry
          in the named table for the given object <arg choice="plain">ID</arg>.
        </para>

        <para>
          The permission store is used by portals.
          Each portal generally has its own table in the permission
          store, and the format of the table entries is specific to
          each portal.
        </para>

    </refsect1>

    <refsect1>
        <title>Options</title>

        <para>The following options are understood:</para>

        <variablelist>
            <varlistentry>
                <term><option>-h</option></term>
                <term><option>--help</option></term>

                <listitem><para>
                    Show help options and exit.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>-v</option></term>
                <term><option>--verbose</option></term>

                <listitem><para>
                    Print debug information during command processing.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--ostree-verbose</option></term>

                <listitem><para>
                    Print OSTree debug information during command processing.
                </para></listitem>
            </varlistentry>
        </variablelist>
    </refsect1>

    <refsect1>
        <title>See also</title>

        <para>
            <citerefentry><refentrytitle>flatpak</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
            <citerefentry><refentrytitle>flatpak-permission-show</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
            <citerefentry><refentrytitle>flatpak-permission-remove</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
            <citerefentry><refentrytitle>flatpak-permission-reset</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
            <citerefentry><refentrytitle>flatpak-permission-set</refentrytitle><manvolnum>1</manvolnum></citerefentry>
        </para>

    </refsect1>

</refentry>

===== ./doc/flatpak-remotes.xml =====
<?xml version='1.0'?> <!--*-nxml-*-->
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
    "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">

<refentry id="flatpak-remotes">

    <refentryinfo>
        <title>flatpak remotes</title>
        <productname>flatpak</productname>

        <authorgroup>
            <author>
                <contrib>Developer</contrib>
                <firstname>Alexander</firstname>
                <surname>Larsson</surname>
                <email>alexl@redhat.com</email>
            </author>
        </authorgroup>
    </refentryinfo>

    <refmeta>
        <refentrytitle>flatpak remotes</refentrytitle>
        <manvolnum>1</manvolnum>
    </refmeta>

    <refnamediv>
        <refname>flatpak-remotes</refname>
        <refpurpose>List remote repositories</refpurpose>
    </refnamediv>

    <refsynopsisdiv>
            <cmdsynopsis>
                <command>flatpak remotes</command>
                <arg choice="opt" rep="repeat">OPTION</arg>
            </cmdsynopsis>
    </refsynopsisdiv>

    <refsect1>
        <title>Description</title>

        <para>
            Lists the known remote repositories, in priority order.
        </para>
        <para>
            By default, both per-user and system-wide installations
            are shown. Use the <option>--user</option>, <option>--system</option> or <option>--installation</option>
            options to change this.
        </para>

    </refsect1>

    <refsect1>
        <title>Options</title>

        <para>The following options are understood:</para>

        <variablelist>
            <varlistentry>
                <term><option>-h</option></term>
                <term><option>--help</option></term>

                <listitem><para>
                    Show help options and exit.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>-u</option></term>
                <term><option>--user</option></term>

                <listitem><para>
                    Show the per-user configuration.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--system</option></term>

                <listitem><para>
                    Show the default system-wide configuration.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--installation=NAME</option></term>

                <listitem><para>
                    Show a system-wide installation by <arg choice="plain">NAME</arg> among
                    those defined in <filename>/etc/flatpak/installations.d/</filename>.
                    Using <option>--installation=default</option> is equivalent to using
                    <option>--system</option>.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>-d</option></term>
                <term><option>--show-details</option></term>

                <listitem><para>
                    Show more information for each repository in addition to the name.
                    Equivalent to <option>--columns=all</option>.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--show-disabled</option></term>

                <listitem><para>
                    Show disabled repos.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>-v</option></term>
                <term><option>--verbose</option></term>

                <listitem><para>
                    Print debug information during command processing.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--ostree-verbose</option></term>

                <listitem><para>
                    Print OSTree debug information during command processing.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--columns=FIELD,…</option></term>

                <listitem><para>
                    Specify what information to show about each ref. You can
                    list multiple fields, or use this option multiple times.
                </para><para>
                    Append :s[tart], :m[iddle], :e[nd] or :f[ull] to column
                    names to change ellipsization.
                </para></listitem>
            </varlistentry>

        </variablelist>
    </refsect1>

   <refsect1>
        <title>Fields</title>

        <para>The following fields are understood by the <option>--columns</option> option:</para>

        <variablelist>
            <varlistentry>
                <term>name</term>

                <listitem><para>
                    Show the name of the remote
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term>title</term>

                <listitem><para>
                    Show the title of the remote
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term>url</term>

                <listitem><para>
                    Show the URL of the remote
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term>filter</term>

                <listitem><para>
                    Show the path to the client-side filter of the remote.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term>collection</term>

                <listitem><para>
                    Show the collection ID of the remote
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term>priority</term>

                <listitem><para>
                    Show the priority of the remote
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term>options</term>

                <listitem><para>
                    Show options
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term>comment</term>

                <listitem><para>
                    Show comment
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term>description</term>

                <listitem><para>
                    Show description
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term>homepage</term>

                <listitem><para>
                    Show homepage
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term>icon</term>

                <listitem><para>
                    Show icon
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term>all</term>

                <listitem><para>
                    Show all columns
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term>help</term>

                <listitem><para>
                    Show the list of available columns
                </para></listitem>
            </varlistentry>
        </variablelist>

        <para>
          Note that field names can be abbreviated to a unique prefix.
        </para>

    </refsect1>

    <refsect1>
        <title>Examples</title>

        <para>
            <command>$ flatpak remotes --user --show-details</command>
        </para>
<programlisting>
testrepo	Test Repository	 http://209.132.179.91/repo/ no-gpg-verify
</programlisting>
    </refsect1>

    <refsect1>
        <title>See also</title>

            <para>
                <citerefentry><refentrytitle>flatpak</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
                <citerefentry><refentrytitle>flatpak-remote-add</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
                <citerefentry><refentrytitle>flatpak-remote-delete</refentrytitle><manvolnum>1</manvolnum></citerefentry>
            </para>
    </refsect1>

</refentry>

===== ./doc/flatpak-document-unexport.xml =====
<?xml version='1.0'?> <!--*-nxml-*-->
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
    "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">

<refentry id="flatpak-document-unexport">

    <refentryinfo>
        <title>flatpak document-unexport</title>
        <productname>flatpak</productname>

        <authorgroup>
            <author>
                <contrib>Developer</contrib>
                <firstname>Alexander</firstname>
                <surname>Larsson</surname>
                <email>alexl@redhat.com</email>
            </author>
        </authorgroup>
    </refentryinfo>

    <refmeta>
        <refentrytitle>flatpak document-unexport</refentrytitle>
        <manvolnum>1</manvolnum>
    </refmeta>

    <refnamediv>
        <refname>flatpak-document-unexport</refname>
        <refpurpose>Stop exporting a file</refpurpose>
    </refnamediv>

    <refsynopsisdiv>
            <cmdsynopsis>
                <command>flatpak document-unexport</command>
                <arg choice="opt" rep="repeat">OPTION</arg>
                <arg choice="plain">FILE</arg>
            </cmdsynopsis>
    </refsynopsisdiv>

    <refsect1>
        <title>Description</title>

        <para>
            Removes the document id for the file from the
            document portal. This will make the document unavailable
            to all sandboxed applications.
        </para>

    </refsect1>

    <refsect1>
        <title>Options</title>

        <para>The following options are understood:</para>

        <variablelist>
            <varlistentry>
                <term><option>--doc-id</option></term>

                <listitem><para>
                    Interpret <arg choice="plain">FILE</arg> as a document ID
                    rather than a file path. This is useful for example when
                    the file has been deleted.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>-h</option></term>
                <term><option>--help</option></term>

                <listitem><para>
                    Show help options and exit.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>-v</option></term>
                <term><option>--verbose</option></term>

                <listitem><para>
                    Print debug information during command processing.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--ostree-verbose</option></term>

                <listitem><para>
                    Print OSTree debug information during command processing.
                </para></listitem>
            </varlistentry>
        </variablelist>
    </refsect1>

    <refsect1>
        <title>See also</title>

        <para>
            <citerefentry><refentrytitle>flatpak</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
            <citerefentry><refentrytitle>flatpak-document-export</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
            <citerefentry><refentrytitle>flatpak-document-info</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
            <citerefentry><refentrytitle>flatpak-documents</refentrytitle><manvolnum>1</manvolnum></citerefentry>
        </para>

    </refsect1>

</refentry>

===== ./doc/flatpak-make-current.xml =====
<?xml version='1.0'?> <!--*-nxml-*-->
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
    "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">

<refentry id="flatpak-make-current">

    <refentryinfo>
        <title>flatpak make-current</title>
        <productname>flatpak</productname>

        <authorgroup>
            <author>
                <contrib>Developer</contrib>
                <firstname>Alexander</firstname>
                <surname>Larsson</surname>
                <email>alexl@redhat.com</email>
            </author>
        </authorgroup>
    </refentryinfo>

    <refmeta>
        <refentrytitle>flatpak make-current</refentrytitle>
        <manvolnum>1</manvolnum>
    </refmeta>

    <refnamediv>
        <refname>flatpak-make-current</refname>
        <refpurpose>Make a specific version of an app current</refpurpose>
    </refnamediv>

    <refsynopsisdiv>
            <cmdsynopsis>
                <command>flatpak make-current</command>
                <arg choice="opt" rep="repeat">OPTION</arg>
                <arg choice="plain">APP</arg>
                <arg choice="plain">BRANCH</arg>
            </cmdsynopsis>
    </refsynopsisdiv>

    <refsect1>
        <title>Description</title>

        <para>
            Makes a particular branch of an application current. Only the current branch
            of an app has its exported files (such as desktop files and icons) made visible
            to the host.
        </para>
        <para>
            When a new branch is installed it will automatically be made current, so this
            command is often not needed.
        </para>
        <para>
            Unless overridden with the <option>--user</option> or <option>--installation</option> options, this command
            changes the default system-wide installation.
        </para>

    </refsect1>

    <refsect1>
        <title>Options</title>

        <para>The following options are understood:</para>

        <variablelist>
            <varlistentry>
                <term><option>-h</option></term>
                <term><option>--help</option></term>

                <listitem><para>
                    Show help options and exit.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>-u</option></term>
                <term><option>--user</option></term>

                <listitem><para>
                    Update a per-user installation.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--system</option></term>

                <listitem><para>
                    Update the default system-wide installation.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--installation=NAME</option></term>

                <listitem><para>
                    Updates a system-wide installation specified by <arg choice="plain">NAME</arg>
                    among those defined in <filename>/etc/flatpak/installations.d/</filename>.
                    Using <option>--installation=default</option> is equivalent to using
                    <option>--system</option>.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--arch=ARCH</option></term>

                <listitem><para>
                    The architecture to make current for. See <command>flatpak --supported-arches</command>
                    for architectures supported by the host.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>-v</option></term>
                <term><option>--verbose</option></term>

                <listitem><para>
                    Print debug information during command processing.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--ostree-verbose</option></term>

                <listitem><para>
                    Print OSTree debug information during command processing.
                </para></listitem>
            </varlistentry>
        </variablelist>
    </refsect1>

    <refsect1>
        <title>Examples</title>

        <para>
            <command>$ flatpak --user make-current org.gnome.gedit 3.14</command>
        </para>

    </refsect1>

    <refsect1>
        <title>See also</title>

        <para>
            <citerefentry><refentrytitle>flatpak</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
            <citerefentry><refentrytitle>flatpak-install</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
            <citerefentry><refentrytitle>flatpak-list</refentrytitle><manvolnum>1</manvolnum></citerefentry>
        </para>

    </refsect1>

</refentry>

===== ./doc/release-checklist.md =====
Flatpak release checklist
=========================

* Update NEWS
* Check that version number in `meson.build` is correct
* Update release date in `NEWS`
* Commit the changes
* `ninja -C ${builddir} flatpak-update-po`
    * This will update `po/`; commit those changes too
* If this is the first release of a new stable release series, update
  `SECURITY.md`. It should list the development branch and new stable branch as
  currently maintained.
* `git evtag sign $VERSION`
* `git push --atomic origin main $VERSION`
* Ensure the release.yml workflow succeeds

After the release:

* Update version number in `meson.build` to the next release version
* Start a new section in `NEWS`

After creating a stable branch:

* Update version number in `meson.build` to the next unstable release version
* Update the `NEWS` section header

===== ./doc/flatpak-permission-remove.xml =====
<?xml version='1.0'?> <!--*-nxml-*-->
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
    "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">

<refentry id="flatpak-permission-remove">

    <refentryinfo>
        <title>flatpak permission-remove</title>
        <productname>flatpak</productname>

        <authorgroup>
            <author>
                <contrib>Developer</contrib>
                <firstname>Matthias</firstname>
                <surname>Clasen</surname>
                <email>mclasen@redhat.com</email>
            </author>
        </authorgroup>
    </refentryinfo>

    <refmeta>
        <refentrytitle>flatpak permission-remove</refentrytitle>
        <manvolnum>1</manvolnum>
    </refmeta>

    <refnamediv>
        <refname>flatpak-permission-remove</refname>
        <refpurpose>Remove permissions</refpurpose>
    </refnamediv>

    <refsynopsisdiv>
            <cmdsynopsis>
                <command>flatpak permission-remove</command>
                <arg choice="opt" rep="repeat">OPTION</arg>
                <arg choice="plain">TABLE</arg>
                <arg choice="plain">ID</arg>
                <arg choice="opt">APP_ID</arg>
            </cmdsynopsis>
    </refsynopsisdiv>

    <refsect1>
        <title>Description</title>

        <para>
          Removes an entry for the object with id <arg choice="plain">ID</arg> to the permission
          store table <arg choice="plain">TABLE</arg>. The <arg choice="plain">ID</arg> must be in
          a suitable format for the table. If <arg choice="plain">APP_ID</arg> is specified, only
          the entry for that application is removed.
        </para>
        <para>
          The permission store is used by portals.
          Each portal generally has its own table in the permission
          store, and the format of the table entries is specific to
          each portal.
        </para>

    </refsect1>

    <refsect1>
        <title>Options</title>

        <para>The following options are understood:</para>

        <variablelist>
            <varlistentry>
                <term><option>-h</option></term>
                <term><option>--help</option></term>

                <listitem><para>
                    Show help options and exit.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>-v</option></term>
                <term><option>--verbose</option></term>

                <listitem><para>
                    Print debug information during command processing.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--ostree-verbose</option></term>

                <listitem><para>
                    Print OSTree debug information during command processing.
                </para></listitem>
            </varlistentry>
        </variablelist>
    </refsect1>

    <refsect1>
        <title>See also</title>

        <para>
            <citerefentry><refentrytitle>flatpak</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
            <citerefentry><refentrytitle>flatpak-permissions</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
            <citerefentry><refentrytitle>flatpak-permission-show</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
            <citerefentry><refentrytitle>flatpak-permission-reset</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
            <citerefentry><refentrytitle>flatpak-permission-set</refentrytitle><manvolnum>1</manvolnum></citerefentry>
        </para>

    </refsect1>

</refentry>

===== ./doc/flatpak-run.xml =====
<?xml version='1.0'?> <!--*-nxml-*-->
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
    "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">

<refentry id="flatpak-run">

    <refentryinfo>
        <title>flatpak run</title>
        <productname>flatpak</productname>

        <authorgroup>
            <author>
                <contrib>Developer</contrib>
                <firstname>Alexander</firstname>
                <surname>Larsson</surname>
                <email>alexl@redhat.com</email>
            </author>
        </authorgroup>
    </refentryinfo>

    <refmeta>
        <refentrytitle>flatpak run</refentrytitle>
        <manvolnum>1</manvolnum>
    </refmeta>

    <refnamediv>
        <refname>flatpak-run</refname>
        <refpurpose>Run an application or open a shell in a runtime</refpurpose>
    </refnamediv>

    <refsynopsisdiv>
            <cmdsynopsis>
                <command>flatpak run</command>
                <arg choice="opt" rep="repeat">OPTION</arg>
                <arg choice="plain">REF</arg>
                <arg choice="opt" rep="repeat">ARG</arg>
            </cmdsynopsis>
    </refsynopsisdiv>

    <refsect1>
        <title>Description</title>

        <para>
            If <arg choice="plain">REF</arg> names an installed application,
            Flatpak runs the application in a sandboxed environment. Extra
            arguments are passed on to the application. The current branch and arch of
            the application is used unless otherwise specified with <option>--branch</option>
            or <option>--arch</option>. See
            <citerefentry><refentrytitle>flatpak-make-current</refentrytitle><manvolnum>1</manvolnum></citerefentry>.
        </para>
        <para>
            If <arg choice="plain">REF</arg> names a runtime, a shell is opened in the
            runtime. This is useful for development and testing. If there is ambiguity about
            which branch to use, you will be prompted to choose. Use <option>--branch</option>
            to avoid this. The primary arch is used unless otherwise specified with
            <option>--arch</option>.
        </para>
        <para>
            By default, Flatpak will look for the application or runtime in the per-user
            installation first, then in all system installations. This can be overridden
            with the <option>--user</option>, <option>--system</option> and
            <option>--installation</option> options.
        </para>
        <para>
            Flatpak creates a sandboxed environment for the application to run in
            by mounting the right runtime at <filename>/usr</filename> and a writable
            directory at <filename>/var</filename>, whose content is preserved between
            application runs. The application itself is mounted at <filename>/app</filename>.
        </para>
        <para>
            The details of the sandboxed environment are controlled by the application
            metadata and various options like <option>--share</option> and <option>--socket</option>
            that are passed to the run command: Access is allowed if it was requested either
            in the application metadata file or with an option and the user hasn't overridden it.
        </para>
        <para>
            The remaining arguments are passed to the command that gets run in the sandboxed
            environment. See the <option>--file-forwarding</option> option for handling of file
            arguments.
        </para>
        <para>
            Environment variables are generally passed on to the sandboxed application, with
            certain exceptions, if <option>--clear-env</option> is not specified. The application
            metadata can override environment variables, as well as the <option>--env</option>
            option. Apart from that, Flatpak always unsets or overrides the following variables,
            since their session values are likely to interfere with the functioning of the sandbox:
        </para>
        <simplelist>
            <member>PATH</member>
            <member>LD_LIBRARY_PATH</member>
            <member>LD_PRELOAD</member>
            <member>LD_AUDIT</member>
            <member>XDG_CONFIG_DIRS</member>
            <member>XDG_DATA_DIRS</member>
            <member>SHELL</member>
            <member>TEMP</member>
            <member>TEMPDIR</member>
            <member>TMP</member>
            <member>TMPDIR</member>
            <member>XDG_RUNTIME_DIR</member>
            <member>container</member>
            <member>TZDIR</member>
            <member>PYTHONPATH</member>
            <member>PYTHONPYCACHEPREFIX</member>
            <member>PERLLIB</member>
            <member>PERL5LIB</member>
            <member>XCURSOR_PATH</member>
            <member>GST_PLUGIN_PATH_1_0</member>
            <member>GST_REGISTRY</member>
            <member>GST_REGISTRY_1_0</member>
            <member>GST_PLUGIN_PATH</member>
            <member>GST_PLUGIN_SYSTEM_PATH</member>
            <member>GST_PLUGIN_SCANNER</member>
            <member>GST_PLUGIN_SCANNER_1_0</member>
            <member>GST_PLUGIN_SYSTEM_PATH_1_0</member>
            <member>GST_PRESET_PATH</member>
            <member>GST_PTP_HELPER</member>
            <member>GST_PTP_HELPER_1_0</member>
            <member>GST_INSTALL_PLUGINS_HELPER</member>
            <member>KRB5CCNAME</member>
            <member>XKB_CONFIG_ROOT</member>
            <member>GIO_EXTRA_MODULES</member>
            <member>GDK_BACKEND</member>
            <member>VK_ADD_DRIVER_FILES</member>
            <member>VK_ADD_LAYER_PATH</member>
            <member>VK_DRIVER_FILES</member>
            <member>VK_ICD_FILENAMES</member>
            <member>VK_LAYER_PATH</member>
            <member>__EGL_EXTERNAL_PLATFORM_CONFIG_DIRS</member>
            <member>__EGL_EXTERNAL_PLATFORM_CONFIG_FILENAMES</member>
            <member>__EGL_VENDOR_LIBRARY_DIRS</member>
            <member>__EGL_VENDOR_LIBRARY_FILENAMES</member>
        </simplelist>
        <para>
            Also several environment variables with the prefix "GST_" that are used by gstreamer
            are unset (since Flatpak 1.12.5).
        </para>
        <para>
            Flatpak also overrides the XDG environment variables to point sandboxed applications
            at their writable filesystem locations below <filename>~/.var/app/$APPID/</filename>:
        </para>
        <simplelist>
            <member>XDG_DATA_HOME</member>
            <member>XDG_CONFIG_HOME</member>
            <member>XDG_CACHE_HOME</member>
            <member>XDG_STATE_HOME (since Flatpak 1.13)</member>
        </simplelist>
        <para>
            Apps can use the <option>--persist=.local/state</option> and
            <option>--unset-env=XDG_STATE_HOME</option> options to get a
            Flatpak 1.13-compatible <filename>~/.local/state</filename>
            on older versions of Flatpak.
        </para>
        <para>
            The host values of these variables are made available inside the sandbox via these
            HOST_-prefixed variables:
        </para>
        <simplelist>
            <member>HOST_XDG_DATA_HOME</member>
            <member>HOST_XDG_CONFIG_HOME</member>
            <member>HOST_XDG_CACHE_HOME</member>
            <member>HOST_XDG_STATE_HOME (since Flatpak 1.13)</member>
        </simplelist>
        <para>
            Flatpak sets the environment variable <envar>FLATPAK_ID</envar> to the application
            ID of the running app.
        </para>
        <para>
            Flatpak also bind-mounts as read-only the host's <filename>/etc/os-release</filename>
            (if available, or <filename>/usr/lib/os-release</filename> as a fallback) to
            <filename>/run/host/os-release</filename> in accordance with the
            <ulink url="https://www.freedesktop.org/software/systemd/man/os-release.html">
            os-release specification</ulink>.
        </para>
        <para>
            If parental controls support is enabled, flatpak will check the
            current user’s parental controls settings, and will refuse to
            run an app if it is blocklisted for the current user.
        </para>
    </refsect1>

    <refsect1>
        <title>Options</title>

        <para>The following options are understood:</para>

        <variablelist>
            <varlistentry>
                <term><option>-h</option></term>
                <term><option>--help</option></term>

                <listitem><para>
                    Show help options and exit.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>-u</option></term>
                <term><option>--user</option></term>

                <listitem><para>
                    Look for the application and runtime in per-user installations.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--system</option></term>

                <listitem><para>
                    Look for the application and runtime in the default system-wide installations.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--installation=NAME</option></term>

                <listitem><para>
                    Look for the application and runtime in the system-wide installation specified
                    by <arg choice="plain">NAME</arg>
                    among those defined in <filename>/etc/flatpak/installations.d/</filename>.
                    Using <option>--installation=default</option> is equivalent to using
                    <option>--system</option>.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>-v</option></term>
                <term><option>--verbose</option></term>

                <listitem><para>
                    Print debug information during command processing.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--ostree-verbose</option></term>

                <listitem><para>
                    Print OSTree debug information during command processing.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--arch=ARCH</option></term>

                <listitem><para>
                    The architecture to run. See <command>flatpak --supported-arches</command>
                    for architectures supported by the host.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--command=COMMAND</option></term>

                <listitem><para>
                    The command to run instead of the one listed in the application metadata.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--cwd=DIR</option></term>

                <listitem><para>
                    The directory to run the command in. Note that this must be a directory
                    inside the sandbox.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--branch=BRANCH</option></term>

                <listitem><para>
                    The branch to use.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>-d</option></term>
                <term><option>--devel</option></term>

                <listitem><para>
                    Use the devel runtime that is specified in the application metadata instead of the regular runtime, and use a seccomp profile that is less likely to break development tools.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--runtime=RUNTIME</option></term>

                <listitem><para>
                  Use this runtime instead of the one that is specified in the application metadata.
                  This is a full tuple, like for example <arg choice="plain">org.freedesktop.Sdk/x86_64/1.2</arg>, but
                  partial tuples are allowed. Any empty or missing parts are filled in with the corresponding
                  values specified by the app.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--runtime-version=VERSION</option></term>

                <listitem><para>
                  Use this version of the runtime instead of the one that is specified in the application metadata.
                  This overrides any version specified with the --runtime option.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--share=SUBSYSTEM</option></term>

                <listitem><para>
                    Share a subsystem with the host session. This overrides
                    the Context section from the application metadata.
                    <arg choice="plain">SUBSYSTEM</arg> must be one of: network, ipc.
                    This option can be used multiple times.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--unshare=SUBSYSTEM</option></term>

                <listitem><para>
                    Don't share a subsystem with the host session. This overrides
                    the Context section from the application metadata.
                    <arg choice="plain">SUBSYSTEM</arg> must be one of: network, ipc.
                    This option can be used multiple times.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--share-if=SUBSYSTEM:CONDITION</option></term>

                <listitem><para>
                    Share a subsystem with the host session conditionally,
                    only when the specified condition is met at runtime.
                    This overrides to the Context section from the application metadata.
                    <arg choice="plain">SUBSYSTEM</arg> must be one of: network, ipc.
                    <arg choice="plain">CONDITION</arg> must be one of:
                    <option>true</option>, <option>false</option>,
                    <option>has-input-device</option>, <option>has-wayland</option>,
                    <option>has-usb-device</option>, <option>has-usb-portal</option>.
                    Conditions can be negated with <literal>!</literal>,
                    for example <option>!has-input-device</option>.
                    This option can be used multiple times.
                    Available since 1.17.
                </para><para>
                    See the Conditional Permissions section in
                    <citerefentry><refentrytitle>flatpak-metadata</refentrytitle><manvolnum>5</manvolnum></citerefentry>
                    for more details.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--socket=SOCKET</option></term>

                <listitem><para>
                    Expose a well known socket to the application. This overrides to
                    the Context section from the application metadata.
                    <arg choice="plain">SOCKET</arg> must be one of: x11, wayland, fallback-x11, pulseaudio, system-bus, session-bus,
                    ssh-auth, pcsc, cups, gpg-agent, inherit-wayland-socket.
                    This option can be used multiple times.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--nosocket=SOCKET</option></term>

                <listitem><para>
                    Don't expose a well known socket to the application. This overrides to
                    the Context section from the application metadata.
                    <arg choice="plain">SOCKET</arg> must be one of: x11, wayland, fallback-x11, pulseaudio, system-bus, session-bus,
                    ssh-auth, pcsc, cups, gpg-agent, inherit-wayland-socket.
                    This option can be used multiple times.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--socket-if=SOCKET:CONDITION</option></term>

                <listitem><para>
                    Expose a well-known socket to the application conditionally,
                    only when the specified condition is met at runtime.
                    This overrides to the Context section from the application metadata.
                    <arg choice="plain">SOCKET</arg> must be one of: x11, wayland, fallback-x11, pulseaudio, system-bus, session-bus,
                    ssh-auth, pcsc, cups, gpg-agent, inherit-wayland-socket.
                    <arg choice="plain">CONDITION</arg> must be one of:
                    <option>true</option>, <option>false</option>,
                    <option>has-input-device</option>, <option>has-wayland</option>,
                    <option>has-usb-device</option>, <option>has-usb-portal</option>.
                    Conditions can be negated with <literal>!</literal>,
                    for example <option>!has-wayland</option>.
                    This option can be used multiple times.
                    Available since 1.17.
                </para><para>
                    See the Conditional Permissions section in
                    <citerefentry><refentrytitle>flatpak-metadata</refentrytitle><manvolnum>5</manvolnum></citerefentry>
                    for more details.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--device=DEVICE</option></term>

                <listitem><para>
                    Expose a device to the application. This overrides to
                    the Context section from the application metadata.
                    <arg choice="plain">DEVICE</arg> must be one of: dri, input, usb, kvm, shm, all.
                    This option can be used multiple times.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--nodevice=DEVICE</option></term>

                <listitem><para>
                    Don't expose a device to the application. This overrides to
                    the Context section from the application metadata.
                    <arg choice="plain">DEVICE</arg> must be one of: dri, input, usb, kvm, shm, all.
                    This option can be used multiple times.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--device-if=DEVICE:CONDITION</option></term>

                <listitem><para>
                    Expose a device to the application conditionally,
                    only when the specified condition is met at runtime.
                    This overrides to the Context section from the application metadata.
                    <arg choice="plain">DEVICE</arg> must be one of: dri, input, usb, kvm, shm, all.
                    <arg choice="plain">CONDITION</arg> must be one of:
                    <option>true</option>, <option>false</option>,
                    <option>has-input-device</option>, <option>has-wayland</option>,
                    <option>has-usb-device</option>, <option>has-usb-portal</option>.
                    Conditions can be negated with <literal>!</literal>,
                    for example <option>!has-input-device</option>.
                    This option can be used multiple times.
                    Available since 1.17.
                </para><para>
                    See the Conditional Permissions section in
                    <citerefentry><refentrytitle>flatpak-metadata</refentrytitle><manvolnum>5</manvolnum></citerefentry>
                    for more details.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--allow=FEATURE</option></term>

                <listitem><para>
                    Allow access to a specific feature. This overrides to
                    the Context section from the application metadata.
                    <arg choice="plain">FEATURE</arg> must be one of: devel, multiarch, bluetooth.
                    This option can be used multiple times.
                    </para><para>
                    See <citerefentry><refentrytitle>flatpak-build-finish</refentrytitle><manvolnum>1</manvolnum></citerefentry>
                    for the meaning of the various features.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--disallow=FEATURE</option></term>

                <listitem><para>
                    Disallow access to a specific feature. This overrides to
                    the Context section from the application metadata.
                    <arg choice="plain">FEATURE</arg> must be one of: devel, multiarch, bluetooth.
                    This option can be used multiple times.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--allow-if=FEATURE:CONDITION</option></term>

                <listitem><para>
                    Allow access to a specific feature conditionally,
                    only when the specified condition is met at runtime.
                    This overrides to the Context section from the application metadata.
                    <arg choice="plain">FEATURE</arg> must be one of: devel, multiarch, bluetooth.
                    <arg choice="plain">CONDITION</arg> must be one of:
                    <option>true</option>, <option>false</option>,
                    <option>has-input-device</option>, <option>has-wayland</option>,
                    <option>has-usb-device</option>, <option>has-usb-portal</option>.
                    Conditions can be negated with <literal>!</literal>,
                    for example <option>!has-input-device</option>.
                    This option can be used multiple times.
                    Available since 1.17.
                </para><para>
                    See the Conditional Permissions section in
                    <citerefentry><refentrytitle>flatpak-metadata</refentrytitle><manvolnum>5</manvolnum></citerefentry>
                    for more details.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--filesystem=FILESYSTEM</option></term>

                <listitem><para>
                    Allow the application access to a subset of the filesystem.
                    This overrides to the Context section from the application metadata.
                    <arg choice="plain">FILESYSTEM</arg> can be one of: home, host, host-os, host-etc, host-root, xdg-desktop, xdg-documents, xdg-download,
                    xdg-music, xdg-pictures, xdg-public-share, xdg-templates, xdg-videos,
                    xdg-run, xdg-config, xdg-cache, xdg-data,
                    an absolute path, or a homedir-relative path like ~/dir or paths
                    relative to the xdg dirs, like xdg-download/subdir.
                    The optional :ro suffix indicates that the location will be read-only.
                    The optional :create suffix indicates that the location will be read-write and created if it doesn't exist.
                    This option can be used multiple times.
                    See the "[Context] filesystems" list in
                    <citerefentry><refentrytitle>flatpak-metadata</refentrytitle><manvolnum>5</manvolnum></citerefentry>
                    for details of the meanings of these filesystems.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--nofilesystem=FILESYSTEM</option></term>

                <listitem><para>
                    Undo the effect of a previous
                    <option>--filesystem=</option><arg choice="plain">FILESYSTEM</arg>
                    in the app's manifest and/or the overrides set up with
                    <citerefentry><refentrytitle>flatpak-override</refentrytitle><manvolnum>1</manvolnum></citerefentry>.
                    This overrides the Context section of the
                    application metadata.
                    <arg choice="plain">FILESYSTEM</arg> can take the same
                    values as for <option>--filesystem</option>, but the
                    <arg choice="plain">:ro</arg> and
                    <arg choice="plain">:create</arg> suffixes are not
                    used here.
                    This option can be used multiple times.
                </para><para>
                    This option does not prevent access to a more
                    narrowly-scoped <option>--filesystem</option>.
                    For example, if an application has the equivalent of
                    <option>--filesystem=xdg-config/MyApp</option> in
                    its manifest or as a system-wide override, and
                    <literal>flatpak override --user --nofilesystem=home</literal>
                    as a per-user override, then it will be prevented from
                    accessing most of the home directory, but it will still
                    be allowed to access
                    <filename>$XDG_CONFIG_HOME/MyApp</filename>.
                </para><para>
                    As a special case,
                    <option>--nofilesystem=host:reset</option>
                    will ignore all <option>--filesystem</option>
                    permissions inherited from the app manifest or
                    <citerefentry><refentrytitle>flatpak-override</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
                    in addition to having the behaviour of
                    <option>--nofilesystem=host</option>.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--add-policy=SUBSYSTEM.KEY=VALUE</option></term>

                <listitem><para>
                    Add generic policy option. For example, "--add-policy=subsystem.key=v1 --add-policy=subsystem.key=v2" would map to this metadata:
<programlisting>
[Policy subsystem]
key=v1;v2;
</programlisting>
                </para><para>
                    This option can be used multiple times.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--remove-policy=SUBSYSTEM.KEY=VALUE</option></term>

                <listitem><para>
                    Remove generic policy option. This option can be used multiple times.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--usb=TYPE[:DATA]</option></term>

                <listitem><para>
                    Adds a USB device query to the application metadata. This
                    allows device enumeration and usage by the USB portal.
                    <arg choice="plain">TYPE</arg> must be one of: all, cls, dev, vnd.
                </para><variablelist>
                    <varlistentry>
                        <term><option>all</option></term>

                        <listitem><para>
                            Match all devices.
                        </para></listitem>
                    </varlistentry>

                    <varlistentry>
                        <term><option>cls</option></term>

                        <listitem><para>
                            A device class and subclass query. <arg choice="plain">DATA</arg>
                            must be in the form of <arg choice="plain">CLASS:SUBCLASS</arg> where
                            both <arg choice="plain">CLASS</arg> and <arg choice="plain">SUBCLASS</arg>
                            must be a valid 2-digit hexadecimal class id number. Alternatively,
                            <arg choice="plain">SUBCLASS</arg> may be <literal>*</literal> to match
                            all subclasses.
                        </para></listitem>
                    </varlistentry>

                    <varlistentry>
                        <term><option>dev</option></term>

                        <listitem><para>
                            A device product id query. <arg choice="plain">DATA</arg>
                            must be a valid 4-digit hexadecimal product id number,
                            for example <option>0a1b</option>. It requires a
                            <option>vnd</option> filter in the query.
                        </para></listitem>
                    </varlistentry>

                    <varlistentry>
                        <term><option>vnd</option></term>

                        <listitem><para>
                            A device vendor id query. <arg choice="plain">DATA</arg>
                            must be a valid 4-digit hexadecimal vendor id number
                            greater than zero, for example <option>0fab</option>.
                        </para></listitem>
                    </varlistentry>

                </variablelist><para>
                    It is possible to compose multiple device queries together
                    with the <literal>+</literal> sign, for example
                    <option>--usb=vnd:0123+dev:4567</option>. The <arg choice="plain">dev</arg>
                    filter requires a <arg choice="plain">vnd</arg>.
                    Available since 1.15.11.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--nousb=VENDOR_ID:PRODUCT_ID</option></term>

                <listitem><para>
                    Adds a blocking USB device query to the application metadata. Blocked
                    devices take precedence over allowed devices. The syntax is exactly
                    equal to <option>--usb</option>.
                    Available since 1.15.11.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--env=VAR=VALUE</option></term>

                <listitem><para>
                    Set an environment variable in the application.
                    This overrides to the Context section from the application metadata.
                    This option can be used multiple times.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--unset-env=VAR</option></term>

                <listitem><para>
                    Unset an environment variable in the application.
                    This overrides the unset-environment entry in the [Context]
                    group of the metadata, and the [Environment] group.
                    This option can be used multiple times.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--env-fd=<replaceable>FD</replaceable></option></term>

                <listitem><para>
                    Read environment variables from the file descriptor
                    <replaceable>FD</replaceable>, and set them as if
                    via <option>--env</option>. This can be used to avoid
                    environment variables and their values becoming visible
                    to other users.
                </para><para>
                    Each environment variable is in the form
                    <replaceable>VAR</replaceable>=<replaceable>VALUE</replaceable>
                    followed by a zero byte. This is the same format used by
                    <literal>env -0</literal> and
                    <filename>/proc/*/environ</filename>.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--clear-env</option></term>

                <listitem><para>
                    Do not pass environment variables from the outside to the
                    sandboxed application. Explicitly set and unset environment
                    variables still get applied.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--own-name=NAME</option></term>

                <listitem><para>
                    Allow the application to own the well known name <arg choice="plain">NAME</arg> on the session bus.
                    If <arg choice="plain">NAME</arg> ends with .*, it allows the application to own all matching names.
                    This overrides to the Context section from the application metadata.
                    This option can be used multiple times.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--talk-name=NAME</option></term>

                <listitem><para>
                    Allow the application to talk to the well known name <arg choice="plain">NAME</arg> on the session bus.
                    If <arg choice="plain">NAME</arg> ends with .*, it allows the application to talk to all matching names.
                    This overrides to the Context section from the application metadata.
                    This option can be used multiple times.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--no-talk-name=NAME</option></term>

                <listitem><para>
                    Don't allow the application to talk to the well known name <arg choice="plain">NAME</arg> on the session bus.
                    If <arg choice="plain">NAME</arg> ends with .*, it allows the application to talk to all matching names.
                    This overrides to the Context section from the application metadata.
                    This option can be used multiple times.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--system-own-name=NAME</option></term>

                <listitem><para>
                    Allow the application to own the well known name <arg choice="plain">NAME</arg> on the system bus.
                    If <arg choice="plain">NAME</arg> ends with .*, it allows the application to own all matching names.
                    This overrides to the Context section from the application metadata.
                    This option can be used multiple times.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--system-talk-name=NAME</option></term>

                <listitem><para>
                    Allow the application to talk to the well known name <arg choice="plain">NAME</arg> on the system bus.
                    If <arg choice="plain">NAME</arg> ends with .*, it allows the application to talk to all matching names.
                    This overrides to the Context section from the application metadata.
                    This option can be used multiple times.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--system-no-talk-name=NAME</option></term>

                <listitem><para>
                    Don't allow the application to talk to the well known name <arg choice="plain">NAME</arg> on the system bus.
                    If <arg choice="plain">NAME</arg> ends with .*, it allows the application to talk to all matching names.
                    This overrides to the Context section from the application metadata.
                    This option can be used multiple times.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--a11y-own-name=NAME</option></term>

                <listitem><para>
                    Allow the application to own the well known name <arg choice="plain">NAME</arg> on the a11y bus.
                    If <arg choice="plain">NAME</arg> ends with .*, it allows the application to own all matching names.
                    This overrides to the Context section from the application metadata.
                    This option can be used multiple times.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--persist=FILENAME</option></term>

                <listitem><para>
                    If the application doesn't have access to the real homedir, make the (homedir-relative) path
                    <arg choice="plain">FILENAME</arg> a bind mount to the corresponding path in the per-application directory,
                    allowing that location to be used for persistent data.
                    This overrides to the Context section from the application metadata.
                    This option can be used multiple times.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--no-session-bus</option></term>

                <listitem><para>
                    Run this instance without the filtered access to the session dbus connection. Note, this is the default when run with --sandbox.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--session-bus</option></term>

                <listitem><para>
                  Allow filtered access to the session dbus connection. This is the default, except when run with --sandbox.
                  </para><para>
                  In sandbox mode, even if you allow access to the session bus the sandbox cannot talk to or own
                  the application ids (org.the.App.*) on the bus (unless explicitly added), only names in the
                  .Sandboxed subset (org.the.App.Sandboxed.* and org.mpris.MediaPlayer2.org.the.App.Sandboxed.*).
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--no-a11y-bus</option></term>

                <listitem><para>
                    Run this instance without the access to the accessibility bus. Note, this is the default when run with --sandbox.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--a11y-bus</option></term>

                <listitem><para>
                    Allow access to the accessibility bus. This is the default, except when run with --sandbox.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--sandbox</option></term>

                <listitem><para>
                  Run the application in sandboxed mode, which means dropping all the extra permissions it would otherwise have, as
                  well as access to the session/system/a11y buses and document portal.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--log-session-bus</option></term>

                <listitem><para>
                    Log session bus traffic. This can be useful to see what access you need to allow in
                    your D-Bus policy.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--log-system-bus</option></term>

                <listitem><para>
                    Log system bus traffic. This can be useful to see what access you need to allow in
                    your D-Bus policy.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>-p</option></term>
                <term><option>--die-with-parent</option></term>

                <listitem><para>
                    Kill the entire sandbox when the launching process dies.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--parent-pid=PID</option></term>

                <listitem><para>
                    Specifies the pid of the "parent" flatpak, used by
                    --parent-expose-pids and --parent-share-pids.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--parent-expose-pids</option></term>

                <listitem><para>
                    Make the processes of the new sandbox visible in the sandbox of the parent flatpak, as defined
                    by --parent-pid.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--parent-share-pids</option></term>

                <listitem><para>
                    Use the same process ID namespace for the processes of
                    the new sandbox and the sandbox of the parent flatpak, as
                    defined by --parent-pid. Implies --parent-expose-pids.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--instance-id-fd</option></term>

                <listitem><para>
                    Write the instance ID string to the given file descriptor.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--file-forwarding</option></term>

                <listitem><para>
                    If this option is specified, the remaining arguments are scanned, and all arguments
                    that are enclosed between a pair of '@@' arguments are interpreted as file paths,
                    exported in the document store, and passed to the command in the form of the
                    resulting document path. Arguments between "@@u" and "@@" are considered URIs,
                    and any "file:" URIs are exported. The exports are non-persistent and with read and write
                    permissions for the application.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--app-path=<replaceable>PATH</replaceable></option></term>
                <listitem><para>
                    Instead of mounting the app's content on
                    <filename>/app</filename> in the sandbox, mount
                    <replaceable>PATH</replaceable> on <filename>/app</filename>,
                    and the app's content on
                    <filename>/run/parent/app</filename>.
                    If the app has extensions, they will also be redirected
                    into <filename>/run/parent/app</filename>, and will not
                    be included in the <envar>LD_LIBRARY_PATH</envar> inside
                    the sandbox.
                </para></listitem>
            </varlistentry>
            <varlistentry>
                <term><option>--app-path=</option></term>
                <listitem><para>
                    As a special case, <option>--app-path=</option>
                    (with an empty <replaceable>PATH</replaceable>)
                    results in an empty directory being mounted on
                    <filename>/app</filename>.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--usr-path=<replaceable>PATH</replaceable></option></term>
                <listitem><para>
                    Instead of mounting the runtime's files on
                    <filename>/usr</filename> in the sandbox, mount
                    <replaceable>PATH</replaceable> on
                    <filename>/usr</filename>,
                    and the runtime's normal files on
                    <filename>/run/parent/usr</filename>.
                    If the runtime has extensions, they will also be redirected
                    into <filename>/run/parent/usr</filename>, and will not
                    be included in the <envar>LD_LIBRARY_PATH</envar> inside
                    the sandbox.
                </para><para>
                    This option will usually only be useful if it is
                    combined with <option>--app-path=</option> and
                    <option>--env=LD_LIBRARY_PATH=<replaceable>...</replaceable></option>.
                </para></listitem>
            </varlistentry>

        </variablelist>

    </refsect1>

    <refsect1>
        <title>Examples</title>

        <para>
            <command>$ flatpak run org.gnome.gedit</command>
        </para>
        <para>
            <command>$ flatpak run --devel --command=bash org.gnome.Builder</command>
        </para>
        <para>
            <command>$ flatpak run --command=bash org.gnome.Sdk</command>
        </para>
        <para>
            <command>$ flatpak run org.gnome.Boxes --nousb=0fd9:*</command>
        </para>

    </refsect1>

    <refsect1>
        <title>See also</title>

        <para>
            <citerefentry><refentrytitle>flatpak</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
            <citerefentry><refentrytitle>flatpak-override</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
            <citerefentry><refentrytitle>flatpak-enter</refentrytitle><manvolnum>1</manvolnum></citerefentry>
        </para>

    </refsect1>

</refentry>

===== ./doc/flatpak.xml =====
<?xml version='1.0'?> <!--*-nxml-*-->
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
    "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">

<refentry id="flatpak">

    <refentryinfo>
        <title>flatpak</title>
        <productname>flatpak</productname>

        <authorgroup>
            <author>
                <contrib>Developer</contrib>
                <firstname>Alexander</firstname>
                <surname>Larsson</surname>
                <email>alexl@redhat.com</email>
            </author>
        </authorgroup>
    </refentryinfo>

    <refmeta>
        <refentrytitle>flatpak</refentrytitle>
        <manvolnum>1</manvolnum>
    </refmeta>

    <refnamediv>
        <refname>flatpak</refname>
        <refpurpose>Build, install and run applications and runtimes</refpurpose>
    </refnamediv>

    <refsynopsisdiv>
            <cmdsynopsis>
                <command>flatpak</command>
                <arg choice="opt" rep="repeat">OPTION</arg>
                <arg choice="req">COMMAND</arg>
            </cmdsynopsis>
    </refsynopsisdiv>

    <refsect1>
        <title>Description</title>

        <para>
            Flatpak is a tool for managing applications and the runtimes
            they use. In the Flatpak model, applications can be built and
            distributed independently from the host system they are used
            on, and they are isolated from the host system ('sandboxed')
            to some degree, at runtime.
        </para>

        <para>
            Flatpak can operate in system-wide or per-user mode. The system-wide
            data (runtimes, applications and configuration) is located in
            <filename>$prefix/var/lib/flatpak/</filename>, and the per-user
            data is in <filename>$HOME/.local/share/flatpak/</filename>.
            Below these locations, there is a local repository in the
            <filename>repo/</filename> subdirectory and installed runtimes
            and applications are in the corresponding <filename>runtime/</filename>
            and <filename>app/</filename> subdirectories.
        </para>

       <para>
            System-wide remotes can be statically preconfigured by dropping
            <citerefentry><refentrytitle>flatpakrepo</refentrytitle><manvolnum>5</manvolnum></citerefentry>
            files into <filename>/usr/share/flatpak/remotes.d/</filename> and
            <filename>/etc/flatpak/remotes.d/</filename>. If a file with
            the same name exists in both, the file under
            <filename>/etc</filename> will take precedence.
       </para>

        <para>
            In addition to the system-wide installation in <filename>$prefix/var/lib/flatpak/</filename>,
            which is always considered the default one unless overridden, more
            system-wide installations can be defined via configuration files in
            <filename>/etc/flatpak/installations.d/</filename>, which must define
            at least the id of the installation and the absolute path to it.
            Other optional parameters like <arg choice="plain">DisplayName</arg>,
            <arg choice="plain">Priority</arg> or <arg choice="plain">StorageType</arg>
            are also supported.
        </para>

        <para>
            Flatpak uses OSTree to distribute and deploy data. The repositories
            it uses are OSTree repositories and can be manipulated with the
            <command>ostree</command> utility. Installed runtimes and
            applications are OSTree checkouts.
        </para>

        <para>
            Basic commands for building flatpaks such as build-init, build and build-finish
            are included in the flatpak utility. For higher-level build support, see
            the separate 
            <citerefentry><refentrytitle>flatpak-builder</refentrytitle><manvolnum>1</manvolnum></citerefentry> tool.
        </para>

        <para>
            Flatpak supports installing from sideload repos. These are partial
            copies of a repository (generated by <command>flatpak create-usb</command>) that are used as
            an installation source when offline (and online as a performance improvement).
            Such repositories are configured by creating symlinks to the sideload sources
            in the <filename>sideload-repos</filename>  subdirectory of the installation directory (i.e. typically
            <filename>/var/lib/flatpak/sideload-repos</filename> or
            <filename>~/.local/share/flatpak/sideload-repos</filename>). Additionally
            symlinks can be created in <filename>/run/flatpak/sideload-repos</filename>
            which is a better location for non-persistent sources (as it is cleared on reboot). These symlinks
            can point to either the directory given to <command>flatpak create-usb</command> which by default
            writes to the subpath <filename>.ostree/repo</filename>, or directly to an ostree repo.
        </para>

    </refsect1>

    <refsect1>
        <title>Options</title>

        <para>
            The following global options are understood. Individual commands have their
            own options.
        </para>

        <variablelist>
            <varlistentry>
                <term><option>-h</option></term>
                <term><option>--help</option></term>

                <listitem><para>
                    Show help options and exit.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>-v</option></term>
                <term><option>--verbose</option></term>

                <listitem><para>
                    Show debug information during command processing. Use -vv for more detail.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--ostree-verbose</option></term>

                <listitem><para>
                    Show OSTree debug information during command processing.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--version</option></term>

                <listitem><para>
                    Print version information and exit.
                </para></listitem>
            </varlistentry>

           <varlistentry>
                <term><option>--default-arch</option></term>

                <listitem><para>
                    Print the default arch and exit.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--supported-arches</option></term>

                <listitem><para>
                    Print the supported arches in priority order and exit.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--gl-drivers</option></term>

                <listitem><para>
                    Print the list of active gl drivers and exit.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--installations</option></term>

                <listitem><para>
                    Print paths of system installations and exit.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--print-system-only</option></term>

                <listitem><para>
                    When the <command>flatpak --print-updated-env</command>
                    command is run, only print the environment for system
                    flatpak installations, not including the user’s home
                    installation.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--print-updated-env</option></term>

                <listitem><para>
                    Print the set of environment variables needed to use
                    flatpaks, amending the current set of environment variables.
                    This is intended to be used in a systemd environment
                    generator, and should not need to be run manually.
                </para></listitem>
            </varlistentry>

        </variablelist>
    </refsect1>

    <refsect1>
        <title>Commands</title>

        <para>Commands for managing installed applications and runtimes:</para>

        <variablelist>
            <varlistentry>
                <term><citerefentry><refentrytitle>flatpak-install</refentrytitle><manvolnum>1</manvolnum></citerefentry></term>

                <listitem><para>
                    Install an application or a runtime from a remote or bundle.
                </para></listitem>
            </varlistentry>
            <varlistentry>
                <term><citerefentry><refentrytitle>flatpak-update</refentrytitle><manvolnum>1</manvolnum></citerefentry></term>

                <listitem><para>
                    Update an installed application or runtime.
                </para></listitem>
            </varlistentry>
            <varlistentry>
                <term><citerefentry><refentrytitle>flatpak-uninstall</refentrytitle><manvolnum>1</manvolnum></citerefentry></term>

                <listitem><para>
                    Uninstall an installed application or runtime.
                </para></listitem>
            </varlistentry>
            <varlistentry>
                <term><citerefentry><refentrytitle>flatpak-mask</refentrytitle><manvolnum>1</manvolnum></citerefentry></term>

                <listitem><para>
                    Mask out updates and automatic installation.
                </para></listitem>
            </varlistentry>
            <varlistentry>
                <term><citerefentry><refentrytitle>flatpak-pin</refentrytitle><manvolnum>1</manvolnum></citerefentry></term>

                <listitem><para>
                    Pin runtimes to prevent automatic removal.
                </para></listitem>
            </varlistentry>
            <varlistentry>
                <term><citerefentry><refentrytitle>flatpak-list</refentrytitle><manvolnum>1</manvolnum></citerefentry></term>

                <listitem><para>
                    List installed applications and/or runtimes.
                </para></listitem>
            </varlistentry>
            <varlistentry>
                <term><citerefentry><refentrytitle>flatpak-info</refentrytitle><manvolnum>1</manvolnum></citerefentry></term>

                <listitem><para>
                    Show information for an installed application or runtime.
                </para></listitem>
            </varlistentry>
            <varlistentry>
                <term><citerefentry><refentrytitle>flatpak-history</refentrytitle><manvolnum>1</manvolnum></citerefentry></term>

                <listitem><para>
                    Show history.
                </para></listitem>
            </varlistentry>
            <varlistentry>
                <term><citerefentry><refentrytitle>flatpak-config</refentrytitle><manvolnum>1</manvolnum></citerefentry></term>

                <listitem><para>
                    Manage flatpak configuration.
                </para></listitem>
            </varlistentry>
            <varlistentry>
                <term><citerefentry><refentrytitle>flatpak-repair</refentrytitle><manvolnum>1</manvolnum></citerefentry></term>

                <listitem><para>
                    Repair flatpak installation.
                </para></listitem>
            </varlistentry>
            <varlistentry>
                <term><citerefentry><refentrytitle>flatpak-create-usb</refentrytitle><manvolnum>1</manvolnum></citerefentry></term>

                <listitem><para>
                    Copy apps and/or runtimes onto removable media.
                </para></listitem>
            </varlistentry>
        </variablelist>


        <para>Commands for finding applications and runtimes:</para>

        <variablelist>
            <varlistentry>
                <term><citerefentry><refentrytitle>flatpak-search</refentrytitle><manvolnum>1</manvolnum></citerefentry></term>

                <listitem><para>
                    Search for applications and runtimes.
                </para></listitem>
            </varlistentry>
        </variablelist>


        <para>Commands for managing running applications:</para>

        <variablelist>
            <varlistentry>
                <term><citerefentry><refentrytitle>flatpak-run</refentrytitle><manvolnum>1</manvolnum></citerefentry></term>

                <listitem><para>
                    Run an application.
                </para></listitem>
            </varlistentry>
            <varlistentry>
                <term><citerefentry><refentrytitle>flatpak-kill</refentrytitle><manvolnum>1</manvolnum></citerefentry></term>

                <listitem><para>
                    Stop a running application.
                </para></listitem>
            </varlistentry>
            <varlistentry>
                <term><citerefentry><refentrytitle>flatpak-override</refentrytitle><manvolnum>1</manvolnum></citerefentry></term>

                <listitem><para>
                    Override permissions for an application.
                </para></listitem>
            </varlistentry>
            <varlistentry>
                <term><citerefentry><refentrytitle>flatpak-make-current</refentrytitle><manvolnum>1</manvolnum></citerefentry></term>

                <listitem><para>
                    Specify the default version to run.
                </para></listitem>
            </varlistentry>
            <varlistentry>
                <term><citerefentry><refentrytitle>flatpak-enter</refentrytitle><manvolnum>1</manvolnum></citerefentry></term>

                <listitem><para>
                    Enter the namespace of a running application.
                </para></listitem>
            </varlistentry>
        </variablelist>

        <para>Commands for managing file access:</para>

        <variablelist>
            <varlistentry>
                <term><citerefentry><refentrytitle>flatpak-document-export</refentrytitle><manvolnum>1</manvolnum></citerefentry></term>

                <listitem><para>
                    Grant an application access to a specific file.
                </para></listitem>
            </varlistentry>
            <varlistentry>
                <term><citerefentry><refentrytitle>flatpak-document-unexport</refentrytitle><manvolnum>1</manvolnum></citerefentry></term>

                <listitem><para>
                    Revoke access to a specific file.
                </para></listitem>
            </varlistentry>
            <varlistentry>
                <term><citerefentry><refentrytitle>flatpak-document-info</refentrytitle><manvolnum>1</manvolnum></citerefentry></term>

                <listitem><para>
                    Show information about a specific file.
                </para></listitem>
            </varlistentry>
            <varlistentry>
                <term><citerefentry><refentrytitle>flatpak-documents</refentrytitle><manvolnum>1</manvolnum></citerefentry></term>

                <listitem><para>
                    List exported files.
                </para></listitem>
            </varlistentry>
        </variablelist>

        <para>Commands for managing the dynamic permission store:</para>

        <variablelist>
            <varlistentry>
                <term><citerefentry><refentrytitle>flatpak-permission-remove</refentrytitle><manvolnum>1</manvolnum></citerefentry></term>

                <listitem><para>
                    Remove item from permission store.
                </para></listitem>
            </varlistentry>
            <varlistentry>
                <term><citerefentry><refentrytitle>flatpak-permissions</refentrytitle><manvolnum>1</manvolnum></citerefentry></term>

                <listitem><para>
                    List permissions.
                </para></listitem>
            </varlistentry>
            <varlistentry>
                <term><citerefentry><refentrytitle>flatpak-permission-show</refentrytitle><manvolnum>1</manvolnum></citerefentry></term>

                <listitem><para>
                    Show app permissions.
                </para></listitem>
            </varlistentry>
            <varlistentry>
                <term><citerefentry><refentrytitle>flatpak-permission-reset</refentrytitle><manvolnum>1</manvolnum></citerefentry></term>

                <listitem><para>
                    Reset app permissions.
                </para></listitem>
            </varlistentry>
            <varlistentry>
                <term><citerefentry><refentrytitle>flatpak-permission-set</refentrytitle><manvolnum>1</manvolnum></citerefentry></term>

                <listitem><para>
                    Set app permissions.
                </para></listitem>
            </varlistentry>
        </variablelist>

        <para>Commands for managing remote repositories:</para>

        <variablelist>
            <varlistentry>
                <term><citerefentry><refentrytitle>flatpak-remotes</refentrytitle><manvolnum>1</manvolnum></citerefentry></term>

                <listitem><para>
                    List all configured remote repositories.
                </para></listitem>
            </varlistentry>
            <varlistentry>
                <term><citerefentry><refentrytitle>flatpak-remote-add</refentrytitle><manvolnum>1</manvolnum></citerefentry></term>

                <listitem><para>
                    Add a new remote repository.
                </para></listitem>
            </varlistentry>
            <varlistentry>
                <term><citerefentry><refentrytitle>flatpak-remote-modify</refentrytitle><manvolnum>1</manvolnum></citerefentry></term>

                <listitem><para>
                    Modify properties of a configured remote repository.
                </para></listitem>
            </varlistentry>
            <varlistentry>
                <term><citerefentry><refentrytitle>flatpak-remote-delete</refentrytitle><manvolnum>1</manvolnum></citerefentry></term>

                <listitem><para>
                    Delete a configured remote repository.
                </para></listitem>
            </varlistentry>
            <varlistentry>
                <term><citerefentry><refentrytitle>flatpak-remote-ls</refentrytitle><manvolnum>1</manvolnum></citerefentry></term>

                <listitem><para>
                    List contents of a configured remote repository.
                </para></listitem>
            </varlistentry>
            <varlistentry>
                <term><citerefentry><refentrytitle>flatpak-remote-info</refentrytitle><manvolnum>1</manvolnum></citerefentry></term>

                <listitem><para>
                    Show information about a ref in a configured remote repository.
                </para></listitem>
            </varlistentry>
        </variablelist>

        <para>Commands for building applications:</para>

        <variablelist>
            <varlistentry>
                <term><citerefentry><refentrytitle>flatpak-build-init</refentrytitle><manvolnum>1</manvolnum></citerefentry></term>

                <listitem><para>
                    Initialize a build directory.
                </para></listitem>
            </varlistentry>
            <varlistentry>
                <term><citerefentry><refentrytitle>flatpak-build</refentrytitle><manvolnum>1</manvolnum></citerefentry></term>

                <listitem><para>
                    Run a build command in a build directory.
                </para></listitem>
            </varlistentry>
            <varlistentry>
                <term><citerefentry><refentrytitle>flatpak-build-finish</refentrytitle><manvolnum>1</manvolnum></citerefentry></term>

                <listitem><para>
                    Finalizes a build directory for export.
                </para></listitem>
            </varlistentry>
            <varlistentry>
                <term><citerefentry><refentrytitle>flatpak-build-export</refentrytitle><manvolnum>1</manvolnum></citerefentry></term>

                <listitem><para>
                    Export a build directory to a repository.
                </para></listitem>
            </varlistentry>
            <varlistentry>
                <term><citerefentry><refentrytitle>flatpak-build-bundle</refentrytitle><manvolnum>1</manvolnum></citerefentry></term>

                <listitem><para>
                    Create a bundle file from a ref in a local repository.
                </para></listitem>
            </varlistentry>
            <varlistentry>
                <term><citerefentry><refentrytitle>flatpak-build-import-bundle</refentrytitle><manvolnum>1</manvolnum></citerefentry></term>

                <listitem><para>
                    Import a file bundle into a local repository.
                </para></listitem>
            </varlistentry>
            <varlistentry>
                <term><citerefentry><refentrytitle>flatpak-build-sign</refentrytitle><manvolnum>1</manvolnum></citerefentry></term>

                <listitem><para>
                    Sign an application or runtime after its been exported.
                </para></listitem>
            </varlistentry>
            <varlistentry>
                <term><citerefentry><refentrytitle>flatpak-build-update-repo</refentrytitle><manvolnum>1</manvolnum></citerefentry></term>

                <listitem><para>
                    Update the summary file in a repository.
                </para></listitem>
            </varlistentry>
            <varlistentry>
                <term><citerefentry><refentrytitle>flatpak-build-commit-from</refentrytitle><manvolnum>1</manvolnum></citerefentry></term>

                <listitem><para>
                    Create a new commit based on an existing ref.
                </para></listitem>
            </varlistentry>
            <varlistentry>
                <term><citerefentry><refentrytitle>flatpak-repo</refentrytitle><manvolnum>1</manvolnum></citerefentry></term>

                <listitem><para>
                    Print information about a repo.
                </para></listitem>
            </varlistentry>
        </variablelist>

        <para>Commands available inside the sandbox:</para>

        <variablelist>
            <varlistentry>
                <term><citerefentry><refentrytitle>flatpak-spawn</refentrytitle><manvolnum>1</manvolnum></citerefentry></term>

                <listitem><para>
                    Run a command in another sandbox.
                </para></listitem>
            </varlistentry>
        </variablelist>

    </refsect1>

    <refsect1>
        <title>File formats</title>

        <para>File formats that are used by Flatpak commands:</para>

        <variablelist>
            <varlistentry>
                <term><citerefentry><refentrytitle>flatpakref</refentrytitle><manvolnum>5</manvolnum></citerefentry></term>

                <listitem><para>
                    Reference to a remote for an application or runtime
                </para></listitem>
            </varlistentry>
            <varlistentry>
                <term><citerefentry><refentrytitle>flatpakrepo</refentrytitle><manvolnum>5</manvolnum></citerefentry></term>

                <listitem><para>
                    Reference to a remote
                </para></listitem>
            </varlistentry>
            <varlistentry>
                <term><citerefentry><refentrytitle>flatpak-remote</refentrytitle><manvolnum>5</manvolnum></citerefentry></term>

                <listitem><para>
                    Configuration for a remote 
                </para></listitem>
            </varlistentry>
            <varlistentry>
                <term><citerefentry><refentrytitle>flatpak-installation</refentrytitle><manvolnum>5</manvolnum></citerefentry></term>

                <listitem><para>
                    Configuration for an installation location
                </para></listitem>
            </varlistentry>
            <varlistentry>
                <term><citerefentry><refentrytitle>flatpak-metadata</refentrytitle><manvolnum>5</manvolnum></citerefentry></term>

                <listitem><para>
                    Information about an application or runtime
                </para></listitem>
            </varlistentry>
        </variablelist>
    </refsect1>

    <refsect1>
        <title>Environment</title>
            <para>
              Besides standard environment variables such as <envar>XDG_DATA_DIRS</envar> and
              <envar>XDG_DATA_HOME</envar>, flatpak consults some of its own.
            </para>
            <variablelist>
                <!-- Please keep these in alphabetical order -->

                <!-- FLATPAK intentionally not documented:
                     it is intended for testing and development only
                     (it is the flatpak executable used by the
                     flatpak-portal) -->

                <varlistentry>
                    <term><envar>FLATPAK_BINARY</envar></term>
                    <listitem><para>
                        Path to the flatpak executable that will be written
                        into exported <filename>.desktop</filename> files
                        and scripts when an app is installed.
                        The default is <filename>/usr/bin/flatpak</filename>,
                        unless overridden at build time by
                        <option>--bindir</option>.
                    </para></listitem>
                </varlistentry>

                <varlistentry>
                    <term><envar>FLATPAK_BWRAP</envar></term>

                    <listitem><para>
                        Path to the
                        <citerefentry><refentrytitle>bwrap</refentrytitle><manvolnum>1</manvolnum></citerefentry>
                        executable that will be used to create the sandbox.
                        Depending on how Flatpak was configured at build-time,
                        the default is either to search the
                        <envar>PATH</envar>,
                        or use a vendored copy which is normally installed as
                        <filename>/usr/libexec/flatpak-bwrap</filename>.
                    </para></listitem>
                </varlistentry>

                <varlistentry>
                    <term><envar>FLATPAK_CONFIG_DIR</envar></term>

                    <listitem><para>
                      The location of flatpak site configuration. If this is not set,
                      <filename>/etc/flatpak</filename> is used (unless overridden at build
                      time by --sysconfdir).
                    </para></listitem>
                </varlistentry>

                <varlistentry>
                    <term><envar>FLATPAK_DATA_DIR</envar></term>
                    <listitem><para>
                        The location of Flatpak's OS-level defaults and
                        integration hooks.
                        If this is not set,
                        <filename>/usr/share/flatpak</filename> is used,
                        unless overridden at build time by
                        <option>--datadir</option>.
                    </para></listitem>
                </varlistentry>

                <varlistentry>
                    <term><envar>FLATPAK_DBUSPROXY</envar></term>

                    <listitem><para>
                        Path to the
                        <citerefentry><refentrytitle>xdg-dbus-proxy</refentrytitle><manvolnum>1</manvolnum></citerefentry>
                        executable that will be used to filter D-Bus
                        traffic between the sandbox and the host system.
                        Depending on how Flatpak was configured at build-time,
                        the default is either to search the
                        <envar>PATH</envar>,
                        or use a vendored copy which is normally installed as
                        <filename>/usr/libexec/flatpak-dbus-proxy</filename>.
                    </para></listitem>
                </varlistentry>

                <!-- FLATPAK_DISABLE_REVOKEFS intentionally not documented:
                     it is intended for testing and development only
                     (it forces use of the code path we would use if
                     FUSE didn't work) -->

                <varlistentry>
                    <term><envar>FLATPAK_DOWNLOAD_TMPDIR</envar></term>
                    <listitem><para>
                        Path to a directory that will be used temporarily
                        when downloading OCI layers,
                        and potentially for other downloads in future.
                        The standard <envar>TMPDIR</envar> is not used
                        for this,
                        because Flatpak apps are frequently too large to
                        fit on a tmpfs.
                    </para></listitem>
                </varlistentry>

                <varlistentry>
                    <term><envar>FLATPAK_FANCY_OUTPUT</envar></term>
                    <listitem><para>
                        May be set to <literal>0</literal> to avoid fancy
                        formatting when outputting to a terminal.
                        This feature is also disabled automatically when
                        standard output is not a terminal,
                        or when <envar>G_MESSAGES_DEBUG</envar> is set.
                    </para></listitem>
                </varlistentry>

                <!-- FLATPAK_FORCE_ALLOW_FUZZY_MATCHING intentionally not documented:
                     it is intended for testing and development only
                     (it forces use of the fuzzy matching code path that
                     we would normally only use when run on a tty) -->

                <varlistentry>
                    <term><envar>FLATPAK_FORCE_TEXT_AUTH</envar></term>
                    <listitem><para>
                        May be set to <literal>1</literal> to force use of
                        a simple built-in
                        <citerefentry><refentrytitle>polkit</refentrytitle><manvolnum>8</manvolnum></citerefentry>
                        agent when authentication is required to modify
                        the system-wide installation.
                        By default,
                        the desktop environment's polkit agent is used,
                        if one is available,
                        usually resulting in a graphical prompt.
                    </para></listitem>
                </varlistentry>

                <varlistentry>
                    <term><envar>FLATPAK_GL_DRIVERS</envar></term>
                    <listitem><para>
                        A colon-separated list of graphics driver extensions
                        to try to use for OpenGL, Vulkan and similar APIs,
                        most-preferred first.
                        The default is to select a graphics driver
                        automatically.
                        Values in this list match the last dot-separated
                        component of the names of extensions with the
                        <literal>active-gl-driver</literal> condition.
                        Typical values are
                        <literal>default</literal>,
                        <literal>mesa-git</literal> or
                        <literal>nvidia-550-120</literal>
                        (replacing the version number by the major and minor
                        version of the <literal>nvidia</literal> kernel module).
                    </para></listitem>
                </varlistentry>

                <!-- FLATPAK_PORTAL_MOCK_FLATPAK intentionally not documented:
                     it is intended for testing and development only
                     (flatpak-portal runs it instead of the real flatpak) -->

                <!-- FLATPAK_REVOKEFS_FUSE intentionally not documented:
                     it is intended for testing and development only
                     (it replaces /usr/libexec/revokefs-fuse) -->

                <varlistentry>
                    <term><envar>FLATPAK_RUN_DIR</envar></term>

                    <listitem><para>
                      The location of flatpak runtime global files. If this is not set,
                      <filename>/run/flatpak</filename> is used.
                    </para></listitem>
                </varlistentry>

                <varlistentry>
                    <term><envar>FLATPAK_SYSTEM_CACHE_DIR</envar></term>

                    <listitem><para>
                      The location where temporary child repositories will be created during pulls
                      into the system-wide installation.  If this is not set, a directory in
                      <filename>/var/tmp/</filename> is used. This is useful because it is more
                      likely to be on the same filesystem as the system repository (thus increasing
                      the chances for e.g. reflink copying), and we can avoid filling the user's
                      home directory with temporary data.
                    </para></listitem>
                </varlistentry>

                <varlistentry>
                    <term><envar>FLATPAK_SYSTEM_DIR</envar></term>

                    <listitem><para>
                      The location of the default system-wide installation. If this is not set,
                      <filename>/var/lib/flatpak</filename> is used (unless overridden at build
                      time by <option>--localstatedir</option> or
                      <option>-Dsystem_install_dir</option>).
                    </para></listitem>
                </varlistentry>

                <!-- FLATPAK_SYSTEM_HELPER_ON_SESSION intentionally not documented:
                     it is intended for testing and development only -->

                <!-- FLATPAK_TEST_COVERAGE intentionally not documented:
                     it is intended for testing and development only -->

                <!-- FLATPAK_TRIGGERSDIR intentionally not documented:
                     it is intended for testing and development only,
                     and is mostly superseded by FLATPAK_DATA_DIR -->

                <varlistentry>
                    <term><envar>FLATPAK_TTY_PROGRESS</envar></term>

                    <listitem><para>
                        May be set to <literal>0</literal> to disable reporting
                        machine-readable progress to the terminal.
                        This feature can be disabled because it uses the OSC 9;4
                        sequence, which some terminal emulators interpret as a
                        popup notification.
                    </para></listitem>
                </varlistentry>

                <varlistentry>
                    <term><envar>FLATPAK_USER_DIR</envar></term>

                    <listitem><para>
                      The location of the per-user installation. If this is not set,
                      <filename>$XDG_DATA_HOME/flatpak</filename> is used.
                    </para></listitem>
                </varlistentry>

                <!-- FLATPAK_VALIDATE_ICON intentionally not documented:
                     it is intended for testing and development only -->
            </variablelist>
    </refsect1>

    <refsect1>
        <title>See also</title>

            <para>
                <citerefentry><refentrytitle>ostree</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
                <citerefentry><refentrytitle>ostree.repo</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
                <citerefentry><refentrytitle>flatpak-remote</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
                <citerefentry><refentrytitle>flatpak-installation</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
                <ulink url="https://www.flatpak.org">https://www.flatpak.org</ulink>
            </para>

    </refsect1>

</refentry>

===== ./doc/flatpak-create-usb.xml =====
<?xml version='1.0'?> <!--*-nxml-*-->
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
    "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">

<refentry id="flatpak-create-usb">

    <refentryinfo>
        <title>flatpak create-usb</title>
        <productname>flatpak</productname>

        <authorgroup>
            <author>
                <contrib>Developer</contrib>
                <firstname>Matthew</firstname>
                <surname>Leeds</surname>
                <email>matthew.leeds@endlessm.com</email>
            </author>
        </authorgroup>
    </refentryinfo>

    <refmeta>
        <refentrytitle>flatpak create-usb</refentrytitle>
        <manvolnum>1</manvolnum>
    </refmeta>

    <refnamediv>
        <refname>flatpak-create-usb</refname>
        <refpurpose>Copy apps and/or runtimes onto removable media.</refpurpose>
    </refnamediv>

    <refsynopsisdiv>
            <cmdsynopsis>
                <command>flatpak create-usb</command>
                <arg choice="opt" rep="repeat">OPTION</arg>
                <arg choice="plain">MOUNT-PATH</arg>
                <arg choice="plain" rep="repeat">REF</arg>
            </cmdsynopsis>
    </refsynopsisdiv>

    <refsect1>
        <title>Description</title>

        <para>
            Copies the specified apps and/or runtimes <arg choice="plain">REF</arg>s onto the removable
            media mounted at <arg choice="plain">MOUNT-PATH</arg>, along with all the dependencies and
            metadata needed for installing them. This is one way of transferring flatpaks
            between computers that doesn't require an Internet connection. After using
            this command, the USB drive can be connected to another computer which already has the
            relevant remote(s) configured, and Flatpak will install or update from the drive offline
            (see below). If online, the drive will be used as a cache, meaning some objects will be
            pulled from it and others from the Internet. For this process to work a collection ID
            must be configured on the relevant remotes on both the source and destination computers,
            and on the remote server.
        </para>
        <para>
            On the destination computer one can install from the USB (or any mounted filesystem)
            using the <option>--sideload-repo</option> option with <command>flatpak install</command>.
            It's also possible to configure sideload paths using symlinks; see
            <citerefentry><refentrytitle>flatpak</refentrytitle><manvolnum>1</manvolnum></citerefentry>.
            Flatpak also includes systemd units to automatically sideload from hot-plugged USB drives,
            but these may or may not be enabled depending on your Linux distribution.
        </para>
        <para>
            Each <arg choice="plain">REF</arg> argument is a full or partial identifier in the
            flatpak ref format, which looks like "(app|runtime)/ID/ARCH/BRANCH". All elements
            except ID are optional and can be left out, including the slashes,
            so most of the time you need only specify ID. Any part left out will be matched
            against what is installed, and if there are multiple matches an error message
            will list the alternatives.
        </para>
        <para>
            By default this looks for both installed apps and runtimes
            with the given <arg choice="plain">REF</arg>, but you can
            limit this by using the <option>--app</option> or <option>--runtime</option> option.
        </para>
        <para>
            All <arg choice="plain">REF</arg>s must be in the same installation (user, system, or other).
            Otherwise it's ambiguous which repository metadata refs to put on the USB drive.
        </para>
        <para>
            By default <command>flatpak create-usb</command> uses <filename>.ostree/repo</filename>
            as the destination directory under <arg choice="plain">MOUNT-PATH</arg> but if you
            specify another location using <option>--destination-repo</option>
            a symbolic link will be created for you in <filename>.ostree/repos.d</filename>.
            This ensures that either way the repository will be found by flatpak (and other
            consumers of libostree) for install/update operations.
        </para>
        <para>
            Unless overridden with the <option>--system</option>, <option>--user</option>, or <option>--installation</option>
            options, this command searches both the system-wide installation
            and the per-user one for <arg choice="plain">REF</arg> and errors
            out if it exists in more than one.
        </para>

    </refsect1>

    <refsect1>
        <title>Options</title>

        <para>The following options are understood:</para>

        <variablelist>
            <varlistentry>
                <term><option>-h</option></term>
                <term><option>--help</option></term>

                <listitem><para>
                    Show help options and exit.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>-u</option></term>
                <term><option>--user</option></term>

                <listitem><para>
                    Copy refs from the per-user installation.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--system</option></term>

                <listitem><para>
                    Copy refs from the default system-wide installation.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--installation=NAME</option></term>

                <listitem><para>
                    Copy refs from a system-wide installation specified by
                    <arg choice="plain">NAME</arg> among those defined in
                    <filename>/etc/flatpak/installations.d/</filename>.  Using
                    <option>--installation=default</option> is
                    equivalent to using <option>--system</option>.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--app</option></term>

                <listitem><para>
                    Assume that all <arg choice="plain">REF</arg>s are apps if not explicitly specified.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--runtime</option></term>
                <listitem><para>
                    Assume that all <arg choice="plain">REF</arg>s are runtimes if not explicitly specified.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--destination-repo</option>=DEST</term>

                <listitem><para>
                  Create the repository in <arg choice="plain">DEST</arg> under <arg choice="plain">MOUNT-PATH</arg>, rather than
                  the default location.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--allow-partial</option></term>

                <listitem><para>
                  Don't print a warning when exporting partially installed commits, for example locale extensions without all
                  languages. These can cause problems when installing them, for example if the language config is different
                  on the installing side.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>-v</option></term>
                <term><option>--verbose</option></term>

                <listitem><para>
                    Print debug information during command processing.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--ostree-verbose</option></term>

                <listitem><para>
                    Print OSTree debug information during command processing.
                </para></listitem>
            </varlistentry>

        </variablelist>
    </refsect1>

    <refsect1>
        <title>Examples</title>

        <para>
            <command>$ flatpak create-usb /run/media/mwleeds/1a9b4cb2-a7ef-4d9b-91a5-6eaf8fdd2bf6/ com.endlessm.wiki_art.en</command>
        </para>

    </refsect1>

    <refsect1>
        <title>See also</title>

        <para>
            <citerefentry><refentrytitle>flatpak</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
            <citerefentry><refentrytitle>flatpak remote-modify</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
            <citerefentry><refentrytitle>flatpak-install</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
            <citerefentry><refentrytitle>flatpak-list</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
            <citerefentry><refentrytitle>ostree-create-usb</refentrytitle><manvolnum>1</manvolnum></citerefentry>
        </para>

    </refsect1>

</refentry>

===== ./doc/flatpak-remote-modify.xml =====
<?xml version='1.0'?> <!--*-nxml-*-->
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
    "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">

<refentry id="flatpak-remote-modify">

    <refentryinfo>
        <title>flatpak remote-modify</title>
        <productname>flatpak</productname>

        <authorgroup>
            <author>
                <contrib>Developer</contrib>
                <firstname>Alexander</firstname>
                <surname>Larsson</surname>
                <email>alexl@redhat.com</email>
            </author>
        </authorgroup>
    </refentryinfo>

    <refmeta>
        <refentrytitle>flatpak remote-modify</refentrytitle>
        <manvolnum>1</manvolnum>
    </refmeta>

    <refnamediv>
        <refname>flatpak-remote-modify</refname>
        <refpurpose>Modify a remote repository</refpurpose>
    </refnamediv>

    <refsynopsisdiv>
            <cmdsynopsis>
                <command>flatpak remote-modify</command>
                <arg choice="opt" rep="repeat">OPTION</arg>
                <arg choice="plain">NAME</arg>
            </cmdsynopsis>
    </refsynopsisdiv>

    <refsect1>
        <title>Description</title>

        <para>
            Modifies options for an existing remote repository in the flatpak repository configuration.
            <arg choice="plain">NAME</arg> is the name for the remote.
        </para>
        <para>
            Unless overridden with the <option>--system</option>, <option>--user</option>, or <option>--installation</option> options,
            this command uses either the default system-wide installation or the
            per-user one, depending on which has the specified
            <arg choice="plain">REMOTE</arg>.
        </para>

    </refsect1>

    <refsect1>
        <title>Options</title>

        <para>The following options are understood:</para>

        <variablelist>
            <varlistentry>
                <term><option>-h</option></term>
                <term><option>--help</option></term>

                <listitem><para>
                    Show help options and exit.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>-u</option></term>
                <term><option>--user</option></term>

                <listitem><para>
                    Modify the per-user configuration.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--system</option></term>

                <listitem><para>
                    Modify the default system-wide configuration.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--installation=NAME</option></term>

                <listitem><para>
                    Modify a system-wide installation specified by <arg choice="plain">NAME</arg>
                    among those defined in <filename>/etc/flatpak/installations.d/</filename>.
                    Using <option>--installation=default</option> is equivalent to using
                    <option>--system</option>.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--no-gpg-verify</option></term>

                <listitem><para>
                    Disable GPG verification for the added remote.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--gpg-verify</option></term>

                <listitem><para>
                    Enable GPG verification for the added remote.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--prio=PRIO</option></term>

                <listitem><para>
                    Set the priority for the remote. Default is 1, higher is more prioritized. This is
                    mainly used for graphical installation tools.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--subset=SUBSET</option></term>

                <listitem><para>
                  Limit the refs available from the remote to those that are part of the named subset.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--no-enumerate</option></term>

                <listitem><para>
                    Mark the remote as not enumerated. This means the remote will
                    not be used to list applications, for instance in graphical
                    installation tools. It will also not be used for runtime dependency
                    resolution (as with <option>--no-use-for-deps</option>).
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--no-use-for-deps</option></term>

                <listitem><para>
                    Mark the remote as not to be used for automatic runtime
                    dependency resolution.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--disable</option></term>

                <listitem><para>
                    Disable the remote. Disabled remotes will not be automatically updated from.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--enable</option></term>

                <listitem><para>
                    Enable the remote.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--enumerate</option></term>

                <listitem><para>
                    Mark the remote as enumerated. This means the remote will
                    be used to list applications, for instance in graphical
                    installation tools.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--use-for-deps</option></term>

                <listitem><para>
                    Mark the remote as to be used for automatic runtime
                    dependency resolution.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--title=TITLE</option></term>

                <listitem><para>
                    A title for the remote, e.g. for display in a UI.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--comment=COMMENT</option></term>

                <listitem><para>
                    A single-line comment for the remote, e.g. for display in a UI.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--description=DESCRIPTION</option></term>

                <listitem><para>
                    A full-paragraph description for the remote, e.g. for display in a UI.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--homepage=URL</option></term>

                <listitem><para>
                    URL for a website for the remote, e.g. for display in a UI.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--icon=URL</option></term>

                <listitem><para>
                    URL for an icon for the remote, e.g. for display in a UI.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--default-branch=BRANCH</option></term>

                <listitem><para>
                    A default branch for the remote, mainly for use in a UI.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--collection-id=COLLECTION-ID</option></term>

                <listitem><para>
                    The globally unique identifier of the remote repository, to
                    allow mirrors to be grouped. This must only be set to the
                    collection ID provided by the remote, and must not be set if the
                    remote does not provide a collection ID.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--url=URL</option></term>

                <listitem><para>
                    Set a new URL.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--update-metadata</option></term>

                <listitem><para>
                    Update the remote's extra metadata from the OSTree repository's summary
                    file. Only xa.title and xa.default-branch are supported at the moment.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--no-filter</option></term>
                <term><option>--filter=FILE</option></term>

                <listitem><para>
                  Modify the path (or unset) for the local filter used for this remote.
                  See <citerefentry><refentrytitle>flatpak-remote-add</refentrytitle><manvolnum>1</manvolnum></citerefentry> for details about the filter file format.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--gpg-import=FILE</option></term>

                <listitem><para>
                     Import gpg keys from the specified keyring file as
                     trusted for the new remote. If the file is - the
                     keyring is read from standard input.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--signature-lookaside=URL</option></term>

                <listitem><para>
                    Specify an URL to be used to look up signatures for this
                    remote (OCI remotes only).
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--authenticator-name=NAME</option></term>

                <listitem><para>
                    Specify the authenticator to use for the remote.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--authenticator-option=KEY=VALUE</option></term>

                <listitem><para>
                    Specify an authenticator option for the remote.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--authenticator-install</option></term>

                <listitem><para>
                    Enable auto-installation of authenticator.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--no-authenticator-install</option></term>

                <listitem><para>
                    Disable auto-installation of authenticator.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--follow-redirect</option></term>

                <listitem><para>
                    Follow xa.redirect-url defined in the summary file.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--no-follow-redirect</option></term>

                <listitem><para>
                    Do not follow xa.redirect-url defined in the summary file.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>-v</option></term>
                <term><option>--verbose</option></term>

                <listitem><para>
                    Print debug information during command processing.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--ostree-verbose</option></term>

                <listitem><para>
                    Print OSTree debug information during command processing.
                </para></listitem>
            </varlistentry>
        </variablelist>
    </refsect1>

    <refsect1>
        <title>Examples</title>

        <para>
            <command>$ flatpak --user remote-modify --no-gpg-verify test-repo</command>
        </para>
    </refsect1>

    <refsect1>
        <title>See also</title>

            <para>
                <citerefentry><refentrytitle>flatpak</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
                <citerefentry><refentrytitle>flatpak-remote-add</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
                <citerefentry><refentrytitle>flatpak-remote-delete</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
                <citerefentry><refentrytitle>flatpak-remotes</refentrytitle><manvolnum>1</manvolnum></citerefentry>
            </para>
    </refsect1>

</refentry>

===== ./doc/flatpak-build-init.xml =====
<?xml version='1.0'?> <!--*-nxml-*-->
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
    "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">

<refentry id="flatpak-build-init">

    <refentryinfo>
        <title>flatpak build-init</title>
        <productname>flatpak</productname>

        <authorgroup>
            <author>
                <contrib>Developer</contrib>
                <firstname>Alexander</firstname>
                <surname>Larsson</surname>
                <email>alexl@redhat.com</email>
            </author>
        </authorgroup>
    </refentryinfo>

    <refmeta>
        <refentrytitle>flatpak build-init</refentrytitle>
        <manvolnum>1</manvolnum>
    </refmeta>

    <refnamediv>
        <refname>flatpak-build-init</refname>
        <refpurpose>Initialize a build directory</refpurpose>
    </refnamediv>

    <refsynopsisdiv>
            <cmdsynopsis>
                <command>flatpak build-init</command>
                <arg choice="opt" rep="repeat">OPTION</arg>
                <arg choice="plain">DIRECTORY</arg>
                <arg choice="plain">APPNAME</arg>
                <arg choice="plain">SDK</arg>
                <arg choice="plain">RUNTIME</arg>
                <arg choice="opt">BRANCH</arg>
            </cmdsynopsis>
    </refsynopsisdiv>

    <refsect1>
        <title>Description</title>

        <para>
            Initializes a separate build directory.
            <arg choice="plain">DIRECTORY</arg> is the name of the directory.
            <arg choice="plain">APPNAME</arg> is the application id of the app
            that will be built.
            <arg choice="plain">SDK</arg> and <arg choice="plain">RUNTIME</arg>
            specify the sdk and runtime that the application should be built
            against and run in.
            <arg choice="plain">BRANCH</arg> specify the version of sdk and runtime
        </para>
        <para>
            Initializes a directory as build directory which can be used as 
            target directory of <command>flatpak build</command>. It
            creates a <filename>metadata</filename> inside the given directory. 
            Additionally, empty <filename>files</filename> and <filename>var</filename>
            subdirectories are created.
        </para>
        <para>
            It is an error to run build-init on a directory that has already
            been initialized as a build directory.
        </para>
    </refsect1>

    <refsect1>
        <title>Options</title>

        <para>The following options are understood:</para>

        <variablelist>
            <varlistentry>
                <term><option>-h</option></term>
                <term><option>--help</option></term>

                <listitem><para>
                    Show help options and exit.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--arch=ARCH</option></term>

                <listitem><para>
                    The architecture to use. See <command>flatpak --supported-arches</command>
                    for architectures supported by the host.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>-v</option></term>
                <term><option>--var=RUNTIME</option></term>

                <listitem><para>
                    Initialize var from the named runtime.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>-w</option></term>
                <term><option>--writable-sdk</option></term>

                <listitem><para>
                    Initialize /usr with a copy of the sdk, which is writable during flatpak build. This can be used
                    if you need to install build tools in /usr during the build. This is stored in the
                    <filename>usr</filename> subdirectory of the app dir, but will not be part of the final
                    app.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--tag=TAG</option></term>

                <listitem><para>
                    Add a tag to the metadata file.
                    This option can be used multiple times.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--sdk-extension=EXTENSION</option></term>

                <listitem><para>
                    When using <option>--writable-sdk</option>, in addition to the sdk, also install the specified extension.
                    This option can be used multiple times.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--extension=NAME=VARIABLE[=VALUE]</option></term>

                <listitem><para>
                  Add extension point info.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--sdk-dir</option></term>

                <listitem><para>
                    Specify a custom subdirectory to use instead of <filename>usr</filename> for <option>--writable-sdk</option>.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--update</option></term>

                <listitem><para>
                    Re-initialize the sdk and var, don't fail if already initialized.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--base=APP</option></term>

                <listitem><para>
                    Initialize the application with files from another specified application.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--base-version=VERSION</option></term>

                <listitem><para>
                    Specify the version to use for <option>--base</option>. If not specified, will default to
                    "master".
                </para></listitem>
            </varlistentry>
            <varlistentry>
                <term><option>--base-extension=EXTENSION</option></term>

                <listitem><para>
                    When using <option>--base</option>, also install the specified extension from the app.
                    This option can be used multiple times.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--type=TYPE</option></term>

                <listitem><para>
                    This can be used to build different types of things. The default
                    is "app" which is a regular app, but "runtime" creates a runtime
                    based on an existing runtime, and "extension" creates an extension
                    for an app or runtime.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--extension-tag=EXTENSION_TAG</option></term>

                <listitem><para>
                    If building an extension, the tag to use when searching for
                    the mount point of the extension.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--verbose</option></term>

                <listitem><para>
                    Print debug information during command processing.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--ostree-verbose</option></term>

                <listitem><para>
                    Print OSTree debug information during command processing.
                </para></listitem>
            </varlistentry>
        </variablelist>
    </refsect1>

    <refsect1>
        <title>Examples</title>

        <para>
            <command>$ flatpak build-init /build/my-app org.example.myapp org.gnome.Sdk org.gnome.Platform 3.36</command>
        </para>

    </refsect1>

    <refsect1>
        <title>See also</title>

        <para>
            <citerefentry><refentrytitle>flatpak</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
            <citerefentry><refentrytitle>flatpak-build</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
            <citerefentry><refentrytitle>flatpak-build-finish</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
            <citerefentry><refentrytitle>flatpak-build-export</refentrytitle><manvolnum>1</manvolnum></citerefentry>
        </para>

    </refsect1>

</refentry>

===== ./doc/xmlto-config.xsl =====
<?xml version='1.0'?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:fo="http://www.w3.org/1999/XSL/Format"
                version="1.0">
  <xsl:param name="html.stylesheet" select="'docbook.css'"/>
  <xsl:param name="citerefentry.link" select="1"/>
  <xsl:template name="generate.citerefentry.link"><xsl:text>#</xsl:text><xsl:value-of select="refentrytitle"/></xsl:template>
  <xsl:param name="chapter.autolabel" select="0"></xsl:param>
</xsl:stylesheet>

===== ./doc/flatpak-kill.xml =====
<?xml version='1.0'?> <!--*-nxml-*-->
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
    "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">

<refentry id="flatpak-kill">

    <refentryinfo>
        <title>flatpak kill</title>
        <productname>flatpak</productname>

        <authorgroup>
            <author>
                <contrib>Developer</contrib>
                <firstname>Matthias</firstname>
                <surname>Clasen</surname>
                <email>mclasen@redhat.com</email>
            </author>
        </authorgroup>
    </refentryinfo>

    <refmeta>
        <refentrytitle>flatpak kill</refentrytitle>
        <manvolnum>1</manvolnum>
    </refmeta>

    <refnamediv>
        <refname>flatpak-kill</refname>
        <refpurpose>Stop a running application</refpurpose>
    </refnamediv>

    <refsynopsisdiv>
            <cmdsynopsis>
                <command>flatpak kill</command>
                <arg choice="plain">INSTANCE</arg>
            </cmdsynopsis>
    </refsynopsisdiv>

    <refsect1>
        <title>Description</title>

        <para>
            Stop a running Flatpak instance.
        </para>

        <para>
            <arg choice="plain">INSTANCE</arg> can be
            either the numeric instance ID or the application ID of a running
            Flatpak. You can use <command>flatpak ps</command> to find the
            instance IDs of running flatpaks.
        </para>

    </refsect1>

    <refsect1>
        <title>Options</title>

        <para>The following options are understood:</para>

        <variablelist>
            <varlistentry>
                <term><option>-h</option></term>
                <term><option>--help</option></term>

                <listitem><para>
                    Show help options and exit.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>-v</option></term>
                <term><option>--verbose</option></term>

                <listitem><para>
                    Print debug information during command processing.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--ostree-verbose</option></term>

                <listitem><para>
                    Print OSTree debug information during command processing.
                </para></listitem>
            </varlistentry>
        </variablelist>
    </refsect1>

    <refsect1>
        <title>Examples</title>

        <para>
            <command>$ flatpak kill org.gnome.Todo</command>
        </para>

    </refsect1>

    <refsect1>
        <title>See also</title>

        <para>
            <citerefentry><refentrytitle>flatpak</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
            <citerefentry><refentrytitle>flatpak-run</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
            <citerefentry><refentrytitle>flatpak-ps</refentrytitle><manvolnum>1</manvolnum></citerefentry>
        </para>

    </refsect1>

</refentry>

===== ./doc/flatpak-pin.xml =====
<?xml version='1.0'?> <!--*-nxml-*-->
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
    "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">

<refentry id="flatpak-pin">

    <refentryinfo>
        <title>flatpak pin</title>
        <productname>flatpak</productname>

        <authorgroup>
            <author>
                <contrib>Developer</contrib>
                <firstname>Matthew</firstname>
                <surname>Leeds</surname>
                <email>matthew.leeds@endlessm.com</email>
            </author>
        </authorgroup>
    </refentryinfo>

    <refmeta>
        <refentrytitle>flatpak pin</refentrytitle>
        <manvolnum>1</manvolnum>
    </refmeta>

    <refnamediv>
        <refname>flatpak-pin</refname>
        <refpurpose>Pin runtimes to prevent automatic removal</refpurpose>
    </refnamediv>

    <refsynopsisdiv>
            <cmdsynopsis>
                <command>flatpak pin</command>
                <arg choice="opt" rep="repeat">OPTION</arg>
                <arg choice="plain" rep="repeat">PATTERN</arg>
            </cmdsynopsis>
    </refsynopsisdiv>

    <refsect1>
        <title>Description</title>

        <para>
          Flatpak maintains a list of patterns that define which refs are pinned.
          A pinned ref will never be automatically uninstalled (as are unused
          runtimes periodically). This can be useful if for example you are using
          a runtime for development purposes.
        </para>
        <para>
          Runtimes that are explicitly installed, rather than installed as a
          dependency of something else, are automatically pinned.
        </para>
        <para>
          The patterns are just a partial ref, with the * character matching anything
          within that part of the ref. Only runtimes can be pinned, not apps. Here
          are some example patterns:
<programlisting>
org.some.Runtime
org.some.Runtime//unstable
runtime/org.domain.*
org.some.Runtime/arm
</programlisting>
        </para>
        <para>
          To list the current set of pins, run this command without any patterns.
        </para>
    </refsect1>

    <refsect1>
        <title>Options</title>

        <para>The following options are understood:</para>

        <variablelist>
            <varlistentry>
                <term><option>-h</option></term>
                <term><option>--help</option></term>

                <listitem><para>
                    Show help options and exit.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--remove</option></term>

                <listitem><para>
                  Instead of adding the patterns, remove matching patterns.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>-u</option></term>
                <term><option>--user</option></term>

                <listitem><para>
                    Pin refs in a per-user installation.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--system</option></term>

                <listitem><para>
                    Pin refs in the default system-wide installation.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--installation=NAME</option></term>

                <listitem><para>
                    Pin refs in a system-wide installation
                    specified by <arg choice="plain">NAME</arg> among those defined in
                    <filename>/etc/flatpak/installations.d/</filename>. Using
                    <option>--installation=default</option> is equivalent to using
                    <option>--system</option>.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>-v</option></term>
                <term><option>--verbose</option></term>

                <listitem><para>
                    Print debug information during command processing.
                </para></listitem>
            </varlistentry>
        </variablelist>
    </refsect1>

    <refsect1>
        <title>Examples</title>

        <para>
            <command>$ flatpak pin</command>
        </para>
        <para>
            <command>$ flatpak pin org.freedesktop.Platform//19.08</command>
        </para>
        <para>
            <command>$ flatpak pin --remove org.freedesktop.Platform//19.08</command>
        </para>

    </refsect1>

    <refsect1>
        <title>See also</title>

        <para>
            <citerefentry><refentrytitle>flatpak</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
            <citerefentry><refentrytitle>flatpak-uninstall</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
        </para>

    </refsect1>

</refentry>

===== ./doc/flatpak-remote-add.xml =====
<?xml version='1.0'?> <!--*-nxml-*-->
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
    "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">

<refentry id="flatpak-remote-add">

    <refentryinfo>
        <title>flatpak remote-add</title>
        <productname>flatpak</productname>

        <authorgroup>
            <author>
                <contrib>Developer</contrib>
                <firstname>Alexander</firstname>
                <surname>Larsson</surname>
                <email>alexl@redhat.com</email>
            </author>
        </authorgroup>
    </refentryinfo>

    <refmeta>
        <refentrytitle>flatpak remote-add</refentrytitle>
        <manvolnum>1</manvolnum>
    </refmeta>

    <refnamediv>
        <refname>flatpak-remote-add</refname>
        <refpurpose>Add a remote repository</refpurpose>
    </refnamediv>

    <refsynopsisdiv>
            <cmdsynopsis>
                <command>flatpak remote-add</command>
                <arg choice="opt" rep="repeat">OPTION</arg>
                <arg choice="plain">NAME</arg>
                <arg choice="plain">LOCATION</arg>
            </cmdsynopsis>
    </refsynopsisdiv>

    <refsect1>
        <title>Description</title>

        <para>
            Adds a remote repository to the flatpak repository configuration.
            <arg choice="plain">NAME</arg> is the name for the new remote, and
            <arg choice="plain">LOCATION</arg> is a url or pathname.
            The <arg choice="plain">LOCATION</arg> is either a flatpak repository,
            or a <filename>.flatpakrepo</filename> file which
            describes a repository. In the former case you may also have to specify
            extra options, such as the gpg key for the repo.
        </para>
        <para>
            Unless overridden with the <option>--user</option> or <option>--installation</option> options, this command
            changes the default system-wide installation.
        </para>

    </refsect1>

    <refsect1>
        <title>Options</title>

        <para>The following options are understood:</para>

        <variablelist>
            <varlistentry>
                <term><option>-h</option></term>
                <term><option>--help</option></term>

                <listitem><para>
                    Show help options and exit.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--from</option></term>

                <listitem><para>
                  Assume the URI is a .flatpakrepo file rather than the repository itself. This is enabled
                  by default if the extension is .flatpakrepo, so generally you don't need this option.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>-u</option></term>
                <term><option>--user</option></term>

                <listitem><para>
                    Modify the per-user configuration.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--system</option></term>

                <listitem><para>
                    Modify the default system-wide configuration.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--installation=NAME</option></term>

                <listitem><para>
                    Modify a system-wide installation specified by <arg choice="plain">NAME</arg>
                    among those defined in <filename>/etc/flatpak/installations.d/</filename>.
                    Using <option>--installation=default</option> is equivalent to using
                    <option>--system</option>.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--no-gpg-verify</option></term>

                <listitem><para>
                    Disable GPG verification for the added remote.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--prio=PRIO</option></term>

                <listitem><para>
                    Set the priority for the remote. Default is 1, higher is more prioritized. This is
                    mainly used for graphical installation tools. It is also used when searching for a
                    remote to provide an app's runtime. The app's origin is checked before other
                    remotes with the same priority.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--subset=SUBSET</option></term>

                <listitem><para>
                  Limit the refs available from the remote to those that are part of the named subset.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--no-enumerate</option></term>

                <listitem><para>
                    Mark the remote as not enumerated. This means the remote will
                    not be used to list applications, for instance in graphical
                    installation tools.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--no-use-for-deps</option></term>

                <listitem><para>
                    Mark the remote as not to be used for automatic runtime
                    dependency resolution.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--if-not-exists</option></term>

                <listitem><para>
                    Do nothing if the provided remote already exists.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--disable</option></term>

                <listitem><para>
                    Disable the added remote.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--title=TITLE</option></term>

                <listitem><para>
                    A title for the remote, e.g. for display in a UI.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--comment=COMMENT</option></term>

                <listitem><para>
                    A single-line comment for the remote, e.g. for display in a UI.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--description=DESCRIPTION</option></term>

                <listitem><para>
                    A full-paragraph description for the remote, e.g. for display in a UI.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--homepage=URL</option></term>

                <listitem><para>
                    URL for a website for the remote, e.g. for display in a UI.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--icon=URL</option></term>

                <listitem><para>
                    URL for an icon for the remote, e.g. for display in a UI.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--default-branch=BRANCH</option></term>

                <listitem><para>
                    A default branch for the remote, mainly for use in a UI.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--filter=PATH</option></term>

                <listitem><para>
                  Add a local filter to the remote. A filter file is a list of lines, each
                  file starting with "allow" or "deny", and then a glob for the ref to
                  allow or disallow. The globs specify a partial ref (i.e. you can leave out
                  trailing parts which will then match everything), but otherwise only "*" is
                  special, matching anything in that part of the ref.
                </para>
                <para>
                  By default all refs are allowed, but if a ref
                  matches a deny rule it is disallowed unless it
                  specifically matches an allow rule. This means you
                  can use this to implement both allowlisting and blocklisting.
                </para>
                <para>
                  Here is an example filter file:
<programlisting>
# This is an allowlist style filter as it denies all first
deny *
allow runtime/org.freedesktop.*
allow org.some.app/arm
allow org.signal.Signal/*/stable
allow org.signal.Signal.*/*/stable
</programlisting>
                </para>
                </listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--gpg-import=FILE</option></term>

                <listitem><para>
                     Import gpg keys from the specified keyring file as
                     trusted for the new remote. If the file is - the
                     keyring is read from standard input.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--signature-lookaside=URL</option></term>

                <listitem><para>
                    Specify an URL to be used to look up signatures for this
                    remote (OCI remotes only).
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--authenticator-name=NAME</option></term>

                <listitem><para>
                    Specify the authenticator to use for the remote.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--authenticator-option=KEY=VALUE</option></term>

                <listitem><para>
                    Specify an authenticator option for the remote.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--authenticator-install</option></term>

                <listitem><para>
                    Enable auto-installation of authenticator.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--no-authenticator-install</option></term>

                <listitem><para>
                    Disable auto-installation of authenticator.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--no-follow-redirect</option></term>

                <listitem><para>
                    Do not follow xa.redirect-url defined in the summary file.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>-v</option></term>
                <term><option>--verbose</option></term>

                <listitem><para>
                    Print debug information during command processing.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--ostree-verbose</option></term>

                <listitem><para>
                    Print OSTree debug information during command processing.
                </para></listitem>
            </varlistentry>
        </variablelist>
    </refsect1>

    <refsect1>
        <title>Examples</title>

        <para>
            <command>$ flatpak remote-add gnome https://sdk.gnome.org/gnome.flatpakrepo</command>
        </para>
        <para>
            <command>$ flatpak --user remote-add --no-gpg-verify test-repo https://people.gnome.org/~alexl/gnome-sdk/repo/</command>
        </para>
    </refsect1>

    <refsect1>
        <title>See also</title>

            <para>
                <citerefentry><refentrytitle>flatpak</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
                <citerefentry><refentrytitle>flatpak-remote-modify</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
                <citerefentry><refentrytitle>flatpak-remote-delete</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
                <citerefentry><refentrytitle>flatpak-remotes</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
                <citerefentry><refentrytitle>flatpakrepo</refentrytitle><manvolnum>5</manvolnum></citerefentry>
            </para>
    </refsect1>

</refentry>

===== ./doc/flatpak-remote-ls.xml =====
<?xml version='1.0'?> <!--*-nxml-*-->
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
    "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">

<refentry id="flatpak-remote-ls">

    <refentryinfo>
        <title>flatpak remote-ls</title>
        <productname>flatpak</productname>

        <authorgroup>
            <author>
                <contrib>Developer</contrib>
                <firstname>Alexander</firstname>
                <surname>Larsson</surname>
                <email>alexl@redhat.com</email>
            </author>
        </authorgroup>
    </refentryinfo>

    <refmeta>
        <refentrytitle>flatpak remote-ls</refentrytitle>
        <manvolnum>1</manvolnum>
    </refmeta>

    <refnamediv>
        <refname>flatpak-remote-ls</refname>
        <refpurpose>Show available runtimes and applications</refpurpose>
    </refnamediv>

    <refsynopsisdiv>
            <cmdsynopsis>
                <command>flatpak remote-ls</command>
                <arg choice="opt" rep="repeat">OPTION</arg>
                <arg choice="opt">REMOTE</arg>
            </cmdsynopsis>
    </refsynopsisdiv>

    <refsect1>
        <title>Description</title>

        <para>
            Shows runtimes and applications that are available in the
            remote repository with the name <arg choice="plain">REMOTE</arg>,
            or all remotes if one isn't specified. You can find all configured
            remote repositories with <command>flatpak remotes</command>.
        </para>
        <para>
            <arg choice="plain">REMOTE</arg> can be a file:// URI pointing to a
            local repository instead of a remote name.
        </para>
        <para>
            Unless overridden with the <option>--system</option>, <option>--user</option>, or <option>--installation</option> options,
            this command uses either the default system-wide installation or the
            per-user one, depending on which has the specified
            <arg choice="plain">REMOTE</arg>.
        </para>

    </refsect1>

    <refsect1>
        <title>Options</title>

        <para>The following options are understood:</para>

        <variablelist>
            <varlistentry>
                <term><option>-h</option></term>
                <term><option>--help</option></term>

                <listitem><para>
                    Show help options and exit.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>-u</option></term>
                <term><option>--user</option></term>

                <listitem><para>
                    Use the per-user configuration.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--system</option></term>

                <listitem><para>
                    Use the default system-wide configuration.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--installation=NAME</option></term>

                <listitem><para>
                    Use a system-wide installation specified by <arg choice="plain">NAME</arg>
                    among those defined in <filename>/etc/flatpak/installations.d/</filename>.
                    Using <option>--installation=default</option> is equivalent to using
                    <option>--system</option>.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--cached</option></term>

                <listitem><para>
                  Prefer to use locally cached information if possible, even though it
                  may be out of date. This is faster, but risks returning stale information.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>-d</option></term>
                <term><option>--show-details</option></term>

                <listitem><para>
                    Show arches, branches and commit ids, in addition to the names.
                    Equivalent to <option>--columns=all</option>.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--runtime</option></term>

                <listitem><para>
                    Show only runtimes, omit applications.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--app</option></term>

                <listitem><para>
                    Show only applications, omit runtimes.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--all</option></term>
                <term><option>-a</option></term>

                <listitem><para> Show everything. By default locale and
                debug extensions as well as secondary arches when the primary
                arch is available are hidden.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--updates</option></term>

                <listitem><para>
                    Show only those which have updates available.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--arch=ARCH</option></term>

                <listitem><para>
                    Show only those matching the specified architecture. By default, only
                    supported architectures are shown. Use <option>--arch=*</option> to show all architectures.
                    See <command>flatpak --supported-arches</command> for architectures supported by the host.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>-v</option></term>
                <term><option>--verbose</option></term>

                <listitem><para>
                    Print debug information during command processing.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--ostree-verbose</option></term>

                <listitem><para>
                    Print OSTree debug information during command processing.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--app-runtime=RUNTIME</option></term>

                <listitem><para>
                    List applications that use the given runtime
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--columns=FIELD,…</option></term>

                <listitem><para>
                    Specify what information to show about each ref. You can
                    list multiple fields, or use this option multiple times.
                </para><para>
                    Append :s[tart], :m[iddle], :e[nd] or :f[ull] to column
                    names to change ellipsization.
                </para></listitem>
            </varlistentry>
        </variablelist>
    </refsect1>

   <refsect1>
        <title>Fields</title>

        <para>The following fields are understood by the <option>--columns</option> option:</para>

        <variablelist>
            <varlistentry>
                <term>name</term>

                <listitem><para>
                    Show the name
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term>description</term>

                <listitem><para>
                    Show the application description
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term>application</term>

                <listitem><para>
                    Show the application or runtime ID
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term>arch</term>

                <listitem><para>
                    Show the arch
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term>branch</term>

                <listitem><para>
                    Show the branch 
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term>version</term>

                <listitem><para>
                    Show the version
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term>ref</term>

                <listitem><para>
                    Show the ref
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term>origin</term>

                <listitem><para>
                    Show the origin remote
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term>commit</term>

                <listitem><para>
                    Show the active commit
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term>runtime</term>

                <listitem><para>
                    Show the used runtime
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term>installed-size</term>

                <listitem><para>
                    Show the installed size
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term>download-size</term>

                <listitem><para>
                    Show the download size
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term>options</term>

                <listitem><para>
                    Show options
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term>all</term>

                <listitem><para>
                    Show all columns
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term>help</term>

                <listitem><para>
                    Show the list of available columns
                </para></listitem>
            </varlistentry>
        </variablelist>

        <para>
          Note that field names can be abbreviated to a unique prefix.
        </para>

    </refsect1>

    <refsect1>
        <title>Examples</title>

        <para>
            <command>$ flatpak --user remote-ls --app testrepo</command>
        </para>
<programlisting>
Ref
org.gnome.Builder
org.freedesktop.glxgears
</programlisting>

        <para>
            <command>$ flatpak remote-ls file:///run/media/mwleeds/d4d37026-cde2-4e5e-8bcc-d23ebbf231f9/.ostree/repo</command>
        </para>
<programlisting>
Ref
org.kde.Khangman
</programlisting>

    </refsect1>

    <refsect1>
        <title>See also</title>

            <para>
                <citerefentry><refentrytitle>flatpak</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
                <citerefentry><refentrytitle>flatpak-remotes</refentrytitle><manvolnum>1</manvolnum></citerefentry>
            </para>
    </refsect1>

</refentry>

===== ./doc/flatpak-installation.xml =====
<?xml version='1.0'?> <!--*-nxml-*-->
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
    "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">

<refentry id="flatpak-installation">

    <refentryinfo>
        <title>flatpak installation</title>
        <productname>flatpak</productname>

        <authorgroup>
            <author>
                <contrib>Developer</contrib>
                <firstname>Alexander</firstname>
                <surname>Larsson</surname>
                <email>alexl@redhat.com</email>
            </author>
        </authorgroup>
    </refentryinfo>

    <refmeta>
        <refentrytitle>flatpak installation</refentrytitle>
        <manvolnum>5</manvolnum>
    </refmeta>

    <refnamediv>
        <refname>flatpak-installation</refname>
        <refpurpose>Configuration for an installation location</refpurpose>
    </refnamediv>

    <refsect1>
        <title>Description</title>

        <para>
            flatpak can operate in system-wide or per-user mode. The system-wide data
            is located in <filename>$prefix/var/lib/flatpak/</filename>, and the per-user data is in
            <filename>$HOME/.local/share/flatpak/</filename>.
        </para>

        <para>
            In addition to the default installation locations, more system-wide installations
            can be defined via configuration files <filename>/etc/flatpak/installations.d/</filename>,
            which must have the .conf extension and follow the format described below.
        </para>
    </refsect1>

    <refsect1>
        <title>File format</title>

        <para>
            The installation config file format is using the same .ini file format that is used
            for systemd unit files or application .desktop files.
        </para>

        <refsect2>
            <title>[Installation …]</title>
            <para>
                All the configuration for the the installation location with name NAME is contained
                in the [Installation "NAME"] group.
            </para>
            <para>
                The following keys are recognized:
            </para>
            <variablelist>
                <varlistentry>
                    <term><option>Path</option> (string)</term>
                    <listitem><para>The path for this installation. This key is mandatory.</para></listitem>
                </varlistentry>
                <varlistentry>
                    <term><option>DisplayName</option> (string)</term>
                    <listitem><para>The name to use when showing this installation in the UI.</para></listitem>
                </varlistentry>
                <varlistentry>
                    <term><option>Priority</option> (integer)</term>
                    <listitem><para>A priority for this installation.</para></listitem>
                </varlistentry>
                <varlistentry>
                    <term><option>StorageType</option> (string)</term>
                    <listitem><para>The type of storage used for this installation. Possible values include: network, mmc, sdcard, harddisk.</para></listitem>
                </varlistentry>
            </variablelist>
        </refsect2>
    </refsect1>

    <refsect1>
        <title>Examples</title>

<programlisting>
[Installation "extra"]
Path=/location/of/sdcard
DisplayName=Extra Installation
StorageType=sdcard
</programlisting>

    </refsect1>

</refentry>

===== ./doc/flatpak-remote-delete.xml =====
<?xml version='1.0'?> <!--*-nxml-*-->
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
    "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">

<refentry id="flatpak-remote-delete">

    <refentryinfo>
        <title>flatpak remote-delete</title>
        <productname>flatpak</productname>

        <authorgroup>
            <author>
                <contrib>Developer</contrib>
                <firstname>Alexander</firstname>
                <surname>Larsson</surname>
                <email>alexl@redhat.com</email>
            </author>
        </authorgroup>
    </refentryinfo>

    <refmeta>
        <refentrytitle>flatpak remote-delete</refentrytitle>
        <manvolnum>1</manvolnum>
    </refmeta>

    <refnamediv>
        <refname>flatpak-remote-delete</refname>
        <refpurpose>Delete a remote repository</refpurpose>
    </refnamediv>

    <refsynopsisdiv>
            <cmdsynopsis>
                <command>flatpak remote-delete</command>
                <arg choice="opt" rep="repeat">OPTION</arg>
                <arg choice="plain">NAME</arg>
            </cmdsynopsis>
    </refsynopsisdiv>

    <refsect1>
        <title>Description</title>

        <para>
            Removes a remote repository from the flatpak repository configuration.
            <arg choice="plain">NAME</arg> is the name of an existing remote.
        </para>
        <para>
            Unless overridden with the <option>--system</option>, <option>--user</option>, or <option>--installation</option> options,
            this command uses either the default system-wide installation or the
            per-user one, depending on which has the specified
            <arg choice="plain">REMOTE</arg>.
        </para>

    </refsect1>

    <refsect1>
        <title>Options</title>

        <para>The following options are understood:</para>

        <variablelist>
            <varlistentry>
                <term><option>-h</option></term>
                <term><option>--help</option></term>

                <listitem><para>
                    Show help options and exit.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>-u</option></term>
                <term><option>--user</option></term>

                <listitem><para>
                    Modify the per-user configuration.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--system</option></term>

                <listitem><para>
                    Modify the default system-wide configuration.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--installation=NAME</option></term>

                <listitem><para>
                    Modify a system-wide installation specified by <arg choice="plain">NAME</arg>
                    among those defined in <filename>/etc/flatpak/installations.d/</filename>.
                    Using <option>--installation=default</option> is equivalent to using
                    <option>--system</option>.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--force</option></term>

                <listitem><para>
                    Remove remote even if its in use by installed apps or runtimes.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>-v</option></term>
                <term><option>--verbose</option></term>

                <listitem><para>
                    Print debug information during command processing.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--ostree-verbose</option></term>

                <listitem><para>
                    Print OSTree debug information during command processing.
                </para></listitem>
            </varlistentry>
        </variablelist>
    </refsect1>

    <refsect1>
        <title>Examples</title>

        <para>
            <command>$ flatpak --user remote-delete dried-raisins</command>
        </para>
    </refsect1>

    <refsect1>
        <title>See also</title>

            <para>
                <citerefentry><refentrytitle>flatpak</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
                <citerefentry><refentrytitle>flatpak-remote-add</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
                <citerefentry><refentrytitle>flatpak-remote-modify</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
                <citerefentry><refentrytitle>flatpak-remotes</refentrytitle><manvolnum>1</manvolnum></citerefentry>
            </para>
    </refsect1>

</refentry>

===== ./doc/flatpak-permission-set.xml =====
<?xml version='1.0'?> <!--*-nxml-*-->
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
    "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">

<refentry id="flatpak-permission-set">

    <refentryinfo>
        <title>flatpak permission-set</title>
        <productname>flatpak</productname>

        <authorgroup>
            <author>
                <contrib>Developer</contrib>
                <firstname>Matthias</firstname>
                <surname>Clasen</surname>
                <email>mclasen@redhat.com</email>
            </author>
        </authorgroup>
    </refentryinfo>

    <refmeta>
        <refentrytitle>flatpak permission-set</refentrytitle>
        <manvolnum>1</manvolnum>
    </refmeta>

    <refnamediv>
        <refname>flatpak-permission-set</refname>
        <refpurpose>Set permissions</refpurpose>
    </refnamediv>

    <refsynopsisdiv>
            <cmdsynopsis>
                <command>flatpak permission-set</command>
                <arg choice="opt" rep="repeat">OPTION</arg>
                <arg choice="plain">TABLE</arg>
                <arg choice="plain">ID</arg>
                <arg choice="plain">APP_ID</arg>
                <arg choice="opt" rep="repeat">PERMISSION</arg>
            </cmdsynopsis>
    </refsynopsisdiv>

    <refsect1>
        <title>Description</title>

        <para>
          Set the permissions for an application in an entry in the permission store.
          The entry is identified by TABLE and ID, the application is identified by
          APP_ID. The PERMISSION strings must be in a format suitable for the table.
        </para>
        <para>
          The permission store is used by portals.
          Each portal generally has its own table in the permission
          store, and the format of the table entries is specific to
          each portal.
        </para>

    </refsect1>

    <refsect1>
        <title>Options</title>

        <para>The following options are understood:</para>

        <variablelist>
            <varlistentry>
                <term><option>-h</option></term>
                <term><option>--help</option></term>

                <listitem><para>
                    Show help options and exit.
                </para></listitem>
            </varlistentry>
            <varlistentry>
                <term><option>--data=DATA</option></term>

                <listitem><para>
                    Associate <arg choice="plain">DATA</arg> with the entry.
                    The data must be a serialized GVariant.
                </para></listitem>
            </varlistentry>
            <varlistentry>
                <term><option>-v</option></term>
                <term><option>--verbose</option></term>

                <listitem><para>
                    Print debug information during command processing.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--ostree-verbose</option></term>

                <listitem><para>
                    Print OSTree debug information during command processing.
                </para></listitem>
            </varlistentry>
        </variablelist>
    </refsect1>

    <refsect1>
        <title>Examples</title>

        <para>
            <command>$ flatpak permission-set --data "{'always-ask':&lt;true&gt;}" desktop-used-apps text/plain org.mozilla.Firefox org.gnome.gedit 0 3</command>
        </para>

    </refsect1>

    <refsect1>
        <title>See also</title>

        <para>
            <citerefentry><refentrytitle>flatpak</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
            <citerefentry><refentrytitle>flatpak-permissions</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
            <citerefentry><refentrytitle>flatpak-permission-remove</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
            <citerefentry><refentrytitle>flatpak-permission-reset</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
            <citerefentry><refentrytitle>flatpak-permission-show</refentrytitle><manvolnum>1</manvolnum></citerefentry>
        </para>

    </refsect1>

</refentry>

===== ./doc/flatpak-permission-show.xml =====
<?xml version='1.0'?> <!--*-nxml-*-->
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
    "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">

<refentry id="flatpak-permission-show">

    <refentryinfo>
        <title>flatpak permission-show</title>
        <productname>flatpak</productname>

        <authorgroup>
            <author>
                <contrib>Developer</contrib>
                <firstname>Matthias</firstname>
                <surname>Clasen</surname>
                <email>mclasen@redhat.com</email>
            </author>
        </authorgroup>
    </refentryinfo>

    <refmeta>
        <refentrytitle>flatpak permission-show</refentrytitle>
        <manvolnum>1</manvolnum>
    </refmeta>

    <refnamediv>
        <refname>flatpak-permission-show</refname>
        <refpurpose>Show permissions</refpurpose>
    </refnamediv>

    <refsynopsisdiv>
            <cmdsynopsis>
                <command>flatpak permission-show</command>
                <arg choice="opt" rep="repeat">OPTION</arg>
                <arg choice="plain">APP_ID</arg>
            </cmdsynopsis>
    </refsynopsisdiv>

    <refsect1>
        <title>Description</title>

        <para>
          Lists dynamic permissions for the given app which are stored
          in the Flatpak permission store.
        </para>

        <para>
          The permission store is used by portals.
          Each portal generally has its own table in the permission
          store, and the format of the table entries is specific to
          each portal.
        </para>

    </refsect1>

    <refsect1>
        <title>Options</title>

        <para>The following options are understood:</para>

        <variablelist>
            <varlistentry>
                <term><option>-h</option></term>
                <term><option>--help</option></term>

                <listitem><para>
                    Show help options and exit.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>-v</option></term>
                <term><option>--verbose</option></term>

                <listitem><para>
                    Print debug information during command processing.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--ostree-verbose</option></term>

                <listitem><para>
                    Print OSTree debug information during command processing.
                </para></listitem>
            </varlistentry>
        </variablelist>
    </refsect1>

    <refsect1>
        <title>See also</title>

        <para>
            <citerefentry><refentrytitle>flatpak</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
            <citerefentry><refentrytitle>flatpak-permissions</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
            <citerefentry><refentrytitle>flatpak-permission-remove</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
            <citerefentry><refentrytitle>flatpak-permission-reset</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
            <citerefentry><refentrytitle>flatpak-permission-set</refentrytitle><manvolnum>1</manvolnum></citerefentry>
        </para>

    </refsect1>

</refentry>

===== ./doc/meson.build =====
# Copyright 2022 Collabora Ltd.
# SPDX-License-Identifier: LGPL-2.1-or-later

if build_gtk_doc
  subdir('reference')
endif

xsltproc_flags = [
  '--nonet',
  '--stringparam', 'man.output.quietly', '1',
  '--stringparam', 'funcsynopsis.style', 'ansi',
  '--stringparam', 'man.th.extra1.suppress', '1',
  '--stringparam', 'man.authors.section.enabled', '0',
  '--stringparam', 'man.copyright.section.enabled', '0',
]

man1 = [
  'flatpak',
  'flatpak-remotes',
  'flatpak-remote-add',
  'flatpak-remote-delete',
  'flatpak-remote-modify',
  'flatpak-remote-ls',
  'flatpak-remote-info',
  'flatpak-install',
  'flatpak-config',
  'flatpak-update',
  'flatpak-uninstall',
  'flatpak-preinstall',
  'flatpak-mask',
  'flatpak-pin',
  'flatpak-list',
  'flatpak-info',
  'flatpak-make-current',
  'flatpak-run',
  'flatpak-override',
  'flatpak-enter',
  'flatpak-ps',
  'flatpak-document-export',
  'flatpak-document-unexport',
  'flatpak-document-info',
  'flatpak-documents',
  'flatpak-permission-remove',
  'flatpak-permissions',
  'flatpak-permission-show',
  'flatpak-permission-reset',
  'flatpak-permission-set',
  'flatpak-build-init',
  'flatpak-build',
  'flatpak-build-bundle',
  'flatpak-build-import-bundle',
  'flatpak-build-finish',
  'flatpak-build-export',
  'flatpak-build-update-repo',
  'flatpak-build-sign',
  'flatpak-build-commit-from',
  'flatpak-repo',
  'flatpak-search',
  'flatpak-create-usb',
  'flatpak-repair',
  'flatpak-kill',
  'flatpak-history',
  'flatpak-spawn',
]

man5 = [
  'flatpak-metadata',
  'flatpakrepo',
  'flatpakref',
  'flatpak-remote',
  'flatpak-installation',
]

man_compat_symlinks = [
   ['flatpak-flatpakrepo', 'flatpakrepo', '5'],
   ['flatpak-flatpakref', 'flatpakref', '5'],
]

xml_files = []

foreach pair : [[man1, '1'], [man5, '5']]
  pages = pair[0]
  section = pair[1]

  foreach man : pages
    xml_files += [man + '.xml']

    if build_man_pages
      custom_target(
        man + '.' + section,
        input : [man + '.xml'],
        output : [man + '.' + section],
        command : [
          xsltproc,
          '-o', '@OUTPUT@',
        ] + xsltproc_flags + [
          manpages_xsl,
          '@INPUT@',
        ],
        build_by_default : true,
        install : true,
        install_dir : get_option('mandir') / ('man' + section),
      )
    endif
  endforeach
endforeach

foreach entry : man_compat_symlinks
  name = entry[0]
  target = entry[1]
  section = entry[2]

  if build_man_pages
    #TODO: replace with install_symlink() when we can depend on meson 0.61
    meson.add_install_script(
      'sh', '-c', 'ln -sf @0@ $MESON_INSTALL_DESTDIR_PREFIX/@1@/@2@'.format(
        target + '.' + section,
        get_option('mandir') / ('man' + section),
        name + '.' + section
      )
    )
  endif
endforeach

if xmlto.found()
  cdata = configuration_data()
  cdata.set('VERSION', meson.project_version())
  cdata.set('srcdir', meson.current_source_dir())
  flatpak_docs_xml = configure_file(
    input : 'flatpak-docs.xml.in',
    output : 'flatpak-docs.xml',
    configuration : cdata,
  )
  custom_target(
    'flatpak-docs.html',
    input : [
      flatpak_docs_xml,
      'xmlto-config.xsl',
    ],
    output : ['flatpak-docs.html'],
    depend_files : xml_files,
    command : [
      xmlto,
      '-o', meson.current_build_dir(),
    ] + get_option('xmlto_flags') + [
      '--skip-validation',
      'xhtml-nochunks',
      '-m', '@INPUT1@',
      '@INPUT0@',
    ],
    build_by_default : true,
    install : true,
    install_dir : docdir,
  )
  install_data('docbook.css', install_dir : docdir)
endif

===== ./doc/flatpak-build-sign.xml =====
<?xml version='1.0'?> <!--*-nxml-*-->
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
    "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">

<refentry id="flatpak-build-sign">

    <refentryinfo>
        <title>flatpak build-sign</title>
        <productname>flatpak</productname>

        <authorgroup>
            <author>
                <contrib>Developer</contrib>
                <firstname>Alexander</firstname>
                <surname>Larsson</surname>
                <email>alexl@redhat.com</email>
            </author>
        </authorgroup>
    </refentryinfo>

    <refmeta>
        <refentrytitle>flatpak build-sign</refentrytitle>
        <manvolnum>1</manvolnum>
    </refmeta>

    <refnamediv>
        <refname>flatpak-build-sign</refname>
        <refpurpose>Sign an application or runtime</refpurpose>
    </refnamediv>

    <refsynopsisdiv>
            <cmdsynopsis>
                <command>flatpak build-sign</command>
                <arg choice="opt" rep="repeat">OPTION</arg>
                <arg choice="plain">LOCATION</arg>
                <arg choice="plain">ID</arg>
                <arg choice="opt">BRANCH</arg>
            </cmdsynopsis>
    </refsynopsisdiv>

    <refsect1>
        <title>Description</title>

        <para>
            Signs the commit for a specified application or runtime in
            a local repository.  <arg choice="plain">LOCATION</arg> is
            the location of the repository. <arg
            choice="plain">ID</arg> is the name of the application, or
            runtime if --runtime is specified. If <arg
            choice="plain">BRANCH</arg> is not specified, it is
            assumed to be "master".
        </para>
        <para>
            Applications can also be signed during build-export, but
            it is sometimes useful to add additional signatures later.
        </para>
    </refsect1>

    <refsect1>
        <title>Options</title>

        <para>The following options are understood:</para>

        <variablelist>
            <varlistentry>
                <term><option>-h</option></term>
                <term><option>--help</option></term>

                <listitem><para>
                    Show help options and exit.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--gpg-sign=KEYID</option></term>

                <listitem><para>
                    Sign the commit with this GPG key.
                    This option can be used multiple times.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--gpg-homedir=PATH</option></term>

                <listitem><para>
                    GPG Homedir to use when looking for keyrings
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--runtime</option></term>

                <listitem><para>
                    Sign a runtime instead of an app.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--arch=ARCH</option></term>

                <listitem><para>
                    The architecture to use. See <command>flatpak --supported-arches</command>
                    for architectures supported by the host.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>-v</option></term>
                <term><option>--verbose</option></term>

                <listitem><para>
                    Print debug information during command processing.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--ostree-verbose</option></term>

                <listitem><para>
                    Print OSTree debug information during command processing.
                </para></listitem>
            </varlistentry>
        </variablelist>
    </refsect1>

    <refsect1>
        <title>Examples</title>

        <para>
            <command>$ flatpak build-sign --gpg-sign=D8BA6573DDD2418027736F1BC33B315E53C1E9D6 /some/repo org.my.App</command>
        </para>

    </refsect1>

    <refsect1>
        <title>See also</title>

        <para>
            <citerefentry><refentrytitle>ostree</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
            <citerefentry><refentrytitle>flatpak</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
            <citerefentry><refentrytitle>flatpak-build-export</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
            <citerefentry><refentrytitle>flatpak-build</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
        </para>

    </refsect1>

</refentry>

===== ./doc/flatpak-build.xml =====
<?xml version='1.0'?> <!--*-nxml-*-->
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
    "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">

<refentry id="flatpak-build">

    <refentryinfo>
        <title>flatpak build</title>
        <productname>flatpak</productname>

        <authorgroup>
            <author>
                <contrib>Developer</contrib>
                <firstname>Alexander</firstname>
                <surname>Larsson</surname>
                <email>alexl@redhat.com</email>
            </author>
        </authorgroup>
    </refentryinfo>

    <refmeta>
        <refentrytitle>flatpak build</refentrytitle>
        <manvolnum>1</manvolnum>
    </refmeta>

    <refnamediv>
        <refname>flatpak-build</refname>
        <refpurpose>Build in a directory</refpurpose>
    </refnamediv>

    <refsynopsisdiv>
            <cmdsynopsis>
                <command>flatpak build</command>
                <arg choice="opt" rep="repeat">OPTION</arg>
                <arg choice="plain">DIRECTORY</arg>
                <arg choice="opt">COMMAND <arg choice="opt" rep="repeat">ARG</arg></arg>
            </cmdsynopsis>
    </refsynopsisdiv>

    <refsect1>
        <title>Description</title>

        <para>
            Runs a build command in a directory. <arg choice="plain">DIRECTORY</arg>
            must have been initialized with <command>flatpak build-init</command>.
        </para>
        <para>
            The sdk that is specified in the <filename>metadata</filename> file
            in the directory is mounted at <filename>/usr</filename> and the
            <filename>files</filename> and <filename>var</filename> subdirectories
            are mounted at <filename>/app</filename> and <filename>/var</filename>,
            respectively. They are writable, and their contents are preserved between
            build commands, to allow accumulating build artifacts there.
        </para>
    </refsect1>

    <refsect1>
        <title>Options</title>

        <para>The following options are understood:</para>

        <variablelist>
            <varlistentry>
                <term><option>-h</option></term>
                <term><option>--help</option></term>

                <listitem><para>
                    Show help options and exit.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>-v</option></term>
                <term><option>--verbose</option></term>

                <listitem><para>
                    Print debug information during command processing.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--ostree-verbose</option></term>

                <listitem><para>
                    Print OSTree debug information during command processing.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>-r</option></term>
                <term><option>--runtime</option></term>

                <listitem><para>
                    Use the non-devel runtime that is specified in the application metadata instead of the devel runtime.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>-p</option></term>
                <term><option>--die-with-parent</option></term>

                <listitem><para>
                    Kill the build process and all children when the launching process dies.
                </para></listitem>
            </varlistentry>

           <varlistentry>
                <term><option>--bind-mount=DEST=SOURCE</option></term>

                <listitem><para>
                    Add a custom bind mount in the build namespace. Can be specified multiple times.
                </para></listitem>
            </varlistentry>

           <varlistentry>
                <term><option>--build-dir=PATH</option></term>

                <listitem><para>
                    Start the build in this directory (default is in the current directory).
                </para></listitem>
            </varlistentry>

           <varlistentry>
                <term><option>--share=SUBSYSTEM</option></term>

                <listitem><para>
                    Share a subsystem with the host session. This overrides
                    the Context section from the application metadata.
                    <arg choice="plain">SUBSYSTEM</arg> must be one of: network, ipc.
                    This option can be used multiple times.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--unshare=SUBSYSTEM</option></term>

                <listitem><para>
                    Don't share a subsystem with the host session. This overrides
                    the Context section from the application metadata.
                    <arg choice="plain">SUBSYSTEM</arg> must be one of: network, ipc.
                    This option can be used multiple times.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--socket=SOCKET</option></term>

                <listitem><para>
                    Expose a well-known socket to the application. This overrides to
                    the Context section from the application metadata.
                    <arg choice="plain">SOCKET</arg> must be one of: x11, wayland, fallback-x11, pulseaudio, system-bus, session-bus,
                    ssh-auth, pcsc, cups, gpg-agent, inherit-wayland-socket.
                    This option can be used multiple times.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--nosocket=SOCKET</option></term>

                <listitem><para>
                    Don't expose a well-known socket to the application. This overrides to
                    the Context section from the application metadata.
                    <arg choice="plain">SOCKET</arg> must be one of: x11, wayland, fallback-x11, pulseaudio, system-bus, session-bus,
                    ssh-auth, pcsc, cups, gpg-agent, inherit-wayland-socket.
                    This option can be used multiple times.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--device=DEVICE</option></term>

                <listitem><para>
                    Expose a device to the application. This overrides to
                    the Context section from the application metadata.
                    <arg choice="plain">DEVICE</arg> must be one of: dri, input, usb, kvm, shm, all.
                    This option can be used multiple times.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--nodevice=DEVICE</option></term>

                <listitem><para>
                    Don't expose a device to the application. This overrides to
                    the Context section from the application metadata.
                    <arg choice="plain">DEVICE</arg> must be one of: dri, input, usb, kvm, shm, all.
                    This option can be used multiple times.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--allow=FEATURE</option></term>

                <listitem><para>
                    Allow access to a specific feature. This updates
                    the [Context] group in the metadata.
                    <arg choice="plain">FEATURE</arg> must be one of:
                    devel, multiarch, bluetooth, canbus,
                    per-app-dev-shm.
                    This option can be used multiple times.
                    </para><para>
                    See <citerefentry><refentrytitle>flatpak-build-finish</refentrytitle><manvolnum>1</manvolnum></citerefentry>
                    for the meaning of the various features.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--disallow=FEATURE</option></term>

                <listitem><para>
                    Disallow access to a specific feature. This updates
                    the [Context] group in the metadata.
                    <arg choice="plain">FEATURE</arg> must be one of:
                    devel, multiarch, bluetooth, canbus,
                    per-app-dev-shm.
                    This option can be used multiple times.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--filesystem=FILESYSTEM[:ro|:create]</option></term>

                <listitem><para>
                    Allow the application access to a subset of the filesystem.
                    This overrides to the Context section from the application metadata.
                    <arg choice="plain">FILESYSTEM</arg> can be one of: home, host, host-os, host-etc, host-root, xdg-desktop, xdg-documents, xdg-download,
                    xdg-music, xdg-pictures, xdg-public-share, xdg-templates, xdg-videos, xdg-run,
                    xdg-config, xdg-cache, xdg-data, an absolute path, or a homedir-relative
                    path like ~/dir or paths relative to the xdg dirs, like xdg-download/subdir.
                    The optional :ro suffix indicates that the location will be read-only.
                    The optional :create suffix indicates that the location will be read-write and created if it doesn't exist.
                    This option can be used multiple times.
                    See the "[Context] filesystems" list in
                    <citerefentry><refentrytitle>flatpak-metadata</refentrytitle><manvolnum>5</manvolnum></citerefentry>
                    for details of the meanings of these filesystems.
                    Before flatpak 1.17.0, access to host was granted by default.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--nofilesystem=FILESYSTEM</option></term>

                <listitem><para>
                    Remove access to the specified subset of the filesystem from
                    the application. This overrides to the Context section from the
                    application metadata.
                    <arg choice="plain">FILESYSTEM</arg> can be one of: home, host, host-os, host-etc, host-root xdg-desktop, xdg-documents, xdg-download,
                    xdg-music, xdg-pictures, xdg-public-share, xdg-templates, xdg-videos,
                    an absolute path, or a homedir-relative path like ~/dir.
                    This option can be used multiple times.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--with-appdir</option></term>

                <listitem><para>
                  Expose and configure access to the per-app storage directory in <filename>$HOME/.var/app</filename>. This is
                  not normally useful when building, but helps when testing built apps.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--add-policy=SUBSYSTEM.KEY=VALUE</option></term>

                <listitem><para>
                    Add generic policy option. For example, "--add-policy=subsystem.key=v1 --add-policy=subsystem.key=v2" would map to this metadata:
<programlisting>
[Policy subsystem]
key=v1;v2;
</programlisting>
                </para><para>
                    This option can be used multiple times.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--remove-policy=SUBSYSTEM.KEY=VALUE</option></term>

                <listitem><para>
                    Remove generic policy option. This option can be used multiple times.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--env=VAR=VALUE</option></term>

                <listitem><para>
                    Set an environment variable in the application.
                    This overrides to the Context section from the application metadata.
                    This option can be used multiple times.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--unset-env=VAR</option></term>

                <listitem><para>
                    Unset an environment variable in the application.
                    This overrides the unset-environment entry in the [Context]
                    group of the metadata, and the [Environment] group.
                    This option can be used multiple times.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--env-fd=<replaceable>FD</replaceable></option></term>

                <listitem><para>
                    Read environment variables from the file descriptor
                    <replaceable>FD</replaceable>, and set them as if
                    via <option>--env</option>. This can be used to avoid
                    environment variables and their values becoming visible
                    to other users.
                </para><para>
                    Each environment variable is in the form
                    <replaceable>VAR</replaceable>=<replaceable>VALUE</replaceable>
                    followed by a zero byte. This is the same format used by
                    <literal>env -0</literal> and
                    <filename>/proc/*/environ</filename>.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--own-name=NAME</option></term>

                <listitem><para>
                    Allow the application to own the well-known name NAME on the session bus.
                    This overrides to the Context section from the application metadata.
                    This option can be used multiple times.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--talk-name=NAME</option></term>

                <listitem><para>
                    Allow the application to talk to the well-known name NAME on the session bus.
                    This overrides to the Context section from the application metadata.
                    This option can be used multiple times.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--system-own-name=NAME</option></term>

                <listitem><para>
                    Allow the application to own the well-known name NAME on the system bus.
                    This overrides to the Context section from the application metadata.
                    This option can be used multiple times.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--system-talk-name=NAME</option></term>

                <listitem><para>
                    Allow the application to talk to the well-known name NAME on the system bus.
                    This overrides to the Context section from the application metadata.
                    This option can be used multiple times.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--persist=FILENAME</option></term>

                <listitem><para>
                    If the application doesn't have access to the real homedir, make the (homedir-relative) path
                    <arg choice="plain">FILENAME</arg> a bind mount to the corresponding path in the per-application directory,
                    allowing that location to be used for persistent data.
                    This overrides to the Context section from the application metadata.
                    This option can be used multiple times.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--sdk-dir=DIR</option></term>

                <listitem><para>
                  Normally if there is a <filename>usr</filename> directory in the build dir, this is used
                  for the runtime files (this can be created by <option>--writable-sdk</option> or <option>--type=runtime</option> arguments
                  to build-init). If you specify <option>--sdk-dir</option>, this directory will be used instead.
                  Use this if you passed <option>--sdk-dir</option> to build-init.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--readonly</option></term>

                <listitem><para>
                  Mount the normally writable destination directories read-only. This can
                  be useful if you want to run something in the sandbox but guarantee that
                  it doesn't affect the build results. For example tests.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--metadata=FILE</option></term>

                <listitem><para>
                  Use the specified filename as metadata in the exported app instead of
                  the default file (called <filename>metadata</filename>). This is useful
                  if you build multiple things from a single build tree (such as both a
                  platform and a sdk).
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--log-session-bus</option></term>

                <listitem><para>
                    Log session bus traffic. This can be useful to see what access you need to allow in
                    your D-Bus policy.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--log-system-bus</option></term>

                <listitem><para>
                    Log system bus traffic. This can be useful to see what access you need to allow in
                    your D-Bus policy.
                </para></listitem>
            </varlistentry>

          </variablelist>
    </refsect1>

    <refsect1>
        <title>Examples</title>

        <para>
            <command>$ flatpak build /build/my-app rpmbuild my-app.src.rpm</command>
        </para>

    </refsect1>

    <refsect1>
        <title>See also</title>

        <para>
            <citerefentry><refentrytitle>flatpak</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
            <citerefentry><refentrytitle>flatpak-build-init</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
            <citerefentry><refentrytitle>flatpak-build-finish</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
            <citerefentry><refentrytitle>flatpak-build-export</refentrytitle><manvolnum>1</manvolnum></citerefentry>
        </para>

    </refsect1>

</refentry>

===== ./doc/flatpak-document-export.xml =====
<?xml version='1.0'?> <!--*-nxml-*-->
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
    "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">

<refentry id="flatpak-document-export">

    <refentryinfo>
        <title>flatpak document-export</title>
        <productname>flatpak</productname>

        <authorgroup>
            <author>
                <contrib>Developer</contrib>
                <firstname>Alexander</firstname>
                <surname>Larsson</surname>
                <email>alexl@redhat.com</email>
            </author>
        </authorgroup>
    </refentryinfo>

    <refmeta>
        <refentrytitle>flatpak document-export</refentrytitle>
        <manvolnum>1</manvolnum>
    </refmeta>

    <refnamediv>
        <refname>flatpak-document-export</refname>
        <refpurpose>Export a file to a sandboxed application</refpurpose>
    </refnamediv>

    <refsynopsisdiv>
            <cmdsynopsis>
                <command>flatpak document-export</command>
                <arg choice="opt" rep="repeat">OPTION</arg>
                <arg choice="plain">FILE</arg>
            </cmdsynopsis>
    </refsynopsisdiv>

    <refsect1>
        <title>Description</title>

        <para>
            Creates a document id for a local file that can be exposed to
            sandboxed applications, allowing them access to files that they
            would not otherwise see. The exported files are exposed in a
            fuse filesystem at <filename>/run/user/$UID/doc/</filename>.
        </para>

        <para>
            This command also lets you modify the per-application
            permissions of the documents, granting or revoking access
            to the file on a per-application basis.
        </para>

    </refsect1>

    <refsect1>
        <title>Options</title>

        <para>The following options are understood:</para>

        <variablelist>
            <varlistentry>
                <term><option>-h</option></term>
                <term><option>--help</option></term>

                <listitem><para>
                    Show help options and exit.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>-u</option></term>
                <term><option>--unique</option></term>

                <listitem><para> Don't reuse an existing document id
                for the file.  This makes it safe to later remove the
                document when you're finished with it.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>-t</option></term>
                <term><option>--transient</option></term>

                <listitem><para>
                  The document will only exist for the length of
                  the session. This is useful for temporary grants.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>-n</option></term>
                <term><option>--noexist</option></term>

                <listitem><para>
                  Don't require the file to exist already.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>-a</option></term>
                <term><option>--app=APPID</option></term>

                <listitem><para>
                  Grant read access to the specified application. The
                  <option>--allow</option> and <option>--forbid</option> options
                  can be used to grant or remove additional privileges.
                  This option can be used multiple times.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>-r</option></term>
                <term><option>--allow-read</option></term>

                <listitem><para>
                  Grant read access to the applications specified with <option>--app</option>.
                  This defaults to TRUE.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--forbid-read</option></term>

                <listitem><para>
                  Revoke read access for the applications specified with <option>--app</option>.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>-w</option></term>
                <term><option>--allow-write</option></term>

                <listitem><para>
                  Grant write access to the applications specified with <option>--app</option>.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--forbid-write</option></term>

                <listitem><para>
                  Revoke write access for the applications specified with <option>--app</option>.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>-d</option></term>
                <term><option>--allow-delete</option></term>

                <listitem><para>
                  Grant the ability to remove the document from the document portal to the applications specified with <option>--app</option>.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--forbid-delete</option></term>

                <listitem><para>
                  Revoke the ability to remove the document from the document portal from the applications specified with <option>--app</option>.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>-g</option></term>
                <term><option>--allow-grant-permission</option></term>

                <listitem><para>
                  Grant the ability to grant further permissions to the applications specified with <option>--app</option>.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--forbid-grant-permission</option></term>

                <listitem><para>
                  Revoke the ability to grant further permissions for the applications specified with <option>--app</option>.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>-v</option></term>
                <term><option>--verbose</option></term>

                <listitem><para>
                    Print debug information during command processing.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--ostree-verbose</option></term>

                <listitem><para>
                    Print OSTree debug information during command processing.
                </para></listitem>
            </varlistentry>
        </variablelist>
    </refsect1>

    <refsect1>
        <title>Examples</title>

        <para>
            <command>$ flatpak document-export --app=org.gnome.gedit ~/test.txt</command>
        </para>
<programlisting>
/run/user/1000/doc/e52f9c6a/test.txt
</programlisting>

    </refsect1>

    <refsect1>
        <title>See also</title>

        <para>
            <citerefentry><refentrytitle>flatpak</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
            <citerefentry><refentrytitle>flatpak-document-unexport</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
            <citerefentry><refentrytitle>flatpak-document-info</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
            <citerefentry><refentrytitle>flatpak-documents</refentrytitle><manvolnum>1</manvolnum></citerefentry>
        </para>

    </refsect1>

</refentry>


===== ./doc/flatpak-override.xml =====
<?xml version='1.0'?> <!--*-nxml-*-->
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
    "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">

<refentry id="flatpak-override">

    <refentryinfo>
        <title>flatpak override</title>
        <productname>flatpak</productname>

        <authorgroup>
            <author>
                <contrib>Developer</contrib>
                <firstname>Alexander</firstname>
                <surname>Larsson</surname>
                <email>alexl@redhat.com</email>
            </author>
        </authorgroup>
    </refentryinfo>

    <refmeta>
        <refentrytitle>flatpak override</refentrytitle>
        <manvolnum>1</manvolnum>
    </refmeta>

    <refnamediv>
        <refname>flatpak-override</refname>
        <refpurpose>Override application requirements</refpurpose>
    </refnamediv>

    <refsynopsisdiv>
            <cmdsynopsis>
                <command>flatpak override</command>
                <arg choice="opt" rep="repeat">OPTION</arg>
                <arg choice="opt">APP</arg>
            </cmdsynopsis>
    </refsynopsisdiv>

    <refsect1>
        <title>Description</title>

        <para>
            Overrides the application specified runtime requirements. This can be used
            to grant a sandboxed application more or less resources than it requested.
        </para>
        <para>
            By default the application gets access to the resources it
            requested when it is started. But the user can override it
            on a particular instance by specifying extra arguments to
            <command>flatpak run</command>, or every time by using
            <command>flatpak override</command>.
        </para>
        <para>
            The application overrides are saved in text files residing in $XDG_DATA_HOME/flatpak/overrides in user mode. 
        </para>
        <para>
            If the application ID <arg choice="plain">APP</arg> is not specified
            then the overrides affect all applications,
            but the per-application overrides can override the global overrides.
        </para>
        <para>
            Unless overridden with the <option>--user</option> or <option>--installation</option> options, this command
            changes the default system-wide installation.
        </para>

    </refsect1>

    <refsect1>
        <title>Options</title>

        <para>The following options are understood:</para>

        <variablelist>
            <varlistentry>
                <term><option>-h</option></term>
                <term><option>--help</option></term>

                <listitem><para>
                    Show help options and exit.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>-u</option></term>
                <term><option>--user</option></term>

                <listitem><para>
                    Update a per-user installation.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--system</option></term>

                <listitem><para>
                    Update the default system-wide installation.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--installation=NAME</option></term>

                <listitem><para>
                    Updates a system-wide installation specified by <arg choice="plain">NAME</arg>
                    among those defined in <filename>/etc/flatpak/installations.d/</filename>.
                    Using <option>--installation=default</option> is equivalent to using
                    <option>--system</option>.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--share=SUBSYSTEM</option></term>

                <listitem><para>
                    Share a subsystem with the host session. This overrides
                    the Context section from the application metadata.
                    <arg choice="plain">SUBSYSTEM</arg> must be one of: network, ipc.
                    This option can be used multiple times.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--unshare=SUBSYSTEM</option></term>

                <listitem><para>
                    Don't share a subsystem with the host session. This overrides
                    the Context section from the application metadata.
                    <arg choice="plain">SUBSYSTEM</arg> must be one of: network, ipc.
                    This option can be used multiple times.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--share-if=SUBSYSTEM:CONDITION</option></term>

                <listitem><para>
                    Share a subsystem with the host session conditionally,
                    only when the specified condition is met at runtime.
                    This overrides to the Context section from the application metadata.
                    <arg choice="plain">SUBSYSTEM</arg> must be one of: network, ipc.
                    <arg choice="plain">CONDITION</arg> must be one of:
                    <option>true</option>, <option>false</option>,
                    <option>has-input-device</option>, <option>has-wayland</option>,
                    <option>has-usb-device</option>, <option>has-usb-portal</option>.
                    Conditions can be negated with <literal>!</literal>,
                    for example <option>!has-input-device</option>.
                    This option can be used multiple times.
                    Available since 1.17.
                </para><para>
                    See the Conditional Permissions section in
                    <citerefentry><refentrytitle>flatpak-metadata</refentrytitle><manvolnum>5</manvolnum></citerefentry>
                    for more details.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--socket=SOCKET</option></term>

                <listitem><para>
                    Expose a well-known socket to the application. This overrides to
                    the Context section from the application metadata.
                    <arg choice="plain">SOCKET</arg> must be one of: x11, wayland, fallback-x11, pulseaudio, system-bus, session-bus,
                    ssh-auth, pcsc, cups, gpg-agent, inherit-wayland-socket.
                    This option can be used multiple times.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--nosocket=SOCKET</option></term>

                <listitem><para>
                    Don't expose a well-known socket to the application. This overrides to
                    the Context section from the application metadata.
                    <arg choice="plain">SOCKET</arg> must be one of: x11, wayland, fallback-x11, pulseaudio, system-bus, session-bus,
                    ssh-auth, pcsc, cups, gpg-agent, inherit-wayland-socket.
                    This option can be used multiple times.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--socket-if=SOCKET:CONDITION</option></term>

                <listitem><para>
                    Expose a well-known socket to the application conditionally,
                    only when the specified condition is met at runtime.
                    This overrides to the Context section from the application
                    metadata.
                    <arg choice="plain">SOCKET</arg> must be one of: x11, wayland, fallback-x11, pulseaudio, system-bus, session-bus,
                    ssh-auth, pcsc, cups, gpg-agent, inherit-wayland-socket.
                    <arg choice="plain">CONDITION</arg> must be one of: true, false, has-input-device, has-wayland, has-usb-device, has-usb-portal.
                    Conditions can be negated with <literal>!</literal>,
                    for example <option>!has-wayland</option>.
                    This option can be used multiple times.
                    Available since 1.17.
                </para><para>
                    See the Conditional Permissions section in
                    <citerefentry><refentrytitle>flatpak-metadata</refentrytitle><manvolnum>5</manvolnum></citerefentry>
                    for more details.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--device=DEVICE</option></term>

                <listitem><para>
                    Expose a device to the application. This overrides to
                    the Context section from the application metadata.
                    <arg choice="plain">DEVICE</arg> must be one of: dri, input, usb, kvm, shm, all.
                    This option can be used multiple times.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--nodevice=DEVICE</option></term>

                <listitem><para>
                    Don't expose a device to the application. This overrides to
                    the Context section from the application metadata.
                    <arg choice="plain">DEVICE</arg> must be one of: dri, input, usb, kvm, shm, all.
                    This option can be used multiple times.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--device-if=DEVICE:CONDITION</option></term>

                <listitem><para>
                    Expose a device to the application conditionally,
                    only when the specified condition is met at runtime.
                    This overrides to the Context section from the application
                    metadata.
                    <arg choice="plain">DEVICE</arg> must be one of: dri, input, usb, kvm, shm, all.
                    <arg choice="plain">CONDITION</arg> must be one of: true, false, has-input-device, has-wayland, has-usb-device, has-usb-portal.
                    Conditions can be negated with <literal>!</literal>,
                    for example <option>!has-input-device</option>.
                    This option can be used multiple times.
                    Available since 1.17.
                </para><para>
                    See the Conditional Permissions section in
                    <citerefentry><refentrytitle>flatpak-metadata</refentrytitle><manvolnum>5</manvolnum></citerefentry>
                    for more details.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--allow=FEATURE</option></term>

                <listitem><para>
                    Allow access to a specific feature. This updates
                    the [Context] group in the metadata.
                    <arg choice="plain">FEATURE</arg> must be one of:
                    devel, multiarch, bluetooth, canbus,
                    per-app-dev-shm.
                    This option can be used multiple times.
                 </para><para>
                    See <citerefentry><refentrytitle>flatpak-build-finish</refentrytitle><manvolnum>1</manvolnum></citerefentry>
                    for the meaning of the various features.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--disallow=FEATURE</option></term>

                <listitem><para>
                    Disallow access to a specific feature. This updates
                    the [Context] group in the metadata.
                    <arg choice="plain">FEATURE</arg> must be one of:
                    devel, multiarch, bluetooth, canbus,
                    per-app-dev-shm.
                    This option can be used multiple times.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--allow-if=FEATURE:CONDITION</option></term>

                <listitem><para>
                    Allow access to a specific feature conditionally,
                    only when the specified condition is met at runtime.
                    This overrides to the Context section from the application metadata.
                    <arg choice="plain">FEATURE</arg> must be one of: devel, multiarch, bluetooth.
                    <arg choice="plain">CONDITION</arg> must be one of:
                    <option>true</option>, <option>false</option>,
                    <option>has-input-device</option>, <option>has-wayland</option>,
                    <option>has-usb-device</option>, <option>has-usb-portal</option>.
                    Conditions can be negated with <literal>!</literal>,
                    for example <option>!has-input-device</option>.
                    This option can be used multiple times.
                    Available since 1.17.
                </para><para>
                    See the Conditional Permissions section in
                    <citerefentry><refentrytitle>flatpak-metadata</refentrytitle><manvolnum>5</manvolnum></citerefentry>
                    for more details.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--filesystem=FILESYSTEM</option></term>

                <listitem><para>
                    Allow the application access to a subset of the filesystem.
                    This overrides to the Context section from the application metadata.
                    <arg choice="plain">FILESYSTEM</arg> can be one of: home, host, host-os, host-etc, host-root, xdg-desktop, xdg-documents, xdg-download,
                    xdg-music, xdg-pictures, xdg-public-share, xdg-templates, xdg-videos, xdg-run,
                    xdg-config, xdg-cache, xdg-data,
                    an absolute path, or a homedir-relative path like ~/dir or paths
                    relative to the xdg dirs, like xdg-download/subdir.
                    The optional :ro suffix indicates that the location will be read-only.
                    The optional :create suffix indicates that the location will be read-write and created if it doesn't exist.
                    This option can be used multiple times.
                    See the "[Context] filesystems" list in
                    <citerefentry><refentrytitle>flatpak-metadata</refentrytitle><manvolnum>5</manvolnum></citerefentry>
                    for details of the meanings of these filesystems.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--nofilesystem=FILESYSTEM</option></term>

                <listitem><para>
                    Undo the effect of a previous
                    <option>--filesystem=</option><arg choice="plain">FILESYSTEM</arg>
                    in the app's manifest or a lower-precedence layer of
                    overrides, and/or remove a previous
                    <option>--filesystem=</option><arg choice="plain">FILESYSTEM</arg>
                    from this layer of overrides.
                    This overrides the Context section of the
                    application metadata.
                    <arg choice="plain">FILESYSTEM</arg> can take the same
                    values as for <option>--filesystem</option>, but the
                    <arg choice="plain">:ro</arg> and
                    <arg choice="plain">:create</arg> suffixes are not
                    used here.
                    This option can be used multiple times.
                </para><para>
                    This option does not prevent access to a more
                    narrowly-scoped <option>--filesystem</option>.
                    For example, if an application has the equivalent of
                    <option>--filesystem=xdg-config/MyApp</option> in
                    its manifest or as a system-wide override, and
                    <literal>flatpak override --user --nofilesystem=home</literal>
                    as a per-user override, then it will be prevented from
                    accessing most of the home directory, but it will still
                    be allowed to access
                    <filename>$XDG_CONFIG_HOME/MyApp</filename>.
                </para><para>
                    As a special case,
                    <option>--nofilesystem=host:reset</option>
                    will ignore all <option>--filesystem</option>
                    permissions inherited from the app manifest or a
                    lower-precedence layer of overrides, in addition to
                    having the behaviour of
                    <option>--nofilesystem=host</option>.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--add-policy=SUBSYSTEM.KEY=VALUE</option></term>

                <listitem><para>
                    Add generic policy option. For example, "--add-policy=subsystem.key=v1 --add-policy=subsystem.key=v2" would map to this metadata:
<programlisting>
[Policy subsystem]
key=v1;v2;
</programlisting>
                </para><para>
                    This option can be used multiple times.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--remove-policy=SUBSYSTEM.KEY=VALUE</option></term>

                <listitem><para>
                    Remove generic policy option. This option can be used multiple times.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--env=VAR=VALUE</option></term>

                <listitem><para>
                    Set an environment variable in the application.
                    This overrides to the Context section from the application metadata.
                    This option can be used multiple times.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--unset-env=VAR</option></term>

                <listitem><para>
                    Unset an environment variable in the application.
                    This overrides the unset-environment entry in the [Context]
                    group of the metadata, and the [Environment] group.
                    This option can be used multiple times.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--env-fd=<replaceable>FD</replaceable></option></term>

                <listitem><para>
                    Read environment variables from the file descriptor
                    <replaceable>FD</replaceable>, and set them as if
                    via <option>--env</option>. This can be used to avoid
                    environment variables and their values becoming visible
                    to other users.
                </para><para>
                    Each environment variable is in the form
                    <replaceable>VAR</replaceable>=<replaceable>VALUE</replaceable>
                    followed by a zero byte. This is the same format used by
                    <literal>env -0</literal> and
                    <filename>/proc/*/environ</filename>.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--own-name=NAME</option></term>

                <listitem><para>
                    Allow the application to own the well-known name <arg choice="plain">NAME</arg> on the session bus.
                    This overrides to the Context section from the application metadata.
                    This option can be used multiple times.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--talk-name=NAME</option></term>

                <listitem><para>
                    Allow the application to talk to the well-known name <arg choice="plain">NAME</arg> on the session bus.
                    This overrides to the Context section from the application metadata.
                    This option can be used multiple times.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--no-talk-name=NAME</option></term>

                <listitem><para>
                    Don't allow the application to talk to the well-known name <arg choice="plain">NAME</arg> on the session bus.
                    This overrides to the Context section from the application metadata.
                    This option can be used multiple times.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--system-own-name=NAME</option></term>

                <listitem><para>
                    Allow the application to own the well known name <arg choice="plain">NAME</arg> on the system bus.
                    If <arg choice="plain">NAME</arg> ends with .*, it allows the application to own all matching names.
                    This overrides to the Context section from the application metadata.
                    This option can be used multiple times.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--system-talk-name=NAME</option></term>

                <listitem><para>
                    Allow the application to talk to the well known name <arg choice="plain">NAME</arg> on the system bus.
                    If <arg choice="plain">NAME</arg> ends with .*, it allows the application to talk to all matching names.
                    This overrides to the Context section from the application metadata.
                    This option can be used multiple times.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--system-no-talk-name=NAME</option></term>

                <listitem><para>
                    Don't allow the application to talk to the well known name <arg choice="plain">NAME</arg> on the system bus.
                    If <arg choice="plain">NAME</arg> ends with .*, it allows the application to talk to all matching names.
                    This overrides to the Context section from the application metadata.
                    This option can be used multiple times.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--persist=FILENAME</option></term>

                <listitem><para>
                    If the application doesn't have access to the real homedir, make the (homedir-relative) path
                    <arg choice="plain">FILENAME</arg> a bind mount to the corresponding path in the per-application directory,
                    allowing that location to be used for persistent data.
                    This overrides to the Context section from the application metadata.
                    This option can be used multiple times.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--reset</option></term>

                <listitem><para>
                    Remove overrides. If an <arg choice="plain">APP</arg> is given, remove the overrides for that
                    application, otherwise remove the global overrides.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--show</option></term>

                <listitem><para>
                    Shows overrides. If an <arg choice="plain">APP</arg> is given, shows the overrides for that
                    application, otherwise shows the global overrides.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>-v</option></term>
                <term><option>--verbose</option></term>

                <listitem><para>
                    Print debug information during command processing.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--ostree-verbose</option></term>

                <listitem><para>
                    Print OSTree debug information during command processing.
                </para></listitem>
            </varlistentry>
        </variablelist>
    </refsect1>

    <refsect1>
        <title>Examples</title>

        <para>
            <command>$ flatpak override --nosocket=wayland org.gnome.gedit</command>
        </para>
        <para>
            <command>$ flatpak override --filesystem=home org.mozilla.Firefox</command>
        </para>
        <para>
            <command>$ flatpak override --socket-if=x11:!has-wayland org.example.App</command>
        </para>
        <para>
            Grant X11 socket access only when not running in a Wayland session.
        </para>

    </refsect1>

    <refsect1>
        <title>See also</title>

        <para>
            <citerefentry><refentrytitle>flatpak</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
            <citerefentry><refentrytitle>flatpak-run</refentrytitle><manvolnum>1</manvolnum></citerefentry>
        </para>

    </refsect1>

</refentry>

===== ./doc/flatpak-docs.xml.in =====
<?xml version="1.0"?>
<!DOCTYPE reference PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
               "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
<!ENTITY % local.common.attrib "xmlns:xi  CDATA  #FIXED 'http://www.w3.org/2003/XInclude'">
]>
<reference xmlns:xi="http://www.w3.org/2003/XInclude">
    <referenceinfo>
      <releaseinfo>Version @VERSION@</releaseinfo>
    </referenceinfo>
    <title>Flatpak Command Reference</title>
    <important>
        <para>
            The command reference is generated from the flatpak repo; see <ulink url="https://github.com/flatpak/flatpak/tree/main/doc"></ulink>
        </para>
    </important>
    <partintro>
      <para>
        Flatpak comes with a rich commandline interface.
      </para>
    </partintro>
    <chapter>
      <title>Executables</title>
      <xi:include href="@srcdir@/flatpak.xml"/>
    </chapter>
    <chapter>
      <title>Commands</title>
      <xi:include href="@srcdir@/flatpak-build-bundle.xml"/>
      <xi:include href="@srcdir@/flatpak-build-commit-from.xml"/>
      <xi:include href="@srcdir@/flatpak-build-export.xml"/>
      <xi:include href="@srcdir@/flatpak-build-finish.xml"/>
      <xi:include href="@srcdir@/flatpak-build-import-bundle.xml"/>
      <xi:include href="@srcdir@/flatpak-build-init.xml"/>
      <xi:include href="@srcdir@/flatpak-build-sign.xml"/>
      <xi:include href="@srcdir@/flatpak-build-update-repo.xml"/>
      <xi:include href="@srcdir@/flatpak-build.xml"/>
      <xi:include href="@srcdir@/flatpak-config.xml"/>
      <xi:include href="@srcdir@/flatpak-create-usb.xml"/>
      <xi:include href="@srcdir@/flatpak-document-export.xml"/>
      <xi:include href="@srcdir@/flatpak-document-info.xml"/>
      <xi:include href="@srcdir@/flatpak-documents.xml"/>
      <xi:include href="@srcdir@/flatpak-document-unexport.xml"/>
      <xi:include href="@srcdir@/flatpak-enter.xml"/>
      <xi:include href="@srcdir@/flatpak-history.xml"/>
      <xi:include href="@srcdir@/flatpak-info.xml"/>
      <xi:include href="@srcdir@/flatpak-install.xml"/>
      <xi:include href="@srcdir@/flatpak-kill.xml"/>
      <xi:include href="@srcdir@/flatpak-list.xml"/>
      <xi:include href="@srcdir@/flatpak-make-current.xml"/>
      <xi:include href="@srcdir@/flatpak-override.xml"/>
      <xi:include href="@srcdir@/flatpak-permission-remove.xml"/>
      <xi:include href="@srcdir@/flatpak-permissions.xml"/>
      <xi:include href="@srcdir@/flatpak-permission-show.xml"/>
      <xi:include href="@srcdir@/flatpak-permission-reset.xml"/>
      <xi:include href="@srcdir@/flatpak-permission-set.xml"/>
      <xi:include href="@srcdir@/flatpak-preinstall.xml"/>
      <xi:include href="@srcdir@/flatpak-ps.xml"/>
      <xi:include href="@srcdir@/flatpak-remote-add.xml"/>
      <xi:include href="@srcdir@/flatpak-remote-delete.xml"/>
      <xi:include href="@srcdir@/flatpak-remote-info.xml"/>
      <xi:include href="@srcdir@/flatpak-remote-ls.xml"/>
      <xi:include href="@srcdir@/flatpak-remote-modify.xml"/>
      <xi:include href="@srcdir@/flatpak-remotes.xml"/>
      <xi:include href="@srcdir@/flatpak-repair.xml"/>
      <xi:include href="@srcdir@/flatpak-repo.xml"/>
      <xi:include href="@srcdir@/flatpak-run.xml"/>
      <xi:include href="@srcdir@/flatpak-search.xml"/>
      <xi:include href="@srcdir@/flatpak-uninstall.xml"/>
      <xi:include href="@srcdir@/flatpak-update.xml"/>
      <xi:include href="@srcdir@/flatpak-spawn.xml"/>
    </chapter>
    <chapter>
      <title>File Formats</title>
      <xi:include href="@srcdir@/flatpakrepo.xml"/>
      <xi:include href="@srcdir@/flatpakref.xml"/>
      <xi:include href="@srcdir@/flatpak-installation.xml"/>
      <xi:include href="@srcdir@/flatpak-metadata.xml"/>
      <xi:include href="@srcdir@/flatpak-remote.xml"/>
    </chapter>
</reference>

===== ./doc/flatpakrepo.xml =====
<?xml version='1.0'?> <!--*-nxml-*-->
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
    "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">

<refentry id="flatpakrepo">

    <refentryinfo>
        <title>flatpakrepo</title>
        <productname>flatpak</productname>

        <authorgroup>
            <author>
                <contrib>Developer</contrib>
                <firstname>Alexander</firstname>
                <surname>Larsson</surname>
                <email>alexl@redhat.com</email>
            </author>
        </authorgroup>
    </refentryinfo>

    <refmeta>
        <refentrytitle>flatpakrepo</refentrytitle>
        <manvolnum>5</manvolnum>
    </refmeta>

    <refnamediv>
        <refname>flatpakrepo</refname>
        <refpurpose>Reference to a remote</refpurpose>
    </refnamediv>

    <refsect1>
        <title>Description</title>

        <para>
            Flatpak uses flatpakrepo files to share information about remotes.
            The <filename>flatpakrepo</filename> file contains enough information
            to add the remote. Use the <command>flatpak remote-add --from</command>
            command to do so.
        </para>

        <para>
            flatpakrepo files may also contain additional information that is useful
            when displaying a remote to the user, e.g. in an app store.
        </para>

        <para>
           The filename extension commonly used for flatpakrepo files is <filename>.flatpakrepo</filename>.
        </para>

        <para>
          flatpakrepo files can also be placed in
          <filename>/usr/share/flatpak/remotes.d/</filename> and
          <filename>/etc/flatpak/remotes.d/</filename>
          to statically preconfigure system-wide remotes. Such files must use the
          <filename>.flatpakrepo</filename> extension. If a file with the
          same name exists in both, the file under <filename>/etc</filename> will
          take precedence.
        </para>

    </refsect1>

    <refsect1>
        <title>File format</title>

        <para>
            The flatpakrepo file is using the same .ini file format that is used for
            systemd unit files or application .desktop files.
        </para>

        <refsect2>
            <title>[Flatpak Repo]</title>

            <para>
                All the information is contained in the [Flatpak Repo] group.
            </para>
            <para>
                The following keys can be present in this group:
            </para>
            <variablelist>
                <varlistentry>
                    <term><option>Version</option> (uint64)</term>
                    <listitem><para>The version of the file format, must be 1 if present.</para></listitem>
                </varlistentry>
                <varlistentry>
                    <term><option>Url</option> (string)</term>
                    <listitem><para>The url for the remote. This key is mandatory.</para></listitem>
                </varlistentry>
                <varlistentry>
                    <term><option>GPGKey</option> (string)</term>
                    <listitem><para>The base64-encoded gpg key for the remote.</para></listitem>
                </varlistentry>
                <varlistentry>
                    <term><option>DefaultBranch</option> (string)</term>
                    <listitem><para>The default branch to use for this remote.</para></listitem>
                </varlistentry>
                <varlistentry>
                    <term><option>Subset</option> (string)</term>
                    <listitem><para>Limit the remote to the named subset of refs.</para></listitem>
                </varlistentry>
                <varlistentry>
                    <term><option>Title</option> (string)</term>
                    <listitem><para>The title of the remote. This should be a user-friendly name that can be displayed e.g. in an app store.</para></listitem>
                </varlistentry>
                <varlistentry>
                    <term><option>Comment</option> (string)</term>
                    <listitem><para>A short summary of the remote, for display e.g. in an app store.</para></listitem>
                </varlistentry>
                <varlistentry>
                    <term><option>Description</option> (string)</term>
                    <listitem><para>A longer description of the remote, for display e.g. in an app store.</para></listitem>
                </varlistentry>
                <varlistentry>
                    <term><option>Icon</option> (string)</term>
                    <listitem><para>The url for an icon that can be used to represent the remote.</para></listitem>
                </varlistentry>
                <varlistentry>
                    <term><option>Homepage</option> (string)</term>
                    <listitem><para>The url of a webpage describing the remote.</para></listitem>
                </varlistentry>
                <varlistentry>
                    <term><option>Filter</option> (string)</term>
                    <listitem><para>The path of a local file to use to filter remote refs. See
                       <citerefentry><refentrytitle>flatpak-remote-add</refentrytitle><manvolnum>1</manvolnum></citerefentry>
                       for details on the format of the file.
                    </para>
                    <para>
                      Note: This field is treated a bit special by flatpak remote-add. If you install a remote with --if-not-exists then
                      and the remote is already configured, then the filter field of the remote configuration will be update anyway.
                      And, if the filter field is *not* specified then any existing filters are cleared. The goal here is to allow
                      a pre-configured filtered remote to be replaced with the regular one if you add the normal upstream (unfiltered)
                      flatpakrepo file.
                    </para></listitem>
                </varlistentry>
                <varlistentry>
                    <term><option>DeploySideloadCollectionID</option> (string)</term>
                    <listitem><para>
                        The collection ID of the remote, if it has one. This uniquely
                        identifies the collection of apps in the remote, to allow peer to peer
                        redistribution (see <citerefentry><refentrytitle>flatpak</refentrytitle><manvolnum>1</manvolnum></citerefentry>).
                        It is recommended to use this key over DeployCollectionID or CollectionID because
                        only newer clients (Flatpak 1.12.8 or later) pay attention to it (and older clients don't handle
                        collection IDs properly).
                    </para></listitem>
                </varlistentry>
                <varlistentry>
                    <term><option>DeployCollectionID</option> (string)</term>
                    <listitem><para>This is deprecated but still supported for backwards compatibility. Use DeploySideloadCollectionID instead.</para></listitem>
                </varlistentry>
                <varlistentry>
                    <term><option>CollectionID</option> (string)</term>
                    <listitem><para>This is deprecated but still supported for backwards compatibility. Use DeploySideloadCollectionID instead.</para></listitem>
                </varlistentry>
            </variablelist>
        </refsect2>
    </refsect1>

    <refsect1>
        <title>Example</title>
<programlisting>
[Flatpak Repo]
Title=gedit
Url=http://sdk.gnome.org/repo-apps/
GPGKey=mQENBFUUCGcBCAC/K9WeV4xCaKr3NKRqPXeY5mpaXAJyasLqCtrDx92WUgbu0voWrhohNAKpqizod2dvzc/XTxm3rHyIxmNfdhz1gaGhynU75Qw4aJVcly2eghTIl++gfDtOvrOZo/VuAq30f32dMIgHQdRwEpgCwz7WyjpqZYltPAEcCNL4MTChAfiHJeeiQ5ibystNBW8W6Ymf7sO4m4g5+/aOxI54oCOzD9TwBAe+yXcJJWtc2rAhMCjtyPJzxd0ZVXqIzCe1xRvJ6Rq7YCiMbiM2DQFWXKnmYQbj4TGNMnwNdAajCdrcBWEMSbzq7EzuThIJRd8Ky4BkEe1St6tuqwFaMZz+F9eXABEBAAG0KEdub21lIFNESyAzLjE2IDxnbm9tZS1vcy1saXN0QGdub21lLm9yZz6JATgEEwECACIFAlUUCGcCGwMGCwkIBwMCBhUIAgkKCwQWAgMBAh4BAheAAAoJEArkz6VV0VKBa5cH/0vXa31YgEjNk78gGFXqnQxdD1WYA87OYxDi189l4lA802EFTF4wCBuZyDOqdd5BhS3Ab0cR778DmZXRUP2gwe+1zTJypU2JMnDpkwJ4NK1VP6/tE4SAPrznBtmb76BKaWBqUfZ9Wq1zg3ugvqkZB/Exq+usypIOwQVp1KL58TrjBRda0HvRctzkNhr0qYAtkfLFe0GvksBp4vBm8uGwAx7fw/HbhIjQ9pekTwvB+5GwDPO/tSip/1bQfCS+XJB8Ffa04HYPLGedalnWBrwhYY+G/kn5Zh9L/AC8xeLwTJTHM212rBjPa9CWs9C6a57MSaeGIEHLC1hEyiJJ15w8jmY=
DeployCollectionID=org.gnome.Apps
</programlisting>
    </refsect1>

    <refsect1>
        <title>See also</title>

        <para>
            <citerefentry><refentrytitle>flatpak</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
            <citerefentry><refentrytitle>flatpak-remote-add</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
            <citerefentry><refentrytitle>flatpakref</refentrytitle><manvolnum>5</manvolnum></citerefentry>
        </para>

    </refsect1>

</refentry>

===== ./doc/flatpak-repair.xml =====
<?xml version='1.0'?> <!--*-nxml-*-->
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
    "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">

<refentry id="flatpak-repair">

    <refentryinfo>
        <title>flatpak repair</title>
        <productname>flatpak</productname>

        <authorgroup>
            <author>
                <contrib>Developer</contrib>
                <firstname>Matthew</firstname>
                <surname>Leeds</surname>
                <email>matthew.leeds@endlessm.com</email>
            </author>
        </authorgroup>
    </refentryinfo>

    <refmeta>
        <refentrytitle>flatpak repair</refentrytitle>
        <manvolnum>1</manvolnum>
    </refmeta>

    <refnamediv>
        <refname>flatpak-repair</refname>
        <refpurpose>Repair a flatpak installation</refpurpose>
    </refnamediv>

    <refsynopsisdiv>
            <cmdsynopsis>
                <command>flatpak repair</command>
                <arg choice="opt" rep="repeat">OPTION</arg>
            </cmdsynopsis>
    </refsynopsisdiv>

    <refsect1>
        <title>Description</title>

        <para>
            Repair a flatpak installation by pruning and reinstalling invalid objects. The repair command does all of the following:
        </para>
        <itemizedlist>
            <listitem><para>
                Scan all locally available refs, removing any that don't correspond to a deployed ref.
            </para></listitem>
            <listitem><para>
                Verify each commit they point to, removing any invalid objects and noting any missing objects.
            </para></listitem>
            <listitem><para>
                Remove any refs that had an invalid object, and any non-partial refs that had missing objects.
            </para></listitem>
            <listitem><para>
                Prune all objects not referenced by a ref, which gets rid of any possibly invalid non-scanned objects.
            </para></listitem>
            <listitem><para>
                Enumerate all deployed refs and re-install any that are not in the repo (or are partial for a non-subdir deploy).
            </para></listitem>
        </itemizedlist>
        <para>
          Note that <command>flatpak repair</command> has to be run with root privileges to
          operate on the system installation.
        </para>
        <para>
          An alternative command for repairing OSTree repositories is ostree fsck.
        </para>

    </refsect1>

    <refsect1>
        <title>Options</title>

        <para>The following options are understood:</para>

        <variablelist>
            <varlistentry>
                <term><option>-h</option></term>
                <term><option>--help</option></term>

                <listitem><para>
                    Show help options and exit.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>-u</option></term>
                <term><option>--user</option></term>

                <listitem><para>
                    Repair per-user installation.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--system</option></term>

                <listitem><para>
                    Repair system-wide installation.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--installation=NAME</option></term>

                <listitem><para>
                    Repair the system-wide installation
                    specified by <arg choice="plain">NAME</arg> among those defined in
                    <filename>/etc/flatpak/installations.d/</filename>. Using
                    <arg choice="plain">--installation=default</arg> is equivalent to using
                    <arg choice="plain">--system</arg>.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--dry-run</option></term>

                <listitem><para>
                    Only report inconsistencies, don't make any changes
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--reinstall-all</option></term>

                <listitem><para>
                    Reinstall all refs, regardless of whether they were removed from
                    the repo or not
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>-v</option></term>
                <term><option>--verbose</option></term>

                <listitem><para>
                    Print debug information during command processing.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--ostree-verbose</option></term>

                <listitem><para>
                    Print OSTree debug information during command processing.
                </para></listitem>
            </varlistentry>
        </variablelist>
    </refsect1>

    <refsect1>
        <title>Examples</title>

        <para>
            <command>$ sudo flatpak repair</command>
        </para>

        <para>
            <command>$ flatpak repair --user</command>
        </para>

    </refsect1>

    <refsect1>
        <title>See also</title>

        <para>
            <citerefentry><refentrytitle>flatpak</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
            <citerefentry><refentrytitle>ostree-fsck</refentrytitle><manvolnum>1</manvolnum></citerefentry>
        </para>

    </refsect1>

</refentry>

===== ./doc/flatpak-remote-info.xml =====
<?xml version='1.0'?> <!--*-nxml-*-->
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
    "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">

<refentry id="flatpak-remote-info">

    <refentryinfo>
        <title>flatpak remote-info</title>
        <productname>flatpak</productname>

        <authorgroup>
            <author>
                <contrib>Developer</contrib>
                <firstname>Alexander</firstname>
                <surname>Larsson</surname>
                <email>alexl@redhat.com</email>
            </author>
        </authorgroup>
    </refentryinfo>

    <refmeta>
        <refentrytitle>flatpak remote-info</refentrytitle>
        <manvolnum>1</manvolnum>
    </refmeta>

    <refnamediv>
        <refname>flatpak-remote-info</refname>
        <refpurpose>Show information about an application or runtime in a remote</refpurpose>
    </refnamediv>

    <refsynopsisdiv>
            <cmdsynopsis>
                <command>flatpak remote-info</command>
                <arg choice="opt" rep="repeat">OPTION</arg>
                <arg choice="plain">REMOTE</arg>
                <arg choice="plain">REF</arg>
            </cmdsynopsis>
    </refsynopsisdiv>

    <refsect1>
        <title>Description</title>

        <para>
            Shows information about the runtime or application <arg choice="plain">REF</arg> from the
            remote repository with the name <arg choice="plain">REMOTE</arg>.
            You can find all configured remote repositories with flatpak remotes.
        </para>
        <para>
            By default, the output is formatted in a friendly format.
            If you specify one of the <option>--show-…</option> options,
            the output is instead formatted in a machine-readable format.
        </para>
        <para>
            Unless overridden with the <option>--system</option>, <option>--user</option>, or <option>--installation</option> options,
            this command uses either the default system-wide installation or the
            per-user one, depending on which has the specified
            <arg choice="plain">REMOTE</arg>.
        </para>

    </refsect1>

    <refsect1>
        <title>Options</title>

        <para>The following options are understood:</para>

        <variablelist>
            <varlistentry>
                <term><option>-h</option></term>
                <term><option>--help</option></term>

                <listitem><para>
                    Show help options and exit.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>-u</option></term>
                <term><option>--user</option></term>

                <listitem><para>
                    Use the per-user configuration.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--system</option></term>

                <listitem><para>
                    Use the default system-wide configuration.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--installation=NAME</option></term>

                <listitem><para>
                    Use a system-wide installation specified by <arg choice="plain">NAME</arg>
                    among those defined in <filename>/etc/flatpak/installations.d/</filename>.
                    Using <option>--installation=default</option> is equivalent to using
                    <option>--system</option>.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--cached</option></term>

                <listitem><para>
                  Prefer to use locally cached information if possible, even though it
                  may be out of date. This is faster, but risks returning stale information.
                  Also, some information is not cached so will not be available.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--runtime</option></term>

                <listitem><para>
                    Assume that <arg choice="plain">REF</arg> is a runtime if not explicitly specified.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--app</option></term>

                <listitem><para>
                    Assume that <arg choice="plain">REF</arg> is an app if not explicitly specified.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--arch=ARCH</option></term>

                <listitem><para>
                    The default architecture to look for, if not given explicitly in
                    the <arg choice="plain">REF</arg>. See <command>flatpak --supported-arches</command>
                    for architectures supported by the host.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--commit=COMMIT</option></term>

                <listitem><para>
                    Show information about the specific commit, rather than the latest version.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--log</option></term>

                <listitem><para>
                    Display a log of previous versions.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>-r</option></term>
                <term><option>--show-ref</option></term>

                <listitem><para>
                    Show the matched ref.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>-c</option></term>
                <term><option>--show-commit</option></term>

                <listitem><para>
                    Show the commit id.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>-p</option></term>
                <term><option>--show-parent</option></term>

                <listitem><para>
                    Show the parent commit id.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>-m</option></term>
                <term><option>--show-metadata</option></term>

                <listitem><para>
                    Show the metadata.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>-v</option></term>
                <term><option>--verbose</option></term>

                <listitem><para>
                    Print debug information during command processing.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--ostree-verbose</option></term>

                <listitem><para>
                    Print OSTree debug information during command processing.
                </para></listitem>
            </varlistentry>

        </variablelist>
    </refsect1>

    <refsect1>
        <title>Examples</title>

        <para>
            <command>$ flatpak --user remote-info flathub org.gnome.gedit</command>
        </para>
<programlisting>
Ref: app/org.gnome.gedit/x86_64/stable
ID: org.gnome.gedit
Arch: x86_64
Branch: stable
Date: 2017-07-31 16:05:22 +0000
Subject: Build org.gnome.gedit at 3ec291fc1ce4d78220527fa79576f4cc1481ebe5
Commit: 3de7e9dde3bb8382aad9dfbbff20eccd9bf2100bc1887a3619ec0372e8066bf7
Parent: -
Download size: 3,4 MB
Installed size: 11,1 MB
Runtime: org.gnome.Platform/x86_64/3.24
</programlisting>

    </refsect1>

    <refsect1>
        <title>See also</title>

            <para>
                <citerefentry><refentrytitle>flatpak</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
                <citerefentry><refentrytitle>flatpak-remotes</refentrytitle><manvolnum>1</manvolnum></citerefentry>
                <citerefentry><refentrytitle>flatpak-remote-ls</refentrytitle><manvolnum>1</manvolnum></citerefentry>
            </para>
    </refsect1>

</refentry>

===== ./doc/flatpak-enter.xml =====
<?xml version='1.0'?> <!--*-nxml-*-->
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
    "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">

<refentry id="flatpak-enter">

    <refentryinfo>
        <title>flatpak enter</title>
        <productname>flatpak</productname>

        <authorgroup>
            <author>
                <contrib>Developer</contrib>
                <firstname>Alexander</firstname>
                <surname>Larsson</surname>
                <email>alexl@redhat.com</email>
            </author>
        </authorgroup>
    </refentryinfo>

    <refmeta>
        <refentrytitle>flatpak enter</refentrytitle>
        <manvolnum>1</manvolnum>
    </refmeta>

    <refnamediv>
        <refname>flatpak-enter</refname>
        <refpurpose>Enter an application or runtime's sandbox</refpurpose>
    </refnamediv>

    <refsynopsisdiv>
            <cmdsynopsis>
                <command>flatpak enter</command>
                <arg choice="opt" rep="repeat">OPTION</arg>
                <arg choice="plain">INSTANCE</arg>
                <arg choice="plain">COMMAND</arg>
                <arg choice="opt" rep="repeat">ARG</arg>
            </cmdsynopsis>
    </refsynopsisdiv>

    <refsect1>
        <title>Description</title>

        <para>
            Enter a running sandbox.
        </para>
        <para>
            <arg choice="plain">INSTANCE</arg> must be either the pid of a process running
            in a flatpak sandbox, or the ID of a running application, or the instance ID
            of a running sandbox. You can use <command>flatpak ps</command> to find the
            instance IDs of running flatpaks.
        </para>
        <para>
            <arg choice="plain">COMMAND</arg> is the command to run in the sandbox.
            Extra arguments are passed on to the command.
        </para>
        <para>
            This creates a new process within the running sandbox, with the same environment.
            This is useful when you want to debug a problem with a running application.
        </para>
        <para>
          This command works as a regular user if the system support unprivileged user namespace. If
          that is not available you need to run run it like: <command>sudo -E flatpak enter</command>.
        </para>

    </refsect1>

    <refsect1>
        <title>Options</title>

        <para>The following options are understood:</para>

        <variablelist>
            <varlistentry>
                <term><option>-h</option></term>
                <term><option>--help</option></term>

                <listitem><para>
                    Show help options and exit.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>-v</option></term>
                <term><option>--verbose</option></term>

                <listitem><para>
                    Print debug information during command processing.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--ostree-verbose</option></term>

                <listitem><para>
                    Print OSTree debug information during command processing.
                </para></listitem>
            </varlistentry>
        </variablelist>
    </refsect1>

    <refsect1>
        <title>Examples</title>

        <para>
            <command>$ flatpak enter 15345 sh</command>
        </para>

    </refsect1>

    <refsect1>
        <title>See also</title>

        <para>
            <citerefentry><refentrytitle>flatpak</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
            <citerefentry><refentrytitle>flatpak-run</refentrytitle><manvolnum>1</manvolnum></citerefentry>
            <citerefentry><refentrytitle>flatpak-ps</refentrytitle><manvolnum>1</manvolnum></citerefentry>
        </para>

    </refsect1>

</refentry>

===== ./doc/reference/libflatpak-docs.xml =====
<?xml version="1.0"?>
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
               "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd"
[
  <!ENTITY % local.common.attrib "xmlns:xi  CDATA  #FIXED 'http://www.w3.org/2003/XInclude'">
  <!ENTITY version SYSTEM "version.xml">
]>
<book id="index">
  <bookinfo>
    <title>Flatpak Library Reference Manual</title>
    <releaseinfo>
      For flatpak &version;
    </releaseinfo>
  </bookinfo>

  <chapter>
    <title>Flatpak</title>
    <xi:include href="xml/flatpak-installation.xml"/>
    <xi:include href="xml/flatpak-remote.xml"/>
    <xi:include href="xml/flatpak-transaction-operation.xml"/>
    <xi:include href="xml/flatpak-transaction-progress.xml"/>
    <xi:include href="xml/flatpak-transaction.xml"/>
    <xi:include href="xml/flatpak-ref.xml"/>
    <xi:include href="xml/flatpak-installed-ref.xml"/>
    <xi:include href="xml/flatpak-related-ref.xml"/>
    <xi:include href="xml/flatpak-remote-ref.xml"/>
    <xi:include href="xml/flatpak-bundle-ref.xml"/>
    <xi:include href="xml/flatpak-instance.xml"/>
    <xi:include href="xml/flatpak-error.xml"/>
    <xi:include href="xml/flatpak-version-macros.xml"/>
  </chapter>

  <chapter>
    <title>D-Bus APIs</title>
    <xi:include href="dbus-org.freedesktop.Flatpak.Authenticator.xml"/>
    <xi:include href="dbus-org.freedesktop.Flatpak.AuthenticatorRequest.xml"/>
    <xi:include href="dbus-org.freedesktop.Flatpak.Development.xml"/>
    <xi:include href="dbus-org.freedesktop.Flatpak.SessionHelper.xml"/>
    <xi:include href="dbus-org.freedesktop.Flatpak.SystemHelper.xml"/>
    <xi:include href="dbus-org.freedesktop.impl.portal.PermissionStore.xml"/>
    <xi:include href="dbus-org.freedesktop.portal.Documents.xml"/>
    <xi:include href="dbus-org.freedesktop.portal.Flatpak.xml"/>
    <xi:include href="dbus-org.freedesktop.portal.Flatpak.UpdateMonitor.xml"/>
  </chapter>

  <chapter id="object-tree">
    <title>Object Hierarchy</title>
    <xi:include href="xml/tree_index.sgml"/>
  </chapter>

  <index id="full-api-index">
    <title>API Index</title>
    <xi:include href="xml/api-index-full.xml"><xi:fallback /></xi:include>
  </index>

  <index id="deprecated-api-index" role="deprecated">
    <title>Index of deprecated API</title>
    <xi:include href="xml/api-index-deprecated.xml"><xi:fallback /></xi:include>
  </index>

  <xi:include href="xml/annotation-glossary.xml"><xi:fallback /></xi:include>
</book>

===== ./doc/reference/version.xml.in =====
@FLATPAK_MAJOR_VERSION@.@FLATPAK_MINOR_VERSION@.@FLATPAK_MICRO_VERSION@

===== ./doc/reference/meson.build =====
# Copyright 2022 Collabora Ltd.
# SPDX-License-Identifier: LGPL-2.1-or-later

cdata = configuration_data()
cdata.set('FLATPAK_MAJOR_VERSION', flatpak_major_version)
cdata.set('FLATPAK_MINOR_VERSION', flatpak_minor_version)
cdata.set('FLATPAK_MICRO_VERSION', flatpak_micro_version)
configure_file(
  configuration : cdata,
  input : 'version.xml.in',
  output : 'version.xml',
)

# We're really only doing this to generate the Docbook XML.
doc_gdbus = gnome.gdbus_codegen(
  'doc-dbus-generated',
  sources : [
    project_source_root / 'data/org.freedesktop.Flatpak.Authenticator.xml',
    project_source_root / 'data/org.freedesktop.Flatpak.xml',
    project_source_root / 'data/org.freedesktop.impl.portal.PermissionStore.xml',
    project_source_root / 'data/org.freedesktop.portal.Documents.xml',
    project_source_root / 'data/org.freedesktop.portal.Flatpak.xml',
  ],
  namespace : 'doc',
  docbook : 'dbus',
)

libflatpak_doc = gnome.gtkdoc(
  'flatpak',
  main_xml : 'libflatpak-docs.xml',
  namespace : 'flatpak',
  src_dir : [
    project_build_root / 'common',
    project_source_root / 'common',
  ],
  content_files : doc_gdbus[2],
  dependencies : base_deps + [libflatpak_dep],
  ignore_headers : [
    'valgrind-private.h',
    'flatpak-bwrap-private.h',
    'flatpak-chain-input-stream-private.h',
    'flatpak-common-types-private.h',
    'flatpak-context-private.h',
    'flatpak-dbus-generated.h',
    'flatpak-dir-private.h',
    'flatpak-document-dbus-generated.h',
    'flatpak-enum-types.h',
    'flatpak-exports-private.h',
    'flatpak-image-collection-private.h',
    'flatpak-image-source-private.h',
    'flatpak-installed-ref-private.h',
    'flatpak-json-oci-private.h',
    'flatpak-json-private.h',
    'flatpak-oci-registry-private.h',
    'flatpak-progress-private.h',
    'flatpak-remote-private.h',
    'flatpak-remote-ref-private.h',
    'flatpak-run-private.h',
    'flatpak-systemd-dbus-generated.h',
    'flatpak-installation-private.h',
    'flatpak-transaction-private.h',
    'flatpak-utils-private.h',
    'flatpak-utils-base-private.h',
    'flatpak-utils-http-private.h',
    'flatpak-instance-private.h',
    'flatpak-auth-private.h',
    'flatpak-parental-controls-private.h',
    'flatpak-appdata-private.h',
    'flatpak-zstd-compressor-private.h',
    'flatpak-zstd-decompressor-private.h',
  ],
  install : true,
  scan_args : [
    '--ignore-decorators=FLATPAK_EXTERN',
    '--rebuild-types',
  ],
)

if xmlto.found()
  custom_target(
    'libflatpak-docs.html',
    input : [
      '../xmlto-config.xsl',
    ],
    output : ['libflatpak-docs.html'],
    depends : libflatpak_doc,
    command : [
      xmlto,
      '-o', meson.current_build_dir(),
    ] + get_option('xmlto_flags') + [
      '--skip-validation',
      'xhtml-nochunks',
      '-m', '@INPUT0@',
      fs.parent(libflatpak_doc.full_path()) / 'libflatpak-docs.xml',
    ],
    build_by_default : true,
    install : true,
    install_dir : docdir,
  )
endif
===== ./doc/reference/flatpak-sections.txt =====
<SECTION>
<FILE>flatpak-installation</FILE>
<TITLE>FlatpakInstallation</TITLE>
FlatpakInstallation
FlatpakQueryFlags
flatpak_installation_new_system
flatpak_installation_new_system_with_id
flatpak_installation_new_user
flatpak_installation_new_for_path
flatpak_installation_get_is_user
flatpak_installation_get_path
flatpak_installation_create_monitor
flatpak_installation_get_timestamp
flatpak_installation_install
flatpak_installation_install_full
flatpak_installation_update
flatpak_installation_update_full
flatpak_installation_uninstall
flatpak_installation_uninstall_full
flatpak_installation_launch
flatpak_installation_launch_full
flatpak_installation_get_current_installed_app
flatpak_installation_get_display_name
flatpak_installation_get_id
flatpak_installation_get_installed_ref
flatpak_installation_get_min_free_space_bytes
flatpak_installation_get_priority
flatpak_installation_get_storage_type
flatpak_installation_set_no_interaction
flatpak_installation_get_no_interaction
flatpak_installation_list_installed_refs
flatpak_installation_list_installed_refs_by_kind
flatpak_installation_list_installed_refs_for_update
flatpak_installation_list_installed_related_refs_sync
flatpak_installation_list_unused_refs
flatpak_installation_list_remote_refs_sync
flatpak_installation_list_remote_refs_sync_full
flatpak_installation_list_remotes_by_type
flatpak_installation_list_remote_related_refs_sync
flatpak_installation_list_remotes
flatpak_installation_get_remote_by_name
flatpak_installation_fetch_remote_metadata_sync
flatpak_installation_fetch_remote_ref_sync
flatpak_installation_fetch_remote_ref_sync_full
flatpak_installation_fetch_remote_size_sync
flatpak_installation_load_app_overrides
flatpak_installation_update_appstream_sync
flatpak_installation_install_bundle
flatpak_installation_install_ref_file
flatpak_installation_drop_caches
flatpak_installation_add_remote
flatpak_installation_modify_remote
flatpak_installation_remove_remote
flatpak_installation_update_remote_sync
flatpak_installation_cleanup_local_refs_sync
flatpak_installation_get_config
flatpak_installation_get_default_languages
flatpak_installation_get_default_locales
flatpak_installation_prune_local_repo
flatpak_installation_remove_local_ref_sync
flatpak_installation_set_config_sync
flatpak_installation_update_appstream_full_sync
flatpak_installation_run_triggers
flatpak_get_default_arch
flatpak_get_supported_arches
flatpak_get_system_installations
FlatpakProgressCallback
FlatpakUpdateFlags
FlatpakInstallFlags
FlatpakUninstallFlags
FlatpakLaunchFlags
FlatpakStorageType
<SUBSECTION Standard>
FLATPAK_INSTALLATION
FLATPAK_IS_INSTALLATION
FLATPAK_TYPE_INSTALLATION
FlatpakInstallationClass
flatpak_installation_get_type
</SECTION>

<SECTION>
<FILE>flatpak-installed-ref</FILE>
<TITLE>FlatpakInstalledRef</TITLE>
FlatpakInstalledRef
flatpak_installed_ref_get_deploy_dir
flatpak_installed_ref_get_installed_size
flatpak_installed_ref_get_is_current
flatpak_installed_ref_get_latest_commit
flatpak_installed_ref_get_origin
flatpak_installed_ref_load_appdata
flatpak_installed_ref_load_metadata
flatpak_installed_ref_get_appdata_license
flatpak_installed_ref_get_appdata_name
flatpak_installed_ref_get_appdata_summary
flatpak_installed_ref_get_appdata_version
flatpak_installed_ref_get_appdata_content_rating
flatpak_installed_ref_get_appdata_content_rating_type
flatpak_installed_ref_get_subpaths
flatpak_installed_ref_get_eol
flatpak_installed_ref_get_eol_rebase
<SUBSECTION Standard>
FlatpakInstalledRefClass
FLATPAK_INSTALLED_REF
FLATPAK_IS_INSTALLED_REF
FLATPAK_TYPE_INSTALLED_REF
flatpak_installed_ref_get_type
</SECTION>

<SECTION>
<FILE>flatpak-remote-ref</FILE>
<TITLE>FlatpakRemoteRef</TITLE>
FlatpakRemoteRef
flatpak_remote_ref_get_remote_name
flatpak_remote_ref_get_download_size
flatpak_remote_ref_get_eol
flatpak_remote_ref_get_eol_rebase
flatpak_remote_ref_get_installed_size
flatpak_remote_ref_get_metadata
<SUBSECTION Standard>
FLATPAK_IS_REMOTE_REF
FLATPAK_REMOTE_REF
FLATPAK_TYPE_REMOTE_REF
FlatpakRemoteRefClass
flatpak_remote_ref_get_type
</SECTION>

<SECTION>
<FILE>flatpak-related-ref</FILE>
<TITLE>FlatpakRelatedRef</TITLE>
FlatpakRelatedRef
flatpak_related_ref_new
flatpak_related_ref_get_subpaths
flatpak_related_ref_should_download
flatpak_related_ref_should_delete
flatpak_related_ref_should_autoprune
<SUBSECTION Standard>
FLATPAK_IS_RELATED_REF
FLATPAK_RELATED_REF
FLATPAK_TYPE_RELATED_REF
FlatpakRelatedRefClass
flatpak_related_ref_get_type
</SECTION>

<SECTION>
<FILE>flatpak-ref</FILE>
<TITLE>FlatpakRef</TITLE>
FlatpakRef
FlatpakRefKind
flatpak_ref_format_ref
flatpak_ref_get_arch
flatpak_ref_get_branch
flatpak_ref_get_collection_id
flatpak_ref_get_commit
flatpak_ref_get_kind
flatpak_ref_get_name
flatpak_ref_parse
<SUBSECTION Standard>
FlatpakRefClass
FLATPAK_IS_REF
FLATPAK_REF
FLATPAK_TYPE_REF
flatpak_ref_get_type
</SECTION>

<SECTION>
<FILE>flatpak-remote</FILE>
<TITLE>FlatpakRemote</TITLE>
FlatpakRemote
flatpak_remote_new
flatpak_remote_new_from_file
flatpak_remote_get_name
flatpak_remote_get_appstream_dir
flatpak_remote_get_appstream_timestamp
flatpak_remote_get_collection_id
flatpak_remote_set_collection_id
flatpak_remote_get_default_branch
flatpak_remote_set_default_branch
flatpak_remote_get_gpg_verify
flatpak_remote_set_gpg_verify
flatpak_remote_set_gpg_key
flatpak_remote_get_nodeps
flatpak_remote_set_nodeps
flatpak_remote_get_noenumerate
flatpak_remote_set_noenumerate
flatpak_remote_get_prio
flatpak_remote_set_prio
flatpak_remote_get_remote_type
flatpak_remote_get_title
flatpak_remote_set_title
flatpak_remote_get_comment
flatpak_remote_set_comment
flatpak_remote_get_description
flatpak_remote_set_description
flatpak_remote_get_homepage
flatpak_remote_set_homepage
flatpak_remote_get_icon
flatpak_remote_set_icon
flatpak_remote_get_url
flatpak_remote_set_url
flatpak_remote_get_disabled
flatpak_remote_set_disabled
flatpak_remote_get_filter
flatpak_remote_set_filter
flatpak_remote_get_main_ref
flatpak_remote_set_main_ref
FlatpakRemoteType
<SUBSECTION Standard>
FlatpakRemoteClass
FLATPAK_IS_REMOTE
FLATPAK_REMOTE
FLATPAK_TYPE_REMOTE
flatpak_remote_get_type
</SECTION>

<SECTION>
<FILE>flatpak-transaction-progress</FILE>
<TITLE>FlatpakTransactionProgress</TITLE>
FlatpakTransactionProgress
flatpak_transaction_progress_get_is_estimating
flatpak_transaction_progress_get_progress
flatpak_transaction_progress_get_status
flatpak_transaction_progress_set_update_frequency
flatpak_transaction_progress_get_bytes_transferred
flatpak_transaction_progress_get_start_time

<SUBSECTION Standard>
FlatpakTransactionProgressClass
FLATPAK_IS_TRANSACTION_PROGRESS
FLATPAK_TRANSACTION_PROGRESS
FLATPAK_TYPE_TRANSACTION_PROGRESS
flatpak_transaction_progress_get_type
</SECTION>

<SECTION>
<FILE>flatpak-transaction-operation</FILE>
<TITLE>FlatpakTransactionOperation</TITLE>
FlatpakTransactionOperation
flatpak_transaction_operation_get_bundle_path
flatpak_transaction_operation_get_commit
flatpak_transaction_operation_get_operation_type
flatpak_transaction_operation_get_ref
flatpak_transaction_operation_get_remote
flatpak_transaction_operation_get_metadata
flatpak_transaction_operation_get_old_metadata
flatpak_transaction_operation_get_download_size
flatpak_transaction_operation_get_installed_size
flatpak_transaction_operation_type_to_string
<SUBSECTION Standard>
FlatpakTransactionOperationClass
FLATPAK_IS_TRANSACTION_OPERATION
FLATPAK_TRANSACTION_OPERATION
FLATPAK_TYPE_TRANSACTION_OPERATION
flatpak_transaction_operation_get_type
</SECTION>

<SECTION>
<FILE>flatpak-transaction</FILE>
<TITLE>FlatpakTransaction</TITLE>
FlatpakTransaction
FlatpakTransactionOperationType
FlatpakTransactionErrorDetails
FlatpakTransactionRemoteReason
FlatpakTransactionResult
flatpak_transaction_new_for_installation
flatpak_transaction_add_install
flatpak_transaction_add_install_bundle
flatpak_transaction_add_install_flatpakref
flatpak_transaction_add_rebase
flatpak_transaction_add_rebase_and_uninstall
flatpak_transaction_add_update
flatpak_transaction_add_uninstall
flatpak_transaction_add_default_dependency_sources
flatpak_transaction_add_dependency_source
flatpak_transaction_run
<SUBSECTION>
flatpak_transaction_get_current_operation
flatpak_transaction_get_installation
flatpak_transaction_get_operations
flatpak_transaction_is_empty
<SUBSECTION>
flatpak_transaction_set_disable_dependencies
flatpak_transaction_set_disable_prune
flatpak_transaction_set_disable_related
flatpak_transaction_set_disable_static_deltas
flatpak_transaction_set_no_deploy
flatpak_transaction_get_no_deploy
flatpak_transaction_set_no_pull
flatpak_transaction_get_no_pull
flatpak_transaction_set_reinstall
flatpak_transaction_set_force_uninstall
flatpak_transaction_set_default_arch
<subsection>
flatpak_transaction_set_parent_window
flatpak_transaction_get_parent_window
flatpak_transaction_abort_webflow

<SUBSECTION Standard>
FlatpakTransactionClass
FLATPAK_IS_TRANSACTION
FLATPAK_TRANSACTION
FLATPAK_TYPE_TRANSACTION
flatpak_transaction_get_type
</SECTION>

<SECTION>
<FILE>flatpak-version-macros</FILE>
FLATPAK_CHECK_VERSION
FLATPAK_MAJOR_VERSION
FLATPAK_MINOR_VERSION
FLATPAK_MICRO_VERSION
<SUBSECTION Standard>
FLATPAK_EXTERN
</SECTION>

<SECTION>
<FILE>flatpak-error</FILE>
FLATPAK_ERROR
FlatpakError
FLATPAK_PORTAL_ERROR
FlatpakPortalError
<SUBSECTION Standard>
flatpak_error_quark
flatpak_portal_error_quark
</SECTION>

<SECTION>
<FILE>flatpak-bundle-ref</FILE>
<TITLE>FlatpakBundleRef</TITLE>
FlatpakBundleRef
flatpak_bundle_ref_new
flatpak_bundle_ref_get_file
flatpak_bundle_ref_get_metadata
flatpak_bundle_ref_get_appstream
flatpak_bundle_ref_get_icon
flatpak_bundle_ref_get_origin
flatpak_bundle_ref_get_installed_size
flatpak_bundle_ref_get_runtime_repo_url
<SUBSECTION Standard>
FlatpakBundleRefClass
FLATPAK_TYPE_BUNDLE_REF
FLATPAK_BUNDLE_REF
FLATPAK_IS_BUNDLE_REF
flatpak_bundle_ref_get_type
</SECTION>

<SECTION>
<FILE>flatpak-instance</FILE>
<TITLE>FlatpakInstance</TITLE>
FlatpakInstance
flatpak_instance_get_all
flatpak_instance_get_id
flatpak_instance_get_app
flatpak_instance_get_arch
flatpak_instance_get_branch
flatpak_instance_get_commit
flatpak_instance_get_runtime
flatpak_instance_get_runtime_commit
flatpak_instance_get_pid
flatpak_instance_get_child_pid
flatpak_instance_get_info
flatpak_instance_is_running
<SUBSECTION Standard>
FlatpakInstanceClass
FLATPAK_TYPE_INSTANCE
FLATPAK_INSTANCE
FLATPAK_IS_INSTANCE
flatpak_instance_get_type
</SECTION>

===== ./doc/reference/.gitignore =====
html/
xml/
*.stamp
*.bak
/dbus-*.xml
/flatpak.actions
flatpak-decl-list.txt
flatpak-decl.txt
flatpak-overrides.txt
flatpak-scan.c
flatpak-undeclared.txt
flatpak-undocumented.txt
flatpak-unused.txt
flatpak.args
flatpak.hierarchy
flatpak.interfaces
flatpak.prerequisites
flatpak.signals
flatpak.types

===== ./doc/docbook.css =====
body
{
  font-family: sans-serif;
}
h1.title
{
}
.permission
{
  color: #ee0000;
  text-decoration: underline;
}
.synopsis, .classsynopsis
{
  background: #eeeeee;
  border: solid 1px #aaaaaa;
  padding: 0.5em;
}
.programlisting
{
  background: #eeeeff;
  border: solid 1px #aaaaff;
  padding: 0.5em;
}
.variablelist
{
  padding: 4px;
  margin-left: 3em;
}
.variablelist td:first-child
{
  vertical-align: top;
}
td.shortcuts
{
  color: #770000;
  font-size: 80%;
}
div.refnamediv
{
  margin-top: 2em;
}
div.toc
{
  border: 2em;
}
a
{
  text-decoration: none;
}
a:hover
{
  text-decoration: underline;
  color: #FF0000;
}

div.table table
{
  border-collapse: collapse;
  border-spacing: 0px;
  border-style: solid;
  border-color: #777777;
  border-width: 1px;
}

div.table table td, div.table table th
{
  border-style: solid;
  border-color: #777777;
  border-width: 1px;
  padding: 3px;
  vertical-align: top;
}

div.table table th
{
  background-color: #eeeeee;
}

===== ./doc/flatpakref.xml =====
<?xml version='1.0'?> <!--*-nxml-*-->
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
    "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">

<refentry id="flatpakref">

    <refentryinfo>
        <title>flatpakref</title>
        <productname>flatpak</productname>

        <authorgroup>
            <author>
                <contrib>Developer</contrib>
                <firstname>Alexander</firstname>
                <surname>Larsson</surname>
                <email>alexl@redhat.com</email>
            </author>
        </authorgroup>
    </refentryinfo>

    <refmeta>
        <refentrytitle>flatpakref</refentrytitle>
        <manvolnum>5</manvolnum>
    </refmeta>

    <refnamediv>
        <refname>flatpakref</refname>
        <refpurpose>Reference to a remote for an application or runtime</refpurpose>
    </refnamediv>

    <refsect1>
        <title>Description</title>

        <para>
            Flatpak uses flatpakref files to share information about a remote for
            a single application. The <filename>flatpakref</filename> file contains
            enough information to add the remote and install the application.
            Use the <command>flatpak install --from</command> command to do so.
        </para>

        <para>
            flatpakref files may also contain additional information that is useful
            when displaying the application to the user, e.g. in an app store.
        </para>

        <para>
           The filename extension commonly used for flatpakref files is <filename>.flatpakref</filename>.
        </para>

        <para>
           A flatpakref file can also refer to a remote for a runtime.
        </para>

    </refsect1>

    <refsect1>
        <title>File format</title>

        <para>
            The flatpakref file is using the same .ini file format that is used for
            systemd unit files or application .desktop files.
        </para>

        <refsect2>
            <title>[Flatpak Ref]</title>

            <para>
                All the information is contained in the [Flatpak Ref] group.
            </para>
            <para>
                The following keys can be present in this group:
            </para>
            <variablelist>
                <varlistentry>
                    <term><option>Version</option> (uint64)</term>
                    <listitem><para>The version of the file format, must be 1 if present.</para></listitem>
                </varlistentry>
                <varlistentry>
                    <term><option>Name</option> (string)</term>
                    <listitem><para>The fully qualified name of the runtime or application. This key is mandatory.</para></listitem>
                </varlistentry>
                <varlistentry>
                    <term><option>Url</option> (string)</term>
                    <listitem><para>The url for the remote. This key is mandatory.</para></listitem>
                </varlistentry>
                <varlistentry>
                    <term><option>Branch</option> (string)</term>
                    <listitem><para>The name of the branch from which to install the application or runtime. If this key is not specified, the "master" branch is used.</para></listitem>
                </varlistentry>
                <varlistentry>
                    <term><option>Title</option> (string)</term>
                    <listitem><para>The title of the application or runtime. This should be a user-friendly name that can be displayed e.g. in an app store.</para></listitem>
                </varlistentry>
                <varlistentry>
                    <term><option>Comment</option> (string)</term>
                    <listitem><para>A short summary of the application or runtime, for display e.g. in an app store.</para></listitem>
                </varlistentry>
                <varlistentry>
                    <term><option>Description</option> (string)</term>
                    <listitem><para>A longer description of the application or runtime, for display e.g. in an app store.</para></listitem>
                </varlistentry>
                <varlistentry>
                    <term><option>Icon</option> (string)</term>
                    <listitem><para>The url for an icon that can be used to represent the application or runtime.</para></listitem>
                </varlistentry>
                <varlistentry>
                    <term><option>Homepage</option> (string)</term>
                    <listitem><para>The url of a webpage describing the application or runtime.</para></listitem>
                </varlistentry>
                <varlistentry>
                    <term><option>DeploySideloadCollectionID</option> (string)</term>
                    <listitem><para>
                        The collection ID of the remote, if it has one. This uniquely
                        identifies the collection of apps in the remote, to allow peer to peer
                        redistribution (see <citerefentry><refentrytitle>flatpak</refentrytitle><manvolnum>1</manvolnum></citerefentry>).
                        It is recommended to use this key over DeployCollectionID or CollectionID because
                        only newer clients (Flatpak 1.12.8 or later) pay attention to it (and older clients don't handle
                        collection IDs properly).
                    </para></listitem>
                </varlistentry>
                <varlistentry>
                    <term><option>DeployCollectionID</option> (string)</term>
                    <listitem><para>This is deprecated but still supported for backwards compatibility. Use DeploySideloadCollectionID instead.</para></listitem>
                </varlistentry>
                <varlistentry>
                    <term><option>CollectionID</option> (string)</term>
                    <listitem><para>This is deprecated but still supported for backwards compatibility. Use DeploySideloadCollectionID instead.</para></listitem>
                </varlistentry>

                <varlistentry>
                    <term><option>IsRuntime</option> (boolean)</term>
                    <listitem><para>Whether this file refers to a runtime. If this key is not specified, the file is assumed to refer to an application.</para></listitem>
                </varlistentry>
                <varlistentry>
                    <term><option>GPGKey</option> (string)</term>
                    <listitem><para>The base64-encoded gpg key for the remote.</para></listitem>
                </varlistentry>
                <varlistentry>
                    <term><option>SignatureLookaside</option> (string)</term>
                    <listitem><para>URL to use to look up signatures (OCI remotes only)</para></listitem>
                </varlistentry>
                <varlistentry>
                    <term><option>RuntimeRepo</option> (string)</term>
                    <listitem><para>The url for a .flatpakrepo file for the remote where the runtime can be found.
                    Note that if the runtime is available in the remote providing the app, that remote may be
                    used instead but the one specified by this option will still be added.</para></listitem>
                </varlistentry>
                <varlistentry>
                    <term><option>SuggestRemoteName</option> (string)</term>
                    <listitem><para>A suggested name for the remote.</para></listitem>
                </varlistentry>
            </variablelist>
        </refsect2>
    </refsect1>

    <refsect1>
        <title>Example</title>
<programlisting>
[Flatpak Ref]
Title=gedit
Name=org.gnome.gedit
Branch=stable
Url=http://sdk.gnome.org/repo-apps/
IsRuntime=false
GPGKey=mQENBFUUCGcBCAC/K9WeV4xCaKr3NKRqPXeY5mpaXAJyasLqCtrDx92WUgbu0voWrhohNAKpqizod2dvzc/XTxm3rHyIxmNfdhz1gaGhynU75Qw4aJVcly2eghTIl++gfDtOvrOZo/VuAq30f32dMIgHQdRwEpgCwz7WyjpqZYltPAEcCNL4MTChAfiHJeeiQ5ibystNBW8W6Ymf7sO4m4g5+/aOxI54oCOzD9TwBAe+yXcJJWtc2rAhMCjtyPJzxd0ZVXqIzCe1xRvJ6Rq7YCiMbiM2DQFWXKnmYQbj4TGNMnwNdAajCdrcBWEMSbzq7EzuThIJRd8Ky4BkEe1St6tuqwFaMZz+F9eXABEBAAG0KEdub21lIFNESyAzLjE2IDxnbm9tZS1vcy1saXN0QGdub21lLm9yZz6JATgEEwECACIFAlUUCGcCGwMGCwkIBwMCBhUIAgkKCwQWAgMBAh4BAheAAAoJEArkz6VV0VKBa5cH/0vXa31YgEjNk78gGFXqnQxdD1WYA87OYxDi189l4lA802EFTF4wCBuZyDOqdd5BhS3Ab0cR778DmZXRUP2gwe+1zTJypU2JMnDpkwJ4NK1VP6/tE4SAPrznBtmb76BKaWBqUfZ9Wq1zg3ugvqkZB/Exq+usypIOwQVp1KL58TrjBRda0HvRctzkNhr0qYAtkfLFe0GvksBp4vBm8uGwAx7fw/HbhIjQ9pekTwvB+5GwDPO/tSip/1bQfCS+XJB8Ffa04HYPLGedalnWBrwhYY+G/kn5Zh9L/AC8xeLwTJTHM212rBjPa9CWs9C6a57MSaeGIEHLC1hEyiJJ15w8jmY=
DeployCollectionID=org.gnome.Apps
</programlisting>
    </refsect1>

    <refsect1>
        <title>See also</title>

        <para>
            <citerefentry><refentrytitle>flatpak</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
            <citerefentry><refentrytitle>flatpak-install</refentrytitle><manvolnum>1</manvolnum></citerefentry>
            <citerefentry><refentrytitle>flatpakrepo</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
        </para>

    </refsect1>

</refentry>

===== ./doc/flatpak-build-import-bundle.xml =====
<?xml version='1.0'?> <!--*-nxml-*-->
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
    "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">

<refentry id="flatpak-build-import-bundle">

    <refentryinfo>
        <title>flatpak build-import-bundle</title>
        <productname>flatpak</productname>

        <authorgroup>
            <author>
                <contrib>Developer</contrib>
                <firstname>Alexander</firstname>
                <surname>Larsson</surname>
                <email>alexl@redhat.com</email>
            </author>
        </authorgroup>
    </refentryinfo>

    <refmeta>
        <refentrytitle>flatpak build-import-bundle</refentrytitle>
        <manvolnum>1</manvolnum>
    </refmeta>

    <refnamediv>
        <refname>flatpak-build-import-bundle</refname>
        <refpurpose>Import a file bundle into a local repository</refpurpose>
    </refnamediv>

    <refsynopsisdiv>
            <cmdsynopsis>
                <command>flatpak build-import-bundle</command>
                <arg choice="opt" rep="repeat">OPTION</arg>
                <arg choice="plain">LOCATION</arg>
                <arg choice="plain">FILENAME</arg>
            </cmdsynopsis>
    </refsynopsisdiv>

    <refsect1>
        <title>Description</title>

        <para>
            Imports a bundle from a file named <arg choice="plain">FILENAME</arg>
            into the repository at <arg choice="plain">LOCATION</arg>.
        </para>
        <para>
            The format of the bundle file is that generated by build-bundle.
        </para>
    </refsect1>

    <refsect1>
        <title>Options</title>

        <para>The following options are understood:</para>

        <variablelist>
            <varlistentry>
                <term><option>-h</option></term>
                <term><option>--help</option></term>

                <listitem><para>
                    Show help options and exit.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>-v</option></term>
                <term><option>--verbose</option></term>

                <listitem><para>
                    Print debug information during command processing.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--ostree-verbose</option></term>

                <listitem><para>
                    Print OSTree debug information during command processing.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--ref=REF</option></term>

                <listitem><para>
                    Override the ref specified in the bundle.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--oci</option></term>

                <listitem><para>
                    Import an OCI image instead of a Flatpak bundle.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--update-appstream</option></term>

                <listitem><para>
                    Update the appstream branch after the build.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--no-update-summary</option></term>

                <listitem><para>
                    Don't update the summary file after the new commit is added. This means
                    the repository will not be useful for serving over http until build-update-repo
                    has been run. This is useful is you want to do multiple repo operations before
                    finally updating the summary.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--gpg-sign=KEYID</option></term>

                <listitem><para>
                    Sign the commit with this GPG key.
                    This option can be used multiple times.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--gpg-homedir=PATH</option></term>

                <listitem><para>
                    GPG Homedir to use when looking for keyrings
                </para></listitem>
            </varlistentry>
        </variablelist>
    </refsect1>

    <refsect1>
        <title>See also</title>

        <para>
            <citerefentry><refentrytitle>ostree</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
            <citerefentry><refentrytitle>flatpak</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
            <citerefentry><refentrytitle>flatpak-build-bundle</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
            <citerefentry><refentrytitle>flatpak-build-update-repo</refentrytitle><manvolnum>1</manvolnum></citerefentry>
        </para>

    </refsect1>

</refentry>

===== ./doc/flatpak-metadata.xml =====
<?xml version='1.0'?> <!--*-nxml-*-->
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
    "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">

<refentry id="flatpak-metadata">

    <refentryinfo>
        <title>flatpak metadata</title>
        <productname>flatpak</productname>

        <authorgroup>
            <author>
                <contrib>Developer</contrib>
                <firstname>Alexander</firstname>
                <surname>Larsson</surname>
                <email>alexl@redhat.com</email>
            </author>
        </authorgroup>
    </refentryinfo>

    <refmeta>
        <refentrytitle>flatpak metadata</refentrytitle>
        <manvolnum>5</manvolnum>
    </refmeta>

    <refnamediv>
        <refname>flatpak-metadata</refname>
        <refpurpose>Information about an application or runtime</refpurpose>
    </refnamediv>

    <refsect1>
        <title>Description</title>

        <para>
            Flatpak uses metadata files to describe applications and runtimes.
            The <filename>metadata</filename> file for a deployed application or
            runtime is placed in the toplevel deploy directory. For example, the
            metadata for the locally installed application org.gnome.Calculator
            is in
            <filename>~/.local/share/flatpak/app/org.gnome.Calculator/current/active/metadata</filename>.
        </para>

        <para>
            Most aspects of the metadata configuration can be overridden when
            launching applications, either temporarily via options of the flatpak
            run command, or permanently with the flatpak override command.
        </para>

        <para>
            A metadata file describing the effective configuration is available
            inside the running sandbox at <filename>/.flatpak-info</filename>.
            For compatibility with older Flatpak versions,
            <filename>/run/user/$UID/flatpak-info</filename> is a symbolic
            link to the same file.
        </para>
    </refsect1>

    <refsect1>
        <title>File format</title>

        <para>
            The metadata file is using the same .ini file format that is used for
            systemd unit files or application .desktop files.
        </para>

        <refsect2 id="application-runtime-metadata">
            <title>[Application] or [Runtime]</title>

            <para>
                Metadata for applications starts with an [Application] group,
                metadata for runtimes with a [Runtime] group.
            </para>
            <para>
                The following keys can be present in these groups:
            </para>
            <variablelist>
                <varlistentry>
                    <term><option>name</option> (string)</term>
                    <listitem><para>The name of the application or runtime. This key is mandatory.</para></listitem>
                </varlistentry>
                <varlistentry>
                    <term><option>runtime</option> (string)</term>
                    <listitem><para>The fully qualified name of the runtime that is used by the application. This key is mandatory for applications.</para></listitem>
                </varlistentry>
                <varlistentry>
                    <term><option>sdk</option> (string)</term>
                    <listitem>
                      <para>
                        The fully qualified name of the sdk that matches the
                        runtime. Available since 0.1.</para>
                    </listitem>
                </varlistentry>
                <varlistentry>
                    <term><option>command</option> (string)</term>
                    <listitem>
                      <para>
                        The command to run. Only relevant for applications.
                        Available since 0.1.
                      </para>
                    </listitem>
                </varlistentry>
                <varlistentry>
                    <term><option>required-flatpak</option> (string list)</term>
                    <listitem><para>
                        The required version of Flatpak to run this application
                        or runtime. For applications, this was available since
                        0.8.0. For runtimes, this was available since 0.9.1,
                        and backported to 0.8.3 for the 0.8.x branch.
                      </para><para>
                        Flatpak after version 1.4.3 and 1.2.5 support multiple versions here.
                        This can be useful if you need to support features that are backported
                        to a previous stable series. For example if you want to use a feature
                        added in 1.6.0 that was also backported to 1.4.4 you would use
                        <literal>1.6.0;1.4.4;</literal>. Note that older versions of flatpak will
                        just use the first element in the list, so make that the largest version.
                    </para></listitem>
                </varlistentry>
                <varlistentry>
                    <term><option>tags</option> (string list)</term>
                    <listitem><para>
                        Tags to include in AppStream XML. Typical values
                        in use on Flathub include
                        <option>beta</option>, <option>stable</option>,
                        <option>proprietary</option>
                        and <option>upstream-maintained</option>.
                        Available since 0.4.12.
                    </para></listitem>
                </varlistentry>
            </variablelist>
        </refsect2>
        <refsect2 id="context-metadata">
            <title>[Context]</title>
            <para>
                This group determines various system resources that may be shared
                with the application when it is run in a flatpak sandbox.
            </para>
            <refsect3 id="conditional-permissions">
                <title>Conditional Permissions</title>
                <para>
                    Some permissions (such as <option>sockets</option> and
                    <option>devices</option>) support conditional grants,
                    where access is only provided when specific runtime
                    conditions are met. This allows applications to adapt
                    to different system capabilities and session types.
                    Available since 1.17.
                </para>
                <para>
                    Conditional permissions use the syntax
                    <literal>if:PERMISSION:CONDITION</literal> in the
                    metadata file. For example,
                    <literal>if:wayland:has-wayland</literal> grants
                    Wayland socket access only when running in a Wayland session.
                </para>
                <para>
                    The following conditions are supported:
                </para>
                <variablelist>
                    <varlistentry>
                        <term><option>true</option></term>
                        <listitem><para>
                            Always evaluates to true.
                        </para></listitem>
                    </varlistentry>
                    <varlistentry>
                        <term><option>false</option></term>
                        <listitem><para>
                            Always evaluates to false.
                        </para></listitem>
                    </varlistentry>
                    <varlistentry>
                        <term><option>has-input-device</option></term>
                        <listitem><para>
                            True if this version of Flatpak supports the
                            <option>input</option> device permission.
                            This is always true in Flatpak 1.15.6 and later,
                            and can be used to provide fallback behavior for
                            older Flatpak versions.
                        </para></listitem>
                    </varlistentry>
                    <varlistentry>
                        <term><option>has-wayland</option></term>
                        <listitem><para>
                            True if the current desktop session supports
                            Wayland.
                        </para></listitem>
                    </varlistentry>
                    <varlistentry>
                        <term><option>has-usb-device</option></term>
                        <listitem><para>
                            True if this version of Flatpak supports the
                            <option>usb</option> device permission.
                            This is always true in Flatpak 1.16.0 and later,
                            and can be used to provide fallback behavior for
                            older Flatpak versions.
                        </para></listitem>
                    </varlistentry>
                    <varlistentry>
                        <term><option>has-usb-portal</option></term>
                        <listitem><para>
                            True if the current desktop session supports
                            the USB Portal.
                        </para></listitem>
                    </varlistentry>
                </variablelist>
                <para>
                    Conditions can be negated by prefixing with
                    <literal>!</literal>. For example,
                    <literal>if:x11:!has-wayland</literal> grants
                    X11 socket access only when NOT running in a Wayland session.
                </para>
                <para>
                    Multiple conditional permissions can be specified for
                    the same resource. If any condition matches, the
                    permission is granted (OR logic). For example:
<programlisting>
sockets=wayland;if:x11:!has-wayland;if:x11:false
</programlisting>
                </para>
                <para>
                    For backward compatibility with older Flatpak versions,
                    conditional permissions can be combined with unconditional
                    grants:
<programlisting>
sockets=x11;if:x11:!has-wayland;
</programlisting>
                    Older Flatpak versions will grant X11 access unconditionally
                    (seeing only <literal>x11</literal>), while newer
                    versions recognize the conditional syntax and grant
                    X11 access only when not in Wayland sessions.
                </para>
                <para>
                    To explicitly deny a permission that might be granted at
                    a lower layer (such as from the runtime or a global override),
                    prefix the permission name with <literal>!</literal>:
<programlisting>
sockets=!x11;
</programlisting>
                    This denial can be combined with conditional grants to
                    remove unconditional access while allowing conditional access:
<programlisting>
sockets=!x11;x11;if:x11:!has-wayland;
</programlisting>
                    This denies unconditional X11 access, but allows X11
                    access conditionally when not running in a Wayland session.
                    The seemingly contradictory <literal>!x11</literal> and
                    <literal>x11</literal> ensures backward compatibility:
                    older Flatpak versions see the final <literal>x11</literal>
                    grant, while newer versions understand the conditional logic.
                </para>
            </refsect3>
            <para>
                All keys in this group (and the group itself) are optional.
            </para>
            <para>
                The keys supported in this group are:
            </para>
            <variablelist>
                <varlistentry>
                    <term><option>shared</option> (list)</term>
                    <listitem><para>
                        List of subsystems to share with the host system.
                        Possible subsystems: network, ipc.
                        Available since 0.3.
                    </para><para>
                        This option supports conditional permissions.
                        See <link linkend="conditional-permissions">Conditional Permissions</link>
                        for details on how to share subsystem access conditionally
                        based on runtime conditions.
                    </para></listitem>
                </varlistentry>

                <varlistentry>
                    <term><option>sockets</option> (list)</term>
                    <listitem><para>
                        List of well-known sockets to make available in the sandbox.
                        Possible sockets: x11, wayland, fallback-x11, pulseaudio, session-bus, system-bus,
                        ssh-auth, pcsc, cups, gpg-agent, inherit-wayland-socket.
                        When making a socket available, flatpak also sets
                        well-known environment variables like DISPLAY or
                        DBUS_SYSTEM_BUS_ADDRESS to let the application
                        find sockets that are not in a fixed location.
                        Available since 0.3.
                    </para><para>
                        This option supports conditional permissions.
                        See <link linkend="conditional-permissions">Conditional Permissions</link>
                        for details on how to grant socket access conditionally
                        based on runtime conditions.
                    </para></listitem>
                </varlistentry>

                <varlistentry>
                    <term><option>devices</option> (list)</term>
                    <listitem><para>
                        List of devices to make available in the sandbox. This
                        just expose the devices nodes, it doesn't grant any
                        permission that the user doesn't already have.
                        Possible values:
                        <variablelist>

                            <varlistentry><term><option>dri</option></term>
                            <listitem><para>
                                GPU graphics and compute
                                (<filename>/dev/dri</filename>), including
                                vendor specific render and compute devices.
                                Available since 0.3.
                            </para></listitem></varlistentry>

                            <varlistentry><term><option>input</option></term>
                            <listitem><para>
                                Input devices
                                (<filename>/dev/input</filename>).
                                Available since 1.15.6.
                            </para></listitem></varlistentry>

                            <varlistentry><term><option>usb</option></term>
                            <listitem><para>
                                USB device bus
                                (all device nodes below
                                <filename>/dev/bus/usb</filename>).
                                Available since 1.15.11.
                            </para></listitem></varlistentry>

                            <varlistentry><term><option>kvm</option></term>
                            <listitem><para>
                                Virtualization
                                (<filename>/dev/kvm</filename>).
                                Available since 0.6.12.
                            </para></listitem></varlistentry>

                            <varlistentry><term><option>all</option></term>
                            <listitem><para>
                                All device nodes in <filename>/dev</filename>, but not /dev/shm (which is separately specified).
                                Available since 0.6.6.
                            </para></listitem></varlistentry>

                            <varlistentry><term><option>shm</option></term>
                            <listitem><para>
                                Access to the host /dev/shm
                                (<filename>/dev/shm</filename>).
                                Available since 1.6.1.
                            </para></listitem></varlistentry>

                        </variablelist>
                    </para><para>
                        This option supports conditional permissions.
                        See <link linkend="conditional-permissions">Conditional Permissions</link>
                        for details on how to grant device access conditionally
                        based on runtime conditions.
                    </para></listitem>
                </varlistentry>

                <varlistentry>
                    <term><option>filesystems</option> (list)</term>
                    <listitem><para>
                        List of filesystem subsets to make available to the
                        application. Possible values:
                        <variablelist>

                            <varlistentry><term><option>home</option></term>
                            <listitem><para>
                                The entire home directory.
                                Available since 0.3.
                            </para></listitem></varlistentry>

                            <varlistentry><term><option>home/<replaceable>path</replaceable></option></term><listitem><para>
                                  Alias for <filename>~/path</filename>
                                  Available since 1.10.
                                  For better compatibility with older
                                  Flatpak versions, prefer to write this
                                  as <filename>~/path</filename>.
                            </para></listitem></varlistentry>

                            <varlistentry><term><option>host</option></term>
                            <listitem><para>
                                The entire host file system, except for
                                directories that are handled specially by
                                Flatpak.
                                In particular, this shares
                                <filename>/home</filename>,
                                <filename>/media</filename>,
                                <filename>/opt</filename>,
                                <filename>/run/media</filename> and
                                <filename>/srv</filename> if they exist.
                            </para>
                            <para>
                                <filename>/dev</filename> is not shared:
                                use <option>devices=all;</option> instead.
                            </para>
                            <para>
                                Parts of <filename>/sys</filename> are always
                                shared. This option does not make additional
                                files in /sys available.
                            </para>
                            <para>
                                Additionally, this keyword provides all of the
                                same directories in
                                <filename>/run/host</filename> as the
                                <option>host-os</option> and
                                <option>host-etc</option> keywords.
                                If this keyword is used in conjunction
                                with one of the <option>host-</option>
                                keywords, whichever access level is higher
                                (more permissive) will be used for the
                                directories in <filename>/run/host</filename>:
                                for example,
                                <code>host:rw;host-os:ro;</code> is
                                equivalent to <code>host:rw;</code>.
                            </para>
                            <para>
                                These other reserved directories are
                                currently excluded:
                                <filename>/app</filename>,
                                <filename>/bin</filename>,
                                <filename>/boot</filename>,
                                <filename>/efi</filename>,
                                <filename>/etc</filename>,
                                <filename>/lib</filename>,
                                <filename>/lib32</filename>,
                                <filename>/lib64</filename>,
                                <filename>/proc</filename>,
                                <filename>/root</filename>,
                                <filename>/run</filename>,
                                <filename>/sbin</filename>,
                                <filename>/tmp</filename>,
                                <filename>/usr</filename>,
                                <filename>/var</filename>.
                            </para>
                            <para>
                                Available since 0.3.
                            </para></listitem></varlistentry>

                            <varlistentry><term><option>host-os</option></term>
                            <listitem><para>
                                The host operating system's libraries,
                                executables and static data from
                                <filename>/usr</filename>
                                and the related directories
                                <filename>/bin</filename>,
                                <filename>/lib</filename>,
                                <filename>/lib32</filename>,
                                <filename>/lib64</filename>,
                                <filename>/sbin</filename>.
                                Additionally, this keyword provides access
                                to a subset of <filename>/etc</filename> that
                                is associated with packaged libraries and
                                executables, even if the
                                <option>host-etc</option> keyword
                                was not used:
                                <filename>/etc/ld.so.cache</filename>,
                                (used by the dynamic linker) and
                                <filename>/etc/alternatives</filename>
                                (on operating systems that use it, such as
                                Debian).
                            </para>
                            <para>
                                To avoid conflicting with the Flatpak
                                runtime, these are mounted in the sandbox
                                at <filename>/run/host/usr</filename>,
                                <filename>/run/host/etc/ld.so.cache</filename>
                                and so on.
                            </para>
                            <para>
                                Available since 1.7.
                            </para></listitem></varlistentry>

                            <varlistentry><term><option>host-etc</option></term>
                            <listitem><para>
                                The host operating system's configuration from
                                <filename>/etc</filename>.
                            </para>
                            <para>
                                To avoid conflicting with the Flatpak
                                runtime, this is mounted in the sandbox
                                at <filename>/run/host/etc</filename>.
                            </para>
                            <para>
                                Available since 1.7.
                            </para></listitem></varlistentry>

                            <varlistentry><term><option>host-root</option></term>
                            <listitem><para>
                                The complete host operating system.
                            </para>
                            <para>
                                To avoid conflicting with the Flatpak
                                runtime, this is mounted in the sandbox
                                at <filename>/run/host/root</filename>.
                            </para>
                            <para>
                                This permission is only intended to be used
                                as a last resort when there is no possible
                                alternative with other filesystem
                                permissions for applications that need the
                                entire root filesystem of the host.
                            </para>
                            <para>
                                Please note that following symlinks under
                                <filename>/run/host/root</filename> naively
                                will result in a wrong path. For example,
                                using <literal>realpath()</literal> is wrong.
                                Instead, applications will have to implement
                                some way of following symlinks in a way that
                                behaves as if it were chroot'd into
                                <filename>/run/host/root</filename>.
                            </para>
                            <para>
                                There are a few ways to do this. Modern
                                kernels support the <ulink url="https://man7.org/linux/man-pages/man2/openat2.2.html">openat2()</ulink>
                                call with <literal>RESOLVE_IN_ROOT</literal>.
                                For a more portable solution with support for
                                older kernels, see the implementation from
                                the <ulink url="https://gitlab.steamos.cloud/steamrt/steam-runtime-tools/-/blob/65adfdd5fc812aeb5f33986755f6ff72c9612afa/steam-runtime-tools/resolve-in-sysroot.c">steam-runtime-tools</ulink>
                                as an example.
                            </para>
                            <para>
                                Available since 1.17.
                            </para></listitem></varlistentry>

                            <varlistentry><term><option>xdg-desktop</option>,
                                <option>xdg-documents</option>,
                                <option>xdg-download</option>,
                                <option>xdg-music</option>,
                                <option>xdg-pictures</option>,
                                <option>xdg-public-share</option>,
                                <option>xdg-videos</option>,
                                <option>xdg-templates</option>
                            </term><listitem><para>
                                <ulink url="https://www.freedesktop.org/wiki/Software/xdg-user-dirs/"
                                  >freedesktop.org special directories</ulink>.
                                Available since 0.3.
                            </para></listitem></varlistentry>

                            <varlistentry><term><option>xdg-desktop/<replaceable>path</replaceable></option>,
                                <option>xdg-documents/<replaceable>path</replaceable></option>,
                                etc.
                            </term><listitem><para>
                                Subdirectories of freedesktop.org special
                                directories. Available since 0.4.13.
                            </para></listitem></varlistentry>

                            <varlistentry><term>
                                <option>xdg-cache</option>,
                                <option>xdg-config</option>,
                                <option>xdg-data</option>
                            </term><listitem><para>
                                Directories defined by the
                                <ulink url="https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html"
                                  >freedesktop.org Base Directory Specification</ulink>.
                                Available since 0.6.14.
                            </para></listitem></varlistentry>

                            <varlistentry><term>
                                <option>xdg-cache/<replaceable>path</replaceable></option>,
                                <option>xdg-config/<replaceable>path</replaceable></option>,
                                <option>xdg-data/<replaceable>path</replaceable></option>
                            </term><listitem><para>
                                Subdirectories of directories defined by the
                                freedesktop.org Base Directory Specification.
                                Available since 0.6.14.
                            </para></listitem></varlistentry>

                            <varlistentry><term>
                                <option>xdg-run/<replaceable>path</replaceable></option>
                            </term><listitem><para>
                                Subdirectories of the
                                <envar>XDG_RUNTIME_DIR</envar> defined by the
                                freedesktop.org Base Directory Specification.
                                Note that <option>xdg-run</option> on its own
                                is not supported. Available since 0.4.13.
                            </para></listitem></varlistentry>

                            <varlistentry><term>
                                <option>/<replaceable>path</replaceable></option>
                            </term><listitem><para>
                                An arbitrary absolute path. Available since 0.3.
                            </para></listitem></varlistentry>

                            <varlistentry><term>
                                <option>~/<replaceable>path</replaceable></option>
                            </term><listitem><para>
                                An arbitrary path relative to the home
                                directory. Available since 0.3.
                            </para></listitem></varlistentry>

                            <varlistentry><term><option>~</option></term>
                            <listitem><para>
                                  The same as <option>home</option>.
                                  Available since 1.10.
                                  For better compatibility with older
                                  Flatpak versions, prefer to write this
                                  as <option>home</option>.
                            </para></listitem></varlistentry>

                            <varlistentry><term>
                                One of the above followed by
                                <option>:ro</option>
                            </term><listitem><para>
                                Make the given directory available read-only.
                            </para></listitem></varlistentry>

                            <varlistentry><term>
                                One of the above followed by
                                <option>:rw</option>
                            </term><listitem><para>
                                Make the given directory available read/write.
                                This is the default.
                            </para></listitem></varlistentry>

                            <varlistentry><term>
                                One of the above followed by
                                <option>:create</option>
                            </term><listitem><para>
                                Make the given directory available read/write,
                                and create it if it does not already exist.
                            </para></listitem></varlistentry>

                        </variablelist>
                    </para></listitem>
                </varlistentry>
                <varlistentry>
                    <term><option>persistent</option> (list)</term>
                    <listitem><para>
                      List of homedir-relative paths to make available at
                      the corresponding path in the per-application home directory,
                      allowing the locations to be used for persistent data when
                      the application does not have access to the real homedir.
                      For instance making ".myapp" persistent would make "~/.myapp"
                      in the sandbox a bind mount to "~/.var/app/org.my.App/.myapp",
                      thus allowing an unmodified application to save data in
                      the per-application location. Available since 0.3.
                    </para></listitem>
                </varlistentry>
                <varlistentry>
                    <term><option>features</option> (list)</term>
                    <listitem><para>
                        List of features available or unavailable to the
                        application, currently from the following list:
                        <variablelist>

                            <varlistentry><term><option>devel</option></term>
                            <listitem><para>
                                Allow system calls used by development-oriented
                                tools such as <command>perf</command>,
                                <command>strace</command> and
                                <command>gdb</command>.
                                Available since 0.6.10.
                            </para></listitem></varlistentry>

                            <varlistentry><term><option>multiarch</option></term>
                            <listitem><para>
                                Allow running multilib/multiarch binaries, for
                                example <literal>i386</literal> binaries in an
                                <literal>x86_64</literal> environment.
                                Available since 0.6.12.
                            </para></listitem></varlistentry>

                            <varlistentry><term><option>bluetooth</option></term>
                            <listitem><para>
                              Allow the application to use bluetooth (AF_BLUETOOTH) sockets.
                              Note, for bluetooth to fully work you must also have network access.
                              Available since 0.11.8.
                            </para></listitem></varlistentry>

                            <varlistentry><term><option>canbus</option></term>
                            <listitem><para>
                              Allow the application to use canbus (AF_CAN) sockets.
                              Note, for this work you must also have network access.
                              Available since 1.0.3.
                            </para></listitem></varlistentry>

                            <varlistentry><term><option>per-app-dev-shm</option></term>
                            <listitem><para>
                              Share a single instance of
                              <filename>/dev/shm</filename> between all
                              instances of this application run by the same
                              user ID, including sub-sandboxes.
                              If the application has the
                              <option>shm</option> device permission in its
                              <option>devices</option> list, then this
                              feature flag is ignored.
                              Available since 1.12.0.
                            </para></listitem></varlistentry>

                        </variablelist>
                        A feature can be prefixed with <option>!</option> to
                        indicate the absence of that feature, for example
                        <option>!devel</option> if development and debugging
                        are not allowed.
                    </para><para>
                        This option supports conditional permissions.
                        See <link linkend="conditional-permissions">Conditional Permissions</link>
                        for details on how to allow features based
                        conditionally on runtime conditions.
                    </para></listitem>
                </varlistentry>
                <varlistentry>
                    <term><option>unset-environment</option> (list)</term>
                    <listitem><para>
                        A list of names of environment variables to unset.
                        Note that environment variables to set to a value
                        (possibly empty) appear in the [Environment]
                        group instead.
                    </para></listitem>
                </varlistentry>
            </variablelist>
        </refsect2>
        <refsect2 id="instance-metadata">
            <title>[Instance]</title>
            <para>
                This group only appears in <filename>/.flatpak-info</filename>
                for a running app, and not in the metadata files written by
                application authors. It is filled in by Flatpak itself.
            </para>
            <!-- In versions prior to 0.6.10 some of this information was
            in [Application], but for simplicity that isn't documented
            here. -->
            <variablelist>
                <varlistentry>
                    <term><option>instance-id</option> (string)</term>
                    <listitem><para>
                        The ID of the running instance. This number is
                        used as the name of the directory in
                        <filename><envar>XDG_RUNTIME_DIR</envar>/.flatpak</filename>
                        where Flatpak stores information about this instance.
                    </para></listitem>
                </varlistentry>
                <varlistentry>
                    <term><option>instance-path</option> (string)</term>
                    <listitem><para>
                        The absolute path on the host system of the app's
                        persistent storage area in <filename>$HOME/.var</filename>.
                    </para></listitem>
                </varlistentry>
                <varlistentry>
                    <term><option>app-path</option> (string)</term>
                    <listitem><para>
                        The absolute path on the host system of the app's
                        app files, as mounted at <filename>/app</filename>
                        inside the container. Available since 0.6.10.
                    </para><para>
                        Since 1.12.0, if <command>flatpak run</command>
                        was run with the <option>--app-path</option> option,
                        this key gives the absolute path of whatever files
                        were mounted on <filename>/app</filename>, even if
                        that differs from the app's normal app files.
                    </para><para>
                        If <command>flatpak run</command> was run with
                        <option>--app-path=</option> (resulting in an
                        empty directory being mounted on
                        <filename>/app</filename>), the value is set to
                        the empty string.
                    </para></listitem>
                </varlistentry>
                <varlistentry>
                    <term><option>original-app-path</option> (string)</term>
                    <listitem><para>
                        If <command>flatpak run</command> was run with the
                        <option>--app-path</option> option, this key gives
                        the absolute path of the app's original files,
                        as mounted at <filename>/run/parent/app</filename>
                        inside the container. Available since 1.12.0.
                    </para><para>
                        If this key is missing, the app files are given
                        by <option>app-path</option>.
                    </para></listitem>
                </varlistentry>
                <varlistentry>
                    <term><option>app-commit</option> (string)</term>
                    <listitem><para>
                        The commit ID of the application that is running.
                        The filename of a deployment of this commit can
                        be found in <option>original-app-path</option>
                        if present, or <option>app-path</option> otherwise.
                    </para></listitem>
                </varlistentry>
                <varlistentry>
                    <term><option>app-extensions</option> (list of strings)</term>
                    <listitem><para>
                        A list of app extensions that are mounted into
                        the running instance. The format for each list item is
                        <option>EXTENSION_ID=COMMIT</option>.
                        If <option>original-app-path</option> is present,
                        the extensions are mounted below
                        <filename>/run/parent/app</filename>; otherwise,
                        they are mounted below <filename>/app</filename>.
                    </para></listitem>
                </varlistentry>
                <varlistentry>
                    <term><option>branch</option> (string)</term>
                    <listitem><para>
                        The branch of the app, for example
                        <literal>stable</literal>. Available since
                        0.6.10.
                    </para></listitem>
                </varlistentry>
                <varlistentry>
                    <term><option>arch</option> (string)</term>
                    <listitem><para>
                        The architecture of the running instance.
                    </para></listitem>
                </varlistentry>
                <varlistentry>
                    <term><option>flatpak-version</option> (string)</term>
                    <listitem><para>
                        The version number of the Flatpak version that ran
                        this app. Available since 0.6.11.
                    </para></listitem>
                </varlistentry>
                <varlistentry>
                    <term><option>runtime-path</option> (string)</term>
                    <listitem><para>
                        The absolute path on the host system of the app's
                        runtime files, as mounted at <filename>/usr</filename>
                        inside the container. Available since 0.6.10.
                    </para><para>
                        Since 1.12.0, if <command>flatpak run</command>
                        was run with the <option>--usr-path</option> option,
                        this key gives the absolute path of whatever files
                        were mounted on <filename>/usr</filename>, even if
                        that differs from the app's normal runtime files.
                    </para></listitem>
                </varlistentry>
                <varlistentry>
                    <term><option>original-runtime-path</option> (string)</term>
                    <listitem><para>
                        If <command>flatpak run</command> was run with the
                        <option>--runtime-path</option> option, this key gives
                        the absolute path of the app's original runtime,
                        as mounted at <filename>/run/parent/usr</filename>
                        inside the container. Available since 1.12.0.
                    </para><para>
                        If this key is missing, the runtime files are given
                        by <option>runtime-path</option>.
                    </para></listitem>
                </varlistentry>
                <varlistentry>
                    <term><option>runtime-commit</option> (string)</term>
                    <listitem><para>
                        The commit ID of the runtime that is used.
                        The filename of a deployment of this commit can be
                        found in <option>original-runtime-path</option>
                        if present, or <option>runtime-path</option>
                        otherwise.
                    </para></listitem>
                </varlistentry>
                <varlistentry>
                    <term><option>runtime-extensions</option> (list of strings)</term>
                    <listitem><para>
                        A list of runtime extensions that are mounted into
                        the running instance. The format for each list item is
                        <option>EXTENSION_ID=COMMIT</option>.
                        If <option>original-app-path</option> is present,
                        the extensions are mounted below
                        <filename>/run/parent/usr</filename>; otherwise,
                        they are mounted below <filename>/usr</filename>.
                    </para></listitem>
                </varlistentry>
                <varlistentry>
                    <term><option>extra-args</option> (string)</term>
                    <listitem><para>
                        Extra arguments that were passed to flatpak run.
                    </para></listitem>
                </varlistentry>
                <varlistentry>
                    <term><option>sandbox</option> (boolean)</term>
                    <listitem><para>
                        Whether the <option>--sandbox</option> option was passed
                        to flatpak run.
                    </para></listitem>
                </varlistentry>
                <varlistentry>
                    <term><option>build</option> (boolean)</term>
                    <listitem><para>
                        Whether this instance was created by flatpak build.
                    </para></listitem>
                </varlistentry>
                <varlistentry>
                    <term><option>session-bus-proxy</option> (boolean)</term>
                    <listitem><para>
                        True if this app cannot access the D-Bus session bus
                        directly (either it goes via a proxy, or it cannot
                        access the session bus at all). Available since 0.8.0.
                        <!-- TODO: Those semantics are weird, are they
                        intended? -->
                    </para></listitem>
                </varlistentry>
                <varlistentry>
                    <term><option>system-bus-proxy</option> (boolean)</term>
                    <listitem><para>
                        True if this app cannot access the D-Bus system bus
                        directly (either it goes via a proxy, or it cannot
                        access the system bus at all). Available since 0.8.0.
                        <!-- TODO: Those semantics are weird, are they
                        intended? -->
                    </para></listitem>
                </varlistentry>
            </variablelist>
        </refsect2>
        <refsect2 id="session-bus-policy-metadata">
            <title>[Session Bus Policy]</title>
            <para>
                If the <option>sockets</option> key is not allowing full access
                to the D-Bus session bus, then flatpak provides filtered access.
            </para>
            <para>
                The default policy for the session bus only allows the
                application to own its own application ID, its
                subnames and its own application ID as a subname of
                <option>org.mpris.MediaPlayer2</option>. For instance if the app is called
                <option>org.my.App</option>, it can only own <option>org.my.App</option>,
                <option>org.my.App.*</option>
                and <option>org.mpris.MediaPlayer2.org.my.App</option>.
                It is only allowed to talk to names matching those patterns, plus
                the bus itself (<option>org.freedesktop.DBus</option>)
                and the portal APIs (bus names of the form <option>org.freedesktop.portal.*</option>).
            </para>
            <para>
                Additionally the app is always allowed to reply to
                messages sent to it, and emit broadcast signals (but
                these will not reach other sandboxed apps unless they
                are allowed to talk to your app.
            </para>
            <para>
                If the <option>[Session Bus Policy]</option> group is present, it provides
                policy for session bus access.
            </para>
            <para>
                Each key in this group has the form of a D-Bus bus name or
                prefix thereof, for example <option>org.gnome.SessionManager</option>
                or <option>org.freedesktop.portal.*</option>.
            </para>
            <para>
                The possible values for an entry are the following, in increasing order of
                access. Each value implies all the access from any lower values:
            </para>
            <variablelist>
                <varlistentry>
                    <term><option>none</option></term>
                    <listitem><para>
                        The bus name is invisible to the application.
                        Available since 0.2.
                    </para></listitem>
                </varlistentry>
                <varlistentry>
                    <term><option>see</option></term>
                    <listitem><para>
                        The bus name can be enumerated by the application.
                        Available since 0.2.
                    </para></listitem>
                </varlistentry>
                <varlistentry>
                    <term><option>talk</option></term>
                    <listitem><para>
                        The application can send messages to, and receive replies and signals from, the bus name.
                        Available since 0.2.
                    </para></listitem>
                </varlistentry>
                <varlistentry>
                    <term><option>own</option></term>
                    <listitem><para>
                        The application can own the bus name.
                        Available since 0.2.
                    </para></listitem>
                </varlistentry>
            </variablelist>
        </refsect2>
        <refsect2 id="system-bus-policy-metadata">
            <title>[System Bus Policy]</title>
            <para>
                If the <option>sockets</option> key is not allowing full access
                to the D-Bus system bus, then flatpak does not make the system
                bus available unless the <option>[System Bus Policy]</option> group is present
                and provides a policy for filtered access. Available since 0.2.
            </para>
            <para>
                Entries in this group have the same form as for the
                <option>[Session Bus Policy]</option> group.
                However, the app has no permissions by default.
            </para>
        </refsect2>
        <refsect2 id="environment-metadata">
            <title>[Environment]</title>
            <para>
                The [Environment] group specifies environment variables to set
                when running the application. Available since 0.3.
            </para>
            <para>
                Entries in this group have the form <option>VAR=VALUE</option>
                where <option>VAR</option> is the name of an environment variable
                to set.
            </para>
            <para>
                Note that environment variables can also be unset (removed
                from the environment) by listing them in the
                <option>unset-environment</option> entry of the
                [Context] group.
              </para>
        </refsect2>
        <refsect2 id="extension-metadata">
            <title>[Extension NAME]</title>
            <para>
                Runtimes and applications can define extension points, which allow
                optional, additional runtimes to be mounted at a specified location
                inside the sandbox when they are present on the system. Typical uses
                for extension points include translations for applications, or debuginfo
                for sdks. The name of the extension point is specified as part of the
                group heading. Since 0.11.4, the name may optionally include a tag
                in the NAME in the name@tag ref syntax if you wish to use different
                configurations (eg, versions) of the same extension concurrently.
                The "tag" is effectively ignored, but is necessary in order to allow
                the same extension name to be specified more than once.
            </para>
            <variablelist>
                <varlistentry>
                    <term><option>directory</option> (string)</term>
                    <listitem><para>
                        The relative path at which the extension will be mounted in
                        the sandbox. If the extension point is for an application, the
                        path is relative to <filename>/app</filename>, otherwise
                        it is relative to <filename>/usr</filename>. This key
                        is mandatory. Available since 0.1.
                    </para></listitem>
                </varlistentry>
                <varlistentry>
                    <term><option>version</option> (string)</term>
                    <listitem><para>
                        The branch to use when looking for the extension. If this is
                        not specified, it defaults to the branch of the application or
                        runtime that the extension point is for.
                        Available since 0.4.1.
                    </para></listitem>
                </varlistentry>
                <varlistentry>
                    <term><option>versions</option> (string)</term>
                    <listitem><para>
                        The branches to use when looking for the extension. If this is
                        not specified, it defaults to the branch of the application or
                        runtime that the extension point is for. Available since
                        0.9.1, and backported to the 0.8.x branch in 0.8.4.
                    </para></listitem>
                </varlistentry>
                <varlistentry>
                    <term><option>add-ld-path</option> (string)</term>
                    <listitem><para>
                        A path relative to the extension point directory that will be appended
                        to LD_LIBRARY_PATH. Available since 0.9.1, and
                        backported to the 0.8.x branch in 0.8.3.
                    </para></listitem>
                </varlistentry>
                <varlistentry>
                    <term><option>merge-dirs</option> (string)</term>
                    <listitem><para>
                        A list of relative paths of directories below the extension point directory
                        that will be merged. Available since 0.9.1, and
                        backported to the 0.8.x branch in 0.8.3.
                    </para></listitem>
                </varlistentry>
                <varlistentry>
                    <term><option>download-if</option> (string)</term>
                    <listitem>
                        <para>
                            A condition that must be true for the extension to be auto-downloaded.
                            As of 1.1.1 this supports multiple conditions separated by semi-colons.
                        </para>
                        <para>
                            These are the supported conditions:
                        </para>
                        <variablelist>
                            <varlistentry>
                                <term><option>active-gl-driver</option></term>
                                <listitem><para>
                                    Is true if the name of the active GL driver matches the
                                    extension point basename. Available since 0.9.1, and backported to
                                    the 0.8.x branch in 0.8.3.
                                </para></listitem>
                            </varlistentry>
                            <varlistentry>
                                <term><option>active-gtk-theme</option></term>
                                <listitem><para>
                                    Is true if the name of the current GTK theme
                                    (via org.gnome.desktop.interface GSetting) matches the extension point
                                    basename. Added 0.10.1.
                                </para></listitem>
                            </varlistentry>
                            <varlistentry>
                                <term><option>have-intel-gpu</option></term>
                                <listitem><para>Is true if the i915 kernel module is loaded. Added 0.10.1.</para></listitem>
                            </varlistentry>
                            <varlistentry>
                                <term><option>have-kernel-module-*</option></term>
                                <listitem><para>
                                    Is true if the suffix (case-sensitive) is found in <literal>/proc/modules</literal>.
                                    For example <literal>have-kernel-module-nvidia</literal>.
                                    Added 1.13.1.
                                </para></listitem>
                            </varlistentry>
                            <varlistentry>
                                <term><option>on-xdg-desktop-*</option></term>
                                <listitem><para>
                                    Is true if the suffix (case-insensitively) is in the
                                    <literal>XDG_CURRENT_DESKTOP</literal> env var.
                                    For example <literal>on-xdg-desktop-GNOME-classic</literal>.
                                    Added 1.1.1.
                                </para></listitem>
                            </varlistentry>
                        </variablelist>
                    </listitem>
                </varlistentry>
                <varlistentry>
                    <term><option>autoprune-unless</option> (string)</term>
                    <listitem><para>
                        A condition that must be false for the extension to be considered unused when
                        pruning. For example, <command>flatpak uninstall --unused</command> and
                        <command>flatpak update</command> use this information. The only currently
                        recognized value is active-gl-driver, which is true if the name of the active
                        GL driver matches the extension point basename. Available since 0.11.8.
                    </para></listitem>
                </varlistentry>
                <varlistentry>
                    <term><option>enable-if</option> (string)</term>
                    <listitem><para>
                        A condition that must be true for the extension to be enabled.
                        As of 1.1.1 this supports multiple conditions separated by semi-colons.
                        See <option>download-if</option> for available conditions.
                    </para></listitem>
                </varlistentry>
                <varlistentry>
                    <term><option>subdirectory-suffix</option> (string)</term>
                    <listitem><para>
                        A suffix that gets appended to the directory name. This is very
                        useful when the extension point naming scheme is "reversed". For example,
                        an extension point for GTK+ themes would be /usr/share/themes/$NAME/gtk-3.0,
                        which could be achieved using subdirectory-suffix=gtk-3.0.
                        Available since 0.9.1, and backported to the 0.8.x
                        branch in 0.8.3.
                    </para></listitem>
                </varlistentry>
                <varlistentry>
                    <term><option>subdirectories</option> (boolean)</term>
                    <listitem><para>
                        If this key is set to true, then flatpak will look for
                        extensions whose name is a prefix of the extension point name, and
                        mount them at the corresponding name below the subdirectory.
                        Available since 0.1.
                    </para></listitem>
                </varlistentry>
                <varlistentry>
                    <term><option>no-autodownload</option> (boolean)</term>
                    <listitem><para>
                        Whether to automatically download extensions matching this extension
                        point when updating or installing a 'related' application or runtime.
                        Available since 0.6.7.
                    </para></listitem>
                </varlistentry>
                <varlistentry>
                    <term><option>locale-subset</option> (boolean)</term>
                    <listitem><para>
                        If set, then the extensions are partially downloaded by default,
                        based on the currently configured locales. This means that the extension
                        contents should be a set of directories with the language code as name.
                        Available since 0.9.13 (and 0.6.6 for any extensions called *.Locale)
                    </para></listitem>
                </varlistentry>
                <varlistentry>
                    <term><option>autodelete</option> (boolean)</term>
                    <listitem><para>
                        Whether to automatically delete extensions matching this extension
                        point when deleting a 'related' application or runtime.
                        Available since 0.6.7.
                    </para></listitem>
                </varlistentry>
                <varlistentry>
                    <term><option>collection-id</option> (string)</term>
                    <listitem><para>
                        The ID of the collection that this extension point belongs to. If this
                        is unspecified, it defaults to the collection ID of the application
                        or runtime that the extension point is for.
                        Currently, extension points must be in the same collection as the
                        application or runtime that they are for.
                        Available since 0.99.1.
                    </para></listitem>
                </varlistentry>
            </variablelist>
        </refsect2>
        <refsect2 id="extension-of-metadata">
            <title>[ExtensionOf]</title>
            <para>
                This optional group may be present if the runtime is an extension.
            </para>
            <variablelist>
                <varlistentry>
                    <term><option>ref</option> (string)</term>
                    <listitem><para>
                        The ref of the runtime or application that this extension
                        belongs to. Available since 0.9.1.
                    </para></listitem>
                </varlistentry>
                <varlistentry>
                    <term><option>runtime</option> (string)</term>
                    <listitem><para>
                        The runtime this extension will be inside of. If it is an
                        app extension, this is the app's runtime; otherwise, this
                        is identical to ref, without the runtime/ prefix.
                        Available since 1.5.0.
                    </para></listitem>
                </varlistentry>
                <varlistentry>
                    <term><option>priority</option> (integer)</term>
                    <listitem><para>
                        The priority to give this extension when looking for the
                        best match. Default is 0. Available since 0.9.1, and
                        backported to the 0.8.x branch in 0.8.3.
                    </para></listitem>
                </varlistentry>
                <varlistentry>
                    <term><option>tag</option> (string)</term>
                    <listitem><para>
                        The tag name to use when searching for this extension's mount
                        point in the parent flatpak. Available since 0.11.4.
                    </para></listitem>
                </varlistentry>
            </variablelist>
        </refsect2>
        <refsect2 id="extra-data-metadata">
            <title>[Extra Data]</title>
            <para>
                This optional group may be present if the runtime or application uses
                extra data that gets downloaded separately. The data in this group
                gets merged into the repository summary, with the xa.extra-data-sources
                key.
            </para>
            <para>
                If multiple extra data sources are present, their uri, size and checksum
                keys are grouped together by using the same suffix. If only one extra
                data source is present, the suffix can be omitted.
            </para>
            <variablelist>
                <varlistentry>
                    <term><option>NoRuntime</option> (boolean)</term>
                    <listitem><para>
                        Whether to mount the runtime while running the /app/bin/apply_extra
                        script. Defaults to true, i.e. not mounting the runtime.
                        Available since 0.9.1, and backported to the 0.8.x
                        branch in 0.8.4.
                    </para></listitem>
                </varlistentry>
                <varlistentry>
                    <term><option>uri<replaceable>X</replaceable></option> (string)</term>
                    <listitem><para>
                        The uri for extra data source
                        <replaceable>X</replaceable>. The only supported uri
                        schemes are http and https. Available since 0.6.13.
                    </para></listitem>
                </varlistentry>
                <varlistentry>
                    <term><option>size<replaceable>X</replaceable></option> (integer)</term>
                    <listitem><para>
                        The size for extra data source
                        <replaceable>X</replaceable>. Available since 0.6.13.
                    </para></listitem>
                </varlistentry>
                <varlistentry>
                    <term><option>checksum<replaceable>X</replaceable></option> (string)</term>
                    <listitem><para>
                        The sha256 sum for extra data source
                        <replaceable>X</replaceable>. Available since 0.6.13.
                    </para></listitem>
                </varlistentry>
            </variablelist>
        </refsect2>
        <refsect2 id="policy-metadata">
          <title>[Policy SUBSYSTEM]</title>
          <para>
            Subsystems can define their own policies to be placed in a group
            whose name has this form. Their values are treated as lists,
            in which items can have their meaning negated by prepending !
            to the value. They are not otherwise parsed by Flatpak.
            Available since 0.6.13.
            <!-- TODO: More information would be nice -->
          </para>
        </refsect2>
        <refsect2 id="usb-devices">
          <title>[USB Devices]</title>
          <para>
            USB devices can be enumerable or hidden by the USB portal as specified
            by the keys in this group. The vendor and product ids are validated
            by Flatpak, but aren't otherwise used or parsed.
            This merely grant the permission to enumerate USB device for use by the
            portal. This does give access to the devices.
            Available since 1.15.11.
          </para>
          <variablelist>
                <varlistentry>
                    <term><option>enumerable-devices</option> (string list)</term>
                    <listitem><para>
                        List of enumerable USB devices. Each element is the same
                        syntax the arguments to `--usb`.
                        Available since 1.15.11.
                    </para></listitem>
                </varlistentry>
                <varlistentry>
                    <term><option>hidden-devices</option> (string list)</term>
                    <listitem><para>
                        List of hidden USB devices, i.e. to remove the enumerable
                        devices list. Each element is the same syntax the arguments
                        to `--nousb`. Hidden devices take precedence over enumerable
                        devices. Available since 1.15.11.
                    </para></listitem>
                </varlistentry>
            </variablelist>
        </refsect2>
    </refsect1>

    <refsect1>
        <title>Example</title>
<programlisting>
[Application]
name=org.gnome.Calculator
runtime=org.gnome.Platform/x86_64/3.20
sdk=org.gnome.Sdk/x86_64/3.20
command=gnome-calculator

[Context]
shared=network;ipc;
sockets=x11;wayland;
filesystems=xdg-run/dconf;~/.config/dconf:ro;

[Session Bus Policy]
ca.desrt.dconf=talk

[Environment]
DCONF_USER_CONFIG_DIR=.config/dconf

[USB Devices]
enumerable-devices=0fd9:*;
hidden-devices=0fd9:0063;

[Extension org.gnome.Calculator.Locale]
directory=share/runtime/locale
subdirectories=true

[Extension org.gnome.Calculator.Debug]
directory=lib/debug
</programlisting>
        <para>
            Example using conditional permissions to support fallback
            from Wayland to X11:
        </para>
<programlisting>
[Application]
name=org.example.App
runtime=org.gnome.Platform/x86_64/3.20
sdk=org.gnome.Sdk/x86_64/3.20

[Context]
shared=network;ipc;
sockets=wayland;x11;if:x11:!has-wayland;
</programlisting>
        <para>
            In this example, the application will always have access to
            the Wayland socket if there the app runs in a Wayland session.
            The X11 socket only is available if the app does not run in
            a wayland session (<option>!has-wayland</option>).
        </para>
    </refsect1>

    <refsect1>
        <title>See also</title>

        <para>
            <citerefentry><refentrytitle>flatpak</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
            <citerefentry><refentrytitle>flatpak-run</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
            <citerefentry><refentrytitle>flatpak-override</refentrytitle><manvolnum>1</manvolnum></citerefentry>
        </para>

    </refsect1>

</refentry>

===== ./doc/flatpak-repo.xml =====
<?xml version='1.0'?> <!--*-nxml-*-->
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
    "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">

<refentry id="flatpak-repo">

    <refentryinfo>
        <title>flatpak repo</title>
        <productname>flatpak</productname>

        <authorgroup>
            <author>
                <contrib>Developer</contrib>
                <firstname>Alexander</firstname>
                <surname>Larsson</surname>
                <email>alexl@redhat.com</email>
            </author>
        </authorgroup>
    </refentryinfo>

    <refmeta>
        <refentrytitle>flatpak repo</refentrytitle>
        <manvolnum>1</manvolnum>
    </refmeta>

    <refnamediv>
        <refname>flatpak-repo</refname>
        <refpurpose>Show information about a local repository</refpurpose>
    </refnamediv>

    <refsynopsisdiv>
            <cmdsynopsis>
                <command>flatpak repo</command>
                <arg choice="opt" rep="repeat">OPTION</arg>
                <arg choice="plain">LOCATION</arg>
            </cmdsynopsis>
    </refsynopsisdiv>

    <refsect1>
        <title>Description</title>

        <para>
            Show information about a local repository.
        </para>
        <para>
            If you need to modify a local repository, see the
            <command>flatpak build-update-repo</command> command, or use the
            <command>ostree</command> tool.
        </para>

    </refsect1>

    <refsect1>
        <title>Options</title>

        <para>The following options are understood:</para>

        <variablelist>
            <varlistentry>
                <term><option>-h</option></term>
                <term><option>--help</option></term>

                <listitem><para>
                    Show help options and exit.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--info</option></term>

                <listitem><para>
                    Print general information about a local repository.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--branches</option></term>

                <listitem><para>
                    List the branches in a local repository.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--metadata=BRANCH</option></term>

                <listitem><para>
                  Print metadata for a branch in the repository.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--commits=BRANCH</option></term>

                <listitem><para>
                  Show commits and deltas for a branch in the repository.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>-v</option></term>
                <term><option>--verbose</option></term>

                <listitem><para>
                    Print debug information during command processing.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--ostree-verbose</option></term>

                <listitem><para>
                    Print OSTree debug information during command processing.
                </para></listitem>
            </varlistentry>
        </variablelist>
    </refsect1>

    <refsect1>
        <title>Examples</title>

        <para>
            <command>$ flatpak repo --info ~/my-repo</command>
        </para>

    </refsect1>

    <refsect1>
        <title>See also</title>

        <para>
            <citerefentry><refentrytitle>flatpak</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
            <citerefentry><refentrytitle>flatpak-info</refentrytitle><manvolnum>1</manvolnum></citerefentry>
            <citerefentry><refentrytitle>flatpak-build-update-repo</refentrytitle><manvolnum>1</manvolnum></citerefentry>
            <citerefentry><refentrytitle>ostree</refentrytitle><manvolnum>1</manvolnum></citerefentry>
        </para>

    </refsect1>

</refentry>

===== ./doc/flatpak-preinstall.xml =====
<?xml version='1.0'?> <!--*-nxml-*-->
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
    "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">

<refentry id="flatpak-preinstall">

    <refentryinfo>
        <title>flatpak preinstall</title>
        <productname>flatpak</productname>

        <authorgroup>
            <author>
                <contrib>Developer</contrib>
                <firstname>Kalev</firstname>
                <surname>Lember</surname>
                <email>klember@redhat.com</email>
            </author>
        </authorgroup>
    </refentryinfo>

    <refmeta>
        <refentrytitle>flatpak preinstall</refentrytitle>
        <manvolnum>1</manvolnum>
    </refmeta>

    <refnamediv>
        <refname>flatpak-preinstall</refname>
        <refpurpose>Install flatpaks that are part of the operating system</refpurpose>
    </refnamediv>

    <refsynopsisdiv>
            <cmdsynopsis>
                <command>flatpak preinstall</command>
                <arg choice="opt" rep="repeat">OPTION</arg>
            </cmdsynopsis>
    </refsynopsisdiv>

    <refsect1>
        <title>Description</title>

        <para>
          This command manages flatpaks that are part of the operating system. If no options are given, running <command>flatpak preinstall</command> will synchronize (install and remove) flatpaks to match the set that the OS vendor has chosen.
        </para>

        <para>
          Preinstalled flatpaks are defined by dropping .preinstall files into the directories <filename>/usr/share/flatpak/preinstall.d/</filename> and <filename>/etc/flatpak/preinstall.d/</filename>. The OS runs <command>flatpak preinstall -y</command> (or its GUI equivalent) on system startup, which then does the actual installation.
        </para>

        <para>
          This system allows the OS vendor to define the list of flatpaks that are installed together with the OS, and also makes it possible for the OS vendor to make changes to the list in the future, which is then applied once <command>flatpak preinstall</command> is run next time.

          Users can opt out of preinstalled flatpaks by simply uninstalling them, at which point they won't get automatically reinstalled again.
        </para>
    </refsect1>

    <refsect1>
        <title>File format</title>

        <para>
            The .preinstall file is using the same .ini file format that is used for systemd unit files or application .desktop files.
        </para>

        <refsect2>
            <title>[Flatpak Preinstall NAME]</title>

            <para>
                The NAME is the fully qualified name of the runtime or application. All the information for a single runtime or application is contained in one [Flatpak Preinstall NAME] group. Multiple groups can be defined in a single file.
            </para>
            <para>
                The following keys can be present in this group:
            </para>
            <variablelist>
                <varlistentry>
                    <term><option>Install</option> (boolean)</term>
                    <listitem><para>
                        Whether this group should be installed. If this key is not specified, the group will be installed.
                    </para></listitem>
                </varlistentry>
                <varlistentry>
                    <term><option>Branch</option> (string)</term>
                    <listitem><para>
                        The name of the branch from which to install the application or runtime. If this key is not specified, the "master" branch is used.
                    </para></listitem>
                </varlistentry>
                <varlistentry>
                    <term><option>IsRuntime</option> (boolean)</term>
                    <listitem><para>
                        Whether this group refers to a runtime. If this key is not specified, the group is assumed to refer to an application.
                    </para></listitem>
                </varlistentry>
                <varlistentry>
                    <term><option>CollectionID</option> (string)</term>
                    <listitem><para>
                        The collection ID of the remote to use, if it has one.
                    </para></listitem>
                </varlistentry>
            </variablelist>
        </refsect2>
    </refsect1>

    <refsect1>
        <title>Example</title>
<programlisting>
[Flatpak Preinstall org.gnome.Loupe]
Branch=stable
IsRuntime=false
</programlisting>
    </refsect1>

    <refsect1>
        <title>Options</title>

        <para>The following options are understood:</para>

        <variablelist>
            <varlistentry>
                <term><option>-h</option></term>
                <term><option>--help</option></term>

                <listitem><para>
                    Show help options and exit.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--reinstall</option></term>

                <listitem><para>
                  Uninstall first if already installed.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>-u</option></term>
                <term><option>--user</option></term>

                <listitem><para>
                    Install the application or runtime in a per-user installation.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--system</option></term>

                <listitem><para>
                    Install the application or runtime in the default system-wide installation.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--installation=NAME</option></term>

                <listitem><para>
                    Install the application or runtime in a system-wide installation
                    specified by <arg choice="plain">NAME</arg> among those defined in
                    <filename>/etc/flatpak/installations.d/</filename>. Using
                    <option>--installation=default</option> is equivalent to using
                    <option>--system</option>.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--no-deploy</option></term>

                <listitem><para>
                    Download the latest version, but don't deploy it.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--no-pull</option></term>

                <listitem><para>
                    Don't download the latest version, deploy whatever is locally available.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--no-related</option></term>

                <listitem><para>
                    Don't download related extensions, such as the locale data.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--no-deps</option></term>

                <listitem><para>
                    Don't verify runtime dependencies when installing.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--sideload-repo=PATH</option></term>

                <listitem><para>
                    Adds an extra local ostree repo as a source for installation. This is equivalent
                    to using the <filename>sideload-repos</filename> directories (see
                    <citerefentry><refentrytitle>flatpak</refentrytitle><manvolnum>1</manvolnum></citerefentry>),
                    but can be done on a per-command basis. Any path added here is used in addition
                    to ones in those directories.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--include-sdk</option></term>

                <listitem><para>
                  For each app being installed, also installs the SDK that was used to build it.
                  Implies <option>--or-update</option>; incompatible with <option>--no-deps</option>.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--include-debug</option></term>

                <listitem><para>
                  For each ref being installed, as well as all dependencies, also installs its
                  debug info. Implies <option>--or-update</option>; incompatible with
                  <option>--no-deps</option>.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>-y</option></term>
                <term><option>--assumeyes</option></term>
                <listitem><para>
                    Automatically answer yes to all questions (or pick the most prioritized answer). This is useful for automation.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--noninteractive</option></term>
                <listitem><para>
                    Produce minimal output and avoid most questions. This is suitable for use in
                    non-interactive situations, e.g. in a build script.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>-v</option></term>
                <term><option>--verbose</option></term>

                <listitem><para>
                    Print debug information during command processing.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--ostree-verbose</option></term>

                <listitem><para>
                    Print OSTree debug information during command processing.
                </para></listitem>
            </varlistentry>
        </variablelist>
    </refsect1>

    <refsect1>
        <title>Examples</title>

        <para>
            <command>$ flatpak preinstall</command>
        </para>
    </refsect1>

    <refsect1>
        <title>See also</title>

        <para>
            <citerefentry><refentrytitle>flatpak</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
        </para>
    </refsect1>

</refentry>

===== ./doc/flatpak-spawn.xml =====
<?xml version='1.0'?> <!--*-nxml-*-->
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
    "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">

<refentry id="flatpak-spawn">

    <refentryinfo>
        <title>flatpak spawn</title>
        <productname>flatpak</productname>

        <authorgroup>
            <author>
                <contrib>Developer</contrib>
                <firstname>Alexander</firstname>
                <surname>Larsson</surname>
                <email>alexl@redhat.com</email>
            </author>
        </authorgroup>
    </refentryinfo>

    <refmeta>
        <refentrytitle>flatpak spawn</refentrytitle>
        <manvolnum>1</manvolnum>
    </refmeta>

    <refnamediv>
        <refname>flatpak-spawn</refname>
        <refpurpose>Run commands in a sandbox</refpurpose>
    </refnamediv>

    <refsynopsisdiv>
            <cmdsynopsis>
                <command>flatpak-spawn</command>
                <arg choice="opt" rep="repeat">OPTION</arg>
                <arg choice="plain">COMMAND</arg>
                <arg choice="opt" rep="repeat">ARGUMENT</arg>
            </cmdsynopsis>
    </refsynopsisdiv>

    <refsect1>
        <title>Description</title>

        <para>
            Unlike other flatpak commands, <command>flatpak-spawn</command> is available
            to applications inside the sandbox. It runs <arg choice="plain">COMMAND</arg>
            outside the sandbox: either in another sandbox, or on the host.
        </para>

        <para>
            When called without <option>--host</option>, <command>flatpak-spawn</command>
            uses the Flatpak portal to create a copy of the sandbox it was called from,
            optionally using tighter permissions and optionally the latest version of the
            app and runtime (see <option>--latest-version</option>).
        </para>

    </refsect1>

    <refsect1>
        <title>Options</title>

        <para>The following options are understood:</para>

        <variablelist>
            <varlistentry>
                <term><option>-h</option></term>
                <term><option>--help</option></term>

                <listitem><para>
                    Show help options and exit.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>-v</option></term>
                <term><option>--verbose</option></term>

                <listitem><para>
                    Print debug information
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--forward-fd=FD</option></term>

                <listitem><para>
                    Forward a file descriptor
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--clear-env</option></term>

                <listitem><para>
                    Run with a clean environment
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--watch-bus</option></term>

                <listitem><para>
                    Make the spawned command exit when <command>flatpak-spawn</command>
                    itself exits; notably, this occurs when its connection to the
                    session bus is closed.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--env=VAR=VALUE</option></term>

                <listitem><para>
                    Set an environment variable
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--latest-version</option></term>

                <listitem><para>
                  Use the latest version of the refs that are used to set up the sandbox
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--no-network</option></term>

                <listitem><para>
                    Run without network access
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--sandbox</option></term>

                <listitem><para>
                  Run fully sandboxed. See the documentation for the <option>--sandbox</option>
                  option in <citerefentry><refentrytitle>flatpak-run</refentrytitle><manvolnum>1</manvolnum></citerefentry>
                </para><para>
                  See the <option>--sandbox-expose</option> and
                  <option>--sandbox-expose-ro</option> options for selective file access.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--sandbox-expose=NAME</option></term>

                <listitem><para>
                  Expose read-write access to a file in the sandbox.
                </para><para>
                  Note that absolute paths or subdirectories are not allowed.
                  The files must be in the <filename>sandbox</filename> subdirectory of
                  the instance directory (i.e. <filename>~/.var/app/$APP_ID/sandbox</filename>).
                </para><para>
                  This option is useful in combination with <option>--sandbox</option> (otherwise the
                  instance directory is accessible anyway).
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--sandbox-expose-ro=NAME</option></term>

                <listitem><para>
                  Expose readonly access to a file in the sandbox.
                </para><para>
                  Note that absolute paths or subdirectories are not allowed.
                  The files must be in the <filename>sandbox</filename> subdirectory of
                  the instance directory (i.e. <filename>~/.var/app/$APP_ID/sandbox</filename>).
                </para><para>
                  This option is useful in combination with <option>--sandbox</option> (otherwise the
                  instance directory is accessible anyway).
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--host</option></term>

                <listitem><para>
                  Run the command unsandboxed on the host. This requires access to
                  the org.freedesktop.Flatpak D-Bus interface.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--directory=DIR</option></term>

                <listitem><para>
                  The working directory in which to run the command.
                </para><para>
                  Note that the given directory must exist in the sandbox or, when used in conjunction
                  with <option>--host</option>, on the host.
                </para></listitem>
            </varlistentry>

        </variablelist>
    </refsect1>

    <refsect1>
        <title>Examples</title>

        <para>
            <command>$ flatpak-spawn ls /var/run</command>
        </para>

    </refsect1>

    <refsect1>
        <title>See also</title>

        <para>
            <citerefentry><refentrytitle>flatpak</refentrytitle><manvolnum>1</manvolnum></citerefentry>
        </para>

    </refsect1>

</refentry>

===== ./doc/flatpak-build-export.xml =====
<?xml version='1.0'?> <!--*-nxml-*-->
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
    "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">

<refentry id="flatpak-build-export">

    <refentryinfo>
        <title>flatpak build-export</title>
        <productname>flatpak</productname>

        <authorgroup>
            <author>
                <contrib>Developer</contrib>
                <firstname>Alexander</firstname>
                <surname>Larsson</surname>
                <email>alexl@redhat.com</email>
            </author>
        </authorgroup>
    </refentryinfo>

    <refmeta>
        <refentrytitle>flatpak build-export</refentrytitle>
        <manvolnum>1</manvolnum>
    </refmeta>

    <refnamediv>
        <refname>flatpak-build-export</refname>
        <refpurpose>Create a repository from a build directory</refpurpose>
    </refnamediv>

    <refsynopsisdiv>
            <cmdsynopsis>
                <command>flatpak build-export</command>
                <arg choice="opt" rep="repeat">OPTION</arg>
                <arg choice="plain">LOCATION</arg>
                <arg choice="plain">DIRECTORY</arg>
                <arg choice="opt">BRANCH</arg>
            </cmdsynopsis>
    </refsynopsisdiv>

    <refsect1>
        <title>Description</title>

        <para>
            Creates or updates a repository with an application build.
            <arg choice="plain">LOCATION</arg> is the location of the
            repository. <arg choice="plain">DIRECTORY</arg> must be a
            finalized build directory. If <arg choice="plain">BRANCH</arg>
            is not specified, it is assumed to be "master".
        </para>
        <para>
            If <arg choice="plain">LOCATION</arg> exists, it is assumed to
            be an OSTree repository, otherwise a new OSTree repository is
            created at this location. The repository can be inspected with
            the <command>ostree</command> tool.
        </para>
        <para>
            The contents of <arg choice="plain">DIRECTORY</arg> are committed
            on the branch with name <literal>app/APPNAME/ARCH/BRANCH</literal>,
            where ARCH is the architecture of the runtime that the application
            is using. A commit filter is used to enforce that only the contents
            of the <filename>files/</filename> and <filename>export/</filename>
            subdirectories and the <filename>metadata</filename> file are included
            in the commit, anything else is ignored.
        </para>
        <para>
            When exporting a flatpak to be published to the internet,
            <option>--collection-id=COLLECTION-ID</option> should be specified
            as a globally unique reverse DNS value to identify the collection of
            flatpaks this will be added to. Setting a globally unique collection
            ID allows the apps in the repository to be shared over peer to peer
            systems without needing further configuration.
        </para>
        <para>
            The build-update-repo command should be used to update repository
            metadata whenever application builds are added to a repository.
        </para>
    </refsect1>

    <refsect1>
        <title>Options</title>

        <para>The following options are understood:</para>

        <variablelist>
            <varlistentry>
                <term><option>-h</option></term>
                <term><option>--help</option></term>

                <listitem><para>
                    Show help options and exit.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>-s</option></term>
                <term><option>--subject=SUBJECT</option></term>

                <listitem><para>
                    One line subject for the commit message.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>-b</option></term>
                <term><option>--body=BODY</option></term>

                <listitem><para>
                    Full description for the commit message.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--collection-id=COLLECTION-ID</option></term>

                <listitem><para>
                    Set as the collection ID of the repository. Setting a globally
                    unique collection ID allows the apps in the repository to be shared over
                    peer to peer systems without needing further configuration.
                    If exporting to an existing repository, the collection ID
                    must match the existing configured collection ID for that
                    repository.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--subset=SUBSET</option></term>

                <listitem><para>
                    Mark the commit to be included in the named subset. This will cause the commit
                    to be put in the named subset summary (in addition to the main one), allowing
                    users to see only this subset instead of the whole repo.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--arch=ARCH</option></term>

                <listitem><para>
                    Specify the architecture component of the branch to export. Only
                    host compatible architectures can be specified; see
                    <command>flatpak --supported-arches</command> for valid values.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--exclude=PATTERN</option></term>

                <listitem><para>
                    Exclude files matching <arg choice="plain">PATTERN</arg> from the commit.
                    This option can be used multiple times.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--include=PATTERN</option></term>

                <listitem><para>
                    Don't exclude files matching <arg choice="plain">PATTERN</arg> from the commit, even if they match the <option>--exclude</option> patterns.
                    This option can be used multiple times.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--metadata=FILENAME</option></term>

                <listitem><para>
                  Use the specified filename as metadata in the exported app instead of
                  the default file (called <filename>metadata</filename>). This is useful
                  if you want to commit multiple things from a single build tree, typically
                  used in combination with <option>--files</option> and <option>--exclude</option>.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--files=SUBDIR</option></term>

                <listitem><para>
                  Use the files in the specified subdirectory as the file contents, rather
                  than the regular <filename>files</filename> directory.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--timestamp=DATE</option></term>

                <listitem><para>
                    Use the specified ISO 8601 formatted date or NOW, for the current time, in the commit metadata and, if <option>--update-appstream</option> is used, the appstream data.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--end-of-life=REASON</option></term>

                <listitem><para>
                    Mark the build as end-of-life. REASON is a message that may be shown to users
                    installing this build.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--end-of-life-rebase=ID</option></term>

                <listitem><para>
                    Mark the build as end-of-life. Unlike <option>--end-of-life</option>,
                    this one takes an ID that supersedes the current one. By the user's
                    request, the application data may be preserved for the new application.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--disable-fsync</option></term>

                <listitem><para>
                  Don't fsync when writing to the repository. This can result in data loss in exceptional situations, but can improve performance when
                  working with temporary or test repositories.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--update-appstream</option></term>

                <listitem><para>
                    Update the appstream branch after the build.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--no-update-summary</option></term>

                <listitem><para>
                    Don't update the summary file after the new commit is added. This means
                    the repository will not be useful for serving over http until build-update-repo
                    has been run. This is useful is you want to do multiple repo operations before
                    finally updating the summary.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--gpg-sign=KEYID</option></term>

                <listitem><para>
                    Sign the commit with this GPG key.
                    This option can be used multiple times.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--gpg-homedir=PATH</option></term>

                <listitem><para>
                    GPG Homedir to use when looking for keyrings
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>-r</option></term>
                <term><option>--runtime</option></term>

                <listitem><para>
                    Export a runtime instead of an app (this uses the usr subdir as files).
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>-v</option></term>
                <term><option>--verbose</option></term>

                <listitem><para>
                    Print debug information during command processing.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--ostree-verbose</option></term>

                <listitem><para>
                    Print OSTree debug information during command processing.
                </para></listitem>
            </varlistentry>
        </variablelist>
    </refsect1>

    <refsect1>
        <title>Examples</title>

        <para>
            <command>$ flatpak build-export ~/repos/gnome-calculator/ ~/build/gnome-calculator/ org.gnome.Calculator</command>
        </para>
<programlisting>
Commit: 9d0044ea480297114d03aec85c3d7ae3779438f9d2cb69d717fb54237acacb8c
Metadata Total: 605
Metadata Written: 5
Content Total: 1174
Content Written: 1
Content Bytes Written: 305
</programlisting>

    </refsect1>

    <refsect1>
        <title>See also</title>

        <para>
            <citerefentry><refentrytitle>ostree</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
            <citerefentry><refentrytitle>flatpak</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
            <citerefentry><refentrytitle>flatpak-build-init</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
            <citerefentry><refentrytitle>flatpak-build</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
            <citerefentry><refentrytitle>flatpak-build-finish</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
            <citerefentry><refentrytitle>flatpak-build-sign</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
            <citerefentry><refentrytitle>flatpak-build-update-repo</refentrytitle><manvolnum>1</manvolnum></citerefentry>
        </para>

    </refsect1>

</refentry>

===== ./doc/flatpak-build-commit-from.xml =====
<?xml version='1.0'?> <!--*-nxml-*-->
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
    "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">

<refentry id="flatpak-build-commit-from">

    <refentryinfo>
        <title>flatpak build-commit-from</title>
        <productname>flatpak</productname>

        <authorgroup>
            <author>
                <contrib>Developer</contrib>
                <firstname>Alexander</firstname>
                <surname>Larsson</surname>
                <email>alexl@redhat.com</email>
            </author>
        </authorgroup>
    </refentryinfo>

    <refmeta>
        <refentrytitle>flatpak build-commit-from</refentrytitle>
        <manvolnum>1</manvolnum>
    </refmeta>

    <refnamediv>
        <refname>flatpak-build-commit-from</refname>
        <refpurpose>Create new commits based on existing one (possibly from another repository)</refpurpose>
    </refnamediv>

    <refsynopsisdiv>
            <cmdsynopsis>
                <command>flatpak build-commit-from</command>
                <arg choice="opt" rep="repeat">OPTION</arg>
                <arg choice="plain">DST-REPO</arg>
                <arg choice="plain" rep="repeat">DST-REF</arg>
            </cmdsynopsis>
    </refsynopsisdiv>

    <refsect1>
        <title>Description</title>

        <para>
            Creates new commits on the <arg choice="plain">DST-REF</arg>
            branch in the <arg choice="plain">DST-REPO</arg>, with the
            contents (and most of the metadata) taken from another
            branch, either from another repo, or from another branch in
            the same repository.
        </para>
        <para>
            The collection ID set on
            <arg choice="plain">DST-REPO</arg> (if set) will be used for the
            newly created commits.
        </para>
        <para>
            This command is very useful when you want to maintain a branch
            with a clean history that has no unsigned or broken commits.
            For instance, you can import the head from a different repository
            from an automatic builder when you've verified that it worked.
            The new commit will have no parents or signatures from the
            autobuilder, and can be properly signed with the official
            key.
        </para>
        <para>
            Any deltas that affect the original commit and that match parent
            commits in the destination repository are copied and rewritten
            for the new commit id.
        </para>
    </refsect1>

    <refsect1>
        <title>Options</title>

        <para>The following options are understood:</para>

        <variablelist>
            <varlistentry>
                <term><option>-h</option></term>
                <term><option>--help</option></term>

                <listitem><para>
                    Show help options and exit.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--src-repo=SRC-REPO</option></term>

                <listitem><para>
                    The (local) repository to pull the source branch from. Defaults to the
                    destination repository.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--src-ref=SRC-REF</option></term>

                <listitem><para>
                    The branch to use as the source for the new commit. Defaults to the same
                    as the destination ref, which is useful only if a different source repo
                    has been specified.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--extra-collection-id=COLLECTION-ID</option></term>

                <listitem><para>
                    Add an extra collection-ref binding for this collection, in addition to whatever
                    would normally be added due to the destination repository collection id.
                    This option can be used multiple times.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--subset=SUBSET</option></term>

                <listitem><para>
                    Mark the commit to be included in the named subset. This will cause the commit
                    to be put in the named subset summary (in addition to the main one), allowing
                    users to see only this subset instead of the whole repo.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--untrusted</option></term>

                <listitem><para>
                    The source repository is not trusted, all objects are copied (not hardlinked) and
                    all checksums are verified.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>-s</option></term>
                <term><option>--subject=SUBJECT</option></term>

                <listitem><para>
                    One line subject for the commit message. If not specified, will be taken from the source commit.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>-b</option></term>
                <term><option>--body=BODY</option></term>

                <listitem><para>
                    Full description for the commit message. If not specified, will be taken from the source commit.
                </para></listitem>
            </varlistentry>


            <varlistentry>
                <term><option>--update-appstream</option></term>

                <listitem><para>
                    Update the appstream branch after the build.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--no-update-summary</option></term>

                <listitem><para>
                    Don't update the summary file after the new commit is added. This means
                    the repository will not be useful for serving over http until build-update-repo
                    has been run. This is useful is you want to do multiple repo operations before
                    finally updating the summary.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--force</option></term>

                <listitem><para>
                    Create new commit even if the content didn't change from the existing branch head.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--disable-fsync</option></term>

                <listitem><para>
                  Don't fsync when writing to the repository. This can result in data loss in exceptional situations, but can improve performance when
                  working with temporary or test repositories.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--gpg-sign=KEYID</option></term>

                <listitem><para>
                    Sign the commit with this GPG key.
                    This option can be used multiple times.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--gpg-homedir=PATH</option></term>

                <listitem><para>
                    GPG Homedir to use when looking for keyrings
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--end-of-life=REASON</option></term>

                <listitem><para>
                    Mark build as end-of-life
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--end-of-life-rebase=OLDID=NEWID</option></term>

                <listitem><para>
                    Mark new refs as end-of-life. Unlike <option>--end-of-life</option>,
                    this one takes an ID that supersedes the current one. By the user's
                    request, the application data may be preserved for the new application.
                    Note, this is actually a prefix match, so if you say org.the.app=org.new.app,
                    then something like org.the.app.Locale will be rebased to org.new.app.Locale.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--timestamp=TIMESTAMP</option></term>

                <listitem><para>
                    Override the timestamp of the commit. Use an ISO 8601 formatted
                    date, or NOW for the current time
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--disable-fsync</option></term>

                <listitem><para>
                    Don't fsync when writing to the repository. This can result in data loss in exceptional situations, but can improve performance when
                    working with temporary or test repositories.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>-v</option></term>
                <term><option>--verbose</option></term>

                <listitem><para>
                    Print debug information during command processing.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--ostree-verbose</option></term>

                <listitem><para>
                    Print OSTree debug information during command processing.
                </para></listitem>
            </varlistentry>
        </variablelist>
    </refsect1>

    <refsect1>
        <title>Examples</title>

        <para>
           To revert a commit to the commit before:
        </para>
        <para>
          <command>$ flatpak build-commit-from --timestamp=NOW --src-ref=app/org.gnome.gedit/x86_64/master^ repo app/org.gnome.gedit/x86_64/master</command>
        </para>

    </refsect1>

    <refsect1>
        <title>See also</title>

        <para>
            <citerefentry><refentrytitle>ostree</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
            <citerefentry><refentrytitle>flatpak</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
            <citerefentry><refentrytitle>flatpak-build-init</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
            <citerefentry><refentrytitle>flatpak-build</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
            <citerefentry><refentrytitle>flatpak-build-finish</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
            <citerefentry><refentrytitle>flatpak-build-sign</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
            <citerefentry><refentrytitle>flatpak-build-update-repo</refentrytitle><manvolnum>1</manvolnum></citerefentry>
        </para>

    </refsect1>

</refentry>

===== ./doc/flatpak-info.xml =====
<?xml version='1.0'?> <!--*-nxml-*-->
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
    "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">

<refentry id="flatpak-info">

    <refentryinfo>
        <title>flatpak info</title>
        <productname>flatpak</productname>

        <authorgroup>
            <author>
                <contrib>Developer</contrib>
                <firstname>Alexander</firstname>
                <surname>Larsson</surname>
                <email>alexl@redhat.com</email>
            </author>
        </authorgroup>
    </refentryinfo>

    <refmeta>
        <refentrytitle>flatpak info</refentrytitle>
        <manvolnum>1</manvolnum>
    </refmeta>

    <refnamediv>
        <refname>flatpak-info</refname>
        <refpurpose>Show information about an installed application or runtime</refpurpose>
    </refnamediv>

    <refsynopsisdiv>
            <cmdsynopsis>
                <command>flatpak info</command>
                <arg choice="opt" rep="repeat">OPTION</arg>
                <arg choice="plain">NAME</arg>
                <arg choice="opt">BRANCH</arg>
            </cmdsynopsis>
    </refsynopsisdiv>

    <refsect1>
        <title>Description</title>

        <para>
            Show info about an installed application or runtime.
        </para>
        <para>
            By default, the output is formatted in a friendly format.
            If you specify any of the <option>--show-…</option> or
            <option>--file-access</option> options, the output is instead
            formatted in a machine-readable format.
        </para>
        <para>
            By default, both per-user and system-wide installations are queried.
            Use the <option>--user</option>, <option>--system</option>
            or <option>--installation</option> options to change this.
        </para>

    </refsect1>

    <refsect1>
        <title>Options</title>

        <para>The following options are understood:</para>

        <variablelist>
            <varlistentry>
                <term><option>-h</option></term>
                <term><option>--help</option></term>

                <listitem><para>
                    Show help options and exit.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>-u</option></term>
                <term><option>--user</option></term>

                <listitem><para>
                    Query per-user installations.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--system</option></term>

                <listitem><para>
                    Query the default system-wide installation.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--installation=NAME</option></term>

                <listitem><para>
                    Query a system-wide installation by <arg choice="plain">NAME</arg> among
                    those defined in <filename>/etc/flatpak/installations.d/</filename>.
                    Using <option>--installation=default</option> is equivalent to using
                    <option>--system</option>.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--arch=ARCH</option></term>

                <listitem><para>
                    Query for this architecture. See <command>flatpak --supported-arches</command>
                    for architectures supported by the host.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>-r</option></term>
                <term><option>--show-ref</option></term>

                <listitem><para>
                    Show the installed ref.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>-o</option></term>
                <term><option>--show-origin</option></term>

                <listitem><para>
                    Show the remote the ref is installed from.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>-c</option></term>
                <term><option>--show-commit</option></term>

                <listitem><para>
                    Show the installed commit id.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>-s</option></term>
                <term><option>--show-size</option></term>

                <listitem><para>
                    Show the installed size.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>-m</option></term>
                <term><option>--show-metadata</option></term>

                <listitem><para>
                    Show the metadata.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--show-runtime</option></term>

                <listitem><para>
                    Show the runtime.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--show-sdk</option></term>

                <listitem><para>
                    Show the SDK.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>-M</option></term>
                <term><option>--show-permissions</option></term>

                <listitem><para>
                    Show the permissions.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--file-access=PATH</option></term>

                <listitem><para>
                    Show the level of access to the given path.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>-e</option></term>
                <term><option>--show-extensions</option></term>

                <listitem><para>
                    Show the matching extensions.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>-l</option></term>
                <term><option>--show-location</option></term>

                <listitem><para>
                    Show the on-disk location of the app or runtime. See the
                    examples below.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>-v</option></term>
                <term><option>--verbose</option></term>

                <listitem><para>
                    Print debug information during command processing.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--ostree-verbose</option></term>

                <listitem><para>
                    Print OSTree debug information during command processing.
                </para></listitem>
            </varlistentry>
        </variablelist>
    </refsect1>

    <refsect1>
        <title>Examples</title>

        <para>
            <command>$ flatpak info org.gnome.Builder//master</command>
        </para>
        <para>
            <command>$ tree `flatpak info -l org.gnome.Builder//master`/files</command>
        </para>

    </refsect1>

    <refsect1>
        <title>See also</title>

        <para>
            <citerefentry><refentrytitle>flatpak</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
            <citerefentry><refentrytitle>flatpak-install</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
            <citerefentry><refentrytitle>flatpak-update</refentrytitle><manvolnum>1</manvolnum></citerefentry>
        </para>

    </refsect1>

</refentry>

===== ./doc/flatpak-build-bundle.xml =====
<?xml version='1.0'?> <!--*-nxml-*-->
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
    "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">

<refentry id="flatpak-build-bundle">

    <refentryinfo>
        <title>flatpak build-bundle</title>
        <productname>flatpak</productname>

        <authorgroup>
            <author>
                <contrib>Developer</contrib>
                <firstname>Alexander</firstname>
                <surname>Larsson</surname>
                <email>alexl@redhat.com</email>
            </author>
        </authorgroup>
    </refentryinfo>

    <refmeta>
        <refentrytitle>flatpak build-bundle</refentrytitle>
        <manvolnum>1</manvolnum>
    </refmeta>

    <refnamediv>
        <refname>flatpak-build-bundle</refname>
        <refpurpose>Create a single-file bundle from a local repository</refpurpose>
    </refnamediv>

    <refsynopsisdiv>
            <cmdsynopsis>
                <command>flatpak build-bundle</command>
                <arg choice="opt" rep="repeat">OPTION</arg>
                <arg choice="plain">LOCATION</arg>
                <arg choice="plain">FILENAME</arg>
                <arg choice="plain">NAME</arg>
                <arg choice="opt">BRANCH</arg>
            </cmdsynopsis>
    </refsynopsisdiv>

    <refsect1>
        <title>Description</title>

        <para>
            Creates a single-file named <arg choice="plain">FILENAME</arg>
            for the application (or runtime) named <arg choice="plain">NAME</arg>
            in the repository at <arg choice="plain">LOCATION</arg>. If
            a <arg choice="plain">BRANCH</arg> is specified, this branch of
            the application is used.
        </para>
        <para>
            The collection ID set on the repository at
            <arg choice="plain">LOCATION</arg> (if set) will be used for the
            bundle.
        </para>
        <para>
            Unless <option>--oci</option> is used, the format of the bundle file is
            that of an ostree static delta (against an empty base) with some flatpak
            specific metadata for the application icons and appdata.
        </para>
    </refsect1>

    <refsect1>
        <title>Options</title>

        <para>The following options are understood:</para>

        <variablelist>
            <varlistentry>
                <term><option>-h</option></term>
                <term><option>--help</option></term>

                <listitem><para>
                    Show help options and exit.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--runtime</option></term>

                <listitem><para>
                    Export a runtime instead of an application.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--arch=ARCH</option></term>

                <listitem><para>
                    The arch to create a bundle for. See <command>flatpak --supported-arches</command>
                    for architectures supported by the host.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--repo-url=URL</option></term>

                <listitem><para>
                    The URL for the repository from which the
                    application can be updated. Installing the
                    bundle will automatically configure a remote
                    for this URL.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--runtime-repo=URL</option></term>

                <listitem><para>
                  The URL for a <filename>.flatpakrepo</filename> file that contains
                  the information about the repository that supplies
                  the runtimes required by the app.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--gpg-keys=FILE</option></term>

                <listitem><para>
                    Add the GPG key from <arg choice="plain">FILE</arg> (use - for stdin).
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--gpg-homedir=PATH</option></term>

                <listitem><para>
                    GPG Homedir to use when looking for keyrings.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--from-commit=COMMIT</option></term>

                <listitem><para>
                    The OSTree commit to create a delta bundle from.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--oci</option></term>

                <listitem><para>
                    Export to an OCI image instead of a Flatpak bundle.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--oci-layer-compress=gzip|zstd</option></term>

                <listitem><para>
                  Choose how to compress the layers in OCI images. gzip (the
                  default) is universally supported, but zstd compresses faster
                  and results in smaller images. As of 2023, zstd support is
                  present in most major registries.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>-v</option></term>
                <term><option>--verbose</option></term>

                <listitem><para>
                    Print debug information during command processing.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--ostree-verbose</option></term>

                <listitem><para>
                    Print OSTree debug information during command processing.
                </para></listitem>
            </varlistentry>

        </variablelist>
    </refsect1>

    <refsect1>
        <title>Examples</title>

        <para>
            <command>$ flatpak build-bundle /var/lib/flatpak/repo gnome-calculator.flatpak org.gnome.Calculator stable</command>
        </para>
        <para>
            <command>$ flatpak build-bundle ~/.local/share/flatpak/repo gnome-calculator.flatpak org.gnome.Calculator stable</command>
        </para>

    </refsect1>

    <refsect1>
        <title>See also</title>

        <para>
            <citerefentry><refentrytitle>ostree</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
            <citerefentry><refentrytitle>flatpak</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
            <citerefentry><refentrytitle>flatpak-build-init</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
            <citerefentry><refentrytitle>flatpak-build</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
            <citerefentry><refentrytitle>flatpak-build-finish</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
            <citerefentry><refentrytitle>flatpak-build-import-bundle</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
            <citerefentry><refentrytitle>flatpak-build-update-repo</refentrytitle><manvolnum>1</manvolnum></citerefentry>
        </para>

    </refsect1>

</refentry>

===== ./doc/flatpak-search.xml =====
<?xml version='1.0'?> <!--*-nxml-*-->
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
    "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">

<refentry id="flatpak-search">

    <refentryinfo>
        <title>flatpak search</title>
        <productname>flatpak</productname>

        <authorgroup>
            <author>
                <contrib>Developer</contrib>
                <firstname>Patrick</firstname>
                <surname>Griffis</surname>
                <email>tingping@tingping.se</email>
            </author>
        </authorgroup>
    </refentryinfo>

    <refmeta>
        <refentrytitle>flatpak search</refentrytitle>
        <manvolnum>1</manvolnum>
    </refmeta>

    <refnamediv>
        <refname>flatpak-search</refname>
        <refpurpose>Search for applications and runtimes</refpurpose>
    </refnamediv>

    <refsynopsisdiv>
            <cmdsynopsis>
                <command>flatpak search</command>
                <arg choice="plain">TEXT</arg>
            </cmdsynopsis>
    </refsynopsisdiv>

    <refsect1>
        <title>Description</title>

        <para>
            Searches for applications and runtimes matching
            <arg choice="plain">TEXT</arg>. Note that this uses appstream data
            that can be updated with the <command>flatpak update</command> command.
            The appstream data is updated automatically only if it's at least a day old.
        </para>
    </refsect1>

    <refsect1>
        <title>Options</title>

        <para>The following options are understood:</para>

        <variablelist>
            <varlistentry>
                <term><option>-u</option></term>
                <term><option>--user</option></term>

                <listitem><para>
                    Only search through remotes in the per-user installation.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--system</option></term>

                <listitem><para>
                    Only search through remotes in the default system-wide installation.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--installation=NAME</option></term>

                <listitem><para>
                    Show a system-wide installation by <arg choice="plain">NAME</arg> among
                    those defined in <filename>/etc/flatpak/installations.d/</filename>.
                    Using <option>--installation=default</option> is equivalent to using
                    <option>--system</option>.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>-h</option></term>
                <term><option>--help</option></term>

                <listitem><para>
                    Show help options and exit.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>-v</option></term>
                <term><option>--verbose</option></term>

                <listitem><para>
                    Print debug information during command processing.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--ostree-verbose</option></term>

                <listitem><para>
                    Print OSTree debug information during command processing.
                </para></listitem>
            </varlistentry>

           <varlistentry>
                <term><option>--columns=FIELD,…</option></term>

                <listitem><para>
                    Specify what information to show about each result. You can
                    list multiple fields, or use this option multiple times.
                </para><para>
                    Append :s[tart], :m[iddle], :e[nd] or :f[ull] to column
                    names to change ellipsization.
                </para></listitem>
            </varlistentry>

        </variablelist>
    </refsect1>

   <refsect1>
        <title>Fields</title>

        <para>The following fields are understood by the <option>--columns</option> option:</para>

        <variablelist>
            <varlistentry>
                <term>name</term>

                <listitem><para>
                    Show the name
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term>description</term>

                <listitem><para>
                    Show the description
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term>application</term>

                <listitem><para>
                    Show the application ID
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term>version</term>

                <listitem><para>
                    Show the version
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term>branch</term>

                <listitem><para>
                    Show the branch
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term>remotes</term>

                <listitem><para>
                    Show the remotes
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term>all</term>

                <listitem><para>
                    Show all columns
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term>help</term>

                <listitem><para>
                    Show the list of available columns
                </para></listitem>
            </varlistentry>
        </variablelist>

        <para>
          Note that field names can be abbreviated to a unique prefix.
        </para>

    </refsect1>

    <refsect1>
        <title>See also</title>

            <para>
                <citerefentry><refentrytitle>flatpak</refentrytitle><manvolnum>1</manvolnum></citerefentry>
            </para>
    </refsect1>

</refentry>

===== ./doc/flatpak-permission-reset.xml =====
<?xml version='1.0'?> <!--*-nxml-*-->
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
    "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">

<refentry id="flatpak-permission-reset">

    <refentryinfo>
        <title>flatpak permission-reset</title>
        <productname>flatpak</productname>

        <authorgroup>
            <author>
                <contrib>Developer</contrib>
                <firstname>Matthias</firstname>
                <surname>Clasen</surname>
                <email>mclasen@redhat.com</email>
            </author>
        </authorgroup>
    </refentryinfo>

    <refmeta>
        <refentrytitle>flatpak permission-reset</refentrytitle>
        <manvolnum>1</manvolnum>
    </refmeta>

    <refnamediv>
        <refname>flatpak-permission-reset</refname>
        <refpurpose>Reset permissions</refpurpose>
    </refnamediv>

    <refsynopsisdiv>
            <cmdsynopsis>
                <command>flatpak permission-reset</command>
                <arg choice="opt" rep="repeat">OPTION</arg>
                <arg choice="plain">APP_ID</arg>
            </cmdsynopsis>
            <cmdsynopsis>
                <command>flatpak permission-reset</command>
                <arg choice="opt" rep="repeat">OPTION</arg>
                <arg choice="plain">--all</arg>
            </cmdsynopsis>
    </refsynopsisdiv>

    <refsect1>
        <title>Description</title>

        <para>
          Removes all permissions for the given app from the Flatpak
          permission store.
        </para>

        <para>
          The permission store is used by portals.
          Each portal generally has its own table in the permission
          store, and the format of the table entries is specific to
          each portal.
        </para>

    </refsect1>

    <refsect1>
        <title>Options</title>

        <para>The following options are understood:</para>

        <variablelist>
            <varlistentry>
                <term><option>--all</option></term>

                <listitem><para>
                    Remove permissions for all applications.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>-h</option></term>
                <term><option>--help</option></term>

                <listitem><para>
                    Show help options and exit.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>-v</option></term>
                <term><option>--verbose</option></term>

                <listitem><para>
                    Print debug information during command processing.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--ostree-verbose</option></term>

                <listitem><para>
                    Print OSTree debug information during command processing.
                </para></listitem>
            </varlistentry>
        </variablelist>
    </refsect1>

    <refsect1>
        <title>See also</title>

        <para>
            <citerefentry><refentrytitle>flatpak</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
            <citerefentry><refentrytitle>flatpak-permissions</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
            <citerefentry><refentrytitle>flatpak-permission-show</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
            <citerefentry><refentrytitle>flatpak-permission-remove</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
            <citerefentry><refentrytitle>flatpak-permission-set</refentrytitle><manvolnum>1</manvolnum></citerefentry>
        </para>

    </refsect1>

</refentry>

===== ./doc/flatpak-document-info.xml =====
<?xml version='1.0'?> <!--*-nxml-*-->
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
    "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">

<refentry id="flatpak-document-info">

    <refentryinfo>
        <title>flatpak document-info</title>
        <productname>flatpak</productname>

        <authorgroup>
            <author>
                <contrib>Developer</contrib>
                <firstname>Alexander</firstname>
                <surname>Larsson</surname>
                <email>alexl@redhat.com</email>
            </author>
        </authorgroup>
    </refentryinfo>

    <refmeta>
        <refentrytitle>flatpak document-info</refentrytitle>
        <manvolnum>1</manvolnum>
    </refmeta>

    <refnamediv>
        <refname>flatpak-document-info</refname>
        <refpurpose>Show information about exported files</refpurpose>
    </refnamediv>

    <refsynopsisdiv>
            <cmdsynopsis>
                <command>flatpak document-info</command>
                <arg choice="opt" rep="repeat">OPTION</arg>
                <arg choice="plain">FILE</arg>
            </cmdsynopsis>
    </refsynopsisdiv>

    <refsect1>
        <title>Description</title>

        <para>
            Shows information about an exported file, such as the
            document id, the fuse path, the original location in the
            filesystem, and the per-application permissions.
        </para>
        <para>
            <arg choice="plain">FILE</arg> can either be a file in the fuse filesystem at <filename>/run/user/$UID/doc/</filename>,
            or a file anywhere else.
        </para>

    </refsect1>

    <refsect1>
        <title>Options</title>

        <para>The following options are understood:</para>

        <variablelist>
            <varlistentry>
                <term><option>-h</option></term>
                <term><option>--help</option></term>

                <listitem><para>
                    Show help options and exit.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>-v</option></term>
                <term><option>--verbose</option></term>

                <listitem><para>
                    Print debug information during command processing.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--ostree-verbose</option></term>

                <listitem><para>
                    Print OSTree debug information during command processing.
                </para></listitem>
            </varlistentry>
        </variablelist>
    </refsect1>

    <refsect1>
        <title>Examples</title>

        <para>
            <command>$ flatpak document-info ~/Sources/gtk/gail-3.0.pc</command>
        </para>
<programlisting>
id: dd32c34a
path: /run/user/1000/doc/dd32c34a/gail-3.0.pc
origin: /home/mclasen/Sources/gtk/gail-3.0.pc
permissions:
        org.gnome.gedit read, write
</programlisting>

    </refsect1>

    <refsect1>
        <title>See also</title>

        <para>
            <citerefentry><refentrytitle>flatpak</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
            <citerefentry><refentrytitle>flatpak-document-export</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
            <citerefentry><refentrytitle>flatpak-document-unexport</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
            <citerefentry><refentrytitle>flatpak-documents</refentrytitle><manvolnum>1</manvolnum></citerefentry>
        </para>

    </refsect1>

</refentry>

===== ./doc/flatpak-build-finish.xml =====
<?xml version='1.0'?> <!--*-nxml-*-->
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
    "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">

<refentry id="flatpak-build-finish">

    <refentryinfo>
        <title>flatpak build-finish</title>
        <productname>flatpak</productname>

        <authorgroup>
            <author>
                <contrib>Developer</contrib>
                <firstname>Alexander</firstname>
                <surname>Larsson</surname>
                <email>alexl@redhat.com</email>
            </author>
        </authorgroup>
    </refentryinfo>

    <refmeta>
        <refentrytitle>flatpak build-finish</refentrytitle>
        <manvolnum>1</manvolnum>
    </refmeta>

    <refnamediv>
        <refname>flatpak-build-finish</refname>
        <refpurpose>Finalize a build directory</refpurpose>
    </refnamediv>

    <refsynopsisdiv>
            <cmdsynopsis>
                <command>flatpak build-finish</command>
                <arg choice="opt" rep="repeat">OPTION</arg>
                <arg choice="plain">DIRECTORY</arg>
            </cmdsynopsis>
    </refsynopsisdiv>

    <refsect1>
        <title>Description</title>

        <para>
            Finalizes a build directory, to prepare it for exporting.
            <arg choice="plain">DIRECTORY</arg> is the name of the directory.
        </para>
        <para>
            The result of this command is that desktop files, icons, D-Bus service
            files, and AppStream metainfo files from the <filename>files</filename>
            subdirectory are copied to a new <filename>export</filename> subdirectory.
            In the <filename>metadata</filename> file, the command key is set in the
            [Application] group, and the supported keys in the [Environment]
            group are set according to the options.
        </para>
        <para>
             As part of finalization you can also specify permissions that the
             app needs, using the various options specified below. Additionally
             during finalization the permissions from the runtime are inherited
             into the app unless you specify <option>--no-inherit-permissions</option>
        </para>
        <para>
            You should review the exported files and the application metadata
            before creating and distributing an application bundle.
        </para>
        <para>
            It is an error to run build-finish on a directory that has not
            been initialized as a build directory, or has already been finalized.
        </para>
    </refsect1>

    <refsect1>
        <title>Options</title>

        <para>The following options are understood:</para>

        <variablelist>
            <varlistentry>
                <term><option>-h</option></term>
                <term><option>--help</option></term>

                <listitem><para>
                    Show help options and exit.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--command=COMMAND</option></term>

                <listitem><para>
                    The command to use. If this option is not specified,
                    the first executable found in <filename>files/bin</filename>
                    is used.
                </para><para>
                    Note that the command is used when the application is run
                    via <command>flatpak run</command>, and does not affect what
                    gets executed when the application is run in other ways,
                    e.g. via the desktop file or D-Bus activation.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--require-version=MAJOR.MINOR.MICRO</option></term>

                <listitem><para>
                    Require this version or later of flatpak to install/update to this build.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--share=SUBSYSTEM</option></term>

                <listitem><para>
                    Share a subsystem with the host session. This updates
                    the [Context] group in the metadata.
                    SUBSYSTEM must be one of: network, ipc.
                    This option can be used multiple times.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--unshare=SUBSYSTEM</option></term>

                <listitem><para>
                    Don't share a subsystem with the host session. This updates
                    the [Context] group in the metadata.
                    SUBSYSTEM must be one of: network, ipc.
                    This option can be used multiple times.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--share-if=SUBSYSTEM:CONDITION</option></term>

                <listitem><para>
                    Share a subsystem with the host session conditionally,
                    only when the specified condition is met at runtime.
                    This updates the [Context] group in the metadata.
                    <arg choice="plain">SUBSYSTEM</arg> must be one of: network, ipc.
                    <arg choice="plain">CONDITION</arg> must be one of:
                    <option>true</option>, <option>false</option>,
                    <option>has-input-device</option>, <option>has-wayland</option>,
                    <option>has-usb-device</option>, <option>has-usb-portal</option>.
                    Conditions can be negated with <literal>!</literal>,
                    for example <option>!has-input-device</option>.
                    This option can be used multiple times.
                    Available since 1.17.
                </para><para>
                    See the Conditional Permissions section in
                    <citerefentry><refentrytitle>flatpak-metadata</refentrytitle><manvolnum>5</manvolnum></citerefentry>
                    for more details.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--socket=SOCKET</option></term>

                <listitem><para>
                    Expose a well-known socket to the application. This updates
                    the [Context] group in the metadata.
                    SOCKET must be one of: x11, wayland, fallback-x11, pulseaudio, system-bus, session-bus,
                    ssh-auth, pcsc, cups, gpg-agent, inherit-wayland-socket.
                    This option can be used multiple times.
                </para><para>
                    The fallback-x11 option makes the X11 socket available only if
                    there is no Wayland socket. This option was introduced in 0.11.3.
                    To support older Flatpak releases, specify both x11 and fallback-x11.
                    The fallback-x11 option takes precedence when both are supported.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--nosocket=SOCKET</option></term>

                <listitem><para>
                    Don't expose a well known socket to the application. This updates
                    the [Context] group in the metadata.
                    SOCKET must be one of: x11, wayland, fallback-x11, pulseaudio, system-bus, session-bus,
                    ssh-auth, pcsc, cups, gpg-agent, inherit-wayland-socket.
                    This option can be used multiple times.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--socket-if=SOCKET:CONDITION</option></term>

                <listitem><para>
                    Expose a well-known socket to the application conditionally,
                    only when the specified condition is met at runtime.
                    This updates the [Context] group in the metadata.
                    SOCKET must be one of: x11, wayland, fallback-x11, pulseaudio, system-bus, session-bus,
                    ssh-auth, pcsc, cups, gpg-agent, inherit-wayland-socket.
                    CONDITION must be one of: true, false, has-input-device, has-wayland, has-usb-device, has-usb-portal.
                    Conditions can be negated with <literal>!</literal>,
                    for example <option>!has-wayland</option>.
                    This option can be used multiple times.
                    Available since 1.17.
                </para><para>
                    See the Conditional Permissions section in
                    <citerefentry><refentrytitle>flatpak-metadata</refentrytitle><manvolnum>5</manvolnum></citerefentry>
                    for more details.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--device=DEVICE</option></term>

                <listitem><para>
                    Expose a device to the application. This updates
                    the [Context] group in the metadata.
                    DEVICE must be one of: dri, input, usb, kvm, shm, all.
                    This option can be used multiple times.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--nodevice=DEVICE</option></term>

                <listitem><para>
                    Don't expose a device to the application. This updates
                    the [Context] group in the metadata.
                    DEVICE must be one of: dri, input, usb, kvm, shm, all.
                    This option can be used multiple times.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--device-if=DEVICE:CONDITION</option></term>

                <listitem><para>
                    Expose a device to the application conditionally,
                    only when the specified condition is met at runtime.
                    This updates the [Context] group in the metadata.
                    DEVICE must be one of: dri, input, usb, kvm, shm, all.
                    CONDITION must be one of: true, false, has-input-device, has-wayland, has-usb-device, has-usb-portal.
                    Conditions can be negated with <literal>!</literal>,
                    for example <option>!has-input-device</option>.
                    This option can be used multiple times.
                    Available since 1.17.
                </para><para>
                    See the Conditional Permissions section in
                    <citerefentry><refentrytitle>flatpak-metadata</refentrytitle><manvolnum>5</manvolnum></citerefentry>
                    for more details.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--allow=FEATURE</option></term>

                <listitem><para>
                    Allow access to a specific feature. This updates
                    the [Context] group in the metadata.
                    FEATURE must be one of: devel, multiarch, bluetooth, canbus,
                    per-app-dev-shm.
                    This option can be used multiple times.
                 </para><para>
                    The <code>devel</code> feature allows the application to
                    access certain syscalls such as <code>ptrace()</code>, and
                <code>perf_event_open()</code>.
                </para><para>
                    The <code>multiarch</code> feature allows the application to
                    execute programs compiled for an ABI other than the one supported
                    natively by the system. For example, for the <code>x86_64</code>
                    architecture, 32-bit <code>x86</code> binaries will be allowed as
                    well.
                </para><para>
                    The <code>bluetooth</code> feature allows the application to
                    use bluetooth (AF_BLUETOOTH) sockets. Note, for bluetooth to
                    fully work you must also have network access.
                </para>
                <para>
                    The <code>canbus</code> feature allows the application to
                    use canbus (AF_CAN) sockets.
                    Note, for this work you must also have network access.
                </para>
                <para>
                    The <code>per-app-dev-shm</code> feature shares a single
                    instance of <filename>/dev/shm</filename> between the
                    application, any unrestricted subsandboxes that it creates,
                    and any other instances of the application that are
                    launched while it is running.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--disallow=FEATURE</option></term>

                <listitem><para>
                    Disallow access to a specific feature. This updates
                    the [Context] group in the metadata.
                    FEATURE must be one of: devel, multiarch, bluetooth, canbus,
                    per-app-dev-shm.
                    This option can be used multiple times.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--allow-if=FEATURE:CONDITION</option></term>

                <listitem><para>
                    Allow access to a specific feature conditionally,
                    only when the specified condition is met at runtime.
                    This updates the [Context] group in the metadata.
                    <arg choice="plain">FEATURE</arg> must be one of: devel, multiarch, bluetooth.
                    <arg choice="plain">CONDITION</arg> must be one of:
                    <option>true</option>, <option>false</option>,
                    <option>has-input-device</option>, <option>has-wayland</option>,
                    <option>has-usb-device</option>, <option>has-usb-portal</option>.
                    Conditions can be negated with <literal>!</literal>,
                    for example <option>!has-input-device</option>.
                    This option can be used multiple times.
                    Available since 1.17.
                </para><para>
                    See the Conditional Permissions section in
                    <citerefentry><refentrytitle>flatpak-metadata</refentrytitle><manvolnum>5</manvolnum></citerefentry>
                    for more details.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--filesystem=FS</option></term>

                <listitem><para>
                    Allow the application access to a subset of the filesystem.
                    This updates the [Context] group in the metadata.
                    FS can be one of: home, host, host-os, host-etc, host-root, xdg-desktop, xdg-documents, xdg-download,
                    xdg-music, xdg-pictures, xdg-public-share, xdg-templates, xdg-videos, xdg-run,
                    xdg-config, xdg-cache, xdg-data, an absolute path, or a homedir-relative
                    path like ~/dir or paths relative to the xdg dirs, like xdg-download/subdir.
                    The optional :ro suffix indicates that the location will be read-only.
                    The optional :create suffix indicates that the location will be read-write and created if it doesn't exist.
                    This option can be used multiple times.
                    See the "[Context] filesystems" list in
                    <citerefentry><refentrytitle>flatpak-metadata</refentrytitle><manvolnum>5</manvolnum></citerefentry>
                    for details of the meanings of these filesystems.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--nofilesystem=FILESYSTEM</option></term>

                <listitem><para>
                    Remove access to the specified subset of the filesystem from
                    the application. This overrides to the Context section from the
                    application metadata.
                    FILESYSTEM can be one of: home, host, host-os, host-etc, host-root, xdg-desktop, xdg-documents, xdg-download,
                    xdg-music, xdg-pictures, xdg-public-share, xdg-templates, xdg-videos,
                    an absolute path, or a homedir-relative path like ~/dir.
                    This option can be used multiple times.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--add-policy=SUBSYSTEM.KEY=VALUE</option></term>

                <listitem><para>
                    Add generic policy option. For example, "--add-policy=subsystem.key=v1 --add-policy=subsystem.key=v2" would map to this metadata:
<programlisting>
[Policy subsystem]
key=v1;v2;
</programlisting>
                </para><para>
                    This option can be used multiple times.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--remove-policy=SUBSYSTEM.KEY=VALUE</option></term>

                <listitem><para>
                    Remove generic policy option. This option can be used multiple times.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--usb=TYPE[:DATA]</option></term>

                <listitem><para>
                    Makes USB devices matching the query visible to the
                    USB portal by adding the query to the application
                    metadata. This does not have any effect on the
                    devices exposed in /dev.
                    <arg choice="plain">TYPE</arg> must be one of: all, cls,
                    dev, vnd.
                </para><variablelist>
                    <varlistentry>
                        <term><option>all</option></term>

                        <listitem><para>
                            Match all devices.
                        </para></listitem>
                    </varlistentry>

                    <varlistentry>
                        <term><option>cls</option></term>

                        <listitem><para>
                            A device class and subclass query. <arg choice="plain">DATA</arg>
                            must be in the form of <arg choice="plain">CLASS:SUBCLASS</arg> where
                            both <arg choice="plain">CLASS</arg> and <arg choice="plain">SUBCLASS</arg>
                            must valid 2-digit hexadecimal class id numbers. Alternatively,
                            <arg choice="plain">SUBCLASS</arg> may be <literal>*</literal> to match
                            all subclasses.
                        </para></listitem>
                    </varlistentry>

                    <varlistentry>
                        <term><option>dev</option></term>

                        <listitem><para>
                            A device product id query. <arg choice="plain">DATA</arg>
                            must be a valid 4-character hexadecimal product id
                            number, for example <option>0a1b</option>. It
                            requires a <option>vnd</option> filter in the query.
                        </para></listitem>
                    </varlistentry>

                    <varlistentry>
                        <term><option>vnd</option></term>

                        <listitem><para>
                            A device vendor id query. <arg choice="plain">DATA</arg>
                            must be a valid 4-character hexadecimal vendor id number
                            greater than zero, for example <option>0fab</option>.
                        </para></listitem>
                    </varlistentry>

                </variablelist><para>
                    It is possible to compose multiple device queries together
                    with the <literal>+</literal> sign, for example
                    <option>--usb=vnd:0123+dev:4567</option>. The <arg choice="plain">dev</arg>
                    filter requires a <arg choice="plain">vnd</arg>.
                    Available since 1.15.11.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--nousb=TYPE[:DATA]</option></term>

                <listitem><para>
                    Hides USB devices matching the query from the USB portal by
                    adding the query to the application metadata. Queries hiding
                    devices take precedence over queries making devices visible
                    (see <option>--usb</option>). The syntax is exactly equal to
                    <option>--usb</option>. This does not have any effect on the
                    devices exposed in /dev. Available since 1.15.11.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--usb-list-file=FILENAME</option></term>

                <listitem><para>
                    Adds USB device queries to the application metadata from the file
                    <arg choice="plain">FILE_NAME</arg>. The line syntax is exactly
                    equal to <option>--usb</option>. Additionally, if it starts
                    with ! then the query is like for <option>--nousb</option>.
                    Lines sthat starts with <literal>#</literal> are ignored,
                    like a comment. Comments will not be persisted.
                    Available since 1.15.11.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--usb-list=LIST</option></term>

                <listitem><para>
                    Adds USB device queries to the application metadata from
                    <arg choice="plain">LIST</arg>. The syntax is exactly equal to
                    <option>--usb</option> with queries separated by
                    <literal>;</literal>. Additionally, if the query starts with
                    <literal>!</literal> then the query is like for
                    <option>--nousb</option>. Available since 1.15.11.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--env=VAR=VALUE</option></term>

                <listitem><para>
                    Set an environment variable in the application.
                    This updates the [Environment] group in the metadata.
                    This overrides to the Context section from the application metadata.
                    This option can be used multiple times.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--unset-env=VAR</option></term>

                <listitem><para>
                    Unset an environment variable in the application.
                    This updates the unset-environment entry in the [Context]
                    group of the metadata.
                    This option can be used multiple times.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--env-fd=<replaceable>FD</replaceable></option></term>

                <listitem><para>
                    Read environment variables from the file descriptor
                    <replaceable>FD</replaceable>, and set them as if
                    via <option>--env</option>. This can be used to avoid
                    environment variables and their values becoming visible
                    to other users.
                </para><para>
                    Each environment variable is in the form
                    <replaceable>VAR</replaceable>=<replaceable>VALUE</replaceable>
                    followed by a zero byte. This is the same format used by
                    <literal>env -0</literal> and
                    <filename>/proc/*/environ</filename>.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--own-name=NAME</option></term>

                <listitem><para>
                    Allow the application to own the well known name <arg choice="plain">NAME</arg> on the session bus.
                    If <arg choice="plain">NAME</arg> ends with .*, it allows the application to own all matching names.

                    This updates the [Session Bus Policy] group in the metadata.
                    This option can be used multiple times.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--talk-name=NAME</option></term>

                <listitem><para>
                    Allow the application to talk to the well known name <arg choice="plain">NAME</arg> on the session bus.
                    If <arg choice="plain">NAME</arg> ends with .*, it allows the application to talk to all matching names.
                    This updates the [Session Bus Policy] group in the metadata.
                    This option can be used multiple times.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--system-own-name=NAME</option></term>

                <listitem><para>
                    Allow the application to own the well known name <arg choice="plain">NAME</arg> on the system bus.
                    If <arg choice="plain">NAME</arg> ends with .*, it allows the application to own all matching names.
                    This updates the [System Bus Policy] group in the metadata.
                    This option can be used multiple times.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--system-talk-name=NAME</option></term>

                <listitem><para>
                    Allow the application to talk to the well known name <arg choice="plain">NAME</arg> on the system bus.
                    If <arg choice="plain">NAME</arg> ends with .*, it allows the application to talk to all matching names.
                    This updates the [System Bus Policy] group in the metadata.
                    This option can be used multiple times.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--persist=FILENAME</option></term>

                <listitem><para>
                    If the application doesn't have access to the real homedir, make the (homedir-relative) path
                    <arg choice="plain">FILENAME</arg> a bind mount to the corresponding path in the per-application directory,
                    allowing that location to be used for persistent data.
                    This updates the [Context] group in the metadata.
                    This option can be used multiple times.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--runtime=RUNTIME</option></term>
                <term><option>--sdk=SDK</option></term>

                <listitem><para>
                  Change the runtime or sdk used by the app to the specified partial ref. Unspecified parts
                  of the ref are taken from the old values or defaults.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--metadata=GROUP=KEY[=VALUE]</option></term>

                <listitem><para>
                  Set a generic key in the metadata file. If value is left out it will
                  be set to "true".
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--extension=NAME=VARIABLE[=VALUE]</option></term>

                <listitem><para>
                  Add extension point info.
                  See the documentation for
                  <citerefentry>
                    <refentrytitle>flatpak-metadata</refentrytitle>
                    <manvolnum>5</manvolnum>
                  </citerefentry>
                  for the possible values of
                  <replaceable>VARIABLE</replaceable> and <replaceable>VALUE</replaceable>.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--remove-extension=NAME</option></term>

                <listitem><para>
                  Remove extension point info.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--extension-priority=VALUE</option></term>

                <listitem><para>
                  Set the priority (library override order) of the extension point.
                  Only useful for extensions. 0 is the default, and higher value means higher
                  priority.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--extra-data=NAME:SHA256:DOWNLOAD-SIZE:INSTALL-SIZE:URL</option></term>

                <listitem><para>
                    Adds information about extra data uris to the app. These will be downloaded
                    and verified by the client when the app is installed and placed in the
                    <filename>/app/extra</filename> directory. You can also supply an <filename>/app/bin/apply_extra</filename> script
                    that will be run after the files are downloaded.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--no-exports</option></term>

                <listitem><para>
                    Don't look for exports in the build.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--no-inherit-permissions</option></term>

                <listitem><para>
                    Don't inherit runtime permissions in the app.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>-v</option></term>
                <term><option>--verbose</option></term>

                <listitem><para>
                    Print debug information during command processing.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--ostree-verbose</option></term>

                <listitem><para>
                    Print OSTree debug information during command processing.
                </para></listitem>
            </varlistentry>
        </variablelist>
    </refsect1>

    <refsect1>
        <title>Examples</title>

        <para>
            <command>$ flatpak build-finish /build/my-app --socket=x11 --share=ipc --usb=vnd:0fd9</command>
        </para>
<programlisting>
Exporting share/applications/gnome-calculator.desktop
Exporting share/dbus-1/services/org.gnome.Calculator.SearchProvider.service
More than one executable
Using gcalccmd as command
Please review the exported files and the metadata
</programlisting>

        <para>
            <command>$ flatpak build-finish /build/my-app --socket=wayland --socket-if=x11:!has-wayland --share=ipc</command>
        </para>
        <para>
            This grants Wayland access unconditionally and X11 access only when not running in a Wayland session,
            allowing the application to fall back to X11 when needed.
        </para>

    </refsect1>

    <refsect1>
        <title>See also</title>

        <para>
            <citerefentry><refentrytitle>flatpak</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
            <citerefentry><refentrytitle>flatpak-build-init</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
            <citerefentry><refentrytitle>flatpak-build</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
            <citerefentry><refentrytitle>flatpak-build-export</refentrytitle><manvolnum>1</manvolnum></citerefentry>
        </para>

    </refsect1>

</refentry>

===== ./doc/flatpak-history.xml =====
<?xml version='1.0'?> <!--*-nxml-*-->
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
    "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">

<refentry id="flatpak-history">

    <refentryinfo>
        <title>flatpak history</title>
        <productname>flatpak</productname>

        <authorgroup>
            <author>
                <contrib>Developer</contrib>
                <firstname>Matthias</firstname>
                <surname>Clasen</surname>
                <email>mclasen@redhat.com</email>
            </author>
        </authorgroup>
    </refentryinfo>

    <refmeta>
        <refentrytitle>flatpak history</refentrytitle>
        <manvolnum>1</manvolnum>
    </refmeta>

    <refnamediv>
        <refname>flatpak-history</refname>
        <refpurpose>Show history</refpurpose>
    </refnamediv>

    <refsynopsisdiv>
            <cmdsynopsis>
                <command>flatpak history</command>
                <arg choice="opt" rep="repeat">OPTION</arg>
            </cmdsynopsis>
    </refsynopsisdiv>

    <refsect1>
        <title>Description</title>

        <para>
            Shows changes to the flatpak installations on the system. This includes
            installs, updates and removals of applications and runtimes.
        </para>
        <para>
            By default, both per-user and system-wide installations are shown. Use the
            <option>--user</option>, <option>--installation</option> or <option>--system</option> options to change this.
        </para>
        <para>
            The information for the history command is taken from the systemd journal,
            and can also be accessed using e.g.
            <command>journalctl MESSAGE_ID=c7b39b1e006b464599465e105b361485</command>
        </para>

    </refsect1>

    <refsect1>
        <title>Options</title>

        <para>The following options are understood:</para>

        <variablelist>
            <varlistentry>
                <term><option>-h</option></term>
                <term><option>--help</option></term>

                <listitem><para>
                    Show help options and exit.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>-u</option></term>
                <term><option>--user</option></term>

                <listitem><para>
                    Show changes to the user installation.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--system</option></term>

                <listitem><para>
                    Show changes to the default system-wide installation.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--installation=NAME</option></term>

                <listitem><para>
                    Show changes to the installation specified by <arg choice="plain">NAME</arg>
                    among those defined in <filename>/etc/flatpak/installations.d/</filename>.
                    Using <option>--installation=default</option> is equivalent to using
                    <option>--system</option>.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--since=TIME</option></term>

                <listitem><para>
                    Only show changes that are newer than the time specified by
                    <arg choice="plain">TIME</arg>.
                </para><para>
                    <arg choice="plain">TIME</arg> can be either an absolute time
                    in a format like YYYY-MM-DD HH:MM:SS, or a relative time like
                    "2h", "7days", "4days 2hours".
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--until=TIME</option></term>

                <listitem><para>
                    Only show changes that are older than the time specified by
                    <arg choice="plain">TIME</arg>.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--reverse</option></term>

                <listitem><para>
                    Show newest entries first.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>-v</option></term>
                <term><option>--verbose</option></term>

                <listitem><para>
                    Print debug information during command processing.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--ostree-verbose</option></term>

                <listitem><para>
                    Print OSTree debug information during command processing.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--columns=FIELD,…</option></term>

                <listitem><para>
                    Specify what information to show about each ref. You can
                    list multiple fields, or use this option multiple times.
                </para><para>
                    Append :s[tart], :m[iddle], :e[nd] or :f[ull] to column
                    names to change ellipsization.
                </para></listitem>
            </varlistentry>

        </variablelist>
    </refsect1>

   <refsect1>
        <title>Fields</title>

        <para>The following fields are understood by the <option>--columns</option> option:</para>

        <variablelist>
            <varlistentry>
                <term>time</term>

                <listitem><para>
                    Show when the change happened
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term>change</term>

                <listitem><para>
                    Show the kind of change
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term>ref</term>

                <listitem><para>
                    Show the ref
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term>application</term>

                <listitem><para>
                    Show the application/runtime ID
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term>arch</term>

                <listitem><para>
                    Show the architecture
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term>branch</term>

                <listitem><para>
                    Show the branch
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term>installation</term>

                <listitem><para>
                    Show the affected installation.
                </para><para>
                    This will be either the ID of a Flatpak installation,
                    or the path to a temporary OSTree repository.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term>remote</term>

                <listitem><para>
                    Show the remote that is used.
                </para><para>
                    This will be either the name of a configured remote,
                    or the path to a temporary OSTree repository.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term>old-commit</term>

                <listitem><para>
                    Show the previous commit. For pulls, this is the previous HEAD of the branch.
                    For deploys, it is the previously active commit
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term>commit</term>

                <listitem><para>
                    Show the current commit. For pulls, this is the HEAD of the branch.
                    For deploys, it is the active commit
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term>url</term>

                <listitem><para>
                    Show the remote url
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term>user</term>

                <listitem><para>
                    Show the user doing the change.
                </para><para>
                    If this is the system helper operating as root,
                    also show which user triggered the change.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term>tool</term>

                <listitem><para>
                    Show the tool that was used.
                </para><para>
                    If this is the system helper, also show
                    which tool was used to triggered the change.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term>all</term>

                <listitem><para>
                    Show all columns
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term>help</term>

                <listitem><para>
                    Show the list of available columns
                </para></listitem>
            </varlistentry>
        </variablelist>

        <para>
          Note that field names can be abbreviated to a unique prefix.
        </para>

    </refsect1>

    <refsect1>
        <title>See also</title>

        <para>
            <citerefentry><refentrytitle>flatpak</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
            <citerefentry><refentrytitle>journalctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>
        </para>

    </refsect1>

</refentry>

===== ./doc/flatpak-update.xml =====
<?xml version='1.0'?> <!--*-nxml-*-->
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
    "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">

<refentry id="flatpak-update">

    <refentryinfo>
        <title>flatpak update</title>
        <productname>flatpak</productname>

        <authorgroup>
            <author>
                <contrib>Developer</contrib>
                <firstname>Alexander</firstname>
                <surname>Larsson</surname>
                <email>alexl@redhat.com</email>
            </author>
        </authorgroup>
    </refentryinfo>

    <refmeta>
        <refentrytitle>flatpak update</refentrytitle>
        <manvolnum>1</manvolnum>
    </refmeta>

    <refnamediv>
        <refname>flatpak-update</refname>
        <refpurpose>Update an application or runtime</refpurpose>
    </refnamediv>

    <refsynopsisdiv>
            <cmdsynopsis>
                <command>flatpak update</command>
                <arg choice="opt" rep="repeat">OPTION</arg>
                <arg choice="opt" rep="repeat">REF</arg>
            </cmdsynopsis>
            <cmdsynopsis>
                <command>flatpak update</command>
                <arg choice="opt" rep="repeat">OPTION</arg>
                <arg choice="plain">--appstream</arg>
                <arg choice="opt">REMOTE</arg>
            </cmdsynopsis>
    </refsynopsisdiv>

    <refsect1>
        <title>Description</title>

        <para>
            Updates applications and runtimes. <arg choice="plain">REF</arg> is a reference to the
            application or runtime to update. If no <arg choice="plain">REF</arg> is given, everything
            is updated, as well as appstream info for all remotes.
        </para>
        <para>
            Each <arg choice="plain">REF</arg> argument is a full or partial identifier in the
            flatpak ref format, which looks like "(app|runtime)/ID/ARCH/BRANCH". All elements
            except ID are optional and can be left out, including the slashes,
            so most of the time you need only specify ID. Any part left out will be matched
            against what is installed, and if there are multiple matches an error message
            will list the alternatives.
        </para>
        <para>
            By default this looks for both apps and runtimes with the given <arg choice="plain">REF</arg>,
            but you can limit this by using the <option>--app</option> or <option>--runtime</option> option, or by supplying the initial
            element in the <arg choice="plain">REF</arg>.
        </para>
        <para>
            Normally, this command updates the application to the tip
            of its branch. But it is possible to check out another commit,
            with the <option>--commit</option> option.
        </para>
        <para>
            If the configured remote for a ref being updated has a collection ID configured on it,
            Flatpak will search the <filename>sideload-repos</filename> directories configured
            either with the <option>--sideload-repo</option> option, or on a per-installation or
            system-wide basis (see
            <citerefentry><refentrytitle>flatpak</refentrytitle><manvolnum>1</manvolnum></citerefentry>).
        </para>
        <para>
          For OCI remotes, sideload repositories can also be specified as
          <option>--sideload-repo=oci:PATH</option> or <option>--sideload-repo=oci-archive:PATH</option>,
          where path points to an OCI image layout or archive of an OCI image layout.
          (See <citerefentry><refentrytitle>containers-transports</refentrytitle><manvolnum>5</manvolnum></citerefentry>.)
          When specified in this fashion, the images found in the image layout are available for all OCI remotes,
          without regard to collection ID. For this reason, there is no directory equivalent -
          it can only be specified on the command line.
        </para>
        <para>
            Note that updating a runtime is different from installing
            a different branch, and runtime updates are expected to keep
            strict compatibility. If an application update does cause
            a problem, it is possible to go back to the previous
            version, with the <option>--commit</option> option.
        </para>
        <para>
            In addition to updates, this command will offer to uninstall any unused end-of-life
            runtimes. Runtimes that were explicitly installed (not as a dependency) or explicitly
            pinned (see <citerefentry><refentrytitle>flatpak-pin</refentrytitle><manvolnum>1</manvolnum></citerefentry>)
            are left installed even if unused and end-of-life.
        </para>
        <para>
            Unless overridden with the <option>--user</option>, <option>--system</option> or <option>--installation</option> option, this command updates
            any matching refs in the standard system-wide installation and the per-user one.
        </para>

    </refsect1>

    <refsect1>
        <title>Options</title>

        <para>The following options are understood:</para>

        <variablelist>
            <varlistentry>
                <term><option>-h</option></term>
                <term><option>--help</option></term>

                <listitem><para>
                    Show help options and exit.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>-u</option></term>
                <term><option>--user</option></term>

                <listitem><para>
                    Update a per-user installation.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--system</option></term>

                <listitem><para>
                    Update the default system-wide installation.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--installation=NAME</option></term>

                <listitem><para>
                    Updates a system-wide installation specified by <arg choice="plain">NAME</arg>
                    among those defined in <filename>/etc/flatpak/installations.d/</filename>.
                    Using <option>--installation=default</option> is equivalent to using
                    <option>--system</option>.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--arch=ARCH</option></term>

                <listitem><para>
                    The architecture to update for. See <command>flatpak --supported-arches</command>
                    for architectures supported by the host.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--subpath=PATH</option></term>

                <listitem><para>
                  Install only a subpath of the ref. This is mainly used to install a subset of locales.
                  This can be added multiple times to install multiple subpaths.
                  If this is not specified the subpaths specified at install time are reused.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--commit=COMMIT</option></term>

                <listitem><para>
                    Update to this commit, instead of the tip of the branch. You can find commits
                    using <command>flatpak remote-info --log REMOTE REF</command>.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--no-deploy</option></term>

                <listitem><para>
                    Download the latest version, but don't deploy it.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--no-pull</option></term>

                <listitem><para>
                    Don't download the latest version, deploy whatever is locally available.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--no-related</option></term>

                <listitem><para>
                    Don't download related extensions, such as the locale data.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--no-deps</option></term>

                <listitem><para>
                    Don't update or install runtime dependencies when installing.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--app</option></term>

                <listitem><para>
                    Only look for an app with the given name.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--appstream</option></term>

                <listitem><para>
                    Update appstream for <arg choice="plain">REMOTE</arg>, or all remotes if no remote is specified.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--runtime</option></term>

                <listitem><para>
                    Only look for a runtime with the given name.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--sideload-repo=PATH</option></term>

                <listitem><para>
                    Adds an extra local ostree repo as a source for installation. This is equivalent
                    to using the <filename>sideload-repos</filename> directories (see
                    <citerefentry><refentrytitle>flatpak</refentrytitle><manvolnum>1</manvolnum></citerefentry>),
                    but can be done on a per-command basis. Any path added here is used in addition
                    to ones in those directories.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>-y</option></term>
                <term><option>--assumeyes</option></term>
                <listitem><para>
                    Automatically answer yes to all questions (or pick the most prioritized answer). This is useful for automation.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--noninteractive</option></term>
                <listitem><para>
                    Produce minimal output and avoid most questions. This is suitable for use in
                    non-interactive situations, e.g. in a build script.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--force-remove</option></term>
                <listitem><para>
                    Remove old files even if they're in use by a running application.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>-v</option></term>
                <term><option>--verbose</option></term>

                <listitem><para>
                    Print debug information during command processing.
                </para></listitem>
            </varlistentry>

            <varlistentry>
                <term><option>--ostree-verbose</option></term>

                <listitem><para>
                    Print OSTree debug information during command processing.
                </para></listitem>
            </varlistentry>
        </variablelist>
    </refsect1>

    <refsect1>
        <title>Examples</title>

        <para>
            <command>$ flatpak --user update org.gnome.gedit</command>
        </para>

    </refsect1>

    <refsect1>
        <title>See also</title>

        <para>
            <citerefentry><refentrytitle>flatpak</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
            <citerefentry><refentrytitle>flatpak-install</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
            <citerefentry><refentrytitle>flatpak-list</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
            <citerefentry><refentrytitle>ostree-find-remotes</refentrytitle><manvolnum>1</manvolnum></citerefentry>
        </para>

    </refsect1>

</refentry>

===== ./po/bg.po =====
# Bulgarian translation of flatpak po-file.
# Copyright (C) 2024, 2025 twlvnn kraftwerk <kraft_werk@tutanota.com>.
# This file is distributed under the same license as the flatpak package.
# twlvnn kraftwerk <kraft_werk@tutanota.com>, 2024, 2025.
#
msgid ""
msgstr ""
"Project-Id-Version: flatpak main\n"
"Report-Msgid-Bugs-To: https://github.com/flatpak/flatpak/issues\n"
"POT-Creation-Date: 2026-05-27 16:39+0200\n"
"PO-Revision-Date: 2025-02-17 08:44+0100\n"
"Last-Translator: twlvnn kraftwerk <kraft_werk@tutanota.com>\n"
"Language-Team: Bulgarian <dict-notifications@fsa-bg.org>\n"
"Language: bg\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
"X-Generator: Gtranslator 47.1\n"

#: app/flatpak-builtins-build-bundle.c:59
msgid "Export runtime instead of app"
msgstr "Изнасяне на среда за изпълнение вместо програма"

#: app/flatpak-builtins-build-bundle.c:60
msgid "Arch to bundle for"
msgstr "Архитектура, за която да се пакетира"

#: app/flatpak-builtins-build-bundle.c:60
#: app/flatpak-builtins-build-export.c:62 app/flatpak-builtins-build-init.c:53
#: app/flatpak-builtins-build-sign.c:42 app/flatpak-builtins-create-usb.c:46
#: app/flatpak-builtins-info.c:55 app/flatpak-builtins-install.c:67
#: app/flatpak-builtins-list.c:50 app/flatpak-builtins-make-current.c:38
#: app/flatpak-builtins-remote-info.c:54 app/flatpak-builtins-remote-ls.c:56
#: app/flatpak-builtins-run.c:158 app/flatpak-builtins-search.c:37
#: app/flatpak-builtins-uninstall.c:54 app/flatpak-builtins-update.c:56
msgid "ARCH"
msgstr "АРХИТЕКТУРА"

#: app/flatpak-builtins-build-bundle.c:61
#, fuzzy
msgid "URL for repo"
msgstr "Адрес на хранилището"

#: app/flatpak-builtins-build-bundle.c:61
#: app/flatpak-builtins-build-bundle.c:62
#: app/flatpak-builtins-build-update-repo.c:68
#: app/flatpak-builtins-build-update-repo.c:72
#: app/flatpak-builtins-build-update-repo.c:73
#: app/flatpak-builtins-history.c:69 app/flatpak-builtins-remote-add.c:80
#: app/flatpak-builtins-remote-add.c:81 app/flatpak-builtins-remote-add.c:85
#: app/flatpak-builtins-remote-list.c:53
#: app/flatpak-builtins-remote-modify.c:70
#: app/flatpak-builtins-remote-modify.c:85
#: app/flatpak-builtins-remote-modify.c:86
#: app/flatpak-builtins-remote-modify.c:90
msgid "URL"
msgstr "АДРЕС"

#: app/flatpak-builtins-build-bundle.c:62
#, fuzzy
msgid "URL for runtime flatpakrepo file"
msgstr "Адрес на файла flatpakrepo за средата за изпълнение"

#: app/flatpak-builtins-build-bundle.c:63
msgid "Add GPG key from FILE (- for stdin)"
msgstr "Добавяне на ключ за GPG от ФАЙЛ („-“ за стандартен вход)"

#: app/flatpak-builtins-build-bundle.c:63 app/flatpak-builtins-build.c:54
#: app/flatpak-builtins-build-export.c:67
#: app/flatpak-builtins-build-update-repo.c:83
#: app/flatpak-builtins-install.c:81 app/flatpak-builtins-remote-add.c:84
#: app/flatpak-builtins-remote-add.c:86 app/flatpak-builtins-remote-modify.c:89
#: app/flatpak-builtins-remote-modify.c:92
msgid "FILE"
msgstr "ФАЙЛ"

#: app/flatpak-builtins-build-bundle.c:64
msgid "GPG Key ID to sign the OCI image with"
msgstr ""
"Идентификатор на ключ за GPG, с който се подписва образа във формат OCI"

#: app/flatpak-builtins-build-bundle.c:64
#: app/flatpak-builtins-build-commit-from.c:68
#: app/flatpak-builtins-build-export.c:68
#: app/flatpak-builtins-build-import-bundle.c:49
#: app/flatpak-builtins-build-sign.c:44
#: app/flatpak-builtins-build-update-repo.c:84
msgid "KEY-ID"
msgstr "ИД_КЛЮЧ"

#: app/flatpak-builtins-build-bundle.c:65
#: app/flatpak-builtins-build-commit-from.c:69
#: app/flatpak-builtins-build-export.c:71
#: app/flatpak-builtins-build-import-bundle.c:50
#: app/flatpak-builtins-build-sign.c:45
#: app/flatpak-builtins-build-update-repo.c:85
msgid "GPG Homedir to use when looking for keyrings"
msgstr "Домашна директория за GPG при търсене на ключодържатели"

#: app/flatpak-builtins-build-bundle.c:65
#: app/flatpak-builtins-build-commit-from.c:69
#: app/flatpak-builtins-build-export.c:71
#: app/flatpak-builtins-build-import-bundle.c:50
#: app/flatpak-builtins-build-sign.c:45
#: app/flatpak-builtins-build-update-repo.c:85
msgid "HOMEDIR"
msgstr "ДОМАШНА_ДИРЕКТОРИЯ"

#: app/flatpak-builtins-build-bundle.c:66
msgid "OSTree commit to create a delta bundle from"
msgstr "От кое подаване в OSTree да се създаде пакет за разлики"

#: app/flatpak-builtins-build-bundle.c:66 app/flatpak-builtins-remote-info.c:55
#: app/flatpak-builtins-update.c:57
msgid "COMMIT"
msgstr "ПОДАВАНЕ"

#: app/flatpak-builtins-build-bundle.c:67
msgid "Export oci image instead of flatpak bundle"
msgstr "Изнасяне на образ във формат OCI вместо пакет на Flatpak"

#: app/flatpak-builtins-build-bundle.c:70
msgid "How to compress OCI image layers (default: gzip)"
msgstr ""

#: app/flatpak-builtins-build-bundle.c:634
msgid ""
"LOCATION FILENAME NAME [BRANCH] - Create a single file bundle from a local "
"repository"
msgstr ""
"МЕСТОПОЛОЖЕНИЕ ИМЕ_НА_ФАЙЛ ИМЕ [КЛОН] — създаване на пакет от един файл от "
"локално хранилище"

#: app/flatpak-builtins-build-bundle.c:641
msgid "LOCATION, FILENAME and NAME must be specified"
msgstr "МЕСТОПОЛОЖЕНИЕто, ИМЕто_НА_ФАЙЛ и ИМЕто са задължителни"

#: app/flatpak-builtins-build-bundle.c:644
#: app/flatpak-builtins-build-export.c:844
#: app/flatpak-builtins-build-import-bundle.c:136
#: app/flatpak-builtins-build-init.c:217 app/flatpak-builtins-build-sign.c:76
#: app/flatpak-builtins-document-export.c:112
#: app/flatpak-builtins-document-info.c:75
#: app/flatpak-builtins-document-list.c:191
#: app/flatpak-builtins-document-unexport.c:70
#: app/flatpak-builtins-history.c:482 app/flatpak-builtins-info.c:130
#: app/flatpak-builtins-install.c:181 app/flatpak-builtins-install.c:234
#: app/flatpak-builtins-install.c:298 app/flatpak-builtins-list.c:419
#: app/flatpak-builtins-make-current.c:72 app/flatpak-builtins-override.c:73
#: app/flatpak-builtins-permission-list.c:162
#: app/flatpak-builtins-permission-remove.c:132
#: app/flatpak-builtins-remote-add.c:323
#: app/flatpak-builtins-remote-delete.c:68
#: app/flatpak-builtins-remote-list.c:241 app/flatpak-builtins-remote-ls.c:407
msgid "Too many arguments"
msgstr "Прекалено много аргументи"

#: app/flatpak-builtins-build-bundle.c:659
#: app/flatpak-builtins-build-commit-from.c:338
#: app/flatpak-builtins-build-commit-from.c:351
#: app/flatpak-builtins-build-import-bundle.c:145
#, c-format
msgid "'%s' is not a valid repository"
msgstr "„%s“ е неправилно хранилище"

#: app/flatpak-builtins-build-bundle.c:663
#, c-format
msgid "'%s' is not a valid repository: "
msgstr "„%s“ е неправилно хранилище: "

#: app/flatpak-builtins-build-bundle.c:674 app/flatpak-builtins-build-sign.c:88
#: common/flatpak-dir.c:14293
#, c-format
msgid "'%s' is not a valid name: %s"
msgstr "„%s“ е неправилно име: %s"

#: app/flatpak-builtins-build-bundle.c:677
#: app/flatpak-builtins-build-export.c:865 app/flatpak-builtins-build-sign.c:91
#: common/flatpak-dir.c:14299
#, c-format
msgid "'%s' is not a valid branch name: %s"
msgstr "„%s“ е неправилно име на клон: %s"

#: app/flatpak-builtins-build-bundle.c:691
#: app/flatpak-builtins-build-import-bundle.c:149
#: app/flatpak-builtins-build-init.c:281
#, c-format
msgid "'%s' is not a valid filename"
msgstr "„%s“ е неправилно име на файл"

#: app/flatpak-builtins-build-bundle.c:706
msgid "--oci-layer-compress value must be gzip or zstd"
msgstr ""

#: app/flatpak-builtins-build.c:49
msgid "Use Platform runtime rather than Sdk"
msgstr "Използване на средата за изпълнение на платформата вместо SDK"

#: app/flatpak-builtins-build.c:50
msgid "Make destination readonly"
msgstr "Целевото местоположение да е само за четене"

#: app/flatpak-builtins-build.c:51
msgid "Add bind mount"
msgstr "Добавяне на точка за монтиране"

#: app/flatpak-builtins-build.c:51
msgid "DEST=SRC"
msgstr "ЦЕЛ=ИЗТОЧНИК"

#: app/flatpak-builtins-build.c:52
msgid "Start build in this directory"
msgstr "Стартиране на изграждането в тази директория"

#: app/flatpak-builtins-build.c:52 app/flatpak-builtins-build.c:53
#: app/flatpak-builtins-build-init.c:64 app/flatpak-builtins-run.c:160
msgid "DIR"
msgstr "ДИРЕКТОРИЯ"

#: app/flatpak-builtins-build.c:53
msgid "Where to look for custom sdk dir (defaults to 'usr')"
msgstr "Къде да се търси директорията за собствени SDK (стандартно е „usr“)"

#: app/flatpak-builtins-build.c:54 app/flatpak-builtins-build-export.c:67
msgid "Use alternative file for the metadata"
msgstr "Използване на друг файл за метаданните"

#: app/flatpak-builtins-build.c:55 app/flatpak-builtins-run.c:177
msgid "Kill processes when the parent process dies"
msgstr "Убиване на процесите, когато родителският процес умре"

#: app/flatpak-builtins-build.c:56
msgid "Export application homedir directory to build"
msgstr "Изнасяне на домашната директория на програмата за изграждане"

#: app/flatpak-builtins-build.c:57 app/flatpak-builtins-run.c:165
msgid "Log session bus calls"
msgstr "Извеждане на извикванията на сесийната шина в журнала"

#: app/flatpak-builtins-build.c:58 app/flatpak-builtins-run.c:166
msgid "Log system bus calls"
msgstr "Извеждане на извикванията на системната шина в журнала"

#: app/flatpak-builtins-build.c:262
msgid "DIRECTORY [COMMAND [ARGUMENT…]] - Build in directory"
msgstr "ДИРЕКТОРИЯ [КОМАНДА [АРГУМЕНТ…]] — изграждане в директория"

#: app/flatpak-builtins-build.c:285 app/flatpak-builtins-build-finish.c:656
msgid "DIRECTORY must be specified"
msgstr "ДИРЕКТОРИЯта трябва да се посочи"

#: app/flatpak-builtins-build.c:296 app/flatpak-builtins-build-export.c:887
#, c-format
msgid "Build directory %s not initialized, use flatpak build-init"
msgstr ""
"Директорията за изграждане %s не е инициализирана, използвайте flatpak build-"
"init"

#: app/flatpak-builtins-build.c:315
msgid "metadata invalid, not application or runtime"
msgstr "метаданните са неправилни, а не програмата или средата за изпълнение"

#: app/flatpak-builtins-build.c:446
#, c-format
msgid "No extension point matching %s in %s"
msgstr "Няма точка на разширение, съответстваща на %s в %s"

#: app/flatpak-builtins-build.c:635
#, c-format
msgid "Missing '=' in bind mount option '%s'"
msgstr "В опцията за монтиране „%s“ липсва „=“"

#: app/flatpak-builtins-build.c:679 common/flatpak-run.c:3961
#, c-format
msgid "Unable to start app"
msgstr "Програмата не може да се стартира"

#: app/flatpak-builtins-build-commit-from.c:58
msgid "Source repo dir"
msgstr "Директория към хранилището на източника"

#: app/flatpak-builtins-build-commit-from.c:58
msgid "SRC-REPO"
msgstr "ИЗТОЧНИК_ХРАНИЛИЩЕ"

#: app/flatpak-builtins-build-commit-from.c:59
msgid "Source repo ref"
msgstr "Указател към хранилището на източника"

#: app/flatpak-builtins-build-commit-from.c:59
msgid "SRC-REF"
msgstr "ИЗТОЧНИК_УКАЗАТЕЛ"

#: app/flatpak-builtins-build-commit-from.c:64
#: app/flatpak-builtins-build-export.c:60
msgid "One line subject"
msgstr "Тема на един ред"

#: app/flatpak-builtins-build-commit-from.c:64
#: app/flatpak-builtins-build-export.c:60
msgid "SUBJECT"
msgstr "ТЕМА"

#: app/flatpak-builtins-build-commit-from.c:65
#: app/flatpak-builtins-build-export.c:61
msgid "Full description"
msgstr "Пълно описание"

#: app/flatpak-builtins-build-commit-from.c:65
#: app/flatpak-builtins-build-export.c:61
msgid "BODY"
msgstr "ТЯЛО"

#: app/flatpak-builtins-build-commit-from.c:66
#: app/flatpak-builtins-build-export.c:64
#: app/flatpak-builtins-build-import-bundle.c:51
msgid "Update the appstream branch"
msgstr "Обновяване на клона на appstream"

#: app/flatpak-builtins-build-commit-from.c:67
#: app/flatpak-builtins-build-export.c:65
#: app/flatpak-builtins-build-import-bundle.c:52
#: app/flatpak-builtins-build-update-repo.c:87
msgid "Don't update the summary"
msgstr "Без обновяване на обобщението"

#: app/flatpak-builtins-build-commit-from.c:68
#: app/flatpak-builtins-build-export.c:68
#: app/flatpak-builtins-build-import-bundle.c:49
#: app/flatpak-builtins-build-sign.c:44
msgid "GPG Key ID to sign the commit with"
msgstr "Идентификатор на GPG ключ, с който се подписва подаването"

#: app/flatpak-builtins-build-commit-from.c:70
#: app/flatpak-builtins-build-export.c:73
msgid "Mark build as end-of-life"
msgstr "Отбелязване на изграждането, че не получава обновления"

#: app/flatpak-builtins-build-commit-from.c:70
#: app/flatpak-builtins-build-export.c:73
msgid "REASON"
msgstr "ПРИЧИНА"

#: app/flatpak-builtins-build-commit-from.c:71
msgid ""
"Mark refs matching the OLDID prefix as end-of-life, to be replaced with the "
"given NEWID"
msgstr ""
"Отбелязване на указателите, отговарящи на представката СТАР_ИДeнтификатор, "
"че не получават обновления и следва да се заменят със зададения "
"НОВ_ИДентификатор"

#: app/flatpak-builtins-build-commit-from.c:71
msgid "OLDID=NEWID"
msgstr "СТАР_ИД=НОВ_ИД"

#: app/flatpak-builtins-build-commit-from.c:72
#: app/flatpak-builtins-build-export.c:75
msgid "Set type of token needed to install this commit"
msgstr "Задаване на вида на токена за инсталиране на това подаване"

#: app/flatpak-builtins-build-commit-from.c:72
#: app/flatpak-builtins-build-export.c:75
msgid "VAL"
msgstr "СТОЙНОСТ"

#: app/flatpak-builtins-build-commit-from.c:73
msgid "Override the timestamp of the commit (NOW for current time)"
msgstr "Заменяне на датата на подаването (NOW за текущото време)"

#: app/flatpak-builtins-build-commit-from.c:73
#: app/flatpak-builtins-build-export.c:76
msgid "TIMESTAMP"
msgstr "ДАТА"

#: app/flatpak-builtins-build-commit-from.c:75
#: app/flatpak-builtins-build-export.c:80
#: app/flatpak-builtins-build-import-bundle.c:53
#: app/flatpak-builtins-build-update-repo.c:97
msgid "Don't generate a summary index"
msgstr "Без генериране на индекс за обобщение"

#: app/flatpak-builtins-build-commit-from.c:278
msgid "DST-REPO [DST-REF…] - Make a new commit from existing commits"
msgstr ""
"ЦЕЛЕВО-ХРАНИЛИЩЕ [ЦЕЛЕВИ-УКАЗАТЕЛ…] — създаване на ново подаване от "
"съществуващи подавания"

#: app/flatpak-builtins-build-commit-from.c:285
msgid "DST-REPO must be specified"
msgstr "ЦЕЛЕВО-ХРАНИЛИЩЕ трябва да се посочи"

#: app/flatpak-builtins-build-commit-from.c:293
msgid ""
"If --src-repo is not specified, exactly one destination ref must be specified"
msgstr ""
"Ако „--src-repo“ не е зададено, трябва да се зададе точно един указател на "
"дестинация"

#: app/flatpak-builtins-build-commit-from.c:296
msgid ""
"If --src-ref is specified, exactly one destination ref must be specified"
msgstr ""
"Ако „--src-ref“ е зададено, трябва да се зададе точно един указател на "
"дестинация"

#: app/flatpak-builtins-build-commit-from.c:299
msgid "Either --src-repo or --src-ref must be specified"
msgstr "Трябва да се посочи или „--src-repo“, или „--src-ref“"

#: app/flatpak-builtins-build-commit-from.c:315
msgid "Invalid argument format of use  --end-of-life-rebase=OLDID=NEWID"
msgstr "Неправилен формат на аргумента --end-of-life-rebase=СТАР_ИД=НОВ_ИД"

#: app/flatpak-builtins-build-commit-from.c:321
#: app/flatpak-builtins-build-commit-from.c:324
#, c-format
msgid "Invalid name %s in --end-of-life-rebase"
msgstr "Неправилно име „%s“ в „--end-of-life-rebase“"

#: app/flatpak-builtins-build-commit-from.c:333
#: app/flatpak-builtins-build-export.c:1092
#, c-format
msgid "Could not parse '%s'"
msgstr "„%s“ не може да се разчете"

#: app/flatpak-builtins-build-commit-from.c:498
msgid "Can't commit from partial source commit"
msgstr "Не може да се извърши подаване от непълно хранилище"

#: app/flatpak-builtins-build-commit-from.c:503
#, c-format
msgid "%s: no change\n"
msgstr "%s: няма промени\n"

#: app/flatpak-builtins-build-export.c:62
msgid "Architecture to export for (must be host compatible)"
msgstr "Архитектура, за която да се изнася (трябва да е съвместима с хоста)"

#: app/flatpak-builtins-build-export.c:63
msgid "Commit runtime (/usr), not /app"
msgstr "Среда за изпълнение на подаването („/usr“), а не „/app“"

#: app/flatpak-builtins-build-export.c:66
msgid "Use alternative directory for the files"
msgstr "Използвайте друга директория за файловете"

#: app/flatpak-builtins-build-export.c:66
msgid "SUBDIR"
msgstr "ПОДДИРЕКТОРИЯ"

#: app/flatpak-builtins-build-export.c:69
msgid "Files to exclude"
msgstr "Файлове за изключване"

#: app/flatpak-builtins-build-export.c:69
#: app/flatpak-builtins-build-export.c:70
#: app/flatpak-builtins-build-update-repo.c:90
msgid "PATTERN"
msgstr "ШАБЛОН"

#: app/flatpak-builtins-build-export.c:70
msgid "Excluded files to include"
msgstr "Изключени файлове за включване"

#: app/flatpak-builtins-build-export.c:74
msgid "Mark build as end-of-life, to be replaced with the given ID"
msgstr ""
"Отбелязване, че изграждането не получава обновления, за да се замени с "
"дадения идентификатор"

#: app/flatpak-builtins-build-export.c:74
#: app/flatpak-builtins-document-list.c:49 app/flatpak-cli-transaction.c:1427
msgid "ID"
msgstr "ИДЕНТИФИКАТОР"

#: app/flatpak-builtins-build-export.c:76
msgid "Override the timestamp of the commit"
msgstr "Заменяне на датата на подаването"

#: app/flatpak-builtins-build-export.c:77
#: app/flatpak-builtins-build-update-repo.c:75
#: app/flatpak-builtins-remote-add.c:83 app/flatpak-builtins-remote-list.c:54
#: app/flatpak-builtins-remote-modify.c:88
msgid "Collection ID"
msgstr "Идентификатор на колекцията"

#: app/flatpak-builtins-build-export.c:472
#, c-format
msgid "WARNING: Error running desktop-file-validate: %s\n"
msgstr "ВНИМАНИЕ: грешка при изпълняване на „desktop-file-validate“: %s\n"

#: app/flatpak-builtins-build-export.c:480
#, c-format
msgid "WARNING: Error reading from desktop-file-validate: %s\n"
msgstr "ВНИМАНИЕ: грешка при четене от „desktop-file-validate“: %s\n"

#: app/flatpak-builtins-build-export.c:486
#, c-format
msgid "WARNING: Failed to validate desktop file %s: %s\n"
msgstr "ВНИМАНИЕ: файла за работния плот %s не може да се провери: %s\n"

#: app/flatpak-builtins-build-export.c:513
#, c-format
msgid "WARNING: Can't find Exec key in %s: %s\n"
msgstr "ВНИМАНИЕ: Ключът „Exec“ в „%s“ липсва: %s\n"

#: app/flatpak-builtins-build-export.c:521
#: app/flatpak-builtins-build-export.c:614
#, c-format
msgid "WARNING: Binary not found for Exec line in %s: %s\n"
msgstr ""
"ВНИМАНИЕ: компилираната програма зададена в реда за изпълнение „%s“ липсва: "
"%s\n"

#: app/flatpak-builtins-build-export.c:529
#, c-format
msgid "WARNING: Icon not matching app id in %s: %s\n"
msgstr ""
"ВНИМАНИЕ: иконката не съвпада с идентификатора на програмата в %s: %s\n"

#: app/flatpak-builtins-build-export.c:552
#, c-format
msgid "WARNING: Icon referenced in desktop file but not exported: %s\n"
msgstr ""
"ВНИМАНИЕ: иконката е посочена във файла за работения плот, но не е изнесена: "
"%s\n"

#: app/flatpak-builtins-build-export.c:719
#, c-format
msgid "Invalid uri type %s, only http/https supported"
msgstr "Неправилен вид адрес „%s“, поддържат се само „http“/„https“"

#: app/flatpak-builtins-build-export.c:737
#, c-format
msgid "Unable to find basename in %s, specify a name explicitly"
msgstr "Основното име в %s не може да се намери, изрично посочете име"

#: app/flatpak-builtins-build-export.c:746
#, c-format
msgid "No slashes allowed in extra data name"
msgstr "Не са позволени наклонени черти в името на допълнителните данни"

#: app/flatpak-builtins-build-export.c:758
#, c-format
msgid "Invalid format for sha256 checksum: '%s'"
msgstr "Неправилен формат за  контролната сума SHA256: „%s“"

#: app/flatpak-builtins-build-export.c:768
#, c-format
msgid "Extra data sizes of zero not supported"
msgstr "Допълнителни размери на данните от нула не се поддържат"

#: app/flatpak-builtins-build-export.c:830
msgid ""
"LOCATION DIRECTORY [BRANCH] - Create a repository from a build directory"
msgstr ""
"МЕСТОПОЛОЖЕНИЕ ДИРЕКТОРИЯ [КЛОН] — създаване на хранилище от директория за "
"изграждане"

#: app/flatpak-builtins-build-export.c:838
msgid "LOCATION and DIRECTORY must be specified"
msgstr "МЕСТОПОЛОЖЕНИЕто И ДИРЕКТОРИЯта са задължителни"

#: app/flatpak-builtins-build-export.c:859
#: app/flatpak-builtins-remote-add.c:327
#, c-format
msgid "‘%s’ is not a valid collection ID: %s"
msgstr "„%s“ е неправилен идентификатор на колекция: %s"

#: app/flatpak-builtins-build-export.c:904
#: app/flatpak-builtins-build-finish.c:684
msgid "No name specified in the metadata"
msgstr "Няма посочено име в метаданните"

#: app/flatpak-builtins-build-export.c:1166
#, c-format
msgid "Commit: %s\n"
msgstr "Подаване: %s\n"

#: app/flatpak-builtins-build-export.c:1167
#, c-format
msgid "Metadata Total: %u\n"
msgstr "Общо метаданни: %u\n"

#: app/flatpak-builtins-build-export.c:1168
#, c-format
msgid "Metadata Written: %u\n"
msgstr "Записани метаданни: %u\n"

#: app/flatpak-builtins-build-export.c:1169
#, c-format
msgid "Content Total: %u\n"
msgstr "Общо съдържание: %u\n"

#: app/flatpak-builtins-build-export.c:1170
#, c-format
msgid "Content Written: %u\n"
msgstr "Записано съдържание: %u\n"

#: app/flatpak-builtins-build-export.c:1171
#, c-format
msgid "Content Bytes Written:"
msgstr "Записано съдържание в байтове:"

#: app/flatpak-builtins-build-finish.c:52
msgid "Command to set"
msgstr "Команда за задаване"

#: app/flatpak-builtins-build-finish.c:52 app/flatpak-builtins-run.c:159
#: app/flatpak-main.c:209
msgid "COMMAND"
msgstr "КОМАНДА"

#: app/flatpak-builtins-build-finish.c:53
msgid "Flatpak version to require"
msgstr "Версията на Flatpak, която да се изисква"

#: app/flatpak-builtins-build-finish.c:53
msgid "MAJOR.MINOR.MICRO"
msgstr "ОСНОВЕН.ДОПЪЛНИТЕЛЕН.МИКРО"

#: app/flatpak-builtins-build-finish.c:54
msgid "Don't process exports"
msgstr "Без обработване на изнесеното"

#: app/flatpak-builtins-build-finish.c:55
msgid "Extra data info"
msgstr "Допълнителни данни"

#: app/flatpak-builtins-build-finish.c:56 app/flatpak-builtins-build-init.c:63
msgid "Add extension point info"
msgstr "Добавяне на информация за точката на разширение"

#: app/flatpak-builtins-build-finish.c:56 app/flatpak-builtins-build-init.c:63
msgid "NAME=VARIABLE[=VALUE]"
msgstr "ИМЕ=ПРОМЕНЛИВА[=СТОЙНОСТ]"

#: app/flatpak-builtins-build-finish.c:57
msgid "Remove extension point info"
msgstr "Премахване на информация за точката на разширение"

#: app/flatpak-builtins-build-finish.c:57
#: app/flatpak-builtins-build-update-repo.c:79 app/flatpak-builtins-info.c:58
#: app/flatpak-builtins-remote-add.c:88 app/flatpak-builtins-remote-modify.c:94
#: app/flatpak-main.c:182
msgid "NAME"
msgstr "ИМЕ"

#: app/flatpak-builtins-build-finish.c:58
msgid "Set extension priority (only for extensions)"
msgstr "Задаване на приоритет на разширението (само за разширения)"

#: app/flatpak-builtins-build-finish.c:58
msgid "VALUE"
msgstr "СТОЙНОСТ"

#: app/flatpak-builtins-build-finish.c:59
msgid "Change the sdk used for the app"
msgstr "Променяне на SDK за програмата"

#: app/flatpak-builtins-build-finish.c:59
msgid "SDK"
msgstr "SDK"

#: app/flatpak-builtins-build-finish.c:60
msgid "Change the runtime used for the app"
msgstr "Променяне на средата за изпълнение за програмата"

#: app/flatpak-builtins-build-finish.c:60 app/flatpak-builtins-build-init.c:54
#: app/flatpak-builtins-list.c:53 app/flatpak-builtins-remote-ls.c:58
#: app/flatpak-builtins-run.c:163
msgid "RUNTIME"
msgstr "СРЕДА_ЗА_ИЗПЪЛНЕНИЕ"

#: app/flatpak-builtins-build-finish.c:61
msgid "Set generic metadata option"
msgstr "Задаване на обща опция за метаданни"

#: app/flatpak-builtins-build-finish.c:61
msgid "GROUP=KEY[=VALUE]"
msgstr "ГРУПА=КЛЮЧ[=СТОЙНОСТ]"

#: app/flatpak-builtins-build-finish.c:62
msgid "Don't inherit permissions from runtime"
msgstr "Без наследяване на права̀та от средата за изпълнение"

#: app/flatpak-builtins-build-finish.c:155
#, c-format
msgid "Not exporting %s, wrong extension\n"
msgstr "%s не може да се изнесе поради грешно разширение\n"

#: app/flatpak-builtins-build-finish.c:163
#, c-format
msgid "Not exporting %s, non-allowed export filename\n"
msgstr "%s не може да се изнесе поради непозволено име на файл за изнасяне\n"

#: app/flatpak-builtins-build-finish.c:167
#, c-format
msgid "Exporting %s\n"
msgstr "Изнасяне на %s\n"

#: app/flatpak-builtins-build-finish.c:440
#, c-format
msgid "More than one executable found\n"
msgstr "Намерен е повече от един изпълним файл\n"

#: app/flatpak-builtins-build-finish.c:451
#, c-format
msgid "Using %s as command\n"
msgstr "Използване на „%s“ като команда\n"

#: app/flatpak-builtins-build-finish.c:456
#, c-format
msgid "No executable found\n"
msgstr "Липсва изпълним файл\n"

#: app/flatpak-builtins-build-finish.c:511
#, c-format
msgid "Invalid --require-version argument: %s"
msgstr "Неправилен аргумент за „--require-version“: %s"

#: app/flatpak-builtins-build-finish.c:543
#, c-format
msgid "Too few elements in --extra-data argument %s"
msgstr "Твърде малко елементи в аргумента на „--extra-data“: %s"

#: app/flatpak-builtins-build-finish.c:575
#, c-format
msgid ""
"Too few elements in --metadata argument %s, format should be "
"GROUP=KEY[=VALUE]]"
msgstr ""
"Твърде малко елементи в аргумента на „--metadata“: %s, форматът трябва да е "
"ГРУПА=КЛЮЧ[=СТОЙНОСТ]]"

#: app/flatpak-builtins-build-finish.c:597
#: app/flatpak-builtins-build-init.c:458
#, c-format
msgid ""
"Too few elements in --extension argument %s, format should be "
"NAME=VAR[=VALUE]"
msgstr ""
"Твърде малко елементи в аргумента на „--extension“: %s, форматът трябва да е "
"ИМЕ=ПРОМЕНЛИВА[=СТОЙНОСТ]"

#: app/flatpak-builtins-build-finish.c:603
#: app/flatpak-builtins-build-init.c:461
#, c-format
msgid "Invalid extension name %s"
msgstr "Неправилно име на разширението „%s“"

#: app/flatpak-builtins-build-finish.c:646
msgid "DIRECTORY - Finalize a build directory"
msgstr "ДИРЕКТОРИЯ — завършване на директория за изграждане"

#: app/flatpak-builtins-build-finish.c:668
#, c-format
msgid "Build directory %s not initialized"
msgstr "Директорията за изграждане „%s“ не е инициализирана"

#: app/flatpak-builtins-build-finish.c:689
#, c-format
msgid "Build directory %s already finalized"
msgstr "Директорията за изграждане „%s“ вече е завършена"

#: app/flatpak-builtins-build-finish.c:702
#, c-format
msgid "Please review the exported files and the metadata\n"
msgstr "Прегледайте изнесените файлове и метаданните\n"

#: app/flatpak-builtins-build-import-bundle.c:47
msgid "Override the ref used for the imported bundle"
msgstr "Заменяне на указателя, използван за внесения пакет"

#: app/flatpak-builtins-build-import-bundle.c:47
msgid "REF"
msgstr "УКАЗАТЕЛ"

#: app/flatpak-builtins-build-import-bundle.c:48
msgid "Import oci image instead of flatpak bundle"
msgstr "Внасяне на образ във формат OCI вместо пакет на Flatpak"

#: app/flatpak-builtins-build-import-bundle.c:77
#: app/flatpak-builtins-build-import-bundle.c:105
#, c-format
msgid "Importing %s (%s)\n"
msgstr "Внасяне на %s (%s)\n"

#: app/flatpak-builtins-build-import-bundle.c:126
msgid "LOCATION FILENAME - Import a file bundle into a local repository"
msgstr ""
"МЕСТОПОЛОЖЕНИЕ ИМЕ_НА_ФАЙЛ — внасяне на пакет от файлове в локално хранилище"

#: app/flatpak-builtins-build-import-bundle.c:133
msgid "LOCATION and FILENAME must be specified"
msgstr "МЕСТОПОЛОЖЕНИЕ и ИМЕ НА ФАЙЛ трябва да се посочат"

#: app/flatpak-builtins-build-init.c:53 app/flatpak-builtins-info.c:55
#: app/flatpak-builtins-run.c:158
msgid "Arch to use"
msgstr "Архитектура за използване"

#: app/flatpak-builtins-build-init.c:54
msgid "Initialize var from named runtime"
msgstr "Иницииране на променлива от именувана среда за изпълнение"

#: app/flatpak-builtins-build-init.c:55
msgid "Initialize apps from named app"
msgstr "Иницииране на програми от именувана програма"

#: app/flatpak-builtins-build-init.c:55
msgid "APP"
msgstr "ПРОГРАМА"

#: app/flatpak-builtins-build-init.c:56
msgid "Specify version for --base"
msgstr "Задайте версия за „--base“"

#: app/flatpak-builtins-build-init.c:56 app/flatpak-builtins-run.c:164
msgid "VERSION"
msgstr "ВЕРСИЯ"

#: app/flatpak-builtins-build-init.c:57
msgid "Include this base extension"
msgstr "Включване на това базово разширение"

#: app/flatpak-builtins-build-init.c:57 app/flatpak-builtins-build-init.c:62
msgid "EXTENSION"
msgstr "РАЗШИРЕНИЕ"

#: app/flatpak-builtins-build-init.c:58
msgid "Extension tag to use if building extension"
msgstr ""
"Етикет за разширение, който да се използва при изграждане на разширение"

#: app/flatpak-builtins-build-init.c:58
msgid "EXTENSION_TAG"
msgstr "ЕТИКЕТ_НА_РАЗШИРЕНИЕ"

#: app/flatpak-builtins-build-init.c:59
msgid "Initialize /usr with a writable copy of the sdk"
msgstr "Инициализиране на „/usr“ с копие на SDK с права̀ за запис"

#: app/flatpak-builtins-build-init.c:60
msgid "Specify the build type (app, runtime, extension)"
msgstr ""
"Посочване на типа изграждане (програма, среда за изпълнение, разширение)"

#: app/flatpak-builtins-build-init.c:60
msgid "TYPE"
msgstr "ВИД"

#: app/flatpak-builtins-build-init.c:61
msgid "Add a tag"
msgstr "Добавяне на етикет"

#: app/flatpak-builtins-build-init.c:61
msgid "TAG"
msgstr "ЕТИКЕТ"

#: app/flatpak-builtins-build-init.c:62
msgid "Include this sdk extension in /usr"
msgstr "Включване на това разширение за SDK в „/usr“"

#: app/flatpak-builtins-build-init.c:64
msgid "Where to store sdk (defaults to 'usr')"
msgstr "Къде да се съхранява SDK (стандартно е „usr“)"

#: app/flatpak-builtins-build-init.c:65
msgid "Re-initialize the sdk/var"
msgstr "Повторно инициализиране на SDK/var"

#: app/flatpak-builtins-build-init.c:118
#, c-format
msgid "Requested extension %s/%s/%s is only partially installed"
msgstr "Заявеното разширение %s/%s/%s е само частично инсталирано"

#: app/flatpak-builtins-build-init.c:147
#, c-format
msgid "Requested extension %s/%s/%s not installed"
msgstr "Заявеното разширение %s/%s/%s не е инсталирано"

#: app/flatpak-builtins-build-init.c:207
msgid ""
"DIRECTORY APPNAME SDK RUNTIME [BRANCH] - Initialize a directory for building"
msgstr ""
"ДИРЕКТОРИЯ ИМЕ_НА_ПРОГРАМА SDK СРЕДА_ЗА_ИЗПЪЛНЕНИЕ [КЛОН] — инициализиране "
"на директория за изграждане"

#: app/flatpak-builtins-build-init.c:214
msgid "RUNTIME must be specified"
msgstr "СРЕДАта_ЗА_ИЗПЪЛНЕНИЕ трябва да се посочи"

#: app/flatpak-builtins-build-init.c:235
#, c-format
msgid "'%s' is not a valid build type name, use app, runtime or extension"
msgstr ""
"„%s“ не е правилно име на вид за изграждане, използвайте програма, среда за "
"изпълнение или разширение"

#: app/flatpak-builtins-build-init.c:241 app/flatpak-builtins-override.c:79
#, c-format
msgid "'%s' is not a valid application name: %s"
msgstr "„%s“ не е правилно име на програма: %s"

#: app/flatpak-builtins-build-init.c:295
#, c-format
msgid "Build directory %s already initialized"
msgstr "Директорията за изграждане „%s“ вече е инициализирана"

#: app/flatpak-builtins-build-sign.c:42 app/flatpak-builtins-install.c:67
#: app/flatpak-builtins-remote-info.c:54
msgid "Arch to install for"
msgstr "Архитектура, за която да се инсталира"

#: app/flatpak-builtins-build-sign.c:43 app/flatpak-builtins-create-usb.c:48
#: app/flatpak-builtins-install.c:74 app/flatpak-builtins-remote-info.c:56
#: app/flatpak-builtins-uninstall.c:58 app/flatpak-builtins-update.c:64
msgid "Look for runtime with the specified name"
msgstr "Търсене на среда за изпълнение с посоченото име"

#: app/flatpak-builtins-build-sign.c:66
msgid "LOCATION [ID [BRANCH]] - Sign an application or runtime"
msgstr ""
"МЕСТОПОЛОЖЕНИЕ [ИДЕНТИФИКАТОР [КЛОН]] — подписване на програма или среда за "
"изпълнение"

#: app/flatpak-builtins-build-sign.c:73
#: app/flatpak-builtins-build-update-repo.c:499
#: app/flatpak-builtins-remote-add.c:320 app/flatpak-builtins-repo.c:739
msgid "LOCATION must be specified"
msgstr "МЕСТОПОЛОЖЕНИЕто е задължително"

#: app/flatpak-builtins-build-sign.c:94
msgid "No gpg key ids specified"
msgstr "Няма посочени идентификатори на ключове за GPG"

#: app/flatpak-builtins-build-update-repo.c:68
msgid "Redirect this repo to a new URL"
msgstr "Пренасочване на това хранилище към нов адрес"

#: app/flatpak-builtins-build-update-repo.c:69
msgid "A nice name to use for this repository"
msgstr "Хубаво име, което да се използва за това хранилище"

#: app/flatpak-builtins-build-update-repo.c:69
#: app/flatpak-builtins-remote-add.c:77 app/flatpak-builtins-remote-modify.c:82
msgid "TITLE"
msgstr "ЗАГЛАВИЕ"

#: app/flatpak-builtins-build-update-repo.c:70
msgid "A one-line comment for this repository"
msgstr "Коментар от един ред за това хранилище"

#: app/flatpak-builtins-build-update-repo.c:70
#: app/flatpak-builtins-remote-add.c:78 app/flatpak-builtins-remote-modify.c:83
msgid "COMMENT"
msgstr "КОМЕНТАР"

#: app/flatpak-builtins-build-update-repo.c:71
msgid "A full-paragraph description for this repository"
msgstr "Пълно описание за това хранилище"

#: app/flatpak-builtins-build-update-repo.c:71
#: app/flatpak-builtins-remote-add.c:79 app/flatpak-builtins-remote-modify.c:84
msgid "DESCRIPTION"
msgstr "ОПИСАНИЕ"

#: app/flatpak-builtins-build-update-repo.c:72
msgid "URL for a website for this repository"
msgstr "Адрес за уеб страница за това хранилище"

#: app/flatpak-builtins-build-update-repo.c:73
msgid "URL for an icon for this repository"
msgstr "Адрес за икона за това хранилище"

#: app/flatpak-builtins-build-update-repo.c:74
msgid "Default branch to use for this repository"
msgstr "Стандартен клон, който да се използва за това хранилище"

#: app/flatpak-builtins-build-update-repo.c:74
#: app/flatpak-builtins-remote-add.c:82 app/flatpak-builtins-remote-modify.c:87
#: app/flatpak-builtins-repo.c:713 app/flatpak-builtins-repo.c:714
#: app/flatpak-builtins-run.c:161
msgid "BRANCH"
msgstr "КЛОН"

#: app/flatpak-builtins-build-update-repo.c:75
#: app/flatpak-builtins-remote-add.c:83 app/flatpak-builtins-remote-modify.c:88
msgid "COLLECTION-ID"
msgstr "ИД_КОЛЕКЦИЯ"

#. Translators: A sideload is when you install from a local USB drive rather than the Internet.
#: app/flatpak-builtins-build-update-repo.c:77
msgid ""
"Permanently deploy collection ID to client remote configurations, only for "
"sideload support"
msgstr ""
"Качване на идентификатора на колекцията в клиентските отдалечени настройки "
"за постоянно, само за локално зареждане (sideload)"

#: app/flatpak-builtins-build-update-repo.c:78
msgid "Permanently deploy collection ID to client remote configurations"
msgstr ""
"Качване на идентификатора на колекцията в клиентските отдалечени настройки "
"за постоянно"

#: app/flatpak-builtins-build-update-repo.c:79
msgid "Name of authenticator for this repository"
msgstr "Име на удостоверител за това хранилище"

#: app/flatpak-builtins-build-update-repo.c:80
msgid "Autoinstall authenticator for this repository"
msgstr "Автоматично инсталиране на удостоверител за това хранилище"

#: app/flatpak-builtins-build-update-repo.c:81
msgid "Don't autoinstall authenticator for this repository"
msgstr "Без автоматично инсталиране на удостоверител за това хранилище"

#: app/flatpak-builtins-build-update-repo.c:82
#: app/flatpak-builtins-remote-add.c:89
msgid "Authenticator option"
msgstr "Опция за удостоверител"

#: app/flatpak-builtins-build-update-repo.c:82
#: app/flatpak-builtins-remote-add.c:89 app/flatpak-builtins-remote-modify.c:95
msgid "KEY=VALUE"
msgstr "КЛЮЧ=СТОЙНОСТ"

#: app/flatpak-builtins-build-update-repo.c:83
msgid "Import new default GPG public key from FILE"
msgstr "Внасяне на нов стандартен публичен GPG ключ от ФАЙЛ"

#: app/flatpak-builtins-build-update-repo.c:84
msgid "GPG Key ID to sign the summary with"
msgstr "Идентификаторът на GPG ключ, с който да се подпише обобщението"

#: app/flatpak-builtins-build-update-repo.c:86
msgid "Generate delta files"
msgstr "Генериране на файлове за разлики"

#: app/flatpak-builtins-build-update-repo.c:88
msgid "Don't update the appstream branch"
msgstr "Без обновяване на клона за appstream"

#: app/flatpak-builtins-build-update-repo.c:89
msgid "Max parallel jobs when creating deltas (default: NUMCPUs)"
msgstr ""
"Максимален брой паралелни задачи при създаване на разлики (стандартно: брой "
"на процесорните ядра)"

#: app/flatpak-builtins-build-update-repo.c:89
msgid "NUM-JOBS"
msgstr "БРОЙ_ЗАДАЧИ"

#: app/flatpak-builtins-build-update-repo.c:90
msgid "Don't create deltas matching refs"
msgstr "Без създаване на разлики, съответстващи на указатели"

#: app/flatpak-builtins-build-update-repo.c:91
msgid "Prune unused objects"
msgstr "Окастряне на неизползваните обекти"

#: app/flatpak-builtins-build-update-repo.c:92
msgid "Prune but don't actually remove anything"
msgstr "Окастряне, но без премахване на нищо"

#: app/flatpak-builtins-build-update-repo.c:93
msgid "Only traverse DEPTH parents for each commit (default: -1=infinite)"
msgstr ""
"Обхождане само на родителите до тази ДЪЛБОЧИНА за всяко подаване "
"(стандартно: -1=безкрайно)"

#: app/flatpak-builtins-build-update-repo.c:93
msgid "DEPTH"
msgstr "ДЪЛБОЧИНА"

#: app/flatpak-builtins-build-update-repo.c:223
#, c-format
msgid "Generating delta: %s (%.10s)\n"
msgstr "Генериране на разликите: %s (%.10s)\n"

#: app/flatpak-builtins-build-update-repo.c:225
#, c-format
msgid "Generating delta: %s (%.10s-%.10s)\n"
msgstr "Генериране на разликите: %s (%.10s-%.10s)\n"

#: app/flatpak-builtins-build-update-repo.c:233
#, c-format
msgid "Failed to generate delta %s (%.10s): "
msgstr "Разликите не може да се генерират %s (%.10s): "

#: app/flatpak-builtins-build-update-repo.c:236
#, c-format
msgid "Failed to generate delta %s (%.10s-%.10s): "
msgstr "Разликите не може да се генерират %s (%.10s-%.10s): "

#: app/flatpak-builtins-build-update-repo.c:492
msgid "LOCATION - Update repository metadata"
msgstr "МЕСТОПОЛОЖЕНИЕ — обновяване на метаданните на хранилището"

#: app/flatpak-builtins-build-update-repo.c:609
#, c-format
msgid "Updating appstream branch\n"
msgstr "Обновяване на клона на appstream\n"

#: app/flatpak-builtins-build-update-repo.c:638
#, c-format
msgid "Updating summary\n"
msgstr "Обновяване на обобщението\n"

#: app/flatpak-builtins-build-update-repo.c:664
#, c-format
msgid "Total objects: %u\n"
msgstr "Общ брой обекти: %u\n"

#: app/flatpak-builtins-build-update-repo.c:666
#, c-format
msgid "No unreachable objects\n"
msgstr "Няма недостъпни обекти\n"

#: app/flatpak-builtins-build-update-repo.c:668
#, c-format
msgid "Deleted %u objects, %s freed\n"
msgstr "Изтрити са %u обекта, освободени са %s\n"

#: app/flatpak-builtins-config.c:41
msgid "List configuration keys and values"
msgstr "Изброяване на ключовете и стойностите за настройката"

#: app/flatpak-builtins-config.c:42
msgid "Get configuration for KEY"
msgstr "Получаване на настройката за КЛЮЧ"

#: app/flatpak-builtins-config.c:43
msgid "Set configuration for KEY to VALUE"
msgstr "Задаване на настройката за КЛЮЧ към СТОЙНОСТ"

#: app/flatpak-builtins-config.c:44
msgid "Unset configuration for KEY"
msgstr "Премахване на настройката за КЛЮЧ"

#: app/flatpak-builtins-config.c:149
#, c-format
msgid "'%s' does not look like a language/locale code"
msgstr "„%s“ не изглежда да е код на език/локал"

#: app/flatpak-builtins-config.c:172
#, c-format
msgid "'%s' does not look like a language code"
msgstr "„%s“ не изглежда да е код на език"

#: app/flatpak-builtins-config.c:190
#, fuzzy, c-format
msgid "'%s' is not a valid value (use 'true' or 'false')"
msgstr "„%s“ е неправилно хранилище: "

#: app/flatpak-builtins-config.c:262
#, c-format
msgid "Unknown configure key '%s'"
msgstr "Неизвестен ключ „%s“ за настройване"

#: app/flatpak-builtins-config.c:284
msgid "Too many arguments for --list"
msgstr "Прекалено много аргументи за „--list“"

#: app/flatpak-builtins-config.c:314 app/flatpak-builtins-config.c:362
msgid "You must specify KEY"
msgstr "Трябва да посочите КЛЮЧ"

#: app/flatpak-builtins-config.c:316
msgid "Too many arguments for --get"
msgstr "Прекалено много аргументи за „--get“"

#: app/flatpak-builtins-config.c:338
msgid "You must specify KEY and VALUE"
msgstr "Трябва да посочите КЛЮЧ и СТОЙНОСТ"

#: app/flatpak-builtins-config.c:340
msgid "Too many arguments for --set"
msgstr "Прекалено много аргументи за „--set“"

#: app/flatpak-builtins-config.c:364
msgid "Too many arguments for --unset"
msgstr "Прекалено много аргументи за „--unset“"

#: app/flatpak-builtins-config.c:383
msgid "[KEY [VALUE]] - Manage configuration"
msgstr "[КЛЮЧ [СТОЙНОСТ]] — управление на настройката"

#: app/flatpak-builtins-config.c:394
msgid "Can only use one of --list, --get, --set or --unset"
msgstr ""
"Може да се използва само една от опциите „--list“, „--get“, „--set“ или „--"
"unset“"

#: app/flatpak-builtins-config.c:408
msgid "Must specify one of --list, --get, --set or --unset"
msgstr ""
"Трябва да се посочи една от опциите „--list“, „--get“, „--set“ или „--unset“"

#: app/flatpak-builtins-create-usb.c:45 app/flatpak-builtins-install.c:75
#: app/flatpak-builtins-remote-info.c:57 app/flatpak-builtins-uninstall.c:59
#: app/flatpak-builtins-update.c:65
msgid "Look for app with the specified name"
msgstr "Търсене на програма с посоченото име"

#: app/flatpak-builtins-create-usb.c:46
msgid "Arch to copy"
msgstr "Архитектура за копиране"

#: app/flatpak-builtins-create-usb.c:47
msgid "DEST"
msgstr "ЦЕЛ"

#: app/flatpak-builtins-create-usb.c:49
msgid "Allow partial commits in the created repo"
msgstr "Позволяване на частични подавания в създаденото хранилище"

#: app/flatpak-builtins-create-usb.c:125 app/flatpak-builtins-create-usb.c:165
#, c-format
msgid ""
"Warning: Related ref ‘%s’ is partially installed. Use --allow-partial to "
"suppress this message.\n"
msgstr ""
"ВНИМАНИЕ: сродният указател „%s“ е частично инсталиран. Използвайте „--allow-"
"partial“, за да спрете това съобщение.\n"

#: app/flatpak-builtins-create-usb.c:158
#, c-format
msgid "Warning: Omitting related ref ‘%s’ because it is not installed.\n"
msgstr ""
"ВНИМАНИЕ: пропускане на сродния указател „%s“, защото не е инсталиран.\n"

#: app/flatpak-builtins-create-usb.c:175
#, c-format
msgid ""
"Warning: Omitting related ref ‘%s’ because its remote ‘%s’ does not have a "
"collection ID set.\n"
msgstr ""
"ВНИМАНИЕ: пропускане на сродния указател „%s“, защото отдалеченото му "
"хранилище „%s“ няма зададен идентификатор на колекция.\n"

#: app/flatpak-builtins-create-usb.c:187
#, c-format
msgid "Warning: Omitting related ref ‘%s’ because it's extra-data.\n"
msgstr ""
"ВНИМАНИЕ: пропускане на сродния указател „%s“, защото е за допълнителни "
"данни.\n"

#: app/flatpak-builtins-create-usb.c:262 app/flatpak-builtins-create-usb.c:637
#, c-format
msgid ""
"Remote ‘%s’ does not have a collection ID set, which is required for P2P "
"distribution of ‘%s’."
msgstr ""
"Отдалеченото хранилище „%s“ няма зададен идентификатор на колекция, който се "
"изисква за разпространение на „%s“ чрез равноправна връзка."

#: app/flatpak-builtins-create-usb.c:272
#, c-format
msgid "Warning: Omitting ref ‘%s’ (runtime of ‘%s’) because it's extra-data.\n"
msgstr ""
"ВНИМАНИЕ: пропускане на указателя „%s“ (среда за изпълнение на „%s“), защото "
"е за допълнителни данни.\n"

#: app/flatpak-builtins-create-usb.c:484
msgid "MOUNT-PATH [REF…] - Copy apps or runtimes onto removable media"
msgstr ""
"ПЪТ_ЗА_МОНТИРАНЕ [УКАЗАТЕЛ…] — копиране на програми или среди за изпълнение "
"на преносимо устройство"

#: app/flatpak-builtins-create-usb.c:493
msgid "MOUNT-PATH and REF must be specified"
msgstr "ПЪТят_ЗА_МОНТИРАНЕ и УКАЗАТЕЛят са задължителни"

#: app/flatpak-builtins-create-usb.c:607
#, c-format
msgid "Ref ‘%s’ found in multiple installations: %s. You must specify one."
msgstr ""
"Указателят „%s“ е намерен в няколко инсталации: %s. Трябва да посочите само "
"една."

#: app/flatpak-builtins-create-usb.c:620
#, c-format
msgid "Refs must all be in the same installation (found in %s and %s)."
msgstr ""
"Всички указатели трябва да са в една и съща инсталация (намират се в %s и "
"%s)."

#: app/flatpak-builtins-create-usb.c:670
#, c-format
msgid ""
"Warning: Ref ‘%s’ is partially installed. Use --allow-partial to suppress "
"this message.\n"
msgstr ""
"ВНИМАНИЕ: указателят „%s“ е частично инсталиран. Използвайте „--allow-"
"partial“, за да спрете това съобщение.\n"

#: app/flatpak-builtins-create-usb.c:681
#, c-format
msgid "Installed ref ‘%s’ is extra-data, and cannot be distributed offline"
msgstr ""
"Инсталираният указател „%s“ е за допълнителните данни и не може да се "
"разпространява"

#: app/flatpak-builtins-create-usb.c:721
#, c-format
msgid "Warning: Couldn't update repo metadata for remote ‘%s’: %s\n"
msgstr ""
"ВНИМАНИЕ: метаданните за отдалеченото хранилище „%s“ не може да се обновят: "
"%s\n"

#: app/flatpak-builtins-create-usb.c:751
#, c-format
msgid "Warning: Couldn't update appstream data for remote ‘%s’ arch ‘%s’: %s\n"
msgstr ""
"ВНИМАНИЕ: данните за appstream за отдалеченото хранилище „%s“ за архитектура "
"„%s“ не може да се обновят: %s\n"

#. Print a warning if both appstream and appstream2 are missing
#: app/flatpak-builtins-create-usb.c:784
#, c-format
msgid ""
"Warning: Couldn't find appstream data for remote ‘%s’ arch ‘%s’: %s; %s\n"
msgstr ""
"ВНИМАНИЕ: данните за appstream за отдалеченото хранилище „%s“ за архитектура "
"„%s“ липсват: %s; %s\n"

#. Appstream2 is only for efficiency, so just print a debug message
#: app/flatpak-builtins-create-usb.c:790
#, c-format
msgid "Couldn't find appstream2 data for remote ‘%s’ arch ‘%s’: %s\n"
msgstr ""
"Данните за appstream2 за отдалеченото хранилище „%s“ за архитектура „%s“ "
"липсват: %s\n"

#: app/flatpak-builtins-document-export.c:62
msgid "Create a unique document reference"
msgstr "Създаване на уникален указател на документа"

#: app/flatpak-builtins-document-export.c:63
msgid "Make the document transient for the current session"
msgstr "Документът да е временен за текущата сесия"

#: app/flatpak-builtins-document-export.c:64
msgid "Don't require the file to exist already"
msgstr "Без изискване файлът вече да съществува"

#: app/flatpak-builtins-document-export.c:65
msgid "Give the app read permissions"
msgstr "Даване на програмата права̀ за четене"

#: app/flatpak-builtins-document-export.c:66
msgid "Give the app write permissions"
msgstr "Даване на програмата права̀ за записване"

#: app/flatpak-builtins-document-export.c:67
msgid "Give the app delete permissions"
msgstr "Даване на програмата права̀ за изтриване"

#: app/flatpak-builtins-document-export.c:68
msgid "Give the app permissions to grant further permissions"
msgstr "Дайте на програмата права̀ да позволява допълнителни права̀"

#: app/flatpak-builtins-document-export.c:69
msgid "Revoke read permissions of the app"
msgstr "Премахване на права̀та за четене на програмата"

#: app/flatpak-builtins-document-export.c:70
msgid "Revoke write permissions of the app"
msgstr "Премахване на права̀та за записване на програмата"

#: app/flatpak-builtins-document-export.c:71
msgid "Revoke delete permissions of the app"
msgstr "Премахване на права̀та за изтриване на програмата"

#: app/flatpak-builtins-document-export.c:72
msgid "Revoke the permission to grant further permissions"
msgstr "Премахване на права̀та на програмата да позволява допълнителни права̀"

#: app/flatpak-builtins-document-export.c:73
msgid "Add permissions for this app"
msgstr "Добавяне на права̀ за тази програма"

#: app/flatpak-builtins-document-export.c:73
msgid "APPID"
msgstr "ИД_НА_ПРОГРАМА"

#: app/flatpak-builtins-document-export.c:100
msgid "FILE - Export a file to apps"
msgstr "ФАЙЛ — изнасяне на файл към програми"

#: app/flatpak-builtins-document-export.c:109
#: app/flatpak-builtins-document-info.c:72
#: app/flatpak-builtins-document-unexport.c:67
msgid "FILE must be specified"
msgstr "ФАЙЛът е задължителен"

#: app/flatpak-builtins-document-info.c:63
msgid "FILE - Get information about an exported file"
msgstr "ФАЙЛ — получаване на информация за изнесен файл"

#: app/flatpak-builtins-document-info.c:100
#: app/flatpak-builtins-document-unexport.c:94
#, c-format
msgid "Not exported\n"
msgstr "Не е изнесено\n"

#: app/flatpak-builtins-document-list.c:43 app/flatpak-builtins-history.c:53
#: app/flatpak-builtins-list.c:54 app/flatpak-builtins-ps.c:43
#: app/flatpak-builtins-remote-list.c:45 app/flatpak-builtins-remote-ls.c:59
#: app/flatpak-builtins-search.c:38
msgid "What information to show"
msgstr "Каква информация да се покаже"

#: app/flatpak-builtins-document-list.c:43 app/flatpak-builtins-history.c:53
#: app/flatpak-builtins-list.c:54 app/flatpak-builtins-ps.c:43
#: app/flatpak-builtins-remote-list.c:45 app/flatpak-builtins-remote-ls.c:59
#: app/flatpak-builtins-search.c:38
msgid "FIELD,…"
msgstr "ПОЛЕ,…"

#: app/flatpak-builtins-document-list.c:44 app/flatpak-builtins-history.c:54
#: app/flatpak-builtins-list.c:52 app/flatpak-builtins-permission-list.c:43
#: app/flatpak-builtins-permission-show.c:43 app/flatpak-builtins-ps.c:44
#: app/flatpak-builtins-remote-list.c:46 app/flatpak-builtins-remote-ls.c:63
#: app/flatpak-builtins-repo.c:717 app/flatpak-builtins-search.c:39
#, fuzzy
msgid "Show output in JSON format"
msgstr "Извеждане на допълнителна информация"

#: app/flatpak-builtins-document-list.c:49
msgid "Show the document ID"
msgstr "Извеждане на идентификатора на документа"

#: app/flatpak-builtins-document-list.c:50
msgid "Path"
msgstr "Път"

#: app/flatpak-builtins-document-list.c:50
#: app/flatpak-builtins-document-list.c:51
msgid "Show the document path"
msgstr "Извеждане на пътя към документа"

#: app/flatpak-builtins-document-list.c:51 app/flatpak-builtins-list.c:66
#: app/flatpak-builtins-remote-ls.c:74
msgid "Origin"
msgstr "Отправна точка"

#: app/flatpak-builtins-document-list.c:52 app/flatpak-builtins-history.c:62
#: app/flatpak-builtins-ps.c:52
msgid "Application"
msgstr "Програма"

#: app/flatpak-builtins-document-list.c:52
msgid "Show applications with permission"
msgstr "Извеждане на програмите с права̀"

#: app/flatpak-builtins-document-list.c:53
#: app/flatpak-builtins-permission-list.c:182
#: app/flatpak-builtins-permission-show.c:145
msgid "Permissions"
msgstr "Права̀"

#: app/flatpak-builtins-document-list.c:53
msgid "Show permissions for applications"
msgstr "Извеждане на права̀та за програми"

#: app/flatpak-builtins-document-list.c:161
#, fuzzy, c-format
msgid "No documents found\n"
msgstr "Няма намерени съвпадения"

#: app/flatpak-builtins-document-list.c:180
msgid "[APPID] - List exported files"
msgstr "[ИД_НА_ПРОГРАМА] — изброяване на изнесените файлове"

#: app/flatpak-builtins-document-unexport.c:43
msgid "Specify the document ID"
msgstr "Посочване на идентификатора на документа"

#: app/flatpak-builtins-document-unexport.c:58
msgid "FILE - Unexport a file to apps"
msgstr "ФАЙЛ — премахване на файл от програми"

#: app/flatpak-builtins-enter.c:88
msgid "INSTANCE COMMAND [ARGUMENT…] - Run a command inside a running sandbox"
msgstr ""
"ИНСТАНЦИЯ КОМАНДА [АРГУМЕНТ…] — изпълняване на команда в работеща ограничена "
"среда"

#: app/flatpak-builtins-enter.c:111
msgid "INSTANCE and COMMAND must be specified"
msgstr "ИНСТАНЦИЯ и КОМАНДА са задължителни"

#: app/flatpak-builtins-enter.c:138
#, c-format
msgid "%s is neither a pid nor an application or instance ID"
msgstr "%s не е нито ид. на процес, нито ид. на програма или инстанция"

#: app/flatpak-builtins-enter.c:144
msgid "entering not supported (need unprivileged user namespaces, or sudo -E)"
msgstr ""
"въвеждането не е позволено (необходими са пространства от имена за "
"непривилегировани потребители, или „sudo -E“)"

#: app/flatpak-builtins-enter.c:145
#, c-format
msgid "No such pid %s"
msgstr "Няма процес с такъв идентификатор %s"

#: app/flatpak-builtins-enter.c:158
msgid "Can't read cwd"
msgstr "Текущият път от „cwd“ не може да се разчете"

#: app/flatpak-builtins-enter.c:163
msgid "Can't read root"
msgstr "Главната директория не може да се разчете"

#: app/flatpak-builtins-enter.c:191
#, c-format
msgid "Invalid %s namespace for pid %d"
msgstr "Пространството от имена %s за ид. пр. %d е неправилно"

#: app/flatpak-builtins-enter.c:202
#, c-format
msgid "Invalid %s namespace for self"
msgstr "Пространството от имена %s за себе си е неправилно"

#: app/flatpak-builtins-enter.c:216
#, c-format
msgid "Can't open %s namespace: %s"
msgstr "Пространството от имена %s не може да се отвори: %s"

#: app/flatpak-builtins-enter.c:226
msgid "entering not supported (need unprivileged user namespaces)"
msgstr ""
"въвеждането не е позволено (необходими са пространства от имена за "
"непривилегировани потребители)"

#: app/flatpak-builtins-enter.c:227
#, c-format
msgid "Can't enter %s namespace: %s"
msgstr "Пространството от имена %s не може да се въведе: %s"

#: app/flatpak-builtins-enter.c:234
msgid "Can't chdir"
msgstr "Неуспешно влизане в директорията"

#: app/flatpak-builtins-enter.c:237
msgid "Can't chroot"
msgstr "Началната директория не може да се промени"

#: app/flatpak-builtins-enter.c:240
msgid "Can't switch gid"
msgstr "Невъзможна смяна на идентификатора на група"

#: app/flatpak-builtins-enter.c:243
msgid "Can't switch uid"
msgstr "Невъзможна смяна на идентификатора на потребител"

#: app/flatpak-builtins-history.c:50
msgid "Only show changes after TIME"
msgstr "Показване на промените само след ВРЕМЕ"

#: app/flatpak-builtins-history.c:50 app/flatpak-builtins-history.c:51
msgid "TIME"
msgstr "ВРЕМЕ"

#: app/flatpak-builtins-history.c:51
msgid "Only show changes before TIME"
msgstr "Показване на промените само преди ВРЕМЕ"

#: app/flatpak-builtins-history.c:52
msgid "Show newest entries first"
msgstr "Първо извеждане на най-новите записи"

#: app/flatpak-builtins-history.c:59
msgid "Time"
msgstr "Време"

#: app/flatpak-builtins-history.c:59
msgid "Show when the change happened"
msgstr "Показване кога е направена промяната"

#: app/flatpak-builtins-history.c:60
msgid "Change"
msgstr "Промяна"

#: app/flatpak-builtins-history.c:60
msgid "Show the kind of change"
msgstr "Извеждане на вида на промяната"

#: app/flatpak-builtins-history.c:61 app/flatpak-builtins-list.c:68
#: app/flatpak-builtins-remote-ls.c:75 app/flatpak-builtins-repo.c:335
msgid "Ref"
msgstr "Указател"

#: app/flatpak-builtins-history.c:61 app/flatpak-builtins-list.c:68
#: app/flatpak-builtins-remote-ls.c:75
msgid "Show the ref"
msgstr "Извеждане на указателя"

#: app/flatpak-builtins-history.c:62
msgid "Show the application/runtime ID"
msgstr "Извеждане на идентификатора на програмата/средата за изпълнение"

#: app/flatpak-builtins-history.c:63 app/flatpak-builtins-list.c:64
#: app/flatpak-builtins-ps.c:53 app/flatpak-builtins-remote-ls.c:73
#: app/flatpak-cli-transaction.c:1435
msgid "Arch"
msgstr "Архитектура"

#: app/flatpak-builtins-history.c:63 app/flatpak-builtins-list.c:64
#: app/flatpak-builtins-ps.c:53 app/flatpak-builtins-remote-ls.c:73
msgid "Show the architecture"
msgstr "Извеждане на архитектурата"

#: app/flatpak-builtins-history.c:64 app/flatpak-builtins-list.c:63
#: app/flatpak-builtins-ps.c:54 app/flatpak-builtins-remote-ls.c:72
#: app/flatpak-builtins-search.c:48 app/flatpak-cli-transaction.c:1438
msgid "Branch"
msgstr "Клон"

#: app/flatpak-builtins-history.c:64 app/flatpak-builtins-list.c:63
#: app/flatpak-builtins-remote-ls.c:72
msgid "Show the branch"
msgstr "Извеждане на клона"

#: app/flatpak-builtins-history.c:65 app/flatpak-builtins-list.c:67
msgid "Installation"
msgstr "Инсталация"

#: app/flatpak-builtins-history.c:65
msgid "Show the affected installation"
msgstr "Извеждане на засегнатата инсталация"

#: app/flatpak-builtins-history.c:66 app/flatpak-cli-transaction.c:1452
msgid "Remote"
msgstr "Отдалечено хранилище"

#: app/flatpak-builtins-history.c:66
msgid "Show the remote"
msgstr "Извеждане на отдалеченото хранилище"

#: app/flatpak-builtins-history.c:67 app/flatpak-builtins-ps.c:55
#: app/flatpak-builtins-remote-ls.c:76
msgid "Commit"
msgstr "Подаване"

#: app/flatpak-builtins-history.c:67
msgid "Show the current commit"
msgstr "Извеждане на текущото подаване"

#: app/flatpak-builtins-history.c:68
msgid "Old Commit"
msgstr "Старо подаване"

#: app/flatpak-builtins-history.c:68
msgid "Show the previous commit"
msgstr "Извеждане на предишното подаване"

#: app/flatpak-builtins-history.c:69
msgid "Show the remote URL"
msgstr "Извеждане на адреса на отдалеченото хранилище"

#: app/flatpak-builtins-history.c:70 app/flatpak-cli-transaction.c:700
msgid "User"
msgstr "Потребител"

#: app/flatpak-builtins-history.c:70
msgid "Show the user doing the change"
msgstr "Извеждане на потребителя, който прави промяната"

#: app/flatpak-builtins-history.c:71
msgid "Tool"
msgstr "Инструмент"

#: app/flatpak-builtins-history.c:71
msgid "Show the tool that was used"
msgstr "Извеждане на използвания инструмент"

#: app/flatpak-builtins-history.c:72 app/flatpak-builtins-list.c:62
#: app/flatpak-builtins-remote-ls.c:71 app/flatpak-builtins-search.c:47
msgid "Version"
msgstr "Версия"

#: app/flatpak-builtins-history.c:72
msgid "Show the Flatpak version"
msgstr "Извеждане на версията на Flatpak"

#: app/flatpak-builtins-history.c:91
#, c-format
msgid "Failed to get journal data (%s): %s"
msgstr "Данните от журнала не може да се получат (%s): %s"

#: app/flatpak-builtins-history.c:146
#, c-format
msgid "Failed to open journal: %s"
msgstr "Журналът не може да се отвори: %s"

#: app/flatpak-builtins-history.c:153
#, c-format
msgid "Failed to add match to journal: %s"
msgstr "Съвпадението не може да се добави в журнала: %s"

#: app/flatpak-builtins-history.c:471
msgid " - Show history"
msgstr " — извеждане на историята"

#: app/flatpak-builtins-history.c:490
#, c-format
msgid "Failed to parse the --since option"
msgstr "Опцията „--since“ не може да се разчете"

#: app/flatpak-builtins-history.c:501
#, c-format
msgid "Failed to parse the --until option"
msgstr "Опцията „--until“ не може да се разчете"

#: app/flatpak-builtins-info.c:56
msgid "Show user installations"
msgstr "Показване на потребителските инсталации"

#: app/flatpak-builtins-info.c:57
msgid "Show system-wide installations"
msgstr "Показване на системните инсталации"

#: app/flatpak-builtins-info.c:58
msgid "Show specific system-wide installations"
msgstr "Показване на конкретни системните инсталации"

#: app/flatpak-builtins-info.c:59 app/flatpak-builtins-remote-info.c:59
msgid "Show ref"
msgstr "Показване на указателя"

#: app/flatpak-builtins-info.c:60 app/flatpak-builtins-remote-info.c:60
msgid "Show commit"
msgstr "Извеждане на подаването"

#: app/flatpak-builtins-info.c:61
msgid "Show origin"
msgstr "Показване на отправната точка"

#: app/flatpak-builtins-info.c:62
msgid "Show size"
msgstr "Извеждане на размера"

#: app/flatpak-builtins-info.c:63 app/flatpak-builtins-remote-info.c:62
msgid "Show metadata"
msgstr "Извеждане на метаданните"

#: app/flatpak-builtins-info.c:64 app/flatpak-builtins-remote-info.c:63
msgid "Show runtime"
msgstr "Извеждане на средата за изпълнение"

#: app/flatpak-builtins-info.c:65 app/flatpak-builtins-remote-info.c:64
msgid "Show sdk"
msgstr "Извеждане на SDK"

#: app/flatpak-builtins-info.c:66
msgid "Show permissions"
msgstr "Извеждане на права̀та"

#: app/flatpak-builtins-info.c:67
msgid "Query file access"
msgstr "Запитване за достъп до файлове"

#: app/flatpak-builtins-info.c:67 app/flatpak-builtins-install.c:82
#: app/flatpak-builtins-install.c:88 app/flatpak-builtins-preinstall.c:68
#: app/flatpak-builtins-run.c:182 app/flatpak-builtins-run.c:184
#: app/flatpak-builtins-update.c:67 app/flatpak-builtins-update.c:71
msgid "PATH"
msgstr "ПЪТ"

#: app/flatpak-builtins-info.c:68
msgid "Show extensions"
msgstr "Извеждане на разширенията"

#: app/flatpak-builtins-info.c:69
msgid "Show location"
msgstr "Извеждане на местоположението"

#: app/flatpak-builtins-info.c:116
msgid "NAME [BRANCH] - Get info about an installed app or runtime"
msgstr ""
"ИМЕ [КЛОН] — получаване на информация относно инсталирана програма или среда "
"за изпълнение"

#: app/flatpak-builtins-info.c:123 app/flatpak-builtins-remote-add.c:317
#: app/flatpak-builtins-remote-delete.c:63
msgid "NAME must be specified"
msgstr "ИМЕто е задължително"

#: app/flatpak-builtins-info.c:196
msgid "ref not present in origin"
msgstr "указателят липсва в оригиналното хранилище"

#: app/flatpak-builtins-info.c:211 app/flatpak-builtins-remote-info.c:217
#, c-format
msgid "Warning: Commit has no flatpak metadata\n"
msgstr "ВНИМАНИЕ: подаването няма метаданни за Flatpak\n"

#: app/flatpak-builtins-info.c:217 app/flatpak-builtins-info.c:259
#: app/flatpak-builtins-info.c:455 app/flatpak-builtins-info.c:513
#: app/flatpak-builtins-remote-info.c:236
#: app/flatpak-builtins-remote-info.c:271
msgid "ID:"
msgstr "Идентификатор:"

#: app/flatpak-builtins-info.c:218 app/flatpak-builtins-info.c:260
#: app/flatpak-builtins-remote-info.c:237
#: app/flatpak-builtins-remote-info.c:272
msgid "Ref:"
msgstr "Указател:"

#: app/flatpak-builtins-info.c:219 app/flatpak-builtins-info.c:261
#: app/flatpak-builtins-remote-info.c:238
#: app/flatpak-builtins-remote-info.c:273
msgid "Arch:"
msgstr "Архитектура:"

#: app/flatpak-builtins-info.c:220 app/flatpak-builtins-info.c:262
#: app/flatpak-builtins-remote-info.c:239
#: app/flatpak-builtins-remote-info.c:274
msgid "Branch:"
msgstr "Клон:"

#: app/flatpak-builtins-info.c:222 app/flatpak-builtins-info.c:264
#: app/flatpak-builtins-remote-info.c:241
#: app/flatpak-builtins-remote-info.c:276
msgid "Version:"
msgstr "Версия:"

#: app/flatpak-builtins-info.c:224 app/flatpak-builtins-info.c:266
#: app/flatpak-builtins-remote-info.c:243
#: app/flatpak-builtins-remote-info.c:278
msgid "License:"
msgstr "Лиценз:"

#: app/flatpak-builtins-info.c:226 app/flatpak-builtins-info.c:269
#: app/flatpak-builtins-remote-info.c:245
#: app/flatpak-builtins-remote-info.c:280
msgid "Collection:"
msgstr "Колекция:"

#: app/flatpak-builtins-info.c:227 app/flatpak-builtins-info.c:270
#: app/flatpak-builtins-info.c:458 app/flatpak-builtins-info.c:516
msgid "Installation:"
msgstr "Инсталация:"

#: app/flatpak-builtins-info.c:228 app/flatpak-builtins-info.c:271
#: app/flatpak-builtins-info.c:459 app/flatpak-builtins-info.c:517
#: app/flatpak-builtins-remote-info.c:249
#: app/flatpak-builtins-remote-info.c:284
#, fuzzy
msgid "Installed Size:"
msgstr "Размер след инсталация"

#: app/flatpak-builtins-info.c:231 app/flatpak-builtins-info.c:279
#: app/flatpak-builtins-remote-info.c:252
#: app/flatpak-builtins-remote-info.c:288
msgid "Runtime:"
msgstr "Среда за изпълнение:"

#: app/flatpak-builtins-info.c:232 app/flatpak-builtins-info.c:288
#: app/flatpak-builtins-remote-info.c:253
#: app/flatpak-builtins-remote-info.c:293
msgid "Sdk:"
msgstr "SDK:"

#: app/flatpak-builtins-info.c:235 app/flatpak-builtins-info.c:313
#: app/flatpak-builtins-remote-info.c:256
#: app/flatpak-builtins-remote-info.c:319
msgid "Date:"
msgstr "Дата:"

#: app/flatpak-builtins-info.c:237 app/flatpak-builtins-info.c:311
#: app/flatpak-builtins-remote-info.c:258
#: app/flatpak-builtins-remote-info.c:317
msgid "Subject:"
msgstr "Тема:"

#: app/flatpak-builtins-info.c:240 app/flatpak-builtins-info.c:295
msgid "Active commit:"
msgstr "Активно подаване:"

#: app/flatpak-builtins-info.c:241 app/flatpak-builtins-info.c:298
msgid "Latest commit:"
msgstr "Последно подаване:"

#: app/flatpak-builtins-info.c:244 app/flatpak-builtins-info.c:303
#: app/flatpak-builtins-info.c:457 app/flatpak-builtins-info.c:515
#: app/flatpak-builtins-remote-info.c:259
#: app/flatpak-builtins-remote-info.c:298
msgid "Commit:"
msgstr "Подаване:"

#: app/flatpak-builtins-info.c:246 app/flatpak-builtins-info.c:308
#: app/flatpak-builtins-remote-info.c:261
#: app/flatpak-builtins-remote-info.c:303
msgid "Parent:"
msgstr "Родител:"

#: app/flatpak-builtins-info.c:248 app/flatpak-builtins-info.c:321
msgid "Alt-id:"
msgstr "Алтернативен идентификатор:"

#: app/flatpak-builtins-info.c:250 app/flatpak-builtins-info.c:325
#: app/flatpak-builtins-remote-info.c:263
#: app/flatpak-builtins-remote-info.c:308
msgid "End-of-life:"
msgstr "Не получава обновления:"

#: app/flatpak-builtins-info.c:252 app/flatpak-builtins-info.c:330
#: app/flatpak-builtins-remote-info.c:265
#: app/flatpak-builtins-remote-info.c:313
msgid "End-of-life-rebase:"
msgstr "Не получава обновления (пребазирано):"

#: app/flatpak-builtins-info.c:254 app/flatpak-builtins-info.c:317
msgid "Subdirectories:"
msgstr "Поддиректории:"

#: app/flatpak-builtins-info.c:255 app/flatpak-builtins-info.c:454
#: app/flatpak-builtins-info.c:512
msgid "Extension:"
msgstr "Разширение:"

#: app/flatpak-builtins-info.c:267 app/flatpak-builtins-info.c:456
#: app/flatpak-builtins-info.c:514
msgid "Origin:"
msgstr "Изходно хранилище:"

#: app/flatpak-builtins-info.c:460 app/flatpak-builtins-info.c:522
msgid "Subpaths:"
msgstr "Подпътища:"

#: app/flatpak-builtins-info.c:478
msgid "unmaintained"
msgstr "неподдържано"

#: app/flatpak-builtins-info.c:480 app/flatpak-builtins-info.c:482
msgid "unknown"
msgstr "неизвестно"

#: app/flatpak-builtins-install.c:68 app/flatpak-builtins-preinstall.c:57
msgid "Don't pull, only install from local cache"
msgstr "Без издърпване, само инсталиране от локалния кеш"

#: app/flatpak-builtins-install.c:69 app/flatpak-builtins-preinstall.c:58
#: app/flatpak-builtins-update.c:60
msgid "Don't deploy, only download to local cache"
msgstr "Без качване, само изтегляне в локалния кеш"

#: app/flatpak-builtins-install.c:70 app/flatpak-builtins-preinstall.c:59
msgid "Don't install related refs"
msgstr "Без инсталиране на сродните указатели"

#: app/flatpak-builtins-install.c:71 app/flatpak-builtins-preinstall.c:60
#: app/flatpak-builtins-update.c:62
msgid "Don't verify/install runtime dependencies"
msgstr ""
"Без потвърждаване/инсталиране на зависимостите за средата за изпълнение"

#: app/flatpak-builtins-install.c:72
msgid "Don't automatically pin explicit installs"
msgstr "Без автоматично закачане на изрични инсталации"

#: app/flatpak-builtins-install.c:73 app/flatpak-builtins-preinstall.c:61
#: app/flatpak-builtins-update.c:63
msgid "Don't use static deltas"
msgstr "Без използване на статичните разлики"

#: app/flatpak-builtins-install.c:76 app/flatpak-builtins-preinstall.c:62
msgid "Additionally install the SDK used to build the given refs"
msgstr "Инсталиране на SDK, използвано за изграждане на дадените указатели"

#: app/flatpak-builtins-install.c:77 app/flatpak-builtins-preinstall.c:63
msgid ""
"Additionally install the debug info for the given refs and their dependencies"
msgstr ""
"Инсталиране на информация за отстраняване на грешки за дадените указатели и "
"техните зависимости"

#: app/flatpak-builtins-install.c:78
msgid "Assume LOCATION is a .flatpak single-file bundle"
msgstr "Приемане на МЕСТОПОЛОЖЕНИЕ като пакет от един .файл flatpak"

#: app/flatpak-builtins-install.c:79
msgid "Assume LOCATION is a .flatpakref application description"
msgstr "Приемане на МЕСТОПОЛОЖЕНИЕ като описание на програма .flatpakref"

#: app/flatpak-builtins-install.c:80
msgid "Assume LOCATION is containers-transports(5) reference to an OCI image"
msgstr ""

#: app/flatpak-builtins-install.c:81
msgid "Check bundle signatures with GPG key from FILE (- for stdin)"
msgstr ""
"Проверяване на подписите на пакетите с GPG ключ от ФАЙЛ („-“ за стандартен "
"вход)"

#: app/flatpak-builtins-install.c:82
msgid "Only install this subpath"
msgstr "Инсталиране само на този подпът"

#: app/flatpak-builtins-install.c:83 app/flatpak-builtins-preinstall.c:64
#: app/flatpak-builtins-uninstall.c:63 app/flatpak-builtins-update.c:68
msgid "Automatically answer yes for all questions"
msgstr "Автоматичен отговор „да“ за всички въпроси"

#: app/flatpak-builtins-install.c:84 app/flatpak-builtins-preinstall.c:65
msgid "Uninstall first if already installed"
msgstr "Първо деинсталиране, ако вече е инсталирано"

#: app/flatpak-builtins-install.c:85 app/flatpak-builtins-preinstall.c:66
#: app/flatpak-builtins-uninstall.c:64 app/flatpak-builtins-update.c:69
msgid "Produce minimal output and don't ask questions"
msgstr "Минимално извеждане и без задаване на въпроси"

#: app/flatpak-builtins-install.c:86
msgid "Update install if already installed"
msgstr "Обновяване, ако вече е инсталирано"

#. Translators: A sideload is when you install from a local USB drive rather than the Internet.
#: app/flatpak-builtins-install.c:88 app/flatpak-builtins-preinstall.c:68
#: app/flatpak-builtins-update.c:71
msgid "Use this local repo for sideloads"
msgstr "Използване на това локално хранилище за локално зареждане"

#: app/flatpak-builtins-install.c:178
msgid "Bundle filename must be specified"
msgstr "Името на пакета е задължително"

#: app/flatpak-builtins-install.c:188
msgid "Remote bundles are not supported"
msgstr "Отдалечени пакети не се поддържат"

#: app/flatpak-builtins-install.c:231
msgid "Filename or uri must be specified"
msgstr "Име на файл или адрес са задължителни"

#: app/flatpak-builtins-install.c:295
#, fuzzy
msgid "Image location must be specified"
msgstr "Поне един УКАЗАТЕЛ трябва да се посочи"

#: app/flatpak-builtins-install.c:345
msgid "[LOCATION/REMOTE] [REF…] - Install applications or runtimes"
msgstr ""
"[МЕСТОПОЛОЖЕНИЕ/ОТДАЛЕЧЕНО_ХРАНИЛИЩЕ] [УКАЗАТЕЛ…] — инсталиране на програми "
"или среди за изпълнение"

#: app/flatpak-builtins-install.c:378
msgid "At least one REF must be specified"
msgstr "Поне един УКАЗАТЕЛ трябва да се посочи"

#: app/flatpak-builtins-install.c:392
#, c-format
msgid "Looking for matches…\n"
msgstr "Проверяване за съвпадения…\n"

#: app/flatpak-builtins-install.c:513
#, c-format
msgid "No remote refs found for ‘%s’"
msgstr "Няма намерени указатели на отдалечено хранилище за „%s“"

#: app/flatpak-builtins-install.c:573 app/flatpak-builtins-uninstall.c:405
#: common/flatpak-ref-utils.c:689 common/flatpak-ref-utils.c:1595
#, c-format
msgid "Invalid branch %s: %s"
msgstr "Неправилен клон %s: %s"

#: app/flatpak-builtins-install.c:606
#, c-format
msgid "Nothing matches %s in local repository for remote %s"
msgstr "Нищо не съвпада с %s в локалното хранилище за отдалеченото %s"

#: app/flatpak-builtins-install.c:608
#, c-format
msgid "Nothing matches %s in remote %s"
msgstr "Нищо не съвпада с %s в отдалеченото хранилище %s"

#: app/flatpak-builtins-install.c:629
#, c-format
msgid "Skipping: %s\n"
msgstr "Пропускане: %s\n"

#: app/flatpak-builtins-kill.c:110
#, c-format
msgid "%s is not running"
msgstr "%s не работи"

#: app/flatpak-builtins-kill.c:136
msgid "INSTANCE - Stop a running application"
msgstr "ИНСТАНЦИЯ — спиране на работеща програма"

#: app/flatpak-builtins-kill.c:144 app/flatpak-builtins-ps.c:256
msgid "Extra arguments given"
msgstr "Предоставени са допълнителни аргументи"

#: app/flatpak-builtins-kill.c:150
msgid "Must specify the app to kill"
msgstr "Трябва да посочите програмата за убиване"

#: app/flatpak-builtins-list.c:47
msgid "Show extra information"
msgstr "Извеждане на допълнителна информация"

#: app/flatpak-builtins-list.c:48
msgid "List installed runtimes"
msgstr "Изброяване на инсталираните среди за изпълнение"

#: app/flatpak-builtins-list.c:49
msgid "List installed applications"
msgstr "Изброяване на инсталираните програми"

#: app/flatpak-builtins-list.c:50
msgid "Arch to show"
msgstr "Архитектура за извеждане"

#: app/flatpak-builtins-list.c:51 app/flatpak-builtins-remote-ls.c:57
msgid "List all refs (including locale/debug)"
msgstr ""
"Изброяване на всички указатели (включително и локалните/отстраняване на "
"грешки)"

#: app/flatpak-builtins-list.c:53 app/flatpak-builtins-remote-ls.c:58
msgid "List all applications using RUNTIME"
msgstr "Изброяване на всички програми използващи СРЕДАта_ЗА_ИЗПЪЛНЕНИЕ"

#: app/flatpak-builtins-list.c:59 app/flatpak-builtins-remote-list.c:51
#: app/flatpak-builtins-remote-ls.c:68 app/flatpak-builtins-search.c:44
msgid "Name"
msgstr "Име"

#: app/flatpak-builtins-list.c:59 app/flatpak-builtins-remote-list.c:51
#: app/flatpak-builtins-remote-ls.c:68 app/flatpak-builtins-search.c:44
msgid "Show the name"
msgstr "Извеждане на името"

#: app/flatpak-builtins-list.c:60 app/flatpak-builtins-remote-list.c:60
#: app/flatpak-builtins-remote-ls.c:69 app/flatpak-builtins-search.c:45
msgid "Description"
msgstr "Описание"

#: app/flatpak-builtins-list.c:60 app/flatpak-builtins-remote-ls.c:69
#: app/flatpak-builtins-search.c:45
msgid "Show the description"
msgstr "Извеждане на описанието"

#: app/flatpak-builtins-list.c:61 app/flatpak-builtins-remote-ls.c:70
#: app/flatpak-builtins-search.c:46
msgid "Application ID"
msgstr "Идентификатор на програмата"

#: app/flatpak-builtins-list.c:61 app/flatpak-builtins-ps.c:52
#: app/flatpak-builtins-remote-ls.c:70 app/flatpak-builtins-search.c:46
msgid "Show the application ID"
msgstr "Извеждане на идентификатора на програмата"

#: app/flatpak-builtins-list.c:62 app/flatpak-builtins-remote-ls.c:71
#: app/flatpak-builtins-search.c:47
msgid "Show the version"
msgstr "Извеждане на версията"

#: app/flatpak-builtins-list.c:65 app/flatpak-builtins-ps.c:56
#: app/flatpak-builtins-remote-ls.c:77
msgid "Runtime"
msgstr "Среда за изпълнение"

#: app/flatpak-builtins-list.c:65
msgid "Show the used runtime"
msgstr "Извеждане на използваната среда за изпълнение"

#: app/flatpak-builtins-list.c:66 app/flatpak-builtins-remote-ls.c:74
msgid "Show the origin remote"
msgstr "Показване на отдалеченото хранилище"

#: app/flatpak-builtins-list.c:67
msgid "Show the installation"
msgstr "Извеждане на инсталацията"

#: app/flatpak-builtins-list.c:69
msgid "Active commit"
msgstr "Активно подаване"

#: app/flatpak-builtins-list.c:69 app/flatpak-builtins-remote-ls.c:76
msgid "Show the active commit"
msgstr "Извеждане на активното подаване"

#: app/flatpak-builtins-list.c:70
msgid "Latest commit"
msgstr "Последното подаване"

#: app/flatpak-builtins-list.c:70
msgid "Show the latest commit"
msgstr "Извеждане на последното подаване"

#: app/flatpak-builtins-list.c:71 app/flatpak-builtins-remote-ls.c:78
msgid "Installed size"
msgstr "Размер след инсталация"

#: app/flatpak-builtins-list.c:71 app/flatpak-builtins-remote-ls.c:78
msgid "Show the installed size"
msgstr "Извеждане на размера на инсталацията"

#: app/flatpak-builtins-list.c:72 app/flatpak-builtins-remote-list.c:58
#: app/flatpak-builtins-remote-ls.c:80 app/flatpak-builtins-repo.c:340
msgid "Options"
msgstr "Опции"

#: app/flatpak-builtins-list.c:72 app/flatpak-builtins-remote-list.c:58
#: app/flatpak-builtins-remote-ls.c:80
msgid "Show options"
msgstr "Извеждане на опциите"

#: app/flatpak-builtins-list.c:180
#, c-format
msgid "Unable to load details of %s: %s"
msgstr "Подробностите за %s не може да се заредят: %s"

#: app/flatpak-builtins-list.c:190
#, c-format
msgid "Unable to inspect current version of %s: %s"
msgstr "Текущата версия за %s не може да се прегледа: %s"

#: app/flatpak-builtins-list.c:408
msgid " - List installed apps and/or runtimes"
msgstr " — изброяване на инсталираните програми и/или среди за изпълнение"

#: app/flatpak-builtins-make-current.c:38
msgid "Arch to make current for"
msgstr "Архитектура за правене на текущ"

#: app/flatpak-builtins-make-current.c:58
msgid "APP BRANCH - Make branch of application current"
msgstr "ПРОГРАМА КЛОН — правене на клона на програмата текущ"

#: app/flatpak-builtins-make-current.c:69 app/flatpak-builtins-run.c:260
msgid "APP must be specified"
msgstr "ПРОГРАМАта е задължителна"

#: app/flatpak-builtins-make-current.c:84
msgid "BRANCH must be specified"
msgstr "КЛОНът е задължителен"

#: app/flatpak-builtins-make-current.c:97
#, c-format
msgid "App %s branch %s is not installed"
msgstr "Програма %s с клон %s не е инсталирана"

#: app/flatpak-builtins-mask.c:42
msgid "Remove matching masks"
msgstr "Премахване на съвпадащите изключения"

#: app/flatpak-builtins-mask.c:54
msgid ""
"[PATTERN…] - disable updates and automatic installation matching patterns"
msgstr ""
"[ШАБЛОН…] — изключване на обновленията и автоматично инсталиране, които "
"отговарят на шаблони"

#: app/flatpak-builtins-mask.c:73
#, c-format
msgid "No masked patterns\n"
msgstr "Няма шаблони за изключване\n"

#: app/flatpak-builtins-mask.c:78
#, c-format
msgid "Masked patterns:\n"
msgstr "Шаблони за изключване:\n"

#: app/flatpak-builtins-override.c:42
msgid "Remove existing overrides"
msgstr "Премахване на предефиниранията"

#: app/flatpak-builtins-override.c:43
msgid "Show existing overrides"
msgstr "Показване на съществуващите предефинирания"

#: app/flatpak-builtins-override.c:59
msgid "[APP] - Override settings [for application]"
msgstr "[ПРОГРАМА] — заменяне на настройките [за програма]"

#: app/flatpak-builtins-permission-list.c:143
msgid "[TABLE] [ID] - List permissions"
msgstr "[ТАБЛИЦА] [ИДЕНТИФИКАТОР] — изброяване на права̀та"

#: app/flatpak-builtins-permission-list.c:179
#: app/flatpak-builtins-permission-show.c:142
msgid "Table"
msgstr "Таблица"

#: app/flatpak-builtins-permission-list.c:180
#: app/flatpak-builtins-permission-show.c:143
msgid "Object"
msgstr "Обект"

#: app/flatpak-builtins-permission-list.c:181
#: app/flatpak-builtins-permission-show.c:144
msgid "App"
msgstr "Програма"

#: app/flatpak-builtins-permission-list.c:183
#: app/flatpak-builtins-permission-show.c:146
msgid "Data"
msgstr "Данни"

#: app/flatpak-builtins-permission-remove.c:120
msgid "TABLE ID [APP_ID] - Remove item from permission store"
msgstr ""
"ИД_НА_ТАБЛИЦА [ИД_НА_ПРОГРАМА] — премахване на елемент от хранилището за "
"права̀"

#: app/flatpak-builtins-permission-remove.c:129
#: app/flatpak-builtins-permission-set.c:120
msgid "Too few arguments"
msgstr "Прекалено много аргументи"

#: app/flatpak-builtins-permission-reset.c:43
msgid "Reset all permissions"
msgstr "Връщане на всички права̀"

#: app/flatpak-builtins-permission-reset.c:144
msgid "APP_ID - Reset permissions for an app"
msgstr "ИД_НА_ПРОГРАМА — връщане на права̀та за програма"

#: app/flatpak-builtins-permission-reset.c:153
#: app/flatpak-builtins-permission-show.c:124
msgid "Wrong number of arguments"
msgstr "Грешен брой аргументи"

#: app/flatpak-builtins-permission-set.c:42
msgid "Associate DATA with the entry"
msgstr "Свързване на ДАННИ със записа"

#: app/flatpak-builtins-permission-set.c:42
msgid "DATA"
msgstr "ДАННИ"

#: app/flatpak-builtins-permission-set.c:111
msgid "TABLE ID APP_ID [PERMISSION...] - Set permissions"
msgstr "ТАБЛИЦА ИД ИД_НА_ПРОГРАМА [ПРАВО...] — задаване на права̀"

#: app/flatpak-builtins-permission-set.c:132
#, c-format
msgid "Failed to parse '%s' as GVariant: "
msgstr "„%s“ не може да се разчете като GVariant: "

#: app/flatpak-builtins-permission-show.c:115
msgid "APP_ID - Show permissions for an app"
msgstr "ИД_НА_ПРОГРАМА — показване на права̀та за програма"

#: app/flatpak-builtins-pin.c:44
msgid "Remove matching pins"
msgstr "Премахване на отговарящите на закачените шаблони"

#: app/flatpak-builtins-pin.c:56
msgid "[PATTERN…] - disable automatic removal of runtimes matching patterns"
msgstr ""
"[ШАБЛОН…] — изключване на автоматичното премахване на среди за изпълнение, "
"които отговарят на шаблони"

#: app/flatpak-builtins-pin.c:75
#, c-format
msgid "No pinned patterns\n"
msgstr "Няма закачени шаблони\n"

#: app/flatpak-builtins-pin.c:80
#, c-format
msgid "Pinned patterns:\n"
msgstr "Закачени шаблони:\n"

#: app/flatpak-builtins-preinstall.c:80
msgid "- Install flatpaks that are part of the operating system"
msgstr ""

#: app/flatpak-builtins-preinstall.c:118
#, c-format
msgid "Nothing to do.\n"
msgstr "Няма нищо за правене.\n"

#: app/flatpak-builtins-ps.c:49
msgid "Instance"
msgstr "Инстанция"

#: app/flatpak-builtins-ps.c:49
msgid "Show the instance ID"
msgstr "Извеждане на ид. на инстанцията"

#: app/flatpak-builtins-ps.c:50 app/flatpak-builtins-run.c:178
msgid "PID"
msgstr "ИД_ПР."

#: app/flatpak-builtins-ps.c:50
msgid "Show the PID of the wrapper process"
msgstr "Показване на ИДентификатора на ПРоцеса на обвиващия процес"

#: app/flatpak-builtins-ps.c:51
msgid "Child-PID"
msgstr "ДЪЩЕРЕН_ИД_ПР"

#: app/flatpak-builtins-ps.c:51
msgid "Show the PID of the sandbox process"
msgstr "Показване на ИДентификатора на ПРоцеса на ограничената среда"

#: app/flatpak-builtins-ps.c:54 app/flatpak-builtins-search.c:48
msgid "Show the application branch"
msgstr "Извеждане на клона на програмата"

#: app/flatpak-builtins-ps.c:55
msgid "Show the application commit"
msgstr "Извеждане на подаването на програмата"

#: app/flatpak-builtins-ps.c:56
msgid "Show the runtime ID"
msgstr "Извеждане на ИДентификатора на средата за изпълнение"

#: app/flatpak-builtins-ps.c:57
msgid "R.-Branch"
msgstr "КЛОН_ЗА_СРЕДА"

#: app/flatpak-builtins-ps.c:57
msgid "Show the runtime branch"
msgstr "Извеждане на КЛОНа_НА_СРЕДАта за изпълнение"

#: app/flatpak-builtins-ps.c:58
msgid "R.-Commit"
msgstr "ПОДАВАНЕ_ЗА_СРЕДА"

#: app/flatpak-builtins-ps.c:58
msgid "Show the runtime commit"
msgstr "Извеждане на ПОДАВАНЕто_ЗА_СРЕДАта за изпълнение"

#: app/flatpak-builtins-ps.c:59
msgid "Active"
msgstr "Активна"

#: app/flatpak-builtins-ps.c:59
msgid "Show whether the app is active"
msgstr "Извеждане дали програмата работи"

#: app/flatpak-builtins-ps.c:60
msgid "Background"
msgstr "Фон"

#: app/flatpak-builtins-ps.c:60
msgid "Show whether the app is background"
msgstr "Извеждане дали програмата работи във фонов режим"

#: app/flatpak-builtins-ps.c:246
msgid " - Enumerate running sandboxes"
msgstr " — изброяване на работещите ограничени среди"

#: app/flatpak-builtins-remote-add.c:66
msgid "Do nothing if the provided remote exists"
msgstr "Не прави нищо, ако предоставеното отдалечено хранилище съществува"

#: app/flatpak-builtins-remote-add.c:67
msgid "LOCATION specifies a configuration file, not the repo location"
msgstr ""
"МЕСТОПОЛОЖЕНИЕ указва файл с настройки, а не местоположението на хранилището"

#: app/flatpak-builtins-remote-add.c:72 app/flatpak-builtins-remote-modify.c:78
msgid "Disable GPG verification"
msgstr "Изключване на проверката с GPG"

#: app/flatpak-builtins-remote-add.c:73 app/flatpak-builtins-remote-modify.c:79
msgid "Mark the remote as don't enumerate"
msgstr "Отбелязване на отдалеченото хранилище да не се изброява"

#: app/flatpak-builtins-remote-add.c:74 app/flatpak-builtins-remote-modify.c:80
msgid "Mark the remote as don't use for deps"
msgstr "Отбелязване на отдалеченото хранилище да не се ползва за зависимости"

#: app/flatpak-builtins-remote-add.c:75 app/flatpak-builtins-remote-modify.c:81
msgid "Set priority (default 1, higher is more prioritized)"
msgstr ""
"Задаване на ПРИОРИТЕТ (стандартното е 1, по-голямо за по-висок приоритет)"

#: app/flatpak-builtins-remote-add.c:75 app/flatpak-builtins-remote-modify.c:81
msgid "PRIORITY"
msgstr "ПРИОРИТЕТ"

#: app/flatpak-builtins-remote-add.c:76
msgid "The named subset to use for this remote"
msgstr ""
"Именувано ПОДМНОЖЕСТВО, което да се използва за това отдалечено хранилище"

#: app/flatpak-builtins-remote-add.c:76 app/flatpak-builtins-remote-modify.c:71
msgid "SUBSET"
msgstr "ПОДМНОЖЕСТВО"

#: app/flatpak-builtins-remote-add.c:77 app/flatpak-builtins-remote-modify.c:82
msgid "A nice name to use for this remote"
msgstr "Хубаво име, което да се използва за това отдалечено хранилище"

#: app/flatpak-builtins-remote-add.c:78 app/flatpak-builtins-remote-modify.c:83
msgid "A one-line comment for this remote"
msgstr "Коментар от един ред за това отдалечено хранилище"

#: app/flatpak-builtins-remote-add.c:79 app/flatpak-builtins-remote-modify.c:84
msgid "A full-paragraph description for this remote"
msgstr "Пълно описание за това отдалечено хранилище"

#: app/flatpak-builtins-remote-add.c:80 app/flatpak-builtins-remote-modify.c:85
msgid "URL for a website for this remote"
msgstr "Адрес на уеб страница за това отдалечено хранилище"

#: app/flatpak-builtins-remote-add.c:81 app/flatpak-builtins-remote-modify.c:86
msgid "URL for an icon for this remote"
msgstr "Адрес на иконка за това отдалечено хранилище"

#: app/flatpak-builtins-remote-add.c:82 app/flatpak-builtins-remote-modify.c:87
msgid "Default branch to use for this remote"
msgstr "Стандартният клон, който да се използва за това отдалечено хранилище"

#: app/flatpak-builtins-remote-add.c:84 app/flatpak-builtins-remote-modify.c:89
msgid "Import GPG key from FILE (- for stdin)"
msgstr "Внасяне на ключ за GPG от ФАЙЛ („-“ за стандартен вход)"

#: app/flatpak-builtins-remote-add.c:85 app/flatpak-builtins-remote-modify.c:90
msgid "Load signatures from URL"
msgstr ""

#: app/flatpak-builtins-remote-add.c:86 app/flatpak-builtins-remote-modify.c:92
msgid "Set path to local filter FILE"
msgstr "Задаване на път до локалния ФАЙЛ с филтър"

#: app/flatpak-builtins-remote-add.c:87 app/flatpak-builtins-remote-modify.c:93
msgid "Disable the remote"
msgstr "Изключване на отдалеченото хранилище"

#: app/flatpak-builtins-remote-add.c:88 app/flatpak-builtins-remote-modify.c:94
msgid "Name of authenticator"
msgstr "Име на удостоверителя"

#: app/flatpak-builtins-remote-add.c:90 app/flatpak-builtins-remote-modify.c:96
msgid "Autoinstall authenticator"
msgstr "Автоматично инсталиране на удостоверителя"

#: app/flatpak-builtins-remote-add.c:91 app/flatpak-builtins-remote-modify.c:97
msgid "Don't autoinstall authenticator"
msgstr "Без автоматично инсталиране на удостоверителя"

#: app/flatpak-builtins-remote-add.c:92 app/flatpak-builtins-remote-modify.c:99
msgid "Don't follow the redirect set in the summary file"
msgstr "Без използване на пренасочването, зададено във файла за обобщение"

#: app/flatpak-builtins-remote-add.c:261 app/flatpak-builtins-remote-add.c:268
#, c-format
msgid "Can't load uri %s: %s\n"
msgstr "Адресът %s не може да се зареди: %s\n"

#: app/flatpak-builtins-remote-add.c:276 common/flatpak-dir.c:4643
#, c-format
msgid "Can't load file %s: %s\n"
msgstr "Файлът %s не може да се зареди: %s\n"

#: app/flatpak-builtins-remote-add.c:304
msgid "NAME LOCATION - Add a remote repository"
msgstr "ИМЕ МЕСТОПОЛОЖЕНИЕ — добавяне на отдалечено хранилище"

#: app/flatpak-builtins-remote-add.c:331
msgid "GPG verification is required if collections are enabled"
msgstr "Необходимо е потвърждаване с GPG, ако колекциите са включени"

#: app/flatpak-builtins-remote-add.c:393
#, c-format
msgid "Remote %s already exists"
msgstr "Отдалеченото хранилище %s вече съществува"

#: app/flatpak-builtins-remote-add.c:405
#: app/flatpak-builtins-remote-modify.c:340
#, c-format
msgid "Invalid authenticator name %s"
msgstr "Неправилно име на удостоверителя %s"

#: app/flatpak-builtins-remote-add.c:422
#, c-format
msgid "Warning: Could not update extra metadata for '%s': %s\n"
msgstr "ВНИМАНИЕ: допълнителните метаданни за „%s“ не може да се обновят: %s\n"

#: app/flatpak-builtins-remote-delete.c:39
msgid "Remove remote even if in use"
msgstr "Премахване на отдалеченото хранилище, дори ако се използва"

#: app/flatpak-builtins-remote-delete.c:53
msgid "NAME - Delete a remote repository"
msgstr "ИМЕ — премахване на отдалечено хранилище"

#: app/flatpak-builtins-remote-delete.c:100
#, c-format
msgid "The following refs are installed from remote '%s':"
msgstr "Следните указатели са инсталирани от отдалеченото хранилище „%s“:"

#: app/flatpak-builtins-remote-delete.c:101
msgid "Remove them?"
msgstr "Да се премахнат ли?"

#: app/flatpak-builtins-remote-delete.c:103
#, c-format
msgid "Can't remove remote '%s' with installed refs"
msgstr ""
"Отдалеченото хранилище „%s“ с инсталирани указатели не може да се премахне"

#: app/flatpak-builtins-remote-info.c:55
msgid "Commit to show info for"
msgstr "Подаване, за което да се покаже информацията"

#: app/flatpak-builtins-remote-info.c:58
msgid "Display log"
msgstr "Извеждане на журнала"

#: app/flatpak-builtins-remote-info.c:61
msgid "Show parent"
msgstr "Извеждане на родителя"

#: app/flatpak-builtins-remote-info.c:65 app/flatpak-builtins-remote-ls.c:60
msgid "Use local caches even if they are stale"
msgstr "Използване на локални кешове, дори ако са остарели"

#. Translators: A sideload is when you install from a local USB drive rather than the Internet.
#: app/flatpak-builtins-remote-info.c:67 app/flatpak-builtins-remote-ls.c:62
msgid "Only list refs available as sideloads"
msgstr "Изброяване само на наличните за локално зареждане указатели"

#: app/flatpak-builtins-remote-info.c:114
msgid ""
" REMOTE REF - Show information about an application or runtime in a remote"
msgstr ""
" ОТДАЛЕЧЕНО_ХРАНИЛИЩЕ УКАЗАТЕЛ — показване на информация за програма или "
"среда за изпълнение в отдалечено хранилище"

#: app/flatpak-builtins-remote-info.c:125
msgid "REMOTE and REF must be specified"
msgstr "и ОТДАЛЕЧЕНОто_ХРАНИЛИЩЕ, и УКАЗАТЕЛят са задължителни"

#: app/flatpak-builtins-remote-info.c:247
#: app/flatpak-builtins-remote-info.c:282
#, fuzzy
msgid "Download Size:"
msgstr "Размер за изтегляне"

#: app/flatpak-builtins-remote-info.c:267
#: app/flatpak-builtins-remote-info.c:325
msgid "History:"
msgstr "История:"

#: app/flatpak-builtins-remote-info.c:348
msgid " Commit:"
msgstr " Подаване:"

#: app/flatpak-builtins-remote-info.c:349
msgid " Subject:"
msgstr " Тема:"

#: app/flatpak-builtins-remote-info.c:350
msgid " Date:"
msgstr " Дата:"

#: app/flatpak-builtins-remote-info.c:383
#, c-format
msgid "Warning: Commit %s has no flatpak metadata\n"
msgstr "ВНИМАНИЕ: подаването %s няма метаданни за flatpak\n"

#: app/flatpak-builtins-remote-list.c:43
msgid "Show remote details"
msgstr "Показване на подробностите на хранилище"

#: app/flatpak-builtins-remote-list.c:44
msgid "Show disabled remotes"
msgstr "Показване на изключените хранилища"

#: app/flatpak-builtins-remote-list.c:52
msgid "Title"
msgstr "Заглавие"

#: app/flatpak-builtins-remote-list.c:52
msgid "Show the title"
msgstr "Извеждане на заглавието"

#: app/flatpak-builtins-remote-list.c:53
msgid "Show the URL"
msgstr "Извеждане на адреса"

#: app/flatpak-builtins-remote-list.c:54
msgid "Show the collection ID"
msgstr "Показване на идентификатора на колекцията"

#: app/flatpak-builtins-remote-list.c:55 app/flatpak-builtins-repo.c:392
msgid "Subset"
msgstr "Подмножество"

#: app/flatpak-builtins-remote-list.c:55
msgid "Show the subset"
msgstr "Показване на подмножеството"

#: app/flatpak-builtins-remote-list.c:56
msgid "Filter"
msgstr "Филтър"

#: app/flatpak-builtins-remote-list.c:56
msgid "Show filter file"
msgstr "Извеждане на файла за филтър"

#: app/flatpak-builtins-remote-list.c:57
msgid "Priority"
msgstr "Приоритет"

#: app/flatpak-builtins-remote-list.c:57
msgid "Show the priority"
msgstr "Извеждане на приоритета"

#: app/flatpak-builtins-remote-list.c:59
msgid "Comment"
msgstr "Коментар"

#: app/flatpak-builtins-remote-list.c:59
msgid "Show comment"
msgstr "Извеждане на коментар"

#: app/flatpak-builtins-remote-list.c:60
msgid "Show description"
msgstr "Извеждане на описанието"

#: app/flatpak-builtins-remote-list.c:61
msgid "Homepage"
msgstr "Начална страница"

#: app/flatpak-builtins-remote-list.c:61
msgid "Show homepage"
msgstr "Извеждане на началната страница"

#: app/flatpak-builtins-remote-list.c:62
msgid "Icon"
msgstr "Иконка"

#: app/flatpak-builtins-remote-list.c:62
msgid "Show icon"
msgstr "Извеждане на иконката"

#: app/flatpak-builtins-remote-list.c:231
msgid " - List remote repositories"
msgstr " — изброяване на отдалечените хранилища"

#: app/flatpak-builtins-remote-ls.c:52
msgid "Show arches and branches"
msgstr "Показване на архитектурите и клоните"

#: app/flatpak-builtins-remote-ls.c:53
msgid "Show only runtimes"
msgstr "Извеждане само на средите за изпълнение"

#: app/flatpak-builtins-remote-ls.c:54
msgid "Show only apps"
msgstr "Извеждане само на програмите"

#: app/flatpak-builtins-remote-ls.c:55
msgid "Show only those where updates are available"
msgstr "Показване само на тези с налични обновления"

#: app/flatpak-builtins-remote-ls.c:56
msgid "Limit to this arch (* for all)"
msgstr "Ограничаване до тази архитектура („*“ за всички)"

#: app/flatpak-builtins-remote-ls.c:77
msgid "Show the runtime"
msgstr "Извеждане на средата за изпълнение"

#: app/flatpak-builtins-remote-ls.c:79
msgid "Download size"
msgstr "Размер за изтегляне"

#: app/flatpak-builtins-remote-ls.c:79
msgid "Show the download size"
msgstr "Извеждане на размера за изтегляне"

#: app/flatpak-builtins-remote-ls.c:391
msgid " [REMOTE or URI] - Show available runtimes and applications"
msgstr ""
" [ОТДАЛЕЧЕНО_ХРАНИЛИЩЕ или АДРЕС] — показване на наличните среди за "
"изпълнение или програми"

#: app/flatpak-builtins-remote-modify.c:67
msgid "Enable GPG verification"
msgstr "Включване на потвърждаване с GPG"

#: app/flatpak-builtins-remote-modify.c:68
msgid "Mark the remote as enumerate"
msgstr "Отбелязване на отдалеченото устройство като изброимо"

#: app/flatpak-builtins-remote-modify.c:69
msgid "Mark the remote as used for dependencies"
msgstr "Отбелязване на отдалеченото хранилище като използвано за зависимости"

#: app/flatpak-builtins-remote-modify.c:70
#, fuzzy
msgid "Set a new URL"
msgstr "Задаване на нов адрес"

#: app/flatpak-builtins-remote-modify.c:71
msgid "Set a new subset to use"
msgstr "Задаване на ново подмножество за ползване"

#: app/flatpak-builtins-remote-modify.c:72
msgid "Enable the remote"
msgstr "Включване на отдалеченото хранилище"

#: app/flatpak-builtins-remote-modify.c:73
msgid "Update extra metadata from the summary file"
msgstr "Обновяване на допълнителните метаданни от файла за обобщение"

#: app/flatpak-builtins-remote-modify.c:91
msgid "Disable local filter"
msgstr "Изключване на локален филтър"

#: app/flatpak-builtins-remote-modify.c:95
msgid "Authenticator options"
msgstr "Опции за удостоверител"

#: app/flatpak-builtins-remote-modify.c:98
msgid "Follow the redirect set in the summary file"
msgstr "Използване на пренасочването от файла за обобщение"

#: app/flatpak-builtins-remote-modify.c:306
msgid "NAME - Modify a remote repository"
msgstr "ИМЕ — промяна на отдалечено хранилище"

#: app/flatpak-builtins-remote-modify.c:316
msgid "Remote NAME must be specified"
msgstr "ИМЕто на отдалеченото хранилище е задължително"

#: app/flatpak-builtins-remote-modify.c:327
#, c-format
msgid "Updating extra metadata from remote summary for %s\n"
msgstr ""
"Обновяване на допълнителни метаданни от обобщението на отдалеченото "
"хранилище за %s\n"

#: app/flatpak-builtins-remote-modify.c:330
#, c-format
msgid "Error updating extra metadata for '%s': %s\n"
msgstr "Допълнителните метаданни за „%s“ не може да се обновят: %s\n"

#: app/flatpak-builtins-remote-modify.c:331
#, c-format
msgid "Could not update extra metadata for %s"
msgstr "Допълнителните метаданни за %s не може да се обновят"

#: app/flatpak-builtins-repair.c:43
msgid "Don't make any changes"
msgstr "Без промени"

#: app/flatpak-builtins-repair.c:44
msgid "Reinstall all refs"
msgstr "Преинсталиране на всички указатели"

#: app/flatpak-builtins-repair.c:68
#, c-format
msgid "Object missing: %s.%s\n"
msgstr "Липсва обект: %s.%s\n"

#: app/flatpak-builtins-repair.c:76
#, c-format
msgid "Object invalid: %s.%s\n"
msgstr "Неправилен обект: %s.%s\n"

#: app/flatpak-builtins-repair.c:81
#, c-format
msgid "%s, deleting object\n"
msgstr "%s, изтриване на обекта\n"

#: app/flatpak-builtins-repair.c:146
#, c-format
msgid "Can't load object %s: %s\n"
msgstr "Обектът не може да се зареди %s: %s\n"

#: app/flatpak-builtins-repair.c:228
#, c-format
msgid "Commit invalid %s: %s\n"
msgstr "Неправилно подаване %s: %s\n"

#: app/flatpak-builtins-repair.c:231
#, c-format
msgid "Deleting invalid commit %s: %s\n"
msgstr "Изтриване на неправилното подаване %s: %s\n"

#: app/flatpak-builtins-repair.c:261
#, c-format
msgid "Commit should be marked partial: %s\n"
msgstr "Подаването трябва да се маркира като частично: %s\n"

#: app/flatpak-builtins-repair.c:264
#, c-format
msgid "Marking commit as partial: %s\n"
msgstr "Маркиране на подаването като частично: %s\n"

#: app/flatpak-builtins-repair.c:293
#, c-format
msgid "Problems loading data for %s: %s\n"
msgstr "Проблеми при зареждането на данните за %s: %s\n"

#: app/flatpak-builtins-repair.c:306
#, c-format
msgid "Error reinstalling %s: %s\n"
msgstr "Грешка при преинсталирането на %s: %s\n"

#: app/flatpak-builtins-repair.c:327
msgid "- Repair a flatpak installation"
msgstr "— поправяне на инсталация на flatpak"

#: app/flatpak-builtins-repair.c:406
#, c-format
msgid "Removing non-deployed ref %s…\n"
msgstr "Премахване на указателя %s, който не е качен…\n"

#: app/flatpak-builtins-repair.c:411
#, c-format
msgid "Skipping non-deployed ref %s…\n"
msgstr "Пропускане на указателя %s, който не е качен…\n"

#: app/flatpak-builtins-repair.c:429
#, c-format
msgid "[%d/%d] Verifying %s…\n"
msgstr "[%d/%d] Потвърждаване %s…\n"

#: app/flatpak-builtins-repair.c:435
#, c-format
msgid "Dry run: "
msgstr "Пробно изпълнение: "

#: app/flatpak-builtins-repair.c:440
#, c-format
msgid "Deleting ref %s due to missing objects\n"
msgstr "Изтриване на указателя %s поради липсващи обекти\n"

#: app/flatpak-builtins-repair.c:444
#, c-format
msgid "Deleting ref %s due to invalid objects\n"
msgstr "Изтриване на указателя %s поради неправилни обекти\n"

#: app/flatpak-builtins-repair.c:448
#, c-format
msgid "Deleting ref %s due to %d\n"
msgstr "Изтриване на указателя %s поради %d\n"

#: app/flatpak-builtins-repair.c:464
#, c-format
msgid "Checking remotes...\n"
msgstr "Проверяване на отдалечените хранилища…\n"

#: app/flatpak-builtins-repair.c:482
#, c-format
msgid "Remote %s for ref %s is missing\n"
msgstr "Отдалеченото хранилище %s за указателя %s липсва\n"

#: app/flatpak-builtins-repair.c:484
#, c-format
msgid "Remote %s for ref %s is disabled\n"
msgstr "Отдалеченото хранилище %s за указателя %s е изключено\n"

#: app/flatpak-builtins-repair.c:490
#, c-format
msgid "Pruning objects\n"
msgstr "Окастряне на обекти\n"

#: app/flatpak-builtins-repair.c:498
#, c-format
msgid "Erasing .removed\n"
msgstr "Изтриване на „.removed“\n"

#: app/flatpak-builtins-repair.c:524
#, c-format
msgid "Reinstalling refs\n"
msgstr "Преинсталиране на указателите\n"

#: app/flatpak-builtins-repair.c:526
#, c-format
msgid "Reinstalling removed refs\n"
msgstr "Преинсталиране на премахнатите указатели\n"

#: app/flatpak-builtins-repair.c:551
#, c-format
msgid "While removing appstream for %s: "
msgstr "По време на премахването на appstream за %s: "

#: app/flatpak-builtins-repair.c:558
#, c-format
msgid "While deploying appstream for %s: "
msgstr "По време на качването на appstream за %s: "

#: app/flatpak-builtins-repo.c:106
#, c-format
msgid "Repo mode: %s\n"
msgstr "Режим на хранилище: %s\n"

#: app/flatpak-builtins-repo.c:113
#, c-format
msgid "Indexed summaries: %s\n"
msgstr "Индексирани обобщения: %s\n"

#: app/flatpak-builtins-repo.c:113 app/flatpak-builtins-repo.c:139
#: app/flatpak-builtins-repo.c:172
msgid "true"
msgstr "истина"

#: app/flatpak-builtins-repo.c:113 app/flatpak-builtins-repo.c:139
#: app/flatpak-builtins-repo.c:172
msgid "false"
msgstr "лъжа"

#: app/flatpak-builtins-repo.c:121
#, c-format
msgid "Subsummaries: "
msgstr "Подобобщения: "

#: app/flatpak-builtins-repo.c:136
#, c-format
msgid "Cache version: %d\n"
msgstr "Кеширана версия: %d\n"

#: app/flatpak-builtins-repo.c:139
#, c-format
msgid "Indexed deltas: %s\n"
msgstr "Индексирани разлики: %s\n"

#: app/flatpak-builtins-repo.c:142
#, c-format
msgid "Title: %s\n"
msgstr "Заглавие: %s\n"

#: app/flatpak-builtins-repo.c:145
#, c-format
msgid "Comment: %s\n"
msgstr "Коментар: %s\n"

#: app/flatpak-builtins-repo.c:148
#, c-format
msgid "Description: %s\n"
msgstr "Описание: %s\n"

#: app/flatpak-builtins-repo.c:151
#, c-format
msgid "Homepage: %s\n"
msgstr "Начална страница: %s\n"

#: app/flatpak-builtins-repo.c:154
#, c-format
msgid "Icon: %s\n"
msgstr "Иконка: %s\n"

#: app/flatpak-builtins-repo.c:157
#, c-format
msgid "Collection ID: %s\n"
msgstr "Идентификатор на колекцията: %s\n"

#: app/flatpak-builtins-repo.c:160
#, c-format
msgid "Default branch: %s\n"
msgstr "Основен клон: %s\n"

#: app/flatpak-builtins-repo.c:163
#, c-format
msgid "Redirect URL: %s\n"
msgstr "Адрес за пренасочване: %s\n"

#: app/flatpak-builtins-repo.c:166
#, c-format
msgid "Deploy collection ID: %s\n"
msgstr "Качване на колекцията с идентификатор: %s\n"

#: app/flatpak-builtins-repo.c:169
#, c-format
msgid "Authenticator name: %s\n"
msgstr "Име на удостоверител: %s\n"

#: app/flatpak-builtins-repo.c:172
#, c-format
msgid "Authenticator install: %s\n"
msgstr "Инсталация на удостоверител: %s\n"

#: app/flatpak-builtins-repo.c:180
#, c-format
msgid "GPG key hash: %s\n"
msgstr "Контролна сума на ключ за GPG: %s\n"

#: app/flatpak-builtins-repo.c:184
#, c-format
msgid "%zd summary branches\n"
msgstr "%zd обобщени клонове\n"

#: app/flatpak-builtins-repo.c:336
msgid "Installed"
msgstr "Инсталирана"

#. Translators: Download is used here as a noun
#: app/flatpak-builtins-repo.c:338 app/flatpak-cli-transaction.c:1462
msgid "Download"
msgstr "Изтегляне"

#: app/flatpak-builtins-repo.c:339
msgid "Subsets"
msgstr "Подмножества"

#: app/flatpak-builtins-repo.c:393
msgid "Digest"
msgstr "Извадка"

#: app/flatpak-builtins-repo.c:394
msgid "History length"
msgstr "Дължина на историята"

#: app/flatpak-builtins-repo.c:711
msgid "Print general information about the repository"
msgstr "Извеждане на обща информация за хранилището"

#: app/flatpak-builtins-repo.c:712
msgid "List the branches in the repository"
msgstr "Изброяване на клоновете в хранилището"

#: app/flatpak-builtins-repo.c:713
msgid "Print metadata for a branch"
msgstr "Извеждане на метаданните за клон"

#: app/flatpak-builtins-repo.c:714
msgid "Show commits for a branch"
msgstr "Извеждане на подаванията за клон"

#: app/flatpak-builtins-repo.c:715
msgid "Print information about the repo subsets"
msgstr "Извеждане на информацията за подмножествата на хранилището"

#: app/flatpak-builtins-repo.c:716
msgid "Limit information to subsets with this prefix"
msgstr "Ограничаване на информацията до подмножествата с тази представка"

#: app/flatpak-builtins-repo.c:732
msgid "LOCATION - Repository maintenance"
msgstr "МЕСТОПОЛОЖЕНИЕ — поддръжка на хранилището"

#: app/flatpak-builtins-run.c:159
msgid "Command to run"
msgstr "Команда за изпълняване"

#: app/flatpak-builtins-run.c:160
msgid "Directory to run the command in"
msgstr "Директория, в която да се изпълни командата"

#: app/flatpak-builtins-run.c:161
msgid "Branch to use"
msgstr "Клон за използване"

#: app/flatpak-builtins-run.c:162
msgid "Use development runtime"
msgstr "Използване на среда за изпълнение за разработчици"

#: app/flatpak-builtins-run.c:163
msgid "Runtime to use"
msgstr "Среда за изпълнение"

#: app/flatpak-builtins-run.c:164
msgid "Runtime version to use"
msgstr "Версия за среда за изпълнение"

#: app/flatpak-builtins-run.c:167
msgid "Log accessibility bus calls"
msgstr "Извеждане в журнала на извикванията на шината за достъпност"

#: app/flatpak-builtins-run.c:168
msgid "Don't proxy accessibility bus calls"
msgstr "Без препредаване на извикванията на шината за достъпност"

#: app/flatpak-builtins-run.c:169
msgid "Proxy accessibility bus calls (default except when sandboxed)"
msgstr ""
"Препредаване на извикванията на шината за достъпност (стандартно, освен "
"когато е в ограничена среда)"

#: app/flatpak-builtins-run.c:170
msgid "Don't proxy session bus calls"
msgstr "Без препредаване на извикванията на сесийната шина"

#: app/flatpak-builtins-run.c:171
msgid "Proxy session bus calls (default except when sandboxed)"
msgstr ""
"Препредаване на извикванията на сесийната шина (стандартно, освен когато е в "
"ограничена среда)"

#: app/flatpak-builtins-run.c:172
msgid "Don't start portals"
msgstr "Без стартиране на портали"

#: app/flatpak-builtins-run.c:173
msgid "Enable file forwarding"
msgstr "Включване на пренасочването на файлове"

#: app/flatpak-builtins-run.c:174
msgid "Run specified commit"
msgstr "Изпълняване на посоченото подаване"

#: app/flatpak-builtins-run.c:175
msgid "Use specified runtime commit"
msgstr "Използване на посоченото подаване за средата за изпълнение"

#: app/flatpak-builtins-run.c:176
msgid "Run completely sandboxed"
msgstr "Изпълняване изцяло в ограничен режим"

#: app/flatpak-builtins-run.c:178
msgid "Use PID as parent pid for sharing namespaces"
msgstr ""
"Използване на идентификатор на процес като родителски за споделяне на "
"пространства от имена"

#: app/flatpak-builtins-run.c:179
msgid "Make processes visible in parent namespace"
msgstr "Процесите да са видими в родителското пространство от имена"

#: app/flatpak-builtins-run.c:180
msgid "Share process ID namespace with parent"
msgstr ""
"Споделяне на идентификатора на процеса на пространството от имена с родителя"

#: app/flatpak-builtins-run.c:181
msgid "Write the instance ID to the given file descriptor"
msgstr "Записване на идентификатора на инстанцията в дадения файлов дескриптор"

#: app/flatpak-builtins-run.c:182
msgid "Use PATH instead of the app's /app"
msgstr "Използване на ПЪТ вместо „/app“ на програмата"

#: app/flatpak-builtins-run.c:183
#, fuzzy
msgid "Use FD instead of the app's /app"
msgstr "Използване на ПЪТ вместо „/app“ на програмата"

#: app/flatpak-builtins-run.c:183 app/flatpak-builtins-run.c:185
#: app/flatpak-builtins-run.c:187 app/flatpak-builtins-run.c:188
#: common/flatpak-context.c:2672
msgid "FD"
msgstr "FD"

#: app/flatpak-builtins-run.c:184
msgid "Use PATH instead of the runtime's /usr"
msgstr "Използване на ПЪТ вместо „/usr“ на средата за изпълнение"

#: app/flatpak-builtins-run.c:185
#, fuzzy
msgid "Use FD instead of the runtime's /usr"
msgstr "Използване на ПЪТ вместо „/usr“ на средата за изпълнение"

#: app/flatpak-builtins-run.c:186
#, fuzzy
msgid "Clear all outside environment variables"
msgstr "Задаване на променлива на средата"

#: app/flatpak-builtins-run.c:187
msgid ""
"Bind mount the file or directory referred to by FD to its canonicalized path"
msgstr ""

#: app/flatpak-builtins-run.c:188
msgid ""
"Bind mount the file or directory referred to by FD read-only to its "
"canonicalized path"
msgstr ""

#: app/flatpak-builtins-run.c:219
msgid "APP [ARGUMENT…] - Run an app"
msgstr "ПРОГРАМА [АРГУМЕНТ…] — изпълняване на програма"

#: app/flatpak-builtins-run.c:370
#, c-format
msgid "runtime/%s/%s/%s not installed"
msgstr "средата за изпълнение/%s/%s/%s не е инсталирана"

#: app/flatpak-builtins-run.c:419
msgid "app-fd and app-path cannot both be used"
msgstr ""

#: app/flatpak-builtins-run.c:449
msgid "usr-fd and usr-path cannot both be used"
msgstr ""

#: app/flatpak-builtins-search.c:37
msgid "Arch to search for"
msgstr "Архитектура, която да се търси"

#: app/flatpak-builtins-search.c:49
msgid "Remotes"
msgstr "Отдалечени хранилища"

#: app/flatpak-builtins-search.c:49
msgid "Show the remotes"
msgstr "Извеждане на отдалечените хранилища"

#: app/flatpak-builtins-search.c:244
msgid "TEXT - Search remote apps/runtimes for text"
msgstr "ТЕКСТ — търсене на отдалечени програми/среди за изпълнение за текст"

#: app/flatpak-builtins-search.c:255
msgid "TEXT must be specified"
msgstr "ТЕКСТът е задължителен"

#: app/flatpak-builtins-search.c:338
msgid "No matches found"
msgstr "Няма намерени съвпадения"

#: app/flatpak-builtins-uninstall.c:54
msgid "Arch to uninstall"
msgstr "Архитектура за деинсталиране"

#: app/flatpak-builtins-uninstall.c:55
msgid "Keep ref in local repository"
msgstr "Запазване на указателя в локалното хранилище"

#: app/flatpak-builtins-uninstall.c:56
msgid "Don't uninstall related refs"
msgstr "Без деинсталиране на свързани указатели"

#: app/flatpak-builtins-uninstall.c:57
msgid "Remove files even if running"
msgstr "Премахване на файлове, дори ако се изпълняват"

#: app/flatpak-builtins-uninstall.c:60
msgid "Uninstall all"
msgstr "Деинсталиране на всички"

#: app/flatpak-builtins-uninstall.c:61
msgid "Uninstall unused"
msgstr "Деинсталиране на неизползваните"

#: app/flatpak-builtins-uninstall.c:62
msgid "Delete app data"
msgstr "Премахване на данните на програмата"

#: app/flatpak-builtins-uninstall.c:141
#, c-format
msgid "Delete data for %s?"
msgstr "Премахване на данните за %s?"

#: app/flatpak-builtins-uninstall.c:220
#, c-format
msgid "Info: applications using the extension %s%s%s branch %s%s%s:\n"
msgstr "ИНФОРМАЦИЯ: програми, използващи разширението %s%s%s от клон %s%s%s:\n"

#: app/flatpak-builtins-uninstall.c:223
#, c-format
msgid "Info: applications using the runtime %s%s%s branch %s%s%s:\n"
msgstr ""
"ИНФОРМАЦИЯ: програми, използващи средата за изпълнение %s%s%s от клон "
"%s%s%s:\n"

#: app/flatpak-builtins-uninstall.c:238
msgid "Really remove?"
msgstr "Сигурни ли сте за изтриването?"

#: app/flatpak-builtins-uninstall.c:255
msgid "[REF…] - Uninstall applications or runtimes"
msgstr "[УКАЗАТЕЛ…] — деинсталиране на програми или среди за изпълнение"

#: app/flatpak-builtins-uninstall.c:264
msgid "Must specify at least one REF, --unused, --all or --delete-data"
msgstr ""
"Трябва да зададете поне един указател, „--unused“, „--all“ или „--delete-"
"data“"

#: app/flatpak-builtins-uninstall.c:267
msgid "Must not specify REFs when using --all"
msgstr "Не трябва да задавате указатели, когато използвате „--all“"

#: app/flatpak-builtins-uninstall.c:270
msgid "Must not specify REFs when using --unused"
msgstr "Не трябва да задавате указатели, когато използвате „--unused“"

#: app/flatpak-builtins-uninstall.c:336
#, c-format
msgid ""
"\n"
"These runtimes in installation '%s' are pinned and won't be removed; see "
"flatpak-pin(1):\n"
msgstr ""
"\n"
"Тези среди за изпълнение в инсталацията „%s“ са закачени и няма да се "
"премахнат. Вижте flatpak-pin(1):\n"

#: app/flatpak-builtins-uninstall.c:370
#, c-format
msgid "Nothing unused to uninstall\n"
msgstr "Няма нищо неизползвано за деинсталиране\n"

#: app/flatpak-builtins-uninstall.c:444
#, c-format
msgid "No installed refs found for ‘%s’"
msgstr "Няма намерени инсталирани указатели за „%s“"

#: app/flatpak-builtins-uninstall.c:447
#, c-format
msgid " with arch ‘%s’"
msgstr " с архитектура „%s“"

#: app/flatpak-builtins-uninstall.c:449
#, c-format
msgid " with branch ‘%s’"
msgstr " с клон „%s“"

#: app/flatpak-builtins-uninstall.c:456
#, c-format
msgid "Warning: %s is not installed\n"
msgstr "ВНИМАНИЕ: %s не е инсталирано\n"

#: app/flatpak-builtins-uninstall.c:490
#, c-format
msgid "None of the specified refs are installed"
msgstr "Нито един от посочените указатели не е инсталиран"

#: app/flatpak-builtins-uninstall.c:599
#, c-format
msgid "No app data to delete\n"
msgstr ""

#: app/flatpak-builtins-update.c:56
msgid "Arch to update for"
msgstr "Архитектура, за която да се обнови"

#: app/flatpak-builtins-update.c:57
msgid "Commit to deploy"
msgstr "Подаване за качване"

#: app/flatpak-builtins-update.c:58
msgid "Remove old files even if running"
msgstr "Премахване на стари файлове, дори ако се изпълняват"

#: app/flatpak-builtins-update.c:59
msgid "Don't pull, only update from local cache"
msgstr "Без издърпване, само обновяване на локалния кеш"

#: app/flatpak-builtins-update.c:61
msgid "Don't update related refs"
msgstr "Без обновяване на свързаните указатели"

#: app/flatpak-builtins-update.c:66
msgid "Update appstream for remote"
msgstr "Обновяване на appstream за отдалеченото хранилище"

#: app/flatpak-builtins-update.c:67
msgid "Only update this subpath"
msgstr "Обновяване само на този подпът"

#: app/flatpak-builtins-update.c:90
msgid "[REF…] - Update applications or runtimes"
msgstr "[УКАЗАТЕЛ…] — обновяване на програми или среди за изпълнение"

#: app/flatpak-builtins-update.c:121
msgid "With --commit, only one REF may be specified"
msgstr "Опцията „--commit“ приема само един указател"

#: app/flatpak-builtins-update.c:162
#, c-format
msgid "Looking for updates…\n"
msgstr "Проверяване за обновления…\n"

#: app/flatpak-builtins-update.c:215
#, c-format
msgid "Unable to update %s: %s\n"
msgstr "%s не може да се обнови: %s\n"

#: app/flatpak-builtins-update.c:274
#, fuzzy, c-format
msgid "Nothing to update.\n"
msgstr "Няма нищо за правене.\n"

#: app/flatpak-builtins-utils.c:337
#, fuzzy, c-format
msgid ""
"Remote ‘%s’ found in multiple installations, unable to proceed in non-"
"interactive mode"
msgstr ""
"Указателят „%s“ е намерен в няколко инсталации: %s. Трябва да посочите само "
"една."

#: app/flatpak-builtins-utils.c:346
#, c-format
msgid "Remote ‘%s’ found in multiple installations:"
msgstr "Отдалеченото хранилище „%s“ е намерено в няколко инсталации:"

#: app/flatpak-builtins-utils.c:347 app/flatpak-builtins-utils.c:442
#: app/flatpak-builtins-utils.c:538 app/flatpak-builtins-utils.c:540
#: app/flatpak-builtins-utils.c:598
msgid "Which do you want to use (0 to abort)?"
msgstr "Кое искате да използвате („0“ за прекратяване)?"

#: app/flatpak-builtins-utils.c:349
#, c-format
msgid "No remote chosen to resolve ‘%s’ which exists in multiple installations"
msgstr ""
"Няма избрано отдалечено хранилище за разрешаване на „%s“, което съществува в "
"няколко инсталации"

#: app/flatpak-builtins-utils.c:358
#, c-format
msgid ""
"Remote \"%s\" not found\n"
"Hint: Use flatpak remote-add to add a remote"
msgstr ""
"Отдалеченото хранилище „%s“ липсва\n"
"ПОДСКАЗКА: Използвайте flatpak remote-add, за да добавите отдалечено "
"хранилище"

#: app/flatpak-builtins-utils.c:364
#, c-format
msgid "Remote \"%s\" not found in the %s installation"
msgstr "Отдалеченото хранилище „%s“ не може да се намери в инсталацията %s"

#: app/flatpak-builtins-utils.c:404
#, c-format
msgid "Multiple refs match ‘%s’, unable to proceed in non-interactive mode"
msgstr ""

#. default to yes on Enter
#: app/flatpak-builtins-utils.c:430
#, c-format
msgid ""
"Found ref ‘%s’ in remote ‘%s’ (%s).\n"
"Use this ref?"
msgstr ""
"Намерен е указателя „%s“ в отдалеченото хранилище „%s“ (%s).\n"
"Използване на този указател?"

#: app/flatpak-builtins-utils.c:434 app/flatpak-builtins-utils.c:444
#: app/flatpak-builtins-utils.c:522 app/flatpak-builtins-utils.c:543
#, c-format
msgid "No ref chosen to resolve matches for ‘%s’"
msgstr "Няма избран указател за разрешаване на съвпадения за „%s“"

#: app/flatpak-builtins-utils.c:440
#, c-format
msgid "Similar refs found for ‘%s’ in remote ‘%s’ (%s):"
msgstr ""
"Намерени са подобни указатели за „%s“ в отдалеченото хранилище „%s“ (%s):"

#: app/flatpak-builtins-utils.c:488
#, c-format
msgid ""
"Multiple installed refs match ‘%s’, unable to proceed in non-interactive mode"
msgstr ""

#. default to yes on Enter
#: app/flatpak-builtins-utils.c:518
#, c-format
msgid "Found installed ref ‘%s’ (%s). Is this correct?"
msgstr "Намерен е инсталирания указател „%s“ (%s). Правилно ли е това?"

#: app/flatpak-builtins-utils.c:534
#, c-format
msgid "All of the above"
msgstr "Всичко изброено по-горе"

#: app/flatpak-builtins-utils.c:535
#, c-format
msgid "Similar installed refs found for ‘%s’:"
msgstr "Намерени са подобни инсталирани указатели за „%s“:"

#: app/flatpak-builtins-utils.c:579
#, c-format
msgid ""
"Multiple remotes have refs matching ‘%s’, unable to proceed in non-"
"interactive mode"
msgstr ""

#: app/flatpak-builtins-utils.c:597
#, c-format
msgid "Remotes found with refs similar to ‘%s’:"
msgstr "Намерени са подобни указатели на „%s“:"

#: app/flatpak-builtins-utils.c:600
#, c-format
msgid "No remote chosen to resolve matches for ‘%s’"
msgstr "Няма избрано отдалечено хранилище за разрешаване на съвпадения за „%s“"

#: app/flatpak-builtins-utils.c:696 app/flatpak-builtins-utils.c:699
#, c-format
msgid "Updating appstream data for user remote %s"
msgstr ""
"Обновяване на данните на appstream за потребителското отдалечено хранилище %s"

#: app/flatpak-builtins-utils.c:706 app/flatpak-builtins-utils.c:709
#, c-format
msgid "Updating appstream data for remote %s"
msgstr "Обновяване на данните на appstream за отдалечено хранилище %s"

#: app/flatpak-builtins-utils.c:717 app/flatpak-builtins-utils.c:719
msgid "Error updating"
msgstr "Грешка при обновяването"

#: app/flatpak-builtins-utils.c:755
#, c-format
msgid "Remote \"%s\" not found"
msgstr "Отдалеченото хранилище „%s“ липсва"

#: app/flatpak-builtins-utils.c:796
#, c-format
msgid "Ambiguous suffix: '%s'."
msgstr "Нееднозначен суфикс: „%s“."

#. Translators: don't translate the values
#: app/flatpak-builtins-utils.c:798 app/flatpak-builtins-utils.c:813
msgid "Possible values are :s[tart], :m[iddle], :e[nd] or :f[ull]"
msgstr "Допустимите стойности са :s[tart], :m[iddle], :e[nd] или :f[ull]"

#: app/flatpak-builtins-utils.c:811
#, c-format
msgid "Invalid suffix: '%s'."
msgstr "Неправилен суфикс: „%s“."

#: app/flatpak-builtins-utils.c:846
#, c-format
msgid "Ambiguous column: %s"
msgstr "Нееднозначна колона: %s"

#: app/flatpak-builtins-utils.c:859
#, c-format
msgid "Unknown column: %s"
msgstr "Неизвестна колона: %s"

#: app/flatpak-builtins-utils.c:917
msgid "Available columns:\n"
msgstr "Налични колони:\n"

#: app/flatpak-builtins-utils.c:927
msgid "Show all columns"
msgstr "Извеждане на всички колони"

#: app/flatpak-builtins-utils.c:928
msgid "Show available columns"
msgstr "Извеждане на наличните колони"

#: app/flatpak-builtins-utils.c:931
msgid "Append :s[tart], :m[iddle], :e[nd] or :f[ull] to change ellipsization"
msgstr ""
"Добавяне на :s[tart], :m[iddle], :e[nd] или :f[ull] за промяна на "
"съкращаването"

#: app/flatpak-builtins-utils.c:1483
#, c-format
msgid "Unknown scheme in sideload location %s"
msgstr ""

#: app/flatpak-cli-transaction.c:96 app/flatpak-cli-transaction.c:102
#, c-format
msgid "Required runtime for %s (%s) found in remote %s\n"
msgstr ""
"Необходимата среда за изпълнение за %s (%s) е намерена в отдалеченото "
"хранилище %s\n"

#: app/flatpak-cli-transaction.c:104
msgid "Do you want to install it?"
msgstr "Искате ли да го инсталирате?"

#: app/flatpak-cli-transaction.c:110
#, c-format
msgid "Required runtime for %s (%s) found in remotes:"
msgstr ""
"Необходимата среда за изпълнение за %s (%s) е намерена в следните отдалечени "
"хранилища:"

#: app/flatpak-cli-transaction.c:112
msgid "Which do you want to install (0 to abort)?"
msgstr "Кое искате да инсталирате („0“ за прекратяване)?"

#: app/flatpak-cli-transaction.c:132
#, c-format
msgid "Configuring %s as new remote '%s'\n"
msgstr "Настройване на „%s“ като ново отдалечено хранилище „%s“\n"

#. default to yes on Enter
#: app/flatpak-cli-transaction.c:139
#, c-format
msgid ""
"The remote '%s', referred to by '%s' at location %s contains additional "
"applications.\n"
"Should the remote be kept for future installations?"
msgstr ""
"Отдалеченото хранилище „%s“, ползвано от „%s“ на местоположението %s, "
"съдържа допълнителни програми.\n"
"Хранилището да се запази ли за бъдещи инсталации?"

#. default to yes on Enter
#: app/flatpak-cli-transaction.c:147
#, c-format
msgid ""
"The application %s depends on runtimes from:\n"
"  %s\n"
"Configure this as new remote '%s'"
msgstr ""
"Програмата %s зависи от средите за изпълнение от:\n"
"  %s\n"
"Настройте това като ново отдалечено хранилище „%s“"

#. Formatted size/remaining time in seconds
#: app/flatpak-cli-transaction.c:321
#, c-format
msgid "%s/s%s%s"
msgstr ""

#. Download progress percentage, use the appropriate
#. percent format for your language
#: app/flatpak-cli-transaction.c:359
#, c-format
msgid "%3d%%"
msgstr ""

#: app/flatpak-cli-transaction.c:414
msgid "Installing…"
msgstr "Инсталиране…"

#: app/flatpak-cli-transaction.c:416
#, c-format
msgid "Installing %d/%d…"
msgstr "Инсталиране %d/%d…"

#: app/flatpak-cli-transaction.c:421
msgid "Updating…"
msgstr "Обновяване…"

#: app/flatpak-cli-transaction.c:423
#, c-format
msgid "Updating %d/%d…"
msgstr "Обновяване %d/%d…"

#: app/flatpak-cli-transaction.c:428
msgid "Uninstalling…"
msgstr "Деинсталиране…"

#: app/flatpak-cli-transaction.c:430
#, c-format
msgid "Uninstalling %d/%d…"
msgstr "Деинсталиране %d/%d…"

#: app/flatpak-cli-transaction.c:496 app/flatpak-quiet-transaction.c:161
#, c-format
msgid "Info: %s was skipped"
msgstr "ИНФОРМАЦИЯ: %s е пропуснато"

#: app/flatpak-cli-transaction.c:519
#, c-format
msgid "Warning: %s%s%s already installed"
msgstr "ВНИМАНИЕ: %s%s%s вече е инсталирано"

#: app/flatpak-cli-transaction.c:522
#, c-format
msgid "Error: %s%s%s already installed"
msgstr "ГРЕШКА: %s%s%s вече е инсталирано"

#: app/flatpak-cli-transaction.c:528
#, c-format
msgid "Warning: %s%s%s not installed"
msgstr "ВНИМАНИЕ: %s%s%s не е инсталирано"

#: app/flatpak-cli-transaction.c:531
#, c-format
msgid "Error: %s%s%s not installed"
msgstr "ГРЕШКА: %s%s%s не е инсталирано"

#: app/flatpak-cli-transaction.c:537
#, c-format
msgid "Warning: %s%s%s needs a later flatpak version"
msgstr "ВНИМАНИЕ: %s%s%s изисква по-нова версия на flatpak"

#: app/flatpak-cli-transaction.c:540
#, c-format
msgid "Error: %s%s%s needs a later flatpak version"
msgstr "ГРЕШКА: %s%s%s изисква по-нова версия на flatpak"

#: app/flatpak-cli-transaction.c:546
msgid "Warning: Not enough disk space to complete this operation"
msgstr ""
"ВНИМАНИЕ: няма достатъчно дисково пространство за завършване на тази операция"

#: app/flatpak-cli-transaction.c:548
msgid "Error: Not enough disk space to complete this operation"
msgstr ""
"ГРЕШКА: Няма достатъчно дисково пространство за завършване на тази операция"

#: app/flatpak-cli-transaction.c:553
#, c-format
msgid "Warning: %s"
msgstr "ВНИМАНИЕ: %s"

#: app/flatpak-cli-transaction.c:555
#, c-format
msgid "Error: %s"
msgstr "ГРЕШКА: %s"

#: app/flatpak-cli-transaction.c:570
#, c-format
msgid "Failed to install %s%s%s: "
msgstr "%s%s%s не може да се инсталира: "

#: app/flatpak-cli-transaction.c:577
#, c-format
msgid "Failed to update %s%s%s: "
msgstr "%s%s%s не може да се обнови: "

#: app/flatpak-cli-transaction.c:584
#, c-format
msgid "Failed to install bundle %s%s%s: "
msgstr "Пакетът %s%s%s не може да се инсталира: "

#: app/flatpak-cli-transaction.c:591
#, c-format
msgid "Failed to uninstall %s%s%s: "
msgstr "%s%s%s не може да се деинсталира: "

#: app/flatpak-cli-transaction.c:642
#, c-format
msgid "Authentication required for remote '%s'\n"
msgstr "За отдалеченото хранилище „%s“ е необходима идентификация\n"

#: app/flatpak-cli-transaction.c:643
msgid "Open browser?"
msgstr "Отваряне на браузър?"

#: app/flatpak-cli-transaction.c:699
#, c-format
msgid "Login required remote %s (realm %s)\n"
msgstr "За отдалеченото хранилище %s (сфера %s) е необходимо вписване\n"

#: app/flatpak-cli-transaction.c:704
msgid "Password"
msgstr "Парола"

#. Only runtimes can be pinned
#: app/flatpak-cli-transaction.c:759
#, c-format
msgid ""
"\n"
"Info: (pinned) runtime %s%s%s branch %s%s%s is end-of-life, in favor of "
"%s%s%s branch %s%s%s\n"
msgstr ""
"\n"
"ИНФОРМАЦИЯ: (закачената) среда за изпълнение %s%s%s клон %s%s%s не получава "
"обновления, в ползва на %s%s%s клон %s%s%s:\n"

#: app/flatpak-cli-transaction.c:765
#, c-format
msgid ""
"\n"
"Info: runtime %s%s%s branch %s%s%s is end-of-life, in favor of %s%s%s branch "
"%s%s%s\n"
msgstr ""
"\n"
"ИНФОРМАЦИЯ: средата за изпълнение %s%s%s клон %s%s%s не получава обновления, "
"в ползва на %s%s%s клон %s%s%s:\n"

#: app/flatpak-cli-transaction.c:768
#, c-format
msgid ""
"\n"
"Info: app %s%s%s branch %s%s%s is end-of-life, in favor of %s%s%s branch "
"%s%s%s\n"
msgstr ""
"\n"
"ИНФОРМАЦИЯ: програмата %s%s%s клон %s%s%s не получава обновления, в ползва "
"на %s%s%s клон %s%s%s:\n"

#. Only runtimes can be pinned
#: app/flatpak-cli-transaction.c:780
#, c-format
msgid ""
"\n"
"Info: (pinned) runtime %s%s%s branch %s%s%s is end-of-life, with reason:\n"
msgstr ""
"\n"
"ИНФОРМАЦИЯ: (закачената) среда за изпълнение %s%s%s клон %s%s%s не получава "
"обновления, с причина:\n"

#: app/flatpak-cli-transaction.c:786
#, c-format
msgid ""
"\n"
"Info: runtime %s%s%s branch %s%s%s is end-of-life, with reason:\n"
msgstr ""
"\n"
"ИНФОРМАЦИЯ: средата за изпълнение %s%s%s клон %s%s%s не получава обновления, "
"с причина:\n"

#: app/flatpak-cli-transaction.c:789
#, c-format
msgid ""
"\n"
"Info: app %s%s%s branch %s%s%s is end-of-life, with reason:\n"
msgstr ""
"\n"
"ИНФОРМАЦИЯ: програмата %s%s%s клон %s%s%s не получава обновления, с "
"причина:\n"

#: app/flatpak-cli-transaction.c:963
#, c-format
msgid "Info: applications using this extension:\n"
msgstr "ИНФОРМАЦИЯ: програми използващи това разширение:\n"

#: app/flatpak-cli-transaction.c:965
#, c-format
msgid "Info: applications using this runtime:\n"
msgstr "ИНФОРМАЦИЯ: програми използващи тази среда за изпълнение:\n"

#: app/flatpak-cli-transaction.c:984
msgid "Replace?"
msgstr "Заместване?"

#: app/flatpak-cli-transaction.c:987 app/flatpak-quiet-transaction.c:247
#, c-format
msgid "Updating to rebased version\n"
msgstr "Обновяване до пребазирана версия\n"

#: app/flatpak-cli-transaction.c:1011
#, c-format
msgid "Failed to rebase %s to %s: "
msgstr "Пребазирането на %s към %s е неуспешно: "

#: app/flatpak-cli-transaction.c:1277
#, c-format
msgid "New %s%s%s permissions:"
msgstr "Нови права̀ за %s%s%s:"

#: app/flatpak-cli-transaction.c:1279
#, c-format
msgid "%s%s%s permissions:"
msgstr "Права̀ за %s%s%s:"

#: app/flatpak-cli-transaction.c:1343
msgid "Warning: "
msgstr "ВНИМАНИЕ: "

#. translators: This is short for operation, the title of a one-char column
#: app/flatpak-cli-transaction.c:1442
msgid "Op"
msgstr "Оп"

#. Avoid resizing the download column too much,
#. * by making the title as long as typical content
#.
#: app/flatpak-cli-transaction.c:1458 app/flatpak-cli-transaction.c:1503
msgid "partial"
msgstr "частично"

#: app/flatpak-cli-transaction.c:1535
msgid "Proceed with these changes to the user installation?"
msgstr "Да се приложат ли промените за потребителската инсталация?"

#: app/flatpak-cli-transaction.c:1537
msgid "Proceed with these changes to the system installation?"
msgstr "Да се приложат ли промените за системната инсталация?"

#: app/flatpak-cli-transaction.c:1539
#, c-format
msgid "Proceed with these changes to the %s?"
msgstr "Да се приложат ли промените за %s?"

#: app/flatpak-cli-transaction.c:1711
msgid "Changes complete."
msgstr "Промените завършиха."

#: app/flatpak-cli-transaction.c:1713
msgid "Uninstall complete."
msgstr "Деинсталирането завърши."

#: app/flatpak-cli-transaction.c:1715
msgid "Installation complete."
msgstr "Инсталирането завърши."

#: app/flatpak-cli-transaction.c:1717
msgid "Updates complete."
msgstr "Обновленията завършиха."

#. For updates/!stop_on_first_error we already printed all errors so we make up
#. a different one.
#: app/flatpak-cli-transaction.c:1750
msgid "There were one or more errors"
msgstr "Имаше една или повече грешки"

#. translators: please keep the leading space
#: app/flatpak-main.c:76
msgid " Manage installed applications and runtimes"
msgstr " Управление на инсталираните програми и среди за изпълнение"

#: app/flatpak-main.c:77
msgid "Install an application or runtime"
msgstr "Инсталиране на програма или среда за изпълнение"

#: app/flatpak-main.c:78
msgid "Update an installed application or runtime"
msgstr "Обновяване на инсталирана програма или среда за изпълнение"

#: app/flatpak-main.c:81
msgid "Uninstall an installed application or runtime"
msgstr "Деинсталиране на инсталирана програма или среда за изпълнение"

#: app/flatpak-main.c:84
msgid "Mask out updates and automatic installation"
msgstr "Изключване на обновленията и автоматичното инсталиране"

#: app/flatpak-main.c:85
msgid "Pin a runtime to prevent automatic removal"
msgstr ""
"Закачване на среда за изпълнение за предотвратяване на автоматично "
"отстраняване"

#: app/flatpak-main.c:86
msgid "List installed apps and/or runtimes"
msgstr "Изброяване на инсталираните програми и/или среди за изпълнение"

#: app/flatpak-main.c:87
msgid "Show info for installed app or runtime"
msgstr ""
"Извеждане на информацията за инсталираната програма или среда за изпълнение"

#: app/flatpak-main.c:88
msgid "Show history"
msgstr "Извеждане на историята"

#: app/flatpak-main.c:89
msgid "Configure flatpak"
msgstr "Настройване на flatpak"

#: app/flatpak-main.c:90
msgid "Repair flatpak installation"
msgstr "Поправяне на инсталация на flatpak"

#: app/flatpak-main.c:91
msgid "Put applications or runtimes onto removable media"
msgstr "Поставяне на програми или среди за изпълнение на преносимо устройство"

#: app/flatpak-main.c:92
msgid "Install flatpaks that are part of the operating system"
msgstr ""

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:95
msgid ""
"\n"
" Find applications and runtimes"
msgstr ""
"\n"
" Търсене на програми и среди за изпълнение"

#: app/flatpak-main.c:96
msgid "Search for remote apps/runtimes"
msgstr "Търсене на отдалечени програми/среди за изпълнение"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:99
msgid ""
"\n"
" Manage running applications"
msgstr ""
"\n"
" Управление на работещи програми"

#: app/flatpak-main.c:100
msgid "Run an application"
msgstr "Изпълняване на програма"

#: app/flatpak-main.c:101
msgid "Override permissions for an application"
msgstr "Пренебрегване на права̀та за програма"

#: app/flatpak-main.c:102
msgid "Specify default version to run"
msgstr "Задаване на стандартната версия за изпълнение"

#: app/flatpak-main.c:103
msgid "Enter the namespace of a running application"
msgstr "Въведете пространство от имена на работеща програма"

#: app/flatpak-main.c:104
msgid "Enumerate running applications"
msgstr "Изброяване на работещите програми"

#: app/flatpak-main.c:105
msgid "Stop a running application"
msgstr "Спиране на работеща програма"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:108
msgid ""
"\n"
" Manage file access"
msgstr ""
"\n"
" Управление на достъпа до файлове"

#: app/flatpak-main.c:109
msgid "List exported files"
msgstr "Изброяване на изнесените файлове"

#: app/flatpak-main.c:110
msgid "Grant an application access to a specific file"
msgstr "Позволяване на достъп на програмата до определен файл"

#: app/flatpak-main.c:111
msgid "Revoke access to a specific file"
msgstr "Премахване на достъпа на програмата до определен файл"

#: app/flatpak-main.c:112
msgid "Show information about a specific file"
msgstr "Извеждане на информация за определен файл"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:116
msgid ""
"\n"
" Manage dynamic permissions"
msgstr ""
"\n"
" Управление на динамични права̀"

#: app/flatpak-main.c:117
msgid "List permissions"
msgstr "Изброяване на права̀та"

#: app/flatpak-main.c:118
msgid "Remove item from permission store"
msgstr "Премахване на елемент от хранилището за права̀"

#: app/flatpak-main.c:120
msgid "Set permissions"
msgstr "Задаване на права̀"

#: app/flatpak-main.c:121
msgid "Show app permissions"
msgstr "Извеждане на права̀та на програмата"

#: app/flatpak-main.c:122
msgid "Reset app permissions"
msgstr "Връщане на права̀та на програмата"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:125
msgid ""
"\n"
" Manage remote repositories"
msgstr ""
"\n"
" Управлeние на отдалечените хранилища"

#: app/flatpak-main.c:126
msgid "List all configured remotes"
msgstr "Изброяване на всички настроени отдалечени хранилища"

#: app/flatpak-main.c:127
msgid "Add a new remote repository (by URL)"
msgstr "Добавяне на ново отдалечено хранилище (с адрес)"

#: app/flatpak-main.c:128
msgid "Modify properties of a configured remote"
msgstr "Промяна на настройките на настроено отдалечено хранилище"

#: app/flatpak-main.c:129
msgid "Delete a configured remote"
msgstr "Изтриване на настроено отдалечено хранилище"

#: app/flatpak-main.c:131
msgid "List contents of a configured remote"
msgstr "Извеждане на съдържанието на настроено отдалечено хранилище"

#: app/flatpak-main.c:132
msgid "Show information about a remote app or runtime"
msgstr ""
"Извеждане на информацията за отдалечена програма или среда за изпълнение"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:135
msgid ""
"\n"
" Build applications"
msgstr ""
"\n"
" Изграждане на програми"

#: app/flatpak-main.c:136
msgid "Initialize a directory for building"
msgstr "Инициализиране на директория за изграждане"

#: app/flatpak-main.c:137
msgid "Run a build command inside the build dir"
msgstr "Изпълняване на команда за изграждане в директорията за изграждане"

#: app/flatpak-main.c:138
msgid "Finish a build dir for export"
msgstr "Подготвяне на директория за изграждане за изнасяне"

#: app/flatpak-main.c:139
msgid "Export a build dir to a repository"
msgstr "Изнасяне на директория за изграждане в хранилище"

#: app/flatpak-main.c:140
msgid "Create a bundle file from a ref in a local repository"
msgstr "Създаване на пратка от указател на локално хранилище"

#: app/flatpak-main.c:141
msgid "Import a bundle file"
msgstr "Внасяне на пратка"

#: app/flatpak-main.c:142
msgid "Sign an application or runtime"
msgstr "Подписване на програма или среда за изпълнение"

#: app/flatpak-main.c:143
msgid "Update the summary file in a repository"
msgstr "Обновяване на файла за обобщение на хранилище"

#: app/flatpak-main.c:144
msgid "Create new commit based on existing ref"
msgstr "Създаване на ново подаване според съществуващ указател"

#: app/flatpak-main.c:145
msgid "Show information about a repo"
msgstr "Извеждане на информацията за хранилище"

#: app/flatpak-main.c:162
msgid "Show debug information, -vv for more detail"
msgstr ""
"Показване на информация за отстраняване на грешки, „-vv“ за повече "
"подробности"

#: app/flatpak-main.c:163
msgid "Show OSTree debug information"
msgstr "Показване на информация на OSTree за отстраняване на грешки"

#: app/flatpak-main.c:169
msgid "Print version information and exit"
msgstr "Извеждане на версията и изход"

#: app/flatpak-main.c:170
msgid "Print default arch and exit"
msgstr "Извеждане на стандартната архитектура и изход"

#: app/flatpak-main.c:171
msgid "Print supported arches and exit"
msgstr "Извеждане на поддържаните версии на архитектура и изход"

#: app/flatpak-main.c:172
msgid "Print active gl drivers and exit"
msgstr "Извеждане на активните графични драйвери и изход"

#: app/flatpak-main.c:173
msgid "Print paths for system installations and exit"
msgstr "Извеждане на пътищата за системните инсталации и изход"

#: app/flatpak-main.c:174
msgid "Print the updated environment needed to run flatpaks"
msgstr ""
"Извеждане на обновената среда, необходима за стартиране на програми с Flatpak"

#: app/flatpak-main.c:175
msgid "Only include the system installation with --print-updated-env"
msgstr "Включване само на системната инсталация с „--print-updated-env“"

#: app/flatpak-main.c:180
msgid "Work on the user installation"
msgstr "В потребителска инсталация"

#: app/flatpak-main.c:181
msgid "Work on the system-wide installation (default)"
msgstr "В инсталация за цялата система (стандартно)"

#: app/flatpak-main.c:182
msgid "Work on a non-default system-wide installation"
msgstr "В нестандартна инсталация за цялата система"

#: app/flatpak-main.c:212
msgid "Builtin Commands:"
msgstr "Вградени команди:"

#: app/flatpak-main.c:298
#, c-format
msgid ""
"Note that the directories %s are not in the search path set by the "
"XDG_DATA_DIRS environment variable, so applications installed by Flatpak may "
"not appear on your desktop until the session is restarted."
msgstr ""
"Директориите %s не са в пътя за търсене, зададен от променливата на средата "
"„XDG_DATA_DIRS“, така че програмите, инсталирани от Flatpak, може да не се "
"появят на работния плот, докато сесията не се рестартира."

#: app/flatpak-main.c:312
#, c-format
msgid ""
"Note that the directory %s is not in the search path set by the "
"XDG_DATA_DIRS environment variable, so applications installed by Flatpak may "
"not appear on your desktop until the session is restarted."
msgstr ""
"Директорията %s не е в пътя за търсене, зададен от променливата на средата "
"„XDG_DATA_DIRS“, така че програмите, инсталирани от Flatpak, може да не се "
"появят на работния плот, докато сесията не се рестартира."

#: app/flatpak-main.c:381
msgid ""
"Refusing to operate under sudo with --user. Omit sudo to operate on the user "
"installation, or use a root shell to operate on the root user's installation."
msgstr ""
"Отказ да се работи като администратор с „--user“. Пропуснете „sudo“, за да "
"работите с потребителската инсталация, или използвайте администраторска "
"обвивката, за да работите с администраторската инсталация."

#: app/flatpak-main.c:453
msgid ""
"Multiple installations specified for a command that works on one installation"
msgstr ""
"Посочени са няколко инсталации за команда, която работи само на една "
"инсталация"

#: app/flatpak-main.c:504 app/flatpak-main.c:697
#, c-format
msgid "See '%s --help'"
msgstr "Вижте „%s --help“"

#: app/flatpak-main.c:706
#, c-format
msgid "'%s' is not a flatpak command. Did you mean '%s%s'?"
msgstr "„%s“ не е команда на Flatpak. Да нямате предвид „%s%s“?"

#: app/flatpak-main.c:709
#, c-format
msgid "'%s' is not a flatpak command"
msgstr "„%s“ не е команда на Flatpak"

#: app/flatpak-main.c:824
msgid "No command specified"
msgstr "Не е дадена команда"

#: app/flatpak-main.c:980
msgid "error:"
msgstr "ГРЕШКА:"

#: app/flatpak-quiet-transaction.c:77
#, c-format
msgid "Installing %s\n"
msgstr "Инсталиране на „%s“\n"

#: app/flatpak-quiet-transaction.c:81
#, c-format
msgid "Updating %s\n"
msgstr "Обновяване на „%s“\n"

#: app/flatpak-quiet-transaction.c:85
#, c-format
msgid "Uninstalling %s\n"
msgstr "Деинсталиране на „%s“\n"

#: app/flatpak-quiet-transaction.c:107
#, c-format
msgid "Warning: Failed to install %s: %s\n"
msgstr "ВНИМАНИЕ: „%s“ не може да се инсталира: %s\n"

#: app/flatpak-quiet-transaction.c:110
#, c-format
msgid "Error: Failed to install %s: %s\n"
msgstr "ГРЕШКА: „%s“ не може да се инсталира: %s\n"

#: app/flatpak-quiet-transaction.c:116
#, c-format
msgid "Warning: Failed to update %s: %s\n"
msgstr "ВНИМАНИЕ: „%s“ не може да се обнови: %s\n"

#: app/flatpak-quiet-transaction.c:119
#, c-format
msgid "Error: Failed to update %s: %s\n"
msgstr "ГРЕШКА: „%s“ не може да се обнови: %s\n"

#: app/flatpak-quiet-transaction.c:125
#, c-format
msgid "Warning: Failed to install bundle %s: %s\n"
msgstr "ВНИМАНИЕ: пакетът „%s“ не може да се инсталира: %s\n"

#: app/flatpak-quiet-transaction.c:128
#, c-format
msgid "Error: Failed to install bundle %s: %s\n"
msgstr "ГРЕШКА: пакетът „%s“ не може да се инсталира: %s\n"

#: app/flatpak-quiet-transaction.c:134
#, c-format
msgid "Warning: Failed to uninstall %s: %s\n"
msgstr "ВНИМАНИЕ: „%s“ не може да се деинсталира: %s\n"

#: app/flatpak-quiet-transaction.c:137
#, c-format
msgid "Error: Failed to uninstall %s: %s\n"
msgstr "ГРЕШКА: „%s“ не може да се деинсталира: %s\n"

#: app/flatpak-quiet-transaction.c:166 common/flatpak-dir.c:11475
#, c-format
msgid "%s already installed"
msgstr "„%s“ вече е инсталиран"

#: app/flatpak-quiet-transaction.c:168 common/flatpak-dir.c:3622
#: common/flatpak-dir.c:4321 common/flatpak-dir.c:16968
#: common/flatpak-dir.c:17258 common/flatpak-dir-utils.c:166
#: common/flatpak-dir-utils.c:259 common/flatpak-transaction.c:2736
#: common/flatpak-transaction.c:2791
#, c-format
msgid "%s not installed"
msgstr "„%s“ не е инсталиран"

#: app/flatpak-quiet-transaction.c:170
#, c-format
msgid "%s needs a later flatpak version"
msgstr "„%s“ изисква по-нова версия на Flatpak"

#: app/flatpak-quiet-transaction.c:172
msgid "Not enough disk space to complete this operation"
msgstr "Няма достатъчно дисково пространство за завършване на тази операция"

#: app/flatpak-quiet-transaction.c:239
#, c-format
msgid "Info: %s is end-of-life, in favor of %s\n"
msgstr "ИНФОРМАЦИЯ: „%s“ не получава обновления, в полза на „%s“\n"

#: app/flatpak-quiet-transaction.c:241
#, c-format
msgid "Info: %s is end-of-life, with reason: %s\n"
msgstr "ИНФОРМАЦИЯ: „%s“ не получава обновления, с причина: %s\n"

#: app/flatpak-quiet-transaction.c:251
#, c-format
msgid "Failed to rebase %s to %s: %s\n"
msgstr "Пребазирането на „%s“ към %s е неуспешно: %s\n"

#: common/flatpak-auth.c:58
#, c-format
msgid "No authenticator configured for remote `%s`"
msgstr "Няма настроен удостоверител за отдалеченото хранилище „%s“"

#: common/flatpak-context.c:637 common/flatpak-context.c:649
#, fuzzy, c-format
msgid "Invalid permission syntax: %s"
msgstr "Неправилно име на разширението „%s“"

#: common/flatpak-context.c:1207
#, c-format
msgid "Unknown share type %s, valid types are: %s"
msgstr "Неизвестен вид за споделяне %s, възможните видове са: %s"

#: common/flatpak-context.c:1228
#, c-format
msgid "Unknown policy type %s, valid types are: %s"
msgstr "Неизвестен вид политика „%s“, възможните видове са: %s"

#: common/flatpak-context.c:1266
#, c-format
msgid "Invalid dbus name %s"
msgstr "Неправилно име за dbus „%s“"

#: common/flatpak-context.c:1279
#, c-format
msgid "Unknown socket type %s, valid types are: %s"
msgstr "Неизвестен вид гнездо „%s“, възможните видове са: %s"

#: common/flatpak-context.c:1294
#, c-format
msgid "Unknown device type %s, valid types are: %s"
msgstr "Неизвестен вид устройство „%s“, възможните видове са: %s"

#: common/flatpak-context.c:1308
#, c-format
msgid "Unknown feature type %s, valid types are: %s"
msgstr "Неизвестен вид функция „%s“, възможните видове са: %s"

#: common/flatpak-context.c:1840
#, c-format
msgid "Filesystem location \"%s\" contains \"..\""
msgstr "Местоположението „%s“ на файловата система съдържа „..“"

#: common/flatpak-context.c:1882
#, c-format
msgid ""
"--filesystem=/ is not available, use --filesystem=host for a similar result"
msgstr ""
"„--filesystem=/“ не е налично, използвайте „--filesystem=host“ за подобен "
"резултат"

#: common/flatpak-context.c:1916
#, fuzzy, c-format
msgid ""
"Unknown filesystem location %s, valid locations are: host, host-os, host-"
"etc, host-root, home, xdg-*[/…], ~/dir, /dir"
msgstr ""
"Неизвестно местоположение „%s“ на файловата система, възможни местоположения "
"са: „host“, „host-os“, „host-etc“, „home“, „xdg-*[/…]“, ~/ДИРЕКТОРИЯ, /"
"ДИРЕКТОРИЯ"

#: common/flatpak-context.c:2015
#, fuzzy, c-format
msgid "Invalid syntax for %s: %s"
msgstr "Неправилно име %s: %s"

#: common/flatpak-context.c:2142
#, c-format
msgid "fallback-x11 can not be conditional"
msgstr ""

#: common/flatpak-context.c:2318
#, c-format
msgid "Invalid env format %s"
msgstr "Неправилен формат на средата %s"

#: common/flatpak-context.c:2399
#, c-format
msgid "Environment variable name must not contain '=': %s"
msgstr "Името на променливата на средата не може да съдържа „=“: %s"

#: common/flatpak-context.c:2527 common/flatpak-context.c:2535
#, c-format
msgid "--add-policy arguments must be in the form SUBSYSTEM.KEY=VALUE"
msgstr ""
"аргументите на „--add-policy“ трябва да се посочат като "
"ПОДСИСТЕМА.КЛЮЧ=СТОЙНОСТ"

#: common/flatpak-context.c:2542
#, c-format
msgid "--add-policy values can't start with \"!\""
msgstr "стойностите на „--add-policy“ не може да започват с „!“"

#: common/flatpak-context.c:2567 common/flatpak-context.c:2575
#, c-format
msgid "--remove-policy arguments must be in the form SUBSYSTEM.KEY=VALUE"
msgstr ""
"аргументите на „--remove-policy“ трябва да се посочат като "
"ПОДСИСТЕМА.КЛЮЧ=СТОЙНОСТ"

#: common/flatpak-context.c:2582
#, c-format
msgid "--remove-policy values can't start with \"!\""
msgstr "стойностите на „--remove-policy“ не може да започват с „!“"

#: common/flatpak-context.c:2657
msgid "Share with host"
msgstr "Споделяне с хоста"

#: common/flatpak-context.c:2657 common/flatpak-context.c:2658
msgid "SHARE"
msgstr "СПОДЕЛЯНЕ"

#: common/flatpak-context.c:2658
msgid "Unshare with host"
msgstr "Спиране на споделянето с хоста"

#: common/flatpak-context.c:2659
msgid "Require conditions to be met for a subsystem to get shared"
msgstr ""

#: common/flatpak-context.c:2659
msgid "SHARE:CONDITION"
msgstr ""

#: common/flatpak-context.c:2660
msgid "Expose socket to app"
msgstr "Разкриване на гнездо за програма"

#: common/flatpak-context.c:2660 common/flatpak-context.c:2661
msgid "SOCKET"
msgstr "ГНЕЗДО"

#: common/flatpak-context.c:2661
msgid "Don't expose socket to app"
msgstr "Без разкриване на гнездо за програма"

#: common/flatpak-context.c:2662
msgid "Require conditions to be met for a socket to get exposed"
msgstr ""

#: common/flatpak-context.c:2662
msgid "SOCKET:CONDITION"
msgstr ""

#: common/flatpak-context.c:2663
msgid "Expose device to app"
msgstr "Разкриване на устройство за програма"

#: common/flatpak-context.c:2663 common/flatpak-context.c:2664
msgid "DEVICE"
msgstr "УСТРОЙСТВО"

#: common/flatpak-context.c:2664
msgid "Don't expose device to app"
msgstr "Без разкриване на устройство за програма"

#: common/flatpak-context.c:2665
msgid "Require conditions to be met for a device to get exposed"
msgstr ""

#: common/flatpak-context.c:2665
msgid "DEVICE:CONDITION"
msgstr ""

#: common/flatpak-context.c:2666
msgid "Allow feature"
msgstr "Позволяване на функционалност"

#: common/flatpak-context.c:2666 common/flatpak-context.c:2667
msgid "FEATURE"
msgstr "ФУНКЦИОНАЛНОСТ"

#: common/flatpak-context.c:2667
msgid "Don't allow feature"
msgstr "Без позволяване на функционалност"

#: common/flatpak-context.c:2668
msgid "Require conditions to be met for a feature to get allowed"
msgstr ""

#: common/flatpak-context.c:2668
msgid "FEATURE:CONDITION"
msgstr ""

#: common/flatpak-context.c:2669
msgid "Expose filesystem to app (:ro for read-only)"
msgstr "Разкриване на файловата система за програмата („:ro“ само за четене)"

#: common/flatpak-context.c:2669
msgid "FILESYSTEM[:ro]"
msgstr "ФАЙЛОВА_СИСТЕМА[:ro]"

#: common/flatpak-context.c:2670
msgid "Don't expose filesystem to app"
msgstr "Програмата да вижда файловата система"

#: common/flatpak-context.c:2670
msgid "FILESYSTEM"
msgstr "ФАЙЛОВА_СИСТЕМА"

#: common/flatpak-context.c:2671
msgid "Set environment variable"
msgstr "Задаване на променлива на средата"

#: common/flatpak-context.c:2671
msgid "VAR=VALUE"
msgstr "ПРОМЕНЛИВА=СТОЙНОСТ"

#: common/flatpak-context.c:2672
msgid "Read environment variables in env -0 format from FD"
msgstr ""
"Четене на променливи на средата във формат „env -0“ от файловия дескриптор"

#: common/flatpak-context.c:2673
msgid "Remove variable from environment"
msgstr "Премахване на променливата от средата"

#: common/flatpak-context.c:2673
msgid "VAR"
msgstr "ПРОМЕНЛИВА"

#: common/flatpak-context.c:2674
msgid "Allow app to own name on the session bus"
msgstr "Позволяване на програмата да има собствено име в сесийната шина"

#: common/flatpak-context.c:2674 common/flatpak-context.c:2675
#: common/flatpak-context.c:2676 common/flatpak-context.c:2677
#: common/flatpak-context.c:2678 common/flatpak-context.c:2679
#: common/flatpak-context.c:2680
msgid "DBUS_NAME"
msgstr "ИМЕ_ЗА_DBUS"

#: common/flatpak-context.c:2675
msgid "Allow app to talk to name on the session bus"
msgstr "Позволяване на програмата да говори с това име в сесийната шина"

#: common/flatpak-context.c:2676
msgid "Don't allow app to talk to name on the session bus"
msgstr "Без позволяване на програмата да говори с това име в сесийната шина"

#: common/flatpak-context.c:2677
msgid "Allow app to own name on the system bus"
msgstr "Позволяване на програмата да има собствено име в системната шина"

#: common/flatpak-context.c:2678
msgid "Allow app to talk to name on the system bus"
msgstr "Позволяване на програмата да говори с това име в системната шина"

#: common/flatpak-context.c:2679
msgid "Don't allow app to talk to name on the system bus"
msgstr "Без позволяване на програмата да говори с това име в системната шина"

#: common/flatpak-context.c:2680
msgid "Allow app to own name on the a11y bus"
msgstr ""
"Позволяване на програмата да има собствено име с име в шината за достъпност"

#: common/flatpak-context.c:2681
msgid "Add generic policy option"
msgstr "Добавяне на обща опция за политика"

#: common/flatpak-context.c:2681 common/flatpak-context.c:2682
msgid "SUBSYSTEM.KEY=VALUE"
msgstr "ПОДСИСТЕМА.КЛЮЧ=СТОЙНОСТ"

#: common/flatpak-context.c:2682
msgid "Remove generic policy option"
msgstr "Премахване на общата опция за политика"

#: common/flatpak-context.c:2683
msgid "Add USB device to enumerables"
msgstr "Добавяне на USB устройство към списъка за изброяване"

#: common/flatpak-context.c:2683 common/flatpak-context.c:2684
msgid "VENDOR_ID:PRODUCT_ID"
msgstr "ИДЕНТИФИКАТОР_НА_ДОСТАВЧИКА:ИДЕНТИФИКАТОР_НА_ПРОДУКТА"

#: common/flatpak-context.c:2684
msgid "Add USB device to hidden list"
msgstr "Добавяне на USB устройство в скрития списък"

#: common/flatpak-context.c:2685
msgid "A list of USB devices that are enumerable"
msgstr "Списък с USB устройства, които да се изброяват"

#: common/flatpak-context.c:2685
msgid "LIST"
msgstr "СПИСЪК"

#: common/flatpak-context.c:2686
msgid "File containing a list of USB devices to make enumerable"
msgstr "Файл, съдържащ списък с USB устройства, които да се изброяват"

#: common/flatpak-context.c:2686 common/flatpak-context.c:2687
msgid "FILENAME"
msgstr "ИМЕ_НА_ФАЙЛ"

#: common/flatpak-context.c:2687
msgid "Persist home directory subpath"
msgstr "Постоянен подпът на домашната директория"

#. This is not needed/used anymore, so hidden, but we accept it for backwards compat
#: common/flatpak-context.c:2689
msgid "Don't require a running session (no cgroups creation)"
msgstr "Без изискване на работеща сесия (без създаване на cgroups)"

#: common/flatpak-context.c:3718
#, c-format
msgid "Not replacing \"%s\" with tmpfs: %s"
msgstr "Без замяна на „%s“ с tmpfs: %s"

#: common/flatpak-context.c:3726
#, c-format
msgid "Not sharing \"%s\" with sandbox: %s"
msgstr "„%s“ няма да се сподели с ограничената среда: %s"

#. Even if the error is one that we would normally silence, like
#. * the path not existing, it seems reasonable to make more of a fuss
#. * about the home directory not existing or otherwise being unusable,
#. * so this is intentionally not using cannot_export()
#: common/flatpak-context.c:3828
#, c-format
msgid "Not allowing home directory access: %s"
msgstr "Достъпът до домашната директория е отказан: %s"

#: common/flatpak-context.c:4062
#, c-format
msgid "Unable to provide a temporary home directory in the sandbox: %s"
msgstr ""
"Не може да се предостави временна домашна директория в ограничената среда: %s"

#: common/flatpak-dir.c:442
#, c-format
msgid "Configured collection ID ‘%s’ not in summary file"
msgstr ""
"Зададеният идентификатор на колекцията „%s“ не е във файла за обобщение"

#: common/flatpak-dir.c:587
#, c-format
msgid "Unable to load summary from remote %s: %s"
msgstr "Обобщението от отдалеченото хранилище %s не може да се зареди: %s"

#: common/flatpak-dir.c:764 common/flatpak-dir.c:800 common/flatpak-dir.c:906
#, c-format
msgid "No such ref '%s' in remote %s"
msgstr "Липсва указател „%s“ в отдалеченото хранилище %s"

#: common/flatpak-dir.c:891 common/flatpak-dir.c:1051 common/flatpak-dir.c:1080
#: common/flatpak-dir.c:1092
#, c-format
msgid "No entry for %s in remote %s summary flatpak cache"
msgstr "Липсва запис за %s в отдалечения %s flatpak кеш за обобщение"

#: common/flatpak-dir.c:1069
#, c-format
msgid "No summary or Flatpak cache available for remote %s"
msgstr "Липсва обобщение или кеш на Flatpak за отдалеченото хранилище %s"

#: common/flatpak-dir.c:1097
#, c-format
msgid "Missing xa.data in summary for remote %s"
msgstr "Липсват „xa.data“ в обобщението за отдалечено хранилище %s"

#: common/flatpak-dir.c:1103 common/flatpak-dir.c:1546
#, c-format
msgid "Unsupported summary version %d for remote %s"
msgstr "Неподдържана версия на обобщението %d за отдалечено хранилище %s"

#: common/flatpak-dir.c:1200
msgid "Remote OCI index has no registry uri"
msgstr "Отдалеченият индекс по OCI няма адрес в регистъра"

#: common/flatpak-dir.c:1261
#, c-format
msgid "Couldn't find ref %s in remote %s"
msgstr "Указателят %s липсва в отдалеченото хранилище %s"

#: common/flatpak-dir.c:1288 common/flatpak-dir.c:1381
#, fuzzy, c-format
msgid "Commit has no requested ref ‘%s’ in ref binding metadata (found: ‘%s’)"
msgstr ""
"Липсва заявен указател „%s“ в подаването в метаданните за зададени указатели"

#: common/flatpak-dir.c:1413
#, c-format
msgid "Configured collection ID ‘%s’ not in binding metadata"
msgstr ""
"Настроеният идентификатор за колекция „%s“ не е в метаданните за зададени "
"указатели"

#: common/flatpak-dir.c:1449 common/flatpak-dir.c:5645
#, c-format
msgid "Couldn't find latest checksum for ref %s in remote %s"
msgstr ""
"Най-новата контролна сума за указателя %s в отдалеченото хранилище %s не "
"може да се намери"

#: common/flatpak-dir.c:1516 common/flatpak-dir.c:1552
#, c-format
msgid "No entry for %s in remote %s summary flatpak sparse cache"
msgstr "Няма запис за %s в частичния отдалечен %s flatpak кеш на обобщението"

#: common/flatpak-dir.c:2540
#, c-format
msgid "Commit metadata for %s not matching expected metadata"
msgstr "Метаданните на подаването за %s не съвпадат с очакваните"

#: common/flatpak-dir.c:2823
msgid "Unable to connect to system bus"
msgstr "Неуспешно свързване към системната шина"

#: common/flatpak-dir.c:3419
msgid "User installation"
msgstr "Потребителска инсталация"

#: common/flatpak-dir.c:3426
#, c-format
msgid "System (%s) installation"
msgstr "Системна (%s) инсталация"

#: common/flatpak-dir.c:3472
#, c-format
msgid "No overrides found for %s"
msgstr "Липсва предефиниране за %s"

#: common/flatpak-dir.c:3625
#, c-format
msgid "%s (commit %s) not installed"
msgstr "%s (при подаване %s) не е инсталирано"

#: common/flatpak-dir.c:4650
#, c-format
msgid "Error parsing system flatpakrepo file for %s: %s"
msgstr "Грешка при разчитането на системния файл flatpakrepo за %s: %s"

#: common/flatpak-dir.c:4735
#, c-format
msgid "While opening repository %s: "
msgstr "По време на отварянето на хранилището %s: "

#: common/flatpak-dir.c:5004
#, c-format
msgid "The config key %s is not set"
msgstr "Ключът в настройките %s липсва"

#: common/flatpak-dir.c:5140
#, c-format
msgid "No current %s pattern matching %s"
msgstr "Няма шаблон %s, който да съответства на %s"

#: common/flatpak-dir.c:5422
msgid "No appstream commit to deploy"
msgstr "Няма подаване на appstream за качване"

#: common/flatpak-dir.c:5941 common/flatpak-dir.c:7266
#: common/flatpak-dir.c:10881 common/flatpak-dir.c:11618
msgid "Can't pull from untrusted non-gpg verified remote"
msgstr ""
"Издърпване от недоверено отдалечено хранилище, което не е потвърдено с gpg, "
"не е възможно"

#: common/flatpak-dir.c:6376 common/flatpak-dir.c:6591
msgid "Extra data not supported for non-gpg-verified local system installs"
msgstr ""
"Не се поддържат допълнителни данни за инсталации на локални системи, които "
"не са потвърдени с gpg"

#: common/flatpak-dir.c:6415 common/flatpak-dir.c:6782
#, c-format
msgid "Invalid checksum for extra data uri %s"
msgstr "Неправилна контролна сума за допълнителния адрес за данни %s"

#: common/flatpak-dir.c:6424
#, c-format
msgid "Empty name for extra data uri %s"
msgstr "Празно име за адреса за допълнителни данни %s"

#: common/flatpak-dir.c:6432
#, c-format
msgid "Unsupported extra data uri %s"
msgstr "Неподдържан адрес за допълнителни данни %s"

#: common/flatpak-dir.c:6461
#, c-format
msgid "Failed to load local extra-data %s: %s"
msgstr "Локалните допълнителни данни %s не може да се заредят: %s"

#: common/flatpak-dir.c:6469
#, c-format
msgid "Wrong size for extra-data %s"
msgstr "Неправилен размер на допълнителните данни %s"

#: common/flatpak-dir.c:6488
#, c-format
msgid "While downloading %s: "
msgstr "По време на изтеглянето на %s: "

#: common/flatpak-dir.c:6498
#, c-format
msgid "Wrong size for extra data %s"
msgstr "Неправилен размер на допълнителните данни %s"

#: common/flatpak-dir.c:6507
#, c-format
msgid "Invalid checksum for extra data %s"
msgstr "Неправилна контролна сума за допълнителните данни %s"

#: common/flatpak-dir.c:7096 common/flatpak-dir.c:7349
#, c-format
msgid "While pulling %s from remote %s: "
msgstr "По време на издърпването на %s от отдалеченото хранилище %s: "

#: common/flatpak-dir.c:7290 common/flatpak-repo-utils.c:3886
msgid "GPG signatures found, but none are in trusted keyring"
msgstr ""
"Намерени са подписи на GPG, но нито един от тях не е в надежден ключодържател"

#: common/flatpak-dir.c:7307
#, c-format
msgid "Commit for ‘%s’ has no ref binding"
msgstr "Подаването за „%s“ не е свързано с указател"

#: common/flatpak-dir.c:7312
#, c-format
msgid "Commit for ‘%s’ is not in expected bound refs: %s"
msgstr "Подаването за „%s“ не е в очакваните свързани указатели: %s"

#: common/flatpak-dir.c:7488
msgid "Only applications can be made current"
msgstr "Само програми може да се направят текущи"

#: common/flatpak-dir.c:8192
msgid "Not enough memory"
msgstr "Няма достатъчно памет"

#: common/flatpak-dir.c:8211
msgid "Failed to read from exported file"
msgstr "Изнесеният файл не може да се прочете"

#: common/flatpak-dir.c:8401
msgid "Error reading mimetype xml file"
msgstr "Грешка при четенето на файл mimetype xml"

#: common/flatpak-dir.c:8406
msgid "Invalid mimetype xml file"
msgstr "Неправилен файл mimetype xml"

#: common/flatpak-dir.c:8492
#, c-format
msgid "D-Bus service file '%s' has wrong name"
msgstr "Файлът на услугата D-Bus „%s“ е с грешно име"

#: common/flatpak-dir.c:8647
#, c-format
msgid "Invalid Exec argument %s"
msgstr "Неправилен аргумент за exec %s"

#: common/flatpak-dir.c:9115
msgid "While getting detached metadata: "
msgstr "По време на получаването на несвързаните метаданни: "

#: common/flatpak-dir.c:9120 common/flatpak-dir.c:9125
#: common/flatpak-dir.c:9129
msgid "Extra data missing in detached metadata"
msgstr "Липсват допълнителни данни в несвързаните метаданни"

#: common/flatpak-dir.c:9133
msgid "While creating extradir: "
msgstr "По време на създаването на extradir: "

#: common/flatpak-dir.c:9154 common/flatpak-dir.c:9187
msgid "Invalid checksum for extra data"
msgstr "Неправилна контролна сума за допълнителните данни"

#: common/flatpak-dir.c:9183
msgid "Wrong size for extra data"
msgstr "Неправилен размер на допълнителните данни"

#: common/flatpak-dir.c:9196
#, c-format
msgid "While writing extra data file '%s': "
msgstr "По време на записването на допълнителния файл с данни „%s“: "

#: common/flatpak-dir.c:9204
#, c-format
msgid "Extra data %s missing in detached metadata"
msgstr "Липсват %s допълнителни данни в несвързаните метаданни"

#: common/flatpak-dir.c:9278
#, fuzzy, c-format
msgid "Unable to get runtime key from metadata"
msgstr "Използване на друг файл за метаданните"

#: common/flatpak-dir.c:9402
#, c-format
msgid "apply_extra script failed, exit status %d"
msgstr "неуспешно изпълнение на скрипта apply_extra, изходен код: %d"

#. Translators: The placeholder is for an app ref.
#: common/flatpak-dir.c:9591
#, c-format
msgid "Installing %s is not allowed by the policy set by your administrator"
msgstr ""
"Инсталирането на %s не е позволено от политиката, зададена от вашия "
"администратор"

#: common/flatpak-dir.c:9690
#, c-format
msgid "While trying to resolve ref %s: "
msgstr "По време на определянето на указателя %s: "

#: common/flatpak-dir.c:9702
#, c-format
msgid "%s is not available"
msgstr "%s не е достъпна"

#: common/flatpak-dir.c:9714 common/flatpak-dir.c:11495
#, c-format
msgid "%s commit %s already installed"
msgstr "Подаването %2$s на %1$s вече е инсталирано"

#: common/flatpak-dir.c:9721
msgid "Can't create deploy directory"
msgstr "Директорията за разгръщане не може да се създаде"

#: common/flatpak-dir.c:9729
#, c-format
msgid "Failed to read commit %s: "
msgstr "Подаването %s не може да се прочете: "

#: common/flatpak-dir.c:9750
#, c-format
msgid "While trying to checkout %s into %s: "
msgstr "По време на изтеглянето на %s в %s: "

#: common/flatpak-dir.c:9769
msgid "While trying to checkout metadata subpath: "
msgstr "По време на изтеглянето на подпътя с метаданни: "

#: common/flatpak-dir.c:9801
#, c-format
msgid "While trying to checkout subpath ‘%s’: "
msgstr "По време на изтеглянето на подпътя „%s“: "

#: common/flatpak-dir.c:9811
msgid "While trying to remove existing extra dir: "
msgstr "По време на премахването на съществуваща допълнителна директория: "

#: common/flatpak-dir.c:9822
msgid "While trying to apply extra data: "
msgstr "По време на прилагането на допълнителни данни: "

#: common/flatpak-dir.c:9849
#, c-format
msgid "Invalid commit ref %s: "
msgstr "Неправилен указател %s за подаването: "

#: common/flatpak-dir.c:9857 common/flatpak-dir.c:9869
#, c-format
msgid "Deployed ref %s does not match commit (%s)"
msgstr "Каченият указател %s не съответства на подаването (%s)"

#: common/flatpak-dir.c:9863
#, c-format
msgid "Deployed ref %s branch does not match commit (%s)"
msgstr "Каченият клон на указателя %s не съответства на подаването (%s)"

#: common/flatpak-dir.c:10125 common/flatpak-installation.c:1911
#, c-format
msgid "%s branch %s already installed"
msgstr "Клонът %2$s на %1$s вече е инсталиран"

#: common/flatpak-dir.c:10985
#, c-format
msgid "Could not unmount revokefs-fuse filesystem at %s: "
msgstr "Файловата система revokefs-fuse на %s не може да се демонтира: "

#: common/flatpak-dir.c:11289
#, c-format
msgid "This version of %s is already installed"
msgstr "Тази версия на %s вече е инсталирана"

#: common/flatpak-dir.c:11302
#, c-format
msgid "Can't change remote during bundle install"
msgstr ""
"Отдалеченото хранилище не може да се промени по време на инсталирането на "
"пакет"

#: common/flatpak-dir.c:11571
msgid "Can't update to a specific commit without root permissions"
msgstr ""
"Обновяването до конкретно подаване не е позволено без администраторски права"

#: common/flatpak-dir.c:11852
#, c-format
msgid "Can't remove %s, it is needed for: %s"
msgstr "%s не може да се премахне, то е необходимо за: %s"

#: common/flatpak-dir.c:11912 common/flatpak-installation.c:2067
#, c-format
msgid "%s branch %s is not installed"
msgstr "Клонът %2$s на %1$s не е инсталиран"

#: common/flatpak-dir.c:12165
#, c-format
msgid "%s commit %s not installed"
msgstr "Подаването %2$s на %1$s не е инсталирано"

#: common/flatpak-dir.c:12501
#, c-format
msgid "Pruning repo failed: %s"
msgstr "Хранилището не може да се окастри: %s"

#: common/flatpak-dir.c:12669 common/flatpak-dir.c:12675
#, c-format
msgid "Failed to load filter '%s'"
msgstr "Филтърът „%s“ не може да се зареди"

#: common/flatpak-dir.c:12681
#, c-format
msgid "Failed to parse filter '%s'"
msgstr "Филтърът „%s“ не може да се разчете"

#: common/flatpak-dir.c:12963
msgid "Failed to write summary cache: "
msgstr "Кешът за обобщението не може да се запише: "

#: common/flatpak-dir.c:12982
#, c-format
msgid "No oci summary cached for remote '%s'"
msgstr "Няма кеширано обобщение по OCI за отдалеченото хранилище „%s“"

#: common/flatpak-dir.c:13207
#, c-format
msgid "No cached summary for remote '%s'"
msgstr "Няма кеширано обобщение за отдалеченото хранилище „%s“"

#: common/flatpak-dir.c:13248
#, c-format
msgid "Invalid checksum for indexed summary %s read from %s"
msgstr "Неправилна контролна сума за индексирано обобщение %s, четено от %s"

#: common/flatpak-dir.c:13321
#, c-format
msgid ""
"Remote listing for %s not available; server has no summary file. Check the "
"URL passed to remote-add was valid."
msgstr ""
"Изброяването на отдалечените сървъри за %s липсва, сървърът не разполага с "
"файл за обобщение. Проверете дали адресът, подаден на remote-add, е правилен."

#: common/flatpak-dir.c:13698
#, c-format
msgid "Invalid checksum for indexed summary %s for remote '%s'"
msgstr ""
"Неправилна контролна сума за индексирано обобщение %s за отдалеченото "
"хранилище „%s“"

#: common/flatpak-dir.c:14388
#, c-format
msgid "Multiple branches available for %s, you must specify one of: "
msgstr "За %s са налични няколко клона, трябва да посочите един от тях: "

#: common/flatpak-dir.c:14454
#, c-format
msgid "Nothing matches %s"
msgstr "Нищо не съвпада с %s"

#: common/flatpak-dir.c:14562
#, c-format
msgid "Can't find ref %s%s%s%s%s"
msgstr "Указателят %s%s%s%s%s липсва"

#: common/flatpak-dir.c:14605
#, c-format
msgid "Error searching remote %s: %s"
msgstr "Грешка при търсенето на отдалеченото хранилище %s: %s"

#: common/flatpak-dir.c:14702
#, c-format
msgid "Error searching local repository: %s"
msgstr "Грешка при търсенето на локалното хранилище: %s"

#: common/flatpak-dir.c:14839
#, c-format
msgid "%s/%s/%s not installed"
msgstr "%s/%s/%s не е инсталирано"

#: common/flatpak-dir.c:15042
#, c-format
msgid "Could not find installation %s"
msgstr "Инсталацията %s липсва"

#: common/flatpak-dir.c:15612
#, c-format
msgid "Invalid file format, no %s group"
msgstr "Неправилен вид файл, няма група %s"

#: common/flatpak-dir.c:15617 common/flatpak-repo-utils.c:2836
#, c-format
msgid "Invalid version %s, only 1 supported"
msgstr "Неправилна версия %s, поддържа се само 1"

#: common/flatpak-dir.c:15622 common/flatpak-dir.c:15627
#, c-format
msgid "Invalid file format, no %s specified"
msgstr "Неправилен вид файл, няма посочен %s"

#. Check some minimal size so we don't get crap
#: common/flatpak-dir.c:15647
msgid "Invalid file format, gpg key invalid"
msgstr "Неправилен вид файл, ключът за GPG е неправилен"

#: common/flatpak-dir.c:15675 common/flatpak-repo-utils.c:2917
msgid "Collection ID requires GPG key to be provided"
msgstr "Идентификаторът на колекцията изисква да се предостави ключ за GPG"

#: common/flatpak-dir.c:15718
#, c-format
msgid "Runtime %s, branch %s is already installed"
msgstr "Средата за изпълнение %s, с клон %s вече е инсталирана"

#: common/flatpak-dir.c:15719
#, c-format
msgid "App %s, branch %s is already installed"
msgstr "Програмата %s, с клон %s вече е инсталирана"

#: common/flatpak-dir.c:15953
#, c-format
msgid "Can't remove remote '%s' with installed ref %s (at least)"
msgstr ""
"Отдалеченото хранилище „%s“ с инсталиран указател %s (поне) не може да се "
"премахне"

#: common/flatpak-dir.c:16058
#, c-format
msgid "Invalid character '/' in remote name: %s"
msgstr "Неправилен знак „/“ в името на отдалеченото хранилище: %s"

#: common/flatpak-dir.c:16064
#, c-format
msgid "No configuration for remote %s specified"
msgstr "Няма посочени настройки за отдалеченото хранилище %s"

#: common/flatpak-dir.c:17597
#, c-format
msgid "Skipping deletion of mirror ref (%s, %s)…\n"
msgstr "Прескачане на изтриването на еднакъв указател (%s, %s)…\n"

#: common/flatpak-exports.c:931
#, c-format
msgid "An absolute path is required"
msgstr "Необходим е абсолютен път"

#: common/flatpak-exports.c:948
#, c-format
msgid "Unable to open path \"%s\": %s"
msgstr "Пътят не може да се отвори „%s“: %s"

#: common/flatpak-exports.c:955
#, c-format
msgid "Unable to get file type of \"%s\": %s"
msgstr "Видът на файла „%s“ не може да се получи: %s"

#: common/flatpak-exports.c:964
#, c-format
msgid "File \"%s\" has unsupported type 0o%o"
msgstr "Файлът „%s“ е неподдържан вид 0o%o"

#: common/flatpak-exports.c:970
#, c-format
msgid "Unable to get filesystem information for \"%s\": %s"
msgstr "Информацията за файловата система за „%s“ не може да се получи: %s"

#: common/flatpak-exports.c:980
#, c-format
msgid "Ignoring blocking autofs path \"%s\""
msgstr "Игнориране на блокиращия път за autofs „%s“"

#: common/flatpak-exports.c:996 common/flatpak-exports.c:1009
#: common/flatpak-exports.c:1022
#, c-format
msgid "Path \"%s\" is reserved by Flatpak"
msgstr "Пътят „%s“ е само за Flatpak"

#: common/flatpak-exports.c:1076
#, c-format
msgid "Unable to resolve symbolic link \"%s\": %s"
msgstr "Символната връзка „%s“ не може да се определи: %s"

#: common/flatpak-glib-backports.c:69
msgid "Empty string is not a number"
msgstr "Празният низ не е число"

#: common/flatpak-glib-backports.c:95
#, c-format
msgid "“%s” is not an unsigned number"
msgstr "„%s“ не е число без знак"

#: common/flatpak-glib-backports.c:105
#, c-format
msgid "Number “%s” is out of bounds [%s, %s]"
msgstr "Числото „%s“ е извън диапазона на допустимите стойности [%s, %s]"

#: common/flatpak-image-source.c:83
msgid "Only sha256 image checksums are supported"
msgstr ""

#: common/flatpak-image-source.c:100 common/flatpak-image-source.c:108
msgid "Image is not a manifest"
msgstr "Изображението не е манифест"

#: common/flatpak-image-source.c:123
msgid "No org.flatpak.ref found in image"
msgstr ""

#: common/flatpak-image-source.c:148
#, c-format
msgid "Ref '%s' not found in registry"
msgstr "Указателят „%s“ не е намерен в регистъра"

#: common/flatpak-image-source.c:157
msgid "Multiple images in registry, specify a ref with --ref"
msgstr "Множество изображения в регистъра, посочете указател с „--ref“"

#: common/flatpak-installation.c:834
#, c-format
msgid "Ref %s not installed"
msgstr "Указателят %s не е инсталиран"

#: common/flatpak-installation.c:875
#, c-format
msgid "App %s not installed"
msgstr "Програмата %s не е инсталирана"

#: common/flatpak-installation.c:1395
#, c-format
msgid "Remote '%s' already exists"
msgstr "Отдалеченото хранилище „%s“ вече съществува"

#: common/flatpak-installation.c:1946
#, c-format
msgid "As requested, %s was only pulled, but not installed"
msgstr "Както е заявено: %s само е издърпано, но не е инсталирано"

#: common/flatpak-instance.c:533 common/flatpak-instance.c:687
#: common/flatpak-instance.c:728
#, c-format
msgid "Unable to create directory %s"
msgstr "Директорията %s не може да се създаде"

#: common/flatpak-instance.c:554
#, c-format
msgid "Unable to lock %s"
msgstr "%s не може да се заключи"

#: common/flatpak-instance.c:627
#, c-format
msgid "Unable to create temporary directory in %s"
msgstr "Временна директория в %s не може да се създаде"

#: common/flatpak-instance.c:639
#, c-format
msgid "Unable to create file %s"
msgstr "Файлът %s не може да се създаде"

#: common/flatpak-instance.c:646
#, c-format
msgid "Unable to update symbolic link %s/%s"
msgstr "Символната връзка %s/%s не може да се обнови"

#: common/flatpak-oci-registry.c:1197
msgid "Only Bearer authentication supported"
msgstr "Поддържа се само удостоверяване на носителя"

#: common/flatpak-oci-registry.c:1206
msgid "Only realm in authentication request"
msgstr "Само област за удостоверяване в заявката за удостоверяване"

#: common/flatpak-oci-registry.c:1213
msgid "Invalid realm in authentication request"
msgstr "Неправилна област за удостоверяване в заявката за удостоверяване"

#: common/flatpak-oci-registry.c:1283
#, c-format
msgid "Authorization failed: %s"
msgstr "Упълномощаването е неуспешно: %s"

#: common/flatpak-oci-registry.c:1285
msgid "Authorization failed"
msgstr "Упълномощаването е неуспешно"

#: common/flatpak-oci-registry.c:1289
#, c-format
msgid "Unexpected response status %d when requesting token: %s"
msgstr "Неочаквано състояние %d на отговор при заявка на токен: %s"

#: common/flatpak-oci-registry.c:1300
msgid "Invalid authentication request response"
msgstr "Неправилен отговор на заявката за удостоверяване"

#: common/flatpak-oci-registry.c:1731
#, c-format
msgid "Flatpak was compiled without zstd support"
msgstr ""

#: common/flatpak-oci-registry.c:1923 common/flatpak-oci-registry.c:1975
#: common/flatpak-oci-registry.c:2004 common/flatpak-oci-registry.c:2059
#: common/flatpak-oci-registry.c:2115 common/flatpak-oci-registry.c:2193
msgid "Invalid delta file format"
msgstr "Неправилен формат на файла за разлики"

#: common/flatpak-oci-registry.c:3198 common/flatpak-oci-registry.c:3382
msgid "Invalid OCI image config"
msgstr "Неправилни настройки на образа във формат OCI"

#: common/flatpak-oci-registry.c:3260 common/flatpak-oci-registry.c:3531
#, c-format
msgid "Wrong layer checksum, expected %s, was %s"
msgstr "Грешна контролна сума на слоя, очакваше се %s, беше %s"

#: common/flatpak-oci-registry.c:3359
#, c-format
msgid "No ref specified for OCI image %s"
msgstr "Няма посочен указател за образа във формат OCI %s"

#: common/flatpak-oci-registry.c:3369
#, c-format
msgid "Wrong ref (%s) specified for OCI image %s, expected %s"
msgstr ""
"Неправилно посочен указател (%s) за образа във формат OCI %s, очакваше се %s"

#: common/flatpak-progress.c:236
#, c-format
msgid "Downloading metadata: %u/(estimating) %s"
msgstr "Изтегляне на метаданните: %u/(приблизително) %s"

#: common/flatpak-progress.c:260
#, c-format
msgid "Downloading: %s/%s"
msgstr "Изтегляне: %s/%s"

#: common/flatpak-progress.c:280
#, c-format
msgid "Downloading extra data: %s/%s"
msgstr "Изтегляне на допълнителни данни: %s/%s"

#: common/flatpak-progress.c:285
#, c-format
msgid "Downloading files: %d/%d %s"
msgstr "Изтегляне на файлове: %d/%d %s"

#: common/flatpak-ref-utils.c:122
msgid "Name can't be empty"
msgstr "Името е задължително"

#: common/flatpak-ref-utils.c:129
msgid "Name can't be longer than 255 characters"
msgstr "Името не може да е по-дълго от 255 знака"

#: common/flatpak-ref-utils.c:142
msgid "Name can't start with a period"
msgstr "Името не може да започва с „.“"

#: common/flatpak-ref-utils.c:148
#, c-format
msgid "Name can't start with %c"
msgstr "Името не може да започва с „%c“"

#: common/flatpak-ref-utils.c:164
msgid "Name can't end with a period"
msgstr "Името не може да завършва с „.“"

#: common/flatpak-ref-utils.c:171 common/flatpak-ref-utils.c:183
msgid "Only last name segment can contain -"
msgstr "Само последната част на името може да съдържа „-“"

#: common/flatpak-ref-utils.c:174
#, c-format
msgid "Name segment can't start with %c"
msgstr "Част в името не може да започва с „%c“"

#: common/flatpak-ref-utils.c:186
#, c-format
msgid "Name can't contain %c"
msgstr "Името не може да съдържа „%c“"

#: common/flatpak-ref-utils.c:195
msgid "Names must contain at least 2 periods"
msgstr "Имената трябва да съдържат поне 2 „.“"

#: common/flatpak-ref-utils.c:312
msgid "Arch can't be empty"
msgstr "Архитектурата е задължителна"

#: common/flatpak-ref-utils.c:323
#, c-format
msgid "Arch can't contain %c"
msgstr "Архитектурата не може да съдържа „%c“"

#: common/flatpak-ref-utils.c:385
msgid "Branch can't be empty"
msgstr "Клонът е задължителен"

#: common/flatpak-ref-utils.c:395
#, c-format
msgid "Branch can't start with %c"
msgstr "Клонът не може да започва с „%c“"

#: common/flatpak-ref-utils.c:405
#, c-format
msgid "Branch can't contain %c"
msgstr "Клонът не може да съдържа „%c“"

#: common/flatpak-ref-utils.c:615 common/flatpak-ref-utils.c:865
msgid "Ref too long"
msgstr "Указателят е прекалено дълго"

#: common/flatpak-ref-utils.c:627
msgid "Invalid remote name"
msgstr "Неправилно име на отдалечено хранилище"

#: common/flatpak-ref-utils.c:641
#, c-format
msgid "%s is not application or runtime"
msgstr "„%s“ не е програма или среда за изпълнение"

#: common/flatpak-ref-utils.c:650 common/flatpak-ref-utils.c:667
#: common/flatpak-ref-utils.c:683
#, c-format
msgid "Wrong number of components in %s"
msgstr "Грешен брой компоненти в %s"

#: common/flatpak-ref-utils.c:656
#, c-format
msgid "Invalid name %.*s: %s"
msgstr "Неправилно име %.*s: %s"

#: common/flatpak-ref-utils.c:673
#, c-format
msgid "Invalid arch: %.*s: %s"
msgstr "Неправилна архитектура: %.*s: %s"

#: common/flatpak-ref-utils.c:816
#, c-format
msgid "Invalid name %s: %s"
msgstr "Неправилно име %s: %s"

#: common/flatpak-ref-utils.c:834
#, c-format
msgid "Invalid arch: %s: %s"
msgstr "Неправилна архитектура: %s: %s"

#: common/flatpak-ref-utils.c:853
#, c-format
msgid "Invalid branch: %s: %s"
msgstr "Неправилен клон: %s: %s"

#: common/flatpak-ref-utils.c:962 common/flatpak-ref-utils.c:970
#: common/flatpak-ref-utils.c:978
#, c-format
msgid "Wrong number of components in partial ref %s"
msgstr "Грешен брой на компонентите в частичния указател %s"

#: common/flatpak-ref-utils.c:1298
msgid " development platform"
msgstr " среда за разработка"

#: common/flatpak-ref-utils.c:1300
msgid " platform"
msgstr " платформа"

#: common/flatpak-ref-utils.c:1302
msgid " application base"
msgstr " база на програмата"

#: common/flatpak-ref-utils.c:1305
msgid " debug symbols"
msgstr " символи за изчистване на грешки"

#: common/flatpak-ref-utils.c:1307
msgid " sourcecode"
msgstr " изходен код"

#: common/flatpak-ref-utils.c:1309
msgid " translations"
msgstr " преводи"

#: common/flatpak-ref-utils.c:1311
msgid " docs"
msgstr " документация"

#: common/flatpak-ref-utils.c:1578
#, c-format
msgid "Invalid id %s: %s"
msgstr "Неправилен идентификатор %s: %s"

#: common/flatpak-remote.c:1216
#, c-format
msgid "Bad remote name: %s"
msgstr "Лошо име на отдалечено хранилище: %s"

#: common/flatpak-remote.c:1220
#, fuzzy
msgid "No URL specified"
msgstr "Няма указан адрес"

#: common/flatpak-remote.c:1266
msgid "GPG verification must be enabled when a collection ID is set"
msgstr ""
"Потвърждаването по GPG трябва да е позволено, когато е зададен идентификатор "
"на колекция"

#: common/flatpak-repo-utils.c:344
#, c-format
msgid "No extra data sources"
msgstr "Няма допълнителни източници на данни"

#: common/flatpak-repo-utils.c:2817
#, c-format
msgid "Invalid %s: Missing group ‘%s’"
msgstr "Неправилен %s: Липсва група „%s“"

#: common/flatpak-repo-utils.c:2826
#, c-format
msgid "Invalid %s: Missing key ‘%s’"
msgstr "Неправилен %s: Липсва ключ „%s“"

#: common/flatpak-repo-utils.c:2876
msgid "Invalid gpg key"
msgstr "Неправилен ключ за GPG"

#: common/flatpak-repo-utils.c:3217
#, c-format
msgid "Error copying 64x64 icon for component %s: %s\n"
msgstr "Грешка при копирането на иконка с размер 64×64 за компонент %s: %s\n"

#: common/flatpak-repo-utils.c:3223
#, c-format
msgid "Error copying 128x128 icon for component %s: %s\n"
msgstr "Грешка при копирането на иконка с размер 128×128 за компонент %s: %s\n"

#: common/flatpak-repo-utils.c:3362
#, c-format
msgid "%s is end-of-life, ignoring for appstream"
msgstr "%s не получава обновления, игнориране за appstream"

#: common/flatpak-repo-utils.c:3397
#, c-format
msgid "No appstream data for %s: %s\n"
msgstr "Няма данни за appstream за %s: %s\n"

#: common/flatpak-repo-utils.c:3744
msgid "Invalid bundle, no ref in metadata"
msgstr "Неправилен пакет, няма указател в метаданните"

#: common/flatpak-repo-utils.c:3846
#, c-format
msgid "Collection ‘%s’ of bundle doesn’t match collection ‘%s’ of remote"
msgstr ""
"Колекция „%s“ на пакета не съвпада с колекция „%s“ на отдалеченото хранилище"

#: common/flatpak-repo-utils.c:3923
msgid "Metadata in header and app are inconsistent"
msgstr "Метаданните в заглавната част и програмата не си съответстват"

#: common/flatpak-run.c:951
msgid "No systemd user session available, cgroups not available"
msgstr "Няма налична потребителска сесия на systemd, cgroups липсва"

#: common/flatpak-run.c:1496
msgid "Unable to allocate instance id"
msgstr "Не може да се задели идентификатор на инстанцията"

#: common/flatpak-run.c:1632 common/flatpak-run.c:1641
#, c-format
msgid "Failed to open flatpak-info file: %s"
msgstr "Файлът flatpak-info не може да се отвори: %s"

#: common/flatpak-run.c:1668
#, c-format
msgid "Failed to open bwrapinfo.json file: %s"
msgstr "Файлът bwrapinfo.json не може да се отвори: %s"

#: common/flatpak-run.c:1689
#, c-format
msgid "Failed to write to instance id fd: %s"
msgstr ""
"Файловият дескриптор с идентификатора на инстанцията не може да се запише: %s"

#: common/flatpak-run.c:2096
msgid "Initialize seccomp failed"
msgstr "Неуспешно инициализиране на seccomp"

#: common/flatpak-run.c:2135
#, c-format
msgid "Failed to add architecture to seccomp filter: %s"
msgstr "Архитектурата не може да се добави във филтъра на seccomp: %s"

#: common/flatpak-run.c:2143
#, c-format
msgid "Failed to add multiarch architecture to seccomp filter: %s"
msgstr ""
"Множествената архитектура не може да се добави във филтъра на seccomp: %s"

#: common/flatpak-run.c:2175 common/flatpak-run.c:2192
#: common/flatpak-run.c:2214
#, c-format
msgid "Failed to block syscall %d: %s"
msgstr "Системното извикване %d не може да се блокира: %s"

#: common/flatpak-run.c:2247
#, c-format
msgid "Failed to export bpf: %s"
msgstr "bpf не може да се изнесе: %s"

#: common/flatpak-run.c:2587
#, c-format
msgid "Failed to open ‘%s’"
msgstr "„%s“ не може да се отвори"

#: common/flatpak-run.c:2597
#, c-format
msgid ""
"Directory forwarding needs version 4 of the document portal (have version %d)"
msgstr ""

#: common/flatpak-run.c:2915
#, c-format
msgid "ldconfig failed, exit status %d"
msgstr "Неуспешно изпълнение на „ldconfi“, изходен код %d"

#: common/flatpak-run.c:2922
msgid "Can't open generated ld.so.cache"
msgstr "Генерираният ld.so.cache не може да се отвори"

#. Translators: The placeholder is for an app ref.
#: common/flatpak-run.c:3045
#, c-format
msgid "Running %s is not allowed by the policy set by your administrator"
msgstr ""
"Изпълняването на %s не е позволено от политиката, зададена от вашия "
"администратор"

#: common/flatpak-run.c:3202
msgid ""
"\"flatpak run\" is not intended to be run as `sudo flatpak run`. Use `sudo "
"-i` or `su -l` instead and invoke \"flatpak run\" from inside the new shell."
msgstr ""
"„flatpak run“ не е предназначено да се изпълнява като „sudo flatpak run“. "
"Вместо това използвайте „sudo -i“ или „su -l“ и извикайте „flatpak run“ от "
"новата обвивка."

#: common/flatpak-run.c:3413
#, c-format
msgid "Failed to migrate from %s: %s"
msgstr "Мигрирането от %s е неуспешно: %s"

#: common/flatpak-run.c:3434
#, c-format
msgid "Failed to migrate old app data directory %s to new name %s: %s"
msgstr ""
"Мигрирането на старата директория за данни на програма %s към новото име %s "
"е неуспешно: %s"

#: common/flatpak-run.c:3443
#, c-format
msgid "Failed to create symlink while migrating %s: %s"
msgstr ""
"Създаването на символна връзка по време на мигрирането на %s е неуспешно: %s"

#: common/flatpak-run-dbus.c:46
msgid "Failed to open app info file"
msgstr "Информационният файл на програмата не може да се отвори"

#: common/flatpak-run-dbus.c:149
msgid "Unable to create sync pipe"
msgstr "Не може да се създаде канал за синхронизиране"

#: common/flatpak-run-dbus.c:185
msgid "Failed to sync with dbus proxy"
msgstr "Синхронизирането с dbus посредника е неуспешно"

#: common/flatpak-transaction.c:2275
#, c-format
msgid "Warning: Problem looking for related refs: %s"
msgstr "ВНИМАНИЕ: проблем с търсенето на свързани указатели: %s"

#: common/flatpak-transaction.c:2493
#, c-format
msgid "The application %s requires the runtime %s which was not found"
msgstr "Програмата %s изисква средата за изпълнение %s, която не е намерена"

#: common/flatpak-transaction.c:2509
#, c-format
msgid "The application %s requires the runtime %s which is not installed"
msgstr "Програмата %s изисква средата за изпълнение %s, която не е инсталирана"

#: common/flatpak-transaction.c:2641
#, c-format
msgid "Can't uninstall %s which is needed by %s"
msgstr "%s, което е необходимо на %s, не може да се деинсталира"

#: common/flatpak-transaction.c:2740
#, c-format
msgid "Remote %s disabled, ignoring %s update"
msgstr "Отдалеченото хранилище %s е изключено, игнориране на %s обновлението"

#: common/flatpak-transaction.c:2773
#, c-format
msgid "%s is already installed"
msgstr "%s вече е инсталирано"

#: common/flatpak-transaction.c:2776
#, c-format
msgid "%s is already installed from remote %s"
msgstr "%s вече е инсталирано от отдалеченото хранилище %s"

#: common/flatpak-transaction.c:3120
#, c-format
msgid "Invalid .flatpakref: %s"
msgstr "Неправилен указател .flatpakref: %s"

#: common/flatpak-transaction.c:3161
msgid "Warning: Could not mark already installed apps as preinstalled"
msgstr ""

#: common/flatpak-transaction.c:3382
#, c-format
msgid "Error updating remote metadata for '%s': %s"
msgstr "Отдалечените метаданни за „%s“ не може да се обновят: %s"

#: common/flatpak-transaction.c:3885
#, c-format
msgid ""
"Warning: Treating remote fetch error as non-fatal since %s is already "
"installed: %s"
msgstr ""
"ВНИМАНИЕ: третиране на грешка при извличането на отдалеченото хранилище като "
"нефатална, тъй като %s вече е инсталирано: %s"

#: common/flatpak-transaction.c:4209
#, c-format
msgid "No authenticator installed for remote '%s'"
msgstr "Няма инсталиран удостоверител за отдалеченото хранилище „%s“"

#: common/flatpak-transaction.c:4313 common/flatpak-transaction.c:4320
#, c-format
msgid "Failed to get tokens for ref: %s"
msgstr "Токените за указателя не може да се получат: %s"

#: common/flatpak-transaction.c:4315 common/flatpak-transaction.c:4322
msgid "Failed to get tokens for ref"
msgstr "Токените за указателя не може да се получат"

#: common/flatpak-transaction.c:4580
#, c-format
msgid "Ref %s from %s matches more than one transaction operation"
msgstr "Указателят %s от %s съответства на повече от една операция"

#: common/flatpak-transaction.c:4581 common/flatpak-transaction.c:4591
msgid "any remote"
msgstr "произволно отдалечено хранилище"

#: common/flatpak-transaction.c:4590
#, c-format
msgid "No transaction operation found for ref %s from %s"
msgstr "Липсва транзакция за операция с указателя %s от %s"

#: common/flatpak-transaction.c:4713
#, c-format
msgid "Flatpakrepo URL %s not file, HTTP or HTTPS"
msgstr "Адресът flatpakrepo „%s“ не е файл, HTTP или HTTPS"

#: common/flatpak-transaction.c:4719
#, c-format
msgid "Can't load dependent file %s: "
msgstr "Зависимият файл „%s“ не може да се зареди: "

#: common/flatpak-transaction.c:4727
#, c-format
msgid "Invalid .flatpakrepo: %s"
msgstr "Неправилно хранилище .flatpakrepo: %s"

#: common/flatpak-transaction.c:5454
msgid "Transaction already executed"
msgstr "Операцията вече е изпълнена"

#: common/flatpak-transaction.c:5469
msgid ""
"Refusing to operate on a user installation as root! This can lead to "
"incorrect file ownership and permission errors."
msgstr ""
"Не може да се работи с потребителска инсталация като администратор! Това "
"може да доведе до неправилна собственост и права̀ на файловете."

#: common/flatpak-transaction.c:5567 common/flatpak-transaction.c:5580
msgid "Aborted by user"
msgstr "Прекратено от потребителя"

#: common/flatpak-transaction.c:5605
#, c-format
msgid "Skipping %s due to previous error"
msgstr "Пропускане на %s поради предишната грешка"

#: common/flatpak-transaction.c:5659
#, c-format
msgid "Aborted due to failure (%s)"
msgstr "Прекратено поради неуспех (%s)"

#: common/flatpak-uri.c:118
#, no-c-format
msgid "Invalid %-encoding in URI"
msgstr "Непозволено кодиране „%-encoding“ в адреса"

#: common/flatpak-uri.c:135
msgid "Illegal character in URI"
msgstr "Непозволен знак в адреса"

#: common/flatpak-uri.c:169
msgid "Non-UTF-8 characters in URI"
msgstr "Знаци в адрес, които не са UTF-8"

#: common/flatpak-uri.c:275
#, c-format
msgid "Invalid IPv6 address ‘%.*s’ in URI"
msgstr "Неправилна част за IPv6 „%.*s“ в адреса"

#: common/flatpak-uri.c:330
#, c-format
msgid "Illegal encoded IP address ‘%.*s’ in URI"
msgstr "Непозволено кодиран IP адрес „%.*s“ в адреса"

#: common/flatpak-uri.c:342
#, c-format
msgid "Illegal internationalized hostname ‘%.*s’ in URI"
msgstr "Непозволено интернационализирано име на хост  „%.*s“ в адреса"

#: common/flatpak-uri.c:374 common/flatpak-uri.c:386
#, c-format
msgid "Could not parse port ‘%.*s’ in URI"
msgstr "Портът „%.*s“ не може да се разчете в адреса"

#: common/flatpak-uri.c:393
#, c-format
msgid "Port ‘%.*s’ in URI is out of range"
msgstr "Портът в адреса „%.*s“ е извън допустимия диапазон"

#: common/flatpak-uri.c:910
msgid "URI is not absolute, and no base URI was provided"
msgstr "Адресът не е абсолютен и не е предоставен базов адрес"

#: common/flatpak-usb.c:83
#, c-format
msgid "USB device query 'all' must not have data"
msgstr "Заявката „all“ за USB устройството не може да има данни"

#: common/flatpak-usb.c:102
#, c-format
msgid "USB query rule 'cls' must be in the form CLASS:SUBCLASS or CLASS:*"
msgstr ""
"Правилото „cls“ за заявката за USB трябва да се посочи като КЛАС:ПОДКЛАС или "
"КЛАС:*"

#: common/flatpak-usb.c:111
#, c-format
msgid "Invalid USB class"
msgstr "Неправилен клас на USB"

#: common/flatpak-usb.c:125
#, c-format
msgid "Invalid USB subclass"
msgstr "Неправилен подклас на USB"

#: common/flatpak-usb.c:141 common/flatpak-usb.c:148
#, c-format
msgid "USB query rule 'dev' must have a valid 4-digit hexadecimal product id"
msgstr ""
"Правилото „dev“ за заявката за USB трябва да има валиден 4-цифрен "
"шестнадесетичен идентификатор на продукта"

#: common/flatpak-usb.c:164 common/flatpak-usb.c:171
#, c-format
msgid "USB query rule 'vnd' must have a valid 4-digit hexadecimal vendor id"
msgstr ""
"Правилото „vnd“ за заявката за USB трябва да има валиден 4-цифрен "
"шестнадесетичен идентификатор на доставчика"

#: common/flatpak-usb.c:205
#, c-format
msgid "USB device queries must be in the form TYPE:DATA"
msgstr "Заявките за USB устройства трябва да се посочат като ТИП:ДАННИ"

#: common/flatpak-usb.c:225
#, c-format
msgid "Unknown USB query rule %s"
msgstr "Неизвестно правило за заявка за USB %s"

#: common/flatpak-usb.c:248
#, c-format
msgid "Empty USB query"
msgstr "Празна заявка за USB"

#: common/flatpak-usb.c:274
#, c-format
msgid "Multiple USB query rules of the same type is not supported"
msgstr "Няколко правила за заявки за USB от един и същи тип не се поддържат"

#: common/flatpak-usb.c:283
#, c-format
msgid "'all' must not contain extra query rules"
msgstr "„all“ не може да съдържа допълнителни правила за заявка"

#: common/flatpak-usb.c:291
#, c-format
msgid "USB queries with 'dev' must also specify vendors"
msgstr "Заявките за USB с „dev“ трябва да посочват и доставчиците"

#: common/flatpak-utils.c:712
msgid "Glob can't match apps"
msgstr "Шаблонът по Unix не съвпада с програми"

#: common/flatpak-utils.c:737
msgid "Empty glob"
msgstr "Празен шаблон по Unix"

#: common/flatpak-utils.c:756
msgid "Too many segments in glob"
msgstr "Твърде много части в шаблона по Unix"

#: common/flatpak-utils.c:777
#, c-format
msgid "Invalid glob character '%c'"
msgstr "Неправилен знак „%c“ в шаблона по Unix"

#: common/flatpak-utils.c:831
#, c-format
msgid "Missing glob on line %d"
msgstr "Липсва шаблон по Unix на ред %d"

#: common/flatpak-utils.c:835
#, c-format
msgid "Trailing text on line %d"
msgstr "Текст в края на ред %d"

#: common/flatpak-utils.c:839
#, c-format
msgid "on line %d"
msgstr "на ред %d"

#: common/flatpak-utils.c:861
#, c-format
msgid "Unexpected word '%s' on line %d"
msgstr "Неочаквана дума „%s“ на ред %d"

#: common/flatpak-utils.c:2118
#, c-format
msgid "Invalid require-flatpak argument %s"
msgstr "Неправилен аргумент за require-flatpak %s"

#: common/flatpak-utils.c:2128 common/flatpak-utils.c:2147
#, c-format
msgid "%s needs a later flatpak version (%s)"
msgstr "%s изисква по-нова версия на flatpak (%s)"

#: oci-authenticator/flatpak-oci-authenticator.c:291
msgid "Not a oci remote, missing summary.xa.oci-repository"
msgstr "Не е отдалечено хранилище по OCI, липсва summary.xa.oci-repository"

#: oci-authenticator/flatpak-oci-authenticator.c:477
msgid "Not a OCI remote"
msgstr "Не е отдалечено хранилище по OCI"

#: oci-authenticator/flatpak-oci-authenticator.c:488
msgid "Invalid token"
msgstr "Неправилен токен"

#: portal/flatpak-portal.c:2292
#, c-format
msgid "No portal support found"
msgstr "Не е намерена поддръжка за портал"

#: portal/flatpak-portal.c:2298
msgid "Deny"
msgstr "Забраняване"

#: portal/flatpak-portal.c:2300
msgid "Update"
msgstr "Обновяване"

#: portal/flatpak-portal.c:2305
#, c-format
msgid "Update %s?"
msgstr "Обновяване на %s?"

#: portal/flatpak-portal.c:2317
msgid "The application wants to update itself."
msgstr "Програмата иска да се обнови."

#: portal/flatpak-portal.c:2318
msgid "Update access can be changed any time from the privacy settings."
msgstr ""
"Достъпът до обновленията може да си промени по всяко време от настройките за "
"поверителност."

#: portal/flatpak-portal.c:2343
#, c-format
msgid "Application update not allowed"
msgstr "Обновяването на програмата не е позволено"

#: portal/flatpak-portal.c:2501
#, c-format
msgid "Self update not supported, new version requires new permissions"
msgstr ""
"Самостоятелното обновяване не се поддържа, новата версия изисква нови права̀"

#: portal/flatpak-portal.c:2684 portal/flatpak-portal.c:2702
#, c-format
msgid "Update ended unexpectedly"
msgstr "Обновлението завърши неочаквано"

#. SECURITY:
#. - Normal users need admin authentication to install software
#. system-wide.
#. - Note that we install polkit rules that allow local users
#. in the wheel group to install without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:23
msgid "Install signed application"
msgstr "Инсталиране на подписана програма"

#: system-helper/org.freedesktop.Flatpak.policy.in:24
#: system-helper/org.freedesktop.Flatpak.policy.in:42
msgid "Authentication is required to install software"
msgstr "За да инсталирате софтуер е необходима идентификация"

#. SECURITY:
#. - Normal users need admin authentication to install software
#. system-wide.
#. - Note that we install polkit rules that allow local users
#. in the wheel group to install without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:41
msgid "Install signed runtime"
msgstr "Инсталиране на подписана среда за изпълнение"

#. SECURITY:
#. - Normal users do not require admin authentication to update an
#. app as the commit will be signed, and the action is required
#. to update the system when unattended.
#. - Changing this to anything other than 'yes' will break unattended
#. updates.
#: system-helper/org.freedesktop.Flatpak.policy.in:60
msgid "Update signed application"
msgstr "Обновяване на подписана среда за изпълнение"

#: system-helper/org.freedesktop.Flatpak.policy.in:61
#: system-helper/org.freedesktop.Flatpak.policy.in:80
msgid "Authentication is required to update software"
msgstr "За да обновявате софтуер е необходима идентификация"

#. SECURITY:
#. - Normal users do not require admin authentication to update a
#. runtime as the commit will be signed, and the action is required
#. to update the system when unattended.
#. - Changing this to anything other than 'yes' will break unattended
#. updates.
#: system-helper/org.freedesktop.Flatpak.policy.in:79
msgid "Update signed runtime"
msgstr "Обновяване на подписана среда за изпълнение"

#. SECURITY:
#. - Normal users do not need authentication to update metadata
#. from signed repositories.
#: system-helper/org.freedesktop.Flatpak.policy.in:94
msgid "Update remote metadata"
msgstr "Обновяване на метаданните на отдалеченото хранилище"

#: system-helper/org.freedesktop.Flatpak.policy.in:95
msgid "Authentication is required to update remote info"
msgstr ""
"За обновяване на информацията за отдалеченото хранилище е необходима "
"идентификация"

#. SECURITY:
#. - Normal users do not need authentication to modify the
#. OSTree repository
#. - Note that we install polkit rules that allow local users
#. in the wheel group to modify repos without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:111
msgid "Update system repository"
msgstr "Обновяване на хранилището за софтуер"

#: system-helper/org.freedesktop.Flatpak.policy.in:112
msgid "Authentication is required to modify a system repository"
msgstr "За да промените системно хранилище е необходима идентификация"

#. SECURITY:
#. - Normal users need admin authentication to install software
#. system-wide.
#: system-helper/org.freedesktop.Flatpak.policy.in:126
msgid "Install bundle"
msgstr "Инсталиране на пакета"

#: system-helper/org.freedesktop.Flatpak.policy.in:127
msgid "Authentication is required to install software from $(path)"
msgstr "За да инсталирате софтуер от $(path) е необходима идентификация"

#. SECURITY:
#. - Normal users need admin authentication to uninstall software
#. system-wide.
#. - Note that we install polkit rules that allow local users
#. in the wheel group to uninstall without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:144
msgid "Uninstall runtime"
msgstr "Деинсталиране на средата за изпълнение"

#: system-helper/org.freedesktop.Flatpak.policy.in:145
msgid "Authentication is required to uninstall software"
msgstr "За да деинсталирате софтуер е необходима идентификация"

#. SECURITY:
#. - Normal users need admin authentication to uninstall software
#. system-wide.
#. - Note that we install polkit rules that allow local users
#. in the wheel group to uninstall without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:161
msgid "Uninstall app"
msgstr "Деинсталиране на програмата"

#: system-helper/org.freedesktop.Flatpak.policy.in:162
msgid "Authentication is required to uninstall $(ref)"
msgstr "За да деинсталирате $(ref) е необходима идентификация"

#. SECURITY:
#. - Normal users need admin authentication to configure system-wide
#. software repositories.
#: system-helper/org.freedesktop.Flatpak.policy.in:177
msgid "Configure Remote"
msgstr "Настройване на отдалеченото хранилище"

#: system-helper/org.freedesktop.Flatpak.policy.in:178
msgid "Authentication is required to configure software repositories"
msgstr "За да настроите хранилищата за софтуер е необходима идентификация"

#. SECURITY:
#. - Normal users need admin authentication to configure the system-wide
#. Flatpak installation.
#: system-helper/org.freedesktop.Flatpak.policy.in:192
msgid "Configure"
msgstr "Настройване"

#: system-helper/org.freedesktop.Flatpak.policy.in:193
msgid "Authentication is required to configure software installation"
msgstr "За да настроите инсталацията на софтуера е необходима идентификация"

#. SECURITY:
#. - Normal users do not require admin authentication to update
#. appstream data as it will be signed, and the action is required
#. to update the system when unattended.
#. - Changing this to anything other than 'yes' will break unattended
#. updates.
#: system-helper/org.freedesktop.Flatpak.policy.in:210
msgid "Update appstream"
msgstr "Обновяване на appstream"

#: system-helper/org.freedesktop.Flatpak.policy.in:211
msgid "Authentication is required to update information about software"
msgstr "За да обновите информацията на софтуера е необходима идентификация"

#. SECURITY:
#. - Normal users do not require admin authentication to update
#. metadata as it will be signed, and the action is required
#. to update the system when unattended.
#. - Changing this to anything other than 'yes' will break unattended
#. updates.
#: system-helper/org.freedesktop.Flatpak.policy.in:228
msgid "Update metadata"
msgstr "Обновяване на метаданните"

#: system-helper/org.freedesktop.Flatpak.policy.in:229
msgid "Authentication is required to update metadata"
msgstr "За да обновите метаданните е необходима идентификация"

#. SECURITY:
#. - Authorisation to actually install software is controlled by
#. org.freedesktop.Flatpak.app-install.
#. - This action is checked after app-install, as it can only be done
#. once the app’s data (including its content rating) has been
#. downloaded.
#. - This action is checked to see if the installation should be allowed
#. based on whether the app being installed has content which doesn’t
#. comply with the user’s parental controls policy (the content is
#. ‘too extreme’).
#. - It is checked only if an app has too extreme content for the user
#. who is trying to install it (in which case, the app is ‘unsafe’).
#. - Typically, normal users will need admin permission to install apps
#. with extreme content; admins will be able to install it without
#. additional checks.
#. - In order to configure the policy so that admins can install safe and
#. unsafe software anywhere without authorisation, and non-admins can
#. install safe software in their user or system dirs without
#. authorisation, but need authorisation to install unsafe software
#. anywhere:
#. * Unconditionally return `yes` from `app-install`.
#. * Return `auth_admin` from `override-parental-controls` for users
#. not in `@privileged_group@`, and `yes` for users in it.
#. * Set the malcontent `is-{user,system}-installation-allowed`
#. properties of all non-admins’ parental controls policies to true.
#. - In order to configure the policy so that admins can install safe and
#. unsafe software anywhere without authorisation, and non-admins can
#. install safe software in their user dir without authorisation, but
#. need authorisation to install safe software in the system dir or to
#. install unsafe software anywhere:
#. * Unconditionally return `yes` from `app-install`.
#. * Return `auth_admin` from `override-parental-controls` for users
#. not in `@privileged_group@`, and `yes` for users in it.
#. * Set the malcontent `is-user-installation-allowed` property of all
#. non-admins’ parental controls policies to true.
#. * Set the malcontent `is-system-installation-allowed` property of
#. all non-admins’ parental controls policies to false.
#. - In order to configure the policy so that all users (including
#. admins) can install safe software anywhere without authorisation,
#. but need authorisation to install unsafe software anywhere (i.e.
#. applying parental controls to admins too):
#. * Unconditionally return `yes` from `app-install`.
#. * Unconditionally return `auth_admin` from `override-parental-controls`.
#. * Set the malcontent `is-user-installation-allowed` property of all
#. users’ parental controls policies to true.
#. * Set the malcontent `is-system-installation-allowed` property of
#. all users’ parental controls policies to true.
#: system-helper/org.freedesktop.Flatpak.policy.in:287
#, fuzzy
msgid "Override parental controls for installs"
msgstr "Пренебрегване на родителския контрол"

#: system-helper/org.freedesktop.Flatpak.policy.in:288
msgid ""
"Authentication is required to install software which is restricted by your "
"parental controls policy"
msgstr ""
"За да инсталирате софтуер, който е ограничен от политиката за родителски "
"контрол, е необходима идентификация"

#. SECURITY:
#. - This is like org.freedesktop.Flatpak.override-parental-controls, but
#. it’s queried for app updates, whereas the former is queried for app
#. installs.
#. - As with the above action, this one is only queried if
#. org.freedesktop.Flatpak.app-update has allowed the app update, and
#. only if the app being updated has too extreme content for the user
#. who is trying to update it.
#. - The default policy for this is to *allow* updates to ‘too extreme’
#. apps by default, on the basis that having an out-of-date (i.e.
#. insecure or unsupported) app is a worse outcome than automatically
#. installing an update which has radically different content from the
#. version of the app which the parent originally vetted and installed.
#: system-helper/org.freedesktop.Flatpak.policy.in:313
#, fuzzy
msgid "Override parental controls for updates"
msgstr "Пренебрегване на родителския контрол"

#: system-helper/org.freedesktop.Flatpak.policy.in:314
#, fuzzy
msgid ""
"Authentication is required to update software which is restricted by your "
"parental controls policy"
msgstr ""
"За да инсталирате софтуер, който е ограничен от политиката за родителски "
"контрол, е необходима идентификация"

#~ msgid "Installed:"
#~ msgstr "Инсталирано:"

#~ msgid "Download:"
#~ msgstr "Изтегляне:"

#, c-format
#~ msgid "No gpg key found with ID %s (homedir: %s)"
#~ msgstr "Няма намерен ключ за GPG с идентификатор %s (homedir: %s)"

#, c-format
#~ msgid "Unable to lookup key ID %s: %d"
#~ msgstr "Идентификаторът на ключа %s не може да се потърси: %d"

#, c-format
#~ msgid "Error signing commit: %d"
#~ msgstr "Грешка при подписване на подаването: %d"

===== ./po/cs.po =====
# Czech translation for flatpak.
# Copyright (C) 2017 flatpak's COPYRIGHT HOLDER
# This file is distributed under the same license as the flatpak package.
# Daniel Rusek <mail@asciiwolf.com>, 2017.
#
msgid ""
msgstr ""
"Project-Id-Version: flatpak master\n"
"Report-Msgid-Bugs-To: https://github.com/flatpak/flatpak/issues\n"
"POT-Creation-Date: 2026-05-27 16:39+0200\n"
"PO-Revision-Date: 2025-09-02 15:46+0200\n"
"Last-Translator: Daniel Rusek <mail@asciiwolf.com>\n"
"Language-Team: Czech <gnome-cs-list@gnome.org>\n"
"Language: cs\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n"
"X-Generator: Poedit 3.7\n"

#: app/flatpak-builtins-build-bundle.c:59
msgid "Export runtime instead of app"
msgstr "Exportovat prostředí namísto aplikace"

#: app/flatpak-builtins-build-bundle.c:60
msgid "Arch to bundle for"
msgstr "Architektura, pro kterou se má vytvořit balík"

#: app/flatpak-builtins-build-bundle.c:60
#: app/flatpak-builtins-build-export.c:62 app/flatpak-builtins-build-init.c:53
#: app/flatpak-builtins-build-sign.c:42 app/flatpak-builtins-create-usb.c:46
#: app/flatpak-builtins-info.c:55 app/flatpak-builtins-install.c:67
#: app/flatpak-builtins-list.c:50 app/flatpak-builtins-make-current.c:38
#: app/flatpak-builtins-remote-info.c:54 app/flatpak-builtins-remote-ls.c:56
#: app/flatpak-builtins-run.c:158 app/flatpak-builtins-search.c:37
#: app/flatpak-builtins-uninstall.c:54 app/flatpak-builtins-update.c:56
msgid "ARCH"
msgstr "ARCHITEKTURA"

#: app/flatpak-builtins-build-bundle.c:61
#, fuzzy
msgid "URL for repo"
msgstr "Url pro repozitář"

#: app/flatpak-builtins-build-bundle.c:61
#: app/flatpak-builtins-build-bundle.c:62
#: app/flatpak-builtins-build-update-repo.c:68
#: app/flatpak-builtins-build-update-repo.c:72
#: app/flatpak-builtins-build-update-repo.c:73
#: app/flatpak-builtins-history.c:69 app/flatpak-builtins-remote-add.c:80
#: app/flatpak-builtins-remote-add.c:81 app/flatpak-builtins-remote-add.c:85
#: app/flatpak-builtins-remote-list.c:53
#: app/flatpak-builtins-remote-modify.c:70
#: app/flatpak-builtins-remote-modify.c:85
#: app/flatpak-builtins-remote-modify.c:86
#: app/flatpak-builtins-remote-modify.c:90
msgid "URL"
msgstr "URL"

#: app/flatpak-builtins-build-bundle.c:62
#, fuzzy
msgid "URL for runtime flatpakrepo file"
msgstr "Url pro flatpakrepo soubor prostředí"

#: app/flatpak-builtins-build-bundle.c:63
msgid "Add GPG key from FILE (- for stdin)"
msgstr "Přidat klíč GPG ze SOUBORU (- pro standardní vstup)"

#: app/flatpak-builtins-build-bundle.c:63 app/flatpak-builtins-build.c:54
#: app/flatpak-builtins-build-export.c:67
#: app/flatpak-builtins-build-update-repo.c:83
#: app/flatpak-builtins-install.c:81 app/flatpak-builtins-remote-add.c:84
#: app/flatpak-builtins-remote-add.c:86 app/flatpak-builtins-remote-modify.c:89
#: app/flatpak-builtins-remote-modify.c:92
msgid "FILE"
msgstr "SOUBOR"

#: app/flatpak-builtins-build-bundle.c:64
msgid "GPG Key ID to sign the OCI image with"
msgstr "ID klíče GPG pro podepsání OCI obrazu"

#: app/flatpak-builtins-build-bundle.c:64
#: app/flatpak-builtins-build-commit-from.c:68
#: app/flatpak-builtins-build-export.c:68
#: app/flatpak-builtins-build-import-bundle.c:49
#: app/flatpak-builtins-build-sign.c:44
#: app/flatpak-builtins-build-update-repo.c:84
msgid "KEY-ID"
msgstr "KLÍČ-ID"

#: app/flatpak-builtins-build-bundle.c:65
#: app/flatpak-builtins-build-commit-from.c:69
#: app/flatpak-builtins-build-export.c:71
#: app/flatpak-builtins-build-import-bundle.c:50
#: app/flatpak-builtins-build-sign.c:45
#: app/flatpak-builtins-build-update-repo.c:85
msgid "GPG Homedir to use when looking for keyrings"
msgstr "Domovský adresář pro použití při hledání klíčenek"

#: app/flatpak-builtins-build-bundle.c:65
#: app/flatpak-builtins-build-commit-from.c:69
#: app/flatpak-builtins-build-export.c:71
#: app/flatpak-builtins-build-import-bundle.c:50
#: app/flatpak-builtins-build-sign.c:45
#: app/flatpak-builtins-build-update-repo.c:85
msgid "HOMEDIR"
msgstr "DOMOVSKÝ_ADRESÁŘ"

#: app/flatpak-builtins-build-bundle.c:66
msgid "OSTree commit to create a delta bundle from"
msgstr "OSTree commit pro vytvoření delta bundle"

#: app/flatpak-builtins-build-bundle.c:66 app/flatpak-builtins-remote-info.c:55
#: app/flatpak-builtins-update.c:57
msgid "COMMIT"
msgstr "COMMIT"

#: app/flatpak-builtins-build-bundle.c:67
msgid "Export oci image instead of flatpak bundle"
msgstr "Exportovat oci obraz namísto flatpak balíku"

#: app/flatpak-builtins-build-bundle.c:70
msgid "How to compress OCI image layers (default: gzip)"
msgstr ""

#: app/flatpak-builtins-build-bundle.c:634
msgid ""
"LOCATION FILENAME NAME [BRANCH] - Create a single file bundle from a local "
"repository"
msgstr ""
"UMÍSTĚNÍ NÁZEV_SOUBORU NÁZEV [VĚTEV] - Vytvořit jeden soubor balíku z "
"místního repozitáře"

#: app/flatpak-builtins-build-bundle.c:641
msgid "LOCATION, FILENAME and NAME must be specified"
msgstr "UMÍSTĚNÍ, NÁZEV_SOUBORU A NÁZEV musí být určeny"

#: app/flatpak-builtins-build-bundle.c:644
#: app/flatpak-builtins-build-export.c:844
#: app/flatpak-builtins-build-import-bundle.c:136
#: app/flatpak-builtins-build-init.c:217 app/flatpak-builtins-build-sign.c:76
#: app/flatpak-builtins-document-export.c:112
#: app/flatpak-builtins-document-info.c:75
#: app/flatpak-builtins-document-list.c:191
#: app/flatpak-builtins-document-unexport.c:70
#: app/flatpak-builtins-history.c:482 app/flatpak-builtins-info.c:130
#: app/flatpak-builtins-install.c:181 app/flatpak-builtins-install.c:234
#: app/flatpak-builtins-install.c:298 app/flatpak-builtins-list.c:419
#: app/flatpak-builtins-make-current.c:72 app/flatpak-builtins-override.c:73
#: app/flatpak-builtins-permission-list.c:162
#: app/flatpak-builtins-permission-remove.c:132
#: app/flatpak-builtins-remote-add.c:323
#: app/flatpak-builtins-remote-delete.c:68
#: app/flatpak-builtins-remote-list.c:241 app/flatpak-builtins-remote-ls.c:407
msgid "Too many arguments"
msgstr "Příliš mnoho parametrů"

#: app/flatpak-builtins-build-bundle.c:659
#: app/flatpak-builtins-build-commit-from.c:338
#: app/flatpak-builtins-build-commit-from.c:351
#: app/flatpak-builtins-build-import-bundle.c:145
#, c-format
msgid "'%s' is not a valid repository"
msgstr "„%s“ není platným repozitářem"

#: app/flatpak-builtins-build-bundle.c:663
#, c-format
msgid "'%s' is not a valid repository: "
msgstr "„%s“ není platným repozitářem: "

#: app/flatpak-builtins-build-bundle.c:674 app/flatpak-builtins-build-sign.c:88
#: common/flatpak-dir.c:14293
#, c-format
msgid "'%s' is not a valid name: %s"
msgstr "„%s“ není platným názvem: %s"

#: app/flatpak-builtins-build-bundle.c:677
#: app/flatpak-builtins-build-export.c:865 app/flatpak-builtins-build-sign.c:91
#: common/flatpak-dir.c:14299
#, c-format
msgid "'%s' is not a valid branch name: %s"
msgstr "„%s“ není platným názvem větve: %s"

#: app/flatpak-builtins-build-bundle.c:691
#: app/flatpak-builtins-build-import-bundle.c:149
#: app/flatpak-builtins-build-init.c:281
#, c-format
msgid "'%s' is not a valid filename"
msgstr "„%s“ není platným názvem souboru"

#: app/flatpak-builtins-build-bundle.c:706
msgid "--oci-layer-compress value must be gzip or zstd"
msgstr ""

#: app/flatpak-builtins-build.c:49
msgid "Use Platform runtime rather than Sdk"
msgstr ""

#: app/flatpak-builtins-build.c:50
msgid "Make destination readonly"
msgstr "Udělat cíl pouze pro čtení"

#: app/flatpak-builtins-build.c:51
msgid "Add bind mount"
msgstr "Přidat vázané připojení"

#: app/flatpak-builtins-build.c:51
msgid "DEST=SRC"
msgstr "CÍL=ZDROJ"

#: app/flatpak-builtins-build.c:52
msgid "Start build in this directory"
msgstr "Spustit sestavení v tomto adresáři"

#: app/flatpak-builtins-build.c:52 app/flatpak-builtins-build.c:53
#: app/flatpak-builtins-build-init.c:64 app/flatpak-builtins-run.c:160
msgid "DIR"
msgstr "ADRESÁŘ"

#: app/flatpak-builtins-build.c:53
msgid "Where to look for custom sdk dir (defaults to 'usr')"
msgstr "Kde hledat adresář s upraveným sdk (výchozí je „usr“)"

#: app/flatpak-builtins-build.c:54 app/flatpak-builtins-build-export.c:67
msgid "Use alternative file for the metadata"
msgstr "Použít alternativní soubor pro metadata"

#: app/flatpak-builtins-build.c:55 app/flatpak-builtins-run.c:177
msgid "Kill processes when the parent process dies"
msgstr "Zabít procesy v případě, že rodičovský proces zemře"

#: app/flatpak-builtins-build.c:56
msgid "Export application homedir directory to build"
msgstr "Exportovat domovský adresář aplikace do sestavení"

#: app/flatpak-builtins-build.c:57 app/flatpak-builtins-run.c:165
msgid "Log session bus calls"
msgstr "Zaznamenávat volání sběrnice sezení"

#: app/flatpak-builtins-build.c:58 app/flatpak-builtins-run.c:166
msgid "Log system bus calls"
msgstr "Zaznamenávat volání systémové sběrnice"

#: app/flatpak-builtins-build.c:262
msgid "DIRECTORY [COMMAND [ARGUMENT…]] - Build in directory"
msgstr "ADRESÁŘ [PŘÍKAZ [ARGUMENT…]] - Sestavit v adresáři"

#: app/flatpak-builtins-build.c:285 app/flatpak-builtins-build-finish.c:656
msgid "DIRECTORY must be specified"
msgstr "ADRESÁŘ musí být určen"

#: app/flatpak-builtins-build.c:296 app/flatpak-builtins-build-export.c:887
#, c-format
msgid "Build directory %s not initialized, use flatpak build-init"
msgstr "Adresář sestavení %s neinicializován, použijte flatpak build-init"

#: app/flatpak-builtins-build.c:315
msgid "metadata invalid, not application or runtime"
msgstr "neplatná metadata, není aplikace nebo prostředí"

#: app/flatpak-builtins-build.c:446
#, c-format
msgid "No extension point matching %s in %s"
msgstr ""

#: app/flatpak-builtins-build.c:635
#, c-format
msgid "Missing '=' in bind mount option '%s'"
msgstr ""

#: app/flatpak-builtins-build.c:679 common/flatpak-run.c:3961
#, c-format
msgid "Unable to start app"
msgstr "Nelze spustit aplikaci"

#: app/flatpak-builtins-build-commit-from.c:58
msgid "Source repo dir"
msgstr "Adresář pro zdrojový repozitář"

#: app/flatpak-builtins-build-commit-from.c:58
msgid "SRC-REPO"
msgstr "ZDROJ-REPOZITÁŘ"

#: app/flatpak-builtins-build-commit-from.c:59
msgid "Source repo ref"
msgstr "Ref pro zdrojový repozitář"

#: app/flatpak-builtins-build-commit-from.c:59
msgid "SRC-REF"
msgstr "ZDROJ-REF"

#: app/flatpak-builtins-build-commit-from.c:64
#: app/flatpak-builtins-build-export.c:60
msgid "One line subject"
msgstr "Předmět na jeden řádek"

#: app/flatpak-builtins-build-commit-from.c:64
#: app/flatpak-builtins-build-export.c:60
msgid "SUBJECT"
msgstr "PŘEDMĚT"

#: app/flatpak-builtins-build-commit-from.c:65
#: app/flatpak-builtins-build-export.c:61
msgid "Full description"
msgstr "Úplný popis"

#: app/flatpak-builtins-build-commit-from.c:65
#: app/flatpak-builtins-build-export.c:61
msgid "BODY"
msgstr "TĚLO"

#: app/flatpak-builtins-build-commit-from.c:66
#: app/flatpak-builtins-build-export.c:64
#: app/flatpak-builtins-build-import-bundle.c:51
msgid "Update the appstream branch"
msgstr "Aktualizovat appstream větev"

#: app/flatpak-builtins-build-commit-from.c:67
#: app/flatpak-builtins-build-export.c:65
#: app/flatpak-builtins-build-import-bundle.c:52
#: app/flatpak-builtins-build-update-repo.c:87
msgid "Don't update the summary"
msgstr "Neaktualizovat shrnutí"

#: app/flatpak-builtins-build-commit-from.c:68
#: app/flatpak-builtins-build-export.c:68
#: app/flatpak-builtins-build-import-bundle.c:49
#: app/flatpak-builtins-build-sign.c:44
msgid "GPG Key ID to sign the commit with"
msgstr "ID klíče GPG pro podepsání commitu"

#: app/flatpak-builtins-build-commit-from.c:70
#: app/flatpak-builtins-build-export.c:73
msgid "Mark build as end-of-life"
msgstr "Označit sestavení jako end-of-life"

#: app/flatpak-builtins-build-commit-from.c:70
#: app/flatpak-builtins-build-export.c:73
msgid "REASON"
msgstr "DŮVOD"

#: app/flatpak-builtins-build-commit-from.c:71
msgid ""
"Mark refs matching the OLDID prefix as end-of-life, to be replaced with the "
"given NEWID"
msgstr ""
"Označit refy odpovídající předponě OLDID jako end-of-life, k nahrazení daným "
"NEWID"

#: app/flatpak-builtins-build-commit-from.c:71
msgid "OLDID=NEWID"
msgstr "OLDID=NEWID"

#: app/flatpak-builtins-build-commit-from.c:72
#: app/flatpak-builtins-build-export.c:75
msgid "Set type of token needed to install this commit"
msgstr "Nastavit typ tokenu požadovaného k instalaci tohoto commitu"

#: app/flatpak-builtins-build-commit-from.c:72
#: app/flatpak-builtins-build-export.c:75
msgid "VAL"
msgstr "HODNOTA"

#: app/flatpak-builtins-build-commit-from.c:73
msgid "Override the timestamp of the commit (NOW for current time)"
msgstr "Přepsat časovou značku commitu (NOW pro aktuální čas)"

#: app/flatpak-builtins-build-commit-from.c:73
#: app/flatpak-builtins-build-export.c:76
msgid "TIMESTAMP"
msgstr "TIMESTAMP"

#: app/flatpak-builtins-build-commit-from.c:75
#: app/flatpak-builtins-build-export.c:80
#: app/flatpak-builtins-build-import-bundle.c:53
#: app/flatpak-builtins-build-update-repo.c:97
msgid "Don't generate a summary index"
msgstr "Negenerovat index shrnutí"

#: app/flatpak-builtins-build-commit-from.c:278
msgid "DST-REPO [DST-REF…] - Make a new commit from existing commits"
msgstr "CÍL-REPO [CÍL-REF…] - Vytvořit nový commit z existujících commitů"

#: app/flatpak-builtins-build-commit-from.c:285
msgid "DST-REPO must be specified"
msgstr "CÍL-REPO musí být určeno"

#: app/flatpak-builtins-build-commit-from.c:293
msgid ""
"If --src-repo is not specified, exactly one destination ref must be specified"
msgstr "Pokud není --src-repo určeno, musí být určen přesně jeden cílový ref"

#: app/flatpak-builtins-build-commit-from.c:296
msgid ""
"If --src-ref is specified, exactly one destination ref must be specified"
msgstr "Pokud je --src-ref určeno, musí být určen přesně jeden cílový ref"

#: app/flatpak-builtins-build-commit-from.c:299
msgid "Either --src-repo or --src-ref must be specified"
msgstr "Buď --src-repo nebo --src-ref musí být určeno"

#: app/flatpak-builtins-build-commit-from.c:315
msgid "Invalid argument format of use  --end-of-life-rebase=OLDID=NEWID"
msgstr "Neplatný formát parametrů použití  --end-of-life-rebase=OLDID=NEWID"

#: app/flatpak-builtins-build-commit-from.c:321
#: app/flatpak-builtins-build-commit-from.c:324
#, c-format
msgid "Invalid name %s in --end-of-life-rebase"
msgstr "Neplatný název %s v --end-of-life-rebase"

#: app/flatpak-builtins-build-commit-from.c:333
#: app/flatpak-builtins-build-export.c:1092
#, c-format
msgid "Could not parse '%s'"
msgstr "Nelze zpracovat „%s“"

#: app/flatpak-builtins-build-commit-from.c:498
msgid "Can't commit from partial source commit"
msgstr ""

#: app/flatpak-builtins-build-commit-from.c:503
#, c-format
msgid "%s: no change\n"
msgstr "%s: žádná změna\n"

#: app/flatpak-builtins-build-export.c:62
msgid "Architecture to export for (must be host compatible)"
msgstr ""
"Architektura, pro kterou exportovat (musí být kompatibilní s hostitelem)"

#: app/flatpak-builtins-build-export.c:63
msgid "Commit runtime (/usr), not /app"
msgstr ""

#: app/flatpak-builtins-build-export.c:66
msgid "Use alternative directory for the files"
msgstr "Použít alternativní adresář pro soubory"

#: app/flatpak-builtins-build-export.c:66
msgid "SUBDIR"
msgstr "PODADRESÁŘ"

#: app/flatpak-builtins-build-export.c:69
msgid "Files to exclude"
msgstr "Soubory k vyloučení"

#: app/flatpak-builtins-build-export.c:69
#: app/flatpak-builtins-build-export.c:70
#: app/flatpak-builtins-build-update-repo.c:90
msgid "PATTERN"
msgstr "VZOR"

#: app/flatpak-builtins-build-export.c:70
msgid "Excluded files to include"
msgstr "Vyloučené soubory k zahrnutí"

#: app/flatpak-builtins-build-export.c:74
msgid "Mark build as end-of-life, to be replaced with the given ID"
msgstr "Označit sestavení jako end-of-life, k nahrazení daným ID"

#: app/flatpak-builtins-build-export.c:74
#: app/flatpak-builtins-document-list.c:49 app/flatpak-cli-transaction.c:1427
msgid "ID"
msgstr "ID"

#: app/flatpak-builtins-build-export.c:76
msgid "Override the timestamp of the commit"
msgstr "Přepsat časovou značku commitu"

#: app/flatpak-builtins-build-export.c:77
#: app/flatpak-builtins-build-update-repo.c:75
#: app/flatpak-builtins-remote-add.c:83 app/flatpak-builtins-remote-list.c:54
#: app/flatpak-builtins-remote-modify.c:88
msgid "Collection ID"
msgstr "ID kolekce"

#: app/flatpak-builtins-build-export.c:472
#, c-format
msgid "WARNING: Error running desktop-file-validate: %s\n"
msgstr ""

#: app/flatpak-builtins-build-export.c:480
#, c-format
msgid "WARNING: Error reading from desktop-file-validate: %s\n"
msgstr ""

#: app/flatpak-builtins-build-export.c:486
#, c-format
msgid "WARNING: Failed to validate desktop file %s: %s\n"
msgstr ""

#: app/flatpak-builtins-build-export.c:513
#, c-format
msgid "WARNING: Can't find Exec key in %s: %s\n"
msgstr ""

#: app/flatpak-builtins-build-export.c:521
#: app/flatpak-builtins-build-export.c:614
#, c-format
msgid "WARNING: Binary not found for Exec line in %s: %s\n"
msgstr ""

#: app/flatpak-builtins-build-export.c:529
#, c-format
msgid "WARNING: Icon not matching app id in %s: %s\n"
msgstr ""

#: app/flatpak-builtins-build-export.c:552
#, c-format
msgid "WARNING: Icon referenced in desktop file but not exported: %s\n"
msgstr ""

#: app/flatpak-builtins-build-export.c:719
#, c-format
msgid "Invalid uri type %s, only http/https supported"
msgstr "Neplatný typ uri %s, pouze http/https jsou podporovány"

#: app/flatpak-builtins-build-export.c:737
#, c-format
msgid "Unable to find basename in %s, specify a name explicitly"
msgstr ""

#: app/flatpak-builtins-build-export.c:746
#, c-format
msgid "No slashes allowed in extra data name"
msgstr "V názvu souboru dodatečných dat nejsou povolena lomítka"

#: app/flatpak-builtins-build-export.c:758
#, c-format
msgid "Invalid format for sha256 checksum: '%s'"
msgstr "Neplatný formát pro kontrolní součet sha256: „%s“"

#: app/flatpak-builtins-build-export.c:768
#, c-format
msgid "Extra data sizes of zero not supported"
msgstr "Dodatečná data s nulovou velikostí nejsou podporována"

#: app/flatpak-builtins-build-export.c:830
msgid ""
"LOCATION DIRECTORY [BRANCH] - Create a repository from a build directory"
msgstr "UMÍSTĚNÍ ADRESÁŘ [VĚTEV] - Vytvořit repozitář z adresáře sestavení"

#: app/flatpak-builtins-build-export.c:838
msgid "LOCATION and DIRECTORY must be specified"
msgstr "UMÍSTĚNÍ a ADRESÁŘ musí být určeny"

#: app/flatpak-builtins-build-export.c:859
#: app/flatpak-builtins-remote-add.c:327
#, c-format
msgid "‘%s’ is not a valid collection ID: %s"
msgstr "„%s“ není platným ID kolekce: %s"

#: app/flatpak-builtins-build-export.c:904
#: app/flatpak-builtins-build-finish.c:684
msgid "No name specified in the metadata"
msgstr "Není určen žádný název v metadatech"

#: app/flatpak-builtins-build-export.c:1166
#, c-format
msgid "Commit: %s\n"
msgstr "Commit: %s\n"

#: app/flatpak-builtins-build-export.c:1167
#, c-format
msgid "Metadata Total: %u\n"
msgstr "Celková metadata: %u\n"

#: app/flatpak-builtins-build-export.c:1168
#, c-format
msgid "Metadata Written: %u\n"
msgstr "Zapsaná metadata: %u\n"

#: app/flatpak-builtins-build-export.c:1169
#, c-format
msgid "Content Total: %u\n"
msgstr "Celkový obsah: %u\n"

#: app/flatpak-builtins-build-export.c:1170
#, c-format
msgid "Content Written: %u\n"
msgstr "Zapsaný obsah: %u\n"

#: app/flatpak-builtins-build-export.c:1171
#, c-format
msgid "Content Bytes Written:"
msgstr "Zapsáno bajtů obsahu:"

#: app/flatpak-builtins-build-finish.c:52
msgid "Command to set"
msgstr "Příkaz, který se má nastavit"

#: app/flatpak-builtins-build-finish.c:52 app/flatpak-builtins-run.c:159
#: app/flatpak-main.c:209
msgid "COMMAND"
msgstr "PŘÍKAZ"

#: app/flatpak-builtins-build-finish.c:53
msgid "Flatpak version to require"
msgstr "Požadovaná verze flatpaku"

#: app/flatpak-builtins-build-finish.c:53
msgid "MAJOR.MINOR.MICRO"
msgstr "MAJOR.MINOR.MICRO"

#: app/flatpak-builtins-build-finish.c:54
msgid "Don't process exports"
msgstr "Nezpracovat exporty"

#: app/flatpak-builtins-build-finish.c:55
msgid "Extra data info"
msgstr "Informace o dodatečných údajích"

#: app/flatpak-builtins-build-finish.c:56 app/flatpak-builtins-build-init.c:63
msgid "Add extension point info"
msgstr ""

#: app/flatpak-builtins-build-finish.c:56 app/flatpak-builtins-build-init.c:63
msgid "NAME=VARIABLE[=VALUE]"
msgstr "NÁZEV=PROMĚNNÁ[=HODNOTA]"

#: app/flatpak-builtins-build-finish.c:57
msgid "Remove extension point info"
msgstr ""

#: app/flatpak-builtins-build-finish.c:57
#: app/flatpak-builtins-build-update-repo.c:79 app/flatpak-builtins-info.c:58
#: app/flatpak-builtins-remote-add.c:88 app/flatpak-builtins-remote-modify.c:94
#: app/flatpak-main.c:182
msgid "NAME"
msgstr "NÁZEV"

#: app/flatpak-builtins-build-finish.c:58
msgid "Set extension priority (only for extensions)"
msgstr "Nastavit prioritu rozšíření (pouze pro rozšíření)"

#: app/flatpak-builtins-build-finish.c:58
msgid "VALUE"
msgstr "HODNOTA"

#: app/flatpak-builtins-build-finish.c:59
msgid "Change the sdk used for the app"
msgstr "Změnit sdk použité pro aplikaci"

#: app/flatpak-builtins-build-finish.c:59
msgid "SDK"
msgstr "SDK"

#: app/flatpak-builtins-build-finish.c:60
msgid "Change the runtime used for the app"
msgstr "Změnit prostředí použité pro aplikaci"

#: app/flatpak-builtins-build-finish.c:60 app/flatpak-builtins-build-init.c:54
#: app/flatpak-builtins-list.c:53 app/flatpak-builtins-remote-ls.c:58
#: app/flatpak-builtins-run.c:163
msgid "RUNTIME"
msgstr "PROSTŘEDÍ"

#: app/flatpak-builtins-build-finish.c:61
msgid "Set generic metadata option"
msgstr "Nastavit generickou volbu metadat"

#: app/flatpak-builtins-build-finish.c:61
msgid "GROUP=KEY[=VALUE]"
msgstr "SKUPINA=KLÍČ[=HODNOTA]"

#: app/flatpak-builtins-build-finish.c:62
msgid "Don't inherit permissions from runtime"
msgstr "Nedědit oprávnění z prostředí"

#: app/flatpak-builtins-build-finish.c:155
#, c-format
msgid "Not exporting %s, wrong extension\n"
msgstr "Neexportuje se %s, neplatné rozšíření\n"

#: app/flatpak-builtins-build-finish.c:163
#, c-format
msgid "Not exporting %s, non-allowed export filename\n"
msgstr "Neexportuje se %s, nepovolený název export souboru\n"

#: app/flatpak-builtins-build-finish.c:167
#, c-format
msgid "Exporting %s\n"
msgstr "Exportuje se %s\n"

#: app/flatpak-builtins-build-finish.c:440
#, c-format
msgid "More than one executable found\n"
msgstr "Nalezen více než jeden spustitelný soubor\n"

#: app/flatpak-builtins-build-finish.c:451
#, c-format
msgid "Using %s as command\n"
msgstr "Používá se %s jako příkaz\n"

#: app/flatpak-builtins-build-finish.c:456
#, c-format
msgid "No executable found\n"
msgstr "Nenalezen žádný spustitelný soubor\n"

#: app/flatpak-builtins-build-finish.c:511
#, c-format
msgid "Invalid --require-version argument: %s"
msgstr "Neplatný --require-version argument: %s"

#: app/flatpak-builtins-build-finish.c:543
#, c-format
msgid "Too few elements in --extra-data argument %s"
msgstr ""

#: app/flatpak-builtins-build-finish.c:575
#, c-format
msgid ""
"Too few elements in --metadata argument %s, format should be "
"GROUP=KEY[=VALUE]]"
msgstr ""

#: app/flatpak-builtins-build-finish.c:597
#: app/flatpak-builtins-build-init.c:458
#, c-format
msgid ""
"Too few elements in --extension argument %s, format should be "
"NAME=VAR[=VALUE]"
msgstr ""

#: app/flatpak-builtins-build-finish.c:603
#: app/flatpak-builtins-build-init.c:461
#, c-format
msgid "Invalid extension name %s"
msgstr "Neplatný název rozšíření %s"

#: app/flatpak-builtins-build-finish.c:646
msgid "DIRECTORY - Finalize a build directory"
msgstr "ADRESÁŘ - Dokončit adresář sestavení"

#: app/flatpak-builtins-build-finish.c:668
#, c-format
msgid "Build directory %s not initialized"
msgstr "Adresář sestavení %s není inicializován"

#: app/flatpak-builtins-build-finish.c:689
#, c-format
msgid "Build directory %s already finalized"
msgstr "Adresář sestavení %s je již uzavřen"

#: app/flatpak-builtins-build-finish.c:702
#, c-format
msgid "Please review the exported files and the metadata\n"
msgstr "Zkontrolujte prosím exportované soubory a metadata\n"

#: app/flatpak-builtins-build-import-bundle.c:47
msgid "Override the ref used for the imported bundle"
msgstr ""

#: app/flatpak-builtins-build-import-bundle.c:47
msgid "REF"
msgstr "REF"

#: app/flatpak-builtins-build-import-bundle.c:48
msgid "Import oci image instead of flatpak bundle"
msgstr "Importovat oci obraz namísto flatpak balíku"

#: app/flatpak-builtins-build-import-bundle.c:77
#: app/flatpak-builtins-build-import-bundle.c:105
#, c-format
msgid "Importing %s (%s)\n"
msgstr "Importuje se %s (%s)\n"

#: app/flatpak-builtins-build-import-bundle.c:126
msgid "LOCATION FILENAME - Import a file bundle into a local repository"
msgstr ""
"UMÍSTĚNÍ NÁZEV_SOUBORU - Importovat soubor balíku do místního repozitáře"

#: app/flatpak-builtins-build-import-bundle.c:133
msgid "LOCATION and FILENAME must be specified"
msgstr "UMÍSTĚNÍ a NÁZEV_SOUBORU musí být určeny"

#: app/flatpak-builtins-build-init.c:53 app/flatpak-builtins-info.c:55
#: app/flatpak-builtins-run.c:158
msgid "Arch to use"
msgstr "Architektura, která se má použít"

#: app/flatpak-builtins-build-init.c:54
msgid "Initialize var from named runtime"
msgstr ""

#: app/flatpak-builtins-build-init.c:55
msgid "Initialize apps from named app"
msgstr ""

#: app/flatpak-builtins-build-init.c:55
msgid "APP"
msgstr "APLIKACE"

#: app/flatpak-builtins-build-init.c:56
msgid "Specify version for --base"
msgstr "Určit verzi pro --base"

#: app/flatpak-builtins-build-init.c:56 app/flatpak-builtins-run.c:164
msgid "VERSION"
msgstr "VERZE"

#: app/flatpak-builtins-build-init.c:57
msgid "Include this base extension"
msgstr "Zahrnout toto základní rozšíření"

#: app/flatpak-builtins-build-init.c:57 app/flatpak-builtins-build-init.c:62
msgid "EXTENSION"
msgstr "ROZŠÍŘENÍ"

#: app/flatpak-builtins-build-init.c:58
msgid "Extension tag to use if building extension"
msgstr "Tag rozšíření, který je použit při sestavování rozšíření"

#: app/flatpak-builtins-build-init.c:58
msgid "EXTENSION_TAG"
msgstr "TAG_ROZŠÍŘENÍ"

#: app/flatpak-builtins-build-init.c:59
msgid "Initialize /usr with a writable copy of the sdk"
msgstr "Inicializovat /usr se zapisovatelnou kopií sdk"

#: app/flatpak-builtins-build-init.c:60
msgid "Specify the build type (app, runtime, extension)"
msgstr "Určit typ sestavení (aplikace, prostředí, rozšíření)"

#: app/flatpak-builtins-build-init.c:60
msgid "TYPE"
msgstr "TYP"

#: app/flatpak-builtins-build-init.c:61
msgid "Add a tag"
msgstr "Přidat značku"

#: app/flatpak-builtins-build-init.c:61
msgid "TAG"
msgstr "ZNAČKA"

#: app/flatpak-builtins-build-init.c:62
msgid "Include this sdk extension in /usr"
msgstr "Zahrnout toto rozšíření sdk v /usr"

#: app/flatpak-builtins-build-init.c:64
msgid "Where to store sdk (defaults to 'usr')"
msgstr "Kam uložit sdk (výchozí je „usr“)"

#: app/flatpak-builtins-build-init.c:65
msgid "Re-initialize the sdk/var"
msgstr "Znovu inicializovat sdk/var"

#: app/flatpak-builtins-build-init.c:118
#, c-format
msgid "Requested extension %s/%s/%s is only partially installed"
msgstr "Požadované rozšíření %s/%s/%s je nainstalováno pouze částečně"

#: app/flatpak-builtins-build-init.c:147
#, c-format
msgid "Requested extension %s/%s/%s not installed"
msgstr "Požadované rozšíření %s/%s/%s není nainstalováno"

#: app/flatpak-builtins-build-init.c:207
msgid ""
"DIRECTORY APPNAME SDK RUNTIME [BRANCH] - Initialize a directory for building"
msgstr ""
"ADRESÁŘ NÁZEV_APLIKACE SDK PROSTŘEDÍ [VĚTEV] - Inicializovat adresář k "
"sestavování"

#: app/flatpak-builtins-build-init.c:214
msgid "RUNTIME must be specified"
msgstr "PROSTŘEDÍ musí byť určeno"

#: app/flatpak-builtins-build-init.c:235
#, c-format
msgid "'%s' is not a valid build type name, use app, runtime or extension"
msgstr ""
"„%s“ není platným názvem typu sestavení, použijte app, runtime nebo extension"

#: app/flatpak-builtins-build-init.c:241 app/flatpak-builtins-override.c:79
#, c-format
msgid "'%s' is not a valid application name: %s"
msgstr "„%s“ není platným názvem aplikace: %s"

#: app/flatpak-builtins-build-init.c:295
#, c-format
msgid "Build directory %s already initialized"
msgstr "Adresář sestavení %s je již inicializován"

#: app/flatpak-builtins-build-sign.c:42 app/flatpak-builtins-install.c:67
#: app/flatpak-builtins-remote-info.c:54
msgid "Arch to install for"
msgstr "Architektura, pro kterou se má instalovat"

#: app/flatpak-builtins-build-sign.c:43 app/flatpak-builtins-create-usb.c:48
#: app/flatpak-builtins-install.c:74 app/flatpak-builtins-remote-info.c:56
#: app/flatpak-builtins-uninstall.c:58 app/flatpak-builtins-update.c:64
msgid "Look for runtime with the specified name"
msgstr "Hledat prostředí s určeným názvem"

#: app/flatpak-builtins-build-sign.c:66
msgid "LOCATION [ID [BRANCH]] - Sign an application or runtime"
msgstr "UMÍSTĚNÍ [ID [VĚTEV]] - Podepsat aplikaci nebo prostředí"

#: app/flatpak-builtins-build-sign.c:73
#: app/flatpak-builtins-build-update-repo.c:499
#: app/flatpak-builtins-remote-add.c:320 app/flatpak-builtins-repo.c:739
msgid "LOCATION must be specified"
msgstr "UMÍSTĚNÍ musí být určeno"

#: app/flatpak-builtins-build-sign.c:94
msgid "No gpg key ids specified"
msgstr "Žádné id klíče gpg určeny"

#: app/flatpak-builtins-build-update-repo.c:68
msgid "Redirect this repo to a new URL"
msgstr "Přesměrovat tento repozitář na novou URL"

#: app/flatpak-builtins-build-update-repo.c:69
msgid "A nice name to use for this repository"
msgstr "Hezký název, který bude použit pro tento repozitář"

#: app/flatpak-builtins-build-update-repo.c:69
#: app/flatpak-builtins-remote-add.c:77 app/flatpak-builtins-remote-modify.c:82
msgid "TITLE"
msgstr "JMÉNO"

#: app/flatpak-builtins-build-update-repo.c:70
msgid "A one-line comment for this repository"
msgstr "Jednořádkový komentář pro tento repozitář"

#: app/flatpak-builtins-build-update-repo.c:70
#: app/flatpak-builtins-remote-add.c:78 app/flatpak-builtins-remote-modify.c:83
msgid "COMMENT"
msgstr "KOMENTÁŘ"

#: app/flatpak-builtins-build-update-repo.c:71
msgid "A full-paragraph description for this repository"
msgstr "Popis v celém odstavci pro tento repozitář"

#: app/flatpak-builtins-build-update-repo.c:71
#: app/flatpak-builtins-remote-add.c:79 app/flatpak-builtins-remote-modify.c:84
msgid "DESCRIPTION"
msgstr "POPIS"

#: app/flatpak-builtins-build-update-repo.c:72
msgid "URL for a website for this repository"
msgstr "URL pro webovou stránku pro tento repozitář"

#: app/flatpak-builtins-build-update-repo.c:73
msgid "URL for an icon for this repository"
msgstr "URL pro ikonu pro tento repozitář"

#: app/flatpak-builtins-build-update-repo.c:74
msgid "Default branch to use for this repository"
msgstr "Výchozí větev pro použití s tímto vzdáleným repozitářem"

#: app/flatpak-builtins-build-update-repo.c:74
#: app/flatpak-builtins-remote-add.c:82 app/flatpak-builtins-remote-modify.c:87
#: app/flatpak-builtins-repo.c:713 app/flatpak-builtins-repo.c:714
#: app/flatpak-builtins-run.c:161
msgid "BRANCH"
msgstr "VĚTEV"

#: app/flatpak-builtins-build-update-repo.c:75
#: app/flatpak-builtins-remote-add.c:83 app/flatpak-builtins-remote-modify.c:88
msgid "COLLECTION-ID"
msgstr "ID-KOLEKCE"

#. Translators: A sideload is when you install from a local USB drive rather than the Internet.
#: app/flatpak-builtins-build-update-repo.c:77
msgid ""
"Permanently deploy collection ID to client remote configurations, only for "
"sideload support"
msgstr ""

#: app/flatpak-builtins-build-update-repo.c:78
msgid "Permanently deploy collection ID to client remote configurations"
msgstr ""

#: app/flatpak-builtins-build-update-repo.c:79
msgid "Name of authenticator for this repository"
msgstr "Název autentikátoru pro tento repozitář"

#: app/flatpak-builtins-build-update-repo.c:80
msgid "Autoinstall authenticator for this repository"
msgstr "Automaticky instalovat autentikátor pro tento repozitář"

#: app/flatpak-builtins-build-update-repo.c:81
msgid "Don't autoinstall authenticator for this repository"
msgstr "Neinstalovat automaticky autentikátor pro tento repozitář"

#: app/flatpak-builtins-build-update-repo.c:82
#: app/flatpak-builtins-remote-add.c:89
msgid "Authenticator option"
msgstr "Volba autentikátoru"

#: app/flatpak-builtins-build-update-repo.c:82
#: app/flatpak-builtins-remote-add.c:89 app/flatpak-builtins-remote-modify.c:95
msgid "KEY=VALUE"
msgstr "KLÍČ=HODNOTA"

#: app/flatpak-builtins-build-update-repo.c:83
msgid "Import new default GPG public key from FILE"
msgstr "Importovat nový výchozí veřejný klíč GPG ze SOUBORU"

#: app/flatpak-builtins-build-update-repo.c:84
msgid "GPG Key ID to sign the summary with"
msgstr "ID klíče GPG pro podepsání shrnutí"

#: app/flatpak-builtins-build-update-repo.c:86
msgid "Generate delta files"
msgstr "Generovat delta soubory"

#: app/flatpak-builtins-build-update-repo.c:88
msgid "Don't update the appstream branch"
msgstr "Neaktualizovat appstream větev"

#: app/flatpak-builtins-build-update-repo.c:89
msgid "Max parallel jobs when creating deltas (default: NUMCPUs)"
msgstr ""

#: app/flatpak-builtins-build-update-repo.c:89
msgid "NUM-JOBS"
msgstr "POČET-ÚLOHY"

#: app/flatpak-builtins-build-update-repo.c:90
msgid "Don't create deltas matching refs"
msgstr ""

#: app/flatpak-builtins-build-update-repo.c:91
msgid "Prune unused objects"
msgstr ""

#: app/flatpak-builtins-build-update-repo.c:92
msgid "Prune but don't actually remove anything"
msgstr ""

#: app/flatpak-builtins-build-update-repo.c:93
msgid "Only traverse DEPTH parents for each commit (default: -1=infinite)"
msgstr ""

#: app/flatpak-builtins-build-update-repo.c:93
msgid "DEPTH"
msgstr "HLOUBKA"

#: app/flatpak-builtins-build-update-repo.c:223
#, c-format
msgid "Generating delta: %s (%.10s)\n"
msgstr "Generování delta souboru: %s (%.10s)\n"

#: app/flatpak-builtins-build-update-repo.c:225
#, c-format
msgid "Generating delta: %s (%.10s-%.10s)\n"
msgstr "Generování delta souboru: %s (%.10s-%.10s)\n"

#: app/flatpak-builtins-build-update-repo.c:233
#, c-format
msgid "Failed to generate delta %s (%.10s): "
msgstr "Selhalo generování delta souboru %s (%.10s): "

#: app/flatpak-builtins-build-update-repo.c:236
#, c-format
msgid "Failed to generate delta %s (%.10s-%.10s): "
msgstr "Selhalo generování delta souboru %s (%.10s-%.10s): "

#: app/flatpak-builtins-build-update-repo.c:492
msgid "LOCATION - Update repository metadata"
msgstr "UMÍSTĚNÍ - Aktualizovat metadata repozitáře"

#: app/flatpak-builtins-build-update-repo.c:609
#, c-format
msgid "Updating appstream branch\n"
msgstr "Aktualizace appstream větve\n"

#: app/flatpak-builtins-build-update-repo.c:638
#, c-format
msgid "Updating summary\n"
msgstr "Aktualizace shrnutí\n"

#: app/flatpak-builtins-build-update-repo.c:664
#, c-format
msgid "Total objects: %u\n"
msgstr "Celkový počet objektů: %u\n"

#: app/flatpak-builtins-build-update-repo.c:666
#, c-format
msgid "No unreachable objects\n"
msgstr "Žádné nedostupné objekty\n"

#: app/flatpak-builtins-build-update-repo.c:668
#, c-format
msgid "Deleted %u objects, %s freed\n"
msgstr "Odstraněno %u objektů, %s uvolněno\n"

#: app/flatpak-builtins-config.c:41
msgid "List configuration keys and values"
msgstr "Vypsat konfigurační klíče a hodnoty"

#: app/flatpak-builtins-config.c:42
msgid "Get configuration for KEY"
msgstr "Získat konfiguraci pro KLÍČ"

#: app/flatpak-builtins-config.c:43
msgid "Set configuration for KEY to VALUE"
msgstr "Nastavit konfiguraci pro KLÍČ na HODNOTU"

#: app/flatpak-builtins-config.c:44
msgid "Unset configuration for KEY"
msgstr "Zrušit konfiguraci pro KLÍČ"

#: app/flatpak-builtins-config.c:149
#, c-format
msgid "'%s' does not look like a language/locale code"
msgstr "„%s“ nevypadá jako jazykový/locale kód"

#: app/flatpak-builtins-config.c:172
#, c-format
msgid "'%s' does not look like a language code"
msgstr "„%s“ nevypadá jako jazykový kód"

#: app/flatpak-builtins-config.c:190
#, fuzzy, c-format
msgid "'%s' is not a valid value (use 'true' or 'false')"
msgstr "„%s“ není platným repozitářem: "

#: app/flatpak-builtins-config.c:262
#, c-format
msgid "Unknown configure key '%s'"
msgstr "Neznámý konfigurační klíč „%s“"

#: app/flatpak-builtins-config.c:284
msgid "Too many arguments for --list"
msgstr "Příliš mnoho parametrů pro --list"

#: app/flatpak-builtins-config.c:314 app/flatpak-builtins-config.c:362
msgid "You must specify KEY"
msgstr "Musíte určit KLÍČ"

#: app/flatpak-builtins-config.c:316
msgid "Too many arguments for --get"
msgstr "Příliš mnoho parametrů pro --get"

#: app/flatpak-builtins-config.c:338
msgid "You must specify KEY and VALUE"
msgstr "Musíte určit KLÍČ a HODNOTU"

#: app/flatpak-builtins-config.c:340
msgid "Too many arguments for --set"
msgstr "Příliš mnoho parametrů pro --set"

#: app/flatpak-builtins-config.c:364
msgid "Too many arguments for --unset"
msgstr "Příliš mnoho parametrů pro --unset"

#: app/flatpak-builtins-config.c:383
msgid "[KEY [VALUE]] - Manage configuration"
msgstr "[KLÍČ [HODNOTA]] - Spravovat konfiguraci"

#: app/flatpak-builtins-config.c:394
msgid "Can only use one of --list, --get, --set or --unset"
msgstr "Můžete určit pouze jedno z --list, --get, --set nebo --unset"

#: app/flatpak-builtins-config.c:408
msgid "Must specify one of --list, --get, --set or --unset"
msgstr "Musíte určit jedno z --list, --get, --set nebo --unset"

#: app/flatpak-builtins-create-usb.c:45 app/flatpak-builtins-install.c:75
#: app/flatpak-builtins-remote-info.c:57 app/flatpak-builtins-uninstall.c:59
#: app/flatpak-builtins-update.c:65
msgid "Look for app with the specified name"
msgstr "Hledat aplikaci s určeným názvem"

#: app/flatpak-builtins-create-usb.c:46
msgid "Arch to copy"
msgstr "Architektura, která se má kopírovat"

#: app/flatpak-builtins-create-usb.c:47
msgid "DEST"
msgstr "CÍL"

#: app/flatpak-builtins-create-usb.c:49
msgid "Allow partial commits in the created repo"
msgstr "Povolit částečné commity ve vytvořeném repozitáři"

#: app/flatpak-builtins-create-usb.c:125 app/flatpak-builtins-create-usb.c:165
#, c-format
msgid ""
"Warning: Related ref ‘%s’ is partially installed. Use --allow-partial to "
"suppress this message.\n"
msgstr ""
"Varování: Související ref „%s“ je částečně nainstalován. Pro potlačení této "
"zprávy použijte --allow-partial.\n"

#: app/flatpak-builtins-create-usb.c:158
#, c-format
msgid "Warning: Omitting related ref ‘%s’ because it is not installed.\n"
msgstr ""
"Varování: Vynechává se související ref „%s“, protože není nainstalován.\n"

#: app/flatpak-builtins-create-usb.c:175
#, c-format
msgid ""
"Warning: Omitting related ref ‘%s’ because its remote ‘%s’ does not have a "
"collection ID set.\n"
msgstr ""
"Varování: Vynechává se související ref „%s“, protože jeho vzdálený repozitář "
"„%s“ nemá nastaveno ID kolekce.\n"

#: app/flatpak-builtins-create-usb.c:187
#, c-format
msgid "Warning: Omitting related ref ‘%s’ because it's extra-data.\n"
msgstr ""
"Varování: Vynechává se související ref „%s“, protože se jedná o extra-data.\n"

#: app/flatpak-builtins-create-usb.c:262 app/flatpak-builtins-create-usb.c:637
#, c-format
msgid ""
"Remote ‘%s’ does not have a collection ID set, which is required for P2P "
"distribution of ‘%s’."
msgstr ""
"Vzdálený repozitář „%s“ nemá nastaveno ID kolekce, které je povinné pro P2P "
"distribuci „%s“."

#: app/flatpak-builtins-create-usb.c:272
#, c-format
msgid "Warning: Omitting ref ‘%s’ (runtime of ‘%s’) because it's extra-data.\n"
msgstr ""
"Varování: Vynechává se ref „%s“ (prostředí „%s“), protože se jedná o extra-"
"data.\n"

#: app/flatpak-builtins-create-usb.c:484
msgid "MOUNT-PATH [REF…] - Copy apps or runtimes onto removable media"
msgstr ""
"CESTA-PŘIPOJENÍ [REF…] - Kopírovat aplikace a/nebo prostředí na vyměnitelné "
"médium"

#: app/flatpak-builtins-create-usb.c:493
msgid "MOUNT-PATH and REF must be specified"
msgstr "CESTA-PŘIPOJENÍ a REF musí být určeny"

#: app/flatpak-builtins-create-usb.c:607
#, c-format
msgid "Ref ‘%s’ found in multiple installations: %s. You must specify one."
msgstr "Ref „%s“ nalezen ve více instalacích: %s. Musíte určit jednu."

#: app/flatpak-builtins-create-usb.c:620
#, c-format
msgid "Refs must all be in the same installation (found in %s and %s)."
msgstr "Refy musí být všechny ve stejné instalaci (nalezeno v %s a %s)."

#: app/flatpak-builtins-create-usb.c:670
#, c-format
msgid ""
"Warning: Ref ‘%s’ is partially installed. Use --allow-partial to suppress "
"this message.\n"
msgstr ""
"Varování: Ref „%s“ je částečně nainstalován. Pro potlačení této zprávy "
"použijte --allow-partial.\n"

#: app/flatpak-builtins-create-usb.c:681
#, c-format
msgid "Installed ref ‘%s’ is extra-data, and cannot be distributed offline"
msgstr "Instalovaný ref „%s“ je extra-data a nemůže být distribuován offline"

#: app/flatpak-builtins-create-usb.c:721
#, c-format
msgid "Warning: Couldn't update repo metadata for remote ‘%s’: %s\n"
msgstr ""
"Varování: Nepodařilo se aktualizovat repo metadata pro vzdálený repozitář "
"„%s“: %s\n"

#: app/flatpak-builtins-create-usb.c:751
#, c-format
msgid "Warning: Couldn't update appstream data for remote ‘%s’ arch ‘%s’: %s\n"
msgstr ""
"Varování: Nepodařilo se aktualizovat appstream data pro vzdálený repozitář "
"„%s“ architektura „%s“: %s\n"

#. Print a warning if both appstream and appstream2 are missing
#: app/flatpak-builtins-create-usb.c:784
#, c-format
msgid ""
"Warning: Couldn't find appstream data for remote ‘%s’ arch ‘%s’: %s; %s\n"
msgstr ""
"Varování: Nelze nalézt appstream data pro vzdálený repozitář „%s“ "
"architektura „%s“: %s; %s\n"

#. Appstream2 is only for efficiency, so just print a debug message
#: app/flatpak-builtins-create-usb.c:790
#, c-format
msgid "Couldn't find appstream2 data for remote ‘%s’ arch ‘%s’: %s\n"
msgstr ""
"Nelze nalézt appstream2 data pro vzdálený repozitář „%s“ architektura „%s“: "
"%s\n"

#: app/flatpak-builtins-document-export.c:62
msgid "Create a unique document reference"
msgstr "Vytvořit unikátní referenci dokumentu"

#: app/flatpak-builtins-document-export.c:63
msgid "Make the document transient for the current session"
msgstr "Udělat dokument dočasný pouze pro toto sezení"

#: app/flatpak-builtins-document-export.c:64
msgid "Don't require the file to exist already"
msgstr "Nevyžadovat, aby soubor již existoval"

#: app/flatpak-builtins-document-export.c:65
msgid "Give the app read permissions"
msgstr "Udělit aplikaci oprávnění ke čtení"

#: app/flatpak-builtins-document-export.c:66
msgid "Give the app write permissions"
msgstr "Udělit aplikaci oprávnění k zápisu"

#: app/flatpak-builtins-document-export.c:67
msgid "Give the app delete permissions"
msgstr "Udělit aplikaci oprávnění k mazání"

#: app/flatpak-builtins-document-export.c:68
msgid "Give the app permissions to grant further permissions"
msgstr "Udělit aplikaci oprávnění k získání dalších oprávnění"

#: app/flatpak-builtins-document-export.c:69
msgid "Revoke read permissions of the app"
msgstr "Zrušit oprávnění aplikace ke čtení"

#: app/flatpak-builtins-document-export.c:70
msgid "Revoke write permissions of the app"
msgstr "Zrušit oprávnění aplikace k zápisu"

#: app/flatpak-builtins-document-export.c:71
msgid "Revoke delete permissions of the app"
msgstr "Zrušit oprávnění aplikace k mazání"

#: app/flatpak-builtins-document-export.c:72
msgid "Revoke the permission to grant further permissions"
msgstr "Zrušit oprávnění k získání dalších oprávnění"

#: app/flatpak-builtins-document-export.c:73
msgid "Add permissions for this app"
msgstr "Přidat oprávnění pro tuto aplikaci"

#: app/flatpak-builtins-document-export.c:73
msgid "APPID"
msgstr "APPID"

#: app/flatpak-builtins-document-export.c:100
msgid "FILE - Export a file to apps"
msgstr "SOUBOR - Exportovat soubor pro aplikace"

#: app/flatpak-builtins-document-export.c:109
#: app/flatpak-builtins-document-info.c:72
#: app/flatpak-builtins-document-unexport.c:67
msgid "FILE must be specified"
msgstr "SOUBOR musí být určen"

#: app/flatpak-builtins-document-info.c:63
msgid "FILE - Get information about an exported file"
msgstr "SOUBOR - Získat informace o exportovaném souboru"

#: app/flatpak-builtins-document-info.c:100
#: app/flatpak-builtins-document-unexport.c:94
#, c-format
msgid "Not exported\n"
msgstr "Neexportováno\n"

#: app/flatpak-builtins-document-list.c:43 app/flatpak-builtins-history.c:53
#: app/flatpak-builtins-list.c:54 app/flatpak-builtins-ps.c:43
#: app/flatpak-builtins-remote-list.c:45 app/flatpak-builtins-remote-ls.c:59
#: app/flatpak-builtins-search.c:38
msgid "What information to show"
msgstr "Jaké informace zobrazit"

#: app/flatpak-builtins-document-list.c:43 app/flatpak-builtins-history.c:53
#: app/flatpak-builtins-list.c:54 app/flatpak-builtins-ps.c:43
#: app/flatpak-builtins-remote-list.c:45 app/flatpak-builtins-remote-ls.c:59
#: app/flatpak-builtins-search.c:38
msgid "FIELD,…"
msgstr "POLE,…"

#: app/flatpak-builtins-document-list.c:44 app/flatpak-builtins-history.c:54
#: app/flatpak-builtins-list.c:52 app/flatpak-builtins-permission-list.c:43
#: app/flatpak-builtins-permission-show.c:43 app/flatpak-builtins-ps.c:44
#: app/flatpak-builtins-remote-list.c:46 app/flatpak-builtins-remote-ls.c:63
#: app/flatpak-builtins-repo.c:717 app/flatpak-builtins-search.c:39
#, fuzzy
msgid "Show output in JSON format"
msgstr "Zobrazit dodatečné informace"

#: app/flatpak-builtins-document-list.c:49
msgid "Show the document ID"
msgstr "Zobrazit ID dokumentu"

#: app/flatpak-builtins-document-list.c:50
msgid "Path"
msgstr "Cesta"

#: app/flatpak-builtins-document-list.c:50
#: app/flatpak-builtins-document-list.c:51
msgid "Show the document path"
msgstr "Zobrazit cestu k dokumentu"

#: app/flatpak-builtins-document-list.c:51 app/flatpak-builtins-list.c:66
#: app/flatpak-builtins-remote-ls.c:74
msgid "Origin"
msgstr "Původ"

#: app/flatpak-builtins-document-list.c:52 app/flatpak-builtins-history.c:62
#: app/flatpak-builtins-ps.c:52
msgid "Application"
msgstr "Aplikace"

#: app/flatpak-builtins-document-list.c:52
msgid "Show applications with permission"
msgstr "Zobrazit aplikace s oprávněním"

#: app/flatpak-builtins-document-list.c:53
#: app/flatpak-builtins-permission-list.c:182
#: app/flatpak-builtins-permission-show.c:145
msgid "Permissions"
msgstr "Oprávnění"

#: app/flatpak-builtins-document-list.c:53
msgid "Show permissions for applications"
msgstr "Zobrazit oprávnění pro aplikace"

#: app/flatpak-builtins-document-list.c:161
#, c-format
msgid "No documents found\n"
msgstr "Nenalezeny žádné dokumenty\n"

#: app/flatpak-builtins-document-list.c:180
msgid "[APPID] - List exported files"
msgstr "[APPID] - Zobrazit exportované soubory"

#: app/flatpak-builtins-document-unexport.c:43
msgid "Specify the document ID"
msgstr "Určit ID dokumentu"

#: app/flatpak-builtins-document-unexport.c:58
msgid "FILE - Unexport a file to apps"
msgstr "SOUBOR - Zrušit export souboru pro aplikace"

#: app/flatpak-builtins-enter.c:88
msgid "INSTANCE COMMAND [ARGUMENT…] - Run a command inside a running sandbox"
msgstr "INSTANCE PŘÍKAZ [ARGUMENT…] - Spustit příkaz v běžícím sandboxu"

#: app/flatpak-builtins-enter.c:111
msgid "INSTANCE and COMMAND must be specified"
msgstr "INSTANCE a PŘÍKAZ musí být určeny"

#: app/flatpak-builtins-enter.c:138
#, c-format
msgid "%s is neither a pid nor an application or instance ID"
msgstr "%s není pid ani aplikace nebo ID instance"

#: app/flatpak-builtins-enter.c:144
msgid "entering not supported (need unprivileged user namespaces, or sudo -E)"
msgstr ""
"vstup není podporován (vyžaduje neprivilegované uživatelské jmenné prostory, "
"nebo sudo -E)"

#: app/flatpak-builtins-enter.c:145
#, c-format
msgid "No such pid %s"
msgstr "Identifikátor pid %s neexistuje"

#: app/flatpak-builtins-enter.c:158
msgid "Can't read cwd"
msgstr "Nelze číst cwd"

#: app/flatpak-builtins-enter.c:163
msgid "Can't read root"
msgstr "Nelze číst root"

#: app/flatpak-builtins-enter.c:191
#, c-format
msgid "Invalid %s namespace for pid %d"
msgstr "Neplatný jmenný prostor %s pro pid %d"

#: app/flatpak-builtins-enter.c:202
#, c-format
msgid "Invalid %s namespace for self"
msgstr "Neplatný jmenný prostor %s pro self"

#: app/flatpak-builtins-enter.c:216
#, c-format
msgid "Can't open %s namespace: %s"
msgstr "Nelze otevřít jmenný prostor %s: %s"

#: app/flatpak-builtins-enter.c:226
msgid "entering not supported (need unprivileged user namespaces)"
msgstr ""
"vstup není podporován (vyžaduje neprivilegované uživatelské jmenné prostory)"

#: app/flatpak-builtins-enter.c:227
#, c-format
msgid "Can't enter %s namespace: %s"
msgstr "Nelze vstoupit do jmenného prostoru %s: %s"

#: app/flatpak-builtins-enter.c:234
msgid "Can't chdir"
msgstr "Nelze vykonat chdir"

#: app/flatpak-builtins-enter.c:237
msgid "Can't chroot"
msgstr "Nelze vykonat chroot"

#: app/flatpak-builtins-enter.c:240
msgid "Can't switch gid"
msgstr "Nelze přepnout gid"

#: app/flatpak-builtins-enter.c:243
msgid "Can't switch uid"
msgstr "Nelze přepnout uid"

#: app/flatpak-builtins-history.c:50
msgid "Only show changes after TIME"
msgstr "Zobrazit pouze změny po ČAS"

#: app/flatpak-builtins-history.c:50 app/flatpak-builtins-history.c:51
msgid "TIME"
msgstr "ČAS"

#: app/flatpak-builtins-history.c:51
msgid "Only show changes before TIME"
msgstr "Zobrazit pouze změny před ČAS"

#: app/flatpak-builtins-history.c:52
msgid "Show newest entries first"
msgstr "Zobrazit nejnovější jako první"

#: app/flatpak-builtins-history.c:59
msgid "Time"
msgstr "Čas"

#: app/flatpak-builtins-history.c:59
msgid "Show when the change happened"
msgstr "Zobrazit, kdy změna nastala"

#: app/flatpak-builtins-history.c:60
msgid "Change"
msgstr "Změna"

#: app/flatpak-builtins-history.c:60
msgid "Show the kind of change"
msgstr "Zobrazit druh změny"

#: app/flatpak-builtins-history.c:61 app/flatpak-builtins-list.c:68
#: app/flatpak-builtins-remote-ls.c:75 app/flatpak-builtins-repo.c:335
msgid "Ref"
msgstr "Ref"

#: app/flatpak-builtins-history.c:61 app/flatpak-builtins-list.c:68
#: app/flatpak-builtins-remote-ls.c:75
msgid "Show the ref"
msgstr "Zobrazit ref"

#: app/flatpak-builtins-history.c:62
msgid "Show the application/runtime ID"
msgstr "Zobrazit ID aplikace/prostředí"

#: app/flatpak-builtins-history.c:63 app/flatpak-builtins-list.c:64
#: app/flatpak-builtins-ps.c:53 app/flatpak-builtins-remote-ls.c:73
#: app/flatpak-cli-transaction.c:1435
msgid "Arch"
msgstr "Architektura"

#: app/flatpak-builtins-history.c:63 app/flatpak-builtins-list.c:64
#: app/flatpak-builtins-ps.c:53 app/flatpak-builtins-remote-ls.c:73
msgid "Show the architecture"
msgstr "Zobrazit architekturu"

#: app/flatpak-builtins-history.c:64 app/flatpak-builtins-list.c:63
#: app/flatpak-builtins-ps.c:54 app/flatpak-builtins-remote-ls.c:72
#: app/flatpak-builtins-search.c:48 app/flatpak-cli-transaction.c:1438
msgid "Branch"
msgstr "Větev"

#: app/flatpak-builtins-history.c:64 app/flatpak-builtins-list.c:63
#: app/flatpak-builtins-remote-ls.c:72
msgid "Show the branch"
msgstr "Zobrazit větev"

#: app/flatpak-builtins-history.c:65 app/flatpak-builtins-list.c:67
msgid "Installation"
msgstr "Instalace"

#: app/flatpak-builtins-history.c:65
msgid "Show the affected installation"
msgstr "Zobrazit ovlivněnou instalaci"

#: app/flatpak-builtins-history.c:66 app/flatpak-cli-transaction.c:1452
msgid "Remote"
msgstr "Vzdálený repozitář"

#: app/flatpak-builtins-history.c:66
msgid "Show the remote"
msgstr "Zobrazit vzdálený repozitář"

#: app/flatpak-builtins-history.c:67 app/flatpak-builtins-ps.c:55
#: app/flatpak-builtins-remote-ls.c:76
msgid "Commit"
msgstr "Commit"

#: app/flatpak-builtins-history.c:67
msgid "Show the current commit"
msgstr "Zobrazit aktuální commit"

#: app/flatpak-builtins-history.c:68
msgid "Old Commit"
msgstr "Starý commit"

#: app/flatpak-builtins-history.c:68
msgid "Show the previous commit"
msgstr "Zobrazit předchozí commit"

#: app/flatpak-builtins-history.c:69
msgid "Show the remote URL"
msgstr "Zobrazit URL vzdáleného repozitáře"

#: app/flatpak-builtins-history.c:70 app/flatpak-cli-transaction.c:700
msgid "User"
msgstr "Uživatel"

#: app/flatpak-builtins-history.c:70
msgid "Show the user doing the change"
msgstr "Zobrazit uživatele provádějícího změnu"

#: app/flatpak-builtins-history.c:71
msgid "Tool"
msgstr "Nástroj"

#: app/flatpak-builtins-history.c:71
msgid "Show the tool that was used"
msgstr "Zobrazit nástroj, který byl použit"

#: app/flatpak-builtins-history.c:72 app/flatpak-builtins-list.c:62
#: app/flatpak-builtins-remote-ls.c:71 app/flatpak-builtins-search.c:47
msgid "Version"
msgstr "Verze"

#: app/flatpak-builtins-history.c:72
msgid "Show the Flatpak version"
msgstr "Zobrazit verzi Flatpaku"

#: app/flatpak-builtins-history.c:91
#, c-format
msgid "Failed to get journal data (%s): %s"
msgstr ""

#: app/flatpak-builtins-history.c:146
#, c-format
msgid "Failed to open journal: %s"
msgstr ""

#: app/flatpak-builtins-history.c:153
#, c-format
msgid "Failed to add match to journal: %s"
msgstr ""

#: app/flatpak-builtins-history.c:471
msgid " - Show history"
msgstr " - Zobrazit historii"

#: app/flatpak-builtins-history.c:490
#, c-format
msgid "Failed to parse the --since option"
msgstr "Nelze zpracovat volbu --since"

#: app/flatpak-builtins-history.c:501
#, c-format
msgid "Failed to parse the --until option"
msgstr "Nelze zpracovat volbu --until"

#: app/flatpak-builtins-info.c:56
msgid "Show user installations"
msgstr "Zobrazit uživatelské instalace"

#: app/flatpak-builtins-info.c:57
msgid "Show system-wide installations"
msgstr "Zobrazit systémové instalace"

#: app/flatpak-builtins-info.c:58
msgid "Show specific system-wide installations"
msgstr "Zobrazit specifické systémové instalace"

#: app/flatpak-builtins-info.c:59 app/flatpak-builtins-remote-info.c:59
msgid "Show ref"
msgstr "Zobrazit ref"

#: app/flatpak-builtins-info.c:60 app/flatpak-builtins-remote-info.c:60
msgid "Show commit"
msgstr "Zobrazit commit"

#: app/flatpak-builtins-info.c:61
msgid "Show origin"
msgstr "Zobrazit původ"

#: app/flatpak-builtins-info.c:62
msgid "Show size"
msgstr "Zobrazit velikost"

#: app/flatpak-builtins-info.c:63 app/flatpak-builtins-remote-info.c:62
msgid "Show metadata"
msgstr "Zobrazit metadata"

#: app/flatpak-builtins-info.c:64 app/flatpak-builtins-remote-info.c:63
msgid "Show runtime"
msgstr "Zobrazit prostředí"

#: app/flatpak-builtins-info.c:65 app/flatpak-builtins-remote-info.c:64
msgid "Show sdk"
msgstr "Zobrazit sdk"

#: app/flatpak-builtins-info.c:66
msgid "Show permissions"
msgstr "Zobrazit oprávnění"

#: app/flatpak-builtins-info.c:67
msgid "Query file access"
msgstr "Dotázat se na přístup k souborům"

#: app/flatpak-builtins-info.c:67 app/flatpak-builtins-install.c:82
#: app/flatpak-builtins-install.c:88 app/flatpak-builtins-preinstall.c:68
#: app/flatpak-builtins-run.c:182 app/flatpak-builtins-run.c:184
#: app/flatpak-builtins-update.c:67 app/flatpak-builtins-update.c:71
msgid "PATH"
msgstr "CESTA"

#: app/flatpak-builtins-info.c:68
msgid "Show extensions"
msgstr "Zobrazit rozšíření"

#: app/flatpak-builtins-info.c:69
msgid "Show location"
msgstr "Zobrazit umístění"

#: app/flatpak-builtins-info.c:116
msgid "NAME [BRANCH] - Get info about an installed app or runtime"
msgstr ""
"NÁZEV [VĚTEV] - Získat informace o nainstalované aplikaci nebo prostředí"

#: app/flatpak-builtins-info.c:123 app/flatpak-builtins-remote-add.c:317
#: app/flatpak-builtins-remote-delete.c:63
msgid "NAME must be specified"
msgstr "NÁZEV musí být určen"

#: app/flatpak-builtins-info.c:196
msgid "ref not present in origin"
msgstr ""

#: app/flatpak-builtins-info.c:211 app/flatpak-builtins-remote-info.c:217
#, c-format
msgid "Warning: Commit has no flatpak metadata\n"
msgstr "Varování: Commit nemá žádná flatpak metadata\n"

#: app/flatpak-builtins-info.c:217 app/flatpak-builtins-info.c:259
#: app/flatpak-builtins-info.c:455 app/flatpak-builtins-info.c:513
#: app/flatpak-builtins-remote-info.c:236
#: app/flatpak-builtins-remote-info.c:271
msgid "ID:"
msgstr "ID:"

#: app/flatpak-builtins-info.c:218 app/flatpak-builtins-info.c:260
#: app/flatpak-builtins-remote-info.c:237
#: app/flatpak-builtins-remote-info.c:272
msgid "Ref:"
msgstr "Ref:"

#: app/flatpak-builtins-info.c:219 app/flatpak-builtins-info.c:261
#: app/flatpak-builtins-remote-info.c:238
#: app/flatpak-builtins-remote-info.c:273
msgid "Arch:"
msgstr "Architektura:"

#: app/flatpak-builtins-info.c:220 app/flatpak-builtins-info.c:262
#: app/flatpak-builtins-remote-info.c:239
#: app/flatpak-builtins-remote-info.c:274
msgid "Branch:"
msgstr "Větev:"

#: app/flatpak-builtins-info.c:222 app/flatpak-builtins-info.c:264
#: app/flatpak-builtins-remote-info.c:241
#: app/flatpak-builtins-remote-info.c:276
msgid "Version:"
msgstr "Verze:"

#: app/flatpak-builtins-info.c:224 app/flatpak-builtins-info.c:266
#: app/flatpak-builtins-remote-info.c:243
#: app/flatpak-builtins-remote-info.c:278
msgid "License:"
msgstr "Licence:"

#: app/flatpak-builtins-info.c:226 app/flatpak-builtins-info.c:269
#: app/flatpak-builtins-remote-info.c:245
#: app/flatpak-builtins-remote-info.c:280
msgid "Collection:"
msgstr "Kolekce:"

#: app/flatpak-builtins-info.c:227 app/flatpak-builtins-info.c:270
#: app/flatpak-builtins-info.c:458 app/flatpak-builtins-info.c:516
msgid "Installation:"
msgstr "Instalace:"

#: app/flatpak-builtins-info.c:228 app/flatpak-builtins-info.c:271
#: app/flatpak-builtins-info.c:459 app/flatpak-builtins-info.c:517
#: app/flatpak-builtins-remote-info.c:249
#: app/flatpak-builtins-remote-info.c:284
#, fuzzy
msgid "Installed Size:"
msgstr "Instalovaná velikost:"

#: app/flatpak-builtins-info.c:231 app/flatpak-builtins-info.c:279
#: app/flatpak-builtins-remote-info.c:252
#: app/flatpak-builtins-remote-info.c:288
msgid "Runtime:"
msgstr "Prostředí:"

#: app/flatpak-builtins-info.c:232 app/flatpak-builtins-info.c:288
#: app/flatpak-builtins-remote-info.c:253
#: app/flatpak-builtins-remote-info.c:293
msgid "Sdk:"
msgstr "Sdk:"

#: app/flatpak-builtins-info.c:235 app/flatpak-builtins-info.c:313
#: app/flatpak-builtins-remote-info.c:256
#: app/flatpak-builtins-remote-info.c:319
msgid "Date:"
msgstr "Datum:"

#: app/flatpak-builtins-info.c:237 app/flatpak-builtins-info.c:311
#: app/flatpak-builtins-remote-info.c:258
#: app/flatpak-builtins-remote-info.c:317
msgid "Subject:"
msgstr "Předmět:"

#: app/flatpak-builtins-info.c:240 app/flatpak-builtins-info.c:295
msgid "Active commit:"
msgstr "Aktivní commit:"

#: app/flatpak-builtins-info.c:241 app/flatpak-builtins-info.c:298
msgid "Latest commit:"
msgstr "Poslední commit:"

#: app/flatpak-builtins-info.c:244 app/flatpak-builtins-info.c:303
#: app/flatpak-builtins-info.c:457 app/flatpak-builtins-info.c:515
#: app/flatpak-builtins-remote-info.c:259
#: app/flatpak-builtins-remote-info.c:298
msgid "Commit:"
msgstr "Commit:"

#: app/flatpak-builtins-info.c:246 app/flatpak-builtins-info.c:308
#: app/flatpak-builtins-remote-info.c:261
#: app/flatpak-builtins-remote-info.c:303
msgid "Parent:"
msgstr "Rodič:"

#: app/flatpak-builtins-info.c:248 app/flatpak-builtins-info.c:321
msgid "Alt-id:"
msgstr "Alt-id:"

#: app/flatpak-builtins-info.c:250 app/flatpak-builtins-info.c:325
#: app/flatpak-builtins-remote-info.c:263
#: app/flatpak-builtins-remote-info.c:308
msgid "End-of-life:"
msgstr "End-of-life:"

#: app/flatpak-builtins-info.c:252 app/flatpak-builtins-info.c:330
#: app/flatpak-builtins-remote-info.c:265
#: app/flatpak-builtins-remote-info.c:313
msgid "End-of-life-rebase:"
msgstr "End-of-life-rebase:"

#: app/flatpak-builtins-info.c:254 app/flatpak-builtins-info.c:317
msgid "Subdirectories:"
msgstr "Podadresáře:"

#: app/flatpak-builtins-info.c:255 app/flatpak-builtins-info.c:454
#: app/flatpak-builtins-info.c:512
msgid "Extension:"
msgstr "Rozšíření:"

#: app/flatpak-builtins-info.c:267 app/flatpak-builtins-info.c:456
#: app/flatpak-builtins-info.c:514
msgid "Origin:"
msgstr "Původ:"

#: app/flatpak-builtins-info.c:460 app/flatpak-builtins-info.c:522
msgid "Subpaths:"
msgstr "Podcesty:"

#: app/flatpak-builtins-info.c:478
msgid "unmaintained"
msgstr "neudržováno"

#: app/flatpak-builtins-info.c:480 app/flatpak-builtins-info.c:482
msgid "unknown"
msgstr "neznámé"

#: app/flatpak-builtins-install.c:68 app/flatpak-builtins-preinstall.c:57
msgid "Don't pull, only install from local cache"
msgstr "Nedělat pull, pouze instalovat z místní cache"

#: app/flatpak-builtins-install.c:69 app/flatpak-builtins-preinstall.c:58
#: app/flatpak-builtins-update.c:60
msgid "Don't deploy, only download to local cache"
msgstr "Nedělat nasazení, pouze stáhnout do místní cache"

#: app/flatpak-builtins-install.c:70 app/flatpak-builtins-preinstall.c:59
msgid "Don't install related refs"
msgstr "Neinstalovat související refy"

#: app/flatpak-builtins-install.c:71 app/flatpak-builtins-preinstall.c:60
#: app/flatpak-builtins-update.c:62
msgid "Don't verify/install runtime dependencies"
msgstr "Neověřovat/neinstalovat běhové závislosti"

#: app/flatpak-builtins-install.c:72
msgid "Don't automatically pin explicit installs"
msgstr "Nepřipínat automaticky explicitní instalace"

#: app/flatpak-builtins-install.c:73 app/flatpak-builtins-preinstall.c:61
#: app/flatpak-builtins-update.c:63
msgid "Don't use static deltas"
msgstr "Nepoužívat statické delta soubory"

#: app/flatpak-builtins-install.c:76 app/flatpak-builtins-preinstall.c:62
msgid "Additionally install the SDK used to build the given refs"
msgstr ""

#: app/flatpak-builtins-install.c:77 app/flatpak-builtins-preinstall.c:63
msgid ""
"Additionally install the debug info for the given refs and their dependencies"
msgstr ""

#: app/flatpak-builtins-install.c:78
msgid "Assume LOCATION is a .flatpak single-file bundle"
msgstr "Předpokládat, že UMÍSTĚNÍ je jednosouborový balíček .flatpak"

#: app/flatpak-builtins-install.c:79
msgid "Assume LOCATION is a .flatpakref application description"
msgstr "Předpokládat, že UMÍSTĚNÍ je popis aplikace .flatpakref"

#: app/flatpak-builtins-install.c:80
msgid "Assume LOCATION is containers-transports(5) reference to an OCI image"
msgstr ""

#: app/flatpak-builtins-install.c:81
msgid "Check bundle signatures with GPG key from FILE (- for stdin)"
msgstr ""
"Zkontrolovat podpisy balíku klíčem GPG ze souboru (- pro standardní vstup)"

#: app/flatpak-builtins-install.c:82
msgid "Only install this subpath"
msgstr "Instalovat pouze tuto podcestu"

#: app/flatpak-builtins-install.c:83 app/flatpak-builtins-preinstall.c:64
#: app/flatpak-builtins-uninstall.c:63 app/flatpak-builtins-update.c:68
msgid "Automatically answer yes for all questions"
msgstr "Automaticky odpovědět ano na všechny otázky"

#: app/flatpak-builtins-install.c:84 app/flatpak-builtins-preinstall.c:65
msgid "Uninstall first if already installed"
msgstr "Nejprve odinstalovat, pokud je již nainstalováno"

#: app/flatpak-builtins-install.c:85 app/flatpak-builtins-preinstall.c:66
#: app/flatpak-builtins-uninstall.c:64 app/flatpak-builtins-update.c:69
msgid "Produce minimal output and don't ask questions"
msgstr "Produkovat minimální výstup a neptat se na otázky"

#: app/flatpak-builtins-install.c:86
msgid "Update install if already installed"
msgstr "Aktualizovat instalaci, pokud je již nainstalováno"

#. Translators: A sideload is when you install from a local USB drive rather than the Internet.
#: app/flatpak-builtins-install.c:88 app/flatpak-builtins-preinstall.c:68
#: app/flatpak-builtins-update.c:71
msgid "Use this local repo for sideloads"
msgstr "Použít tento místní repozitář pro sideloady"

#: app/flatpak-builtins-install.c:178
msgid "Bundle filename must be specified"
msgstr "Název souboru balíku musí byt určen"

#: app/flatpak-builtins-install.c:188
msgid "Remote bundles are not supported"
msgstr "Vzdálené balíky nejsou podporovány"

#: app/flatpak-builtins-install.c:231
msgid "Filename or uri must be specified"
msgstr "Název souboru nebo uri musí být určen"

#: app/flatpak-builtins-install.c:295
msgid "Image location must be specified"
msgstr ""

#: app/flatpak-builtins-install.c:345
msgid "[LOCATION/REMOTE] [REF…] - Install applications or runtimes"
msgstr "[UMÍSTĚNÍ/VZDÁLENÉ] [REF…] - Instalovat aplikace nebo prostředí"

#: app/flatpak-builtins-install.c:378
msgid "At least one REF must be specified"
msgstr "Alespoň jeden REF musí být určen"

#: app/flatpak-builtins-install.c:392
#, c-format
msgid "Looking for matches…\n"
msgstr "Vyhledávají se shody…\n"

#: app/flatpak-builtins-install.c:513
#, c-format
msgid "No remote refs found for ‘%s’"
msgstr "Nenalezeny žádné vzdálené refy pro „%s“"

#: app/flatpak-builtins-install.c:573 app/flatpak-builtins-uninstall.c:405
#: common/flatpak-ref-utils.c:689 common/flatpak-ref-utils.c:1595
#, c-format
msgid "Invalid branch %s: %s"
msgstr "Neplatná větev %s: %s"

#: app/flatpak-builtins-install.c:606
#, c-format
msgid "Nothing matches %s in local repository for remote %s"
msgstr "Nic nevyhovuje názvu %s v místním repozitáři pro vzdálený repozitář %s"

#: app/flatpak-builtins-install.c:608
#, c-format
msgid "Nothing matches %s in remote %s"
msgstr "Nic nevyhovuje názvu %s ve vzdáleném repozitáři %s"

#: app/flatpak-builtins-install.c:629
#, c-format
msgid "Skipping: %s\n"
msgstr "Přeskakuje se: %s\n"

#: app/flatpak-builtins-kill.c:110
#, c-format
msgid "%s is not running"
msgstr "%s neběží"

#: app/flatpak-builtins-kill.c:136
msgid "INSTANCE - Stop a running application"
msgstr "INSTANCE - Zastavit běžící aplikaci"

#: app/flatpak-builtins-kill.c:144 app/flatpak-builtins-ps.c:256
msgid "Extra arguments given"
msgstr "Zadány parametry navíc"

#: app/flatpak-builtins-kill.c:150
msgid "Must specify the app to kill"
msgstr "Musíte určit aplikaci k zabití"

#: app/flatpak-builtins-list.c:47
msgid "Show extra information"
msgstr "Zobrazit dodatečné informace"

#: app/flatpak-builtins-list.c:48
msgid "List installed runtimes"
msgstr "Vypsat seznam nainstalovaných prostředí"

#: app/flatpak-builtins-list.c:49
msgid "List installed applications"
msgstr "Vypsat seznam nainstalovaných aplikací"

#: app/flatpak-builtins-list.c:50
msgid "Arch to show"
msgstr "Architektura, která se má zobrazit"

#: app/flatpak-builtins-list.c:51 app/flatpak-builtins-remote-ls.c:57
msgid "List all refs (including locale/debug)"
msgstr "Zobrazit všechny refy (včetně locale/debug)"

#: app/flatpak-builtins-list.c:53 app/flatpak-builtins-remote-ls.c:58
msgid "List all applications using RUNTIME"
msgstr "Vypsat všechny aplikace používající PROSTŘEDÍ"

#: app/flatpak-builtins-list.c:59 app/flatpak-builtins-remote-list.c:51
#: app/flatpak-builtins-remote-ls.c:68 app/flatpak-builtins-search.c:44
msgid "Name"
msgstr "Název"

#: app/flatpak-builtins-list.c:59 app/flatpak-builtins-remote-list.c:51
#: app/flatpak-builtins-remote-ls.c:68 app/flatpak-builtins-search.c:44
msgid "Show the name"
msgstr "Zobrazit název"

#: app/flatpak-builtins-list.c:60 app/flatpak-builtins-remote-list.c:60
#: app/flatpak-builtins-remote-ls.c:69 app/flatpak-builtins-search.c:45
msgid "Description"
msgstr "Popis"

#: app/flatpak-builtins-list.c:60 app/flatpak-builtins-remote-ls.c:69
#: app/flatpak-builtins-search.c:45
msgid "Show the description"
msgstr "Zobrazit popis"

#: app/flatpak-builtins-list.c:61 app/flatpak-builtins-remote-ls.c:70
#: app/flatpak-builtins-search.c:46
msgid "Application ID"
msgstr "ID aplikace"

#: app/flatpak-builtins-list.c:61 app/flatpak-builtins-ps.c:52
#: app/flatpak-builtins-remote-ls.c:70 app/flatpak-builtins-search.c:46
msgid "Show the application ID"
msgstr "Zobrazit ID aplikace"

#: app/flatpak-builtins-list.c:62 app/flatpak-builtins-remote-ls.c:71
#: app/flatpak-builtins-search.c:47
msgid "Show the version"
msgstr "Zobrazit verzi"

#: app/flatpak-builtins-list.c:65 app/flatpak-builtins-ps.c:56
#: app/flatpak-builtins-remote-ls.c:77
msgid "Runtime"
msgstr "Prostředí"

#: app/flatpak-builtins-list.c:65
msgid "Show the used runtime"
msgstr "Zobrazit použité prostředí"

#: app/flatpak-builtins-list.c:66 app/flatpak-builtins-remote-ls.c:74
msgid "Show the origin remote"
msgstr "Zobrazit prostředí původu"

#: app/flatpak-builtins-list.c:67
msgid "Show the installation"
msgstr "Zobrazit instalaci"

#: app/flatpak-builtins-list.c:69
msgid "Active commit"
msgstr "Aktivní commit"

#: app/flatpak-builtins-list.c:69 app/flatpak-builtins-remote-ls.c:76
msgid "Show the active commit"
msgstr "Zobrazit aktivní commit"

#: app/flatpak-builtins-list.c:70
msgid "Latest commit"
msgstr "Poslední commit"

#: app/flatpak-builtins-list.c:70
msgid "Show the latest commit"
msgstr "Zobrazit nejnovější commit"

#: app/flatpak-builtins-list.c:71 app/flatpak-builtins-remote-ls.c:78
msgid "Installed size"
msgstr "Instalovaná velikost"

#: app/flatpak-builtins-list.c:71 app/flatpak-builtins-remote-ls.c:78
msgid "Show the installed size"
msgstr "Zobrazit instalovanou velikost"

#: app/flatpak-builtins-list.c:72 app/flatpak-builtins-remote-list.c:58
#: app/flatpak-builtins-remote-ls.c:80 app/flatpak-builtins-repo.c:340
msgid "Options"
msgstr "Možnosti"

#: app/flatpak-builtins-list.c:72 app/flatpak-builtins-remote-list.c:58
#: app/flatpak-builtins-remote-ls.c:80
msgid "Show options"
msgstr "Zobrazit volby"

#: app/flatpak-builtins-list.c:180
#, c-format
msgid "Unable to load details of %s: %s"
msgstr "Selhalo načtení podrobností o %s: %s"

#: app/flatpak-builtins-list.c:190
#, c-format
msgid "Unable to inspect current version of %s: %s"
msgstr "Selhala kontrola aktuální verze %s: %s"

#: app/flatpak-builtins-list.c:408
msgid " - List installed apps and/or runtimes"
msgstr " - Vypsat nainstalované aplikace a/nebo prostředí"

#: app/flatpak-builtins-make-current.c:38
msgid "Arch to make current for"
msgstr ""

#: app/flatpak-builtins-make-current.c:58
msgid "APP BRANCH - Make branch of application current"
msgstr ""

#: app/flatpak-builtins-make-current.c:69 app/flatpak-builtins-run.c:260
msgid "APP must be specified"
msgstr "APLIKACE musí být určena"

#: app/flatpak-builtins-make-current.c:84
msgid "BRANCH must be specified"
msgstr "VĚTEV musí být určena"

#: app/flatpak-builtins-make-current.c:97
#, c-format
msgid "App %s branch %s is not installed"
msgstr "Aplikace %s větev %s není nainstalována"

#: app/flatpak-builtins-mask.c:42
msgid "Remove matching masks"
msgstr "Odstranit odpovídající masky"

#: app/flatpak-builtins-mask.c:54
msgid ""
"[PATTERN…] - disable updates and automatic installation matching patterns"
msgstr ""
"[VZOR…] - zakázat aktualizace a automatickou instalaci podle odpovídajících "
"vzorů"

#: app/flatpak-builtins-mask.c:73
#, c-format
msgid "No masked patterns\n"
msgstr "Žádné maskované vzory\n"

#: app/flatpak-builtins-mask.c:78
#, c-format
msgid "Masked patterns:\n"
msgstr "Maskované vzory:\n"

#: app/flatpak-builtins-override.c:42
msgid "Remove existing overrides"
msgstr "Odstranit existující přepsání"

#: app/flatpak-builtins-override.c:43
msgid "Show existing overrides"
msgstr "Zobrazit existující přepsání"

#: app/flatpak-builtins-override.c:59
msgid "[APP] - Override settings [for application]"
msgstr "[APLIKACE] - Přepsat nastavení [pro aplikaci]"

#: app/flatpak-builtins-permission-list.c:143
msgid "[TABLE] [ID] - List permissions"
msgstr "[TABULKA] [ID] - Zobrazit oprávnění"

#: app/flatpak-builtins-permission-list.c:179
#: app/flatpak-builtins-permission-show.c:142
msgid "Table"
msgstr "Tabulka"

#: app/flatpak-builtins-permission-list.c:180
#: app/flatpak-builtins-permission-show.c:143
msgid "Object"
msgstr "Objekt"

#: app/flatpak-builtins-permission-list.c:181
#: app/flatpak-builtins-permission-show.c:144
msgid "App"
msgstr "Aplikace"

#: app/flatpak-builtins-permission-list.c:183
#: app/flatpak-builtins-permission-show.c:146
msgid "Data"
msgstr "Data"

#: app/flatpak-builtins-permission-remove.c:120
msgid "TABLE ID [APP_ID] - Remove item from permission store"
msgstr "TABULKA ID [APP_ID] - Odstranit položku z úložiště oprávnění"

#: app/flatpak-builtins-permission-remove.c:129
#: app/flatpak-builtins-permission-set.c:120
msgid "Too few arguments"
msgstr "Příliš málo parametrů"

#: app/flatpak-builtins-permission-reset.c:43
msgid "Reset all permissions"
msgstr "Resetovat všechna oprávnění"

#: app/flatpak-builtins-permission-reset.c:144
msgid "APP_ID - Reset permissions for an app"
msgstr "APP_ID - Resetovat oprávnění pro aplikaci"

#: app/flatpak-builtins-permission-reset.c:153
#: app/flatpak-builtins-permission-show.c:124
msgid "Wrong number of arguments"
msgstr "Špatný počet parametrů"

#: app/flatpak-builtins-permission-set.c:42
msgid "Associate DATA with the entry"
msgstr "Asociovat DATA s položkou"

#: app/flatpak-builtins-permission-set.c:42
msgid "DATA"
msgstr "DATA"

#: app/flatpak-builtins-permission-set.c:111
msgid "TABLE ID APP_ID [PERMISSION...] - Set permissions"
msgstr "TABULKA ID APP_ID [OPRÁVNĚNÍ...] - Nastavit oprávnění"

#: app/flatpak-builtins-permission-set.c:132
#, c-format
msgid "Failed to parse '%s' as GVariant: "
msgstr "Nelze zpracovat „%s“ jako GVariant: "

#: app/flatpak-builtins-permission-show.c:115
msgid "APP_ID - Show permissions for an app"
msgstr "APP_ID - Zobrazit oprávnění pro aplikaci"

#: app/flatpak-builtins-pin.c:44
msgid "Remove matching pins"
msgstr "Odstranit odpovídající připnutí"

#: app/flatpak-builtins-pin.c:56
msgid "[PATTERN…] - disable automatic removal of runtimes matching patterns"
msgstr ""
"[VZOR…] - zakázat automatické odstranění prostředí podle odpovídajících vzorů"

#: app/flatpak-builtins-pin.c:75
#, c-format
msgid "No pinned patterns\n"
msgstr "Žádné připnuté vzory\n"

#: app/flatpak-builtins-pin.c:80
#, c-format
msgid "Pinned patterns:\n"
msgstr "Připnuté vzory:\n"

#: app/flatpak-builtins-preinstall.c:80
msgid "- Install flatpaks that are part of the operating system"
msgstr "- Nainstalovat flatpaky, které jsou součástí operačního systému"

#: app/flatpak-builtins-preinstall.c:118
#, c-format
msgid "Nothing to do.\n"
msgstr "Není co dělat.\n"

#: app/flatpak-builtins-ps.c:49
msgid "Instance"
msgstr "Instance"

#: app/flatpak-builtins-ps.c:49
msgid "Show the instance ID"
msgstr "Zobrazit ID instance"

#: app/flatpak-builtins-ps.c:50 app/flatpak-builtins-run.c:178
msgid "PID"
msgstr "PID"

#: app/flatpak-builtins-ps.c:50
msgid "Show the PID of the wrapper process"
msgstr "Zobrazit PID wrapper procesu"

#: app/flatpak-builtins-ps.c:51
msgid "Child-PID"
msgstr "Potomek-PID"

#: app/flatpak-builtins-ps.c:51
msgid "Show the PID of the sandbox process"
msgstr "Zobrazit PID sandbox procesu"

#: app/flatpak-builtins-ps.c:54 app/flatpak-builtins-search.c:48
msgid "Show the application branch"
msgstr "Zobrazit větev aplikace"

#: app/flatpak-builtins-ps.c:55
msgid "Show the application commit"
msgstr "Zobrazit commit aplikace"

#: app/flatpak-builtins-ps.c:56
msgid "Show the runtime ID"
msgstr "Zobrazit ID prostředí"

#: app/flatpak-builtins-ps.c:57
msgid "R.-Branch"
msgstr "R.-Větev"

#: app/flatpak-builtins-ps.c:57
msgid "Show the runtime branch"
msgstr "Zobrazit větev prostředí"

#: app/flatpak-builtins-ps.c:58
msgid "R.-Commit"
msgstr "R.-Commit"

#: app/flatpak-builtins-ps.c:58
msgid "Show the runtime commit"
msgstr "Zobrazit commit prostředí"

#: app/flatpak-builtins-ps.c:59
msgid "Active"
msgstr "Aktivní"

#: app/flatpak-builtins-ps.c:59
msgid "Show whether the app is active"
msgstr "Zobrazit, když je aplikace aktivní"

#: app/flatpak-builtins-ps.c:60
msgid "Background"
msgstr "Pozadí"

#: app/flatpak-builtins-ps.c:60
msgid "Show whether the app is background"
msgstr "Zobrazit, když běží aplikace na pozadí"

#: app/flatpak-builtins-ps.c:246
msgid " - Enumerate running sandboxes"
msgstr " - Vypsat spuštěné sandboxy"

#: app/flatpak-builtins-remote-add.c:66
msgid "Do nothing if the provided remote exists"
msgstr "Nedělat nic, pokud poskytnutý vzdálený repozitář již existuje"

#: app/flatpak-builtins-remote-add.c:67
msgid "LOCATION specifies a configuration file, not the repo location"
msgstr "UMÍSTĚNÍ určuje konfigurační soubor, ne cestu k repozitáři"

#: app/flatpak-builtins-remote-add.c:72 app/flatpak-builtins-remote-modify.c:78
msgid "Disable GPG verification"
msgstr "Zakázat ověřování pomocí GPG"

#: app/flatpak-builtins-remote-add.c:73 app/flatpak-builtins-remote-modify.c:79
msgid "Mark the remote as don't enumerate"
msgstr "Označit vzdálený repozitář jako nepoužit pro enumeraci"

#: app/flatpak-builtins-remote-add.c:74 app/flatpak-builtins-remote-modify.c:80
msgid "Mark the remote as don't use for deps"
msgstr "Označit vzdálený repozitář jako nepoužit pro závislosti"

#: app/flatpak-builtins-remote-add.c:75 app/flatpak-builtins-remote-modify.c:81
msgid "Set priority (default 1, higher is more prioritized)"
msgstr ""
"Nastavit prioritu (výchozí hodnota je 1, vyšší hodnota znamená větší "
"prioritu)"

#: app/flatpak-builtins-remote-add.c:75 app/flatpak-builtins-remote-modify.c:81
msgid "PRIORITY"
msgstr "PRIORITA"

#: app/flatpak-builtins-remote-add.c:76
msgid "The named subset to use for this remote"
msgstr ""
"Pojmenovaná podmnožina, která bude použita pro tento vzdálený repozitář"

#: app/flatpak-builtins-remote-add.c:76 app/flatpak-builtins-remote-modify.c:71
msgid "SUBSET"
msgstr "PODMNOŽINA"

#: app/flatpak-builtins-remote-add.c:77 app/flatpak-builtins-remote-modify.c:82
msgid "A nice name to use for this remote"
msgstr "Hezký název, který bude použit pro tento vzdálený repozitář"

#: app/flatpak-builtins-remote-add.c:78 app/flatpak-builtins-remote-modify.c:83
msgid "A one-line comment for this remote"
msgstr "Jednořádkový komentář pro tento vzdálený repozitář"

#: app/flatpak-builtins-remote-add.c:79 app/flatpak-builtins-remote-modify.c:84
msgid "A full-paragraph description for this remote"
msgstr "Popis v celém odstavci pro tento vzdálený repozitář"

#: app/flatpak-builtins-remote-add.c:80 app/flatpak-builtins-remote-modify.c:85
msgid "URL for a website for this remote"
msgstr "URL pro webovou stránku pro tento vzdálený repozitář"

#: app/flatpak-builtins-remote-add.c:81 app/flatpak-builtins-remote-modify.c:86
msgid "URL for an icon for this remote"
msgstr "URL pro ikonu pro tento vzdálený repozitář"

#: app/flatpak-builtins-remote-add.c:82 app/flatpak-builtins-remote-modify.c:87
msgid "Default branch to use for this remote"
msgstr "Výchozí větev pro použití s tímto vzdáleným repozitářem"

#: app/flatpak-builtins-remote-add.c:84 app/flatpak-builtins-remote-modify.c:89
msgid "Import GPG key from FILE (- for stdin)"
msgstr "Importovat klíč GPG ze SOUBORU (- pro standardní vstup)"

#: app/flatpak-builtins-remote-add.c:85 app/flatpak-builtins-remote-modify.c:90
msgid "Load signatures from URL"
msgstr ""

#: app/flatpak-builtins-remote-add.c:86 app/flatpak-builtins-remote-modify.c:92
msgid "Set path to local filter FILE"
msgstr "Nastavit cestu pro místní SOUBOR filtru"

#: app/flatpak-builtins-remote-add.c:87 app/flatpak-builtins-remote-modify.c:93
msgid "Disable the remote"
msgstr "Zakázat vzdálený repozitář"

#: app/flatpak-builtins-remote-add.c:88 app/flatpak-builtins-remote-modify.c:94
msgid "Name of authenticator"
msgstr "Název autentikátoru"

#: app/flatpak-builtins-remote-add.c:90 app/flatpak-builtins-remote-modify.c:96
msgid "Autoinstall authenticator"
msgstr "Automaticky instalovat autentikátor"

#: app/flatpak-builtins-remote-add.c:91 app/flatpak-builtins-remote-modify.c:97
msgid "Don't autoinstall authenticator"
msgstr "Neinstalovat automaticky autentikátor"

#: app/flatpak-builtins-remote-add.c:92 app/flatpak-builtins-remote-modify.c:99
msgid "Don't follow the redirect set in the summary file"
msgstr ""

#: app/flatpak-builtins-remote-add.c:261 app/flatpak-builtins-remote-add.c:268
#, c-format
msgid "Can't load uri %s: %s\n"
msgstr "Nelze načíst uri %s: %s\n"

#: app/flatpak-builtins-remote-add.c:276 common/flatpak-dir.c:4643
#, c-format
msgid "Can't load file %s: %s\n"
msgstr "Nelze načíst soubor %s: %s\n"

#: app/flatpak-builtins-remote-add.c:304
msgid "NAME LOCATION - Add a remote repository"
msgstr "NÁZEV UMÍSTĚNÍ - Přidat vzdálený repozitář"

#: app/flatpak-builtins-remote-add.c:331
msgid "GPG verification is required if collections are enabled"
msgstr "Ověřování pomocí GPG je vyžadováno, pokud jsou povoleny kolekce"

#: app/flatpak-builtins-remote-add.c:393
#, c-format
msgid "Remote %s already exists"
msgstr "Vzdálený repozitář %s již existuje"

#: app/flatpak-builtins-remote-add.c:405
#: app/flatpak-builtins-remote-modify.c:340
#, c-format
msgid "Invalid authenticator name %s"
msgstr "Neplatný název autentikátoru %s"

#: app/flatpak-builtins-remote-add.c:422
#, c-format
msgid "Warning: Could not update extra metadata for '%s': %s\n"
msgstr "Varování: Nepodařilo se aktualizovat dodatečná metadata pro „%s“: %s\n"

#: app/flatpak-builtins-remote-delete.c:39
msgid "Remove remote even if in use"
msgstr "Odstranit vzdálený repozitář i pokud se používá"

#: app/flatpak-builtins-remote-delete.c:53
msgid "NAME - Delete a remote repository"
msgstr "NÁZEV - Odstranit vzdálený repozitář"

#: app/flatpak-builtins-remote-delete.c:100
#, c-format
msgid "The following refs are installed from remote '%s':"
msgstr "Následující refy jsou nainstalovány ze vzdáleného repozitáře „%s“:"

#: app/flatpak-builtins-remote-delete.c:101
msgid "Remove them?"
msgstr "Odstranit je?"

#: app/flatpak-builtins-remote-delete.c:103
#, c-format
msgid "Can't remove remote '%s' with installed refs"
msgstr "Nelze odstranit vzdálený repozitář „%s“ s instalovanými refy"

#: app/flatpak-builtins-remote-info.c:55
msgid "Commit to show info for"
msgstr "Commit, pro který zobrazit informace"

#: app/flatpak-builtins-remote-info.c:58
msgid "Display log"
msgstr "Zobrazit záznam"

#: app/flatpak-builtins-remote-info.c:61
msgid "Show parent"
msgstr "Zobrazit rodiče"

#: app/flatpak-builtins-remote-info.c:65 app/flatpak-builtins-remote-ls.c:60
msgid "Use local caches even if they are stale"
msgstr "Použít místní cache i pokud jsou zastaralé"

#. Translators: A sideload is when you install from a local USB drive rather than the Internet.
#: app/flatpak-builtins-remote-info.c:67 app/flatpak-builtins-remote-ls.c:62
msgid "Only list refs available as sideloads"
msgstr "Vypsat pouze refy dostupné jako sideloady"

#: app/flatpak-builtins-remote-info.c:114
msgid ""
" REMOTE REF - Show information about an application or runtime in a remote"
msgstr ""
" VZDÁLENÉ REF - Zobrazit informace o aplikaci nebo prostředí ve vzdáleném "
"repozitáři"

#: app/flatpak-builtins-remote-info.c:125
msgid "REMOTE and REF must be specified"
msgstr "VZDÁLENÉ a REF musí být určeny"

#: app/flatpak-builtins-remote-info.c:247
#: app/flatpak-builtins-remote-info.c:282
#, fuzzy
msgid "Download Size:"
msgstr "Stahovaná velikost:"

#: app/flatpak-builtins-remote-info.c:267
#: app/flatpak-builtins-remote-info.c:325
msgid "History:"
msgstr "Historie:"

#: app/flatpak-builtins-remote-info.c:348
msgid " Commit:"
msgstr " Commit:"

#: app/flatpak-builtins-remote-info.c:349
msgid " Subject:"
msgstr " Předmět:"

#: app/flatpak-builtins-remote-info.c:350
msgid " Date:"
msgstr " Datum:"

#: app/flatpak-builtins-remote-info.c:383
#, c-format
msgid "Warning: Commit %s has no flatpak metadata\n"
msgstr "Varování: Commit %s nemá žádná flatpak metadata\n"

#: app/flatpak-builtins-remote-list.c:43
msgid "Show remote details"
msgstr "Zobrazit detaily vzdáleného repozitáře"

#: app/flatpak-builtins-remote-list.c:44
msgid "Show disabled remotes"
msgstr "Zobrazit zakázané vzdálené repozitáře"

#: app/flatpak-builtins-remote-list.c:52
msgid "Title"
msgstr "Jméno"

#: app/flatpak-builtins-remote-list.c:52
msgid "Show the title"
msgstr "Zobrazit jméno"

#: app/flatpak-builtins-remote-list.c:53
msgid "Show the URL"
msgstr "Zobrazit URL"

#: app/flatpak-builtins-remote-list.c:54
msgid "Show the collection ID"
msgstr "Zobrazit ID kolekce"

#: app/flatpak-builtins-remote-list.c:55 app/flatpak-builtins-repo.c:392
msgid "Subset"
msgstr "Podmnožina"

#: app/flatpak-builtins-remote-list.c:55
msgid "Show the subset"
msgstr "Zobrazit podmnožinu"

#: app/flatpak-builtins-remote-list.c:56
msgid "Filter"
msgstr "Filtr"

#: app/flatpak-builtins-remote-list.c:56
msgid "Show filter file"
msgstr "Zobrazit soubor filtru"

#: app/flatpak-builtins-remote-list.c:57
msgid "Priority"
msgstr "Priorita"

#: app/flatpak-builtins-remote-list.c:57
msgid "Show the priority"
msgstr "Zobrazit prioritu"

#: app/flatpak-builtins-remote-list.c:59
msgid "Comment"
msgstr "Komentář"

#: app/flatpak-builtins-remote-list.c:59
msgid "Show comment"
msgstr "Zobrazit komentář"

#: app/flatpak-builtins-remote-list.c:60
msgid "Show description"
msgstr "Zobrazit popis"

#: app/flatpak-builtins-remote-list.c:61
msgid "Homepage"
msgstr "Domovská stránka"

#: app/flatpak-builtins-remote-list.c:61
msgid "Show homepage"
msgstr "Zobrazit domovskou stránku"

#: app/flatpak-builtins-remote-list.c:62
msgid "Icon"
msgstr "Ikona"

#: app/flatpak-builtins-remote-list.c:62
msgid "Show icon"
msgstr "Zobrazit ikonu"

#: app/flatpak-builtins-remote-list.c:231
msgid " - List remote repositories"
msgstr " - Vypsat vzdálené repozitáře"

#: app/flatpak-builtins-remote-ls.c:52
msgid "Show arches and branches"
msgstr "Zobrazit architektury a větve"

#: app/flatpak-builtins-remote-ls.c:53
msgid "Show only runtimes"
msgstr "Zobrazit pouze prostředí"

#: app/flatpak-builtins-remote-ls.c:54
msgid "Show only apps"
msgstr "Zobrazit pouze aplikace"

#: app/flatpak-builtins-remote-ls.c:55
msgid "Show only those where updates are available"
msgstr "Zobrazit pouze ty, pro které jsou k dispozici aktualizace"

#: app/flatpak-builtins-remote-ls.c:56
msgid "Limit to this arch (* for all)"
msgstr "Omezit na tuto architekturu (* pro všechny)"

#: app/flatpak-builtins-remote-ls.c:77
msgid "Show the runtime"
msgstr "Zobrazit prostředí"

#: app/flatpak-builtins-remote-ls.c:79
msgid "Download size"
msgstr "Stahovaná velikost"

#: app/flatpak-builtins-remote-ls.c:79
msgid "Show the download size"
msgstr "Zobrazit stahovanou velikost"

#: app/flatpak-builtins-remote-ls.c:391
msgid " [REMOTE or URI] - Show available runtimes and applications"
msgstr " [VZDÁLENÉ nebo URI] - Zobrazit dostupná prostředí a aplikace"

#: app/flatpak-builtins-remote-modify.c:67
msgid "Enable GPG verification"
msgstr "Povolit ověřování pomocí GPG"

#: app/flatpak-builtins-remote-modify.c:68
msgid "Mark the remote as enumerate"
msgstr "Označit vzdálený repozitář jako použit pro enumeraci"

#: app/flatpak-builtins-remote-modify.c:69
msgid "Mark the remote as used for dependencies"
msgstr "Označit vzdálený repozitář jako použit pro závislosti"

#: app/flatpak-builtins-remote-modify.c:70
#, fuzzy
msgid "Set a new URL"
msgstr "Nastavit novou url"

#: app/flatpak-builtins-remote-modify.c:71
msgid "Set a new subset to use"
msgstr "Nastavit novou podmnožinu k použití"

#: app/flatpak-builtins-remote-modify.c:72
msgid "Enable the remote"
msgstr "Povolit vzdálený repozitář"

#: app/flatpak-builtins-remote-modify.c:73
msgid "Update extra metadata from the summary file"
msgstr "Aktualizovat dodatečná metadata ze souboru shrnutí"

#: app/flatpak-builtins-remote-modify.c:91
msgid "Disable local filter"
msgstr "Zakázat místní filtr"

#: app/flatpak-builtins-remote-modify.c:95
msgid "Authenticator options"
msgstr "Volby autentikátoru"

#: app/flatpak-builtins-remote-modify.c:98
msgid "Follow the redirect set in the summary file"
msgstr ""

#: app/flatpak-builtins-remote-modify.c:306
msgid "NAME - Modify a remote repository"
msgstr "NÁZEV - Upravit vzdálený repozitář"

#: app/flatpak-builtins-remote-modify.c:316
msgid "Remote NAME must be specified"
msgstr "NÁZEV vzdáleného repozitáře musí být určen"

#: app/flatpak-builtins-remote-modify.c:327
#, c-format
msgid "Updating extra metadata from remote summary for %s\n"
msgstr "Aktualizují se dodatečná metadata ze vzdáleného shrnutí pro %s\n"

#: app/flatpak-builtins-remote-modify.c:330
#, c-format
msgid "Error updating extra metadata for '%s': %s\n"
msgstr "Chyba během aktualizace dodatečných metadat pro „%s“: %s\n"

#: app/flatpak-builtins-remote-modify.c:331
#, c-format
msgid "Could not update extra metadata for %s"
msgstr "Nepodařilo se aktualizovat dodatečná metadata pro %s"

#: app/flatpak-builtins-repair.c:43
msgid "Don't make any changes"
msgstr "Nedělat žádné změny"

#: app/flatpak-builtins-repair.c:44
msgid "Reinstall all refs"
msgstr "Reinstalovat všechny refy"

#: app/flatpak-builtins-repair.c:68
#, c-format
msgid "Object missing: %s.%s\n"
msgstr "Objekt chybí: %s.%s\n"

#: app/flatpak-builtins-repair.c:76
#, c-format
msgid "Object invalid: %s.%s\n"
msgstr "Neplatný objekt: %s.%s\n"

#: app/flatpak-builtins-repair.c:81
#, c-format
msgid "%s, deleting object\n"
msgstr "%s, maže se objekt\n"

#: app/flatpak-builtins-repair.c:146
#, c-format
msgid "Can't load object %s: %s\n"
msgstr "Nelze načíst objekt %s: %s\n"

#: app/flatpak-builtins-repair.c:228
#, c-format
msgid "Commit invalid %s: %s\n"
msgstr "Neplatný commit %s: %s\n"

#: app/flatpak-builtins-repair.c:231
#, c-format
msgid "Deleting invalid commit %s: %s\n"
msgstr "Maže se neplatný commit %s: %s\n"

#: app/flatpak-builtins-repair.c:261
#, c-format
msgid "Commit should be marked partial: %s\n"
msgstr "Commit by měl být označen jako částečný: %s\n"

#: app/flatpak-builtins-repair.c:264
#, c-format
msgid "Marking commit as partial: %s\n"
msgstr "Commit se označuje jako částečný: %s\n"

#: app/flatpak-builtins-repair.c:293
#, c-format
msgid "Problems loading data for %s: %s\n"
msgstr "Problémy při načítání dat pro %s: %s\n"

#: app/flatpak-builtins-repair.c:306
#, c-format
msgid "Error reinstalling %s: %s\n"
msgstr "Chyba při reinstalování %s: %s\n"

#: app/flatpak-builtins-repair.c:327
msgid "- Repair a flatpak installation"
msgstr "- Opravit flatpak instalaci"

#: app/flatpak-builtins-repair.c:406
#, c-format
msgid "Removing non-deployed ref %s…\n"
msgstr ""

#: app/flatpak-builtins-repair.c:411
#, c-format
msgid "Skipping non-deployed ref %s…\n"
msgstr ""

#: app/flatpak-builtins-repair.c:429
#, c-format
msgid "[%d/%d] Verifying %s…\n"
msgstr "[%d/%d] Ověřuje se %s…\n"

#: app/flatpak-builtins-repair.c:435
#, c-format
msgid "Dry run: "
msgstr "Chod naprázdno: "

#: app/flatpak-builtins-repair.c:440
#, c-format
msgid "Deleting ref %s due to missing objects\n"
msgstr "Maže se ref %s z důvodu chybějících objektů\n"

#: app/flatpak-builtins-repair.c:444
#, c-format
msgid "Deleting ref %s due to invalid objects\n"
msgstr "Maže se ref %s z důvodu neplatných objektů\n"

#: app/flatpak-builtins-repair.c:448
#, c-format
msgid "Deleting ref %s due to %d\n"
msgstr "Maže se ref %s z důvodu %d\n"

#: app/flatpak-builtins-repair.c:464
#, c-format
msgid "Checking remotes...\n"
msgstr "Kontrolují se vzdálené repozitáře...\n"

#: app/flatpak-builtins-repair.c:482
#, c-format
msgid "Remote %s for ref %s is missing\n"
msgstr "Vzdálený repozitář %s pro ref %s chybí\n"

#: app/flatpak-builtins-repair.c:484
#, c-format
msgid "Remote %s for ref %s is disabled\n"
msgstr "Vzdálený repozitář %s pro ref %s je zakázán\n"

#: app/flatpak-builtins-repair.c:490
#, c-format
msgid "Pruning objects\n"
msgstr ""

#: app/flatpak-builtins-repair.c:498
#, c-format
msgid "Erasing .removed\n"
msgstr "Odstraňuje se .removed\n"

#: app/flatpak-builtins-repair.c:524
#, c-format
msgid "Reinstalling refs\n"
msgstr "Reinstalují se refy\n"

#: app/flatpak-builtins-repair.c:526
#, c-format
msgid "Reinstalling removed refs\n"
msgstr "Reinstalují se odstraněné refy\n"

#: app/flatpak-builtins-repair.c:551
#, c-format
msgid "While removing appstream for %s: "
msgstr "Během odstraňování appstream pro %s: "

#: app/flatpak-builtins-repair.c:558
#, c-format
msgid "While deploying appstream for %s: "
msgstr "Během nasazování appstream pro %s: "

#: app/flatpak-builtins-repo.c:106
#, c-format
msgid "Repo mode: %s\n"
msgstr "Mód repozitáře: %s\n"

#: app/flatpak-builtins-repo.c:113
#, c-format
msgid "Indexed summaries: %s\n"
msgstr "Indexovaná shrnutí: %s\n"

#: app/flatpak-builtins-repo.c:113 app/flatpak-builtins-repo.c:139
#: app/flatpak-builtins-repo.c:172
msgid "true"
msgstr "pravda"

#: app/flatpak-builtins-repo.c:113 app/flatpak-builtins-repo.c:139
#: app/flatpak-builtins-repo.c:172
msgid "false"
msgstr "nepravda"

#: app/flatpak-builtins-repo.c:121
#, c-format
msgid "Subsummaries: "
msgstr "Podshrnutí: "

#: app/flatpak-builtins-repo.c:136
#, c-format
msgid "Cache version: %d\n"
msgstr "Verze cache: %d\n"

#: app/flatpak-builtins-repo.c:139
#, c-format
msgid "Indexed deltas: %s\n"
msgstr "Indexované delty: %s\n"

#: app/flatpak-builtins-repo.c:142
#, c-format
msgid "Title: %s\n"
msgstr "Jméno: %s\n"

#: app/flatpak-builtins-repo.c:145
#, c-format
msgid "Comment: %s\n"
msgstr "Komentář: %s\n"

#: app/flatpak-builtins-repo.c:148
#, c-format
msgid "Description: %s\n"
msgstr "Popis: %s\n"

#: app/flatpak-builtins-repo.c:151
#, c-format
msgid "Homepage: %s\n"
msgstr "Domovská stránka: %s\n"

#: app/flatpak-builtins-repo.c:154
#, c-format
msgid "Icon: %s\n"
msgstr "Ikona: %s\n"

#: app/flatpak-builtins-repo.c:157
#, c-format
msgid "Collection ID: %s\n"
msgstr "ID kolekce: %s\n"

#: app/flatpak-builtins-repo.c:160
#, c-format
msgid "Default branch: %s\n"
msgstr "Výchozí větev: %s\n"

#: app/flatpak-builtins-repo.c:163
#, c-format
msgid "Redirect URL: %s\n"
msgstr "URL přesměrování: %s\n"

#: app/flatpak-builtins-repo.c:166
#, c-format
msgid "Deploy collection ID: %s\n"
msgstr "ID kolekce nasazení: %s\n"

#: app/flatpak-builtins-repo.c:169
#, c-format
msgid "Authenticator name: %s\n"
msgstr "Název autentikátoru: %s\n"

#: app/flatpak-builtins-repo.c:172
#, c-format
msgid "Authenticator install: %s\n"
msgstr "Instalace autentikátoru: %s\n"

#: app/flatpak-builtins-repo.c:180
#, c-format
msgid "GPG key hash: %s\n"
msgstr "Hash klíče GPG: %s\n"

#: app/flatpak-builtins-repo.c:184
#, c-format
msgid "%zd summary branches\n"
msgstr "%zd větví shrnutí\n"

#: app/flatpak-builtins-repo.c:336
msgid "Installed"
msgstr "Instalováno"

#. Translators: Download is used here as a noun
#: app/flatpak-builtins-repo.c:338 app/flatpak-cli-transaction.c:1462
msgid "Download"
msgstr "Stažení"

#: app/flatpak-builtins-repo.c:339
msgid "Subsets"
msgstr "Podmnožiny"

#: app/flatpak-builtins-repo.c:393
msgid "Digest"
msgstr "Výběr"

#: app/flatpak-builtins-repo.c:394
msgid "History length"
msgstr "Délka historie"

#: app/flatpak-builtins-repo.c:711
msgid "Print general information about the repository"
msgstr "Vypsat obecné informace o repozitáři"

#: app/flatpak-builtins-repo.c:712
msgid "List the branches in the repository"
msgstr "Vypsat větve v repozitáři"

#: app/flatpak-builtins-repo.c:713
msgid "Print metadata for a branch"
msgstr "Vypsat metadata pro větev"

#: app/flatpak-builtins-repo.c:714
msgid "Show commits for a branch"
msgstr "Zobrazit commity pro větev"

#: app/flatpak-builtins-repo.c:715
msgid "Print information about the repo subsets"
msgstr "Vypsat informace o podmnožině repozitářů"

#: app/flatpak-builtins-repo.c:716
msgid "Limit information to subsets with this prefix"
msgstr "Omezit informace na podmnožiny s touto předponou"

#: app/flatpak-builtins-repo.c:732
msgid "LOCATION - Repository maintenance"
msgstr "UMÍSTĚNÍ - Údržba repozitáře"

#: app/flatpak-builtins-run.c:159
msgid "Command to run"
msgstr "Příkaz, který se má spustit"

#: app/flatpak-builtins-run.c:160
msgid "Directory to run the command in"
msgstr "Adresář, ve kterém se má příkaz spustit"

#: app/flatpak-builtins-run.c:161
msgid "Branch to use"
msgstr "Větev, která se má použít"

#: app/flatpak-builtins-run.c:162
msgid "Use development runtime"
msgstr "Použije vývojové prostředí"

#: app/flatpak-builtins-run.c:163
msgid "Runtime to use"
msgstr "Prostředí, které se má použít"

#: app/flatpak-builtins-run.c:164
msgid "Runtime version to use"
msgstr "Verze prostředí, které se má použít"

#: app/flatpak-builtins-run.c:167
msgid "Log accessibility bus calls"
msgstr "Zaznamenávat volání sběrnice zpřístupnění"

#: app/flatpak-builtins-run.c:168
msgid "Don't proxy accessibility bus calls"
msgstr "Nepoužívat proxy pro volání sběrnice zpřístupnění"

#: app/flatpak-builtins-run.c:169
msgid "Proxy accessibility bus calls (default except when sandboxed)"
msgstr ""
"Používat proxy pro volání sběrnice zpřístupnění (výchozí, s výjimkou běhu v "
"sandboxu)"

#: app/flatpak-builtins-run.c:170
msgid "Don't proxy session bus calls"
msgstr "Nepoužívat proxy pro volání sběrnice sezení"

#: app/flatpak-builtins-run.c:171
msgid "Proxy session bus calls (default except when sandboxed)"
msgstr ""
"Používat proxy pro volání sběrnice sezení (výchozí, s výjimkou běhu v "
"sandboxu)"

#: app/flatpak-builtins-run.c:172
msgid "Don't start portals"
msgstr "Nespouštět portály"

#: app/flatpak-builtins-run.c:173
msgid "Enable file forwarding"
msgstr "Povolit přesměrování souboru"

#: app/flatpak-builtins-run.c:174
msgid "Run specified commit"
msgstr "Spustit určený commit"

#: app/flatpak-builtins-run.c:175
msgid "Use specified runtime commit"
msgstr "Použít určený commit prostředí"

#: app/flatpak-builtins-run.c:176
msgid "Run completely sandboxed"
msgstr "Spustit kompletně v sandboxu"

#: app/flatpak-builtins-run.c:178
msgid "Use PID as parent pid for sharing namespaces"
msgstr ""

#: app/flatpak-builtins-run.c:179
msgid "Make processes visible in parent namespace"
msgstr ""

#: app/flatpak-builtins-run.c:180
msgid "Share process ID namespace with parent"
msgstr ""

#: app/flatpak-builtins-run.c:181
msgid "Write the instance ID to the given file descriptor"
msgstr ""

#: app/flatpak-builtins-run.c:182
msgid "Use PATH instead of the app's /app"
msgstr ""

#: app/flatpak-builtins-run.c:183
msgid "Use FD instead of the app's /app"
msgstr ""

#: app/flatpak-builtins-run.c:183 app/flatpak-builtins-run.c:185
#: app/flatpak-builtins-run.c:187 app/flatpak-builtins-run.c:188
#: common/flatpak-context.c:2672
msgid "FD"
msgstr "FD"

#: app/flatpak-builtins-run.c:184
msgid "Use PATH instead of the runtime's /usr"
msgstr ""

#: app/flatpak-builtins-run.c:185
msgid "Use FD instead of the runtime's /usr"
msgstr ""

#: app/flatpak-builtins-run.c:186
#, fuzzy
msgid "Clear all outside environment variables"
msgstr "Nastavit proměnnou prostředí"

#: app/flatpak-builtins-run.c:187
msgid ""
"Bind mount the file or directory referred to by FD to its canonicalized path"
msgstr ""

#: app/flatpak-builtins-run.c:188
msgid ""
"Bind mount the file or directory referred to by FD read-only to its "
"canonicalized path"
msgstr ""

#: app/flatpak-builtins-run.c:219
msgid "APP [ARGUMENT…] - Run an app"
msgstr "APLIKACE [ARGUMENT…] - Spustit aplikaci"

#: app/flatpak-builtins-run.c:370
#, c-format
msgid "runtime/%s/%s/%s not installed"
msgstr "prostředí/%s/%s/%s nenainstalováno"

#: app/flatpak-builtins-run.c:419
msgid "app-fd and app-path cannot both be used"
msgstr ""

#: app/flatpak-builtins-run.c:449
msgid "usr-fd and usr-path cannot both be used"
msgstr ""

#: app/flatpak-builtins-search.c:37
msgid "Arch to search for"
msgstr "Architektura, která se má hledat"

#: app/flatpak-builtins-search.c:49
msgid "Remotes"
msgstr "Vzdálené repozitáře"

#: app/flatpak-builtins-search.c:49
msgid "Show the remotes"
msgstr "Zobrazit vzdálené repozitáře"

#: app/flatpak-builtins-search.c:244
msgid "TEXT - Search remote apps/runtimes for text"
msgstr "TEXT - Vyhledat text ve vzdálených aplikacích/prostředích"

#: app/flatpak-builtins-search.c:255
msgid "TEXT must be specified"
msgstr "TEXT musí být určen"

#: app/flatpak-builtins-search.c:338
msgid "No matches found"
msgstr "Nenalezeny žádné shody"

#: app/flatpak-builtins-uninstall.c:54
msgid "Arch to uninstall"
msgstr "Architektura k odinstalování"

#: app/flatpak-builtins-uninstall.c:55
msgid "Keep ref in local repository"
msgstr "Nechat ref v místním repozitáři"

#: app/flatpak-builtins-uninstall.c:56
msgid "Don't uninstall related refs"
msgstr "Neodinstalovat související refy"

#: app/flatpak-builtins-uninstall.c:57
msgid "Remove files even if running"
msgstr "Odstranit soubory i za běhu"

#: app/flatpak-builtins-uninstall.c:60
msgid "Uninstall all"
msgstr "Odinstalovat vše"

#: app/flatpak-builtins-uninstall.c:61
msgid "Uninstall unused"
msgstr "Odinstalovat nepoužívané"

#: app/flatpak-builtins-uninstall.c:62
msgid "Delete app data"
msgstr "Odstranit data aplikace"

#: app/flatpak-builtins-uninstall.c:141
#, c-format
msgid "Delete data for %s?"
msgstr "Odstranit data pro %s?"

#: app/flatpak-builtins-uninstall.c:220
#, c-format
msgid "Info: applications using the extension %s%s%s branch %s%s%s:\n"
msgstr "Informace: aplikace používající rozšíření %s%s%s větev %s%s%s:\n"

#: app/flatpak-builtins-uninstall.c:223
#, c-format
msgid "Info: applications using the runtime %s%s%s branch %s%s%s:\n"
msgstr "Informace: aplikace používající prostředí %s%s%s větev %s%s%s:\n"

#: app/flatpak-builtins-uninstall.c:238
msgid "Really remove?"
msgstr "Opravdu odstranit?"

#: app/flatpak-builtins-uninstall.c:255
msgid "[REF…] - Uninstall applications or runtimes"
msgstr "[REF…] - Odinstalovat aplikace nebo prostředí"

#: app/flatpak-builtins-uninstall.c:264
msgid "Must specify at least one REF, --unused, --all or --delete-data"
msgstr "Musí být určen alespoň jeden REF, --unused, --all nebo --delete-data"

#: app/flatpak-builtins-uninstall.c:267
msgid "Must not specify REFs when using --all"
msgstr "REFy nesmí být určeny, pokud se používá --all"

#: app/flatpak-builtins-uninstall.c:270
msgid "Must not specify REFs when using --unused"
msgstr "REFy nesmí být určeny, pokud se používá --unused"

#: app/flatpak-builtins-uninstall.c:336
#, c-format
msgid ""
"\n"
"These runtimes in installation '%s' are pinned and won't be removed; see "
"flatpak-pin(1):\n"
msgstr ""
"\n"
"Tyto prostředí v instalaci „%s“ jsou připnuty a nebudou odstraněny; viz "
"flatpak-pin(1):\n"

#: app/flatpak-builtins-uninstall.c:370
#, c-format
msgid "Nothing unused to uninstall\n"
msgstr "Nic nepoužívaného k odinstalaci\n"

#: app/flatpak-builtins-uninstall.c:444
#, c-format
msgid "No installed refs found for ‘%s’"
msgstr "Nenalezeny žádné nainstalované refy pro „%s“"

#: app/flatpak-builtins-uninstall.c:447
#, c-format
msgid " with arch ‘%s’"
msgstr " s architekturou „%s“"

#: app/flatpak-builtins-uninstall.c:449
#, c-format
msgid " with branch ‘%s’"
msgstr " s větví „%s“"

#: app/flatpak-builtins-uninstall.c:456
#, c-format
msgid "Warning: %s is not installed\n"
msgstr "Varování: %s není nainstalováno\n"

#: app/flatpak-builtins-uninstall.c:490
#, c-format
msgid "None of the specified refs are installed"
msgstr "Žádný z uvedených refů není nainstalován"

#: app/flatpak-builtins-uninstall.c:599
#, c-format
msgid "No app data to delete\n"
msgstr "Žádná data aplikace k odstranění\n"

#: app/flatpak-builtins-update.c:56
msgid "Arch to update for"
msgstr "Architektura, pro kterou se má aktualizovat"

#: app/flatpak-builtins-update.c:57
msgid "Commit to deploy"
msgstr "Commit k nasazení"

#: app/flatpak-builtins-update.c:58
msgid "Remove old files even if running"
msgstr "Odstranit staré soubory i za běhu"

#: app/flatpak-builtins-update.c:59
msgid "Don't pull, only update from local cache"
msgstr "Nedělat pull, pouze aktualizovat z místní cache"

#: app/flatpak-builtins-update.c:61
msgid "Don't update related refs"
msgstr "Neaktualizovat související refy"

#: app/flatpak-builtins-update.c:66
msgid "Update appstream for remote"
msgstr "Aktualizovat appstream pro vzdálený repozitář"

#: app/flatpak-builtins-update.c:67
msgid "Only update this subpath"
msgstr "Aktualizovat pouze tuto podcestu"

#: app/flatpak-builtins-update.c:90
msgid "[REF…] - Update applications or runtimes"
msgstr "[REF…] - Aktualizovat aplikace nebo prostředí"

#: app/flatpak-builtins-update.c:121
msgid "With --commit, only one REF may be specified"
msgstr ""

#: app/flatpak-builtins-update.c:162
#, c-format
msgid "Looking for updates…\n"
msgstr "Vyhledávají se aktualizace…\n"

#: app/flatpak-builtins-update.c:215
#, c-format
msgid "Unable to update %s: %s\n"
msgstr "Nelze aktualizovat %s: %s\n"

#: app/flatpak-builtins-update.c:274
#, fuzzy, c-format
msgid "Nothing to update.\n"
msgstr "Není co dělat.\n"

#: app/flatpak-builtins-utils.c:337
#, fuzzy, c-format
msgid ""
"Remote ‘%s’ found in multiple installations, unable to proceed in non-"
"interactive mode"
msgstr "Ref „%s“ nalezen ve více instalacích: %s. Musíte určit jednu."

#: app/flatpak-builtins-utils.c:346
#, c-format
msgid "Remote ‘%s’ found in multiple installations:"
msgstr "Vzdálený repozitář „%s“ nalezen ve více instalacích:"

#: app/flatpak-builtins-utils.c:347 app/flatpak-builtins-utils.c:442
#: app/flatpak-builtins-utils.c:538 app/flatpak-builtins-utils.c:540
#: app/flatpak-builtins-utils.c:598
msgid "Which do you want to use (0 to abort)?"
msgstr "Který si přejete použít (0 pro zrušení)?"

#: app/flatpak-builtins-utils.c:349
#, c-format
msgid "No remote chosen to resolve ‘%s’ which exists in multiple installations"
msgstr ""
"Nebyl vybrán žádný vzdálený repozitář pro vyřešení „%s“, který existuje ve "
"více instalacích"

#: app/flatpak-builtins-utils.c:358
#, c-format
msgid ""
"Remote \"%s\" not found\n"
"Hint: Use flatpak remote-add to add a remote"
msgstr ""
"Vzdálený repozitář „%s“ nebyl nalezen\n"
"Tip: Pro přidání vzdáleného repozitáře použijte flatpak remote-add"

#: app/flatpak-builtins-utils.c:364
#, c-format
msgid "Remote \"%s\" not found in the %s installation"
msgstr "Vzdálený repozitář „%s“ nebyl nalezen v instalaci %s"

#: app/flatpak-builtins-utils.c:404
#, c-format
msgid "Multiple refs match ‘%s’, unable to proceed in non-interactive mode"
msgstr ""

#. default to yes on Enter
#: app/flatpak-builtins-utils.c:430
#, c-format
msgid ""
"Found ref ‘%s’ in remote ‘%s’ (%s).\n"
"Use this ref?"
msgstr ""
"Nalezen ref „%s“ ve vzdáleném repozitáři „%s“ (%s).\n"
"Použít tento ref?"

#: app/flatpak-builtins-utils.c:434 app/flatpak-builtins-utils.c:444
#: app/flatpak-builtins-utils.c:522 app/flatpak-builtins-utils.c:543
#, c-format
msgid "No ref chosen to resolve matches for ‘%s’"
msgstr "Nevybrán žádný ref pro vyřešení shod pro „%s“"

#: app/flatpak-builtins-utils.c:440
#, c-format
msgid "Similar refs found for ‘%s’ in remote ‘%s’ (%s):"
msgstr "Podobné refy pro „%s“ nalezeny ve vzdáleném repozitáři „%s“ (%s):"

#: app/flatpak-builtins-utils.c:488
#, c-format
msgid ""
"Multiple installed refs match ‘%s’, unable to proceed in non-interactive mode"
msgstr ""

#. default to yes on Enter
#: app/flatpak-builtins-utils.c:518
#, c-format
msgid "Found installed ref ‘%s’ (%s). Is this correct?"
msgstr "Nalezen nainstalovaný ref „%s“ (%s). Je to správně?"

#: app/flatpak-builtins-utils.c:534
#, c-format
msgid "All of the above"
msgstr "Všechny výše uvedené"

#: app/flatpak-builtins-utils.c:535
#, c-format
msgid "Similar installed refs found for ‘%s’:"
msgstr "Nalezeny podobné nainstalované refy pro „%s“:"

#: app/flatpak-builtins-utils.c:579
#, c-format
msgid ""
"Multiple remotes have refs matching ‘%s’, unable to proceed in non-"
"interactive mode"
msgstr ""

#: app/flatpak-builtins-utils.c:597
#, c-format
msgid "Remotes found with refs similar to ‘%s’:"
msgstr "Nalezeny vzdálené repozitáře s refy podobnými „%s“:"

#: app/flatpak-builtins-utils.c:600
#, c-format
msgid "No remote chosen to resolve matches for ‘%s’"
msgstr "Nevybrán žádný vzdálený repozitář pro vyřešení shod pro „%s“"

#: app/flatpak-builtins-utils.c:696 app/flatpak-builtins-utils.c:699
#, c-format
msgid "Updating appstream data for user remote %s"
msgstr "Aktualizují se appstream data pro uživatelský vzdálený repozitář %s"

#: app/flatpak-builtins-utils.c:706 app/flatpak-builtins-utils.c:709
#, c-format
msgid "Updating appstream data for remote %s"
msgstr "Aktualizují se appstream data pro vzdálený repozitář %s"

#: app/flatpak-builtins-utils.c:717 app/flatpak-builtins-utils.c:719
msgid "Error updating"
msgstr "Chyba během aktualizace"

#: app/flatpak-builtins-utils.c:755
#, c-format
msgid "Remote \"%s\" not found"
msgstr "Vzdálený repozitář „%s“ nebyl nalezen"

#: app/flatpak-builtins-utils.c:796
#, c-format
msgid "Ambiguous suffix: '%s'."
msgstr "Nejednoznačná přípona: „%s“."

#. Translators: don't translate the values
#: app/flatpak-builtins-utils.c:798 app/flatpak-builtins-utils.c:813
msgid "Possible values are :s[tart], :m[iddle], :e[nd] or :f[ull]"
msgstr "Možné hodnoty jsou :s[tart], :m[iddle], :e[nd] nebo :f[ull]"

#: app/flatpak-builtins-utils.c:811
#, c-format
msgid "Invalid suffix: '%s'."
msgstr "Neplatná přípona: „%s“."

#: app/flatpak-builtins-utils.c:846
#, c-format
msgid "Ambiguous column: %s"
msgstr "Nejednoznačný sloupec: %s"

#: app/flatpak-builtins-utils.c:859
#, c-format
msgid "Unknown column: %s"
msgstr "Neznámý sloupec: %s"

#: app/flatpak-builtins-utils.c:917
msgid "Available columns:\n"
msgstr "Dostupné sloupce:\n"

#: app/flatpak-builtins-utils.c:927
msgid "Show all columns"
msgstr "Zobrazit všechny sloupce"

#: app/flatpak-builtins-utils.c:928
msgid "Show available columns"
msgstr "Zobrazit dostupné sloupce"

#: app/flatpak-builtins-utils.c:931
msgid "Append :s[tart], :m[iddle], :e[nd] or :f[ull] to change ellipsization"
msgstr ""

#: app/flatpak-builtins-utils.c:1483
#, c-format
msgid "Unknown scheme in sideload location %s"
msgstr ""

#: app/flatpak-cli-transaction.c:96 app/flatpak-cli-transaction.c:102
#, c-format
msgid "Required runtime for %s (%s) found in remote %s\n"
msgstr ""
"Požadované prostředí pro %s (%s) bylo nalezeno ve vzdáleném repozitáři %s\n"

#: app/flatpak-cli-transaction.c:104
msgid "Do you want to install it?"
msgstr "Chcete ho nainstalovat?"

#: app/flatpak-cli-transaction.c:110
#, c-format
msgid "Required runtime for %s (%s) found in remotes:"
msgstr ""
"Požadované prostředí pro %s (%s) bylo nalezeno ve vzdálených repozitářích:"

#: app/flatpak-cli-transaction.c:112
msgid "Which do you want to install (0 to abort)?"
msgstr "Který si přejete instalovat (0 pro zrušení)?"

#: app/flatpak-cli-transaction.c:132
#, c-format
msgid "Configuring %s as new remote '%s'\n"
msgstr "Nastavuje se %s jako nový vzdálený repozitář „%s“\n"

#. default to yes on Enter
#: app/flatpak-cli-transaction.c:139
#, c-format
msgid ""
"The remote '%s', referred to by '%s' at location %s contains additional "
"applications.\n"
"Should the remote be kept for future installations?"
msgstr ""
"Vzdálený repozitář „%s“, na který odkazuje „%s“ v umístění %s obsahuje "
"dodatečné aplikace.\n"
"Má být vzdálený repozitář ponechán pro budoucí instalace?"

#. default to yes on Enter
#: app/flatpak-cli-transaction.c:147
#, c-format
msgid ""
"The application %s depends on runtimes from:\n"
"  %s\n"
"Configure this as new remote '%s'"
msgstr ""
"Aplikace %s závisí na prostředí z:\n"
"  %s\n"
"Konfigurovat tohle jako nový vzdálený repozitář „%s“"

#. Formatted size/remaining time in seconds
#: app/flatpak-cli-transaction.c:321
#, c-format
msgid "%s/s%s%s"
msgstr ""

#. Download progress percentage, use the appropriate
#. percent format for your language
#: app/flatpak-cli-transaction.c:359
#, c-format
msgid "%3d%%"
msgstr ""

#: app/flatpak-cli-transaction.c:414
msgid "Installing…"
msgstr "Instalace…"

#: app/flatpak-cli-transaction.c:416
#, c-format
msgid "Installing %d/%d…"
msgstr "Instalace %d/%d…"

#: app/flatpak-cli-transaction.c:421
msgid "Updating…"
msgstr "Aktualizace…"

#: app/flatpak-cli-transaction.c:423
#, c-format
msgid "Updating %d/%d…"
msgstr "Aktualizace %d/%d…"

#: app/flatpak-cli-transaction.c:428
msgid "Uninstalling…"
msgstr "Odinstalace…"

#: app/flatpak-cli-transaction.c:430
#, c-format
msgid "Uninstalling %d/%d…"
msgstr "Odinstalace %d/%d…"

#: app/flatpak-cli-transaction.c:496 app/flatpak-quiet-transaction.c:161
#, c-format
msgid "Info: %s was skipped"
msgstr "Informace: %s bylo přeskočeno"

#: app/flatpak-cli-transaction.c:519
#, c-format
msgid "Warning: %s%s%s already installed"
msgstr "Varování: %s%s%s je již nainstalováno"

#: app/flatpak-cli-transaction.c:522
#, c-format
msgid "Error: %s%s%s already installed"
msgstr "Chyba: %s%s%s je již nainstalováno"

#: app/flatpak-cli-transaction.c:528
#, c-format
msgid "Warning: %s%s%s not installed"
msgstr "Varování: %s%s%s nenainstalováno"

#: app/flatpak-cli-transaction.c:531
#, c-format
msgid "Error: %s%s%s not installed"
msgstr "Chyba: %s%s%s nenainstalováno"

#: app/flatpak-cli-transaction.c:537
#, c-format
msgid "Warning: %s%s%s needs a later flatpak version"
msgstr "Varování: %s%s%s vyžaduje novější verzi flatpaku"

#: app/flatpak-cli-transaction.c:540
#, c-format
msgid "Error: %s%s%s needs a later flatpak version"
msgstr "Chyba: %s%s%s vyžaduje novější verzi flatpaku"

#: app/flatpak-cli-transaction.c:546
msgid "Warning: Not enough disk space to complete this operation"
msgstr "Varování: Na disku není dostatek místa k provedení této operace"

#: app/flatpak-cli-transaction.c:548
msgid "Error: Not enough disk space to complete this operation"
msgstr "Chyba: Na disku není dostatek místa k provedení této operace"

#: app/flatpak-cli-transaction.c:553
#, c-format
msgid "Warning: %s"
msgstr "Varování: %s"

#: app/flatpak-cli-transaction.c:555
#, c-format
msgid "Error: %s"
msgstr "Chyba: %s"

#: app/flatpak-cli-transaction.c:570
#, c-format
msgid "Failed to install %s%s%s: "
msgstr "Selhala instalace %s%s%s: "

#: app/flatpak-cli-transaction.c:577
#, c-format
msgid "Failed to update %s%s%s: "
msgstr "Selhala aktualizace %s%s%s: "

#: app/flatpak-cli-transaction.c:584
#, c-format
msgid "Failed to install bundle %s%s%s: "
msgstr "Selhala instalace balíku %s%s%s: "

#: app/flatpak-cli-transaction.c:591
#, c-format
msgid "Failed to uninstall %s%s%s: "
msgstr "Selhala odinstalace %s%s%s: "

#: app/flatpak-cli-transaction.c:642
#, c-format
msgid "Authentication required for remote '%s'\n"
msgstr "Pro vzdálený repozitář „%s“ je vyžadováno ověření\n"

#: app/flatpak-cli-transaction.c:643
msgid "Open browser?"
msgstr "Otevřít prohlížeč?"

#: app/flatpak-cli-transaction.c:699
#, c-format
msgid "Login required remote %s (realm %s)\n"
msgstr "Přihlášení vyžadující vzdálený repozitář %s (doména %s)\n"

#: app/flatpak-cli-transaction.c:704
msgid "Password"
msgstr "Heslo"

#. Only runtimes can be pinned
#: app/flatpak-cli-transaction.c:759
#, c-format
msgid ""
"\n"
"Info: (pinned) runtime %s%s%s branch %s%s%s is end-of-life, in favor of "
"%s%s%s branch %s%s%s\n"
msgstr ""
"\n"
"Informace: (připnuto) prostředí %s%s%s větev %s%s%s je end-of-life, ve "
"prospěch %s%s%s větev %s%s%s\n"

#: app/flatpak-cli-transaction.c:765
#, c-format
msgid ""
"\n"
"Info: runtime %s%s%s branch %s%s%s is end-of-life, in favor of %s%s%s branch "
"%s%s%s\n"
msgstr ""
"\n"
"Informace: prostředí %s%s%s větev %s%s%s je end-of-life, ve prospěch %s%s%s "
"větev %s%s%s\n"

#: app/flatpak-cli-transaction.c:768
#, c-format
msgid ""
"\n"
"Info: app %s%s%s branch %s%s%s is end-of-life, in favor of %s%s%s branch "
"%s%s%s\n"
msgstr ""
"\n"
"Informace: aplikace %s%s%s větev %s%s%s je end-of-life, ve prospěch %s%s%s "
"větev %s%s%s\n"

#. Only runtimes can be pinned
#: app/flatpak-cli-transaction.c:780
#, c-format
msgid ""
"\n"
"Info: (pinned) runtime %s%s%s branch %s%s%s is end-of-life, with reason:\n"
msgstr ""
"\n"
"Informace: (připnuto) prostředí %s%s%s větev %s%s%s je end-of-life, z "
"důvodu:\n"

#: app/flatpak-cli-transaction.c:786
#, c-format
msgid ""
"\n"
"Info: runtime %s%s%s branch %s%s%s is end-of-life, with reason:\n"
msgstr ""
"\n"
"Informace: prostředí %s%s%s větev %s%s%s je end-of-life, z důvodu:\n"

#: app/flatpak-cli-transaction.c:789
#, c-format
msgid ""
"\n"
"Info: app %s%s%s branch %s%s%s is end-of-life, with reason:\n"
msgstr ""
"\n"
"Informace: aplikace %s%s%s větev %s%s%s je end-of-life, z důvodu:\n"

#: app/flatpak-cli-transaction.c:963
#, c-format
msgid "Info: applications using this extension:\n"
msgstr "Informace: aplikace používající toto rozšíření:\n"

#: app/flatpak-cli-transaction.c:965
#, c-format
msgid "Info: applications using this runtime:\n"
msgstr "Informace: aplikace používající toto prostředí:\n"

#: app/flatpak-cli-transaction.c:984
msgid "Replace?"
msgstr "Nahradit?"

#: app/flatpak-cli-transaction.c:987 app/flatpak-quiet-transaction.c:247
#, c-format
msgid "Updating to rebased version\n"
msgstr "Aktualizace na rebased verzi\n"

#: app/flatpak-cli-transaction.c:1011
#, c-format
msgid "Failed to rebase %s to %s: "
msgstr "Selhalo rebase %s na %s: "

#: app/flatpak-cli-transaction.c:1277
#, c-format
msgid "New %s%s%s permissions:"
msgstr "Nových %s%s%s oprávnění:"

#: app/flatpak-cli-transaction.c:1279
#, c-format
msgid "%s%s%s permissions:"
msgstr "%s%s%s oprávnění:"

#: app/flatpak-cli-transaction.c:1343
msgid "Warning: "
msgstr "Varování: "

#. translators: This is short for operation, the title of a one-char column
#: app/flatpak-cli-transaction.c:1442
msgid "Op"
msgstr "Op"

#. Avoid resizing the download column too much,
#. * by making the title as long as typical content
#.
#: app/flatpak-cli-transaction.c:1458 app/flatpak-cli-transaction.c:1503
msgid "partial"
msgstr "částečný"

#: app/flatpak-cli-transaction.c:1535
msgid "Proceed with these changes to the user installation?"
msgstr "Pokračovat s těmito změnami do uživatelské instalace?"

#: app/flatpak-cli-transaction.c:1537
msgid "Proceed with these changes to the system installation?"
msgstr "Pokračovat s těmito změnami do systémové instalace?"

#: app/flatpak-cli-transaction.c:1539
#, c-format
msgid "Proceed with these changes to the %s?"
msgstr "Pokračovat s těmito změnami do %s?"

#: app/flatpak-cli-transaction.c:1711
msgid "Changes complete."
msgstr "Změny dokončeny."

#: app/flatpak-cli-transaction.c:1713
msgid "Uninstall complete."
msgstr "Odinstalace dokončena."

#: app/flatpak-cli-transaction.c:1715
msgid "Installation complete."
msgstr "Instalace dokončena."

#: app/flatpak-cli-transaction.c:1717
msgid "Updates complete."
msgstr "Aktualizace dokončeny."

#. For updates/!stop_on_first_error we already printed all errors so we make up
#. a different one.
#: app/flatpak-cli-transaction.c:1750
msgid "There were one or more errors"
msgstr "Vyskytla se jedna či více chyb"

#. translators: please keep the leading space
#: app/flatpak-main.c:76
msgid " Manage installed applications and runtimes"
msgstr " Správa instalovaných aplikací a prostředí"

#: app/flatpak-main.c:77
msgid "Install an application or runtime"
msgstr "Instalovat aplikaci nebo prostředí"

#: app/flatpak-main.c:78
msgid "Update an installed application or runtime"
msgstr "Aktualizovat instalovanou aplikaci nebo prostředí"

#: app/flatpak-main.c:81
msgid "Uninstall an installed application or runtime"
msgstr "Odinstalovat instalovanou aplikaci nebo prostředí"

#: app/flatpak-main.c:84
msgid "Mask out updates and automatic installation"
msgstr "Maskovat aktualizace a automatickou instalaci"

#: app/flatpak-main.c:85
msgid "Pin a runtime to prevent automatic removal"
msgstr "Připnout prostředí pro zabránění automatickému odstranění"

#: app/flatpak-main.c:86
msgid "List installed apps and/or runtimes"
msgstr "Vypsat nainstalované aplikace a/nebo prostředí"

#: app/flatpak-main.c:87
msgid "Show info for installed app or runtime"
msgstr "Zobrazit informace pro nainstalovanou aplikaci či prostředí"

#: app/flatpak-main.c:88
msgid "Show history"
msgstr "Zobrazit historii"

#: app/flatpak-main.c:89
msgid "Configure flatpak"
msgstr "Nastavit flatpak"

#: app/flatpak-main.c:90
msgid "Repair flatpak installation"
msgstr "Opravit flatpak instalaci"

#: app/flatpak-main.c:91
msgid "Put applications or runtimes onto removable media"
msgstr "Umístit aplikace nebo prostředí na vyměnitelné médium"

#: app/flatpak-main.c:92
msgid "Install flatpaks that are part of the operating system"
msgstr "Nainstalovat flatpaky, které jsou součástí operačního systému"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:95
msgid ""
"\n"
" Find applications and runtimes"
msgstr ""
"\n"
" Vyhledávání aplikací a prostředí"

#: app/flatpak-main.c:96
msgid "Search for remote apps/runtimes"
msgstr "Hledat vzdálené aplikace/prostředí"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:99
msgid ""
"\n"
" Manage running applications"
msgstr ""
"\n"
" Správa běžících aplikací"

#: app/flatpak-main.c:100
msgid "Run an application"
msgstr "Spustit aplikaci"

#: app/flatpak-main.c:101
msgid "Override permissions for an application"
msgstr "Přepsat oprávnění pro aplikaci"

#: app/flatpak-main.c:102
msgid "Specify default version to run"
msgstr "Určit výchozí verzi ke spuštění"

#: app/flatpak-main.c:103
msgid "Enter the namespace of a running application"
msgstr "Vstoupit do jmenného prostoru běžící aplikace"

#: app/flatpak-main.c:104
msgid "Enumerate running applications"
msgstr "Vypsat spuštěné aplikace"

#: app/flatpak-main.c:105
msgid "Stop a running application"
msgstr "Zastavit běžící aplikaci"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:108
msgid ""
"\n"
" Manage file access"
msgstr ""
"\n"
" Správa přístupu k souborům"

#: app/flatpak-main.c:109
msgid "List exported files"
msgstr "Zobrazit exportované soubory"

#: app/flatpak-main.c:110
msgid "Grant an application access to a specific file"
msgstr "Udělit aplikaci přístup k určenému souboru"

#: app/flatpak-main.c:111
msgid "Revoke access to a specific file"
msgstr "Zrušit přístup aplikace k určenému souboru"

#: app/flatpak-main.c:112
msgid "Show information about a specific file"
msgstr "Zobrazit informace o určeném souboru"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:116
msgid ""
"\n"
" Manage dynamic permissions"
msgstr ""
"\n"
" Správa dynamických oprávnění"

#: app/flatpak-main.c:117
msgid "List permissions"
msgstr "Vypsat oprávnění"

#: app/flatpak-main.c:118
msgid "Remove item from permission store"
msgstr "Odstranit položku z úložiště oprávnění"

#: app/flatpak-main.c:120
msgid "Set permissions"
msgstr "Nastavit oprávnění"

#: app/flatpak-main.c:121
msgid "Show app permissions"
msgstr "Zobrazit oprávnění aplikace"

#: app/flatpak-main.c:122
msgid "Reset app permissions"
msgstr "Resetovat oprávnění aplikace"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:125
msgid ""
"\n"
" Manage remote repositories"
msgstr ""
"\n"
" Správa vzdálených repozitářů"

#: app/flatpak-main.c:126
msgid "List all configured remotes"
msgstr "Vypsat všechny nastavené vzdálené repozitáře"

#: app/flatpak-main.c:127
msgid "Add a new remote repository (by URL)"
msgstr "Přidat nový vzdálený repozitář (pomocí URL)"

#: app/flatpak-main.c:128
msgid "Modify properties of a configured remote"
msgstr "Měnit vlastnosti nastaveného vzdáleného repozitáře"

#: app/flatpak-main.c:129
msgid "Delete a configured remote"
msgstr "Odstranit nastavený vzdálený repozitář"

#: app/flatpak-main.c:131
msgid "List contents of a configured remote"
msgstr "Vypsat obsah nastaveného vzdáleného repozitáře"

#: app/flatpak-main.c:132
msgid "Show information about a remote app or runtime"
msgstr "Zobrazit informace o vzdálené aplikaci či prostředí"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:135
msgid ""
"\n"
" Build applications"
msgstr ""
"\n"
" Sestavení aplikací"

#: app/flatpak-main.c:136
msgid "Initialize a directory for building"
msgstr "Inicializovat adresář pro sestavení"

#: app/flatpak-main.c:137
msgid "Run a build command inside the build dir"
msgstr "Spustit příkaz k sestavení uvnitř adresáře sestavení"

#: app/flatpak-main.c:138
msgid "Finish a build dir for export"
msgstr "Dokončit adresář sestavení pro export"

#: app/flatpak-main.c:139
msgid "Export a build dir to a repository"
msgstr "Exportovat adresář sestavení do repozitáře"

#: app/flatpak-main.c:140
msgid "Create a bundle file from a ref in a local repository"
msgstr "Vytvořit soubor balíku z refu v místním repozitáři"

#: app/flatpak-main.c:141
msgid "Import a bundle file"
msgstr "Importovat soubor balíku"

#: app/flatpak-main.c:142
msgid "Sign an application or runtime"
msgstr "Podepsat aplikaci nebo prostředí"

#: app/flatpak-main.c:143
msgid "Update the summary file in a repository"
msgstr "Aktualizovat soubor shrnutí v repozitáři"

#: app/flatpak-main.c:144
msgid "Create new commit based on existing ref"
msgstr "Vytvořit nový commit založený na existujícím ref"

#: app/flatpak-main.c:145
msgid "Show information about a repo"
msgstr "Zobrazit informace o repozitáři"

#: app/flatpak-main.c:162
msgid "Show debug information, -vv for more detail"
msgstr "Zobrazit ladicí informace, -vv pro více detailů"

#: app/flatpak-main.c:163
msgid "Show OSTree debug information"
msgstr "Zobrazit ladicí informace OSTree"

#: app/flatpak-main.c:169
msgid "Print version information and exit"
msgstr "Vypsat informace o verzi a skončit"

#: app/flatpak-main.c:170
msgid "Print default arch and exit"
msgstr "Vypsat výchozí architekturu a skončit"

#: app/flatpak-main.c:171
msgid "Print supported arches and exit"
msgstr "Vypsat podporované architektury a skončit"

#: app/flatpak-main.c:172
msgid "Print active gl drivers and exit"
msgstr "Vypsat aktivní gl ovladače a skončit"

#: app/flatpak-main.c:173
msgid "Print paths for system installations and exit"
msgstr "Vypsat cesty k systémovým instalacím a skončit"

#: app/flatpak-main.c:174
msgid "Print the updated environment needed to run flatpaks"
msgstr "Vypsat aktualizované prostředí požadované pro běh flatpaků"

#: app/flatpak-main.c:175
msgid "Only include the system installation with --print-updated-env"
msgstr "Zahrnout pouze systémové instalace s --print-updated-env"

#: app/flatpak-main.c:180
msgid "Work on the user installation"
msgstr "Pracovat na uživatelské instalaci"

#: app/flatpak-main.c:181
msgid "Work on the system-wide installation (default)"
msgstr "Pracovat na systémové instalaci (výchozí)"

#: app/flatpak-main.c:182
msgid "Work on a non-default system-wide installation"
msgstr "Pracovat na nevýchozí systémové instalaci"

#: app/flatpak-main.c:212
msgid "Builtin Commands:"
msgstr "Vestavěné příkazy:"

#: app/flatpak-main.c:298
#, c-format
msgid ""
"Note that the directories %s are not in the search path set by the "
"XDG_DATA_DIRS environment variable, so applications installed by Flatpak may "
"not appear on your desktop until the session is restarted."
msgstr ""
"Všimněte si, že adresáře %s nejsou ve vyhledávací cestě nastavené proměnnou "
"prostředí XDG_DATA_DIRS, takže aplikace nainstalované pomocí Flatpaku se "
"nemusí objevit na vaší ploše, dokud nebude sezení restartováno."

#: app/flatpak-main.c:312
#, c-format
msgid ""
"Note that the directory %s is not in the search path set by the "
"XDG_DATA_DIRS environment variable, so applications installed by Flatpak may "
"not appear on your desktop until the session is restarted."
msgstr ""
"Všimněte si, že adresář %s není ve vyhledávací cestě nastavené proměnnou "
"prostředí XDG_DATA_DIRS, takže aplikace nainstalované pomocí Flatpaku se "
"nemusí objevit na vaší ploše, dokud nebude sezení restartováno."

#: app/flatpak-main.c:381
msgid ""
"Refusing to operate under sudo with --user. Omit sudo to operate on the user "
"installation, or use a root shell to operate on the root user's installation."
msgstr ""
"Odmítá se operace pod sudo s --user. Vynechte sudo pro operaci na "
"uživatelské instalaci, nebo použijte shell uživatele root pro operaci na "
"instalaci uživatele root."

#: app/flatpak-main.c:453
msgid ""
"Multiple installations specified for a command that works on one installation"
msgstr "Více instalací určeno pro příkaz, který funguje na jedné instalaci"

#: app/flatpak-main.c:504 app/flatpak-main.c:697
#, c-format
msgid "See '%s --help'"
msgstr "Viz „%s --help“"

#: app/flatpak-main.c:706
#, c-format
msgid "'%s' is not a flatpak command. Did you mean '%s%s'?"
msgstr "„%s“ není platným flatpak příkazem. Měli jste na mysli „%s%s“?"

#: app/flatpak-main.c:709
#, c-format
msgid "'%s' is not a flatpak command"
msgstr "„%s“ není příkaz flatpaku"

#: app/flatpak-main.c:824
msgid "No command specified"
msgstr "Nebyl určen žádný příkaz"

#: app/flatpak-main.c:980
msgid "error:"
msgstr "chyba:"

#: app/flatpak-quiet-transaction.c:77
#, c-format
msgid "Installing %s\n"
msgstr "Instaluje se %s\n"

#: app/flatpak-quiet-transaction.c:81
#, c-format
msgid "Updating %s\n"
msgstr "Aktualizuje se %s\n"

#: app/flatpak-quiet-transaction.c:85
#, c-format
msgid "Uninstalling %s\n"
msgstr "Odstraňuje se %s\n"

#: app/flatpak-quiet-transaction.c:107
#, c-format
msgid "Warning: Failed to install %s: %s\n"
msgstr "Varování: Selhala instalace %s: %s\n"

#: app/flatpak-quiet-transaction.c:110
#, c-format
msgid "Error: Failed to install %s: %s\n"
msgstr "Chyba: Selhala instalace %s: %s\n"

#: app/flatpak-quiet-transaction.c:116
#, c-format
msgid "Warning: Failed to update %s: %s\n"
msgstr "Varování: Selhala aktualizace %s: %s\n"

#: app/flatpak-quiet-transaction.c:119
#, c-format
msgid "Error: Failed to update %s: %s\n"
msgstr "Chyba: Selhala aktualizace %s: %s\n"

#: app/flatpak-quiet-transaction.c:125
#, c-format
msgid "Warning: Failed to install bundle %s: %s\n"
msgstr "Varování: Selhala instalace balíku %s: %s\n"

#: app/flatpak-quiet-transaction.c:128
#, c-format
msgid "Error: Failed to install bundle %s: %s\n"
msgstr "Chyba: Selhala instalace balíku %s: %s\n"

#: app/flatpak-quiet-transaction.c:134
#, c-format
msgid "Warning: Failed to uninstall %s: %s\n"
msgstr "Varování: Selhala odinstalace %s: %s\n"

#: app/flatpak-quiet-transaction.c:137
#, c-format
msgid "Error: Failed to uninstall %s: %s\n"
msgstr "Chyba: Selhala odinstalace %s: %s\n"

#: app/flatpak-quiet-transaction.c:166 common/flatpak-dir.c:11475
#, c-format
msgid "%s already installed"
msgstr "%s je již nainstalováno"

#: app/flatpak-quiet-transaction.c:168 common/flatpak-dir.c:3622
#: common/flatpak-dir.c:4321 common/flatpak-dir.c:16968
#: common/flatpak-dir.c:17258 common/flatpak-dir-utils.c:166
#: common/flatpak-dir-utils.c:259 common/flatpak-transaction.c:2736
#: common/flatpak-transaction.c:2791
#, c-format
msgid "%s not installed"
msgstr "%s není nainstalováno"

#: app/flatpak-quiet-transaction.c:170
#, c-format
msgid "%s needs a later flatpak version"
msgstr "%s vyžaduje novější verzi flatpaku"

#: app/flatpak-quiet-transaction.c:172
msgid "Not enough disk space to complete this operation"
msgstr "Na disku není dostatek místa k provedení této operace"

#: app/flatpak-quiet-transaction.c:239
#, c-format
msgid "Info: %s is end-of-life, in favor of %s\n"
msgstr "Informace: %s je end-of-life, ve prospěch %s\n"

#: app/flatpak-quiet-transaction.c:241
#, c-format
msgid "Info: %s is end-of-life, with reason: %s\n"
msgstr "Informace: %s je end-of-life, z důvodu: %s\n"

#: app/flatpak-quiet-transaction.c:251
#, c-format
msgid "Failed to rebase %s to %s: %s\n"
msgstr "Selhalo rebase %s na %s: %s\n"

#: common/flatpak-auth.c:58
#, c-format
msgid "No authenticator configured for remote `%s`"
msgstr "Nenastaven žádný autentikátor pro vzdálený repozitář „%s“"

#: common/flatpak-context.c:637 common/flatpak-context.c:649
#, fuzzy, c-format
msgid "Invalid permission syntax: %s"
msgstr "Neplatný název rozšíření %s"

#: common/flatpak-context.c:1207
#, c-format
msgid "Unknown share type %s, valid types are: %s"
msgstr "Neznámý typ sdílení %s, platné typy jsou: %s"

#: common/flatpak-context.c:1228
#, c-format
msgid "Unknown policy type %s, valid types are: %s"
msgstr "Neznámý typ zásad %s, platné typy jsou: %s"

#: common/flatpak-context.c:1266
#, c-format
msgid "Invalid dbus name %s"
msgstr "Neplatný název dbus %s"

#: common/flatpak-context.c:1279
#, c-format
msgid "Unknown socket type %s, valid types are: %s"
msgstr "Neznámý typ soketu %s, platné typy jsou: %s"

#: common/flatpak-context.c:1294
#, c-format
msgid "Unknown device type %s, valid types are: %s"
msgstr "Neznámý typ zařízení %s, platné typy jsou: %s"

#: common/flatpak-context.c:1308
#, c-format
msgid "Unknown feature type %s, valid types are: %s"
msgstr "Neznámý typ funkce %s, platné typy jsou: %s"

#: common/flatpak-context.c:1840
#, c-format
msgid "Filesystem location \"%s\" contains \"..\""
msgstr "Umístění systému souborů „%s“ obsahuje „..“"

#: common/flatpak-context.c:1882
#, c-format
msgid ""
"--filesystem=/ is not available, use --filesystem=host for a similar result"
msgstr ""
"--filesystem=/ není dostupné, pro podobný výsledek použijte --filesystem=host"

#: common/flatpak-context.c:1916
#, fuzzy, c-format
msgid ""
"Unknown filesystem location %s, valid locations are: host, host-os, host-"
"etc, host-root, home, xdg-*[/…], ~/dir, /dir"
msgstr ""
"Neplatné umístění systému souborů %s, platná umístění jsou: host, host-os, "
"host-etc, home, xdg-*[/…], ~/dir, /dir"

#: common/flatpak-context.c:2015
#, fuzzy, c-format
msgid "Invalid syntax for %s: %s"
msgstr "Neplatný název %s: %s"

#: common/flatpak-context.c:2142
#, c-format
msgid "fallback-x11 can not be conditional"
msgstr ""

#: common/flatpak-context.c:2318
#, c-format
msgid "Invalid env format %s"
msgstr "Neplatný formát env %s"

#: common/flatpak-context.c:2399
#, c-format
msgid "Environment variable name must not contain '=': %s"
msgstr "Název proměnné prostředí nesmí obsahovat '=': %s"

#: common/flatpak-context.c:2527 common/flatpak-context.c:2535
#, c-format
msgid "--add-policy arguments must be in the form SUBSYSTEM.KEY=VALUE"
msgstr "--add-policy argumenty musí být ve formě SUBSYSTÉM.KLÍČ=HODNOTA"

#: common/flatpak-context.c:2542
#, c-format
msgid "--add-policy values can't start with \"!\""
msgstr "--add-policy hodnoty nemohou začínat „!“"

#: common/flatpak-context.c:2567 common/flatpak-context.c:2575
#, c-format
msgid "--remove-policy arguments must be in the form SUBSYSTEM.KEY=VALUE"
msgstr "--remove-policy argumenty musí být ve formě SUBSYSTÉM.KLÍČ=HODNOTA"

#: common/flatpak-context.c:2582
#, c-format
msgid "--remove-policy values can't start with \"!\""
msgstr "--remove-policy hodnoty nemohou začínat „!“"

#: common/flatpak-context.c:2657
msgid "Share with host"
msgstr "Sdílet s hostitelem"

#: common/flatpak-context.c:2657 common/flatpak-context.c:2658
msgid "SHARE"
msgstr "SDÍLET"

#: common/flatpak-context.c:2658
msgid "Unshare with host"
msgstr "Zrušit sdílení s hostitelem"

#: common/flatpak-context.c:2659
msgid "Require conditions to be met for a subsystem to get shared"
msgstr ""

#: common/flatpak-context.c:2659
msgid "SHARE:CONDITION"
msgstr ""

#: common/flatpak-context.c:2660
msgid "Expose socket to app"
msgstr "Odhalit soket aplikaci"

#: common/flatpak-context.c:2660 common/flatpak-context.c:2661
msgid "SOCKET"
msgstr "SOKET"

#: common/flatpak-context.c:2661
msgid "Don't expose socket to app"
msgstr "Neodhalovat soket aplikaci"

#: common/flatpak-context.c:2662
msgid "Require conditions to be met for a socket to get exposed"
msgstr ""

#: common/flatpak-context.c:2662
msgid "SOCKET:CONDITION"
msgstr ""

#: common/flatpak-context.c:2663
msgid "Expose device to app"
msgstr "Odhalit zařízení aplikaci"

#: common/flatpak-context.c:2663 common/flatpak-context.c:2664
msgid "DEVICE"
msgstr "ZAŘÍZENÍ"

#: common/flatpak-context.c:2664
msgid "Don't expose device to app"
msgstr "Neodhalovat zařízení aplikaci"

#: common/flatpak-context.c:2665
msgid "Require conditions to be met for a device to get exposed"
msgstr ""

#: common/flatpak-context.c:2665
msgid "DEVICE:CONDITION"
msgstr ""

#: common/flatpak-context.c:2666
msgid "Allow feature"
msgstr "Umožnit funkci"

#: common/flatpak-context.c:2666 common/flatpak-context.c:2667
msgid "FEATURE"
msgstr "FUNKCE"

#: common/flatpak-context.c:2667
msgid "Don't allow feature"
msgstr "Neumožnit funkci"

#: common/flatpak-context.c:2668
msgid "Require conditions to be met for a feature to get allowed"
msgstr ""

#: common/flatpak-context.c:2668
msgid "FEATURE:CONDITION"
msgstr ""

#: common/flatpak-context.c:2669
msgid "Expose filesystem to app (:ro for read-only)"
msgstr "Odhalit systém souborů aplikaci (:ro pro přístup pouze ke čtení)"

#: common/flatpak-context.c:2669
msgid "FILESYSTEM[:ro]"
msgstr "SYSTÉM_SOUBORŮ[:ro]"

#: common/flatpak-context.c:2670
msgid "Don't expose filesystem to app"
msgstr "Neodhalovat systém souborů aplikaci"

#: common/flatpak-context.c:2670
msgid "FILESYSTEM"
msgstr "SYSTÉM_SOUBORŮ"

#: common/flatpak-context.c:2671
msgid "Set environment variable"
msgstr "Nastavit proměnnou prostředí"

#: common/flatpak-context.c:2671
msgid "VAR=VALUE"
msgstr "PROMĚNNÁ=HODNOTA"

#: common/flatpak-context.c:2672
msgid "Read environment variables in env -0 format from FD"
msgstr "Číst proměnné prostředí ve formátu env -0 z FD"

#: common/flatpak-context.c:2673
msgid "Remove variable from environment"
msgstr "Odstranit proměnnou z prostředí"

#: common/flatpak-context.c:2673
msgid "VAR"
msgstr "PROMĚNNÁ"

#: common/flatpak-context.c:2674
msgid "Allow app to own name on the session bus"
msgstr "Povolit aplikaci vlastnit název na sběrnici sezení"

#: common/flatpak-context.c:2674 common/flatpak-context.c:2675
#: common/flatpak-context.c:2676 common/flatpak-context.c:2677
#: common/flatpak-context.c:2678 common/flatpak-context.c:2679
#: common/flatpak-context.c:2680
msgid "DBUS_NAME"
msgstr "NÁZEV_DBUS"

#: common/flatpak-context.c:2675
msgid "Allow app to talk to name on the session bus"
msgstr "Povolit aplikaci komunikovat s názvem na sběrnici sezení"

#: common/flatpak-context.c:2676
msgid "Don't allow app to talk to name on the session bus"
msgstr "Nepovolit aplikaci komunikovat s názvem na sběrnici sezení"

#: common/flatpak-context.c:2677
msgid "Allow app to own name on the system bus"
msgstr "Povolit aplikaci vlastnit název na systémové sběrnici"

#: common/flatpak-context.c:2678
msgid "Allow app to talk to name on the system bus"
msgstr "Povolit aplikaci komunikovat s názvem na systémové sběrnici"

#: common/flatpak-context.c:2679
msgid "Don't allow app to talk to name on the system bus"
msgstr "Nepovolit aplikaci komunikovat s názvem na systémové sběrnici"

#: common/flatpak-context.c:2680
msgid "Allow app to own name on the a11y bus"
msgstr "Povolit aplikaci vlastnit název na sběrnici a11y"

#: common/flatpak-context.c:2681
msgid "Add generic policy option"
msgstr "Přidat generickou volbu bezpečnostní politiky"

#: common/flatpak-context.c:2681 common/flatpak-context.c:2682
msgid "SUBSYSTEM.KEY=VALUE"
msgstr "SUBSYSTÉM.KLÍČ=HODNOTA"

#: common/flatpak-context.c:2682
msgid "Remove generic policy option"
msgstr "Odebrat generickou volbu bezpečnostní politiky"

#: common/flatpak-context.c:2683
msgid "Add USB device to enumerables"
msgstr "Přidat zařízení USB do enumerovatelných"

#: common/flatpak-context.c:2683 common/flatpak-context.c:2684
msgid "VENDOR_ID:PRODUCT_ID"
msgstr "ID_VÝROBCE:ID_PRODUKTU"

#: common/flatpak-context.c:2684
msgid "Add USB device to hidden list"
msgstr "Přidat zařízení USB do skrytého seznamu"

#: common/flatpak-context.c:2685
msgid "A list of USB devices that are enumerable"
msgstr "Seznam zařízení USB pro enumeraci"

#: common/flatpak-context.c:2685
msgid "LIST"
msgstr "SEZNAM"

#: common/flatpak-context.c:2686
msgid "File containing a list of USB devices to make enumerable"
msgstr "Soubor obsahující seznam zařízení USB pro enumeraci"

#: common/flatpak-context.c:2686 common/flatpak-context.c:2687
msgid "FILENAME"
msgstr "NÁZEV_SOUBORU"

#: common/flatpak-context.c:2687
msgid "Persist home directory subpath"
msgstr "Trvalá podcesta domovského adresáře"

#. This is not needed/used anymore, so hidden, but we accept it for backwards compat
#: common/flatpak-context.c:2689
msgid "Don't require a running session (no cgroups creation)"
msgstr "Nevyžadovat běžící sezení (bez vytvoření cgroups)"

#: common/flatpak-context.c:3718
#, c-format
msgid "Not replacing \"%s\" with tmpfs: %s"
msgstr "Nenahrazení „%s“ tmpfs: %s"

#: common/flatpak-context.c:3726
#, c-format
msgid "Not sharing \"%s\" with sandbox: %s"
msgstr "Nesdílení „%s“ se sandboxem: %s"

#. Even if the error is one that we would normally silence, like
#. * the path not existing, it seems reasonable to make more of a fuss
#. * about the home directory not existing or otherwise being unusable,
#. * so this is intentionally not using cannot_export()
#: common/flatpak-context.c:3828
#, c-format
msgid "Not allowing home directory access: %s"
msgstr "Nepovolení přístupu k domovskému adresáři: %s"

#: common/flatpak-context.c:4062
#, c-format
msgid "Unable to provide a temporary home directory in the sandbox: %s"
msgstr "Selhalo poskytnutí dočasného domovského adresáře v sandboxu: %s"

#: common/flatpak-dir.c:442
#, c-format
msgid "Configured collection ID ‘%s’ not in summary file"
msgstr ""

#: common/flatpak-dir.c:587
#, c-format
msgid "Unable to load summary from remote %s: %s"
msgstr "Nelze načíst shrnutí ze vzdáleného repozitáře %s: %s"

#: common/flatpak-dir.c:764 common/flatpak-dir.c:800 common/flatpak-dir.c:906
#, c-format
msgid "No such ref '%s' in remote %s"
msgstr "Nemohu nalézt ref „%s“ ve vzdáleném repozitáři %s"

#: common/flatpak-dir.c:891 common/flatpak-dir.c:1051 common/flatpak-dir.c:1080
#: common/flatpak-dir.c:1092
#, c-format
msgid "No entry for %s in remote %s summary flatpak cache"
msgstr "Žádný záznam pro %s ve flatpak cache shrnutí vzdáleného repozitáře %s"

#: common/flatpak-dir.c:1069
#, c-format
msgid "No summary or Flatpak cache available for remote %s"
msgstr "Žádné shrnutí nebo Flatpak cache dostupná pro vzdálený repozitář %s"

#: common/flatpak-dir.c:1097
#, c-format
msgid "Missing xa.data in summary for remote %s"
msgstr "Chybějící xa.data ve shrnutí pro vzdálený repozitář %s"

#: common/flatpak-dir.c:1103 common/flatpak-dir.c:1546
#, c-format
msgid "Unsupported summary version %d for remote %s"
msgstr "Nepodporovaná verze shrnutí %d pro vzdálený repozitář %s"

#: common/flatpak-dir.c:1200
msgid "Remote OCI index has no registry uri"
msgstr ""

#: common/flatpak-dir.c:1261
#, c-format
msgid "Couldn't find ref %s in remote %s"
msgstr "Nepodařilo se nalézt ref %s ve vzdáleném repozitáři %s"

#: common/flatpak-dir.c:1288 common/flatpak-dir.c:1381
#, c-format
msgid "Commit has no requested ref ‘%s’ in ref binding metadata (found: ‘%s’)"
msgstr ""

#: common/flatpak-dir.c:1413
#, c-format
msgid "Configured collection ID ‘%s’ not in binding metadata"
msgstr ""

#: common/flatpak-dir.c:1449 common/flatpak-dir.c:5645
#, c-format
msgid "Couldn't find latest checksum for ref %s in remote %s"
msgstr ""
"Nepodařilo se získat nejnovější kontrolní součet pro ref %s ve vzdáleném "
"repozitáři %s"

#: common/flatpak-dir.c:1516 common/flatpak-dir.c:1552
#, c-format
msgid "No entry for %s in remote %s summary flatpak sparse cache"
msgstr "Žádný záznam pro %s v řídké cache shrnutí vzdáleného repozitáře %s"

#: common/flatpak-dir.c:2540
#, c-format
msgid "Commit metadata for %s not matching expected metadata"
msgstr ""

#: common/flatpak-dir.c:2823
msgid "Unable to connect to system bus"
msgstr "Nelze se připojit k systémové sběrnici"

#: common/flatpak-dir.c:3419
msgid "User installation"
msgstr "Uživatelská instalace"

#: common/flatpak-dir.c:3426
#, c-format
msgid "System (%s) installation"
msgstr "Systémová (%s) instalace"

#: common/flatpak-dir.c:3472
#, c-format
msgid "No overrides found for %s"
msgstr "Žádná přepsání nenalezena pro %s"

#: common/flatpak-dir.c:3625
#, c-format
msgid "%s (commit %s) not installed"
msgstr "%s (commit %s) nenainstalováno"

#: common/flatpak-dir.c:4650
#, c-format
msgid "Error parsing system flatpakrepo file for %s: %s"
msgstr "Chyba během zpracování souboru flatpakrepo pro %s: %s"

#: common/flatpak-dir.c:4735
#, c-format
msgid "While opening repository %s: "
msgstr "Během otevírání repozitáře %s: "

#: common/flatpak-dir.c:5004
#, c-format
msgid "The config key %s is not set"
msgstr "Konfigurační klíč %s není nastaven"

#: common/flatpak-dir.c:5140
#, c-format
msgid "No current %s pattern matching %s"
msgstr "Žádný současný vzor %s odpovídající %s"

#: common/flatpak-dir.c:5422
msgid "No appstream commit to deploy"
msgstr "Žádný appstream commit k nasazení"

#: common/flatpak-dir.c:5941 common/flatpak-dir.c:7266
#: common/flatpak-dir.c:10881 common/flatpak-dir.c:11618
msgid "Can't pull from untrusted non-gpg verified remote"
msgstr ""

#: common/flatpak-dir.c:6376 common/flatpak-dir.c:6591
msgid "Extra data not supported for non-gpg-verified local system installs"
msgstr ""

#: common/flatpak-dir.c:6415 common/flatpak-dir.c:6782
#, c-format
msgid "Invalid checksum for extra data uri %s"
msgstr "Neplatný kontrolní součet pro uri dodatečných dat %s"

#: common/flatpak-dir.c:6424
#, c-format
msgid "Empty name for extra data uri %s"
msgstr "Prázdný název pro uri dodatečných dat %s"

#: common/flatpak-dir.c:6432
#, c-format
msgid "Unsupported extra data uri %s"
msgstr "Nepodporovaný uri dodatečných dat %s"

#: common/flatpak-dir.c:6461
#, c-format
msgid "Failed to load local extra-data %s: %s"
msgstr "Chyba během načítání místních dodatečných dat %s: %s"

#: common/flatpak-dir.c:6469
#, c-format
msgid "Wrong size for extra-data %s"
msgstr "Chybná velikost pro dodatečná data %s"

#: common/flatpak-dir.c:6488
#, c-format
msgid "While downloading %s: "
msgstr "Během stahování %s: "

#: common/flatpak-dir.c:6498
#, c-format
msgid "Wrong size for extra data %s"
msgstr "Chybná velikost pro dodatečná data %s"

#: common/flatpak-dir.c:6507
#, c-format
msgid "Invalid checksum for extra data %s"
msgstr "Neplatný kontrolní součet pro dodatečná data %s"

#: common/flatpak-dir.c:7096 common/flatpak-dir.c:7349
#, c-format
msgid "While pulling %s from remote %s: "
msgstr "Během stahování %s ze vzdáleného repozitáře %s: "

#: common/flatpak-dir.c:7290 common/flatpak-repo-utils.c:3886
msgid "GPG signatures found, but none are in trusted keyring"
msgstr "GPG podpisy nalezeny, ale žádný není ve svazku důvěryhodných klíčů"

#: common/flatpak-dir.c:7307
#, c-format
msgid "Commit for ‘%s’ has no ref binding"
msgstr ""

#: common/flatpak-dir.c:7312
#, c-format
msgid "Commit for ‘%s’ is not in expected bound refs: %s"
msgstr ""

#: common/flatpak-dir.c:7488
msgid "Only applications can be made current"
msgstr ""

#: common/flatpak-dir.c:8192
msgid "Not enough memory"
msgstr "Nedostatek paměti"

#: common/flatpak-dir.c:8211
msgid "Failed to read from exported file"
msgstr "Selhalo čtení z exportovaného souboru"

#: common/flatpak-dir.c:8401
msgid "Error reading mimetype xml file"
msgstr "Chyba při čtení mimetype xml souboru"

#: common/flatpak-dir.c:8406
msgid "Invalid mimetype xml file"
msgstr "Neplatný mimetype xml soubor"

#: common/flatpak-dir.c:8492
#, c-format
msgid "D-Bus service file '%s' has wrong name"
msgstr "Soubor služby D-Bus „%s“ má neplatný název"

#: common/flatpak-dir.c:8647
#, c-format
msgid "Invalid Exec argument %s"
msgstr "Neplatný Exec argument %s"

#: common/flatpak-dir.c:9115
msgid "While getting detached metadata: "
msgstr ""

#: common/flatpak-dir.c:9120 common/flatpak-dir.c:9125
#: common/flatpak-dir.c:9129
msgid "Extra data missing in detached metadata"
msgstr ""

#: common/flatpak-dir.c:9133
msgid "While creating extradir: "
msgstr ""

#: common/flatpak-dir.c:9154 common/flatpak-dir.c:9187
msgid "Invalid checksum for extra data"
msgstr "Neplatný kontrolní součet pro dodatečná data"

#: common/flatpak-dir.c:9183
msgid "Wrong size for extra data"
msgstr "Chybná velikost pro dodatečná data"

#: common/flatpak-dir.c:9196
#, c-format
msgid "While writing extra data file '%s': "
msgstr "Během zapisování souboru dodatečných dat „%s“: "

#: common/flatpak-dir.c:9204
#, c-format
msgid "Extra data %s missing in detached metadata"
msgstr ""

#: common/flatpak-dir.c:9278
#, c-format
msgid "Unable to get runtime key from metadata"
msgstr ""

#: common/flatpak-dir.c:9402
#, c-format
msgid "apply_extra script failed, exit status %d"
msgstr "apply_extra skript selhal, návratová hodnota %d"

#. Translators: The placeholder is for an app ref.
#: common/flatpak-dir.c:9591
#, c-format
msgid "Installing %s is not allowed by the policy set by your administrator"
msgstr ""
"Instalace aplikace %s není povolena bezpečnostní politikou, kterou nastavil "
"váš administrátor"

#: common/flatpak-dir.c:9690
#, c-format
msgid "While trying to resolve ref %s: "
msgstr "Během pokusu o vyřešení ref %s: "

#: common/flatpak-dir.c:9702
#, c-format
msgid "%s is not available"
msgstr "%s není dostupné"

#: common/flatpak-dir.c:9714 common/flatpak-dir.c:11495
#, c-format
msgid "%s commit %s already installed"
msgstr "%s commit %s je již nainstalováno"

#: common/flatpak-dir.c:9721
msgid "Can't create deploy directory"
msgstr "Nemohu vytvořit adresář sestavení"

#: common/flatpak-dir.c:9729
#, c-format
msgid "Failed to read commit %s: "
msgstr "Nelze číst commit %s: "

#: common/flatpak-dir.c:9750
#, c-format
msgid "While trying to checkout %s into %s: "
msgstr ""

#: common/flatpak-dir.c:9769
msgid "While trying to checkout metadata subpath: "
msgstr ""

#: common/flatpak-dir.c:9801
#, c-format
msgid "While trying to checkout subpath ‘%s’: "
msgstr ""

#: common/flatpak-dir.c:9811
msgid "While trying to remove existing extra dir: "
msgstr "Během pokusu o odstranění existujícího dodatečného adresáře: "

#: common/flatpak-dir.c:9822
msgid "While trying to apply extra data: "
msgstr "Během pokusu o aplikaci dodatečných dat: "

#: common/flatpak-dir.c:9849
#, c-format
msgid "Invalid commit ref %s: "
msgstr "Neplatný ref %s commitu: "

#: common/flatpak-dir.c:9857 common/flatpak-dir.c:9869
#, c-format
msgid "Deployed ref %s does not match commit (%s)"
msgstr ""

#: common/flatpak-dir.c:9863
#, c-format
msgid "Deployed ref %s branch does not match commit (%s)"
msgstr ""

#: common/flatpak-dir.c:10125 common/flatpak-installation.c:1911
#, c-format
msgid "%s branch %s already installed"
msgstr "%s větev %s je již nainstalováno"

#: common/flatpak-dir.c:10985
#, c-format
msgid "Could not unmount revokefs-fuse filesystem at %s: "
msgstr ""

#: common/flatpak-dir.c:11289
#, c-format
msgid "This version of %s is already installed"
msgstr "Tato verze aplikace %s je již nainstalována"

#: common/flatpak-dir.c:11302
#, c-format
msgid "Can't change remote during bundle install"
msgstr "Nemohu změnit vzdálený repozitář během instalace balíčku"

#: common/flatpak-dir.c:11571
msgid "Can't update to a specific commit without root permissions"
msgstr "Nelze aktualizovat na specifický commit bez root oprávnění"

#: common/flatpak-dir.c:11852
#, c-format
msgid "Can't remove %s, it is needed for: %s"
msgstr "Nelze odstranit %s, je požadováno pro: %s"

#: common/flatpak-dir.c:11912 common/flatpak-installation.c:2067
#, c-format
msgid "%s branch %s is not installed"
msgstr "%s větev %s není nainstalováno"

#: common/flatpak-dir.c:12165
#, c-format
msgid "%s commit %s not installed"
msgstr "%s commit %s nenainstalováno"

#: common/flatpak-dir.c:12501
#, c-format
msgid "Pruning repo failed: %s"
msgstr ""

#: common/flatpak-dir.c:12669 common/flatpak-dir.c:12675
#, c-format
msgid "Failed to load filter '%s'"
msgstr "Nelze načíst filtr „%s“"

#: common/flatpak-dir.c:12681
#, c-format
msgid "Failed to parse filter '%s'"
msgstr "Nelze zpracovat filtr „%s“"

#: common/flatpak-dir.c:12963
msgid "Failed to write summary cache: "
msgstr "Nelze zapsat cache shrnutí: "

#: common/flatpak-dir.c:12982
#, c-format
msgid "No oci summary cached for remote '%s'"
msgstr ""

#: common/flatpak-dir.c:13207
#, c-format
msgid "No cached summary for remote '%s'"
msgstr ""

#: common/flatpak-dir.c:13248
#, c-format
msgid "Invalid checksum for indexed summary %s read from %s"
msgstr ""

#: common/flatpak-dir.c:13321
#, c-format
msgid ""
"Remote listing for %s not available; server has no summary file. Check the "
"URL passed to remote-add was valid."
msgstr ""

#: common/flatpak-dir.c:13698
#, c-format
msgid "Invalid checksum for indexed summary %s for remote '%s'"
msgstr ""

#: common/flatpak-dir.c:14388
#, c-format
msgid "Multiple branches available for %s, you must specify one of: "
msgstr "Pro %s je dostupno více větví, musíte určit jednu z nich: "

#: common/flatpak-dir.c:14454
#, c-format
msgid "Nothing matches %s"
msgstr "Nic nevyhovuje názvu %s"

#: common/flatpak-dir.c:14562
#, c-format
msgid "Can't find ref %s%s%s%s%s"
msgstr "Nemohu nalézt ref %s%s%s%s%s"

#: common/flatpak-dir.c:14605
#, c-format
msgid "Error searching remote %s: %s"
msgstr "Chyba během prohledávání vzdáleného repozitáře %s: %s"

#: common/flatpak-dir.c:14702
#, c-format
msgid "Error searching local repository: %s"
msgstr "Chyba během prohledávání místního repozitáře: %s"

#: common/flatpak-dir.c:14839
#, c-format
msgid "%s/%s/%s not installed"
msgstr "%s/%s/%s nenainstalováno"

#: common/flatpak-dir.c:15042
#, c-format
msgid "Could not find installation %s"
msgstr "Nemohu nalézt instalaci %s"

#: common/flatpak-dir.c:15612
#, c-format
msgid "Invalid file format, no %s group"
msgstr "Neplatný formát souboru, žádná skupina %s"

#: common/flatpak-dir.c:15617 common/flatpak-repo-utils.c:2836
#, c-format
msgid "Invalid version %s, only 1 supported"
msgstr "Neplatná verze %s, pouze 1 je podporována"

#: common/flatpak-dir.c:15622 common/flatpak-dir.c:15627
#, c-format
msgid "Invalid file format, no %s specified"
msgstr "Neplatný formát souboru, %s není určen"

#. Check some minimal size so we don't get crap
#: common/flatpak-dir.c:15647
msgid "Invalid file format, gpg key invalid"
msgstr "Neplatný formát souboru, neplatný klíč gpg"

#: common/flatpak-dir.c:15675 common/flatpak-repo-utils.c:2917
msgid "Collection ID requires GPG key to be provided"
msgstr "ID kolekce vyžaduje poskytnutí GPG klíče"

#: common/flatpak-dir.c:15718
#, c-format
msgid "Runtime %s, branch %s is already installed"
msgstr "Prostředí %s, větev %s je již nainstalováno"

#: common/flatpak-dir.c:15719
#, c-format
msgid "App %s, branch %s is already installed"
msgstr "Aplikace %s, větev %s je již nainstalováno"

#: common/flatpak-dir.c:15953
#, c-format
msgid "Can't remove remote '%s' with installed ref %s (at least)"
msgstr ""
"Nelze odstranit vzdálený repozitář „%s“ s nainstalovaným refem %s (minimálně)"

#: common/flatpak-dir.c:16058
#, c-format
msgid "Invalid character '/' in remote name: %s"
msgstr "Neplatný znak „/“ v názvu vzdáleného repozitáře: %s"

#: common/flatpak-dir.c:16064
#, c-format
msgid "No configuration for remote %s specified"
msgstr "Neurčena žádná konfigurace pro vzdálený repozitář %s"

#: common/flatpak-dir.c:17597
#, c-format
msgid "Skipping deletion of mirror ref (%s, %s)…\n"
msgstr ""

#: common/flatpak-exports.c:931
#, c-format
msgid "An absolute path is required"
msgstr "Je vyžadována absolutní cesta"

#: common/flatpak-exports.c:948
#, c-format
msgid "Unable to open path \"%s\": %s"
msgstr "Nelze otevřít cestu „%s“: %s"

#: common/flatpak-exports.c:955
#, c-format
msgid "Unable to get file type of \"%s\": %s"
msgstr "Selhalo získání typu souboru „%s“: %s"

#: common/flatpak-exports.c:964
#, c-format
msgid "File \"%s\" has unsupported type 0o%o"
msgstr "Soubor „%s“ má nepodporovaný typ 0o%o"

#: common/flatpak-exports.c:970
#, c-format
msgid "Unable to get filesystem information for \"%s\": %s"
msgstr "Selhalo získání informací o souborovém systému pro „%s“: %s"

#: common/flatpak-exports.c:980
#, c-format
msgid "Ignoring blocking autofs path \"%s\""
msgstr ""

#: common/flatpak-exports.c:996 common/flatpak-exports.c:1009
#: common/flatpak-exports.c:1022
#, c-format
msgid "Path \"%s\" is reserved by Flatpak"
msgstr "Cesta „%s“ je rezervována Flatpakem"

#: common/flatpak-exports.c:1076
#, c-format
msgid "Unable to resolve symbolic link \"%s\": %s"
msgstr "Selhal překlad symbolického odkazu „%s“: %s"

#: common/flatpak-glib-backports.c:69
msgid "Empty string is not a number"
msgstr "Prázdný řetězec není číslo"

#: common/flatpak-glib-backports.c:95
#, c-format
msgid "“%s” is not an unsigned number"
msgstr "„%s“ není číslo bez znaménka"

#: common/flatpak-glib-backports.c:105
#, c-format
msgid "Number “%s” is out of bounds [%s, %s]"
msgstr ""

#: common/flatpak-image-source.c:83
msgid "Only sha256 image checksums are supported"
msgstr ""

#: common/flatpak-image-source.c:100 common/flatpak-image-source.c:108
msgid "Image is not a manifest"
msgstr "Obraz není manifest"

#: common/flatpak-image-source.c:123
msgid "No org.flatpak.ref found in image"
msgstr ""

#: common/flatpak-image-source.c:148
#, c-format
msgid "Ref '%s' not found in registry"
msgstr "Ref „%s“ nebyl nalezen v registru"

#: common/flatpak-image-source.c:157
msgid "Multiple images in registry, specify a ref with --ref"
msgstr "Více obrazů v registru, určete ref pomocí --ref"

#: common/flatpak-installation.c:834
#, c-format
msgid "Ref %s not installed"
msgstr "Ref %s není nainstalován"

#: common/flatpak-installation.c:875
#, c-format
msgid "App %s not installed"
msgstr "Aplikace %s není nainstalována"

#: common/flatpak-installation.c:1395
#, c-format
msgid "Remote '%s' already exists"
msgstr "Vzdálený repozitář „%s“ již existuje"

#: common/flatpak-installation.c:1946
#, c-format
msgid "As requested, %s was only pulled, but not installed"
msgstr "Jak bylo požadováno, %s bylo pouze staženo, ale nebylo nainstalováno"

#: common/flatpak-instance.c:533 common/flatpak-instance.c:687
#: common/flatpak-instance.c:728
#, c-format
msgid "Unable to create directory %s"
msgstr "Selhalo vytvoření adresáře %s"

#: common/flatpak-instance.c:554
#, c-format
msgid "Unable to lock %s"
msgstr "Selhalo uzamčení %s"

#: common/flatpak-instance.c:627
#, c-format
msgid "Unable to create temporary directory in %s"
msgstr "Selhalo vytvoření dočasného adresáře %s"

#: common/flatpak-instance.c:639
#, c-format
msgid "Unable to create file %s"
msgstr "Selhalo vytvoření souboru %s"

#: common/flatpak-instance.c:646
#, c-format
msgid "Unable to update symbolic link %s/%s"
msgstr "Selhala aktualizace symbolického odkazu %s/%s"

#: common/flatpak-oci-registry.c:1197
msgid "Only Bearer authentication supported"
msgstr ""

#: common/flatpak-oci-registry.c:1206
msgid "Only realm in authentication request"
msgstr ""

#: common/flatpak-oci-registry.c:1213
msgid "Invalid realm in authentication request"
msgstr ""

#: common/flatpak-oci-registry.c:1283
#, c-format
msgid "Authorization failed: %s"
msgstr "Autorizace selhala: %s"

#: common/flatpak-oci-registry.c:1285
msgid "Authorization failed"
msgstr "Autorizace selhala"

#: common/flatpak-oci-registry.c:1289
#, c-format
msgid "Unexpected response status %d when requesting token: %s"
msgstr ""

#: common/flatpak-oci-registry.c:1300
msgid "Invalid authentication request response"
msgstr ""

#: common/flatpak-oci-registry.c:1731
#, c-format
msgid "Flatpak was compiled without zstd support"
msgstr ""

#: common/flatpak-oci-registry.c:1923 common/flatpak-oci-registry.c:1975
#: common/flatpak-oci-registry.c:2004 common/flatpak-oci-registry.c:2059
#: common/flatpak-oci-registry.c:2115 common/flatpak-oci-registry.c:2193
msgid "Invalid delta file format"
msgstr "Neplatný formát souboru delta"

#: common/flatpak-oci-registry.c:3198 common/flatpak-oci-registry.c:3382
msgid "Invalid OCI image config"
msgstr "Neplatná konfigurace OCI obrazu"

#: common/flatpak-oci-registry.c:3260 common/flatpak-oci-registry.c:3531
#, c-format
msgid "Wrong layer checksum, expected %s, was %s"
msgstr ""

#: common/flatpak-oci-registry.c:3359
#, c-format
msgid "No ref specified for OCI image %s"
msgstr "Neurčen žádný ref pro OCI obraz %s"

#: common/flatpak-oci-registry.c:3369
#, c-format
msgid "Wrong ref (%s) specified for OCI image %s, expected %s"
msgstr "Špatný ref (%s) určen pro OCI obraz %s, očekáváno %s"

#: common/flatpak-progress.c:236
#, c-format
msgid "Downloading metadata: %u/(estimating) %s"
msgstr "Stahují se metadata: %u/(odhadováno) %s"

#: common/flatpak-progress.c:260
#, c-format
msgid "Downloading: %s/%s"
msgstr "Stahuje se: %s/%s"

#: common/flatpak-progress.c:280
#, c-format
msgid "Downloading extra data: %s/%s"
msgstr "Stahují se dodatečná data: %s/%s"

#: common/flatpak-progress.c:285
#, c-format
msgid "Downloading files: %d/%d %s"
msgstr "Stahují se soubory: %d/%d %s"

#: common/flatpak-ref-utils.c:122
msgid "Name can't be empty"
msgstr "Název nemůže být prázdný"

#: common/flatpak-ref-utils.c:129
msgid "Name can't be longer than 255 characters"
msgstr "Název nemůže být delší než 255 znaků"

#: common/flatpak-ref-utils.c:142
msgid "Name can't start with a period"
msgstr "Název nemůže začínat tečkou"

#: common/flatpak-ref-utils.c:148
#, c-format
msgid "Name can't start with %c"
msgstr "Název nemůže začínat %c"

#: common/flatpak-ref-utils.c:164
msgid "Name can't end with a period"
msgstr "Název nemůže končit tečkou"

#: common/flatpak-ref-utils.c:171 common/flatpak-ref-utils.c:183
msgid "Only last name segment can contain -"
msgstr "Pouze poslední část názvu může obsahovat -"

#: common/flatpak-ref-utils.c:174
#, c-format
msgid "Name segment can't start with %c"
msgstr "Část názvu nemůže začínat %c"

#: common/flatpak-ref-utils.c:186
#, c-format
msgid "Name can't contain %c"
msgstr "Název nemůže obsahovat %c"

#: common/flatpak-ref-utils.c:195
msgid "Names must contain at least 2 periods"
msgstr "Názvy musí obsahovat alespoň dvě tečky"

#: common/flatpak-ref-utils.c:312
msgid "Arch can't be empty"
msgstr "Architektura nemůže být prázdná"

#: common/flatpak-ref-utils.c:323
#, c-format
msgid "Arch can't contain %c"
msgstr "Architektura nemůže obsahovat %c"

#: common/flatpak-ref-utils.c:385
msgid "Branch can't be empty"
msgstr "Větev nemůže být prázdná"

#: common/flatpak-ref-utils.c:395
#, c-format
msgid "Branch can't start with %c"
msgstr "Větev nemůže začínat %c"

#: common/flatpak-ref-utils.c:405
#, c-format
msgid "Branch can't contain %c"
msgstr "Větev nemůže obsahovat %c"

#: common/flatpak-ref-utils.c:615 common/flatpak-ref-utils.c:865
msgid "Ref too long"
msgstr "Ref je příliš dlouhý"

#: common/flatpak-ref-utils.c:627
msgid "Invalid remote name"
msgstr "Neplatný název vzdáleného repozitáře"

#: common/flatpak-ref-utils.c:641
#, c-format
msgid "%s is not application or runtime"
msgstr "%s není aplikace nebo prostředí"

#: common/flatpak-ref-utils.c:650 common/flatpak-ref-utils.c:667
#: common/flatpak-ref-utils.c:683
#, c-format
msgid "Wrong number of components in %s"
msgstr "Špatný počet součástí v %s"

#: common/flatpak-ref-utils.c:656
#, c-format
msgid "Invalid name %.*s: %s"
msgstr "Neplatný název %.*s: %s"

#: common/flatpak-ref-utils.c:673
#, c-format
msgid "Invalid arch: %.*s: %s"
msgstr "Neplatná architektura: %.*s: %s"

#: common/flatpak-ref-utils.c:816
#, c-format
msgid "Invalid name %s: %s"
msgstr "Neplatný název %s: %s"

#: common/flatpak-ref-utils.c:834
#, c-format
msgid "Invalid arch: %s: %s"
msgstr "Neplatná architektura: %s: %s"

#: common/flatpak-ref-utils.c:853
#, c-format
msgid "Invalid branch: %s: %s"
msgstr "Neplatná větev: %s: %s"

#: common/flatpak-ref-utils.c:962 common/flatpak-ref-utils.c:970
#: common/flatpak-ref-utils.c:978
#, c-format
msgid "Wrong number of components in partial ref %s"
msgstr "Špatný počet součástí v částečném refu %s"

#: common/flatpak-ref-utils.c:1298
msgid " development platform"
msgstr " vývojová platforma"

#: common/flatpak-ref-utils.c:1300
msgid " platform"
msgstr " platforma"

#: common/flatpak-ref-utils.c:1302
msgid " application base"
msgstr " základ aplikace"

#: common/flatpak-ref-utils.c:1305
msgid " debug symbols"
msgstr " ladicí symboly"

#: common/flatpak-ref-utils.c:1307
msgid " sourcecode"
msgstr " zdrojový kód"

#: common/flatpak-ref-utils.c:1309
msgid " translations"
msgstr " překlady"

#: common/flatpak-ref-utils.c:1311
msgid " docs"
msgstr " dokumentace"

#: common/flatpak-ref-utils.c:1578
#, c-format
msgid "Invalid id %s: %s"
msgstr "Neplatné id %s: %s"

#: common/flatpak-remote.c:1216
#, c-format
msgid "Bad remote name: %s"
msgstr "Neplatný název vzdáleného repozitáře: %s"

#: common/flatpak-remote.c:1220
#, fuzzy
msgid "No URL specified"
msgstr "Neurčen žádný url"

#: common/flatpak-remote.c:1266
msgid "GPG verification must be enabled when a collection ID is set"
msgstr "Ověřování pomocí GPG musí být povoleno, pokud je nastaveno ID kolekce"

#: common/flatpak-repo-utils.c:344
#, c-format
msgid "No extra data sources"
msgstr "Žádné zdroje dodatečných dat"

#: common/flatpak-repo-utils.c:2817
#, c-format
msgid "Invalid %s: Missing group ‘%s’"
msgstr "Neplatný %s: Chybí skupina „%s“"

#: common/flatpak-repo-utils.c:2826
#, c-format
msgid "Invalid %s: Missing key ‘%s’"
msgstr "Neplatný %s: Chybí klíč „%s“"

#: common/flatpak-repo-utils.c:2876
msgid "Invalid gpg key"
msgstr "Neplatný klíč gpg"

#: common/flatpak-repo-utils.c:3217
#, c-format
msgid "Error copying 64x64 icon for component %s: %s\n"
msgstr "Chyba během kopírování 64x64 ikony pro součást %s: %s\n"

#: common/flatpak-repo-utils.c:3223
#, c-format
msgid "Error copying 128x128 icon for component %s: %s\n"
msgstr "Chyba během kopírování 128x128 ikony pro součást %s: %s\n"

#: common/flatpak-repo-utils.c:3362
#, c-format
msgid "%s is end-of-life, ignoring for appstream"
msgstr "%s je end-of-life, ignoruje se pro appstream"

#: common/flatpak-repo-utils.c:3397
#, c-format
msgid "No appstream data for %s: %s\n"
msgstr "Žádná appstream data pro %s: %s\n"

#: common/flatpak-repo-utils.c:3744
msgid "Invalid bundle, no ref in metadata"
msgstr ""

#: common/flatpak-repo-utils.c:3846
#, c-format
msgid "Collection ‘%s’ of bundle doesn’t match collection ‘%s’ of remote"
msgstr ""

#: common/flatpak-repo-utils.c:3923
msgid "Metadata in header and app are inconsistent"
msgstr "Metadata ve hlavičce a aplikaci jsou nekonzistentní"

#: common/flatpak-run.c:951
msgid "No systemd user session available, cgroups not available"
msgstr "Uživatelské sezení systemd není dostupné, cgroups nejsou dostupné"

#: common/flatpak-run.c:1496
msgid "Unable to allocate instance id"
msgstr "Selhala alokace id instance"

#: common/flatpak-run.c:1632 common/flatpak-run.c:1641
#, c-format
msgid "Failed to open flatpak-info file: %s"
msgstr "Selhalo otevření souboru flatpak-info: %s"

#: common/flatpak-run.c:1668
#, c-format
msgid "Failed to open bwrapinfo.json file: %s"
msgstr "Selhalo otevření souboru bwrapinfo.json: %s"

#: common/flatpak-run.c:1689
#, c-format
msgid "Failed to write to instance id fd: %s"
msgstr ""

#: common/flatpak-run.c:2096
msgid "Initialize seccomp failed"
msgstr "Selhala inicializace seccomp"

#: common/flatpak-run.c:2135
#, c-format
msgid "Failed to add architecture to seccomp filter: %s"
msgstr "Selhalo přidání architektury do seccomp filtru: %s"

#: common/flatpak-run.c:2143
#, c-format
msgid "Failed to add multiarch architecture to seccomp filter: %s"
msgstr "Selhalo přidání multiarch architektury do seccomp filtru: %s"

#: common/flatpak-run.c:2175 common/flatpak-run.c:2192
#: common/flatpak-run.c:2214
#, c-format
msgid "Failed to block syscall %d: %s"
msgstr "Selhalo blokování systémového volání %d: %s"

#: common/flatpak-run.c:2247
#, c-format
msgid "Failed to export bpf: %s"
msgstr "Selhalo exportování bpf: %s"

#: common/flatpak-run.c:2587
#, c-format
msgid "Failed to open ‘%s’"
msgstr "Selhalo otevření „%s“"

#: common/flatpak-run.c:2597
#, c-format
msgid ""
"Directory forwarding needs version 4 of the document portal (have version %d)"
msgstr ""

#: common/flatpak-run.c:2915
#, c-format
msgid "ldconfig failed, exit status %d"
msgstr "ldconfig selhal, návratová hodnota %d"

#: common/flatpak-run.c:2922
msgid "Can't open generated ld.so.cache"
msgstr "Nelze otevřít vygenerovaný ld.so.cache"

#. Translators: The placeholder is for an app ref.
#: common/flatpak-run.c:3045
#, c-format
msgid "Running %s is not allowed by the policy set by your administrator"
msgstr ""
"Spouštění aplikace %s není povoleno bezpečnostní politikou, kterou nastavil "
"váš administrátor"

#: common/flatpak-run.c:3202
msgid ""
"\"flatpak run\" is not intended to be run as `sudo flatpak run`. Use `sudo "
"-i` or `su -l` instead and invoke \"flatpak run\" from inside the new shell."
msgstr ""
"Příkaz „flatpak run“ není určen ke spuštění jako „sudo flatpak run“. Místo "
"toho použijte `sudo -i` nebo `su -l` a ​​vyvolejte „flatpak run“ z nového "
"shellu."

#: common/flatpak-run.c:3413
#, c-format
msgid "Failed to migrate from %s: %s"
msgstr "Selhala migrace z %s: %s"

#: common/flatpak-run.c:3434
#, c-format
msgid "Failed to migrate old app data directory %s to new name %s: %s"
msgstr "Selhala migrace starého adresáře dat aplikace %s na nový název %s: %s"

#: common/flatpak-run.c:3443
#, c-format
msgid "Failed to create symlink while migrating %s: %s"
msgstr "Selhalo vytváření symlinku během migrace %s: %s"

#: common/flatpak-run-dbus.c:46
msgid "Failed to open app info file"
msgstr "Selhalo otevření souboru s informacemi o aplikaci"

#: common/flatpak-run-dbus.c:149
msgid "Unable to create sync pipe"
msgstr "Selhalo vytvoření synchronizační roury"

#: common/flatpak-run-dbus.c:185
msgid "Failed to sync with dbus proxy"
msgstr "Selhala synchronizace s dbus proxy"

#: common/flatpak-transaction.c:2275
#, c-format
msgid "Warning: Problem looking for related refs: %s"
msgstr "Varování: Problém při hledání souvisejících refů: %s"

#: common/flatpak-transaction.c:2493
#, c-format
msgid "The application %s requires the runtime %s which was not found"
msgstr "Aplikace %s vyžaduje prostředí %s, které nebylo nalezeno"

#: common/flatpak-transaction.c:2509
#, c-format
msgid "The application %s requires the runtime %s which is not installed"
msgstr "Aplikace %s vyžaduje prostředí %s, které není nainstalováno"

#: common/flatpak-transaction.c:2641
#, c-format
msgid "Can't uninstall %s which is needed by %s"
msgstr "Nelze odinstalovat %s, který je vyžadován %s"

#: common/flatpak-transaction.c:2740
#, c-format
msgid "Remote %s disabled, ignoring %s update"
msgstr "Vzdálený repozitář %s je zakázán, ignoruje se aktualizace %s"

#: common/flatpak-transaction.c:2773
#, c-format
msgid "%s is already installed"
msgstr "%s je již nainstalováno"

#: common/flatpak-transaction.c:2776
#, c-format
msgid "%s is already installed from remote %s"
msgstr "%s je již nainstalováno ze vzdáleného repozitáře %s"

#: common/flatpak-transaction.c:3120
#, c-format
msgid "Invalid .flatpakref: %s"
msgstr "Neplatný .flatpakref: %s"

#: common/flatpak-transaction.c:3161
msgid "Warning: Could not mark already installed apps as preinstalled"
msgstr ""

#: common/flatpak-transaction.c:3382
#, c-format
msgid "Error updating remote metadata for '%s': %s"
msgstr "Chyba během aktualizace vzdálených metadat pro „%s“: %s"

#: common/flatpak-transaction.c:3885
#, c-format
msgid ""
"Warning: Treating remote fetch error as non-fatal since %s is already "
"installed: %s"
msgstr ""
"Varování: Chyba načtení vzdáleného repozitáře není považována za závažnou, "
"protože %s je již nainstalováno: %s"

#: common/flatpak-transaction.c:4209
#, c-format
msgid "No authenticator installed for remote '%s'"
msgstr "Nenainstalován žádný autentikátor pro vzdálený repozitář „%s“"

#: common/flatpak-transaction.c:4313 common/flatpak-transaction.c:4320
#, c-format
msgid "Failed to get tokens for ref: %s"
msgstr "Selhalo získání tokenů pro ref: %s"

#: common/flatpak-transaction.c:4315 common/flatpak-transaction.c:4322
msgid "Failed to get tokens for ref"
msgstr "Selhalo získání tokenů pro ref"

#: common/flatpak-transaction.c:4580
#, c-format
msgid "Ref %s from %s matches more than one transaction operation"
msgstr ""

#: common/flatpak-transaction.c:4581 common/flatpak-transaction.c:4591
msgid "any remote"
msgstr "libovolný vzdálený repozitář"

#: common/flatpak-transaction.c:4590
#, c-format
msgid "No transaction operation found for ref %s from %s"
msgstr ""

#: common/flatpak-transaction.c:4713
#, c-format
msgid "Flatpakrepo URL %s not file, HTTP or HTTPS"
msgstr "Flatpakrepo URL %s není soubor, HTTP nebo HTTPS"

#: common/flatpak-transaction.c:4719
#, c-format
msgid "Can't load dependent file %s: "
msgstr ""

#: common/flatpak-transaction.c:4727
#, c-format
msgid "Invalid .flatpakrepo: %s"
msgstr "Neplatné .flatpakrepo: %s"

#: common/flatpak-transaction.c:5454
msgid "Transaction already executed"
msgstr "Transakce již běží"

#: common/flatpak-transaction.c:5469
msgid ""
"Refusing to operate on a user installation as root! This can lead to "
"incorrect file ownership and permission errors."
msgstr ""
"Odmítnuta operace na uživatelské instalaci jako root! Toto může vést k "
"nesprávným vlastnictvím souborů a chybám s oprávněními."

#: common/flatpak-transaction.c:5567 common/flatpak-transaction.c:5580
msgid "Aborted by user"
msgstr "Přerušeno uživatelem"

#: common/flatpak-transaction.c:5605
#, c-format
msgid "Skipping %s due to previous error"
msgstr "Přeskakuje se %s z důvodu předchozí chyby"

#: common/flatpak-transaction.c:5659
#, c-format
msgid "Aborted due to failure (%s)"
msgstr "Přerušeno z důvodu selhání (%s)"

#: common/flatpak-uri.c:118
#, no-c-format
msgid "Invalid %-encoding in URI"
msgstr "Neplatné %-kódování v URI"

#: common/flatpak-uri.c:135
msgid "Illegal character in URI"
msgstr "Neplatný znak v URI"

#: common/flatpak-uri.c:169
msgid "Non-UTF-8 characters in URI"
msgstr "Znaky jiné než UTF-8 v URI"

#: common/flatpak-uri.c:275
#, c-format
msgid "Invalid IPv6 address ‘%.*s’ in URI"
msgstr "Neplatná adresa IPv6 „%.*s“ v URI"

#: common/flatpak-uri.c:330
#, c-format
msgid "Illegal encoded IP address ‘%.*s’ in URI"
msgstr "Neplatně kódovaná IP adresa „%.*s“ v URI"

#: common/flatpak-uri.c:342
#, c-format
msgid "Illegal internationalized hostname ‘%.*s’ in URI"
msgstr "Neplatný internacionalizovaný název hostitele „%.*s“ v URI"

#: common/flatpak-uri.c:374 common/flatpak-uri.c:386
#, c-format
msgid "Could not parse port ‘%.*s’ in URI"
msgstr "Port „%.*s“ v URI nelze zpracovat"

#: common/flatpak-uri.c:393
#, c-format
msgid "Port ‘%.*s’ in URI is out of range"
msgstr "Port „%.*s“ v URI je mimo rozsah"

#: common/flatpak-uri.c:910
msgid "URI is not absolute, and no base URI was provided"
msgstr "URI není absolutní a nebyl poskytnut žádný základní URI"

#: common/flatpak-usb.c:83
#, c-format
msgid "USB device query 'all' must not have data"
msgstr ""

#: common/flatpak-usb.c:102
#, c-format
msgid "USB query rule 'cls' must be in the form CLASS:SUBCLASS or CLASS:*"
msgstr ""

#: common/flatpak-usb.c:111
#, c-format
msgid "Invalid USB class"
msgstr "Neplatná třída USB"

#: common/flatpak-usb.c:125
#, c-format
msgid "Invalid USB subclass"
msgstr "Neplatná podtřída USB"

#: common/flatpak-usb.c:141 common/flatpak-usb.c:148
#, c-format
msgid "USB query rule 'dev' must have a valid 4-digit hexadecimal product id"
msgstr ""

#: common/flatpak-usb.c:164 common/flatpak-usb.c:171
#, c-format
msgid "USB query rule 'vnd' must have a valid 4-digit hexadecimal vendor id"
msgstr ""

#: common/flatpak-usb.c:205
#, c-format
msgid "USB device queries must be in the form TYPE:DATA"
msgstr ""

#: common/flatpak-usb.c:225
#, c-format
msgid "Unknown USB query rule %s"
msgstr ""

#: common/flatpak-usb.c:248
#, c-format
msgid "Empty USB query"
msgstr ""

#: common/flatpak-usb.c:274
#, c-format
msgid "Multiple USB query rules of the same type is not supported"
msgstr ""

#: common/flatpak-usb.c:283
#, c-format
msgid "'all' must not contain extra query rules"
msgstr ""

#: common/flatpak-usb.c:291
#, c-format
msgid "USB queries with 'dev' must also specify vendors"
msgstr ""

#: common/flatpak-utils.c:712
msgid "Glob can't match apps"
msgstr ""

#: common/flatpak-utils.c:737
msgid "Empty glob"
msgstr ""

#: common/flatpak-utils.c:756
msgid "Too many segments in glob"
msgstr ""

#: common/flatpak-utils.c:777
#, c-format
msgid "Invalid glob character '%c'"
msgstr ""

#: common/flatpak-utils.c:831
#, c-format
msgid "Missing glob on line %d"
msgstr ""

#: common/flatpak-utils.c:835
#, c-format
msgid "Trailing text on line %d"
msgstr ""

#: common/flatpak-utils.c:839
#, c-format
msgid "on line %d"
msgstr "na řádku %d"

#: common/flatpak-utils.c:861
#, c-format
msgid "Unexpected word '%s' on line %d"
msgstr "Neočekávané slovo „%s“ na řádku %d"

#: common/flatpak-utils.c:2118
#, c-format
msgid "Invalid require-flatpak argument %s"
msgstr "Neplatný require-flatpak argument %s"

#: common/flatpak-utils.c:2128 common/flatpak-utils.c:2147
#, c-format
msgid "%s needs a later flatpak version (%s)"
msgstr "%s vyžaduje novější verzi flatpaku (%s)"

#: oci-authenticator/flatpak-oci-authenticator.c:291
msgid "Not a oci remote, missing summary.xa.oci-repository"
msgstr "Není vzdálený repozitář oci, chybí summary.xa.oci-repository"

#: oci-authenticator/flatpak-oci-authenticator.c:477
msgid "Not a OCI remote"
msgstr "Není vzdálený repozitář OCI"

#: oci-authenticator/flatpak-oci-authenticator.c:488
msgid "Invalid token"
msgstr "Neplatný token"

#: portal/flatpak-portal.c:2292
#, c-format
msgid "No portal support found"
msgstr "Nenalezena podpora portálů"

#: portal/flatpak-portal.c:2298
msgid "Deny"
msgstr "Zamítnout"

#: portal/flatpak-portal.c:2300
msgid "Update"
msgstr "Aktualizovat"

#: portal/flatpak-portal.c:2305
#, c-format
msgid "Update %s?"
msgstr "Aktualizovat %s?"

#: portal/flatpak-portal.c:2317
msgid "The application wants to update itself."
msgstr "Tato aplikace se chce sama aktualizovat."

#: portal/flatpak-portal.c:2318
msgid "Update access can be changed any time from the privacy settings."
msgstr "Přístup k aktualizacím můžete kdykoliv změnit v nastavení soukromí."

#: portal/flatpak-portal.c:2343
#, c-format
msgid "Application update not allowed"
msgstr "Aktualizace aplikace nepovolena"

#: portal/flatpak-portal.c:2501
#, c-format
msgid "Self update not supported, new version requires new permissions"
msgstr ""
"Aktualizace sebe sama není podporována, nová verze vyžaduje nové oprávnění"

#: portal/flatpak-portal.c:2684 portal/flatpak-portal.c:2702
#, c-format
msgid "Update ended unexpectedly"
msgstr "Aktualizace byla neočekávaně ukončena"

#. SECURITY:
#. - Normal users need admin authentication to install software
#. system-wide.
#. - Note that we install polkit rules that allow local users
#. in the wheel group to install without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:23
msgid "Install signed application"
msgstr "Instalovat podepsanou aplikaci"

#: system-helper/org.freedesktop.Flatpak.policy.in:24
#: system-helper/org.freedesktop.Flatpak.policy.in:42
msgid "Authentication is required to install software"
msgstr "K instalaci softwaru je vyžadováno ověření"

#. SECURITY:
#. - Normal users need admin authentication to install software
#. system-wide.
#. - Note that we install polkit rules that allow local users
#. in the wheel group to install without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:41
msgid "Install signed runtime"
msgstr "Instalovat podepsané prostředí"

#. SECURITY:
#. - Normal users do not require admin authentication to update an
#. app as the commit will be signed, and the action is required
#. to update the system when unattended.
#. - Changing this to anything other than 'yes' will break unattended
#. updates.
#: system-helper/org.freedesktop.Flatpak.policy.in:60
msgid "Update signed application"
msgstr "Aktualizovat podepsanou aplikaci"

#: system-helper/org.freedesktop.Flatpak.policy.in:61
#: system-helper/org.freedesktop.Flatpak.policy.in:80
msgid "Authentication is required to update software"
msgstr "K aktualizaci softwaru je vyžadováno ověření"

#. SECURITY:
#. - Normal users do not require admin authentication to update a
#. runtime as the commit will be signed, and the action is required
#. to update the system when unattended.
#. - Changing this to anything other than 'yes' will break unattended
#. updates.
#: system-helper/org.freedesktop.Flatpak.policy.in:79
msgid "Update signed runtime"
msgstr "Aktualizovat podepsané prostředí"

#. SECURITY:
#. - Normal users do not need authentication to update metadata
#. from signed repositories.
#: system-helper/org.freedesktop.Flatpak.policy.in:94
msgid "Update remote metadata"
msgstr "Aktualizovat vzdálená metadata"

#: system-helper/org.freedesktop.Flatpak.policy.in:95
msgid "Authentication is required to update remote info"
msgstr "K aktualizaci vzdálených informací je vyžadováno ověření"

#. SECURITY:
#. - Normal users do not need authentication to modify the
#. OSTree repository
#. - Note that we install polkit rules that allow local users
#. in the wheel group to modify repos without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:111
msgid "Update system repository"
msgstr "Aktualizovat systémový repozitář"

#: system-helper/org.freedesktop.Flatpak.policy.in:112
msgid "Authentication is required to modify a system repository"
msgstr "K úpravě systémového repozitáře je vyžadováno ověření"

#. SECURITY:
#. - Normal users need admin authentication to install software
#. system-wide.
#: system-helper/org.freedesktop.Flatpak.policy.in:126
msgid "Install bundle"
msgstr "Instalovat balík"

#: system-helper/org.freedesktop.Flatpak.policy.in:127
msgid "Authentication is required to install software from $(path)"
msgstr "K instalaci softwaru z $(path) je vyžadováno ověření"

#. SECURITY:
#. - Normal users need admin authentication to uninstall software
#. system-wide.
#. - Note that we install polkit rules that allow local users
#. in the wheel group to uninstall without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:144
msgid "Uninstall runtime"
msgstr "Odinstalovat prostředí"

#: system-helper/org.freedesktop.Flatpak.policy.in:145
msgid "Authentication is required to uninstall software"
msgstr "K odinstalování softwaru je vyžadováno ověření"

#. SECURITY:
#. - Normal users need admin authentication to uninstall software
#. system-wide.
#. - Note that we install polkit rules that allow local users
#. in the wheel group to uninstall without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:161
msgid "Uninstall app"
msgstr "Odinstalovat aplikaci"

#: system-helper/org.freedesktop.Flatpak.policy.in:162
msgid "Authentication is required to uninstall $(ref)"
msgstr "K odinstalování refu $(ref) je vyžadováno ověření"

#. SECURITY:
#. - Normal users need admin authentication to configure system-wide
#. software repositories.
#: system-helper/org.freedesktop.Flatpak.policy.in:177
msgid "Configure Remote"
msgstr "Nastavit vzdálený repozitář"

#: system-helper/org.freedesktop.Flatpak.policy.in:178
msgid "Authentication is required to configure software repositories"
msgstr "K nastavení repozitářů softwaru je vyžadováno ověření"

#. SECURITY:
#. - Normal users need admin authentication to configure the system-wide
#. Flatpak installation.
#: system-helper/org.freedesktop.Flatpak.policy.in:192
msgid "Configure"
msgstr "Nastavit"

#: system-helper/org.freedesktop.Flatpak.policy.in:193
msgid "Authentication is required to configure software installation"
msgstr "K nastavení instalace softwaru je vyžadováno ověření"

#. SECURITY:
#. - Normal users do not require admin authentication to update
#. appstream data as it will be signed, and the action is required
#. to update the system when unattended.
#. - Changing this to anything other than 'yes' will break unattended
#. updates.
#: system-helper/org.freedesktop.Flatpak.policy.in:210
msgid "Update appstream"
msgstr "Aktualizovat appstream"

#: system-helper/org.freedesktop.Flatpak.policy.in:211
msgid "Authentication is required to update information about software"
msgstr "K aktualizaci informací o softwaru je vyžadováno ověření"

#. SECURITY:
#. - Normal users do not require admin authentication to update
#. metadata as it will be signed, and the action is required
#. to update the system when unattended.
#. - Changing this to anything other than 'yes' will break unattended
#. updates.
#: system-helper/org.freedesktop.Flatpak.policy.in:228
msgid "Update metadata"
msgstr "Aktualizovat metadata"

#: system-helper/org.freedesktop.Flatpak.policy.in:229
msgid "Authentication is required to update metadata"
msgstr "K aktualizaci metadat je vyžadováno ověření"

#. SECURITY:
#. - Authorisation to actually install software is controlled by
#. org.freedesktop.Flatpak.app-install.
#. - This action is checked after app-install, as it can only be done
#. once the app’s data (including its content rating) has been
#. downloaded.
#. - This action is checked to see if the installation should be allowed
#. based on whether the app being installed has content which doesn’t
#. comply with the user’s parental controls policy (the content is
#. ‘too extreme’).
#. - It is checked only if an app has too extreme content for the user
#. who is trying to install it (in which case, the app is ‘unsafe’).
#. - Typically, normal users will need admin permission to install apps
#. with extreme content; admins will be able to install it without
#. additional checks.
#. - In order to configure the policy so that admins can install safe and
#. unsafe software anywhere without authorisation, and non-admins can
#. install safe software in their user or system dirs without
#. authorisation, but need authorisation to install unsafe software
#. anywhere:
#. * Unconditionally return `yes` from `app-install`.
#. * Return `auth_admin` from `override-parental-controls` for users
#. not in `@privileged_group@`, and `yes` for users in it.
#. * Set the malcontent `is-{user,system}-installation-allowed`
#. properties of all non-admins’ parental controls policies to true.
#. - In order to configure the policy so that admins can install safe and
#. unsafe software anywhere without authorisation, and non-admins can
#. install safe software in their user dir without authorisation, but
#. need authorisation to install safe software in the system dir or to
#. install unsafe software anywhere:
#. * Unconditionally return `yes` from `app-install`.
#. * Return `auth_admin` from `override-parental-controls` for users
#. not in `@privileged_group@`, and `yes` for users in it.
#. * Set the malcontent `is-user-installation-allowed` property of all
#. non-admins’ parental controls policies to true.
#. * Set the malcontent `is-system-installation-allowed` property of
#. all non-admins’ parental controls policies to false.
#. - In order to configure the policy so that all users (including
#. admins) can install safe software anywhere without authorisation,
#. but need authorisation to install unsafe software anywhere (i.e.
#. applying parental controls to admins too):
#. * Unconditionally return `yes` from `app-install`.
#. * Unconditionally return `auth_admin` from `override-parental-controls`.
#. * Set the malcontent `is-user-installation-allowed` property of all
#. users’ parental controls policies to true.
#. * Set the malcontent `is-system-installation-allowed` property of
#. all users’ parental controls policies to true.
#: system-helper/org.freedesktop.Flatpak.policy.in:287
msgid "Override parental controls for installs"
msgstr "Přepsat rodičovskou kontrolu pro instalace"

#: system-helper/org.freedesktop.Flatpak.policy.in:288
msgid ""
"Authentication is required to install software which is restricted by your "
"parental controls policy"
msgstr ""
"K instalaci softwaru, který je omezen bezpečnostní politikou rodičovské "
"kontroly je vyžadováno ověření"

#. SECURITY:
#. - This is like org.freedesktop.Flatpak.override-parental-controls, but
#. it’s queried for app updates, whereas the former is queried for app
#. installs.
#. - As with the above action, this one is only queried if
#. org.freedesktop.Flatpak.app-update has allowed the app update, and
#. only if the app being updated has too extreme content for the user
#. who is trying to update it.
#. - The default policy for this is to *allow* updates to ‘too extreme’
#. apps by default, on the basis that having an out-of-date (i.e.
#. insecure or unsupported) app is a worse outcome than automatically
#. installing an update which has radically different content from the
#. version of the app which the parent originally vetted and installed.
#: system-helper/org.freedesktop.Flatpak.policy.in:313
msgid "Override parental controls for updates"
msgstr "Přepsat rodičovskou kontrolu pro aktualizace"

#: system-helper/org.freedesktop.Flatpak.policy.in:314
msgid ""
"Authentication is required to update software which is restricted by your "
"parental controls policy"
msgstr ""
"K aktualizaci softwaru, který je omezen bezpečnostní politikou rodičovské "
"kontroly je vyžadováno ověření"

#~ msgid "Installed:"
#~ msgstr "Instalováno:"

#~ msgid "Download:"
#~ msgstr "Stažení:"

#, c-format
#~ msgid "Error signing commit: %d"
#~ msgstr "Chyba během podepisování commitu: %d"

#, c-format
#~ msgid ""
#~ "Found similar ref(s) for ‘%s’ in remote ‘%s’ (%s).\n"
#~ "Use this remote?"
#~ msgstr ""
#~ "Nalezeny podobné refy pro „%s“ ve vzdáleném repozitáři „%s“ (%s).\n"
#~ "Použít tento vzdálený repozitář?"

#, c-format
#~ msgid "No entry for %s in remote '%s' summary cache "
#~ msgstr "Žádný záznam pro %s v cache shrnutí vzdáleného repozitáře „%s“ "

#, c-format
#~ msgid "Failed to uninstall %s for rebase to %s: "
#~ msgstr "Selhala odinstalace %s pro rebase na %s: "

#, c-format
#~ msgid "Failed to uninstall %s for rebase to %s: %s\n"
#~ msgstr "Selhala odinstalace %s pro rebase na %s: %s\n"

#, c-format
#~ msgid "Unable to open directory %s"
#~ msgstr "Selhalo otevření adresáře %s"

#~ msgid "install"
#~ msgstr "instalace"

#~ msgid "update"
#~ msgstr "aktualizace"

#~ msgid "install bundle"
#~ msgstr "instalace balíku"

#~ msgid "uninstall"
#~ msgstr "odinstalace"

#~ msgid "(internal error, please report)"
#~ msgstr "(vnitřní chyba, prosím nahlaste)"

#~ msgid "Warning:"
#~ msgstr "Varování:"

#, fuzzy
#~ msgid "runtime"
#~ msgstr "Prostředí"

#, fuzzy
#~ msgid "app"
#~ msgstr "Aplikace"

#, c-format
#~ msgid "%s Failed to %s %s: %s\n"
#~ msgstr "%s Selhalo %s %s: %s\n"

#~ msgid "[REF…] - Uninstall an application"
#~ msgstr "[REF…] - Odinstalovat aplikaci"

#, c-format
#~ msgid "Replace it with %s?"
#~ msgstr "Nahradit za %s?"

#~ msgid "\"flatpak run\" is not intended to be ran with sudo"
#~ msgstr "„flatpak run“ není určen pro běh se sudo"

#, c-format
#~ msgid "Failed to determine parts from ref: %s"
#~ msgstr "Selhalo zjištění částí z refu: %s"

#, c-format
#~ msgid "Invalid arch %s"
#~ msgstr "Neplatná architektura %s"

#, fuzzy, c-format
#~ msgid "Related ref '%s' is only partially installed"
#~ msgstr "Požadované rozšíření %s je nainstalováno pouze částečně"

#, fuzzy, c-format
#~ msgid "Ref '%s' is only partially installed"
#~ msgstr "Požadované rozšíření %s je nainstalováno pouze částečně"

#, c-format
#~ msgid "No such ref (%s, %s) in remote %s"
#~ msgstr "Nemohu nalézt ref (%s, %s) ve vzdáleném repozitáři %s"

#, c-format
#~ msgid "No flatpak cache in remote '%s' summary"
#~ msgstr "Žádná cache ve shrnutí vzdáleného repozitáře „%s“"

#, c-format
#~ msgid "No such ref (%s, %s) in remote %s or elsewhere"
#~ msgstr "Žádný ref (%s, %s) ve vzdáleném repozitáři %s nebo jinde"

#, c-format
#~ msgid "No remotes found which provide these refs: [%s]"
#~ msgstr ""
#~ "Nenalezeny žádné vzdálené repozitáře, které poskytují tyto refy: [%s]"

#, c-format
#~ msgid "No remotes found which provide the ref (%s, %s)"
#~ msgstr ""
#~ "Nenalezeny žádné vzdálené repozitáře, které poskytují tento ref (%s, %s)"

#~ msgid "No summary found"
#~ msgstr "Nenalezeno žádné shrnutí"

#~ msgid "No metadata branch for OCI"
#~ msgstr "Žádná větev metadat pro OCI"

#, c-format
#~ msgid "Invalid group: %d"
#~ msgstr "Neplatná skupina: %d"

#, c-format
#~ msgid "Warning: Can't find %s metadata for dependencies: %s"
#~ msgstr "Varování: Nelze nalézt %s metadata pro závislosti: %s"

#~ msgid "OPTIONS"
#~ msgstr "VOLBY"

#~ msgid "Not running as root, may be unable to enter namespace"
#~ msgstr "Neběží jako root, možná nebude možné vstoupit do jmenného prostoru"

#~ msgid "Default system installation"
#~ msgstr "Výchozí systémová instalace"

#~ msgid "No url specified in flatpakrepo file"
#~ msgstr "Žádný url není určen ve flatpakrepo souboru"

#~ msgid "Extracting icons for component %s\n"
#~ msgstr "Získávají se ikony pro komponentu %s\n"

#~ msgid "%s branch already installed"
#~ msgstr "větev %s je již nainstalována"

#~ msgid "%s branch %s not installed"
#~ msgstr "%s větev %s nenainstalováno"

#~ msgid "Show help options"
#~ msgstr "Zobrazit volby nápovědy"

#~ msgid "0"
#~ msgstr "0"

#~ msgid "Print OSTree debug information during command processing"
#~ msgstr "Vypsat ladicí informace OSTree během zpracovávání příkazu"

#~ msgid "Architecture"
#~ msgstr "Architektura"

#~ msgid "Location:"
#~ msgstr "Umístění:"

#~ msgid "Installing for user: %s from %s\n"
#~ msgstr "Instaluje se pro uživatele: %s z %s\n"

#~ msgid "Installing: %s from %s\n"
#~ msgstr "Instaluje se: %s z %s\n"

#~ msgid "Updating for user: %s from %s\n"
#~ msgstr "Aktualizuje se pro uživatele: %s z %s\n"

#~ msgid "Updating: %s from %s\n"
#~ msgstr "Aktualizuje se: %s z %s\n"

#~ msgid "Installing for user: %s from bundle %s\n"
#~ msgstr "Instaluje se pro uživatele: %s z balíku %s\n"

#~ msgid "Installing: %s from bundle %s\n"
#~ msgstr "Instaluje se: %s z balíku %s\n"

#~ msgid "Uninstalling for user: %s\n"
#~ msgstr "Odstraňuje se pro uživatele: %s\n"

#~ msgid "No updates.\n"
#~ msgstr "Žádné aktualizace.\n"

#~ msgid "Now at %s.\n"
#~ msgstr "Nyní na %s.\n"

#~ msgid "new file access"
#~ msgstr "nový přístup k souborům"

#~ msgid "file access"
#~ msgstr "přístup k souborům"

#~ msgid "new dbus access"
#~ msgstr "nový přístup k dbus"

#~ msgid "dbus access"
#~ msgstr "přístup k dbus"

#~ msgid "new dbus ownership"
#~ msgstr "nové vlastnictví dbus"

#~ msgid "dbus ownership"
#~ msgstr "vlastnictví dbus"

#~ msgid "new system dbus access"
#~ msgstr "nový přístup k systémové dbus"

#~ msgid "system dbus access"
#~ msgstr "přístup k systémové dbus"

#~ msgid "new system dbus ownership"
#~ msgstr "nové vlastnictví systémové dbus"

#~ msgid "system dbus ownership"
#~ msgstr "vlastnictví systémové dbus"

#~ msgid "new tags"
#~ msgstr "nové tagy"

#~ msgid "tags"
#~ msgstr "tagy"

#~ msgid "Installing in %s:\n"
#~ msgstr "Instaluje se v %s:\n"

#~ msgid "Is this ok"
#~ msgstr "Je tohle ok"

#, fuzzy
#~ msgid "Invalid .flatpakref"
#~ msgstr "Neplatný klíč gpg"

#, fuzzy
#~ msgid "Authentication is required to install $(ref) from $(origin)"
#~ msgstr "K instalaci softwaru je vyžadováno ověření"

#, fuzzy
#~ msgid "Authentication is required to update $(ref) from $(origin)"
#~ msgstr "K aktualizaci vzdálených informací je vyžadováno ověření"

#, fuzzy
#~ msgid "Authentication is required to update the remote $(remote)"
#~ msgstr "K aktualizaci vzdálených informací je vyžadováno ověření"

#, fuzzy
#~ msgid "Authentication is required to modify the remote $(remote)"
#~ msgstr "K aktualizaci vzdálených informací je vyžadováno ověření"

#, fuzzy
#~ msgid "Authentication is required to configure the remote $(remote)"
#~ msgstr "K nastavení repozitářů softwaru je vyžadováno ověření"

#~ msgid "Runtime Branch"
#~ msgstr "Větev prostředí"

#~ msgid "Runtime Commit"
#~ msgstr "Commit prostředí"

#~ msgid "Unknown command '%s'"
#~ msgstr "Neznámý příkaz „%s“"

#~ msgid "Migrating %s to %s\n"
#~ msgstr "Migruje se %s do %s\n"

#~ msgid "Error during migration: %s\n"
#~ msgstr "Chyba během migrace: %s\n"

#~ msgid "Redirect collection ID: %s\n"
#~ msgstr "ID kolekce přesměrování: %s\n"

#~ msgid "Invalid sha256 for extra data uri %s"
#~ msgstr "Neplatný sha256 pro dodatečná data uri %s"

#~ msgid "Invalid sha256 for extra data"
#~ msgstr "Neplatný sha256 pro dodatečná data"

#~ msgid "Is this ok?"
#~ msgstr "Je tohle ok?"

#~ msgid "Add OCI registry"
#~ msgstr "Přidat OCI registr"

#~ msgid "Found in remote %s\n"
#~ msgstr "Nalezeno ve vzdáleném repozitáři %s\n"

#~ msgid "Found in remote %s, do you want to install it?"
#~ msgstr "Nalezeno ve vzdáleném repozitáři %s, přejete si provést instalaci?"

#~ msgid "Found in several remotes:\n"
#~ msgstr "Nalezeno v několika vzdálených repozitářích:\n"

#~ msgid "The required runtime %s was not found in a configured remote.\n"
#~ msgstr "Požadované prostředí %s nebylo nalezeno v nastaveném repozitáři.\n"

#~ msgid "%s already installed, skipping\n"
#~ msgstr "%s je již nainstalováno, přeskakuje se\n"

#~ msgid "One or more operations failed"
#~ msgstr "Jedna nebo více operací selhalo"

#~ msgid "No ref information available in repository"
#~ msgstr "V repozitáři nejsou dostupné žádné ref informace"

#~ msgid "Remote title not set"
#~ msgstr "Jméno vzdáleného adresáře nenastaveno"

#~ msgid "Remote default-branch not set"
#~ msgstr "Vzdálený default-branch nenastaven"

#~ msgid "Search specific system-wide installations"
#~ msgstr "Prohledat specifické systémové instalace"

#~ msgid "Failed to unlink temporary file"
#~ msgstr "Selhalo odlinkování dočasného souboru"

#~ msgid "REMOTE must be specified"
#~ msgstr "VZDÁLENÉ musí být určeno"

#~ msgid "Building %s"
#~ msgstr "Sestavuje se %s"

#~ msgid "Cleanup %s"
#~ msgstr "Čištění %s"

#~ msgid "'%s' is not a valid runtime name: %s"
#~ msgstr "„%s“ není platným názvem prostředí: %s"

#~ msgid "'%s' is not a valid sdk name: %s"
#~ msgstr "„%s“ není platným názvem sdk: %s"

#~ msgid "OCI repo Filename or uri must be specified"
#~ msgstr "Název vzdáleného OCI repozitáře musí být určen"

#~ msgid "OCI image is not a flatpak (missing ref)"
#~ msgstr "OCI obraz není flatpak (chybí ref)"

===== ./po/id.po =====
# Indonesian translation for flatpak.
# Copyright (C) 2017 flatpak's COPYRIGHT HOLDER
# This file is distributed under the same license as the flatpak package.
# Kukuh Syafaat <kukuhsyafaat@gnome.org>, 2017-2023.
#
msgid ""
msgstr ""
"Project-Id-Version: flatpak master\n"
"Report-Msgid-Bugs-To: https://github.com/flatpak/flatpak/issues\n"
"POT-Creation-Date: 2026-05-27 16:39+0200\n"
"PO-Revision-Date: 2023-04-29 13:15+0700\n"
"Last-Translator: Kukuh Syafaat <kukuhsyafaat@gnome.org>\n"
"Language-Team: Indonesian <gnome-l10n-id@googlegroups.com>\n"
"Language: id\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: Poedit 3.2.2\n"

#: app/flatpak-builtins-build-bundle.c:59
msgid "Export runtime instead of app"
msgstr "Ekspor runtime alih-alih aplikasi"

#: app/flatpak-builtins-build-bundle.c:60
msgid "Arch to bundle for"
msgstr "Arsitektur tujuan bundel"

#: app/flatpak-builtins-build-bundle.c:60
#: app/flatpak-builtins-build-export.c:62 app/flatpak-builtins-build-init.c:53
#: app/flatpak-builtins-build-sign.c:42 app/flatpak-builtins-create-usb.c:46
#: app/flatpak-builtins-info.c:55 app/flatpak-builtins-install.c:67
#: app/flatpak-builtins-list.c:50 app/flatpak-builtins-make-current.c:38
#: app/flatpak-builtins-remote-info.c:54 app/flatpak-builtins-remote-ls.c:56
#: app/flatpak-builtins-run.c:158 app/flatpak-builtins-search.c:37
#: app/flatpak-builtins-uninstall.c:54 app/flatpak-builtins-update.c:56
msgid "ARCH"
msgstr "ARSITEKTUR"

#: app/flatpak-builtins-build-bundle.c:61
#, fuzzy
msgid "URL for repo"
msgstr "Url untuk repo"

#: app/flatpak-builtins-build-bundle.c:61
#: app/flatpak-builtins-build-bundle.c:62
#: app/flatpak-builtins-build-update-repo.c:68
#: app/flatpak-builtins-build-update-repo.c:72
#: app/flatpak-builtins-build-update-repo.c:73
#: app/flatpak-builtins-history.c:69 app/flatpak-builtins-remote-add.c:80
#: app/flatpak-builtins-remote-add.c:81 app/flatpak-builtins-remote-add.c:85
#: app/flatpak-builtins-remote-list.c:53
#: app/flatpak-builtins-remote-modify.c:70
#: app/flatpak-builtins-remote-modify.c:85
#: app/flatpak-builtins-remote-modify.c:86
#: app/flatpak-builtins-remote-modify.c:90
msgid "URL"
msgstr "URL"

#: app/flatpak-builtins-build-bundle.c:62
#, fuzzy
msgid "URL for runtime flatpakrepo file"
msgstr "Url untuk berkas flatpakrepo runtime"

#: app/flatpak-builtins-build-bundle.c:63
msgid "Add GPG key from FILE (- for stdin)"
msgstr "Tambah kunci GPG dari BERKAS (- untuk stdin)"

#: app/flatpak-builtins-build-bundle.c:63 app/flatpak-builtins-build.c:54
#: app/flatpak-builtins-build-export.c:67
#: app/flatpak-builtins-build-update-repo.c:83
#: app/flatpak-builtins-install.c:81 app/flatpak-builtins-remote-add.c:84
#: app/flatpak-builtins-remote-add.c:86 app/flatpak-builtins-remote-modify.c:89
#: app/flatpak-builtins-remote-modify.c:92
msgid "FILE"
msgstr "BERKAS"

#: app/flatpak-builtins-build-bundle.c:64
msgid "GPG Key ID to sign the OCI image with"
msgstr "ID kunci GPG untuk menandatangani citra OCI"

#: app/flatpak-builtins-build-bundle.c:64
#: app/flatpak-builtins-build-commit-from.c:68
#: app/flatpak-builtins-build-export.c:68
#: app/flatpak-builtins-build-import-bundle.c:49
#: app/flatpak-builtins-build-sign.c:44
#: app/flatpak-builtins-build-update-repo.c:84
msgid "KEY-ID"
msgstr "ID KUNCI"

#: app/flatpak-builtins-build-bundle.c:65
#: app/flatpak-builtins-build-commit-from.c:69
#: app/flatpak-builtins-build-export.c:71
#: app/flatpak-builtins-build-import-bundle.c:50
#: app/flatpak-builtins-build-sign.c:45
#: app/flatpak-builtins-build-update-repo.c:85
msgid "GPG Homedir to use when looking for keyrings"
msgstr "Homedir GPG untuk digunakan saat mencari ring kunci"

#: app/flatpak-builtins-build-bundle.c:65
#: app/flatpak-builtins-build-commit-from.c:69
#: app/flatpak-builtins-build-export.c:71
#: app/flatpak-builtins-build-import-bundle.c:50
#: app/flatpak-builtins-build-sign.c:45
#: app/flatpak-builtins-build-update-repo.c:85
msgid "HOMEDIR"
msgstr "HOMEDIR"

#: app/flatpak-builtins-build-bundle.c:66
msgid "OSTree commit to create a delta bundle from"
msgstr "Komit OSTree untuk membuat bundel delta dari"

#: app/flatpak-builtins-build-bundle.c:66 app/flatpak-builtins-remote-info.c:55
#: app/flatpak-builtins-update.c:57
msgid "COMMIT"
msgstr "KOMIT"

#: app/flatpak-builtins-build-bundle.c:67
msgid "Export oci image instead of flatpak bundle"
msgstr "Ekspor citra oci alih-alih paket flatpak"

#: app/flatpak-builtins-build-bundle.c:70
msgid "How to compress OCI image layers (default: gzip)"
msgstr ""

#: app/flatpak-builtins-build-bundle.c:634
msgid ""
"LOCATION FILENAME NAME [BRANCH] - Create a single file bundle from a local "
"repository"
msgstr ""
"LOKASI NAMABERKAS NAMA [CABANG] - Buat bundel berkas tunggal dari repositori "
"lokal"

#: app/flatpak-builtins-build-bundle.c:641
msgid "LOCATION, FILENAME and NAME must be specified"
msgstr "LOKASI, NAMABERKAS dan NAMA harus ditentukan"

#: app/flatpak-builtins-build-bundle.c:644
#: app/flatpak-builtins-build-export.c:844
#: app/flatpak-builtins-build-import-bundle.c:136
#: app/flatpak-builtins-build-init.c:217 app/flatpak-builtins-build-sign.c:76
#: app/flatpak-builtins-document-export.c:112
#: app/flatpak-builtins-document-info.c:75
#: app/flatpak-builtins-document-list.c:191
#: app/flatpak-builtins-document-unexport.c:70
#: app/flatpak-builtins-history.c:482 app/flatpak-builtins-info.c:130
#: app/flatpak-builtins-install.c:181 app/flatpak-builtins-install.c:234
#: app/flatpak-builtins-install.c:298 app/flatpak-builtins-list.c:419
#: app/flatpak-builtins-make-current.c:72 app/flatpak-builtins-override.c:73
#: app/flatpak-builtins-permission-list.c:162
#: app/flatpak-builtins-permission-remove.c:132
#: app/flatpak-builtins-remote-add.c:323
#: app/flatpak-builtins-remote-delete.c:68
#: app/flatpak-builtins-remote-list.c:241 app/flatpak-builtins-remote-ls.c:407
msgid "Too many arguments"
msgstr "Terlalu banyak argumen"

#: app/flatpak-builtins-build-bundle.c:659
#: app/flatpak-builtins-build-commit-from.c:338
#: app/flatpak-builtins-build-commit-from.c:351
#: app/flatpak-builtins-build-import-bundle.c:145
#, c-format
msgid "'%s' is not a valid repository"
msgstr "'%s' bukan repositori yang valid"

#: app/flatpak-builtins-build-bundle.c:663
#, c-format
msgid "'%s' is not a valid repository: "
msgstr "'%s' bukan repositori yang valid: "

#: app/flatpak-builtins-build-bundle.c:674 app/flatpak-builtins-build-sign.c:88
#: common/flatpak-dir.c:14293
#, c-format
msgid "'%s' is not a valid name: %s"
msgstr "'%s' bukan nama yang valid: %s"

#: app/flatpak-builtins-build-bundle.c:677
#: app/flatpak-builtins-build-export.c:865 app/flatpak-builtins-build-sign.c:91
#: common/flatpak-dir.c:14299
#, c-format
msgid "'%s' is not a valid branch name: %s"
msgstr "'%s' bukan nama cabang yang valid: %s"

#: app/flatpak-builtins-build-bundle.c:691
#: app/flatpak-builtins-build-import-bundle.c:149
#: app/flatpak-builtins-build-init.c:281
#, c-format
msgid "'%s' is not a valid filename"
msgstr "'%s' bukan nama berkas yang valid"

#: app/flatpak-builtins-build-bundle.c:706
msgid "--oci-layer-compress value must be gzip or zstd"
msgstr ""

#: app/flatpak-builtins-build.c:49
msgid "Use Platform runtime rather than Sdk"
msgstr "Gunakan runtime Platform alih-alih Sdk"

#: app/flatpak-builtins-build.c:50
msgid "Make destination readonly"
msgstr "Buat tujuan hanya baca"

#: app/flatpak-builtins-build.c:51
msgid "Add bind mount"
msgstr "Tambah kait bind"

#: app/flatpak-builtins-build.c:51
msgid "DEST=SRC"
msgstr "DEST=SRC"

#: app/flatpak-builtins-build.c:52
msgid "Start build in this directory"
msgstr "Mulai bangun di direktori ini"

#: app/flatpak-builtins-build.c:52 app/flatpak-builtins-build.c:53
#: app/flatpak-builtins-build-init.c:64 app/flatpak-builtins-run.c:160
msgid "DIR"
msgstr "DIR"

#: app/flatpak-builtins-build.c:53
msgid "Where to look for custom sdk dir (defaults to 'usr')"
msgstr "Di mana mencari direktori sdk tersuai (bawaan ke 'usr')"

#: app/flatpak-builtins-build.c:54 app/flatpak-builtins-build-export.c:67
msgid "Use alternative file for the metadata"
msgstr "Gunakan berkas alternatif untuk metadata"

#: app/flatpak-builtins-build.c:55 app/flatpak-builtins-run.c:177
msgid "Kill processes when the parent process dies"
msgstr "Bunuh proses saat proses induk mati"

#: app/flatpak-builtins-build.c:56
msgid "Export application homedir directory to build"
msgstr "Ekspor direktori homedir aplikasi untuk membangun"

#: app/flatpak-builtins-build.c:57 app/flatpak-builtins-run.c:165
msgid "Log session bus calls"
msgstr "Catat log pemanggilan bus sesi"

#: app/flatpak-builtins-build.c:58 app/flatpak-builtins-run.c:166
msgid "Log system bus calls"
msgstr "Catat log pemanggilan bus sistem"

#: app/flatpak-builtins-build.c:262
msgid "DIRECTORY [COMMAND [ARGUMENT…]] - Build in directory"
msgstr "DIREKTORI [PERINTAH [ARGUMEN...]] - Bangun di direktori"

#: app/flatpak-builtins-build.c:285 app/flatpak-builtins-build-finish.c:656
msgid "DIRECTORY must be specified"
msgstr "DIREKTORI harus ditentukan"

#: app/flatpak-builtins-build.c:296 app/flatpak-builtins-build-export.c:887
#, c-format
msgid "Build directory %s not initialized, use flatpak build-init"
msgstr "Direktori bangun %s tidak diinisialisasi, gunakan flatpak build-init"

#: app/flatpak-builtins-build.c:315
msgid "metadata invalid, not application or runtime"
msgstr "metadata tidak valid, bukan aplikasi atau runtime"

#: app/flatpak-builtins-build.c:446
#, c-format
msgid "No extension point matching %s in %s"
msgstr "Tidak ada titik ekstensi %s yang cocok pada %s"

#: app/flatpak-builtins-build.c:635
#, c-format
msgid "Missing '=' in bind mount option '%s'"
msgstr "Kehilangan '=' pada opsi kait bind '%s'"

#: app/flatpak-builtins-build.c:679 common/flatpak-run.c:3961
#, c-format
msgid "Unable to start app"
msgstr "Tidak dapat memulai aplikasi"

#: app/flatpak-builtins-build-commit-from.c:58
msgid "Source repo dir"
msgstr "Direktori repo sumber"

#: app/flatpak-builtins-build-commit-from.c:58
msgid "SRC-REPO"
msgstr "SRC-REPO"

#: app/flatpak-builtins-build-commit-from.c:59
msgid "Source repo ref"
msgstr "Ref repo sumber"

#: app/flatpak-builtins-build-commit-from.c:59
msgid "SRC-REF"
msgstr "SRC-REF"

#: app/flatpak-builtins-build-commit-from.c:64
#: app/flatpak-builtins-build-export.c:60
msgid "One line subject"
msgstr "Subjek satu baris"

#: app/flatpak-builtins-build-commit-from.c:64
#: app/flatpak-builtins-build-export.c:60
msgid "SUBJECT"
msgstr "SUBJEK"

#: app/flatpak-builtins-build-commit-from.c:65
#: app/flatpak-builtins-build-export.c:61
msgid "Full description"
msgstr "Deskripsi lengkap"

#: app/flatpak-builtins-build-commit-from.c:65
#: app/flatpak-builtins-build-export.c:61
msgid "BODY"
msgstr "TUBUH"

#: app/flatpak-builtins-build-commit-from.c:66
#: app/flatpak-builtins-build-export.c:64
#: app/flatpak-builtins-build-import-bundle.c:51
msgid "Update the appstream branch"
msgstr "Mutakhirkan cabang appstream"

#: app/flatpak-builtins-build-commit-from.c:67
#: app/flatpak-builtins-build-export.c:65
#: app/flatpak-builtins-build-import-bundle.c:52
#: app/flatpak-builtins-build-update-repo.c:87
msgid "Don't update the summary"
msgstr "Jangan mutakhirkan ringkasan"

#: app/flatpak-builtins-build-commit-from.c:68
#: app/flatpak-builtins-build-export.c:68
#: app/flatpak-builtins-build-import-bundle.c:49
#: app/flatpak-builtins-build-sign.c:44
msgid "GPG Key ID to sign the commit with"
msgstr "ID kunci GPG untuk menandatangani komit dengan"

#: app/flatpak-builtins-build-commit-from.c:70
#: app/flatpak-builtins-build-export.c:73
msgid "Mark build as end-of-life"
msgstr "Tandai bangun sebagai akhir masa pakai"

#: app/flatpak-builtins-build-commit-from.c:70
#: app/flatpak-builtins-build-export.c:73
msgid "REASON"
msgstr "ALASAN"

#: app/flatpak-builtins-build-commit-from.c:71
msgid ""
"Mark refs matching the OLDID prefix as end-of-life, to be replaced with the "
"given NEWID"
msgstr ""
"Tandai ref yang cocok dengan awalan IDLAMA sebagai akhir masa pakainya, "
"untuk diganti dengan IDBARU yang diberikan"

#: app/flatpak-builtins-build-commit-from.c:71
msgid "OLDID=NEWID"
msgstr "IDLAMA=IDBARU"

#: app/flatpak-builtins-build-commit-from.c:72
#: app/flatpak-builtins-build-export.c:75
msgid "Set type of token needed to install this commit"
msgstr "Setel jenis token yang diperlukan untuk memasang komit ini"

#: app/flatpak-builtins-build-commit-from.c:72
#: app/flatpak-builtins-build-export.c:75
msgid "VAL"
msgstr "VAL"

#: app/flatpak-builtins-build-commit-from.c:73
msgid "Override the timestamp of the commit (NOW for current time)"
msgstr "Timpa cap waktu komit (SEKARANG untuk waktu sekarang)"

#: app/flatpak-builtins-build-commit-from.c:73
#: app/flatpak-builtins-build-export.c:76
msgid "TIMESTAMP"
msgstr "TIMESTAMP"

#: app/flatpak-builtins-build-commit-from.c:75
#: app/flatpak-builtins-build-export.c:80
#: app/flatpak-builtins-build-import-bundle.c:53
#: app/flatpak-builtins-build-update-repo.c:97
msgid "Don't generate a summary index"
msgstr "Jangan hasilkan indeks ringkasan"

#: app/flatpak-builtins-build-commit-from.c:278
msgid "DST-REPO [DST-REF…] - Make a new commit from existing commits"
msgstr ""
"DST-REPO [DST-REF...] - Buat komit baru berdasarkan komit yang sudah ada"

#: app/flatpak-builtins-build-commit-from.c:285
msgid "DST-REPO must be specified"
msgstr "DST-REPO harus ditentukan"

#: app/flatpak-builtins-build-commit-from.c:293
msgid ""
"If --src-repo is not specified, exactly one destination ref must be specified"
msgstr ""
"Jika --src-repo tidak ditentukan, tepatnya satu tujuan harus ditentukan"

#: app/flatpak-builtins-build-commit-from.c:296
msgid ""
"If --src-ref is specified, exactly one destination ref must be specified"
msgstr "Jika --src-ref ditentukan, salah satu tujuan ref harus ditentukan"

#: app/flatpak-builtins-build-commit-from.c:299
msgid "Either --src-repo or --src-ref must be specified"
msgstr "Salah satu --src-repo atau --src-ref harus ditentukan"

#: app/flatpak-builtins-build-commit-from.c:315
msgid "Invalid argument format of use  --end-of-life-rebase=OLDID=NEWID"
msgstr ""
"Format argumen penggunaan tidak valid  --end-of-life-rebase=IDLAMA=IDBARU"

#: app/flatpak-builtins-build-commit-from.c:321
#: app/flatpak-builtins-build-commit-from.c:324
#, c-format
msgid "Invalid name %s in --end-of-life-rebase"
msgstr "Nama %s tidak valid dalam --end-of-life-rebase"

#: app/flatpak-builtins-build-commit-from.c:333
#: app/flatpak-builtins-build-export.c:1092
#, c-format
msgid "Could not parse '%s'"
msgstr "Tidak dapat mengurai '%s'"

#: app/flatpak-builtins-build-commit-from.c:498
msgid "Can't commit from partial source commit"
msgstr "Tidak dapat melakukan komit dari komit sumber parsial"

#: app/flatpak-builtins-build-commit-from.c:503
#, c-format
msgid "%s: no change\n"
msgstr "%s: tidak ada perubahan\n"

#: app/flatpak-builtins-build-export.c:62
msgid "Architecture to export for (must be host compatible)"
msgstr "Arsitektur tujuan ekspor (mesti kompatibel dengan host)"

#: app/flatpak-builtins-build-export.c:63
msgid "Commit runtime (/usr), not /app"
msgstr "Runtime komit (/usr), bukan /app"

#: app/flatpak-builtins-build-export.c:66
msgid "Use alternative directory for the files"
msgstr "Gunakan direktori alternatif untuk berkas"

#: app/flatpak-builtins-build-export.c:66
msgid "SUBDIR"
msgstr "SUBDIR"

#: app/flatpak-builtins-build-export.c:69
msgid "Files to exclude"
msgstr "Berkas untuk dikecualikan"

#: app/flatpak-builtins-build-export.c:69
#: app/flatpak-builtins-build-export.c:70
#: app/flatpak-builtins-build-update-repo.c:90
msgid "PATTERN"
msgstr "POLA"

#: app/flatpak-builtins-build-export.c:70
msgid "Excluded files to include"
msgstr "Sertakan berkas yang dikecualikan"

#: app/flatpak-builtins-build-export.c:74
msgid "Mark build as end-of-life, to be replaced with the given ID"
msgstr ""
"Tandai bangun sebagai akhir masa pakai, harus diganti dengan ID yang "
"diberikan"

#: app/flatpak-builtins-build-export.c:74
#: app/flatpak-builtins-document-list.c:49 app/flatpak-cli-transaction.c:1427
msgid "ID"
msgstr "ID"

#: app/flatpak-builtins-build-export.c:76
msgid "Override the timestamp of the commit"
msgstr "Timpa timestamp dari komit"

#: app/flatpak-builtins-build-export.c:77
#: app/flatpak-builtins-build-update-repo.c:75
#: app/flatpak-builtins-remote-add.c:83 app/flatpak-builtins-remote-list.c:54
#: app/flatpak-builtins-remote-modify.c:88
msgid "Collection ID"
msgstr "ID Koleksi"

#: app/flatpak-builtins-build-export.c:472
#, c-format
msgid "WARNING: Error running desktop-file-validate: %s\n"
msgstr "PERINGATAN: Galat menjalankan desktop-file-validate: %s\n"

#: app/flatpak-builtins-build-export.c:480
#, c-format
msgid "WARNING: Error reading from desktop-file-validate: %s\n"
msgstr "PERINGATAN: Galat membaca dari desktop-file-validate: %s\n"

#: app/flatpak-builtins-build-export.c:486
#, c-format
msgid "WARNING: Failed to validate desktop file %s: %s\n"
msgstr "PERINGATAN: Gagal memvalidasi berkas destop %s: %s\n"

#: app/flatpak-builtins-build-export.c:513
#, c-format
msgid "WARNING: Can't find Exec key in %s: %s\n"
msgstr "PERINGATAN: Tidak dapat menemukan kunci Exec di %s: %s\n"

#: app/flatpak-builtins-build-export.c:521
#: app/flatpak-builtins-build-export.c:614
#, c-format
msgid "WARNING: Binary not found for Exec line in %s: %s\n"
msgstr "PERINGATAN: Biner tidak ditemukan untuk baris Exec di %s: %s\n"

#: app/flatpak-builtins-build-export.c:529
#, c-format
msgid "WARNING: Icon not matching app id in %s: %s\n"
msgstr "PERINGATAN: Ikon tidak cocok dengan id aplikasi di %s: %s\n"

#: app/flatpak-builtins-build-export.c:552
#, c-format
msgid "WARNING: Icon referenced in desktop file but not exported: %s\n"
msgstr ""
"PERINGATAN: Ikon direferensikan dalam berkas destop tapi tidak diekspor: %s\n"

#: app/flatpak-builtins-build-export.c:719
#, c-format
msgid "Invalid uri type %s, only http/https supported"
msgstr "Jenis uri %s tidak valid, hanya http/https yang didukung"

#: app/flatpak-builtins-build-export.c:737
#, c-format
msgid "Unable to find basename in %s, specify a name explicitly"
msgstr "Tidak dapat menemukan basename di %s, tentukan nama secara eksplisit"

#: app/flatpak-builtins-build-export.c:746
#, c-format
msgid "No slashes allowed in extra data name"
msgstr "Garis miring tidak diperbolehkan pada nama data ekstra"

#: app/flatpak-builtins-build-export.c:758
#, c-format
msgid "Invalid format for sha256 checksum: '%s'"
msgstr "Format tidak valid untuk checksum sha256: '%s'"

#: app/flatpak-builtins-build-export.c:768
#, c-format
msgid "Extra data sizes of zero not supported"
msgstr "Data ekstra berukuran nol tidak didukung"

#: app/flatpak-builtins-build-export.c:830
msgid ""
"LOCATION DIRECTORY [BRANCH] - Create a repository from a build directory"
msgstr "LOKASI DIREKTORI [CABANG] - Buat repositori dari direktori bangun"

#: app/flatpak-builtins-build-export.c:838
msgid "LOCATION and DIRECTORY must be specified"
msgstr "LOKASI dan DIREKTORI harus ditentukan"

#: app/flatpak-builtins-build-export.c:859
#: app/flatpak-builtins-remote-add.c:327
#, c-format
msgid "‘%s’ is not a valid collection ID: %s"
msgstr "'%s' bukan ID koleksi yang valid: %s"

#: app/flatpak-builtins-build-export.c:904
#: app/flatpak-builtins-build-finish.c:684
msgid "No name specified in the metadata"
msgstr "Tidak ada nama yang ditentukan dalam metadata"

#: app/flatpak-builtins-build-export.c:1166
#, c-format
msgid "Commit: %s\n"
msgstr "Komit: %s\n"

#: app/flatpak-builtins-build-export.c:1167
#, c-format
msgid "Metadata Total: %u\n"
msgstr "Jumlah Metadata: %u\n"

#: app/flatpak-builtins-build-export.c:1168
#, c-format
msgid "Metadata Written: %u\n"
msgstr "Metadata Tertulis: %u\n"

#: app/flatpak-builtins-build-export.c:1169
#, c-format
msgid "Content Total: %u\n"
msgstr "Total Isi: %u\n"

#: app/flatpak-builtins-build-export.c:1170
#, c-format
msgid "Content Written: %u\n"
msgstr "Konten Tertulis: %u\n"

#: app/flatpak-builtins-build-export.c:1171
#, c-format
msgid "Content Bytes Written:"
msgstr "Byte Konten Tertulis:"

#: app/flatpak-builtins-build-finish.c:52
msgid "Command to set"
msgstr "Perintah yang akan diatur"

#: app/flatpak-builtins-build-finish.c:52 app/flatpak-builtins-run.c:159
#: app/flatpak-main.c:209
msgid "COMMAND"
msgstr "PERINTAH"

#: app/flatpak-builtins-build-finish.c:53
msgid "Flatpak version to require"
msgstr "Versi Flatpak yang dibutuhkan"

#: app/flatpak-builtins-build-finish.c:53
msgid "MAJOR.MINOR.MICRO"
msgstr "MAYOR.MINOR.MIKRO"

#: app/flatpak-builtins-build-finish.c:54
msgid "Don't process exports"
msgstr "Jangan memproses ekspor"

#: app/flatpak-builtins-build-finish.c:55
msgid "Extra data info"
msgstr "Info data ekstra"

#: app/flatpak-builtins-build-finish.c:56 app/flatpak-builtins-build-init.c:63
msgid "Add extension point info"
msgstr "Menambahkan info titik ekstensi"

#: app/flatpak-builtins-build-finish.c:56 app/flatpak-builtins-build-init.c:63
msgid "NAME=VARIABLE[=VALUE]"
msgstr "NAMA=VARIABEL[=NILAI]"

#: app/flatpak-builtins-build-finish.c:57
msgid "Remove extension point info"
msgstr "Hapus info titik ekstensi"

#: app/flatpak-builtins-build-finish.c:57
#: app/flatpak-builtins-build-update-repo.c:79 app/flatpak-builtins-info.c:58
#: app/flatpak-builtins-remote-add.c:88 app/flatpak-builtins-remote-modify.c:94
#: app/flatpak-main.c:182
msgid "NAME"
msgstr "NAMA"

#: app/flatpak-builtins-build-finish.c:58
msgid "Set extension priority (only for extensions)"
msgstr "Atur prioritas ekstensi (hanya untuk ekstensi)"

#: app/flatpak-builtins-build-finish.c:58
msgid "VALUE"
msgstr "NILAI"

#: app/flatpak-builtins-build-finish.c:59
msgid "Change the sdk used for the app"
msgstr "Ubah SDK yang digunakan untuk aplikasi"

#: app/flatpak-builtins-build-finish.c:59
msgid "SDK"
msgstr "SDK"

#: app/flatpak-builtins-build-finish.c:60
msgid "Change the runtime used for the app"
msgstr "Ubah runtime yang digunakan untuk aplikasi"

#: app/flatpak-builtins-build-finish.c:60 app/flatpak-builtins-build-init.c:54
#: app/flatpak-builtins-list.c:53 app/flatpak-builtins-remote-ls.c:58
#: app/flatpak-builtins-run.c:163
msgid "RUNTIME"
msgstr "RUNTIME"

#: app/flatpak-builtins-build-finish.c:61
msgid "Set generic metadata option"
msgstr "Atur pilihan metadata generik"

#: app/flatpak-builtins-build-finish.c:61
msgid "GROUP=KEY[=VALUE]"
msgstr "GRUP=KUNCI[=NILAI]"

#: app/flatpak-builtins-build-finish.c:62
msgid "Don't inherit permissions from runtime"
msgstr "Jangan mewarisi izin dari runtime"

#: app/flatpak-builtins-build-finish.c:155
#, c-format
msgid "Not exporting %s, wrong extension\n"
msgstr "Tidak mengekspor %s, salah ekstensi\n"

#: app/flatpak-builtins-build-finish.c:163
#, c-format
msgid "Not exporting %s, non-allowed export filename\n"
msgstr "Tidak mengekspor %s, nama berkas ekspor yang tidak diizinkan\n"

#: app/flatpak-builtins-build-finish.c:167
#, c-format
msgid "Exporting %s\n"
msgstr "Mengekspor %s\n"

#: app/flatpak-builtins-build-finish.c:440
#, c-format
msgid "More than one executable found\n"
msgstr "Lebih dari satu yang bisa dieksekusi ditemukan\n"

#: app/flatpak-builtins-build-finish.c:451
#, c-format
msgid "Using %s as command\n"
msgstr "Menggunakan %s sebagai perintah\n"

#: app/flatpak-builtins-build-finish.c:456
#, c-format
msgid "No executable found\n"
msgstr "Tidak ditemukan yang bisa dieksekusi\n"

#: app/flatpak-builtins-build-finish.c:511
#, c-format
msgid "Invalid --require-version argument: %s"
msgstr "Argumen --require-version tidak valid: %s"

#: app/flatpak-builtins-build-finish.c:543
#, c-format
msgid "Too few elements in --extra-data argument %s"
msgstr "Terlalu sedikit elemen dalam argumen --extra-data %s"

#: app/flatpak-builtins-build-finish.c:575
#, c-format
msgid ""
"Too few elements in --metadata argument %s, format should be "
"GROUP=KEY[=VALUE]]"
msgstr ""
"Terlalu sedikit elemen dalam argumen --metadata %s, format seharusnya "
"GRUP=KUNCI[=NILAI]]"

#: app/flatpak-builtins-build-finish.c:597
#: app/flatpak-builtins-build-init.c:458
#, c-format
msgid ""
"Too few elements in --extension argument %s, format should be "
"NAME=VAR[=VALUE]"
msgstr ""
"Terlalu sedikit elemen dalam argumen --ekstensi %s, format seharusnya "
"NAMA=VAR[=NILAI]"

#: app/flatpak-builtins-build-finish.c:603
#: app/flatpak-builtins-build-init.c:461
#, c-format
msgid "Invalid extension name %s"
msgstr "Nama ekstensi tidak valid %s"

#: app/flatpak-builtins-build-finish.c:646
msgid "DIRECTORY - Finalize a build directory"
msgstr "DIREKTORI - Finalisasi direktori bangun"

#: app/flatpak-builtins-build-finish.c:668
#, c-format
msgid "Build directory %s not initialized"
msgstr "Direktori bangun %s tidak diinisialisasi"

#: app/flatpak-builtins-build-finish.c:689
#, c-format
msgid "Build directory %s already finalized"
msgstr "Direktori bangun %s sudah diselesaikan"

#: app/flatpak-builtins-build-finish.c:702
#, c-format
msgid "Please review the exported files and the metadata\n"
msgstr "Harap tinjau berkas yang diekspor dan metadata\n"

#: app/flatpak-builtins-build-import-bundle.c:47
msgid "Override the ref used for the imported bundle"
msgstr "Timpa ref yang digunakan untuk bundel yang diimpor"

#: app/flatpak-builtins-build-import-bundle.c:47
msgid "REF"
msgstr "REF"

#: app/flatpak-builtins-build-import-bundle.c:48
msgid "Import oci image instead of flatpak bundle"
msgstr "Impor citra oci, bukan bundel flatpak"

#: app/flatpak-builtins-build-import-bundle.c:77
#: app/flatpak-builtins-build-import-bundle.c:105
#, c-format
msgid "Importing %s (%s)\n"
msgstr "Mengimpor %s (%s)\n"

#: app/flatpak-builtins-build-import-bundle.c:126
msgid "LOCATION FILENAME - Import a file bundle into a local repository"
msgstr "LOKASI NAMABERKAS - Impor bundel berkas ke repositori lokal"

#: app/flatpak-builtins-build-import-bundle.c:133
msgid "LOCATION and FILENAME must be specified"
msgstr "LOKASI dan NAMABERKAS harus ditentukan"

#: app/flatpak-builtins-build-init.c:53 app/flatpak-builtins-info.c:55
#: app/flatpak-builtins-run.c:158
msgid "Arch to use"
msgstr "Arsitektur yang digunakan"

#: app/flatpak-builtins-build-init.c:54
msgid "Initialize var from named runtime"
msgstr "Menginisialisasi var dari runtime yang disebut"

#: app/flatpak-builtins-build-init.c:55
msgid "Initialize apps from named app"
msgstr "Menginisialisasi aplikasi dari aplikasi yang disebut"

#: app/flatpak-builtins-build-init.c:55
msgid "APP"
msgstr "APP"

#: app/flatpak-builtins-build-init.c:56
msgid "Specify version for --base"
msgstr "Tentukan versi untuk --base"

#: app/flatpak-builtins-build-init.c:56 app/flatpak-builtins-run.c:164
msgid "VERSION"
msgstr "VERSI"

#: app/flatpak-builtins-build-init.c:57
msgid "Include this base extension"
msgstr "Sertakan ekstensi dasar ini"

#: app/flatpak-builtins-build-init.c:57 app/flatpak-builtins-build-init.c:62
msgid "EXTENSION"
msgstr "EKSTENSI"

#: app/flatpak-builtins-build-init.c:58
msgid "Extension tag to use if building extension"
msgstr "Tanda ekstensi untuk digunakan jika ekstensi membangun"

#: app/flatpak-builtins-build-init.c:58
msgid "EXTENSION_TAG"
msgstr "TANDA_EKSTENSI"

#: app/flatpak-builtins-build-init.c:59
msgid "Initialize /usr with a writable copy of the sdk"
msgstr "Inisialisasi /usr dengan salinan sdk yang dapat ditulis"

#: app/flatpak-builtins-build-init.c:60
msgid "Specify the build type (app, runtime, extension)"
msgstr "Tentukan jenis bangun (aplikasi, runtime, ekstensi)"

#: app/flatpak-builtins-build-init.c:60
msgid "TYPE"
msgstr "JENIS"

#: app/flatpak-builtins-build-init.c:61
msgid "Add a tag"
msgstr "Tambahkan tanda"

#: app/flatpak-builtins-build-init.c:61
msgid "TAG"
msgstr "TANDA"

#: app/flatpak-builtins-build-init.c:62
msgid "Include this sdk extension in /usr"
msgstr "Sertakan ekstensi sdk ini di /usr"

#: app/flatpak-builtins-build-init.c:64
msgid "Where to store sdk (defaults to 'usr')"
msgstr "Di mana tempat menyimpan sdk (bawaannya ke 'usr')"

#: app/flatpak-builtins-build-init.c:65
msgid "Re-initialize the sdk/var"
msgstr "Menginisialisasi ulang sdk/var"

#: app/flatpak-builtins-build-init.c:118
#, c-format
msgid "Requested extension %s/%s/%s is only partially installed"
msgstr "Ekstensi %s/%s/%s yang diminta hanya dipasang sebagian"

#: app/flatpak-builtins-build-init.c:147
#, c-format
msgid "Requested extension %s/%s/%s not installed"
msgstr "Ekstensi %s/%s/%s yang diminta tidak dipasang"

#: app/flatpak-builtins-build-init.c:207
msgid ""
"DIRECTORY APPNAME SDK RUNTIME [BRANCH] - Initialize a directory for building"
msgstr ""
"DIREKTORI NAMAAPL SDK RUNTIME [CABANG] - Menginisialisasi direktori untuk "
"membangun"

#: app/flatpak-builtins-build-init.c:214
msgid "RUNTIME must be specified"
msgstr "RUNTIME harus ditentukan"

#: app/flatpak-builtins-build-init.c:235
#, c-format
msgid "'%s' is not a valid build type name, use app, runtime or extension"
msgstr ""
"'%s' bukan nama jenis bangun yang valid, gunakan app, runtime, atau ekstensi"

#: app/flatpak-builtins-build-init.c:241 app/flatpak-builtins-override.c:79
#, c-format
msgid "'%s' is not a valid application name: %s"
msgstr "'%s' bukan nama aplikasi yang valid: %s"

#: app/flatpak-builtins-build-init.c:295
#, c-format
msgid "Build directory %s already initialized"
msgstr "Direktori bangun %s sudah diinisialisasi"

#: app/flatpak-builtins-build-sign.c:42 app/flatpak-builtins-install.c:67
#: app/flatpak-builtins-remote-info.c:54
msgid "Arch to install for"
msgstr "Arsitektur tujuan pemasangan"

#: app/flatpak-builtins-build-sign.c:43 app/flatpak-builtins-create-usb.c:48
#: app/flatpak-builtins-install.c:74 app/flatpak-builtins-remote-info.c:56
#: app/flatpak-builtins-uninstall.c:58 app/flatpak-builtins-update.c:64
msgid "Look for runtime with the specified name"
msgstr "Cari runtime dengan nama yang ditentukan"

#: app/flatpak-builtins-build-sign.c:66
msgid "LOCATION [ID [BRANCH]] - Sign an application or runtime"
msgstr "LOKASI [ID [CABANG]] - Menandatangani sebuah aplikasi atau runtime"

#: app/flatpak-builtins-build-sign.c:73
#: app/flatpak-builtins-build-update-repo.c:499
#: app/flatpak-builtins-remote-add.c:320 app/flatpak-builtins-repo.c:739
msgid "LOCATION must be specified"
msgstr "LOKASI harus ditentukan"

#: app/flatpak-builtins-build-sign.c:94
msgid "No gpg key ids specified"
msgstr "Tidak ada id kunci gpg yang ditentukan"

#: app/flatpak-builtins-build-update-repo.c:68
msgid "Redirect this repo to a new URL"
msgstr "Arahkan ulang repo ini ke URL baru"

#: app/flatpak-builtins-build-update-repo.c:69
msgid "A nice name to use for this repository"
msgstr "Nama yang bagus untuk digunakan pada repositori ini"

#: app/flatpak-builtins-build-update-repo.c:69
#: app/flatpak-builtins-remote-add.c:77 app/flatpak-builtins-remote-modify.c:82
msgid "TITLE"
msgstr "JUDUL"

#: app/flatpak-builtins-build-update-repo.c:70
msgid "A one-line comment for this repository"
msgstr "Komentar baris-tunggal untuk repositori ini"

#: app/flatpak-builtins-build-update-repo.c:70
#: app/flatpak-builtins-remote-add.c:78 app/flatpak-builtins-remote-modify.c:83
msgid "COMMENT"
msgstr "KOMENTAR"

#: app/flatpak-builtins-build-update-repo.c:71
msgid "A full-paragraph description for this repository"
msgstr "Deskripsi paragraf lengkap untuk repositori ini"

#: app/flatpak-builtins-build-update-repo.c:71
#: app/flatpak-builtins-remote-add.c:79 app/flatpak-builtins-remote-modify.c:84
msgid "DESCRIPTION"
msgstr "DESKRIPSI"

#: app/flatpak-builtins-build-update-repo.c:72
msgid "URL for a website for this repository"
msgstr "URL untuk situs web untuk repositori ini"

#: app/flatpak-builtins-build-update-repo.c:73
msgid "URL for an icon for this repository"
msgstr "URL untuk ikon untuk repositori ini"

#: app/flatpak-builtins-build-update-repo.c:74
msgid "Default branch to use for this repository"
msgstr "Cabang bawaan yang akan digunakan untuk repositori ini"

#: app/flatpak-builtins-build-update-repo.c:74
#: app/flatpak-builtins-remote-add.c:82 app/flatpak-builtins-remote-modify.c:87
#: app/flatpak-builtins-repo.c:713 app/flatpak-builtins-repo.c:714
#: app/flatpak-builtins-run.c:161
msgid "BRANCH"
msgstr "CABANG"

#: app/flatpak-builtins-build-update-repo.c:75
#: app/flatpak-builtins-remote-add.c:83 app/flatpak-builtins-remote-modify.c:88
msgid "COLLECTION-ID"
msgstr "ID-KOLEKSI"

#. Translators: A sideload is when you install from a local USB drive rather than the Internet.
#: app/flatpak-builtins-build-update-repo.c:77
msgid ""
"Permanently deploy collection ID to client remote configurations, only for "
"sideload support"
msgstr ""
"Deploy ID koleksi secara permanen ke konfigurasi remote klien, hanya untuk "
"dukungan sideload"

#: app/flatpak-builtins-build-update-repo.c:78
msgid "Permanently deploy collection ID to client remote configurations"
msgstr "Deploy ID koleksi secara permanen ke konfigurasi klien remote"

#: app/flatpak-builtins-build-update-repo.c:79
msgid "Name of authenticator for this repository"
msgstr "Nama autentikator untuk repositori ini"

#: app/flatpak-builtins-build-update-repo.c:80
msgid "Autoinstall authenticator for this repository"
msgstr "Pasang otomatis autentikator untuk repositori ini"

#: app/flatpak-builtins-build-update-repo.c:81
msgid "Don't autoinstall authenticator for this repository"
msgstr "Jangan pasang otomatis autentikator untuk repositori ini"

#: app/flatpak-builtins-build-update-repo.c:82
#: app/flatpak-builtins-remote-add.c:89
msgid "Authenticator option"
msgstr "Opsi autentikator"

#: app/flatpak-builtins-build-update-repo.c:82
#: app/flatpak-builtins-remote-add.c:89 app/flatpak-builtins-remote-modify.c:95
msgid "KEY=VALUE"
msgstr "KEY=VALUE"

#: app/flatpak-builtins-build-update-repo.c:83
msgid "Import new default GPG public key from FILE"
msgstr "Impor kunci publik GPG bawaan baru dari BERKAS"

#: app/flatpak-builtins-build-update-repo.c:84
msgid "GPG Key ID to sign the summary with"
msgstr "ID Kunci GPG untuk menandatangani ringkasan"

#: app/flatpak-builtins-build-update-repo.c:86
msgid "Generate delta files"
msgstr "Hasilkan berkas delta"

#: app/flatpak-builtins-build-update-repo.c:88
msgid "Don't update the appstream branch"
msgstr "Jangan mutakhirkan cabang appstream"

#: app/flatpak-builtins-build-update-repo.c:89
msgid "Max parallel jobs when creating deltas (default: NUMCPUs)"
msgstr "Tugas paralel maksimal saat membuat delta (standar: NUMCPU)"

#: app/flatpak-builtins-build-update-repo.c:89
msgid "NUM-JOBS"
msgstr "NOMOR-TUGAS"

#: app/flatpak-builtins-build-update-repo.c:90
msgid "Don't create deltas matching refs"
msgstr "Jangan membuat delta yang sesuai dengan ref"

#: app/flatpak-builtins-build-update-repo.c:91
msgid "Prune unused objects"
msgstr "Pangkas objek yang tidak terpakai"

#: app/flatpak-builtins-build-update-repo.c:92
msgid "Prune but don't actually remove anything"
msgstr "Pangkas tetapi jangan benar-benar membuang apa pun"

#: app/flatpak-builtins-build-update-repo.c:93
msgid "Only traverse DEPTH parents for each commit (default: -1=infinite)"
msgstr ""
"Hanya melintasi induk KEDALAMAN untuk setiap komit (bawaan: -1 = tak "
"terbatas)"

#: app/flatpak-builtins-build-update-repo.c:93
msgid "DEPTH"
msgstr "KEDALAMAN"

#: app/flatpak-builtins-build-update-repo.c:223
#, c-format
msgid "Generating delta: %s (%.10s)\n"
msgstr ""
"Menghasilkan delta: %s (%.10s)\n"
"\n"

#: app/flatpak-builtins-build-update-repo.c:225
#, c-format
msgid "Generating delta: %s (%.10s-%.10s)\n"
msgstr "Menghasilkan delta: %s (%.10s-%.10s)\n"

#: app/flatpak-builtins-build-update-repo.c:233
#, c-format
msgid "Failed to generate delta %s (%.10s): "
msgstr "Gagal menghasilkan delta %s (%.10s): "

#: app/flatpak-builtins-build-update-repo.c:236
#, c-format
msgid "Failed to generate delta %s (%.10s-%.10s): "
msgstr "Gagal menghasilkan delta %s (%.10s-%.10s): "

#: app/flatpak-builtins-build-update-repo.c:492
msgid "LOCATION - Update repository metadata"
msgstr "LOKASI - Mutakhirkan metadata repositori"

#: app/flatpak-builtins-build-update-repo.c:609
#, c-format
msgid "Updating appstream branch\n"
msgstr "Memutakhirkan cabang appstream\n"

#: app/flatpak-builtins-build-update-repo.c:638
#, c-format
msgid "Updating summary\n"
msgstr "Memutakhirkan ringkasan\n"

#: app/flatpak-builtins-build-update-repo.c:664
#, c-format
msgid "Total objects: %u\n"
msgstr "Total objek: %u\n"

#: app/flatpak-builtins-build-update-repo.c:666
#, c-format
msgid "No unreachable objects\n"
msgstr "Tidak ada objek yang tidak terjangkau\n"

#: app/flatpak-builtins-build-update-repo.c:668
#, c-format
msgid "Deleted %u objects, %s freed\n"
msgstr "%u objek dihapus, %s dibebaskan\n"

#: app/flatpak-builtins-config.c:41
msgid "List configuration keys and values"
msgstr "Buat daftar kunci dan nilai konfigurasi"

#: app/flatpak-builtins-config.c:42
msgid "Get configuration for KEY"
msgstr "Dapatkan konfigurasi untuk KUNCI"

#: app/flatpak-builtins-config.c:43
msgid "Set configuration for KEY to VALUE"
msgstr "Atur konfigurasi untuk KUNCI ke NILAI"

#: app/flatpak-builtins-config.c:44
msgid "Unset configuration for KEY"
msgstr "Batalkan konfigurasi untuk KUNCI"

#: app/flatpak-builtins-config.c:149
#, c-format
msgid "'%s' does not look like a language/locale code"
msgstr "'%s' tidak terlihat seperti kode bahasa/locale"

#: app/flatpak-builtins-config.c:172
#, c-format
msgid "'%s' does not look like a language code"
msgstr "'%s' tidak terlihat seperti kode bahasa"

#: app/flatpak-builtins-config.c:190
#, fuzzy, c-format
msgid "'%s' is not a valid value (use 'true' or 'false')"
msgstr "'%s' bukan repositori yang valid: "

#: app/flatpak-builtins-config.c:262
#, c-format
msgid "Unknown configure key '%s'"
msgstr "Kunci konfigurasi tidak dikenal '%s'"

#: app/flatpak-builtins-config.c:284
msgid "Too many arguments for --list"
msgstr "Terlalu banyak argumen untuk --list"

#: app/flatpak-builtins-config.c:314 app/flatpak-builtins-config.c:362
msgid "You must specify KEY"
msgstr "Anda harus menentukan KUNCI"

#: app/flatpak-builtins-config.c:316
msgid "Too many arguments for --get"
msgstr "Terlalu banyak argumen untuk --get"

#: app/flatpak-builtins-config.c:338
msgid "You must specify KEY and VALUE"
msgstr "Anda harus menentukan KUNCI dan NILAI"

#: app/flatpak-builtins-config.c:340
msgid "Too many arguments for --set"
msgstr "Terlalu banyak argumen untuk --set"

#: app/flatpak-builtins-config.c:364
msgid "Too many arguments for --unset"
msgstr "Terlalu banyak argumen untuk --unset"

#: app/flatpak-builtins-config.c:383
msgid "[KEY [VALUE]] - Manage configuration"
msgstr "[KUNCI [NILAI]] - Kelola konfigurasi"

#: app/flatpak-builtins-config.c:394
msgid "Can only use one of --list, --get, --set or --unset"
msgstr ""
"Hanya bisa menggunakan salah satu dari --list, --get, --set atau --unset"

#: app/flatpak-builtins-config.c:408
msgid "Must specify one of --list, --get, --set or --unset"
msgstr "Harus menentukan salah satu dari --list, --get, --set atau --unset"

#: app/flatpak-builtins-create-usb.c:45 app/flatpak-builtins-install.c:75
#: app/flatpak-builtins-remote-info.c:57 app/flatpak-builtins-uninstall.c:59
#: app/flatpak-builtins-update.c:65
msgid "Look for app with the specified name"
msgstr "Cari aplikasi dengan nama yang ditentukan"

#: app/flatpak-builtins-create-usb.c:46
msgid "Arch to copy"
msgstr "Arsitektur yang disalin"

#: app/flatpak-builtins-create-usb.c:47
msgid "DEST"
msgstr "DEST"

#: app/flatpak-builtins-create-usb.c:49
msgid "Allow partial commits in the created repo"
msgstr "Izinkan komit parsial dalam repo yang dibuat"

#: app/flatpak-builtins-create-usb.c:125 app/flatpak-builtins-create-usb.c:165
#, c-format
msgid ""
"Warning: Related ref ‘%s’ is partially installed. Use --allow-partial to "
"suppress this message.\n"
msgstr ""
"Peringatan: Ref terkait '%s' terpasang sebagian. Gunakan --allow-partial "
"untuk menekan pesan ini.\n"

#: app/flatpak-builtins-create-usb.c:158
#, c-format
msgid "Warning: Omitting related ref ‘%s’ because it is not installed.\n"
msgstr "Peringatan: Menghilangkan ref terkait '%s' karena tidak dipasang.\n"

#: app/flatpak-builtins-create-usb.c:175
#, c-format
msgid ""
"Warning: Omitting related ref ‘%s’ because its remote ‘%s’ does not have a "
"collection ID set.\n"
msgstr ""
"Peringatan: Menghilangkan ref terkait '%s' karena remote ‘%s’ tidak memiliki "
"koleksi kumpulan ID.\n"

#: app/flatpak-builtins-create-usb.c:187
#, c-format
msgid "Warning: Omitting related ref ‘%s’ because it's extra-data.\n"
msgstr ""
"Peringatan: Menghilangkan ref terkait '%s' karena ini adalah extra-data.\n"

#: app/flatpak-builtins-create-usb.c:262 app/flatpak-builtins-create-usb.c:637
#, c-format
msgid ""
"Remote ‘%s’ does not have a collection ID set, which is required for P2P "
"distribution of ‘%s’."
msgstr ""
"Remote ‘%s’ tidak memiliki koleksi kumpulan ID, yang diperlukan untuk "
"distribusi P2P ‘%s’."

#: app/flatpak-builtins-create-usb.c:272
#, c-format
msgid "Warning: Omitting ref ‘%s’ (runtime of ‘%s’) because it's extra-data.\n"
msgstr ""
"Peringatan: Menghilangkan ref '%s' (runtime dari ‘%s’) karena ini adalah "
"extra-data.\n"

#: app/flatpak-builtins-create-usb.c:484
msgid "MOUNT-PATH [REF…] - Copy apps or runtimes onto removable media"
msgstr "MOUNT-PATH [REF...] - Menyalin aplikasi atau runtime ke media lepasan"

#: app/flatpak-builtins-create-usb.c:493
msgid "MOUNT-PATH and REF must be specified"
msgstr "MOUNT-PATH dan REF harus ditentukan"

#: app/flatpak-builtins-create-usb.c:607
#, c-format
msgid "Ref ‘%s’ found in multiple installations: %s. You must specify one."
msgstr ""
"Ref ‘%s’ ditemukan pada beberapa pemasangan: %s. Anda harus menentukan satu."

#: app/flatpak-builtins-create-usb.c:620
#, c-format
msgid "Refs must all be in the same installation (found in %s and %s)."
msgstr ""
"Ref harus semuanya berada pada pemasangan yang sama (ditemukan di %s dan %s)."

#: app/flatpak-builtins-create-usb.c:670
#, c-format
msgid ""
"Warning: Ref ‘%s’ is partially installed. Use --allow-partial to suppress "
"this message.\n"
msgstr ""
"Peringatan: Ref '%s' terpasang sebagian. Gunakan --allow-partial untuk "
"menekan pesan ini.\n"

#: app/flatpak-builtins-create-usb.c:681
#, c-format
msgid "Installed ref ‘%s’ is extra-data, and cannot be distributed offline"
msgstr ""
"Ref '%s' yang dipasang adalah extra-data, dan tidak dapat didistribusikan "
"secara luring"

#: app/flatpak-builtins-create-usb.c:721
#, c-format
msgid "Warning: Couldn't update repo metadata for remote ‘%s’: %s\n"
msgstr "Peringatan: Tidak dapat memutakhirkan metadata repo untuk '%s': %s\n"

#: app/flatpak-builtins-create-usb.c:751
#, c-format
msgid "Warning: Couldn't update appstream data for remote ‘%s’ arch ‘%s’: %s\n"
msgstr ""
"Peringatan: Tidak dapat memutakhirkan data appstream untuk remote ‘%s’ "
"arsitektur ‘%s’:%s\n"

#. Print a warning if both appstream and appstream2 are missing
#: app/flatpak-builtins-create-usb.c:784
#, c-format
msgid ""
"Warning: Couldn't find appstream data for remote ‘%s’ arch ‘%s’: %s; %s\n"
msgstr ""
"Peringatan: Tidak dapat menemukan data appstream untuk remote ‘%s’ "
"arsitektur ‘%s’: %s; %s\n"

#. Appstream2 is only for efficiency, so just print a debug message
#: app/flatpak-builtins-create-usb.c:790
#, c-format
msgid "Couldn't find appstream2 data for remote ‘%s’ arch ‘%s’: %s\n"
msgstr ""
"Tidak dapat menemukan data appstream2 untuk remote ‘%s’ arsitektur ‘%s’:%s\n"

#: app/flatpak-builtins-document-export.c:62
msgid "Create a unique document reference"
msgstr "Buat referensi dokumen yang unik"

#: app/flatpak-builtins-document-export.c:63
msgid "Make the document transient for the current session"
msgstr "Buat dokumen sementara untuk sesi saat ini"

#: app/flatpak-builtins-document-export.c:64
msgid "Don't require the file to exist already"
msgstr "Tidak memerlukan berkas yang sudah ada"

#: app/flatpak-builtins-document-export.c:65
msgid "Give the app read permissions"
msgstr "Berikan aplikasi izin untuk membaca"

#: app/flatpak-builtins-document-export.c:66
msgid "Give the app write permissions"
msgstr "Berikan aplikasi izin untuk menulis"

#: app/flatpak-builtins-document-export.c:67
msgid "Give the app delete permissions"
msgstr "Berikan aplikasi izin untuk menghapus"

#: app/flatpak-builtins-document-export.c:68
msgid "Give the app permissions to grant further permissions"
msgstr "Berikan izin aplikasi untuk memberikan izin lebih lanjut"

#: app/flatpak-builtins-document-export.c:69
msgid "Revoke read permissions of the app"
msgstr "Cabut izin baca dari aplikasi"

#: app/flatpak-builtins-document-export.c:70
msgid "Revoke write permissions of the app"
msgstr "Cabut izin tulis dari aplikasi"

#: app/flatpak-builtins-document-export.c:71
msgid "Revoke delete permissions of the app"
msgstr "Cabut izin hapus dari aplikasi"

#: app/flatpak-builtins-document-export.c:72
msgid "Revoke the permission to grant further permissions"
msgstr "Cabut izin untuk memberikan izin lebih lanjut"

#: app/flatpak-builtins-document-export.c:73
msgid "Add permissions for this app"
msgstr "Tambahkan izin untuk aplikasi ini"

#: app/flatpak-builtins-document-export.c:73
msgid "APPID"
msgstr "APPID"

#: app/flatpak-builtins-document-export.c:100
msgid "FILE - Export a file to apps"
msgstr "BERKAS - Ekspor berkas ke aplikasi"

#: app/flatpak-builtins-document-export.c:109
#: app/flatpak-builtins-document-info.c:72
#: app/flatpak-builtins-document-unexport.c:67
msgid "FILE must be specified"
msgstr "BERKAS harus ditentukan"

#: app/flatpak-builtins-document-info.c:63
msgid "FILE - Get information about an exported file"
msgstr "BERKAS - Dapatkan informasi tentang berkas yang diekspor"

#: app/flatpak-builtins-document-info.c:100
#: app/flatpak-builtins-document-unexport.c:94
#, c-format
msgid "Not exported\n"
msgstr "Tidak diekspor\n"

#: app/flatpak-builtins-document-list.c:43 app/flatpak-builtins-history.c:53
#: app/flatpak-builtins-list.c:54 app/flatpak-builtins-ps.c:43
#: app/flatpak-builtins-remote-list.c:45 app/flatpak-builtins-remote-ls.c:59
#: app/flatpak-builtins-search.c:38
msgid "What information to show"
msgstr "Informasi apa untuk ditampilkan"

#: app/flatpak-builtins-document-list.c:43 app/flatpak-builtins-history.c:53
#: app/flatpak-builtins-list.c:54 app/flatpak-builtins-ps.c:43
#: app/flatpak-builtins-remote-list.c:45 app/flatpak-builtins-remote-ls.c:59
#: app/flatpak-builtins-search.c:38
msgid "FIELD,…"
msgstr "RUAS,…"

#: app/flatpak-builtins-document-list.c:44 app/flatpak-builtins-history.c:54
#: app/flatpak-builtins-list.c:52 app/flatpak-builtins-permission-list.c:43
#: app/flatpak-builtins-permission-show.c:43 app/flatpak-builtins-ps.c:44
#: app/flatpak-builtins-remote-list.c:46 app/flatpak-builtins-remote-ls.c:63
#: app/flatpak-builtins-repo.c:717 app/flatpak-builtins-search.c:39
#, fuzzy
msgid "Show output in JSON format"
msgstr "Tampilkan informasi ekstra"

#: app/flatpak-builtins-document-list.c:49
msgid "Show the document ID"
msgstr "Tampilkan ID dokumen"

#: app/flatpak-builtins-document-list.c:50
msgid "Path"
msgstr "Path"

#: app/flatpak-builtins-document-list.c:50
#: app/flatpak-builtins-document-list.c:51
msgid "Show the document path"
msgstr "Tampilkan path dokumen"

#: app/flatpak-builtins-document-list.c:51 app/flatpak-builtins-list.c:66
#: app/flatpak-builtins-remote-ls.c:74
msgid "Origin"
msgstr "Asal"

#: app/flatpak-builtins-document-list.c:52 app/flatpak-builtins-history.c:62
#: app/flatpak-builtins-ps.c:52
msgid "Application"
msgstr "Aplikasi"

#: app/flatpak-builtins-document-list.c:52
msgid "Show applications with permission"
msgstr "Tampilkan aplikasi dengan izin"

#: app/flatpak-builtins-document-list.c:53
#: app/flatpak-builtins-permission-list.c:182
#: app/flatpak-builtins-permission-show.c:145
msgid "Permissions"
msgstr "Izin"

#: app/flatpak-builtins-document-list.c:53
msgid "Show permissions for applications"
msgstr "Tampilkan izin untuk aplikasi"

#: app/flatpak-builtins-document-list.c:161
#, fuzzy, c-format
msgid "No documents found\n"
msgstr "Tidak ditemukan kecocokan"

#: app/flatpak-builtins-document-list.c:180
msgid "[APPID] - List exported files"
msgstr "[APPID] - Daftar berkas yang diekspor"

#: app/flatpak-builtins-document-unexport.c:43
msgid "Specify the document ID"
msgstr "Tentukan ID dokumen"

#: app/flatpak-builtins-document-unexport.c:58
msgid "FILE - Unexport a file to apps"
msgstr "BERKAS - Tidak mengekspor berkas ke aplikasi"

#: app/flatpak-builtins-enter.c:88
msgid "INSTANCE COMMAND [ARGUMENT…] - Run a command inside a running sandbox"
msgstr ""
"INSTANCE PERINTAH [ARGUMEN...] - Jalankan perintah di dalam sandbox yang "
"sedang berjalan"

#: app/flatpak-builtins-enter.c:111
msgid "INSTANCE and COMMAND must be specified"
msgstr "INSTANCE dan PERINTAH harus ditentukan"

#: app/flatpak-builtins-enter.c:138
#, c-format
msgid "%s is neither a pid nor an application or instance ID"
msgstr "%s bukan pid atau aplikasi atau ID instance"

#: app/flatpak-builtins-enter.c:144
msgid "entering not supported (need unprivileged user namespaces, or sudo -E)"
msgstr ""
"enter tidak didukung (perlu ruang nama pengguna yang tidak terjangkau, atau "
"sudo -E)"

#: app/flatpak-builtins-enter.c:145
#, c-format
msgid "No such pid %s"
msgstr "Tidak ada pid seperti itu %s"

#: app/flatpak-builtins-enter.c:158
msgid "Can't read cwd"
msgstr "Tidak bisa membaca cwd"

#: app/flatpak-builtins-enter.c:163
msgid "Can't read root"
msgstr "Tidak bisa membaca root"

#: app/flatpak-builtins-enter.c:191
#, c-format
msgid "Invalid %s namespace for pid %d"
msgstr "Namespace %s tidak valid untuk pid %d"

#: app/flatpak-builtins-enter.c:202
#, c-format
msgid "Invalid %s namespace for self"
msgstr "Namespace %s tidak valid untuk diri sendiri"

#: app/flatpak-builtins-enter.c:216
#, c-format
msgid "Can't open %s namespace: %s"
msgstr "Tidak dapat membuka namespace %s: %s"

#: app/flatpak-builtins-enter.c:226
msgid "entering not supported (need unprivileged user namespaces)"
msgstr "enter tidak didukung (perlu ruang nama pengguna yang tidak terjangkau)"

#: app/flatpak-builtins-enter.c:227
#, c-format
msgid "Can't enter %s namespace: %s"
msgstr "Tidak dapat memasuki namespace %s: %s"

#: app/flatpak-builtins-enter.c:234
msgid "Can't chdir"
msgstr "Tidak dapat chdir"

#: app/flatpak-builtins-enter.c:237
msgid "Can't chroot"
msgstr "Tidak dapat chroot"

#: app/flatpak-builtins-enter.c:240
msgid "Can't switch gid"
msgstr "Tidak dapat berganti gid"

#: app/flatpak-builtins-enter.c:243
msgid "Can't switch uid"
msgstr "Tidak dapat berganti uid"

#: app/flatpak-builtins-history.c:50
msgid "Only show changes after TIME"
msgstr "Hanya tampilkan perubahan setelah WAKTU"

#: app/flatpak-builtins-history.c:50 app/flatpak-builtins-history.c:51
msgid "TIME"
msgstr "WAKTU"

#: app/flatpak-builtins-history.c:51
msgid "Only show changes before TIME"
msgstr "Hanya tampilkan perubahan sebelum WAKTU"

#: app/flatpak-builtins-history.c:52
msgid "Show newest entries first"
msgstr "Tampilkan entri terbaru terlebih dahulu"

#: app/flatpak-builtins-history.c:59
msgid "Time"
msgstr "Waktu"

#: app/flatpak-builtins-history.c:59
msgid "Show when the change happened"
msgstr "Tampilkan saat perubahan itu terjadi"

#: app/flatpak-builtins-history.c:60
msgid "Change"
msgstr "Ubah"

#: app/flatpak-builtins-history.c:60
msgid "Show the kind of change"
msgstr "Tampilkan jenis perubahan"

#: app/flatpak-builtins-history.c:61 app/flatpak-builtins-list.c:68
#: app/flatpak-builtins-remote-ls.c:75 app/flatpak-builtins-repo.c:335
msgid "Ref"
msgstr "Ref"

#: app/flatpak-builtins-history.c:61 app/flatpak-builtins-list.c:68
#: app/flatpak-builtins-remote-ls.c:75
msgid "Show the ref"
msgstr "Tampilkan ref"

#: app/flatpak-builtins-history.c:62
msgid "Show the application/runtime ID"
msgstr "Tampilkan ID aplikasi/runtime"

#: app/flatpak-builtins-history.c:63 app/flatpak-builtins-list.c:64
#: app/flatpak-builtins-ps.c:53 app/flatpak-builtins-remote-ls.c:73
#: app/flatpak-cli-transaction.c:1435
msgid "Arch"
msgstr "Arsitektur"

#: app/flatpak-builtins-history.c:63 app/flatpak-builtins-list.c:64
#: app/flatpak-builtins-ps.c:53 app/flatpak-builtins-remote-ls.c:73
msgid "Show the architecture"
msgstr "Tampilkan arsitektur"

#: app/flatpak-builtins-history.c:64 app/flatpak-builtins-list.c:63
#: app/flatpak-builtins-ps.c:54 app/flatpak-builtins-remote-ls.c:72
#: app/flatpak-builtins-search.c:48 app/flatpak-cli-transaction.c:1438
msgid "Branch"
msgstr "Cabang"

#: app/flatpak-builtins-history.c:64 app/flatpak-builtins-list.c:63
#: app/flatpak-builtins-remote-ls.c:72
msgid "Show the branch"
msgstr "Tampilkan cabang"

#: app/flatpak-builtins-history.c:65 app/flatpak-builtins-list.c:67
msgid "Installation"
msgstr "Pemasangan"

#: app/flatpak-builtins-history.c:65
msgid "Show the affected installation"
msgstr "Tampilkan pemasangan yang terpengaruh"

#: app/flatpak-builtins-history.c:66 app/flatpak-cli-transaction.c:1452
msgid "Remote"
msgstr "Remote"

#: app/flatpak-builtins-history.c:66
msgid "Show the remote"
msgstr "Tampilkan remote"

#: app/flatpak-builtins-history.c:67 app/flatpak-builtins-ps.c:55
#: app/flatpak-builtins-remote-ls.c:76
msgid "Commit"
msgstr "Komit"

#: app/flatpak-builtins-history.c:67
msgid "Show the current commit"
msgstr "Tampilkan komit saat ini"

#: app/flatpak-builtins-history.c:68
msgid "Old Commit"
msgstr "Komit Lama"

#: app/flatpak-builtins-history.c:68
msgid "Show the previous commit"
msgstr "Tampilkan komit sebelumnya"

#: app/flatpak-builtins-history.c:69
msgid "Show the remote URL"
msgstr "Tampilkan URL remote"

#: app/flatpak-builtins-history.c:70 app/flatpak-cli-transaction.c:700
msgid "User"
msgstr "Pengguna"

#: app/flatpak-builtins-history.c:70
msgid "Show the user doing the change"
msgstr "Tampilkan pengguna yang melakukan perubahan"

#: app/flatpak-builtins-history.c:71
msgid "Tool"
msgstr "Perkakas"

#: app/flatpak-builtins-history.c:71
msgid "Show the tool that was used"
msgstr "Tampilkan perkakas yang digunakan"

#: app/flatpak-builtins-history.c:72 app/flatpak-builtins-list.c:62
#: app/flatpak-builtins-remote-ls.c:71 app/flatpak-builtins-search.c:47
msgid "Version"
msgstr "Versi"

#: app/flatpak-builtins-history.c:72
msgid "Show the Flatpak version"
msgstr "Tampilkan versi Flatpak"

#: app/flatpak-builtins-history.c:91
#, c-format
msgid "Failed to get journal data (%s): %s"
msgstr "Gagal memuat data jurnal (%s): %s"

#: app/flatpak-builtins-history.c:146
#, c-format
msgid "Failed to open journal: %s"
msgstr "Gagal membuka jurnal: %s"

#: app/flatpak-builtins-history.c:153
#, c-format
msgid "Failed to add match to journal: %s"
msgstr "Gagal menambahkan kecocokan ke jurnal: %s"

#: app/flatpak-builtins-history.c:471
msgid " - Show history"
msgstr " - Tampilkan riwayat"

#: app/flatpak-builtins-history.c:490
#, c-format
msgid "Failed to parse the --since option"
msgstr "Gagal menguraikan opsi --since"

#: app/flatpak-builtins-history.c:501
#, c-format
msgid "Failed to parse the --until option"
msgstr "Gagal mengurai opsi --until"

#: app/flatpak-builtins-info.c:56
msgid "Show user installations"
msgstr "Tampilkan pemasangan pengguna"

#: app/flatpak-builtins-info.c:57
msgid "Show system-wide installations"
msgstr "Tampilkan pemasangan di seluruh sistem"

#: app/flatpak-builtins-info.c:58
msgid "Show specific system-wide installations"
msgstr "Tampilkan pemasangan tertentu di seluruh sistem"

#: app/flatpak-builtins-info.c:59 app/flatpak-builtins-remote-info.c:59
msgid "Show ref"
msgstr "Tampilkan ref"

#: app/flatpak-builtins-info.c:60 app/flatpak-builtins-remote-info.c:60
msgid "Show commit"
msgstr "Tampilkan komit"

#: app/flatpak-builtins-info.c:61
msgid "Show origin"
msgstr "Tampilkan asal"

#: app/flatpak-builtins-info.c:62
msgid "Show size"
msgstr "Tampilkan ukuran"

#: app/flatpak-builtins-info.c:63 app/flatpak-builtins-remote-info.c:62
msgid "Show metadata"
msgstr "Tampilkan metadata"

#: app/flatpak-builtins-info.c:64 app/flatpak-builtins-remote-info.c:63
msgid "Show runtime"
msgstr "Tampilkan runtime"

#: app/flatpak-builtins-info.c:65 app/flatpak-builtins-remote-info.c:64
msgid "Show sdk"
msgstr "Tampilkan sdk"

#: app/flatpak-builtins-info.c:66
msgid "Show permissions"
msgstr "Tampilkan izin"

#: app/flatpak-builtins-info.c:67
msgid "Query file access"
msgstr "Akses berkas kueri"

#: app/flatpak-builtins-info.c:67 app/flatpak-builtins-install.c:82
#: app/flatpak-builtins-install.c:88 app/flatpak-builtins-preinstall.c:68
#: app/flatpak-builtins-run.c:182 app/flatpak-builtins-run.c:184
#: app/flatpak-builtins-update.c:67 app/flatpak-builtins-update.c:71
msgid "PATH"
msgstr "PATH"

#: app/flatpak-builtins-info.c:68
msgid "Show extensions"
msgstr "Tampilkan ekstensi"

#: app/flatpak-builtins-info.c:69
msgid "Show location"
msgstr "Tampilkan lokasi"

#: app/flatpak-builtins-info.c:116
msgid "NAME [BRANCH] - Get info about an installed app or runtime"
msgstr ""
"NAMA [CABANG] - Dapatkan info tentang aplikasi atau runtime yang terpasang"

#: app/flatpak-builtins-info.c:123 app/flatpak-builtins-remote-add.c:317
#: app/flatpak-builtins-remote-delete.c:63
msgid "NAME must be specified"
msgstr "NAMA harus ditentukan"

#: app/flatpak-builtins-info.c:196
msgid "ref not present in origin"
msgstr "ref tidak ada di asal"

#: app/flatpak-builtins-info.c:211 app/flatpak-builtins-remote-info.c:217
#, c-format
msgid "Warning: Commit has no flatpak metadata\n"
msgstr "Peringatan: Komit tidak memiliki metadata flatpak\n"

#: app/flatpak-builtins-info.c:217 app/flatpak-builtins-info.c:259
#: app/flatpak-builtins-info.c:455 app/flatpak-builtins-info.c:513
#: app/flatpak-builtins-remote-info.c:236
#: app/flatpak-builtins-remote-info.c:271
msgid "ID:"
msgstr "ID:"

#: app/flatpak-builtins-info.c:218 app/flatpak-builtins-info.c:260
#: app/flatpak-builtins-remote-info.c:237
#: app/flatpak-builtins-remote-info.c:272
msgid "Ref:"
msgstr "Ref:"

#: app/flatpak-builtins-info.c:219 app/flatpak-builtins-info.c:261
#: app/flatpak-builtins-remote-info.c:238
#: app/flatpak-builtins-remote-info.c:273
msgid "Arch:"
msgstr "Arsitektur:"

#: app/flatpak-builtins-info.c:220 app/flatpak-builtins-info.c:262
#: app/flatpak-builtins-remote-info.c:239
#: app/flatpak-builtins-remote-info.c:274
msgid "Branch:"
msgstr "Cabang:"

#: app/flatpak-builtins-info.c:222 app/flatpak-builtins-info.c:264
#: app/flatpak-builtins-remote-info.c:241
#: app/flatpak-builtins-remote-info.c:276
msgid "Version:"
msgstr "Versi:"

#: app/flatpak-builtins-info.c:224 app/flatpak-builtins-info.c:266
#: app/flatpak-builtins-remote-info.c:243
#: app/flatpak-builtins-remote-info.c:278
msgid "License:"
msgstr "Lisensi:"

#: app/flatpak-builtins-info.c:226 app/flatpak-builtins-info.c:269
#: app/flatpak-builtins-remote-info.c:245
#: app/flatpak-builtins-remote-info.c:280
msgid "Collection:"
msgstr "Koleksi:"

#: app/flatpak-builtins-info.c:227 app/flatpak-builtins-info.c:270
#: app/flatpak-builtins-info.c:458 app/flatpak-builtins-info.c:516
msgid "Installation:"
msgstr "Pemasangan:"

#: app/flatpak-builtins-info.c:228 app/flatpak-builtins-info.c:271
#: app/flatpak-builtins-info.c:459 app/flatpak-builtins-info.c:517
#: app/flatpak-builtins-remote-info.c:249
#: app/flatpak-builtins-remote-info.c:284
#, fuzzy
msgid "Installed Size:"
msgstr "Ukuran terpasang:"

#: app/flatpak-builtins-info.c:231 app/flatpak-builtins-info.c:279
#: app/flatpak-builtins-remote-info.c:252
#: app/flatpak-builtins-remote-info.c:288
msgid "Runtime:"
msgstr "Runtime:"

#: app/flatpak-builtins-info.c:232 app/flatpak-builtins-info.c:288
#: app/flatpak-builtins-remote-info.c:253
#: app/flatpak-builtins-remote-info.c:293
msgid "Sdk:"
msgstr "Sdk:"

#: app/flatpak-builtins-info.c:235 app/flatpak-builtins-info.c:313
#: app/flatpak-builtins-remote-info.c:256
#: app/flatpak-builtins-remote-info.c:319
msgid "Date:"
msgstr "Tanggal:"

#: app/flatpak-builtins-info.c:237 app/flatpak-builtins-info.c:311
#: app/flatpak-builtins-remote-info.c:258
#: app/flatpak-builtins-remote-info.c:317
msgid "Subject:"
msgstr "Subjek:"

#: app/flatpak-builtins-info.c:240 app/flatpak-builtins-info.c:295
msgid "Active commit:"
msgstr "Komit aktif:"

#: app/flatpak-builtins-info.c:241 app/flatpak-builtins-info.c:298
msgid "Latest commit:"
msgstr "Komit terbaru:"

#: app/flatpak-builtins-info.c:244 app/flatpak-builtins-info.c:303
#: app/flatpak-builtins-info.c:457 app/flatpak-builtins-info.c:515
#: app/flatpak-builtins-remote-info.c:259
#: app/flatpak-builtins-remote-info.c:298
msgid "Commit:"
msgstr "Komit:"

#: app/flatpak-builtins-info.c:246 app/flatpak-builtins-info.c:308
#: app/flatpak-builtins-remote-info.c:261
#: app/flatpak-builtins-remote-info.c:303
msgid "Parent:"
msgstr "Induk:"

#: app/flatpak-builtins-info.c:248 app/flatpak-builtins-info.c:321
msgid "Alt-id:"
msgstr "Alt-id:"

#: app/flatpak-builtins-info.c:250 app/flatpak-builtins-info.c:325
#: app/flatpak-builtins-remote-info.c:263
#: app/flatpak-builtins-remote-info.c:308
msgid "End-of-life:"
msgstr "Akhir-masa-pakai:"

#: app/flatpak-builtins-info.c:252 app/flatpak-builtins-info.c:330
#: app/flatpak-builtins-remote-info.c:265
#: app/flatpak-builtins-remote-info.c:313
msgid "End-of-life-rebase:"
msgstr "Rebase-akhir-masa-pakai:"

#: app/flatpak-builtins-info.c:254 app/flatpak-builtins-info.c:317
msgid "Subdirectories:"
msgstr "Subdirektori:"

#: app/flatpak-builtins-info.c:255 app/flatpak-builtins-info.c:454
#: app/flatpak-builtins-info.c:512
msgid "Extension:"
msgstr "Ekstensi:"

#: app/flatpak-builtins-info.c:267 app/flatpak-builtins-info.c:456
#: app/flatpak-builtins-info.c:514
msgid "Origin:"
msgstr "Asal:"

#: app/flatpak-builtins-info.c:460 app/flatpak-builtins-info.c:522
msgid "Subpaths:"
msgstr "Subpath:"

#: app/flatpak-builtins-info.c:478
msgid "unmaintained"
msgstr "tidak dirawat"

#: app/flatpak-builtins-info.c:480 app/flatpak-builtins-info.c:482
msgid "unknown"
msgstr "tidak dikenal"

#: app/flatpak-builtins-install.c:68 app/flatpak-builtins-preinstall.c:57
msgid "Don't pull, only install from local cache"
msgstr "Jangan tarik, hanya memasang dari singgahan lokal"

#: app/flatpak-builtins-install.c:69 app/flatpak-builtins-preinstall.c:58
#: app/flatpak-builtins-update.c:60
msgid "Don't deploy, only download to local cache"
msgstr "Jangan deploy, hanya mengunduh ke singgahan lokal"

#: app/flatpak-builtins-install.c:70 app/flatpak-builtins-preinstall.c:59
msgid "Don't install related refs"
msgstr "Jangan pasang ref yang terkait"

#: app/flatpak-builtins-install.c:71 app/flatpak-builtins-preinstall.c:60
#: app/flatpak-builtins-update.c:62
msgid "Don't verify/install runtime dependencies"
msgstr "Jangan memverifikasi/memasang dependensi runtime"

#: app/flatpak-builtins-install.c:72
msgid "Don't automatically pin explicit installs"
msgstr "Jangan secara otomatis menyematkan pemasangan eksplisit"

#: app/flatpak-builtins-install.c:73 app/flatpak-builtins-preinstall.c:61
#: app/flatpak-builtins-update.c:63
msgid "Don't use static deltas"
msgstr "Jangan menggunakan delta statis"

#: app/flatpak-builtins-install.c:76 app/flatpak-builtins-preinstall.c:62
msgid "Additionally install the SDK used to build the given refs"
msgstr "Selain itu, pasang SDK yang digunakan untuk membuat ref yang diberikan"

#: app/flatpak-builtins-install.c:77 app/flatpak-builtins-preinstall.c:63
msgid ""
"Additionally install the debug info for the given refs and their dependencies"
msgstr ""
"Selain itu, pasang info awakutu untuk ref yang diberikan dan dependensinya"

#: app/flatpak-builtins-install.c:78
msgid "Assume LOCATION is a .flatpak single-file bundle"
msgstr "Asumsikan LOKASI adalah bundel berkas tunggal .flatpak"

#: app/flatpak-builtins-install.c:79
msgid "Assume LOCATION is a .flatpakref application description"
msgstr "Asumsikan LOKASI adalah deskripsi aplikasi .flatpakref"

#: app/flatpak-builtins-install.c:80
msgid "Assume LOCATION is containers-transports(5) reference to an OCI image"
msgstr ""

#: app/flatpak-builtins-install.c:81
msgid "Check bundle signatures with GPG key from FILE (- for stdin)"
msgstr ""
"Periksa tanda tangan bundel dengan kunci GPG dari BERKAS (-untuk stdin)"

#: app/flatpak-builtins-install.c:82
msgid "Only install this subpath"
msgstr "Hanya pasang subpath ini"

#: app/flatpak-builtins-install.c:83 app/flatpak-builtins-preinstall.c:64
#: app/flatpak-builtins-uninstall.c:63 app/flatpak-builtins-update.c:68
msgid "Automatically answer yes for all questions"
msgstr "Secara otomatis menjawab ya untuk semua pertanyaan"

#: app/flatpak-builtins-install.c:84 app/flatpak-builtins-preinstall.c:65
msgid "Uninstall first if already installed"
msgstr "Hapus dulu jika sudah terpasang"

#: app/flatpak-builtins-install.c:85 app/flatpak-builtins-preinstall.c:66
#: app/flatpak-builtins-uninstall.c:64 app/flatpak-builtins-update.c:69
msgid "Produce minimal output and don't ask questions"
msgstr "Menghasilkan keluaran minimal dan jangan bertanya"

#: app/flatpak-builtins-install.c:86
msgid "Update install if already installed"
msgstr "Mutakhirkan pemasangan jika sudah terpasang"

#. Translators: A sideload is when you install from a local USB drive rather than the Internet.
#: app/flatpak-builtins-install.c:88 app/flatpak-builtins-preinstall.c:68
#: app/flatpak-builtins-update.c:71
msgid "Use this local repo for sideloads"
msgstr "Gunakan repo lokal ini untuk sideload"

#: app/flatpak-builtins-install.c:178
msgid "Bundle filename must be specified"
msgstr "Nama berkas bundel harus ditentukan"

#: app/flatpak-builtins-install.c:188
msgid "Remote bundles are not supported"
msgstr "Bundel remote tidak didukung"

#: app/flatpak-builtins-install.c:231
msgid "Filename or uri must be specified"
msgstr "Nama berkas atau uri harus ditentukan"

#: app/flatpak-builtins-install.c:295
#, fuzzy
msgid "Image location must be specified"
msgstr "Setidaknya satu REF harus ditentukan"

#: app/flatpak-builtins-install.c:345
msgid "[LOCATION/REMOTE] [REF…] - Install applications or runtimes"
msgstr "[LOKASI/REMOTE] [REF...] - Pasang aplikasi atau runtime"

#: app/flatpak-builtins-install.c:378
msgid "At least one REF must be specified"
msgstr "Setidaknya satu REF harus ditentukan"

#: app/flatpak-builtins-install.c:392
#, c-format
msgid "Looking for matches…\n"
msgstr ""
"Mencari kecocokan...\n"
"\n"

#: app/flatpak-builtins-install.c:513
#, c-format
msgid "No remote refs found for ‘%s’"
msgstr "Tidak ada remote ref yang ditemukan untuk ‘%s’"

#: app/flatpak-builtins-install.c:573 app/flatpak-builtins-uninstall.c:405
#: common/flatpak-ref-utils.c:689 common/flatpak-ref-utils.c:1595
#, c-format
msgid "Invalid branch %s: %s"
msgstr "Cabang tidak valid %s: %s"

#: app/flatpak-builtins-install.c:606
#, c-format
msgid "Nothing matches %s in local repository for remote %s"
msgstr "Tidak ada yang cocok dengan %s di repositori lokal untuk remote %s"

#: app/flatpak-builtins-install.c:608
#, c-format
msgid "Nothing matches %s in remote %s"
msgstr "Tidak ada yang cocok dengan %s di remote %s"

#: app/flatpak-builtins-install.c:629
#, c-format
msgid "Skipping: %s\n"
msgstr "Melewatkan: %s\n"

#: app/flatpak-builtins-kill.c:110
#, c-format
msgid "%s is not running"
msgstr "%s tidak berjalan"

#: app/flatpak-builtins-kill.c:136
msgid "INSTANCE - Stop a running application"
msgstr "INSTANCE - Menghentikan aplikasi yang sedang berjalan"

#: app/flatpak-builtins-kill.c:144 app/flatpak-builtins-ps.c:256
msgid "Extra arguments given"
msgstr "Argumen ekstra diberikan"

#: app/flatpak-builtins-kill.c:150
msgid "Must specify the app to kill"
msgstr "Harus menentukan aplikasi untuk dibunuh"

#: app/flatpak-builtins-list.c:47
msgid "Show extra information"
msgstr "Tampilkan informasi ekstra"

#: app/flatpak-builtins-list.c:48
msgid "List installed runtimes"
msgstr "Daftar runtime yang terpasang"

#: app/flatpak-builtins-list.c:49
msgid "List installed applications"
msgstr "Daftar aplikasi yang terpasang"

#: app/flatpak-builtins-list.c:50
msgid "Arch to show"
msgstr "Arsitektur yang akan ditampilkan"

#: app/flatpak-builtins-list.c:51 app/flatpak-builtins-remote-ls.c:57
msgid "List all refs (including locale/debug)"
msgstr "Daftar semua ref (termasuk lokal/awakutu)"

#: app/flatpak-builtins-list.c:53 app/flatpak-builtins-remote-ls.c:58
msgid "List all applications using RUNTIME"
msgstr "Daftar semua aplikasi yang menggunakan RUNTIME"

#: app/flatpak-builtins-list.c:59 app/flatpak-builtins-remote-list.c:51
#: app/flatpak-builtins-remote-ls.c:68 app/flatpak-builtins-search.c:44
msgid "Name"
msgstr "Nama"

#: app/flatpak-builtins-list.c:59 app/flatpak-builtins-remote-list.c:51
#: app/flatpak-builtins-remote-ls.c:68 app/flatpak-builtins-search.c:44
msgid "Show the name"
msgstr "Tampilkan nama"

#: app/flatpak-builtins-list.c:60 app/flatpak-builtins-remote-list.c:60
#: app/flatpak-builtins-remote-ls.c:69 app/flatpak-builtins-search.c:45
msgid "Description"
msgstr "Deskripsi"

#: app/flatpak-builtins-list.c:60 app/flatpak-builtins-remote-ls.c:69
#: app/flatpak-builtins-search.c:45
msgid "Show the description"
msgstr "Tampilkan deskripsi"

#: app/flatpak-builtins-list.c:61 app/flatpak-builtins-remote-ls.c:70
#: app/flatpak-builtins-search.c:46
msgid "Application ID"
msgstr "ID Aplikasi"

#: app/flatpak-builtins-list.c:61 app/flatpak-builtins-ps.c:52
#: app/flatpak-builtins-remote-ls.c:70 app/flatpak-builtins-search.c:46
msgid "Show the application ID"
msgstr "Tampilkan ID aplikasi"

#: app/flatpak-builtins-list.c:62 app/flatpak-builtins-remote-ls.c:71
#: app/flatpak-builtins-search.c:47
msgid "Show the version"
msgstr "Tampilkan versi"

#: app/flatpak-builtins-list.c:65 app/flatpak-builtins-ps.c:56
#: app/flatpak-builtins-remote-ls.c:77
msgid "Runtime"
msgstr "Runtime"

#: app/flatpak-builtins-list.c:65
msgid "Show the used runtime"
msgstr "Tampilkan runtime yang digunakan"

#: app/flatpak-builtins-list.c:66 app/flatpak-builtins-remote-ls.c:74
msgid "Show the origin remote"
msgstr "Tampilkan remote asal"

#: app/flatpak-builtins-list.c:67
msgid "Show the installation"
msgstr "Tampilkan pemasangan"

#: app/flatpak-builtins-list.c:69
msgid "Active commit"
msgstr "Komit aktif"

#: app/flatpak-builtins-list.c:69 app/flatpak-builtins-remote-ls.c:76
msgid "Show the active commit"
msgstr "Tampilkan komit aktif"

#: app/flatpak-builtins-list.c:70
msgid "Latest commit"
msgstr "Komit terbaru"

#: app/flatpak-builtins-list.c:70
msgid "Show the latest commit"
msgstr "Tampilkan komit terbaru"

#: app/flatpak-builtins-list.c:71 app/flatpak-builtins-remote-ls.c:78
msgid "Installed size"
msgstr "Ukuran terpasang"

#: app/flatpak-builtins-list.c:71 app/flatpak-builtins-remote-ls.c:78
msgid "Show the installed size"
msgstr "Tampilkan ukuran terpasang"

#: app/flatpak-builtins-list.c:72 app/flatpak-builtins-remote-list.c:58
#: app/flatpak-builtins-remote-ls.c:80 app/flatpak-builtins-repo.c:340
msgid "Options"
msgstr "Opsi"

#: app/flatpak-builtins-list.c:72 app/flatpak-builtins-remote-list.c:58
#: app/flatpak-builtins-remote-ls.c:80
msgid "Show options"
msgstr "Tampilkan opsi"

#: app/flatpak-builtins-list.c:180
#, c-format
msgid "Unable to load details of %s: %s"
msgstr "Tidak dapat memuat rincian %s: %s"

#: app/flatpak-builtins-list.c:190
#, c-format
msgid "Unable to inspect current version of %s: %s"
msgstr "Tidak dapat memeriksa versi %s saat ini: %s"

#: app/flatpak-builtins-list.c:408
msgid " - List installed apps and/or runtimes"
msgstr " - Daftar aplikasi dan/atau runtime yang terpasang"

#: app/flatpak-builtins-make-current.c:38
msgid "Arch to make current for"
msgstr "Arsitektur seperti sekarang"

#: app/flatpak-builtins-make-current.c:58
msgid "APP BRANCH - Make branch of application current"
msgstr "APL CABANG - Buat cabang aplikasi saat ini"

#: app/flatpak-builtins-make-current.c:69 app/flatpak-builtins-run.c:260
msgid "APP must be specified"
msgstr "APL harus ditentukan"

#: app/flatpak-builtins-make-current.c:84
msgid "BRANCH must be specified"
msgstr "CABANG harus ditentukan"

#: app/flatpak-builtins-make-current.c:97
#, c-format
msgid "App %s branch %s is not installed"
msgstr "Aplikasi %s cabang %s tidak terpasang"

#: app/flatpak-builtins-mask.c:42
msgid "Remove matching masks"
msgstr "Hapus mask yang cocok"

#: app/flatpak-builtins-mask.c:54
msgid ""
"[PATTERN…] - disable updates and automatic installation matching patterns"
msgstr ""
"[POLA ...] - nonaktifkan pemutakhiran dan pola pencocokan pemasangan otomatis"

#: app/flatpak-builtins-mask.c:73
#, c-format
msgid "No masked patterns\n"
msgstr "Tidak ada pola mask\n"

#: app/flatpak-builtins-mask.c:78
#, c-format
msgid "Masked patterns:\n"
msgstr "Pola mask:\n"

#: app/flatpak-builtins-override.c:42
msgid "Remove existing overrides"
msgstr "Hapus timpaan yang ada"

#: app/flatpak-builtins-override.c:43
msgid "Show existing overrides"
msgstr "Tampilkan timpaan yang ada"

#: app/flatpak-builtins-override.c:59
msgid "[APP] - Override settings [for application]"
msgstr "[APP] - Timpa pengaturan [untuk aplikasi]"

#: app/flatpak-builtins-permission-list.c:143
msgid "[TABLE] [ID] - List permissions"
msgstr "[TABEL] [ID] - Daftar izin"

#: app/flatpak-builtins-permission-list.c:179
#: app/flatpak-builtins-permission-show.c:142
msgid "Table"
msgstr "Tabel"

#: app/flatpak-builtins-permission-list.c:180
#: app/flatpak-builtins-permission-show.c:143
msgid "Object"
msgstr "Objek"

#: app/flatpak-builtins-permission-list.c:181
#: app/flatpak-builtins-permission-show.c:144
msgid "App"
msgstr "Aplikasi"

#: app/flatpak-builtins-permission-list.c:183
#: app/flatpak-builtins-permission-show.c:146
msgid "Data"
msgstr "Data"

#: app/flatpak-builtins-permission-remove.c:120
msgid "TABLE ID [APP_ID] - Remove item from permission store"
msgstr "TABEL ID [APP_ID] - Hapus butir dari penyimpanan perizinan"

#: app/flatpak-builtins-permission-remove.c:129
#: app/flatpak-builtins-permission-set.c:120
msgid "Too few arguments"
msgstr "Terlalu sedikit argumen"

#: app/flatpak-builtins-permission-reset.c:43
msgid "Reset all permissions"
msgstr "Atur ulang semua izin"

#: app/flatpak-builtins-permission-reset.c:144
msgid "APP_ID - Reset permissions for an app"
msgstr "APP_ID - Atur ulang izin untuk suatu aplikasi"

#: app/flatpak-builtins-permission-reset.c:153
#: app/flatpak-builtins-permission-show.c:124
msgid "Wrong number of arguments"
msgstr "Jumlah argumen salah"

#: app/flatpak-builtins-permission-set.c:42
msgid "Associate DATA with the entry"
msgstr "Asosiasikan DATA dengan entri"

#: app/flatpak-builtins-permission-set.c:42
msgid "DATA"
msgstr "DATA"

#: app/flatpak-builtins-permission-set.c:111
msgid "TABLE ID APP_ID [PERMISSION...] - Set permissions"
msgstr "TABEL ID APP_ID [IZIN ...] - Tetapkan izin"

#: app/flatpak-builtins-permission-set.c:132
#, c-format
msgid "Failed to parse '%s' as GVariant: "
msgstr "Gagal mengurai '%s' sebagai GVariant: "

#: app/flatpak-builtins-permission-show.c:115
msgid "APP_ID - Show permissions for an app"
msgstr "APP_ID - Tampilkan izin untuk suatu aplikasi"

#: app/flatpak-builtins-pin.c:44
msgid "Remove matching pins"
msgstr "Hapus pin yang cocok"

#: app/flatpak-builtins-pin.c:56
msgid "[PATTERN…] - disable automatic removal of runtimes matching patterns"
msgstr "[POLA...] - nonaktifkan penghapusan otomatis pola pencocokan runtime"

#: app/flatpak-builtins-pin.c:75
#, c-format
msgid "No pinned patterns\n"
msgstr "Tidak ada pola yang disematkan\n"

#: app/flatpak-builtins-pin.c:80
#, c-format
msgid "Pinned patterns:\n"
msgstr "Pola yang disematkan:\n"

#: app/flatpak-builtins-preinstall.c:80
msgid "- Install flatpaks that are part of the operating system"
msgstr ""

#: app/flatpak-builtins-preinstall.c:118
#, c-format
msgid "Nothing to do.\n"
msgstr "Tidak ada yang bisa dilakukan.\n"

#: app/flatpak-builtins-ps.c:49
msgid "Instance"
msgstr "Instansi"

#: app/flatpak-builtins-ps.c:49
msgid "Show the instance ID"
msgstr "Tampilkan ID instance"

#: app/flatpak-builtins-ps.c:50 app/flatpak-builtins-run.c:178
msgid "PID"
msgstr "PID"

#: app/flatpak-builtins-ps.c:50
msgid "Show the PID of the wrapper process"
msgstr "Tampilkan PID dari proses bungkus"

#: app/flatpak-builtins-ps.c:51
msgid "Child-PID"
msgstr "PID-anak"

#: app/flatpak-builtins-ps.c:51
msgid "Show the PID of the sandbox process"
msgstr "Tampilkan PID dari proses sandbox"

#: app/flatpak-builtins-ps.c:54 app/flatpak-builtins-search.c:48
msgid "Show the application branch"
msgstr "Tampilkan cabang aplikasi"

#: app/flatpak-builtins-ps.c:55
msgid "Show the application commit"
msgstr "Tampilkan komit aplikasi"

#: app/flatpak-builtins-ps.c:56
msgid "Show the runtime ID"
msgstr "Tampilkan ID runtime"

#: app/flatpak-builtins-ps.c:57
msgid "R.-Branch"
msgstr "R.-Cabang"

#: app/flatpak-builtins-ps.c:57
msgid "Show the runtime branch"
msgstr "Tampilkan cabang runtime"

#: app/flatpak-builtins-ps.c:58
msgid "R.-Commit"
msgstr "R.-Komit"

#: app/flatpak-builtins-ps.c:58
msgid "Show the runtime commit"
msgstr "Tampilkan komit runtime"

#: app/flatpak-builtins-ps.c:59
msgid "Active"
msgstr "Aktif"

#: app/flatpak-builtins-ps.c:59
msgid "Show whether the app is active"
msgstr "Tampilkan apakah aplikasi aktif"

#: app/flatpak-builtins-ps.c:60
msgid "Background"
msgstr "Latar Belakang"

#: app/flatpak-builtins-ps.c:60
msgid "Show whether the app is background"
msgstr "Tampilkan apakah aplikasi tersebut di latar belakang"

#: app/flatpak-builtins-ps.c:246
msgid " - Enumerate running sandboxes"
msgstr " - Enumerasikan sandbox yang berjalan"

#: app/flatpak-builtins-remote-add.c:66
msgid "Do nothing if the provided remote exists"
msgstr "Tidak melakukan apapun jika remote yang disediakan ada"

#: app/flatpak-builtins-remote-add.c:67
msgid "LOCATION specifies a configuration file, not the repo location"
msgstr "LOKASI menentukan berkas konfigurasi, bukan lokasi repo"

#: app/flatpak-builtins-remote-add.c:72 app/flatpak-builtins-remote-modify.c:78
msgid "Disable GPG verification"
msgstr "Nonaktifkan verifikasi GPG"

#: app/flatpak-builtins-remote-add.c:73 app/flatpak-builtins-remote-modify.c:79
msgid "Mark the remote as don't enumerate"
msgstr "Tandai remote untuk tidak dienumerasi"

#: app/flatpak-builtins-remote-add.c:74 app/flatpak-builtins-remote-modify.c:80
msgid "Mark the remote as don't use for deps"
msgstr "Tandai remote untuk tidak digunakan sebagai sumber dependensi"

#: app/flatpak-builtins-remote-add.c:75 app/flatpak-builtins-remote-modify.c:81
msgid "Set priority (default 1, higher is more prioritized)"
msgstr "Atur prioritas (bawaan 1, lebih tinggi berarti lebih diprioritaskan)"

#: app/flatpak-builtins-remote-add.c:75 app/flatpak-builtins-remote-modify.c:81
msgid "PRIORITY"
msgstr "PRIORITAS"

#: app/flatpak-builtins-remote-add.c:76
msgid "The named subset to use for this remote"
msgstr "Subset bernama yang digunakan untuk remote ini"

#: app/flatpak-builtins-remote-add.c:76 app/flatpak-builtins-remote-modify.c:71
msgid "SUBSET"
msgstr "SUBSET"

#: app/flatpak-builtins-remote-add.c:77 app/flatpak-builtins-remote-modify.c:82
msgid "A nice name to use for this remote"
msgstr "Sebuah nama yang bagus untuk digunakan bagi remote ini"

#: app/flatpak-builtins-remote-add.c:78 app/flatpak-builtins-remote-modify.c:83
msgid "A one-line comment for this remote"
msgstr "Komentar satu baris untuk remote ini"

#: app/flatpak-builtins-remote-add.c:79 app/flatpak-builtins-remote-modify.c:84
msgid "A full-paragraph description for this remote"
msgstr "Deskripsi paragraf lengkap untuk remote ini"

#: app/flatpak-builtins-remote-add.c:80 app/flatpak-builtins-remote-modify.c:85
msgid "URL for a website for this remote"
msgstr "URL untuk situs web untuk remote ini"

#: app/flatpak-builtins-remote-add.c:81 app/flatpak-builtins-remote-modify.c:86
msgid "URL for an icon for this remote"
msgstr "URL untuk ikon untuk remote ini"

#: app/flatpak-builtins-remote-add.c:82 app/flatpak-builtins-remote-modify.c:87
msgid "Default branch to use for this remote"
msgstr "Cabang bawaan yang digunakan untuk remote ini"

#: app/flatpak-builtins-remote-add.c:84 app/flatpak-builtins-remote-modify.c:89
msgid "Import GPG key from FILE (- for stdin)"
msgstr "Impor kunci GPG dari BERKAS (- untuk stdin)"

#: app/flatpak-builtins-remote-add.c:85 app/flatpak-builtins-remote-modify.c:90
msgid "Load signatures from URL"
msgstr ""

#: app/flatpak-builtins-remote-add.c:86 app/flatpak-builtins-remote-modify.c:92
msgid "Set path to local filter FILE"
msgstr "Atur path ke penyaring BERKAS lokal"

#: app/flatpak-builtins-remote-add.c:87 app/flatpak-builtins-remote-modify.c:93
msgid "Disable the remote"
msgstr "Nonaktifkan remote"

#: app/flatpak-builtins-remote-add.c:88 app/flatpak-builtins-remote-modify.c:94
msgid "Name of authenticator"
msgstr "Nama autentikator"

#: app/flatpak-builtins-remote-add.c:90 app/flatpak-builtins-remote-modify.c:96
msgid "Autoinstall authenticator"
msgstr "Pasang otomatis autentikator"

#: app/flatpak-builtins-remote-add.c:91 app/flatpak-builtins-remote-modify.c:97
msgid "Don't autoinstall authenticator"
msgstr "Jangan pasang otomatis autentikator"

#: app/flatpak-builtins-remote-add.c:92 app/flatpak-builtins-remote-modify.c:99
msgid "Don't follow the redirect set in the summary file"
msgstr "Jangan ikuti kumpulan pengalihan dalam berkas ringkasan"

#: app/flatpak-builtins-remote-add.c:261 app/flatpak-builtins-remote-add.c:268
#, c-format
msgid "Can't load uri %s: %s\n"
msgstr "Tidak dapat memuat uri %s: %s\n"

#: app/flatpak-builtins-remote-add.c:276 common/flatpak-dir.c:4643
#, c-format
msgid "Can't load file %s: %s\n"
msgstr "Tidak dapat memuat berkas %s: %s\n"

#: app/flatpak-builtins-remote-add.c:304
msgid "NAME LOCATION - Add a remote repository"
msgstr "NAMA LOKASI - Tambah repositori remote"

#: app/flatpak-builtins-remote-add.c:331
msgid "GPG verification is required if collections are enabled"
msgstr "Verifikasi GPG diperlukan jika koleksi diaktifkan"

#: app/flatpak-builtins-remote-add.c:393
#, c-format
msgid "Remote %s already exists"
msgstr "Remote %s sudah ada"

#: app/flatpak-builtins-remote-add.c:405
#: app/flatpak-builtins-remote-modify.c:340
#, c-format
msgid "Invalid authenticator name %s"
msgstr "Nama autentikator tidak valid %s"

#: app/flatpak-builtins-remote-add.c:422
#, c-format
msgid "Warning: Could not update extra metadata for '%s': %s\n"
msgstr "Peringatan: Tidak dapat memutakhirkan metadata ekstra untuk '%s': %s\n"

#: app/flatpak-builtins-remote-delete.c:39
msgid "Remove remote even if in use"
msgstr "Hapus remote meskipun digunakan"

#: app/flatpak-builtins-remote-delete.c:53
msgid "NAME - Delete a remote repository"
msgstr "NAMA - Menghapus repositori remote"

#: app/flatpak-builtins-remote-delete.c:100
#, c-format
msgid "The following refs are installed from remote '%s':"
msgstr "Ref berikut dipasang dari remote '%s':"

#: app/flatpak-builtins-remote-delete.c:101
msgid "Remove them?"
msgstr "Hapus mereka?"

#: app/flatpak-builtins-remote-delete.c:103
#, c-format
msgid "Can't remove remote '%s' with installed refs"
msgstr "Tidak dapat menghapus remote '%s' dengan ref yang terpasang"

#: app/flatpak-builtins-remote-info.c:55
msgid "Commit to show info for"
msgstr "Komit untuk menunjukkan info untuk"

#: app/flatpak-builtins-remote-info.c:58
msgid "Display log"
msgstr "Tampilkan log"

#: app/flatpak-builtins-remote-info.c:61
msgid "Show parent"
msgstr "Tampilkan induk"

#: app/flatpak-builtins-remote-info.c:65 app/flatpak-builtins-remote-ls.c:60
msgid "Use local caches even if they are stale"
msgstr "Gunakan singgahan lokal bahkan jika itu basi"

#. Translators: A sideload is when you install from a local USB drive rather than the Internet.
#: app/flatpak-builtins-remote-info.c:67 app/flatpak-builtins-remote-ls.c:62
msgid "Only list refs available as sideloads"
msgstr "Hanya daftar ref yang tersedia sebagai sideload"

#: app/flatpak-builtins-remote-info.c:114
msgid ""
" REMOTE REF - Show information about an application or runtime in a remote"
msgstr ""
" REMOTE REF - Tampilkan informasi tentang aplikasi atau runtime pada remote"

#: app/flatpak-builtins-remote-info.c:125
msgid "REMOTE and REF must be specified"
msgstr "REMOTE dan REF harus ditentukan"

#: app/flatpak-builtins-remote-info.c:247
#: app/flatpak-builtins-remote-info.c:282
#, fuzzy
msgid "Download Size:"
msgstr "Ukuran unduh:"

#: app/flatpak-builtins-remote-info.c:267
#: app/flatpak-builtins-remote-info.c:325
msgid "History:"
msgstr "Riwayat:"

#: app/flatpak-builtins-remote-info.c:348
msgid " Commit:"
msgstr " Komit:"

#: app/flatpak-builtins-remote-info.c:349
msgid " Subject:"
msgstr " Subjek:"

#: app/flatpak-builtins-remote-info.c:350
msgid " Date:"
msgstr " Tanggal:"

#: app/flatpak-builtins-remote-info.c:383
#, c-format
msgid "Warning: Commit %s has no flatpak metadata\n"
msgstr "Peringatan: Komit %s tidak memiliki metadata flatpak\n"

#: app/flatpak-builtins-remote-list.c:43
msgid "Show remote details"
msgstr "Tampilkan detail remote"

#: app/flatpak-builtins-remote-list.c:44
msgid "Show disabled remotes"
msgstr "Tampilkan remote yang dinonaktifkan"

#: app/flatpak-builtins-remote-list.c:52
msgid "Title"
msgstr "Judul"

#: app/flatpak-builtins-remote-list.c:52
msgid "Show the title"
msgstr "Tampilkan judul"

#: app/flatpak-builtins-remote-list.c:53
msgid "Show the URL"
msgstr "Tampilkan URL"

#: app/flatpak-builtins-remote-list.c:54
msgid "Show the collection ID"
msgstr "Tampilkan ID koleksi"

#: app/flatpak-builtins-remote-list.c:55 app/flatpak-builtins-repo.c:392
msgid "Subset"
msgstr "Subset"

#: app/flatpak-builtins-remote-list.c:55
msgid "Show the subset"
msgstr "Tampilkan subset"

#: app/flatpak-builtins-remote-list.c:56
msgid "Filter"
msgstr "Penyaring"

#: app/flatpak-builtins-remote-list.c:56
msgid "Show filter file"
msgstr "Tampilkan berkas penyaring"

#: app/flatpak-builtins-remote-list.c:57
msgid "Priority"
msgstr "Prioritas"

#: app/flatpak-builtins-remote-list.c:57
msgid "Show the priority"
msgstr "Tampilkan prioritas"

#: app/flatpak-builtins-remote-list.c:59
msgid "Comment"
msgstr "Komentar"

#: app/flatpak-builtins-remote-list.c:59
msgid "Show comment"
msgstr "Tampilkan komentar"

#: app/flatpak-builtins-remote-list.c:60
msgid "Show description"
msgstr "Tampilkan deskripsi"

#: app/flatpak-builtins-remote-list.c:61
msgid "Homepage"
msgstr "Halaman Web"

#: app/flatpak-builtins-remote-list.c:61
msgid "Show homepage"
msgstr "Tampilkan halaman web"

#: app/flatpak-builtins-remote-list.c:62
msgid "Icon"
msgstr "Ikon"

#: app/flatpak-builtins-remote-list.c:62
msgid "Show icon"
msgstr "Tampilkan ikon"

#: app/flatpak-builtins-remote-list.c:231
msgid " - List remote repositories"
msgstr " - Daftar repositori remote"

#: app/flatpak-builtins-remote-ls.c:52
msgid "Show arches and branches"
msgstr "Tampilkan arsitektur dan cabang"

#: app/flatpak-builtins-remote-ls.c:53
msgid "Show only runtimes"
msgstr "Hanya tampilkan runtime"

#: app/flatpak-builtins-remote-ls.c:54
msgid "Show only apps"
msgstr "Hanya tampilkan aplikasi"

#: app/flatpak-builtins-remote-ls.c:55
msgid "Show only those where updates are available"
msgstr "Hanya tampilkan itu ketika pemutakhiran tersedia"

#: app/flatpak-builtins-remote-ls.c:56
msgid "Limit to this arch (* for all)"
msgstr "Batasi arsitektur ini (* untuk semua)"

#: app/flatpak-builtins-remote-ls.c:77
msgid "Show the runtime"
msgstr "Tampilkan runtime"

#: app/flatpak-builtins-remote-ls.c:79
msgid "Download size"
msgstr "Ukuran unduh"

#: app/flatpak-builtins-remote-ls.c:79
msgid "Show the download size"
msgstr "Tampilkan ukuran unduh"

#: app/flatpak-builtins-remote-ls.c:391
msgid " [REMOTE or URI] - Show available runtimes and applications"
msgstr " [REMOTE atau URI] - Tampilkan runtime dan aplikasi yang tersedia"

#: app/flatpak-builtins-remote-modify.c:67
msgid "Enable GPG verification"
msgstr "Aktifkan verifikasi GPG"

#: app/flatpak-builtins-remote-modify.c:68
msgid "Mark the remote as enumerate"
msgstr "Tandai remote sebagai enumerasi"

#: app/flatpak-builtins-remote-modify.c:69
msgid "Mark the remote as used for dependencies"
msgstr "Tandai remote seperti yang digunakan untuk dependensi"

#: app/flatpak-builtins-remote-modify.c:70
#, fuzzy
msgid "Set a new URL"
msgstr "Atur url baru"

#: app/flatpak-builtins-remote-modify.c:71
msgid "Set a new subset to use"
msgstr "Atur subset baru untuk digunakan"

#: app/flatpak-builtins-remote-modify.c:72
msgid "Enable the remote"
msgstr "Aktifkan remote"

#: app/flatpak-builtins-remote-modify.c:73
msgid "Update extra metadata from the summary file"
msgstr "Mutakhirkan metadata ekstra dari berkas ringkasan"

#: app/flatpak-builtins-remote-modify.c:91
msgid "Disable local filter"
msgstr "Nonaktifkan penyaring lokal"

#: app/flatpak-builtins-remote-modify.c:95
msgid "Authenticator options"
msgstr "Opsi autentikator"

#: app/flatpak-builtins-remote-modify.c:98
msgid "Follow the redirect set in the summary file"
msgstr "Mengikuti kumpulan pengalihan dalam berkas ringkasan"

#: app/flatpak-builtins-remote-modify.c:306
msgid "NAME - Modify a remote repository"
msgstr "NAMA - Mengubah repositori remote"

#: app/flatpak-builtins-remote-modify.c:316
msgid "Remote NAME must be specified"
msgstr "NAMA remote harus ditentukan"

#: app/flatpak-builtins-remote-modify.c:327
#, c-format
msgid "Updating extra metadata from remote summary for %s\n"
msgstr "Memutakhirkan metadata ekstra dari ringkasan remote untuk %s\n"

#: app/flatpak-builtins-remote-modify.c:330
#, c-format
msgid "Error updating extra metadata for '%s': %s\n"
msgstr "Galat memutakhirkan metadata ekstra untuk '%s': %s\n"

#: app/flatpak-builtins-remote-modify.c:331
#, c-format
msgid "Could not update extra metadata for %s"
msgstr "Tidak dapat memutakhirkan metadata ekstra untuk %s"

#: app/flatpak-builtins-repair.c:43
msgid "Don't make any changes"
msgstr "Jangan lakukan perubahan apa pun"

#: app/flatpak-builtins-repair.c:44
msgid "Reinstall all refs"
msgstr "Pasang ulang semua ref"

#: app/flatpak-builtins-repair.c:68
#, c-format
msgid "Object missing: %s.%s\n"
msgstr "Objek hilang: %s.%s\n"

#: app/flatpak-builtins-repair.c:76
#, c-format
msgid "Object invalid: %s.%s\n"
msgstr "Objek tidak valid: %s.%s\n"

#: app/flatpak-builtins-repair.c:81
#, c-format
msgid "%s, deleting object\n"
msgstr "%s, menghapus objek\n"

#: app/flatpak-builtins-repair.c:146
#, c-format
msgid "Can't load object %s: %s\n"
msgstr "Tidak dapat memuat objek %s: %s\n"

#: app/flatpak-builtins-repair.c:228
#, c-format
msgid "Commit invalid %s: %s\n"
msgstr "Komit tidak valid: %s.%s\n"

#: app/flatpak-builtins-repair.c:231
#, c-format
msgid "Deleting invalid commit %s: %s\n"
msgstr "Menghapus %s komit yang tidak valid: %s\n"

#: app/flatpak-builtins-repair.c:261
#, c-format
msgid "Commit should be marked partial: %s\n"
msgstr "Komit harus ditandai parsial: %s\n"

#: app/flatpak-builtins-repair.c:264
#, c-format
msgid "Marking commit as partial: %s\n"
msgstr "Menandai komit sebagai parsial: %s\n"

#: app/flatpak-builtins-repair.c:293
#, c-format
msgid "Problems loading data for %s: %s\n"
msgstr "Masalah memuat data untuk %s: %s\n"

#: app/flatpak-builtins-repair.c:306
#, c-format
msgid "Error reinstalling %s: %s\n"
msgstr ""
"Galat memasang ulang %s: %s\n"
"\n"

#: app/flatpak-builtins-repair.c:327
msgid "- Repair a flatpak installation"
msgstr "- Perbaiki pemasangan flatpak"

#: app/flatpak-builtins-repair.c:406
#, c-format
msgid "Removing non-deployed ref %s…\n"
msgstr "Menghapus ref tidak ter-deploy %s...\n"

#: app/flatpak-builtins-repair.c:411
#, c-format
msgid "Skipping non-deployed ref %s…\n"
msgstr "Melewati ref tidak ter-deploy %s...\n"

#: app/flatpak-builtins-repair.c:429
#, c-format
msgid "[%d/%d] Verifying %s…\n"
msgstr "[%d/%d] Memverifikasi %s...\n"

#: app/flatpak-builtins-repair.c:435
#, c-format
msgid "Dry run: "
msgstr "Uji coba: "

#: app/flatpak-builtins-repair.c:440
#, c-format
msgid "Deleting ref %s due to missing objects\n"
msgstr "Menghapus ref %s karena objek yang hilang\n"

#: app/flatpak-builtins-repair.c:444
#, c-format
msgid "Deleting ref %s due to invalid objects\n"
msgstr "Menghapus ref %s karena objek tidak valid\n"

#: app/flatpak-builtins-repair.c:448
#, c-format
msgid "Deleting ref %s due to %d\n"
msgstr "Menghapus ref %s karena %d\n"

#: app/flatpak-builtins-repair.c:464
#, c-format
msgid "Checking remotes...\n"
msgstr "Memeriksa remote...\n"

#: app/flatpak-builtins-repair.c:482
#, c-format
msgid "Remote %s for ref %s is missing\n"
msgstr "Remote %s untuk ref %s tidak ada\n"

#: app/flatpak-builtins-repair.c:484
#, c-format
msgid "Remote %s for ref %s is disabled\n"
msgstr "Remote %s untuk ref %s dinonaktifkan\n"

#: app/flatpak-builtins-repair.c:490
#, c-format
msgid "Pruning objects\n"
msgstr "Pangkas objek\n"

#: app/flatpak-builtins-repair.c:498
#, c-format
msgid "Erasing .removed\n"
msgstr "Menghapus .removed\n"

#: app/flatpak-builtins-repair.c:524
#, c-format
msgid "Reinstalling refs\n"
msgstr "Memasang ulang ref\n"

#: app/flatpak-builtins-repair.c:526
#, c-format
msgid "Reinstalling removed refs\n"
msgstr "Memasang ulang ref yang dihapus\n"

#: app/flatpak-builtins-repair.c:551
#, c-format
msgid "While removing appstream for %s: "
msgstr "Saat menghapus appstream untuk %s: "

#: app/flatpak-builtins-repair.c:558
#, c-format
msgid "While deploying appstream for %s: "
msgstr "Saat mendeploy appstream untuk %s: "

#: app/flatpak-builtins-repo.c:106
#, c-format
msgid "Repo mode: %s\n"
msgstr "Mode repo: %s\n"

#: app/flatpak-builtins-repo.c:113
#, c-format
msgid "Indexed summaries: %s\n"
msgstr "Ringkasan terindeks: %s\n"

#: app/flatpak-builtins-repo.c:113 app/flatpak-builtins-repo.c:139
#: app/flatpak-builtins-repo.c:172
msgid "true"
msgstr "true"

#: app/flatpak-builtins-repo.c:113 app/flatpak-builtins-repo.c:139
#: app/flatpak-builtins-repo.c:172
msgid "false"
msgstr "false"

#: app/flatpak-builtins-repo.c:121
#, c-format
msgid "Subsummaries: "
msgstr "Sub ringkasan: "

#: app/flatpak-builtins-repo.c:136
#, c-format
msgid "Cache version: %d\n"
msgstr "Versi singgahan: %d\n"

#: app/flatpak-builtins-repo.c:139
#, c-format
msgid "Indexed deltas: %s\n"
msgstr "Delta terindeks: %s\n"

#: app/flatpak-builtins-repo.c:142
#, c-format
msgid "Title: %s\n"
msgstr "Judul: %s\n"

#: app/flatpak-builtins-repo.c:145
#, c-format
msgid "Comment: %s\n"
msgstr "Komentar: %s\n"

#: app/flatpak-builtins-repo.c:148
#, c-format
msgid "Description: %s\n"
msgstr "Deskripsi: %s\n"

#: app/flatpak-builtins-repo.c:151
#, c-format
msgid "Homepage: %s\n"
msgstr "Halaman Web: %s\n"

#: app/flatpak-builtins-repo.c:154
#, c-format
msgid "Icon: %s\n"
msgstr "Ikon: %s\n"

#: app/flatpak-builtins-repo.c:157
#, c-format
msgid "Collection ID: %s\n"
msgstr "ID koleksi: %s\n"

#: app/flatpak-builtins-repo.c:160
#, c-format
msgid "Default branch: %s\n"
msgstr "Cabang bawaan: %s\n"

#: app/flatpak-builtins-repo.c:163
#, c-format
msgid "Redirect URL: %s\n"
msgstr "URL pengalihan: %s\n"

#: app/flatpak-builtins-repo.c:166
#, c-format
msgid "Deploy collection ID: %s\n"
msgstr "Deploy ID koleksi: %s\n"

#: app/flatpak-builtins-repo.c:169
#, c-format
msgid "Authenticator name: %s\n"
msgstr "Nama autentikator: %s\n"

#: app/flatpak-builtins-repo.c:172
#, c-format
msgid "Authenticator install: %s\n"
msgstr "Pasang autentikator: %s\n"

#: app/flatpak-builtins-repo.c:180
#, c-format
msgid "GPG key hash: %s\n"
msgstr "Hash kunci GPG: %s\n"

#: app/flatpak-builtins-repo.c:184
#, c-format
msgid "%zd summary branches\n"
msgstr "%zd cabang ringkasan\n"

#: app/flatpak-builtins-repo.c:336
msgid "Installed"
msgstr "Terpasang"

#. Translators: Download is used here as a noun
#: app/flatpak-builtins-repo.c:338 app/flatpak-cli-transaction.c:1462
msgid "Download"
msgstr "Unduh"

#: app/flatpak-builtins-repo.c:339
msgid "Subsets"
msgstr "Subset"

#: app/flatpak-builtins-repo.c:393
msgid "Digest"
msgstr "Intisari"

#: app/flatpak-builtins-repo.c:394
msgid "History length"
msgstr "Panjang riwayat"

#: app/flatpak-builtins-repo.c:711
msgid "Print general information about the repository"
msgstr "Cetak informasi umum tentang repositori"

#: app/flatpak-builtins-repo.c:712
msgid "List the branches in the repository"
msgstr "Daftar cabang di repositori"

#: app/flatpak-builtins-repo.c:713
msgid "Print metadata for a branch"
msgstr "Cetak metadata untuk cabang"

#: app/flatpak-builtins-repo.c:714
msgid "Show commits for a branch"
msgstr "Tampilkan komit untuk cabang"

#: app/flatpak-builtins-repo.c:715
msgid "Print information about the repo subsets"
msgstr "Cetak informasi tentang subset repositori"

#: app/flatpak-builtins-repo.c:716
msgid "Limit information to subsets with this prefix"
msgstr "Batasi informasi ke subset dengan awalan ini"

#: app/flatpak-builtins-repo.c:732
msgid "LOCATION - Repository maintenance"
msgstr "LOKASI - Pemeliharaan repositori"

#: app/flatpak-builtins-run.c:159
msgid "Command to run"
msgstr "Perintah untuk menjalankan"

#: app/flatpak-builtins-run.c:160
msgid "Directory to run the command in"
msgstr "Direktori untuk menjalankan perintah"

#: app/flatpak-builtins-run.c:161
msgid "Branch to use"
msgstr "Cabang untuk digunakan"

#: app/flatpak-builtins-run.c:162
msgid "Use development runtime"
msgstr "Gunakan runtime pengembangan"

#: app/flatpak-builtins-run.c:163
msgid "Runtime to use"
msgstr "Runtime untuk digunakan"

#: app/flatpak-builtins-run.c:164
msgid "Runtime version to use"
msgstr "Versi runtime untuk digunakan"

#: app/flatpak-builtins-run.c:167
msgid "Log accessibility bus calls"
msgstr "Catat log aksesibilitas bus sesi"

#: app/flatpak-builtins-run.c:168
msgid "Don't proxy accessibility bus calls"
msgstr "Jangan proksi aksesibilitas panggilan bus"

#: app/flatpak-builtins-run.c:169
msgid "Proxy accessibility bus calls (default except when sandboxed)"
msgstr "Panggilan bus aksesibilitas proksi (bawaan kecuali saat sandbox)"

#: app/flatpak-builtins-run.c:170
msgid "Don't proxy session bus calls"
msgstr "Jangan proksi panggilan bus sesi"

#: app/flatpak-builtins-run.c:171
msgid "Proxy session bus calls (default except when sandboxed)"
msgstr "Panggilan bus sesi proksi (bawaan kecuali saat sandbox)"

#: app/flatpak-builtins-run.c:172
msgid "Don't start portals"
msgstr "Jangan memulai portal"

#: app/flatpak-builtins-run.c:173
msgid "Enable file forwarding"
msgstr "Aktifkan penerusan berkas"

#: app/flatpak-builtins-run.c:174
msgid "Run specified commit"
msgstr "Jalankan komit yang ditentukan"

#: app/flatpak-builtins-run.c:175
msgid "Use specified runtime commit"
msgstr "Gunakan komit runtime yang ditentukan"

#: app/flatpak-builtins-run.c:176
msgid "Run completely sandboxed"
msgstr "Jalankan sepenuhnya di dalam sandbox"

#: app/flatpak-builtins-run.c:178
msgid "Use PID as parent pid for sharing namespaces"
msgstr "Gunakan PID sebagai pid induk untuk berbagi ruang nama"

#: app/flatpak-builtins-run.c:179
msgid "Make processes visible in parent namespace"
msgstr "Jadikan proses terlihat di ruang nama induk"

#: app/flatpak-builtins-run.c:180
msgid "Share process ID namespace with parent"
msgstr "Bagikan ruang nama ID proses dengan induk"

#: app/flatpak-builtins-run.c:181
msgid "Write the instance ID to the given file descriptor"
msgstr "Tulis ID instance ke deskriptor berkas yang diberikan"

#: app/flatpak-builtins-run.c:182
msgid "Use PATH instead of the app's /app"
msgstr "Gunakan PATH alih-alih /app aplikasi"

#: app/flatpak-builtins-run.c:183
#, fuzzy
msgid "Use FD instead of the app's /app"
msgstr "Gunakan PATH alih-alih /app aplikasi"

#: app/flatpak-builtins-run.c:183 app/flatpak-builtins-run.c:185
#: app/flatpak-builtins-run.c:187 app/flatpak-builtins-run.c:188
#: common/flatpak-context.c:2672
msgid "FD"
msgstr "FD"

#: app/flatpak-builtins-run.c:184
msgid "Use PATH instead of the runtime's /usr"
msgstr "Gunakan PATH alih-alih /usr runtime"

#: app/flatpak-builtins-run.c:185
#, fuzzy
msgid "Use FD instead of the runtime's /usr"
msgstr "Gunakan PATH alih-alih /usr runtime"

#: app/flatpak-builtins-run.c:186
#, fuzzy
msgid "Clear all outside environment variables"
msgstr "Atur variabel lingkungan"

#: app/flatpak-builtins-run.c:187
msgid ""
"Bind mount the file or directory referred to by FD to its canonicalized path"
msgstr ""

#: app/flatpak-builtins-run.c:188
msgid ""
"Bind mount the file or directory referred to by FD read-only to its "
"canonicalized path"
msgstr ""

#: app/flatpak-builtins-run.c:219
msgid "APP [ARGUMENT…] - Run an app"
msgstr "APP ARGUMEN...] - Jalankan aplikasi"

#: app/flatpak-builtins-run.c:370
#, c-format
msgid "runtime/%s/%s/%s not installed"
msgstr "runtime/%s/%s/%s tidak terpasang"

#: app/flatpak-builtins-run.c:419
msgid "app-fd and app-path cannot both be used"
msgstr ""

#: app/flatpak-builtins-run.c:449
msgid "usr-fd and usr-path cannot both be used"
msgstr ""

#: app/flatpak-builtins-search.c:37
msgid "Arch to search for"
msgstr "Arsitektur tujuan pencarian"

#: app/flatpak-builtins-search.c:49
msgid "Remotes"
msgstr "Remote"

#: app/flatpak-builtins-search.c:49
msgid "Show the remotes"
msgstr "Tampilkan remote"

#: app/flatpak-builtins-search.c:244
msgid "TEXT - Search remote apps/runtimes for text"
msgstr "TEKS - Cari aplikasi remote/runtime untuk teks"

#: app/flatpak-builtins-search.c:255
msgid "TEXT must be specified"
msgstr "TEKS harus ditentukan"

#: app/flatpak-builtins-search.c:338
msgid "No matches found"
msgstr "Tidak ditemukan kecocokan"

#: app/flatpak-builtins-uninstall.c:54
msgid "Arch to uninstall"
msgstr "Arsitektur untuk dihapus"

#: app/flatpak-builtins-uninstall.c:55
msgid "Keep ref in local repository"
msgstr "Simpan ref di repositori lokal"

#: app/flatpak-builtins-uninstall.c:56
msgid "Don't uninstall related refs"
msgstr "Jangan hapus ref terkait"

#: app/flatpak-builtins-uninstall.c:57
msgid "Remove files even if running"
msgstr "Hapus berkas meski sedang berjalan"

#: app/flatpak-builtins-uninstall.c:60
msgid "Uninstall all"
msgstr "Hapus semua"

#: app/flatpak-builtins-uninstall.c:61
msgid "Uninstall unused"
msgstr "Hapus yang tidak digunakan"

#: app/flatpak-builtins-uninstall.c:62
msgid "Delete app data"
msgstr "Hapus data aplikasi"

#: app/flatpak-builtins-uninstall.c:141
#, c-format
msgid "Delete data for %s?"
msgstr "Hapus data untuk %s?"

#: app/flatpak-builtins-uninstall.c:220
#, c-format
msgid "Info: applications using the extension %s%s%s branch %s%s%s:\n"
msgstr "Info: aplikasi menggunakan ekstensi %s%s%s cabang %s%s%s:\n"

#: app/flatpak-builtins-uninstall.c:223
#, c-format
msgid "Info: applications using the runtime %s%s%s branch %s%s%s:\n"
msgstr "Info: aplikasi yang menggunakan runtime %s%s%s cabang %s%s%s:\n"

#: app/flatpak-builtins-uninstall.c:238
msgid "Really remove?"
msgstr "Benar-benar menghapus?"

#: app/flatpak-builtins-uninstall.c:255
msgid "[REF…] - Uninstall applications or runtimes"
msgstr "[REF...] - Hapus aplikasi atau runtime"

#: app/flatpak-builtins-uninstall.c:264
msgid "Must specify at least one REF, --unused, --all or --delete-data"
msgstr ""
"Harus menentukan setidaknya satu REF, --unused, --all atau --delete-data"

#: app/flatpak-builtins-uninstall.c:267
msgid "Must not specify REFs when using --all"
msgstr "Tidak harus menentukan REF ketika menggunakan --all"

#: app/flatpak-builtins-uninstall.c:270
msgid "Must not specify REFs when using --unused"
msgstr "Tidak harus menentukan REF ketika menggunakan --unused"

#: app/flatpak-builtins-uninstall.c:336
#, c-format
msgid ""
"\n"
"These runtimes in installation '%s' are pinned and won't be removed; see "
"flatpak-pin(1):\n"
msgstr ""
"\n"
"Runtime ini dalam pemasangan '%s' disematkan dan tidak akan dihapus; lihat "
"flatpak-pin(1):\n"

#: app/flatpak-builtins-uninstall.c:370
#, c-format
msgid "Nothing unused to uninstall\n"
msgstr "Tidak ada yang tidak digunakan untuk menghapus\n"

#: app/flatpak-builtins-uninstall.c:444
#, c-format
msgid "No installed refs found for ‘%s’"
msgstr "Tidak ditemukan ref terpasang untuk '%s'"

#: app/flatpak-builtins-uninstall.c:447
#, c-format
msgid " with arch ‘%s’"
msgstr " dengan arsitektur '%s'"

#: app/flatpak-builtins-uninstall.c:449
#, c-format
msgid " with branch ‘%s’"
msgstr " dengan cabang '%s'"

#: app/flatpak-builtins-uninstall.c:456
#, c-format
msgid "Warning: %s is not installed\n"
msgstr "Peringatan:%s tidak dipasang\n"

#: app/flatpak-builtins-uninstall.c:490
#, c-format
msgid "None of the specified refs are installed"
msgstr "Tidak ada ref yang ditentukan yang dipasang"

#: app/flatpak-builtins-uninstall.c:599
#, c-format
msgid "No app data to delete\n"
msgstr ""

#: app/flatpak-builtins-update.c:56
msgid "Arch to update for"
msgstr "Arsitektur untuk pemutakhiran"

#: app/flatpak-builtins-update.c:57
msgid "Commit to deploy"
msgstr "Komit untuk deploy"

#: app/flatpak-builtins-update.c:58
msgid "Remove old files even if running"
msgstr "Hapus berkas lama meski berjalan"

#: app/flatpak-builtins-update.c:59
msgid "Don't pull, only update from local cache"
msgstr "Jangan tarik, hanya mutakhirkan dari singgahan lokal"

#: app/flatpak-builtins-update.c:61
msgid "Don't update related refs"
msgstr "Jangan pemutakhiran ref terkait"

#: app/flatpak-builtins-update.c:66
msgid "Update appstream for remote"
msgstr "Mutakhirkan appstream untuk remote"

#: app/flatpak-builtins-update.c:67
msgid "Only update this subpath"
msgstr "Hanya mutakhirkan subpath ini"

#: app/flatpak-builtins-update.c:90
msgid "[REF…] - Update applications or runtimes"
msgstr "[REF...] - Mutakhirkan aplikasi atau runtime"

#: app/flatpak-builtins-update.c:121
msgid "With --commit, only one REF may be specified"
msgstr "Dengan --commit, hanya satu REF yang dapat ditentukan"

#: app/flatpak-builtins-update.c:162
#, c-format
msgid "Looking for updates…\n"
msgstr "Mencari pemutakhiran...\n"

#: app/flatpak-builtins-update.c:215
#, c-format
msgid "Unable to update %s: %s\n"
msgstr "Tidak dapat memutakhirkan %s: %s\n"

#: app/flatpak-builtins-update.c:274
#, fuzzy, c-format
msgid "Nothing to update.\n"
msgstr "Tidak ada yang bisa dilakukan.\n"

#: app/flatpak-builtins-utils.c:337
#, fuzzy, c-format
msgid ""
"Remote ‘%s’ found in multiple installations, unable to proceed in non-"
"interactive mode"
msgstr ""
"Ref ‘%s’ ditemukan pada beberapa pemasangan: %s. Anda harus menentukan satu."

#: app/flatpak-builtins-utils.c:346
#, c-format
msgid "Remote ‘%s’ found in multiple installations:"
msgstr "Remote '%s' ditemukan pada beberapa pemasangan:"

#: app/flatpak-builtins-utils.c:347 app/flatpak-builtins-utils.c:442
#: app/flatpak-builtins-utils.c:538 app/flatpak-builtins-utils.c:540
#: app/flatpak-builtins-utils.c:598
msgid "Which do you want to use (0 to abort)?"
msgstr "Mana yang ingin Anda gunakan (0 untuk membatalkan)?"

#: app/flatpak-builtins-utils.c:349
#, c-format
msgid "No remote chosen to resolve ‘%s’ which exists in multiple installations"
msgstr ""
"Tidak ada remote yang dipilih untuk menyelesaikan '%s' yang ada pada "
"beberapa pemasangan"

#: app/flatpak-builtins-utils.c:358
#, c-format
msgid ""
"Remote \"%s\" not found\n"
"Hint: Use flatpak remote-add to add a remote"
msgstr ""
"Remote \"%s\" tidak ditemukan\n"
"Petunjuk: Gunakan flatpak remote-add untuk menambahkan remote"

#: app/flatpak-builtins-utils.c:364
#, c-format
msgid "Remote \"%s\" not found in the %s installation"
msgstr "Remote \"%s\" tidak ditemukan dalam pemasangan %s"

#: app/flatpak-builtins-utils.c:404
#, c-format
msgid "Multiple refs match ‘%s’, unable to proceed in non-interactive mode"
msgstr ""

#. default to yes on Enter
#: app/flatpak-builtins-utils.c:430
#, c-format
msgid ""
"Found ref ‘%s’ in remote ‘%s’ (%s).\n"
"Use this ref?"
msgstr ""
"Ref ‘%s’ ditemukan dalam remote ‘%s’ (%s):\n"
"Gunakan ref ini?"

#: app/flatpak-builtins-utils.c:434 app/flatpak-builtins-utils.c:444
#: app/flatpak-builtins-utils.c:522 app/flatpak-builtins-utils.c:543
#, c-format
msgid "No ref chosen to resolve matches for ‘%s’"
msgstr "Tidak ada ref yang dipilih untuk menyelesaikan kecocokan untuk ‘%s’"

#: app/flatpak-builtins-utils.c:440
#, c-format
msgid "Similar refs found for ‘%s’ in remote ‘%s’ (%s):"
msgstr "Ref serupa ditemukan untuk ‘%s’ dalam remote ‘%s’ (%s):"

#: app/flatpak-builtins-utils.c:488
#, c-format
msgid ""
"Multiple installed refs match ‘%s’, unable to proceed in non-interactive mode"
msgstr ""

#. default to yes on Enter
#: app/flatpak-builtins-utils.c:518
#, c-format
msgid "Found installed ref ‘%s’ (%s). Is this correct?"
msgstr "Ditemukan ref yang terpasang ‘%s’ (%s). Apakah ini benar?"

#: app/flatpak-builtins-utils.c:534
#, c-format
msgid "All of the above"
msgstr "Semua yang di atas"

#: app/flatpak-builtins-utils.c:535
#, c-format
msgid "Similar installed refs found for ‘%s’:"
msgstr "Ref terpasang serupa ditemukan untuk ‘%s’:"

#: app/flatpak-builtins-utils.c:579
#, c-format
msgid ""
"Multiple remotes have refs matching ‘%s’, unable to proceed in non-"
"interactive mode"
msgstr ""

#: app/flatpak-builtins-utils.c:597
#, c-format
msgid "Remotes found with refs similar to ‘%s’:"
msgstr "Remote ditemukan dengan ref yang serupa dengan ‘%s’:"

#: app/flatpak-builtins-utils.c:600
#, c-format
msgid "No remote chosen to resolve matches for ‘%s’"
msgstr "Tidak ada remote yang dipilih untuk menyelesaikan kecocokan untuk ‘%s’"

#: app/flatpak-builtins-utils.c:696 app/flatpak-builtins-utils.c:699
#, c-format
msgid "Updating appstream data for user remote %s"
msgstr "Memutakhirkan data appstream untuk remote pengguna %s"

#: app/flatpak-builtins-utils.c:706 app/flatpak-builtins-utils.c:709
#, c-format
msgid "Updating appstream data for remote %s"
msgstr "Memutakhirkan data appstream untuk remote %s"

#: app/flatpak-builtins-utils.c:717 app/flatpak-builtins-utils.c:719
msgid "Error updating"
msgstr "Galat memutakhirkan"

#: app/flatpak-builtins-utils.c:755
#, c-format
msgid "Remote \"%s\" not found"
msgstr "Remote \"%s\" tidak ditemukan"

#: app/flatpak-builtins-utils.c:796
#, c-format
msgid "Ambiguous suffix: '%s'."
msgstr "Sufiks ambigu: '%s'."

#. Translators: don't translate the values
#: app/flatpak-builtins-utils.c:798 app/flatpak-builtins-utils.c:813
msgid "Possible values are :s[tart], :m[iddle], :e[nd] or :f[ull]"
msgstr "Nilai yang mungkin adalah :s[tart], :m[iddle], :e[nd] or :f[ull]"

#: app/flatpak-builtins-utils.c:811
#, c-format
msgid "Invalid suffix: '%s'."
msgstr "Sufiks tidak valid: '%s'."

#: app/flatpak-builtins-utils.c:846
#, c-format
msgid "Ambiguous column: %s"
msgstr "Kolom ambigu: %s"

#: app/flatpak-builtins-utils.c:859
#, c-format
msgid "Unknown column: %s"
msgstr "Kolom tidak dikenal: %s"

#: app/flatpak-builtins-utils.c:917
msgid "Available columns:\n"
msgstr "Kolom yang tersedia:\n"

#: app/flatpak-builtins-utils.c:927
msgid "Show all columns"
msgstr "Tampilkan semua kolom"

#: app/flatpak-builtins-utils.c:928
msgid "Show available columns"
msgstr "Tampilkan kolom yang tersedia"

#: app/flatpak-builtins-utils.c:931
msgid "Append :s[tart], :m[iddle], :e[nd] or :f[ull] to change ellipsization"
msgstr ""
"Menambahkan :s[tart], :m[iddle], :e[nd] atau :f[ull] untuk mengubah "
"elipsisasi"

#: app/flatpak-builtins-utils.c:1483
#, c-format
msgid "Unknown scheme in sideload location %s"
msgstr ""

#: app/flatpak-cli-transaction.c:96 app/flatpak-cli-transaction.c:102
#, c-format
msgid "Required runtime for %s (%s) found in remote %s\n"
msgstr "Runtime yang diperlukan %s (%s) ditemukan di remote %s\n"

#: app/flatpak-cli-transaction.c:104
msgid "Do you want to install it?"
msgstr "Apakah Anda ingin memasangnya?"

#: app/flatpak-cli-transaction.c:110
#, c-format
msgid "Required runtime for %s (%s) found in remotes:"
msgstr "Diperlukan runtime untuk %s (%s) yang ditemukan pada remote:"

#: app/flatpak-cli-transaction.c:112
msgid "Which do you want to install (0 to abort)?"
msgstr "Mana yang ingin Anda pasang (0 untuk membatalkan)?"

#: app/flatpak-cli-transaction.c:132
#, c-format
msgid "Configuring %s as new remote '%s'\n"
msgstr "Mengonfigurasi %s sebagai '%s' remote baru\n"

#. default to yes on Enter
#: app/flatpak-cli-transaction.c:139
#, c-format
msgid ""
"The remote '%s', referred to by '%s' at location %s contains additional "
"applications.\n"
"Should the remote be kept for future installations?"
msgstr ""
"Remote '%s', yang dirujuk oleh '%s' pada lokasi %s berisi aplikasi "
"tambahan.\n"
"Haruskah remote disimpan untuk pemasangan di masa depan?"

#. default to yes on Enter
#: app/flatpak-cli-transaction.c:147
#, c-format
msgid ""
"The application %s depends on runtimes from:\n"
"  %s\n"
"Configure this as new remote '%s'"
msgstr ""
"Aplikasi %s bergantung pada runtime dari:\n"
"   %s\n"
"Konfigurasikan ini sebagai remote baru '%s'"

#. Formatted size/remaining time in seconds
#: app/flatpak-cli-transaction.c:321
#, c-format
msgid "%s/s%s%s"
msgstr ""

#. Download progress percentage, use the appropriate
#. percent format for your language
#: app/flatpak-cli-transaction.c:359
#, c-format
msgid "%3d%%"
msgstr ""

#: app/flatpak-cli-transaction.c:414
msgid "Installing…"
msgstr "Memasang…"

#: app/flatpak-cli-transaction.c:416
#, c-format
msgid "Installing %d/%d…"
msgstr "Memasang %d/%d…"

#: app/flatpak-cli-transaction.c:421
msgid "Updating…"
msgstr "Memutakhirkan…"

#: app/flatpak-cli-transaction.c:423
#, c-format
msgid "Updating %d/%d…"
msgstr "Memutakhirkan %d/%d…"

#: app/flatpak-cli-transaction.c:428
msgid "Uninstalling…"
msgstr "Menghapus pemasangan…"

#: app/flatpak-cli-transaction.c:430
#, c-format
msgid "Uninstalling %d/%d…"
msgstr "Menghapus pemasangan %d/%d…"

#: app/flatpak-cli-transaction.c:496 app/flatpak-quiet-transaction.c:161
#, c-format
msgid "Info: %s was skipped"
msgstr "Info: %s dilewati"

#: app/flatpak-cli-transaction.c:519
#, c-format
msgid "Warning: %s%s%s already installed"
msgstr "Peringatan: %s%s %s sudah dipasang"

#: app/flatpak-cli-transaction.c:522
#, c-format
msgid "Error: %s%s%s already installed"
msgstr "Galat: %s%s%s sudah dipasang"

#: app/flatpak-cli-transaction.c:528
#, c-format
msgid "Warning: %s%s%s not installed"
msgstr "Peringatan: %s%s %s sudah dipasang"

#: app/flatpak-cli-transaction.c:531
#, c-format
msgid "Error: %s%s%s not installed"
msgstr "Galat: %s%s%s sudah dipasang"

#: app/flatpak-cli-transaction.c:537
#, c-format
msgid "Warning: %s%s%s needs a later flatpak version"
msgstr "Peringatan: %s%s%s membutuhkan versi flatpak yang lebih baru"

#: app/flatpak-cli-transaction.c:540
#, c-format
msgid "Error: %s%s%s needs a later flatpak version"
msgstr "Galat: %s%s%s membutuhkan versi flatpak yang lebih baru"

#: app/flatpak-cli-transaction.c:546
msgid "Warning: Not enough disk space to complete this operation"
msgstr "Peringatan: Tidak cukup ruang diska untuk menyelesaikan operasi ini"

#: app/flatpak-cli-transaction.c:548
msgid "Error: Not enough disk space to complete this operation"
msgstr "Galat: Tidak cukup ruang diska untuk menyelesaikan operasi ini"

#: app/flatpak-cli-transaction.c:553
#, c-format
msgid "Warning: %s"
msgstr "Peringatan: %s"

#: app/flatpak-cli-transaction.c:555
#, c-format
msgid "Error: %s"
msgstr "Galat: %s"

#: app/flatpak-cli-transaction.c:570
#, c-format
msgid "Failed to install %s%s%s: "
msgstr "Gagal memasang %s%s%s: "

#: app/flatpak-cli-transaction.c:577
#, c-format
msgid "Failed to update %s%s%s: "
msgstr "Gagal memutakhirkan %s%s%s: "

#: app/flatpak-cli-transaction.c:584
#, c-format
msgid "Failed to install bundle %s%s%s: "
msgstr "Gagal memasang bundel %s%s%s: "

#: app/flatpak-cli-transaction.c:591
#, c-format
msgid "Failed to uninstall %s%s%s: "
msgstr "Gagal menghapus %s%s%s: "

#: app/flatpak-cli-transaction.c:642
#, c-format
msgid "Authentication required for remote '%s'\n"
msgstr "Diperlukan autentikasi untuk remote '%s'\n"

#: app/flatpak-cli-transaction.c:643
msgid "Open browser?"
msgstr "Buka peramban?"

#: app/flatpak-cli-transaction.c:699
#, c-format
msgid "Login required remote %s (realm %s)\n"
msgstr "Diperlukan login jarak jauh %s (ranah %s)\n"

#: app/flatpak-cli-transaction.c:704
msgid "Password"
msgstr "Kata sandi"

#. Only runtimes can be pinned
#: app/flatpak-cli-transaction.c:759
#, c-format
msgid ""
"\n"
"Info: (pinned) runtime %s%s%s branch %s%s%s is end-of-life, in favor of "
"%s%s%s branch %s%s%s\n"
msgstr ""
"\n"
"Info: (disematkan) runtime %s%s%s cabang %s%s%s sudah habis masa pakainya, "
"mendukung %s%s%s cabang %s%s%s\n"

#: app/flatpak-cli-transaction.c:765
#, c-format
msgid ""
"\n"
"Info: runtime %s%s%s branch %s%s%s is end-of-life, in favor of %s%s%s branch "
"%s%s%s\n"
msgstr ""
"\n"
"Info: runtime %s%s%s cabang %s%s%s sudah habis masa pakainya, mendukung "
"%s%s%s cabang %s%s%s\n"

#: app/flatpak-cli-transaction.c:768
#, c-format
msgid ""
"\n"
"Info: app %s%s%s branch %s%s%s is end-of-life, in favor of %s%s%s branch "
"%s%s%s\n"
msgstr ""
"\n"
"Info: aplikasi %s%s%s cabang %s%s%s sudah habis masa pakainya, mendukung "
"%s%s%s cabang %s%s%s\n"

#. Only runtimes can be pinned
#: app/flatpak-cli-transaction.c:780
#, c-format
msgid ""
"\n"
"Info: (pinned) runtime %s%s%s branch %s%s%s is end-of-life, with reason:\n"
msgstr ""
"\n"
"Info: (disematkan) runtime %s%s%s cabang %s%s%s sudah habis masa pakainya, "
"dengan alasan:\n"

#: app/flatpak-cli-transaction.c:786
#, c-format
msgid ""
"\n"
"Info: runtime %s%s%s branch %s%s%s is end-of-life, with reason:\n"
msgstr ""
"\n"
"Info: runtime %s%s%s cabang %s%s%s sudah habis masa pakainya, dengan "
"alasan:\n"

#: app/flatpak-cli-transaction.c:789
#, c-format
msgid ""
"\n"
"Info: app %s%s%s branch %s%s%s is end-of-life, with reason:\n"
msgstr ""
"\n"
"Info: aplikasi %s%s%s cabang %s%s%s sudah habis masa pakainya, dengan "
"alasan:\n"

#: app/flatpak-cli-transaction.c:963
#, c-format
msgid "Info: applications using this extension:\n"
msgstr "Info: aplikasi yang menggunakan ekstensi ini:\n"

#: app/flatpak-cli-transaction.c:965
#, c-format
msgid "Info: applications using this runtime:\n"
msgstr "Info: aplikasi yang menggunakan runtime ini:\n"

#: app/flatpak-cli-transaction.c:984
msgid "Replace?"
msgstr "Ganti?"

#: app/flatpak-cli-transaction.c:987 app/flatpak-quiet-transaction.c:247
#, c-format
msgid "Updating to rebased version\n"
msgstr "Memutakhirkan ke versi yang di-rebase\n"

#: app/flatpak-cli-transaction.c:1011
#, c-format
msgid "Failed to rebase %s to %s: "
msgstr "Gagal rebase %s ke %s: "

#: app/flatpak-cli-transaction.c:1277
#, c-format
msgid "New %s%s%s permissions:"
msgstr "Izin %s%s%s baru:"

#: app/flatpak-cli-transaction.c:1279
#, c-format
msgid "%s%s%s permissions:"
msgstr "izin %s%s%s:"

#: app/flatpak-cli-transaction.c:1343
msgid "Warning: "
msgstr "Peringatan: "

#. translators: This is short for operation, the title of a one-char column
#: app/flatpak-cli-transaction.c:1442
msgid "Op"
msgstr "Op"

#. Avoid resizing the download column too much,
#. * by making the title as long as typical content
#.
#: app/flatpak-cli-transaction.c:1458 app/flatpak-cli-transaction.c:1503
msgid "partial"
msgstr "parsial"

#: app/flatpak-cli-transaction.c:1535
msgid "Proceed with these changes to the user installation?"
msgstr "Lanjutkan dengan perubahan ini pada pemasangan pengguna?"

#: app/flatpak-cli-transaction.c:1537
msgid "Proceed with these changes to the system installation?"
msgstr "Lanjutkan dengan perubahan ini pada pemasangan sistem?"

#: app/flatpak-cli-transaction.c:1539
#, c-format
msgid "Proceed with these changes to the %s?"
msgstr "Lanjutkan dengan perubahan ini ke %s?"

#: app/flatpak-cli-transaction.c:1711
msgid "Changes complete."
msgstr "Perubahan selesai."

#: app/flatpak-cli-transaction.c:1713
msgid "Uninstall complete."
msgstr "Hapus selesai."

#: app/flatpak-cli-transaction.c:1715
msgid "Installation complete."
msgstr "Pemasangan selesai."

#: app/flatpak-cli-transaction.c:1717
msgid "Updates complete."
msgstr "Pemutakhiran selesai."

#. For updates/!stop_on_first_error we already printed all errors so we make up
#. a different one.
#: app/flatpak-cli-transaction.c:1750
msgid "There were one or more errors"
msgstr "Ada satu galat atau lebih"

#. translators: please keep the leading space
#: app/flatpak-main.c:76
msgid " Manage installed applications and runtimes"
msgstr " Mengelola aplikasi dan runtime yang terpasang"

#: app/flatpak-main.c:77
msgid "Install an application or runtime"
msgstr "Pasang aplikasi atau runtime"

#: app/flatpak-main.c:78
msgid "Update an installed application or runtime"
msgstr "Mutakhirkan aplikasi atau runtime yang terpasang"

#: app/flatpak-main.c:81
msgid "Uninstall an installed application or runtime"
msgstr "Hapus aplikasi atau runtime yang terpasang"

#: app/flatpak-main.c:84
msgid "Mask out updates and automatic installation"
msgstr "Tutup pemutakhiran dan pemasangan otomatis"

#: app/flatpak-main.c:85
msgid "Pin a runtime to prevent automatic removal"
msgstr "Menyematkan runtime untuk mencegah penghapusan otomatis"

#: app/flatpak-main.c:86
msgid "List installed apps and/or runtimes"
msgstr "Daftar aplikasi dan/atau runtime yang terpasang"

#: app/flatpak-main.c:87
msgid "Show info for installed app or runtime"
msgstr "Tampilkan info untuk aplikasi atau runtime yang terpasang"

#: app/flatpak-main.c:88
msgid "Show history"
msgstr "Tampilkan riwayat"

#: app/flatpak-main.c:89
msgid "Configure flatpak"
msgstr "Konfigurasi flatpak"

#: app/flatpak-main.c:90
msgid "Repair flatpak installation"
msgstr "Perbaiki pemasangan flatpak"

#: app/flatpak-main.c:91
msgid "Put applications or runtimes onto removable media"
msgstr "Pasang aplikasi atau runtime ke media lepasan"

#: app/flatpak-main.c:92
msgid "Install flatpaks that are part of the operating system"
msgstr ""

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:95
msgid ""
"\n"
" Find applications and runtimes"
msgstr ""
"\n"
"Temukan aplikasi dan runtime"

#: app/flatpak-main.c:96
msgid "Search for remote apps/runtimes"
msgstr "Cari aplikasi remote/runtime"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:99
msgid ""
"\n"
" Manage running applications"
msgstr ""
"\n"
"Kelola aplikasi yang sedang berjalan"

#: app/flatpak-main.c:100
msgid "Run an application"
msgstr "Jalankan aplikasi"

#: app/flatpak-main.c:101
msgid "Override permissions for an application"
msgstr "Timpa perizinan aplikasi"

#: app/flatpak-main.c:102
msgid "Specify default version to run"
msgstr "Tentukan versi bawaan untuk dijalankan"

#: app/flatpak-main.c:103
msgid "Enter the namespace of a running application"
msgstr "Masuk ke dalam namespace aplikasi yang sedang berjalan"

#: app/flatpak-main.c:104
msgid "Enumerate running applications"
msgstr "Enumerasikan aplikasi yang sedang berjalan"

#: app/flatpak-main.c:105
msgid "Stop a running application"
msgstr "Hentikan aplikasi yang sedang berjalan"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:108
msgid ""
"\n"
" Manage file access"
msgstr ""
"\n"
" Kelola akses berkas"

#: app/flatpak-main.c:109
msgid "List exported files"
msgstr "Daftar berkas yang diekspor"

#: app/flatpak-main.c:110
msgid "Grant an application access to a specific file"
msgstr "Berikan akses aplikasi ke berkas tertentu"

#: app/flatpak-main.c:111
msgid "Revoke access to a specific file"
msgstr "Cabut akses ke berkas tertentu"

#: app/flatpak-main.c:112
msgid "Show information about a specific file"
msgstr "Tampilkan informasi tentang berkas tertentu"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:116
msgid ""
"\n"
" Manage dynamic permissions"
msgstr ""
"\n"
"Kelola izin dinamis"

#: app/flatpak-main.c:117
msgid "List permissions"
msgstr "Daftar izin"

#: app/flatpak-main.c:118
msgid "Remove item from permission store"
msgstr "Hapus butir dari menyimpan perizinan"

#: app/flatpak-main.c:120
msgid "Set permissions"
msgstr "Tetapkan izin"

#: app/flatpak-main.c:121
msgid "Show app permissions"
msgstr "Tampilkan izin aplikasi"

#: app/flatpak-main.c:122
msgid "Reset app permissions"
msgstr "Atur ulang izin aplikasi"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:125
msgid ""
"\n"
" Manage remote repositories"
msgstr ""
"\n"
" Kelola repositori remote"

#: app/flatpak-main.c:126
msgid "List all configured remotes"
msgstr "Daftar semua remote yang dikonfigurasi"

#: app/flatpak-main.c:127
msgid "Add a new remote repository (by URL)"
msgstr "Tambahkan repositori remote baru (menurut URL)"

#: app/flatpak-main.c:128
msgid "Modify properties of a configured remote"
msgstr "Modifikasi properti dari remote yang terkonfigurasi"

#: app/flatpak-main.c:129
msgid "Delete a configured remote"
msgstr "Hapus remote yang terkonfigurasi"

#: app/flatpak-main.c:131
msgid "List contents of a configured remote"
msgstr "Daftar isi dari remote yang terkonfigurasi"

#: app/flatpak-main.c:132
msgid "Show information about a remote app or runtime"
msgstr "Tampilkan informasi tentang aplikasi remote atau runtime"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:135
msgid ""
"\n"
" Build applications"
msgstr ""
"\n"
" Bangun aplikasi"

#: app/flatpak-main.c:136
msgid "Initialize a directory for building"
msgstr "Inisialisasi direktori untuk membangun"

#: app/flatpak-main.c:137
msgid "Run a build command inside the build dir"
msgstr "Jalankan perintah bangun di dalam direktori bangun"

#: app/flatpak-main.c:138
msgid "Finish a build dir for export"
msgstr "Selesaikan direktori bangun untuk ekspor"

#: app/flatpak-main.c:139
msgid "Export a build dir to a repository"
msgstr "Ekspor direktori bangun ke repositori"

#: app/flatpak-main.c:140
msgid "Create a bundle file from a ref in a local repository"
msgstr "Buat berkas bundel dari ref pada repositori lokal"

#: app/flatpak-main.c:141
msgid "Import a bundle file"
msgstr "Impor berkas bundel"

#: app/flatpak-main.c:142
msgid "Sign an application or runtime"
msgstr "Menandatangani sebuah aplikasi atau runtime"

#: app/flatpak-main.c:143
msgid "Update the summary file in a repository"
msgstr "Mutakhirkan berkas ringkasan dalam repositori"

#: app/flatpak-main.c:144
msgid "Create new commit based on existing ref"
msgstr "Buat komit baru berdasarkan ref yang ada"

#: app/flatpak-main.c:145
msgid "Show information about a repo"
msgstr "Tampilkan informasi tentang repo"

#: app/flatpak-main.c:162
msgid "Show debug information, -vv for more detail"
msgstr "Tampilkan informasi awakutu, -vv untuk lebih detail"

#: app/flatpak-main.c:163
msgid "Show OSTree debug information"
msgstr "Tampilkan informasi awakutu OSTree"

#: app/flatpak-main.c:169
msgid "Print version information and exit"
msgstr "Cetak informasi versi dan keluar"

#: app/flatpak-main.c:170
msgid "Print default arch and exit"
msgstr "Cetak arsitektur bawaan dan keluar"

#: app/flatpak-main.c:171
msgid "Print supported arches and exit"
msgstr "Cetak arsitektur yang didukung dan keluar"

#: app/flatpak-main.c:172
msgid "Print active gl drivers and exit"
msgstr "Cetak penggerak gl aktif dan keluar"

#: app/flatpak-main.c:173
msgid "Print paths for system installations and exit"
msgstr "Cetak path untuk pemasangan sistem dan keluar"

#: app/flatpak-main.c:174
msgid "Print the updated environment needed to run flatpaks"
msgstr ""
"Cetak lingkungan yang diperbarui yang diperlukan untuk menjalankan flatpak"

#: app/flatpak-main.c:175
msgid "Only include the system installation with --print-updated-env"
msgstr "Hanya sertakan pemasangan sistem dengan --print-updated-env"

#: app/flatpak-main.c:180
msgid "Work on the user installation"
msgstr "Bekerja pada pemasangan pengguna"

#: app/flatpak-main.c:181
msgid "Work on the system-wide installation (default)"
msgstr "Bekerja pada pemasangan di seluruh sistem (bawaan)"

#: app/flatpak-main.c:182
msgid "Work on a non-default system-wide installation"
msgstr "Bekerja pada pemasangan seluruh sistem non-bawaan"

#: app/flatpak-main.c:212
msgid "Builtin Commands:"
msgstr "Perintah Bawaan:"

#: app/flatpak-main.c:298
#, c-format
msgid ""
"Note that the directories %s are not in the search path set by the "
"XDG_DATA_DIRS environment variable, so applications installed by Flatpak may "
"not appear on your desktop until the session is restarted."
msgstr ""
"Perhatikan bahwa direktori %s tidak termasuk dalam path pencarian yang "
"ditetapkan oleh variabel lingkungan XDG_DATA_DIRS, sehingga aplikasi yang "
"dipasang oleh Flatpak mungkin tidak muncul di destop Anda sampai sesi "
"dimulai ulang."

#: app/flatpak-main.c:312
#, c-format
msgid ""
"Note that the directory %s is not in the search path set by the "
"XDG_DATA_DIRS environment variable, so applications installed by Flatpak may "
"not appear on your desktop until the session is restarted."
msgstr ""
"Perhatikan bahwa direktori %s tidak termasuk dalam path pencarian yang "
"ditetapkan oleh variabel lingkungan XDG_DATA_DIRS, sehingga aplikasi yang "
"dipasang oleh Flatpak mungkin tidak muncul di destop Anda hingga sesi "
"dimulai ulang."

#: app/flatpak-main.c:381
msgid ""
"Refusing to operate under sudo with --user. Omit sudo to operate on the user "
"installation, or use a root shell to operate on the root user's installation."
msgstr ""
"Menolak untuk beroperasi di bawah sudo dengan --user. Menghilangkan sudo "
"untuk beroperasi pada pemasangan pengguna (user), atau menggunakan shell "
"root untuk beroperasi pada pemasangan pengguna root."

#: app/flatpak-main.c:453
msgid ""
"Multiple installations specified for a command that works on one installation"
msgstr ""
"Beberapa pemasangan ditentukan untuk perintah yang bekerja pada satu "
"pemasangan"

#: app/flatpak-main.c:504 app/flatpak-main.c:697
#, c-format
msgid "See '%s --help'"
msgstr "Lihat '%s --help'"

#: app/flatpak-main.c:706
#, c-format
msgid "'%s' is not a flatpak command. Did you mean '%s%s'?"
msgstr "'%s' bukan perintah flatpak. Apakah maksud Anda '%s%s'?"

#: app/flatpak-main.c:709
#, c-format
msgid "'%s' is not a flatpak command"
msgstr "'%s' bukan perintah flatpak"

#: app/flatpak-main.c:824
msgid "No command specified"
msgstr "Tidak ada perintah yang ditentukan"

#: app/flatpak-main.c:980
msgid "error:"
msgstr "galat:"

#: app/flatpak-quiet-transaction.c:77
#, c-format
msgid "Installing %s\n"
msgstr "Memasang %s\n"

#: app/flatpak-quiet-transaction.c:81
#, c-format
msgid "Updating %s\n"
msgstr "Memutakhirkan %s\n"

#: app/flatpak-quiet-transaction.c:85
#, c-format
msgid "Uninstalling %s\n"
msgstr "Menghapus pemasangan %s\n"

#: app/flatpak-quiet-transaction.c:107
#, c-format
msgid "Warning: Failed to install %s: %s\n"
msgstr "Peringatan: Gagal memasang %s: %s\n"

#: app/flatpak-quiet-transaction.c:110
#, c-format
msgid "Error: Failed to install %s: %s\n"
msgstr "Galat: Gagal memasang %s: %s\n"

#: app/flatpak-quiet-transaction.c:116
#, c-format
msgid "Warning: Failed to update %s: %s\n"
msgstr "Peringatan: Gagal memutakhirkan %s: %s\n"

#: app/flatpak-quiet-transaction.c:119
#, c-format
msgid "Error: Failed to update %s: %s\n"
msgstr "Galat: Gagal memutakhirkan %s: %s\n"

#: app/flatpak-quiet-transaction.c:125
#, c-format
msgid "Warning: Failed to install bundle %s: %s\n"
msgstr "Peringatan: Gagal memasang bundel %s: %s\n"

#: app/flatpak-quiet-transaction.c:128
#, c-format
msgid "Error: Failed to install bundle %s: %s\n"
msgstr "Gaalt: Gagal memasang bundel %s: %s\n"

#: app/flatpak-quiet-transaction.c:134
#, c-format
msgid "Warning: Failed to uninstall %s: %s\n"
msgstr "Peringatan: Gagal menghapus %s: %s\n"

#: app/flatpak-quiet-transaction.c:137
#, c-format
msgid "Error: Failed to uninstall %s: %s\n"
msgstr "Galat: Gagal menghapus %s: %s\n"

#: app/flatpak-quiet-transaction.c:166 common/flatpak-dir.c:11475
#, c-format
msgid "%s already installed"
msgstr "%s sudah terpasang"

#: app/flatpak-quiet-transaction.c:168 common/flatpak-dir.c:3622
#: common/flatpak-dir.c:4321 common/flatpak-dir.c:16968
#: common/flatpak-dir.c:17258 common/flatpak-dir-utils.c:166
#: common/flatpak-dir-utils.c:259 common/flatpak-transaction.c:2736
#: common/flatpak-transaction.c:2791
#, c-format
msgid "%s not installed"
msgstr "%s tidak terpasang"

#: app/flatpak-quiet-transaction.c:170
#, c-format
msgid "%s needs a later flatpak version"
msgstr "%s membutuhkan versi flatpak yang lebih baru"

#: app/flatpak-quiet-transaction.c:172
msgid "Not enough disk space to complete this operation"
msgstr "Ruang diska tidak cukup untuk menyelesaikan operasi ini"

#: app/flatpak-quiet-transaction.c:239
#, c-format
msgid "Info: %s is end-of-life, in favor of %s\n"
msgstr "Info: %s adalah akhir masa pakai, lebih disukai %s\n"

#: app/flatpak-quiet-transaction.c:241
#, c-format
msgid "Info: %s is end-of-life, with reason: %s\n"
msgstr "Info: %s adalah akhir masa pakai, dengan alasan: %s\n"

#: app/flatpak-quiet-transaction.c:251
#, c-format
msgid "Failed to rebase %s to %s: %s\n"
msgstr "Gagal rebase %s to %s: %s\n"

#: common/flatpak-auth.c:58
#, c-format
msgid "No authenticator configured for remote `%s`"
msgstr "Tidak ada autentikator yang dikonfigurasikan untuk remote `%s`"

#: common/flatpak-context.c:637 common/flatpak-context.c:649
#, fuzzy, c-format
msgid "Invalid permission syntax: %s"
msgstr "Nama ekstensi tidak valid %s"

#: common/flatpak-context.c:1207
#, c-format
msgid "Unknown share type %s, valid types are: %s"
msgstr "Jenis pembagian %s tidak diketahui, jenis yang valid adalah: %s"

#: common/flatpak-context.c:1228
#, c-format
msgid "Unknown policy type %s, valid types are: %s"
msgstr "Jenis kebijakan %s tidak diketahui, jenis yang valid adalah: %s"

#: common/flatpak-context.c:1266
#, c-format
msgid "Invalid dbus name %s"
msgstr "Nama dbus %s tidak valid"

#: common/flatpak-context.c:1279
#, c-format
msgid "Unknown socket type %s, valid types are: %s"
msgstr "Jenis soket %s tidak diketahui, jenis yang valid adalah: %s"

#: common/flatpak-context.c:1294
#, c-format
msgid "Unknown device type %s, valid types are: %s"
msgstr "Jenis perangkat %s tidak diketahui, jenis yang valid adalah: %s"

#: common/flatpak-context.c:1308
#, c-format
msgid "Unknown feature type %s, valid types are: %s"
msgstr "Jenis fitur %s tidak diketahui, jenis yang valid adalah: %s"

#: common/flatpak-context.c:1840
#, c-format
msgid "Filesystem location \"%s\" contains \"..\""
msgstr "Lokasi sistem berkas \"%s\" berisi \"..\""

#: common/flatpak-context.c:1882
#, c-format
msgid ""
"--filesystem=/ is not available, use --filesystem=host for a similar result"
msgstr ""
"--filesystem=/ tidak tersedia, gunakan --filesystem=host untuk hasil yang "
"sama"

#: common/flatpak-context.c:1916
#, fuzzy, c-format
msgid ""
"Unknown filesystem location %s, valid locations are: host, host-os, host-"
"etc, host-root, home, xdg-*[/…], ~/dir, /dir"
msgstr ""
"Lokasi sistem berkas yang tidak diketahui %s, lokasi yang valid adalah: "
"host, host-os, host-etc, home, xdg-*[/…], ~/dir, /dir"

#: common/flatpak-context.c:2015
#, fuzzy, c-format
msgid "Invalid syntax for %s: %s"
msgstr "Nama tidak valid %s: %s"

#: common/flatpak-context.c:2142
#, c-format
msgid "fallback-x11 can not be conditional"
msgstr ""

#: common/flatpak-context.c:2318
#, c-format
msgid "Invalid env format %s"
msgstr "Format env tidak valid %s"

#: common/flatpak-context.c:2399
#, c-format
msgid "Environment variable name must not contain '=': %s"
msgstr "Nama variabel lingkungan tidak boleh berisi '=': %s"

#: common/flatpak-context.c:2527 common/flatpak-context.c:2535
#, c-format
msgid "--add-policy arguments must be in the form SUBSYSTEM.KEY=VALUE"
msgstr "Argumen --add-policy harus dalam bentuk SUBSISTEM.KUNCI=NILAI"

#: common/flatpak-context.c:2542
#, c-format
msgid "--add-policy values can't start with \"!\""
msgstr "Nilai --add-policy tidak dapat dimulai dengan \"!\""

#: common/flatpak-context.c:2567 common/flatpak-context.c:2575
#, c-format
msgid "--remove-policy arguments must be in the form SUBSYSTEM.KEY=VALUE"
msgstr "Argumen --remove-policy harus dalam bentuk SUBSISTEM.KUNCI=NILAI"

#: common/flatpak-context.c:2582
#, c-format
msgid "--remove-policy values can't start with \"!\""
msgstr "Nilai --remove-policy tidak dapat dimulai dengan \"!\""

#: common/flatpak-context.c:2657
msgid "Share with host"
msgstr "Berbagi dengan host"

#: common/flatpak-context.c:2657 common/flatpak-context.c:2658
msgid "SHARE"
msgstr "BERBAGI"

#: common/flatpak-context.c:2658
msgid "Unshare with host"
msgstr "Tidak berbagi dengan host"

#: common/flatpak-context.c:2659
msgid "Require conditions to be met for a subsystem to get shared"
msgstr ""

#: common/flatpak-context.c:2659
msgid "SHARE:CONDITION"
msgstr ""

#: common/flatpak-context.c:2660
msgid "Expose socket to app"
msgstr "Ekspos soket ke aplikasi"

#: common/flatpak-context.c:2660 common/flatpak-context.c:2661
msgid "SOCKET"
msgstr "SOKET"

#: common/flatpak-context.c:2661
msgid "Don't expose socket to app"
msgstr "Jangan ekspos soket ke aplikasi"

#: common/flatpak-context.c:2662
msgid "Require conditions to be met for a socket to get exposed"
msgstr ""

#: common/flatpak-context.c:2662
msgid "SOCKET:CONDITION"
msgstr ""

#: common/flatpak-context.c:2663
msgid "Expose device to app"
msgstr "Ekspos perangkat ke aplikasi"

#: common/flatpak-context.c:2663 common/flatpak-context.c:2664
msgid "DEVICE"
msgstr "PERANGKAT"

#: common/flatpak-context.c:2664
msgid "Don't expose device to app"
msgstr "Jangan ekspos perangkat ke aplikasi"

#: common/flatpak-context.c:2665
msgid "Require conditions to be met for a device to get exposed"
msgstr ""

#: common/flatpak-context.c:2665
msgid "DEVICE:CONDITION"
msgstr ""

#: common/flatpak-context.c:2666
msgid "Allow feature"
msgstr "Izinkan fitur"

#: common/flatpak-context.c:2666 common/flatpak-context.c:2667
msgid "FEATURE"
msgstr "FITUR"

#: common/flatpak-context.c:2667
msgid "Don't allow feature"
msgstr "Jangan izinkan fitur"

#: common/flatpak-context.c:2668
msgid "Require conditions to be met for a feature to get allowed"
msgstr ""

#: common/flatpak-context.c:2668
msgid "FEATURE:CONDITION"
msgstr ""

#: common/flatpak-context.c:2669
msgid "Expose filesystem to app (:ro for read-only)"
msgstr "Ekspos sistem berkas ke aplikasi (:ro untuk hanya baca)"

#: common/flatpak-context.c:2669
msgid "FILESYSTEM[:ro]"
msgstr "SISTEMBERKAS[:ro]"

#: common/flatpak-context.c:2670
msgid "Don't expose filesystem to app"
msgstr "Jangan ekspos sistem berkas ke aplikasi"

#: common/flatpak-context.c:2670
msgid "FILESYSTEM"
msgstr "SISTEMBERKAS"

#: common/flatpak-context.c:2671
msgid "Set environment variable"
msgstr "Atur variabel lingkungan"

#: common/flatpak-context.c:2671
msgid "VAR=VALUE"
msgstr "VAR=NILAI"

#: common/flatpak-context.c:2672
msgid "Read environment variables in env -0 format from FD"
msgstr "Baca variabel lingkungan dalam format env -0 dari FD"

#: common/flatpak-context.c:2673
msgid "Remove variable from environment"
msgstr "Hapus variabel dari lingkungan"

#: common/flatpak-context.c:2673
msgid "VAR"
msgstr "VAR"

#: common/flatpak-context.c:2674
msgid "Allow app to own name on the session bus"
msgstr "Izinkan aplikasi memiliki nama di bus sesi"

#: common/flatpak-context.c:2674 common/flatpak-context.c:2675
#: common/flatpak-context.c:2676 common/flatpak-context.c:2677
#: common/flatpak-context.c:2678 common/flatpak-context.c:2679
#: common/flatpak-context.c:2680
msgid "DBUS_NAME"
msgstr "NAMA_DBUS"

#: common/flatpak-context.c:2675
msgid "Allow app to talk to name on the session bus"
msgstr "Izinkan aplikasi berbicara dengan nama di bus sesi"

#: common/flatpak-context.c:2676
msgid "Don't allow app to talk to name on the session bus"
msgstr "Jangan izinkan aplikasi berbicara dengan nama di bus sesi"

#: common/flatpak-context.c:2677
msgid "Allow app to own name on the system bus"
msgstr "Izinkan aplikasi memiliki nama di bus sistem"

#: common/flatpak-context.c:2678
msgid "Allow app to talk to name on the system bus"
msgstr "Izinkan aplikasi berbicara dengan nama di bus sistem"

#: common/flatpak-context.c:2679
msgid "Don't allow app to talk to name on the system bus"
msgstr "Jangan izinkan aplikasi berbicara dengan nama di bus sistem"

#: common/flatpak-context.c:2680
#, fuzzy
msgid "Allow app to own name on the a11y bus"
msgstr "Izinkan aplikasi memiliki nama di bus sistem"

#: common/flatpak-context.c:2681
msgid "Add generic policy option"
msgstr "Tambahkan opsi kebijakan umum"

#: common/flatpak-context.c:2681 common/flatpak-context.c:2682
msgid "SUBSYSTEM.KEY=VALUE"
msgstr "SUBSISTEM.KUNCI=NILAI"

#: common/flatpak-context.c:2682
msgid "Remove generic policy option"
msgstr "Hapus opsi kebijakan umum"

#: common/flatpak-context.c:2683
msgid "Add USB device to enumerables"
msgstr ""

#: common/flatpak-context.c:2683 common/flatpak-context.c:2684
msgid "VENDOR_ID:PRODUCT_ID"
msgstr ""

#: common/flatpak-context.c:2684
msgid "Add USB device to hidden list"
msgstr ""

#: common/flatpak-context.c:2685
msgid "A list of USB devices that are enumerable"
msgstr ""

#: common/flatpak-context.c:2685
msgid "LIST"
msgstr ""

#: common/flatpak-context.c:2686
msgid "File containing a list of USB devices to make enumerable"
msgstr ""

#: common/flatpak-context.c:2686 common/flatpak-context.c:2687
msgid "FILENAME"
msgstr "NAMABERKAS"

#: common/flatpak-context.c:2687
msgid "Persist home directory subpath"
msgstr "Mempertahankan subpath direktori home"

#. This is not needed/used anymore, so hidden, but we accept it for backwards compat
#: common/flatpak-context.c:2689
msgid "Don't require a running session (no cgroups creation)"
msgstr "Tidak memerlukan sesi berjalan (tidak ada pembuatan cgroups)"

#: common/flatpak-context.c:3718
#, c-format
msgid "Not replacing \"%s\" with tmpfs: %s"
msgstr "Tidak mengganti \"%s\" dengan tmpfs: %s"

#: common/flatpak-context.c:3726
#, c-format
msgid "Not sharing \"%s\" with sandbox: %s"
msgstr "Tidak berbagi \"%s\" dengan sandbox: %s"

#. Even if the error is one that we would normally silence, like
#. * the path not existing, it seems reasonable to make more of a fuss
#. * about the home directory not existing or otherwise being unusable,
#. * so this is intentionally not using cannot_export()
#: common/flatpak-context.c:3828
#, c-format
msgid "Not allowing home directory access: %s"
msgstr "Tidak mengizinkan akses direktori rumah: %s"

#: common/flatpak-context.c:4062
#, c-format
msgid "Unable to provide a temporary home directory in the sandbox: %s"
msgstr "Tidak dapat menyediakan direktori rumah sementara di sandbox: %s"

#: common/flatpak-dir.c:442
#, c-format
msgid "Configured collection ID ‘%s’ not in summary file"
msgstr "ID koleksi yang dikonfigurasi '%s' tidak dalam berkas ringkasan"

#: common/flatpak-dir.c:587
#, c-format
msgid "Unable to load summary from remote %s: %s"
msgstr "Tidak dapat memuat ringkasan dari remote %s: %s"

#: common/flatpak-dir.c:764 common/flatpak-dir.c:800 common/flatpak-dir.c:906
#, c-format
msgid "No such ref '%s' in remote %s"
msgstr "Tidak ada ref '%s' pada remote %s"

#: common/flatpak-dir.c:891 common/flatpak-dir.c:1051 common/flatpak-dir.c:1080
#: common/flatpak-dir.c:1092
#, fuzzy, c-format
msgid "No entry for %s in remote %s summary flatpak cache"
msgstr ""
"Tidak ada entri untuk %s dalam ringkasan singgahan remote flatpak '%s' "

#: common/flatpak-dir.c:1069
#, c-format
msgid "No summary or Flatpak cache available for remote %s"
msgstr ""
"Tidak ada ringkasan atau singgahan Flatpak yang tersedia untuk remote %s"

#: common/flatpak-dir.c:1097
#, c-format
msgid "Missing xa.data in summary for remote %s"
msgstr "Hilang xa.data dalam ringkasan untuk remote %s"

#: common/flatpak-dir.c:1103 common/flatpak-dir.c:1546
#, c-format
msgid "Unsupported summary version %d for remote %s"
msgstr "Versi ringkasan yang tidak didukung %d untuk remote %s"

#: common/flatpak-dir.c:1200
msgid "Remote OCI index has no registry uri"
msgstr "Indeks remote OCI tidak memiliki registry uri"

#: common/flatpak-dir.c:1261
#, c-format
msgid "Couldn't find ref %s in remote %s"
msgstr "Tidak dapat menemukan ref %s di remote %s"

#: common/flatpak-dir.c:1288 common/flatpak-dir.c:1381
#, fuzzy, c-format
msgid "Commit has no requested ref ‘%s’ in ref binding metadata (found: ‘%s’)"
msgstr "Komit tidak meminta ref '%s' dalam metadata yang mengikat ref"

#: common/flatpak-dir.c:1413
#, c-format
msgid "Configured collection ID ‘%s’ not in binding metadata"
msgstr "ID koleksi yang dikonfigurasi '%s' tidak dalam metadata yang mengikat"

#: common/flatpak-dir.c:1449 common/flatpak-dir.c:5645
#, c-format
msgid "Couldn't find latest checksum for ref %s in remote %s"
msgstr "Tidak dapat menemukan checksum terbaru untuk %s pada remote %s"

#: common/flatpak-dir.c:1516 common/flatpak-dir.c:1552
#, c-format
msgid "No entry for %s in remote %s summary flatpak sparse cache"
msgstr ""
"Tidak ada entri untuk %s di remote %s ringkasan singgahan jarang flatpak"

#: common/flatpak-dir.c:2540
#, c-format
msgid "Commit metadata for %s not matching expected metadata"
msgstr "Metadata komit untuk %s tidak cocok dengan metadata yang diharapkan"

#: common/flatpak-dir.c:2823
msgid "Unable to connect to system bus"
msgstr "Tidak dapat terhubung ke bus sistem"

#: common/flatpak-dir.c:3419
msgid "User installation"
msgstr "Pemasangan pengguna"

#: common/flatpak-dir.c:3426
#, c-format
msgid "System (%s) installation"
msgstr "Pemasangan sistem (%s)"

#: common/flatpak-dir.c:3472
#, c-format
msgid "No overrides found for %s"
msgstr "Tidak ada timpaan yang ditemukan untuk %s"

#: common/flatpak-dir.c:3625
#, c-format
msgid "%s (commit %s) not installed"
msgstr "%s (komit %s) tidak terpasang"

#: common/flatpak-dir.c:4650
#, c-format
msgid "Error parsing system flatpakrepo file for %s: %s"
msgstr "Galat mengurai berkas sistem flatpakrepo untuk %s: %s"

#: common/flatpak-dir.c:4735
#, c-format
msgid "While opening repository %s: "
msgstr "Saat membuka repositori %s: "

#: common/flatpak-dir.c:5004
#, c-format
msgid "The config key %s is not set"
msgstr "Kunci konfig %s tidak disetel"

#: common/flatpak-dir.c:5140
#, c-format
msgid "No current %s pattern matching %s"
msgstr "Tidak ada pola %s saat ini yang cocok %s"

#: common/flatpak-dir.c:5422
msgid "No appstream commit to deploy"
msgstr "Tidak ada komit aplikasi untuk dideploy"

#: common/flatpak-dir.c:5941 common/flatpak-dir.c:7266
#: common/flatpak-dir.c:10881 common/flatpak-dir.c:11618
msgid "Can't pull from untrusted non-gpg verified remote"
msgstr "Tidak dapat menarik remote non-gpg yang tidak terpercaya"

#: common/flatpak-dir.c:6376 common/flatpak-dir.c:6591
msgid "Extra data not supported for non-gpg-verified local system installs"
msgstr ""
"Data ekstra tidak didukung untuk pemasangan sistem lokal yang tidak "
"diverifikasi gpg"

#: common/flatpak-dir.c:6415 common/flatpak-dir.c:6782
#, c-format
msgid "Invalid checksum for extra data uri %s"
msgstr "Checkum tidak valid untuk uri data ekstra %s"

#: common/flatpak-dir.c:6424
#, c-format
msgid "Empty name for extra data uri %s"
msgstr "Nama kosong untuk uri data ekstra %s"

#: common/flatpak-dir.c:6432
#, c-format
msgid "Unsupported extra data uri %s"
msgstr "Uri data ekstra yang tidak didukung %s"

#: common/flatpak-dir.c:6461
#, c-format
msgid "Failed to load local extra-data %s: %s"
msgstr "Gagal memuat data-ekstra lokal %s: %s"

#: common/flatpak-dir.c:6469
#, c-format
msgid "Wrong size for extra-data %s"
msgstr "Ukuran yang salah untuk data-ekstra %s"

#: common/flatpak-dir.c:6488
#, c-format
msgid "While downloading %s: "
msgstr "Saat mengunduh %s: "

#: common/flatpak-dir.c:6498
#, c-format
msgid "Wrong size for extra data %s"
msgstr "Ukuran yang salah untuk data ekstra %s"

#: common/flatpak-dir.c:6507
#, c-format
msgid "Invalid checksum for extra data %s"
msgstr "Checksum tidak valid untuk data ekstra %s"

#: common/flatpak-dir.c:7096 common/flatpak-dir.c:7349
#, c-format
msgid "While pulling %s from remote %s: "
msgstr "Saat menarik %s dari remote %s: "

#: common/flatpak-dir.c:7290 common/flatpak-repo-utils.c:3886
msgid "GPG signatures found, but none are in trusted keyring"
msgstr ""
"Tanda tangan GPG ditemukan, tetapi tidak ada dalam ring kunci terpercaya"

#: common/flatpak-dir.c:7307
#, c-format
msgid "Commit for ‘%s’ has no ref binding"
msgstr "Komit untuk ‘%s’ tidak memiliki pengikatan ref"

#: common/flatpak-dir.c:7312
#, c-format
msgid "Commit for ‘%s’ is not in expected bound refs: %s"
msgstr "Komit untuk ‘%s’ tidak dalam batas yang diharapkan, ref: %s"

#: common/flatpak-dir.c:7488
msgid "Only applications can be made current"
msgstr "Hanya aplikasi yang dapat dibuat saat ini"

#: common/flatpak-dir.c:8192
msgid "Not enough memory"
msgstr "Memori tidak cukup"

#: common/flatpak-dir.c:8211
msgid "Failed to read from exported file"
msgstr "Gagal membaca dari berkas yang diekspor"

#: common/flatpak-dir.c:8401
msgid "Error reading mimetype xml file"
msgstr "Kesalahan saat membaca berkas xml mimetype"

#: common/flatpak-dir.c:8406
msgid "Invalid mimetype xml file"
msgstr "Berkas xml mimetype tidak valid"

#: common/flatpak-dir.c:8492
#, c-format
msgid "D-Bus service file '%s' has wrong name"
msgstr "Berkas layanan D-Bus '%s' memiliki nama yang salah"

#: common/flatpak-dir.c:8647
#, c-format
msgid "Invalid Exec argument %s"
msgstr "Argumen Exec %s tidak valid"

#: common/flatpak-dir.c:9115
msgid "While getting detached metadata: "
msgstr "Saat mendapatkan metadata yang terpisah: "

#: common/flatpak-dir.c:9120 common/flatpak-dir.c:9125
#: common/flatpak-dir.c:9129
msgid "Extra data missing in detached metadata"
msgstr "Data ekstra hilang dalam metadata terpisah"

#: common/flatpak-dir.c:9133
msgid "While creating extradir: "
msgstr "Saat membuat direktori ekstra: "

#: common/flatpak-dir.c:9154 common/flatpak-dir.c:9187
msgid "Invalid checksum for extra data"
msgstr "Checksum tidak valid untuk data ekstra"

#: common/flatpak-dir.c:9183
msgid "Wrong size for extra data"
msgstr "Ukuran yang salah untuk data ekstra"

#: common/flatpak-dir.c:9196
#, c-format
msgid "While writing extra data file '%s': "
msgstr "Saat menulis berkas data ekstra '%s': "

#: common/flatpak-dir.c:9204
#, c-format
msgid "Extra data %s missing in detached metadata"
msgstr "Data ekstra %s hilang dalam metadata terpisah"

#: common/flatpak-dir.c:9278
#, fuzzy, c-format
msgid "Unable to get runtime key from metadata"
msgstr "Gunakan berkas alternatif untuk metadata"

#: common/flatpak-dir.c:9402
#, c-format
msgid "apply_extra script failed, exit status %d"
msgstr "Skrip apply_extra gagal, status keluar %d"

#. Translators: The placeholder is for an app ref.
#: common/flatpak-dir.c:9591
#, c-format
msgid "Installing %s is not allowed by the policy set by your administrator"
msgstr ""
"Pemasangan %s tidak diizinkan oleh kebijakan yang ditetapkan oleh "
"administrator Anda"

#: common/flatpak-dir.c:9690
#, c-format
msgid "While trying to resolve ref %s: "
msgstr "Saat mencoba menyelesaikan ref %s: "

#: common/flatpak-dir.c:9702
#, c-format
msgid "%s is not available"
msgstr "%s tak tersedia"

#: common/flatpak-dir.c:9714 common/flatpak-dir.c:11495
#, c-format
msgid "%s commit %s already installed"
msgstr "%s komit %s sudah terpasang"

#: common/flatpak-dir.c:9721
msgid "Can't create deploy directory"
msgstr "Tidak dapat membuat direktori deploy"

#: common/flatpak-dir.c:9729
#, c-format
msgid "Failed to read commit %s: "
msgstr "Gagal membaca komit %s: "

#: common/flatpak-dir.c:9750
#, c-format
msgid "While trying to checkout %s into %s: "
msgstr "Saat mencoba melakukan checkout %s ke %s: "

#: common/flatpak-dir.c:9769
msgid "While trying to checkout metadata subpath: "
msgstr "Saat mencoba melakukan checkout metadata subpath: "

#: common/flatpak-dir.c:9801
#, c-format
msgid "While trying to checkout subpath ‘%s’: "
msgstr "Saat mencoba melakukan checkout subpath ‘%s’: "

#: common/flatpak-dir.c:9811
msgid "While trying to remove existing extra dir: "
msgstr "Saat mencoba menghapus direktori ekstra yang ada: "

#: common/flatpak-dir.c:9822
msgid "While trying to apply extra data: "
msgstr "Saat mencoba menerapkan data ekstra: "

#: common/flatpak-dir.c:9849
#, c-format
msgid "Invalid commit ref %s: "
msgstr "Komit ref %s tidak valid: "

#: common/flatpak-dir.c:9857 common/flatpak-dir.c:9869
#, c-format
msgid "Deployed ref %s does not match commit (%s)"
msgstr "Ref %s yang dideploy tidak cocok dengan komit (%s)"

#: common/flatpak-dir.c:9863
#, c-format
msgid "Deployed ref %s branch does not match commit (%s)"
msgstr "Cabang ref %s yang dideploy tidak cocok dengan komit (%s)"

#: common/flatpak-dir.c:10125 common/flatpak-installation.c:1911
#, c-format
msgid "%s branch %s already installed"
msgstr "%s cabang %s sudah terpasang"

#: common/flatpak-dir.c:10985
#, c-format
msgid "Could not unmount revokefs-fuse filesystem at %s: "
msgstr "Tidak dapat melepas kait sistem berkas revokefs-fuse pada %s: "

#: common/flatpak-dir.c:11289
#, c-format
msgid "This version of %s is already installed"
msgstr "Versi %s ini sudah terpasang"

#: common/flatpak-dir.c:11302
#, c-format
msgid "Can't change remote during bundle install"
msgstr "Tidak dapat mengubah remote saat memasang paket"

#: common/flatpak-dir.c:11571
msgid "Can't update to a specific commit without root permissions"
msgstr "Tidak dapat memutakhirkan ke komit spesifik tanpa izin root"

#: common/flatpak-dir.c:11852
#, c-format
msgid "Can't remove %s, it is needed for: %s"
msgstr "Tidak dapat menghapus %s, diperlukan untuk: %s"

#: common/flatpak-dir.c:11912 common/flatpak-installation.c:2067
#, c-format
msgid "%s branch %s is not installed"
msgstr "%s cabang %s tidak terpasang"

#: common/flatpak-dir.c:12165
#, c-format
msgid "%s commit %s not installed"
msgstr "%s komit %s tidak terpasang"

#: common/flatpak-dir.c:12501
#, c-format
msgid "Pruning repo failed: %s"
msgstr "Pemangkasan repo gagal: %s"

#: common/flatpak-dir.c:12669 common/flatpak-dir.c:12675
#, c-format
msgid "Failed to load filter '%s'"
msgstr "Gagal memuat penyaring '%s'"

#: common/flatpak-dir.c:12681
#, c-format
msgid "Failed to parse filter '%s'"
msgstr "Gagal mengurai penyaring '%s'"

#: common/flatpak-dir.c:12963
msgid "Failed to write summary cache: "
msgstr "Gagal menulis singgahan ringkasan: "

#: common/flatpak-dir.c:12982
#, c-format
msgid "No oci summary cached for remote '%s'"
msgstr "Tidak ada ringkasan oci tersinggah untuk remote '%s'"

#: common/flatpak-dir.c:13207
#, c-format
msgid "No cached summary for remote '%s'"
msgstr "Tidak ada ringkasan tersinggah untuk remote '%s'"

#: common/flatpak-dir.c:13248
#, c-format
msgid "Invalid checksum for indexed summary %s read from %s"
msgstr "Checksum tidak valid untuk ringkasan terindeks %s dibaca dari %s"

#: common/flatpak-dir.c:13321
#, c-format
msgid ""
"Remote listing for %s not available; server has no summary file. Check the "
"URL passed to remote-add was valid."
msgstr ""
"Daftar remote untuk %s tidak tersedia; server tidak memiliki berkas "
"ringkasan. Pastikan bahwa URL yang diteruskan ke remote-add valid."

#: common/flatpak-dir.c:13698
#, c-format
msgid "Invalid checksum for indexed summary %s for remote '%s'"
msgstr "Checksum tidak valid untuk ringkasan terindeks %s untuk remote '%s'"

#: common/flatpak-dir.c:14388
#, c-format
msgid "Multiple branches available for %s, you must specify one of: "
msgstr ""
"Beberapa cabang tersedia untuk %s, Anda harus menentukan salah satu dari: "

#: common/flatpak-dir.c:14454
#, c-format
msgid "Nothing matches %s"
msgstr "Tidak ada yang cocok dengan %s"

#: common/flatpak-dir.c:14562
#, c-format
msgid "Can't find ref %s%s%s%s%s"
msgstr "Tidak dapat menemukan ref %s%s%s%s%s"

#: common/flatpak-dir.c:14605
#, c-format
msgid "Error searching remote %s: %s"
msgstr "Galat mencari remote %s: %s"

#: common/flatpak-dir.c:14702
#, c-format
msgid "Error searching local repository: %s"
msgstr "Galat mencari repositori lokal: %s"

#: common/flatpak-dir.c:14839
#, c-format
msgid "%s/%s/%s not installed"
msgstr "%s/%s/%s tidak terpasang"

#: common/flatpak-dir.c:15042
#, c-format
msgid "Could not find installation %s"
msgstr "Tidak dapat menemukan pemasangan %s"

#: common/flatpak-dir.c:15612
#, c-format
msgid "Invalid file format, no %s group"
msgstr "Format berkas tidak valid, tidak ada grup %s"

#: common/flatpak-dir.c:15617 common/flatpak-repo-utils.c:2836
#, c-format
msgid "Invalid version %s, only 1 supported"
msgstr "Versi %s tidak valid, hanya 1 yang didukung"

#: common/flatpak-dir.c:15622 common/flatpak-dir.c:15627
#, c-format
msgid "Invalid file format, no %s specified"
msgstr "Format berkas tidak valid, tidak ada %s yang ditentukan"

#. Check some minimal size so we don't get crap
#: common/flatpak-dir.c:15647
msgid "Invalid file format, gpg key invalid"
msgstr "Format berkas tidak valid, kunci gpg tidak valid"

#: common/flatpak-dir.c:15675 common/flatpak-repo-utils.c:2917
msgid "Collection ID requires GPG key to be provided"
msgstr "ID Koleksi membutuhkan kunci GPG yang akan disediakan"

#: common/flatpak-dir.c:15718
#, c-format
msgid "Runtime %s, branch %s is already installed"
msgstr "Runtime %s, cabang %s telah terpasang"

#: common/flatpak-dir.c:15719
#, c-format
msgid "App %s, branch %s is already installed"
msgstr "Aplikasi %s, cabang %s sudah terpasang"

#: common/flatpak-dir.c:15953
#, c-format
msgid "Can't remove remote '%s' with installed ref %s (at least)"
msgstr ""
"Tidak dapat menghapus remote '%s' dengan ref %s yang terpasang (setidaknya)"

#: common/flatpak-dir.c:16058
#, c-format
msgid "Invalid character '/' in remote name: %s"
msgstr "Karakter tidak valid '/' dalam nama remote: %s"

#: common/flatpak-dir.c:16064
#, c-format
msgid "No configuration for remote %s specified"
msgstr "Tidak ada konfigurasi untuk remote %s yang ditentukan"

#: common/flatpak-dir.c:17597
#, c-format
msgid "Skipping deletion of mirror ref (%s, %s)…\n"
msgstr "Melewati penghapusan mirror ref (%s, %s)…\n"

#: common/flatpak-exports.c:931
#, c-format
msgid "An absolute path is required"
msgstr "Diperlukan path absolut"

#: common/flatpak-exports.c:948
#, c-format
msgid "Unable to open path \"%s\": %s"
msgstr "Tidak dapat membuka path \"%s\": %s"

#: common/flatpak-exports.c:955
#, c-format
msgid "Unable to get file type of \"%s\": %s"
msgstr "Tidak dapat mendapatkan jenis berkas \"%s\": %s"

#: common/flatpak-exports.c:964
#, c-format
msgid "File \"%s\" has unsupported type 0o%o"
msgstr "Berkas \"%s\" memiliki tipe 0o yang tidak didukung%o"

#: common/flatpak-exports.c:970
#, c-format
msgid "Unable to get filesystem information for \"%s\": %s"
msgstr "Tidak dapat memperoleh informasi sistem berkas untuk \"%s\": %s"

#: common/flatpak-exports.c:980
#, c-format
msgid "Ignoring blocking autofs path \"%s\""
msgstr "Mengabaikan pemblokiran path autofs \"%s\""

#: common/flatpak-exports.c:996 common/flatpak-exports.c:1009
#: common/flatpak-exports.c:1022
#, c-format
msgid "Path \"%s\" is reserved by Flatpak"
msgstr "Path \"%s\" disediakan oleh Flatpak"

#: common/flatpak-exports.c:1076
#, c-format
msgid "Unable to resolve symbolic link \"%s\": %s"
msgstr "Tidak dapat menyelesaikan tautan simbolis \"%s\": %s"

#: common/flatpak-glib-backports.c:69
msgid "Empty string is not a number"
msgstr "String kosong bukanlah angka"

#: common/flatpak-glib-backports.c:95
#, c-format
msgid "“%s” is not an unsigned number"
msgstr "\"%s\" bukan bilangan tak bertanda"

#: common/flatpak-glib-backports.c:105
#, c-format
msgid "Number “%s” is out of bounds [%s, %s]"
msgstr "Nomor \"%s\" berada di luar batas [%s, %s]"

#: common/flatpak-image-source.c:83
msgid "Only sha256 image checksums are supported"
msgstr ""

#: common/flatpak-image-source.c:100 common/flatpak-image-source.c:108
msgid "Image is not a manifest"
msgstr "Citra bukan merupakan manifes"

#: common/flatpak-image-source.c:123
msgid "No org.flatpak.ref found in image"
msgstr ""

#: common/flatpak-image-source.c:148
#, c-format
msgid "Ref '%s' not found in registry"
msgstr "Ref '%s' tidak ditemukan di registri"

#: common/flatpak-image-source.c:157
msgid "Multiple images in registry, specify a ref with --ref"
msgstr "Beberapa gambar pada registry, tentukan ref dengan --ref"

#: common/flatpak-installation.c:834
#, c-format
msgid "Ref %s not installed"
msgstr "Ref %s tidak terpasang"

#: common/flatpak-installation.c:875
#, c-format
msgid "App %s not installed"
msgstr "Aplikasi %s tidak terpasang"

#: common/flatpak-installation.c:1395
#, c-format
msgid "Remote '%s' already exists"
msgstr "Remote '%s' sudah ada"

#: common/flatpak-installation.c:1946
#, c-format
msgid "As requested, %s was only pulled, but not installed"
msgstr "Seperti yang diminta, %s hanya ditarik, tetapi tidak dipasang"

#: common/flatpak-instance.c:533 common/flatpak-instance.c:687
#: common/flatpak-instance.c:728
#, c-format
msgid "Unable to create directory %s"
msgstr "Tidak dapat membuat direktori %s"

#: common/flatpak-instance.c:554
#, c-format
msgid "Unable to lock %s"
msgstr "Tidak dapat mengunci %s"

#: common/flatpak-instance.c:627
#, c-format
msgid "Unable to create temporary directory in %s"
msgstr "Tidak dapat membuat direktori sementara dalam %s"

#: common/flatpak-instance.c:639
#, c-format
msgid "Unable to create file %s"
msgstr "Tidak dapat membuat berkas %s"

#: common/flatpak-instance.c:646
#, c-format
msgid "Unable to update symbolic link %s/%s"
msgstr "Tidak dapat memutakhirkan tautan simbolik %s/%s"

#: common/flatpak-oci-registry.c:1197
msgid "Only Bearer authentication supported"
msgstr "Hanya autentikasi Bearer yang didukung"

#: common/flatpak-oci-registry.c:1206
msgid "Only realm in authentication request"
msgstr "Hanya realm dalam permintaan autentikasi"

#: common/flatpak-oci-registry.c:1213
msgid "Invalid realm in authentication request"
msgstr "Realm tidak valid dalam permintaan autentikasi"

#: common/flatpak-oci-registry.c:1283
#, c-format
msgid "Authorization failed: %s"
msgstr "Otorisasi gagal: %s"

#: common/flatpak-oci-registry.c:1285
msgid "Authorization failed"
msgstr "Otorisasi gagal"

#: common/flatpak-oci-registry.c:1289
#, c-format
msgid "Unexpected response status %d when requesting token: %s"
msgstr "Status respons tak terduga %d saat meminta token: %s"

#: common/flatpak-oci-registry.c:1300
msgid "Invalid authentication request response"
msgstr "Respons permintaan autentikasi tidak valid"

#: common/flatpak-oci-registry.c:1731
#, c-format
msgid "Flatpak was compiled without zstd support"
msgstr ""

#: common/flatpak-oci-registry.c:1923 common/flatpak-oci-registry.c:1975
#: common/flatpak-oci-registry.c:2004 common/flatpak-oci-registry.c:2059
#: common/flatpak-oci-registry.c:2115 common/flatpak-oci-registry.c:2193
msgid "Invalid delta file format"
msgstr "Format berkas delta tidak valid"

#: common/flatpak-oci-registry.c:3198 common/flatpak-oci-registry.c:3382
msgid "Invalid OCI image config"
msgstr "Konfigurasi citra OCI tidak valid"

#: common/flatpak-oci-registry.c:3260 common/flatpak-oci-registry.c:3531
#, c-format
msgid "Wrong layer checksum, expected %s, was %s"
msgstr "Pemeriksaan layer yang salah, yang diharapkan %s, ternyata %s"

#: common/flatpak-oci-registry.c:3359
#, c-format
msgid "No ref specified for OCI image %s"
msgstr "Tidak ada ref yang ditentukan untuk citra OCI %s"

#: common/flatpak-oci-registry.c:3369
#, c-format
msgid "Wrong ref (%s) specified for OCI image %s, expected %s"
msgstr "Ref (%s) yang salah ditentukan untuk citra OCI %s, yang diharapkan %s"

#: common/flatpak-progress.c:236
#, c-format
msgid "Downloading metadata: %u/(estimating) %s"
msgstr "Mengunduh metadata: %u /(perkiraan) %s"

#: common/flatpak-progress.c:260
#, c-format
msgid "Downloading: %s/%s"
msgstr "Mengunduh: %s/%s"

#: common/flatpak-progress.c:280
#, c-format
msgid "Downloading extra data: %s/%s"
msgstr "Mengunduh data ekstra: %s/%s"

#: common/flatpak-progress.c:285
#, c-format
msgid "Downloading files: %d/%d %s"
msgstr "Mengunduh berkas: %d/%d %s"

#: common/flatpak-ref-utils.c:122
msgid "Name can't be empty"
msgstr "Nama tidak boleh kosong"

#: common/flatpak-ref-utils.c:129
msgid "Name can't be longer than 255 characters"
msgstr "Nama tidak boleh lebih dari 255 karakter"

#: common/flatpak-ref-utils.c:142
msgid "Name can't start with a period"
msgstr "Nama tidak boleh dimulai dengan titik"

#: common/flatpak-ref-utils.c:148
#, c-format
msgid "Name can't start with %c"
msgstr "Nama tidak boleh dimulai dengan %c"

#: common/flatpak-ref-utils.c:164
msgid "Name can't end with a period"
msgstr "Nama tidak boleh diakhiri dengan titik"

#: common/flatpak-ref-utils.c:171 common/flatpak-ref-utils.c:183
msgid "Only last name segment can contain -"
msgstr "Hanya segmen nama belakang yang boleh berisi -"

#: common/flatpak-ref-utils.c:174
#, c-format
msgid "Name segment can't start with %c"
msgstr "Segmen nama tidak boleh dimulai dengan %c"

#: common/flatpak-ref-utils.c:186
#, c-format
msgid "Name can't contain %c"
msgstr "Nama tidak boleh mengandung %c"

#: common/flatpak-ref-utils.c:195
msgid "Names must contain at least 2 periods"
msgstr "Nama harus mengandung setidaknya 2 titik"

#: common/flatpak-ref-utils.c:312
msgid "Arch can't be empty"
msgstr "Arsitektur tidak boleh kosong"

#: common/flatpak-ref-utils.c:323
#, c-format
msgid "Arch can't contain %c"
msgstr "Arsitektur tidak boleh berisi %c"

#: common/flatpak-ref-utils.c:385
msgid "Branch can't be empty"
msgstr "Cabang tidak boleh kosong"

#: common/flatpak-ref-utils.c:395
#, c-format
msgid "Branch can't start with %c"
msgstr "Cabang tidak boleh dimulai dengan %c"

#: common/flatpak-ref-utils.c:405
#, c-format
msgid "Branch can't contain %c"
msgstr "Cabang tidak boleh berisi %c"

#: common/flatpak-ref-utils.c:615 common/flatpak-ref-utils.c:865
msgid "Ref too long"
msgstr "Ref terlalu panjang"

#: common/flatpak-ref-utils.c:627
msgid "Invalid remote name"
msgstr "Nama remote tidak valid"

#: common/flatpak-ref-utils.c:641
#, c-format
msgid "%s is not application or runtime"
msgstr "%s bukan aplikasi atau runtime"

#: common/flatpak-ref-utils.c:650 common/flatpak-ref-utils.c:667
#: common/flatpak-ref-utils.c:683
#, c-format
msgid "Wrong number of components in %s"
msgstr "Salah jumlah komponen dalam %s"

#: common/flatpak-ref-utils.c:656
#, c-format
msgid "Invalid name %.*s: %s"
msgstr "Nama tidak valid %.*s: %s"

#: common/flatpak-ref-utils.c:673
#, c-format
msgid "Invalid arch: %.*s: %s"
msgstr "Arsitektur tidak valid: %.*s: %s"

#: common/flatpak-ref-utils.c:816
#, c-format
msgid "Invalid name %s: %s"
msgstr "Nama tidak valid %s: %s"

#: common/flatpak-ref-utils.c:834
#, c-format
msgid "Invalid arch: %s: %s"
msgstr "Arsitektur tidak valid: %s: %s"

#: common/flatpak-ref-utils.c:853
#, c-format
msgid "Invalid branch: %s: %s"
msgstr "Cabang tidak valid: %s: %s"

#: common/flatpak-ref-utils.c:962 common/flatpak-ref-utils.c:970
#: common/flatpak-ref-utils.c:978
#, c-format
msgid "Wrong number of components in partial ref %s"
msgstr "Jumlah komponen yang salah dalam ref %s"

#: common/flatpak-ref-utils.c:1298
msgid " development platform"
msgstr " platform pengembangan"

#: common/flatpak-ref-utils.c:1300
msgid " platform"
msgstr " platform"

#: common/flatpak-ref-utils.c:1302
msgid " application base"
msgstr " basis aplikasi"

#: common/flatpak-ref-utils.c:1305
msgid " debug symbols"
msgstr " simbol awakutu"

#: common/flatpak-ref-utils.c:1307
msgid " sourcecode"
msgstr " kode sumber"

#: common/flatpak-ref-utils.c:1309
msgid " translations"
msgstr " terjemahan"

#: common/flatpak-ref-utils.c:1311
msgid " docs"
msgstr " dokumen"

#: common/flatpak-ref-utils.c:1578
#, c-format
msgid "Invalid id %s: %s"
msgstr "Id tidak valid %s: %s"

#: common/flatpak-remote.c:1216
#, c-format
msgid "Bad remote name: %s"
msgstr "Nama remote buruk: %s"

#: common/flatpak-remote.c:1220
#, fuzzy
msgid "No URL specified"
msgstr "Tidak ada url yang ditentukan"

#: common/flatpak-remote.c:1266
msgid "GPG verification must be enabled when a collection ID is set"
msgstr "Verifikasi GPG harus diaktifkan ketika ID koleksi ditetapkan"

#: common/flatpak-repo-utils.c:344
#, c-format
msgid "No extra data sources"
msgstr "Tidak ada sumber data ekstra"

#: common/flatpak-repo-utils.c:2817
#, c-format
msgid "Invalid %s: Missing group ‘%s’"
msgstr "%s tidak valid: Grup ‘%s’ tidak ada"

#: common/flatpak-repo-utils.c:2826
#, c-format
msgid "Invalid %s: Missing key ‘%s’"
msgstr "%s tidak valid: Kunci ‘%s’ tidak ada"

#: common/flatpak-repo-utils.c:2876
msgid "Invalid gpg key"
msgstr "Kunci gpg tidak valid"

#: common/flatpak-repo-utils.c:3217
#, c-format
msgid "Error copying 64x64 icon for component %s: %s\n"
msgstr "Galat menyalin ikon 64x64 untuk komponen %s: %s\n"

#: common/flatpak-repo-utils.c:3223
#, c-format
msgid "Error copying 128x128 icon for component %s: %s\n"
msgstr "Galat menyalin ikon 128x128 untuk komponen %s: %s\n"

#: common/flatpak-repo-utils.c:3362
#, c-format
msgid "%s is end-of-life, ignoring for appstream"
msgstr "%s adalah akhir masa pakai, mengabaikan untuk appstream"

#: common/flatpak-repo-utils.c:3397
#, c-format
msgid "No appstream data for %s: %s\n"
msgstr "Tidak ada data appstream untuk %s: %s\n"

#: common/flatpak-repo-utils.c:3744
msgid "Invalid bundle, no ref in metadata"
msgstr "Bundel tidak valid, tidak ada ref dalam metadata"

#: common/flatpak-repo-utils.c:3846
#, c-format
msgid "Collection ‘%s’ of bundle doesn’t match collection ‘%s’ of remote"
msgstr "Koleksi ‘%s’ dari bundel tidak cocok dengan koleksi ‘%s’ dari remote"

#: common/flatpak-repo-utils.c:3923
msgid "Metadata in header and app are inconsistent"
msgstr "Metadata pada header dan aplikasi tidak konsisten"

#: common/flatpak-run.c:951
msgid "No systemd user session available, cgroups not available"
msgstr "Tidak ada sesi pengguna systemd, cgroup tidak tersedia"

#: common/flatpak-run.c:1496
msgid "Unable to allocate instance id"
msgstr "Tidak dapat mengalokasikan id instance"

#: common/flatpak-run.c:1632 common/flatpak-run.c:1641
#, c-format
msgid "Failed to open flatpak-info file: %s"
msgstr "Gagal membuka berkas flatpak-info: %s"

#: common/flatpak-run.c:1668
#, c-format
msgid "Failed to open bwrapinfo.json file: %s"
msgstr "Gagal membuka berkas bwrapinfo.json: %s"

#: common/flatpak-run.c:1689
#, c-format
msgid "Failed to write to instance id fd: %s"
msgstr "Gagal menulis ke id instance fd: %s"

#: common/flatpak-run.c:2096
msgid "Initialize seccomp failed"
msgstr "Inisialisasi seccomp gagal"

#: common/flatpak-run.c:2135
#, c-format
msgid "Failed to add architecture to seccomp filter: %s"
msgstr "Gagal menambahkan arsitektur ke penyaring seccomp: %s"

#: common/flatpak-run.c:2143
#, c-format
msgid "Failed to add multiarch architecture to seccomp filter: %s"
msgstr "Gagal menambahkan arsitektur multiarch ke penyaring seccomp: %s"

#: common/flatpak-run.c:2175 common/flatpak-run.c:2192
#: common/flatpak-run.c:2214
#, c-format
msgid "Failed to block syscall %d: %s"
msgstr "Gagal memblokir syscall %d: %s"

#: common/flatpak-run.c:2247
#, c-format
msgid "Failed to export bpf: %s"
msgstr "Gagal mengekspor bpf: %s"

#: common/flatpak-run.c:2587
#, c-format
msgid "Failed to open ‘%s’"
msgstr "Gagal membuka ‘%s’"

#: common/flatpak-run.c:2597
#, c-format
msgid ""
"Directory forwarding needs version 4 of the document portal (have version %d)"
msgstr ""

#: common/flatpak-run.c:2915
#, c-format
msgid "ldconfig failed, exit status %d"
msgstr "ldconfig gagal, status keluar %d"

#: common/flatpak-run.c:2922
msgid "Can't open generated ld.so.cache"
msgstr "Tidak dapat membuka ld.so.cache yang dihasilkan"

#. Translators: The placeholder is for an app ref.
#: common/flatpak-run.c:3045
#, c-format
msgid "Running %s is not allowed by the policy set by your administrator"
msgstr ""
"Menjalankan %s tidak diizinkan oleh kebijakan yang ditetapkan oleh "
"administrator Anda"

#: common/flatpak-run.c:3202
msgid ""
"\"flatpak run\" is not intended to be run as `sudo flatpak run`. Use `sudo "
"-i` or `su -l` instead and invoke \"flatpak run\" from inside the new shell."
msgstr ""
"\"flatpak run\" tidak dimaksudkan untuk dijalankan sebagai `sudo flatpak "
"run`. Gunakan `sudo -i` atau `su -l` sebagai gantinya dan panggil \"flatpak "
"run\" dari dalam shell baru."

#: common/flatpak-run.c:3413
#, c-format
msgid "Failed to migrate from %s: %s"
msgstr "Gagal bermigrasi dari %s: %s"

#: common/flatpak-run.c:3434
#, c-format
msgid "Failed to migrate old app data directory %s to new name %s: %s"
msgstr "Gagal memigrasi direktori data aplikasi lama %s ke nama baru %s: %s"

#: common/flatpak-run.c:3443
#, c-format
msgid "Failed to create symlink while migrating %s: %s"
msgstr "Gagal membuat tautan simbolik saat memigrasi %s: %s"

#: common/flatpak-run-dbus.c:46
msgid "Failed to open app info file"
msgstr "Gagal membuka berkas info aplikasi"

#: common/flatpak-run-dbus.c:149
msgid "Unable to create sync pipe"
msgstr "Tidak dapat membuat pipa sinkronisasi"

#: common/flatpak-run-dbus.c:185
msgid "Failed to sync with dbus proxy"
msgstr "Gagal melakukan sinkronisasi dengan proksi dbus"

#: common/flatpak-transaction.c:2275
#, c-format
msgid "Warning: Problem looking for related refs: %s"
msgstr "Peringatan: Masalah mencari ref terkait: %s"

#: common/flatpak-transaction.c:2493
#, c-format
msgid "The application %s requires the runtime %s which was not found"
msgstr "Aplikasi %s membutuhkan runtime %s yang tidak ditemukan"

#: common/flatpak-transaction.c:2509
#, c-format
msgid "The application %s requires the runtime %s which is not installed"
msgstr "Aplikasi %s membutuhkan runtime %s yang tidak terpasang"

#: common/flatpak-transaction.c:2641
#, c-format
msgid "Can't uninstall %s which is needed by %s"
msgstr "Tidak dapat menghapus %s yang diperlukan untuk %s"

#: common/flatpak-transaction.c:2740
#, c-format
msgid "Remote %s disabled, ignoring %s update"
msgstr "Remote %s dinonaktifkan, mengabaikan pemutakhiran %s"

#: common/flatpak-transaction.c:2773
#, c-format
msgid "%s is already installed"
msgstr "%s sudah dipasang"

#: common/flatpak-transaction.c:2776
#, c-format
msgid "%s is already installed from remote %s"
msgstr "%s sudah dipasang dari remote %s"

#: common/flatpak-transaction.c:3120
#, c-format
msgid "Invalid .flatpakref: %s"
msgstr ".flatpakref tidak valid: %s"

#: common/flatpak-transaction.c:3161
msgid "Warning: Could not mark already installed apps as preinstalled"
msgstr ""

#: common/flatpak-transaction.c:3382
#, c-format
msgid "Error updating remote metadata for '%s': %s"
msgstr "Galat memutakhirkan metadata remote untuk '%s': %s"

#: common/flatpak-transaction.c:3885
#, c-format
msgid ""
"Warning: Treating remote fetch error as non-fatal since %s is already "
"installed: %s"
msgstr ""
"Peringatan: Memperlakukan kesalahan pengambilan remote sebagai non-fatal "
"sejak %s sudah dipasang: %s"

#: common/flatpak-transaction.c:4209
#, c-format
msgid "No authenticator installed for remote '%s'"
msgstr "Tidak ada autentikator yang dipasang untuk remote `%s`"

#: common/flatpak-transaction.c:4313 common/flatpak-transaction.c:4320
#, c-format
msgid "Failed to get tokens for ref: %s"
msgstr "Gagal mendapatkan token untuk ref: %s"

#: common/flatpak-transaction.c:4315 common/flatpak-transaction.c:4322
msgid "Failed to get tokens for ref"
msgstr "Gagal mendapatkan token untuk ref"

#: common/flatpak-transaction.c:4580
#, c-format
msgid "Ref %s from %s matches more than one transaction operation"
msgstr "Ref %s dari %s cocok dengan lebih dari satu operasi transaksi"

#: common/flatpak-transaction.c:4581 common/flatpak-transaction.c:4591
msgid "any remote"
msgstr "remote apapun"

#: common/flatpak-transaction.c:4590
#, c-format
msgid "No transaction operation found for ref %s from %s"
msgstr "Tidak ditemukan operasi transaksi untuk referensi %s dari %s"

#: common/flatpak-transaction.c:4713
#, c-format
msgid "Flatpakrepo URL %s not file, HTTP or HTTPS"
msgstr "URL flatpakrepo %s bukan berkas, HTTP atau HTTPS"

#: common/flatpak-transaction.c:4719
#, c-format
msgid "Can't load dependent file %s: "
msgstr "Tidak dapat memuat berkas dependen %s: "

#: common/flatpak-transaction.c:4727
#, c-format
msgid "Invalid .flatpakrepo: %s"
msgstr ".flatpakrepo tidak valid: %s"

#: common/flatpak-transaction.c:5454
msgid "Transaction already executed"
msgstr "Transaksi sudah dijalankan"

#: common/flatpak-transaction.c:5469
msgid ""
"Refusing to operate on a user installation as root! This can lead to "
"incorrect file ownership and permission errors."
msgstr ""
"Menolak beroperasi pada pemasangan pengguna sebagai root! Ini dapat "
"menyebabkan galat kepemilikan berkas dan izin."

#: common/flatpak-transaction.c:5567 common/flatpak-transaction.c:5580
msgid "Aborted by user"
msgstr "Dibatalkan oleh pengguna"

#: common/flatpak-transaction.c:5605
#, c-format
msgid "Skipping %s due to previous error"
msgstr "Melewatkan %s karena galat sebelumnya"

#: common/flatpak-transaction.c:5659
#, c-format
msgid "Aborted due to failure (%s)"
msgstr "Dibatalkan karena gagal (%s)"

#: common/flatpak-uri.c:118
#, no-c-format
msgid "Invalid %-encoding in URI"
msgstr "%-encoding tidak valid dalam URI"

#: common/flatpak-uri.c:135
msgid "Illegal character in URI"
msgstr "Karakter ilegal dalam URI"

#: common/flatpak-uri.c:169
msgid "Non-UTF-8 characters in URI"
msgstr "Karakter non-UTF-8 dalam URI"

#: common/flatpak-uri.c:275
#, c-format
msgid "Invalid IPv6 address ‘%.*s’ in URI"
msgstr "Alamat IPv6 tidak valid ‘%.*s’ dalam URI"

#: common/flatpak-uri.c:330
#, c-format
msgid "Illegal encoded IP address ‘%.*s’ in URI"
msgstr "Alamat IP dikodekan ilegal ‘%.*s’ dalam URI"

#: common/flatpak-uri.c:342
#, c-format
msgid "Illegal internationalized hostname ‘%.*s’ in URI"
msgstr "Nama host internasional ilegal '%.*s' di URI"

#: common/flatpak-uri.c:374 common/flatpak-uri.c:386
#, c-format
msgid "Could not parse port ‘%.*s’ in URI"
msgstr "Tidak dapat mengurai port '%.*s' di URI"

#: common/flatpak-uri.c:393
#, c-format
msgid "Port ‘%.*s’ in URI is out of range"
msgstr "Port ‘%.*s’ dalam URI di luar jangkauan"

#: common/flatpak-uri.c:910
msgid "URI is not absolute, and no base URI was provided"
msgstr "URI tidak mutlak, dan tidak ada URI dasar yang disediakan"

#: common/flatpak-usb.c:83
#, c-format
msgid "USB device query 'all' must not have data"
msgstr ""

#: common/flatpak-usb.c:102
#, c-format
msgid "USB query rule 'cls' must be in the form CLASS:SUBCLASS or CLASS:*"
msgstr ""

#: common/flatpak-usb.c:111
#, fuzzy, c-format
msgid "Invalid USB class"
msgstr "Id tidak valid %s: %s"

#: common/flatpak-usb.c:125
#, c-format
msgid "Invalid USB subclass"
msgstr ""

#: common/flatpak-usb.c:141 common/flatpak-usb.c:148
#, c-format
msgid "USB query rule 'dev' must have a valid 4-digit hexadecimal product id"
msgstr ""

#: common/flatpak-usb.c:164 common/flatpak-usb.c:171
#, c-format
msgid "USB query rule 'vnd' must have a valid 4-digit hexadecimal vendor id"
msgstr ""

#: common/flatpak-usb.c:205
#, c-format
msgid "USB device queries must be in the form TYPE:DATA"
msgstr ""

#: common/flatpak-usb.c:225
#, c-format
msgid "Unknown USB query rule %s"
msgstr ""

#: common/flatpak-usb.c:248
#, c-format
msgid "Empty USB query"
msgstr ""

#: common/flatpak-usb.c:274
#, c-format
msgid "Multiple USB query rules of the same type is not supported"
msgstr ""

#: common/flatpak-usb.c:283
#, c-format
msgid "'all' must not contain extra query rules"
msgstr ""

#: common/flatpak-usb.c:291
#, c-format
msgid "USB queries with 'dev' must also specify vendors"
msgstr ""

#: common/flatpak-utils.c:712
msgid "Glob can't match apps"
msgstr "Glob tidak dapat mencocokkan aplikasi"

#: common/flatpak-utils.c:737
msgid "Empty glob"
msgstr "Glob kosong"

#: common/flatpak-utils.c:756
msgid "Too many segments in glob"
msgstr "Terlalu banyak segmen pada glob"

#: common/flatpak-utils.c:777
#, c-format
msgid "Invalid glob character '%c'"
msgstr "Karakter glob tidak valid '%c'"

#: common/flatpak-utils.c:831
#, c-format
msgid "Missing glob on line %d"
msgstr "Glob yang hilang pada baris %d"

#: common/flatpak-utils.c:835
#, c-format
msgid "Trailing text on line %d"
msgstr "Perataan teks pada baris %d"

#: common/flatpak-utils.c:839
#, c-format
msgid "on line %d"
msgstr "pada baris %d"

#: common/flatpak-utils.c:861
#, c-format
msgid "Unexpected word '%s' on line %d"
msgstr "Kata '%s' tak diharapkan pada baris %d"

#: common/flatpak-utils.c:2118
#, c-format
msgid "Invalid require-flatpak argument %s"
msgstr "Argumen require-flatpak %s tidak valid"

#: common/flatpak-utils.c:2128 common/flatpak-utils.c:2147
#, c-format
msgid "%s needs a later flatpak version (%s)"
msgstr "%s membutuhkan versi flatpak yang lebih baru (%s)"

#: oci-authenticator/flatpak-oci-authenticator.c:291
msgid "Not a oci remote, missing summary.xa.oci-repository"
msgstr "Bukan remote oci, hilang summary.xa.oci-repository"

#: oci-authenticator/flatpak-oci-authenticator.c:477
msgid "Not a OCI remote"
msgstr "Bukan remote OCI"

#: oci-authenticator/flatpak-oci-authenticator.c:488
msgid "Invalid token"
msgstr "Token tidak valid"

#: portal/flatpak-portal.c:2292
#, c-format
msgid "No portal support found"
msgstr "Dukungan portal tidak ditemukan"

#: portal/flatpak-portal.c:2298
msgid "Deny"
msgstr "Tolak"

#: portal/flatpak-portal.c:2300
msgid "Update"
msgstr "Mutakhirkan"

#: portal/flatpak-portal.c:2305
#, c-format
msgid "Update %s?"
msgstr "Mutakhirkan %s?"

#: portal/flatpak-portal.c:2317
msgid "The application wants to update itself."
msgstr "Aplikasi ingin memutakhirkan dirinya sendiri."

#: portal/flatpak-portal.c:2318
msgid "Update access can be changed any time from the privacy settings."
msgstr "Akses pemutakhiran dapat diubah kapan saja dari pengaturan privasi."

#: portal/flatpak-portal.c:2343
#, c-format
msgid "Application update not allowed"
msgstr "Pemutakhiran aplikasi tidak diizinkan"

#: portal/flatpak-portal.c:2501
#, c-format
msgid "Self update not supported, new version requires new permissions"
msgstr ""
"Pemutakhiran diri sendiri tidak didukung, versi baru memerlukan izin baru"

#: portal/flatpak-portal.c:2684 portal/flatpak-portal.c:2702
#, c-format
msgid "Update ended unexpectedly"
msgstr "Pemutakhiran berakhir tidak terduga"

#. SECURITY:
#. - Normal users need admin authentication to install software
#. system-wide.
#. - Note that we install polkit rules that allow local users
#. in the wheel group to install without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:23
msgid "Install signed application"
msgstr "Pasang aplikasi yang bertandatangan"

#: system-helper/org.freedesktop.Flatpak.policy.in:24
#: system-helper/org.freedesktop.Flatpak.policy.in:42
msgid "Authentication is required to install software"
msgstr "Autentikasi diperlukan untuk memasang perangkat lunak"

#. SECURITY:
#. - Normal users need admin authentication to install software
#. system-wide.
#. - Note that we install polkit rules that allow local users
#. in the wheel group to install without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:41
msgid "Install signed runtime"
msgstr "Pasang runtime bertandatangan"

#. SECURITY:
#. - Normal users do not require admin authentication to update an
#. app as the commit will be signed, and the action is required
#. to update the system when unattended.
#. - Changing this to anything other than 'yes' will break unattended
#. updates.
#: system-helper/org.freedesktop.Flatpak.policy.in:60
msgid "Update signed application"
msgstr "Mutakhirkan aplikasi yang bertandatangan"

#: system-helper/org.freedesktop.Flatpak.policy.in:61
#: system-helper/org.freedesktop.Flatpak.policy.in:80
msgid "Authentication is required to update software"
msgstr "Autentikasi diperlukan untuk memutakhirkan perangkat lunak"

#. SECURITY:
#. - Normal users do not require admin authentication to update a
#. runtime as the commit will be signed, and the action is required
#. to update the system when unattended.
#. - Changing this to anything other than 'yes' will break unattended
#. updates.
#: system-helper/org.freedesktop.Flatpak.policy.in:79
msgid "Update signed runtime"
msgstr "Mutakhirkan runtime yang bertandatangan"

#. SECURITY:
#. - Normal users do not need authentication to update metadata
#. from signed repositories.
#: system-helper/org.freedesktop.Flatpak.policy.in:94
msgid "Update remote metadata"
msgstr "Mutakhirkan metadata remote"

#: system-helper/org.freedesktop.Flatpak.policy.in:95
msgid "Authentication is required to update remote info"
msgstr "Autentikasi diperlukan untuk memutakhirkan info remote"

#. SECURITY:
#. - Normal users do not need authentication to modify the
#. OSTree repository
#. - Note that we install polkit rules that allow local users
#. in the wheel group to modify repos without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:111
msgid "Update system repository"
msgstr "Mutakhirkan repositori sistem"

#: system-helper/org.freedesktop.Flatpak.policy.in:112
msgid "Authentication is required to modify a system repository"
msgstr "Autentikasi diperlukan untuk memodifikasi sistem repositori"

#. SECURITY:
#. - Normal users need admin authentication to install software
#. system-wide.
#: system-helper/org.freedesktop.Flatpak.policy.in:126
msgid "Install bundle"
msgstr "Pasang bundel"

#: system-helper/org.freedesktop.Flatpak.policy.in:127
msgid "Authentication is required to install software from $(path)"
msgstr "Autentikasi diperlukan untuk memasang perangkat lunak dari $(path)"

#. SECURITY:
#. - Normal users need admin authentication to uninstall software
#. system-wide.
#. - Note that we install polkit rules that allow local users
#. in the wheel group to uninstall without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:144
msgid "Uninstall runtime"
msgstr "Hapus runtime"

#: system-helper/org.freedesktop.Flatpak.policy.in:145
msgid "Authentication is required to uninstall software"
msgstr "Autentikasi diperlukan untuk menghapus perangkat lunak"

#. SECURITY:
#. - Normal users need admin authentication to uninstall software
#. system-wide.
#. - Note that we install polkit rules that allow local users
#. in the wheel group to uninstall without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:161
msgid "Uninstall app"
msgstr "Hapus pemasangan aplikasi"

#: system-helper/org.freedesktop.Flatpak.policy.in:162
msgid "Authentication is required to uninstall $(ref)"
msgstr "Autentikasi diperlukan untuk menghapus $(ref)"

#. SECURITY:
#. - Normal users need admin authentication to configure system-wide
#. software repositories.
#: system-helper/org.freedesktop.Flatpak.policy.in:177
msgid "Configure Remote"
msgstr "Mengkonfigurasi Remote"

#: system-helper/org.freedesktop.Flatpak.policy.in:178
msgid "Authentication is required to configure software repositories"
msgstr ""
"Autentikasi diperlukan untuk mengkonfigurasi repositori perangkat lunak"

#. SECURITY:
#. - Normal users need admin authentication to configure the system-wide
#. Flatpak installation.
#: system-helper/org.freedesktop.Flatpak.policy.in:192
msgid "Configure"
msgstr "Konfigurasi"

#: system-helper/org.freedesktop.Flatpak.policy.in:193
msgid "Authentication is required to configure software installation"
msgstr ""
"Autentikasi diperlukan untuk mengkonfigurasi pemasangan perangkat lunak"

#. SECURITY:
#. - Normal users do not require admin authentication to update
#. appstream data as it will be signed, and the action is required
#. to update the system when unattended.
#. - Changing this to anything other than 'yes' will break unattended
#. updates.
#: system-helper/org.freedesktop.Flatpak.policy.in:210
msgid "Update appstream"
msgstr "Mutakhirkan appstream"

#: system-helper/org.freedesktop.Flatpak.policy.in:211
msgid "Authentication is required to update information about software"
msgstr ""
"Autentikasi diperlukan untuk memutakhirkan informasi tentang perangkat lunak"

#. SECURITY:
#. - Normal users do not require admin authentication to update
#. metadata as it will be signed, and the action is required
#. to update the system when unattended.
#. - Changing this to anything other than 'yes' will break unattended
#. updates.
#: system-helper/org.freedesktop.Flatpak.policy.in:228
msgid "Update metadata"
msgstr "Mutakhirkan metadata"

#: system-helper/org.freedesktop.Flatpak.policy.in:229
msgid "Authentication is required to update metadata"
msgstr "Autentikasi diperlukan untuk memutakhirkan metadata"

#. SECURITY:
#. - Authorisation to actually install software is controlled by
#. org.freedesktop.Flatpak.app-install.
#. - This action is checked after app-install, as it can only be done
#. once the app’s data (including its content rating) has been
#. downloaded.
#. - This action is checked to see if the installation should be allowed
#. based on whether the app being installed has content which doesn’t
#. comply with the user’s parental controls policy (the content is
#. ‘too extreme’).
#. - It is checked only if an app has too extreme content for the user
#. who is trying to install it (in which case, the app is ‘unsafe’).
#. - Typically, normal users will need admin permission to install apps
#. with extreme content; admins will be able to install it without
#. additional checks.
#. - In order to configure the policy so that admins can install safe and
#. unsafe software anywhere without authorisation, and non-admins can
#. install safe software in their user or system dirs without
#. authorisation, but need authorisation to install unsafe software
#. anywhere:
#. * Unconditionally return `yes` from `app-install`.
#. * Return `auth_admin` from `override-parental-controls` for users
#. not in `@privileged_group@`, and `yes` for users in it.
#. * Set the malcontent `is-{user,system}-installation-allowed`
#. properties of all non-admins’ parental controls policies to true.
#. - In order to configure the policy so that admins can install safe and
#. unsafe software anywhere without authorisation, and non-admins can
#. install safe software in their user dir without authorisation, but
#. need authorisation to install safe software in the system dir or to
#. install unsafe software anywhere:
#. * Unconditionally return `yes` from `app-install`.
#. * Return `auth_admin` from `override-parental-controls` for users
#. not in `@privileged_group@`, and `yes` for users in it.
#. * Set the malcontent `is-user-installation-allowed` property of all
#. non-admins’ parental controls policies to true.
#. * Set the malcontent `is-system-installation-allowed` property of
#. all non-admins’ parental controls policies to false.
#. - In order to configure the policy so that all users (including
#. admins) can install safe software anywhere without authorisation,
#. but need authorisation to install unsafe software anywhere (i.e.
#. applying parental controls to admins too):
#. * Unconditionally return `yes` from `app-install`.
#. * Unconditionally return `auth_admin` from `override-parental-controls`.
#. * Set the malcontent `is-user-installation-allowed` property of all
#. users’ parental controls policies to true.
#. * Set the malcontent `is-system-installation-allowed` property of
#. all users’ parental controls policies to true.
#: system-helper/org.freedesktop.Flatpak.policy.in:287
#, fuzzy
msgid "Override parental controls for installs"
msgstr "Timpa kontrol orangtua"

#: system-helper/org.freedesktop.Flatpak.policy.in:288
msgid ""
"Authentication is required to install software which is restricted by your "
"parental controls policy"
msgstr ""
"Autentikasi diperlukan untuk memasang perangkat lunak yang dibatasi oleh "
"kebijakan kontrol orang tua Anda"

#. SECURITY:
#. - This is like org.freedesktop.Flatpak.override-parental-controls, but
#. it’s queried for app updates, whereas the former is queried for app
#. installs.
#. - As with the above action, this one is only queried if
#. org.freedesktop.Flatpak.app-update has allowed the app update, and
#. only if the app being updated has too extreme content for the user
#. who is trying to update it.
#. - The default policy for this is to *allow* updates to ‘too extreme’
#. apps by default, on the basis that having an out-of-date (i.e.
#. insecure or unsupported) app is a worse outcome than automatically
#. installing an update which has radically different content from the
#. version of the app which the parent originally vetted and installed.
#: system-helper/org.freedesktop.Flatpak.policy.in:313
#, fuzzy
msgid "Override parental controls for updates"
msgstr "Timpa kontrol orangtua"

#: system-helper/org.freedesktop.Flatpak.policy.in:314
#, fuzzy
msgid ""
"Authentication is required to update software which is restricted by your "
"parental controls policy"
msgstr ""
"Autentikasi diperlukan untuk memasang perangkat lunak yang dibatasi oleh "
"kebijakan kontrol orang tua Anda"

#~ msgid "Installed:"
#~ msgstr "Terpasang:"

#~ msgid "Download:"
#~ msgstr "Unduh:"

#, c-format
#~ msgid "No gpg key found with ID %s (homedir: %s)"
#~ msgstr "Tidak ditemukan kunci gpg dengan ID %s (homedir: %s)"

#, c-format
#~ msgid "Unable to lookup key ID %s: %d"
#~ msgstr "Tidak dapat mencari ID kunci %s: %d"

#, c-format
#~ msgid "Error signing commit: %d"
#~ msgstr "Galat menandatangani komit: %d"

#, c-format
#~ msgid ""
#~ "Found similar ref(s) for ‘%s’ in remote ‘%s’ (%s).\n"
#~ "Use this remote?"
#~ msgstr ""
#~ "Ref serupa ditemukan untuk ‘%s’ dalam remote ‘%s’ (%s):\n"
#~ "Gunakan remote ini?"

#, c-format
#~ msgid "No entry for %s in remote '%s' summary cache "
#~ msgstr "Tidak ada entri untuk %s dalam singgahan ringkasan remote '%s' "

#, c-format
#~ msgid "Failed to uninstall %s for rebase to %s: "
#~ msgstr "Gagal menghapus %s untuk rebase ke %s: "

#, c-format
#~ msgid "Failed to uninstall %s for rebase to %s: %s\n"
#~ msgstr "Gagal menghapus %s untuk %s: %s\n"

#, c-format
#~ msgid "Unable to open directory %s"
#~ msgstr "Tidak dapat membuka direktori %s"

#~ msgid "install"
#~ msgstr "pasang"

#~ msgid "update"
#~ msgstr "pemutakhiran"

#~ msgid "install bundle"
#~ msgstr "pasang bundel"

#~ msgid "uninstall"
#~ msgstr "hapus pemasangan"

#~ msgid "(internal error, please report)"
#~ msgstr "(galat internal, silakan laporkan)"

#~ msgid "Warning:"
#~ msgstr "Peringatan:"

#, fuzzy
#~ msgid "runtime"
#~ msgstr "Runtime"

#, fuzzy
#~ msgid "app"
#~ msgstr "Aplikasi"

#~ msgid "%s Failed to %s %s: %s\n"
#~ msgstr "%s Gagal untuk %s %s: %s\n"

#~ msgid "[REF…] - Uninstall an application"
#~ msgstr "[REF…] - Hapus aplikasi"

#~ msgid "Replace it with %s?"
#~ msgstr "Ganti dengan %s?"

#~ msgid "\"flatpak run\" is not intended to be ran with sudo"
#~ msgstr "\"flatpak run\" tidak dimaksudkan untuk dijalankan dengan sudo"

#~ msgid "Related ref '%s' is only partially installed"
#~ msgstr "Ref '%s' terkait hanya dipasang sebagian"

#~ msgid "Ref '%s' is only partially installed"
#~ msgstr "Ref '%s' hanya dipasang sebagian"

#~ msgid "Invalid deployed ref %s: "
#~ msgstr "Ref %s yang dideploy tidak valid: "

#~ msgid "Deployed ref %s kind does not match commit (%s)"
#~ msgstr "Jenis ref %s yang dideploy tidak cocok dengan komit (%s)"

#~ msgid "Deployed ref %s name does not match commit (%s)"
#~ msgstr "Nama ref %s yang dideploy tidak cocok dengan komit (%s)"

#~ msgid "Deployed ref %s arch does not match commit (%s)"
#~ msgstr "Arsitektur ref %s yang dideploy tidak cocok dengan komit (%s)"

#~ msgid "Invalid arch %s"
#~ msgstr "Arsitektur tidak valid %s"

#~ msgid "No such ref (%s, %s) in remote %s"
#~ msgstr "Tidak ada ref (%s, %s) pada remote %s"

#~ msgid "No flatpak cache in remote '%s' summary"
#~ msgstr "Tidak ada singgahan flatpak dalam ringkasan remote '%s'"

#~ msgid "No such ref (%s, %s) in remote %s or elsewhere"
#~ msgstr "Tidak ada ref (%s, %s) pada remote %s atau di tempat lain"

#~ msgid "No remotes found which provide these refs: [%s]"
#~ msgstr "Tidak ditemukan remote yang menyediakan ref ini: [%s]"

#~ msgid "No remotes found which provide the ref (%s, %s)"
#~ msgstr "Tidak ditemukan remote yang menyediakan ref (%s, %s)"

#~ msgid "No summary found"
#~ msgstr "Tidak ditemukan ringkasan"

#~ msgid ""
#~ "GPG verification enabled, but no summary signatures found for remote '%s'"
#~ msgstr ""
#~ "Verifikasi GPG diaktifkan, tetapi tidak ada ringkasan tanda tangan yang "
#~ "ditemukan untuk remote '%s'"

#~ msgid ""
#~ "GPG signatures found for remote '%s', but none are in trusted keyring"
#~ msgstr ""
#~ "Tanda tangan GPG ditemukan untuk remote '%s', tetapi tidak ada dalam ring "
#~ "kunci terpercaya"

#~ msgid "Expected commit metadata to have ref binding information, found none"
#~ msgstr ""
#~ "Metadata komit yang diharapkan untuk memiliki informasi yang mengikat, "
#~ "tidak menemukan satu pun"

#~ msgid ""
#~ "Expected commit metadata to have collection ID binding information, found "
#~ "none"
#~ msgstr ""
#~ "Metadata komit yang diharapkan untuk memiliki informasi pengikatan ID "
#~ "koleksi, tidak menemukan satu pun"

#~ msgid ""
#~ "Commit has collection ID ‘%s’ in collection binding metadata, while the "
#~ "remote it came from has collection ID ‘%s’"
#~ msgstr ""
#~ "Komit memiliki ID koleksi ‘%s’ dalam koleksi yang mengikat metadata, "
#~ "sedangkan remote itu berasal dari yang memiliki ID koleksi ‘%s’"

#~ msgid "Deployed metadata does not match commit"
#~ msgstr "Metadata yang dideploy tidak cocok dengan komit"

#~ msgid "No repo metadata cached for remote '%s'"
#~ msgstr "Tidak ada metadata repo yang disinggahkan untuk remote '%s'"

#~ msgid "No metadata branch for OCI"
#~ msgstr "Tidak ada cabang metadata untuk OCI"

#~ msgid "Invalid group: %d"
#~ msgstr "Grup tidak valid: %d"

#~ msgid "Warning: Can't find %s metadata for dependencies: %s"
#~ msgstr "Peringatan: Tidak dapat menemukan metadata %s untuk dependensi: %s"

#~ msgid "Use OCI labels instead of annotations"
#~ msgstr "Gunakan label OCI alih-alih anotasi"

#~ msgid "Not running as root, may be unable to enter namespace"
#~ msgstr "Tidak berjalan sebagai root, mungkin tidak bisa memasuki namespace"

#~ msgid "Default system installation"
#~ msgstr "Pemasangan sistem bawaan"

#~ msgid "No url specified in flatpakrepo file"
#~ msgstr "Tidak ada url yang ditentukan dalam berkas flatpakrepo"

#~ msgid "Extracting icons for component %s\n"
#~ msgstr "Mengekstrak ikon untuk komponen %s\n"

#~ msgid "%s branch already installed"
#~ msgstr "%s cabang sudah terpasang"

#~ msgid "%s branch %s not installed"
#~ msgstr "%s cabang %s tidak terpasang"

#~ msgid "Show help options"
#~ msgstr "Tampilkan opsi bantuan"

#~ msgid "0"
#~ msgstr "0"

#~ msgid "Print OSTree debug information during command processing"
#~ msgstr "Cetak informasi awakutu OSTree selama pemrosesan perintah"

#~ msgid "Architecture"
#~ msgstr "Arsitektur"

#~ msgid "Location:"
#~ msgstr "Lokasi:"

#~ msgid "Installing for user: %s from %s\n"
#~ msgstr "Memasang untuk pengguna: %s dari %s\n"

#~ msgid "Installing: %s from %s\n"
#~ msgstr "Memasang: %s dari %s\n"

#~ msgid "Updating for user: %s from %s\n"
#~ msgstr "Memperbarui untuk pengguna: %s dari %s\n"

#~ msgid "Updating: %s from %s\n"
#~ msgstr "Memperbarui: %s dari %s\n"

#~ msgid "Installing for user: %s from bundle %s\n"
#~ msgstr "Memasang untuk pengguna: %s dari bundel %s\n"

#~ msgid "Installing: %s from bundle %s\n"
#~ msgstr ""
#~ "Memasang: %s dari bundel %s\n"
#~ "\n"

#~ msgid "Uninstalling for user: %s\n"
#~ msgstr "Hapus pemasangan untuk pengguna: %s\n"

#~ msgid "No updates.\n"
#~ msgstr "Tidak ada pembaruan.\n"

#~ msgid "Now at %s.\n"
#~ msgstr "Sekarang di %s.\n"

#~ msgid "new file access"
#~ msgstr "akses berkas baru"

#~ msgid "file access"
#~ msgstr "akses berkas"

#~ msgid "new dbus access"
#~ msgstr "akses dbus baru"

#~ msgid "dbus access"
#~ msgstr "akses dbus"

#~ msgid "new dbus ownership"
#~ msgstr "kepemilikan dbus baru"

#~ msgid "dbus ownership"
#~ msgstr "kepemilikan dbus"

#~ msgid "new system dbus access"
#~ msgstr "akses sistem dbus baru"

#~ msgid "system dbus access"
#~ msgstr "akses sistem dbus"

#~ msgid "new system dbus ownership"
#~ msgstr "kepemilikan sistem dbus baru"

#~ msgid "system dbus ownership"
#~ msgstr "kepemilikan sistem dbus"

#~ msgid "new tags"
#~ msgstr "tanda baru"

#~ msgid "tags"
#~ msgstr "tanda"

#~ msgid "Installing in %s:\n"
#~ msgstr "Memasang dalam: %s\n"

#~ msgid "Is this ok"
#~ msgstr "Apakah ini ok"

#~ msgid "Authentication is required to install $(ref) from $(origin)"
#~ msgstr "Autentikasi diperlukan untuk memasang $(ref) dari $(origin)"

#~ msgid "Authentication is required to update $(ref) from $(origin)"
#~ msgstr "Autentikasi diperlukan untuk memperbarui $(ref) dari $(origin)"

#~ msgid "Authentication is required to update the remote $(remote)"
#~ msgstr "Autentikasi diperlukan untuk memperbarui remote $(remote)"

#~ msgid "Authentication is required to modify the remote $(remote)"
#~ msgstr "Autentikasi diperlukan untuk memodifikasi remote $(remote)"

#~ msgid "Authentication is required to configure the remote $(remote)"
#~ msgstr "Autentikasi diperlukan untuk mengkonfigurasi remote $(remote)"

#~ msgid "Invalid .flatpakref"
#~ msgstr ".flatpakref tidak valid"

#~ msgid "Unknown command '%s'"
#~ msgstr "Perintah tidak dikenal '%s'"

#~ msgid "Migrating %s to %s\n"
#~ msgstr "Migrasi %s ke %s\n"

#~ msgid "Error during migration: %s\n"
#~ msgstr "Galat saat migrasi: %s\n"

#~ msgid "Runtime Branch"
#~ msgstr "Cabang Runtime"

#~ msgid "Runtime Commit"
#~ msgstr "Komit Runtime"

#~ msgid "Invalid sha256 for extra data uri %s"
#~ msgstr "Sha256 tidak valid untuk data ekstra uri %s"

#~ msgid "Invalid sha256 for extra data"
#~ msgstr "Sha256 tidak valid untuk data ekstra"

#~ msgid "Redirect collection ID: %s\n"
#~ msgstr "Mengalihkan ID koleksi: %s\n"

#~ msgid "Is this ok?"
#~ msgstr "Apakah ini ok?"

#~ msgid "Add OCI registry"
#~ msgstr "Tambah registri OCI"

#~ msgid "Found in remote %s\n"
#~ msgstr ""
#~ "Ditemukan di remote %s\n"
#~ "\n"

#~ msgid "Found in remote %s, do you want to install it?"
#~ msgstr "Ditemukan di remote %s, apakah Anda ingin memasangnya?"

#~ msgid "Found in several remotes:\n"
#~ msgstr "Ditemukan di beberapa remote:\n"

#~ msgid "The required runtime %s was not found in a configured remote.\n"
#~ msgstr ""
#~ "Runtime %s yang dibutuhkan tidak ditemukan di remote yang dikonfigurasi.\n"

#~ msgid "%s already installed, skipping\n"
#~ msgstr "%s sudah terpasang, melewati\n"

#~ msgid "fetch remote info"
#~ msgstr "ambil info remote"

#~ msgid "One or more operations failed"
#~ msgstr "Satu atau beberapa operasi gagal"

#~ msgid ""
#~ "/var/tmp does not suport xattrs which is needed for system-wide "
#~ "installation as a user. FLATPAK_SYSTEM_CACHE_DIR can be used to set an "
#~ "alternative path."
#~ msgstr ""
#~ "/var/tmp tidak mendukung xattrs yang diperlukan untuk pemasangan pada "
#~ "seluruh sistem sebagai pengguna. FLATPAK_SYSTEM_CACHE_DIR dapat digunakan "
#~ "untuk menetapkan path alternatif."

#~ msgid "No ref information available in repository"
#~ msgstr "Tidak ada informasi ref yang tersedia dalam repositori"

#~ msgid "Remote title not set"
#~ msgstr "Judul remote tidak diatur"

#~ msgid "Remote default-branch not set"
#~ msgstr "Cabang bawaaan remote tidak diatur"

#~ msgid "Search specific system-wide installations"
#~ msgstr "Cari pemasangan tertentu di seluruh sistem"

#~ msgid "Failed to unlink temporary file"
#~ msgstr "Gagal menghapus tautan berkas sementara"

#~ msgid "Building %s"
#~ msgstr "Membangun %s"

#~ msgid "Post-Install %s"
#~ msgstr "Setelah Pemasangan %s"

#~ msgid "Cleanup %s"
#~ msgstr "Bersihkan %s"

===== ./po/da.po =====
# Danish translation for flatpak.
# Copyright (C) 2019 flatpak's COPYRIGHT HOLDER
# This file is distributed under the same license as the flatpak package.
# scootergrisen, 2019-2021.
#
# scootergrisen: kan ikke få "remote" oversat godt.
# scootergrisen: det er vel fordi det efter "remote" ofte er udeladt
# scootergrisen: på IRC fik jeg at vide "remote" altid er "remote repo"
# scootergrisen: her er remote fra diverse strenge:
# scootergrisen: remote
# scootergrisen: remote %s
# scootergrisen: remote '%s'
# scootergrisen: remote NAME
# scootergrisen: remote OCI index
# scootergrisen: remote REF
# scootergrisen: remote URL
# scootergrisen: remote \"%s\"
# scootergrisen: remote `%s`
# scootergrisen: remote app or runtime
# scootergrisen: remote apps/runtimes
# scootergrisen: remote bundles
# scootergrisen: remote configurations
# scootergrisen: remote details
# scootergrisen: remote fetch error
# scootergrisen: remote info
# scootergrisen: remote listing
# scootergrisen: remote metadata
# scootergrisen: remote name
# scootergrisen: remote or URI
# scootergrisen: remote refs
# scootergrisen: remote repositories
# scootergrisen: remote repository
# scootergrisen: remote summary
# scootergrisen: remote ‘%s’
#
# scootergrisen: foreslag fra gennemlæsning:
# scootergrisen: Den eksterne ... (ekstern er ikke et navneord) - også i flere efterfølgende
# scootergrisen: repository - arkiv - prøver med depot
# scootergrisen: find ud af om "subset" skal oversættes
#
msgid ""
msgstr ""
"Project-Id-Version: flatpak master\n"
"Report-Msgid-Bugs-To: https://github.com/flatpak/flatpak/issues\n"
"POT-Creation-Date: 2026-05-27 16:39+0200\n"
"PO-Revision-Date: 2021-05-21 18:36+0200\n"
"Last-Translator: scootergrisen\n"
"Language-Team: Danish\n"
"Language: da\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"

#: app/flatpak-builtins-build-bundle.c:59
msgid "Export runtime instead of app"
msgstr "Eksportér runtime i stedet for program"

#: app/flatpak-builtins-build-bundle.c:60
msgid "Arch to bundle for"
msgstr "Arkitektur som bundet er til"

#: app/flatpak-builtins-build-bundle.c:60
#: app/flatpak-builtins-build-export.c:62 app/flatpak-builtins-build-init.c:53
#: app/flatpak-builtins-build-sign.c:42 app/flatpak-builtins-create-usb.c:46
#: app/flatpak-builtins-info.c:55 app/flatpak-builtins-install.c:67
#: app/flatpak-builtins-list.c:50 app/flatpak-builtins-make-current.c:38
#: app/flatpak-builtins-remote-info.c:54 app/flatpak-builtins-remote-ls.c:56
#: app/flatpak-builtins-run.c:158 app/flatpak-builtins-search.c:37
#: app/flatpak-builtins-uninstall.c:54 app/flatpak-builtins-update.c:56
msgid "ARCH"
msgstr "ARKITEKTUR"

#: app/flatpak-builtins-build-bundle.c:61
#, fuzzy
msgid "URL for repo"
msgstr "Url til depot"

#: app/flatpak-builtins-build-bundle.c:61
#: app/flatpak-builtins-build-bundle.c:62
#: app/flatpak-builtins-build-update-repo.c:68
#: app/flatpak-builtins-build-update-repo.c:72
#: app/flatpak-builtins-build-update-repo.c:73
#: app/flatpak-builtins-history.c:69 app/flatpak-builtins-remote-add.c:80
#: app/flatpak-builtins-remote-add.c:81 app/flatpak-builtins-remote-add.c:85
#: app/flatpak-builtins-remote-list.c:53
#: app/flatpak-builtins-remote-modify.c:70
#: app/flatpak-builtins-remote-modify.c:85
#: app/flatpak-builtins-remote-modify.c:86
#: app/flatpak-builtins-remote-modify.c:90
msgid "URL"
msgstr "URL"

#: app/flatpak-builtins-build-bundle.c:62
#, fuzzy
msgid "URL for runtime flatpakrepo file"
msgstr "Url til flatpakrepo-fil for runtime"

#: app/flatpak-builtins-build-bundle.c:63
msgid "Add GPG key from FILE (- for stdin)"
msgstr "Tilføj GPG-nøgle fra FIL (- for stdin)"

#: app/flatpak-builtins-build-bundle.c:63 app/flatpak-builtins-build.c:54
#: app/flatpak-builtins-build-export.c:67
#: app/flatpak-builtins-build-update-repo.c:83
#: app/flatpak-builtins-install.c:81 app/flatpak-builtins-remote-add.c:84
#: app/flatpak-builtins-remote-add.c:86 app/flatpak-builtins-remote-modify.c:89
#: app/flatpak-builtins-remote-modify.c:92
msgid "FILE"
msgstr "FIL"

#: app/flatpak-builtins-build-bundle.c:64
msgid "GPG Key ID to sign the OCI image with"
msgstr "GPG-nøgle-id til at underskrive OCI-aftrykket med"

#: app/flatpak-builtins-build-bundle.c:64
#: app/flatpak-builtins-build-commit-from.c:68
#: app/flatpak-builtins-build-export.c:68
#: app/flatpak-builtins-build-import-bundle.c:49
#: app/flatpak-builtins-build-sign.c:44
#: app/flatpak-builtins-build-update-repo.c:84
msgid "KEY-ID"
msgstr "NØGLE-ID"

#: app/flatpak-builtins-build-bundle.c:65
#: app/flatpak-builtins-build-commit-from.c:69
#: app/flatpak-builtins-build-export.c:71
#: app/flatpak-builtins-build-import-bundle.c:50
#: app/flatpak-builtins-build-sign.c:45
#: app/flatpak-builtins-build-update-repo.c:85
msgid "GPG Homedir to use when looking for keyrings"
msgstr "GPG-hjemmemappe som skal bruges til at lede efter nøgleringe"

#: app/flatpak-builtins-build-bundle.c:65
#: app/flatpak-builtins-build-commit-from.c:69
#: app/flatpak-builtins-build-export.c:71
#: app/flatpak-builtins-build-import-bundle.c:50
#: app/flatpak-builtins-build-sign.c:45
#: app/flatpak-builtins-build-update-repo.c:85
msgid "HOMEDIR"
msgstr "HJEMMEMAPPE"

#: app/flatpak-builtins-build-bundle.c:66
msgid "OSTree commit to create a delta bundle from"
msgstr "OSTree-indsendelse til at oprette et delta-bundt fra"

#: app/flatpak-builtins-build-bundle.c:66 app/flatpak-builtins-remote-info.c:55
#: app/flatpak-builtins-update.c:57
msgid "COMMIT"
msgstr "INDSEND"

#: app/flatpak-builtins-build-bundle.c:67
msgid "Export oci image instead of flatpak bundle"
msgstr "Eksportér oci-aftryk i stedet for flatpak-bundt"

#: app/flatpak-builtins-build-bundle.c:70
msgid "How to compress OCI image layers (default: gzip)"
msgstr ""

#: app/flatpak-builtins-build-bundle.c:634
msgid ""
"LOCATION FILENAME NAME [BRANCH] - Create a single file bundle from a local "
"repository"
msgstr ""
"PLACERING FILNAVN NAVN [GREN] - Opret et enkeltfils bundt fra et lokalt depot"

#: app/flatpak-builtins-build-bundle.c:641
msgid "LOCATION, FILENAME and NAME must be specified"
msgstr "PLACERING, FILNAVN og NAVN skal angives"

#: app/flatpak-builtins-build-bundle.c:644
#: app/flatpak-builtins-build-export.c:844
#: app/flatpak-builtins-build-import-bundle.c:136
#: app/flatpak-builtins-build-init.c:217 app/flatpak-builtins-build-sign.c:76
#: app/flatpak-builtins-document-export.c:112
#: app/flatpak-builtins-document-info.c:75
#: app/flatpak-builtins-document-list.c:191
#: app/flatpak-builtins-document-unexport.c:70
#: app/flatpak-builtins-history.c:482 app/flatpak-builtins-info.c:130
#: app/flatpak-builtins-install.c:181 app/flatpak-builtins-install.c:234
#: app/flatpak-builtins-install.c:298 app/flatpak-builtins-list.c:419
#: app/flatpak-builtins-make-current.c:72 app/flatpak-builtins-override.c:73
#: app/flatpak-builtins-permission-list.c:162
#: app/flatpak-builtins-permission-remove.c:132
#: app/flatpak-builtins-remote-add.c:323
#: app/flatpak-builtins-remote-delete.c:68
#: app/flatpak-builtins-remote-list.c:241 app/flatpak-builtins-remote-ls.c:407
msgid "Too many arguments"
msgstr "For mange argumenter"

#: app/flatpak-builtins-build-bundle.c:659
#: app/flatpak-builtins-build-commit-from.c:338
#: app/flatpak-builtins-build-commit-from.c:351
#: app/flatpak-builtins-build-import-bundle.c:145
#, c-format
msgid "'%s' is not a valid repository"
msgstr "'%s' er ikke et gyldigt depot"

#: app/flatpak-builtins-build-bundle.c:663
#, c-format
msgid "'%s' is not a valid repository: "
msgstr "'%s' er ikke et gyldigt depot: "

#: app/flatpak-builtins-build-bundle.c:674 app/flatpak-builtins-build-sign.c:88
#: common/flatpak-dir.c:14293
#, c-format
msgid "'%s' is not a valid name: %s"
msgstr "'%s' er ikke et gyldigt navn: %s"

#: app/flatpak-builtins-build-bundle.c:677
#: app/flatpak-builtins-build-export.c:865 app/flatpak-builtins-build-sign.c:91
#: common/flatpak-dir.c:14299
#, c-format
msgid "'%s' is not a valid branch name: %s"
msgstr "'%s' er ikke et gyldigt grennavn: %s"

#: app/flatpak-builtins-build-bundle.c:691
#: app/flatpak-builtins-build-import-bundle.c:149
#: app/flatpak-builtins-build-init.c:281
#, c-format
msgid "'%s' is not a valid filename"
msgstr "'%s' er ikke et gyldigt filnavn"

#: app/flatpak-builtins-build-bundle.c:706
msgid "--oci-layer-compress value must be gzip or zstd"
msgstr ""

#: app/flatpak-builtins-build.c:49
msgid "Use Platform runtime rather than Sdk"
msgstr "Brug platform-runtime i stedet for Sdk"

#: app/flatpak-builtins-build.c:50
msgid "Make destination readonly"
msgstr "Gør destinationen skrivebeskyttet"

#: app/flatpak-builtins-build.c:51
msgid "Add bind mount"
msgstr "Tilføj bindingsmontering"

#: app/flatpak-builtins-build.c:51
msgid "DEST=SRC"
msgstr "DESTINATION=KILDE"

#: app/flatpak-builtins-build.c:52
msgid "Start build in this directory"
msgstr "Start bygning i denne mappe"

#: app/flatpak-builtins-build.c:52 app/flatpak-builtins-build.c:53
#: app/flatpak-builtins-build-init.c:64 app/flatpak-builtins-run.c:160
msgid "DIR"
msgstr "MAPPE"

#: app/flatpak-builtins-build.c:53
msgid "Where to look for custom sdk dir (defaults to 'usr')"
msgstr "Hvor der skal ledes efter tilpasset sdk-mappe (standard er 'usr')"

#: app/flatpak-builtins-build.c:54 app/flatpak-builtins-build-export.c:67
msgid "Use alternative file for the metadata"
msgstr "Brug alternativ fil til metadataene"

#: app/flatpak-builtins-build.c:55 app/flatpak-builtins-run.c:177
msgid "Kill processes when the parent process dies"
msgstr "Dræb processerne når forælderprocessen dør"

#: app/flatpak-builtins-build.c:56
msgid "Export application homedir directory to build"
msgstr "Eksportér programmets hjemmemappe-mappe til bygning"

#: app/flatpak-builtins-build.c:57 app/flatpak-builtins-run.c:165
msgid "Log session bus calls"
msgstr "Log buskald for session"

#: app/flatpak-builtins-build.c:58 app/flatpak-builtins-run.c:166
msgid "Log system bus calls"
msgstr "Log buskald for system"

#: app/flatpak-builtins-build.c:262
msgid "DIRECTORY [COMMAND [ARGUMENT…]] - Build in directory"
msgstr "MAPPE [KOMMANDO [ARGUMENT …]] - Byg i mappe"

#: app/flatpak-builtins-build.c:285 app/flatpak-builtins-build-finish.c:656
msgid "DIRECTORY must be specified"
msgstr "MAPPE skal angives"

#: app/flatpak-builtins-build.c:296 app/flatpak-builtins-build-export.c:887
#, c-format
msgid "Build directory %s not initialized, use flatpak build-init"
msgstr "Byggemappen %s er ikke initieret, brug flatpak build-init"

#: app/flatpak-builtins-build.c:315
msgid "metadata invalid, not application or runtime"
msgstr "metadata er ugyldig, ikke program eller runtime"

#: app/flatpak-builtins-build.c:446
#, c-format
msgid "No extension point matching %s in %s"
msgstr "Intet udvidelsespunkt matcher %s i %s"

#: app/flatpak-builtins-build.c:635
#, c-format
msgid "Missing '=' in bind mount option '%s'"
msgstr "Manglende '=' i bindingsmonteringstilvalget '%s'"

#: app/flatpak-builtins-build.c:679 common/flatpak-run.c:3961
#, c-format
msgid "Unable to start app"
msgstr "Kan ikke starte program"

#: app/flatpak-builtins-build-commit-from.c:58
msgid "Source repo dir"
msgstr "Mappe for kildedepot"

#: app/flatpak-builtins-build-commit-from.c:58
msgid "SRC-REPO"
msgstr "KILDEDEPOT"

#: app/flatpak-builtins-build-commit-from.c:59
msgid "Source repo ref"
msgstr "Reference for kildedepot"

#: app/flatpak-builtins-build-commit-from.c:59
msgid "SRC-REF"
msgstr "KILDEREFERENCE"

#: app/flatpak-builtins-build-commit-from.c:64
#: app/flatpak-builtins-build-export.c:60
msgid "One line subject"
msgstr "Emne på én linje"

#: app/flatpak-builtins-build-commit-from.c:64
#: app/flatpak-builtins-build-export.c:60
msgid "SUBJECT"
msgstr "EMNE"

#: app/flatpak-builtins-build-commit-from.c:65
#: app/flatpak-builtins-build-export.c:61
msgid "Full description"
msgstr "Fuld beskrivelse"

#: app/flatpak-builtins-build-commit-from.c:65
#: app/flatpak-builtins-build-export.c:61
msgid "BODY"
msgstr "KROP"

#: app/flatpak-builtins-build-commit-from.c:66
#: app/flatpak-builtins-build-export.c:64
#: app/flatpak-builtins-build-import-bundle.c:51
msgid "Update the appstream branch"
msgstr "Opdater appstream-grenen"

#: app/flatpak-builtins-build-commit-from.c:67
#: app/flatpak-builtins-build-export.c:65
#: app/flatpak-builtins-build-import-bundle.c:52
#: app/flatpak-builtins-build-update-repo.c:87
msgid "Don't update the summary"
msgstr "Opdater ikke opsummeringen"

#: app/flatpak-builtins-build-commit-from.c:68
#: app/flatpak-builtins-build-export.c:68
#: app/flatpak-builtins-build-import-bundle.c:49
#: app/flatpak-builtins-build-sign.c:44
msgid "GPG Key ID to sign the commit with"
msgstr "GPG-nøgle-id til at underskrive indsendelsen med"

#: app/flatpak-builtins-build-commit-from.c:70
#: app/flatpak-builtins-build-export.c:73
msgid "Mark build as end-of-life"
msgstr "Mærk bygning som end-of-life"

#: app/flatpak-builtins-build-commit-from.c:70
#: app/flatpak-builtins-build-export.c:73
msgid "REASON"
msgstr "ÅRSAG"

#: app/flatpak-builtins-build-commit-from.c:71
msgid ""
"Mark refs matching the OLDID prefix as end-of-life, to be replaced with the "
"given NEWID"
msgstr ""
"Mærk referencer som matcher GAMLEID-præfikset som end-of-life, så den "
"erstattes med det angivne NYEID"

#: app/flatpak-builtins-build-commit-from.c:71
msgid "OLDID=NEWID"
msgstr "GAMLEID=NYEID"

#: app/flatpak-builtins-build-commit-from.c:72
#: app/flatpak-builtins-build-export.c:75
msgid "Set type of token needed to install this commit"
msgstr "Indstil typen af token som bruges for at installere indsendelsen"

#: app/flatpak-builtins-build-commit-from.c:72
#: app/flatpak-builtins-build-export.c:75
msgid "VAL"
msgstr "VÆR"

#: app/flatpak-builtins-build-commit-from.c:73
msgid "Override the timestamp of the commit (NOW for current time)"
msgstr ""
"Tilsidesæt tidsstemplet på indsendelsen (NOW for at bruge det nuværende "
"tidspunkt)"

#: app/flatpak-builtins-build-commit-from.c:73
#: app/flatpak-builtins-build-export.c:76
msgid "TIMESTAMP"
msgstr "TIDSSTEMPEL"

#: app/flatpak-builtins-build-commit-from.c:75
#: app/flatpak-builtins-build-export.c:80
#: app/flatpak-builtins-build-import-bundle.c:53
#: app/flatpak-builtins-build-update-repo.c:97
msgid "Don't generate a summary index"
msgstr "Generer ikke et opsummeringsindeks"

#: app/flatpak-builtins-build-commit-from.c:278
msgid "DST-REPO [DST-REF…] - Make a new commit from existing commits"
msgstr ""
"DESTINATIONSDEPOT [DESTINATIONSREFERENCE …] - Foretag en ny indsendelse fra "
"eksisterende indsendelser"

#: app/flatpak-builtins-build-commit-from.c:285
msgid "DST-REPO must be specified"
msgstr "DESTINATIONSDEPOT skal angives"

#: app/flatpak-builtins-build-commit-from.c:293
msgid ""
"If --src-repo is not specified, exactly one destination ref must be specified"
msgstr ""
"Hvis --src-repo ikke angives, så skal præcist én destinationsreference "
"angives"

#: app/flatpak-builtins-build-commit-from.c:296
msgid ""
"If --src-ref is specified, exactly one destination ref must be specified"
msgstr ""
"Hvis --src-ref angives, så skal præcist én destinationsreference angives"

#: app/flatpak-builtins-build-commit-from.c:299
msgid "Either --src-repo or --src-ref must be specified"
msgstr "Enten --src-repo eller --src-ref skal angives"

#: app/flatpak-builtins-build-commit-from.c:315
msgid "Invalid argument format of use  --end-of-life-rebase=OLDID=NEWID"
msgstr "Ugyldigt argumentformat brugt i --end-of-life-rebase=GAMLEID=NYEID"

#: app/flatpak-builtins-build-commit-from.c:321
#: app/flatpak-builtins-build-commit-from.c:324
#, c-format
msgid "Invalid name %s in --end-of-life-rebase"
msgstr "Ugyldigt navn %s i --end-of-life-rebase"

#: app/flatpak-builtins-build-commit-from.c:333
#: app/flatpak-builtins-build-export.c:1092
#, c-format
msgid "Could not parse '%s'"
msgstr "Kunne ikke fortolke '%s'"

#: app/flatpak-builtins-build-commit-from.c:498
msgid "Can't commit from partial source commit"
msgstr "Kan ikke indsende fra delvis kildeindsendelse"

#: app/flatpak-builtins-build-commit-from.c:503
#, c-format
msgid "%s: no change\n"
msgstr "%s: ingen ændring\n"

#: app/flatpak-builtins-build-export.c:62
msgid "Architecture to export for (must be host compatible)"
msgstr "Arkitektur som skal eksporteres (skal være kompatibel med værten)"

#: app/flatpak-builtins-build-export.c:63
msgid "Commit runtime (/usr), not /app"
msgstr "Indsend-runtime (/usr), ikke /app"

#: app/flatpak-builtins-build-export.c:66
msgid "Use alternative directory for the files"
msgstr "Brug alternativ mappe til filerne"

#: app/flatpak-builtins-build-export.c:66
msgid "SUBDIR"
msgstr "UNDERMAPPE"

#: app/flatpak-builtins-build-export.c:69
msgid "Files to exclude"
msgstr "Filer som skal ekskluderes"

#: app/flatpak-builtins-build-export.c:69
#: app/flatpak-builtins-build-export.c:70
#: app/flatpak-builtins-build-update-repo.c:90
msgid "PATTERN"
msgstr "MØNSTER"

#: app/flatpak-builtins-build-export.c:70
msgid "Excluded files to include"
msgstr "Ekskluderede filer som skal medtages"

#: app/flatpak-builtins-build-export.c:74
msgid "Mark build as end-of-life, to be replaced with the given ID"
msgstr "Mærk bygning som end-of-life, så den erstattes med det angivne id"

#: app/flatpak-builtins-build-export.c:74
#: app/flatpak-builtins-document-list.c:49 app/flatpak-cli-transaction.c:1427
msgid "ID"
msgstr "ID"

#: app/flatpak-builtins-build-export.c:76
msgid "Override the timestamp of the commit"
msgstr "Tilsidesæt tidsstemplet på indsendelsen"

#: app/flatpak-builtins-build-export.c:77
#: app/flatpak-builtins-build-update-repo.c:75
#: app/flatpak-builtins-remote-add.c:83 app/flatpak-builtins-remote-list.c:54
#: app/flatpak-builtins-remote-modify.c:88
msgid "Collection ID"
msgstr "Samlings-id"

#: app/flatpak-builtins-build-export.c:472
#, c-format
msgid "WARNING: Error running desktop-file-validate: %s\n"
msgstr "ADVARSEL: Fejl ved kørsel af desktop-file-validate: %s\n"

#: app/flatpak-builtins-build-export.c:480
#, c-format
msgid "WARNING: Error reading from desktop-file-validate: %s\n"
msgstr "ADVARSEL: Fejl ved læsning fra desktop-file-validate: %s\n"

#: app/flatpak-builtins-build-export.c:486
#, c-format
msgid "WARNING: Failed to validate desktop file %s: %s\n"
msgstr "ADVARSEL: Kunne ikke validere skrivebordsfilen %s: %s\n"

#: app/flatpak-builtins-build-export.c:513
#, c-format
msgid "WARNING: Can't find Exec key in %s: %s\n"
msgstr "ADVARSEL: Kan ikke finde Exec-nøgle i %s: %s\n"

#: app/flatpak-builtins-build-export.c:521
#: app/flatpak-builtins-build-export.c:614
#, c-format
msgid "WARNING: Binary not found for Exec line in %s: %s\n"
msgstr "ADVARSEL: Binær ikke fundet for Exec-linje i %s: %s\n"

#: app/flatpak-builtins-build-export.c:529
#, c-format
msgid "WARNING: Icon not matching app id in %s: %s\n"
msgstr "ADVARSEL: Ikon matcher ikke programid i %s: %s\n"

#: app/flatpak-builtins-build-export.c:552
#, c-format
msgid "WARNING: Icon referenced in desktop file but not exported: %s\n"
msgstr ""
"ADVARSEL: Ikon refereres i skrivebordsfilen, men blev ikke eksporteret: %s\n"

#: app/flatpak-builtins-build-export.c:719
#, c-format
msgid "Invalid uri type %s, only http/https supported"
msgstr "Ugyldig uri-type %s, der understøttes kun http/https"

#: app/flatpak-builtins-build-export.c:737
#, c-format
msgid "Unable to find basename in %s, specify a name explicitly"
msgstr "Kan ikke finde grundnavn i %s, angiv venligst et navn eksplicit"

#: app/flatpak-builtins-build-export.c:746
#, c-format
msgid "No slashes allowed in extra data name"
msgstr "Skråstreger er ikke tilladt i navn til ekstra-data"

#: app/flatpak-builtins-build-export.c:758
#, c-format
msgid "Invalid format for sha256 checksum: '%s'"
msgstr "Ugyldigt format for sha256-checksum: '%s'"

#: app/flatpak-builtins-build-export.c:768
#, c-format
msgid "Extra data sizes of zero not supported"
msgstr "Der understøttes ikke nulstørrelse for ekstra-data"

#: app/flatpak-builtins-build-export.c:830
msgid ""
"LOCATION DIRECTORY [BRANCH] - Create a repository from a build directory"
msgstr "PLACERING MAPPE [GREN] - Opret et depot fra en byggemappe"

#: app/flatpak-builtins-build-export.c:838
msgid "LOCATION and DIRECTORY must be specified"
msgstr "PLACERING og MAPPE skal angives"

#: app/flatpak-builtins-build-export.c:859
#: app/flatpak-builtins-remote-add.c:327
#, c-format
msgid "‘%s’ is not a valid collection ID: %s"
msgstr "‘%s’ er ikke et gyldigt samlings-id: %s"

#: app/flatpak-builtins-build-export.c:904
#: app/flatpak-builtins-build-finish.c:684
msgid "No name specified in the metadata"
msgstr "Der er ikke angivet noget navn i metadataene"

#: app/flatpak-builtins-build-export.c:1166
#, c-format
msgid "Commit: %s\n"
msgstr "Indsend: %s\n"

#: app/flatpak-builtins-build-export.c:1167
#, c-format
msgid "Metadata Total: %u\n"
msgstr "Metadata i alt: %u\n"

#: app/flatpak-builtins-build-export.c:1168
#, c-format
msgid "Metadata Written: %u\n"
msgstr "Metadata skrevet: %u\n"

#: app/flatpak-builtins-build-export.c:1169
#, c-format
msgid "Content Total: %u\n"
msgstr "Indhold i alt: %u\n"

#: app/flatpak-builtins-build-export.c:1170
#, c-format
msgid "Content Written: %u\n"
msgstr "Indhold skrevet: %u\n"

#: app/flatpak-builtins-build-export.c:1171
#, c-format
msgid "Content Bytes Written:"
msgstr "Indhold skrevet i bytes:"

#: app/flatpak-builtins-build-finish.c:52
msgid "Command to set"
msgstr "Kommando som skal indstilles"

#: app/flatpak-builtins-build-finish.c:52 app/flatpak-builtins-run.c:159
#: app/flatpak-main.c:209
msgid "COMMAND"
msgstr "KOMMANDO"

#: app/flatpak-builtins-build-finish.c:53
msgid "Flatpak version to require"
msgstr "Flatpak-version som kræves"

#: app/flatpak-builtins-build-finish.c:53
msgid "MAJOR.MINOR.MICRO"
msgstr "STOR.LILLE.MIKRO"

#: app/flatpak-builtins-build-finish.c:54
msgid "Don't process exports"
msgstr "Behandl ikke eksporter"

#: app/flatpak-builtins-build-finish.c:55
msgid "Extra data info"
msgstr "Information for ekstra-data"

#: app/flatpak-builtins-build-finish.c:56 app/flatpak-builtins-build-init.c:63
msgid "Add extension point info"
msgstr "Tilføj information om udvidelsespunkt"

#: app/flatpak-builtins-build-finish.c:56 app/flatpak-builtins-build-init.c:63
msgid "NAME=VARIABLE[=VALUE]"
msgstr "NAVN=VARIABEL[=VÆRDI]"

#: app/flatpak-builtins-build-finish.c:57
msgid "Remove extension point info"
msgstr "Fjern information om udvidelsespunkt"

#: app/flatpak-builtins-build-finish.c:57
#: app/flatpak-builtins-build-update-repo.c:79 app/flatpak-builtins-info.c:58
#: app/flatpak-builtins-remote-add.c:88 app/flatpak-builtins-remote-modify.c:94
#: app/flatpak-main.c:182
msgid "NAME"
msgstr "NAVN"

#: app/flatpak-builtins-build-finish.c:58
msgid "Set extension priority (only for extensions)"
msgstr "Indstil prioritet for udvidelse (kun til udvidelser)"

#: app/flatpak-builtins-build-finish.c:58
msgid "VALUE"
msgstr "VÆRDI"

#: app/flatpak-builtins-build-finish.c:59
msgid "Change the sdk used for the app"
msgstr "Skift sdk'et som bruges af programmet"

#: app/flatpak-builtins-build-finish.c:59
msgid "SDK"
msgstr "SDK"

#: app/flatpak-builtins-build-finish.c:60
msgid "Change the runtime used for the app"
msgstr "Skift runtimen som bruges af programmet"

#: app/flatpak-builtins-build-finish.c:60 app/flatpak-builtins-build-init.c:54
#: app/flatpak-builtins-list.c:53 app/flatpak-builtins-remote-ls.c:58
#: app/flatpak-builtins-run.c:163
msgid "RUNTIME"
msgstr "RUNTIME"

#: app/flatpak-builtins-build-finish.c:61
msgid "Set generic metadata option"
msgstr "Indstil tilvalg for generisk metadata"

#: app/flatpak-builtins-build-finish.c:61
msgid "GROUP=KEY[=VALUE]"
msgstr "GRUPPE=NØGLE[=VÆRDI]"

#: app/flatpak-builtins-build-finish.c:62
msgid "Don't inherit permissions from runtime"
msgstr "Nedarv ikke tilladelser fra runtime"

#: app/flatpak-builtins-build-finish.c:155
#, c-format
msgid "Not exporting %s, wrong extension\n"
msgstr "Eksporterer ikke %s, forkert udvidelse\n"

#: app/flatpak-builtins-build-finish.c:163
#, c-format
msgid "Not exporting %s, non-allowed export filename\n"
msgstr "Eksporterer ikke %s, eksportfilnavnet er ikke tilladt\n"

#: app/flatpak-builtins-build-finish.c:167
#, c-format
msgid "Exporting %s\n"
msgstr "Eksporterer %s\n"

#: app/flatpak-builtins-build-finish.c:440
#, c-format
msgid "More than one executable found\n"
msgstr "Fandt mere end en eksekverbar\n"

#: app/flatpak-builtins-build-finish.c:451
#, c-format
msgid "Using %s as command\n"
msgstr "Bruger %s som kommando\n"

#: app/flatpak-builtins-build-finish.c:456
#, c-format
msgid "No executable found\n"
msgstr "Fandt ingen eksekverbar\n"

#: app/flatpak-builtins-build-finish.c:511
#, c-format
msgid "Invalid --require-version argument: %s"
msgstr "Ugyldigt --require-version-argument: %s"

#: app/flatpak-builtins-build-finish.c:543
#, c-format
msgid "Too few elements in --extra-data argument %s"
msgstr "For få elementer i --extra-data-argumentet %s"

#: app/flatpak-builtins-build-finish.c:575
#, c-format
msgid ""
"Too few elements in --metadata argument %s, format should be "
"GROUP=KEY[=VALUE]]"
msgstr ""
"For få elementer i --metadata-argumentet %s, formatet skal være "
"GRUPPE=NØGLE[=VÆRDI]]"

#: app/flatpak-builtins-build-finish.c:597
#: app/flatpak-builtins-build-init.c:458
#, c-format
msgid ""
"Too few elements in --extension argument %s, format should be "
"NAME=VAR[=VALUE]"
msgstr ""
"For få elementer i --extension-argumentet %s, formatet skal være "
"NAVN=VARIABEL[=VÆRDI]"

#: app/flatpak-builtins-build-finish.c:603
#: app/flatpak-builtins-build-init.c:461
#, c-format
msgid "Invalid extension name %s"
msgstr "Ugyldigt udvidelsesnavn %s"

#: app/flatpak-builtins-build-finish.c:646
msgid "DIRECTORY - Finalize a build directory"
msgstr "MAPPE - Færdiggør en byggemappe"

#: app/flatpak-builtins-build-finish.c:668
#, c-format
msgid "Build directory %s not initialized"
msgstr "Byggemappen %s er ikke initieret"

#: app/flatpak-builtins-build-finish.c:689
#, c-format
msgid "Build directory %s already finalized"
msgstr "Byggemappen %s er allerede færdiggjort"

#: app/flatpak-builtins-build-finish.c:702
#, c-format
msgid "Please review the exported files and the metadata\n"
msgstr "Gennemgå venligst de eksporterede filer og metadataene\n"

#: app/flatpak-builtins-build-import-bundle.c:47
msgid "Override the ref used for the imported bundle"
msgstr "Tilsidesæt referencen som bruges til det importerede bundt"

#: app/flatpak-builtins-build-import-bundle.c:47
msgid "REF"
msgstr "REFERENCE"

#: app/flatpak-builtins-build-import-bundle.c:48
msgid "Import oci image instead of flatpak bundle"
msgstr "Importér oci-aftryk i stedet for flatpak-bundt"

#: app/flatpak-builtins-build-import-bundle.c:77
#: app/flatpak-builtins-build-import-bundle.c:105
#, c-format
msgid "Importing %s (%s)\n"
msgstr "Importerer %s (%s)\n"

#: app/flatpak-builtins-build-import-bundle.c:126
msgid "LOCATION FILENAME - Import a file bundle into a local repository"
msgstr "PLACERING FILNAVN - Importér et filbundt ind i et lokalt depot"

#: app/flatpak-builtins-build-import-bundle.c:133
msgid "LOCATION and FILENAME must be specified"
msgstr "PLACERING og FILNAVN skal angives"

#: app/flatpak-builtins-build-init.c:53 app/flatpak-builtins-info.c:55
#: app/flatpak-builtins-run.c:158
msgid "Arch to use"
msgstr "Arkitektur som skal bruges"

#: app/flatpak-builtins-build-init.c:54
msgid "Initialize var from named runtime"
msgstr "Initier variabel fra navngivet runtime"

#: app/flatpak-builtins-build-init.c:55
msgid "Initialize apps from named app"
msgstr "Initier programmer fra navngivet program"

#: app/flatpak-builtins-build-init.c:55
msgid "APP"
msgstr "PROGRAM"

#: app/flatpak-builtins-build-init.c:56
msgid "Specify version for --base"
msgstr "Angiv version for --base"

#: app/flatpak-builtins-build-init.c:56 app/flatpak-builtins-run.c:164
msgid "VERSION"
msgstr "VERSION"

#: app/flatpak-builtins-build-init.c:57
msgid "Include this base extension"
msgstr "Medtag denne grundudvidelse"

#: app/flatpak-builtins-build-init.c:57 app/flatpak-builtins-build-init.c:62
msgid "EXTENSION"
msgstr "UDVIDELSE"

#: app/flatpak-builtins-build-init.c:58
msgid "Extension tag to use if building extension"
msgstr "Udvidelsesmærkat som skal bruges hvis der bygges udvidelse"

#: app/flatpak-builtins-build-init.c:58
msgid "EXTENSION_TAG"
msgstr "UDVIDELSESMÆRKAT"

#: app/flatpak-builtins-build-init.c:59
msgid "Initialize /usr with a writable copy of the sdk"
msgstr "Initier /usr med en skrivbar kopi af sdk'et"

#: app/flatpak-builtins-build-init.c:60
msgid "Specify the build type (app, runtime, extension)"
msgstr "Angiv byggetypen (program, runtime, udvidelse)"

#: app/flatpak-builtins-build-init.c:60
msgid "TYPE"
msgstr "TYPE"

#: app/flatpak-builtins-build-init.c:61
msgid "Add a tag"
msgstr "Tilføj et mærkat"

#: app/flatpak-builtins-build-init.c:61
msgid "TAG"
msgstr "MÆRKAT"

#: app/flatpak-builtins-build-init.c:62
msgid "Include this sdk extension in /usr"
msgstr "Medtag denne sdk-udvidelse i /usr"

#: app/flatpak-builtins-build-init.c:64
msgid "Where to store sdk (defaults to 'usr')"
msgstr "Hvor sdk skal gemmes (standard er 'usr')"

#: app/flatpak-builtins-build-init.c:65
msgid "Re-initialize the sdk/var"
msgstr "Geninitier sdk'et/var'en"

#: app/flatpak-builtins-build-init.c:118
#, fuzzy, c-format
msgid "Requested extension %s/%s/%s is only partially installed"
msgstr "Anmodet udvidelse %s er kun installeret delvist"

#: app/flatpak-builtins-build-init.c:147
#, fuzzy, c-format
msgid "Requested extension %s/%s/%s not installed"
msgstr "Anmodet udvidelse %s er ikke installeret"

#: app/flatpak-builtins-build-init.c:207
msgid ""
"DIRECTORY APPNAME SDK RUNTIME [BRANCH] - Initialize a directory for building"
msgstr "MAPPE PROGRAMNAVN SDK RUNTIME [GREN] - Initier en mappe til bygning"

#: app/flatpak-builtins-build-init.c:214
msgid "RUNTIME must be specified"
msgstr "RUNTIME skal angives"

#: app/flatpak-builtins-build-init.c:235
#, c-format
msgid "'%s' is not a valid build type name, use app, runtime or extension"
msgstr ""
"'%s' er ikke et gyldigt navn for byggetype, brug program, runtime eller "
"udvidelse"

#: app/flatpak-builtins-build-init.c:241 app/flatpak-builtins-override.c:79
#, c-format
msgid "'%s' is not a valid application name: %s"
msgstr "'%s' er ikke et gyldigt programnavn: %s"

#: app/flatpak-builtins-build-init.c:295
#, c-format
msgid "Build directory %s already initialized"
msgstr "Byggemappen %s er allerede initieret"

#: app/flatpak-builtins-build-sign.c:42 app/flatpak-builtins-install.c:67
#: app/flatpak-builtins-remote-info.c:54
msgid "Arch to install for"
msgstr "Arkitektur som skal installeres for"

#: app/flatpak-builtins-build-sign.c:43 app/flatpak-builtins-create-usb.c:48
#: app/flatpak-builtins-install.c:74 app/flatpak-builtins-remote-info.c:56
#: app/flatpak-builtins-uninstall.c:58 app/flatpak-builtins-update.c:64
msgid "Look for runtime with the specified name"
msgstr "Led efter runtime med det angivne navn"

#: app/flatpak-builtins-build-sign.c:66
msgid "LOCATION [ID [BRANCH]] - Sign an application or runtime"
msgstr "PLACERING [ID [GREN]] - Underskriv et program eller runtime"

#: app/flatpak-builtins-build-sign.c:73
#: app/flatpak-builtins-build-update-repo.c:499
#: app/flatpak-builtins-remote-add.c:320 app/flatpak-builtins-repo.c:739
msgid "LOCATION must be specified"
msgstr "PLACERING skal angives"

#: app/flatpak-builtins-build-sign.c:94
msgid "No gpg key ids specified"
msgstr "Ingen gpg-nøgle-id'er angivet"

#: app/flatpak-builtins-build-update-repo.c:68
msgid "Redirect this repo to a new URL"
msgstr "Omdiriger depotet til en ny URL"

#: app/flatpak-builtins-build-update-repo.c:69
msgid "A nice name to use for this repository"
msgstr "Et godt navn som skal bruges til depotet"

#: app/flatpak-builtins-build-update-repo.c:69
#: app/flatpak-builtins-remote-add.c:77 app/flatpak-builtins-remote-modify.c:82
msgid "TITLE"
msgstr "TITEL"

#: app/flatpak-builtins-build-update-repo.c:70
msgid "A one-line comment for this repository"
msgstr "En kommentar på én linje til depotet"

#: app/flatpak-builtins-build-update-repo.c:70
#: app/flatpak-builtins-remote-add.c:78 app/flatpak-builtins-remote-modify.c:83
msgid "COMMENT"
msgstr "KOMMENTAR"

#: app/flatpak-builtins-build-update-repo.c:71
msgid "A full-paragraph description for this repository"
msgstr "En beskrivelse på et helt afsnit til depotet"

#: app/flatpak-builtins-build-update-repo.c:71
#: app/flatpak-builtins-remote-add.c:79 app/flatpak-builtins-remote-modify.c:84
msgid "DESCRIPTION"
msgstr "BESKRIVELSE"

#: app/flatpak-builtins-build-update-repo.c:72
msgid "URL for a website for this repository"
msgstr "URL til et websted til depotet"

#: app/flatpak-builtins-build-update-repo.c:73
msgid "URL for an icon for this repository"
msgstr "URL til et ikon til depotet"

#: app/flatpak-builtins-build-update-repo.c:74
msgid "Default branch to use for this repository"
msgstr "Standardgren som skal bruges til depotet"

#: app/flatpak-builtins-build-update-repo.c:74
#: app/flatpak-builtins-remote-add.c:82 app/flatpak-builtins-remote-modify.c:87
#: app/flatpak-builtins-repo.c:713 app/flatpak-builtins-repo.c:714
#: app/flatpak-builtins-run.c:161
msgid "BRANCH"
msgstr "GREN"

#: app/flatpak-builtins-build-update-repo.c:75
#: app/flatpak-builtins-remote-add.c:83 app/flatpak-builtins-remote-modify.c:88
msgid "COLLECTION-ID"
msgstr "SAMLINGS-ID"

#. Translators: A sideload is when you install from a local USB drive rather than the Internet.
#: app/flatpak-builtins-build-update-repo.c:77
msgid ""
"Permanently deploy collection ID to client remote configurations, only for "
"sideload support"
msgstr ""
"Permanent udsendelse af samlings-id til klientens konfigurationer af "
"eksterne, kun til understøttelse af sideindlæsning"

#: app/flatpak-builtins-build-update-repo.c:78
msgid "Permanently deploy collection ID to client remote configurations"
msgstr ""
"Permanent udsendelse af samlings-id til klientens konfigurationer af eksterne"

#: app/flatpak-builtins-build-update-repo.c:79
msgid "Name of authenticator for this repository"
msgstr "Navn på godkender til depotet"

#: app/flatpak-builtins-build-update-repo.c:80
msgid "Autoinstall authenticator for this repository"
msgstr "Automatisk installation af godkender til depotet"

#: app/flatpak-builtins-build-update-repo.c:81
msgid "Don't autoinstall authenticator for this repository"
msgstr "Brug ikke automatisk installation af godkender til depotet"

#: app/flatpak-builtins-build-update-repo.c:82
#: app/flatpak-builtins-remote-add.c:89
msgid "Authenticator option"
msgstr "Tilvalg for godkender"

#: app/flatpak-builtins-build-update-repo.c:82
#: app/flatpak-builtins-remote-add.c:89 app/flatpak-builtins-remote-modify.c:95
msgid "KEY=VALUE"
msgstr "NØGLE=VÆRDI"

#: app/flatpak-builtins-build-update-repo.c:83
msgid "Import new default GPG public key from FILE"
msgstr "Importér ny standard GPG offentlig nøgle fra FIL"

#: app/flatpak-builtins-build-update-repo.c:84
msgid "GPG Key ID to sign the summary with"
msgstr "GPG-nøgle-id som opsummeringen skal underskrives med"

#: app/flatpak-builtins-build-update-repo.c:86
msgid "Generate delta files"
msgstr "Generer deltafiler"

#: app/flatpak-builtins-build-update-repo.c:88
msgid "Don't update the appstream branch"
msgstr "Opdater ikke appstream-grenen"

#: app/flatpak-builtins-build-update-repo.c:89
msgid "Max parallel jobs when creating deltas (default: NUMCPUs)"
msgstr "Maks. parallelle jobs når der oprettes deltaer (standard: ANTALCPU'er)"

#: app/flatpak-builtins-build-update-repo.c:89
msgid "NUM-JOBS"
msgstr "ANTAL-JOBS"

#: app/flatpak-builtins-build-update-repo.c:90
msgid "Don't create deltas matching refs"
msgstr "Opret ikke deltaer som matcher referencer"

#: app/flatpak-builtins-build-update-repo.c:91
msgid "Prune unused objects"
msgstr "Beskær ubrugte objekter"

#: app/flatpak-builtins-build-update-repo.c:92
msgid "Prune but don't actually remove anything"
msgstr "Beskær, men fjern ikke noget"

#: app/flatpak-builtins-build-update-repo.c:93
msgid "Only traverse DEPTH parents for each commit (default: -1=infinite)"
msgstr ""
"Gennemgå kun DYBDE forældre for hver indsendelse (standard: -1=uendeligt)"

#: app/flatpak-builtins-build-update-repo.c:93
msgid "DEPTH"
msgstr "DYBDE"

#: app/flatpak-builtins-build-update-repo.c:223
#, c-format
msgid "Generating delta: %s (%.10s)\n"
msgstr "Genererer delta: %s (%.10s)\n"

#: app/flatpak-builtins-build-update-repo.c:225
#, c-format
msgid "Generating delta: %s (%.10s-%.10s)\n"
msgstr "Genererer delta: %s (%.10s-%.10s)\n"

#: app/flatpak-builtins-build-update-repo.c:233
#, c-format
msgid "Failed to generate delta %s (%.10s): "
msgstr "Kunne ikke generere deltaen %s (%.10s): "

#: app/flatpak-builtins-build-update-repo.c:236
#, c-format
msgid "Failed to generate delta %s (%.10s-%.10s): "
msgstr "Kunne ikke generere deltaen %s (%.10s-%.10s): "

#: app/flatpak-builtins-build-update-repo.c:492
msgid "LOCATION - Update repository metadata"
msgstr "PLACERING - Opdater depot-metadata"

#: app/flatpak-builtins-build-update-repo.c:609
#, c-format
msgid "Updating appstream branch\n"
msgstr "Opdaterer appstream-gren\n"

#: app/flatpak-builtins-build-update-repo.c:638
#, c-format
msgid "Updating summary\n"
msgstr "Opdaterer opsummering\n"

#: app/flatpak-builtins-build-update-repo.c:664
#, c-format
msgid "Total objects: %u\n"
msgstr "Samlet objekter: %u\n"

#: app/flatpak-builtins-build-update-repo.c:666
#, c-format
msgid "No unreachable objects\n"
msgstr "Ingen objekter som ikke kan nås\n"

#: app/flatpak-builtins-build-update-repo.c:668
#, c-format
msgid "Deleted %u objects, %s freed\n"
msgstr "Slettede %u objekter, %s frigivet\n"

#: app/flatpak-builtins-config.c:41
msgid "List configuration keys and values"
msgstr "Vis konfigurerede nøgler og værdier"

#: app/flatpak-builtins-config.c:42
msgid "Get configuration for KEY"
msgstr "Hent konfiguration for NØGLE"

#: app/flatpak-builtins-config.c:43
msgid "Set configuration for KEY to VALUE"
msgstr "Indstil konfiguration for NØGLE til VÆRDI"

#: app/flatpak-builtins-config.c:44
msgid "Unset configuration for KEY"
msgstr "Fjern indstilling af konfiguration for NØGLE"

#: app/flatpak-builtins-config.c:149
#, c-format
msgid "'%s' does not look like a language/locale code"
msgstr "'%s' ser ikke ud til at være en sprog-/lokalitetskode"

#: app/flatpak-builtins-config.c:172
#, c-format
msgid "'%s' does not look like a language code"
msgstr "'%s' ser ikke ud til at være en sprogkode"

#: app/flatpak-builtins-config.c:190
#, fuzzy, c-format
msgid "'%s' is not a valid value (use 'true' or 'false')"
msgstr "'%s' er ikke et gyldigt depot: "

#: app/flatpak-builtins-config.c:262
#, c-format
msgid "Unknown configure key '%s'"
msgstr "Ukendt konfigurationsnøgle '%s'"

#: app/flatpak-builtins-config.c:284
msgid "Too many arguments for --list"
msgstr "For mange argumenter til --list"

#: app/flatpak-builtins-config.c:314 app/flatpak-builtins-config.c:362
msgid "You must specify KEY"
msgstr "Du skal angive NØGLE"

#: app/flatpak-builtins-config.c:316
msgid "Too many arguments for --get"
msgstr "For mange argumenter til --get"

#: app/flatpak-builtins-config.c:338
msgid "You must specify KEY and VALUE"
msgstr "Du skal angive NØGLE og VÆRDI"

#: app/flatpak-builtins-config.c:340
msgid "Too many arguments for --set"
msgstr "For mange argumenter til --set"

#: app/flatpak-builtins-config.c:364
msgid "Too many arguments for --unset"
msgstr "For mange argumenter til --unset"

#: app/flatpak-builtins-config.c:383
msgid "[KEY [VALUE]] - Manage configuration"
msgstr "[NØGLE [VÆRDI]] - Håndter konfiguration"

#: app/flatpak-builtins-config.c:394
msgid "Can only use one of --list, --get, --set or --unset"
msgstr "Kan kun bruge én af --list, --get, --set eller --unset"

#: app/flatpak-builtins-config.c:408
msgid "Must specify one of --list, --get, --set or --unset"
msgstr "Skal angive én af --list, --get, --set eller --unset"

#: app/flatpak-builtins-create-usb.c:45 app/flatpak-builtins-install.c:75
#: app/flatpak-builtins-remote-info.c:57 app/flatpak-builtins-uninstall.c:59
#: app/flatpak-builtins-update.c:65
msgid "Look for app with the specified name"
msgstr "Led efter program med det angivne navn"

#: app/flatpak-builtins-create-usb.c:46
msgid "Arch to copy"
msgstr "Arkitektur som skal kopieres"

#: app/flatpak-builtins-create-usb.c:47
msgid "DEST"
msgstr "DESTINATION"

#: app/flatpak-builtins-create-usb.c:49
msgid "Allow partial commits in the created repo"
msgstr "Tillad delvise indsendelser i det oprettede depot"

#: app/flatpak-builtins-create-usb.c:125 app/flatpak-builtins-create-usb.c:165
#, c-format
msgid ""
"Warning: Related ref ‘%s’ is partially installed. Use --allow-partial to "
"suppress this message.\n"
msgstr ""
"Advarsel: Relateret reference ‘%s’ er delvist installeret. Brug --allow-"
"partial for at undertrykke meddelelsen.\n"

#: app/flatpak-builtins-create-usb.c:158
#, c-format
msgid "Warning: Omitting related ref ‘%s’ because it is not installed.\n"
msgstr ""
"Advarsel: Udelader den relateret reference ‘%s’ da den ikke er installeret.\n"

#: app/flatpak-builtins-create-usb.c:175
#, c-format
msgid ""
"Warning: Omitting related ref ‘%s’ because its remote ‘%s’ does not have a "
"collection ID set.\n"
msgstr ""
"Advarsel: Udelader den relateret reference ‘%s’ da dens eksterne ‘%s’ ikke "
"har indstillet et samlings-id.\n"

#: app/flatpak-builtins-create-usb.c:187
#, c-format
msgid "Warning: Omitting related ref ‘%s’ because it's extra-data.\n"
msgstr "Advarsel: Udelader relaterede reference ‘%s’ da den er extra-data.\n"

#: app/flatpak-builtins-create-usb.c:262 app/flatpak-builtins-create-usb.c:637
#, c-format
msgid ""
"Remote ‘%s’ does not have a collection ID set, which is required for P2P "
"distribution of ‘%s’."
msgstr ""
"Eksternen ‘%s’ har ikke indstillet et samlings-id, som kræves til P2P-"
"distribution af ‘%s’."

#: app/flatpak-builtins-create-usb.c:272
#, c-format
msgid "Warning: Omitting ref ‘%s’ (runtime of ‘%s’) because it's extra-data.\n"
msgstr ""
"Advarsel: Udelader referencen ‘%s’ (runtime af ‘%s’) da den er extra-data.\n"

#: app/flatpak-builtins-create-usb.c:484
msgid "MOUNT-PATH [REF…] - Copy apps or runtimes onto removable media"
msgstr ""
"MONTERINGSSTI [REFERENCE …] - Kopiér programmer eller runtimes til flytbart "
"medie"

#: app/flatpak-builtins-create-usb.c:493
msgid "MOUNT-PATH and REF must be specified"
msgstr "MONTERINGSSTI og REFERENCE skal angives"

#: app/flatpak-builtins-create-usb.c:607
#, c-format
msgid "Ref ‘%s’ found in multiple installations: %s. You must specify one."
msgstr ""
"Referencen ‘%s’ blev fundet i flere installationer: %s. Du kan angive en."

#: app/flatpak-builtins-create-usb.c:620
#, c-format
msgid "Refs must all be in the same installation (found in %s and %s)."
msgstr ""
"Referencer skal alle være i den samme installation (findes i %s og %s)."

#: app/flatpak-builtins-create-usb.c:670
#, c-format
msgid ""
"Warning: Ref ‘%s’ is partially installed. Use --allow-partial to suppress "
"this message.\n"
msgstr ""
"Advarsel: Referencen ‘%s’ er delvist installeret. Brug --allow-partial for "
"at undertrykke meddelelsen.\n"

#: app/flatpak-builtins-create-usb.c:681
#, c-format
msgid "Installed ref ‘%s’ is extra-data, and cannot be distributed offline"
msgstr ""
"Installerede reference ‘%s’ er extra-data og kan ikke distribueres offline"

#: app/flatpak-builtins-create-usb.c:721
#, c-format
msgid "Warning: Couldn't update repo metadata for remote ‘%s’: %s\n"
msgstr "Advarsel: Kunne ikke opdatere depot-metadata for eksternen ‘%s’: %s\n"

#: app/flatpak-builtins-create-usb.c:751
#, c-format
msgid "Warning: Couldn't update appstream data for remote ‘%s’ arch ‘%s’: %s\n"
msgstr ""
"Advarsel: Kunne ikke opdatere appstream-data for eksternen ‘%s’ arkitekturen "
"‘%s’: %s\n"

#. Print a warning if both appstream and appstream2 are missing
#: app/flatpak-builtins-create-usb.c:784
#, c-format
msgid ""
"Warning: Couldn't find appstream data for remote ‘%s’ arch ‘%s’: %s; %s\n"
msgstr ""
"Advarsel: Kunne ikke finde appstream-data for eksternen ‘%s’ arkitekturen "
"‘%s’: %s; %s\n"

#. Appstream2 is only for efficiency, so just print a debug message
#: app/flatpak-builtins-create-usb.c:790
#, c-format
msgid "Couldn't find appstream2 data for remote ‘%s’ arch ‘%s’: %s\n"
msgstr ""
"Kunne ikke finde appstream2-data for eksternen ‘%s’ arkitekturen ‘%s’: %s\n"

#: app/flatpak-builtins-document-export.c:62
msgid "Create a unique document reference"
msgstr "Opret en unik dokumentreference"

#: app/flatpak-builtins-document-export.c:63
msgid "Make the document transient for the current session"
msgstr "Lad dokumentet overgå til den nuværende session"

#: app/flatpak-builtins-document-export.c:64
msgid "Don't require the file to exist already"
msgstr "Kræv ikke at filen allerede findes"

#: app/flatpak-builtins-document-export.c:65
msgid "Give the app read permissions"
msgstr "Giv programmet læsetilladelser"

#: app/flatpak-builtins-document-export.c:66
msgid "Give the app write permissions"
msgstr "Giv programmet skrivetilladelser"

#: app/flatpak-builtins-document-export.c:67
msgid "Give the app delete permissions"
msgstr "Giv programmet slettetilladelser"

#: app/flatpak-builtins-document-export.c:68
msgid "Give the app permissions to grant further permissions"
msgstr "Giv programmet tilladelser til at give yderligere tilladelser"

#: app/flatpak-builtins-document-export.c:69
msgid "Revoke read permissions of the app"
msgstr "Tilbagekald programmets læsetilladelser"

#: app/flatpak-builtins-document-export.c:70
msgid "Revoke write permissions of the app"
msgstr "Tilbagekald programmets skrivetilladelser"

#: app/flatpak-builtins-document-export.c:71
msgid "Revoke delete permissions of the app"
msgstr "Tilbagekald programmets slettetilladelser"

#: app/flatpak-builtins-document-export.c:72
msgid "Revoke the permission to grant further permissions"
msgstr "Tilbagekald tilladelsen til at give yderligere tilladelser"

#: app/flatpak-builtins-document-export.c:73
msgid "Add permissions for this app"
msgstr "Tilføj tilladelser til programmet"

#: app/flatpak-builtins-document-export.c:73
msgid "APPID"
msgstr "PROGRAMID"

#: app/flatpak-builtins-document-export.c:100
msgid "FILE - Export a file to apps"
msgstr "FIL - Eksportér en fil til programmer"

#: app/flatpak-builtins-document-export.c:109
#: app/flatpak-builtins-document-info.c:72
#: app/flatpak-builtins-document-unexport.c:67
msgid "FILE must be specified"
msgstr "FIL skal angives"

#: app/flatpak-builtins-document-info.c:63
msgid "FILE - Get information about an exported file"
msgstr "FIL - Hent information om en eksporteret fil"

#: app/flatpak-builtins-document-info.c:100
#: app/flatpak-builtins-document-unexport.c:94
#, c-format
msgid "Not exported\n"
msgstr "Ikke eksporteret\n"

#: app/flatpak-builtins-document-list.c:43 app/flatpak-builtins-history.c:53
#: app/flatpak-builtins-list.c:54 app/flatpak-builtins-ps.c:43
#: app/flatpak-builtins-remote-list.c:45 app/flatpak-builtins-remote-ls.c:59
#: app/flatpak-builtins-search.c:38
msgid "What information to show"
msgstr "Den information der skal vises"

#: app/flatpak-builtins-document-list.c:43 app/flatpak-builtins-history.c:53
#: app/flatpak-builtins-list.c:54 app/flatpak-builtins-ps.c:43
#: app/flatpak-builtins-remote-list.c:45 app/flatpak-builtins-remote-ls.c:59
#: app/flatpak-builtins-search.c:38
msgid "FIELD,…"
msgstr "FELT, …"

#: app/flatpak-builtins-document-list.c:44 app/flatpak-builtins-history.c:54
#: app/flatpak-builtins-list.c:52 app/flatpak-builtins-permission-list.c:43
#: app/flatpak-builtins-permission-show.c:43 app/flatpak-builtins-ps.c:44
#: app/flatpak-builtins-remote-list.c:46 app/flatpak-builtins-remote-ls.c:63
#: app/flatpak-builtins-repo.c:717 app/flatpak-builtins-search.c:39
#, fuzzy
msgid "Show output in JSON format"
msgstr "Vis ekstra-information"

#: app/flatpak-builtins-document-list.c:49
msgid "Show the document ID"
msgstr "Vis dokument-id'et"

#: app/flatpak-builtins-document-list.c:50
msgid "Path"
msgstr "Sti"

#: app/flatpak-builtins-document-list.c:50
#: app/flatpak-builtins-document-list.c:51
msgid "Show the document path"
msgstr "Vis dokumentstien"

#: app/flatpak-builtins-document-list.c:51 app/flatpak-builtins-list.c:66
#: app/flatpak-builtins-remote-ls.c:74
msgid "Origin"
msgstr "Oprindelse"

#: app/flatpak-builtins-document-list.c:52 app/flatpak-builtins-history.c:62
#: app/flatpak-builtins-ps.c:52
msgid "Application"
msgstr "Program"

#: app/flatpak-builtins-document-list.c:52
msgid "Show applications with permission"
msgstr "Vis programmer med tilladelse"

#: app/flatpak-builtins-document-list.c:53
#: app/flatpak-builtins-permission-list.c:182
#: app/flatpak-builtins-permission-show.c:145
msgid "Permissions"
msgstr "Tilladelser"

#: app/flatpak-builtins-document-list.c:53
msgid "Show permissions for applications"
msgstr "Vis tilladelser for programmer"

#: app/flatpak-builtins-document-list.c:161
#, fuzzy, c-format
msgid "No documents found\n"
msgstr "Fandt ingen match"

#: app/flatpak-builtins-document-list.c:180
msgid "[APPID] - List exported files"
msgstr "[PROGRAMID] - Vis eksporterede filer"

#: app/flatpak-builtins-document-unexport.c:43
#, fuzzy
msgid "Specify the document ID"
msgstr "Vis dokument-id'et"

#: app/flatpak-builtins-document-unexport.c:58
msgid "FILE - Unexport a file to apps"
msgstr "FIL - Fjern eksport af en fil til programmer"

#: app/flatpak-builtins-enter.c:88
msgid "INSTANCE COMMAND [ARGUMENT…] - Run a command inside a running sandbox"
msgstr "INSTANS KOMMANDO [ARGUMENT …] - Kør en kommando i en kørende sandkasse"

#: app/flatpak-builtins-enter.c:111
msgid "INSTANCE and COMMAND must be specified"
msgstr "INSTANS og KOMMANDO skal angives"

#: app/flatpak-builtins-enter.c:138
#, c-format
msgid "%s is neither a pid nor an application or instance ID"
msgstr "%s er hverken et pid, et program eller instans-id"

#: app/flatpak-builtins-enter.c:144
msgid "entering not supported (need unprivileged user namespaces, or sudo -E)"
msgstr ""
"indgang understøttes ikke (behøver brugernavnerum uden tilladelser, eller "
"sudo -E)"

#: app/flatpak-builtins-enter.c:145
#, c-format
msgid "No such pid %s"
msgstr "Intet sådan pid %s"

#: app/flatpak-builtins-enter.c:158
msgid "Can't read cwd"
msgstr "Kan ikke læse den nuværende mappe"

#: app/flatpak-builtins-enter.c:163
msgid "Can't read root"
msgstr "Kan ikke læse roden"

#: app/flatpak-builtins-enter.c:191
#, c-format
msgid "Invalid %s namespace for pid %d"
msgstr "Ugyldigt %s-navnerum for pid'et %d"

#: app/flatpak-builtins-enter.c:202
#, c-format
msgid "Invalid %s namespace for self"
msgstr "Ugyldigt %s-navnerum for self"

#: app/flatpak-builtins-enter.c:216
#, c-format
msgid "Can't open %s namespace: %s"
msgstr "Kan ikke åbne %s-navnerum: %s"

#: app/flatpak-builtins-enter.c:226
msgid "entering not supported (need unprivileged user namespaces)"
msgstr "indgang understøttes ikke (behøver brugernavnerum uden tilladelser)"

#: app/flatpak-builtins-enter.c:227
#, c-format
msgid "Can't enter %s namespace: %s"
msgstr "Kan ikke gå ind i %s-navnerum: %s"

#: app/flatpak-builtins-enter.c:234
msgid "Can't chdir"
msgstr "Kan ikke chdir"

#: app/flatpak-builtins-enter.c:237
msgid "Can't chroot"
msgstr "Kan ikke chroot"

#: app/flatpak-builtins-enter.c:240
msgid "Can't switch gid"
msgstr "Kan ikke skifte gid"

#: app/flatpak-builtins-enter.c:243
msgid "Can't switch uid"
msgstr "Kan ikke skifte uid"

#: app/flatpak-builtins-history.c:50
msgid "Only show changes after TIME"
msgstr "Vis kun ændringer efter TIDSPUNKT"

#: app/flatpak-builtins-history.c:50 app/flatpak-builtins-history.c:51
msgid "TIME"
msgstr "TIDSPUNKT"

#: app/flatpak-builtins-history.c:51
msgid "Only show changes before TIME"
msgstr "Vis kun ændringer før TIDSPUNKT"

#: app/flatpak-builtins-history.c:52
msgid "Show newest entries first"
msgstr "Vis seneste poster først"

#: app/flatpak-builtins-history.c:59
msgid "Time"
msgstr "Tidspunkt"

#: app/flatpak-builtins-history.c:59
msgid "Show when the change happened"
msgstr "Vis hvornår ændringen skete"

#: app/flatpak-builtins-history.c:60
msgid "Change"
msgstr "Ændring"

#: app/flatpak-builtins-history.c:60
msgid "Show the kind of change"
msgstr "Vis ændringens type"

#: app/flatpak-builtins-history.c:61 app/flatpak-builtins-list.c:68
#: app/flatpak-builtins-remote-ls.c:75 app/flatpak-builtins-repo.c:335
msgid "Ref"
msgstr "Reference"

#: app/flatpak-builtins-history.c:61 app/flatpak-builtins-list.c:68
#: app/flatpak-builtins-remote-ls.c:75
msgid "Show the ref"
msgstr "Vis referencen"

#: app/flatpak-builtins-history.c:62
msgid "Show the application/runtime ID"
msgstr "Vis program-/runtime-id'et"

#: app/flatpak-builtins-history.c:63 app/flatpak-builtins-list.c:64
#: app/flatpak-builtins-ps.c:53 app/flatpak-builtins-remote-ls.c:73
#: app/flatpak-cli-transaction.c:1435
msgid "Arch"
msgstr "Arkitektur"

#: app/flatpak-builtins-history.c:63 app/flatpak-builtins-list.c:64
#: app/flatpak-builtins-ps.c:53 app/flatpak-builtins-remote-ls.c:73
msgid "Show the architecture"
msgstr "Vis arkitekturen"

#: app/flatpak-builtins-history.c:64 app/flatpak-builtins-list.c:63
#: app/flatpak-builtins-ps.c:54 app/flatpak-builtins-remote-ls.c:72
#: app/flatpak-builtins-search.c:48 app/flatpak-cli-transaction.c:1438
msgid "Branch"
msgstr "Gren"

#: app/flatpak-builtins-history.c:64 app/flatpak-builtins-list.c:63
#: app/flatpak-builtins-remote-ls.c:72
msgid "Show the branch"
msgstr "Vis grenen"

#: app/flatpak-builtins-history.c:65 app/flatpak-builtins-list.c:67
msgid "Installation"
msgstr "Installation"

#: app/flatpak-builtins-history.c:65
msgid "Show the affected installation"
msgstr "Vis den berørte installation"

#: app/flatpak-builtins-history.c:66 app/flatpak-cli-transaction.c:1452
msgid "Remote"
msgstr "Ekstern"

#: app/flatpak-builtins-history.c:66
msgid "Show the remote"
msgstr "Vis eksternen"

#: app/flatpak-builtins-history.c:67 app/flatpak-builtins-ps.c:55
#: app/flatpak-builtins-remote-ls.c:76
msgid "Commit"
msgstr "Indsendelse"

#: app/flatpak-builtins-history.c:67
msgid "Show the current commit"
msgstr "Vis den nuværende indsendelse"

#: app/flatpak-builtins-history.c:68
msgid "Old Commit"
msgstr "Gammel indsendelse"

#: app/flatpak-builtins-history.c:68
msgid "Show the previous commit"
msgstr "Vis den forrige indsendelse"

#: app/flatpak-builtins-history.c:69
msgid "Show the remote URL"
msgstr "Vis eksterne-URL"

#: app/flatpak-builtins-history.c:70 app/flatpak-cli-transaction.c:700
msgid "User"
msgstr "Bruger"

#: app/flatpak-builtins-history.c:70
msgid "Show the user doing the change"
msgstr "Vis brugeren som foretager ændringen"

#: app/flatpak-builtins-history.c:71
msgid "Tool"
msgstr "Værktøj"

#: app/flatpak-builtins-history.c:71
msgid "Show the tool that was used"
msgstr "Vis værktøjet som blev brugt"

#: app/flatpak-builtins-history.c:72 app/flatpak-builtins-list.c:62
#: app/flatpak-builtins-remote-ls.c:71 app/flatpak-builtins-search.c:47
msgid "Version"
msgstr "Version"

#: app/flatpak-builtins-history.c:72
msgid "Show the Flatpak version"
msgstr "Vis Flatpak-versionen"

#: app/flatpak-builtins-history.c:91
#, c-format
msgid "Failed to get journal data (%s): %s"
msgstr "Kunne ikke hente journaldata (%s): %s"

#: app/flatpak-builtins-history.c:146
#, c-format
msgid "Failed to open journal: %s"
msgstr "Kunne ikke åbne journal: %s"

#: app/flatpak-builtins-history.c:153
#, c-format
msgid "Failed to add match to journal: %s"
msgstr "Kunne ikke tilføje match til journal: %s"

#: app/flatpak-builtins-history.c:471
msgid " - Show history"
msgstr " - Vis historik"

#: app/flatpak-builtins-history.c:490
#, c-format
msgid "Failed to parse the --since option"
msgstr "Kunne ikke fortolke --since-tilvalget"

#: app/flatpak-builtins-history.c:501
#, c-format
msgid "Failed to parse the --until option"
msgstr "Kunne ikke fortolke --until-tilvalget"

#: app/flatpak-builtins-info.c:56
msgid "Show user installations"
msgstr "Vis brugerinstallationer"

#: app/flatpak-builtins-info.c:57
msgid "Show system-wide installations"
msgstr "Vis systembrede installationer"

#: app/flatpak-builtins-info.c:58
msgid "Show specific system-wide installations"
msgstr "Vis bestemte systembrede installationer"

#: app/flatpak-builtins-info.c:59 app/flatpak-builtins-remote-info.c:59
msgid "Show ref"
msgstr "Vis reference"

#: app/flatpak-builtins-info.c:60 app/flatpak-builtins-remote-info.c:60
msgid "Show commit"
msgstr "Vis indsendelse"

#: app/flatpak-builtins-info.c:61
msgid "Show origin"
msgstr "Vis oprindelse"

#: app/flatpak-builtins-info.c:62
msgid "Show size"
msgstr "Vis størrelse"

#: app/flatpak-builtins-info.c:63 app/flatpak-builtins-remote-info.c:62
msgid "Show metadata"
msgstr "Vis metadata"

#: app/flatpak-builtins-info.c:64 app/flatpak-builtins-remote-info.c:63
msgid "Show runtime"
msgstr "Vis runtime"

#: app/flatpak-builtins-info.c:65 app/flatpak-builtins-remote-info.c:64
msgid "Show sdk"
msgstr "Vis sdk"

#: app/flatpak-builtins-info.c:66
msgid "Show permissions"
msgstr "Vis tilladelser"

#: app/flatpak-builtins-info.c:67
msgid "Query file access"
msgstr "Forespørg filadgang"

#: app/flatpak-builtins-info.c:67 app/flatpak-builtins-install.c:82
#: app/flatpak-builtins-install.c:88 app/flatpak-builtins-preinstall.c:68
#: app/flatpak-builtins-run.c:182 app/flatpak-builtins-run.c:184
#: app/flatpak-builtins-update.c:67 app/flatpak-builtins-update.c:71
msgid "PATH"
msgstr "STI"

#: app/flatpak-builtins-info.c:68
msgid "Show extensions"
msgstr "Vis udvidelser"

#: app/flatpak-builtins-info.c:69
msgid "Show location"
msgstr "Vis placering"

#: app/flatpak-builtins-info.c:116
msgid "NAME [BRANCH] - Get info about an installed app or runtime"
msgstr "NAVN [GREN] - Hent information om et installeret program eller runtime"

#: app/flatpak-builtins-info.c:123 app/flatpak-builtins-remote-add.c:317
#: app/flatpak-builtins-remote-delete.c:63
msgid "NAME must be specified"
msgstr "NAVN skal angives"

#: app/flatpak-builtins-info.c:196
msgid "ref not present in origin"
msgstr "reference findes ikke i oprindelse"

#: app/flatpak-builtins-info.c:211 app/flatpak-builtins-remote-info.c:217
#, c-format
msgid "Warning: Commit has no flatpak metadata\n"
msgstr "Advarsel: Indsendelsen har ikke nogen flatpak-metadata\n"

#: app/flatpak-builtins-info.c:217 app/flatpak-builtins-info.c:259
#: app/flatpak-builtins-info.c:455 app/flatpak-builtins-info.c:513
#: app/flatpak-builtins-remote-info.c:236
#: app/flatpak-builtins-remote-info.c:271
msgid "ID:"
msgstr "ID:"

#: app/flatpak-builtins-info.c:218 app/flatpak-builtins-info.c:260
#: app/flatpak-builtins-remote-info.c:237
#: app/flatpak-builtins-remote-info.c:272
msgid "Ref:"
msgstr "Reference:"

#: app/flatpak-builtins-info.c:219 app/flatpak-builtins-info.c:261
#: app/flatpak-builtins-remote-info.c:238
#: app/flatpak-builtins-remote-info.c:273
msgid "Arch:"
msgstr "Arkitektur:"

#: app/flatpak-builtins-info.c:220 app/flatpak-builtins-info.c:262
#: app/flatpak-builtins-remote-info.c:239
#: app/flatpak-builtins-remote-info.c:274
msgid "Branch:"
msgstr "Gren:"

#: app/flatpak-builtins-info.c:222 app/flatpak-builtins-info.c:264
#: app/flatpak-builtins-remote-info.c:241
#: app/flatpak-builtins-remote-info.c:276
msgid "Version:"
msgstr "Version:"

#: app/flatpak-builtins-info.c:224 app/flatpak-builtins-info.c:266
#: app/flatpak-builtins-remote-info.c:243
#: app/flatpak-builtins-remote-info.c:278
msgid "License:"
msgstr "Licens:"

#: app/flatpak-builtins-info.c:226 app/flatpak-builtins-info.c:269
#: app/flatpak-builtins-remote-info.c:245
#: app/flatpak-builtins-remote-info.c:280
msgid "Collection:"
msgstr "Samling:"

#: app/flatpak-builtins-info.c:227 app/flatpak-builtins-info.c:270
#: app/flatpak-builtins-info.c:458 app/flatpak-builtins-info.c:516
msgid "Installation:"
msgstr "Installation:"

#: app/flatpak-builtins-info.c:228 app/flatpak-builtins-info.c:271
#: app/flatpak-builtins-info.c:459 app/flatpak-builtins-info.c:517
#: app/flatpak-builtins-remote-info.c:249
#: app/flatpak-builtins-remote-info.c:284
#, fuzzy
msgid "Installed Size:"
msgstr "Installeret størrelse"

#: app/flatpak-builtins-info.c:231 app/flatpak-builtins-info.c:279
#: app/flatpak-builtins-remote-info.c:252
#: app/flatpak-builtins-remote-info.c:288
msgid "Runtime:"
msgstr "Runtime:"

#: app/flatpak-builtins-info.c:232 app/flatpak-builtins-info.c:288
#: app/flatpak-builtins-remote-info.c:253
#: app/flatpak-builtins-remote-info.c:293
msgid "Sdk:"
msgstr "Sdk:"

#: app/flatpak-builtins-info.c:235 app/flatpak-builtins-info.c:313
#: app/flatpak-builtins-remote-info.c:256
#: app/flatpak-builtins-remote-info.c:319
msgid "Date:"
msgstr "Dato:"

#: app/flatpak-builtins-info.c:237 app/flatpak-builtins-info.c:311
#: app/flatpak-builtins-remote-info.c:258
#: app/flatpak-builtins-remote-info.c:317
msgid "Subject:"
msgstr "Emne:"

#: app/flatpak-builtins-info.c:240 app/flatpak-builtins-info.c:295
msgid "Active commit:"
msgstr "Aktive indsendelse:"

#: app/flatpak-builtins-info.c:241 app/flatpak-builtins-info.c:298
msgid "Latest commit:"
msgstr "Seneste indsendelse:"

#: app/flatpak-builtins-info.c:244 app/flatpak-builtins-info.c:303
#: app/flatpak-builtins-info.c:457 app/flatpak-builtins-info.c:515
#: app/flatpak-builtins-remote-info.c:259
#: app/flatpak-builtins-remote-info.c:298
msgid "Commit:"
msgstr "Indsendelse:"

#: app/flatpak-builtins-info.c:246 app/flatpak-builtins-info.c:308
#: app/flatpak-builtins-remote-info.c:261
#: app/flatpak-builtins-remote-info.c:303
msgid "Parent:"
msgstr "Forælder:"

#: app/flatpak-builtins-info.c:248 app/flatpak-builtins-info.c:321
msgid "Alt-id:"
msgstr "Alt-id:"

#: app/flatpak-builtins-info.c:250 app/flatpak-builtins-info.c:325
#: app/flatpak-builtins-remote-info.c:263
#: app/flatpak-builtins-remote-info.c:308
msgid "End-of-life:"
msgstr "End-of-life:"

#: app/flatpak-builtins-info.c:252 app/flatpak-builtins-info.c:330
#: app/flatpak-builtins-remote-info.c:265
#: app/flatpak-builtins-remote-info.c:313
msgid "End-of-life-rebase:"
msgstr "End-of-life-rebase:"

#: app/flatpak-builtins-info.c:254 app/flatpak-builtins-info.c:317
msgid "Subdirectories:"
msgstr "Undermapper:"

#: app/flatpak-builtins-info.c:255 app/flatpak-builtins-info.c:454
#: app/flatpak-builtins-info.c:512
msgid "Extension:"
msgstr "Udvidelse:"

#: app/flatpak-builtins-info.c:267 app/flatpak-builtins-info.c:456
#: app/flatpak-builtins-info.c:514
msgid "Origin:"
msgstr "Oprindelse:"

#: app/flatpak-builtins-info.c:460 app/flatpak-builtins-info.c:522
msgid "Subpaths:"
msgstr "Understier:"

#: app/flatpak-builtins-info.c:478
msgid "unmaintained"
msgstr "vedligeholdes ikke"

#: app/flatpak-builtins-info.c:480 app/flatpak-builtins-info.c:482
msgid "unknown"
msgstr "ukendt"

#: app/flatpak-builtins-install.c:68 app/flatpak-builtins-preinstall.c:57
msgid "Don't pull, only install from local cache"
msgstr "Pull ikke, installer kun fra lokalt mellemlager"

#: app/flatpak-builtins-install.c:69 app/flatpak-builtins-preinstall.c:58
#: app/flatpak-builtins-update.c:60
msgid "Don't deploy, only download to local cache"
msgstr "Udsend ikke, download kun til lokalt mellemlager"

#: app/flatpak-builtins-install.c:70 app/flatpak-builtins-preinstall.c:59
msgid "Don't install related refs"
msgstr "Installer ikke relaterede referencer"

#: app/flatpak-builtins-install.c:71 app/flatpak-builtins-preinstall.c:60
#: app/flatpak-builtins-update.c:62
msgid "Don't verify/install runtime dependencies"
msgstr "Verificer/installer ikke runtime-afhængigheder"

#: app/flatpak-builtins-install.c:72
msgid "Don't automatically pin explicit installs"
msgstr "Fastgør ikke automatisk eksplicitte installationer"

#: app/flatpak-builtins-install.c:73 app/flatpak-builtins-preinstall.c:61
#: app/flatpak-builtins-update.c:63
msgid "Don't use static deltas"
msgstr "Brug ikke statiske deltaer"

#: app/flatpak-builtins-install.c:76 app/flatpak-builtins-preinstall.c:62
msgid "Additionally install the SDK used to build the given refs"
msgstr ""

#: app/flatpak-builtins-install.c:77 app/flatpak-builtins-preinstall.c:63
msgid ""
"Additionally install the debug info for the given refs and their dependencies"
msgstr ""

#: app/flatpak-builtins-install.c:78
msgid "Assume LOCATION is a .flatpak single-file bundle"
msgstr "Antag at PLACERING er et enkeltfils .flatpak-bundt"

#: app/flatpak-builtins-install.c:79
msgid "Assume LOCATION is a .flatpakref application description"
msgstr "Antag at PLACERING er en .flatpakref-programbeskrivelse"

#: app/flatpak-builtins-install.c:80
msgid "Assume LOCATION is containers-transports(5) reference to an OCI image"
msgstr ""

#: app/flatpak-builtins-install.c:81
msgid "Check bundle signatures with GPG key from FILE (- for stdin)"
msgstr "Tjek bundt-underskrifter med GPG-nøgle fra FIL (- for stdin)"

#: app/flatpak-builtins-install.c:82
msgid "Only install this subpath"
msgstr "Installer kun denne understi"

#: app/flatpak-builtins-install.c:83 app/flatpak-builtins-preinstall.c:64
#: app/flatpak-builtins-uninstall.c:63 app/flatpak-builtins-update.c:68
msgid "Automatically answer yes for all questions"
msgstr "Svar automatisk ja til alle spørgsmål"

#: app/flatpak-builtins-install.c:84 app/flatpak-builtins-preinstall.c:65
msgid "Uninstall first if already installed"
msgstr "Afinstaller først hvis den allerede er installeret"

#: app/flatpak-builtins-install.c:85 app/flatpak-builtins-preinstall.c:66
#: app/flatpak-builtins-uninstall.c:64 app/flatpak-builtins-update.c:69
msgid "Produce minimal output and don't ask questions"
msgstr "Producer minimalt output og stil ikke spørgsmål"

#: app/flatpak-builtins-install.c:86
msgid "Update install if already installed"
msgstr "Opdateringsinstallation er allerede installeret"

#. Translators: A sideload is when you install from a local USB drive rather than the Internet.
#: app/flatpak-builtins-install.c:88 app/flatpak-builtins-preinstall.c:68
#: app/flatpak-builtins-update.c:71
msgid "Use this local repo for sideloads"
msgstr "Brug dette lokale depot til sideindlæsninger"

#: app/flatpak-builtins-install.c:178
msgid "Bundle filename must be specified"
msgstr "Bundt-filnavn skal angives"

#: app/flatpak-builtins-install.c:188
msgid "Remote bundles are not supported"
msgstr "Eksterne bundter understøttes ikke"

#: app/flatpak-builtins-install.c:231
msgid "Filename or uri must be specified"
msgstr "Filnavn eller uri skal angives"

#: app/flatpak-builtins-install.c:295
#, fuzzy
msgid "Image location must be specified"
msgstr "Der skal angives mindst én REFERENCE"

#: app/flatpak-builtins-install.c:345
msgid "[LOCATION/REMOTE] [REF…] - Install applications or runtimes"
msgstr ""
"[PLACERING/EKSTERNE] [REFERENCE …] - Installer programmer eller runtimes"

#: app/flatpak-builtins-install.c:378
msgid "At least one REF must be specified"
msgstr "Der skal angives mindst én REFERENCE"

#: app/flatpak-builtins-install.c:392
#, c-format
msgid "Looking for matches…\n"
msgstr "Leder efter match …\n"

#: app/flatpak-builtins-install.c:513
#, fuzzy, c-format
msgid "No remote refs found for ‘%s’"
msgstr "Fandt ingen eksterne referencer som ligner ‘%s’"

#: app/flatpak-builtins-install.c:573 app/flatpak-builtins-uninstall.c:405
#: common/flatpak-ref-utils.c:689 common/flatpak-ref-utils.c:1595
#, c-format
msgid "Invalid branch %s: %s"
msgstr "Ugyldig gren %s: %s"

#: app/flatpak-builtins-install.c:606
#, c-format
msgid "Nothing matches %s in local repository for remote %s"
msgstr "Intet matcher %s i lokalt depot for eksternen %s"

#: app/flatpak-builtins-install.c:608
#, c-format
msgid "Nothing matches %s in remote %s"
msgstr "Intet matcher %s i eksternen %s"

#: app/flatpak-builtins-install.c:629
#, c-format
msgid "Skipping: %s\n"
msgstr "Springer over: %s\n"

#: app/flatpak-builtins-kill.c:110
#, c-format
msgid "%s is not running"
msgstr "%s kører ikke"

#: app/flatpak-builtins-kill.c:136
msgid "INSTANCE - Stop a running application"
msgstr "INSTANS - Stop et kørende program"

#: app/flatpak-builtins-kill.c:144 app/flatpak-builtins-ps.c:256
msgid "Extra arguments given"
msgstr "Ekstra-argumenter givet"

#: app/flatpak-builtins-kill.c:150
msgid "Must specify the app to kill"
msgstr "Skal angive programmet for at dræbe"

#: app/flatpak-builtins-list.c:47
msgid "Show extra information"
msgstr "Vis ekstra-information"

#: app/flatpak-builtins-list.c:48
msgid "List installed runtimes"
msgstr "Vis installerede runtimes"

#: app/flatpak-builtins-list.c:49
msgid "List installed applications"
msgstr "Vis installerede programmer"

#: app/flatpak-builtins-list.c:50
msgid "Arch to show"
msgstr "Arkitektur som skal vises"

#: app/flatpak-builtins-list.c:51 app/flatpak-builtins-remote-ls.c:57
msgid "List all refs (including locale/debug)"
msgstr "Vis alle referencer (inklusive lokale/fejlretning)"

#: app/flatpak-builtins-list.c:53 app/flatpak-builtins-remote-ls.c:58
msgid "List all applications using RUNTIME"
msgstr "Vis alle programmer med RUNTIME"

#: app/flatpak-builtins-list.c:59 app/flatpak-builtins-remote-list.c:51
#: app/flatpak-builtins-remote-ls.c:68 app/flatpak-builtins-search.c:44
msgid "Name"
msgstr "Navn"

#: app/flatpak-builtins-list.c:59 app/flatpak-builtins-remote-list.c:51
#: app/flatpak-builtins-remote-ls.c:68 app/flatpak-builtins-search.c:44
msgid "Show the name"
msgstr "Vis navnet"

#: app/flatpak-builtins-list.c:60 app/flatpak-builtins-remote-list.c:60
#: app/flatpak-builtins-remote-ls.c:69 app/flatpak-builtins-search.c:45
msgid "Description"
msgstr "Beskrivelse"

#: app/flatpak-builtins-list.c:60 app/flatpak-builtins-remote-ls.c:69
#: app/flatpak-builtins-search.c:45
msgid "Show the description"
msgstr "Vis beskrivelsen"

#: app/flatpak-builtins-list.c:61 app/flatpak-builtins-remote-ls.c:70
#: app/flatpak-builtins-search.c:46
msgid "Application ID"
msgstr "Program-id"

#: app/flatpak-builtins-list.c:61 app/flatpak-builtins-ps.c:52
#: app/flatpak-builtins-remote-ls.c:70 app/flatpak-builtins-search.c:46
msgid "Show the application ID"
msgstr "Vis program-id'et"

#: app/flatpak-builtins-list.c:62 app/flatpak-builtins-remote-ls.c:71
#: app/flatpak-builtins-search.c:47
msgid "Show the version"
msgstr "Vis versionen"

#: app/flatpak-builtins-list.c:65 app/flatpak-builtins-ps.c:56
#: app/flatpak-builtins-remote-ls.c:77
msgid "Runtime"
msgstr "Runtime"

#: app/flatpak-builtins-list.c:65
msgid "Show the used runtime"
msgstr "Vis den brugte runtime"

#: app/flatpak-builtins-list.c:66 app/flatpak-builtins-remote-ls.c:74
msgid "Show the origin remote"
msgstr "Vis oprindelseseksternen"

#: app/flatpak-builtins-list.c:67
msgid "Show the installation"
msgstr "Vis installationen"

#: app/flatpak-builtins-list.c:69
msgid "Active commit"
msgstr "Aktive indsendelse"

#: app/flatpak-builtins-list.c:69 app/flatpak-builtins-remote-ls.c:76
msgid "Show the active commit"
msgstr "Vis den aktive indsendelse"

#: app/flatpak-builtins-list.c:70
msgid "Latest commit"
msgstr "Seneste indsendelse"

#: app/flatpak-builtins-list.c:70
msgid "Show the latest commit"
msgstr "Vis den seneste indsendelse"

#: app/flatpak-builtins-list.c:71 app/flatpak-builtins-remote-ls.c:78
msgid "Installed size"
msgstr "Installeret størrelse"

#: app/flatpak-builtins-list.c:71 app/flatpak-builtins-remote-ls.c:78
msgid "Show the installed size"
msgstr "Vis den installeret størrelse"

#: app/flatpak-builtins-list.c:72 app/flatpak-builtins-remote-list.c:58
#: app/flatpak-builtins-remote-ls.c:80 app/flatpak-builtins-repo.c:340
msgid "Options"
msgstr "Tilvalg"

#: app/flatpak-builtins-list.c:72 app/flatpak-builtins-remote-list.c:58
#: app/flatpak-builtins-remote-ls.c:80
msgid "Show options"
msgstr "Vis tilvalg"

#: app/flatpak-builtins-list.c:180
#, fuzzy, c-format
msgid "Unable to load details of %s: %s"
msgstr "Kan ikke oprette filen %s"

#: app/flatpak-builtins-list.c:190
#, fuzzy, c-format
msgid "Unable to inspect current version of %s: %s"
msgstr "Kan ikke oprette filen %s"

#: app/flatpak-builtins-list.c:408
msgid " - List installed apps and/or runtimes"
msgstr " - Vis installerede programmer og/eller runtimes"

#: app/flatpak-builtins-make-current.c:38
msgid "Arch to make current for"
msgstr "Arkitektur som skal gøres til den nuværende for"

#: app/flatpak-builtins-make-current.c:58
msgid "APP BRANCH - Make branch of application current"
msgstr "PROGRAM GREN - Gør gren af program til den nuværende"

#: app/flatpak-builtins-make-current.c:69 app/flatpak-builtins-run.c:260
msgid "APP must be specified"
msgstr "PROGRAM skal angives"

#: app/flatpak-builtins-make-current.c:84
msgid "BRANCH must be specified"
msgstr "GREN skal angives"

#: app/flatpak-builtins-make-current.c:97
#, c-format
msgid "App %s branch %s is not installed"
msgstr "Programmet %s grenen %s er ikke installeret"

#: app/flatpak-builtins-mask.c:42
msgid "Remove matching masks"
msgstr "Fjern matchende masker"

#: app/flatpak-builtins-mask.c:54
msgid ""
"[PATTERN…] - disable updates and automatic installation matching patterns"
msgstr ""
"[MØNSTER …] - deaktivér opdateringer og automatisk installation af matchende "
"mønstre"

#: app/flatpak-builtins-mask.c:73
#, c-format
msgid "No masked patterns\n"
msgstr "Ingen maskerede mønstre\n"

#: app/flatpak-builtins-mask.c:78
#, c-format
msgid "Masked patterns:\n"
msgstr "Maskerede mønstre:\n"

#: app/flatpak-builtins-override.c:42
msgid "Remove existing overrides"
msgstr "Fjern eksisterende tilsidesættelser"

#: app/flatpak-builtins-override.c:43
msgid "Show existing overrides"
msgstr "Vis eksisterende tilsidesættelser"

#: app/flatpak-builtins-override.c:59
msgid "[APP] - Override settings [for application]"
msgstr "[APP] - Tilsidesættelsesindstillinger [til program]"

#: app/flatpak-builtins-permission-list.c:143
msgid "[TABLE] [ID] - List permissions"
msgstr "[TABEL] [ID] - Vis tilladelser"

#: app/flatpak-builtins-permission-list.c:179
#: app/flatpak-builtins-permission-show.c:142
msgid "Table"
msgstr "Tabel"

#: app/flatpak-builtins-permission-list.c:180
#: app/flatpak-builtins-permission-show.c:143
msgid "Object"
msgstr "Objekt"

#: app/flatpak-builtins-permission-list.c:181
#: app/flatpak-builtins-permission-show.c:144
msgid "App"
msgstr "Program"

#: app/flatpak-builtins-permission-list.c:183
#: app/flatpak-builtins-permission-show.c:146
msgid "Data"
msgstr "Data"

#: app/flatpak-builtins-permission-remove.c:120
msgid "TABLE ID [APP_ID] - Remove item from permission store"
msgstr "TABEL ID [PROGRAMID] - Fjern punkt fra tilladelseslager"

#: app/flatpak-builtins-permission-remove.c:129
#: app/flatpak-builtins-permission-set.c:120
msgid "Too few arguments"
msgstr "For få argumenter"

#: app/flatpak-builtins-permission-reset.c:43
msgid "Reset all permissions"
msgstr "Nulstil alle tilladelser"

#: app/flatpak-builtins-permission-reset.c:144
msgid "APP_ID - Reset permissions for an app"
msgstr "PROGRAMID - Nulstil tilladelser for et program"

#: app/flatpak-builtins-permission-reset.c:153
#: app/flatpak-builtins-permission-show.c:124
msgid "Wrong number of arguments"
msgstr "Forkert antal argumenter"

#: app/flatpak-builtins-permission-set.c:42
msgid "Associate DATA with the entry"
msgstr "Tilknyt DATA med punktet"

#: app/flatpak-builtins-permission-set.c:42
msgid "DATA"
msgstr "DATA"

#: app/flatpak-builtins-permission-set.c:111
msgid "TABLE ID APP_ID [PERMISSION...] - Set permissions"
msgstr "TABEL ID PROGRAMID [RETTIGHEDER ...] - Indstil tilladelser"

#: app/flatpak-builtins-permission-set.c:132
#, c-format
msgid "Failed to parse '%s' as GVariant: "
msgstr "Kunne ikke fortolke '%s' som GVariant: "

#: app/flatpak-builtins-permission-show.c:115
msgid "APP_ID - Show permissions for an app"
msgstr "PROGRAMID - Vis tilladelser for et program"

#: app/flatpak-builtins-pin.c:44
msgid "Remove matching pins"
msgstr "Fjern matchende fastgørelser"

#: app/flatpak-builtins-pin.c:56
msgid "[PATTERN…] - disable automatic removal of runtimes matching patterns"
msgstr ""
"[MØNSTER …] - deaktivér automatisk fjernelse af runtimes der matcher mønstre"

#: app/flatpak-builtins-pin.c:75
#, c-format
msgid "No pinned patterns\n"
msgstr "Ingen fastgjorte mønstre\n"

#: app/flatpak-builtins-pin.c:80
#, c-format
msgid "Pinned patterns:\n"
msgstr "Fastgjorte mønstre:\n"

#: app/flatpak-builtins-preinstall.c:80
msgid "- Install flatpaks that are part of the operating system"
msgstr ""

#: app/flatpak-builtins-preinstall.c:118
#, c-format
msgid "Nothing to do.\n"
msgstr "Intet at foretage.\n"

#: app/flatpak-builtins-ps.c:49
msgid "Instance"
msgstr "Instans"

#: app/flatpak-builtins-ps.c:49
msgid "Show the instance ID"
msgstr "Vis instans-id'et"

#: app/flatpak-builtins-ps.c:50 app/flatpak-builtins-run.c:178
msgid "PID"
msgstr "PID"

#: app/flatpak-builtins-ps.c:50
msgid "Show the PID of the wrapper process"
msgstr "Vis PID'et for den omgivende proces"

#: app/flatpak-builtins-ps.c:51
msgid "Child-PID"
msgstr "Barne-PID"

#: app/flatpak-builtins-ps.c:51
msgid "Show the PID of the sandbox process"
msgstr "Vis PID'et for sandkasseprocessen"

#: app/flatpak-builtins-ps.c:54 app/flatpak-builtins-search.c:48
msgid "Show the application branch"
msgstr "Vis programgrenen"

#: app/flatpak-builtins-ps.c:55
msgid "Show the application commit"
msgstr "Vis programindsendelsen"

#: app/flatpak-builtins-ps.c:56
msgid "Show the runtime ID"
msgstr "Vis runtime-id'et"

#: app/flatpak-builtins-ps.c:57
msgid "R.-Branch"
msgstr "Runtime-gren"

#: app/flatpak-builtins-ps.c:57
msgid "Show the runtime branch"
msgstr "Vis runtime-grenen"

#: app/flatpak-builtins-ps.c:58
msgid "R.-Commit"
msgstr "R.-indsendelse"

#: app/flatpak-builtins-ps.c:58
msgid "Show the runtime commit"
msgstr "Vis runtimeindsendelsen"

#: app/flatpak-builtins-ps.c:59
msgid "Active"
msgstr "Aktivt"

#: app/flatpak-builtins-ps.c:59
msgid "Show whether the app is active"
msgstr "Vis om programmet er aktivt"

#: app/flatpak-builtins-ps.c:60
msgid "Background"
msgstr "Baggrunden"

#: app/flatpak-builtins-ps.c:60
msgid "Show whether the app is background"
msgstr "Vis om programmet er i baggrunden"

#: app/flatpak-builtins-ps.c:246
msgid " - Enumerate running sandboxes"
msgstr " - Oplist kørende sandkasser"

#: app/flatpak-builtins-remote-add.c:66
msgid "Do nothing if the provided remote exists"
msgstr "Foretag intet hvis den leverede eksterne findes"

#: app/flatpak-builtins-remote-add.c:67
msgid "LOCATION specifies a configuration file, not the repo location"
msgstr "PLACERING angiver en konfigurationsfil, ikke depotplaceringen"

#: app/flatpak-builtins-remote-add.c:72 app/flatpak-builtins-remote-modify.c:78
msgid "Disable GPG verification"
msgstr "Deaktivér GPG-verifikation"

#: app/flatpak-builtins-remote-add.c:73 app/flatpak-builtins-remote-modify.c:79
msgid "Mark the remote as don't enumerate"
msgstr "Mærk eksternen som oplist ikke"

#: app/flatpak-builtins-remote-add.c:74 app/flatpak-builtins-remote-modify.c:80
msgid "Mark the remote as don't use for deps"
msgstr "Mærk eksternen som brug ikke for afhængigheder"

#: app/flatpak-builtins-remote-add.c:75 app/flatpak-builtins-remote-modify.c:81
msgid "Set priority (default 1, higher is more prioritized)"
msgstr "Indstil prioritet (standard er 1, højere er mere prioriteret)"

#: app/flatpak-builtins-remote-add.c:75 app/flatpak-builtins-remote-modify.c:81
msgid "PRIORITY"
msgstr "PRIORITET"

#: app/flatpak-builtins-remote-add.c:76
msgid "The named subset to use for this remote"
msgstr "Det navngivet subset som skal bruges til eksternen"

#: app/flatpak-builtins-remote-add.c:76 app/flatpak-builtins-remote-modify.c:71
msgid "SUBSET"
msgstr "SUBSET"

#: app/flatpak-builtins-remote-add.c:77 app/flatpak-builtins-remote-modify.c:82
msgid "A nice name to use for this remote"
msgstr "Et godt navn som skal bruges til eksternen"

#: app/flatpak-builtins-remote-add.c:78 app/flatpak-builtins-remote-modify.c:83
msgid "A one-line comment for this remote"
msgstr "En kommentar på én linje til eksternen"

#: app/flatpak-builtins-remote-add.c:79 app/flatpak-builtins-remote-modify.c:84
msgid "A full-paragraph description for this remote"
msgstr "En beskrivelse på et helt afsnit til eksternen"

#: app/flatpak-builtins-remote-add.c:80 app/flatpak-builtins-remote-modify.c:85
msgid "URL for a website for this remote"
msgstr "URL til et websted til eksternen"

#: app/flatpak-builtins-remote-add.c:81 app/flatpak-builtins-remote-modify.c:86
msgid "URL for an icon for this remote"
msgstr "URL til et ikon til eksternen"

#: app/flatpak-builtins-remote-add.c:82 app/flatpak-builtins-remote-modify.c:87
msgid "Default branch to use for this remote"
msgstr "Standardgren som skal bruges til eksternen"

#: app/flatpak-builtins-remote-add.c:84 app/flatpak-builtins-remote-modify.c:89
msgid "Import GPG key from FILE (- for stdin)"
msgstr "Importér GPG-nøgle fra FIL (- for stdin)"

#: app/flatpak-builtins-remote-add.c:85 app/flatpak-builtins-remote-modify.c:90
msgid "Load signatures from URL"
msgstr ""

#: app/flatpak-builtins-remote-add.c:86 app/flatpak-builtins-remote-modify.c:92
msgid "Set path to local filter FILE"
msgstr "Indstil sti til lokal filterFIL"

#: app/flatpak-builtins-remote-add.c:87 app/flatpak-builtins-remote-modify.c:93
msgid "Disable the remote"
msgstr "Deaktivér eksternen"

#: app/flatpak-builtins-remote-add.c:88 app/flatpak-builtins-remote-modify.c:94
msgid "Name of authenticator"
msgstr "Navn på godkender"

#: app/flatpak-builtins-remote-add.c:90 app/flatpak-builtins-remote-modify.c:96
msgid "Autoinstall authenticator"
msgstr "Automatisk installation af godkender"

#: app/flatpak-builtins-remote-add.c:91 app/flatpak-builtins-remote-modify.c:97
msgid "Don't autoinstall authenticator"
msgstr "Brug ikke automatisk installation af godkender"

#: app/flatpak-builtins-remote-add.c:92 app/flatpak-builtins-remote-modify.c:99
msgid "Don't follow the redirect set in the summary file"
msgstr "Følg ikke den omdirigering som er indstillet i opsummeringsfilen"

#: app/flatpak-builtins-remote-add.c:261 app/flatpak-builtins-remote-add.c:268
#, c-format
msgid "Can't load uri %s: %s\n"
msgstr "Kan ikke indlæse uri'en %s: %s\n"

#: app/flatpak-builtins-remote-add.c:276 common/flatpak-dir.c:4643
#, c-format
msgid "Can't load file %s: %s\n"
msgstr "Kan ikke indlæse filen %s: %s\n"

#: app/flatpak-builtins-remote-add.c:304
msgid "NAME LOCATION - Add a remote repository"
msgstr "NAVN PLACERING - Tilføj et eksternt depot"

#: app/flatpak-builtins-remote-add.c:331
msgid "GPG verification is required if collections are enabled"
msgstr "Der kræves GPG-verifikation hvis samlingerne aktiveres"

#: app/flatpak-builtins-remote-add.c:393
#, c-format
msgid "Remote %s already exists"
msgstr "Eksternen %s findes allerede"

#: app/flatpak-builtins-remote-add.c:405
#: app/flatpak-builtins-remote-modify.c:340
#, c-format
msgid "Invalid authenticator name %s"
msgstr "Ugyldigt godkendernavn %s"

#: app/flatpak-builtins-remote-add.c:422
#, c-format
msgid "Warning: Could not update extra metadata for '%s': %s\n"
msgstr "Advarsel: Kunne ikke opdatere ekstra-metadata for '%s': %s\n"

#: app/flatpak-builtins-remote-delete.c:39
msgid "Remove remote even if in use"
msgstr "Fjern eksternen, selv hvis den er i brug"

#: app/flatpak-builtins-remote-delete.c:53
msgid "NAME - Delete a remote repository"
msgstr "NAVN - Slet et eksternt depot"

#: app/flatpak-builtins-remote-delete.c:100
#, c-format
msgid "The following refs are installed from remote '%s':"
msgstr "Følgende referencer er installeret fra eksternen '%s':"

#: app/flatpak-builtins-remote-delete.c:101
msgid "Remove them?"
msgstr "Fjern dem?"

#: app/flatpak-builtins-remote-delete.c:103
#, c-format
msgid "Can't remove remote '%s' with installed refs"
msgstr "Kan ikke fjerne eksternen '%s' med installerede referencer"

#: app/flatpak-builtins-remote-info.c:55
msgid "Commit to show info for"
msgstr "Indsendelse som skal vises information for"

#: app/flatpak-builtins-remote-info.c:58
msgid "Display log"
msgstr "Vis log"

#: app/flatpak-builtins-remote-info.c:61
msgid "Show parent"
msgstr "Vis forælder"

#: app/flatpak-builtins-remote-info.c:65 app/flatpak-builtins-remote-ls.c:60
msgid "Use local caches even if they are stale"
msgstr "Brug lokale mellemlagre selv hvis de er gamle"

#. Translators: A sideload is when you install from a local USB drive rather than the Internet.
#: app/flatpak-builtins-remote-info.c:67 app/flatpak-builtins-remote-ls.c:62
msgid "Only list refs available as sideloads"
msgstr "Vist kun referencer som er tilgængelige som sideindlæsninger"

#: app/flatpak-builtins-remote-info.c:114
msgid ""
" REMOTE REF - Show information about an application or runtime in a remote"
msgstr ""
" EKSTERNE REFERENCE - Vis information om et program eller runtime i en "
"ekstern"

#: app/flatpak-builtins-remote-info.c:125
msgid "REMOTE and REF must be specified"
msgstr "EKSTERNE og REFERENCE skal angives"

#: app/flatpak-builtins-remote-info.c:247
#: app/flatpak-builtins-remote-info.c:282
#, fuzzy
msgid "Download Size:"
msgstr "Downloadstørrelse"

#: app/flatpak-builtins-remote-info.c:267
#: app/flatpak-builtins-remote-info.c:325
msgid "History:"
msgstr "Historik:"

#: app/flatpak-builtins-remote-info.c:348
msgid " Commit:"
msgstr " Indsendelse:"

#: app/flatpak-builtins-remote-info.c:349
msgid " Subject:"
msgstr " Emne:"

#: app/flatpak-builtins-remote-info.c:350
msgid " Date:"
msgstr " Dato:"

#: app/flatpak-builtins-remote-info.c:383
#, c-format
msgid "Warning: Commit %s has no flatpak metadata\n"
msgstr "Advarsel: Indsendelsen %s har ikke nogen flatpak-metadata\n"

#: app/flatpak-builtins-remote-list.c:43
msgid "Show remote details"
msgstr "Vis detaljer for eksternen"

#: app/flatpak-builtins-remote-list.c:44
msgid "Show disabled remotes"
msgstr "Vis deaktiverede eksterne"

#: app/flatpak-builtins-remote-list.c:52
msgid "Title"
msgstr "Titel"

#: app/flatpak-builtins-remote-list.c:52
msgid "Show the title"
msgstr "Vis titlen"

#: app/flatpak-builtins-remote-list.c:53
msgid "Show the URL"
msgstr "Vis URL'en"

#: app/flatpak-builtins-remote-list.c:54
msgid "Show the collection ID"
msgstr "Vis samlings-id'et"

#: app/flatpak-builtins-remote-list.c:55 app/flatpak-builtins-repo.c:392
msgid "Subset"
msgstr "Subset"

#: app/flatpak-builtins-remote-list.c:55
msgid "Show the subset"
msgstr "Vis subset'tet"

#: app/flatpak-builtins-remote-list.c:56
msgid "Filter"
msgstr "Filter"

#: app/flatpak-builtins-remote-list.c:56
msgid "Show filter file"
msgstr "Vis filterfil"

#: app/flatpak-builtins-remote-list.c:57
msgid "Priority"
msgstr "Prioritet"

#: app/flatpak-builtins-remote-list.c:57
msgid "Show the priority"
msgstr "Vis prioriteten"

#: app/flatpak-builtins-remote-list.c:59
msgid "Comment"
msgstr "Kommentar"

#: app/flatpak-builtins-remote-list.c:59
msgid "Show comment"
msgstr "Vis kommentar"

#: app/flatpak-builtins-remote-list.c:60
msgid "Show description"
msgstr "Vis beskrivelse"

#: app/flatpak-builtins-remote-list.c:61
msgid "Homepage"
msgstr "Hjemmeside"

#: app/flatpak-builtins-remote-list.c:61
msgid "Show homepage"
msgstr "Vis hjemmeside"

#: app/flatpak-builtins-remote-list.c:62
msgid "Icon"
msgstr "Ikon"

#: app/flatpak-builtins-remote-list.c:62
msgid "Show icon"
msgstr "Vis ikon"

#: app/flatpak-builtins-remote-list.c:231
msgid " - List remote repositories"
msgstr " - Vis de eksterne depoter"

#: app/flatpak-builtins-remote-ls.c:52
msgid "Show arches and branches"
msgstr "Vis arkitekturer og grene"

#: app/flatpak-builtins-remote-ls.c:53
msgid "Show only runtimes"
msgstr "Vis kun runtimes"

#: app/flatpak-builtins-remote-ls.c:54
msgid "Show only apps"
msgstr "Vis kun programmer"

#: app/flatpak-builtins-remote-ls.c:55
msgid "Show only those where updates are available"
msgstr "Vis kun dem der findes opdateringer til"

#: app/flatpak-builtins-remote-ls.c:56
msgid "Limit to this arch (* for all)"
msgstr "Begræns til denne arkitektur (* for alle)"

#: app/flatpak-builtins-remote-ls.c:77
msgid "Show the runtime"
msgstr "Vis runtimen"

#: app/flatpak-builtins-remote-ls.c:79
msgid "Download size"
msgstr "Downloadstørrelse"

#: app/flatpak-builtins-remote-ls.c:79
msgid "Show the download size"
msgstr "Vis downloadstørrelsen"

#: app/flatpak-builtins-remote-ls.c:391
msgid " [REMOTE or URI] - Show available runtimes and applications"
msgstr " [EKSTERNE eller URI] - Vis tilgængelige runtimes og programmer"

#: app/flatpak-builtins-remote-modify.c:67
msgid "Enable GPG verification"
msgstr "Aktivér GPG-verifikation"

#: app/flatpak-builtins-remote-modify.c:68
msgid "Mark the remote as enumerate"
msgstr "Mærk eksternen som oplist"

#: app/flatpak-builtins-remote-modify.c:69
msgid "Mark the remote as used for dependencies"
msgstr "Mærk eksternen som bruges af afhængigheder"

#: app/flatpak-builtins-remote-modify.c:70
#, fuzzy
msgid "Set a new URL"
msgstr "Indstil en ny url"

#: app/flatpak-builtins-remote-modify.c:71
msgid "Set a new subset to use"
msgstr "Indstil et nyt subset som skal bruges"

#: app/flatpak-builtins-remote-modify.c:72
msgid "Enable the remote"
msgstr "Aktivér eksternen"

#: app/flatpak-builtins-remote-modify.c:73
msgid "Update extra metadata from the summary file"
msgstr "Opdater ekstra-metadata fra opsummeringsfilen"

#: app/flatpak-builtins-remote-modify.c:91
msgid "Disable local filter"
msgstr "Deaktivér lokalt filter"

#: app/flatpak-builtins-remote-modify.c:95
msgid "Authenticator options"
msgstr "Tilvalg for godkender"

#: app/flatpak-builtins-remote-modify.c:98
msgid "Follow the redirect set in the summary file"
msgstr "Følg den omdirigering som er indstillet i opsummeringsfilen"

#: app/flatpak-builtins-remote-modify.c:306
msgid "NAME - Modify a remote repository"
msgstr "NAVN - Rediger et eksternt depot"

#: app/flatpak-builtins-remote-modify.c:316
msgid "Remote NAME must be specified"
msgstr "NAVN af eksterne skal angives"

#: app/flatpak-builtins-remote-modify.c:327
#, c-format
msgid "Updating extra metadata from remote summary for %s\n"
msgstr "Opdaterer ekstra-metadata fra opsummering af eksterne for %s\n"

#: app/flatpak-builtins-remote-modify.c:330
#, c-format
msgid "Error updating extra metadata for '%s': %s\n"
msgstr "Fejl ved opdatering af ekstra-metadata for '%s': %s\n"

#: app/flatpak-builtins-remote-modify.c:331
#, c-format
msgid "Could not update extra metadata for %s"
msgstr "Kunne ikke opdatere ekstra-metadata for %s"

#: app/flatpak-builtins-repair.c:43
msgid "Don't make any changes"
msgstr "Foretag ikke nogen ændringer"

#: app/flatpak-builtins-repair.c:44
msgid "Reinstall all refs"
msgstr "Geninstaller alle referencer"

#: app/flatpak-builtins-repair.c:68
#, c-format
msgid "Object missing: %s.%s\n"
msgstr "Objekt mangler: %s.%s\n"

#: app/flatpak-builtins-repair.c:76
#, c-format
msgid "Object invalid: %s.%s\n"
msgstr "Objekt er ugyldigt: %s.%s\n"

#: app/flatpak-builtins-repair.c:81
#, c-format
msgid "%s, deleting object\n"
msgstr "%s, sletter objekt\n"

#: app/flatpak-builtins-repair.c:146
#, c-format
msgid "Can't load object %s: %s\n"
msgstr "Kan ikke indlæse objektet %s: %s\n"

#: app/flatpak-builtins-repair.c:228
#, fuzzy, c-format
msgid "Commit invalid %s: %s\n"
msgstr "Objekt er ugyldigt: %s.%s\n"

#: app/flatpak-builtins-repair.c:231
#, fuzzy, c-format
msgid "Deleting invalid commit %s: %s\n"
msgstr "Ugyldig indsend-reference %s: "

#: app/flatpak-builtins-repair.c:261
#, c-format
msgid "Commit should be marked partial: %s\n"
msgstr ""

#: app/flatpak-builtins-repair.c:264
#, c-format
msgid "Marking commit as partial: %s\n"
msgstr ""

#: app/flatpak-builtins-repair.c:293
#, c-format
msgid "Problems loading data for %s: %s\n"
msgstr "Problemer ved indlæsning af data for %s: %s\n"

#: app/flatpak-builtins-repair.c:306
#, c-format
msgid "Error reinstalling %s: %s\n"
msgstr "Fejl ved geninstallation af %s: %s\n"

#: app/flatpak-builtins-repair.c:327
msgid "- Repair a flatpak installation"
msgstr "- Reparer en flatpak-installation"

#: app/flatpak-builtins-repair.c:406
#, c-format
msgid "Removing non-deployed ref %s…\n"
msgstr "Fjerner ikke-udsendt reference %s …\n"

#: app/flatpak-builtins-repair.c:411
#, c-format
msgid "Skipping non-deployed ref %s…\n"
msgstr "Springer over ikke-udsendt reference %s …\n"

#: app/flatpak-builtins-repair.c:429
#, c-format
msgid "[%d/%d] Verifying %s…\n"
msgstr "[%d/%d] Verificerer %s …\n"

# scootergrisen: find ud af hvad "Dry run: " skal oversættes til
#: app/flatpak-builtins-repair.c:435
#, c-format
msgid "Dry run: "
msgstr "Dry run: "

#: app/flatpak-builtins-repair.c:440
#, c-format
msgid "Deleting ref %s due to missing objects\n"
msgstr "Sletter referencen %s pga. manglende objekter\n"

#: app/flatpak-builtins-repair.c:444
#, c-format
msgid "Deleting ref %s due to invalid objects\n"
msgstr "Sletter referencen %s pga. ugyldige objekter\n"

#: app/flatpak-builtins-repair.c:448
#, c-format
msgid "Deleting ref %s due to %d\n"
msgstr "Sletter referencen %s pga. %d\n"

#: app/flatpak-builtins-repair.c:464
#, c-format
msgid "Checking remotes...\n"
msgstr "Tjekker eksterne ...\n"

#: app/flatpak-builtins-repair.c:482
#, c-format
msgid "Remote %s for ref %s is missing\n"
msgstr "Eksternen %s for referencen %s mangler\n"

#: app/flatpak-builtins-repair.c:484
#, c-format
msgid "Remote %s for ref %s is disabled\n"
msgstr "Eksternen %s for referencen %s er deaktiveret\n"

#: app/flatpak-builtins-repair.c:490
#, c-format
msgid "Pruning objects\n"
msgstr "Beskærer objekter\n"

#: app/flatpak-builtins-repair.c:498
#, c-format
msgid "Erasing .removed\n"
msgstr "Sletter .removed\n"

#: app/flatpak-builtins-repair.c:524
#, c-format
msgid "Reinstalling refs\n"
msgstr "Geninstallerer referencer\n"

#: app/flatpak-builtins-repair.c:526
#, c-format
msgid "Reinstalling removed refs\n"
msgstr "Geninstallerer fjernede referencer\n"

#: app/flatpak-builtins-repair.c:551
#, c-format
msgid "While removing appstream for %s: "
msgstr "Ved fjernelse af appstream for %s: "

#: app/flatpak-builtins-repair.c:558
#, c-format
msgid "While deploying appstream for %s: "
msgstr "Ved udsendelse af appstream for %s: "

#: app/flatpak-builtins-repo.c:106
#, c-format
msgid "Repo mode: %s\n"
msgstr "Depottilstand: %s\n"

#: app/flatpak-builtins-repo.c:113
#, c-format
msgid "Indexed summaries: %s\n"
msgstr "Indekserede opsummeringer: %s\n"

#: app/flatpak-builtins-repo.c:113 app/flatpak-builtins-repo.c:139
#: app/flatpak-builtins-repo.c:172
msgid "true"
msgstr "sand"

#: app/flatpak-builtins-repo.c:113 app/flatpak-builtins-repo.c:139
#: app/flatpak-builtins-repo.c:172
msgid "false"
msgstr "falsk"

#: app/flatpak-builtins-repo.c:121
#, c-format
msgid "Subsummaries: "
msgstr "Underopsummeringer: "

#: app/flatpak-builtins-repo.c:136
#, c-format
msgid "Cache version: %d\n"
msgstr "Mellemlagerets version: %d\n"

#: app/flatpak-builtins-repo.c:139
#, c-format
msgid "Indexed deltas: %s\n"
msgstr "Indekserede deltaer: %s\n"

#: app/flatpak-builtins-repo.c:142
#, c-format
msgid "Title: %s\n"
msgstr "Titel: %s\n"

#: app/flatpak-builtins-repo.c:145
#, c-format
msgid "Comment: %s\n"
msgstr "Kommentar: %s\n"

#: app/flatpak-builtins-repo.c:148
#, c-format
msgid "Description: %s\n"
msgstr "Beskrivelse: %s\n"

#: app/flatpak-builtins-repo.c:151
#, c-format
msgid "Homepage: %s\n"
msgstr "Hjemmeside: %s\n"

#: app/flatpak-builtins-repo.c:154
#, c-format
msgid "Icon: %s\n"
msgstr "Ikon: %s\n"

#: app/flatpak-builtins-repo.c:157
#, c-format
msgid "Collection ID: %s\n"
msgstr "Samlings-id: %s\n"

#: app/flatpak-builtins-repo.c:160
#, c-format
msgid "Default branch: %s\n"
msgstr "Standardgren: %s\n"

#: app/flatpak-builtins-repo.c:163
#, c-format
msgid "Redirect URL: %s\n"
msgstr "Omdirigerings-URL: %s\n"

#: app/flatpak-builtins-repo.c:166
#, c-format
msgid "Deploy collection ID: %s\n"
msgstr "Udsend samlings-id: %s\n"

#: app/flatpak-builtins-repo.c:169
#, c-format
msgid "Authenticator name: %s\n"
msgstr "Godkendernavn: %s\n"

#: app/flatpak-builtins-repo.c:172
#, c-format
msgid "Authenticator install: %s\n"
msgstr "Godkenderinstallation: %s\n"

#: app/flatpak-builtins-repo.c:180
#, c-format
msgid "GPG key hash: %s\n"
msgstr "Hash for GPG-nøgle: %s\n"

#: app/flatpak-builtins-repo.c:184
#, c-format
msgid "%zd summary branches\n"
msgstr "%zd opsummeringsgrene\n"

#: app/flatpak-builtins-repo.c:336
msgid "Installed"
msgstr "Installeret"

#. Translators: Download is used here as a noun
#: app/flatpak-builtins-repo.c:338 app/flatpak-cli-transaction.c:1462
msgid "Download"
msgstr "Download"

#: app/flatpak-builtins-repo.c:339
msgid "Subsets"
msgstr "Subsets"

# scootergrisen: find ud af hvad "Digest" skal oversættes til
#: app/flatpak-builtins-repo.c:393
msgid "Digest"
msgstr "Digest"

#: app/flatpak-builtins-repo.c:394
msgid "History length"
msgstr "Historiklængde"

#: app/flatpak-builtins-repo.c:711
msgid "Print general information about the repository"
msgstr "Udskriv generel information om depotet"

#: app/flatpak-builtins-repo.c:712
msgid "List the branches in the repository"
msgstr "Vis grenene i depotet"

#: app/flatpak-builtins-repo.c:713
msgid "Print metadata for a branch"
msgstr "Udskriv metadata for en gren"

#: app/flatpak-builtins-repo.c:714
msgid "Show commits for a branch"
msgstr "Vis indsendelser for en gren"

#: app/flatpak-builtins-repo.c:715
msgid "Print information about the repo subsets"
msgstr "Udskriv information om depotets subsets"

#: app/flatpak-builtins-repo.c:716
msgid "Limit information to subsets with this prefix"
msgstr "Begræns information til subsets med dette præfiks"

#: app/flatpak-builtins-repo.c:732
msgid "LOCATION - Repository maintenance"
msgstr "PLACERING - Vedligeholdelse af depot"

#: app/flatpak-builtins-run.c:159
msgid "Command to run"
msgstr "Kommando som skal køres"

#: app/flatpak-builtins-run.c:160
msgid "Directory to run the command in"
msgstr "Mappe som kommandoen skal køres i"

#: app/flatpak-builtins-run.c:161
msgid "Branch to use"
msgstr "Gren som skal bruges"

#: app/flatpak-builtins-run.c:162
msgid "Use development runtime"
msgstr "Brug udvikling-runtime"

#: app/flatpak-builtins-run.c:163
msgid "Runtime to use"
msgstr "Runtime som skal bruges"

#: app/flatpak-builtins-run.c:164
msgid "Runtime version to use"
msgstr "Runtime-version som skal bruges"

#: app/flatpak-builtins-run.c:167
msgid "Log accessibility bus calls"
msgstr "Log buskald for tilgængelighed"

#: app/flatpak-builtins-run.c:168
msgid "Don't proxy accessibility bus calls"
msgstr "Brug ikke proxy til buskald for tilgængelighed"

#: app/flatpak-builtins-run.c:169
msgid "Proxy accessibility bus calls (default except when sandboxed)"
msgstr ""
"Brug proxy til buskald for tilgængelighed (standard undtagen i sandkasse)"

#: app/flatpak-builtins-run.c:170
msgid "Don't proxy session bus calls"
msgstr "Brug ikke proxy til buskald for session"

#: app/flatpak-builtins-run.c:171
msgid "Proxy session bus calls (default except when sandboxed)"
msgstr "Brug proxy til buskald for session (standard undtagen i sandkasse)"

#: app/flatpak-builtins-run.c:172
msgid "Don't start portals"
msgstr "Start ikke portaler"

#: app/flatpak-builtins-run.c:173
msgid "Enable file forwarding"
msgstr "Aktivér videresendelse af fil"

#: app/flatpak-builtins-run.c:174
msgid "Run specified commit"
msgstr "Kør angivne indsendelse"

#: app/flatpak-builtins-run.c:175
msgid "Use specified runtime commit"
msgstr "Brug angivne runtime-indsendelse"

#: app/flatpak-builtins-run.c:176
msgid "Run completely sandboxed"
msgstr "Kør helt i sandkasse"

#: app/flatpak-builtins-run.c:178
msgid "Use PID as parent pid for sharing namespaces"
msgstr "Brug PID som forælderens pid til deling af navnerum"

#: app/flatpak-builtins-run.c:179
msgid "Make processes visible in parent namespace"
msgstr "Gør processer synlige i forælderens navnerum"

#: app/flatpak-builtins-run.c:180
msgid "Share process ID namespace with parent"
msgstr "Del navnerum for proces-id med forælder"

#: app/flatpak-builtins-run.c:181
msgid "Write the instance ID to the given file descriptor"
msgstr "Skriv instans-id'et til den angivne filbeskriver"

# scootergrisen: find ud af om PATH skal oversættes til PATH eller STI
#: app/flatpak-builtins-run.c:182
msgid "Use PATH instead of the app's /app"
msgstr "Brug STI i stedet for programmets /app"

# scootergrisen: find ud af om PATH skal oversættes til PATH eller STI
#: app/flatpak-builtins-run.c:183
#, fuzzy
msgid "Use FD instead of the app's /app"
msgstr "Brug STI i stedet for programmets /app"

# scootergrisen: ved ikke hvad FD er
#: app/flatpak-builtins-run.c:183 app/flatpak-builtins-run.c:185
#: app/flatpak-builtins-run.c:187 app/flatpak-builtins-run.c:188
#: common/flatpak-context.c:2672
msgid "FD"
msgstr "FD"

#: app/flatpak-builtins-run.c:184
msgid "Use PATH instead of the runtime's /usr"
msgstr "Brug STI i stedet for runtimens /usr"

#: app/flatpak-builtins-run.c:185
#, fuzzy
msgid "Use FD instead of the runtime's /usr"
msgstr "Brug STI i stedet for runtimens /usr"

#: app/flatpak-builtins-run.c:186
#, fuzzy
msgid "Clear all outside environment variables"
msgstr "Indstil miljøvariabel"

#: app/flatpak-builtins-run.c:187
msgid ""
"Bind mount the file or directory referred to by FD to its canonicalized path"
msgstr ""

#: app/flatpak-builtins-run.c:188
msgid ""
"Bind mount the file or directory referred to by FD read-only to its "
"canonicalized path"
msgstr ""

#: app/flatpak-builtins-run.c:219
msgid "APP [ARGUMENT…] - Run an app"
msgstr "PROGRAM [ARGUMENT …] - Kør et program"

#: app/flatpak-builtins-run.c:370
#, c-format
msgid "runtime/%s/%s/%s not installed"
msgstr "runtime/%s/%s/%s er ikke installeret"

#: app/flatpak-builtins-run.c:419
msgid "app-fd and app-path cannot both be used"
msgstr ""

#: app/flatpak-builtins-run.c:449
msgid "usr-fd and usr-path cannot both be used"
msgstr ""

#: app/flatpak-builtins-search.c:37
msgid "Arch to search for"
msgstr "Arkitektur som skal søges efter"

#: app/flatpak-builtins-search.c:49
msgid "Remotes"
msgstr "Eksterne"

#: app/flatpak-builtins-search.c:49
msgid "Show the remotes"
msgstr "Vis eksternerne"

#: app/flatpak-builtins-search.c:244
msgid "TEXT - Search remote apps/runtimes for text"
msgstr "TEKST - Søg efter tekst i eksterne programmer/-runtimes"

#: app/flatpak-builtins-search.c:255
msgid "TEXT must be specified"
msgstr "TEKST skal angives"

#: app/flatpak-builtins-search.c:338
msgid "No matches found"
msgstr "Fandt ingen match"

#: app/flatpak-builtins-uninstall.c:54
msgid "Arch to uninstall"
msgstr "Arkitektur som skal afinstalleres"

#: app/flatpak-builtins-uninstall.c:55
msgid "Keep ref in local repository"
msgstr "Bevar reference i lokalt depot"

#: app/flatpak-builtins-uninstall.c:56
msgid "Don't uninstall related refs"
msgstr "Afinstaller ikke relaterede referencer"

#: app/flatpak-builtins-uninstall.c:57
msgid "Remove files even if running"
msgstr "Fjern filerne, selv under kørsel"

#: app/flatpak-builtins-uninstall.c:60
msgid "Uninstall all"
msgstr "Afinstaller alle"

#: app/flatpak-builtins-uninstall.c:61
msgid "Uninstall unused"
msgstr "Afinstaller ubrugte"

#: app/flatpak-builtins-uninstall.c:62
msgid "Delete app data"
msgstr "Slet programdata"

#: app/flatpak-builtins-uninstall.c:141
#, c-format
msgid "Delete data for %s?"
msgstr "Slet data for %s?"

#: app/flatpak-builtins-uninstall.c:220
#, c-format
msgid "Info: applications using the extension %s%s%s branch %s%s%s:\n"
msgstr ""

#: app/flatpak-builtins-uninstall.c:223
#, fuzzy, c-format
msgid "Info: applications using the runtime %s%s%s branch %s%s%s:\n"
msgstr "Programmer som bruger denne runtime:\n"

#: app/flatpak-builtins-uninstall.c:238
#, fuzzy
msgid "Really remove?"
msgstr "Ekstern"

#: app/flatpak-builtins-uninstall.c:255
#, fuzzy
msgid "[REF…] - Uninstall applications or runtimes"
msgstr "[REFERENCE …] - Opdater programmer eller runtimes"

#: app/flatpak-builtins-uninstall.c:264
msgid "Must specify at least one REF, --unused, --all or --delete-data"
msgstr "Skal mindst angive én REFERENCE, --unused, --all eller --delete-data"

#: app/flatpak-builtins-uninstall.c:267
msgid "Must not specify REFs when using --all"
msgstr "REFERENCEr skal ikke angives når --all bruges"

#: app/flatpak-builtins-uninstall.c:270
msgid "Must not specify REFs when using --unused"
msgstr "REFERENCEr skal ikke angives når --unused bruges"

#: app/flatpak-builtins-uninstall.c:336
#, c-format
msgid ""
"\n"
"These runtimes in installation '%s' are pinned and won't be removed; see "
"flatpak-pin(1):\n"
msgstr ""
"\n"
"Disse runtimes i installationen '%s' er fastgjorte og fjernes ikke; se "
"flatpak-pin(1):\n"

#: app/flatpak-builtins-uninstall.c:370
#, c-format
msgid "Nothing unused to uninstall\n"
msgstr "Der er ikke noget ubrugt at afinstallere\n"

#: app/flatpak-builtins-uninstall.c:444
#, fuzzy, c-format
msgid "No installed refs found for ‘%s’"
msgstr "Lignende installerede referencer fundet for ‘%s’:"

#: app/flatpak-builtins-uninstall.c:447
#, c-format
msgid " with arch ‘%s’"
msgstr ""

#: app/flatpak-builtins-uninstall.c:449
#, c-format
msgid " with branch ‘%s’"
msgstr ""

#: app/flatpak-builtins-uninstall.c:456
#, c-format
msgid "Warning: %s is not installed\n"
msgstr "Advarsel: %s er ikke installeret\n"

#: app/flatpak-builtins-uninstall.c:490
#, c-format
msgid "None of the specified refs are installed"
msgstr ""

#: app/flatpak-builtins-uninstall.c:599
#, c-format
msgid "No app data to delete\n"
msgstr ""

#: app/flatpak-builtins-update.c:56
msgid "Arch to update for"
msgstr "Arkitektur som skal opdateres til"

#: app/flatpak-builtins-update.c:57
msgid "Commit to deploy"
msgstr "Indsendelse som skal udsendes"

#: app/flatpak-builtins-update.c:58
msgid "Remove old files even if running"
msgstr "Fjern gamle filer, selv under kørsel"

#: app/flatpak-builtins-update.c:59
msgid "Don't pull, only update from local cache"
msgstr "Pull ikke, opdater kun fra lokalt mellemlager"

#: app/flatpak-builtins-update.c:61
msgid "Don't update related refs"
msgstr "Opdater ikke relaterede referencer"

#: app/flatpak-builtins-update.c:66
msgid "Update appstream for remote"
msgstr "Opdater appstream for ekstern"

#: app/flatpak-builtins-update.c:67
msgid "Only update this subpath"
msgstr "Opdater kun denne understi"

#: app/flatpak-builtins-update.c:90
msgid "[REF…] - Update applications or runtimes"
msgstr "[REFERENCE …] - Opdater programmer eller runtimes"

#: app/flatpak-builtins-update.c:121
msgid "With --commit, only one REF may be specified"
msgstr "Med --commit må der kun angives mindst én REFERENCE"

#: app/flatpak-builtins-update.c:162
#, c-format
msgid "Looking for updates…\n"
msgstr "Leder efter opdateringer …\n"

#: app/flatpak-builtins-update.c:215
#, c-format
msgid "Unable to update %s: %s\n"
msgstr "Kan ikke opdatere %s: %s\n"

#: app/flatpak-builtins-update.c:274
#, fuzzy, c-format
msgid "Nothing to update.\n"
msgstr "Intet at foretage.\n"

#: app/flatpak-builtins-utils.c:337
#, fuzzy, c-format
msgid ""
"Remote ‘%s’ found in multiple installations, unable to proceed in non-"
"interactive mode"
msgstr ""
"Referencen ‘%s’ blev fundet i flere installationer: %s. Du kan angive en."

#: app/flatpak-builtins-utils.c:346
#, c-format
msgid "Remote ‘%s’ found in multiple installations:"
msgstr "Eksternen ‘%s’ blev fundet i flere installationer:"

#: app/flatpak-builtins-utils.c:347 app/flatpak-builtins-utils.c:442
#: app/flatpak-builtins-utils.c:538 app/flatpak-builtins-utils.c:540
#: app/flatpak-builtins-utils.c:598
msgid "Which do you want to use (0 to abort)?"
msgstr "Hvad vil du bruge (0 for at afbryde)?"

#: app/flatpak-builtins-utils.c:349
#, c-format
msgid "No remote chosen to resolve ‘%s’ which exists in multiple installations"
msgstr ""
"Ingen eksterne valgt til at løse ‘%s’ som findes i flere installationer"

#: app/flatpak-builtins-utils.c:358
#, c-format
msgid ""
"Remote \"%s\" not found\n"
"Hint: Use flatpak remote-add to add a remote"
msgstr ""
"Eksternen \"%s\" blev ikke fundet\n"
"Tip: Brug flatpak remote-add for at tilføje en eksterne"

#: app/flatpak-builtins-utils.c:364
#, c-format
msgid "Remote \"%s\" not found in the %s installation"
msgstr "Eksternen \"%s\" blev fundet i %s-installationen"

#: app/flatpak-builtins-utils.c:404
#, c-format
msgid "Multiple refs match ‘%s’, unable to proceed in non-interactive mode"
msgstr ""

#. default to yes on Enter
#: app/flatpak-builtins-utils.c:430
#, c-format
msgid ""
"Found ref ‘%s’ in remote ‘%s’ (%s).\n"
"Use this ref?"
msgstr ""
"Fandt referencen ‘%s’ i eksternen ‘%s’ (%s).\n"
"Brug referencen?"

#: app/flatpak-builtins-utils.c:434 app/flatpak-builtins-utils.c:444
#: app/flatpak-builtins-utils.c:522 app/flatpak-builtins-utils.c:543
#, c-format
msgid "No ref chosen to resolve matches for ‘%s’"
msgstr "Der er ikke valgt nogen reference til at løse match for ‘%s’"

#: app/flatpak-builtins-utils.c:440
#, c-format
msgid "Similar refs found for ‘%s’ in remote ‘%s’ (%s):"
msgstr "Lignende referencer fundet for ‘%s’ i eksternen ‘%s’ (%s):"

#: app/flatpak-builtins-utils.c:488
#, c-format
msgid ""
"Multiple installed refs match ‘%s’, unable to proceed in non-interactive mode"
msgstr ""

#. default to yes on Enter
#: app/flatpak-builtins-utils.c:518
#, c-format
msgid "Found installed ref ‘%s’ (%s). Is this correct?"
msgstr "Fandt installerede reference ‘%s’ (%s). Er det korrekt?"

#: app/flatpak-builtins-utils.c:534
#, c-format
msgid "All of the above"
msgstr "Allesammen"

#: app/flatpak-builtins-utils.c:535
#, c-format
msgid "Similar installed refs found for ‘%s’:"
msgstr "Lignende installerede referencer fundet for ‘%s’:"

#: app/flatpak-builtins-utils.c:579
#, c-format
msgid ""
"Multiple remotes have refs matching ‘%s’, unable to proceed in non-"
"interactive mode"
msgstr ""

#: app/flatpak-builtins-utils.c:597
#, c-format
msgid "Remotes found with refs similar to ‘%s’:"
msgstr "Fandt eksterne med referencer som ligner ‘%s’:"

#: app/flatpak-builtins-utils.c:600
#, c-format
msgid "No remote chosen to resolve matches for ‘%s’"
msgstr "Der er ikke valgt nogen eksterne til at løse match for ‘%s’"

#: app/flatpak-builtins-utils.c:696 app/flatpak-builtins-utils.c:699
#, c-format
msgid "Updating appstream data for user remote %s"
msgstr "Opdaterer appstream-data for brugereksternen %s"

#: app/flatpak-builtins-utils.c:706 app/flatpak-builtins-utils.c:709
#, c-format
msgid "Updating appstream data for remote %s"
msgstr "Opdaterer appstream-data for eksternen %s"

#: app/flatpak-builtins-utils.c:717 app/flatpak-builtins-utils.c:719
msgid "Error updating"
msgstr "Fejl ved opdatering"

#: app/flatpak-builtins-utils.c:755
#, c-format
msgid "Remote \"%s\" not found"
msgstr "Eksternen \"%s\" blev ikke fundet"

#: app/flatpak-builtins-utils.c:796
#, c-format
msgid "Ambiguous suffix: '%s'."
msgstr "Flertydigt suffiks: '%s'."

#. Translators: don't translate the values
#: app/flatpak-builtins-utils.c:798 app/flatpak-builtins-utils.c:813
msgid "Possible values are :s[tart], :m[iddle], :e[nd] or :f[ull]"
msgstr "Mulige værdier er :s[tart], :m[iddle], :e[nd] eller :f[ull]"

#: app/flatpak-builtins-utils.c:811
#, c-format
msgid "Invalid suffix: '%s'."
msgstr "Ugyldigt suffiks: '%s'."

#: app/flatpak-builtins-utils.c:846
#, c-format
msgid "Ambiguous column: %s"
msgstr "Flertydig kolonne: %s"

#: app/flatpak-builtins-utils.c:859
#, c-format
msgid "Unknown column: %s"
msgstr "Ukendt kolonne: %s"

#: app/flatpak-builtins-utils.c:917
msgid "Available columns:\n"
msgstr "Tilgængelige kolonner:\n"

#: app/flatpak-builtins-utils.c:927
msgid "Show all columns"
msgstr "Vis alle kolonner"

#: app/flatpak-builtins-utils.c:928
msgid "Show available columns"
msgstr "Vis tilgængelige kolonner"

#: app/flatpak-builtins-utils.c:931
msgid "Append :s[tart], :m[iddle], :e[nd] or :f[ull] to change ellipsization"
msgstr ""
"Tilføj :s[tart], :m[iddle], :e[nd] eller :f[ull] for at skifte brug af "
"ellipse"

#: app/flatpak-builtins-utils.c:1483
#, c-format
msgid "Unknown scheme in sideload location %s"
msgstr ""

#: app/flatpak-cli-transaction.c:96 app/flatpak-cli-transaction.c:102
#, c-format
msgid "Required runtime for %s (%s) found in remote %s\n"
msgstr "Krævede runtime for %s (%s) blev fundet i eksternen %s\n"

#: app/flatpak-cli-transaction.c:104
msgid "Do you want to install it?"
msgstr "Vil du installere den?"

#: app/flatpak-cli-transaction.c:110
#, c-format
msgid "Required runtime for %s (%s) found in remotes:"
msgstr "Krævede runtime til %s (%s) blev fundet i eksterne:"

#: app/flatpak-cli-transaction.c:112
msgid "Which do you want to install (0 to abort)?"
msgstr "Hvad vil du installere (0 for at afbryde)?"

#: app/flatpak-cli-transaction.c:132
#, fuzzy, c-format
msgid "Configuring %s as new remote '%s'\n"
msgstr "Konfigurerer %s som ny eksterne '%s'"

#. default to yes on Enter
#: app/flatpak-cli-transaction.c:139
#, c-format
msgid ""
"The remote '%s', referred to by '%s' at location %s contains additional "
"applications.\n"
"Should the remote be kept for future installations?"
msgstr ""
"Eksternen '%s', som refereres til af '%s' på placeringen %s indeholder "
"yderligere programmer.\n"
"Skal eksternen beholdes til fremtidige installationer?"

#. default to yes on Enter
#: app/flatpak-cli-transaction.c:147
#, c-format
msgid ""
"The application %s depends on runtimes from:\n"
"  %s\n"
"Configure this as new remote '%s'"
msgstr ""
"Programmet %s afhænger af runtimes fra:\n"
"  %s\n"
"Konfigurer det som ny eksterne '%s'"

#. Formatted size/remaining time in seconds
#: app/flatpak-cli-transaction.c:321
#, c-format
msgid "%s/s%s%s"
msgstr ""

#. Download progress percentage, use the appropriate
#. percent format for your language
#: app/flatpak-cli-transaction.c:359
#, c-format
msgid "%3d%%"
msgstr ""

#: app/flatpak-cli-transaction.c:414
msgid "Installing…"
msgstr "Installerer …"

#: app/flatpak-cli-transaction.c:416
#, c-format
msgid "Installing %d/%d…"
msgstr "Installerer %d/%d …"

#: app/flatpak-cli-transaction.c:421
msgid "Updating…"
msgstr "Opdaterer …"

#: app/flatpak-cli-transaction.c:423
#, c-format
msgid "Updating %d/%d…"
msgstr "Opdaterer %d/%d …"

#: app/flatpak-cli-transaction.c:428
msgid "Uninstalling…"
msgstr "Afinstallerer …"

#: app/flatpak-cli-transaction.c:430
#, c-format
msgid "Uninstalling %d/%d…"
msgstr "Afinstallerer %d/%d …"

#: app/flatpak-cli-transaction.c:496 app/flatpak-quiet-transaction.c:161
#, c-format
msgid "Info: %s was skipped"
msgstr "Info: %s blev sprunget over"

#: app/flatpak-cli-transaction.c:519
#, fuzzy, c-format
msgid "Warning: %s%s%s already installed"
msgstr "%s er allerede installeret"

#: app/flatpak-cli-transaction.c:522
#, fuzzy, c-format
msgid "Error: %s%s%s already installed"
msgstr "%s er allerede installeret"

#: app/flatpak-cli-transaction.c:528
#, fuzzy, c-format
msgid "Warning: %s%s%s not installed"
msgstr "Advarsel: %s er ikke installeret\n"

#: app/flatpak-cli-transaction.c:531
#, fuzzy, c-format
msgid "Error: %s%s%s not installed"
msgstr "%s/%s/%s er ikke installeret"

#: app/flatpak-cli-transaction.c:537
#, fuzzy, c-format
msgid "Warning: %s%s%s needs a later flatpak version"
msgstr "%s har brug for en nyere flatpak-version"

#: app/flatpak-cli-transaction.c:540
#, fuzzy, c-format
msgid "Error: %s%s%s needs a later flatpak version"
msgstr "%s har brug for en nyere flatpak-version"

#: app/flatpak-cli-transaction.c:546
#, fuzzy
msgid "Warning: Not enough disk space to complete this operation"
msgstr "Der er ikke nok ledig diskplads til at gennemføre handlingen"

#: app/flatpak-cli-transaction.c:548
#, fuzzy
msgid "Error: Not enough disk space to complete this operation"
msgstr "Der er ikke nok ledig diskplads til at gennemføre handlingen"

#: app/flatpak-cli-transaction.c:553
#, fuzzy, c-format
msgid "Warning: %s"
msgstr "Advarsel: "

#: app/flatpak-cli-transaction.c:555
#, fuzzy, c-format
msgid "Error: %s"
msgstr "Fejl:"

#: app/flatpak-cli-transaction.c:570
#, fuzzy, c-format
msgid "Failed to install %s%s%s: "
msgstr "Kunne ikke rebase %s til %s: "

#: app/flatpak-cli-transaction.c:577
#, fuzzy, c-format
msgid "Failed to update %s%s%s: "
msgstr "Kunne ikke %s %s: "

#: app/flatpak-cli-transaction.c:584
#, fuzzy, c-format
msgid "Failed to install bundle %s%s%s: "
msgstr "Kunne ikke rebase %s til %s: "

#: app/flatpak-cli-transaction.c:591
#, fuzzy, c-format
msgid "Failed to uninstall %s%s%s: "
msgstr "Kunne ikke rebase %s til %s: "

#: app/flatpak-cli-transaction.c:642
#, c-format
msgid "Authentication required for remote '%s'\n"
msgstr "Der kræves godkendelse til eksternen '%s'\n"

#: app/flatpak-cli-transaction.c:643
msgid "Open browser?"
msgstr "Åbn browser?"

#: app/flatpak-cli-transaction.c:699
#, c-format
msgid "Login required remote %s (realm %s)\n"
msgstr "Der kræves login til eksternen %s (realm %s)\n"

#: app/flatpak-cli-transaction.c:704
msgid "Password"
msgstr "Adgangskode"

#. Only runtimes can be pinned
#: app/flatpak-cli-transaction.c:759
#, fuzzy, c-format
msgid ""
"\n"
"Info: (pinned) runtime %s%s%s branch %s%s%s is end-of-life, in favor of "
"%s%s%s branch %s%s%s\n"
msgstr "Info: (fastgjort) %s//%s er end-of-life, til fordel for %s\n"

#: app/flatpak-cli-transaction.c:765
#, fuzzy, c-format
msgid ""
"\n"
"Info: runtime %s%s%s branch %s%s%s is end-of-life, in favor of %s%s%s branch "
"%s%s%s\n"
msgstr "Info: %s//%s er end-of-life, til fordel for %s\n"

#: app/flatpak-cli-transaction.c:768
#, fuzzy, c-format
msgid ""
"\n"
"Info: app %s%s%s branch %s%s%s is end-of-life, in favor of %s%s%s branch "
"%s%s%s\n"
msgstr "Info: %s//%s er end-of-life, til fordel for %s\n"

#. Only runtimes can be pinned
#: app/flatpak-cli-transaction.c:780
#, fuzzy, c-format
msgid ""
"\n"
"Info: (pinned) runtime %s%s%s branch %s%s%s is end-of-life, with reason:\n"
msgstr "Info (fastgjort): %s//%s er end-of-life, med årsagen:\n"

#: app/flatpak-cli-transaction.c:786
#, fuzzy, c-format
msgid ""
"\n"
"Info: runtime %s%s%s branch %s%s%s is end-of-life, with reason:\n"
msgstr "Info: %s//%s er end-of-life, med årsagen:\n"

#: app/flatpak-cli-transaction.c:789
#, fuzzy, c-format
msgid ""
"\n"
"Info: app %s%s%s branch %s%s%s is end-of-life, with reason:\n"
msgstr "Info: %s//%s er end-of-life, med årsagen:\n"

#: app/flatpak-cli-transaction.c:963
#, fuzzy, c-format
msgid "Info: applications using this extension:\n"
msgstr "Programmer som bruger denne runtime:\n"

#: app/flatpak-cli-transaction.c:965
#, fuzzy, c-format
msgid "Info: applications using this runtime:\n"
msgstr "Programmer som bruger denne runtime:\n"

#: app/flatpak-cli-transaction.c:984
msgid "Replace?"
msgstr ""

#: app/flatpak-cli-transaction.c:987 app/flatpak-quiet-transaction.c:247
#, c-format
msgid "Updating to rebased version\n"
msgstr "Opdaterer til rebased version\n"

#: app/flatpak-cli-transaction.c:1011
#, c-format
msgid "Failed to rebase %s to %s: "
msgstr "Kunne ikke rebase %s til %s: "

#: app/flatpak-cli-transaction.c:1277
#, fuzzy, c-format
msgid "New %s%s%s permissions:"
msgstr "Nye tilladelser for %s:"

#: app/flatpak-cli-transaction.c:1279
#, fuzzy, c-format
msgid "%s%s%s permissions:"
msgstr "Tilladelser for %s:"

#: app/flatpak-cli-transaction.c:1343
msgid "Warning: "
msgstr "Advarsel: "

#. translators: This is short for operation, the title of a one-char column
#: app/flatpak-cli-transaction.c:1442
msgid "Op"
msgstr "Ha"

#. Avoid resizing the download column too much,
#. * by making the title as long as typical content
#.
#: app/flatpak-cli-transaction.c:1458 app/flatpak-cli-transaction.c:1503
msgid "partial"
msgstr "delvist"

#: app/flatpak-cli-transaction.c:1535
msgid "Proceed with these changes to the user installation?"
msgstr "Fortsæt med ændringerne til brugerinstallationen?"

#: app/flatpak-cli-transaction.c:1537
msgid "Proceed with these changes to the system installation?"
msgstr "Fortsæt med ændringerne til systeminstallationen?"

#: app/flatpak-cli-transaction.c:1539
#, c-format
msgid "Proceed with these changes to the %s?"
msgstr "Fortsæt med ændringerne til %s?"

#: app/flatpak-cli-transaction.c:1711
msgid "Changes complete."
msgstr "Ændringerne blev gennemført."

#: app/flatpak-cli-transaction.c:1713
msgid "Uninstall complete."
msgstr "Afinstallationen blev gennemført."

#: app/flatpak-cli-transaction.c:1715
msgid "Installation complete."
msgstr "Installationen blev gennemført."

#: app/flatpak-cli-transaction.c:1717
msgid "Updates complete."
msgstr "Opdateringerne blev gennemført."

#. For updates/!stop_on_first_error we already printed all errors so we make up
#. a different one.
#: app/flatpak-cli-transaction.c:1750
msgid "There were one or more errors"
msgstr "Der opstod en eller flere fejl"

#. translators: please keep the leading space
#: app/flatpak-main.c:76
msgid " Manage installed applications and runtimes"
msgstr " Håndter installerede programmer og runtimes"

#: app/flatpak-main.c:77
msgid "Install an application or runtime"
msgstr "Installer et program eller runtime"

#: app/flatpak-main.c:78
msgid "Update an installed application or runtime"
msgstr "Opdater et installeret program eller runtime"

#: app/flatpak-main.c:81
msgid "Uninstall an installed application or runtime"
msgstr "Afinstaller et installeret program eller runtime"

#: app/flatpak-main.c:84
msgid "Mask out updates and automatic installation"
msgstr "Maskér opdateringer og automatisk installation"

#: app/flatpak-main.c:85
msgid "Pin a runtime to prevent automatic removal"
msgstr "Fastgør en runtime for at forhindre automatisk fjernelse"

#: app/flatpak-main.c:86
msgid "List installed apps and/or runtimes"
msgstr "Vis installerede programmer og/eller runtimes"

#: app/flatpak-main.c:87
msgid "Show info for installed app or runtime"
msgstr "Vis information for installeret program eller runtime"

#: app/flatpak-main.c:88
msgid "Show history"
msgstr "Vis historik"

#: app/flatpak-main.c:89
msgid "Configure flatpak"
msgstr "Konfigurer flatpak"

#: app/flatpak-main.c:90
msgid "Repair flatpak installation"
msgstr "Reparer flatpak-installation"

#: app/flatpak-main.c:91
msgid "Put applications or runtimes onto removable media"
msgstr "Læg programmer eller runtimes på flytbart medie"

#: app/flatpak-main.c:92
msgid "Install flatpaks that are part of the operating system"
msgstr ""

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:95
msgid ""
"\n"
" Find applications and runtimes"
msgstr ""
"\n"
" Find programmer og runtimes"

#: app/flatpak-main.c:96
msgid "Search for remote apps/runtimes"
msgstr "Søg efter eksternt programmer/-runtimes"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:99
msgid ""
"\n"
" Manage running applications"
msgstr ""
"\n"
" Håndter kørende programmer"

#: app/flatpak-main.c:100
msgid "Run an application"
msgstr "Kør et program"

#: app/flatpak-main.c:101
msgid "Override permissions for an application"
msgstr "Tilsidesæt tilladelser for et program"

#: app/flatpak-main.c:102
msgid "Specify default version to run"
msgstr "Angiv standardversion som skal køres"

#: app/flatpak-main.c:103
msgid "Enter the namespace of a running application"
msgstr "Indtast navnerummet på et kørende program"

#: app/flatpak-main.c:104
msgid "Enumerate running applications"
msgstr "Oplist kørende programmer"

#: app/flatpak-main.c:105
msgid "Stop a running application"
msgstr "Stop et kørende program"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:108
msgid ""
"\n"
" Manage file access"
msgstr ""
"\n"
" Håndter filadgang"

#: app/flatpak-main.c:109
msgid "List exported files"
msgstr "Vis eksporterede filer"

#: app/flatpak-main.c:110
msgid "Grant an application access to a specific file"
msgstr "Giv et program adgang til en bestemt fil"

#: app/flatpak-main.c:111
msgid "Revoke access to a specific file"
msgstr "Tilbagekald adgang til en bestemt fil"

#: app/flatpak-main.c:112
msgid "Show information about a specific file"
msgstr "Vis information om en bestemt fil"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:116
msgid ""
"\n"
" Manage dynamic permissions"
msgstr ""
"\n"
" Håndter dynamiske tilladelser"

#: app/flatpak-main.c:117
msgid "List permissions"
msgstr "Vis tilladelser"

#: app/flatpak-main.c:118
msgid "Remove item from permission store"
msgstr "Fjern punkt fra tilladelseslager"

#: app/flatpak-main.c:120
msgid "Set permissions"
msgstr "Indstil tilladelser"

#: app/flatpak-main.c:121
msgid "Show app permissions"
msgstr "Vis programtilladelser"

#: app/flatpak-main.c:122
msgid "Reset app permissions"
msgstr "Nulstil programtilladelser"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:125
msgid ""
"\n"
" Manage remote repositories"
msgstr ""
"\n"
" Håndter eksterne depoter"

#: app/flatpak-main.c:126
msgid "List all configured remotes"
msgstr "Vis alle konfigurerede eksterne"

#: app/flatpak-main.c:127
msgid "Add a new remote repository (by URL)"
msgstr "Tilføj et nyt eksternt depot (med URL)"

#: app/flatpak-main.c:128
msgid "Modify properties of a configured remote"
msgstr "Rediger egenskaber for en konfigureret ekstern"

#: app/flatpak-main.c:129
msgid "Delete a configured remote"
msgstr "Slet en konfigureret ekstern"

#: app/flatpak-main.c:131
msgid "List contents of a configured remote"
msgstr "Vis indholdet af en konfigureret ekstern"

#: app/flatpak-main.c:132
msgid "Show information about a remote app or runtime"
msgstr "Vis information om et eksternt program eller -runtime"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:135
msgid ""
"\n"
" Build applications"
msgstr ""
"\n"
" Byg programmer"

#: app/flatpak-main.c:136
msgid "Initialize a directory for building"
msgstr "Initier en mappe til bygning"

#: app/flatpak-main.c:137
msgid "Run a build command inside the build dir"
msgstr "Kør en byggekommando i byggemappen"

#: app/flatpak-main.c:138
msgid "Finish a build dir for export"
msgstr "Færdiggør en byggemappe til eksport"

#: app/flatpak-main.c:139
msgid "Export a build dir to a repository"
msgstr "Eksportér en byggemappe til et depot"

#: app/flatpak-main.c:140
msgid "Create a bundle file from a ref in a local repository"
msgstr "Opret en bundt-fil fra en reference i et lokalt depot"

#: app/flatpak-main.c:141
msgid "Import a bundle file"
msgstr "Importér en bundt-fil"

#: app/flatpak-main.c:142
msgid "Sign an application or runtime"
msgstr "Underskriv et program eller runtime"

#: app/flatpak-main.c:143
msgid "Update the summary file in a repository"
msgstr "Opdater opsummeringsfilen i et depot"

#: app/flatpak-main.c:144
msgid "Create new commit based on existing ref"
msgstr "Opret ny indsendelse baseret på eksisterende reference"

#: app/flatpak-main.c:145
msgid "Show information about a repo"
msgstr "Vis information om et depot"

#: app/flatpak-main.c:162
msgid "Show debug information, -vv for more detail"
msgstr "Vis information om fejlretning, -vv for flere detaljer"

#: app/flatpak-main.c:163
msgid "Show OSTree debug information"
msgstr "Vis information om OSTree-fejlretning"

#: app/flatpak-main.c:169
msgid "Print version information and exit"
msgstr "Udskriv versionsinformation og afslut"

#: app/flatpak-main.c:170
msgid "Print default arch and exit"
msgstr "Udskriv standardarkitektur og afslut"

#: app/flatpak-main.c:171
msgid "Print supported arches and exit"
msgstr "Udskriv understøttede arkitekturer og afslut"

#: app/flatpak-main.c:172
msgid "Print active gl drivers and exit"
msgstr "Udskriv aktive gl-drivere og afslut"

#: app/flatpak-main.c:173
msgid "Print paths for system installations and exit"
msgstr "Udskriv stier for systeminstallationer og afslut"

#: app/flatpak-main.c:174
msgid "Print the updated environment needed to run flatpaks"
msgstr "Udskriv det opdaterede miljø som behøves for at køre flatpaks"

#: app/flatpak-main.c:175
msgid "Only include the system installation with --print-updated-env"
msgstr "Medtag kun systeminstallationen med --print-updated-env"

#: app/flatpak-main.c:180
msgid "Work on the user installation"
msgstr "Arbejd på brugerinstallationen"

#: app/flatpak-main.c:181
msgid "Work on the system-wide installation (default)"
msgstr "Arbejd på den systembrede installation (standard)"

#: app/flatpak-main.c:182
msgid "Work on a non-default system-wide installation"
msgstr "Arbejd på en ikke-standard systembred installation"

#: app/flatpak-main.c:212
msgid "Builtin Commands:"
msgstr "Indbyggede kommandoer:"

#: app/flatpak-main.c:298
#, c-format
msgid ""
"Note that the directories %s are not in the search path set by the "
"XDG_DATA_DIRS environment variable, so applications installed by Flatpak may "
"not appear on your desktop until the session is restarted."
msgstr ""
"Bemærk at mapperne %s ikke er i søgestien som er indstillet af XDG_DATA_DIRS-"
"miljøvariablen, så programmer som er installeret af Flatpak vises måske ikke "
"på dit skrivebord før sessionen genstartes."

#: app/flatpak-main.c:312
#, c-format
msgid ""
"Note that the directory %s is not in the search path set by the "
"XDG_DATA_DIRS environment variable, so applications installed by Flatpak may "
"not appear on your desktop until the session is restarted."
msgstr ""
"Bemærk at mappen %s ikke er i søgestien som er indstillet af XDG_DATA_DIRS-"
"miljøvariablen, så programmer som er installeret af Flatpak vises måske ikke "
"på dit skrivebord før sessionen genstartes."

#: app/flatpak-main.c:381
msgid ""
"Refusing to operate under sudo with --user. Omit sudo to operate on the user "
"installation, or use a root shell to operate on the root user's installation."
msgstr ""

#: app/flatpak-main.c:453
msgid ""
"Multiple installations specified for a command that works on one installation"
msgstr ""
"Flere installationer angivet til en kommando der virker på en installation"

#: app/flatpak-main.c:504 app/flatpak-main.c:697
#, c-format
msgid "See '%s --help'"
msgstr "Se '%s --help'"

#: app/flatpak-main.c:706
#, c-format
msgid "'%s' is not a flatpak command. Did you mean '%s%s'?"
msgstr "'%s' er ikke en flatpak-kommando. Mente du '%s%s'?"

#: app/flatpak-main.c:709
#, c-format
msgid "'%s' is not a flatpak command"
msgstr "'%s' er ikke en flatpak-kommando"

#: app/flatpak-main.c:824
msgid "No command specified"
msgstr "Der er ikke angivet nogen kommando"

#: app/flatpak-main.c:980
msgid "error:"
msgstr "fejl:"

#: app/flatpak-quiet-transaction.c:77
#, c-format
msgid "Installing %s\n"
msgstr "Installerer %s\n"

#: app/flatpak-quiet-transaction.c:81
#, c-format
msgid "Updating %s\n"
msgstr "Opdaterer %s\n"

#: app/flatpak-quiet-transaction.c:85
#, c-format
msgid "Uninstalling %s\n"
msgstr "Afinstallerer %s\n"

#: app/flatpak-quiet-transaction.c:107
#, fuzzy, c-format
msgid "Warning: Failed to install %s: %s\n"
msgstr "%s Kunne ikke %s %s: %s\n"

#: app/flatpak-quiet-transaction.c:110
#, fuzzy, c-format
msgid "Error: Failed to install %s: %s\n"
msgstr "Fejl ved geninstallation af %s: %s\n"

#: app/flatpak-quiet-transaction.c:116
#, fuzzy, c-format
msgid "Warning: Failed to update %s: %s\n"
msgstr "Kan ikke opdatere %s: %s\n"

#: app/flatpak-quiet-transaction.c:119
#, fuzzy, c-format
msgid "Error: Failed to update %s: %s\n"
msgstr "Kan ikke opdatere %s: %s\n"

#: app/flatpak-quiet-transaction.c:125
#, fuzzy, c-format
msgid "Warning: Failed to install bundle %s: %s\n"
msgstr "Kunne ikke rebase %s til %s: %s\n"

#: app/flatpak-quiet-transaction.c:128
#, fuzzy, c-format
msgid "Error: Failed to install bundle %s: %s\n"
msgstr "Fejl ved geninstallation af %s: %s\n"

#: app/flatpak-quiet-transaction.c:134
#, fuzzy, c-format
msgid "Warning: Failed to uninstall %s: %s\n"
msgstr "%s Kunne ikke %s %s: %s\n"

#: app/flatpak-quiet-transaction.c:137
#, fuzzy, c-format
msgid "Error: Failed to uninstall %s: %s\n"
msgstr "Fejl ved geninstallation af %s: %s\n"

#: app/flatpak-quiet-transaction.c:166 common/flatpak-dir.c:11475
#, c-format
msgid "%s already installed"
msgstr "%s er allerede installeret"

#: app/flatpak-quiet-transaction.c:168 common/flatpak-dir.c:3622
#: common/flatpak-dir.c:4321 common/flatpak-dir.c:16968
#: common/flatpak-dir.c:17258 common/flatpak-dir-utils.c:166
#: common/flatpak-dir-utils.c:259 common/flatpak-transaction.c:2736
#: common/flatpak-transaction.c:2791
#, c-format
msgid "%s not installed"
msgstr "%s er ikke installeret"

#: app/flatpak-quiet-transaction.c:170
#, c-format
msgid "%s needs a later flatpak version"
msgstr "%s har brug for en nyere flatpak-version"

#: app/flatpak-quiet-transaction.c:172
msgid "Not enough disk space to complete this operation"
msgstr "Der er ikke nok ledig diskplads til at gennemføre handlingen"

#: app/flatpak-quiet-transaction.c:239
#, c-format
msgid "Info: %s is end-of-life, in favor of %s\n"
msgstr "Info: %s er end-of-life, til fordel for %s\n"

#: app/flatpak-quiet-transaction.c:241
#, c-format
msgid "Info: %s is end-of-life, with reason: %s\n"
msgstr "Info: %s er end-of-life, med årsagen: %s\n"

#: app/flatpak-quiet-transaction.c:251
#, c-format
msgid "Failed to rebase %s to %s: %s\n"
msgstr "Kunne ikke rebase %s til %s: %s\n"

#: common/flatpak-auth.c:58
#, c-format
msgid "No authenticator configured for remote `%s`"
msgstr "Ingen godkender konfigureret for eksternen `%s`"

#: common/flatpak-context.c:637 common/flatpak-context.c:649
#, fuzzy, c-format
msgid "Invalid permission syntax: %s"
msgstr "Ugyldigt udvidelsesnavn %s"

#: common/flatpak-context.c:1207
#, c-format
msgid "Unknown share type %s, valid types are: %s"
msgstr "Ukendt delingstype %s, gyldige typer er: %s"

#: common/flatpak-context.c:1228
#, c-format
msgid "Unknown policy type %s, valid types are: %s"
msgstr "Ukendt politiktype %s, gyldige typer er: %s"

#: common/flatpak-context.c:1266
#, c-format
msgid "Invalid dbus name %s"
msgstr "Ugyldigt dbus-navn %s"

#: common/flatpak-context.c:1279
#, c-format
msgid "Unknown socket type %s, valid types are: %s"
msgstr "Ukendt sokkeltype %s, gyldige typer er: %s"

#: common/flatpak-context.c:1294
#, c-format
msgid "Unknown device type %s, valid types are: %s"
msgstr "Ukendt enhedstype %s, gyldige typer er: %s"

#: common/flatpak-context.c:1308
#, c-format
msgid "Unknown feature type %s, valid types are: %s"
msgstr "Ukendt funktionalitetstype %s, gyldige typer er: %s"

#: common/flatpak-context.c:1840
#, c-format
msgid "Filesystem location \"%s\" contains \"..\""
msgstr "Filsystemsplaceringen \"%s\" indeholder \"..\""

#: common/flatpak-context.c:1882
#, c-format
msgid ""
"--filesystem=/ is not available, use --filesystem=host for a similar result"
msgstr ""
"--filesystem=/ er ikke tilgængelig, brug --filesystem=vært for et lignende "
"resultat"

#: common/flatpak-context.c:1916
#, fuzzy, c-format
msgid ""
"Unknown filesystem location %s, valid locations are: host, host-os, host-"
"etc, host-root, home, xdg-*[/…], ~/dir, /dir"
msgstr ""
"Ukendt filsystemplacering %s, gyldige placeringer er: vært, vært-"
"styresystem, vært-osv., xdg-*[/ …], ~/mappe, /mappe"

#: common/flatpak-context.c:2015
#, fuzzy, c-format
msgid "Invalid syntax for %s: %s"
msgstr "Ugyldigt navn %s: %s"

#: common/flatpak-context.c:2142
#, c-format
msgid "fallback-x11 can not be conditional"
msgstr ""

#: common/flatpak-context.c:2318
#, c-format
msgid "Invalid env format %s"
msgstr "Ugyldigt miljøformat %s"

#: common/flatpak-context.c:2399
#, c-format
msgid "Environment variable name must not contain '=': %s"
msgstr "Miljøvariabelnavn må ikke indeholde '=': %s"

#: common/flatpak-context.c:2527 common/flatpak-context.c:2535
#, c-format
msgid "--add-policy arguments must be in the form SUBSYSTEM.KEY=VALUE"
msgstr "--add-policy-argumenter skal være i formatet UNDERSYSTEM.NØGLE=VÆRDI"

#: common/flatpak-context.c:2542
#, c-format
msgid "--add-policy values can't start with \"!\""
msgstr "--add-policy-værdier må ikke begynde med \"!\""

#: common/flatpak-context.c:2567 common/flatpak-context.c:2575
#, c-format
msgid "--remove-policy arguments must be in the form SUBSYSTEM.KEY=VALUE"
msgstr ""
"--remove-policy-argumenter skal være i formatet UNDERSYSTEM.NØGLE=VÆRDI"

#: common/flatpak-context.c:2582
#, c-format
msgid "--remove-policy values can't start with \"!\""
msgstr "--remove-policy må ikke begynde med \"!\""

#: common/flatpak-context.c:2657
msgid "Share with host"
msgstr "Del med vært"

#: common/flatpak-context.c:2657 common/flatpak-context.c:2658
msgid "SHARE"
msgstr "DEL"

#: common/flatpak-context.c:2658
msgid "Unshare with host"
msgstr "Stop deling med vært"

#: common/flatpak-context.c:2659
msgid "Require conditions to be met for a subsystem to get shared"
msgstr ""

#: common/flatpak-context.c:2659
msgid "SHARE:CONDITION"
msgstr ""

#: common/flatpak-context.c:2660
msgid "Expose socket to app"
msgstr "Eksponer sokkel til program"

#: common/flatpak-context.c:2660 common/flatpak-context.c:2661
msgid "SOCKET"
msgstr "SOKKEL"

#: common/flatpak-context.c:2661
msgid "Don't expose socket to app"
msgstr "Eksponer ikke sokkel til program"

#: common/flatpak-context.c:2662
msgid "Require conditions to be met for a socket to get exposed"
msgstr ""

#: common/flatpak-context.c:2662
msgid "SOCKET:CONDITION"
msgstr ""

#: common/flatpak-context.c:2663
msgid "Expose device to app"
msgstr "Eksponer enhed til program"

#: common/flatpak-context.c:2663 common/flatpak-context.c:2664
msgid "DEVICE"
msgstr "ENHED"

#: common/flatpak-context.c:2664
msgid "Don't expose device to app"
msgstr "Eksponer ikke enhed til program"

#: common/flatpak-context.c:2665
msgid "Require conditions to be met for a device to get exposed"
msgstr ""

#: common/flatpak-context.c:2665
msgid "DEVICE:CONDITION"
msgstr ""

#: common/flatpak-context.c:2666
msgid "Allow feature"
msgstr "Tillad funktionalitet"

#: common/flatpak-context.c:2666 common/flatpak-context.c:2667
msgid "FEATURE"
msgstr "FUNKTIONALITET"

#: common/flatpak-context.c:2667
msgid "Don't allow feature"
msgstr "Tillad ikke funktionalitet"

#: common/flatpak-context.c:2668
msgid "Require conditions to be met for a feature to get allowed"
msgstr ""

#: common/flatpak-context.c:2668
msgid "FEATURE:CONDITION"
msgstr ""

#: common/flatpak-context.c:2669
msgid "Expose filesystem to app (:ro for read-only)"
msgstr "Eksponer filsystem til program (:ro for skrivebeskyttet)"

#: common/flatpak-context.c:2669
msgid "FILESYSTEM[:ro]"
msgstr "FILSYSTEM[:ro]"

#: common/flatpak-context.c:2670
msgid "Don't expose filesystem to app"
msgstr "Eksponer ikke filsystem til program"

#: common/flatpak-context.c:2670
msgid "FILESYSTEM"
msgstr "FILSYSTEM"

#: common/flatpak-context.c:2671
msgid "Set environment variable"
msgstr "Indstil miljøvariabel"

#: common/flatpak-context.c:2671
msgid "VAR=VALUE"
msgstr "VARIABEL=VÆRDI"

# scootergrisen: ved ikke hvad FD er
# scootergrisen: "Læs miljøvariabler i formatet env -0 fra ..."
#: common/flatpak-context.c:2672
msgid "Read environment variables in env -0 format from FD"
msgstr "Læs miljøvariabler i formatet env -0 fra FD"

#: common/flatpak-context.c:2673
msgid "Remove variable from environment"
msgstr "Fjern variabel fra miljø"

#: common/flatpak-context.c:2673
msgid "VAR"
msgstr "VAR"

#: common/flatpak-context.c:2674
msgid "Allow app to own name on the session bus"
msgstr "Giv program tilladelse til eget navn på sessionsbussen"

#: common/flatpak-context.c:2674 common/flatpak-context.c:2675
#: common/flatpak-context.c:2676 common/flatpak-context.c:2677
#: common/flatpak-context.c:2678 common/flatpak-context.c:2679
#: common/flatpak-context.c:2680
msgid "DBUS_NAME"
msgstr "DBUS_NAVN"

#: common/flatpak-context.c:2675
msgid "Allow app to talk to name on the session bus"
msgstr "Giv program tilladelse til at snakke med navn på sessionsbussen"

#: common/flatpak-context.c:2676
msgid "Don't allow app to talk to name on the session bus"
msgstr "Giv ikke program tilladelse til at snakke med navn på sessionsbussen"

#: common/flatpak-context.c:2677
msgid "Allow app to own name on the system bus"
msgstr "Giv program tilladelse til eget navn på systembussen"

#: common/flatpak-context.c:2678
msgid "Allow app to talk to name on the system bus"
msgstr "Giv program tilladelse til at snakke med navn på systembussen"

#: common/flatpak-context.c:2679
msgid "Don't allow app to talk to name on the system bus"
msgstr "Giv ikke program tilladelse til at snakke med navn på systembussen"

#: common/flatpak-context.c:2680
#, fuzzy
msgid "Allow app to own name on the a11y bus"
msgstr "Giv program tilladelse til eget navn på systembussen"

#: common/flatpak-context.c:2681
msgid "Add generic policy option"
msgstr "Tilføj tilvalg for generisk politik"

#: common/flatpak-context.c:2681 common/flatpak-context.c:2682
msgid "SUBSYSTEM.KEY=VALUE"
msgstr "UNDERSYSTEM.NØGLE=VÆRDI"

#: common/flatpak-context.c:2682
msgid "Remove generic policy option"
msgstr "Fjern tilvalg for generisk politik"

#: common/flatpak-context.c:2683
msgid "Add USB device to enumerables"
msgstr ""

#: common/flatpak-context.c:2683 common/flatpak-context.c:2684
msgid "VENDOR_ID:PRODUCT_ID"
msgstr ""

#: common/flatpak-context.c:2684
msgid "Add USB device to hidden list"
msgstr ""

#: common/flatpak-context.c:2685
msgid "A list of USB devices that are enumerable"
msgstr ""

#: common/flatpak-context.c:2685
msgid "LIST"
msgstr ""

#: common/flatpak-context.c:2686
msgid "File containing a list of USB devices to make enumerable"
msgstr ""

#: common/flatpak-context.c:2686 common/flatpak-context.c:2687
msgid "FILENAME"
msgstr "FILNAVN"

#: common/flatpak-context.c:2687
msgid "Persist home directory subpath"
msgstr "Vedvarende understi for hjemmemappe"

#. This is not needed/used anymore, so hidden, but we accept it for backwards compat
#: common/flatpak-context.c:2689
msgid "Don't require a running session (no cgroups creation)"
msgstr "Kræv ikke en kørende session (ingen cgroups-oprettelse)"

#: common/flatpak-context.c:3718
#, c-format
msgid "Not replacing \"%s\" with tmpfs: %s"
msgstr ""

#: common/flatpak-context.c:3726
#, c-format
msgid "Not sharing \"%s\" with sandbox: %s"
msgstr ""

#. Even if the error is one that we would normally silence, like
#. * the path not existing, it seems reasonable to make more of a fuss
#. * about the home directory not existing or otherwise being unusable,
#. * so this is intentionally not using cannot_export()
#: common/flatpak-context.c:3828
#, c-format
msgid "Not allowing home directory access: %s"
msgstr ""

#: common/flatpak-context.c:4062
#, fuzzy, c-format
msgid "Unable to provide a temporary home directory in the sandbox: %s"
msgstr "Kan ikke oprette midlertidig mappe i %s"

#: common/flatpak-dir.c:442
#, c-format
msgid "Configured collection ID ‘%s’ not in summary file"
msgstr "Konfigurerede samlings-id ‘%s’ ikke i opsummeringsfil"

#: common/flatpak-dir.c:587
#, c-format
msgid "Unable to load summary from remote %s: %s"
msgstr "Kan ikke indlæse opsummering fra eksternen %s: %s"

#: common/flatpak-dir.c:764 common/flatpak-dir.c:800 common/flatpak-dir.c:906
#, c-format
msgid "No such ref '%s' in remote %s"
msgstr "Ingen sådan reference '%s' i eksternen %s"

#: common/flatpak-dir.c:891 common/flatpak-dir.c:1051 common/flatpak-dir.c:1080
#: common/flatpak-dir.c:1092
#, fuzzy, c-format
msgid "No entry for %s in remote %s summary flatpak cache"
msgstr ""
"Ingen post for %s i mellemlager til opsummerings-flatpak for eksternen '%s' "

#: common/flatpak-dir.c:1069
#, c-format
msgid "No summary or Flatpak cache available for remote %s"
msgstr ""
"Ingen opsummering eller Flatpak-mellemlager tilgængelig for eksternen %s"

#: common/flatpak-dir.c:1097
#, c-format
msgid "Missing xa.data in summary for remote %s"
msgstr "Manglende xa.data i opsummering for eksternen %s"

#: common/flatpak-dir.c:1103 common/flatpak-dir.c:1546
#, c-format
msgid "Unsupported summary version %d for remote %s"
msgstr "Uunderstøttet opsummeringsversion %d for eksternen %s"

#: common/flatpak-dir.c:1200
msgid "Remote OCI index has no registry uri"
msgstr "Eksternt OCI-indeks har ikke nogen register-uri"

#: common/flatpak-dir.c:1261
#, c-format
msgid "Couldn't find ref %s in remote %s"
msgstr "Kunne ikke finde referencen %s i eksternen %s"

#: common/flatpak-dir.c:1288 common/flatpak-dir.c:1381
#, fuzzy, c-format
msgid "Commit has no requested ref ‘%s’ in ref binding metadata (found: ‘%s’)"
msgstr ""
"Indsendelse har ikke nogen anmodet reference ‘%s’ i metadata for "
"referencebinding"

#: common/flatpak-dir.c:1413
#, c-format
msgid "Configured collection ID ‘%s’ not in binding metadata"
msgstr "Konfigurerede samlings-id ‘%s’ ikke i metadata for binding"

#: common/flatpak-dir.c:1449 common/flatpak-dir.c:5645
#, c-format
msgid "Couldn't find latest checksum for ref %s in remote %s"
msgstr "Kunne ikke finde seneste checksum for referencen %s i eksternen %s"

#: common/flatpak-dir.c:1516 common/flatpak-dir.c:1552
#, fuzzy, c-format
msgid "No entry for %s in remote %s summary flatpak sparse cache"
msgstr ""
"Ingen post for %s i mellemlager til opsummerings-flatpak-sparse for "
"eksternen "

#: common/flatpak-dir.c:2540
#, c-format
msgid "Commit metadata for %s not matching expected metadata"
msgstr "Indsendelsesmetadata for %s matcher ikke ventede metadata"

#: common/flatpak-dir.c:2823
msgid "Unable to connect to system bus"
msgstr "Kan ikke oprette forbindelse til systembus"

#: common/flatpak-dir.c:3419
msgid "User installation"
msgstr "Brugerinstallation"

#: common/flatpak-dir.c:3426
#, c-format
msgid "System (%s) installation"
msgstr "System (%s) -installation"

#: common/flatpak-dir.c:3472
#, c-format
msgid "No overrides found for %s"
msgstr "Ingen tilsidesættelser fundet for %s"

#: common/flatpak-dir.c:3625
#, c-format
msgid "%s (commit %s) not installed"
msgstr "%s (indsendelsen %s) er ikke installeret"

#: common/flatpak-dir.c:4650
#, c-format
msgid "Error parsing system flatpakrepo file for %s: %s"
msgstr "Fejl ved fortolkning af systemets flatpakrepo-fil til %s: %s"

#: common/flatpak-dir.c:4735
#, c-format
msgid "While opening repository %s: "
msgstr "Ved åbning af depotet %s: "

#: common/flatpak-dir.c:5004
#, c-format
msgid "The config key %s is not set"
msgstr "Konfigurationsnøglen %s er ikke indstillet"

#: common/flatpak-dir.c:5140
#, c-format
msgid "No current %s pattern matching %s"
msgstr "Ingen nuværende %s mønster matcher %s"

#: common/flatpak-dir.c:5422
msgid "No appstream commit to deploy"
msgstr "Ingen appstream-indsendelse som skal udsendes"

#: common/flatpak-dir.c:5941 common/flatpak-dir.c:7266
#: common/flatpak-dir.c:10881 common/flatpak-dir.c:11618
msgid "Can't pull from untrusted non-gpg verified remote"
msgstr "Kan ikke pull fra ubetroet eksterne som ikke er gpg-verificeret"

#: common/flatpak-dir.c:6376 common/flatpak-dir.c:6591
msgid "Extra data not supported for non-gpg-verified local system installs"
msgstr ""
"Ekstra-data understøttes ikke for lokale systeminstallationer som ikke er "
"gpg-verificeret"

#: common/flatpak-dir.c:6415 common/flatpak-dir.c:6782
#, c-format
msgid "Invalid checksum for extra data uri %s"
msgstr "Ugyldig checksum for ekstra-data-uri'en %s"

#: common/flatpak-dir.c:6424
#, c-format
msgid "Empty name for extra data uri %s"
msgstr "Tomt navn for ekstra-data-uri'en %s"

#: common/flatpak-dir.c:6432
#, c-format
msgid "Unsupported extra data uri %s"
msgstr "Uunderstøttet ekstra-data-uri %s"

#: common/flatpak-dir.c:6461
#, c-format
msgid "Failed to load local extra-data %s: %s"
msgstr "Kunne ikke indlæse lokal extra-data %s: %s"

#: common/flatpak-dir.c:6469
#, c-format
msgid "Wrong size for extra-data %s"
msgstr "Forkert størrelse for extra-data %s"

#: common/flatpak-dir.c:6488
#, c-format
msgid "While downloading %s: "
msgstr "Ved download af %s: "

#: common/flatpak-dir.c:6498
#, c-format
msgid "Wrong size for extra data %s"
msgstr "Forkert størrelse for ekstra-data %s"

#: common/flatpak-dir.c:6507
#, c-format
msgid "Invalid checksum for extra data %s"
msgstr "Ugyldig checksum for ekstra-data %s"

#: common/flatpak-dir.c:7096 common/flatpak-dir.c:7349
#, c-format
msgid "While pulling %s from remote %s: "
msgstr "Ved pulling af %s fra eksternen %s: "

#: common/flatpak-dir.c:7290 common/flatpak-repo-utils.c:3886
msgid "GPG signatures found, but none are in trusted keyring"
msgstr "Fandt GPG-underskrifter, men ingen af dem i betroet nøglering"

#: common/flatpak-dir.c:7307
#, c-format
msgid "Commit for ‘%s’ has no ref binding"
msgstr "Indsendelse til ‘%s’ har ikke nogen referencebinding"

#: common/flatpak-dir.c:7312
#, c-format
msgid "Commit for ‘%s’ is not in expected bound refs: %s"
msgstr ""
"Indsendelse til ‘%s’ er ikke indenfor ventede afgrænsningsreferencer: %s"

#: common/flatpak-dir.c:7488
msgid "Only applications can be made current"
msgstr "Kun programmer kan gøres nuværende"

#: common/flatpak-dir.c:8192
msgid "Not enough memory"
msgstr "Ikke nok hukommelse"

#: common/flatpak-dir.c:8211
msgid "Failed to read from exported file"
msgstr "Kunne ikke låse fra eksporteret fil"

#: common/flatpak-dir.c:8401
msgid "Error reading mimetype xml file"
msgstr "Fejl ved læsning af mimetype-xml-fil"

#: common/flatpak-dir.c:8406
msgid "Invalid mimetype xml file"
msgstr "Ugyldig mimetype-xml-fil"

#: common/flatpak-dir.c:8492
#, c-format
msgid "D-Bus service file '%s' has wrong name"
msgstr "D-Bus-tjenestefilen '%s' har forkert navn"

#: common/flatpak-dir.c:8647
#, c-format
msgid "Invalid Exec argument %s"
msgstr "Ugyldigt Exec-argument %s"

#: common/flatpak-dir.c:9115
msgid "While getting detached metadata: "
msgstr "Ved hentning af løsrevet metadata: "

#: common/flatpak-dir.c:9120 common/flatpak-dir.c:9125
#: common/flatpak-dir.c:9129
msgid "Extra data missing in detached metadata"
msgstr "Ekstra-data mangler i løsrevet metadata"

#: common/flatpak-dir.c:9133
msgid "While creating extradir: "
msgstr "Ved oprettelse af ekstra-mappe: "

#: common/flatpak-dir.c:9154 common/flatpak-dir.c:9187
msgid "Invalid checksum for extra data"
msgstr "Ugyldig checksum for ekstra-data"

#: common/flatpak-dir.c:9183
msgid "Wrong size for extra data"
msgstr "Forkert størrelse for ekstra-data"

#: common/flatpak-dir.c:9196
#, c-format
msgid "While writing extra data file '%s': "
msgstr "Ved skrivning af ekstra-data-filen '%s': "

#: common/flatpak-dir.c:9204
#, c-format
msgid "Extra data %s missing in detached metadata"
msgstr "Ekstra-data %s mangler i løsrevet metadata"

#: common/flatpak-dir.c:9278
#, fuzzy, c-format
msgid "Unable to get runtime key from metadata"
msgstr "Brug alternativ fil til metadataene"

#: common/flatpak-dir.c:9402
#, c-format
msgid "apply_extra script failed, exit status %d"
msgstr "apply_extra-script mislykkedes, afslutningsstatus %d"

#. Translators: The placeholder is for an app ref.
#: common/flatpak-dir.c:9591
#, c-format
msgid "Installing %s is not allowed by the policy set by your administrator"
msgstr ""
"Installation af %s er ikke tilladt af politikken som er indstillet af din "
"administrator"

#: common/flatpak-dir.c:9690
#, c-format
msgid "While trying to resolve ref %s: "
msgstr "Ved forsøg på løsning af referencen %s: "

#: common/flatpak-dir.c:9702
#, c-format
msgid "%s is not available"
msgstr "%s er ikke tilgængelig"

#: common/flatpak-dir.c:9714 common/flatpak-dir.c:11495
#, c-format
msgid "%s commit %s already installed"
msgstr "%s indsendelsen %s er allerede installeret"

#: common/flatpak-dir.c:9721
msgid "Can't create deploy directory"
msgstr "Kan ikke oprette udsendelsesmappe"

#: common/flatpak-dir.c:9729
#, c-format
msgid "Failed to read commit %s: "
msgstr "Kunne ikke læse indsendelsen %s: "

#: common/flatpak-dir.c:9750
#, c-format
msgid "While trying to checkout %s into %s: "
msgstr "Ved forsøg på checkout af %s i %s: "

#: common/flatpak-dir.c:9769
msgid "While trying to checkout metadata subpath: "
msgstr "Ved forsøg på checkout af metadata-understi: "

#: common/flatpak-dir.c:9801
#, c-format
msgid "While trying to checkout subpath ‘%s’: "
msgstr "Ved forsøg på checkout af understien ‘%s’: "

#: common/flatpak-dir.c:9811
msgid "While trying to remove existing extra dir: "
msgstr "Ved forsøg på fjernelse af eksisterende ekstra-mappe: "

#: common/flatpak-dir.c:9822
msgid "While trying to apply extra data: "
msgstr "Ved forsøg på anvendelse af ekstra-data: "

#: common/flatpak-dir.c:9849
#, c-format
msgid "Invalid commit ref %s: "
msgstr "Ugyldig indsend-reference %s: "

#: common/flatpak-dir.c:9857 common/flatpak-dir.c:9869
#, c-format
msgid "Deployed ref %s does not match commit (%s)"
msgstr "Udsendt reference %s matcher ikke indsendelse (%s)"

#: common/flatpak-dir.c:9863
#, c-format
msgid "Deployed ref %s branch does not match commit (%s)"
msgstr "Udsendt reference %s gren matcher ikke indsendelse (%s)"

#: common/flatpak-dir.c:10125 common/flatpak-installation.c:1911
#, c-format
msgid "%s branch %s already installed"
msgstr "%s grenen %s er allerede installeret"

#: common/flatpak-dir.c:10985
#, c-format
msgid "Could not unmount revokefs-fuse filesystem at %s: "
msgstr "Kunne ikke afmontere filsystemet revokefs-fuse på %s: "

#: common/flatpak-dir.c:11289
#, c-format
msgid "This version of %s is already installed"
msgstr "Versionen af %s er allerede installeret"

#: common/flatpak-dir.c:11302
#, c-format
msgid "Can't change remote during bundle install"
msgstr "Kan ikke skifte eksterne under installation af bundt"

#: common/flatpak-dir.c:11571
msgid "Can't update to a specific commit without root permissions"
msgstr "Kan ikke opdatere en bestemt indsendelse uden root-tilladelser"

#: common/flatpak-dir.c:11852
#, c-format
msgid "Can't remove %s, it is needed for: %s"
msgstr "Kan ikke fjerne %s, da den behøves af: %s"

#: common/flatpak-dir.c:11912 common/flatpak-installation.c:2067
#, c-format
msgid "%s branch %s is not installed"
msgstr "%s grenen %s er ikke installeret"

#: common/flatpak-dir.c:12165
#, c-format
msgid "%s commit %s not installed"
msgstr "%s indsendelsen %s er ikke installeret"

#: common/flatpak-dir.c:12501
#, c-format
msgid "Pruning repo failed: %s"
msgstr "Beskæring af depot mislykkedes: %s"

#: common/flatpak-dir.c:12669 common/flatpak-dir.c:12675
#, c-format
msgid "Failed to load filter '%s'"
msgstr "Kunne ikke indlæse filteret '%s'"

#: common/flatpak-dir.c:12681
#, c-format
msgid "Failed to parse filter '%s'"
msgstr "Kunne ikke fortolke filteret '%s'"

#: common/flatpak-dir.c:12963
msgid "Failed to write summary cache: "
msgstr "Kunne ikke skrive opsummeringsmellemlager: "

#: common/flatpak-dir.c:12982
#, c-format
msgid "No oci summary cached for remote '%s'"
msgstr "Ingen oci-opsummering mellemlagret for eksternen '%s'"

#: common/flatpak-dir.c:13207
#, c-format
msgid "No cached summary for remote '%s'"
msgstr "Ingen mellemlagret opsummering for eksternen '%s'"

#: common/flatpak-dir.c:13248
#, fuzzy, c-format
msgid "Invalid checksum for indexed summary %s read from %s"
msgstr "Ugyldig checksum for indekseret opsummering %s for eksternen '%s'"

#: common/flatpak-dir.c:13321
#, c-format
msgid ""
"Remote listing for %s not available; server has no summary file. Check the "
"URL passed to remote-add was valid."
msgstr ""
"Visning af eksterne for %s er ikke tilgængelig; serveren har ikke nogen "
"opsummeringsfil. Tjek at URL'en som blev givet til remote-add er gyldig."

#: common/flatpak-dir.c:13698
#, c-format
msgid "Invalid checksum for indexed summary %s for remote '%s'"
msgstr "Ugyldig checksum for indekseret opsummering %s for eksternen '%s'"

#: common/flatpak-dir.c:14388
#, c-format
msgid "Multiple branches available for %s, you must specify one of: "
msgstr "Flere grene tilgængelige for %s, du skal angive en af: "

#: common/flatpak-dir.c:14454
#, c-format
msgid "Nothing matches %s"
msgstr "Intet matcher %s"

#: common/flatpak-dir.c:14562
#, c-format
msgid "Can't find ref %s%s%s%s%s"
msgstr "Kan ikke finde referencen %s%s%s%s%s"

#: common/flatpak-dir.c:14605
#, c-format
msgid "Error searching remote %s: %s"
msgstr "Fejl ved søgning efter eksternen %s: %s"

#: common/flatpak-dir.c:14702
#, c-format
msgid "Error searching local repository: %s"
msgstr "Fejl ved søgning i lokalt depot: %s"

#: common/flatpak-dir.c:14839
#, c-format
msgid "%s/%s/%s not installed"
msgstr "%s/%s/%s er ikke installeret"

#: common/flatpak-dir.c:15042
#, c-format
msgid "Could not find installation %s"
msgstr "Kunne ikke finde installationen %s"

#: common/flatpak-dir.c:15612
#, c-format
msgid "Invalid file format, no %s group"
msgstr "Ugyldigt filformat, ingen %s gruppe"

#: common/flatpak-dir.c:15617 common/flatpak-repo-utils.c:2836
#, c-format
msgid "Invalid version %s, only 1 supported"
msgstr "Ugyldig version %s, understøtter kun 1"

#: common/flatpak-dir.c:15622 common/flatpak-dir.c:15627
#, c-format
msgid "Invalid file format, no %s specified"
msgstr "Ugyldigt filformat, ingen %s angivet"

#. Check some minimal size so we don't get crap
#: common/flatpak-dir.c:15647
msgid "Invalid file format, gpg key invalid"
msgstr "Ugyldigt filformat, gpg-nøglen er ugyldig"

#: common/flatpak-dir.c:15675 common/flatpak-repo-utils.c:2917
msgid "Collection ID requires GPG key to be provided"
msgstr "Samlings-id'et kræver levering af GPG-nøgle"

#: common/flatpak-dir.c:15718
#, c-format
msgid "Runtime %s, branch %s is already installed"
msgstr "Runtimen %s, grenen %s er allerede installeret"

#: common/flatpak-dir.c:15719
#, c-format
msgid "App %s, branch %s is already installed"
msgstr "Programmet %s, grenen %s er allerede installeret"

#: common/flatpak-dir.c:15953
#, c-format
msgid "Can't remove remote '%s' with installed ref %s (at least)"
msgstr ""
"Kan ikke fjerne eksternen '%s' med installerede reference %s (som det "
"mindste)"

#: common/flatpak-dir.c:16058
#, c-format
msgid "Invalid character '/' in remote name: %s"
msgstr "Ugyldigt tegn '/' i navn for eksterne: %s"

#: common/flatpak-dir.c:16064
#, c-format
msgid "No configuration for remote %s specified"
msgstr "Der er ikke angivet nogen konfiguration for eksternen %s"

#: common/flatpak-dir.c:17597
#, c-format
msgid "Skipping deletion of mirror ref (%s, %s)…\n"
msgstr "Springer over sletning af spejlreference (%s, %s) …\n"

#: common/flatpak-exports.c:931
#, c-format
msgid "An absolute path is required"
msgstr ""

#: common/flatpak-exports.c:948
#, fuzzy, c-format
msgid "Unable to open path \"%s\": %s"
msgstr "Kan ikke opdatere %s: %s\n"

#: common/flatpak-exports.c:955
#, fuzzy, c-format
msgid "Unable to get file type of \"%s\": %s"
msgstr "Kan ikke oprette filen %s"

#: common/flatpak-exports.c:964
#, c-format
msgid "File \"%s\" has unsupported type 0o%o"
msgstr ""

#: common/flatpak-exports.c:970
#, c-format
msgid "Unable to get filesystem information for \"%s\": %s"
msgstr ""

#: common/flatpak-exports.c:980
#, c-format
msgid "Ignoring blocking autofs path \"%s\""
msgstr ""

#: common/flatpak-exports.c:996 common/flatpak-exports.c:1009
#: common/flatpak-exports.c:1022
#, c-format
msgid "Path \"%s\" is reserved by Flatpak"
msgstr ""

#: common/flatpak-exports.c:1076
#, fuzzy, c-format
msgid "Unable to resolve symbolic link \"%s\": %s"
msgstr "Kan ikke opdatere symbolsk link %s/%s"

#: common/flatpak-glib-backports.c:69
msgid "Empty string is not a number"
msgstr "Tom streng er ikke et tal"

#: common/flatpak-glib-backports.c:95
#, c-format
msgid "“%s” is not an unsigned number"
msgstr "“%s” er ikke et tal uden fortegn"

#: common/flatpak-glib-backports.c:105
#, c-format
msgid "Number “%s” is out of bounds [%s, %s]"
msgstr "Tallet “%s” er uden for afgrænsningerne [%s, %s]"

#: common/flatpak-image-source.c:83
msgid "Only sha256 image checksums are supported"
msgstr ""

#: common/flatpak-image-source.c:100 common/flatpak-image-source.c:108
msgid "Image is not a manifest"
msgstr "Aftrykket er ikke et manifest"

#: common/flatpak-image-source.c:123
msgid "No org.flatpak.ref found in image"
msgstr ""

#: common/flatpak-image-source.c:148
#, c-format
msgid "Ref '%s' not found in registry"
msgstr "Referencen '%s' blev ikke fundet i registeret"

#: common/flatpak-image-source.c:157
msgid "Multiple images in registry, specify a ref with --ref"
msgstr "Flere aftryk i registeret, angiv en reference med --ref"

#: common/flatpak-installation.c:834
#, c-format
msgid "Ref %s not installed"
msgstr "Referencen %s er ikke installeret"

#: common/flatpak-installation.c:875
#, c-format
msgid "App %s not installed"
msgstr "Programmet %s er ikke installeret"

#: common/flatpak-installation.c:1395
#, c-format
msgid "Remote '%s' already exists"
msgstr "Eksternen '%s' findes allerede"

#: common/flatpak-installation.c:1946
#, c-format
msgid "As requested, %s was only pulled, but not installed"
msgstr "Som anmodet, blev %s kun pulled, men ikke installeret"

#: common/flatpak-instance.c:533 common/flatpak-instance.c:687
#: common/flatpak-instance.c:728
#, c-format
msgid "Unable to create directory %s"
msgstr "Kan ikke oprette mappen %s"

#: common/flatpak-instance.c:554
#, c-format
msgid "Unable to lock %s"
msgstr "Kan ikke låse %s"

#: common/flatpak-instance.c:627
#, c-format
msgid "Unable to create temporary directory in %s"
msgstr "Kan ikke oprette midlertidig mappe i %s"

#: common/flatpak-instance.c:639
#, c-format
msgid "Unable to create file %s"
msgstr "Kan ikke oprette filen %s"

#: common/flatpak-instance.c:646
#, c-format
msgid "Unable to update symbolic link %s/%s"
msgstr "Kan ikke opdatere symbolsk link %s/%s"

#: common/flatpak-oci-registry.c:1197
msgid "Only Bearer authentication supported"
msgstr "Kun Bearer-godkendelse understøttes"

#: common/flatpak-oci-registry.c:1206
msgid "Only realm in authentication request"
msgstr "Kun realm i godkendelsesanmodning"

#: common/flatpak-oci-registry.c:1213
msgid "Invalid realm in authentication request"
msgstr "Ugyldig realm i godkendelsesanmodning"

#: common/flatpak-oci-registry.c:1283
#, c-format
msgid "Authorization failed: %s"
msgstr "Godkendelse mislykkedes: %s"

#: common/flatpak-oci-registry.c:1285
msgid "Authorization failed"
msgstr "Godkendelse mislykkedes"

#: common/flatpak-oci-registry.c:1289
#, c-format
msgid "Unexpected response status %d when requesting token: %s"
msgstr "Uventet svarstatus %d ved anmodning af token: %s"

#: common/flatpak-oci-registry.c:1300
msgid "Invalid authentication request response"
msgstr "Ugyldigt svar fra godkendelsesanmodning"

#: common/flatpak-oci-registry.c:1731
#, c-format
msgid "Flatpak was compiled without zstd support"
msgstr ""

#: common/flatpak-oci-registry.c:1923 common/flatpak-oci-registry.c:1975
#: common/flatpak-oci-registry.c:2004 common/flatpak-oci-registry.c:2059
#: common/flatpak-oci-registry.c:2115 common/flatpak-oci-registry.c:2193
msgid "Invalid delta file format"
msgstr "Ugyldigt deltafilformat"

#: common/flatpak-oci-registry.c:3198 common/flatpak-oci-registry.c:3382
msgid "Invalid OCI image config"
msgstr "Ugyldig konfiguration for OCI-aftryk"

#: common/flatpak-oci-registry.c:3260 common/flatpak-oci-registry.c:3531
#, c-format
msgid "Wrong layer checksum, expected %s, was %s"
msgstr "Forkert lag-checksum, ventede %s, var %s"

#: common/flatpak-oci-registry.c:3359
#, c-format
msgid "No ref specified for OCI image %s"
msgstr "Ingen reference angivet for OCI-aftrykket %s"

#: common/flatpak-oci-registry.c:3369
#, c-format
msgid "Wrong ref (%s) specified for OCI image %s, expected %s"
msgstr "Forkert reference (%s) angivet for OCI-aftrykket %s, ventede %s"

#: common/flatpak-progress.c:236
#, c-format
msgid "Downloading metadata: %u/(estimating) %s"
msgstr "Downloader metadata: %u/(estimeret) %s"

#: common/flatpak-progress.c:260
#, c-format
msgid "Downloading: %s/%s"
msgstr "Downloader: %s/%s"

#: common/flatpak-progress.c:280
#, c-format
msgid "Downloading extra data: %s/%s"
msgstr "Downloader ekstra-data: %s/%s"

#: common/flatpak-progress.c:285
#, c-format
msgid "Downloading files: %d/%d %s"
msgstr "Downloader filer: %d/%d %s"

#: common/flatpak-ref-utils.c:122
msgid "Name can't be empty"
msgstr "Navnet må ikke være tomt"

#: common/flatpak-ref-utils.c:129
msgid "Name can't be longer than 255 characters"
msgstr "Navnet må ikke være længere end 255 tegn"

#: common/flatpak-ref-utils.c:142
msgid "Name can't start with a period"
msgstr "Navnet må ikke begynde med et punktum"

#: common/flatpak-ref-utils.c:148
#, c-format
msgid "Name can't start with %c"
msgstr "Navnet må ikke begynde med %c"

#: common/flatpak-ref-utils.c:164
msgid "Name can't end with a period"
msgstr "Navnet må ikke slutte med et punktum"

#: common/flatpak-ref-utils.c:171 common/flatpak-ref-utils.c:183
msgid "Only last name segment can contain -"
msgstr "Kun det sidste navnesegment må indeholde -"

#: common/flatpak-ref-utils.c:174
#, c-format
msgid "Name segment can't start with %c"
msgstr "Navnesegmentet må ikke begynde med %c"

#: common/flatpak-ref-utils.c:186
#, c-format
msgid "Name can't contain %c"
msgstr "Navnet må ikke indeholde %c"

#: common/flatpak-ref-utils.c:195
msgid "Names must contain at least 2 periods"
msgstr "Navne skal indeholde mindst 2 punktummer"

#: common/flatpak-ref-utils.c:312
msgid "Arch can't be empty"
msgstr "Arkitektur må ikke være tom"

#: common/flatpak-ref-utils.c:323
#, c-format
msgid "Arch can't contain %c"
msgstr "Arkitektur må ikke indeholde %c"

#: common/flatpak-ref-utils.c:385
msgid "Branch can't be empty"
msgstr "Grenen må ikke være tom"

#: common/flatpak-ref-utils.c:395
#, c-format
msgid "Branch can't start with %c"
msgstr "Grenen må ikke begynde med %c"

#: common/flatpak-ref-utils.c:405
#, c-format
msgid "Branch can't contain %c"
msgstr "Grenen må ikke indeholde %c"

#: common/flatpak-ref-utils.c:615 common/flatpak-ref-utils.c:865
msgid "Ref too long"
msgstr "Reference for lang"

#: common/flatpak-ref-utils.c:627
msgid "Invalid remote name"
msgstr "Ugyldig navn for eksterne"

#: common/flatpak-ref-utils.c:641
#, c-format
msgid "%s is not application or runtime"
msgstr "%s er ikke et program eller runtime"

#: common/flatpak-ref-utils.c:650 common/flatpak-ref-utils.c:667
#: common/flatpak-ref-utils.c:683
#, c-format
msgid "Wrong number of components in %s"
msgstr "Forkert antal komponenter i %s"

#: common/flatpak-ref-utils.c:656
#, c-format
msgid "Invalid name %.*s: %s"
msgstr "Ugyldigt navn %.*s: %s"

#: common/flatpak-ref-utils.c:673
#, c-format
msgid "Invalid arch: %.*s: %s"
msgstr "Ugyldig arkitektur: %.*s: %s"

#: common/flatpak-ref-utils.c:816
#, c-format
msgid "Invalid name %s: %s"
msgstr "Ugyldigt navn %s: %s"

#: common/flatpak-ref-utils.c:834
#, c-format
msgid "Invalid arch: %s: %s"
msgstr "Ugyldig arkitektur: %s: %s"

#: common/flatpak-ref-utils.c:853
#, c-format
msgid "Invalid branch: %s: %s"
msgstr "Ugyldig gren: %s: %s"

#: common/flatpak-ref-utils.c:962 common/flatpak-ref-utils.c:970
#: common/flatpak-ref-utils.c:978
#, c-format
msgid "Wrong number of components in partial ref %s"
msgstr "Forkert antal komponenter i delvis reference %s"

#: common/flatpak-ref-utils.c:1298
msgid " development platform"
msgstr " udviklingsplatform"

#: common/flatpak-ref-utils.c:1300
msgid " platform"
msgstr " platform"

# scootergrisen: " programgrund"
# scootergrisen: " programbase"
# scootergrisen: måske noget med grundlæggende
#: common/flatpak-ref-utils.c:1302
msgid " application base"
msgstr " programbase"

#: common/flatpak-ref-utils.c:1305
msgid " debug symbols"
msgstr " fejlretningssymboler"

#: common/flatpak-ref-utils.c:1307
msgid " sourcecode"
msgstr " kildekode"

#: common/flatpak-ref-utils.c:1309
msgid " translations"
msgstr " oversættelser"

#: common/flatpak-ref-utils.c:1311
msgid " docs"
msgstr " dokumentationer"

#: common/flatpak-ref-utils.c:1578
#, c-format
msgid "Invalid id %s: %s"
msgstr "Ugyldigt id %s: %s"

#: common/flatpak-remote.c:1216
#, c-format
msgid "Bad remote name: %s"
msgstr "Dårligt navn for eksterne: %s"

#: common/flatpak-remote.c:1220
#, fuzzy
msgid "No URL specified"
msgstr "Ingen url angivet"

#: common/flatpak-remote.c:1266
msgid "GPG verification must be enabled when a collection ID is set"
msgstr "GPG-verifikation skal være aktiveret når et samlings-id indstilles"

#: common/flatpak-repo-utils.c:344
#, c-format
msgid "No extra data sources"
msgstr "Ingen ekstra-data-kilder"

#: common/flatpak-repo-utils.c:2817
#, c-format
msgid "Invalid %s: Missing group ‘%s’"
msgstr "Ugyldig %s: Mangler gruppen ‘%s’"

#: common/flatpak-repo-utils.c:2826
#, c-format
msgid "Invalid %s: Missing key ‘%s’"
msgstr "Ugyldig %s: Mangler nøglen ‘%s’"

#: common/flatpak-repo-utils.c:2876
msgid "Invalid gpg key"
msgstr "Ugyldig gpg-nøgle"

#: common/flatpak-repo-utils.c:3217
#, c-format
msgid "Error copying 64x64 icon for component %s: %s\n"
msgstr "Fejl ved kopiering af 64x64-ikon for komponenten %s: %s\n"

#: common/flatpak-repo-utils.c:3223
#, c-format
msgid "Error copying 128x128 icon for component %s: %s\n"
msgstr "Fejl ved kopiering af 128x128-ikon for komponenten %s: %s\n"

#: common/flatpak-repo-utils.c:3362
#, c-format
msgid "%s is end-of-life, ignoring for appstream"
msgstr "%s er end-of-life, ignorerer for appstream"

#: common/flatpak-repo-utils.c:3397
#, c-format
msgid "No appstream data for %s: %s\n"
msgstr "Ingen appstream-data for %s: %s\n"

#: common/flatpak-repo-utils.c:3744
msgid "Invalid bundle, no ref in metadata"
msgstr "Ugyldig bundt, ingen reference i metadata"

#: common/flatpak-repo-utils.c:3846
#, c-format
msgid "Collection ‘%s’ of bundle doesn’t match collection ‘%s’ of remote"
msgstr "Samlingen ‘%s’ af bundt matcher ikke samlingen ‘%s’ af ekstern"

#: common/flatpak-repo-utils.c:3923
msgid "Metadata in header and app are inconsistent"
msgstr "Metadata i header og program er uoverensstemmende"

#: common/flatpak-run.c:951
msgid "No systemd user session available, cgroups not available"
msgstr "Ingen systemd-brugersession tilgængelig, cgroups er ikke tilgængelig"

#: common/flatpak-run.c:1496
msgid "Unable to allocate instance id"
msgstr "Kan ikke allokere instans-id"

#: common/flatpak-run.c:1632 common/flatpak-run.c:1641
#, c-format
msgid "Failed to open flatpak-info file: %s"
msgstr "Kunne ikke åbne flatpak-info-filen: %s"

#: common/flatpak-run.c:1668
#, c-format
msgid "Failed to open bwrapinfo.json file: %s"
msgstr "Kunne ikke åbne bwrapinfo.json-filen: %s"

# scootergrisen: tjek oversættelsen af "instance id fd"
#: common/flatpak-run.c:1689
#, c-format
msgid "Failed to write to instance id fd: %s"
msgstr "Kunne ikke skrive instans-id fd: %s"

#: common/flatpak-run.c:2096
msgid "Initialize seccomp failed"
msgstr "Initiering af seccomp mislykkedes"

#: common/flatpak-run.c:2135
#, fuzzy, c-format
msgid "Failed to add architecture to seccomp filter: %s"
msgstr "Kunne ikke tilføje arkitektur til seccomp-filter"

#: common/flatpak-run.c:2143
#, fuzzy, c-format
msgid "Failed to add multiarch architecture to seccomp filter: %s"
msgstr "Kunne ikke tilføje multiarch-arkitektur til seccomp-filter"

#: common/flatpak-run.c:2175 common/flatpak-run.c:2192
#: common/flatpak-run.c:2214
#, fuzzy, c-format
msgid "Failed to block syscall %d: %s"
msgstr "Kunne ikke blokere syskaldet %d"

#: common/flatpak-run.c:2247
#, fuzzy, c-format
msgid "Failed to export bpf: %s"
msgstr "Kunne ikke eksportere bpf"

#: common/flatpak-run.c:2587
#, c-format
msgid "Failed to open ‘%s’"
msgstr "Kunne ikke åbne ‘%s’"

#: common/flatpak-run.c:2597
#, c-format
msgid ""
"Directory forwarding needs version 4 of the document portal (have version %d)"
msgstr ""

#: common/flatpak-run.c:2915
#, c-format
msgid "ldconfig failed, exit status %d"
msgstr "ldconfig mislykkedes, afslutningsstatus %d"

#: common/flatpak-run.c:2922
msgid "Can't open generated ld.so.cache"
msgstr "Kan ikke åbne genererede ld.so.cache"

#. Translators: The placeholder is for an app ref.
#: common/flatpak-run.c:3045
#, c-format
msgid "Running %s is not allowed by the policy set by your administrator"
msgstr ""
"Kørsel af %s er ikke tilladt af politikken som er indstillet af din "
"administrator"

#: common/flatpak-run.c:3202
msgid ""
"\"flatpak run\" is not intended to be run as `sudo flatpak run`. Use `sudo "
"-i` or `su -l` instead and invoke \"flatpak run\" from inside the new shell."
msgstr ""

#: common/flatpak-run.c:3413
#, c-format
msgid "Failed to migrate from %s: %s"
msgstr "Kunne ikke migrere fra %s: %s"

#: common/flatpak-run.c:3434
#, c-format
msgid "Failed to migrate old app data directory %s to new name %s: %s"
msgstr ""
"Kunne ikke migrere den gamle programdatamappe %s til det nye navn %s: %s"

#: common/flatpak-run.c:3443
#, c-format
msgid "Failed to create symlink while migrating %s: %s"
msgstr "Kunne ikke oprette symlink under migrering af %s: %s"

#: common/flatpak-run-dbus.c:46
msgid "Failed to open app info file"
msgstr "Kunne ikke åbne programinfo-fil"

#: common/flatpak-run-dbus.c:149
msgid "Unable to create sync pipe"
msgstr "Kan ikke oprette synkroniseringsledning"

#: common/flatpak-run-dbus.c:185
msgid "Failed to sync with dbus proxy"
msgstr "Kunne ikke synkronisere med dbus-proxy"

#: common/flatpak-transaction.c:2275
#, c-format
msgid "Warning: Problem looking for related refs: %s"
msgstr "Advarsel: Problem ved søgning efter relaterede referencer: %s"

#: common/flatpak-transaction.c:2493
#, c-format
msgid "The application %s requires the runtime %s which was not found"
msgstr "Programmet %s kræver runtimen %s som ikke blev fundet"

#: common/flatpak-transaction.c:2509
#, c-format
msgid "The application %s requires the runtime %s which is not installed"
msgstr "Programmet %s kræver runtimen %s som ikke er installeret"

#: common/flatpak-transaction.c:2641
#, c-format
msgid "Can't uninstall %s which is needed by %s"
msgstr "Kan ikke afinstallere %s som behøves af %s"

#: common/flatpak-transaction.c:2740
#, c-format
msgid "Remote %s disabled, ignoring %s update"
msgstr "Eksternen %s er deaktiveret, ignorerer opdatering af %s"

#: common/flatpak-transaction.c:2773
#, c-format
msgid "%s is already installed"
msgstr "%s er allerede installeret"

#: common/flatpak-transaction.c:2776
#, c-format
msgid "%s is already installed from remote %s"
msgstr "%s er allerede installeret fra eksternen %s"

#: common/flatpak-transaction.c:3120
#, c-format
msgid "Invalid .flatpakref: %s"
msgstr "Ugyldig .flatpakref: %s"

#: common/flatpak-transaction.c:3161
msgid "Warning: Could not mark already installed apps as preinstalled"
msgstr ""

#: common/flatpak-transaction.c:3382
#, c-format
msgid "Error updating remote metadata for '%s': %s"
msgstr "Fejl ved opdatering af metadata af eksterne for '%s': %s"

#: common/flatpak-transaction.c:3885
#, c-format
msgid ""
"Warning: Treating remote fetch error as non-fatal since %s is already "
"installed: %s"
msgstr ""
"Advarsel: Behandler fejl ved fetch af eksterne som ikke-fatale eftersom %s "
"allerede er installeret: %s"

#: common/flatpak-transaction.c:4209
#, c-format
msgid "No authenticator installed for remote '%s'"
msgstr "Ingen godkender installeret for eksternen '%s'"

#: common/flatpak-transaction.c:4313 common/flatpak-transaction.c:4320
#, c-format
msgid "Failed to get tokens for ref: %s"
msgstr "Kunne ikke hente tokens for reference: %s"

#: common/flatpak-transaction.c:4315 common/flatpak-transaction.c:4322
msgid "Failed to get tokens for ref"
msgstr "Kunne ikke hente tokens for reference"

#: common/flatpak-transaction.c:4580
#, c-format
msgid "Ref %s from %s matches more than one transaction operation"
msgstr ""

#: common/flatpak-transaction.c:4581 common/flatpak-transaction.c:4591
#, fuzzy
msgid "any remote"
msgstr "Ekstern"

#: common/flatpak-transaction.c:4590
#, c-format
msgid "No transaction operation found for ref %s from %s"
msgstr ""

#: common/flatpak-transaction.c:4713
#, c-format
msgid "Flatpakrepo URL %s not file, HTTP or HTTPS"
msgstr "Flatpakrepo-URL'en %s er ikke file, HTTP eller HTTPS"

#: common/flatpak-transaction.c:4719
#, c-format
msgid "Can't load dependent file %s: "
msgstr "Kan ikke indlæse afhængig fil %s: "

#: common/flatpak-transaction.c:4727
#, c-format
msgid "Invalid .flatpakrepo: %s"
msgstr "Ugyldig .flatpakrepo: %s"

#: common/flatpak-transaction.c:5454
msgid "Transaction already executed"
msgstr "Transaktionen er allerede udført"

#: common/flatpak-transaction.c:5469
msgid ""
"Refusing to operate on a user installation as root! This can lead to "
"incorrect file ownership and permission errors."
msgstr ""
"Nægter er operere på en brugerinstallation som root! Det kan lede til fejl "
"om ukorrekt filejerskab og -tilladelse."

#: common/flatpak-transaction.c:5567 common/flatpak-transaction.c:5580
msgid "Aborted by user"
msgstr "Afbrudt af bruger"

#: common/flatpak-transaction.c:5605
#, c-format
msgid "Skipping %s due to previous error"
msgstr "Springer over %s pga. tidligere fejl"

#: common/flatpak-transaction.c:5659
#, c-format
msgid "Aborted due to failure (%s)"
msgstr "Afbrudt pga. fejl (%s)"

#: common/flatpak-uri.c:118
#, fuzzy, no-c-format
msgid "Invalid %-encoding in URI"
msgstr "Ugyldigt udvidelsesnavn %s"

#: common/flatpak-uri.c:135
msgid "Illegal character in URI"
msgstr ""

#: common/flatpak-uri.c:169
msgid "Non-UTF-8 characters in URI"
msgstr ""

#: common/flatpak-uri.c:275
#, c-format
msgid "Invalid IPv6 address ‘%.*s’ in URI"
msgstr ""

#: common/flatpak-uri.c:330
#, c-format
msgid "Illegal encoded IP address ‘%.*s’ in URI"
msgstr ""

#: common/flatpak-uri.c:342
#, c-format
msgid "Illegal internationalized hostname ‘%.*s’ in URI"
msgstr ""

#: common/flatpak-uri.c:374 common/flatpak-uri.c:386
#, fuzzy, c-format
msgid "Could not parse port ‘%.*s’ in URI"
msgstr "Kunne ikke fortolke '%s'"

#: common/flatpak-uri.c:393
#, c-format
msgid "Port ‘%.*s’ in URI is out of range"
msgstr ""

#: common/flatpak-uri.c:910
msgid "URI is not absolute, and no base URI was provided"
msgstr ""

#: common/flatpak-usb.c:83
#, c-format
msgid "USB device query 'all' must not have data"
msgstr ""

#: common/flatpak-usb.c:102
#, c-format
msgid "USB query rule 'cls' must be in the form CLASS:SUBCLASS or CLASS:*"
msgstr ""

#: common/flatpak-usb.c:111
#, fuzzy, c-format
msgid "Invalid USB class"
msgstr "Ugyldigt id %s: %s"

#: common/flatpak-usb.c:125
#, c-format
msgid "Invalid USB subclass"
msgstr ""

#: common/flatpak-usb.c:141 common/flatpak-usb.c:148
#, c-format
msgid "USB query rule 'dev' must have a valid 4-digit hexadecimal product id"
msgstr ""

#: common/flatpak-usb.c:164 common/flatpak-usb.c:171
#, c-format
msgid "USB query rule 'vnd' must have a valid 4-digit hexadecimal vendor id"
msgstr ""

#: common/flatpak-usb.c:205
#, c-format
msgid "USB device queries must be in the form TYPE:DATA"
msgstr ""

#: common/flatpak-usb.c:225
#, c-format
msgid "Unknown USB query rule %s"
msgstr ""

#: common/flatpak-usb.c:248
#, c-format
msgid "Empty USB query"
msgstr ""

#: common/flatpak-usb.c:274
#, c-format
msgid "Multiple USB query rules of the same type is not supported"
msgstr ""

#: common/flatpak-usb.c:283
#, c-format
msgid "'all' must not contain extra query rules"
msgstr ""

#: common/flatpak-usb.c:291
#, c-format
msgid "USB queries with 'dev' must also specify vendors"
msgstr ""

#: common/flatpak-utils.c:712
msgid "Glob can't match apps"
msgstr "Glob kan ikke matche programmer"

#: common/flatpak-utils.c:737
msgid "Empty glob"
msgstr "Tom glob"

#: common/flatpak-utils.c:756
msgid "Too many segments in glob"
msgstr "For mange argumenter i glob"

#: common/flatpak-utils.c:777
#, c-format
msgid "Invalid glob character '%c'"
msgstr "Ugyldigt glob-tegn '%c'"

#: common/flatpak-utils.c:831
#, c-format
msgid "Missing glob on line %d"
msgstr "Manglende glob på linje %d"

#: common/flatpak-utils.c:835
#, c-format
msgid "Trailing text on line %d"
msgstr "Efterstillet tekst på linje %d"

#: common/flatpak-utils.c:839
#, c-format
msgid "on line %d"
msgstr "på linje %d"

#: common/flatpak-utils.c:861
#, c-format
msgid "Unexpected word '%s' on line %d"
msgstr "Uventet ord '%s' på linje %d"

#: common/flatpak-utils.c:2118
#, c-format
msgid "Invalid require-flatpak argument %s"
msgstr "Ugyldigt require-flatpak-argument %s"

#: common/flatpak-utils.c:2128 common/flatpak-utils.c:2147
#, c-format
msgid "%s needs a later flatpak version (%s)"
msgstr "%s har brug for en nyere flatpak-version (%s)"

#: oci-authenticator/flatpak-oci-authenticator.c:291
msgid "Not a oci remote, missing summary.xa.oci-repository"
msgstr "Ikke en oci-eksterne — manglende summary.xa.oci-repository"

#: oci-authenticator/flatpak-oci-authenticator.c:477
msgid "Not a OCI remote"
msgstr "Ikke en OCI-eksterne"

#: oci-authenticator/flatpak-oci-authenticator.c:488
msgid "Invalid token"
msgstr "Ugyldig token"

#: portal/flatpak-portal.c:2292
#, c-format
msgid "No portal support found"
msgstr "Fandt ingen understøttelse af portal"

#: portal/flatpak-portal.c:2298
msgid "Deny"
msgstr "Nægt"

#: portal/flatpak-portal.c:2300
msgid "Update"
msgstr "Opdater"

#: portal/flatpak-portal.c:2305
#, c-format
msgid "Update %s?"
msgstr "Opdater %s?"

#: portal/flatpak-portal.c:2317
msgid "The application wants to update itself."
msgstr "Programmet vil gerne opdatere sig selv."

#: portal/flatpak-portal.c:2318
msgid "Update access can be changed any time from the privacy settings."
msgstr ""
"Opdateringsadgang kan ændres når som helst fra privatlivsindstillingerne."

#: portal/flatpak-portal.c:2343
#, c-format
msgid "Application update not allowed"
msgstr "Programopdatering ikke tilladt"

#: portal/flatpak-portal.c:2501
#, c-format
msgid "Self update not supported, new version requires new permissions"
msgstr "Selvopdatering understøttes ikke – ny version kræver nye tilladelser"

#: portal/flatpak-portal.c:2684 portal/flatpak-portal.c:2702
#, c-format
msgid "Update ended unexpectedly"
msgstr "Opdatering sluttede uventet"

#. SECURITY:
#. - Normal users need admin authentication to install software
#. system-wide.
#. - Note that we install polkit rules that allow local users
#. in the wheel group to install without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:23
msgid "Install signed application"
msgstr "Installer underskrevet program"

#: system-helper/org.freedesktop.Flatpak.policy.in:24
#: system-helper/org.freedesktop.Flatpak.policy.in:42
msgid "Authentication is required to install software"
msgstr "Der kræves godkendelse for at installere software"

#. SECURITY:
#. - Normal users need admin authentication to install software
#. system-wide.
#. - Note that we install polkit rules that allow local users
#. in the wheel group to install without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:41
msgid "Install signed runtime"
msgstr "Installer underskrevet runtime"

#. SECURITY:
#. - Normal users do not require admin authentication to update an
#. app as the commit will be signed, and the action is required
#. to update the system when unattended.
#. - Changing this to anything other than 'yes' will break unattended
#. updates.
#: system-helper/org.freedesktop.Flatpak.policy.in:60
msgid "Update signed application"
msgstr "Opdater underskrevet program"

#: system-helper/org.freedesktop.Flatpak.policy.in:61
#: system-helper/org.freedesktop.Flatpak.policy.in:80
msgid "Authentication is required to update software"
msgstr "Der kræves godkendelse for at opdatere software"

#. SECURITY:
#. - Normal users do not require admin authentication to update a
#. runtime as the commit will be signed, and the action is required
#. to update the system when unattended.
#. - Changing this to anything other than 'yes' will break unattended
#. updates.
#: system-helper/org.freedesktop.Flatpak.policy.in:79
msgid "Update signed runtime"
msgstr "Opdater underskrevet runtime"

#. SECURITY:
#. - Normal users do not need authentication to update metadata
#. from signed repositories.
#: system-helper/org.freedesktop.Flatpak.policy.in:94
msgid "Update remote metadata"
msgstr "Opdater metadata for eksterne"

#: system-helper/org.freedesktop.Flatpak.policy.in:95
msgid "Authentication is required to update remote info"
msgstr "Der kræves godkendelse for at opdatere information for eksterne"

#. SECURITY:
#. - Normal users do not need authentication to modify the
#. OSTree repository
#. - Note that we install polkit rules that allow local users
#. in the wheel group to modify repos without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:111
msgid "Update system repository"
msgstr "Opdater systemdepot"

#: system-helper/org.freedesktop.Flatpak.policy.in:112
msgid "Authentication is required to modify a system repository"
msgstr "Der kræves godkendelse for at ændre et systemdepot"

#. SECURITY:
#. - Normal users need admin authentication to install software
#. system-wide.
#: system-helper/org.freedesktop.Flatpak.policy.in:126
msgid "Install bundle"
msgstr "Installer bundt"

#: system-helper/org.freedesktop.Flatpak.policy.in:127
msgid "Authentication is required to install software from $(path)"
msgstr "Der kræves godkendelse for at installere software fra $(path)"

#. SECURITY:
#. - Normal users need admin authentication to uninstall software
#. system-wide.
#. - Note that we install polkit rules that allow local users
#. in the wheel group to uninstall without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:144
msgid "Uninstall runtime"
msgstr "Afinstaller runtime"

#: system-helper/org.freedesktop.Flatpak.policy.in:145
msgid "Authentication is required to uninstall software"
msgstr "Der kræves godkendelse for at afinstallere software"

#. SECURITY:
#. - Normal users need admin authentication to uninstall software
#. system-wide.
#. - Note that we install polkit rules that allow local users
#. in the wheel group to uninstall without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:161
msgid "Uninstall app"
msgstr "Afinstaller program"

#: system-helper/org.freedesktop.Flatpak.policy.in:162
msgid "Authentication is required to uninstall $(ref)"
msgstr "Der kræves godkendelse for at afinstallere $(ref)"

#. SECURITY:
#. - Normal users need admin authentication to configure system-wide
#. software repositories.
#: system-helper/org.freedesktop.Flatpak.policy.in:177
msgid "Configure Remote"
msgstr "Konfigurer ekstern"

#: system-helper/org.freedesktop.Flatpak.policy.in:178
msgid "Authentication is required to configure software repositories"
msgstr "Der kræves godkendelse for at konfigurere softwaredepoter"

#. SECURITY:
#. - Normal users need admin authentication to configure the system-wide
#. Flatpak installation.
#: system-helper/org.freedesktop.Flatpak.policy.in:192
msgid "Configure"
msgstr "Konfigurer"

#: system-helper/org.freedesktop.Flatpak.policy.in:193
msgid "Authentication is required to configure software installation"
msgstr "Der kræves godkendelse for at konfigurere softwareinstallation"

#. SECURITY:
#. - Normal users do not require admin authentication to update
#. appstream data as it will be signed, and the action is required
#. to update the system when unattended.
#. - Changing this to anything other than 'yes' will break unattended
#. updates.
#: system-helper/org.freedesktop.Flatpak.policy.in:210
msgid "Update appstream"
msgstr "Opdater appstream"

#: system-helper/org.freedesktop.Flatpak.policy.in:211
msgid "Authentication is required to update information about software"
msgstr "Der kræves godkendelse for at opdatere information om software"

#. SECURITY:
#. - Normal users do not require admin authentication to update
#. metadata as it will be signed, and the action is required
#. to update the system when unattended.
#. - Changing this to anything other than 'yes' will break unattended
#. updates.
#: system-helper/org.freedesktop.Flatpak.policy.in:228
msgid "Update metadata"
msgstr "Opdater metadata"

#: system-helper/org.freedesktop.Flatpak.policy.in:229
msgid "Authentication is required to update metadata"
msgstr "Der kræves godkendelse for at opdatere metadata"

#. SECURITY:
#. - Authorisation to actually install software is controlled by
#. org.freedesktop.Flatpak.app-install.
#. - This action is checked after app-install, as it can only be done
#. once the app’s data (including its content rating) has been
#. downloaded.
#. - This action is checked to see if the installation should be allowed
#. based on whether the app being installed has content which doesn’t
#. comply with the user’s parental controls policy (the content is
#. ‘too extreme’).
#. - It is checked only if an app has too extreme content for the user
#. who is trying to install it (in which case, the app is ‘unsafe’).
#. - Typically, normal users will need admin permission to install apps
#. with extreme content; admins will be able to install it without
#. additional checks.
#. - In order to configure the policy so that admins can install safe and
#. unsafe software anywhere without authorisation, and non-admins can
#. install safe software in their user or system dirs without
#. authorisation, but need authorisation to install unsafe software
#. anywhere:
#. * Unconditionally return `yes` from `app-install`.
#. * Return `auth_admin` from `override-parental-controls` for users
#. not in `@privileged_group@`, and `yes` for users in it.
#. * Set the malcontent `is-{user,system}-installation-allowed`
#. properties of all non-admins’ parental controls policies to true.
#. - In order to configure the policy so that admins can install safe and
#. unsafe software anywhere without authorisation, and non-admins can
#. install safe software in their user dir without authorisation, but
#. need authorisation to install safe software in the system dir or to
#. install unsafe software anywhere:
#. * Unconditionally return `yes` from `app-install`.
#. * Return `auth_admin` from `override-parental-controls` for users
#. not in `@privileged_group@`, and `yes` for users in it.
#. * Set the malcontent `is-user-installation-allowed` property of all
#. non-admins’ parental controls policies to true.
#. * Set the malcontent `is-system-installation-allowed` property of
#. all non-admins’ parental controls policies to false.
#. - In order to configure the policy so that all users (including
#. admins) can install safe software anywhere without authorisation,
#. but need authorisation to install unsafe software anywhere (i.e.
#. applying parental controls to admins too):
#. * Unconditionally return `yes` from `app-install`.
#. * Unconditionally return `auth_admin` from `override-parental-controls`.
#. * Set the malcontent `is-user-installation-allowed` property of all
#. users’ parental controls policies to true.
#. * Set the malcontent `is-system-installation-allowed` property of
#. all users’ parental controls policies to true.
#: system-helper/org.freedesktop.Flatpak.policy.in:287
#, fuzzy
msgid "Override parental controls for installs"
msgstr "Tilsidesæt forælderstyringer"

#: system-helper/org.freedesktop.Flatpak.policy.in:288
msgid ""
"Authentication is required to install software which is restricted by your "
"parental controls policy"
msgstr ""
"Der kræves godkendelse for at installere software som er begrænset af din "
"politik for forælderstyringer"

#. SECURITY:
#. - This is like org.freedesktop.Flatpak.override-parental-controls, but
#. it’s queried for app updates, whereas the former is queried for app
#. installs.
#. - As with the above action, this one is only queried if
#. org.freedesktop.Flatpak.app-update has allowed the app update, and
#. only if the app being updated has too extreme content for the user
#. who is trying to update it.
#. - The default policy for this is to *allow* updates to ‘too extreme’
#. apps by default, on the basis that having an out-of-date (i.e.
#. insecure or unsupported) app is a worse outcome than automatically
#. installing an update which has radically different content from the
#. version of the app which the parent originally vetted and installed.
#: system-helper/org.freedesktop.Flatpak.policy.in:313
#, fuzzy
msgid "Override parental controls for updates"
msgstr "Tilsidesæt forælderstyringer"

#: system-helper/org.freedesktop.Flatpak.policy.in:314
#, fuzzy
msgid ""
"Authentication is required to update software which is restricted by your "
"parental controls policy"
msgstr ""
"Der kræves godkendelse for at installere software som er begrænset af din "
"politik for forælderstyringer"

#~ msgid "Installed:"
#~ msgstr "Installeret:"

#~ msgid "Download:"
#~ msgstr "Download:"

#, c-format
#~ msgid "No gpg key found with ID %s (homedir: %s)"
#~ msgstr "Ingen gpg-nøgle fundet med id'et %s (hjemmemappe: %s)"

#, fuzzy, c-format
#~ msgid "Unable to lookup key ID %s: %d"
#~ msgstr "Kan ikke opslå nøgle-id'et %s: %d)"

#, c-format
#~ msgid "Error signing commit: %d"
#~ msgstr "Fejl ved underskrivning af indsendelse: %d"

#, c-format
#~ msgid ""
#~ "Found similar ref(s) for ‘%s’ in remote ‘%s’ (%s).\n"
#~ "Use this remote?"
#~ msgstr ""
#~ "Fandt lignende reference(r) for ‘%s’ i eksternen ‘%s’ (%s).\n"
#~ "Brug eksternen?"

#, c-format
#~ msgid "No entry for %s in remote '%s' summary cache "
#~ msgstr "Ingen post for %s i mellemlager til opsummering for eksternen '%s' "

#, fuzzy, c-format
#~ msgid "Failed to uninstall %s for rebase to %s: "
#~ msgstr "Kunne ikke rebase %s til %s: "

#, fuzzy, c-format
#~ msgid "Failed to uninstall %s for rebase to %s: %s\n"
#~ msgstr "Kunne ikke rebase %s til %s: %s\n"

#, c-format
#~ msgid "Unable to open directory %s"
#~ msgstr "Kan ikke åbne mappen %s"

#~ msgid "install"
#~ msgstr "installer"

#~ msgid "update"
#~ msgstr "opdater"

#~ msgid "install bundle"
#~ msgstr "installer bundt"

#~ msgid "uninstall"
#~ msgstr "afinstaller"

#~ msgid "(internal error, please report)"
#~ msgstr "(intern fejl — rapportér det venligst)"

#~ msgid "Warning:"
#~ msgstr "Advarsel:"

#, fuzzy
#~ msgid "runtime"
#~ msgstr "Runtime"

#, fuzzy
#~ msgid "app"
#~ msgstr "Program"

#~ msgid "[REF…] - Uninstall an application"
#~ msgstr "[REFERENCE …] - Afinstaller et program"

#, c-format
#~ msgid "Replace it with %s?"
#~ msgstr "Erstat den med %s?"

#~ msgid "\"flatpak run\" is not intended to be ran with sudo"
#~ msgstr "\"flatpak run\" er ikke beregnet til at blive kørt med sudo"

===== ./po/LINGUAS =====
bg
cs
da
de
en_GB
eo
es
fr
gl
hi
hr
hu
id
ka
kk
nl
oc
pl
pt
pt_BR
ro
ru
sk
sl
sr
sv
tr
uk
zh_CN
zh_TW

===== ./po/Makevars =====
# Makefile variables for PO directory in any package using GNU gettext.

# Usually the message domain is the same as the package name.
DOMAIN = $(PACKAGE)

# These two variables depend on the location of this directory.
subdir = po
top_builddir = ..

# These options get passed to xgettext.
XGETTEXT_OPTIONS = --from-code=UTF-8 --keyword=_ --keyword=N_ --keyword=C_:1c,2 --keyword=NC_:1c,2 --keyword=g_dngettext:2,3 --add-comments

# This is the copyright holder that gets inserted into the header of the
# $(DOMAIN).pot file.  Set this to the copyright holder of the surrounding
# package.  (Note that the msgstr strings, extracted from the package's
# sources, belong to the copyright holder of the package.)  Translators are
# expected to transfer the copyright for their translations to this person
# or entity, or to disclaim their copyright.  The empty string stands for
# the public domain; in this case the translators are expected to disclaim
# their copyright.
COPYRIGHT_HOLDER = Flatpak team and others.

# This is the email address or URL to which the translators shall report
# bugs in the untranslated strings:
# - Strings which are not entire sentences, see the maintainer guidelines
#   in the GNU gettext documentation, section 'Preparing Strings'.
# - Strings which use unclear terms or require additional context to be
#   understood.
# - Strings which make invalid assumptions about notation of date, time or
#   money.
# - Pluralisation problems.
# - Incorrect English spelling.
# - Incorrect formatting.
# It can be your email address, or a mailing list address where translators
# can write to without being subscribed, or the URL of a web page through
# which the translators can contact you.
MSGID_BUGS_ADDRESS = https://github.com/flatpak/flatpak/issues

# This is the list of locale categories, beyond LC_MESSAGES, for which the
# message catalogs shall be used.  It is usually empty.
EXTRA_LOCALE_CATEGORIES =

# This tells whether the $(DOMAIN).pot file contains messages with an 'msgctxt'
# context.  Possible values are "yes" and "no".  Set this to yes if the
# package uses functions taking also a message context, like pgettext(), or
# if in $(XGETTEXT_OPTIONS) you define keywords with a context argument.
USE_MSGCTXT = yes

# These options get passed to msgmerge.
# Useful options are in particular:
#   --previous            to keep previous msgids of translated messages,
#   --quiet               to reduce the verbosity.
MSGMERGE_OPTIONS =

# These options get passed to msginit.
# If you want to disable line wrapping when writing PO files, add
# --no-wrap to MSGMERGE_OPTIONS, XGETTEXT_OPTIONS, and
# MSGINIT_OPTIONS.
MSGINIT_OPTIONS =

# This tells whether or not to regenerate a PO file when $(DOMAIN).pot
# has changed.  Possible values are "yes" and "no".  Set this to no if
# the POT file is checked in the repository and the version control
# program ignores timestamps.
PO_DEPENDS_ON_POT = no

# This tells whether or not to forcibly update $(DOMAIN).pot and
# regenerate PO files on "make dist".  Possible values are "yes" and
# "no".  Set this to no if the POT file and PO files are maintained
# externally.
DIST_DEPENDS_ON_UPDATE_PO = no

===== ./po/pl.po =====
# Polish translation for flatpak.
# Copyright © 2016-2025 the flatpak authors.
# This file is distributed under the same license as the flatpak package.
# Piotr Drąg <piotrdrag@gmail.com>, 2016-2025.
# Aviary.pl <community-poland@mozilla.org>, 2016-2025.
#
msgid ""
msgstr ""
"Project-Id-Version: flatpak\n"
"Report-Msgid-Bugs-To: https://github.com/flatpak/flatpak/issues\n"
"POT-Creation-Date: 2026-05-27 16:39+0200\n"
"PO-Revision-Date: 2025-08-27 18:42+0200\n"
"Last-Translator: Piotr Drąg <piotrdrag@gmail.com>\n"
"Language-Team: Polish <community-poland@mozilla.org>\n"
"Language: pl\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 "
"|| n%100>=20) ? 1 : 2);\n"

#: app/flatpak-builtins-build-bundle.c:59
msgid "Export runtime instead of app"
msgstr "Eksportuje środowisko wykonawcze zamiast programu"

#: app/flatpak-builtins-build-bundle.c:60
msgid "Arch to bundle for"
msgstr "Architektura pakietu"

#: app/flatpak-builtins-build-bundle.c:60
#: app/flatpak-builtins-build-export.c:62 app/flatpak-builtins-build-init.c:53
#: app/flatpak-builtins-build-sign.c:42 app/flatpak-builtins-create-usb.c:46
#: app/flatpak-builtins-info.c:55 app/flatpak-builtins-install.c:67
#: app/flatpak-builtins-list.c:50 app/flatpak-builtins-make-current.c:38
#: app/flatpak-builtins-remote-info.c:54 app/flatpak-builtins-remote-ls.c:56
#: app/flatpak-builtins-run.c:158 app/flatpak-builtins-search.c:37
#: app/flatpak-builtins-uninstall.c:54 app/flatpak-builtins-update.c:56
msgid "ARCH"
msgstr "ARCHITEKTURA"

#: app/flatpak-builtins-build-bundle.c:61
#, fuzzy
msgid "URL for repo"
msgstr "Adres URL do repozytorium"

#: app/flatpak-builtins-build-bundle.c:61
#: app/flatpak-builtins-build-bundle.c:62
#: app/flatpak-builtins-build-update-repo.c:68
#: app/flatpak-builtins-build-update-repo.c:72
#: app/flatpak-builtins-build-update-repo.c:73
#: app/flatpak-builtins-history.c:69 app/flatpak-builtins-remote-add.c:80
#: app/flatpak-builtins-remote-add.c:81 app/flatpak-builtins-remote-add.c:85
#: app/flatpak-builtins-remote-list.c:53
#: app/flatpak-builtins-remote-modify.c:70
#: app/flatpak-builtins-remote-modify.c:85
#: app/flatpak-builtins-remote-modify.c:86
#: app/flatpak-builtins-remote-modify.c:90
msgid "URL"
msgstr "URL"

#: app/flatpak-builtins-build-bundle.c:62
#, fuzzy
msgid "URL for runtime flatpakrepo file"
msgstr "Adres URL do pliku repozytorium Flatpak środowiska wykonawczego"

#: app/flatpak-builtins-build-bundle.c:63
msgid "Add GPG key from FILE (- for stdin)"
msgstr "Dodaje klucz GPG z PLIKU (- dla standardowego wejścia)"

#: app/flatpak-builtins-build-bundle.c:63 app/flatpak-builtins-build.c:54
#: app/flatpak-builtins-build-export.c:67
#: app/flatpak-builtins-build-update-repo.c:83
#: app/flatpak-builtins-install.c:81 app/flatpak-builtins-remote-add.c:84
#: app/flatpak-builtins-remote-add.c:86 app/flatpak-builtins-remote-modify.c:89
#: app/flatpak-builtins-remote-modify.c:92
msgid "FILE"
msgstr "PLIK"

#: app/flatpak-builtins-build-bundle.c:64
msgid "GPG Key ID to sign the OCI image with"
msgstr "Identyfikator klucza GPG do podpisania obrazu OCI"

#: app/flatpak-builtins-build-bundle.c:64
#: app/flatpak-builtins-build-commit-from.c:68
#: app/flatpak-builtins-build-export.c:68
#: app/flatpak-builtins-build-import-bundle.c:49
#: app/flatpak-builtins-build-sign.c:44
#: app/flatpak-builtins-build-update-repo.c:84
msgid "KEY-ID"
msgstr "IDENTYFIKATOR-KLUCZA"

#: app/flatpak-builtins-build-bundle.c:65
#: app/flatpak-builtins-build-commit-from.c:69
#: app/flatpak-builtins-build-export.c:71
#: app/flatpak-builtins-build-import-bundle.c:50
#: app/flatpak-builtins-build-sign.c:45
#: app/flatpak-builtins-build-update-repo.c:85
msgid "GPG Homedir to use when looking for keyrings"
msgstr "Katalog domowy GPG do wyszukiwania baz kluczy"

#: app/flatpak-builtins-build-bundle.c:65
#: app/flatpak-builtins-build-commit-from.c:69
#: app/flatpak-builtins-build-export.c:71
#: app/flatpak-builtins-build-import-bundle.c:50
#: app/flatpak-builtins-build-sign.c:45
#: app/flatpak-builtins-build-update-repo.c:85
msgid "HOMEDIR"
msgstr "KATALOG-DOMOWY"

#: app/flatpak-builtins-build-bundle.c:66
msgid "OSTree commit to create a delta bundle from"
msgstr "Zatwierdzenie OSTree, z którego utworzyć pakiet delty"

#: app/flatpak-builtins-build-bundle.c:66 app/flatpak-builtins-remote-info.c:55
#: app/flatpak-builtins-update.c:57
msgid "COMMIT"
msgstr "ZATWIERDZENIE"

#: app/flatpak-builtins-build-bundle.c:67
msgid "Export oci image instead of flatpak bundle"
msgstr "Eksportuje obraz OCI zamiast pakietu Flatpak"

#: app/flatpak-builtins-build-bundle.c:70
msgid "How to compress OCI image layers (default: gzip)"
msgstr ""

#: app/flatpak-builtins-build-bundle.c:634
msgid ""
"LOCATION FILENAME NAME [BRANCH] - Create a single file bundle from a local "
"repository"
msgstr ""
"POŁOŻENIE NAZWA-PLIKU NAZWA [GAŁĄŹ] — tworzy pakiet w jednym pliku "
"z lokalnego repozytorium"

#: app/flatpak-builtins-build-bundle.c:641
msgid "LOCATION, FILENAME and NAME must be specified"
msgstr "Należy podać POŁOŻENIE, NAZWĘ-PLIKU i NAZWĘ"

#: app/flatpak-builtins-build-bundle.c:644
#: app/flatpak-builtins-build-export.c:844
#: app/flatpak-builtins-build-import-bundle.c:136
#: app/flatpak-builtins-build-init.c:217 app/flatpak-builtins-build-sign.c:76
#: app/flatpak-builtins-document-export.c:112
#: app/flatpak-builtins-document-info.c:75
#: app/flatpak-builtins-document-list.c:191
#: app/flatpak-builtins-document-unexport.c:70
#: app/flatpak-builtins-history.c:482 app/flatpak-builtins-info.c:130
#: app/flatpak-builtins-install.c:181 app/flatpak-builtins-install.c:234
#: app/flatpak-builtins-install.c:298 app/flatpak-builtins-list.c:419
#: app/flatpak-builtins-make-current.c:72 app/flatpak-builtins-override.c:73
#: app/flatpak-builtins-permission-list.c:162
#: app/flatpak-builtins-permission-remove.c:132
#: app/flatpak-builtins-remote-add.c:323
#: app/flatpak-builtins-remote-delete.c:68
#: app/flatpak-builtins-remote-list.c:241 app/flatpak-builtins-remote-ls.c:407
msgid "Too many arguments"
msgstr "Za dużo parametrów"

#: app/flatpak-builtins-build-bundle.c:659
#: app/flatpak-builtins-build-commit-from.c:338
#: app/flatpak-builtins-build-commit-from.c:351
#: app/flatpak-builtins-build-import-bundle.c:145
#, c-format
msgid "'%s' is not a valid repository"
msgstr "„%s” nie jest prawidłowym repozytorium"

#: app/flatpak-builtins-build-bundle.c:663
#, c-format
msgid "'%s' is not a valid repository: "
msgstr "„%s” nie jest prawidłowym repozytorium: "

#: app/flatpak-builtins-build-bundle.c:674 app/flatpak-builtins-build-sign.c:88
#: common/flatpak-dir.c:14293
#, c-format
msgid "'%s' is not a valid name: %s"
msgstr "„%s” nie jest prawidłową nazwą: %s"

#: app/flatpak-builtins-build-bundle.c:677
#: app/flatpak-builtins-build-export.c:865 app/flatpak-builtins-build-sign.c:91
#: common/flatpak-dir.c:14299
#, c-format
msgid "'%s' is not a valid branch name: %s"
msgstr "„%s” nie jest prawidłową nazwą gałęzi: %s"

#: app/flatpak-builtins-build-bundle.c:691
#: app/flatpak-builtins-build-import-bundle.c:149
#: app/flatpak-builtins-build-init.c:281
#, c-format
msgid "'%s' is not a valid filename"
msgstr "„%s” nie jest prawidłową nazwą pliku"

#: app/flatpak-builtins-build-bundle.c:706
msgid "--oci-layer-compress value must be gzip or zstd"
msgstr ""

#: app/flatpak-builtins-build.c:49
msgid "Use Platform runtime rather than Sdk"
msgstr ""
"Używa środowiska wykonawczego typu Platforma zamiast środowiska "
"programistycznego"

#: app/flatpak-builtins-build.c:50
msgid "Make destination readonly"
msgstr "Ustawia element docelowy jako tylko do odczytu"

#: app/flatpak-builtins-build.c:51
msgid "Add bind mount"
msgstr "Dodaje montowanie dowiązania"

#: app/flatpak-builtins-build.c:51
msgid "DEST=SRC"
msgstr "CEL=ŹRÓDŁO"

#: app/flatpak-builtins-build.c:52
msgid "Start build in this directory"
msgstr "Rozpoczyna budowanie w tym katalogu"

#: app/flatpak-builtins-build.c:52 app/flatpak-builtins-build.c:53
#: app/flatpak-builtins-build-init.c:64 app/flatpak-builtins-run.c:160
msgid "DIR"
msgstr "KATALOG"

#: app/flatpak-builtins-build.c:53
msgid "Where to look for custom sdk dir (defaults to 'usr')"
msgstr ""
"Gdzie szukać niestandardowego katalogu środowiska programistycznego "
"(domyślnie „usr”)"

#: app/flatpak-builtins-build.c:54 app/flatpak-builtins-build-export.c:67
msgid "Use alternative file for the metadata"
msgstr "Używa alternatywnego pliku dla metadanych"

#: app/flatpak-builtins-build.c:55 app/flatpak-builtins-run.c:177
msgid "Kill processes when the parent process dies"
msgstr "Usuwa procesy po usunięciu procesu nadrzędnego"

#: app/flatpak-builtins-build.c:56
msgid "Export application homedir directory to build"
msgstr "Eksportuje katalog domowy programu do budowania"

#: app/flatpak-builtins-build.c:57 app/flatpak-builtins-run.c:165
msgid "Log session bus calls"
msgstr "Zapisywanie wywołań magistrali sesji w dzienniku"

#: app/flatpak-builtins-build.c:58 app/flatpak-builtins-run.c:166
msgid "Log system bus calls"
msgstr "Zapisywanie wywołań magistrali systemu w dzienniku"

#: app/flatpak-builtins-build.c:262
msgid "DIRECTORY [COMMAND [ARGUMENT…]] - Build in directory"
msgstr "KATALOG [POLECENIE [PARAMETR…]] — buduje w katalogu"

#: app/flatpak-builtins-build.c:285 app/flatpak-builtins-build-finish.c:656
msgid "DIRECTORY must be specified"
msgstr "Należy podać KATALOG"

#: app/flatpak-builtins-build.c:296 app/flatpak-builtins-build-export.c:887
#, c-format
msgid "Build directory %s not initialized, use flatpak build-init"
msgstr ""
"Nie zainicjowano katalogu budowania %s, należy użyć „flatpak build-init”"

#: app/flatpak-builtins-build.c:315
msgid "metadata invalid, not application or runtime"
msgstr ""
"nieprawidłowe metadane, nie jest programem lub środowiskiem wykonawczym"

#: app/flatpak-builtins-build.c:446
#, c-format
msgid "No extension point matching %s in %s"
msgstr "Brak punktu rozszerzeń pasującego do %s w %s"

#: app/flatpak-builtins-build.c:635
#, c-format
msgid "Missing '=' in bind mount option '%s'"
msgstr "Brak „=” w opcji montowania dowiązania „%s”"

#: app/flatpak-builtins-build.c:679 common/flatpak-run.c:3961
#, c-format
msgid "Unable to start app"
msgstr "Nie można uruchomić programu"

#: app/flatpak-builtins-build-commit-from.c:58
msgid "Source repo dir"
msgstr "Źródłowy katalog repozytorium"

#: app/flatpak-builtins-build-commit-from.c:58
msgid "SRC-REPO"
msgstr "REPOZYTORIUM-ŹRÓDŁOWE"

#: app/flatpak-builtins-build-commit-from.c:59
msgid "Source repo ref"
msgstr "Źródłowe odniesienie repozytorium"

#: app/flatpak-builtins-build-commit-from.c:59
msgid "SRC-REF"
msgstr "ODNIESIENIE-ŹRÓDŁOWE"

#: app/flatpak-builtins-build-commit-from.c:64
#: app/flatpak-builtins-build-export.c:60
msgid "One line subject"
msgstr "Jednowierszowy temat"

#: app/flatpak-builtins-build-commit-from.c:64
#: app/flatpak-builtins-build-export.c:60
msgid "SUBJECT"
msgstr "TEMAT"

#: app/flatpak-builtins-build-commit-from.c:65
#: app/flatpak-builtins-build-export.c:61
msgid "Full description"
msgstr "Pełny opis"

#: app/flatpak-builtins-build-commit-from.c:65
#: app/flatpak-builtins-build-export.c:61
msgid "BODY"
msgstr "TREŚĆ"

#: app/flatpak-builtins-build-commit-from.c:66
#: app/flatpak-builtins-build-export.c:64
#: app/flatpak-builtins-build-import-bundle.c:51
msgid "Update the appstream branch"
msgstr "Aktualizuje gałąź AppStream"

#: app/flatpak-builtins-build-commit-from.c:67
#: app/flatpak-builtins-build-export.c:65
#: app/flatpak-builtins-build-import-bundle.c:52
#: app/flatpak-builtins-build-update-repo.c:87
msgid "Don't update the summary"
msgstr "Bez aktualizowania podsumowania"

#: app/flatpak-builtins-build-commit-from.c:68
#: app/flatpak-builtins-build-export.c:68
#: app/flatpak-builtins-build-import-bundle.c:49
#: app/flatpak-builtins-build-sign.c:44
msgid "GPG Key ID to sign the commit with"
msgstr "Identyfikator klucza GPG do podpisania zatwierdzenia"

#: app/flatpak-builtins-build-commit-from.c:70
#: app/flatpak-builtins-build-export.c:73
msgid "Mark build as end-of-life"
msgstr "Oznacza wersję jako niewspieraną"

#: app/flatpak-builtins-build-commit-from.c:70
#: app/flatpak-builtins-build-export.c:73
msgid "REASON"
msgstr "POWÓD"

#: app/flatpak-builtins-build-commit-from.c:71
msgid ""
"Mark refs matching the OLDID prefix as end-of-life, to be replaced with the "
"given NEWID"
msgstr ""
"Oznacza odniesienia pasujące do przedrostka POPRZEDNIEGO-IDENTYFIKATORA jako "
"niewspierane, do zastąpienia podanym NOWYM-IDENTYFIKATOREM"

#: app/flatpak-builtins-build-commit-from.c:71
msgid "OLDID=NEWID"
msgstr "POPRZEDNI-IDENTYFIKATOR=NOWY-IDENTYFIKATOR"

#: app/flatpak-builtins-build-commit-from.c:72
#: app/flatpak-builtins-build-export.c:75
msgid "Set type of token needed to install this commit"
msgstr "Ustawia typ tokena wymagany do zainstalowania tego zatwierdzenia"

#: app/flatpak-builtins-build-commit-from.c:72
#: app/flatpak-builtins-build-export.c:75
msgid "VAL"
msgstr "WARTOŚĆ"

#: app/flatpak-builtins-build-commit-from.c:73
msgid "Override the timestamp of the commit (NOW for current time)"
msgstr "Zastępuje czas zatwierdzenia („NOW” oznacza obecny czas)"

#: app/flatpak-builtins-build-commit-from.c:73
#: app/flatpak-builtins-build-export.c:76
msgid "TIMESTAMP"
msgstr "CZAS"

#: app/flatpak-builtins-build-commit-from.c:75
#: app/flatpak-builtins-build-export.c:80
#: app/flatpak-builtins-build-import-bundle.c:53
#: app/flatpak-builtins-build-update-repo.c:97
msgid "Don't generate a summary index"
msgstr "Bez tworzenia indeksu podsumowania"

#: app/flatpak-builtins-build-commit-from.c:278
msgid "DST-REPO [DST-REF…] - Make a new commit from existing commits"
msgstr ""
"REPOZYTORIUM-DOCELOWE [ODNIESIENIE-DOCELOWE…] — tworzy nowe zatwierdzenie na "
"podstawie istniejących zatwierdzeń"

#: app/flatpak-builtins-build-commit-from.c:285
msgid "DST-REPO must be specified"
msgstr "Należy podać REPOZYTORIUM-DOCELOWE"

#: app/flatpak-builtins-build-commit-from.c:293
msgid ""
"If --src-repo is not specified, exactly one destination ref must be specified"
msgstr ""
"Jeśli nie podano --src-repo, to należy podać dokładnie jedno odniesienie "
"docelowe"

#: app/flatpak-builtins-build-commit-from.c:296
msgid ""
"If --src-ref is specified, exactly one destination ref must be specified"
msgstr ""
"Jeśli podano --src-ref, to należy podać dokładnie jedno odniesienie docelowe"

#: app/flatpak-builtins-build-commit-from.c:299
msgid "Either --src-repo or --src-ref must be specified"
msgstr "Należy podać --src-repo lub --src-ref"

#: app/flatpak-builtins-build-commit-from.c:315
msgid "Invalid argument format of use  --end-of-life-rebase=OLDID=NEWID"
msgstr ""
"Nieprawidłowy format parametru użycia --end-of-life-rebase=POPRZEDNI-"
"IDENTYFIKATOR=NOWY-IDENTYFIKATOR"

#: app/flatpak-builtins-build-commit-from.c:321
#: app/flatpak-builtins-build-commit-from.c:324
#, c-format
msgid "Invalid name %s in --end-of-life-rebase"
msgstr "Nieprawidłowa nazwa %s w --end-of-life-rebase"

#: app/flatpak-builtins-build-commit-from.c:333
#: app/flatpak-builtins-build-export.c:1092
#, c-format
msgid "Could not parse '%s'"
msgstr "Nie można przetworzyć „%s”"

#: app/flatpak-builtins-build-commit-from.c:498
msgid "Can't commit from partial source commit"
msgstr "Nie można zatwierdzić z częściowego zatwierdzenia źródłowego"

#: app/flatpak-builtins-build-commit-from.c:503
#, c-format
msgid "%s: no change\n"
msgstr "%s: brak zmian\n"

#: app/flatpak-builtins-build-export.c:62
msgid "Architecture to export for (must be host compatible)"
msgstr "Architektura eksportu (musi być zgodna z komputerem)"

#: app/flatpak-builtins-build-export.c:63
msgid "Commit runtime (/usr), not /app"
msgstr "Zatwierdza środowisko wykonawcze (/usr), nie /app"

#: app/flatpak-builtins-build-export.c:66
msgid "Use alternative directory for the files"
msgstr "Używa alternatywnego katalogu dla plików"

#: app/flatpak-builtins-build-export.c:66
msgid "SUBDIR"
msgstr "PODKATALOG"

#: app/flatpak-builtins-build-export.c:69
msgid "Files to exclude"
msgstr "Wykluczone pliki"

#: app/flatpak-builtins-build-export.c:69
#: app/flatpak-builtins-build-export.c:70
#: app/flatpak-builtins-build-update-repo.c:90
msgid "PATTERN"
msgstr "WZÓR"

#: app/flatpak-builtins-build-export.c:70
msgid "Excluded files to include"
msgstr "Wykluczone pliki do dołączenia"

#: app/flatpak-builtins-build-export.c:74
msgid "Mark build as end-of-life, to be replaced with the given ID"
msgstr ""
"Oznacza wersję jako niewspieraną, do zastąpienia podanym IDENTYFIKATOREM"

#: app/flatpak-builtins-build-export.c:74
#: app/flatpak-builtins-document-list.c:49 app/flatpak-cli-transaction.c:1427
msgid "ID"
msgstr "Identyfikator"

#: app/flatpak-builtins-build-export.c:76
msgid "Override the timestamp of the commit"
msgstr "Zastępuje czas zatwierdzenia"

#: app/flatpak-builtins-build-export.c:77
#: app/flatpak-builtins-build-update-repo.c:75
#: app/flatpak-builtins-remote-add.c:83 app/flatpak-builtins-remote-list.c:54
#: app/flatpak-builtins-remote-modify.c:88
msgid "Collection ID"
msgstr "Identyfikator kolekcji"

#: app/flatpak-builtins-build-export.c:472
#, c-format
msgid "WARNING: Error running desktop-file-validate: %s\n"
msgstr ""
"OSTRZEŻENIE: błąd podczas wykonywania polecenia desktop-file-validate: %s\n"

#: app/flatpak-builtins-build-export.c:480
#, c-format
msgid "WARNING: Error reading from desktop-file-validate: %s\n"
msgstr ""
"OSTRZEŻENIE: błąd podczas odczytywania z polecenia desktop-file-validate: "
"%s\n"

#: app/flatpak-builtins-build-export.c:486
#, c-format
msgid "WARNING: Failed to validate desktop file %s: %s\n"
msgstr ""
"OSTRZEŻENIE: sprawdzenie poprawności pliku desktop %s się nie powiodło: %s\n"

#: app/flatpak-builtins-build-export.c:513
#, c-format
msgid "WARNING: Can't find Exec key in %s: %s\n"
msgstr "OSTRZEŻENIE: nie można odnaleźć klucza Exec w %s: %s\n"

#: app/flatpak-builtins-build-export.c:521
#: app/flatpak-builtins-build-export.c:614
#, c-format
msgid "WARNING: Binary not found for Exec line in %s: %s\n"
msgstr ""
"OSTRZEŻENIE: nie odnaleziono pliku binarnego dla wiersza Exec w %s: %s\n"

#: app/flatpak-builtins-build-export.c:529
#, c-format
msgid "WARNING: Icon not matching app id in %s: %s\n"
msgstr "OSTRZEŻENIE: ikona nie pasuje do identyfikatora programu w %s: %s\n"

#: app/flatpak-builtins-build-export.c:552
#, c-format
msgid "WARNING: Icon referenced in desktop file but not exported: %s\n"
msgstr ""
"OSTRZEŻENIE: ikona jest wymieniona w pliku desktop, ale nie jest "
"eksportowana: %s\n"

#: app/flatpak-builtins-build-export.c:719
#, c-format
msgid "Invalid uri type %s, only http/https supported"
msgstr ""
"Nieprawidłowy typ adresu URI %s, obsługiwane są tylko adresy HTTP/HTTPS"

#: app/flatpak-builtins-build-export.c:737
#, c-format
msgid "Unable to find basename in %s, specify a name explicitly"
msgstr "Nie można odnaleźć podstawowej nazwy w %s, należy podać nazwę"

#: app/flatpak-builtins-build-export.c:746
#, c-format
msgid "No slashes allowed in extra data name"
msgstr "Ukośniki są niedozwolone w nazwach dodatkowych danych"

#: app/flatpak-builtins-build-export.c:758
#, c-format
msgid "Invalid format for sha256 checksum: '%s'"
msgstr "Nieprawidłowy format sumy kontrolnej SHA256: „%s”"

#: app/flatpak-builtins-build-export.c:768
#, c-format
msgid "Extra data sizes of zero not supported"
msgstr "Dodatkowe dane o zerowym rozmiarze są nieobsługiwane"

#: app/flatpak-builtins-build-export.c:830
msgid ""
"LOCATION DIRECTORY [BRANCH] - Create a repository from a build directory"
msgstr "POŁOŻENIE KATALOG [GAŁĄŹ] — tworzy repozytorium z katalogu budowania"

#: app/flatpak-builtins-build-export.c:838
msgid "LOCATION and DIRECTORY must be specified"
msgstr "Należy podać POŁOŻENIE i KATALOG"

#: app/flatpak-builtins-build-export.c:859
#: app/flatpak-builtins-remote-add.c:327
#, c-format
msgid "‘%s’ is not a valid collection ID: %s"
msgstr "„%s” nie jest prawidłowym identyfikatorem kolekcji: %s"

#: app/flatpak-builtins-build-export.c:904
#: app/flatpak-builtins-build-finish.c:684
msgid "No name specified in the metadata"
msgstr "Nie podano nazwy w metadanych"

#: app/flatpak-builtins-build-export.c:1166
#, c-format
msgid "Commit: %s\n"
msgstr "Zatwierdzenie: %s\n"

#: app/flatpak-builtins-build-export.c:1167
#, c-format
msgid "Metadata Total: %u\n"
msgstr "Razem metadanych: %u\n"

#: app/flatpak-builtins-build-export.c:1168
#, c-format
msgid "Metadata Written: %u\n"
msgstr "Zapisane metadane: %u\n"

#: app/flatpak-builtins-build-export.c:1169
#, c-format
msgid "Content Total: %u\n"
msgstr "Razem treść: %u\n"

#: app/flatpak-builtins-build-export.c:1170
#, c-format
msgid "Content Written: %u\n"
msgstr "Zapisana treść: %u\n"

#: app/flatpak-builtins-build-export.c:1171
#, c-format
msgid "Content Bytes Written:"
msgstr "Zapisane bajty treści:"

#: app/flatpak-builtins-build-finish.c:52
msgid "Command to set"
msgstr "Ustawiane polecenie"

#: app/flatpak-builtins-build-finish.c:52 app/flatpak-builtins-run.c:159
#: app/flatpak-main.c:209
msgid "COMMAND"
msgstr "POLECENIE"

#: app/flatpak-builtins-build-finish.c:53
msgid "Flatpak version to require"
msgstr "Wymagana wersja Flatpak"

#: app/flatpak-builtins-build-finish.c:53
msgid "MAJOR.MINOR.MICRO"
msgstr "WIĘKSZA.MNIEJSZA.MIKRO"

#: app/flatpak-builtins-build-finish.c:54
msgid "Don't process exports"
msgstr "Bez przetwarzania eksportów"

#: app/flatpak-builtins-build-finish.c:55
msgid "Extra data info"
msgstr "Informacje o dodatkowych danych"

#: app/flatpak-builtins-build-finish.c:56 app/flatpak-builtins-build-init.c:63
msgid "Add extension point info"
msgstr "Dodaje informacje o punkcie rozszerzeń"

#: app/flatpak-builtins-build-finish.c:56 app/flatpak-builtins-build-init.c:63
msgid "NAME=VARIABLE[=VALUE]"
msgstr "NAZWA=ZMIENNA[=WARTOŚĆ]"

#: app/flatpak-builtins-build-finish.c:57
msgid "Remove extension point info"
msgstr "Usuwa informacje o punkcie rozszerzeń"

#: app/flatpak-builtins-build-finish.c:57
#: app/flatpak-builtins-build-update-repo.c:79 app/flatpak-builtins-info.c:58
#: app/flatpak-builtins-remote-add.c:88 app/flatpak-builtins-remote-modify.c:94
#: app/flatpak-main.c:182
msgid "NAME"
msgstr "NAZWA"

#: app/flatpak-builtins-build-finish.c:58
msgid "Set extension priority (only for extensions)"
msgstr "Ustawia priorytet rozszerzenia (tylko dla rozszerzeń)"

#: app/flatpak-builtins-build-finish.c:58
msgid "VALUE"
msgstr "WARTOŚĆ"

#: app/flatpak-builtins-build-finish.c:59
msgid "Change the sdk used for the app"
msgstr "Zmienia środowisko programistyczne używane dla programu"

#: app/flatpak-builtins-build-finish.c:59
msgid "SDK"
msgstr "ŚRODOWISKO-PROGRAMISTYCZNE"

#: app/flatpak-builtins-build-finish.c:60
msgid "Change the runtime used for the app"
msgstr "Zatwierdza środowisko wykonawcze używane dla programu"

#: app/flatpak-builtins-build-finish.c:60 app/flatpak-builtins-build-init.c:54
#: app/flatpak-builtins-list.c:53 app/flatpak-builtins-remote-ls.c:58
#: app/flatpak-builtins-run.c:163
msgid "RUNTIME"
msgstr "ŚRODOWISKO-WYKONAWCZE"

#: app/flatpak-builtins-build-finish.c:61
msgid "Set generic metadata option"
msgstr "Ustawia opcję ogólnych metadanych"

#: app/flatpak-builtins-build-finish.c:61
msgid "GROUP=KEY[=VALUE]"
msgstr "GRUPA=KLUCZ[=WARTOŚĆ]"

#: app/flatpak-builtins-build-finish.c:62
msgid "Don't inherit permissions from runtime"
msgstr "Bez dziedziczenia uprawnień ze środowiska wykonawczego"

#: app/flatpak-builtins-build-finish.c:155
#, c-format
msgid "Not exporting %s, wrong extension\n"
msgstr "%s nie zostanie wyeksportowane, błędne rozszerzenie\n"

#: app/flatpak-builtins-build-finish.c:163
#, c-format
msgid "Not exporting %s, non-allowed export filename\n"
msgstr "%s nie zostanie wyeksportowane, niedozwolona nazwa pliku eksportu\n"

#: app/flatpak-builtins-build-finish.c:167
#, c-format
msgid "Exporting %s\n"
msgstr "Eksportowanie %s\n"

#: app/flatpak-builtins-build-finish.c:440
#, c-format
msgid "More than one executable found\n"
msgstr "Odnaleziono więcej niż jeden plik wykonywalny\n"

#: app/flatpak-builtins-build-finish.c:451
#, c-format
msgid "Using %s as command\n"
msgstr "Używanie %s jako polecenia\n"

#: app/flatpak-builtins-build-finish.c:456
#, c-format
msgid "No executable found\n"
msgstr "Nie odnaleziono żadnych plików wykonywalnych\n"

#: app/flatpak-builtins-build-finish.c:511
#, c-format
msgid "Invalid --require-version argument: %s"
msgstr "Nieprawidłowy parametr --require-version: %s"

#: app/flatpak-builtins-build-finish.c:543
#, c-format
msgid "Too few elements in --extra-data argument %s"
msgstr "Za mało elementów w parametrze %s opcji --extra-data"

#: app/flatpak-builtins-build-finish.c:575
#, c-format
msgid ""
"Too few elements in --metadata argument %s, format should be "
"GROUP=KEY[=VALUE]]"
msgstr ""
"Za mało elementów w parametrze %s opcji --metadata, musi być w formacie "
"GRUPA=KLUCZ[=WARTOŚĆ]]"

#: app/flatpak-builtins-build-finish.c:597
#: app/flatpak-builtins-build-init.c:458
#, c-format
msgid ""
"Too few elements in --extension argument %s, format should be "
"NAME=VAR[=VALUE]"
msgstr ""
"Za mało elementów w parametrze %s opcji --extension, musi być w formacie "
"NAZWA=ZMIENNA[=WARTOŚĆ]"

#: app/flatpak-builtins-build-finish.c:603
#: app/flatpak-builtins-build-init.c:461
#, c-format
msgid "Invalid extension name %s"
msgstr "Nieprawidłowa nazwa rozszerzenia %s"

#: app/flatpak-builtins-build-finish.c:646
msgid "DIRECTORY - Finalize a build directory"
msgstr "KATALOG — finalizuje katalog budowania"

#: app/flatpak-builtins-build-finish.c:668
#, c-format
msgid "Build directory %s not initialized"
msgstr "Nie zainicjowano katalogu budowania %s"

#: app/flatpak-builtins-build-finish.c:689
#, c-format
msgid "Build directory %s already finalized"
msgstr "Już sfinalizowano katalog budowania %s"

#: app/flatpak-builtins-build-finish.c:702
#, c-format
msgid "Please review the exported files and the metadata\n"
msgstr "Proszę przejrzeć wyeksportowane pliki i metadane\n"

#: app/flatpak-builtins-build-import-bundle.c:47
msgid "Override the ref used for the imported bundle"
msgstr "Zastępuje odniesienie dla zaimportowanego pakietu"

#: app/flatpak-builtins-build-import-bundle.c:47
msgid "REF"
msgstr "ODNIESIENIE"

#: app/flatpak-builtins-build-import-bundle.c:48
msgid "Import oci image instead of flatpak bundle"
msgstr "Importuje obraz OCI zamiast pakietu Flatpak"

#: app/flatpak-builtins-build-import-bundle.c:77
#: app/flatpak-builtins-build-import-bundle.c:105
#, c-format
msgid "Importing %s (%s)\n"
msgstr "Importowanie %s (%s)\n"

#: app/flatpak-builtins-build-import-bundle.c:126
msgid "LOCATION FILENAME - Import a file bundle into a local repository"
msgstr ""
"POŁOŻENIE NAZWA-PLIKU — importuje pakiet plików do lokalnego repozytorium"

#: app/flatpak-builtins-build-import-bundle.c:133
msgid "LOCATION and FILENAME must be specified"
msgstr "Należy podać POŁOŻENIE i NAZWĘ-PLIKU"

#: app/flatpak-builtins-build-init.c:53 app/flatpak-builtins-info.c:55
#: app/flatpak-builtins-run.c:158
msgid "Arch to use"
msgstr "Używana architektura"

#: app/flatpak-builtins-build-init.c:54
msgid "Initialize var from named runtime"
msgstr "Inicjuje zmienną z nazwanego środowiska wykonawczego"

#: app/flatpak-builtins-build-init.c:55
msgid "Initialize apps from named app"
msgstr "Inicjuje programy z nazwanego programu"

#: app/flatpak-builtins-build-init.c:55
msgid "APP"
msgstr "PROGRAM"

#: app/flatpak-builtins-build-init.c:56
msgid "Specify version for --base"
msgstr "Podaje wersję dla opcji --base"

#: app/flatpak-builtins-build-init.c:56 app/flatpak-builtins-run.c:164
msgid "VERSION"
msgstr "WERSJA"

#: app/flatpak-builtins-build-init.c:57
msgid "Include this base extension"
msgstr "Dołącza to podstawowe rozszerzenie"

#: app/flatpak-builtins-build-init.c:57 app/flatpak-builtins-build-init.c:62
msgid "EXTENSION"
msgstr "ROZSZERZENIE"

#: app/flatpak-builtins-build-init.c:58
msgid "Extension tag to use if building extension"
msgstr "Etykieta rozszerzenia używana, jeśli budowane jest rozszerzenie"

#: app/flatpak-builtins-build-init.c:58
msgid "EXTENSION_TAG"
msgstr "ETYKIETA_ROZSZERZENIA"

#: app/flatpak-builtins-build-init.c:59
msgid "Initialize /usr with a writable copy of the sdk"
msgstr "Inicjuje /usr z zapisywalną kopią środowiska programistycznego"

#: app/flatpak-builtins-build-init.c:60
msgid "Specify the build type (app, runtime, extension)"
msgstr ""
"Podaje typ budowania, jedno z „app” (program), „runtime” (środowisko "
"wykonawcze) lub „extension” (rozszerzenie)"

#: app/flatpak-builtins-build-init.c:60
msgid "TYPE"
msgstr "TYP"

#: app/flatpak-builtins-build-init.c:61
msgid "Add a tag"
msgstr "Dodaje etykietę"

#: app/flatpak-builtins-build-init.c:61
msgid "TAG"
msgstr "ETYKIETA"

#: app/flatpak-builtins-build-init.c:62
msgid "Include this sdk extension in /usr"
msgstr "Dołącza to rozszerzenie środowiska programistycznego w /usr"

#: app/flatpak-builtins-build-init.c:64
msgid "Where to store sdk (defaults to 'usr')"
msgstr "Gdzie przechowywać środowisko programistyczne (domyślnie „usr”)"

#: app/flatpak-builtins-build-init.c:65
msgid "Re-initialize the sdk/var"
msgstr "Ponownie inicjuje środowisko programistyczne/zmienną"

#: app/flatpak-builtins-build-init.c:118
#, c-format
msgid "Requested extension %s/%s/%s is only partially installed"
msgstr "Żądane rozszerzenie %s/%s/%s jest tylko częściowo zainstalowane"

#: app/flatpak-builtins-build-init.c:147
#, c-format
msgid "Requested extension %s/%s/%s not installed"
msgstr "Nie zainstalowano żądanego rozszerzenia %s/%s/%s"

#: app/flatpak-builtins-build-init.c:207
msgid ""
"DIRECTORY APPNAME SDK RUNTIME [BRANCH] - Initialize a directory for building"
msgstr ""
"KATALOG NAZWA-PROGRAMU ŚRODOWISKO-PROGRAMISTYCZNE [GAŁĄŹ] — inicjuje katalog "
"do budowania"

#: app/flatpak-builtins-build-init.c:214
msgid "RUNTIME must be specified"
msgstr "Należy podać ŚRODOWISKO-WYKONAWCZE"

#: app/flatpak-builtins-build-init.c:235
#, c-format
msgid "'%s' is not a valid build type name, use app, runtime or extension"
msgstr ""
"„%s” nie jest prawidłową nazwą typu budowania, należy użyć „app” (program), "
"„runtime” (środowisko wykonawcze) lub „extension” (rozszerzenie)"

#: app/flatpak-builtins-build-init.c:241 app/flatpak-builtins-override.c:79
#, c-format
msgid "'%s' is not a valid application name: %s"
msgstr "„%s” nie jest prawidłową nazwą programu: %s"

#: app/flatpak-builtins-build-init.c:295
#, c-format
msgid "Build directory %s already initialized"
msgstr "Już zainicjowano katalog budowania %s"

#: app/flatpak-builtins-build-sign.c:42 app/flatpak-builtins-install.c:67
#: app/flatpak-builtins-remote-info.c:54
msgid "Arch to install for"
msgstr "Instalowana architektura"

#: app/flatpak-builtins-build-sign.c:43 app/flatpak-builtins-create-usb.c:48
#: app/flatpak-builtins-install.c:74 app/flatpak-builtins-remote-info.c:56
#: app/flatpak-builtins-uninstall.c:58 app/flatpak-builtins-update.c:64
msgid "Look for runtime with the specified name"
msgstr "Wyszukuje środowisko wykonawcze o podanej nazwie"

#: app/flatpak-builtins-build-sign.c:66
msgid "LOCATION [ID [BRANCH]] - Sign an application or runtime"
msgstr ""
"POŁOŻENIE [IDENTYFIKATOR [GAŁĄŹ]] — podpisuje program lub środowisko "
"wykonawcze"

#: app/flatpak-builtins-build-sign.c:73
#: app/flatpak-builtins-build-update-repo.c:499
#: app/flatpak-builtins-remote-add.c:320 app/flatpak-builtins-repo.c:739
msgid "LOCATION must be specified"
msgstr "Należy podać POŁOŻENIE"

#: app/flatpak-builtins-build-sign.c:94
msgid "No gpg key ids specified"
msgstr "Nie podano identyfikatorów kluczy GPG"

#: app/flatpak-builtins-build-update-repo.c:68
msgid "Redirect this repo to a new URL"
msgstr "Przekierowuje to repozytorium do nowego adresu URL"

#: app/flatpak-builtins-build-update-repo.c:69
msgid "A nice name to use for this repository"
msgstr "Czytelna nazwa używana dla tego repozytorium"

#: app/flatpak-builtins-build-update-repo.c:69
#: app/flatpak-builtins-remote-add.c:77 app/flatpak-builtins-remote-modify.c:82
msgid "TITLE"
msgstr "TYTUŁ"

#: app/flatpak-builtins-build-update-repo.c:70
msgid "A one-line comment for this repository"
msgstr "Jednowierszowy komentarz dla tego repozytorium"

#: app/flatpak-builtins-build-update-repo.c:70
#: app/flatpak-builtins-remote-add.c:78 app/flatpak-builtins-remote-modify.c:83
msgid "COMMENT"
msgstr "KOMENTARZ"

#: app/flatpak-builtins-build-update-repo.c:71
msgid "A full-paragraph description for this repository"
msgstr "Akapit opisu dla tego repozytorium"

#: app/flatpak-builtins-build-update-repo.c:71
#: app/flatpak-builtins-remote-add.c:79 app/flatpak-builtins-remote-modify.c:84
msgid "DESCRIPTION"
msgstr "OPIS"

#: app/flatpak-builtins-build-update-repo.c:72
msgid "URL for a website for this repository"
msgstr "Adres URL strony dla tego repozytorium"

#: app/flatpak-builtins-build-update-repo.c:73
msgid "URL for an icon for this repository"
msgstr "Adres URL ikony dla tego repozytorium"

#: app/flatpak-builtins-build-update-repo.c:74
msgid "Default branch to use for this repository"
msgstr "Domyślna gałąź używana dla tego repozytorium"

#: app/flatpak-builtins-build-update-repo.c:74
#: app/flatpak-builtins-remote-add.c:82 app/flatpak-builtins-remote-modify.c:87
#: app/flatpak-builtins-repo.c:713 app/flatpak-builtins-repo.c:714
#: app/flatpak-builtins-run.c:161
msgid "BRANCH"
msgstr "GAŁĄŹ"

#: app/flatpak-builtins-build-update-repo.c:75
#: app/flatpak-builtins-remote-add.c:83 app/flatpak-builtins-remote-modify.c:88
msgid "COLLECTION-ID"
msgstr "IDENTYFIKATOR-KOLEKCJI"

#. Translators: A sideload is when you install from a local USB drive rather than the Internet.
#: app/flatpak-builtins-build-update-repo.c:77
msgid ""
"Permanently deploy collection ID to client remote configurations, only for "
"sideload support"
msgstr ""
"Trwale wdraża identyfikator kolekcji do konfiguracji repozytoriów klienta, "
"tylko do obsługi wczytywania bocznego"

#: app/flatpak-builtins-build-update-repo.c:78
msgid "Permanently deploy collection ID to client remote configurations"
msgstr ""
"Trwale wdraża identyfikator kolekcji do konfiguracji repozytoriów klienta"

#: app/flatpak-builtins-build-update-repo.c:79
msgid "Name of authenticator for this repository"
msgstr "Nazwa programu uwierzytelniającego dla tego repozytorium"

#: app/flatpak-builtins-build-update-repo.c:80
msgid "Autoinstall authenticator for this repository"
msgstr ""
"Automatycznie instaluje program uwierzytelniający dla tego repozytorium"

#: app/flatpak-builtins-build-update-repo.c:81
msgid "Don't autoinstall authenticator for this repository"
msgstr ""
"Bez automatycznego instalowania programu uwierzytelniającego dla tego "
"repozytorium"

#: app/flatpak-builtins-build-update-repo.c:82
#: app/flatpak-builtins-remote-add.c:89
msgid "Authenticator option"
msgstr "Opcja programu uwierzytelniającego"

#: app/flatpak-builtins-build-update-repo.c:82
#: app/flatpak-builtins-remote-add.c:89 app/flatpak-builtins-remote-modify.c:95
msgid "KEY=VALUE"
msgstr "KLUCZ=WARTOŚĆ"

#: app/flatpak-builtins-build-update-repo.c:83
msgid "Import new default GPG public key from FILE"
msgstr "Importuje nowy domyślny klucz publiczny GPG z PLIKU"

#: app/flatpak-builtins-build-update-repo.c:84
msgid "GPG Key ID to sign the summary with"
msgstr "Identyfikator klucza GPG do podpisania podsumowania"

#: app/flatpak-builtins-build-update-repo.c:86
msgid "Generate delta files"
msgstr "Tworzy pliki delty"

#: app/flatpak-builtins-build-update-repo.c:88
msgid "Don't update the appstream branch"
msgstr "Bez aktualizowania gałęzi AppStream"

#: app/flatpak-builtins-build-update-repo.c:89
msgid "Max parallel jobs when creating deltas (default: NUMCPUs)"
msgstr ""
"Maksymalna liczba równoległych zadań podczas tworzenia delt (domyślnie: "
"LICZBA-PROCESORÓW)"

#: app/flatpak-builtins-build-update-repo.c:89
msgid "NUM-JOBS"
msgstr "LICZBA-ZADAŃ"

#: app/flatpak-builtins-build-update-repo.c:90
msgid "Don't create deltas matching refs"
msgstr "Bez tworzenia delt pasujących odniesień"

#: app/flatpak-builtins-build-update-repo.c:91
msgid "Prune unused objects"
msgstr "Czyści nieużywane obiekty"

#: app/flatpak-builtins-build-update-repo.c:92
msgid "Prune but don't actually remove anything"
msgstr "Czyści, ale nic nie usuwa"

#: app/flatpak-builtins-build-update-repo.c:93
msgid "Only traverse DEPTH parents for each commit (default: -1=infinite)"
msgstr ""
"Przechodzi tylko przez podaną GŁĘBIĘ elementów nadrzędnych każdego "
"zatwierdzenia (domyślnie: -1=nieskończoność)"

#: app/flatpak-builtins-build-update-repo.c:93
msgid "DEPTH"
msgstr "GŁĘBIA"

#: app/flatpak-builtins-build-update-repo.c:223
#, c-format
msgid "Generating delta: %s (%.10s)\n"
msgstr "Tworzenie delty: %s (%.10s)\n"

#: app/flatpak-builtins-build-update-repo.c:225
#, c-format
msgid "Generating delta: %s (%.10s-%.10s)\n"
msgstr "Tworzenie delty: %s (%.10s-%.10s)\n"

#: app/flatpak-builtins-build-update-repo.c:233
#, c-format
msgid "Failed to generate delta %s (%.10s): "
msgstr "Utworzenie delty %s się nie powiodło (%.10s): "

#: app/flatpak-builtins-build-update-repo.c:236
#, c-format
msgid "Failed to generate delta %s (%.10s-%.10s): "
msgstr "Utworzenie delty %s się nie powiodło (%.10s-%.10s): "

#: app/flatpak-builtins-build-update-repo.c:492
msgid "LOCATION - Update repository metadata"
msgstr "POŁOŻENIE — aktualizuje metadane repozytorium"

#: app/flatpak-builtins-build-update-repo.c:609
#, c-format
msgid "Updating appstream branch\n"
msgstr "Aktualizowanie danych AppStream\n"

#: app/flatpak-builtins-build-update-repo.c:638
#, c-format
msgid "Updating summary\n"
msgstr "Aktualizowanie podsumowania\n"

#: app/flatpak-builtins-build-update-repo.c:664
#, c-format
msgid "Total objects: %u\n"
msgstr "Razem obiektów: %u\n"

#: app/flatpak-builtins-build-update-repo.c:666
#, c-format
msgid "No unreachable objects\n"
msgstr "Brak nieosiągalnych obiektów\n"

#: app/flatpak-builtins-build-update-repo.c:668
#, c-format
msgid "Deleted %u objects, %s freed\n"
msgstr "Usunięto %u obiektów, uwolniono %s\n"

#: app/flatpak-builtins-config.c:41
msgid "List configuration keys and values"
msgstr "Wyświetla listę kluczy i wartości konfiguracji"

#: app/flatpak-builtins-config.c:42
msgid "Get configuration for KEY"
msgstr "Pobiera konfigurację KLUCZA"

#: app/flatpak-builtins-config.c:43
msgid "Set configuration for KEY to VALUE"
msgstr "Ustawia konfigurację KLUCZA na WARTOŚĆ"

#: app/flatpak-builtins-config.c:44
msgid "Unset configuration for KEY"
msgstr "Usuwa ustawienie konfiguracji KLUCZA"

#: app/flatpak-builtins-config.c:149
#, c-format
msgid "'%s' does not look like a language/locale code"
msgstr "„%s” nie jest kodem języka/lokalizacji"

#: app/flatpak-builtins-config.c:172
#, c-format
msgid "'%s' does not look like a language code"
msgstr "„%s” nie jest kodem języka"

#: app/flatpak-builtins-config.c:190
#, fuzzy, c-format
msgid "'%s' is not a valid value (use 'true' or 'false')"
msgstr "„%s” nie jest prawidłowym repozytorium: "

#: app/flatpak-builtins-config.c:262
#, c-format
msgid "Unknown configure key '%s'"
msgstr "Nieznany klucz konfiguracji „%s”"

#: app/flatpak-builtins-config.c:284
msgid "Too many arguments for --list"
msgstr "Za dużo parametrów dla --list"

#: app/flatpak-builtins-config.c:314 app/flatpak-builtins-config.c:362
msgid "You must specify KEY"
msgstr "Należy podać KLUCZ"

#: app/flatpak-builtins-config.c:316
msgid "Too many arguments for --get"
msgstr "Za dużo parametrów dla --get"

#: app/flatpak-builtins-config.c:338
msgid "You must specify KEY and VALUE"
msgstr "Należy podać KLUCZ i WARTOŚĆ"

#: app/flatpak-builtins-config.c:340
msgid "Too many arguments for --set"
msgstr "Za dużo parametrów dla --set"

#: app/flatpak-builtins-config.c:364
msgid "Too many arguments for --unset"
msgstr "Za dużo parametrów dla --unset"

#: app/flatpak-builtins-config.c:383
msgid "[KEY [VALUE]] - Manage configuration"
msgstr "[KLUCZ [WARTOŚĆ]] — zarządza konfiguracją"

#: app/flatpak-builtins-config.c:394
msgid "Can only use one of --list, --get, --set or --unset"
msgstr "Można użyć tylko jednego z --list, --get, --set lub --unset"

#: app/flatpak-builtins-config.c:408
msgid "Must specify one of --list, --get, --set or --unset"
msgstr "Należy podać jedną z opcji --list, --get, --set lub --unset"

#: app/flatpak-builtins-create-usb.c:45 app/flatpak-builtins-install.c:75
#: app/flatpak-builtins-remote-info.c:57 app/flatpak-builtins-uninstall.c:59
#: app/flatpak-builtins-update.c:65
msgid "Look for app with the specified name"
msgstr "Wyszukuje program o podanej nazwie"

#: app/flatpak-builtins-create-usb.c:46
msgid "Arch to copy"
msgstr "Kopiowana architektura"

#: app/flatpak-builtins-create-usb.c:47
msgid "DEST"
msgstr "CEL"

#: app/flatpak-builtins-create-usb.c:49
msgid "Allow partial commits in the created repo"
msgstr "Zezwala na częściowe zatwierdzenia w utworzonym repozytorium"

#: app/flatpak-builtins-create-usb.c:125 app/flatpak-builtins-create-usb.c:165
#, c-format
msgid ""
"Warning: Related ref ‘%s’ is partially installed. Use --allow-partial to "
"suppress this message.\n"
msgstr ""
"Ostrzeżenie: powiązane odniesienie „%s” jest częściowo zainstalowane. Użycie "
"opcji --allow-partial wyciszy ten komunikat.\n"

#: app/flatpak-builtins-create-usb.c:158
#, c-format
msgid "Warning: Omitting related ref ‘%s’ because it is not installed.\n"
msgstr ""
"Ostrzeżenie: pomijanie powiązanego odniesienia „%s”, ponieważ nie jest "
"zainstalowane.\n"

#: app/flatpak-builtins-create-usb.c:175
#, c-format
msgid ""
"Warning: Omitting related ref ‘%s’ because its remote ‘%s’ does not have a "
"collection ID set.\n"
msgstr ""
"Ostrzeżenie: pomijanie powiązanego odniesienia „%s”, ponieważ jego "
"repozytorium „%s” nie ma ustawionego identyfikatora kolekcji.\n"

#: app/flatpak-builtins-create-usb.c:187
#, c-format
msgid "Warning: Omitting related ref ‘%s’ because it's extra-data.\n"
msgstr ""
"Ostrzeżenie: pomijanie powiązanego odniesienia „%s”, ponieważ jest "
"dodatkowymi danymi.\n"

#: app/flatpak-builtins-create-usb.c:262 app/flatpak-builtins-create-usb.c:637
#, c-format
msgid ""
"Remote ‘%s’ does not have a collection ID set, which is required for P2P "
"distribution of ‘%s’."
msgstr ""
"Repozytorium „%s” nie ma ustawionego identyfikatora kolekcji, który jest "
"wymagany do rozpowszechniania „%s” typu P2P."

#: app/flatpak-builtins-create-usb.c:272
#, c-format
msgid "Warning: Omitting ref ‘%s’ (runtime of ‘%s’) because it's extra-data.\n"
msgstr ""
"Ostrzeżenie: pomijanie odniesienia „%s” (środowisko wykonawcze „%s”), "
"ponieważ jest dodatkowymi danymi.\n"

#: app/flatpak-builtins-create-usb.c:484
msgid "MOUNT-PATH [REF…] - Copy apps or runtimes onto removable media"
msgstr ""
"ŚCIEŻKA-DO-PUNKTU-MONTOWANIA [ODNIESIENIE…] — kopiuje programy lub "
"środowiska wykonawcze na nośniki wymienne"

#: app/flatpak-builtins-create-usb.c:493
msgid "MOUNT-PATH and REF must be specified"
msgstr "Należy podać ŚCIEŻKĘ-DO-PUNKTU-MONTOWANIA i ODNIESIENIE"

#: app/flatpak-builtins-create-usb.c:607
#, c-format
msgid "Ref ‘%s’ found in multiple installations: %s. You must specify one."
msgstr ""
"Odnaleziono odniesienie „%s” w wielu instalacjach: %s. Należy podać jedno."

#: app/flatpak-builtins-create-usb.c:620
#, c-format
msgid "Refs must all be in the same installation (found in %s and %s)."
msgstr ""
"Wszystkie odniesienia muszą być w tej samej instalacji (odnaleziono w %s "
"i %s)."

#: app/flatpak-builtins-create-usb.c:670
#, c-format
msgid ""
"Warning: Ref ‘%s’ is partially installed. Use --allow-partial to suppress "
"this message.\n"
msgstr ""
"Ostrzeżenie: odniesienie „%s” jest częściowo zainstalowane. Użycie opcji --"
"allow-partial wyciszy ten komunikat.\n"

#: app/flatpak-builtins-create-usb.c:681
#, c-format
msgid "Installed ref ‘%s’ is extra-data, and cannot be distributed offline"
msgstr ""
"Zainstalowane odniesienie „%s” jest dodatkowymi danymi i nie może być "
"rozprowadzane w trybie offline"

#: app/flatpak-builtins-create-usb.c:721
#, c-format
msgid "Warning: Couldn't update repo metadata for remote ‘%s’: %s\n"
msgstr ""
"Ostrzeżenie: nie można zaktualizować metadanych dla repozytorium „%s”: %s\n"

#: app/flatpak-builtins-create-usb.c:751
#, c-format
msgid "Warning: Couldn't update appstream data for remote ‘%s’ arch ‘%s’: %s\n"
msgstr ""
"Ostrzeżenie: nie można zaktualizować danych AppStream dla repozytorium „%s”, "
"architektury „%s”: %s\n"

#. Print a warning if both appstream and appstream2 are missing
#: app/flatpak-builtins-create-usb.c:784
#, c-format
msgid ""
"Warning: Couldn't find appstream data for remote ‘%s’ arch ‘%s’: %s; %s\n"
msgstr ""
"Ostrzeżenie: nie można odnaleźć danych AppStream dla repozytorium „%s”, "
"architektury „%s”: %s; %s\n"

#. Appstream2 is only for efficiency, so just print a debug message
#: app/flatpak-builtins-create-usb.c:790
#, c-format
msgid "Couldn't find appstream2 data for remote ‘%s’ arch ‘%s’: %s\n"
msgstr ""
"Nie można odnaleźć danych AppStream2 dla repozytorium „%s”, architektury "
"„%s”: %s\n"

#: app/flatpak-builtins-document-export.c:62
msgid "Create a unique document reference"
msgstr "Tworzy unikalne odniesienie dokumentu"

#: app/flatpak-builtins-document-export.c:63
msgid "Make the document transient for the current session"
msgstr "Dokument jest przejściowy dla bieżącej sesji"

#: app/flatpak-builtins-document-export.c:64
msgid "Don't require the file to exist already"
msgstr "Plik nie musi już istnieć"

#: app/flatpak-builtins-document-export.c:65
msgid "Give the app read permissions"
msgstr "Nadaje programowi uprawnienia do odczytu"

#: app/flatpak-builtins-document-export.c:66
msgid "Give the app write permissions"
msgstr "Nadaje programowi uprawnienia do zapisu"

#: app/flatpak-builtins-document-export.c:67
msgid "Give the app delete permissions"
msgstr "Nadaje programowi uprawnienia do usuwania"

#: app/flatpak-builtins-document-export.c:68
msgid "Give the app permissions to grant further permissions"
msgstr "Nadaje programowi uprawnienia do nadawania dalszych uprawnień"

#: app/flatpak-builtins-document-export.c:69
msgid "Revoke read permissions of the app"
msgstr "Odbiera programowi uprawnienia do odczytu"

#: app/flatpak-builtins-document-export.c:70
msgid "Revoke write permissions of the app"
msgstr "Odbiera programowi uprawnienia do zapisu"

#: app/flatpak-builtins-document-export.c:71
msgid "Revoke delete permissions of the app"
msgstr "Odbiera programowi uprawnienia do usuwania"

#: app/flatpak-builtins-document-export.c:72
msgid "Revoke the permission to grant further permissions"
msgstr "Odbiera programowi uprawnienia do nadawania dalszych uprawnień"

#: app/flatpak-builtins-document-export.c:73
msgid "Add permissions for this app"
msgstr "Dodaje uprawnienia programowi"

#: app/flatpak-builtins-document-export.c:73
msgid "APPID"
msgstr "IDENTYFIKATOR-PROGRAMU"

#: app/flatpak-builtins-document-export.c:100
msgid "FILE - Export a file to apps"
msgstr "PLIK — eksportuje plik do programów"

#: app/flatpak-builtins-document-export.c:109
#: app/flatpak-builtins-document-info.c:72
#: app/flatpak-builtins-document-unexport.c:67
msgid "FILE must be specified"
msgstr "Należy podać PLIK"

#: app/flatpak-builtins-document-info.c:63
msgid "FILE - Get information about an exported file"
msgstr "PLIK — pobiera informacje o wyeksportowanym pliku"

#: app/flatpak-builtins-document-info.c:100
#: app/flatpak-builtins-document-unexport.c:94
#, c-format
msgid "Not exported\n"
msgstr "Nie wyeksportowano\n"

#: app/flatpak-builtins-document-list.c:43 app/flatpak-builtins-history.c:53
#: app/flatpak-builtins-list.c:54 app/flatpak-builtins-ps.c:43
#: app/flatpak-builtins-remote-list.c:45 app/flatpak-builtins-remote-ls.c:59
#: app/flatpak-builtins-search.c:38
msgid "What information to show"
msgstr "Które informacje wyświetlać"

#: app/flatpak-builtins-document-list.c:43 app/flatpak-builtins-history.c:53
#: app/flatpak-builtins-list.c:54 app/flatpak-builtins-ps.c:43
#: app/flatpak-builtins-remote-list.c:45 app/flatpak-builtins-remote-ls.c:59
#: app/flatpak-builtins-search.c:38
msgid "FIELD,…"
msgstr "POLE,…"

#: app/flatpak-builtins-document-list.c:44 app/flatpak-builtins-history.c:54
#: app/flatpak-builtins-list.c:52 app/flatpak-builtins-permission-list.c:43
#: app/flatpak-builtins-permission-show.c:43 app/flatpak-builtins-ps.c:44
#: app/flatpak-builtins-remote-list.c:46 app/flatpak-builtins-remote-ls.c:63
#: app/flatpak-builtins-repo.c:717 app/flatpak-builtins-search.c:39
#, fuzzy
msgid "Show output in JSON format"
msgstr "Wyświetla dodatkowe informacje"

#: app/flatpak-builtins-document-list.c:49
msgid "Show the document ID"
msgstr "Wyświetla identyfikator dokumentu"

#: app/flatpak-builtins-document-list.c:50
msgid "Path"
msgstr "Ścieżka"

#: app/flatpak-builtins-document-list.c:50
#: app/flatpak-builtins-document-list.c:51
msgid "Show the document path"
msgstr "Wyświetla ścieżkę do dokumentu"

#: app/flatpak-builtins-document-list.c:51 app/flatpak-builtins-list.c:66
#: app/flatpak-builtins-remote-ls.c:74
msgid "Origin"
msgstr "Pochodzenie"

#: app/flatpak-builtins-document-list.c:52 app/flatpak-builtins-history.c:62
#: app/flatpak-builtins-ps.c:52
msgid "Application"
msgstr "Program"

#: app/flatpak-builtins-document-list.c:52
msgid "Show applications with permission"
msgstr "Wyświetla programy z uprawnieniem"

#: app/flatpak-builtins-document-list.c:53
#: app/flatpak-builtins-permission-list.c:182
#: app/flatpak-builtins-permission-show.c:145
msgid "Permissions"
msgstr "Uprawnienia"

#: app/flatpak-builtins-document-list.c:53
msgid "Show permissions for applications"
msgstr "Wyświetla uprawnienia programów"

#: app/flatpak-builtins-document-list.c:161
#, c-format
msgid "No documents found\n"
msgstr "Nie odnaleziono dokumentów\n"

#: app/flatpak-builtins-document-list.c:180
msgid "[APPID] - List exported files"
msgstr "[IDENTYFIKATOR-PROGRAMU] — wyświetla listę wyeksportowanych plików"

#: app/flatpak-builtins-document-unexport.c:43
msgid "Specify the document ID"
msgstr "Podaje identyfikator dokumentu"

#: app/flatpak-builtins-document-unexport.c:58
msgid "FILE - Unexport a file to apps"
msgstr "PLIK — usuwa eksport pliku do programów"

#: app/flatpak-builtins-enter.c:88
msgid "INSTANCE COMMAND [ARGUMENT…] - Run a command inside a running sandbox"
msgstr ""
"WYSTĄPIENIE POLECENIE [PARAMETR…] — wykonuje polecenie w działającej "
"piaskownicy"

#: app/flatpak-builtins-enter.c:111
msgid "INSTANCE and COMMAND must be specified"
msgstr "Należy podać WYSTĄPIENIE i POLECENIE"

#: app/flatpak-builtins-enter.c:138
#, c-format
msgid "%s is neither a pid nor an application or instance ID"
msgstr "%s nie jest PID ani identyfikatorem programu lub wystąpienia"

#: app/flatpak-builtins-enter.c:144
msgid "entering not supported (need unprivileged user namespaces, or sudo -E)"
msgstr ""
"przejście jest nieobsługiwane (wymaga nieuprawnionych przestrzeni nazw "
"użytkownika lub „sudo -E”)"

#: app/flatpak-builtins-enter.c:145
#, c-format
msgid "No such pid %s"
msgstr "Brak PID %s"

#: app/flatpak-builtins-enter.c:158
msgid "Can't read cwd"
msgstr "Nie można odczytać polecenia cwd"

#: app/flatpak-builtins-enter.c:163
msgid "Can't read root"
msgstr "Nie można odczytać roota"

#: app/flatpak-builtins-enter.c:191
#, c-format
msgid "Invalid %s namespace for pid %d"
msgstr "Nieprawidłowa przestrzeń nazw %s dla PID %d"

#: app/flatpak-builtins-enter.c:202
#, c-format
msgid "Invalid %s namespace for self"
msgstr "Nieprawidłowa przestrzeń nazw %s dla siebie"

#: app/flatpak-builtins-enter.c:216
#, c-format
msgid "Can't open %s namespace: %s"
msgstr "Nie można otworzyć przestrzeni nazw %s: %s"

#: app/flatpak-builtins-enter.c:226
msgid "entering not supported (need unprivileged user namespaces)"
msgstr ""
"przejście jest nieobsługiwane (wymaga nieuprawnionych przestrzeni nazw "
"użytkownika)"

#: app/flatpak-builtins-enter.c:227
#, c-format
msgid "Can't enter %s namespace: %s"
msgstr "Nie można przejść do przestrzeni nazw %s: %s"

#: app/flatpak-builtins-enter.c:234
msgid "Can't chdir"
msgstr "Nie można wykonać polecenia chdir"

#: app/flatpak-builtins-enter.c:237
msgid "Can't chroot"
msgstr "Nie można wykonać polecenia chroot"

#: app/flatpak-builtins-enter.c:240
msgid "Can't switch gid"
msgstr "Nie można przełączyć GID"

#: app/flatpak-builtins-enter.c:243
msgid "Can't switch uid"
msgstr "Nie można przełączyć UID"

#: app/flatpak-builtins-history.c:50
msgid "Only show changes after TIME"
msgstr "Wyświetla tylko zmiany po CZASIE"

#: app/flatpak-builtins-history.c:50 app/flatpak-builtins-history.c:51
msgid "TIME"
msgstr "CZAS"

#: app/flatpak-builtins-history.c:51
msgid "Only show changes before TIME"
msgstr "Wyświetla tylko zmiany przed CZASEM"

#: app/flatpak-builtins-history.c:52
msgid "Show newest entries first"
msgstr "Wyświetla najpierw najnowsze wpisy"

#: app/flatpak-builtins-history.c:59
msgid "Time"
msgstr "Czas"

#: app/flatpak-builtins-history.c:59
msgid "Show when the change happened"
msgstr "Wyświetla, kiedy zmiana się wydarzyła"

#: app/flatpak-builtins-history.c:60
msgid "Change"
msgstr "Zmiana"

#: app/flatpak-builtins-history.c:60
msgid "Show the kind of change"
msgstr "Wyświetla rodzaj zmiany"

#: app/flatpak-builtins-history.c:61 app/flatpak-builtins-list.c:68
#: app/flatpak-builtins-remote-ls.c:75 app/flatpak-builtins-repo.c:335
msgid "Ref"
msgstr "Odniesienie"

#: app/flatpak-builtins-history.c:61 app/flatpak-builtins-list.c:68
#: app/flatpak-builtins-remote-ls.c:75
msgid "Show the ref"
msgstr "Wyświetla odniesienie"

#: app/flatpak-builtins-history.c:62
msgid "Show the application/runtime ID"
msgstr "Wyświetla identyfikator programu/środowiska wykonawczego"

#: app/flatpak-builtins-history.c:63 app/flatpak-builtins-list.c:64
#: app/flatpak-builtins-ps.c:53 app/flatpak-builtins-remote-ls.c:73
#: app/flatpak-cli-transaction.c:1435
msgid "Arch"
msgstr "Architektura"

#: app/flatpak-builtins-history.c:63 app/flatpak-builtins-list.c:64
#: app/flatpak-builtins-ps.c:53 app/flatpak-builtins-remote-ls.c:73
msgid "Show the architecture"
msgstr "Wyświetla architekturę"

#: app/flatpak-builtins-history.c:64 app/flatpak-builtins-list.c:63
#: app/flatpak-builtins-ps.c:54 app/flatpak-builtins-remote-ls.c:72
#: app/flatpak-builtins-search.c:48 app/flatpak-cli-transaction.c:1438
msgid "Branch"
msgstr "Gałąź"

#: app/flatpak-builtins-history.c:64 app/flatpak-builtins-list.c:63
#: app/flatpak-builtins-remote-ls.c:72
msgid "Show the branch"
msgstr "Wyświetla gałąź"

#: app/flatpak-builtins-history.c:65 app/flatpak-builtins-list.c:67
msgid "Installation"
msgstr "Instalacja"

#: app/flatpak-builtins-history.c:65
msgid "Show the affected installation"
msgstr "Wyświetla instalację, której to dotyczy"

#: app/flatpak-builtins-history.c:66 app/flatpak-cli-transaction.c:1452
msgid "Remote"
msgstr "Repozytorium"

#: app/flatpak-builtins-history.c:66
msgid "Show the remote"
msgstr "Wyświetla repozytorium"

#: app/flatpak-builtins-history.c:67 app/flatpak-builtins-ps.c:55
#: app/flatpak-builtins-remote-ls.c:76
msgid "Commit"
msgstr "Zatwierdzenie"

#: app/flatpak-builtins-history.c:67
msgid "Show the current commit"
msgstr "Wyświetla obecne zatwierdzenie"

#: app/flatpak-builtins-history.c:68
msgid "Old Commit"
msgstr "Poprzednie zatwierdzenie"

#: app/flatpak-builtins-history.c:68
msgid "Show the previous commit"
msgstr "Wyświetla poprzednie zatwierdzenie"

#: app/flatpak-builtins-history.c:69
msgid "Show the remote URL"
msgstr "Wyświetla adres URL repozytorium"

#: app/flatpak-builtins-history.c:70 app/flatpak-cli-transaction.c:700
msgid "User"
msgstr "Użytkownik"

#: app/flatpak-builtins-history.c:70
msgid "Show the user doing the change"
msgstr "Wyświetla użytkownika wprowadzającego zmianę"

#: app/flatpak-builtins-history.c:71
msgid "Tool"
msgstr "Narzędzie"

#: app/flatpak-builtins-history.c:71
msgid "Show the tool that was used"
msgstr "Wyświetla użyte narzędzie"

#: app/flatpak-builtins-history.c:72 app/flatpak-builtins-list.c:62
#: app/flatpak-builtins-remote-ls.c:71 app/flatpak-builtins-search.c:47
msgid "Version"
msgstr "Wersja"

#: app/flatpak-builtins-history.c:72
msgid "Show the Flatpak version"
msgstr "Wyświetla wersję Flatpak"

#: app/flatpak-builtins-history.c:91
#, c-format
msgid "Failed to get journal data (%s): %s"
msgstr "Uzyskanie danych dziennika się nie powiodło (%s): %s"

#: app/flatpak-builtins-history.c:146
#, c-format
msgid "Failed to open journal: %s"
msgstr "Otwarcie dziennika się nie powiodło: %s"

#: app/flatpak-builtins-history.c:153
#, c-format
msgid "Failed to add match to journal: %s"
msgstr "Dodanie wyniku do dziennika się nie powiodło: %s"

#: app/flatpak-builtins-history.c:471
msgid " - Show history"
msgstr " — Wyświetla historię"

#: app/flatpak-builtins-history.c:490
#, c-format
msgid "Failed to parse the --since option"
msgstr "Przetworzenie opcji --since się nie powiodło"

#: app/flatpak-builtins-history.c:501
#, c-format
msgid "Failed to parse the --until option"
msgstr "Przetworzenie opcji --until się nie powiodło"

#: app/flatpak-builtins-info.c:56
msgid "Show user installations"
msgstr "Wyświetla instalacje użytkownika"

#: app/flatpak-builtins-info.c:57
msgid "Show system-wide installations"
msgstr "Wyświetla instalacje systemowe"

#: app/flatpak-builtins-info.c:58
msgid "Show specific system-wide installations"
msgstr "Wyświetla podane instalacje systemowe"

#: app/flatpak-builtins-info.c:59 app/flatpak-builtins-remote-info.c:59
msgid "Show ref"
msgstr "Wyświetla odniesienie"

#: app/flatpak-builtins-info.c:60 app/flatpak-builtins-remote-info.c:60
msgid "Show commit"
msgstr "Wyświetla zatwierdzenie"

#: app/flatpak-builtins-info.c:61
msgid "Show origin"
msgstr "Wyświetla pochodzenie"

#: app/flatpak-builtins-info.c:62
msgid "Show size"
msgstr "Wyświetla rozmiar"

#: app/flatpak-builtins-info.c:63 app/flatpak-builtins-remote-info.c:62
msgid "Show metadata"
msgstr "Wyświetla metadane"

#: app/flatpak-builtins-info.c:64 app/flatpak-builtins-remote-info.c:63
msgid "Show runtime"
msgstr "Wyświetla środowisko wykonawcze"

#: app/flatpak-builtins-info.c:65 app/flatpak-builtins-remote-info.c:64
msgid "Show sdk"
msgstr "Wyświetla środowisko programistyczne"

#: app/flatpak-builtins-info.c:66
msgid "Show permissions"
msgstr "Wyświetla uprawnienia"

#: app/flatpak-builtins-info.c:67
msgid "Query file access"
msgstr "Odpytuje dostęp do plików"

#: app/flatpak-builtins-info.c:67 app/flatpak-builtins-install.c:82
#: app/flatpak-builtins-install.c:88 app/flatpak-builtins-preinstall.c:68
#: app/flatpak-builtins-run.c:182 app/flatpak-builtins-run.c:184
#: app/flatpak-builtins-update.c:67 app/flatpak-builtins-update.c:71
msgid "PATH"
msgstr "ŚCIEŻKA"

#: app/flatpak-builtins-info.c:68
msgid "Show extensions"
msgstr "Wyświetla rozszerzenia"

#: app/flatpak-builtins-info.c:69
msgid "Show location"
msgstr "Wyświetla położenie"

#: app/flatpak-builtins-info.c:116
msgid "NAME [BRANCH] - Get info about an installed app or runtime"
msgstr ""
"NAZWA [GAŁĄŹ] — pobiera informacje o zainstalowanym programie lub środowisku "
"wykonawczym"

#: app/flatpak-builtins-info.c:123 app/flatpak-builtins-remote-add.c:317
#: app/flatpak-builtins-remote-delete.c:63
msgid "NAME must be specified"
msgstr "Należy podać NAZWĘ"

#: app/flatpak-builtins-info.c:196
msgid "ref not present in origin"
msgstr "odniesienia nie ma w pochodzeniu"

#: app/flatpak-builtins-info.c:211 app/flatpak-builtins-remote-info.c:217
#, c-format
msgid "Warning: Commit has no flatpak metadata\n"
msgstr "Ostrzeżenie: zatwierdzenie nie ma metadanych Flatpak\n"

#: app/flatpak-builtins-info.c:217 app/flatpak-builtins-info.c:259
#: app/flatpak-builtins-info.c:455 app/flatpak-builtins-info.c:513
#: app/flatpak-builtins-remote-info.c:236
#: app/flatpak-builtins-remote-info.c:271
msgid "ID:"
msgstr "Identyfikator:"

#: app/flatpak-builtins-info.c:218 app/flatpak-builtins-info.c:260
#: app/flatpak-builtins-remote-info.c:237
#: app/flatpak-builtins-remote-info.c:272
msgid "Ref:"
msgstr "Odniesienie:"

#: app/flatpak-builtins-info.c:219 app/flatpak-builtins-info.c:261
#: app/flatpak-builtins-remote-info.c:238
#: app/flatpak-builtins-remote-info.c:273
msgid "Arch:"
msgstr "Architektura:"

#: app/flatpak-builtins-info.c:220 app/flatpak-builtins-info.c:262
#: app/flatpak-builtins-remote-info.c:239
#: app/flatpak-builtins-remote-info.c:274
msgid "Branch:"
msgstr "Gałąź:"

#: app/flatpak-builtins-info.c:222 app/flatpak-builtins-info.c:264
#: app/flatpak-builtins-remote-info.c:241
#: app/flatpak-builtins-remote-info.c:276
msgid "Version:"
msgstr "Wersja:"

#: app/flatpak-builtins-info.c:224 app/flatpak-builtins-info.c:266
#: app/flatpak-builtins-remote-info.c:243
#: app/flatpak-builtins-remote-info.c:278
msgid "License:"
msgstr "Licencja:"

#: app/flatpak-builtins-info.c:226 app/flatpak-builtins-info.c:269
#: app/flatpak-builtins-remote-info.c:245
#: app/flatpak-builtins-remote-info.c:280
msgid "Collection:"
msgstr "Kolekcja:"

#: app/flatpak-builtins-info.c:227 app/flatpak-builtins-info.c:270
#: app/flatpak-builtins-info.c:458 app/flatpak-builtins-info.c:516
msgid "Installation:"
msgstr "Instalacja:"

#: app/flatpak-builtins-info.c:228 app/flatpak-builtins-info.c:271
#: app/flatpak-builtins-info.c:459 app/flatpak-builtins-info.c:517
#: app/flatpak-builtins-remote-info.c:249
#: app/flatpak-builtins-remote-info.c:284
#, fuzzy
msgid "Installed Size:"
msgstr "Rozmiar po instalacji"

#: app/flatpak-builtins-info.c:231 app/flatpak-builtins-info.c:279
#: app/flatpak-builtins-remote-info.c:252
#: app/flatpak-builtins-remote-info.c:288
msgid "Runtime:"
msgstr "Środowisko wykonawcze:"

#: app/flatpak-builtins-info.c:232 app/flatpak-builtins-info.c:288
#: app/flatpak-builtins-remote-info.c:253
#: app/flatpak-builtins-remote-info.c:293
msgid "Sdk:"
msgstr "Środowisko programistyczne:"

#: app/flatpak-builtins-info.c:235 app/flatpak-builtins-info.c:313
#: app/flatpak-builtins-remote-info.c:256
#: app/flatpak-builtins-remote-info.c:319
msgid "Date:"
msgstr "Data:"

#: app/flatpak-builtins-info.c:237 app/flatpak-builtins-info.c:311
#: app/flatpak-builtins-remote-info.c:258
#: app/flatpak-builtins-remote-info.c:317
msgid "Subject:"
msgstr "Temat:"

#: app/flatpak-builtins-info.c:240 app/flatpak-builtins-info.c:295
msgid "Active commit:"
msgstr "Aktywne zatwierdzenie:"

#: app/flatpak-builtins-info.c:241 app/flatpak-builtins-info.c:298
msgid "Latest commit:"
msgstr "Najnowsze zatwierdzenie:"

#: app/flatpak-builtins-info.c:244 app/flatpak-builtins-info.c:303
#: app/flatpak-builtins-info.c:457 app/flatpak-builtins-info.c:515
#: app/flatpak-builtins-remote-info.c:259
#: app/flatpak-builtins-remote-info.c:298
msgid "Commit:"
msgstr "Zatwierdzenie:"

#: app/flatpak-builtins-info.c:246 app/flatpak-builtins-info.c:308
#: app/flatpak-builtins-remote-info.c:261
#: app/flatpak-builtins-remote-info.c:303
msgid "Parent:"
msgstr "Element nadrzędny:"

#: app/flatpak-builtins-info.c:248 app/flatpak-builtins-info.c:321
msgid "Alt-id:"
msgstr "Alternatywny identyfikator:"

#: app/flatpak-builtins-info.c:250 app/flatpak-builtins-info.c:325
#: app/flatpak-builtins-remote-info.c:263
#: app/flatpak-builtins-remote-info.c:308
msgid "End-of-life:"
msgstr "Niewspierane:"

#: app/flatpak-builtins-info.c:252 app/flatpak-builtins-info.c:330
#: app/flatpak-builtins-remote-info.c:265
#: app/flatpak-builtins-remote-info.c:313
msgid "End-of-life-rebase:"
msgstr "Niewspierane-rebase:"

#: app/flatpak-builtins-info.c:254 app/flatpak-builtins-info.c:317
msgid "Subdirectories:"
msgstr "Podkatalogi:"

#: app/flatpak-builtins-info.c:255 app/flatpak-builtins-info.c:454
#: app/flatpak-builtins-info.c:512
msgid "Extension:"
msgstr "Rozszerzenie:"

#: app/flatpak-builtins-info.c:267 app/flatpak-builtins-info.c:456
#: app/flatpak-builtins-info.c:514
msgid "Origin:"
msgstr "Pochodzenie:"

#: app/flatpak-builtins-info.c:460 app/flatpak-builtins-info.c:522
msgid "Subpaths:"
msgstr "Podścieżki:"

#: app/flatpak-builtins-info.c:478
msgid "unmaintained"
msgstr "niewspierane"

#: app/flatpak-builtins-info.c:480 app/flatpak-builtins-info.c:482
msgid "unknown"
msgstr "nieznane"

#: app/flatpak-builtins-install.c:68 app/flatpak-builtins-preinstall.c:57
msgid "Don't pull, only install from local cache"
msgstr "Bez pobierania, tylko instaluje z lokalnej pamięci podręcznej"

#: app/flatpak-builtins-install.c:69 app/flatpak-builtins-preinstall.c:58
#: app/flatpak-builtins-update.c:60
msgid "Don't deploy, only download to local cache"
msgstr "Bez wdrażania, tylko pobiera do lokalnej pamięci podręcznej"

#: app/flatpak-builtins-install.c:70 app/flatpak-builtins-preinstall.c:59
msgid "Don't install related refs"
msgstr "Bez instalowania powiązanych odniesień"

#: app/flatpak-builtins-install.c:71 app/flatpak-builtins-preinstall.c:60
#: app/flatpak-builtins-update.c:62
msgid "Don't verify/install runtime dependencies"
msgstr "Bez sprawdzania poprawności/instalowania zależności wykonawczych"

#: app/flatpak-builtins-install.c:72
msgid "Don't automatically pin explicit installs"
msgstr "Bez automatycznego przypinania instalacji przez użytkownika"

#: app/flatpak-builtins-install.c:73 app/flatpak-builtins-preinstall.c:61
#: app/flatpak-builtins-update.c:63
msgid "Don't use static deltas"
msgstr "Bez używania statycznych delt"

#: app/flatpak-builtins-install.c:76 app/flatpak-builtins-preinstall.c:62
msgid "Additionally install the SDK used to build the given refs"
msgstr ""
"Dodatkowo instaluje środowisko programistyczne użyte do zbudowania podanych "
"odniesień"

#: app/flatpak-builtins-install.c:77 app/flatpak-builtins-preinstall.c:63
msgid ""
"Additionally install the debug info for the given refs and their dependencies"
msgstr ""
"Dodatkowo instaluje informacje debugowania dla podanych odniesień i ich "
"zależności"

#: app/flatpak-builtins-install.c:78
msgid "Assume LOCATION is a .flatpak single-file bundle"
msgstr "Przyjmuje, że POŁOŻENIE to jednoplikowy pakiet .flatpak"

#: app/flatpak-builtins-install.c:79
msgid "Assume LOCATION is a .flatpakref application description"
msgstr "Przyjmuje, że POŁOŻENIE to opis programu .flatpakref"

#: app/flatpak-builtins-install.c:80
msgid "Assume LOCATION is containers-transports(5) reference to an OCI image"
msgstr ""
"Przyjmuje, że POŁOŻENIE to odniesienie containers-transports(5) do obrazu OCI"

#: app/flatpak-builtins-install.c:81
msgid "Check bundle signatures with GPG key from FILE (- for stdin)"
msgstr ""
"Sprawdza podpisy pakietów za pomocą klucza GPG z PLIKU (- dla standardowego "
"wejścia)"

#: app/flatpak-builtins-install.c:82
msgid "Only install this subpath"
msgstr "Instaluje tylko tę podścieżkę"

#: app/flatpak-builtins-install.c:83 app/flatpak-builtins-preinstall.c:64
#: app/flatpak-builtins-uninstall.c:63 app/flatpak-builtins-update.c:68
msgid "Automatically answer yes for all questions"
msgstr "Automatycznie odpowiada tak na wszystkie pytania"

#: app/flatpak-builtins-install.c:84 app/flatpak-builtins-preinstall.c:65
msgid "Uninstall first if already installed"
msgstr "Należy najpierw odinstalować, jeśli jest już zainstalowane"

#: app/flatpak-builtins-install.c:85 app/flatpak-builtins-preinstall.c:66
#: app/flatpak-builtins-uninstall.c:64 app/flatpak-builtins-update.c:69
msgid "Produce minimal output and don't ask questions"
msgstr "Wyświetla minimum informacji i nie zadaje pytań"

#: app/flatpak-builtins-install.c:86
msgid "Update install if already installed"
msgstr "Aktualizuje instalację, jeśli jest już zainstalowane"

#. Translators: A sideload is when you install from a local USB drive rather than the Internet.
#: app/flatpak-builtins-install.c:88 app/flatpak-builtins-preinstall.c:68
#: app/flatpak-builtins-update.c:71
msgid "Use this local repo for sideloads"
msgstr "Używa tego lokalnego repozytorium do wczytywania bocznego"

#: app/flatpak-builtins-install.c:178
msgid "Bundle filename must be specified"
msgstr "Należy podać nazwę pliku pakietu"

#: app/flatpak-builtins-install.c:188
msgid "Remote bundles are not supported"
msgstr "Zdalne pakiety nie są obsługiwane"

#: app/flatpak-builtins-install.c:231
msgid "Filename or uri must be specified"
msgstr "Należy podać nazwę pliku lub adres URI"

#: app/flatpak-builtins-install.c:295
msgid "Image location must be specified"
msgstr "Należy podać położenie obrazu"

#: app/flatpak-builtins-install.c:345
msgid "[LOCATION/REMOTE] [REF…] - Install applications or runtimes"
msgstr ""
"[POŁOŻENIE/REPOZYTORIUM] [ODNIESIENIE…] — instaluje programy lub środowiska "
"wykonawcze"

#: app/flatpak-builtins-install.c:378
msgid "At least one REF must be specified"
msgstr "Należy podać co najmniej jedno ODNIESIENIE"

#: app/flatpak-builtins-install.c:392
#, c-format
msgid "Looking for matches…\n"
msgstr "Wyszukiwanie wyników…\n"

#: app/flatpak-builtins-install.c:513
#, c-format
msgid "No remote refs found for ‘%s’"
msgstr "Nie odnaleziono zdalnych odniesień dla „%s”"

#: app/flatpak-builtins-install.c:573 app/flatpak-builtins-uninstall.c:405
#: common/flatpak-ref-utils.c:689 common/flatpak-ref-utils.c:1595
#, c-format
msgid "Invalid branch %s: %s"
msgstr "Nieprawidłowa gałąź %s: %s"

#: app/flatpak-builtins-install.c:606
#, c-format
msgid "Nothing matches %s in local repository for remote %s"
msgstr "Nic nie pasuje do %s w lokalnym repozytorium dla %s"

#: app/flatpak-builtins-install.c:608
#, c-format
msgid "Nothing matches %s in remote %s"
msgstr "Nic nie pasuje do %s w repozytorium %s"

#: app/flatpak-builtins-install.c:629
#, c-format
msgid "Skipping: %s\n"
msgstr "Pomijanie: %s\n"

#: app/flatpak-builtins-kill.c:110
#, c-format
msgid "%s is not running"
msgstr "%s nie jest uruchomione"

#: app/flatpak-builtins-kill.c:136
msgid "INSTANCE - Stop a running application"
msgstr "WYSTĄPIENIE — zatrzymuje uruchomiony program"

#: app/flatpak-builtins-kill.c:144 app/flatpak-builtins-ps.c:256
msgid "Extra arguments given"
msgstr "Podano dodatkowe parametry"

#: app/flatpak-builtins-kill.c:150
msgid "Must specify the app to kill"
msgstr "Należy podać program do zatrzymania"

#: app/flatpak-builtins-list.c:47
msgid "Show extra information"
msgstr "Wyświetla dodatkowe informacje"

#: app/flatpak-builtins-list.c:48
msgid "List installed runtimes"
msgstr "Wyświetla listę zainstalowanych środowisk wykonawczych"

#: app/flatpak-builtins-list.c:49
msgid "List installed applications"
msgstr "Wyświetla listę zainstalowanych programów"

#: app/flatpak-builtins-list.c:50
msgid "Arch to show"
msgstr "Wyświetlana architektura"

#: app/flatpak-builtins-list.c:51 app/flatpak-builtins-remote-ls.c:57
msgid "List all refs (including locale/debug)"
msgstr "Wyświetla listę wszystkich odniesień (także lokalizacji/debugowania)"

#: app/flatpak-builtins-list.c:53 app/flatpak-builtins-remote-ls.c:58
msgid "List all applications using RUNTIME"
msgstr ""
"Wyświetla listę wszystkich programów używających ŚRODOWISKA-WYKONAWCZEGO"

#: app/flatpak-builtins-list.c:59 app/flatpak-builtins-remote-list.c:51
#: app/flatpak-builtins-remote-ls.c:68 app/flatpak-builtins-search.c:44
msgid "Name"
msgstr "Nazwa"

#: app/flatpak-builtins-list.c:59 app/flatpak-builtins-remote-list.c:51
#: app/flatpak-builtins-remote-ls.c:68 app/flatpak-builtins-search.c:44
msgid "Show the name"
msgstr "Wyświetla nazwę"

#: app/flatpak-builtins-list.c:60 app/flatpak-builtins-remote-list.c:60
#: app/flatpak-builtins-remote-ls.c:69 app/flatpak-builtins-search.c:45
msgid "Description"
msgstr "Opis"

#: app/flatpak-builtins-list.c:60 app/flatpak-builtins-remote-ls.c:69
#: app/flatpak-builtins-search.c:45
msgid "Show the description"
msgstr "Wyświetla opis"

#: app/flatpak-builtins-list.c:61 app/flatpak-builtins-remote-ls.c:70
#: app/flatpak-builtins-search.c:46
msgid "Application ID"
msgstr "Identyfikator programu"

#: app/flatpak-builtins-list.c:61 app/flatpak-builtins-ps.c:52
#: app/flatpak-builtins-remote-ls.c:70 app/flatpak-builtins-search.c:46
msgid "Show the application ID"
msgstr "Wyświetla identyfikator programu"

#: app/flatpak-builtins-list.c:62 app/flatpak-builtins-remote-ls.c:71
#: app/flatpak-builtins-search.c:47
msgid "Show the version"
msgstr "Wyświetla wersję"

#: app/flatpak-builtins-list.c:65 app/flatpak-builtins-ps.c:56
#: app/flatpak-builtins-remote-ls.c:77
msgid "Runtime"
msgstr "Środowisko wykonawcze"

#: app/flatpak-builtins-list.c:65
msgid "Show the used runtime"
msgstr "Wyświetla używane środowisko wykonawcze"

#: app/flatpak-builtins-list.c:66 app/flatpak-builtins-remote-ls.c:74
msgid "Show the origin remote"
msgstr "Wyświetla repozytorium pochodzenia"

#: app/flatpak-builtins-list.c:67
msgid "Show the installation"
msgstr "Wyświetla instalację"

#: app/flatpak-builtins-list.c:69
msgid "Active commit"
msgstr "Aktywne zatwierdzenie"

#: app/flatpak-builtins-list.c:69 app/flatpak-builtins-remote-ls.c:76
msgid "Show the active commit"
msgstr "Wyświetla aktywne zatwierdzenie"

#: app/flatpak-builtins-list.c:70
msgid "Latest commit"
msgstr "Najnowsze zatwierdzenie"

#: app/flatpak-builtins-list.c:70
msgid "Show the latest commit"
msgstr "Wyświetla najnowsze zatwierdzenie"

#: app/flatpak-builtins-list.c:71 app/flatpak-builtins-remote-ls.c:78
msgid "Installed size"
msgstr "Rozmiar po instalacji"

#: app/flatpak-builtins-list.c:71 app/flatpak-builtins-remote-ls.c:78
msgid "Show the installed size"
msgstr "Wyświetla rozmiar po instalacji"

#: app/flatpak-builtins-list.c:72 app/flatpak-builtins-remote-list.c:58
#: app/flatpak-builtins-remote-ls.c:80 app/flatpak-builtins-repo.c:340
msgid "Options"
msgstr "Opcje"

#: app/flatpak-builtins-list.c:72 app/flatpak-builtins-remote-list.c:58
#: app/flatpak-builtins-remote-ls.c:80
msgid "Show options"
msgstr "Wyświetla opcje"

#: app/flatpak-builtins-list.c:180
#, c-format
msgid "Unable to load details of %s: %s"
msgstr "Nie można wczytać szczegółów %s: %s"

#: app/flatpak-builtins-list.c:190
#, c-format
msgid "Unable to inspect current version of %s: %s"
msgstr "Nie można zbadać obecnej wersji %s: %s"

#: app/flatpak-builtins-list.c:408
msgid " - List installed apps and/or runtimes"
msgstr ""
" — wyświetla listę zainstalowanych programów lub środowisk wykonawczych"

#: app/flatpak-builtins-make-current.c:38
msgid "Arch to make current for"
msgstr "Architektura ustawiania na bieżącą"

#: app/flatpak-builtins-make-current.c:58
msgid "APP BRANCH - Make branch of application current"
msgstr "PROGRAM GAŁĄŹ — ustawia gałąź programu jako bieżącą"

#: app/flatpak-builtins-make-current.c:69 app/flatpak-builtins-run.c:260
msgid "APP must be specified"
msgstr "Należy podać PROGRAM"

#: app/flatpak-builtins-make-current.c:84
msgid "BRANCH must be specified"
msgstr "Należy podać GAŁĄŹ"

#: app/flatpak-builtins-make-current.c:97
#, c-format
msgid "App %s branch %s is not installed"
msgstr "Nie zainstalowano programu %s, gałęzi %s"

#: app/flatpak-builtins-mask.c:42
msgid "Remove matching masks"
msgstr "Usuwa pasujące maski"

#: app/flatpak-builtins-mask.c:54
msgid ""
"[PATTERN…] - disable updates and automatic installation matching patterns"
msgstr ""
"[WZÓR…] — wyłącza aktualizacje i automatyczną instalację pasujących wzorów"

#: app/flatpak-builtins-mask.c:73
#, c-format
msgid "No masked patterns\n"
msgstr "Brak zamaskowanych wzorów\n"

#: app/flatpak-builtins-mask.c:78
#, c-format
msgid "Masked patterns:\n"
msgstr "Zamaskowane wzory:\n"

#: app/flatpak-builtins-override.c:42
msgid "Remove existing overrides"
msgstr "Usuwa istniejące zastępniki"

#: app/flatpak-builtins-override.c:43
msgid "Show existing overrides"
msgstr "Wyświetla istniejące zastępniki"

#: app/flatpak-builtins-override.c:59
msgid "[APP] - Override settings [for application]"
msgstr "[PROGRAM] — zastępuje ustawienia [programu]"

#: app/flatpak-builtins-permission-list.c:143
msgid "[TABLE] [ID] - List permissions"
msgstr "[TABLICA] [IDENTYFIKATOR] — wyświetla listę uprawnień"

#: app/flatpak-builtins-permission-list.c:179
#: app/flatpak-builtins-permission-show.c:142
msgid "Table"
msgstr "Tablica"

#: app/flatpak-builtins-permission-list.c:180
#: app/flatpak-builtins-permission-show.c:143
msgid "Object"
msgstr "Obiekt"

#: app/flatpak-builtins-permission-list.c:181
#: app/flatpak-builtins-permission-show.c:144
msgid "App"
msgstr "Program"

#: app/flatpak-builtins-permission-list.c:183
#: app/flatpak-builtins-permission-show.c:146
msgid "Data"
msgstr "Dane"

#: app/flatpak-builtins-permission-remove.c:120
msgid "TABLE ID [APP_ID] - Remove item from permission store"
msgstr ""
"TABLICA IDENTYFIKATOR [IDENTYFIKATOR_PROGRAMU] — usuwa element "
"z przechowalni uprawnień"

#: app/flatpak-builtins-permission-remove.c:129
#: app/flatpak-builtins-permission-set.c:120
msgid "Too few arguments"
msgstr "Za mało parametrów"

#: app/flatpak-builtins-permission-reset.c:43
msgid "Reset all permissions"
msgstr "Przywraca wszystkie uprawnienia"

#: app/flatpak-builtins-permission-reset.c:144
msgid "APP_ID - Reset permissions for an app"
msgstr "IDENTYFIKATOR_PROGRAMU — przywraca uprawnienia programowi"

#: app/flatpak-builtins-permission-reset.c:153
#: app/flatpak-builtins-permission-show.c:124
msgid "Wrong number of arguments"
msgstr "Błędna liczba parametrów"

#: app/flatpak-builtins-permission-set.c:42
msgid "Associate DATA with the entry"
msgstr "Kojarzy DANE z wpisem"

#: app/flatpak-builtins-permission-set.c:42
msgid "DATA"
msgstr "DANE"

#: app/flatpak-builtins-permission-set.c:111
msgid "TABLE ID APP_ID [PERMISSION...] - Set permissions"
msgstr ""
"TABLICA IDENTYFIKATOR IDENTYFIKATOR_PROGRAMU [UPRAWNIENIE…] — ustawia "
"uprawnienia"

#: app/flatpak-builtins-permission-set.c:132
#, c-format
msgid "Failed to parse '%s' as GVariant: "
msgstr "Przetworzenie „%s” jako GVariant się nie powiodło: "

#: app/flatpak-builtins-permission-show.c:115
msgid "APP_ID - Show permissions for an app"
msgstr "IDENTYFIKATOR_PROGRAMU — wyświetla uprawnienia programu"

#: app/flatpak-builtins-pin.c:44
msgid "Remove matching pins"
msgstr "Usuwa pasujące przypięcia"

#: app/flatpak-builtins-pin.c:56
msgid "[PATTERN…] - disable automatic removal of runtimes matching patterns"
msgstr ""
"[WZÓR…] — wyłącza automatyczne usuwanie środowisk wykonawczych pasujących do "
"wzorów"

#: app/flatpak-builtins-pin.c:75
#, c-format
msgid "No pinned patterns\n"
msgstr "Brak przypiętych wzorów\n"

#: app/flatpak-builtins-pin.c:80
#, c-format
msgid "Pinned patterns:\n"
msgstr "Przypięte wzory:\n"

#: app/flatpak-builtins-preinstall.c:80
msgid "- Install flatpaks that are part of the operating system"
msgstr "— instaluje pakiety Flatpak będące częścią systemu operacyjnego"

#: app/flatpak-builtins-preinstall.c:118
#, c-format
msgid "Nothing to do.\n"
msgstr "Nie ma nic do zrobienia.\n"

#: app/flatpak-builtins-ps.c:49
msgid "Instance"
msgstr "Wystąpienie"

#: app/flatpak-builtins-ps.c:49
msgid "Show the instance ID"
msgstr "Wyświetla identyfikator wystąpienia"

#: app/flatpak-builtins-ps.c:50 app/flatpak-builtins-run.c:178
msgid "PID"
msgstr "PID"

#: app/flatpak-builtins-ps.c:50
msgid "Show the PID of the wrapper process"
msgstr "Wyświetla PID procesu zawijającego"

#: app/flatpak-builtins-ps.c:51
msgid "Child-PID"
msgstr "PID elementu potomnego"

#: app/flatpak-builtins-ps.c:51
msgid "Show the PID of the sandbox process"
msgstr "Wyświetla PID procesu piaskownicy"

#: app/flatpak-builtins-ps.c:54 app/flatpak-builtins-search.c:48
msgid "Show the application branch"
msgstr "Wyświetla gałąź programu"

#: app/flatpak-builtins-ps.c:55
msgid "Show the application commit"
msgstr "Wyświetla zatwierdzenie programu"

#: app/flatpak-builtins-ps.c:56
msgid "Show the runtime ID"
msgstr "Wyświetla identyfikator środowiska wykonawczego"

#: app/flatpak-builtins-ps.c:57
msgid "R.-Branch"
msgstr "Gałąź-Śr."

#: app/flatpak-builtins-ps.c:57
msgid "Show the runtime branch"
msgstr "Wyświetla gałąź środowiska wykonawczego"

#: app/flatpak-builtins-ps.c:58
msgid "R.-Commit"
msgstr "Zatwierdzenie-Śr."

#: app/flatpak-builtins-ps.c:58
msgid "Show the runtime commit"
msgstr "Wyświetla zatwierdzenie środowiska wykonawczego"

#: app/flatpak-builtins-ps.c:59
msgid "Active"
msgstr "Aktywne"

#: app/flatpak-builtins-ps.c:59
msgid "Show whether the app is active"
msgstr "Wyświetla, czy program jest aktywny"

#: app/flatpak-builtins-ps.c:60
msgid "Background"
msgstr "W tle"

#: app/flatpak-builtins-ps.c:60
msgid "Show whether the app is background"
msgstr "Wyświetla, czy program jest w tle"

#: app/flatpak-builtins-ps.c:246
msgid " - Enumerate running sandboxes"
msgstr " — wylicza działające piaskownice"

#: app/flatpak-builtins-remote-add.c:66
msgid "Do nothing if the provided remote exists"
msgstr "Nie robi nic, jeśli podane repozytorium istnieje"

#: app/flatpak-builtins-remote-add.c:67
msgid "LOCATION specifies a configuration file, not the repo location"
msgstr "POŁOŻENIE podaje plik konfiguracji, nie położenie repozytorium"

#: app/flatpak-builtins-remote-add.c:72 app/flatpak-builtins-remote-modify.c:78
msgid "Disable GPG verification"
msgstr "Wyłącza sprawdzanie poprawności GPG"

#: app/flatpak-builtins-remote-add.c:73 app/flatpak-builtins-remote-modify.c:79
msgid "Mark the remote as don't enumerate"
msgstr "Oznacza repozytorium jako niewyliczeniowe"

#: app/flatpak-builtins-remote-add.c:74 app/flatpak-builtins-remote-modify.c:80
msgid "Mark the remote as don't use for deps"
msgstr "Oznacza repozytorium jako nieużywane dla zależności"

#: app/flatpak-builtins-remote-add.c:75 app/flatpak-builtins-remote-modify.c:81
msgid "Set priority (default 1, higher is more prioritized)"
msgstr "Ustawia priorytet (domyślnie 1, wyższy numer to wyższy priorytet)"

#: app/flatpak-builtins-remote-add.c:75 app/flatpak-builtins-remote-modify.c:81
msgid "PRIORITY"
msgstr "PRIORYTET"

#: app/flatpak-builtins-remote-add.c:76
msgid "The named subset to use for this remote"
msgstr "Nazwany podzbiór używany dla tego repozytorium"

#: app/flatpak-builtins-remote-add.c:76 app/flatpak-builtins-remote-modify.c:71
msgid "SUBSET"
msgstr "PODZBIÓR"

#: app/flatpak-builtins-remote-add.c:77 app/flatpak-builtins-remote-modify.c:82
msgid "A nice name to use for this remote"
msgstr "Czytelna nazwa tego repozytorium"

#: app/flatpak-builtins-remote-add.c:78 app/flatpak-builtins-remote-modify.c:83
msgid "A one-line comment for this remote"
msgstr "Jednowierszowy komentarz dla tego repozytorium"

#: app/flatpak-builtins-remote-add.c:79 app/flatpak-builtins-remote-modify.c:84
msgid "A full-paragraph description for this remote"
msgstr "Akapit opisu dla tego repozytorium"

#: app/flatpak-builtins-remote-add.c:80 app/flatpak-builtins-remote-modify.c:85
msgid "URL for a website for this remote"
msgstr "Adres URL strony dla tego repozytorium"

#: app/flatpak-builtins-remote-add.c:81 app/flatpak-builtins-remote-modify.c:86
msgid "URL for an icon for this remote"
msgstr "Adres URL ikony dla tego repozytorium"

#: app/flatpak-builtins-remote-add.c:82 app/flatpak-builtins-remote-modify.c:87
msgid "Default branch to use for this remote"
msgstr "Domyślna gałąź używana dla tego repozytorium"

#: app/flatpak-builtins-remote-add.c:84 app/flatpak-builtins-remote-modify.c:89
msgid "Import GPG key from FILE (- for stdin)"
msgstr "Importuje klucz GPG z PLIKU (- dla standardowego wejścia)"

#: app/flatpak-builtins-remote-add.c:85 app/flatpak-builtins-remote-modify.c:90
msgid "Load signatures from URL"
msgstr ""

#: app/flatpak-builtins-remote-add.c:86 app/flatpak-builtins-remote-modify.c:92
msgid "Set path to local filter FILE"
msgstr "Ustawia ścieżkę do PLIKU lokalnego filtru"

#: app/flatpak-builtins-remote-add.c:87 app/flatpak-builtins-remote-modify.c:93
msgid "Disable the remote"
msgstr "Wyłącza repozytorium"

#: app/flatpak-builtins-remote-add.c:88 app/flatpak-builtins-remote-modify.c:94
msgid "Name of authenticator"
msgstr "Nazwa programu uwierzytelniającego"

#: app/flatpak-builtins-remote-add.c:90 app/flatpak-builtins-remote-modify.c:96
msgid "Autoinstall authenticator"
msgstr "Automatycznie instaluje program uwierzytelniający"

#: app/flatpak-builtins-remote-add.c:91 app/flatpak-builtins-remote-modify.c:97
msgid "Don't autoinstall authenticator"
msgstr "Bez automatycznego instalowania programu uwierzytelniającego"

#: app/flatpak-builtins-remote-add.c:92 app/flatpak-builtins-remote-modify.c:99
msgid "Don't follow the redirect set in the summary file"
msgstr "Bez podążania za przekierowaniem ustawionym w pliku podsumowania"

#: app/flatpak-builtins-remote-add.c:261 app/flatpak-builtins-remote-add.c:268
#, c-format
msgid "Can't load uri %s: %s\n"
msgstr "Nie można wczytać adresu URI %s: %s\n"

#: app/flatpak-builtins-remote-add.c:276 common/flatpak-dir.c:4643
#, c-format
msgid "Can't load file %s: %s\n"
msgstr "Nie można wczytać pliku %s: %s\n"

#: app/flatpak-builtins-remote-add.c:304
msgid "NAME LOCATION - Add a remote repository"
msgstr "NAZWA POŁOŻENIE — dodaje zdalne repozytorium"

#: app/flatpak-builtins-remote-add.c:331
msgid "GPG verification is required if collections are enabled"
msgstr "Sprawdzanie poprawności GPG jest wymagane, jeśli kolekcje są włączone"

#: app/flatpak-builtins-remote-add.c:393
#, c-format
msgid "Remote %s already exists"
msgstr "Repozytorium %s już istnieje"

#: app/flatpak-builtins-remote-add.c:405
#: app/flatpak-builtins-remote-modify.c:340
#, c-format
msgid "Invalid authenticator name %s"
msgstr "Nieprawidłowa nazwa programu uwierzytelniającego %s"

#: app/flatpak-builtins-remote-add.c:422
#, c-format
msgid "Warning: Could not update extra metadata for '%s': %s\n"
msgstr ""
"Ostrzeżenie: nie można zaktualizować dodatkowych metadanych dla „%s”: %s\n"

#: app/flatpak-builtins-remote-delete.c:39
msgid "Remove remote even if in use"
msgstr "Usuwa repozytorium nawet, jeśli jest używane"

#: app/flatpak-builtins-remote-delete.c:53
msgid "NAME - Delete a remote repository"
msgstr "NAZWA — usuwa zdalne repozytorium"

#: app/flatpak-builtins-remote-delete.c:100
#, c-format
msgid "The following refs are installed from remote '%s':"
msgstr "Te odniesienia są zainstalowane z repozytorium „%s”:"

#: app/flatpak-builtins-remote-delete.c:101
msgid "Remove them?"
msgstr "Usunąć je?"

#: app/flatpak-builtins-remote-delete.c:103
#, c-format
msgid "Can't remove remote '%s' with installed refs"
msgstr "Nie można usunąć repozytorium „%s” z zainstalowanymi odniesieniami"

#: app/flatpak-builtins-remote-info.c:55
msgid "Commit to show info for"
msgstr "Zatwierdzenie, dla którego wyświetlić informacje"

#: app/flatpak-builtins-remote-info.c:58
msgid "Display log"
msgstr "Wyświetla dziennik"

#: app/flatpak-builtins-remote-info.c:61
msgid "Show parent"
msgstr "Wyświetla element nadrzędny"

#: app/flatpak-builtins-remote-info.c:65 app/flatpak-builtins-remote-ls.c:60
msgid "Use local caches even if they are stale"
msgstr "Używa lokalnych pamięci podręcznych, nawet jeśli są przeterminowane"

#. Translators: A sideload is when you install from a local USB drive rather than the Internet.
#: app/flatpak-builtins-remote-info.c:67 app/flatpak-builtins-remote-ls.c:62
msgid "Only list refs available as sideloads"
msgstr "Wyświetla tylko odniesienia dostępne jako wczytywanie boczne"

#: app/flatpak-builtins-remote-info.c:114
msgid ""
" REMOTE REF - Show information about an application or runtime in a remote"
msgstr ""
" REPOZYTORIUM ODNIESIENIE — wyświetla informacje o programie lub środowisku "
"wykonawczym w repozytorium"

#: app/flatpak-builtins-remote-info.c:125
msgid "REMOTE and REF must be specified"
msgstr "Należy podać REPOZYTORIUM i ODNIESIENIE"

#: app/flatpak-builtins-remote-info.c:247
#: app/flatpak-builtins-remote-info.c:282
#, fuzzy
msgid "Download Size:"
msgstr "Rozmiar do pobrania"

#: app/flatpak-builtins-remote-info.c:267
#: app/flatpak-builtins-remote-info.c:325
msgid "History:"
msgstr "Historia:"

#: app/flatpak-builtins-remote-info.c:348
msgid " Commit:"
msgstr " Zatwierdzenie:"

#: app/flatpak-builtins-remote-info.c:349
msgid " Subject:"
msgstr " Temat:"

#: app/flatpak-builtins-remote-info.c:350
msgid " Date:"
msgstr " Data:"

#: app/flatpak-builtins-remote-info.c:383
#, c-format
msgid "Warning: Commit %s has no flatpak metadata\n"
msgstr "Ostrzeżenie: zatwierdzenie %s nie ma metadanych Flatpak\n"

#: app/flatpak-builtins-remote-list.c:43
msgid "Show remote details"
msgstr "Wyświetla informacje o repozytorium"

#: app/flatpak-builtins-remote-list.c:44
msgid "Show disabled remotes"
msgstr "Wyświetla wyłączone repozytoria"

#: app/flatpak-builtins-remote-list.c:52
msgid "Title"
msgstr "Tytuł"

#: app/flatpak-builtins-remote-list.c:52
msgid "Show the title"
msgstr "Wyświetla tytuł"

#: app/flatpak-builtins-remote-list.c:53
msgid "Show the URL"
msgstr "Wyświetla adres URL"

#: app/flatpak-builtins-remote-list.c:54
msgid "Show the collection ID"
msgstr "Wyświetla identyfikator kolekcji"

#: app/flatpak-builtins-remote-list.c:55 app/flatpak-builtins-repo.c:392
msgid "Subset"
msgstr "Podzbiór"

#: app/flatpak-builtins-remote-list.c:55
msgid "Show the subset"
msgstr "Wyświetla podzbiór"

#: app/flatpak-builtins-remote-list.c:56
msgid "Filter"
msgstr "Filtr"

#: app/flatpak-builtins-remote-list.c:56
msgid "Show filter file"
msgstr "Wyświetla plik filtra"

#: app/flatpak-builtins-remote-list.c:57
msgid "Priority"
msgstr "Priorytet"

#: app/flatpak-builtins-remote-list.c:57
msgid "Show the priority"
msgstr "Wyświetla priorytet"

#: app/flatpak-builtins-remote-list.c:59
msgid "Comment"
msgstr "Komentarz"

#: app/flatpak-builtins-remote-list.c:59
msgid "Show comment"
msgstr "Wyświetla komentarz"

#: app/flatpak-builtins-remote-list.c:60
msgid "Show description"
msgstr "Wyświetla opis"

#: app/flatpak-builtins-remote-list.c:61
msgid "Homepage"
msgstr "Strona domowa"

#: app/flatpak-builtins-remote-list.c:61
msgid "Show homepage"
msgstr "Wyświetla stronę domową"

#: app/flatpak-builtins-remote-list.c:62
msgid "Icon"
msgstr "Ikona"

#: app/flatpak-builtins-remote-list.c:62
msgid "Show icon"
msgstr "Wyświetla ikonę"

#: app/flatpak-builtins-remote-list.c:231
msgid " - List remote repositories"
msgstr " — wyświetla listę zdalnych repozytoriów"

#: app/flatpak-builtins-remote-ls.c:52
msgid "Show arches and branches"
msgstr "Wyświetla architektury i gałęzie"

#: app/flatpak-builtins-remote-ls.c:53
msgid "Show only runtimes"
msgstr "Wyświetla tylko środowiska wykonawcze"

#: app/flatpak-builtins-remote-ls.c:54
msgid "Show only apps"
msgstr "Wyświetla tylko programy"

#: app/flatpak-builtins-remote-ls.c:55
msgid "Show only those where updates are available"
msgstr "Wyświetla tylko z dostępnymi aktualizacjami"

#: app/flatpak-builtins-remote-ls.c:56
msgid "Limit to this arch (* for all)"
msgstr "Ogranicza do tej architektury (* dla wszystkich)"

#: app/flatpak-builtins-remote-ls.c:77
msgid "Show the runtime"
msgstr "Wyświetla środowisko wykonawcze"

#: app/flatpak-builtins-remote-ls.c:79
msgid "Download size"
msgstr "Rozmiar do pobrania"

#: app/flatpak-builtins-remote-ls.c:79
msgid "Show the download size"
msgstr "Wyświetla rozmiar do pobrania"

#: app/flatpak-builtins-remote-ls.c:391
msgid " [REMOTE or URI] - Show available runtimes and applications"
msgstr ""
" [REPOZYTORIUM lub URI] — wyświetla dostępne środowiska wykonawcze i programy"

#: app/flatpak-builtins-remote-modify.c:67
msgid "Enable GPG verification"
msgstr "Włącza sprawdzanie poprawności GPG"

#: app/flatpak-builtins-remote-modify.c:68
msgid "Mark the remote as enumerate"
msgstr "Oznacza repozytorium jako wyliczeniowe"

#: app/flatpak-builtins-remote-modify.c:69
msgid "Mark the remote as used for dependencies"
msgstr "Oznacza repozytorium jako używane dla zależności"

#: app/flatpak-builtins-remote-modify.c:70
#, fuzzy
msgid "Set a new URL"
msgstr "Ustawia nowy adres URL"

#: app/flatpak-builtins-remote-modify.c:71
msgid "Set a new subset to use"
msgstr "Ustawia nowy podzbiór do użycia"

#: app/flatpak-builtins-remote-modify.c:72
msgid "Enable the remote"
msgstr "Włącza repozytorium"

#: app/flatpak-builtins-remote-modify.c:73
msgid "Update extra metadata from the summary file"
msgstr "Aktualizuje dodatkowe metadane z pliku podsumowania"

#: app/flatpak-builtins-remote-modify.c:91
msgid "Disable local filter"
msgstr "Wyłącza lokalny filtr"

#: app/flatpak-builtins-remote-modify.c:95
msgid "Authenticator options"
msgstr "Opcje programu uwierzytelniającego"

#: app/flatpak-builtins-remote-modify.c:98
msgid "Follow the redirect set in the summary file"
msgstr "Podąża za przekierowaniem ustawionym w pliku podsumowania"

#: app/flatpak-builtins-remote-modify.c:306
msgid "NAME - Modify a remote repository"
msgstr "NAZWA — modyfikuje zdalne repozytorium"

#: app/flatpak-builtins-remote-modify.c:316
msgid "Remote NAME must be specified"
msgstr "Należy podać NAZWĘ repozytorium"

#: app/flatpak-builtins-remote-modify.c:327
#, c-format
msgid "Updating extra metadata from remote summary for %s\n"
msgstr ""
"Aktualizowanie dodatkowych metadanych z podsumowania repozytorium dla %s\n"

#: app/flatpak-builtins-remote-modify.c:330
#, c-format
msgid "Error updating extra metadata for '%s': %s\n"
msgstr "Błąd podczas aktualizowania dodatkowych metadanych dla „%s”: %s\n"

#: app/flatpak-builtins-remote-modify.c:331
#, c-format
msgid "Could not update extra metadata for %s"
msgstr "Nie można zaktualizować dodatkowych metadanych dla %s"

#: app/flatpak-builtins-repair.c:43
msgid "Don't make any changes"
msgstr "Bez wprowadzania zmian"

#: app/flatpak-builtins-repair.c:44
msgid "Reinstall all refs"
msgstr "Ponownie instaluje wszystkie odniesienia"

#: app/flatpak-builtins-repair.c:68
#, c-format
msgid "Object missing: %s.%s\n"
msgstr "Brak obiektu: %s.%s\n"

#: app/flatpak-builtins-repair.c:76
#, c-format
msgid "Object invalid: %s.%s\n"
msgstr "Nieprawidłowy obiekt: %s.%s\n"

#: app/flatpak-builtins-repair.c:81
#, c-format
msgid "%s, deleting object\n"
msgstr "%s, usuwanie obiektu\n"

#: app/flatpak-builtins-repair.c:146
#, c-format
msgid "Can't load object %s: %s\n"
msgstr "Nie można wczytać obiektu %s: %s\n"

#: app/flatpak-builtins-repair.c:228
#, c-format
msgid "Commit invalid %s: %s\n"
msgstr "Nieprawidłowe zatwierdzenie %s: %s\n"

#: app/flatpak-builtins-repair.c:231
#, c-format
msgid "Deleting invalid commit %s: %s\n"
msgstr "Usuwanie nieprawidłowego zatwierdzenia %s: %s\n"

#: app/flatpak-builtins-repair.c:261
#, c-format
msgid "Commit should be marked partial: %s\n"
msgstr "Zatwierdzenie powinno być oznaczone jako częściowe: %s\n"

#: app/flatpak-builtins-repair.c:264
#, c-format
msgid "Marking commit as partial: %s\n"
msgstr "Oznaczanie zatwierdzenia jako częściowego: %s\n"

#: app/flatpak-builtins-repair.c:293
#, c-format
msgid "Problems loading data for %s: %s\n"
msgstr "Problemy podczas wczytywania danych dla %s: %s\n"

#: app/flatpak-builtins-repair.c:306
#, c-format
msgid "Error reinstalling %s: %s\n"
msgstr "Błąd podczas ponownej instalacji %s: %s\n"

#: app/flatpak-builtins-repair.c:327
msgid "- Repair a flatpak installation"
msgstr "— naprawia instalację Flatpak"

#: app/flatpak-builtins-repair.c:406
#, c-format
msgid "Removing non-deployed ref %s…\n"
msgstr "Usuwanie niewdrożonego odniesienia %s…\n"

#: app/flatpak-builtins-repair.c:411
#, c-format
msgid "Skipping non-deployed ref %s…\n"
msgstr "Pomijanie niewdrożonego odniesienia %s…\n"

#: app/flatpak-builtins-repair.c:429
#, c-format
msgid "[%d/%d] Verifying %s…\n"
msgstr "[%d/%d] Sprawdzanie poprawności %s…\n"

#: app/flatpak-builtins-repair.c:435
#, c-format
msgid "Dry run: "
msgstr "Próbne wykonanie: "

#: app/flatpak-builtins-repair.c:440
#, c-format
msgid "Deleting ref %s due to missing objects\n"
msgstr "Usuwanie odniesienia %s z powodu brakujących obiektów\n"

#: app/flatpak-builtins-repair.c:444
#, c-format
msgid "Deleting ref %s due to invalid objects\n"
msgstr "Usuwanie odniesienia %s z powodu nieprawidłowych obiektów\n"

#: app/flatpak-builtins-repair.c:448
#, c-format
msgid "Deleting ref %s due to %d\n"
msgstr "Usuwanie odniesienia %s z powodu %d\n"

#: app/flatpak-builtins-repair.c:464
#, c-format
msgid "Checking remotes...\n"
msgstr "Sprawdzanie repozytoriów…\n"

#: app/flatpak-builtins-repair.c:482
#, c-format
msgid "Remote %s for ref %s is missing\n"
msgstr "Brak repozytorium %s dla odniesienia %s\n"

#: app/flatpak-builtins-repair.c:484
#, c-format
msgid "Remote %s for ref %s is disabled\n"
msgstr "Repozytorium %s dla odniesienia %s jest wyłączone\n"

#: app/flatpak-builtins-repair.c:490
#, c-format
msgid "Pruning objects\n"
msgstr "Usuwanie nieużywanych obiektów\n"

#: app/flatpak-builtins-repair.c:498
#, c-format
msgid "Erasing .removed\n"
msgstr "Usuwanie „.removed”\n"

#: app/flatpak-builtins-repair.c:524
#, c-format
msgid "Reinstalling refs\n"
msgstr "Ponowne instalowanie odniesień\n"

#: app/flatpak-builtins-repair.c:526
#, c-format
msgid "Reinstalling removed refs\n"
msgstr "Ponowne instalowanie usuniętych odniesień\n"

#: app/flatpak-builtins-repair.c:551
#, c-format
msgid "While removing appstream for %s: "
msgstr "Podczas usuwania AppStream dla %s: "

#: app/flatpak-builtins-repair.c:558
#, c-format
msgid "While deploying appstream for %s: "
msgstr "Podczas wdrażania AppStream dla %s: "

#: app/flatpak-builtins-repo.c:106
#, c-format
msgid "Repo mode: %s\n"
msgstr "Tryb repozytorium: %s\n"

#: app/flatpak-builtins-repo.c:113
#, c-format
msgid "Indexed summaries: %s\n"
msgstr "Zindeksowane podsumowania: %s\n"

#: app/flatpak-builtins-repo.c:113 app/flatpak-builtins-repo.c:139
#: app/flatpak-builtins-repo.c:172
msgid "true"
msgstr "prawda"

#: app/flatpak-builtins-repo.c:113 app/flatpak-builtins-repo.c:139
#: app/flatpak-builtins-repo.c:172
msgid "false"
msgstr "fałsz"

#: app/flatpak-builtins-repo.c:121
#, c-format
msgid "Subsummaries: "
msgstr "Podsumowania podrzędne: "

#: app/flatpak-builtins-repo.c:136
#, c-format
msgid "Cache version: %d\n"
msgstr "Wersja pamięci podręcznej: %d\n"

#: app/flatpak-builtins-repo.c:139
#, c-format
msgid "Indexed deltas: %s\n"
msgstr "Zindeksowane delty: %s\n"

#: app/flatpak-builtins-repo.c:142
#, c-format
msgid "Title: %s\n"
msgstr "Tytuł: %s\n"

#: app/flatpak-builtins-repo.c:145
#, c-format
msgid "Comment: %s\n"
msgstr "Komentarz: %s\n"

#: app/flatpak-builtins-repo.c:148
#, c-format
msgid "Description: %s\n"
msgstr "Opis: %s\n"

#: app/flatpak-builtins-repo.c:151
#, c-format
msgid "Homepage: %s\n"
msgstr "Strona domowa: %s\n"

#: app/flatpak-builtins-repo.c:154
#, c-format
msgid "Icon: %s\n"
msgstr "Ikona: %s\n"

#: app/flatpak-builtins-repo.c:157
#, c-format
msgid "Collection ID: %s\n"
msgstr "Identyfikator kolekcji: %s\n"

#: app/flatpak-builtins-repo.c:160
#, c-format
msgid "Default branch: %s\n"
msgstr "Domyślna gałąź: %s\n"

#: app/flatpak-builtins-repo.c:163
#, c-format
msgid "Redirect URL: %s\n"
msgstr "Adres URL przekierowania: %s\n"

#: app/flatpak-builtins-repo.c:166
#, c-format
msgid "Deploy collection ID: %s\n"
msgstr "Identyfikator wdrożenia kolekcji: %s\n"

#: app/flatpak-builtins-repo.c:169
#, c-format
msgid "Authenticator name: %s\n"
msgstr "Nazwa programu uwierzytelniającego: %s\n"

#: app/flatpak-builtins-repo.c:172
#, c-format
msgid "Authenticator install: %s\n"
msgstr "Instalacja programu uwierzytelniającego: %s\n"

#: app/flatpak-builtins-repo.c:180
#, c-format
msgid "GPG key hash: %s\n"
msgstr "Suma klucza GPG: %s\n"

#: app/flatpak-builtins-repo.c:184
#, c-format
msgid "%zd summary branches\n"
msgstr "Gałęzie podsumowań: %zd\n"

#: app/flatpak-builtins-repo.c:336
msgid "Installed"
msgstr "Zainstalowano"

#. Translators: Download is used here as a noun
#: app/flatpak-builtins-repo.c:338 app/flatpak-cli-transaction.c:1462
msgid "Download"
msgstr "Pobieranie"

#: app/flatpak-builtins-repo.c:339
msgid "Subsets"
msgstr "Podzbiory"

#: app/flatpak-builtins-repo.c:393
msgid "Digest"
msgstr "Skrót"

#: app/flatpak-builtins-repo.c:394
msgid "History length"
msgstr "Długość historii"

#: app/flatpak-builtins-repo.c:711
msgid "Print general information about the repository"
msgstr "Wyświetla ogólne informacje o repozytorium"

#: app/flatpak-builtins-repo.c:712
msgid "List the branches in the repository"
msgstr "Wyświetla listę gałęzi w repozytorium"

#: app/flatpak-builtins-repo.c:713
msgid "Print metadata for a branch"
msgstr "Wyświetla metadane gałęzi"

#: app/flatpak-builtins-repo.c:714
msgid "Show commits for a branch"
msgstr "Wyświetla zatwierdzenia dla gałęzi"

#: app/flatpak-builtins-repo.c:715
msgid "Print information about the repo subsets"
msgstr "Wyświetla informacje o podzbiorach repozytorium"

#: app/flatpak-builtins-repo.c:716
msgid "Limit information to subsets with this prefix"
msgstr "Ogranicza informacje do podzbiorów o tym przedrostku"

#: app/flatpak-builtins-repo.c:732
msgid "LOCATION - Repository maintenance"
msgstr "POŁOŻENIE — zarządzanie repozytorium"

#: app/flatpak-builtins-run.c:159
msgid "Command to run"
msgstr "Wykonywane polecenie"

#: app/flatpak-builtins-run.c:160
msgid "Directory to run the command in"
msgstr "Katalog, w którym wykonać polecenie"

#: app/flatpak-builtins-run.c:161
msgid "Branch to use"
msgstr "Używana gałąź"

#: app/flatpak-builtins-run.c:162
msgid "Use development runtime"
msgstr "Używa programistycznego środowiska wykonawczego"

#: app/flatpak-builtins-run.c:163
msgid "Runtime to use"
msgstr "Używane środowisko wykonawcze"

#: app/flatpak-builtins-run.c:164
msgid "Runtime version to use"
msgstr "Używana wersja środowiska wykonawczego"

#: app/flatpak-builtins-run.c:167
msgid "Log accessibility bus calls"
msgstr "Zapisywanie wywołań magistrali ułatwień dostępu w dzienniku"

#: app/flatpak-builtins-run.c:168
msgid "Don't proxy accessibility bus calls"
msgstr "Bez pośredniczenia wywołań magistrali ułatwień dostępu"

#: app/flatpak-builtins-run.c:169
msgid "Proxy accessibility bus calls (default except when sandboxed)"
msgstr ""
"Pośredniczy wywołania magistrali ułatwień dostępu (domyślne, chyba że "
"w piaskownicy)"

#: app/flatpak-builtins-run.c:170
msgid "Don't proxy session bus calls"
msgstr "Bez pośredniczenia wywołań magistrali sesji"

#: app/flatpak-builtins-run.c:171
msgid "Proxy session bus calls (default except when sandboxed)"
msgstr ""
"Pośredniczy wywołania magistrali sesji (domyślne, chyba że w piaskownicy)"

#: app/flatpak-builtins-run.c:172
msgid "Don't start portals"
msgstr "Bez uruchamiania portali"

#: app/flatpak-builtins-run.c:173
msgid "Enable file forwarding"
msgstr "Włącza przekazywanie plików"

#: app/flatpak-builtins-run.c:174
msgid "Run specified commit"
msgstr "Wykonuje podane zatwierdzenie"

#: app/flatpak-builtins-run.c:175
msgid "Use specified runtime commit"
msgstr "Używa podanego zatwierdzenia środowiska wykonawczego"

#: app/flatpak-builtins-run.c:176
msgid "Run completely sandboxed"
msgstr "Wykonuje całkowicie w piaskownicy"

#: app/flatpak-builtins-run.c:178
msgid "Use PID as parent pid for sharing namespaces"
msgstr "Używa PID jako nadrzędny PID do współdzielenia przestrzeni nazw"

#: app/flatpak-builtins-run.c:179
msgid "Make processes visible in parent namespace"
msgstr "Sprawia, że procesy są widoczne w nadrzędnej przestrzeni nazw"

#: app/flatpak-builtins-run.c:180
msgid "Share process ID namespace with parent"
msgstr "Współdzieli przestrzeń nazw identyfikatora procesu z nadrzędnym"

#: app/flatpak-builtins-run.c:181
msgid "Write the instance ID to the given file descriptor"
msgstr "Zapisuje identyfikator wystąpienia do podanego deskryptora pliku"

#: app/flatpak-builtins-run.c:182
msgid "Use PATH instead of the app's /app"
msgstr "Używa ŚCIEŻKI zamiast /app programu"

#: app/flatpak-builtins-run.c:183
#, fuzzy
msgid "Use FD instead of the app's /app"
msgstr "Używa ŚCIEŻKI zamiast /app programu"

#: app/flatpak-builtins-run.c:183 app/flatpak-builtins-run.c:185
#: app/flatpak-builtins-run.c:187 app/flatpak-builtins-run.c:188
#: common/flatpak-context.c:2672
msgid "FD"
msgstr "FD"

#: app/flatpak-builtins-run.c:184
msgid "Use PATH instead of the runtime's /usr"
msgstr "Używa ŚCIEŻKI zamiast /usr środowiska wykonawczego"

#: app/flatpak-builtins-run.c:185
#, fuzzy
msgid "Use FD instead of the runtime's /usr"
msgstr "Używa ŚCIEŻKI zamiast /usr środowiska wykonawczego"

#: app/flatpak-builtins-run.c:186
#, fuzzy
msgid "Clear all outside environment variables"
msgstr "Ustawia zmienną środowiskową"

#: app/flatpak-builtins-run.c:187
msgid ""
"Bind mount the file or directory referred to by FD to its canonicalized path"
msgstr ""

#: app/flatpak-builtins-run.c:188
msgid ""
"Bind mount the file or directory referred to by FD read-only to its "
"canonicalized path"
msgstr ""

#: app/flatpak-builtins-run.c:219
msgid "APP [ARGUMENT…] - Run an app"
msgstr "PROGRAM [PARAMETR…] — uruchamia program"

#: app/flatpak-builtins-run.c:370
#, c-format
msgid "runtime/%s/%s/%s not installed"
msgstr "Nie zainstalowano środowiska wykonawczego/%s/%s/%s"

#: app/flatpak-builtins-run.c:419
msgid "app-fd and app-path cannot both be used"
msgstr ""

#: app/flatpak-builtins-run.c:449
msgid "usr-fd and usr-path cannot both be used"
msgstr ""

#: app/flatpak-builtins-search.c:37
msgid "Arch to search for"
msgstr "Wyszukiwana architektura"

#: app/flatpak-builtins-search.c:49
msgid "Remotes"
msgstr "Repozytoria"

#: app/flatpak-builtins-search.c:49
msgid "Show the remotes"
msgstr "Wyświetla repozytoria"

#: app/flatpak-builtins-search.c:244
msgid "TEXT - Search remote apps/runtimes for text"
msgstr ""
"TEKST — wyszukuje programy/środowiska wykonawcze repozytorium według tekstu"

#: app/flatpak-builtins-search.c:255
msgid "TEXT must be specified"
msgstr "Należy podać TEKST"

#: app/flatpak-builtins-search.c:338
msgid "No matches found"
msgstr "Brak wyników"

#: app/flatpak-builtins-uninstall.c:54
msgid "Arch to uninstall"
msgstr "Odinstalowywana architektura"

#: app/flatpak-builtins-uninstall.c:55
msgid "Keep ref in local repository"
msgstr "Zachowywanie odniesienia w lokalnym repozytorium"

#: app/flatpak-builtins-uninstall.c:56
msgid "Don't uninstall related refs"
msgstr "Bez odinstalowywania powiązanych odniesień"

#: app/flatpak-builtins-uninstall.c:57
msgid "Remove files even if running"
msgstr "Usuwa nawet uruchomione pliki"

#: app/flatpak-builtins-uninstall.c:60
msgid "Uninstall all"
msgstr "Odinstalowuje wszystko"

#: app/flatpak-builtins-uninstall.c:61
msgid "Uninstall unused"
msgstr "Odinstalowuje nieużywane"

#: app/flatpak-builtins-uninstall.c:62
msgid "Delete app data"
msgstr "Usuwa dane programu"

#: app/flatpak-builtins-uninstall.c:141
#, c-format
msgid "Delete data for %s?"
msgstr "Usunąć dane programu %s?"

#: app/flatpak-builtins-uninstall.c:220
#, c-format
msgid "Info: applications using the extension %s%s%s branch %s%s%s:\n"
msgstr "Informacja: programy używające rozszerzenia %s%s%s, gałęzi %s%s%s:\n"

#: app/flatpak-builtins-uninstall.c:223
#, c-format
msgid "Info: applications using the runtime %s%s%s branch %s%s%s:\n"
msgstr ""
"Informacja: programy używające środowiska wykonawczego %s%s%s, gałęzi "
"%s%s%s:\n"

#: app/flatpak-builtins-uninstall.c:238
msgid "Really remove?"
msgstr "Na pewno usunąć?"

#: app/flatpak-builtins-uninstall.c:255
msgid "[REF…] - Uninstall applications or runtimes"
msgstr "[ODNIESIENIE…] — odinstalowuje programy lub środowiska wykonawcze"

#: app/flatpak-builtins-uninstall.c:264
msgid "Must specify at least one REF, --unused, --all or --delete-data"
msgstr ""
"Należy podać co najmniej jedno ODNIESIENIE, --unused, --all lub --delete-data"

#: app/flatpak-builtins-uninstall.c:267
msgid "Must not specify REFs when using --all"
msgstr "Nie można podać ODNIESIEŃ podczas używania parametru --all"

#: app/flatpak-builtins-uninstall.c:270
msgid "Must not specify REFs when using --unused"
msgstr "Nie można podać ODNIESIEŃ podczas używania parametru --unused"

#: app/flatpak-builtins-uninstall.c:336
#, c-format
msgid ""
"\n"
"These runtimes in installation '%s' are pinned and won't be removed; see "
"flatpak-pin(1):\n"
msgstr ""
"\n"
"Te środowiska wykonawcze w instalacji „%s” są przypięte i nie zostaną "
"usunięte; flatpak-pin(1) zawiera więcej informacji:\n"

#: app/flatpak-builtins-uninstall.c:370
#, c-format
msgid "Nothing unused to uninstall\n"
msgstr "Nie ma nic nieużywanego do odinstalowania\n"

#: app/flatpak-builtins-uninstall.c:444
#, c-format
msgid "No installed refs found for ‘%s’"
msgstr "Nie odnaleziono zainstalowanych odniesień dla „%s”"

#: app/flatpak-builtins-uninstall.c:447
#, c-format
msgid " with arch ‘%s’"
msgstr " o architekturze „%s”"

#: app/flatpak-builtins-uninstall.c:449
#, c-format
msgid " with branch ‘%s’"
msgstr " o gałęzi „%s”"

#: app/flatpak-builtins-uninstall.c:456
#, c-format
msgid "Warning: %s is not installed\n"
msgstr "Ostrzeżenie: %s nie jest zainstalowane\n"

#: app/flatpak-builtins-uninstall.c:490
#, c-format
msgid "None of the specified refs are installed"
msgstr "Żadne z podanych odniesień nie są zainstalowane"

#: app/flatpak-builtins-uninstall.c:599
#, c-format
msgid "No app data to delete\n"
msgstr "Brak danych programu do usunięcia\n"

#: app/flatpak-builtins-update.c:56
msgid "Arch to update for"
msgstr "Aktualizowana architektura"

#: app/flatpak-builtins-update.c:57
msgid "Commit to deploy"
msgstr "Wdrażane zatwierdzenie"

#: app/flatpak-builtins-update.c:58
msgid "Remove old files even if running"
msgstr "Usuwa stare pliki nawet, jeśli są uruchomione"

#: app/flatpak-builtins-update.c:59
msgid "Don't pull, only update from local cache"
msgstr "Bez pobierania, tylko aktualizuje z lokalnej pamięci podręcznej"

#: app/flatpak-builtins-update.c:61
msgid "Don't update related refs"
msgstr "Bez aktualizowania powiązanych odniesień"

#: app/flatpak-builtins-update.c:66
msgid "Update appstream for remote"
msgstr "Aktualizuje AppStream dla repozytorium"

#: app/flatpak-builtins-update.c:67
msgid "Only update this subpath"
msgstr "Aktualizuje tylko tę podścieżkę"

#: app/flatpak-builtins-update.c:90
msgid "[REF…] - Update applications or runtimes"
msgstr "[ODNIESIENIE…] — aktualizuje programy lub środowiska wykonawcze"

#: app/flatpak-builtins-update.c:121
msgid "With --commit, only one REF may be specified"
msgstr "Używając opcji --commit można podać tylko jedno ODNIESIENIE"

#: app/flatpak-builtins-update.c:162
#, c-format
msgid "Looking for updates…\n"
msgstr "Wyszukiwanie aktualizacji…\n"

#: app/flatpak-builtins-update.c:215
#, c-format
msgid "Unable to update %s: %s\n"
msgstr "Nie można zaktualizować %s: %s\n"

#: app/flatpak-builtins-update.c:274
#, fuzzy, c-format
msgid "Nothing to update.\n"
msgstr "Nie ma nic do zrobienia.\n"

#: app/flatpak-builtins-utils.c:337
#, fuzzy, c-format
msgid ""
"Remote ‘%s’ found in multiple installations, unable to proceed in non-"
"interactive mode"
msgstr ""
"Odnaleziono odniesienie „%s” w wielu instalacjach: %s. Należy podać jedno."

#: app/flatpak-builtins-utils.c:346
#, c-format
msgid "Remote ‘%s’ found in multiple installations:"
msgstr "Odnaleziono repozytorium „%s” w wielu instalacjach:"

#: app/flatpak-builtins-utils.c:347 app/flatpak-builtins-utils.c:442
#: app/flatpak-builtins-utils.c:538 app/flatpak-builtins-utils.c:540
#: app/flatpak-builtins-utils.c:598
msgid "Which do you want to use (0 to abort)?"
msgstr "Którego użyć (0 przerwie)?"

#: app/flatpak-builtins-utils.c:349
#, c-format
msgid "No remote chosen to resolve ‘%s’ which exists in multiple installations"
msgstr ""
"Nie wybrano repozytorium do rozwiązania „%s”, które istnieje w wielu "
"instalacjach"

#: app/flatpak-builtins-utils.c:358
#, c-format
msgid ""
"Remote \"%s\" not found\n"
"Hint: Use flatpak remote-add to add a remote"
msgstr ""
"Nie odnaleziono repozytorium „%s”\n"
"Wskazówka: można użyć polecenia „flatpak remote-add”, aby dodać repozytorium"

#: app/flatpak-builtins-utils.c:364
#, c-format
msgid "Remote \"%s\" not found in the %s installation"
msgstr "Nie odnaleziono repozytorium „%s” w instalacji %s"

#: app/flatpak-builtins-utils.c:404
#, c-format
msgid "Multiple refs match ‘%s’, unable to proceed in non-interactive mode"
msgstr ""

#. default to yes on Enter
#: app/flatpak-builtins-utils.c:430
#, c-format
msgid ""
"Found ref ‘%s’ in remote ‘%s’ (%s).\n"
"Use this ref?"
msgstr ""
"Odnaleziono odniesienie „%s” w repozytorium „%s” (%s).\n"
"Użyć tego odniesienia?"

#: app/flatpak-builtins-utils.c:434 app/flatpak-builtins-utils.c:444
#: app/flatpak-builtins-utils.c:522 app/flatpak-builtins-utils.c:543
#, c-format
msgid "No ref chosen to resolve matches for ‘%s’"
msgstr "Nie wybrano odniesienia do rozwiązania wyników dla „%s”"

#: app/flatpak-builtins-utils.c:440
#, c-format
msgid "Similar refs found for ‘%s’ in remote ‘%s’ (%s):"
msgstr "Odnaleziono podobne odniesienia do „%s” w repozytorium „%s” (%s):"

#: app/flatpak-builtins-utils.c:488
#, c-format
msgid ""
"Multiple installed refs match ‘%s’, unable to proceed in non-interactive mode"
msgstr ""

#. default to yes on Enter
#: app/flatpak-builtins-utils.c:518
#, c-format
msgid "Found installed ref ‘%s’ (%s). Is this correct?"
msgstr "Odnaleziono zainstalowane odniesienie „%s” (%s). Czy to w porządku?"

#: app/flatpak-builtins-utils.c:534
#, c-format
msgid "All of the above"
msgstr "Wszystko powyższe"

#: app/flatpak-builtins-utils.c:535
#, c-format
msgid "Similar installed refs found for ‘%s’:"
msgstr "Odnaleziono podobne zainstalowane odniesienie do „%s”:"

#: app/flatpak-builtins-utils.c:579
#, c-format
msgid ""
"Multiple remotes have refs matching ‘%s’, unable to proceed in non-"
"interactive mode"
msgstr ""

#: app/flatpak-builtins-utils.c:597
#, c-format
msgid "Remotes found with refs similar to ‘%s’:"
msgstr "Odnaleziono repozytoria z odniesieniami podobnymi do „%s”:"

#: app/flatpak-builtins-utils.c:600
#, c-format
msgid "No remote chosen to resolve matches for ‘%s’"
msgstr "Nie wybrano repozytorium do rozwiązania wyników dla „%s”"

#: app/flatpak-builtins-utils.c:696 app/flatpak-builtins-utils.c:699
#, c-format
msgid "Updating appstream data for user remote %s"
msgstr "Aktualizowanie danych AppStream dla repozytorium użytkownika %s"

#: app/flatpak-builtins-utils.c:706 app/flatpak-builtins-utils.c:709
#, c-format
msgid "Updating appstream data for remote %s"
msgstr "Aktualizowanie danych AppStream dla repozytorium %s"

#: app/flatpak-builtins-utils.c:717 app/flatpak-builtins-utils.c:719
msgid "Error updating"
msgstr "Błąd podczas aktualizowania"

#: app/flatpak-builtins-utils.c:755
#, c-format
msgid "Remote \"%s\" not found"
msgstr "Nie odnaleziono repozytorium „%s”"

#: app/flatpak-builtins-utils.c:796
#, c-format
msgid "Ambiguous suffix: '%s'."
msgstr "Niejednoznaczny przyrostek: „%s”."

#. Translators: don't translate the values
#: app/flatpak-builtins-utils.c:798 app/flatpak-builtins-utils.c:813
msgid "Possible values are :s[tart], :m[iddle], :e[nd] or :f[ull]"
msgstr ""
"Możliwe wartości to :s[tart] (początek), :m[iddle] (środek), :e[nd] (koniec) "
"lub :f[ull] (pełne)"

#: app/flatpak-builtins-utils.c:811
#, c-format
msgid "Invalid suffix: '%s'."
msgstr "Nieprawidłowy przyrostek: „%s”."

#: app/flatpak-builtins-utils.c:846
#, c-format
msgid "Ambiguous column: %s"
msgstr "Niejednoznaczna kolumna: %s"

#: app/flatpak-builtins-utils.c:859
#, c-format
msgid "Unknown column: %s"
msgstr "Nieznana kolumna: %s"

#: app/flatpak-builtins-utils.c:917
msgid "Available columns:\n"
msgstr "Dostępne kolumny:\n"

#: app/flatpak-builtins-utils.c:927
msgid "Show all columns"
msgstr "Wyświetla wszystkie kolumny"

#: app/flatpak-builtins-utils.c:928
msgid "Show available columns"
msgstr "Wyświetla dostępne kolumny"

#: app/flatpak-builtins-utils.c:931
msgid "Append :s[tart], :m[iddle], :e[nd] or :f[ull] to change ellipsization"
msgstr ""
"Dołączenie :s[tart], :m[iddle], :e[nd] lub :f[ull] zmieni sposób skracania"

#: app/flatpak-builtins-utils.c:1483
#, c-format
msgid "Unknown scheme in sideload location %s"
msgstr ""

#: app/flatpak-cli-transaction.c:96 app/flatpak-cli-transaction.c:102
#, c-format
msgid "Required runtime for %s (%s) found in remote %s\n"
msgstr ""
"Wymagane środowisko wykonawcze dla %s (%s) zostało odnalezione "
"w repozytorium %s\n"

#: app/flatpak-cli-transaction.c:104
msgid "Do you want to install it?"
msgstr "Zainstalować je?"

#: app/flatpak-cli-transaction.c:110
#, c-format
msgid "Required runtime for %s (%s) found in remotes:"
msgstr ""
"Odnaleziono wymagane środowisko wykonawcze dla %s (%s) w repozytoriach:"

#: app/flatpak-cli-transaction.c:112
msgid "Which do you want to install (0 to abort)?"
msgstr "Które zainstalować (0 przerwie)?"

#: app/flatpak-cli-transaction.c:132
#, c-format
msgid "Configuring %s as new remote '%s'\n"
msgstr "Konfigurowanie %s jako nowe repozytorium „%s”\n"

#. default to yes on Enter
#: app/flatpak-cli-transaction.c:139
#, c-format
msgid ""
"The remote '%s', referred to by '%s' at location %s contains additional "
"applications.\n"
"Should the remote be kept for future installations?"
msgstr ""
"Repozytorium „%s”, do którego odnosi się „%s” w położeniu %s zawiera "
"dodatkowe programy.\n"
"Zachować repozytorium, aby móc instalować z niego w przyszłości?"

#. default to yes on Enter
#: app/flatpak-cli-transaction.c:147
#, c-format
msgid ""
"The application %s depends on runtimes from:\n"
"  %s\n"
"Configure this as new remote '%s'"
msgstr ""
"Program „%s” zależy od środowisk wykonawczych z:\n"
"  %s\n"
"Należy skonfigurować jako nowe repozytorium „%s”"

#. Formatted size/remaining time in seconds
#: app/flatpak-cli-transaction.c:321
#, c-format
msgid "%s/s%s%s"
msgstr ""

#. Download progress percentage, use the appropriate
#. percent format for your language
#: app/flatpak-cli-transaction.c:359
#, c-format
msgid "%3d%%"
msgstr ""

#: app/flatpak-cli-transaction.c:414
msgid "Installing…"
msgstr "Instalowanie…"

#: app/flatpak-cli-transaction.c:416
#, c-format
msgid "Installing %d/%d…"
msgstr "Instalowanie %d/%d…"

#: app/flatpak-cli-transaction.c:421
msgid "Updating…"
msgstr "Aktualizowanie…"

#: app/flatpak-cli-transaction.c:423
#, c-format
msgid "Updating %d/%d…"
msgstr "Aktualizowanie %d/%d…"

#: app/flatpak-cli-transaction.c:428
msgid "Uninstalling…"
msgstr "Odinstalowywanie…"

#: app/flatpak-cli-transaction.c:430
#, c-format
msgid "Uninstalling %d/%d…"
msgstr "Odinstalowywanie %d/%d…"

#: app/flatpak-cli-transaction.c:496 app/flatpak-quiet-transaction.c:161
#, c-format
msgid "Info: %s was skipped"
msgstr "Informacja: %s zostało pominięte"

#: app/flatpak-cli-transaction.c:519
#, c-format
msgid "Warning: %s%s%s already installed"
msgstr "Ostrzeżenie: już zainstalowano %s%s%s"

#: app/flatpak-cli-transaction.c:522
#, c-format
msgid "Error: %s%s%s already installed"
msgstr "Błąd: już zainstalowano %s%s%s"

#: app/flatpak-cli-transaction.c:528
#, c-format
msgid "Warning: %s%s%s not installed"
msgstr "Ostrzeżenie: nie zainstalowano %s%s%s"

#: app/flatpak-cli-transaction.c:531
#, c-format
msgid "Error: %s%s%s not installed"
msgstr "Błąd: nie zainstalowano %s%s%s"

#: app/flatpak-cli-transaction.c:537
#, c-format
msgid "Warning: %s%s%s needs a later flatpak version"
msgstr "Ostrzeżenie: %s%s%s wymaga nowszej wersji Flatpak"

#: app/flatpak-cli-transaction.c:540
#, c-format
msgid "Error: %s%s%s needs a later flatpak version"
msgstr "Błąd: %s%s%s wymaga nowszej wersji Flatpak"

#: app/flatpak-cli-transaction.c:546
msgid "Warning: Not enough disk space to complete this operation"
msgstr "Ostrzeżenie: za mało miejsca na dysku, aby ukończyć to działanie"

#: app/flatpak-cli-transaction.c:548
msgid "Error: Not enough disk space to complete this operation"
msgstr "Błąd: za mało miejsca na dysku, aby ukończyć to działanie"

#: app/flatpak-cli-transaction.c:553
#, c-format
msgid "Warning: %s"
msgstr "Ostrzeżenie: %s"

#: app/flatpak-cli-transaction.c:555
#, c-format
msgid "Error: %s"
msgstr "Błąd: %s"

#: app/flatpak-cli-transaction.c:570
#, c-format
msgid "Failed to install %s%s%s: "
msgstr "Zainstalowanie %s%s%s się nie powiodło: "

#: app/flatpak-cli-transaction.c:577
#, c-format
msgid "Failed to update %s%s%s: "
msgstr "Zaktualizowanie %s%s%s się nie powiodło: "

#: app/flatpak-cli-transaction.c:584
#, c-format
msgid "Failed to install bundle %s%s%s: "
msgstr "Zainstalowanie pakietu %s%s%s się nie powiodło: "

#: app/flatpak-cli-transaction.c:591
#, c-format
msgid "Failed to uninstall %s%s%s: "
msgstr "Odinstalowanie %s%s%s się nie powiodło: "

#: app/flatpak-cli-transaction.c:642
#, c-format
msgid "Authentication required for remote '%s'\n"
msgstr "Wymagane jest uwierzytelnienie dla repozytorium „%s”\n"

#: app/flatpak-cli-transaction.c:643
msgid "Open browser?"
msgstr "Otworzyć przeglądarkę?"

#: app/flatpak-cli-transaction.c:699
#, c-format
msgid "Login required remote %s (realm %s)\n"
msgstr "Wymagane jest logowanie do repozytorium %s (obszar %s)\n"

#: app/flatpak-cli-transaction.c:704
msgid "Password"
msgstr "Hasło"

#. Only runtimes can be pinned
#: app/flatpak-cli-transaction.c:759
#, c-format
msgid ""
"\n"
"Info: (pinned) runtime %s%s%s branch %s%s%s is end-of-life, in favor of "
"%s%s%s branch %s%s%s\n"
msgstr ""
"\n"
"Informacja: (przypięte) środowisko wykonawcze %s%s%s, gałąź %s%s%s jest "
"niewspierane, w zamian jest %s%s%s, gałąź %s%s%s\n"

#: app/flatpak-cli-transaction.c:765
#, c-format
msgid ""
"\n"
"Info: runtime %s%s%s branch %s%s%s is end-of-life, in favor of %s%s%s branch "
"%s%s%s\n"
msgstr ""
"\n"
"Informacja: środowisko wykonawcze %s%s%s, gałąź %s%s%s jest niewspierane, "
"w zamian jest %s%s%s, gałąź %s%s%s\n"

#: app/flatpak-cli-transaction.c:768
#, c-format
msgid ""
"\n"
"Info: app %s%s%s branch %s%s%s is end-of-life, in favor of %s%s%s branch "
"%s%s%s\n"
msgstr ""
"\n"
"Informacja: program %s%s%s, gałąź %s%s%s jest niewspierany, w zamian jest "
"%s%s%s, gałąź %s%s%s\n"

#. Only runtimes can be pinned
#: app/flatpak-cli-transaction.c:780
#, c-format
msgid ""
"\n"
"Info: (pinned) runtime %s%s%s branch %s%s%s is end-of-life, with reason:\n"
msgstr ""
"\n"
"Informacja: (przypięte) środowisko wykonawcze %s%s%s, gałąź %s%s%s jest "
"niewspierane z powodu:\n"

#: app/flatpak-cli-transaction.c:786
#, c-format
msgid ""
"\n"
"Info: runtime %s%s%s branch %s%s%s is end-of-life, with reason:\n"
msgstr ""
"\n"
"Informacja: środowisko wykonawcze %s%s%s, gałąź %s%s%s jest niewspierane "
"z powodu:\n"

#: app/flatpak-cli-transaction.c:789
#, c-format
msgid ""
"\n"
"Info: app %s%s%s branch %s%s%s is end-of-life, with reason:\n"
msgstr ""
"\n"
"Informacja: program %s%s%s, gałąź %s%s%s jest niewspierany z powodu:\n"

#: app/flatpak-cli-transaction.c:963
#, c-format
msgid "Info: applications using this extension:\n"
msgstr "Informacja: programy używające tego rozszerzenia:\n"

#: app/flatpak-cli-transaction.c:965
#, c-format
msgid "Info: applications using this runtime:\n"
msgstr "Informacja: programy używające tego środowiska wykonawczego:\n"

#: app/flatpak-cli-transaction.c:984
msgid "Replace?"
msgstr "Zastąpić?"

#: app/flatpak-cli-transaction.c:987 app/flatpak-quiet-transaction.c:247
#, c-format
msgid "Updating to rebased version\n"
msgstr "Aktualizowanie do zmienionej wersji\n"

#: app/flatpak-cli-transaction.c:1011
#, c-format
msgid "Failed to rebase %s to %s: "
msgstr "Zmiana %s na %s się nie powiodła: "

#: app/flatpak-cli-transaction.c:1277
#, c-format
msgid "New %s%s%s permissions:"
msgstr "Nowe uprawnienia %s%s%s:"

#: app/flatpak-cli-transaction.c:1279
#, c-format
msgid "%s%s%s permissions:"
msgstr "Uprawnienia %s%s%s:"

#: app/flatpak-cli-transaction.c:1343
msgid "Warning: "
msgstr "Ostrzeżenie: "

#. translators: This is short for operation, the title of a one-char column
#: app/flatpak-cli-transaction.c:1442
msgid "Op"
msgstr "Dz"

#. Avoid resizing the download column too much,
#. * by making the title as long as typical content
#.
#: app/flatpak-cli-transaction.c:1458 app/flatpak-cli-transaction.c:1503
msgid "partial"
msgstr "częściowo"

#: app/flatpak-cli-transaction.c:1535
msgid "Proceed with these changes to the user installation?"
msgstr "Kontynuować te zmiany w instalacji użytkownika?"

#: app/flatpak-cli-transaction.c:1537
msgid "Proceed with these changes to the system installation?"
msgstr "Kontynuować te zmiany w instalacji systemowej?"

#: app/flatpak-cli-transaction.c:1539
#, c-format
msgid "Proceed with these changes to the %s?"
msgstr "Kontynuować te zmiany w: %s?"

#: app/flatpak-cli-transaction.c:1711
msgid "Changes complete."
msgstr "Ukończono zmiany."

#: app/flatpak-cli-transaction.c:1713
msgid "Uninstall complete."
msgstr "Ukończono odinstalowywanie."

#: app/flatpak-cli-transaction.c:1715
msgid "Installation complete."
msgstr "Ukończono instalację."

#: app/flatpak-cli-transaction.c:1717
msgid "Updates complete."
msgstr "Ukończono aktualizacje."

#. For updates/!stop_on_first_error we already printed all errors so we make up
#. a different one.
#: app/flatpak-cli-transaction.c:1750
msgid "There were one or more errors"
msgstr "Wystąpił jeden lub więcej błędów"

#. translators: please keep the leading space
#: app/flatpak-main.c:76
msgid " Manage installed applications and runtimes"
msgstr " Zarządza zainstalowanymi programami i środowiskami wykonawczymi"

#: app/flatpak-main.c:77
msgid "Install an application or runtime"
msgstr "Instaluje program lub środowisko wykonawcze"

#: app/flatpak-main.c:78
msgid "Update an installed application or runtime"
msgstr "Aktualizuje zainstalowany program lub środowisko wykonawcze"

#: app/flatpak-main.c:81
msgid "Uninstall an installed application or runtime"
msgstr "Odinstalowuje zainstalowany program lub środowisko wykonawcze"

#: app/flatpak-main.c:84
msgid "Mask out updates and automatic installation"
msgstr "Maskuje aktualizacje i automatyczną instalację"

#: app/flatpak-main.c:85
msgid "Pin a runtime to prevent automatic removal"
msgstr ""
"Przypina środowisko wykonawcze, aby uniemożliwić automatyczne usunięcie"

#: app/flatpak-main.c:86
msgid "List installed apps and/or runtimes"
msgstr "Wyświetla listę zainstalowanych programów lub środowisk wykonawczych"

#: app/flatpak-main.c:87
msgid "Show info for installed app or runtime"
msgstr ""
"Wyświetla informacje o zainstalowanym programie lub środowisku wykonawczym"

#: app/flatpak-main.c:88
msgid "Show history"
msgstr "Wyświetla historię"

#: app/flatpak-main.c:89
msgid "Configure flatpak"
msgstr "Konfiguruje Flatpak"

#: app/flatpak-main.c:90
msgid "Repair flatpak installation"
msgstr "Naprawia instalację Flatpak"

#: app/flatpak-main.c:91
msgid "Put applications or runtimes onto removable media"
msgstr "Umieszcza programy lub środowiska wykonawcze na nośnikach wymiennych"

#: app/flatpak-main.c:92
msgid "Install flatpaks that are part of the operating system"
msgstr "Instaluje pakiety Flatpak będące częścią systemu operacyjnego"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:95
msgid ""
"\n"
" Find applications and runtimes"
msgstr ""
"\n"
" Wyszukuje programy i środowiska wykonawcze"

#: app/flatpak-main.c:96
msgid "Search for remote apps/runtimes"
msgstr "Wyszukuje programy/środowiska wykonawcze repozytorium"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:99
msgid ""
"\n"
" Manage running applications"
msgstr ""
"\n"
" Zarządza uruchamianiem programów"

#: app/flatpak-main.c:100
msgid "Run an application"
msgstr "Uruchamia program"

#: app/flatpak-main.c:101
msgid "Override permissions for an application"
msgstr "Zastępuje uprawnienia programu"

#: app/flatpak-main.c:102
msgid "Specify default version to run"
msgstr "Podaje domyślnie uruchamianą wersję"

#: app/flatpak-main.c:103
msgid "Enter the namespace of a running application"
msgstr "Przestrzeń nazw działającego programu"

#: app/flatpak-main.c:104
msgid "Enumerate running applications"
msgstr "Wylicza uruchomione programy"

#: app/flatpak-main.c:105
msgid "Stop a running application"
msgstr "Zatrzymuje uruchomiony program"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:108
msgid ""
"\n"
" Manage file access"
msgstr ""
"\n"
" Zarządza dostępem do plików"

#: app/flatpak-main.c:109
msgid "List exported files"
msgstr "Wyświetla listę wyeksportowanych plików"

#: app/flatpak-main.c:110
msgid "Grant an application access to a specific file"
msgstr "Nadaje programowi dostęp do podanego pliku"

#: app/flatpak-main.c:111
msgid "Revoke access to a specific file"
msgstr "Odbiera dostęp do podanego pliku"

#: app/flatpak-main.c:112
msgid "Show information about a specific file"
msgstr "Wyświetla informacje o podanym pliku"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:116
msgid ""
"\n"
" Manage dynamic permissions"
msgstr ""
"\n"
" Zarządza dynamicznymi uprawnieniami"

#: app/flatpak-main.c:117
msgid "List permissions"
msgstr "Wyświetla listę uprawnień"

#: app/flatpak-main.c:118
msgid "Remove item from permission store"
msgstr "Usuwa element z przechowalni uprawnień"

#: app/flatpak-main.c:120
msgid "Set permissions"
msgstr "Ustawia uprawnienia"

#: app/flatpak-main.c:121
msgid "Show app permissions"
msgstr "Wyświetla uprawnienia programu"

#: app/flatpak-main.c:122
msgid "Reset app permissions"
msgstr "Przywraca uprawnienia programu"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:125
msgid ""
"\n"
" Manage remote repositories"
msgstr ""
"\n"
" Zarządza zdalnymi repozytoriami"

#: app/flatpak-main.c:126
msgid "List all configured remotes"
msgstr "Wyświetla listę wszystkich skonfigurowanych repozytoriów"

#: app/flatpak-main.c:127
msgid "Add a new remote repository (by URL)"
msgstr "Dodaje nowe zdalne repozytorium (według adresu URL)"

#: app/flatpak-main.c:128
msgid "Modify properties of a configured remote"
msgstr "Modyfikuje właściwości skonfigurowanego repozytorium"

#: app/flatpak-main.c:129
msgid "Delete a configured remote"
msgstr "Usuwa skonfigurowane repozytorium"

#: app/flatpak-main.c:131
msgid "List contents of a configured remote"
msgstr "Wyświetla listę zawartości skonfigurowanego repozytorium"

#: app/flatpak-main.c:132
msgid "Show information about a remote app or runtime"
msgstr ""
"Wyświetla informacje o programie lub środowisku wykonawczym repozytorium"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:135
msgid ""
"\n"
" Build applications"
msgstr ""
"\n"
" Buduje programy"

#: app/flatpak-main.c:136
msgid "Initialize a directory for building"
msgstr "Inicjuje katalog do budowania"

#: app/flatpak-main.c:137
msgid "Run a build command inside the build dir"
msgstr "Wykonuje polecenie budowania w katalogu budowania"

#: app/flatpak-main.c:138
msgid "Finish a build dir for export"
msgstr "Kończy katalog budowania do eksportu"

#: app/flatpak-main.c:139
msgid "Export a build dir to a repository"
msgstr "Eksportuje katalog budowania do repozytorium"

#: app/flatpak-main.c:140
msgid "Create a bundle file from a ref in a local repository"
msgstr "Tworzy pakiet z odniesienia w lokalnym repozytorium"

#: app/flatpak-main.c:141
msgid "Import a bundle file"
msgstr "Importuje pakiet"

#: app/flatpak-main.c:142
msgid "Sign an application or runtime"
msgstr "Podpisuje program lub środowisko wykonawcze"

#: app/flatpak-main.c:143
msgid "Update the summary file in a repository"
msgstr "Aktualizuje plik podsumowania w repozytorium"

#: app/flatpak-main.c:144
msgid "Create new commit based on existing ref"
msgstr "Tworzy nowe zatwierdzenie na podstawie istniejącego odniesienia"

#: app/flatpak-main.c:145
msgid "Show information about a repo"
msgstr "Wyświetla informacje o repozytorium"

#: app/flatpak-main.c:162
msgid "Show debug information, -vv for more detail"
msgstr "Wyświetla informacje debugowania, -vv wyświetla więcej"

#: app/flatpak-main.c:163
msgid "Show OSTree debug information"
msgstr "Wyświetla informacje debugowania OSTree"

#: app/flatpak-main.c:169
msgid "Print version information and exit"
msgstr "Wyświetla informacje o wersji i kończy działanie"

#: app/flatpak-main.c:170
msgid "Print default arch and exit"
msgstr "Wyświetla domyślną architekturę i kończy działanie"

#: app/flatpak-main.c:171
msgid "Print supported arches and exit"
msgstr "Wyświetla obsługiwane architektury i kończy działanie"

#: app/flatpak-main.c:172
msgid "Print active gl drivers and exit"
msgstr "Wyświetla aktywne sterowniki GL i kończy działanie"

#: app/flatpak-main.c:173
msgid "Print paths for system installations and exit"
msgstr "Wyświetla ścieżki do instalacji systemowych i kończy działanie"

#: app/flatpak-main.c:174
msgid "Print the updated environment needed to run flatpaks"
msgstr ""
"Wyświetla zaktualizowane środowisko wymagane do uruchamiania pakietów Flatpak"

#: app/flatpak-main.c:175
msgid "Only include the system installation with --print-updated-env"
msgstr "Zawiera tylko instalacje systemowe w --print-updated-env"

#: app/flatpak-main.c:180
msgid "Work on the user installation"
msgstr "Działa na instalacji użytkownika"

#: app/flatpak-main.c:181
msgid "Work on the system-wide installation (default)"
msgstr "Działa na instalacji systemowej (domyślnie)"

#: app/flatpak-main.c:182
msgid "Work on a non-default system-wide installation"
msgstr "Działa na niedomyślnej instalacji systemowej"

#: app/flatpak-main.c:212
msgid "Builtin Commands:"
msgstr "Wbudowane polecenia:"

#: app/flatpak-main.c:298
#, c-format
msgid ""
"Note that the directories %s are not in the search path set by the "
"XDG_DATA_DIRS environment variable, so applications installed by Flatpak may "
"not appear on your desktop until the session is restarted."
msgstr ""
"Proszę zauważyć, że katalogi %s nie są w ścieżce wyszukiwania ustawionej "
"przez zmienną środowiskową XDG_DATA_DIRS, więc programy zainstalowane przez "
"Flatpak mogą nie pojawić się w środowisku pulpitu do czasu ponownego "
"uruchomienia sesji."

#: app/flatpak-main.c:312
#, c-format
msgid ""
"Note that the directory %s is not in the search path set by the "
"XDG_DATA_DIRS environment variable, so applications installed by Flatpak may "
"not appear on your desktop until the session is restarted."
msgstr ""
"Proszę zauważyć, że katalog %s nie jest w ścieżce wyszukiwania ustawionej "
"przez zmienną środowiskową XDG_DATA_DIRS, więc programy zainstalowane przez "
"Flatpak mogą nie pojawić się w środowisku pulpitu do czasu ponownego "
"uruchomienia sesji."

#: app/flatpak-main.c:381
msgid ""
"Refusing to operate under sudo with --user. Omit sudo to operate on the user "
"installation, or use a root shell to operate on the root user's installation."
msgstr ""
"Odmowa działania pod sudo z opcją --user. Należy ominąć sudo, aby działać "
"w instalacji użytkownika, albo użyć powłoki roota, aby działać w instalacji "
"użytkownika root."

#: app/flatpak-main.c:453
msgid ""
"Multiple installations specified for a command that works on one installation"
msgstr ""
"Podano wiele instalacji dla polecenia, które działa na jednej instalacji"

#: app/flatpak-main.c:504 app/flatpak-main.c:697
#, c-format
msgid "See '%s --help'"
msgstr "„%s --help” wyświetli więcej informacji"

#: app/flatpak-main.c:706
#, c-format
msgid "'%s' is not a flatpak command. Did you mean '%s%s'?"
msgstr "„%s” nie jest poleceniem Flatpak. Czy chodziło o „%s%s”?"

#: app/flatpak-main.c:709
#, c-format
msgid "'%s' is not a flatpak command"
msgstr "„%s” nie jest poleceniem Flatpak"

#: app/flatpak-main.c:824
msgid "No command specified"
msgstr "Nie podano polecenia"

#: app/flatpak-main.c:980
msgid "error:"
msgstr "błąd:"

#: app/flatpak-quiet-transaction.c:77
#, c-format
msgid "Installing %s\n"
msgstr "Instalowanie %s\n"

#: app/flatpak-quiet-transaction.c:81
#, c-format
msgid "Updating %s\n"
msgstr "Aktualizowanie %s\n"

#: app/flatpak-quiet-transaction.c:85
#, c-format
msgid "Uninstalling %s\n"
msgstr "Odinstalowywanie %s\n"

#: app/flatpak-quiet-transaction.c:107
#, c-format
msgid "Warning: Failed to install %s: %s\n"
msgstr "Ostrzeżenie: zainstalowanie %s się nie powiodło: %s\n"

#: app/flatpak-quiet-transaction.c:110
#, c-format
msgid "Error: Failed to install %s: %s\n"
msgstr "Błąd: zainstalowanie %s się nie powiodło: %s\n"

#: app/flatpak-quiet-transaction.c:116
#, c-format
msgid "Warning: Failed to update %s: %s\n"
msgstr "Ostrzeżenie: zaktualizowanie %s się nie powiodło: %s\n"

#: app/flatpak-quiet-transaction.c:119
#, c-format
msgid "Error: Failed to update %s: %s\n"
msgstr "Błąd: zaktualizowanie %s się nie powiodło: %s\n"

#: app/flatpak-quiet-transaction.c:125
#, c-format
msgid "Warning: Failed to install bundle %s: %s\n"
msgstr "Ostrzeżenie: zainstalowanie pakietu %s się nie powiodło: %s\n"

#: app/flatpak-quiet-transaction.c:128
#, c-format
msgid "Error: Failed to install bundle %s: %s\n"
msgstr "Błąd: zainstalowanie pakietu %s się nie powiodło: %s\n"

#: app/flatpak-quiet-transaction.c:134
#, c-format
msgid "Warning: Failed to uninstall %s: %s\n"
msgstr "Ostrzeżenie: odinstalowanie %s się nie powiodło: %s\n"

#: app/flatpak-quiet-transaction.c:137
#, c-format
msgid "Error: Failed to uninstall %s: %s\n"
msgstr "Błąd: odinstalowanie %s się nie powiodło: %s\n"

#: app/flatpak-quiet-transaction.c:166 common/flatpak-dir.c:11475
#, c-format
msgid "%s already installed"
msgstr "Już zainstalowano %s"

#: app/flatpak-quiet-transaction.c:168 common/flatpak-dir.c:3622
#: common/flatpak-dir.c:4321 common/flatpak-dir.c:16968
#: common/flatpak-dir.c:17258 common/flatpak-dir-utils.c:166
#: common/flatpak-dir-utils.c:259 common/flatpak-transaction.c:2736
#: common/flatpak-transaction.c:2791
#, c-format
msgid "%s not installed"
msgstr "Nie zainstalowano %s"

#: app/flatpak-quiet-transaction.c:170
#, c-format
msgid "%s needs a later flatpak version"
msgstr "%s wymaga nowszej wersji Flatpak"

#: app/flatpak-quiet-transaction.c:172
msgid "Not enough disk space to complete this operation"
msgstr "Za mało miejsca na dysku, aby ukończyć to działanie"

#: app/flatpak-quiet-transaction.c:239
#, c-format
msgid "Info: %s is end-of-life, in favor of %s\n"
msgstr "Informacja: %s jest niewspierane, w zamian jest %s\n"

#: app/flatpak-quiet-transaction.c:241
#, c-format
msgid "Info: %s is end-of-life, with reason: %s\n"
msgstr "Informacja: %s jest niewspierane z powodu: %s\n"

#: app/flatpak-quiet-transaction.c:251
#, c-format
msgid "Failed to rebase %s to %s: %s\n"
msgstr "Zmiana %s na %s się nie powiodła: %s\n"

#: common/flatpak-auth.c:58
#, c-format
msgid "No authenticator configured for remote `%s`"
msgstr "Nie skonfigurowano programu uwierzytelniającego dla repozytorium „%s”"

#: common/flatpak-context.c:637 common/flatpak-context.c:649
#, fuzzy, c-format
msgid "Invalid permission syntax: %s"
msgstr "Nieprawidłowa nazwa rozszerzenia %s"

#: common/flatpak-context.c:1207
#, c-format
msgid "Unknown share type %s, valid types are: %s"
msgstr "Nieznany typ udziału %s, prawidłowe typy: %s"

#: common/flatpak-context.c:1228
#, c-format
msgid "Unknown policy type %s, valid types are: %s"
msgstr "Nieznany typ polityki %s, prawidłowe typy: %s"

#: common/flatpak-context.c:1266
#, c-format
msgid "Invalid dbus name %s"
msgstr "Nieprawidłowa nazwa D-Bus %s"

#: common/flatpak-context.c:1279
#, c-format
msgid "Unknown socket type %s, valid types are: %s"
msgstr "Nieznany typ gniazda %s, prawidłowe typy: %s"

#: common/flatpak-context.c:1294
#, c-format
msgid "Unknown device type %s, valid types are: %s"
msgstr "Nieznany typ urządzenia %s, prawidłowe typy: %s"

#: common/flatpak-context.c:1308
#, c-format
msgid "Unknown feature type %s, valid types are: %s"
msgstr "Nieznany typ funkcji %s, prawidłowe typy: %s"

#: common/flatpak-context.c:1840
#, c-format
msgid "Filesystem location \"%s\" contains \"..\""
msgstr "Położenie w systemie plików „%s” zawiera „..”"

#: common/flatpak-context.c:1882
#, c-format
msgid ""
"--filesystem=/ is not available, use --filesystem=host for a similar result"
msgstr ""
"--filesystem=/ jest niedostępne, należy użyć --filesystem=host, aby osiągnąć "
"podobny efekt"

#: common/flatpak-context.c:1916
#, fuzzy, c-format
msgid ""
"Unknown filesystem location %s, valid locations are: host, host-os, host-"
"etc, host-root, home, xdg-*[/…], ~/dir, /dir"
msgstr ""
"Nieznane położenie systemu plików %s, prawidłowe położenia: host, host-os, "
"host-etc, home, xdg-*[/…], ~/dir, /dir"

#: common/flatpak-context.c:2015
#, fuzzy, c-format
msgid "Invalid syntax for %s: %s"
msgstr "Nieprawidłowa nazwa %s: %s"

#: common/flatpak-context.c:2142
#, c-format
msgid "fallback-x11 can not be conditional"
msgstr ""

#: common/flatpak-context.c:2318
#, c-format
msgid "Invalid env format %s"
msgstr "Nieznany format środowiska %s"

#: common/flatpak-context.c:2399
#, c-format
msgid "Environment variable name must not contain '=': %s"
msgstr "Nazwa zmiennej środowiskowej nie może zawierać „=”: %s"

#: common/flatpak-context.c:2527 common/flatpak-context.c:2535
#, c-format
msgid "--add-policy arguments must be in the form SUBSYSTEM.KEY=VALUE"
msgstr "Parametry --add-policy muszą być w formacie PODSYSTEM.KLUCZ=WARTOŚĆ"

#: common/flatpak-context.c:2542
#, c-format
msgid "--add-policy values can't start with \"!\""
msgstr "Wartości --add-policy nie mogą zaczynać się od znaku „!”"

#: common/flatpak-context.c:2567 common/flatpak-context.c:2575
#, c-format
msgid "--remove-policy arguments must be in the form SUBSYSTEM.KEY=VALUE"
msgstr "Parametry --remove-policy muszą być w formacie PODSYSTEM.KLUCZ=WARTOŚĆ"

#: common/flatpak-context.c:2582
#, c-format
msgid "--remove-policy values can't start with \"!\""
msgstr "Wartości --remove-policy nie mogą zaczynać się od znaku „!”"

#: common/flatpak-context.c:2657
msgid "Share with host"
msgstr "Udostępnia temu komputerowi"

#: common/flatpak-context.c:2657 common/flatpak-context.c:2658
msgid "SHARE"
msgstr "UDZIAŁ"

#: common/flatpak-context.c:2658
msgid "Unshare with host"
msgstr "Przestaje udostępniać temu komputerowi"

#: common/flatpak-context.c:2659
msgid "Require conditions to be met for a subsystem to get shared"
msgstr ""

#: common/flatpak-context.c:2659
msgid "SHARE:CONDITION"
msgstr ""

#: common/flatpak-context.c:2660
msgid "Expose socket to app"
msgstr "Udostępnia gniazdo programowi"

#: common/flatpak-context.c:2660 common/flatpak-context.c:2661
msgid "SOCKET"
msgstr "GNIAZDO"

#: common/flatpak-context.c:2661
msgid "Don't expose socket to app"
msgstr "Nie udostępnia gniazda programowi"

#: common/flatpak-context.c:2662
msgid "Require conditions to be met for a socket to get exposed"
msgstr ""

#: common/flatpak-context.c:2662
msgid "SOCKET:CONDITION"
msgstr ""

#: common/flatpak-context.c:2663
msgid "Expose device to app"
msgstr "Udostępnia urządzenie programowi"

#: common/flatpak-context.c:2663 common/flatpak-context.c:2664
msgid "DEVICE"
msgstr "URZĄDZENIE"

#: common/flatpak-context.c:2664
msgid "Don't expose device to app"
msgstr "Nie udostępnia urządzenia programowi"

#: common/flatpak-context.c:2665
msgid "Require conditions to be met for a device to get exposed"
msgstr ""

#: common/flatpak-context.c:2665
msgid "DEVICE:CONDITION"
msgstr ""

#: common/flatpak-context.c:2666
msgid "Allow feature"
msgstr "Zezwala na funkcję"

#: common/flatpak-context.c:2666 common/flatpak-context.c:2667
msgid "FEATURE"
msgstr "FUNKCJA"

#: common/flatpak-context.c:2667
msgid "Don't allow feature"
msgstr "Bez zezwolenia na funkcję"

#: common/flatpak-context.c:2668
msgid "Require conditions to be met for a feature to get allowed"
msgstr ""

#: common/flatpak-context.c:2668
msgid "FEATURE:CONDITION"
msgstr ""

#: common/flatpak-context.c:2669
msgid "Expose filesystem to app (:ro for read-only)"
msgstr "Udostępnia system plików programowi (:ro dla tylko do odczytu)"

#: common/flatpak-context.c:2669
msgid "FILESYSTEM[:ro]"
msgstr "SYSTEM-PLIKÓW[:ro]"

#: common/flatpak-context.c:2670
msgid "Don't expose filesystem to app"
msgstr "Nie udostępnia systemu plików programowi"

#: common/flatpak-context.c:2670
msgid "FILESYSTEM"
msgstr "SYSTEM-PLIKÓW"

#: common/flatpak-context.c:2671
msgid "Set environment variable"
msgstr "Ustawia zmienną środowiskową"

#: common/flatpak-context.c:2671
msgid "VAR=VALUE"
msgstr "ZMIENNA=WARTOŚĆ"

#: common/flatpak-context.c:2672
msgid "Read environment variables in env -0 format from FD"
msgstr "Odczytuje zmienne środowiskowe w formacie env -0 z FD"

#: common/flatpak-context.c:2673
msgid "Remove variable from environment"
msgstr "Usuwa zmienną ze środowiska"

#: common/flatpak-context.c:2673
msgid "VAR"
msgstr "ZMIENNA"

#: common/flatpak-context.c:2674
msgid "Allow app to own name on the session bus"
msgstr "Zezwala programowi na posiadanie nazwy na magistrali sesji"

#: common/flatpak-context.c:2674 common/flatpak-context.c:2675
#: common/flatpak-context.c:2676 common/flatpak-context.c:2677
#: common/flatpak-context.c:2678 common/flatpak-context.c:2679
#: common/flatpak-context.c:2680
msgid "DBUS_NAME"
msgstr "NAZWA_D-BUS"

#: common/flatpak-context.c:2675
msgid "Allow app to talk to name on the session bus"
msgstr "Umożliwia programowi rozmawianie z nazwą na magistrali sesji"

#: common/flatpak-context.c:2676
msgid "Don't allow app to talk to name on the session bus"
msgstr "Bez zezwolenia programowi na rozmawianie z nazwą na magistrali sesji"

#: common/flatpak-context.c:2677
msgid "Allow app to own name on the system bus"
msgstr "Zezwala programowi na posiadanie nazwy na magistrali systemu"

#: common/flatpak-context.c:2678
msgid "Allow app to talk to name on the system bus"
msgstr "Umożliwia programowi rozmawianie z nazwą na magistrali systemu"

#: common/flatpak-context.c:2679
msgid "Don't allow app to talk to name on the system bus"
msgstr "Bez zezwolenia programowi na rozmawianie z nazwą na magistrali systemu"

#: common/flatpak-context.c:2680
msgid "Allow app to own name on the a11y bus"
msgstr "Zezwala programowi na posiadanie nazwy na magistrali ułatwień dostępu"

#: common/flatpak-context.c:2681
msgid "Add generic policy option"
msgstr "Dodaje ogólną opcję polityki"

#: common/flatpak-context.c:2681 common/flatpak-context.c:2682
msgid "SUBSYSTEM.KEY=VALUE"
msgstr "PODSYSTEM.KLUCZ=WARTOŚĆ"

#: common/flatpak-context.c:2682
msgid "Remove generic policy option"
msgstr "Usuwa ogólną opcję polityki"

#: common/flatpak-context.c:2683
msgid "Add USB device to enumerables"
msgstr "Dodaje urządzenie USB do wyliczeń"

#: common/flatpak-context.c:2683 common/flatpak-context.c:2684
msgid "VENDOR_ID:PRODUCT_ID"
msgstr "IDENTYFIKATOR_PRODUCENTA:IDENTYFIKATOR_PRODUKTU"

#: common/flatpak-context.c:2684
msgid "Add USB device to hidden list"
msgstr "Dodaje urządzenie USB do listy ukrytych"

#: common/flatpak-context.c:2685
msgid "A list of USB devices that are enumerable"
msgstr "Lista urządzeń USB, które można wyliczać"

#: common/flatpak-context.c:2685
msgid "LIST"
msgstr "LISTA"

#: common/flatpak-context.c:2686
msgid "File containing a list of USB devices to make enumerable"
msgstr "Plik zawierający listę urządzeń USB, które będzie można wyliczać"

#: common/flatpak-context.c:2686 common/flatpak-context.c:2687
msgid "FILENAME"
msgstr "NAZWA-PLIKU"

#: common/flatpak-context.c:2687
msgid "Persist home directory subpath"
msgstr "Trwała podścieżka katalogu domowego"

#. This is not needed/used anymore, so hidden, but we accept it for backwards compat
#: common/flatpak-context.c:2689
msgid "Don't require a running session (no cgroups creation)"
msgstr "Bez wymagania działającej sesji (bez tworzenia cgroups)"

#: common/flatpak-context.c:3718
#, c-format
msgid "Not replacing \"%s\" with tmpfs: %s"
msgstr "„%s” nie zostanie zastąpione tmpfs: %s"

#: common/flatpak-context.c:3726
#, c-format
msgid "Not sharing \"%s\" with sandbox: %s"
msgstr "„%s” nie będzie udostępniane piaskownicy: %s"

#. Even if the error is one that we would normally silence, like
#. * the path not existing, it seems reasonable to make more of a fuss
#. * about the home directory not existing or otherwise being unusable,
#. * so this is intentionally not using cannot_export()
#: common/flatpak-context.c:3828
#, c-format
msgid "Not allowing home directory access: %s"
msgstr "Dostęp do katalogu domowego nie zostanie udzielony: %s"

#: common/flatpak-context.c:4062
#, c-format
msgid "Unable to provide a temporary home directory in the sandbox: %s"
msgstr "Nie można dostarczyć tymczasowego katalogu domowego w piaskownicy: %s"

#: common/flatpak-dir.c:442
#, c-format
msgid "Configured collection ID ‘%s’ not in summary file"
msgstr ""
"Identyfikator skonfigurowanej kolekcji „%s” nie jest w pliku podsumowania"

#: common/flatpak-dir.c:587
#, c-format
msgid "Unable to load summary from remote %s: %s"
msgstr "Nie można wczytać podsumowania z repozytorium %s: %s"

#: common/flatpak-dir.c:764 common/flatpak-dir.c:800 common/flatpak-dir.c:906
#, c-format
msgid "No such ref '%s' in remote %s"
msgstr "Brak odniesienia „%s” w repozytorium %s"

#: common/flatpak-dir.c:891 common/flatpak-dir.c:1051 common/flatpak-dir.c:1080
#: common/flatpak-dir.c:1092
#, c-format
msgid "No entry for %s in remote %s summary flatpak cache"
msgstr ""
"Brak wpisu dla %s w pamięci podręcznej Flatpak podsumowania repozytorium %s"

#: common/flatpak-dir.c:1069
#, c-format
msgid "No summary or Flatpak cache available for remote %s"
msgstr ""
"Brak dostępnego podsumowania lub pamięci podręcznej Flatpak dla repozytorium "
"%s"

#: common/flatpak-dir.c:1097
#, c-format
msgid "Missing xa.data in summary for remote %s"
msgstr "Brak „xa.data” w podsumowaniu dla repozytorium %s"

#: common/flatpak-dir.c:1103 common/flatpak-dir.c:1546
#, c-format
msgid "Unsupported summary version %d for remote %s"
msgstr "Nieobsługiwana wersja podsumowania %d dla repozytorium %s"

#: common/flatpak-dir.c:1200
msgid "Remote OCI index has no registry uri"
msgstr "Indeks OCI repozytorium nie ma adresu URI rejestru"

#: common/flatpak-dir.c:1261
#, c-format
msgid "Couldn't find ref %s in remote %s"
msgstr "Nie można odnaleźć odniesienia %s w repozytorium %s"

#: common/flatpak-dir.c:1288 common/flatpak-dir.c:1381
#, fuzzy, c-format
msgid "Commit has no requested ref ‘%s’ in ref binding metadata (found: ‘%s’)"
msgstr ""
"Zatwierdzenie nie ma żądanego odniesienia „%s” w metadanych dowiązania "
"odniesienia"

#: common/flatpak-dir.c:1413
#, c-format
msgid "Configured collection ID ‘%s’ not in binding metadata"
msgstr ""
"Identyfikator skonfigurowanej kolekcji „%s” nie jest w metadanych dowiązania"

#: common/flatpak-dir.c:1449 common/flatpak-dir.c:5645
#, c-format
msgid "Couldn't find latest checksum for ref %s in remote %s"
msgstr ""
"Nie można odnaleźć najnowszej sumy kontrolnej dla odniesienia %s "
"w repozytorium %s"

#: common/flatpak-dir.c:1516 common/flatpak-dir.c:1552
#, c-format
msgid "No entry for %s in remote %s summary flatpak sparse cache"
msgstr ""
"Brak wpisu dla %s w rozsianej pamięci podręcznej Flatpak podsumowania "
"repozytorium %s"

#: common/flatpak-dir.c:2540
#, c-format
msgid "Commit metadata for %s not matching expected metadata"
msgstr ""
"Metadane zatwierdzenia dla %s nie zgadzają się z oczekiwanymi metadanymi"

#: common/flatpak-dir.c:2823
msgid "Unable to connect to system bus"
msgstr "Nie można połączyć się z magistralą systemu"

#: common/flatpak-dir.c:3419
msgid "User installation"
msgstr "Instalacja użytkownika"

#: common/flatpak-dir.c:3426
#, c-format
msgid "System (%s) installation"
msgstr "Instalacja systemowa (%s)"

#: common/flatpak-dir.c:3472
#, c-format
msgid "No overrides found for %s"
msgstr "Nie odnaleziono zastępników dla %s"

#: common/flatpak-dir.c:3625
#, c-format
msgid "%s (commit %s) not installed"
msgstr "Nie zainstalowano %s (zatwierdzenie %s)"

#: common/flatpak-dir.c:4650
#, c-format
msgid "Error parsing system flatpakrepo file for %s: %s"
msgstr "Błąd podczas przetwarzania pliku repozytorium Flatpak dla %s: %s"

#: common/flatpak-dir.c:4735
#, c-format
msgid "While opening repository %s: "
msgstr "Podczas otwierania repozytorium %s: "

#: common/flatpak-dir.c:5004
#, c-format
msgid "The config key %s is not set"
msgstr "Klucz konfiguracji %s nie jest ustawiony"

#: common/flatpak-dir.c:5140
#, c-format
msgid "No current %s pattern matching %s"
msgstr "Brak obecnych wzorów %s pasujących do %s"

#: common/flatpak-dir.c:5422
msgid "No appstream commit to deploy"
msgstr "Brak zatwierdzenia AppStream do wdrożenia"

#: common/flatpak-dir.c:5941 common/flatpak-dir.c:7266
#: common/flatpak-dir.c:10881 common/flatpak-dir.c:11618
msgid "Can't pull from untrusted non-gpg verified remote"
msgstr ""
"Nie można pobrać z niezaufanego, niesprawdzonego przez GPG repozytorium"

#: common/flatpak-dir.c:6376 common/flatpak-dir.c:6591
msgid "Extra data not supported for non-gpg-verified local system installs"
msgstr ""
"Dodatkowe dane nie są obsługiwane dla niesprawdzonych przez GPG lokalnych "
"instalacji systemowych"

#: common/flatpak-dir.c:6415 common/flatpak-dir.c:6782
#, c-format
msgid "Invalid checksum for extra data uri %s"
msgstr "Nieprawidłowa suma kontrolna dla adresu URI dodatkowych danych %s"

#: common/flatpak-dir.c:6424
#, c-format
msgid "Empty name for extra data uri %s"
msgstr "Pusta nazwa dla adresu URI %s dodatkowych danych"

#: common/flatpak-dir.c:6432
#, c-format
msgid "Unsupported extra data uri %s"
msgstr "Nieobsługiwany adres URI %s dodatkowych danych"

#: common/flatpak-dir.c:6461
#, c-format
msgid "Failed to load local extra-data %s: %s"
msgstr "Wczytanie lokalnych dodatkowych danych %s się nie powiodło: %s"

#: common/flatpak-dir.c:6469
#, c-format
msgid "Wrong size for extra-data %s"
msgstr "Błędny rozmiar dodatkowych danych %s"

#: common/flatpak-dir.c:6488
#, c-format
msgid "While downloading %s: "
msgstr "Podczas pobierania %s: "

#: common/flatpak-dir.c:6498
#, c-format
msgid "Wrong size for extra data %s"
msgstr "Błędny rozmiar dodatkowych danych %s"

#: common/flatpak-dir.c:6507
#, c-format
msgid "Invalid checksum for extra data %s"
msgstr "Nieprawidłowa suma kontrolna dodatkowych danych %s"

#: common/flatpak-dir.c:7096 common/flatpak-dir.c:7349
#, c-format
msgid "While pulling %s from remote %s: "
msgstr "Podczas pobierania %s z repozytorium %s: "

#: common/flatpak-dir.c:7290 common/flatpak-repo-utils.c:3886
msgid "GPG signatures found, but none are in trusted keyring"
msgstr "Odnaleziono podpisy GPG, ale żadne nie są w zaufanej bazie kluczy"

#: common/flatpak-dir.c:7307
#, c-format
msgid "Commit for ‘%s’ has no ref binding"
msgstr "Zatwierdzenie dla „%s” nie ma dowiązania odniesienia"

#: common/flatpak-dir.c:7312
#, c-format
msgid "Commit for ‘%s’ is not in expected bound refs: %s"
msgstr ""
"Zatwierdzenie dla „%s” nie jest w oczekiwanych dowiązanych odniesieniach: %s"

#: common/flatpak-dir.c:7488
msgid "Only applications can be made current"
msgstr "Tylko programy mogą być ustawione jako bieżące"

#: common/flatpak-dir.c:8192
msgid "Not enough memory"
msgstr "Za mało pamięci"

#: common/flatpak-dir.c:8211
msgid "Failed to read from exported file"
msgstr "Odczytanie z wyeksportowanego pliku się nie powiodło"

#: common/flatpak-dir.c:8401
msgid "Error reading mimetype xml file"
msgstr "Błąd podczas odczytywania pliku XML typu MIME"

#: common/flatpak-dir.c:8406
msgid "Invalid mimetype xml file"
msgstr "Nieprawidłowy plik XML typu MIME"

#: common/flatpak-dir.c:8492
#, c-format
msgid "D-Bus service file '%s' has wrong name"
msgstr "Plik usługi D-Bus „%s” ma błędną nazwę"

#: common/flatpak-dir.c:8647
#, c-format
msgid "Invalid Exec argument %s"
msgstr "Nieprawidłowy parametr Exec %s"

#: common/flatpak-dir.c:9115
msgid "While getting detached metadata: "
msgstr "Podczas pobierania odłączonych metadanych: "

#: common/flatpak-dir.c:9120 common/flatpak-dir.c:9125
#: common/flatpak-dir.c:9129
msgid "Extra data missing in detached metadata"
msgstr "Brak dodatkowych danych w odłączonych metadanych"

#: common/flatpak-dir.c:9133
msgid "While creating extradir: "
msgstr "Podczas tworzenia dodatkowego katalogu: "

#: common/flatpak-dir.c:9154 common/flatpak-dir.c:9187
msgid "Invalid checksum for extra data"
msgstr "Nieprawidłowa suma kontrolna dodatkowych danych"

#: common/flatpak-dir.c:9183
msgid "Wrong size for extra data"
msgstr "Błędny rozmiar dodatkowych danych"

#: common/flatpak-dir.c:9196
#, c-format
msgid "While writing extra data file '%s': "
msgstr "Podczas zapisywania pliku dodatkowych danych „%s”: "

#: common/flatpak-dir.c:9204
#, c-format
msgid "Extra data %s missing in detached metadata"
msgstr "Brak dodatkowych danych %s w odłączonych metadanych"

#: common/flatpak-dir.c:9278
#, c-format
msgid "Unable to get runtime key from metadata"
msgstr "Nie można uzyskać klucza środowiska wykonawczego z metadanych"

#: common/flatpak-dir.c:9402
#, c-format
msgid "apply_extra script failed, exit status %d"
msgstr "Skrypt „apply_extra” się nie powiódł, stan wyjścia %d"

#. Translators: The placeholder is for an app ref.
#: common/flatpak-dir.c:9591
#, c-format
msgid "Installing %s is not allowed by the policy set by your administrator"
msgstr ""
"Instalacja programu %s jest zabroniona przez zasady ustawione przez "
"administratora"

#: common/flatpak-dir.c:9690
#, c-format
msgid "While trying to resolve ref %s: "
msgstr "Podczas rozwiązywania odniesienia %s: "

#: common/flatpak-dir.c:9702
#, c-format
msgid "%s is not available"
msgstr "%s jest niedostępne"

#: common/flatpak-dir.c:9714 common/flatpak-dir.c:11495
#, c-format
msgid "%s commit %s already installed"
msgstr "Już zainstalowano %s, zatwierdzenie %s"

#: common/flatpak-dir.c:9721
msgid "Can't create deploy directory"
msgstr "Nie można utworzyć katalogu wdrażania"

#: common/flatpak-dir.c:9729
#, c-format
msgid "Failed to read commit %s: "
msgstr "Odczytanie zatwierdzenia %s się nie powiodło: "

#: common/flatpak-dir.c:9750
#, c-format
msgid "While trying to checkout %s into %s: "
msgstr "Podczas wymeldowywania %s do %s: "

#: common/flatpak-dir.c:9769
msgid "While trying to checkout metadata subpath: "
msgstr "Podczas wymeldowywania podścieżki metadanych: "

#: common/flatpak-dir.c:9801
#, c-format
msgid "While trying to checkout subpath ‘%s’: "
msgstr "Podczas wymeldowywania podścieżki „%s”: "

#: common/flatpak-dir.c:9811
msgid "While trying to remove existing extra dir: "
msgstr "Podczas usuwania istniejącego dodatkowego katalogu: "

#: common/flatpak-dir.c:9822
msgid "While trying to apply extra data: "
msgstr "Podczas zastosowywania dodatkowych danych: "

#: common/flatpak-dir.c:9849
#, c-format
msgid "Invalid commit ref %s: "
msgstr "Nieprawidłowe odniesienie zatwierdzenia %s: "

#: common/flatpak-dir.c:9857 common/flatpak-dir.c:9869
#, c-format
msgid "Deployed ref %s does not match commit (%s)"
msgstr "Wdrożone odniesienie %s nie pasuje do zatwierdzenia (%s)"

#: common/flatpak-dir.c:9863
#, c-format
msgid "Deployed ref %s branch does not match commit (%s)"
msgstr "Gałąź wdrożonego odniesienia %s nie pasuje do zatwierdzenia (%s)"

#: common/flatpak-dir.c:10125 common/flatpak-installation.c:1911
#, c-format
msgid "%s branch %s already installed"
msgstr "Już zainstalowano %s, gałąź %s"

#: common/flatpak-dir.c:10985
#, c-format
msgid "Could not unmount revokefs-fuse filesystem at %s: "
msgstr "Nie można odmontować systemu plików revokefs-fuse w %s: "

#: common/flatpak-dir.c:11289
#, c-format
msgid "This version of %s is already installed"
msgstr "Ta wersja programu %s jest już zainstalowana"

#: common/flatpak-dir.c:11302
#, c-format
msgid "Can't change remote during bundle install"
msgstr "Nie można zmienić repozytorium podczas instalacji pakietu"

#: common/flatpak-dir.c:11571
msgid "Can't update to a specific commit without root permissions"
msgstr "Nie można zaktualizować do podanego zatwierdzenia bez uprawnień roota"

#: common/flatpak-dir.c:11852
#, c-format
msgid "Can't remove %s, it is needed for: %s"
msgstr "Nie można usunąć %s, jest wymagane dla: %s"

#: common/flatpak-dir.c:11912 common/flatpak-installation.c:2067
#, c-format
msgid "%s branch %s is not installed"
msgstr "Nie zainstalowano %s, gałęzi %s"

#: common/flatpak-dir.c:12165
#, c-format
msgid "%s commit %s not installed"
msgstr "Nie zainstalowano %s, zatwierdzenie %s"

#: common/flatpak-dir.c:12501
#, c-format
msgid "Pruning repo failed: %s"
msgstr "Usuwanie nieużywanych obiektów z repozytorium się nie powiodło: %s"

#: common/flatpak-dir.c:12669 common/flatpak-dir.c:12675
#, c-format
msgid "Failed to load filter '%s'"
msgstr "Wczytanie filtru „%s” się nie powiodło"

#: common/flatpak-dir.c:12681
#, c-format
msgid "Failed to parse filter '%s'"
msgstr "Przetworzenie filtru „%s” się nie powiodło"

#: common/flatpak-dir.c:12963
msgid "Failed to write summary cache: "
msgstr "Zapisanie pamięci podręcznej podsumowań się nie powiodło: "

#: common/flatpak-dir.c:12982
#, c-format
msgid "No oci summary cached for remote '%s'"
msgstr "Brak podsumowania OCI w pamięci podręcznej dla repozytorium „%s”"

#: common/flatpak-dir.c:13207
#, c-format
msgid "No cached summary for remote '%s'"
msgstr "Brak podsumowania w pamięci podręcznej dla repozytorium „%s”"

#: common/flatpak-dir.c:13248
#, c-format
msgid "Invalid checksum for indexed summary %s read from %s"
msgstr ""
"Nieprawidłowa suma kontrolna zindeksowanego podsumowania %s odczytanego z %s"

#: common/flatpak-dir.c:13321
#, c-format
msgid ""
"Remote listing for %s not available; server has no summary file. Check the "
"URL passed to remote-add was valid."
msgstr ""
"Lista repozytorium dla %s jest niedostępna — serwer nie ma pliku "
"podsumowania. Proszę sprawdzić, czy adres URL przekazywany do remote-add "
"jest prawidłowy."

#: common/flatpak-dir.c:13698
#, c-format
msgid "Invalid checksum for indexed summary %s for remote '%s'"
msgstr ""
"Nieprawidłowa suma kontrolna zindeksowanego podsumowania %s dla repozytorium "
"„%s”"

#: common/flatpak-dir.c:14388
#, c-format
msgid "Multiple branches available for %s, you must specify one of: "
msgstr "Dla %s dostępnych jest wiele gałęzi, należy podać jedną z: "

#: common/flatpak-dir.c:14454
#, c-format
msgid "Nothing matches %s"
msgstr "Nic nie pasuje do %s"

#: common/flatpak-dir.c:14562
#, c-format
msgid "Can't find ref %s%s%s%s%s"
msgstr "Nie można odnaleźć odniesienia %s%s%s%s%s"

#: common/flatpak-dir.c:14605
#, c-format
msgid "Error searching remote %s: %s"
msgstr "Błąd podczas wyszukiwania repozytorium %s: %s"

#: common/flatpak-dir.c:14702
#, c-format
msgid "Error searching local repository: %s"
msgstr "Błąd podczas wyszukiwania lokalnego repozytorium: %s"

#: common/flatpak-dir.c:14839
#, c-format
msgid "%s/%s/%s not installed"
msgstr "Nie zainstalowano %s/%s/%s"

#: common/flatpak-dir.c:15042
#, c-format
msgid "Could not find installation %s"
msgstr "Nie można odnaleźć instalacji %s"

#: common/flatpak-dir.c:15612
#, c-format
msgid "Invalid file format, no %s group"
msgstr "Nieprawidłowy format pliku, brak grupy %s"

#: common/flatpak-dir.c:15617 common/flatpak-repo-utils.c:2836
#, c-format
msgid "Invalid version %s, only 1 supported"
msgstr "Nieprawidłowa wersja %s, obsługiwana jest tylko wersja 1"

#: common/flatpak-dir.c:15622 common/flatpak-dir.c:15627
#, c-format
msgid "Invalid file format, no %s specified"
msgstr "Nieprawidłowy format pliku, nie podano %s"

#. Check some minimal size so we don't get crap
#: common/flatpak-dir.c:15647
msgid "Invalid file format, gpg key invalid"
msgstr "Nieprawidłowy format pliku, nieprawidłowy klucz GPG"

#: common/flatpak-dir.c:15675 common/flatpak-repo-utils.c:2917
msgid "Collection ID requires GPG key to be provided"
msgstr "Identyfikator kolekcji wymaga dostarczenia klucza GPG"

#: common/flatpak-dir.c:15718
#, c-format
msgid "Runtime %s, branch %s is already installed"
msgstr "Już zainstalowano środowisko wykonawcze %s, gałąź %s"

#: common/flatpak-dir.c:15719
#, c-format
msgid "App %s, branch %s is already installed"
msgstr "Już zainstalowano program %s, gałąź %s"

#: common/flatpak-dir.c:15953
#, c-format
msgid "Can't remove remote '%s' with installed ref %s (at least)"
msgstr ""
"Nie można usunąć repozytorium „%s” z zainstalowanym odniesieniem %s (co "
"najmniej)"

#: common/flatpak-dir.c:16058
#, c-format
msgid "Invalid character '/' in remote name: %s"
msgstr "Nieprawidłowy znak „/” w nazwie repozytorium: %s"

#: common/flatpak-dir.c:16064
#, c-format
msgid "No configuration for remote %s specified"
msgstr "Nie podano konfiguracji dla repozytorium %s"

#: common/flatpak-dir.c:17597
#, c-format
msgid "Skipping deletion of mirror ref (%s, %s)…\n"
msgstr "Pomijanie usuwania odniesienia serwera lustrzanego (%s, %s)…\n"

#: common/flatpak-exports.c:931
#, c-format
msgid "An absolute path is required"
msgstr "Wymagana jest ścieżka bezwzględna"

#: common/flatpak-exports.c:948
#, c-format
msgid "Unable to open path \"%s\": %s"
msgstr "Nie można otworzyć ścieżki „%s”: %s"

#: common/flatpak-exports.c:955
#, c-format
msgid "Unable to get file type of \"%s\": %s"
msgstr "Nie można uzyskać typu pliku „%s”: %s"

#: common/flatpak-exports.c:964
#, c-format
msgid "File \"%s\" has unsupported type 0o%o"
msgstr "Plik „%s” ma nieobsługiwany typ 0o%o"

#: common/flatpak-exports.c:970
#, c-format
msgid "Unable to get filesystem information for \"%s\": %s"
msgstr "Nie można uzyskać informacji o systemie plików dla „%s”: %s"

#: common/flatpak-exports.c:980
#, c-format
msgid "Ignoring blocking autofs path \"%s\""
msgstr "Ignorowanie blokującej ścieżki autofs „%s”"

#: common/flatpak-exports.c:996 common/flatpak-exports.c:1009
#: common/flatpak-exports.c:1022
#, c-format
msgid "Path \"%s\" is reserved by Flatpak"
msgstr "Ścieżka „%s” jest zastrzeżona przez Flatpak"

#: common/flatpak-exports.c:1076
#, c-format
msgid "Unable to resolve symbolic link \"%s\": %s"
msgstr "Nie można rozwiązać dowiązania symbolicznego „%s”: %s"

#: common/flatpak-glib-backports.c:69
msgid "Empty string is not a number"
msgstr "Pusty ciąg nie jest liczbą"

#: common/flatpak-glib-backports.c:95
#, c-format
msgid "“%s” is not an unsigned number"
msgstr "„%s” nie jest liczbą bez znaku"

#: common/flatpak-glib-backports.c:105
#, c-format
msgid "Number “%s” is out of bounds [%s, %s]"
msgstr "Liczba „%s” jest poza zakresem [%s, %s]"

#: common/flatpak-image-source.c:83
msgid "Only sha256 image checksums are supported"
msgstr ""

#: common/flatpak-image-source.c:100 common/flatpak-image-source.c:108
msgid "Image is not a manifest"
msgstr "Obraz nie jest w manifeście"

#: common/flatpak-image-source.c:123
msgid "No org.flatpak.ref found in image"
msgstr "W obrazie nie odnaleziono org.flatpak.ref"

#: common/flatpak-image-source.c:148
#, c-format
msgid "Ref '%s' not found in registry"
msgstr "Nie odnaleziono odniesienia „%s” w rejestrze"

#: common/flatpak-image-source.c:157
msgid "Multiple images in registry, specify a ref with --ref"
msgstr ""
"Wiele obrazów w rejestrze, należy podać odniesienie za pomocą opcji --ref"

#: common/flatpak-installation.c:834
#, c-format
msgid "Ref %s not installed"
msgstr "Nie zainstalowano odniesienia %s"

#: common/flatpak-installation.c:875
#, c-format
msgid "App %s not installed"
msgstr "Nie zainstalowano programu %s"

#: common/flatpak-installation.c:1395
#, c-format
msgid "Remote '%s' already exists"
msgstr "Repozytorium „%s” już istnieje"

#: common/flatpak-installation.c:1946
#, c-format
msgid "As requested, %s was only pulled, but not installed"
msgstr "Jak zażądano, %s zostało tylko pobrane, ale nie zainstalowane"

#: common/flatpak-instance.c:533 common/flatpak-instance.c:687
#: common/flatpak-instance.c:728
#, c-format
msgid "Unable to create directory %s"
msgstr "Nie można utworzyć katalogu %s"

#: common/flatpak-instance.c:554
#, c-format
msgid "Unable to lock %s"
msgstr "Nie można zablokować %s"

#: common/flatpak-instance.c:627
#, c-format
msgid "Unable to create temporary directory in %s"
msgstr "Nie można utworzyć tymczasowego katalogu w %s"

#: common/flatpak-instance.c:639
#, c-format
msgid "Unable to create file %s"
msgstr "Nie można utworzyć pliku %s"

#: common/flatpak-instance.c:646
#, c-format
msgid "Unable to update symbolic link %s/%s"
msgstr "Nie można zaktualizować dowiązania symbolicznego %s/%s"

#: common/flatpak-oci-registry.c:1197
msgid "Only Bearer authentication supported"
msgstr "Obsługiwane jest tylko uwierzytelnianie na okaziciela"

#: common/flatpak-oci-registry.c:1206
msgid "Only realm in authentication request"
msgstr "Tylko obszar w żądaniu uwierzytelnienia"

#: common/flatpak-oci-registry.c:1213
msgid "Invalid realm in authentication request"
msgstr "Nieprawidłowy obszar w żądaniu uwierzytelnienia"

#: common/flatpak-oci-registry.c:1283
#, c-format
msgid "Authorization failed: %s"
msgstr "Upoważnienie się nie powiodło: %s"

#: common/flatpak-oci-registry.c:1285
msgid "Authorization failed"
msgstr "Upoważnienie się nie powiodło"

#: common/flatpak-oci-registry.c:1289
#, c-format
msgid "Unexpected response status %d when requesting token: %s"
msgstr "Nieoczekiwany stan odpowiedzi %d podczas żądania tokena: %s"

#: common/flatpak-oci-registry.c:1300
msgid "Invalid authentication request response"
msgstr "Nieprawidłowa odpowiedź żądania uwierzytelnienia"

#: common/flatpak-oci-registry.c:1731
#, c-format
msgid "Flatpak was compiled without zstd support"
msgstr ""

#: common/flatpak-oci-registry.c:1923 common/flatpak-oci-registry.c:1975
#: common/flatpak-oci-registry.c:2004 common/flatpak-oci-registry.c:2059
#: common/flatpak-oci-registry.c:2115 common/flatpak-oci-registry.c:2193
msgid "Invalid delta file format"
msgstr "Nieprawidłowy format pliku delty"

#: common/flatpak-oci-registry.c:3198 common/flatpak-oci-registry.c:3382
msgid "Invalid OCI image config"
msgstr "Nieprawidłowa konfiguracja obrazu OCI"

#: common/flatpak-oci-registry.c:3260 common/flatpak-oci-registry.c:3531
#, c-format
msgid "Wrong layer checksum, expected %s, was %s"
msgstr "Błędna suma kontrolna warstwy, oczekiwano %s, wynosi %s"

#: common/flatpak-oci-registry.c:3359
#, c-format
msgid "No ref specified for OCI image %s"
msgstr "Nie podano odniesienia dla obrazu OCI %s"

#: common/flatpak-oci-registry.c:3369
#, c-format
msgid "Wrong ref (%s) specified for OCI image %s, expected %s"
msgstr "Podano błędne odniesienie (%s) dla obrazu OCI %s, oczekiwano %s"

#: common/flatpak-progress.c:236
#, c-format
msgid "Downloading metadata: %u/(estimating) %s"
msgstr "Pobieranie metadanych: %u/(szacowanie) %s"

#: common/flatpak-progress.c:260
#, c-format
msgid "Downloading: %s/%s"
msgstr "Pobieranie: %s/%s"

#: common/flatpak-progress.c:280
#, c-format
msgid "Downloading extra data: %s/%s"
msgstr "Pobieranie dodatkowych danych: %s/%s"

#: common/flatpak-progress.c:285
#, c-format
msgid "Downloading files: %d/%d %s"
msgstr "Pobieranie plików: %d/%d %s"

#: common/flatpak-ref-utils.c:122
msgid "Name can't be empty"
msgstr "Nazwa nie może być pusta"

#: common/flatpak-ref-utils.c:129
msgid "Name can't be longer than 255 characters"
msgstr "Nazwa nie może mieć więcej niż 255 znaków"

#: common/flatpak-ref-utils.c:142
msgid "Name can't start with a period"
msgstr "Nazwa nie może zaczynać się od kropki"

#: common/flatpak-ref-utils.c:148
#, c-format
msgid "Name can't start with %c"
msgstr "Nazwa nie może zaczynać się od %c"

#: common/flatpak-ref-utils.c:164
msgid "Name can't end with a period"
msgstr "Nazwa nie może kończyć się kropką"

#: common/flatpak-ref-utils.c:171 common/flatpak-ref-utils.c:183
msgid "Only last name segment can contain -"
msgstr "Tylko ostatni segment nazwy może zawierać -"

#: common/flatpak-ref-utils.c:174
#, c-format
msgid "Name segment can't start with %c"
msgstr "Segment nazwy nie może zaczynać się od %c"

#: common/flatpak-ref-utils.c:186
#, c-format
msgid "Name can't contain %c"
msgstr "Nazwa nie może zawierać %c"

#: common/flatpak-ref-utils.c:195
msgid "Names must contain at least 2 periods"
msgstr "Nazwy muszą zawierać co najmniej dwie kropki"

#: common/flatpak-ref-utils.c:312
msgid "Arch can't be empty"
msgstr "Architektura nie może być pusta"

#: common/flatpak-ref-utils.c:323
#, c-format
msgid "Arch can't contain %c"
msgstr "Architektura nie może zawierać %c"

#: common/flatpak-ref-utils.c:385
msgid "Branch can't be empty"
msgstr "Gałąź nie może być pusta"

#: common/flatpak-ref-utils.c:395
#, c-format
msgid "Branch can't start with %c"
msgstr "Gałąź nie może zaczynać się od %c"

#: common/flatpak-ref-utils.c:405
#, c-format
msgid "Branch can't contain %c"
msgstr "Gałąź nie może zawierać %c"

#: common/flatpak-ref-utils.c:615 common/flatpak-ref-utils.c:865
msgid "Ref too long"
msgstr "Odniesienie jest za długie"

#: common/flatpak-ref-utils.c:627
msgid "Invalid remote name"
msgstr "Nieprawidłowa nazwa repozytorium"

#: common/flatpak-ref-utils.c:641
#, c-format
msgid "%s is not application or runtime"
msgstr "%s nie jest programem ani środowiskiem wykonawczym"

#: common/flatpak-ref-utils.c:650 common/flatpak-ref-utils.c:667
#: common/flatpak-ref-utils.c:683
#, c-format
msgid "Wrong number of components in %s"
msgstr "Błędna liczba składników w %s"

#: common/flatpak-ref-utils.c:656
#, c-format
msgid "Invalid name %.*s: %s"
msgstr "Nieprawidłowa nazwa %.*s: %s"

#: common/flatpak-ref-utils.c:673
#, c-format
msgid "Invalid arch: %.*s: %s"
msgstr "Nieprawidłowa architektura: %.*s: %s"

#: common/flatpak-ref-utils.c:816
#, c-format
msgid "Invalid name %s: %s"
msgstr "Nieprawidłowa nazwa %s: %s"

#: common/flatpak-ref-utils.c:834
#, c-format
msgid "Invalid arch: %s: %s"
msgstr "Nieprawidłowa architektura: %s: %s"

#: common/flatpak-ref-utils.c:853
#, c-format
msgid "Invalid branch: %s: %s"
msgstr "Nieprawidłowa gałąź: %s: %s"

#: common/flatpak-ref-utils.c:962 common/flatpak-ref-utils.c:970
#: common/flatpak-ref-utils.c:978
#, c-format
msgid "Wrong number of components in partial ref %s"
msgstr "Błędna liczba składników w częściowym odniesieniu %s"

#: common/flatpak-ref-utils.c:1298
msgid " development platform"
msgstr " platforma programistyczna"

#: common/flatpak-ref-utils.c:1300
msgid " platform"
msgstr " platforma"

#: common/flatpak-ref-utils.c:1302
msgid " application base"
msgstr " podstawa programu"

#: common/flatpak-ref-utils.c:1305
msgid " debug symbols"
msgstr " symbole debugowania"

#: common/flatpak-ref-utils.c:1307
msgid " sourcecode"
msgstr " kod źródłowy"

#: common/flatpak-ref-utils.c:1309
msgid " translations"
msgstr " tłumaczenia"

#: common/flatpak-ref-utils.c:1311
msgid " docs"
msgstr " dokumentacja"

#: common/flatpak-ref-utils.c:1578
#, c-format
msgid "Invalid id %s: %s"
msgstr "Nieprawidłowy identyfikator %s: %s"

#: common/flatpak-remote.c:1216
#, c-format
msgid "Bad remote name: %s"
msgstr "Błędna nazwa repozytorium: %s"

#: common/flatpak-remote.c:1220
#, fuzzy
msgid "No URL specified"
msgstr "Nie podano adresu URL"

#: common/flatpak-remote.c:1266
msgid "GPG verification must be enabled when a collection ID is set"
msgstr ""
"Sprawdzanie poprawności GPG musi być włączone, kiedy ustawiony jest "
"identyfikator kolekcji"

#: common/flatpak-repo-utils.c:344
#, c-format
msgid "No extra data sources"
msgstr "Brak źródeł dodatkowych danych"

#: common/flatpak-repo-utils.c:2817
#, c-format
msgid "Invalid %s: Missing group ‘%s’"
msgstr "Nieprawidłowe %s: brak grupy „%s”"

#: common/flatpak-repo-utils.c:2826
#, c-format
msgid "Invalid %s: Missing key ‘%s’"
msgstr "Nieprawidłowe %s: brak klucza „%s”"

#: common/flatpak-repo-utils.c:2876
msgid "Invalid gpg key"
msgstr "Nieprawidłowy klucz GPG"

#: common/flatpak-repo-utils.c:3217
#, c-format
msgid "Error copying 64x64 icon for component %s: %s\n"
msgstr "Błąd podczas kopiowania ikony 64×64 dla składnika %s: %s\n"

#: common/flatpak-repo-utils.c:3223
#, c-format
msgid "Error copying 128x128 icon for component %s: %s\n"
msgstr "Błąd podczas kopiowania ikony 128×128 dla składnika %s: %s\n"

#: common/flatpak-repo-utils.c:3362
#, c-format
msgid "%s is end-of-life, ignoring for appstream"
msgstr "%s jest niewspierane, ignorowanie dla AppStream"

#: common/flatpak-repo-utils.c:3397
#, c-format
msgid "No appstream data for %s: %s\n"
msgstr "Brak danych AppStream dla %s: %s\n"

#: common/flatpak-repo-utils.c:3744
msgid "Invalid bundle, no ref in metadata"
msgstr "Nieprawidłowy pakiet, brak odniesienia w metadanych"

#: common/flatpak-repo-utils.c:3846
#, c-format
msgid "Collection ‘%s’ of bundle doesn’t match collection ‘%s’ of remote"
msgstr "Kolekcja „%s” pakietu nie zgadza się z kolekcją „%s” repozytorium"

#: common/flatpak-repo-utils.c:3923
msgid "Metadata in header and app are inconsistent"
msgstr "Metadane w nagłówku i programie są niespójne"

#: common/flatpak-run.c:951
msgid "No systemd user session available, cgroups not available"
msgstr "Brak dostępnej sesji użytkownika systemd, cgroups nie są dostępne"

#: common/flatpak-run.c:1496
msgid "Unable to allocate instance id"
msgstr "Nie można przydzielić identyfikatora wystąpienia"

#: common/flatpak-run.c:1632 common/flatpak-run.c:1641
#, c-format
msgid "Failed to open flatpak-info file: %s"
msgstr "Otwarcie pliku „flatpak-info” się nie powiodło: %s"

#: common/flatpak-run.c:1668
#, c-format
msgid "Failed to open bwrapinfo.json file: %s"
msgstr "Otwarcie pliku „bwrapinfo.json” się nie powiodło: %s"

#: common/flatpak-run.c:1689
#, c-format
msgid "Failed to write to instance id fd: %s"
msgstr "Zapisanie do FD identyfikatora wystąpienia się nie powiodło: %s"

#: common/flatpak-run.c:2096
msgid "Initialize seccomp failed"
msgstr "Inicjacja seccomp się nie powiodła"

#: common/flatpak-run.c:2135
#, c-format
msgid "Failed to add architecture to seccomp filter: %s"
msgstr "Dodanie architektury do filtru seccomp się nie powiodło: %s"

#: common/flatpak-run.c:2143
#, c-format
msgid "Failed to add multiarch architecture to seccomp filter: %s"
msgstr ""
"Dodanie wieloarchitekturowej architektury do filtru seccomp się nie "
"powiodło: %s"

#: common/flatpak-run.c:2175 common/flatpak-run.c:2192
#: common/flatpak-run.c:2214
#, c-format
msgid "Failed to block syscall %d: %s"
msgstr "Zablokowanie wywołania systemowego %d się nie powiodło: %s"

#: common/flatpak-run.c:2247
#, c-format
msgid "Failed to export bpf: %s"
msgstr "Wyeksportowanie bpf się nie powiodło: %s"

#: common/flatpak-run.c:2587
#, c-format
msgid "Failed to open ‘%s’"
msgstr "Otwarcie „%s” się nie powiodło"

#: common/flatpak-run.c:2597
#, c-format
msgid ""
"Directory forwarding needs version 4 of the document portal (have version %d)"
msgstr ""
"Przekazywanie katalogów wymaga 4. wersji portalu dokumentów (obecna wersja "
"to %d)"

#: common/flatpak-run.c:2915
#, c-format
msgid "ldconfig failed, exit status %d"
msgstr "ldconfig się nie powiodło, stan wyjścia %d"

#: common/flatpak-run.c:2922
msgid "Can't open generated ld.so.cache"
msgstr "Nie można otworzyć utworzonego ld.so.cache"

#. Translators: The placeholder is for an app ref.
#: common/flatpak-run.c:3045
#, c-format
msgid "Running %s is not allowed by the policy set by your administrator"
msgstr ""
"Uruchomienie programu %s jest zabronione przez zasady ustawione przez "
"administratora"

#: common/flatpak-run.c:3202
msgid ""
"\"flatpak run\" is not intended to be run as `sudo flatpak run`. Use `sudo "
"-i` or `su -l` instead and invoke \"flatpak run\" from inside the new shell."
msgstr ""
"„flatpak run” nie powinno być wykonywane jako „sudo flatpak run”. Należy "
"użyć „sudo -i” lub „su -l” zamiast tego i wywołać „flatpak run” z nowej "
"powłoki."

#: common/flatpak-run.c:3413
#, c-format
msgid "Failed to migrate from %s: %s"
msgstr "Migracja z %s się nie powiodła: %s"

#: common/flatpak-run.c:3434
#, c-format
msgid "Failed to migrate old app data directory %s to new name %s: %s"
msgstr ""
"Migracja poprzedniego katalogu danych programu %s do nowej nazwy %s się nie "
"powiodła: %s"

#: common/flatpak-run.c:3443
#, c-format
msgid "Failed to create symlink while migrating %s: %s"
msgstr ""
"Utworzenie dowiązania symbolicznego podczas migracji %s się nie powiodło: %s"

#: common/flatpak-run-dbus.c:46
msgid "Failed to open app info file"
msgstr "Otwarcie pliku informacji o programie się nie powiodło"

#: common/flatpak-run-dbus.c:149
msgid "Unable to create sync pipe"
msgstr "Utworzenie potoku synchronizacji się nie powiodło"

#: common/flatpak-run-dbus.c:185
msgid "Failed to sync with dbus proxy"
msgstr "Synchronizacja z pośrednikiem D-Bus się nie powiodła"

#: common/flatpak-transaction.c:2275
#, c-format
msgid "Warning: Problem looking for related refs: %s"
msgstr "Ostrzeżenie: problem podczas wyszukiwania powiązanych odniesień: %s"

#: common/flatpak-transaction.c:2493
#, c-format
msgid "The application %s requires the runtime %s which was not found"
msgstr "Program %s wymaga środowiska wykonawczego %s, którego nie odnaleziono"

#: common/flatpak-transaction.c:2509
#, c-format
msgid "The application %s requires the runtime %s which is not installed"
msgstr ""
"Program %s wymaga środowiska wykonawczego %s, które nie jest zainstalowane"

#: common/flatpak-transaction.c:2641
#, c-format
msgid "Can't uninstall %s which is needed by %s"
msgstr "Nie można odinstalować %s, które jest wymagane przez %s"

#: common/flatpak-transaction.c:2740
#, c-format
msgid "Remote %s disabled, ignoring %s update"
msgstr "Repozytorium %s jest wyłączone, ignorowanie aktualizacji %s"

#: common/flatpak-transaction.c:2773
#, c-format
msgid "%s is already installed"
msgstr "Już zainstalowano %s"

#: common/flatpak-transaction.c:2776
#, c-format
msgid "%s is already installed from remote %s"
msgstr "%s jest już zainstalowane z repozytorium %s"

#: common/flatpak-transaction.c:3120
#, c-format
msgid "Invalid .flatpakref: %s"
msgstr "Nieprawidłowy plik .flatpakref: %s"

#: common/flatpak-transaction.c:3161
msgid "Warning: Could not mark already installed apps as preinstalled"
msgstr ""
"Ostrzeżenie: nie można oznaczyć już zainstalowanych programów jako "
"zainstalowane standardowo"

#: common/flatpak-transaction.c:3382
#, c-format
msgid "Error updating remote metadata for '%s': %s"
msgstr "Błąd podczas aktualizowania metadanych repozytorium dla „%s”: %s"

#: common/flatpak-transaction.c:3885
#, c-format
msgid ""
"Warning: Treating remote fetch error as non-fatal since %s is already "
"installed: %s"
msgstr ""
"Ostrzeżenie: traktowanie błędu pobierania repozytorium jako niekrytycznego, "
"ponieważ %s jest już zainstalowane: %s"

#: common/flatpak-transaction.c:4209
#, c-format
msgid "No authenticator installed for remote '%s'"
msgstr "Nie zainstalowano programu uwierzytelniającego dla repozytorium „%s”"

#: common/flatpak-transaction.c:4313 common/flatpak-transaction.c:4320
#, c-format
msgid "Failed to get tokens for ref: %s"
msgstr "Uzyskanie tokenów dla odniesienia się nie powiodło: %s"

#: common/flatpak-transaction.c:4315 common/flatpak-transaction.c:4322
msgid "Failed to get tokens for ref"
msgstr "Uzyskanie tokenów dla odniesienia się nie powiodło"

#: common/flatpak-transaction.c:4580
#, c-format
msgid "Ref %s from %s matches more than one transaction operation"
msgstr "Odniesienie %s z %s pasuje do więcej niż jednej transakcji"

#: common/flatpak-transaction.c:4581 common/flatpak-transaction.c:4591
msgid "any remote"
msgstr "dowolnego repozytorium"

#: common/flatpak-transaction.c:4590
#, c-format
msgid "No transaction operation found for ref %s from %s"
msgstr "Nie odnaleziono transakcji dla odniesienia %s z %s"

#: common/flatpak-transaction.c:4713
#, c-format
msgid "Flatpakrepo URL %s not file, HTTP or HTTPS"
msgstr ""
"Adres URL repozytorium Flatpak %s nie jest adresem „file”, HTTP ani HTTPS"

#: common/flatpak-transaction.c:4719
#, c-format
msgid "Can't load dependent file %s: "
msgstr "Nie można wczytać zależnego pliku %s: "

#: common/flatpak-transaction.c:4727
#, c-format
msgid "Invalid .flatpakrepo: %s"
msgstr "Nieprawidłowy plik .flatpakrepo: %s"

#: common/flatpak-transaction.c:5454
msgid "Transaction already executed"
msgstr "Transakcja została już wykonana"

#: common/flatpak-transaction.c:5469
msgid ""
"Refusing to operate on a user installation as root! This can lead to "
"incorrect file ownership and permission errors."
msgstr ""
"Odmowa działania na instalacji użytkownika jako root. Może to spowodować "
"niepoprawnych właścicieli plików i błędy uprawnień."

#: common/flatpak-transaction.c:5567 common/flatpak-transaction.c:5580
msgid "Aborted by user"
msgstr "Przerwane przez użytkownika"

#: common/flatpak-transaction.c:5605
#, c-format
msgid "Skipping %s due to previous error"
msgstr "Pomijanie %s z powodu poprzedniego błędu"

#: common/flatpak-transaction.c:5659
#, c-format
msgid "Aborted due to failure (%s)"
msgstr "Przerwano z powodu niepowodzenia (%s)"

#: common/flatpak-uri.c:118
#, no-c-format
msgid "Invalid %-encoding in URI"
msgstr "Nieprawidłowe „%-encoding” w adresie URI"

#: common/flatpak-uri.c:135
msgid "Illegal character in URI"
msgstr "Niedozwolony znak w adresie URI"

#: common/flatpak-uri.c:169
msgid "Non-UTF-8 characters in URI"
msgstr "Znaki niebędące UTF-8 w adresie URI"

#: common/flatpak-uri.c:275
#, c-format
msgid "Invalid IPv6 address ‘%.*s’ in URI"
msgstr "Nieprawidłowy adres IPv6 „%.*s” w adresie URI"

#: common/flatpak-uri.c:330
#, c-format
msgid "Illegal encoded IP address ‘%.*s’ in URI"
msgstr "Niedozwolony zakodowany adres IP „%.*s” w adresie URI"

#: common/flatpak-uri.c:342
#, c-format
msgid "Illegal internationalized hostname ‘%.*s’ in URI"
msgstr "Niedozwolona umiędzynarodowiona nazwa komputera „%.*s” w adresie URI"

#: common/flatpak-uri.c:374 common/flatpak-uri.c:386
#, c-format
msgid "Could not parse port ‘%.*s’ in URI"
msgstr "Nie można przetworzyć portu „%.*s” w adresie URI"

#: common/flatpak-uri.c:393
#, c-format
msgid "Port ‘%.*s’ in URI is out of range"
msgstr "Port „%.*s” w adresie URI jest poza zakresem"

#: common/flatpak-uri.c:910
msgid "URI is not absolute, and no base URI was provided"
msgstr "Adres URI nie jest bezwzględny i nie podano podstawy adresu URI"

#: common/flatpak-usb.c:83
#, c-format
msgid "USB device query 'all' must not have data"
msgstr "Zapytanie „all” urządzenia USB nie może mieć danych"

#: common/flatpak-usb.c:102
#, c-format
msgid "USB query rule 'cls' must be in the form CLASS:SUBCLASS or CLASS:*"
msgstr ""
"Reguła „cls” zapytania USB musi być w formie KLASA:PODKLASA lub KLASA:*"

#: common/flatpak-usb.c:111
#, c-format
msgid "Invalid USB class"
msgstr "Nieprawidłowa klasa USB"

#: common/flatpak-usb.c:125
#, c-format
msgid "Invalid USB subclass"
msgstr "Nieprawidłowa podklasa USB"

#: common/flatpak-usb.c:141 common/flatpak-usb.c:148
#, c-format
msgid "USB query rule 'dev' must have a valid 4-digit hexadecimal product id"
msgstr ""
"Reguła „dev” zapytania USB musi mieć prawidłowy czterocyfrowy szesnastkowy "
"identyfikator produktu"

#: common/flatpak-usb.c:164 common/flatpak-usb.c:171
#, c-format
msgid "USB query rule 'vnd' must have a valid 4-digit hexadecimal vendor id"
msgstr ""
"Reguła „vnd” zapytania USB musi mieć prawidłowy czterocyfrowy szesnastkowy "
"identyfikator producenta"

#: common/flatpak-usb.c:205
#, c-format
msgid "USB device queries must be in the form TYPE:DATA"
msgstr "Zapytania urządzeń USB muszą być w formie TYP:DANE"

#: common/flatpak-usb.c:225
#, c-format
msgid "Unknown USB query rule %s"
msgstr "Nieznana reguła zapytania USB %s"

#: common/flatpak-usb.c:248
#, c-format
msgid "Empty USB query"
msgstr "Puste zapytanie USB"

#: common/flatpak-usb.c:274
#, c-format
msgid "Multiple USB query rules of the same type is not supported"
msgstr "Wiele reguł zapytań USB tego samego typu nie jest obsługiwanych"

#: common/flatpak-usb.c:283
#, c-format
msgid "'all' must not contain extra query rules"
msgstr "„all” nie może zawierać dodatkowych reguł zapytań"

#: common/flatpak-usb.c:291
#, c-format
msgid "USB queries with 'dev' must also specify vendors"
msgstr "Zapytania USB z „dev” muszą także określać producentów"

#: common/flatpak-utils.c:712
msgid "Glob can't match apps"
msgstr "Wzorzec nie pasuje do programów"

#: common/flatpak-utils.c:737
msgid "Empty glob"
msgstr "Pusty wzorzec"

#: common/flatpak-utils.c:756
msgid "Too many segments in glob"
msgstr "Za dużo segmentów we wzorcu"

#: common/flatpak-utils.c:777
#, c-format
msgid "Invalid glob character '%c'"
msgstr "Nieprawidłowy znak wzorca „%c”"

#: common/flatpak-utils.c:831
#, c-format
msgid "Missing glob on line %d"
msgstr "Brak wzorca w %d. wierszu"

#: common/flatpak-utils.c:835
#, c-format
msgid "Trailing text on line %d"
msgstr "Kończący tekst w %d. wierszu"

#: common/flatpak-utils.c:839
#, c-format
msgid "on line %d"
msgstr "w %d. wierszu"

#: common/flatpak-utils.c:861
#, c-format
msgid "Unexpected word '%s' on line %d"
msgstr "Nieoczekiwany wyraz „%s” w %d. wierszu"

#: common/flatpak-utils.c:2118
#, c-format
msgid "Invalid require-flatpak argument %s"
msgstr "Nieprawidłowy parametr require-flatpak %s"

#: common/flatpak-utils.c:2128 common/flatpak-utils.c:2147
#, c-format
msgid "%s needs a later flatpak version (%s)"
msgstr "%s wymaga nowszej wersji Flatpak (%s)"

#: oci-authenticator/flatpak-oci-authenticator.c:291
msgid "Not a oci remote, missing summary.xa.oci-repository"
msgstr "Nie jest repozytorium OCI, nie ma summary.xa.oci-repository"

#: oci-authenticator/flatpak-oci-authenticator.c:477
msgid "Not a OCI remote"
msgstr "Nie jest repozytorium OCI"

#: oci-authenticator/flatpak-oci-authenticator.c:488
msgid "Invalid token"
msgstr "Nieprawidłowy token"

#: portal/flatpak-portal.c:2292
#, c-format
msgid "No portal support found"
msgstr "Nie odnaleziono obsługi portali"

#: portal/flatpak-portal.c:2298
msgid "Deny"
msgstr "Odmów"

#: portal/flatpak-portal.c:2300
msgid "Update"
msgstr "Zaktualizuj"

#: portal/flatpak-portal.c:2305
#, c-format
msgid "Update %s?"
msgstr "Zaktualizować %s?"

#: portal/flatpak-portal.c:2317
msgid "The application wants to update itself."
msgstr "Program chce się zaktualizować."

#: portal/flatpak-portal.c:2318
msgid "Update access can be changed any time from the privacy settings."
msgstr ""
"Dostęp do aktualizacji można zmienić w każdej chwili w ustawieniach "
"prywatności."

#: portal/flatpak-portal.c:2343
#, c-format
msgid "Application update not allowed"
msgstr "Aktualizacja programu jest zabroniona"

#: portal/flatpak-portal.c:2501
#, c-format
msgid "Self update not supported, new version requires new permissions"
msgstr ""
"Samodzielna aktualizacja nie jest obsługiwana, nowa wersja wymaga nowych "
"uprawnień"

#: portal/flatpak-portal.c:2684 portal/flatpak-portal.c:2702
#, c-format
msgid "Update ended unexpectedly"
msgstr "Aktualizacja została nieoczekiwanie zakończona"

#. SECURITY:
#. - Normal users need admin authentication to install software
#. system-wide.
#. - Note that we install polkit rules that allow local users
#. in the wheel group to install without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:23
msgid "Install signed application"
msgstr "Instalacja podpisanego programu"

#: system-helper/org.freedesktop.Flatpak.policy.in:24
#: system-helper/org.freedesktop.Flatpak.policy.in:42
msgid "Authentication is required to install software"
msgstr "Wymagane jest uwierzytelnienie, aby zainstalować oprogramowanie"

#. SECURITY:
#. - Normal users need admin authentication to install software
#. system-wide.
#. - Note that we install polkit rules that allow local users
#. in the wheel group to install without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:41
msgid "Install signed runtime"
msgstr "Instalacja podpisanego środowiska wykonawczego"

#. SECURITY:
#. - Normal users do not require admin authentication to update an
#. app as the commit will be signed, and the action is required
#. to update the system when unattended.
#. - Changing this to anything other than 'yes' will break unattended
#. updates.
#: system-helper/org.freedesktop.Flatpak.policy.in:60
msgid "Update signed application"
msgstr "Aktualizacja podpisanego programu"

#: system-helper/org.freedesktop.Flatpak.policy.in:61
#: system-helper/org.freedesktop.Flatpak.policy.in:80
msgid "Authentication is required to update software"
msgstr "Wymagane jest uwierzytelnienie, aby zaktualizować oprogramowanie"

#. SECURITY:
#. - Normal users do not require admin authentication to update a
#. runtime as the commit will be signed, and the action is required
#. to update the system when unattended.
#. - Changing this to anything other than 'yes' will break unattended
#. updates.
#: system-helper/org.freedesktop.Flatpak.policy.in:79
msgid "Update signed runtime"
msgstr "Aktualizacja podpisanego środowiska wykonawczego"

#. SECURITY:
#. - Normal users do not need authentication to update metadata
#. from signed repositories.
#: system-helper/org.freedesktop.Flatpak.policy.in:94
msgid "Update remote metadata"
msgstr "Aktualizacja metadanych repozytorium"

#: system-helper/org.freedesktop.Flatpak.policy.in:95
msgid "Authentication is required to update remote info"
msgstr ""
"Wymagane jest uwierzytelnienie, aby zaktualizować informacje o repozytorium"

#. SECURITY:
#. - Normal users do not need authentication to modify the
#. OSTree repository
#. - Note that we install polkit rules that allow local users
#. in the wheel group to modify repos without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:111
msgid "Update system repository"
msgstr "Aktualizacja repozytorium systemu"

#: system-helper/org.freedesktop.Flatpak.policy.in:112
msgid "Authentication is required to modify a system repository"
msgstr "Wymagane jest uwierzytelnienie, aby zmodyfikować repozytorium systemu"

#. SECURITY:
#. - Normal users need admin authentication to install software
#. system-wide.
#: system-helper/org.freedesktop.Flatpak.policy.in:126
msgid "Install bundle"
msgstr "Instalacja pakietu"

#: system-helper/org.freedesktop.Flatpak.policy.in:127
msgid "Authentication is required to install software from $(path)"
msgstr ""
"Wymagane jest uwierzytelnienie, aby zainstalować oprogramowanie z $(path)"

#. SECURITY:
#. - Normal users need admin authentication to uninstall software
#. system-wide.
#. - Note that we install polkit rules that allow local users
#. in the wheel group to uninstall without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:144
msgid "Uninstall runtime"
msgstr "Odinstalowanie środowiska wykonawczego"

#: system-helper/org.freedesktop.Flatpak.policy.in:145
msgid "Authentication is required to uninstall software"
msgstr "Wymagane jest uwierzytelnienie, aby odinstalować oprogramowanie"

#. SECURITY:
#. - Normal users need admin authentication to uninstall software
#. system-wide.
#. - Note that we install polkit rules that allow local users
#. in the wheel group to uninstall without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:161
msgid "Uninstall app"
msgstr "Odinstalowanie programu"

#: system-helper/org.freedesktop.Flatpak.policy.in:162
msgid "Authentication is required to uninstall $(ref)"
msgstr "Wymagane jest uwierzytelnienie, aby odinstalować $(ref)"

#. SECURITY:
#. - Normal users need admin authentication to configure system-wide
#. software repositories.
#: system-helper/org.freedesktop.Flatpak.policy.in:177
msgid "Configure Remote"
msgstr "Konfiguracja repozytorium"

#: system-helper/org.freedesktop.Flatpak.policy.in:178
msgid "Authentication is required to configure software repositories"
msgstr ""
"Wymagane jest uwierzytelnienie, aby skonfigurować repozytoria oprogramowania"

#. SECURITY:
#. - Normal users need admin authentication to configure the system-wide
#. Flatpak installation.
#: system-helper/org.freedesktop.Flatpak.policy.in:192
msgid "Configure"
msgstr "Konfiguracja"

#: system-helper/org.freedesktop.Flatpak.policy.in:193
msgid "Authentication is required to configure software installation"
msgstr ""
"Wymagane jest uwierzytelnienie, aby skonfigurować instalację oprogramowania"

#. SECURITY:
#. - Normal users do not require admin authentication to update
#. appstream data as it will be signed, and the action is required
#. to update the system when unattended.
#. - Changing this to anything other than 'yes' will break unattended
#. updates.
#: system-helper/org.freedesktop.Flatpak.policy.in:210
msgid "Update appstream"
msgstr "Aktualizacja danych AppStream"

#: system-helper/org.freedesktop.Flatpak.policy.in:211
msgid "Authentication is required to update information about software"
msgstr ""
"Wymagane jest uwierzytelnienie, aby zaktualizować informacje o oprogramowaniu"

#. SECURITY:
#. - Normal users do not require admin authentication to update
#. metadata as it will be signed, and the action is required
#. to update the system when unattended.
#. - Changing this to anything other than 'yes' will break unattended
#. updates.
#: system-helper/org.freedesktop.Flatpak.policy.in:228
msgid "Update metadata"
msgstr "Aktualizacja metadanych"

#: system-helper/org.freedesktop.Flatpak.policy.in:229
msgid "Authentication is required to update metadata"
msgstr "Wymagane jest uwierzytelnienie, aby zaktualizować metadane"

#. SECURITY:
#. - Authorisation to actually install software is controlled by
#. org.freedesktop.Flatpak.app-install.
#. - This action is checked after app-install, as it can only be done
#. once the app’s data (including its content rating) has been
#. downloaded.
#. - This action is checked to see if the installation should be allowed
#. based on whether the app being installed has content which doesn’t
#. comply with the user’s parental controls policy (the content is
#. ‘too extreme’).
#. - It is checked only if an app has too extreme content for the user
#. who is trying to install it (in which case, the app is ‘unsafe’).
#. - Typically, normal users will need admin permission to install apps
#. with extreme content; admins will be able to install it without
#. additional checks.
#. - In order to configure the policy so that admins can install safe and
#. unsafe software anywhere without authorisation, and non-admins can
#. install safe software in their user or system dirs without
#. authorisation, but need authorisation to install unsafe software
#. anywhere:
#. * Unconditionally return `yes` from `app-install`.
#. * Return `auth_admin` from `override-parental-controls` for users
#. not in `@privileged_group@`, and `yes` for users in it.
#. * Set the malcontent `is-{user,system}-installation-allowed`
#. properties of all non-admins’ parental controls policies to true.
#. - In order to configure the policy so that admins can install safe and
#. unsafe software anywhere without authorisation, and non-admins can
#. install safe software in their user dir without authorisation, but
#. need authorisation to install safe software in the system dir or to
#. install unsafe software anywhere:
#. * Unconditionally return `yes` from `app-install`.
#. * Return `auth_admin` from `override-parental-controls` for users
#. not in `@privileged_group@`, and `yes` for users in it.
#. * Set the malcontent `is-user-installation-allowed` property of all
#. non-admins’ parental controls policies to true.
#. * Set the malcontent `is-system-installation-allowed` property of
#. all non-admins’ parental controls policies to false.
#. - In order to configure the policy so that all users (including
#. admins) can install safe software anywhere without authorisation,
#. but need authorisation to install unsafe software anywhere (i.e.
#. applying parental controls to admins too):
#. * Unconditionally return `yes` from `app-install`.
#. * Unconditionally return `auth_admin` from `override-parental-controls`.
#. * Set the malcontent `is-user-installation-allowed` property of all
#. users’ parental controls policies to true.
#. * Set the malcontent `is-system-installation-allowed` property of
#. all users’ parental controls policies to true.
#: system-helper/org.freedesktop.Flatpak.policy.in:287
msgid "Override parental controls for installs"
msgstr "Zastąpienie kontroli rodzicielskiej dla instalacji"

#: system-helper/org.freedesktop.Flatpak.policy.in:288
msgid ""
"Authentication is required to install software which is restricted by your "
"parental controls policy"
msgstr ""
"Wymagane jest uwierzytelnienie, aby zainstalować oprogramowanie ograniczane "
"przez zasady kontroli rodzicielskiej"

#. SECURITY:
#. - This is like org.freedesktop.Flatpak.override-parental-controls, but
#. it’s queried for app updates, whereas the former is queried for app
#. installs.
#. - As with the above action, this one is only queried if
#. org.freedesktop.Flatpak.app-update has allowed the app update, and
#. only if the app being updated has too extreme content for the user
#. who is trying to update it.
#. - The default policy for this is to *allow* updates to ‘too extreme’
#. apps by default, on the basis that having an out-of-date (i.e.
#. insecure or unsupported) app is a worse outcome than automatically
#. installing an update which has radically different content from the
#. version of the app which the parent originally vetted and installed.
#: system-helper/org.freedesktop.Flatpak.policy.in:313
msgid "Override parental controls for updates"
msgstr "Zastąpienie kontroli rodzicielskiej dla aktualizacji"

#: system-helper/org.freedesktop.Flatpak.policy.in:314
msgid ""
"Authentication is required to update software which is restricted by your "
"parental controls policy"
msgstr ""
"Wymagane jest uwierzytelnienie, aby zaktualizować oprogramowanie ograniczane "
"przez zasady kontroli rodzicielskiej"

#~ msgid "Installed:"
#~ msgstr "Zainstalowano:"

#~ msgid "Download:"
#~ msgstr "Pobieranie:"

#, c-format
#~ msgid "No gpg key found with ID %s (homedir: %s)"
#~ msgstr ""
#~ "Nie odnaleziono klucza GPG z identyfikatorem %s (katalog domowy: %s)"

#, c-format
#~ msgid "Unable to lookup key ID %s: %d"
#~ msgstr "Nie można wyszukać identyfikatora klucza %s: %d"

#, c-format
#~ msgid "Error signing commit: %d"
#~ msgstr "Błąd podczas podpisywania zatwierdzenia: %d"

===== ./po/zh_TW.po =====
# Chinese (Taiwan) translation for flatpak.
# Copyright (C) 2018 flatpak's COPYRIGHT HOLDER
# This file is distributed under the same license as the flatpak package.
#
# Jeff Huang <s8321414@gmail.com>, 2018.
# Cheng-Chia Tseng <pswo10680@gmail.com>, 2018.
# Yi-Jyun Pan <pan93412@gmail.com>, 2020.
msgid ""
msgstr ""
"Project-Id-Version: flatpak master\n"
"Report-Msgid-Bugs-To: https://github.com/flatpak/flatpak/issues\n"
"POT-Creation-Date: 2026-05-27 16:39+0200\n"
"PO-Revision-Date: 2020-05-17 17:53+0000\n"
"Last-Translator: Yi-Jyun Pan <pan93412@gmail.com>\n"
"Language-Team: Chinese (Traditional) <zh-l10n@lists.linux.org.tw>\n"
"Language: zh_TW\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
"X-Generator: Weblate 4.0.4\n"

#: app/flatpak-builtins-build-bundle.c:59
msgid "Export runtime instead of app"
msgstr "匯出執行時期環境而非程式"

#: app/flatpak-builtins-build-bundle.c:60
msgid "Arch to bundle for"
msgstr "套組的架構"

#: app/flatpak-builtins-build-bundle.c:60
#: app/flatpak-builtins-build-export.c:62 app/flatpak-builtins-build-init.c:53
#: app/flatpak-builtins-build-sign.c:42 app/flatpak-builtins-create-usb.c:46
#: app/flatpak-builtins-info.c:55 app/flatpak-builtins-install.c:67
#: app/flatpak-builtins-list.c:50 app/flatpak-builtins-make-current.c:38
#: app/flatpak-builtins-remote-info.c:54 app/flatpak-builtins-remote-ls.c:56
#: app/flatpak-builtins-run.c:158 app/flatpak-builtins-search.c:37
#: app/flatpak-builtins-uninstall.c:54 app/flatpak-builtins-update.c:56
msgid "ARCH"
msgstr "ARCH"

#: app/flatpak-builtins-build-bundle.c:61
#, fuzzy
msgid "URL for repo"
msgstr "軟體庫的 URL"

#: app/flatpak-builtins-build-bundle.c:61
#: app/flatpak-builtins-build-bundle.c:62
#: app/flatpak-builtins-build-update-repo.c:68
#: app/flatpak-builtins-build-update-repo.c:72
#: app/flatpak-builtins-build-update-repo.c:73
#: app/flatpak-builtins-history.c:69 app/flatpak-builtins-remote-add.c:80
#: app/flatpak-builtins-remote-add.c:81 app/flatpak-builtins-remote-add.c:85
#: app/flatpak-builtins-remote-list.c:53
#: app/flatpak-builtins-remote-modify.c:70
#: app/flatpak-builtins-remote-modify.c:85
#: app/flatpak-builtins-remote-modify.c:86
#: app/flatpak-builtins-remote-modify.c:90
msgid "URL"
msgstr "URL"

#: app/flatpak-builtins-build-bundle.c:62
#, fuzzy
msgid "URL for runtime flatpakrepo file"
msgstr "執行時期環境 flatpakrepo 檔的 URL"

#: app/flatpak-builtins-build-bundle.c:63
msgid "Add GPG key from FILE (- for stdin)"
msgstr "取用 FILE 作為 GPG 金鑰加入（- 代表 stdin）"

#: app/flatpak-builtins-build-bundle.c:63 app/flatpak-builtins-build.c:54
#: app/flatpak-builtins-build-export.c:67
#: app/flatpak-builtins-build-update-repo.c:83
#: app/flatpak-builtins-install.c:81 app/flatpak-builtins-remote-add.c:84
#: app/flatpak-builtins-remote-add.c:86 app/flatpak-builtins-remote-modify.c:89
#: app/flatpak-builtins-remote-modify.c:92
msgid "FILE"
msgstr "FILE"

#: app/flatpak-builtins-build-bundle.c:64
msgid "GPG Key ID to sign the OCI image with"
msgstr "用以簽署 OCI 映像檔的 GPG 金鑰 ID"

#: app/flatpak-builtins-build-bundle.c:64
#: app/flatpak-builtins-build-commit-from.c:68
#: app/flatpak-builtins-build-export.c:68
#: app/flatpak-builtins-build-import-bundle.c:49
#: app/flatpak-builtins-build-sign.c:44
#: app/flatpak-builtins-build-update-repo.c:84
msgid "KEY-ID"
msgstr "KEY-ID"

#: app/flatpak-builtins-build-bundle.c:65
#: app/flatpak-builtins-build-commit-from.c:69
#: app/flatpak-builtins-build-export.c:71
#: app/flatpak-builtins-build-import-bundle.c:50
#: app/flatpak-builtins-build-sign.c:45
#: app/flatpak-builtins-build-update-repo.c:85
msgid "GPG Homedir to use when looking for keyrings"
msgstr "查找鑰匙圈時所要使用的 GPG 家目錄"

#: app/flatpak-builtins-build-bundle.c:65
#: app/flatpak-builtins-build-commit-from.c:69
#: app/flatpak-builtins-build-export.c:71
#: app/flatpak-builtins-build-import-bundle.c:50
#: app/flatpak-builtins-build-sign.c:45
#: app/flatpak-builtins-build-update-repo.c:85
msgid "HOMEDIR"
msgstr "HOMEDIR"

#: app/flatpak-builtins-build-bundle.c:66
msgid "OSTree commit to create a delta bundle from"
msgstr "建立增減檔套組用的 OSTree 提交"

#: app/flatpak-builtins-build-bundle.c:66 app/flatpak-builtins-remote-info.c:55
#: app/flatpak-builtins-update.c:57
msgid "COMMIT"
msgstr "COMMIT"

#: app/flatpak-builtins-build-bundle.c:67
msgid "Export oci image instead of flatpak bundle"
msgstr "匯出 OCI 映像檔而非 flatpak 套組"

#: app/flatpak-builtins-build-bundle.c:70
msgid "How to compress OCI image layers (default: gzip)"
msgstr ""

#: app/flatpak-builtins-build-bundle.c:634
msgid ""
"LOCATION FILENAME NAME [BRANCH] - Create a single file bundle from a local "
"repository"
msgstr "LOCATION FILENAME NAME [BRANCH] - 根據本機軟體庫建立一個單一檔案套組"

#: app/flatpak-builtins-build-bundle.c:641
msgid "LOCATION, FILENAME and NAME must be specified"
msgstr "必須指定 LOCATION、FILENAME、NAME"

#: app/flatpak-builtins-build-bundle.c:644
#: app/flatpak-builtins-build-export.c:844
#: app/flatpak-builtins-build-import-bundle.c:136
#: app/flatpak-builtins-build-init.c:217 app/flatpak-builtins-build-sign.c:76
#: app/flatpak-builtins-document-export.c:112
#: app/flatpak-builtins-document-info.c:75
#: app/flatpak-builtins-document-list.c:191
#: app/flatpak-builtins-document-unexport.c:70
#: app/flatpak-builtins-history.c:482 app/flatpak-builtins-info.c:130
#: app/flatpak-builtins-install.c:181 app/flatpak-builtins-install.c:234
#: app/flatpak-builtins-install.c:298 app/flatpak-builtins-list.c:419
#: app/flatpak-builtins-make-current.c:72 app/flatpak-builtins-override.c:73
#: app/flatpak-builtins-permission-list.c:162
#: app/flatpak-builtins-permission-remove.c:132
#: app/flatpak-builtins-remote-add.c:323
#: app/flatpak-builtins-remote-delete.c:68
#: app/flatpak-builtins-remote-list.c:241 app/flatpak-builtins-remote-ls.c:407
msgid "Too many arguments"
msgstr "引數過多"

#: app/flatpak-builtins-build-bundle.c:659
#: app/flatpak-builtins-build-commit-from.c:338
#: app/flatpak-builtins-build-commit-from.c:351
#: app/flatpak-builtins-build-import-bundle.c:145
#, c-format
msgid "'%s' is not a valid repository"
msgstr "「%s」不是有效的軟體庫"

#: app/flatpak-builtins-build-bundle.c:663
#, c-format
msgid "'%s' is not a valid repository: "
msgstr "「%s」不是有效的軟體庫："

#: app/flatpak-builtins-build-bundle.c:674 app/flatpak-builtins-build-sign.c:88
#: common/flatpak-dir.c:14293
#, c-format
msgid "'%s' is not a valid name: %s"
msgstr "「%s」不是有效的名稱：%s"

#: app/flatpak-builtins-build-bundle.c:677
#: app/flatpak-builtins-build-export.c:865 app/flatpak-builtins-build-sign.c:91
#: common/flatpak-dir.c:14299
#, c-format
msgid "'%s' is not a valid branch name: %s"
msgstr "「%s」不是有效的分支名稱：%s"

#: app/flatpak-builtins-build-bundle.c:691
#: app/flatpak-builtins-build-import-bundle.c:149
#: app/flatpak-builtins-build-init.c:281
#, c-format
msgid "'%s' is not a valid filename"
msgstr "「%s」不是有效的檔名"

#: app/flatpak-builtins-build-bundle.c:706
msgid "--oci-layer-compress value must be gzip or zstd"
msgstr ""

#: app/flatpak-builtins-build.c:49
msgid "Use Platform runtime rather than Sdk"
msgstr "偏好使用平臺的執行時期環境更勝 SDK"

#: app/flatpak-builtins-build.c:50
msgid "Make destination readonly"
msgstr "讓目的地位置變成唯讀狀態"

#: app/flatpak-builtins-build.c:51
msgid "Add bind mount"
msgstr "新增綁定掛載"

#: app/flatpak-builtins-build.c:51
msgid "DEST=SRC"
msgstr "DEST=SRC"

#: app/flatpak-builtins-build.c:52
msgid "Start build in this directory"
msgstr "在此目錄中開始組建"

#: app/flatpak-builtins-build.c:52 app/flatpak-builtins-build.c:53
#: app/flatpak-builtins-build-init.c:64 app/flatpak-builtins-run.c:160
msgid "DIR"
msgstr "DIR"

#: app/flatpak-builtins-build.c:53
msgid "Where to look for custom sdk dir (defaults to 'usr')"
msgstr "要在何處查找自訂的 SDK 目錄（預設為「usr」）"

#: app/flatpak-builtins-build.c:54 app/flatpak-builtins-build-export.c:67
msgid "Use alternative file for the metadata"
msgstr "為中介資料使用替代檔案"

#: app/flatpak-builtins-build.c:55 app/flatpak-builtins-run.c:177
msgid "Kill processes when the parent process dies"
msgstr "當上層行程消亡後截殺子代行程"

#: app/flatpak-builtins-build.c:56
msgid "Export application homedir directory to build"
msgstr "匯出要組建的應用程式家目錄"

#: app/flatpak-builtins-build.c:57 app/flatpak-builtins-run.c:165
msgid "Log session bus calls"
msgstr "記錄工作階段匯流排呼叫"

#: app/flatpak-builtins-build.c:58 app/flatpak-builtins-run.c:166
msgid "Log system bus calls"
msgstr "記錄系統匯流排呼叫"

#: app/flatpak-builtins-build.c:262
msgid "DIRECTORY [COMMAND [ARGUMENT…]] - Build in directory"
msgstr "DIRECTORY [COMMAND [ARGUMENT…]] - 在目錄中組建"

#: app/flatpak-builtins-build.c:285 app/flatpak-builtins-build-finish.c:656
msgid "DIRECTORY must be specified"
msgstr "必須指定 DIRECTORY"

#: app/flatpak-builtins-build.c:296 app/flatpak-builtins-build-export.c:887
#, c-format
msgid "Build directory %s not initialized, use flatpak build-init"
msgstr "組建目錄 %s 尚未初始化，請使用 flatpak build-init"

#: app/flatpak-builtins-build.c:315
msgid "metadata invalid, not application or runtime"
msgstr "中介資料無效，沒有應用程式或執行時期環境"

#: app/flatpak-builtins-build.c:446
#, c-format
msgid "No extension point matching %s in %s"
msgstr "%2$s 中沒有符合 %1$s 的擴充點"

#: app/flatpak-builtins-build.c:635
#, c-format
msgid "Missing '=' in bind mount option '%s'"
msgstr "綁定用掛載選項「%s」中遺失「=」"

#: app/flatpak-builtins-build.c:679 common/flatpak-run.c:3961
#, c-format
msgid "Unable to start app"
msgstr "無法啟動程式"

#: app/flatpak-builtins-build-commit-from.c:58
msgid "Source repo dir"
msgstr "來源軟體庫目錄"

#: app/flatpak-builtins-build-commit-from.c:58
msgid "SRC-REPO"
msgstr "SRC-REPO"

#: app/flatpak-builtins-build-commit-from.c:59
msgid "Source repo ref"
msgstr "來源軟體庫參照"

#: app/flatpak-builtins-build-commit-from.c:59
msgid "SRC-REF"
msgstr "SRC-REF"

#: app/flatpak-builtins-build-commit-from.c:64
#: app/flatpak-builtins-build-export.c:60
msgid "One line subject"
msgstr "一列式主旨"

#: app/flatpak-builtins-build-commit-from.c:64
#: app/flatpak-builtins-build-export.c:60
msgid "SUBJECT"
msgstr "SUBJECT"

#: app/flatpak-builtins-build-commit-from.c:65
#: app/flatpak-builtins-build-export.c:61
msgid "Full description"
msgstr "完整的描述說明"

#: app/flatpak-builtins-build-commit-from.c:65
#: app/flatpak-builtins-build-export.c:61
msgid "BODY"
msgstr "BODY"

#: app/flatpak-builtins-build-commit-from.c:66
#: app/flatpak-builtins-build-export.c:64
#: app/flatpak-builtins-build-import-bundle.c:51
msgid "Update the appstream branch"
msgstr "更新 appstream 分支"

#: app/flatpak-builtins-build-commit-from.c:67
#: app/flatpak-builtins-build-export.c:65
#: app/flatpak-builtins-build-import-bundle.c:52
#: app/flatpak-builtins-build-update-repo.c:87
msgid "Don't update the summary"
msgstr "不要更新摘要"

#: app/flatpak-builtins-build-commit-from.c:68
#: app/flatpak-builtins-build-export.c:68
#: app/flatpak-builtins-build-import-bundle.c:49
#: app/flatpak-builtins-build-sign.c:44
msgid "GPG Key ID to sign the commit with"
msgstr "用以簽署提交的 GPG 金鑰 ID"

#: app/flatpak-builtins-build-commit-from.c:70
#: app/flatpak-builtins-build-export.c:73
msgid "Mark build as end-of-life"
msgstr "將組建標為 end-of-life"

#: app/flatpak-builtins-build-commit-from.c:70
#: app/flatpak-builtins-build-export.c:73
msgid "REASON"
msgstr "REASON"

#: app/flatpak-builtins-build-commit-from.c:71
msgid ""
"Mark refs matching the OLDID prefix as end-of-life, to be replaced with the "
"given NEWID"
msgstr "將符合 OLDID 前綴的參照標為 end-of-life，會以提供的 NEWID 取代"

#: app/flatpak-builtins-build-commit-from.c:71
msgid "OLDID=NEWID"
msgstr "OLDID=NEWID"

#: app/flatpak-builtins-build-commit-from.c:72
#: app/flatpak-builtins-build-export.c:75
msgid "Set type of token needed to install this commit"
msgstr ""

#: app/flatpak-builtins-build-commit-from.c:72
#: app/flatpak-builtins-build-export.c:75
msgid "VAL"
msgstr "VAL"

#: app/flatpak-builtins-build-commit-from.c:73
msgid "Override the timestamp of the commit (NOW for current time)"
msgstr "凌駕提交的時間戳（NOW 則為目前時間）"

#: app/flatpak-builtins-build-commit-from.c:73
#: app/flatpak-builtins-build-export.c:76
msgid "TIMESTAMP"
msgstr "TIMESTAMP"

#: app/flatpak-builtins-build-commit-from.c:75
#: app/flatpak-builtins-build-export.c:80
#: app/flatpak-builtins-build-import-bundle.c:53
#: app/flatpak-builtins-build-update-repo.c:97
#, fuzzy
msgid "Don't generate a summary index"
msgstr "不要更新摘要"

#: app/flatpak-builtins-build-commit-from.c:278
msgid "DST-REPO [DST-REF…] - Make a new commit from existing commits"
msgstr "DST-REPO [DST-REF…] - 根據現有提交建立新提交"

#: app/flatpak-builtins-build-commit-from.c:285
msgid "DST-REPO must be specified"
msgstr "必須指定 DST-REPO"

#: app/flatpak-builtins-build-commit-from.c:293
msgid ""
"If --src-repo is not specified, exactly one destination ref must be specified"
msgstr "若未指定 --src-repo，必須確實指定一個目的地參照"

#: app/flatpak-builtins-build-commit-from.c:296
msgid ""
"If --src-ref is specified, exactly one destination ref must be specified"
msgstr "若已指定 --src-ref，則必須確實指定一個目的地參照"

#: app/flatpak-builtins-build-commit-from.c:299
msgid "Either --src-repo or --src-ref must be specified"
msgstr "必須指定 --src-repo 或 --src-ref 之一。"

#: app/flatpak-builtins-build-commit-from.c:315
msgid "Invalid argument format of use  --end-of-life-rebase=OLDID=NEWID"
msgstr "--end-of-life-rebase=OLDID=NEWID 的引數使用格式錯誤"

#: app/flatpak-builtins-build-commit-from.c:321
#: app/flatpak-builtins-build-commit-from.c:324
#, c-format
msgid "Invalid name %s in --end-of-life-rebase"
msgstr "--end-of-life-rebase 中的 %s 名稱無效"

#: app/flatpak-builtins-build-commit-from.c:333
#: app/flatpak-builtins-build-export.c:1092
#, c-format
msgid "Could not parse '%s'"
msgstr "無法解析「%s」"

#: app/flatpak-builtins-build-commit-from.c:498
msgid "Can't commit from partial source commit"
msgstr "無法根據部份來源提交進行提交"

#: app/flatpak-builtins-build-commit-from.c:503
#, c-format
msgid "%s: no change\n"
msgstr "%s：沒有變更\n"

#: app/flatpak-builtins-build-export.c:62
msgid "Architecture to export for (must be host compatible)"
msgstr "要匯出的架構（必須與主機相容）"

#: app/flatpak-builtins-build-export.c:63
msgid "Commit runtime (/usr), not /app"
msgstr "提交的執行時期環境 (/usr)，並非 /app"

#: app/flatpak-builtins-build-export.c:66
msgid "Use alternative directory for the files"
msgstr "為檔案使用替代目錄"

#: app/flatpak-builtins-build-export.c:66
msgid "SUBDIR"
msgstr "SUBDIR"

#: app/flatpak-builtins-build-export.c:69
msgid "Files to exclude"
msgstr "要排除的檔案"

#: app/flatpak-builtins-build-export.c:69
#: app/flatpak-builtins-build-export.c:70
#: app/flatpak-builtins-build-update-repo.c:90
msgid "PATTERN"
msgstr "PATTERN"

#: app/flatpak-builtins-build-export.c:70
msgid "Excluded files to include"
msgstr "要納入的排除檔案"

#: app/flatpak-builtins-build-export.c:74
msgid "Mark build as end-of-life, to be replaced with the given ID"
msgstr "將組建標為 end-of-life，會以提供的 ID 取代"

#: app/flatpak-builtins-build-export.c:74
#: app/flatpak-builtins-document-list.c:49 app/flatpak-cli-transaction.c:1427
msgid "ID"
msgstr "ID"

#: app/flatpak-builtins-build-export.c:76
msgid "Override the timestamp of the commit"
msgstr "凌駕提交的時間戳"

#: app/flatpak-builtins-build-export.c:77
#: app/flatpak-builtins-build-update-repo.c:75
#: app/flatpak-builtins-remote-add.c:83 app/flatpak-builtins-remote-list.c:54
#: app/flatpak-builtins-remote-modify.c:88
msgid "Collection ID"
msgstr "收藏 ID"

#: app/flatpak-builtins-build-export.c:472
#, c-format
msgid "WARNING: Error running desktop-file-validate: %s\n"
msgstr "警告：執行 desktop-file-validate 時發生錯誤：%s\n"

#: app/flatpak-builtins-build-export.c:480
#, c-format
msgid "WARNING: Error reading from desktop-file-validate: %s\n"
msgstr "警告：讀取 desktop-file-validate 時發生錯誤：%s\n"

#: app/flatpak-builtins-build-export.c:486
#, c-format
msgid "WARNING: Failed to validate desktop file %s: %s\n"
msgstr "警告：%s 桌面檔驗證失敗：%s\n"

#: app/flatpak-builtins-build-export.c:513
#, c-format
msgid "WARNING: Can't find Exec key in %s: %s\n"
msgstr "警告：在 %s 中找不到 Exec 鍵：%s\n"

#: app/flatpak-builtins-build-export.c:521
#: app/flatpak-builtins-build-export.c:614
#, c-format
msgid "WARNING: Binary not found for Exec line in %s: %s\n"
msgstr "警告：在 %s 找不到 Exec 列中的二進位檔：%s\n"

#: app/flatpak-builtins-build-export.c:529
#, c-format
msgid "WARNING: Icon not matching app id in %s: %s\n"
msgstr "警告：%s 中的圖示與應用程式 ID 不符：%s\n"

#: app/flatpak-builtins-build-export.c:552
#, c-format
msgid "WARNING: Icon referenced in desktop file but not exported: %s\n"
msgstr "警告：桌面檔內有參照的圖示但並未匯出：%s\n"

#: app/flatpak-builtins-build-export.c:719
#, c-format
msgid "Invalid uri type %s, only http/https supported"
msgstr "無效的 URI 類型 %s，僅支援 http/https"

#: app/flatpak-builtins-build-export.c:737
#, c-format
msgid "Unable to find basename in %s, specify a name explicitly"
msgstr "在 %s 中找不到基礎名，請明確指定名稱"

#: app/flatpak-builtins-build-export.c:746
#, c-format
msgid "No slashes allowed in extra data name"
msgstr "額外資料的名稱中不允許使用斜線"

#: app/flatpak-builtins-build-export.c:758
#, c-format
msgid "Invalid format for sha256 checksum: '%s'"
msgstr "Sha256 檢核碼格式無效：「%s」"

#: app/flatpak-builtins-build-export.c:768
#, c-format
msgid "Extra data sizes of zero not supported"
msgstr "不支援額外資料大小為零"

#: app/flatpak-builtins-build-export.c:830
msgid ""
"LOCATION DIRECTORY [BRANCH] - Create a repository from a build directory"
msgstr "LOCATION DIRECTORY [BRANCH] - 根據組建目錄建立軟體庫"

#: app/flatpak-builtins-build-export.c:838
msgid "LOCATION and DIRECTORY must be specified"
msgstr "必須指定 LOCATION 與 DIRECTORY"

#: app/flatpak-builtins-build-export.c:859
#: app/flatpak-builtins-remote-add.c:327
#, c-format
msgid "‘%s’ is not a valid collection ID: %s"
msgstr "「%s」不是有效的收藏 ID：%s"

#: app/flatpak-builtins-build-export.c:904
#: app/flatpak-builtins-build-finish.c:684
msgid "No name specified in the metadata"
msgstr "中介資料中沒有指定名稱"

#: app/flatpak-builtins-build-export.c:1166
#, c-format
msgid "Commit: %s\n"
msgstr "提交：%s\n"

#: app/flatpak-builtins-build-export.c:1167
#, c-format
msgid "Metadata Total: %u\n"
msgstr "中介資料總計：%u\n"

#: app/flatpak-builtins-build-export.c:1168
#, c-format
msgid "Metadata Written: %u\n"
msgstr "中介資料已寫入：%u\n"

#: app/flatpak-builtins-build-export.c:1169
#, c-format
msgid "Content Total: %u\n"
msgstr "內容總計：%u\n"

#: app/flatpak-builtins-build-export.c:1170
#, c-format
msgid "Content Written: %u\n"
msgstr "內容已寫入：%u\n"

#: app/flatpak-builtins-build-export.c:1171
#, c-format
msgid "Content Bytes Written:"
msgstr "內容已寫入位元組："

#: app/flatpak-builtins-build-finish.c:52
msgid "Command to set"
msgstr "要設定的指令"

#: app/flatpak-builtins-build-finish.c:52 app/flatpak-builtins-run.c:159
#: app/flatpak-main.c:209
msgid "COMMAND"
msgstr "COMMAND"

#: app/flatpak-builtins-build-finish.c:53
msgid "Flatpak version to require"
msgstr "要求的 Flatpak 版本"

#: app/flatpak-builtins-build-finish.c:53
msgid "MAJOR.MINOR.MICRO"
msgstr "MAJOR.MINOR.MICRO"

#: app/flatpak-builtins-build-finish.c:54
msgid "Don't process exports"
msgstr "不要處理匯出"

#: app/flatpak-builtins-build-finish.c:55
msgid "Extra data info"
msgstr "額外資料的資訊"

#: app/flatpak-builtins-build-finish.c:56 app/flatpak-builtins-build-init.c:63
msgid "Add extension point info"
msgstr "新增擴充點資訊"

#: app/flatpak-builtins-build-finish.c:56 app/flatpak-builtins-build-init.c:63
msgid "NAME=VARIABLE[=VALUE]"
msgstr "NAME=VARIABLE[=VALUE]"

#: app/flatpak-builtins-build-finish.c:57
msgid "Remove extension point info"
msgstr "移除擴充點資訊"

#: app/flatpak-builtins-build-finish.c:57
#: app/flatpak-builtins-build-update-repo.c:79 app/flatpak-builtins-info.c:58
#: app/flatpak-builtins-remote-add.c:88 app/flatpak-builtins-remote-modify.c:94
#: app/flatpak-main.c:182
msgid "NAME"
msgstr "NAME"

#: app/flatpak-builtins-build-finish.c:58
msgid "Set extension priority (only for extensions)"
msgstr "設定擴充優先順序（僅供擴充使用）"

#: app/flatpak-builtins-build-finish.c:58
msgid "VALUE"
msgstr "VALUE"

#: app/flatpak-builtins-build-finish.c:59
msgid "Change the sdk used for the app"
msgstr "變更用於程式的 SDK"

#: app/flatpak-builtins-build-finish.c:59
msgid "SDK"
msgstr "SDK"

#: app/flatpak-builtins-build-finish.c:60
msgid "Change the runtime used for the app"
msgstr "變更用於程式的執行時期環境"

#: app/flatpak-builtins-build-finish.c:60 app/flatpak-builtins-build-init.c:54
#: app/flatpak-builtins-list.c:53 app/flatpak-builtins-remote-ls.c:58
#: app/flatpak-builtins-run.c:163
msgid "RUNTIME"
msgstr "RUNTIME"

#: app/flatpak-builtins-build-finish.c:61
msgid "Set generic metadata option"
msgstr "設定通用的中介資料選項"

#: app/flatpak-builtins-build-finish.c:61
msgid "GROUP=KEY[=VALUE]"
msgstr "GROUP=KEY[=VALUE]"

#: app/flatpak-builtins-build-finish.c:62
msgid "Don't inherit permissions from runtime"
msgstr "不要從執行時期環境繼承權限"

#: app/flatpak-builtins-build-finish.c:155
#, c-format
msgid "Not exporting %s, wrong extension\n"
msgstr "未匯出 %s，錯誤的擴充\n"

#: app/flatpak-builtins-build-finish.c:163
#, c-format
msgid "Not exporting %s, non-allowed export filename\n"
msgstr "未匯出 %s，不允許的匯出檔名\n"

#: app/flatpak-builtins-build-finish.c:167
#, c-format
msgid "Exporting %s\n"
msgstr "正在匯出 %s\n"

#: app/flatpak-builtins-build-finish.c:440
#, c-format
msgid "More than one executable found\n"
msgstr "找到一個以上的執行檔\n"

#: app/flatpak-builtins-build-finish.c:451
#, c-format
msgid "Using %s as command\n"
msgstr "使用 %s 作為指令\n"

#: app/flatpak-builtins-build-finish.c:456
#, c-format
msgid "No executable found\n"
msgstr "找不到執行檔\n"

#: app/flatpak-builtins-build-finish.c:511
#, c-format
msgid "Invalid --require-version argument: %s"
msgstr "無效的 --require-version 引數：%s"

#: app/flatpak-builtins-build-finish.c:543
#, c-format
msgid "Too few elements in --extra-data argument %s"
msgstr "--extra-data 引數 %s 中的元素過少"

#: app/flatpak-builtins-build-finish.c:575
#, c-format
msgid ""
"Too few elements in --metadata argument %s, format should be "
"GROUP=KEY[=VALUE]]"
msgstr "--metadata 引數 %s 中的元素過少，格式應該為 GROUP=KEY[=VALUE]]"

#: app/flatpak-builtins-build-finish.c:597
#: app/flatpak-builtins-build-init.c:458
#, c-format
msgid ""
"Too few elements in --extension argument %s, format should be "
"NAME=VAR[=VALUE]"
msgstr "--extension 引數 %s 中的元素過少，格式應該為 NAME=VAR[=VALUE]"

#: app/flatpak-builtins-build-finish.c:603
#: app/flatpak-builtins-build-init.c:461
#, fuzzy, c-format
msgid "Invalid extension name %s"
msgstr "無效的身分核對器名稱 %s"

#: app/flatpak-builtins-build-finish.c:646
msgid "DIRECTORY - Finalize a build directory"
msgstr "DIRECTORY - 總結一組建目錄"

#: app/flatpak-builtins-build-finish.c:668
#, c-format
msgid "Build directory %s not initialized"
msgstr "組建目錄 %s 尚未初始化"

#: app/flatpak-builtins-build-finish.c:689
#, c-format
msgid "Build directory %s already finalized"
msgstr "組建目錄 %s 已經總結"

#: app/flatpak-builtins-build-finish.c:702
#, c-format
msgid "Please review the exported files and the metadata\n"
msgstr "請檢閱匯出的檔案與中介資料\n"

#: app/flatpak-builtins-build-import-bundle.c:47
msgid "Override the ref used for the imported bundle"
msgstr "凌駕匯出套組使用的參照"

#: app/flatpak-builtins-build-import-bundle.c:47
msgid "REF"
msgstr "REF"

#: app/flatpak-builtins-build-import-bundle.c:48
msgid "Import oci image instead of flatpak bundle"
msgstr "匯出 OCI 映像檔而非 flatpak 套組"

#: app/flatpak-builtins-build-import-bundle.c:77
#: app/flatpak-builtins-build-import-bundle.c:105
#, c-format
msgid "Importing %s (%s)\n"
msgstr "正在匯入 %s (%s)\n"

#: app/flatpak-builtins-build-import-bundle.c:126
msgid "LOCATION FILENAME - Import a file bundle into a local repository"
msgstr "LOCATION FILENAME - 匯入一個檔案套組到本機軟體庫中"

#: app/flatpak-builtins-build-import-bundle.c:133
msgid "LOCATION and FILENAME must be specified"
msgstr "必須指定 LOCATION 與 FILENAME"

#: app/flatpak-builtins-build-init.c:53 app/flatpak-builtins-info.c:55
#: app/flatpak-builtins-run.c:158
msgid "Arch to use"
msgstr "要使用的架構"

#: app/flatpak-builtins-build-init.c:54
msgid "Initialize var from named runtime"
msgstr "根據命名的執行時期環境初始化變數"

#: app/flatpak-builtins-build-init.c:55
msgid "Initialize apps from named app"
msgstr "根據命名的應用程式初始化應用程式"

#: app/flatpak-builtins-build-init.c:55
msgid "APP"
msgstr "APP"

#: app/flatpak-builtins-build-init.c:56
msgid "Specify version for --base"
msgstr "為 --base 指定版本"

#: app/flatpak-builtins-build-init.c:56 app/flatpak-builtins-run.c:164
msgid "VERSION"
msgstr "VERSION"

#: app/flatpak-builtins-build-init.c:57
msgid "Include this base extension"
msgstr "納入此基礎擴充"

#: app/flatpak-builtins-build-init.c:57 app/flatpak-builtins-build-init.c:62
msgid "EXTENSION"
msgstr "EXTENSION"

#: app/flatpak-builtins-build-init.c:58
msgid "Extension tag to use if building extension"
msgstr "若要組建擴充則要使用擴充標籤"

#: app/flatpak-builtins-build-init.c:58
msgid "EXTENSION_TAG"
msgstr "EXTENSION_TAG"

#: app/flatpak-builtins-build-init.c:59
msgid "Initialize /usr with a writable copy of the sdk"
msgstr "以一份可寫入的 SDK 副本初始化 /usr"

#: app/flatpak-builtins-build-init.c:60
msgid "Specify the build type (app, runtime, extension)"
msgstr "指定組建類型（app、runtime、extension）"

#: app/flatpak-builtins-build-init.c:60
msgid "TYPE"
msgstr "TYPE"

#: app/flatpak-builtins-build-init.c:61
msgid "Add a tag"
msgstr "加入標籤"

#: app/flatpak-builtins-build-init.c:61
msgid "TAG"
msgstr "TAG"

#: app/flatpak-builtins-build-init.c:62
msgid "Include this sdk extension in /usr"
msgstr "在 /usr 中納入此 SDK 擴充"

#: app/flatpak-builtins-build-init.c:64
msgid "Where to store sdk (defaults to 'usr')"
msgstr "儲存 SDK 的地方（預設為「usr」）"

#: app/flatpak-builtins-build-init.c:65
msgid "Re-initialize the sdk/var"
msgstr "重新初始化 sdk/var"

#: app/flatpak-builtins-build-init.c:118
#, fuzzy, c-format
msgid "Requested extension %s/%s/%s is only partially installed"
msgstr "要求的 %s 擴充僅部份安裝"

#: app/flatpak-builtins-build-init.c:147
#, fuzzy, c-format
msgid "Requested extension %s/%s/%s not installed"
msgstr "要求的 %s 擴充尚未安裝"

#: app/flatpak-builtins-build-init.c:207
msgid ""
"DIRECTORY APPNAME SDK RUNTIME [BRANCH] - Initialize a directory for building"
msgstr "DIRECTORY APPNAME SDK RUNTIME [BRANCH] - 初始化目錄以供組建使用"

#: app/flatpak-builtins-build-init.c:214
msgid "RUNTIME must be specified"
msgstr "必須指定 RUNTIME"

#: app/flatpak-builtins-build-init.c:235
#, c-format
msgid "'%s' is not a valid build type name, use app, runtime or extension"
msgstr "「%s」不是有效的組建類型名稱，請使用 app、runtime、extension"

#: app/flatpak-builtins-build-init.c:241 app/flatpak-builtins-override.c:79
#, c-format
msgid "'%s' is not a valid application name: %s"
msgstr "「%s」不是有效的應用程式名稱：%s"

#: app/flatpak-builtins-build-init.c:295
#, c-format
msgid "Build directory %s already initialized"
msgstr "組建目錄 %s 已經初始化"

#: app/flatpak-builtins-build-sign.c:42 app/flatpak-builtins-install.c:67
#: app/flatpak-builtins-remote-info.c:54
msgid "Arch to install for"
msgstr "要安裝的架構"

#: app/flatpak-builtins-build-sign.c:43 app/flatpak-builtins-create-usb.c:48
#: app/flatpak-builtins-install.c:74 app/flatpak-builtins-remote-info.c:56
#: app/flatpak-builtins-uninstall.c:58 app/flatpak-builtins-update.c:64
msgid "Look for runtime with the specified name"
msgstr "以指定名稱查找執行時期環境"

#: app/flatpak-builtins-build-sign.c:66
msgid "LOCATION [ID [BRANCH]] - Sign an application or runtime"
msgstr "LOCATION [ID [BRANCH]] - 簽署應用程式或執行時期環境"

#: app/flatpak-builtins-build-sign.c:73
#: app/flatpak-builtins-build-update-repo.c:499
#: app/flatpak-builtins-remote-add.c:320 app/flatpak-builtins-repo.c:739
msgid "LOCATION must be specified"
msgstr "必須指定 LOCATION"

#: app/flatpak-builtins-build-sign.c:94
msgid "No gpg key ids specified"
msgstr "尚未指定 GPG 金鑰 ID"

#: app/flatpak-builtins-build-update-repo.c:68
msgid "Redirect this repo to a new URL"
msgstr "將此軟體庫重導至新 URL"

#: app/flatpak-builtins-build-update-repo.c:69
msgid "A nice name to use for this repository"
msgstr "用於此軟體庫的好讀名稱"

#: app/flatpak-builtins-build-update-repo.c:69
#: app/flatpak-builtins-remote-add.c:77 app/flatpak-builtins-remote-modify.c:82
msgid "TITLE"
msgstr "TITLE"

#: app/flatpak-builtins-build-update-repo.c:70
msgid "A one-line comment for this repository"
msgstr "此軟體庫的一列評註"

#: app/flatpak-builtins-build-update-repo.c:70
#: app/flatpak-builtins-remote-add.c:78 app/flatpak-builtins-remote-modify.c:83
msgid "COMMENT"
msgstr "COMMENT"

#: app/flatpak-builtins-build-update-repo.c:71
msgid "A full-paragraph description for this repository"
msgstr "此軟體庫的整段描述"

#: app/flatpak-builtins-build-update-repo.c:71
#: app/flatpak-builtins-remote-add.c:79 app/flatpak-builtins-remote-modify.c:84
msgid "DESCRIPTION"
msgstr "DESCRIPTION"

#: app/flatpak-builtins-build-update-repo.c:72
msgid "URL for a website for this repository"
msgstr "此軟體庫的網站 URL"

#: app/flatpak-builtins-build-update-repo.c:73
msgid "URL for an icon for this repository"
msgstr "此軟體庫的圖示 URL"

#: app/flatpak-builtins-build-update-repo.c:74
msgid "Default branch to use for this repository"
msgstr "用於此軟體庫的預設分支"

#: app/flatpak-builtins-build-update-repo.c:74
#: app/flatpak-builtins-remote-add.c:82 app/flatpak-builtins-remote-modify.c:87
#: app/flatpak-builtins-repo.c:713 app/flatpak-builtins-repo.c:714
#: app/flatpak-builtins-run.c:161
msgid "BRANCH"
msgstr "BRANCH"

#: app/flatpak-builtins-build-update-repo.c:75
#: app/flatpak-builtins-remote-add.c:83 app/flatpak-builtins-remote-modify.c:88
msgid "COLLECTION-ID"
msgstr "COLLECTION-ID"

#. Translators: A sideload is when you install from a local USB drive rather than the Internet.
#: app/flatpak-builtins-build-update-repo.c:77
msgid ""
"Permanently deploy collection ID to client remote configurations, only for "
"sideload support"
msgstr "永久布署收藏 ID 至用戶端遠端設定，僅供側載支援"

#: app/flatpak-builtins-build-update-repo.c:78
msgid "Permanently deploy collection ID to client remote configurations"
msgstr "永久布署收藏 ID 到客戶端的遠端組態"

#: app/flatpak-builtins-build-update-repo.c:79
msgid "Name of authenticator for this repository"
msgstr "此軟體庫的身分核對器名稱"

#: app/flatpak-builtins-build-update-repo.c:80
msgid "Autoinstall authenticator for this repository"
msgstr "自動安裝此軟體庫的身分核對器"

#: app/flatpak-builtins-build-update-repo.c:81
msgid "Don't autoinstall authenticator for this repository"
msgstr "不要自動安裝此軟體庫的身分核對器"

#: app/flatpak-builtins-build-update-repo.c:82
#: app/flatpak-builtins-remote-add.c:89
msgid "Authenticator option"
msgstr "身分核對器選項"

#: app/flatpak-builtins-build-update-repo.c:82
#: app/flatpak-builtins-remote-add.c:89 app/flatpak-builtins-remote-modify.c:95
msgid "KEY=VALUE"
msgstr "KEY=VALUE"

#: app/flatpak-builtins-build-update-repo.c:83
msgid "Import new default GPG public key from FILE"
msgstr "以 FILE 作為新的預設 GPG 公開金鑰匯入"

#: app/flatpak-builtins-build-update-repo.c:84
msgid "GPG Key ID to sign the summary with"
msgstr "用於簽署摘要的 GPG 金鑰 ID"

#: app/flatpak-builtins-build-update-repo.c:86
msgid "Generate delta files"
msgstr "生成增減檔"

#: app/flatpak-builtins-build-update-repo.c:88
msgid "Don't update the appstream branch"
msgstr "不要更新 AppStream 分支"

#: app/flatpak-builtins-build-update-repo.c:89
msgid "Max parallel jobs when creating deltas (default: NUMCPUs)"
msgstr "建立增減檔的最大並行作業數（預設值：CPU 數 (NUMCPUs)）"

#: app/flatpak-builtins-build-update-repo.c:89
msgid "NUM-JOBS"
msgstr "NUM-JOBS"

#: app/flatpak-builtins-build-update-repo.c:90
msgid "Don't create deltas matching refs"
msgstr "不建立符合參照的增減檔"

#: app/flatpak-builtins-build-update-repo.c:91
msgid "Prune unused objects"
msgstr "修除未使用的物件"

#: app/flatpak-builtins-build-update-repo.c:92
msgid "Prune but don't actually remove anything"
msgstr ""

#: app/flatpak-builtins-build-update-repo.c:93
msgid "Only traverse DEPTH parents for each commit (default: -1=infinite)"
msgstr "每個提交僅橫跨 DEPTH 個層級的上層目錄（預設值：-1=無限）"

#: app/flatpak-builtins-build-update-repo.c:93
msgid "DEPTH"
msgstr "DEPTH"

#: app/flatpak-builtins-build-update-repo.c:223
#, c-format
msgid "Generating delta: %s (%.10s)\n"
msgstr "正在生成增減檔：%s (%.10s)\n"

#: app/flatpak-builtins-build-update-repo.c:225
#, c-format
msgid "Generating delta: %s (%.10s-%.10s)\n"
msgstr "正在生成增減檔：%s (%.10s-%.10s)\n"

#: app/flatpak-builtins-build-update-repo.c:233
#, c-format
msgid "Failed to generate delta %s (%.10s): "
msgstr "增減檔 %s 生成失敗 (%.10s)："

#: app/flatpak-builtins-build-update-repo.c:236
#, c-format
msgid "Failed to generate delta %s (%.10s-%.10s): "
msgstr "增減檔 %s 生成失敗 (%.10s-%.10s)："

#: app/flatpak-builtins-build-update-repo.c:492
msgid "LOCATION - Update repository metadata"
msgstr "LOCATION - 更新軟體庫中介資料"

#: app/flatpak-builtins-build-update-repo.c:609
#, c-format
msgid "Updating appstream branch\n"
msgstr "正在更新 appstream 分支\n"

#: app/flatpak-builtins-build-update-repo.c:638
#, c-format
msgid "Updating summary\n"
msgstr "正在更新摘要\n"

#: app/flatpak-builtins-build-update-repo.c:664
#, c-format
msgid "Total objects: %u\n"
msgstr "物件總數：%u\n"

#: app/flatpak-builtins-build-update-repo.c:666
#, c-format
msgid "No unreachable objects\n"
msgstr "沒有無法觸及的物件\n"

#: app/flatpak-builtins-build-update-repo.c:668
#, c-format
msgid "Deleted %u objects, %s freed\n"
msgstr "已刪除 %u 個物件，已釋放 %s 空間\n"

#: app/flatpak-builtins-config.c:41
msgid "List configuration keys and values"
msgstr "列出組態的鍵值清單"

#: app/flatpak-builtins-config.c:42
msgid "Get configuration for KEY"
msgstr "取得 KEY 的組態"

#: app/flatpak-builtins-config.c:43
msgid "Set configuration for KEY to VALUE"
msgstr "將組態的 KEY 設定為 VALUE"

#: app/flatpak-builtins-config.c:44
msgid "Unset configuration for KEY"
msgstr "取消組態的 KEY 設定"

#: app/flatpak-builtins-config.c:149
#, c-format
msgid "'%s' does not look like a language/locale code"
msgstr "「%s」看似不像語言或地區代碼"

#: app/flatpak-builtins-config.c:172
#, c-format
msgid "'%s' does not look like a language code"
msgstr "「%s」看起來不像語言碼"

#: app/flatpak-builtins-config.c:190
#, fuzzy, c-format
msgid "'%s' is not a valid value (use 'true' or 'false')"
msgstr "「%s」不是有效的軟體庫："

#: app/flatpak-builtins-config.c:262
#, c-format
msgid "Unknown configure key '%s'"
msgstr "未知的組態鍵「%s」"

#: app/flatpak-builtins-config.c:284
msgid "Too many arguments for --list"
msgstr "--list 的引數過多"

#: app/flatpak-builtins-config.c:314 app/flatpak-builtins-config.c:362
msgid "You must specify KEY"
msgstr "您必須指定 KEY"

#: app/flatpak-builtins-config.c:316
msgid "Too many arguments for --get"
msgstr "--get 的引數過多"

#: app/flatpak-builtins-config.c:338
msgid "You must specify KEY and VALUE"
msgstr "您必須指定 KEY 與 VALUE"

#: app/flatpak-builtins-config.c:340
msgid "Too many arguments for --set"
msgstr "傳入 --set 的引數過多"

#: app/flatpak-builtins-config.c:364
msgid "Too many arguments for --unset"
msgstr "--unset 的引數過多"

#: app/flatpak-builtins-config.c:383
msgid "[KEY [VALUE]] - Manage configuration"
msgstr "[KEY [VALUE]] - 管理組態"

#: app/flatpak-builtins-config.c:394
msgid "Can only use one of --list, --get, --set or --unset"
msgstr "僅可以使用 --list、--get、--set 或 --unset 其中之一"

#: app/flatpak-builtins-config.c:408
msgid "Must specify one of --list, --get, --set or --unset"
msgstr "必須指定 --list、--get、--set、--unset 其中之一"

#: app/flatpak-builtins-create-usb.c:45 app/flatpak-builtins-install.c:75
#: app/flatpak-builtins-remote-info.c:57 app/flatpak-builtins-uninstall.c:59
#: app/flatpak-builtins-update.c:65
msgid "Look for app with the specified name"
msgstr "以指定名稱查找程式"

#: app/flatpak-builtins-create-usb.c:46
msgid "Arch to copy"
msgstr "要複製的架構"

#: app/flatpak-builtins-create-usb.c:47
msgid "DEST"
msgstr "DEST"

#: app/flatpak-builtins-create-usb.c:49
msgid "Allow partial commits in the created repo"
msgstr "允許在建立的軟體庫進行部分提交"

#: app/flatpak-builtins-create-usb.c:125 app/flatpak-builtins-create-usb.c:165
#, fuzzy, c-format
msgid ""
"Warning: Related ref ‘%s’ is partially installed. Use --allow-partial to "
"suppress this message.\n"
msgstr "警告：忽略相關的「%s」參照，因為已部分安裝。\n"

#: app/flatpak-builtins-create-usb.c:158
#, c-format
msgid "Warning: Omitting related ref ‘%s’ because it is not installed.\n"
msgstr "警告：忽略相關的「%s」參照，因為它尚未安裝。\n"

#: app/flatpak-builtins-create-usb.c:175
#, c-format
msgid ""
"Warning: Omitting related ref ‘%s’ because its remote ‘%s’ does not have a "
"collection ID set.\n"
msgstr "警告：忽略相關的「%s」參照，因為它的「%s」遠端並未設定收藏 ID。\n"

#: app/flatpak-builtins-create-usb.c:187
#, fuzzy, c-format
msgid "Warning: Omitting related ref ‘%s’ because it's extra-data.\n"
msgstr "警告：忽略相關的「%s」參照，因為它尚未安裝。\n"

#: app/flatpak-builtins-create-usb.c:262 app/flatpak-builtins-create-usb.c:637
#, c-format
msgid ""
"Remote ‘%s’ does not have a collection ID set, which is required for P2P "
"distribution of ‘%s’."
msgstr "「%s」遠端並沒有設定收藏 ID，但這在「%s」的 P2P 散布作業中卻有要求。"

#: app/flatpak-builtins-create-usb.c:272
#, fuzzy, c-format
msgid "Warning: Omitting ref ‘%s’ (runtime of ‘%s’) because it's extra-data.\n"
msgstr "警告：忽略相關的「%s」參照，因為它尚未安裝。\n"

#: app/flatpak-builtins-create-usb.c:484
msgid "MOUNT-PATH [REF…] - Copy apps or runtimes onto removable media"
msgstr "MOUNT-PATH [REF…] - 複製 App 或執行時期至可移除式媒體"

#: app/flatpak-builtins-create-usb.c:493
msgid "MOUNT-PATH and REF must be specified"
msgstr "必須指定 MOUNT-PATH 與 REF"

#: app/flatpak-builtins-create-usb.c:607
#, c-format
msgid "Ref ‘%s’ found in multiple installations: %s. You must specify one."
msgstr "在多個安裝中找到「%s」參照：%s。您必須指定一個。"

#: app/flatpak-builtins-create-usb.c:620
#, c-format
msgid "Refs must all be in the same installation (found in %s and %s)."
msgstr "參照必須全部都在相同的安裝裡（在 %s 與 %s 中都有找到）。"

#: app/flatpak-builtins-create-usb.c:670
#, c-format
msgid ""
"Warning: Ref ‘%s’ is partially installed. Use --allow-partial to suppress "
"this message.\n"
msgstr ""

#: app/flatpak-builtins-create-usb.c:681
#, c-format
msgid "Installed ref ‘%s’ is extra-data, and cannot be distributed offline"
msgstr ""

#: app/flatpak-builtins-create-usb.c:721
#, c-format
msgid "Warning: Couldn't update repo metadata for remote ‘%s’: %s\n"
msgstr "警告：無法更新「%s」遠端的軟體庫中介資料：%s\n"

#: app/flatpak-builtins-create-usb.c:751
#, c-format
msgid "Warning: Couldn't update appstream data for remote ‘%s’ arch ‘%s’: %s\n"
msgstr "警告：無法更新「%s」遠端的「%s」架構 appstream 資料：%s\n"

#. Print a warning if both appstream and appstream2 are missing
#: app/flatpak-builtins-create-usb.c:784
#, c-format
msgid ""
"Warning: Couldn't find appstream data for remote ‘%s’ arch ‘%s’: %s; %s\n"
msgstr "警告：找不到「%s」遠端的「%s」架構 appstream 資料：%s; %s\n"

#. Appstream2 is only for efficiency, so just print a debug message
#: app/flatpak-builtins-create-usb.c:790
#, c-format
msgid "Couldn't find appstream2 data for remote ‘%s’ arch ‘%s’: %s\n"
msgstr "找不到「%s」遠端的「%s」架構 appstream2 資料：%s\n"

#: app/flatpak-builtins-document-export.c:62
msgid "Create a unique document reference"
msgstr "建立獨一的文件參照"

#: app/flatpak-builtins-document-export.c:63
msgid "Make the document transient for the current session"
msgstr "讓文件在目前的工作階段轉為暫時狀態"

#: app/flatpak-builtins-document-export.c:64
msgid "Don't require the file to exist already"
msgstr "不須要特定檔案已先存在"

#: app/flatpak-builtins-document-export.c:65
msgid "Give the app read permissions"
msgstr "給予程式讀取許可"

#: app/flatpak-builtins-document-export.c:66
msgid "Give the app write permissions"
msgstr "給予程式寫入許可"

#: app/flatpak-builtins-document-export.c:67
msgid "Give the app delete permissions"
msgstr "給予程式刪除許可"

#: app/flatpak-builtins-document-export.c:68
msgid "Give the app permissions to grant further permissions"
msgstr "給予程式得以授予其他許可的權利"

#: app/flatpak-builtins-document-export.c:69
msgid "Revoke read permissions of the app"
msgstr "撤銷程式的讀取許可"

#: app/flatpak-builtins-document-export.c:70
msgid "Revoke write permissions of the app"
msgstr "撤銷程式的寫入許可"

#: app/flatpak-builtins-document-export.c:71
msgid "Revoke delete permissions of the app"
msgstr "撤銷程式的刪除許可"

#: app/flatpak-builtins-document-export.c:72
msgid "Revoke the permission to grant further permissions"
msgstr "撤銷程式得以授予其他許可的權利"

#: app/flatpak-builtins-document-export.c:73
msgid "Add permissions for this app"
msgstr "為此程式新增許可"

#: app/flatpak-builtins-document-export.c:73
msgid "APPID"
msgstr "APPID"

#: app/flatpak-builtins-document-export.c:100
msgid "FILE - Export a file to apps"
msgstr "FILE - 匯出檔案給程式"

#: app/flatpak-builtins-document-export.c:109
#: app/flatpak-builtins-document-info.c:72
#: app/flatpak-builtins-document-unexport.c:67
msgid "FILE must be specified"
msgstr "必須要指定 FILE"

#: app/flatpak-builtins-document-info.c:63
msgid "FILE - Get information about an exported file"
msgstr "FILE - 取得已匯出檔案的相關資訊"

#: app/flatpak-builtins-document-info.c:100
#: app/flatpak-builtins-document-unexport.c:94
#, c-format
msgid "Not exported\n"
msgstr "未匯出\n"

#: app/flatpak-builtins-document-list.c:43 app/flatpak-builtins-history.c:53
#: app/flatpak-builtins-list.c:54 app/flatpak-builtins-ps.c:43
#: app/flatpak-builtins-remote-list.c:45 app/flatpak-builtins-remote-ls.c:59
#: app/flatpak-builtins-search.c:38
msgid "What information to show"
msgstr "要顯示什麼資訊"

#: app/flatpak-builtins-document-list.c:43 app/flatpak-builtins-history.c:53
#: app/flatpak-builtins-list.c:54 app/flatpak-builtins-ps.c:43
#: app/flatpak-builtins-remote-list.c:45 app/flatpak-builtins-remote-ls.c:59
#: app/flatpak-builtins-search.c:38
msgid "FIELD,…"
msgstr "FIELD,…"

#: app/flatpak-builtins-document-list.c:44 app/flatpak-builtins-history.c:54
#: app/flatpak-builtins-list.c:52 app/flatpak-builtins-permission-list.c:43
#: app/flatpak-builtins-permission-show.c:43 app/flatpak-builtins-ps.c:44
#: app/flatpak-builtins-remote-list.c:46 app/flatpak-builtins-remote-ls.c:63
#: app/flatpak-builtins-repo.c:717 app/flatpak-builtins-search.c:39
#, fuzzy
msgid "Show output in JSON format"
msgstr "顯示額外資訊"

#: app/flatpak-builtins-document-list.c:49
msgid "Show the document ID"
msgstr "顯示文件 ID"

#: app/flatpak-builtins-document-list.c:50
msgid "Path"
msgstr "路徑"

#: app/flatpak-builtins-document-list.c:50
#: app/flatpak-builtins-document-list.c:51
msgid "Show the document path"
msgstr "顯示文件路徑"

#: app/flatpak-builtins-document-list.c:51 app/flatpak-builtins-list.c:66
#: app/flatpak-builtins-remote-ls.c:74
msgid "Origin"
msgstr "來源"

#: app/flatpak-builtins-document-list.c:52 app/flatpak-builtins-history.c:62
#: app/flatpak-builtins-ps.c:52
msgid "Application"
msgstr "應用程式"

#: app/flatpak-builtins-document-list.c:52
msgid "Show applications with permission"
msgstr "顯示應用程式與權限"

#: app/flatpak-builtins-document-list.c:53
#: app/flatpak-builtins-permission-list.c:182
#: app/flatpak-builtins-permission-show.c:145
msgid "Permissions"
msgstr "權限"

#: app/flatpak-builtins-document-list.c:53
msgid "Show permissions for applications"
msgstr "顯示應用程式的權限"

#: app/flatpak-builtins-document-list.c:161
#, fuzzy, c-format
msgid "No documents found\n"
msgstr "找不到符合項目"

#: app/flatpak-builtins-document-list.c:180
msgid "[APPID] - List exported files"
msgstr "[APPID] - 列出已匯出的檔案"

#: app/flatpak-builtins-document-unexport.c:43
#, fuzzy
msgid "Specify the document ID"
msgstr "顯示文件 ID"

#: app/flatpak-builtins-document-unexport.c:58
msgid "FILE - Unexport a file to apps"
msgstr "FILE - 取消檔案匯出到程式的動作"

#: app/flatpak-builtins-enter.c:88
msgid "INSTANCE COMMAND [ARGUMENT…] - Run a command inside a running sandbox"
msgstr "INSTANCE COMMAND [ARGUMENT…] - 在執行中的沙盒裡執行指令"

#: app/flatpak-builtins-enter.c:111
msgid "INSTANCE and COMMAND must be specified"
msgstr "必須指定 INSTANCE 與 COMMAND"

#: app/flatpak-builtins-enter.c:138
#, c-format
msgid "%s is neither a pid nor an application or instance ID"
msgstr "%s 不是 PID 也不是應用程式或實體 ID"

#: app/flatpak-builtins-enter.c:144
msgid "entering not supported (need unprivileged user namespaces, or sudo -E)"
msgstr "不支援 entering（需要非特權的使用者命名空間或 sudo -E）"

#: app/flatpak-builtins-enter.c:145
#, c-format
msgid "No such pid %s"
msgstr "無此 PID %s"

#: app/flatpak-builtins-enter.c:158
msgid "Can't read cwd"
msgstr "無法讀取 cwd"

#: app/flatpak-builtins-enter.c:163
msgid "Can't read root"
msgstr "無法讀取 root"

#: app/flatpak-builtins-enter.c:191
#, c-format
msgid "Invalid %s namespace for pid %d"
msgstr "PID %2$d 的 %1$s namespace 無效"

#: app/flatpak-builtins-enter.c:202
#, c-format
msgid "Invalid %s namespace for self"
msgstr "self 的 %s namespace 無效"

#: app/flatpak-builtins-enter.c:216
#, c-format
msgid "Can't open %s namespace: %s"
msgstr "無法開啟 %s namespace：%s"

#: app/flatpak-builtins-enter.c:226
msgid "entering not supported (need unprivileged user namespaces)"
msgstr "不支援 entering（需要非特權的使用者命名空間）"

#: app/flatpak-builtins-enter.c:227
#, c-format
msgid "Can't enter %s namespace: %s"
msgstr "無法進入 %s namespace：%s"

#: app/flatpak-builtins-enter.c:234
msgid "Can't chdir"
msgstr "無法 chdir"

#: app/flatpak-builtins-enter.c:237
msgid "Can't chroot"
msgstr "無法 chroot"

#: app/flatpak-builtins-enter.c:240
msgid "Can't switch gid"
msgstr "無法切換 GID"

#: app/flatpak-builtins-enter.c:243
msgid "Can't switch uid"
msgstr "無法切換 UID"

#: app/flatpak-builtins-history.c:50
msgid "Only show changes after TIME"
msgstr "僅顯示 TIME 之後的變更"

#: app/flatpak-builtins-history.c:50 app/flatpak-builtins-history.c:51
msgid "TIME"
msgstr "TIME"

#: app/flatpak-builtins-history.c:51
msgid "Only show changes before TIME"
msgstr "僅顯示 TIME 之前的變更"

#: app/flatpak-builtins-history.c:52
msgid "Show newest entries first"
msgstr "先顯示最新的條目"

#: app/flatpak-builtins-history.c:59
msgid "Time"
msgstr "時間"

#: app/flatpak-builtins-history.c:59
msgid "Show when the change happened"
msgstr "發生變更時顯示"

#: app/flatpak-builtins-history.c:60
msgid "Change"
msgstr "變更"

#: app/flatpak-builtins-history.c:60
msgid "Show the kind of change"
msgstr "顯示變更的類型"

#: app/flatpak-builtins-history.c:61 app/flatpak-builtins-list.c:68
#: app/flatpak-builtins-remote-ls.c:75 app/flatpak-builtins-repo.c:335
msgid "Ref"
msgstr "參照"

#: app/flatpak-builtins-history.c:61 app/flatpak-builtins-list.c:68
#: app/flatpak-builtins-remote-ls.c:75
msgid "Show the ref"
msgstr "顯示參照"

#: app/flatpak-builtins-history.c:62
msgid "Show the application/runtime ID"
msgstr "顯示應用程式或執行時期環境 ID"

#: app/flatpak-builtins-history.c:63 app/flatpak-builtins-list.c:64
#: app/flatpak-builtins-ps.c:53 app/flatpak-builtins-remote-ls.c:73
#: app/flatpak-cli-transaction.c:1435
msgid "Arch"
msgstr "架構"

#: app/flatpak-builtins-history.c:63 app/flatpak-builtins-list.c:64
#: app/flatpak-builtins-ps.c:53 app/flatpak-builtins-remote-ls.c:73
msgid "Show the architecture"
msgstr "顯示架構"

#: app/flatpak-builtins-history.c:64 app/flatpak-builtins-list.c:63
#: app/flatpak-builtins-ps.c:54 app/flatpak-builtins-remote-ls.c:72
#: app/flatpak-builtins-search.c:48 app/flatpak-cli-transaction.c:1438
msgid "Branch"
msgstr "分支"

#: app/flatpak-builtins-history.c:64 app/flatpak-builtins-list.c:63
#: app/flatpak-builtins-remote-ls.c:72
msgid "Show the branch"
msgstr "顯示分支"

#: app/flatpak-builtins-history.c:65 app/flatpak-builtins-list.c:67
msgid "Installation"
msgstr "安裝"

#: app/flatpak-builtins-history.c:65
msgid "Show the affected installation"
msgstr "顯示受影響的安裝"

#: app/flatpak-builtins-history.c:66 app/flatpak-cli-transaction.c:1452
msgid "Remote"
msgstr "遠端"

#: app/flatpak-builtins-history.c:66
msgid "Show the remote"
msgstr "顯示遠端"

#: app/flatpak-builtins-history.c:67 app/flatpak-builtins-ps.c:55
#: app/flatpak-builtins-remote-ls.c:76
msgid "Commit"
msgstr "提交"

#: app/flatpak-builtins-history.c:67
msgid "Show the current commit"
msgstr "顯示目前的提交"

#: app/flatpak-builtins-history.c:68
msgid "Old Commit"
msgstr "舊的提交"

#: app/flatpak-builtins-history.c:68
msgid "Show the previous commit"
msgstr "顯示先前的提交"

#: app/flatpak-builtins-history.c:69
msgid "Show the remote URL"
msgstr "顯示遠端 URL"

#: app/flatpak-builtins-history.c:70 app/flatpak-cli-transaction.c:700
msgid "User"
msgstr "使用者"

#: app/flatpak-builtins-history.c:70
msgid "Show the user doing the change"
msgstr "顯示做出變更的使用者"

#: app/flatpak-builtins-history.c:71
msgid "Tool"
msgstr "工具"

#: app/flatpak-builtins-history.c:71
msgid "Show the tool that was used"
msgstr "顯示使用的工具"

#: app/flatpak-builtins-history.c:72 app/flatpak-builtins-list.c:62
#: app/flatpak-builtins-remote-ls.c:71 app/flatpak-builtins-search.c:47
msgid "Version"
msgstr "版本"

#: app/flatpak-builtins-history.c:72
msgid "Show the Flatpak version"
msgstr "顯示 Flatpak 版本"

#: app/flatpak-builtins-history.c:91
#, c-format
msgid "Failed to get journal data (%s): %s"
msgstr "日誌資料 (%s) 取得失敗：%s"

#: app/flatpak-builtins-history.c:146
#, c-format
msgid "Failed to open journal: %s"
msgstr "日誌開啟失敗：%s"

#: app/flatpak-builtins-history.c:153
#, c-format
msgid "Failed to add match to journal: %s"
msgstr "將符合項目加到日誌時失敗：%s"

#: app/flatpak-builtins-history.c:471
msgid " - Show history"
msgstr " - 顯示歷史"

#: app/flatpak-builtins-history.c:490
#, c-format
msgid "Failed to parse the --since option"
msgstr "無法解析 --since 選項"

#: app/flatpak-builtins-history.c:501
#, c-format
msgid "Failed to parse the --until option"
msgstr "無法解析 --until 選項"

#: app/flatpak-builtins-info.c:56
msgid "Show user installations"
msgstr "顯示使用者層級的安裝"

#: app/flatpak-builtins-info.c:57
msgid "Show system-wide installations"
msgstr "顯示系統層級的安裝"

#: app/flatpak-builtins-info.c:58
msgid "Show specific system-wide installations"
msgstr "顯示指定的系統層級安裝"

#: app/flatpak-builtins-info.c:59 app/flatpak-builtins-remote-info.c:59
msgid "Show ref"
msgstr "顯示參照"

#: app/flatpak-builtins-info.c:60 app/flatpak-builtins-remote-info.c:60
msgid "Show commit"
msgstr "顯示提交"

#: app/flatpak-builtins-info.c:61
msgid "Show origin"
msgstr "顯示來源"

#: app/flatpak-builtins-info.c:62
msgid "Show size"
msgstr "顯示大小"

#: app/flatpak-builtins-info.c:63 app/flatpak-builtins-remote-info.c:62
msgid "Show metadata"
msgstr "顯示中介資料"

#: app/flatpak-builtins-info.c:64 app/flatpak-builtins-remote-info.c:63
msgid "Show runtime"
msgstr "顯示執行時期環境"

#: app/flatpak-builtins-info.c:65 app/flatpak-builtins-remote-info.c:64
msgid "Show sdk"
msgstr "顯示 SDK"

#: app/flatpak-builtins-info.c:66
msgid "Show permissions"
msgstr "顯示權限"

#: app/flatpak-builtins-info.c:67
msgid "Query file access"
msgstr "查詢檔案存取"

#: app/flatpak-builtins-info.c:67 app/flatpak-builtins-install.c:82
#: app/flatpak-builtins-install.c:88 app/flatpak-builtins-preinstall.c:68
#: app/flatpak-builtins-run.c:182 app/flatpak-builtins-run.c:184
#: app/flatpak-builtins-update.c:67 app/flatpak-builtins-update.c:71
msgid "PATH"
msgstr "PATH"

#: app/flatpak-builtins-info.c:68
msgid "Show extensions"
msgstr "顯示擴充"

#: app/flatpak-builtins-info.c:69
msgid "Show location"
msgstr "顯示位置"

#: app/flatpak-builtins-info.c:116
msgid "NAME [BRANCH] - Get info about an installed app or runtime"
msgstr "NAME [BRANCH] - 取得已安裝程式或執行時期環境的相關資訊"

#: app/flatpak-builtins-info.c:123 app/flatpak-builtins-remote-add.c:317
#: app/flatpak-builtins-remote-delete.c:63
msgid "NAME must be specified"
msgstr "必須指定 NAME"

#: app/flatpak-builtins-info.c:196
msgid "ref not present in origin"
msgstr "參照不在來源中"

#: app/flatpak-builtins-info.c:211 app/flatpak-builtins-remote-info.c:217
#, c-format
msgid "Warning: Commit has no flatpak metadata\n"
msgstr "警告：提交中沒有 flatpak 中介資料\n"

#: app/flatpak-builtins-info.c:217 app/flatpak-builtins-info.c:259
#: app/flatpak-builtins-info.c:455 app/flatpak-builtins-info.c:513
#: app/flatpak-builtins-remote-info.c:236
#: app/flatpak-builtins-remote-info.c:271
msgid "ID:"
msgstr "ID："

#: app/flatpak-builtins-info.c:218 app/flatpak-builtins-info.c:260
#: app/flatpak-builtins-remote-info.c:237
#: app/flatpak-builtins-remote-info.c:272
msgid "Ref:"
msgstr "參照："

#: app/flatpak-builtins-info.c:219 app/flatpak-builtins-info.c:261
#: app/flatpak-builtins-remote-info.c:238
#: app/flatpak-builtins-remote-info.c:273
msgid "Arch:"
msgstr "架構："

#: app/flatpak-builtins-info.c:220 app/flatpak-builtins-info.c:262
#: app/flatpak-builtins-remote-info.c:239
#: app/flatpak-builtins-remote-info.c:274
msgid "Branch:"
msgstr "分支："

#: app/flatpak-builtins-info.c:222 app/flatpak-builtins-info.c:264
#: app/flatpak-builtins-remote-info.c:241
#: app/flatpak-builtins-remote-info.c:276
msgid "Version:"
msgstr "版本："

#: app/flatpak-builtins-info.c:224 app/flatpak-builtins-info.c:266
#: app/flatpak-builtins-remote-info.c:243
#: app/flatpak-builtins-remote-info.c:278
msgid "License:"
msgstr "授權條款："

#: app/flatpak-builtins-info.c:226 app/flatpak-builtins-info.c:269
#: app/flatpak-builtins-remote-info.c:245
#: app/flatpak-builtins-remote-info.c:280
msgid "Collection:"
msgstr "收藏："

#: app/flatpak-builtins-info.c:227 app/flatpak-builtins-info.c:270
#: app/flatpak-builtins-info.c:458 app/flatpak-builtins-info.c:516
msgid "Installation:"
msgstr "安裝："

#: app/flatpak-builtins-info.c:228 app/flatpak-builtins-info.c:271
#: app/flatpak-builtins-info.c:459 app/flatpak-builtins-info.c:517
#: app/flatpak-builtins-remote-info.c:249
#: app/flatpak-builtins-remote-info.c:284
#, fuzzy
msgid "Installed Size:"
msgstr "已安裝大小："

#: app/flatpak-builtins-info.c:231 app/flatpak-builtins-info.c:279
#: app/flatpak-builtins-remote-info.c:252
#: app/flatpak-builtins-remote-info.c:288
msgid "Runtime:"
msgstr "執行時期環境："

#: app/flatpak-builtins-info.c:232 app/flatpak-builtins-info.c:288
#: app/flatpak-builtins-remote-info.c:253
#: app/flatpak-builtins-remote-info.c:293
msgid "Sdk:"
msgstr "SDK："

#: app/flatpak-builtins-info.c:235 app/flatpak-builtins-info.c:313
#: app/flatpak-builtins-remote-info.c:256
#: app/flatpak-builtins-remote-info.c:319
msgid "Date:"
msgstr "日期："

#: app/flatpak-builtins-info.c:237 app/flatpak-builtins-info.c:311
#: app/flatpak-builtins-remote-info.c:258
#: app/flatpak-builtins-remote-info.c:317
msgid "Subject:"
msgstr "主題："

#: app/flatpak-builtins-info.c:240 app/flatpak-builtins-info.c:295
msgid "Active commit:"
msgstr "活躍提交："

#: app/flatpak-builtins-info.c:241 app/flatpak-builtins-info.c:298
msgid "Latest commit:"
msgstr "最近提交："

#: app/flatpak-builtins-info.c:244 app/flatpak-builtins-info.c:303
#: app/flatpak-builtins-info.c:457 app/flatpak-builtins-info.c:515
#: app/flatpak-builtins-remote-info.c:259
#: app/flatpak-builtins-remote-info.c:298
msgid "Commit:"
msgstr "提交："

#: app/flatpak-builtins-info.c:246 app/flatpak-builtins-info.c:308
#: app/flatpak-builtins-remote-info.c:261
#: app/flatpak-builtins-remote-info.c:303
msgid "Parent:"
msgstr "上層："

#: app/flatpak-builtins-info.c:248 app/flatpak-builtins-info.c:321
msgid "Alt-id:"
msgstr "Alt-id："

#: app/flatpak-builtins-info.c:250 app/flatpak-builtins-info.c:325
#: app/flatpak-builtins-remote-info.c:263
#: app/flatpak-builtins-remote-info.c:308
msgid "End-of-life:"
msgstr "End-of-life："

#: app/flatpak-builtins-info.c:252 app/flatpak-builtins-info.c:330
#: app/flatpak-builtins-remote-info.c:265
#: app/flatpak-builtins-remote-info.c:313
msgid "End-of-life-rebase:"
msgstr "End-of-life-rebase:"

#: app/flatpak-builtins-info.c:254 app/flatpak-builtins-info.c:317
msgid "Subdirectories:"
msgstr "子目錄："

#: app/flatpak-builtins-info.c:255 app/flatpak-builtins-info.c:454
#: app/flatpak-builtins-info.c:512
msgid "Extension:"
msgstr "擴充："

#: app/flatpak-builtins-info.c:267 app/flatpak-builtins-info.c:456
#: app/flatpak-builtins-info.c:514
msgid "Origin:"
msgstr "來源："

#: app/flatpak-builtins-info.c:460 app/flatpak-builtins-info.c:522
msgid "Subpaths:"
msgstr "子路徑："

#: app/flatpak-builtins-info.c:478
msgid "unmaintained"
msgstr "已不維護"

#: app/flatpak-builtins-info.c:480 app/flatpak-builtins-info.c:482
msgid "unknown"
msgstr "未知"

#: app/flatpak-builtins-install.c:68 app/flatpak-builtins-preinstall.c:57
msgid "Don't pull, only install from local cache"
msgstr "不要拉入，僅從本機快取中安裝"

#: app/flatpak-builtins-install.c:69 app/flatpak-builtins-preinstall.c:58
#: app/flatpak-builtins-update.c:60
msgid "Don't deploy, only download to local cache"
msgstr "不要布署，僅下載到本機快取"

#: app/flatpak-builtins-install.c:70 app/flatpak-builtins-preinstall.c:59
msgid "Don't install related refs"
msgstr "不要安裝相關的參照"

#: app/flatpak-builtins-install.c:71 app/flatpak-builtins-preinstall.c:60
#: app/flatpak-builtins-update.c:62
msgid "Don't verify/install runtime dependencies"
msgstr "不要核驗或安裝執行時期環境依賴"

#: app/flatpak-builtins-install.c:72
msgid "Don't automatically pin explicit installs"
msgstr ""

#: app/flatpak-builtins-install.c:73 app/flatpak-builtins-preinstall.c:61
#: app/flatpak-builtins-update.c:63
msgid "Don't use static deltas"
msgstr "不要使用靜態增減檔"

#: app/flatpak-builtins-install.c:76 app/flatpak-builtins-preinstall.c:62
msgid "Additionally install the SDK used to build the given refs"
msgstr ""

#: app/flatpak-builtins-install.c:77 app/flatpak-builtins-preinstall.c:63
msgid ""
"Additionally install the debug info for the given refs and their dependencies"
msgstr ""

#: app/flatpak-builtins-install.c:78
msgid "Assume LOCATION is a .flatpak single-file bundle"
msgstr "假定 LOCATION 是 .flatpak 單一檔案套組"

#: app/flatpak-builtins-install.c:79
msgid "Assume LOCATION is a .flatpakref application description"
msgstr "假定 LOCATION 是 .flatpakref 應用程式描述"

#: app/flatpak-builtins-install.c:80
msgid "Assume LOCATION is containers-transports(5) reference to an OCI image"
msgstr ""

#: app/flatpak-builtins-install.c:81
msgid "Check bundle signatures with GPG key from FILE (- for stdin)"
msgstr "取用 FILE 作為 GPG 金鑰來檢查套組簽章（- 代表 stdin）"

#: app/flatpak-builtins-install.c:82
msgid "Only install this subpath"
msgstr "僅安裝此子路徑"

#: app/flatpak-builtins-install.c:83 app/flatpak-builtins-preinstall.c:64
#: app/flatpak-builtins-uninstall.c:63 app/flatpak-builtins-update.c:68
msgid "Automatically answer yes for all questions"
msgstr "自動為所有問題回答 yes"

#: app/flatpak-builtins-install.c:84 app/flatpak-builtins-preinstall.c:65
msgid "Uninstall first if already installed"
msgstr "若已經安裝則先解除安裝"

#: app/flatpak-builtins-install.c:85 app/flatpak-builtins-preinstall.c:66
#: app/flatpak-builtins-uninstall.c:64 app/flatpak-builtins-update.c:69
msgid "Produce minimal output and don't ask questions"
msgstr "輸出最少內容，且不詢問問題"

#: app/flatpak-builtins-install.c:86
msgid "Update install if already installed"
msgstr "若已經安裝則更新安裝"

#. Translators: A sideload is when you install from a local USB drive rather than the Internet.
#: app/flatpak-builtins-install.c:88 app/flatpak-builtins-preinstall.c:68
#: app/flatpak-builtins-update.c:71
msgid "Use this local repo for sideloads"
msgstr "使用此本機軟體庫側載"

#: app/flatpak-builtins-install.c:178
msgid "Bundle filename must be specified"
msgstr "必須指定套組檔名"

#: app/flatpak-builtins-install.c:188
msgid "Remote bundles are not supported"
msgstr "不支援遠端套組"

#: app/flatpak-builtins-install.c:231
msgid "Filename or uri must be specified"
msgstr "必須指定檔名或 URI"

#: app/flatpak-builtins-install.c:295
#, fuzzy
msgid "Image location must be specified"
msgstr "必須指定至少一個 REF"

#: app/flatpak-builtins-install.c:345
msgid "[LOCATION/REMOTE] [REF…] - Install applications or runtimes"
msgstr "[LOCATION/REMOTE] [REF…] - 安裝應用程式或執行時期"

#: app/flatpak-builtins-install.c:378
msgid "At least one REF must be specified"
msgstr "必須指定至少一個 REF"

#: app/flatpak-builtins-install.c:392
#, c-format
msgid "Looking for matches…\n"
msgstr "正在尋找符合項目…\n"

#: app/flatpak-builtins-install.c:513
#, fuzzy, c-format
msgid "No remote refs found for ‘%s’"
msgstr "沒有與「%s」相似的遠端參照"

#: app/flatpak-builtins-install.c:573 app/flatpak-builtins-uninstall.c:405
#: common/flatpak-ref-utils.c:689 common/flatpak-ref-utils.c:1595
#, c-format
msgid "Invalid branch %s: %s"
msgstr "無效的 %s 分支：%s"

#: app/flatpak-builtins-install.c:606
#, c-format
msgid "Nothing matches %s in local repository for remote %s"
msgstr "「%2$s」遠端的本機軟體庫中沒有項目符合「%1$s」"

#: app/flatpak-builtins-install.c:608
#, c-format
msgid "Nothing matches %s in remote %s"
msgstr "%2$s 遠端沒有項目符合 %1$s"

#: app/flatpak-builtins-install.c:629
#, c-format
msgid "Skipping: %s\n"
msgstr "正在略過：%s\n"

#: app/flatpak-builtins-kill.c:110
#, c-format
msgid "%s is not running"
msgstr "%s 未在執行"

#: app/flatpak-builtins-kill.c:136
msgid "INSTANCE - Stop a running application"
msgstr "INSTANCE - 停止運行中的應用程式"

#: app/flatpak-builtins-kill.c:144 app/flatpak-builtins-ps.c:256
msgid "Extra arguments given"
msgstr "給予額外的引數"

#: app/flatpak-builtins-kill.c:150
msgid "Must specify the app to kill"
msgstr "必須指定要截殺的程式"

#: app/flatpak-builtins-list.c:47
msgid "Show extra information"
msgstr "顯示額外資訊"

#: app/flatpak-builtins-list.c:48
msgid "List installed runtimes"
msgstr "列出已安裝的執行時期環境"

#: app/flatpak-builtins-list.c:49
msgid "List installed applications"
msgstr "列出已安裝的應用程式"

#: app/flatpak-builtins-list.c:50
msgid "Arch to show"
msgstr "要顯示的架構"

#: app/flatpak-builtins-list.c:51 app/flatpak-builtins-remote-ls.c:57
msgid "List all refs (including locale/debug)"
msgstr "列出所有參照（包含語言地區/除錯）"

#: app/flatpak-builtins-list.c:53 app/flatpak-builtins-remote-ls.c:58
msgid "List all applications using RUNTIME"
msgstr "列出使用 RUNTIME 的所有應用程式"

#: app/flatpak-builtins-list.c:59 app/flatpak-builtins-remote-list.c:51
#: app/flatpak-builtins-remote-ls.c:68 app/flatpak-builtins-search.c:44
msgid "Name"
msgstr "名稱"

#: app/flatpak-builtins-list.c:59 app/flatpak-builtins-remote-list.c:51
#: app/flatpak-builtins-remote-ls.c:68 app/flatpak-builtins-search.c:44
msgid "Show the name"
msgstr "顯示名稱"

#: app/flatpak-builtins-list.c:60 app/flatpak-builtins-remote-list.c:60
#: app/flatpak-builtins-remote-ls.c:69 app/flatpak-builtins-search.c:45
msgid "Description"
msgstr "描述"

#: app/flatpak-builtins-list.c:60 app/flatpak-builtins-remote-ls.c:69
#: app/flatpak-builtins-search.c:45
msgid "Show the description"
msgstr "顯示描述"

#: app/flatpak-builtins-list.c:61 app/flatpak-builtins-remote-ls.c:70
#: app/flatpak-builtins-search.c:46
msgid "Application ID"
msgstr "應用程式 ID"

#: app/flatpak-builtins-list.c:61 app/flatpak-builtins-ps.c:52
#: app/flatpak-builtins-remote-ls.c:70 app/flatpak-builtins-search.c:46
msgid "Show the application ID"
msgstr "顯示應用程式 ID"

#: app/flatpak-builtins-list.c:62 app/flatpak-builtins-remote-ls.c:71
#: app/flatpak-builtins-search.c:47
msgid "Show the version"
msgstr "顯示版本"

#: app/flatpak-builtins-list.c:65 app/flatpak-builtins-ps.c:56
#: app/flatpak-builtins-remote-ls.c:77
msgid "Runtime"
msgstr "執行時期環境"

#: app/flatpak-builtins-list.c:65
msgid "Show the used runtime"
msgstr "顯示使用的執行時期"

#: app/flatpak-builtins-list.c:66 app/flatpak-builtins-remote-ls.c:74
msgid "Show the origin remote"
msgstr "顯示來源遠端"

#: app/flatpak-builtins-list.c:67
msgid "Show the installation"
msgstr "顯示安裝"

#: app/flatpak-builtins-list.c:69
msgid "Active commit"
msgstr "活躍的提交"

#: app/flatpak-builtins-list.c:69 app/flatpak-builtins-remote-ls.c:76
msgid "Show the active commit"
msgstr "顯示活躍的提交"

#: app/flatpak-builtins-list.c:70
msgid "Latest commit"
msgstr "最近的提交"

#: app/flatpak-builtins-list.c:70
msgid "Show the latest commit"
msgstr "顯示最近的提交"

#: app/flatpak-builtins-list.c:71 app/flatpak-builtins-remote-ls.c:78
msgid "Installed size"
msgstr "安裝後大小"

#: app/flatpak-builtins-list.c:71 app/flatpak-builtins-remote-ls.c:78
msgid "Show the installed size"
msgstr "顯示安裝後大小"

#: app/flatpak-builtins-list.c:72 app/flatpak-builtins-remote-list.c:58
#: app/flatpak-builtins-remote-ls.c:80 app/flatpak-builtins-repo.c:340
msgid "Options"
msgstr "選項"

#: app/flatpak-builtins-list.c:72 app/flatpak-builtins-remote-list.c:58
#: app/flatpak-builtins-remote-ls.c:80
msgid "Show options"
msgstr "顯示選項"

#: app/flatpak-builtins-list.c:180
#, fuzzy, c-format
msgid "Unable to load details of %s: %s"
msgstr "無法從遠端載入中介資料 %s：%s"

#: app/flatpak-builtins-list.c:190
#, fuzzy, c-format
msgid "Unable to inspect current version of %s: %s"
msgstr "無法建立同步管道"

#: app/flatpak-builtins-list.c:408
msgid " - List installed apps and/or runtimes"
msgstr " - 列出已安裝的程式與或執行時期環境"

#: app/flatpak-builtins-make-current.c:38
msgid "Arch to make current for"
msgstr "目前要製作的架構"

#: app/flatpak-builtins-make-current.c:58
msgid "APP BRANCH - Make branch of application current"
msgstr "APP BRANCH - 製作目前應用程式的分支"

#: app/flatpak-builtins-make-current.c:69 app/flatpak-builtins-run.c:260
msgid "APP must be specified"
msgstr "必須指定 APP"

#: app/flatpak-builtins-make-current.c:84
msgid "BRANCH must be specified"
msgstr "必須指定 BRANCH"

#: app/flatpak-builtins-make-current.c:97
#, c-format
msgid "App %s branch %s is not installed"
msgstr "未安裝 %s 程式的 %s 分支"

#: app/flatpak-builtins-mask.c:42
msgid "Remove matching masks"
msgstr "移除符合的遮罩"

#: app/flatpak-builtins-mask.c:54
msgid ""
"[PATTERN…] - disable updates and automatic installation matching patterns"
msgstr "[PATTERN…] - 停用符合 PATTERN 的更新及自動安裝"

#: app/flatpak-builtins-mask.c:73
#, c-format
msgid "No masked patterns\n"
msgstr "沒有加上遮罩的模式\n"

#: app/flatpak-builtins-mask.c:78
#, c-format
msgid "Masked patterns:\n"
msgstr "加上遮罩的模式：\n"

#: app/flatpak-builtins-override.c:42
msgid "Remove existing overrides"
msgstr "移除既有的凌駕值"

#: app/flatpak-builtins-override.c:43
msgid "Show existing overrides"
msgstr "顯示既有的凌駕值"

#: app/flatpak-builtins-override.c:59
msgid "[APP] - Override settings [for application]"
msgstr "[APP] - 凌駕 [對象應用程式] 設定值"

#: app/flatpak-builtins-permission-list.c:143
msgid "[TABLE] [ID] - List permissions"
msgstr "[TABLE] [ID] - 列出權限"

#: app/flatpak-builtins-permission-list.c:179
#: app/flatpak-builtins-permission-show.c:142
msgid "Table"
msgstr "表格"

#: app/flatpak-builtins-permission-list.c:180
#: app/flatpak-builtins-permission-show.c:143
msgid "Object"
msgstr "物件"

#: app/flatpak-builtins-permission-list.c:181
#: app/flatpak-builtins-permission-show.c:144
msgid "App"
msgstr "程式"

#: app/flatpak-builtins-permission-list.c:183
#: app/flatpak-builtins-permission-show.c:146
msgid "Data"
msgstr "資料"

#: app/flatpak-builtins-permission-remove.c:120
msgid "TABLE ID [APP_ID] - Remove item from permission store"
msgstr "TABLE ID [APP_ID] - 從權限儲存移除項目"

#: app/flatpak-builtins-permission-remove.c:129
#: app/flatpak-builtins-permission-set.c:120
msgid "Too few arguments"
msgstr "引數過少"

#: app/flatpak-builtins-permission-reset.c:43
msgid "Reset all permissions"
msgstr "重設所有權限"

#: app/flatpak-builtins-permission-reset.c:144
msgid "APP_ID - Reset permissions for an app"
msgstr "APP_ID - 重設程式的權限"

#: app/flatpak-builtins-permission-reset.c:153
#: app/flatpak-builtins-permission-show.c:124
msgid "Wrong number of arguments"
msgstr "引數數量錯誤"

#: app/flatpak-builtins-permission-set.c:42
msgid "Associate DATA with the entry"
msgstr "關聯 DATA 至項目"

#: app/flatpak-builtins-permission-set.c:42
msgid "DATA"
msgstr "DATA"

#: app/flatpak-builtins-permission-set.c:111
msgid "TABLE ID APP_ID [PERMISSION...] - Set permissions"
msgstr "TABLE ID APP_ID [PERMISSION...] - 設定權限"

#: app/flatpak-builtins-permission-set.c:132
#, c-format
msgid "Failed to parse '%s' as GVariant: "
msgstr "無法將「%s」當作 GVariant 解析： "

#: app/flatpak-builtins-permission-show.c:115
msgid "APP_ID - Show permissions for an app"
msgstr "APP_ID - 顯示程式的權限"

#: app/flatpak-builtins-pin.c:44
#, fuzzy
msgid "Remove matching pins"
msgstr "移除符合的遮罩"

#: app/flatpak-builtins-pin.c:56
#, fuzzy
msgid "[PATTERN…] - disable automatic removal of runtimes matching patterns"
msgstr "[PATTERN…] - 停用符合 PATTERN 的更新及自動安裝"

#: app/flatpak-builtins-pin.c:75
#, fuzzy, c-format
msgid "No pinned patterns\n"
msgstr "沒有加上遮罩的模式\n"

#: app/flatpak-builtins-pin.c:80
#, fuzzy, c-format
msgid "Pinned patterns:\n"
msgstr "加上遮罩的模式：\n"

#: app/flatpak-builtins-preinstall.c:80
msgid "- Install flatpaks that are part of the operating system"
msgstr ""

#: app/flatpak-builtins-preinstall.c:118
#, c-format
msgid "Nothing to do.\n"
msgstr "無事可做。\n"

#: app/flatpak-builtins-ps.c:49
msgid "Instance"
msgstr "實體"

#: app/flatpak-builtins-ps.c:49
msgid "Show the instance ID"
msgstr "顯示實體 ID"

#: app/flatpak-builtins-ps.c:50 app/flatpak-builtins-run.c:178
msgid "PID"
msgstr "PID"

#: app/flatpak-builtins-ps.c:50
msgid "Show the PID of the wrapper process"
msgstr "顯示包裝器行程的 PID"

#: app/flatpak-builtins-ps.c:51
msgid "Child-PID"
msgstr "Child-PID"

#: app/flatpak-builtins-ps.c:51
msgid "Show the PID of the sandbox process"
msgstr "顯示沙盒行程的 PID"

#: app/flatpak-builtins-ps.c:54 app/flatpak-builtins-search.c:48
msgid "Show the application branch"
msgstr "顯示應用程式分支"

#: app/flatpak-builtins-ps.c:55
msgid "Show the application commit"
msgstr "顯示應用程式提交"

#: app/flatpak-builtins-ps.c:56
msgid "Show the runtime ID"
msgstr "顯示執行時期環境 ID"

#: app/flatpak-builtins-ps.c:57
msgid "R.-Branch"
msgstr "R.-Branch"

#: app/flatpak-builtins-ps.c:57
msgid "Show the runtime branch"
msgstr "顯示執行時期環境分支"

#: app/flatpak-builtins-ps.c:58
msgid "R.-Commit"
msgstr "R.-Commit"

#: app/flatpak-builtins-ps.c:58
msgid "Show the runtime commit"
msgstr "顯示執行時期環境提交"

#: app/flatpak-builtins-ps.c:59
msgid "Active"
msgstr "活躍"

#: app/flatpak-builtins-ps.c:59
msgid "Show whether the app is active"
msgstr "顯示 App 是否活躍"

#: app/flatpak-builtins-ps.c:60
msgid "Background"
msgstr "背景"

#: app/flatpak-builtins-ps.c:60
msgid "Show whether the app is background"
msgstr "顯示 App 是否為背景"

#: app/flatpak-builtins-ps.c:246
msgid " - Enumerate running sandboxes"
msgstr " - 枚舉正在執行的沙盒"

#: app/flatpak-builtins-remote-add.c:66
msgid "Do nothing if the provided remote exists"
msgstr "若提供的遠端存在的話，則不要做任何事情"

#: app/flatpak-builtins-remote-add.c:67
msgid "LOCATION specifies a configuration file, not the repo location"
msgstr "LOCATION 用來指定組態檔，而非軟體庫位置"

#: app/flatpak-builtins-remote-add.c:72 app/flatpak-builtins-remote-modify.c:78
msgid "Disable GPG verification"
msgstr "停用 GPG 驗證"

#: app/flatpak-builtins-remote-add.c:73 app/flatpak-builtins-remote-modify.c:79
msgid "Mark the remote as don't enumerate"
msgstr "將遠端標記為不進行枚舉"

#: app/flatpak-builtins-remote-add.c:74 app/flatpak-builtins-remote-modify.c:80
msgid "Mark the remote as don't use for deps"
msgstr "將遠端標記為不做為依賴"

#: app/flatpak-builtins-remote-add.c:75 app/flatpak-builtins-remote-modify.c:81
msgid "Set priority (default 1, higher is more prioritized)"
msgstr "設定優先權（預設為 1，數字愈大優先權愈高）"

#: app/flatpak-builtins-remote-add.c:75 app/flatpak-builtins-remote-modify.c:81
msgid "PRIORITY"
msgstr "PRIORITY"

#: app/flatpak-builtins-remote-add.c:76
#, fuzzy
msgid "The named subset to use for this remote"
msgstr "用於此遠端的好讀名稱"

#: app/flatpak-builtins-remote-add.c:76 app/flatpak-builtins-remote-modify.c:71
msgid "SUBSET"
msgstr ""

#: app/flatpak-builtins-remote-add.c:77 app/flatpak-builtins-remote-modify.c:82
msgid "A nice name to use for this remote"
msgstr "用於此遠端的好讀名稱"

#: app/flatpak-builtins-remote-add.c:78 app/flatpak-builtins-remote-modify.c:83
msgid "A one-line comment for this remote"
msgstr "此遠端的一列評註"

#: app/flatpak-builtins-remote-add.c:79 app/flatpak-builtins-remote-modify.c:84
msgid "A full-paragraph description for this remote"
msgstr "此遠端的整段描述"

#: app/flatpak-builtins-remote-add.c:80 app/flatpak-builtins-remote-modify.c:85
msgid "URL for a website for this remote"
msgstr "此遠端的網站 URL"

#: app/flatpak-builtins-remote-add.c:81 app/flatpak-builtins-remote-modify.c:86
msgid "URL for an icon for this remote"
msgstr "此遠端的圖示 URL"

#: app/flatpak-builtins-remote-add.c:82 app/flatpak-builtins-remote-modify.c:87
msgid "Default branch to use for this remote"
msgstr "用於此遠端的預設分支"

#: app/flatpak-builtins-remote-add.c:84 app/flatpak-builtins-remote-modify.c:89
msgid "Import GPG key from FILE (- for stdin)"
msgstr "取用 FILE 作為 GPG 金鑰匯入（- 代表 stdin）"

#: app/flatpak-builtins-remote-add.c:85 app/flatpak-builtins-remote-modify.c:90
msgid "Load signatures from URL"
msgstr ""

#: app/flatpak-builtins-remote-add.c:86 app/flatpak-builtins-remote-modify.c:92
msgid "Set path to local filter FILE"
msgstr "設定本機過濾器 FILE 的路徑"

#: app/flatpak-builtins-remote-add.c:87 app/flatpak-builtins-remote-modify.c:93
msgid "Disable the remote"
msgstr "停用遠端"

#: app/flatpak-builtins-remote-add.c:88 app/flatpak-builtins-remote-modify.c:94
msgid "Name of authenticator"
msgstr "身分核對器名稱"

#: app/flatpak-builtins-remote-add.c:90 app/flatpak-builtins-remote-modify.c:96
msgid "Autoinstall authenticator"
msgstr "自動安裝身分核對器"

#: app/flatpak-builtins-remote-add.c:91 app/flatpak-builtins-remote-modify.c:97
msgid "Don't autoinstall authenticator"
msgstr "不自動安裝身分核對器"

#: app/flatpak-builtins-remote-add.c:92 app/flatpak-builtins-remote-modify.c:99
msgid "Don't follow the redirect set in the summary file"
msgstr ""

#: app/flatpak-builtins-remote-add.c:261 app/flatpak-builtins-remote-add.c:268
#, c-format
msgid "Can't load uri %s: %s\n"
msgstr "無法載入 URI %s：%s\n"

#: app/flatpak-builtins-remote-add.c:276 common/flatpak-dir.c:4643
#, c-format
msgid "Can't load file %s: %s\n"
msgstr "無法載入 %s 檔案：%s\n"

#: app/flatpak-builtins-remote-add.c:304
msgid "NAME LOCATION - Add a remote repository"
msgstr "NAME LOCATION - 新增遠端軟體庫"

#: app/flatpak-builtins-remote-add.c:331
msgid "GPG verification is required if collections are enabled"
msgstr "若有啟用收藏，則必須使用 GPG 驗證"

#: app/flatpak-builtins-remote-add.c:393
#, c-format
msgid "Remote %s already exists"
msgstr "遠端 %s 已經存在"

#: app/flatpak-builtins-remote-add.c:405
#: app/flatpak-builtins-remote-modify.c:340
#, c-format
msgid "Invalid authenticator name %s"
msgstr "無效的身分核對器名稱 %s"

#: app/flatpak-builtins-remote-add.c:422
#, c-format
msgid "Warning: Could not update extra metadata for '%s': %s\n"
msgstr "警告：無法更新「%s」的額外中介資料：%s\n"

#: app/flatpak-builtins-remote-delete.c:39
msgid "Remove remote even if in use"
msgstr "即使在使用中也要移除遠端"

#: app/flatpak-builtins-remote-delete.c:53
msgid "NAME - Delete a remote repository"
msgstr "NAME - 刪除遠端軟體庫"

#: app/flatpak-builtins-remote-delete.c:100
#, c-format
msgid "The following refs are installed from remote '%s':"
msgstr "以下參照是從「%s」遠端安裝的："

#: app/flatpak-builtins-remote-delete.c:101
msgid "Remove them?"
msgstr "是否移除？"

#: app/flatpak-builtins-remote-delete.c:103
#, c-format
msgid "Can't remove remote '%s' with installed refs"
msgstr "無法移除有安裝的參照的「%s」遠端"

#: app/flatpak-builtins-remote-info.c:55
msgid "Commit to show info for"
msgstr "提交要顯示的資訊"

#: app/flatpak-builtins-remote-info.c:58
msgid "Display log"
msgstr "顯示紀錄檔"

#: app/flatpak-builtins-remote-info.c:61
msgid "Show parent"
msgstr "顯示上層"

#: app/flatpak-builtins-remote-info.c:65 app/flatpak-builtins-remote-ls.c:60
msgid "Use local caches even if they are stale"
msgstr "就算已經過期，仍使用本機快取"

#. Translators: A sideload is when you install from a local USB drive rather than the Internet.
#: app/flatpak-builtins-remote-info.c:67 app/flatpak-builtins-remote-ls.c:62
msgid "Only list refs available as sideloads"
msgstr "只列出能夠以側載使用的參照"

#: app/flatpak-builtins-remote-info.c:114
msgid ""
" REMOTE REF - Show information about an application or runtime in a remote"
msgstr " REMOTE REF - 顯示遠端中應用程式或執行時期環境的相關資訊"

#: app/flatpak-builtins-remote-info.c:125
msgid "REMOTE and REF must be specified"
msgstr "必須指定 REMOTE 與 REF"

#: app/flatpak-builtins-remote-info.c:247
#: app/flatpak-builtins-remote-info.c:282
#, fuzzy
msgid "Download Size:"
msgstr "下載大小："

#: app/flatpak-builtins-remote-info.c:267
#: app/flatpak-builtins-remote-info.c:325
msgid "History:"
msgstr "歷史："

#: app/flatpak-builtins-remote-info.c:348
msgid " Commit:"
msgstr " 提交："

#: app/flatpak-builtins-remote-info.c:349
msgid " Subject:"
msgstr " 主旨："

#: app/flatpak-builtins-remote-info.c:350
msgid " Date:"
msgstr " 日期："

#: app/flatpak-builtins-remote-info.c:383
#, c-format
msgid "Warning: Commit %s has no flatpak metadata\n"
msgstr "警告：%s 提交中沒有 flatpak 中介資料\n"

#: app/flatpak-builtins-remote-list.c:43
msgid "Show remote details"
msgstr "顯示遠端詳細資料"

#: app/flatpak-builtins-remote-list.c:44
msgid "Show disabled remotes"
msgstr "顯示已停用的遠端"

#: app/flatpak-builtins-remote-list.c:52
msgid "Title"
msgstr "標題"

#: app/flatpak-builtins-remote-list.c:52
msgid "Show the title"
msgstr "顯示標題"

#: app/flatpak-builtins-remote-list.c:53
msgid "Show the URL"
msgstr "顯示 URL"

#: app/flatpak-builtins-remote-list.c:54
msgid "Show the collection ID"
msgstr "顯示收藏 ID"

#: app/flatpak-builtins-remote-list.c:55 app/flatpak-builtins-repo.c:392
msgid "Subset"
msgstr ""

#: app/flatpak-builtins-remote-list.c:55
#, fuzzy
msgid "Show the subset"
msgstr "顯示參照"

#: app/flatpak-builtins-remote-list.c:56
msgid "Filter"
msgstr "過濾器"

#: app/flatpak-builtins-remote-list.c:56
msgid "Show filter file"
msgstr "顯示過濾器檔案"

#: app/flatpak-builtins-remote-list.c:57
msgid "Priority"
msgstr "優先權"

#: app/flatpak-builtins-remote-list.c:57
msgid "Show the priority"
msgstr "顯示優先權"

#: app/flatpak-builtins-remote-list.c:59
msgid "Comment"
msgstr "評註"

#: app/flatpak-builtins-remote-list.c:59
msgid "Show comment"
msgstr "顯示評註"

#: app/flatpak-builtins-remote-list.c:60
msgid "Show description"
msgstr "顯示描述"

#: app/flatpak-builtins-remote-list.c:61
msgid "Homepage"
msgstr "首頁"

#: app/flatpak-builtins-remote-list.c:61
msgid "Show homepage"
msgstr "顯示首頁"

#: app/flatpak-builtins-remote-list.c:62
msgid "Icon"
msgstr "圖示"

#: app/flatpak-builtins-remote-list.c:62
msgid "Show icon"
msgstr "顯示圖示"

#: app/flatpak-builtins-remote-list.c:231
msgid " - List remote repositories"
msgstr " - 列出遠端軟體庫"

#: app/flatpak-builtins-remote-ls.c:52
msgid "Show arches and branches"
msgstr "顯示架構與分支"

#: app/flatpak-builtins-remote-ls.c:53
msgid "Show only runtimes"
msgstr "僅顯示執行時期環境"

#: app/flatpak-builtins-remote-ls.c:54
msgid "Show only apps"
msgstr "僅顯示程式"

#: app/flatpak-builtins-remote-ls.c:55
msgid "Show only those where updates are available"
msgstr "僅顯示有可用更新的那些項目"

#: app/flatpak-builtins-remote-ls.c:56
msgid "Limit to this arch (* for all)"
msgstr "限制在這種架構（* 代表全部）"

#: app/flatpak-builtins-remote-ls.c:77
msgid "Show the runtime"
msgstr "顯示執行時期環境"

#: app/flatpak-builtins-remote-ls.c:79
msgid "Download size"
msgstr "下載大小"

#: app/flatpak-builtins-remote-ls.c:79
msgid "Show the download size"
msgstr "顯示下載大小"

#: app/flatpak-builtins-remote-ls.c:391
msgid " [REMOTE or URI] - Show available runtimes and applications"
msgstr " [REMOTE 或 URI] - 顯示可用的執行時期環境與應用程式"

#: app/flatpak-builtins-remote-modify.c:67
msgid "Enable GPG verification"
msgstr "啟用 GPG 驗證"

#: app/flatpak-builtins-remote-modify.c:68
msgid "Mark the remote as enumerate"
msgstr "將遠端標記為進行枚舉"

#: app/flatpak-builtins-remote-modify.c:69
msgid "Mark the remote as used for dependencies"
msgstr "將遠端標記為做為依賴"

#: app/flatpak-builtins-remote-modify.c:70
#, fuzzy
msgid "Set a new URL"
msgstr "設定新的 URL"

#: app/flatpak-builtins-remote-modify.c:71
#, fuzzy
msgid "Set a new subset to use"
msgstr "設定新的 URL"

#: app/flatpak-builtins-remote-modify.c:72
msgid "Enable the remote"
msgstr "啟用遠端"

#: app/flatpak-builtins-remote-modify.c:73
msgid "Update extra metadata from the summary file"
msgstr "根據摘要檔案更新額外中介資料"

#: app/flatpak-builtins-remote-modify.c:91
msgid "Disable local filter"
msgstr "停用本機過濾器"

#: app/flatpak-builtins-remote-modify.c:95
msgid "Authenticator options"
msgstr "身分核對器選項"

#: app/flatpak-builtins-remote-modify.c:98
#, fuzzy
msgid "Follow the redirect set in the summary file"
msgstr "根據摘要檔案更新額外中介資料"

#: app/flatpak-builtins-remote-modify.c:306
msgid "NAME - Modify a remote repository"
msgstr "NAME - 修改遠端軟體庫"

#: app/flatpak-builtins-remote-modify.c:316
msgid "Remote NAME must be specified"
msgstr "必須指定遠端的 NAME"

#: app/flatpak-builtins-remote-modify.c:327
#, c-format
msgid "Updating extra metadata from remote summary for %s\n"
msgstr "正在從 %s 的遠端摘要更新額外中介資料\n"

#: app/flatpak-builtins-remote-modify.c:330
#, c-format
msgid "Error updating extra metadata for '%s': %s\n"
msgstr "更新「%s」的額外中介資料時發生錯誤：%s\n"

#: app/flatpak-builtins-remote-modify.c:331
#, c-format
msgid "Could not update extra metadata for %s"
msgstr "無法更新 %s 的額外中介資料"

#: app/flatpak-builtins-repair.c:43
msgid "Don't make any changes"
msgstr "不做任何變更"

#: app/flatpak-builtins-repair.c:44
msgid "Reinstall all refs"
msgstr "重新安裝所有參照"

#: app/flatpak-builtins-repair.c:68
#, c-format
msgid "Object missing: %s.%s\n"
msgstr "物件遺失：%s.%s\n"

#: app/flatpak-builtins-repair.c:76
#, c-format
msgid "Object invalid: %s.%s\n"
msgstr "物件無效：%s.%s\n"

#: app/flatpak-builtins-repair.c:81
#, c-format
msgid "%s, deleting object\n"
msgstr "%s，正在刪除物件\n"

#: app/flatpak-builtins-repair.c:146
#, c-format
msgid "Can't load object %s: %s\n"
msgstr "無法載入物件 %s：%s\n"

#: app/flatpak-builtins-repair.c:228
#, fuzzy, c-format
msgid "Commit invalid %s: %s\n"
msgstr "物件無效：%s.%s\n"

#: app/flatpak-builtins-repair.c:231
#, fuzzy, c-format
msgid "Deleting invalid commit %s: %s\n"
msgstr "無效的 %s 參照提交："

#: app/flatpak-builtins-repair.c:261
#, c-format
msgid "Commit should be marked partial: %s\n"
msgstr ""

#: app/flatpak-builtins-repair.c:264
#, c-format
msgid "Marking commit as partial: %s\n"
msgstr ""

#: app/flatpak-builtins-repair.c:293
#, c-format
msgid "Problems loading data for %s: %s\n"
msgstr "載入 %s 的資料時發生問題：%s\n"

#: app/flatpak-builtins-repair.c:306
#, c-format
msgid "Error reinstalling %s: %s\n"
msgstr "重新安裝 %s 時發生錯誤：%s\n"

#: app/flatpak-builtins-repair.c:327
msgid "- Repair a flatpak installation"
msgstr "- 修復 flatpak 安裝"

#: app/flatpak-builtins-repair.c:406
#, c-format
msgid "Removing non-deployed ref %s…\n"
msgstr "正在移除未布署的參照 %s…\n"

#: app/flatpak-builtins-repair.c:411
#, c-format
msgid "Skipping non-deployed ref %s…\n"
msgstr "正在跳過未布署的參照 %s…\n"

#: app/flatpak-builtins-repair.c:429
#, fuzzy, c-format
msgid "[%d/%d] Verifying %s…\n"
msgstr "正在核驗 %s…\n"

#: app/flatpak-builtins-repair.c:435
#, c-format
msgid "Dry run: "
msgstr ""

#: app/flatpak-builtins-repair.c:440
#, c-format
msgid "Deleting ref %s due to missing objects\n"
msgstr "因為遺失物件，正在刪除 %s 參照\n"

#: app/flatpak-builtins-repair.c:444
#, c-format
msgid "Deleting ref %s due to invalid objects\n"
msgstr "因為物件無效而刪除 %s 參照\n"

#: app/flatpak-builtins-repair.c:448
#, c-format
msgid "Deleting ref %s due to %d\n"
msgstr "因 %2$d 而刪除 %1$s 參照\n"

#: app/flatpak-builtins-repair.c:464
#, c-format
msgid "Checking remotes...\n"
msgstr ""

#: app/flatpak-builtins-repair.c:482
#, c-format
msgid "Remote %s for ref %s is missing\n"
msgstr "%s 遠端（用於 %s 參照）不存在\n"

#: app/flatpak-builtins-repair.c:484
#, c-format
msgid "Remote %s for ref %s is disabled\n"
msgstr "%s 遠端（用於 %s 參照）已停用\n"

#: app/flatpak-builtins-repair.c:490
#, c-format
msgid "Pruning objects\n"
msgstr "正在修除物件\n"

#: app/flatpak-builtins-repair.c:498
#, c-format
msgid "Erasing .removed\n"
msgstr "正在擦除 .removed\n"

#: app/flatpak-builtins-repair.c:524
#, c-format
msgid "Reinstalling refs\n"
msgstr "正在重新安裝參照\n"

#: app/flatpak-builtins-repair.c:526
#, c-format
msgid "Reinstalling removed refs\n"
msgstr "正在重新安裝已移除的參照\n"

#: app/flatpak-builtins-repair.c:551
#, c-format
msgid "While removing appstream for %s: "
msgstr "當移除 %s 的 AppStream 時： "

#: app/flatpak-builtins-repair.c:558
#, c-format
msgid "While deploying appstream for %s: "
msgstr "當布署 %s 的 AppStream 時： "

#: app/flatpak-builtins-repo.c:106
#, c-format
msgid "Repo mode: %s\n"
msgstr "軟體庫模式：%s\n"

#: app/flatpak-builtins-repo.c:113
#, c-format
msgid "Indexed summaries: %s\n"
msgstr ""

#: app/flatpak-builtins-repo.c:113 app/flatpak-builtins-repo.c:139
#: app/flatpak-builtins-repo.c:172
msgid "true"
msgstr "true"

#: app/flatpak-builtins-repo.c:113 app/flatpak-builtins-repo.c:139
#: app/flatpak-builtins-repo.c:172
msgid "false"
msgstr "false"

#: app/flatpak-builtins-repo.c:121
#, c-format
msgid "Subsummaries: "
msgstr ""

#: app/flatpak-builtins-repo.c:136
#, c-format
msgid "Cache version: %d\n"
msgstr ""

#: app/flatpak-builtins-repo.c:139
#, c-format
msgid "Indexed deltas: %s\n"
msgstr ""

#: app/flatpak-builtins-repo.c:142
#, c-format
msgid "Title: %s\n"
msgstr "標題：%s\n"

#: app/flatpak-builtins-repo.c:145
#, c-format
msgid "Comment: %s\n"
msgstr "評註：%s\n"

#: app/flatpak-builtins-repo.c:148
#, c-format
msgid "Description: %s\n"
msgstr "描述：%s\n"

#: app/flatpak-builtins-repo.c:151
#, c-format
msgid "Homepage: %s\n"
msgstr "首頁：%s\n"

#: app/flatpak-builtins-repo.c:154
#, c-format
msgid "Icon: %s\n"
msgstr "圖示：%s\n"

#: app/flatpak-builtins-repo.c:157
#, c-format
msgid "Collection ID: %s\n"
msgstr "收藏 ID：%s\n"

#: app/flatpak-builtins-repo.c:160
#, c-format
msgid "Default branch: %s\n"
msgstr "預設分支：%s\n"

#: app/flatpak-builtins-repo.c:163
#, c-format
msgid "Redirect URL: %s\n"
msgstr "重導 URL：%s\n"

#: app/flatpak-builtins-repo.c:166
#, c-format
msgid "Deploy collection ID: %s\n"
msgstr "布署收藏 ID：%s\n"

#: app/flatpak-builtins-repo.c:169
#, c-format
msgid "Authenticator name: %s\n"
msgstr "身分核對器名稱：%s\n"

#: app/flatpak-builtins-repo.c:172
#, c-format
msgid "Authenticator install: %s\n"
msgstr "身分核對器安裝：%s\n"

#: app/flatpak-builtins-repo.c:180
#, c-format
msgid "GPG key hash: %s\n"
msgstr "GPG 金鑰雜湊碼：%s\n"

#: app/flatpak-builtins-repo.c:184
#, fuzzy, c-format
msgid "%zd summary branches\n"
msgstr "%zd 分支\n"

#: app/flatpak-builtins-repo.c:336
msgid "Installed"
msgstr "已安裝"

#. Translators: Download is used here as a noun
#: app/flatpak-builtins-repo.c:338 app/flatpak-cli-transaction.c:1462
msgid "Download"
msgstr "下載"

#: app/flatpak-builtins-repo.c:339
msgid "Subsets"
msgstr ""

#: app/flatpak-builtins-repo.c:393
msgid "Digest"
msgstr ""

#: app/flatpak-builtins-repo.c:394
#, fuzzy
msgid "History length"
msgstr "歷史："

#: app/flatpak-builtins-repo.c:711
msgid "Print general information about the repository"
msgstr "列印軟體庫的一般資訊"

#: app/flatpak-builtins-repo.c:712
msgid "List the branches in the repository"
msgstr "列出軟體庫中的分支"

#: app/flatpak-builtins-repo.c:713
msgid "Print metadata for a branch"
msgstr "列印分支的中介資料"

#: app/flatpak-builtins-repo.c:714
msgid "Show commits for a branch"
msgstr "顯示分支的提交"

#: app/flatpak-builtins-repo.c:715
#, fuzzy
msgid "Print information about the repo subsets"
msgstr "列印軟體庫的一般資訊"

#: app/flatpak-builtins-repo.c:716
msgid "Limit information to subsets with this prefix"
msgstr ""

#: app/flatpak-builtins-repo.c:732
msgid "LOCATION - Repository maintenance"
msgstr "LOCATION - 軟體庫維護"

#: app/flatpak-builtins-run.c:159
msgid "Command to run"
msgstr "要執行的指令"

#: app/flatpak-builtins-run.c:160
msgid "Directory to run the command in"
msgstr "命令的執行目錄"

#: app/flatpak-builtins-run.c:161
msgid "Branch to use"
msgstr "要使用的分支"

#: app/flatpak-builtins-run.c:162
msgid "Use development runtime"
msgstr "使用開發用執行時期環境"

#: app/flatpak-builtins-run.c:163
msgid "Runtime to use"
msgstr "要使用的執行時期環境"

#: app/flatpak-builtins-run.c:164
msgid "Runtime version to use"
msgstr "要使用的執行時期環境"

#: app/flatpak-builtins-run.c:167
msgid "Log accessibility bus calls"
msgstr "記錄無障礙匯流排呼叫"

#: app/flatpak-builtins-run.c:168
msgid "Don't proxy accessibility bus calls"
msgstr "不要代理無障礙匯流排呼叫"

#: app/flatpak-builtins-run.c:169
msgid "Proxy accessibility bus calls (default except when sandboxed)"
msgstr "代理無障礙匯流排呼叫（除非在沙盒中，否則是預設值）"

#: app/flatpak-builtins-run.c:170
msgid "Don't proxy session bus calls"
msgstr "不要代理工作階段匯流排呼叫"

#: app/flatpak-builtins-run.c:171
msgid "Proxy session bus calls (default except when sandboxed)"
msgstr "代理工作階段匯流排呼叫（除非在沙盒中，否則為預設值）"

#: app/flatpak-builtins-run.c:172
msgid "Don't start portals"
msgstr "不要啟動入口"

#: app/flatpak-builtins-run.c:173
msgid "Enable file forwarding"
msgstr "啟用檔案轉送"

#: app/flatpak-builtins-run.c:174
msgid "Run specified commit"
msgstr "執行指定的提交"

#: app/flatpak-builtins-run.c:175
msgid "Use specified runtime commit"
msgstr "使用指定的執行時期環境提交"

#: app/flatpak-builtins-run.c:176
msgid "Run completely sandboxed"
msgstr "完全在沙盒中執行"

#: app/flatpak-builtins-run.c:178
msgid "Use PID as parent pid for sharing namespaces"
msgstr "將 PID 當作父 PID 以分享命名空間"

#: app/flatpak-builtins-run.c:179
msgid "Make processes visible in parent namespace"
msgstr "讓行程能夠在上層命名空間看見"

#: app/flatpak-builtins-run.c:180
msgid "Share process ID namespace with parent"
msgstr ""

#: app/flatpak-builtins-run.c:181
msgid "Write the instance ID to the given file descriptor"
msgstr ""

#: app/flatpak-builtins-run.c:182
msgid "Use PATH instead of the app's /app"
msgstr ""

#: app/flatpak-builtins-run.c:183
msgid "Use FD instead of the app's /app"
msgstr ""

#: app/flatpak-builtins-run.c:183 app/flatpak-builtins-run.c:185
#: app/flatpak-builtins-run.c:187 app/flatpak-builtins-run.c:188
#: common/flatpak-context.c:2672
msgid "FD"
msgstr ""

#: app/flatpak-builtins-run.c:184
msgid "Use PATH instead of the runtime's /usr"
msgstr ""

#: app/flatpak-builtins-run.c:185
msgid "Use FD instead of the runtime's /usr"
msgstr ""

#: app/flatpak-builtins-run.c:186
#, fuzzy
msgid "Clear all outside environment variables"
msgstr "設定環境變數"

#: app/flatpak-builtins-run.c:187
msgid ""
"Bind mount the file or directory referred to by FD to its canonicalized path"
msgstr ""

#: app/flatpak-builtins-run.c:188
msgid ""
"Bind mount the file or directory referred to by FD read-only to its "
"canonicalized path"
msgstr ""

#: app/flatpak-builtins-run.c:219
msgid "APP [ARGUMENT…] - Run an app"
msgstr "APP [ARGUMENT…] - 執行 App"

#: app/flatpak-builtins-run.c:370
#, c-format
msgid "runtime/%s/%s/%s not installed"
msgstr "執行時期/%s/%s/%s 未安裝"

#: app/flatpak-builtins-run.c:419
msgid "app-fd and app-path cannot both be used"
msgstr ""

#: app/flatpak-builtins-run.c:449
msgid "usr-fd and usr-path cannot both be used"
msgstr ""

#: app/flatpak-builtins-search.c:37
msgid "Arch to search for"
msgstr "要搜尋的架構"

#: app/flatpak-builtins-search.c:49
msgid "Remotes"
msgstr "遠端"

#: app/flatpak-builtins-search.c:49
msgid "Show the remotes"
msgstr "顯示遠端"

#: app/flatpak-builtins-search.c:244
msgid "TEXT - Search remote apps/runtimes for text"
msgstr "TEXT - 搜尋遠端程式或執行時期環境用的文字"

#: app/flatpak-builtins-search.c:255
msgid "TEXT must be specified"
msgstr "必須指定 TEXT"

#: app/flatpak-builtins-search.c:338
msgid "No matches found"
msgstr "找不到符合項目"

#: app/flatpak-builtins-uninstall.c:54
msgid "Arch to uninstall"
msgstr "要解除安裝的架構"

#: app/flatpak-builtins-uninstall.c:55
msgid "Keep ref in local repository"
msgstr "在本機軟體庫中保留參照"

#: app/flatpak-builtins-uninstall.c:56
msgid "Don't uninstall related refs"
msgstr "不要解除安裝相關的參照"

#: app/flatpak-builtins-uninstall.c:57
msgid "Remove files even if running"
msgstr "即使在執行中也要移除檔案"

#: app/flatpak-builtins-uninstall.c:60
msgid "Uninstall all"
msgstr "全部解除安裝"

#: app/flatpak-builtins-uninstall.c:61
msgid "Uninstall unused"
msgstr "解除安裝未使用項目"

#: app/flatpak-builtins-uninstall.c:62
msgid "Delete app data"
msgstr "刪除 App 資料"

#: app/flatpak-builtins-uninstall.c:141
#, c-format
msgid "Delete data for %s?"
msgstr "是否刪除 %s 的資料？"

#: app/flatpak-builtins-uninstall.c:220
#, c-format
msgid "Info: applications using the extension %s%s%s branch %s%s%s:\n"
msgstr ""

#: app/flatpak-builtins-uninstall.c:223
#, fuzzy, c-format
msgid "Info: applications using the runtime %s%s%s branch %s%s%s:\n"
msgstr ""
"\n"
"正在尋找應用程式與執行時期環境"

#: app/flatpak-builtins-uninstall.c:238
#, fuzzy
msgid "Really remove?"
msgstr "遠端"

#: app/flatpak-builtins-uninstall.c:255
#, fuzzy
msgid "[REF…] - Uninstall applications or runtimes"
msgstr "[REF...] - 更新應用程式或執行時期"

#: app/flatpak-builtins-uninstall.c:264
msgid "Must specify at least one REF, --unused, --all or --delete-data"
msgstr "必須指定至少一個 REF、--unused、--all 或 --delete-data"

#: app/flatpak-builtins-uninstall.c:267
msgid "Must not specify REFs when using --all"
msgstr "使用 --all 時則無法指定 REF"

#: app/flatpak-builtins-uninstall.c:270
msgid "Must not specify REFs when using --unused"
msgstr "使用 --unused 時則無法指定 REF"

#: app/flatpak-builtins-uninstall.c:336
#, c-format
msgid ""
"\n"
"These runtimes in installation '%s' are pinned and won't be removed; see "
"flatpak-pin(1):\n"
msgstr ""

#: app/flatpak-builtins-uninstall.c:370
#, c-format
msgid "Nothing unused to uninstall\n"
msgstr "沒有可解除安裝的未使用項目\n"

#: app/flatpak-builtins-uninstall.c:444
#, fuzzy, c-format
msgid "No installed refs found for ‘%s’"
msgstr "找到「%s」的相似已安裝參照："

#: app/flatpak-builtins-uninstall.c:447
#, c-format
msgid " with arch ‘%s’"
msgstr ""

#: app/flatpak-builtins-uninstall.c:449
#, c-format
msgid " with branch ‘%s’"
msgstr ""

#: app/flatpak-builtins-uninstall.c:456
#, fuzzy, c-format
msgid "Warning: %s is not installed\n"
msgstr "%s 的 %s 分支尚未安裝"

#: app/flatpak-builtins-uninstall.c:490
#, c-format
msgid "None of the specified refs are installed"
msgstr ""

#: app/flatpak-builtins-uninstall.c:599
#, c-format
msgid "No app data to delete\n"
msgstr ""

#: app/flatpak-builtins-update.c:56
msgid "Arch to update for"
msgstr "要更新的架構"

#: app/flatpak-builtins-update.c:57
msgid "Commit to deploy"
msgstr "提交至布署"

#: app/flatpak-builtins-update.c:58
msgid "Remove old files even if running"
msgstr "即使在執行中也要移除舊檔案"

#: app/flatpak-builtins-update.c:59
msgid "Don't pull, only update from local cache"
msgstr "不要拉入，僅從本機快取中更新"

#: app/flatpak-builtins-update.c:61
msgid "Don't update related refs"
msgstr "不要更新相關參照"

#: app/flatpak-builtins-update.c:66
msgid "Update appstream for remote"
msgstr "更新遠端的 appstream"

#: app/flatpak-builtins-update.c:67
msgid "Only update this subpath"
msgstr "僅更新此子路徑"

#: app/flatpak-builtins-update.c:90
msgid "[REF…] - Update applications or runtimes"
msgstr "[REF...] - 更新應用程式或執行時期"

#: app/flatpak-builtins-update.c:121
#, fuzzy
msgid "With --commit, only one REF may be specified"
msgstr "必須指定至少一個 REF"

#: app/flatpak-builtins-update.c:162
#, c-format
msgid "Looking for updates…\n"
msgstr "正在尋找更新...\n"

#: app/flatpak-builtins-update.c:215
#, c-format
msgid "Unable to update %s: %s\n"
msgstr "無法更新 %s：%s\n"

#: app/flatpak-builtins-update.c:274
#, fuzzy, c-format
msgid "Nothing to update.\n"
msgstr "無事可做。\n"

#: app/flatpak-builtins-utils.c:337
#, fuzzy, c-format
msgid ""
"Remote ‘%s’ found in multiple installations, unable to proceed in non-"
"interactive mode"
msgstr "在多個安裝中找到「%s」參照：%s。您必須指定一個。"

#: app/flatpak-builtins-utils.c:346
#, c-format
msgid "Remote ‘%s’ found in multiple installations:"
msgstr "在多份安裝中找到「%s」遠端："

#: app/flatpak-builtins-utils.c:347 app/flatpak-builtins-utils.c:442
#: app/flatpak-builtins-utils.c:538 app/flatpak-builtins-utils.c:540
#: app/flatpak-builtins-utils.c:598
msgid "Which do you want to use (0 to abort)?"
msgstr "您想要使用哪一個（0 為中止）？"

#: app/flatpak-builtins-utils.c:349
#, c-format
msgid "No remote chosen to resolve ‘%s’ which exists in multiple installations"
msgstr "沒有為多份安裝中都存在的「%s」遠端選擇解決方式"

#: app/flatpak-builtins-utils.c:358
#, c-format
msgid ""
"Remote \"%s\" not found\n"
"Hint: Use flatpak remote-add to add a remote"
msgstr ""
"找不到「%s」遠端\n"
"提示：使用 flatpak remote-add 加入遠端"

#: app/flatpak-builtins-utils.c:364
#, c-format
msgid "Remote \"%s\" not found in the %s installation"
msgstr "在 %2$s 安裝中找不到「%1$s」遠端"

#: app/flatpak-builtins-utils.c:404
#, c-format
msgid "Multiple refs match ‘%s’, unable to proceed in non-interactive mode"
msgstr ""

#. default to yes on Enter
#: app/flatpak-builtins-utils.c:430
#, c-format
msgid ""
"Found ref ‘%s’ in remote ‘%s’ (%s).\n"
"Use this ref?"
msgstr ""
"找到「%s」參照（位於「%s」遠端）(%s)。\n"
"是否使用此參照？"

#: app/flatpak-builtins-utils.c:434 app/flatpak-builtins-utils.c:444
#: app/flatpak-builtins-utils.c:522 app/flatpak-builtins-utils.c:543
#, c-format
msgid "No ref chosen to resolve matches for ‘%s’"
msgstr "未選擇要解析「%s」之符合項目的參照"

#: app/flatpak-builtins-utils.c:440
#, c-format
msgid "Similar refs found for ‘%s’ in remote ‘%s’ (%s):"
msgstr "在「%2$s」遠端中的「%1$s」找到相似的參照 (%3$s)："

#: app/flatpak-builtins-utils.c:488
#, c-format
msgid ""
"Multiple installed refs match ‘%s’, unable to proceed in non-interactive mode"
msgstr ""

#. default to yes on Enter
#: app/flatpak-builtins-utils.c:518
#, c-format
msgid "Found installed ref ‘%s’ (%s). Is this correct?"
msgstr "找到安裝的參照「%s」(%s)。對嗎？"

#: app/flatpak-builtins-utils.c:534
#, c-format
msgid "All of the above"
msgstr "以上全部"

#: app/flatpak-builtins-utils.c:535
#, c-format
msgid "Similar installed refs found for ‘%s’:"
msgstr "找到「%s」的相似已安裝參照："

#: app/flatpak-builtins-utils.c:579
#, c-format
msgid ""
"Multiple remotes have refs matching ‘%s’, unable to proceed in non-"
"interactive mode"
msgstr ""

#: app/flatpak-builtins-utils.c:597
#, c-format
msgid "Remotes found with refs similar to ‘%s’:"
msgstr "找到參照與「%s」相似的遠端："

#: app/flatpak-builtins-utils.c:600
#, c-format
msgid "No remote chosen to resolve matches for ‘%s’"
msgstr "沒有選擇要解析「%s」符合項目的遠端"

#: app/flatpak-builtins-utils.c:696 app/flatpak-builtins-utils.c:699
#, c-format
msgid "Updating appstream data for user remote %s"
msgstr "正在更新使用者 %s 遠端的 appstream 資料"

#: app/flatpak-builtins-utils.c:706 app/flatpak-builtins-utils.c:709
#, c-format
msgid "Updating appstream data for remote %s"
msgstr "正在更新 %s 遠端的 appstream 資料"

#: app/flatpak-builtins-utils.c:717 app/flatpak-builtins-utils.c:719
msgid "Error updating"
msgstr "更新發生錯誤"

#: app/flatpak-builtins-utils.c:755
#, c-format
msgid "Remote \"%s\" not found"
msgstr "找不到「%s」遠端"

#: app/flatpak-builtins-utils.c:796
#, c-format
msgid "Ambiguous suffix: '%s'."
msgstr "不明的後綴：「%s」。"

#. Translators: don't translate the values
#: app/flatpak-builtins-utils.c:798 app/flatpak-builtins-utils.c:813
msgid "Possible values are :s[tart], :m[iddle], :e[nd] or :f[ull]"
msgstr "值可以是 :s[tart]、:m[iddle]、:e[nd] 或 :f[ull]"

#: app/flatpak-builtins-utils.c:811
#, c-format
msgid "Invalid suffix: '%s'."
msgstr "無效的後綴：「%s」。"

#: app/flatpak-builtins-utils.c:846
#, c-format
msgid "Ambiguous column: %s"
msgstr "不明的欄位：%s"

#: app/flatpak-builtins-utils.c:859
#, c-format
msgid "Unknown column: %s"
msgstr "未知的欄位：%s"

#: app/flatpak-builtins-utils.c:917
msgid "Available columns:\n"
msgstr "可用的欄位：\n"

#: app/flatpak-builtins-utils.c:927
msgid "Show all columns"
msgstr "顯示所有欄位"

#: app/flatpak-builtins-utils.c:928
msgid "Show available columns"
msgstr "顯示可用欄位"

#: app/flatpak-builtins-utils.c:931
msgid "Append :s[tart], :m[iddle], :e[nd] or :f[ull] to change ellipsization"
msgstr "在後方加上 :s[tart]、:m[iddle]、:e[nd] 或 :f[ull] 以變更「…」的使用"

#: app/flatpak-builtins-utils.c:1483
#, c-format
msgid "Unknown scheme in sideload location %s"
msgstr ""

#: app/flatpak-cli-transaction.c:96 app/flatpak-cli-transaction.c:102
#, c-format
msgid "Required runtime for %s (%s) found in remote %s\n"
msgstr "%s (%s) 所要求的執行時期環境在 %s 遠端中有找到\n"

#: app/flatpak-cli-transaction.c:104
msgid "Do you want to install it?"
msgstr "您想要安裝嗎？"

#: app/flatpak-cli-transaction.c:110
#, c-format
msgid "Required runtime for %s (%s) found in remotes:"
msgstr "在遠端找到 %s (%s) 需要的執行時期："

#: app/flatpak-cli-transaction.c:112
msgid "Which do you want to install (0 to abort)?"
msgstr "您想要安裝哪一個（0 為中止）？"

#: app/flatpak-cli-transaction.c:132
#, fuzzy, c-format
msgid "Configuring %s as new remote '%s'\n"
msgstr "正在設定 %s 為新的「%s」遠端"

#. default to yes on Enter
#: app/flatpak-cli-transaction.c:139
#, c-format
msgid ""
"The remote '%s', referred to by '%s' at location %s contains additional "
"applications.\n"
"Should the remote be kept for future installations?"
msgstr ""
"「%s」遠端（被「%s」在 %s 位置參照）包含其他的應用程式。\n"
"是否應該保留遠端以便將來安裝？"

#. default to yes on Enter
#: app/flatpak-cli-transaction.c:147
#, c-format
msgid ""
"The application %s depends on runtimes from:\n"
"  %s\n"
"Configure this as new remote '%s'"
msgstr ""
"%s 應用程式依賴的執行時期環境來自：\n"
"  %s\n"
"設定這為新的「%s」遠端"

#. Formatted size/remaining time in seconds
#: app/flatpak-cli-transaction.c:321
#, c-format
msgid "%s/s%s%s"
msgstr ""

#. Download progress percentage, use the appropriate
#. percent format for your language
#: app/flatpak-cli-transaction.c:359
#, c-format
msgid "%3d%%"
msgstr ""

#: app/flatpak-cli-transaction.c:414
msgid "Installing…"
msgstr "正在安裝…"

#: app/flatpak-cli-transaction.c:416
#, c-format
msgid "Installing %d/%d…"
msgstr "正在安裝 %d/%d…"

#: app/flatpak-cli-transaction.c:421
msgid "Updating…"
msgstr "正在更新…"

#: app/flatpak-cli-transaction.c:423
#, c-format
msgid "Updating %d/%d…"
msgstr "正在更新 %d/%d…"

#: app/flatpak-cli-transaction.c:428
msgid "Uninstalling…"
msgstr "正在解除安裝…"

#: app/flatpak-cli-transaction.c:430
#, c-format
msgid "Uninstalling %d/%d…"
msgstr "正在解除安裝 %d/%d…"

#: app/flatpak-cli-transaction.c:496 app/flatpak-quiet-transaction.c:161
#, c-format
msgid "Info: %s was skipped"
msgstr "資訊：%s 被跳過"

#: app/flatpak-cli-transaction.c:519
#, fuzzy, c-format
msgid "Warning: %s%s%s already installed"
msgstr "已經安裝 %s"

#: app/flatpak-cli-transaction.c:522
#, fuzzy, c-format
msgid "Error: %s%s%s already installed"
msgstr "已經安裝 %s"

#: app/flatpak-cli-transaction.c:528
#, fuzzy, c-format
msgid "Warning: %s%s%s not installed"
msgstr "%s 的 %s 分支尚未安裝"

#: app/flatpak-cli-transaction.c:531
#, fuzzy, c-format
msgid "Error: %s%s%s not installed"
msgstr "%s/%s/%s 未安裝"

#: app/flatpak-cli-transaction.c:537
#, fuzzy, c-format
msgid "Warning: %s%s%s needs a later flatpak version"
msgstr "%s 需要較新的 flatpak 版本"

#: app/flatpak-cli-transaction.c:540
#, fuzzy, c-format
msgid "Error: %s%s%s needs a later flatpak version"
msgstr "%s 需要較新的 flatpak 版本"

#: app/flatpak-cli-transaction.c:546
#, fuzzy
msgid "Warning: Not enough disk space to complete this operation"
msgstr "磁碟空間不足以完成此操作"

#: app/flatpak-cli-transaction.c:548
#, fuzzy
msgid "Error: Not enough disk space to complete this operation"
msgstr "磁碟空間不足以完成此操作"

#: app/flatpak-cli-transaction.c:553
#, fuzzy, c-format
msgid "Warning: %s"
msgstr "警告： "

#: app/flatpak-cli-transaction.c:555
#, fuzzy, c-format
msgid "Error: %s"
msgstr "錯誤："

#: app/flatpak-cli-transaction.c:570
#, fuzzy, c-format
msgid "Failed to install %s%s%s: "
msgstr "無法將 %s rebase 至 %s： "

#: app/flatpak-cli-transaction.c:577
#, fuzzy, c-format
msgid "Failed to update %s%s%s: "
msgstr "無法 %s %s："

#: app/flatpak-cli-transaction.c:584
#, fuzzy, c-format
msgid "Failed to install bundle %s%s%s: "
msgstr "無法將 %s rebase 至 %s： "

#: app/flatpak-cli-transaction.c:591
#, fuzzy, c-format
msgid "Failed to uninstall %s%s%s: "
msgstr "無法將 %s rebase 至 %s： "

#: app/flatpak-cli-transaction.c:642
#, c-format
msgid "Authentication required for remote '%s'\n"
msgstr "「%s」遠端需要通過身分核對\n"

#: app/flatpak-cli-transaction.c:643
msgid "Open browser?"
msgstr "是否開啟瀏覽器？"

#: app/flatpak-cli-transaction.c:699
#, c-format
msgid "Login required remote %s (realm %s)\n"
msgstr "需要登入 遠端 %s (領域 %s)\n"

#: app/flatpak-cli-transaction.c:704
msgid "Password"
msgstr "密碼"

#. Only runtimes can be pinned
#: app/flatpak-cli-transaction.c:759
#, fuzzy, c-format
msgid ""
"\n"
"Info: (pinned) runtime %s%s%s branch %s%s%s is end-of-life, in favor of "
"%s%s%s branch %s%s%s\n"
msgstr "資訊：%s 已經 end-of-life，故偏好 %s\n"

#: app/flatpak-cli-transaction.c:765
#, fuzzy, c-format
msgid ""
"\n"
"Info: runtime %s%s%s branch %s%s%s is end-of-life, in favor of %s%s%s branch "
"%s%s%s\n"
msgstr "資訊：%s 已經 end-of-life，故偏好 %s\n"

#: app/flatpak-cli-transaction.c:768
#, fuzzy, c-format
msgid ""
"\n"
"Info: app %s%s%s branch %s%s%s is end-of-life, in favor of %s%s%s branch "
"%s%s%s\n"
msgstr "資訊：%s 已經 end-of-life，故偏好 %s\n"

#. Only runtimes can be pinned
#: app/flatpak-cli-transaction.c:780
#, fuzzy, c-format
msgid ""
"\n"
"Info: (pinned) runtime %s%s%s branch %s%s%s is end-of-life, with reason:\n"
msgstr "資訊：%s 已經 end-of-life，理由是：%s\n"

#: app/flatpak-cli-transaction.c:786
#, fuzzy, c-format
msgid ""
"\n"
"Info: runtime %s%s%s branch %s%s%s is end-of-life, with reason:\n"
msgstr "資訊：%s 已經 end-of-life，理由是：%s\n"

#: app/flatpak-cli-transaction.c:789
#, fuzzy, c-format
msgid ""
"\n"
"Info: app %s%s%s branch %s%s%s is end-of-life, with reason:\n"
msgstr "資訊：%s 已經 end-of-life，理由是：%s\n"

#: app/flatpak-cli-transaction.c:963
#, fuzzy, c-format
msgid "Info: applications using this extension:\n"
msgstr ""
"\n"
"正在尋找應用程式與執行時期環境"

#: app/flatpak-cli-transaction.c:965
#, fuzzy, c-format
msgid "Info: applications using this runtime:\n"
msgstr ""
"\n"
"正在尋找應用程式與執行時期環境"

#: app/flatpak-cli-transaction.c:984
msgid "Replace?"
msgstr ""

#: app/flatpak-cli-transaction.c:987 app/flatpak-quiet-transaction.c:247
#, c-format
msgid "Updating to rebased version\n"
msgstr "正在更新至已經 rebase 的版本\n"

#: app/flatpak-cli-transaction.c:1011
#, c-format
msgid "Failed to rebase %s to %s: "
msgstr "無法將 %s rebase 至 %s： "

#: app/flatpak-cli-transaction.c:1277
#, fuzzy, c-format
msgid "New %s%s%s permissions:"
msgstr "新的%s權限："

#: app/flatpak-cli-transaction.c:1279
#, fuzzy, c-format
msgid "%s%s%s permissions:"
msgstr "%s權限："

#: app/flatpak-cli-transaction.c:1343
msgid "Warning: "
msgstr "警告： "

#. translators: This is short for operation, the title of a one-char column
#: app/flatpak-cli-transaction.c:1442
msgid "Op"
msgstr "Op"

#. Avoid resizing the download column too much,
#. * by making the title as long as typical content
#.
#: app/flatpak-cli-transaction.c:1458 app/flatpak-cli-transaction.c:1503
msgid "partial"
msgstr "部分"

#: app/flatpak-cli-transaction.c:1535
msgid "Proceed with these changes to the user installation?"
msgstr "是否繼續這些會影響使用者安裝的變更？"

#: app/flatpak-cli-transaction.c:1537
msgid "Proceed with these changes to the system installation?"
msgstr "是否繼續這些會影響系統安裝的變更？"

#: app/flatpak-cli-transaction.c:1539
#, c-format
msgid "Proceed with these changes to the %s?"
msgstr "是否繼續這些會影響 %s 的變更？"

#: app/flatpak-cli-transaction.c:1711
msgid "Changes complete."
msgstr "變更完成。"

#: app/flatpak-cli-transaction.c:1713
msgid "Uninstall complete."
msgstr "解除安裝完成。"

#: app/flatpak-cli-transaction.c:1715
msgid "Installation complete."
msgstr "安裝完成。"

#: app/flatpak-cli-transaction.c:1717
msgid "Updates complete."
msgstr "更新完成。"

#. For updates/!stop_on_first_error we already printed all errors so we make up
#. a different one.
#: app/flatpak-cli-transaction.c:1750
msgid "There were one or more errors"
msgstr "有一個或多個錯誤"

#. translators: please keep the leading space
#: app/flatpak-main.c:76
msgid " Manage installed applications and runtimes"
msgstr " 管理安裝的應用程式及執行時期"

#: app/flatpak-main.c:77
msgid "Install an application or runtime"
msgstr "安裝應用程式或執行時期環境"

#: app/flatpak-main.c:78
msgid "Update an installed application or runtime"
msgstr "更新已安裝的應用程式或執行時期環境"

#: app/flatpak-main.c:81
msgid "Uninstall an installed application or runtime"
msgstr "解除安裝已安裝的應用程式或執行時期環境"

#: app/flatpak-main.c:84
msgid "Mask out updates and automatic installation"
msgstr "隱藏掉更新及自動安裝"

#: app/flatpak-main.c:85
msgid "Pin a runtime to prevent automatic removal"
msgstr ""

#: app/flatpak-main.c:86
msgid "List installed apps and/or runtimes"
msgstr "列出已安裝的程式與或執行時期環境"

#: app/flatpak-main.c:87
msgid "Show info for installed app or runtime"
msgstr "顯示已安裝程式或執行時期環境的資訊"

#: app/flatpak-main.c:88
msgid "Show history"
msgstr "顯示歷史"

#: app/flatpak-main.c:89
msgid "Configure flatpak"
msgstr "設定 flatpak"

#: app/flatpak-main.c:90
msgid "Repair flatpak installation"
msgstr "修復 flatpak 安裝"

#: app/flatpak-main.c:91
msgid "Put applications or runtimes onto removable media"
msgstr "將應用程式或執行時期放入可移除式媒體"

#: app/flatpak-main.c:92
msgid "Install flatpaks that are part of the operating system"
msgstr ""

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:95
#, fuzzy
msgid ""
"\n"
" Find applications and runtimes"
msgstr ""
"\n"
"正在尋找應用程式與執行時期環境"

#: app/flatpak-main.c:96
msgid "Search for remote apps/runtimes"
msgstr "搜尋遠端的程式或執行時期環境"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:99
#, fuzzy
msgid ""
"\n"
" Manage running applications"
msgstr ""
"\n"
"正在執行應用程式"

#: app/flatpak-main.c:100
msgid "Run an application"
msgstr "執行應用程式"

#: app/flatpak-main.c:101
msgid "Override permissions for an application"
msgstr "凌駕應用程式權限"

#: app/flatpak-main.c:102
msgid "Specify default version to run"
msgstr "指定要執行的預設版本"

#: app/flatpak-main.c:103
msgid "Enter the namespace of a running application"
msgstr "輸入正在執行應用程式的 namespace"

#: app/flatpak-main.c:104
msgid "Enumerate running applications"
msgstr "枚舉正在執行的應用程式"

#: app/flatpak-main.c:105
msgid "Stop a running application"
msgstr "停止運行中的應用程式"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:108
msgid ""
"\n"
" Manage file access"
msgstr ""
"\n"
" 管理檔案存取"

#: app/flatpak-main.c:109
msgid "List exported files"
msgstr "列出已匯出的檔案"

#: app/flatpak-main.c:110
msgid "Grant an application access to a specific file"
msgstr "授予應用程式對特定檔案的存取"

#: app/flatpak-main.c:111
msgid "Revoke access to a specific file"
msgstr "撤銷對特定檔案的存取"

#: app/flatpak-main.c:112
msgid "Show information about a specific file"
msgstr "顯示特定檔案的相關資訊"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:116
msgid ""
"\n"
" Manage dynamic permissions"
msgstr ""
"\n"
" 管理動態權限"

#: app/flatpak-main.c:117
msgid "List permissions"
msgstr "列出權限"

#: app/flatpak-main.c:118
msgid "Remove item from permission store"
msgstr "從權限儲存中移除項目"

#: app/flatpak-main.c:120
msgid "Set permissions"
msgstr "設定權限"

#: app/flatpak-main.c:121
msgid "Show app permissions"
msgstr "顯示程式權限"

#: app/flatpak-main.c:122
msgid "Reset app permissions"
msgstr "重設程式權限"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:125
msgid ""
"\n"
" Manage remote repositories"
msgstr ""
"\n"
" 管理遠端軟體庫"

#: app/flatpak-main.c:126
msgid "List all configured remotes"
msgstr "列出所有已設定的遠端"

#: app/flatpak-main.c:127
msgid "Add a new remote repository (by URL)"
msgstr "加入新的遠端軟體庫（根據 URL）"

#: app/flatpak-main.c:128
msgid "Modify properties of a configured remote"
msgstr "修改已設定遠端的屬性"

#: app/flatpak-main.c:129
msgid "Delete a configured remote"
msgstr "刪除已設定遠端"

#: app/flatpak-main.c:131
msgid "List contents of a configured remote"
msgstr "列出已設定遠端的內容"

#: app/flatpak-main.c:132
msgid "Show information about a remote app or runtime"
msgstr "顯示遠端程式或執行時期環境的相關資訊"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:135
msgid ""
"\n"
" Build applications"
msgstr ""
"\n"
" 組建應用程式"

#: app/flatpak-main.c:136
msgid "Initialize a directory for building"
msgstr "初始化目錄以供組建"

#: app/flatpak-main.c:137
msgid "Run a build command inside the build dir"
msgstr "在組建目錄中執行組建指令"

#: app/flatpak-main.c:138
msgid "Finish a build dir for export"
msgstr "結束組建目錄以匯出"

#: app/flatpak-main.c:139
msgid "Export a build dir to a repository"
msgstr "將組建目錄匯出為軟體庫"

#: app/flatpak-main.c:140
msgid "Create a bundle file from a ref in a local repository"
msgstr "從本機軟體庫中的參照建立一個套組檔案"

#: app/flatpak-main.c:141
msgid "Import a bundle file"
msgstr "匯入一個套組檔案"

#: app/flatpak-main.c:142
msgid "Sign an application or runtime"
msgstr "簽署應用程式或執行時期環境"

#: app/flatpak-main.c:143
msgid "Update the summary file in a repository"
msgstr "更新軟體庫中的摘要檔案"

#: app/flatpak-main.c:144
msgid "Create new commit based on existing ref"
msgstr "建立以既有參照為基礎的新提交"

#: app/flatpak-main.c:145
msgid "Show information about a repo"
msgstr "顯示軟體庫的資訊"

#: app/flatpak-main.c:162
msgid "Show debug information, -vv for more detail"
msgstr "顯示除錯資訊，-vv 顯示更多"

#: app/flatpak-main.c:163
msgid "Show OSTree debug information"
msgstr "顯示 OSTree 除錯資訊"

#: app/flatpak-main.c:169
msgid "Print version information and exit"
msgstr "列印版本資訊並離開"

#: app/flatpak-main.c:170
msgid "Print default arch and exit"
msgstr "列印預設架構並離開"

#: app/flatpak-main.c:171
msgid "Print supported arches and exit"
msgstr "列印支援的架構並離開"

#: app/flatpak-main.c:172
msgid "Print active gl drivers and exit"
msgstr "列印作用中的 GL 驅動程式並離開"

#: app/flatpak-main.c:173
msgid "Print paths for system installations and exit"
msgstr "輸出系統安裝的路徑後結束"

#: app/flatpak-main.c:174
msgid "Print the updated environment needed to run flatpaks"
msgstr ""

#: app/flatpak-main.c:175
msgid "Only include the system installation with --print-updated-env"
msgstr ""

#: app/flatpak-main.c:180
msgid "Work on the user installation"
msgstr "在使用者安裝上運作"

#: app/flatpak-main.c:181
msgid "Work on the system-wide installation (default)"
msgstr "在系統層安裝上運作（預設值）"

#: app/flatpak-main.c:182
msgid "Work on a non-default system-wide installation"
msgstr "在非預設系統層安裝上運作"

#: app/flatpak-main.c:212
msgid "Builtin Commands:"
msgstr "內建指令："

#: app/flatpak-main.c:298
#, c-format
msgid ""
"Note that the directories %s are not in the search path set by the "
"XDG_DATA_DIRS environment variable, so applications installed by Flatpak may "
"not appear on your desktop until the session is restarted."
msgstr ""
"註：「%s」目錄不在 XDG_DATA_DIRS 環境變數設定的搜尋路徑中，所以 Flatpak 安裝"
"的應用程式可能在工作階段重新啟動前，都無法在桌面看見。"

#: app/flatpak-main.c:312
#, c-format
msgid ""
"Note that the directory %s is not in the search path set by the "
"XDG_DATA_DIRS environment variable, so applications installed by Flatpak may "
"not appear on your desktop until the session is restarted."
msgstr ""
"註：「%s」目錄不在 XDG_DATA_DIRS 環境變數設定的搜尋路徑中，所以 Flatpak 安裝"
"的應用程式可能在工作階段重新啟動前，都無法在桌面看見。"

#: app/flatpak-main.c:381
msgid ""
"Refusing to operate under sudo with --user. Omit sudo to operate on the user "
"installation, or use a root shell to operate on the root user's installation."
msgstr ""

#: app/flatpak-main.c:453
#, fuzzy
msgid ""
"Multiple installations specified for a command that works on one installation"
msgstr "--installation 選項在某一安裝上可運作的指令中已使用過多次"

#: app/flatpak-main.c:504 app/flatpak-main.c:697
#, c-format
msgid "See '%s --help'"
msgstr "請查看「%s --help」"

#: app/flatpak-main.c:706
#, c-format
msgid "'%s' is not a flatpak command. Did you mean '%s%s'?"
msgstr "「%s」不是 Flatpak 命令。您是指「%s%s」嗎？"

#: app/flatpak-main.c:709
#, c-format
msgid "'%s' is not a flatpak command"
msgstr "「%s」不是 flatpak 指令"

#: app/flatpak-main.c:824
msgid "No command specified"
msgstr "沒有指定指令"

#: app/flatpak-main.c:980
msgid "error:"
msgstr "錯誤："

#: app/flatpak-quiet-transaction.c:77
#, c-format
msgid "Installing %s\n"
msgstr "正在安裝 %s\n"

#: app/flatpak-quiet-transaction.c:81
#, c-format
msgid "Updating %s\n"
msgstr "正在更新 %s\n"

#: app/flatpak-quiet-transaction.c:85
#, c-format
msgid "Uninstalling %s\n"
msgstr "正在解除安裝 %s\n"

#: app/flatpak-quiet-transaction.c:107
#, fuzzy, c-format
msgid "Warning: Failed to install %s: %s\n"
msgstr "警告：無法 %s %s：%s\n"

#: app/flatpak-quiet-transaction.c:110
#, fuzzy, c-format
msgid "Error: Failed to install %s: %s\n"
msgstr "錯誤：無法 %s %s：%s\n"

#: app/flatpak-quiet-transaction.c:116
#, fuzzy, c-format
msgid "Warning: Failed to update %s: %s\n"
msgstr "警告：無法 %s %s：%s\n"

#: app/flatpak-quiet-transaction.c:119
#, fuzzy, c-format
msgid "Error: Failed to update %s: %s\n"
msgstr "錯誤：無法 %s %s：%s\n"

#: app/flatpak-quiet-transaction.c:125
#, fuzzy, c-format
msgid "Warning: Failed to install bundle %s: %s\n"
msgstr "警告：無法 %s %s：%s\n"

#: app/flatpak-quiet-transaction.c:128
#, fuzzy, c-format
msgid "Error: Failed to install bundle %s: %s\n"
msgstr "錯誤：無法 %s %s：%s\n"

#: app/flatpak-quiet-transaction.c:134
#, fuzzy, c-format
msgid "Warning: Failed to uninstall %s: %s\n"
msgstr "警告：無法 %s %s：%s\n"

#: app/flatpak-quiet-transaction.c:137
#, fuzzy, c-format
msgid "Error: Failed to uninstall %s: %s\n"
msgstr "錯誤：無法 %s %s：%s\n"

#: app/flatpak-quiet-transaction.c:166 common/flatpak-dir.c:11475
#, c-format
msgid "%s already installed"
msgstr "已經安裝 %s"

#: app/flatpak-quiet-transaction.c:168 common/flatpak-dir.c:3622
#: common/flatpak-dir.c:4321 common/flatpak-dir.c:16968
#: common/flatpak-dir.c:17258 common/flatpak-dir-utils.c:166
#: common/flatpak-dir-utils.c:259 common/flatpak-transaction.c:2736
#: common/flatpak-transaction.c:2791
#, c-format
msgid "%s not installed"
msgstr "%s 未安裝"

#: app/flatpak-quiet-transaction.c:170
#, c-format
msgid "%s needs a later flatpak version"
msgstr "%s 需要較新的 flatpak 版本"

#: app/flatpak-quiet-transaction.c:172
msgid "Not enough disk space to complete this operation"
msgstr "磁碟空間不足以完成此操作"

#: app/flatpak-quiet-transaction.c:239
#, c-format
msgid "Info: %s is end-of-life, in favor of %s\n"
msgstr "資訊：%s 已經 end-of-life，故偏好 %s\n"

#: app/flatpak-quiet-transaction.c:241
#, c-format
msgid "Info: %s is end-of-life, with reason: %s\n"
msgstr "資訊：%s 已經 end-of-life，理由是：%s\n"

#: app/flatpak-quiet-transaction.c:251
#, c-format
msgid "Failed to rebase %s to %s: %s\n"
msgstr "無法重定 %s 的基底 (rebase) 至 %s：%s\n"

#: common/flatpak-auth.c:58
#, c-format
msgid "No authenticator configured for remote `%s`"
msgstr "未設定用於「%s」遠端的身分核對器"

#: common/flatpak-context.c:637 common/flatpak-context.c:649
#, fuzzy, c-format
msgid "Invalid permission syntax: %s"
msgstr "無效的身分核對器名稱 %s"

#: common/flatpak-context.c:1207
#, c-format
msgid "Unknown share type %s, valid types are: %s"
msgstr "未知的分享類型 %s，有效的類型為：%s"

#: common/flatpak-context.c:1228
#, c-format
msgid "Unknown policy type %s, valid types are: %s"
msgstr "未知的方針類型 %s，有效的類型為：%s"

#: common/flatpak-context.c:1266
#, c-format
msgid "Invalid dbus name %s"
msgstr "無效的 dbus 名稱 %s"

#: common/flatpak-context.c:1279
#, c-format
msgid "Unknown socket type %s, valid types are: %s"
msgstr "未知的接口類型 %s，有效的類型為：%s"

#: common/flatpak-context.c:1294
#, c-format
msgid "Unknown device type %s, valid types are: %s"
msgstr "未知的裝置類型 %s，有效的類型為：%s"

#: common/flatpak-context.c:1308
#, c-format
msgid "Unknown feature type %s, valid types are: %s"
msgstr "未知的功能類型 %s，有效的類型為：%s"

#: common/flatpak-context.c:1840
#, c-format
msgid "Filesystem location \"%s\" contains \"..\""
msgstr ""

#: common/flatpak-context.c:1882
#, c-format
msgid ""
"--filesystem=/ is not available, use --filesystem=host for a similar result"
msgstr ""

#: common/flatpak-context.c:1916
#, fuzzy, c-format
msgid ""
"Unknown filesystem location %s, valid locations are: host, host-os, host-"
"etc, host-root, home, xdg-*[/…], ~/dir, /dir"
msgstr ""
"未知的檔案系統位置 %s，有效的位置為：host、host-os、host-etc、home、xdg-"
"*[/…]、~/dir、/dir"

#: common/flatpak-context.c:2015
#, fuzzy, c-format
msgid "Invalid syntax for %s: %s"
msgstr "無效的 %s 名稱：%s"

#: common/flatpak-context.c:2142
#, c-format
msgid "fallback-x11 can not be conditional"
msgstr ""

#: common/flatpak-context.c:2318
#, c-format
msgid "Invalid env format %s"
msgstr "無效的 env 格式 %s"

#: common/flatpak-context.c:2399
#, c-format
msgid "Environment variable name must not contain '=': %s"
msgstr ""

#: common/flatpak-context.c:2527 common/flatpak-context.c:2535
#, c-format
msgid "--add-policy arguments must be in the form SUBSYSTEM.KEY=VALUE"
msgstr "--add-policy 引數必須是 SUBSYSTEM.KEY=VALUE 的形式"

#: common/flatpak-context.c:2542
#, c-format
msgid "--add-policy values can't start with \"!\""
msgstr "--add-policy 的值不能以「!」開始"

#: common/flatpak-context.c:2567 common/flatpak-context.c:2575
#, c-format
msgid "--remove-policy arguments must be in the form SUBSYSTEM.KEY=VALUE"
msgstr "--remove-policy 的引數必須是 SUBSYSTEM.KEY=VALUE 的形式"

#: common/flatpak-context.c:2582
#, c-format
msgid "--remove-policy values can't start with \"!\""
msgstr "--remove-policy 的值不能以「!」開始"

#: common/flatpak-context.c:2657
msgid "Share with host"
msgstr "與主機分享"

#: common/flatpak-context.c:2657 common/flatpak-context.c:2658
msgid "SHARE"
msgstr "SHARE"

#: common/flatpak-context.c:2658
msgid "Unshare with host"
msgstr "不與主機分享"

#: common/flatpak-context.c:2659
msgid "Require conditions to be met for a subsystem to get shared"
msgstr ""

#: common/flatpak-context.c:2659
msgid "SHARE:CONDITION"
msgstr ""

#: common/flatpak-context.c:2660
msgid "Expose socket to app"
msgstr "將接口開放給程式"

#: common/flatpak-context.c:2660 common/flatpak-context.c:2661
msgid "SOCKET"
msgstr "SOCKET"

#: common/flatpak-context.c:2661
msgid "Don't expose socket to app"
msgstr "不要將接口開放給程式"

#: common/flatpak-context.c:2662
msgid "Require conditions to be met for a socket to get exposed"
msgstr ""

#: common/flatpak-context.c:2662
msgid "SOCKET:CONDITION"
msgstr ""

#: common/flatpak-context.c:2663
msgid "Expose device to app"
msgstr "將裝置開放給程式"

#: common/flatpak-context.c:2663 common/flatpak-context.c:2664
msgid "DEVICE"
msgstr "DEVICE"

#: common/flatpak-context.c:2664
msgid "Don't expose device to app"
msgstr "不要將裝置開放給程式"

#: common/flatpak-context.c:2665
msgid "Require conditions to be met for a device to get exposed"
msgstr ""

#: common/flatpak-context.c:2665
msgid "DEVICE:CONDITION"
msgstr ""

#: common/flatpak-context.c:2666
msgid "Allow feature"
msgstr "允許功能"

#: common/flatpak-context.c:2666 common/flatpak-context.c:2667
msgid "FEATURE"
msgstr "FEATURE"

#: common/flatpak-context.c:2667
msgid "Don't allow feature"
msgstr "不允許功能"

#: common/flatpak-context.c:2668
msgid "Require conditions to be met for a feature to get allowed"
msgstr ""

#: common/flatpak-context.c:2668
msgid "FEATURE:CONDITION"
msgstr ""

#: common/flatpak-context.c:2669
msgid "Expose filesystem to app (:ro for read-only)"
msgstr "將檔案系統開放給程式（:ro 表示唯讀）"

#: common/flatpak-context.c:2669
msgid "FILESYSTEM[:ro]"
msgstr "FILESYSTEM[:ro]"

#: common/flatpak-context.c:2670
msgid "Don't expose filesystem to app"
msgstr "不要將檔案系統開放給程式"

#: common/flatpak-context.c:2670
msgid "FILESYSTEM"
msgstr "FILESYSTEM"

#: common/flatpak-context.c:2671
msgid "Set environment variable"
msgstr "設定環境變數"

#: common/flatpak-context.c:2671
msgid "VAR=VALUE"
msgstr "VAR=VALUE"

#: common/flatpak-context.c:2672
msgid "Read environment variables in env -0 format from FD"
msgstr ""

#: common/flatpak-context.c:2673
#, fuzzy
msgid "Remove variable from environment"
msgstr "從權限儲存中移除項目"

#: common/flatpak-context.c:2673
#, fuzzy
msgid "VAR"
msgstr "VAL"

#: common/flatpak-context.c:2674
msgid "Allow app to own name on the session bus"
msgstr "允許程式在工作階段匯流排上擁有自己的名稱"

#: common/flatpak-context.c:2674 common/flatpak-context.c:2675
#: common/flatpak-context.c:2676 common/flatpak-context.c:2677
#: common/flatpak-context.c:2678 common/flatpak-context.c:2679
#: common/flatpak-context.c:2680
msgid "DBUS_NAME"
msgstr "DBUS_NAME"

#: common/flatpak-context.c:2675
msgid "Allow app to talk to name on the session bus"
msgstr "允許程式與工作階段匯流排上的名稱溝通"

#: common/flatpak-context.c:2676
msgid "Don't allow app to talk to name on the session bus"
msgstr "不允許程式與工作階段匯流排上的名稱溝通"

#: common/flatpak-context.c:2677
msgid "Allow app to own name on the system bus"
msgstr "允許程式在系統匯流排上擁有自己的名稱"

#: common/flatpak-context.c:2678
msgid "Allow app to talk to name on the system bus"
msgstr "允許程式與系統匯流排上的名稱溝通"

#: common/flatpak-context.c:2679
msgid "Don't allow app to talk to name on the system bus"
msgstr "不允許程式與系統匯流排上的名稱溝通"

#: common/flatpak-context.c:2680
#, fuzzy
msgid "Allow app to own name on the a11y bus"
msgstr "允許程式在系統匯流排上擁有自己的名稱"

#: common/flatpak-context.c:2681
msgid "Add generic policy option"
msgstr "新增通用方針選項"

#: common/flatpak-context.c:2681 common/flatpak-context.c:2682
msgid "SUBSYSTEM.KEY=VALUE"
msgstr "SUBSYSTEM.KEY=VALUE"

#: common/flatpak-context.c:2682
msgid "Remove generic policy option"
msgstr "移除通用方針選項"

#: common/flatpak-context.c:2683
msgid "Add USB device to enumerables"
msgstr ""

#: common/flatpak-context.c:2683 common/flatpak-context.c:2684
msgid "VENDOR_ID:PRODUCT_ID"
msgstr ""

#: common/flatpak-context.c:2684
msgid "Add USB device to hidden list"
msgstr ""

#: common/flatpak-context.c:2685
msgid "A list of USB devices that are enumerable"
msgstr ""

#: common/flatpak-context.c:2685
msgid "LIST"
msgstr ""

#: common/flatpak-context.c:2686
msgid "File containing a list of USB devices to make enumerable"
msgstr ""

#: common/flatpak-context.c:2686 common/flatpak-context.c:2687
msgid "FILENAME"
msgstr "FILENAME"

#: common/flatpak-context.c:2687
msgid "Persist home directory subpath"
msgstr "留存家目錄的子路徑"

#. This is not needed/used anymore, so hidden, but we accept it for backwards compat
#: common/flatpak-context.c:2689
msgid "Don't require a running session (no cgroups creation)"
msgstr "不需要有執行中的工作階段（不會建立 cgroups）"

#: common/flatpak-context.c:3718
#, c-format
msgid "Not replacing \"%s\" with tmpfs: %s"
msgstr ""

#: common/flatpak-context.c:3726
#, c-format
msgid "Not sharing \"%s\" with sandbox: %s"
msgstr ""

#. Even if the error is one that we would normally silence, like
#. * the path not existing, it seems reasonable to make more of a fuss
#. * about the home directory not existing or otherwise being unusable,
#. * so this is intentionally not using cannot_export()
#: common/flatpak-context.c:3828
#, c-format
msgid "Not allowing home directory access: %s"
msgstr ""

#: common/flatpak-context.c:4062
#, fuzzy, c-format
msgid "Unable to provide a temporary home directory in the sandbox: %s"
msgstr "無法建立布署目錄"

#: common/flatpak-dir.c:442
#, c-format
msgid "Configured collection ID ‘%s’ not in summary file"
msgstr ""

#: common/flatpak-dir.c:587
#, c-format
msgid "Unable to load summary from remote %s: %s"
msgstr "無法從遠端載入摘要 %s：%s"

#: common/flatpak-dir.c:764 common/flatpak-dir.c:800 common/flatpak-dir.c:906
#, c-format
msgid "No such ref '%s' in remote %s"
msgstr "在遠端 %2$s 中無此參照「%1$s」"

#: common/flatpak-dir.c:891 common/flatpak-dir.c:1051 common/flatpak-dir.c:1080
#: common/flatpak-dir.c:1092
#, fuzzy, c-format
msgid "No entry for %s in remote %s summary flatpak cache"
msgstr "在「%2$s」遠端的摘要 flatpak 快取中沒有 %1$s 條目 "

#: common/flatpak-dir.c:1069
#, c-format
msgid "No summary or Flatpak cache available for remote %s"
msgstr "%s 遠端沒有摘要或 Flatpak 快取"

#: common/flatpak-dir.c:1097
#, fuzzy, c-format
msgid "Missing xa.data in summary for remote %s"
msgstr "未快取「%s」遠端的 oci 摘要"

#: common/flatpak-dir.c:1103 common/flatpak-dir.c:1546
#, fuzzy, c-format
msgid "Unsupported summary version %d for remote %s"
msgstr "未快取「%s」遠端的摘要"

#: common/flatpak-dir.c:1200
msgid "Remote OCI index has no registry uri"
msgstr "遠端 OCI 索引沒有註冊 URI"

#: common/flatpak-dir.c:1261
#, fuzzy, c-format
msgid "Couldn't find ref %s in remote %s"
msgstr "在 %2$s 遠端中找不到 %1$s 參照的最近檢核碼"

#: common/flatpak-dir.c:1288 common/flatpak-dir.c:1381
#, fuzzy, c-format
msgid "Commit has no requested ref ‘%s’ in ref binding metadata (found: ‘%s’)"
msgstr "提交的參照綁定中介資料中沒有要求的「%s」參照"

#: common/flatpak-dir.c:1413
#, fuzzy, c-format
msgid "Configured collection ID ‘%s’ not in binding metadata"
msgstr "提交的參照綁定中介資料中沒有要求的「%s」參照"

#: common/flatpak-dir.c:1449 common/flatpak-dir.c:5645
#, c-format
msgid "Couldn't find latest checksum for ref %s in remote %s"
msgstr "在 %2$s 遠端中找不到 %1$s 參照的最近檢核碼"

#: common/flatpak-dir.c:1516 common/flatpak-dir.c:1552
#, fuzzy, c-format
msgid "No entry for %s in remote %s summary flatpak sparse cache"
msgstr "在遠端的摘要 flatpak 簡要快取中沒有 %s 條目 "

#: common/flatpak-dir.c:2540
#, c-format
msgid "Commit metadata for %s not matching expected metadata"
msgstr ""

#: common/flatpak-dir.c:2823
msgid "Unable to connect to system bus"
msgstr "無法連接系統匯流排"

#: common/flatpak-dir.c:3419
msgid "User installation"
msgstr "使用者安裝"

#: common/flatpak-dir.c:3426
#, c-format
msgid "System (%s) installation"
msgstr "系統 (%s) 安裝"

#: common/flatpak-dir.c:3472
#, c-format
msgid "No overrides found for %s"
msgstr "找不到 %s 的凌駕值"

#: common/flatpak-dir.c:3625
#, c-format
msgid "%s (commit %s) not installed"
msgstr "%s（%s 提交）未安裝"

#: common/flatpak-dir.c:4650
#, c-format
msgid "Error parsing system flatpakrepo file for %s: %s"
msgstr "解析 %s 的系統 flatpakrepo 檔案時發生錯誤：%s"

#: common/flatpak-dir.c:4735
#, c-format
msgid "While opening repository %s: "
msgstr "當開啟 %s 軟體庫時："

#: common/flatpak-dir.c:5004
#, c-format
msgid "The config key %s is not set"
msgstr "未設定 %s 設定鍵"

#: common/flatpak-dir.c:5140
#, fuzzy, c-format
msgid "No current %s pattern matching %s"
msgstr "目前沒有符合 %s 的遮罩"

#: common/flatpak-dir.c:5422
msgid "No appstream commit to deploy"
msgstr "沒有要布署的 appstream 提交"

#: common/flatpak-dir.c:5941 common/flatpak-dir.c:7266
#: common/flatpak-dir.c:10881 common/flatpak-dir.c:11618
msgid "Can't pull from untrusted non-gpg verified remote"
msgstr "無法從未受信任的無 GPG 驗證過的遠端拉入"

#: common/flatpak-dir.c:6376 common/flatpak-dir.c:6591
msgid "Extra data not supported for non-gpg-verified local system installs"
msgstr "不支援無 GPG 驗證過的本機系統安裝的額外資料"

#: common/flatpak-dir.c:6415 common/flatpak-dir.c:6782
#, c-format
msgid "Invalid checksum for extra data uri %s"
msgstr "額外資料 URI %s 的檢核碼無效"

#: common/flatpak-dir.c:6424
#, c-format
msgid "Empty name for extra data uri %s"
msgstr "額外資料 URI %s 的名稱空白"

#: common/flatpak-dir.c:6432
#, c-format
msgid "Unsupported extra data uri %s"
msgstr "不支援的額外資料 URI %s"

#: common/flatpak-dir.c:6461
#, c-format
msgid "Failed to load local extra-data %s: %s"
msgstr "本機額外資料 %s 載入失敗：%s"

#: common/flatpak-dir.c:6469
#, c-format
msgid "Wrong size for extra-data %s"
msgstr "額外資料 %s 的大小錯誤"

#: common/flatpak-dir.c:6488
#, c-format
msgid "While downloading %s: "
msgstr "當下載 %s 時："

#: common/flatpak-dir.c:6498
#, c-format
msgid "Wrong size for extra data %s"
msgstr "額外資料 %s 的大小錯誤"

#: common/flatpak-dir.c:6507
#, c-format
msgid "Invalid checksum for extra data %s"
msgstr "額外資料 %s 的檢核碼無效"

#: common/flatpak-dir.c:7096 common/flatpak-dir.c:7349
#, c-format
msgid "While pulling %s from remote %s: "
msgstr "當從 %2$s 遠端拉入 %1$s 時："

#: common/flatpak-dir.c:7290 common/flatpak-repo-utils.c:3886
msgid "GPG signatures found, but none are in trusted keyring"
msgstr "找到 GPG 簽章，但不在受信任的鑰匙圈中"

#: common/flatpak-dir.c:7307
#, c-format
msgid "Commit for ‘%s’ has no ref binding"
msgstr "「%s」的提交沒有參照綁定"

#: common/flatpak-dir.c:7312
#, c-format
msgid "Commit for ‘%s’ is not in expected bound refs: %s"
msgstr "「%s」的提交不在期望的邊界參照中：%s"

#: common/flatpak-dir.c:7488
#, fuzzy
msgid "Only applications can be made current"
msgstr ""
"\n"
"正在尋找應用程式與執行時期環境"

#: common/flatpak-dir.c:8192
msgid "Not enough memory"
msgstr "記憶體不足"

#: common/flatpak-dir.c:8211
msgid "Failed to read from exported file"
msgstr "從已匯出的檔案讀取失敗"

#: common/flatpak-dir.c:8401
msgid "Error reading mimetype xml file"
msgstr "讀取 mimetype XML 檔案時發生錯誤"

#: common/flatpak-dir.c:8406
msgid "Invalid mimetype xml file"
msgstr "無效的 mimetype XML 檔案"

#: common/flatpak-dir.c:8492
#, c-format
msgid "D-Bus service file '%s' has wrong name"
msgstr "D-Bus 服務檔案「%s」的名稱錯誤"

#: common/flatpak-dir.c:8647
#, fuzzy, c-format
msgid "Invalid Exec argument %s"
msgstr "無效的 require-flatpak 引數 %s"

#: common/flatpak-dir.c:9115
msgid "While getting detached metadata: "
msgstr "當取得分離的中介資料時："

#: common/flatpak-dir.c:9120 common/flatpak-dir.c:9125
#: common/flatpak-dir.c:9129
msgid "Extra data missing in detached metadata"
msgstr "分離的中介資料遺失額外資料"

#: common/flatpak-dir.c:9133
msgid "While creating extradir: "
msgstr "當建立額外目錄時："

#: common/flatpak-dir.c:9154 common/flatpak-dir.c:9187
msgid "Invalid checksum for extra data"
msgstr "額外資料的檢核碼無效"

#: common/flatpak-dir.c:9183
msgid "Wrong size for extra data"
msgstr "額外資料的大小錯誤"

#: common/flatpak-dir.c:9196
#, c-format
msgid "While writing extra data file '%s': "
msgstr "當寫入「%s」額外資料檔案時："

#: common/flatpak-dir.c:9204
#, c-format
msgid "Extra data %s missing in detached metadata"
msgstr "分離的中介資料遺失額外資料 %s"

#: common/flatpak-dir.c:9278
#, fuzzy, c-format
msgid "Unable to get runtime key from metadata"
msgstr "為中介資料使用替代檔案"

#: common/flatpak-dir.c:9402
#, c-format
msgid "apply_extra script failed, exit status %d"
msgstr "apply_extra 指令稿執行失敗，結束狀態為 %d"

#. Translators: The placeholder is for an app ref.
#: common/flatpak-dir.c:9591
#, c-format
msgid "Installing %s is not allowed by the policy set by your administrator"
msgstr "因管理員設定的方針，不允許安裝 %s"

#: common/flatpak-dir.c:9690
#, c-format
msgid "While trying to resolve ref %s: "
msgstr "當嘗試解決 %s 參照時："

#: common/flatpak-dir.c:9702
#, c-format
msgid "%s is not available"
msgstr "%s 無法使用"

#: common/flatpak-dir.c:9714 common/flatpak-dir.c:11495
#, c-format
msgid "%s commit %s already installed"
msgstr "已經安裝 %s 的 %s 提交"

#: common/flatpak-dir.c:9721
msgid "Can't create deploy directory"
msgstr "無法建立布署目錄"

#: common/flatpak-dir.c:9729
#, c-format
msgid "Failed to read commit %s: "
msgstr "%s 提交讀取失敗："

#: common/flatpak-dir.c:9750
#, c-format
msgid "While trying to checkout %s into %s: "
msgstr "當嘗試將 %s 檢出至 %s 時："

#: common/flatpak-dir.c:9769
msgid "While trying to checkout metadata subpath: "
msgstr "當嘗試檢出中介資料子路徑時："

#: common/flatpak-dir.c:9801
#, c-format
msgid "While trying to checkout subpath ‘%s’: "
msgstr "當嘗試檢出子路徑「%s」時："

#: common/flatpak-dir.c:9811
msgid "While trying to remove existing extra dir: "
msgstr "當嘗試移除既有的額外目錄時："

#: common/flatpak-dir.c:9822
msgid "While trying to apply extra data: "
msgstr "當嘗試套用額外資料時："

#: common/flatpak-dir.c:9849
#, c-format
msgid "Invalid commit ref %s: "
msgstr "無效的 %s 參照提交："

#: common/flatpak-dir.c:9857 common/flatpak-dir.c:9869
#, c-format
msgid "Deployed ref %s does not match commit (%s)"
msgstr "已布署的 %s 參照與提交不符（%s）"

#: common/flatpak-dir.c:9863
#, c-format
msgid "Deployed ref %s branch does not match commit (%s)"
msgstr "已布署的 %s 參照分支與提交不符（%s）"

#: common/flatpak-dir.c:10125 common/flatpak-installation.c:1911
#, c-format
msgid "%s branch %s already installed"
msgstr "已經安裝 %s 的 %s 分支"

#: common/flatpak-dir.c:10985
#, c-format
msgid "Could not unmount revokefs-fuse filesystem at %s: "
msgstr ""

#: common/flatpak-dir.c:11289
#, c-format
msgid "This version of %s is already installed"
msgstr "已經安裝此版本的 %s"

#: common/flatpak-dir.c:11302
#, c-format
msgid "Can't change remote during bundle install"
msgstr "無法在套組安裝時變更遠端"

#: common/flatpak-dir.c:11571
msgid "Can't update to a specific commit without root permissions"
msgstr "沒有 root 權利時無法更新至特定提交"

#: common/flatpak-dir.c:11852
#, c-format
msgid "Can't remove %s, it is needed for: %s"
msgstr "無法移除 %s，它為此項目所需要：%s"

#: common/flatpak-dir.c:11912 common/flatpak-installation.c:2067
#, c-format
msgid "%s branch %s is not installed"
msgstr "%s 的 %s 分支尚未安裝"

#: common/flatpak-dir.c:12165
#, c-format
msgid "%s commit %s not installed"
msgstr "未安裝 %s (提交 %s)"

#: common/flatpak-dir.c:12501
#, c-format
msgid "Pruning repo failed: %s"
msgstr "修除軟體庫失敗：%s"

#: common/flatpak-dir.c:12669 common/flatpak-dir.c:12675
#, c-format
msgid "Failed to load filter '%s'"
msgstr "無法載入過濾器「%s」"

#: common/flatpak-dir.c:12681
#, c-format
msgid "Failed to parse filter '%s'"
msgstr "無法解析「%s」過濾器"

#: common/flatpak-dir.c:12963
msgid "Failed to write summary cache: "
msgstr "無法寫入摘要快取： "

#: common/flatpak-dir.c:12982
#, c-format
msgid "No oci summary cached for remote '%s'"
msgstr "未快取「%s」遠端的 oci 摘要"

#: common/flatpak-dir.c:13207
#, fuzzy, c-format
msgid "No cached summary for remote '%s'"
msgstr "未快取「%s」遠端的 oci 摘要"

#: common/flatpak-dir.c:13248
#, fuzzy, c-format
msgid "Invalid checksum for indexed summary %s read from %s"
msgstr "額外資料 %s 的檢核碼無效"

#: common/flatpak-dir.c:13321
#, c-format
msgid ""
"Remote listing for %s not available; server has no summary file. Check the "
"URL passed to remote-add was valid."
msgstr ""
"%s 的遠端列表無法使用；伺服器沒有摘要檔案。請檢查傳給 remote-add 的 URL 是否"
"有效。"

#: common/flatpak-dir.c:13698
#, fuzzy, c-format
msgid "Invalid checksum for indexed summary %s for remote '%s'"
msgstr "額外資料 %s 的檢核碼無效"

#: common/flatpak-dir.c:14388
#, c-format
msgid "Multiple branches available for %s, you must specify one of: "
msgstr "%s 有多個分支可用，您必須指定其中一個："

#: common/flatpak-dir.c:14454
#, c-format
msgid "Nothing matches %s"
msgstr "沒有項目符合 %s"

#: common/flatpak-dir.c:14562
#, c-format
msgid "Can't find ref %s%s%s%s%s"
msgstr "找不到參照 %s%s%s%s%s"

#: common/flatpak-dir.c:14605
#, c-format
msgid "Error searching remote %s: %s"
msgstr "搜尋 %s 遠端時發生錯誤：%s"

#: common/flatpak-dir.c:14702
#, c-format
msgid "Error searching local repository: %s"
msgstr "搜尋本機軟體庫時發生錯誤：%s"

#: common/flatpak-dir.c:14839
#, c-format
msgid "%s/%s/%s not installed"
msgstr "%s/%s/%s 未安裝"

#: common/flatpak-dir.c:15042
#, c-format
msgid "Could not find installation %s"
msgstr "找不到 %s 安裝"

#: common/flatpak-dir.c:15612
#, c-format
msgid "Invalid file format, no %s group"
msgstr "無效的檔案格式，沒有 %s 群組"

#: common/flatpak-dir.c:15617 common/flatpak-repo-utils.c:2836
#, c-format
msgid "Invalid version %s, only 1 supported"
msgstr "%s 版本無效，僅支援 1 版"

#: common/flatpak-dir.c:15622 common/flatpak-dir.c:15627
#, c-format
msgid "Invalid file format, no %s specified"
msgstr "無效的檔案格式，未指定 %s"

#. Check some minimal size so we don't get crap
#: common/flatpak-dir.c:15647
msgid "Invalid file format, gpg key invalid"
msgstr "無效的檔案格式，GPG 金鑰無效"

#: common/flatpak-dir.c:15675 common/flatpak-repo-utils.c:2917
msgid "Collection ID requires GPG key to be provided"
msgstr "收藏 ID 必須提供 GPG 金鑰"

#: common/flatpak-dir.c:15718
#, c-format
msgid "Runtime %s, branch %s is already installed"
msgstr "已經安裝 %s 執行時期環境，%s 分支"

#: common/flatpak-dir.c:15719
#, c-format
msgid "App %s, branch %s is already installed"
msgstr "已經安裝 %s 程式，%s 分支"

#: common/flatpak-dir.c:15953
#, c-format
msgid "Can't remove remote '%s' with installed ref %s (at least)"
msgstr "無法移除「%s」遠端的已安裝 %s 參照（至少）"

#: common/flatpak-dir.c:16058
#, c-format
msgid "Invalid character '/' in remote name: %s"
msgstr "在遠端的名稱中有無效字元「/」：%s"

#: common/flatpak-dir.c:16064
#, c-format
msgid "No configuration for remote %s specified"
msgstr "沒有設定 %s 遠端的組態"

#: common/flatpak-dir.c:17597
#, c-format
msgid "Skipping deletion of mirror ref (%s, %s)…\n"
msgstr "正在略過鏡像參照 (%s, %s)…\n"

#: common/flatpak-exports.c:931
#, c-format
msgid "An absolute path is required"
msgstr ""

#: common/flatpak-exports.c:948
#, fuzzy, c-format
msgid "Unable to open path \"%s\": %s"
msgstr "無法更新 %s：%s\n"

#: common/flatpak-exports.c:955
#, fuzzy, c-format
msgid "Unable to get file type of \"%s\": %s"
msgstr "無法建立同步管道"

#: common/flatpak-exports.c:964
#, c-format
msgid "File \"%s\" has unsupported type 0o%o"
msgstr ""

#: common/flatpak-exports.c:970
#, c-format
msgid "Unable to get filesystem information for \"%s\": %s"
msgstr ""

#: common/flatpak-exports.c:980
#, c-format
msgid "Ignoring blocking autofs path \"%s\""
msgstr ""

#: common/flatpak-exports.c:996 common/flatpak-exports.c:1009
#: common/flatpak-exports.c:1022
#, c-format
msgid "Path \"%s\" is reserved by Flatpak"
msgstr ""

#: common/flatpak-exports.c:1076
#, fuzzy, c-format
msgid "Unable to resolve symbolic link \"%s\": %s"
msgstr "無法更新 %s：%s\n"

#: common/flatpak-glib-backports.c:69
msgid "Empty string is not a number"
msgstr "空字串不是數字"

#: common/flatpak-glib-backports.c:95
#, c-format
msgid "“%s” is not an unsigned number"
msgstr "「%s」不是無號數"

#: common/flatpak-glib-backports.c:105
#, c-format
msgid "Number “%s” is out of bounds [%s, %s]"
msgstr "數字「%s」超出邊界 [%s, %s]"

#: common/flatpak-image-source.c:83
msgid "Only sha256 image checksums are supported"
msgstr ""

#: common/flatpak-image-source.c:100 common/flatpak-image-source.c:108
msgid "Image is not a manifest"
msgstr "影像並非 manifest"

#: common/flatpak-image-source.c:123
msgid "No org.flatpak.ref found in image"
msgstr ""

#: common/flatpak-image-source.c:148
#, c-format
msgid "Ref '%s' not found in registry"
msgstr "註冊中找不到「%s」參照"

#: common/flatpak-image-source.c:157
msgid "Multiple images in registry, specify a ref with --ref"
msgstr "註冊中有多個映像檔，請以 --ref 指定一個參照"

#: common/flatpak-installation.c:834
#, c-format
msgid "Ref %s not installed"
msgstr "未安裝 %s 參照"

#: common/flatpak-installation.c:875
#, c-format
msgid "App %s not installed"
msgstr "未安裝 %s 程式"

#: common/flatpak-installation.c:1395
#, c-format
msgid "Remote '%s' already exists"
msgstr "遠端「%s」已經存在"

#: common/flatpak-installation.c:1946
#, c-format
msgid "As requested, %s was only pulled, but not installed"
msgstr "根據要求，%s 僅被拉入，但未安裝"

#: common/flatpak-instance.c:533 common/flatpak-instance.c:687
#: common/flatpak-instance.c:728
#, fuzzy, c-format
msgid "Unable to create directory %s"
msgstr "無法建立同步管道"

#: common/flatpak-instance.c:554
#, fuzzy, c-format
msgid "Unable to lock %s"
msgstr "無法查找金鑰 ID %s：%d"

#: common/flatpak-instance.c:627
#, fuzzy, c-format
msgid "Unable to create temporary directory in %s"
msgstr "無法建立布署目錄"

#: common/flatpak-instance.c:639
#, fuzzy, c-format
msgid "Unable to create file %s"
msgstr "無法建立同步管道"

#: common/flatpak-instance.c:646
#, fuzzy, c-format
msgid "Unable to update symbolic link %s/%s"
msgstr "無法更新 %s：%s\n"

#: common/flatpak-oci-registry.c:1197
msgid "Only Bearer authentication supported"
msgstr ""

#: common/flatpak-oci-registry.c:1206
#, fuzzy
msgid "Only realm in authentication request"
msgstr "無效的身分核對器名稱 %s"

#: common/flatpak-oci-registry.c:1213
#, fuzzy
msgid "Invalid realm in authentication request"
msgstr "無效的身分核對器名稱 %s"

#: common/flatpak-oci-registry.c:1283
#, fuzzy, c-format
msgid "Authorization failed: %s"
msgstr "身分核對器名稱：%s\n"

#: common/flatpak-oci-registry.c:1285
msgid "Authorization failed"
msgstr ""

#: common/flatpak-oci-registry.c:1289
#, c-format
msgid "Unexpected response status %d when requesting token: %s"
msgstr ""

#: common/flatpak-oci-registry.c:1300
#, fuzzy
msgid "Invalid authentication request response"
msgstr "無效的身分核對器名稱 %s"

#: common/flatpak-oci-registry.c:1731
#, c-format
msgid "Flatpak was compiled without zstd support"
msgstr ""

#: common/flatpak-oci-registry.c:1923 common/flatpak-oci-registry.c:1975
#: common/flatpak-oci-registry.c:2004 common/flatpak-oci-registry.c:2059
#: common/flatpak-oci-registry.c:2115 common/flatpak-oci-registry.c:2193
#, fuzzy
msgid "Invalid delta file format"
msgstr "檔案格式無效"

#: common/flatpak-oci-registry.c:3198 common/flatpak-oci-registry.c:3382
msgid "Invalid OCI image config"
msgstr ""

#: common/flatpak-oci-registry.c:3260 common/flatpak-oci-registry.c:3531
#, c-format
msgid "Wrong layer checksum, expected %s, was %s"
msgstr "錯誤的層次檢核碼，預期為 %s，實際為 %s"

#: common/flatpak-oci-registry.c:3359
#, c-format
msgid "No ref specified for OCI image %s"
msgstr "%s OCI 映像檔未指定參照"

#: common/flatpak-oci-registry.c:3369
#, c-format
msgid "Wrong ref (%s) specified for OCI image %s, expected %s"
msgstr "錯誤的參照 (%s) 指定給了 %s OCI 映像檔，預期為 %s"

#: common/flatpak-progress.c:236
#, c-format
msgid "Downloading metadata: %u/(estimating) %s"
msgstr "正在下載中介資料：%u/（估計）%s"

#: common/flatpak-progress.c:260
#, c-format
msgid "Downloading: %s/%s"
msgstr "正在下載：%s/%s"

#: common/flatpak-progress.c:280
#, c-format
msgid "Downloading extra data: %s/%s"
msgstr "正在下載額外資料：%s/%s"

#: common/flatpak-progress.c:285
#, c-format
msgid "Downloading files: %d/%d %s"
msgstr "正在下載檔案：%d/%d %s"

#: common/flatpak-ref-utils.c:122
msgid "Name can't be empty"
msgstr "名稱不能空白"

#: common/flatpak-ref-utils.c:129
msgid "Name can't be longer than 255 characters"
msgstr "名稱不能超過 255 個字元"

#: common/flatpak-ref-utils.c:142
msgid "Name can't start with a period"
msgstr "名稱不能以句號開始"

#: common/flatpak-ref-utils.c:148
#, c-format
msgid "Name can't start with %c"
msgstr "名稱不能以 %c 開始"

#: common/flatpak-ref-utils.c:164
msgid "Name can't end with a period"
msgstr "名稱不能以半形句點結尾"

#: common/flatpak-ref-utils.c:171 common/flatpak-ref-utils.c:183
msgid "Only last name segment can contain -"
msgstr "僅姓氏區段可以包含 -"

#: common/flatpak-ref-utils.c:174
#, c-format
msgid "Name segment can't start with %c"
msgstr "名稱區段不能以 %c 開始"

#: common/flatpak-ref-utils.c:186
#, c-format
msgid "Name can't contain %c"
msgstr "名稱不能包含 %c"

#: common/flatpak-ref-utils.c:195
msgid "Names must contain at least 2 periods"
msgstr "名稱必須包含至少兩個半形句點"

#: common/flatpak-ref-utils.c:312
#, fuzzy
msgid "Arch can't be empty"
msgstr "分支不能空白"

#: common/flatpak-ref-utils.c:323
#, fuzzy, c-format
msgid "Arch can't contain %c"
msgstr "分支不能包含 %c"

#: common/flatpak-ref-utils.c:385
msgid "Branch can't be empty"
msgstr "分支不能空白"

#: common/flatpak-ref-utils.c:395
#, c-format
msgid "Branch can't start with %c"
msgstr "分支不能以 %c 開始"

#: common/flatpak-ref-utils.c:405
#, c-format
msgid "Branch can't contain %c"
msgstr "分支不能包含 %c"

#: common/flatpak-ref-utils.c:615 common/flatpak-ref-utils.c:865
msgid "Ref too long"
msgstr ""

#: common/flatpak-ref-utils.c:627
#, fuzzy
msgid "Invalid remote name"
msgstr "遠端名稱不良：%s"

#: common/flatpak-ref-utils.c:641
#, c-format
msgid "%s is not application or runtime"
msgstr "%s 不是應用程式或執行時期環境"

#: common/flatpak-ref-utils.c:650 common/flatpak-ref-utils.c:667
#: common/flatpak-ref-utils.c:683
#, c-format
msgid "Wrong number of components in %s"
msgstr "%s 中的組件數量錯誤"

#: common/flatpak-ref-utils.c:656
#, fuzzy, c-format
msgid "Invalid name %.*s: %s"
msgstr "無效的 %s 名稱：%s"

#: common/flatpak-ref-utils.c:673
#, fuzzy, c-format
msgid "Invalid arch: %.*s: %s"
msgstr "無效的 %s 分支：%s"

#: common/flatpak-ref-utils.c:816
#, c-format
msgid "Invalid name %s: %s"
msgstr "無效的 %s 名稱：%s"

#: common/flatpak-ref-utils.c:834
#, fuzzy, c-format
msgid "Invalid arch: %s: %s"
msgstr "無效的 %s 分支：%s"

#: common/flatpak-ref-utils.c:853
#, fuzzy, c-format
msgid "Invalid branch: %s: %s"
msgstr "無效的 %s 分支：%s"

#: common/flatpak-ref-utils.c:962 common/flatpak-ref-utils.c:970
#: common/flatpak-ref-utils.c:978
#, fuzzy, c-format
msgid "Wrong number of components in partial ref %s"
msgstr "%s 執行時期環境中的組件數量錯誤"

#: common/flatpak-ref-utils.c:1298
#, fuzzy
msgid " development platform"
msgstr "使用開發用執行時期環境"

#: common/flatpak-ref-utils.c:1300
msgid " platform"
msgstr ""

#: common/flatpak-ref-utils.c:1302
#, fuzzy
msgid " application base"
msgstr "應用程式"

#: common/flatpak-ref-utils.c:1305
msgid " debug symbols"
msgstr ""

#: common/flatpak-ref-utils.c:1307
msgid " sourcecode"
msgstr ""

#: common/flatpak-ref-utils.c:1309
#, fuzzy
msgid " translations"
msgstr "安裝"

#: common/flatpak-ref-utils.c:1311
msgid " docs"
msgstr ""

#: common/flatpak-ref-utils.c:1578
#, c-format
msgid "Invalid id %s: %s"
msgstr "無效的 ID %s：%s"

#: common/flatpak-remote.c:1216
#, c-format
msgid "Bad remote name: %s"
msgstr "遠端名稱不良：%s"

#: common/flatpak-remote.c:1220
#, fuzzy
msgid "No URL specified"
msgstr "未指定 URL"

#: common/flatpak-remote.c:1266
msgid "GPG verification must be enabled when a collection ID is set"
msgstr "如有設定收藏 ID，則必須啟用 GPG 驗證"

#: common/flatpak-repo-utils.c:344
#, c-format
msgid "No extra data sources"
msgstr "沒有額外的資料來源"

#: common/flatpak-repo-utils.c:2817
#, c-format
msgid "Invalid %s: Missing group ‘%s’"
msgstr "%s 無效：缺少「%s」群組"

#: common/flatpak-repo-utils.c:2826
#, c-format
msgid "Invalid %s: Missing key ‘%s’"
msgstr "%s 無效：缺少「%s」鍵"

#: common/flatpak-repo-utils.c:2876
msgid "Invalid gpg key"
msgstr "無效的 GPG 金鑰"

#: common/flatpak-repo-utils.c:3217
#, c-format
msgid "Error copying 64x64 icon for component %s: %s\n"
msgstr "複製 %s 元件的 64x64 圖示時發生錯誤：%s\n"

#: common/flatpak-repo-utils.c:3223
#, c-format
msgid "Error copying 128x128 icon for component %s: %s\n"
msgstr "複製 %s 元件的 128x128 圖示時發生錯誤：%s\n"

#: common/flatpak-repo-utils.c:3362
#, fuzzy, c-format
msgid "%s is end-of-life, ignoring for appstream"
msgstr "%s 已經 end-of-life，故忽略\n"

#: common/flatpak-repo-utils.c:3397
#, c-format
msgid "No appstream data for %s: %s\n"
msgstr "%s 沒有 appstream 資料：%s\n"

#: common/flatpak-repo-utils.c:3744
msgid "Invalid bundle, no ref in metadata"
msgstr "無效的套組，中介資料內沒有參照"

#: common/flatpak-repo-utils.c:3846
#, c-format
msgid "Collection ‘%s’ of bundle doesn’t match collection ‘%s’ of remote"
msgstr "套組的「%s」收藏與遠端站點的「%s」收藏不符"

#: common/flatpak-repo-utils.c:3923
msgid "Metadata in header and app are inconsistent"
msgstr "檔案標頭的中介資料與程式不一致"

#: common/flatpak-run.c:951
msgid "No systemd user session available, cgroups not available"
msgstr "沒有可用的 systemd 使用者工作階段，cgroups 無法使用"

#: common/flatpak-run.c:1496
msgid "Unable to allocate instance id"
msgstr "無法分配實體 ID"

#: common/flatpak-run.c:1632 common/flatpak-run.c:1641
#, c-format
msgid "Failed to open flatpak-info file: %s"
msgstr "flatpak-info 檔開啟失敗：%s"

#: common/flatpak-run.c:1668
#, c-format
msgid "Failed to open bwrapinfo.json file: %s"
msgstr "bwrapinfo.json 檔開啟失敗：%s"

#: common/flatpak-run.c:1689
#, fuzzy, c-format
msgid "Failed to write to instance id fd: %s"
msgstr "無法寫入摘要快取： "

#: common/flatpak-run.c:2096
msgid "Initialize seccomp failed"
msgstr "seccomp 初始化失敗"

#: common/flatpak-run.c:2135
#, fuzzy, c-format
msgid "Failed to add architecture to seccomp filter: %s"
msgstr "架構新增至 seccomp 過濾器失敗"

#: common/flatpak-run.c:2143
#, fuzzy, c-format
msgid "Failed to add multiarch architecture to seccomp filter: %s"
msgstr "multiarch 架構新增至 seccomp 過濾器失敗"

#: common/flatpak-run.c:2175 common/flatpak-run.c:2192
#: common/flatpak-run.c:2214
#, fuzzy, c-format
msgid "Failed to block syscall %d: %s"
msgstr "封鎖系統呼叫 %d 失敗"

#: common/flatpak-run.c:2247
#, fuzzy, c-format
msgid "Failed to export bpf: %s"
msgstr "匯出 bpf 失敗"

#: common/flatpak-run.c:2587
#, c-format
msgid "Failed to open ‘%s’"
msgstr "無法開啟「%s」"

#: common/flatpak-run.c:2597
#, c-format
msgid ""
"Directory forwarding needs version 4 of the document portal (have version %d)"
msgstr ""

#: common/flatpak-run.c:2915
#, c-format
msgid "ldconfig failed, exit status %d"
msgstr "ldconfig 失敗，離開狀態為 %d"

#: common/flatpak-run.c:2922
msgid "Can't open generated ld.so.cache"
msgstr "無法開啟生成的 ld.so.cache"

#. Translators: The placeholder is for an app ref.
#: common/flatpak-run.c:3045
#, c-format
msgid "Running %s is not allowed by the policy set by your administrator"
msgstr "因管理員設定的方針，不允許執行 %s"

#: common/flatpak-run.c:3202
msgid ""
"\"flatpak run\" is not intended to be run as `sudo flatpak run`. Use `sudo "
"-i` or `su -l` instead and invoke \"flatpak run\" from inside the new shell."
msgstr ""

#: common/flatpak-run.c:3413
#, c-format
msgid "Failed to migrate from %s: %s"
msgstr "無法從 %s 轉移：%s"

#: common/flatpak-run.c:3434
#, c-format
msgid "Failed to migrate old app data directory %s to new name %s: %s"
msgstr "無法轉移舊的 App 資料目錄 %s 至新名稱 %s：%s"

#: common/flatpak-run.c:3443
#, c-format
msgid "Failed to create symlink while migrating %s: %s"
msgstr "無法在轉移 %s 時建立符號連結：%s"

#: common/flatpak-run-dbus.c:46
msgid "Failed to open app info file"
msgstr "程式資訊檔開啟失敗"

#: common/flatpak-run-dbus.c:149
msgid "Unable to create sync pipe"
msgstr "無法建立同步管道"

#: common/flatpak-run-dbus.c:185
msgid "Failed to sync with dbus proxy"
msgstr "與 dbus 代理同步失敗"

#: common/flatpak-transaction.c:2275
#, c-format
msgid "Warning: Problem looking for related refs: %s"
msgstr "警告：尋找相關參照時發生問題：%s"

#: common/flatpak-transaction.c:2493
#, c-format
msgid "The application %s requires the runtime %s which was not found"
msgstr "%s 應用程式要求的 %s 執行時期環境找不到"

#: common/flatpak-transaction.c:2509
#, c-format
msgid "The application %s requires the runtime %s which is not installed"
msgstr "%s 應用程式要求的 %s 執行時期環境尚未安裝"

#: common/flatpak-transaction.c:2641
#, c-format
msgid "Can't uninstall %s which is needed by %s"
msgstr "無法解除安裝 %s，它為 %s 所需要"

#: common/flatpak-transaction.c:2740
#, c-format
msgid "Remote %s disabled, ignoring %s update"
msgstr "%s 遠端已停用，故忽略 %s 更新"

#: common/flatpak-transaction.c:2773
#, c-format
msgid "%s is already installed"
msgstr "已經安裝 %s"

#: common/flatpak-transaction.c:2776
#, c-format
msgid "%s is already installed from remote %s"
msgstr "已經安裝來自 %2$s 遠端的 %1$s"

#: common/flatpak-transaction.c:3120
#, c-format
msgid "Invalid .flatpakref: %s"
msgstr "無效的 .flatpakref：%s"

#: common/flatpak-transaction.c:3161
msgid "Warning: Could not mark already installed apps as preinstalled"
msgstr ""

#: common/flatpak-transaction.c:3382
#, c-format
msgid "Error updating remote metadata for '%s': %s"
msgstr "更新「%s」的遠端中介資料時發生錯誤：%s"

#: common/flatpak-transaction.c:3885
#, c-format
msgid ""
"Warning: Treating remote fetch error as non-fatal since %s is already "
"installed: %s"
msgstr "警告：由於已經安裝 %s，因此將遠端擷取錯誤視為非重大錯誤：%s"

#: common/flatpak-transaction.c:4209
#, fuzzy, c-format
msgid "No authenticator installed for remote '%s'"
msgstr "未設定用於「%s」遠端的身分核對器"

#: common/flatpak-transaction.c:4313 common/flatpak-transaction.c:4320
#, fuzzy, c-format
msgid "Failed to get tokens for ref: %s"
msgstr "從參照判定部分失敗：%s"

#: common/flatpak-transaction.c:4315 common/flatpak-transaction.c:4322
#, fuzzy
msgid "Failed to get tokens for ref"
msgstr "從參照判定部分失敗：%s"

#: common/flatpak-transaction.c:4580
#, c-format
msgid "Ref %s from %s matches more than one transaction operation"
msgstr ""

#: common/flatpak-transaction.c:4581 common/flatpak-transaction.c:4591
#, fuzzy
msgid "any remote"
msgstr "遠端"

#: common/flatpak-transaction.c:4590
#, c-format
msgid "No transaction operation found for ref %s from %s"
msgstr ""

#: common/flatpak-transaction.c:4713
#, c-format
msgid "Flatpakrepo URL %s not file, HTTP or HTTPS"
msgstr "Flatpakrepo URL %s 不是檔案、HTTP 或 HTTPS"

#: common/flatpak-transaction.c:4719
#, c-format
msgid "Can't load dependent file %s: "
msgstr "無法載入依賴檔案 %s： "

#: common/flatpak-transaction.c:4727
#, c-format
msgid "Invalid .flatpakrepo: %s"
msgstr "無效的 .flatpakrepo：%s"

#: common/flatpak-transaction.c:5454
msgid "Transaction already executed"
msgstr "處理事項已經執行"

#: common/flatpak-transaction.c:5469
msgid ""
"Refusing to operate on a user installation as root! This can lead to "
"incorrect file ownership and permission errors."
msgstr "拒絕以 root 在使用者安裝操作！這可能會導致檔案所有權不正確及權限錯誤。"

#: common/flatpak-transaction.c:5567 common/flatpak-transaction.c:5580
msgid "Aborted by user"
msgstr "由使用者中止"

#: common/flatpak-transaction.c:5605
#, c-format
msgid "Skipping %s due to previous error"
msgstr "因為先前的錯誤而略過 %s"

#: common/flatpak-transaction.c:5659
#, fuzzy, c-format
msgid "Aborted due to failure (%s)"
msgstr "因為失敗而中止"

#: common/flatpak-uri.c:118
#, fuzzy, no-c-format
msgid "Invalid %-encoding in URI"
msgstr "無效的身分核對器名稱 %s"

#: common/flatpak-uri.c:135
msgid "Illegal character in URI"
msgstr ""

#: common/flatpak-uri.c:169
msgid "Non-UTF-8 characters in URI"
msgstr ""

#: common/flatpak-uri.c:275
#, c-format
msgid "Invalid IPv6 address ‘%.*s’ in URI"
msgstr ""

#: common/flatpak-uri.c:330
#, c-format
msgid "Illegal encoded IP address ‘%.*s’ in URI"
msgstr ""

#: common/flatpak-uri.c:342
#, c-format
msgid "Illegal internationalized hostname ‘%.*s’ in URI"
msgstr ""

#: common/flatpak-uri.c:374 common/flatpak-uri.c:386
#, fuzzy, c-format
msgid "Could not parse port ‘%.*s’ in URI"
msgstr "無法解析「%s」"

#: common/flatpak-uri.c:393
#, c-format
msgid "Port ‘%.*s’ in URI is out of range"
msgstr ""

#: common/flatpak-uri.c:910
msgid "URI is not absolute, and no base URI was provided"
msgstr ""

#: common/flatpak-usb.c:83
#, c-format
msgid "USB device query 'all' must not have data"
msgstr ""

#: common/flatpak-usb.c:102
#, c-format
msgid "USB query rule 'cls' must be in the form CLASS:SUBCLASS or CLASS:*"
msgstr ""

#: common/flatpak-usb.c:111
#, fuzzy, c-format
msgid "Invalid USB class"
msgstr "無效的 ID %s：%s"

#: common/flatpak-usb.c:125
#, c-format
msgid "Invalid USB subclass"
msgstr ""

#: common/flatpak-usb.c:141 common/flatpak-usb.c:148
#, c-format
msgid "USB query rule 'dev' must have a valid 4-digit hexadecimal product id"
msgstr ""

#: common/flatpak-usb.c:164 common/flatpak-usb.c:171
#, c-format
msgid "USB query rule 'vnd' must have a valid 4-digit hexadecimal vendor id"
msgstr ""

#: common/flatpak-usb.c:205
#, c-format
msgid "USB device queries must be in the form TYPE:DATA"
msgstr ""

#: common/flatpak-usb.c:225
#, c-format
msgid "Unknown USB query rule %s"
msgstr ""

#: common/flatpak-usb.c:248
#, c-format
msgid "Empty USB query"
msgstr ""

#: common/flatpak-usb.c:274
#, c-format
msgid "Multiple USB query rules of the same type is not supported"
msgstr ""

#: common/flatpak-usb.c:283
#, c-format
msgid "'all' must not contain extra query rules"
msgstr ""

#: common/flatpak-usb.c:291
#, c-format
msgid "USB queries with 'dev' must also specify vendors"
msgstr ""

#: common/flatpak-utils.c:712
msgid "Glob can't match apps"
msgstr ""

#: common/flatpak-utils.c:737
msgid "Empty glob"
msgstr "glob 空白"

#: common/flatpak-utils.c:756
msgid "Too many segments in glob"
msgstr "glob 中的區段過多"

#: common/flatpak-utils.c:777
#, c-format
msgid "Invalid glob character '%c'"
msgstr "「%c」glob 字元無效"

#: common/flatpak-utils.c:831
#, c-format
msgid "Missing glob on line %d"
msgstr "第 %d 列沒有 glob"

#: common/flatpak-utils.c:835
#, c-format
msgid "Trailing text on line %d"
msgstr "第 %d 列末尾有文字"

#: common/flatpak-utils.c:839
#, c-format
msgid "on line %d"
msgstr "在第 %d 列"

#: common/flatpak-utils.c:861
#, c-format
msgid "Unexpected word '%s' on line %d"
msgstr "第 %2$d 列有非預期的「%1$s」單字"

#: common/flatpak-utils.c:2118
#, c-format
msgid "Invalid require-flatpak argument %s"
msgstr "無效的 require-flatpak 引數 %s"

#: common/flatpak-utils.c:2128 common/flatpak-utils.c:2147
#, c-format
msgid "%s needs a later flatpak version (%s)"
msgstr "%s 需要較新的 flatpak 版本 (%s)"

#: oci-authenticator/flatpak-oci-authenticator.c:291
msgid "Not a oci remote, missing summary.xa.oci-repository"
msgstr ""

#: oci-authenticator/flatpak-oci-authenticator.c:477
msgid "Not a OCI remote"
msgstr ""

#: oci-authenticator/flatpak-oci-authenticator.c:488
#, fuzzy
msgid "Invalid token"
msgstr "無效的 GPG 金鑰"

#: portal/flatpak-portal.c:2292
#, c-format
msgid "No portal support found"
msgstr "找不到入口支援"

#: portal/flatpak-portal.c:2298
msgid "Deny"
msgstr "拒絕"

#: portal/flatpak-portal.c:2300
msgid "Update"
msgstr "更新"

#: portal/flatpak-portal.c:2305
#, c-format
msgid "Update %s?"
msgstr "是否更新 %s？"

#: portal/flatpak-portal.c:2317
msgid "The application wants to update itself."
msgstr "應用程式想要自我更新。"

#: portal/flatpak-portal.c:2318
msgid "Update access can be changed any time from the privacy settings."
msgstr "更新存取權限隨時都可以在隱私權設定變更。"

#: portal/flatpak-portal.c:2343
#, c-format
msgid "Application update not allowed"
msgstr "不允許應用程式更新"

#: portal/flatpak-portal.c:2501
#, c-format
msgid "Self update not supported, new version requires new permissions"
msgstr "不支援自我更新，新版需要新權限"

#: portal/flatpak-portal.c:2684 portal/flatpak-portal.c:2702
#, c-format
msgid "Update ended unexpectedly"
msgstr "更新非預期結束"

#. SECURITY:
#. - Normal users need admin authentication to install software
#. system-wide.
#. - Note that we install polkit rules that allow local users
#. in the wheel group to install without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:23
msgid "Install signed application"
msgstr "安裝已簽署的應用程式"

#: system-helper/org.freedesktop.Flatpak.policy.in:24
#: system-helper/org.freedesktop.Flatpak.policy.in:42
msgid "Authentication is required to install software"
msgstr "安裝軟體時必須通過身分核對"

#. SECURITY:
#. - Normal users need admin authentication to install software
#. system-wide.
#. - Note that we install polkit rules that allow local users
#. in the wheel group to install without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:41
msgid "Install signed runtime"
msgstr "安裝已簽署的執行時期環境"

#. SECURITY:
#. - Normal users do not require admin authentication to update an
#. app as the commit will be signed, and the action is required
#. to update the system when unattended.
#. - Changing this to anything other than 'yes' will break unattended
#. updates.
#: system-helper/org.freedesktop.Flatpak.policy.in:60
msgid "Update signed application"
msgstr "更新已簽署的應用程式"

#: system-helper/org.freedesktop.Flatpak.policy.in:61
#: system-helper/org.freedesktop.Flatpak.policy.in:80
msgid "Authentication is required to update software"
msgstr "更新軟體時必須通過身分核對"

#. SECURITY:
#. - Normal users do not require admin authentication to update a
#. runtime as the commit will be signed, and the action is required
#. to update the system when unattended.
#. - Changing this to anything other than 'yes' will break unattended
#. updates.
#: system-helper/org.freedesktop.Flatpak.policy.in:79
msgid "Update signed runtime"
msgstr "更新已簽署的執行時期環境"

#. SECURITY:
#. - Normal users do not need authentication to update metadata
#. from signed repositories.
#: system-helper/org.freedesktop.Flatpak.policy.in:94
msgid "Update remote metadata"
msgstr "更新遠端的中介資料"

#: system-helper/org.freedesktop.Flatpak.policy.in:95
msgid "Authentication is required to update remote info"
msgstr "更新遠端資訊時必須通過身分核對"

#. SECURITY:
#. - Normal users do not need authentication to modify the
#. OSTree repository
#. - Note that we install polkit rules that allow local users
#. in the wheel group to modify repos without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:111
msgid "Update system repository"
msgstr "更新系統軟體庫"

#: system-helper/org.freedesktop.Flatpak.policy.in:112
msgid "Authentication is required to modify a system repository"
msgstr "修改系統軟體庫時必須通過身分核對"

#. SECURITY:
#. - Normal users need admin authentication to install software
#. system-wide.
#: system-helper/org.freedesktop.Flatpak.policy.in:126
msgid "Install bundle"
msgstr "安裝套組"

#: system-helper/org.freedesktop.Flatpak.policy.in:127
msgid "Authentication is required to install software from $(path)"
msgstr "從 $(path) 安裝軟體需要通過身分核對"

#. SECURITY:
#. - Normal users need admin authentication to uninstall software
#. system-wide.
#. - Note that we install polkit rules that allow local users
#. in the wheel group to uninstall without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:144
msgid "Uninstall runtime"
msgstr "解除安裝執行時期環境"

#: system-helper/org.freedesktop.Flatpak.policy.in:145
msgid "Authentication is required to uninstall software"
msgstr "解除安裝軟體時必須通過身分核對"

#. SECURITY:
#. - Normal users need admin authentication to uninstall software
#. system-wide.
#. - Note that we install polkit rules that allow local users
#. in the wheel group to uninstall without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:161
msgid "Uninstall app"
msgstr "解除安裝程式"

#: system-helper/org.freedesktop.Flatpak.policy.in:162
msgid "Authentication is required to uninstall $(ref)"
msgstr "解除安裝 $(ref) 時必須通過身分核對"

#. SECURITY:
#. - Normal users need admin authentication to configure system-wide
#. software repositories.
#: system-helper/org.freedesktop.Flatpak.policy.in:177
msgid "Configure Remote"
msgstr "設定遠端站點"

#: system-helper/org.freedesktop.Flatpak.policy.in:178
msgid "Authentication is required to configure software repositories"
msgstr "設定軟體軟體庫時必須通過身分核對"

#. SECURITY:
#. - Normal users need admin authentication to configure the system-wide
#. Flatpak installation.
#: system-helper/org.freedesktop.Flatpak.policy.in:192
msgid "Configure"
msgstr "設定"

#: system-helper/org.freedesktop.Flatpak.policy.in:193
msgid "Authentication is required to configure software installation"
msgstr "設定軟體安裝時必須通過身分核對"

#. SECURITY:
#. - Normal users do not require admin authentication to update
#. appstream data as it will be signed, and the action is required
#. to update the system when unattended.
#. - Changing this to anything other than 'yes' will break unattended
#. updates.
#: system-helper/org.freedesktop.Flatpak.policy.in:210
msgid "Update appstream"
msgstr "更新 appstream"

#: system-helper/org.freedesktop.Flatpak.policy.in:211
msgid "Authentication is required to update information about software"
msgstr "更新軟體資訊時必須通過身分核對"

#. SECURITY:
#. - Normal users do not require admin authentication to update
#. metadata as it will be signed, and the action is required
#. to update the system when unattended.
#. - Changing this to anything other than 'yes' will break unattended
#. updates.
#: system-helper/org.freedesktop.Flatpak.policy.in:228
msgid "Update metadata"
msgstr "更新中介資料"

#: system-helper/org.freedesktop.Flatpak.policy.in:229
msgid "Authentication is required to update metadata"
msgstr "更新中介資料時必須通過身分核對"

#. SECURITY:
#. - Authorisation to actually install software is controlled by
#. org.freedesktop.Flatpak.app-install.
#. - This action is checked after app-install, as it can only be done
#. once the app’s data (including its content rating) has been
#. downloaded.
#. - This action is checked to see if the installation should be allowed
#. based on whether the app being installed has content which doesn’t
#. comply with the user’s parental controls policy (the content is
#. ‘too extreme’).
#. - It is checked only if an app has too extreme content for the user
#. who is trying to install it (in which case, the app is ‘unsafe’).
#. - Typically, normal users will need admin permission to install apps
#. with extreme content; admins will be able to install it without
#. additional checks.
#. - In order to configure the policy so that admins can install safe and
#. unsafe software anywhere without authorisation, and non-admins can
#. install safe software in their user or system dirs without
#. authorisation, but need authorisation to install unsafe software
#. anywhere:
#. * Unconditionally return `yes` from `app-install`.
#. * Return `auth_admin` from `override-parental-controls` for users
#. not in `@privileged_group@`, and `yes` for users in it.
#. * Set the malcontent `is-{user,system}-installation-allowed`
#. properties of all non-admins’ parental controls policies to true.
#. - In order to configure the policy so that admins can install safe and
#. unsafe software anywhere without authorisation, and non-admins can
#. install safe software in their user dir without authorisation, but
#. need authorisation to install safe software in the system dir or to
#. install unsafe software anywhere:
#. * Unconditionally return `yes` from `app-install`.
#. * Return `auth_admin` from `override-parental-controls` for users
#. not in `@privileged_group@`, and `yes` for users in it.
#. * Set the malcontent `is-user-installation-allowed` property of all
#. non-admins’ parental controls policies to true.
#. * Set the malcontent `is-system-installation-allowed` property of
#. all non-admins’ parental controls policies to false.
#. - In order to configure the policy so that all users (including
#. admins) can install safe software anywhere without authorisation,
#. but need authorisation to install unsafe software anywhere (i.e.
#. applying parental controls to admins too):
#. * Unconditionally return `yes` from `app-install`.
#. * Unconditionally return `auth_admin` from `override-parental-controls`.
#. * Set the malcontent `is-user-installation-allowed` property of all
#. users’ parental controls policies to true.
#. * Set the malcontent `is-system-installation-allowed` property of
#. all users’ parental controls policies to true.
#: system-helper/org.freedesktop.Flatpak.policy.in:287
#, fuzzy
msgid "Override parental controls for installs"
msgstr "覆蓋上級控制"

#: system-helper/org.freedesktop.Flatpak.policy.in:288
msgid ""
"Authentication is required to install software which is restricted by your "
"parental controls policy"
msgstr "安裝被上級控制方針限制的軟體時需要通過身分驗證"

#. SECURITY:
#. - This is like org.freedesktop.Flatpak.override-parental-controls, but
#. it’s queried for app updates, whereas the former is queried for app
#. installs.
#. - As with the above action, this one is only queried if
#. org.freedesktop.Flatpak.app-update has allowed the app update, and
#. only if the app being updated has too extreme content for the user
#. who is trying to update it.
#. - The default policy for this is to *allow* updates to ‘too extreme’
#. apps by default, on the basis that having an out-of-date (i.e.
#. insecure or unsupported) app is a worse outcome than automatically
#. installing an update which has radically different content from the
#. version of the app which the parent originally vetted and installed.
#: system-helper/org.freedesktop.Flatpak.policy.in:313
#, fuzzy
msgid "Override parental controls for updates"
msgstr "覆蓋上級控制"

#: system-helper/org.freedesktop.Flatpak.policy.in:314
#, fuzzy
msgid ""
"Authentication is required to update software which is restricted by your "
"parental controls policy"
msgstr "安裝被上級控制方針限制的軟體時需要通過身分驗證"

#~ msgid "Installed:"
#~ msgstr "已安裝："

#~ msgid "Download:"
#~ msgstr "下載："

#, c-format
#~ msgid "No gpg key found with ID %s (homedir: %s)"
#~ msgstr "找不到 ID %s 的 GPG 金鑰（家目錄：%s）"

#, fuzzy, c-format
#~ msgid "Unable to lookup key ID %s: %d"
#~ msgstr "無法查找金鑰 ID %s：%d"

#, c-format
#~ msgid "Error signing commit: %d"
#~ msgstr "簽署提交時發生錯誤：%d"

#, c-format
#~ msgid ""
#~ "Found similar ref(s) for ‘%s’ in remote ‘%s’ (%s).\n"
#~ "Use this remote?"
#~ msgstr ""
#~ "找到「%s」的相似參照（在「%s」(%s) 遠端）。\n"
#~ "是否使用此遠端？"

#, fuzzy, c-format
#~ msgid "No entry for %s in remote '%s' summary cache "
#~ msgstr "在「%2$s」遠端的摘要 flatpak 快取中沒有 %1$s 條目 "

#, fuzzy, c-format
#~ msgid "Failed to uninstall %s for rebase to %s: "
#~ msgstr "無法將 %s rebase 至 %s： "

#, fuzzy, c-format
#~ msgid "Failed to uninstall %s for rebase to %s: %s\n"
#~ msgstr "無法重定 %s 的基底 (rebase) 至 %s：%s\n"

#, fuzzy, c-format
#~ msgid "Unable to open directory %s"
#~ msgstr "無法連接系統匯流排"

#~ msgid "install"
#~ msgstr "安裝"

#~ msgid "update"
#~ msgstr "更新"

#~ msgid "install bundle"
#~ msgstr "安裝套組"

#~ msgid "uninstall"
#~ msgstr "解除安裝"

#~ msgid "Warning:"
#~ msgstr "警告："

#, fuzzy
#~ msgid "runtime"
#~ msgstr "執行時期環境"

#, fuzzy
#~ msgid "app"
#~ msgstr "程式"

#, c-format
#~ msgid "%s Failed to %s %s: %s\n"
#~ msgstr "%s 無法%s %s：%s\n"

#~ msgid "[REF…] - Uninstall an application"
#~ msgstr "[REF…] - 解除安裝應用程式"

#, c-format
#~ msgid "Replace it with %s?"
#~ msgstr "是否用 %s 取代？"

#~ msgid "\"flatpak run\" is not intended to be ran with sudo"
#~ msgstr "「flatpak run」不應使用 sudo 執行"

#, c-format
#~ msgid "Invalid deployed ref %s: "
#~ msgstr "無效的已布署 %s 參照："

#, c-format
#~ msgid "Deployed ref %s kind does not match commit (%s)"
#~ msgstr "已布署的 %s 參照類型與提交不符（%s）"

#, c-format
#~ msgid "Deployed ref %s name does not match commit (%s)"
#~ msgstr "已布署的 %s 參照名稱與提交不符（%s）"

#, c-format
#~ msgid "Deployed ref %s arch does not match commit (%s)"
#~ msgstr "已布署的 %s 參照架構與提交不符（%s）"

#, c-format
#~ msgid "Failed to determine parts from ref: %s"
#~ msgstr "從參照判定部分失敗：%s"

#, c-format
#~ msgid "Invalid arch %s"
#~ msgstr "無效的 %s 架構"

#, c-format
#~ msgid "Related ref '%s' is only partially installed"
#~ msgstr "僅部分安裝「%s」相關參照"

#, c-format
#~ msgid "Ref '%s' is only partially installed"
#~ msgstr "僅部分安裝「%s」參照"

#, c-format
#~ msgid "No such ref (%s, %s) in remote %s"
#~ msgstr "在遠端 %3$s 中無此參照 (%1$s, %2$s)"

#, c-format
#~ msgid "No flatpak cache in remote '%s' summary"
#~ msgstr "在遠端「%s」摘要中沒有 flatpak 快取"

#, c-format
#~ msgid "No such ref (%s, %s) in remote %s or elsewhere"
#~ msgstr "在 %3$s 遠端中或其他地方無此參照 (%1$s, %2$s)"

#~ msgid "No summary found"
#~ msgstr "找不到摘要"

#, c-format
#~ msgid ""
#~ "GPG verification enabled, but no summary signatures found for remote '%s'"
#~ msgstr "GPG 驗證已啟用，但「%s」遠端找不到摘要簽章"

#, c-format
#~ msgid ""
#~ "GPG signatures found for remote '%s', but none are in trusted keyring"
#~ msgstr "找到「%s」遠端的 GPG 簽章，但不在受信任的鑰匙圈中"

#~ msgid "Expected commit metadata to have ref binding information, found none"
#~ msgstr "提交的中介資料預期有參照綁定資訊，但找不到"

#~ msgid ""
#~ "Expected commit metadata to have collection ID binding information, found "
#~ "none"
#~ msgstr "提交的中介資料預期有收藏 ID 綁定資訊，但找不到"

#, c-format
#~ msgid ""
#~ "Commit has collection ID ‘%s’ in collection binding metadata, while the "
#~ "remote it came from has collection ID ‘%s’"
#~ msgstr ""
#~ "提交的收藏綁定中介資料中採用的是「%s」收藏 ID ，而它所來自的遠端則是「%s」"
#~ "收藏 ID"

#~ msgid "Deployed metadata does not match commit"
#~ msgstr "已布署的中介資料與提交不符"

#, fuzzy, c-format
#~ msgid "No repo metadata cached for remote '%s'"
#~ msgstr "%s 遠端沒有摘要或 Flatpak 快取"

#~ msgid "No metadata branch for OCI"
#~ msgstr "沒有 OCI 的中介資料分支"

#, c-format
#~ msgid "Invalid group: %d"
#~ msgstr "無效的群組：%d"

#, c-format
#~ msgid "Warning: Can't find %s metadata for dependencies: %s"
#~ msgstr "警告：找不到依賴的 %s 中介資料：%s"

#~ msgid "Not running as root, may be unable to enter namespace"
#~ msgstr "若不以 root 身份執行，可能無法進入 namespace"

#, fuzzy
#~ msgid "Default system installation"
#~ msgstr "顯示系統層級的安裝"

#~ msgid "No url specified in flatpakrepo file"
#~ msgstr "flatpakrepo 檔案中未指定 URL"

#~ msgid "Extracting icons for component %s\n"
#~ msgstr "正在抽出 %s 組件的圖示\n"

#~ msgid "%s branch already installed"
#~ msgstr "已經安裝 %s 分支"

#~ msgid "%s branch %s not installed"
#~ msgstr "%s 的 %s 分支未安裝"

#~ msgid "0"
#~ msgstr "0"

#~ msgid "Print OSTree debug information during command processing"
#~ msgstr "列印指令處理時期的 OSTree 除錯資訊"

#~ msgid "Show help options"
#~ msgstr "顯示幫助說明選項"

#~ msgid "Architecture"
#~ msgstr "架構"

#~ msgid "Location:"
#~ msgstr "位置："

#~ msgid "Installing for user: %s from %s\n"
#~ msgstr "正在為使用者安裝：%s 來自 %s\n"

#~ msgid "Installing: %s from %s\n"
#~ msgstr "正在安裝：%s 來自 %s\n"

#~ msgid "Updating for user: %s from %s\n"
#~ msgstr "正在為使用者更新：%s 來自 %s\n"

#~ msgid "Updating: %s from %s\n"
#~ msgstr "正在更新：%s 來自 %s\n"

#~ msgid "Installing for user: %s from bundle %s\n"
#~ msgstr "正在為使用者安裝：%s 來自 %s 套組\n"

#~ msgid "Installing: %s from bundle %s\n"
#~ msgstr "正在安裝：%s 來自 %s 套組\n"

#~ msgid "Uninstalling for user: %s\n"
#~ msgstr "正在為使用者解除安裝：%s\n"

#~ msgid "No updates.\n"
#~ msgstr "沒有更新。\n"

#~ msgid "Now at %s.\n"
#~ msgstr "現在位於 %s。\n"

#~ msgid "new file access"
#~ msgstr "新檔案存取"

#~ msgid "file access"
#~ msgstr "檔案存取"

#~ msgid "new dbus access"
#~ msgstr "新 dbus 存取"

#~ msgid "dbus access"
#~ msgstr "dbus 存取"

#~ msgid "new dbus ownership"
#~ msgstr "新 dbus 擁有權"

#~ msgid "dbus ownership"
#~ msgstr "dbus 擁有權"

#~ msgid "new system dbus access"
#~ msgstr "新系統 dbus 存取"

#~ msgid "system dbus access"
#~ msgstr "系統 dbus 存取"

#~ msgid "new system dbus ownership"
#~ msgstr "新系統 dbus 擁有權"

#~ msgid "system dbus ownership"
#~ msgstr "系統 dbus 擁有權"

#~ msgid "new tags"
#~ msgstr "新標籤"

#~ msgid "tags"
#~ msgstr "標籤"

#~ msgid "Is this ok"
#~ msgstr "這樣可以嗎"

#~ msgid "Invalid .flatpakref"
#~ msgstr "無效的 .flatpakref"

#, fuzzy
#~ msgid "Authentication is required to install $(ref) from $(origin)"
#~ msgstr "安裝軟體時必須通過身分核對"

#, fuzzy
#~ msgid "Authentication is required to update $(ref) from $(origin)"
#~ msgstr "更新遠端資訊時必須通過身分核對"

#, fuzzy
#~ msgid "Authentication is required to update the remote $(remote)"
#~ msgstr "更新遠端資訊時必須通過身分核對"

#, fuzzy
#~ msgid "Authentication is required to modify the remote $(remote)"
#~ msgstr "更新遠端資訊時必須通過身分核對"

#, fuzzy
#~ msgid "Authentication is required to configure the remote $(remote)"
#~ msgstr "設定軟體庫時必須通過身分核對"

#~ msgid ""
#~ "DST-REPO [DST-REF]... - Make a new commit based on existing commit(s)"
#~ msgstr "DST-REPO [DST-REF]... - 以既有的提交（可多項）為基礎做新提交"

#~ msgid "You must specify key"
#~ msgstr "您必須指定鍵"

#~ msgid "You must specify both key and value"
#~ msgstr "您必須同時指定鍵與值"

#~ msgid ""
#~ "SANDBOXEDPID [COMMAND [args...]] - Run a command inside a running sandbox"
#~ msgstr "SANDBOXEDPID [COMMAND [args...]] - 在運行中的沙盒裡執行指令"

#~ msgid "SANDBOXEDPID and COMMAND must be specified"
#~ msgstr "必須指定 SANDBOXEDPID 與 COMMAND"

#~ msgid "Runtime Branch"
#~ msgstr "執行時環境分支"

#~ msgid "Runtime Commit"
#~ msgstr "執行時環境提交"

#~ msgid "Child PID"
#~ msgstr "子代 PID"

#~ msgid "Unknown command '%s'"
#~ msgstr "未知的「%s」指令"

#~ msgid "Migrating %s to %s\n"
#~ msgstr "正在遷移 %s 至 %s\n"

#~ msgid "Error during migration: %s\n"
#~ msgstr "遷移時發生錯誤：%s\n"

===== ./po/de.po =====
# German translation for flatpak.
# Copyright (C) 2016 flatpak's COPYRIGHT HOLDER
# This file is distributed under the same license as the flatpak package.
# Wolfgang Stöggl <c72578@yahoo.de>, 2016.
# Mario Blättermann <mario.blaettermann@gmail.com>, 2016-2017.
# Thomas Siegele <tsiegele@gmx.at>, 2019
# Christian Kirbach <christian.kirbach@gmail.com>, 2017, 2021.
# Philipp Kiemle <philipp.kiemle@gmail.com>, 2021.
# Ettore Atalan <atalanttore@gmail.com>, 2022.
# Philipp Trulson <philipp@trulson.de>, 2023.
#
msgid ""
msgstr ""
"Project-Id-Version: flatpak master\n"
"Report-Msgid-Bugs-To: https://github.com/flatpak/flatpak/issues\n"
"POT-Creation-Date: 2026-05-27 16:39+0200\n"
"PO-Revision-Date: 2023-11-23 23:33+0100\n"
"Last-Translator: Philipp Trulson <philipp@trulson.de>\n"
"Language-Team: German <gnome-de@gnome.org>\n"
"Language: de\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Generator: Poedit 3.4.1\n"

#: app/flatpak-builtins-build-bundle.c:59
msgid "Export runtime instead of app"
msgstr "Laufzeitumgebung anstelle der Anwendung exportieren"

#: app/flatpak-builtins-build-bundle.c:60
msgid "Arch to bundle for"
msgstr "Architektur für die gebündelt wird"

#: app/flatpak-builtins-build-bundle.c:60
#: app/flatpak-builtins-build-export.c:62 app/flatpak-builtins-build-init.c:53
#: app/flatpak-builtins-build-sign.c:42 app/flatpak-builtins-create-usb.c:46
#: app/flatpak-builtins-info.c:55 app/flatpak-builtins-install.c:67
#: app/flatpak-builtins-list.c:50 app/flatpak-builtins-make-current.c:38
#: app/flatpak-builtins-remote-info.c:54 app/flatpak-builtins-remote-ls.c:56
#: app/flatpak-builtins-run.c:158 app/flatpak-builtins-search.c:37
#: app/flatpak-builtins-uninstall.c:54 app/flatpak-builtins-update.c:56
msgid "ARCH"
msgstr "ARCH"

#: app/flatpak-builtins-build-bundle.c:61
#, fuzzy
msgid "URL for repo"
msgstr "Adresse für Quelle"

#: app/flatpak-builtins-build-bundle.c:61
#: app/flatpak-builtins-build-bundle.c:62
#: app/flatpak-builtins-build-update-repo.c:68
#: app/flatpak-builtins-build-update-repo.c:72
#: app/flatpak-builtins-build-update-repo.c:73
#: app/flatpak-builtins-history.c:69 app/flatpak-builtins-remote-add.c:80
#: app/flatpak-builtins-remote-add.c:81 app/flatpak-builtins-remote-add.c:85
#: app/flatpak-builtins-remote-list.c:53
#: app/flatpak-builtins-remote-modify.c:70
#: app/flatpak-builtins-remote-modify.c:85
#: app/flatpak-builtins-remote-modify.c:86
#: app/flatpak-builtins-remote-modify.c:90
msgid "URL"
msgstr "ADRESSE"

#: app/flatpak-builtins-build-bundle.c:62
#, fuzzy
msgid "URL for runtime flatpakrepo file"
msgstr "Adresse der flatpakrepo-Datei der Laufzeit"

#: app/flatpak-builtins-build-bundle.c:63
msgid "Add GPG key from FILE (- for stdin)"
msgstr "GPG-Schlüssel aus DATEI hinzufügen (- für stdin)"

#: app/flatpak-builtins-build-bundle.c:63 app/flatpak-builtins-build.c:54
#: app/flatpak-builtins-build-export.c:67
#: app/flatpak-builtins-build-update-repo.c:83
#: app/flatpak-builtins-install.c:81 app/flatpak-builtins-remote-add.c:84
#: app/flatpak-builtins-remote-add.c:86 app/flatpak-builtins-remote-modify.c:89
#: app/flatpak-builtins-remote-modify.c:92
msgid "FILE"
msgstr "DATEI"

#: app/flatpak-builtins-build-bundle.c:64
msgid "GPG Key ID to sign the OCI image with"
msgstr "GPG-Schlüsselkennung zum Unterschreiben des OCI-Abbilds"

#: app/flatpak-builtins-build-bundle.c:64
#: app/flatpak-builtins-build-commit-from.c:68
#: app/flatpak-builtins-build-export.c:68
#: app/flatpak-builtins-build-import-bundle.c:49
#: app/flatpak-builtins-build-sign.c:44
#: app/flatpak-builtins-build-update-repo.c:84
msgid "KEY-ID"
msgstr "SCHLÜSSELKENNUNG"

#: app/flatpak-builtins-build-bundle.c:65
#: app/flatpak-builtins-build-commit-from.c:69
#: app/flatpak-builtins-build-export.c:71
#: app/flatpak-builtins-build-import-bundle.c:50
#: app/flatpak-builtins-build-sign.c:45
#: app/flatpak-builtins-build-update-repo.c:85
msgid "GPG Homedir to use when looking for keyrings"
msgstr "GPG-Basisordner für die Suche nach Schlüsselbünden"

#: app/flatpak-builtins-build-bundle.c:65
#: app/flatpak-builtins-build-commit-from.c:69
#: app/flatpak-builtins-build-export.c:71
#: app/flatpak-builtins-build-import-bundle.c:50
#: app/flatpak-builtins-build-sign.c:45
#: app/flatpak-builtins-build-update-repo.c:85
msgid "HOMEDIR"
msgstr "BASISORDNER"

#: app/flatpak-builtins-build-bundle.c:66
msgid "OSTree commit to create a delta bundle from"
msgstr ""

#: app/flatpak-builtins-build-bundle.c:66 app/flatpak-builtins-remote-info.c:55
#: app/flatpak-builtins-update.c:57
msgid "COMMIT"
msgstr "COMMIT"

#: app/flatpak-builtins-build-bundle.c:67
msgid "Export oci image instead of flatpak bundle"
msgstr "In ein OCI-Abbild anstelle eines Flatpak-Bündels exportieren"

#: app/flatpak-builtins-build-bundle.c:70
msgid "How to compress OCI image layers (default: gzip)"
msgstr ""

#: app/flatpak-builtins-build-bundle.c:634
msgid ""
"LOCATION FILENAME NAME [BRANCH] - Create a single file bundle from a local "
"repository"
msgstr ""
"ORT DATEINAME NAME [ZWEIG] - Ein einzelnes Dateibündel aus lokaler Quelle "
"erstellen"

#: app/flatpak-builtins-build-bundle.c:641
msgid "LOCATION, FILENAME and NAME must be specified"
msgstr "ORT, DATEINAME und NAME müssen angegeben werden"

#: app/flatpak-builtins-build-bundle.c:644
#: app/flatpak-builtins-build-export.c:844
#: app/flatpak-builtins-build-import-bundle.c:136
#: app/flatpak-builtins-build-init.c:217 app/flatpak-builtins-build-sign.c:76
#: app/flatpak-builtins-document-export.c:112
#: app/flatpak-builtins-document-info.c:75
#: app/flatpak-builtins-document-list.c:191
#: app/flatpak-builtins-document-unexport.c:70
#: app/flatpak-builtins-history.c:482 app/flatpak-builtins-info.c:130
#: app/flatpak-builtins-install.c:181 app/flatpak-builtins-install.c:234
#: app/flatpak-builtins-install.c:298 app/flatpak-builtins-list.c:419
#: app/flatpak-builtins-make-current.c:72 app/flatpak-builtins-override.c:73
#: app/flatpak-builtins-permission-list.c:162
#: app/flatpak-builtins-permission-remove.c:132
#: app/flatpak-builtins-remote-add.c:323
#: app/flatpak-builtins-remote-delete.c:68
#: app/flatpak-builtins-remote-list.c:241 app/flatpak-builtins-remote-ls.c:407
msgid "Too many arguments"
msgstr "Zu viele Argumente"

#: app/flatpak-builtins-build-bundle.c:659
#: app/flatpak-builtins-build-commit-from.c:338
#: app/flatpak-builtins-build-commit-from.c:351
#: app/flatpak-builtins-build-import-bundle.c:145
#, c-format
msgid "'%s' is not a valid repository"
msgstr "»%s« ist keine gültige Quelle"

#: app/flatpak-builtins-build-bundle.c:663
#, c-format
msgid "'%s' is not a valid repository: "
msgstr "»%s« ist keine gültige Quelle: "

#: app/flatpak-builtins-build-bundle.c:674 app/flatpak-builtins-build-sign.c:88
#: common/flatpak-dir.c:14293
#, c-format
msgid "'%s' is not a valid name: %s"
msgstr "»%s« ist kein gültiger Name: %s"

#: app/flatpak-builtins-build-bundle.c:677
#: app/flatpak-builtins-build-export.c:865 app/flatpak-builtins-build-sign.c:91
#: common/flatpak-dir.c:14299
#, c-format
msgid "'%s' is not a valid branch name: %s"
msgstr "»%s« ist kein gültiger Zweig-Name: %s"

#: app/flatpak-builtins-build-bundle.c:691
#: app/flatpak-builtins-build-import-bundle.c:149
#: app/flatpak-builtins-build-init.c:281
#, c-format
msgid "'%s' is not a valid filename"
msgstr "»%s« ist kein gültiger Dateiname"

#: app/flatpak-builtins-build-bundle.c:706
msgid "--oci-layer-compress value must be gzip or zstd"
msgstr ""

#: app/flatpak-builtins-build.c:49
msgid "Use Platform runtime rather than Sdk"
msgstr "Plattform-Laufzeitumgebung eher verwenden als Sdk"

#: app/flatpak-builtins-build.c:50
msgid "Make destination readonly"
msgstr "Ziel mit nur Lesezugriff machen"

#: app/flatpak-builtins-build.c:51
msgid "Add bind mount"
msgstr "»Bind-Mount« hinzufügen"

#: app/flatpak-builtins-build.c:51
msgid "DEST=SRC"
msgstr "ZIEL=QUELLE"

#: app/flatpak-builtins-build.c:52
msgid "Start build in this directory"
msgstr "Erstellung in diesem Ordner starten"

#: app/flatpak-builtins-build.c:52 app/flatpak-builtins-build.c:53
#: app/flatpak-builtins-build-init.c:64 app/flatpak-builtins-run.c:160
msgid "DIR"
msgstr "VERZ"

#: app/flatpak-builtins-build.c:53
msgid "Where to look for custom sdk dir (defaults to 'usr')"
msgstr "Legt fest, wo der eigene sdk-Ordner gesucht wird (Standard ist »usr«)"

#: app/flatpak-builtins-build.c:54 app/flatpak-builtins-build-export.c:67
msgid "Use alternative file for the metadata"
msgstr "Alternative Datei für diese Metadaten verwenden"

#: app/flatpak-builtins-build.c:55 app/flatpak-builtins-run.c:177
msgid "Kill processes when the parent process dies"
msgstr "Prozesse abwürgen, wenn der übergeordnete Prozess beendet wird"

#: app/flatpak-builtins-build.c:56
msgid "Export application homedir directory to build"
msgstr ""

#: app/flatpak-builtins-build.c:57 app/flatpak-builtins-run.c:165
msgid "Log session bus calls"
msgstr "Sitzungsbus-Aufrufe protokollieren"

#: app/flatpak-builtins-build.c:58 app/flatpak-builtins-run.c:166
msgid "Log system bus calls"
msgstr "Systembus-Aufrufe protokollieren"

#: app/flatpak-builtins-build.c:262
msgid "DIRECTORY [COMMAND [ARGUMENT…]] - Build in directory"
msgstr "ORDNER [BEFEHL [Argumente …]] - In Ordner erstellen"

#: app/flatpak-builtins-build.c:285 app/flatpak-builtins-build-finish.c:656
msgid "DIRECTORY must be specified"
msgstr "ORDNER muss angegeben werden"

#: app/flatpak-builtins-build.c:296 app/flatpak-builtins-build-export.c:887
#, c-format
msgid "Build directory %s not initialized, use flatpak build-init"
msgstr ""
"Erstellungsordner %s ist nicht initialisiert. Verwenden Sie flatpak build-"
"init"

#: app/flatpak-builtins-build.c:315
msgid "metadata invalid, not application or runtime"
msgstr "Metadaten sind ungültig. Es ist keine Anwendung oder Laufzeit"

#: app/flatpak-builtins-build.c:446
#, c-format
msgid "No extension point matching %s in %s"
msgstr "Kein Erweiterungspunkt entspricht %s in %s"

#: app/flatpak-builtins-build.c:635
#, c-format
msgid "Missing '=' in bind mount option '%s'"
msgstr "Fehlendes »=« in Bind-Mount-Option »%s«"

#: app/flatpak-builtins-build.c:679 common/flatpak-run.c:3961
#, c-format
msgid "Unable to start app"
msgstr "Anwendung kann nicht gestartet werden"

#: app/flatpak-builtins-build-commit-from.c:58
msgid "Source repo dir"
msgstr "Quellenordner"

#: app/flatpak-builtins-build-commit-from.c:58
msgid "SRC-REPO"
msgstr "QUELL-REPO"

#: app/flatpak-builtins-build-commit-from.c:59
msgid "Source repo ref"
msgstr "Quellenreferenz"

#: app/flatpak-builtins-build-commit-from.c:59
msgid "SRC-REF"
msgstr "QUELL-REF"

#: app/flatpak-builtins-build-commit-from.c:64
#: app/flatpak-builtins-build-export.c:60
msgid "One line subject"
msgstr "Einzeiliger Betreff"

#: app/flatpak-builtins-build-commit-from.c:64
#: app/flatpak-builtins-build-export.c:60
msgid "SUBJECT"
msgstr "BETREFF"

#: app/flatpak-builtins-build-commit-from.c:65
#: app/flatpak-builtins-build-export.c:61
msgid "Full description"
msgstr "Vollständige Beschreibung"

#: app/flatpak-builtins-build-commit-from.c:65
#: app/flatpak-builtins-build-export.c:61
msgid "BODY"
msgstr "TEXTKÖRPER"

#: app/flatpak-builtins-build-commit-from.c:66
#: app/flatpak-builtins-build-export.c:64
#: app/flatpak-builtins-build-import-bundle.c:51
msgid "Update the appstream branch"
msgstr "Appstream-Zweig aktualisieren"

#: app/flatpak-builtins-build-commit-from.c:67
#: app/flatpak-builtins-build-export.c:65
#: app/flatpak-builtins-build-import-bundle.c:52
#: app/flatpak-builtins-build-update-repo.c:87
msgid "Don't update the summary"
msgstr "Die Zusammenfassung nicht aktualisieren"

#: app/flatpak-builtins-build-commit-from.c:68
#: app/flatpak-builtins-build-export.c:68
#: app/flatpak-builtins-build-import-bundle.c:49
#: app/flatpak-builtins-build-sign.c:44
msgid "GPG Key ID to sign the commit with"
msgstr "GPG-Schlüsselkennung zum Unterschreiben des Commits"

#: app/flatpak-builtins-build-commit-from.c:70
#: app/flatpak-builtins-build-export.c:73
msgid "Mark build as end-of-life"
msgstr ""

#: app/flatpak-builtins-build-commit-from.c:70
#: app/flatpak-builtins-build-export.c:73
msgid "REASON"
msgstr "GRUND"

#: app/flatpak-builtins-build-commit-from.c:71
msgid ""
"Mark refs matching the OLDID prefix as end-of-life, to be replaced with the "
"given NEWID"
msgstr ""

#: app/flatpak-builtins-build-commit-from.c:71
msgid "OLDID=NEWID"
msgstr ""

#: app/flatpak-builtins-build-commit-from.c:72
#: app/flatpak-builtins-build-export.c:75
msgid "Set type of token needed to install this commit"
msgstr ""

#: app/flatpak-builtins-build-commit-from.c:72
#: app/flatpak-builtins-build-export.c:75
msgid "VAL"
msgstr "WERT"

#: app/flatpak-builtins-build-commit-from.c:73
msgid "Override the timestamp of the commit (NOW for current time)"
msgstr ""
"Zeitstempel des Commits überschreiben (»NOW« bedeutete aktuelle Uhrzeit)"

#: app/flatpak-builtins-build-commit-from.c:73
#: app/flatpak-builtins-build-export.c:76
msgid "TIMESTAMP"
msgstr "ZEITSTEMPEL"

#: app/flatpak-builtins-build-commit-from.c:75
#: app/flatpak-builtins-build-export.c:80
#: app/flatpak-builtins-build-import-bundle.c:53
#: app/flatpak-builtins-build-update-repo.c:97
msgid "Don't generate a summary index"
msgstr "Keinen Index der Zusammenfassung erstellen"

#: app/flatpak-builtins-build-commit-from.c:278
msgid "DST-REPO [DST-REF…] - Make a new commit from existing commits"
msgstr ""
"ZIEL-REPO [ZIEL-REF]... - Einen neuen Commit auf Basis eines vorhandenen "
"Commits ausführen"

#: app/flatpak-builtins-build-commit-from.c:285
msgid "DST-REPO must be specified"
msgstr "ZIEL-REPO muss angegeben werden"

#: app/flatpak-builtins-build-commit-from.c:293
msgid ""
"If --src-repo is not specified, exactly one destination ref must be specified"
msgstr ""
"Wenn --src-repo nicht angegeben ist, so muss genau eine Zielreferenz "
"angegeben werden"

#: app/flatpak-builtins-build-commit-from.c:296
msgid ""
"If --src-ref is specified, exactly one destination ref must be specified"
msgstr ""
"Wenn --src-ref nicht angegeben ist, so muss genau eine Zielreferenz "
"angegeben werden"

#: app/flatpak-builtins-build-commit-from.c:299
msgid "Either --src-repo or --src-ref must be specified"
msgstr "Es muss entweder »--src-repo« oder »--src-ref« angegeben werden"

#: app/flatpak-builtins-build-commit-from.c:315
msgid "Invalid argument format of use  --end-of-life-rebase=OLDID=NEWID"
msgstr ""

#: app/flatpak-builtins-build-commit-from.c:321
#: app/flatpak-builtins-build-commit-from.c:324
#, c-format
msgid "Invalid name %s in --end-of-life-rebase"
msgstr ""

#: app/flatpak-builtins-build-commit-from.c:333
#: app/flatpak-builtins-build-export.c:1092
#, c-format
msgid "Could not parse '%s'"
msgstr ""

#: app/flatpak-builtins-build-commit-from.c:498
msgid "Can't commit from partial source commit"
msgstr ""

#: app/flatpak-builtins-build-commit-from.c:503
#, c-format
msgid "%s: no change\n"
msgstr "%s: keine Änderung\n"

#: app/flatpak-builtins-build-export.c:62
msgid "Architecture to export for (must be host compatible)"
msgstr "Zu exportierende Architektur (muss kompatibel mit dem Rechner sein)"

#: app/flatpak-builtins-build-export.c:63
msgid "Commit runtime (/usr), not /app"
msgstr "Commit von Laufzeitumgebung (/usr), nicht /app"

#: app/flatpak-builtins-build-export.c:66
msgid "Use alternative directory for the files"
msgstr "Alternativen Ordner für die Dateien verwenden"

#: app/flatpak-builtins-build-export.c:66
msgid "SUBDIR"
msgstr "UNTERVERZ"

#: app/flatpak-builtins-build-export.c:69
msgid "Files to exclude"
msgstr "Auszuschließende Dateien"

#: app/flatpak-builtins-build-export.c:69
#: app/flatpak-builtins-build-export.c:70
#: app/flatpak-builtins-build-update-repo.c:90
msgid "PATTERN"
msgstr "MUSTER"

#: app/flatpak-builtins-build-export.c:70
msgid "Excluded files to include"
msgstr "Einzuschließende ausgeschlossene Dateien"

#: app/flatpak-builtins-build-export.c:74
msgid "Mark build as end-of-life, to be replaced with the given ID"
msgstr ""

#: app/flatpak-builtins-build-export.c:74
#: app/flatpak-builtins-document-list.c:49 app/flatpak-cli-transaction.c:1427
msgid "ID"
msgstr "KENNUNG"

#: app/flatpak-builtins-build-export.c:76
msgid "Override the timestamp of the commit"
msgstr "Zeitstempel des Commits überschreiben"

#: app/flatpak-builtins-build-export.c:77
#: app/flatpak-builtins-build-update-repo.c:75
#: app/flatpak-builtins-remote-add.c:83 app/flatpak-builtins-remote-list.c:54
#: app/flatpak-builtins-remote-modify.c:88
msgid "Collection ID"
msgstr "Sammlungskennung"

#: app/flatpak-builtins-build-export.c:472
#, c-format
msgid "WARNING: Error running desktop-file-validate: %s\n"
msgstr ""

#: app/flatpak-builtins-build-export.c:480
#, c-format
msgid "WARNING: Error reading from desktop-file-validate: %s\n"
msgstr ""

#: app/flatpak-builtins-build-export.c:486
#, c-format
msgid "WARNING: Failed to validate desktop file %s: %s\n"
msgstr "WARNUNG: Kontrollprüfung der desktop-Datei %s ist gescheitert: %s\n"

#: app/flatpak-builtins-build-export.c:513
#, c-format
msgid "WARNING: Can't find Exec key in %s: %s\n"
msgstr "WARNUNG: Exec-Schlüssel in %s nicht gefunden: %s\n"

#: app/flatpak-builtins-build-export.c:521
#: app/flatpak-builtins-build-export.c:614
#, c-format
msgid "WARNING: Binary not found for Exec line in %s: %s\n"
msgstr "WARNUNG: Binärdatei für Exec-Zeile in %s nicht gefunden: %s\n"

#: app/flatpak-builtins-build-export.c:529
#, c-format
msgid "WARNING: Icon not matching app id in %s: %s\n"
msgstr "WARNUNG: Symbol passt nicht zur Anwendungskennung in %s: %s\n"

#: app/flatpak-builtins-build-export.c:552
#, c-format
msgid "WARNING: Icon referenced in desktop file but not exported: %s\n"
msgstr ""
"WARNING: Symbol in desktop-Datei referenziert, aber nicht exportiert: %s\n"

#: app/flatpak-builtins-build-export.c:719
#, c-format
msgid "Invalid uri type %s, only http/https supported"
msgstr "Ungültiger URI-Typ %s, nur http/https werden unterstützt"

#: app/flatpak-builtins-build-export.c:737
#, c-format
msgid "Unable to find basename in %s, specify a name explicitly"
msgstr ""
"Basisname konnte in %s nicht gefunden werden, bitte geben Sie einen Namen "
"explizit an"

#: app/flatpak-builtins-build-export.c:746
#, c-format
msgid "No slashes allowed in extra data name"
msgstr "Schrägstriche sind nicht im zusätzlichen Datennamen erlaubt"

#: app/flatpak-builtins-build-export.c:758
#, c-format
msgid "Invalid format for sha256 checksum: '%s'"
msgstr "Ungültiges Format der sha256-Prüfsumme: »%s«"

#: app/flatpak-builtins-build-export.c:768
#, c-format
msgid "Extra data sizes of zero not supported"
msgstr "Größe 0 der Extradaten wird nicht unterstützt"

#: app/flatpak-builtins-build-export.c:830
msgid ""
"LOCATION DIRECTORY [BRANCH] - Create a repository from a build directory"
msgstr "ORT ORDNER [ZWEIG] - Quelle aus Erstellungsordner erzeugen"

#: app/flatpak-builtins-build-export.c:838
msgid "LOCATION and DIRECTORY must be specified"
msgstr "ORT und ORDNER müssen angegeben werden"

#: app/flatpak-builtins-build-export.c:859
#: app/flatpak-builtins-remote-add.c:327
#, c-format
msgid "‘%s’ is not a valid collection ID: %s"
msgstr "»%s« ist keine gültige Sammlungskennung: %s"

#: app/flatpak-builtins-build-export.c:904
#: app/flatpak-builtins-build-finish.c:684
msgid "No name specified in the metadata"
msgstr "In den Metadaten ist kein Name angegeben"

#: app/flatpak-builtins-build-export.c:1166
#, c-format
msgid "Commit: %s\n"
msgstr "Commit: %s\n"

#: app/flatpak-builtins-build-export.c:1167
#, c-format
msgid "Metadata Total: %u\n"
msgstr "Metadaten insgesamt: %u\n"

#: app/flatpak-builtins-build-export.c:1168
#, c-format
msgid "Metadata Written: %u\n"
msgstr "Metadaten geschrieben: %u\n"

#: app/flatpak-builtins-build-export.c:1169
#, c-format
msgid "Content Total: %u\n"
msgstr "Inhalt insgesamt: %u\n"

#: app/flatpak-builtins-build-export.c:1170
#, c-format
msgid "Content Written: %u\n"
msgstr "Inhalt geschrieben: %u\n"

#: app/flatpak-builtins-build-export.c:1171
#, c-format
msgid "Content Bytes Written:"
msgstr ""

#: app/flatpak-builtins-build-finish.c:52
msgid "Command to set"
msgstr "Festzulegender Befehl"

#: app/flatpak-builtins-build-finish.c:52 app/flatpak-builtins-run.c:159
#: app/flatpak-main.c:209
msgid "COMMAND"
msgstr "BEFEHL"

#: app/flatpak-builtins-build-finish.c:53
msgid "Flatpak version to require"
msgstr "Benötigte Flatpak-Version"

#: app/flatpak-builtins-build-finish.c:53
msgid "MAJOR.MINOR.MICRO"
msgstr "HAUPT.NEBEN.MIKRO"

#: app/flatpak-builtins-build-finish.c:54
msgid "Don't process exports"
msgstr "Exporte nicht verarbeiten"

#: app/flatpak-builtins-build-finish.c:55
msgid "Extra data info"
msgstr "Zusätzliche Dateninformation"

#: app/flatpak-builtins-build-finish.c:56 app/flatpak-builtins-build-init.c:63
msgid "Add extension point info"
msgstr "Information zu Erweiterungspunkt hinzufügen"

#: app/flatpak-builtins-build-finish.c:56 app/flatpak-builtins-build-init.c:63
msgid "NAME=VARIABLE[=VALUE]"
msgstr "NAME=VARIABLE[=WERT]"

#: app/flatpak-builtins-build-finish.c:57
msgid "Remove extension point info"
msgstr "Information zum Erweiterungspunkt entfernen"

#: app/flatpak-builtins-build-finish.c:57
#: app/flatpak-builtins-build-update-repo.c:79 app/flatpak-builtins-info.c:58
#: app/flatpak-builtins-remote-add.c:88 app/flatpak-builtins-remote-modify.c:94
#: app/flatpak-main.c:182
msgid "NAME"
msgstr "NAME"

#: app/flatpak-builtins-build-finish.c:58
msgid "Set extension priority (only for extensions)"
msgstr "Priorität der Erweiterung festlegen (nur für Erweiterungen)"

#: app/flatpak-builtins-build-finish.c:58
msgid "VALUE"
msgstr "WERT"

#: app/flatpak-builtins-build-finish.c:59
msgid "Change the sdk used for the app"
msgstr "Das für die Anwendung verwendete Sdk ändern"

#: app/flatpak-builtins-build-finish.c:59
msgid "SDK"
msgstr "SDK"

#: app/flatpak-builtins-build-finish.c:60
msgid "Change the runtime used for the app"
msgstr "Die für die Anwendung verwendete Laufzeitumgebung ändern"

#: app/flatpak-builtins-build-finish.c:60 app/flatpak-builtins-build-init.c:54
#: app/flatpak-builtins-list.c:53 app/flatpak-builtins-remote-ls.c:58
#: app/flatpak-builtins-run.c:163
msgid "RUNTIME"
msgstr "LAUFZEITUMGEBUNG"

#: app/flatpak-builtins-build-finish.c:61
msgid "Set generic metadata option"
msgstr "Allgemeine Metadaten-Einstellungen festlegen"

#: app/flatpak-builtins-build-finish.c:61
msgid "GROUP=KEY[=VALUE]"
msgstr "GRUPPE=SCHLÜSSEL[=WERT]]"

#: app/flatpak-builtins-build-finish.c:62
msgid "Don't inherit permissions from runtime"
msgstr "Berechtigungen nicht von der Laufzeitumgebung vererben"

#: app/flatpak-builtins-build-finish.c:155
#, c-format
msgid "Not exporting %s, wrong extension\n"
msgstr "%s wird nicht exportiert, falsche Erweiterung\n"

#: app/flatpak-builtins-build-finish.c:163
#, c-format
msgid "Not exporting %s, non-allowed export filename\n"
msgstr "%s wird nicht exportiert, nicht zulässiger Export-Dateiname\n"

#: app/flatpak-builtins-build-finish.c:167
#, c-format
msgid "Exporting %s\n"
msgstr "%s wird exportiert\n"

#: app/flatpak-builtins-build-finish.c:440
#, c-format
msgid "More than one executable found\n"
msgstr "Mehr als eine ausführbare Datei gefunden\n"

#: app/flatpak-builtins-build-finish.c:451
#, c-format
msgid "Using %s as command\n"
msgstr "%s als Befehl verwenden\n"

#: app/flatpak-builtins-build-finish.c:456
#, c-format
msgid "No executable found\n"
msgstr "Keine ausführbare Datei gefunden\n"

#: app/flatpak-builtins-build-finish.c:511
#, c-format
msgid "Invalid --require-version argument: %s"
msgstr "Ungültiges Argument --require-version: %s"

#: app/flatpak-builtins-build-finish.c:543
#, c-format
msgid "Too few elements in --extra-data argument %s"
msgstr "Zu wenige Elemente im Argument %s von --extra-data"

#: app/flatpak-builtins-build-finish.c:575
#, c-format
msgid ""
"Too few elements in --metadata argument %s, format should be "
"GROUP=KEY[=VALUE]]"
msgstr ""
"Zu wenige Elemente im Argument %s von --metadata. Das Format ist "
"GRUPPE=SCHLÜSSEL[=WERT]]"

#: app/flatpak-builtins-build-finish.c:597
#: app/flatpak-builtins-build-init.c:458
#, c-format
msgid ""
"Too few elements in --extension argument %s, format should be "
"NAME=VAR[=VALUE]"
msgstr ""
"Zu wenige Elemente für den Parameter %s von --extension. Das Format ist "
"NAME=VAR[=WERT]"

#: app/flatpak-builtins-build-finish.c:603
#: app/flatpak-builtins-build-init.c:461
#, c-format
msgid "Invalid extension name %s"
msgstr "Ungültiger Erweiterungsname %s"

#: app/flatpak-builtins-build-finish.c:646
msgid "DIRECTORY - Finalize a build directory"
msgstr "ORDNER - einen Erstellungsordner abschließen"

#: app/flatpak-builtins-build-finish.c:668
#, c-format
msgid "Build directory %s not initialized"
msgstr "Erstellungsordner %s ist nicht initialisiert"

#: app/flatpak-builtins-build-finish.c:689
#, c-format
msgid "Build directory %s already finalized"
msgstr "Erstellungsordner %s wurde bereits finalisiert"

#: app/flatpak-builtins-build-finish.c:702
#, c-format
msgid "Please review the exported files and the metadata\n"
msgstr "Bitte überprüfen Sie die exportierten Dateien und die Metadaten\n"

#: app/flatpak-builtins-build-import-bundle.c:47
msgid "Override the ref used for the imported bundle"
msgstr "Referenz für das importierte Bündel ersetzen"

#: app/flatpak-builtins-build-import-bundle.c:47
msgid "REF"
msgstr "REF"

#: app/flatpak-builtins-build-import-bundle.c:48
msgid "Import oci image instead of flatpak bundle"
msgstr "OCI-Abbild anstelle eines Flatpak-Bündels importieren"

#: app/flatpak-builtins-build-import-bundle.c:77
#: app/flatpak-builtins-build-import-bundle.c:105
#, c-format
msgid "Importing %s (%s)\n"
msgstr "»%s« (%s) wird importiert\n"

#: app/flatpak-builtins-build-import-bundle.c:126
msgid "LOCATION FILENAME - Import a file bundle into a local repository"
msgstr "ORT DATEINAME - Ein Dateibündel in eine lokale Quelle importieren"

#: app/flatpak-builtins-build-import-bundle.c:133
msgid "LOCATION and FILENAME must be specified"
msgstr "ORT und DATEINAME müssen angegeben werden"

#: app/flatpak-builtins-build-init.c:53 app/flatpak-builtins-info.c:55
#: app/flatpak-builtins-run.c:158
msgid "Arch to use"
msgstr "Zu verwendende Architektur"

#: app/flatpak-builtins-build-init.c:54
msgid "Initialize var from named runtime"
msgstr "Variable anhand der benannten Laufzeitumgebung initialisieren"

#: app/flatpak-builtins-build-init.c:55
msgid "Initialize apps from named app"
msgstr "Anwendungen anhand der benannten Anwendung initialisieren "

#: app/flatpak-builtins-build-init.c:55
msgid "APP"
msgstr "APP"

#: app/flatpak-builtins-build-init.c:56
msgid "Specify version for --base"
msgstr "Version für --base angeben"

#: app/flatpak-builtins-build-init.c:56 app/flatpak-builtins-run.c:164
msgid "VERSION"
msgstr "VERSION"

#: app/flatpak-builtins-build-init.c:57
msgid "Include this base extension"
msgstr "Diese Basiserweiterung einschließen"

#: app/flatpak-builtins-build-init.c:57 app/flatpak-builtins-build-init.c:62
msgid "EXTENSION"
msgstr "ERWEITERUNG"

#: app/flatpak-builtins-build-init.c:58
msgid "Extension tag to use if building extension"
msgstr ""

#: app/flatpak-builtins-build-init.c:58
msgid "EXTENSION_TAG"
msgstr "ERWEITERUNG_SCHLAGWORT"

#: app/flatpak-builtins-build-init.c:59
msgid "Initialize /usr with a writable copy of the sdk"
msgstr "/usr mit einer schreibbaren Kopie der sdk initialisieren"

#: app/flatpak-builtins-build-init.c:60
msgid "Specify the build type (app, runtime, extension)"
msgstr "Geben Sie den Erstellungstyp an (App, Laufzeit, Erweiterung)"

#: app/flatpak-builtins-build-init.c:60
msgid "TYPE"
msgstr "TYP"

#: app/flatpak-builtins-build-init.c:61
msgid "Add a tag"
msgstr "Schlagwort hinzufügen"

#: app/flatpak-builtins-build-init.c:61
msgid "TAG"
msgstr "SCHLAGWORT"

#: app/flatpak-builtins-build-init.c:62
msgid "Include this sdk extension in /usr"
msgstr "Diese sdk-Erweiterung in /usr einschließen"

#: app/flatpak-builtins-build-init.c:64
msgid "Where to store sdk (defaults to 'usr')"
msgstr "Legt fest, wo sdk gespeichert wird (Standard ist »usr«)"

#: app/flatpak-builtins-build-init.c:65
msgid "Re-initialize the sdk/var"
msgstr "sdk/var reinitialisieren"

#: app/flatpak-builtins-build-init.c:118
#, fuzzy, c-format
msgid "Requested extension %s/%s/%s is only partially installed"
msgstr "Angeforderte Erweiterung »%s« ist nur teilweise installiert"

#: app/flatpak-builtins-build-init.c:147
#, fuzzy, c-format
msgid "Requested extension %s/%s/%s not installed"
msgstr "Angeforderte Erweiterung »%s« ist nicht installiert"

#: app/flatpak-builtins-build-init.c:207
msgid ""
"DIRECTORY APPNAME SDK RUNTIME [BRANCH] - Initialize a directory for building"
msgstr ""
"ORDNER ANWENDUNGSNAME SDK LAUFZEITUMGEBUNG [ZWEIG] - Einen Erstellungsordner "
"initialisieren"

#: app/flatpak-builtins-build-init.c:214
msgid "RUNTIME must be specified"
msgstr "LAUFZEITUMGEBUNG muss angegeben werden"

#: app/flatpak-builtins-build-init.c:235
#, c-format
msgid "'%s' is not a valid build type name, use app, runtime or extension"
msgstr ""

#: app/flatpak-builtins-build-init.c:241 app/flatpak-builtins-override.c:79
#, c-format
msgid "'%s' is not a valid application name: %s"
msgstr "»%s« ist kein gültiger Anwendungsname: %s"

#: app/flatpak-builtins-build-init.c:295
#, c-format
msgid "Build directory %s already initialized"
msgstr "Erstellungsordner %s ist bereits initialisiert"

#: app/flatpak-builtins-build-sign.c:42 app/flatpak-builtins-install.c:67
#: app/flatpak-builtins-remote-info.c:54
msgid "Arch to install for"
msgstr "Architektur, für die installiert wird"

#: app/flatpak-builtins-build-sign.c:43 app/flatpak-builtins-create-usb.c:48
#: app/flatpak-builtins-install.c:74 app/flatpak-builtins-remote-info.c:56
#: app/flatpak-builtins-uninstall.c:58 app/flatpak-builtins-update.c:64
msgid "Look for runtime with the specified name"
msgstr "Nach Laufzeitumgebung unter dem angegebenen Namen suchen"

#: app/flatpak-builtins-build-sign.c:66
msgid "LOCATION [ID [BRANCH]] - Sign an application or runtime"
msgstr "QUELLE [NAME [ZWEIG]] - Eine Anwendung oder Laufzeitumgebung signieren"

#: app/flatpak-builtins-build-sign.c:73
#: app/flatpak-builtins-build-update-repo.c:499
#: app/flatpak-builtins-remote-add.c:320 app/flatpak-builtins-repo.c:739
msgid "LOCATION must be specified"
msgstr "ORT muss angegeben werden"

#: app/flatpak-builtins-build-sign.c:94
msgid "No gpg key ids specified"
msgstr "Keine gpg-Schlüsselkennungen angegeben"

#: app/flatpak-builtins-build-update-repo.c:68
msgid "Redirect this repo to a new URL"
msgstr "Diese Quelle zu einer neuen Adresse umleiten"

#: app/flatpak-builtins-build-update-repo.c:69
msgid "A nice name to use for this repository"
msgstr "Ein passender Name für diese Quelle"

#: app/flatpak-builtins-build-update-repo.c:69
#: app/flatpak-builtins-remote-add.c:77 app/flatpak-builtins-remote-modify.c:82
msgid "TITLE"
msgstr "TITEL"

#: app/flatpak-builtins-build-update-repo.c:70
msgid "A one-line comment for this repository"
msgstr "Eine einzeilige Beschreibung für dieses Depot"

#: app/flatpak-builtins-build-update-repo.c:70
#: app/flatpak-builtins-remote-add.c:78 app/flatpak-builtins-remote-modify.c:83
msgid "COMMENT"
msgstr "KOMMENTAR"

#: app/flatpak-builtins-build-update-repo.c:71
msgid "A full-paragraph description for this repository"
msgstr "Ein vollständiger Absatz als Beschreibung für diese Quelle"

#: app/flatpak-builtins-build-update-repo.c:71
#: app/flatpak-builtins-remote-add.c:79 app/flatpak-builtins-remote-modify.c:84
msgid "DESCRIPTION"
msgstr "BESCHREIBUNG"

#: app/flatpak-builtins-build-update-repo.c:72
msgid "URL for a website for this repository"
msgstr "Eine Adresse für die Internetseite für diese Quelle"

#: app/flatpak-builtins-build-update-repo.c:73
msgid "URL for an icon for this repository"
msgstr "Eine Adresse für ein Symbol für diese Quelle"

#: app/flatpak-builtins-build-update-repo.c:74
msgid "Default branch to use for this repository"
msgstr "Vorgabezweig für diese Quelle"

#: app/flatpak-builtins-build-update-repo.c:74
#: app/flatpak-builtins-remote-add.c:82 app/flatpak-builtins-remote-modify.c:87
#: app/flatpak-builtins-repo.c:713 app/flatpak-builtins-repo.c:714
#: app/flatpak-builtins-run.c:161
msgid "BRANCH"
msgstr "ZWEIG"

#: app/flatpak-builtins-build-update-repo.c:75
#: app/flatpak-builtins-remote-add.c:83 app/flatpak-builtins-remote-modify.c:88
msgid "COLLECTION-ID"
msgstr "SAMMLUNGSKENNUNG"

#. Translators: A sideload is when you install from a local USB drive rather than the Internet.
#: app/flatpak-builtins-build-update-repo.c:77
msgid ""
"Permanently deploy collection ID to client remote configurations, only for "
"sideload support"
msgstr ""

#: app/flatpak-builtins-build-update-repo.c:78
msgid "Permanently deploy collection ID to client remote configurations"
msgstr ""

#: app/flatpak-builtins-build-update-repo.c:79
msgid "Name of authenticator for this repository"
msgstr "Name des Authentifikators für dieses Quelle"

#: app/flatpak-builtins-build-update-repo.c:80
msgid "Autoinstall authenticator for this repository"
msgstr "Authentifikator für diese Quelle automatisch installieren"

#: app/flatpak-builtins-build-update-repo.c:81
msgid "Don't autoinstall authenticator for this repository"
msgstr "Authentifikator für diese Quelle nicht automatisch installieren"

#: app/flatpak-builtins-build-update-repo.c:82
#: app/flatpak-builtins-remote-add.c:89
msgid "Authenticator option"
msgstr "Authentifikator-Option"

#: app/flatpak-builtins-build-update-repo.c:82
#: app/flatpak-builtins-remote-add.c:89 app/flatpak-builtins-remote-modify.c:95
msgid "KEY=VALUE"
msgstr "SCHLÜSSEL=WERT"

#: app/flatpak-builtins-build-update-repo.c:83
msgid "Import new default GPG public key from FILE"
msgstr "Neuen öffentlichen GPG-Vorgabeschlüssel aus DATEI importieren"

#: app/flatpak-builtins-build-update-repo.c:84
msgid "GPG Key ID to sign the summary with"
msgstr "GPG-Schlüsselkennung zum Unterschreiben der Zusammenfassung"

#: app/flatpak-builtins-build-update-repo.c:86
msgid "Generate delta files"
msgstr "Differenzdateien erzeugen"

#: app/flatpak-builtins-build-update-repo.c:88
msgid "Don't update the appstream branch"
msgstr "Appstream-Zweig nicht aktualisieren"

#: app/flatpak-builtins-build-update-repo.c:89
msgid "Max parallel jobs when creating deltas (default: NUMCPUs)"
msgstr ""

#: app/flatpak-builtins-build-update-repo.c:89
msgid "NUM-JOBS"
msgstr ""

#: app/flatpak-builtins-build-update-repo.c:90
msgid "Don't create deltas matching refs"
msgstr "Keine Deltas erstellen, die mit Referenzen übereinstimmen"

#: app/flatpak-builtins-build-update-repo.c:91
msgid "Prune unused objects"
msgstr "Ungenutzte Objekte abschneiden"

#: app/flatpak-builtins-build-update-repo.c:92
msgid "Prune but don't actually remove anything"
msgstr "Abschneiden, aber nicht wirklich etwas entfernen"

#: app/flatpak-builtins-build-update-repo.c:93
msgid "Only traverse DEPTH parents for each commit (default: -1=infinite)"
msgstr ""
"Nur übergeordnete Ebenen der angegebenen TIEFE für jeden Commit durchqueren "
"(Standard: -1=unendlich)"

#: app/flatpak-builtins-build-update-repo.c:93
msgid "DEPTH"
msgstr "TIEFE"

#: app/flatpak-builtins-build-update-repo.c:223
#, c-format
msgid "Generating delta: %s (%.10s)\n"
msgstr "Delta wird erstellt: %s (%.10s)\n"

#: app/flatpak-builtins-build-update-repo.c:225
#, c-format
msgid "Generating delta: %s (%.10s-%.10s)\n"
msgstr "Delta wird erstellt: %s (%.10s-%.10s)\n"

#: app/flatpak-builtins-build-update-repo.c:233
#, c-format
msgid "Failed to generate delta %s (%.10s): "
msgstr "Erstellung des Delta %s (%.10s) fehlgeschlagen: "

#: app/flatpak-builtins-build-update-repo.c:236
#, c-format
msgid "Failed to generate delta %s (%.10s-%.10s): "
msgstr "Erstellung des Delta %s (%.10s-%.10s) fehlgeschlagen: "

#: app/flatpak-builtins-build-update-repo.c:492
msgid "LOCATION - Update repository metadata"
msgstr "ORT - Metadaten der Quelle aktualisieren"

#: app/flatpak-builtins-build-update-repo.c:609
#, c-format
msgid "Updating appstream branch\n"
msgstr "Appstream-Zweig wird aktualisiert\n"

#: app/flatpak-builtins-build-update-repo.c:638
#, c-format
msgid "Updating summary\n"
msgstr "Zusammenfassung wird aktualisiert\n"

#: app/flatpak-builtins-build-update-repo.c:664
#, c-format
msgid "Total objects: %u\n"
msgstr "Objekte gesamt: %u\n"

#: app/flatpak-builtins-build-update-repo.c:666
#, c-format
msgid "No unreachable objects\n"
msgstr "Keine unerreichbaren Objekte\n"

#: app/flatpak-builtins-build-update-repo.c:668
#, c-format
msgid "Deleted %u objects, %s freed\n"
msgstr "%u Objekte gelöscht, %s freigemacht\n"

#: app/flatpak-builtins-config.c:41
msgid "List configuration keys and values"
msgstr "Konfigurationsschlüssel und Werte auflisten"

#: app/flatpak-builtins-config.c:42
msgid "Get configuration for KEY"
msgstr "Konfiguration für SCHLÜSSEL holen"

#: app/flatpak-builtins-config.c:43
msgid "Set configuration for KEY to VALUE"
msgstr "Konfiguration für SCHLÜSSEL auf WERT setzen"

#: app/flatpak-builtins-config.c:44
msgid "Unset configuration for KEY"
msgstr "Konfiguration für SCHLÜSSEL zurücksetzen"

#: app/flatpak-builtins-config.c:149
#, c-format
msgid "'%s' does not look like a language/locale code"
msgstr "'%s' sieht nicht aus wie ein Sprach- /Regionscode"

#: app/flatpak-builtins-config.c:172
#, c-format
msgid "'%s' does not look like a language code"
msgstr "'%s' sieht nicht aus wie ein Sprachcode"

#: app/flatpak-builtins-config.c:190
#, fuzzy, c-format
msgid "'%s' is not a valid value (use 'true' or 'false')"
msgstr "»%s« ist keine gültige Quelle: "

#: app/flatpak-builtins-config.c:262
#, c-format
msgid "Unknown configure key '%s'"
msgstr "Unbekannter Konfigurationsschlüssel »%s«"

#: app/flatpak-builtins-config.c:284
msgid "Too many arguments for --list"
msgstr "Zu viele Argumente für »--list«"

#: app/flatpak-builtins-config.c:314 app/flatpak-builtins-config.c:362
msgid "You must specify KEY"
msgstr "SCHLÜSSEL muss angegeben werden"

#: app/flatpak-builtins-config.c:316
msgid "Too many arguments for --get"
msgstr "Zu viele Argumente für »--get«"

#: app/flatpak-builtins-config.c:338
msgid "You must specify KEY and VALUE"
msgstr "Sie müssen SCHLÜSSEL und WERT angeben"

#: app/flatpak-builtins-config.c:340
msgid "Too many arguments for --set"
msgstr "Zu viele Argumente für »--set«"

#: app/flatpak-builtins-config.c:364
msgid "Too many arguments for --unset"
msgstr "Zu viele Argumente für »--unset«"

#: app/flatpak-builtins-config.c:383
msgid "[KEY [VALUE]] - Manage configuration"
msgstr "[SCHLÜSSEL [WERT]] - Konfiguration verwalten"

#: app/flatpak-builtins-config.c:394
msgid "Can only use one of --list, --get, --set or --unset"
msgstr ""
"Sie können nur eines von »--list«, »--get«, »--set« oder »--unset« verwenden"

#: app/flatpak-builtins-config.c:408
msgid "Must specify one of --list, --get, --set or --unset"
msgstr "Sie müssen eines von »--list«, »--get«, »--set« oder »--unset« angeben"

#: app/flatpak-builtins-create-usb.c:45 app/flatpak-builtins-install.c:75
#: app/flatpak-builtins-remote-info.c:57 app/flatpak-builtins-uninstall.c:59
#: app/flatpak-builtins-update.c:65
msgid "Look for app with the specified name"
msgstr "Nach einer Anwendung mit dem angegebenen Namen suchen"

#: app/flatpak-builtins-create-usb.c:46
#, fuzzy
msgid "Arch to copy"
msgstr "Anzuzeigende Architektur"

#: app/flatpak-builtins-create-usb.c:47
msgid "DEST"
msgstr "ZIEL"

#: app/flatpak-builtins-create-usb.c:49
msgid "Allow partial commits in the created repo"
msgstr ""

#: app/flatpak-builtins-create-usb.c:125 app/flatpak-builtins-create-usb.c:165
#, c-format
msgid ""
"Warning: Related ref ‘%s’ is partially installed. Use --allow-partial to "
"suppress this message.\n"
msgstr ""

#: app/flatpak-builtins-create-usb.c:158
#, c-format
msgid "Warning: Omitting related ref ‘%s’ because it is not installed.\n"
msgstr ""

#: app/flatpak-builtins-create-usb.c:175
#, c-format
msgid ""
"Warning: Omitting related ref ‘%s’ because its remote ‘%s’ does not have a "
"collection ID set.\n"
msgstr ""

#: app/flatpak-builtins-create-usb.c:187
#, c-format
msgid "Warning: Omitting related ref ‘%s’ because it's extra-data.\n"
msgstr ""

#: app/flatpak-builtins-create-usb.c:262 app/flatpak-builtins-create-usb.c:637
#, c-format
msgid ""
"Remote ‘%s’ does not have a collection ID set, which is required for P2P "
"distribution of ‘%s’."
msgstr ""

#: app/flatpak-builtins-create-usb.c:272
#, c-format
msgid "Warning: Omitting ref ‘%s’ (runtime of ‘%s’) because it's extra-data.\n"
msgstr ""

#: app/flatpak-builtins-create-usb.c:484
msgid "MOUNT-PATH [REF…] - Copy apps or runtimes onto removable media"
msgstr ""

#: app/flatpak-builtins-create-usb.c:493
msgid "MOUNT-PATH and REF must be specified"
msgstr "EINHÄNGEPFAD und REF muss angegeben werden"

#: app/flatpak-builtins-create-usb.c:607
#, c-format
msgid "Ref ‘%s’ found in multiple installations: %s. You must specify one."
msgstr ""

#: app/flatpak-builtins-create-usb.c:620
#, c-format
msgid "Refs must all be in the same installation (found in %s and %s)."
msgstr ""

#: app/flatpak-builtins-create-usb.c:670
#, c-format
msgid ""
"Warning: Ref ‘%s’ is partially installed. Use --allow-partial to suppress "
"this message.\n"
msgstr ""

#: app/flatpak-builtins-create-usb.c:681
#, c-format
msgid "Installed ref ‘%s’ is extra-data, and cannot be distributed offline"
msgstr ""

#: app/flatpak-builtins-create-usb.c:721
#, c-format
msgid "Warning: Couldn't update repo metadata for remote ‘%s’: %s\n"
msgstr ""
"Warnung: Quellen-Metadaten für Gegenstelle »%s« konnten nicht aktualisiert "
"werden: %s\n"

#: app/flatpak-builtins-create-usb.c:751
#, c-format
msgid "Warning: Couldn't update appstream data for remote ‘%s’ arch ‘%s’: %s\n"
msgstr ""

#. Print a warning if both appstream and appstream2 are missing
#: app/flatpak-builtins-create-usb.c:784
#, c-format
msgid ""
"Warning: Couldn't find appstream data for remote ‘%s’ arch ‘%s’: %s; %s\n"
msgstr ""

#. Appstream2 is only for efficiency, so just print a debug message
#: app/flatpak-builtins-create-usb.c:790
#, c-format
msgid "Couldn't find appstream2 data for remote ‘%s’ arch ‘%s’: %s\n"
msgstr ""

#: app/flatpak-builtins-document-export.c:62
msgid "Create a unique document reference"
msgstr "Eine eindeutige Dokumentenreferenz erstellen"

#: app/flatpak-builtins-document-export.c:63
msgid "Make the document transient for the current session"
msgstr "Das Dokument transient für die aktuelle Sitzung machen"

#: app/flatpak-builtins-document-export.c:64
msgid "Don't require the file to exist already"
msgstr "Es ist nicht erforderlich, dass die Datei bereits vorhanden ist"

#: app/flatpak-builtins-document-export.c:65
msgid "Give the app read permissions"
msgstr "Der Anwendung Lese-Berechtigungen erteilen"

#: app/flatpak-builtins-document-export.c:66
msgid "Give the app write permissions"
msgstr "Der Anwendung Schreib-Berechtigungen erteilen"

#: app/flatpak-builtins-document-export.c:67
msgid "Give the app delete permissions"
msgstr "Der Anwendung Lösch-Berechtigungen erteilen"

#: app/flatpak-builtins-document-export.c:68
msgid "Give the app permissions to grant further permissions"
msgstr ""
"Der Anwendung Berechtigungen erteilen, weitere Berechtigungen zu gewähren"

#: app/flatpak-builtins-document-export.c:69
msgid "Revoke read permissions of the app"
msgstr "Lese-Berechtigungen der Anwendung widerrufen"

#: app/flatpak-builtins-document-export.c:70
msgid "Revoke write permissions of the app"
msgstr "Schreib-Berechtigungen der Anwendung widerrufen"

#: app/flatpak-builtins-document-export.c:71
msgid "Revoke delete permissions of the app"
msgstr "Lösch-Berechtigungen der Anwendung widerrufen"

#: app/flatpak-builtins-document-export.c:72
msgid "Revoke the permission to grant further permissions"
msgstr "Berechtigungen widerrufen, weitere Berechtigungen zu gewähren"

#: app/flatpak-builtins-document-export.c:73
msgid "Add permissions for this app"
msgstr "Dieser Anwendung Berechtigungen erteilen"

#: app/flatpak-builtins-document-export.c:73
msgid "APPID"
msgstr "ANWENDUNGSKENNUNG"

#: app/flatpak-builtins-document-export.c:100
msgid "FILE - Export a file to apps"
msgstr "DATEI - Eine Datei an Anwendungen exportieren"

#: app/flatpak-builtins-document-export.c:109
#: app/flatpak-builtins-document-info.c:72
#: app/flatpak-builtins-document-unexport.c:67
msgid "FILE must be specified"
msgstr "DATEI muss angegeben werden"

#: app/flatpak-builtins-document-info.c:63
msgid "FILE - Get information about an exported file"
msgstr "DATEI - Informationen über die exportierte Datei erhalten"

#: app/flatpak-builtins-document-info.c:100
#: app/flatpak-builtins-document-unexport.c:94
#, c-format
msgid "Not exported\n"
msgstr "Nicht exportiert\n"

#: app/flatpak-builtins-document-list.c:43 app/flatpak-builtins-history.c:53
#: app/flatpak-builtins-list.c:54 app/flatpak-builtins-ps.c:43
#: app/flatpak-builtins-remote-list.c:45 app/flatpak-builtins-remote-ls.c:59
#: app/flatpak-builtins-search.c:38
msgid "What information to show"
msgstr "Welche Informationen angezeigt werden sollen"

#: app/flatpak-builtins-document-list.c:43 app/flatpak-builtins-history.c:53
#: app/flatpak-builtins-list.c:54 app/flatpak-builtins-ps.c:43
#: app/flatpak-builtins-remote-list.c:45 app/flatpak-builtins-remote-ls.c:59
#: app/flatpak-builtins-search.c:38
msgid "FIELD,…"
msgstr "FELD,…"

#: app/flatpak-builtins-document-list.c:44 app/flatpak-builtins-history.c:54
#: app/flatpak-builtins-list.c:52 app/flatpak-builtins-permission-list.c:43
#: app/flatpak-builtins-permission-show.c:43 app/flatpak-builtins-ps.c:44
#: app/flatpak-builtins-remote-list.c:46 app/flatpak-builtins-remote-ls.c:63
#: app/flatpak-builtins-repo.c:717 app/flatpak-builtins-search.c:39
#, fuzzy
msgid "Show output in JSON format"
msgstr "Zusätzliche Informationen anzeigen"

#: app/flatpak-builtins-document-list.c:49
msgid "Show the document ID"
msgstr "Die Dokumentkennung anzeigen"

#: app/flatpak-builtins-document-list.c:50
msgid "Path"
msgstr "Pfad"

#: app/flatpak-builtins-document-list.c:50
#: app/flatpak-builtins-document-list.c:51
msgid "Show the document path"
msgstr "Den Dokumentpfad anzeigen"

#: app/flatpak-builtins-document-list.c:51 app/flatpak-builtins-list.c:66
#: app/flatpak-builtins-remote-ls.c:74
msgid "Origin"
msgstr "Ursprung"

#: app/flatpak-builtins-document-list.c:52 app/flatpak-builtins-history.c:62
#: app/flatpak-builtins-ps.c:52
msgid "Application"
msgstr "Anwendung"

#: app/flatpak-builtins-document-list.c:52
msgid "Show applications with permission"
msgstr "Anwendungen mit Berechtigung anzeigen"

#: app/flatpak-builtins-document-list.c:53
#: app/flatpak-builtins-permission-list.c:182
#: app/flatpak-builtins-permission-show.c:145
msgid "Permissions"
msgstr "Berechtigungen"

#: app/flatpak-builtins-document-list.c:53
msgid "Show permissions for applications"
msgstr "Berechtigungen für Anwendungen anzeigen"

#: app/flatpak-builtins-document-list.c:161
#, fuzzy, c-format
msgid "No documents found\n"
msgstr "Keine Übereinstimmung gefunden"

#: app/flatpak-builtins-document-list.c:180
msgid "[APPID] - List exported files"
msgstr "[ANWENDUNGSKENNUNG] - Exportierte Dateien auflisten"

#: app/flatpak-builtins-document-unexport.c:43
msgid "Specify the document ID"
msgstr "Dokumentkennung angeben"

#: app/flatpak-builtins-document-unexport.c:58
msgid "FILE - Unexport a file to apps"
msgstr "DATEI - Export einer Datei an Anwendungen rückgängig machen"

#: app/flatpak-builtins-enter.c:88
msgid "INSTANCE COMMAND [ARGUMENT…] - Run a command inside a running sandbox"
msgstr ""
"INSTANZ BEFEHL [Argumente …] - Einen Befehl in einer laufenden Sandbox "
"ausführen"

#: app/flatpak-builtins-enter.c:111
msgid "INSTANCE and COMMAND must be specified"
msgstr "INSTANZ und BEFEHL müssen angegeben werden"

#: app/flatpak-builtins-enter.c:138
#, c-format
msgid "%s is neither a pid nor an application or instance ID"
msgstr ""
"»%s« ist weder eine Prozesskennung noch eine Anwendung oder eine "
"Instanzkennung"

#: app/flatpak-builtins-enter.c:144
msgid "entering not supported (need unprivileged user namespaces, or sudo -E)"
msgstr ""

#: app/flatpak-builtins-enter.c:145
#, c-format
msgid "No such pid %s"
msgstr "Prozesskennung %s nicht vorhanden"

#: app/flatpak-builtins-enter.c:158
msgid "Can't read cwd"
msgstr "cwd kann nicht gelesen werden"

#: app/flatpak-builtins-enter.c:163
msgid "Can't read root"
msgstr "root kann nicht gelesen werden"

#: app/flatpak-builtins-enter.c:191
#, c-format
msgid "Invalid %s namespace for pid %d"
msgstr "Ungültiger %s-Namensraum für Prozesskennung %d"

#: app/flatpak-builtins-enter.c:202
#, c-format
msgid "Invalid %s namespace for self"
msgstr "Ungültiger %s-Namensraum für sich selbst"

#: app/flatpak-builtins-enter.c:216
#, c-format
msgid "Can't open %s namespace: %s"
msgstr "Namensraum %s konnte nicht geöffnet werden: %s"

#: app/flatpak-builtins-enter.c:226
msgid "entering not supported (need unprivileged user namespaces)"
msgstr ""

#: app/flatpak-builtins-enter.c:227
#, c-format
msgid "Can't enter %s namespace: %s"
msgstr "In den Namensraum %s konnte nicht gewechselt werden: %s"

#: app/flatpak-builtins-enter.c:234
msgid "Can't chdir"
msgstr "chdir nicht möglich"

#: app/flatpak-builtins-enter.c:237
msgid "Can't chroot"
msgstr "chroot nicht möglich"

#: app/flatpak-builtins-enter.c:240
msgid "Can't switch gid"
msgstr "Gruppenkennung kann nicht gewechselt werden"

#: app/flatpak-builtins-enter.c:243
msgid "Can't switch uid"
msgstr "Benutzerkennung kann nicht gewechselt werden"

#: app/flatpak-builtins-history.c:50
msgid "Only show changes after TIME"
msgstr "Nur Änderungen nach ZEIT anzeigen"

#: app/flatpak-builtins-history.c:50 app/flatpak-builtins-history.c:51
msgid "TIME"
msgstr "ZEIT"

#: app/flatpak-builtins-history.c:51
msgid "Only show changes before TIME"
msgstr "Nur Änderungen vor ZEIT anzeigen"

#: app/flatpak-builtins-history.c:52
msgid "Show newest entries first"
msgstr "Jjüngste Einträge zuerst anzeigen"

#: app/flatpak-builtins-history.c:59
msgid "Time"
msgstr "Zeit"

#: app/flatpak-builtins-history.c:59
msgid "Show when the change happened"
msgstr "Anzeigen, wann die Änderung stattgefunden hat"

#: app/flatpak-builtins-history.c:60
msgid "Change"
msgstr "Ändern"

#: app/flatpak-builtins-history.c:60
msgid "Show the kind of change"
msgstr "Art der Änderung anzeigen"

#: app/flatpak-builtins-history.c:61 app/flatpak-builtins-list.c:68
#: app/flatpak-builtins-remote-ls.c:75 app/flatpak-builtins-repo.c:335
msgid "Ref"
msgstr "Referenz"

#: app/flatpak-builtins-history.c:61 app/flatpak-builtins-list.c:68
#: app/flatpak-builtins-remote-ls.c:75
#, fuzzy
msgid "Show the ref"
msgstr "Referenz anzeigen"

#: app/flatpak-builtins-history.c:62
msgid "Show the application/runtime ID"
msgstr "Anwendung-/Laufzeitkennung anzeigen"

#: app/flatpak-builtins-history.c:63 app/flatpak-builtins-list.c:64
#: app/flatpak-builtins-ps.c:53 app/flatpak-builtins-remote-ls.c:73
#: app/flatpak-cli-transaction.c:1435
msgid "Arch"
msgstr "Architektur"

#: app/flatpak-builtins-history.c:63 app/flatpak-builtins-list.c:64
#: app/flatpak-builtins-ps.c:53 app/flatpak-builtins-remote-ls.c:73
msgid "Show the architecture"
msgstr "Architektur anzeigen"

#: app/flatpak-builtins-history.c:64 app/flatpak-builtins-list.c:63
#: app/flatpak-builtins-ps.c:54 app/flatpak-builtins-remote-ls.c:72
#: app/flatpak-builtins-search.c:48 app/flatpak-cli-transaction.c:1438
msgid "Branch"
msgstr "Zweig"

#: app/flatpak-builtins-history.c:64 app/flatpak-builtins-list.c:63
#: app/flatpak-builtins-remote-ls.c:72
msgid "Show the branch"
msgstr "Zweig anzeigen"

#: app/flatpak-builtins-history.c:65 app/flatpak-builtins-list.c:67
msgid "Installation"
msgstr "Installation"

#: app/flatpak-builtins-history.c:65
msgid "Show the affected installation"
msgstr "Betroffene Installationen anzeigen"

#: app/flatpak-builtins-history.c:66 app/flatpak-cli-transaction.c:1452
msgid "Remote"
msgstr "Gegenstelle"

#: app/flatpak-builtins-history.c:66
msgid "Show the remote"
msgstr "Gegenstelle anzeigen"

#: app/flatpak-builtins-history.c:67 app/flatpak-builtins-ps.c:55
#: app/flatpak-builtins-remote-ls.c:76
msgid "Commit"
msgstr "Commit"

#: app/flatpak-builtins-history.c:67
msgid "Show the current commit"
msgstr "Aktuellen Commit anzeigen"

#: app/flatpak-builtins-history.c:68
msgid "Old Commit"
msgstr "Alter Commit"

#: app/flatpak-builtins-history.c:68
msgid "Show the previous commit"
msgstr "Vorherigen Commit anzeigen"

#: app/flatpak-builtins-history.c:69
msgid "Show the remote URL"
msgstr "URL der Gegenstelle anzeigen"

#: app/flatpak-builtins-history.c:70 app/flatpak-cli-transaction.c:700
msgid "User"
msgstr "Benutzer"

#: app/flatpak-builtins-history.c:70
msgid "Show the user doing the change"
msgstr "Benutzer anzeigen, der die Änderung vornimmt"

#: app/flatpak-builtins-history.c:71
msgid "Tool"
msgstr "Werkzeug"

#: app/flatpak-builtins-history.c:71
msgid "Show the tool that was used"
msgstr "Verwendetes Werkzeug anzeigen"

#: app/flatpak-builtins-history.c:72 app/flatpak-builtins-list.c:62
#: app/flatpak-builtins-remote-ls.c:71 app/flatpak-builtins-search.c:47
msgid "Version"
msgstr "Version"

#: app/flatpak-builtins-history.c:72
msgid "Show the Flatpak version"
msgstr "Flatpak-Version anzeigen"

#: app/flatpak-builtins-history.c:91
#, c-format
msgid "Failed to get journal data (%s): %s"
msgstr "Journaldaten (%s) konnten nicht abgerufen werden: %s"

#: app/flatpak-builtins-history.c:146
#, c-format
msgid "Failed to open journal: %s"
msgstr "Journal konnte nicht geöffnet werden: %s"

#: app/flatpak-builtins-history.c:153
#, c-format
msgid "Failed to add match to journal: %s"
msgstr "Übereinstimmung konnte nicht zum Journal hinzugefügt werden: %s"

#: app/flatpak-builtins-history.c:471
msgid " - Show history"
msgstr " - Verlauf anzeigen"

#: app/flatpak-builtins-history.c:490
#, c-format
msgid "Failed to parse the --since option"
msgstr ""

#: app/flatpak-builtins-history.c:501
#, c-format
msgid "Failed to parse the --until option"
msgstr ""

#: app/flatpak-builtins-info.c:56
msgid "Show user installations"
msgstr "Benutzerinstallationen anzeigen"

#: app/flatpak-builtins-info.c:57
msgid "Show system-wide installations"
msgstr "Systemweite Installationen anzeigen"

#: app/flatpak-builtins-info.c:58
msgid "Show specific system-wide installations"
msgstr "Spezifische systemweite Installationen anzeigen"

#: app/flatpak-builtins-info.c:59 app/flatpak-builtins-remote-info.c:59
msgid "Show ref"
msgstr "Referenz anzeigen"

#: app/flatpak-builtins-info.c:60 app/flatpak-builtins-remote-info.c:60
msgid "Show commit"
msgstr "Commit anzeigen"

#: app/flatpak-builtins-info.c:61
msgid "Show origin"
msgstr "Ursprung anzeigen"

#: app/flatpak-builtins-info.c:62
msgid "Show size"
msgstr "Größe anzeigen"

#: app/flatpak-builtins-info.c:63 app/flatpak-builtins-remote-info.c:62
msgid "Show metadata"
msgstr "Metadaten anzeigen"

#: app/flatpak-builtins-info.c:64 app/flatpak-builtins-remote-info.c:63
msgid "Show runtime"
msgstr "Laufzeitumgebung anzeigen"

#: app/flatpak-builtins-info.c:65 app/flatpak-builtins-remote-info.c:64
msgid "Show sdk"
msgstr "sdk anzeigen"

#: app/flatpak-builtins-info.c:66
msgid "Show permissions"
msgstr "Berechtigungen anzeigen"

#: app/flatpak-builtins-info.c:67
msgid "Query file access"
msgstr "Dateizugriff abfragen"

#: app/flatpak-builtins-info.c:67 app/flatpak-builtins-install.c:82
#: app/flatpak-builtins-install.c:88 app/flatpak-builtins-preinstall.c:68
#: app/flatpak-builtins-run.c:182 app/flatpak-builtins-run.c:184
#: app/flatpak-builtins-update.c:67 app/flatpak-builtins-update.c:71
msgid "PATH"
msgstr "PFAD"

#: app/flatpak-builtins-info.c:68
msgid "Show extensions"
msgstr "Erweiterungen anzeigen"

#: app/flatpak-builtins-info.c:69
msgid "Show location"
msgstr "Ort anzeigen"

#: app/flatpak-builtins-info.c:116
msgid "NAME [BRANCH] - Get info about an installed app or runtime"
msgstr ""
"NAME [ZWEIG] - Informationen über eine installierte Anwendung oder "
"Laufzeitumgebung erhalten"

#: app/flatpak-builtins-info.c:123 app/flatpak-builtins-remote-add.c:317
#: app/flatpak-builtins-remote-delete.c:63
msgid "NAME must be specified"
msgstr "NAME muss angegeben werden"

#: app/flatpak-builtins-info.c:196
msgid "ref not present in origin"
msgstr "Referenz ist im Ursprung nicht vorhanden"

#: app/flatpak-builtins-info.c:211 app/flatpak-builtins-remote-info.c:217
#, c-format
msgid "Warning: Commit has no flatpak metadata\n"
msgstr "Warnung: Commit hat keine Flatpak-Metadaten\n"

#: app/flatpak-builtins-info.c:217 app/flatpak-builtins-info.c:259
#: app/flatpak-builtins-info.c:455 app/flatpak-builtins-info.c:513
#: app/flatpak-builtins-remote-info.c:236
#: app/flatpak-builtins-remote-info.c:271
msgid "ID:"
msgstr "Kennung:"

#: app/flatpak-builtins-info.c:218 app/flatpak-builtins-info.c:260
#: app/flatpak-builtins-remote-info.c:237
#: app/flatpak-builtins-remote-info.c:272
msgid "Ref:"
msgstr "Ref:"

#: app/flatpak-builtins-info.c:219 app/flatpak-builtins-info.c:261
#: app/flatpak-builtins-remote-info.c:238
#: app/flatpak-builtins-remote-info.c:273
msgid "Arch:"
msgstr "Architektur:"

#: app/flatpak-builtins-info.c:220 app/flatpak-builtins-info.c:262
#: app/flatpak-builtins-remote-info.c:239
#: app/flatpak-builtins-remote-info.c:274
msgid "Branch:"
msgstr "Zweig:"

#: app/flatpak-builtins-info.c:222 app/flatpak-builtins-info.c:264
#: app/flatpak-builtins-remote-info.c:241
#: app/flatpak-builtins-remote-info.c:276
msgid "Version:"
msgstr "Version:"

#: app/flatpak-builtins-info.c:224 app/flatpak-builtins-info.c:266
#: app/flatpak-builtins-remote-info.c:243
#: app/flatpak-builtins-remote-info.c:278
msgid "License:"
msgstr "Lizenz:"

#: app/flatpak-builtins-info.c:226 app/flatpak-builtins-info.c:269
#: app/flatpak-builtins-remote-info.c:245
#: app/flatpak-builtins-remote-info.c:280
msgid "Collection:"
msgstr "Sammlung:"

#: app/flatpak-builtins-info.c:227 app/flatpak-builtins-info.c:270
#: app/flatpak-builtins-info.c:458 app/flatpak-builtins-info.c:516
msgid "Installation:"
msgstr "Installation:"

#: app/flatpak-builtins-info.c:228 app/flatpak-builtins-info.c:271
#: app/flatpak-builtins-info.c:459 app/flatpak-builtins-info.c:517
#: app/flatpak-builtins-remote-info.c:249
#: app/flatpak-builtins-remote-info.c:284
#, fuzzy
msgid "Installed Size:"
msgstr "Installierte Größe:"

#: app/flatpak-builtins-info.c:231 app/flatpak-builtins-info.c:279
#: app/flatpak-builtins-remote-info.c:252
#: app/flatpak-builtins-remote-info.c:288
msgid "Runtime:"
msgstr "Laufzeitumgebung:"

#: app/flatpak-builtins-info.c:232 app/flatpak-builtins-info.c:288
#: app/flatpak-builtins-remote-info.c:253
#: app/flatpak-builtins-remote-info.c:293
msgid "Sdk:"
msgstr "Sdk:"

#: app/flatpak-builtins-info.c:235 app/flatpak-builtins-info.c:313
#: app/flatpak-builtins-remote-info.c:256
#: app/flatpak-builtins-remote-info.c:319
msgid "Date:"
msgstr "Datum:"

#: app/flatpak-builtins-info.c:237 app/flatpak-builtins-info.c:311
#: app/flatpak-builtins-remote-info.c:258
#: app/flatpak-builtins-remote-info.c:317
msgid "Subject:"
msgstr "Betreff:"

#: app/flatpak-builtins-info.c:240 app/flatpak-builtins-info.c:295
msgid "Active commit:"
msgstr "Aktiver Commit:"

#: app/flatpak-builtins-info.c:241 app/flatpak-builtins-info.c:298
msgid "Latest commit:"
msgstr "Letzter Commit:"

#: app/flatpak-builtins-info.c:244 app/flatpak-builtins-info.c:303
#: app/flatpak-builtins-info.c:457 app/flatpak-builtins-info.c:515
#: app/flatpak-builtins-remote-info.c:259
#: app/flatpak-builtins-remote-info.c:298
msgid "Commit:"
msgstr "Commit:"

#: app/flatpak-builtins-info.c:246 app/flatpak-builtins-info.c:308
#: app/flatpak-builtins-remote-info.c:261
#: app/flatpak-builtins-remote-info.c:303
msgid "Parent:"
msgstr ""

#: app/flatpak-builtins-info.c:248 app/flatpak-builtins-info.c:321
msgid "Alt-id:"
msgstr ""

#: app/flatpak-builtins-info.c:250 app/flatpak-builtins-info.c:325
#: app/flatpak-builtins-remote-info.c:263
#: app/flatpak-builtins-remote-info.c:308
msgid "End-of-life:"
msgstr "Ende des Lebenszyklus:"

#: app/flatpak-builtins-info.c:252 app/flatpak-builtins-info.c:330
#: app/flatpak-builtins-remote-info.c:265
#: app/flatpak-builtins-remote-info.c:313
msgid "End-of-life-rebase:"
msgstr ""

#: app/flatpak-builtins-info.c:254 app/flatpak-builtins-info.c:317
msgid "Subdirectories:"
msgstr "Unterverzeichnisse:"

#: app/flatpak-builtins-info.c:255 app/flatpak-builtins-info.c:454
#: app/flatpak-builtins-info.c:512
msgid "Extension:"
msgstr "Erweiterung:"

#: app/flatpak-builtins-info.c:267 app/flatpak-builtins-info.c:456
#: app/flatpak-builtins-info.c:514
msgid "Origin:"
msgstr "Ursprung:"

#: app/flatpak-builtins-info.c:460 app/flatpak-builtins-info.c:522
msgid "Subpaths:"
msgstr "Unterpfade:"

#: app/flatpak-builtins-info.c:478
msgid "unmaintained"
msgstr "nicht gewartet"

#: app/flatpak-builtins-info.c:480 app/flatpak-builtins-info.c:482
msgid "unknown"
msgstr "unbekannt"

#: app/flatpak-builtins-install.c:68 app/flatpak-builtins-preinstall.c:57
msgid "Don't pull, only install from local cache"
msgstr "Keinen »Pull« ausführen, Installation nur aus lokalem Zwischenspeicher"

#: app/flatpak-builtins-install.c:69 app/flatpak-builtins-preinstall.c:58
#: app/flatpak-builtins-update.c:60
msgid "Don't deploy, only download to local cache"
msgstr "Nicht bereitstellen, nur in lokalen Zwischenspeicher herunterladen"

#: app/flatpak-builtins-install.c:70 app/flatpak-builtins-preinstall.c:59
msgid "Don't install related refs"
msgstr "Zugehörige Referenzen nicht installieren"

#: app/flatpak-builtins-install.c:71 app/flatpak-builtins-preinstall.c:60
#: app/flatpak-builtins-update.c:62
msgid "Don't verify/install runtime dependencies"
msgstr "Laufzeitabhängigkeiten nicht prüfen/installieren"

#: app/flatpak-builtins-install.c:72
msgid "Don't automatically pin explicit installs"
msgstr ""

#: app/flatpak-builtins-install.c:73 app/flatpak-builtins-preinstall.c:61
#: app/flatpak-builtins-update.c:63
msgid "Don't use static deltas"
msgstr "Keine statischen Deltas verwenden"

#: app/flatpak-builtins-install.c:76 app/flatpak-builtins-preinstall.c:62
msgid "Additionally install the SDK used to build the given refs"
msgstr ""
"Das SDK für die Erstellung der angegebenen Referenzen zusätzlich installieren"

#: app/flatpak-builtins-install.c:77 app/flatpak-builtins-preinstall.c:63
msgid ""
"Additionally install the debug info for the given refs and their dependencies"
msgstr ""
"Die Debug-Informationen für die angegebenen Referenzen und ihre "
"Abhängigkeiten zusätzlich installieren"

#: app/flatpak-builtins-install.c:78
msgid "Assume LOCATION is a .flatpak single-file bundle"
msgstr "ORT als .flatpak Einzelbündel-Datei ansehen"

#: app/flatpak-builtins-install.c:79
msgid "Assume LOCATION is a .flatpakref application description"
msgstr "ORT als .flatpakref-Anwendungsbeschreibung ansehen"

#: app/flatpak-builtins-install.c:80
msgid "Assume LOCATION is containers-transports(5) reference to an OCI image"
msgstr ""

#: app/flatpak-builtins-install.c:81
msgid "Check bundle signatures with GPG key from FILE (- for stdin)"
msgstr ""
"Bündel-Signaturen anhand des GPG-Schlüssels aus DATEI prüfen (- für "
"Standardeingabe)"

#: app/flatpak-builtins-install.c:82
msgid "Only install this subpath"
msgstr "Nur diesen Unterpfad installieren"

#: app/flatpak-builtins-install.c:83 app/flatpak-builtins-preinstall.c:64
#: app/flatpak-builtins-uninstall.c:63 app/flatpak-builtins-update.c:68
msgid "Automatically answer yes for all questions"
msgstr "Automatisch alle Fragen mit ja beantworten"

#: app/flatpak-builtins-install.c:84 app/flatpak-builtins-preinstall.c:65
msgid "Uninstall first if already installed"
msgstr "Zuerst deinstallieren sofern bereits installiert"

#: app/flatpak-builtins-install.c:85 app/flatpak-builtins-preinstall.c:66
#: app/flatpak-builtins-uninstall.c:64 app/flatpak-builtins-update.c:69
msgid "Produce minimal output and don't ask questions"
msgstr "minimale Ausgabe produzieren und keine Fragen stellen"

#: app/flatpak-builtins-install.c:86
msgid "Update install if already installed"
msgstr "Installation aktualisieren sofern bereits installiert"

#. Translators: A sideload is when you install from a local USB drive rather than the Internet.
#: app/flatpak-builtins-install.c:88 app/flatpak-builtins-preinstall.c:68
#: app/flatpak-builtins-update.c:71
msgid "Use this local repo for sideloads"
msgstr ""

#: app/flatpak-builtins-install.c:178
msgid "Bundle filename must be specified"
msgstr "Name der Bündel-Datei muss angegeben werden"

#: app/flatpak-builtins-install.c:188
msgid "Remote bundles are not supported"
msgstr "Entfernte Bündel werden nicht unterstützt"

#: app/flatpak-builtins-install.c:231
msgid "Filename or uri must be specified"
msgstr "Dateiname oder URI muss angegeben werden"

#: app/flatpak-builtins-install.c:295
#, fuzzy
msgid "Image location must be specified"
msgstr "Mindestens eine REF muss angegeben werden"

#: app/flatpak-builtins-install.c:345
msgid "[LOCATION/REMOTE] [REF…] - Install applications or runtimes"
msgstr ""
"ORT/GEGENSTELLE [REF…] - Anwendungen oder Laufzeitumgebungen installieren"

#: app/flatpak-builtins-install.c:378
msgid "At least one REF must be specified"
msgstr "Mindestens eine REF muss angegeben werden"

#: app/flatpak-builtins-install.c:392
#, c-format
msgid "Looking for matches…\n"
msgstr "Suchen nach Übereinstimmungen …\n"

#: app/flatpak-builtins-install.c:513
#, fuzzy, c-format
msgid "No remote refs found for ‘%s’"
msgstr "Keine Ersetzungen für %s gefunden"

#: app/flatpak-builtins-install.c:573 app/flatpak-builtins-uninstall.c:405
#: common/flatpak-ref-utils.c:689 common/flatpak-ref-utils.c:1595
#, c-format
msgid "Invalid branch %s: %s"
msgstr "Ungültiger Zweig %s: %s"

#: app/flatpak-builtins-install.c:606
#, fuzzy, c-format
msgid "Nothing matches %s in local repository for remote %s"
msgstr "Fehler beim Suchen der lokalen Quelle: %s"

#: app/flatpak-builtins-install.c:608
#, c-format
msgid "Nothing matches %s in remote %s"
msgstr "Kein Treffer für %s in Gegenstelle %s"

#: app/flatpak-builtins-install.c:629
#, c-format
msgid "Skipping: %s\n"
msgstr "Wird übersprungen: %s\n"

#: app/flatpak-builtins-kill.c:110
#, c-format
msgid "%s is not running"
msgstr "%s wird nicht ausgeführt"

#: app/flatpak-builtins-kill.c:136
msgid "INSTANCE - Stop a running application"
msgstr "INSTANZ - Stoppen einer laufenden Anwendung"

#: app/flatpak-builtins-kill.c:144 app/flatpak-builtins-ps.c:256
msgid "Extra arguments given"
msgstr "Zusätzliche Argumente angegeben"

#: app/flatpak-builtins-kill.c:150
msgid "Must specify the app to kill"
msgstr ""

#: app/flatpak-builtins-list.c:47
msgid "Show extra information"
msgstr "Zusätzliche Informationen anzeigen"

#: app/flatpak-builtins-list.c:48
msgid "List installed runtimes"
msgstr "Installierte Laufzeitumgebungen auflisten"

#: app/flatpak-builtins-list.c:49
msgid "List installed applications"
msgstr "Installierte Anwendungen auflisten"

#: app/flatpak-builtins-list.c:50
msgid "Arch to show"
msgstr "Anzuzeigende Architektur"

#: app/flatpak-builtins-list.c:51 app/flatpak-builtins-remote-ls.c:57
msgid "List all refs (including locale/debug)"
msgstr "Alle Referenzen auflisten (einschließlich lokale und Debug-Referenzen)"

#: app/flatpak-builtins-list.c:53 app/flatpak-builtins-remote-ls.c:58
msgid "List all applications using RUNTIME"
msgstr "Alle Anwendungen auflisten, die die LAUFZEITUMGEBUNG verwenden"

#: app/flatpak-builtins-list.c:59 app/flatpak-builtins-remote-list.c:51
#: app/flatpak-builtins-remote-ls.c:68 app/flatpak-builtins-search.c:44
msgid "Name"
msgstr "Name"

#: app/flatpak-builtins-list.c:59 app/flatpak-builtins-remote-list.c:51
#: app/flatpak-builtins-remote-ls.c:68 app/flatpak-builtins-search.c:44
msgid "Show the name"
msgstr "Name anzeigen"

#: app/flatpak-builtins-list.c:60 app/flatpak-builtins-remote-list.c:60
#: app/flatpak-builtins-remote-ls.c:69 app/flatpak-builtins-search.c:45
msgid "Description"
msgstr "Beschreibung"

#: app/flatpak-builtins-list.c:60 app/flatpak-builtins-remote-ls.c:69
#: app/flatpak-builtins-search.c:45
msgid "Show the description"
msgstr "Beschreibung anzeigen"

#: app/flatpak-builtins-list.c:61 app/flatpak-builtins-remote-ls.c:70
#: app/flatpak-builtins-search.c:46
msgid "Application ID"
msgstr "Anwendungskennung"

#: app/flatpak-builtins-list.c:61 app/flatpak-builtins-ps.c:52
#: app/flatpak-builtins-remote-ls.c:70 app/flatpak-builtins-search.c:46
msgid "Show the application ID"
msgstr "Anwendungskennung anzeigen"

#: app/flatpak-builtins-list.c:62 app/flatpak-builtins-remote-ls.c:71
#: app/flatpak-builtins-search.c:47
msgid "Show the version"
msgstr "Version anzeigen"

#: app/flatpak-builtins-list.c:65 app/flatpak-builtins-ps.c:56
#: app/flatpak-builtins-remote-ls.c:77
msgid "Runtime"
msgstr "Laufzeit"

#: app/flatpak-builtins-list.c:65
msgid "Show the used runtime"
msgstr "Verwendete Laufzeitumgebung anzeigen"

#: app/flatpak-builtins-list.c:66 app/flatpak-builtins-remote-ls.c:74
msgid "Show the origin remote"
msgstr ""

#: app/flatpak-builtins-list.c:67
msgid "Show the installation"
msgstr "Insatallation anzeigen"

#: app/flatpak-builtins-list.c:69
msgid "Active commit"
msgstr "Aktiver Commit"

#: app/flatpak-builtins-list.c:69 app/flatpak-builtins-remote-ls.c:76
msgid "Show the active commit"
msgstr "Aktiven Commit anzeigen"

#: app/flatpak-builtins-list.c:70
msgid "Latest commit"
msgstr "Letzter Commit"

#: app/flatpak-builtins-list.c:70
msgid "Show the latest commit"
msgstr "Letzten Commit anzeigen"

#: app/flatpak-builtins-list.c:71 app/flatpak-builtins-remote-ls.c:78
msgid "Installed size"
msgstr "Installierte Größe"

#: app/flatpak-builtins-list.c:71 app/flatpak-builtins-remote-ls.c:78
msgid "Show the installed size"
msgstr "Installierte Größe anzeigen"

#: app/flatpak-builtins-list.c:72 app/flatpak-builtins-remote-list.c:58
#: app/flatpak-builtins-remote-ls.c:80 app/flatpak-builtins-repo.c:340
msgid "Options"
msgstr "Optionen"

#: app/flatpak-builtins-list.c:72 app/flatpak-builtins-remote-list.c:58
#: app/flatpak-builtins-remote-ls.c:80
msgid "Show options"
msgstr "Optionen anzeigen"

#: app/flatpak-builtins-list.c:180
#, fuzzy, c-format
msgid "Unable to load details of %s: %s"
msgstr ""
"Zusätzliche Metadaten aus Zusammenfassung der entfernten Quelle für %s "
"werden aktualisiert\n"

#: app/flatpak-builtins-list.c:190
#, fuzzy, c-format
msgid "Unable to inspect current version of %s: %s"
msgstr "Datei %s kann nicht erstellt werden"

#: app/flatpak-builtins-list.c:408
msgid " - List installed apps and/or runtimes"
msgstr " - Installierte Anwendungen und/oder Laufzeiten auflisten"

#: app/flatpak-builtins-make-current.c:38
msgid "Arch to make current for"
msgstr "Architektur als aktuell festlegen für"

#: app/flatpak-builtins-make-current.c:58
msgid "APP BRANCH - Make branch of application current"
msgstr "ANWENDUNG ZWEIG - Zweig der Anwendung aktuell setzen"

#: app/flatpak-builtins-make-current.c:69 app/flatpak-builtins-run.c:260
msgid "APP must be specified"
msgstr "ANWENDUNG muss angegeben werden"

#: app/flatpak-builtins-make-current.c:84
msgid "BRANCH must be specified"
msgstr "ZWEIG muss angegeben werden"

#: app/flatpak-builtins-make-current.c:97
#, c-format
msgid "App %s branch %s is not installed"
msgstr "Anwendung %s Zweig %s ist nicht installiert"

#: app/flatpak-builtins-mask.c:42
msgid "Remove matching masks"
msgstr "Übereinstimmende Masken entfernen"

#: app/flatpak-builtins-mask.c:54
msgid ""
"[PATTERN…] - disable updates and automatic installation matching patterns"
msgstr ""
"[MUSTER...] - Aktualisierungen und automatische Installation nach Mustern "
"deaktivieren"

#: app/flatpak-builtins-mask.c:73
#, c-format
msgid "No masked patterns\n"
msgstr "Keine maskierten Muster\n"

#: app/flatpak-builtins-mask.c:78
#, c-format
msgid "Masked patterns:\n"
msgstr "Maskierte Muster:\n"

#: app/flatpak-builtins-override.c:42
msgid "Remove existing overrides"
msgstr ""

#: app/flatpak-builtins-override.c:43
msgid "Show existing overrides"
msgstr ""

#: app/flatpak-builtins-override.c:59
msgid "[APP] - Override settings [for application]"
msgstr "[ANWENDUNG] - Einstellungen für ANWENDUNG überschreiben"

#: app/flatpak-builtins-permission-list.c:143
msgid "[TABLE] [ID] - List permissions"
msgstr "[TABELLE] [KENNUNG] - Berechtigungen auflisten"

#: app/flatpak-builtins-permission-list.c:179
#: app/flatpak-builtins-permission-show.c:142
msgid "Table"
msgstr "Tabelle"

#: app/flatpak-builtins-permission-list.c:180
#: app/flatpak-builtins-permission-show.c:143
msgid "Object"
msgstr "Objekt"

#: app/flatpak-builtins-permission-list.c:181
#: app/flatpak-builtins-permission-show.c:144
msgid "App"
msgstr "Anwendung"

#: app/flatpak-builtins-permission-list.c:183
#: app/flatpak-builtins-permission-show.c:146
msgid "Data"
msgstr "Daten"

#: app/flatpak-builtins-permission-remove.c:120
msgid "TABLE ID [APP_ID] - Remove item from permission store"
msgstr ""
"TABELLE KENNUNG [APP_KENNUNG] - Element aus dem Berechtigungsspeicher "
"entfernen"

#: app/flatpak-builtins-permission-remove.c:129
#: app/flatpak-builtins-permission-set.c:120
msgid "Too few arguments"
msgstr "Zu wenig Argumente"

#: app/flatpak-builtins-permission-reset.c:43
msgid "Reset all permissions"
msgstr "Alle Berechtigungen zurücksetzen"

#: app/flatpak-builtins-permission-reset.c:144
msgid "APP_ID - Reset permissions for an app"
msgstr "APP_KENNUNG - Berechtigungen für eine Anwendung zurücksetzen"

#: app/flatpak-builtins-permission-reset.c:153
#: app/flatpak-builtins-permission-show.c:124
msgid "Wrong number of arguments"
msgstr "Falsche Anzahl an Argumenten"

#: app/flatpak-builtins-permission-set.c:42
msgid "Associate DATA with the entry"
msgstr "DATEN mit dem Eintrag verknüpfen"

#: app/flatpak-builtins-permission-set.c:42
msgid "DATA"
msgstr "DATEN"

#: app/flatpak-builtins-permission-set.c:111
msgid "TABLE ID APP_ID [PERMISSION...] - Set permissions"
msgstr ""
"TABELLE KENNUNG APP_KENNUNG [BERECHTIGUNG...] - Berechtigungen festlegen"

#: app/flatpak-builtins-permission-set.c:132
#, c-format
msgid "Failed to parse '%s' as GVariant: "
msgstr ""

#: app/flatpak-builtins-permission-show.c:115
msgid "APP_ID - Show permissions for an app"
msgstr "APP_KENNUNG - Berechtigungen für eine Anwendung anzeigen"

#: app/flatpak-builtins-pin.c:44
msgid "Remove matching pins"
msgstr ""

#: app/flatpak-builtins-pin.c:56
msgid "[PATTERN…] - disable automatic removal of runtimes matching patterns"
msgstr ""
"[MUSTER...] - automatische Entfernung von Laufzeiten, die einem Muster "
"entsprechen, deaktivieren"

#: app/flatpak-builtins-pin.c:75
#, c-format
msgid "No pinned patterns\n"
msgstr ""

#: app/flatpak-builtins-pin.c:80
#, c-format
msgid "Pinned patterns:\n"
msgstr ""

#: app/flatpak-builtins-preinstall.c:80
msgid "- Install flatpaks that are part of the operating system"
msgstr ""

#: app/flatpak-builtins-preinstall.c:118
#, c-format
msgid "Nothing to do.\n"
msgstr "Nichts zu tun.\n"

#: app/flatpak-builtins-ps.c:49
msgid "Instance"
msgstr "Instanz"

#: app/flatpak-builtins-ps.c:49
msgid "Show the instance ID"
msgstr "Instanzkennung anzeigen"

#: app/flatpak-builtins-ps.c:50 app/flatpak-builtins-run.c:178
msgid "PID"
msgstr "Prozesskennung"

#: app/flatpak-builtins-ps.c:50
msgid "Show the PID of the wrapper process"
msgstr ""

#: app/flatpak-builtins-ps.c:51
msgid "Child-PID"
msgstr ""

#: app/flatpak-builtins-ps.c:51
msgid "Show the PID of the sandbox process"
msgstr ""

#: app/flatpak-builtins-ps.c:54 app/flatpak-builtins-search.c:48
msgid "Show the application branch"
msgstr "Anwendungszweig anzeigen"

#: app/flatpak-builtins-ps.c:55
msgid "Show the application commit"
msgstr ""

#: app/flatpak-builtins-ps.c:56
msgid "Show the runtime ID"
msgstr "Laufzeitkennung anzeigen"

#: app/flatpak-builtins-ps.c:57
msgid "R.-Branch"
msgstr "R.-Zweig"

#: app/flatpak-builtins-ps.c:57
msgid "Show the runtime branch"
msgstr "Laufzeitzweig anzeigen"

#: app/flatpak-builtins-ps.c:58
msgid "R.-Commit"
msgstr ""

#: app/flatpak-builtins-ps.c:58
msgid "Show the runtime commit"
msgstr ""

#: app/flatpak-builtins-ps.c:59
msgid "Active"
msgstr "Aktiv"

#: app/flatpak-builtins-ps.c:59
msgid "Show whether the app is active"
msgstr "Anzeigen, ob die Anwendung aktiv ist"

#: app/flatpak-builtins-ps.c:60
msgid "Background"
msgstr "Hintergrund"

#: app/flatpak-builtins-ps.c:60
msgid "Show whether the app is background"
msgstr "Anzeigen, ob die Anwendung im Hintergrund läuft"

#: app/flatpak-builtins-ps.c:246
msgid " - Enumerate running sandboxes"
msgstr " - Laufende Sandboxen nummerieren"

#: app/flatpak-builtins-remote-add.c:66
msgid "Do nothing if the provided remote exists"
msgstr "Nichts unternehmen, wenn die Gegenstelle existiert"

#: app/flatpak-builtins-remote-add.c:67
msgid "LOCATION specifies a configuration file, not the repo location"
msgstr "ORT legt eine Konfigurationsdatei fest, nicht den Quellort"

#: app/flatpak-builtins-remote-add.c:72 app/flatpak-builtins-remote-modify.c:78
msgid "Disable GPG verification"
msgstr "GPG-Überprüfung deaktivieren"

# Bedeutung aus flatpak-remote-add.xml
# Mark the remote as not enumerated. This means the remote will not be used to list applications, for instance in graphical installation tools.
#: app/flatpak-builtins-remote-add.c:73 app/flatpak-builtins-remote-modify.c:79
msgid "Mark the remote as don't enumerate"
msgstr "Gegenstelle als »nicht berücksichtigen« markieren"

# Bedeutung aus flatpak-remote-add.xml
# Mark the remote as not enumerated. This means the remote will not be used to list applications, for instance in graphical installation tools.
#: app/flatpak-builtins-remote-add.c:74 app/flatpak-builtins-remote-modify.c:80
msgid "Mark the remote as don't use for deps"
msgstr "Gegenstelle als »Nicht für Abhängigkeiten verwenden« markieren"

#: app/flatpak-builtins-remote-add.c:75 app/flatpak-builtins-remote-modify.c:81
msgid "Set priority (default 1, higher is more prioritized)"
msgstr "Priorität festlegen (Standard 1, mehr bedeutet höhere Priorität)"

#: app/flatpak-builtins-remote-add.c:75 app/flatpak-builtins-remote-modify.c:81
msgid "PRIORITY"
msgstr "PRIORITÄT"

#: app/flatpak-builtins-remote-add.c:76
msgid "The named subset to use for this remote"
msgstr ""
"Die benannte Teilmenge, die für diese Gegenstelle verwendet werden soll"

#: app/flatpak-builtins-remote-add.c:76 app/flatpak-builtins-remote-modify.c:71
msgid "SUBSET"
msgstr "TEILMENGE"

#: app/flatpak-builtins-remote-add.c:77 app/flatpak-builtins-remote-modify.c:82
msgid "A nice name to use for this remote"
msgstr "Ein schöner Name, der für diese Gegenstelle verwendet werden soll "

#: app/flatpak-builtins-remote-add.c:78 app/flatpak-builtins-remote-modify.c:83
msgid "A one-line comment for this remote"
msgstr "Eine einzeilige Beschreibung für diese Gegenstelle"

#: app/flatpak-builtins-remote-add.c:79 app/flatpak-builtins-remote-modify.c:84
msgid "A full-paragraph description for this remote"
msgstr "Ein vollständiger Absatz als Beschreibung für diese Gegenstelle"

#: app/flatpak-builtins-remote-add.c:80 app/flatpak-builtins-remote-modify.c:85
msgid "URL for a website for this remote"
msgstr "URL für eine Webseite für diese Gegenstelle"

#: app/flatpak-builtins-remote-add.c:81 app/flatpak-builtins-remote-modify.c:86
msgid "URL for an icon for this remote"
msgstr "URL für ein Symbol für diese Gegenstelle"

#: app/flatpak-builtins-remote-add.c:82 app/flatpak-builtins-remote-modify.c:87
msgid "Default branch to use for this remote"
msgstr "Zu verwendender Vorgabe-Zweig für diese Gegenstelle"

#: app/flatpak-builtins-remote-add.c:84 app/flatpak-builtins-remote-modify.c:89
msgid "Import GPG key from FILE (- for stdin)"
msgstr "GPG-Schlüssel aus DATEI importieren (- für stdin)"

#: app/flatpak-builtins-remote-add.c:85 app/flatpak-builtins-remote-modify.c:90
msgid "Load signatures from URL"
msgstr ""

#: app/flatpak-builtins-remote-add.c:86 app/flatpak-builtins-remote-modify.c:92
msgid "Set path to local filter FILE"
msgstr ""

#: app/flatpak-builtins-remote-add.c:87 app/flatpak-builtins-remote-modify.c:93
msgid "Disable the remote"
msgstr "Gegenstelle deaktivieren"

#: app/flatpak-builtins-remote-add.c:88 app/flatpak-builtins-remote-modify.c:94
msgid "Name of authenticator"
msgstr "Name des Authentifikators"

#: app/flatpak-builtins-remote-add.c:90 app/flatpak-builtins-remote-modify.c:96
msgid "Autoinstall authenticator"
msgstr "Authentifikator automatisch installieren"

#: app/flatpak-builtins-remote-add.c:91 app/flatpak-builtins-remote-modify.c:97
msgid "Don't autoinstall authenticator"
msgstr "Authentifikator nicht automatisch installieren"

#: app/flatpak-builtins-remote-add.c:92 app/flatpak-builtins-remote-modify.c:99
msgid "Don't follow the redirect set in the summary file"
msgstr ""

#: app/flatpak-builtins-remote-add.c:261 app/flatpak-builtins-remote-add.c:268
#, c-format
msgid "Can't load uri %s: %s\n"
msgstr ""

#: app/flatpak-builtins-remote-add.c:276 common/flatpak-dir.c:4643
#, c-format
msgid "Can't load file %s: %s\n"
msgstr ""

#: app/flatpak-builtins-remote-add.c:304
msgid "NAME LOCATION - Add a remote repository"
msgstr "NAME ORT - Eine Gegenstelle hinzufügen"

#: app/flatpak-builtins-remote-add.c:331
msgid "GPG verification is required if collections are enabled"
msgstr "GPG-Überprüfung ist erforderlich, wenn Sammlungen aktiviert sind"

#: app/flatpak-builtins-remote-add.c:393
#, c-format
msgid "Remote %s already exists"
msgstr "Gegenstelle %s existiert bereits"

#: app/flatpak-builtins-remote-add.c:405
#: app/flatpak-builtins-remote-modify.c:340
#, c-format
msgid "Invalid authenticator name %s"
msgstr "Ungültiger Authentifikator-Name %s"

#: app/flatpak-builtins-remote-add.c:422
#, c-format
msgid "Warning: Could not update extra metadata for '%s': %s\n"
msgstr ""
"Warnung: Zusätzliche Metadaten für »%s« konnten nicht aktualisiert werden: "
"%s\n"

#: app/flatpak-builtins-remote-delete.c:39
msgid "Remove remote even if in use"
msgstr "Gegenstelle entfernen, selbst wenn sie in Verwendung ist"

#: app/flatpak-builtins-remote-delete.c:53
msgid "NAME - Delete a remote repository"
msgstr "NAME - Gegenstelle löschen"

#: app/flatpak-builtins-remote-delete.c:100
#, c-format
msgid "The following refs are installed from remote '%s':"
msgstr ""

#: app/flatpak-builtins-remote-delete.c:101
msgid "Remove them?"
msgstr ""

#: app/flatpak-builtins-remote-delete.c:103
#, c-format
msgid "Can't remove remote '%s' with installed refs"
msgstr ""

#: app/flatpak-builtins-remote-info.c:55
msgid "Commit to show info for"
msgstr ""

#: app/flatpak-builtins-remote-info.c:58
msgid "Display log"
msgstr "Protokoll anzeigen"

#: app/flatpak-builtins-remote-info.c:61
msgid "Show parent"
msgstr ""

#: app/flatpak-builtins-remote-info.c:65 app/flatpak-builtins-remote-ls.c:60
msgid "Use local caches even if they are stale"
msgstr ""

#. Translators: A sideload is when you install from a local USB drive rather than the Internet.
#: app/flatpak-builtins-remote-info.c:67 app/flatpak-builtins-remote-ls.c:62
msgid "Only list refs available as sideloads"
msgstr ""

#: app/flatpak-builtins-remote-info.c:114
msgid ""
" REMOTE REF - Show information about an application or runtime in a remote"
msgstr ""

#: app/flatpak-builtins-remote-info.c:125
msgid "REMOTE and REF must be specified"
msgstr "GEGENSTELLE und REFERENZ muss angegeben werden"

#: app/flatpak-builtins-remote-info.c:247
#: app/flatpak-builtins-remote-info.c:282
#, fuzzy
msgid "Download Size:"
msgstr "Heruntergeladene Größe"

#: app/flatpak-builtins-remote-info.c:267
#: app/flatpak-builtins-remote-info.c:325
msgid "History:"
msgstr "Verlauf:"

#: app/flatpak-builtins-remote-info.c:348
msgid " Commit:"
msgstr " Commit:"

#: app/flatpak-builtins-remote-info.c:349
msgid " Subject:"
msgstr " Betreff:"

#: app/flatpak-builtins-remote-info.c:350
msgid " Date:"
msgstr " Datum:"

#: app/flatpak-builtins-remote-info.c:383
#, c-format
msgid "Warning: Commit %s has no flatpak metadata\n"
msgstr ""

#: app/flatpak-builtins-remote-list.c:43
msgid "Show remote details"
msgstr "Details zur Gegenstelle anzeigen"

#: app/flatpak-builtins-remote-list.c:44
msgid "Show disabled remotes"
msgstr "Deaktivierte Gegenstellen anzeigen"

#: app/flatpak-builtins-remote-list.c:52
msgid "Title"
msgstr "Titel"

#: app/flatpak-builtins-remote-list.c:52
msgid "Show the title"
msgstr "Titel anzeigen"

#: app/flatpak-builtins-remote-list.c:53
msgid "Show the URL"
msgstr "URL anzeigen"

#: app/flatpak-builtins-remote-list.c:54
msgid "Show the collection ID"
msgstr "Sammlungskennung anzeigen"

#: app/flatpak-builtins-remote-list.c:55 app/flatpak-builtins-repo.c:392
msgid "Subset"
msgstr "Teilmenge"

#: app/flatpak-builtins-remote-list.c:55
msgid "Show the subset"
msgstr "Teilmenge anzeigen"

#: app/flatpak-builtins-remote-list.c:56
msgid "Filter"
msgstr "Filter"

#: app/flatpak-builtins-remote-list.c:56
msgid "Show filter file"
msgstr "Filterdatei anzeigen"

#: app/flatpak-builtins-remote-list.c:57
msgid "Priority"
msgstr "Priorität"

#: app/flatpak-builtins-remote-list.c:57
msgid "Show the priority"
msgstr "Priorität anzeigen"

# Kommentar oder kommentieren?
#: app/flatpak-builtins-remote-list.c:59
msgid "Comment"
msgstr "Kommentar"

#: app/flatpak-builtins-remote-list.c:59
msgid "Show comment"
msgstr "Kommentar anzeigen"

#: app/flatpak-builtins-remote-list.c:60
msgid "Show description"
msgstr "Beschreibung anzeigen"

#: app/flatpak-builtins-remote-list.c:61
msgid "Homepage"
msgstr "Webseite"

#: app/flatpak-builtins-remote-list.c:61
msgid "Show homepage"
msgstr "Webseite anzeigen"

#: app/flatpak-builtins-remote-list.c:62
msgid "Icon"
msgstr "Symbol"

#: app/flatpak-builtins-remote-list.c:62
msgid "Show icon"
msgstr "Symbol anzeigen"

#: app/flatpak-builtins-remote-list.c:231
msgid " - List remote repositories"
msgstr " - Quellen der Gegenstelle auflisten"

#: app/flatpak-builtins-remote-ls.c:52
msgid "Show arches and branches"
msgstr "Architekturen und Zweige zeigen"

#: app/flatpak-builtins-remote-ls.c:53
msgid "Show only runtimes"
msgstr "Nur Laufzeitumgebungen anzeigen"

#: app/flatpak-builtins-remote-ls.c:54
msgid "Show only apps"
msgstr "Nur Anwendungen anzeigen"

#: app/flatpak-builtins-remote-ls.c:55
msgid "Show only those where updates are available"
msgstr "Nur Anwendungen anzeigen, die aktualisiert werden können"

#: app/flatpak-builtins-remote-ls.c:56
msgid "Limit to this arch (* for all)"
msgstr "Auf diese Architektur begrenzen (* für alle)"

#: app/flatpak-builtins-remote-ls.c:77
msgid "Show the runtime"
msgstr "Die Laufzeitumgebung anzeigen"

#: app/flatpak-builtins-remote-ls.c:79
msgid "Download size"
msgstr "Heruntergeladene Größe"

#: app/flatpak-builtins-remote-ls.c:79
msgid "Show the download size"
msgstr "Heruntergeladene Größe anzeigen"

#: app/flatpak-builtins-remote-ls.c:391
msgid " [REMOTE or URI] - Show available runtimes and applications"
msgstr ""
" [GEGENSTELLE oder ADRESSE] - Verfügbare Laufzeitumgebungen und Anwendungen "
"anzeigen"

#: app/flatpak-builtins-remote-modify.c:67
msgid "Enable GPG verification"
msgstr "GPG-Überprüfung aktivieren"

#: app/flatpak-builtins-remote-modify.c:68
msgid "Mark the remote as enumerate"
msgstr "Gegenstelle markieren als »berücksichtigen«"

# Bedeutung aus flatpak-remote-add.xml
# Mark the remote as not enumerated. This means the remote will not be used to list applications, for instance in graphical installation tools.
#: app/flatpak-builtins-remote-modify.c:69
msgid "Mark the remote as used for dependencies"
msgstr "Gegenstelle markieren als »Verwendet für Abhängigkeiten«"

#: app/flatpak-builtins-remote-modify.c:70
#, fuzzy
msgid "Set a new URL"
msgstr "Eine neue Adresse festlegen"

#: app/flatpak-builtins-remote-modify.c:71
msgid "Set a new subset to use"
msgstr ""

#: app/flatpak-builtins-remote-modify.c:72
msgid "Enable the remote"
msgstr "Gegenstelle aktivieren"

#: app/flatpak-builtins-remote-modify.c:73
msgid "Update extra metadata from the summary file"
msgstr "Zusätzliche Metadaten aus der Zusammenfassungsdatei aktualisieren"

#: app/flatpak-builtins-remote-modify.c:91
msgid "Disable local filter"
msgstr "Lokalen Filter deaktivieren"

#: app/flatpak-builtins-remote-modify.c:95
msgid "Authenticator options"
msgstr "Authentifikator-Optionen"

#: app/flatpak-builtins-remote-modify.c:98
#, fuzzy
msgid "Follow the redirect set in the summary file"
msgstr "Zusätzliche Metadaten aus der Zusammenfassungsdatei aktualisieren"

#: app/flatpak-builtins-remote-modify.c:306
msgid "NAME - Modify a remote repository"
msgstr "NAME - Gegenstelle verändern"

#: app/flatpak-builtins-remote-modify.c:316
msgid "Remote NAME must be specified"
msgstr "NAME der Gegenstelle muss angegeben werden"

#: app/flatpak-builtins-remote-modify.c:327
#, c-format
msgid "Updating extra metadata from remote summary for %s\n"
msgstr ""
"Zusätzliche Metadaten aus Zusammenfassung der Gegenstelle für %s werden "
"aktualisiert\n"

#: app/flatpak-builtins-remote-modify.c:330
#, c-format
msgid "Error updating extra metadata for '%s': %s\n"
msgstr "Fehler beim Aktualisieren der Metadaten für »%s«: %s\n"

#: app/flatpak-builtins-remote-modify.c:331
#, c-format
msgid "Could not update extra metadata for %s"
msgstr "Zusätzliche Metadaten für %s konnten nicht aktualisiert werden"

#: app/flatpak-builtins-repair.c:43
msgid "Don't make any changes"
msgstr "Keine Änderungen vornehmen"

#: app/flatpak-builtins-repair.c:44
msgid "Reinstall all refs"
msgstr ""

#: app/flatpak-builtins-repair.c:68
#, c-format
msgid "Object missing: %s.%s\n"
msgstr "Objekt fehlt: %s.%s\n"

#: app/flatpak-builtins-repair.c:76
#, c-format
msgid "Object invalid: %s.%s\n"
msgstr "Objekt ungültig: %s.%s\n"

#: app/flatpak-builtins-repair.c:81
#, c-format
msgid "%s, deleting object\n"
msgstr "%s, Objekt wird gelöscht\n"

#: app/flatpak-builtins-repair.c:146
#, c-format
msgid "Can't load object %s: %s\n"
msgstr "Objekt %s kann nicht geladen werden: %s\n"

#: app/flatpak-builtins-repair.c:228
#, c-format
msgid "Commit invalid %s: %s\n"
msgstr "Commit ungültig %s: %s\n"

#: app/flatpak-builtins-repair.c:231
#, c-format
msgid "Deleting invalid commit %s: %s\n"
msgstr "Ungültiger Commit %s wird gelöscht: %s \n"

#: app/flatpak-builtins-repair.c:261
#, c-format
msgid "Commit should be marked partial: %s\n"
msgstr ""

#: app/flatpak-builtins-repair.c:264
#, c-format
msgid "Marking commit as partial: %s\n"
msgstr ""

#: app/flatpak-builtins-repair.c:293
#, c-format
msgid "Problems loading data for %s: %s\n"
msgstr "Probleme beim Laden von Daten für %s: %s\n"

#: app/flatpak-builtins-repair.c:306
#, c-format
msgid "Error reinstalling %s: %s\n"
msgstr "Fehler bei der Neuinstallation von %s: %s\n"

#: app/flatpak-builtins-repair.c:327
msgid "- Repair a flatpak installation"
msgstr "- Reparatur einer Flatpak-Installation"

#: app/flatpak-builtins-repair.c:406
#, c-format
msgid "Removing non-deployed ref %s…\n"
msgstr ""

#: app/flatpak-builtins-repair.c:411
#, c-format
msgid "Skipping non-deployed ref %s…\n"
msgstr ""

#: app/flatpak-builtins-repair.c:429
#, c-format
msgid "[%d/%d] Verifying %s…\n"
msgstr "[%d/%d] Wird verifiziert %s …\n"

#: app/flatpak-builtins-repair.c:435
#, c-format
msgid "Dry run: "
msgstr "Trockenlauf:"

#: app/flatpak-builtins-repair.c:440
#, c-format
msgid "Deleting ref %s due to missing objects\n"
msgstr ""

#: app/flatpak-builtins-repair.c:444
#, c-format
msgid "Deleting ref %s due to invalid objects\n"
msgstr ""

#: app/flatpak-builtins-repair.c:448
#, c-format
msgid "Deleting ref %s due to %d\n"
msgstr ""

#: app/flatpak-builtins-repair.c:464
#, c-format
msgid "Checking remotes...\n"
msgstr "Gegenstellen werden überprüft ...\n"

#: app/flatpak-builtins-repair.c:482
#, c-format
msgid "Remote %s for ref %s is missing\n"
msgstr ""

#: app/flatpak-builtins-repair.c:484
#, c-format
msgid "Remote %s for ref %s is disabled\n"
msgstr ""

#: app/flatpak-builtins-repair.c:490
#, c-format
msgid "Pruning objects\n"
msgstr ""

#: app/flatpak-builtins-repair.c:498
#, c-format
msgid "Erasing .removed\n"
msgstr ""

#: app/flatpak-builtins-repair.c:524
#, c-format
msgid "Reinstalling refs\n"
msgstr ""

#: app/flatpak-builtins-repair.c:526
#, c-format
msgid "Reinstalling removed refs\n"
msgstr ""

#: app/flatpak-builtins-repair.c:551
#, c-format
msgid "While removing appstream for %s: "
msgstr ""

#: app/flatpak-builtins-repair.c:558
#, c-format
msgid "While deploying appstream for %s: "
msgstr ""

#: app/flatpak-builtins-repo.c:106
#, c-format
msgid "Repo mode: %s\n"
msgstr ""

#: app/flatpak-builtins-repo.c:113
#, c-format
msgid "Indexed summaries: %s\n"
msgstr ""

#: app/flatpak-builtins-repo.c:113 app/flatpak-builtins-repo.c:139
#: app/flatpak-builtins-repo.c:172
msgid "true"
msgstr "wahr"

#: app/flatpak-builtins-repo.c:113 app/flatpak-builtins-repo.c:139
#: app/flatpak-builtins-repo.c:172
msgid "false"
msgstr "falsch"

#: app/flatpak-builtins-repo.c:121
#, c-format
msgid "Subsummaries: "
msgstr ""

#: app/flatpak-builtins-repo.c:136
#, c-format
msgid "Cache version: %d\n"
msgstr ""

#: app/flatpak-builtins-repo.c:139
#, c-format
msgid "Indexed deltas: %s\n"
msgstr "Indexierte Deltas: %s\n"

#: app/flatpak-builtins-repo.c:142
#, c-format
msgid "Title: %s\n"
msgstr "Titel: %s\n"

#: app/flatpak-builtins-repo.c:145
#, c-format
msgid "Comment: %s\n"
msgstr "Kommentar: %s\n"

#: app/flatpak-builtins-repo.c:148
#, c-format
msgid "Description: %s\n"
msgstr "Beschreibung: %s\n"

#: app/flatpak-builtins-repo.c:151
#, c-format
msgid "Homepage: %s\n"
msgstr "Webseite: %s\n"

#: app/flatpak-builtins-repo.c:154
#, c-format
msgid "Icon: %s\n"
msgstr "Symbol: %s\n"

#: app/flatpak-builtins-repo.c:157
#, c-format
msgid "Collection ID: %s\n"
msgstr "Sammlungskennung: %s\n"

#: app/flatpak-builtins-repo.c:160
#, c-format
msgid "Default branch: %s\n"
msgstr "Standardzweig: %s\n"

#: app/flatpak-builtins-repo.c:163
#, c-format
msgid "Redirect URL: %s\n"
msgstr "URL-Weiterleitung: %s\n"

#: app/flatpak-builtins-repo.c:166
#, c-format
msgid "Deploy collection ID: %s\n"
msgstr ""

#: app/flatpak-builtins-repo.c:169
#, c-format
msgid "Authenticator name: %s\n"
msgstr "Authentifikator-Name: %s\n"

#: app/flatpak-builtins-repo.c:172
#, c-format
msgid "Authenticator install: %s\n"
msgstr ""

#: app/flatpak-builtins-repo.c:180
#, c-format
msgid "GPG key hash: %s\n"
msgstr ""

#: app/flatpak-builtins-repo.c:184
#, c-format
msgid "%zd summary branches\n"
msgstr ""

#: app/flatpak-builtins-repo.c:336
msgid "Installed"
msgstr "Installiert"

#. Translators: Download is used here as a noun
#: app/flatpak-builtins-repo.c:338 app/flatpak-cli-transaction.c:1462
msgid "Download"
msgstr "Herunterladen"

#: app/flatpak-builtins-repo.c:339
msgid "Subsets"
msgstr "Teilmengen"

#: app/flatpak-builtins-repo.c:393
msgid "Digest"
msgstr "Prüfsumme"

#: app/flatpak-builtins-repo.c:394
msgid "History length"
msgstr "Verkaufslänge"

#: app/flatpak-builtins-repo.c:711
msgid "Print general information about the repository"
msgstr "Allgemeine Informationen über die Quelle ausgeben"

#: app/flatpak-builtins-repo.c:712
msgid "List the branches in the repository"
msgstr "Zweige in dieser Quelle auflisten"

#: app/flatpak-builtins-repo.c:713
msgid "Print metadata for a branch"
msgstr "Metadaten für einen Zweig ausgeben"

#: app/flatpak-builtins-repo.c:714
msgid "Show commits for a branch"
msgstr "Commits für einen Zweig anzeigen"

#: app/flatpak-builtins-repo.c:715
#, fuzzy
msgid "Print information about the repo subsets"
msgstr "Allgemeine Informationen über die Quelle ausgeben"

#: app/flatpak-builtins-repo.c:716
msgid "Limit information to subsets with this prefix"
msgstr ""

#: app/flatpak-builtins-repo.c:732
msgid "LOCATION - Repository maintenance"
msgstr "ORT - Wartung der Quelle"

#: app/flatpak-builtins-run.c:159
msgid "Command to run"
msgstr "Auszuführender Befehl"

#: app/flatpak-builtins-run.c:160
msgid "Directory to run the command in"
msgstr "Verzeichnis, in dem der Befehl ausgeführt werden soll"

#: app/flatpak-builtins-run.c:161
msgid "Branch to use"
msgstr "Zu verwendender Zweig"

#: app/flatpak-builtins-run.c:162
msgid "Use development runtime"
msgstr "Entwickler-Laufzeitumgebung verwenden"

#: app/flatpak-builtins-run.c:163
msgid "Runtime to use"
msgstr "Zu verwendende Laufzeitumgebung"

#: app/flatpak-builtins-run.c:164
msgid "Runtime version to use"
msgstr "Zu verwendende Laufzeit"

#: app/flatpak-builtins-run.c:167
msgid "Log accessibility bus calls"
msgstr "Hilfstechnologie-Bus-Aufrufe protokollieren"

#: app/flatpak-builtins-run.c:168
msgid "Don't proxy accessibility bus calls"
msgstr ""

#: app/flatpak-builtins-run.c:169
msgid "Proxy accessibility bus calls (default except when sandboxed)"
msgstr ""

#: app/flatpak-builtins-run.c:170
msgid "Don't proxy session bus calls"
msgstr ""

#: app/flatpak-builtins-run.c:171
msgid "Proxy session bus calls (default except when sandboxed)"
msgstr ""

#: app/flatpak-builtins-run.c:172
msgid "Don't start portals"
msgstr ""

#: app/flatpak-builtins-run.c:173
msgid "Enable file forwarding"
msgstr "Dateiweiterleitung aktivieren"

#: app/flatpak-builtins-run.c:174
msgid "Run specified commit"
msgstr ""

#: app/flatpak-builtins-run.c:175
msgid "Use specified runtime commit"
msgstr ""

#: app/flatpak-builtins-run.c:176
msgid "Run completely sandboxed"
msgstr "Vollständig im Sandboxmodus ausführen"

#: app/flatpak-builtins-run.c:178
msgid "Use PID as parent pid for sharing namespaces"
msgstr ""

#: app/flatpak-builtins-run.c:179
msgid "Make processes visible in parent namespace"
msgstr ""

#: app/flatpak-builtins-run.c:180
msgid "Share process ID namespace with parent"
msgstr ""

#: app/flatpak-builtins-run.c:181
msgid "Write the instance ID to the given file descriptor"
msgstr ""

#: app/flatpak-builtins-run.c:182
msgid "Use PATH instead of the app's /app"
msgstr ""

#: app/flatpak-builtins-run.c:183
msgid "Use FD instead of the app's /app"
msgstr ""

#: app/flatpak-builtins-run.c:183 app/flatpak-builtins-run.c:185
#: app/flatpak-builtins-run.c:187 app/flatpak-builtins-run.c:188
#: common/flatpak-context.c:2672
msgid "FD"
msgstr "FD"

#: app/flatpak-builtins-run.c:184
msgid "Use PATH instead of the runtime's /usr"
msgstr ""

#: app/flatpak-builtins-run.c:185
msgid "Use FD instead of the runtime's /usr"
msgstr ""

#: app/flatpak-builtins-run.c:186
#, fuzzy
msgid "Clear all outside environment variables"
msgstr "Umgebungsvariable festlegen"

#: app/flatpak-builtins-run.c:187
msgid ""
"Bind mount the file or directory referred to by FD to its canonicalized path"
msgstr ""

#: app/flatpak-builtins-run.c:188
msgid ""
"Bind mount the file or directory referred to by FD read-only to its "
"canonicalized path"
msgstr ""

#: app/flatpak-builtins-run.c:219
msgid "APP [ARGUMENT…] - Run an app"
msgstr "ANWENDUNG [ARGUMENT…] - Eine Anwendung ausführen"

#: app/flatpak-builtins-run.c:370
#, c-format
msgid "runtime/%s/%s/%s not installed"
msgstr "Laufzeit/%s/%s/%s ist nicht installiert"

#: app/flatpak-builtins-run.c:419
msgid "app-fd and app-path cannot both be used"
msgstr ""

#: app/flatpak-builtins-run.c:449
msgid "usr-fd and usr-path cannot both be used"
msgstr ""

#: app/flatpak-builtins-search.c:37
msgid "Arch to search for"
msgstr "Architektur, nach der gesucht werden soll"

#: app/flatpak-builtins-search.c:49
msgid "Remotes"
msgstr "Gegenstellen"

#: app/flatpak-builtins-search.c:49
msgid "Show the remotes"
msgstr "Gegenstellen anzeigen"

#: app/flatpak-builtins-search.c:244
msgid "TEXT - Search remote apps/runtimes for text"
msgstr ""

#: app/flatpak-builtins-search.c:255
msgid "TEXT must be specified"
msgstr "TEXT muss angegeben werden"

#: app/flatpak-builtins-search.c:338
msgid "No matches found"
msgstr "Keine Übereinstimmung gefunden"

#: app/flatpak-builtins-uninstall.c:54
msgid "Arch to uninstall"
msgstr "Zu installierende Architektur"

#: app/flatpak-builtins-uninstall.c:55
msgid "Keep ref in local repository"
msgstr "Referenz in lokaler Quelle behalten"

#: app/flatpak-builtins-uninstall.c:56
msgid "Don't uninstall related refs"
msgstr "Zugehörige Referenzen nicht deinstallieren"

#: app/flatpak-builtins-uninstall.c:57
msgid "Remove files even if running"
msgstr "Dateien entfernen, selbst wenn sie in Verwendung sind"

#: app/flatpak-builtins-uninstall.c:60
msgid "Uninstall all"
msgstr "Alle deinstallieren"

#: app/flatpak-builtins-uninstall.c:61
msgid "Uninstall unused"
msgstr ""

#: app/flatpak-builtins-uninstall.c:62
msgid "Delete app data"
msgstr "Anwendungsdaten löschen"

#: app/flatpak-builtins-uninstall.c:141
#, c-format
msgid "Delete data for %s?"
msgstr "Daten für %s löschen?"

#: app/flatpak-builtins-uninstall.c:220
#, c-format
msgid "Info: applications using the extension %s%s%s branch %s%s%s:\n"
msgstr ""

#: app/flatpak-builtins-uninstall.c:223
#, fuzzy, c-format
msgid "Info: applications using the runtime %s%s%s branch %s%s%s:\n"
msgstr "Anwendungen, die diese Laufzeitumgebung verwenden:\n"

#: app/flatpak-builtins-uninstall.c:238
#, fuzzy
msgid "Really remove?"
msgstr "jede Gegenstelle"

#: app/flatpak-builtins-uninstall.c:255
msgid "[REF…] - Uninstall applications or runtimes"
msgstr "[REF…] - Anwendungen oder Laufzeiten deinstallieren"

#: app/flatpak-builtins-uninstall.c:264
#, fuzzy
msgid "Must specify at least one REF, --unused, --all or --delete-data"
msgstr "Es muss zumindest eine REFERENZ angegeben werden"

#: app/flatpak-builtins-uninstall.c:267
msgid "Must not specify REFs when using --all"
msgstr ""

#: app/flatpak-builtins-uninstall.c:270
msgid "Must not specify REFs when using --unused"
msgstr ""

#: app/flatpak-builtins-uninstall.c:336
#, c-format
msgid ""
"\n"
"These runtimes in installation '%s' are pinned and won't be removed; see "
"flatpak-pin(1):\n"
msgstr ""

#: app/flatpak-builtins-uninstall.c:370
#, c-format
msgid "Nothing unused to uninstall\n"
msgstr ""

#: app/flatpak-builtins-uninstall.c:444
#, c-format
msgid "No installed refs found for ‘%s’"
msgstr ""

#: app/flatpak-builtins-uninstall.c:447
#, c-format
msgid " with arch ‘%s’"
msgstr ""

#: app/flatpak-builtins-uninstall.c:449
#, c-format
msgid " with branch ‘%s’"
msgstr ""

#: app/flatpak-builtins-uninstall.c:456
#, c-format
msgid "Warning: %s is not installed\n"
msgstr "Warnung: %s ist nicht installiert\n"

#: app/flatpak-builtins-uninstall.c:490
#, c-format
msgid "None of the specified refs are installed"
msgstr ""

#: app/flatpak-builtins-uninstall.c:599
#, c-format
msgid "No app data to delete\n"
msgstr ""

#: app/flatpak-builtins-update.c:56
msgid "Arch to update for"
msgstr "Architektur für Aktualisierung"

#: app/flatpak-builtins-update.c:57
msgid "Commit to deploy"
msgstr "Bereitzustellender Commit"

#: app/flatpak-builtins-update.c:58
msgid "Remove old files even if running"
msgstr "Alte Dateien entfernen, selbst wenn sie in Verwendung sind"

# Alternative: Nicht herunterziehen, …
#: app/flatpak-builtins-update.c:59
msgid "Don't pull, only update from local cache"
msgstr ""
"Keinen »Pull« ausführen, nur aus lokalem Zwischenspeicher aktualisieren"

#: app/flatpak-builtins-update.c:61
msgid "Don't update related refs"
msgstr "Zugehörige Referenzen nicht aktualisieren"

#: app/flatpak-builtins-update.c:66
msgid "Update appstream for remote"
msgstr "Appstream für Gegenstelle aktualisieren"

#: app/flatpak-builtins-update.c:67
msgid "Only update this subpath"
msgstr "Nur diesen Unterpfad aktualisieren"

#: app/flatpak-builtins-update.c:90
msgid "[REF…] - Update applications or runtimes"
msgstr "[REF…] - Anwendungen oder Laufzeitumgebungen aktualisieren"

#: app/flatpak-builtins-update.c:121
#, fuzzy
msgid "With --commit, only one REF may be specified"
msgstr "FERNE QUELLE und REFERENZ muss angegeben werden"

#: app/flatpak-builtins-update.c:162
#, c-format
msgid "Looking for updates…\n"
msgstr "Suche nach Aktualisierungen …\n"

#: app/flatpak-builtins-update.c:215
#, c-format
msgid "Unable to update %s: %s\n"
msgstr ""

#: app/flatpak-builtins-update.c:274
#, fuzzy, c-format
msgid "Nothing to update.\n"
msgstr "Nichts zu tun.\n"

#: app/flatpak-builtins-utils.c:337
#, c-format
msgid ""
"Remote ‘%s’ found in multiple installations, unable to proceed in non-"
"interactive mode"
msgstr ""

#: app/flatpak-builtins-utils.c:346
#, c-format
msgid "Remote ‘%s’ found in multiple installations:"
msgstr ""

#: app/flatpak-builtins-utils.c:347 app/flatpak-builtins-utils.c:442
#: app/flatpak-builtins-utils.c:538 app/flatpak-builtins-utils.c:540
#: app/flatpak-builtins-utils.c:598
#, fuzzy
msgid "Which do you want to use (0 to abort)?"
msgstr "Was wollen Sie installieren (0 zum Abbrechen)?"

#: app/flatpak-builtins-utils.c:349
#, c-format
msgid "No remote chosen to resolve ‘%s’ which exists in multiple installations"
msgstr ""

#: app/flatpak-builtins-utils.c:358
#, c-format
msgid ""
"Remote \"%s\" not found\n"
"Hint: Use flatpak remote-add to add a remote"
msgstr ""

#: app/flatpak-builtins-utils.c:364
#, fuzzy, c-format
msgid "Remote \"%s\" not found in the %s installation"
msgstr "Benutzerinstallationen bearbeiten"

#: app/flatpak-builtins-utils.c:404
#, c-format
msgid "Multiple refs match ‘%s’, unable to proceed in non-interactive mode"
msgstr ""

#. default to yes on Enter
#: app/flatpak-builtins-utils.c:430
#, c-format
msgid ""
"Found ref ‘%s’ in remote ‘%s’ (%s).\n"
"Use this ref?"
msgstr ""

#: app/flatpak-builtins-utils.c:434 app/flatpak-builtins-utils.c:444
#: app/flatpak-builtins-utils.c:522 app/flatpak-builtins-utils.c:543
#, c-format
msgid "No ref chosen to resolve matches for ‘%s’"
msgstr ""

#: app/flatpak-builtins-utils.c:440
#, c-format
msgid "Similar refs found for ‘%s’ in remote ‘%s’ (%s):"
msgstr ""

#: app/flatpak-builtins-utils.c:488
#, c-format
msgid ""
"Multiple installed refs match ‘%s’, unable to proceed in non-interactive mode"
msgstr ""

#. default to yes on Enter
#: app/flatpak-builtins-utils.c:518
#, c-format
msgid "Found installed ref ‘%s’ (%s). Is this correct?"
msgstr ""

#: app/flatpak-builtins-utils.c:534
#, c-format
msgid "All of the above"
msgstr ""

#: app/flatpak-builtins-utils.c:535
#, c-format
msgid "Similar installed refs found for ‘%s’:"
msgstr ""

#: app/flatpak-builtins-utils.c:579
#, c-format
msgid ""
"Multiple remotes have refs matching ‘%s’, unable to proceed in non-"
"interactive mode"
msgstr ""

#: app/flatpak-builtins-utils.c:597
#, c-format
msgid "Remotes found with refs similar to ‘%s’:"
msgstr ""

#: app/flatpak-builtins-utils.c:600
#, c-format
msgid "No remote chosen to resolve matches for ‘%s’"
msgstr ""

#: app/flatpak-builtins-utils.c:696 app/flatpak-builtins-utils.c:699
#, c-format
msgid "Updating appstream data for user remote %s"
msgstr "Appstream-Daten für Benutzer-Gegenstelle %s werden aktualisiert"

#: app/flatpak-builtins-utils.c:706 app/flatpak-builtins-utils.c:709
#, c-format
msgid "Updating appstream data for remote %s"
msgstr "Appstream-Daten für Gegenstelle %s werden aktualisiert"

#: app/flatpak-builtins-utils.c:717 app/flatpak-builtins-utils.c:719
msgid "Error updating"
msgstr "Fehler beim Aktualisieren"

#: app/flatpak-builtins-utils.c:755
#, c-format
msgid "Remote \"%s\" not found"
msgstr ""

#: app/flatpak-builtins-utils.c:796
#, c-format
msgid "Ambiguous suffix: '%s'."
msgstr ""

#. Translators: don't translate the values
#: app/flatpak-builtins-utils.c:798 app/flatpak-builtins-utils.c:813
msgid "Possible values are :s[tart], :m[iddle], :e[nd] or :f[ull]"
msgstr ""

#: app/flatpak-builtins-utils.c:811
#, c-format
msgid "Invalid suffix: '%s'."
msgstr ""

#: app/flatpak-builtins-utils.c:846
#, c-format
msgid "Ambiguous column: %s"
msgstr "Mehrdeutige Spalte: %s"

#: app/flatpak-builtins-utils.c:859
#, c-format
msgid "Unknown column: %s"
msgstr "Unbekannte Spalte: %s"

#: app/flatpak-builtins-utils.c:917
msgid "Available columns:\n"
msgstr "Verfügbare Spalten:\n"

#: app/flatpak-builtins-utils.c:927
msgid "Show all columns"
msgstr "Alle Spalten anzeigen"

#: app/flatpak-builtins-utils.c:928
msgid "Show available columns"
msgstr "Verfügbare Spalten anzeigen"

#: app/flatpak-builtins-utils.c:931
msgid "Append :s[tart], :m[iddle], :e[nd] or :f[ull] to change ellipsization"
msgstr ""

#: app/flatpak-builtins-utils.c:1483
#, c-format
msgid "Unknown scheme in sideload location %s"
msgstr ""

#: app/flatpak-cli-transaction.c:96 app/flatpak-cli-transaction.c:102
#, c-format
msgid "Required runtime for %s (%s) found in remote %s\n"
msgstr ""

#: app/flatpak-cli-transaction.c:104
msgid "Do you want to install it?"
msgstr "Möchten Sie es installieren?"

#: app/flatpak-cli-transaction.c:110
#, c-format
msgid "Required runtime for %s (%s) found in remotes:"
msgstr ""

#: app/flatpak-cli-transaction.c:112
msgid "Which do you want to install (0 to abort)?"
msgstr "Was wollen Sie installieren (0 zum Abbrechen)?"

#: app/flatpak-cli-transaction.c:132
#, fuzzy, c-format
msgid "Configuring %s as new remote '%s'\n"
msgstr "%s wird als neue ferne Quelle »%s« eingerichtet"

#. default to yes on Enter
#: app/flatpak-cli-transaction.c:139
#, fuzzy, c-format
msgid ""
"The remote '%s', referred to by '%s' at location %s contains additional "
"applications.\n"
"Should the remote be kept for future installations?"
msgstr ""
"Die entfernte Quelle »%s« in %s enthält zusätzliche Anwendungen.\n"
"Wollen Sie weitere Anwendungen von dort installieren?"

#. default to yes on Enter
#: app/flatpak-cli-transaction.c:147
#, fuzzy, c-format
msgid ""
"The application %s depends on runtimes from:\n"
"  %s\n"
"Configure this as new remote '%s'"
msgstr ""
"Diese Anwendung ist abhängig von Laufzeiten von:\n"
"  %s\n"
"Richten Sie diese als neue entfernte Quelle »%s« ein"

#. Formatted size/remaining time in seconds
#: app/flatpak-cli-transaction.c:321
#, c-format
msgid "%s/s%s%s"
msgstr ""

#. Download progress percentage, use the appropriate
#. percent format for your language
#: app/flatpak-cli-transaction.c:359
#, c-format
msgid "%3d%%"
msgstr ""

#: app/flatpak-cli-transaction.c:414
msgid "Installing…"
msgstr "Wird installiert …"

#: app/flatpak-cli-transaction.c:416
#, c-format
msgid "Installing %d/%d…"
msgstr "Installiere %d/%d …"

#: app/flatpak-cli-transaction.c:421
msgid "Updating…"
msgstr "Wird aktualisiert …"

#: app/flatpak-cli-transaction.c:423
#, c-format
msgid "Updating %d/%d…"
msgstr "Aktualisiere %d/%d …"

#: app/flatpak-cli-transaction.c:428
msgid "Uninstalling…"
msgstr "Wird deinstalliert …"

#: app/flatpak-cli-transaction.c:430
#, c-format
msgid "Uninstalling %d/%d…"
msgstr "Deinstalliere %d/%d …"

#: app/flatpak-cli-transaction.c:496 app/flatpak-quiet-transaction.c:161
#, c-format
msgid "Info: %s was skipped"
msgstr "Info: %s wurde übersprungen"

#: app/flatpak-cli-transaction.c:519
#, fuzzy, c-format
msgid "Warning: %s%s%s already installed"
msgstr "%s bereits installiert"

#: app/flatpak-cli-transaction.c:522
#, fuzzy, c-format
msgid "Error: %s%s%s already installed"
msgstr "%s bereits installiert"

#: app/flatpak-cli-transaction.c:528
#, fuzzy, c-format
msgid "Warning: %s%s%s not installed"
msgstr "Warnung: %s ist nicht installiert\n"

#: app/flatpak-cli-transaction.c:531
#, fuzzy, c-format
msgid "Error: %s%s%s not installed"
msgstr "%s/%s/%s nicht installiert"

#: app/flatpak-cli-transaction.c:537
#, fuzzy, c-format
msgid "Warning: %s%s%s needs a later flatpak version"
msgstr "%s benötigt eine neuere Flatpak-Version"

#: app/flatpak-cli-transaction.c:540
#, fuzzy, c-format
msgid "Error: %s%s%s needs a later flatpak version"
msgstr "%s benötigt eine neuere Flatpak-Version"

#: app/flatpak-cli-transaction.c:546
#, fuzzy
msgid "Warning: Not enough disk space to complete this operation"
msgstr "Nicht genügend Festplattenplatz, um diesen Vorgang abzuschließen"

#: app/flatpak-cli-transaction.c:548
#, fuzzy
msgid "Error: Not enough disk space to complete this operation"
msgstr "Nicht genügend Festplattenplatz, um diesen Vorgang abzuschließen"

#: app/flatpak-cli-transaction.c:553
#, fuzzy, c-format
msgid "Warning: %s"
msgstr "Warnung: "

#: app/flatpak-cli-transaction.c:555
#, fuzzy, c-format
msgid "Error: %s"
msgstr "Fehler:"

#: app/flatpak-cli-transaction.c:570
#, fuzzy, c-format
msgid "Failed to install %s%s%s: "
msgstr "Commit %s konnte nicht gelesen werden: "

#: app/flatpak-cli-transaction.c:577
#, fuzzy, c-format
msgid "Failed to update %s%s%s: "
msgstr "Commit %s konnte nicht gelesen werden: "

#: app/flatpak-cli-transaction.c:584
#, fuzzy, c-format
msgid "Failed to install bundle %s%s%s: "
msgstr "Erstellung des Delta %s (%.10s-%.10s) fehlgeschlagen: "

#: app/flatpak-cli-transaction.c:591
#, fuzzy, c-format
msgid "Failed to uninstall %s%s%s: "
msgstr "Commit %s konnte nicht gelesen werden: "

#: app/flatpak-cli-transaction.c:642
#, c-format
msgid "Authentication required for remote '%s'\n"
msgstr ""

#: app/flatpak-cli-transaction.c:643
msgid "Open browser?"
msgstr "Browser öffnen?"

#: app/flatpak-cli-transaction.c:699
#, c-format
msgid "Login required remote %s (realm %s)\n"
msgstr ""

#: app/flatpak-cli-transaction.c:704
msgid "Password"
msgstr "Passwort"

#. Only runtimes can be pinned
#: app/flatpak-cli-transaction.c:759
#, c-format
msgid ""
"\n"
"Info: (pinned) runtime %s%s%s branch %s%s%s is end-of-life, in favor of "
"%s%s%s branch %s%s%s\n"
msgstr ""

#: app/flatpak-cli-transaction.c:765
#, c-format
msgid ""
"\n"
"Info: runtime %s%s%s branch %s%s%s is end-of-life, in favor of %s%s%s branch "
"%s%s%s\n"
msgstr ""

#: app/flatpak-cli-transaction.c:768
#, c-format
msgid ""
"\n"
"Info: app %s%s%s branch %s%s%s is end-of-life, in favor of %s%s%s branch "
"%s%s%s\n"
msgstr ""

#. Only runtimes can be pinned
#: app/flatpak-cli-transaction.c:780
#, c-format
msgid ""
"\n"
"Info: (pinned) runtime %s%s%s branch %s%s%s is end-of-life, with reason:\n"
msgstr ""

#: app/flatpak-cli-transaction.c:786
#, c-format
msgid ""
"\n"
"Info: runtime %s%s%s branch %s%s%s is end-of-life, with reason:\n"
msgstr ""

#: app/flatpak-cli-transaction.c:789
#, c-format
msgid ""
"\n"
"Info: app %s%s%s branch %s%s%s is end-of-life, with reason:\n"
msgstr ""

#: app/flatpak-cli-transaction.c:963
#, fuzzy, c-format
msgid "Info: applications using this extension:\n"
msgstr "Anwendungen, die diese Laufzeitumgebung verwenden:\n"

#: app/flatpak-cli-transaction.c:965
#, fuzzy, c-format
msgid "Info: applications using this runtime:\n"
msgstr "Anwendungen, die diese Laufzeitumgebung verwenden:\n"

#: app/flatpak-cli-transaction.c:984
msgid "Replace?"
msgstr "Ersetzen?"

#: app/flatpak-cli-transaction.c:987 app/flatpak-quiet-transaction.c:247
#, c-format
msgid "Updating to rebased version\n"
msgstr ""

#: app/flatpak-cli-transaction.c:1011
#, c-format
msgid "Failed to rebase %s to %s: "
msgstr ""

#: app/flatpak-cli-transaction.c:1277
#, c-format
msgid "New %s%s%s permissions:"
msgstr "Neue %s%s%s Berechtigungen:"

#: app/flatpak-cli-transaction.c:1279
#, c-format
msgid "%s%s%s permissions:"
msgstr "%s%s%s Berechtigungen:"

#: app/flatpak-cli-transaction.c:1343
msgid "Warning: "
msgstr "Warnung: "

#. translators: This is short for operation, the title of a one-char column
#: app/flatpak-cli-transaction.c:1442
msgid "Op"
msgstr ""

#. Avoid resizing the download column too much,
#. * by making the title as long as typical content
#.
#: app/flatpak-cli-transaction.c:1458 app/flatpak-cli-transaction.c:1503
msgid "partial"
msgstr "teilweise"

#: app/flatpak-cli-transaction.c:1535
msgid "Proceed with these changes to the user installation?"
msgstr "Mit diesen Änderungen an der Benutzerinstallation fortfahren?"

#: app/flatpak-cli-transaction.c:1537
msgid "Proceed with these changes to the system installation?"
msgstr "Mit diesen Änderungen an der Systeminstallation fortfahren?"

#: app/flatpak-cli-transaction.c:1539
#, c-format
msgid "Proceed with these changes to the %s?"
msgstr "Mit diesen Änderungen an %s fortfahren?"

#: app/flatpak-cli-transaction.c:1711
msgid "Changes complete."
msgstr "Änderungen abgeschlossen."

#: app/flatpak-cli-transaction.c:1713
msgid "Uninstall complete."
msgstr "Deinstallation abgeschlossen."

#: app/flatpak-cli-transaction.c:1715
msgid "Installation complete."
msgstr "Installation abgeschlossen."

#: app/flatpak-cli-transaction.c:1717
msgid "Updates complete."
msgstr "Aktualisierungen abgeschlossen."

#. For updates/!stop_on_first_error we already printed all errors so we make up
#. a different one.
#: app/flatpak-cli-transaction.c:1750
msgid "There were one or more errors"
msgstr "Es gab einen oder mehrere Fehler"

#. translators: please keep the leading space
#: app/flatpak-main.c:76
msgid " Manage installed applications and runtimes"
msgstr " Installierte Anwendungen und Laufzeitumgebungen verwalten"

#: app/flatpak-main.c:77
msgid "Install an application or runtime"
msgstr "Eine Anwendung oder Laufzeitumgebung installieren"

#: app/flatpak-main.c:78
msgid "Update an installed application or runtime"
msgstr "Eine installierte Anwendung oder Laufzeitumgebung aktualisieren"

#: app/flatpak-main.c:81
msgid "Uninstall an installed application or runtime"
msgstr "Eine installierte Anwendung oder Laufzeitumgebung deinstallieren"

#: app/flatpak-main.c:84
msgid "Mask out updates and automatic installation"
msgstr ""

#: app/flatpak-main.c:85
msgid "Pin a runtime to prevent automatic removal"
msgstr ""

#: app/flatpak-main.c:86
msgid "List installed apps and/or runtimes"
msgstr "Installierte Anwendungen und/oder Laufzeitumgebungen auflisten"

#: app/flatpak-main.c:87
msgid "Show info for installed app or runtime"
msgstr ""
"Informationen zu installierter Anwendung oder Laufzeitumgebungen anzeigen"

#: app/flatpak-main.c:88
msgid "Show history"
msgstr "Verlauf anzeigen"

#: app/flatpak-main.c:89
msgid "Configure flatpak"
msgstr "Flatpak einrichten"

#: app/flatpak-main.c:90
msgid "Repair flatpak installation"
msgstr "Flatpak-Installation reparieren"

#: app/flatpak-main.c:91
msgid "Put applications or runtimes onto removable media"
msgstr ""

#: app/flatpak-main.c:92
msgid "Install flatpaks that are part of the operating system"
msgstr ""

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:95
msgid ""
"\n"
" Find applications and runtimes"
msgstr ""
"\n"
" Anwendungen und Laufzeitumgebungen finden"

#: app/flatpak-main.c:96
msgid "Search for remote apps/runtimes"
msgstr ""

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:99
msgid ""
"\n"
" Manage running applications"
msgstr ""
"\n"
" Laufende Anwendungen verwalten"

#: app/flatpak-main.c:100
msgid "Run an application"
msgstr "Eine Anwendung ausführen"

#: app/flatpak-main.c:101
msgid "Override permissions for an application"
msgstr "Berechtigungen für eine Anwendung ersetzen"

#: app/flatpak-main.c:102
msgid "Specify default version to run"
msgstr "Die als Standard auszuführende Version angeben"

#: app/flatpak-main.c:103
msgid "Enter the namespace of a running application"
msgstr "In den Namensraum einer laufenden Anwendung wechseln"

#: app/flatpak-main.c:104
msgid "Enumerate running applications"
msgstr "Laufende Anwendungen nummerieren"

#: app/flatpak-main.c:105
msgid "Stop a running application"
msgstr "Stoppen einer laufenden Anwendung"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:108
msgid ""
"\n"
" Manage file access"
msgstr ""
"\n"
" Dateizugriff verwalten"

#: app/flatpak-main.c:109
msgid "List exported files"
msgstr "Exportierte Dateien auflisten"

#: app/flatpak-main.c:110
msgid "Grant an application access to a specific file"
msgstr "Einer Anwendung den Zugriff auf eine bestimmte Datei gewähren"

#: app/flatpak-main.c:111
msgid "Revoke access to a specific file"
msgstr "Den Zugriff auf eine bestimmte Datei widerrufen"

#: app/flatpak-main.c:112
msgid "Show information about a specific file"
msgstr "Informationen zu einer bestimmten Datei anzeigen"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:116
msgid ""
"\n"
" Manage dynamic permissions"
msgstr ""

#: app/flatpak-main.c:117
msgid "List permissions"
msgstr "Berechtigungen auflisten"

#: app/flatpak-main.c:118
msgid "Remove item from permission store"
msgstr "Element aus dem Berechtigungsspeicher entfernen"

#: app/flatpak-main.c:120
msgid "Set permissions"
msgstr "Berechtigungen festlegen"

#: app/flatpak-main.c:121
msgid "Show app permissions"
msgstr "Anwendungsberechtigungen anzeigen"

#: app/flatpak-main.c:122
msgid "Reset app permissions"
msgstr "Anwendungsberechtigungen zurücksetzen"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:125
msgid ""
"\n"
" Manage remote repositories"
msgstr ""
"\n"
" Quellen der Gegenstelle verwalten"

#: app/flatpak-main.c:126
msgid "List all configured remotes"
msgstr "Alle konfigurierten Gegenstellen auflisten"

#: app/flatpak-main.c:127
msgid "Add a new remote repository (by URL)"
msgstr "Eine neue Gegenstelle hinzufügen (mittels Adresse)"

#: app/flatpak-main.c:128
msgid "Modify properties of a configured remote"
msgstr "Eigenschaften einer konfigurierten Gegenstelle verändern"

#: app/flatpak-main.c:129
msgid "Delete a configured remote"
msgstr "Eine konfigurierte Gegenstelle löschen"

#: app/flatpak-main.c:131
msgid "List contents of a configured remote"
msgstr "Inhalt einer konfigurierten Gegenstelle auflisten"

#: app/flatpak-main.c:132
msgid "Show information about a remote app or runtime"
msgstr ""
"Informationen über eine entfernte Anwendung oder Laufzeitumgebung anzeigen"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:135
msgid ""
"\n"
" Build applications"
msgstr ""
"\n"
" Anwendungen erstellen"

#: app/flatpak-main.c:136
msgid "Initialize a directory for building"
msgstr "Einen Ordner für die Erstellung initialisieren"

#: app/flatpak-main.c:137
msgid "Run a build command inside the build dir"
msgstr "Einen Erstellungsbefehl innerhalb des Erstellungsordners ausführen"

#: app/flatpak-main.c:138
msgid "Finish a build dir for export"
msgstr "Einen Erstellungsordner für den Export finalisieren"

#: app/flatpak-main.c:139
msgid "Export a build dir to a repository"
msgstr "Erstellungsordner in eine Quelle exportieren"

#: app/flatpak-main.c:140
#, fuzzy
msgid "Create a bundle file from a ref in a local repository"
msgstr "Eine Bündel-Datei aus einem Erstellungsordner erzeugen"

#: app/flatpak-main.c:141
msgid "Import a bundle file"
msgstr "Eine Bündel-Datei importieren"

#: app/flatpak-main.c:142
msgid "Sign an application or runtime"
msgstr "Eine Anwendung oder Laufzeitumgebung signieren"

#: app/flatpak-main.c:143
msgid "Update the summary file in a repository"
msgstr "Zusammenfassungsdatei in einer Quelle aktualisieren"

#: app/flatpak-main.c:144
msgid "Create new commit based on existing ref"
msgstr "Neuen Commit basierend auf existierendem Ref erstellen"

#: app/flatpak-main.c:145
msgid "Show information about a repo"
msgstr "Informationen über eine Quelle anzeigen"

#: app/flatpak-main.c:162
#, fuzzy
msgid "Show debug information, -vv for more detail"
msgstr ""
"Fehlerdiagnoseinformationen während der Befehlsverarbeitung ausgeben, -vv "
"für mehr Details"

#: app/flatpak-main.c:163
msgid "Show OSTree debug information"
msgstr "OSTree-Fehlersuchinformationen anzeigen"

#: app/flatpak-main.c:169
msgid "Print version information and exit"
msgstr "Versionsinformationen ausgeben und beenden"

#: app/flatpak-main.c:170
msgid "Print default arch and exit"
msgstr "Standard-Architektur ausgeben und beenden"

#: app/flatpak-main.c:171
msgid "Print supported arches and exit"
msgstr "Unterstützte Architekturen ausgeben und beenden"

#: app/flatpak-main.c:172
msgid "Print active gl drivers and exit"
msgstr "Aktiven GL-Treiber ausgeben und beenden"

#: app/flatpak-main.c:173
msgid "Print paths for system installations and exit"
msgstr "Pfade für Systeminstallationen ausgeben und beenden"

#: app/flatpak-main.c:174
msgid "Print the updated environment needed to run flatpaks"
msgstr ""

#: app/flatpak-main.c:175
msgid "Only include the system installation with --print-updated-env"
msgstr ""

#: app/flatpak-main.c:180
msgid "Work on the user installation"
msgstr "An der Benutzerinstallation arbeiten"

#: app/flatpak-main.c:181
msgid "Work on the system-wide installation (default)"
msgstr "An der systemweiten Installation arbeiten (Standard)"

#: app/flatpak-main.c:182
msgid "Work on a non-default system-wide installation"
msgstr "An einer nicht standardmäßigen systemweiten Installation arbeiten"

#: app/flatpak-main.c:212
msgid "Builtin Commands:"
msgstr "Eingebaute Befehle:"

#: app/flatpak-main.c:298
#, c-format
msgid ""
"Note that the directories %s are not in the search path set by the "
"XDG_DATA_DIRS environment variable, so applications installed by Flatpak may "
"not appear on your desktop until the session is restarted."
msgstr ""

#: app/flatpak-main.c:312
#, c-format
msgid ""
"Note that the directory %s is not in the search path set by the "
"XDG_DATA_DIRS environment variable, so applications installed by Flatpak may "
"not appear on your desktop until the session is restarted."
msgstr ""

#: app/flatpak-main.c:381
msgid ""
"Refusing to operate under sudo with --user. Omit sudo to operate on the user "
"installation, or use a root shell to operate on the root user's installation."
msgstr ""

#: app/flatpak-main.c:453
msgid ""
"Multiple installations specified for a command that works on one installation"
msgstr ""

#: app/flatpak-main.c:504 app/flatpak-main.c:697
#, c-format
msgid "See '%s --help'"
msgstr ""

#: app/flatpak-main.c:706
#, c-format
msgid "'%s' is not a flatpak command. Did you mean '%s%s'?"
msgstr "»%s« ist kein Flatpak-Befehl. Meinten Sie »%s%s«?"

#: app/flatpak-main.c:709
#, c-format
msgid "'%s' is not a flatpak command"
msgstr ""

#: app/flatpak-main.c:824
msgid "No command specified"
msgstr "Kein Befehl angegeben"

#: app/flatpak-main.c:980
msgid "error:"
msgstr "Fehler:"

#: app/flatpak-quiet-transaction.c:77
#, c-format
msgid "Installing %s\n"
msgstr "%s wird installiert\n"

#: app/flatpak-quiet-transaction.c:81
#, c-format
msgid "Updating %s\n"
msgstr "%s wird aktualisiert\n"

#: app/flatpak-quiet-transaction.c:85
#, c-format
msgid "Uninstalling %s\n"
msgstr "%s wird deinstalliert\n"

#: app/flatpak-quiet-transaction.c:107
#, fuzzy, c-format
msgid "Warning: Failed to install %s: %s\n"
msgstr "Warnung:  %s %s fehlgeschlagen: %s\n"

#: app/flatpak-quiet-transaction.c:110
#, fuzzy, c-format
msgid "Error: Failed to install %s: %s\n"
msgstr "Fehler: %s %s ist fehlgeschlagen: %s\n"

#: app/flatpak-quiet-transaction.c:116
#, fuzzy, c-format
msgid "Warning: Failed to update %s: %s\n"
msgstr "Warnung:  %s %s fehlgeschlagen: %s\n"

#: app/flatpak-quiet-transaction.c:119
#, fuzzy, c-format
msgid "Error: Failed to update %s: %s\n"
msgstr "Fehler: %s %s ist fehlgeschlagen: %s\n"

#: app/flatpak-quiet-transaction.c:125
#, fuzzy, c-format
msgid "Warning: Failed to install bundle %s: %s\n"
msgstr "Warnung:  %s %s fehlgeschlagen: %s\n"

#: app/flatpak-quiet-transaction.c:128
#, fuzzy, c-format
msgid "Error: Failed to install bundle %s: %s\n"
msgstr "Fehler: %s %s ist fehlgeschlagen: %s\n"

#: app/flatpak-quiet-transaction.c:134
#, fuzzy, c-format
msgid "Warning: Failed to uninstall %s: %s\n"
msgstr "Warnung:  %s %s fehlgeschlagen: %s\n"

#: app/flatpak-quiet-transaction.c:137
#, fuzzy, c-format
msgid "Error: Failed to uninstall %s: %s\n"
msgstr "Fehler: %s %s ist fehlgeschlagen: %s\n"

#: app/flatpak-quiet-transaction.c:166 common/flatpak-dir.c:11475
#, c-format
msgid "%s already installed"
msgstr "%s bereits installiert"

#: app/flatpak-quiet-transaction.c:168 common/flatpak-dir.c:3622
#: common/flatpak-dir.c:4321 common/flatpak-dir.c:16968
#: common/flatpak-dir.c:17258 common/flatpak-dir-utils.c:166
#: common/flatpak-dir-utils.c:259 common/flatpak-transaction.c:2736
#: common/flatpak-transaction.c:2791
#, c-format
msgid "%s not installed"
msgstr "%s ist nicht installiert"

#: app/flatpak-quiet-transaction.c:170
#, c-format
msgid "%s needs a later flatpak version"
msgstr "%s benötigt eine neuere Flatpak-Version"

#: app/flatpak-quiet-transaction.c:172
msgid "Not enough disk space to complete this operation"
msgstr "Nicht genügend Festplattenplatz, um diesen Vorgang abzuschließen"

#: app/flatpak-quiet-transaction.c:239
#, c-format
msgid "Info: %s is end-of-life, in favor of %s\n"
msgstr ""

#: app/flatpak-quiet-transaction.c:241
#, c-format
msgid "Info: %s is end-of-life, with reason: %s\n"
msgstr ""

#: app/flatpak-quiet-transaction.c:251
#, c-format
msgid "Failed to rebase %s to %s: %s\n"
msgstr ""

#: common/flatpak-auth.c:58
#, c-format
msgid "No authenticator configured for remote `%s`"
msgstr ""

#: common/flatpak-context.c:637 common/flatpak-context.c:649
#, fuzzy, c-format
msgid "Invalid permission syntax: %s"
msgstr "Ungültiger Erweiterungsname %s"

#: common/flatpak-context.c:1207
#, c-format
msgid "Unknown share type %s, valid types are: %s"
msgstr "Unbekannter Freigabetyp %s, zulässige Typen sind: %s"

#: common/flatpak-context.c:1228
#, c-format
msgid "Unknown policy type %s, valid types are: %s"
msgstr "Unbekannter Regeltyp %s, zulässige Typen sind: %s"

#: common/flatpak-context.c:1266
#, c-format
msgid "Invalid dbus name %s"
msgstr "Ungültiger dbus-Name %s"

#: common/flatpak-context.c:1279
#, c-format
msgid "Unknown socket type %s, valid types are: %s"
msgstr "Unbekannter Socket-Typ %s, zulässige Typen sind: %s"

#: common/flatpak-context.c:1294
#, c-format
msgid "Unknown device type %s, valid types are: %s"
msgstr "Unbekannter Gerätetyp %s, zulässige Typen sind: %s"

#: common/flatpak-context.c:1308
#, c-format
msgid "Unknown feature type %s, valid types are: %s"
msgstr "Unbekannter Funktionstyp %s, zulässige Typen sind: %s"

#: common/flatpak-context.c:1840
#, c-format
msgid "Filesystem location \"%s\" contains \"..\""
msgstr ""

#: common/flatpak-context.c:1882
#, c-format
msgid ""
"--filesystem=/ is not available, use --filesystem=host for a similar result"
msgstr ""

#: common/flatpak-context.c:1916
#, fuzzy, c-format
msgid ""
"Unknown filesystem location %s, valid locations are: host, host-os, host-"
"etc, host-root, home, xdg-*[/…], ~/dir, /dir"
msgstr ""
"Unbekannter Dateisystem-Ort %s, zulässige Orte sind: host, home, xdg-"
"*[/...], ~/Ordner, /Ordner"

#: common/flatpak-context.c:2015
#, fuzzy, c-format
msgid "Invalid syntax for %s: %s"
msgstr "Ungültiger Name %s: %s"

#: common/flatpak-context.c:2142
#, c-format
msgid "fallback-x11 can not be conditional"
msgstr ""

#: common/flatpak-context.c:2318
#, c-format
msgid "Invalid env format %s"
msgstr "Ungültiges Umgebungsformat: %s"

#: common/flatpak-context.c:2399
#, c-format
msgid "Environment variable name must not contain '=': %s"
msgstr ""

#: common/flatpak-context.c:2527 common/flatpak-context.c:2535
#, c-format
msgid "--add-policy arguments must be in the form SUBSYSTEM.KEY=VALUE"
msgstr ""

#: common/flatpak-context.c:2542
#, c-format
msgid "--add-policy values can't start with \"!\""
msgstr ""

#: common/flatpak-context.c:2567 common/flatpak-context.c:2575
#, c-format
msgid "--remove-policy arguments must be in the form SUBSYSTEM.KEY=VALUE"
msgstr ""

#: common/flatpak-context.c:2582
#, c-format
msgid "--remove-policy values can't start with \"!\""
msgstr ""

#: common/flatpak-context.c:2657
msgid "Share with host"
msgstr "Mit Rechner teilen"

#: common/flatpak-context.c:2657 common/flatpak-context.c:2658
msgid "SHARE"
msgstr "FREIGABE"

#: common/flatpak-context.c:2658
msgid "Unshare with host"
msgstr "Freigabe für Rechner aufheben"

#: common/flatpak-context.c:2659
msgid "Require conditions to be met for a subsystem to get shared"
msgstr ""

#: common/flatpak-context.c:2659
msgid "SHARE:CONDITION"
msgstr ""

#: common/flatpak-context.c:2660
msgid "Expose socket to app"
msgstr "Socket für die Anwendung sichtbar machen"

#: common/flatpak-context.c:2660 common/flatpak-context.c:2661
msgid "SOCKET"
msgstr "SOCKET"

#: common/flatpak-context.c:2661
msgid "Don't expose socket to app"
msgstr "Socket vor der Anwendung verbergen"

#: common/flatpak-context.c:2662
msgid "Require conditions to be met for a socket to get exposed"
msgstr ""

#: common/flatpak-context.c:2662
msgid "SOCKET:CONDITION"
msgstr ""

#: common/flatpak-context.c:2663
msgid "Expose device to app"
msgstr "Gerät für die Anwendung sichtbar machen"

#: common/flatpak-context.c:2663 common/flatpak-context.c:2664
msgid "DEVICE"
msgstr "GERÄT"

#: common/flatpak-context.c:2664
msgid "Don't expose device to app"
msgstr "Gerät vor der Anwendung verbergen"

#: common/flatpak-context.c:2665
msgid "Require conditions to be met for a device to get exposed"
msgstr ""

#: common/flatpak-context.c:2665
msgid "DEVICE:CONDITION"
msgstr ""

#: common/flatpak-context.c:2666
msgid "Allow feature"
msgstr "Funktion erlauben"

#: common/flatpak-context.c:2666 common/flatpak-context.c:2667
msgid "FEATURE"
msgstr "FUNKTION"

#: common/flatpak-context.c:2667
msgid "Don't allow feature"
msgstr "Funktion nicht erlauben"

#: common/flatpak-context.c:2668
msgid "Require conditions to be met for a feature to get allowed"
msgstr ""

#: common/flatpak-context.c:2668
msgid "FEATURE:CONDITION"
msgstr ""

#: common/flatpak-context.c:2669
msgid "Expose filesystem to app (:ro for read-only)"
msgstr ""
"Das Dateisystem für die Anwendung sichtbar machen (:ro für schreibgeschützt)"

#: common/flatpak-context.c:2669
msgid "FILESYSTEM[:ro]"
msgstr "DATEISYSTEM[:ro]"

#: common/flatpak-context.c:2670
msgid "Don't expose filesystem to app"
msgstr "Das Dateisystem vor der Anwendung verbergen"

#: common/flatpak-context.c:2670
msgid "FILESYSTEM"
msgstr "DATEISYSTEM"

#: common/flatpak-context.c:2671
msgid "Set environment variable"
msgstr "Umgebungsvariable festlegen"

#: common/flatpak-context.c:2671
msgid "VAR=VALUE"
msgstr "VAR=WERT"

#: common/flatpak-context.c:2672
msgid "Read environment variables in env -0 format from FD"
msgstr ""

#: common/flatpak-context.c:2673
msgid "Remove variable from environment"
msgstr "Variable aus der Umgebung entfernen"

#: common/flatpak-context.c:2673
msgid "VAR"
msgstr "VAR"

#: common/flatpak-context.c:2674
msgid "Allow app to own name on the session bus"
msgstr ""
"Der Anwendung erlauben, einen Namen auf dem Sitzungsbus zu beanspruchen"

#: common/flatpak-context.c:2674 common/flatpak-context.c:2675
#: common/flatpak-context.c:2676 common/flatpak-context.c:2677
#: common/flatpak-context.c:2678 common/flatpak-context.c:2679
#: common/flatpak-context.c:2680
msgid "DBUS_NAME"
msgstr "DBUS_NAME"

#: common/flatpak-context.c:2675
msgid "Allow app to talk to name on the session bus"
msgstr "Der Anwendung erlauben, mit Namen auf dem Sitzungsbus zu kommunizieren"

#: common/flatpak-context.c:2676
#, fuzzy
msgid "Don't allow app to talk to name on the session bus"
msgstr "Der Anwendung erlauben, mit Namen auf dem Sitzungsbus zu kommunizieren"

#: common/flatpak-context.c:2677
msgid "Allow app to own name on the system bus"
msgstr ""
"Der Anwendung erlauben, einen Namen auf dem Sitzungsbus zu beanspruchen"

#: common/flatpak-context.c:2678
msgid "Allow app to talk to name on the system bus"
msgstr "Der Anwendung erlauben, mit Namen auf dem Systembus zu kommunizieren"

#: common/flatpak-context.c:2679
#, fuzzy
msgid "Don't allow app to talk to name on the system bus"
msgstr "Der Anwendung erlauben, mit Namen auf dem Systembus zu kommunizieren"

#: common/flatpak-context.c:2680
#, fuzzy
msgid "Allow app to own name on the a11y bus"
msgstr ""
"Der Anwendung erlauben, einen Namen auf dem Sitzungsbus zu beanspruchen"

#: common/flatpak-context.c:2681
msgid "Add generic policy option"
msgstr "Allgemeine Richtlinien-Einstellungen hinzufügen"

#: common/flatpak-context.c:2681 common/flatpak-context.c:2682
msgid "SUBSYSTEM.KEY=VALUE"
msgstr "SUBSYSTEM.SCHLÜSSEL=WERT"

#: common/flatpak-context.c:2682
msgid "Remove generic policy option"
msgstr "Allgemeine Richtlinien-Einstellungen entfernen"

#: common/flatpak-context.c:2683
msgid "Add USB device to enumerables"
msgstr ""

#: common/flatpak-context.c:2683 common/flatpak-context.c:2684
msgid "VENDOR_ID:PRODUCT_ID"
msgstr ""

#: common/flatpak-context.c:2684
msgid "Add USB device to hidden list"
msgstr ""

#: common/flatpak-context.c:2685
msgid "A list of USB devices that are enumerable"
msgstr ""

#: common/flatpak-context.c:2685
msgid "LIST"
msgstr ""

#: common/flatpak-context.c:2686
msgid "File containing a list of USB devices to make enumerable"
msgstr ""

#: common/flatpak-context.c:2686 common/flatpak-context.c:2687
msgid "FILENAME"
msgstr "DATEINAME"

#: common/flatpak-context.c:2687
#, fuzzy
msgid "Persist home directory subpath"
msgstr "Basisordner beständig machen"

#. This is not needed/used anymore, so hidden, but we accept it for backwards compat
#: common/flatpak-context.c:2689
msgid "Don't require a running session (no cgroups creation)"
msgstr ""
"Laufende Sitzung als nicht erforderlich festlegen (keine Erstellung von "
"cgroups)"

#: common/flatpak-context.c:3718
#, c-format
msgid "Not replacing \"%s\" with tmpfs: %s"
msgstr ""

#: common/flatpak-context.c:3726
#, c-format
msgid "Not sharing \"%s\" with sandbox: %s"
msgstr ""

#. Even if the error is one that we would normally silence, like
#. * the path not existing, it seems reasonable to make more of a fuss
#. * about the home directory not existing or otherwise being unusable,
#. * so this is intentionally not using cannot_export()
#: common/flatpak-context.c:3828
#, c-format
msgid "Not allowing home directory access: %s"
msgstr ""

#: common/flatpak-context.c:4062
#, fuzzy, c-format
msgid "Unable to provide a temporary home directory in the sandbox: %s"
msgstr "Bereitstellungsordner konnte nicht erstellt werden"

#: common/flatpak-dir.c:442
#, c-format
msgid "Configured collection ID ‘%s’ not in summary file"
msgstr ""

#: common/flatpak-dir.c:587
#, fuzzy, c-format
msgid "Unable to load summary from remote %s: %s"
msgstr "Während des Holens von %s von der entfernten Quelle %s: "

#: common/flatpak-dir.c:764 common/flatpak-dir.c:800 common/flatpak-dir.c:906
#, fuzzy, c-format
msgid "No such ref '%s' in remote %s"
msgstr "%s konnte nicht in entfernter Quelle %s gefunden werden"

#: common/flatpak-dir.c:891 common/flatpak-dir.c:1051 common/flatpak-dir.c:1080
#: common/flatpak-dir.c:1092
#, fuzzy, c-format
msgid "No entry for %s in remote %s summary flatpak cache"
msgstr ""
"Kein Eintrag für %s in Zusammenfassung des entfernten Flatpak-"
"Zwischenspeichers"

#: common/flatpak-dir.c:1069
#, fuzzy, c-format
msgid "No summary or Flatpak cache available for remote %s"
msgstr "Kein Flatpak-Zwischenspeicher in Zusammenfassung entfernter Quelle"

#: common/flatpak-dir.c:1097
#, fuzzy, c-format
msgid "Missing xa.data in summary for remote %s"
msgstr "Kein Flatpak-Zwischenspeicher in Zusammenfassung entfernter Quelle"

#: common/flatpak-dir.c:1103 common/flatpak-dir.c:1546
#, fuzzy, c-format
msgid "Unsupported summary version %d for remote %s"
msgstr "Kein Flatpak-Zwischenspeicher in Zusammenfassung entfernter Quelle"

#: common/flatpak-dir.c:1200
msgid "Remote OCI index has no registry uri"
msgstr ""

#: common/flatpak-dir.c:1261
#, fuzzy, c-format
msgid "Couldn't find ref %s in remote %s"
msgstr "%s konnte nicht in entfernter Quelle %s gefunden werden"

#: common/flatpak-dir.c:1288 common/flatpak-dir.c:1381
#, c-format
msgid "Commit has no requested ref ‘%s’ in ref binding metadata (found: ‘%s’)"
msgstr ""

#: common/flatpak-dir.c:1413
#, c-format
msgid "Configured collection ID ‘%s’ not in binding metadata"
msgstr ""

#: common/flatpak-dir.c:1449 common/flatpak-dir.c:5645
#, fuzzy, c-format
msgid "Couldn't find latest checksum for ref %s in remote %s"
msgstr "%s konnte nicht in entfernter Quelle %s gefunden werden"

#: common/flatpak-dir.c:1516 common/flatpak-dir.c:1552
#, fuzzy, c-format
msgid "No entry for %s in remote %s summary flatpak sparse cache"
msgstr ""
"Kein Eintrag für %s in Zusammenfassung des entfernten Flatpak-"
"Zwischenspeichers"

#: common/flatpak-dir.c:2540
#, c-format
msgid "Commit metadata for %s not matching expected metadata"
msgstr ""

#: common/flatpak-dir.c:2823
#, fuzzy
msgid "Unable to connect to system bus"
msgstr ""
"Der Anwendung erlauben, einen Namen auf dem Sitzungsbus zu beanspruchen"

#: common/flatpak-dir.c:3419
msgid "User installation"
msgstr "Benutzerinstallation"

#: common/flatpak-dir.c:3426
#, c-format
msgid "System (%s) installation"
msgstr "Systeminstallation (%s)"

#: common/flatpak-dir.c:3472
#, c-format
msgid "No overrides found for %s"
msgstr "Keine Ersetzungen für %s gefunden"

#: common/flatpak-dir.c:3625
#, c-format
msgid "%s (commit %s) not installed"
msgstr "%s (Commit %s) nicht installiert"

#: common/flatpak-dir.c:4650
#, fuzzy, c-format
msgid "Error parsing system flatpakrepo file for %s: %s"
msgstr "Fehler beim Aktualisieren der Metadaten für »%s«: %s\n"

#: common/flatpak-dir.c:4735
#, c-format
msgid "While opening repository %s: "
msgstr "Während des Öffnens der Quelle %s: "

#: common/flatpak-dir.c:5004
#, c-format
msgid "The config key %s is not set"
msgstr "Der Konfigurationsschlüssel %s ist nicht festgelegt"

#: common/flatpak-dir.c:5140
#, fuzzy, c-format
msgid "No current %s pattern matching %s"
msgstr "Zugehörige Referenzen nicht aktualisieren"

#: common/flatpak-dir.c:5422
#, fuzzy
msgid "No appstream commit to deploy"
msgstr "Bereitzustellender Commit"

#: common/flatpak-dir.c:5941 common/flatpak-dir.c:7266
#: common/flatpak-dir.c:10881 common/flatpak-dir.c:11618
msgid "Can't pull from untrusted non-gpg verified remote"
msgstr ""

#: common/flatpak-dir.c:6376 common/flatpak-dir.c:6591
msgid "Extra data not supported for non-gpg-verified local system installs"
msgstr ""

#: common/flatpak-dir.c:6415 common/flatpak-dir.c:6782
#, fuzzy, c-format
msgid "Invalid checksum for extra data uri %s"
msgstr "Ungültige Prüfsumme für Extradaten %s"

#: common/flatpak-dir.c:6424
#, c-format
msgid "Empty name for extra data uri %s"
msgstr "Leerer Name für die Adresse %s der Extradaten"

#: common/flatpak-dir.c:6432
#, c-format
msgid "Unsupported extra data uri %s"
msgstr "Nicht unterstützte Adresse %s der Extradaten"

#: common/flatpak-dir.c:6461
#, c-format
msgid "Failed to load local extra-data %s: %s"
msgstr "Zusätzliche lokale Daten %s konnten nicht gelesen werden: %s"

#: common/flatpak-dir.c:6469
#, c-format
msgid "Wrong size for extra-data %s"
msgstr "Falsche Größe für Extradaten %s"

#: common/flatpak-dir.c:6488
#, c-format
msgid "While downloading %s: "
msgstr "Während des Herunterladens von %s: "

#: common/flatpak-dir.c:6498
#, c-format
msgid "Wrong size for extra data %s"
msgstr "Falsche Größe für Extradaten %s"

#: common/flatpak-dir.c:6507
#, c-format
msgid "Invalid checksum for extra data %s"
msgstr "Ungültige Prüfsumme für Extradaten %s"

#: common/flatpak-dir.c:7096 common/flatpak-dir.c:7349
#, c-format
msgid "While pulling %s from remote %s: "
msgstr "Während des Holens von %s von der Gegenstelle %s: "

#: common/flatpak-dir.c:7290 common/flatpak-repo-utils.c:3886
msgid "GPG signatures found, but none are in trusted keyring"
msgstr ""

#: common/flatpak-dir.c:7307
#, c-format
msgid "Commit for ‘%s’ has no ref binding"
msgstr ""

#: common/flatpak-dir.c:7312
#, c-format
msgid "Commit for ‘%s’ is not in expected bound refs: %s"
msgstr ""

#: common/flatpak-dir.c:7488
#, fuzzy
msgid "Only applications can be made current"
msgstr "Eine Anwendung oder Laufzeitumgebung signieren"

#: common/flatpak-dir.c:8192
msgid "Not enough memory"
msgstr "Nicht genug Speicher"

#: common/flatpak-dir.c:8211
msgid "Failed to read from exported file"
msgstr "Lesen aus der exportierten Datei fehlgeschlagen"

#: common/flatpak-dir.c:8401
msgid "Error reading mimetype xml file"
msgstr "Fehler beim Lesen der MIME-Typen-XML-Datei"

#: common/flatpak-dir.c:8406
msgid "Invalid mimetype xml file"
msgstr "Ungültige MIME-Typen-XML-Datei"

#: common/flatpak-dir.c:8492
#, c-format
msgid "D-Bus service file '%s' has wrong name"
msgstr ""

#: common/flatpak-dir.c:8647
#, fuzzy, c-format
msgid "Invalid Exec argument %s"
msgstr "Ungültiges Umgebungsformat: %s"

#: common/flatpak-dir.c:9115
msgid "While getting detached metadata: "
msgstr "Während des Versuchs, abgekoppelte Metadaten zu holen: "

#: common/flatpak-dir.c:9120 common/flatpak-dir.c:9125
#: common/flatpak-dir.c:9129
#, fuzzy
msgid "Extra data missing in detached metadata"
msgstr "Während des Versuchs, abgekoppelte Metadaten zu holen: "

#: common/flatpak-dir.c:9133
msgid "While creating extradir: "
msgstr "Beim Anlegen von extradir: "

#: common/flatpak-dir.c:9154 common/flatpak-dir.c:9187
msgid "Invalid checksum for extra data"
msgstr "Ungültige Prüfsumme für zusätzliche Daten"

#: common/flatpak-dir.c:9183
msgid "Wrong size for extra data"
msgstr "Falsche Größe für zusätzliche Daten"

#: common/flatpak-dir.c:9196
#, c-format
msgid "While writing extra data file '%s': "
msgstr "Fehler beim Schreiben der zusätzlichen Datendatei: »%s«: "

#: common/flatpak-dir.c:9204
#, fuzzy, c-format
msgid "Extra data %s missing in detached metadata"
msgstr "Während des Versuchs, abgekoppelte Metadaten zu holen: "

#: common/flatpak-dir.c:9278
#, fuzzy, c-format
msgid "Unable to get runtime key from metadata"
msgstr "Alternative Datei für diese Metadaten verwenden"

#: common/flatpak-dir.c:9402
#, c-format
msgid "apply_extra script failed, exit status %d"
msgstr "Skript apply_extra ist fehlgeschlagen, Exit-Status %d"

#. Translators: The placeholder is for an app ref.
#: common/flatpak-dir.c:9591
#, c-format
msgid "Installing %s is not allowed by the policy set by your administrator"
msgstr ""

#: common/flatpak-dir.c:9690
#, c-format
msgid "While trying to resolve ref %s: "
msgstr "Während des Auflösens der Referenz %s: "

#: common/flatpak-dir.c:9702
#, c-format
msgid "%s is not available"
msgstr "%s ist nicht verfügbar"

#: common/flatpak-dir.c:9714 common/flatpak-dir.c:11495
#, c-format
msgid "%s commit %s already installed"
msgstr "%s-Commit %s wurde bereits installiert"

#: common/flatpak-dir.c:9721
msgid "Can't create deploy directory"
msgstr "Bereitstellungsordner konnte nicht erstellt werden"

#: common/flatpak-dir.c:9729
#, c-format
msgid "Failed to read commit %s: "
msgstr "Commit %s konnte nicht gelesen werden: "

#: common/flatpak-dir.c:9750
#, c-format
msgid "While trying to checkout %s into %s: "
msgstr "Während des Versuchs, eine Arbeitskopie von %s nach %s zu erstellen: "

#: common/flatpak-dir.c:9769
msgid "While trying to checkout metadata subpath: "
msgstr ""
"Während des Versuchs, eine Arbeitskopie des Metadaten-Unterordners zu "
"erstellen: "

#: common/flatpak-dir.c:9801
#, fuzzy, c-format
msgid "While trying to checkout subpath ‘%s’: "
msgstr "Während des Versuchs, eine Arbeitskopie von %s nach %s zu erstellen: "

#: common/flatpak-dir.c:9811
msgid "While trying to remove existing extra dir: "
msgstr "Während des Versuchs, den bestehenden Extraordner zu entfernen: "

#: common/flatpak-dir.c:9822
msgid "While trying to apply extra data: "
msgstr "Während des Versuchs, zusätzliche Daten anzuwenden: "

#: common/flatpak-dir.c:9849
#, c-format
msgid "Invalid commit ref %s: "
msgstr "Ungültige Commit-Referenz %s: "

#: common/flatpak-dir.c:9857 common/flatpak-dir.c:9869
#, c-format
msgid "Deployed ref %s does not match commit (%s)"
msgstr "Bereitgestellte Referenz %s entspricht nicht dem Commit (%s)"

#: common/flatpak-dir.c:9863
#, c-format
msgid "Deployed ref %s branch does not match commit (%s)"
msgstr ""
"Bereitgestellte Referenz des Zweigs %s entspricht nicht dem Commit (%s)"

#: common/flatpak-dir.c:10125 common/flatpak-installation.c:1911
#, c-format
msgid "%s branch %s already installed"
msgstr "%s Zweig %s wurde bereits installiert"

#: common/flatpak-dir.c:10985
#, c-format
msgid "Could not unmount revokefs-fuse filesystem at %s: "
msgstr ""

#: common/flatpak-dir.c:11289
#, c-format
msgid "This version of %s is already installed"
msgstr "Diese Version von %s ist bereits installiert"

#: common/flatpak-dir.c:11302
#, c-format
msgid "Can't change remote during bundle install"
msgstr ""

#: common/flatpak-dir.c:11571
msgid "Can't update to a specific commit without root permissions"
msgstr ""

#: common/flatpak-dir.c:11852
#, c-format
msgid "Can't remove %s, it is needed for: %s"
msgstr ""

#: common/flatpak-dir.c:11912 common/flatpak-installation.c:2067
#, c-format
msgid "%s branch %s is not installed"
msgstr "%s Zweig %s ist nicht installiert"

#: common/flatpak-dir.c:12165
#, c-format
msgid "%s commit %s not installed"
msgstr "%s Commit %s nicht installiert"

#: common/flatpak-dir.c:12501
#, c-format
msgid "Pruning repo failed: %s"
msgstr ""

#: common/flatpak-dir.c:12669 common/flatpak-dir.c:12675
#, fuzzy, c-format
msgid "Failed to load filter '%s'"
msgstr "Commit %s konnte nicht gelesen werden: "

#: common/flatpak-dir.c:12681
#, fuzzy, c-format
msgid "Failed to parse filter '%s'"
msgstr "Commit %s konnte nicht gelesen werden: "

#: common/flatpak-dir.c:12963
#, fuzzy
msgid "Failed to write summary cache: "
msgstr "Commit %s konnte nicht gelesen werden: "

#: common/flatpak-dir.c:12982
#, fuzzy, c-format
msgid "No oci summary cached for remote '%s'"
msgstr "Kein Flatpak-Zwischenspeicher in Zusammenfassung entfernter Quelle"

#: common/flatpak-dir.c:13207
#, fuzzy, c-format
msgid "No cached summary for remote '%s'"
msgstr "Kein Flatpak-Zwischenspeicher in Zusammenfassung entfernter Quelle"

#: common/flatpak-dir.c:13248
#, fuzzy, c-format
msgid "Invalid checksum for indexed summary %s read from %s"
msgstr "Ungültige Prüfsumme für Extradaten %s"

#: common/flatpak-dir.c:13321
#, c-format
msgid ""
"Remote listing for %s not available; server has no summary file. Check the "
"URL passed to remote-add was valid."
msgstr ""

#: common/flatpak-dir.c:13698
#, fuzzy, c-format
msgid "Invalid checksum for indexed summary %s for remote '%s'"
msgstr "Ungültige Prüfsumme für Extradaten %s"

#: common/flatpak-dir.c:14388
#, c-format
msgid "Multiple branches available for %s, you must specify one of: "
msgstr ""

#: common/flatpak-dir.c:14454
#, c-format
msgid "Nothing matches %s"
msgstr "Kein Treffer für %s"

#: common/flatpak-dir.c:14562
#, c-format
msgid "Can't find ref %s%s%s%s%s"
msgstr "Referenz %s%s%s%s%s kann nicht gefunden werden"

#: common/flatpak-dir.c:14605
#, c-format
msgid "Error searching remote %s: %s"
msgstr "Fehler bei der Suche nach der Gegenstelle %s: %s"

#: common/flatpak-dir.c:14702
#, c-format
msgid "Error searching local repository: %s"
msgstr "Fehler beim Suchen der lokalen Quelle: %s"

#: common/flatpak-dir.c:14839
#, c-format
msgid "%s/%s/%s not installed"
msgstr "%s/%s/%s nicht installiert"

#: common/flatpak-dir.c:15042
#, c-format
msgid "Could not find installation %s"
msgstr "Installation %s konnte nicht gefunden werden"

#: common/flatpak-dir.c:15612
#, fuzzy, c-format
msgid "Invalid file format, no %s group"
msgstr "Ungültiges Umgebungsformat: %s"

#: common/flatpak-dir.c:15617 common/flatpak-repo-utils.c:2836
#, fuzzy, c-format
msgid "Invalid version %s, only 1 supported"
msgstr "Ungültiger URI-Typ %s, nur http/https werden unterstützt"

#: common/flatpak-dir.c:15622 common/flatpak-dir.c:15627
#, fuzzy, c-format
msgid "Invalid file format, no %s specified"
msgstr "Ungültiges Umgebungsformat: %s"

#. Check some minimal size so we don't get crap
#: common/flatpak-dir.c:15647
#, fuzzy
msgid "Invalid file format, gpg key invalid"
msgstr "Ungültiges Umgebungsformat: %s"

#: common/flatpak-dir.c:15675 common/flatpak-repo-utils.c:2917
msgid "Collection ID requires GPG key to be provided"
msgstr ""

#: common/flatpak-dir.c:15718
#, c-format
msgid "Runtime %s, branch %s is already installed"
msgstr "Laufzeitumgebung %s, Zweig %s ist bereits installiert"

#: common/flatpak-dir.c:15719
#, c-format
msgid "App %s, branch %s is already installed"
msgstr "Anwendung %s, Zweig %s ist bereits installiert"

#: common/flatpak-dir.c:15953
#, c-format
msgid "Can't remove remote '%s' with installed ref %s (at least)"
msgstr ""

#: common/flatpak-dir.c:16058
#, fuzzy, c-format
msgid "Invalid character '/' in remote name: %s"
msgstr "%s konnte nicht in entfernter Quelle %s gefunden werden"

#: common/flatpak-dir.c:16064
#, c-format
msgid "No configuration for remote %s specified"
msgstr "Keine Konfiguration für Gegenstelle %s angegeben"

#: common/flatpak-dir.c:17597
#, fuzzy, c-format
msgid "Skipping deletion of mirror ref (%s, %s)…\n"
msgstr "Ungültige bereitgestellte Referenz %s: "

#: common/flatpak-exports.c:931
#, c-format
msgid "An absolute path is required"
msgstr ""

#: common/flatpak-exports.c:948
#, fuzzy, c-format
msgid "Unable to open path \"%s\": %s"
msgstr "Verzeichnis %s kann nicht geöffnet werden"

#: common/flatpak-exports.c:955
#, fuzzy, c-format
msgid "Unable to get file type of \"%s\": %s"
msgstr "Datei %s kann nicht erstellt werden"

#: common/flatpak-exports.c:964
#, c-format
msgid "File \"%s\" has unsupported type 0o%o"
msgstr ""

#: common/flatpak-exports.c:970
#, c-format
msgid "Unable to get filesystem information for \"%s\": %s"
msgstr ""

#: common/flatpak-exports.c:980
#, c-format
msgid "Ignoring blocking autofs path \"%s\""
msgstr ""

#: common/flatpak-exports.c:996 common/flatpak-exports.c:1009
#: common/flatpak-exports.c:1022
#, c-format
msgid "Path \"%s\" is reserved by Flatpak"
msgstr ""

#: common/flatpak-exports.c:1076
#, fuzzy, c-format
msgid "Unable to resolve symbolic link \"%s\": %s"
msgstr "Während des Holens von %s von der entfernten Quelle %s: "

#: common/flatpak-glib-backports.c:69
msgid "Empty string is not a number"
msgstr "Leere Zeichenkette ist keine Zahl"

#: common/flatpak-glib-backports.c:95
#, c-format
msgid "“%s” is not an unsigned number"
msgstr "»%s« ist keine vorzeichenlose Zahl"

#: common/flatpak-glib-backports.c:105
#, c-format
msgid "Number “%s” is out of bounds [%s, %s]"
msgstr "Zahl »%s« ist außerhalb des zulässigen Bereichs [%s, %s]"

#: common/flatpak-image-source.c:83
msgid "Only sha256 image checksums are supported"
msgstr ""

#: common/flatpak-image-source.c:100 common/flatpak-image-source.c:108
msgid "Image is not a manifest"
msgstr "Abbild ist kein Manifest"

#: common/flatpak-image-source.c:123
msgid "No org.flatpak.ref found in image"
msgstr ""

#: common/flatpak-image-source.c:148
#, c-format
msgid "Ref '%s' not found in registry"
msgstr "Referenz »%s« wurde in der Registrierungsdatenbank nicht gefunden"

#: common/flatpak-image-source.c:157
msgid "Multiple images in registry, specify a ref with --ref"
msgstr ""
"Mehrere Abbilder in der Registrierungsdatenbank, geben Sie eine Referenz mit "
"--ref an"

#: common/flatpak-installation.c:834
#, fuzzy, c-format
msgid "Ref %s not installed"
msgstr "%s ist nicht installiert"

#: common/flatpak-installation.c:875
#, c-format
msgid "App %s not installed"
msgstr "Anwendung »%s« nicht installiert"

#: common/flatpak-installation.c:1395
#, fuzzy, c-format
msgid "Remote '%s' already exists"
msgstr "Entfernt gelegene Quelle %s existiert bereits"

#: common/flatpak-installation.c:1946
#, c-format
msgid "As requested, %s was only pulled, but not installed"
msgstr "Wie gewünscht, wurde »%s« nur heruntergeladen und nicht installiert"

#: common/flatpak-instance.c:533 common/flatpak-instance.c:687
#: common/flatpak-instance.c:728
#, c-format
msgid "Unable to create directory %s"
msgstr "Verzeichnis %s kann nicht erstellt werden"

#: common/flatpak-instance.c:554
#, c-format
msgid "Unable to lock %s"
msgstr "%s kann nicht gesperrt werden"

#: common/flatpak-instance.c:627
#, fuzzy, c-format
msgid "Unable to create temporary directory in %s"
msgstr "Bereitstellungsordner konnte nicht erstellt werden"

#: common/flatpak-instance.c:639
#, c-format
msgid "Unable to create file %s"
msgstr "Datei %s kann nicht erstellt werden"

#: common/flatpak-instance.c:646
#, fuzzy, c-format
msgid "Unable to update symbolic link %s/%s"
msgstr "Während des Holens von %s von der entfernten Quelle %s: "

#: common/flatpak-oci-registry.c:1197
msgid "Only Bearer authentication supported"
msgstr ""

#: common/flatpak-oci-registry.c:1206
#, fuzzy
msgid "Only realm in authentication request"
msgstr "Ungültiger Dbus-Name %s\n"

#: common/flatpak-oci-registry.c:1213
#, fuzzy
msgid "Invalid realm in authentication request"
msgstr "Ungültiger Dbus-Name %s\n"

#: common/flatpak-oci-registry.c:1283
#, c-format
msgid "Authorization failed: %s"
msgstr "Autorisierung fehlgeschlagen: %s"

#: common/flatpak-oci-registry.c:1285
msgid "Authorization failed"
msgstr "Legitimierung gescheitert"

#: common/flatpak-oci-registry.c:1289
#, c-format
msgid "Unexpected response status %d when requesting token: %s"
msgstr ""

#: common/flatpak-oci-registry.c:1300
#, fuzzy
msgid "Invalid authentication request response"
msgstr "Ungültiger Dbus-Name %s\n"

#: common/flatpak-oci-registry.c:1731
#, c-format
msgid "Flatpak was compiled without zstd support"
msgstr ""

#: common/flatpak-oci-registry.c:1923 common/flatpak-oci-registry.c:1975
#: common/flatpak-oci-registry.c:2004 common/flatpak-oci-registry.c:2059
#: common/flatpak-oci-registry.c:2115 common/flatpak-oci-registry.c:2193
#, fuzzy
msgid "Invalid delta file format"
msgstr "Ungültiges Umgebungsformat: %s"

#: common/flatpak-oci-registry.c:3198 common/flatpak-oci-registry.c:3382
msgid "Invalid OCI image config"
msgstr ""

#: common/flatpak-oci-registry.c:3260 common/flatpak-oci-registry.c:3531
#, c-format
msgid "Wrong layer checksum, expected %s, was %s"
msgstr ""

#: common/flatpak-oci-registry.c:3359
#, c-format
msgid "No ref specified for OCI image %s"
msgstr ""

#: common/flatpak-oci-registry.c:3369
#, c-format
msgid "Wrong ref (%s) specified for OCI image %s, expected %s"
msgstr ""

#: common/flatpak-progress.c:236
#, fuzzy, c-format
msgid "Downloading metadata: %u/(estimating) %s"
msgstr "Keine zusätzlichen Datenquellen"

#: common/flatpak-progress.c:260
#, c-format
msgid "Downloading: %s/%s"
msgstr "Wird heruntergeladen: %s/%s"

#: common/flatpak-progress.c:280
#, c-format
msgid "Downloading extra data: %s/%s"
msgstr "Zusätzliche Daten werden heruntergeladen: %s/%s"

#: common/flatpak-progress.c:285
#, c-format
msgid "Downloading files: %d/%d %s"
msgstr "Dateien werden heruntergeladen: %d/%d %s"

#: common/flatpak-ref-utils.c:122
msgid "Name can't be empty"
msgstr "Name darf nicht leer sein"

#: common/flatpak-ref-utils.c:129
msgid "Name can't be longer than 255 characters"
msgstr "Name darf nicht länger als 255 Zeichen sein"

#: common/flatpak-ref-utils.c:142
msgid "Name can't start with a period"
msgstr "Name darf nicht mit einem Punkt beginnen"

#: common/flatpak-ref-utils.c:148
#, c-format
msgid "Name can't start with %c"
msgstr "Name darf nicht mit %c beginnen"

#: common/flatpak-ref-utils.c:164
msgid "Name can't end with a period"
msgstr "Name darf nicht mit einem Punkt enden"

#: common/flatpak-ref-utils.c:171 common/flatpak-ref-utils.c:183
msgid "Only last name segment can contain -"
msgstr "Nur das letzte Namenssegment darf - enthalten"

#: common/flatpak-ref-utils.c:174
#, c-format
msgid "Name segment can't start with %c"
msgstr "Namenssegment darf nicht mit %c beginnen"

#: common/flatpak-ref-utils.c:186
#, c-format
msgid "Name can't contain %c"
msgstr "Name darf %c nicht enthalten"

#: common/flatpak-ref-utils.c:195
msgid "Names must contain at least 2 periods"
msgstr "Name muss mindestens 2 Punkte enthalten"

#: common/flatpak-ref-utils.c:312
msgid "Arch can't be empty"
msgstr "Architektur darf nicht leer sein"

#: common/flatpak-ref-utils.c:323
#, c-format
msgid "Arch can't contain %c"
msgstr "Architektur darf %c nicht enthalten"

#: common/flatpak-ref-utils.c:385
msgid "Branch can't be empty"
msgstr "Zweig darf nicht leer sein"

#: common/flatpak-ref-utils.c:395
#, c-format
msgid "Branch can't start with %c"
msgstr "Zweig darf nicht mit %c beginnen"

#: common/flatpak-ref-utils.c:405
#, c-format
msgid "Branch can't contain %c"
msgstr "Zweig darf %c nicht enthalten"

#: common/flatpak-ref-utils.c:615 common/flatpak-ref-utils.c:865
msgid "Ref too long"
msgstr ""

#: common/flatpak-ref-utils.c:627
msgid "Invalid remote name"
msgstr "Ungültiger Gegenstellenname"

#: common/flatpak-ref-utils.c:641
#, c-format
msgid "%s is not application or runtime"
msgstr "%s ist keine Anwendung oder Laufzeitumgebung"

#: common/flatpak-ref-utils.c:650 common/flatpak-ref-utils.c:667
#: common/flatpak-ref-utils.c:683
#, c-format
msgid "Wrong number of components in %s"
msgstr "Falsche Anzahl an Komponenten in %s"

#: common/flatpak-ref-utils.c:656
#, c-format
msgid "Invalid name %.*s: %s"
msgstr "Ungültiger Name %.*s: %s"

#: common/flatpak-ref-utils.c:673
#, c-format
msgid "Invalid arch: %.*s: %s"
msgstr "Ungültige Architektur: %.*s: %s"

#: common/flatpak-ref-utils.c:816
#, c-format
msgid "Invalid name %s: %s"
msgstr "Ungültiger Name %s: %s"

#: common/flatpak-ref-utils.c:834
#, c-format
msgid "Invalid arch: %s: %s"
msgstr "Ungültige Architektur: %s: %s"

#: common/flatpak-ref-utils.c:853
#, c-format
msgid "Invalid branch: %s: %s"
msgstr "Ungültiger Zweig: %s: %s"

#: common/flatpak-ref-utils.c:962 common/flatpak-ref-utils.c:970
#: common/flatpak-ref-utils.c:978
#, c-format
msgid "Wrong number of components in partial ref %s"
msgstr ""

#: common/flatpak-ref-utils.c:1298
msgid " development platform"
msgstr " Entwicklungsplattform"

#: common/flatpak-ref-utils.c:1300
msgid " platform"
msgstr " Plattform"

#: common/flatpak-ref-utils.c:1302
msgid " application base"
msgstr "Anwendungsbasis"

#: common/flatpak-ref-utils.c:1305
msgid " debug symbols"
msgstr " Fehlersuchsymbole"

#: common/flatpak-ref-utils.c:1307
msgid " sourcecode"
msgstr " Quellcode"

#: common/flatpak-ref-utils.c:1309
msgid " translations"
msgstr " Übersetzungen"

#: common/flatpak-ref-utils.c:1311
msgid " docs"
msgstr " Dokumentation"

#: common/flatpak-ref-utils.c:1578
#, c-format
msgid "Invalid id %s: %s"
msgstr "Ungültige Kennung %s: %s"

#: common/flatpak-remote.c:1216
#, c-format
msgid "Bad remote name: %s"
msgstr "Falscher Gegenstellenname: %s"

#: common/flatpak-remote.c:1220
#, fuzzy
msgid "No URL specified"
msgstr "Keine URL angegeben"

#: common/flatpak-remote.c:1266
#, fuzzy
msgid "GPG verification must be enabled when a collection ID is set"
msgstr "GPG-Überprüfung ist erforderlich, wenn Sammlungen aktiviert sind"

#: common/flatpak-repo-utils.c:344
#, c-format
msgid "No extra data sources"
msgstr "Keine zusätzlichen Datenquellen"

#: common/flatpak-repo-utils.c:2817
#, c-format
msgid "Invalid %s: Missing group ‘%s’"
msgstr ""

#: common/flatpak-repo-utils.c:2826
#, c-format
msgid "Invalid %s: Missing key ‘%s’"
msgstr ""

#: common/flatpak-repo-utils.c:2876
msgid "Invalid gpg key"
msgstr "Ungültiger GPG-Schlüssel"

#: common/flatpak-repo-utils.c:3217
#, fuzzy, c-format
msgid "Error copying 64x64 icon for component %s: %s\n"
msgstr "Fehler bei der Suche nach dem entfernten %s: %s"

#: common/flatpak-repo-utils.c:3223
#, fuzzy, c-format
msgid "Error copying 128x128 icon for component %s: %s\n"
msgstr "Fehler bei der Suche nach dem entfernten %s: %s"

#: common/flatpak-repo-utils.c:3362
#, c-format
msgid "%s is end-of-life, ignoring for appstream"
msgstr ""

#: common/flatpak-repo-utils.c:3397
#, fuzzy, c-format
msgid "No appstream data for %s: %s\n"
msgstr "Fehler beim Aktualisieren der Metadaten für »%s«: %s\n"

#: common/flatpak-repo-utils.c:3744
#, fuzzy
msgid "Invalid bundle, no ref in metadata"
msgstr "Ungültige Prüfsumme für zusätzliche Daten"

#: common/flatpak-repo-utils.c:3846
#, c-format
msgid "Collection ‘%s’ of bundle doesn’t match collection ‘%s’ of remote"
msgstr ""

#: common/flatpak-repo-utils.c:3923
msgid "Metadata in header and app are inconsistent"
msgstr ""

#: common/flatpak-run.c:951
msgid "No systemd user session available, cgroups not available"
msgstr ""

#: common/flatpak-run.c:1496
msgid "Unable to allocate instance id"
msgstr ""

#: common/flatpak-run.c:1632 common/flatpak-run.c:1641
#, fuzzy, c-format
msgid "Failed to open flatpak-info file: %s"
msgstr "Öffnen der temporären flatpak-Informationsdatei fehlgeschlagen: %s"

#: common/flatpak-run.c:1668
#, fuzzy, c-format
msgid "Failed to open bwrapinfo.json file: %s"
msgstr "Öffnen der temporären flatpak-Informationsdatei fehlgeschlagen: %s"

#: common/flatpak-run.c:1689
#, fuzzy, c-format
msgid "Failed to write to instance id fd: %s"
msgstr "Commit %s konnte nicht gelesen werden: "

#: common/flatpak-run.c:2096
msgid "Initialize seccomp failed"
msgstr ""

#: common/flatpak-run.c:2135
#, fuzzy, c-format
msgid "Failed to add architecture to seccomp filter: %s"
msgstr "Zusätzliche lokale Daten %s konnten nicht gelesen werden: %s"

#: common/flatpak-run.c:2143
#, fuzzy, c-format
msgid "Failed to add multiarch architecture to seccomp filter: %s"
msgstr "Zusätzliche lokale Daten %s konnten nicht gelesen werden: %s"

#: common/flatpak-run.c:2175 common/flatpak-run.c:2192
#: common/flatpak-run.c:2214
#, fuzzy, c-format
msgid "Failed to block syscall %d: %s"
msgstr "Fehler: %s %s ist fehlgeschlagen: %s\n"

#: common/flatpak-run.c:2247
#, fuzzy, c-format
msgid "Failed to export bpf: %s"
msgstr "Lesen aus der exportierten Datei fehlgeschlagen"

#: common/flatpak-run.c:2587
#, fuzzy, c-format
msgid "Failed to open ‘%s’"
msgstr "Öffnen der temporären flatpak-Informationsdatei fehlgeschlagen: %s"

#: common/flatpak-run.c:2597
#, c-format
msgid ""
"Directory forwarding needs version 4 of the document portal (have version %d)"
msgstr ""

#: common/flatpak-run.c:2915
#, c-format
msgid "ldconfig failed, exit status %d"
msgstr "ldconfig ist fehlgeschlagen, Exit-Status %d"

#: common/flatpak-run.c:2922
#, fuzzy
msgid "Can't open generated ld.so.cache"
msgstr "Namensraum %s konnte nicht geöffnet werden: %s"

#. Translators: The placeholder is for an app ref.
#: common/flatpak-run.c:3045
#, c-format
msgid "Running %s is not allowed by the policy set by your administrator"
msgstr ""

#: common/flatpak-run.c:3202
msgid ""
"\"flatpak run\" is not intended to be run as `sudo flatpak run`. Use `sudo "
"-i` or `su -l` instead and invoke \"flatpak run\" from inside the new shell."
msgstr ""

#: common/flatpak-run.c:3413
#, fuzzy, c-format
msgid "Failed to migrate from %s: %s"
msgstr "Commit %s konnte nicht gelesen werden: "

#: common/flatpak-run.c:3434
#, c-format
msgid "Failed to migrate old app data directory %s to new name %s: %s"
msgstr ""

#: common/flatpak-run.c:3443
#, fuzzy, c-format
msgid "Failed to create symlink while migrating %s: %s"
msgstr "Commit %s konnte nicht gelesen werden: "

#: common/flatpak-run-dbus.c:46
#, fuzzy
msgid "Failed to open app info file"
msgstr "Öffnen der Informationsdatei der Anwendung fehlgeschlagen: %s"

#: common/flatpak-run-dbus.c:149
msgid "Unable to create sync pipe"
msgstr "»Sync-Pipe« konnte nicht erstellt werden"

#: common/flatpak-run-dbus.c:185
msgid "Failed to sync with dbus proxy"
msgstr "Abgleich mit Dbus-Proxy ist fehlgeschlagen"

#: common/flatpak-transaction.c:2275
#, fuzzy, c-format
msgid "Warning: Problem looking for related refs: %s"
msgstr "Warnung: Problem bei der Suche nach zugehörigen Referenzen: %s\n"

#: common/flatpak-transaction.c:2493
#, fuzzy, c-format
msgid "The application %s requires the runtime %s which was not found"
msgstr "Anwendung %s Zweig %s ist nicht installiert"

#: common/flatpak-transaction.c:2509
#, fuzzy, c-format
msgid "The application %s requires the runtime %s which is not installed"
msgstr "Anwendung %s Zweig %s ist nicht installiert"

#: common/flatpak-transaction.c:2641
#, c-format
msgid "Can't uninstall %s which is needed by %s"
msgstr ""

#: common/flatpak-transaction.c:2740
#, c-format
msgid "Remote %s disabled, ignoring %s update"
msgstr "Gegenstelle %s ist deaktiviert. Aktualisierung %s wird ignoriert"

#: common/flatpak-transaction.c:2773
#, c-format
msgid "%s is already installed"
msgstr "%s wurde bereits installiert"

#: common/flatpak-transaction.c:2776
#, c-format
msgid "%s is already installed from remote %s"
msgstr "%s wurde bereits von der Gegenstelle %s installiert"

#: common/flatpak-transaction.c:3120
#, fuzzy, c-format
msgid "Invalid .flatpakref: %s"
msgstr "Ungültige Commit-Referenz %s: "

#: common/flatpak-transaction.c:3161
msgid "Warning: Could not mark already installed apps as preinstalled"
msgstr ""

#: common/flatpak-transaction.c:3382
#, fuzzy, c-format
msgid "Error updating remote metadata for '%s': %s"
msgstr "Fehler beim Aktualisieren der Metadaten für »%s«: %s\n"

#: common/flatpak-transaction.c:3885
#, c-format
msgid ""
"Warning: Treating remote fetch error as non-fatal since %s is already "
"installed: %s"
msgstr ""

#: common/flatpak-transaction.c:4209
#, fuzzy, c-format
msgid "No authenticator installed for remote '%s'"
msgstr "Legitimierung wird benötigt, um Software zu aktualisieren"

#: common/flatpak-transaction.c:4313 common/flatpak-transaction.c:4320
#, fuzzy, c-format
msgid "Failed to get tokens for ref: %s"
msgstr "Temporäre Datei konnte nicht geöffnet werden: %s"

#: common/flatpak-transaction.c:4315 common/flatpak-transaction.c:4322
#, fuzzy
msgid "Failed to get tokens for ref"
msgstr "Temporäre Datei konnte nicht geöffnet werden: %s"

#: common/flatpak-transaction.c:4580
#, c-format
msgid "Ref %s from %s matches more than one transaction operation"
msgstr ""

#: common/flatpak-transaction.c:4581 common/flatpak-transaction.c:4591
msgid "any remote"
msgstr "jede Gegenstelle"

#: common/flatpak-transaction.c:4590
#, c-format
msgid "No transaction operation found for ref %s from %s"
msgstr ""

#: common/flatpak-transaction.c:4713
#, c-format
msgid "Flatpakrepo URL %s not file, HTTP or HTTPS"
msgstr ""

#: common/flatpak-transaction.c:4719
#, fuzzy, c-format
msgid "Can't load dependent file %s: "
msgstr "Namensraum %s konnte nicht geöffnet werden: %s"

#: common/flatpak-transaction.c:4727
#, c-format
msgid "Invalid .flatpakrepo: %s"
msgstr ""

#: common/flatpak-transaction.c:5454
msgid "Transaction already executed"
msgstr "Transaktion bereits ausgeführt"

#: common/flatpak-transaction.c:5469
msgid ""
"Refusing to operate on a user installation as root! This can lead to "
"incorrect file ownership and permission errors."
msgstr ""

#: common/flatpak-transaction.c:5567 common/flatpak-transaction.c:5580
msgid "Aborted by user"
msgstr "Vom Benutzer abgebrochen"

#: common/flatpak-transaction.c:5605
#, c-format
msgid "Skipping %s due to previous error"
msgstr ""

#: common/flatpak-transaction.c:5659
#, c-format
msgid "Aborted due to failure (%s)"
msgstr ""

#: common/flatpak-uri.c:118
#, fuzzy, no-c-format
msgid "Invalid %-encoding in URI"
msgstr "Ungültiger Erweiterungsname %s"

#: common/flatpak-uri.c:135
msgid "Illegal character in URI"
msgstr ""

#: common/flatpak-uri.c:169
msgid "Non-UTF-8 characters in URI"
msgstr ""

#: common/flatpak-uri.c:275
#, c-format
msgid "Invalid IPv6 address ‘%.*s’ in URI"
msgstr ""

#: common/flatpak-uri.c:330
#, c-format
msgid "Illegal encoded IP address ‘%.*s’ in URI"
msgstr ""

#: common/flatpak-uri.c:342
#, c-format
msgid "Illegal internationalized hostname ‘%.*s’ in URI"
msgstr ""

#: common/flatpak-uri.c:374 common/flatpak-uri.c:386
#, c-format
msgid "Could not parse port ‘%.*s’ in URI"
msgstr ""

#: common/flatpak-uri.c:393
#, c-format
msgid "Port ‘%.*s’ in URI is out of range"
msgstr ""

#: common/flatpak-uri.c:910
msgid "URI is not absolute, and no base URI was provided"
msgstr ""

#: common/flatpak-usb.c:83
#, c-format
msgid "USB device query 'all' must not have data"
msgstr ""

#: common/flatpak-usb.c:102
#, c-format
msgid "USB query rule 'cls' must be in the form CLASS:SUBCLASS or CLASS:*"
msgstr ""

#: common/flatpak-usb.c:111
#, fuzzy, c-format
msgid "Invalid USB class"
msgstr "Ungültige Kennung %s: %s"

#: common/flatpak-usb.c:125
#, c-format
msgid "Invalid USB subclass"
msgstr ""

#: common/flatpak-usb.c:141 common/flatpak-usb.c:148
#, c-format
msgid "USB query rule 'dev' must have a valid 4-digit hexadecimal product id"
msgstr ""

#: common/flatpak-usb.c:164 common/flatpak-usb.c:171
#, c-format
msgid "USB query rule 'vnd' must have a valid 4-digit hexadecimal vendor id"
msgstr ""

#: common/flatpak-usb.c:205
#, c-format
msgid "USB device queries must be in the form TYPE:DATA"
msgstr ""

#: common/flatpak-usb.c:225
#, c-format
msgid "Unknown USB query rule %s"
msgstr ""

#: common/flatpak-usb.c:248
#, c-format
msgid "Empty USB query"
msgstr ""

#: common/flatpak-usb.c:274
#, c-format
msgid "Multiple USB query rules of the same type is not supported"
msgstr ""

#: common/flatpak-usb.c:283
#, c-format
msgid "'all' must not contain extra query rules"
msgstr ""

#: common/flatpak-usb.c:291
#, c-format
msgid "USB queries with 'dev' must also specify vendors"
msgstr ""

#: common/flatpak-utils.c:712
msgid "Glob can't match apps"
msgstr ""

#: common/flatpak-utils.c:737
msgid "Empty glob"
msgstr ""

#: common/flatpak-utils.c:756
#, fuzzy
msgid "Too many segments in glob"
msgstr "Zu viele Argumente"

#: common/flatpak-utils.c:777
#, fuzzy, c-format
msgid "Invalid glob character '%c'"
msgstr "Ungültige Prozesskennung %s"

#: common/flatpak-utils.c:831
#, c-format
msgid "Missing glob on line %d"
msgstr ""

#: common/flatpak-utils.c:835
#, c-format
msgid "Trailing text on line %d"
msgstr ""

#: common/flatpak-utils.c:839
#, c-format
msgid "on line %d"
msgstr "in Zeile %d"

#: common/flatpak-utils.c:861
#, c-format
msgid "Unexpected word '%s' on line %d"
msgstr ""

#: common/flatpak-utils.c:2118
#, c-format
msgid "Invalid require-flatpak argument %s"
msgstr ""

#: common/flatpak-utils.c:2128 common/flatpak-utils.c:2147
#, c-format
msgid "%s needs a later flatpak version (%s)"
msgstr "%s verlangt eine neuere Version von flatpak (%s)"

#: oci-authenticator/flatpak-oci-authenticator.c:291
msgid "Not a oci remote, missing summary.xa.oci-repository"
msgstr ""

#: oci-authenticator/flatpak-oci-authenticator.c:477
msgid "Not a OCI remote"
msgstr "Keine OCI-Gegenstelle"

#: oci-authenticator/flatpak-oci-authenticator.c:488
msgid "Invalid token"
msgstr "Ungültiges Token"

#: portal/flatpak-portal.c:2292
#, c-format
msgid "No portal support found"
msgstr ""

#: portal/flatpak-portal.c:2298
msgid "Deny"
msgstr "Ablehnen"

#: portal/flatpak-portal.c:2300
msgid "Update"
msgstr "Aktualisieren"

#: portal/flatpak-portal.c:2305
#, c-format
msgid "Update %s?"
msgstr "%s aktualisieren?"

#: portal/flatpak-portal.c:2317
msgid "The application wants to update itself."
msgstr "Die Anwendung möchte sich selbst aktualisieren."

#: portal/flatpak-portal.c:2318
msgid "Update access can be changed any time from the privacy settings."
msgstr ""
"Der Aktualisierungszugang kann jederzeit in den Datenschutzeinstellungen "
"geändert werden."

#: portal/flatpak-portal.c:2343
#, c-format
msgid "Application update not allowed"
msgstr "Anwendungsaktualisierung nicht erlaubt"

#: portal/flatpak-portal.c:2501
#, c-format
msgid "Self update not supported, new version requires new permissions"
msgstr ""
"Selbstaktualisierung nicht unterstützt, neue Version erfordert neue "
"Berechtigungen"

#: portal/flatpak-portal.c:2684 portal/flatpak-portal.c:2702
#, c-format
msgid "Update ended unexpectedly"
msgstr "Aktualisierung unerwartet beendet"

#. SECURITY:
#. - Normal users need admin authentication to install software
#. system-wide.
#. - Note that we install polkit rules that allow local users
#. in the wheel group to install without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:23
msgid "Install signed application"
msgstr "Signierte Anwendung installieren"

#: system-helper/org.freedesktop.Flatpak.policy.in:24
#: system-helper/org.freedesktop.Flatpak.policy.in:42
msgid "Authentication is required to install software"
msgstr "Legitimation ist zum Installieren von Software erforderlich"

#. SECURITY:
#. - Normal users need admin authentication to install software
#. system-wide.
#. - Note that we install polkit rules that allow local users
#. in the wheel group to install without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:41
msgid "Install signed runtime"
msgstr "Signierte Laufzeitumgebung installieren"

#. SECURITY:
#. - Normal users do not require admin authentication to update an
#. app as the commit will be signed, and the action is required
#. to update the system when unattended.
#. - Changing this to anything other than 'yes' will break unattended
#. updates.
#: system-helper/org.freedesktop.Flatpak.policy.in:60
msgid "Update signed application"
msgstr "Signierte Anwendung aktualisieren"

#: system-helper/org.freedesktop.Flatpak.policy.in:61
#: system-helper/org.freedesktop.Flatpak.policy.in:80
msgid "Authentication is required to update software"
msgstr "Legitimierung wird benötigt, um Software zu aktualisieren"

#. SECURITY:
#. - Normal users do not require admin authentication to update a
#. runtime as the commit will be signed, and the action is required
#. to update the system when unattended.
#. - Changing this to anything other than 'yes' will break unattended
#. updates.
#: system-helper/org.freedesktop.Flatpak.policy.in:79
msgid "Update signed runtime"
msgstr "Signierte Laufzeitumgebung aktualisieren"

#. SECURITY:
#. - Normal users do not need authentication to update metadata
#. from signed repositories.
#: system-helper/org.freedesktop.Flatpak.policy.in:94
msgid "Update remote metadata"
msgstr "Entfernte Metadaten aktualisieren"

#: system-helper/org.freedesktop.Flatpak.policy.in:95
msgid "Authentication is required to update remote info"
msgstr ""

#. SECURITY:
#. - Normal users do not need authentication to modify the
#. OSTree repository
#. - Note that we install polkit rules that allow local users
#. in the wheel group to modify repos without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:111
msgid "Update system repository"
msgstr "Systemquelle aktualisieren"

#: system-helper/org.freedesktop.Flatpak.policy.in:112
msgid "Authentication is required to modify a system repository"
msgstr "Legitimierung wird benötigt, um ein System-Softwaredepot zu ändern"

#. SECURITY:
#. - Normal users need admin authentication to install software
#. system-wide.
#: system-helper/org.freedesktop.Flatpak.policy.in:126
msgid "Install bundle"
msgstr "Bündel installieren"

#: system-helper/org.freedesktop.Flatpak.policy.in:127
msgid "Authentication is required to install software from $(path)"
msgstr "Legitimierung wird benötigt, um Software von $(path) zu installieren"

#. SECURITY:
#. - Normal users need admin authentication to uninstall software
#. system-wide.
#. - Note that we install polkit rules that allow local users
#. in the wheel group to uninstall without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:144
msgid "Uninstall runtime"
msgstr "Laufzeitumgebung deinstallieren"

#: system-helper/org.freedesktop.Flatpak.policy.in:145
msgid "Authentication is required to uninstall software"
msgstr "Legitimierung wird benötigt, um Software zu deinstallieren"

#. SECURITY:
#. - Normal users need admin authentication to uninstall software
#. system-wide.
#. - Note that we install polkit rules that allow local users
#. in the wheel group to uninstall without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:161
msgid "Uninstall app"
msgstr "Anwendung deinstallieren"

#: system-helper/org.freedesktop.Flatpak.policy.in:162
msgid "Authentication is required to uninstall $(ref)"
msgstr "Legitimierung wird benötigt, um $(ref) zu deinstallieren"

#. SECURITY:
#. - Normal users need admin authentication to configure system-wide
#. software repositories.
#: system-helper/org.freedesktop.Flatpak.policy.in:177
msgid "Configure Remote"
msgstr "Gegenstelle konfigurieren"

#: system-helper/org.freedesktop.Flatpak.policy.in:178
msgid "Authentication is required to configure software repositories"
msgstr "Legitimierung wird benötigt, um die Softwarequellen zu konfigurieren"

#. SECURITY:
#. - Normal users need admin authentication to configure the system-wide
#. Flatpak installation.
#: system-helper/org.freedesktop.Flatpak.policy.in:192
msgid "Configure"
msgstr "Konfigurieren"

#: system-helper/org.freedesktop.Flatpak.policy.in:193
msgid "Authentication is required to configure software installation"
msgstr ""
"Legitimierung wird benötigt, um die Installation von Software zu "
"konfigurieren"

#. SECURITY:
#. - Normal users do not require admin authentication to update
#. appstream data as it will be signed, and the action is required
#. to update the system when unattended.
#. - Changing this to anything other than 'yes' will break unattended
#. updates.
#: system-helper/org.freedesktop.Flatpak.policy.in:210
msgid "Update appstream"
msgstr "Appstream aktualisieren"

#: system-helper/org.freedesktop.Flatpak.policy.in:211
#, fuzzy
msgid "Authentication is required to update information about software"
msgstr ""
"Legitimierung wird benötigt, um Info zu entfernter Quelle zu aktualisieren"

#. SECURITY:
#. - Normal users do not require admin authentication to update
#. metadata as it will be signed, and the action is required
#. to update the system when unattended.
#. - Changing this to anything other than 'yes' will break unattended
#. updates.
#: system-helper/org.freedesktop.Flatpak.policy.in:228
msgid "Update metadata"
msgstr "Metadaten aktualisieren"

#: system-helper/org.freedesktop.Flatpak.policy.in:229
msgid "Authentication is required to update metadata"
msgstr "Legitimierung wird benötigt, um Metadaten zu aktualisieren"

#. SECURITY:
#. - Authorisation to actually install software is controlled by
#. org.freedesktop.Flatpak.app-install.
#. - This action is checked after app-install, as it can only be done
#. once the app’s data (including its content rating) has been
#. downloaded.
#. - This action is checked to see if the installation should be allowed
#. based on whether the app being installed has content which doesn’t
#. comply with the user’s parental controls policy (the content is
#. ‘too extreme’).
#. - It is checked only if an app has too extreme content for the user
#. who is trying to install it (in which case, the app is ‘unsafe’).
#. - Typically, normal users will need admin permission to install apps
#. with extreme content; admins will be able to install it without
#. additional checks.
#. - In order to configure the policy so that admins can install safe and
#. unsafe software anywhere without authorisation, and non-admins can
#. install safe software in their user or system dirs without
#. authorisation, but need authorisation to install unsafe software
#. anywhere:
#. * Unconditionally return `yes` from `app-install`.
#. * Return `auth_admin` from `override-parental-controls` for users
#. not in `@privileged_group@`, and `yes` for users in it.
#. * Set the malcontent `is-{user,system}-installation-allowed`
#. properties of all non-admins’ parental controls policies to true.
#. - In order to configure the policy so that admins can install safe and
#. unsafe software anywhere without authorisation, and non-admins can
#. install safe software in their user dir without authorisation, but
#. need authorisation to install safe software in the system dir or to
#. install unsafe software anywhere:
#. * Unconditionally return `yes` from `app-install`.
#. * Return `auth_admin` from `override-parental-controls` for users
#. not in `@privileged_group@`, and `yes` for users in it.
#. * Set the malcontent `is-user-installation-allowed` property of all
#. non-admins’ parental controls policies to true.
#. * Set the malcontent `is-system-installation-allowed` property of
#. all non-admins’ parental controls policies to false.
#. - In order to configure the policy so that all users (including
#. admins) can install safe software anywhere without authorisation,
#. but need authorisation to install unsafe software anywhere (i.e.
#. applying parental controls to admins too):
#. * Unconditionally return `yes` from `app-install`.
#. * Unconditionally return `auth_admin` from `override-parental-controls`.
#. * Set the malcontent `is-user-installation-allowed` property of all
#. users’ parental controls policies to true.
#. * Set the malcontent `is-system-installation-allowed` property of
#. all users’ parental controls policies to true.
#: system-helper/org.freedesktop.Flatpak.policy.in:287
#, fuzzy
msgid "Override parental controls for installs"
msgstr "Kindersicherung außer Kraft setzen"

#: system-helper/org.freedesktop.Flatpak.policy.in:288
msgid ""
"Authentication is required to install software which is restricted by your "
"parental controls policy"
msgstr ""
"Legitimierung wird benötigt, um Software zu installieren, welche durch die "
"Kindersicherung gesperrt ist"

#. SECURITY:
#. - This is like org.freedesktop.Flatpak.override-parental-controls, but
#. it’s queried for app updates, whereas the former is queried for app
#. installs.
#. - As with the above action, this one is only queried if
#. org.freedesktop.Flatpak.app-update has allowed the app update, and
#. only if the app being updated has too extreme content for the user
#. who is trying to update it.
#. - The default policy for this is to *allow* updates to ‘too extreme’
#. apps by default, on the basis that having an out-of-date (i.e.
#. insecure or unsupported) app is a worse outcome than automatically
#. installing an update which has radically different content from the
#. version of the app which the parent originally vetted and installed.
#: system-helper/org.freedesktop.Flatpak.policy.in:313
#, fuzzy
msgid "Override parental controls for updates"
msgstr "Kindersicherung außer Kraft setzen"

#: system-helper/org.freedesktop.Flatpak.policy.in:314
#, fuzzy
msgid ""
"Authentication is required to update software which is restricted by your "
"parental controls policy"
msgstr ""
"Legitimierung wird benötigt, um Software zu installieren, welche durch die "
"Kindersicherung gesperrt ist"

#~ msgid "Installed:"
#~ msgstr "Installiert:"

#~ msgid "Download:"
#~ msgstr "Herunterladen"

#, fuzzy, c-format
#~ msgid "Unable to lookup key ID %s: %d"
#~ msgstr "Während des Holens von %s von der entfernten Quelle %s: "

#, fuzzy, c-format
#~ msgid "Error signing commit: %d"
#~ msgstr "Fehler bei der Suche nach dem entfernten %s: %s"

#, fuzzy, c-format
#~ msgid "No entry for %s in remote '%s' summary cache "
#~ msgstr ""
#~ "Kein Eintrag für %s in Zusammenfassung des entfernten Flatpak-"
#~ "Zwischenspeichers"

#, c-format
#~ msgid "Unable to open directory %s"
#~ msgstr "Verzeichnis %s kann nicht geöffnet werden"

#~ msgid "install"
#~ msgstr "installieren"

#~ msgid "update"
#~ msgstr "update"

#~ msgid "install bundle"
#~ msgstr "Bündel installieren"

#~ msgid "uninstall"
#~ msgstr "deinstallieren"

#~ msgid "(internal error, please report)"
#~ msgstr "(interner Fehler, bitte melden)"

#~ msgid "Warning:"
#~ msgstr "Warnung:"

#, c-format
#~ msgid "%s%s%s branch %s%s%s"
#~ msgstr "%s%s%s Zweig %s%s%s"

#~ msgid "runtime"
#~ msgstr "Laufzeit"

#~ msgid "app"
#~ msgstr "Anwendung"

# Das ist aber schwer zu übersetzen...
#, c-format
#~ msgid "%s Failed to %s %s: %s\n"
#~ msgstr "%s Fehler bei der Aktion %s %s: %s\n"

#~ msgid "[REF…] - Uninstall an application"
#~ msgstr "[REF…] - Eine Anwendung deinstallieren"

#~ msgid "Invalid deployed ref %s: "
#~ msgstr "Ungültige bereitgestellte Referenz %s: "

#~ msgid "Deployed ref %s kind does not match commit (%s)"
#~ msgstr ""
#~ "Bereitgestellte Referenz des Typs %s entspricht nicht dem Commit (%s)"

#~ msgid "Deployed ref %s name does not match commit (%s)"
#~ msgstr "Bereitgestellte Referenz namens %s entspricht nicht dem Commit (%s)"

#~ msgid "Deployed ref %s arch does not match commit (%s)"
#~ msgstr ""
#~ "Bereitgestellte Referenz der Architektur %s entspricht nicht dem Commit "
#~ "(%s)"

#, fuzzy
#~ msgid "Failed to determine parts from ref: %s"
#~ msgstr "Temporäre Datei konnte nicht geöffnet werden: %s"

#, fuzzy
#~ msgid "Invalid arch %s"
#~ msgstr "Ungültige Prozesskennung %s"

#, fuzzy
#~ msgid "Related ref '%s' is only partially installed"
#~ msgstr "Angeforderte Erweiterung »%s« ist nur teilweise installiert"

#, fuzzy
#~ msgid "Ref '%s' is only partially installed"
#~ msgstr "Angeforderte Erweiterung »%s« ist nur teilweise installiert"

#, fuzzy
#~ msgid "No such ref (%s, %s) in remote %s"
#~ msgstr "%s konnte nicht in entfernter Quelle %s gefunden werden"

#, fuzzy
#~ msgid "No flatpak cache in remote '%s' summary"
#~ msgstr "Kein Flatpak-Zwischenspeicher in Zusammenfassung entfernter Quelle"

#, fuzzy
#~ msgid "No such ref (%s, %s) in remote %s or elsewhere"
#~ msgstr "%s konnte nicht in entfernter Quelle %s gefunden werden"

#, fuzzy
#~ msgid "No summary found"
#~ msgstr "Kein Treffer für %s"

#~ msgid "Deployed metadata does not match commit"
#~ msgstr "Bereitgestellte Metadaten entsprechen nicht dem Commit"

#, fuzzy
#~ msgid "No repo metadata cached for remote '%s'"
#~ msgstr "Kein Flatpak-Zwischenspeicher in Zusammenfassung entfernter Quelle"

#, fuzzy
#~ msgid "No metadata branch for OCI"
#~ msgstr "Metadaten für einen Zweig ausgeben"

#, fuzzy
#~ msgid "Invalid group: %d"
#~ msgstr "Ungültige Prozesskennung %s"

#, fuzzy
#~ msgid "Warning: Can't find %s metadata for dependencies: %s"
#~ msgstr ""
#~ "Warnung: Zusätzliche Metadaten für »%s« konnten nicht aktualisiert "
#~ "werden: %s\n"

#~ msgid "Not running as root, may be unable to enter namespace"
#~ msgstr ""
#~ "Wird nicht mit Root-Rechten ausgeführt, Betreten des Namensraums könnte "
#~ "nicht möglich sein"

#, fuzzy
#~ msgid "Default system installation"
#~ msgstr "Systemweite Installationen anzeigen"

#~ msgid "No url specified in flatpakrepo file"
#~ msgstr "In der flatpakrepo-Datei ist keine Adresse angegeben"

#, fuzzy
#~ msgid "%s branch already installed"
#~ msgstr "%s Zweig %s wurde bereits installiert"

#~ msgid "%s branch %s not installed"
#~ msgstr "%s Zweig %s ist nicht installiert"

#~ msgid "0"
#~ msgstr "0"

#~ msgid "Print OSTree debug information during command processing"
#~ msgstr ""
#~ "OSTree-Fehlerdiagnoseinformationen während der Befehlsverarbeitung "
#~ "ausgeben"

#~ msgid "Show help options"
#~ msgstr "Hilfeoptionen anzeigen"

#, fuzzy
#~ msgid "Architecture"
#~ msgstr "Zu verwendende Architektur"

#~ msgid "Location:"
#~ msgstr "Ort:"

#, fuzzy
#~ msgid "Installing for user: %s from %s\n"
#~ msgstr "Installieren: %s von %s\n"

#~ msgid "Installing: %s from %s\n"
#~ msgstr "Installieren: %s von %s\n"

#, fuzzy
#~ msgid "Updating for user: %s from %s\n"
#~ msgstr "Aktualisieren: %s von %s\n"

#~ msgid "Updating: %s from %s\n"
#~ msgstr "Aktualisieren: %s von %s\n"

#, fuzzy
#~ msgid "Installing for user: %s from bundle %s\n"
#~ msgstr "Installieren: %s von Bündel %s\n"

#~ msgid "Installing: %s from bundle %s\n"
#~ msgstr "Installieren: %s von Bündel %s\n"

#, fuzzy
#~ msgid "Uninstalling for user: %s\n"
#~ msgstr "Installieren: %s\n"

#~ msgid "No updates.\n"
#~ msgstr "Keine Aktualisierungen.\n"

#~ msgid "Now at %s.\n"
#~ msgstr "Jetzt bei %s.\n"

#, fuzzy
#~ msgid "new file access"
#~ msgstr ""
#~ "\n"
#~ " Dateizugriff verwalten"

#, fuzzy
#~ msgid "file access"
#~ msgstr ""
#~ "\n"
#~ " Dateizugriff verwalten"

#, fuzzy
#~ msgid "new system dbus access"
#~ msgstr "Systembus-Aufrufe protokollieren"

#, fuzzy
#~ msgid "system dbus access"
#~ msgstr "Systembus-Aufrufe protokollieren"

#, fuzzy
#~ msgid "Invalid .flatpakref"
#~ msgstr "Ungültiger GPG-Schlüssel"

#, fuzzy
#~ msgid "Authentication is required to install $(ref) from $(origin)"
#~ msgstr "Legitimierung wird benötigt, um Software zu installieren"

#, fuzzy
#~ msgid "Authentication is required to update $(ref) from $(origin)"
#~ msgstr ""
#~ "Legitimierung wird benötigt, um Info zu entfernter Quelle zu aktualisieren"

#, fuzzy
#~ msgid "Authentication is required to update the remote $(remote)"
#~ msgstr ""
#~ "Legitimierung wird benötigt, um Info zu entfernter Quelle zu aktualisieren"

#, fuzzy
#~ msgid "Authentication is required to modify the remote $(remote)"
#~ msgstr ""
#~ "Legitimierung wird benötigt, um Info zu entfernter Quelle zu aktualisieren"

#, fuzzy
#~ msgid "Authentication is required to configure the remote $(remote)"
#~ msgstr ""
#~ "Legitimierung wird benötigt, um die Softwarequellen zu konfigurieren"

#, fuzzy
#~ msgid "Runtime Branch"
#~ msgstr "Laufzeitumgebung:"

#, fuzzy
#~ msgid "Runtime Commit"
#~ msgstr "Aktiver Commit"

#~ msgid "Unknown command '%s'"
#~ msgstr "Unbekannter Befehl »%s«"

#, fuzzy
#~ msgid "Migrating %s to %s\n"
#~ msgstr "Aktualisieren: %s von %s\n"

#, fuzzy
#~ msgid "Error during migration: %s\n"
#~ msgstr "Fehler bei der Suche nach dem entfernten %s: %s"

#, fuzzy
#~ msgid "Redirect collection ID: %s\n"
#~ msgstr "Sammlungskennung"

#~ msgid "Invalid sha256 for extra data uri %s"
#~ msgstr "Ungültiges sha256 für die Adresse %s der Extradaten"

#~ msgid "Invalid sha256 for extra data"
#~ msgstr "Ungültige sha256 für zusätzliche Daten"

#~ msgid "Add OCI registry"
#~ msgstr "OCI-Registrierung hinzufügen"

#~ msgid "No ref information available in repository"
#~ msgstr "Keine Referenz-Informationen im Softwarebestand verfügbar"

#, fuzzy
#~| msgid "Found in several remotes:\n"
#~ msgid "Found in remote %s\n"
#~ msgstr "In verschiedenen fernen Quellen gefunden:\n"

#~ msgid "Found in remote %s, do you want to install it?"
#~ msgstr "In entfernter Quelle %s gefunden, wollen Sie es installieren?"

#~ msgid "Found in several remotes:\n"
#~ msgstr "In verschiedenen fernen Quellen gefunden:\n"

#~ msgid "The required runtime %s was not found in a configured remote.\n"
#~ msgstr ""
#~ "Die erforderliche Laufzeit %s wurde in keiner konfigurierten entfernten "
#~ "Quelle gefunden.\n"

#~ msgid "%s already installed, skipping\n"
#~ msgstr "%s ist bereits installiert, wird übersprungen\n"

#~ msgid "One or more operations failed"
#~ msgstr "Ein oder mehrere Vorgänge sind fehlgeschlagen"

#~ msgid "Remote title not set"
#~ msgstr "Entfernter Titel nicht gesetzt"

#~ msgid "Remote default-branch not set"
#~ msgstr "Vorgabe-Zweig für ferne Quelle nicht definiert"

===== ./po/kk.po =====
# Kazakh translation for flatpak.
# Copyright (C) 2026 flatpak's COPYRIGHT HOLDER
# This file is distributed under the same license as the flatpak package.
# Baurzhan Muftakhidinov <baurthefirst@gmail.com>,  2026.
#
msgid ""
msgstr ""
"Project-Id-Version: flatpak main\n"
"Report-Msgid-Bugs-To: https://github.com/flatpak/flatpak/issues\n"
"POT-Creation-Date: 2026-05-27 16:39+0200\n"
"PO-Revision-Date: 2026-03-29 22:26+0500\n"
"Last-Translator: Baurzhan Muftakhidinov <baurthefirst@gmail.com>\n"
"Language-Team: Kazakh\n"
"Language: kk\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
"X-Generator: Poedit 3.9\n"

#: app/flatpak-builtins-build-bundle.c:59
msgid "Export runtime instead of app"
msgstr "Қолданба орнына орындалу ортасын экспорттау"

#: app/flatpak-builtins-build-bundle.c:60
msgid "Arch to bundle for"
msgstr "Дестелеуге арналған архитектура"

#: app/flatpak-builtins-build-bundle.c:60
#: app/flatpak-builtins-build-export.c:62 app/flatpak-builtins-build-init.c:53
#: app/flatpak-builtins-build-sign.c:42 app/flatpak-builtins-create-usb.c:46
#: app/flatpak-builtins-info.c:55 app/flatpak-builtins-install.c:67
#: app/flatpak-builtins-list.c:50 app/flatpak-builtins-make-current.c:38
#: app/flatpak-builtins-remote-info.c:54 app/flatpak-builtins-remote-ls.c:56
#: app/flatpak-builtins-run.c:158 app/flatpak-builtins-search.c:37
#: app/flatpak-builtins-uninstall.c:54 app/flatpak-builtins-update.c:56
msgid "ARCH"
msgstr "АРХ"

#: app/flatpak-builtins-build-bundle.c:61
msgid "URL for repo"
msgstr "Репозиторий үшін URL"

#: app/flatpak-builtins-build-bundle.c:61
#: app/flatpak-builtins-build-bundle.c:62
#: app/flatpak-builtins-build-update-repo.c:68
#: app/flatpak-builtins-build-update-repo.c:72
#: app/flatpak-builtins-build-update-repo.c:73
#: app/flatpak-builtins-history.c:69 app/flatpak-builtins-remote-add.c:80
#: app/flatpak-builtins-remote-add.c:81 app/flatpak-builtins-remote-add.c:85
#: app/flatpak-builtins-remote-list.c:53
#: app/flatpak-builtins-remote-modify.c:70
#: app/flatpak-builtins-remote-modify.c:85
#: app/flatpak-builtins-remote-modify.c:86
#: app/flatpak-builtins-remote-modify.c:90
msgid "URL"
msgstr "URL"

#: app/flatpak-builtins-build-bundle.c:62
msgid "URL for runtime flatpakrepo file"
msgstr "Орындалу ортасының flatpakrepo файлы үшін URL"

#: app/flatpak-builtins-build-bundle.c:63
msgid "Add GPG key from FILE (- for stdin)"
msgstr "ФАЙЛ-дан GPG кілтін қосу (stdin үшін -)"

#: app/flatpak-builtins-build-bundle.c:63 app/flatpak-builtins-build.c:54
#: app/flatpak-builtins-build-export.c:67
#: app/flatpak-builtins-build-update-repo.c:83
#: app/flatpak-builtins-install.c:81 app/flatpak-builtins-remote-add.c:84
#: app/flatpak-builtins-remote-add.c:86 app/flatpak-builtins-remote-modify.c:89
#: app/flatpak-builtins-remote-modify.c:92
msgid "FILE"
msgstr "ФАЙЛ"

#: app/flatpak-builtins-build-bundle.c:64
msgid "GPG Key ID to sign the OCI image with"
msgstr "OCI бейнесіне қол қою үшін GPG кілт ID-і"

#: app/flatpak-builtins-build-bundle.c:64
#: app/flatpak-builtins-build-commit-from.c:68
#: app/flatpak-builtins-build-export.c:68
#: app/flatpak-builtins-build-import-bundle.c:49
#: app/flatpak-builtins-build-sign.c:44
#: app/flatpak-builtins-build-update-repo.c:84
msgid "KEY-ID"
msgstr "КІЛТ-ID"

#: app/flatpak-builtins-build-bundle.c:65
#: app/flatpak-builtins-build-commit-from.c:69
#: app/flatpak-builtins-build-export.c:71
#: app/flatpak-builtins-build-import-bundle.c:50
#: app/flatpak-builtins-build-sign.c:45
#: app/flatpak-builtins-build-update-repo.c:85
msgid "GPG Homedir to use when looking for keyrings"
msgstr "Кілттерді іздеу үшін қолданылатын GPG үй бумасы"

#: app/flatpak-builtins-build-bundle.c:65
#: app/flatpak-builtins-build-commit-from.c:69
#: app/flatpak-builtins-build-export.c:71
#: app/flatpak-builtins-build-import-bundle.c:50
#: app/flatpak-builtins-build-sign.c:45
#: app/flatpak-builtins-build-update-repo.c:85
msgid "HOMEDIR"
msgstr "ҮЙ-БУМАСЫ"

#: app/flatpak-builtins-build-bundle.c:66
msgid "OSTree commit to create a delta bundle from"
msgstr "Дельта дестесін жасауға арналған OSTree коммиті"

#: app/flatpak-builtins-build-bundle.c:66 app/flatpak-builtins-remote-info.c:55
#: app/flatpak-builtins-update.c:57
msgid "COMMIT"
msgstr "КОММИТ"

#: app/flatpak-builtins-build-bundle.c:67
msgid "Export oci image instead of flatpak bundle"
msgstr "Flatpak дестесінің орнына oci бейнесін экспорттау"

#: app/flatpak-builtins-build-bundle.c:70
msgid "How to compress OCI image layers (default: gzip)"
msgstr "OCI бейне қабаттарын қалай сығу керек (бастапқы: gzip)"

#: app/flatpak-builtins-build-bundle.c:634
msgid ""
"LOCATION FILENAME NAME [BRANCH] - Create a single file bundle from a local "
"repository"
msgstr ""
"ОРНЫ ФАЙЛ-АТЫ АТЫ [ТАРМАҚ] - Жергілікті репозиторийден бір файлдық десте "
"жасау"

#: app/flatpak-builtins-build-bundle.c:641
msgid "LOCATION, FILENAME and NAME must be specified"
msgstr "ОРНЫ, ФАЙЛ-АТЫ және АТЫ көрсетілуі тиіс"

#: app/flatpak-builtins-build-bundle.c:644
#: app/flatpak-builtins-build-export.c:844
#: app/flatpak-builtins-build-import-bundle.c:136
#: app/flatpak-builtins-build-init.c:217 app/flatpak-builtins-build-sign.c:76
#: app/flatpak-builtins-document-export.c:112
#: app/flatpak-builtins-document-info.c:75
#: app/flatpak-builtins-document-list.c:191
#: app/flatpak-builtins-document-unexport.c:70
#: app/flatpak-builtins-history.c:482 app/flatpak-builtins-info.c:130
#: app/flatpak-builtins-install.c:181 app/flatpak-builtins-install.c:234
#: app/flatpak-builtins-install.c:298 app/flatpak-builtins-list.c:419
#: app/flatpak-builtins-make-current.c:72 app/flatpak-builtins-override.c:73
#: app/flatpak-builtins-permission-list.c:162
#: app/flatpak-builtins-permission-remove.c:132
#: app/flatpak-builtins-remote-add.c:323
#: app/flatpak-builtins-remote-delete.c:68
#: app/flatpak-builtins-remote-list.c:241 app/flatpak-builtins-remote-ls.c:407
msgid "Too many arguments"
msgstr "Аргументтер саны тым көп"

#: app/flatpak-builtins-build-bundle.c:659
#: app/flatpak-builtins-build-commit-from.c:338
#: app/flatpak-builtins-build-commit-from.c:351
#: app/flatpak-builtins-build-import-bundle.c:145
#, c-format
msgid "'%s' is not a valid repository"
msgstr "'%s' жарамды репозиторий емес"

#: app/flatpak-builtins-build-bundle.c:663
#, c-format
msgid "'%s' is not a valid repository: "
msgstr "'%s' жарамды репозиторий емес: "

#: app/flatpak-builtins-build-bundle.c:674 app/flatpak-builtins-build-sign.c:88
#: common/flatpak-dir.c:14293
#, c-format
msgid "'%s' is not a valid name: %s"
msgstr "'%s' жарамды атау емес: %s"

#: app/flatpak-builtins-build-bundle.c:677
#: app/flatpak-builtins-build-export.c:865 app/flatpak-builtins-build-sign.c:91
#: common/flatpak-dir.c:14299
#, c-format
msgid "'%s' is not a valid branch name: %s"
msgstr "'%s' жарамды тармақ атауы емес: %s"

#: app/flatpak-builtins-build-bundle.c:691
#: app/flatpak-builtins-build-import-bundle.c:149
#: app/flatpak-builtins-build-init.c:281
#, c-format
msgid "'%s' is not a valid filename"
msgstr "'%s' жарамды файл атауы емес"

#: app/flatpak-builtins-build-bundle.c:706
msgid "--oci-layer-compress value must be gzip or zstd"
msgstr "--oci-layer-compress мәні gzip немесе zstd болуы тиіс"

#: app/flatpak-builtins-build.c:49
msgid "Use Platform runtime rather than Sdk"
msgstr "Sdk орнына Platform орындалу ортасын қолдану"

#: app/flatpak-builtins-build.c:50
msgid "Make destination readonly"
msgstr "Мақсатты тек оқу үшін ету"

#: app/flatpak-builtins-build.c:51
msgid "Add bind mount"
msgstr "Байланыстырылған тіркеуді қосу"

#: app/flatpak-builtins-build.c:51
msgid "DEST=SRC"
msgstr "МАҚСАТ=ҚАЙНАР КӨЗ"

#: app/flatpak-builtins-build.c:52
msgid "Start build in this directory"
msgstr "Құрастыруды осы бумада бастау"

#: app/flatpak-builtins-build.c:52 app/flatpak-builtins-build.c:53
#: app/flatpak-builtins-build-init.c:64 app/flatpak-builtins-run.c:160
msgid "DIR"
msgstr "БУМА"

#: app/flatpak-builtins-build.c:53
msgid "Where to look for custom sdk dir (defaults to 'usr')"
msgstr "Арнайы sdk бумасын іздейтін орын (бастапқысы 'usr')"

#: app/flatpak-builtins-build.c:54 app/flatpak-builtins-build-export.c:67
msgid "Use alternative file for the metadata"
msgstr "Метадеректер үшін балама файлды қолдану"

#: app/flatpak-builtins-build.c:55 app/flatpak-builtins-run.c:177
msgid "Kill processes when the parent process dies"
msgstr "Аталық процесс тоқтағанда процестерді жою"

#: app/flatpak-builtins-build.c:56
msgid "Export application homedir directory to build"
msgstr "Құрастыру үшін қолданбаның үй бумасын экспорттау"

#: app/flatpak-builtins-build.c:57 app/flatpak-builtins-run.c:165
msgid "Log session bus calls"
msgstr "Сессия шинасының шақыруларын журналдау"

#: app/flatpak-builtins-build.c:58 app/flatpak-builtins-run.c:166
msgid "Log system bus calls"
msgstr "Жүйелік шина шақыруларын журналдау"

#: app/flatpak-builtins-build.c:262
msgid "DIRECTORY [COMMAND [ARGUMENT…]] - Build in directory"
msgstr "БУМА [КОМАНДА [АРГУМЕНТ…]] - Бумада құрастыру"

#: app/flatpak-builtins-build.c:285 app/flatpak-builtins-build-finish.c:656
msgid "DIRECTORY must be specified"
msgstr "БУМА көрсетілуі тиіс"

#: app/flatpak-builtins-build.c:296 app/flatpak-builtins-build-export.c:887
#, c-format
msgid "Build directory %s not initialized, use flatpak build-init"
msgstr ""
"%s құрастыру бумасы инициализацияланбаған, flatpak build-init қолданыңыз"

#: app/flatpak-builtins-build.c:315
msgid "metadata invalid, not application or runtime"
msgstr "метадеректер жарамсыз, қолданба немесе орындалу ортасы емес"

#: app/flatpak-builtins-build.c:446
#, c-format
msgid "No extension point matching %s in %s"
msgstr "%2$s ішінде %1$s сәйкес келетін кеңейту нүктесі жоқ"

#: app/flatpak-builtins-build.c:635
#, c-format
msgid "Missing '=' in bind mount option '%s'"
msgstr "'%s' байланыстырылған тіркеу опциясында '=' жоқ"

#: app/flatpak-builtins-build.c:679 common/flatpak-run.c:3961
#, c-format
msgid "Unable to start app"
msgstr "Қолданбаны іске қосу мүмкін емес"

#: app/flatpak-builtins-build-commit-from.c:58
msgid "Source repo dir"
msgstr "Қайнар көз репозиторий бумасы"

#: app/flatpak-builtins-build-commit-from.c:58
msgid "SRC-REPO"
msgstr "ҚАЙНАР-КӨЗ-РЕПОЗИТОРИЙІ"

#: app/flatpak-builtins-build-commit-from.c:59
msgid "Source repo ref"
msgstr "Қайнар көз репозиторий сілтемесі"

#: app/flatpak-builtins-build-commit-from.c:59
msgid "SRC-REF"
msgstr "ҚАЙНАР-КӨЗ-СІЛТЕМЕСІ"

#: app/flatpak-builtins-build-commit-from.c:64
#: app/flatpak-builtins-build-export.c:60
msgid "One line subject"
msgstr "Бір жолдық тақырып"

#: app/flatpak-builtins-build-commit-from.c:64
#: app/flatpak-builtins-build-export.c:60
msgid "SUBJECT"
msgstr "ТАҚЫРЫП"

#: app/flatpak-builtins-build-commit-from.c:65
#: app/flatpak-builtins-build-export.c:61
msgid "Full description"
msgstr "Толық сипаттама"

#: app/flatpak-builtins-build-commit-from.c:65
#: app/flatpak-builtins-build-export.c:61
msgid "BODY"
msgstr "ДЕНЕСІ"

#: app/flatpak-builtins-build-commit-from.c:66
#: app/flatpak-builtins-build-export.c:64
#: app/flatpak-builtins-build-import-bundle.c:51
msgid "Update the appstream branch"
msgstr "appstream тармағын жаңарту"

#: app/flatpak-builtins-build-commit-from.c:67
#: app/flatpak-builtins-build-export.c:65
#: app/flatpak-builtins-build-import-bundle.c:52
#: app/flatpak-builtins-build-update-repo.c:87
msgid "Don't update the summary"
msgstr "Жиынтықты жаңартпау"

#: app/flatpak-builtins-build-commit-from.c:68
#: app/flatpak-builtins-build-export.c:68
#: app/flatpak-builtins-build-import-bundle.c:49
#: app/flatpak-builtins-build-sign.c:44
msgid "GPG Key ID to sign the commit with"
msgstr "Коммитке қол қою үшін GPG кілт ID-і"

#: app/flatpak-builtins-build-commit-from.c:70
#: app/flatpak-builtins-build-export.c:73
msgid "Mark build as end-of-life"
msgstr "Құрастыруды қолдау мерзімі аяқталған деп белгілеу"

#: app/flatpak-builtins-build-commit-from.c:70
#: app/flatpak-builtins-build-export.c:73
msgid "REASON"
msgstr "СЕБЕП"

#: app/flatpak-builtins-build-commit-from.c:71
msgid ""
"Mark refs matching the OLDID prefix as end-of-life, to be replaced with the "
"given NEWID"
msgstr ""
"OLDID префиксіне сәйкес келетін сілтемелерді қолдау мерзімі аяқталған деп "
"белгілеп, берілген NEWID-пен алмастыру"

#: app/flatpak-builtins-build-commit-from.c:71
msgid "OLDID=NEWID"
msgstr "ЕСКІ-ID=ЖАҢА-ID"

#: app/flatpak-builtins-build-commit-from.c:72
#: app/flatpak-builtins-build-export.c:75
msgid "Set type of token needed to install this commit"
msgstr "Осы коммитті орнату үшін қажетті токен түрін орнату"

#: app/flatpak-builtins-build-commit-from.c:72
#: app/flatpak-builtins-build-export.c:75
msgid "VAL"
msgstr "МӘН"

#: app/flatpak-builtins-build-commit-from.c:73
msgid "Override the timestamp of the commit (NOW for current time)"
msgstr "Коммиттің уақыт белгісін қайта анықтау (ағымдағы уақыт үшін NOW)"

#: app/flatpak-builtins-build-commit-from.c:73
#: app/flatpak-builtins-build-export.c:76
msgid "TIMESTAMP"
msgstr "УАҚЫТ_МӘНІ"

#: app/flatpak-builtins-build-commit-from.c:75
#: app/flatpak-builtins-build-export.c:80
#: app/flatpak-builtins-build-import-bundle.c:53
#: app/flatpak-builtins-build-update-repo.c:97
msgid "Don't generate a summary index"
msgstr "Жиынтық индексін жасамау"

#: app/flatpak-builtins-build-commit-from.c:278
msgid "DST-REPO [DST-REF…] - Make a new commit from existing commits"
msgstr "МАҚСАТ-РЕПО [МАҚСАТ-СІЛТЕМЕ…] - Бар коммиттерден жаңа коммит жасау"

#: app/flatpak-builtins-build-commit-from.c:285
msgid "DST-REPO must be specified"
msgstr "МАҚСАТ-РЕПО көрсетілуі тиіс"

#: app/flatpak-builtins-build-commit-from.c:293
msgid ""
"If --src-repo is not specified, exactly one destination ref must be specified"
msgstr "Егер --src-repo көрсетілмесе, дәл бір мақсатты сілтеме көрсетілуі тиіс"

#: app/flatpak-builtins-build-commit-from.c:296
msgid ""
"If --src-ref is specified, exactly one destination ref must be specified"
msgstr "Егер --src-ref көрсетілсе, дәл бір мақсатты сілтеме көрсетілуі тиіс"

#: app/flatpak-builtins-build-commit-from.c:299
msgid "Either --src-repo or --src-ref must be specified"
msgstr "Не --src-repo, не --src-ref көрсетілуі тиіс"

#: app/flatpak-builtins-build-commit-from.c:315
msgid "Invalid argument format of use  --end-of-life-rebase=OLDID=NEWID"
msgstr ""
"--end-of-life-rebase=OLDID=NEWID қолданылуының аргумент пішімі жарамсыз"

#: app/flatpak-builtins-build-commit-from.c:321
#: app/flatpak-builtins-build-commit-from.c:324
#, c-format
msgid "Invalid name %s in --end-of-life-rebase"
msgstr "--end-of-life-rebase ішіндегі %s атауы жарамсыз"

#: app/flatpak-builtins-build-commit-from.c:333
#: app/flatpak-builtins-build-export.c:1092
#, c-format
msgid "Could not parse '%s'"
msgstr "'%s' талдау мүмкін емес"

#: app/flatpak-builtins-build-commit-from.c:498
msgid "Can't commit from partial source commit"
msgstr "Жартылай қайнар көз коммитінен коммит жасау мүмкін емес"

#: app/flatpak-builtins-build-commit-from.c:503
#, c-format
msgid "%s: no change\n"
msgstr "%s: өзгеріс жоқ\n"

#: app/flatpak-builtins-build-export.c:62
msgid "Architecture to export for (must be host compatible)"
msgstr "Экспортталатын архитектура (хостпен үйлесімді болуы тиіс)"

#: app/flatpak-builtins-build-export.c:63
msgid "Commit runtime (/usr), not /app"
msgstr "/app емес, орындалу ортасын (/usr) коммиттеу"

#: app/flatpak-builtins-build-export.c:66
msgid "Use alternative directory for the files"
msgstr "Файлдар үшін балама буманы қолдану"

#: app/flatpak-builtins-build-export.c:66
msgid "SUBDIR"
msgstr "ІШКІ-БУМА"

#: app/flatpak-builtins-build-export.c:69
msgid "Files to exclude"
msgstr "Шығарылатын файлдар"

#: app/flatpak-builtins-build-export.c:69
#: app/flatpak-builtins-build-export.c:70
#: app/flatpak-builtins-build-update-repo.c:90
msgid "PATTERN"
msgstr "ШАБЛОН"

#: app/flatpak-builtins-build-export.c:70
msgid "Excluded files to include"
msgstr "Шығарылған файлдар ішінен қосылатындары"

#: app/flatpak-builtins-build-export.c:74
msgid "Mark build as end-of-life, to be replaced with the given ID"
msgstr ""
"Құрастыруды қолдау мерзімі аяқталған деп белгілеп, берілген ID-пен алмастыру"

#: app/flatpak-builtins-build-export.c:74
#: app/flatpak-builtins-document-list.c:49 app/flatpak-cli-transaction.c:1427
msgid "ID"
msgstr "ID"

#: app/flatpak-builtins-build-export.c:76
msgid "Override the timestamp of the commit"
msgstr "Коммиттің уақыт белгісін қайта анықтау"

#: app/flatpak-builtins-build-export.c:77
#: app/flatpak-builtins-build-update-repo.c:75
#: app/flatpak-builtins-remote-add.c:83 app/flatpak-builtins-remote-list.c:54
#: app/flatpak-builtins-remote-modify.c:88
msgid "Collection ID"
msgstr "Коллекция ID-і"

#: app/flatpak-builtins-build-export.c:472
#, c-format
msgid "WARNING: Error running desktop-file-validate: %s\n"
msgstr "ЕСКЕРТУ: desktop-file-validate орындау қатесі: %s\n"

#: app/flatpak-builtins-build-export.c:480
#, c-format
msgid "WARNING: Error reading from desktop-file-validate: %s\n"
msgstr "ЕСКЕРТУ: desktop-file-validate-тен оқу қатесі: %s\n"

#: app/flatpak-builtins-build-export.c:486
#, c-format
msgid "WARNING: Failed to validate desktop file %s: %s\n"
msgstr "ЕСКЕРТУ: %s жұмыс үстелі файлын тексеру сәтсіз аяқталды: %s\n"

#: app/flatpak-builtins-build-export.c:513
#, c-format
msgid "WARNING: Can't find Exec key in %s: %s\n"
msgstr "ЕСКЕРТУ: %s ішінен Exec кілті табылмады: %s\n"

#: app/flatpak-builtins-build-export.c:521
#: app/flatpak-builtins-build-export.c:614
#, c-format
msgid "WARNING: Binary not found for Exec line in %s: %s\n"
msgstr "ЕСКЕРТУ: %s ішіндегі Exec жолы үшін бинарлы файл табылмады: %s\n"

#: app/flatpak-builtins-build-export.c:529
#, c-format
msgid "WARNING: Icon not matching app id in %s: %s\n"
msgstr "ЕСКЕРТУ: %s ішіндегі таңбаша қолданба ID-іне сәйкес келмейді: %s\n"

#: app/flatpak-builtins-build-export.c:552
#, c-format
msgid "WARNING: Icon referenced in desktop file but not exported: %s\n"
msgstr ""
"ЕСКЕРТУ: Таңбаша жұмыс үстелі файлында сілтенген, бірақ экспортталмаған: %s\n"

#: app/flatpak-builtins-build-export.c:719
#, c-format
msgid "Invalid uri type %s, only http/https supported"
msgstr "Жарамсыз uri түрі %s, тек http/https қолдау көрсетіледі"

#: app/flatpak-builtins-build-export.c:737
#, c-format
msgid "Unable to find basename in %s, specify a name explicitly"
msgstr "%s ішінен базалық атау табылмады, атауды анық көрсетіңіз"

#: app/flatpak-builtins-build-export.c:746
#, c-format
msgid "No slashes allowed in extra data name"
msgstr "Қосымша деректер атауында қиғаш сызықтарға рұқсат жоқ"

#: app/flatpak-builtins-build-export.c:758
#, c-format
msgid "Invalid format for sha256 checksum: '%s'"
msgstr "sha256 бақылау сомасы үшін жарамсыз пішім: '%s'"

#: app/flatpak-builtins-build-export.c:768
#, c-format
msgid "Extra data sizes of zero not supported"
msgstr "Нөлдік қосымша деректер өлшемдеріне қолдау көрсетілмейді"

#: app/flatpak-builtins-build-export.c:830
msgid ""
"LOCATION DIRECTORY [BRANCH] - Create a repository from a build directory"
msgstr "ОРНЫ БУМА [ТАРМАҚ] - Құрастыру бумасынан репозиторий жасау"

#: app/flatpak-builtins-build-export.c:838
msgid "LOCATION and DIRECTORY must be specified"
msgstr "ОРНЫ және БУМА көрсетілуі тиіс"

#: app/flatpak-builtins-build-export.c:859
#: app/flatpak-builtins-remote-add.c:327
#, c-format
msgid "‘%s’ is not a valid collection ID: %s"
msgstr "‘%s’ жарамды коллекция ID-і емес: %s"

#: app/flatpak-builtins-build-export.c:904
#: app/flatpak-builtins-build-finish.c:684
msgid "No name specified in the metadata"
msgstr "Метадеректерде ешқандай атау көрсетілмеген"

#: app/flatpak-builtins-build-export.c:1166
#, c-format
msgid "Commit: %s\n"
msgstr "Коммит: %s\n"

#: app/flatpak-builtins-build-export.c:1167
#, c-format
msgid "Metadata Total: %u\n"
msgstr "Метадеректер жиынтығы: %u\n"

#: app/flatpak-builtins-build-export.c:1168
#, c-format
msgid "Metadata Written: %u\n"
msgstr "Жазылған метадеректер: %u\n"

#: app/flatpak-builtins-build-export.c:1169
#, c-format
msgid "Content Total: %u\n"
msgstr "Мазмұн жиынтығы: %u\n"

#: app/flatpak-builtins-build-export.c:1170
#, c-format
msgid "Content Written: %u\n"
msgstr "Жазылған мазмұн: %u\n"

#: app/flatpak-builtins-build-export.c:1171
#, c-format
msgid "Content Bytes Written:"
msgstr "Жазылған мазмұн байттары:"

#: app/flatpak-builtins-build-finish.c:52
msgid "Command to set"
msgstr "Орнатылатын команда"

#: app/flatpak-builtins-build-finish.c:52 app/flatpak-builtins-run.c:159
#: app/flatpak-main.c:209
msgid "COMMAND"
msgstr "КОМАНДА"

#: app/flatpak-builtins-build-finish.c:53
msgid "Flatpak version to require"
msgstr "Талап етілетін Flatpak нұсқасы"

#: app/flatpak-builtins-build-finish.c:53
msgid "MAJOR.MINOR.MICRO"
msgstr "MAJOR.MINOR.MICRO"

#: app/flatpak-builtins-build-finish.c:54
msgid "Don't process exports"
msgstr "Экспорттарды өңдемеу"

#: app/flatpak-builtins-build-finish.c:55
msgid "Extra data info"
msgstr "Қосымша деректер ақпараты"

#: app/flatpak-builtins-build-finish.c:56 app/flatpak-builtins-build-init.c:63
msgid "Add extension point info"
msgstr "Кеңейту нүктесі ақпаратын қосу"

#: app/flatpak-builtins-build-finish.c:56 app/flatpak-builtins-build-init.c:63
msgid "NAME=VARIABLE[=VALUE]"
msgstr "АТЫ=АЙНЫМАЛЫ[=МӘН]"

#: app/flatpak-builtins-build-finish.c:57
msgid "Remove extension point info"
msgstr "Кеңейту нүктесі ақпаратын өшіру"

#: app/flatpak-builtins-build-finish.c:57
#: app/flatpak-builtins-build-update-repo.c:79 app/flatpak-builtins-info.c:58
#: app/flatpak-builtins-remote-add.c:88 app/flatpak-builtins-remote-modify.c:94
#: app/flatpak-main.c:182
msgid "NAME"
msgstr "АТЫ"

#: app/flatpak-builtins-build-finish.c:58
msgid "Set extension priority (only for extensions)"
msgstr "Кеңейту басымдылығын орнату (тек кеңейтулер үшін)"

#: app/flatpak-builtins-build-finish.c:58
msgid "VALUE"
msgstr "МӘН"

#: app/flatpak-builtins-build-finish.c:59
msgid "Change the sdk used for the app"
msgstr "Қолданба үшін қолданылатын sdk-ны өзгерту"

#: app/flatpak-builtins-build-finish.c:59
msgid "SDK"
msgstr "SDK"

#: app/flatpak-builtins-build-finish.c:60
msgid "Change the runtime used for the app"
msgstr "Қолданба үшін қолданылатын орындалу ортасын өзгерту"

#: app/flatpak-builtins-build-finish.c:60 app/flatpak-builtins-build-init.c:54
#: app/flatpak-builtins-list.c:53 app/flatpak-builtins-remote-ls.c:58
#: app/flatpak-builtins-run.c:163
msgid "RUNTIME"
msgstr "ОРЫНДАЛУ_ОРТАСЫ"

#: app/flatpak-builtins-build-finish.c:61
msgid "Set generic metadata option"
msgstr "Жалпы метадеректер опциясын орнату"

#: app/flatpak-builtins-build-finish.c:61
msgid "GROUP=KEY[=VALUE]"
msgstr "ТОП=КІЛТ[=МӘН]"

#: app/flatpak-builtins-build-finish.c:62
msgid "Don't inherit permissions from runtime"
msgstr "Рұқсаттарды орындалу ортасынан мұраға алмау"

#: app/flatpak-builtins-build-finish.c:155
#, c-format
msgid "Not exporting %s, wrong extension\n"
msgstr "%s экспортталмайды, кеңейту қате\n"

#: app/flatpak-builtins-build-finish.c:163
#, c-format
msgid "Not exporting %s, non-allowed export filename\n"
msgstr "%s экспортталмайды, экспорттық файл атауына рұқсат жоқ\n"

#: app/flatpak-builtins-build-finish.c:167
#, c-format
msgid "Exporting %s\n"
msgstr "%s экспортталуда\n"

#: app/flatpak-builtins-build-finish.c:440
#, c-format
msgid "More than one executable found\n"
msgstr "Бірден көп орындалатын файл табылды\n"

#: app/flatpak-builtins-build-finish.c:451
#, c-format
msgid "Using %s as command\n"
msgstr "Команда ретінде %s қолданылуда\n"

#: app/flatpak-builtins-build-finish.c:456
#, c-format
msgid "No executable found\n"
msgstr "Орындалатын файл табылмады\n"

#: app/flatpak-builtins-build-finish.c:511
#, c-format
msgid "Invalid --require-version argument: %s"
msgstr "--require-version аргументі жарамсыз: %s"

#: app/flatpak-builtins-build-finish.c:543
#, c-format
msgid "Too few elements in --extra-data argument %s"
msgstr "--extra-data аргументіндегі элементтер тым аз: %s"

#: app/flatpak-builtins-build-finish.c:575
#, c-format
msgid ""
"Too few elements in --metadata argument %s, format should be "
"GROUP=KEY[=VALUE]]"
msgstr ""
"--metadata %s аргументіндегі элементтер тым аз, пішімі ТОП=КІЛТ[=МӘН] болуы "
"тиіс"

#: app/flatpak-builtins-build-finish.c:597
#: app/flatpak-builtins-build-init.c:458
#, c-format
msgid ""
"Too few elements in --extension argument %s, format should be "
"NAME=VAR[=VALUE]"
msgstr ""
"--extension %s аргументіндегі элементтер тым аз, пішімі АТЫ=АЙНЫМАЛЫ[=МӘН] "
"болуы тиіс"

#: app/flatpak-builtins-build-finish.c:603
#: app/flatpak-builtins-build-init.c:461
#, c-format
msgid "Invalid extension name %s"
msgstr "Кеңейту атауы жарамсыз: %s"

#: app/flatpak-builtins-build-finish.c:646
msgid "DIRECTORY - Finalize a build directory"
msgstr "БУМА - Құрастыру бумасын аяқтау"

#: app/flatpak-builtins-build-finish.c:668
#, c-format
msgid "Build directory %s not initialized"
msgstr "%s құрастыру бумасы инициализацияланбаған"

#: app/flatpak-builtins-build-finish.c:689
#, c-format
msgid "Build directory %s already finalized"
msgstr "%s құрастыру бумасы қазірдің өзінде аяқталған"

#: app/flatpak-builtins-build-finish.c:702
#, c-format
msgid "Please review the exported files and the metadata\n"
msgstr "Экспортталған файлдар мен метадеректерді қарап шығыңыз\n"

#: app/flatpak-builtins-build-import-bundle.c:47
msgid "Override the ref used for the imported bundle"
msgstr "Импортталған десте үшін қолданылатын сілтемені қайта анықтау"

#: app/flatpak-builtins-build-import-bundle.c:47
msgid "REF"
msgstr "СІЛТЕМЕ"

#: app/flatpak-builtins-build-import-bundle.c:48
msgid "Import oci image instead of flatpak bundle"
msgstr "Flatpak дестесінің орнына oci бейнесін импорттау"

#: app/flatpak-builtins-build-import-bundle.c:77
#: app/flatpak-builtins-build-import-bundle.c:105
#, c-format
msgid "Importing %s (%s)\n"
msgstr "%s (%s) импортталуда\n"

#: app/flatpak-builtins-build-import-bundle.c:126
msgid "LOCATION FILENAME - Import a file bundle into a local repository"
msgstr "ОРНЫ ФАЙЛ-АТЫ - Жергілікті репозиторийге файлдық дестені импорттау"

#: app/flatpak-builtins-build-import-bundle.c:133
msgid "LOCATION and FILENAME must be specified"
msgstr "ОРНЫ және ФАЙЛ-АТЫ көрсетілуі тиіс"

#: app/flatpak-builtins-build-init.c:53 app/flatpak-builtins-info.c:55
#: app/flatpak-builtins-run.c:158
msgid "Arch to use"
msgstr "Қолданылатын архитектура"

#: app/flatpak-builtins-build-init.c:54
msgid "Initialize var from named runtime"
msgstr "var-ды аталған орындалу ортасынан инициализациялау"

#: app/flatpak-builtins-build-init.c:55
msgid "Initialize apps from named app"
msgstr "Қолданбаларды аталған қолданбадан инициализациялау"

#: app/flatpak-builtins-build-init.c:55
msgid "APP"
msgstr "ҚОЛДАНБА"

#: app/flatpak-builtins-build-init.c:56
msgid "Specify version for --base"
msgstr "--base үшін нұсқаны көрсету"

#: app/flatpak-builtins-build-init.c:56 app/flatpak-builtins-run.c:164
msgid "VERSION"
msgstr "НҰСҚА"

#: app/flatpak-builtins-build-init.c:57
msgid "Include this base extension"
msgstr "Осы базалық кеңейтуді қосу"

#: app/flatpak-builtins-build-init.c:57 app/flatpak-builtins-build-init.c:62
msgid "EXTENSION"
msgstr "КЕҢЕЙТУ"

#: app/flatpak-builtins-build-init.c:58
msgid "Extension tag to use if building extension"
msgstr "Егер кеңейту құрастырылса, қолданылатын кеңейту тегі"

#: app/flatpak-builtins-build-init.c:58
msgid "EXTENSION_TAG"
msgstr "КЕҢЕЙТУ_ТЕГІ"

#: app/flatpak-builtins-build-init.c:59
msgid "Initialize /usr with a writable copy of the sdk"
msgstr "/usr-ды sdk-ның жазуға болатын көшірмесімен инициализациялау"

#: app/flatpak-builtins-build-init.c:60
msgid "Specify the build type (app, runtime, extension)"
msgstr "Құрастыру түрін көрсету (app, runtime, extension)"

#: app/flatpak-builtins-build-init.c:60
msgid "TYPE"
msgstr "ТҮР"

#: app/flatpak-builtins-build-init.c:61
msgid "Add a tag"
msgstr "Тег қосу"

#: app/flatpak-builtins-build-init.c:61
msgid "TAG"
msgstr "ТЕГ"

#: app/flatpak-builtins-build-init.c:62
msgid "Include this sdk extension in /usr"
msgstr "/usr ішіне осы sdk кеңейтуін қосу"

#: app/flatpak-builtins-build-init.c:64
msgid "Where to store sdk (defaults to 'usr')"
msgstr "sdk сақталатын орын (бастапқысы 'usr')"

#: app/flatpak-builtins-build-init.c:65
msgid "Re-initialize the sdk/var"
msgstr "sdk/var-ды қайта инициализациялау"

#: app/flatpak-builtins-build-init.c:118
#, c-format
msgid "Requested extension %s/%s/%s is only partially installed"
msgstr "Сұралған %s/%s/%s кеңейтуі тек жартылай орнатылған"

#: app/flatpak-builtins-build-init.c:147
#, c-format
msgid "Requested extension %s/%s/%s not installed"
msgstr "Сұралған %s/%s/%s кеңейтуі орнатылмаған"

#: app/flatpak-builtins-build-init.c:207
msgid ""
"DIRECTORY APPNAME SDK RUNTIME [BRANCH] - Initialize a directory for building"
msgstr ""
"БУМА ҚОЛДАНБА_АТАУЫ SDK ОРЫНДАЛУ_ОРТАСЫ [ТАРМАҚ] - Құрастыру үшін буманы "
"инициализациялау"

#: app/flatpak-builtins-build-init.c:214
msgid "RUNTIME must be specified"
msgstr "ОРЫНДАЛУ_ОРТАСЫ көрсетілуі тиіс"

#: app/flatpak-builtins-build-init.c:235
#, c-format
msgid "'%s' is not a valid build type name, use app, runtime or extension"
msgstr ""
"'%s' жарамды құрастыру түрі емес, app, runtime немесе extension қолданыңыз"

#: app/flatpak-builtins-build-init.c:241 app/flatpak-builtins-override.c:79
#, c-format
msgid "'%s' is not a valid application name: %s"
msgstr "'%s' жарамды қолданба атауы емес: %s"

#: app/flatpak-builtins-build-init.c:295
#, c-format
msgid "Build directory %s already initialized"
msgstr "%s құрастыру бумасы қазірдің өзінде инициализацияланған"

#: app/flatpak-builtins-build-sign.c:42 app/flatpak-builtins-install.c:67
#: app/flatpak-builtins-remote-info.c:54
msgid "Arch to install for"
msgstr "Орнату архитектурасы"

#: app/flatpak-builtins-build-sign.c:43 app/flatpak-builtins-create-usb.c:48
#: app/flatpak-builtins-install.c:74 app/flatpak-builtins-remote-info.c:56
#: app/flatpak-builtins-uninstall.c:58 app/flatpak-builtins-update.c:64
msgid "Look for runtime with the specified name"
msgstr "Көрсетілген атауы бар орындалу ортасын іздеу"

#: app/flatpak-builtins-build-sign.c:66
msgid "LOCATION [ID [BRANCH]] - Sign an application or runtime"
msgstr "ОРНЫ [ID [ТАРМАҚ]] - Қолданбаға немесе орындалу ортасына қол қою"

#: app/flatpak-builtins-build-sign.c:73
#: app/flatpak-builtins-build-update-repo.c:499
#: app/flatpak-builtins-remote-add.c:320 app/flatpak-builtins-repo.c:739
msgid "LOCATION must be specified"
msgstr "ОРНЫ көрсетілуі тиіс"

#: app/flatpak-builtins-build-sign.c:94
msgid "No gpg key ids specified"
msgstr "GPG кілт ID-лері көрсетілмеген"

#: app/flatpak-builtins-build-update-repo.c:68
msgid "Redirect this repo to a new URL"
msgstr "Бұл репозиторийді жаңа URL-ге бағыттау"

#: app/flatpak-builtins-build-update-repo.c:69
msgid "A nice name to use for this repository"
msgstr "Бұл репозиторий үшін қолданылатын жақсы атау"

#: app/flatpak-builtins-build-update-repo.c:69
#: app/flatpak-builtins-remote-add.c:77 app/flatpak-builtins-remote-modify.c:82
msgid "TITLE"
msgstr "АТАУЫ"

#: app/flatpak-builtins-build-update-repo.c:70
msgid "A one-line comment for this repository"
msgstr "Бұл репозиторий үшін бір жолдық түсініктеме"

#: app/flatpak-builtins-build-update-repo.c:70
#: app/flatpak-builtins-remote-add.c:78 app/flatpak-builtins-remote-modify.c:83
msgid "COMMENT"
msgstr "ТҮСІНІКТЕМЕ"

#: app/flatpak-builtins-build-update-repo.c:71
msgid "A full-paragraph description for this repository"
msgstr "Бұл репозиторий үшін толық сипаттама"

#: app/flatpak-builtins-build-update-repo.c:71
#: app/flatpak-builtins-remote-add.c:79 app/flatpak-builtins-remote-modify.c:84
msgid "DESCRIPTION"
msgstr "СИПАТТАМА"

#: app/flatpak-builtins-build-update-repo.c:72
msgid "URL for a website for this repository"
msgstr "Бұл репозиторийдің веб-сайты үшін URL"

#: app/flatpak-builtins-build-update-repo.c:73
msgid "URL for an icon for this repository"
msgstr "Бұл репозиторийдің таңбашасы үшін URL"

#: app/flatpak-builtins-build-update-repo.c:74
msgid "Default branch to use for this repository"
msgstr "Осы репозиторий үшін бастапқы тармақ"

#: app/flatpak-builtins-build-update-repo.c:74
#: app/flatpak-builtins-remote-add.c:82 app/flatpak-builtins-remote-modify.c:87
#: app/flatpak-builtins-repo.c:713 app/flatpak-builtins-repo.c:714
#: app/flatpak-builtins-run.c:161
msgid "BRANCH"
msgstr "ТАРМАҚ"

#: app/flatpak-builtins-build-update-repo.c:75
#: app/flatpak-builtins-remote-add.c:83 app/flatpak-builtins-remote-modify.c:88
msgid "COLLECTION-ID"
msgstr "КОЛЛЕКЦИЯ-ID"

#. Translators: A sideload is when you install from a local USB drive rather than the Internet.
#: app/flatpak-builtins-build-update-repo.c:77
msgid ""
"Permanently deploy collection ID to client remote configurations, only for "
"sideload support"
msgstr ""
"Тек қатар жүктеуді қолдау үшін, коллекция ID-ін клиенттің қашықтағы "
"конфигурацияларына тұрақты орналастыру"

#: app/flatpak-builtins-build-update-repo.c:78
msgid "Permanently deploy collection ID to client remote configurations"
msgstr ""
"Коллекция ID-ін клиенттің қашықтағы конфигурацияларына тұрақты орналастыру"

#: app/flatpak-builtins-build-update-repo.c:79
msgid "Name of authenticator for this repository"
msgstr "Осы репозиторий үшін аутентификатор атауы"

#: app/flatpak-builtins-build-update-repo.c:80
msgid "Autoinstall authenticator for this repository"
msgstr "Осы репозиторий үшін аутентификаторды автоматты орнату"

#: app/flatpak-builtins-build-update-repo.c:81
msgid "Don't autoinstall authenticator for this repository"
msgstr "Осы репозиторий үшін аутентификаторды автоматты орнатпау"

#: app/flatpak-builtins-build-update-repo.c:82
#: app/flatpak-builtins-remote-add.c:89
msgid "Authenticator option"
msgstr "Аутентификатор опциясы"

#: app/flatpak-builtins-build-update-repo.c:82
#: app/flatpak-builtins-remote-add.c:89 app/flatpak-builtins-remote-modify.c:95
msgid "KEY=VALUE"
msgstr "КІЛТ=МӘН"

#: app/flatpak-builtins-build-update-repo.c:83
msgid "Import new default GPG public key from FILE"
msgstr "ФАЙЛ-дан жаңа бастапқы GPG ашық кілтін импорттау"

#: app/flatpak-builtins-build-update-repo.c:84
msgid "GPG Key ID to sign the summary with"
msgstr "Жиынтыққа қол қою үшін GPG кілт ID-і"

#: app/flatpak-builtins-build-update-repo.c:86
msgid "Generate delta files"
msgstr "Дельта файлдарын жасау"

#: app/flatpak-builtins-build-update-repo.c:88
msgid "Don't update the appstream branch"
msgstr "appstream тармағын жаңартпау"

#: app/flatpak-builtins-build-update-repo.c:89
msgid "Max parallel jobs when creating deltas (default: NUMCPUs)"
msgstr ""
"Дельталарды жасау кезіндегі максималды параллель жұмыстар (бастапқысы: "
"NUMCPUs)"

#: app/flatpak-builtins-build-update-repo.c:89
msgid "NUM-JOBS"
msgstr "ЖҰМЫС-САНЫ"

#: app/flatpak-builtins-build-update-repo.c:90
msgid "Don't create deltas matching refs"
msgstr "Сілтемелерге сәйкес келетін дельталарды жасамау"

#: app/flatpak-builtins-build-update-repo.c:91
msgid "Prune unused objects"
msgstr "Қолданылмайтын объектілерді тазалау"

#: app/flatpak-builtins-build-update-repo.c:92
msgid "Prune but don't actually remove anything"
msgstr "Тазалау, бірақ іс жүзінде ештеңені өшірмеу"

#: app/flatpak-builtins-build-update-repo.c:93
msgid "Only traverse DEPTH parents for each commit (default: -1=infinite)"
msgstr "Әр коммит үшін тек DEPTH аталықтарын өту (бастапқысы: -1=шексіз)"

#: app/flatpak-builtins-build-update-repo.c:93
msgid "DEPTH"
msgstr "ТЕРЕҢДІК"

#: app/flatpak-builtins-build-update-repo.c:223
#, c-format
msgid "Generating delta: %s (%.10s)\n"
msgstr "Дельта жасалуда: %s (%.10s)\n"

#: app/flatpak-builtins-build-update-repo.c:225
#, c-format
msgid "Generating delta: %s (%.10s-%.10s)\n"
msgstr "Дельта жасалуда: %s (%.10s-%.10s)\n"

#: app/flatpak-builtins-build-update-repo.c:233
#, c-format
msgid "Failed to generate delta %s (%.10s): "
msgstr "%s (%.10s) дельтасын жасау сәтсіз аяқталды: "

#: app/flatpak-builtins-build-update-repo.c:236
#, c-format
msgid "Failed to generate delta %s (%.10s-%.10s): "
msgstr "%s (%.10s-%.10s) дельтасын жасау сәтсіз аяқталды: "

#: app/flatpak-builtins-build-update-repo.c:492
msgid "LOCATION - Update repository metadata"
msgstr "ОРНЫ - Репозиторий метадеректерін жаңарту"

#: app/flatpak-builtins-build-update-repo.c:609
#, c-format
msgid "Updating appstream branch\n"
msgstr "appstream тармағы жаңартылуда\n"

#: app/flatpak-builtins-build-update-repo.c:638
#, c-format
msgid "Updating summary\n"
msgstr "Жиынтық жаңартылуда\n"

#: app/flatpak-builtins-build-update-repo.c:664
#, c-format
msgid "Total objects: %u\n"
msgstr "Жалпы объектілер: %u\n"

#: app/flatpak-builtins-build-update-repo.c:666
#, c-format
msgid "No unreachable objects\n"
msgstr "Қол жетімсіз объектілер жоқ\n"

#: app/flatpak-builtins-build-update-repo.c:668
#, c-format
msgid "Deleted %u objects, %s freed\n"
msgstr "%u объект өшірілді, %s босатылды\n"

#: app/flatpak-builtins-config.c:41
msgid "List configuration keys and values"
msgstr "Конфигурация кілттері мен мәндерін тізімдеу"

#: app/flatpak-builtins-config.c:42
msgid "Get configuration for KEY"
msgstr "КІЛТ үшін конфигурацияны алу"

#: app/flatpak-builtins-config.c:43
msgid "Set configuration for KEY to VALUE"
msgstr "КІЛТ үшін конфигурацияны МӘН-ге орнату"

#: app/flatpak-builtins-config.c:44
msgid "Unset configuration for KEY"
msgstr "КІЛТ үшін конфигурацияны алып тастау"

#: app/flatpak-builtins-config.c:149
#, c-format
msgid "'%s' does not look like a language/locale code"
msgstr "'%s' тіл/локаль кодына ұқсамайды"

#: app/flatpak-builtins-config.c:172
#, c-format
msgid "'%s' does not look like a language code"
msgstr "'%s' тіл кодына ұқсамайды"

#: app/flatpak-builtins-config.c:190
#, c-format
msgid "'%s' is not a valid value (use 'true' or 'false')"
msgstr "'%s' жарамды мән емес ('true' немесе 'false' қолданыңыз)"

#: app/flatpak-builtins-config.c:262
#, c-format
msgid "Unknown configure key '%s'"
msgstr "Белгісіз конфигурация кілті '%s'"

#: app/flatpak-builtins-config.c:284
msgid "Too many arguments for --list"
msgstr "--list үшін аргументтер тым көп"

#: app/flatpak-builtins-config.c:314 app/flatpak-builtins-config.c:362
msgid "You must specify KEY"
msgstr "КІЛТ көрсетілуі тиіс"

#: app/flatpak-builtins-config.c:316
msgid "Too many arguments for --get"
msgstr "--get үшін аргументтер тым көп"

#: app/flatpak-builtins-config.c:338
msgid "You must specify KEY and VALUE"
msgstr "КІЛТ және МӘН көрсетілуі тиіс"

#: app/flatpak-builtins-config.c:340
msgid "Too many arguments for --set"
msgstr "--set үшін аргументтер тым көп"

#: app/flatpak-builtins-config.c:364
msgid "Too many arguments for --unset"
msgstr "--unset үшін аргументтер тым көп"

#: app/flatpak-builtins-config.c:383
msgid "[KEY [VALUE]] - Manage configuration"
msgstr "[КІЛТ [МӘН]] - Конфигурацияны басқару"

#: app/flatpak-builtins-config.c:394
msgid "Can only use one of --list, --get, --set or --unset"
msgstr ""
"--list, --get, --set немесе --unset опцияларының тек біреуін қолдануға болады"

#: app/flatpak-builtins-config.c:408
msgid "Must specify one of --list, --get, --set or --unset"
msgstr ""
"--list, --get, --set немесе --unset опцияларының біреуі көрсетілуі тиіс"

#: app/flatpak-builtins-create-usb.c:45 app/flatpak-builtins-install.c:75
#: app/flatpak-builtins-remote-info.c:57 app/flatpak-builtins-uninstall.c:59
#: app/flatpak-builtins-update.c:65
msgid "Look for app with the specified name"
msgstr "Көрсетілген атауы бар қолданбаны іздеу"

#: app/flatpak-builtins-create-usb.c:46
msgid "Arch to copy"
msgstr "Көшірілетін архитектура"

#: app/flatpak-builtins-create-usb.c:47
msgid "DEST"
msgstr "МАҚСАТ"

#: app/flatpak-builtins-create-usb.c:49
msgid "Allow partial commits in the created repo"
msgstr "Жасалған репозиторийде жартылай коммиттерге рұқсат беру"

#: app/flatpak-builtins-create-usb.c:125 app/flatpak-builtins-create-usb.c:165
#, c-format
msgid ""
"Warning: Related ref ‘%s’ is partially installed. Use --allow-partial to "
"suppress this message.\n"
msgstr ""
"Ескерту: Қатысты ‘%s’ сілтемесі жартылай орнатылған. Бұл хабарды болдырмау "
"үшін --allow-partial қолданыңыз.\n"

#: app/flatpak-builtins-create-usb.c:158
#, c-format
msgid "Warning: Omitting related ref ‘%s’ because it is not installed.\n"
msgstr ""
"Ескерту: Қатысты ‘%s’ сілтемесі орнатылмағандықтан өткізіліп жіберілді.\n"

#: app/flatpak-builtins-create-usb.c:175
#, c-format
msgid ""
"Warning: Omitting related ref ‘%s’ because its remote ‘%s’ does not have a "
"collection ID set.\n"
msgstr ""
"Ескерту: Қатысты ‘%s’ сілтемесі өткізіліп жіберілді, себебі оның ‘%s’ "
"қашықтағы репозиторийінде коллекция ID-і орнатылмаған.\n"

#: app/flatpak-builtins-create-usb.c:187
#, c-format
msgid "Warning: Omitting related ref ‘%s’ because it's extra-data.\n"
msgstr ""
"Ескерту: Қатысты ‘%s’ сілтемесі қосымша деректер болғандықтан өткізіліп "
"жіберілді.\n"

#: app/flatpak-builtins-create-usb.c:262 app/flatpak-builtins-create-usb.c:637
#, c-format
msgid ""
"Remote ‘%s’ does not have a collection ID set, which is required for P2P "
"distribution of ‘%s’."
msgstr ""
"‘%s’ қашықтағы репозиторийінде коллекция ID-і орнатылмаған, бұл ‘%s’ P2P "
"таратылымы үшін қажет."

#: app/flatpak-builtins-create-usb.c:272
#, c-format
msgid "Warning: Omitting ref ‘%s’ (runtime of ‘%s’) because it's extra-data.\n"
msgstr ""
"Ескерту: ‘%s’ сілтемесі (‘%s’ орындалу ортасы) қосымша деректер болғандықтан "
"өткізіліп жіберілді.\n"

#: app/flatpak-builtins-create-usb.c:484
msgid "MOUNT-PATH [REF…] - Copy apps or runtimes onto removable media"
msgstr ""
"ТІРКЕУ-ЖОЛЫ [СІЛТЕМЕ…] - Қолданбаларды немесе орындалу орталарын алынбалы "
"тасымалдағышқа көшіру"

#: app/flatpak-builtins-create-usb.c:493
msgid "MOUNT-PATH and REF must be specified"
msgstr "ТІРКЕУ-ЖОЛЫ және СІЛТЕМЕ көрсетілуі тиіс"

#: app/flatpak-builtins-create-usb.c:607
#, c-format
msgid "Ref ‘%s’ found in multiple installations: %s. You must specify one."
msgstr ""
"‘%s’ сілтемесі бірнеше орнатылымда табылды: %s. Сіз біреуін көрсетуіңіз "
"керек."

#: app/flatpak-builtins-create-usb.c:620
#, c-format
msgid "Refs must all be in the same installation (found in %s and %s)."
msgstr "Сілтемелердің бәрі бір орнатылымда болуы тиіс (%s және %s табылды)."

#: app/flatpak-builtins-create-usb.c:670
#, c-format
msgid ""
"Warning: Ref ‘%s’ is partially installed. Use --allow-partial to suppress "
"this message.\n"
msgstr ""
"Ескерту: ‘%s’ сілтемесі жартылай орнатылған. Бұл хабарды болдырмау үшін --"
"allow-partial қолданыңыз.\n"

#: app/flatpak-builtins-create-usb.c:681
#, c-format
msgid "Installed ref ‘%s’ is extra-data, and cannot be distributed offline"
msgstr ""
"Орнатылған ‘%s’ сілтемесі қосымша дерек болып табылады және оны желіден тыс "
"тарату мүмкін емес"

#: app/flatpak-builtins-create-usb.c:721
#, c-format
msgid "Warning: Couldn't update repo metadata for remote ‘%s’: %s\n"
msgstr ""
"Ескерту: ‘%s’ қашықтағы репозиторийінің метадеректерін жаңарту мүмкін "
"болмады: %s\n"

#: app/flatpak-builtins-create-usb.c:751
#, c-format
msgid "Warning: Couldn't update appstream data for remote ‘%s’ arch ‘%s’: %s\n"
msgstr ""
"Ескерту: ‘%s’ қашықтағы репозиторийінің ‘%s’ архитектурасы үшін appstream "
"деректерін жаңарту мүмкін болмады: %s\n"

#. Print a warning if both appstream and appstream2 are missing
#: app/flatpak-builtins-create-usb.c:784
#, c-format
msgid ""
"Warning: Couldn't find appstream data for remote ‘%s’ arch ‘%s’: %s; %s\n"
msgstr ""
"Ескерту: ‘%s’ қашықтағы репозиторийінің ‘%s’ архитектурасы үшін appstream "
"деректері табылмады: %s; %s\n"

#. Appstream2 is only for efficiency, so just print a debug message
#: app/flatpak-builtins-create-usb.c:790
#, c-format
msgid "Couldn't find appstream2 data for remote ‘%s’ arch ‘%s’: %s\n"
msgstr ""
"‘%s’ қашықтағы репозиторийінің ‘%s’ архитектурасы үшін appstream2 деректері "
"табылмады: %s\n"

#: app/flatpak-builtins-document-export.c:62
msgid "Create a unique document reference"
msgstr "Құжаттың бірегей сілтемесін жасау"

#: app/flatpak-builtins-document-export.c:63
msgid "Make the document transient for the current session"
msgstr "Құжатты ағымдағы сессия үшін уақытша ету"

#: app/flatpak-builtins-document-export.c:64
msgid "Don't require the file to exist already"
msgstr "Файлдың алдын ала болуын талап етпеу"

#: app/flatpak-builtins-document-export.c:65
msgid "Give the app read permissions"
msgstr "Қолданбаға оқу рұқсатын беру"

#: app/flatpak-builtins-document-export.c:66
msgid "Give the app write permissions"
msgstr "Қолданбаға жазу рұқсатын беру"

#: app/flatpak-builtins-document-export.c:67
msgid "Give the app delete permissions"
msgstr "Қолданбаға өшіру рұқсатын беру"

#: app/flatpak-builtins-document-export.c:68
msgid "Give the app permissions to grant further permissions"
msgstr "Қолданбаға әрі қарай рұқсаттар беру құқығын беру"

#: app/flatpak-builtins-document-export.c:69
msgid "Revoke read permissions of the app"
msgstr "Қолданбаның оқу рұқсатын қайтарып алу"

#: app/flatpak-builtins-document-export.c:70
msgid "Revoke write permissions of the app"
msgstr "Қолданбаның жазу рұқсатын қайтарып алу"

#: app/flatpak-builtins-document-export.c:71
msgid "Revoke delete permissions of the app"
msgstr "Қолданбаның өшіру рұқсатын қайтарып алу"

#: app/flatpak-builtins-document-export.c:72
msgid "Revoke the permission to grant further permissions"
msgstr "Әрі қарай рұқсаттар беру құқығын қайтарып алу"

#: app/flatpak-builtins-document-export.c:73
msgid "Add permissions for this app"
msgstr "Осы қолданба үшін рұқсаттар қосу"

#: app/flatpak-builtins-document-export.c:73
msgid "APPID"
msgstr "ҚОЛДАНБА_ID"

#: app/flatpak-builtins-document-export.c:100
msgid "FILE - Export a file to apps"
msgstr "ФАЙЛ - Файлды қолданбаларға экспорттау"

#: app/flatpak-builtins-document-export.c:109
#: app/flatpak-builtins-document-info.c:72
#: app/flatpak-builtins-document-unexport.c:67
msgid "FILE must be specified"
msgstr "ФАЙЛ көрсетілуі тиіс"

#: app/flatpak-builtins-document-info.c:63
msgid "FILE - Get information about an exported file"
msgstr "ФАЙЛ - Экспортталған файл туралы ақпарат алу"

#: app/flatpak-builtins-document-info.c:100
#: app/flatpak-builtins-document-unexport.c:94
#, c-format
msgid "Not exported\n"
msgstr "Экспортталмаған\n"

#: app/flatpak-builtins-document-list.c:43 app/flatpak-builtins-history.c:53
#: app/flatpak-builtins-list.c:54 app/flatpak-builtins-ps.c:43
#: app/flatpak-builtins-remote-list.c:45 app/flatpak-builtins-remote-ls.c:59
#: app/flatpak-builtins-search.c:38
msgid "What information to show"
msgstr "Қандай ақпаратты көрсету керек"

#: app/flatpak-builtins-document-list.c:43 app/flatpak-builtins-history.c:53
#: app/flatpak-builtins-list.c:54 app/flatpak-builtins-ps.c:43
#: app/flatpak-builtins-remote-list.c:45 app/flatpak-builtins-remote-ls.c:59
#: app/flatpak-builtins-search.c:38
msgid "FIELD,…"
msgstr "ӨРІС,…"

#: app/flatpak-builtins-document-list.c:44 app/flatpak-builtins-history.c:54
#: app/flatpak-builtins-list.c:52 app/flatpak-builtins-permission-list.c:43
#: app/flatpak-builtins-permission-show.c:43 app/flatpak-builtins-ps.c:44
#: app/flatpak-builtins-remote-list.c:46 app/flatpak-builtins-remote-ls.c:63
#: app/flatpak-builtins-repo.c:717 app/flatpak-builtins-search.c:39
msgid "Show output in JSON format"
msgstr "Нәтижені JSON пішімінде көрсету"

#: app/flatpak-builtins-document-list.c:49
msgid "Show the document ID"
msgstr "Құжат ID-ін көрсету"

#: app/flatpak-builtins-document-list.c:50
msgid "Path"
msgstr "Жол"

#: app/flatpak-builtins-document-list.c:50
#: app/flatpak-builtins-document-list.c:51
msgid "Show the document path"
msgstr "Құжат жолын көрсету"

#: app/flatpak-builtins-document-list.c:51 app/flatpak-builtins-list.c:66
#: app/flatpak-builtins-remote-ls.c:74
msgid "Origin"
msgstr "Шығу тегі"

#: app/flatpak-builtins-document-list.c:52 app/flatpak-builtins-history.c:62
#: app/flatpak-builtins-ps.c:52
msgid "Application"
msgstr "Қолданба"

#: app/flatpak-builtins-document-list.c:52
msgid "Show applications with permission"
msgstr "Рұқсаты бар қолданбаларды көрсету"

#: app/flatpak-builtins-document-list.c:53
#: app/flatpak-builtins-permission-list.c:182
#: app/flatpak-builtins-permission-show.c:145
msgid "Permissions"
msgstr "Рұқсаттар"

#: app/flatpak-builtins-document-list.c:53
msgid "Show permissions for applications"
msgstr "Қолданбалар үшін рұқсаттарды көрсету"

#: app/flatpak-builtins-document-list.c:161
#, c-format
msgid "No documents found\n"
msgstr "Құжаттар табылмады\n"

#: app/flatpak-builtins-document-list.c:180
msgid "[APPID] - List exported files"
msgstr "[ҚОЛДАНБА_ID] - Экспортталған файлдарды тізімдеу"

#: app/flatpak-builtins-document-unexport.c:43
msgid "Specify the document ID"
msgstr "Құжат ID-ін көрсетіңіз"

#: app/flatpak-builtins-document-unexport.c:58
msgid "FILE - Unexport a file to apps"
msgstr "ФАЙЛ - Файлды қолданбалар үшін экспорттаудан алып тастау"

#: app/flatpak-builtins-enter.c:88
msgid "INSTANCE COMMAND [ARGUMENT…] - Run a command inside a running sandbox"
msgstr ""
"ИНСТАНЦИЯ КОМАНДА [АРГУМЕНТ…] - Жұмыс істеп тұрған құмсалғыш ішінде "
"команданы орындау"

#: app/flatpak-builtins-enter.c:111
msgid "INSTANCE and COMMAND must be specified"
msgstr "ИНСТАНЦИЯ және КОМАНДА көрсетілуі тиіс"

#: app/flatpak-builtins-enter.c:138
#, c-format
msgid "%s is neither a pid nor an application or instance ID"
msgstr "%s не pid, не қолданба, не инстанция ID-і емес"

#: app/flatpak-builtins-enter.c:144
msgid "entering not supported (need unprivileged user namespaces, or sudo -E)"
msgstr ""
"кіруге қолдау көрсетілмейді (артықшылығы жоқ пайдаланушы атау кеңістіктері "
"немесе sudo -E қажет)"

#: app/flatpak-builtins-enter.c:145
#, c-format
msgid "No such pid %s"
msgstr "Мұндай pid табылмады: %s"

#: app/flatpak-builtins-enter.c:158
msgid "Can't read cwd"
msgstr "cwd оқу мүмкін емес"

#: app/flatpak-builtins-enter.c:163
msgid "Can't read root"
msgstr "root оқу мүмкін емес"

#: app/flatpak-builtins-enter.c:191
#, c-format
msgid "Invalid %s namespace for pid %d"
msgstr "pid %2$d үшін жарамсыз %1$s атау кеңістігі"

#: app/flatpak-builtins-enter.c:202
#, c-format
msgid "Invalid %s namespace for self"
msgstr "Өзі үшін жарамсыз %s атау кеңістігі"

#: app/flatpak-builtins-enter.c:216
#, c-format
msgid "Can't open %s namespace: %s"
msgstr "%s атау кеңістігін ашу мүмкін емес: %s"

#: app/flatpak-builtins-enter.c:226
msgid "entering not supported (need unprivileged user namespaces)"
msgstr ""
"кіруге қолдау көрсетілмейді (привилегиясы жоқ пайдаланушы атау кеңістіктері "
"қажет)"

#: app/flatpak-builtins-enter.c:227
#, c-format
msgid "Can't enter %s namespace: %s"
msgstr "%s атау кеңістігіне кіру мүмкін емес: %s"

#: app/flatpak-builtins-enter.c:234
msgid "Can't chdir"
msgstr "chdir орындау мүмкін емес"

#: app/flatpak-builtins-enter.c:237
msgid "Can't chroot"
msgstr "chroot орындау мүмкін емес"

#: app/flatpak-builtins-enter.c:240
msgid "Can't switch gid"
msgstr "gid ауыстыру мүмкін емес"

#: app/flatpak-builtins-enter.c:243
msgid "Can't switch uid"
msgstr "uid ауыстыру мүмкін емес"

#: app/flatpak-builtins-history.c:50
msgid "Only show changes after TIME"
msgstr "Тек УАҚЫТ-тан кейінгі өзгерістерді көрсету"

#: app/flatpak-builtins-history.c:50 app/flatpak-builtins-history.c:51
msgid "TIME"
msgstr "УАҚЫТ"

#: app/flatpak-builtins-history.c:51
msgid "Only show changes before TIME"
msgstr "Тек УАҚЫТ-қа дейінгі өзгерістерді көрсету"

#: app/flatpak-builtins-history.c:52
msgid "Show newest entries first"
msgstr "Ең жаңа жазбаларды бірінші көрсету"

#: app/flatpak-builtins-history.c:59
msgid "Time"
msgstr "Уақыт"

#: app/flatpak-builtins-history.c:59
msgid "Show when the change happened"
msgstr "Өзгерістің қашан болғанын көрсету"

#: app/flatpak-builtins-history.c:60
msgid "Change"
msgstr "Өзгеріс"

#: app/flatpak-builtins-history.c:60
msgid "Show the kind of change"
msgstr "Өзгеріс түрін көрсету"

#: app/flatpak-builtins-history.c:61 app/flatpak-builtins-list.c:68
#: app/flatpak-builtins-remote-ls.c:75 app/flatpak-builtins-repo.c:335
msgid "Ref"
msgstr "Сілтеме"

#: app/flatpak-builtins-history.c:61 app/flatpak-builtins-list.c:68
#: app/flatpak-builtins-remote-ls.c:75
msgid "Show the ref"
msgstr "Сілтемені көрсету"

#: app/flatpak-builtins-history.c:62
msgid "Show the application/runtime ID"
msgstr "Қолданба/орындалу ортасы ID-ін көрсету"

#: app/flatpak-builtins-history.c:63 app/flatpak-builtins-list.c:64
#: app/flatpak-builtins-ps.c:53 app/flatpak-builtins-remote-ls.c:73
#: app/flatpak-cli-transaction.c:1435
msgid "Arch"
msgstr "Архитектура"

#: app/flatpak-builtins-history.c:63 app/flatpak-builtins-list.c:64
#: app/flatpak-builtins-ps.c:53 app/flatpak-builtins-remote-ls.c:73
msgid "Show the architecture"
msgstr "Архитектураны көрсету"

#: app/flatpak-builtins-history.c:64 app/flatpak-builtins-list.c:63
#: app/flatpak-builtins-ps.c:54 app/flatpak-builtins-remote-ls.c:72
#: app/flatpak-builtins-search.c:48 app/flatpak-cli-transaction.c:1438
msgid "Branch"
msgstr "Тармақ"

#: app/flatpak-builtins-history.c:64 app/flatpak-builtins-list.c:63
#: app/flatpak-builtins-remote-ls.c:72
msgid "Show the branch"
msgstr "Тармақты көрсету"

#: app/flatpak-builtins-history.c:65 app/flatpak-builtins-list.c:67
msgid "Installation"
msgstr "Орнатылым"

#: app/flatpak-builtins-history.c:65
msgid "Show the affected installation"
msgstr "Әсер еткен орнатылымды көрсету"

#: app/flatpak-builtins-history.c:66 app/flatpak-cli-transaction.c:1452
msgid "Remote"
msgstr "Қашықтағы"

#: app/flatpak-builtins-history.c:66
msgid "Show the remote"
msgstr "Қашықтағы репозиторийді көрсету"

#: app/flatpak-builtins-history.c:67 app/flatpak-builtins-ps.c:55
#: app/flatpak-builtins-remote-ls.c:76
msgid "Commit"
msgstr "Коммит"

#: app/flatpak-builtins-history.c:67
msgid "Show the current commit"
msgstr "Ағымдағы коммитті көрсету"

#: app/flatpak-builtins-history.c:68
msgid "Old Commit"
msgstr "Ескі коммит"

#: app/flatpak-builtins-history.c:68
msgid "Show the previous commit"
msgstr "Алдыңғы коммитті көрсету"

#: app/flatpak-builtins-history.c:69
msgid "Show the remote URL"
msgstr "Қашықтағы URL-ді көрсету"

#: app/flatpak-builtins-history.c:70 app/flatpak-cli-transaction.c:700
msgid "User"
msgstr "Пайдаланушы"

#: app/flatpak-builtins-history.c:70
msgid "Show the user doing the change"
msgstr "Өзгерісті жасаған пайдаланушыны көрсету"

#: app/flatpak-builtins-history.c:71
msgid "Tool"
msgstr "Сайман"

#: app/flatpak-builtins-history.c:71
msgid "Show the tool that was used"
msgstr "Қолданылған сайманды көрсету"

#: app/flatpak-builtins-history.c:72 app/flatpak-builtins-list.c:62
#: app/flatpak-builtins-remote-ls.c:71 app/flatpak-builtins-search.c:47
msgid "Version"
msgstr "Нұсқа"

#: app/flatpak-builtins-history.c:72
msgid "Show the Flatpak version"
msgstr "Flatpak нұсқасын көрсету"

#: app/flatpak-builtins-history.c:91
#, c-format
msgid "Failed to get journal data (%s): %s"
msgstr "Журнал деректерін алу сәтсіз аяқталды (%s): %s"

#: app/flatpak-builtins-history.c:146
#, c-format
msgid "Failed to open journal: %s"
msgstr "Журналды ашу мүмкін болмады: %s"

#: app/flatpak-builtins-history.c:153
#, c-format
msgid "Failed to add match to journal: %s"
msgstr "Журналға сәйкестікті қосу мүмкін болмады: %s"

#: app/flatpak-builtins-history.c:471
msgid " - Show history"
msgstr " - Тарихты көрсету"

#: app/flatpak-builtins-history.c:490
#, c-format
msgid "Failed to parse the --since option"
msgstr "--since опциясын талдау сәтсіз аяқталды"

#: app/flatpak-builtins-history.c:501
#, c-format
msgid "Failed to parse the --until option"
msgstr "--until опциясын талдау сәтсіз аяқталды"

#: app/flatpak-builtins-info.c:56
msgid "Show user installations"
msgstr "Пайдаланушы орнатылымдарын көрсету"

#: app/flatpak-builtins-info.c:57
msgid "Show system-wide installations"
msgstr "Жүйелік орнатылымдарды көрсету"

#: app/flatpak-builtins-info.c:58
msgid "Show specific system-wide installations"
msgstr "Арнайы жүйелік орнатылымдарды көрсету"

#: app/flatpak-builtins-info.c:59 app/flatpak-builtins-remote-info.c:59
msgid "Show ref"
msgstr "Сілтемені көрсету"

#: app/flatpak-builtins-info.c:60 app/flatpak-builtins-remote-info.c:60
msgid "Show commit"
msgstr "Коммитті көрсету"

#: app/flatpak-builtins-info.c:61
msgid "Show origin"
msgstr "Шығу тегін көрсету"

#: app/flatpak-builtins-info.c:62
msgid "Show size"
msgstr "Өлшемін көрсету"

#: app/flatpak-builtins-info.c:63 app/flatpak-builtins-remote-info.c:62
msgid "Show metadata"
msgstr "Метадеректерді көрсету"

#: app/flatpak-builtins-info.c:64 app/flatpak-builtins-remote-info.c:63
msgid "Show runtime"
msgstr "Орындалу ортасын көрсету"

#: app/flatpak-builtins-info.c:65 app/flatpak-builtins-remote-info.c:64
msgid "Show sdk"
msgstr "sdk көрсету"

#: app/flatpak-builtins-info.c:66
msgid "Show permissions"
msgstr "Рұқсаттарды көрсету"

#: app/flatpak-builtins-info.c:67
msgid "Query file access"
msgstr "Файлға қол жеткізуді сұрау"

#: app/flatpak-builtins-info.c:67 app/flatpak-builtins-install.c:82
#: app/flatpak-builtins-install.c:88 app/flatpak-builtins-preinstall.c:68
#: app/flatpak-builtins-run.c:182 app/flatpak-builtins-run.c:184
#: app/flatpak-builtins-update.c:67 app/flatpak-builtins-update.c:71
msgid "PATH"
msgstr "ЖОЛ"

#: app/flatpak-builtins-info.c:68
msgid "Show extensions"
msgstr "Кеңейтулерді көрсету"

#: app/flatpak-builtins-info.c:69
msgid "Show location"
msgstr "Орналасуын көрсету"

#: app/flatpak-builtins-info.c:116
msgid "NAME [BRANCH] - Get info about an installed app or runtime"
msgstr ""
"АТЫ [ТАРМАҚ] - Орнатылған қолданба немесе орындалу ортасы туралы ақпарат алу"

#: app/flatpak-builtins-info.c:123 app/flatpak-builtins-remote-add.c:317
#: app/flatpak-builtins-remote-delete.c:63
msgid "NAME must be specified"
msgstr "АТЫ көрсетілуі тиіс"

#: app/flatpak-builtins-info.c:196
msgid "ref not present in origin"
msgstr "сілтеме шығу тегінде жоқ"

#: app/flatpak-builtins-info.c:211 app/flatpak-builtins-remote-info.c:217
#, c-format
msgid "Warning: Commit has no flatpak metadata\n"
msgstr "Ескерту: Коммитте flatpak метадеректері жоқ\n"

#: app/flatpak-builtins-info.c:217 app/flatpak-builtins-info.c:259
#: app/flatpak-builtins-info.c:455 app/flatpak-builtins-info.c:513
#: app/flatpak-builtins-remote-info.c:236
#: app/flatpak-builtins-remote-info.c:271
msgid "ID:"
msgstr "ID:"

#: app/flatpak-builtins-info.c:218 app/flatpak-builtins-info.c:260
#: app/flatpak-builtins-remote-info.c:237
#: app/flatpak-builtins-remote-info.c:272
msgid "Ref:"
msgstr "Сілтеме:"

#: app/flatpak-builtins-info.c:219 app/flatpak-builtins-info.c:261
#: app/flatpak-builtins-remote-info.c:238
#: app/flatpak-builtins-remote-info.c:273
msgid "Arch:"
msgstr "Архитектура:"

#: app/flatpak-builtins-info.c:220 app/flatpak-builtins-info.c:262
#: app/flatpak-builtins-remote-info.c:239
#: app/flatpak-builtins-remote-info.c:274
msgid "Branch:"
msgstr "Тармақ:"

#: app/flatpak-builtins-info.c:222 app/flatpak-builtins-info.c:264
#: app/flatpak-builtins-remote-info.c:241
#: app/flatpak-builtins-remote-info.c:276
msgid "Version:"
msgstr "Нұсқа:"

#: app/flatpak-builtins-info.c:224 app/flatpak-builtins-info.c:266
#: app/flatpak-builtins-remote-info.c:243
#: app/flatpak-builtins-remote-info.c:278
msgid "License:"
msgstr "Лицензия:"

#: app/flatpak-builtins-info.c:226 app/flatpak-builtins-info.c:269
#: app/flatpak-builtins-remote-info.c:245
#: app/flatpak-builtins-remote-info.c:280
msgid "Collection:"
msgstr "Коллекция:"

#: app/flatpak-builtins-info.c:227 app/flatpak-builtins-info.c:270
#: app/flatpak-builtins-info.c:458 app/flatpak-builtins-info.c:516
msgid "Installation:"
msgstr "Орнатылым:"

#: app/flatpak-builtins-info.c:228 app/flatpak-builtins-info.c:271
#: app/flatpak-builtins-info.c:459 app/flatpak-builtins-info.c:517
#: app/flatpak-builtins-remote-info.c:249
#: app/flatpak-builtins-remote-info.c:284
msgid "Installed Size:"
msgstr "Орнатылған өлшемі:"

#: app/flatpak-builtins-info.c:231 app/flatpak-builtins-info.c:279
#: app/flatpak-builtins-remote-info.c:252
#: app/flatpak-builtins-remote-info.c:288
msgid "Runtime:"
msgstr "Орындалу ортасы:"

#: app/flatpak-builtins-info.c:232 app/flatpak-builtins-info.c:288
#: app/flatpak-builtins-remote-info.c:253
#: app/flatpak-builtins-remote-info.c:293
msgid "Sdk:"
msgstr "Sdk:"

#: app/flatpak-builtins-info.c:235 app/flatpak-builtins-info.c:313
#: app/flatpak-builtins-remote-info.c:256
#: app/flatpak-builtins-remote-info.c:319
msgid "Date:"
msgstr "Күні:"

#: app/flatpak-builtins-info.c:237 app/flatpak-builtins-info.c:311
#: app/flatpak-builtins-remote-info.c:258
#: app/flatpak-builtins-remote-info.c:317
msgid "Subject:"
msgstr "Тақырыбы:"

#: app/flatpak-builtins-info.c:240 app/flatpak-builtins-info.c:295
msgid "Active commit:"
msgstr "Белсенді коммит:"

#: app/flatpak-builtins-info.c:241 app/flatpak-builtins-info.c:298
msgid "Latest commit:"
msgstr "Соңғы коммит:"

#: app/flatpak-builtins-info.c:244 app/flatpak-builtins-info.c:303
#: app/flatpak-builtins-info.c:457 app/flatpak-builtins-info.c:515
#: app/flatpak-builtins-remote-info.c:259
#: app/flatpak-builtins-remote-info.c:298
msgid "Commit:"
msgstr "Коммит:"

#: app/flatpak-builtins-info.c:246 app/flatpak-builtins-info.c:308
#: app/flatpak-builtins-remote-info.c:261
#: app/flatpak-builtins-remote-info.c:303
msgid "Parent:"
msgstr "Ата-анасы:"

#: app/flatpak-builtins-info.c:248 app/flatpak-builtins-info.c:321
msgid "Alt-id:"
msgstr "Alt-id:"

#: app/flatpak-builtins-info.c:250 app/flatpak-builtins-info.c:325
#: app/flatpak-builtins-remote-info.c:263
#: app/flatpak-builtins-remote-info.c:308
msgid "End-of-life:"
msgstr "Қолдау мерзімі аяқталған:"

#: app/flatpak-builtins-info.c:252 app/flatpak-builtins-info.c:330
#: app/flatpak-builtins-remote-info.c:265
#: app/flatpak-builtins-remote-info.c:313
msgid "End-of-life-rebase:"
msgstr "Қолдау мерзімі аяқталған соң ауысу:"

#: app/flatpak-builtins-info.c:254 app/flatpak-builtins-info.c:317
msgid "Subdirectories:"
msgstr "Ішкі бумалар:"

#: app/flatpak-builtins-info.c:255 app/flatpak-builtins-info.c:454
#: app/flatpak-builtins-info.c:512
msgid "Extension:"
msgstr "Кеңейту:"

#: app/flatpak-builtins-info.c:267 app/flatpak-builtins-info.c:456
#: app/flatpak-builtins-info.c:514
msgid "Origin:"
msgstr "Шығу тегі:"

#: app/flatpak-builtins-info.c:460 app/flatpak-builtins-info.c:522
msgid "Subpaths:"
msgstr "Ішкі жолдар:"

#: app/flatpak-builtins-info.c:478
msgid "unmaintained"
msgstr "сүйемелденбейді"

#: app/flatpak-builtins-info.c:480 app/flatpak-builtins-info.c:482
msgid "unknown"
msgstr "белгісіз"

#: app/flatpak-builtins-install.c:68 app/flatpak-builtins-preinstall.c:57
msgid "Don't pull, only install from local cache"
msgstr "Тартпау, тек жергілікті кэштен орнату"

#: app/flatpak-builtins-install.c:69 app/flatpak-builtins-preinstall.c:58
#: app/flatpak-builtins-update.c:60
msgid "Don't deploy, only download to local cache"
msgstr "Орналастырмау, тек жергілікті кэшке жүктеп алу"

#: app/flatpak-builtins-install.c:70 app/flatpak-builtins-preinstall.c:59
msgid "Don't install related refs"
msgstr "Қатысты сілтемелерді орнатпау"

#: app/flatpak-builtins-install.c:71 app/flatpak-builtins-preinstall.c:60
#: app/flatpak-builtins-update.c:62
msgid "Don't verify/install runtime dependencies"
msgstr "Орындалу ортасының тәуелділіктерін тексермеу/орнатпау"

#: app/flatpak-builtins-install.c:72
msgid "Don't automatically pin explicit installs"
msgstr "Анық орнатылымдарды автоматты түрде бекітпеу"

#: app/flatpak-builtins-install.c:73 app/flatpak-builtins-preinstall.c:61
#: app/flatpak-builtins-update.c:63
msgid "Don't use static deltas"
msgstr "Статикалық дельталарды қолданбау"

#: app/flatpak-builtins-install.c:76 app/flatpak-builtins-preinstall.c:62
msgid "Additionally install the SDK used to build the given refs"
msgstr ""
"Сонымен қатар, берілген сілтемелерді құрастыру үшін қолданылған SDK-ны орнату"

#: app/flatpak-builtins-install.c:77 app/flatpak-builtins-preinstall.c:63
msgid ""
"Additionally install the debug info for the given refs and their dependencies"
msgstr ""
"Сонымен қатар, берілген сілтемелер мен олардың тәуелділіктері үшін жөндеу "
"ақпаратын орнату"

#: app/flatpak-builtins-install.c:78
msgid "Assume LOCATION is a .flatpak single-file bundle"
msgstr "ОРНЫ-ны .flatpak бір файлдық дестесі деп есептеу"

#: app/flatpak-builtins-install.c:79
msgid "Assume LOCATION is a .flatpakref application description"
msgstr "ОРНЫ-ны .flatpakref қолданба сипаттамасы деп есептеу"

#: app/flatpak-builtins-install.c:80
msgid "Assume LOCATION is containers-transports(5) reference to an OCI image"
msgstr "ОРНЫ-ны OCI бейнесіне containers-transports(5) сілтемесі деп есептеу"

#: app/flatpak-builtins-install.c:81
msgid "Check bundle signatures with GPG key from FILE (- for stdin)"
msgstr ""
"Десте қолтаңбаларын ФАЙЛ-дан алынған GPG кілтімен тексеру (stdin үшін -)"

#: app/flatpak-builtins-install.c:82
msgid "Only install this subpath"
msgstr "Тек осы ішкі жолды орнату"

#: app/flatpak-builtins-install.c:83 app/flatpak-builtins-preinstall.c:64
#: app/flatpak-builtins-uninstall.c:63 app/flatpak-builtins-update.c:68
msgid "Automatically answer yes for all questions"
msgstr "Барлық сұрақтарға автоматты түрде иә деп жауап беру"

#: app/flatpak-builtins-install.c:84 app/flatpak-builtins-preinstall.c:65
msgid "Uninstall first if already installed"
msgstr "Егер орнатылған болса, алдымен өшіру"

#: app/flatpak-builtins-install.c:85 app/flatpak-builtins-preinstall.c:66
#: app/flatpak-builtins-uninstall.c:64 app/flatpak-builtins-update.c:69
msgid "Produce minimal output and don't ask questions"
msgstr "Минималды нәтиже шығару және сұрақтар қоймау"

#: app/flatpak-builtins-install.c:86
msgid "Update install if already installed"
msgstr "Егер орнатылған болса, орнатылымды жаңарту"

#. Translators: A sideload is when you install from a local USB drive rather than the Internet.
#: app/flatpak-builtins-install.c:88 app/flatpak-builtins-preinstall.c:68
#: app/flatpak-builtins-update.c:71
msgid "Use this local repo for sideloads"
msgstr "Қатар жүктеулер (sideloads) үшін осы жергілікті репозиторийді қолдану"

#: app/flatpak-builtins-install.c:178
msgid "Bundle filename must be specified"
msgstr "Десте файл атауы көрсетілуі тиіс"

#: app/flatpak-builtins-install.c:188
msgid "Remote bundles are not supported"
msgstr "Қашықтағы дестелерге қолдау көрсетілмейді"

#: app/flatpak-builtins-install.c:231
msgid "Filename or uri must be specified"
msgstr "Файл атауы немесе uri көрсетілуі тиіс"

#: app/flatpak-builtins-install.c:295
msgid "Image location must be specified"
msgstr "Бейне орны көрсетілуі тиіс"

#: app/flatpak-builtins-install.c:345
msgid "[LOCATION/REMOTE] [REF…] - Install applications or runtimes"
msgstr ""
"[ОРНЫ/ҚАШЫҚТАҒЫ] [СІЛТЕМЕ…] - Қолданбаларды немесе орындалу орталарын орнату"

#: app/flatpak-builtins-install.c:378
msgid "At least one REF must be specified"
msgstr "Кем дегенде бір СІЛТЕМЕ көрсетілуі тиіс"

#: app/flatpak-builtins-install.c:392
#, c-format
msgid "Looking for matches…\n"
msgstr "Сәйкестіктерді іздеу…\n"

#: app/flatpak-builtins-install.c:513
#, c-format
msgid "No remote refs found for ‘%s’"
msgstr "‘%s’ үшін қашықтағы сілтемелер табылмады"

#: app/flatpak-builtins-install.c:573 app/flatpak-builtins-uninstall.c:405
#: common/flatpak-ref-utils.c:689 common/flatpak-ref-utils.c:1595
#, c-format
msgid "Invalid branch %s: %s"
msgstr "Жарамсыз тармақ %s: %s"

#: app/flatpak-builtins-install.c:606
#, c-format
msgid "Nothing matches %s in local repository for remote %s"
msgstr ""
"%2$s қашықтағы репозиторийінің жергілікті репозиторийінде %1$s сәйкес "
"келетін ештеңе табылмады"

#: app/flatpak-builtins-install.c:608
#, c-format
msgid "Nothing matches %s in remote %s"
msgstr "%2$s қашықтағы репозиторийінде %1$s сәйкес келетін ештеңе табылмады"

#: app/flatpak-builtins-install.c:629
#, c-format
msgid "Skipping: %s\n"
msgstr "Өткізіп жіберу: %s\n"

#: app/flatpak-builtins-kill.c:110
#, c-format
msgid "%s is not running"
msgstr "%s жұмыс істеп тұрған жоқ"

#: app/flatpak-builtins-kill.c:136
msgid "INSTANCE - Stop a running application"
msgstr "ИНСТАНЦИЯ - Жұмыс істеп тұрған қолданбаны тоқтату"

#: app/flatpak-builtins-kill.c:144 app/flatpak-builtins-ps.c:256
msgid "Extra arguments given"
msgstr "Артық аргументтер берілген"

#: app/flatpak-builtins-kill.c:150
msgid "Must specify the app to kill"
msgstr "Жойылатын (kill) қолданбаны көрсету керек"

#: app/flatpak-builtins-list.c:47
msgid "Show extra information"
msgstr "Қосымша ақпаратты көрсету"

#: app/flatpak-builtins-list.c:48
msgid "List installed runtimes"
msgstr "Орнатылған орындалу орталарын тізімдеу"

#: app/flatpak-builtins-list.c:49
msgid "List installed applications"
msgstr "Орнатылған қолданбаларды тізімдеу"

#: app/flatpak-builtins-list.c:50
msgid "Arch to show"
msgstr "Көрсетілетін архитектура"

#: app/flatpak-builtins-list.c:51 app/flatpak-builtins-remote-ls.c:57
msgid "List all refs (including locale/debug)"
msgstr "Барлық сілтемелерді тізімдеу (соның ішінде локаль/жөндеу)"

#: app/flatpak-builtins-list.c:53 app/flatpak-builtins-remote-ls.c:58
msgid "List all applications using RUNTIME"
msgstr "ОРЫНДАЛУ_ОРТАСЫН қолданатын барлық қолданбаларды тізімдеу"

#: app/flatpak-builtins-list.c:59 app/flatpak-builtins-remote-list.c:51
#: app/flatpak-builtins-remote-ls.c:68 app/flatpak-builtins-search.c:44
msgid "Name"
msgstr "Атауы"

#: app/flatpak-builtins-list.c:59 app/flatpak-builtins-remote-list.c:51
#: app/flatpak-builtins-remote-ls.c:68 app/flatpak-builtins-search.c:44
msgid "Show the name"
msgstr "Атауын көрсету"

#: app/flatpak-builtins-list.c:60 app/flatpak-builtins-remote-list.c:60
#: app/flatpak-builtins-remote-ls.c:69 app/flatpak-builtins-search.c:45
msgid "Description"
msgstr "Сипаттамасы"

#: app/flatpak-builtins-list.c:60 app/flatpak-builtins-remote-ls.c:69
#: app/flatpak-builtins-search.c:45
msgid "Show the description"
msgstr "Сипаттамасын көрсету"

#: app/flatpak-builtins-list.c:61 app/flatpak-builtins-remote-ls.c:70
#: app/flatpak-builtins-search.c:46
msgid "Application ID"
msgstr "Қолданба ID-і"

#: app/flatpak-builtins-list.c:61 app/flatpak-builtins-ps.c:52
#: app/flatpak-builtins-remote-ls.c:70 app/flatpak-builtins-search.c:46
msgid "Show the application ID"
msgstr "Қолданба ID-ін көрсету"

#: app/flatpak-builtins-list.c:62 app/flatpak-builtins-remote-ls.c:71
#: app/flatpak-builtins-search.c:47
msgid "Show the version"
msgstr "Нұсқаны көрсету"

#: app/flatpak-builtins-list.c:65 app/flatpak-builtins-ps.c:56
#: app/flatpak-builtins-remote-ls.c:77
msgid "Runtime"
msgstr "Орындалу ортасы"

#: app/flatpak-builtins-list.c:65
msgid "Show the used runtime"
msgstr "Қолданылатын орындалу ортасын көрсету"

#: app/flatpak-builtins-list.c:66 app/flatpak-builtins-remote-ls.c:74
msgid "Show the origin remote"
msgstr "Шығу тегі болып табылатын қашықтағы репозиторийді көрсету"

#: app/flatpak-builtins-list.c:67
msgid "Show the installation"
msgstr "Орнатылымды көрсету"

#: app/flatpak-builtins-list.c:69
msgid "Active commit"
msgstr "Белсенді коммит"

#: app/flatpak-builtins-list.c:69 app/flatpak-builtins-remote-ls.c:76
msgid "Show the active commit"
msgstr "Белсенді коммитті көрсету"

#: app/flatpak-builtins-list.c:70
msgid "Latest commit"
msgstr "Соңғы коммит"

#: app/flatpak-builtins-list.c:70
msgid "Show the latest commit"
msgstr "Соңғы коммитті көрсету"

#: app/flatpak-builtins-list.c:71 app/flatpak-builtins-remote-ls.c:78
msgid "Installed size"
msgstr "Орнатылған өлшемі"

#: app/flatpak-builtins-list.c:71 app/flatpak-builtins-remote-ls.c:78
msgid "Show the installed size"
msgstr "Орнатылған өлшемін көрсету"

#: app/flatpak-builtins-list.c:72 app/flatpak-builtins-remote-list.c:58
#: app/flatpak-builtins-remote-ls.c:80 app/flatpak-builtins-repo.c:340
msgid "Options"
msgstr "Опциялар"

#: app/flatpak-builtins-list.c:72 app/flatpak-builtins-remote-list.c:58
#: app/flatpak-builtins-remote-ls.c:80
msgid "Show options"
msgstr "Опцияларды көрсету"

#: app/flatpak-builtins-list.c:180
#, c-format
msgid "Unable to load details of %s: %s"
msgstr "%s мәліметтерін жүктеу мүмкін емес: %s"

#: app/flatpak-builtins-list.c:190
#, c-format
msgid "Unable to inspect current version of %s: %s"
msgstr "%s ағымдағы нұсқасын тексеру мүмкін емес: %s"

#: app/flatpak-builtins-list.c:408
msgid " - List installed apps and/or runtimes"
msgstr " - Орнатылған қолданбаларды және/немесе орындалу орталарын тізімдеу"

#: app/flatpak-builtins-make-current.c:38
msgid "Arch to make current for"
msgstr "Ағымдағы қылатын архитектура"

#: app/flatpak-builtins-make-current.c:58
msgid "APP BRANCH - Make branch of application current"
msgstr "ҚОЛДАНБА ТАРМАҚ - Қолданба тармағын ағымдағы ету"

#: app/flatpak-builtins-make-current.c:69 app/flatpak-builtins-run.c:260
msgid "APP must be specified"
msgstr "ҚОЛДАНБА көрсетілуі тиіс"

#: app/flatpak-builtins-make-current.c:84
msgid "BRANCH must be specified"
msgstr "ТАРМАҚ көрсетілуі тиіс"

#: app/flatpak-builtins-make-current.c:97
#, c-format
msgid "App %s branch %s is not installed"
msgstr "%s қолданбасының %s тармағы орнатылмаған"

#: app/flatpak-builtins-mask.c:42
msgid "Remove matching masks"
msgstr "Сәйкес келетін маскаларды өшіру"

#: app/flatpak-builtins-mask.c:54
msgid ""
"[PATTERN…] - disable updates and automatic installation matching patterns"
msgstr ""
"[ШАБЛОН…] - Шаблондарға сәйкес келетін жаңартулар мен автоматты орнатуды "
"сөндіру"

#: app/flatpak-builtins-mask.c:73
#, c-format
msgid "No masked patterns\n"
msgstr "Маскаланған шаблондар жоқ\n"

#: app/flatpak-builtins-mask.c:78
#, c-format
msgid "Masked patterns:\n"
msgstr "Маскаланған шаблондар:\n"

#: app/flatpak-builtins-override.c:42
msgid "Remove existing overrides"
msgstr "Бар қайта анықтауларды өшіру"

#: app/flatpak-builtins-override.c:43
msgid "Show existing overrides"
msgstr "Бар қайта анықтауларды көрсету"

#: app/flatpak-builtins-override.c:59
msgid "[APP] - Override settings [for application]"
msgstr "[ҚОЛДАНБА] - [Қолданба үшін] баптауларды қайта анықтау"

#: app/flatpak-builtins-permission-list.c:143
msgid "[TABLE] [ID] - List permissions"
msgstr "[КЕСТЕ] [ID] - Рұқсаттарды тізімдеу"

#: app/flatpak-builtins-permission-list.c:179
#: app/flatpak-builtins-permission-show.c:142
msgid "Table"
msgstr "Кесте"

#: app/flatpak-builtins-permission-list.c:180
#: app/flatpak-builtins-permission-show.c:143
msgid "Object"
msgstr "Объект"

#: app/flatpak-builtins-permission-list.c:181
#: app/flatpak-builtins-permission-show.c:144
msgid "App"
msgstr "Қолданба"

#: app/flatpak-builtins-permission-list.c:183
#: app/flatpak-builtins-permission-show.c:146
msgid "Data"
msgstr "Деректер"

#: app/flatpak-builtins-permission-remove.c:120
msgid "TABLE ID [APP_ID] - Remove item from permission store"
msgstr "КЕСТЕ ID [ҚОЛДАНБА_ID] - Элементті рұқсаттар қоймасынан өшіру"

#: app/flatpak-builtins-permission-remove.c:129
#: app/flatpak-builtins-permission-set.c:120
msgid "Too few arguments"
msgstr "Аргументтер тым аз"

#: app/flatpak-builtins-permission-reset.c:43
msgid "Reset all permissions"
msgstr "Барлық рұқсаттарды тастау"

#: app/flatpak-builtins-permission-reset.c:144
msgid "APP_ID - Reset permissions for an app"
msgstr "ҚОЛДАНБА_ID - Қолданба рұқсаттарын тастау"

#: app/flatpak-builtins-permission-reset.c:153
#: app/flatpak-builtins-permission-show.c:124
msgid "Wrong number of arguments"
msgstr "Аргументтер саны қате"

#: app/flatpak-builtins-permission-set.c:42
msgid "Associate DATA with the entry"
msgstr "Жазбамен ДЕРЕКТЕР-ді байланыстыру"

#: app/flatpak-builtins-permission-set.c:42
msgid "DATA"
msgstr "ДЕРЕКТЕР"

#: app/flatpak-builtins-permission-set.c:111
msgid "TABLE ID APP_ID [PERMISSION...] - Set permissions"
msgstr "КЕСТЕ ID ҚОЛДАНБА_ID [РҰҚСАТ...] - Рұқсаттарды орнату"

#: app/flatpak-builtins-permission-set.c:132
#, c-format
msgid "Failed to parse '%s' as GVariant: "
msgstr "'%s' мәнін GVariant ретінде өңдеу сәтсіз аяқталды: "

#: app/flatpak-builtins-permission-show.c:115
msgid "APP_ID - Show permissions for an app"
msgstr "ҚОЛДАНБА_ID - Қолданба рұқсаттарын көрсету"

#: app/flatpak-builtins-pin.c:44
msgid "Remove matching pins"
msgstr "Сәйкес келетін бекітулерді өшіру"

#: app/flatpak-builtins-pin.c:56
msgid "[PATTERN…] - disable automatic removal of runtimes matching patterns"
msgstr ""
"[ШАБЛОН…] - Шаблондарға сәйкес келетін орындалу орталарын автоматты өшіруді "
"сөндіру"

#: app/flatpak-builtins-pin.c:75
#, c-format
msgid "No pinned patterns\n"
msgstr "Бекітілген шаблондар жоқ\n"

#: app/flatpak-builtins-pin.c:80
#, c-format
msgid "Pinned patterns:\n"
msgstr "Бекітілген шаблондар:\n"

#: app/flatpak-builtins-preinstall.c:80
msgid "- Install flatpaks that are part of the operating system"
msgstr "- Операциялық жүйенің бөлігі болып табылатын flatpak-тарды орнату"

#: app/flatpak-builtins-preinstall.c:118
#, c-format
msgid "Nothing to do.\n"
msgstr "Ештеңе істеу керек емес.\n"

#: app/flatpak-builtins-ps.c:49
msgid "Instance"
msgstr "Инстанция"

#: app/flatpak-builtins-ps.c:49
msgid "Show the instance ID"
msgstr "Инстанция ID-ін көрсету"

#: app/flatpak-builtins-ps.c:50 app/flatpak-builtins-run.c:178
msgid "PID"
msgstr "PID"

#: app/flatpak-builtins-ps.c:50
msgid "Show the PID of the wrapper process"
msgstr "Орауыш процестің PID-ін көрсету"

#: app/flatpak-builtins-ps.c:51
msgid "Child-PID"
msgstr "Бала-PID"

#: app/flatpak-builtins-ps.c:51
msgid "Show the PID of the sandbox process"
msgstr "Құмсалғыш процесінің PID-ін көрсету"

#: app/flatpak-builtins-ps.c:54 app/flatpak-builtins-search.c:48
msgid "Show the application branch"
msgstr "Қолданба тармағын көрсету"

#: app/flatpak-builtins-ps.c:55
msgid "Show the application commit"
msgstr "Қолданба коммитін көрсету"

#: app/flatpak-builtins-ps.c:56
msgid "Show the runtime ID"
msgstr "Орындалу ортасы ID-ін көрсету"

#: app/flatpak-builtins-ps.c:57
msgid "R.-Branch"
msgstr "О.О.-Тармағы"

#: app/flatpak-builtins-ps.c:57
msgid "Show the runtime branch"
msgstr "Орындалу ортасының тармағын көрсету"

#: app/flatpak-builtins-ps.c:58
msgid "R.-Commit"
msgstr "О.О.-Коммиті"

#: app/flatpak-builtins-ps.c:58
msgid "Show the runtime commit"
msgstr "Орындалу ортасының коммитін көрсету"

#: app/flatpak-builtins-ps.c:59
msgid "Active"
msgstr "Белсенді"

#: app/flatpak-builtins-ps.c:59
msgid "Show whether the app is active"
msgstr "Қолданбаның белсенді екенін көрсету"

#: app/flatpak-builtins-ps.c:60
msgid "Background"
msgstr "Фон"

#: app/flatpak-builtins-ps.c:60
msgid "Show whether the app is background"
msgstr "Қолданбаның фонда екенін көрсету"

#: app/flatpak-builtins-ps.c:246
msgid " - Enumerate running sandboxes"
msgstr " - Жұмыс істеп тұрған құмсалғыштарды санап шығу"

#: app/flatpak-builtins-remote-add.c:66
msgid "Do nothing if the provided remote exists"
msgstr "Егер берілген қашықтағы репозиторий бар болса, ештеңе істемеу"

#: app/flatpak-builtins-remote-add.c:67
msgid "LOCATION specifies a configuration file, not the repo location"
msgstr "ОРНЫ репозиторий орнын емес, конфигурация файлын білдіреді"

#: app/flatpak-builtins-remote-add.c:72 app/flatpak-builtins-remote-modify.c:78
msgid "Disable GPG verification"
msgstr "GPG тексеруін сөндіру"

#: app/flatpak-builtins-remote-add.c:73 app/flatpak-builtins-remote-modify.c:79
msgid "Mark the remote as don't enumerate"
msgstr "Қашықтағы репозиторийді санамау ретінде белгілеу"

#: app/flatpak-builtins-remote-add.c:74 app/flatpak-builtins-remote-modify.c:80
msgid "Mark the remote as don't use for deps"
msgstr "Қашықтағы репозиторийді тәуелділіктер үшін қолданбау ретінде белгілеу"

#: app/flatpak-builtins-remote-add.c:75 app/flatpak-builtins-remote-modify.c:81
msgid "Set priority (default 1, higher is more prioritized)"
msgstr ""
"Приоритетті орнату (бастапқысы 1, неғұрлым жоғары болса, соғұрлым басым)"

#: app/flatpak-builtins-remote-add.c:75 app/flatpak-builtins-remote-modify.c:81
msgid "PRIORITY"
msgstr "ПРИОРИТЕТ"

#: app/flatpak-builtins-remote-add.c:76
msgid "The named subset to use for this remote"
msgstr "Осы қашықтағы репозиторий үшін қолданылатын аталған жиын"

#: app/flatpak-builtins-remote-add.c:76 app/flatpak-builtins-remote-modify.c:71
msgid "SUBSET"
msgstr "ЖИЫН"

#: app/flatpak-builtins-remote-add.c:77 app/flatpak-builtins-remote-modify.c:82
msgid "A nice name to use for this remote"
msgstr "Бұл қашықтағы репозиторий үшін қолданылатын жақсы атау"

#: app/flatpak-builtins-remote-add.c:78 app/flatpak-builtins-remote-modify.c:83
msgid "A one-line comment for this remote"
msgstr "Бұл қашықтағы репозиторий үшін бір жолдық түсініктеме"

#: app/flatpak-builtins-remote-add.c:79 app/flatpak-builtins-remote-modify.c:84
msgid "A full-paragraph description for this remote"
msgstr "Бұл қашықтағы репозиторий үшін толық сипаттама"

#: app/flatpak-builtins-remote-add.c:80 app/flatpak-builtins-remote-modify.c:85
msgid "URL for a website for this remote"
msgstr "Бұл қашықтағы репозиторийдің веб-сайты үшін URL"

#: app/flatpak-builtins-remote-add.c:81 app/flatpak-builtins-remote-modify.c:86
msgid "URL for an icon for this remote"
msgstr "Бұл қашықтағы репозиторийдің таңбашасы үшін URL"

#: app/flatpak-builtins-remote-add.c:82 app/flatpak-builtins-remote-modify.c:87
msgid "Default branch to use for this remote"
msgstr "Осы қашықтағы репозиторий үшін бастапқы тармақ"

#: app/flatpak-builtins-remote-add.c:84 app/flatpak-builtins-remote-modify.c:89
msgid "Import GPG key from FILE (- for stdin)"
msgstr "ФАЙЛ-дан GPG кілтін импорттау (stdin үшін -)"

#: app/flatpak-builtins-remote-add.c:85 app/flatpak-builtins-remote-modify.c:90
msgid "Load signatures from URL"
msgstr "Қолтаңбаларды URL-ден жүктеу"

#: app/flatpak-builtins-remote-add.c:86 app/flatpak-builtins-remote-modify.c:92
msgid "Set path to local filter FILE"
msgstr "Жергілікті ФАЙЛ сүзгісіне жолды орнату"

#: app/flatpak-builtins-remote-add.c:87 app/flatpak-builtins-remote-modify.c:93
msgid "Disable the remote"
msgstr "Қашықтағы репозиторийді сөндіру"

#: app/flatpak-builtins-remote-add.c:88 app/flatpak-builtins-remote-modify.c:94
msgid "Name of authenticator"
msgstr "Аутентификатор атауы"

#: app/flatpak-builtins-remote-add.c:90 app/flatpak-builtins-remote-modify.c:96
msgid "Autoinstall authenticator"
msgstr "Аутентификаторды автоматты орнату"

#: app/flatpak-builtins-remote-add.c:91 app/flatpak-builtins-remote-modify.c:97
msgid "Don't autoinstall authenticator"
msgstr "Аутентификаторды автоматты орнатпау"

#: app/flatpak-builtins-remote-add.c:92 app/flatpak-builtins-remote-modify.c:99
msgid "Don't follow the redirect set in the summary file"
msgstr "Жиынтық файлында орнатылған қайта бағыттауды орындамау"

#: app/flatpak-builtins-remote-add.c:261 app/flatpak-builtins-remote-add.c:268
#, c-format
msgid "Can't load uri %s: %s\n"
msgstr "%s uri-ін жүктеу мүмкін емес: %s\n"

#: app/flatpak-builtins-remote-add.c:276 common/flatpak-dir.c:4643
#, c-format
msgid "Can't load file %s: %s\n"
msgstr "%s файлын жүктеу мүмкін емес: %s\n"

#: app/flatpak-builtins-remote-add.c:304
msgid "NAME LOCATION - Add a remote repository"
msgstr "АТЫ ОРНЫ - Қашықтағы репозиторийді қосу"

#: app/flatpak-builtins-remote-add.c:331
msgid "GPG verification is required if collections are enabled"
msgstr "Егер коллекциялар іске қосылса, GPG тексеруі міндетті"

#: app/flatpak-builtins-remote-add.c:393
#, c-format
msgid "Remote %s already exists"
msgstr "%s қашықтағы репозиторийі қазірдің өзінде бар"

#: app/flatpak-builtins-remote-add.c:405
#: app/flatpak-builtins-remote-modify.c:340
#, c-format
msgid "Invalid authenticator name %s"
msgstr "Аутентификатор атауы жарамсыз: %s"

#: app/flatpak-builtins-remote-add.c:422
#, c-format
msgid "Warning: Could not update extra metadata for '%s': %s\n"
msgstr "Ескерту: '%s' үшін қосымша метадеректерді жаңарту мүмкін болмады: %s\n"

#: app/flatpak-builtins-remote-delete.c:39
msgid "Remove remote even if in use"
msgstr "Қолданыста болса да, қашықтағы репозиторийді өшіру"

#: app/flatpak-builtins-remote-delete.c:53
msgid "NAME - Delete a remote repository"
msgstr "АТЫ - Қашықтағы репозиторийді өшіру"

#: app/flatpak-builtins-remote-delete.c:100
#, c-format
msgid "The following refs are installed from remote '%s':"
msgstr "Келесі сілтемелер '%s' қашықтағы репозиторийінен орнатылған:"

#: app/flatpak-builtins-remote-delete.c:101
msgid "Remove them?"
msgstr "Оларды өшіру керек пе?"

#: app/flatpak-builtins-remote-delete.c:103
#, c-format
msgid "Can't remove remote '%s' with installed refs"
msgstr ""
"Орнатылған сілтемелері бар '%s' қашықтағы репозиторийін өшіру мүмкін емес"

#: app/flatpak-builtins-remote-info.c:55
msgid "Commit to show info for"
msgstr "Ақпараты көрсетілетін коммит"

#: app/flatpak-builtins-remote-info.c:58
msgid "Display log"
msgstr "Журналды көрсету"

#: app/flatpak-builtins-remote-info.c:61
msgid "Show parent"
msgstr "Аталығын көрсету"

#: app/flatpak-builtins-remote-info.c:65 app/flatpak-builtins-remote-ls.c:60
msgid "Use local caches even if they are stale"
msgstr "Жергілікті кэштер ескірген болса да, оларды қолдану"

#. Translators: A sideload is when you install from a local USB drive rather than the Internet.
#: app/flatpak-builtins-remote-info.c:67 app/flatpak-builtins-remote-ls.c:62
msgid "Only list refs available as sideloads"
msgstr "Тек қатар жүктеу ретінде қолжетімді сілтемелерді тізімдеу"

#: app/flatpak-builtins-remote-info.c:114
msgid ""
" REMOTE REF - Show information about an application or runtime in a remote"
msgstr ""
" ҚАШЫҚТАҒЫ СІЛТЕМЕ - Қашықтағы репозиторийдегі қолданба немесе орындалу "
"ортасы туралы ақпаратты көрсету"

#: app/flatpak-builtins-remote-info.c:125
msgid "REMOTE and REF must be specified"
msgstr "ҚАШЫҚТАҒЫ және СІЛТЕМЕ көрсетілуі тиіс"

#: app/flatpak-builtins-remote-info.c:247
#: app/flatpak-builtins-remote-info.c:282
msgid "Download Size:"
msgstr "Жүктеп алу өлшемі:"

#: app/flatpak-builtins-remote-info.c:267
#: app/flatpak-builtins-remote-info.c:325
msgid "History:"
msgstr "Тарихы:"

#: app/flatpak-builtins-remote-info.c:348
msgid " Commit:"
msgstr " Коммит:"

#: app/flatpak-builtins-remote-info.c:349
msgid " Subject:"
msgstr " Тақырыбы:"

#: app/flatpak-builtins-remote-info.c:350
msgid " Date:"
msgstr " Күні:"

#: app/flatpak-builtins-remote-info.c:383
#, c-format
msgid "Warning: Commit %s has no flatpak metadata\n"
msgstr "Ескерту: %s коммитінде flatpak метадеректері жоқ\n"

#: app/flatpak-builtins-remote-list.c:43
msgid "Show remote details"
msgstr "Қашықтағы репозиторий мәліметтерін көрсету"

#: app/flatpak-builtins-remote-list.c:44
msgid "Show disabled remotes"
msgstr "Сөндірілген қашықтағы репозиторийлерді көрсету"

#: app/flatpak-builtins-remote-list.c:52
msgid "Title"
msgstr "Атауы"

#: app/flatpak-builtins-remote-list.c:52
msgid "Show the title"
msgstr "Атауын көрсету"

#: app/flatpak-builtins-remote-list.c:53
msgid "Show the URL"
msgstr "URL-ді көрсету"

#: app/flatpak-builtins-remote-list.c:54
msgid "Show the collection ID"
msgstr "Коллекция ID-ін көрсету"

#: app/flatpak-builtins-remote-list.c:55 app/flatpak-builtins-repo.c:392
msgid "Subset"
msgstr "Жиын"

#: app/flatpak-builtins-remote-list.c:55
msgid "Show the subset"
msgstr "Жиынды көрсету"

#: app/flatpak-builtins-remote-list.c:56
msgid "Filter"
msgstr "Сүзгі"

#: app/flatpak-builtins-remote-list.c:56
msgid "Show filter file"
msgstr "Сүзгі файлын көрсету"

#: app/flatpak-builtins-remote-list.c:57
msgid "Priority"
msgstr "Басымдылық"

#: app/flatpak-builtins-remote-list.c:57
msgid "Show the priority"
msgstr "Басымдылықты көрсету"

#: app/flatpak-builtins-remote-list.c:59
msgid "Comment"
msgstr "Түсiнiктеме"

#: app/flatpak-builtins-remote-list.c:59
msgid "Show comment"
msgstr "Түсініктемені көрсету"

#: app/flatpak-builtins-remote-list.c:60
msgid "Show description"
msgstr "Сипаттамасын көрсету"

#: app/flatpak-builtins-remote-list.c:61
msgid "Homepage"
msgstr "Үй беті"

#: app/flatpak-builtins-remote-list.c:61
msgid "Show homepage"
msgstr "Үй бетін көрсету"

#: app/flatpak-builtins-remote-list.c:62
msgid "Icon"
msgstr "Таңбаша"

#: app/flatpak-builtins-remote-list.c:62
msgid "Show icon"
msgstr "Таңбашаны көрсету"

#: app/flatpak-builtins-remote-list.c:231
msgid " - List remote repositories"
msgstr " - Қашықтағы репозиторийлерді тізімдеу"

#: app/flatpak-builtins-remote-ls.c:52
msgid "Show arches and branches"
msgstr "Архитектуралар мен тармақтарды көрсету"

#: app/flatpak-builtins-remote-ls.c:53
msgid "Show only runtimes"
msgstr "Тек орындалу орталарын көрсету"

#: app/flatpak-builtins-remote-ls.c:54
msgid "Show only apps"
msgstr "Тек қолданбаларды көрсету"

#: app/flatpak-builtins-remote-ls.c:55
msgid "Show only those where updates are available"
msgstr "Тек жаңартулары барларын көрсету"

#: app/flatpak-builtins-remote-ls.c:56
msgid "Limit to this arch (* for all)"
msgstr "Осы архитектурамен шектеу (барлығы үшін *)"

#: app/flatpak-builtins-remote-ls.c:77
msgid "Show the runtime"
msgstr "Орындалу ортасын көрсету"

#: app/flatpak-builtins-remote-ls.c:79
msgid "Download size"
msgstr "Жүктеп алу өлшемі"

#: app/flatpak-builtins-remote-ls.c:79
msgid "Show the download size"
msgstr "Жүктеп алу өлшемін көрсету"

#: app/flatpak-builtins-remote-ls.c:391
msgid " [REMOTE or URI] - Show available runtimes and applications"
msgstr ""
" [ҚАШЫҚТАҒЫ немесе URI] - Қолжетімді орындалу орталары мен қолданбаларды "
"көрсету"

#: app/flatpak-builtins-remote-modify.c:67
msgid "Enable GPG verification"
msgstr "GPG тексеруін іске қосу"

#: app/flatpak-builtins-remote-modify.c:68
msgid "Mark the remote as enumerate"
msgstr "Қашықтағы репозиторийді санаулы ретінде белгілеу"

#: app/flatpak-builtins-remote-modify.c:69
msgid "Mark the remote as used for dependencies"
msgstr ""
"Қашықтағы репозиторийді тәуелділіктер үшін қолданылатын ретінде белгілеу"

#: app/flatpak-builtins-remote-modify.c:70
msgid "Set a new URL"
msgstr "Жаңа URL орнату"

#: app/flatpak-builtins-remote-modify.c:71
msgid "Set a new subset to use"
msgstr "Қолданылатын жаңа жиынды орнату"

#: app/flatpak-builtins-remote-modify.c:72
msgid "Enable the remote"
msgstr "Қашықтағы репозиторийді іске қосу"

#: app/flatpak-builtins-remote-modify.c:73
msgid "Update extra metadata from the summary file"
msgstr "Жиынтық файлынан қосымша метадеректерді жаңарту"

#: app/flatpak-builtins-remote-modify.c:91
msgid "Disable local filter"
msgstr "Жергілікті сүзгіні сөндіру"

#: app/flatpak-builtins-remote-modify.c:95
msgid "Authenticator options"
msgstr "Аутентификатор опциялары"

#: app/flatpak-builtins-remote-modify.c:98
msgid "Follow the redirect set in the summary file"
msgstr "Жиынтық файлында орнатылған қайта бағыттауды орындау"

#: app/flatpak-builtins-remote-modify.c:306
msgid "NAME - Modify a remote repository"
msgstr "АТЫ - Қашықтағы репозиторийді өзгерту"

#: app/flatpak-builtins-remote-modify.c:316
msgid "Remote NAME must be specified"
msgstr "Қашықтағы АТЫ көрсетілуі тиіс"

#: app/flatpak-builtins-remote-modify.c:327
#, c-format
msgid "Updating extra metadata from remote summary for %s\n"
msgstr "%s үшін қашықтағы жиынтықтан қосымша метадеректер жаңартылуда\n"

#: app/flatpak-builtins-remote-modify.c:330
#, c-format
msgid "Error updating extra metadata for '%s': %s\n"
msgstr "'%s' үшін қосымша метадеректерді жаңарту қатесі: %s\n"

#: app/flatpak-builtins-remote-modify.c:331
#, c-format
msgid "Could not update extra metadata for %s"
msgstr "%s үшін қосымша метадеректерді жаңарту мүмкін болмады"

#: app/flatpak-builtins-repair.c:43
msgid "Don't make any changes"
msgstr "Ешқандай өзгеріс жасамау"

#: app/flatpak-builtins-repair.c:44
msgid "Reinstall all refs"
msgstr "Барлық сілтемелерді қайта орнату"

#: app/flatpak-builtins-repair.c:68
#, c-format
msgid "Object missing: %s.%s\n"
msgstr "Объект жоқ: %s.%s\n"

#: app/flatpak-builtins-repair.c:76
#, c-format
msgid "Object invalid: %s.%s\n"
msgstr "Объект жарамсыз: %s.%s\n"

#: app/flatpak-builtins-repair.c:81
#, c-format
msgid "%s, deleting object\n"
msgstr "%s, объект өшірілуде\n"

#: app/flatpak-builtins-repair.c:146
#, c-format
msgid "Can't load object %s: %s\n"
msgstr "%s объектісін жүктеу мүмкін емес: %s\n"

#: app/flatpak-builtins-repair.c:228
#, c-format
msgid "Commit invalid %s: %s\n"
msgstr "%s коммиті жарамсыз: %s\n"

#: app/flatpak-builtins-repair.c:231
#, c-format
msgid "Deleting invalid commit %s: %s\n"
msgstr "Жарамсыз %s коммиті өшірілуде: %s\n"

#: app/flatpak-builtins-repair.c:261
#, c-format
msgid "Commit should be marked partial: %s\n"
msgstr "Коммит жартылай деп белгіленуі тиіс: %s\n"

#: app/flatpak-builtins-repair.c:264
#, c-format
msgid "Marking commit as partial: %s\n"
msgstr "Коммитті жартылай деп белгілеу: %s\n"

#: app/flatpak-builtins-repair.c:293
#, c-format
msgid "Problems loading data for %s: %s\n"
msgstr "%s үшін деректерді жүктеу кезіндегі мәселелер: %s\n"

#: app/flatpak-builtins-repair.c:306
#, c-format
msgid "Error reinstalling %s: %s\n"
msgstr "%s қайта орнату қатесі: %s\n"

#: app/flatpak-builtins-repair.c:327
msgid "- Repair a flatpak installation"
msgstr "- Flatpak орнатылымын жөндеу"

#: app/flatpak-builtins-repair.c:406
#, c-format
msgid "Removing non-deployed ref %s…\n"
msgstr "Орналастырылмаған %s сілтемесі өшірілуде…\n"

#: app/flatpak-builtins-repair.c:411
#, c-format
msgid "Skipping non-deployed ref %s…\n"
msgstr "Орналастырылмаған %s сілтемесі өткізіліп жіберілуде…\n"

#: app/flatpak-builtins-repair.c:429
#, c-format
msgid "[%d/%d] Verifying %s…\n"
msgstr "[%d/%d] %s тексерілуде…\n"

#: app/flatpak-builtins-repair.c:435
#, c-format
msgid "Dry run: "
msgstr "Сынақ ретінде орындау: "

#: app/flatpak-builtins-repair.c:440
#, c-format
msgid "Deleting ref %s due to missing objects\n"
msgstr "Объектілер жоқ болғандықтан %s сілтемесі өшірілуде\n"

#: app/flatpak-builtins-repair.c:444
#, c-format
msgid "Deleting ref %s due to invalid objects\n"
msgstr "Объектілер жарамсыз болғандықтан %s сілтемесі өшірілуде\n"

#: app/flatpak-builtins-repair.c:448
#, c-format
msgid "Deleting ref %s due to %d\n"
msgstr "%2$d себебінен %1$s сілтемесі өшірілуде\n"

#: app/flatpak-builtins-repair.c:464
#, c-format
msgid "Checking remotes...\n"
msgstr "Қашықтағы репозиторийлер тексерілуде...\n"

#: app/flatpak-builtins-repair.c:482
#, c-format
msgid "Remote %s for ref %s is missing\n"
msgstr "%2$s сілтемесі үшін %1$s қашықтағы репозиторийі жоқ\n"

#: app/flatpak-builtins-repair.c:484
#, c-format
msgid "Remote %s for ref %s is disabled\n"
msgstr "%2$s сілтемесі үшін %1$s қашықтағы репозиторийі сөндірілген\n"

#: app/flatpak-builtins-repair.c:490
#, c-format
msgid "Pruning objects\n"
msgstr "Объектілер тазалануда\n"

#: app/flatpak-builtins-repair.c:498
#, c-format
msgid "Erasing .removed\n"
msgstr ".removed жойылуда\n"

#: app/flatpak-builtins-repair.c:524
#, c-format
msgid "Reinstalling refs\n"
msgstr "Сілтемелер қайта орнатылуда\n"

#: app/flatpak-builtins-repair.c:526
#, c-format
msgid "Reinstalling removed refs\n"
msgstr "Өшірілген сілтемелер қайта орнатылуда\n"

#: app/flatpak-builtins-repair.c:551
#, c-format
msgid "While removing appstream for %s: "
msgstr "%s үшін appstream өшіру кезінде: "

#: app/flatpak-builtins-repair.c:558
#, c-format
msgid "While deploying appstream for %s: "
msgstr "%s үшін appstream орналастыру кезінде: "

#: app/flatpak-builtins-repo.c:106
#, c-format
msgid "Repo mode: %s\n"
msgstr "Репозиторий режимі: %s\n"

#: app/flatpak-builtins-repo.c:113
#, c-format
msgid "Indexed summaries: %s\n"
msgstr "Индекстелген жиынтықтар: %s\n"

#: app/flatpak-builtins-repo.c:113 app/flatpak-builtins-repo.c:139
#: app/flatpak-builtins-repo.c:172
msgid "true"
msgstr "true"

#: app/flatpak-builtins-repo.c:113 app/flatpak-builtins-repo.c:139
#: app/flatpak-builtins-repo.c:172
msgid "false"
msgstr "false"

#: app/flatpak-builtins-repo.c:121
#, c-format
msgid "Subsummaries: "
msgstr "Ішкі жиынтықтар: "

#: app/flatpak-builtins-repo.c:136
#, c-format
msgid "Cache version: %d\n"
msgstr "Кэш нұсқасы: %d\n"

#: app/flatpak-builtins-repo.c:139
#, c-format
msgid "Indexed deltas: %s\n"
msgstr "Индекстелген дельталар: %s\n"

#: app/flatpak-builtins-repo.c:142
#, c-format
msgid "Title: %s\n"
msgstr "Тақырыбы: %s\n"

#: app/flatpak-builtins-repo.c:145
#, c-format
msgid "Comment: %s\n"
msgstr "Түсініктеме: %s\n"

#: app/flatpak-builtins-repo.c:148
#, c-format
msgid "Description: %s\n"
msgstr "Сипаттама: %s\n"

#: app/flatpak-builtins-repo.c:151
#, c-format
msgid "Homepage: %s\n"
msgstr "Үй беті: %s\n"

#: app/flatpak-builtins-repo.c:154
#, c-format
msgid "Icon: %s\n"
msgstr "Таңбаша: %s\n"

#: app/flatpak-builtins-repo.c:157
#, c-format
msgid "Collection ID: %s\n"
msgstr "Коллекция ID-і: %s\n"

#: app/flatpak-builtins-repo.c:160
#, c-format
msgid "Default branch: %s\n"
msgstr "Бастапқы тармақ: %s\n"

#: app/flatpak-builtins-repo.c:163
#, c-format
msgid "Redirect URL: %s\n"
msgstr "Қайта бағыттау URL-і: %s\n"

#: app/flatpak-builtins-repo.c:166
#, c-format
msgid "Deploy collection ID: %s\n"
msgstr "Коллекция ID-ін орналастыру: %s\n"

#: app/flatpak-builtins-repo.c:169
#, c-format
msgid "Authenticator name: %s\n"
msgstr "Аутентификатор атауы: %s\n"

#: app/flatpak-builtins-repo.c:172
#, c-format
msgid "Authenticator install: %s\n"
msgstr "Аутентификатор орнату: %s\n"

#: app/flatpak-builtins-repo.c:180
#, c-format
msgid "GPG key hash: %s\n"
msgstr "GPG кілт хэші: %s\n"

#: app/flatpak-builtins-repo.c:184
#, c-format
msgid "%zd summary branches\n"
msgstr "%zd жиынтық тармағы\n"

#: app/flatpak-builtins-repo.c:336
msgid "Installed"
msgstr "Орнатылған"

#. Translators: Download is used here as a noun
#: app/flatpak-builtins-repo.c:338 app/flatpak-cli-transaction.c:1462
msgid "Download"
msgstr "Жүктеп алу"

#: app/flatpak-builtins-repo.c:339
msgid "Subsets"
msgstr "Жиындар"

#: app/flatpak-builtins-repo.c:393
msgid "Digest"
msgstr "Дайджест"

#: app/flatpak-builtins-repo.c:394
msgid "History length"
msgstr "Тарих ұзындығы"

#: app/flatpak-builtins-repo.c:711
msgid "Print general information about the repository"
msgstr "Репозиторий туралы жалпы ақпаратты шығару"

#: app/flatpak-builtins-repo.c:712
msgid "List the branches in the repository"
msgstr "Репозиторийдегі тармақтарды тізімдеу"

#: app/flatpak-builtins-repo.c:713
msgid "Print metadata for a branch"
msgstr "Тармақ үшін метадеректерді шығару"

#: app/flatpak-builtins-repo.c:714
msgid "Show commits for a branch"
msgstr "Тармақ үшін коммиттерді көрсету"

#: app/flatpak-builtins-repo.c:715
msgid "Print information about the repo subsets"
msgstr "Репо жиындары туралы ақпаратты шығару"

#: app/flatpak-builtins-repo.c:716
msgid "Limit information to subsets with this prefix"
msgstr "Ақпаратты осы префиксі бар жиындармен шектеу"

#: app/flatpak-builtins-repo.c:732
msgid "LOCATION - Repository maintenance"
msgstr "ОРНЫ - Репозиторийге техникалық қызмет көрсету"

#: app/flatpak-builtins-run.c:159
msgid "Command to run"
msgstr "Орындалатын команда"

#: app/flatpak-builtins-run.c:160
msgid "Directory to run the command in"
msgstr "Команда орындалатын бума"

#: app/flatpak-builtins-run.c:161
msgid "Branch to use"
msgstr "Қолданылатын тармақ"

#: app/flatpak-builtins-run.c:162
msgid "Use development runtime"
msgstr "Әзірлеуге арналған орындалу ортасын қолдану"

#: app/flatpak-builtins-run.c:163
msgid "Runtime to use"
msgstr "Қолданылатын орындалу ортасы"

#: app/flatpak-builtins-run.c:164
msgid "Runtime version to use"
msgstr "Қолданылатын орындалу ортасының нұсқасы"

#: app/flatpak-builtins-run.c:167
msgid "Log accessibility bus calls"
msgstr "Арнайы мүмкіндіктер шинасының шақыруларын журналдау"

#: app/flatpak-builtins-run.c:168
msgid "Don't proxy accessibility bus calls"
msgstr "Арнайы мүмкіндіктер шинасының шақыруларын проксилемеу"

#: app/flatpak-builtins-run.c:169
msgid "Proxy accessibility bus calls (default except when sandboxed)"
msgstr ""
"Арнайы мүмкіндіктер шинасының шақыруларын проксилеу (құмсалғышта болғаннан "
"басқа жағдайда бастапқы)"

#: app/flatpak-builtins-run.c:170
msgid "Don't proxy session bus calls"
msgstr "Сессия шинасының шақыруларын проксилемеу"

#: app/flatpak-builtins-run.c:171
msgid "Proxy session bus calls (default except when sandboxed)"
msgstr ""
"Сессия шинасының шақыруларын проксилеу (құмсалғышта болғаннан басқа жағдайда "
"бастапқы)"

#: app/flatpak-builtins-run.c:172
msgid "Don't start portals"
msgstr "Порталдарды іске қоспау"

#: app/flatpak-builtins-run.c:173
msgid "Enable file forwarding"
msgstr "Файлды қайта бағыттауды іске қосу"

#: app/flatpak-builtins-run.c:174
msgid "Run specified commit"
msgstr "Көрсетілген коммитті орындау"

#: app/flatpak-builtins-run.c:175
msgid "Use specified runtime commit"
msgstr "Көрсетілген орындалу ортасының коммитін қолдану"

#: app/flatpak-builtins-run.c:176
msgid "Run completely sandboxed"
msgstr "Толық құмсалғышта орындау"

#: app/flatpak-builtins-run.c:178
msgid "Use PID as parent pid for sharing namespaces"
msgstr "Атау кеңістіктерін бөлісу үшін PID-ті аталық pid ретінде қолдану"

#: app/flatpak-builtins-run.c:179
msgid "Make processes visible in parent namespace"
msgstr "Процестерді аталық атау кеңістігінде көрінетін ету"

#: app/flatpak-builtins-run.c:180
msgid "Share process ID namespace with parent"
msgstr "Процесс ID атау кеңістігін аталықпен бөлісу"

#: app/flatpak-builtins-run.c:181
msgid "Write the instance ID to the given file descriptor"
msgstr "Инстанция ID-ін берілген файл дескрипторына жазу"

#: app/flatpak-builtins-run.c:182
msgid "Use PATH instead of the app's /app"
msgstr "Қолданбаның /app орнына ЖОЛ-ды қолдану"

#: app/flatpak-builtins-run.c:183
#, fuzzy
msgid "Use FD instead of the app's /app"
msgstr "Қолданбаның /app орнына ЖОЛ-ды қолдану"

#: app/flatpak-builtins-run.c:183 app/flatpak-builtins-run.c:185
#: app/flatpak-builtins-run.c:187 app/flatpak-builtins-run.c:188
#: common/flatpak-context.c:2672
msgid "FD"
msgstr "FD"

#: app/flatpak-builtins-run.c:184
msgid "Use PATH instead of the runtime's /usr"
msgstr "Орындалу ортасының /usr орнына ЖОЛ-ды қолдану"

#: app/flatpak-builtins-run.c:185
#, fuzzy
msgid "Use FD instead of the runtime's /usr"
msgstr "Орындалу ортасының /usr орнына ЖОЛ-ды қолдану"

#: app/flatpak-builtins-run.c:186
msgid "Clear all outside environment variables"
msgstr "Барлық сыртқы орта айнымалыларын тазалау"

#: app/flatpak-builtins-run.c:187
msgid ""
"Bind mount the file or directory referred to by FD to its canonicalized path"
msgstr ""

#: app/flatpak-builtins-run.c:188
msgid ""
"Bind mount the file or directory referred to by FD read-only to its "
"canonicalized path"
msgstr ""

#: app/flatpak-builtins-run.c:219
msgid "APP [ARGUMENT…] - Run an app"
msgstr "ҚОЛДАНБА [АРГУМЕНТ…] - Қолданбаны орындау"

#: app/flatpak-builtins-run.c:370
#, c-format
msgid "runtime/%s/%s/%s not installed"
msgstr "runtime/%s/%s/%s орнатылмаған"

#: app/flatpak-builtins-run.c:419
msgid "app-fd and app-path cannot both be used"
msgstr ""

#: app/flatpak-builtins-run.c:449
msgid "usr-fd and usr-path cannot both be used"
msgstr ""

#: app/flatpak-builtins-search.c:37
msgid "Arch to search for"
msgstr "Ізделетін архитектура"

#: app/flatpak-builtins-search.c:49
msgid "Remotes"
msgstr "Қашықтағы репозиторийлер"

#: app/flatpak-builtins-search.c:49
msgid "Show the remotes"
msgstr "Қашықтағы репозиторийлерді көрсету"

#: app/flatpak-builtins-search.c:244
msgid "TEXT - Search remote apps/runtimes for text"
msgstr "МӘТІН - Қашықтағы қолданбалардан/орындалу орталарынан мәтінді іздеу"

#: app/flatpak-builtins-search.c:255
msgid "TEXT must be specified"
msgstr "МӘТІН көрсетілуі тиіс"

#: app/flatpak-builtins-search.c:338
msgid "No matches found"
msgstr "Сәйкестіктер табылмады"

#: app/flatpak-builtins-uninstall.c:54
msgid "Arch to uninstall"
msgstr "Өшірілетін архитектура"

#: app/flatpak-builtins-uninstall.c:55
msgid "Keep ref in local repository"
msgstr "Сілтемені жергілікті репозиторийде сақтау"

#: app/flatpak-builtins-uninstall.c:56
msgid "Don't uninstall related refs"
msgstr "Қатысты сілтемелерді өшірмеу"

#: app/flatpak-builtins-uninstall.c:57
msgid "Remove files even if running"
msgstr "Жұмыс істеп тұрса да, файлдарды өшіру"

#: app/flatpak-builtins-uninstall.c:60
msgid "Uninstall all"
msgstr "Барлығын өшіру"

#: app/flatpak-builtins-uninstall.c:61
msgid "Uninstall unused"
msgstr "Қолданылмайтындарды өшіру"

#: app/flatpak-builtins-uninstall.c:62
msgid "Delete app data"
msgstr "Қолданба деректерін өшіру"

#: app/flatpak-builtins-uninstall.c:141
#, c-format
msgid "Delete data for %s?"
msgstr "%s үшін деректерді өшіру керек пе?"

#: app/flatpak-builtins-uninstall.c:220
#, c-format
msgid "Info: applications using the extension %s%s%s branch %s%s%s:\n"
msgstr "Ақпарат: %s%s%s кеңейтуінің %s%s%s тармағын қолданатын қолданбалар:\n"

#: app/flatpak-builtins-uninstall.c:223
#, c-format
msgid "Info: applications using the runtime %s%s%s branch %s%s%s:\n"
msgstr ""
"Ақпарат: %s%s%s орындалу ортасының %s%s%s тармағын қолданатын қолданбалар:\n"

#: app/flatpak-builtins-uninstall.c:238
msgid "Really remove?"
msgstr "Шынымен өшіру керек пе?"

#: app/flatpak-builtins-uninstall.c:255
msgid "[REF…] - Uninstall applications or runtimes"
msgstr "[СІЛТЕМЕ…] - Қолданбаларды немесе орындалу орталарын өшіру"

#: app/flatpak-builtins-uninstall.c:264
msgid "Must specify at least one REF, --unused, --all or --delete-data"
msgstr ""
"Кем дегенде бір СІЛТЕМЕ, --unused, --all немесе --delete-data көрсетілуі тиіс"

#: app/flatpak-builtins-uninstall.c:267
msgid "Must not specify REFs when using --all"
msgstr "--all қолданғанда СІЛТЕМЕ-лер көрсетілмеуі тиіс"

#: app/flatpak-builtins-uninstall.c:270
msgid "Must not specify REFs when using --unused"
msgstr "--unused қолданғанда СІЛТЕМЕ-лер көрсетілмеуі тиіс"

#: app/flatpak-builtins-uninstall.c:336
#, c-format
msgid ""
"\n"
"These runtimes in installation '%s' are pinned and won't be removed; see "
"flatpak-pin(1):\n"
msgstr ""
"\n"
"'%s' орнатылымындағы мына орындалу орталары бекітілген (pinned) және "
"өшірілмейді; flatpak-pin(1) қараңыз:\n"

#: app/flatpak-builtins-uninstall.c:370
#, c-format
msgid "Nothing unused to uninstall\n"
msgstr "Өшіретін қолданылмайтын ештеңе жоқ\n"

#: app/flatpak-builtins-uninstall.c:444
#, c-format
msgid "No installed refs found for ‘%s’"
msgstr "‘%s’ үшін орнатылған сілтемелер табылмады"

#: app/flatpak-builtins-uninstall.c:447
#, c-format
msgid " with arch ‘%s’"
msgstr " ‘%s’ архитектурасымен"

#: app/flatpak-builtins-uninstall.c:449
#, c-format
msgid " with branch ‘%s’"
msgstr " ‘%s’ тармағымен"

#: app/flatpak-builtins-uninstall.c:456
#, c-format
msgid "Warning: %s is not installed\n"
msgstr "Ескерту: %s орнатылмаған\n"

#: app/flatpak-builtins-uninstall.c:490
#, c-format
msgid "None of the specified refs are installed"
msgstr "Көрсетілген сілтемелердің ешқайсысы орнатылмаған"

#: app/flatpak-builtins-uninstall.c:599
#, c-format
msgid "No app data to delete\n"
msgstr "Өшірілетін қолданба деректері жоқ\n"

#: app/flatpak-builtins-update.c:56
msgid "Arch to update for"
msgstr "Жаңартылатын архитектура"

#: app/flatpak-builtins-update.c:57
msgid "Commit to deploy"
msgstr "Орналастырылатын коммит"

#: app/flatpak-builtins-update.c:58
msgid "Remove old files even if running"
msgstr "Жұмыс істеп тұрса да, ескі файлдарды өшіру"

#: app/flatpak-builtins-update.c:59
msgid "Don't pull, only update from local cache"
msgstr "Тартпау, тек жергілікті кэштен жаңарту"

#: app/flatpak-builtins-update.c:61
msgid "Don't update related refs"
msgstr "Қатысты сілтемелерді жаңартпау"

#: app/flatpak-builtins-update.c:66
msgid "Update appstream for remote"
msgstr "Қашықтағы репозиторий үшін appstream жаңарту"

#: app/flatpak-builtins-update.c:67
msgid "Only update this subpath"
msgstr "Тек осы ішкі жолды жаңарту"

#: app/flatpak-builtins-update.c:90
msgid "[REF…] - Update applications or runtimes"
msgstr "[СІЛТЕМЕ…] - Қолданбаларды немесе орындалу орталарын жаңарту"

#: app/flatpak-builtins-update.c:121
msgid "With --commit, only one REF may be specified"
msgstr "--commit қолданғанда, тек бір СІЛТЕМЕ көрсетілуі мүмкін"

#: app/flatpak-builtins-update.c:162
#, c-format
msgid "Looking for updates…\n"
msgstr "Жаңартулар ізделуде…\n"

#: app/flatpak-builtins-update.c:215
#, c-format
msgid "Unable to update %s: %s\n"
msgstr "%s жаңарту мүмкін емес: %s\n"

#: app/flatpak-builtins-update.c:274
#, c-format
msgid "Nothing to update.\n"
msgstr "Жаңартатын ештеңе жоқ.\n"

#: app/flatpak-builtins-utils.c:337
#, c-format
msgid ""
"Remote ‘%s’ found in multiple installations, unable to proceed in non-"
"interactive mode"
msgstr ""
"‘%s’ қашықтағы репозиторийі бірнеше орнатылымда табылды, интерактивті емес "
"режимде жалғастыру мүмкін емес"

#: app/flatpak-builtins-utils.c:346
#, c-format
msgid "Remote ‘%s’ found in multiple installations:"
msgstr "‘%s’ қашықтағы репозиторийі бірнеше орнатылымда табылды:"

#: app/flatpak-builtins-utils.c:347 app/flatpak-builtins-utils.c:442
#: app/flatpak-builtins-utils.c:538 app/flatpak-builtins-utils.c:540
#: app/flatpak-builtins-utils.c:598
msgid "Which do you want to use (0 to abort)?"
msgstr "Қайсысын қолданғыңыз келеді (бас тарту үшін 0)?"

#: app/flatpak-builtins-utils.c:349
#, c-format
msgid "No remote chosen to resolve ‘%s’ which exists in multiple installations"
msgstr ""
"Бірнеше орнатылымда бар ‘%s’ сәйкестігін шешу үшін ешқандай қашықтағы "
"репозиторий таңдалмады"

#: app/flatpak-builtins-utils.c:358
#, c-format
msgid ""
"Remote \"%s\" not found\n"
"Hint: Use flatpak remote-add to add a remote"
msgstr ""
"\"%s\" қашықтағы репозиторийі табылмады\n"
"Кеңес: Қашықтағы репозиторийді қосу үшін flatpak remote-add қолданыңыз"

#: app/flatpak-builtins-utils.c:364
#, c-format
msgid "Remote \"%s\" not found in the %s installation"
msgstr "\"%s\" қашықтағы репозиторийі %s орнатылымынан табылмады"

#: app/flatpak-builtins-utils.c:404
#, c-format
msgid "Multiple refs match ‘%s’, unable to proceed in non-interactive mode"
msgstr ""
"‘%s’ сұранысына бірнеше сілтеме сәйкес келеді, интерактивті емес режимде "
"жалғастыру мүмкін емес"

#. default to yes on Enter
#: app/flatpak-builtins-utils.c:430
#, c-format
msgid ""
"Found ref ‘%s’ in remote ‘%s’ (%s).\n"
"Use this ref?"
msgstr ""
"‘%2$s’ (%3$s) қашықтағы репозиторийден ‘%1$s’ сілтемесі табылды.\n"
"Осы сілтемені қолдану керек пе?"

#: app/flatpak-builtins-utils.c:434 app/flatpak-builtins-utils.c:444
#: app/flatpak-builtins-utils.c:522 app/flatpak-builtins-utils.c:543
#, c-format
msgid "No ref chosen to resolve matches for ‘%s’"
msgstr "‘%s’ үшін сәйкестіктерді шешуге ешқандай сілтеме таңдалмады"

#: app/flatpak-builtins-utils.c:440
#, c-format
msgid "Similar refs found for ‘%s’ in remote ‘%s’ (%s):"
msgstr ""
"‘%2$s’ (%3$s) қашықтағы репозиторийден ‘%1$s’ үшін ұқсас сілтемелер табылды:"

#: app/flatpak-builtins-utils.c:488
#, c-format
msgid ""
"Multiple installed refs match ‘%s’, unable to proceed in non-interactive mode"
msgstr ""
"‘%s’ сұранысына бірнеше орнатылған сілтеме сәйкес келеді, интерактивті емес "
"режимде жалғастыру мүмкін емес"

#. default to yes on Enter
#: app/flatpak-builtins-utils.c:518
#, c-format
msgid "Found installed ref ‘%s’ (%s). Is this correct?"
msgstr "Орнатылған ‘%s’ (%s) сілтемесі табылды. Бұл дұрыс па?"

#: app/flatpak-builtins-utils.c:534
#, c-format
msgid "All of the above"
msgstr "Жоғарыдағылардың барлығы"

#: app/flatpak-builtins-utils.c:535
#, c-format
msgid "Similar installed refs found for ‘%s’:"
msgstr "‘%s’ үшін ұқсас орнатылған сілтемелер табылды:"

#: app/flatpak-builtins-utils.c:579
#, c-format
msgid ""
"Multiple remotes have refs matching ‘%s’, unable to proceed in non-"
"interactive mode"
msgstr ""
"Бірнеше қашықтағы репозиторийде ‘%s’ сәйкес келетін сілтемелер бар, "
"интерактивті емес режимде жалғастыру мүмкін емес"

#: app/flatpak-builtins-utils.c:597
#, c-format
msgid "Remotes found with refs similar to ‘%s’:"
msgstr ""
"‘%s’ сілтемесіне ұқсас сілтемелері бар қашықтағы репозиторийлер табылды:"

#: app/flatpak-builtins-utils.c:600
#, c-format
msgid "No remote chosen to resolve matches for ‘%s’"
msgstr ""
"‘%s’ үшін сәйкестіктерді шешуге ешқандай қашықтағы репозиторий таңдалмады"

#: app/flatpak-builtins-utils.c:696 app/flatpak-builtins-utils.c:699
#, c-format
msgid "Updating appstream data for user remote %s"
msgstr ""
"Пайдаланушының %s қашықтағы репозиторийі үшін appstream деректері жаңартылуда"

#: app/flatpak-builtins-utils.c:706 app/flatpak-builtins-utils.c:709
#, c-format
msgid "Updating appstream data for remote %s"
msgstr "%s қашықтағы репозиторийі үшін appstream деректері жаңартылуда"

#: app/flatpak-builtins-utils.c:717 app/flatpak-builtins-utils.c:719
msgid "Error updating"
msgstr "Жаңарту қатесі"

#: app/flatpak-builtins-utils.c:755
#, c-format
msgid "Remote \"%s\" not found"
msgstr "\"%s\" қашықтағы репозиторийі табылмады"

#: app/flatpak-builtins-utils.c:796
#, c-format
msgid "Ambiguous suffix: '%s'."
msgstr "Екіұшты суффикс: '%s'."

#. Translators: don't translate the values
#: app/flatpak-builtins-utils.c:798 app/flatpak-builtins-utils.c:813
msgid "Possible values are :s[tart], :m[iddle], :e[nd] or :f[ull]"
msgstr "Мүмкін мәндер: :s[tart], :m[iddle], :e[nd] немесе :f[ull]"

#: app/flatpak-builtins-utils.c:811
#, c-format
msgid "Invalid suffix: '%s'."
msgstr "Жарамсыз суффикс: '%s'."

#: app/flatpak-builtins-utils.c:846
#, c-format
msgid "Ambiguous column: %s"
msgstr "Екіұшты баған: %s"

#: app/flatpak-builtins-utils.c:859
#, c-format
msgid "Unknown column: %s"
msgstr "Белгісіз баған: %s"

#: app/flatpak-builtins-utils.c:917
msgid "Available columns:\n"
msgstr "Қолжетімді бағандар:\n"

#: app/flatpak-builtins-utils.c:927
msgid "Show all columns"
msgstr "Барлық бағандарды көрсету"

#: app/flatpak-builtins-utils.c:928
msgid "Show available columns"
msgstr "Қолжетімді бағандарды көрсету"

#: app/flatpak-builtins-utils.c:931
msgid "Append :s[tart], :m[iddle], :e[nd] or :f[ull] to change ellipsization"
msgstr ""
"Көпнүктені өзгерту үшін :s[tart], :m[iddle], :e[nd] немесе :f[ull] жалғаңыз"

#: app/flatpak-builtins-utils.c:1483
#, c-format
msgid "Unknown scheme in sideload location %s"
msgstr "%s қатар жүктеу орнындағы схема белгісіз"

#: app/flatpak-cli-transaction.c:96 app/flatpak-cli-transaction.c:102
#, c-format
msgid "Required runtime for %s (%s) found in remote %s\n"
msgstr ""
"%s (%s) үшін қажетті орындалу ортасы %s қашықтағы репозиторийінен табылды\n"

#: app/flatpak-cli-transaction.c:104
msgid "Do you want to install it?"
msgstr "Оны орнатқыңыз келеді ме?"

#: app/flatpak-cli-transaction.c:110
#, c-format
msgid "Required runtime for %s (%s) found in remotes:"
msgstr ""
"%s (%s) үшін қажетті орындалу ортасы мына қашықтағы репозиторийлерден "
"табылды:"

#: app/flatpak-cli-transaction.c:112
msgid "Which do you want to install (0 to abort)?"
msgstr "Қайсысын орнатқыңыз келеді (бас тарту үшін 0)?"

#: app/flatpak-cli-transaction.c:132
#, c-format
msgid "Configuring %s as new remote '%s'\n"
msgstr "%s жаңа '%s' қашықтағы репозиторийі ретінде конфигурациялануда\n"

#. default to yes on Enter
#: app/flatpak-cli-transaction.c:139
#, c-format
msgid ""
"The remote '%s', referred to by '%s' at location %s contains additional "
"applications.\n"
"Should the remote be kept for future installations?"
msgstr ""
"%3$s орнындағы '%2$s' сілтеме жасаған '%1$s' қашықтағы репозиторийінде "
"қосымша қолданбалар бар.\n"
"Қашықтағы репозиторийді болашақ орнатылымдар үшін сақтау керек пе?"

#. default to yes on Enter
#: app/flatpak-cli-transaction.c:147
#, c-format
msgid ""
"The application %s depends on runtimes from:\n"
"  %s\n"
"Configure this as new remote '%s'"
msgstr ""
"%s қолданбасы мына жердегі орындалу орталарына тәуелді:\n"
"  %s\n"
"Мұны жаңа '%s' қашықтағы репозиторийі ретінде конфигурациялау керек пе?"

#. Formatted size/remaining time in seconds
#: app/flatpak-cli-transaction.c:321
#, c-format
msgid "%s/s%s%s"
msgstr "%s/с%s%s"

#. Download progress percentage, use the appropriate
#. percent format for your language
#: app/flatpak-cli-transaction.c:359
#, c-format
msgid "%3d%%"
msgstr "%3d%%"

#: app/flatpak-cli-transaction.c:414
msgid "Installing…"
msgstr "Орнатылуда…"

#: app/flatpak-cli-transaction.c:416
#, c-format
msgid "Installing %d/%d…"
msgstr "%d/%d орнатылуда…"

#: app/flatpak-cli-transaction.c:421
msgid "Updating…"
msgstr "Жаңартылуда…"

#: app/flatpak-cli-transaction.c:423
#, c-format
msgid "Updating %d/%d…"
msgstr "%d/%d жаңартылуда…"

#: app/flatpak-cli-transaction.c:428
msgid "Uninstalling…"
msgstr "Өшірілуде…"

#: app/flatpak-cli-transaction.c:430
#, c-format
msgid "Uninstalling %d/%d…"
msgstr "%d/%d өшірілуде…"

#: app/flatpak-cli-transaction.c:496 app/flatpak-quiet-transaction.c:161
#, c-format
msgid "Info: %s was skipped"
msgstr "Ақпарат: %s өткізіліп жіберілді"

#: app/flatpak-cli-transaction.c:519
#, c-format
msgid "Warning: %s%s%s already installed"
msgstr "Ескерту: %s%s%s қазірдің өзінде орнатылған"

#: app/flatpak-cli-transaction.c:522
#, c-format
msgid "Error: %s%s%s already installed"
msgstr "Қате: %s%s%s қазірдің өзінде орнатылған"

#: app/flatpak-cli-transaction.c:528
#, c-format
msgid "Warning: %s%s%s not installed"
msgstr "Ескерту: %s%s%s орнатылмаған"

#: app/flatpak-cli-transaction.c:531
#, c-format
msgid "Error: %s%s%s not installed"
msgstr "Қате: %s%s%s орнатылмаған"

#: app/flatpak-cli-transaction.c:537
#, c-format
msgid "Warning: %s%s%s needs a later flatpak version"
msgstr "Ескерту: %s%s%s үшін кейінгі flatpak нұсқасы қажет"

#: app/flatpak-cli-transaction.c:540
#, c-format
msgid "Error: %s%s%s needs a later flatpak version"
msgstr "Қате: %s%s%s үшін кейінгі flatpak нұсқасы қажет"

#: app/flatpak-cli-transaction.c:546
msgid "Warning: Not enough disk space to complete this operation"
msgstr "Ескерту: Бұл операцияны аяқтау үшін дискіде орын жеткіліксіз"

#: app/flatpak-cli-transaction.c:548
msgid "Error: Not enough disk space to complete this operation"
msgstr "Қате: Бұл операцияны аяқтау үшін дискіде орын жеткіліксіз"

#: app/flatpak-cli-transaction.c:553
#, c-format
msgid "Warning: %s"
msgstr "Ескерту: %s"

#: app/flatpak-cli-transaction.c:555
#, c-format
msgid "Error: %s"
msgstr "Қате: %s"

#: app/flatpak-cli-transaction.c:570
#, c-format
msgid "Failed to install %s%s%s: "
msgstr "%s%s%s орнату сәтсіз аяқталды: "

#: app/flatpak-cli-transaction.c:577
#, c-format
msgid "Failed to update %s%s%s: "
msgstr "%s%s%s жаңарту сәтсіз аяқталды: "

#: app/flatpak-cli-transaction.c:584
#, c-format
msgid "Failed to install bundle %s%s%s: "
msgstr "%s%s%s дестесін орнату сәтсіз аяқталды: "

#: app/flatpak-cli-transaction.c:591
#, c-format
msgid "Failed to uninstall %s%s%s: "
msgstr "%s%s%s өшіру сәтсіз аяқталды: "

#: app/flatpak-cli-transaction.c:642
#, c-format
msgid "Authentication required for remote '%s'\n"
msgstr "'%s' қашықтағы репозиторийі үшін аутентификация қажет\n"

#: app/flatpak-cli-transaction.c:643
msgid "Open browser?"
msgstr "Браузерді ашу керек пе?"

#: app/flatpak-cli-transaction.c:699
#, c-format
msgid "Login required remote %s (realm %s)\n"
msgstr "%s қашықтағы репозиторийі үшін кіру қажет (realm %s)\n"

#: app/flatpak-cli-transaction.c:704
msgid "Password"
msgstr "Пароль"

#. Only runtimes can be pinned
#: app/flatpak-cli-transaction.c:759
#, c-format
msgid ""
"\n"
"Info: (pinned) runtime %s%s%s branch %s%s%s is end-of-life, in favor of "
"%s%s%s branch %s%s%s\n"
msgstr ""
"\n"
"Ақпарат: (бекітілген) %s%s%s орындалу ортасының %s%s%s тармағының қолдау "
"мерзімі аяқталды, оның орнына %s%s%s орындалу ортасының %s%s%s тармағын "
"қолданыңыз\n"

#: app/flatpak-cli-transaction.c:765
#, c-format
msgid ""
"\n"
"Info: runtime %s%s%s branch %s%s%s is end-of-life, in favor of %s%s%s branch "
"%s%s%s\n"
msgstr ""
"\n"
"Ақпарат: %s%s%s орындалу ортасының %s%s%s тармағының қолдау мерзімі "
"аяқталды, оның орнына %s%s%s орындалу ортасының %s%s%s тармағын қолданыңыз\n"

#: app/flatpak-cli-transaction.c:768
#, c-format
msgid ""
"\n"
"Info: app %s%s%s branch %s%s%s is end-of-life, in favor of %s%s%s branch "
"%s%s%s\n"
msgstr ""
"\n"
"Ақпарат: %s%s%s қолданбасының %s%s%s тармағының қолдау мерзімі аяқталды, "
"оның орнына %s%s%s қолданбасының %s%s%s тармағын қолданыңыз\n"

#. Only runtimes can be pinned
#: app/flatpak-cli-transaction.c:780
#, c-format
msgid ""
"\n"
"Info: (pinned) runtime %s%s%s branch %s%s%s is end-of-life, with reason:\n"
msgstr ""
"\n"
"Ақпарат: (бекітілген) %s%s%s орындалу ортасының %s%s%s тармағының қолдау "
"мерзімі аяқталды, себебі:\n"

#: app/flatpak-cli-transaction.c:786
#, c-format
msgid ""
"\n"
"Info: runtime %s%s%s branch %s%s%s is end-of-life, with reason:\n"
msgstr ""
"\n"
"Ақпарат: %s%s%s орындалу ортасының %s%s%s тармағының қолдау мерзімі "
"аяқталды, себебі:\n"

#: app/flatpak-cli-transaction.c:789
#, c-format
msgid ""
"\n"
"Info: app %s%s%s branch %s%s%s is end-of-life, with reason:\n"
msgstr ""
"\n"
"Ақпарат: %s%s%s қолданбасының %s%s%s тармағының қолдау мерзімі аяқталды, "
"себебі:\n"

#: app/flatpak-cli-transaction.c:963
#, c-format
msgid "Info: applications using this extension:\n"
msgstr "Ақпарат: осы кеңейтуді қолданатын қолданбалар:\n"

#: app/flatpak-cli-transaction.c:965
#, c-format
msgid "Info: applications using this runtime:\n"
msgstr "Ақпарат: осы орындалу ортасын қолданатын қолданбалар:\n"

#: app/flatpak-cli-transaction.c:984
msgid "Replace?"
msgstr "Алмастыру керек пе?"

#: app/flatpak-cli-transaction.c:987 app/flatpak-quiet-transaction.c:247
#, c-format
msgid "Updating to rebased version\n"
msgstr "Базасы ауыстырылған нұсқаға жаңартылуда\n"

#: app/flatpak-cli-transaction.c:1011
#, c-format
msgid "Failed to rebase %s to %s: "
msgstr "%s базасын %s мәніне ауыстыру сәтсіз аяқталды: "

#: app/flatpak-cli-transaction.c:1277
#, c-format
msgid "New %s%s%s permissions:"
msgstr "Жаңа %s%s%s рұқсаттары:"

#: app/flatpak-cli-transaction.c:1279
#, c-format
msgid "%s%s%s permissions:"
msgstr "%s%s%s рұқсаттары:"

#: app/flatpak-cli-transaction.c:1343
msgid "Warning: "
msgstr "Ескерту: "

#. translators: This is short for operation, the title of a one-char column
#: app/flatpak-cli-transaction.c:1442
msgid "Op"
msgstr "Оп"

#. Avoid resizing the download column too much,
#. * by making the title as long as typical content
#.
#: app/flatpak-cli-transaction.c:1458 app/flatpak-cli-transaction.c:1503
msgid "partial"
msgstr "жартылай"

#: app/flatpak-cli-transaction.c:1535
msgid "Proceed with these changes to the user installation?"
msgstr "Пайдаланушы орнатылымына осы өзгерістерді қолдану керек пе?"

#: app/flatpak-cli-transaction.c:1537
msgid "Proceed with these changes to the system installation?"
msgstr "Жүйелік орнатылымға осы өзгерістерді қолдану керек пе?"

#: app/flatpak-cli-transaction.c:1539
#, c-format
msgid "Proceed with these changes to the %s?"
msgstr "%s орнатылымына осы өзгерістерді қолдану керек пе?"

#: app/flatpak-cli-transaction.c:1711
msgid "Changes complete."
msgstr "Өзгерістер аяқталды."

#: app/flatpak-cli-transaction.c:1713
msgid "Uninstall complete."
msgstr "Өшіру аяқталды."

#: app/flatpak-cli-transaction.c:1715
msgid "Installation complete."
msgstr "Орнату аяқталды."

#: app/flatpak-cli-transaction.c:1717
msgid "Updates complete."
msgstr "Жаңартулар аяқталды."

#. For updates/!stop_on_first_error we already printed all errors so we make up
#. a different one.
#: app/flatpak-cli-transaction.c:1750
msgid "There were one or more errors"
msgstr "Бір немесе бірнеше қателер болды"

#. translators: please keep the leading space
#: app/flatpak-main.c:76
msgid " Manage installed applications and runtimes"
msgstr " Орнатылған қолданбалар мен орындалу орталарын басқару"

#: app/flatpak-main.c:77
msgid "Install an application or runtime"
msgstr "Қолданбаны немесе орындалу ортасын орнату"

#: app/flatpak-main.c:78
msgid "Update an installed application or runtime"
msgstr "Орнатылған қолданбаны немесе орындалу ортасын жаңарту"

#: app/flatpak-main.c:81
msgid "Uninstall an installed application or runtime"
msgstr "Орнатылған қолданбаны немесе орындалу ортасын өшіру"

#: app/flatpak-main.c:84
msgid "Mask out updates and automatic installation"
msgstr "Жаңартулар мен автоматты орнатуды маскалау"

#: app/flatpak-main.c:85
msgid "Pin a runtime to prevent automatic removal"
msgstr "Автоматты өшіруді болдырмау үшін орындалу ортасын бекіту"

#: app/flatpak-main.c:86
msgid "List installed apps and/or runtimes"
msgstr "Орнатылған қолданбаларды және/немесе орындалу орталарын тізімдеу"

#: app/flatpak-main.c:87
msgid "Show info for installed app or runtime"
msgstr "Орнатылған қолданба немесе орындалу ортасы туралы ақпаратты көрсету"

#: app/flatpak-main.c:88
msgid "Show history"
msgstr "Тарихты көрсету"

#: app/flatpak-main.c:89
msgid "Configure flatpak"
msgstr "Flatpak баптау"

#: app/flatpak-main.c:90
msgid "Repair flatpak installation"
msgstr "Flatpak орнатылымын жөндеу"

#: app/flatpak-main.c:91
msgid "Put applications or runtimes onto removable media"
msgstr "Қолданбаларды немесе орындалу орталарын алынбалы тасымалдағышқа салу"

#: app/flatpak-main.c:92
msgid "Install flatpaks that are part of the operating system"
msgstr "Операциялық жүйенің бөлігі болып табылатын flatpak-тарды орнату"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:95
msgid ""
"\n"
" Find applications and runtimes"
msgstr ""
"\n"
" Қолданбалар мен орындалу орталарын табу"

#: app/flatpak-main.c:96
msgid "Search for remote apps/runtimes"
msgstr "Қашықтағы қолданбаларды/орындалу орталарын іздеу"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:99
msgid ""
"\n"
" Manage running applications"
msgstr ""
"\n"
" Жұмыс істеп тұрған қолданбаларды басқару"

#: app/flatpak-main.c:100
msgid "Run an application"
msgstr "Қолданбаны орындау"

#: app/flatpak-main.c:101
msgid "Override permissions for an application"
msgstr "Қолданба рұқсаттарын қайта анықтау"

#: app/flatpak-main.c:102
msgid "Specify default version to run"
msgstr "Орындау үшін бастапқы нұсқаны көрсету"

#: app/flatpak-main.c:103
msgid "Enter the namespace of a running application"
msgstr "Жұмыс істеп тұрған қолданбаның атау кеңістігіне кіру"

#: app/flatpak-main.c:104
msgid "Enumerate running applications"
msgstr "Жұмыс істеп тұрған қолданбаларды санап шығу"

#: app/flatpak-main.c:105
msgid "Stop a running application"
msgstr "Жұмыс істеп тұрған қолданбаны тоқтату"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:108
msgid ""
"\n"
" Manage file access"
msgstr ""
"\n"
" Файлға қол жеткізуді басқару"

#: app/flatpak-main.c:109
msgid "List exported files"
msgstr "Экспортталған файлдарды тізімдеу"

#: app/flatpak-main.c:110
msgid "Grant an application access to a specific file"
msgstr "Қолданбаға арнайы файлға қол жеткізу рұқсатын беру"

#: app/flatpak-main.c:111
msgid "Revoke access to a specific file"
msgstr "Арнайы файлға қол жеткізу рұқсатын қайтарып алу"

#: app/flatpak-main.c:112
msgid "Show information about a specific file"
msgstr "Арнайы файл туралы ақпаратты көрсету"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:116
msgid ""
"\n"
" Manage dynamic permissions"
msgstr ""
"\n"
" Динамикалық рұқсаттарды басқару"

#: app/flatpak-main.c:117
msgid "List permissions"
msgstr "Рұқсаттарды тізімдеу"

#: app/flatpak-main.c:118
msgid "Remove item from permission store"
msgstr "Элементті рұқсаттар қоймасынан өшіру"

#: app/flatpak-main.c:120
msgid "Set permissions"
msgstr "Рұқсаттарды орнату"

#: app/flatpak-main.c:121
msgid "Show app permissions"
msgstr "Қолданба рұқсаттарын көрсету"

#: app/flatpak-main.c:122
msgid "Reset app permissions"
msgstr "Қолданба рұқсаттарын тастау"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:125
msgid ""
"\n"
" Manage remote repositories"
msgstr ""
"\n"
" Қашықтағы репозиторийлерді басқару"

#: app/flatpak-main.c:126
msgid "List all configured remotes"
msgstr "Барлық конфигурацияланған қашықтағы репозиторийлерді тізімдеу"

#: app/flatpak-main.c:127
msgid "Add a new remote repository (by URL)"
msgstr "Жаңа қашықтағы репозиторий қосу (URL арқылы)"

#: app/flatpak-main.c:128
msgid "Modify properties of a configured remote"
msgstr "Конфигурацияланған қашықтағы репозиторийдің қасиеттерін өзгерту"

#: app/flatpak-main.c:129
msgid "Delete a configured remote"
msgstr "Конфигурацияланған қашықтағы репозиторийді өшіру"

#: app/flatpak-main.c:131
msgid "List contents of a configured remote"
msgstr "Конфигурацияланған қашықтағы репозиторийдің мазмұнын тізімдеу"

#: app/flatpak-main.c:132
msgid "Show information about a remote app or runtime"
msgstr "Қашықтағы қолданба немесе орындалу ортасы туралы ақпаратты көрсету"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:135
msgid ""
"\n"
" Build applications"
msgstr ""
"\n"
" Қолданбаларды құрастыру"

#: app/flatpak-main.c:136
msgid "Initialize a directory for building"
msgstr "Құрастыру үшін буманы инициализациялау"

#: app/flatpak-main.c:137
msgid "Run a build command inside the build dir"
msgstr "Құрастыру бумасының ішінде құрастыру командасын орындау"

#: app/flatpak-main.c:138
msgid "Finish a build dir for export"
msgstr "Экспорттау үшін құрастыру бумасын аяқтау"

#: app/flatpak-main.c:139
msgid "Export a build dir to a repository"
msgstr "Құрастыру бумасын репозиторийге экспорттау"

#: app/flatpak-main.c:140
msgid "Create a bundle file from a ref in a local repository"
msgstr "Жергілікті репозиторийдегі сілтемеден десте файлын жасау"

#: app/flatpak-main.c:141
msgid "Import a bundle file"
msgstr "Десте файлын импорттау"

#: app/flatpak-main.c:142
msgid "Sign an application or runtime"
msgstr "Қолданбаға немесе орындалу ортасына қол қою"

#: app/flatpak-main.c:143
msgid "Update the summary file in a repository"
msgstr "Репозиторийдегі жиынтық файлын жаңарту"

#: app/flatpak-main.c:144
msgid "Create new commit based on existing ref"
msgstr "Бар сілтеме негізінде жаңа коммит жасау"

#: app/flatpak-main.c:145
msgid "Show information about a repo"
msgstr "Репо туралы ақпаратты көрсету"

#: app/flatpak-main.c:162
msgid "Show debug information, -vv for more detail"
msgstr "Жөндеу ақпаратын көрсету, толығырақ мәлімет үшін -vv қолданыңыз"

#: app/flatpak-main.c:163
msgid "Show OSTree debug information"
msgstr "OSTree жөндеу ақпаратын көрсету"

#: app/flatpak-main.c:169
msgid "Print version information and exit"
msgstr "Нұсқа ақпаратын шығару және шығу"

#: app/flatpak-main.c:170
msgid "Print default arch and exit"
msgstr "Бастапқы архитектураны шығару және шығу"

#: app/flatpak-main.c:171
msgid "Print supported arches and exit"
msgstr "Қолдау көрсетілетін архитектураларды шығару және шығу"

#: app/flatpak-main.c:172
msgid "Print active gl drivers and exit"
msgstr "Белсенді gl драйверлерін шығару және шығу"

#: app/flatpak-main.c:173
msgid "Print paths for system installations and exit"
msgstr "Жүйелік орнатылымдардың жолдарын шығару және шығу"

#: app/flatpak-main.c:174
msgid "Print the updated environment needed to run flatpaks"
msgstr "Flatpak-тарды орындау үшін қажетті жаңартылған ортаны шығару"

#: app/flatpak-main.c:175
msgid "Only include the system installation with --print-updated-env"
msgstr "--print-updated-env опциясымен тек жүйелік орнатылымды қосу"

#: app/flatpak-main.c:180
msgid "Work on the user installation"
msgstr "Пайдаланушы орнатылымымен жұмыс істеу"

#: app/flatpak-main.c:181
msgid "Work on the system-wide installation (default)"
msgstr "Жүйелік орнатылыммен жұмыс істеу (бастапқы)"

#: app/flatpak-main.c:182
msgid "Work on a non-default system-wide installation"
msgstr "Бастапқы емес жүйелік орнатылыммен жұмыс істеу"

#: app/flatpak-main.c:212
msgid "Builtin Commands:"
msgstr "Кірістірілген командалар:"

#: app/flatpak-main.c:298
#, c-format
msgid ""
"Note that the directories %s are not in the search path set by the "
"XDG_DATA_DIRS environment variable, so applications installed by Flatpak may "
"not appear on your desktop until the session is restarted."
msgstr ""
"%s бумалары XDG_DATA_DIRS орта айнымалысы арқылы орнатылған іздеу жолында "
"жоқ екенін ескеріңіз, сондықтан Flatpak арқылы орнатылған қолданбалар сессия "
"қайта іске қосылғанша жұмыс үстеліңізде көрінбеуі мүмкін."

#: app/flatpak-main.c:312
#, c-format
msgid ""
"Note that the directory %s is not in the search path set by the "
"XDG_DATA_DIRS environment variable, so applications installed by Flatpak may "
"not appear on your desktop until the session is restarted."
msgstr ""
"%s бумасы XDG_DATA_DIRS орта айнымалысы арқылы орнатылған іздеу жолында жоқ "
"екенін ескеріңіз, сондықтан Flatpak арқылы орнатылған қолданбалар сессия "
"қайта іске қосылғанша жұмыс үстеліңізде көрінбеуі мүмкін."

#: app/flatpak-main.c:381
msgid ""
"Refusing to operate under sudo with --user. Omit sudo to operate on the user "
"installation, or use a root shell to operate on the root user's installation."
msgstr ""
"--user опциясымен sudo астында жұмыс істеуден бас тартылды. Пайдаланушы "
"орнатылымында жұмыс істеу үшін sudo-ны алып тастаңыз немесе әкімші "
"пайдаланушының орнатылымында жұмыс істеу үшін әкімші қоршамын қолданыңыз."

#: app/flatpak-main.c:453
msgid ""
"Multiple installations specified for a command that works on one installation"
msgstr ""
"Бір орнатылымда жұмыс істейтін команда үшін бірнеше орнатылым көрсетілді"

#: app/flatpak-main.c:504 app/flatpak-main.c:697
#, c-format
msgid "See '%s --help'"
msgstr "'%s --help' қараңыз"

#: app/flatpak-main.c:706
#, c-format
msgid "'%s' is not a flatpak command. Did you mean '%s%s'?"
msgstr "'%s' flatpak командасы емес. Сіздің ойлағаныңыз '%s%s' бе?"

#: app/flatpak-main.c:709
#, c-format
msgid "'%s' is not a flatpak command"
msgstr "'%s' flatpak командасы емес"

#: app/flatpak-main.c:824
msgid "No command specified"
msgstr "Команда көрсетілмеген"

#: app/flatpak-main.c:980
msgid "error:"
msgstr "қате:"

#: app/flatpak-quiet-transaction.c:77
#, c-format
msgid "Installing %s\n"
msgstr "%s орнатылуда\n"

#: app/flatpak-quiet-transaction.c:81
#, c-format
msgid "Updating %s\n"
msgstr "%s жаңартылуда\n"

#: app/flatpak-quiet-transaction.c:85
#, c-format
msgid "Uninstalling %s\n"
msgstr "%s өшірілуде\n"

#: app/flatpak-quiet-transaction.c:107
#, c-format
msgid "Warning: Failed to install %s: %s\n"
msgstr "Ескерту: %s орнату сәтсіз аяқталды: %s\n"

#: app/flatpak-quiet-transaction.c:110
#, c-format
msgid "Error: Failed to install %s: %s\n"
msgstr "Қате: %s орнату сәтсіз аяқталды: %s\n"

#: app/flatpak-quiet-transaction.c:116
#, c-format
msgid "Warning: Failed to update %s: %s\n"
msgstr "Ескерту: %s жаңарту сәтсіз аяқталды: %s\n"

#: app/flatpak-quiet-transaction.c:119
#, c-format
msgid "Error: Failed to update %s: %s\n"
msgstr "Қате: %s жаңарту сәтсіз аяқталды: %s\n"

#: app/flatpak-quiet-transaction.c:125
#, c-format
msgid "Warning: Failed to install bundle %s: %s\n"
msgstr "Ескерту: %s дестесін орнату сәтсіз аяқталды: %s\n"

#: app/flatpak-quiet-transaction.c:128
#, c-format
msgid "Error: Failed to install bundle %s: %s\n"
msgstr "Қате: %s дестесін орнату сәтсіз аяқталды: %s\n"

#: app/flatpak-quiet-transaction.c:134
#, c-format
msgid "Warning: Failed to uninstall %s: %s\n"
msgstr "Ескерту: %s өшіру сәтсіз аяқталды: %s\n"

#: app/flatpak-quiet-transaction.c:137
#, c-format
msgid "Error: Failed to uninstall %s: %s\n"
msgstr "Қате: %s өшіру сәтсіз аяқталды: %s\n"

#: app/flatpak-quiet-transaction.c:166 common/flatpak-dir.c:11475
#, c-format
msgid "%s already installed"
msgstr "%s қазірдің өзінде орнатылған"

#: app/flatpak-quiet-transaction.c:168 common/flatpak-dir.c:3622
#: common/flatpak-dir.c:4321 common/flatpak-dir.c:16968
#: common/flatpak-dir.c:17258 common/flatpak-dir-utils.c:166
#: common/flatpak-dir-utils.c:259 common/flatpak-transaction.c:2736
#: common/flatpak-transaction.c:2791
#, c-format
msgid "%s not installed"
msgstr "%s орнатылмаған"

#: app/flatpak-quiet-transaction.c:170
#, c-format
msgid "%s needs a later flatpak version"
msgstr "%s үшін кейінгі flatpak нұсқасы қажет"

#: app/flatpak-quiet-transaction.c:172
msgid "Not enough disk space to complete this operation"
msgstr "Бұл операцияны аяқтау үшін дискіде орын жеткіліксіз"

#: app/flatpak-quiet-transaction.c:239
#, c-format
msgid "Info: %s is end-of-life, in favor of %s\n"
msgstr "Ақпарат: %s қолдау мерзімі аяқталған, оның орнына %s қолданыңыз\n"

#: app/flatpak-quiet-transaction.c:241
#, c-format
msgid "Info: %s is end-of-life, with reason: %s\n"
msgstr "Ақпарат: %s қолдау мерзімі аяқталған, себебі: %s\n"

#: app/flatpak-quiet-transaction.c:251
#, c-format
msgid "Failed to rebase %s to %s: %s\n"
msgstr "%s базасын %s мәніне ауыстыру сәтсіз аяқталды: %s\n"

#: common/flatpak-auth.c:58
#, c-format
msgid "No authenticator configured for remote `%s`"
msgstr ""
"‘%s’ қашықтағы репозиторийі үшін ешқандай аутентификатор конфигурацияланбаған"

#: common/flatpak-context.c:637 common/flatpak-context.c:649
#, c-format
msgid "Invalid permission syntax: %s"
msgstr "Рұқсат синтаксисі жарамсыз: %s"

#: common/flatpak-context.c:1207
#, c-format
msgid "Unknown share type %s, valid types are: %s"
msgstr "Бөлісу түрі %s белгісіз, жарамды түрлері: %s"

#: common/flatpak-context.c:1228
#, c-format
msgid "Unknown policy type %s, valid types are: %s"
msgstr "Саясат түрі %s белгісіз, жарамды түрлері: %s"

#: common/flatpak-context.c:1266
#, c-format
msgid "Invalid dbus name %s"
msgstr "dbus атауы жарамсыз: %s"

#: common/flatpak-context.c:1279
#, c-format
msgid "Unknown socket type %s, valid types are: %s"
msgstr "Сокет түрі %s белгісіз, жарамды түрлері: %s"

#: common/flatpak-context.c:1294
#, c-format
msgid "Unknown device type %s, valid types are: %s"
msgstr "Құрылғы түрі %s белгісіз, жарамды түрлері: %s"

#: common/flatpak-context.c:1308
#, c-format
msgid "Unknown feature type %s, valid types are: %s"
msgstr "Мүмкіндік түрі %s белгісіз, жарамды түрлері: %s"

#: common/flatpak-context.c:1840
#, c-format
msgid "Filesystem location \"%s\" contains \"..\""
msgstr "Файлдық жүйе орны \"%s\" құрамында \"..\" бар"

#: common/flatpak-context.c:1882
#, c-format
msgid ""
"--filesystem=/ is not available, use --filesystem=host for a similar result"
msgstr ""
"--filesystem=/ қолжетімді емес, ұқсас нәтиже үшін --filesystem=host "
"қолданыңыз"

#: common/flatpak-context.c:1916
#, c-format
msgid ""
"Unknown filesystem location %s, valid locations are: host, host-os, host-"
"etc, host-root, home, xdg-*[/…], ~/dir, /dir"
msgstr ""
"Файлдық жүйе орны %s белгісіз, жарамды орындар: host, host-os, host-etc, "
"host-root, home, xdg-*[/…], ~/бума, /бума"

#: common/flatpak-context.c:2015
#, c-format
msgid "Invalid syntax for %s: %s"
msgstr "%s үшін синтаксис жарамсыз: %s"

#: common/flatpak-context.c:2142
#, c-format
msgid "fallback-x11 can not be conditional"
msgstr "fallback-x11 шартты бола алмайды"

#: common/flatpak-context.c:2318
#, c-format
msgid "Invalid env format %s"
msgstr "Орта айнымалысының пішімі жарамсыз: %s"

#: common/flatpak-context.c:2399
#, c-format
msgid "Environment variable name must not contain '=': %s"
msgstr "Орта айнымалысының атауында '=' болмауы тиіс: %s"

#: common/flatpak-context.c:2527 common/flatpak-context.c:2535
#, c-format
msgid "--add-policy arguments must be in the form SUBSYSTEM.KEY=VALUE"
msgstr "--add-policy аргументтері ІШКІ_ЖҮЙЕ.КІЛТ=МӘНІ түрінде болуы тиіс"

#: common/flatpak-context.c:2542
#, c-format
msgid "--add-policy values can't start with \"!\""
msgstr "--add-policy мәндері \"!\" таңбасынан басталмауы тиіс"

#: common/flatpak-context.c:2567 common/flatpak-context.c:2575
#, c-format
msgid "--remove-policy arguments must be in the form SUBSYSTEM.KEY=VALUE"
msgstr "--remove-policy аргументтері ІШКІ_ЖҮЙЕ.КІЛТ=МӘНІ түрінде болуы тиіс"

#: common/flatpak-context.c:2582
#, c-format
msgid "--remove-policy values can't start with \"!\""
msgstr "--remove-policy мәндері \"!\" таңбасынан басталмауы тиіс"

#: common/flatpak-context.c:2657
msgid "Share with host"
msgstr "Хостпен бөлісу"

#: common/flatpak-context.c:2657 common/flatpak-context.c:2658
msgid "SHARE"
msgstr "БӨЛІСУ"

#: common/flatpak-context.c:2658
msgid "Unshare with host"
msgstr "Хостпен бөлісуді тоқтату"

#: common/flatpak-context.c:2659
msgid "Require conditions to be met for a subsystem to get shared"
msgstr "Ішкі жүйені бөлісу үшін шарттардың орындалуын талап ету"

#: common/flatpak-context.c:2659
msgid "SHARE:CONDITION"
msgstr "БӨЛІСУ:ШАРТ"

#: common/flatpak-context.c:2660
msgid "Expose socket to app"
msgstr "Сокетті қолданбаға ашу"

#: common/flatpak-context.c:2660 common/flatpak-context.c:2661
msgid "SOCKET"
msgstr "СОКЕТ"

#: common/flatpak-context.c:2661
msgid "Don't expose socket to app"
msgstr "Сокетті қолданбаға ашпау"

#: common/flatpak-context.c:2662
msgid "Require conditions to be met for a socket to get exposed"
msgstr "Сокетті ашу үшін шарттардың орындалуын талап ету"

#: common/flatpak-context.c:2662
msgid "SOCKET:CONDITION"
msgstr "СОКЕТ:ШАРТ"

#: common/flatpak-context.c:2663
msgid "Expose device to app"
msgstr "Құрылғыны қолданбаға ашу"

#: common/flatpak-context.c:2663 common/flatpak-context.c:2664
msgid "DEVICE"
msgstr "ҚҰРЫЛҒЫ"

#: common/flatpak-context.c:2664
msgid "Don't expose device to app"
msgstr "Құрылғыны қолданбаға ашпау"

#: common/flatpak-context.c:2665
msgid "Require conditions to be met for a device to get exposed"
msgstr "Құрылғыны ашу үшін шарттардың орындалуын талап ету"

#: common/flatpak-context.c:2665
msgid "DEVICE:CONDITION"
msgstr "ҚҰРЫЛҒЫ:ШАРТ"

#: common/flatpak-context.c:2666
msgid "Allow feature"
msgstr "Мүмкіндікке рұқсат беру"

#: common/flatpak-context.c:2666 common/flatpak-context.c:2667
msgid "FEATURE"
msgstr "МҮМКІНДІК"

#: common/flatpak-context.c:2667
msgid "Don't allow feature"
msgstr "Мүмкіндікке рұқсат бермеу"

#: common/flatpak-context.c:2668
msgid "Require conditions to be met for a feature to get allowed"
msgstr "Мүмкіндікке рұқсат беру үшін шарттардың орындалуын талап ету"

#: common/flatpak-context.c:2668
msgid "FEATURE:CONDITION"
msgstr "МҮМКІНДІК:ШАРТ"

#: common/flatpak-context.c:2669
msgid "Expose filesystem to app (:ro for read-only)"
msgstr "Файлдық жүйені қолданбаға ашу (тек оқу үшін :ro)"

#: common/flatpak-context.c:2669
msgid "FILESYSTEM[:ro]"
msgstr "ФАЙЛДЫҚ_ЖҮЙЕ[:ro]"

#: common/flatpak-context.c:2670
msgid "Don't expose filesystem to app"
msgstr "Файлдық жүйені қолданбаға ашпау"

#: common/flatpak-context.c:2670
msgid "FILESYSTEM"
msgstr "ФАЙЛДЫҚ_ЖҮЙЕ"

#: common/flatpak-context.c:2671
msgid "Set environment variable"
msgstr "Орта айнымалысын орнату"

#: common/flatpak-context.c:2671
msgid "VAR=VALUE"
msgstr "АЙНЫМАЛЫ=МӘН"

#: common/flatpak-context.c:2672
msgid "Read environment variables in env -0 format from FD"
msgstr "Орта айнымалыларын FD-дан env -0 пішімінде оқу"

#: common/flatpak-context.c:2673
msgid "Remove variable from environment"
msgstr "Айнымалыны ортадан өшіру"

#: common/flatpak-context.c:2673
msgid "VAR"
msgstr "АЙНЫМАЛЫ"

#: common/flatpak-context.c:2674
msgid "Allow app to own name on the session bus"
msgstr "Қолданбаға сессия шинасында атау иеленуге рұқсат беру"

#: common/flatpak-context.c:2674 common/flatpak-context.c:2675
#: common/flatpak-context.c:2676 common/flatpak-context.c:2677
#: common/flatpak-context.c:2678 common/flatpak-context.c:2679
#: common/flatpak-context.c:2680
msgid "DBUS_NAME"
msgstr "DBUS_АТАУЫ"

#: common/flatpak-context.c:2675
msgid "Allow app to talk to name on the session bus"
msgstr "Қолданбаға сессия шинасындағы атаумен сөйлесуге рұқсат беру"

#: common/flatpak-context.c:2676
msgid "Don't allow app to talk to name on the session bus"
msgstr "Қолданбаға сессия шинасындағы атаумен сөйлесуге рұқсат бермеу"

#: common/flatpak-context.c:2677
msgid "Allow app to own name on the system bus"
msgstr "Қолданбаға жүйелік шинада атау иеленуге рұқсат беру"

#: common/flatpak-context.c:2678
msgid "Allow app to talk to name on the system bus"
msgstr "Қолданбаға жүйелік шинадағы атаумен сөйлесуге рұқсат беру"

#: common/flatpak-context.c:2679
msgid "Don't allow app to talk to name on the system bus"
msgstr "Қолданбаға жүйелік шинадағы атаумен сөйлесуге рұқсат бермеу"

#: common/flatpak-context.c:2680
msgid "Allow app to own name on the a11y bus"
msgstr "Қолданбаға a11y шинасында атау иеленуге рұқсат беру"

#: common/flatpak-context.c:2681
msgid "Add generic policy option"
msgstr "Жалпы саясат опциясын қосу"

#: common/flatpak-context.c:2681 common/flatpak-context.c:2682
msgid "SUBSYSTEM.KEY=VALUE"
msgstr "ІШКІ_ЖҮЙЕ.КІЛТ=МӘНІ"

#: common/flatpak-context.c:2682
msgid "Remove generic policy option"
msgstr "Жалпы саясат опциясын өшіру"

#: common/flatpak-context.c:2683
msgid "Add USB device to enumerables"
msgstr "USB құрылғысын санаулыларға қосу"

#: common/flatpak-context.c:2683 common/flatpak-context.c:2684
msgid "VENDOR_ID:PRODUCT_ID"
msgstr "ӨНДІРУШІ_ID:ӨНІМ_ID"

#: common/flatpak-context.c:2684
msgid "Add USB device to hidden list"
msgstr "USB құрылғысын жасырын тізімге қосу"

#: common/flatpak-context.c:2685
msgid "A list of USB devices that are enumerable"
msgstr "Саналатын USB құрылғыларының тізімі"

#: common/flatpak-context.c:2685
msgid "LIST"
msgstr "ТІЗІМ"

#: common/flatpak-context.c:2686
msgid "File containing a list of USB devices to make enumerable"
msgstr "Саналатын USB құрылғыларының тізімі бар файл"

#: common/flatpak-context.c:2686 common/flatpak-context.c:2687
msgid "FILENAME"
msgstr "ФАЙЛ_АТАУЫ"

#: common/flatpak-context.c:2687
msgid "Persist home directory subpath"
msgstr "Үй бумасының ішкі жолын тұрақты ету"

#. This is not needed/used anymore, so hidden, but we accept it for backwards compat
#: common/flatpak-context.c:2689
msgid "Don't require a running session (no cgroups creation)"
msgstr "Жұмыс істеп тұрған сессияны талап етпеу (cgroups жасалмауы)"

#: common/flatpak-context.c:3718
#, c-format
msgid "Not replacing \"%s\" with tmpfs: %s"
msgstr "\"%s\" мәні tmpfs-пен алмастырылмайды: %s"

#: common/flatpak-context.c:3726
#, c-format
msgid "Not sharing \"%s\" with sandbox: %s"
msgstr "\"%s\" құмсалғышпен бөлісілмейді: %s"

#. Even if the error is one that we would normally silence, like
#. * the path not existing, it seems reasonable to make more of a fuss
#. * about the home directory not existing or otherwise being unusable,
#. * so this is intentionally not using cannot_export()
#: common/flatpak-context.c:3828
#, c-format
msgid "Not allowing home directory access: %s"
msgstr "Үй бумасына қол жеткізуге рұқсат берілмейді: %s"

#: common/flatpak-context.c:4062
#, c-format
msgid "Unable to provide a temporary home directory in the sandbox: %s"
msgstr "Құмсалғыш ішінде уақытша үй бумасын қамтамасыз ету мүмкін емес: %s"

#: common/flatpak-dir.c:442
#, c-format
msgid "Configured collection ID ‘%s’ not in summary file"
msgstr "Конфигурацияланған ‘%s’ коллекция ID-і жиынтық файлында жоқ"

#: common/flatpak-dir.c:587
#, c-format
msgid "Unable to load summary from remote %s: %s"
msgstr "%s қашықтағы репозиторийден жиынтықты жүктеу мүмкін емес: %s"

#: common/flatpak-dir.c:764 common/flatpak-dir.c:800 common/flatpak-dir.c:906
#, c-format
msgid "No such ref '%s' in remote %s"
msgstr "%2$s қашықтағы репозиторийінде '%1$s' сілтемесі жоқ"

#: common/flatpak-dir.c:891 common/flatpak-dir.c:1051 common/flatpak-dir.c:1080
#: common/flatpak-dir.c:1092
#, c-format
msgid "No entry for %s in remote %s summary flatpak cache"
msgstr "%2$s қашықтағы жиынтығының flatpak кэшінде %1$s үшін жазба жоқ"

#: common/flatpak-dir.c:1069
#, c-format
msgid "No summary or Flatpak cache available for remote %s"
msgstr ""
"%s қашықтағы репозиторийі үшін ешқандай жиынтық немесе Flatpak кэші "
"қолжетімді емес"

#: common/flatpak-dir.c:1097
#, c-format
msgid "Missing xa.data in summary for remote %s"
msgstr "%s қашықтағы репозиторийдің жиынтығында xa.data жоқ"

#: common/flatpak-dir.c:1103 common/flatpak-dir.c:1546
#, c-format
msgid "Unsupported summary version %d for remote %s"
msgstr ""
"%2$s қашықтағы репозиторийі үшін қолдау көрсетілмейтін жиынтық нұсқасы %1$d"

#: common/flatpak-dir.c:1200
msgid "Remote OCI index has no registry uri"
msgstr "Қашықтағы OCI индексінде тіркеу uri-і жоқ"

#: common/flatpak-dir.c:1261
#, c-format
msgid "Couldn't find ref %s in remote %s"
msgstr "%2$s қашықтағы репозиторийден %1$s сілтемесі табылмады"

#: common/flatpak-dir.c:1288 common/flatpak-dir.c:1381
#, fuzzy, c-format
msgid "Commit has no requested ref ‘%s’ in ref binding metadata (found: ‘%s’)"
msgstr ""
"Коммиттің сілтемелерді байланыстыру метадеректерінде сұралған ‘%s’ сілтемесі "
"жоқ"

#: common/flatpak-dir.c:1413
#, c-format
msgid "Configured collection ID ‘%s’ not in binding metadata"
msgstr ""
"Байланыстыру метадеректерінде конфигурацияланған ‘%s’ коллекция ID-і жоқ"

#: common/flatpak-dir.c:1449 common/flatpak-dir.c:5645
#, c-format
msgid "Couldn't find latest checksum for ref %s in remote %s"
msgstr ""
"%2$s қашықтағы репозиторийден %1$s сілтемесі үшін соңғы бақылау сомасы "
"табылмады"

#: common/flatpak-dir.c:1516 common/flatpak-dir.c:1552
#, c-format
msgid "No entry for %s in remote %s summary flatpak sparse cache"
msgstr "%2$s қашықтағы жиынтығының flatpak сирек кэшінде %1$s үшін жазба жоқ"

#: common/flatpak-dir.c:2540
#, c-format
msgid "Commit metadata for %s not matching expected metadata"
msgstr "%s үшін коммит метадеректері күтілген метадеректерге сәйкес келмейді"

#: common/flatpak-dir.c:2823
msgid "Unable to connect to system bus"
msgstr "Жүйелік шинаға қосылу мүмкін емес"

#: common/flatpak-dir.c:3419
msgid "User installation"
msgstr "Пайдаланушы орнатылымы"

#: common/flatpak-dir.c:3426
#, c-format
msgid "System (%s) installation"
msgstr "Жүйелік (%s) орнатылым"

#: common/flatpak-dir.c:3472
#, c-format
msgid "No overrides found for %s"
msgstr "%s үшін қайта анықтаулар табылмады"

#: common/flatpak-dir.c:3625
#, c-format
msgid "%s (commit %s) not installed"
msgstr "%s (%s коммиті) орнатылмаған"

#: common/flatpak-dir.c:4650
#, c-format
msgid "Error parsing system flatpakrepo file for %s: %s"
msgstr "%s үшін жүйелік flatpakrepo файлын өңдеу қатесі: %s"

#: common/flatpak-dir.c:4735
#, c-format
msgid "While opening repository %s: "
msgstr "%s репозиторийін ашу кезінде: "

#: common/flatpak-dir.c:5004
#, c-format
msgid "The config key %s is not set"
msgstr "%s конфигурация кілті орнатылмаған"

#: common/flatpak-dir.c:5140
#, c-format
msgid "No current %s pattern matching %s"
msgstr "%2$s-ге сәйкес келетін ағымдағы %1$s шаблоны жоқ"

#: common/flatpak-dir.c:5422
msgid "No appstream commit to deploy"
msgstr "Орналастыратын appstream коммиті жоқ"

#: common/flatpak-dir.c:5941 common/flatpak-dir.c:7266
#: common/flatpak-dir.c:10881 common/flatpak-dir.c:11618
msgid "Can't pull from untrusted non-gpg verified remote"
msgstr ""
"Сенімсіз, gpg арқылы тексерілмеген қашықтағы репозиторийден тарту мүмкін емес"

#: common/flatpak-dir.c:6376 common/flatpak-dir.c:6591
msgid "Extra data not supported for non-gpg-verified local system installs"
msgstr ""
"gpg-тексерілмеген жергілікті жүйелік орнатылымдар үшін қосымша деректерге "
"қолдау көрсетілмейді"

#: common/flatpak-dir.c:6415 common/flatpak-dir.c:6782
#, c-format
msgid "Invalid checksum for extra data uri %s"
msgstr "%s қосымша деректер uri-і үшін бақылау сомасы жарамсыз"

#: common/flatpak-dir.c:6424
#, c-format
msgid "Empty name for extra data uri %s"
msgstr "%s қосымша деректер uri-і үшін атау бос"

#: common/flatpak-dir.c:6432
#, c-format
msgid "Unsupported extra data uri %s"
msgstr "Қолдау көрсетілмейтін %s қосымша деректер uri-і"

#: common/flatpak-dir.c:6461
#, c-format
msgid "Failed to load local extra-data %s: %s"
msgstr "Жергілікті %s қосымша деректерін жүктеу мүмкін емес: %s"

#: common/flatpak-dir.c:6469
#, c-format
msgid "Wrong size for extra-data %s"
msgstr "%s қосымша деректерінің өлшемі қате"

#: common/flatpak-dir.c:6488
#, c-format
msgid "While downloading %s: "
msgstr "%s жүктеп алу кезінде: "

#: common/flatpak-dir.c:6498
#, c-format
msgid "Wrong size for extra data %s"
msgstr "%s қосымша деректері үшін қате өлшем"

#: common/flatpak-dir.c:6507
#, c-format
msgid "Invalid checksum for extra data %s"
msgstr "%s қосымша деректері үшін бақылау сомасы жарамсыз"

#: common/flatpak-dir.c:7096 common/flatpak-dir.c:7349
#, c-format
msgid "While pulling %s from remote %s: "
msgstr "%2$s қашықтағы репозиторийден %1$s тарту кезінде: "

#: common/flatpak-dir.c:7290 common/flatpak-repo-utils.c:3886
msgid "GPG signatures found, but none are in trusted keyring"
msgstr ""
"GPG қолтаңбалары табылды, бірақ олардың ешқайсысы сенімді кілттер жинағында "
"жоқ"

#: common/flatpak-dir.c:7307
#, c-format
msgid "Commit for ‘%s’ has no ref binding"
msgstr "‘%s’ коммитінде сілтеме байланысы жоқ"

#: common/flatpak-dir.c:7312
#, c-format
msgid "Commit for ‘%s’ is not in expected bound refs: %s"
msgstr "‘%s’ коммиті күтілген байланысты сілтемелерде жоқ: %s"

#: common/flatpak-dir.c:7488
msgid "Only applications can be made current"
msgstr "Тек қолданбаларды ағымдағы етуге болады"

#: common/flatpak-dir.c:8192
msgid "Not enough memory"
msgstr "Жад жеткіліксіз"

#: common/flatpak-dir.c:8211
msgid "Failed to read from exported file"
msgstr "Экспортталған файлдан оқу сәтсіз аяқталды"

#: common/flatpak-dir.c:8401
msgid "Error reading mimetype xml file"
msgstr "mimetype xml файлын оқу қатесі"

#: common/flatpak-dir.c:8406
msgid "Invalid mimetype xml file"
msgstr "mimetype xml файлы жарамсыз"

#: common/flatpak-dir.c:8492
#, c-format
msgid "D-Bus service file '%s' has wrong name"
msgstr "'%s' D-Bus қызмет файлының атауы қате"

#: common/flatpak-dir.c:8647
#, c-format
msgid "Invalid Exec argument %s"
msgstr "Exec аргументі жарамсыз: %s"

#: common/flatpak-dir.c:9115
msgid "While getting detached metadata: "
msgstr "Бөлінген метадеректерді алу кезінде: "

#: common/flatpak-dir.c:9120 common/flatpak-dir.c:9125
#: common/flatpak-dir.c:9129
msgid "Extra data missing in detached metadata"
msgstr "Бөлінген метадеректерде қосымша деректер жоқ"

#: common/flatpak-dir.c:9133
msgid "While creating extradir: "
msgstr "extradir жасау кезінде: "

#: common/flatpak-dir.c:9154 common/flatpak-dir.c:9187
msgid "Invalid checksum for extra data"
msgstr "Қосымша деректер үшін бақылау сомасы жарамсыз"

#: common/flatpak-dir.c:9183
msgid "Wrong size for extra data"
msgstr "Қосымша деректер өлшемі қате"

#: common/flatpak-dir.c:9196
#, c-format
msgid "While writing extra data file '%s': "
msgstr "'%s' қосымша деректер файлын жазу кезінде: "

#: common/flatpak-dir.c:9204
#, c-format
msgid "Extra data %s missing in detached metadata"
msgstr "Бөлінген метадеректерде %s қосымша деректері жоқ"

#: common/flatpak-dir.c:9278
#, c-format
msgid "Unable to get runtime key from metadata"
msgstr "Метадеректерден орындалу ортасы кілтін алу мүмкін емес"

#: common/flatpak-dir.c:9402
#, c-format
msgid "apply_extra script failed, exit status %d"
msgstr "apply_extra скрипті сәтсіз аяқталды, шығу күйі %d"

#. Translators: The placeholder is for an app ref.
#: common/flatpak-dir.c:9591
#, c-format
msgid "Installing %s is not allowed by the policy set by your administrator"
msgstr "%s орнатуға әкімші орнатқан саясатпен рұқсат берілмеген"

#: common/flatpak-dir.c:9690
#, c-format
msgid "While trying to resolve ref %s: "
msgstr "%s сілтемесін шешу кезінде: "

#: common/flatpak-dir.c:9702
#, c-format
msgid "%s is not available"
msgstr "%s қолжетімді емес"

#: common/flatpak-dir.c:9714 common/flatpak-dir.c:11495
#, c-format
msgid "%s commit %s already installed"
msgstr "%s %s коммиті қазірдің өзінде орнатылған"

#: common/flatpak-dir.c:9721
msgid "Can't create deploy directory"
msgstr "Орналастыру бумасын жасау мүмкін емес"

#: common/flatpak-dir.c:9729
#, c-format
msgid "Failed to read commit %s: "
msgstr "%s коммитін оқу сәтсіз аяқталды: "

#: common/flatpak-dir.c:9750
#, c-format
msgid "While trying to checkout %s into %s: "
msgstr "%s-ді %s ішіне тексеріп шығу (checkout) кезінде: "

#: common/flatpak-dir.c:9769
msgid "While trying to checkout metadata subpath: "
msgstr "Метадеректердің ішкі жолын тексеріп шығу (checkout) кезінде: "

#: common/flatpak-dir.c:9801
#, c-format
msgid "While trying to checkout subpath ‘%s’: "
msgstr "‘%s’ ішкі жолын тексеріп шығу (checkout) кезінде: "

#: common/flatpak-dir.c:9811
msgid "While trying to remove existing extra dir: "
msgstr "Бар қосымша буманы өшіру кезінде: "

#: common/flatpak-dir.c:9822
msgid "While trying to apply extra data: "
msgstr "Қосымша деректерді қолдану кезінде: "

#: common/flatpak-dir.c:9849
#, c-format
msgid "Invalid commit ref %s: "
msgstr "%s коммит сілтемесі жарамсыз: "

#: common/flatpak-dir.c:9857 common/flatpak-dir.c:9869
#, c-format
msgid "Deployed ref %s does not match commit (%s)"
msgstr "Орналастырылған %s сілтемесі коммитке (%s) сәйкес келмейді"

#: common/flatpak-dir.c:9863
#, c-format
msgid "Deployed ref %s branch does not match commit (%s)"
msgstr "Орналастырылған %s сілтеме тармағы коммитке (%s) сәйкес келмейді"

#: common/flatpak-dir.c:10125 common/flatpak-installation.c:1911
#, c-format
msgid "%s branch %s already installed"
msgstr "%s %s тармағы қазірдің өзінде орнатылған"

#: common/flatpak-dir.c:10985
#, c-format
msgid "Could not unmount revokefs-fuse filesystem at %s: "
msgstr "%s орнындағы revokefs-fuse файлдық жүйесін ажырату мүмкін болмады: "

#: common/flatpak-dir.c:11289
#, c-format
msgid "This version of %s is already installed"
msgstr "%s осы нұсқасы қазірдің өзінде орнатылған"

#: common/flatpak-dir.c:11302
#, c-format
msgid "Can't change remote during bundle install"
msgstr "Дестені орнату кезінде қашықтағы репозиторийді өзгерту мүмкін емес"

#: common/flatpak-dir.c:11571
msgid "Can't update to a specific commit without root permissions"
msgstr "root рұқсатынсыз арнайы коммитке жаңарту мүмкін емес"

#: common/flatpak-dir.c:11852
#, c-format
msgid "Can't remove %s, it is needed for: %s"
msgstr "%s өшіру мүмкін емес, ол мынау үшін қажет: %s"

#: common/flatpak-dir.c:11912 common/flatpak-installation.c:2067
#, c-format
msgid "%s branch %s is not installed"
msgstr "%s %s тармағы орнатылмаған"

#: common/flatpak-dir.c:12165
#, c-format
msgid "%s commit %s not installed"
msgstr "%s %s коммиті орнатылмаған"

#: common/flatpak-dir.c:12501
#, c-format
msgid "Pruning repo failed: %s"
msgstr "Репозиторийді тазалау сәтсіз аяқталды: %s"

#: common/flatpak-dir.c:12669 common/flatpak-dir.c:12675
#, c-format
msgid "Failed to load filter '%s'"
msgstr "'%s' сүзгісін жүктеу сәтсіз аяқталды"

#: common/flatpak-dir.c:12681
#, c-format
msgid "Failed to parse filter '%s'"
msgstr "'%s' сүзгісін өңдеу сәтсіз аяқталды"

#: common/flatpak-dir.c:12963
msgid "Failed to write summary cache: "
msgstr "Жиынтық кэшін жазу сәтсіз аяқталды: "

#: common/flatpak-dir.c:12982
#, c-format
msgid "No oci summary cached for remote '%s'"
msgstr "'%s' қашықтағы репозиторийі үшін ешқандай oci жиынтығы кэштелмеген"

#: common/flatpak-dir.c:13207
#, c-format
msgid "No cached summary for remote '%s'"
msgstr "'%s' қашықтағы репозиторийі үшін ешқандай кэштелген жиынтық жоқ"

#: common/flatpak-dir.c:13248
#, c-format
msgid "Invalid checksum for indexed summary %s read from %s"
msgstr "%2$s-ден оқылған индекстелген %1$s жиынтығының бақылау сомасы жарамсыз"

#: common/flatpak-dir.c:13321
#, c-format
msgid ""
"Remote listing for %s not available; server has no summary file. Check the "
"URL passed to remote-add was valid."
msgstr ""
"%s үшін қашықтағы тізім қолжетімді емес; серверде жиынтық файлы жоқ. remote-"
"add үшін берілген URL дұрыстығын тексеріңіз."

#: common/flatpak-dir.c:13698
#, c-format
msgid "Invalid checksum for indexed summary %s for remote '%s'"
msgstr ""
"'%2$s' қашықтағы репозиторийі үшін индекстелген %1$s жиынтығының бақылау "
"сомасы жарамсыз"

#: common/flatpak-dir.c:14388
#, c-format
msgid "Multiple branches available for %s, you must specify one of: "
msgstr ""
"%s үшін бірнеше тармақ қолжетімді, сіз мыналардың біреуін көрсетуіңіз керек: "

#: common/flatpak-dir.c:14454
#, c-format
msgid "Nothing matches %s"
msgstr "%s-ге сәйкес келетін ештеңе жоқ"

#: common/flatpak-dir.c:14562
#, c-format
msgid "Can't find ref %s%s%s%s%s"
msgstr "%s%s%s%s%s сілтемесі табылмады"

#: common/flatpak-dir.c:14605
#, c-format
msgid "Error searching remote %s: %s"
msgstr "%s қашықтағы репозиторийден іздеу қатесі: %s"

#: common/flatpak-dir.c:14702
#, c-format
msgid "Error searching local repository: %s"
msgstr "Жергілікті репозиторийден іздеу қатесі: %s"

#: common/flatpak-dir.c:14839
#, c-format
msgid "%s/%s/%s not installed"
msgstr "%s/%s/%s орнатылмаған"

#: common/flatpak-dir.c:15042
#, c-format
msgid "Could not find installation %s"
msgstr "%s орнатылымы табылмады"

#: common/flatpak-dir.c:15612
#, c-format
msgid "Invalid file format, no %s group"
msgstr "Файл пішімі жарамсыз, %s тобы жоқ"

#: common/flatpak-dir.c:15617 common/flatpak-repo-utils.c:2836
#, c-format
msgid "Invalid version %s, only 1 supported"
msgstr "Жарамсыз нұсқа %s, тек 1 қолдау көрсетіледі"

#: common/flatpak-dir.c:15622 common/flatpak-dir.c:15627
#, c-format
msgid "Invalid file format, no %s specified"
msgstr "Файл пішімі жарамсыз, %s көрсетілмеген"

#. Check some minimal size so we don't get crap
#: common/flatpak-dir.c:15647
msgid "Invalid file format, gpg key invalid"
msgstr "Файл пішімі жарамсыз, gpg кілті жарамсыз"

#: common/flatpak-dir.c:15675 common/flatpak-repo-utils.c:2917
msgid "Collection ID requires GPG key to be provided"
msgstr "Коллекция ID-і GPG кілтінің берілуін талап етеді"

#: common/flatpak-dir.c:15718
#, c-format
msgid "Runtime %s, branch %s is already installed"
msgstr "%s орындалу ортасының %s тармағы қазірдің өзінде орнатылған"

#: common/flatpak-dir.c:15719
#, c-format
msgid "App %s, branch %s is already installed"
msgstr "%s қолданбасының %s тармағы қазірдің өзінде орнатылған"

#: common/flatpak-dir.c:15953
#, c-format
msgid "Can't remove remote '%s' with installed ref %s (at least)"
msgstr ""
"Орнатылған %s сілтемесі (кем дегенде) болғандықтан, '%s' қашықтағы "
"репозиторийін өшіру мүмкін емес"

#: common/flatpak-dir.c:16058
#, c-format
msgid "Invalid character '/' in remote name: %s"
msgstr "Қашықтағы репозиторий атауында жарамсыз '/' таңбасы бар: %s"

#: common/flatpak-dir.c:16064
#, c-format
msgid "No configuration for remote %s specified"
msgstr "%s қашықтағы репозиторийі үшін ешқандай конфигурация көрсетілмеген"

#: common/flatpak-dir.c:17597
#, c-format
msgid "Skipping deletion of mirror ref (%s, %s)…\n"
msgstr "Айна сілтемесін (%s, %s) өшіру өткізіліп жіберілуде…\n"

#: common/flatpak-exports.c:931
#, c-format
msgid "An absolute path is required"
msgstr "Абсолюттік жол қажет"

#: common/flatpak-exports.c:948
#, c-format
msgid "Unable to open path \"%s\": %s"
msgstr "\"%s\" жолын ашу мүмкін емес: %s"

#: common/flatpak-exports.c:955
#, c-format
msgid "Unable to get file type of \"%s\": %s"
msgstr "\"%s\" файл түрін алу мүмкін емес: %s"

#: common/flatpak-exports.c:964
#, c-format
msgid "File \"%s\" has unsupported type 0o%o"
msgstr "\"%s\" файлының түрі 0o%o қолдау көрсетілмейді"

#: common/flatpak-exports.c:970
#, c-format
msgid "Unable to get filesystem information for \"%s\": %s"
msgstr "\"%s\" үшін файлдық жүйе ақпаратын алу мүмкін емес: %s"

#: common/flatpak-exports.c:980
#, c-format
msgid "Ignoring blocking autofs path \"%s\""
msgstr "Бөгеуші autofs \"%s\" жолы еленбейді"

#: common/flatpak-exports.c:996 common/flatpak-exports.c:1009
#: common/flatpak-exports.c:1022
#, c-format
msgid "Path \"%s\" is reserved by Flatpak"
msgstr "\"%s\" жолы Flatpak үшін брондалған"

#: common/flatpak-exports.c:1076
#, c-format
msgid "Unable to resolve symbolic link \"%s\": %s"
msgstr "\"%s\" символдық сілтемесін шешу мүмкін емес: %s"

#: common/flatpak-glib-backports.c:69
msgid "Empty string is not a number"
msgstr "Бос жол сан емес"

#: common/flatpak-glib-backports.c:95
#, c-format
msgid "“%s” is not an unsigned number"
msgstr "“%s” таңбасыз сан емес"

#: common/flatpak-glib-backports.c:105
#, c-format
msgid "Number “%s” is out of bounds [%s, %s]"
msgstr "“%s” саны [%s, %s] шегінен тыс"

#: common/flatpak-image-source.c:83
msgid "Only sha256 image checksums are supported"
msgstr "Тек sha256 бейне бақылау сомаларына қолдау көрсетіледі"

#: common/flatpak-image-source.c:100 common/flatpak-image-source.c:108
msgid "Image is not a manifest"
msgstr "Бейне манифест емес"

#: common/flatpak-image-source.c:123
msgid "No org.flatpak.ref found in image"
msgstr "Бейне ішінен org.flatpak.ref табылмады"

#: common/flatpak-image-source.c:148
#, c-format
msgid "Ref '%s' not found in registry"
msgstr "'%s' сілтемесі тіркеуден табылмады"

#: common/flatpak-image-source.c:157
msgid "Multiple images in registry, specify a ref with --ref"
msgstr "Тіркеуде бірнеше бейне бар, --ref арқылы сілтемені көрсетіңіз"

#: common/flatpak-installation.c:834
#, c-format
msgid "Ref %s not installed"
msgstr "%s сілтемесі орнатылмаған"

#: common/flatpak-installation.c:875
#, c-format
msgid "App %s not installed"
msgstr "%s қолданбасы орнатылмаған"

#: common/flatpak-installation.c:1395
#, c-format
msgid "Remote '%s' already exists"
msgstr "'%s' қашықтағы репозиторийі қазірдің өзінде бар"

#: common/flatpak-installation.c:1946
#, c-format
msgid "As requested, %s was only pulled, but not installed"
msgstr "Сұралғандай, %s тек тартылды, бірақ орнатылған жоқ"

#: common/flatpak-instance.c:533 common/flatpak-instance.c:687
#: common/flatpak-instance.c:728
#, c-format
msgid "Unable to create directory %s"
msgstr "%s бумасын жасау мүмкін емес"

#: common/flatpak-instance.c:554
#, c-format
msgid "Unable to lock %s"
msgstr "%s құлыптау мүмкін емес"

#: common/flatpak-instance.c:627
#, c-format
msgid "Unable to create temporary directory in %s"
msgstr "%s ішінде уақытша бума жасау мүмкін емес"

#: common/flatpak-instance.c:639
#, c-format
msgid "Unable to create file %s"
msgstr "%s файлын жасау мүмкін емес"

#: common/flatpak-instance.c:646
#, c-format
msgid "Unable to update symbolic link %s/%s"
msgstr "%s/%s символдық сілтемесін жаңарту мүмкін емес"

#: common/flatpak-oci-registry.c:1197
msgid "Only Bearer authentication supported"
msgstr "Тек Bearer аутентификациясына қолдау көрсетіледі"

#: common/flatpak-oci-registry.c:1206
msgid "Only realm in authentication request"
msgstr "Аутентификация сұранысында тек realm бар"

#: common/flatpak-oci-registry.c:1213
msgid "Invalid realm in authentication request"
msgstr "Аутентификация сұранысында realm жарамсыз"

#: common/flatpak-oci-registry.c:1283
#, c-format
msgid "Authorization failed: %s"
msgstr "Авторизация сәтсіз аяқталды: %s"

#: common/flatpak-oci-registry.c:1285
msgid "Authorization failed"
msgstr "Авторизация сәтсіз аяқталды"

#: common/flatpak-oci-registry.c:1289
#, c-format
msgid "Unexpected response status %d when requesting token: %s"
msgstr "Токенді сұрау кезінде күтілмеген %d жауап күйі: %s"

#: common/flatpak-oci-registry.c:1300
msgid "Invalid authentication request response"
msgstr "Аутентификация сұранысына жауап жарамсыз"

#: common/flatpak-oci-registry.c:1731
#, c-format
msgid "Flatpak was compiled without zstd support"
msgstr "Flatpak zstd қолдауынсыз жинақталған"

#: common/flatpak-oci-registry.c:1923 common/flatpak-oci-registry.c:1975
#: common/flatpak-oci-registry.c:2004 common/flatpak-oci-registry.c:2059
#: common/flatpak-oci-registry.c:2115 common/flatpak-oci-registry.c:2193
msgid "Invalid delta file format"
msgstr "Дельта файл пішімі жарамсыз"

#: common/flatpak-oci-registry.c:3198 common/flatpak-oci-registry.c:3382
msgid "Invalid OCI image config"
msgstr "OCI бейне конфигурациясы жарамсыз"

#: common/flatpak-oci-registry.c:3260 common/flatpak-oci-registry.c:3531
#, c-format
msgid "Wrong layer checksum, expected %s, was %s"
msgstr "Қабаттың бақылау сомасы қате, %s күтілді, бірақ %s болды"

#: common/flatpak-oci-registry.c:3359
#, c-format
msgid "No ref specified for OCI image %s"
msgstr "%s OCI бейнесі үшін сілтеме көрсетілмеген"

#: common/flatpak-oci-registry.c:3369
#, c-format
msgid "Wrong ref (%s) specified for OCI image %s, expected %s"
msgstr "%2$s OCI бейнесі үшін %1$s сілтемесі қате, %3$s күтілді"

#: common/flatpak-progress.c:236
#, c-format
msgid "Downloading metadata: %u/(estimating) %s"
msgstr "Метадеректер жүктелуде: %u/(шамамен) %s"

#: common/flatpak-progress.c:260
#, c-format
msgid "Downloading: %s/%s"
msgstr "Жүктелуде: %s/%s"

#: common/flatpak-progress.c:280
#, c-format
msgid "Downloading extra data: %s/%s"
msgstr "Қосымша деректер жүктелуде: %s/%s"

#: common/flatpak-progress.c:285
#, c-format
msgid "Downloading files: %d/%d %s"
msgstr "Файлдар жүктелуде: %1$d/%2$d %3$s"

#: common/flatpak-ref-utils.c:122
msgid "Name can't be empty"
msgstr "Атау бос болмауы тиіс"

#: common/flatpak-ref-utils.c:129
msgid "Name can't be longer than 255 characters"
msgstr "Атау 255 таңбадан ұзын болмауы тиіс"

#: common/flatpak-ref-utils.c:142
msgid "Name can't start with a period"
msgstr "Атау нүктеден басталмауы тиіс"

#: common/flatpak-ref-utils.c:148
#, c-format
msgid "Name can't start with %c"
msgstr "Атау %c таңбасынан басталмауы тиіс"

#: common/flatpak-ref-utils.c:164
msgid "Name can't end with a period"
msgstr "Атау нүктемен аяқталмауы тиіс"

#: common/flatpak-ref-utils.c:171 common/flatpak-ref-utils.c:183
msgid "Only last name segment can contain -"
msgstr "Тек соңғы атау сегментінде - болуы мүмкін"

#: common/flatpak-ref-utils.c:174
#, c-format
msgid "Name segment can't start with %c"
msgstr "Атау сегменті %c таңбасынан басталмауы тиіс"

#: common/flatpak-ref-utils.c:186
#, c-format
msgid "Name can't contain %c"
msgstr "Атауда %c болмауы тиіс"

#: common/flatpak-ref-utils.c:195
msgid "Names must contain at least 2 periods"
msgstr "Атауларда кем дегенде 2 нүкте болуы тиіс"

#: common/flatpak-ref-utils.c:312
msgid "Arch can't be empty"
msgstr "Архитектура бос болмауы тиіс"

#: common/flatpak-ref-utils.c:323
#, c-format
msgid "Arch can't contain %c"
msgstr "Архитектурада %c болмауы тиіс"

#: common/flatpak-ref-utils.c:385
msgid "Branch can't be empty"
msgstr "Тармақ бос болмауы тиіс"

#: common/flatpak-ref-utils.c:395
#, c-format
msgid "Branch can't start with %c"
msgstr "Тармақ %c таңбасынан басталмауы тиіс"

#: common/flatpak-ref-utils.c:405
#, c-format
msgid "Branch can't contain %c"
msgstr "Тармақта %c болмауы тиіс"

#: common/flatpak-ref-utils.c:615 common/flatpak-ref-utils.c:865
msgid "Ref too long"
msgstr "Сілтеме тым ұзын"

#: common/flatpak-ref-utils.c:627
msgid "Invalid remote name"
msgstr "Қашықтағы репозиторий атауы жарамсыз"

#: common/flatpak-ref-utils.c:641
#, c-format
msgid "%s is not application or runtime"
msgstr "%s қолданба немесе орындалу ортасы емес"

#: common/flatpak-ref-utils.c:650 common/flatpak-ref-utils.c:667
#: common/flatpak-ref-utils.c:683
#, c-format
msgid "Wrong number of components in %s"
msgstr "%s ішіндегі компоненттер саны қате"

#: common/flatpak-ref-utils.c:656
#, c-format
msgid "Invalid name %.*s: %s"
msgstr "Жарамсыз атау %.*s: %s"

#: common/flatpak-ref-utils.c:673
#, c-format
msgid "Invalid arch: %.*s: %s"
msgstr "Жарамсыз архитектура: %.*s: %s"

#: common/flatpak-ref-utils.c:816
#, c-format
msgid "Invalid name %s: %s"
msgstr "Жарамсыз атау %s: %s"

#: common/flatpak-ref-utils.c:834
#, c-format
msgid "Invalid arch: %s: %s"
msgstr "Жарамсыз архитектура: %s: %s"

#: common/flatpak-ref-utils.c:853
#, c-format
msgid "Invalid branch: %s: %s"
msgstr "Жарамсыз тармақ: %s: %s"

#: common/flatpak-ref-utils.c:962 common/flatpak-ref-utils.c:970
#: common/flatpak-ref-utils.c:978
#, c-format
msgid "Wrong number of components in partial ref %s"
msgstr "Жартылай %s сілтемесіндегі компоненттер саны қате"

#: common/flatpak-ref-utils.c:1298
msgid " development platform"
msgstr " әзірлеу платформасы"

#: common/flatpak-ref-utils.c:1300
msgid " platform"
msgstr " платформа"

#: common/flatpak-ref-utils.c:1302
msgid " application base"
msgstr " қолданба негізі"

#: common/flatpak-ref-utils.c:1305
msgid " debug symbols"
msgstr " жөндеу таңбалары"

#: common/flatpak-ref-utils.c:1307
msgid " sourcecode"
msgstr " бастапқы код"

#: common/flatpak-ref-utils.c:1309
msgid " translations"
msgstr " аудармалар"

#: common/flatpak-ref-utils.c:1311
msgid " docs"
msgstr " құжаттама"

#: common/flatpak-ref-utils.c:1578
#, c-format
msgid "Invalid id %s: %s"
msgstr "Жарамсыз id %s: %s"

#: common/flatpak-remote.c:1216
#, c-format
msgid "Bad remote name: %s"
msgstr "Қашықтағы репозиторий атауы қате: %s"

#: common/flatpak-remote.c:1220
msgid "No URL specified"
msgstr "URL көрсетілмеген"

#: common/flatpak-remote.c:1266
msgid "GPG verification must be enabled when a collection ID is set"
msgstr "Коллекция ID-і орнатылған кезде GPG тексеруі іске қосылуы тиіс"

#: common/flatpak-repo-utils.c:344
#, c-format
msgid "No extra data sources"
msgstr "Қосымша дерек көздері жоқ"

#: common/flatpak-repo-utils.c:2817
#, c-format
msgid "Invalid %s: Missing group ‘%s’"
msgstr "Жарамсыз %s: ‘%s’ тобы жоқ"

#: common/flatpak-repo-utils.c:2826
#, c-format
msgid "Invalid %s: Missing key ‘%s’"
msgstr "Жарамсыз %s: ‘%s’ кілті жоқ"

#: common/flatpak-repo-utils.c:2876
msgid "Invalid gpg key"
msgstr "GPG кілті жарамсыз"

#: common/flatpak-repo-utils.c:3217
#, c-format
msgid "Error copying 64x64 icon for component %s: %s\n"
msgstr "%s компоненті үшін 64x64 таңбашасын көшіру қатесі: %s\n"

#: common/flatpak-repo-utils.c:3223
#, c-format
msgid "Error copying 128x128 icon for component %s: %s\n"
msgstr "%s компоненті үшін 128x128 таңбашасын көшіру қатесі: %s\n"

#: common/flatpak-repo-utils.c:3362
#, c-format
msgid "%s is end-of-life, ignoring for appstream"
msgstr "%s қолдау мерзімі аяқталған, appstream үшін еленбейді"

#: common/flatpak-repo-utils.c:3397
#, c-format
msgid "No appstream data for %s: %s\n"
msgstr "%s үшін appstream деректері жоқ: %s\n"

#: common/flatpak-repo-utils.c:3744
msgid "Invalid bundle, no ref in metadata"
msgstr "Десте жарамсыз, метадеректерде сілтеме жоқ"

#: common/flatpak-repo-utils.c:3846
#, c-format
msgid "Collection ‘%s’ of bundle doesn’t match collection ‘%s’ of remote"
msgstr ""
"Дестенің ‘%s’ коллекциясы қашықтағы репозиторийдің ‘%s’ коллекциясына сәйкес "
"келмейді"

#: common/flatpak-repo-utils.c:3923
msgid "Metadata in header and app are inconsistent"
msgstr "Тақырыптама және қолданбадағы метадеректер сәйкес емес"

#: common/flatpak-run.c:951
msgid "No systemd user session available, cgroups not available"
msgstr "systemd пайдаланушы сессиясы қолжетімді емес, cgroups қолжетімді емес"

#: common/flatpak-run.c:1496
msgid "Unable to allocate instance id"
msgstr "Инстанция id-ін бөлу мүмкін емес"

#: common/flatpak-run.c:1632 common/flatpak-run.c:1641
#, c-format
msgid "Failed to open flatpak-info file: %s"
msgstr "flatpak-info файлын ашу сәтсіз аяқталды: %s"

#: common/flatpak-run.c:1668
#, c-format
msgid "Failed to open bwrapinfo.json file: %s"
msgstr "bwrapinfo.json файлын ашу сәтсіз аяқталды: %s"

#: common/flatpak-run.c:1689
#, c-format
msgid "Failed to write to instance id fd: %s"
msgstr "Инстанция id fd-ге жазу сәтсіз аяқталды: %s"

#: common/flatpak-run.c:2096
msgid "Initialize seccomp failed"
msgstr "Seccomp инициализациясы сәтсіз аяқталды"

#: common/flatpak-run.c:2135
#, c-format
msgid "Failed to add architecture to seccomp filter: %s"
msgstr "Архитектураны seccomp сүзгісіне қосу сәтсіз аяқталды: %s"

#: common/flatpak-run.c:2143
#, c-format
msgid "Failed to add multiarch architecture to seccomp filter: %s"
msgstr "Мультиархитектураны seccomp сүзгісіне қосу сәтсіз аяқталды: %s"

#: common/flatpak-run.c:2175 common/flatpak-run.c:2192
#: common/flatpak-run.c:2214
#, c-format
msgid "Failed to block syscall %d: %s"
msgstr "%d жүйелік шақыруын бөгеу сәтсіз аяқталды: %s"

#: common/flatpak-run.c:2247
#, c-format
msgid "Failed to export bpf: %s"
msgstr "bpf экспорттау сәтсіз аяқталды: %s"

#: common/flatpak-run.c:2587
#, c-format
msgid "Failed to open ‘%s’"
msgstr "‘%s’ ашу мүмкін болмады"

#: common/flatpak-run.c:2597
#, c-format
msgid ""
"Directory forwarding needs version 4 of the document portal (have version %d)"
msgstr ""
"Буманы қайта бағыттау үшін құжат порталының 4-нұсқасы қажет (%d нұсқасы бар)"

#: common/flatpak-run.c:2915
#, c-format
msgid "ldconfig failed, exit status %d"
msgstr "ldconfig сәтсіз аяқталды, шығу күйі %d"

#: common/flatpak-run.c:2922
msgid "Can't open generated ld.so.cache"
msgstr "Жасалған ld.so.cache файлын ашу мүмкін емес"

#. Translators: The placeholder is for an app ref.
#: common/flatpak-run.c:3045
#, c-format
msgid "Running %s is not allowed by the policy set by your administrator"
msgstr "%s орындауға әкімші орнатқан саясатпен рұқсат берілмеген"

#: common/flatpak-run.c:3202
msgid ""
"\"flatpak run\" is not intended to be run as `sudo flatpak run`. Use `sudo "
"-i` or `su -l` instead and invoke \"flatpak run\" from inside the new shell."
msgstr ""
"\"flatpak run\" командасы `sudo flatpak run` ретінде орындауға арналмаған. "
"Оның орнына `sudo -i` немесе `su -l` қолданыңыз және жаңа қоршам ішінен "
"\"flatpak run\" шақырыңыз."

#: common/flatpak-run.c:3413
#, c-format
msgid "Failed to migrate from %s: %s"
msgstr "%s-ден көшіру сәтсіз аяқталды: %s"

#: common/flatpak-run.c:3434
#, c-format
msgid "Failed to migrate old app data directory %s to new name %s: %s"
msgstr ""
"Ескі қолданба деректер бумасын %s жаңа %s атауына көшіру сәтсіз аяқталды: %s"

#: common/flatpak-run.c:3443
#, c-format
msgid "Failed to create symlink while migrating %s: %s"
msgstr "%s көшіру кезінде символдық сілтеме жасау сәтсіз аяқталды: %s"

#: common/flatpak-run-dbus.c:46
msgid "Failed to open app info file"
msgstr "Қолданба ақпараты файлын ашу сәтсіз аяқталды"

#: common/flatpak-run-dbus.c:149
msgid "Unable to create sync pipe"
msgstr "Синхрондау арнасын (pipe) жасау мүмкін емес"

#: common/flatpak-run-dbus.c:185
msgid "Failed to sync with dbus proxy"
msgstr "dbus проксиімен синхрондау сәтсіз аяқталды"

#: common/flatpak-transaction.c:2275
#, c-format
msgid "Warning: Problem looking for related refs: %s"
msgstr "Ескерту: Қатысты сілтемелерді іздеу мәселесі: %s"

#: common/flatpak-transaction.c:2493
#, c-format
msgid "The application %s requires the runtime %s which was not found"
msgstr "%s қолданбасы %s орындалу ортасын талап етеді, ол табылмады"

#: common/flatpak-transaction.c:2509
#, c-format
msgid "The application %s requires the runtime %s which is not installed"
msgstr "%s қолданбасы %s орындалу ортасын талап етеді, ол орнатылмаған"

#: common/flatpak-transaction.c:2641
#, c-format
msgid "Can't uninstall %s which is needed by %s"
msgstr "%2$s үшін қажет %1$s өшіру мүмкін емес"

#: common/flatpak-transaction.c:2740
#, c-format
msgid "Remote %s disabled, ignoring %s update"
msgstr "%s қашықтағы репозиторийі сөндірілген, %s жаңартуы еленбейді"

#: common/flatpak-transaction.c:2773
#, c-format
msgid "%s is already installed"
msgstr "%s қазірдің өзінде орнатылған"

#: common/flatpak-transaction.c:2776
#, c-format
msgid "%s is already installed from remote %s"
msgstr "%s қазірдің өзінде %s қашықтағы репозиторийден орнатылған"

#: common/flatpak-transaction.c:3120
#, c-format
msgid "Invalid .flatpakref: %s"
msgstr ".flatpakref жарамсыз: %s"

#: common/flatpak-transaction.c:3161
msgid "Warning: Could not mark already installed apps as preinstalled"
msgstr ""
"Ескерту: Орнатылып қойған қолданбаларды алдын ала орнатылған деп белгілеу "
"мүмкін болмады"

#: common/flatpak-transaction.c:3382
#, c-format
msgid "Error updating remote metadata for '%s': %s"
msgstr "'%s' үшін қашықтағы метадеректерді жаңарту қатесі: %s"

#: common/flatpak-transaction.c:3885
#, c-format
msgid ""
"Warning: Treating remote fetch error as non-fatal since %s is already "
"installed: %s"
msgstr ""
"Ескерту: %s қазірдің өзінде орнатылғандықтан, қашықтағы алу қатесі "
"критикалық емес деп есептеледі: %s"

#: common/flatpak-transaction.c:4209
#, c-format
msgid "No authenticator installed for remote '%s'"
msgstr "'%s' қашықтағы репозиторийі үшін ешқандай аутентификатор орнатылмаған"

#: common/flatpak-transaction.c:4313 common/flatpak-transaction.c:4320
#, c-format
msgid "Failed to get tokens for ref: %s"
msgstr "Сілтеме үшін токендерді алу сәтсіз аяқталды: %s"

#: common/flatpak-transaction.c:4315 common/flatpak-transaction.c:4322
msgid "Failed to get tokens for ref"
msgstr "Сілтеме үшін токендерді алу сәтсіз аяқталды"

#: common/flatpak-transaction.c:4580
#, c-format
msgid "Ref %s from %s matches more than one transaction operation"
msgstr ""
"%2$s ішіндегі %1$s сілтемесі бірден көп транзакция операциясына сәйкес келеді"

#: common/flatpak-transaction.c:4581 common/flatpak-transaction.c:4591
msgid "any remote"
msgstr "кез келген қашықтағы репозиторий"

#: common/flatpak-transaction.c:4590
#, c-format
msgid "No transaction operation found for ref %s from %s"
msgstr ""
"%2$s ішіндегі %1$s сілтемесі үшін ешқандай транзакция операциясы табылмады"

#: common/flatpak-transaction.c:4713
#, c-format
msgid "Flatpakrepo URL %s not file, HTTP or HTTPS"
msgstr "Flatpakrepo URL-і %s файл, HTTP немесе HTTPS емес"

#: common/flatpak-transaction.c:4719
#, c-format
msgid "Can't load dependent file %s: "
msgstr "Тәуелді %s файлын жүктеу мүмкін емес: "

#: common/flatpak-transaction.c:4727
#, c-format
msgid "Invalid .flatpakrepo: %s"
msgstr ".flatpakrepo жарамсыз: %s"

#: common/flatpak-transaction.c:5454
msgid "Transaction already executed"
msgstr "Транзакция қазірдің өзінде орындалған"

#: common/flatpak-transaction.c:5469
msgid ""
"Refusing to operate on a user installation as root! This can lead to "
"incorrect file ownership and permission errors."
msgstr ""
"Root ретінде пайдаланушы орнатылымында жұмыс істеуден бас тартылды! Бұл файл "
"иелігі мен рұқсаттарының қате болуына әкелуі мүмкін."

#: common/flatpak-transaction.c:5567 common/flatpak-transaction.c:5580
msgid "Aborted by user"
msgstr "Пайдаланушымен тоқтатылды"

#: common/flatpak-transaction.c:5605
#, c-format
msgid "Skipping %s due to previous error"
msgstr "Алдыңғы қатеге байланысты %s өткізіліп жіберілуде"

#: common/flatpak-transaction.c:5659
#, c-format
msgid "Aborted due to failure (%s)"
msgstr "Сәтсіздікке байланысты тоқтатылды (%s)"

#: common/flatpak-uri.c:118
#, no-c-format
msgid "Invalid %-encoding in URI"
msgstr "URI-дегі %-кодтау жарамсыз"

#: common/flatpak-uri.c:135
msgid "Illegal character in URI"
msgstr "URI-дегі рұқсат етілмеген таңба"

#: common/flatpak-uri.c:169
msgid "Non-UTF-8 characters in URI"
msgstr "URI-дегі UTF-8 емес таңбалар"

#: common/flatpak-uri.c:275
#, c-format
msgid "Invalid IPv6 address ‘%.*s’ in URI"
msgstr "URI-дегі жарамсыз IPv6 адресі ‘%.*s’"

#: common/flatpak-uri.c:330
#, c-format
msgid "Illegal encoded IP address ‘%.*s’ in URI"
msgstr "URI-дегі қате кодталған IP адресі ‘%.*s’"

#: common/flatpak-uri.c:342
#, c-format
msgid "Illegal internationalized hostname ‘%.*s’ in URI"
msgstr "URI-дегі рұқсат етілмеген интернационалдандырылған хост атауы ‘%.*s’"

#: common/flatpak-uri.c:374 common/flatpak-uri.c:386
#, c-format
msgid "Could not parse port ‘%.*s’ in URI"
msgstr "URI-дегі ‘%.*s’ портын өңдеу мүмкін емес"

#: common/flatpak-uri.c:393
#, c-format
msgid "Port ‘%.*s’ in URI is out of range"
msgstr "URI-дегі ‘%.*s’ порты шектен тыс"

#: common/flatpak-uri.c:910
msgid "URI is not absolute, and no base URI was provided"
msgstr "URI абсолютті емес және ешқандай базалық URI берілмеген"

#: common/flatpak-usb.c:83
#, c-format
msgid "USB device query 'all' must not have data"
msgstr "USB құрылғысының 'all' сұранысында деректер болмауы тиіс"

#: common/flatpak-usb.c:102
#, c-format
msgid "USB query rule 'cls' must be in the form CLASS:SUBCLASS or CLASS:*"
msgstr ""
"USB 'cls' сұраныс ережесі CLASS:SUBCLASS немесе CLASS:* түрінде болуы тиіс"

#: common/flatpak-usb.c:111
#, c-format
msgid "Invalid USB class"
msgstr "USB класы жарамсыз"

#: common/flatpak-usb.c:125
#, c-format
msgid "Invalid USB subclass"
msgstr "USB ішкі класы жарамсыз"

#: common/flatpak-usb.c:141 common/flatpak-usb.c:148
#, c-format
msgid "USB query rule 'dev' must have a valid 4-digit hexadecimal product id"
msgstr ""
"USB 'dev' сұраныс ережесінде жарамды 4 таңбалы он алтылық өнім id-і болуы "
"тиіс"

#: common/flatpak-usb.c:164 common/flatpak-usb.c:171
#, c-format
msgid "USB query rule 'vnd' must have a valid 4-digit hexadecimal vendor id"
msgstr ""
"USB 'vnd' сұраныс ережесінде жарамды 4 таңбалы он алтылық өндіруші id-і "
"болуы тиіс"

#: common/flatpak-usb.c:205
#, c-format
msgid "USB device queries must be in the form TYPE:DATA"
msgstr "USB құрылғысының сұраныстары ТҮРІ:ДЕРЕКТЕР пішімінде болуы тиіс"

#: common/flatpak-usb.c:225
#, c-format
msgid "Unknown USB query rule %s"
msgstr "USB сұранысының %s ережесі белгісіз"

#: common/flatpak-usb.c:248
#, c-format
msgid "Empty USB query"
msgstr "USB сұранысы бос"

#: common/flatpak-usb.c:274
#, c-format
msgid "Multiple USB query rules of the same type is not supported"
msgstr "Бірдей түрдегі бірнеше USB сұраныс ережелеріне қолдау көрсетілмейді"

#: common/flatpak-usb.c:283
#, c-format
msgid "'all' must not contain extra query rules"
msgstr "'all' құрамында артық сұраныс ережелері болмауы тиіс"

#: common/flatpak-usb.c:291
#, c-format
msgid "USB queries with 'dev' must also specify vendors"
msgstr "'dev' бар USB сұраныстары өндірушілерді де көрсетуі тиіс"

#: common/flatpak-utils.c:712
msgid "Glob can't match apps"
msgstr "Глоб қолданбаларға сәйкес келе алмайды"

#: common/flatpak-utils.c:737
msgid "Empty glob"
msgstr "Глоб бос"

#: common/flatpak-utils.c:756
msgid "Too many segments in glob"
msgstr "Глобта сегменттер тым көп"

#: common/flatpak-utils.c:777
#, c-format
msgid "Invalid glob character '%c'"
msgstr "Глоб таңбасы жарамсыз: '%c'"

#: common/flatpak-utils.c:831
#, c-format
msgid "Missing glob on line %d"
msgstr "%d жолында глоб жоқ"

#: common/flatpak-utils.c:835
#, c-format
msgid "Trailing text on line %d"
msgstr "%d жолының соңында артық мәтін бар"

#: common/flatpak-utils.c:839
#, c-format
msgid "on line %d"
msgstr "%d жолында"

#: common/flatpak-utils.c:861
#, c-format
msgid "Unexpected word '%s' on line %d"
msgstr "%2$d жолында күтілмеген '%1$s' сөзі"

#: common/flatpak-utils.c:2118
#, c-format
msgid "Invalid require-flatpak argument %s"
msgstr "require-flatpak аргументі жарамсыз: %s"

#: common/flatpak-utils.c:2128 common/flatpak-utils.c:2147
#, c-format
msgid "%s needs a later flatpak version (%s)"
msgstr "%s үшін кейінгі flatpak нұсқасы қажет (%s)"

#: oci-authenticator/flatpak-oci-authenticator.c:291
msgid "Not a oci remote, missing summary.xa.oci-repository"
msgstr "oci қашықтағы репозиторийі емес, summary.xa.oci-repository жоқ"

#: oci-authenticator/flatpak-oci-authenticator.c:477
msgid "Not a OCI remote"
msgstr "OCI қашықтағы репозиторийі емес"

#: oci-authenticator/flatpak-oci-authenticator.c:488
msgid "Invalid token"
msgstr "Токен жарамсыз"

#: portal/flatpak-portal.c:2292
#, c-format
msgid "No portal support found"
msgstr "Портал қолдауы табылмады"

#: portal/flatpak-portal.c:2298
msgid "Deny"
msgstr "Тыйым салу"

#: portal/flatpak-portal.c:2300
msgid "Update"
msgstr "Жаңарту"

#: portal/flatpak-portal.c:2305
#, c-format
msgid "Update %s?"
msgstr "%s жаңарту керек пе?"

#: portal/flatpak-portal.c:2317
msgid "The application wants to update itself."
msgstr "Қолданба өз-өзін жаңартқысы келеді."

#: portal/flatpak-portal.c:2318
msgid "Update access can be changed any time from the privacy settings."
msgstr ""
"Жаңарту рұқсатын кез келген уақытта жекелік баптауларынан өзгертуге болады."

#: portal/flatpak-portal.c:2343
#, c-format
msgid "Application update not allowed"
msgstr "Қолданбаны жаңартуға рұқсат жоқ"

#: portal/flatpak-portal.c:2501
#, c-format
msgid "Self update not supported, new version requires new permissions"
msgstr ""
"Өзін-өзі жаңартуға қолдау көрсетілмейді, жаңа нұсқа жаңа рұқсаттарды талап "
"етеді"

#: portal/flatpak-portal.c:2684 portal/flatpak-portal.c:2702
#, c-format
msgid "Update ended unexpectedly"
msgstr "Жаңарту күтпеген жерден аяқталды"

#. SECURITY:
#. - Normal users need admin authentication to install software
#. system-wide.
#. - Note that we install polkit rules that allow local users
#. in the wheel group to install without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:23
msgid "Install signed application"
msgstr "Қол қойылған қолданбаны орнату"

#: system-helper/org.freedesktop.Flatpak.policy.in:24
#: system-helper/org.freedesktop.Flatpak.policy.in:42
msgid "Authentication is required to install software"
msgstr "Бағдарламалық қамтаманы орнату үшін аутентификация қажет"

#. SECURITY:
#. - Normal users need admin authentication to install software
#. system-wide.
#. - Note that we install polkit rules that allow local users
#. in the wheel group to install without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:41
msgid "Install signed runtime"
msgstr "Қол қойылған орындалу ортасын орнату"

#. SECURITY:
#. - Normal users do not require admin authentication to update an
#. app as the commit will be signed, and the action is required
#. to update the system when unattended.
#. - Changing this to anything other than 'yes' will break unattended
#. updates.
#: system-helper/org.freedesktop.Flatpak.policy.in:60
msgid "Update signed application"
msgstr "Қол қойылған қолданбаны жаңарту"

#: system-helper/org.freedesktop.Flatpak.policy.in:61
#: system-helper/org.freedesktop.Flatpak.policy.in:80
msgid "Authentication is required to update software"
msgstr "Бағдарламалық қамтаманы жаңарту үшін аутентификация қажет"

#. SECURITY:
#. - Normal users do not require admin authentication to update a
#. runtime as the commit will be signed, and the action is required
#. to update the system when unattended.
#. - Changing this to anything other than 'yes' will break unattended
#. updates.
#: system-helper/org.freedesktop.Flatpak.policy.in:79
msgid "Update signed runtime"
msgstr "Қол қойылған орындалу ортасын жаңарту"

#. SECURITY:
#. - Normal users do not need authentication to update metadata
#. from signed repositories.
#: system-helper/org.freedesktop.Flatpak.policy.in:94
msgid "Update remote metadata"
msgstr "Қашықтағы метадеректерді жаңарту"

#: system-helper/org.freedesktop.Flatpak.policy.in:95
msgid "Authentication is required to update remote info"
msgstr "Қашықтағы ақпаратты жаңарту үшін аутентификация қажет"

#. SECURITY:
#. - Normal users do not need authentication to modify the
#. OSTree repository
#. - Note that we install polkit rules that allow local users
#. in the wheel group to modify repos without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:111
msgid "Update system repository"
msgstr "Жүйелік репозиторийді жаңарту"

#: system-helper/org.freedesktop.Flatpak.policy.in:112
msgid "Authentication is required to modify a system repository"
msgstr "Жүйелік репозиторийді өзгерту үшін аутентификация қажет"

#. SECURITY:
#. - Normal users need admin authentication to install software
#. system-wide.
#: system-helper/org.freedesktop.Flatpak.policy.in:126
msgid "Install bundle"
msgstr "Дестені орнату"

#: system-helper/org.freedesktop.Flatpak.policy.in:127
msgid "Authentication is required to install software from $(path)"
msgstr ""
"$(path) орнынан бағдарламалық қамтаманы орнату үшін аутентификация қажет"

#. SECURITY:
#. - Normal users need admin authentication to uninstall software
#. system-wide.
#. - Note that we install polkit rules that allow local users
#. in the wheel group to uninstall without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:144
msgid "Uninstall runtime"
msgstr "Орындалу ортасын өшіру"

#: system-helper/org.freedesktop.Flatpak.policy.in:145
msgid "Authentication is required to uninstall software"
msgstr "Бағдарламалық қамтаманы өшіру үшін аутентификация қажет"

#. SECURITY:
#. - Normal users need admin authentication to uninstall software
#. system-wide.
#. - Note that we install polkit rules that allow local users
#. in the wheel group to uninstall without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:161
msgid "Uninstall app"
msgstr "Қолданбаны өшіру"

#: system-helper/org.freedesktop.Flatpak.policy.in:162
msgid "Authentication is required to uninstall $(ref)"
msgstr "$(ref) өшіру үшін аутентификация қажет"

#. SECURITY:
#. - Normal users need admin authentication to configure system-wide
#. software repositories.
#: system-helper/org.freedesktop.Flatpak.policy.in:177
msgid "Configure Remote"
msgstr "Қашықтағы репозиторийді баптау"

#: system-helper/org.freedesktop.Flatpak.policy.in:178
msgid "Authentication is required to configure software repositories"
msgstr ""
"Бағдарламалық қамтама репозиторийлерін баптау үшін аутентификация қажет"

#. SECURITY:
#. - Normal users need admin authentication to configure the system-wide
#. Flatpak installation.
#: system-helper/org.freedesktop.Flatpak.policy.in:192
msgid "Configure"
msgstr "Баптау"

#: system-helper/org.freedesktop.Flatpak.policy.in:193
msgid "Authentication is required to configure software installation"
msgstr "Бағдарламалық қамтама орнатылымын баптау үшін аутентификация қажет"

#. SECURITY:
#. - Normal users do not require admin authentication to update
#. appstream data as it will be signed, and the action is required
#. to update the system when unattended.
#. - Changing this to anything other than 'yes' will break unattended
#. updates.
#: system-helper/org.freedesktop.Flatpak.policy.in:210
msgid "Update appstream"
msgstr "appstream жаңарту"

#: system-helper/org.freedesktop.Flatpak.policy.in:211
msgid "Authentication is required to update information about software"
msgstr ""
"Бағдарламалық қамтама туралы ақпаратты жаңарту үшін аутентификация қажет"

#. SECURITY:
#. - Normal users do not require admin authentication to update
#. metadata as it will be signed, and the action is required
#. to update the system when unattended.
#. - Changing this to anything other than 'yes' will break unattended
#. updates.
#: system-helper/org.freedesktop.Flatpak.policy.in:228
msgid "Update metadata"
msgstr "Метадеректерді жаңарту"

#: system-helper/org.freedesktop.Flatpak.policy.in:229
msgid "Authentication is required to update metadata"
msgstr "Метадеректерді жаңарту үшін аутентификация қажет"

#. SECURITY:
#. - Authorisation to actually install software is controlled by
#. org.freedesktop.Flatpak.app-install.
#. - This action is checked after app-install, as it can only be done
#. once the app’s data (including its content rating) has been
#. downloaded.
#. - This action is checked to see if the installation should be allowed
#. based on whether the app being installed has content which doesn’t
#. comply with the user’s parental controls policy (the content is
#. ‘too extreme’).
#. - It is checked only if an app has too extreme content for the user
#. who is trying to install it (in which case, the app is ‘unsafe’).
#. - Typically, normal users will need admin permission to install apps
#. with extreme content; admins will be able to install it without
#. additional checks.
#. - In order to configure the policy so that admins can install safe and
#. unsafe software anywhere without authorisation, and non-admins can
#. install safe software in their user or system dirs without
#. authorisation, but need authorisation to install unsafe software
#. anywhere:
#. * Unconditionally return `yes` from `app-install`.
#. * Return `auth_admin` from `override-parental-controls` for users
#. not in `@privileged_group@`, and `yes` for users in it.
#. * Set the malcontent `is-{user,system}-installation-allowed`
#. properties of all non-admins’ parental controls policies to true.
#. - In order to configure the policy so that admins can install safe and
#. unsafe software anywhere without authorisation, and non-admins can
#. install safe software in their user dir without authorisation, but
#. need authorisation to install safe software in the system dir or to
#. install unsafe software anywhere:
#. * Unconditionally return `yes` from `app-install`.
#. * Return `auth_admin` from `override-parental-controls` for users
#. not in `@privileged_group@`, and `yes` for users in it.
#. * Set the malcontent `is-user-installation-allowed` property of all
#. non-admins’ parental controls policies to true.
#. * Set the malcontent `is-system-installation-allowed` property of
#. all non-admins’ parental controls policies to false.
#. - In order to configure the policy so that all users (including
#. admins) can install safe software anywhere without authorisation,
#. but need authorisation to install unsafe software anywhere (i.e.
#. applying parental controls to admins too):
#. * Unconditionally return `yes` from `app-install`.
#. * Unconditionally return `auth_admin` from `override-parental-controls`.
#. * Set the malcontent `is-user-installation-allowed` property of all
#. users’ parental controls policies to true.
#. * Set the malcontent `is-system-installation-allowed` property of
#. all users’ parental controls policies to true.
#: system-helper/org.freedesktop.Flatpak.policy.in:287
msgid "Override parental controls for installs"
msgstr "Орнату үшін ата-аналық бақылауды қайта анықтау"

#: system-helper/org.freedesktop.Flatpak.policy.in:288
msgid ""
"Authentication is required to install software which is restricted by your "
"parental controls policy"
msgstr ""
"Ата-аналық бақылау саясатымен шектелген бағдарламалық қамтаманы орнату үшін "
"аутентификация қажет"

#. SECURITY:
#. - This is like org.freedesktop.Flatpak.override-parental-controls, but
#. it’s queried for app updates, whereas the former is queried for app
#. installs.
#. - As with the above action, this one is only queried if
#. org.freedesktop.Flatpak.app-update has allowed the app update, and
#. only if the app being updated has too extreme content for the user
#. who is trying to update it.
#. - The default policy for this is to *allow* updates to ‘too extreme’
#. apps by default, on the basis that having an out-of-date (i.e.
#. insecure or unsupported) app is a worse outcome than automatically
#. installing an update which has radically different content from the
#. version of the app which the parent originally vetted and installed.
#: system-helper/org.freedesktop.Flatpak.policy.in:313
msgid "Override parental controls for updates"
msgstr "Жаңартулар үшін ата-аналық бақылауды қайта анықтау"

#: system-helper/org.freedesktop.Flatpak.policy.in:314
msgid ""
"Authentication is required to update software which is restricted by your "
"parental controls policy"
msgstr ""
"Ата-аналық бақылау саясатымен шектелген бағдарламалық қамтаманы жаңарту үшін "
"аутентификация қажет"

===== ./po/POTFILES.in =====
# List of source files containing translatable strings.
# Please keep this file sorted alphabetically.
app/flatpak-builtins-build-bundle.c
app/flatpak-builtins-build.c
app/flatpak-builtins-build-commit-from.c
app/flatpak-builtins-build-export.c
app/flatpak-builtins-build-finish.c
app/flatpak-builtins-build-import-bundle.c
app/flatpak-builtins-build-init.c
app/flatpak-builtins-build-sign.c
app/flatpak-builtins-build-update-repo.c
app/flatpak-builtins-config.c
app/flatpak-builtins-create-usb.c
app/flatpak-builtins-document-export.c
app/flatpak-builtins-document-info.c
app/flatpak-builtins-document-list.c
app/flatpak-builtins-document-unexport.c
app/flatpak-builtins-enter.c
app/flatpak-builtins-history.c
app/flatpak-builtins-info.c
app/flatpak-builtins-install.c
app/flatpak-builtins-kill.c
app/flatpak-builtins-list.c
app/flatpak-builtins-make-current.c
app/flatpak-builtins-mask.c
app/flatpak-builtins-override.c
app/flatpak-builtins-permission-list.c
app/flatpak-builtins-permission-remove.c
app/flatpak-builtins-permission-reset.c
app/flatpak-builtins-permission-set.c
app/flatpak-builtins-permission-show.c
app/flatpak-builtins-pin.c
app/flatpak-builtins-preinstall.c
app/flatpak-builtins-ps.c
app/flatpak-builtins-remote-add.c
app/flatpak-builtins-remote-delete.c
app/flatpak-builtins-remote-info.c
app/flatpak-builtins-remote-list.c
app/flatpak-builtins-remote-ls.c
app/flatpak-builtins-remote-modify.c
app/flatpak-builtins-repair.c
app/flatpak-builtins-repo.c
app/flatpak-builtins-run.c
app/flatpak-builtins-search.c
app/flatpak-builtins-uninstall.c
app/flatpak-builtins-update.c
app/flatpak-builtins-utils.c
app/flatpak-cli-transaction.c
app/flatpak-main.c
app/flatpak-quiet-transaction.c
app/flatpak-table-printer.c
common/flatpak-auth.c
common/flatpak-context.c
common/flatpak-dir.c
common/flatpak-dir-utils.c
common/flatpak-exports.c
common/flatpak-glib-backports.c
common/flatpak-image-source.c
common/flatpak-installation.c
common/flatpak-instance.c
common/flatpak-oci-registry.c
common/flatpak-progress.c
common/flatpak-ref-utils.c
common/flatpak-remote.c
common/flatpak-repo-utils.c
common/flatpak-run.c
common/flatpak-run-dbus.c
common/flatpak-transaction.c
common/flatpak-uri.c
common/flatpak-usb.c
common/flatpak-utils.c
oci-authenticator/flatpak-oci-authenticator.c
portal/flatpak-portal.c
system-helper/org.freedesktop.Flatpak.policy.in

===== ./po/nl.po =====
# Dutch translation for flatpak.
# Copyright (C) 2023 flatpak's COPYRIGHT HOLDER
# This file is distributed under the same license as the flatpak package.
# Philip Goto <philip.goto@gmail.com>, 2023.
# Nathan Follens <nfollens@gnome.org>, 2023
# Sijmen Schoon <me@sijmenschoon.nl>, 2025
#
msgid ""
msgstr ""
"Project-Id-Version: flatpak main\n"
"Report-Msgid-Bugs-To: https://github.com/flatpak/flatpak/issues\n"
"POT-Creation-Date: 2026-05-27 16:39+0200\n"
"PO-Revision-Date: 2023-04-02 11:48+0200\n"
"Last-Translator: Nathan Follens <nfollens@gnome.org>\n"
"Language-Team: Dutch https://matrix.to/#/#nl:gnome.org\n"
"Language: nl\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Generator: Poedit 3.2.2\n"

#: app/flatpak-builtins-build-bundle.c:59
msgid "Export runtime instead of app"
msgstr "Runtime exporteren in plaats van toepassing"

#: app/flatpak-builtins-build-bundle.c:60
msgid "Arch to bundle for"
msgstr "Architectuur om voor te bundelen"

#: app/flatpak-builtins-build-bundle.c:60
#: app/flatpak-builtins-build-export.c:62 app/flatpak-builtins-build-init.c:53
#: app/flatpak-builtins-build-sign.c:42 app/flatpak-builtins-create-usb.c:46
#: app/flatpak-builtins-info.c:55 app/flatpak-builtins-install.c:67
#: app/flatpak-builtins-list.c:50 app/flatpak-builtins-make-current.c:38
#: app/flatpak-builtins-remote-info.c:54 app/flatpak-builtins-remote-ls.c:56
#: app/flatpak-builtins-run.c:158 app/flatpak-builtins-search.c:37
#: app/flatpak-builtins-uninstall.c:54 app/flatpak-builtins-update.c:56
msgid "ARCH"
msgstr "ARCH"

#: app/flatpak-builtins-build-bundle.c:61
#, fuzzy
msgid "URL for repo"
msgstr "URL voor bron"

#: app/flatpak-builtins-build-bundle.c:61
#: app/flatpak-builtins-build-bundle.c:62
#: app/flatpak-builtins-build-update-repo.c:68
#: app/flatpak-builtins-build-update-repo.c:72
#: app/flatpak-builtins-build-update-repo.c:73
#: app/flatpak-builtins-history.c:69 app/flatpak-builtins-remote-add.c:80
#: app/flatpak-builtins-remote-add.c:81 app/flatpak-builtins-remote-add.c:85
#: app/flatpak-builtins-remote-list.c:53
#: app/flatpak-builtins-remote-modify.c:70
#: app/flatpak-builtins-remote-modify.c:85
#: app/flatpak-builtins-remote-modify.c:86
#: app/flatpak-builtins-remote-modify.c:90
msgid "URL"
msgstr "URL"

#: app/flatpak-builtins-build-bundle.c:62
#, fuzzy
msgid "URL for runtime flatpakrepo file"
msgstr "URL voor runtime-flatpakrepo-bestand"

#: app/flatpak-builtins-build-bundle.c:63
msgid "Add GPG key from FILE (- for stdin)"
msgstr "GPG-sleutel van BESTAND toevoegen (- voor stdin)"

#: app/flatpak-builtins-build-bundle.c:63 app/flatpak-builtins-build.c:54
#: app/flatpak-builtins-build-export.c:67
#: app/flatpak-builtins-build-update-repo.c:83
#: app/flatpak-builtins-install.c:81 app/flatpak-builtins-remote-add.c:84
#: app/flatpak-builtins-remote-add.c:86 app/flatpak-builtins-remote-modify.c:89
#: app/flatpak-builtins-remote-modify.c:92
msgid "FILE"
msgstr "BESTAND"

#: app/flatpak-builtins-build-bundle.c:64
msgid "GPG Key ID to sign the OCI image with"
msgstr "GPG-sleutel-ID om de OCI-image mee te ondertekenen"

#: app/flatpak-builtins-build-bundle.c:64
#: app/flatpak-builtins-build-commit-from.c:68
#: app/flatpak-builtins-build-export.c:68
#: app/flatpak-builtins-build-import-bundle.c:49
#: app/flatpak-builtins-build-sign.c:44
#: app/flatpak-builtins-build-update-repo.c:84
msgid "KEY-ID"
msgstr "SLEUTEL-ID"

#: app/flatpak-builtins-build-bundle.c:65
#: app/flatpak-builtins-build-commit-from.c:69
#: app/flatpak-builtins-build-export.c:71
#: app/flatpak-builtins-build-import-bundle.c:50
#: app/flatpak-builtins-build-sign.c:45
#: app/flatpak-builtins-build-update-repo.c:85
msgid "GPG Homedir to use when looking for keyrings"
msgstr "GPG-thuismap om te gebruiken bij het zoeken naar sleutelbossen"

#: app/flatpak-builtins-build-bundle.c:65
#: app/flatpak-builtins-build-commit-from.c:69
#: app/flatpak-builtins-build-export.c:71
#: app/flatpak-builtins-build-import-bundle.c:50
#: app/flatpak-builtins-build-sign.c:45
#: app/flatpak-builtins-build-update-repo.c:85
msgid "HOMEDIR"
msgstr "THUISMAP"

#: app/flatpak-builtins-build-bundle.c:66
msgid "OSTree commit to create a delta bundle from"
msgstr "OSTree-commit om een deltabundel van te maken"

#: app/flatpak-builtins-build-bundle.c:66 app/flatpak-builtins-remote-info.c:55
#: app/flatpak-builtins-update.c:57
msgid "COMMIT"
msgstr "COMMIT"

#: app/flatpak-builtins-build-bundle.c:67
msgid "Export oci image instead of flatpak bundle"
msgstr "OCI-image exporteren in plaats van Flatpak-bundel"

#: app/flatpak-builtins-build-bundle.c:70
msgid "How to compress OCI image layers (default: gzip)"
msgstr ""

#: app/flatpak-builtins-build-bundle.c:634
msgid ""
"LOCATION FILENAME NAME [BRANCH] - Create a single file bundle from a local "
"repository"
msgstr ""
"LOCATIE BESTANDSNAAM NAAM [BRANCH] - Maak een enkel-bestandsbundel van een "
"lokale pakketbron"

#: app/flatpak-builtins-build-bundle.c:641
msgid "LOCATION, FILENAME and NAME must be specified"
msgstr "LOCATIE, BESTANDSNAAM en NAAM moeten worden opgegeven"

#: app/flatpak-builtins-build-bundle.c:644
#: app/flatpak-builtins-build-export.c:844
#: app/flatpak-builtins-build-import-bundle.c:136
#: app/flatpak-builtins-build-init.c:217 app/flatpak-builtins-build-sign.c:76
#: app/flatpak-builtins-document-export.c:112
#: app/flatpak-builtins-document-info.c:75
#: app/flatpak-builtins-document-list.c:191
#: app/flatpak-builtins-document-unexport.c:70
#: app/flatpak-builtins-history.c:482 app/flatpak-builtins-info.c:130
#: app/flatpak-builtins-install.c:181 app/flatpak-builtins-install.c:234
#: app/flatpak-builtins-install.c:298 app/flatpak-builtins-list.c:419
#: app/flatpak-builtins-make-current.c:72 app/flatpak-builtins-override.c:73
#: app/flatpak-builtins-permission-list.c:162
#: app/flatpak-builtins-permission-remove.c:132
#: app/flatpak-builtins-remote-add.c:323
#: app/flatpak-builtins-remote-delete.c:68
#: app/flatpak-builtins-remote-list.c:241 app/flatpak-builtins-remote-ls.c:407
msgid "Too many arguments"
msgstr "Te veel argumenten"

#: app/flatpak-builtins-build-bundle.c:659
#: app/flatpak-builtins-build-commit-from.c:338
#: app/flatpak-builtins-build-commit-from.c:351
#: app/flatpak-builtins-build-import-bundle.c:145
#, c-format
msgid "'%s' is not a valid repository"
msgstr "‘%s’ is geen geldige pakketbron"

#: app/flatpak-builtins-build-bundle.c:663
#, c-format
msgid "'%s' is not a valid repository: "
msgstr "‘%s’ is geen geldige pakketbron: "

#: app/flatpak-builtins-build-bundle.c:674 app/flatpak-builtins-build-sign.c:88
#: common/flatpak-dir.c:14293
#, c-format
msgid "'%s' is not a valid name: %s"
msgstr "‘%s’ is geen geldige naam: %s"

#: app/flatpak-builtins-build-bundle.c:677
#: app/flatpak-builtins-build-export.c:865 app/flatpak-builtins-build-sign.c:91
#: common/flatpak-dir.c:14299
#, c-format
msgid "'%s' is not a valid branch name: %s"
msgstr "‘%s’ is geen geldige branch-naam: %s"

#: app/flatpak-builtins-build-bundle.c:691
#: app/flatpak-builtins-build-import-bundle.c:149
#: app/flatpak-builtins-build-init.c:281
#, c-format
msgid "'%s' is not a valid filename"
msgstr "‘%s’ is geen geldige bestandsnaam"

#: app/flatpak-builtins-build-bundle.c:706
msgid "--oci-layer-compress value must be gzip or zstd"
msgstr ""

#: app/flatpak-builtins-build.c:49
msgid "Use Platform runtime rather than Sdk"
msgstr "Platform-runtime gebruiken in plaats van SDK"

#: app/flatpak-builtins-build.c:50
msgid "Make destination readonly"
msgstr "Bestemming alleen-lezen maken"

#: app/flatpak-builtins-build.c:51
msgid "Add bind mount"
msgstr "Bindingskoppeling toevoegen"

#: app/flatpak-builtins-build.c:51
msgid "DEST=SRC"
msgstr "BESTEMMING=BRON"

#: app/flatpak-builtins-build.c:52
msgid "Start build in this directory"
msgstr "Compilatie starten in deze map"

#: app/flatpak-builtins-build.c:52 app/flatpak-builtins-build.c:53
#: app/flatpak-builtins-build-init.c:64 app/flatpak-builtins-run.c:160
msgid "DIR"
msgstr "MAP"

#: app/flatpak-builtins-build.c:53
msgid "Where to look for custom sdk dir (defaults to 'usr')"
msgstr "Waar te zoeken naar aangepaste SDK-map (standaard is ‘%s’)"

#: app/flatpak-builtins-build.c:54 app/flatpak-builtins-build-export.c:67
msgid "Use alternative file for the metadata"
msgstr "Alternatief bestand voor metadata gebruiken"

#: app/flatpak-builtins-build.c:55 app/flatpak-builtins-run.c:177
msgid "Kill processes when the parent process dies"
msgstr "Processen beëindigen wanneer het bovenliggende proces is beëindigd"

#: app/flatpak-builtins-build.c:56
msgid "Export application homedir directory to build"
msgstr "Thuismap van toepassing exporteren om te bouwen"

#: app/flatpak-builtins-build.c:57 app/flatpak-builtins-run.c:165
msgid "Log session bus calls"
msgstr "Sessiebusaanroepen bijhouden"

#: app/flatpak-builtins-build.c:58 app/flatpak-builtins-run.c:166
msgid "Log system bus calls"
msgstr "Systeembusaanroepen bijhouden"

#: app/flatpak-builtins-build.c:262
msgid "DIRECTORY [COMMAND [ARGUMENT…]] - Build in directory"
msgstr "MAP [OPDRACHT [ARGUMENT…]] - Bouwen in map"

#: app/flatpak-builtins-build.c:285 app/flatpak-builtins-build-finish.c:656
msgid "DIRECTORY must be specified"
msgstr "MAP moet worden opgegeven"

# Aanhalingstekens toegevoegd ter verduidlijking van opdracht
#: app/flatpak-builtins-build.c:296 app/flatpak-builtins-build-export.c:887
#, c-format
msgid "Build directory %s not initialized, use flatpak build-init"
msgstr "Compilatiemap %s niet geïnitialiseerd, gebruik ‘flatpak build-init’"

#: app/flatpak-builtins-build.c:315
msgid "metadata invalid, not application or runtime"
msgstr "metadata ongeldig, geen toepassing of runtime"

#: app/flatpak-builtins-build.c:446
#, c-format
msgid "No extension point matching %s in %s"
msgstr "Geen uitbreidingspunt overeenkomend met %s in %s"

#: app/flatpak-builtins-build.c:635
#, c-format
msgid "Missing '=' in bind mount option '%s'"
msgstr "Ontbrekende ‘=’ in bindingskoppelingsoptie ‘%s’"

#: app/flatpak-builtins-build.c:679 common/flatpak-run.c:3961
#, c-format
msgid "Unable to start app"
msgstr "Kon toepassing niet starten"

# Deze en onderstaande items zijn moeilijk te vertalen, misschien wordt later een betere vertaling duidelijk.  - Philip
#: app/flatpak-builtins-build-commit-from.c:58
msgid "Source repo dir"
msgstr "Map van source-pakketbron"

#: app/flatpak-builtins-build-commit-from.c:58
msgid "SRC-REPO"
msgstr "SRC-PAKKETBRON"

#: app/flatpak-builtins-build-commit-from.c:59
msgid "Source repo ref"
msgstr "Ref van source-pakketbron"

#: app/flatpak-builtins-build-commit-from.c:59
msgid "SRC-REF"
msgstr "SRC-REF"

#: app/flatpak-builtins-build-commit-from.c:64
#: app/flatpak-builtins-build-export.c:60
msgid "One line subject"
msgstr "Onderwerp op enkele regel"

#: app/flatpak-builtins-build-commit-from.c:64
#: app/flatpak-builtins-build-export.c:60
msgid "SUBJECT"
msgstr "ONDERWERP"

#: app/flatpak-builtins-build-commit-from.c:65
#: app/flatpak-builtins-build-export.c:61
msgid "Full description"
msgstr "Volledige omschrijving"

#: app/flatpak-builtins-build-commit-from.c:65
#: app/flatpak-builtins-build-export.c:61
msgid "BODY"
msgstr "BODY"

#: app/flatpak-builtins-build-commit-from.c:66
#: app/flatpak-builtins-build-export.c:64
#: app/flatpak-builtins-build-import-bundle.c:51
msgid "Update the appstream branch"
msgstr "Appstream-branch bijwerken"

#: app/flatpak-builtins-build-commit-from.c:67
#: app/flatpak-builtins-build-export.c:65
#: app/flatpak-builtins-build-import-bundle.c:52
#: app/flatpak-builtins-build-update-repo.c:87
msgid "Don't update the summary"
msgstr "Samenvatting niet bijwerken"

#: app/flatpak-builtins-build-commit-from.c:68
#: app/flatpak-builtins-build-export.c:68
#: app/flatpak-builtins-build-import-bundle.c:49
#: app/flatpak-builtins-build-sign.c:44
msgid "GPG Key ID to sign the commit with"
msgstr "GPG-sleutel-ID om de commit mee te ondertekenen"

#: app/flatpak-builtins-build-commit-from.c:70
#: app/flatpak-builtins-build-export.c:73
msgid "Mark build as end-of-life"
msgstr "Pakket markeren als end-of-life"

#: app/flatpak-builtins-build-commit-from.c:70
#: app/flatpak-builtins-build-export.c:73
msgid "REASON"
msgstr "REDEN"

#: app/flatpak-builtins-build-commit-from.c:71
msgid ""
"Mark refs matching the OLDID prefix as end-of-life, to be replaced with the "
"given NEWID"
msgstr ""
"Refs overeenkomend met de OUDE-ID markeren als end-of-life, om te worden "
"vervangen met de opgegeven NIEUWE-ID"

#: app/flatpak-builtins-build-commit-from.c:71
msgid "OLDID=NEWID"
msgstr "OUDE-ID=NIEUWE-ID"

#: app/flatpak-builtins-build-commit-from.c:72
#: app/flatpak-builtins-build-export.c:75
msgid "Set type of token needed to install this commit"
msgstr "Benodigd tokentype voor het installeren van deze commit instellen"

#: app/flatpak-builtins-build-commit-from.c:72
#: app/flatpak-builtins-build-export.c:75
msgid "VAL"
msgstr "WAARDE"

#: app/flatpak-builtins-build-commit-from.c:73
msgid "Override the timestamp of the commit (NOW for current time)"
msgstr "Tijdstempel van de commit overschrijven (NOW voor huidige tijd)"

#: app/flatpak-builtins-build-commit-from.c:73
#: app/flatpak-builtins-build-export.c:76
msgid "TIMESTAMP"
msgstr "TIJDSTEMPEL"

#: app/flatpak-builtins-build-commit-from.c:75
#: app/flatpak-builtins-build-export.c:80
#: app/flatpak-builtins-build-import-bundle.c:53
#: app/flatpak-builtins-build-update-repo.c:97
msgid "Don't generate a summary index"
msgstr "Geen samenvattingsindex genereren"

#: app/flatpak-builtins-build-commit-from.c:278
msgid "DST-REPO [DST-REF…] - Make a new commit from existing commits"
msgstr ""
"DST-PAKKETBRON [DST-REF…] - Nieuwe commit aanmaken van bestaande commits"

#: app/flatpak-builtins-build-commit-from.c:285
msgid "DST-REPO must be specified"
msgstr "DST-PAKKETBRON moet worden opgegeven"

#: app/flatpak-builtins-build-commit-from.c:293
msgid ""
"If --src-repo is not specified, exactly one destination ref must be specified"
msgstr ""
"Indien --src-repo niet is opgegeven, moet exact één bestemmings-ref worden "
"opgegeven"

#: app/flatpak-builtins-build-commit-from.c:296
msgid ""
"If --src-ref is specified, exactly one destination ref must be specified"
msgstr ""
"Indien --src-ref is opgegeven, moet exact één bestemmings-ref worden "
"opgegeven"

#: app/flatpak-builtins-build-commit-from.c:299
msgid "Either --src-repo or --src-ref must be specified"
msgstr "--src-repo of --src-ref moet worden opgegeven"

#: app/flatpak-builtins-build-commit-from.c:315
msgid "Invalid argument format of use  --end-of-life-rebase=OLDID=NEWID"
msgstr "Ongeldig argumentformaat in --end-of-life-rebase=OUDE-ID=NIEUWE-ID"

#: app/flatpak-builtins-build-commit-from.c:321
#: app/flatpak-builtins-build-commit-from.c:324
#, c-format
msgid "Invalid name %s in --end-of-life-rebase"
msgstr "Ongeldige naam %s in --end-of-life-rebase"

#: app/flatpak-builtins-build-commit-from.c:333
#: app/flatpak-builtins-build-export.c:1092
#, c-format
msgid "Could not parse '%s'"
msgstr "Kon ‘%s’ niet parsen"

#: app/flatpak-builtins-build-commit-from.c:498
msgid "Can't commit from partial source commit"
msgstr "Kan niet committen van gedeeltelijke bron-commit"

#: app/flatpak-builtins-build-commit-from.c:503
#, c-format
msgid "%s: no change\n"
msgstr "%s: geen wijzigingen\n"

#: app/flatpak-builtins-build-export.c:62
msgid "Architecture to export for (must be host compatible)"
msgstr "Architectuur om voor te exporteren (moet compatibel zijn met host)"

#: app/flatpak-builtins-build-export.c:63
msgid "Commit runtime (/usr), not /app"
msgstr "Runtime (/usr) committen, niet /app"

#: app/flatpak-builtins-build-export.c:66
msgid "Use alternative directory for the files"
msgstr "Alternatieve map voor de bestanden gebruiken"

#: app/flatpak-builtins-build-export.c:66
msgid "SUBDIR"
msgstr "SUBMAP"

#: app/flatpak-builtins-build-export.c:69
msgid "Files to exclude"
msgstr "Bestanden om uit te sluiten"

#: app/flatpak-builtins-build-export.c:69
#: app/flatpak-builtins-build-export.c:70
#: app/flatpak-builtins-build-update-repo.c:90
msgid "PATTERN"
msgstr "PATROON"

#: app/flatpak-builtins-build-export.c:70
msgid "Excluded files to include"
msgstr "Uitgesloten bestanden om toe te voegen"

#: app/flatpak-builtins-build-export.c:74
msgid "Mark build as end-of-life, to be replaced with the given ID"
msgstr ""
"Pakket als end-of-life markeren, om te worden vervangen met de opgegeven ID"

#: app/flatpak-builtins-build-export.c:74
#: app/flatpak-builtins-document-list.c:49 app/flatpak-cli-transaction.c:1427
msgid "ID"
msgstr "ID"

#: app/flatpak-builtins-build-export.c:76
msgid "Override the timestamp of the commit"
msgstr "Tijdstempel van de commit overschrijven"

#: app/flatpak-builtins-build-export.c:77
#: app/flatpak-builtins-build-update-repo.c:75
#: app/flatpak-builtins-remote-add.c:83 app/flatpak-builtins-remote-list.c:54
#: app/flatpak-builtins-remote-modify.c:88
msgid "Collection ID"
msgstr "Verzamelings-ID"

#: app/flatpak-builtins-build-export.c:472
#, c-format
msgid "WARNING: Error running desktop-file-validate: %s\n"
msgstr "WAARSCHUWING: Fout bij uitvoeren van desktop-file-validate: %s\n"

#: app/flatpak-builtins-build-export.c:480
#, c-format
msgid "WARNING: Error reading from desktop-file-validate: %s\n"
msgstr "WAARSCHUWING: Fout bij lezen van desktop-file-validate: %s\n"

#: app/flatpak-builtins-build-export.c:486
#, c-format
msgid "WARNING: Failed to validate desktop file %s: %s\n"
msgstr "WAARSCHUWING: Desktop-bestand %s valideren mislukt: %s\n"

#: app/flatpak-builtins-build-export.c:513
#, c-format
msgid "WARNING: Can't find Exec key in %s: %s\n"
msgstr "WAARSCHUWING: Kan Exec-sleutel in %s niet vinden: %s\n"

#: app/flatpak-builtins-build-export.c:521
#: app/flatpak-builtins-build-export.c:614
#, c-format
msgid "WARNING: Binary not found for Exec line in %s: %s\n"
msgstr ""
"WAARSCHUWING: Programmabestand voor Exec-regel in %s niet gevonden: %s\n"

#: app/flatpak-builtins-build-export.c:529
#, c-format
msgid "WARNING: Icon not matching app id in %s: %s\n"
msgstr ""
"WAARSCHUWING: Pictogram komt niet overeen met toepassings-ID in %s: %s\n"

#: app/flatpak-builtins-build-export.c:552
#, c-format
msgid "WARNING: Icon referenced in desktop file but not exported: %s\n"
msgstr ""
"WAARSCHUWING: Pictogram benoemd in desktop-bestand maar niet geëxporteerd: "
"%s\n"

#: app/flatpak-builtins-build-export.c:719
#, c-format
msgid "Invalid uri type %s, only http/https supported"
msgstr "Ongeldig URI-type %s, enkel http/https worden ondersteund"

#: app/flatpak-builtins-build-export.c:737
#, c-format
msgid "Unable to find basename in %s, specify a name explicitly"
msgstr "Kon basisnaam in %s niet vinden, geef een naam expliciet op"

#: app/flatpak-builtins-build-export.c:746
#, c-format
msgid "No slashes allowed in extra data name"
msgstr "Geen slashes toegestaan in naam van extra gegevens"

#: app/flatpak-builtins-build-export.c:758
#, c-format
msgid "Invalid format for sha256 checksum: '%s'"
msgstr "Ongeldig formaat voor SHA256-controlesom: ‘%s’"

#: app/flatpak-builtins-build-export.c:768
#, c-format
msgid "Extra data sizes of zero not supported"
msgstr "Extra-gegevensgroottes van nul niet ondersteund"

#: app/flatpak-builtins-build-export.c:830
msgid ""
"LOCATION DIRECTORY [BRANCH] - Create a repository from a build directory"
msgstr "LOCATIE MAP [BRANCH] - Pakketbron aanmaken vanuit een compilatiemap"

#: app/flatpak-builtins-build-export.c:838
msgid "LOCATION and DIRECTORY must be specified"
msgstr "LOCATIE en MAP moeten worden opgegeven"

#: app/flatpak-builtins-build-export.c:859
#: app/flatpak-builtins-remote-add.c:327
#, c-format
msgid "‘%s’ is not a valid collection ID: %s"
msgstr "‘%s’ is geen geldige verzamelings-ID: %s"

#: app/flatpak-builtins-build-export.c:904
#: app/flatpak-builtins-build-finish.c:684
msgid "No name specified in the metadata"
msgstr "Geen naam opgegeven in de metagegevens"

#: app/flatpak-builtins-build-export.c:1166
#, c-format
msgid "Commit: %s\n"
msgstr "Commit: %s\n"

#: app/flatpak-builtins-build-export.c:1167
#, c-format
msgid "Metadata Total: %u\n"
msgstr "Metagegevens (totaal): %u\n"

#: app/flatpak-builtins-build-export.c:1168
#, c-format
msgid "Metadata Written: %u\n"
msgstr "Metagegevens (geschreven): %u\n"

#: app/flatpak-builtins-build-export.c:1169
#, c-format
msgid "Content Total: %u\n"
msgstr "Inhoud (totaal): %u\n"

#: app/flatpak-builtins-build-export.c:1170
#, c-format
msgid "Content Written: %u\n"
msgstr "Inhoud (geschreven): %u\n"

#: app/flatpak-builtins-build-export.c:1171
#, c-format
msgid "Content Bytes Written:"
msgstr "Inhoud (geschreven bytes):"

#: app/flatpak-builtins-build-finish.c:52
msgid "Command to set"
msgstr "Opdracht om in te stellen"

#: app/flatpak-builtins-build-finish.c:52 app/flatpak-builtins-run.c:159
#: app/flatpak-main.c:209
msgid "COMMAND"
msgstr "OPDRACHT"

#: app/flatpak-builtins-build-finish.c:53
msgid "Flatpak version to require"
msgstr "Vereiste flatpak-versie"

#: app/flatpak-builtins-build-finish.c:53
msgid "MAJOR.MINOR.MICRO"
msgstr "MAJOR.MINOR.MICRO"

#: app/flatpak-builtins-build-finish.c:54
msgid "Don't process exports"
msgstr "Exports niet verwerken"

#: app/flatpak-builtins-build-finish.c:55
msgid "Extra data info"
msgstr "Extra gegevensinfo"

#: app/flatpak-builtins-build-finish.c:56 app/flatpak-builtins-build-init.c:63
msgid "Add extension point info"
msgstr "Uitbreidingspuntinfo toevoegen"

#: app/flatpak-builtins-build-finish.c:56 app/flatpak-builtins-build-init.c:63
msgid "NAME=VARIABLE[=VALUE]"
msgstr "NAAM=VARIABELE[=WAARDE]"

#: app/flatpak-builtins-build-finish.c:57
msgid "Remove extension point info"
msgstr "Uitbreidingspuntinfo verwijderen"

#: app/flatpak-builtins-build-finish.c:57
#: app/flatpak-builtins-build-update-repo.c:79 app/flatpak-builtins-info.c:58
#: app/flatpak-builtins-remote-add.c:88 app/flatpak-builtins-remote-modify.c:94
#: app/flatpak-main.c:182
msgid "NAME"
msgstr "NAAM"

#: app/flatpak-builtins-build-finish.c:58
msgid "Set extension priority (only for extensions)"
msgstr "Uitbreidingsprioriteit instellen (enkel voor uitbreidingen)"

#: app/flatpak-builtins-build-finish.c:58
msgid "VALUE"
msgstr "WAARDE"

#: app/flatpak-builtins-build-finish.c:59
msgid "Change the sdk used for the app"
msgstr "SDK gebruikt door toepassing wijzigen"

#: app/flatpak-builtins-build-finish.c:59
msgid "SDK"
msgstr "SDK"

#: app/flatpak-builtins-build-finish.c:60
msgid "Change the runtime used for the app"
msgstr "Runtime gebruikt door toepassing wijzigen"

#: app/flatpak-builtins-build-finish.c:60 app/flatpak-builtins-build-init.c:54
#: app/flatpak-builtins-list.c:53 app/flatpak-builtins-remote-ls.c:58
#: app/flatpak-builtins-run.c:163
msgid "RUNTIME"
msgstr "RUNTIME"

#: app/flatpak-builtins-build-finish.c:61
msgid "Set generic metadata option"
msgstr "Algemene metagegevensoptie instellen"

#: app/flatpak-builtins-build-finish.c:61
msgid "GROUP=KEY[=VALUE]"
msgstr "GROEP=SLEUTEL[=WAARDE]"

#: app/flatpak-builtins-build-finish.c:62
msgid "Don't inherit permissions from runtime"
msgstr "Rechten niet overnemen van runtime"

#: app/flatpak-builtins-build-finish.c:155
#, c-format
msgid "Not exporting %s, wrong extension\n"
msgstr "%s wordt niet geëxporteerd, verkeerde extensie\n"

#: app/flatpak-builtins-build-finish.c:163
#, c-format
msgid "Not exporting %s, non-allowed export filename\n"
msgstr "%s wordt niet geëxporteerd, exportbestandsnaam niet toegestaan\n"

#: app/flatpak-builtins-build-finish.c:167
#, c-format
msgid "Exporting %s\n"
msgstr "%s exporteren\n"

#: app/flatpak-builtins-build-finish.c:440
#, c-format
msgid "More than one executable found\n"
msgstr "Meer dan één uitvoerbaar bestand gevonden\n"

#: app/flatpak-builtins-build-finish.c:451
#, c-format
msgid "Using %s as command\n"
msgstr "%s wordt als opdracht gebruikt\n"

#: app/flatpak-builtins-build-finish.c:456
#, c-format
msgid "No executable found\n"
msgstr "Geen uitvoerbaar bestand gevonden\n"

#: app/flatpak-builtins-build-finish.c:511
#, c-format
msgid "Invalid --require-version argument: %s"
msgstr "Ongeldig argument voor --require-version: %s"

#: app/flatpak-builtins-build-finish.c:543
#, c-format
msgid "Too few elements in --extra-data argument %s"
msgstr "Te weinig elementen in argument %s van --extra-data"

#: app/flatpak-builtins-build-finish.c:575
#, c-format
msgid ""
"Too few elements in --metadata argument %s, format should be "
"GROUP=KEY[=VALUE]]"
msgstr ""
"Te weinig elementen in argument %s van --metadata, formaat moet "
"GROEP=SLEUTEL[=WAARDE]] zijn"

#: app/flatpak-builtins-build-finish.c:597
#: app/flatpak-builtins-build-init.c:458
#, c-format
msgid ""
"Too few elements in --extension argument %s, format should be "
"NAME=VAR[=VALUE]"
msgstr ""
"Te weinig elementen in argument %s van --extension, formaat moet "
"NAAM=VAR[=WAARDE] zijn"

#: app/flatpak-builtins-build-finish.c:603
#: app/flatpak-builtins-build-init.c:461
#, c-format
msgid "Invalid extension name %s"
msgstr "Ongeldige uitbreidingsnaam %s"

#: app/flatpak-builtins-build-finish.c:646
msgid "DIRECTORY - Finalize a build directory"
msgstr "MAP - Compilatiemap afronden"

#: app/flatpak-builtins-build-finish.c:668
#, c-format
msgid "Build directory %s not initialized"
msgstr "Compilatiemap %s niet geïnitialiseerd"

#: app/flatpak-builtins-build-finish.c:689
#, c-format
msgid "Build directory %s already finalized"
msgstr "Compilatiemap %s al afgerond"

#: app/flatpak-builtins-build-finish.c:702
#, c-format
msgid "Please review the exported files and the metadata\n"
msgstr "Controleer de geëxporteerde bestanden en metagegevens\n"

#: app/flatpak-builtins-build-import-bundle.c:47
msgid "Override the ref used for the imported bundle"
msgstr "Ref gebruikt voor geïmporteerde bundel overschrijven"

#: app/flatpak-builtins-build-import-bundle.c:47
msgid "REF"
msgstr "REF"

#: app/flatpak-builtins-build-import-bundle.c:48
msgid "Import oci image instead of flatpak bundle"
msgstr "OCI-image importeren in plaats van de Flatpak-bundel"

#: app/flatpak-builtins-build-import-bundle.c:77
#: app/flatpak-builtins-build-import-bundle.c:105
#, c-format
msgid "Importing %s (%s)\n"
msgstr "%s importeren (%s)\n"

#: app/flatpak-builtins-build-import-bundle.c:126
msgid "LOCATION FILENAME - Import a file bundle into a local repository"
msgstr ""
"LOCATIE BESTANDSNAAM - Bestandsbundel importeren naar een locale pakketbron"

#: app/flatpak-builtins-build-import-bundle.c:133
msgid "LOCATION and FILENAME must be specified"
msgstr "LOCATIE en BESTANDSNAAM moeten worden opgegeven"

#: app/flatpak-builtins-build-init.c:53 app/flatpak-builtins-info.c:55
#: app/flatpak-builtins-run.c:158
msgid "Arch to use"
msgstr "Architectuur om te gebruiken"

#: app/flatpak-builtins-build-init.c:54
msgid "Initialize var from named runtime"
msgstr "Var initialiseren vanuit opgegeven runtime"

#: app/flatpak-builtins-build-init.c:55
msgid "Initialize apps from named app"
msgstr "Toepassingen initialiseren vanuit opgegeven toepassing"

#: app/flatpak-builtins-build-init.c:55
msgid "APP"
msgstr "TOEPASSING"

#: app/flatpak-builtins-build-init.c:56
msgid "Specify version for --base"
msgstr "Versie voor --base opgeven"

#: app/flatpak-builtins-build-init.c:56 app/flatpak-builtins-run.c:164
msgid "VERSION"
msgstr "VERSIE"

#: app/flatpak-builtins-build-init.c:57
msgid "Include this base extension"
msgstr "Basisuitbreiding toevoegen"

#: app/flatpak-builtins-build-init.c:57 app/flatpak-builtins-build-init.c:62
msgid "EXTENSION"
msgstr "UITBREIDING"

#: app/flatpak-builtins-build-init.c:58
msgid "Extension tag to use if building extension"
msgstr "Uitbreidings-tag om te gebruiken bij het bouwen van uitbreiding"

#: app/flatpak-builtins-build-init.c:58
msgid "EXTENSION_TAG"
msgstr "UITBREIDINGS-TAG"

#: app/flatpak-builtins-build-init.c:59
msgid "Initialize /usr with a writable copy of the sdk"
msgstr "/usr initialiseren met een overschrijfbare kopie van de SDK"

#: app/flatpak-builtins-build-init.c:60
msgid "Specify the build type (app, runtime, extension)"
msgstr "Compilatietype specificeren (toepassing, runtime, uitbreiding)"

#: app/flatpak-builtins-build-init.c:60
msgid "TYPE"
msgstr "TYPE"

#: app/flatpak-builtins-build-init.c:61
msgid "Add a tag"
msgstr "Tag toevoegen"

#: app/flatpak-builtins-build-init.c:61
msgid "TAG"
msgstr "TAG"

#: app/flatpak-builtins-build-init.c:62
msgid "Include this sdk extension in /usr"
msgstr "Deze SDK-uitbreiding aan /usr toevoegen"

#: app/flatpak-builtins-build-init.c:64
msgid "Where to store sdk (defaults to 'usr')"
msgstr "Waar de SDK moet worden opgeslagen (standaard: ‘usr’)"

#: app/flatpak-builtins-build-init.c:65
msgid "Re-initialize the sdk/var"
msgstr "SDK/var herinitialiseren"

#: app/flatpak-builtins-build-init.c:118
#, c-format
msgid "Requested extension %s/%s/%s is only partially installed"
msgstr "Opgevraagde uitbreiding %s/%s/%s is enkel deels geïnstalleerd"

#: app/flatpak-builtins-build-init.c:147
#, c-format
msgid "Requested extension %s/%s/%s not installed"
msgstr "Opgevraagde uitbreiding %s/%s/%s is niet geïnstalleerd"

#: app/flatpak-builtins-build-init.c:207
msgid ""
"DIRECTORY APPNAME SDK RUNTIME [BRANCH] - Initialize a directory for building"
msgstr ""
"MAP TOEPASSINGSNAAM SDK RUNTIME [BRANCH] - Map initialiseren voor compilatie"

#: app/flatpak-builtins-build-init.c:214
msgid "RUNTIME must be specified"
msgstr "RUNTIME moet worden opgegeven"

#: app/flatpak-builtins-build-init.c:235
#, c-format
msgid "'%s' is not a valid build type name, use app, runtime or extension"
msgstr "‘%s’ is geen geldig compilatietype, gebruik app, runtime of extension"

#: app/flatpak-builtins-build-init.c:241 app/flatpak-builtins-override.c:79
#, c-format
msgid "'%s' is not a valid application name: %s"
msgstr "‘%s’ is geen geldige toepassingsnaam: %s"

#: app/flatpak-builtins-build-init.c:295
#, c-format
msgid "Build directory %s already initialized"
msgstr "Compilatiemap %s is al geïnitialiseerd"

#: app/flatpak-builtins-build-sign.c:42 app/flatpak-builtins-install.c:67
#: app/flatpak-builtins-remote-info.c:54
msgid "Arch to install for"
msgstr "Architectuur om voor te installeren"

#: app/flatpak-builtins-build-sign.c:43 app/flatpak-builtins-create-usb.c:48
#: app/flatpak-builtins-install.c:74 app/flatpak-builtins-remote-info.c:56
#: app/flatpak-builtins-uninstall.c:58 app/flatpak-builtins-update.c:64
msgid "Look for runtime with the specified name"
msgstr "Zoeken naar runtime met de opgegeven naam"

#: app/flatpak-builtins-build-sign.c:66
msgid "LOCATION [ID [BRANCH]] - Sign an application or runtime"
msgstr "LOCATIE [ID [BRANCH]] - Toepassing of runtime ondertekenen"

#: app/flatpak-builtins-build-sign.c:73
#: app/flatpak-builtins-build-update-repo.c:499
#: app/flatpak-builtins-remote-add.c:320 app/flatpak-builtins-repo.c:739
msgid "LOCATION must be specified"
msgstr "LOCATIE moet worden opgegeven"

#: app/flatpak-builtins-build-sign.c:94
msgid "No gpg key ids specified"
msgstr "Geen GPG-sleutel-ID’s opgegeven"

#: app/flatpak-builtins-build-update-repo.c:68
msgid "Redirect this repo to a new URL"
msgstr "Deze pakketbron doorverwijzen naar een nieuwe URL"

#: app/flatpak-builtins-build-update-repo.c:69
msgid "A nice name to use for this repository"
msgstr "Naam om te gebruiken voor deze pakketbron"

#: app/flatpak-builtins-build-update-repo.c:69
#: app/flatpak-builtins-remote-add.c:77 app/flatpak-builtins-remote-modify.c:82
msgid "TITLE"
msgstr "TITEL"

#: app/flatpak-builtins-build-update-repo.c:70
msgid "A one-line comment for this repository"
msgstr "Opmerking van enkele regel voor deze pakketbron"

#: app/flatpak-builtins-build-update-repo.c:70
#: app/flatpak-builtins-remote-add.c:78 app/flatpak-builtins-remote-modify.c:83
msgid "COMMENT"
msgstr "OPMERKING"

#: app/flatpak-builtins-build-update-repo.c:71
msgid "A full-paragraph description for this repository"
msgstr "Alinea als omschrijving voor deze pakketbron"

#: app/flatpak-builtins-build-update-repo.c:71
#: app/flatpak-builtins-remote-add.c:79 app/flatpak-builtins-remote-modify.c:84
msgid "DESCRIPTION"
msgstr "OMSCHRIJVING"

#: app/flatpak-builtins-build-update-repo.c:72
msgid "URL for a website for this repository"
msgstr "URL van website voor deze pakketbron"

#: app/flatpak-builtins-build-update-repo.c:73
msgid "URL for an icon for this repository"
msgstr "URL van pictogram voor deze pakketbron"

#: app/flatpak-builtins-build-update-repo.c:74
msgid "Default branch to use for this repository"
msgstr "Standaard-branch om te gebruiken voor deze pakketbron"

#: app/flatpak-builtins-build-update-repo.c:74
#: app/flatpak-builtins-remote-add.c:82 app/flatpak-builtins-remote-modify.c:87
#: app/flatpak-builtins-repo.c:713 app/flatpak-builtins-repo.c:714
#: app/flatpak-builtins-run.c:161
msgid "BRANCH"
msgstr "BRANCH"

#: app/flatpak-builtins-build-update-repo.c:75
#: app/flatpak-builtins-remote-add.c:83 app/flatpak-builtins-remote-modify.c:88
msgid "COLLECTION-ID"
msgstr "VERZAMELINGS-ID"

#. Translators: A sideload is when you install from a local USB drive rather than the Internet.
#: app/flatpak-builtins-build-update-repo.c:77
msgid ""
"Permanently deploy collection ID to client remote configurations, only for "
"sideload support"
msgstr ""
"Collectie-ID permanent uitrollen naar remote-configuraties van "
"clients.Alleen voor ondersteuning voor sideloaden"

#: app/flatpak-builtins-build-update-repo.c:78
msgid "Permanently deploy collection ID to client remote configurations"
msgstr "Collectie-ID permanent uitrollen naar remote-configuraties van clients"

#: app/flatpak-builtins-build-update-repo.c:79
msgid "Name of authenticator for this repository"
msgstr "Naam van authenticator voor deze pakketbron"

#: app/flatpak-builtins-build-update-repo.c:80
msgid "Autoinstall authenticator for this repository"
msgstr "Authenticator automatisch installeren voor deze pakketbron"

#: app/flatpak-builtins-build-update-repo.c:81
msgid "Don't autoinstall authenticator for this repository"
msgstr "Authenticator niet automatisch installeren voor deze pakketbron"

#: app/flatpak-builtins-build-update-repo.c:82
#: app/flatpak-builtins-remote-add.c:89
msgid "Authenticator option"
msgstr "Authenticator-optie"

#: app/flatpak-builtins-build-update-repo.c:82
#: app/flatpak-builtins-remote-add.c:89 app/flatpak-builtins-remote-modify.c:95
msgid "KEY=VALUE"
msgstr "SLEUTEL=WAARDE"

#: app/flatpak-builtins-build-update-repo.c:83
msgid "Import new default GPG public key from FILE"
msgstr "Nieuwe publieke GPG-standaardsleutel importeren vanuit BESTAND"

#: app/flatpak-builtins-build-update-repo.c:84
msgid "GPG Key ID to sign the summary with"
msgstr "GPG-sleutel-ID om de samenvatting mee te ondertekenen"

#: app/flatpak-builtins-build-update-repo.c:86
msgid "Generate delta files"
msgstr "Deltabestanden genereren"

#: app/flatpak-builtins-build-update-repo.c:88
msgid "Don't update the appstream branch"
msgstr "Appstream-branch niet bijwerken"

#: app/flatpak-builtins-build-update-repo.c:89
msgid "Max parallel jobs when creating deltas (default: NUMCPUs)"
msgstr ""
"Maximum aantal gelijktijdige taken bij het maken van delta’s (standaard: "
"NUMCPUs)"

#: app/flatpak-builtins-build-update-repo.c:89
msgid "NUM-JOBS"
msgstr "AANTAL-TAKEN"

#: app/flatpak-builtins-build-update-repo.c:90
msgid "Don't create deltas matching refs"
msgstr "Geen delta’s overeenkomstig met refs aanmaken"

#: app/flatpak-builtins-build-update-repo.c:91
msgid "Prune unused objects"
msgstr "Ongebruikte objecten opruimen"

#: app/flatpak-builtins-build-update-repo.c:92
msgid "Prune but don't actually remove anything"
msgstr "Opruimen maar niets echt verwijderen"

#: app/flatpak-builtins-build-update-repo.c:93
msgid "Only traverse DEPTH parents for each commit (default: -1=infinite)"
msgstr ""
"Enkel DIEPTE aantal bovenliggende items voor elke commit doorlopen "
"(standaard: -1=infinite)"

#: app/flatpak-builtins-build-update-repo.c:93
msgid "DEPTH"
msgstr "DIEPTE"

#: app/flatpak-builtins-build-update-repo.c:223
#, c-format
msgid "Generating delta: %s (%.10s)\n"
msgstr "Delta genereren: %s (%.10s)\n"

#: app/flatpak-builtins-build-update-repo.c:225
#, c-format
msgid "Generating delta: %s (%.10s-%.10s)\n"
msgstr "Delta genereren: %s (%.10s-%.10s)\n"

#: app/flatpak-builtins-build-update-repo.c:233
#, c-format
msgid "Failed to generate delta %s (%.10s): "
msgstr "Delta genereren mislukt %s (%.10s): "

#: app/flatpak-builtins-build-update-repo.c:236
#, c-format
msgid "Failed to generate delta %s (%.10s-%.10s): "
msgstr "Delta genereren mislukt %s (%.10s-%.10s): "

#: app/flatpak-builtins-build-update-repo.c:492
msgid "LOCATION - Update repository metadata"
msgstr "LOCATIE - Metagegevens van pakketbron bijwerken"

#: app/flatpak-builtins-build-update-repo.c:609
#, c-format
msgid "Updating appstream branch\n"
msgstr "Appstream-branch bijwerken\n"

#: app/flatpak-builtins-build-update-repo.c:638
#, c-format
msgid "Updating summary\n"
msgstr "Samenvatting bijwerken\n"

#: app/flatpak-builtins-build-update-repo.c:664
#, c-format
msgid "Total objects: %u\n"
msgstr "Totaal aantal objecten: %u\n"

#: app/flatpak-builtins-build-update-repo.c:666
#, c-format
msgid "No unreachable objects\n"
msgstr "Geen onbereikbare objecten\n"

#: app/flatpak-builtins-build-update-repo.c:668
#, c-format
msgid "Deleted %u objects, %s freed\n"
msgstr "%u objecten verwijderd, %s vrijgemaakt\n"

#: app/flatpak-builtins-config.c:41
msgid "List configuration keys and values"
msgstr "Configuratiesleutels en -waarden opsommen"

#: app/flatpak-builtins-config.c:42
msgid "Get configuration for KEY"
msgstr "Configuratie voor SLEUTEL ophalen"

#: app/flatpak-builtins-config.c:43
msgid "Set configuration for KEY to VALUE"
msgstr "Configuratie voor SLEUTEL instellen op WAARDE"

#: app/flatpak-builtins-config.c:44
msgid "Unset configuration for KEY"
msgstr "Configuratie verwijderen voor SLEUTEL"

#: app/flatpak-builtins-config.c:149
#, c-format
msgid "'%s' does not look like a language/locale code"
msgstr "‘%s’ is geen taal-/regiocode"

#: app/flatpak-builtins-config.c:172
#, c-format
msgid "'%s' does not look like a language code"
msgstr "‘%s’ is geen taalcode"

#: app/flatpak-builtins-config.c:190
#, fuzzy, c-format
msgid "'%s' is not a valid value (use 'true' or 'false')"
msgstr "‘%s’ is geen geldige pakketbron: "

#: app/flatpak-builtins-config.c:262
#, c-format
msgid "Unknown configure key '%s'"
msgstr "Onbekende configuratiesleutel ‘%s’"

#: app/flatpak-builtins-config.c:284
msgid "Too many arguments for --list"
msgstr "Te veel argumenten voor --list"

#: app/flatpak-builtins-config.c:314 app/flatpak-builtins-config.c:362
msgid "You must specify KEY"
msgstr "SLEUTEL moet worden opgegeven"

#: app/flatpak-builtins-config.c:316
msgid "Too many arguments for --get"
msgstr "Te veel argumenten voor --get"

#: app/flatpak-builtins-config.c:338
msgid "You must specify KEY and VALUE"
msgstr "SLEUTEL en WAARDE moeten worden opgegeven"

#: app/flatpak-builtins-config.c:340
msgid "Too many arguments for --set"
msgstr "Te veel argumenten voor --set"

#: app/flatpak-builtins-config.c:364
msgid "Too many arguments for --unset"
msgstr "Te veel argumenten voor --unset"

#: app/flatpak-builtins-config.c:383
msgid "[KEY [VALUE]] - Manage configuration"
msgstr "[SLEUTEL [WAARDE]] - Configuratie beheren"

#: app/flatpak-builtins-config.c:394
msgid "Can only use one of --list, --get, --set or --unset"
msgstr ""
"Kan enkel één van de volgende argumenten gebruiken: --list, --get, --set, --"
"unset"

#: app/flatpak-builtins-config.c:408
msgid "Must specify one of --list, --get, --set or --unset"
msgstr ""
"Eén van de volgende argumenten moet worden opgegeven: --list, --get, --set, "
"--unset"

#: app/flatpak-builtins-create-usb.c:45 app/flatpak-builtins-install.c:75
#: app/flatpak-builtins-remote-info.c:57 app/flatpak-builtins-uninstall.c:59
#: app/flatpak-builtins-update.c:65
msgid "Look for app with the specified name"
msgstr "Zoeken naar toepassing met de opgegeven naam"

#: app/flatpak-builtins-create-usb.c:46
msgid "Arch to copy"
msgstr "Architectuur om te kopiëren"

#: app/flatpak-builtins-create-usb.c:47
msgid "DEST"
msgstr "DOEL"

#: app/flatpak-builtins-create-usb.c:49
msgid "Allow partial commits in the created repo"
msgstr "Gedeeltelijke commits in de aangemaakte pakketbron toestaan"

#: app/flatpak-builtins-create-usb.c:125 app/flatpak-builtins-create-usb.c:165
#, c-format
msgid ""
"Warning: Related ref ‘%s’ is partially installed. Use --allow-partial to "
"suppress this message.\n"
msgstr ""
"Waarschuwing: De verwante ref ‘%s’ is gedeeltelijk geïnstalleerd. Gebruik --"
"allow-partial om dit bericht te onderdrukken.\n"

#: app/flatpak-builtins-create-usb.c:158
#, c-format
msgid "Warning: Omitting related ref ‘%s’ because it is not installed.\n"
msgstr ""
"Waarschuwing: De verwante ref ‘%s’ wordt overgeslagen omdat deze niet is "
"geïnstalleerd.\n"

#: app/flatpak-builtins-create-usb.c:175
#, c-format
msgid ""
"Warning: Omitting related ref ‘%s’ because its remote ‘%s’ does not have a "
"collection ID set.\n"
msgstr ""
"Waarschuwing: De verwante referentie ‘%s’ wordt overgeslagen omdat de remote "
"‘%s’ geen collectie-ID heeft ingesteld.\n"

#: app/flatpak-builtins-create-usb.c:187
#, c-format
msgid "Warning: Omitting related ref ‘%s’ because it's extra-data.\n"
msgstr ""
"Waarschuwing: De verwante ref ‘%s’ wordt overgeslagen omdat het om extra-"
"data gaat.\n"

#: app/flatpak-builtins-create-usb.c:262 app/flatpak-builtins-create-usb.c:637
#, c-format
msgid ""
"Remote ‘%s’ does not have a collection ID set, which is required for P2P "
"distribution of ‘%s’."
msgstr ""
"De remote ‘%s’ heeft geen ingestelde collectie-ID, wat vereist is voor P2P-"
"distributie van ‘%s’."

#: app/flatpak-builtins-create-usb.c:272
#, c-format
msgid "Warning: Omitting ref ‘%s’ (runtime of ‘%s’) because it's extra-data.\n"
msgstr ""
"Waarschuwing: De ref ‘%s’ (runtime van ‘%s’) wordt overgeslagen omdat het om "
"extra-data gaat.\n"

#: app/flatpak-builtins-create-usb.c:484
msgid "MOUNT-PATH [REF…] - Copy apps or runtimes onto removable media"
msgstr ""
"AANKOPPELPAD [REF…] - Kopieer apps of runtimes naar verwijderbare media"

#: app/flatpak-builtins-create-usb.c:493
msgid "MOUNT-PATH and REF must be specified"
msgstr "AANKOPPELPAD en REF moeten worden opgegeven"

#: app/flatpak-builtins-create-usb.c:607
#, c-format
msgid "Ref ‘%s’ found in multiple installations: %s. You must specify one."
msgstr ""
"De ref ‘%s’ is gevonden in meerdere installaties: %s. Er moet er één "
"gespecificeerd worden."

#: app/flatpak-builtins-create-usb.c:620
#, c-format
msgid "Refs must all be in the same installation (found in %s and %s)."
msgstr ""
"Alle refs moeten zich in dezelfde installatie bevinden (gevonden in %s en "
"%s)."

#: app/flatpak-builtins-create-usb.c:670
#, c-format
msgid ""
"Warning: Ref ‘%s’ is partially installed. Use --allow-partial to suppress "
"this message.\n"
msgstr ""
"Waarschuwing: De ref ‘%s’ is gedeeltelijk geïnstalleerd. Gebruik --allow-"
"partial om dit bericht te onderdrukken.\n"

#: app/flatpak-builtins-create-usb.c:681
#, c-format
msgid "Installed ref ‘%s’ is extra-data, and cannot be distributed offline"
msgstr ""
"De geïnstalleerde ref ‘%s’ is extra-data, en kan niet offline worden "
"gedistribueerd"

#: app/flatpak-builtins-create-usb.c:721
#, c-format
msgid "Warning: Couldn't update repo metadata for remote ‘%s’: %s\n"
msgstr ""
"Waarschuwing: Kon pakketbron-metadata niet bijwerken voor remote ‘%s’: %s\n"

#: app/flatpak-builtins-create-usb.c:751
#, c-format
msgid "Warning: Couldn't update appstream data for remote ‘%s’ arch ‘%s’: %s\n"
msgstr ""
"Waarschuwing: Kon appstream-data niet bijwerken voor remote ‘%s’, arch ‘%s’: "
"%s\n"

#. Print a warning if both appstream and appstream2 are missing
#: app/flatpak-builtins-create-usb.c:784
#, c-format
msgid ""
"Warning: Couldn't find appstream data for remote ‘%s’ arch ‘%s’: %s; %s\n"
msgstr ""
"Waarschuwing: Kon appstream-data niet vinden voor remote ‘%s’, arch ‘%s’: "
"%s\n"

#. Appstream2 is only for efficiency, so just print a debug message
#: app/flatpak-builtins-create-usb.c:790
#, c-format
msgid "Couldn't find appstream2 data for remote ‘%s’ arch ‘%s’: %s\n"
msgstr ""
"Waarschuwing: Kon appstream2-data niet vinden voor remote ‘%s’, arch ‘%s’: "
"%s\n"

#: app/flatpak-builtins-document-export.c:62
msgid "Create a unique document reference"
msgstr "Een unieke documentreferentie aanmaken"

#: app/flatpak-builtins-document-export.c:63
msgid "Make the document transient for the current session"
msgstr "Dit document transiënt maken voor de huidige sessie"

#: app/flatpak-builtins-document-export.c:64
msgid "Don't require the file to exist already"
msgstr "Vereis niet dat het bestand al bestaat"

#: app/flatpak-builtins-document-export.c:65
msgid "Give the app read permissions"
msgstr "Leesrechten aan de toepassing verlenen"

#: app/flatpak-builtins-document-export.c:66
msgid "Give the app write permissions"
msgstr "Schrijfrechten aan de toepassing verlenen"

#: app/flatpak-builtins-document-export.c:67
msgid "Give the app delete permissions"
msgstr "Verwijderingsrechten aan de toepassing verlenen"

#: app/flatpak-builtins-document-export.c:68
msgid "Give the app permissions to grant further permissions"
msgstr "Rechten aan de toepassing verlenen om meer rechten te verlenen"

#: app/flatpak-builtins-document-export.c:69
msgid "Revoke read permissions of the app"
msgstr "Leesrechten van de toepassing intrekken"

#: app/flatpak-builtins-document-export.c:70
msgid "Revoke write permissions of the app"
msgstr "Schrijfrechten van de toepassing intrekken"

#: app/flatpak-builtins-document-export.c:71
msgid "Revoke delete permissions of the app"
msgstr "Verwijderingsrechten van de toepassing intrekken"

#: app/flatpak-builtins-document-export.c:72
msgid "Revoke the permission to grant further permissions"
msgstr "Rechten van de toepassing intrekken om meer rechten te verlenen"

#: app/flatpak-builtins-document-export.c:73
msgid "Add permissions for this app"
msgstr "Rechten voor deze toepassing toevoegen"

#: app/flatpak-builtins-document-export.c:73
msgid "APPID"
msgstr "APPID"

#: app/flatpak-builtins-document-export.c:100
msgid "FILE - Export a file to apps"
msgstr "BESTAND - Bestand exporteren naar toepassingen"

#: app/flatpak-builtins-document-export.c:109
#: app/flatpak-builtins-document-info.c:72
#: app/flatpak-builtins-document-unexport.c:67
msgid "FILE must be specified"
msgstr "BESTAND moet worden opgegeven"

#: app/flatpak-builtins-document-info.c:63
msgid "FILE - Get information about an exported file"
msgstr "BESTAND - Informatie verkrijgen over een geëxporteerd bestand"

#: app/flatpak-builtins-document-info.c:100
#: app/flatpak-builtins-document-unexport.c:94
#, c-format
msgid "Not exported\n"
msgstr "Niet geëxporteerd\n"

#: app/flatpak-builtins-document-list.c:43 app/flatpak-builtins-history.c:53
#: app/flatpak-builtins-list.c:54 app/flatpak-builtins-ps.c:43
#: app/flatpak-builtins-remote-list.c:45 app/flatpak-builtins-remote-ls.c:59
#: app/flatpak-builtins-search.c:38
msgid "What information to show"
msgstr "Welke informatie te tonen"

#: app/flatpak-builtins-document-list.c:43 app/flatpak-builtins-history.c:53
#: app/flatpak-builtins-list.c:54 app/flatpak-builtins-ps.c:43
#: app/flatpak-builtins-remote-list.c:45 app/flatpak-builtins-remote-ls.c:59
#: app/flatpak-builtins-search.c:38
msgid "FIELD,…"
msgstr "VELD,…"

#: app/flatpak-builtins-document-list.c:44 app/flatpak-builtins-history.c:54
#: app/flatpak-builtins-list.c:52 app/flatpak-builtins-permission-list.c:43
#: app/flatpak-builtins-permission-show.c:43 app/flatpak-builtins-ps.c:44
#: app/flatpak-builtins-remote-list.c:46 app/flatpak-builtins-remote-ls.c:63
#: app/flatpak-builtins-repo.c:717 app/flatpak-builtins-search.c:39
#, fuzzy
msgid "Show output in JSON format"
msgstr "Extra informatie tonen"

#: app/flatpak-builtins-document-list.c:49
msgid "Show the document ID"
msgstr "Document-ID tonen"

#: app/flatpak-builtins-document-list.c:50
msgid "Path"
msgstr "Pad"

#: app/flatpak-builtins-document-list.c:50
#: app/flatpak-builtins-document-list.c:51
msgid "Show the document path"
msgstr "Documentpad tonen"

#: app/flatpak-builtins-document-list.c:51 app/flatpak-builtins-list.c:66
#: app/flatpak-builtins-remote-ls.c:74
msgid "Origin"
msgstr "Herkomst"

#: app/flatpak-builtins-document-list.c:52 app/flatpak-builtins-history.c:62
#: app/flatpak-builtins-ps.c:52
msgid "Application"
msgstr "Toepassing"

#: app/flatpak-builtins-document-list.c:52
msgid "Show applications with permission"
msgstr "Toepassingen met toestemming tonen"

#: app/flatpak-builtins-document-list.c:53
#: app/flatpak-builtins-permission-list.c:182
#: app/flatpak-builtins-permission-show.c:145
msgid "Permissions"
msgstr "Rechten"

#: app/flatpak-builtins-document-list.c:53
msgid "Show permissions for applications"
msgstr "Rechten voor toepassingen tonen"

#: app/flatpak-builtins-document-list.c:161
#, fuzzy, c-format
msgid "No documents found\n"
msgstr "Geen overeenkomsten gevonden"

#: app/flatpak-builtins-document-list.c:180
msgid "[APPID] - List exported files"
msgstr "[TOEPASINGS-ID] - Geëxporteerde bestanden opsommen"

#: app/flatpak-builtins-document-unexport.c:43
msgid "Specify the document ID"
msgstr "Geef de document-ID op"

#: app/flatpak-builtins-document-unexport.c:58
msgid "FILE - Unexport a file to apps"
msgstr "BESTAND - Bestand niet meer exporteren naar toepassingen"

#: app/flatpak-builtins-enter.c:88
msgid "INSTANCE COMMAND [ARGUMENT…] - Run a command inside a running sandbox"
msgstr ""
"INSTANTIE OPDRACHT [ARGUMENT…] - Opdracht uitvoeren in een draaiende zandbak"

#: app/flatpak-builtins-enter.c:111
msgid "INSTANCE and COMMAND must be specified"
msgstr "INSTANTIE en OPDRACHT moeten worden opgegeven"

#: app/flatpak-builtins-enter.c:138
#, c-format
msgid "%s is neither a pid nor an application or instance ID"
msgstr "%s is geen PID noch toepassings- of instantie-ID"

#: app/flatpak-builtins-enter.c:144
msgid "entering not supported (need unprivileged user namespaces, or sudo -E)"
msgstr ""
"Betreden niet ondersteund (onbevoorrechte gebruikers-namespaces benodigd, of "
"sudo -E)"

#: app/flatpak-builtins-enter.c:145
#, c-format
msgid "No such pid %s"
msgstr "PID %s bestaat niet"

#: app/flatpak-builtins-enter.c:158
msgid "Can't read cwd"
msgstr "Kan cwd niet lezen"

#: app/flatpak-builtins-enter.c:163
msgid "Can't read root"
msgstr "Kan root niet lezen"

#: app/flatpak-builtins-enter.c:191
#, c-format
msgid "Invalid %s namespace for pid %d"
msgstr "Ongeldige %s-namespace voor PID %d"

# Wat is hier een goede vertaling voor self?  - Philip
#: app/flatpak-builtins-enter.c:202
#, c-format
msgid "Invalid %s namespace for self"
msgstr "Ongeldige %s-namespace"

#: app/flatpak-builtins-enter.c:216
#, c-format
msgid "Can't open %s namespace: %s"
msgstr "Kan %s-namespace niet openen: %s"

#: app/flatpak-builtins-enter.c:226
msgid "entering not supported (need unprivileged user namespaces)"
msgstr ""
"Betreden niet ondersteund (onbevoorrechte gebruikers-namespaces benodigd)"

#: app/flatpak-builtins-enter.c:227
#, c-format
msgid "Can't enter %s namespace: %s"
msgstr "Kan %s-namespace niet betreden: %s"

#: app/flatpak-builtins-enter.c:234
msgid "Can't chdir"
msgstr "Kan chdir niet uitvoeren"

#: app/flatpak-builtins-enter.c:237
msgid "Can't chroot"
msgstr "Kan chroot niet uitvoeren"

#: app/flatpak-builtins-enter.c:240
msgid "Can't switch gid"
msgstr "Kan GID niet wisselen"

#: app/flatpak-builtins-enter.c:243
msgid "Can't switch uid"
msgstr "Kan UID niet wisselen"

#: app/flatpak-builtins-history.c:50
msgid "Only show changes after TIME"
msgstr "Enkel wijzigingen na TIJD tonen"

#: app/flatpak-builtins-history.c:50 app/flatpak-builtins-history.c:51
msgid "TIME"
msgstr "TIJD"

#: app/flatpak-builtins-history.c:51
msgid "Only show changes before TIME"
msgstr "Enkel wijzigingen voor TIJD tonen"

#: app/flatpak-builtins-history.c:52
msgid "Show newest entries first"
msgstr "Nieuwste items eerst tonen"

#: app/flatpak-builtins-history.c:59
msgid "Time"
msgstr "Tijd"

#: app/flatpak-builtins-history.c:59
msgid "Show when the change happened"
msgstr "Wijzigingsmoment tonen"

#: app/flatpak-builtins-history.c:60
msgid "Change"
msgstr "Wijzigen"

#: app/flatpak-builtins-history.c:60
msgid "Show the kind of change"
msgstr "Wijzigingstype tonen"

#: app/flatpak-builtins-history.c:61 app/flatpak-builtins-list.c:68
#: app/flatpak-builtins-remote-ls.c:75 app/flatpak-builtins-repo.c:335
msgid "Ref"
msgstr "Red"

#: app/flatpak-builtins-history.c:61 app/flatpak-builtins-list.c:68
#: app/flatpak-builtins-remote-ls.c:75
msgid "Show the ref"
msgstr "Ref tonen"

#: app/flatpak-builtins-history.c:62
msgid "Show the application/runtime ID"
msgstr "Toepassings-/runtime-ID tonen"

#: app/flatpak-builtins-history.c:63 app/flatpak-builtins-list.c:64
#: app/flatpak-builtins-ps.c:53 app/flatpak-builtins-remote-ls.c:73
#: app/flatpak-cli-transaction.c:1435
msgid "Arch"
msgstr "Arch"

#: app/flatpak-builtins-history.c:63 app/flatpak-builtins-list.c:64
#: app/flatpak-builtins-ps.c:53 app/flatpak-builtins-remote-ls.c:73
msgid "Show the architecture"
msgstr "Architectuur tonen"

#: app/flatpak-builtins-history.c:64 app/flatpak-builtins-list.c:63
#: app/flatpak-builtins-ps.c:54 app/flatpak-builtins-remote-ls.c:72
#: app/flatpak-builtins-search.c:48 app/flatpak-cli-transaction.c:1438
msgid "Branch"
msgstr "Branch"

#: app/flatpak-builtins-history.c:64 app/flatpak-builtins-list.c:63
#: app/flatpak-builtins-remote-ls.c:72
msgid "Show the branch"
msgstr "Branch tonen"

#: app/flatpak-builtins-history.c:65 app/flatpak-builtins-list.c:67
msgid "Installation"
msgstr "Installatie"

#: app/flatpak-builtins-history.c:65
msgid "Show the affected installation"
msgstr "Installatie tonen"

#: app/flatpak-builtins-history.c:66 app/flatpak-cli-transaction.c:1452
msgid "Remote"
msgstr "Remote"

#: app/flatpak-builtins-history.c:66
msgid "Show the remote"
msgstr "Remote tonen"

#: app/flatpak-builtins-history.c:67 app/flatpak-builtins-ps.c:55
#: app/flatpak-builtins-remote-ls.c:76
msgid "Commit"
msgstr "Commit"

#: app/flatpak-builtins-history.c:67
msgid "Show the current commit"
msgstr "Huidige commit tonen"

#: app/flatpak-builtins-history.c:68
msgid "Old Commit"
msgstr "Oude commit"

#: app/flatpak-builtins-history.c:68
msgid "Show the previous commit"
msgstr "Vorige commit tonen"

#: app/flatpak-builtins-history.c:69
msgid "Show the remote URL"
msgstr "Remote-URL tonen"

#: app/flatpak-builtins-history.c:70 app/flatpak-cli-transaction.c:700
msgid "User"
msgstr "Gebruiker"

#: app/flatpak-builtins-history.c:70
msgid "Show the user doing the change"
msgstr "Gebruiker verantwoordelijk voor wijziging tonen"

#: app/flatpak-builtins-history.c:71
msgid "Tool"
msgstr "Gereedschap"

#: app/flatpak-builtins-history.c:71
msgid "Show the tool that was used"
msgstr "Gebruikt gereedschap tonen"

#: app/flatpak-builtins-history.c:72 app/flatpak-builtins-list.c:62
#: app/flatpak-builtins-remote-ls.c:71 app/flatpak-builtins-search.c:47
msgid "Version"
msgstr "Versie"

#: app/flatpak-builtins-history.c:72
msgid "Show the Flatpak version"
msgstr "Flatpak-versie tonen"

#: app/flatpak-builtins-history.c:91
#, c-format
msgid "Failed to get journal data (%s): %s"
msgstr "Logboekgegevens (%s) verkrijgen mislukt: %s"

#: app/flatpak-builtins-history.c:146
#, c-format
msgid "Failed to open journal: %s"
msgstr "Logboek openen mislukt: %s"

#: app/flatpak-builtins-history.c:153
#, c-format
msgid "Failed to add match to journal: %s"
msgstr "Overeenkomst aan logboek toevoegen mislukt: %s"

#: app/flatpak-builtins-history.c:471
msgid " - Show history"
msgstr " - Geschiedenis tonen"

#: app/flatpak-builtins-history.c:490
#, c-format
msgid "Failed to parse the --since option"
msgstr "Optie --since parsen mislukt"

#: app/flatpak-builtins-history.c:501
#, c-format
msgid "Failed to parse the --until option"
msgstr "Optie --until parsen mislukt"

#: app/flatpak-builtins-info.c:56
msgid "Show user installations"
msgstr "Gebruikersinstallaties tonen"

#: app/flatpak-builtins-info.c:57
msgid "Show system-wide installations"
msgstr "Systeembrede installaties tonen"

#: app/flatpak-builtins-info.c:58
msgid "Show specific system-wide installations"
msgstr "Specifieke systeembrede installaties tonen"

#: app/flatpak-builtins-info.c:59 app/flatpak-builtins-remote-info.c:59
msgid "Show ref"
msgstr "Ref tonen"

#: app/flatpak-builtins-info.c:60 app/flatpak-builtins-remote-info.c:60
msgid "Show commit"
msgstr "Commit tonen"

#: app/flatpak-builtins-info.c:61
msgid "Show origin"
msgstr "Oorsprong tonen"

#: app/flatpak-builtins-info.c:62
msgid "Show size"
msgstr "Grootte tonen"

#: app/flatpak-builtins-info.c:63 app/flatpak-builtins-remote-info.c:62
msgid "Show metadata"
msgstr "Metagegevens tonen"

#: app/flatpak-builtins-info.c:64 app/flatpak-builtins-remote-info.c:63
msgid "Show runtime"
msgstr "Runtime tonen"

#: app/flatpak-builtins-info.c:65 app/flatpak-builtins-remote-info.c:64
msgid "Show sdk"
msgstr "SDK tonen"

#: app/flatpak-builtins-info.c:66
msgid "Show permissions"
msgstr "Rechten tonen"

#: app/flatpak-builtins-info.c:67
msgid "Query file access"
msgstr "Bestandstoegang opvragen"

#: app/flatpak-builtins-info.c:67 app/flatpak-builtins-install.c:82
#: app/flatpak-builtins-install.c:88 app/flatpak-builtins-preinstall.c:68
#: app/flatpak-builtins-run.c:182 app/flatpak-builtins-run.c:184
#: app/flatpak-builtins-update.c:67 app/flatpak-builtins-update.c:71
msgid "PATH"
msgstr "PAD"

#: app/flatpak-builtins-info.c:68
msgid "Show extensions"
msgstr "Uitbreidingen tonen"

#: app/flatpak-builtins-info.c:69
msgid "Show location"
msgstr "Locatie tonen"

#: app/flatpak-builtins-info.c:116
msgid "NAME [BRANCH] - Get info about an installed app or runtime"
msgstr ""
"NAAM [BRANCH] - Info over een geïnstalleerde toepassing of runtime verkrijgen"

#: app/flatpak-builtins-info.c:123 app/flatpak-builtins-remote-add.c:317
#: app/flatpak-builtins-remote-delete.c:63
msgid "NAME must be specified"
msgstr "Naam moet worden opgegeven"

#: app/flatpak-builtins-info.c:196
msgid "ref not present in origin"
msgstr "Ref niet aanwezig in oorsprong"

#: app/flatpak-builtins-info.c:211 app/flatpak-builtins-remote-info.c:217
#, c-format
msgid "Warning: Commit has no flatpak metadata\n"
msgstr "Waarchuwing: Commit heeft geen Flatpak-metadata\n"

#: app/flatpak-builtins-info.c:217 app/flatpak-builtins-info.c:259
#: app/flatpak-builtins-info.c:455 app/flatpak-builtins-info.c:513
#: app/flatpak-builtins-remote-info.c:236
#: app/flatpak-builtins-remote-info.c:271
msgid "ID:"
msgstr "ID:"

#: app/flatpak-builtins-info.c:218 app/flatpak-builtins-info.c:260
#: app/flatpak-builtins-remote-info.c:237
#: app/flatpak-builtins-remote-info.c:272
msgid "Ref:"
msgstr "Ref:"

#: app/flatpak-builtins-info.c:219 app/flatpak-builtins-info.c:261
#: app/flatpak-builtins-remote-info.c:238
#: app/flatpak-builtins-remote-info.c:273
msgid "Arch:"
msgstr "Arch:"

#: app/flatpak-builtins-info.c:220 app/flatpak-builtins-info.c:262
#: app/flatpak-builtins-remote-info.c:239
#: app/flatpak-builtins-remote-info.c:274
msgid "Branch:"
msgstr "Branch:"

#: app/flatpak-builtins-info.c:222 app/flatpak-builtins-info.c:264
#: app/flatpak-builtins-remote-info.c:241
#: app/flatpak-builtins-remote-info.c:276
msgid "Version:"
msgstr "Versie:"

#: app/flatpak-builtins-info.c:224 app/flatpak-builtins-info.c:266
#: app/flatpak-builtins-remote-info.c:243
#: app/flatpak-builtins-remote-info.c:278
msgid "License:"
msgstr "Licentie:"

#: app/flatpak-builtins-info.c:226 app/flatpak-builtins-info.c:269
#: app/flatpak-builtins-remote-info.c:245
#: app/flatpak-builtins-remote-info.c:280
msgid "Collection:"
msgstr "Verzameling:"

#: app/flatpak-builtins-info.c:227 app/flatpak-builtins-info.c:270
#: app/flatpak-builtins-info.c:458 app/flatpak-builtins-info.c:516
msgid "Installation:"
msgstr "Installatie:"

#: app/flatpak-builtins-info.c:228 app/flatpak-builtins-info.c:271
#: app/flatpak-builtins-info.c:459 app/flatpak-builtins-info.c:517
#: app/flatpak-builtins-remote-info.c:249
#: app/flatpak-builtins-remote-info.c:284
#, fuzzy
msgid "Installed Size:"
msgstr "Geïnstalleerde grootte"

#: app/flatpak-builtins-info.c:231 app/flatpak-builtins-info.c:279
#: app/flatpak-builtins-remote-info.c:252
#: app/flatpak-builtins-remote-info.c:288
msgid "Runtime:"
msgstr "Runtime:"

#: app/flatpak-builtins-info.c:232 app/flatpak-builtins-info.c:288
#: app/flatpak-builtins-remote-info.c:253
#: app/flatpak-builtins-remote-info.c:293
msgid "Sdk:"
msgstr "SDK:"

#: app/flatpak-builtins-info.c:235 app/flatpak-builtins-info.c:313
#: app/flatpak-builtins-remote-info.c:256
#: app/flatpak-builtins-remote-info.c:319
msgid "Date:"
msgstr "Datum:"

#: app/flatpak-builtins-info.c:237 app/flatpak-builtins-info.c:311
#: app/flatpak-builtins-remote-info.c:258
#: app/flatpak-builtins-remote-info.c:317
msgid "Subject:"
msgstr "Onderwerp:"

#: app/flatpak-builtins-info.c:240 app/flatpak-builtins-info.c:295
msgid "Active commit:"
msgstr "Actieve commit:"

#: app/flatpak-builtins-info.c:241 app/flatpak-builtins-info.c:298
msgid "Latest commit:"
msgstr "Laatste commit:"

#: app/flatpak-builtins-info.c:244 app/flatpak-builtins-info.c:303
#: app/flatpak-builtins-info.c:457 app/flatpak-builtins-info.c:515
#: app/flatpak-builtins-remote-info.c:259
#: app/flatpak-builtins-remote-info.c:298
msgid "Commit:"
msgstr "Commit:"

#: app/flatpak-builtins-info.c:246 app/flatpak-builtins-info.c:308
#: app/flatpak-builtins-remote-info.c:261
#: app/flatpak-builtins-remote-info.c:303
msgid "Parent:"
msgstr "Bovenliggend:"

#: app/flatpak-builtins-info.c:248 app/flatpak-builtins-info.c:321
msgid "Alt-id:"
msgstr "Alt-id:"

#: app/flatpak-builtins-info.c:250 app/flatpak-builtins-info.c:325
#: app/flatpak-builtins-remote-info.c:263
#: app/flatpak-builtins-remote-info.c:308
msgid "End-of-life:"
msgstr "End-of-life:"

#: app/flatpak-builtins-info.c:252 app/flatpak-builtins-info.c:330
#: app/flatpak-builtins-remote-info.c:265
#: app/flatpak-builtins-remote-info.c:313
msgid "End-of-life-rebase:"
msgstr "End-of-life-rebase:"

#: app/flatpak-builtins-info.c:254 app/flatpak-builtins-info.c:317
msgid "Subdirectories:"
msgstr "Submappen:"

#: app/flatpak-builtins-info.c:255 app/flatpak-builtins-info.c:454
#: app/flatpak-builtins-info.c:512
msgid "Extension:"
msgstr "Uitbreiding:"

#: app/flatpak-builtins-info.c:267 app/flatpak-builtins-info.c:456
#: app/flatpak-builtins-info.c:514
msgid "Origin:"
msgstr "Herkomst:"

#: app/flatpak-builtins-info.c:460 app/flatpak-builtins-info.c:522
msgid "Subpaths:"
msgstr "Subpaden:"

#: app/flatpak-builtins-info.c:478
msgid "unmaintained"
msgstr "onbeheerd"

#: app/flatpak-builtins-info.c:480 app/flatpak-builtins-info.c:482
msgid "unknown"
msgstr "onbekend"

#: app/flatpak-builtins-install.c:68 app/flatpak-builtins-preinstall.c:57
msgid "Don't pull, only install from local cache"
msgstr "Niet ophalen, alleen installeren vanaf lokale cache"

#: app/flatpak-builtins-install.c:69 app/flatpak-builtins-preinstall.c:58
#: app/flatpak-builtins-update.c:60
msgid "Don't deploy, only download to local cache"
msgstr "Niet deployen, alleen downloaden naar lokale cache"

#: app/flatpak-builtins-install.c:70 app/flatpak-builtins-preinstall.c:59
msgid "Don't install related refs"
msgstr "Verwante refs niet installeren"

#: app/flatpak-builtins-install.c:71 app/flatpak-builtins-preinstall.c:60
#: app/flatpak-builtins-update.c:62
msgid "Don't verify/install runtime dependencies"
msgstr "Runtime-afhankelijkheden niet verifiëren/installeren"

#: app/flatpak-builtins-install.c:72
msgid "Don't automatically pin explicit installs"
msgstr "Expliciete installaties niet automatisch vastpinnen"

#: app/flatpak-builtins-install.c:73 app/flatpak-builtins-preinstall.c:61
#: app/flatpak-builtins-update.c:63
msgid "Don't use static deltas"
msgstr "Geen statische delta’s gebruiken"

#: app/flatpak-builtins-install.c:76 app/flatpak-builtins-preinstall.c:62
msgid "Additionally install the SDK used to build the given refs"
msgstr "Installeer ook de SDK die is gebruikt om de opgegeven refs te bouwen"

#: app/flatpak-builtins-install.c:77 app/flatpak-builtins-preinstall.c:63
msgid ""
"Additionally install the debug info for the given refs and their dependencies"
msgstr ""
"Installeer ook de debug-info voor de gegeven refs en hun afhankelijkheden"

#: app/flatpak-builtins-install.c:78
msgid "Assume LOCATION is a .flatpak single-file bundle"
msgstr "Neem aan dat LOCATIE een .flatpak-single-file-bundel is"

#: app/flatpak-builtins-install.c:79
msgid "Assume LOCATION is a .flatpakref application description"
msgstr "Neem aan dat LOCATIE een .flatpakref-toepassingsbeschrijving is"

#: app/flatpak-builtins-install.c:80
msgid "Assume LOCATION is containers-transports(5) reference to an OCI image"
msgstr ""

#: app/flatpak-builtins-install.c:81
msgid "Check bundle signatures with GPG key from FILE (- for stdin)"
msgstr ""
"Controleer bundelhandtekeningen met de GPG-sleutel uit BESTAND (- voor stdin)"

#: app/flatpak-builtins-install.c:82
msgid "Only install this subpath"
msgstr "Enkel dit subpad installeren"

#: app/flatpak-builtins-install.c:83 app/flatpak-builtins-preinstall.c:64
#: app/flatpak-builtins-uninstall.c:63 app/flatpak-builtins-update.c:68
msgid "Automatically answer yes for all questions"
msgstr "Alle vragen automatisch beantwoorden met ja"

#: app/flatpak-builtins-install.c:84 app/flatpak-builtins-preinstall.c:65
msgid "Uninstall first if already installed"
msgstr "Eerst verwijderen indien reeds geïnstalleerd"

#: app/flatpak-builtins-install.c:85 app/flatpak-builtins-preinstall.c:66
#: app/flatpak-builtins-uninstall.c:64 app/flatpak-builtins-update.c:69
msgid "Produce minimal output and don't ask questions"
msgstr "Minimale uitvoer produceren en geen vragen stellen"

#: app/flatpak-builtins-install.c:86
msgid "Update install if already installed"
msgstr "Installatie bijwerken indien reeds geïnstalleerd"

#. Translators: A sideload is when you install from a local USB drive rather than the Internet.
#: app/flatpak-builtins-install.c:88 app/flatpak-builtins-preinstall.c:68
#: app/flatpak-builtins-update.c:71
msgid "Use this local repo for sideloads"
msgstr "Gebruik deze lokale pakketbron voor sideloads"

#: app/flatpak-builtins-install.c:178
msgid "Bundle filename must be specified"
msgstr "Bundelbestandsnaam moet worden gespecificeerd"

#: app/flatpak-builtins-install.c:188
msgid "Remote bundles are not supported"
msgstr "Remotebundels zijn niet ondersteund"

#: app/flatpak-builtins-install.c:231
msgid "Filename or uri must be specified"
msgstr "Bestandsnaam of URI moet worden opgegeven"

#: app/flatpak-builtins-install.c:295
#, fuzzy
msgid "Image location must be specified"
msgstr "Ten minste één REF moet worden gespecificeerd"

#: app/flatpak-builtins-install.c:345
msgid "[LOCATION/REMOTE] [REF…] - Install applications or runtimes"
msgstr "[LOCATIE/REMOTE] [REF…] - Installeer toepassingen of runtimes"

#: app/flatpak-builtins-install.c:378
msgid "At least one REF must be specified"
msgstr "Ten minste één REF moet worden gespecificeerd"

#: app/flatpak-builtins-install.c:392
#, c-format
msgid "Looking for matches…\n"
msgstr "Zoeken naar overeenkomsten…\n"

#: app/flatpak-builtins-install.c:513
#, c-format
msgid "No remote refs found for ‘%s’"
msgstr "Geen externe refs gevonden voor ‘%s’"

#: app/flatpak-builtins-install.c:573 app/flatpak-builtins-uninstall.c:405
#: common/flatpak-ref-utils.c:689 common/flatpak-ref-utils.c:1595
#, c-format
msgid "Invalid branch %s: %s"
msgstr "Ongeldige branch %s: %s"

#: app/flatpak-builtins-install.c:606
#, c-format
msgid "Nothing matches %s in local repository for remote %s"
msgstr "Geen overeenkomsten met %s in lokale pakketbron voor remote %s"

#: app/flatpak-builtins-install.c:608
#, c-format
msgid "Nothing matches %s in remote %s"
msgstr "Geen overeenkomsten met %s in remote %s"

#: app/flatpak-builtins-install.c:629
#, c-format
msgid "Skipping: %s\n"
msgstr "%s overgeslagen\n"

#: app/flatpak-builtins-kill.c:110
#, c-format
msgid "%s is not running"
msgstr "%s draait niet"

#: app/flatpak-builtins-kill.c:136
msgid "INSTANCE - Stop a running application"
msgstr "INSTANTIE - Draaiende toepassing stoppen"

#: app/flatpak-builtins-kill.c:144 app/flatpak-builtins-ps.c:256
msgid "Extra arguments given"
msgstr "Extra argumenten meegegeven"

#: app/flatpak-builtins-kill.c:150
msgid "Must specify the app to kill"
msgstr "Toepassing om te stoppen moet worden opgegeven"

#: app/flatpak-builtins-list.c:47
msgid "Show extra information"
msgstr "Extra informatie tonen"

#: app/flatpak-builtins-list.c:48
msgid "List installed runtimes"
msgstr "Geïnstalleerde runtimes opsommen"

#: app/flatpak-builtins-list.c:49
msgid "List installed applications"
msgstr "Geïnstalleerde toepassingen opsommen"

#: app/flatpak-builtins-list.c:50
msgid "Arch to show"
msgstr "Architectuur om te tonen"

#: app/flatpak-builtins-list.c:51 app/flatpak-builtins-remote-ls.c:57
msgid "List all refs (including locale/debug)"
msgstr "Alle refs opsommen (inclusief locale/debug)"

#: app/flatpak-builtins-list.c:53 app/flatpak-builtins-remote-ls.c:58
msgid "List all applications using RUNTIME"
msgstr "Alle toepassingen die RUNTIME gebruiken opsommen"

#: app/flatpak-builtins-list.c:59 app/flatpak-builtins-remote-list.c:51
#: app/flatpak-builtins-remote-ls.c:68 app/flatpak-builtins-search.c:44
msgid "Name"
msgstr "Naam"

#: app/flatpak-builtins-list.c:59 app/flatpak-builtins-remote-list.c:51
#: app/flatpak-builtins-remote-ls.c:68 app/flatpak-builtins-search.c:44
msgid "Show the name"
msgstr "Naam tonen"

#: app/flatpak-builtins-list.c:60 app/flatpak-builtins-remote-list.c:60
#: app/flatpak-builtins-remote-ls.c:69 app/flatpak-builtins-search.c:45
msgid "Description"
msgstr "Omschrijving"

#: app/flatpak-builtins-list.c:60 app/flatpak-builtins-remote-ls.c:69
#: app/flatpak-builtins-search.c:45
msgid "Show the description"
msgstr "Omschrijving tonen"

#: app/flatpak-builtins-list.c:61 app/flatpak-builtins-remote-ls.c:70
#: app/flatpak-builtins-search.c:46
msgid "Application ID"
msgstr "Toepassings-ID"

#: app/flatpak-builtins-list.c:61 app/flatpak-builtins-ps.c:52
#: app/flatpak-builtins-remote-ls.c:70 app/flatpak-builtins-search.c:46
msgid "Show the application ID"
msgstr "Toepassings-ID tonen"

#: app/flatpak-builtins-list.c:62 app/flatpak-builtins-remote-ls.c:71
#: app/flatpak-builtins-search.c:47
msgid "Show the version"
msgstr "Versie tonen"

#: app/flatpak-builtins-list.c:65 app/flatpak-builtins-ps.c:56
#: app/flatpak-builtins-remote-ls.c:77
msgid "Runtime"
msgstr "Runtime"

#: app/flatpak-builtins-list.c:65
msgid "Show the used runtime"
msgstr "Gebruikte runtime tonen"

#: app/flatpak-builtins-list.c:66 app/flatpak-builtins-remote-ls.c:74
msgid "Show the origin remote"
msgstr "Herkomst-remote tonen"

#: app/flatpak-builtins-list.c:67
msgid "Show the installation"
msgstr "Installatie tonen"

#: app/flatpak-builtins-list.c:69
msgid "Active commit"
msgstr "Actieve commit"

#: app/flatpak-builtins-list.c:69 app/flatpak-builtins-remote-ls.c:76
msgid "Show the active commit"
msgstr "Actieve commit tonen"

#: app/flatpak-builtins-list.c:70
msgid "Latest commit"
msgstr "Laatste commit"

#: app/flatpak-builtins-list.c:70
msgid "Show the latest commit"
msgstr "Laatste commit tonen"

#: app/flatpak-builtins-list.c:71 app/flatpak-builtins-remote-ls.c:78
msgid "Installed size"
msgstr "Geïnstalleerde grootte"

#: app/flatpak-builtins-list.c:71 app/flatpak-builtins-remote-ls.c:78
msgid "Show the installed size"
msgstr "Geïnstalleerde grootte tonen"

#: app/flatpak-builtins-list.c:72 app/flatpak-builtins-remote-list.c:58
#: app/flatpak-builtins-remote-ls.c:80 app/flatpak-builtins-repo.c:340
msgid "Options"
msgstr "Opties"

#: app/flatpak-builtins-list.c:72 app/flatpak-builtins-remote-list.c:58
#: app/flatpak-builtins-remote-ls.c:80
msgid "Show options"
msgstr "Opties tonen"

#: app/flatpak-builtins-list.c:180
#, c-format
msgid "Unable to load details of %s: %s"
msgstr "Kon details van %s niet laden: %s"

#: app/flatpak-builtins-list.c:190
#, c-format
msgid "Unable to inspect current version of %s: %s"
msgstr "Kon huidige versie van %s niet inspecteren: %s"

#: app/flatpak-builtins-list.c:408
msgid " - List installed apps and/or runtimes"
msgstr " - Geïnstalleerde toepassingen en/of runtimes opsommen"

# Ik snap deze zin niet, maar dit is een letterlijke vertaling  - Philip
#: app/flatpak-builtins-make-current.c:38
msgid "Arch to make current for"
msgstr "Architectuur om huidig voor te maken"

#: app/flatpak-builtins-make-current.c:58
msgid "APP BRANCH - Make branch of application current"
msgstr "TOEPASSING BRANCH - Branch als actief instellen voor toepassing"

#: app/flatpak-builtins-make-current.c:69 app/flatpak-builtins-run.c:260
msgid "APP must be specified"
msgstr "TOEPASSING moet worden opgegeven"

#: app/flatpak-builtins-make-current.c:84
msgid "BRANCH must be specified"
msgstr "BRANCH moet worden opgegeven"

#: app/flatpak-builtins-make-current.c:97
#, c-format
msgid "App %s branch %s is not installed"
msgstr "Toepassing %s met branch %s is niet geïnstalleerd"

#: app/flatpak-builtins-mask.c:42
msgid "Remove matching masks"
msgstr "Overeenkomende verhullingen verwijderen"

#: app/flatpak-builtins-mask.c:54
msgid ""
"[PATTERN…] - disable updates and automatic installation matching patterns"
msgstr ""
"[PATROON…] - Patronen voor updates en automatische installatie uitschakelen"

#: app/flatpak-builtins-mask.c:73
#, c-format
msgid "No masked patterns\n"
msgstr "Geen verhulde patronen\n"

#: app/flatpak-builtins-mask.c:78
#, c-format
msgid "Masked patterns:\n"
msgstr "Verhulde patronen:\n"

#: app/flatpak-builtins-override.c:42
msgid "Remove existing overrides"
msgstr "Bestaande overschrijvingen verwijderen"

#: app/flatpak-builtins-override.c:43
msgid "Show existing overrides"
msgstr "Bestaande overschrijvingen tonen"

# Blokhaken om ‘voor toepassing’ weggelaten voor consistentie  - Philip
#: app/flatpak-builtins-override.c:59
msgid "[APP] - Override settings [for application]"
msgstr "[TOEPASSING] - Instellingen overschrijven voor toepassing"

#: app/flatpak-builtins-permission-list.c:143
msgid "[TABLE] [ID] - List permissions"
msgstr "[TABEL] [ID] - Rechten opsommen"

#: app/flatpak-builtins-permission-list.c:179
#: app/flatpak-builtins-permission-show.c:142
msgid "Table"
msgstr "Tabel"

#: app/flatpak-builtins-permission-list.c:180
#: app/flatpak-builtins-permission-show.c:143
msgid "Object"
msgstr "Object"

#: app/flatpak-builtins-permission-list.c:181
#: app/flatpak-builtins-permission-show.c:144
msgid "App"
msgstr "Toepassing"

#: app/flatpak-builtins-permission-list.c:183
#: app/flatpak-builtins-permission-show.c:146
msgid "Data"
msgstr "Gegevens"

#: app/flatpak-builtins-permission-remove.c:120
msgid "TABLE ID [APP_ID] - Remove item from permission store"
msgstr "TABEL ID [TOEPASSINGS-ID] - Item van rechtenopslag verwijderen"

#: app/flatpak-builtins-permission-remove.c:129
#: app/flatpak-builtins-permission-set.c:120
msgid "Too few arguments"
msgstr "Te weinig argumenten"

#: app/flatpak-builtins-permission-reset.c:43
msgid "Reset all permissions"
msgstr "Alle rechten resetten"

#: app/flatpak-builtins-permission-reset.c:144
msgid "APP_ID - Reset permissions for an app"
msgstr "APP-ID - Rechten voor een toepassing resetten"

#: app/flatpak-builtins-permission-reset.c:153
#: app/flatpak-builtins-permission-show.c:124
msgid "Wrong number of arguments"
msgstr "Ongeldig aantal argumenten"

#: app/flatpak-builtins-permission-set.c:42
msgid "Associate DATA with the entry"
msgstr "GEGEVENS associëren met de invoer"

#: app/flatpak-builtins-permission-set.c:42
msgid "DATA"
msgstr "GEGEVENS"

#: app/flatpak-builtins-permission-set.c:111
msgid "TABLE ID APP_ID [PERMISSION...] - Set permissions"
msgstr "TABEL ID TOEPASSINGS-ID [RECHT…] - Rechten instellen"

#: app/flatpak-builtins-permission-set.c:132
#, c-format
msgid "Failed to parse '%s' as GVariant: "
msgstr "‘%s’ parsen als GVariant mislukt: "

#: app/flatpak-builtins-permission-show.c:115
msgid "APP_ID - Show permissions for an app"
msgstr "TOEPASSINGS-ID - Rechten voor een toepassing tonen"

#: app/flatpak-builtins-pin.c:44
msgid "Remove matching pins"
msgstr "Overeenkomende pins verwijderen"

#: app/flatpak-builtins-pin.c:56
msgid "[PATTERN…] - disable automatic removal of runtimes matching patterns"
msgstr ""
"[PATROON…] - Automatische verwijdering van runtimes overeenkomend met "
"patronen uitschakelen"

#: app/flatpak-builtins-pin.c:75
#, c-format
msgid "No pinned patterns\n"
msgstr "Geen vastgepinde patronen\n"

#: app/flatpak-builtins-pin.c:80
#, c-format
msgid "Pinned patterns:\n"
msgstr "Vastgepinde patronen:\n"

#: app/flatpak-builtins-preinstall.c:80
msgid "- Install flatpaks that are part of the operating system"
msgstr ""

# Ik heb de punten hier weggelaten voor consistentie met de rest van de mededelingen  - Philip
#: app/flatpak-builtins-preinstall.c:118
#, c-format
msgid "Nothing to do.\n"
msgstr "Er valt niets te doen\n"

#: app/flatpak-builtins-ps.c:49
msgid "Instance"
msgstr "Instantie"

#: app/flatpak-builtins-ps.c:49
msgid "Show the instance ID"
msgstr "Instantie-ID tonen"

#: app/flatpak-builtins-ps.c:50 app/flatpak-builtins-run.c:178
msgid "PID"
msgstr "PID"

#: app/flatpak-builtins-ps.c:50
msgid "Show the PID of the wrapper process"
msgstr "PID van het wrapper-proces tonen"

#: app/flatpak-builtins-ps.c:51
msgid "Child-PID"
msgstr "Sub-PID"

#: app/flatpak-builtins-ps.c:51
msgid "Show the PID of the sandbox process"
msgstr "PID van het zandbakproces tonen"

#: app/flatpak-builtins-ps.c:54 app/flatpak-builtins-search.c:48
msgid "Show the application branch"
msgstr "Toepassingsbranch tonen"

#: app/flatpak-builtins-ps.c:55
msgid "Show the application commit"
msgstr "Toepassingscommit tonen"

#: app/flatpak-builtins-ps.c:56
msgid "Show the runtime ID"
msgstr "Runtime-ID tonen"

#: app/flatpak-builtins-ps.c:57
msgid "R.-Branch"
msgstr "Runtime-branch"

#: app/flatpak-builtins-ps.c:57
msgid "Show the runtime branch"
msgstr "Runtime-branch tonen"

#: app/flatpak-builtins-ps.c:58
msgid "R.-Commit"
msgstr "Runtime-commit"

#: app/flatpak-builtins-ps.c:58
msgid "Show the runtime commit"
msgstr "Runtime-commit tonen"

#: app/flatpak-builtins-ps.c:59
msgid "Active"
msgstr "Actief"

#: app/flatpak-builtins-ps.c:59
msgid "Show whether the app is active"
msgstr "Tonen of de toepassing actief is"

#: app/flatpak-builtins-ps.c:60
msgid "Background"
msgstr "Achtergrond"

#: app/flatpak-builtins-ps.c:60
msgid "Show whether the app is background"
msgstr "Tonen of de toepassing op de achtergrond is"

#: app/flatpak-builtins-ps.c:246
msgid " - Enumerate running sandboxes"
msgstr " - Draaiende zandbakken opsommen"

#: app/flatpak-builtins-remote-add.c:66
msgid "Do nothing if the provided remote exists"
msgstr "Niets doen als de opgegeven remote bestaat"

#: app/flatpak-builtins-remote-add.c:67
msgid "LOCATION specifies a configuration file, not the repo location"
msgstr "LOCATIE geeft een configuratiebestand aan, niet de pakketbronlocatie"

#: app/flatpak-builtins-remote-add.c:72 app/flatpak-builtins-remote-modify.c:78
msgid "Disable GPG verification"
msgstr "GPG-verificatie uitschakelen"

#: app/flatpak-builtins-remote-add.c:73 app/flatpak-builtins-remote-modify.c:79
msgid "Mark the remote as don't enumerate"
msgstr "Remote markeren als niet te enumereren"

#: app/flatpak-builtins-remote-add.c:74 app/flatpak-builtins-remote-modify.c:80
msgid "Mark the remote as don't use for deps"
msgstr "Remote markeren als niet te gebruiken voor afhankelijkheden"

#: app/flatpak-builtins-remote-add.c:75 app/flatpak-builtins-remote-modify.c:81
msgid "Set priority (default 1, higher is more prioritized)"
msgstr "Prioriteit (standaard: 1, hoger voor meer prioriteit)"

#: app/flatpak-builtins-remote-add.c:75 app/flatpak-builtins-remote-modify.c:81
msgid "PRIORITY"
msgstr "PRIORITEIT"

#: app/flatpak-builtins-remote-add.c:76
msgid "The named subset to use for this remote"
msgstr "Benoemde subset om te gebruiken voor deze remote"

#: app/flatpak-builtins-remote-add.c:76 app/flatpak-builtins-remote-modify.c:71
msgid "SUBSET"
msgstr "SUBSET"

#: app/flatpak-builtins-remote-add.c:77 app/flatpak-builtins-remote-modify.c:82
msgid "A nice name to use for this remote"
msgstr "Naam om te gebruiken voor deze remote"

#: app/flatpak-builtins-remote-add.c:78 app/flatpak-builtins-remote-modify.c:83
msgid "A one-line comment for this remote"
msgstr "Opmerking van één regel voor deze remote"

#: app/flatpak-builtins-remote-add.c:79 app/flatpak-builtins-remote-modify.c:84
msgid "A full-paragraph description for this remote"
msgstr "Omschrijving van een volledige alinea voor deze remote"

#: app/flatpak-builtins-remote-add.c:80 app/flatpak-builtins-remote-modify.c:85
msgid "URL for a website for this remote"
msgstr "URL voor website van deze remote"

#: app/flatpak-builtins-remote-add.c:81 app/flatpak-builtins-remote-modify.c:86
msgid "URL for an icon for this remote"
msgstr "URL voor pictogram van deze remote"

#: app/flatpak-builtins-remote-add.c:82 app/flatpak-builtins-remote-modify.c:87
msgid "Default branch to use for this remote"
msgstr "Standaard-branch om te gebruiken voor deze remote"

#: app/flatpak-builtins-remote-add.c:84 app/flatpak-builtins-remote-modify.c:89
msgid "Import GPG key from FILE (- for stdin)"
msgstr "GPG-sleutel uit BESTAND importeren (- voor stdin)"

#: app/flatpak-builtins-remote-add.c:85 app/flatpak-builtins-remote-modify.c:90
msgid "Load signatures from URL"
msgstr ""

#: app/flatpak-builtins-remote-add.c:86 app/flatpak-builtins-remote-modify.c:92
msgid "Set path to local filter FILE"
msgstr "Pad instellen naar lokaal filter-BESTAND"

#: app/flatpak-builtins-remote-add.c:87 app/flatpak-builtins-remote-modify.c:93
msgid "Disable the remote"
msgstr "Remote uitschakelen"

#: app/flatpak-builtins-remote-add.c:88 app/flatpak-builtins-remote-modify.c:94
msgid "Name of authenticator"
msgstr "Naam van authenticator"

#: app/flatpak-builtins-remote-add.c:90 app/flatpak-builtins-remote-modify.c:96
msgid "Autoinstall authenticator"
msgstr "Authenticator automatisch installeren"

#: app/flatpak-builtins-remote-add.c:91 app/flatpak-builtins-remote-modify.c:97
msgid "Don't autoinstall authenticator"
msgstr "Authenticator niet automatisch installeren"

#: app/flatpak-builtins-remote-add.c:92 app/flatpak-builtins-remote-modify.c:99
msgid "Don't follow the redirect set in the summary file"
msgstr "Omleidingsset in samenvattingsbestand niet volgen"

#: app/flatpak-builtins-remote-add.c:261 app/flatpak-builtins-remote-add.c:268
#, c-format
msgid "Can't load uri %s: %s\n"
msgstr "Kan URI %s niet laden: %s\n"

#: app/flatpak-builtins-remote-add.c:276 common/flatpak-dir.c:4643
#, c-format
msgid "Can't load file %s: %s\n"
msgstr "Kan bestand %s niet laden: %s\n"

#: app/flatpak-builtins-remote-add.c:304
msgid "NAME LOCATION - Add a remote repository"
msgstr "NAAM LOCATIE - Externe pakketbron toevoegen"

#: app/flatpak-builtins-remote-add.c:331
msgid "GPG verification is required if collections are enabled"
msgstr "GPG-verificatie is vereist als verzamelingen zijn ingeschakeld"

#: app/flatpak-builtins-remote-add.c:393
#, c-format
msgid "Remote %s already exists"
msgstr "Remote %s bestaat al"

#: app/flatpak-builtins-remote-add.c:405
#: app/flatpak-builtins-remote-modify.c:340
#, c-format
msgid "Invalid authenticator name %s"
msgstr "Ongeldige authenticatornaam %s"

#: app/flatpak-builtins-remote-add.c:422
#, c-format
msgid "Warning: Could not update extra metadata for '%s': %s\n"
msgstr "Waarschuwing: Kon extra metadata voor ‘%s’ niet bijwerken: %s\n"

#: app/flatpak-builtins-remote-delete.c:39
msgid "Remove remote even if in use"
msgstr "Remote verwijderen zelfs indien in gebruik"

#: app/flatpak-builtins-remote-delete.c:53
msgid "NAME - Delete a remote repository"
msgstr "NAAM - Verwijder een externe pakketbron"

#: app/flatpak-builtins-remote-delete.c:100
#, c-format
msgid "The following refs are installed from remote '%s':"
msgstr "De volgende refs zijn geïnstalleerd vanaf remote '%s':"

#: app/flatpak-builtins-remote-delete.c:101
msgid "Remove them?"
msgstr "Deze verwijderen?"

#: app/flatpak-builtins-remote-delete.c:103
#, c-format
msgid "Can't remove remote '%s' with installed refs"
msgstr "Kan remote '%s' met geïnstalleerde refs niet verwijderen"

#: app/flatpak-builtins-remote-info.c:55
msgid "Commit to show info for"
msgstr "Committen om informatie te tonen voor"

#: app/flatpak-builtins-remote-info.c:58
msgid "Display log"
msgstr "Logboek tonen"

#: app/flatpak-builtins-remote-info.c:61
msgid "Show parent"
msgstr "Bovenliggende tonen"

#: app/flatpak-builtins-remote-info.c:65 app/flatpak-builtins-remote-ls.c:60
msgid "Use local caches even if they are stale"
msgstr "Gebruik lokale caches, zelfs als ze verouderd zijn"

#. Translators: A sideload is when you install from a local USB drive rather than the Internet.
#: app/flatpak-builtins-remote-info.c:67 app/flatpak-builtins-remote-ls.c:62
msgid "Only list refs available as sideloads"
msgstr "Geef alleen refs weer die beschikbaar zijn als sideloads"

#: app/flatpak-builtins-remote-info.c:114
msgid ""
" REMOTE REF - Show information about an application or runtime in a remote"
msgstr ""
" REMOTE REF - Toon informatie over een toepassing of een runtime in een "
"remote"

#: app/flatpak-builtins-remote-info.c:125
msgid "REMOTE and REF must be specified"
msgstr "REMOTE en REF moeten worden opgegeven"

#: app/flatpak-builtins-remote-info.c:247
#: app/flatpak-builtins-remote-info.c:282
#, fuzzy
msgid "Download Size:"
msgstr "Downloadgrootte"

#: app/flatpak-builtins-remote-info.c:267
#: app/flatpak-builtins-remote-info.c:325
msgid "History:"
msgstr "Geschiedenis:"

#: app/flatpak-builtins-remote-info.c:348
msgid " Commit:"
msgstr " Commit:"

#: app/flatpak-builtins-remote-info.c:349
msgid " Subject:"
msgstr " Onderwerp:"

#: app/flatpak-builtins-remote-info.c:350
msgid " Date:"
msgstr " Datum:"

#: app/flatpak-builtins-remote-info.c:383
#, c-format
msgid "Warning: Commit %s has no flatpak metadata\n"
msgstr "Waarchuwing: Commit %s heeft geen Flatpak-metagegevens\n"

#: app/flatpak-builtins-remote-list.c:43
msgid "Show remote details"
msgstr "Details van remote tonen"

#: app/flatpak-builtins-remote-list.c:44
msgid "Show disabled remotes"
msgstr "Uitgeschakelde remotes tonen"

#: app/flatpak-builtins-remote-list.c:52
msgid "Title"
msgstr "Titel"

#: app/flatpak-builtins-remote-list.c:52
msgid "Show the title"
msgstr "Titel tonen"

#: app/flatpak-builtins-remote-list.c:53
msgid "Show the URL"
msgstr "URL tonen"

#: app/flatpak-builtins-remote-list.c:54
msgid "Show the collection ID"
msgstr "Verzamelings-ID tonen"

#: app/flatpak-builtins-remote-list.c:55 app/flatpak-builtins-repo.c:392
msgid "Subset"
msgstr "Subset"

#: app/flatpak-builtins-remote-list.c:55
msgid "Show the subset"
msgstr "Subset tonen"

#: app/flatpak-builtins-remote-list.c:56
msgid "Filter"
msgstr "Filter"

#: app/flatpak-builtins-remote-list.c:56
msgid "Show filter file"
msgstr "Filterbestand tonen"

#: app/flatpak-builtins-remote-list.c:57
msgid "Priority"
msgstr "Prioriteit"

#: app/flatpak-builtins-remote-list.c:57
msgid "Show the priority"
msgstr "Prioriteit tonen"

#: app/flatpak-builtins-remote-list.c:59
msgid "Comment"
msgstr "Opmerking"

#: app/flatpak-builtins-remote-list.c:59
msgid "Show comment"
msgstr "Opmerking tonen"

#: app/flatpak-builtins-remote-list.c:60
msgid "Show description"
msgstr "Omschrijving tonen"

#: app/flatpak-builtins-remote-list.c:61
msgid "Homepage"
msgstr "Startpagina"

#: app/flatpak-builtins-remote-list.c:61
msgid "Show homepage"
msgstr "Startpagina tonen"

#: app/flatpak-builtins-remote-list.c:62
msgid "Icon"
msgstr "Pictogram"

#: app/flatpak-builtins-remote-list.c:62
msgid "Show icon"
msgstr "Pictogram tonen"

#: app/flatpak-builtins-remote-list.c:231
msgid " - List remote repositories"
msgstr " - Externe pakketbronnen opsommen"

#: app/flatpak-builtins-remote-ls.c:52
msgid "Show arches and branches"
msgstr "Architecturen en branches tonen"

#: app/flatpak-builtins-remote-ls.c:53
msgid "Show only runtimes"
msgstr "Enkel runtimes tonen"

#: app/flatpak-builtins-remote-ls.c:54
msgid "Show only apps"
msgstr "Enkel toepassingen tonen"

#: app/flatpak-builtins-remote-ls.c:55
msgid "Show only those where updates are available"
msgstr "Toon alleen runtimes waarvoor updates beschikbaar zijn"

#: app/flatpak-builtins-remote-ls.c:56
msgid "Limit to this arch (* for all)"
msgstr "Beperk tot deze arch (* voor alle)"

#: app/flatpak-builtins-remote-ls.c:77
msgid "Show the runtime"
msgstr "De runtime tonen"

#: app/flatpak-builtins-remote-ls.c:79
msgid "Download size"
msgstr "Downloadgrootte"

#: app/flatpak-builtins-remote-ls.c:79
msgid "Show the download size"
msgstr "Downloadgrootte tonen"

#: app/flatpak-builtins-remote-ls.c:391
msgid " [REMOTE or URI] - Show available runtimes and applications"
msgstr " [REMOTE of URI] - Toon beschikbare runtimes en toepassingen"

#: app/flatpak-builtins-remote-modify.c:67
msgid "Enable GPG verification"
msgstr "GPG-verificatie inschakelen"

#: app/flatpak-builtins-remote-modify.c:68
msgid "Mark the remote as enumerate"
msgstr "Remote markeren als te enumereren"

#: app/flatpak-builtins-remote-modify.c:69
msgid "Mark the remote as used for dependencies"
msgstr "Remote markeren als te gebruiken voor afhankelijkheden"

#: app/flatpak-builtins-remote-modify.c:70
#, fuzzy
msgid "Set a new URL"
msgstr "Nieuwe URL instellen"

#: app/flatpak-builtins-remote-modify.c:71
msgid "Set a new subset to use"
msgstr "Nieuwe subset om te gebruiken instellen"

#: app/flatpak-builtins-remote-modify.c:72
msgid "Enable the remote"
msgstr "Remote inschakelen"

#: app/flatpak-builtins-remote-modify.c:73
msgid "Update extra metadata from the summary file"
msgstr "Extra metagegevens bijwerken vanuit samenvattingsbestand"

#: app/flatpak-builtins-remote-modify.c:91
msgid "Disable local filter"
msgstr "Lokaal filter uitschakelen"

#: app/flatpak-builtins-remote-modify.c:95
msgid "Authenticator options"
msgstr "Authenticator-opties"

#: app/flatpak-builtins-remote-modify.c:98
msgid "Follow the redirect set in the summary file"
msgstr "Omleidingsset in samenvattingsbestand volgen"

#: app/flatpak-builtins-remote-modify.c:306
msgid "NAME - Modify a remote repository"
msgstr "NAAM - Pas een externe pakketbron aan"

#: app/flatpak-builtins-remote-modify.c:316
msgid "Remote NAME must be specified"
msgstr "Remote NAAM moet worden opgegeven"

#: app/flatpak-builtins-remote-modify.c:327
#, c-format
msgid "Updating extra metadata from remote summary for %s\n"
msgstr "Extra metadata van remote-samenvatting van %s bijwerken\n"

#: app/flatpak-builtins-remote-modify.c:330
#, c-format
msgid "Error updating extra metadata for '%s': %s\n"
msgstr "Fout bij bijwerken van extra metadata van '%s': %s\n"

#: app/flatpak-builtins-remote-modify.c:331
#, c-format
msgid "Could not update extra metadata for %s"
msgstr "Kon extra metadata van %s niet bijwerken"

#: app/flatpak-builtins-repair.c:43
msgid "Don't make any changes"
msgstr "Geen wijzigingen maken"

#: app/flatpak-builtins-repair.c:44
msgid "Reinstall all refs"
msgstr "Alle refs herinstalleren"

#: app/flatpak-builtins-repair.c:68
#, c-format
msgid "Object missing: %s.%s\n"
msgstr "Object ontbreekt: %s.%s\n"

#: app/flatpak-builtins-repair.c:76
#, c-format
msgid "Object invalid: %s.%s\n"
msgstr "Ongeldig object: %s.%s\n"

#: app/flatpak-builtins-repair.c:81
#, c-format
msgid "%s, deleting object\n"
msgstr "%s, object wordt verwijderd\n"

#: app/flatpak-builtins-repair.c:146
#, c-format
msgid "Can't load object %s: %s\n"
msgstr "Kan object %s niet laden: %s\n"

#: app/flatpak-builtins-repair.c:228
#, c-format
msgid "Commit invalid %s: %s\n"
msgstr "Commit %s ongeldig: %s\n"

#: app/flatpak-builtins-repair.c:231
#, c-format
msgid "Deleting invalid commit %s: %s\n"
msgstr "Ongeldige commit %s wordt verwijderd: %s\n"

#: app/flatpak-builtins-repair.c:261
#, c-format
msgid "Commit should be marked partial: %s\n"
msgstr "Commit moet als gedeeltelijk gemarkeerd worden: %s\n"

#: app/flatpak-builtins-repair.c:264
#, c-format
msgid "Marking commit as partial: %s\n"
msgstr "Commit wordt als gedeeltelijk gemarkeerd: %s\n"

#: app/flatpak-builtins-repair.c:293
#, c-format
msgid "Problems loading data for %s: %s\n"
msgstr "Problemen met laden van gegevens voor %s: %s\n"

#: app/flatpak-builtins-repair.c:306
#, c-format
msgid "Error reinstalling %s: %s\n"
msgstr "Fout bij herinstalleren van %s: %s\n"

#: app/flatpak-builtins-repair.c:327
msgid "- Repair a flatpak installation"
msgstr "- Een Flatpak-installatie herstellen"

#: app/flatpak-builtins-repair.c:406
#, c-format
msgid "Removing non-deployed ref %s…\n"
msgstr "Niet-uitgerolde ref %s wordt verwijderd…\n"

#: app/flatpak-builtins-repair.c:411
#, c-format
msgid "Skipping non-deployed ref %s…\n"
msgstr "Niet-uitgerolde ref %s wordt overgeslagen…\n"

#: app/flatpak-builtins-repair.c:429
#, c-format
msgid "[%d/%d] Verifying %s…\n"
msgstr "[%d/%d] %s verifieren…\n"

#: app/flatpak-builtins-repair.c:435
#, c-format
msgid "Dry run: "
msgstr "Dry-run: "

#: app/flatpak-builtins-repair.c:440
#, c-format
msgid "Deleting ref %s due to missing objects\n"
msgstr "Ref %s wordt verwijderd vanwege ontbrekende objecten\n"

#: app/flatpak-builtins-repair.c:444
#, c-format
msgid "Deleting ref %s due to invalid objects\n"
msgstr "Ref %s wordt verwijderd vanwege ongeldige objecten\n"

#: app/flatpak-builtins-repair.c:448
#, c-format
msgid "Deleting ref %s due to %d\n"
msgstr "Ref %s wordt verwijderd vanwege %d\n"

#: app/flatpak-builtins-repair.c:464
#, c-format
msgid "Checking remotes...\n"
msgstr "Remotes controleren…\n"

#: app/flatpak-builtins-repair.c:482
#, c-format
msgid "Remote %s for ref %s is missing\n"
msgstr "Remote %s voor ref %s ontbreekt\n"

#: app/flatpak-builtins-repair.c:484
#, c-format
msgid "Remote %s for ref %s is disabled\n"
msgstr "Remote %s voor ref %s is uitgeschakeld\n"

#: app/flatpak-builtins-repair.c:490
#, c-format
msgid "Pruning objects\n"
msgstr "Objecten opschonen\n"

#: app/flatpak-builtins-repair.c:498
#, c-format
msgid "Erasing .removed\n"
msgstr ".removed verwijderen\n"

#: app/flatpak-builtins-repair.c:524
#, c-format
msgid "Reinstalling refs\n"
msgstr "Refs herinstalleren\n"

#: app/flatpak-builtins-repair.c:526
#, c-format
msgid "Reinstalling removed refs\n"
msgstr "Verwijderde refs herinstalleren\n"

#: app/flatpak-builtins-repair.c:551
#, c-format
msgid "While removing appstream for %s: "
msgstr "Tijdens het verwijderen van de appstream voor %s: "

#: app/flatpak-builtins-repair.c:558
#, c-format
msgid "While deploying appstream for %s: "
msgstr "Tijdens het uitrollen van de appstream voor %s: "

#: app/flatpak-builtins-repo.c:106
#, c-format
msgid "Repo mode: %s\n"
msgstr "Modus van pakketbron: %s\n"

#: app/flatpak-builtins-repo.c:113
#, c-format
msgid "Indexed summaries: %s\n"
msgstr "Geïndexeerde samenvattingen: %s\n"

#: app/flatpak-builtins-repo.c:113 app/flatpak-builtins-repo.c:139
#: app/flatpak-builtins-repo.c:172
msgid "true"
msgstr "waar"

#: app/flatpak-builtins-repo.c:113 app/flatpak-builtins-repo.c:139
#: app/flatpak-builtins-repo.c:172
msgid "false"
msgstr "onwaar"

#: app/flatpak-builtins-repo.c:121
#, c-format
msgid "Subsummaries: "
msgstr "Subsamenvattingen: "

#: app/flatpak-builtins-repo.c:136
#, c-format
msgid "Cache version: %d\n"
msgstr "Cache-versie: %d\n"

#: app/flatpak-builtins-repo.c:139
#, c-format
msgid "Indexed deltas: %s\n"
msgstr "Geïndexeerde delta’s: %s\n"

#: app/flatpak-builtins-repo.c:142
#, c-format
msgid "Title: %s\n"
msgstr "Titel: %s\n"

#: app/flatpak-builtins-repo.c:145
#, c-format
msgid "Comment: %s\n"
msgstr "Opmerking: %s\n"

#: app/flatpak-builtins-repo.c:148
#, c-format
msgid "Description: %s\n"
msgstr "Omschrijving: %s\n"

#: app/flatpak-builtins-repo.c:151
#, c-format
msgid "Homepage: %s\n"
msgstr "Startpagina: %s\n"

#: app/flatpak-builtins-repo.c:154
#, c-format
msgid "Icon: %s\n"
msgstr "Pictogram: %s\n"

#: app/flatpak-builtins-repo.c:157
#, c-format
msgid "Collection ID: %s\n"
msgstr "Verzamelings-ID: %s\n"

#: app/flatpak-builtins-repo.c:160
#, c-format
msgid "Default branch: %s\n"
msgstr "Standaard-branch: %s\n"

#: app/flatpak-builtins-repo.c:163
#, c-format
msgid "Redirect URL: %s\n"
msgstr "Doorverwijzings-URL: %s\n"

#: app/flatpak-builtins-repo.c:166
#, c-format
msgid "Deploy collection ID: %s\n"
msgstr "Inzettingsverzamelings-ID: %s\n"

#: app/flatpak-builtins-repo.c:169
#, c-format
msgid "Authenticator name: %s\n"
msgstr "Authenticatornaam: %s\n"

#: app/flatpak-builtins-repo.c:172
#, c-format
msgid "Authenticator install: %s\n"
msgstr "Authenticatorinstallatie: %s\n"

#: app/flatpak-builtins-repo.c:180
#, c-format
msgid "GPG key hash: %s\n"
msgstr "Hash van GPG-sleutel: %s\n"

#: app/flatpak-builtins-repo.c:184
#, c-format
msgid "%zd summary branches\n"
msgstr "%zd samenvattings-branches\n"

#: app/flatpak-builtins-repo.c:336
msgid "Installed"
msgstr "Geïnstalleerd"

#. Translators: Download is used here as a noun
#: app/flatpak-builtins-repo.c:338 app/flatpak-cli-transaction.c:1462
msgid "Download"
msgstr "Downloaden"

#: app/flatpak-builtins-repo.c:339
msgid "Subsets"
msgstr "Subsets"

#: app/flatpak-builtins-repo.c:393
msgid "Digest"
msgstr "Overzicht"

#: app/flatpak-builtins-repo.c:394
msgid "History length"
msgstr "Geschiedenislengte"

#: app/flatpak-builtins-repo.c:711
msgid "Print general information about the repository"
msgstr "Algemene informatie tonen over de pakketbron"

#: app/flatpak-builtins-repo.c:712
msgid "List the branches in the repository"
msgstr "Branches in de pakketbron tonen"

#: app/flatpak-builtins-repo.c:713
msgid "Print metadata for a branch"
msgstr "Metadata van een branch tonen"

#: app/flatpak-builtins-repo.c:714
msgid "Show commits for a branch"
msgstr "Commits van een branch tonen"

#: app/flatpak-builtins-repo.c:715
msgid "Print information about the repo subsets"
msgstr "Informatie tonen over de pakketbron-subsets"

#: app/flatpak-builtins-repo.c:716
msgid "Limit information to subsets with this prefix"
msgstr "Informatie tot subsets met deze prefix limiteren"

#: app/flatpak-builtins-repo.c:732
msgid "LOCATION - Repository maintenance"
msgstr "LOCATIE - Onderhoud van pakketbronnen"

#: app/flatpak-builtins-run.c:159
msgid "Command to run"
msgstr "Opdracht om uit te voeren"

#: app/flatpak-builtins-run.c:160
msgid "Directory to run the command in"
msgstr "Map om de opdracht in uit te voeren"

#: app/flatpak-builtins-run.c:161
msgid "Branch to use"
msgstr "Branch om te gebruiken"

#: app/flatpak-builtins-run.c:162
msgid "Use development runtime"
msgstr "Ontwikkelaars-runtime gebruiken"

#: app/flatpak-builtins-run.c:163
msgid "Runtime to use"
msgstr "Runtime om te gebruiken"

#: app/flatpak-builtins-run.c:164
msgid "Runtime version to use"
msgstr "Runtime-versie om te gebruiken"

#: app/flatpak-builtins-run.c:167
msgid "Log accessibility bus calls"
msgstr "Aanroepen van toegankelijkheidsbus bijhouden"

#: app/flatpak-builtins-run.c:168
msgid "Don't proxy accessibility bus calls"
msgstr "Aanroepen van toegankelijkheidsbus niet omleiden"

#: app/flatpak-builtins-run.c:169
msgid "Proxy accessibility bus calls (default except when sandboxed)"
msgstr ""
"Aanroepen naar toegankelijkheidsbus proxyen (standaard, behalve wanneer "
"gesandboxed)"

#: app/flatpak-builtins-run.c:170
msgid "Don't proxy session bus calls"
msgstr "Sessiebusaanroepen niet proxyen"

#: app/flatpak-builtins-run.c:171
msgid "Proxy session bus calls (default except when sandboxed)"
msgstr "Sessiebusaanroepen proxyen (standaard, behalve wanneer gesandboxed)"

#: app/flatpak-builtins-run.c:172
msgid "Don't start portals"
msgstr "Geen portalen starten"

#: app/flatpak-builtins-run.c:173
msgid "Enable file forwarding"
msgstr "Bestandsdoorschakeling inschakelen"

#: app/flatpak-builtins-run.c:174
msgid "Run specified commit"
msgstr "Opgegeven commit uitvoeren"

#: app/flatpak-builtins-run.c:175
msgid "Use specified runtime commit"
msgstr "Opgegeven runtime-commit gebruiken"

#: app/flatpak-builtins-run.c:176
msgid "Run completely sandboxed"
msgstr "Compleet gesandboxed uitvoeren"

#: app/flatpak-builtins-run.c:178
msgid "Use PID as parent pid for sharing namespaces"
msgstr "PID als bovenliggende PID gebruiken voor het delen van namespaces"

#: app/flatpak-builtins-run.c:179
msgid "Make processes visible in parent namespace"
msgstr "Maak processen zichtbaar in bovenliggende namespace"

#: app/flatpak-builtins-run.c:180
msgid "Share process ID namespace with parent"
msgstr "Deel proces-ID-namespace met bovenliggende"

#: app/flatpak-builtins-run.c:181
msgid "Write the instance ID to the given file descriptor"
msgstr "Schrijf instantie-ID weg naar de opgegeven bestanddescriptor"

#: app/flatpak-builtins-run.c:182
msgid "Use PATH instead of the app's /app"
msgstr "Gebruik PAD in plaats van de /app van de toepassing"

#: app/flatpak-builtins-run.c:183
#, fuzzy
msgid "Use FD instead of the app's /app"
msgstr "Gebruik PAD in plaats van de /app van de toepassing"

#: app/flatpak-builtins-run.c:183 app/flatpak-builtins-run.c:185
#: app/flatpak-builtins-run.c:187 app/flatpak-builtins-run.c:188
#: common/flatpak-context.c:2672
msgid "FD"
msgstr "FD"

#: app/flatpak-builtins-run.c:184
msgid "Use PATH instead of the runtime's /usr"
msgstr "Gebruik PAD in plaats van de /usr van de runtime"

#: app/flatpak-builtins-run.c:185
#, fuzzy
msgid "Use FD instead of the runtime's /usr"
msgstr "Gebruik PAD in plaats van de /usr van de runtime"

#: app/flatpak-builtins-run.c:186
#, fuzzy
msgid "Clear all outside environment variables"
msgstr "Omgevingsvariabele instellen"

#: app/flatpak-builtins-run.c:187
msgid ""
"Bind mount the file or directory referred to by FD to its canonicalized path"
msgstr ""

#: app/flatpak-builtins-run.c:188
msgid ""
"Bind mount the file or directory referred to by FD read-only to its "
"canonicalized path"
msgstr ""

#: app/flatpak-builtins-run.c:219
msgid "APP [ARGUMENT…] - Run an app"
msgstr "APP [ARGUMENT…] - Voer een app uit"

#: app/flatpak-builtins-run.c:370
#, c-format
msgid "runtime/%s/%s/%s not installed"
msgstr "runtime/%s/%s/%s is niet geïnstalleerd"

#: app/flatpak-builtins-run.c:419
msgid "app-fd and app-path cannot both be used"
msgstr ""

#: app/flatpak-builtins-run.c:449
msgid "usr-fd and usr-path cannot both be used"
msgstr ""

#: app/flatpak-builtins-search.c:37
msgid "Arch to search for"
msgstr "Arch om voor te zoeken"

#: app/flatpak-builtins-search.c:49
msgid "Remotes"
msgstr "Remotes"

#: app/flatpak-builtins-search.c:49
msgid "Show the remotes"
msgstr "De remotes tonen"

#: app/flatpak-builtins-search.c:244
msgid "TEXT - Search remote apps/runtimes for text"
msgstr "TEKST - Zoek in remote apps/runtimes voor tekst"

#: app/flatpak-builtins-search.c:255
msgid "TEXT must be specified"
msgstr "TEKST moet worden opgegeven"

#: app/flatpak-builtins-search.c:338
msgid "No matches found"
msgstr "Geen overeenkomsten gevonden"

#: app/flatpak-builtins-uninstall.c:54
msgid "Arch to uninstall"
msgstr "Arch om te de-installeren"

#: app/flatpak-builtins-uninstall.c:55
msgid "Keep ref in local repository"
msgstr "Ref in lokale pakketbron behouden"

#: app/flatpak-builtins-uninstall.c:56
msgid "Don't uninstall related refs"
msgstr "Gerelateerde refs niet de-installeren"

#: app/flatpak-builtins-uninstall.c:57
msgid "Remove files even if running"
msgstr "Bestanden verwijderen zelfs indien in gebruik"

#: app/flatpak-builtins-uninstall.c:60
msgid "Uninstall all"
msgstr "Alle verwijderen"

#: app/flatpak-builtins-uninstall.c:61
msgid "Uninstall unused"
msgstr "Ongebruikte verwijderen"

#: app/flatpak-builtins-uninstall.c:62
msgid "Delete app data"
msgstr "Toepassingsgegevens verwijderen"

#: app/flatpak-builtins-uninstall.c:141
#, c-format
msgid "Delete data for %s?"
msgstr "Gegevens voor %s verwijderen?"

#: app/flatpak-builtins-uninstall.c:220
#, c-format
msgid "Info: applications using the extension %s%s%s branch %s%s%s:\n"
msgstr "Info: toepassingen die extensie %s%s%s, branch %s%s%s gebruiken:\n"

#: app/flatpak-builtins-uninstall.c:223
#, c-format
msgid "Info: applications using the runtime %s%s%s branch %s%s%s:\n"
msgstr ""
"Info: toepassingen die de runtime %s%s%s, met branch %s%s%s gebruiken:\n"

#: app/flatpak-builtins-uninstall.c:238
msgid "Really remove?"
msgstr "Echt verwijderen?"

#: app/flatpak-builtins-uninstall.c:255
msgid "[REF…] - Uninstall applications or runtimes"
msgstr "[REF…] - Toepassingen of runtimes de-installeren"

#: app/flatpak-builtins-uninstall.c:264
msgid "Must specify at least one REF, --unused, --all or --delete-data"
msgstr ""
"Er moet minimaal één REF, of --unused, --all of --delete-data, worden opgeven"

#: app/flatpak-builtins-uninstall.c:267
msgid "Must not specify REFs when using --all"
msgstr "Er mogen geen REFs worden opgeven in combinatie met --all"

#: app/flatpak-builtins-uninstall.c:270
msgid "Must not specify REFs when using --unused"
msgstr "Er mogen geen REFs worden opgegeven in combinatie met --unused"

#: app/flatpak-builtins-uninstall.c:336
#, c-format
msgid ""
"\n"
"These runtimes in installation '%s' are pinned and won't be removed; see "
"flatpak-pin(1):\n"
msgstr ""
"\n"
"Deze runtimes in installatie '%s' zijn gepind en zullen niet worden "
"verwijderd; zie flatpak-pin(1):\n"

#: app/flatpak-builtins-uninstall.c:370
#, c-format
msgid "Nothing unused to uninstall\n"
msgstr "Geen ongebruikte items om te verwijderen\n"

#: app/flatpak-builtins-uninstall.c:444
#, c-format
msgid "No installed refs found for ‘%s’"
msgstr "Geen geïnstalleerde refs gevonden voor ‘%s’"

#: app/flatpak-builtins-uninstall.c:447
#, c-format
msgid " with arch ‘%s’"
msgstr " met architectuur ‘%s’"

#: app/flatpak-builtins-uninstall.c:449
#, c-format
msgid " with branch ‘%s’"
msgstr " met branch ‘%s’"

#: app/flatpak-builtins-uninstall.c:456
#, c-format
msgid "Warning: %s is not installed\n"
msgstr "Waarschuwing: %s is niet geïnstalleerd\n"

#: app/flatpak-builtins-uninstall.c:490
#, c-format
msgid "None of the specified refs are installed"
msgstr "Geen van de opgegeven refs is geïnstaleerd"

#: app/flatpak-builtins-uninstall.c:599
#, c-format
msgid "No app data to delete\n"
msgstr ""

#: app/flatpak-builtins-update.c:56
msgid "Arch to update for"
msgstr "Architectuur om voor bij te werken"

#: app/flatpak-builtins-update.c:57
msgid "Commit to deploy"
msgstr "Commit om uit te rollen"

#: app/flatpak-builtins-update.c:58
msgid "Remove old files even if running"
msgstr "Oude bestanden verwijderen, zelfs als de toepassing wordt uitgevoerd"

#: app/flatpak-builtins-update.c:59
msgid "Don't pull, only update from local cache"
msgstr "Niet ophalen, aleen bijwerken vanaf lokale cache"

#: app/flatpak-builtins-update.c:61
msgid "Don't update related refs"
msgstr "Verwante refs niet bijwerken"

#: app/flatpak-builtins-update.c:66
msgid "Update appstream for remote"
msgstr "Appstream voor remote bijwerken"

#: app/flatpak-builtins-update.c:67
msgid "Only update this subpath"
msgstr "Enkel dit subpad bijwerken"

#: app/flatpak-builtins-update.c:90
msgid "[REF…] - Update applications or runtimes"
msgstr "[REF…] - Toepassingen of runtimes bijwerken"

#: app/flatpak-builtins-update.c:121
msgid "With --commit, only one REF may be specified"
msgstr "In combinatie met --commit mag er slechts één REF worden opgegeven"

#: app/flatpak-builtins-update.c:162
#, c-format
msgid "Looking for updates…\n"
msgstr "Zoeken naar updates…\n"

#: app/flatpak-builtins-update.c:215
#, c-format
msgid "Unable to update %s: %s\n"
msgstr "Kon %s niet bijwerken:%s\n"

# Ik heb de punten hier weggelaten voor consistentie met de rest van de mededelingen  - Philip
#: app/flatpak-builtins-update.c:274
#, fuzzy, c-format
msgid "Nothing to update.\n"
msgstr "Er valt niets te doen\n"

#: app/flatpak-builtins-utils.c:337
#, fuzzy, c-format
msgid ""
"Remote ‘%s’ found in multiple installations, unable to proceed in non-"
"interactive mode"
msgstr ""
"De ref ‘%s’ is gevonden in meerdere installaties: %s. Er moet er één "
"gespecificeerd worden."

#: app/flatpak-builtins-utils.c:346
#, c-format
msgid "Remote ‘%s’ found in multiple installations:"
msgstr "Remote ‘%s’ in meerdere installaties gevonden:"

#: app/flatpak-builtins-utils.c:347 app/flatpak-builtins-utils.c:442
#: app/flatpak-builtins-utils.c:538 app/flatpak-builtins-utils.c:540
#: app/flatpak-builtins-utils.c:598
msgid "Which do you want to use (0 to abort)?"
msgstr "Welke wilt u gebruiken (0 om af te breken)?"

#: app/flatpak-builtins-utils.c:349
#, c-format
msgid "No remote chosen to resolve ‘%s’ which exists in multiple installations"
msgstr ""
"Geen remote gekozen om ‘%s’, welke in meerdere installaties voorkomt, mee op "
"te lossen"

#: app/flatpak-builtins-utils.c:358
#, c-format
msgid ""
"Remote \"%s\" not found\n"
"Hint: Use flatpak remote-add to add a remote"
msgstr ""
"Remote \"%s\" niet gevonden\n"
"Hint: Gebruik flatpak remote-add om een remote toe te voegen"

#: app/flatpak-builtins-utils.c:364
#, c-format
msgid "Remote \"%s\" not found in the %s installation"
msgstr "Remote \"%s\" niet gevonden in de %s-installatie"

#: app/flatpak-builtins-utils.c:404
#, c-format
msgid "Multiple refs match ‘%s’, unable to proceed in non-interactive mode"
msgstr ""

#. default to yes on Enter
#: app/flatpak-builtins-utils.c:430
#, c-format
msgid ""
"Found ref ‘%s’ in remote ‘%s’ (%s).\n"
"Use this ref?"
msgstr ""
"Ref ‘%s’ in remote ‘%s’ (%s) gevonden.\n"
"Deze ref gebruiken?"

#: app/flatpak-builtins-utils.c:434 app/flatpak-builtins-utils.c:444
#: app/flatpak-builtins-utils.c:522 app/flatpak-builtins-utils.c:543
#, c-format
msgid "No ref chosen to resolve matches for ‘%s’"
msgstr "Geen ref gekozen om overeenkomsten voor ‘%s’ mee op te lossen"

#: app/flatpak-builtins-utils.c:440
#, c-format
msgid "Similar refs found for ‘%s’ in remote ‘%s’ (%s):"
msgstr "Vergelijkbare refs gevonden voor ‘%s’ in remote ‘%s’"

#: app/flatpak-builtins-utils.c:488
#, c-format
msgid ""
"Multiple installed refs match ‘%s’, unable to proceed in non-interactive mode"
msgstr ""

#. default to yes on Enter
#: app/flatpak-builtins-utils.c:518
#, c-format
msgid "Found installed ref ‘%s’ (%s). Is this correct?"
msgstr "Geïnstalleerde ref ‘%s’ (%s) gevonden. Is dit correct?"

#: app/flatpak-builtins-utils.c:534
#, c-format
msgid "All of the above"
msgstr "Alle bovenstaanden"

#: app/flatpak-builtins-utils.c:535
#, c-format
msgid "Similar installed refs found for ‘%s’:"
msgstr "Vergelijkbare geïnstalleerde refs gevonden voor ‘%s’:"

#: app/flatpak-builtins-utils.c:579
#, c-format
msgid ""
"Multiple remotes have refs matching ‘%s’, unable to proceed in non-"
"interactive mode"
msgstr ""

#: app/flatpak-builtins-utils.c:597
#, c-format
msgid "Remotes found with refs similar to ‘%s’:"
msgstr "Remotes gevonden met refs vergelijkbaar met ‘%s’:"

#: app/flatpak-builtins-utils.c:600
#, c-format
msgid "No remote chosen to resolve matches for ‘%s’"
msgstr "Geen remote gekozen om overeenkomsten voor ‘%s’ mee op te lossen"

#: app/flatpak-builtins-utils.c:696 app/flatpak-builtins-utils.c:699
#, c-format
msgid "Updating appstream data for user remote %s"
msgstr "Appstream-data bijwerken voor gebruikersremote %s"

#: app/flatpak-builtins-utils.c:706 app/flatpak-builtins-utils.c:709
#, c-format
msgid "Updating appstream data for remote %s"
msgstr "Appstream-data bijwerken voor remote %s"

#: app/flatpak-builtins-utils.c:717 app/flatpak-builtins-utils.c:719
msgid "Error updating"
msgstr "Fout bij bijwerken"

#: app/flatpak-builtins-utils.c:755
#, c-format
msgid "Remote \"%s\" not found"
msgstr "Remote ‘%s’ niet gevonden"

#: app/flatpak-builtins-utils.c:796
#, c-format
msgid "Ambiguous suffix: '%s'."
msgstr "Dubbelzinnig achtervoegsel ‘%s’"

#. Translators: don't translate the values
#: app/flatpak-builtins-utils.c:798 app/flatpak-builtins-utils.c:813
msgid "Possible values are :s[tart], :m[iddle], :e[nd] or :f[ull]"
msgstr "Geldige waarden zijn :s[tart], :m[iddle], :e[nd] of :f[ull]"

#: app/flatpak-builtins-utils.c:811
#, c-format
msgid "Invalid suffix: '%s'."
msgstr "Ongeldig achtervoegsel ‘%s’"

#: app/flatpak-builtins-utils.c:846
#, c-format
msgid "Ambiguous column: %s"
msgstr "Dubbelzinnige kolom: %s"

#: app/flatpak-builtins-utils.c:859
#, c-format
msgid "Unknown column: %s"
msgstr "Onbekende kolom: %s"

#: app/flatpak-builtins-utils.c:917
msgid "Available columns:\n"
msgstr "Beschikbare kolommen:\n"

#: app/flatpak-builtins-utils.c:927
msgid "Show all columns"
msgstr "Alle kolommen tonen"

#: app/flatpak-builtins-utils.c:928
msgid "Show available columns"
msgstr "Beschikbare kolommen tonen"

#: app/flatpak-builtins-utils.c:931
msgid "Append :s[tart], :m[iddle], :e[nd] or :f[ull] to change ellipsization"
msgstr ""
"Voeg :s[tart], :m[iddle], :e[nd] of :f[ull] toe om weglating te wijzigen"

#: app/flatpak-builtins-utils.c:1483
#, c-format
msgid "Unknown scheme in sideload location %s"
msgstr ""

#: app/flatpak-cli-transaction.c:96 app/flatpak-cli-transaction.c:102
#, c-format
msgid "Required runtime for %s (%s) found in remote %s\n"
msgstr "Vereiste runtime voor %s (%s) gevonden in remote %s\n"

#: app/flatpak-cli-transaction.c:104
msgid "Do you want to install it?"
msgstr "Wilt u deze installeren?"

#: app/flatpak-cli-transaction.c:110
#, c-format
msgid "Required runtime for %s (%s) found in remotes:"
msgstr "Vereiste runtime voor %s (%s) gevonden in meerdere remotes:"

#: app/flatpak-cli-transaction.c:112
msgid "Which do you want to install (0 to abort)?"
msgstr "Welke wilt u installeren? (0 om af te breken)"

#: app/flatpak-cli-transaction.c:132
#, c-format
msgid "Configuring %s as new remote '%s'\n"
msgstr "%s als nieuwe remote ‘%s’ configureren\n"

#. default to yes on Enter
#: app/flatpak-cli-transaction.c:139
#, c-format
msgid ""
"The remote '%s', referred to by '%s' at location %s contains additional "
"applications.\n"
"Should the remote be kept for future installations?"
msgstr ""
"De remote '%s', waarnaar gerefereerd wordt door '%s' op locatie %s, bevat "
"aanvullende toepassingen.\n"
"Moet deze remote behouden worden voor toekomstige installaties?"

#. default to yes on Enter
#: app/flatpak-cli-transaction.c:147
#, c-format
msgid ""
"The application %s depends on runtimes from:\n"
"  %s\n"
"Configure this as new remote '%s'"
msgstr ""
"De toepassing %s is afhankelijk van runtimes van:\n"
"  %s\n"
"Deze remote als nieuwe remote '%s' configureren?"

#. Formatted size/remaining time in seconds
#: app/flatpak-cli-transaction.c:321
#, c-format
msgid "%s/s%s%s"
msgstr ""

#. Download progress percentage, use the appropriate
#. percent format for your language
#: app/flatpak-cli-transaction.c:359
#, c-format
msgid "%3d%%"
msgstr ""

#: app/flatpak-cli-transaction.c:414
msgid "Installing…"
msgstr "Installeren…"

#: app/flatpak-cli-transaction.c:416
#, c-format
msgid "Installing %d/%d…"
msgstr "%d/%d installeren…"

#: app/flatpak-cli-transaction.c:421
msgid "Updating…"
msgstr "Bijwerken…"

#: app/flatpak-cli-transaction.c:423
#, c-format
msgid "Updating %d/%d…"
msgstr "%d/%d bijwerken…"

#: app/flatpak-cli-transaction.c:428
msgid "Uninstalling…"
msgstr "Verwijderen…"

#: app/flatpak-cli-transaction.c:430
#, c-format
msgid "Uninstalling %d/%d…"
msgstr "%d/%d verwijderen…"

#: app/flatpak-cli-transaction.c:496 app/flatpak-quiet-transaction.c:161
#, c-format
msgid "Info: %s was skipped"
msgstr "Info: %s is overgeslagen"

#: app/flatpak-cli-transaction.c:519
#, c-format
msgid "Warning: %s%s%s already installed"
msgstr "Waarschuwing: %s%s%s al geïnstalleerd"

#: app/flatpak-cli-transaction.c:522
#, c-format
msgid "Error: %s%s%s already installed"
msgstr "Fout: %s%s%s al geïnstalleerd"

#: app/flatpak-cli-transaction.c:528
#, c-format
msgid "Warning: %s%s%s not installed"
msgstr "Waarschuwing: %s%s%s niet geïnstalleerd"

#: app/flatpak-cli-transaction.c:531
#, c-format
msgid "Error: %s%s%s not installed"
msgstr "Fout: %s%s%s niet geïnstalleerd"

#: app/flatpak-cli-transaction.c:537
#, c-format
msgid "Warning: %s%s%s needs a later flatpak version"
msgstr "Waarschuwing: %s%s%s vereist een nieuwere flatpak-versie"

#: app/flatpak-cli-transaction.c:540
#, c-format
msgid "Error: %s%s%s needs a later flatpak version"
msgstr "Fout: %s%s%s vereist een nieuwere flatpak-versie"

#: app/flatpak-cli-transaction.c:546
msgid "Warning: Not enough disk space to complete this operation"
msgstr "Waarschuwing: Niet genoeg opslagruimte om deze handeling te voltooien"

#: app/flatpak-cli-transaction.c:548
msgid "Error: Not enough disk space to complete this operation"
msgstr "Fout: Niet genoeg opslagruimte om deze handeling te voltooien"

#: app/flatpak-cli-transaction.c:553
#, c-format
msgid "Warning: %s"
msgstr "Waarschuwing: %s"

#: app/flatpak-cli-transaction.c:555
#, c-format
msgid "Error: %s"
msgstr "Fout: %s"

#: app/flatpak-cli-transaction.c:570
#, c-format
msgid "Failed to install %s%s%s: "
msgstr "%s%s%s installeren mislukt: "

#: app/flatpak-cli-transaction.c:577
#, c-format
msgid "Failed to update %s%s%s: "
msgstr "%s%s%s bijwerken mislukt: "

#: app/flatpak-cli-transaction.c:584
#, c-format
msgid "Failed to install bundle %s%s%s: "
msgstr "Bundel %s%s%s installeren mislukt: "

#: app/flatpak-cli-transaction.c:591
#, c-format
msgid "Failed to uninstall %s%s%s: "
msgstr "%s%s%s verwijderen mislukt: "

#: app/flatpak-cli-transaction.c:642
#, c-format
msgid "Authentication required for remote '%s'\n"
msgstr "Authenticatie vereist voor remote ‘%s’\n"

#: app/flatpak-cli-transaction.c:643
msgid "Open browser?"
msgstr "Browser openen?"

#: app/flatpak-cli-transaction.c:699
#, c-format
msgid "Login required remote %s (realm %s)\n"
msgstr "Inloggen vereist de remote %s (rijk %s)\n"

#: app/flatpak-cli-transaction.c:704
msgid "Password"
msgstr "Wachtwoord"

#. Only runtimes can be pinned
#: app/flatpak-cli-transaction.c:759
#, c-format
msgid ""
"\n"
"Info: (pinned) runtime %s%s%s branch %s%s%s is end-of-life, in favor of "
"%s%s%s branch %s%s%s\n"
msgstr ""
"\n"
"Info: (gepinde) runtime %s%s%s branch %s%s%s is end-of-life en is vervangen "
"door %s%s%s branch %s%s%s\n"

#: app/flatpak-cli-transaction.c:765
#, c-format
msgid ""
"\n"
"Info: runtime %s%s%s branch %s%s%s is end-of-life, in favor of %s%s%s branch "
"%s%s%s\n"
msgstr ""
"\n"
"Info: runtime %s%s%s branch %s%s%s is end-of-life en is vervangen door "
"%s%s%s branch %s%s%s\n"

#: app/flatpak-cli-transaction.c:768
#, c-format
msgid ""
"\n"
"Info: app %s%s%s branch %s%s%s is end-of-life, in favor of %s%s%s branch "
"%s%s%s\n"
msgstr ""
"\n"
"Info: app %s%s%s branch %s%s%s is end-of-life en is vervangen door %s%s%s "
"branch %s%s%s\n"

#. Only runtimes can be pinned
#: app/flatpak-cli-transaction.c:780
#, c-format
msgid ""
"\n"
"Info: (pinned) runtime %s%s%s branch %s%s%s is end-of-life, with reason:\n"
msgstr ""
"\n"
"Info: (gepinde) runtime %s%s%s branch %s%s%s is end-of-life, met reden:\n"

#: app/flatpak-cli-transaction.c:786
#, c-format
msgid ""
"\n"
"Info: runtime %s%s%s branch %s%s%s is end-of-life, with reason:\n"
msgstr ""
"\n"
"Info: runtime %s%s%s branch %s%s%s is end-of-life, met reden:\n"

#: app/flatpak-cli-transaction.c:789
#, c-format
msgid ""
"\n"
"Info: app %s%s%s branch %s%s%s is end-of-life, with reason:\n"
msgstr ""
"\n"
"Info: app %s%s%s branch %s%s%s is end-of-life, met reden:\n"

#: app/flatpak-cli-transaction.c:963
#, c-format
msgid "Info: applications using this extension:\n"
msgstr "Info: toepassingen die deze extensie gebruiken:\n"

#: app/flatpak-cli-transaction.c:965
#, c-format
msgid "Info: applications using this runtime:\n"
msgstr "Info: toepassingen die deze runtime gebruiken:\n"

#: app/flatpak-cli-transaction.c:984
msgid "Replace?"
msgstr "Vervangen?"

#: app/flatpak-cli-transaction.c:987 app/flatpak-quiet-transaction.c:247
#, c-format
msgid "Updating to rebased version\n"
msgstr "Bijwerken naar de gerebasede versie\n"

#: app/flatpak-cli-transaction.c:1011
#, c-format
msgid "Failed to rebase %s to %s: "
msgstr "%s naar %s rebasen mislukt"

#: app/flatpak-cli-transaction.c:1277
#, c-format
msgid "New %s%s%s permissions:"
msgstr "Nieuwe rechten van %s%s%s:"

#: app/flatpak-cli-transaction.c:1279
#, c-format
msgid "%s%s%s permissions:"
msgstr "Rechten van %s%s%s:"

#: app/flatpak-cli-transaction.c:1343
msgid "Warning: "
msgstr "Waarschuwing: "

#. translators: This is short for operation, the title of a one-char column
#: app/flatpak-cli-transaction.c:1442
msgid "Op"
msgstr "Op"

#. Avoid resizing the download column too much,
#. * by making the title as long as typical content
#.
#: app/flatpak-cli-transaction.c:1458 app/flatpak-cli-transaction.c:1503
msgid "partial"
msgstr "deels"

#: app/flatpak-cli-transaction.c:1535
msgid "Proceed with these changes to the user installation?"
msgstr "Deze wijzigingen doorzetten in de gebruikersinstallatie?"

#: app/flatpak-cli-transaction.c:1537
msgid "Proceed with these changes to the system installation?"
msgstr "Deze wijzigingen doorzetten in de systeeminstallatie?"

#: app/flatpak-cli-transaction.c:1539
#, c-format
msgid "Proceed with these changes to the %s?"
msgstr "Deze wijzigingen doorzetten in de %s?"

# Ik heb de punten hier weggelaten voor consistentie met de rest van de mededelingen  - Philip
#: app/flatpak-cli-transaction.c:1711
msgid "Changes complete."
msgstr "Veranderingen voltooid"

#: app/flatpak-cli-transaction.c:1713
msgid "Uninstall complete."
msgstr "De-installatie voltooid"

#: app/flatpak-cli-transaction.c:1715
msgid "Installation complete."
msgstr "Installatie voltooid"

#: app/flatpak-cli-transaction.c:1717
msgid "Updates complete."
msgstr "Updates voltooid"

#. For updates/!stop_on_first_error we already printed all errors so we make up
#. a different one.
#: app/flatpak-cli-transaction.c:1750
msgid "There were one or more errors"
msgstr "Er waren één of meerdere fouten"

#. translators: please keep the leading space
#: app/flatpak-main.c:76
msgid " Manage installed applications and runtimes"
msgstr "Geïnstalleerde toepassingen en runtimes beheren"

#: app/flatpak-main.c:77
msgid "Install an application or runtime"
msgstr "Toepassing of runtime installeren"

#: app/flatpak-main.c:78
msgid "Update an installed application or runtime"
msgstr "Geïnstalleerde toepassing of runtime bijwerken"

#: app/flatpak-main.c:81
msgid "Uninstall an installed application or runtime"
msgstr "Geïnstalleerde toepassing of runtime de-installeren"

#: app/flatpak-main.c:84
msgid "Mask out updates and automatic installation"
msgstr "Updates en automatische installatie verhullen"

#: app/flatpak-main.c:85
msgid "Pin a runtime to prevent automatic removal"
msgstr "Runtime vastpinnen om automatische verwijdering tegen te gaan"

#: app/flatpak-main.c:86
msgid "List installed apps and/or runtimes"
msgstr "Geïnstalleerde toepassingen en/of runtimes opsommen"

#: app/flatpak-main.c:87
msgid "Show info for installed app or runtime"
msgstr "Info over geïnstalleerde toepassing of runtime tonen"

#: app/flatpak-main.c:88
msgid "Show history"
msgstr "Geschiedenis tonen"

#: app/flatpak-main.c:89
msgid "Configure flatpak"
msgstr "Flatpak configureren"

#: app/flatpak-main.c:90
msgid "Repair flatpak installation"
msgstr "Flatpak-installatie herstellen"

#: app/flatpak-main.c:91
msgid "Put applications or runtimes onto removable media"
msgstr "Toepassingen of runtimes op verwijderbare media plaatsen"

#: app/flatpak-main.c:92
msgid "Install flatpaks that are part of the operating system"
msgstr ""

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:95
msgid ""
"\n"
" Find applications and runtimes"
msgstr ""
"\n"
" Zoeken naar toepassingen en runtimes"

#: app/flatpak-main.c:96
msgid "Search for remote apps/runtimes"
msgstr "Zoeken naar toepassingen/runtimes van remote"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:99
msgid ""
"\n"
" Manage running applications"
msgstr ""
"\n"
" Draaiende toepassingen beheren"

#: app/flatpak-main.c:100
msgid "Run an application"
msgstr "Toepassing starten"

#: app/flatpak-main.c:101
msgid "Override permissions for an application"
msgstr "Rechten voor een toepassing overschrijven"

#: app/flatpak-main.c:102
msgid "Specify default version to run"
msgstr "Standaardversie opgeven om uit te voeren"

#: app/flatpak-main.c:103
msgid "Enter the namespace of a running application"
msgstr "Namespace van een draaiende toepassing betreden"

#: app/flatpak-main.c:104
msgid "Enumerate running applications"
msgstr "Draaiende toepassingen opsommen"

#: app/flatpak-main.c:105
msgid "Stop a running application"
msgstr "Draaiende toepassing stoppen"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:108
msgid ""
"\n"
" Manage file access"
msgstr ""
"\n"
"Bestandstoegang beheren"

#: app/flatpak-main.c:109
msgid "List exported files"
msgstr "Geëxporteerde bestanden opsommen"

#: app/flatpak-main.c:110
msgid "Grant an application access to a specific file"
msgstr "Toepassing toegang geven tot een specifiek bestand"

#: app/flatpak-main.c:111
msgid "Revoke access to a specific file"
msgstr "Toegang tot een specifiek bestand intrekken"

#: app/flatpak-main.c:112
msgid "Show information about a specific file"
msgstr "Informatie tonen over specifiek bestand"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:116
msgid ""
"\n"
" Manage dynamic permissions"
msgstr ""
"\n"
"Dynamische rechten beheren"

#: app/flatpak-main.c:117
msgid "List permissions"
msgstr "Rechten opsommen"

#: app/flatpak-main.c:118
msgid "Remove item from permission store"
msgstr "Item van rechtenopslag verwijderen"

#: app/flatpak-main.c:120
msgid "Set permissions"
msgstr "Rechten instellen"

#: app/flatpak-main.c:121
msgid "Show app permissions"
msgstr "Toepassingsrechten tonen"

#: app/flatpak-main.c:122
msgid "Reset app permissions"
msgstr "Toepassingsrechten resetten"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:125
msgid ""
"\n"
" Manage remote repositories"
msgstr ""
"\n"
" Externe pakketbronnen beheren"

#: app/flatpak-main.c:126
msgid "List all configured remotes"
msgstr "Alle geconfigureerde remotes opsommen"

#: app/flatpak-main.c:127
msgid "Add a new remote repository (by URL)"
msgstr "Nieuwe externe pakketbron toevoegen (als URL)"

#: app/flatpak-main.c:128
msgid "Modify properties of a configured remote"
msgstr "Eigenschappen bewerken van een geconfigureerde remote"

#: app/flatpak-main.c:129
msgid "Delete a configured remote"
msgstr "Geconfigureerde remote verwijderen"

#: app/flatpak-main.c:131
msgid "List contents of a configured remote"
msgstr "Inhoud van een geconfigureerde remote opsommen"

#: app/flatpak-main.c:132
msgid "Show information about a remote app or runtime"
msgstr "Informatie over een externe toepassing of runtime tonen"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:135
msgid ""
"\n"
" Build applications"
msgstr ""
"\n"
" Toepassingen bouwen"

#: app/flatpak-main.c:136
msgid "Initialize a directory for building"
msgstr "Map initialiseren voor compilatie"

#: app/flatpak-main.c:137
msgid "Run a build command inside the build dir"
msgstr "Opdracht uitvoeren in de compilatiemap"

#: app/flatpak-main.c:138
msgid "Finish a build dir for export"
msgstr "Compilatiemap voltooien voor export"

#: app/flatpak-main.c:139
msgid "Export a build dir to a repository"
msgstr "Compilatiemap exporteren naar een pakketbron"

#: app/flatpak-main.c:140
msgid "Create a bundle file from a ref in a local repository"
msgstr "Bundelbestand aanmaken vanuit een ref in een lokale pakketbron"

#: app/flatpak-main.c:141
msgid "Import a bundle file"
msgstr "Bundelbestand importeren"

#: app/flatpak-main.c:142
msgid "Sign an application or runtime"
msgstr "Toepassing of runtime ondertekenen"

#: app/flatpak-main.c:143
msgid "Update the summary file in a repository"
msgstr "Samenvattingsbestand in een pakketbron bijwerken"

#: app/flatpak-main.c:144
msgid "Create new commit based on existing ref"
msgstr "Nieuwe commit aanmaken gebaseerd op bestaande ref"

#: app/flatpak-main.c:145
msgid "Show information about a repo"
msgstr "Informatie over een pakketbron tonen"

#: app/flatpak-main.c:162
msgid "Show debug information, -vv for more detail"
msgstr "Foutopsporingsinformatie tonen, -vv voor meer details"

#: app/flatpak-main.c:163
msgid "Show OSTree debug information"
msgstr "OSTree-foutopsporingsinformatie tonen"

#: app/flatpak-main.c:169
msgid "Print version information and exit"
msgstr "Versie-informatie tonen en afsluiten"

#: app/flatpak-main.c:170
msgid "Print default arch and exit"
msgstr "Standaardarchitectuur tonen en sluiten"

#: app/flatpak-main.c:171
msgid "Print supported arches and exit"
msgstr "Ondersteunde architecturen afdrukken en sluiten"

#: app/flatpak-main.c:172
msgid "Print active gl drivers and exit"
msgstr "Actieve GL-drivers tonen en sluiten"

#: app/flatpak-main.c:173
msgid "Print paths for system installations and exit"
msgstr "Paden voor systeeminstallaties tonen en sluiten"

#: app/flatpak-main.c:174
msgid "Print the updated environment needed to run flatpaks"
msgstr "Bijgewerkte omgeving benodigd om Flatpaks uit te voeren tonen"

#: app/flatpak-main.c:175
msgid "Only include the system installation with --print-updated-env"
msgstr "Enkel de systeeminstallatie toevoegen met --print-updated-env"

#: app/flatpak-main.c:180
msgid "Work on the user installation"
msgstr "Werken met de gebruikersinstallatie"

#: app/flatpak-main.c:181
msgid "Work on the system-wide installation (default)"
msgstr "Werken met de systeembrede installatie (standaard)"

#: app/flatpak-main.c:182
msgid "Work on a non-default system-wide installation"
msgstr "Werken met een niet-standaard systeembrede installatie"

#: app/flatpak-main.c:212
msgid "Builtin Commands:"
msgstr "Ingebouwde opdrachten:"

#: app/flatpak-main.c:298
#, c-format
msgid ""
"Note that the directories %s are not in the search path set by the "
"XDG_DATA_DIRS environment variable, so applications installed by Flatpak may "
"not appear on your desktop until the session is restarted."
msgstr ""
"Houd er rekening mee dat de mappen %s niet in het zoekpad staan dat is "
"ingesteld via de omgevingsvariabele XDG_DATA_DIRS. Hierdoor verschijnen door "
"Flatpak geïnstalleerde toepassingen mogelijk niet op je bureaublad totdat je "
"de sessie opnieuw start."

#: app/flatpak-main.c:312
#, c-format
msgid ""
"Note that the directory %s is not in the search path set by the "
"XDG_DATA_DIRS environment variable, so applications installed by Flatpak may "
"not appear on your desktop until the session is restarted."
msgstr ""
"Houd er rekening mee dat de map %s niet in het zoekpad staat dat is "
"ingesteld via de omgevingsvariabele XDG_DATA_DIRS. Hierdoor verschijnen door "
"Flatpak geïnstalleerde toepassingen mogelijk niet op je bureaublad totdat je "
"de sessie opnieuw start."

#: app/flatpak-main.c:381
msgid ""
"Refusing to operate under sudo with --user. Omit sudo to operate on the user "
"installation, or use a root shell to operate on the root user's installation."
msgstr ""
"--user kan niet worden gebruikt met sudo. Laat sudo weg om met de "
"gebruikersinstallatie te werken, of gebruik een root-shell voor die van de "
"rootgebruiker."

#: app/flatpak-main.c:453
msgid ""
"Multiple installations specified for a command that works on one installation"
msgstr ""
"Meerdere installaties opgegeven voor een commando dat werkt met één "
"installatie"

#: app/flatpak-main.c:504 app/flatpak-main.c:697
#, c-format
msgid "See '%s --help'"
msgstr "Zie ‘%s --help’"

#: app/flatpak-main.c:706
#, c-format
msgid "'%s' is not a flatpak command. Did you mean '%s%s'?"
msgstr "‘%s’ is geen flatpak-opdracht. Bedoelde u ‘%s%s’?"

#: app/flatpak-main.c:709
#, c-format
msgid "'%s' is not a flatpak command"
msgstr "‘%s’ is geen flatpak-opdracht"

#: app/flatpak-main.c:824
msgid "No command specified"
msgstr "Geen opdracht opgegeven"

#: app/flatpak-main.c:980
msgid "error:"
msgstr "fout:"

#: app/flatpak-quiet-transaction.c:77
#, c-format
msgid "Installing %s\n"
msgstr "%s installeren\n"

#: app/flatpak-quiet-transaction.c:81
#, c-format
msgid "Updating %s\n"
msgstr "%s bijwerken\n"

#: app/flatpak-quiet-transaction.c:85
#, c-format
msgid "Uninstalling %s\n"
msgstr "%s de-installeren\n"

#: app/flatpak-quiet-transaction.c:107
#, c-format
msgid "Warning: Failed to install %s: %s\n"
msgstr "Waarschuwing: %s installeren mislukt: %s\n"

#: app/flatpak-quiet-transaction.c:110
#, c-format
msgid "Error: Failed to install %s: %s\n"
msgstr "Fout: %s installeren mislukt: %s\n"

#: app/flatpak-quiet-transaction.c:116
#, c-format
msgid "Warning: Failed to update %s: %s\n"
msgstr "Waarschuwing: %s bijwerken mislukt: %s\n"

#: app/flatpak-quiet-transaction.c:119
#, c-format
msgid "Error: Failed to update %s: %s\n"
msgstr "Fout: %s bijwerken mislukt: %s\n"

#: app/flatpak-quiet-transaction.c:125
#, c-format
msgid "Warning: Failed to install bundle %s: %s\n"
msgstr "Waarschuwing: Bundel %s installeren mislukt: %s\n"

#: app/flatpak-quiet-transaction.c:128
#, c-format
msgid "Error: Failed to install bundle %s: %s\n"
msgstr "Fout: Bundel %s installeren mislukt: %s\n"

#: app/flatpak-quiet-transaction.c:134
#, c-format
msgid "Warning: Failed to uninstall %s: %s\n"
msgstr "Waarschuwing: %s de-installeren mislukt: %s\n"

#: app/flatpak-quiet-transaction.c:137
#, c-format
msgid "Error: Failed to uninstall %s: %s\n"
msgstr "Fout: %s de-installeren mislukt: %s\n"

#: app/flatpak-quiet-transaction.c:166 common/flatpak-dir.c:11475
#, c-format
msgid "%s already installed"
msgstr "%s al geïnstalleerd"

#: app/flatpak-quiet-transaction.c:168 common/flatpak-dir.c:3622
#: common/flatpak-dir.c:4321 common/flatpak-dir.c:16968
#: common/flatpak-dir.c:17258 common/flatpak-dir-utils.c:166
#: common/flatpak-dir-utils.c:259 common/flatpak-transaction.c:2736
#: common/flatpak-transaction.c:2791
#, c-format
msgid "%s not installed"
msgstr "%s niet geïnstalleerd"

#: app/flatpak-quiet-transaction.c:170
#, c-format
msgid "%s needs a later flatpak version"
msgstr "%s vereist een nieuwere flatpak-versie"

#: app/flatpak-quiet-transaction.c:172
msgid "Not enough disk space to complete this operation"
msgstr "Niet genoeg opslagruimte om deze handeling te voltooien"

#: app/flatpak-quiet-transaction.c:239
#, c-format
msgid "Info: %s is end-of-life, in favor of %s\n"
msgstr "Info: %s is end-of-life, en wordt vervangen door %s\n"

#: app/flatpak-quiet-transaction.c:241
#, c-format
msgid "Info: %s is end-of-life, with reason: %s\n"
msgstr "Info: %s is end-of-life, met reden: %s\n"

#: app/flatpak-quiet-transaction.c:251
#, c-format
msgid "Failed to rebase %s to %s: %s\n"
msgstr "Rebasen van %s naar %s mislukt %s\n"

#: common/flatpak-auth.c:58
#, c-format
msgid "No authenticator configured for remote `%s`"
msgstr "Geen authenticator voor remote ‘%s’ geconfigureerd"

#: common/flatpak-context.c:637 common/flatpak-context.c:649
#, fuzzy, c-format
msgid "Invalid permission syntax: %s"
msgstr "Ongeldige uitbreidingsnaam %s"

#: common/flatpak-context.c:1207
#, c-format
msgid "Unknown share type %s, valid types are: %s"
msgstr "Onbekend deeltype %s, geldige types zijn: %s"

#: common/flatpak-context.c:1228
#, c-format
msgid "Unknown policy type %s, valid types are: %s"
msgstr "Onbekend beleidstype %s, geldige types zijn: %s"

#: common/flatpak-context.c:1266
#, c-format
msgid "Invalid dbus name %s"
msgstr "Ongeldige D-Bus-naam %s"

#: common/flatpak-context.c:1279
#, c-format
msgid "Unknown socket type %s, valid types are: %s"
msgstr "Onbekend socket-type %s, geldige types zijn: %s"

#: common/flatpak-context.c:1294
#, c-format
msgid "Unknown device type %s, valid types are: %s"
msgstr "Onbekend apparaattype %s, geldige types zijn: %s"

#: common/flatpak-context.c:1308
#, c-format
msgid "Unknown feature type %s, valid types are: %s"
msgstr "Onbekend functietype %s, geldige types zijn: %s"

#: common/flatpak-context.c:1840
#, c-format
msgid "Filesystem location \"%s\" contains \"..\""
msgstr "Bestandssysteemlocatie ‘%s’ bevat ‘..’"

#: common/flatpak-context.c:1882
#, c-format
msgid ""
"--filesystem=/ is not available, use --filesystem=host for a similar result"
msgstr ""
"--filesystem=/ is niet beschikbaar; gebruik --filesystem=host voor een "
"vergelijkbaar resultaat"

#: common/flatpak-context.c:1916
#, fuzzy, c-format
msgid ""
"Unknown filesystem location %s, valid locations are: host, host-os, host-"
"etc, host-root, home, xdg-*[/…], ~/dir, /dir"
msgstr ""
"Onbekende bestandssysteemlocatie %s; geldige locaties zijn: host, host-os, "
"host-etc, home, xdg-*[/…], ~/dir, /dir"

#: common/flatpak-context.c:2015
#, fuzzy, c-format
msgid "Invalid syntax for %s: %s"
msgstr "Ongeldige naam %s: %s"

#: common/flatpak-context.c:2142
#, c-format
msgid "fallback-x11 can not be conditional"
msgstr ""

#: common/flatpak-context.c:2318
#, c-format
msgid "Invalid env format %s"
msgstr "Ongeldig omgevingsformaat %s"

#: common/flatpak-context.c:2399
#, c-format
msgid "Environment variable name must not contain '=': %s"
msgstr "Naam van omgevingsvariabele mag geen '=' bevatten: %s"

#: common/flatpak-context.c:2527 common/flatpak-context.c:2535
#, c-format
msgid "--add-policy arguments must be in the form SUBSYSTEM.KEY=VALUE"
msgstr ""
"Argumenten voor --add-policy moeten in het formaat SUBSYSTEEM.SLEUTEL=WAARDE "
"zijn"

#: common/flatpak-context.c:2542
#, c-format
msgid "--add-policy values can't start with \"!\""
msgstr "Waarden voor --add-policy kunnen niet beginnen met \"!\""

#: common/flatpak-context.c:2567 common/flatpak-context.c:2575
#, c-format
msgid "--remove-policy arguments must be in the form SUBSYSTEM.KEY=VALUE"
msgstr ""
"Argumenten voor --remove-policy moeten in het formaat "
"SUBSYSTEEM.SLEUTEL=WAARDE zijn"

#: common/flatpak-context.c:2582
#, c-format
msgid "--remove-policy values can't start with \"!\""
msgstr "Waarden voor --remove-policy kunnen niet beginnen met \"!\""

#: common/flatpak-context.c:2657
msgid "Share with host"
msgstr "Delen met host"

#: common/flatpak-context.c:2657 common/flatpak-context.c:2658
msgid "SHARE"
msgstr "DELEN"

#: common/flatpak-context.c:2658
msgid "Unshare with host"
msgstr "Niet meer delen met host"

#: common/flatpak-context.c:2659
msgid "Require conditions to be met for a subsystem to get shared"
msgstr ""

#: common/flatpak-context.c:2659
msgid "SHARE:CONDITION"
msgstr ""

#: common/flatpak-context.c:2660
msgid "Expose socket to app"
msgstr "Socket blootstellen aan toepassing"

#: common/flatpak-context.c:2660 common/flatpak-context.c:2661
msgid "SOCKET"
msgstr "SOCKET"

#: common/flatpak-context.c:2661
msgid "Don't expose socket to app"
msgstr "Socket niet blootstellen aan toepassing"

#: common/flatpak-context.c:2662
msgid "Require conditions to be met for a socket to get exposed"
msgstr ""

#: common/flatpak-context.c:2662
msgid "SOCKET:CONDITION"
msgstr ""

#: common/flatpak-context.c:2663
msgid "Expose device to app"
msgstr "Apparaat blootstellen aan toepassing"

#: common/flatpak-context.c:2663 common/flatpak-context.c:2664
msgid "DEVICE"
msgstr "APPARAAT"

#: common/flatpak-context.c:2664
msgid "Don't expose device to app"
msgstr "Apparaat niet blootstellen aan toepassing"

#: common/flatpak-context.c:2665
msgid "Require conditions to be met for a device to get exposed"
msgstr ""

#: common/flatpak-context.c:2665
msgid "DEVICE:CONDITION"
msgstr ""

#: common/flatpak-context.c:2666
msgid "Allow feature"
msgstr "Functie toestaan"

#: common/flatpak-context.c:2666 common/flatpak-context.c:2667
msgid "FEATURE"
msgstr "FUNCTIE"

#: common/flatpak-context.c:2667
msgid "Don't allow feature"
msgstr "Functie niet toestaan"

#: common/flatpak-context.c:2668
msgid "Require conditions to be met for a feature to get allowed"
msgstr ""

#: common/flatpak-context.c:2668
msgid "FEATURE:CONDITION"
msgstr ""

#: common/flatpak-context.c:2669
msgid "Expose filesystem to app (:ro for read-only)"
msgstr "Apparaat blootstellen aan toepassing (:ro voor alleen-lezen)"

#: common/flatpak-context.c:2669
msgid "FILESYSTEM[:ro]"
msgstr "BESTANDSSYSTEEM[:ro]"

#: common/flatpak-context.c:2670
msgid "Don't expose filesystem to app"
msgstr "Bestandssysteem niet aan toepassing blootstellen"

#: common/flatpak-context.c:2670
msgid "FILESYSTEM"
msgstr "BESTANDSSYSTEEM"

#: common/flatpak-context.c:2671
msgid "Set environment variable"
msgstr "Omgevingsvariabele instellen"

#: common/flatpak-context.c:2671
msgid "VAR=VALUE"
msgstr "VAR=WAARDE"

#: common/flatpak-context.c:2672
msgid "Read environment variables in env -0 format from FD"
msgstr "Lees omgevingsvariabelen in ‘env -0’-formaat vanaf FD"

#: common/flatpak-context.c:2673
msgid "Remove variable from environment"
msgstr "Variabele verwijderen uit omgeving"

#: common/flatpak-context.c:2673
msgid "VAR"
msgstr "VAR"

#: common/flatpak-context.c:2674
msgid "Allow app to own name on the session bus"
msgstr "Sta app toe naam te bezitten op de sessiebus"

#: common/flatpak-context.c:2674 common/flatpak-context.c:2675
#: common/flatpak-context.c:2676 common/flatpak-context.c:2677
#: common/flatpak-context.c:2678 common/flatpak-context.c:2679
#: common/flatpak-context.c:2680
msgid "DBUS_NAME"
msgstr "DBUS-NAAM"

#: common/flatpak-context.c:2675
msgid "Allow app to talk to name on the session bus"
msgstr "Sta app toe om met naam te communiceren op de sessiebus"

#: common/flatpak-context.c:2676
msgid "Don't allow app to talk to name on the session bus"
msgstr "Sta app niet toe om met naam te communiceren op de sessiebus"

#: common/flatpak-context.c:2677
msgid "Allow app to own name on the system bus"
msgstr "Sta app toe om naam te bezitten op de systeembus"

#: common/flatpak-context.c:2678
msgid "Allow app to talk to name on the system bus"
msgstr "Sta app toe om te communiceren met naam op de systeembus"

#: common/flatpak-context.c:2679
msgid "Don't allow app to talk to name on the system bus"
msgstr "Sta app niet toe om te communiceren met naam op de systeembus"

#: common/flatpak-context.c:2680
msgid "Allow app to own name on the a11y bus"
msgstr "Sta app toe om naam te bezitten op de toegankelijkheidsbus"

#: common/flatpak-context.c:2681
msgid "Add generic policy option"
msgstr "Voeg generieke beleidoptie toe"

#: common/flatpak-context.c:2681 common/flatpak-context.c:2682
msgid "SUBSYSTEM.KEY=VALUE"
msgstr "SUBSYSTEEM.SLEUTEL=WAARDE"

#: common/flatpak-context.c:2682
msgid "Remove generic policy option"
msgstr "Algemeen beleidoptie verwijderen"

#: common/flatpak-context.c:2683
msgid "Add USB device to enumerables"
msgstr "Voeg USB-apparaat toe aan lijst van enumereerbare USB-apparaten"

#: common/flatpak-context.c:2683 common/flatpak-context.c:2684
msgid "VENDOR_ID:PRODUCT_ID"
msgstr "LEVERANCIER_ID:PRODUCT_ID"

#: common/flatpak-context.c:2684
msgid "Add USB device to hidden list"
msgstr "Voeg USB-apparaat toe aan lijst met verborgen apparaten"

#: common/flatpak-context.c:2685
msgid "A list of USB devices that are enumerable"
msgstr "Lijst van enumereerbare USB-apparaten"

#: common/flatpak-context.c:2685
msgid "LIST"
msgstr "LIJST"

#: common/flatpak-context.c:2686
msgid "File containing a list of USB devices to make enumerable"
msgstr "Bestand met een lijst van USB-apparaten om enumereerbaar te maken"

#: common/flatpak-context.c:2686 common/flatpak-context.c:2687
msgid "FILENAME"
msgstr "BESTANDSNAAM"

#: common/flatpak-context.c:2687
msgid "Persist home directory subpath"
msgstr "Subpad van persoonlijke map behouden"

#. This is not needed/used anymore, so hidden, but we accept it for backwards compat
#: common/flatpak-context.c:2689
msgid "Don't require a running session (no cgroups creation)"
msgstr "Vereis geen actieve sessie (cgroups worden niet aangemaakt)"

#: common/flatpak-context.c:3718
#, c-format
msgid "Not replacing \"%s\" with tmpfs: %s"
msgstr "Kan ‘%s’ niet vervangen door tmpfs: %s"

#: common/flatpak-context.c:3726
#, c-format
msgid "Not sharing \"%s\" with sandbox: %s"
msgstr "Kan ‘%s’ niet delen met de sandbox: %s"

#. Even if the error is one that we would normally silence, like
#. * the path not existing, it seems reasonable to make more of a fuss
#. * about the home directory not existing or otherwise being unusable,
#. * so this is intentionally not using cannot_export()
#: common/flatpak-context.c:3828
#, c-format
msgid "Not allowing home directory access: %s"
msgstr "Geen toegang toegestaan tot thuismap: %s"

#: common/flatpak-context.c:4062
#, c-format
msgid "Unable to provide a temporary home directory in the sandbox: %s"
msgstr "Kan geen tijdelijke thuismap bieden in de sandbox: %s"

#: common/flatpak-dir.c:442
#, c-format
msgid "Configured collection ID ‘%s’ not in summary file"
msgstr ""
"Ingestelde collectie-ID ‘%s’ komt niet voor in het samenvattingsbestand"

#: common/flatpak-dir.c:587
#, c-format
msgid "Unable to load summary from remote %s: %s"
msgstr "Kan samenvatting van remote ‘%s’ niet laden: %s"

#: common/flatpak-dir.c:764 common/flatpak-dir.c:800 common/flatpak-dir.c:906
#, c-format
msgid "No such ref '%s' in remote %s"
msgstr "Ref ‘%s’ bestaat niet in remote ‘%s’"

# Ik snap deze foutmelding niet helemaal, letterlijk vertaald -Sijmen
#: common/flatpak-dir.c:891 common/flatpak-dir.c:1051 common/flatpak-dir.c:1080
#: common/flatpak-dir.c:1092
#, c-format
msgid "No entry for %s in remote %s summary flatpak cache"
msgstr "Geen item voor ‘%s’ in externe %s samenvattingsflatpak-cache"

#: common/flatpak-dir.c:1069
#, c-format
msgid "No summary or Flatpak cache available for remote %s"
msgstr "Geen samenvattings- of flatpak-cache beschikbaar voor remote ‘%s’"

#: common/flatpak-dir.c:1097
#, c-format
msgid "Missing xa.data in summary for remote %s"
msgstr "xa.data ontbreekt in samenvatting van remote ‘%s’"

#: common/flatpak-dir.c:1103 common/flatpak-dir.c:1546
#, c-format
msgid "Unsupported summary version %d for remote %s"
msgstr "Niet-ondersteunde samenvattingsversie %d voor remote %s"

#: common/flatpak-dir.c:1200
msgid "Remote OCI index has no registry uri"
msgstr "OCI-index van remote heeft geen registry-uri"

#: common/flatpak-dir.c:1261
#, c-format
msgid "Couldn't find ref %s in remote %s"
msgstr "Kon ref %s niet vinden in remote %s"

#: common/flatpak-dir.c:1288 common/flatpak-dir.c:1381
#, fuzzy, c-format
msgid "Commit has no requested ref ‘%s’ in ref binding metadata (found: ‘%s’)"
msgstr "Commit heeft geen gevraagde ref ‘%s’ in ref-binding-metadata"

#: common/flatpak-dir.c:1413
#, c-format
msgid "Configured collection ID ‘%s’ not in binding metadata"
msgstr "Ingestelde collectie-ID ‘%s’ niet in binding-metadata"

#: common/flatpak-dir.c:1449 common/flatpak-dir.c:5645
#, c-format
msgid "Couldn't find latest checksum for ref %s in remote %s"
msgstr "Kon nieuwste controlesom voor ref %s niet vinden in remote %s"

# Ik snap deze foutmelding niet helemaal, letterlijk vertaald -Sijmen
#: common/flatpak-dir.c:1516 common/flatpak-dir.c:1552
#, c-format
msgid "No entry for %s in remote %s summary flatpak sparse cache"
msgstr "Geen item voor ‘%s’ in externe %s samenvattingsflatpak-sparse-cache"

#: common/flatpak-dir.c:2540
#, c-format
msgid "Commit metadata for %s not matching expected metadata"
msgstr "Commit-metadata voor %s komt niet overeen met de verwachte metadata"

#: common/flatpak-dir.c:2823
msgid "Unable to connect to system bus"
msgstr "Kon niet verbinden met systeembus"

#: common/flatpak-dir.c:3419
msgid "User installation"
msgstr "Gebruikersinstallatie"

#: common/flatpak-dir.c:3426
#, c-format
msgid "System (%s) installation"
msgstr "Systeeminstallatie (%s)"

#: common/flatpak-dir.c:3472
#, c-format
msgid "No overrides found for %s"
msgstr "Geen overschrijvingen gevonden voor %s"

#: common/flatpak-dir.c:3625
#, c-format
msgid "%s (commit %s) not installed"
msgstr "%s (commit %s) niet geïnstalleerd"

#: common/flatpak-dir.c:4650
#, c-format
msgid "Error parsing system flatpakrepo file for %s: %s"
msgstr "Fout bij parsen van systeem-flatpakrepo-bestand voor %s : %s"

#: common/flatpak-dir.c:4735
#, c-format
msgid "While opening repository %s: "
msgstr "Bij het openen van pakketbron %s: "

#: common/flatpak-dir.c:5004
#, c-format
msgid "The config key %s is not set"
msgstr "De configuratiesleutel %s is niet ingesteld"

#: common/flatpak-dir.c:5140
#, c-format
msgid "No current %s pattern matching %s"
msgstr "Geen huidige %s-patroon dat overeenkomt met %s"

#: common/flatpak-dir.c:5422
msgid "No appstream commit to deploy"
msgstr "Geen appstream-commit om uit te rollen"

#: common/flatpak-dir.c:5941 common/flatpak-dir.c:7266
#: common/flatpak-dir.c:10881 common/flatpak-dir.c:11618
msgid "Can't pull from untrusted non-gpg verified remote"
msgstr "Kan niet van onvertrouwde, niet-gpg-geverifieerde remote"

#: common/flatpak-dir.c:6376 common/flatpak-dir.c:6591
msgid "Extra data not supported for non-gpg-verified local system installs"
msgstr ""
"Extra-data niet ondersteund voor niet-gpg-geverifieerde lokale "
"systeeminstallaties"

#: common/flatpak-dir.c:6415 common/flatpak-dir.c:6782
#, c-format
msgid "Invalid checksum for extra data uri %s"
msgstr "Ongeldige controlesom voor extra-data-uri %s"

#: common/flatpak-dir.c:6424
#, c-format
msgid "Empty name for extra data uri %s"
msgstr "Lege naam voor extra-data-uri %s"

#: common/flatpak-dir.c:6432
#, c-format
msgid "Unsupported extra data uri %s"
msgstr "Niet-ondersteunde extra-data-uri %s"

#: common/flatpak-dir.c:6461
#, c-format
msgid "Failed to load local extra-data %s: %s"
msgstr "Kon lokale extra-data %s niet laden: %s"

#: common/flatpak-dir.c:6469
#, c-format
msgid "Wrong size for extra-data %s"
msgstr "Onjuiste grootte voor extra-data %s"

#: common/flatpak-dir.c:6488
#, c-format
msgid "While downloading %s: "
msgstr "Tijdens het downloaden van %s: "

#: common/flatpak-dir.c:6498
#, c-format
msgid "Wrong size for extra data %s"
msgstr "Onjuiste grootte voor extra-data %s"

#: common/flatpak-dir.c:6507
#, c-format
msgid "Invalid checksum for extra data %s"
msgstr "Ongeldige controlesom voor extra-data %s"

#: common/flatpak-dir.c:7096 common/flatpak-dir.c:7349
#, c-format
msgid "While pulling %s from remote %s: "
msgstr "Tijdens het ophalen van %s van remote %s: "

#: common/flatpak-dir.c:7290 common/flatpak-repo-utils.c:3886
msgid "GPG signatures found, but none are in trusted keyring"
msgstr ""
"GPG-handtekeningen gevonden, maar geen daarvan staat in de vertrouwde "
"sleutelbos"

#: common/flatpak-dir.c:7307
#, c-format
msgid "Commit for ‘%s’ has no ref binding"
msgstr "Commit voor ‘%s’ heeft geen ref-binding"

#: common/flatpak-dir.c:7312
#, c-format
msgid "Commit for ‘%s’ is not in expected bound refs: %s"
msgstr "Commit voor ‘%s’ staat niet in verwachte bound-refs: %s"

#: common/flatpak-dir.c:7488
msgid "Only applications can be made current"
msgstr "Alleen toepassingen kunnen als huidig gemarkeerd worden"

#: common/flatpak-dir.c:8192
msgid "Not enough memory"
msgstr "Onvoldoende geheugen"

#: common/flatpak-dir.c:8211
msgid "Failed to read from exported file"
msgstr "Lezen van geëxporteerd bestand mislukt"

#: common/flatpak-dir.c:8401
msgid "Error reading mimetype xml file"
msgstr "Fout bij lezen mimetype-XML-bestand"

#: common/flatpak-dir.c:8406
msgid "Invalid mimetype xml file"
msgstr "Ongeldig mimetype-XML-bestand"

#: common/flatpak-dir.c:8492
#, c-format
msgid "D-Bus service file '%s' has wrong name"
msgstr "D-Bus-servicebestand ‘%s’ heeft een ongeldige naam"

#: common/flatpak-dir.c:8647
#, c-format
msgid "Invalid Exec argument %s"
msgstr "Ongeldig Exec-argument %s"

#: common/flatpak-dir.c:9115
msgid "While getting detached metadata: "
msgstr "Tijdens het ophalen van losgekoppelde metadata: "

#: common/flatpak-dir.c:9120 common/flatpak-dir.c:9125
#: common/flatpak-dir.c:9129
msgid "Extra data missing in detached metadata"
msgstr "Extra-data ontbreekt in losgekoppelde metadata"

#: common/flatpak-dir.c:9133
msgid "While creating extradir: "
msgstr "Tijdens het aanmaken van extradir: "

#: common/flatpak-dir.c:9154 common/flatpak-dir.c:9187
msgid "Invalid checksum for extra data"
msgstr "Ongeldige controlesom voor extra-data"

#: common/flatpak-dir.c:9183
msgid "Wrong size for extra data"
msgstr "Incorrecte grootte voor extra-data"

#: common/flatpak-dir.c:9196
#, c-format
msgid "While writing extra data file '%s': "
msgstr "Tijdens het wegschrijven van extra-data-bestand ‘%s’: "

#: common/flatpak-dir.c:9204
#, c-format
msgid "Extra data %s missing in detached metadata"
msgstr "Extra-data %s ontbreekt in losgekoppelde metadata"

#: common/flatpak-dir.c:9278
#, fuzzy, c-format
msgid "Unable to get runtime key from metadata"
msgstr "Alternatief bestand voor metadata gebruiken"

#: common/flatpak-dir.c:9402
#, c-format
msgid "apply_extra script failed, exit status %d"
msgstr "apply_extra-script is mislukt, afsluitstatus %d"

#. Translators: The placeholder is for an app ref.
#: common/flatpak-dir.c:9591
#, c-format
msgid "Installing %s is not allowed by the policy set by your administrator"
msgstr ""
"Het installeren van %s is niet toegestaan volgens het beleid dat door de "
"systeembeheerder is ingesteld"

#: common/flatpak-dir.c:9690
#, c-format
msgid "While trying to resolve ref %s: "
msgstr "Bij het proberen op te lossen van ref %s: "

#: common/flatpak-dir.c:9702
#, c-format
msgid "%s is not available"
msgstr "%s is niet beschikbaar"

#: common/flatpak-dir.c:9714 common/flatpak-dir.c:11495
#, c-format
msgid "%s commit %s already installed"
msgstr "%s commit %s is al geïnstalleerd"

#: common/flatpak-dir.c:9721
msgid "Can't create deploy directory"
msgstr "Kan geen lege uitrolmap aanmaken"

#: common/flatpak-dir.c:9729
#, c-format
msgid "Failed to read commit %s: "
msgstr "Lezen van commit %s is mislukt: "

#: common/flatpak-dir.c:9750
#, c-format
msgid "While trying to checkout %s into %s: "
msgstr "Tijdens het proberen uit te checken van %s naar %s: "

#: common/flatpak-dir.c:9769
msgid "While trying to checkout metadata subpath: "
msgstr "Tijdens het proberen uit te checken van het metadata-subpad: "

#: common/flatpak-dir.c:9801
#, c-format
msgid "While trying to checkout subpath ‘%s’: "
msgstr "Tijdens het proberen uit te checken van subpad ‘%s’: "

#: common/flatpak-dir.c:9811
msgid "While trying to remove existing extra dir: "
msgstr "Tijdens het proberen te verwijderen van bestaande extra-map: "

#: common/flatpak-dir.c:9822
msgid "While trying to apply extra data: "
msgstr "Tijdens het proberen toe te passen van extra-data: "

#: common/flatpak-dir.c:9849
#, c-format
msgid "Invalid commit ref %s: "
msgstr "Ongeldige commit-ref %s: "

#: common/flatpak-dir.c:9857 common/flatpak-dir.c:9869
#, c-format
msgid "Deployed ref %s does not match commit (%s)"
msgstr "Uitgerolde ref %s komt niet overeen met commit (%s)"

#: common/flatpak-dir.c:9863
#, c-format
msgid "Deployed ref %s branch does not match commit (%s)"
msgstr "Uitgerolde branch van ref %s komt niet overeen met commit (%s)"

#: common/flatpak-dir.c:10125 common/flatpak-installation.c:1911
#, c-format
msgid "%s branch %s already installed"
msgstr "%s-branch %s is al geïnstalleerd"

#: common/flatpak-dir.c:10985
#, c-format
msgid "Could not unmount revokefs-fuse filesystem at %s: "
msgstr "Kon revokefs-fuse-bestandssysteem op %s niet afkoppelen: "

#: common/flatpak-dir.c:11289
#, c-format
msgid "This version of %s is already installed"
msgstr "Deze versie van %s is al geïnstalleerd"

#: common/flatpak-dir.c:11302
#, c-format
msgid "Can't change remote during bundle install"
msgstr "Kan remote niet wijzigen tijdens bundelinstallatie"

#: common/flatpak-dir.c:11571
msgid "Can't update to a specific commit without root permissions"
msgstr "Kan niet bijewerken naar een specifieke commit zonder root-rechten"

#: common/flatpak-dir.c:11852
#, c-format
msgid "Can't remove %s, it is needed for: %s"
msgstr "Kan %s niet verwijderen; het is nodig voor: %s"

#: common/flatpak-dir.c:11912 common/flatpak-installation.c:2067
#, c-format
msgid "%s branch %s is not installed"
msgstr "%s-branch %s is niet geïnstalleerd"

#: common/flatpak-dir.c:12165
#, c-format
msgid "%s commit %s not installed"
msgstr "%s-commit %s is niet geïnstalleerd"

#: common/flatpak-dir.c:12501
#, c-format
msgid "Pruning repo failed: %s"
msgstr "Opruimen van pakketbron mislukt: %s"

#: common/flatpak-dir.c:12669 common/flatpak-dir.c:12675
#, c-format
msgid "Failed to load filter '%s'"
msgstr "Laden van filter ‘%s’ mislukt"

#: common/flatpak-dir.c:12681
#, c-format
msgid "Failed to parse filter '%s'"
msgstr "Parsen van filter ‘%s’ mislukt"

#: common/flatpak-dir.c:12963
msgid "Failed to write summary cache: "
msgstr "Wegschrijven van samenvattingscache mislukt: "

#: common/flatpak-dir.c:12982
#, c-format
msgid "No oci summary cached for remote '%s'"
msgstr "Geen oci-samenvatting gecachet voor remote ‘%s’"

#: common/flatpak-dir.c:13207
#, c-format
msgid "No cached summary for remote '%s'"
msgstr "Geen gecachete samenvatting voor remote ‘%s’"

#: common/flatpak-dir.c:13248
#, c-format
msgid "Invalid checksum for indexed summary %s read from %s"
msgstr ""
"Ongeldige controlesom voor de geïndexeerde samenvatting %s, gelezen vanaf %s"

#: common/flatpak-dir.c:13321
#, c-format
msgid ""
"Remote listing for %s not available; server has no summary file. Check the "
"URL passed to remote-add was valid."
msgstr ""
"Remote listing voor %s niet beschikbaar; server heeft geen "
"samenvattingsbestand. Controleer of de URL die aan remote-add is meegegeven "
"geldig is."

#: common/flatpak-dir.c:13698
#, c-format
msgid "Invalid checksum for indexed summary %s for remote '%s'"
msgstr ""
"Ongeldige controlesom voor geïndexeerde samenvatting %s voor remote ‘%s’"

#: common/flatpak-dir.c:14388
#, c-format
msgid "Multiple branches available for %s, you must specify one of: "
msgstr ""
"Meerdere branches beschikbaar voor %s. Er moet er één opgegeven worden uit: "

#: common/flatpak-dir.c:14454
#, c-format
msgid "Nothing matches %s"
msgstr "Geen overeenkomsten met %s"

#: common/flatpak-dir.c:14562
#, c-format
msgid "Can't find ref %s%s%s%s%s"
msgstr "Kan ref %s%s%s%s%s niet vinden"

#: common/flatpak-dir.c:14605
#, c-format
msgid "Error searching remote %s: %s"
msgstr "Fout bij zoeken in remote %s: %s"

#: common/flatpak-dir.c:14702
#, c-format
msgid "Error searching local repository: %s"
msgstr "Fout bij zoeken in lokale pakketbron: %s"

#: common/flatpak-dir.c:14839
#, c-format
msgid "%s/%s/%s not installed"
msgstr "%s/%s/%s niet geïnstalleerd"

#: common/flatpak-dir.c:15042
#, c-format
msgid "Could not find installation %s"
msgstr "Kon installatie van %s niet vinden"

#: common/flatpak-dir.c:15612
#, c-format
msgid "Invalid file format, no %s group"
msgstr "Ongeldig bestandsformaat, geen %s-groep"

#: common/flatpak-dir.c:15617 common/flatpak-repo-utils.c:2836
#, c-format
msgid "Invalid version %s, only 1 supported"
msgstr "Ongeldige versie %s, enkel 1 ondersteund"

#: common/flatpak-dir.c:15622 common/flatpak-dir.c:15627
#, c-format
msgid "Invalid file format, no %s specified"
msgstr "Ongeldig bestandsformaat, geen %s opgegeven"

#. Check some minimal size so we don't get crap
#: common/flatpak-dir.c:15647
msgid "Invalid file format, gpg key invalid"
msgstr "Ongeldig bestandsformaat, GPG-sleutel ongeldig"

#: common/flatpak-dir.c:15675 common/flatpak-repo-utils.c:2917
msgid "Collection ID requires GPG key to be provided"
msgstr "Verzamelings-ID vereist dat GPG-sleutel moet worden opgegeven"

#: common/flatpak-dir.c:15718
#, c-format
msgid "Runtime %s, branch %s is already installed"
msgstr "Runtime %s, branch %s is reeds geïnstalleerd"

#: common/flatpak-dir.c:15719
#, c-format
msgid "App %s, branch %s is already installed"
msgstr "Toepassing %s, branch %s is reeds geïnstalleerd"

#: common/flatpak-dir.c:15953
#, c-format
msgid "Can't remove remote '%s' with installed ref %s (at least)"
msgstr "Kan remote ‘%s’ niet verwijderen met geïnstalleerde ref %s (o.a.)"

#: common/flatpak-dir.c:16058
#, c-format
msgid "Invalid character '/' in remote name: %s"
msgstr "Ongeldig teken ‘/’ in remote-naam: %s"

#: common/flatpak-dir.c:16064
#, c-format
msgid "No configuration for remote %s specified"
msgstr "Geen configuratie opgegeven voor remote %s"

#: common/flatpak-dir.c:17597
#, c-format
msgid "Skipping deletion of mirror ref (%s, %s)…\n"
msgstr "Verwijderen van mirror-ref (%s, %s) wordt overgeslagen…\n"

#: common/flatpak-exports.c:931
#, c-format
msgid "An absolute path is required"
msgstr "Een absoluut pad is vereist"

#: common/flatpak-exports.c:948
#, c-format
msgid "Unable to open path \"%s\": %s"
msgstr "Kan pad ‘%s’ niet openen: %s"

#: common/flatpak-exports.c:955
#, c-format
msgid "Unable to get file type of \"%s\": %s"
msgstr "Kan bestandstype van ‘%s’ niet verkrijgen: %s"

#: common/flatpak-exports.c:964
#, c-format
msgid "File \"%s\" has unsupported type 0o%o"
msgstr "Bestand ‘%s’ heeft niet-ondersteund bestandstype 0o%o"

#: common/flatpak-exports.c:970
#, c-format
msgid "Unable to get filesystem information for \"%s\": %s"
msgstr "Kan bestandssysteeminformatie voor ‘%s’ niet verkrijgen: %s"

#: common/flatpak-exports.c:980
#, c-format
msgid "Ignoring blocking autofs path \"%s\""
msgstr "Blokkerend autofs-pad ‘%s’ wordt genegeerd"

#: common/flatpak-exports.c:996 common/flatpak-exports.c:1009
#: common/flatpak-exports.c:1022
#, c-format
msgid "Path \"%s\" is reserved by Flatpak"
msgstr "Pad ‘%s’ is gereserveerd door Flatpak"

#: common/flatpak-exports.c:1076
#, c-format
msgid "Unable to resolve symbolic link \"%s\": %s"
msgstr "Kon symbolische link ‘%s’ niet volgen: %s"

#: common/flatpak-glib-backports.c:69
msgid "Empty string is not a number"
msgstr "Lege tekenreeks is geen getal"

#: common/flatpak-glib-backports.c:95
#, c-format
msgid "“%s” is not an unsigned number"
msgstr "‘%s’ is geen ongetekend getal"

#: common/flatpak-glib-backports.c:105
#, c-format
msgid "Number “%s” is out of bounds [%s, %s]"
msgstr "Getal ‘%s’ is buiten bereik [%s, %s]"

#: common/flatpak-image-source.c:83
msgid "Only sha256 image checksums are supported"
msgstr ""

#: common/flatpak-image-source.c:100 common/flatpak-image-source.c:108
msgid "Image is not a manifest"
msgstr "Image is geen manifest"

#: common/flatpak-image-source.c:123
msgid "No org.flatpak.ref found in image"
msgstr ""

#: common/flatpak-image-source.c:148
#, c-format
msgid "Ref '%s' not found in registry"
msgstr "Ref ‘%s’ niet gevonden in register"

#: common/flatpak-image-source.c:157
msgid "Multiple images in registry, specify a ref with --ref"
msgstr "Meerdere images in register, specificeer een ref met --ref"

#: common/flatpak-installation.c:834
#, c-format
msgid "Ref %s not installed"
msgstr "Ref %s niet geïnstalleerd"

#: common/flatpak-installation.c:875
#, c-format
msgid "App %s not installed"
msgstr "Toepassing %s niet geïnstalleerd"

#: common/flatpak-installation.c:1395
#, c-format
msgid "Remote '%s' already exists"
msgstr "Remote ‘%s’ bestaat al"

#: common/flatpak-installation.c:1946
#, c-format
msgid "As requested, %s was only pulled, but not installed"
msgstr "Zoals verzocht is %s enkel opgehaald maar niet geïnstalleerd"

#: common/flatpak-instance.c:533 common/flatpak-instance.c:687
#: common/flatpak-instance.c:728
#, c-format
msgid "Unable to create directory %s"
msgstr "Kon map %s niet aanmaken"

#: common/flatpak-instance.c:554
#, c-format
msgid "Unable to lock %s"
msgstr "Kon %s niet vergrendelen"

#: common/flatpak-instance.c:627
#, c-format
msgid "Unable to create temporary directory in %s"
msgstr "Kon tijdelijke map in %s niet aanmaken"

#: common/flatpak-instance.c:639
#, c-format
msgid "Unable to create file %s"
msgstr "Kon bestand %s niet aanmaken"

#: common/flatpak-instance.c:646
#, c-format
msgid "Unable to update symbolic link %s/%s"
msgstr "Kon symbolische link %s/%s niet aanmaken"

#: common/flatpak-oci-registry.c:1197
msgid "Only Bearer authentication supported"
msgstr "Enkel Bearer-authenticatie ondersteund"

# Ik mis hier wat context, dit is een letterlijke vertaling  - Philip
#: common/flatpak-oci-registry.c:1206
msgid "Only realm in authentication request"
msgstr "Enige rijk in authenticatieverzoek"

#: common/flatpak-oci-registry.c:1213
msgid "Invalid realm in authentication request"
msgstr "Ongeldig rijk in authenticatieverzoek"

#: common/flatpak-oci-registry.c:1283
#, c-format
msgid "Authorization failed: %s"
msgstr "Autorisatie mislukt: %s"

#: common/flatpak-oci-registry.c:1285
msgid "Authorization failed"
msgstr "Autorisatie mislukt"

#: common/flatpak-oci-registry.c:1289
#, c-format
msgid "Unexpected response status %d when requesting token: %s"
msgstr "Onverwachte antwoordstatus %d bij aanvragen van token: %s"

#: common/flatpak-oci-registry.c:1300
msgid "Invalid authentication request response"
msgstr "Ongeldig antwoord op authenticatieverzoek"

#: common/flatpak-oci-registry.c:1731
#, c-format
msgid "Flatpak was compiled without zstd support"
msgstr ""

#: common/flatpak-oci-registry.c:1923 common/flatpak-oci-registry.c:1975
#: common/flatpak-oci-registry.c:2004 common/flatpak-oci-registry.c:2059
#: common/flatpak-oci-registry.c:2115 common/flatpak-oci-registry.c:2193
msgid "Invalid delta file format"
msgstr "Ongeldig deltabestandsformaat"

#: common/flatpak-oci-registry.c:3198 common/flatpak-oci-registry.c:3382
msgid "Invalid OCI image config"
msgstr "Ongeldige configuratie van OCI-image"

#: common/flatpak-oci-registry.c:3260 common/flatpak-oci-registry.c:3531
#, c-format
msgid "Wrong layer checksum, expected %s, was %s"
msgstr "Ongeldige controlesom van laag, %s verwacht, %s opgegeven"

#: common/flatpak-oci-registry.c:3359
#, c-format
msgid "No ref specified for OCI image %s"
msgstr "Geen ref opgegeven voor OCI-image %s"

#: common/flatpak-oci-registry.c:3369
#, c-format
msgid "Wrong ref (%s) specified for OCI image %s, expected %s"
msgstr "Ongeldige ref (%s) opgegeven voor OCI-image %s, %s verwacht"

#: common/flatpak-progress.c:236
#, c-format
msgid "Downloading metadata: %u/(estimating) %s"
msgstr "Metagegevens downloaden: %u/(schatten) %s"

#: common/flatpak-progress.c:260
#, c-format
msgid "Downloading: %s/%s"
msgstr "Downloaden: %s/%s"

#: common/flatpak-progress.c:280
#, c-format
msgid "Downloading extra data: %s/%s"
msgstr "Extra gegevens downloaden: %s/%s"

#: common/flatpak-progress.c:285
#, c-format
msgid "Downloading files: %d/%d %s"
msgstr "Bestanden downloaden: %d/%d %s"

#: common/flatpak-ref-utils.c:122
msgid "Name can't be empty"
msgstr "Naam mag niet leeg zijn"

#: common/flatpak-ref-utils.c:129
msgid "Name can't be longer than 255 characters"
msgstr "Naam mag niet langer zijn dan 255 tekens"

#: common/flatpak-ref-utils.c:142
msgid "Name can't start with a period"
msgstr "Naam mag niet starten met een punt"

#: common/flatpak-ref-utils.c:148
#, c-format
msgid "Name can't start with %c"
msgstr "Naam mag niet starten met %c"

#: common/flatpak-ref-utils.c:164
msgid "Name can't end with a period"
msgstr "Naam mag niet eindigen met een punt"

#: common/flatpak-ref-utils.c:171 common/flatpak-ref-utils.c:183
msgid "Only last name segment can contain -"
msgstr "Enkel het laatste naamsegment mag een streepje bevatten"

#: common/flatpak-ref-utils.c:174
#, c-format
msgid "Name segment can't start with %c"
msgstr "Naamsegment mag niet starten met %c"

#: common/flatpak-ref-utils.c:186
#, c-format
msgid "Name can't contain %c"
msgstr "Naam mag geen %c bevatten"

#: common/flatpak-ref-utils.c:195
msgid "Names must contain at least 2 periods"
msgstr "Namen moeten ten minste 2 punten bevatten"

#: common/flatpak-ref-utils.c:312
msgid "Arch can't be empty"
msgstr "Arch mag niet leeg zijn"

#: common/flatpak-ref-utils.c:323
#, c-format
msgid "Arch can't contain %c"
msgstr "Arch mag geen %c bevatten"

#: common/flatpak-ref-utils.c:385
msgid "Branch can't be empty"
msgstr "Branch mag niet leeg zijn"

#: common/flatpak-ref-utils.c:395
#, c-format
msgid "Branch can't start with %c"
msgstr "Branch mag niet starten met %c"

#: common/flatpak-ref-utils.c:405
#, c-format
msgid "Branch can't contain %c"
msgstr "Branch mag geen %c bevatten"

#: common/flatpak-ref-utils.c:615 common/flatpak-ref-utils.c:865
msgid "Ref too long"
msgstr "REF te lang"

#: common/flatpak-ref-utils.c:627
msgid "Invalid remote name"
msgstr "Ongeldige remote-naam"

#: common/flatpak-ref-utils.c:641
#, c-format
msgid "%s is not application or runtime"
msgstr "%s is geen toepassing of runtime"

#: common/flatpak-ref-utils.c:650 common/flatpak-ref-utils.c:667
#: common/flatpak-ref-utils.c:683
#, c-format
msgid "Wrong number of components in %s"
msgstr "Ongeldig aantal onderdelen in %s"

#: common/flatpak-ref-utils.c:656
#, c-format
msgid "Invalid name %.*s: %s"
msgstr "Ongeldige naam %.*s: %s"

#: common/flatpak-ref-utils.c:673
#, c-format
msgid "Invalid arch: %.*s: %s"
msgstr "Ongeldige architectuur %.*s: %s"

#: common/flatpak-ref-utils.c:816
#, c-format
msgid "Invalid name %s: %s"
msgstr "Ongeldige naam %s: %s"

#: common/flatpak-ref-utils.c:834
#, c-format
msgid "Invalid arch: %s: %s"
msgstr "Ongeldige architectuur %s: %s"

#: common/flatpak-ref-utils.c:853
#, c-format
msgid "Invalid branch: %s: %s"
msgstr "Ongeldige branch %s: %s"

#: common/flatpak-ref-utils.c:962 common/flatpak-ref-utils.c:970
#: common/flatpak-ref-utils.c:978
#, c-format
msgid "Wrong number of components in partial ref %s"
msgstr "Onjuist aantal onderdelen in gedeeltelijke ref %s"

#: common/flatpak-ref-utils.c:1298
msgid " development platform"
msgstr " ontwikkelingsplatform"

#: common/flatpak-ref-utils.c:1300
msgid " platform"
msgstr " platform"

#: common/flatpak-ref-utils.c:1302
msgid " application base"
msgstr " toepassingsbasis"

#: common/flatpak-ref-utils.c:1305
msgid " debug symbols"
msgstr " foutopsporingssymbolen"

#: common/flatpak-ref-utils.c:1307
msgid " sourcecode"
msgstr " broncode"

#: common/flatpak-ref-utils.c:1309
msgid " translations"
msgstr " vertalingen"

#: common/flatpak-ref-utils.c:1311
msgid " docs"
msgstr " documentatie"

#: common/flatpak-ref-utils.c:1578
#, c-format
msgid "Invalid id %s: %s"
msgstr "Ongeldige ID %s: %s"

#: common/flatpak-remote.c:1216
#, c-format
msgid "Bad remote name: %s"
msgstr "Ongeldige remote-naam: %s"

#: common/flatpak-remote.c:1220
#, fuzzy
msgid "No URL specified"
msgstr "Geen URL opgegeven"

#: common/flatpak-remote.c:1266
msgid "GPG verification must be enabled when a collection ID is set"
msgstr ""
"GPG-verificatie moet worden ingechakeld wanneer een verzamelings-ID is "
"ingesteld"

#: common/flatpak-repo-utils.c:344
#, c-format
msgid "No extra data sources"
msgstr "Geen extra databronnen"

#: common/flatpak-repo-utils.c:2817
#, c-format
msgid "Invalid %s: Missing group ‘%s’"
msgstr "Ongeldig(e) %s: Groep ‘%s’ ontbreekt"

#: common/flatpak-repo-utils.c:2826
#, c-format
msgid "Invalid %s: Missing key ‘%s’"
msgstr "Ongeldig(e) %s: Sleutel ‘%s’ ontbreekt"

#: common/flatpak-repo-utils.c:2876
msgid "Invalid gpg key"
msgstr "Ongeldige GPG-sleutel"

#: common/flatpak-repo-utils.c:3217
#, c-format
msgid "Error copying 64x64 icon for component %s: %s\n"
msgstr "Fout bij kopiëren van 64x64-pictogram voor onderdeel %s: %s\n"

#: common/flatpak-repo-utils.c:3223
#, c-format
msgid "Error copying 128x128 icon for component %s: %s\n"
msgstr "Fout bij kopiëren van 128x128-pictogram voor onderdeel %s: %s\n"

#: common/flatpak-repo-utils.c:3362
#, c-format
msgid "%s is end-of-life, ignoring for appstream"
msgstr "%s is end-of-life, wordt genegeerd voor appstream"

#: common/flatpak-repo-utils.c:3397
#, c-format
msgid "No appstream data for %s: %s\n"
msgstr "Geen appstream-gegevens voor %s: %s\n"

#: common/flatpak-repo-utils.c:3744
msgid "Invalid bundle, no ref in metadata"
msgstr "Ongeldige bundel, geen ref in metagegevens"

#: common/flatpak-repo-utils.c:3846
#, c-format
msgid "Collection ‘%s’ of bundle doesn’t match collection ‘%s’ of remote"
msgstr ""
"Verzameling ‘%s’ van bundel komt niet overeen met verzameling ‘%s’ van remote"

#: common/flatpak-repo-utils.c:3923
msgid "Metadata in header and app are inconsistent"
msgstr "Metagegevens in header en toepassing zijn inconsistent"

#: common/flatpak-run.c:951
msgid "No systemd user session available, cgroups not available"
msgstr "Geen systemd-gebruikerssessie beschikbaar, cgroups niet beschikbaar"

#: common/flatpak-run.c:1496
msgid "Unable to allocate instance id"
msgstr "Kon instantie-ID niet toewijzen"

#: common/flatpak-run.c:1632 common/flatpak-run.c:1641
#, c-format
msgid "Failed to open flatpak-info file: %s"
msgstr "Bestand flatpak-info openen mislukt: %s"

#: common/flatpak-run.c:1668
#, c-format
msgid "Failed to open bwrapinfo.json file: %s"
msgstr "Bestand bwrapinfo.json openen mislukt: %s"

#: common/flatpak-run.c:1689
#, c-format
msgid "Failed to write to instance id fd: %s"
msgstr "Schrijven naar instantie-ID-FD mislukt: %s"

#: common/flatpak-run.c:2096
msgid "Initialize seccomp failed"
msgstr "Seccomp initialiseren mislukt"

#: common/flatpak-run.c:2135
#, c-format
msgid "Failed to add architecture to seccomp filter: %s"
msgstr "Architectuur aan seccomp-filter toevoegen mislukt: %s"

#: common/flatpak-run.c:2143
#, c-format
msgid "Failed to add multiarch architecture to seccomp filter: %s"
msgstr "Multiarch-architectuur aan seccomp-filter toevoegen mislukt: %s"

#: common/flatpak-run.c:2175 common/flatpak-run.c:2192
#: common/flatpak-run.c:2214
#, c-format
msgid "Failed to block syscall %d: %s"
msgstr "Syscall %d blokkeren mislukt: %s"

#: common/flatpak-run.c:2247
#, c-format
msgid "Failed to export bpf: %s"
msgstr "BPF exporteren mislukt: %s"

#: common/flatpak-run.c:2587
#, c-format
msgid "Failed to open ‘%s’"
msgstr "‘%s’ openen mislukt"

#: common/flatpak-run.c:2597
#, c-format
msgid ""
"Directory forwarding needs version 4 of the document portal (have version %d)"
msgstr ""

#: common/flatpak-run.c:2915
#, c-format
msgid "ldconfig failed, exit status %d"
msgstr "ldconfig mislukt, afsluitstatus %d"

#: common/flatpak-run.c:2922
msgid "Can't open generated ld.so.cache"
msgstr "Kan gegenereerde ld.so.cache niet openen"

#. Translators: The placeholder is for an app ref.
#: common/flatpak-run.c:3045
#, c-format
msgid "Running %s is not allowed by the policy set by your administrator"
msgstr ""
"%s uitvoeren is niet toegestaan door het door uw administrator ingestelde "
"beleid"

#: common/flatpak-run.c:3202
msgid ""
"\"flatpak run\" is not intended to be run as `sudo flatpak run`. Use `sudo "
"-i` or `su -l` instead and invoke \"flatpak run\" from inside the new shell."
msgstr ""
"`flatpak run` is niet bedoeld om als `sudo flatpak run` uitgevoerd te "
"worden. Maak in plaats hiervan gebruik van `sudo -i` of `sudo -l` en voer "
"`flatpak run` uit vanuit de nieuwe shell."

#: common/flatpak-run.c:3413
#, c-format
msgid "Failed to migrate from %s: %s"
msgstr "Migratie van %s mislukt: %s"

#: common/flatpak-run.c:3434
#, c-format
msgid "Failed to migrate old app data directory %s to new name %s: %s"
msgstr ""
"Oude toepassingsgegevensmap %s migreren naar nieuwe naam %s mislukt: %s"

#: common/flatpak-run.c:3443
#, c-format
msgid "Failed to create symlink while migrating %s: %s"
msgstr "Symbolische link aanmaken bij migreren van %s mislukt: %s"

#: common/flatpak-run-dbus.c:46
msgid "Failed to open app info file"
msgstr "Toepassingsinfobestand openen mislukt"

#: common/flatpak-run-dbus.c:149
msgid "Unable to create sync pipe"
msgstr "Kon synchronisatie-pipe niet aanmaken"

#: common/flatpak-run-dbus.c:185
msgid "Failed to sync with dbus proxy"
msgstr "Synchroniseren met D-Bus-proxy mislukt"

#: common/flatpak-transaction.c:2275
#, c-format
msgid "Warning: Problem looking for related refs: %s"
msgstr "Waarschuwing: Probleem bij zoeken naar verwante refs: %s"

#: common/flatpak-transaction.c:2493
#, c-format
msgid "The application %s requires the runtime %s which was not found"
msgstr "De toepassing %s vereist de runtime %s, welke niet kon worden gevonden"

#: common/flatpak-transaction.c:2509
#, c-format
msgid "The application %s requires the runtime %s which is not installed"
msgstr "De toepassing %s vereist de runtime %s, welke niet is geïnstalleerd"

#: common/flatpak-transaction.c:2641
#, c-format
msgid "Can't uninstall %s which is needed by %s"
msgstr "Kan %s niet de-installeren, deze is benodigd door %s"

#: common/flatpak-transaction.c:2740
#, c-format
msgid "Remote %s disabled, ignoring %s update"
msgstr "Remote %s is uitgeschakeld, update van %s wordt genegeerd"

#: common/flatpak-transaction.c:2773
#, c-format
msgid "%s is already installed"
msgstr "%s is al geïnstalleerd"

#: common/flatpak-transaction.c:2776
#, c-format
msgid "%s is already installed from remote %s"
msgstr "%s is al geïnstalleerd van remote %s"

#: common/flatpak-transaction.c:3120
#, c-format
msgid "Invalid .flatpakref: %s"
msgstr "Ongeldige .flatpakref: %s"

#: common/flatpak-transaction.c:3161
msgid "Warning: Could not mark already installed apps as preinstalled"
msgstr ""

#: common/flatpak-transaction.c:3382
#, c-format
msgid "Error updating remote metadata for '%s': %s"
msgstr "Fout bij bijwerken van remote-metagegevens voor ‘%s’ : %s"

#: common/flatpak-transaction.c:3885
#, c-format
msgid ""
"Warning: Treating remote fetch error as non-fatal since %s is already "
"installed: %s"
msgstr ""
"Waarschuwing: remote-ophaalfout wordt behandeld als niet-fataal omdat %s al "
"is geïnstalleerd: %s"

#: common/flatpak-transaction.c:4209
#, c-format
msgid "No authenticator installed for remote '%s'"
msgstr "Geen authenticator geïnstalleerd voor remote ‘%s’"

#: common/flatpak-transaction.c:4313 common/flatpak-transaction.c:4320
#, c-format
msgid "Failed to get tokens for ref: %s"
msgstr "Tokens voor ref verkrijgen mislukt: %s"

#: common/flatpak-transaction.c:4315 common/flatpak-transaction.c:4322
msgid "Failed to get tokens for ref"
msgstr "Tokens voor ref verkrijgen mislukt"

#: common/flatpak-transaction.c:4580
#, c-format
msgid "Ref %s from %s matches more than one transaction operation"
msgstr "Ref %s van %s komt overeen met meer dan één transactiehandeling"

#: common/flatpak-transaction.c:4581 common/flatpak-transaction.c:4591
msgid "any remote"
msgstr "elke remote"

#: common/flatpak-transaction.c:4590
#, c-format
msgid "No transaction operation found for ref %s from %s"
msgstr "Geen transactiehandeling gevonden voor ref %s van %s"

#: common/flatpak-transaction.c:4713
#, c-format
msgid "Flatpakrepo URL %s not file, HTTP or HTTPS"
msgstr "Flatpakrepo-URL %s is geen bestand, HTTP of HTTPS"

#: common/flatpak-transaction.c:4719
#, c-format
msgid "Can't load dependent file %s: "
msgstr "Kan afhankelijk bestand %s niet laden: "

#: common/flatpak-transaction.c:4727
#, c-format
msgid "Invalid .flatpakrepo: %s"
msgstr "Ongeldige .flatpakrepo: %s"

#: common/flatpak-transaction.c:5454
msgid "Transaction already executed"
msgstr "Transactie al uitgevoerd"

#: common/flatpak-transaction.c:5469
msgid ""
"Refusing to operate on a user installation as root! This can lead to "
"incorrect file ownership and permission errors."
msgstr ""
"Handelingen uitvoeren op een gebruikersinstallatie als root geweigerd! Dit "
"kan leiden tot onjuiste bestandseigendommen en rechtenfouten."

#: common/flatpak-transaction.c:5567 common/flatpak-transaction.c:5580
msgid "Aborted by user"
msgstr "Afgebroken door gebruiker"

#: common/flatpak-transaction.c:5605
#, c-format
msgid "Skipping %s due to previous error"
msgstr "%s wordt overgeslagen vanwege een vorige fout"

#: common/flatpak-transaction.c:5659
#, c-format
msgid "Aborted due to failure (%s)"
msgstr "Afgebroken vanwege fout (%s)"

#: common/flatpak-uri.c:118
#, no-c-format
msgid "Invalid %-encoding in URI"
msgstr "Ongeldige %-codering in URI"

#: common/flatpak-uri.c:135
msgid "Illegal character in URI"
msgstr "Ongeldig teken in URI"

#: common/flatpak-uri.c:169
msgid "Non-UTF-8 characters in URI"
msgstr "Ongeldige UTF-8-tekens in URI"

#: common/flatpak-uri.c:275
#, c-format
msgid "Invalid IPv6 address ‘%.*s’ in URI"
msgstr "Ongeldig IPv6-adres ‘%.*s’ in URI"

#: common/flatpak-uri.c:330
#, c-format
msgid "Illegal encoded IP address ‘%.*s’ in URI"
msgstr "Ongeldig gecodeerd IP-adres ‘%.*s’ in URI"

#: common/flatpak-uri.c:342
#, c-format
msgid "Illegal internationalized hostname ‘%.*s’ in URI"
msgstr "Ongeldig geïnternationaliseerde hostnaam ‘%.*s’ in URI"

#: common/flatpak-uri.c:374 common/flatpak-uri.c:386
#, c-format
msgid "Could not parse port ‘%.*s’ in URI"
msgstr "Kon poort ‘%.*s’ in URI niet parsen"

#: common/flatpak-uri.c:393
#, c-format
msgid "Port ‘%.*s’ in URI is out of range"
msgstr "Poort ‘%.*s’ in URI is buiten bereik"

#: common/flatpak-uri.c:910
msgid "URI is not absolute, and no base URI was provided"
msgstr "URI is niet absoluut, en er is geen basis-URI opgegeven"

#: common/flatpak-usb.c:83
#, c-format
msgid "USB device query 'all' must not have data"
msgstr "USB-apparaatquery ‘all’ mag geen gegevens bevatten"

#: common/flatpak-usb.c:102
#, c-format
msgid "USB query rule 'cls' must be in the form CLASS:SUBCLASS or CLASS:*"
msgstr ""
"USB-queryregel ‘cls’ moet in het formaat KLASSE:SUBKLASSE of KLASSE:* zijn"

#: common/flatpak-usb.c:111
#, fuzzy, c-format
msgid "Invalid USB class"
msgstr "Ongeldige USB-klasse"

#: common/flatpak-usb.c:125
#, c-format
msgid "Invalid USB subclass"
msgstr "Ongeldige USB-subklasse"

#: common/flatpak-usb.c:141 common/flatpak-usb.c:148
#, c-format
msgid "USB query rule 'dev' must have a valid 4-digit hexadecimal product id"
msgstr ""
"USB-queryregel ‘dev’ moet een geldig 4-cijferig hexadecimaal product-id "
"bevatten"

#: common/flatpak-usb.c:164 common/flatpak-usb.c:171
#, c-format
msgid "USB query rule 'vnd' must have a valid 4-digit hexadecimal vendor id"
msgstr ""
"USB-queryregel ‘vnd’ moet een geldig 4-cijferig hexadecimaal levaranciers-id "
"bevatten"

#: common/flatpak-usb.c:205
#, c-format
msgid "USB device queries must be in the form TYPE:DATA"
msgstr "USB-apparaatquery's moeten in het formaat TYPE:GEGEVENS zijn"

#: common/flatpak-usb.c:225
#, c-format
msgid "Unknown USB query rule %s"
msgstr "Onbekende USB-queryregel %s"

#: common/flatpak-usb.c:248
#, c-format
msgid "Empty USB query"
msgstr "Lege USB-query"

#: common/flatpak-usb.c:274
#, c-format
msgid "Multiple USB query rules of the same type is not supported"
msgstr "Meerdere USB-queryregels van hetzelfde type worden niet ondersteund"

#: common/flatpak-usb.c:283
#, c-format
msgid "'all' must not contain extra query rules"
msgstr "‘all’ mag geen extra queryregels bevatten"

#: common/flatpak-usb.c:291
#, c-format
msgid "USB queries with 'dev' must also specify vendors"
msgstr "USB-queries met ‘dev’ moet ook leveranciers specificeren"

#: common/flatpak-utils.c:712
msgid "Glob can't match apps"
msgstr "Glob kan niet overeenkomen met toepassingen"

#: common/flatpak-utils.c:737
msgid "Empty glob"
msgstr "Lege glob"

#: common/flatpak-utils.c:756
msgid "Too many segments in glob"
msgstr "Te veel segmenten in glob"

#: common/flatpak-utils.c:777
#, c-format
msgid "Invalid glob character '%c'"
msgstr "Ongeldig glob-teken ‘%c’"

#: common/flatpak-utils.c:831
#, c-format
msgid "Missing glob on line %d"
msgstr "Ontbrekende glob op regel %d"

#: common/flatpak-utils.c:835
#, c-format
msgid "Trailing text on line %d"
msgstr "Tekst achteraan regel %d"

#: common/flatpak-utils.c:839
#, c-format
msgid "on line %d"
msgstr "op regel %d"

#: common/flatpak-utils.c:861
#, c-format
msgid "Unexpected word '%s' on line %d"
msgstr "Onverwacht woord ‘%s’ op regel %d"

#: common/flatpak-utils.c:2118
#, c-format
msgid "Invalid require-flatpak argument %s"
msgstr "Ongeldig argument %s van require-flatpak"

#: common/flatpak-utils.c:2128 common/flatpak-utils.c:2147
#, c-format
msgid "%s needs a later flatpak version (%s)"
msgstr "%s vereist een nieuwere flatpak-versie (%s)"

#: oci-authenticator/flatpak-oci-authenticator.c:291
msgid "Not a oci remote, missing summary.xa.oci-repository"
msgstr "Geen OCI-remote, summary.xa.oci-pakketbron ontbreekt"

#: oci-authenticator/flatpak-oci-authenticator.c:477
msgid "Not a OCI remote"
msgstr "Geen OCI-remote"

#: oci-authenticator/flatpak-oci-authenticator.c:488
msgid "Invalid token"
msgstr "Ongeldige token"

#: portal/flatpak-portal.c:2292
#, c-format
msgid "No portal support found"
msgstr "Geen ondersteuning voor portalen gevonden"

#: portal/flatpak-portal.c:2298
msgid "Deny"
msgstr "Weigeren"

#: portal/flatpak-portal.c:2300
msgid "Update"
msgstr "Bijwerken"

#: portal/flatpak-portal.c:2305
#, c-format
msgid "Update %s?"
msgstr "%s bijwerken?"

#: portal/flatpak-portal.c:2317
msgid "The application wants to update itself."
msgstr "De toepassing wil zichzelf bijwerken."

#: portal/flatpak-portal.c:2318
msgid "Update access can be changed any time from the privacy settings."
msgstr ""
"Update-toegang kan te allen tijde worden gewijzigd via de privacy-"
"instellingen."

#: portal/flatpak-portal.c:2343
#, c-format
msgid "Application update not allowed"
msgstr "Bijwerken van toepassing niet toegestaan"

#: portal/flatpak-portal.c:2501
#, c-format
msgid "Self update not supported, new version requires new permissions"
msgstr ""
"Zelf updaten wordt niet ondersteund, nieuwe versie vereist nieuwe rechten"

#: portal/flatpak-portal.c:2684 portal/flatpak-portal.c:2702
#, c-format
msgid "Update ended unexpectedly"
msgstr "Bijwerken is onverwachts gestopt"

#. SECURITY:
#. - Normal users need admin authentication to install software
#. system-wide.
#. - Note that we install polkit rules that allow local users
#. in the wheel group to install without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:23
msgid "Install signed application"
msgstr "Ondertekende toepassing installeren"

#: system-helper/org.freedesktop.Flatpak.policy.in:24
#: system-helper/org.freedesktop.Flatpak.policy.in:42
msgid "Authentication is required to install software"
msgstr "Authenticatie is vereist om software te installeren"

#. SECURITY:
#. - Normal users need admin authentication to install software
#. system-wide.
#. - Note that we install polkit rules that allow local users
#. in the wheel group to install without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:41
msgid "Install signed runtime"
msgstr "Ondertekende runtime installeren"

#. SECURITY:
#. - Normal users do not require admin authentication to update an
#. app as the commit will be signed, and the action is required
#. to update the system when unattended.
#. - Changing this to anything other than 'yes' will break unattended
#. updates.
#: system-helper/org.freedesktop.Flatpak.policy.in:60
msgid "Update signed application"
msgstr "Ondertekende toepassing bijwerken"

#: system-helper/org.freedesktop.Flatpak.policy.in:61
#: system-helper/org.freedesktop.Flatpak.policy.in:80
msgid "Authentication is required to update software"
msgstr "Authenticatie is vereist om software bij te werken"

#. SECURITY:
#. - Normal users do not require admin authentication to update a
#. runtime as the commit will be signed, and the action is required
#. to update the system when unattended.
#. - Changing this to anything other than 'yes' will break unattended
#. updates.
#: system-helper/org.freedesktop.Flatpak.policy.in:79
msgid "Update signed runtime"
msgstr "Ondertekende runtime bijwerken"

#. SECURITY:
#. - Normal users do not need authentication to update metadata
#. from signed repositories.
#: system-helper/org.freedesktop.Flatpak.policy.in:94
msgid "Update remote metadata"
msgstr "Remote-metadata bijwerken"

#: system-helper/org.freedesktop.Flatpak.policy.in:95
msgid "Authentication is required to update remote info"
msgstr "Authenticatie is vereist om remote-info bij te werken"

#. SECURITY:
#. - Normal users do not need authentication to modify the
#. OSTree repository
#. - Note that we install polkit rules that allow local users
#. in the wheel group to modify repos without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:111
msgid "Update system repository"
msgstr "Systeempakketbron bijwerken"

#: system-helper/org.freedesktop.Flatpak.policy.in:112
msgid "Authentication is required to modify a system repository"
msgstr "Authenticatie is vereist om een systeempakketbron te bewerken"

#. SECURITY:
#. - Normal users need admin authentication to install software
#. system-wide.
#: system-helper/org.freedesktop.Flatpak.policy.in:126
msgid "Install bundle"
msgstr "Bundel installeren"

#: system-helper/org.freedesktop.Flatpak.policy.in:127
msgid "Authentication is required to install software from $(path)"
msgstr "Authenticatie is vereist om software te installeren van $(path)"

#. SECURITY:
#. - Normal users need admin authentication to uninstall software
#. system-wide.
#. - Note that we install polkit rules that allow local users
#. in the wheel group to uninstall without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:144
msgid "Uninstall runtime"
msgstr "Runtime de-installeren"

#: system-helper/org.freedesktop.Flatpak.policy.in:145
msgid "Authentication is required to uninstall software"
msgstr "Authenticatie is vereist om software te verwijderen"

#. SECURITY:
#. - Normal users need admin authentication to uninstall software
#. system-wide.
#. - Note that we install polkit rules that allow local users
#. in the wheel group to uninstall without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:161
msgid "Uninstall app"
msgstr "Toepassing de-installeren"

#: system-helper/org.freedesktop.Flatpak.policy.in:162
msgid "Authentication is required to uninstall $(ref)"
msgstr "Authenticatie is vereist om $(ref) te verwijderen"

#. SECURITY:
#. - Normal users need admin authentication to configure system-wide
#. software repositories.
#: system-helper/org.freedesktop.Flatpak.policy.in:177
msgid "Configure Remote"
msgstr "Remote configureren"

#: system-helper/org.freedesktop.Flatpak.policy.in:178
msgid "Authentication is required to configure software repositories"
msgstr "Authenticatie is vereist om softwarepakketbronnen te configureren"

#. SECURITY:
#. - Normal users need admin authentication to configure the system-wide
#. Flatpak installation.
#: system-helper/org.freedesktop.Flatpak.policy.in:192
msgid "Configure"
msgstr "Configureren"

#: system-helper/org.freedesktop.Flatpak.policy.in:193
msgid "Authentication is required to configure software installation"
msgstr "Authenticatie is vereist om software-installatie te configureren"

#. SECURITY:
#. - Normal users do not require admin authentication to update
#. appstream data as it will be signed, and the action is required
#. to update the system when unattended.
#. - Changing this to anything other than 'yes' will break unattended
#. updates.
#: system-helper/org.freedesktop.Flatpak.policy.in:210
msgid "Update appstream"
msgstr "Appstream bijwerken"

#: system-helper/org.freedesktop.Flatpak.policy.in:211
msgid "Authentication is required to update information about software"
msgstr "Authenticatie is vereist om informatie over software bij te werken"

#. SECURITY:
#. - Normal users do not require admin authentication to update
#. metadata as it will be signed, and the action is required
#. to update the system when unattended.
#. - Changing this to anything other than 'yes' will break unattended
#. updates.
#: system-helper/org.freedesktop.Flatpak.policy.in:228
msgid "Update metadata"
msgstr "Metagegevens bijwerken"

#: system-helper/org.freedesktop.Flatpak.policy.in:229
msgid "Authentication is required to update metadata"
msgstr "Authenticatie is vereist om metagegevens bij te werken"

#. SECURITY:
#. - Authorisation to actually install software is controlled by
#. org.freedesktop.Flatpak.app-install.
#. - This action is checked after app-install, as it can only be done
#. once the app’s data (including its content rating) has been
#. downloaded.
#. - This action is checked to see if the installation should be allowed
#. based on whether the app being installed has content which doesn’t
#. comply with the user’s parental controls policy (the content is
#. ‘too extreme’).
#. - It is checked only if an app has too extreme content for the user
#. who is trying to install it (in which case, the app is ‘unsafe’).
#. - Typically, normal users will need admin permission to install apps
#. with extreme content; admins will be able to install it without
#. additional checks.
#. - In order to configure the policy so that admins can install safe and
#. unsafe software anywhere without authorisation, and non-admins can
#. install safe software in their user or system dirs without
#. authorisation, but need authorisation to install unsafe software
#. anywhere:
#. * Unconditionally return `yes` from `app-install`.
#. * Return `auth_admin` from `override-parental-controls` for users
#. not in `@privileged_group@`, and `yes` for users in it.
#. * Set the malcontent `is-{user,system}-installation-allowed`
#. properties of all non-admins’ parental controls policies to true.
#. - In order to configure the policy so that admins can install safe and
#. unsafe software anywhere without authorisation, and non-admins can
#. install safe software in their user dir without authorisation, but
#. need authorisation to install safe software in the system dir or to
#. install unsafe software anywhere:
#. * Unconditionally return `yes` from `app-install`.
#. * Return `auth_admin` from `override-parental-controls` for users
#. not in `@privileged_group@`, and `yes` for users in it.
#. * Set the malcontent `is-user-installation-allowed` property of all
#. non-admins’ parental controls policies to true.
#. * Set the malcontent `is-system-installation-allowed` property of
#. all non-admins’ parental controls policies to false.
#. - In order to configure the policy so that all users (including
#. admins) can install safe software anywhere without authorisation,
#. but need authorisation to install unsafe software anywhere (i.e.
#. applying parental controls to admins too):
#. * Unconditionally return `yes` from `app-install`.
#. * Unconditionally return `auth_admin` from `override-parental-controls`.
#. * Set the malcontent `is-user-installation-allowed` property of all
#. users’ parental controls policies to true.
#. * Set the malcontent `is-system-installation-allowed` property of
#. all users’ parental controls policies to true.
#: system-helper/org.freedesktop.Flatpak.policy.in:287
#, fuzzy
msgid "Override parental controls for installs"
msgstr "Ouderlijk toezicht overschrijven voor installaties"

#: system-helper/org.freedesktop.Flatpak.policy.in:288
msgid ""
"Authentication is required to install software which is restricted by your "
"parental controls policy"
msgstr ""
"Authenticatie is vereist om software te installeren welke is beperkt door uw "
"beleid van ouderlijk toezicht"

#. SECURITY:
#. - This is like org.freedesktop.Flatpak.override-parental-controls, but
#. it’s queried for app updates, whereas the former is queried for app
#. installs.
#. - As with the above action, this one is only queried if
#. org.freedesktop.Flatpak.app-update has allowed the app update, and
#. only if the app being updated has too extreme content for the user
#. who is trying to update it.
#. - The default policy for this is to *allow* updates to ‘too extreme’
#. apps by default, on the basis that having an out-of-date (i.e.
#. insecure or unsupported) app is a worse outcome than automatically
#. installing an update which has radically different content from the
#. version of the app which the parent originally vetted and installed.
#: system-helper/org.freedesktop.Flatpak.policy.in:313
#, fuzzy
msgid "Override parental controls for updates"
msgstr "Ouderlijk toezicht overschrijven voor updates"

#: system-helper/org.freedesktop.Flatpak.policy.in:314
#, fuzzy
msgid ""
"Authentication is required to update software which is restricted by your "
"parental controls policy"
msgstr ""
"Authenticatie is vereist om software te installeren welke is beperkt door uw "
"beleid van ouderlijk toezicht"

#~ msgid "Installed:"
#~ msgstr "Geïnstalleerd:"

#~ msgid "Download:"
#~ msgstr "Download:"

#, c-format
#~ msgid "No gpg key found with ID %s (homedir: %s)"
#~ msgstr "Geen GPG-sleutel gevonden met ID %s (thuismap: %s)"

#, c-format
#~ msgid "Unable to lookup key ID %s: %d"
#~ msgstr "Kon sleutel-ID %s niet opzoeken: %d"

#, c-format
#~ msgid "Error signing commit: %d"
#~ msgstr "Fout bij ondertekenen van commit: %d"

#, c-format
#~ msgid "Unable to open directory %s"
#~ msgstr "Kon map %s niet openen"

#, c-format
#~ msgid "Failed to uninstall %s for rebase to %s: "
#~ msgstr "%s verwijderen mislukt voor rebase naar %s: "

#, c-format
#~ msgid "Failed to uninstall %s for rebase to %s: %s\n"
#~ msgstr "%s verwijderen mislukt voor rebase naar %s: %s\n"

===== ./po/hi.po =====
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
# Dmitry <dmitrydmitry761@gmail.com>, 2021.
# Scrambled777 <weblate.scrambled777@simplelogin.com>, 2024.
#
msgid ""
msgstr ""
"Project-Id-Version: flatpak master\n"
"Report-Msgid-Bugs-To: https://github.com/flatpak/flatpak/issues\n"
"POT-Creation-Date: 2026-05-27 16:39+0200\n"
"PO-Revision-Date: 2024-06-08 20:21+0530\n"
"Last-Translator: Scrambled777 <weblate.scrambled777@simplelogin.com>\n"
"Language-Team: Hindi <indlinux-hindi@lists.sourceforge.net>\n"
"Language: hi\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
"X-Generator: Gtranslator 46.1\n"

#: app/flatpak-builtins-build-bundle.c:59
msgid "Export runtime instead of app"
msgstr "ऐप के बजाय रनटाइम निर्यात करें"

#: app/flatpak-builtins-build-bundle.c:60
msgid "Arch to bundle for"
msgstr "बंडल करने हेतु आर्किटेक्चर"

#: app/flatpak-builtins-build-bundle.c:60
#: app/flatpak-builtins-build-export.c:62 app/flatpak-builtins-build-init.c:53
#: app/flatpak-builtins-build-sign.c:42 app/flatpak-builtins-create-usb.c:46
#: app/flatpak-builtins-info.c:55 app/flatpak-builtins-install.c:67
#: app/flatpak-builtins-list.c:50 app/flatpak-builtins-make-current.c:38
#: app/flatpak-builtins-remote-info.c:54 app/flatpak-builtins-remote-ls.c:56
#: app/flatpak-builtins-run.c:158 app/flatpak-builtins-search.c:37
#: app/flatpak-builtins-uninstall.c:54 app/flatpak-builtins-update.c:56
msgid "ARCH"
msgstr "आर्किटेक्चर"

#: app/flatpak-builtins-build-bundle.c:61
#, fuzzy
msgid "URL for repo"
msgstr "रेपो के लिए URL"

#: app/flatpak-builtins-build-bundle.c:61
#: app/flatpak-builtins-build-bundle.c:62
#: app/flatpak-builtins-build-update-repo.c:68
#: app/flatpak-builtins-build-update-repo.c:72
#: app/flatpak-builtins-build-update-repo.c:73
#: app/flatpak-builtins-history.c:69 app/flatpak-builtins-remote-add.c:80
#: app/flatpak-builtins-remote-add.c:81 app/flatpak-builtins-remote-add.c:85
#: app/flatpak-builtins-remote-list.c:53
#: app/flatpak-builtins-remote-modify.c:70
#: app/flatpak-builtins-remote-modify.c:85
#: app/flatpak-builtins-remote-modify.c:86
#: app/flatpak-builtins-remote-modify.c:90
msgid "URL"
msgstr "URL"

#: app/flatpak-builtins-build-bundle.c:62
#, fuzzy
msgid "URL for runtime flatpakrepo file"
msgstr "रनटाइम flatpakrepo फाइल के लिए URL"

#: app/flatpak-builtins-build-bundle.c:63
msgid "Add GPG key from FILE (- for stdin)"
msgstr "फाइल से GPG कुंजी जोड़ें (- stdin के लिए)"

#: app/flatpak-builtins-build-bundle.c:63 app/flatpak-builtins-build.c:54
#: app/flatpak-builtins-build-export.c:67
#: app/flatpak-builtins-build-update-repo.c:83
#: app/flatpak-builtins-install.c:81 app/flatpak-builtins-remote-add.c:84
#: app/flatpak-builtins-remote-add.c:86 app/flatpak-builtins-remote-modify.c:89
#: app/flatpak-builtins-remote-modify.c:92
msgid "FILE"
msgstr "फाइल"

#: app/flatpak-builtins-build-bundle.c:64
msgid "GPG Key ID to sign the OCI image with"
msgstr "OCI छवि पर हस्ताक्षर करने के लिए GPG कुंजी ID"

#: app/flatpak-builtins-build-bundle.c:64
#: app/flatpak-builtins-build-commit-from.c:68
#: app/flatpak-builtins-build-export.c:68
#: app/flatpak-builtins-build-import-bundle.c:49
#: app/flatpak-builtins-build-sign.c:44
#: app/flatpak-builtins-build-update-repo.c:84
msgid "KEY-ID"
msgstr "कुंजी-ID"

#: app/flatpak-builtins-build-bundle.c:65
#: app/flatpak-builtins-build-commit-from.c:69
#: app/flatpak-builtins-build-export.c:71
#: app/flatpak-builtins-build-import-bundle.c:50
#: app/flatpak-builtins-build-sign.c:45
#: app/flatpak-builtins-build-update-repo.c:85
msgid "GPG Homedir to use when looking for keyrings"
msgstr "कीरिंग की तलाश करते समय GPG गृह-निर्देशिका का प्रयोग करें"

#: app/flatpak-builtins-build-bundle.c:65
#: app/flatpak-builtins-build-commit-from.c:69
#: app/flatpak-builtins-build-export.c:71
#: app/flatpak-builtins-build-import-bundle.c:50
#: app/flatpak-builtins-build-sign.c:45
#: app/flatpak-builtins-build-update-repo.c:85
msgid "HOMEDIR"
msgstr "गृह-निर्देशिका"

#: app/flatpak-builtins-build-bundle.c:66
msgid "OSTree commit to create a delta bundle from"
msgstr "डेल्टा बंडल बनाने के लिए OSTree कमिट"

#: app/flatpak-builtins-build-bundle.c:66 app/flatpak-builtins-remote-info.c:55
#: app/flatpak-builtins-update.c:57
msgid "COMMIT"
msgstr "कमिट"

#: app/flatpak-builtins-build-bundle.c:67
msgid "Export oci image instead of flatpak bundle"
msgstr "Flatpak बंडल के बजाय oci छवि निर्यात करें"

#: app/flatpak-builtins-build-bundle.c:70
msgid "How to compress OCI image layers (default: gzip)"
msgstr ""

#: app/flatpak-builtins-build-bundle.c:634
msgid ""
"LOCATION FILENAME NAME [BRANCH] - Create a single file bundle from a local "
"repository"
msgstr "स्थान फाइलनाम नाम [शाखा] - स्थानीय भंडार से एकल फाइल बंडल बनाएं"

#: app/flatpak-builtins-build-bundle.c:641
msgid "LOCATION, FILENAME and NAME must be specified"
msgstr "स्थान, फाइलनाम और नाम अवश्य निर्दिष्ट किया जाना चाहिए"

#: app/flatpak-builtins-build-bundle.c:644
#: app/flatpak-builtins-build-export.c:844
#: app/flatpak-builtins-build-import-bundle.c:136
#: app/flatpak-builtins-build-init.c:217 app/flatpak-builtins-build-sign.c:76
#: app/flatpak-builtins-document-export.c:112
#: app/flatpak-builtins-document-info.c:75
#: app/flatpak-builtins-document-list.c:191
#: app/flatpak-builtins-document-unexport.c:70
#: app/flatpak-builtins-history.c:482 app/flatpak-builtins-info.c:130
#: app/flatpak-builtins-install.c:181 app/flatpak-builtins-install.c:234
#: app/flatpak-builtins-install.c:298 app/flatpak-builtins-list.c:419
#: app/flatpak-builtins-make-current.c:72 app/flatpak-builtins-override.c:73
#: app/flatpak-builtins-permission-list.c:162
#: app/flatpak-builtins-permission-remove.c:132
#: app/flatpak-builtins-remote-add.c:323
#: app/flatpak-builtins-remote-delete.c:68
#: app/flatpak-builtins-remote-list.c:241 app/flatpak-builtins-remote-ls.c:407
msgid "Too many arguments"
msgstr "बहुत ज्यादा तर्क"

#: app/flatpak-builtins-build-bundle.c:659
#: app/flatpak-builtins-build-commit-from.c:338
#: app/flatpak-builtins-build-commit-from.c:351
#: app/flatpak-builtins-build-import-bundle.c:145
#, c-format
msgid "'%s' is not a valid repository"
msgstr "'%s' मान्य रिपोजिटरी नहीं है"

#: app/flatpak-builtins-build-bundle.c:663
#, c-format
msgid "'%s' is not a valid repository: "
msgstr "'%s' मान्य रिपोजिटरी नहीं है: "

#: app/flatpak-builtins-build-bundle.c:674 app/flatpak-builtins-build-sign.c:88
#: common/flatpak-dir.c:14293
#, c-format
msgid "'%s' is not a valid name: %s"
msgstr "'%s' मान्य नाम नहीं है: %s"

#: app/flatpak-builtins-build-bundle.c:677
#: app/flatpak-builtins-build-export.c:865 app/flatpak-builtins-build-sign.c:91
#: common/flatpak-dir.c:14299
#, c-format
msgid "'%s' is not a valid branch name: %s"
msgstr "'%s' मान्य शाखा नाम नहीं है: %s"

#: app/flatpak-builtins-build-bundle.c:691
#: app/flatpak-builtins-build-import-bundle.c:149
#: app/flatpak-builtins-build-init.c:281
#, c-format
msgid "'%s' is not a valid filename"
msgstr "'%s' मान्य फाइल नाम नहीं है"

#: app/flatpak-builtins-build-bundle.c:706
msgid "--oci-layer-compress value must be gzip or zstd"
msgstr ""

#: app/flatpak-builtins-build.c:49
msgid "Use Platform runtime rather than Sdk"
msgstr "SDK के बजाय प्लेटफ़ॉर्म रनटाइम का प्रयोग करें"

#: app/flatpak-builtins-build.c:50
msgid "Make destination readonly"
msgstr "गंतव्य को केवल-पढ़ने योग्य बनाएं"

#: app/flatpak-builtins-build.c:51
msgid "Add bind mount"
msgstr "बाइंड माउंट जोड़ें"

#: app/flatpak-builtins-build.c:51
msgid "DEST=SRC"
msgstr "DEST=SRC"

#: app/flatpak-builtins-build.c:52
msgid "Start build in this directory"
msgstr "इस निर्देशिका में निर्माण प्रारंभ करें"

#: app/flatpak-builtins-build.c:52 app/flatpak-builtins-build.c:53
#: app/flatpak-builtins-build-init.c:64 app/flatpak-builtins-run.c:160
msgid "DIR"
msgstr "निर्देशिका"

#: app/flatpak-builtins-build.c:53
msgid "Where to look for custom sdk dir (defaults to 'usr')"
msgstr "तदनुकूल SDK निर्देशिका कहां देखें (तयशुदा 'usr' है)"

#: app/flatpak-builtins-build.c:54 app/flatpak-builtins-build-export.c:67
msgid "Use alternative file for the metadata"
msgstr "मेटाडेटा के लिए वैकल्पिक फाइल का प्रयोग करें"

#: app/flatpak-builtins-build.c:55 app/flatpak-builtins-run.c:177
msgid "Kill processes when the parent process dies"
msgstr "जब प्रधान प्रक्रिया समाप्त हो जाए तो प्रक्रियाओं को समाप्त कर दें"

#: app/flatpak-builtins-build.c:56
msgid "Export application homedir directory to build"
msgstr "निर्माण के लिए अनुप्रयोग गृह-निर्देशिका निर्यात करें"

#: app/flatpak-builtins-build.c:57 app/flatpak-builtins-run.c:165
msgid "Log session bus calls"
msgstr "सत्र बस कॉल लॉग करें"

#: app/flatpak-builtins-build.c:58 app/flatpak-builtins-run.c:166
msgid "Log system bus calls"
msgstr "सिस्टम बस कॉल लॉग करें"

#: app/flatpak-builtins-build.c:262
msgid "DIRECTORY [COMMAND [ARGUMENT…]] - Build in directory"
msgstr "निर्देशिका [कमांड [तर्क…]] - निर्देशिका में बनाएं"

#: app/flatpak-builtins-build.c:285 app/flatpak-builtins-build-finish.c:656
msgid "DIRECTORY must be specified"
msgstr "निर्देशिका निर्दिष्ट होनी चाहिए"

#: app/flatpak-builtins-build.c:296 app/flatpak-builtins-build-export.c:887
#, c-format
msgid "Build directory %s not initialized, use flatpak build-init"
msgstr "निर्माण निर्देशिका %s प्रारंभ नहीं हुई, flatpak build-init का प्रयोग करें"

#: app/flatpak-builtins-build.c:315
msgid "metadata invalid, not application or runtime"
msgstr "मेटाडेटा अमान्य है, अनुप्रयोग या रनटाइम नहीं"

#: app/flatpak-builtins-build.c:446
#, c-format
msgid "No extension point matching %s in %s"
msgstr "%2$s में %1$s से मेल खाने वाला कोई विस्तार बिंदु नहीं"

#: app/flatpak-builtins-build.c:635
#, c-format
msgid "Missing '=' in bind mount option '%s'"
msgstr "बाइंड माउंट विकल्प '%s' में '=' गुम है"

#: app/flatpak-builtins-build.c:679 common/flatpak-run.c:3961
#, c-format
msgid "Unable to start app"
msgstr "ऐप प्रारंभ करने में असमर्थ"

#: app/flatpak-builtins-build-commit-from.c:58
msgid "Source repo dir"
msgstr "स्रोत रेपो निर्देशिका"

#: app/flatpak-builtins-build-commit-from.c:58
msgid "SRC-REPO"
msgstr "SRC-REPO"

#: app/flatpak-builtins-build-commit-from.c:59
msgid "Source repo ref"
msgstr "स्रोत रेपो निर्देशिका"

#: app/flatpak-builtins-build-commit-from.c:59
msgid "SRC-REF"
msgstr "SRC-REF"

#: app/flatpak-builtins-build-commit-from.c:64
#: app/flatpak-builtins-build-export.c:60
msgid "One line subject"
msgstr "एक पंक्ति विषय"

#: app/flatpak-builtins-build-commit-from.c:64
#: app/flatpak-builtins-build-export.c:60
msgid "SUBJECT"
msgstr "विषय"

#: app/flatpak-builtins-build-commit-from.c:65
#: app/flatpak-builtins-build-export.c:61
msgid "Full description"
msgstr "पूर्ण विवरण"

#: app/flatpak-builtins-build-commit-from.c:65
#: app/flatpak-builtins-build-export.c:61
msgid "BODY"
msgstr "मुख्यभाग"

#: app/flatpak-builtins-build-commit-from.c:66
#: app/flatpak-builtins-build-export.c:64
#: app/flatpak-builtins-build-import-bundle.c:51
msgid "Update the appstream branch"
msgstr "एपस्ट्रीम शाखा को अद्यतन करें"

#: app/flatpak-builtins-build-commit-from.c:67
#: app/flatpak-builtins-build-export.c:65
#: app/flatpak-builtins-build-import-bundle.c:52
#: app/flatpak-builtins-build-update-repo.c:87
msgid "Don't update the summary"
msgstr "सारांश को अद्यतन न करें"

#: app/flatpak-builtins-build-commit-from.c:68
#: app/flatpak-builtins-build-export.c:68
#: app/flatpak-builtins-build-import-bundle.c:49
#: app/flatpak-builtins-build-sign.c:44
msgid "GPG Key ID to sign the commit with"
msgstr "कमिट पर हस्ताक्षर करने हेतु GPG कुंजी ID"

#: app/flatpak-builtins-build-commit-from.c:70
#: app/flatpak-builtins-build-export.c:73
msgid "Mark build as end-of-life"
msgstr "निर्माण को जीवन-समाप्ति के रूप में चिह्नित करें"

#: app/flatpak-builtins-build-commit-from.c:70
#: app/flatpak-builtins-build-export.c:73
msgid "REASON"
msgstr "कारण"

#: app/flatpak-builtins-build-commit-from.c:71
msgid ""
"Mark refs matching the OLDID prefix as end-of-life, to be replaced with the "
"given NEWID"
msgstr ""
"OLDID उपसर्ग से मेल खाने वाले संदर्भ को जीवन के अंत के रूप में चिह्नित करें, जिसे दिए गए "
"NEWID से प्रतिस्थापित किया जाना है"

#: app/flatpak-builtins-build-commit-from.c:71
msgid "OLDID=NEWID"
msgstr "OLDID=NEWID"

#: app/flatpak-builtins-build-commit-from.c:72
#: app/flatpak-builtins-build-export.c:75
msgid "Set type of token needed to install this commit"
msgstr "इस कमिट को स्थापित करने के लिए आवश्यक टोकन का प्रकार निर्धारित करें"

#: app/flatpak-builtins-build-commit-from.c:72
#: app/flatpak-builtins-build-export.c:75
msgid "VAL"
msgstr "मान"

#: app/flatpak-builtins-build-commit-from.c:73
msgid "Override the timestamp of the commit (NOW for current time)"
msgstr "कमिट के समय-चिह्न को अध्यारोहण करें (अभी वर्तमान समय के लिए)"

#: app/flatpak-builtins-build-commit-from.c:73
#: app/flatpak-builtins-build-export.c:76
msgid "TIMESTAMP"
msgstr "समय-चिह्न"

#: app/flatpak-builtins-build-commit-from.c:75
#: app/flatpak-builtins-build-export.c:80
#: app/flatpak-builtins-build-import-bundle.c:53
#: app/flatpak-builtins-build-update-repo.c:97
msgid "Don't generate a summary index"
msgstr "सारांश सूचकांक उत्पन्न न करें"

#: app/flatpak-builtins-build-commit-from.c:278
msgid "DST-REPO [DST-REF…] - Make a new commit from existing commits"
msgstr "DST-REPO [DST-REF…] - मौजूदा कमिट से एक नया कमिट बनाएं"

#: app/flatpak-builtins-build-commit-from.c:285
msgid "DST-REPO must be specified"
msgstr "DST-REPO निर्दिष्ट होना चाहिए"

#: app/flatpak-builtins-build-commit-from.c:293
msgid ""
"If --src-repo is not specified, exactly one destination ref must be specified"
msgstr ""
"यदि --src-repo निर्दिष्ट नहीं है, तो बिल्कुल एक गंतव्य संदर्भ निर्दिष्ट किया जाना चाहिए"

#: app/flatpak-builtins-build-commit-from.c:296
msgid ""
"If --src-ref is specified, exactly one destination ref must be specified"
msgstr "यदि --src-ref निर्दिष्ट है, तो बिल्कुल एक गंतव्य संदर्भ निर्दिष्ट किया जाना चाहिए"

#: app/flatpak-builtins-build-commit-from.c:299
msgid "Either --src-repo or --src-ref must be specified"
msgstr "या तो --src-repo या --src-ref निर्दिष्ट किया जाना चाहिए"

#: app/flatpak-builtins-build-commit-from.c:315
msgid "Invalid argument format of use  --end-of-life-rebase=OLDID=NEWID"
msgstr "प्रयोग का अमान्य तर्क प्रारूप --end-of-life-rebase=OLDID=NEWID"

#: app/flatpak-builtins-build-commit-from.c:321
#: app/flatpak-builtins-build-commit-from.c:324
#, c-format
msgid "Invalid name %s in --end-of-life-rebase"
msgstr "--end-of-life-rebase में अमान्य नाम %s"

#: app/flatpak-builtins-build-commit-from.c:333
#: app/flatpak-builtins-build-export.c:1092
#, c-format
msgid "Could not parse '%s'"
msgstr "'%s' का विश्लेषण नहीं किया जा सका"

#: app/flatpak-builtins-build-commit-from.c:498
msgid "Can't commit from partial source commit"
msgstr "आंशिक स्रोत कमिट से कमिट नहीं किया जा सकता"

#: app/flatpak-builtins-build-commit-from.c:503
#, c-format
msgid "%s: no change\n"
msgstr "%s: कोई परिवर्तन नहीं\n"

#: app/flatpak-builtins-build-export.c:62
msgid "Architecture to export for (must be host compatible)"
msgstr "निर्यात के लिए आर्किटेक्चर (होस्ट संगत होना चाहिए)"

#: app/flatpak-builtins-build-export.c:63
msgid "Commit runtime (/usr), not /app"
msgstr "रनटाइम (/usr) कमिट करें, /app नहीं"

#: app/flatpak-builtins-build-export.c:66
msgid "Use alternative directory for the files"
msgstr "फाइलों के लिए वैकल्पिक निर्देशिका का प्रयोग करें"

#: app/flatpak-builtins-build-export.c:66
msgid "SUBDIR"
msgstr "उपनिर्देशिका"

#: app/flatpak-builtins-build-export.c:69
msgid "Files to exclude"
msgstr "बहिष्कृत करने के लिए फाइलें"

#: app/flatpak-builtins-build-export.c:69
#: app/flatpak-builtins-build-export.c:70
#: app/flatpak-builtins-build-update-repo.c:90
msgid "PATTERN"
msgstr "प्रतिमान"

#: app/flatpak-builtins-build-export.c:70
msgid "Excluded files to include"
msgstr "शामिल करने के लिए बहिष्कृत फाइलें"

#: app/flatpak-builtins-build-export.c:74
msgid "Mark build as end-of-life, to be replaced with the given ID"
msgstr "निर्माण को जीवन-समाप्ति के रूप में चिह्नित करें, जिसे दी गई ID से बदला जाएगा"

#: app/flatpak-builtins-build-export.c:74
#: app/flatpak-builtins-document-list.c:49 app/flatpak-cli-transaction.c:1427
msgid "ID"
msgstr "ID"

#: app/flatpak-builtins-build-export.c:76
msgid "Override the timestamp of the commit"
msgstr "कमिट के समय-चिह्न को अध्यारोहण करें"

#: app/flatpak-builtins-build-export.c:77
#: app/flatpak-builtins-build-update-repo.c:75
#: app/flatpak-builtins-remote-add.c:83 app/flatpak-builtins-remote-list.c:54
#: app/flatpak-builtins-remote-modify.c:88
msgid "Collection ID"
msgstr "संग्रह ID"

#: app/flatpak-builtins-build-export.c:472
#, c-format
msgid "WARNING: Error running desktop-file-validate: %s\n"
msgstr "चेतावनी: desktop-file-validate चलाने में त्रुटि: %s\n"

#: app/flatpak-builtins-build-export.c:480
#, c-format
msgid "WARNING: Error reading from desktop-file-validate: %s\n"
msgstr "चेतावनी: desktop-file-validate से पढ़ने में त्रुटि: %s\n"

#: app/flatpak-builtins-build-export.c:486
#, c-format
msgid "WARNING: Failed to validate desktop file %s: %s\n"
msgstr "चेतावनी: डेस्कटॉप फाइल %s को सत्यापित करने में विफल: %s\n"

#: app/flatpak-builtins-build-export.c:513
#, c-format
msgid "WARNING: Can't find Exec key in %s: %s\n"
msgstr "चेतावनी: %s में निष्पादन कुंजी नहीं मिल सकी: %s\n"

#: app/flatpak-builtins-build-export.c:521
#: app/flatpak-builtins-build-export.c:614
#, c-format
msgid "WARNING: Binary not found for Exec line in %s: %s\n"
msgstr "चेतावनी: %s में निष्पादन पंक्ति के लिए बाइनरी नहीं मिली: %s\n"

#: app/flatpak-builtins-build-export.c:529
#, c-format
msgid "WARNING: Icon not matching app id in %s: %s\n"
msgstr "चेतावनी: %s में आइकन ऐप ID से मेल नहीं खा रहा है: %s\n"

#: app/flatpak-builtins-build-export.c:552
#, c-format
msgid "WARNING: Icon referenced in desktop file but not exported: %s\n"
msgstr "चेतावनी: आइकन डेस्कटॉप फाइल में संदर्भित है लेकिन निर्यात नहीं किया गया है: %s\n"

#: app/flatpak-builtins-build-export.c:719
#, c-format
msgid "Invalid uri type %s, only http/https supported"
msgstr "अमान्य URI प्रकार %s, केवल http/https समर्थित है"

#: app/flatpak-builtins-build-export.c:737
#, c-format
msgid "Unable to find basename in %s, specify a name explicitly"
msgstr "%s में बेसनाम ढूंढने में असमर्थ, स्पष्ट रूप से एक नाम निर्दिष्ट करें"

#: app/flatpak-builtins-build-export.c:746
#, c-format
msgid "No slashes allowed in extra data name"
msgstr "अतिरिक्त डेटा नाम में कोई कटौती की अनुमति नहीं है"

#: app/flatpak-builtins-build-export.c:758
#, c-format
msgid "Invalid format for sha256 checksum: '%s'"
msgstr "SHA256 चेकसम के लिए अमान्य प्रारूप: '%s'"

#: app/flatpak-builtins-build-export.c:768
#, c-format
msgid "Extra data sizes of zero not supported"
msgstr "शून्य के अतिरिक्त डेटा आकार समर्थित नहीं हैं"

#: app/flatpak-builtins-build-export.c:830
msgid ""
"LOCATION DIRECTORY [BRANCH] - Create a repository from a build directory"
msgstr "स्थान निर्देशिका [शाखा] - एक निर्माण निर्देशिका से एक रिपॉजिटरी बनाएं"

#: app/flatpak-builtins-build-export.c:838
msgid "LOCATION and DIRECTORY must be specified"
msgstr "स्थान और निर्देशिका निर्दिष्ट होनी चाहिए"

#: app/flatpak-builtins-build-export.c:859
#: app/flatpak-builtins-remote-add.c:327
#, c-format
msgid "‘%s’ is not a valid collection ID: %s"
msgstr "‘%s’ मान्य संग्रह ID नहीं है: %s"

#: app/flatpak-builtins-build-export.c:904
#: app/flatpak-builtins-build-finish.c:684
msgid "No name specified in the metadata"
msgstr "मेटाडेटा में कोई नाम निर्दिष्ट नहीं है"

#: app/flatpak-builtins-build-export.c:1166
#, c-format
msgid "Commit: %s\n"
msgstr "कमिट: %s\n"

#: app/flatpak-builtins-build-export.c:1167
#, c-format
msgid "Metadata Total: %u\n"
msgstr "कुल मेटाडेटा: %u\n"

#: app/flatpak-builtins-build-export.c:1168
#, c-format
msgid "Metadata Written: %u\n"
msgstr "लिखित मेटाडेटा: %u\n"

#: app/flatpak-builtins-build-export.c:1169
#, c-format
msgid "Content Total: %u\n"
msgstr "कुल सामग्री: %u\n"

#: app/flatpak-builtins-build-export.c:1170
#, c-format
msgid "Content Written: %u\n"
msgstr "लिखित सामग्री: %u\n"

#: app/flatpak-builtins-build-export.c:1171
#, c-format
msgid "Content Bytes Written:"
msgstr "लिखित सामग्री बाइट्स:"

#: app/flatpak-builtins-build-finish.c:52
msgid "Command to set"
msgstr "निर्धारित करने हेतु कमांड"

#: app/flatpak-builtins-build-finish.c:52 app/flatpak-builtins-run.c:159
#: app/flatpak-main.c:209
msgid "COMMAND"
msgstr "कमांड"

#: app/flatpak-builtins-build-finish.c:53
msgid "Flatpak version to require"
msgstr "आवश्यकता Flatpak संस्करण"

#: app/flatpak-builtins-build-finish.c:53
msgid "MAJOR.MINOR.MICRO"
msgstr "प्रमुख.मामूली.सूक्ष्म"

#: app/flatpak-builtins-build-finish.c:54
msgid "Don't process exports"
msgstr "निर्यात संसाधित न करें"

#: app/flatpak-builtins-build-finish.c:55
msgid "Extra data info"
msgstr "अतिरिक्त डेटा जानकारी"

#: app/flatpak-builtins-build-finish.c:56 app/flatpak-builtins-build-init.c:63
msgid "Add extension point info"
msgstr "एक्सटेंशन बिंदु जानकारी जोड़ें"

#: app/flatpak-builtins-build-finish.c:56 app/flatpak-builtins-build-init.c:63
msgid "NAME=VARIABLE[=VALUE]"
msgstr "नाम=चर[=मान]"

#: app/flatpak-builtins-build-finish.c:57
msgid "Remove extension point info"
msgstr "एक्सटेंशन बिंदु जानकारी हटाएं"

#: app/flatpak-builtins-build-finish.c:57
#: app/flatpak-builtins-build-update-repo.c:79 app/flatpak-builtins-info.c:58
#: app/flatpak-builtins-remote-add.c:88 app/flatpak-builtins-remote-modify.c:94
#: app/flatpak-main.c:182
msgid "NAME"
msgstr "नाम"

#: app/flatpak-builtins-build-finish.c:58
msgid "Set extension priority (only for extensions)"
msgstr "एक्सटेंशन की प्राथमिकता निर्धारित करें (केवल एक्सटेंशन के लिए)"

#: app/flatpak-builtins-build-finish.c:58
msgid "VALUE"
msgstr "मान"

#: app/flatpak-builtins-build-finish.c:59
msgid "Change the sdk used for the app"
msgstr "ऐप के लिए प्रयुक्त SDK बदलें"

#: app/flatpak-builtins-build-finish.c:59
msgid "SDK"
msgstr "SDK"

#: app/flatpak-builtins-build-finish.c:60
msgid "Change the runtime used for the app"
msgstr "ऐप के लिए प्रयोग किए गए रनटाइम को बदलें"

#: app/flatpak-builtins-build-finish.c:60 app/flatpak-builtins-build-init.c:54
#: app/flatpak-builtins-list.c:53 app/flatpak-builtins-remote-ls.c:58
#: app/flatpak-builtins-run.c:163
msgid "RUNTIME"
msgstr "रनटाइम"

#: app/flatpak-builtins-build-finish.c:61
msgid "Set generic metadata option"
msgstr "सामान्य मेटाडेटा विकल्प निर्धारित करें"

#: app/flatpak-builtins-build-finish.c:61
msgid "GROUP=KEY[=VALUE]"
msgstr "समूह=कुंजी[=मान]"

#: app/flatpak-builtins-build-finish.c:62
msgid "Don't inherit permissions from runtime"
msgstr "रनटाइम से अनुमतियां प्राप्त न करें"

#: app/flatpak-builtins-build-finish.c:155
#, c-format
msgid "Not exporting %s, wrong extension\n"
msgstr "%s निर्यात नहीं हो रहा, गलत एक्सटेंशन\n"

#: app/flatpak-builtins-build-finish.c:163
#, c-format
msgid "Not exporting %s, non-allowed export filename\n"
msgstr "%s निर्यात नहीं किया जा रहा, गैर-अनुमत निर्यात फाइल नाम\n"

#: app/flatpak-builtins-build-finish.c:167
#, c-format
msgid "Exporting %s\n"
msgstr "%s निर्यात किया जा रहा है\n"

#: app/flatpak-builtins-build-finish.c:440
#, c-format
msgid "More than one executable found\n"
msgstr "एक से अधिक निष्पादनयोग्य मिले\n"

#: app/flatpak-builtins-build-finish.c:451
#, c-format
msgid "Using %s as command\n"
msgstr "कमांड के रूप में %s का प्रयोग करना\n"

#: app/flatpak-builtins-build-finish.c:456
#, c-format
msgid "No executable found\n"
msgstr "कोई निष्पादन-योग्य नहीं मिला\n"

#: app/flatpak-builtins-build-finish.c:511
#, c-format
msgid "Invalid --require-version argument: %s"
msgstr "अमान्य --require-version तर्क: %s"

#: app/flatpak-builtins-build-finish.c:543
#, c-format
msgid "Too few elements in --extra-data argument %s"
msgstr "--extra-data तर्क %s में बहुत कम तत्व"

#: app/flatpak-builtins-build-finish.c:575
#, c-format
msgid ""
"Too few elements in --metadata argument %s, format should be "
"GROUP=KEY[=VALUE]]"
msgstr "--metadata तर्क %s में बहुत कम तत्व, प्रारूप समूह=कुंजी[=मान]] होना चाहिए"

#: app/flatpak-builtins-build-finish.c:597
#: app/flatpak-builtins-build-init.c:458
#, c-format
msgid ""
"Too few elements in --extension argument %s, format should be "
"NAME=VAR[=VALUE]"
msgstr "--extension तर्क %s में बहुत कम तत्व, प्रारूप नाम=परिवर्तनीय[=मान] होना चाहिए"

#: app/flatpak-builtins-build-finish.c:603
#: app/flatpak-builtins-build-init.c:461
#, c-format
msgid "Invalid extension name %s"
msgstr "अमान्य एक्सटेंशन नाम %s"

#: app/flatpak-builtins-build-finish.c:646
msgid "DIRECTORY - Finalize a build directory"
msgstr "निर्देशिका - एक निर्माण निर्देशिका को अंतिम रूप दें"

#: app/flatpak-builtins-build-finish.c:668
#, c-format
msgid "Build directory %s not initialized"
msgstr "निर्माण निर्देशिका %s प्रारंभ नहीं हुई"

#: app/flatpak-builtins-build-finish.c:689
#, c-format
msgid "Build directory %s already finalized"
msgstr "निर्माण निर्देशिका %s को पहले ही अंतिम रूप दिया जा चुका है"

#: app/flatpak-builtins-build-finish.c:702
#, c-format
msgid "Please review the exported files and the metadata\n"
msgstr "कृपया निर्यात की गई फाइलों और मेटाडेटा की समीक्षा करें\n"

#: app/flatpak-builtins-build-import-bundle.c:47
msgid "Override the ref used for the imported bundle"
msgstr "आयातित बंडल के लिए प्रयुक्त संदर्भ को अध्यारोहण करें"

#: app/flatpak-builtins-build-import-bundle.c:47
msgid "REF"
msgstr "संदर्भ"

#: app/flatpak-builtins-build-import-bundle.c:48
msgid "Import oci image instead of flatpak bundle"
msgstr "Flatpak बंडल के बजाय OCI छवि आयात करें"

#: app/flatpak-builtins-build-import-bundle.c:77
#: app/flatpak-builtins-build-import-bundle.c:105
#, c-format
msgid "Importing %s (%s)\n"
msgstr "%s आयात किया जा रहा है (%s)\n"

#: app/flatpak-builtins-build-import-bundle.c:126
msgid "LOCATION FILENAME - Import a file bundle into a local repository"
msgstr "स्थान फाइलनाम - फाइल बंडल को स्थानीय रिपॉजिटरी में आयात करें"

#: app/flatpak-builtins-build-import-bundle.c:133
msgid "LOCATION and FILENAME must be specified"
msgstr "स्थान और फाइलनाम निर्दिष्ट होना चाहिए"

#: app/flatpak-builtins-build-init.c:53 app/flatpak-builtins-info.c:55
#: app/flatpak-builtins-run.c:158
msgid "Arch to use"
msgstr "प्रयोग करने के लिए आर्किटेक्चर"

#: app/flatpak-builtins-build-init.c:54
msgid "Initialize var from named runtime"
msgstr "नामित रनटाइम से var प्रारंभ करें"

#: app/flatpak-builtins-build-init.c:55
msgid "Initialize apps from named app"
msgstr "नामित ऐप से ऐप्स प्रारंभ करें"

#: app/flatpak-builtins-build-init.c:55
msgid "APP"
msgstr "ऐप"

#: app/flatpak-builtins-build-init.c:56
msgid "Specify version for --base"
msgstr "--base के लिए संस्करण निर्दिष्ट करें"

#: app/flatpak-builtins-build-init.c:56 app/flatpak-builtins-run.c:164
msgid "VERSION"
msgstr "संस्करण"

#: app/flatpak-builtins-build-init.c:57
msgid "Include this base extension"
msgstr "इस आधार एक्सटेंशन को शामिल करें"

#: app/flatpak-builtins-build-init.c:57 app/flatpak-builtins-build-init.c:62
msgid "EXTENSION"
msgstr "एक्सटेंशन"

#: app/flatpak-builtins-build-init.c:58
msgid "Extension tag to use if building extension"
msgstr "एक्सटेंशन बनाते समय प्रयोग के लिए एक्सटेंशन टैग"

#: app/flatpak-builtins-build-init.c:58
msgid "EXTENSION_TAG"
msgstr "एक्सटेंशन_टैग"

#: app/flatpak-builtins-build-init.c:59
msgid "Initialize /usr with a writable copy of the sdk"
msgstr "SDK की एक लिखने योग्य प्रति के साथ /usr प्रारंभ करें"

#: app/flatpak-builtins-build-init.c:60
msgid "Specify the build type (app, runtime, extension)"
msgstr "निर्माण प्रकार निर्दिष्ट करें (ऐप, रनटाइम, एक्सटेंशन)"

#: app/flatpak-builtins-build-init.c:60
msgid "TYPE"
msgstr "प्रकार"

#: app/flatpak-builtins-build-init.c:61
msgid "Add a tag"
msgstr "टैग जोड़ें"

#: app/flatpak-builtins-build-init.c:61
msgid "TAG"
msgstr "टैग"

#: app/flatpak-builtins-build-init.c:62
msgid "Include this sdk extension in /usr"
msgstr "इस SDK एक्सटेंशन को /usr में शामिल करें"

#: app/flatpak-builtins-build-init.c:64
msgid "Where to store sdk (defaults to 'usr')"
msgstr "SDK को कहां संग्रहित करें (तयशुदा रूप से 'usr')"

#: app/flatpak-builtins-build-init.c:65
msgid "Re-initialize the sdk/var"
msgstr "SDK/var को पुनः प्रारंभ करें"

#: app/flatpak-builtins-build-init.c:118
#, c-format
msgid "Requested extension %s/%s/%s is only partially installed"
msgstr "अनुरोधित एक्सटेंशन %s/%s/%s केवल आंशिक रूप से स्थापित है"

#: app/flatpak-builtins-build-init.c:147
#, c-format
msgid "Requested extension %s/%s/%s not installed"
msgstr "अनुरोधित एक्सटेंशन %s/%s/%s स्थापित नहीं है"

#: app/flatpak-builtins-build-init.c:207
msgid ""
"DIRECTORY APPNAME SDK RUNTIME [BRANCH] - Initialize a directory for building"
msgstr "निर्देशिका ऐपनाम SDK रनटाइम [शाखा] - निर्माण के लिए एक निर्देशिका प्रारंभ करें"

#: app/flatpak-builtins-build-init.c:214
msgid "RUNTIME must be specified"
msgstr "रनटाइम निर्दिष्ट होना चाहिए"

#: app/flatpak-builtins-build-init.c:235
#, c-format
msgid "'%s' is not a valid build type name, use app, runtime or extension"
msgstr "'%s' मान्य बिल्ड प्रकार का नाम नहीं है, ऐप, रनटाइम या एक्सटेंशन का प्रयोग करें"

#: app/flatpak-builtins-build-init.c:241 app/flatpak-builtins-override.c:79
#, c-format
msgid "'%s' is not a valid application name: %s"
msgstr "'%s' मान्य अनुप्रयोग नाम नहीं है: %s"

#: app/flatpak-builtins-build-init.c:295
#, c-format
msgid "Build directory %s already initialized"
msgstr "बिल्ड निर्देशिका %s पहले ही प्रारंभ हो चुकी है"

#: app/flatpak-builtins-build-sign.c:42 app/flatpak-builtins-install.c:67
#: app/flatpak-builtins-remote-info.c:54
msgid "Arch to install for"
msgstr "स्थापित करने हेतु आर्किटेक्चर"

#: app/flatpak-builtins-build-sign.c:43 app/flatpak-builtins-create-usb.c:48
#: app/flatpak-builtins-install.c:74 app/flatpak-builtins-remote-info.c:56
#: app/flatpak-builtins-uninstall.c:58 app/flatpak-builtins-update.c:64
msgid "Look for runtime with the specified name"
msgstr "निर्दिष्ट नाम के साथ रनटाइम देखें"

#: app/flatpak-builtins-build-sign.c:66
msgid "LOCATION [ID [BRANCH]] - Sign an application or runtime"
msgstr "स्थान [ID [शाखा]] - एक आवेदन या रनटाइम पर हस्ताक्षर करें"

#: app/flatpak-builtins-build-sign.c:73
#: app/flatpak-builtins-build-update-repo.c:499
#: app/flatpak-builtins-remote-add.c:320 app/flatpak-builtins-repo.c:739
msgid "LOCATION must be specified"
msgstr "स्थान निर्दिष्ट किया जाना चाहिए"

#: app/flatpak-builtins-build-sign.c:94
msgid "No gpg key ids specified"
msgstr "कोई gpg कुंजी ID निर्दिष्ट नहीं है"

#: app/flatpak-builtins-build-update-repo.c:68
msgid "Redirect this repo to a new URL"
msgstr "इस रेपो को एक नए URL पर पुनर्निर्देशित करें"

#: app/flatpak-builtins-build-update-repo.c:69
msgid "A nice name to use for this repository"
msgstr "इस रिपॉजिटरी के लिए प्रयोग करने के लिए एक अच्छा नाम"

#: app/flatpak-builtins-build-update-repo.c:69
#: app/flatpak-builtins-remote-add.c:77 app/flatpak-builtins-remote-modify.c:82
msgid "TITLE"
msgstr "शीर्षक"

#: app/flatpak-builtins-build-update-repo.c:70
msgid "A one-line comment for this repository"
msgstr "इस रिपॉजिटरी के लिए एक पंक्ति की टिप्पणी"

#: app/flatpak-builtins-build-update-repo.c:70
#: app/flatpak-builtins-remote-add.c:78 app/flatpak-builtins-remote-modify.c:83
msgid "COMMENT"
msgstr "टिप्पणी"

#: app/flatpak-builtins-build-update-repo.c:71
msgid "A full-paragraph description for this repository"
msgstr "इस रिपॉजिटरी के लिए एक पूर्ण-अनुच्छेद विवरण"

#: app/flatpak-builtins-build-update-repo.c:71
#: app/flatpak-builtins-remote-add.c:79 app/flatpak-builtins-remote-modify.c:84
msgid "DESCRIPTION"
msgstr "विवरण"

#: app/flatpak-builtins-build-update-repo.c:72
msgid "URL for a website for this repository"
msgstr "इस रिपॉजिटरी के लिए वेबसाइट का URL"

#: app/flatpak-builtins-build-update-repo.c:73
msgid "URL for an icon for this repository"
msgstr "इस रिपॉजिटरी के लिए आइकन के लिए URL"

#: app/flatpak-builtins-build-update-repo.c:74
msgid "Default branch to use for this repository"
msgstr "इस रिपॉजिटरी के लिए प्रयोग करने के लिए तयशुदा शाखा"

#: app/flatpak-builtins-build-update-repo.c:74
#: app/flatpak-builtins-remote-add.c:82 app/flatpak-builtins-remote-modify.c:87
#: app/flatpak-builtins-repo.c:713 app/flatpak-builtins-repo.c:714
#: app/flatpak-builtins-run.c:161
msgid "BRANCH"
msgstr "शाखा"

#: app/flatpak-builtins-build-update-repo.c:75
#: app/flatpak-builtins-remote-add.c:83 app/flatpak-builtins-remote-modify.c:88
msgid "COLLECTION-ID"
msgstr "संग्रह-ID"

#. Translators: A sideload is when you install from a local USB drive rather than the Internet.
#: app/flatpak-builtins-build-update-repo.c:77
msgid ""
"Permanently deploy collection ID to client remote configurations, only for "
"sideload support"
msgstr ""
"केवल साइडलोड समर्थन के लिए, क्लाइंट रिमोट विन्यास में संग्रह ID को स्थायी रूप से "
"परिनियोजित करें"

#: app/flatpak-builtins-build-update-repo.c:78
msgid "Permanently deploy collection ID to client remote configurations"
msgstr "क्लाइंट रिमोट विन्यास में संग्रह ID को स्थायी रूप से परिनियोजित करें"

#: app/flatpak-builtins-build-update-repo.c:79
msgid "Name of authenticator for this repository"
msgstr "इस रिपॉजिटरी के लिए प्रमाणक का नाम"

#: app/flatpak-builtins-build-update-repo.c:80
msgid "Autoinstall authenticator for this repository"
msgstr "इस रिपॉजिटरी के लिए प्रमाणक को स्वतः स्थापित करें"

#: app/flatpak-builtins-build-update-repo.c:81
msgid "Don't autoinstall authenticator for this repository"
msgstr "इस रिपॉजिटरी के लिए प्रमाणक को स्वतः स्थापित न करें"

#: app/flatpak-builtins-build-update-repo.c:82
#: app/flatpak-builtins-remote-add.c:89
msgid "Authenticator option"
msgstr "प्रमाणक विकल्प"

#: app/flatpak-builtins-build-update-repo.c:82
#: app/flatpak-builtins-remote-add.c:89 app/flatpak-builtins-remote-modify.c:95
msgid "KEY=VALUE"
msgstr "कुंजी=मान"

#: app/flatpak-builtins-build-update-repo.c:83
msgid "Import new default GPG public key from FILE"
msgstr "फाइल से नई तयशुदा GPG सार्वजनिक कुंजी आयात करें"

#: app/flatpak-builtins-build-update-repo.c:84
msgid "GPG Key ID to sign the summary with"
msgstr "सारांश पर हस्ताक्षर करने के लिए GPG कुंजी ID"

#: app/flatpak-builtins-build-update-repo.c:86
msgid "Generate delta files"
msgstr "डेल्टा फाइलें उत्पन्न करें"

#: app/flatpak-builtins-build-update-repo.c:88
msgid "Don't update the appstream branch"
msgstr "ऐपस्ट्रीम शाखा को अद्यतन न करें"

#: app/flatpak-builtins-build-update-repo.c:89
msgid "Max parallel jobs when creating deltas (default: NUMCPUs)"
msgstr "डेल्टा बनाते समय अधिकतम समानांतर नौकरियां (तयशुदा: NUMCPUs)"

#: app/flatpak-builtins-build-update-repo.c:89
msgid "NUM-JOBS"
msgstr "NUM-JOBS"

#: app/flatpak-builtins-build-update-repo.c:90
msgid "Don't create deltas matching refs"
msgstr "डेल्टा मिलान संदर्भ न बनाएं"

#: app/flatpak-builtins-build-update-repo.c:91
msgid "Prune unused objects"
msgstr "अप्रयुक्त वस्तुओं को छाँटें"

#: app/flatpak-builtins-build-update-repo.c:92
msgid "Prune but don't actually remove anything"
msgstr "छँटाई करें लेकिन वास्तव में कुछ भी न हटाएं"

#: app/flatpak-builtins-build-update-repo.c:93
msgid "Only traverse DEPTH parents for each commit (default: -1=infinite)"
msgstr "प्रत्येक कमिट के लिए केवल प्रधान गहराई को पार करें (तयशुदा: -1=अनंत)"

#: app/flatpak-builtins-build-update-repo.c:93
msgid "DEPTH"
msgstr "गहराई"

#: app/flatpak-builtins-build-update-repo.c:223
#, c-format
msgid "Generating delta: %s (%.10s)\n"
msgstr "डेल्टा उत्पन्न किया जा रहा है: %s (%.10s)\n"

#: app/flatpak-builtins-build-update-repo.c:225
#, c-format
msgid "Generating delta: %s (%.10s-%.10s)\n"
msgstr "डेल्टा उत्पन्न किया जा रहा है: %s (%.10s-%.10s)\n"

#: app/flatpak-builtins-build-update-repo.c:233
#, c-format
msgid "Failed to generate delta %s (%.10s): "
msgstr "डेल्टा %s (%.10s) उत्पन्न करने में विफल: "

#: app/flatpak-builtins-build-update-repo.c:236
#, c-format
msgid "Failed to generate delta %s (%.10s-%.10s): "
msgstr "डेल्टा %s (%.10s-%.10s) उत्पन्न करने में विफल: "

#: app/flatpak-builtins-build-update-repo.c:492
msgid "LOCATION - Update repository metadata"
msgstr "स्थान - रिपॉजिटरी मेटाडेटा अद्यतन करें"

#: app/flatpak-builtins-build-update-repo.c:609
#, c-format
msgid "Updating appstream branch\n"
msgstr "ऐपस्ट्रीम शाखा को अद्यतन किया जा रहा है\n"

#: app/flatpak-builtins-build-update-repo.c:638
#, c-format
msgid "Updating summary\n"
msgstr "सारांश अद्यतन किया जा रहा है\n"

#: app/flatpak-builtins-build-update-repo.c:664
#, c-format
msgid "Total objects: %u\n"
msgstr "कुल वस्तुएं: %u\n"

#: app/flatpak-builtins-build-update-repo.c:666
#, c-format
msgid "No unreachable objects\n"
msgstr "कोई पहुंच योग्य वस्तु नहीं\n"

#: app/flatpak-builtins-build-update-repo.c:668
#, c-format
msgid "Deleted %u objects, %s freed\n"
msgstr "%u वस्तुएं हटाये गये, %s मुक्त किये गये\n"

#: app/flatpak-builtins-config.c:41
msgid "List configuration keys and values"
msgstr "विन्यास कुंजियां और मान सूचीबद्ध करें"

#: app/flatpak-builtins-config.c:42
msgid "Get configuration for KEY"
msgstr "कुंजी के लिए विन्यास प्राप्त करें"

#: app/flatpak-builtins-config.c:43
msgid "Set configuration for KEY to VALUE"
msgstr "कुंजी के लिए विन्यास को मान पर निर्धारित करें"

#: app/flatpak-builtins-config.c:44
msgid "Unset configuration for KEY"
msgstr "कुंजी के लिए विन्यास अनिर्धारित करें"

#: app/flatpak-builtins-config.c:149
#, c-format
msgid "'%s' does not look like a language/locale code"
msgstr "'%s' भाषा/लोकेल कोड जैसा नहीं दिखता"

#: app/flatpak-builtins-config.c:172
#, c-format
msgid "'%s' does not look like a language code"
msgstr "'%s' भाषा कोड जैसा नहीं दिखता"

#: app/flatpak-builtins-config.c:190
#, fuzzy, c-format
msgid "'%s' is not a valid value (use 'true' or 'false')"
msgstr "'%s' मान्य रिपोजिटरी नहीं है: "

#: app/flatpak-builtins-config.c:262
#, c-format
msgid "Unknown configure key '%s'"
msgstr "अज्ञात विन्यास कुंजी '%s'"

#: app/flatpak-builtins-config.c:284
msgid "Too many arguments for --list"
msgstr "--list के लिए बहुत सारे तर्क"

#: app/flatpak-builtins-config.c:314 app/flatpak-builtins-config.c:362
msgid "You must specify KEY"
msgstr "आपको कुंजी निर्दिष्ट करनी होगी"

#: app/flatpak-builtins-config.c:316
msgid "Too many arguments for --get"
msgstr "--get के लिए बहुत सारे तर्क"

#: app/flatpak-builtins-config.c:338
msgid "You must specify KEY and VALUE"
msgstr "आपको कुंजी और मान निर्दिष्ट करना होगा"

#: app/flatpak-builtins-config.c:340
msgid "Too many arguments for --set"
msgstr "--set के लिए बहुत सारे तर्क"

#: app/flatpak-builtins-config.c:364
msgid "Too many arguments for --unset"
msgstr "--unset के लिए बहुत सारे तर्क"

#: app/flatpak-builtins-config.c:383
msgid "[KEY [VALUE]] - Manage configuration"
msgstr "[कुंजी [मान]] - विन्यास प्रबंधित करें"

#: app/flatpak-builtins-config.c:394
msgid "Can only use one of --list, --get, --set or --unset"
msgstr "केवल --list, --get, --set या --unset में से किसी एक का प्रयोग कर सकते हैं"

#: app/flatpak-builtins-config.c:408
msgid "Must specify one of --list, --get, --set or --unset"
msgstr "--list, --get, --set या --unset में से एक निर्दिष्ट करना होगा"

#: app/flatpak-builtins-create-usb.c:45 app/flatpak-builtins-install.c:75
#: app/flatpak-builtins-remote-info.c:57 app/flatpak-builtins-uninstall.c:59
#: app/flatpak-builtins-update.c:65
msgid "Look for app with the specified name"
msgstr "निर्दिष्ट नाम वाला ऐप खोजें"

#: app/flatpak-builtins-create-usb.c:46
msgid "Arch to copy"
msgstr "कॉपी करने के लिए आर्किटेक्चर"

#: app/flatpak-builtins-create-usb.c:47
msgid "DEST"
msgstr "गंतव्य"

#: app/flatpak-builtins-create-usb.c:49
msgid "Allow partial commits in the created repo"
msgstr "निर्मित रेपो में आंशिक कमिट की अनुमति दें"

#: app/flatpak-builtins-create-usb.c:125 app/flatpak-builtins-create-usb.c:165
#, c-format
msgid ""
"Warning: Related ref ‘%s’ is partially installed. Use --allow-partial to "
"suppress this message.\n"
msgstr ""
"चेतावनी: संबंधित संदर्भ ‘%s’ आंशिक रूप से स्थापित है। इस संदेश को दबाने के लिए --allow-"
"partial का प्रयोग करें।\n"

#: app/flatpak-builtins-create-usb.c:158
#, c-format
msgid "Warning: Omitting related ref ‘%s’ because it is not installed.\n"
msgstr "चेतावनी: संबंधित संदर्भ ‘%s’ को छोड़ दिया गया है क्योंकि यह स्थापित नहीं है।\n"

#: app/flatpak-builtins-create-usb.c:175
#, c-format
msgid ""
"Warning: Omitting related ref ‘%s’ because its remote ‘%s’ does not have a "
"collection ID set.\n"
msgstr ""
"चेतावनी: संबंधित संदर्भ ‘%s’ को छोड़ा जा रहा है क्योंकि इसके रिमोट ‘%s’ में संग्रह ID "
"निर्धारित नहीं है।\n"

#: app/flatpak-builtins-create-usb.c:187
#, c-format
msgid "Warning: Omitting related ref ‘%s’ because it's extra-data.\n"
msgstr "चेतावनी: संबंधित संदर्भ ‘%s’ को छोड़ दिया गया है क्योंकि यह अतिरिक्त डेटा है।\n"

#: app/flatpak-builtins-create-usb.c:262 app/flatpak-builtins-create-usb.c:637
#, c-format
msgid ""
"Remote ‘%s’ does not have a collection ID set, which is required for P2P "
"distribution of ‘%s’."
msgstr ""
"रिमोट ‘%s’ में संग्रह ID निर्धारित नहीं है, जो ‘%s’ के P2P वितरण के लिए आवश्यक है।"

#: app/flatpak-builtins-create-usb.c:272
#, c-format
msgid "Warning: Omitting ref ‘%s’ (runtime of ‘%s’) because it's extra-data.\n"
msgstr ""
"चेतावनी: संदर्भ ‘%s’ (‘%s’ का रनटाइम) को छोड़ा जा रहा है क्योंकि यह अतिरिक्त डेटा है।\n"

#: app/flatpak-builtins-create-usb.c:484
msgid "MOUNT-PATH [REF…] - Copy apps or runtimes onto removable media"
msgstr "माउंट-पथ [संदर्भ…] - ऐप्स या रनटाइम को हटाने योग्य मीडिया पर कॉपी करें"

#: app/flatpak-builtins-create-usb.c:493
msgid "MOUNT-PATH and REF must be specified"
msgstr "माउंट-पाथ और संदर्भ निर्दिष्ट किया जाना चाहिए"

#: app/flatpak-builtins-create-usb.c:607
#, c-format
msgid "Ref ‘%s’ found in multiple installations: %s. You must specify one."
msgstr "संदर्भ ‘%s’ कई स्थापनाओं में पाया गया: %s। आपको एक निर्दिष्ट करना होगा।"

#: app/flatpak-builtins-create-usb.c:620
#, c-format
msgid "Refs must all be in the same installation (found in %s and %s)."
msgstr "सभी संदर्भ एक ही स्थापना में होने चाहिए (%s और %s में पाए जाते हैं)।"

#: app/flatpak-builtins-create-usb.c:670
#, c-format
msgid ""
"Warning: Ref ‘%s’ is partially installed. Use --allow-partial to suppress "
"this message.\n"
msgstr ""
"चेतावनी: संदर्भ ‘%s’ आंशिक रूप से स्थापित है। इस संदेश को दबाने के लिए --allow-partial "
"का प्रयोग करें।\n"

#: app/flatpak-builtins-create-usb.c:681
#, c-format
msgid "Installed ref ‘%s’ is extra-data, and cannot be distributed offline"
msgstr "स्थापित रेफरी ‘%s’ अतिरिक्त डेटा है, और इसे ऑफ़लाइन वितरित नहीं किया जा सकता है"

#: app/flatpak-builtins-create-usb.c:721
#, c-format
msgid "Warning: Couldn't update repo metadata for remote ‘%s’: %s\n"
msgstr "चेतावनी: रिमोट ‘%s’ के लिए रेपो मेटाडेटा अद्यतन नहीं किया जा सका: %s\n"

#: app/flatpak-builtins-create-usb.c:751
#, c-format
msgid "Warning: Couldn't update appstream data for remote ‘%s’ arch ‘%s’: %s\n"
msgstr ""
"चेतावनी: रिमोट ‘%s’ आर्किटेक्चर ‘%s’ के लिए ऐपस्ट्रीम डेटा अद्यतित नहीं किया जा सका: "
"%s\n"

#. Print a warning if both appstream and appstream2 are missing
#: app/flatpak-builtins-create-usb.c:784
#, c-format
msgid ""
"Warning: Couldn't find appstream data for remote ‘%s’ arch ‘%s’: %s; %s\n"
msgstr ""
"चेतावनी: रिमोट ‘%s’ आर्किटेक्चर ‘%s’ के लिए ऐपस्ट्रीम डेटा नहीं मिल सका: %s; %s\n"

#. Appstream2 is only for efficiency, so just print a debug message
#: app/flatpak-builtins-create-usb.c:790
#, c-format
msgid "Couldn't find appstream2 data for remote ‘%s’ arch ‘%s’: %s\n"
msgstr "रिमोट ‘%s’ आर्किटेक्चर ‘%s’ के लिए ऐपस्ट्रीम2 डेटा नहीं मिल सका: %s\n"

#: app/flatpak-builtins-document-export.c:62
msgid "Create a unique document reference"
msgstr "एक अद्वितीय दस्तावेज़ संदर्भ बनाएं"

#: app/flatpak-builtins-document-export.c:63
msgid "Make the document transient for the current session"
msgstr "वर्तमान सत्र के लिए दस्तावेज़ को क्षणिक बनाएं"

#: app/flatpak-builtins-document-export.c:64
msgid "Don't require the file to exist already"
msgstr "फाइल का पहले से मौजूद होना ज़रूरी नहीं है"

#: app/flatpak-builtins-document-export.c:65
msgid "Give the app read permissions"
msgstr "ऐप को पढ़ने की अनुमति दें"

#: app/flatpak-builtins-document-export.c:66
msgid "Give the app write permissions"
msgstr "ऐप को लिखने की अनुमति दें"

#: app/flatpak-builtins-document-export.c:67
msgid "Give the app delete permissions"
msgstr "ऐप को मिटाने की अनुमति दें"

#: app/flatpak-builtins-document-export.c:68
msgid "Give the app permissions to grant further permissions"
msgstr "आगे की अनुमति देने के लिए ऐप को अनुमति दें"

#: app/flatpak-builtins-document-export.c:69
msgid "Revoke read permissions of the app"
msgstr "ऐप की पढ़ने की अनुमति रद्द करें"

#: app/flatpak-builtins-document-export.c:70
msgid "Revoke write permissions of the app"
msgstr "ऐप की लिखने की अनुमति रद्द करें"

#: app/flatpak-builtins-document-export.c:71
msgid "Revoke delete permissions of the app"
msgstr "ऐप की मिटाने की अनुमतियां रद्द करें"

#: app/flatpak-builtins-document-export.c:72
msgid "Revoke the permission to grant further permissions"
msgstr "आगे की अनुमति देने के लिए अनुमति रद्द करें"

#: app/flatpak-builtins-document-export.c:73
msgid "Add permissions for this app"
msgstr "इस ऐप के लिए अनुमतियां जोड़ें"

#: app/flatpak-builtins-document-export.c:73
msgid "APPID"
msgstr "APPID"

#: app/flatpak-builtins-document-export.c:100
msgid "FILE - Export a file to apps"
msgstr "फाइल - ऐप्स पर फाइल निर्यात करें"

#: app/flatpak-builtins-document-export.c:109
#: app/flatpak-builtins-document-info.c:72
#: app/flatpak-builtins-document-unexport.c:67
msgid "FILE must be specified"
msgstr "फाइल निर्दिष्ट होनी चाहिए"

#: app/flatpak-builtins-document-info.c:63
msgid "FILE - Get information about an exported file"
msgstr "फाइल - निर्यात की गई फाइल के बारे में जानकारी प्राप्त करें"

#: app/flatpak-builtins-document-info.c:100
#: app/flatpak-builtins-document-unexport.c:94
#, c-format
msgid "Not exported\n"
msgstr "निर्यात नहीं हुआ\n"

#: app/flatpak-builtins-document-list.c:43 app/flatpak-builtins-history.c:53
#: app/flatpak-builtins-list.c:54 app/flatpak-builtins-ps.c:43
#: app/flatpak-builtins-remote-list.c:45 app/flatpak-builtins-remote-ls.c:59
#: app/flatpak-builtins-search.c:38
msgid "What information to show"
msgstr "क्या जानकारी दिखानी है"

#: app/flatpak-builtins-document-list.c:43 app/flatpak-builtins-history.c:53
#: app/flatpak-builtins-list.c:54 app/flatpak-builtins-ps.c:43
#: app/flatpak-builtins-remote-list.c:45 app/flatpak-builtins-remote-ls.c:59
#: app/flatpak-builtins-search.c:38
msgid "FIELD,…"
msgstr "क्षेत्र,…"

#: app/flatpak-builtins-document-list.c:44 app/flatpak-builtins-history.c:54
#: app/flatpak-builtins-list.c:52 app/flatpak-builtins-permission-list.c:43
#: app/flatpak-builtins-permission-show.c:43 app/flatpak-builtins-ps.c:44
#: app/flatpak-builtins-remote-list.c:46 app/flatpak-builtins-remote-ls.c:63
#: app/flatpak-builtins-repo.c:717 app/flatpak-builtins-search.c:39
#, fuzzy
msgid "Show output in JSON format"
msgstr "अतिरिक्त जानकारी दिखाएं"

#: app/flatpak-builtins-document-list.c:49
msgid "Show the document ID"
msgstr "दस्तावेज़ ID दिखाएं"

#: app/flatpak-builtins-document-list.c:50
msgid "Path"
msgstr "पथ"

#: app/flatpak-builtins-document-list.c:50
#: app/flatpak-builtins-document-list.c:51
msgid "Show the document path"
msgstr "दस्तावेज़ पथ दिखाएं"

#: app/flatpak-builtins-document-list.c:51 app/flatpak-builtins-list.c:66
#: app/flatpak-builtins-remote-ls.c:74
msgid "Origin"
msgstr "मूल"

#: app/flatpak-builtins-document-list.c:52 app/flatpak-builtins-history.c:62
#: app/flatpak-builtins-ps.c:52
msgid "Application"
msgstr "अनुप्रयोग"

#: app/flatpak-builtins-document-list.c:52
msgid "Show applications with permission"
msgstr "अनुमति के साथ अनुप्रयोग दिखाएं"

#: app/flatpak-builtins-document-list.c:53
#: app/flatpak-builtins-permission-list.c:182
#: app/flatpak-builtins-permission-show.c:145
msgid "Permissions"
msgstr "अनुमतियां"

#: app/flatpak-builtins-document-list.c:53
msgid "Show permissions for applications"
msgstr "अनुप्रयोगों के लिए अनुमतियां दिखाएं"

#: app/flatpak-builtins-document-list.c:161
#, fuzzy, c-format
msgid "No documents found\n"
msgstr "कोई मेल नहीं मिले"

#: app/flatpak-builtins-document-list.c:180
msgid "[APPID] - List exported files"
msgstr "[APPID] - निर्यात की गई फाइलों की सूची"

#: app/flatpak-builtins-document-unexport.c:43
msgid "Specify the document ID"
msgstr "दस्तावेज़ ID निर्दिष्ट करें"

#: app/flatpak-builtins-document-unexport.c:58
msgid "FILE - Unexport a file to apps"
msgstr "फाइल - किसी फाइल को ऐप्स पर अनएक्सपोर्ट करें"

#: app/flatpak-builtins-enter.c:88
msgid "INSTANCE COMMAND [ARGUMENT…] - Run a command inside a running sandbox"
msgstr "इंस्टैंस कमांड [तर्क…] - चल रहे सैंडबॉक्स के अंदर एक कमांड चलाएं"

#: app/flatpak-builtins-enter.c:111
msgid "INSTANCE and COMMAND must be specified"
msgstr "इंस्टैंस और कमांड निर्दिष्ट होना चाहिए"

#: app/flatpak-builtins-enter.c:138
#, c-format
msgid "%s is neither a pid nor an application or instance ID"
msgstr "%s न तो कोई PID है और न ही कोई अनुप्रयोग या इंस्टैंस ID है"

#: app/flatpak-builtins-enter.c:144
msgid "entering not supported (need unprivileged user namespaces, or sudo -E)"
msgstr ""
"प्रवेश समर्थित नहीं है (विशेषाधिकार प्राप्त उपयोक्ता नामस्थान या sudo -E की आवश्यकता है)"

#: app/flatpak-builtins-enter.c:145
#, c-format
msgid "No such pid %s"
msgstr "ऐसा कोई pid %s नहीं"

#: app/flatpak-builtins-enter.c:158
msgid "Can't read cwd"
msgstr "cwd नहीं पढ़ सके"

#: app/flatpak-builtins-enter.c:163
msgid "Can't read root"
msgstr "रूट नहीं पढ़ सके"

#: app/flatpak-builtins-enter.c:191
#, c-format
msgid "Invalid %s namespace for pid %d"
msgstr "pid %2$d के लिए अमान्य %1$s नामस्थान"

#: app/flatpak-builtins-enter.c:202
#, c-format
msgid "Invalid %s namespace for self"
msgstr "स्वयं के लिए अमान्य %s नामस्थान"

#: app/flatpak-builtins-enter.c:216
#, c-format
msgid "Can't open %s namespace: %s"
msgstr "%s नामस्थान नहीं खोल सके: %s"

#: app/flatpak-builtins-enter.c:226
msgid "entering not supported (need unprivileged user namespaces)"
msgstr "प्रवेश समर्थित नहीं है (अविशेषाधिकार प्राप्त उपयोक्ता नामस्थान की आवश्यकता है)"

#: app/flatpak-builtins-enter.c:227
#, c-format
msgid "Can't enter %s namespace: %s"
msgstr "%s नामस्थान दर्ज नहीं कर सकते: %s"

#: app/flatpak-builtins-enter.c:234
msgid "Can't chdir"
msgstr "chdir नहीं कर सकते"

#: app/flatpak-builtins-enter.c:237
msgid "Can't chroot"
msgstr "chroot नहीं कर सकते"

#: app/flatpak-builtins-enter.c:240
msgid "Can't switch gid"
msgstr "GID नहीं बदल सकते"

#: app/flatpak-builtins-enter.c:243
msgid "Can't switch uid"
msgstr "UID नहीं बदल सकते"

#: app/flatpak-builtins-history.c:50
msgid "Only show changes after TIME"
msgstr "परिवर्तन केवल समय के बाद दिखाएं"

#: app/flatpak-builtins-history.c:50 app/flatpak-builtins-history.c:51
msgid "TIME"
msgstr "समय"

#: app/flatpak-builtins-history.c:51
msgid "Only show changes before TIME"
msgstr "केवल समय से पहले परिवर्तन दिखाएं"

#: app/flatpak-builtins-history.c:52
msgid "Show newest entries first"
msgstr "नवीनतम प्रविष्टियां पहले दिखाएं"

#: app/flatpak-builtins-history.c:59
msgid "Time"
msgstr "समय"

#: app/flatpak-builtins-history.c:59
msgid "Show when the change happened"
msgstr "दिखाएं कि परिवर्तन कब हुआ"

#: app/flatpak-builtins-history.c:60
msgid "Change"
msgstr "बदलें"

#: app/flatpak-builtins-history.c:60
msgid "Show the kind of change"
msgstr "परिवर्तन किस प्रकार का है यह दिखाइये"

#: app/flatpak-builtins-history.c:61 app/flatpak-builtins-list.c:68
#: app/flatpak-builtins-remote-ls.c:75 app/flatpak-builtins-repo.c:335
msgid "Ref"
msgstr "संदर्भ"

#: app/flatpak-builtins-history.c:61 app/flatpak-builtins-list.c:68
#: app/flatpak-builtins-remote-ls.c:75
msgid "Show the ref"
msgstr "संदर्भ दिखाएं"

#: app/flatpak-builtins-history.c:62
msgid "Show the application/runtime ID"
msgstr "अनुप्रयोग/रनटाइम ID दिखाएं"

#: app/flatpak-builtins-history.c:63 app/flatpak-builtins-list.c:64
#: app/flatpak-builtins-ps.c:53 app/flatpak-builtins-remote-ls.c:73
#: app/flatpak-cli-transaction.c:1435
msgid "Arch"
msgstr "आर्किटेक्चर"

#: app/flatpak-builtins-history.c:63 app/flatpak-builtins-list.c:64
#: app/flatpak-builtins-ps.c:53 app/flatpak-builtins-remote-ls.c:73
msgid "Show the architecture"
msgstr "आर्किटेक्चर दिखाएं"

#: app/flatpak-builtins-history.c:64 app/flatpak-builtins-list.c:63
#: app/flatpak-builtins-ps.c:54 app/flatpak-builtins-remote-ls.c:72
#: app/flatpak-builtins-search.c:48 app/flatpak-cli-transaction.c:1438
msgid "Branch"
msgstr "शाखा"

#: app/flatpak-builtins-history.c:64 app/flatpak-builtins-list.c:63
#: app/flatpak-builtins-remote-ls.c:72
msgid "Show the branch"
msgstr "शाखा दिखाएं"

#: app/flatpak-builtins-history.c:65 app/flatpak-builtins-list.c:67
msgid "Installation"
msgstr "स्थापना"

#: app/flatpak-builtins-history.c:65
msgid "Show the affected installation"
msgstr "प्रभावित स्थापना दिखाएं"

#: app/flatpak-builtins-history.c:66 app/flatpak-cli-transaction.c:1452
msgid "Remote"
msgstr "रिमोट"

#: app/flatpak-builtins-history.c:66
msgid "Show the remote"
msgstr "रिमोट दिखाएं"

#: app/flatpak-builtins-history.c:67 app/flatpak-builtins-ps.c:55
#: app/flatpak-builtins-remote-ls.c:76
msgid "Commit"
msgstr "कमिट"

#: app/flatpak-builtins-history.c:67
msgid "Show the current commit"
msgstr "वर्तमान कमिट दिखाएं"

#: app/flatpak-builtins-history.c:68
msgid "Old Commit"
msgstr "पुराने कमिट"

#: app/flatpak-builtins-history.c:68
msgid "Show the previous commit"
msgstr "पिछले कमिट दिखाएं"

#: app/flatpak-builtins-history.c:69
msgid "Show the remote URL"
msgstr "रिमोट URl दिखाएं"

#: app/flatpak-builtins-history.c:70 app/flatpak-cli-transaction.c:700
msgid "User"
msgstr "उपयोक्ता"

#: app/flatpak-builtins-history.c:70
msgid "Show the user doing the change"
msgstr "उपयोक्ता को परिवर्तन करते हुए दिखाएं"

#: app/flatpak-builtins-history.c:71
msgid "Tool"
msgstr "टूल"

#: app/flatpak-builtins-history.c:71
msgid "Show the tool that was used"
msgstr "वह उपकरण दिखाएं जिसका प्रयोग किया गया था"

#: app/flatpak-builtins-history.c:72 app/flatpak-builtins-list.c:62
#: app/flatpak-builtins-remote-ls.c:71 app/flatpak-builtins-search.c:47
msgid "Version"
msgstr "संस्करण"

#: app/flatpak-builtins-history.c:72
msgid "Show the Flatpak version"
msgstr "फ़्लैटपैक संस्करण दिखाएं"

#: app/flatpak-builtins-history.c:91
#, c-format
msgid "Failed to get journal data (%s): %s"
msgstr "Failed to get journal data (%s): %s"

#: app/flatpak-builtins-history.c:146
#, c-format
msgid "Failed to open journal: %s"
msgstr "जर्नल खोलने में विफल: %s"

#: app/flatpak-builtins-history.c:153
#, c-format
msgid "Failed to add match to journal: %s"
msgstr "जर्नल में मिलान जोड़ने में विफल: %s"

#: app/flatpak-builtins-history.c:471
msgid " - Show history"
msgstr " - इतिहास दिखाएं"

#: app/flatpak-builtins-history.c:490
#, c-format
msgid "Failed to parse the --since option"
msgstr "--since विकल्प का विश्लेषण करने में विफल"

#: app/flatpak-builtins-history.c:501
#, c-format
msgid "Failed to parse the --until option"
msgstr "--until विकल्प का विश्लेषण करने में विफल"

#: app/flatpak-builtins-info.c:56
msgid "Show user installations"
msgstr "उपयोक्ता स्थापनाएं दिखाएं"

#: app/flatpak-builtins-info.c:57
msgid "Show system-wide installations"
msgstr "सिस्टम-व्यापी स्थापनाएं दिखाएं"

#: app/flatpak-builtins-info.c:58
msgid "Show specific system-wide installations"
msgstr "विशिष्ट सिस्टम-व्यापी संस्थापन दिखाएं"

#: app/flatpak-builtins-info.c:59 app/flatpak-builtins-remote-info.c:59
msgid "Show ref"
msgstr "संदर्भ दिखाएं"

#: app/flatpak-builtins-info.c:60 app/flatpak-builtins-remote-info.c:60
msgid "Show commit"
msgstr "कमिट दिखाएं"

#: app/flatpak-builtins-info.c:61
msgid "Show origin"
msgstr "मूल दिखाएं"

#: app/flatpak-builtins-info.c:62
msgid "Show size"
msgstr "आकार दिखाएं"

#: app/flatpak-builtins-info.c:63 app/flatpak-builtins-remote-info.c:62
msgid "Show metadata"
msgstr "मेटाडेटा दिखाएं"

#: app/flatpak-builtins-info.c:64 app/flatpak-builtins-remote-info.c:63
msgid "Show runtime"
msgstr "रनटाइम दिखाएं"

#: app/flatpak-builtins-info.c:65 app/flatpak-builtins-remote-info.c:64
msgid "Show sdk"
msgstr "SDK दिखाएं"

#: app/flatpak-builtins-info.c:66
msgid "Show permissions"
msgstr "अनुमतियां दिखाएं"

#: app/flatpak-builtins-info.c:67
msgid "Query file access"
msgstr "फाइल पहुंच क्वेरी करें"

#: app/flatpak-builtins-info.c:67 app/flatpak-builtins-install.c:82
#: app/flatpak-builtins-install.c:88 app/flatpak-builtins-preinstall.c:68
#: app/flatpak-builtins-run.c:182 app/flatpak-builtins-run.c:184
#: app/flatpak-builtins-update.c:67 app/flatpak-builtins-update.c:71
msgid "PATH"
msgstr "पथ"

#: app/flatpak-builtins-info.c:68
msgid "Show extensions"
msgstr "एक्सटेंशन दिखाएं"

#: app/flatpak-builtins-info.c:69
msgid "Show location"
msgstr "स्थान दिखाएं"

#: app/flatpak-builtins-info.c:116
msgid "NAME [BRANCH] - Get info about an installed app or runtime"
msgstr "नाम [शाखा] - स्थापित ऐप या रनटाइम के बारे में जानकारी प्राप्त करें"

#: app/flatpak-builtins-info.c:123 app/flatpak-builtins-remote-add.c:317
#: app/flatpak-builtins-remote-delete.c:63
msgid "NAME must be specified"
msgstr "नाम निर्दिष्ट होना चाहिए"

#: app/flatpak-builtins-info.c:196
msgid "ref not present in origin"
msgstr "संदर्भ मूल में मौजूद नहीं है"

#: app/flatpak-builtins-info.c:211 app/flatpak-builtins-remote-info.c:217
#, c-format
msgid "Warning: Commit has no flatpak metadata\n"
msgstr "चेतावनी: कमिट के पास कोई फ़्लैटपैक मेटाडेटा नहीं है\n"

#: app/flatpak-builtins-info.c:217 app/flatpak-builtins-info.c:259
#: app/flatpak-builtins-info.c:455 app/flatpak-builtins-info.c:513
#: app/flatpak-builtins-remote-info.c:236
#: app/flatpak-builtins-remote-info.c:271
msgid "ID:"
msgstr "ID:"

#: app/flatpak-builtins-info.c:218 app/flatpak-builtins-info.c:260
#: app/flatpak-builtins-remote-info.c:237
#: app/flatpak-builtins-remote-info.c:272
msgid "Ref:"
msgstr "संदर्भ:"

#: app/flatpak-builtins-info.c:219 app/flatpak-builtins-info.c:261
#: app/flatpak-builtins-remote-info.c:238
#: app/flatpak-builtins-remote-info.c:273
msgid "Arch:"
msgstr "आर्किटेक्चर:"

#: app/flatpak-builtins-info.c:220 app/flatpak-builtins-info.c:262
#: app/flatpak-builtins-remote-info.c:239
#: app/flatpak-builtins-remote-info.c:274
msgid "Branch:"
msgstr "शाखा:"

#: app/flatpak-builtins-info.c:222 app/flatpak-builtins-info.c:264
#: app/flatpak-builtins-remote-info.c:241
#: app/flatpak-builtins-remote-info.c:276
msgid "Version:"
msgstr "संस्करण:"

#: app/flatpak-builtins-info.c:224 app/flatpak-builtins-info.c:266
#: app/flatpak-builtins-remote-info.c:243
#: app/flatpak-builtins-remote-info.c:278
msgid "License:"
msgstr "लाइसेंस:"

#: app/flatpak-builtins-info.c:226 app/flatpak-builtins-info.c:269
#: app/flatpak-builtins-remote-info.c:245
#: app/flatpak-builtins-remote-info.c:280
msgid "Collection:"
msgstr "संग्रह:"

#: app/flatpak-builtins-info.c:227 app/flatpak-builtins-info.c:270
#: app/flatpak-builtins-info.c:458 app/flatpak-builtins-info.c:516
msgid "Installation:"
msgstr "स्थापना:"

#: app/flatpak-builtins-info.c:228 app/flatpak-builtins-info.c:271
#: app/flatpak-builtins-info.c:459 app/flatpak-builtins-info.c:517
#: app/flatpak-builtins-remote-info.c:249
#: app/flatpak-builtins-remote-info.c:284
#, fuzzy
msgid "Installed Size:"
msgstr "स्थापित आकार"

#: app/flatpak-builtins-info.c:231 app/flatpak-builtins-info.c:279
#: app/flatpak-builtins-remote-info.c:252
#: app/flatpak-builtins-remote-info.c:288
msgid "Runtime:"
msgstr "रनटाइम:"

#: app/flatpak-builtins-info.c:232 app/flatpak-builtins-info.c:288
#: app/flatpak-builtins-remote-info.c:253
#: app/flatpak-builtins-remote-info.c:293
msgid "Sdk:"
msgstr "SDK:"

#: app/flatpak-builtins-info.c:235 app/flatpak-builtins-info.c:313
#: app/flatpak-builtins-remote-info.c:256
#: app/flatpak-builtins-remote-info.c:319
msgid "Date:"
msgstr "तारीख:"

#: app/flatpak-builtins-info.c:237 app/flatpak-builtins-info.c:311
#: app/flatpak-builtins-remote-info.c:258
#: app/flatpak-builtins-remote-info.c:317
msgid "Subject:"
msgstr "विषय:"

#: app/flatpak-builtins-info.c:240 app/flatpak-builtins-info.c:295
msgid "Active commit:"
msgstr "सक्रिय कमिट:"

#: app/flatpak-builtins-info.c:241 app/flatpak-builtins-info.c:298
msgid "Latest commit:"
msgstr "नवीनतम कमिट:"

#: app/flatpak-builtins-info.c:244 app/flatpak-builtins-info.c:303
#: app/flatpak-builtins-info.c:457 app/flatpak-builtins-info.c:515
#: app/flatpak-builtins-remote-info.c:259
#: app/flatpak-builtins-remote-info.c:298
msgid "Commit:"
msgstr "कमिट:"

#: app/flatpak-builtins-info.c:246 app/flatpak-builtins-info.c:308
#: app/flatpak-builtins-remote-info.c:261
#: app/flatpak-builtins-remote-info.c:303
msgid "Parent:"
msgstr "प्रधान:"

#: app/flatpak-builtins-info.c:248 app/flatpak-builtins-info.c:321
msgid "Alt-id:"
msgstr "वैकल्पिक-ID:"

#: app/flatpak-builtins-info.c:250 app/flatpak-builtins-info.c:325
#: app/flatpak-builtins-remote-info.c:263
#: app/flatpak-builtins-remote-info.c:308
msgid "End-of-life:"
msgstr "जीवन-समाप्ति:"

#: app/flatpak-builtins-info.c:252 app/flatpak-builtins-info.c:330
#: app/flatpak-builtins-remote-info.c:265
#: app/flatpak-builtins-remote-info.c:313
msgid "End-of-life-rebase:"
msgstr "जीवन-समाप्ति-पुनःआधार:"

#: app/flatpak-builtins-info.c:254 app/flatpak-builtins-info.c:317
msgid "Subdirectories:"
msgstr "उप-निर्देशिकाएं:"

#: app/flatpak-builtins-info.c:255 app/flatpak-builtins-info.c:454
#: app/flatpak-builtins-info.c:512
msgid "Extension:"
msgstr "एक्सटेंशन:"

#: app/flatpak-builtins-info.c:267 app/flatpak-builtins-info.c:456
#: app/flatpak-builtins-info.c:514
msgid "Origin:"
msgstr "मूल:"

#: app/flatpak-builtins-info.c:460 app/flatpak-builtins-info.c:522
msgid "Subpaths:"
msgstr "उपपथ:"

#: app/flatpak-builtins-info.c:478
msgid "unmaintained"
msgstr "अनुरक्षणहीन"

#: app/flatpak-builtins-info.c:480 app/flatpak-builtins-info.c:482
msgid "unknown"
msgstr "अज्ञात"

#: app/flatpak-builtins-install.c:68 app/flatpak-builtins-preinstall.c:57
msgid "Don't pull, only install from local cache"
msgstr "खींचें नहीं, केवल स्थानीय कैशे से स्थापित करें"

#: app/flatpak-builtins-install.c:69 app/flatpak-builtins-preinstall.c:58
#: app/flatpak-builtins-update.c:60
msgid "Don't deploy, only download to local cache"
msgstr "परिनियोजन न करें, केवल स्थानीय कैशे में डाउनलोड करें"

#: app/flatpak-builtins-install.c:70 app/flatpak-builtins-preinstall.c:59
msgid "Don't install related refs"
msgstr "संबंधित संदर्भ स्थापित न करें"

#: app/flatpak-builtins-install.c:71 app/flatpak-builtins-preinstall.c:60
#: app/flatpak-builtins-update.c:62
msgid "Don't verify/install runtime dependencies"
msgstr "रनटाइम निर्भरताओं को सत्यापित/स्थापित न करें"

#: app/flatpak-builtins-install.c:72
msgid "Don't automatically pin explicit installs"
msgstr "स्पष्ट स्थापना को स्वचालित रूप से पिन न करें"

#: app/flatpak-builtins-install.c:73 app/flatpak-builtins-preinstall.c:61
#: app/flatpak-builtins-update.c:63
msgid "Don't use static deltas"
msgstr "स्थैतिक डेल्टा का प्रयोग न करें"

#: app/flatpak-builtins-install.c:76 app/flatpak-builtins-preinstall.c:62
msgid "Additionally install the SDK used to build the given refs"
msgstr "इसके अतिरिक्त दिए गए संदर्भ को बनाने के लिए प्रयोग किए गए SDK को स्थापित करें"

#: app/flatpak-builtins-install.c:77 app/flatpak-builtins-preinstall.c:63
msgid ""
"Additionally install the debug info for the given refs and their dependencies"
msgstr "इसके अतिरिक्त दिए गए संदर्भ और उनकी निर्भरता के लिए डिबग जानकारी स्थापित करें"

#: app/flatpak-builtins-install.c:78
msgid "Assume LOCATION is a .flatpak single-file bundle"
msgstr "मान लें कि स्थान एक .flatpak एकल-फाइल बंडल है"

#: app/flatpak-builtins-install.c:79
msgid "Assume LOCATION is a .flatpakref application description"
msgstr "मान लें कि स्थान एक .flatpakref अनुप्रयोग विवरण है"

#: app/flatpak-builtins-install.c:80
msgid "Assume LOCATION is containers-transports(5) reference to an OCI image"
msgstr ""

#: app/flatpak-builtins-install.c:81
msgid "Check bundle signatures with GPG key from FILE (- for stdin)"
msgstr "फाइल से GPG कुंजी के साथ बंडल हस्ताक्षर जांचें (- stdin के लिए)"

#: app/flatpak-builtins-install.c:82
msgid "Only install this subpath"
msgstr "केवल यह उपपथ स्थापित करें"

#: app/flatpak-builtins-install.c:83 app/flatpak-builtins-preinstall.c:64
#: app/flatpak-builtins-uninstall.c:63 app/flatpak-builtins-update.c:68
msgid "Automatically answer yes for all questions"
msgstr "सभी प्रश्नों के लिए स्वचालित रूप से हाँ में उत्तर दें"

#: app/flatpak-builtins-install.c:84 app/flatpak-builtins-preinstall.c:65
msgid "Uninstall first if already installed"
msgstr "यदि पहले से स्थापित है तो पहले अस्थापित करें"

#: app/flatpak-builtins-install.c:85 app/flatpak-builtins-preinstall.c:66
#: app/flatpak-builtins-uninstall.c:64 app/flatpak-builtins-update.c:69
msgid "Produce minimal output and don't ask questions"
msgstr "न्यूनतम आउटपुट दें और प्रश्न न पूछें"

#: app/flatpak-builtins-install.c:86
msgid "Update install if already installed"
msgstr "यदि पहले से स्थापित है तो स्थापना को अद्यतन करें"

#. Translators: A sideload is when you install from a local USB drive rather than the Internet.
#: app/flatpak-builtins-install.c:88 app/flatpak-builtins-preinstall.c:68
#: app/flatpak-builtins-update.c:71
msgid "Use this local repo for sideloads"
msgstr "साइडलोड के लिए इस स्थानीय रेपो का प्रयोग करें"

#: app/flatpak-builtins-install.c:178
msgid "Bundle filename must be specified"
msgstr "बंडल फाइल नाम निर्दिष्ट होना चाहिए"

#: app/flatpak-builtins-install.c:188
msgid "Remote bundles are not supported"
msgstr "रिमोट बंडल समर्थित नहीं हैं"

#: app/flatpak-builtins-install.c:231
msgid "Filename or uri must be specified"
msgstr "फाइलनाम या URI निर्दिष्ट किया जाना चाहिए"

#: app/flatpak-builtins-install.c:295
#, fuzzy
msgid "Image location must be specified"
msgstr "कम से कम एक संदर्भ निर्दिष्ट होना चाहिए"

#: app/flatpak-builtins-install.c:345
msgid "[LOCATION/REMOTE] [REF…] - Install applications or runtimes"
msgstr "[स्थान/रिमोट] [संदर्भ…] - अनुप्रयोग या रनटाइम स्थापित करें"

#: app/flatpak-builtins-install.c:378
msgid "At least one REF must be specified"
msgstr "कम से कम एक संदर्भ निर्दिष्ट होना चाहिए"

#: app/flatpak-builtins-install.c:392
#, c-format
msgid "Looking for matches…\n"
msgstr "मिलान खोज रहे हैं…\n"

#: app/flatpak-builtins-install.c:513
#, c-format
msgid "No remote refs found for ‘%s’"
msgstr "‘%s’ के लिए कोई रिमोट संदर्भ नहीं मिला"

#: app/flatpak-builtins-install.c:573 app/flatpak-builtins-uninstall.c:405
#: common/flatpak-ref-utils.c:689 common/flatpak-ref-utils.c:1595
#, c-format
msgid "Invalid branch %s: %s"
msgstr "अमान्य शाखा %s: %s"

#: app/flatpak-builtins-install.c:606
#, c-format
msgid "Nothing matches %s in local repository for remote %s"
msgstr "रिमोट %2$s के लिए स्थानीय रिपॉजिटरी में %1$s से कुछ भी मेल नहीं खाता"

#: app/flatpak-builtins-install.c:608
#, c-format
msgid "Nothing matches %s in remote %s"
msgstr "रिमोट %2$s में %1$s से कुछ भी मेल नहीं खाता"

#: app/flatpak-builtins-install.c:629
#, c-format
msgid "Skipping: %s\n"
msgstr "छोड़ा जा रहा है: %s\n"

#: app/flatpak-builtins-kill.c:110
#, c-format
msgid "%s is not running"
msgstr "%s नहीं चल रहा है"

#: app/flatpak-builtins-kill.c:136
msgid "INSTANCE - Stop a running application"
msgstr "इंस्टैंस - किसी चालू अनुप्रयोग को रोकें"

#: app/flatpak-builtins-kill.c:144 app/flatpak-builtins-ps.c:256
msgid "Extra arguments given"
msgstr "अतिरिक्त तर्क दिए गए"

#: app/flatpak-builtins-kill.c:150
msgid "Must specify the app to kill"
msgstr "खत्म हेतु ऐप निर्दिष्ट करना होगा"

#: app/flatpak-builtins-list.c:47
msgid "Show extra information"
msgstr "अतिरिक्त जानकारी दिखाएं"

#: app/flatpak-builtins-list.c:48
msgid "List installed runtimes"
msgstr "स्थापित रनटाइम की सूची बनाएं"

#: app/flatpak-builtins-list.c:49
msgid "List installed applications"
msgstr "स्थापित अनुप्रयोगों की सूची बनाएं"

#: app/flatpak-builtins-list.c:50
msgid "Arch to show"
msgstr "दिखाने के लिए आर्किटेक्चर"

#: app/flatpak-builtins-list.c:51 app/flatpak-builtins-remote-ls.c:57
msgid "List all refs (including locale/debug)"
msgstr "सभी संदर्भों की सूची बनाएं (लोकेल/डीबग सहित)"

#: app/flatpak-builtins-list.c:53 app/flatpak-builtins-remote-ls.c:58
msgid "List all applications using RUNTIME"
msgstr "रनटाइम का प्रयोग करने वाले सभी अनुप्रयोग सूचीबद्ध करें"

#: app/flatpak-builtins-list.c:59 app/flatpak-builtins-remote-list.c:51
#: app/flatpak-builtins-remote-ls.c:68 app/flatpak-builtins-search.c:44
msgid "Name"
msgstr "नाम"

#: app/flatpak-builtins-list.c:59 app/flatpak-builtins-remote-list.c:51
#: app/flatpak-builtins-remote-ls.c:68 app/flatpak-builtins-search.c:44
msgid "Show the name"
msgstr "नाम दिखायें"

#: app/flatpak-builtins-list.c:60 app/flatpak-builtins-remote-list.c:60
#: app/flatpak-builtins-remote-ls.c:69 app/flatpak-builtins-search.c:45
msgid "Description"
msgstr "विवरण"

#: app/flatpak-builtins-list.c:60 app/flatpak-builtins-remote-ls.c:69
#: app/flatpak-builtins-search.c:45
msgid "Show the description"
msgstr "विवरण दिखाएं"

#: app/flatpak-builtins-list.c:61 app/flatpak-builtins-remote-ls.c:70
#: app/flatpak-builtins-search.c:46
msgid "Application ID"
msgstr "अनुप्रयोग ID"

#: app/flatpak-builtins-list.c:61 app/flatpak-builtins-ps.c:52
#: app/flatpak-builtins-remote-ls.c:70 app/flatpak-builtins-search.c:46
msgid "Show the application ID"
msgstr "अनुप्रयोग ID दिखाएं"

#: app/flatpak-builtins-list.c:62 app/flatpak-builtins-remote-ls.c:71
#: app/flatpak-builtins-search.c:47
msgid "Show the version"
msgstr "संस्करण दिखाएं"

#: app/flatpak-builtins-list.c:65 app/flatpak-builtins-ps.c:56
#: app/flatpak-builtins-remote-ls.c:77
msgid "Runtime"
msgstr "रनटाइम"

#: app/flatpak-builtins-list.c:65
msgid "Show the used runtime"
msgstr "प्रयुक्त रनटाइम दिखाएं"

#: app/flatpak-builtins-list.c:66 app/flatpak-builtins-remote-ls.c:74
msgid "Show the origin remote"
msgstr "मूल रिमोट दिखाएं"

#: app/flatpak-builtins-list.c:67
msgid "Show the installation"
msgstr "स्थापना दिखाएं"

#: app/flatpak-builtins-list.c:69
msgid "Active commit"
msgstr "सक्रिय कमिट"

#: app/flatpak-builtins-list.c:69 app/flatpak-builtins-remote-ls.c:76
msgid "Show the active commit"
msgstr "सक्रिय कमिट दिखाएं"

#: app/flatpak-builtins-list.c:70
msgid "Latest commit"
msgstr "नवीनतम कमिट"

#: app/flatpak-builtins-list.c:70
msgid "Show the latest commit"
msgstr "नवीनतम कमिट दिखाएं"

#: app/flatpak-builtins-list.c:71 app/flatpak-builtins-remote-ls.c:78
msgid "Installed size"
msgstr "स्थापित आकार"

#: app/flatpak-builtins-list.c:71 app/flatpak-builtins-remote-ls.c:78
msgid "Show the installed size"
msgstr "स्थापित आकार दिखाएं"

#: app/flatpak-builtins-list.c:72 app/flatpak-builtins-remote-list.c:58
#: app/flatpak-builtins-remote-ls.c:80 app/flatpak-builtins-repo.c:340
msgid "Options"
msgstr "विकल्प"

#: app/flatpak-builtins-list.c:72 app/flatpak-builtins-remote-list.c:58
#: app/flatpak-builtins-remote-ls.c:80
msgid "Show options"
msgstr "विकल्प दिखाएं"

#: app/flatpak-builtins-list.c:180
#, c-format
msgid "Unable to load details of %s: %s"
msgstr "%s का विवरण लोड करने में असमर्थ: %s"

#: app/flatpak-builtins-list.c:190
#, c-format
msgid "Unable to inspect current version of %s: %s"
msgstr "%s के वर्तमान संस्करण का निरीक्षण करने में असमर्थ: %s"

#: app/flatpak-builtins-list.c:408
msgid " - List installed apps and/or runtimes"
msgstr " - स्थापित ऐप्स और/या रनटाइम की सूची बनाएं"

#: app/flatpak-builtins-make-current.c:38
msgid "Arch to make current for"
msgstr "वर्तमान बनाने के लिए आर्किटेक्चर"

#: app/flatpak-builtins-make-current.c:58
msgid "APP BRANCH - Make branch of application current"
msgstr "ऐप शाखा - आवेदन की शाखा को चालू बनाएं"

#: app/flatpak-builtins-make-current.c:69 app/flatpak-builtins-run.c:260
msgid "APP must be specified"
msgstr "ऐप निर्दिष्ट होना चाहिए"

#: app/flatpak-builtins-make-current.c:84
msgid "BRANCH must be specified"
msgstr "शाखा निर्दिष्ट होनी चाहिए"

#: app/flatpak-builtins-make-current.c:97
#, c-format
msgid "App %s branch %s is not installed"
msgstr "ऐप %s शाखा %s स्थापित नहीं है"

#: app/flatpak-builtins-mask.c:42
msgid "Remove matching masks"
msgstr "मैचिंग मास्क हटाएं"

#: app/flatpak-builtins-mask.c:54
msgid ""
"[PATTERN…] - disable updates and automatic installation matching patterns"
msgstr "[प्रतिमान…] - अद्यतन और स्वचालित स्थापना मिलान प्रतिमान अक्षम करें"

#: app/flatpak-builtins-mask.c:73
#, c-format
msgid "No masked patterns\n"
msgstr "कोई मास्क प्रतिमान नहीं\n"

#: app/flatpak-builtins-mask.c:78
#, c-format
msgid "Masked patterns:\n"
msgstr "मास्क प्रतिमान:\n"

#: app/flatpak-builtins-override.c:42
msgid "Remove existing overrides"
msgstr "मौजूदा अध्यारोहण हटाएं"

#: app/flatpak-builtins-override.c:43
msgid "Show existing overrides"
msgstr "मौजूदा अध्यारोहण दिखाएं"

#: app/flatpak-builtins-override.c:59
msgid "[APP] - Override settings [for application]"
msgstr "[ऐप] - अध्यारोहण सेटिंग्स [अनुप्रयोग के लिए]"

#: app/flatpak-builtins-permission-list.c:143
msgid "[TABLE] [ID] - List permissions"
msgstr "[तालिका] [ID] - अनुमतियां सूचीबद्ध करें"

#: app/flatpak-builtins-permission-list.c:179
#: app/flatpak-builtins-permission-show.c:142
msgid "Table"
msgstr "तालिका"

#: app/flatpak-builtins-permission-list.c:180
#: app/flatpak-builtins-permission-show.c:143
msgid "Object"
msgstr "वस्तु"

#: app/flatpak-builtins-permission-list.c:181
#: app/flatpak-builtins-permission-show.c:144
msgid "App"
msgstr "ऐप"

#: app/flatpak-builtins-permission-list.c:183
#: app/flatpak-builtins-permission-show.c:146
msgid "Data"
msgstr "डेटा"

#: app/flatpak-builtins-permission-remove.c:120
msgid "TABLE ID [APP_ID] - Remove item from permission store"
msgstr "टेबल ID [ऐप_ID] - अनुमति स्टोर से वस्तु हटाएं"

#: app/flatpak-builtins-permission-remove.c:129
#: app/flatpak-builtins-permission-set.c:120
msgid "Too few arguments"
msgstr "बहुत कम तर्क"

#: app/flatpak-builtins-permission-reset.c:43
msgid "Reset all permissions"
msgstr "सभी अनुमतियां रीसेट करें"

#: app/flatpak-builtins-permission-reset.c:144
msgid "APP_ID - Reset permissions for an app"
msgstr "ऐप_ID - ऐप के लिए अनुमतियां रीसेट करें"

#: app/flatpak-builtins-permission-reset.c:153
#: app/flatpak-builtins-permission-show.c:124
msgid "Wrong number of arguments"
msgstr "तर्कों की गलत संख्या"

#: app/flatpak-builtins-permission-set.c:42
msgid "Associate DATA with the entry"
msgstr "प्रविष्टि के साथ डेटा संबद्ध करें"

#: app/flatpak-builtins-permission-set.c:42
msgid "DATA"
msgstr "डेटा"

#: app/flatpak-builtins-permission-set.c:111
msgid "TABLE ID APP_ID [PERMISSION...] - Set permissions"
msgstr "तालिका ID ऐप_ID [अनुमति...] - अनुमतियां निर्धारित करें"

#: app/flatpak-builtins-permission-set.c:132
#, c-format
msgid "Failed to parse '%s' as GVariant: "
msgstr "'%s' को GVariant के रूप में विश्लेषण करने में विफल: "

#: app/flatpak-builtins-permission-show.c:115
msgid "APP_ID - Show permissions for an app"
msgstr "ऐप_ID - किसी ऐप के लिए अनुमतियां दिखाएं"

#: app/flatpak-builtins-pin.c:44
msgid "Remove matching pins"
msgstr "मेल खाते पिन हटाएं"

#: app/flatpak-builtins-pin.c:56
msgid "[PATTERN…] - disable automatic removal of runtimes matching patterns"
msgstr "[प्रतिमान…] - रनटाइम मिलान प्रतिमान का स्वचालित निष्कासन अक्षम करें"

#: app/flatpak-builtins-pin.c:75
#, c-format
msgid "No pinned patterns\n"
msgstr "कोई पिन किया गया प्रतिमान नहीं\n"

#: app/flatpak-builtins-pin.c:80
#, c-format
msgid "Pinned patterns:\n"
msgstr "पिन किये गये प्रतिमान:\n"

#: app/flatpak-builtins-preinstall.c:80
msgid "- Install flatpaks that are part of the operating system"
msgstr ""

#: app/flatpak-builtins-preinstall.c:118
#, c-format
msgid "Nothing to do.\n"
msgstr "कुछ करने को नहीं है।\n"

#: app/flatpak-builtins-ps.c:49
msgid "Instance"
msgstr "इंस्टैंस"

#: app/flatpak-builtins-ps.c:49
msgid "Show the instance ID"
msgstr "इंस्टैंस ID दिखाएं"

#: app/flatpak-builtins-ps.c:50 app/flatpak-builtins-run.c:178
msgid "PID"
msgstr "PID"

#: app/flatpak-builtins-ps.c:50
msgid "Show the PID of the wrapper process"
msgstr "रैपर प्रक्रिया की PID दिखाएं"

#: app/flatpak-builtins-ps.c:51
msgid "Child-PID"
msgstr "उप-PID"

#: app/flatpak-builtins-ps.c:51
msgid "Show the PID of the sandbox process"
msgstr "सैंडबॉक्स प्रक्रिया की PID दिखाएं"

#: app/flatpak-builtins-ps.c:54 app/flatpak-builtins-search.c:48
msgid "Show the application branch"
msgstr "अनुप्रयोग शाखा दिखाएं"

#: app/flatpak-builtins-ps.c:55
msgid "Show the application commit"
msgstr "अनुप्रयोग कमिट दिखाएं"

#: app/flatpak-builtins-ps.c:56
msgid "Show the runtime ID"
msgstr "रनटाइम ID दिखाएं"

#: app/flatpak-builtins-ps.c:57
msgid "R.-Branch"
msgstr "R.-Branch"

#: app/flatpak-builtins-ps.c:57
msgid "Show the runtime branch"
msgstr "रनटाइम शाखा दिखाएं"

#: app/flatpak-builtins-ps.c:58
msgid "R.-Commit"
msgstr "R.-Commit"

#: app/flatpak-builtins-ps.c:58
msgid "Show the runtime commit"
msgstr "रनटाइम कमिट दिखाएं"

#: app/flatpak-builtins-ps.c:59
msgid "Active"
msgstr "सक्रिय"

#: app/flatpak-builtins-ps.c:59
msgid "Show whether the app is active"
msgstr "दिखाएं कि क्या ऐप सक्रिय है"

#: app/flatpak-builtins-ps.c:60
msgid "Background"
msgstr "पृष्ठभूमि"

#: app/flatpak-builtins-ps.c:60
msgid "Show whether the app is background"
msgstr "दिखाएं कि क्या ऐप पृष्ठभूमि में है"

#: app/flatpak-builtins-ps.c:246
msgid " - Enumerate running sandboxes"
msgstr " - चल रहे सैंडबॉक्स की गणना करें"

#: app/flatpak-builtins-remote-add.c:66
msgid "Do nothing if the provided remote exists"
msgstr "यदि दिया गया रिमोट मौजूद है तो कुछ न करें"

#: app/flatpak-builtins-remote-add.c:67
msgid "LOCATION specifies a configuration file, not the repo location"
msgstr "स्थान एक विन्यास फाइल निर्दिष्ट करता है, रेपो स्थान नहीं"

#: app/flatpak-builtins-remote-add.c:72 app/flatpak-builtins-remote-modify.c:78
msgid "Disable GPG verification"
msgstr "GPG सत्यापन अक्षम करें"

#: app/flatpak-builtins-remote-add.c:73 app/flatpak-builtins-remote-modify.c:79
msgid "Mark the remote as don't enumerate"
msgstr "रिमोट को गणना न करें के रूप में चिह्नित करें"

#: app/flatpak-builtins-remote-add.c:74 app/flatpak-builtins-remote-modify.c:80
msgid "Mark the remote as don't use for deps"
msgstr "रिमोट को निर्भरता के लिए प्रयोग न करें के रूप में चिह्नित करें"

#: app/flatpak-builtins-remote-add.c:75 app/flatpak-builtins-remote-modify.c:81
msgid "Set priority (default 1, higher is more prioritized)"
msgstr "प्राथमिकता निर्धारित करें (तयशुदा 1, उच्चतर को अधिक प्राथमिकता दी जाती है)"

#: app/flatpak-builtins-remote-add.c:75 app/flatpak-builtins-remote-modify.c:81
msgid "PRIORITY"
msgstr "प्राथमिकता"

#: app/flatpak-builtins-remote-add.c:76
msgid "The named subset to use for this remote"
msgstr "इस रिमोट के लिए प्रयोग करने के लिए नामित उपसमुच्चय"

#: app/flatpak-builtins-remote-add.c:76 app/flatpak-builtins-remote-modify.c:71
msgid "SUBSET"
msgstr "उपसमुच्चय"

#: app/flatpak-builtins-remote-add.c:77 app/flatpak-builtins-remote-modify.c:82
msgid "A nice name to use for this remote"
msgstr "इस रिमोट के लिए प्रयोग करने के लिए एक अच्छा नाम"

#: app/flatpak-builtins-remote-add.c:78 app/flatpak-builtins-remote-modify.c:83
msgid "A one-line comment for this remote"
msgstr "इस रिमोट के लिए एक पंक्ति की टिप्पणी"

#: app/flatpak-builtins-remote-add.c:79 app/flatpak-builtins-remote-modify.c:84
msgid "A full-paragraph description for this remote"
msgstr "इस रिमोट के लिए एक पूर्ण-अनुच्छेद विवरण"

#: app/flatpak-builtins-remote-add.c:80 app/flatpak-builtins-remote-modify.c:85
msgid "URL for a website for this remote"
msgstr "इस रिमोट के लिए एक वेबसाइट का URL"

#: app/flatpak-builtins-remote-add.c:81 app/flatpak-builtins-remote-modify.c:86
msgid "URL for an icon for this remote"
msgstr "इस रिमोट के लिए एक आइकन का URL"

#: app/flatpak-builtins-remote-add.c:82 app/flatpak-builtins-remote-modify.c:87
msgid "Default branch to use for this remote"
msgstr "इस रिमोट के लिए प्रयोग की जाने वाली तयशुदा शाखा"

#: app/flatpak-builtins-remote-add.c:84 app/flatpak-builtins-remote-modify.c:89
msgid "Import GPG key from FILE (- for stdin)"
msgstr "फाइल से GPG कुंजी आयात करें (- stdin हेतु)"

#: app/flatpak-builtins-remote-add.c:85 app/flatpak-builtins-remote-modify.c:90
msgid "Load signatures from URL"
msgstr ""

#: app/flatpak-builtins-remote-add.c:86 app/flatpak-builtins-remote-modify.c:92
msgid "Set path to local filter FILE"
msgstr "स्थानीय फिल्टर फाइल पर पथ निर्धारित करें"

#: app/flatpak-builtins-remote-add.c:87 app/flatpak-builtins-remote-modify.c:93
msgid "Disable the remote"
msgstr "रिमोट अक्षम करें"

#: app/flatpak-builtins-remote-add.c:88 app/flatpak-builtins-remote-modify.c:94
msgid "Name of authenticator"
msgstr "प्रमाणक का नाम"

#: app/flatpak-builtins-remote-add.c:90 app/flatpak-builtins-remote-modify.c:96
msgid "Autoinstall authenticator"
msgstr "प्रमाणक स्वतः स्थापित करें"

#: app/flatpak-builtins-remote-add.c:91 app/flatpak-builtins-remote-modify.c:97
msgid "Don't autoinstall authenticator"
msgstr "प्रमाणक को स्वतः स्थापित न करें"

#: app/flatpak-builtins-remote-add.c:92 app/flatpak-builtins-remote-modify.c:99
msgid "Don't follow the redirect set in the summary file"
msgstr "सारांश फाइल में रीडायरेक्ट निर्धारित का अनुसरण न करें"

#: app/flatpak-builtins-remote-add.c:261 app/flatpak-builtins-remote-add.c:268
#, c-format
msgid "Can't load uri %s: %s\n"
msgstr "URI %s लोड नहीं कर सकता: %s\n"

#: app/flatpak-builtins-remote-add.c:276 common/flatpak-dir.c:4643
#, c-format
msgid "Can't load file %s: %s\n"
msgstr "फाइल %s लोड नहीं कर सकता: %s\n"

#: app/flatpak-builtins-remote-add.c:304
msgid "NAME LOCATION - Add a remote repository"
msgstr "नाम स्थान - एक रिमोट रिपॉजिटरी जोड़ें"

#: app/flatpak-builtins-remote-add.c:331
msgid "GPG verification is required if collections are enabled"
msgstr "यदि संग्रह सक्षम हैं तो GPG सत्यापन आवश्यक है"

#: app/flatpak-builtins-remote-add.c:393
#, c-format
msgid "Remote %s already exists"
msgstr "रिमोट %s पहले से मौजूद है"

#: app/flatpak-builtins-remote-add.c:405
#: app/flatpak-builtins-remote-modify.c:340
#, c-format
msgid "Invalid authenticator name %s"
msgstr "अमान्य प्रमाणक नाम %s"

#: app/flatpak-builtins-remote-add.c:422
#, c-format
msgid "Warning: Could not update extra metadata for '%s': %s\n"
msgstr "चेतावनी: '%s' के लिए अतिरिक्त मेटाडेटा अद्यतन नहीं किया जा सका: %s\n"

#: app/flatpak-builtins-remote-delete.c:39
msgid "Remove remote even if in use"
msgstr "यदि प्रयोग में है तो भी रिमोट हटा दें"

#: app/flatpak-builtins-remote-delete.c:53
msgid "NAME - Delete a remote repository"
msgstr "नाम - एक रिमोट रिपॉजिटरी मिटाएं"

#: app/flatpak-builtins-remote-delete.c:100
#, c-format
msgid "The following refs are installed from remote '%s':"
msgstr "निम्नलिखित संदर्भ रिमोट '%s' से स्थापित किए गए हैं:"

#: app/flatpak-builtins-remote-delete.c:101
msgid "Remove them?"
msgstr "उन्हें हटाएं?"

#: app/flatpak-builtins-remote-delete.c:103
#, c-format
msgid "Can't remove remote '%s' with installed refs"
msgstr "स्थापित संदर्भ के साथ रिमोट '%s' को नहीं हटाया जा सकता"

#: app/flatpak-builtins-remote-info.c:55
msgid "Commit to show info for"
msgstr "कमिट जिसके लिए जानकारी दिखानी है"

#: app/flatpak-builtins-remote-info.c:58
msgid "Display log"
msgstr "लॉग प्रदर्शित करें"

#: app/flatpak-builtins-remote-info.c:61
msgid "Show parent"
msgstr "प्रधान दिखाएं"

#: app/flatpak-builtins-remote-info.c:65 app/flatpak-builtins-remote-ls.c:60
msgid "Use local caches even if they are stale"
msgstr "स्थानीय कैशे का प्रयोग करें, भले ही वे पुराने हों"

#. Translators: A sideload is when you install from a local USB drive rather than the Internet.
#: app/flatpak-builtins-remote-info.c:67 app/flatpak-builtins-remote-ls.c:62
msgid "Only list refs available as sideloads"
msgstr "साइडलोड के रूप में केवल सूची संदर्भ उपलब्ध हैं"

#: app/flatpak-builtins-remote-info.c:114
msgid ""
" REMOTE REF - Show information about an application or runtime in a remote"
msgstr " रिमोट संदर्भ - रिमोट में किसी अनुप्रयोग या रनटाइम के बारे में जानकारी दिखाएं"

#: app/flatpak-builtins-remote-info.c:125
msgid "REMOTE and REF must be specified"
msgstr "रिमोट और संदर्भ निर्दिष्ट होना चाहिए"

#: app/flatpak-builtins-remote-info.c:247
#: app/flatpak-builtins-remote-info.c:282
#, fuzzy
msgid "Download Size:"
msgstr "डाउनलोड आकार"

#: app/flatpak-builtins-remote-info.c:267
#: app/flatpak-builtins-remote-info.c:325
msgid "History:"
msgstr "इतिहास:"

#: app/flatpak-builtins-remote-info.c:348
msgid " Commit:"
msgstr " कमिट:"

#: app/flatpak-builtins-remote-info.c:349
msgid " Subject:"
msgstr " विषय:"

#: app/flatpak-builtins-remote-info.c:350
msgid " Date:"
msgstr " तारीख:"

#: app/flatpak-builtins-remote-info.c:383
#, c-format
msgid "Warning: Commit %s has no flatpak metadata\n"
msgstr "चेतावनी: कमिट %s में कोई फ़्लैटपैक मेटाडेटा नहीं है\n"

#: app/flatpak-builtins-remote-list.c:43
msgid "Show remote details"
msgstr "रिमोट विवरण दिखाएं"

#: app/flatpak-builtins-remote-list.c:44
msgid "Show disabled remotes"
msgstr "अक्षम रिमोट दिखाएं"

#: app/flatpak-builtins-remote-list.c:52
msgid "Title"
msgstr "शीर्षक"

#: app/flatpak-builtins-remote-list.c:52
msgid "Show the title"
msgstr "शीर्षक दिखाएं"

#: app/flatpak-builtins-remote-list.c:53
msgid "Show the URL"
msgstr "URL दिखाएं"

#: app/flatpak-builtins-remote-list.c:54
msgid "Show the collection ID"
msgstr "संग्रह ID दिखाएं"

#: app/flatpak-builtins-remote-list.c:55 app/flatpak-builtins-repo.c:392
msgid "Subset"
msgstr "उपसमुच्चय"

#: app/flatpak-builtins-remote-list.c:55
msgid "Show the subset"
msgstr "उपसमुच्चय दिखाएं"

#: app/flatpak-builtins-remote-list.c:56
msgid "Filter"
msgstr "फिल्टर"

#: app/flatpak-builtins-remote-list.c:56
msgid "Show filter file"
msgstr "फिल्टर फाइल दिखाएं"

#: app/flatpak-builtins-remote-list.c:57
msgid "Priority"
msgstr "प्राथमिकता"

#: app/flatpak-builtins-remote-list.c:57
msgid "Show the priority"
msgstr "प्राथमिकता दिखाएं"

#: app/flatpak-builtins-remote-list.c:59
msgid "Comment"
msgstr "टिप्पणी"

#: app/flatpak-builtins-remote-list.c:59
msgid "Show comment"
msgstr "टिप्पणी दिखाएं"

#: app/flatpak-builtins-remote-list.c:60
msgid "Show description"
msgstr "विवरण दिखाएं"

#: app/flatpak-builtins-remote-list.c:61
msgid "Homepage"
msgstr "मुखपृष्ठ"

#: app/flatpak-builtins-remote-list.c:61
msgid "Show homepage"
msgstr "मुखपृष्ठ दिखाएं"

#: app/flatpak-builtins-remote-list.c:62
msgid "Icon"
msgstr "आइकन"

#: app/flatpak-builtins-remote-list.c:62
msgid "Show icon"
msgstr "आइकन दिखाएं"

#: app/flatpak-builtins-remote-list.c:231
msgid " - List remote repositories"
msgstr " - रिमोट रिपॉजिटरी की सूची बनाएं"

#: app/flatpak-builtins-remote-ls.c:52
msgid "Show arches and branches"
msgstr "आर्किटेक्चर और शाखाएं दिखाएं"

#: app/flatpak-builtins-remote-ls.c:53
msgid "Show only runtimes"
msgstr "केवल रनटाइम दिखाएं"

#: app/flatpak-builtins-remote-ls.c:54
msgid "Show only apps"
msgstr "केवल ऐप्स दिखाएं"

#: app/flatpak-builtins-remote-ls.c:55
msgid "Show only those where updates are available"
msgstr "केवल वही दिखाएं जहां अद्यतन उपलब्ध हैं"

#: app/flatpak-builtins-remote-ls.c:56
msgid "Limit to this arch (* for all)"
msgstr "इस आर्किटेक्चर तक सीमित (* सभी के लिए)"

#: app/flatpak-builtins-remote-ls.c:77
msgid "Show the runtime"
msgstr "रनटाइम दिखाएं"

#: app/flatpak-builtins-remote-ls.c:79
msgid "Download size"
msgstr "डाउनलोड आकार"

#: app/flatpak-builtins-remote-ls.c:79
msgid "Show the download size"
msgstr "डाउनलोड आकार दिखाएं"

#: app/flatpak-builtins-remote-ls.c:391
msgid " [REMOTE or URI] - Show available runtimes and applications"
msgstr " [रिमोट या URI] - उपलब्ध रनटाइम और अनुप्रयोग दिखाएं"

#: app/flatpak-builtins-remote-modify.c:67
msgid "Enable GPG verification"
msgstr "GPG सत्यापन सक्षम करें"

#: app/flatpak-builtins-remote-modify.c:68
msgid "Mark the remote as enumerate"
msgstr "रिमोट को एन्युमरेट के रूप में चिह्नित करें"

#: app/flatpak-builtins-remote-modify.c:69
msgid "Mark the remote as used for dependencies"
msgstr "रिमोट को निर्भरता के लिए प्रयुक्त के रूप में चिह्नित करें"

#: app/flatpak-builtins-remote-modify.c:70
#, fuzzy
msgid "Set a new URL"
msgstr "नया URL निर्धारित करें"

#: app/flatpak-builtins-remote-modify.c:71
msgid "Set a new subset to use"
msgstr "प्रयोग के लिए एक नया उपसमुच्चय निर्धारित करें"

#: app/flatpak-builtins-remote-modify.c:72
msgid "Enable the remote"
msgstr "रिमोट सक्षम करें"

#: app/flatpak-builtins-remote-modify.c:73
msgid "Update extra metadata from the summary file"
msgstr "सारांश फाइल से अतिरिक्त मेटाडेटा अद्यतन करें"

#: app/flatpak-builtins-remote-modify.c:91
msgid "Disable local filter"
msgstr "स्थानीय फिल्टर अक्षम करें"

#: app/flatpak-builtins-remote-modify.c:95
msgid "Authenticator options"
msgstr "प्रमाणक विकल्प"

#: app/flatpak-builtins-remote-modify.c:98
msgid "Follow the redirect set in the summary file"
msgstr "सारांश फाइल में रीडायरेक्ट निर्धारित का पालन करें"

#: app/flatpak-builtins-remote-modify.c:306
msgid "NAME - Modify a remote repository"
msgstr "नाम - रिमोट रिपोजिटरी को संशोधित करें"

#: app/flatpak-builtins-remote-modify.c:316
msgid "Remote NAME must be specified"
msgstr "रिमोट नाम निर्दिष्ट किया जाना चाहिए"

#: app/flatpak-builtins-remote-modify.c:327
#, c-format
msgid "Updating extra metadata from remote summary for %s\n"
msgstr "%s के लिए रिमोट सारांश से अतिरिक्त मेटाडेटा अद्यतन किया जा रहा है\n"

#: app/flatpak-builtins-remote-modify.c:330
#, c-format
msgid "Error updating extra metadata for '%s': %s\n"
msgstr "'%s' के लिए अतिरिक्त मेटाडेटा अद्यतन करने में त्रुटि: %s\n"

#: app/flatpak-builtins-remote-modify.c:331
#, c-format
msgid "Could not update extra metadata for %s"
msgstr "%s के लिए अतिरिक्त मेटाडेटा अद्यतन नहीं किया जा सका"

#: app/flatpak-builtins-repair.c:43
msgid "Don't make any changes"
msgstr "कोई बदलाव न करें"

#: app/flatpak-builtins-repair.c:44
msgid "Reinstall all refs"
msgstr "सभी संदर्भ पुनः स्थापित करें"

#: app/flatpak-builtins-repair.c:68
#, c-format
msgid "Object missing: %s.%s\n"
msgstr "वस्तु अनुपलब्ध: %s.%s\n"

#: app/flatpak-builtins-repair.c:76
#, c-format
msgid "Object invalid: %s.%s\n"
msgstr "वस्तु अमान्य: %s.%s\n"

#: app/flatpak-builtins-repair.c:81
#, c-format
msgid "%s, deleting object\n"
msgstr "%s, वस्तु मिटाई जा रही है\n"

#: app/flatpak-builtins-repair.c:146
#, c-format
msgid "Can't load object %s: %s\n"
msgstr "वस्तु %s लोड नहीं किया जा सका: %s\n"

#: app/flatpak-builtins-repair.c:228
#, c-format
msgid "Commit invalid %s: %s\n"
msgstr "अमान्य कमिट %s: %s\n"

#: app/flatpak-builtins-repair.c:231
#, c-format
msgid "Deleting invalid commit %s: %s\n"
msgstr "अमान्य कमिट %s को हटाया जा रहा है: %s\n"

#: app/flatpak-builtins-repair.c:261
#, c-format
msgid "Commit should be marked partial: %s\n"
msgstr "कमिट को आंशिक चिह्नित किया जाना चाहिए: %s\n"

#: app/flatpak-builtins-repair.c:264
#, c-format
msgid "Marking commit as partial: %s\n"
msgstr "कमिट को आंशिक के रूप में चिह्नित जा रहा है: %s\n"

#: app/flatpak-builtins-repair.c:293
#, c-format
msgid "Problems loading data for %s: %s\n"
msgstr "%s के लिए डेटा लोड करने में समस्याएं: %s\n"

#: app/flatpak-builtins-repair.c:306
#, c-format
msgid "Error reinstalling %s: %s\n"
msgstr "%s को पुनः स्थापित करने में त्रुटि: %s\n"

#: app/flatpak-builtins-repair.c:327
msgid "- Repair a flatpak installation"
msgstr "- फ़्लैटपैक स्थापना की मरम्मत करें"

#: app/flatpak-builtins-repair.c:406
#, c-format
msgid "Removing non-deployed ref %s…\n"
msgstr "गैर-परिनियोजित संदर्भ %s को हटाया जा रहा है…\n"

#: app/flatpak-builtins-repair.c:411
#, c-format
msgid "Skipping non-deployed ref %s…\n"
msgstr "गैर-परिनियोजित संदर्भ %s को छोड़ा जा रहा है…\n"

#: app/flatpak-builtins-repair.c:429
#, c-format
msgid "[%d/%d] Verifying %s…\n"
msgstr "[%d/%d] %s का सत्यापन हो रहा है…\n"

#: app/flatpak-builtins-repair.c:435
#, c-format
msgid "Dry run: "
msgstr "पूर्वाभ्यास: "

#: app/flatpak-builtins-repair.c:440
#, c-format
msgid "Deleting ref %s due to missing objects\n"
msgstr "गुम वस्तुओं के कारण संदर्भ %s को हटाया जा रहा है\n"

#: app/flatpak-builtins-repair.c:444
#, c-format
msgid "Deleting ref %s due to invalid objects\n"
msgstr "अमान्य वस्तुओं के कारण संदर्भ %s को हटाया जा रहा है\n"

#: app/flatpak-builtins-repair.c:448
#, c-format
msgid "Deleting ref %s due to %d\n"
msgstr "%2$d के कारण संदर्भ %1$s को हटाया जा रहा है\n"

#: app/flatpak-builtins-repair.c:464
#, c-format
msgid "Checking remotes...\n"
msgstr "रिमोट की जांच हो रही है...\n"

#: app/flatpak-builtins-repair.c:482
#, c-format
msgid "Remote %s for ref %s is missing\n"
msgstr "संदर्भ %2$s के लिए रिमोट %1$s गायब है\n"

#: app/flatpak-builtins-repair.c:484
#, c-format
msgid "Remote %s for ref %s is disabled\n"
msgstr "संदर्भ %2$s के लिए रिमोट %1$s अक्षम है\n"

#: app/flatpak-builtins-repair.c:490
#, c-format
msgid "Pruning objects\n"
msgstr "वस्तुओं की छँटाई की जा रही है\n"

#: app/flatpak-builtins-repair.c:498
#, c-format
msgid "Erasing .removed\n"
msgstr ".removed मिटाया जा रहा है\n"

#: app/flatpak-builtins-repair.c:524
#, c-format
msgid "Reinstalling refs\n"
msgstr "संदर्भ को पुनः स्थापित किया जा रहा है\n"

#: app/flatpak-builtins-repair.c:526
#, c-format
msgid "Reinstalling removed refs\n"
msgstr "हटाए गए संदर्भ को पुनः स्थापित किया जा रहा है\n"

#: app/flatpak-builtins-repair.c:551
#, c-format
msgid "While removing appstream for %s: "
msgstr "%s के लिए ऐपस्ट्रीम हटाते समय: "

#: app/flatpak-builtins-repair.c:558
#, c-format
msgid "While deploying appstream for %s: "
msgstr "%s के लिए ऐपस्ट्रीम परिनियोजित करते समय: "

#: app/flatpak-builtins-repo.c:106
#, c-format
msgid "Repo mode: %s\n"
msgstr "रेपो मोड: %s\n"

#: app/flatpak-builtins-repo.c:113
#, c-format
msgid "Indexed summaries: %s\n"
msgstr "अनुक्रमित सारांश: %s\n"

#: app/flatpak-builtins-repo.c:113 app/flatpak-builtins-repo.c:139
#: app/flatpak-builtins-repo.c:172
msgid "true"
msgstr "अनुक्रमित सारांश: %s"

#: app/flatpak-builtins-repo.c:113 app/flatpak-builtins-repo.c:139
#: app/flatpak-builtins-repo.c:172
msgid "false"
msgstr "गलत"

#: app/flatpak-builtins-repo.c:121
#, c-format
msgid "Subsummaries: "
msgstr "उपसंक्षेप: "

#: app/flatpak-builtins-repo.c:136
#, c-format
msgid "Cache version: %d\n"
msgstr "कैशे संस्करण: %d\n"

#: app/flatpak-builtins-repo.c:139
#, c-format
msgid "Indexed deltas: %s\n"
msgstr "अनुक्रमित डेल्टा: %s\n"

#: app/flatpak-builtins-repo.c:142
#, c-format
msgid "Title: %s\n"
msgstr "शीर्षक: %s\n"

#: app/flatpak-builtins-repo.c:145
#, c-format
msgid "Comment: %s\n"
msgstr "टिप्पणी: %s\n"

#: app/flatpak-builtins-repo.c:148
#, c-format
msgid "Description: %s\n"
msgstr "विवरण: %s\n"

#: app/flatpak-builtins-repo.c:151
#, c-format
msgid "Homepage: %s\n"
msgstr "मुखपृष्ठ: %s\n"

#: app/flatpak-builtins-repo.c:154
#, c-format
msgid "Icon: %s\n"
msgstr "आइकन: %s\n"

#: app/flatpak-builtins-repo.c:157
#, c-format
msgid "Collection ID: %s\n"
msgstr "संग्रह ID: %s\n"

#: app/flatpak-builtins-repo.c:160
#, c-format
msgid "Default branch: %s\n"
msgstr "तयशुदा शाखा: %s\n"

#: app/flatpak-builtins-repo.c:163
#, c-format
msgid "Redirect URL: %s\n"
msgstr "पुनर्निर्देशन URL: %s\n"

#: app/flatpak-builtins-repo.c:166
#, c-format
msgid "Deploy collection ID: %s\n"
msgstr "परिनियोजन संग्रह ID: %s\n"

#: app/flatpak-builtins-repo.c:169
#, c-format
msgid "Authenticator name: %s\n"
msgstr "प्रमाणक का नाम: %s\n"

#: app/flatpak-builtins-repo.c:172
#, c-format
msgid "Authenticator install: %s\n"
msgstr "प्रमाणक स्थापित करें: %s\n"

#: app/flatpak-builtins-repo.c:180
#, c-format
msgid "GPG key hash: %s\n"
msgstr "GPG कुंजी हैश: %s\n"

#: app/flatpak-builtins-repo.c:184
#, c-format
msgid "%zd summary branches\n"
msgstr "%zd सारांश शाखाएं\n"

#: app/flatpak-builtins-repo.c:336
msgid "Installed"
msgstr "स्थापित"

#. Translators: Download is used here as a noun
#: app/flatpak-builtins-repo.c:338 app/flatpak-cli-transaction.c:1462
msgid "Download"
msgstr "डाउनलोड"

#: app/flatpak-builtins-repo.c:339
msgid "Subsets"
msgstr "उपसमुच्चय"

#: app/flatpak-builtins-repo.c:393
msgid "Digest"
msgstr "डाइजेस्ट"

#: app/flatpak-builtins-repo.c:394
msgid "History length"
msgstr "इतिहास लंबाई"

#: app/flatpak-builtins-repo.c:711
msgid "Print general information about the repository"
msgstr "रिपॉजिटरी के बारे में सामान्य जानकारी प्रिंट करें"

#: app/flatpak-builtins-repo.c:712
msgid "List the branches in the repository"
msgstr "रिपॉजिटरी में शाखाओं की सूची बनाएं"

#: app/flatpak-builtins-repo.c:713
msgid "Print metadata for a branch"
msgstr "किसी शाखा के लिए मेटाडेटा प्रिंट करें"

#: app/flatpak-builtins-repo.c:714
msgid "Show commits for a branch"
msgstr "किसी शाखा के लिए कमिट दिखाएं"

#: app/flatpak-builtins-repo.c:715
msgid "Print information about the repo subsets"
msgstr "रेपो उपसमुच्चय के बारे में जानकारी प्रिंट करें"

#: app/flatpak-builtins-repo.c:716
msgid "Limit information to subsets with this prefix"
msgstr "इस उपसर्ग के साथ जानकारी को उपसमुच्चय तक सीमित करें"

#: app/flatpak-builtins-repo.c:732
msgid "LOCATION - Repository maintenance"
msgstr "स्थान - रिपॉजिटरी रखरखाव"

#: app/flatpak-builtins-run.c:159
msgid "Command to run"
msgstr "चलाने की कमांड"

#: app/flatpak-builtins-run.c:160
msgid "Directory to run the command in"
msgstr "कमांड चलाने के लिए निर्देशिका"

#: app/flatpak-builtins-run.c:161
msgid "Branch to use"
msgstr "प्रयोग हेतु शाखा"

#: app/flatpak-builtins-run.c:162
msgid "Use development runtime"
msgstr "डेवलपमेंट रनटाइम का प्रयोग करें"

#: app/flatpak-builtins-run.c:163
msgid "Runtime to use"
msgstr "प्रयोग करने के लिए रनटाइम"

#: app/flatpak-builtins-run.c:164
msgid "Runtime version to use"
msgstr "प्रयोग करने के लिए रनटाइम संस्करण"

#: app/flatpak-builtins-run.c:167
msgid "Log accessibility bus calls"
msgstr "अभिगम्यता बस कॉल लॉग करें"

#: app/flatpak-builtins-run.c:168
msgid "Don't proxy accessibility bus calls"
msgstr "अभिगम्यता बस कॉल को प्रॉक्सी न करें"

#: app/flatpak-builtins-run.c:169
msgid "Proxy accessibility bus calls (default except when sandboxed)"
msgstr "प्रॉक्सी अभिगम्यता बस कॉल (सैंडबॉक्स किए जाने को छोड़कर तयशुदा)"

#: app/flatpak-builtins-run.c:170
msgid "Don't proxy session bus calls"
msgstr "प्रॉक्सी सत्र बस कॉल न करें"

#: app/flatpak-builtins-run.c:171
msgid "Proxy session bus calls (default except when sandboxed)"
msgstr "प्रॉक्सी सत्र बस कॉल (सैंडबॉक्स किए जाने को छोड़कर तयशुदा)"

#: app/flatpak-builtins-run.c:172
msgid "Don't start portals"
msgstr "पोर्टल प्रारंभ न करें"

#: app/flatpak-builtins-run.c:173
msgid "Enable file forwarding"
msgstr "फाइल अग्रेषण सक्षम करें"

#: app/flatpak-builtins-run.c:174
msgid "Run specified commit"
msgstr "निर्दिष्ट कमिट चलाएं"

#: app/flatpak-builtins-run.c:175
msgid "Use specified runtime commit"
msgstr "निर्दिष्ट रनटाइम कमिट का प्रयोग करें"

#: app/flatpak-builtins-run.c:176
msgid "Run completely sandboxed"
msgstr "पूरी तरह से सैंडबॉक्स करके चलाएं"

#: app/flatpak-builtins-run.c:178
msgid "Use PID as parent pid for sharing namespaces"
msgstr "नेमस्पेस साझा करने के लिए PID को प्रधान PID के रूप में प्रयोग करें"

#: app/flatpak-builtins-run.c:179
msgid "Make processes visible in parent namespace"
msgstr "प्रक्रियाओं को प्रधान नेमस्पेस में दृश्यमान बनाएं"

#: app/flatpak-builtins-run.c:180
msgid "Share process ID namespace with parent"
msgstr "प्रधान के साथ प्रक्रिया ID नेमस्पेस साझा करें"

#: app/flatpak-builtins-run.c:181
msgid "Write the instance ID to the given file descriptor"
msgstr "दिए गए फाइल डिस्क्रिप्टर पर इंस्टेंस ID लिखें"

#: app/flatpak-builtins-run.c:182
msgid "Use PATH instead of the app's /app"
msgstr "ऐप के /app के बजाय पथ का प्रयोग करें"

#: app/flatpak-builtins-run.c:183
#, fuzzy
msgid "Use FD instead of the app's /app"
msgstr "ऐप के /app के बजाय पथ का प्रयोग करें"

#: app/flatpak-builtins-run.c:183 app/flatpak-builtins-run.c:185
#: app/flatpak-builtins-run.c:187 app/flatpak-builtins-run.c:188
#: common/flatpak-context.c:2672
msgid "FD"
msgstr "FD"

#: app/flatpak-builtins-run.c:184
msgid "Use PATH instead of the runtime's /usr"
msgstr "रनटाइम के /usr के बजाय पथ का प्रयोग करें"

#: app/flatpak-builtins-run.c:185
#, fuzzy
msgid "Use FD instead of the runtime's /usr"
msgstr "रनटाइम के /usr के बजाय पथ का प्रयोग करें"

#: app/flatpak-builtins-run.c:186
#, fuzzy
msgid "Clear all outside environment variables"
msgstr "वातावरण चर निर्धारित करें"

#: app/flatpak-builtins-run.c:187
msgid ""
"Bind mount the file or directory referred to by FD to its canonicalized path"
msgstr ""

#: app/flatpak-builtins-run.c:188
msgid ""
"Bind mount the file or directory referred to by FD read-only to its "
"canonicalized path"
msgstr ""

#: app/flatpak-builtins-run.c:219
msgid "APP [ARGUMENT…] - Run an app"
msgstr "ऐप [तर्क…] - एक ऐप चलाएं"

#: app/flatpak-builtins-run.c:370
#, c-format
msgid "runtime/%s/%s/%s not installed"
msgstr "रनटाइम/%s/%s/%s स्थापित नहीं है"

#: app/flatpak-builtins-run.c:419
msgid "app-fd and app-path cannot both be used"
msgstr ""

#: app/flatpak-builtins-run.c:449
msgid "usr-fd and usr-path cannot both be used"
msgstr ""

#: app/flatpak-builtins-search.c:37
msgid "Arch to search for"
msgstr "खोजने के लिए आर्किटेक्चर"

#: app/flatpak-builtins-search.c:49
msgid "Remotes"
msgstr "रिमोट"

#: app/flatpak-builtins-search.c:49
msgid "Show the remotes"
msgstr "रिमोट दिखाएं"

#: app/flatpak-builtins-search.c:244
msgid "TEXT - Search remote apps/runtimes for text"
msgstr "पाठ - पाठ के लिए रिमोट ऐप्स/रनटाइम खोजें"

#: app/flatpak-builtins-search.c:255
msgid "TEXT must be specified"
msgstr "पाठ निर्दिष्ट किया जाना चाहिए"

#: app/flatpak-builtins-search.c:338
msgid "No matches found"
msgstr "कोई मेल नहीं मिले"

#: app/flatpak-builtins-uninstall.c:54
msgid "Arch to uninstall"
msgstr "स्थापना रद्द करने के लिए आर्किटेक्चर"

#: app/flatpak-builtins-uninstall.c:55
msgid "Keep ref in local repository"
msgstr "संदर्भ को स्थानीय रिपॉजिटरी में रखें"

#: app/flatpak-builtins-uninstall.c:56
msgid "Don't uninstall related refs"
msgstr "संबंधित संदर्भ को अस्थापित न करें"

#: app/flatpak-builtins-uninstall.c:57
msgid "Remove files even if running"
msgstr "चल रहे होने पर भी फाइलें हटाएं"

#: app/flatpak-builtins-uninstall.c:60
msgid "Uninstall all"
msgstr "सभी अस्थापित करें"

#: app/flatpak-builtins-uninstall.c:61
msgid "Uninstall unused"
msgstr "अप्रयुक्त अस्थापित करें"

#: app/flatpak-builtins-uninstall.c:62
msgid "Delete app data"
msgstr "ऐप डेटा मिटाएं"

#: app/flatpak-builtins-uninstall.c:141
#, c-format
msgid "Delete data for %s?"
msgstr "%s के लिए डेटा मिटाएं?"

#: app/flatpak-builtins-uninstall.c:220
#, c-format
msgid "Info: applications using the extension %s%s%s branch %s%s%s:\n"
msgstr "जानकारी: एक्सटेंशन %s%s%s शाखा %s%s%s का प्रयोग करने वाले अनुप्रयोग:\n"

#: app/flatpak-builtins-uninstall.c:223
#, c-format
msgid "Info: applications using the runtime %s%s%s branch %s%s%s:\n"
msgstr "जानकारी: रनटाइम %s%s%s शाखा %s%s%s का प्रयोग करने वाले अनुप्रयोग:\n"

#: app/flatpak-builtins-uninstall.c:238
msgid "Really remove?"
msgstr "वास्तव में हटाएं?"

#: app/flatpak-builtins-uninstall.c:255
msgid "[REF…] - Uninstall applications or runtimes"
msgstr "[संदर्भ…] - अनुप्रयोग या रनटाइम अस्थापित करें"

#: app/flatpak-builtins-uninstall.c:264
msgid "Must specify at least one REF, --unused, --all or --delete-data"
msgstr "कम से कम एक संदर्भ, --unused, --all या --delete-data निर्दिष्ट करना होगा"

#: app/flatpak-builtins-uninstall.c:267
msgid "Must not specify REFs when using --all"
msgstr "--all का प्रयोग करते समय संदर्भ निर्दिष्ट नहीं करना चाहिए"

#: app/flatpak-builtins-uninstall.c:270
msgid "Must not specify REFs when using --unused"
msgstr "--unused का प्रयोग करते समय संदर्भ निर्दिष्ट नहीं करना चाहिए"

#: app/flatpak-builtins-uninstall.c:336
#, c-format
msgid ""
"\n"
"These runtimes in installation '%s' are pinned and won't be removed; see "
"flatpak-pin(1):\n"
msgstr ""
"\n"
"स्थापना '%s' में ये रनटाइम पिन किए गए हैं और इन्हें हटाया नहीं जाएगा; flatpak-pin(1) "
"देखें:\n"

#: app/flatpak-builtins-uninstall.c:370
#, c-format
msgid "Nothing unused to uninstall\n"
msgstr "अस्थापित करने के लिए कुछ भी अप्रयुक्त नहीं\n"

#: app/flatpak-builtins-uninstall.c:444
#, c-format
msgid "No installed refs found for ‘%s’"
msgstr "‘%s’ के लिए कोई स्थापित संदर्भ नहीं मिला"

#: app/flatpak-builtins-uninstall.c:447
#, c-format
msgid " with arch ‘%s’"
msgstr " आर्किटेक्चर ‘%s’ के साथ"

#: app/flatpak-builtins-uninstall.c:449
#, c-format
msgid " with branch ‘%s’"
msgstr " शाखा ‘%s’ के साथ"

#: app/flatpak-builtins-uninstall.c:456
#, c-format
msgid "Warning: %s is not installed\n"
msgstr "चेतावनी: %s स्थापित नहीं है\n"

#: app/flatpak-builtins-uninstall.c:490
#, c-format
msgid "None of the specified refs are installed"
msgstr "निर्दिष्ट संदर्भ में से कोई भी स्थापित नहीं है"

#: app/flatpak-builtins-uninstall.c:599
#, c-format
msgid "No app data to delete\n"
msgstr ""

#: app/flatpak-builtins-update.c:56
msgid "Arch to update for"
msgstr "अद्यतन करने के लिए आर्किटेक्चर"

#: app/flatpak-builtins-update.c:57
msgid "Commit to deploy"
msgstr "परिनियोजन करने के लिए कमिट"

#: app/flatpak-builtins-update.c:58
msgid "Remove old files even if running"
msgstr "पुरानी फाइलें चल रही हों तो भी हटाएं"

#: app/flatpak-builtins-update.c:59
msgid "Don't pull, only update from local cache"
msgstr "खींचें नहीं, केवल स्थानीय कैशे से अद्यतन करें"

#: app/flatpak-builtins-update.c:61
msgid "Don't update related refs"
msgstr "संबंधित संदर्भ अद्यतन न करें"

#: app/flatpak-builtins-update.c:66
msgid "Update appstream for remote"
msgstr "रिमोट के लिए ऐपस्ट्रीम अद्यतन करें"

#: app/flatpak-builtins-update.c:67
msgid "Only update this subpath"
msgstr "केवल इस उपपथ को अद्यतन करें"

#: app/flatpak-builtins-update.c:90
msgid "[REF…] - Update applications or runtimes"
msgstr "[संदर्भ…] - अनुप्रयोग या रनटाइम अद्यतन करें"

#: app/flatpak-builtins-update.c:121
msgid "With --commit, only one REF may be specified"
msgstr "--commit के साथ, केवल एक संदर्भ निर्दिष्ट किया जा सकता है"

#: app/flatpak-builtins-update.c:162
#, c-format
msgid "Looking for updates…\n"
msgstr "अद्यतन खोज रहे हैं…\n"

#: app/flatpak-builtins-update.c:215
#, c-format
msgid "Unable to update %s: %s\n"
msgstr "%s को अद्यतन करने में असमर्थ: %s\n"

#: app/flatpak-builtins-update.c:274
#, fuzzy, c-format
msgid "Nothing to update.\n"
msgstr "कुछ करने को नहीं है।\n"

#: app/flatpak-builtins-utils.c:337
#, fuzzy, c-format
msgid ""
"Remote ‘%s’ found in multiple installations, unable to proceed in non-"
"interactive mode"
msgstr "संदर्भ ‘%s’ कई स्थापनाओं में पाया गया: %s। आपको एक निर्दिष्ट करना होगा।"

#: app/flatpak-builtins-utils.c:346
#, c-format
msgid "Remote ‘%s’ found in multiple installations:"
msgstr "रिमोट ‘%s’ एकाधिक स्थापनाओं में पाया गया:"

#: app/flatpak-builtins-utils.c:347 app/flatpak-builtins-utils.c:442
#: app/flatpak-builtins-utils.c:538 app/flatpak-builtins-utils.c:540
#: app/flatpak-builtins-utils.c:598
msgid "Which do you want to use (0 to abort)?"
msgstr "आप किसका प्रयोग करना चाहते हैं (निरस्त करने के लिए 0)?"

#: app/flatpak-builtins-utils.c:349
#, c-format
msgid "No remote chosen to resolve ‘%s’ which exists in multiple installations"
msgstr "एकाधिक स्थापना में मौजूद ‘%s’ को हल करने के लिए कोई रिमोट नहीं चुना गया"

#: app/flatpak-builtins-utils.c:358
#, c-format
msgid ""
"Remote \"%s\" not found\n"
"Hint: Use flatpak remote-add to add a remote"
msgstr ""
"रिमोट \"%s\" नहीं मिला\n"
"संकेत: रिमोट जोड़ने के लिए flatpak remote-add का प्रयोग करें"

#: app/flatpak-builtins-utils.c:364
#, c-format
msgid "Remote \"%s\" not found in the %s installation"
msgstr "%2$s स्थापना में रिमोट \"%1$s\" नहीं मिला"

#: app/flatpak-builtins-utils.c:404
#, c-format
msgid "Multiple refs match ‘%s’, unable to proceed in non-interactive mode"
msgstr ""

#. default to yes on Enter
#: app/flatpak-builtins-utils.c:430
#, c-format
msgid ""
"Found ref ‘%s’ in remote ‘%s’ (%s).\n"
"Use this ref?"
msgstr ""
"रिमोट ‘%2$s’ (%3$s) में संदर्भ ‘%1$s’ मिला।\n"
"इस संदर्भ का प्रयोग करें?"

#: app/flatpak-builtins-utils.c:434 app/flatpak-builtins-utils.c:444
#: app/flatpak-builtins-utils.c:522 app/flatpak-builtins-utils.c:543
#, c-format
msgid "No ref chosen to resolve matches for ‘%s’"
msgstr "‘%s’ के मिलान को हल करने के लिए कोई संदर्भ नहीं चुना गया"

#: app/flatpak-builtins-utils.c:440
#, c-format
msgid "Similar refs found for ‘%s’ in remote ‘%s’ (%s):"
msgstr "रिमोट ‘%2$s’ (%3$s) में ‘%1$s’ के लिए समान संदर्भ पाए गए:"

#: app/flatpak-builtins-utils.c:488
#, c-format
msgid ""
"Multiple installed refs match ‘%s’, unable to proceed in non-interactive mode"
msgstr ""

#. default to yes on Enter
#: app/flatpak-builtins-utils.c:518
#, c-format
msgid "Found installed ref ‘%s’ (%s). Is this correct?"
msgstr "स्थापित संदर्भ ‘%s’ (%s) मिला। क्या यह सही है?"

#: app/flatpak-builtins-utils.c:534
#, c-format
msgid "All of the above"
msgstr "उपरोक्त सभी"

#: app/flatpak-builtins-utils.c:535
#, c-format
msgid "Similar installed refs found for ‘%s’:"
msgstr "‘%s’ के लिए समान स्थापित संदर्भ मिले:"

#: app/flatpak-builtins-utils.c:579
#, c-format
msgid ""
"Multiple remotes have refs matching ‘%s’, unable to proceed in non-"
"interactive mode"
msgstr ""

#: app/flatpak-builtins-utils.c:597
#, c-format
msgid "Remotes found with refs similar to ‘%s’:"
msgstr "‘%s’ के समान संदर्भ वाले रिमोट मिले:"

#: app/flatpak-builtins-utils.c:600
#, c-format
msgid "No remote chosen to resolve matches for ‘%s’"
msgstr "‘%s’ के मिलान को हल करने के लिए कोई रिमोट नहीं चुना गया"

#: app/flatpak-builtins-utils.c:696 app/flatpak-builtins-utils.c:699
#, c-format
msgid "Updating appstream data for user remote %s"
msgstr "उपयोक्ता रिमोट %s के लिए ऐपस्ट्रीम डेटा अद्यतन कर रहा है"

#: app/flatpak-builtins-utils.c:706 app/flatpak-builtins-utils.c:709
#, c-format
msgid "Updating appstream data for remote %s"
msgstr "रिमोट %s के लिए ऐपस्ट्रीम डेटा अद्यतन कर रहा है"

#: app/flatpak-builtins-utils.c:717 app/flatpak-builtins-utils.c:719
msgid "Error updating"
msgstr "अद्यतन करने में त्रुटि"

#: app/flatpak-builtins-utils.c:755
#, c-format
msgid "Remote \"%s\" not found"
msgstr "रिमोट \"%s\" नहीं मिला"

#: app/flatpak-builtins-utils.c:796
#, c-format
msgid "Ambiguous suffix: '%s'."
msgstr "अस्पष्ट प्रत्यय: '%s'।"

#. Translators: don't translate the values
#: app/flatpak-builtins-utils.c:798 app/flatpak-builtins-utils.c:813
msgid "Possible values are :s[tart], :m[iddle], :e[nd] or :f[ull]"
msgstr "संभावित मान हैं :s[tart], :m[iddle], :e[nd] or :f[ull]"

#: app/flatpak-builtins-utils.c:811
#, c-format
msgid "Invalid suffix: '%s'."
msgstr "अमान्य प्रत्यय: '%s'।"

#: app/flatpak-builtins-utils.c:846
#, c-format
msgid "Ambiguous column: %s"
msgstr "अस्पष्ट कॉलम: %s"

#: app/flatpak-builtins-utils.c:859
#, c-format
msgid "Unknown column: %s"
msgstr "अज्ञात कॉलम: %s"

#: app/flatpak-builtins-utils.c:917
msgid "Available columns:\n"
msgstr "उपलब्ध कॉलम:\n"

#: app/flatpak-builtins-utils.c:927
msgid "Show all columns"
msgstr "सभी कॉलम दिखाएं"

#: app/flatpak-builtins-utils.c:928
msgid "Show available columns"
msgstr "उपलब्ध कॉलम दिखाएं"

#: app/flatpak-builtins-utils.c:931
msgid "Append :s[tart], :m[iddle], :e[nd] or :f[ull] to change ellipsization"
msgstr "दीर्घवृत्त आकार बदलने के लिए :s[tart], :m[iddle], :e[nd] या :f[ull] जोड़ें"

#: app/flatpak-builtins-utils.c:1483
#, c-format
msgid "Unknown scheme in sideload location %s"
msgstr ""

#: app/flatpak-cli-transaction.c:96 app/flatpak-cli-transaction.c:102
#, c-format
msgid "Required runtime for %s (%s) found in remote %s\n"
msgstr "%s (%s) के लिए आवश्यक रनटाइम रिमोट %s में मिला\n"

#: app/flatpak-cli-transaction.c:104
msgid "Do you want to install it?"
msgstr "क्या आप इसे स्थापित करना चाहते हैं?"

#: app/flatpak-cli-transaction.c:110
#, c-format
msgid "Required runtime for %s (%s) found in remotes:"
msgstr "रिमोट में %s (%s) के लिए आवश्यक रनटाइम पाया गया:"

#: app/flatpak-cli-transaction.c:112
msgid "Which do you want to install (0 to abort)?"
msgstr "आप किसे स्थापित करना चाहते हैं (निरस्त करने के लिए 0)?"

#: app/flatpak-cli-transaction.c:132
#, c-format
msgid "Configuring %s as new remote '%s'\n"
msgstr "%s को नए रिमोट '%s' के रूप में विन्यस्त किया जा रहा है\n"

#. default to yes on Enter
#: app/flatpak-cli-transaction.c:139
#, c-format
msgid ""
"The remote '%s', referred to by '%s' at location %s contains additional "
"applications.\n"
"Should the remote be kept for future installations?"
msgstr ""
"रिमोट '%1$s', जिसे स्थान %3$s पर '%2$s' द्वारा संदर्भित किया जाता है, में अतिरिक्त "
"अनुप्रयोग शामिल हैं।\n"
"क्या भविष्य में स्थापना के लिए रिमोट रखा जाना चाहिए?"

#. default to yes on Enter
#: app/flatpak-cli-transaction.c:147
#, c-format
msgid ""
"The application %s depends on runtimes from:\n"
"  %s\n"
"Configure this as new remote '%s'"
msgstr ""
"अनुप्रयोग %s निम्न रनटाइम पर निर्भर करता है:\n"
"  %s\n"
"इसे नए रिमोट '%s' के रूप में विन्यस्त करें"

#. Formatted size/remaining time in seconds
#: app/flatpak-cli-transaction.c:321
#, c-format
msgid "%s/s%s%s"
msgstr ""

#. Download progress percentage, use the appropriate
#. percent format for your language
#: app/flatpak-cli-transaction.c:359
#, c-format
msgid "%3d%%"
msgstr ""

#: app/flatpak-cli-transaction.c:414
msgid "Installing…"
msgstr "स्थापित किया जा रहा है…"

#: app/flatpak-cli-transaction.c:416
#, c-format
msgid "Installing %d/%d…"
msgstr "%d/%d स्थापित किया जा रहा है…"

#: app/flatpak-cli-transaction.c:421
msgid "Updating…"
msgstr "अद्यतन किया जा रहा है…"

#: app/flatpak-cli-transaction.c:423
#, c-format
msgid "Updating %d/%d…"
msgstr "%d/%d अद्यतन किया जा रहा है…"

#: app/flatpak-cli-transaction.c:428
msgid "Uninstalling…"
msgstr "अस्थापित किया जा रहा है…"

#: app/flatpak-cli-transaction.c:430
#, c-format
msgid "Uninstalling %d/%d…"
msgstr "%d/%d अस्थापित किया जा रहा है…"

#: app/flatpak-cli-transaction.c:496 app/flatpak-quiet-transaction.c:161
#, c-format
msgid "Info: %s was skipped"
msgstr "जानकारी: %s को छोड़ दिया गया"

#: app/flatpak-cli-transaction.c:519
#, c-format
msgid "Warning: %s%s%s already installed"
msgstr "चेतावनी: %s%s%s पहले से ही स्थापित है"

#: app/flatpak-cli-transaction.c:522
#, c-format
msgid "Error: %s%s%s already installed"
msgstr "त्रुटि: %s%s%s पहले से ही स्थापित है"

#: app/flatpak-cli-transaction.c:528
#, c-format
msgid "Warning: %s%s%s not installed"
msgstr "चेतावनी: %s%s%s स्थापित नहीं है"

#: app/flatpak-cli-transaction.c:531
#, c-format
msgid "Error: %s%s%s not installed"
msgstr "त्रुटि: %s%s%s स्थापित नहीं है"

#: app/flatpak-cli-transaction.c:537
#, c-format
msgid "Warning: %s%s%s needs a later flatpak version"
msgstr "चेतावनी: %s%s%s को बाद के फ़्लैटपैक संस्करण की आवश्यकता है"

#: app/flatpak-cli-transaction.c:540
#, c-format
msgid "Error: %s%s%s needs a later flatpak version"
msgstr "त्रुटि: %s%s%s को बाद के फ़्लैटपैक संस्करण की आवश्यकता है"

#: app/flatpak-cli-transaction.c:546
msgid "Warning: Not enough disk space to complete this operation"
msgstr "चेतावनी: इस ऑपरेशन को पूरा करने के लिए पर्याप्त डिस्क स्थान नहीं है"

#: app/flatpak-cli-transaction.c:548
msgid "Error: Not enough disk space to complete this operation"
msgstr "त्रुटि: इस ऑपरेशन को पूरा करने के लिए पर्याप्त डिस्क स्थान नहीं है"

#: app/flatpak-cli-transaction.c:553
#, c-format
msgid "Warning: %s"
msgstr "चेतावनी: %s"

#: app/flatpak-cli-transaction.c:555
#, c-format
msgid "Error: %s"
msgstr "त्रुटि: %s"

#: app/flatpak-cli-transaction.c:570
#, c-format
msgid "Failed to install %s%s%s: "
msgstr "%s%s%s स्थापित करने में विफल: "

#: app/flatpak-cli-transaction.c:577
#, c-format
msgid "Failed to update %s%s%s: "
msgstr "%s%s%s को अद्यतन करने में विफल: "

#: app/flatpak-cli-transaction.c:584
#, c-format
msgid "Failed to install bundle %s%s%s: "
msgstr "बंडल %s%s%s स्थापित करने में विफल: "

#: app/flatpak-cli-transaction.c:591
#, c-format
msgid "Failed to uninstall %s%s%s: "
msgstr "%s%s%s को अस्थापित करने में विफल: "

#: app/flatpak-cli-transaction.c:642
#, c-format
msgid "Authentication required for remote '%s'\n"
msgstr "रिमोट '%s' के लिए प्रमाणीकरण आवश्यक\n"

#: app/flatpak-cli-transaction.c:643
msgid "Open browser?"
msgstr "ब्राउज़र खोलें?"

#: app/flatpak-cli-transaction.c:699
#, c-format
msgid "Login required remote %s (realm %s)\n"
msgstr "लॉगिन आवश्यक रिमोट %s (रियल्म %s)\n"

#: app/flatpak-cli-transaction.c:704
msgid "Password"
msgstr "पासवर्ड"

#. Only runtimes can be pinned
#: app/flatpak-cli-transaction.c:759
#, c-format
msgid ""
"\n"
"Info: (pinned) runtime %s%s%s branch %s%s%s is end-of-life, in favor of "
"%s%s%s branch %s%s%s\n"
msgstr ""
"\n"
"जानकारी: (पिन किया गया) रनटाइम %s%s%s शाखा %s%s%s का जीवन समाप्त हो गया है, "
"%s%s%s शाखा %s%s%s के पक्ष में\n"

#: app/flatpak-cli-transaction.c:765
#, c-format
msgid ""
"\n"
"Info: runtime %s%s%s branch %s%s%s is end-of-life, in favor of %s%s%s branch "
"%s%s%s\n"
msgstr ""
"\n"
"जानकारी: रनटाइम %s%s%s शाखा %s%s%s का जीवन समाप्त हो गया है, %s%s%s शाखा "
"%s%s%s के पक्ष में\n"

#: app/flatpak-cli-transaction.c:768
#, c-format
msgid ""
"\n"
"Info: app %s%s%s branch %s%s%s is end-of-life, in favor of %s%s%s branch "
"%s%s%s\n"
msgstr ""
"\n"
"जानकारी: ऐप %s%s%s शाखा %s%s%s का जीवन समाप्त हो गया है, %s%s%s शाखा %s%s%s के "
"पक्ष में\n"

#. Only runtimes can be pinned
#: app/flatpak-cli-transaction.c:780
#, c-format
msgid ""
"\n"
"Info: (pinned) runtime %s%s%s branch %s%s%s is end-of-life, with reason:\n"
msgstr ""
"\n"
"जानकारी: (पिन किया गया) रनटाइम %s%s%s शाखा %s%s%s का जीवन समाप्त हो गया है, "
"इसके कारण:\n"

#: app/flatpak-cli-transaction.c:786
#, c-format
msgid ""
"\n"
"Info: runtime %s%s%s branch %s%s%s is end-of-life, with reason:\n"
msgstr ""
"\n"
"जानकारी: रनटाइम %s%s%s शाखा %s%s%s का जीवन समाप्त हो गया है, इसके कारण:\n"

#: app/flatpak-cli-transaction.c:789
#, c-format
msgid ""
"\n"
"Info: app %s%s%s branch %s%s%s is end-of-life, with reason:\n"
msgstr ""
"\n"
"जानकारी: ऐप %s%s%s शाखा %s%s%s का जीवन समाप्त हो गया है, इसके कारण:\n"

#: app/flatpak-cli-transaction.c:963
#, c-format
msgid "Info: applications using this extension:\n"
msgstr "जानकारी: इस एक्सटेंशन का प्रयोग करने वाले अनुप्रयोग:\n"

#: app/flatpak-cli-transaction.c:965
#, c-format
msgid "Info: applications using this runtime:\n"
msgstr "सूचना: इस रनटाइम का प्रयोग करने वाले अनुप्रयोग:\n"

#: app/flatpak-cli-transaction.c:984
msgid "Replace?"
msgstr "प्रतिस्थापित करें?"

#: app/flatpak-cli-transaction.c:987 app/flatpak-quiet-transaction.c:247
#, c-format
msgid "Updating to rebased version\n"
msgstr "पुनः आधारित संस्करण में अद्यतन किया जा रहा है\n"

#: app/flatpak-cli-transaction.c:1011
#, c-format
msgid "Failed to rebase %s to %s: "
msgstr "%1$s को %2$s पर पुनः आधार बनाने में विफल: "

#: app/flatpak-cli-transaction.c:1277
#, c-format
msgid "New %s%s%s permissions:"
msgstr "नई %s%s%s अनुमतियां:"

#: app/flatpak-cli-transaction.c:1279
#, c-format
msgid "%s%s%s permissions:"
msgstr "%s%s%s अनुमतियां:"

#: app/flatpak-cli-transaction.c:1343
msgid "Warning: "
msgstr "चेतावनी: "

#. translators: This is short for operation, the title of a one-char column
#: app/flatpak-cli-transaction.c:1442
msgid "Op"
msgstr "अभि."

#. Avoid resizing the download column too much,
#. * by making the title as long as typical content
#.
#: app/flatpak-cli-transaction.c:1458 app/flatpak-cli-transaction.c:1503
msgid "partial"
msgstr "आंशिक"

#: app/flatpak-cli-transaction.c:1535
msgid "Proceed with these changes to the user installation?"
msgstr "उपयोक्ता स्थापना में इन परिवर्तनों के साथ आगे बढ़ें?"

#: app/flatpak-cli-transaction.c:1537
msgid "Proceed with these changes to the system installation?"
msgstr "सिस्टम स्थापना में इन परिवर्तनों के साथ आगे बढ़ें?"

#: app/flatpak-cli-transaction.c:1539
#, c-format
msgid "Proceed with these changes to the %s?"
msgstr "%s में इन परिवर्तनों के साथ आगे बढ़ें?"

#: app/flatpak-cli-transaction.c:1711
msgid "Changes complete."
msgstr "परिवर्तन पूर्ण।"

#: app/flatpak-cli-transaction.c:1713
msgid "Uninstall complete."
msgstr "अस्थापना पूर्ण।"

#: app/flatpak-cli-transaction.c:1715
msgid "Installation complete."
msgstr "स्थापना पूर्ण।"

#: app/flatpak-cli-transaction.c:1717
msgid "Updates complete."
msgstr "अद्यतन पूर्ण।"

#. For updates/!stop_on_first_error we already printed all errors so we make up
#. a different one.
#: app/flatpak-cli-transaction.c:1750
msgid "There were one or more errors"
msgstr "एक या अधिक त्रुटियां थीं"

#. translators: please keep the leading space
#: app/flatpak-main.c:76
msgid " Manage installed applications and runtimes"
msgstr " स्थापित अनुप्रयोग और रनटाइम को प्रबंधित करें"

#: app/flatpak-main.c:77
msgid "Install an application or runtime"
msgstr "कोई अनुप्रयोग या रनटाइम स्थापित करें"

#: app/flatpak-main.c:78
msgid "Update an installed application or runtime"
msgstr "स्थापित अनुप्रयोग या रनटाइम को अद्यतित करें"

#: app/flatpak-main.c:81
msgid "Uninstall an installed application or runtime"
msgstr "स्थापित अनुप्रयोग या रनटाइम को अस्थापित करें"

#: app/flatpak-main.c:84
msgid "Mask out updates and automatic installation"
msgstr "अद्यतनों और स्वचालित स्थापना को छिपाएं"

#: app/flatpak-main.c:85
msgid "Pin a runtime to prevent automatic removal"
msgstr "स्वत: निष्कासन को रोकने के लिए रनटाइम पिन करें"

#: app/flatpak-main.c:86
msgid "List installed apps and/or runtimes"
msgstr "स्थापित ऐप्स और/या रनटाइम की सूची बनाएं"

#: app/flatpak-main.c:87
msgid "Show info for installed app or runtime"
msgstr "स्थापित ऐप या रनटाइम की जानकारी दिखाएं"

#: app/flatpak-main.c:88
msgid "Show history"
msgstr "इतिहास दिखाएं"

#: app/flatpak-main.c:89
msgid "Configure flatpak"
msgstr "फ़्लैटपैक विन्यस्त करें"

#: app/flatpak-main.c:90
msgid "Repair flatpak installation"
msgstr "फ़्लैटपैक स्थापना की मरम्मत करें"

#: app/flatpak-main.c:91
msgid "Put applications or runtimes onto removable media"
msgstr "अनुप्रयोग या रनटाइम को हटाने योग्य मीडिया पर रखें"

#: app/flatpak-main.c:92
msgid "Install flatpaks that are part of the operating system"
msgstr ""

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:95
msgid ""
"\n"
" Find applications and runtimes"
msgstr ""
"\n"
" अनुप्रयोग और रनटाइम खोजें"

#: app/flatpak-main.c:96
msgid "Search for remote apps/runtimes"
msgstr "रिमोट ऐप्स/रनटाइम खोजें"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:99
msgid ""
"\n"
" Manage running applications"
msgstr ""
"\n"
" चल रहे अनुप्रयोग प्रबंधित करें"

#: app/flatpak-main.c:100
msgid "Run an application"
msgstr "एक अनुप्रयोग चलाएं"

#: app/flatpak-main.c:101
msgid "Override permissions for an application"
msgstr "किसी अनुप्रयोग के लिए अनुमतियां अध्यारोहण करें"

#: app/flatpak-main.c:102
msgid "Specify default version to run"
msgstr "चलाने हेतु तयशुदा संस्करण निर्दिष्ट करें"

#: app/flatpak-main.c:103
msgid "Enter the namespace of a running application"
msgstr "चल रहे अनुप्रयोग का नामस्थान दर्ज करें"

#: app/flatpak-main.c:104
msgid "Enumerate running applications"
msgstr "चल रहे अनुप्रयोगों की गणना करें"

#: app/flatpak-main.c:105
msgid "Stop a running application"
msgstr "चल रहे अनुप्रयोग को रोकें"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:108
msgid ""
"\n"
" Manage file access"
msgstr ""
"\n"
" फाइल पहुंच प्रबंधित करें"

#: app/flatpak-main.c:109
msgid "List exported files"
msgstr "निर्यातित फाइलों की सूची बनाएं"

#: app/flatpak-main.c:110
msgid "Grant an application access to a specific file"
msgstr "किसी अनुप्रयोग को किसी विशिष्ट फाइल तक पहुंच प्रदान करें"

#: app/flatpak-main.c:111
msgid "Revoke access to a specific file"
msgstr "किसी विशिष्ट फाइल तक पहुंच रद्द करें"

#: app/flatpak-main.c:112
msgid "Show information about a specific file"
msgstr "किसी विशिष्ट फाइल के बारे में जानकारी दिखाएं"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:116
msgid ""
"\n"
" Manage dynamic permissions"
msgstr ""
"\n"
" गतिशील अनुमतियां प्रबंधित करें"

#: app/flatpak-main.c:117
msgid "List permissions"
msgstr "अनुमतियां सूचीबद्ध करें"

#: app/flatpak-main.c:118
msgid "Remove item from permission store"
msgstr "अनुमति स्टोर से वस्तु हटाएं"

#: app/flatpak-main.c:120
msgid "Set permissions"
msgstr "अनुमतियां निर्धारित करें"

#: app/flatpak-main.c:121
msgid "Show app permissions"
msgstr "ऐप अनुमतियां दिखाएं"

#: app/flatpak-main.c:122
msgid "Reset app permissions"
msgstr "ऐप अनुमतियां रीसेट करें"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:125
msgid ""
"\n"
" Manage remote repositories"
msgstr ""
"\n"
" रिमोट रिपॉजिटरी प्रबंधित करें"

#: app/flatpak-main.c:126
msgid "List all configured remotes"
msgstr "सभी विन्यस्त रिमोट की सूची बनाएं"

#: app/flatpak-main.c:127
msgid "Add a new remote repository (by URL)"
msgstr "एक नया रिमोट रिपॉजिटरी जोड़ें (URL द्वारा)"

#: app/flatpak-main.c:128
msgid "Modify properties of a configured remote"
msgstr "विन्यस्त रिमोट के गुणों को संशोधित करें"

#: app/flatpak-main.c:129
msgid "Delete a configured remote"
msgstr "विन्यस्त किया गया रिमोट हटाएं"

#: app/flatpak-main.c:131
msgid "List contents of a configured remote"
msgstr "कॉन्फिगर रिमोट की अंतर्वस्तु की सूची बनाएं"

#: app/flatpak-main.c:132
msgid "Show information about a remote app or runtime"
msgstr "रिमोट ऐप या रनटाइम के बारे में जानकारी दिखाएं"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:135
msgid ""
"\n"
" Build applications"
msgstr ""
"\n"
" अनुप्रयोग बनाएं"

#: app/flatpak-main.c:136
msgid "Initialize a directory for building"
msgstr "निर्माण के लिए एक निर्देशिका प्रारंभ करें"

#: app/flatpak-main.c:137
msgid "Run a build command inside the build dir"
msgstr "निर्माण निर्देशिका के अंदर एक निर्माण कमांड चलाएं"

#: app/flatpak-main.c:138
msgid "Finish a build dir for export"
msgstr "निर्यात के लिए निर्माण निर्देशिका समाप्त करें"

#: app/flatpak-main.c:139
msgid "Export a build dir to a repository"
msgstr "निर्माण निर्देशिका को रिपोजिटरी में निर्यात करें"

#: app/flatpak-main.c:140
msgid "Create a bundle file from a ref in a local repository"
msgstr "स्थानीय रिपॉजिटरी में संदर्भ से एक बंडल फाइल बनाएं"

#: app/flatpak-main.c:141
msgid "Import a bundle file"
msgstr "बंडल फाइल आयात करें"

#: app/flatpak-main.c:142
msgid "Sign an application or runtime"
msgstr "अनुप्रयोग या रनटाइम पर हस्ताक्षर करें"

#: app/flatpak-main.c:143
msgid "Update the summary file in a repository"
msgstr "सारांश फाइल को रिपॉजिटरी में अद्यतन करें"

#: app/flatpak-main.c:144
msgid "Create new commit based on existing ref"
msgstr "मौजूदा संदर्भ के आधार पर नई कमिट बनाएं"

#: app/flatpak-main.c:145
msgid "Show information about a repo"
msgstr "रेपो के बारे में जानकारी दिखाएं"

#: app/flatpak-main.c:162
msgid "Show debug information, -vv for more detail"
msgstr "अधिक विवरण के लिए डिबग जानकारी, -vv दिखाएं"

#: app/flatpak-main.c:163
msgid "Show OSTree debug information"
msgstr "OSTree डीबग जानकारी दिखाएं"

#: app/flatpak-main.c:169
msgid "Print version information and exit"
msgstr "संस्करण जानकारी प्रिंट करें और बाहर निकलें"

#: app/flatpak-main.c:170
msgid "Print default arch and exit"
msgstr "तयशुदा आर्किटेक्चर प्रिंट करें और बाहर निकलें"

#: app/flatpak-main.c:171
msgid "Print supported arches and exit"
msgstr "समर्थित आर्किटेक्चर प्रिंट करें और बाहर निकलें"

#: app/flatpak-main.c:172
msgid "Print active gl drivers and exit"
msgstr "सक्रिय gl ड्राइवर प्रिंट करें और बाहर निकलें"

#: app/flatpak-main.c:173
msgid "Print paths for system installations and exit"
msgstr "सिस्टम स्थापना के लिए पथ प्रिंट करें और बाहर निकलें"

#: app/flatpak-main.c:174
msgid "Print the updated environment needed to run flatpaks"
msgstr "Flatpak चलाने के लिए आवश्यक अद्यतन वातावरण प्रिंट करें"

#: app/flatpak-main.c:175
msgid "Only include the system installation with --print-updated-env"
msgstr "सिस्टम स्थापना को केवल --print-updated-env के साथ शामिल करें"

#: app/flatpak-main.c:180
msgid "Work on the user installation"
msgstr "उपयोक्ता स्थापना पर कार्य करें"

#: app/flatpak-main.c:181
msgid "Work on the system-wide installation (default)"
msgstr "सिस्टम-व्यापी स्थापना पर कार्य करें (तयशुदा)"

#: app/flatpak-main.c:182
msgid "Work on a non-default system-wide installation"
msgstr "गैर-तयशुदा सिस्टम-व्यापी स्थापना पर कार्य करें"

#: app/flatpak-main.c:212
msgid "Builtin Commands:"
msgstr "अंतर्निहित कमांड:"

#: app/flatpak-main.c:298
#, c-format
msgid ""
"Note that the directories %s are not in the search path set by the "
"XDG_DATA_DIRS environment variable, so applications installed by Flatpak may "
"not appear on your desktop until the session is restarted."
msgstr ""
"ध्यान दें कि निर्देशिका %s XDG_DATA_DIRS वातावरण चर द्वारा निर्धारित खोज पथ में नहीं "
"हैं, इसलिए Flatpak द्वारा स्थापित किए गए अनुप्रयोग सत्र पुनरारंभ होने तक आपके डेस्कटॉप पर "
"दिखाई नहीं दे सकते हैं।"

#: app/flatpak-main.c:312
#, c-format
msgid ""
"Note that the directory %s is not in the search path set by the "
"XDG_DATA_DIRS environment variable, so applications installed by Flatpak may "
"not appear on your desktop until the session is restarted."
msgstr ""
"ध्यान दें कि निर्देशिका %s XDG_DATA_DIRS वातावरण चर द्वारा निर्धारित खोज पथ में नहीं "
"है, इसलिए Flatpak द्वारा स्थापित किए गए अनुप्रयोग सत्र पुनरारंभ होने तक आपके डेस्कटॉप पर "
"दिखाई नहीं दे सकते हैं।"

#: app/flatpak-main.c:381
msgid ""
"Refusing to operate under sudo with --user. Omit sudo to operate on the user "
"installation, or use a root shell to operate on the root user's installation."
msgstr ""
"--user के साथ sudo के अंतर्गत कार्य करने से इंकार करना। उपयोक्ता स्थापना पर काम करने के "
"लिए sudo को छोड़ दें, या रूट उपयोक्ता के स्थापना पर काम करने के लिए रूट शेल का प्रयोग करें।"

#: app/flatpak-main.c:453
msgid ""
"Multiple installations specified for a command that works on one installation"
msgstr "एक कमांड के लिए एकाधिक स्थापना निर्दिष्ट हैं जो एक स्थापना पर काम करता है"

#: app/flatpak-main.c:504 app/flatpak-main.c:697
#, c-format
msgid "See '%s --help'"
msgstr "'%s --help' देखें"

#: app/flatpak-main.c:706
#, c-format
msgid "'%s' is not a flatpak command. Did you mean '%s%s'?"
msgstr "'%s' एक flatpak कमांड नहीं है। क्या आपका मतलब '%s%s' था?"

#: app/flatpak-main.c:709
#, c-format
msgid "'%s' is not a flatpak command"
msgstr "'%s' flatpak कमांड नहीं है"

#: app/flatpak-main.c:824
msgid "No command specified"
msgstr "कोई कमांड निर्दिष्ट नहीं"

#: app/flatpak-main.c:980
msgid "error:"
msgstr "त्रुटि:"

#: app/flatpak-quiet-transaction.c:77
#, c-format
msgid "Installing %s\n"
msgstr "%s स्थापित किया जा रहा है\n"

#: app/flatpak-quiet-transaction.c:81
#, c-format
msgid "Updating %s\n"
msgstr "%s को अद्यतित किया जा रहा है\n"

#: app/flatpak-quiet-transaction.c:85
#, c-format
msgid "Uninstalling %s\n"
msgstr "%s को अस्थापित किया जा रहा है\n"

#: app/flatpak-quiet-transaction.c:107
#, c-format
msgid "Warning: Failed to install %s: %s\n"
msgstr "चेतावनी: %s स्थापित करने में विफल: %s\n"

#: app/flatpak-quiet-transaction.c:110
#, c-format
msgid "Error: Failed to install %s: %s\n"
msgstr "त्रुटि: %s स्थापित करने में विफल: %s\n"

#: app/flatpak-quiet-transaction.c:116
#, c-format
msgid "Warning: Failed to update %s: %s\n"
msgstr "चेतावनी: %s को अद्यतन करने में विफल: %s\n"

#: app/flatpak-quiet-transaction.c:119
#, c-format
msgid "Error: Failed to update %s: %s\n"
msgstr "त्रुटि: %s को अद्यतन करने में विफल: %s\n"

#: app/flatpak-quiet-transaction.c:125
#, c-format
msgid "Warning: Failed to install bundle %s: %s\n"
msgstr "चेतावनी: बंडल %s स्थापित करने में विफल: %s\n"

#: app/flatpak-quiet-transaction.c:128
#, c-format
msgid "Error: Failed to install bundle %s: %s\n"
msgstr "त्रुटि: बंडल %s स्थापित करने में विफल: %s\n"

#: app/flatpak-quiet-transaction.c:134
#, c-format
msgid "Warning: Failed to uninstall %s: %s\n"
msgstr "चेतावनी: %s को अस्थापित करने में विफल: %s\n"

#: app/flatpak-quiet-transaction.c:137
#, c-format
msgid "Error: Failed to uninstall %s: %s\n"
msgstr "त्रुटि: %s को अस्थापित करने में विफल: %s\n"

#: app/flatpak-quiet-transaction.c:166 common/flatpak-dir.c:11475
#, c-format
msgid "%s already installed"
msgstr "%s पहले से ही स्थापित है"

#: app/flatpak-quiet-transaction.c:168 common/flatpak-dir.c:3622
#: common/flatpak-dir.c:4321 common/flatpak-dir.c:16968
#: common/flatpak-dir.c:17258 common/flatpak-dir-utils.c:166
#: common/flatpak-dir-utils.c:259 common/flatpak-transaction.c:2736
#: common/flatpak-transaction.c:2791
#, c-format
msgid "%s not installed"
msgstr "%s स्थापित नहीं है"

#: app/flatpak-quiet-transaction.c:170
#, c-format
msgid "%s needs a later flatpak version"
msgstr "%s को बाद के flatpak संस्करण की आवश्यकता है"

#: app/flatpak-quiet-transaction.c:172
msgid "Not enough disk space to complete this operation"
msgstr "इस अभियान को पूरा करने के लिए पर्याप्त डिस्क स्थान नहीं है"

#: app/flatpak-quiet-transaction.c:239
#, c-format
msgid "Info: %s is end-of-life, in favor of %s\n"
msgstr "जानकारी: %s जीवन समाप्ति पर है, %s के पक्ष में\n"

#: app/flatpak-quiet-transaction.c:241
#, c-format
msgid "Info: %s is end-of-life, with reason: %s\n"
msgstr "जानकारी: %s जीवन समाप्ति पर है, इसका कारण: %s\n"

#: app/flatpak-quiet-transaction.c:251
#, c-format
msgid "Failed to rebase %s to %s: %s\n"
msgstr "%1$s को %2$s पर पुनः आधार बनाने में विफल: %3$s\n"

#: common/flatpak-auth.c:58
#, c-format
msgid "No authenticator configured for remote `%s`"
msgstr "रिमोट `%s` के लिए कोई प्रमाणक विन्यस्त नहीं किया गया"

#: common/flatpak-context.c:637 common/flatpak-context.c:649
#, fuzzy, c-format
msgid "Invalid permission syntax: %s"
msgstr "अमान्य एक्सटेंशन नाम %s"

#: common/flatpak-context.c:1207
#, c-format
msgid "Unknown share type %s, valid types are: %s"
msgstr "अज्ञात साझा प्रकार %s, मान्य प्रकार हैं: %s"

#: common/flatpak-context.c:1228
#, c-format
msgid "Unknown policy type %s, valid types are: %s"
msgstr "अज्ञात नीति प्रकार %s, मान्य प्रकार हैं: %s"

#: common/flatpak-context.c:1266
#, c-format
msgid "Invalid dbus name %s"
msgstr "अमान्य डी-बस नाम %s"

#: common/flatpak-context.c:1279
#, c-format
msgid "Unknown socket type %s, valid types are: %s"
msgstr "अज्ञात सॉकेट प्रकार %s, मान्य प्रकार हैं: %s"

#: common/flatpak-context.c:1294
#, c-format
msgid "Unknown device type %s, valid types are: %s"
msgstr "अज्ञात डिवाइस प्रकार %s, मान्य प्रकार हैं: %s"

#: common/flatpak-context.c:1308
#, c-format
msgid "Unknown feature type %s, valid types are: %s"
msgstr "अज्ञात विशेषता प्रकार %s, मान्य प्रकार हैं: %s"

#: common/flatpak-context.c:1840
#, c-format
msgid "Filesystem location \"%s\" contains \"..\""
msgstr "फाइलप्रणाली स्थान \"%s\" में \"..\" शामिल है"

#: common/flatpak-context.c:1882
#, c-format
msgid ""
"--filesystem=/ is not available, use --filesystem=host for a similar result"
msgstr ""
"--filesystem=/ उपलब्ध नहीं है, समान परिणाम के लिए --filesystem=host का प्रयोग करें"

#: common/flatpak-context.c:1916
#, fuzzy, c-format
msgid ""
"Unknown filesystem location %s, valid locations are: host, host-os, host-"
"etc, host-root, home, xdg-*[/…], ~/dir, /dir"
msgstr ""
"अज्ञात फाइलप्रणाली स्थान %s, मान्य स्थान हैं: host, host-os, host-etc, home, xdg-"
"*[/…], ~/dir, /dir"

#: common/flatpak-context.c:2015
#, fuzzy, c-format
msgid "Invalid syntax for %s: %s"
msgstr "अमान्य नाम %s: %s"

#: common/flatpak-context.c:2142
#, c-format
msgid "fallback-x11 can not be conditional"
msgstr ""

#: common/flatpak-context.c:2318
#, c-format
msgid "Invalid env format %s"
msgstr "अमान्य वातावरण प्रारूप %s"

#: common/flatpak-context.c:2399
#, c-format
msgid "Environment variable name must not contain '=': %s"
msgstr "वातावरण चर नाम में '=' नहीं होना चाहिए: %s"

#: common/flatpak-context.c:2527 common/flatpak-context.c:2535
#, c-format
msgid "--add-policy arguments must be in the form SUBSYSTEM.KEY=VALUE"
msgstr "--add-policy तर्क SUBSYSTEM.KEY=VALUE के रूप में होने चाहिए"

#: common/flatpak-context.c:2542
#, c-format
msgid "--add-policy values can't start with \"!\""
msgstr "--add-policy मान \"!\" से प्रारंभ नहीं हो सकते"

#: common/flatpak-context.c:2567 common/flatpak-context.c:2575
#, c-format
msgid "--remove-policy arguments must be in the form SUBSYSTEM.KEY=VALUE"
msgstr "--remove-policy तर्क SUBSYSTEM.KEY=VALUE के रूप में होने चाहिए"

#: common/flatpak-context.c:2582
#, c-format
msgid "--remove-policy values can't start with \"!\""
msgstr "--remove-policy मान \"!\" से प्रारंभ नहीं हो सकते"

#: common/flatpak-context.c:2657
msgid "Share with host"
msgstr "होस्ट के साथ साझा करें"

#: common/flatpak-context.c:2657 common/flatpak-context.c:2658
msgid "SHARE"
msgstr "साझा करें"

#: common/flatpak-context.c:2658
msgid "Unshare with host"
msgstr "होस्ट के साथ साझाकरण रद्द करें"

#: common/flatpak-context.c:2659
msgid "Require conditions to be met for a subsystem to get shared"
msgstr ""

#: common/flatpak-context.c:2659
msgid "SHARE:CONDITION"
msgstr ""

#: common/flatpak-context.c:2660
msgid "Expose socket to app"
msgstr "सॉकेट को ऐप के संपर्क में लाएं"

#: common/flatpak-context.c:2660 common/flatpak-context.c:2661
msgid "SOCKET"
msgstr "सॉकेट"

#: common/flatpak-context.c:2661
msgid "Don't expose socket to app"
msgstr "सॉकेट को ऐप के संपर्क में लाएं"

#: common/flatpak-context.c:2662
msgid "Require conditions to be met for a socket to get exposed"
msgstr ""

#: common/flatpak-context.c:2662
msgid "SOCKET:CONDITION"
msgstr ""

#: common/flatpak-context.c:2663
msgid "Expose device to app"
msgstr "डिवाइस को ऐप के संपर्क में लाएं"

#: common/flatpak-context.c:2663 common/flatpak-context.c:2664
msgid "DEVICE"
msgstr "उपकरण"

#: common/flatpak-context.c:2664
msgid "Don't expose device to app"
msgstr "डिवाइस को ऐप के संपर्क में न लाएं"

#: common/flatpak-context.c:2665
msgid "Require conditions to be met for a device to get exposed"
msgstr ""

#: common/flatpak-context.c:2665
msgid "DEVICE:CONDITION"
msgstr ""

#: common/flatpak-context.c:2666
msgid "Allow feature"
msgstr "विशेषता को अनुमति दें"

#: common/flatpak-context.c:2666 common/flatpak-context.c:2667
msgid "FEATURE"
msgstr "विशेषता"

#: common/flatpak-context.c:2667
msgid "Don't allow feature"
msgstr "विशेषता को अनुमति न दें"

#: common/flatpak-context.c:2668
msgid "Require conditions to be met for a feature to get allowed"
msgstr ""

#: common/flatpak-context.c:2668
msgid "FEATURE:CONDITION"
msgstr ""

#: common/flatpak-context.c:2669
msgid "Expose filesystem to app (:ro for read-only)"
msgstr "फाइलप्रणाली को ऐप में उजागर करें (: केवल पढ़ने के लिए ro)"

#: common/flatpak-context.c:2669
msgid "FILESYSTEM[:ro]"
msgstr "फाइलप्रणाली[:ro]"

#: common/flatpak-context.c:2670
msgid "Don't expose filesystem to app"
msgstr "ऐप के सामने फाइलप्रणाली को उजागर न करें"

#: common/flatpak-context.c:2670
msgid "FILESYSTEM"
msgstr "फाइलप्रणाली"

#: common/flatpak-context.c:2671
msgid "Set environment variable"
msgstr "वातावरण चर निर्धारित करें"

#: common/flatpak-context.c:2671
msgid "VAR=VALUE"
msgstr "चर=मान"

#: common/flatpak-context.c:2672
msgid "Read environment variables in env -0 format from FD"
msgstr "FD से env -0 प्रारूप में वातावरण चर पढ़ें"

#: common/flatpak-context.c:2673
msgid "Remove variable from environment"
msgstr "वातावरण से चर हटाएं"

#: common/flatpak-context.c:2673
msgid "VAR"
msgstr "चर"

#: common/flatpak-context.c:2674
msgid "Allow app to own name on the session bus"
msgstr "ऐप को सत्र बस में अपना नाम रखने की अनुमति दें"

#: common/flatpak-context.c:2674 common/flatpak-context.c:2675
#: common/flatpak-context.c:2676 common/flatpak-context.c:2677
#: common/flatpak-context.c:2678 common/flatpak-context.c:2679
#: common/flatpak-context.c:2680
msgid "DBUS_NAME"
msgstr "DBUS_NAME"

#: common/flatpak-context.c:2675
msgid "Allow app to talk to name on the session bus"
msgstr "ऐप को सत्र बस में नाम से बात करने की अनुमति दें"

#: common/flatpak-context.c:2676
msgid "Don't allow app to talk to name on the session bus"
msgstr "ऐप को सत्र बस में नाम से बात करने की अनुमति न दें"

#: common/flatpak-context.c:2677
msgid "Allow app to own name on the system bus"
msgstr "ऐप को सिस्टम बस पर अपना नाम रखने की अनुमति दें"

#: common/flatpak-context.c:2678
msgid "Allow app to talk to name on the system bus"
msgstr "ऐप को सिस्टम बस पर नाम से बात करने की अनुमति दें"

#: common/flatpak-context.c:2679
msgid "Don't allow app to talk to name on the system bus"
msgstr "ऐप को सिस्टम बस पर नाम से बात करने की अनुमति न दें"

#: common/flatpak-context.c:2680
#, fuzzy
msgid "Allow app to own name on the a11y bus"
msgstr "ऐप को सिस्टम बस पर अपना नाम रखने की अनुमति दें"

#: common/flatpak-context.c:2681
msgid "Add generic policy option"
msgstr "सामान्य नीति विकल्प जोड़ें"

#: common/flatpak-context.c:2681 common/flatpak-context.c:2682
msgid "SUBSYSTEM.KEY=VALUE"
msgstr "SUBSYSTEM.KEY=VALUE"

#: common/flatpak-context.c:2682
msgid "Remove generic policy option"
msgstr "सामान्य नीति विकल्प हटाएं"

#: common/flatpak-context.c:2683
msgid "Add USB device to enumerables"
msgstr ""

#: common/flatpak-context.c:2683 common/flatpak-context.c:2684
msgid "VENDOR_ID:PRODUCT_ID"
msgstr ""

#: common/flatpak-context.c:2684
msgid "Add USB device to hidden list"
msgstr ""

#: common/flatpak-context.c:2685
msgid "A list of USB devices that are enumerable"
msgstr ""

#: common/flatpak-context.c:2685
msgid "LIST"
msgstr ""

#: common/flatpak-context.c:2686
msgid "File containing a list of USB devices to make enumerable"
msgstr ""

#: common/flatpak-context.c:2686 common/flatpak-context.c:2687
msgid "FILENAME"
msgstr "फाइलनाम"

#: common/flatpak-context.c:2687
msgid "Persist home directory subpath"
msgstr "गृह निर्देशिका उपपथ जारी रखें"

#. This is not needed/used anymore, so hidden, but we accept it for backwards compat
#: common/flatpak-context.c:2689
msgid "Don't require a running session (no cgroups creation)"
msgstr "किसी चालू सत्र की आवश्यकता नहीं है (कोई cgroups निर्माण नहीं)"

#: common/flatpak-context.c:3718
#, c-format
msgid "Not replacing \"%s\" with tmpfs: %s"
msgstr "\"%s\" को tmpfs से प्रतिस्थापित नहीं किया जा रहा है: %s"

#: common/flatpak-context.c:3726
#, c-format
msgid "Not sharing \"%s\" with sandbox: %s"
msgstr "सैंडबॉक्स के साथ \"%s\" साझा नहीं किया जा रहा: %s"

#. Even if the error is one that we would normally silence, like
#. * the path not existing, it seems reasonable to make more of a fuss
#. * about the home directory not existing or otherwise being unusable,
#. * so this is intentionally not using cannot_export()
#: common/flatpak-context.c:3828
#, c-format
msgid "Not allowing home directory access: %s"
msgstr "गृह निर्देशिका तक पहुंच की अनुमति नहीं: %s"

#: common/flatpak-context.c:4062
#, c-format
msgid "Unable to provide a temporary home directory in the sandbox: %s"
msgstr "सैंडबॉक्स में अस्थायी गृह निर्देशिका प्रदान करने में असमर्थ: %s"

#: common/flatpak-dir.c:442
#, c-format
msgid "Configured collection ID ‘%s’ not in summary file"
msgstr "विन्यस्त संग्रह ID ‘%s’ सारांश फाइल में नहीं है"

#: common/flatpak-dir.c:587
#, c-format
msgid "Unable to load summary from remote %s: %s"
msgstr "रिमोट %s से सारांश लोड करने में असमर्थ: %s"

#: common/flatpak-dir.c:764 common/flatpak-dir.c:800 common/flatpak-dir.c:906
#, c-format
msgid "No such ref '%s' in remote %s"
msgstr "रिमोट %2$s में ऐसा कोई संदर्भ '%1$s' नहीं है"

#: common/flatpak-dir.c:891 common/flatpak-dir.c:1051 common/flatpak-dir.c:1080
#: common/flatpak-dir.c:1092
#, c-format
msgid "No entry for %s in remote %s summary flatpak cache"
msgstr "रिमोट %2$s सारांश flatpak कैशे में %1$s के लिए कोई प्रविष्टि नहीं"

#: common/flatpak-dir.c:1069
#, c-format
msgid "No summary or Flatpak cache available for remote %s"
msgstr "रिमोट %s के लिए कोई सारांश या Flatpak कैशे उपलब्ध नहीं है"

#: common/flatpak-dir.c:1097
#, c-format
msgid "Missing xa.data in summary for remote %s"
msgstr "रिमोट %s के सारांश में xa.data गुम है"

#: common/flatpak-dir.c:1103 common/flatpak-dir.c:1546
#, c-format
msgid "Unsupported summary version %d for remote %s"
msgstr "रिमोट %2$s के लिए असमर्थित सारांश संस्करण %1$d"

#: common/flatpak-dir.c:1200
msgid "Remote OCI index has no registry uri"
msgstr "रिमोट OCI सूचकांक में कोई रजिस्ट्री URI नहीं है"

#: common/flatpak-dir.c:1261
#, c-format
msgid "Couldn't find ref %s in remote %s"
msgstr "रिमोट %2$s में संदर्भ %1$s नहीं मिल सका"

#: common/flatpak-dir.c:1288 common/flatpak-dir.c:1381
#, fuzzy, c-format
msgid "Commit has no requested ref ‘%s’ in ref binding metadata (found: ‘%s’)"
msgstr "संदर्भ बाइंडिंग मेटाडेटा में कमिट ने संदर्भ ‘%s’ का कोई अनुरोध नहीं किया है"

#: common/flatpak-dir.c:1413
#, c-format
msgid "Configured collection ID ‘%s’ not in binding metadata"
msgstr "विन्यस्त संग्रह ID ‘%s’  बाइंडिंग मेटाडेटा में नहीं है"

#: common/flatpak-dir.c:1449 common/flatpak-dir.c:5645
#, c-format
msgid "Couldn't find latest checksum for ref %s in remote %s"
msgstr "रिमोट %2$s में संदर्भ %1$s के लिए नवीनतम चेकसम नहीं मिल सका"

#: common/flatpak-dir.c:1516 common/flatpak-dir.c:1552
#, c-format
msgid "No entry for %s in remote %s summary flatpak sparse cache"
msgstr "रिमोट %2$s सारांश flatpak स्पार्स कैशे में %1$s के लिए कोई प्रविष्टि नहीं"

#: common/flatpak-dir.c:2540
#, c-format
msgid "Commit metadata for %s not matching expected metadata"
msgstr "%s के लिए कमिट मेटाडेटा अपेक्षित मेटाडेटा से मेल नहीं खा रहा है"

#: common/flatpak-dir.c:2823
msgid "Unable to connect to system bus"
msgstr "सिस्टम बस से जुड़ने में असमर्थ"

#: common/flatpak-dir.c:3419
msgid "User installation"
msgstr "उपयोक्ता स्थापना"

#: common/flatpak-dir.c:3426
#, c-format
msgid "System (%s) installation"
msgstr "सिस्टम (%s) स्थापना"

#: common/flatpak-dir.c:3472
#, c-format
msgid "No overrides found for %s"
msgstr "%s के लिए कोई अध्यारोहण नहीं मिला"

#: common/flatpak-dir.c:3625
#, c-format
msgid "%s (commit %s) not installed"
msgstr "%s (कमिट %s) स्थापित नहीं है"

#: common/flatpak-dir.c:4650
#, c-format
msgid "Error parsing system flatpakrepo file for %s: %s"
msgstr "%s के लिए सिस्टम flatpakrepo फाइल का विश्लेषण करने में त्रुटि: %s"

#: common/flatpak-dir.c:4735
#, c-format
msgid "While opening repository %s: "
msgstr "रिपॉजिटरी %s खोलते समय: "

#: common/flatpak-dir.c:5004
#, c-format
msgid "The config key %s is not set"
msgstr "विन्यास कुंजी %s निर्धारित नहीं है"

#: common/flatpak-dir.c:5140
#, c-format
msgid "No current %s pattern matching %s"
msgstr "%2$s से मेल खाता कोई वर्तमान %1$s प्रतिमान नहीं"

#: common/flatpak-dir.c:5422
msgid "No appstream commit to deploy"
msgstr "परिनियोजन के लिए कोई ऐपस्ट्रीम कमिट नहीं है"

#: common/flatpak-dir.c:5941 common/flatpak-dir.c:7266
#: common/flatpak-dir.c:10881 common/flatpak-dir.c:11618
msgid "Can't pull from untrusted non-gpg verified remote"
msgstr "अविश्वसनीय गैर-जीपीजी सत्यापित रिमोट से नहीं खींच सकते"

#: common/flatpak-dir.c:6376 common/flatpak-dir.c:6591
msgid "Extra data not supported for non-gpg-verified local system installs"
msgstr "गैर-जीपीजी-सत्यापित स्थानीय सिस्टम स्थापना के लिए अतिरिक्त डेटा समर्थित नहीं है"

#: common/flatpak-dir.c:6415 common/flatpak-dir.c:6782
#, c-format
msgid "Invalid checksum for extra data uri %s"
msgstr "अतिरिक्त डेटा URI %s के लिए अमान्य चेकसम"

#: common/flatpak-dir.c:6424
#, c-format
msgid "Empty name for extra data uri %s"
msgstr "अतिरिक्त डेटा URI %s के लिए खाली नाम"

#: common/flatpak-dir.c:6432
#, c-format
msgid "Unsupported extra data uri %s"
msgstr "असमर्थित अतिरिक्त डेटा URI %s"

#: common/flatpak-dir.c:6461
#, c-format
msgid "Failed to load local extra-data %s: %s"
msgstr "स्थानीय अतिरिक्त डेटा %s लोड करने में विफल: %s"

#: common/flatpak-dir.c:6469
#, c-format
msgid "Wrong size for extra-data %s"
msgstr "अतिरिक्त डेटा %s के लिए गलत आकार"

#: common/flatpak-dir.c:6488
#, c-format
msgid "While downloading %s: "
msgstr "%s डाउनलोड करते समय: "

#: common/flatpak-dir.c:6498
#, c-format
msgid "Wrong size for extra data %s"
msgstr "अतिरिक्त डेटा %s के लिए गलत आकार"

#: common/flatpak-dir.c:6507
#, c-format
msgid "Invalid checksum for extra data %s"
msgstr "अतिरिक्त डेटा %s के लिए अमान्य चेकसम"

#: common/flatpak-dir.c:7096 common/flatpak-dir.c:7349
#, c-format
msgid "While pulling %s from remote %s: "
msgstr "रिमोट %2$s से %1$s खींचते समय: "

#: common/flatpak-dir.c:7290 common/flatpak-repo-utils.c:3886
msgid "GPG signatures found, but none are in trusted keyring"
msgstr "GPG हस्ताक्षर मिले, लेकिन विश्वसनीय कीरिंग में कोई भी नहीं है"

#: common/flatpak-dir.c:7307
#, c-format
msgid "Commit for ‘%s’ has no ref binding"
msgstr "‘%s’ के लिए प्रतिबद्धता में कोई संदर्भ बंधन नहीं है"

#: common/flatpak-dir.c:7312
#, c-format
msgid "Commit for ‘%s’ is not in expected bound refs: %s"
msgstr "‘%s’ के लिए कमिट अपेक्षित बाध्य संदर्भ में नहीं है: %s"

#: common/flatpak-dir.c:7488
msgid "Only applications can be made current"
msgstr "केवल अनुप्रयोगों को वर्तमान बनाया जा सकता है"

#: common/flatpak-dir.c:8192
msgid "Not enough memory"
msgstr "पर्याप्त मेमोरी नहीं"

#: common/flatpak-dir.c:8211
msgid "Failed to read from exported file"
msgstr "निर्यात की गई फाइल से पढ़ने में विफल"

#: common/flatpak-dir.c:8401
msgid "Error reading mimetype xml file"
msgstr "माइमटाइप xml फाइल पढ़ने में त्रुटि"

#: common/flatpak-dir.c:8406
msgid "Invalid mimetype xml file"
msgstr "अमान्य माइमटाइप xml फाइल"

#: common/flatpak-dir.c:8492
#, c-format
msgid "D-Bus service file '%s' has wrong name"
msgstr "डी-बस सेवा फाइल '%s' का नाम गलत है"

#: common/flatpak-dir.c:8647
#, c-format
msgid "Invalid Exec argument %s"
msgstr "अमान्य निष्पादन तर्क %s"

#: common/flatpak-dir.c:9115
msgid "While getting detached metadata: "
msgstr "पृथक मेटाडेटा प्राप्त करते समय: "

#: common/flatpak-dir.c:9120 common/flatpak-dir.c:9125
#: common/flatpak-dir.c:9129
msgid "Extra data missing in detached metadata"
msgstr "पृथक मेटाडेटा में अतिरिक्त डेटा गायब है"

#: common/flatpak-dir.c:9133
msgid "While creating extradir: "
msgstr "अतिरिक्त निर्देशिका बनाते समय: "

#: common/flatpak-dir.c:9154 common/flatpak-dir.c:9187
msgid "Invalid checksum for extra data"
msgstr "अतिरिक्त डेटा के लिए अमान्य चेकसम"

#: common/flatpak-dir.c:9183
msgid "Wrong size for extra data"
msgstr "अतिरिक्त डेटा के लिए गलत आकार"

#: common/flatpak-dir.c:9196
#, c-format
msgid "While writing extra data file '%s': "
msgstr "अतिरिक्त डेटा फाइल '%s' लिखते समय: "

#: common/flatpak-dir.c:9204
#, c-format
msgid "Extra data %s missing in detached metadata"
msgstr "पृथक मेटाडेटा में अतिरिक्त डेटा %s गायब है"

#: common/flatpak-dir.c:9278
#, fuzzy, c-format
msgid "Unable to get runtime key from metadata"
msgstr "मेटाडेटा के लिए वैकल्पिक फाइल का प्रयोग करें"

#: common/flatpak-dir.c:9402
#, c-format
msgid "apply_extra script failed, exit status %d"
msgstr "apply_extra स्क्रिप्ट विफल, निकास स्थिति %d"

#. Translators: The placeholder is for an app ref.
#: common/flatpak-dir.c:9591
#, c-format
msgid "Installing %s is not allowed by the policy set by your administrator"
msgstr "आपके प्रशासक द्वारा निर्धारित नीति के अनुसार %s स्थापित करने की अनुमति नहीं है"

#: common/flatpak-dir.c:9690
#, c-format
msgid "While trying to resolve ref %s: "
msgstr "संदर्भ %s को हल करने का प्रयास करते समय: "

#: common/flatpak-dir.c:9702
#, c-format
msgid "%s is not available"
msgstr "%s उपलब्ध नहीं है"

#: common/flatpak-dir.c:9714 common/flatpak-dir.c:11495
#, c-format
msgid "%s commit %s already installed"
msgstr "%1$s कमिट %2$s पहले से ही स्थापित है"

#: common/flatpak-dir.c:9721
msgid "Can't create deploy directory"
msgstr "परिनियोजन निर्देशिका नहीं बना सके"

#: common/flatpak-dir.c:9729
#, c-format
msgid "Failed to read commit %s: "
msgstr "कमिट %s को पढ़ने में विफल: "

#: common/flatpak-dir.c:9750
#, c-format
msgid "While trying to checkout %s into %s: "
msgstr "%1$s को %2$s में चेकआउट करने का प्रयास करते समय: "

#: common/flatpak-dir.c:9769
msgid "While trying to checkout metadata subpath: "
msgstr "मेटाडेटा उपपथ को चेकआउट करने का प्रयास करते समय: "

#: common/flatpak-dir.c:9801
#, c-format
msgid "While trying to checkout subpath ‘%s’: "
msgstr "उपपथ ‘%s’ को चेकआउट करने का प्रयास करते समय: "

#: common/flatpak-dir.c:9811
msgid "While trying to remove existing extra dir: "
msgstr "मौजूदा अतिरिक्त निर्देशिका को हटाने की कोशिश करते समय: "

#: common/flatpak-dir.c:9822
msgid "While trying to apply extra data: "
msgstr "अतिरिक्त डेटा लागू करने का प्रयास करते समय: "

#: common/flatpak-dir.c:9849
#, c-format
msgid "Invalid commit ref %s: "
msgstr "अमान्य कमिट संदर्भ %s: "

#: common/flatpak-dir.c:9857 common/flatpak-dir.c:9869
#, c-format
msgid "Deployed ref %s does not match commit (%s)"
msgstr "परिनियोजित संदर्भ %s कमिट (%s) से मेल नहीं खाता"

#: common/flatpak-dir.c:9863
#, c-format
msgid "Deployed ref %s branch does not match commit (%s)"
msgstr "परिनियोजित संदर्भ %s शाखा कमिट (%s) से मेल नहीं खाती"

#: common/flatpak-dir.c:10125 common/flatpak-installation.c:1911
#, c-format
msgid "%s branch %s already installed"
msgstr "%1$s शाखा %2$s पहले से ही स्थापित है"

#: common/flatpak-dir.c:10985
#, c-format
msgid "Could not unmount revokefs-fuse filesystem at %s: "
msgstr "%s पर revokefs-fuse फाइलप्रणाली को अनमाउंट नहीं किया जा सका: "

#: common/flatpak-dir.c:11289
#, c-format
msgid "This version of %s is already installed"
msgstr "%s का यह संस्करण पहले से ही स्थापित है"

#: common/flatpak-dir.c:11302
#, c-format
msgid "Can't change remote during bundle install"
msgstr "बंडल स्थापना के दौरान रिमोट नहीं बदला जा सकता"

#: common/flatpak-dir.c:11571
msgid "Can't update to a specific commit without root permissions"
msgstr "रूट अनुमतियों के बिना किसी विशिष्ट कमिट में अद्यतन नहीं किया जा सकता"

#: common/flatpak-dir.c:11852
#, c-format
msgid "Can't remove %s, it is needed for: %s"
msgstr "%s को हटाया नहीं जा सकता, इसकी आवश्यकता है: %s"

#: common/flatpak-dir.c:11912 common/flatpak-installation.c:2067
#, c-format
msgid "%s branch %s is not installed"
msgstr "%1$s शाखा %2$s स्थापित नहीं है"

#: common/flatpak-dir.c:12165
#, c-format
msgid "%s commit %s not installed"
msgstr "%1$s कमिट %2$s स्थापित नहीं है"

#: common/flatpak-dir.c:12501
#, c-format
msgid "Pruning repo failed: %s"
msgstr "रेपो छंटाई विफल: %s"

#: common/flatpak-dir.c:12669 common/flatpak-dir.c:12675
#, c-format
msgid "Failed to load filter '%s'"
msgstr "'%s' फिल्टर लोड करने में विफल"

#: common/flatpak-dir.c:12681
#, c-format
msgid "Failed to parse filter '%s'"
msgstr "'%s' फिल्टर का विश्लेषण करने में विफल"

#: common/flatpak-dir.c:12963
msgid "Failed to write summary cache: "
msgstr "सारांश कैशे लिखने में विफल: "

#: common/flatpak-dir.c:12982
#, c-format
msgid "No oci summary cached for remote '%s'"
msgstr "रिमोट '%s' के लिए कोई oci सारांश कैशे नहीं किया गया"

#: common/flatpak-dir.c:13207
#, c-format
msgid "No cached summary for remote '%s'"
msgstr "रिमोट '%s' के लिए कोई कैश्ड सारांश नहीं"

#: common/flatpak-dir.c:13248
#, c-format
msgid "Invalid checksum for indexed summary %s read from %s"
msgstr "%2$s से पढ़े गए अनुक्रमित सारांश %1$s के लिए अमान्य चेकसम"

#: common/flatpak-dir.c:13321
#, c-format
msgid ""
"Remote listing for %s not available; server has no summary file. Check the "
"URL passed to remote-add was valid."
msgstr ""
"%s के लिए रिमोट सूची उपलब्ध नहीं है; सर्वर में कोई सारांश फाइल नहीं है। जांचें कि remote-"
"add को दिया गया URL मान्य था।"

#: common/flatpak-dir.c:13698
#, c-format
msgid "Invalid checksum for indexed summary %s for remote '%s'"
msgstr "रिमोट '%2$s' के लिए अनुक्रमित सारांश %1$s के लिए अमान्य चेकसम"

#: common/flatpak-dir.c:14388
#, c-format
msgid "Multiple branches available for %s, you must specify one of: "
msgstr "%s के लिए एकाधिक शाखाएं उपलब्ध हैं, आपको इनमें से एक निर्दिष्ट करना होगा: "

#: common/flatpak-dir.c:14454
#, c-format
msgid "Nothing matches %s"
msgstr "%s से कुछ भी मेल नहीं खाता"

#: common/flatpak-dir.c:14562
#, c-format
msgid "Can't find ref %s%s%s%s%s"
msgstr "संदर्भ %s%s%s%s%s नहीं मिल सका"

#: common/flatpak-dir.c:14605
#, c-format
msgid "Error searching remote %s: %s"
msgstr "रिमोट %s को खोजने में त्रुटि: %s"

#: common/flatpak-dir.c:14702
#, c-format
msgid "Error searching local repository: %s"
msgstr "स्थानीय रिपोजिटरी खोजने में त्रुटिः %s"

#: common/flatpak-dir.c:14839
#, c-format
msgid "%s/%s/%s not installed"
msgstr "%s/%s/%s स्थापित नहीं है"

#: common/flatpak-dir.c:15042
#, c-format
msgid "Could not find installation %s"
msgstr "स्थापना %s नहीं मिल सकी"

#: common/flatpak-dir.c:15612
#, c-format
msgid "Invalid file format, no %s group"
msgstr "अमान्य फाइल प्रारूप, कोई %s समूह नहीं"

#: common/flatpak-dir.c:15617 common/flatpak-repo-utils.c:2836
#, c-format
msgid "Invalid version %s, only 1 supported"
msgstr "अमान्य संस्करण %s, केवल 1 समर्थित"

#: common/flatpak-dir.c:15622 common/flatpak-dir.c:15627
#, c-format
msgid "Invalid file format, no %s specified"
msgstr "अमान्य फाइल प्रारूप, कोई %s निर्दिष्ट नहीं"

#. Check some minimal size so we don't get crap
#: common/flatpak-dir.c:15647
msgid "Invalid file format, gpg key invalid"
msgstr "अमान्य फाइल प्रारूप, gpg कुंजी अमान्य"

#: common/flatpak-dir.c:15675 common/flatpak-repo-utils.c:2917
msgid "Collection ID requires GPG key to be provided"
msgstr "संग्रह ID के लिए GPG कुंजी प्रदान करना आवश्यक है"

#: common/flatpak-dir.c:15718
#, c-format
msgid "Runtime %s, branch %s is already installed"
msgstr "रनटाइम %s, शाखा %s पहले से ही स्थापित है"

#: common/flatpak-dir.c:15719
#, c-format
msgid "App %s, branch %s is already installed"
msgstr "ऐप %s, शाखा %s पहले से ही स्थापित है"

#: common/flatpak-dir.c:15953
#, c-format
msgid "Can't remove remote '%s' with installed ref %s (at least)"
msgstr "स्थापित संदर्भ %2$s के साथ रिमोट '%1$s' को नहीं हटाया जा सकता (कम से कम)"

#: common/flatpak-dir.c:16058
#, c-format
msgid "Invalid character '/' in remote name: %s"
msgstr "रिमोट नाम में अमान्य वर्ण '/': %s"

#: common/flatpak-dir.c:16064
#, c-format
msgid "No configuration for remote %s specified"
msgstr "रिमोट %s के लिए कोई विन्यास निर्दिष्ट नहीं है"

#: common/flatpak-dir.c:17597
#, c-format
msgid "Skipping deletion of mirror ref (%s, %s)…\n"
msgstr "मिरर संदर्भ का विलोपन छोड़ा जा रहा है (%s, %s)…\n"

#: common/flatpak-exports.c:931
#, c-format
msgid "An absolute path is required"
msgstr "एक पूर्ण पथ की आवश्यकता है"

#: common/flatpak-exports.c:948
#, c-format
msgid "Unable to open path \"%s\": %s"
msgstr "पथ \"%s\" खोलने में असमर्थ: %s"

#: common/flatpak-exports.c:955
#, c-format
msgid "Unable to get file type of \"%s\": %s"
msgstr "\"%s\" का फाइल प्रकार प्राप्त करने में असमर्थ: %s"

#: common/flatpak-exports.c:964
#, c-format
msgid "File \"%s\" has unsupported type 0o%o"
msgstr "फाइल \"%s\" में असमर्थित प्रकार 0o%o है"

#: common/flatpak-exports.c:970
#, c-format
msgid "Unable to get filesystem information for \"%s\": %s"
msgstr "\"%s\" के लिए फाइलप्रणाली जानकारी प्राप्त करने में असमर्थ: %s"

#: common/flatpak-exports.c:980
#, c-format
msgid "Ignoring blocking autofs path \"%s\""
msgstr "अवरुद्ध autofs पथ \"%s\" को अनदेखा किया जा रहा है"

#: common/flatpak-exports.c:996 common/flatpak-exports.c:1009
#: common/flatpak-exports.c:1022
#, c-format
msgid "Path \"%s\" is reserved by Flatpak"
msgstr "पथ \"%s\" Flatpak द्वारा आरक्षित है"

#: common/flatpak-exports.c:1076
#, c-format
msgid "Unable to resolve symbolic link \"%s\": %s"
msgstr "प्रतीकात्मक लिंक \"%s\" का समाधान करने में असमर्थ: %s"

#: common/flatpak-glib-backports.c:69
msgid "Empty string is not a number"
msgstr "ख़ाली स्ट्रिंग एक संख्या नहीं है"

#: common/flatpak-glib-backports.c:95
#, c-format
msgid "“%s” is not an unsigned number"
msgstr "“%s” एक अहस्ताक्षरित संख्या नहीं है"

#: common/flatpak-glib-backports.c:105
#, c-format
msgid "Number “%s” is out of bounds [%s, %s]"
msgstr "संख्या “%s” सीमा से बाहर है [%s, %s]"

#: common/flatpak-image-source.c:83
msgid "Only sha256 image checksums are supported"
msgstr ""

#: common/flatpak-image-source.c:100 common/flatpak-image-source.c:108
msgid "Image is not a manifest"
msgstr "छवि मैनिफेस्ट नहीं है"

#: common/flatpak-image-source.c:123
msgid "No org.flatpak.ref found in image"
msgstr ""

#: common/flatpak-image-source.c:148
#, c-format
msgid "Ref '%s' not found in registry"
msgstr "संदर्भ '%s' रजिस्ट्री में नहीं मिला"

#: common/flatpak-image-source.c:157
msgid "Multiple images in registry, specify a ref with --ref"
msgstr "रजिस्ट्री में एकाधिक छवियां, --ref के साथ एक संदर्भ निर्दिष्ट करें"

#: common/flatpak-installation.c:834
#, c-format
msgid "Ref %s not installed"
msgstr "संदर्भ %s स्थापित नहीं है"

#: common/flatpak-installation.c:875
#, c-format
msgid "App %s not installed"
msgstr "ऐप %s स्थापित नहीं हुआ"

#: common/flatpak-installation.c:1395
#, c-format
msgid "Remote '%s' already exists"
msgstr "रिमोट '%s' पहले से मौजूद है"

#: common/flatpak-installation.c:1946
#, c-format
msgid "As requested, %s was only pulled, but not installed"
msgstr "जैसा कि अनुरोध किया गया था, %s को केवल खींचा गया, लेकिन स्थापित नहीं किया गया"

#: common/flatpak-instance.c:533 common/flatpak-instance.c:687
#: common/flatpak-instance.c:728
#, c-format
msgid "Unable to create directory %s"
msgstr "निर्देशिका %s बनाने में असमर्थ"

#: common/flatpak-instance.c:554
#, c-format
msgid "Unable to lock %s"
msgstr "%s को लॉक करने में असमर्थ"

#: common/flatpak-instance.c:627
#, c-format
msgid "Unable to create temporary directory in %s"
msgstr "%s में अस्थायी निर्देशिका बनाने में असमर्थ"

#: common/flatpak-instance.c:639
#, c-format
msgid "Unable to create file %s"
msgstr "फाइल %s बनाने में असमर्थ"

#: common/flatpak-instance.c:646
#, c-format
msgid "Unable to update symbolic link %s/%s"
msgstr "प्रतीकात्मक लिंक %s/%s को अद्यतन करने में असमर्थ"

#: common/flatpak-oci-registry.c:1197
msgid "Only Bearer authentication supported"
msgstr "केवल बियरर प्रमाणीकरण समर्थित"

#: common/flatpak-oci-registry.c:1206
msgid "Only realm in authentication request"
msgstr "प्रमाणीकरण अनुरोध में केवल रियल्म"

#: common/flatpak-oci-registry.c:1213
msgid "Invalid realm in authentication request"
msgstr "प्रमाणीकरण अनुरोध में अमान्य रियल्म"

#: common/flatpak-oci-registry.c:1283
#, c-format
msgid "Authorization failed: %s"
msgstr "अधिकृतीकरण विफल: %s"

#: common/flatpak-oci-registry.c:1285
msgid "Authorization failed"
msgstr "अधिकृतीकरण विफल"

#: common/flatpak-oci-registry.c:1289
#, c-format
msgid "Unexpected response status %d when requesting token: %s"
msgstr "टोकन का अनुरोध करते समय अप्रत्याशित प्रतिक्रिया स्थिति %d: %s"

#: common/flatpak-oci-registry.c:1300
msgid "Invalid authentication request response"
msgstr "अमान्य प्रमाणीकरण अनुरोध प्रतिक्रिया"

#: common/flatpak-oci-registry.c:1731
#, c-format
msgid "Flatpak was compiled without zstd support"
msgstr ""

#: common/flatpak-oci-registry.c:1923 common/flatpak-oci-registry.c:1975
#: common/flatpak-oci-registry.c:2004 common/flatpak-oci-registry.c:2059
#: common/flatpak-oci-registry.c:2115 common/flatpak-oci-registry.c:2193
msgid "Invalid delta file format"
msgstr "अमान्य डेल्टा फाइल प्रारूप"

#: common/flatpak-oci-registry.c:3198 common/flatpak-oci-registry.c:3382
msgid "Invalid OCI image config"
msgstr "अमान्य OCI छवि विन्यास"

#: common/flatpak-oci-registry.c:3260 common/flatpak-oci-registry.c:3531
#, c-format
msgid "Wrong layer checksum, expected %s, was %s"
msgstr "गलत परत चेकसम, अपेक्षित %s, %s था"

#: common/flatpak-oci-registry.c:3359
#, c-format
msgid "No ref specified for OCI image %s"
msgstr "OCI छवि %s के लिए कोई संदर्भ निर्दिष्ट नहीं है"

#: common/flatpak-oci-registry.c:3369
#, c-format
msgid "Wrong ref (%s) specified for OCI image %s, expected %s"
msgstr "OCI छवि %s के लिए संदर्भ रेफरी (%s) निर्दिष्ट, अपेक्षित %s"

#: common/flatpak-progress.c:236
#, c-format
msgid "Downloading metadata: %u/(estimating) %s"
msgstr "मेटाडेटा डाउनलोड हो रहा है: %u/(estimating) %s"

#: common/flatpak-progress.c:260
#, c-format
msgid "Downloading: %s/%s"
msgstr "डाउनलोड हो रहा है: %s/%s"

#: common/flatpak-progress.c:280
#, c-format
msgid "Downloading extra data: %s/%s"
msgstr "अतिरिक्त डेटा डाउनलोड हो रहा है: %s/%s"

#: common/flatpak-progress.c:285
#, c-format
msgid "Downloading files: %d/%d %s"
msgstr "फाइलें डाउनलोड हो रही हैं: %d/%d %s"

#: common/flatpak-ref-utils.c:122
msgid "Name can't be empty"
msgstr "नाम खाली नहीं हो सकता"

#: common/flatpak-ref-utils.c:129
msgid "Name can't be longer than 255 characters"
msgstr "नाम 255 अक्षरों से अधिक लंबा नहीं हो सकता"

#: common/flatpak-ref-utils.c:142
msgid "Name can't start with a period"
msgstr "नाम किसी पूर्णविराम से प्रारंभ नहीं हो सकता"

#: common/flatpak-ref-utils.c:148
#, c-format
msgid "Name can't start with %c"
msgstr "नाम %c से प्रारंभ नहीं हो सकता"

#: common/flatpak-ref-utils.c:164
msgid "Name can't end with a period"
msgstr "नाम किसी पूर्णविराम के साथ समाप्त नहीं हो सकता"

#: common/flatpak-ref-utils.c:171 common/flatpak-ref-utils.c:183
msgid "Only last name segment can contain -"
msgstr "केवल अंतिम नाम खंड में शामिल हो सकते हैं -"

#: common/flatpak-ref-utils.c:174
#, c-format
msgid "Name segment can't start with %c"
msgstr "नाम खंड %c से प्रारंभ नहीं हो सकता"

#: common/flatpak-ref-utils.c:186
#, c-format
msgid "Name can't contain %c"
msgstr "नाम में %c नहीं हो सकता"

#: common/flatpak-ref-utils.c:195
msgid "Names must contain at least 2 periods"
msgstr "नाम में कम से कम 2 पूर्णविराम अवश्य होने चाहिए"

#: common/flatpak-ref-utils.c:312
msgid "Arch can't be empty"
msgstr "आर्किटेक्चर खाली नहीं हो सकता"

#: common/flatpak-ref-utils.c:323
#, c-format
msgid "Arch can't contain %c"
msgstr "आर्किटेक्चर में %c नहीं हो सकता"

#: common/flatpak-ref-utils.c:385
msgid "Branch can't be empty"
msgstr "शाखा खाली नहीं हो सकती"

#: common/flatpak-ref-utils.c:395
#, c-format
msgid "Branch can't start with %c"
msgstr "शाखा %c से प्रारंभ नहीं हो सकती"

#: common/flatpak-ref-utils.c:405
#, c-format
msgid "Branch can't contain %c"
msgstr "शाखा में %c नहीं हो सकता"

#: common/flatpak-ref-utils.c:615 common/flatpak-ref-utils.c:865
msgid "Ref too long"
msgstr "संदर्भ बहुत लंबा है"

#: common/flatpak-ref-utils.c:627
msgid "Invalid remote name"
msgstr "अमान्य रिमोट नाम"

#: common/flatpak-ref-utils.c:641
#, c-format
msgid "%s is not application or runtime"
msgstr "%s अनुप्रयोग या रनटाइम नहीं है"

#: common/flatpak-ref-utils.c:650 common/flatpak-ref-utils.c:667
#: common/flatpak-ref-utils.c:683
#, c-format
msgid "Wrong number of components in %s"
msgstr "%s में घटकों की गलत संख्या"

#: common/flatpak-ref-utils.c:656
#, c-format
msgid "Invalid name %.*s: %s"
msgstr "अमान्य नाम %.*s: %s"

#: common/flatpak-ref-utils.c:673
#, c-format
msgid "Invalid arch: %.*s: %s"
msgstr "अमान्य आर्किटेक्चर: %.*s: %s"

#: common/flatpak-ref-utils.c:816
#, c-format
msgid "Invalid name %s: %s"
msgstr "अमान्य नाम %s: %s"

#: common/flatpak-ref-utils.c:834
#, c-format
msgid "Invalid arch: %s: %s"
msgstr "अमान्य आर्किटेक्चर: %s: %s"

#: common/flatpak-ref-utils.c:853
#, c-format
msgid "Invalid branch: %s: %s"
msgstr "अमान्य शाखा: %s: %s"

#: common/flatpak-ref-utils.c:962 common/flatpak-ref-utils.c:970
#: common/flatpak-ref-utils.c:978
#, c-format
msgid "Wrong number of components in partial ref %s"
msgstr "आंशिक संदर्भ %s में घटकों की गलत संख्या"

#: common/flatpak-ref-utils.c:1298
msgid " development platform"
msgstr " विकास प्लेटफ़ॉर्म"

#: common/flatpak-ref-utils.c:1300
msgid " platform"
msgstr " प्लेटफ़ॉर्म"

#: common/flatpak-ref-utils.c:1302
msgid " application base"
msgstr " अनुप्रयोग आधार"

#: common/flatpak-ref-utils.c:1305
msgid " debug symbols"
msgstr " डिबग प्रतीक"

#: common/flatpak-ref-utils.c:1307
msgid " sourcecode"
msgstr " स्रोतकोड"

#: common/flatpak-ref-utils.c:1309
msgid " translations"
msgstr " अनुवाद"

#: common/flatpak-ref-utils.c:1311
msgid " docs"
msgstr " दस्तावेज़"

#: common/flatpak-ref-utils.c:1578
#, c-format
msgid "Invalid id %s: %s"
msgstr "अमान्य ID %s: %s"

#: common/flatpak-remote.c:1216
#, c-format
msgid "Bad remote name: %s"
msgstr "खराब रिमोट नाम: %s"

#: common/flatpak-remote.c:1220
#, fuzzy
msgid "No URL specified"
msgstr "कोई URL निर्दिष्ट नहीं"

#: common/flatpak-remote.c:1266
msgid "GPG verification must be enabled when a collection ID is set"
msgstr "संग्रह ID निर्धारित होने पर GPG सत्यापन सक्षम होना चाहिए"

#: common/flatpak-repo-utils.c:344
#, c-format
msgid "No extra data sources"
msgstr "कोई अतिरिक्त डेटा स्रोत नहीं"

#: common/flatpak-repo-utils.c:2817
#, c-format
msgid "Invalid %s: Missing group ‘%s’"
msgstr "अमान्य %s: गुम समूह ‘%s’"

#: common/flatpak-repo-utils.c:2826
#, c-format
msgid "Invalid %s: Missing key ‘%s’"
msgstr "अमान्य %s: गुम कुंजी ‘%s’"

#: common/flatpak-repo-utils.c:2876
msgid "Invalid gpg key"
msgstr "अमान्य gpg कुंजी"

#: common/flatpak-repo-utils.c:3217
#, c-format
msgid "Error copying 64x64 icon for component %s: %s\n"
msgstr "घटक %s के लिए 64x64 आइकन कॉपी करने में त्रुटि: %s\n"

#: common/flatpak-repo-utils.c:3223
#, c-format
msgid "Error copying 128x128 icon for component %s: %s\n"
msgstr "घटक %s के लिए 128x128 आइकन कॉपी करने में त्रुटि: %s\n"

#: common/flatpak-repo-utils.c:3362
#, c-format
msgid "%s is end-of-life, ignoring for appstream"
msgstr "%s जीवन का अंत है, ऐपस्ट्रीम को अनदेखा कर रहा है"

#: common/flatpak-repo-utils.c:3397
#, c-format
msgid "No appstream data for %s: %s\n"
msgstr "%s के लिए कोई ऐपस्ट्रीम डेटा नहीं: %s\n"

#: common/flatpak-repo-utils.c:3744
msgid "Invalid bundle, no ref in metadata"
msgstr "अमान्य बंडल, मेटाडेटा में कोई संदर्भ नहीं"

#: common/flatpak-repo-utils.c:3846
#, c-format
msgid "Collection ‘%s’ of bundle doesn’t match collection ‘%s’ of remote"
msgstr "बंडल का संग्रह ‘%s’ रिमोट के संग्रह ‘%s’ से मेल नहीं खाता"

#: common/flatpak-repo-utils.c:3923
msgid "Metadata in header and app are inconsistent"
msgstr "शीर्षलेख और ऐप में मेटाडेटा असंगत हैं"

#: common/flatpak-run.c:951
msgid "No systemd user session available, cgroups not available"
msgstr "कोई systemd उपयोक्ता सत्र उपलब्ध नहीं है, cgroups उपलब्ध नहीं है"

#: common/flatpak-run.c:1496
msgid "Unable to allocate instance id"
msgstr "इंस्टैंस ID आवंटित करने में असमर्थ"

#: common/flatpak-run.c:1632 common/flatpak-run.c:1641
#, c-format
msgid "Failed to open flatpak-info file: %s"
msgstr "flatpak-info फाइल खोलने में विफल: %s"

#: common/flatpak-run.c:1668
#, c-format
msgid "Failed to open bwrapinfo.json file: %s"
msgstr "bwrapinfo.json फाइल खोलने में विफल: %s"

#: common/flatpak-run.c:1689
#, c-format
msgid "Failed to write to instance id fd: %s"
msgstr "इंस्टैंस ID fd पर लिखने में विफल: %s"

#: common/flatpak-run.c:2096
msgid "Initialize seccomp failed"
msgstr "seccomp को प्रारंभ करना विफल रहा"

#: common/flatpak-run.c:2135
#, c-format
msgid "Failed to add architecture to seccomp filter: %s"
msgstr "seccomp फिल्टर में आर्किटेक्चर जोड़ने में विफल: %s"

#: common/flatpak-run.c:2143
#, c-format
msgid "Failed to add multiarch architecture to seccomp filter: %s"
msgstr "seccomp फिल्टर में बहुआर्क आर्किटेक्चर जोड़ने में विफल: %s"

#: common/flatpak-run.c:2175 common/flatpak-run.c:2192
#: common/flatpak-run.c:2214
#, c-format
msgid "Failed to block syscall %d: %s"
msgstr "syscall %d को अवरुद्ध करने में विफल: %s"

#: common/flatpak-run.c:2247
#, c-format
msgid "Failed to export bpf: %s"
msgstr "bpf निर्यात करने में विफल: %s"

#: common/flatpak-run.c:2587
#, c-format
msgid "Failed to open ‘%s’"
msgstr "‘%s’ खोलने में विफल"

#: common/flatpak-run.c:2597
#, c-format
msgid ""
"Directory forwarding needs version 4 of the document portal (have version %d)"
msgstr ""

#: common/flatpak-run.c:2915
#, c-format
msgid "ldconfig failed, exit status %d"
msgstr "ldconfig विफल, निकास स्थिति %d"

#: common/flatpak-run.c:2922
msgid "Can't open generated ld.so.cache"
msgstr "उत्पन्न ld.so.cache नहीं खोल सके"

#. Translators: The placeholder is for an app ref.
#: common/flatpak-run.c:3045
#, c-format
msgid "Running %s is not allowed by the policy set by your administrator"
msgstr "आपके प्रशासक द्वारा निर्धारित नीति के अनुसार %s चलाने की अनुमति नहीं है"

#: common/flatpak-run.c:3202
msgid ""
"\"flatpak run\" is not intended to be run as `sudo flatpak run`. Use `sudo "
"-i` or `su -l` instead and invoke \"flatpak run\" from inside the new shell."
msgstr ""
"\"flatpak run\" को `sudo flatpak run` के रूप में चलाने का इरादा नहीं है। इसके बजाय "
"`sudo -i` या `su -l` का प्रयोग करें और नए शेल के अंदर से \"flatpak run\" शुरू करें।"

#: common/flatpak-run.c:3413
#, c-format
msgid "Failed to migrate from %s: %s"
msgstr "%s से प्रवासित होने में विफल: %s"

#: common/flatpak-run.c:3434
#, c-format
msgid "Failed to migrate old app data directory %s to new name %s: %s"
msgstr "पुराने ऐप डेटा निर्देशिका %s को नए नाम %s में प्रवासित करने में विफल: %s"

#: common/flatpak-run.c:3443
#, c-format
msgid "Failed to create symlink while migrating %s: %s"
msgstr "%s प्रवासित करते समय सिम्लिंक बनाने में विफल: %s"

#: common/flatpak-run-dbus.c:46
msgid "Failed to open app info file"
msgstr "ऐप जानकारी फाइल खोलने में विफल"

#: common/flatpak-run-dbus.c:149
msgid "Unable to create sync pipe"
msgstr "समन्वयन पाइप बनाने में असमर्थ"

#: common/flatpak-run-dbus.c:185
msgid "Failed to sync with dbus proxy"
msgstr "Dbus प्रॉक्सी के साथ समन्वयित करने में विफल"

#: common/flatpak-transaction.c:2275
#, c-format
msgid "Warning: Problem looking for related refs: %s"
msgstr "चेतावनी: संबंधित संदर्भ ढूंढने में समस्या आ रही है: %s"

#: common/flatpak-transaction.c:2493
#, c-format
msgid "The application %s requires the runtime %s which was not found"
msgstr "अनुप्रयोग %s को रनटाइम %s की आवश्यकता है जो नहीं मिला"

#: common/flatpak-transaction.c:2509
#, c-format
msgid "The application %s requires the runtime %s which is not installed"
msgstr "अनुप्रयोग %s को रनटाइम %s की आवश्यकता है जो स्थापित नहीं है"

#: common/flatpak-transaction.c:2641
#, c-format
msgid "Can't uninstall %s which is needed by %s"
msgstr "%s को अस्थापित नहीं किया जा सकता जिसकी %s को आवश्यकता है"

#: common/flatpak-transaction.c:2740
#, c-format
msgid "Remote %s disabled, ignoring %s update"
msgstr "रिमोट %s अक्षम, %s अद्यतन को अनदेखा कर रहा है"

#: common/flatpak-transaction.c:2773
#, c-format
msgid "%s is already installed"
msgstr "%s पहले से ही स्थापित है"

#: common/flatpak-transaction.c:2776
#, c-format
msgid "%s is already installed from remote %s"
msgstr "%s पहले से ही रिमोट %s से स्थापित है"

#: common/flatpak-transaction.c:3120
#, c-format
msgid "Invalid .flatpakref: %s"
msgstr "अमान्य .flatpakref: %s"

#: common/flatpak-transaction.c:3161
msgid "Warning: Could not mark already installed apps as preinstalled"
msgstr ""

#: common/flatpak-transaction.c:3382
#, c-format
msgid "Error updating remote metadata for '%s': %s"
msgstr "'%s' के लिए रिमोट मेटाडेटा अद्यतन करने में त्रुटि: %s"

#: common/flatpak-transaction.c:3885
#, c-format
msgid ""
"Warning: Treating remote fetch error as non-fatal since %s is already "
"installed: %s"
msgstr ""
"Warning: Treating remote fetch error as non-fatal since %s is already "
"installed: %s"

#: common/flatpak-transaction.c:4209
#, c-format
msgid "No authenticator installed for remote '%s'"
msgstr "संदर्भ '%s' के लिए कोई प्रमाणक स्थापित नहीं"

#: common/flatpak-transaction.c:4313 common/flatpak-transaction.c:4320
#, c-format
msgid "Failed to get tokens for ref: %s"
msgstr "संदर्भ के लिए टोकन प्राप्त करने में विफल: %s"

#: common/flatpak-transaction.c:4315 common/flatpak-transaction.c:4322
msgid "Failed to get tokens for ref"
msgstr "रेफरी के लिए टोकन प्राप्त करने में विफल"

#: common/flatpak-transaction.c:4580
#, c-format
msgid "Ref %s from %s matches more than one transaction operation"
msgstr "%2$s से संदर्भ %1$s एक से अधिक लेन-देन अभियान से मेल खाता है"

#: common/flatpak-transaction.c:4581 common/flatpak-transaction.c:4591
msgid "any remote"
msgstr "कोई रिमोट"

#: common/flatpak-transaction.c:4590
#, c-format
msgid "No transaction operation found for ref %s from %s"
msgstr "%2$s से रेफरी %1$s के लिए कोई लेनदेन संचालन नहीं मिला"

#: common/flatpak-transaction.c:4713
#, c-format
msgid "Flatpakrepo URL %s not file, HTTP or HTTPS"
msgstr "Flatpakrepo URL %s फाइल नहीं, HTTP या HTTPS"

#: common/flatpak-transaction.c:4719
#, c-format
msgid "Can't load dependent file %s: "
msgstr "आश्रित फाइल %s लोड नहीं किया जा सकता: "

#: common/flatpak-transaction.c:4727
#, c-format
msgid "Invalid .flatpakrepo: %s"
msgstr "अमान्य .flatpakrepo: %s"

#: common/flatpak-transaction.c:5454
msgid "Transaction already executed"
msgstr "लेनदेन पहले ही निष्पादित हो चुका"

#: common/flatpak-transaction.c:5469
msgid ""
"Refusing to operate on a user installation as root! This can lead to "
"incorrect file ownership and permission errors."
msgstr ""
"उपयोक्ता स्थापना को रूट के रूप में संचालित करने से इंकार करना! इससे गलत फाइल स्वामित्व और "
"अनुमति संबंधी त्रुटियां हो सकती हैं।"

#: common/flatpak-transaction.c:5567 common/flatpak-transaction.c:5580
msgid "Aborted by user"
msgstr "उपयोक्ता द्वारा निरस्त"

#: common/flatpak-transaction.c:5605
#, c-format
msgid "Skipping %s due to previous error"
msgstr "पिछली त्रुटि के कारण %s को छोड़ा जा रहा है"

#: common/flatpak-transaction.c:5659
#, c-format
msgid "Aborted due to failure (%s)"
msgstr "विफलता के कारण निरस्त (%s)"

#: common/flatpak-uri.c:118
#, no-c-format
msgid "Invalid %-encoding in URI"
msgstr "URI में अमान्य %-एन्कोडिंग"

#: common/flatpak-uri.c:135
msgid "Illegal character in URI"
msgstr "URI में अमान्य वर्ण"

#: common/flatpak-uri.c:169
msgid "Non-UTF-8 characters in URI"
msgstr "URI में गैर-UTF-8 वर्ण"

#: common/flatpak-uri.c:275
#, c-format
msgid "Invalid IPv6 address ‘%.*s’ in URI"
msgstr "URI में अमान्य IPv6 पता ‘%.*s’"

#: common/flatpak-uri.c:330
#, c-format
msgid "Illegal encoded IP address ‘%.*s’ in URI"
msgstr "URI में अमान्य एन्कोडेड IP पता ‘%.*s’"

#: common/flatpak-uri.c:342
#, c-format
msgid "Illegal internationalized hostname ‘%.*s’ in URI"
msgstr "URI में अमान्य अंतर्राष्ट्रीयकृत होस्टनाम ‘%.*s’"

#: common/flatpak-uri.c:374 common/flatpak-uri.c:386
#, c-format
msgid "Could not parse port ‘%.*s’ in URI"
msgstr "URI में पोर्ट ‘%.*s’ का विश्लेषण नहीं किया जा सका"

#: common/flatpak-uri.c:393
#, c-format
msgid "Port ‘%.*s’ in URI is out of range"
msgstr "URI में पोर्ट ‘%.*s’ सीमा से बाहर है"

#: common/flatpak-uri.c:910
msgid "URI is not absolute, and no base URI was provided"
msgstr "URI पूर्ण नहीं है, और कोई आधार URI प्रदान नहीं किया गया"

#: common/flatpak-usb.c:83
#, c-format
msgid "USB device query 'all' must not have data"
msgstr ""

#: common/flatpak-usb.c:102
#, c-format
msgid "USB query rule 'cls' must be in the form CLASS:SUBCLASS or CLASS:*"
msgstr ""

#: common/flatpak-usb.c:111
#, fuzzy, c-format
msgid "Invalid USB class"
msgstr "अमान्य ID %s: %s"

#: common/flatpak-usb.c:125
#, c-format
msgid "Invalid USB subclass"
msgstr ""

#: common/flatpak-usb.c:141 common/flatpak-usb.c:148
#, c-format
msgid "USB query rule 'dev' must have a valid 4-digit hexadecimal product id"
msgstr ""

#: common/flatpak-usb.c:164 common/flatpak-usb.c:171
#, c-format
msgid "USB query rule 'vnd' must have a valid 4-digit hexadecimal vendor id"
msgstr ""

#: common/flatpak-usb.c:205
#, c-format
msgid "USB device queries must be in the form TYPE:DATA"
msgstr ""

#: common/flatpak-usb.c:225
#, c-format
msgid "Unknown USB query rule %s"
msgstr ""

#: common/flatpak-usb.c:248
#, c-format
msgid "Empty USB query"
msgstr ""

#: common/flatpak-usb.c:274
#, c-format
msgid "Multiple USB query rules of the same type is not supported"
msgstr ""

#: common/flatpak-usb.c:283
#, c-format
msgid "'all' must not contain extra query rules"
msgstr ""

#: common/flatpak-usb.c:291
#, c-format
msgid "USB queries with 'dev' must also specify vendors"
msgstr ""

#: common/flatpak-utils.c:712
msgid "Glob can't match apps"
msgstr "ग्लोब ऐप्स का मिलान नहीं कर सका"

#: common/flatpak-utils.c:737
msgid "Empty glob"
msgstr "खाली ग्लोब"

#: common/flatpak-utils.c:756
msgid "Too many segments in glob"
msgstr "ग्लोब में बहुत सारे खंड"

#: common/flatpak-utils.c:777
#, c-format
msgid "Invalid glob character '%c'"
msgstr "अमान्य ग्लोब वर्ण '%c'"

#: common/flatpak-utils.c:831
#, c-format
msgid "Missing glob on line %d"
msgstr "पंक्ति %d पर ग्लोब गुम है"

#: common/flatpak-utils.c:835
#, c-format
msgid "Trailing text on line %d"
msgstr "पंक्ति %d पर अनुगामी पाठ"

#: common/flatpak-utils.c:839
#, c-format
msgid "on line %d"
msgstr "पंक्ति %d पर"

#: common/flatpak-utils.c:861
#, c-format
msgid "Unexpected word '%s' on line %d"
msgstr "लाइन %2$d पर अप्रत्याशित शब्द '%1$s'"

#: common/flatpak-utils.c:2118
#, c-format
msgid "Invalid require-flatpak argument %s"
msgstr "अमान्य require-flatpak तर्क %s"

#: common/flatpak-utils.c:2128 common/flatpak-utils.c:2147
#, c-format
msgid "%s needs a later flatpak version (%s)"
msgstr "%s को बाद के flatpak संस्करण की आवश्यकता है (%s)"

#: oci-authenticator/flatpak-oci-authenticator.c:291
msgid "Not a oci remote, missing summary.xa.oci-repository"
msgstr "OCI रिमोट नहीं है, summary.xa.oci-repository गायब है"

#: oci-authenticator/flatpak-oci-authenticator.c:477
msgid "Not a OCI remote"
msgstr "OCI रिमोट नहीं"

#: oci-authenticator/flatpak-oci-authenticator.c:488
msgid "Invalid token"
msgstr "अमान्य टोकन"

#: portal/flatpak-portal.c:2292
#, c-format
msgid "No portal support found"
msgstr "कोई पोर्टल समर्थन नहीं मिला"

#: portal/flatpak-portal.c:2298
msgid "Deny"
msgstr "अस्वीकारें"

#: portal/flatpak-portal.c:2300
msgid "Update"
msgstr "अद्यतन"

#: portal/flatpak-portal.c:2305
#, c-format
msgid "Update %s?"
msgstr "%s अद्यतन करें?"

#: portal/flatpak-portal.c:2317
msgid "The application wants to update itself."
msgstr "अनुप्रयोग स्वयं को अद्यतन करना चाहता है।"

#: portal/flatpak-portal.c:2318
msgid "Update access can be changed any time from the privacy settings."
msgstr "अद्यतन पहुंच को गोपनीयता सेटिंग्स से किसी भी समय बदला जा सकता है।"

#: portal/flatpak-portal.c:2343
#, c-format
msgid "Application update not allowed"
msgstr "अनुप्रयोग अद्यतन की अनुमति नहीं है"

#: portal/flatpak-portal.c:2501
#, c-format
msgid "Self update not supported, new version requires new permissions"
msgstr "स्वयं अद्यतन समर्थित नहीं है, नए संस्करण के लिए नई अनुमतियों की आवश्यकता है"

#: portal/flatpak-portal.c:2684 portal/flatpak-portal.c:2702
#, c-format
msgid "Update ended unexpectedly"
msgstr "अद्यतन अप्रत्याशित रूप से समाप्त हो गया"

#. SECURITY:
#. - Normal users need admin authentication to install software
#. system-wide.
#. - Note that we install polkit rules that allow local users
#. in the wheel group to install without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:23
msgid "Install signed application"
msgstr "हस्ताक्षरित अनुप्रयोग स्थापित करें"

#: system-helper/org.freedesktop.Flatpak.policy.in:24
#: system-helper/org.freedesktop.Flatpak.policy.in:42
msgid "Authentication is required to install software"
msgstr "सॉफ्टवेयर स्थापित करने के लिए प्रमाणीकरण आवश्यक है"

#. SECURITY:
#. - Normal users need admin authentication to install software
#. system-wide.
#. - Note that we install polkit rules that allow local users
#. in the wheel group to install without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:41
msgid "Install signed runtime"
msgstr "हस्ताक्षरित रनटाइम स्थापित करें"

#. SECURITY:
#. - Normal users do not require admin authentication to update an
#. app as the commit will be signed, and the action is required
#. to update the system when unattended.
#. - Changing this to anything other than 'yes' will break unattended
#. updates.
#: system-helper/org.freedesktop.Flatpak.policy.in:60
msgid "Update signed application"
msgstr "हस्ताक्षरित आवेदन अद्यतन करें"

#: system-helper/org.freedesktop.Flatpak.policy.in:61
#: system-helper/org.freedesktop.Flatpak.policy.in:80
msgid "Authentication is required to update software"
msgstr "सॉफ्टवेयर अद्यतन करने के लिए प्रमाणीकरण आवश्यक है"

#. SECURITY:
#. - Normal users do not require admin authentication to update a
#. runtime as the commit will be signed, and the action is required
#. to update the system when unattended.
#. - Changing this to anything other than 'yes' will break unattended
#. updates.
#: system-helper/org.freedesktop.Flatpak.policy.in:79
msgid "Update signed runtime"
msgstr "हस्ताक्षरित रनटाइम अद्यतन करें"

#. SECURITY:
#. - Normal users do not need authentication to update metadata
#. from signed repositories.
#: system-helper/org.freedesktop.Flatpak.policy.in:94
msgid "Update remote metadata"
msgstr "रिमोट मेटाडेटा अद्यतन करें"

#: system-helper/org.freedesktop.Flatpak.policy.in:95
msgid "Authentication is required to update remote info"
msgstr "रिमोट जानकारी को अद्यतन करने के लिए प्रमाणीकरण आवश्यक है"

#. SECURITY:
#. - Normal users do not need authentication to modify the
#. OSTree repository
#. - Note that we install polkit rules that allow local users
#. in the wheel group to modify repos without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:111
msgid "Update system repository"
msgstr "सिस्टम रिपोजिटरी को अद्यतन करें"

#: system-helper/org.freedesktop.Flatpak.policy.in:112
msgid "Authentication is required to modify a system repository"
msgstr "सिस्टम रिपॉजिटरी को संशोधित करने के लिए प्रमाणीकरण आवश्यक है"

#. SECURITY:
#. - Normal users need admin authentication to install software
#. system-wide.
#: system-helper/org.freedesktop.Flatpak.policy.in:126
msgid "Install bundle"
msgstr "बंडल स्थापित करें"

#: system-helper/org.freedesktop.Flatpak.policy.in:127
msgid "Authentication is required to install software from $(path)"
msgstr "$(पथ) से सॉफ्टवेयर स्थापित करने के लिए प्रमाणीकरण आवश्यक है"

#. SECURITY:
#. - Normal users need admin authentication to uninstall software
#. system-wide.
#. - Note that we install polkit rules that allow local users
#. in the wheel group to uninstall without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:144
msgid "Uninstall runtime"
msgstr "रनटाइम अस्थापित करें"

#: system-helper/org.freedesktop.Flatpak.policy.in:145
msgid "Authentication is required to uninstall software"
msgstr "सॉफ्टवेयर अस्थापित करने के लिए प्रमाणीकरण आवश्यक है"

#. SECURITY:
#. - Normal users need admin authentication to uninstall software
#. system-wide.
#. - Note that we install polkit rules that allow local users
#. in the wheel group to uninstall without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:161
msgid "Uninstall app"
msgstr "ऐप अस्थापित करें"

#: system-helper/org.freedesktop.Flatpak.policy.in:162
msgid "Authentication is required to uninstall $(ref)"
msgstr "$(ref) को अस्थापित करने के लिए प्रमाणीकरण आवश्यक है"

#. SECURITY:
#. - Normal users need admin authentication to configure system-wide
#. software repositories.
#: system-helper/org.freedesktop.Flatpak.policy.in:177
msgid "Configure Remote"
msgstr "रिमोट विन्यस्त करें"

#: system-helper/org.freedesktop.Flatpak.policy.in:178
msgid "Authentication is required to configure software repositories"
msgstr "सॉफ्टवेयर रिपॉजिटरी को विन्यस्त करने के लिए प्रमाणीकरण आवश्यक है"

#. SECURITY:
#. - Normal users need admin authentication to configure the system-wide
#. Flatpak installation.
#: system-helper/org.freedesktop.Flatpak.policy.in:192
msgid "Configure"
msgstr "विन्यस्त करें"

#: system-helper/org.freedesktop.Flatpak.policy.in:193
msgid "Authentication is required to configure software installation"
msgstr "सॉफ्टवेयर स्थापना को विन्यस्त करने के लिए प्रमाणीकरण आवश्यक है"

#. SECURITY:
#. - Normal users do not require admin authentication to update
#. appstream data as it will be signed, and the action is required
#. to update the system when unattended.
#. - Changing this to anything other than 'yes' will break unattended
#. updates.
#: system-helper/org.freedesktop.Flatpak.policy.in:210
msgid "Update appstream"
msgstr "ऐपस्ट्रीम अद्यतन करें"

#: system-helper/org.freedesktop.Flatpak.policy.in:211
msgid "Authentication is required to update information about software"
msgstr "सॉफ्टवेयर के बारे में जानकारी अद्यतन करने के लिए प्रमाणीकरण आवश्यक है"

#. SECURITY:
#. - Normal users do not require admin authentication to update
#. metadata as it will be signed, and the action is required
#. to update the system when unattended.
#. - Changing this to anything other than 'yes' will break unattended
#. updates.
#: system-helper/org.freedesktop.Flatpak.policy.in:228
msgid "Update metadata"
msgstr "मेटाडेटा अद्यतन करें"

#: system-helper/org.freedesktop.Flatpak.policy.in:229
msgid "Authentication is required to update metadata"
msgstr "मेटाडेटा को अद्यतन करने के लिए प्रमाणीकरण आवश्यक है"

#. SECURITY:
#. - Authorisation to actually install software is controlled by
#. org.freedesktop.Flatpak.app-install.
#. - This action is checked after app-install, as it can only be done
#. once the app’s data (including its content rating) has been
#. downloaded.
#. - This action is checked to see if the installation should be allowed
#. based on whether the app being installed has content which doesn’t
#. comply with the user’s parental controls policy (the content is
#. ‘too extreme’).
#. - It is checked only if an app has too extreme content for the user
#. who is trying to install it (in which case, the app is ‘unsafe’).
#. - Typically, normal users will need admin permission to install apps
#. with extreme content; admins will be able to install it without
#. additional checks.
#. - In order to configure the policy so that admins can install safe and
#. unsafe software anywhere without authorisation, and non-admins can
#. install safe software in their user or system dirs without
#. authorisation, but need authorisation to install unsafe software
#. anywhere:
#. * Unconditionally return `yes` from `app-install`.
#. * Return `auth_admin` from `override-parental-controls` for users
#. not in `@privileged_group@`, and `yes` for users in it.
#. * Set the malcontent `is-{user,system}-installation-allowed`
#. properties of all non-admins’ parental controls policies to true.
#. - In order to configure the policy so that admins can install safe and
#. unsafe software anywhere without authorisation, and non-admins can
#. install safe software in their user dir without authorisation, but
#. need authorisation to install safe software in the system dir or to
#. install unsafe software anywhere:
#. * Unconditionally return `yes` from `app-install`.
#. * Return `auth_admin` from `override-parental-controls` for users
#. not in `@privileged_group@`, and `yes` for users in it.
#. * Set the malcontent `is-user-installation-allowed` property of all
#. non-admins’ parental controls policies to true.
#. * Set the malcontent `is-system-installation-allowed` property of
#. all non-admins’ parental controls policies to false.
#. - In order to configure the policy so that all users (including
#. admins) can install safe software anywhere without authorisation,
#. but need authorisation to install unsafe software anywhere (i.e.
#. applying parental controls to admins too):
#. * Unconditionally return `yes` from `app-install`.
#. * Unconditionally return `auth_admin` from `override-parental-controls`.
#. * Set the malcontent `is-user-installation-allowed` property of all
#. users’ parental controls policies to true.
#. * Set the malcontent `is-system-installation-allowed` property of
#. all users’ parental controls policies to true.
#: system-helper/org.freedesktop.Flatpak.policy.in:287
#, fuzzy
msgid "Override parental controls for installs"
msgstr "अभिभावकीय नियंत्रण को अध्यारोहण करें"

#: system-helper/org.freedesktop.Flatpak.policy.in:288
msgid ""
"Authentication is required to install software which is restricted by your "
"parental controls policy"
msgstr ""
"सॉफ्टवेयर स्थापित करने के लिए प्रमाणीकरण आवश्यक है जो आपकी अभिभावकीय नियंत्रण नीति "
"द्वारा प्रतिबंधित है"

#. SECURITY:
#. - This is like org.freedesktop.Flatpak.override-parental-controls, but
#. it’s queried for app updates, whereas the former is queried for app
#. installs.
#. - As with the above action, this one is only queried if
#. org.freedesktop.Flatpak.app-update has allowed the app update, and
#. only if the app being updated has too extreme content for the user
#. who is trying to update it.
#. - The default policy for this is to *allow* updates to ‘too extreme’
#. apps by default, on the basis that having an out-of-date (i.e.
#. insecure or unsupported) app is a worse outcome than automatically
#. installing an update which has radically different content from the
#. version of the app which the parent originally vetted and installed.
#: system-helper/org.freedesktop.Flatpak.policy.in:313
#, fuzzy
msgid "Override parental controls for updates"
msgstr "अभिभावकीय नियंत्रण को अध्यारोहण करें"

#: system-helper/org.freedesktop.Flatpak.policy.in:314
#, fuzzy
msgid ""
"Authentication is required to update software which is restricted by your "
"parental controls policy"
msgstr ""
"सॉफ्टवेयर स्थापित करने के लिए प्रमाणीकरण आवश्यक है जो आपकी अभिभावकीय नियंत्रण नीति "
"द्वारा प्रतिबंधित है"

#~ msgid "Installed:"
#~ msgstr "स्थापित:"

#~ msgid "Download:"
#~ msgstr "डाउनलोड:"

#, c-format
#~ msgid "No gpg key found with ID %s (homedir: %s)"
#~ msgstr "ID %s के साथ कोई gpg कुंजी नहीं मिली (गृह-निर्देशिका: %s)"

#, c-format
#~ msgid "Unable to lookup key ID %s: %d"
#~ msgstr "कुंजी ID %s देखने में असमर्थ: %d"

#, c-format
#~ msgid "Error signing commit: %d"
#~ msgstr "कमिट पर हस्ताक्षर करने में त्रुटि: %d"

#, c-format
#~ msgid ""
#~ "Found similar ref(s) for ‘%s’ in remote ‘%s’ (%s).\n"
#~ "Use this remote?"
#~ msgstr ""
#~ "रिमोट '%2$s' (%3$s) में '%1$s' के लिए समान संदर्भ मिला।\n"
#~ "इस रिमोट का प्रयोग करें?"

===== ./po/sl.po =====
# Slovenian translation for flatpak.
# Copyright (C) 2022 flatpak's COPYRIGHT HOLDER
# This file is distributed under the same license as the flatpak package.
#
# Martin Srebotnjak <miles@filmsi.net>, 2022-2026.
#
msgid ""
msgstr ""
"Project-Id-Version: flatpak main\n"
"Report-Msgid-Bugs-To: https://github.com/flatpak/flatpak/issues\n"
"POT-Creation-Date: 2026-05-27 16:39+0200\n"
"PO-Revision-Date: 2026-01-17 00:18+0100\n"
"Last-Translator: Martin Srebotnjak <miles@filmsi.net>\n"
"Language-Team: Slovenian GNOME Translation Team <gnome-si@googlegroups.com>\n"
"Language: sl\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=4; plural=(n%100==1 ? 1 : n%100==2 ? 2 : n%100==3 || "
"n%100==4 ? 3 : 0) ;\n"
"X-Generator: Poedit 2.2.1\n"

#: app/flatpak-builtins-build-bundle.c:59
msgid "Export runtime instead of app"
msgstr "Izvozi izvajalno datoteko namesto aplikacije"

#: app/flatpak-builtins-build-bundle.c:60
msgid "Arch to bundle for"
msgstr "Arhitektura za izdelavo svežnja"

#: app/flatpak-builtins-build-bundle.c:60
#: app/flatpak-builtins-build-export.c:62 app/flatpak-builtins-build-init.c:53
#: app/flatpak-builtins-build-sign.c:42 app/flatpak-builtins-create-usb.c:46
#: app/flatpak-builtins-info.c:55 app/flatpak-builtins-install.c:67
#: app/flatpak-builtins-list.c:50 app/flatpak-builtins-make-current.c:38
#: app/flatpak-builtins-remote-info.c:54 app/flatpak-builtins-remote-ls.c:56
#: app/flatpak-builtins-run.c:158 app/flatpak-builtins-search.c:37
#: app/flatpak-builtins-uninstall.c:54 app/flatpak-builtins-update.c:56
msgid "ARCH"
msgstr "ARH"

#: app/flatpak-builtins-build-bundle.c:61
msgid "URL for repo"
msgstr "URL za skladišče"

#: app/flatpak-builtins-build-bundle.c:61
#: app/flatpak-builtins-build-bundle.c:62
#: app/flatpak-builtins-build-update-repo.c:68
#: app/flatpak-builtins-build-update-repo.c:72
#: app/flatpak-builtins-build-update-repo.c:73
#: app/flatpak-builtins-history.c:69 app/flatpak-builtins-remote-add.c:80
#: app/flatpak-builtins-remote-add.c:81 app/flatpak-builtins-remote-add.c:85
#: app/flatpak-builtins-remote-list.c:53
#: app/flatpak-builtins-remote-modify.c:70
#: app/flatpak-builtins-remote-modify.c:85
#: app/flatpak-builtins-remote-modify.c:86
#: app/flatpak-builtins-remote-modify.c:90
msgid "URL"
msgstr "URL"

#: app/flatpak-builtins-build-bundle.c:62
msgid "URL for runtime flatpakrepo file"
msgstr "URL za izvajalno datoteko flatpakrepo"

#: app/flatpak-builtins-build-bundle.c:63
msgid "Add GPG key from FILE (- for stdin)"
msgstr "Dodaj ključ GPG iz DATOTEKE (- za stdin)"

#: app/flatpak-builtins-build-bundle.c:63 app/flatpak-builtins-build.c:54
#: app/flatpak-builtins-build-export.c:67
#: app/flatpak-builtins-build-update-repo.c:83
#: app/flatpak-builtins-install.c:81 app/flatpak-builtins-remote-add.c:84
#: app/flatpak-builtins-remote-add.c:86 app/flatpak-builtins-remote-modify.c:89
#: app/flatpak-builtins-remote-modify.c:92
msgid "FILE"
msgstr "DATOTEKA"

#: app/flatpak-builtins-build-bundle.c:64
msgid "GPG Key ID to sign the OCI image with"
msgstr "ID ključa GPG za podpis slike OCI"

#: app/flatpak-builtins-build-bundle.c:64
#: app/flatpak-builtins-build-commit-from.c:68
#: app/flatpak-builtins-build-export.c:68
#: app/flatpak-builtins-build-import-bundle.c:49
#: app/flatpak-builtins-build-sign.c:44
#: app/flatpak-builtins-build-update-repo.c:84
msgid "KEY-ID"
msgstr "ID-KLJUČA"

#: app/flatpak-builtins-build-bundle.c:65
#: app/flatpak-builtins-build-commit-from.c:69
#: app/flatpak-builtins-build-export.c:71
#: app/flatpak-builtins-build-import-bundle.c:50
#: app/flatpak-builtins-build-sign.c:45
#: app/flatpak-builtins-build-update-repo.c:85
msgid "GPG Homedir to use when looking for keyrings"
msgstr "Domača mapa GPG za uporabo, ko iščete verige ključev"

#: app/flatpak-builtins-build-bundle.c:65
#: app/flatpak-builtins-build-commit-from.c:69
#: app/flatpak-builtins-build-export.c:71
#: app/flatpak-builtins-build-import-bundle.c:50
#: app/flatpak-builtins-build-sign.c:45
#: app/flatpak-builtins-build-update-repo.c:85
msgid "HOMEDIR"
msgstr "DOMAČA-MAPA"

#: app/flatpak-builtins-build-bundle.c:66
msgid "OSTree commit to create a delta bundle from"
msgstr "Uveljavitev OSTree, iz katere bo ustvarjen delta sveženj"

#: app/flatpak-builtins-build-bundle.c:66 app/flatpak-builtins-remote-info.c:55
#: app/flatpak-builtins-update.c:57
msgid "COMMIT"
msgstr "UVELJAVI"

#: app/flatpak-builtins-build-bundle.c:67
msgid "Export oci image instead of flatpak bundle"
msgstr "Izvozi sliko OCI namesto svežnja flatpak"

#: app/flatpak-builtins-build-bundle.c:70
msgid "How to compress OCI image layers (default: gzip)"
msgstr "Kako stisniti slikovne plasti OCI (privzeto: gzip)"

#: app/flatpak-builtins-build-bundle.c:634
msgid ""
"LOCATION FILENAME NAME [BRANCH] - Create a single file bundle from a local "
"repository"
msgstr ""
"MEST IME-DATOTEKE IME [VEJA] - Ustvarite sveženj ene same datoteke iz "
"krajevnega skladišča"

#: app/flatpak-builtins-build-bundle.c:641
msgid "LOCATION, FILENAME and NAME must be specified"
msgstr "Navesti morate MESTO, IME-DATOTEKE in IME"

#: app/flatpak-builtins-build-bundle.c:644
#: app/flatpak-builtins-build-export.c:844
#: app/flatpak-builtins-build-import-bundle.c:136
#: app/flatpak-builtins-build-init.c:217 app/flatpak-builtins-build-sign.c:76
#: app/flatpak-builtins-document-export.c:112
#: app/flatpak-builtins-document-info.c:75
#: app/flatpak-builtins-document-list.c:191
#: app/flatpak-builtins-document-unexport.c:70
#: app/flatpak-builtins-history.c:482 app/flatpak-builtins-info.c:130
#: app/flatpak-builtins-install.c:181 app/flatpak-builtins-install.c:234
#: app/flatpak-builtins-install.c:298 app/flatpak-builtins-list.c:419
#: app/flatpak-builtins-make-current.c:72 app/flatpak-builtins-override.c:73
#: app/flatpak-builtins-permission-list.c:162
#: app/flatpak-builtins-permission-remove.c:132
#: app/flatpak-builtins-remote-add.c:323
#: app/flatpak-builtins-remote-delete.c:68
#: app/flatpak-builtins-remote-list.c:241 app/flatpak-builtins-remote-ls.c:407
msgid "Too many arguments"
msgstr "Preveč argumentov"

#: app/flatpak-builtins-build-bundle.c:659
#: app/flatpak-builtins-build-commit-from.c:338
#: app/flatpak-builtins-build-commit-from.c:351
#: app/flatpak-builtins-build-import-bundle.c:145
#, c-format
msgid "'%s' is not a valid repository"
msgstr "»%s« ni veljavno skladišče"

#: app/flatpak-builtins-build-bundle.c:663
#, c-format
msgid "'%s' is not a valid repository: "
msgstr "»%s« ni veljavno skladišče: "

#: app/flatpak-builtins-build-bundle.c:674 app/flatpak-builtins-build-sign.c:88
#: common/flatpak-dir.c:14293
#, c-format
msgid "'%s' is not a valid name: %s"
msgstr "»%s« ni veljavno ime: %s"

#: app/flatpak-builtins-build-bundle.c:677
#: app/flatpak-builtins-build-export.c:865 app/flatpak-builtins-build-sign.c:91
#: common/flatpak-dir.c:14299
#, c-format
msgid "'%s' is not a valid branch name: %s"
msgstr "»%s« ni veljavno ime veje: %s"

#: app/flatpak-builtins-build-bundle.c:691
#: app/flatpak-builtins-build-import-bundle.c:149
#: app/flatpak-builtins-build-init.c:281
#, c-format
msgid "'%s' is not a valid filename"
msgstr "»%s« ni veljavno ime datoteke"

#: app/flatpak-builtins-build-bundle.c:706
msgid "--oci-layer-compress value must be gzip or zstd"
msgstr "Vrednost --oci-layer-compress mora biti gzip ali zstd"

#: app/flatpak-builtins-build.c:49
msgid "Use Platform runtime rather than Sdk"
msgstr "Uporabite izvajalnik platforme namesto SDK"

#: app/flatpak-builtins-build.c:50
msgid "Make destination readonly"
msgstr "Naj bo cilj samo za branje"

#: app/flatpak-builtins-build.c:51
msgid "Add bind mount"
msgstr "Dodaj priklop za navezavo"

#: app/flatpak-builtins-build.c:51
msgid "DEST=SRC"
msgstr "CILJ=VIR"

#: app/flatpak-builtins-build.c:52
msgid "Start build in this directory"
msgstr "Začni graditi v tej mapi"

#: app/flatpak-builtins-build.c:52 app/flatpak-builtins-build.c:53
#: app/flatpak-builtins-build-init.c:64 app/flatpak-builtins-run.c:160
msgid "DIR"
msgstr "MAPA"

#: app/flatpak-builtins-build.c:53
msgid "Where to look for custom sdk dir (defaults to 'usr')"
msgstr "Kje poiskati sdk dir po meri (privzeto na »usr«)"

#: app/flatpak-builtins-build.c:54 app/flatpak-builtins-build-export.c:67
msgid "Use alternative file for the metadata"
msgstr "Uporabi alternativno datoteko za metapodatke"

#: app/flatpak-builtins-build.c:55 app/flatpak-builtins-run.c:177
msgid "Kill processes when the parent process dies"
msgstr "Ubij procese, ko nadrejeni proces umre"

#: app/flatpak-builtins-build.c:56
msgid "Export application homedir directory to build"
msgstr "Izvozi mapo homedir programa za izgradnjo"

#: app/flatpak-builtins-build.c:57 app/flatpak-builtins-run.c:165
msgid "Log session bus calls"
msgstr "Beleži klice vodila seje"

#: app/flatpak-builtins-build.c:58 app/flatpak-builtins-run.c:166
msgid "Log system bus calls"
msgstr "Beleži klice sistemskega vodila"

#: app/flatpak-builtins-build.c:262
msgid "DIRECTORY [COMMAND [ARGUMENT…]] - Build in directory"
msgstr "MAPA [UKAZ [ARGUMENT...]] - Gradi v mapi"

#: app/flatpak-builtins-build.c:285 app/flatpak-builtins-build-finish.c:656
msgid "DIRECTORY must be specified"
msgstr "Navesti je treba MAPO"

#: app/flatpak-builtins-build.c:296 app/flatpak-builtins-build-export.c:887
#, c-format
msgid "Build directory %s not initialized, use flatpak build-init"
msgstr "Mapa za gradnjo %s ni inicializirana, uporabite flatpak build-init"

#: app/flatpak-builtins-build.c:315
msgid "metadata invalid, not application or runtime"
msgstr "metapodatki neveljavni, niti aplikacija niti izvajalna datoteka"

#: app/flatpak-builtins-build.c:446
#, c-format
msgid "No extension point matching %s in %s"
msgstr "Ni razširitvene točke, ki bi se ujemala z %s (v %s)"

#: app/flatpak-builtins-build.c:635
#, c-format
msgid "Missing '=' in bind mount option '%s'"
msgstr "Manjka »=« v možnosti bind mount »%s«"

#: app/flatpak-builtins-build.c:679 common/flatpak-run.c:3961
#, c-format
msgid "Unable to start app"
msgstr "Aplikacije ni mogoče zagnati"

#: app/flatpak-builtins-build-commit-from.c:58
msgid "Source repo dir"
msgstr "Mapa skladišča izvorne kode"

#: app/flatpak-builtins-build-commit-from.c:58
msgid "SRC-REPO"
msgstr "SRC-REPO"

#: app/flatpak-builtins-build-commit-from.c:59
msgid "Source repo ref"
msgstr "Ref skladišča izvorne kode"

#: app/flatpak-builtins-build-commit-from.c:59
msgid "SRC-REF"
msgstr "SRC-REF"

#: app/flatpak-builtins-build-commit-from.c:64
#: app/flatpak-builtins-build-export.c:60
msgid "One line subject"
msgstr "Zadeva v eni vrstici"

#: app/flatpak-builtins-build-commit-from.c:64
#: app/flatpak-builtins-build-export.c:60
msgid "SUBJECT"
msgstr "ZADEVA"

#: app/flatpak-builtins-build-commit-from.c:65
#: app/flatpak-builtins-build-export.c:61
msgid "Full description"
msgstr "Celoten opis"

#: app/flatpak-builtins-build-commit-from.c:65
#: app/flatpak-builtins-build-export.c:61
msgid "BODY"
msgstr "TELO"

#: app/flatpak-builtins-build-commit-from.c:66
#: app/flatpak-builtins-build-export.c:64
#: app/flatpak-builtins-build-import-bundle.c:51
msgid "Update the appstream branch"
msgstr "Posodobi vejo appstream"

#: app/flatpak-builtins-build-commit-from.c:67
#: app/flatpak-builtins-build-export.c:65
#: app/flatpak-builtins-build-import-bundle.c:52
#: app/flatpak-builtins-build-update-repo.c:87
msgid "Don't update the summary"
msgstr "Ne posodabljaj povzetka"

#: app/flatpak-builtins-build-commit-from.c:68
#: app/flatpak-builtins-build-export.c:68
#: app/flatpak-builtins-build-import-bundle.c:49
#: app/flatpak-builtins-build-sign.c:44
msgid "GPG Key ID to sign the commit with"
msgstr "ID ključa GPG za podpis uveljavitve"

#: app/flatpak-builtins-build-commit-from.c:70
#: app/flatpak-builtins-build-export.c:73
msgid "Mark build as end-of-life"
msgstr "Označi gradnjo za zaključno v življenjski dobi"

#: app/flatpak-builtins-build-commit-from.c:70
#: app/flatpak-builtins-build-export.c:73
msgid "REASON"
msgstr "RAZLOG"

#: app/flatpak-builtins-build-commit-from.c:71
msgid ""
"Mark refs matching the OLDID prefix as end-of-life, to be replaced with the "
"given NEWID"
msgstr ""
"Označite reference, ki ustrezajo predponi OLDID, kot je konec življenjske "
"dobe, ki jo je treba nadomestiti z NEWID"

#: app/flatpak-builtins-build-commit-from.c:71
msgid "OLDID=NEWID"
msgstr "STARID=NOVID"

#: app/flatpak-builtins-build-commit-from.c:72
#: app/flatpak-builtins-build-export.c:75
msgid "Set type of token needed to install this commit"
msgstr "Nastavitev vrste žetona, ki je potrebna za namestitev te objave"

#: app/flatpak-builtins-build-commit-from.c:72
#: app/flatpak-builtins-build-export.c:75
msgid "VAL"
msgstr "VRED"

#: app/flatpak-builtins-build-commit-from.c:73
msgid "Override the timestamp of the commit (NOW for current time)"
msgstr "Preglasi časovni žig objave (NOW za trenutni čas)"

#: app/flatpak-builtins-build-commit-from.c:73
#: app/flatpak-builtins-build-export.c:76
msgid "TIMESTAMP"
msgstr "ČASOVNIŽIG"

#: app/flatpak-builtins-build-commit-from.c:75
#: app/flatpak-builtins-build-export.c:80
#: app/flatpak-builtins-build-import-bundle.c:53
#: app/flatpak-builtins-build-update-repo.c:97
msgid "Don't generate a summary index"
msgstr "Ne ustvari indeksa povzetka"

#: app/flatpak-builtins-build-commit-from.c:278
msgid "DST-REPO [DST-REF…] - Make a new commit from existing commits"
msgstr "DST-REPO [DST-REF...] - Naredite novo objavo iz obstoječih objav"

#: app/flatpak-builtins-build-commit-from.c:285
msgid "DST-REPO must be specified"
msgstr "CILJ-SKLAD je treba navesti"

#: app/flatpak-builtins-build-commit-from.c:293
msgid ""
"If --src-repo is not specified, exactly one destination ref must be specified"
msgstr "Če --src-repo ni določen, je treba natančno določiti eno ciljno ref"

#: app/flatpak-builtins-build-commit-from.c:296
msgid ""
"If --src-ref is specified, exactly one destination ref must be specified"
msgstr ""
"Če je določen --src-ref, je treba natančno določiti natanko eno ciljno ref"

#: app/flatpak-builtins-build-commit-from.c:299
msgid "Either --src-repo or --src-ref must be specified"
msgstr "Bodisi --src-repo ali --src-ref je treba določiti"

#: app/flatpak-builtins-build-commit-from.c:315
msgid "Invalid argument format of use  --end-of-life-rebase=OLDID=NEWID"
msgstr "Neveljavna oblika argumenta uporabe --end-of-life-rebase=OLDID=NEWID"

#: app/flatpak-builtins-build-commit-from.c:321
#: app/flatpak-builtins-build-commit-from.c:324
#, c-format
msgid "Invalid name %s in --end-of-life-rebase"
msgstr "Neveljavno ime %s v --end-of-life-rebase"

#: app/flatpak-builtins-build-commit-from.c:333
#: app/flatpak-builtins-build-export.c:1092
#, c-format
msgid "Could not parse '%s'"
msgstr "Ni mogoče razčleniti »%s«"

#: app/flatpak-builtins-build-commit-from.c:498
msgid "Can't commit from partial source commit"
msgstr "Ni mogoče objaviti iz delne objave izvorne kode"

#: app/flatpak-builtins-build-commit-from.c:503
#, c-format
msgid "%s: no change\n"
msgstr "%s: brez sprememb\n"

#: app/flatpak-builtins-build-export.c:62
msgid "Architecture to export for (must be host compatible)"
msgstr "Ciljna arhitektura izvoza (mora biti združljiva z gostiteljem)"

#: app/flatpak-builtins-build-export.c:63
msgid "Commit runtime (/usr), not /app"
msgstr "Objavi izvršilno (/usr), ne /app"

#: app/flatpak-builtins-build-export.c:66
msgid "Use alternative directory for the files"
msgstr "Uporabi nadomestno mapo za datoteke"

#: app/flatpak-builtins-build-export.c:66
msgid "SUBDIR"
msgstr "PODMAPA"

#: app/flatpak-builtins-build-export.c:69
msgid "Files to exclude"
msgstr "Datoteke, ki jih je treba izključiti"

#: app/flatpak-builtins-build-export.c:69
#: app/flatpak-builtins-build-export.c:70
#: app/flatpak-builtins-build-update-repo.c:90
msgid "PATTERN"
msgstr "VZOREC"

#: app/flatpak-builtins-build-export.c:70
msgid "Excluded files to include"
msgstr "Izključene datoteke za vključitev"

#: app/flatpak-builtins-build-export.c:74
msgid "Mark build as end-of-life, to be replaced with the given ID"
msgstr ""
"Označi gradnjo kot zastarelo, ki jo je treba nadomestiti z danim ID-jem"

#: app/flatpak-builtins-build-export.c:74
#: app/flatpak-builtins-document-list.c:49 app/flatpak-cli-transaction.c:1427
msgid "ID"
msgstr "ID"

#: app/flatpak-builtins-build-export.c:76
msgid "Override the timestamp of the commit"
msgstr "Preglasi časovni žig objave"

#: app/flatpak-builtins-build-export.c:77
#: app/flatpak-builtins-build-update-repo.c:75
#: app/flatpak-builtins-remote-add.c:83 app/flatpak-builtins-remote-list.c:54
#: app/flatpak-builtins-remote-modify.c:88
msgid "Collection ID"
msgstr "ID zbirke"

#: app/flatpak-builtins-build-export.c:472
#, c-format
msgid "WARNING: Error running desktop-file-validate: %s\n"
msgstr "OPOZORILO: Napaka pri izvajanju desktop-file-validate: %s\n"

#: app/flatpak-builtins-build-export.c:480
#, c-format
msgid "WARNING: Error reading from desktop-file-validate: %s\n"
msgstr "OPOZORILO: Napaka pri branju iz desktop-file-validate: %s\n"

#: app/flatpak-builtins-build-export.c:486
#, c-format
msgid "WARNING: Failed to validate desktop file %s: %s\n"
msgstr "OPOZORILO: Preverjanje veljavnosti namizne datoteke %s: %s\n"

#: app/flatpak-builtins-build-export.c:513
#, c-format
msgid "WARNING: Can't find Exec key in %s: %s\n"
msgstr "OPOZORILO: Ključa Exec ni mogoče najti v %s: %s\n"

#: app/flatpak-builtins-build-export.c:521
#: app/flatpak-builtins-build-export.c:614
#, c-format
msgid "WARNING: Binary not found for Exec line in %s: %s\n"
msgstr "OPOZORILO: binarne ni bilo mogoče najti za vrstico Exec v %s: %s\n"

#: app/flatpak-builtins-build-export.c:529
#, c-format
msgid "WARNING: Icon not matching app id in %s: %s\n"
msgstr "OPOZORILO: Ikona se ne ujema z ID-jem aplikacije v %s: %s\n"

#: app/flatpak-builtins-build-export.c:552
#, c-format
msgid "WARNING: Icon referenced in desktop file but not exported: %s\n"
msgstr ""
"OPOZORILO: v namizni datoteki je sklic na ikono, vendar ni izvožena: %s\n"

#: app/flatpak-builtins-build-export.c:719
#, c-format
msgid "Invalid uri type %s, only http/https supported"
msgstr "Neveljavna vrsta uri %s, podprta samo http/https"

#: app/flatpak-builtins-build-export.c:737
#, c-format
msgid "Unable to find basename in %s, specify a name explicitly"
msgstr "Ni mogoče najti osnovnega imena v %s, izrecno navedite ime"

#: app/flatpak-builtins-build-export.c:746
#, c-format
msgid "No slashes allowed in extra data name"
msgstr "V dodatnem imenu podatkov niso dovoljene poševnice"

#: app/flatpak-builtins-build-export.c:758
#, c-format
msgid "Invalid format for sha256 checksum: '%s'"
msgstr "Neveljavna oblika za kontrolno vsoto sha256: »%s«"

#: app/flatpak-builtins-build-export.c:768
#, c-format
msgid "Extra data sizes of zero not supported"
msgstr "Dodatne velikosti podatkov ničle niso podprte"

#: app/flatpak-builtins-build-export.c:830
msgid ""
"LOCATION DIRECTORY [BRANCH] - Create a repository from a build directory"
msgstr "MESTO MAPA [VEJA] - Ustvarite skladišče iz mape gradnje"

#: app/flatpak-builtins-build-export.c:838
msgid "LOCATION and DIRECTORY must be specified"
msgstr "Navesti morate MESTO in MAPO"

#: app/flatpak-builtins-build-export.c:859
#: app/flatpak-builtins-remote-add.c:327
#, c-format
msgid "‘%s’ is not a valid collection ID: %s"
msgstr "»%s« ni veljaven ID zbirke: %s"

#: app/flatpak-builtins-build-export.c:904
#: app/flatpak-builtins-build-finish.c:684
msgid "No name specified in the metadata"
msgstr "V metapodatkih ni navedeno ime"

#: app/flatpak-builtins-build-export.c:1166
#, c-format
msgid "Commit: %s\n"
msgstr "Objava: %s\n"

#: app/flatpak-builtins-build-export.c:1167
#, c-format
msgid "Metadata Total: %u\n"
msgstr "Skupaj metapodatkov: %u\n"

#: app/flatpak-builtins-build-export.c:1168
#, c-format
msgid "Metadata Written: %u\n"
msgstr "Zapisanih metapodatkov: %u\n"

#: app/flatpak-builtins-build-export.c:1169
#, c-format
msgid "Content Total: %u\n"
msgstr "Skupaj vsebine: %u\n"

#: app/flatpak-builtins-build-export.c:1170
#, c-format
msgid "Content Written: %u\n"
msgstr "Zapisane vsebine: %u\n"

#: app/flatpak-builtins-build-export.c:1171
#, c-format
msgid "Content Bytes Written:"
msgstr "Zapisano bajtov vsebine:"

#: app/flatpak-builtins-build-finish.c:52
msgid "Command to set"
msgstr "Ukaz za nastavitev"

#: app/flatpak-builtins-build-finish.c:52 app/flatpak-builtins-run.c:159
#: app/flatpak-main.c:209
msgid "COMMAND"
msgstr "UKAZ"

#: app/flatpak-builtins-build-finish.c:53
msgid "Flatpak version to require"
msgstr "Zahtevana različica Flatpaka"

#: app/flatpak-builtins-build-finish.c:53
msgid "MAJOR.MINOR.MICRO"
msgstr "GLAVNA.MANJŠA.MIKRO"

#: app/flatpak-builtins-build-finish.c:54
msgid "Don't process exports"
msgstr "Ne obdeluj izvozov"

#: app/flatpak-builtins-build-finish.c:55
msgid "Extra data info"
msgstr "Dodatne informacije o podatkih"

#: app/flatpak-builtins-build-finish.c:56 app/flatpak-builtins-build-init.c:63
msgid "Add extension point info"
msgstr "Dodaj podatke o razširitveni točki"

#: app/flatpak-builtins-build-finish.c:56 app/flatpak-builtins-build-init.c:63
msgid "NAME=VARIABLE[=VALUE]"
msgstr "IME=SPREMENLJIVKA[=VREDNOST]"

#: app/flatpak-builtins-build-finish.c:57
msgid "Remove extension point info"
msgstr "Odstrani podatke o razširitveni točki"

#: app/flatpak-builtins-build-finish.c:57
#: app/flatpak-builtins-build-update-repo.c:79 app/flatpak-builtins-info.c:58
#: app/flatpak-builtins-remote-add.c:88 app/flatpak-builtins-remote-modify.c:94
#: app/flatpak-main.c:182
msgid "NAME"
msgstr "IME"

#: app/flatpak-builtins-build-finish.c:58
msgid "Set extension priority (only for extensions)"
msgstr "Nastavite prednosti razširitve (samo za razširitve)"

#: app/flatpak-builtins-build-finish.c:58
msgid "VALUE"
msgstr "VREDNOST"

#: app/flatpak-builtins-build-finish.c:59
msgid "Change the sdk used for the app"
msgstr "Spremeni sdk, uporabljen za aplikacijo"

#: app/flatpak-builtins-build-finish.c:59
msgid "SDK"
msgstr "SDK"

#: app/flatpak-builtins-build-finish.c:60
msgid "Change the runtime used for the app"
msgstr "Spremeni izvršilno datoteko, uporabljeno za aplikacijo"

#: app/flatpak-builtins-build-finish.c:60 app/flatpak-builtins-build-init.c:54
#: app/flatpak-builtins-list.c:53 app/flatpak-builtins-remote-ls.c:58
#: app/flatpak-builtins-run.c:163
msgid "RUNTIME"
msgstr "IZVAJALNA"

#: app/flatpak-builtins-build-finish.c:61
msgid "Set generic metadata option"
msgstr "Nastavi možnost generičnih metapodatkov"

#: app/flatpak-builtins-build-finish.c:61
msgid "GROUP=KEY[=VALUE]"
msgstr "SKUPINA=KLJUČ[=VREDNOST]"

#: app/flatpak-builtins-build-finish.c:62
msgid "Don't inherit permissions from runtime"
msgstr "Ne deduj pravic iz izvajalne datoteke"

#: app/flatpak-builtins-build-finish.c:155
#, c-format
msgid "Not exporting %s, wrong extension\n"
msgstr "Brez izvažanja %s, napačna končnica\n"

#: app/flatpak-builtins-build-finish.c:163
#, c-format
msgid "Not exporting %s, non-allowed export filename\n"
msgstr "Brez izvažanja %s, ime datoteke za izvoz ni dovoljeno\n"

#: app/flatpak-builtins-build-finish.c:167
#, c-format
msgid "Exporting %s\n"
msgstr "Izvažanje %s\n"

#: app/flatpak-builtins-build-finish.c:440
#, c-format
msgid "More than one executable found\n"
msgstr "Najdenih več kot ena izvršljiva datoteka\n"

#: app/flatpak-builtins-build-finish.c:451
#, c-format
msgid "Using %s as command\n"
msgstr "Uporaba %s kot ukaza\n"

#: app/flatpak-builtins-build-finish.c:456
#, c-format
msgid "No executable found\n"
msgstr "Ni mogoče najti izvršljive datoteke\n"

#: app/flatpak-builtins-build-finish.c:511
#, c-format
msgid "Invalid --require-version argument: %s"
msgstr "Neveljaven argument --require-version: %s"

#: app/flatpak-builtins-build-finish.c:543
#, c-format
msgid "Too few elements in --extra-data argument %s"
msgstr "Premalo elementov v argumentu --extra-data %s"

#: app/flatpak-builtins-build-finish.c:575
#, c-format
msgid ""
"Too few elements in --metadata argument %s, format should be "
"GROUP=KEY[=VALUE]]"
msgstr ""
"Premalo elementov v argumentu --metadata %s, oblika mora biti "
"SKUPINA=KLJUČ[=VREDNOST]]"

#: app/flatpak-builtins-build-finish.c:597
#: app/flatpak-builtins-build-init.c:458
#, c-format
msgid ""
"Too few elements in --extension argument %s, format should be "
"NAME=VAR[=VALUE]"
msgstr ""
"Premalo elementov v argumentu --extension %s, oblika mora biti "
"IME=SPREMENLJIVKA[=VREDNOST]"

#: app/flatpak-builtins-build-finish.c:603
#: app/flatpak-builtins-build-init.c:461
#, c-format
msgid "Invalid extension name %s"
msgstr "Neveljavno ime razširitve %s"

#: app/flatpak-builtins-build-finish.c:646
msgid "DIRECTORY - Finalize a build directory"
msgstr "MAPA - Dokončanje mape gradnje"

#: app/flatpak-builtins-build-finish.c:668
#, c-format
msgid "Build directory %s not initialized"
msgstr "Mapa gradnje %s ni inicializirana"

#: app/flatpak-builtins-build-finish.c:689
#, c-format
msgid "Build directory %s already finalized"
msgstr "Mapa gradnje %s je že dokončana"

#: app/flatpak-builtins-build-finish.c:702
#, c-format
msgid "Please review the exported files and the metadata\n"
msgstr "Preglejte izvožene datoteke in metapodatke\n"

#: app/flatpak-builtins-build-import-bundle.c:47
msgid "Override the ref used for the imported bundle"
msgstr "Preglasi sklic, ki se uporablja za uvoženi sveženj"

#: app/flatpak-builtins-build-import-bundle.c:47
msgid "REF"
msgstr "REF"

#: app/flatpak-builtins-build-import-bundle.c:48
msgid "Import oci image instead of flatpak bundle"
msgstr "Uvozi sliko oci namesto svežnja flatpak"

#: app/flatpak-builtins-build-import-bundle.c:77
#: app/flatpak-builtins-build-import-bundle.c:105
#, c-format
msgid "Importing %s (%s)\n"
msgstr "Uvažanje %s (%s)\n"

#: app/flatpak-builtins-build-import-bundle.c:126
msgid "LOCATION FILENAME - Import a file bundle into a local repository"
msgstr "MESTO IMEDATOTEKE - Uvozi sveženj datotek v krajevno skladišče"

#: app/flatpak-builtins-build-import-bundle.c:133
msgid "LOCATION and FILENAME must be specified"
msgstr "Navesti morata MESTO in IMEDATOTEKE"

#: app/flatpak-builtins-build-init.c:53 app/flatpak-builtins-info.c:55
#: app/flatpak-builtins-run.c:158
msgid "Arch to use"
msgstr "Arh za uporabo"

#: app/flatpak-builtins-build-init.c:54
msgid "Initialize var from named runtime"
msgstr "Inicializacija var iz imenovanega izvajalnika"

#: app/flatpak-builtins-build-init.c:55
msgid "Initialize apps from named app"
msgstr "Inicializacija aplikacij iz imenovane aplikacije"

#: app/flatpak-builtins-build-init.c:55
msgid "APP"
msgstr "PROG"

#: app/flatpak-builtins-build-init.c:56
msgid "Specify version for --base"
msgstr "Navedite različico za --base"

#: app/flatpak-builtins-build-init.c:56 app/flatpak-builtins-run.c:164
msgid "VERSION"
msgstr "RAZLIČICA"

#: app/flatpak-builtins-build-init.c:57
msgid "Include this base extension"
msgstr "Vključi to osnovno razširitev"

#: app/flatpak-builtins-build-init.c:57 app/flatpak-builtins-build-init.c:62
msgid "EXTENSION"
msgstr "RAZŠIRITEV"

#: app/flatpak-builtins-build-init.c:58
msgid "Extension tag to use if building extension"
msgstr "Razširitvena značka za uporabo ob gradnji razširitve"

#: app/flatpak-builtins-build-init.c:58
msgid "EXTENSION_TAG"
msgstr "ZNAČKA_RAZŠIRITVE"

#: app/flatpak-builtins-build-init.c:59
msgid "Initialize /usr with a writable copy of the sdk"
msgstr "Inicializirae /usr z zapisljivo kopijo sdk"

#: app/flatpak-builtins-build-init.c:60
msgid "Specify the build type (app, runtime, extension)"
msgstr "Določite vrsto gradnje (aplikacija, izv. program, razširitev)"

#: app/flatpak-builtins-build-init.c:60
msgid "TYPE"
msgstr "VRSTA"

#: app/flatpak-builtins-build-init.c:61
msgid "Add a tag"
msgstr "Dodaj značko"

#: app/flatpak-builtins-build-init.c:61
msgid "TAG"
msgstr "OZNAKA"

#: app/flatpak-builtins-build-init.c:62
msgid "Include this sdk extension in /usr"
msgstr "Vključi to razširitev SDK v /usr"

#: app/flatpak-builtins-build-init.c:64
msgid "Where to store sdk (defaults to 'usr')"
msgstr "Kje shraniti SDK (privzeto v »usr«)"

#: app/flatpak-builtins-build-init.c:65
msgid "Re-initialize the sdk/var"
msgstr "Ponovno inicializiraj sdk/var"

#: app/flatpak-builtins-build-init.c:118
#, c-format
msgid "Requested extension %s/%s/%s is only partially installed"
msgstr "Zahtevana razširitev %s/%s/%s je samo delno nameščena"

#: app/flatpak-builtins-build-init.c:147
#, c-format
msgid "Requested extension %s/%s/%s not installed"
msgstr "Zahtevana razširitev %s/%s/%s ni nameščena"

#: app/flatpak-builtins-build-init.c:207
msgid ""
"DIRECTORY APPNAME SDK RUNTIME [BRANCH] - Initialize a directory for building"
msgstr "MAPA IMEPROGRAMA SDK IZVAJALNA [VEJA] - Inicializacija mape za gradnjo"

#: app/flatpak-builtins-build-init.c:214
msgid "RUNTIME must be specified"
msgstr "IZVAJALNO je treba določiti"

#: app/flatpak-builtins-build-init.c:235
#, c-format
msgid "'%s' is not a valid build type name, use app, runtime or extension"
msgstr ""
"»%s« ni veljavno ime vrste gradnje, uporabite app, runtime ali extension"

#: app/flatpak-builtins-build-init.c:241 app/flatpak-builtins-override.c:79
#, c-format
msgid "'%s' is not a valid application name: %s"
msgstr "»%s« ni veljavno ime aplikacije: %s"

#: app/flatpak-builtins-build-init.c:295
#, c-format
msgid "Build directory %s already initialized"
msgstr "Mapa gradnje je %s že inicializirana"

#: app/flatpak-builtins-build-sign.c:42 app/flatpak-builtins-install.c:67
#: app/flatpak-builtins-remote-info.c:54
msgid "Arch to install for"
msgstr "Arh za nameščanje"

#: app/flatpak-builtins-build-sign.c:43 app/flatpak-builtins-create-usb.c:48
#: app/flatpak-builtins-install.c:74 app/flatpak-builtins-remote-info.c:56
#: app/flatpak-builtins-uninstall.c:58 app/flatpak-builtins-update.c:64
msgid "Look for runtime with the specified name"
msgstr "Poiščite izvajalno datoteko z navedenim imenom"

#: app/flatpak-builtins-build-sign.c:66
msgid "LOCATION [ID [BRANCH]] - Sign an application or runtime"
msgstr "MESTO [ID [VEJA]] - Podpišite aplikacijo ali izvajalno datoteko"

#: app/flatpak-builtins-build-sign.c:73
#: app/flatpak-builtins-build-update-repo.c:499
#: app/flatpak-builtins-remote-add.c:320 app/flatpak-builtins-repo.c:739
msgid "LOCATION must be specified"
msgstr "Določiti je treba MESTO"

#: app/flatpak-builtins-build-sign.c:94
msgid "No gpg key ids specified"
msgstr "Ni navedenih ID-jev ključev gpg"

#: app/flatpak-builtins-build-update-repo.c:68
msgid "Redirect this repo to a new URL"
msgstr "Preusmeri to skladišče na nov URL"

#: app/flatpak-builtins-build-update-repo.c:69
msgid "A nice name to use for this repository"
msgstr "Lepo ime, ki se lahko uporablja za to skladišče"

#: app/flatpak-builtins-build-update-repo.c:69
#: app/flatpak-builtins-remote-add.c:77 app/flatpak-builtins-remote-modify.c:82
msgid "TITLE"
msgstr "NASLOV"

#: app/flatpak-builtins-build-update-repo.c:70
msgid "A one-line comment for this repository"
msgstr "Enovrstična pripomba za to skladišče"

#: app/flatpak-builtins-build-update-repo.c:70
#: app/flatpak-builtins-remote-add.c:78 app/flatpak-builtins-remote-modify.c:83
msgid "COMMENT"
msgstr "KOMENTAR"

#: app/flatpak-builtins-build-update-repo.c:71
msgid "A full-paragraph description for this repository"
msgstr "Opisni odstavek za to skladišče"

#: app/flatpak-builtins-build-update-repo.c:71
#: app/flatpak-builtins-remote-add.c:79 app/flatpak-builtins-remote-modify.c:84
msgid "DESCRIPTION"
msgstr "OPIS"

#: app/flatpak-builtins-build-update-repo.c:72
msgid "URL for a website for this repository"
msgstr "URL spletišča za to skladišče"

#: app/flatpak-builtins-build-update-repo.c:73
msgid "URL for an icon for this repository"
msgstr "URL za ikono za to skladišče"

#: app/flatpak-builtins-build-update-repo.c:74
msgid "Default branch to use for this repository"
msgstr "Privzeta veja, ki jo želite uporabiti za to skladišče"

#: app/flatpak-builtins-build-update-repo.c:74
#: app/flatpak-builtins-remote-add.c:82 app/flatpak-builtins-remote-modify.c:87
#: app/flatpak-builtins-repo.c:713 app/flatpak-builtins-repo.c:714
#: app/flatpak-builtins-run.c:161
msgid "BRANCH"
msgstr "VEJA"

#: app/flatpak-builtins-build-update-repo.c:75
#: app/flatpak-builtins-remote-add.c:83 app/flatpak-builtins-remote-modify.c:88
msgid "COLLECTION-ID"
msgstr "ID-ZBIRKE"

#. Translators: A sideload is when you install from a local USB drive rather than the Internet.
#: app/flatpak-builtins-build-update-repo.c:77
msgid ""
"Permanently deploy collection ID to client remote configurations, only for "
"sideload support"
msgstr ""
"Trajno uvedi ID zbirke v oddaljene prilagoditve odjemalca, samo za podporo "
"nalaganja z naprave"

#: app/flatpak-builtins-build-update-repo.c:78
msgid "Permanently deploy collection ID to client remote configurations"
msgstr "Trajno uvedi ID-ja zbirke v oddaljene prilagoditve odjemalca"

#: app/flatpak-builtins-build-update-repo.c:79
msgid "Name of authenticator for this repository"
msgstr "Ime preverjevalnika za to skladišče"

#: app/flatpak-builtins-build-update-repo.c:80
msgid "Autoinstall authenticator for this repository"
msgstr "Samodejno namesti preverjevalnik za to skladišče"

#: app/flatpak-builtins-build-update-repo.c:81
msgid "Don't autoinstall authenticator for this repository"
msgstr "Ne namesti samodejno preverjevalnika za to skladišče"

#: app/flatpak-builtins-build-update-repo.c:82
#: app/flatpak-builtins-remote-add.c:89
msgid "Authenticator option"
msgstr "Možnost overjevalnika"

#: app/flatpak-builtins-build-update-repo.c:82
#: app/flatpak-builtins-remote-add.c:89 app/flatpak-builtins-remote-modify.c:95
msgid "KEY=VALUE"
msgstr "KLJUČ=VREDNOST"

#: app/flatpak-builtins-build-update-repo.c:83
msgid "Import new default GPG public key from FILE"
msgstr "Uvozi novi privzeti javni ključ GPG iz DATOTEKE"

#: app/flatpak-builtins-build-update-repo.c:84
msgid "GPG Key ID to sign the summary with"
msgstr "ID ključa GPG za podpis povzetka"

#: app/flatpak-builtins-build-update-repo.c:86
msgid "Generate delta files"
msgstr "Ustvari datoteke delta"

#: app/flatpak-builtins-build-update-repo.c:88
msgid "Don't update the appstream branch"
msgstr "Ne posodabljaj veje appstream"

#: app/flatpak-builtins-build-update-repo.c:89
msgid "Max parallel jobs when creating deltas (default: NUMCPUs)"
msgstr ""
"Največje število vzporednih opravil pri ustvarjanju delte (privzeto: ŠT_CPE)"

#: app/flatpak-builtins-build-update-repo.c:89
msgid "NUM-JOBS"
msgstr "ŠT-POSLOV"

#: app/flatpak-builtins-build-update-repo.c:90
msgid "Don't create deltas matching refs"
msgstr "Ne ustvarjaj delt, ki ustrezajo ref."

#: app/flatpak-builtins-build-update-repo.c:91
msgid "Prune unused objects"
msgstr "Obreži neuporabljene predmete"

#: app/flatpak-builtins-build-update-repo.c:92
msgid "Prune but don't actually remove anything"
msgstr "Obreži, vendar ne odstrani ničesar"

#: app/flatpak-builtins-build-update-repo.c:93
msgid "Only traverse DEPTH parents for each commit (default: -1=infinite)"
msgstr ""
"Samo prečkaj GLOBINO nadrejenih za vsako objavo (privzeto: -1=neskončno)"

#: app/flatpak-builtins-build-update-repo.c:93
msgid "DEPTH"
msgstr "GLOBINA"

#: app/flatpak-builtins-build-update-repo.c:223
#, c-format
msgid "Generating delta: %s (%.10s)\n"
msgstr "Tvorjenje delte: %s (%.10s)\n"

#: app/flatpak-builtins-build-update-repo.c:225
#, c-format
msgid "Generating delta: %s (%.10s-%.10s)\n"
msgstr "Tvorjenje delte: %s (%.10s-%.10s)\n"

#: app/flatpak-builtins-build-update-repo.c:233
#, c-format
msgid "Failed to generate delta %s (%.10s): "
msgstr "Ni uspelo ustvariti delte %s (%.10s): "

#: app/flatpak-builtins-build-update-repo.c:236
#, c-format
msgid "Failed to generate delta %s (%.10s-%.10s): "
msgstr "Ni uspelo ustvariti delte %s (%.10s-%.10s): "

#: app/flatpak-builtins-build-update-repo.c:492
msgid "LOCATION - Update repository metadata"
msgstr "MESTO - Posodobi metapodatke skladišča"

#: app/flatpak-builtins-build-update-repo.c:609
#, c-format
msgid "Updating appstream branch\n"
msgstr "Posodabljanje vaje v appstream\n"

#: app/flatpak-builtins-build-update-repo.c:638
#, c-format
msgid "Updating summary\n"
msgstr "Posodabljanje povzetka\n"

#: app/flatpak-builtins-build-update-repo.c:664
#, c-format
msgid "Total objects: %u\n"
msgstr "Skupaj predmetov: %u\n"

#: app/flatpak-builtins-build-update-repo.c:666
#, c-format
msgid "No unreachable objects\n"
msgstr "Ni nedosegljivih predmetov\n"

#: app/flatpak-builtins-build-update-repo.c:668
#, c-format
msgid "Deleted %u objects, %s freed\n"
msgstr "Izbrisanih %u predmetov, %s sproščeno\n"

#: app/flatpak-builtins-config.c:41
msgid "List configuration keys and values"
msgstr "Seznam priilagoditvenih ključev in vrednosti"

#: app/flatpak-builtins-config.c:42
msgid "Get configuration for KEY"
msgstr "Pridobi prilagoditev za KLJUČ"

#: app/flatpak-builtins-config.c:43
msgid "Set configuration for KEY to VALUE"
msgstr "Nastavi prilagoditev za KLJUČ na VREDNOST"

#: app/flatpak-builtins-config.c:44
msgid "Unset configuration for KEY"
msgstr "Nenastavljena prilagoditev za KLJUČ"

#: app/flatpak-builtins-config.c:149
#, c-format
msgid "'%s' does not look like a language/locale code"
msgstr "»%s« ni videti kot koda jezika/področne nastavitve"

#: app/flatpak-builtins-config.c:172
#, c-format
msgid "'%s' does not look like a language code"
msgstr "»%s« ni videti kot jezikovna koda"

#: app/flatpak-builtins-config.c:190
#, c-format
msgid "'%s' is not a valid value (use 'true' or 'false')"
msgstr "»%s« ni veljavna vrednost (uporabite »true« ali »false«)"

#: app/flatpak-builtins-config.c:262
#, c-format
msgid "Unknown configure key '%s'"
msgstr "Neznan prilagoditveni ključ »%s«"

#: app/flatpak-builtins-config.c:284
msgid "Too many arguments for --list"
msgstr "Preveč argumentov za --list"

#: app/flatpak-builtins-config.c:314 app/flatpak-builtins-config.c:362
msgid "You must specify KEY"
msgstr "Določiti morate KLJUČ"

#: app/flatpak-builtins-config.c:316
msgid "Too many arguments for --get"
msgstr "Preveč argumentov za --get"

#: app/flatpak-builtins-config.c:338
msgid "You must specify KEY and VALUE"
msgstr "Navesti morate KLJUČ in VREDNOST"

#: app/flatpak-builtins-config.c:340
msgid "Too many arguments for --set"
msgstr "Preveč argumentov za --set"

#: app/flatpak-builtins-config.c:364
msgid "Too many arguments for --unset"
msgstr "Preveč argumentov za --unset"

#: app/flatpak-builtins-config.c:383
msgid "[KEY [VALUE]] - Manage configuration"
msgstr "[KLJUČ [VREDNOST]] - Upravljanje prilagoditve"

#: app/flatpak-builtins-config.c:394
msgid "Can only use one of --list, --get, --set or --unset"
msgstr "Uporabite lahko samo enega od --list, --get, --set ali --unset"

#: app/flatpak-builtins-config.c:408
msgid "Must specify one of --list, --get, --set or --unset"
msgstr "Določiti morate enega od --list, --get, --set ali --unset"

#: app/flatpak-builtins-create-usb.c:45 app/flatpak-builtins-install.c:75
#: app/flatpak-builtins-remote-info.c:57 app/flatpak-builtins-uninstall.c:59
#: app/flatpak-builtins-update.c:65
msgid "Look for app with the specified name"
msgstr "Poiščite aplikacijo z navedenim imenom"

#: app/flatpak-builtins-create-usb.c:46
msgid "Arch to copy"
msgstr "Arh za kopiranje"

#: app/flatpak-builtins-create-usb.c:47
msgid "DEST"
msgstr "CILJ"

#: app/flatpak-builtins-create-usb.c:49
msgid "Allow partial commits in the created repo"
msgstr "Dovoli delne objave v ustvarjenem skladišču"

#: app/flatpak-builtins-create-usb.c:125 app/flatpak-builtins-create-usb.c:165
#, c-format
msgid ""
"Warning: Related ref ‘%s’ is partially installed. Use --allow-partial to "
"suppress this message.\n"
msgstr ""
"Opozorilo: Sorodna ref »%s« je delno nameščena. Uporabite --allow-partial, "
"da zatrete to sporočilo.\n"

#: app/flatpak-builtins-create-usb.c:158
#, c-format
msgid "Warning: Omitting related ref ‘%s’ because it is not installed.\n"
msgstr "Opozorilo: izpuščanje povezane ref. »%s«, ker ni nameščeno.\n"

#: app/flatpak-builtins-create-usb.c:175
#, c-format
msgid ""
"Warning: Omitting related ref ‘%s’ because its remote ‘%s’ does not have a "
"collection ID set.\n"
msgstr ""
"Opozorilo: izpuščanje povezane ref »%s«, ker njen oddaljeni »%s« nima "
"nastavljenega ID zbirke.\n"

#: app/flatpak-builtins-create-usb.c:187
#, c-format
msgid "Warning: Omitting related ref ‘%s’ because it's extra-data.\n"
msgstr ""
"Opozorilo: izpuščanje povezane ref. »%s«, ker gre za dodatne podatke.\n"

#: app/flatpak-builtins-create-usb.c:262 app/flatpak-builtins-create-usb.c:637
#, c-format
msgid ""
"Remote ‘%s’ does not have a collection ID set, which is required for P2P "
"distribution of ‘%s’."
msgstr ""
"Oddaljeni »%s« nima nabora ID-ja zbirke, ki je potreben za distribucijo P2P "
"»%s«."

#: app/flatpak-builtins-create-usb.c:272
#, c-format
msgid "Warning: Omitting ref ‘%s’ (runtime of ‘%s’) because it's extra-data.\n"
msgstr ""
"Opozorilo: izpuščanje »%s« (izvajalna datoteka »%s«), ker gre za dodatne "
"podatke.\n"

#: app/flatpak-builtins-create-usb.c:484
msgid "MOUNT-PATH [REF…] - Copy apps or runtimes onto removable media"
msgstr ""
"MOUNT-PATH [REF...] - Kopirajte programe ali izvajalne aplikacije na "
"izmenljive medije"

#: app/flatpak-builtins-create-usb.c:493
msgid "MOUNT-PATH and REF must be specified"
msgstr "Določiti je treba MOUNT-PATH in REF"

#: app/flatpak-builtins-create-usb.c:607
#, c-format
msgid "Ref ‘%s’ found in multiple installations: %s. You must specify one."
msgstr "Ref »%s« je moč najti v več namestitvah: %s. Navesti morate eno."

#: app/flatpak-builtins-create-usb.c:620
#, c-format
msgid "Refs must all be in the same installation (found in %s and %s)."
msgstr "Vsi ref morajo biti v isti namestitvi (najdeno v %s in %s)."

#: app/flatpak-builtins-create-usb.c:670
#, c-format
msgid ""
"Warning: Ref ‘%s’ is partially installed. Use --allow-partial to suppress "
"this message.\n"
msgstr ""
"Opozorilo: ref »%s« je delno nameščen. Uporabite --allow-partial za "
"zatiranje tega sporočila.\n"

#: app/flatpak-builtins-create-usb.c:681
#, c-format
msgid "Installed ref ‘%s’ is extra-data, and cannot be distributed offline"
msgstr ""
"Nameščeni ref »%s« je dodatni podatek in ga ni mogoče distribuirati brez "
"povezave"

#: app/flatpak-builtins-create-usb.c:721
#, c-format
msgid "Warning: Couldn't update repo metadata for remote ‘%s’: %s\n"
msgstr ""
"Opozorilo: metapodatkov skladišča za oddaljeni »%s« ni bilo mogoče "
"posodobiti: %s\n"

#: app/flatpak-builtins-create-usb.c:751
#, c-format
msgid "Warning: Couldn't update appstream data for remote ‘%s’ arch ‘%s’: %s\n"
msgstr ""
"Opozorilo: ni bilo mogoče posodobiti podatkov appstream za oddaljeni »%s« "
"arh. »%s«: %s\n"

#. Print a warning if both appstream and appstream2 are missing
#: app/flatpak-builtins-create-usb.c:784
#, c-format
msgid ""
"Warning: Couldn't find appstream data for remote ‘%s’ arch ‘%s’: %s; %s\n"
msgstr ""
"Opozorilo: ni bilo mogoče najti podatkov appstream za oddaljeni »%s« arh. "
"»%s«: %s; %s\n"

#. Appstream2 is only for efficiency, so just print a debug message
#: app/flatpak-builtins-create-usb.c:790
#, c-format
msgid "Couldn't find appstream2 data for remote ‘%s’ arch ‘%s’: %s\n"
msgstr "Podatkov appstream2 za oddaljeni »%s « arh. %s ni možno najti: %s\n"

#: app/flatpak-builtins-document-export.c:62
msgid "Create a unique document reference"
msgstr "Ustvari enolično referenco dokumenta"

#: app/flatpak-builtins-document-export.c:63
msgid "Make the document transient for the current session"
msgstr "Naredi dokument prehoden za trenutno sejo"

#: app/flatpak-builtins-document-export.c:64
msgid "Don't require the file to exist already"
msgstr "Ne zahtevaj, da datoteka že obstaja"

#: app/flatpak-builtins-document-export.c:65
msgid "Give the app read permissions"
msgstr "Dodeli aplikaciji pravice za branje"

#: app/flatpak-builtins-document-export.c:66
msgid "Give the app write permissions"
msgstr "Dodeli aplikaciji pravice za pisanje"

#: app/flatpak-builtins-document-export.c:67
msgid "Give the app delete permissions"
msgstr "Dodeli aplikaciji pravice za brisanje"

#: app/flatpak-builtins-document-export.c:68
msgid "Give the app permissions to grant further permissions"
msgstr "Dodeli aplikaciji pravice za za podeljevanje dodatnih pravic"

#: app/flatpak-builtins-document-export.c:69
msgid "Revoke read permissions of the app"
msgstr "Prekliči dovoljenja za branje aplikaciji"

#: app/flatpak-builtins-document-export.c:70
msgid "Revoke write permissions of the app"
msgstr "Prekliči dovoljenja za pisanje aplikaciji"

#: app/flatpak-builtins-document-export.c:71
msgid "Revoke delete permissions of the app"
msgstr "Prekliči dovoljenja za brisanje aplikaciji"

#: app/flatpak-builtins-document-export.c:72
msgid "Revoke the permission to grant further permissions"
msgstr "Prekliči dovoljenja za dodelitev dodatnih dovoljenj"

#: app/flatpak-builtins-document-export.c:73
msgid "Add permissions for this app"
msgstr "Dodaj dovoljenja za ta program"

#: app/flatpak-builtins-document-export.c:73
msgid "APPID"
msgstr "APPID"

#: app/flatpak-builtins-document-export.c:100
msgid "FILE - Export a file to apps"
msgstr "DATOTEKA – Izvozite datoteko v aplikacije"

#: app/flatpak-builtins-document-export.c:109
#: app/flatpak-builtins-document-info.c:72
#: app/flatpak-builtins-document-unexport.c:67
msgid "FILE must be specified"
msgstr "DATOTEKA mora biti navedena"

#: app/flatpak-builtins-document-info.c:63
msgid "FILE - Get information about an exported file"
msgstr "DATOTEKA – Pridobite informacije o izvoženi datoteki"

#: app/flatpak-builtins-document-info.c:100
#: app/flatpak-builtins-document-unexport.c:94
#, c-format
msgid "Not exported\n"
msgstr "Ni izvoženo\n"

#: app/flatpak-builtins-document-list.c:43 app/flatpak-builtins-history.c:53
#: app/flatpak-builtins-list.c:54 app/flatpak-builtins-ps.c:43
#: app/flatpak-builtins-remote-list.c:45 app/flatpak-builtins-remote-ls.c:59
#: app/flatpak-builtins-search.c:38
msgid "What information to show"
msgstr "Katere informacije je treba pokazati"

#: app/flatpak-builtins-document-list.c:43 app/flatpak-builtins-history.c:53
#: app/flatpak-builtins-list.c:54 app/flatpak-builtins-ps.c:43
#: app/flatpak-builtins-remote-list.c:45 app/flatpak-builtins-remote-ls.c:59
#: app/flatpak-builtins-search.c:38
msgid "FIELD,…"
msgstr "POLJE,…"

#: app/flatpak-builtins-document-list.c:44 app/flatpak-builtins-history.c:54
#: app/flatpak-builtins-list.c:52 app/flatpak-builtins-permission-list.c:43
#: app/flatpak-builtins-permission-show.c:43 app/flatpak-builtins-ps.c:44
#: app/flatpak-builtins-remote-list.c:46 app/flatpak-builtins-remote-ls.c:63
#: app/flatpak-builtins-repo.c:717 app/flatpak-builtins-search.c:39
msgid "Show output in JSON format"
msgstr "Pokaži izhod v zapisu JSON"

#: app/flatpak-builtins-document-list.c:49
msgid "Show the document ID"
msgstr "Pokaži ID dokumenta"

#: app/flatpak-builtins-document-list.c:50
msgid "Path"
msgstr "Pot"

#: app/flatpak-builtins-document-list.c:50
#: app/flatpak-builtins-document-list.c:51
msgid "Show the document path"
msgstr "Pokaži pot dokumenta"

#: app/flatpak-builtins-document-list.c:51 app/flatpak-builtins-list.c:66
#: app/flatpak-builtins-remote-ls.c:74
msgid "Origin"
msgstr "Vir"

#: app/flatpak-builtins-document-list.c:52 app/flatpak-builtins-history.c:62
#: app/flatpak-builtins-ps.c:52
msgid "Application"
msgstr "Program"

#: app/flatpak-builtins-document-list.c:52
msgid "Show applications with permission"
msgstr "Pokaži programe z dovoljenjem"

#: app/flatpak-builtins-document-list.c:53
#: app/flatpak-builtins-permission-list.c:182
#: app/flatpak-builtins-permission-show.c:145
msgid "Permissions"
msgstr "Dovoljenja"

#: app/flatpak-builtins-document-list.c:53
msgid "Show permissions for applications"
msgstr "Pokaži dovoljenja za aplikacije"

#: app/flatpak-builtins-document-list.c:161
#, c-format
msgid "No documents found\n"
msgstr "Ni najdenih dokumentov\n"

#: app/flatpak-builtins-document-list.c:180
msgid "[APPID] - List exported files"
msgstr "[IDAPL] - Izpiši seznam izvoženih datotek"

#: app/flatpak-builtins-document-unexport.c:43
msgid "Specify the document ID"
msgstr "Navedite ID dokumenta"

#: app/flatpak-builtins-document-unexport.c:58
msgid "FILE - Unexport a file to apps"
msgstr "DATOTEKA – Prekličite izvoz datoteke v aplikacije"

#: app/flatpak-builtins-enter.c:88
msgid "INSTANCE COMMAND [ARGUMENT…] - Run a command inside a running sandbox"
msgstr "POJAVITEV UKAZ [ARGUMENT...] - Zaženite ukaz v zagnanem peskovniku"

#: app/flatpak-builtins-enter.c:111
msgid "INSTANCE and COMMAND must be specified"
msgstr "PRIMEREK in UKAZ morata biti določena"

#: app/flatpak-builtins-enter.c:138
#, c-format
msgid "%s is neither a pid nor an application or instance ID"
msgstr "%s ni niti pid niti ID aplikacije ali primerka"

#: app/flatpak-builtins-enter.c:144
msgid "entering not supported (need unprivileged user namespaces, or sudo -E)"
msgstr ""
"vnašanje ni podprto (potrebujete uporabniški imenski prostor brez "
"privilegijev ali sudo -E)"

#: app/flatpak-builtins-enter.c:145
#, c-format
msgid "No such pid %s"
msgstr "Ni takšnih pid %s"

#: app/flatpak-builtins-enter.c:158
msgid "Can't read cwd"
msgstr "Ni možno prebrati cwd"

#: app/flatpak-builtins-enter.c:163
msgid "Can't read root"
msgstr "Ni možno prebrati root"

#: app/flatpak-builtins-enter.c:191
#, c-format
msgid "Invalid %s namespace for pid %d"
msgstr "Neveljaven imenski prostor %s za pid %d"

#: app/flatpak-builtins-enter.c:202
#, c-format
msgid "Invalid %s namespace for self"
msgstr "Neveljaven imenski prostor %s za sebe"

#: app/flatpak-builtins-enter.c:216
#, c-format
msgid "Can't open %s namespace: %s"
msgstr "Ni mogoče odpreti imenskega prostora %s: %s"

#: app/flatpak-builtins-enter.c:226
msgid "entering not supported (need unprivileged user namespaces)"
msgstr ""
"vnos ni podprt (potrebujete neprivilegirane uporabniške imenske prostore)"

#: app/flatpak-builtins-enter.c:227
#, c-format
msgid "Can't enter %s namespace: %s"
msgstr "Ni mogoče vstopiti v imenski prostor %s: %s"

#: app/flatpak-builtins-enter.c:234
msgid "Can't chdir"
msgstr "Ni možno izvesti chdir"

#: app/flatpak-builtins-enter.c:237
msgid "Can't chroot"
msgstr "Ni možno izvesti chroot"

#: app/flatpak-builtins-enter.c:240
msgid "Can't switch gid"
msgstr "Ni mogoče preklopiti gid"

#: app/flatpak-builtins-enter.c:243
msgid "Can't switch uid"
msgstr "Ni mogoče preklopiti uid"

#: app/flatpak-builtins-history.c:50
msgid "Only show changes after TIME"
msgstr "Samo pokaži spremembe po ČAS-u"

#: app/flatpak-builtins-history.c:50 app/flatpak-builtins-history.c:51
msgid "TIME"
msgstr "ČAS"

#: app/flatpak-builtins-history.c:51
msgid "Only show changes before TIME"
msgstr "Pokaži samo spremembe pred časom TIME/ČAS"

#: app/flatpak-builtins-history.c:52
msgid "Show newest entries first"
msgstr "Najprej pokaži nove vnose"

#: app/flatpak-builtins-history.c:59
msgid "Time"
msgstr "Čas"

#: app/flatpak-builtins-history.c:59
msgid "Show when the change happened"
msgstr "Pokaži, kdaj se je sprememba zgodila"

#: app/flatpak-builtins-history.c:60
msgid "Change"
msgstr "Spremeni"

#: app/flatpak-builtins-history.c:60
msgid "Show the kind of change"
msgstr "Pokaži vrsto spremembe"

#: app/flatpak-builtins-history.c:61 app/flatpak-builtins-list.c:68
#: app/flatpak-builtins-remote-ls.c:75 app/flatpak-builtins-repo.c:335
msgid "Ref"
msgstr "Ref"

#: app/flatpak-builtins-history.c:61 app/flatpak-builtins-list.c:68
#: app/flatpak-builtins-remote-ls.c:75
msgid "Show the ref"
msgstr "Pokaži ref"

#: app/flatpak-builtins-history.c:62
msgid "Show the application/runtime ID"
msgstr "Pokaži ID programa/izvajalnika"

#: app/flatpak-builtins-history.c:63 app/flatpak-builtins-list.c:64
#: app/flatpak-builtins-ps.c:53 app/flatpak-builtins-remote-ls.c:73
#: app/flatpak-cli-transaction.c:1435
msgid "Arch"
msgstr "Arhitektura"

#: app/flatpak-builtins-history.c:63 app/flatpak-builtins-list.c:64
#: app/flatpak-builtins-ps.c:53 app/flatpak-builtins-remote-ls.c:73
msgid "Show the architecture"
msgstr "Pokaži arhitekturo"

#: app/flatpak-builtins-history.c:64 app/flatpak-builtins-list.c:63
#: app/flatpak-builtins-ps.c:54 app/flatpak-builtins-remote-ls.c:72
#: app/flatpak-builtins-search.c:48 app/flatpak-cli-transaction.c:1438
msgid "Branch"
msgstr "Veja"

#: app/flatpak-builtins-history.c:64 app/flatpak-builtins-list.c:63
#: app/flatpak-builtins-remote-ls.c:72
msgid "Show the branch"
msgstr "Pokaži vejo"

#: app/flatpak-builtins-history.c:65 app/flatpak-builtins-list.c:67
msgid "Installation"
msgstr "Namestitev"

#: app/flatpak-builtins-history.c:65
msgid "Show the affected installation"
msgstr "Pokaži prizadete namestitve"

#: app/flatpak-builtins-history.c:66 app/flatpak-cli-transaction.c:1452
msgid "Remote"
msgstr "Oddaljeno"

#: app/flatpak-builtins-history.c:66
msgid "Show the remote"
msgstr "Pokaži oddaljeni"

#: app/flatpak-builtins-history.c:67 app/flatpak-builtins-ps.c:55
#: app/flatpak-builtins-remote-ls.c:76
msgid "Commit"
msgstr "Uveljavi"

#: app/flatpak-builtins-history.c:67
msgid "Show the current commit"
msgstr "Pokaži trenutno objavo"

#: app/flatpak-builtins-history.c:68
msgid "Old Commit"
msgstr "Stara objava"

#: app/flatpak-builtins-history.c:68
msgid "Show the previous commit"
msgstr "Pokaži prejšnjo objavo"

#: app/flatpak-builtins-history.c:69
msgid "Show the remote URL"
msgstr "Prikaži oddaljeni URL"

#: app/flatpak-builtins-history.c:70 app/flatpak-cli-transaction.c:700
msgid "User"
msgstr "Uporabnik"

#: app/flatpak-builtins-history.c:70
msgid "Show the user doing the change"
msgstr "Pokaži uporabniku, ki dela spremembo"

#: app/flatpak-builtins-history.c:71
msgid "Tool"
msgstr "Orodje"

#: app/flatpak-builtins-history.c:71
msgid "Show the tool that was used"
msgstr "Pokaži orodje, ki je bilo uporabljeno"

#: app/flatpak-builtins-history.c:72 app/flatpak-builtins-list.c:62
#: app/flatpak-builtins-remote-ls.c:71 app/flatpak-builtins-search.c:47
msgid "Version"
msgstr "Različica"

#: app/flatpak-builtins-history.c:72
msgid "Show the Flatpak version"
msgstr "Pokaži različico Flatpak"

#: app/flatpak-builtins-history.c:91
#, c-format
msgid "Failed to get journal data (%s): %s"
msgstr "Prenos podatkov dnevnika (%s) je spodletel: %s"

#: app/flatpak-builtins-history.c:146
#, c-format
msgid "Failed to open journal: %s"
msgstr "Odpiranje dnevnika ni uspelo: %s"

#: app/flatpak-builtins-history.c:153
#, c-format
msgid "Failed to add match to journal: %s"
msgstr "Dodajanje ujemanja v dnevnik ni uspelo: %s"

#: app/flatpak-builtins-history.c:471
msgid " - Show history"
msgstr " - Pokaži zgodovino"

#: app/flatpak-builtins-history.c:490
#, c-format
msgid "Failed to parse the --since option"
msgstr "Spodletelo razčlenjevanje možnosti --since"

#: app/flatpak-builtins-history.c:501
#, c-format
msgid "Failed to parse the --until option"
msgstr "Spodletelo razčlenjevanje možnosti --until"

#: app/flatpak-builtins-info.c:56
msgid "Show user installations"
msgstr "Pokaži uporabniške namestitve"

#: app/flatpak-builtins-info.c:57
msgid "Show system-wide installations"
msgstr "Pokaži sistemske namestitve"

#: app/flatpak-builtins-info.c:58
msgid "Show specific system-wide installations"
msgstr "Pokaži določene sistemske namestitve"

#: app/flatpak-builtins-info.c:59 app/flatpak-builtins-remote-info.c:59
msgid "Show ref"
msgstr "Pokaži ref"

#: app/flatpak-builtins-info.c:60 app/flatpak-builtins-remote-info.c:60
msgid "Show commit"
msgstr "Prikaži uveljavitev"

#: app/flatpak-builtins-info.c:61
msgid "Show origin"
msgstr "Pokaži izvor"

#: app/flatpak-builtins-info.c:62
msgid "Show size"
msgstr "Pokaži velikost"

#: app/flatpak-builtins-info.c:63 app/flatpak-builtins-remote-info.c:62
msgid "Show metadata"
msgstr "Pokaži metapodatke"

#: app/flatpak-builtins-info.c:64 app/flatpak-builtins-remote-info.c:63
msgid "Show runtime"
msgstr "Pokaži izvajalnik"

#: app/flatpak-builtins-info.c:65 app/flatpak-builtins-remote-info.c:64
msgid "Show sdk"
msgstr "Pokaži SDK"

#: app/flatpak-builtins-info.c:66
msgid "Show permissions"
msgstr "Pokaži dovoljenja"

#: app/flatpak-builtins-info.c:67
msgid "Query file access"
msgstr "Dostop do datoteke poizvedbe"

#: app/flatpak-builtins-info.c:67 app/flatpak-builtins-install.c:82
#: app/flatpak-builtins-install.c:88 app/flatpak-builtins-preinstall.c:68
#: app/flatpak-builtins-run.c:182 app/flatpak-builtins-run.c:184
#: app/flatpak-builtins-update.c:67 app/flatpak-builtins-update.c:71
msgid "PATH"
msgstr "POT"

#: app/flatpak-builtins-info.c:68
msgid "Show extensions"
msgstr "Pokaži razširitve"

#: app/flatpak-builtins-info.c:69
msgid "Show location"
msgstr "Pokaži mesto"

#: app/flatpak-builtins-info.c:116
msgid "NAME [BRANCH] - Get info about an installed app or runtime"
msgstr "IME [VEJA] - Informacije o nameščeni aplikaciji ali izvajalniku"

#: app/flatpak-builtins-info.c:123 app/flatpak-builtins-remote-add.c:317
#: app/flatpak-builtins-remote-delete.c:63
msgid "NAME must be specified"
msgstr "IME mora biti navedeno"

#: app/flatpak-builtins-info.c:196
msgid "ref not present in origin"
msgstr "ref ni prisoten v izvoru"

#: app/flatpak-builtins-info.c:211 app/flatpak-builtins-remote-info.c:217
#, c-format
msgid "Warning: Commit has no flatpak metadata\n"
msgstr "Opozorilo: objava nima metapodatkov flatpak\n"

#: app/flatpak-builtins-info.c:217 app/flatpak-builtins-info.c:259
#: app/flatpak-builtins-info.c:455 app/flatpak-builtins-info.c:513
#: app/flatpak-builtins-remote-info.c:236
#: app/flatpak-builtins-remote-info.c:271
msgid "ID:"
msgstr "ID:"

#: app/flatpak-builtins-info.c:218 app/flatpak-builtins-info.c:260
#: app/flatpak-builtins-remote-info.c:237
#: app/flatpak-builtins-remote-info.c:272
msgid "Ref:"
msgstr "Ref:"

#: app/flatpak-builtins-info.c:219 app/flatpak-builtins-info.c:261
#: app/flatpak-builtins-remote-info.c:238
#: app/flatpak-builtins-remote-info.c:273
msgid "Arch:"
msgstr "Arh:"

#: app/flatpak-builtins-info.c:220 app/flatpak-builtins-info.c:262
#: app/flatpak-builtins-remote-info.c:239
#: app/flatpak-builtins-remote-info.c:274
msgid "Branch:"
msgstr "Veja:"

#: app/flatpak-builtins-info.c:222 app/flatpak-builtins-info.c:264
#: app/flatpak-builtins-remote-info.c:241
#: app/flatpak-builtins-remote-info.c:276
msgid "Version:"
msgstr "Različica:"

#: app/flatpak-builtins-info.c:224 app/flatpak-builtins-info.c:266
#: app/flatpak-builtins-remote-info.c:243
#: app/flatpak-builtins-remote-info.c:278
msgid "License:"
msgstr "Dovoljenje:"

#: app/flatpak-builtins-info.c:226 app/flatpak-builtins-info.c:269
#: app/flatpak-builtins-remote-info.c:245
#: app/flatpak-builtins-remote-info.c:280
msgid "Collection:"
msgstr "Zbirka:"

#: app/flatpak-builtins-info.c:227 app/flatpak-builtins-info.c:270
#: app/flatpak-builtins-info.c:458 app/flatpak-builtins-info.c:516
msgid "Installation:"
msgstr "Namestitev:"

#: app/flatpak-builtins-info.c:228 app/flatpak-builtins-info.c:271
#: app/flatpak-builtins-info.c:459 app/flatpak-builtins-info.c:517
#: app/flatpak-builtins-remote-info.c:249
#: app/flatpak-builtins-remote-info.c:284
msgid "Installed Size:"
msgstr "Nameščena velikost:"

#: app/flatpak-builtins-info.c:231 app/flatpak-builtins-info.c:279
#: app/flatpak-builtins-remote-info.c:252
#: app/flatpak-builtins-remote-info.c:288
msgid "Runtime:"
msgstr "Izvajalni program:"

#: app/flatpak-builtins-info.c:232 app/flatpak-builtins-info.c:288
#: app/flatpak-builtins-remote-info.c:253
#: app/flatpak-builtins-remote-info.c:293
msgid "Sdk:"
msgstr "Sdk:"

#: app/flatpak-builtins-info.c:235 app/flatpak-builtins-info.c:313
#: app/flatpak-builtins-remote-info.c:256
#: app/flatpak-builtins-remote-info.c:319
msgid "Date:"
msgstr "Datum:"

#: app/flatpak-builtins-info.c:237 app/flatpak-builtins-info.c:311
#: app/flatpak-builtins-remote-info.c:258
#: app/flatpak-builtins-remote-info.c:317
msgid "Subject:"
msgstr "Predmet:"

#: app/flatpak-builtins-info.c:240 app/flatpak-builtins-info.c:295
msgid "Active commit:"
msgstr "Aktivna uveljavitev:"

#: app/flatpak-builtins-info.c:241 app/flatpak-builtins-info.c:298
msgid "Latest commit:"
msgstr "Najnovejša uveljavitev:"

#: app/flatpak-builtins-info.c:244 app/flatpak-builtins-info.c:303
#: app/flatpak-builtins-info.c:457 app/flatpak-builtins-info.c:515
#: app/flatpak-builtins-remote-info.c:259
#: app/flatpak-builtins-remote-info.c:298
msgid "Commit:"
msgstr "Uveljavitev:"

#: app/flatpak-builtins-info.c:246 app/flatpak-builtins-info.c:308
#: app/flatpak-builtins-remote-info.c:261
#: app/flatpak-builtins-remote-info.c:303
msgid "Parent:"
msgstr "Nadrejeni:"

#: app/flatpak-builtins-info.c:248 app/flatpak-builtins-info.c:321
msgid "Alt-id:"
msgstr "Alt-id:"

#: app/flatpak-builtins-info.c:250 app/flatpak-builtins-info.c:325
#: app/flatpak-builtins-remote-info.c:263
#: app/flatpak-builtins-remote-info.c:308
msgid "End-of-life:"
msgstr "Konec življenjske dobe:"

#: app/flatpak-builtins-info.c:252 app/flatpak-builtins-info.c:330
#: app/flatpak-builtins-remote-info.c:265
#: app/flatpak-builtins-remote-info.c:313
msgid "End-of-life-rebase:"
msgstr "Preosnovanje ob koncu življenjske dobe:"

#: app/flatpak-builtins-info.c:254 app/flatpak-builtins-info.c:317
msgid "Subdirectories:"
msgstr "Podmape:"

#: app/flatpak-builtins-info.c:255 app/flatpak-builtins-info.c:454
#: app/flatpak-builtins-info.c:512
msgid "Extension:"
msgstr "Pripona:"

#: app/flatpak-builtins-info.c:267 app/flatpak-builtins-info.c:456
#: app/flatpak-builtins-info.c:514
msgid "Origin:"
msgstr "Izvor:"

#: app/flatpak-builtins-info.c:460 app/flatpak-builtins-info.c:522
msgid "Subpaths:"
msgstr "Podpoti:"

#: app/flatpak-builtins-info.c:478
msgid "unmaintained"
msgstr "nevzdrževano"

#: app/flatpak-builtins-info.c:480 app/flatpak-builtins-info.c:482
msgid "unknown"
msgstr "neznano"

#: app/flatpak-builtins-install.c:68 app/flatpak-builtins-preinstall.c:57
msgid "Don't pull, only install from local cache"
msgstr "Ne povleci, le namesti iz krajevnega predpomnilnika"

#: app/flatpak-builtins-install.c:69 app/flatpak-builtins-preinstall.c:58
#: app/flatpak-builtins-update.c:60
msgid "Don't deploy, only download to local cache"
msgstr "Ne uvajaj, samo prejmi v krajevni predpomnilnik"

#: app/flatpak-builtins-install.c:70 app/flatpak-builtins-preinstall.c:59
msgid "Don't install related refs"
msgstr "Ne nameščaj povezanih ref"

#: app/flatpak-builtins-install.c:71 app/flatpak-builtins-preinstall.c:60
#: app/flatpak-builtins-update.c:62
msgid "Don't verify/install runtime dependencies"
msgstr "Ne preverjaj/namesti odvisnosti izvajalnikov"

#: app/flatpak-builtins-install.c:72
msgid "Don't automatically pin explicit installs"
msgstr "Ne pripni samodejno eksplicitnih namestitev"

#: app/flatpak-builtins-install.c:73 app/flatpak-builtins-preinstall.c:61
#: app/flatpak-builtins-update.c:63
msgid "Don't use static deltas"
msgstr "Ne uporabljaj statičnih delt"

#: app/flatpak-builtins-install.c:76 app/flatpak-builtins-preinstall.c:62
msgid "Additionally install the SDK used to build the given refs"
msgstr "Poleg tega namesti SDK, ki se uporablja za izdelavo danih referenc"

#: app/flatpak-builtins-install.c:77 app/flatpak-builtins-preinstall.c:63
msgid ""
"Additionally install the debug info for the given refs and their dependencies"
msgstr ""
"Poleg tega namesti informacije o odpravljanju napak za dane reference in "
"njihove odvisnosti"

#: app/flatpak-builtins-install.c:78
msgid "Assume LOCATION is a .flatpak single-file bundle"
msgstr "Predpostavi, da je MESTO enodatotečni sveženj .flatpak"

#: app/flatpak-builtins-install.c:79
msgid "Assume LOCATION is a .flatpakref application description"
msgstr "Predpostavi, da je MESTO opis aplikacije .flatpakref"

#: app/flatpak-builtins-install.c:80
msgid "Assume LOCATION is containers-transports(5) reference to an OCI image"
msgstr "Predpostavi, da je MESTO sklic containers-transports(5) na sliko OCI"

#: app/flatpak-builtins-install.c:81
msgid "Check bundle signatures with GPG key from FILE (- for stdin)"
msgstr "Preverite podpise svežnja s ključem GPG iz DATOTEKE (- za stdin)"

#: app/flatpak-builtins-install.c:82
msgid "Only install this subpath"
msgstr "Namesti samo to podpot"

#: app/flatpak-builtins-install.c:83 app/flatpak-builtins-preinstall.c:64
#: app/flatpak-builtins-uninstall.c:63 app/flatpak-builtins-update.c:68
msgid "Automatically answer yes for all questions"
msgstr "Samodejno odgovori z »da« na vsa vprašanja"

#: app/flatpak-builtins-install.c:84 app/flatpak-builtins-preinstall.c:65
msgid "Uninstall first if already installed"
msgstr "Najprej odstrani, če je že nameščeno"

#: app/flatpak-builtins-install.c:85 app/flatpak-builtins-preinstall.c:66
#: app/flatpak-builtins-uninstall.c:64 app/flatpak-builtins-update.c:69
msgid "Produce minimal output and don't ask questions"
msgstr "Ustvari minimalen izhod in ne postavljaj vprašanj"

#: app/flatpak-builtins-install.c:86
msgid "Update install if already installed"
msgstr "Posodobi namestitev, če je že nameščena"

#. Translators: A sideload is when you install from a local USB drive rather than the Internet.
#: app/flatpak-builtins-install.c:88 app/flatpak-builtins-preinstall.c:68
#: app/flatpak-builtins-update.c:71
msgid "Use this local repo for sideloads"
msgstr "Uporabi to krajevno skladišče za nalaganje z naprave"

#: app/flatpak-builtins-install.c:178
msgid "Bundle filename must be specified"
msgstr "Določiti je treba ime datoteke svežnja"

#: app/flatpak-builtins-install.c:188
msgid "Remote bundles are not supported"
msgstr "Oddaljeni svežnji niso podprti"

#: app/flatpak-builtins-install.c:231
msgid "Filename or uri must be specified"
msgstr "Navesti je treba ime datoteke ali uri"

#: app/flatpak-builtins-install.c:295
msgid "Image location must be specified"
msgstr "Določiti je treba mesto slike"

#: app/flatpak-builtins-install.c:345
msgid "[LOCATION/REMOTE] [REF…] - Install applications or runtimes"
msgstr "[MESTO/ODDALJENI] [REF...] - Namestite aplikacije ali izvajalnike"

#: app/flatpak-builtins-install.c:378
msgid "At least one REF must be specified"
msgstr "Določiti je treba vsaj en REF"

#: app/flatpak-builtins-install.c:392
#, c-format
msgid "Looking for matches…\n"
msgstr "Iskanje zadetkov ...\n"

#: app/flatpak-builtins-install.c:513
#, c-format
msgid "No remote refs found for ‘%s’"
msgstr "Ni najdenih oddaljenih ref za »%s«"

#: app/flatpak-builtins-install.c:573 app/flatpak-builtins-uninstall.c:405
#: common/flatpak-ref-utils.c:689 common/flatpak-ref-utils.c:1595
#, c-format
msgid "Invalid branch %s: %s"
msgstr "Neveljavna veja %s: %s"

#: app/flatpak-builtins-install.c:606
#, c-format
msgid "Nothing matches %s in local repository for remote %s"
msgstr "Nič se ne ujema s/z %s v krajevnem skladišču za oddaljeni %s"

#: app/flatpak-builtins-install.c:608
#, c-format
msgid "Nothing matches %s in remote %s"
msgstr "Nič se ne ujema s/z %s v oddaljenem %s"

#: app/flatpak-builtins-install.c:629
#, c-format
msgid "Skipping: %s\n"
msgstr "Preskakovanje: %s\n"

#: app/flatpak-builtins-kill.c:110
#, c-format
msgid "%s is not running"
msgstr "%s se ne izvaja"

#: app/flatpak-builtins-kill.c:136
msgid "INSTANCE - Stop a running application"
msgstr "POJAVITEV – Zaustavi zagnano aplikacijo"

#: app/flatpak-builtins-kill.c:144 app/flatpak-builtins-ps.c:256
msgid "Extra arguments given"
msgstr "Podani dodatni argumenti"

#: app/flatpak-builtins-kill.c:150
msgid "Must specify the app to kill"
msgstr "Navesti morate aplikacijo za uboj"

#: app/flatpak-builtins-list.c:47
msgid "Show extra information"
msgstr "Pokaži dodatne podrobnosti"

#: app/flatpak-builtins-list.c:48
msgid "List installed runtimes"
msgstr "Izpiši seznam nameščenih izvajalnikov"

#: app/flatpak-builtins-list.c:49
msgid "List installed applications"
msgstr "Izpiši seznam nameščenih aplikacij"

#: app/flatpak-builtins-list.c:50
msgid "Arch to show"
msgstr "Arh. za prikaz"

#: app/flatpak-builtins-list.c:51 app/flatpak-builtins-remote-ls.c:57
msgid "List all refs (including locale/debug)"
msgstr "Izpiši vse ref (vključno s področnimi/razhroščevalnimi)"

#: app/flatpak-builtins-list.c:53 app/flatpak-builtins-remote-ls.c:58
msgid "List all applications using RUNTIME"
msgstr "Izpiši seznam vseh aplikacij, ki uporabljajo IZVAJALNIK"

#: app/flatpak-builtins-list.c:59 app/flatpak-builtins-remote-list.c:51
#: app/flatpak-builtins-remote-ls.c:68 app/flatpak-builtins-search.c:44
msgid "Name"
msgstr "Ime"

#: app/flatpak-builtins-list.c:59 app/flatpak-builtins-remote-list.c:51
#: app/flatpak-builtins-remote-ls.c:68 app/flatpak-builtins-search.c:44
msgid "Show the name"
msgstr "Pokaži ime"

#: app/flatpak-builtins-list.c:60 app/flatpak-builtins-remote-list.c:60
#: app/flatpak-builtins-remote-ls.c:69 app/flatpak-builtins-search.c:45
msgid "Description"
msgstr "Opis"

#: app/flatpak-builtins-list.c:60 app/flatpak-builtins-remote-ls.c:69
#: app/flatpak-builtins-search.c:45
msgid "Show the description"
msgstr "Pokaži opis"

#: app/flatpak-builtins-list.c:61 app/flatpak-builtins-remote-ls.c:70
#: app/flatpak-builtins-search.c:46
msgid "Application ID"
msgstr "ID aplikacije"

#: app/flatpak-builtins-list.c:61 app/flatpak-builtins-ps.c:52
#: app/flatpak-builtins-remote-ls.c:70 app/flatpak-builtins-search.c:46
msgid "Show the application ID"
msgstr "Pokaži ID programa"

#: app/flatpak-builtins-list.c:62 app/flatpak-builtins-remote-ls.c:71
#: app/flatpak-builtins-search.c:47
msgid "Show the version"
msgstr "Pokaži različico"

#: app/flatpak-builtins-list.c:65 app/flatpak-builtins-ps.c:56
#: app/flatpak-builtins-remote-ls.c:77
msgid "Runtime"
msgstr "Izvajalni program"

#: app/flatpak-builtins-list.c:65
msgid "Show the used runtime"
msgstr "Pokaži uporabljeni izvajalnik"

#: app/flatpak-builtins-list.c:66 app/flatpak-builtins-remote-ls.c:74
msgid "Show the origin remote"
msgstr "Pokaži izvornega oddaljenega"

#: app/flatpak-builtins-list.c:67
msgid "Show the installation"
msgstr "Pokaži namestitev"

#: app/flatpak-builtins-list.c:69
msgid "Active commit"
msgstr "Aktivna uveljavitev"

#: app/flatpak-builtins-list.c:69 app/flatpak-builtins-remote-ls.c:76
msgid "Show the active commit"
msgstr "Pokaži aktivno objavo"

#: app/flatpak-builtins-list.c:70
msgid "Latest commit"
msgstr "Najnovejša uveljavitev"

#: app/flatpak-builtins-list.c:70
msgid "Show the latest commit"
msgstr "Pokaži najnovejšo objavo"

#: app/flatpak-builtins-list.c:71 app/flatpak-builtins-remote-ls.c:78
msgid "Installed size"
msgstr "Nameščena velikost"

#: app/flatpak-builtins-list.c:71 app/flatpak-builtins-remote-ls.c:78
msgid "Show the installed size"
msgstr "Pokaži velikost nameščenega"

#: app/flatpak-builtins-list.c:72 app/flatpak-builtins-remote-list.c:58
#: app/flatpak-builtins-remote-ls.c:80 app/flatpak-builtins-repo.c:340
msgid "Options"
msgstr "Možnosti"

#: app/flatpak-builtins-list.c:72 app/flatpak-builtins-remote-list.c:58
#: app/flatpak-builtins-remote-ls.c:80
msgid "Show options"
msgstr "Pokaži možnosti"

#: app/flatpak-builtins-list.c:180
#, c-format
msgid "Unable to load details of %s: %s"
msgstr "Podrobnosti o %s ni mogoče naložiti: %s"

#: app/flatpak-builtins-list.c:190
#, c-format
msgid "Unable to inspect current version of %s: %s"
msgstr "Trenutne različice %s ni mogoče pregledati: %s"

#: app/flatpak-builtins-list.c:408
msgid " - List installed apps and/or runtimes"
msgstr " - seznam nameščenih aplikacij in/ali izvajalnikov"

#: app/flatpak-builtins-make-current.c:38
msgid "Arch to make current for"
msgstr "Arh., za katero želite izdelati sodobnika"

#: app/flatpak-builtins-make-current.c:58
msgid "APP BRANCH - Make branch of application current"
msgstr "APL VEJA - Naj bo veja aplikacije sodobna"

#: app/flatpak-builtins-make-current.c:69 app/flatpak-builtins-run.c:260
msgid "APP must be specified"
msgstr "Določiti je treba APP"

#: app/flatpak-builtins-make-current.c:84
msgid "BRANCH must be specified"
msgstr "VEJA mora biti določena"

#: app/flatpak-builtins-make-current.c:97
#, c-format
msgid "App %s branch %s is not installed"
msgstr "Aplikacija %s veja %s ni nameščena"

#: app/flatpak-builtins-mask.c:42
msgid "Remove matching masks"
msgstr "Odstrani ujemajoče maske"

#: app/flatpak-builtins-mask.c:54
msgid ""
"[PATTERN…] - disable updates and automatic installation matching patterns"
msgstr ""
"[VZOREC...] - onemogoči posodobitve in samodejne namestitve z ujemajočim "
"vzorcem"

#: app/flatpak-builtins-mask.c:73
#, c-format
msgid "No masked patterns\n"
msgstr "Ni maskiranih vzorcev\n"

#: app/flatpak-builtins-mask.c:78
#, c-format
msgid "Masked patterns:\n"
msgstr "Maskirani vzorci:\n"

#: app/flatpak-builtins-override.c:42
msgid "Remove existing overrides"
msgstr "Odstrani obstoječe preglasitve"

#: app/flatpak-builtins-override.c:43
msgid "Show existing overrides"
msgstr "Pokaži obstoječe preglasitve"

#: app/flatpak-builtins-override.c:59
msgid "[APP] - Override settings [for application]"
msgstr "[APL] - Preglasi nastavitve [za aplikacijo]"

#: app/flatpak-builtins-permission-list.c:143
msgid "[TABLE] [ID] - List permissions"
msgstr "[TABELA] [ID] - Izpiši dovoljenja"

#: app/flatpak-builtins-permission-list.c:179
#: app/flatpak-builtins-permission-show.c:142
msgid "Table"
msgstr "Tabela"

#: app/flatpak-builtins-permission-list.c:180
#: app/flatpak-builtins-permission-show.c:143
msgid "Object"
msgstr "Predmet"

#: app/flatpak-builtins-permission-list.c:181
#: app/flatpak-builtins-permission-show.c:144
msgid "App"
msgstr "Program"

#: app/flatpak-builtins-permission-list.c:183
#: app/flatpak-builtins-permission-show.c:146
msgid "Data"
msgstr "Podatki"

#: app/flatpak-builtins-permission-remove.c:120
msgid "TABLE ID [APP_ID] - Remove item from permission store"
msgstr "TABELA ID [APL_ID] - Odstrani element iz shrambe dovoljenj"

#: app/flatpak-builtins-permission-remove.c:129
#: app/flatpak-builtins-permission-set.c:120
msgid "Too few arguments"
msgstr "Premalo argumentov"

#: app/flatpak-builtins-permission-reset.c:43
msgid "Reset all permissions"
msgstr "Ponastavi vsa dovoljenja"

#: app/flatpak-builtins-permission-reset.c:144
msgid "APP_ID - Reset permissions for an app"
msgstr "PROG_ID – Ponastavi dovoljenja za aplikacijo"

#: app/flatpak-builtins-permission-reset.c:153
#: app/flatpak-builtins-permission-show.c:124
msgid "Wrong number of arguments"
msgstr "Napačno število argumentov"

#: app/flatpak-builtins-permission-set.c:42
msgid "Associate DATA with the entry"
msgstr "Poveži PODATKE z vnosom"

#: app/flatpak-builtins-permission-set.c:42
msgid "DATA"
msgstr "PODATKI"

#: app/flatpak-builtins-permission-set.c:111
msgid "TABLE ID APP_ID [PERMISSION...] - Set permissions"
msgstr "TABELA ID APL_ID [DOVOLJENEJE…] - Nastavite dovoljenja"

#: app/flatpak-builtins-permission-set.c:132
#, c-format
msgid "Failed to parse '%s' as GVariant: "
msgstr "Razčlenjevanje »%s« kot GVariant ni uspelo: "

#: app/flatpak-builtins-permission-show.c:115
msgid "APP_ID - Show permissions for an app"
msgstr "APL_ID – Pokaži dovoljenja za aplikacijo"

#: app/flatpak-builtins-pin.c:44
msgid "Remove matching pins"
msgstr "Odstrani ujemajoče se pripete"

#: app/flatpak-builtins-pin.c:56
msgid "[PATTERN…] - disable automatic removal of runtimes matching patterns"
msgstr ""
"[VZOREC...] - onemogočite samodejno odstranjevanje ujemajočih vzorcev "
"izvajalnikov"

#: app/flatpak-builtins-pin.c:75
#, c-format
msgid "No pinned patterns\n"
msgstr "Brez pripetih vzorcev\n"

#: app/flatpak-builtins-pin.c:80
#, c-format
msgid "Pinned patterns:\n"
msgstr "Pripeti vzorci:\n"

#: app/flatpak-builtins-preinstall.c:80
msgid "- Install flatpaks that are part of the operating system"
msgstr "- Namesti flatpake, ki so del operacijskega sistema"

#: app/flatpak-builtins-preinstall.c:118
#, c-format
msgid "Nothing to do.\n"
msgstr "Nič ni za storiti.\n"

#: app/flatpak-builtins-ps.c:49
msgid "Instance"
msgstr "Primerek"

#: app/flatpak-builtins-ps.c:49
msgid "Show the instance ID"
msgstr "Prikaži ID primerka"

#: app/flatpak-builtins-ps.c:50 app/flatpak-builtins-run.c:178
msgid "PID"
msgstr "PID"

#: app/flatpak-builtins-ps.c:50
msgid "Show the PID of the wrapper process"
msgstr "Pokaži PID procesa ovoja"

#: app/flatpak-builtins-ps.c:51
msgid "Child-PID"
msgstr "PID-podrejenega"

#: app/flatpak-builtins-ps.c:51
msgid "Show the PID of the sandbox process"
msgstr "Pokaži PID procesa peskovnika"

#: app/flatpak-builtins-ps.c:54 app/flatpak-builtins-search.c:48
msgid "Show the application branch"
msgstr "Pokaži vejo programa"

#: app/flatpak-builtins-ps.c:55
msgid "Show the application commit"
msgstr "Pokaži objavo programa"

#: app/flatpak-builtins-ps.c:56
msgid "Show the runtime ID"
msgstr "Pokaži ID izvajalnika"

#: app/flatpak-builtins-ps.c:57
msgid "R.-Branch"
msgstr "R.-veja"

#: app/flatpak-builtins-ps.c:57
msgid "Show the runtime branch"
msgstr "Pokaži vejo izvajalnika"

#: app/flatpak-builtins-ps.c:58
msgid "R.-Commit"
msgstr "R.-objava"

#: app/flatpak-builtins-ps.c:58
msgid "Show the runtime commit"
msgstr "Pokaži objavo izvajalnika"

#: app/flatpak-builtins-ps.c:59
msgid "Active"
msgstr "Dejaven"

#: app/flatpak-builtins-ps.c:59
msgid "Show whether the app is active"
msgstr "Pokaži, ali je aplikacija aktivna"

#: app/flatpak-builtins-ps.c:60
msgid "Background"
msgstr "Ozadje"

#: app/flatpak-builtins-ps.c:60
msgid "Show whether the app is background"
msgstr "Pokaži, ali je aplikacija v ozadju"

#: app/flatpak-builtins-ps.c:246
msgid " - Enumerate running sandboxes"
msgstr " - Oštevilči peskovnike v teku"

#: app/flatpak-builtins-remote-add.c:66
msgid "Do nothing if the provided remote exists"
msgstr "Ne stori ničesar, če obstaja podani oddaljeni"

#: app/flatpak-builtins-remote-add.c:67
msgid "LOCATION specifies a configuration file, not the repo location"
msgstr "MESTO določa prilagoditveno datoteko, ne mesto skladišča"

#: app/flatpak-builtins-remote-add.c:72 app/flatpak-builtins-remote-modify.c:78
msgid "Disable GPG verification"
msgstr "Onemogoči preverjanje GPG"

#: app/flatpak-builtins-remote-add.c:73 app/flatpak-builtins-remote-modify.c:79
msgid "Mark the remote as don't enumerate"
msgstr "Označi oddaljeni kot ne šteti"

#: app/flatpak-builtins-remote-add.c:74 app/flatpak-builtins-remote-modify.c:80
msgid "Mark the remote as don't use for deps"
msgstr "Označi oddaljeni kot ne uporabljen za odvisne"

#: app/flatpak-builtins-remote-add.c:75 app/flatpak-builtins-remote-modify.c:81
msgid "Set priority (default 1, higher is more prioritized)"
msgstr "Nastavite prednost (privzeto 1, višje je bolj prednostno)"

#: app/flatpak-builtins-remote-add.c:75 app/flatpak-builtins-remote-modify.c:81
msgid "PRIORITY"
msgstr "PREDNOST"

#: app/flatpak-builtins-remote-add.c:76
msgid "The named subset to use for this remote"
msgstr "Imenovani podnabor, ki ga želite uporabiti za to oddaljeno"

#: app/flatpak-builtins-remote-add.c:76 app/flatpak-builtins-remote-modify.c:71
msgid "SUBSET"
msgstr "PODMNOŽICA"

#: app/flatpak-builtins-remote-add.c:77 app/flatpak-builtins-remote-modify.c:82
msgid "A nice name to use for this remote"
msgstr "Lepo ime, ki ga lahko uporabite za tega oddaljenega"

#: app/flatpak-builtins-remote-add.c:78 app/flatpak-builtins-remote-modify.c:83
msgid "A one-line comment for this remote"
msgstr "Enovrstični komentar za oddaljeni"

#: app/flatpak-builtins-remote-add.c:79 app/flatpak-builtins-remote-modify.c:84
msgid "A full-paragraph description for this remote"
msgstr "Opis polnega odstavka za ta oddaljeni"

#: app/flatpak-builtins-remote-add.c:80 app/flatpak-builtins-remote-modify.c:85
msgid "URL for a website for this remote"
msgstr "URL za spletno mesto za ta oddaljeni"

#: app/flatpak-builtins-remote-add.c:81 app/flatpak-builtins-remote-modify.c:86
msgid "URL for an icon for this remote"
msgstr "URL za ikono za ta oddaljeni"

#: app/flatpak-builtins-remote-add.c:82 app/flatpak-builtins-remote-modify.c:87
msgid "Default branch to use for this remote"
msgstr "Privzeta veja za uporabo za ta oddaljeni"

#: app/flatpak-builtins-remote-add.c:84 app/flatpak-builtins-remote-modify.c:89
msgid "Import GPG key from FILE (- for stdin)"
msgstr "Uvozi ključ GPG iz DATOTEKE (- za stdin)"

#: app/flatpak-builtins-remote-add.c:85 app/flatpak-builtins-remote-modify.c:90
msgid "Load signatures from URL"
msgstr "Naloži podpise iz URL-ja"

#: app/flatpak-builtins-remote-add.c:86 app/flatpak-builtins-remote-modify.c:92
msgid "Set path to local filter FILE"
msgstr "Nastavite pot do krajevne filtrirne DATOTEKE"

#: app/flatpak-builtins-remote-add.c:87 app/flatpak-builtins-remote-modify.c:93
msgid "Disable the remote"
msgstr "Onemogočite oddaljenega"

#: app/flatpak-builtins-remote-add.c:88 app/flatpak-builtins-remote-modify.c:94
msgid "Name of authenticator"
msgstr "Ime avtentifikatorja"

#: app/flatpak-builtins-remote-add.c:90 app/flatpak-builtins-remote-modify.c:96
msgid "Autoinstall authenticator"
msgstr "Samodejno namesti avtentifikator"

#: app/flatpak-builtins-remote-add.c:91 app/flatpak-builtins-remote-modify.c:97
msgid "Don't autoinstall authenticator"
msgstr "Ne namesti samodejno preverjevalnika pristnosti"

#: app/flatpak-builtins-remote-add.c:92 app/flatpak-builtins-remote-modify.c:99
msgid "Don't follow the redirect set in the summary file"
msgstr "Ne sledi preusmeritvi, določeni v datoteki povzetka"

#: app/flatpak-builtins-remote-add.c:261 app/flatpak-builtins-remote-add.c:268
#, c-format
msgid "Can't load uri %s: %s\n"
msgstr "Uri %s ni mogoče naložiti: %s\n"

#: app/flatpak-builtins-remote-add.c:276 common/flatpak-dir.c:4643
#, c-format
msgid "Can't load file %s: %s\n"
msgstr "Datoteke %s ni mogoče naložiti: %s\n"

#: app/flatpak-builtins-remote-add.c:304
msgid "NAME LOCATION - Add a remote repository"
msgstr "IME MESTO - Dodajate oddaljeno skladišče"

#: app/flatpak-builtins-remote-add.c:331
msgid "GPG verification is required if collections are enabled"
msgstr "Preverjanje GPG je potrebno, če so zbirke omogočene"

#: app/flatpak-builtins-remote-add.c:393
#, c-format
msgid "Remote %s already exists"
msgstr "Oddaljeni %s že obstaja"

#: app/flatpak-builtins-remote-add.c:405
#: app/flatpak-builtins-remote-modify.c:340
#, c-format
msgid "Invalid authenticator name %s"
msgstr "Neveljavno ime avtentikatorja %s"

#: app/flatpak-builtins-remote-add.c:422
#, c-format
msgid "Warning: Could not update extra metadata for '%s': %s\n"
msgstr "Opozorilo: dodatnih metapodatkov za »%s« ni možno posodobiti: %s\n"

#: app/flatpak-builtins-remote-delete.c:39
msgid "Remove remote even if in use"
msgstr "Odstrani oddaljeno, tudi če je v uporabi"

#: app/flatpak-builtins-remote-delete.c:53
msgid "NAME - Delete a remote repository"
msgstr "IME - Izbriši oddaljeno skladišče"

#: app/flatpak-builtins-remote-delete.c:100
#, c-format
msgid "The following refs are installed from remote '%s':"
msgstr "Iz oddaljenega »%s« so nameščeni naslednji ref:"

#: app/flatpak-builtins-remote-delete.c:101
msgid "Remove them?"
msgstr "Ali jih želite odstraniti?"

#: app/flatpak-builtins-remote-delete.c:103
#, c-format
msgid "Can't remove remote '%s' with installed refs"
msgstr "Oddaljenega »%s« z nameščenimi ref ni mogoče odstraniti"

#: app/flatpak-builtins-remote-info.c:55
msgid "Commit to show info for"
msgstr "Objavi za prikaz informacij za"

#: app/flatpak-builtins-remote-info.c:58
msgid "Display log"
msgstr "Prikaži zapisnik"

#: app/flatpak-builtins-remote-info.c:61
msgid "Show parent"
msgstr "Pokaži nadrejene"

#: app/flatpak-builtins-remote-info.c:65 app/flatpak-builtins-remote-ls.c:60
msgid "Use local caches even if they are stale"
msgstr "Uporabi krajevne predpomnilnike, tudi če so neosveženi"

#. Translators: A sideload is when you install from a local USB drive rather than the Internet.
#: app/flatpak-builtins-remote-info.c:67 app/flatpak-builtins-remote-ls.c:62
msgid "Only list refs available as sideloads"
msgstr "Izpiši samo seznam ref na voljo kot nalaganje z naprave"

#: app/flatpak-builtins-remote-info.c:114
msgid ""
" REMOTE REF - Show information about an application or runtime in a remote"
msgstr ""
" DALJINSKO REF – Pokaži informacije o aplikaciji ali izvajalniku v daljinskem"

#: app/flatpak-builtins-remote-info.c:125
msgid "REMOTE and REF must be specified"
msgstr "ODDALJENI in REF morata biti določena"

#: app/flatpak-builtins-remote-info.c:247
#: app/flatpak-builtins-remote-info.c:282
msgid "Download Size:"
msgstr "Velikost prenosa:"

#: app/flatpak-builtins-remote-info.c:267
#: app/flatpak-builtins-remote-info.c:325
msgid "History:"
msgstr "Zgodovina:"

#: app/flatpak-builtins-remote-info.c:348
msgid " Commit:"
msgstr "Objavi:"

#: app/flatpak-builtins-remote-info.c:349
msgid " Subject:"
msgstr " Zadeva:"

#: app/flatpak-builtins-remote-info.c:350
msgid " Date:"
msgstr " Datum:"

#: app/flatpak-builtins-remote-info.c:383
#, c-format
msgid "Warning: Commit %s has no flatpak metadata\n"
msgstr "Opozorilo: objava %s nima metapodatkov flatpak\n"

#: app/flatpak-builtins-remote-list.c:43
msgid "Show remote details"
msgstr "Pokaži podrobnosti oddaljenega"

#: app/flatpak-builtins-remote-list.c:44
msgid "Show disabled remotes"
msgstr "Pokaži onemogočene oddaljene"

#: app/flatpak-builtins-remote-list.c:52
msgid "Title"
msgstr "Naslov"

#: app/flatpak-builtins-remote-list.c:52
msgid "Show the title"
msgstr "Pokaži naslov"

#: app/flatpak-builtins-remote-list.c:53
msgid "Show the URL"
msgstr "Pokaži URL"

#: app/flatpak-builtins-remote-list.c:54
msgid "Show the collection ID"
msgstr "Pokaži ID zbirke"

#: app/flatpak-builtins-remote-list.c:55 app/flatpak-builtins-repo.c:392
msgid "Subset"
msgstr "Podmnožica"

#: app/flatpak-builtins-remote-list.c:55
msgid "Show the subset"
msgstr "Pokaži podmnožico"

#: app/flatpak-builtins-remote-list.c:56
msgid "Filter"
msgstr "Filter"

#: app/flatpak-builtins-remote-list.c:56
msgid "Show filter file"
msgstr "Pokaži datoteko filtra"

#: app/flatpak-builtins-remote-list.c:57
msgid "Priority"
msgstr "Prioriteta"

#: app/flatpak-builtins-remote-list.c:57
msgid "Show the priority"
msgstr "Pokaži prioriteto"

#: app/flatpak-builtins-remote-list.c:59
msgid "Comment"
msgstr "Komentar"

#: app/flatpak-builtins-remote-list.c:59
msgid "Show comment"
msgstr "Pokaži komentar"

#: app/flatpak-builtins-remote-list.c:60
msgid "Show description"
msgstr "Pokaži opis"

#: app/flatpak-builtins-remote-list.c:61
msgid "Homepage"
msgstr "Domača stran"

#: app/flatpak-builtins-remote-list.c:61
msgid "Show homepage"
msgstr "Pokaži domačo stran"

#: app/flatpak-builtins-remote-list.c:62
msgid "Icon"
msgstr "Ikona"

#: app/flatpak-builtins-remote-list.c:62
msgid "Show icon"
msgstr "Pokaži ikono"

#: app/flatpak-builtins-remote-list.c:231
msgid " - List remote repositories"
msgstr " - Seznam oddaljenih skladišč"

#: app/flatpak-builtins-remote-ls.c:52
msgid "Show arches and branches"
msgstr "Pokaži arh. in veje"

#: app/flatpak-builtins-remote-ls.c:53
msgid "Show only runtimes"
msgstr "Pokaži samo izvajalne programe"

#: app/flatpak-builtins-remote-ls.c:54
msgid "Show only apps"
msgstr "Pokaži le programe-aplikacije"

#: app/flatpak-builtins-remote-ls.c:55
msgid "Show only those where updates are available"
msgstr "Pokaži samo tiste, za katere so na voljo posodobitve"

#: app/flatpak-builtins-remote-ls.c:56
msgid "Limit to this arch (* for all)"
msgstr "Omeji na to arhitekturo (* za vse)"

#: app/flatpak-builtins-remote-ls.c:77
msgid "Show the runtime"
msgstr "Pokaži izvajalno dat."

#: app/flatpak-builtins-remote-ls.c:79
msgid "Download size"
msgstr "Velikost prenosa"

#: app/flatpak-builtins-remote-ls.c:79
msgid "Show the download size"
msgstr "Pokaži velikost prejemanja"

#: app/flatpak-builtins-remote-ls.c:391
msgid " [REMOTE or URI] - Show available runtimes and applications"
msgstr " [ODDALJENI ali URI] - Pokaži razpoložljive izvajalnike in aplikacije"

#: app/flatpak-builtins-remote-modify.c:67
msgid "Enable GPG verification"
msgstr "Omogoči preverjanje GPG"

#: app/flatpak-builtins-remote-modify.c:68
msgid "Mark the remote as enumerate"
msgstr "Označite oddaljenega kot štetega"

#: app/flatpak-builtins-remote-modify.c:69
msgid "Mark the remote as used for dependencies"
msgstr "Označite oddaljenega kot uporabljenega za odvisnosti"

#: app/flatpak-builtins-remote-modify.c:70
msgid "Set a new URL"
msgstr "Nastavite nov URL"

#: app/flatpak-builtins-remote-modify.c:71
msgid "Set a new subset to use"
msgstr "Nastavite nov podnabor za uporabo"

#: app/flatpak-builtins-remote-modify.c:72
msgid "Enable the remote"
msgstr "Omogočite oddaljenega"

#: app/flatpak-builtins-remote-modify.c:73
msgid "Update extra metadata from the summary file"
msgstr "Posodobit dodatne metapodatke iz datoteke povzetka"

#: app/flatpak-builtins-remote-modify.c:91
msgid "Disable local filter"
msgstr "Onemogoči krajevni filter"

#: app/flatpak-builtins-remote-modify.c:95
msgid "Authenticator options"
msgstr "Možnosti preverjalnika pristnosti"

#: app/flatpak-builtins-remote-modify.c:98
msgid "Follow the redirect set in the summary file"
msgstr "Sledi preusmeritvi, določeni v datoteki povzetka"

#: app/flatpak-builtins-remote-modify.c:306
msgid "NAME - Modify a remote repository"
msgstr "IME – Spremenite oddaljeno skladišče"

#: app/flatpak-builtins-remote-modify.c:316
msgid "Remote NAME must be specified"
msgstr "Določiti je treba oddaljeno IME"

#: app/flatpak-builtins-remote-modify.c:327
#, c-format
msgid "Updating extra metadata from remote summary for %s\n"
msgstr "Posodabljanje dodatnih metapodatkov iz oddaljenega povzetka za %s\n"

#: app/flatpak-builtins-remote-modify.c:330
#, c-format
msgid "Error updating extra metadata for '%s': %s\n"
msgstr "Napaka pri posodabljanju dodatnih metapodatkov za »%s«: %s\n"

#: app/flatpak-builtins-remote-modify.c:331
#, c-format
msgid "Could not update extra metadata for %s"
msgstr "Dodatnih metapodatkov za »%s« ni možno posodobiti"

#: app/flatpak-builtins-repair.c:43
msgid "Don't make any changes"
msgstr "Ne opravi nobene spremembe"

#: app/flatpak-builtins-repair.c:44
msgid "Reinstall all refs"
msgstr "Ponovno namesti vse ref"

#: app/flatpak-builtins-repair.c:68
#, c-format
msgid "Object missing: %s.%s\n"
msgstr "Predmet manjka: %s.%s\n"

#: app/flatpak-builtins-repair.c:76
#, c-format
msgid "Object invalid: %s.%s\n"
msgstr "Predmet ni veljaven: %s.%s\n"

#: app/flatpak-builtins-repair.c:81
#, c-format
msgid "%s, deleting object\n"
msgstr "%s, brisanje predmeta\n"

#: app/flatpak-builtins-repair.c:146
#, c-format
msgid "Can't load object %s: %s\n"
msgstr "Ni mogoče naložiti predmeta %s: %s\n"

#: app/flatpak-builtins-repair.c:228
#, c-format
msgid "Commit invalid %s: %s\n"
msgstr "Neveljavna objava %s: %s\n"

#: app/flatpak-builtins-repair.c:231
#, c-format
msgid "Deleting invalid commit %s: %s\n"
msgstr "Brisanje neveljavne objave %s: %s\n"

#: app/flatpak-builtins-repair.c:261
#, c-format
msgid "Commit should be marked partial: %s\n"
msgstr "Objava mora biti označena kot delna: %s\n"

#: app/flatpak-builtins-repair.c:264
#, c-format
msgid "Marking commit as partial: %s\n"
msgstr "Označevanje objave kot delne: %s\n"

#: app/flatpak-builtins-repair.c:293
#, c-format
msgid "Problems loading data for %s: %s\n"
msgstr "Težave pri nalaganju podatkov za %s: %s\n"

#: app/flatpak-builtins-repair.c:306
#, c-format
msgid "Error reinstalling %s: %s\n"
msgstr "Napaka pri ponovni namestitvi %s: %s\n"

#: app/flatpak-builtins-repair.c:327
msgid "- Repair a flatpak installation"
msgstr "- Popravi namestitev flatpak"

#: app/flatpak-builtins-repair.c:406
#, c-format
msgid "Removing non-deployed ref %s…\n"
msgstr "Odstranjevanje neuveljavljenega ref %s ...\n"

#: app/flatpak-builtins-repair.c:411
#, c-format
msgid "Skipping non-deployed ref %s…\n"
msgstr "Preskakovanje neuveljavljenega ref %s ...\n"

#: app/flatpak-builtins-repair.c:429
#, c-format
msgid "[%d/%d] Verifying %s…\n"
msgstr "[%d/%d] Preverjanje %s ...\n"

#: app/flatpak-builtins-repair.c:435
#, c-format
msgid "Dry run: "
msgstr "Suh zagon: "

#: app/flatpak-builtins-repair.c:440
#, c-format
msgid "Deleting ref %s due to missing objects\n"
msgstr "Brisanje ref %s zaradi manjkajočih predmetov\n"

#: app/flatpak-builtins-repair.c:444
#, c-format
msgid "Deleting ref %s due to invalid objects\n"
msgstr "Brisanje res %s zaradi neveljavnih predmetov\n"

#: app/flatpak-builtins-repair.c:448
#, c-format
msgid "Deleting ref %s due to %d\n"
msgstr "Brisanje ref %s zaradi %d\n"

#: app/flatpak-builtins-repair.c:464
#, c-format
msgid "Checking remotes...\n"
msgstr "Preverjanje oddaljenih …\n"

#: app/flatpak-builtins-repair.c:482
#, c-format
msgid "Remote %s for ref %s is missing\n"
msgstr "Oddaljeni %s za ref %s manjka\n"

#: app/flatpak-builtins-repair.c:484
#, c-format
msgid "Remote %s for ref %s is disabled\n"
msgstr "Daljinski %s za ref %s je onemogočen\n"

#: app/flatpak-builtins-repair.c:490
#, c-format
msgid "Pruning objects\n"
msgstr "Obrezovanje predmetov\n"

#: app/flatpak-builtins-repair.c:498
#, c-format
msgid "Erasing .removed\n"
msgstr "Brisanje .removed\n"

#: app/flatpak-builtins-repair.c:524
#, c-format
msgid "Reinstalling refs\n"
msgstr "Ponovna namestitev ref\n"

#: app/flatpak-builtins-repair.c:526
#, c-format
msgid "Reinstalling removed refs\n"
msgstr "Ponovno nameščanje odstranjenih ref.\n"

#: app/flatpak-builtins-repair.c:551
#, c-format
msgid "While removing appstream for %s: "
msgstr "Med odstranjevanjem appstream za %s: "

#: app/flatpak-builtins-repair.c:558
#, c-format
msgid "While deploying appstream for %s: "
msgstr "Med uvajanjem appstream za %s: "

#: app/flatpak-builtins-repo.c:106
#, c-format
msgid "Repo mode: %s\n"
msgstr "NNačin skladišča: %s\n"

#: app/flatpak-builtins-repo.c:113
#, c-format
msgid "Indexed summaries: %s\n"
msgstr "Indeksirani povzetki: %s\n"

#: app/flatpak-builtins-repo.c:113 app/flatpak-builtins-repo.c:139
#: app/flatpak-builtins-repo.c:172
msgid "true"
msgstr "je resnično"

#: app/flatpak-builtins-repo.c:113 app/flatpak-builtins-repo.c:139
#: app/flatpak-builtins-repo.c:172
msgid "false"
msgstr "ni resnično"

#: app/flatpak-builtins-repo.c:121
#, c-format
msgid "Subsummaries: "
msgstr "Podpovzetki: "

#: app/flatpak-builtins-repo.c:136
#, c-format
msgid "Cache version: %d\n"
msgstr "Različica predpomnilnika: %d\n"

#: app/flatpak-builtins-repo.c:139
#, c-format
msgid "Indexed deltas: %s\n"
msgstr "Indeksirane delte: %s\n"

#: app/flatpak-builtins-repo.c:142
#, c-format
msgid "Title: %s\n"
msgstr "Naslov: %s\n"

#: app/flatpak-builtins-repo.c:145
#, c-format
msgid "Comment: %s\n"
msgstr "Komentar: %s\n"

#: app/flatpak-builtins-repo.c:148
#, c-format
msgid "Description: %s\n"
msgstr "Opis: %s\n"

#: app/flatpak-builtins-repo.c:151
#, c-format
msgid "Homepage: %s\n"
msgstr "Domača stran: %s\n"

#: app/flatpak-builtins-repo.c:154
#, c-format
msgid "Icon: %s\n"
msgstr "Ikona: %s\n"

#: app/flatpak-builtins-repo.c:157
#, c-format
msgid "Collection ID: %s\n"
msgstr "ID zbirke: %s\n"

#: app/flatpak-builtins-repo.c:160
#, c-format
msgid "Default branch: %s\n"
msgstr "Privzeta veja: %s\n"

#: app/flatpak-builtins-repo.c:163
#, c-format
msgid "Redirect URL: %s\n"
msgstr "URL preusmeritve: %s\n"

#: app/flatpak-builtins-repo.c:166
#, c-format
msgid "Deploy collection ID: %s\n"
msgstr "Uvedi ID zbirke: %s\n"

#: app/flatpak-builtins-repo.c:169
#, c-format
msgid "Authenticator name: %s\n"
msgstr "Ime preverjevalnika: %s\n"

#: app/flatpak-builtins-repo.c:172
#, c-format
msgid "Authenticator install: %s\n"
msgstr "Namestitev preverjevalnika: %s\n"

#: app/flatpak-builtins-repo.c:180
#, c-format
msgid "GPG key hash: %s\n"
msgstr "Razpršitev ključa GPG: %s\n"

#: app/flatpak-builtins-repo.c:184
#, c-format
msgid "%zd summary branches\n"
msgstr "%zd povzetka vej\n"

#: app/flatpak-builtins-repo.c:336
msgid "Installed"
msgstr "Nameščeno"

#. Translators: Download is used here as a noun
#: app/flatpak-builtins-repo.c:338 app/flatpak-cli-transaction.c:1462
msgid "Download"
msgstr "Prenesi"

#: app/flatpak-builtins-repo.c:339
msgid "Subsets"
msgstr "Podmnožice"

#: app/flatpak-builtins-repo.c:393
msgid "Digest"
msgstr "Izvleček"

#: app/flatpak-builtins-repo.c:394
msgid "History length"
msgstr "Dolžina zgodovine"

#: app/flatpak-builtins-repo.c:711
msgid "Print general information about the repository"
msgstr "Natisni splošne informacije o skladišču"

#: app/flatpak-builtins-repo.c:712
msgid "List the branches in the repository"
msgstr "Izpiši veje v skladišču"

#: app/flatpak-builtins-repo.c:713
msgid "Print metadata for a branch"
msgstr "Natisni metapodatke za vejo"

#: app/flatpak-builtins-repo.c:714
msgid "Show commits for a branch"
msgstr "Pokaži objave za podružnico"

#: app/flatpak-builtins-repo.c:715
msgid "Print information about the repo subsets"
msgstr "Natisni informacije o podskupinah skladišč"

#: app/flatpak-builtins-repo.c:716
msgid "Limit information to subsets with this prefix"
msgstr "Omeji informacije na podskupine s to predpono"

#: app/flatpak-builtins-repo.c:732
msgid "LOCATION - Repository maintenance"
msgstr "MESTO - Vzdrževanje skladišča"

#: app/flatpak-builtins-run.c:159
msgid "Command to run"
msgstr "Ukaz za izvajanje"

#: app/flatpak-builtins-run.c:160
msgid "Directory to run the command in"
msgstr "Mapa za izvajanje ukaza"

#: app/flatpak-builtins-run.c:161
msgid "Branch to use"
msgstr "Veja za uporabo"

#: app/flatpak-builtins-run.c:162
msgid "Use development runtime"
msgstr "Uporabi razvojni izvajalnik"

#: app/flatpak-builtins-run.c:163
msgid "Runtime to use"
msgstr "Izvajalnik za uporabo"

#: app/flatpak-builtins-run.c:164
msgid "Runtime version to use"
msgstr "Različica izvajalnika, ki jo želite uporabiti"

#: app/flatpak-builtins-run.c:167
msgid "Log accessibility bus calls"
msgstr "Beleži klice vodila za dostopnost"

#: app/flatpak-builtins-run.c:168
msgid "Don't proxy accessibility bus calls"
msgstr "Ne preusmerjaj klicev vodila za dostopnost"

#: app/flatpak-builtins-run.c:169
msgid "Proxy accessibility bus calls (default except when sandboxed)"
msgstr "Posreduj klice vodila za dostopnost (privzeto, razen v peskovniku)"

#: app/flatpak-builtins-run.c:170
msgid "Don't proxy session bus calls"
msgstr "Ne posreduj klicev vodila seje"

#: app/flatpak-builtins-run.c:171
msgid "Proxy session bus calls (default except when sandboxed)"
msgstr "Posredni klici vodila seje (privzeto, razen v peskovniku)"

#: app/flatpak-builtins-run.c:172
msgid "Don't start portals"
msgstr "Ne zaženi portalov"

#: app/flatpak-builtins-run.c:173
msgid "Enable file forwarding"
msgstr "Omogoči posredovanje datotek"

#: app/flatpak-builtins-run.c:174
msgid "Run specified commit"
msgstr "Zaženi določeno objavo"

#: app/flatpak-builtins-run.c:175
msgid "Use specified runtime commit"
msgstr "Uporabi navedeno objavo izvajalne datoteke"

#: app/flatpak-builtins-run.c:176
msgid "Run completely sandboxed"
msgstr "Zaženi povsem v peskovniku"

#: app/flatpak-builtins-run.c:178
msgid "Use PID as parent pid for sharing namespaces"
msgstr "Uporabi PID kot nadrejeni pid za skupno rabo imenskih prostorov"

#: app/flatpak-builtins-run.c:179
msgid "Make processes visible in parent namespace"
msgstr "Naredi procese vidne nadrejenemu imenskemu prostoru"

#: app/flatpak-builtins-run.c:180
msgid "Share process ID namespace with parent"
msgstr "Delite imenski prostor ID-ja procesa z nadrejenim"

#: app/flatpak-builtins-run.c:181
msgid "Write the instance ID to the given file descriptor"
msgstr "Zapišite ID primerka v dani opisnik datoteke"

#: app/flatpak-builtins-run.c:182
msgid "Use PATH instead of the app's /app"
msgstr "Uporaba POT namesto /app od aplikacije"

#: app/flatpak-builtins-run.c:183
#, fuzzy
msgid "Use FD instead of the app's /app"
msgstr "Uporaba POT namesto /app od aplikacije"

#: app/flatpak-builtins-run.c:183 app/flatpak-builtins-run.c:185
#: app/flatpak-builtins-run.c:187 app/flatpak-builtins-run.c:188
#: common/flatpak-context.c:2672
msgid "FD"
msgstr "FD"

#: app/flatpak-builtins-run.c:184
msgid "Use PATH instead of the runtime's /usr"
msgstr "Uporabite POT namesto /usr izvajalne"

#: app/flatpak-builtins-run.c:185
#, fuzzy
msgid "Use FD instead of the runtime's /usr"
msgstr "Uporabite POT namesto /usr izvajalne"

#: app/flatpak-builtins-run.c:186
msgid "Clear all outside environment variables"
msgstr "Počisti vse zunanje spremenljivke okolja"

#: app/flatpak-builtins-run.c:187
msgid ""
"Bind mount the file or directory referred to by FD to its canonicalized path"
msgstr ""

#: app/flatpak-builtins-run.c:188
msgid ""
"Bind mount the file or directory referred to by FD read-only to its "
"canonicalized path"
msgstr ""

#: app/flatpak-builtins-run.c:219
msgid "APP [ARGUMENT…] - Run an app"
msgstr "APL [ARGUMENT...] - Zaženite aplikacijo"

#: app/flatpak-builtins-run.c:370
#, c-format
msgid "runtime/%s/%s/%s not installed"
msgstr "runtime/%s/%s/%s ni nameščen"

#: app/flatpak-builtins-run.c:419
msgid "app-fd and app-path cannot both be used"
msgstr ""

#: app/flatpak-builtins-run.c:449
msgid "usr-fd and usr-path cannot both be used"
msgstr ""

#: app/flatpak-builtins-search.c:37
msgid "Arch to search for"
msgstr "Arh za iskanje"

#: app/flatpak-builtins-search.c:49
msgid "Remotes"
msgstr "Oddaljeni"

#: app/flatpak-builtins-search.c:49
msgid "Show the remotes"
msgstr "Pokažite oddaljene"

#: app/flatpak-builtins-search.c:244
msgid "TEXT - Search remote apps/runtimes for text"
msgstr "BESEDILO – Išči besedilo po oddaljenih aplikacijah/izvajalnikih"

#: app/flatpak-builtins-search.c:255
msgid "TEXT must be specified"
msgstr "BESEDILO je treba navedeti"

#: app/flatpak-builtins-search.c:338
msgid "No matches found"
msgstr "Ni zadetkov"

#: app/flatpak-builtins-uninstall.c:54
msgid "Arch to uninstall"
msgstr "Arh, ki jo želite odstraniti"

#: app/flatpak-builtins-uninstall.c:55
msgid "Keep ref in local repository"
msgstr "Ohrani ref v krajevnem skladišču"

#: app/flatpak-builtins-uninstall.c:56
msgid "Don't uninstall related refs"
msgstr "Ne odstrani povezanih ref."

#: app/flatpak-builtins-uninstall.c:57
msgid "Remove files even if running"
msgstr "Odstrani datoteke, tudi če se izvajajo"

#: app/flatpak-builtins-uninstall.c:60
msgid "Uninstall all"
msgstr "Odstrani vse"

#: app/flatpak-builtins-uninstall.c:61
msgid "Uninstall unused"
msgstr "Odstrani neuporabljeno"

#: app/flatpak-builtins-uninstall.c:62
msgid "Delete app data"
msgstr "Izbriši podatke aplikacije"

#: app/flatpak-builtins-uninstall.c:141
#, c-format
msgid "Delete data for %s?"
msgstr "Ali želite izbrisati podatke za %s?"

#: app/flatpak-builtins-uninstall.c:220
#, c-format
msgid "Info: applications using the extension %s%s%s branch %s%s%s:\n"
msgstr ""
"Informacije: aplikacije, ki uporabljajo razširitev %s%s%s veje %s%s%s:\n"

#: app/flatpak-builtins-uninstall.c:223
#, c-format
msgid "Info: applications using the runtime %s%s%s branch %s%s%s:\n"
msgstr ""
"Informacije: Aplikacije, ki uporabljajo izvajalno datoteko %s%s%s veje "
"%s%s%s:\n"

#: app/flatpak-builtins-uninstall.c:238
msgid "Really remove?"
msgstr "Ali res želite odstraniti?"

#: app/flatpak-builtins-uninstall.c:255
msgid "[REF…] - Uninstall applications or runtimes"
msgstr "[REF...] - Posodabljanje aplikacij ali izvajalnih datotek"

#: app/flatpak-builtins-uninstall.c:264
msgid "Must specify at least one REF, --unused, --all or --delete-data"
msgstr "Določititi morate vsaj en REF, --unused, --all ali --delete-data"

#: app/flatpak-builtins-uninstall.c:267
msgid "Must not specify REFs when using --all"
msgstr "Ni dovoljeno določati REF pri uporabi --all"

#: app/flatpak-builtins-uninstall.c:270
msgid "Must not specify REFs when using --unused"
msgstr "Ni dovoljeno določati REF pri uporabi --unused"

#: app/flatpak-builtins-uninstall.c:336
#, c-format
msgid ""
"\n"
"These runtimes in installation '%s' are pinned and won't be removed; see "
"flatpak-pin(1):\n"
msgstr ""
"\n"
"Ti izvajalniki v namestitvi »%s« so pripeti in ne bodo odstranjeni; glejte "
"flatpak-pin(1):\n"

#: app/flatpak-builtins-uninstall.c:370
#, c-format
msgid "Nothing unused to uninstall\n"
msgstr "Nič neuporabljenega ni za odstranitev\n"

#: app/flatpak-builtins-uninstall.c:444
#, c-format
msgid "No installed refs found for ‘%s’"
msgstr "Za »%s« ni bilo najdenih nameščenih ref."

#: app/flatpak-builtins-uninstall.c:447
#, c-format
msgid " with arch ‘%s’"
msgstr "z arh. »%s«"

#: app/flatpak-builtins-uninstall.c:449
#, c-format
msgid " with branch ‘%s’"
msgstr "z vejo »%s«"

#: app/flatpak-builtins-uninstall.c:456
#, c-format
msgid "Warning: %s is not installed\n"
msgstr "Opozorilo: %s ni nameščen\n"

#: app/flatpak-builtins-uninstall.c:490
#, c-format
msgid "None of the specified refs are installed"
msgstr "Nobena od navedenih ref. ni nameščena"

#: app/flatpak-builtins-uninstall.c:599
#, c-format
msgid "No app data to delete\n"
msgstr "Ni podatkov o aplikaciji za brisanje\n"

#: app/flatpak-builtins-update.c:56
msgid "Arch to update for"
msgstr "Arh. za posodobitev"

#: app/flatpak-builtins-update.c:57
msgid "Commit to deploy"
msgstr "Objava za uvajanje"

#: app/flatpak-builtins-update.c:58
msgid "Remove old files even if running"
msgstr "Odstrani stare datoteke, tudi če se izvajajo"

#: app/flatpak-builtins-update.c:59
msgid "Don't pull, only update from local cache"
msgstr "Ne povleci, samo posodobi z krajevnega predpomnilnika"

#: app/flatpak-builtins-update.c:61
msgid "Don't update related refs"
msgstr "Ne posodabljaj povezanih ref"

#: app/flatpak-builtins-update.c:66
msgid "Update appstream for remote"
msgstr "Posodobi appstream za oddaljeni"

#: app/flatpak-builtins-update.c:67
msgid "Only update this subpath"
msgstr "Posodobi le to podpot"

#: app/flatpak-builtins-update.c:90
msgid "[REF…] - Update applications or runtimes"
msgstr "[REF...] - Posodobite aplikacije ali izvajalnike"

#: app/flatpak-builtins-update.c:121
msgid "With --commit, only one REF may be specified"
msgstr "S --commit se lahko določi le en REF"

#: app/flatpak-builtins-update.c:162
#, c-format
msgid "Looking for updates…\n"
msgstr "Iskanje posodobitev ...\n"

#: app/flatpak-builtins-update.c:215
#, c-format
msgid "Unable to update %s: %s\n"
msgstr "Ni mogoče posodobiti %s: %s\n"

#: app/flatpak-builtins-update.c:274
#, fuzzy, c-format
msgid "Nothing to update.\n"
msgstr "Nič ni za storiti.\n"

#: app/flatpak-builtins-utils.c:337
#, c-format
msgid ""
"Remote ‘%s’ found in multiple installations, unable to proceed in non-"
"interactive mode"
msgstr ""
"Oddaljeni »%s« je moč najti v več namestitvah, ni možno nadaljevati v ne-"
"interaktivnem načinu"

#: app/flatpak-builtins-utils.c:346
#, c-format
msgid "Remote ‘%s’ found in multiple installations:"
msgstr "Oddaljeni »%s« najden v več namestitvah:"

#: app/flatpak-builtins-utils.c:347 app/flatpak-builtins-utils.c:442
#: app/flatpak-builtins-utils.c:538 app/flatpak-builtins-utils.c:540
#: app/flatpak-builtins-utils.c:598
msgid "Which do you want to use (0 to abort)?"
msgstr "Katero želite uporabiti (0 za prekinitev)?"

#: app/flatpak-builtins-utils.c:349
#, c-format
msgid "No remote chosen to resolve ‘%s’ which exists in multiple installations"
msgstr ""
"Noben oddaljeni ni izbran za razreševanje %s, ki obstaja v več namestitvah"

#: app/flatpak-builtins-utils.c:358
#, c-format
msgid ""
"Remote \"%s\" not found\n"
"Hint: Use flatpak remote-add to add a remote"
msgstr ""
"Oddaljeni »%s« ni najden\n"
"Namig: Za dodajanje oddaljenega uporabite flatpak remote-add"

#: app/flatpak-builtins-utils.c:364
#, c-format
msgid "Remote \"%s\" not found in the %s installation"
msgstr "Oddaljeni »%s« ni najden v namestitvi %s"

#: app/flatpak-builtins-utils.c:404
#, c-format
msgid "Multiple refs match ‘%s’, unable to proceed in non-interactive mode"
msgstr ""
"Več sklicev ref se ujema z »%s«, ni možno nadaljevati v ne-interaktivnem "
"načinu"

#. default to yes on Enter
#: app/flatpak-builtins-utils.c:430
#, c-format
msgid ""
"Found ref ‘%s’ in remote ‘%s’ (%s).\n"
"Use this ref?"
msgstr ""
"Najden ref »%s« v oddaljenem »%s« (%s).\n"
"Ali želite uporabiti ta ref?"

#: app/flatpak-builtins-utils.c:434 app/flatpak-builtins-utils.c:444
#: app/flatpak-builtins-utils.c:522 app/flatpak-builtins-utils.c:543
#, c-format
msgid "No ref chosen to resolve matches for ‘%s’"
msgstr "Noben ref ni izbran za razrešitev ujemanja za »%s«"

#: app/flatpak-builtins-utils.c:440
#, c-format
msgid "Similar refs found for ‘%s’ in remote ‘%s’ (%s):"
msgstr "Podobni ref za »%s« najdeni v oddaljenem »%s« (%s):"

#: app/flatpak-builtins-utils.c:488
#, c-format
msgid ""
"Multiple installed refs match ‘%s’, unable to proceed in non-interactive mode"
msgstr ""
"Več nameščenih sklicev (ref) se ujema z »%s«, ni možno nadaljevati v ne-"
"interaktivnem načinu"

#. default to yes on Enter
#: app/flatpak-builtins-utils.c:518
#, c-format
msgid "Found installed ref ‘%s’ (%s). Is this correct?"
msgstr "Najden nameščeni ref »%s« (%s). Ali je to pravilno?"

#: app/flatpak-builtins-utils.c:534
#, c-format
msgid "All of the above"
msgstr "Vse zgoraj navedeno"

#: app/flatpak-builtins-utils.c:535
#, c-format
msgid "Similar installed refs found for ‘%s’:"
msgstr "Podobni nameščeni ref najdeni za »%s«:"

#: app/flatpak-builtins-utils.c:579
#, c-format
msgid ""
"Multiple remotes have refs matching ‘%s’, unable to proceed in non-"
"interactive mode"
msgstr ""
"Več oddaljenih ima sklice, ki se ujemajo z »%s«, ne morejo nadaljevati v ne-"
"interaktivnem načinu"

#: app/flatpak-builtins-utils.c:597
#, c-format
msgid "Remotes found with refs similar to ‘%s’:"
msgstr "Oddaljeni, najdeni z ref, podobnimi »%s«:"

#: app/flatpak-builtins-utils.c:600
#, c-format
msgid "No remote chosen to resolve matches for ‘%s’"
msgstr "Za razrešitev ujemanja za »%s« ni izbran noben oddaljeni"

#: app/flatpak-builtins-utils.c:696 app/flatpak-builtins-utils.c:699
#, c-format
msgid "Updating appstream data for user remote %s"
msgstr "Posodabljanje podatkov appstream za uporabniški oddaljeni %s"

#: app/flatpak-builtins-utils.c:706 app/flatpak-builtins-utils.c:709
#, c-format
msgid "Updating appstream data for remote %s"
msgstr "Posodabljanje podatkov appstream za oddaljeni %s"

#: app/flatpak-builtins-utils.c:717 app/flatpak-builtins-utils.c:719
msgid "Error updating"
msgstr "Napaka pri posodabljanju"

#: app/flatpak-builtins-utils.c:755
#, c-format
msgid "Remote \"%s\" not found"
msgstr "Oddaljenega skladišča »%s« ni možno najti"

#: app/flatpak-builtins-utils.c:796
#, c-format
msgid "Ambiguous suffix: '%s'."
msgstr "Dvoumna pripona: »%s«."

#. Translators: don't translate the values
#: app/flatpak-builtins-utils.c:798 app/flatpak-builtins-utils.c:813
msgid "Possible values are :s[tart], :m[iddle], :e[nd] or :f[ull]"
msgstr ""
"Možne vrednosti so :s[tart] (začetek), :m[iddle] (sredina), :e[nd] (konec) "
"in :f[ull] (polno)"

#: app/flatpak-builtins-utils.c:811
#, c-format
msgid "Invalid suffix: '%s'."
msgstr "Neveljavna pripona: »%s«."

#: app/flatpak-builtins-utils.c:846
#, c-format
msgid "Ambiguous column: %s"
msgstr "Dvoumni stolpec: %s"

#: app/flatpak-builtins-utils.c:859
#, c-format
msgid "Unknown column: %s"
msgstr "Neznan stolpec: %s"

#: app/flatpak-builtins-utils.c:917
msgid "Available columns:\n"
msgstr "Razpoložljivi stolpci:\n"

#: app/flatpak-builtins-utils.c:927
msgid "Show all columns"
msgstr "Pokaži vse stolpce"

#: app/flatpak-builtins-utils.c:928
msgid "Show available columns"
msgstr "Pokaži razpoložljive stolpce"

#: app/flatpak-builtins-utils.c:931
msgid "Append :s[tart], :m[iddle], :e[nd] or :f[ull] to change ellipsization"
msgstr ""
"Dodatajte :s[tart], :m[iddle], :e[nd] ali :f[ull] za spremembo elipsizacije"

#: app/flatpak-builtins-utils.c:1483
#, c-format
msgid "Unknown scheme in sideload location %s"
msgstr "Neznana shema na mestu nalaganja z naprave %s"

#: app/flatpak-cli-transaction.c:96 app/flatpak-cli-transaction.c:102
#, c-format
msgid "Required runtime for %s (%s) found in remote %s\n"
msgstr "Zahtevani izvajalnik za %s (%s) najden v oddaljenem %s\n"

#: app/flatpak-cli-transaction.c:104
msgid "Do you want to install it?"
msgstr "Ali ga želite namestiti?"

#: app/flatpak-cli-transaction.c:110
#, c-format
msgid "Required runtime for %s (%s) found in remotes:"
msgstr "Zahtevani izvajalnik za %s (%s) najden v oddaljenih:"

#: app/flatpak-cli-transaction.c:112
msgid "Which do you want to install (0 to abort)?"
msgstr "Katero želite namestiti (0 za prekinitev)?"

#: app/flatpak-cli-transaction.c:132
#, c-format
msgid "Configuring %s as new remote '%s'\n"
msgstr "Prilagajanje %s kot novega oddaljenega »%s«\n"

#. default to yes on Enter
#: app/flatpak-cli-transaction.c:139
#, c-format
msgid ""
"The remote '%s', referred to by '%s' at location %s contains additional "
"applications.\n"
"Should the remote be kept for future installations?"
msgstr ""
"Oddaljeni »%s«, na katerega se sklicuje »%s« na mestu %s vsebuje dodatne "
"aplikacije.\n"
"Ali je treba oddaljenega hraniti za prihodnje namestitve?"

#. default to yes on Enter
#: app/flatpak-cli-transaction.c:147
#, c-format
msgid ""
"The application %s depends on runtimes from:\n"
"  %s\n"
"Configure this as new remote '%s'"
msgstr ""
"Aplikacija %s je odvisna od izvjalnikov od:\n"
"  %s\n"
"Prilagodi jo kot novega oddaljenega »%s«"

#. Formatted size/remaining time in seconds
#: app/flatpak-cli-transaction.c:321
#, c-format
msgid "%s/s%s%s"
msgstr "%s/s%s%s"

#. Download progress percentage, use the appropriate
#. percent format for your language
#: app/flatpak-cli-transaction.c:359
#, c-format
msgid "%3d%%"
msgstr "%3d %%"

#: app/flatpak-cli-transaction.c:414
msgid "Installing…"
msgstr "Poteka nameščanje …"

#: app/flatpak-cli-transaction.c:416
#, c-format
msgid "Installing %d/%d…"
msgstr "Nameščanje %d/%d ..."

#: app/flatpak-cli-transaction.c:421
msgid "Updating…"
msgstr "Poteka posodabljanje …"

#: app/flatpak-cli-transaction.c:423
#, c-format
msgid "Updating %d/%d…"
msgstr "Posodabljanje %d/%d ..."

#: app/flatpak-cli-transaction.c:428
msgid "Uninstalling…"
msgstr "Poteka odstranjevanje namestitve …"

#: app/flatpak-cli-transaction.c:430
#, c-format
msgid "Uninstalling %d/%d…"
msgstr "Odstranjevanje %d/%d ..."

#: app/flatpak-cli-transaction.c:496 app/flatpak-quiet-transaction.c:161
#, c-format
msgid "Info: %s was skipped"
msgstr "Informacije: %s je bil preskočen"

#: app/flatpak-cli-transaction.c:519
#, c-format
msgid "Warning: %s%s%s already installed"
msgstr "Opozorilo: %s%s%s je že nameščen"

#: app/flatpak-cli-transaction.c:522
#, c-format
msgid "Error: %s%s%s already installed"
msgstr "Napaka: %s%s%s je že nameščen"

#: app/flatpak-cli-transaction.c:528
#, c-format
msgid "Warning: %s%s%s not installed"
msgstr "Opozorilo: %s%s%s ni nameščen"

#: app/flatpak-cli-transaction.c:531
#, c-format
msgid "Error: %s%s%s not installed"
msgstr "Napaka: %s%s%s ni nameščen"

#: app/flatpak-cli-transaction.c:537
#, c-format
msgid "Warning: %s%s%s needs a later flatpak version"
msgstr "Opozorilo: %s%s%s potrebuje novejšo različico flatpaka"

#: app/flatpak-cli-transaction.c:540
#, c-format
msgid "Error: %s%s%s needs a later flatpak version"
msgstr "Napaka: %s%s%s potrebuje novejšo različico flatpaka"

#: app/flatpak-cli-transaction.c:546
msgid "Warning: Not enough disk space to complete this operation"
msgstr "Opozorilo: za dokončanje te operacije ni dovolj prostora na disku"

#: app/flatpak-cli-transaction.c:548
msgid "Error: Not enough disk space to complete this operation"
msgstr "Napaka: za dokončanje te operacije ni dovolj prostora na disku"

#: app/flatpak-cli-transaction.c:553
#, c-format
msgid "Warning: %s"
msgstr "Opozorilo: %s"

#: app/flatpak-cli-transaction.c:555
#, c-format
msgid "Error: %s"
msgstr "Napaka: %s"

#: app/flatpak-cli-transaction.c:570
#, c-format
msgid "Failed to install %s%s%s: "
msgstr "Namestitev %s%s%s ni uspela: "

#: app/flatpak-cli-transaction.c:577
#, c-format
msgid "Failed to update %s%s%s: "
msgstr "Posodobitev %s%s%s ni uspela: "

#: app/flatpak-cli-transaction.c:584
#, c-format
msgid "Failed to install bundle %s%s%s: "
msgstr "Namestitev svežnja %s%s%s ni uspela: "

#: app/flatpak-cli-transaction.c:591
#, c-format
msgid "Failed to uninstall %s%s%s: "
msgstr "Odstranitev %s%s%s ni uspela: "

#: app/flatpak-cli-transaction.c:642
#, c-format
msgid "Authentication required for remote '%s'\n"
msgstr "Preverjanje pristnosti je potrebno za oddaljeni »%s«\n"

#: app/flatpak-cli-transaction.c:643
msgid "Open browser?"
msgstr "Želite odpreti brskalnik?"

#: app/flatpak-cli-transaction.c:699
#, c-format
msgid "Login required remote %s (realm %s)\n"
msgstr "Prijava je potrebna za oddaljeni %s (območje %s)\n"

#: app/flatpak-cli-transaction.c:704
msgid "Password"
msgstr "Geslo"

#. Only runtimes can be pinned
#: app/flatpak-cli-transaction.c:759
#, c-format
msgid ""
"\n"
"Info: (pinned) runtime %s%s%s branch %s%s%s is end-of-life, in favor of "
"%s%s%s branch %s%s%s\n"
msgstr ""
"\n"
"Informacije: (pripeti) izvajalnik %s%s%s veje %s%s%s je dosegel konec "
"življenjske dobe, v korist %s%s%s veje %s%s%s\n"

#: app/flatpak-cli-transaction.c:765
#, c-format
msgid ""
"\n"
"Info: runtime %s%s%s branch %s%s%s is end-of-life, in favor of %s%s%s branch "
"%s%s%s\n"
msgstr ""
"\n"
"Informacije: izvajalnik %s%s%s veje %s%s%s je dosegel konec življenjske "
"dobe, v korist %s%s%s veje %s%s%s\n"

#: app/flatpak-cli-transaction.c:768
#, c-format
msgid ""
"\n"
"Info: app %s%s%s branch %s%s%s is end-of-life, in favor of %s%s%s branch "
"%s%s%s\n"
msgstr ""
"\n"
"Informacije: aplikacija %s%s%s veje %s%s%s je dosegla konec življenjske "
"dobe, v korist %s%s%s veje %s%s%s\n"

#. Only runtimes can be pinned
#: app/flatpak-cli-transaction.c:780
#, c-format
msgid ""
"\n"
"Info: (pinned) runtime %s%s%s branch %s%s%s is end-of-life, with reason:\n"
msgstr ""
"\n"
"Informacije: (pripeti) izvajalnik %s%s%s veje %s%s%s je dosegel konec "
"življenjske dobe, razlog:\n"

#: app/flatpak-cli-transaction.c:786
#, c-format
msgid ""
"\n"
"Info: runtime %s%s%s branch %s%s%s is end-of-life, with reason:\n"
msgstr ""
"\n"
"Informacije:  izvajalnik %s%s%s veje %s%s%s je dosegel konec življenjske "
"dobe, razlog:\n"

#: app/flatpak-cli-transaction.c:789
#, c-format
msgid ""
"\n"
"Info: app %s%s%s branch %s%s%s is end-of-life, with reason:\n"
msgstr ""
"\n"
"Informacije: aplikacija %s%s%s veje %s%s%s je dosegla konec življenjske "
"dobe, razlog:\n"

#: app/flatpak-cli-transaction.c:963
#, c-format
msgid "Info: applications using this extension:\n"
msgstr "Informacije: Aplikacije, ki uporabljajo to razširitev:\n"

#: app/flatpak-cli-transaction.c:965
#, c-format
msgid "Info: applications using this runtime:\n"
msgstr "Informacije: Aplikacije, ki uporabljajo ta izvajalni program:\n"

#: app/flatpak-cli-transaction.c:984
msgid "Replace?"
msgstr "Ali želite zamenjati?"

#: app/flatpak-cli-transaction.c:987 app/flatpak-quiet-transaction.c:247
#, c-format
msgid "Updating to rebased version\n"
msgstr "Posodabljanje v preosnovano različico\n"

#: app/flatpak-cli-transaction.c:1011
#, c-format
msgid "Failed to rebase %s to %s: "
msgstr "Ni bilo mogoče preosnovati %s na %s: "

#: app/flatpak-cli-transaction.c:1277
#, c-format
msgid "New %s%s%s permissions:"
msgstr "Nova dovoljenja %s%s%s:"

#: app/flatpak-cli-transaction.c:1279
#, c-format
msgid "%s%s%s permissions:"
msgstr "Dovoljenja %s%s%s:"

#: app/flatpak-cli-transaction.c:1343
msgid "Warning: "
msgstr "Opozorilo: "

#. translators: This is short for operation, the title of a one-char column
#: app/flatpak-cli-transaction.c:1442
msgid "Op"
msgstr "Op"

#. Avoid resizing the download column too much,
#. * by making the title as long as typical content
#.
#: app/flatpak-cli-transaction.c:1458 app/flatpak-cli-transaction.c:1503
msgid "partial"
msgstr "delno"

#: app/flatpak-cli-transaction.c:1535
msgid "Proceed with these changes to the user installation?"
msgstr "Ali želite nadaljevati s temi spremembami uporabniške namestitve?"

#: app/flatpak-cli-transaction.c:1537
msgid "Proceed with these changes to the system installation?"
msgstr "Ali želite nadaljevati s temi spremembami sistemske namestitve?"

#: app/flatpak-cli-transaction.c:1539
#, c-format
msgid "Proceed with these changes to the %s?"
msgstr "Ali želite nadaljevati s temi spremembami %s?"

#: app/flatpak-cli-transaction.c:1711
msgid "Changes complete."
msgstr "Spremembe so dokončane."

#: app/flatpak-cli-transaction.c:1713
msgid "Uninstall complete."
msgstr "Odstranitev je končana."

#: app/flatpak-cli-transaction.c:1715
msgid "Installation complete."
msgstr "Namestitev končana."

#: app/flatpak-cli-transaction.c:1717
msgid "Updates complete."
msgstr "Posodobitve dokončane."

#. For updates/!stop_on_first_error we already printed all errors so we make up
#. a different one.
#: app/flatpak-cli-transaction.c:1750
msgid "There were one or more errors"
msgstr "Prišlo je do ene ali več napak"

#. translators: please keep the leading space
#: app/flatpak-main.c:76
msgid " Manage installed applications and runtimes"
msgstr " Upravljajte nameščene aplikacije in izvajalnike"

#: app/flatpak-main.c:77
msgid "Install an application or runtime"
msgstr "Namestite aplikacijo ali izvajalnik"

#: app/flatpak-main.c:78
msgid "Update an installed application or runtime"
msgstr "Posodobite nameščeno aplikacijo ali izvajalno datoteko"

#: app/flatpak-main.c:81
msgid "Uninstall an installed application or runtime"
msgstr "Odstranite nameščeno aplikacijo ali izvajalno datoteko"

#: app/flatpak-main.c:84
msgid "Mask out updates and automatic installation"
msgstr "Prikrivaj posodobitve in samodejno nameščanje"

#: app/flatpak-main.c:85
msgid "Pin a runtime to prevent automatic removal"
msgstr "Pripnite izvajalnik, da preprečite samodejno odstranjevanje"

#: app/flatpak-main.c:86
msgid "List installed apps and/or runtimes"
msgstr "Izpiši seznam nameščenih aplikacij in/ali izvajalnikov"

#: app/flatpak-main.c:87
msgid "Show info for installed app or runtime"
msgstr "Pokaži informacije za nameščeno aplikacijo ali izvajalnik"

#: app/flatpak-main.c:88
msgid "Show history"
msgstr "Pokaži zgodovino"

#: app/flatpak-main.c:89
msgid "Configure flatpak"
msgstr "Prilagodi flatpak"

#: app/flatpak-main.c:90
msgid "Repair flatpak installation"
msgstr "Popravi namestitev flatpak"

#: app/flatpak-main.c:91
msgid "Put applications or runtimes onto removable media"
msgstr "Postavi aplikacije ali izvajalnik na izmenljive medije"

#: app/flatpak-main.c:92
msgid "Install flatpaks that are part of the operating system"
msgstr "Namesti flatpake, ki so del operacijskega sistema"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:95
msgid ""
"\n"
" Find applications and runtimes"
msgstr ""
"\n"
"Poiščite aplikacije in izvajalnike"

#: app/flatpak-main.c:96
msgid "Search for remote apps/runtimes"
msgstr "Iskanje oddaljenih aplikacij/izvajalnikov"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:99
msgid ""
"\n"
" Manage running applications"
msgstr ""
"\n"
"Upravljaj aplikacije v izvajanju"

#: app/flatpak-main.c:100
msgid "Run an application"
msgstr "Zaženite aplikacijo"

#: app/flatpak-main.c:101
msgid "Override permissions for an application"
msgstr "Preglasi dovoljenja za program"

#: app/flatpak-main.c:102
msgid "Specify default version to run"
msgstr "Navedite privzeto različico, ki jo želite zagnati"

#: app/flatpak-main.c:103
msgid "Enter the namespace of a running application"
msgstr "Vnesite imenski prostor za program v izvajanju"

#: app/flatpak-main.c:104
msgid "Enumerate running applications"
msgstr "Oštevilči izvajajoče se aplikacije"

#: app/flatpak-main.c:105
msgid "Stop a running application"
msgstr "Zaustavite izvajajoči se program"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:108
msgid ""
"\n"
" Manage file access"
msgstr ""
"\n"
"Upravljajte dostop do datotek"

#: app/flatpak-main.c:109
msgid "List exported files"
msgstr "Seznam izvoženih datotek"

#: app/flatpak-main.c:110
msgid "Grant an application access to a specific file"
msgstr "Odobrite dostop aplikaciji do določene datoteke"

#: app/flatpak-main.c:111
msgid "Revoke access to a specific file"
msgstr "Prekliči dostop do določene datoteke"

#: app/flatpak-main.c:112
msgid "Show information about a specific file"
msgstr "Prikaz informacij o določeni datoteki"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:116
msgid ""
"\n"
" Manage dynamic permissions"
msgstr ""
"\n"
"Upravljaj dinamične pravice"

#: app/flatpak-main.c:117
msgid "List permissions"
msgstr "Izpiši dovoljenja"

#: app/flatpak-main.c:118
msgid "Remove item from permission store"
msgstr "Odstrani element iz shrambe dovoljenj"

#: app/flatpak-main.c:120
msgid "Set permissions"
msgstr "Nastavi dovoljenja"

#: app/flatpak-main.c:121
msgid "Show app permissions"
msgstr "Pokaži dovoljenja za aplikacijo"

#: app/flatpak-main.c:122
msgid "Reset app permissions"
msgstr "Ponastavi dovoljenja za aplikacije"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:125
msgid ""
"\n"
" Manage remote repositories"
msgstr ""
"\n"
" Upravljaj oddaljena skladišča"

#: app/flatpak-main.c:126
msgid "List all configured remotes"
msgstr "Izpiši seznam vseh nastavljenih oddaljenih"

#: app/flatpak-main.c:127
msgid "Add a new remote repository (by URL)"
msgstr "Dodajte novo oddaljeno skladišče (po URL-ju)"

#: app/flatpak-main.c:128
msgid "Modify properties of a configured remote"
msgstr "Spremenite lastnosti prilagojenega oddaljenega"

#: app/flatpak-main.c:129
msgid "Delete a configured remote"
msgstr "Izbrišite nastavljeni oddaljeni"

#: app/flatpak-main.c:131
msgid "List contents of a configured remote"
msgstr "Izpišite seznam nastavljenega oddaljenega"

#: app/flatpak-main.c:132
msgid "Show information about a remote app or runtime"
msgstr "Pokaži informacije o aplikaciji ali izvajalniku oddaljenega"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:135
msgid ""
"\n"
" Build applications"
msgstr ""
"\n"
"Gradi aplikacije"

#: app/flatpak-main.c:136
msgid "Initialize a directory for building"
msgstr "Inicializiraj mapo za gradnjo"

#: app/flatpak-main.c:137
msgid "Run a build command inside the build dir"
msgstr "Zaženite ukaz za gradnjo znotraj mape za gradnjo"

#: app/flatpak-main.c:138
msgid "Finish a build dir for export"
msgstr "Dokončajte mapo gradnje za izvoz"

#: app/flatpak-main.c:139
msgid "Export a build dir to a repository"
msgstr "Izvozite mapo gradnje v skladišče"

#: app/flatpak-main.c:140
msgid "Create a bundle file from a ref in a local repository"
msgstr "Ustvarjanje datoteke svežnja iz sklica ref v krajevnem skladišču"

#: app/flatpak-main.c:141
msgid "Import a bundle file"
msgstr "Uvozite datoteko svežnja"

#: app/flatpak-main.c:142
msgid "Sign an application or runtime"
msgstr "Podpišite program ali izvajalno datoteko"

#: app/flatpak-main.c:143
msgid "Update the summary file in a repository"
msgstr "Posodobite datoteko povzetka v skladišču"

#: app/flatpak-main.c:144
msgid "Create new commit based on existing ref"
msgstr "Ustvarite novo objavo na podlagi obstoječe ref"

#: app/flatpak-main.c:145
msgid "Show information about a repo"
msgstr "Pokaži podatke o skladišču"

#: app/flatpak-main.c:162
msgid "Show debug information, -vv for more detail"
msgstr "Pokaži informacije za odpravljanje napak, -vv za več podrobnosti"

#: app/flatpak-main.c:163
msgid "Show OSTree debug information"
msgstr "Pokaži informacije za odpravljanje napak OSTree"

#: app/flatpak-main.c:169
msgid "Print version information and exit"
msgstr "Izpiši podatke o različici in končaj"

#: app/flatpak-main.c:170
msgid "Print default arch and exit"
msgstr "Izpiši privzeto arh in končaj"

#: app/flatpak-main.c:171
msgid "Print supported arches and exit"
msgstr "Izpiši podprte arh in končaj"

#: app/flatpak-main.c:172
msgid "Print active gl drivers and exit"
msgstr "Izpiši aktivne gonilnike GL in končaj"

#: app/flatpak-main.c:173
msgid "Print paths for system installations and exit"
msgstr "Izpiši poti za sistemske namestitve in končaj"

#: app/flatpak-main.c:174
msgid "Print the updated environment needed to run flatpaks"
msgstr "Izpiši posodobljeno okolje, potrebno za zagon flatpaks"

#: app/flatpak-main.c:175
msgid "Only include the system installation with --print-updated-env"
msgstr "Vključi samo sistemsko namestitev s --print-updated-env"

#: app/flatpak-main.c:180
msgid "Work on the user installation"
msgstr "Delo na uporabniški namestitvi"

#: app/flatpak-main.c:181
msgid "Work on the system-wide installation (default)"
msgstr "Delo na vse-sistemski namestitvi (privzeto)"

#: app/flatpak-main.c:182
msgid "Work on a non-default system-wide installation"
msgstr "Delo na ne privzeti vse-sistemski namestitvi"

#: app/flatpak-main.c:212
msgid "Builtin Commands:"
msgstr "Vgrajeni ukazi:"

#: app/flatpak-main.c:298
#, c-format
msgid ""
"Note that the directories %s are not in the search path set by the "
"XDG_DATA_DIRS environment variable, so applications installed by Flatpak may "
"not appear on your desktop until the session is restarted."
msgstr ""
"Upoštevajte, da mape %s niso v poti iskanja, ki jo določa spremenljivka "
"okolja XDG_DATA_DIRS, zato se aplikacije, ki jih namesti Flatpak, morda ne "
"bodo pojavile na namizju, dokler se seja ne bo znova zagnala."

#: app/flatpak-main.c:312
#, c-format
msgid ""
"Note that the directory %s is not in the search path set by the "
"XDG_DATA_DIRS environment variable, so applications installed by Flatpak may "
"not appear on your desktop until the session is restarted."
msgstr ""
"Upoštevajte, da mapa %s ni v poti iskanja, ki jo določa spremenljivka okolja "
"XDG_DATA_DIRS, zato se aplikacije, ki jih namesti Flatpak, morda ne bodo "
"pojavile na namizju, dokler se seja ne bo znova zagnala."

#: app/flatpak-main.c:381
msgid ""
"Refusing to operate under sudo with --user. Omit sudo to operate on the user "
"installation, or use a root shell to operate on the root user's installation."
msgstr ""
"Zavračanje delovanja pod sudo z --user. Izpustite sudo za delovanje na "
"uporabniški namestitvi ali uporabite korensko lupino za delovanje na "
"namestitvi korenskega uporabnika."

#: app/flatpak-main.c:453
msgid ""
"Multiple installations specified for a command that works on one installation"
msgstr "Več namestitev, določenih za ukaz, ki deluje na eni namestitvi"

#: app/flatpak-main.c:504 app/flatpak-main.c:697
#, c-format
msgid "See '%s --help'"
msgstr "Glejte »%s --help«"

#: app/flatpak-main.c:706
#, c-format
msgid "'%s' is not a flatpak command. Did you mean '%s%s'?"
msgstr "»%s« ni ukaz flatpak. Ste mislili »%s%s«?"

#: app/flatpak-main.c:709
#, c-format
msgid "'%s' is not a flatpak command"
msgstr "»%s« ni ukaz flatpak"

#: app/flatpak-main.c:824
msgid "No command specified"
msgstr "Ukaz ni določen"

#: app/flatpak-main.c:980
msgid "error:"
msgstr "napaka:"

#: app/flatpak-quiet-transaction.c:77
#, c-format
msgid "Installing %s\n"
msgstr "Nameščanje %s\n"

#: app/flatpak-quiet-transaction.c:81
#, c-format
msgid "Updating %s\n"
msgstr "Posodabljanje %s\n"

#: app/flatpak-quiet-transaction.c:85
#, c-format
msgid "Uninstalling %s\n"
msgstr "Odstranjevanje %s\n"

#: app/flatpak-quiet-transaction.c:107
#, c-format
msgid "Warning: Failed to install %s: %s\n"
msgstr "Opozorilo: Namestitev %s ni uspela: %s\n"

#: app/flatpak-quiet-transaction.c:110
#, c-format
msgid "Error: Failed to install %s: %s\n"
msgstr "Napaka: namestitev %s ni uspela: %s\n"

#: app/flatpak-quiet-transaction.c:116
#, c-format
msgid "Warning: Failed to update %s: %s\n"
msgstr "Opozorilo: Ni mogoče posodobiti %s: %s\n"

#: app/flatpak-quiet-transaction.c:119
#, c-format
msgid "Error: Failed to update %s: %s\n"
msgstr "Napaka: Neuspešna posodobitev %s: %s\n"

#: app/flatpak-quiet-transaction.c:125
#, c-format
msgid "Warning: Failed to install bundle %s: %s\n"
msgstr "Opozorilo: Ni bilo mogoče namestiti svežnja %s: %s\n"

#: app/flatpak-quiet-transaction.c:128
#, c-format
msgid "Error: Failed to install bundle %s: %s\n"
msgstr "Napaka: Namestitev svežnja %s ni uspela: %s\n"

#: app/flatpak-quiet-transaction.c:134
#, c-format
msgid "Warning: Failed to uninstall %s: %s\n"
msgstr "Opozorilo: Odstranitev %s ni uspela: %s\n"

#: app/flatpak-quiet-transaction.c:137
#, c-format
msgid "Error: Failed to uninstall %s: %s\n"
msgstr "Napaka: Odstranitev %s ni uspela: %s\n"

#: app/flatpak-quiet-transaction.c:166 common/flatpak-dir.c:11475
#, c-format
msgid "%s already installed"
msgstr "%s je že nameščen"

#: app/flatpak-quiet-transaction.c:168 common/flatpak-dir.c:3622
#: common/flatpak-dir.c:4321 common/flatpak-dir.c:16968
#: common/flatpak-dir.c:17258 common/flatpak-dir-utils.c:166
#: common/flatpak-dir-utils.c:259 common/flatpak-transaction.c:2736
#: common/flatpak-transaction.c:2791
#, c-format
msgid "%s not installed"
msgstr "%s ni nameščen"

#: app/flatpak-quiet-transaction.c:170
#, c-format
msgid "%s needs a later flatpak version"
msgstr "%s potrebuje novejšo različico flatpak"

#: app/flatpak-quiet-transaction.c:172
msgid "Not enough disk space to complete this operation"
msgstr "Za dokončanje te operacije ni dovolj prostora na disku"

#: app/flatpak-quiet-transaction.c:239
#, c-format
msgid "Info: %s is end-of-life, in favor of %s\n"
msgstr "Informacije: %s je dosegla konec življenjske dobe, v korist %s\n"

#: app/flatpak-quiet-transaction.c:241
#, c-format
msgid "Info: %s is end-of-life, with reason: %s\n"
msgstr "Informacije: %s je dosegla konec življenjske dobe, z razlogom: %s\n"

#: app/flatpak-quiet-transaction.c:251
#, c-format
msgid "Failed to rebase %s to %s: %s\n"
msgstr "Ni bilo mogoče preosnovati %s na %s: %s\n"

#: common/flatpak-auth.c:58
#, c-format
msgid "No authenticator configured for remote `%s`"
msgstr "Ni avtentikatorja, nastavljenega za oddaljeni »%s«"

#: common/flatpak-context.c:637 common/flatpak-context.c:649
#, c-format
msgid "Invalid permission syntax: %s"
msgstr "Neveljavna skladnja dovoljenja: %s"

#: common/flatpak-context.c:1207
#, c-format
msgid "Unknown share type %s, valid types are: %s"
msgstr "Neznana vrsta skupne rabe %s, veljavne vrste so: %s"

#: common/flatpak-context.c:1228
#, c-format
msgid "Unknown policy type %s, valid types are: %s"
msgstr "Neznana vrsta pravil %s, veljavne vrste so: %s"

#: common/flatpak-context.c:1266
#, c-format
msgid "Invalid dbus name %s"
msgstr "Neveljavno ime dbus-a %s"

#: common/flatpak-context.c:1279
#, c-format
msgid "Unknown socket type %s, valid types are: %s"
msgstr "Neznana vrsta vtičnice %s, veljavne vrste so: %s"

#: common/flatpak-context.c:1294
#, c-format
msgid "Unknown device type %s, valid types are: %s"
msgstr "Neznana vrsta naprave %s, veljavne vrste so: %s"

#: common/flatpak-context.c:1308
#, c-format
msgid "Unknown feature type %s, valid types are: %s"
msgstr "Neznana vrsta funkcije %s, veljavne vrste so: %s"

#: common/flatpak-context.c:1840
#, c-format
msgid "Filesystem location \"%s\" contains \"..\""
msgstr "Mesto datotečnega sistema »%s« vsebuje »..«"

#: common/flatpak-context.c:1882
#, c-format
msgid ""
"--filesystem=/ is not available, use --filesystem=host for a similar result"
msgstr ""
"--filesystem=/ ni na voljo, uporabite --filesystem=host za podoben rezultat"

#: common/flatpak-context.c:1916
#, c-format
msgid ""
"Unknown filesystem location %s, valid locations are: host, host-os, host-"
"etc, host-root, home, xdg-*[/…], ~/dir, /dir"
msgstr ""
"Neznano mesto datotečnega sistema %s, veljavna mesta so: host, host-os, host-"
"etc, host-root, home, xdg-*[/…], ~/dir, /dir"

#: common/flatpak-context.c:2015
#, c-format
msgid "Invalid syntax for %s: %s"
msgstr "Neveljavna skladnja za %s: %s"

#: common/flatpak-context.c:2142
#, c-format
msgid "fallback-x11 can not be conditional"
msgstr "fallback-x11 ne more biti pogojen"

#: common/flatpak-context.c:2318
#, c-format
msgid "Invalid env format %s"
msgstr "Neveljavna oblika env %s"

#: common/flatpak-context.c:2399
#, c-format
msgid "Environment variable name must not contain '=': %s"
msgstr "Ime spremenljivke okolja ne sme vsebovati »=«: %s"

#: common/flatpak-context.c:2527 common/flatpak-context.c:2535
#, c-format
msgid "--add-policy arguments must be in the form SUBSYSTEM.KEY=VALUE"
msgstr "Argumenti --add-policy morajo biti v obliki PODSISTEM.KLJUČ=VREDNOST"

#: common/flatpak-context.c:2542
#, c-format
msgid "--add-policy values can't start with \"!\""
msgstr "Vrednosti --add-policy se ne morejo začeti z »!«"

#: common/flatpak-context.c:2567 common/flatpak-context.c:2575
#, c-format
msgid "--remove-policy arguments must be in the form SUBSYSTEM.KEY=VALUE"
msgstr ""
"Argumenti --remove-policy morajo biti v obliki PODSISTEM.KLJUČ=VREDNOST"

#: common/flatpak-context.c:2582
#, c-format
msgid "--remove-policy values can't start with \"!\""
msgstr "Vrednosti --remove-policy se ne morejo začeti z »!«"

#: common/flatpak-context.c:2657
msgid "Share with host"
msgstr "Skupna raba z gostiteljem"

#: common/flatpak-context.c:2657 common/flatpak-context.c:2658
msgid "SHARE"
msgstr "DELI"

#: common/flatpak-context.c:2658
msgid "Unshare with host"
msgstr "Preklic skupne rabe z gostiteljem"

#: common/flatpak-context.c:2659
msgid "Require conditions to be met for a subsystem to get shared"
msgstr "Zahtevaj izpolnjene pogoje, da se podsistem deli v skupni rabi"

#: common/flatpak-context.c:2659
msgid "SHARE:CONDITION"
msgstr "SKUPNARABA:POGOJ"

#: common/flatpak-context.c:2660
msgid "Expose socket to app"
msgstr "Razkrij vtičnico aplikaciji"

#: common/flatpak-context.c:2660 common/flatpak-context.c:2661
msgid "SOCKET"
msgstr "VTIČNICA"

#: common/flatpak-context.c:2661
msgid "Don't expose socket to app"
msgstr "Ne razkrij vtičnice aplikaciji"

#: common/flatpak-context.c:2662
msgid "Require conditions to be met for a socket to get exposed"
msgstr "Zahtevaj izpolnjene pogoje, da se vtičnica izpostavi"

#: common/flatpak-context.c:2662
msgid "SOCKET:CONDITION"
msgstr "VTIČNICA:POGOJ"

#: common/flatpak-context.c:2663
msgid "Expose device to app"
msgstr "Razkrij napravo aplikaciji"

#: common/flatpak-context.c:2663 common/flatpak-context.c:2664
msgid "DEVICE"
msgstr "NAPRAVA"

#: common/flatpak-context.c:2664
msgid "Don't expose device to app"
msgstr "Naprave ne razkrij aplikaciji"

#: common/flatpak-context.c:2665
msgid "Require conditions to be met for a device to get exposed"
msgstr "Zahtevaj izpolnjene pogoje, da se naprava izpostavi"

#: common/flatpak-context.c:2665
msgid "DEVICE:CONDITION"
msgstr "NAPRAVA:POGOJ"

#: common/flatpak-context.c:2666
msgid "Allow feature"
msgstr "Dovoli funkcijo"

#: common/flatpak-context.c:2666 common/flatpak-context.c:2667
msgid "FEATURE"
msgstr "FUNKCIJA"

#: common/flatpak-context.c:2667
msgid "Don't allow feature"
msgstr "Ne dovoli funkcije"

#: common/flatpak-context.c:2668
msgid "Require conditions to be met for a feature to get allowed"
msgstr "Zahtevaj izpolnjene pogoje, da bo funkcija dovoljena"

#: common/flatpak-context.c:2668
msgid "FEATURE:CONDITION"
msgstr "FUNKCIJA:POGOJ"

#: common/flatpak-context.c:2669
msgid "Expose filesystem to app (:ro for read-only)"
msgstr "Razrkij datotečni sistem aplikaciji (:ro samo za branje)"

#: common/flatpak-context.c:2669
msgid "FILESYSTEM[:ro]"
msgstr "DATOTEČNISISTEM[:RO]"

#: common/flatpak-context.c:2670
msgid "Don't expose filesystem to app"
msgstr "Ne razkrij datotečnega sistema aplikaciji"

#: common/flatpak-context.c:2670
msgid "FILESYSTEM"
msgstr "DATOTEČNISISTEM"

#: common/flatpak-context.c:2671
msgid "Set environment variable"
msgstr "Nastavi spremenljivko okolja"

#: common/flatpak-context.c:2671
msgid "VAR=VALUE"
msgstr "SPREMENLJIVKA=VREDNOST"

#: common/flatpak-context.c:2672
msgid "Read environment variables in env -0 format from FD"
msgstr "Beri spremenljivke okolja v obliki env -0 iz FD"

#: common/flatpak-context.c:2673
msgid "Remove variable from environment"
msgstr "Odstrani spremenljivko iz okolja"

#: common/flatpak-context.c:2673
msgid "VAR"
msgstr "SPRE"

#: common/flatpak-context.c:2674
msgid "Allow app to own name on the session bus"
msgstr "Dovoli aplikaciji, da si lasti ime na vodilu seje"

#: common/flatpak-context.c:2674 common/flatpak-context.c:2675
#: common/flatpak-context.c:2676 common/flatpak-context.c:2677
#: common/flatpak-context.c:2678 common/flatpak-context.c:2679
#: common/flatpak-context.c:2680
msgid "DBUS_NAME"
msgstr "DBUS_IME"

#: common/flatpak-context.c:2675
msgid "Allow app to talk to name on the session bus"
msgstr "Dovoli aplikaciji, da govori z imenom na vodilu seje"

#: common/flatpak-context.c:2676
msgid "Don't allow app to talk to name on the session bus"
msgstr "Ne dovoli aplikaciji, da govori z imenom na vodilu seje"

#: common/flatpak-context.c:2677
msgid "Allow app to own name on the system bus"
msgstr "Dovoli aplikaciji, da ima lastno ime v sistemskem vodilu"

#: common/flatpak-context.c:2678
msgid "Allow app to talk to name on the system bus"
msgstr "Dovoli aplikaciji, da govori z imenom na sistemskem vodilu"

#: common/flatpak-context.c:2679
msgid "Don't allow app to talk to name on the system bus"
msgstr "Ne dovoli aplikaciji, da govori z imenom na sistemskem vodilu"

#: common/flatpak-context.c:2680
msgid "Allow app to own name on the a11y bus"
msgstr "Dovoli aplikaciji, da ima lastno ime na sistemskem vodilu"

#: common/flatpak-context.c:2681
msgid "Add generic policy option"
msgstr "Dodaja možnostisplošnega pravilnika"

#: common/flatpak-context.c:2681 common/flatpak-context.c:2682
msgid "SUBSYSTEM.KEY=VALUE"
msgstr "PODSISTEM.KLJUČ=VREDNOST"

#: common/flatpak-context.c:2682
msgid "Remove generic policy option"
msgstr "Odstrani možnost splošnega pravilnika"

#: common/flatpak-context.c:2683
msgid "Add USB device to enumerables"
msgstr "Dodaj napravo USB med oštevičene"

#: common/flatpak-context.c:2683 common/flatpak-context.c:2684
msgid "VENDOR_ID:PRODUCT_ID"
msgstr "ID_PROIZVAJALCA:ID_IZDELKA"

#: common/flatpak-context.c:2684
msgid "Add USB device to hidden list"
msgstr "Dodaj napravo USB na skriti seznam"

#: common/flatpak-context.c:2685
msgid "A list of USB devices that are enumerable"
msgstr "Seznam naprav USB, ki jih je mogoče našteti"

#: common/flatpak-context.c:2685
msgid "LIST"
msgstr "SEZNAM"

#: common/flatpak-context.c:2686
msgid "File containing a list of USB devices to make enumerable"
msgstr "Datoteka, ki vsebuje seznam naprav USB, ki jih je mogoče našteti"

#: common/flatpak-context.c:2686 common/flatpak-context.c:2687
msgid "FILENAME"
msgstr "IMEDATOTEKE"

#: common/flatpak-context.c:2687
msgid "Persist home directory subpath"
msgstr "Vztrajaj pri podpoti domačega mape"

#. This is not needed/used anymore, so hidden, but we accept it for backwards compat
#: common/flatpak-context.c:2689
msgid "Don't require a running session (no cgroups creation)"
msgstr "Ni potrebno izvajati seje (brez ustvarjanja cgroups)"

#: common/flatpak-context.c:3718
#, c-format
msgid "Not replacing \"%s\" with tmpfs: %s"
msgstr "Brez zamenjave »%s« s tmpfs: %s"

#: common/flatpak-context.c:3726
#, c-format
msgid "Not sharing \"%s\" with sandbox: %s"
msgstr "Ni skupne rabe »%s« s peskovnikom: %s"

#. Even if the error is one that we would normally silence, like
#. * the path not existing, it seems reasonable to make more of a fuss
#. * about the home directory not existing or otherwise being unusable,
#. * so this is intentionally not using cannot_export()
#: common/flatpak-context.c:3828
#, c-format
msgid "Not allowing home directory access: %s"
msgstr "Dostop do domače mape ni dovoljen: %s"

#: common/flatpak-context.c:4062
#, c-format
msgid "Unable to provide a temporary home directory in the sandbox: %s"
msgstr "Ni mogoče zagotoviti začasne domače mape v peskovniku: %s"

#: common/flatpak-dir.c:442
#, c-format
msgid "Configured collection ID ‘%s’ not in summary file"
msgstr "Prilagojeni ID zbirke »%s« ni v datoteki povzetka"

#: common/flatpak-dir.c:587
#, c-format
msgid "Unable to load summary from remote %s: %s"
msgstr "Ni mogoče naložiti povzetka iz oddaljenega %s: %s"

#: common/flatpak-dir.c:764 common/flatpak-dir.c:800 common/flatpak-dir.c:906
#, c-format
msgid "No such ref '%s' in remote %s"
msgstr "Ni takšnega ref »%s« v oddaljenem %s"

#: common/flatpak-dir.c:891 common/flatpak-dir.c:1051 common/flatpak-dir.c:1080
#: common/flatpak-dir.c:1092
#, c-format
msgid "No entry for %s in remote %s summary flatpak cache"
msgstr "Ni vnosa za %s v oddaljenem %s predpomnilniku povzetka flatpak"

#: common/flatpak-dir.c:1069
#, c-format
msgid "No summary or Flatpak cache available for remote %s"
msgstr "Za oddaljeni %s ni na voljo povzetka ali predpomnilnika Flatpak"

#: common/flatpak-dir.c:1097
#, c-format
msgid "Missing xa.data in summary for remote %s"
msgstr "Manjkajo xa.data v povzetku za oddaljeni %s"

#: common/flatpak-dir.c:1103 common/flatpak-dir.c:1546
#, c-format
msgid "Unsupported summary version %d for remote %s"
msgstr "Nepodprta različica povzetka %d za oddaljeni %s"

#: common/flatpak-dir.c:1200
msgid "Remote OCI index has no registry uri"
msgstr "OddaljenI indeks OCI nima uri registra"

#: common/flatpak-dir.c:1261
#, c-format
msgid "Couldn't find ref %s in remote %s"
msgstr "Ni možno najti ref %s v oddaljenem %s"

#: common/flatpak-dir.c:1288 common/flatpak-dir.c:1381
#, fuzzy, c-format
msgid "Commit has no requested ref ‘%s’ in ref binding metadata (found: ‘%s’)"
msgstr "Objava nima zahtevanega ref »%s« v navezanih metapodatkih"

#: common/flatpak-dir.c:1413
#, c-format
msgid "Configured collection ID ‘%s’ not in binding metadata"
msgstr "Prilagojeni ID zbirke »%s« ni v navezanih metapodatkih"

#: common/flatpak-dir.c:1449 common/flatpak-dir.c:5645
#, c-format
msgid "Couldn't find latest checksum for ref %s in remote %s"
msgstr "Najnovejše kontrolne vsote za ref %s v oddaljenem %s ni možno najti"

#: common/flatpak-dir.c:1516 common/flatpak-dir.c:1552
#, c-format
msgid "No entry for %s in remote %s summary flatpak sparse cache"
msgstr ""
"Ni vnosa za %s v oddaljenem %s s povzetki flatpak redkega predpomnilnika"

#: common/flatpak-dir.c:2540
#, c-format
msgid "Commit metadata for %s not matching expected metadata"
msgstr "Metapodatki objave za %s se ne ujemajo s pričakovanimi metapodatki"

#: common/flatpak-dir.c:2823
msgid "Unable to connect to system bus"
msgstr "Povezave s sistemskim vodilom ni mogoče vzpostaviti"

#: common/flatpak-dir.c:3419
msgid "User installation"
msgstr "Uporabniška namestitev"

#: common/flatpak-dir.c:3426
#, c-format
msgid "System (%s) installation"
msgstr "Namestitev sistema (%s)"

#: common/flatpak-dir.c:3472
#, c-format
msgid "No overrides found for %s"
msgstr "Ni preglasitev za %s"

#: common/flatpak-dir.c:3625
#, c-format
msgid "%s (commit %s) not installed"
msgstr "%s (objava %s) - ni nameščeno"

#: common/flatpak-dir.c:4650
#, c-format
msgid "Error parsing system flatpakrepo file for %s: %s"
msgstr "Napaka pri razčlenjevanju sistemske datoteke flatpakrepo za %s: %s"

#: common/flatpak-dir.c:4735
#, c-format
msgid "While opening repository %s: "
msgstr "Med odpiranjem skladišča %s: "

#: common/flatpak-dir.c:5004
#, c-format
msgid "The config key %s is not set"
msgstr "Prilagoditveni ključ %s ni nastavljen"

#: common/flatpak-dir.c:5140
#, c-format
msgid "No current %s pattern matching %s"
msgstr "Ni trenutnega vzorca %s, ki se ujema s/z %s"

#: common/flatpak-dir.c:5422
msgid "No appstream commit to deploy"
msgstr "Ni objave appstream za uvajanje"

#: common/flatpak-dir.c:5941 common/flatpak-dir.c:7266
#: common/flatpak-dir.c:10881 common/flatpak-dir.c:11618
msgid "Can't pull from untrusted non-gpg verified remote"
msgstr ""
"Ni mogoče potegniti iz zaupanja ne vrednega ne-GPG preverjenega oddaljenega"

#: common/flatpak-dir.c:6376 common/flatpak-dir.c:6591
msgid "Extra data not supported for non-gpg-verified local system installs"
msgstr ""
"Dodatni podatki niso podprti za ne-GPG-preverjene krajevne sistemske "
"namestitve"

#: common/flatpak-dir.c:6415 common/flatpak-dir.c:6782
#, c-format
msgid "Invalid checksum for extra data uri %s"
msgstr "Neveljavna kontrolna vsota za uri dodatnih podatkov %s"

#: common/flatpak-dir.c:6424
#, c-format
msgid "Empty name for extra data uri %s"
msgstr "Prazno ime za uri dodatnih podatkov %s"

#: common/flatpak-dir.c:6432
#, c-format
msgid "Unsupported extra data uri %s"
msgstr "Nepodprti uri dodatnih podatkov %s"

#: common/flatpak-dir.c:6461
#, c-format
msgid "Failed to load local extra-data %s: %s"
msgstr "Nalaganje krajevnih dodatnih podatkov (extra-data) %s ni uspelo: %s"

#: common/flatpak-dir.c:6469
#, c-format
msgid "Wrong size for extra-data %s"
msgstr "Napačna velikost za dodatne podatke %s"

#: common/flatpak-dir.c:6488
#, c-format
msgid "While downloading %s: "
msgstr "Med prenosom %s: "

#: common/flatpak-dir.c:6498
#, c-format
msgid "Wrong size for extra data %s"
msgstr "Napačna velikost za dodatne podatke %s"

#: common/flatpak-dir.c:6507
#, c-format
msgid "Invalid checksum for extra data %s"
msgstr "Neveljavna kontrolna vsota za dodatne podatke %s"

#: common/flatpak-dir.c:7096 common/flatpak-dir.c:7349
#, c-format
msgid "While pulling %s from remote %s: "
msgstr "Med potegom %s iz oddaljenega %s: "

#: common/flatpak-dir.c:7290 common/flatpak-repo-utils.c:3886
msgid "GPG signatures found, but none are in trusted keyring"
msgstr ""
"Podpisi GPG najdeni, vendar nobeden ni v zaupanja vredni zbirki ključev"

#: common/flatpak-dir.c:7307
#, c-format
msgid "Commit for ‘%s’ has no ref binding"
msgstr "Objava za »%s« nima zavezujočega ref"

#: common/flatpak-dir.c:7312
#, c-format
msgid "Commit for ‘%s’ is not in expected bound refs: %s"
msgstr "Objava »%s« nima pričakovanih vezanih ref: %s"

#: common/flatpak-dir.c:7488
msgid "Only applications can be made current"
msgstr "Samo aplikacije se lahko naredijo kot osvežene"

#: common/flatpak-dir.c:8192
msgid "Not enough memory"
msgstr "Ni dovolj pomnilnika"

#: common/flatpak-dir.c:8211
msgid "Failed to read from exported file"
msgstr "Branje iz izvožene datoteke ni uspelo"

#: common/flatpak-dir.c:8401
msgid "Error reading mimetype xml file"
msgstr "Napaka pri branju datoteke mimetype xml"

#: common/flatpak-dir.c:8406
msgid "Invalid mimetype xml file"
msgstr "Neveljavna datoteka mimetype XML"

#: common/flatpak-dir.c:8492
#, c-format
msgid "D-Bus service file '%s' has wrong name"
msgstr "Servisna datoteka vodika D-Bus »%s« ima napačno ime"

#: common/flatpak-dir.c:8647
#, c-format
msgid "Invalid Exec argument %s"
msgstr "Neveljaven argument Exec %s"

#: common/flatpak-dir.c:9115
msgid "While getting detached metadata: "
msgstr "Med pridobivanjem ločenih metapodatkov: "

#: common/flatpak-dir.c:9120 common/flatpak-dir.c:9125
#: common/flatpak-dir.c:9129
msgid "Extra data missing in detached metadata"
msgstr "Dodatni podatki, ki manjkajo v odklopljenih metapodatkih"

#: common/flatpak-dir.c:9133
msgid "While creating extradir: "
msgstr "Med ustvarjanjem extradir: "

#: common/flatpak-dir.c:9154 common/flatpak-dir.c:9187
msgid "Invalid checksum for extra data"
msgstr "Neveljavna kontrolna vsota za dodatne podatke"

#: common/flatpak-dir.c:9183
msgid "Wrong size for extra data"
msgstr "Napačna velikost za dodatne podatke"

#: common/flatpak-dir.c:9196
#, c-format
msgid "While writing extra data file '%s': "
msgstr "Med pisanjem dodatne podatkovne datoteke »%s«: "

#: common/flatpak-dir.c:9204
#, c-format
msgid "Extra data %s missing in detached metadata"
msgstr "Dodatni podatki %s manjkajo v odklopljenih metapodatkih"

#: common/flatpak-dir.c:9278
#, c-format
msgid "Unable to get runtime key from metadata"
msgstr "Iz metapodatkov ni mogoče pridobiti ključa izvajalnika"

#: common/flatpak-dir.c:9402
#, c-format
msgid "apply_extra script failed, exit status %d"
msgstr "Skript apply_extra je spodletel, stanje izhoda %d"

#. Translators: The placeholder is for an app ref.
#: common/flatpak-dir.c:9591
#, c-format
msgid "Installing %s is not allowed by the policy set by your administrator"
msgstr "Namestitve %s ne dovolijo pravila, ki jih je določil skrbnik"

#: common/flatpak-dir.c:9690
#, c-format
msgid "While trying to resolve ref %s: "
msgstr "Med poskusom razreševanja ref %s: "

#: common/flatpak-dir.c:9702
#, c-format
msgid "%s is not available"
msgstr "%s ni na voljo"

#: common/flatpak-dir.c:9714 common/flatpak-dir.c:11495
#, c-format
msgid "%s commit %s already installed"
msgstr "%s (objava %s) - že nameščeno"

#: common/flatpak-dir.c:9721
msgid "Can't create deploy directory"
msgstr "Ni mogoče ustvariti mape uvajanja"

#: common/flatpak-dir.c:9729
#, c-format
msgid "Failed to read commit %s: "
msgstr "Branje objave %s je spodletelo: "

#: common/flatpak-dir.c:9750
#, c-format
msgid "While trying to checkout %s into %s: "
msgstr "Med poskusom prevzema %s v %s: "

#: common/flatpak-dir.c:9769
msgid "While trying to checkout metadata subpath: "
msgstr "Med poskusom prevzema podpoti metapodatkov: "

#: common/flatpak-dir.c:9801
#, c-format
msgid "While trying to checkout subpath ‘%s’: "
msgstr "Med poskusom prevzema podpoti »%s«: "

#: common/flatpak-dir.c:9811
msgid "While trying to remove existing extra dir: "
msgstr "Med poskusom odstranjevanja obstoječe dodatne mape: "

#: common/flatpak-dir.c:9822
msgid "While trying to apply extra data: "
msgstr "Med poskusom uveljavitve dodatnih podatkov: "

#: common/flatpak-dir.c:9849
#, c-format
msgid "Invalid commit ref %s: "
msgstr "Neveljavna objava ref %s: "

#: common/flatpak-dir.c:9857 common/flatpak-dir.c:9869
#, c-format
msgid "Deployed ref %s does not match commit (%s)"
msgstr "Uvedeni ref %s se ne ujema z objavo (%s)"

#: common/flatpak-dir.c:9863
#, c-format
msgid "Deployed ref %s branch does not match commit (%s)"
msgstr "Veja uvedenega ref %s se ne ujema z objavo (%s)"

#: common/flatpak-dir.c:10125 common/flatpak-installation.c:1911
#, c-format
msgid "%s branch %s already installed"
msgstr "%s veje %s - že nameščeno"

#: common/flatpak-dir.c:10985
#, c-format
msgid "Could not unmount revokefs-fuse filesystem at %s: "
msgstr "Ni bilo mogoče odklopiti datotečnega sistema revokefs-fuse na %s: "

#: common/flatpak-dir.c:11289
#, c-format
msgid "This version of %s is already installed"
msgstr "Ta različica %s je že nameščena"

#: common/flatpak-dir.c:11302
#, c-format
msgid "Can't change remote during bundle install"
msgstr "Med namestitvijo svežnja ni mogoče spreminjati oddaljenega"

#: common/flatpak-dir.c:11571
msgid "Can't update to a specific commit without root permissions"
msgstr "Brez korenskih dovoljenj ni mogoče posodobiti na določeno objavo"

#: common/flatpak-dir.c:11852
#, c-format
msgid "Can't remove %s, it is needed for: %s"
msgstr "Ni mogoče odstraniti %s, potrebna je za: %s"

#: common/flatpak-dir.c:11912 common/flatpak-installation.c:2067
#, c-format
msgid "%s branch %s is not installed"
msgstr "Veja %s %s ni nameščena"

#: common/flatpak-dir.c:12165
#, c-format
msgid "%s commit %s not installed"
msgstr "%s objava %s ni nameščen"

#: common/flatpak-dir.c:12501
#, c-format
msgid "Pruning repo failed: %s"
msgstr "Obrezovanje skladišča ni uspelo: %s"

#: common/flatpak-dir.c:12669 common/flatpak-dir.c:12675
#, c-format
msgid "Failed to load filter '%s'"
msgstr "Nalaganje filtra »%s« ni uspelo"

#: common/flatpak-dir.c:12681
#, c-format
msgid "Failed to parse filter '%s'"
msgstr "Razčlenjevanje filtra »%s« ni uspelo"

#: common/flatpak-dir.c:12963
msgid "Failed to write summary cache: "
msgstr "Pisanje predpomnilnika povzetka ni uspelo: "

#: common/flatpak-dir.c:12982
#, c-format
msgid "No oci summary cached for remote '%s'"
msgstr "Ni predpomnilnega povzetka oci za oddaljeni »%s«"

#: common/flatpak-dir.c:13207
#, c-format
msgid "No cached summary for remote '%s'"
msgstr "Ni predpomnjenega povzetka za oddaljeni strežnik »%s«."

#: common/flatpak-dir.c:13248
#, c-format
msgid "Invalid checksum for indexed summary %s read from %s"
msgstr "Neveljavna kontrolna vsota za indeksirani povzetek %s, prebran iz %s"

#: common/flatpak-dir.c:13321
#, c-format
msgid ""
"Remote listing for %s not available; server has no summary file. Check the "
"URL passed to remote-add was valid."
msgstr ""
"Oddaljeni seznam za %s ni na voljo; strežnik nima datoteke s povzetjem. "
"Preverite, ali je URL, ki je bil podan remote-add, veljaven."

#: common/flatpak-dir.c:13698
#, c-format
msgid "Invalid checksum for indexed summary %s for remote '%s'"
msgstr ""
"Neveljavna kontrolna vsota za indeksirani povzetek %s za oddaljeni »%s«"

#: common/flatpak-dir.c:14388
#, c-format
msgid "Multiple branches available for %s, you must specify one of: "
msgstr "Več vej je na voljo za %s, navesti morate eno izmed: "

#: common/flatpak-dir.c:14454
#, c-format
msgid "Nothing matches %s"
msgstr "Nič se ne ujema s/z %s"

#: common/flatpak-dir.c:14562
#, c-format
msgid "Can't find ref %s%s%s%s%s"
msgstr "Ni mogoče najti ref %s%s%s%s%s"

#: common/flatpak-dir.c:14605
#, c-format
msgid "Error searching remote %s: %s"
msgstr "Napaka pri iskanju po oddaljenem %s: %s"

#: common/flatpak-dir.c:14702
#, c-format
msgid "Error searching local repository: %s"
msgstr "Napaka pri iskanju po krajevnem skladišču: %s"

#: common/flatpak-dir.c:14839
#, c-format
msgid "%s/%s/%s not installed"
msgstr "%s/%s/%s ni nameščen"

#: common/flatpak-dir.c:15042
#, c-format
msgid "Could not find installation %s"
msgstr "Ni mogoče najti namestitve %s"

#: common/flatpak-dir.c:15612
#, c-format
msgid "Invalid file format, no %s group"
msgstr "Neveljavna vrsta datoteke, ni skupine %s"

#: common/flatpak-dir.c:15617 common/flatpak-repo-utils.c:2836
#, c-format
msgid "Invalid version %s, only 1 supported"
msgstr "Neveljavna različica %s, podprta je samo 1"

#: common/flatpak-dir.c:15622 common/flatpak-dir.c:15627
#, c-format
msgid "Invalid file format, no %s specified"
msgstr "Neveljavna vrsta datoteke, %s ni določena"

#. Check some minimal size so we don't get crap
#: common/flatpak-dir.c:15647
msgid "Invalid file format, gpg key invalid"
msgstr "Neveljavna oblika zapisa, ključ GPG ni veljaven"

#: common/flatpak-dir.c:15675 common/flatpak-repo-utils.c:2917
msgid "Collection ID requires GPG key to be provided"
msgstr "ID zbirke zahteva, da se zagotovi ključ GPG"

#: common/flatpak-dir.c:15718
#, c-format
msgid "Runtime %s, branch %s is already installed"
msgstr "Izvajalnik %s, veja %s je že nameščen"

#: common/flatpak-dir.c:15719
#, c-format
msgid "App %s, branch %s is already installed"
msgstr "Aplikacija %s, veja %s je že nameščena"

#: common/flatpak-dir.c:15953
#, c-format
msgid "Can't remove remote '%s' with installed ref %s (at least)"
msgstr "Oddaljenega »%s« ni mogoče odstraniti z nameščenim  ref. %s (vsaj)"

#: common/flatpak-dir.c:16058
#, c-format
msgid "Invalid character '/' in remote name: %s"
msgstr "Neveljaven znak »/» v imenu oddaljenega: %s"

#: common/flatpak-dir.c:16064
#, c-format
msgid "No configuration for remote %s specified"
msgstr "Prilagoditev za oddaljeni %s ni navedena"

#: common/flatpak-dir.c:17597
#, c-format
msgid "Skipping deletion of mirror ref (%s, %s)…\n"
msgstr "Preskakovanje brisanja zrcalne ref (%s, %s) ...\n"

#: common/flatpak-exports.c:931
#, c-format
msgid "An absolute path is required"
msgstr "Potrebna je absolutna pot"

#: common/flatpak-exports.c:948
#, c-format
msgid "Unable to open path \"%s\": %s"
msgstr "Ni mogoče odpreti poti »%s«: %s"

#: common/flatpak-exports.c:955
#, c-format
msgid "Unable to get file type of \"%s\": %s"
msgstr "Vrste datoteke »%s« ni mogoče pridobiti: %s"

#: common/flatpak-exports.c:964
#, c-format
msgid "File \"%s\" has unsupported type 0o%o"
msgstr "Datoteka »%s« je podprte vrste 0o%o"

#: common/flatpak-exports.c:970
#, c-format
msgid "Unable to get filesystem information for \"%s\": %s"
msgstr "Ni mogoče pridobiti informacij datotečnega sistema za »%s«: %s"

#: common/flatpak-exports.c:980
#, c-format
msgid "Ignoring blocking autofs path \"%s\""
msgstr "Prezrtje blokiranja poti autofs »%s«"

#: common/flatpak-exports.c:996 common/flatpak-exports.c:1009
#: common/flatpak-exports.c:1022
#, c-format
msgid "Path \"%s\" is reserved by Flatpak"
msgstr "Pot »%s« je rezervirana za Flatpak"

#: common/flatpak-exports.c:1076
#, c-format
msgid "Unable to resolve symbolic link \"%s\": %s"
msgstr "Ni mogoče razrešiti simbolne povezave »%s«: %s"

#: common/flatpak-glib-backports.c:69
msgid "Empty string is not a number"
msgstr "Prazen niz ni število"

#: common/flatpak-glib-backports.c:95
#, c-format
msgid "“%s” is not an unsigned number"
msgstr "»%s« ni število brez predznaka"

#: common/flatpak-glib-backports.c:105
#, c-format
msgid "Number “%s” is out of bounds [%s, %s]"
msgstr "Število »%s« je izven območja [%s, %s]"

#: common/flatpak-image-source.c:83
msgid "Only sha256 image checksums are supported"
msgstr "Podprte so samo kontrolne vsote slik sha256"

#: common/flatpak-image-source.c:100 common/flatpak-image-source.c:108
msgid "Image is not a manifest"
msgstr "Slika ni manifest"

#: common/flatpak-image-source.c:123
msgid "No org.flatpak.ref found in image"
msgstr "V sliki ni bilo mogoče najti org.flatpak.ref"

#: common/flatpak-image-source.c:148
#, c-format
msgid "Ref '%s' not found in registry"
msgstr "Sklic »%s« ni v registru"

#: common/flatpak-image-source.c:157
msgid "Multiple images in registry, specify a ref with --ref"
msgstr "Več slik v registru, določite ref z --ref"

#: common/flatpak-installation.c:834
#, c-format
msgid "Ref %s not installed"
msgstr "Ref %s ni nameščen"

#: common/flatpak-installation.c:875
#, c-format
msgid "App %s not installed"
msgstr "Program %s ni nameščen"

#: common/flatpak-installation.c:1395
#, c-format
msgid "Remote '%s' already exists"
msgstr "Oddaljeni »%s« že obstaja"

#: common/flatpak-installation.c:1946
#, c-format
msgid "As requested, %s was only pulled, but not installed"
msgstr "Kot je bilo zahtevano, %s je samo potegnjen, vendar ni nameščen"

#: common/flatpak-instance.c:533 common/flatpak-instance.c:687
#: common/flatpak-instance.c:728
#, c-format
msgid "Unable to create directory %s"
msgstr "Ni mogoče ustvariti mape %s"

#: common/flatpak-instance.c:554
#, c-format
msgid "Unable to lock %s"
msgstr "Ni mogoče zakleniti %s"

#: common/flatpak-instance.c:627
#, c-format
msgid "Unable to create temporary directory in %s"
msgstr "Ni mogoče ustvariti začasne mape v %s"

#: common/flatpak-instance.c:639
#, c-format
msgid "Unable to create file %s"
msgstr "Ni mogoče ustvariti datoteke %s"

#: common/flatpak-instance.c:646
#, c-format
msgid "Unable to update symbolic link %s/%s"
msgstr "Ni mogoče posodobiti simbolične povezave %s/%s"

#: common/flatpak-oci-registry.c:1197
msgid "Only Bearer authentication supported"
msgstr "Podprto samo preverjanje pristnosti prinosnika"

#: common/flatpak-oci-registry.c:1206
msgid "Only realm in authentication request"
msgstr "Samo območje v zahtevi za preverjanje pristnosti"

#: common/flatpak-oci-registry.c:1213
msgid "Invalid realm in authentication request"
msgstr "Neveljavno območje v zahtevi za preverjanje pristnosti"

#: common/flatpak-oci-registry.c:1283
#, c-format
msgid "Authorization failed: %s"
msgstr "Overitev ni uspela: %s"

#: common/flatpak-oci-registry.c:1285
msgid "Authorization failed"
msgstr "Overitev ni uspela"

#: common/flatpak-oci-registry.c:1289
#, c-format
msgid "Unexpected response status %d when requesting token: %s"
msgstr "Pri zahtevanju žetona nepričakovano stanje odziva %d: %s"

#: common/flatpak-oci-registry.c:1300
msgid "Invalid authentication request response"
msgstr "Neveljaven odgovor na zahtevo za preverjanje pristnosti"

#: common/flatpak-oci-registry.c:1731
#, c-format
msgid "Flatpak was compiled without zstd support"
msgstr "Flatpak je bil preveden brez podpore za zstd"

#: common/flatpak-oci-registry.c:1923 common/flatpak-oci-registry.c:1975
#: common/flatpak-oci-registry.c:2004 common/flatpak-oci-registry.c:2059
#: common/flatpak-oci-registry.c:2115 common/flatpak-oci-registry.c:2193
msgid "Invalid delta file format"
msgstr "Neveljavna oblika datoteke delta"

#: common/flatpak-oci-registry.c:3198 common/flatpak-oci-registry.c:3382
msgid "Invalid OCI image config"
msgstr "Neveljavna prilagoditev slike OCI"

#: common/flatpak-oci-registry.c:3260 common/flatpak-oci-registry.c:3531
#, c-format
msgid "Wrong layer checksum, expected %s, was %s"
msgstr "Napačna kontrolna vsota plasti, pričakovana %s, bila je %s"

#: common/flatpak-oci-registry.c:3359
#, c-format
msgid "No ref specified for OCI image %s"
msgstr "Za sliko OCI %s ni določen noben ref"

#: common/flatpak-oci-registry.c:3369
#, c-format
msgid "Wrong ref (%s) specified for OCI image %s, expected %s"
msgstr "Napačni ref (%s) je določen za sliko OCI %s, pričakovano %s"

#: common/flatpak-progress.c:236
#, c-format
msgid "Downloading metadata: %u/(estimating) %s"
msgstr "Prenos metapodatkov: %u/(ocenjeno) %s"

#: common/flatpak-progress.c:260
#, c-format
msgid "Downloading: %s/%s"
msgstr "Prejemanje: %s/%s"

#: common/flatpak-progress.c:280
#, c-format
msgid "Downloading extra data: %s/%s"
msgstr "Prejemanje dodatnih podatkov: %s/%s"

#: common/flatpak-progress.c:285
#, c-format
msgid "Downloading files: %d/%d %s"
msgstr "Prejemanje datotek: %d/%d %s"

#: common/flatpak-ref-utils.c:122
msgid "Name can't be empty"
msgstr "Ime ne sme biti prazno"

#: common/flatpak-ref-utils.c:129
msgid "Name can't be longer than 255 characters"
msgstr "Ime ne sme biti daljše od 255 znakov"

#: common/flatpak-ref-utils.c:142
msgid "Name can't start with a period"
msgstr "Ime se ne more začeti s piko"

#: common/flatpak-ref-utils.c:148
#, c-format
msgid "Name can't start with %c"
msgstr "Ime se ne more začeti s/z %c"

#: common/flatpak-ref-utils.c:164
msgid "Name can't end with a period"
msgstr "Ime se ne more končati s piko"

#: common/flatpak-ref-utils.c:171 common/flatpak-ref-utils.c:183
msgid "Only last name segment can contain -"
msgstr "Samo segment priimka lahko vsebuje -"

#: common/flatpak-ref-utils.c:174
#, c-format
msgid "Name segment can't start with %c"
msgstr "Segment imena se ne more začeti s/z %c"

#: common/flatpak-ref-utils.c:186
#, c-format
msgid "Name can't contain %c"
msgstr "Ime ne more vsebovati %c"

#: common/flatpak-ref-utils.c:195
msgid "Names must contain at least 2 periods"
msgstr "Imena morajo vsebovati vsaj dve vejici"

#: common/flatpak-ref-utils.c:312
msgid "Arch can't be empty"
msgstr "Arch ne more biti prazen"

#: common/flatpak-ref-utils.c:323
#, c-format
msgid "Arch can't contain %c"
msgstr "Arch ne more vsebovati %c"

#: common/flatpak-ref-utils.c:385
msgid "Branch can't be empty"
msgstr "Veja ne more biti prazna"

#: common/flatpak-ref-utils.c:395
#, c-format
msgid "Branch can't start with %c"
msgstr "Podružnica se ne more začeti z %c"

#: common/flatpak-ref-utils.c:405
#, c-format
msgid "Branch can't contain %c"
msgstr "Veja ne more vsebovati %c"

#: common/flatpak-ref-utils.c:615 common/flatpak-ref-utils.c:865
msgid "Ref too long"
msgstr "Predolg ref"

#: common/flatpak-ref-utils.c:627
msgid "Invalid remote name"
msgstr "Neveljavno oddaljeno ime"

#: common/flatpak-ref-utils.c:641
#, c-format
msgid "%s is not application or runtime"
msgstr "%s ni aplikacija ali izvajalnik"

#: common/flatpak-ref-utils.c:650 common/flatpak-ref-utils.c:667
#: common/flatpak-ref-utils.c:683
#, c-format
msgid "Wrong number of components in %s"
msgstr "Napačno število komponent v %s"

#: common/flatpak-ref-utils.c:656
#, c-format
msgid "Invalid name %.*s: %s"
msgstr "Neveljavno ime %.*s: %s"

#: common/flatpak-ref-utils.c:673
#, c-format
msgid "Invalid arch: %.*s: %s"
msgstr "Neveljavna arh.: %.*s: %s"

#: common/flatpak-ref-utils.c:816
#, c-format
msgid "Invalid name %s: %s"
msgstr "Neveljavno ime %s: %s"

#: common/flatpak-ref-utils.c:834
#, c-format
msgid "Invalid arch: %s: %s"
msgstr "Neveljavna arh.: %s: %s"

#: common/flatpak-ref-utils.c:853
#, c-format
msgid "Invalid branch: %s: %s"
msgstr "Neveljavna veja: %s: %s"

#: common/flatpak-ref-utils.c:962 common/flatpak-ref-utils.c:970
#: common/flatpak-ref-utils.c:978
#, c-format
msgid "Wrong number of components in partial ref %s"
msgstr "Napačno število komponent v delni %s"

#: common/flatpak-ref-utils.c:1298
msgid " development platform"
msgstr " razvojna platforma"

#: common/flatpak-ref-utils.c:1300
msgid " platform"
msgstr " platforma"

#: common/flatpak-ref-utils.c:1302
msgid " application base"
msgstr " osnova aplikacije"

#: common/flatpak-ref-utils.c:1305
msgid " debug symbols"
msgstr "simboli za razhroščevanje"

#: common/flatpak-ref-utils.c:1307
msgid " sourcecode"
msgstr " izvorna koda"

#: common/flatpak-ref-utils.c:1309
msgid " translations"
msgstr "prevodi"

#: common/flatpak-ref-utils.c:1311
msgid " docs"
msgstr "dokumentacija"

#: common/flatpak-ref-utils.c:1578
#, c-format
msgid "Invalid id %s: %s"
msgstr "Neveljaven ID %s: %s"

#: common/flatpak-remote.c:1216
#, c-format
msgid "Bad remote name: %s"
msgstr "Slabo oddaljeno ime: %s"

#: common/flatpak-remote.c:1220
msgid "No URL specified"
msgstr "URL ni naveden"

#: common/flatpak-remote.c:1266
msgid "GPG verification must be enabled when a collection ID is set"
msgstr "Preverjanje GPG mora biti omogočeno, ko je nastavljen ID zbirke"

#: common/flatpak-repo-utils.c:344
#, c-format
msgid "No extra data sources"
msgstr "Ni dodatnih virov podatkov"

#: common/flatpak-repo-utils.c:2817
#, c-format
msgid "Invalid %s: Missing group ‘%s’"
msgstr "Neveljaven %s: manjka skupina »%s«"

#: common/flatpak-repo-utils.c:2826
#, c-format
msgid "Invalid %s: Missing key ‘%s’"
msgstr "Neveljaven %s: manjka ključ »%s«"

#: common/flatpak-repo-utils.c:2876
msgid "Invalid gpg key"
msgstr "Neveljaven ključ gpg"

#: common/flatpak-repo-utils.c:3217
#, c-format
msgid "Error copying 64x64 icon for component %s: %s\n"
msgstr "Napaka pri kopiranju ikone 64x64 za komponento %s: %s\n"

#: common/flatpak-repo-utils.c:3223
#, c-format
msgid "Error copying 128x128 icon for component %s: %s\n"
msgstr "Napaka pri kopiranju ikone 128x128 za komponento %s: %s\n"

#: common/flatpak-repo-utils.c:3362
#, c-format
msgid "%s is end-of-life, ignoring for appstream"
msgstr "%s je dosegla konec življenjske dobe, prezrta bo za appstream"

#: common/flatpak-repo-utils.c:3397
#, c-format
msgid "No appstream data for %s: %s\n"
msgstr "Za %s ni podatkov appstream: %s\n"

#: common/flatpak-repo-utils.c:3744
msgid "Invalid bundle, no ref in metadata"
msgstr "Neveljaven sveženj, v metapodatki ni sklica ref"

#: common/flatpak-repo-utils.c:3846
#, c-format
msgid "Collection ‘%s’ of bundle doesn’t match collection ‘%s’ of remote"
msgstr "Zbirka »%s« svežnja se ne ujema z zbirko »%s« oddaljenega"

#: common/flatpak-repo-utils.c:3923
msgid "Metadata in header and app are inconsistent"
msgstr "Metapodatki v glavi in aplikaciji so nedosledni"

#: common/flatpak-run.c:951
msgid "No systemd user session available, cgroups not available"
msgstr "Uporabniška seja systemd ni na voljo, cgroups ni na voljo"

#: common/flatpak-run.c:1496
msgid "Unable to allocate instance id"
msgstr "ID-ja primerka ni mogoče dodeliti"

#: common/flatpak-run.c:1632 common/flatpak-run.c:1641
#, c-format
msgid "Failed to open flatpak-info file: %s"
msgstr "Odpiranje datoteke flatpak-info ni uspelo: %s"

#: common/flatpak-run.c:1668
#, c-format
msgid "Failed to open bwrapinfo.json file: %s"
msgstr "Odpiranje datoteke bwrapinfo.json ni uspelo: %s"

#: common/flatpak-run.c:1689
#, c-format
msgid "Failed to write to instance id fd: %s"
msgstr "Pisanje v ID primerka fd ni uspelo: %s"

#: common/flatpak-run.c:2096
msgid "Initialize seccomp failed"
msgstr "Inicializacija seccomp ni uspela"

#: common/flatpak-run.c:2135
#, c-format
msgid "Failed to add architecture to seccomp filter: %s"
msgstr "Dodajanje arhitekture v filter seccomp ni uspelo: %s"

#: common/flatpak-run.c:2143
#, c-format
msgid "Failed to add multiarch architecture to seccomp filter: %s"
msgstr "Dodajanje arhitekture multiarch v filter seccomp ni uspelo: %s"

#: common/flatpak-run.c:2175 common/flatpak-run.c:2192
#: common/flatpak-run.c:2214
#, c-format
msgid "Failed to block syscall %d: %s"
msgstr "Blokiranje syscall %d je spodletelo: %s"

#: common/flatpak-run.c:2247
#, c-format
msgid "Failed to export bpf: %s"
msgstr "Izvoz BPF ni uspel: %s"

#: common/flatpak-run.c:2587
#, c-format
msgid "Failed to open ‘%s’"
msgstr "Datoteke »%s« ni mogoče odpreti"

#: common/flatpak-run.c:2597
#, c-format
msgid ""
"Directory forwarding needs version 4 of the document portal (have version %d)"
msgstr ""
"Posredovanje mape potrebuje različico 4 portala za dokumente (imate "
"različico %d)"

#: common/flatpak-run.c:2915
#, c-format
msgid "ldconfig failed, exit status %d"
msgstr "ldconfig ni uspel, stanje izhoda %d"

#: common/flatpak-run.c:2922
msgid "Can't open generated ld.so.cache"
msgstr "Ni mogoče odpreti ustvarjenega ld.so.cache"

#. Translators: The placeholder is for an app ref.
#: common/flatpak-run.c:3045
#, c-format
msgid "Running %s is not allowed by the policy set by your administrator"
msgstr "Zagon %s ni dovoljen s pravili, ki jih je določil skrbnik"

#: common/flatpak-run.c:3202
msgid ""
"\"flatpak run\" is not intended to be run as `sudo flatpak run`. Use `sudo "
"-i` or `su -l` instead and invoke \"flatpak run\" from inside the new shell."
msgstr ""
"»flatpak run« ni namenjen izvajanju  kot `sudo flatpak run`. Namesto tega "
"uporabite `sudo -i` ali `su -l` in iz nove lupine kličite »flatpak run«."

#: common/flatpak-run.c:3413
#, c-format
msgid "Failed to migrate from %s: %s"
msgstr "Selitev iz %s ni uspela: %s"

#: common/flatpak-run.c:3434
#, c-format
msgid "Failed to migrate old app data directory %s to new name %s: %s"
msgstr "Selitev podatkovne mape stare aplikacije %s v novo ime %s: %s"

#: common/flatpak-run.c:3443
#, c-format
msgid "Failed to create symlink while migrating %s: %s"
msgstr "Med migracijo %s ni uspelo ustvariti simbolne povezave: %s"

#: common/flatpak-run-dbus.c:46
msgid "Failed to open app info file"
msgstr "Odpiranje datoteke z informacijami o aplikaciji ni uspelo"

#: common/flatpak-run-dbus.c:149
msgid "Unable to create sync pipe"
msgstr "Ni mogoče ustvariti sinhronizacijske cevi"

#: common/flatpak-run-dbus.c:185
msgid "Failed to sync with dbus proxy"
msgstr "Sinhronizacija s posrednikom za dbus ni uspela"

#: common/flatpak-transaction.c:2275
#, c-format
msgid "Warning: Problem looking for related refs: %s"
msgstr "Opozorilo: Težava pri iskanju sorodnih ref: %s"

#: common/flatpak-transaction.c:2493
#, c-format
msgid "The application %s requires the runtime %s which was not found"
msgstr "Aplikacija %s zahteva izvajalnik %s, ki ni bil najden"

#: common/flatpak-transaction.c:2509
#, c-format
msgid "The application %s requires the runtime %s which is not installed"
msgstr "Aplikacija %s zahteva izvajalnik %s, ki ni nameščen"

#: common/flatpak-transaction.c:2641
#, c-format
msgid "Can't uninstall %s which is needed by %s"
msgstr "Ni mogoče odstraniti %s, ki ga potrebuje %s"

#: common/flatpak-transaction.c:2740
#, c-format
msgid "Remote %s disabled, ignoring %s update"
msgstr "Oddaljeni %s onemogočen, prezrta posodobitev %s"

#: common/flatpak-transaction.c:2773
#, c-format
msgid "%s is already installed"
msgstr "%s je že nameščen"

#: common/flatpak-transaction.c:2776
#, c-format
msgid "%s is already installed from remote %s"
msgstr "%s je že nameščen iz oddaljenega %s"

#: common/flatpak-transaction.c:3120
#, c-format
msgid "Invalid .flatpakref: %s"
msgstr "Neveljaven .flatpakref: %s"

#: common/flatpak-transaction.c:3161
msgid "Warning: Could not mark already installed apps as preinstalled"
msgstr ""
"Opozorilo: Že nameščenih aplikacij ni bilo mogoče označiti kot vnaprej "
"nameščenih"

#: common/flatpak-transaction.c:3382
#, c-format
msgid "Error updating remote metadata for '%s': %s"
msgstr "Napaka pri posodabljanju oddaljenih metapodatkov za »%s«: %s"

#: common/flatpak-transaction.c:3885
#, c-format
msgid ""
"Warning: Treating remote fetch error as non-fatal since %s is already "
"installed: %s"
msgstr ""
"Opozorilo: Obravnavanje napake pri oddaljenem pridobivanju kot ne usodne, "
"kajti %s je že nameščen: %s"

#: common/flatpak-transaction.c:4209
#, c-format
msgid "No authenticator installed for remote '%s'"
msgstr "Za oddaljeni »%s« ni nameščen avtentikator"

#: common/flatpak-transaction.c:4313 common/flatpak-transaction.c:4320
#, c-format
msgid "Failed to get tokens for ref: %s"
msgstr "Ni mogoče dobiti žetonov za ref: %s"

#: common/flatpak-transaction.c:4315 common/flatpak-transaction.c:4322
msgid "Failed to get tokens for ref"
msgstr "Ni mogoče dobiti žetonov za ref"

#: common/flatpak-transaction.c:4580
#, c-format
msgid "Ref %s from %s matches more than one transaction operation"
msgstr "Sklic %s iz %s se ujema z več kot eno transakcijsko operacijo"

#: common/flatpak-transaction.c:4581 common/flatpak-transaction.c:4591
msgid "any remote"
msgstr "poljubni oddaljeni"

#: common/flatpak-transaction.c:4590
#, c-format
msgid "No transaction operation found for ref %s from %s"
msgstr "Za ref %s iz %s ni bila najdena nobena operacija transakcije"

#: common/flatpak-transaction.c:4713
#, c-format
msgid "Flatpakrepo URL %s not file, HTTP or HTTPS"
msgstr "URL flatpakrepo %s ni datoteka, HTTP ali HTTPS"

#: common/flatpak-transaction.c:4719
#, c-format
msgid "Can't load dependent file %s: "
msgstr "Ni mogoče naložiti odvisne datoteke %s: "

#: common/flatpak-transaction.c:4727
#, c-format
msgid "Invalid .flatpakrepo: %s"
msgstr "Neveljaven .flatpakrepo: %s"

#: common/flatpak-transaction.c:5454
msgid "Transaction already executed"
msgstr "Transakcija je že izvršena"

#: common/flatpak-transaction.c:5469
msgid ""
"Refusing to operate on a user installation as root! This can lead to "
"incorrect file ownership and permission errors."
msgstr ""
"Zavračanje delovanja na uporabniški namestitvi kot korenski uporabnik! To "
"lahko povzroči nepravilno lastništvo datotek in napake pri pravicah."

#: common/flatpak-transaction.c:5567 common/flatpak-transaction.c:5580
msgid "Aborted by user"
msgstr "Prekinil uporabnik"

#: common/flatpak-transaction.c:5605
#, c-format
msgid "Skipping %s due to previous error"
msgstr "Preskakovanje %s zaradi prejšnje napake"

#: common/flatpak-transaction.c:5659
#, c-format
msgid "Aborted due to failure (%s)"
msgstr "Prekinitev zaradi neuspeha (%s)"

#: common/flatpak-uri.c:118
#, no-c-format
msgid "Invalid %-encoding in URI"
msgstr "Neveljavni nabor znakov % v naslovu URI"

#: common/flatpak-uri.c:135
msgid "Illegal character in URI"
msgstr "Neveljaven znak v naslovu URI"

#: common/flatpak-uri.c:169
msgid "Non-UTF-8 characters in URI"
msgstr "V naslovu URI so znaki, ki niso UTF-8"

#: common/flatpak-uri.c:275
#, c-format
msgid "Invalid IPv6 address ‘%.*s’ in URI"
msgstr "Neveljaven naslov IPv6 »%.*s« v naslovu URI"

#: common/flatpak-uri.c:330
#, c-format
msgid "Illegal encoded IP address ‘%.*s’ in URI"
msgstr "Neveljaven kodiran naslov IP »%.*s« v naslovu URI"

#: common/flatpak-uri.c:342
#, c-format
msgid "Illegal internationalized hostname ‘%.*s’ in URI"
msgstr "Neveljavno internacionalizirano ime gostitelja »%.*s« v naslovu URI"

#: common/flatpak-uri.c:374 common/flatpak-uri.c:386
#, c-format
msgid "Could not parse port ‘%.*s’ in URI"
msgstr "Ni mogoče razčleniti vrat »%.*s« v naslovu URI"

#: common/flatpak-uri.c:393
#, c-format
msgid "Port ‘%.*s’ in URI is out of range"
msgstr "Vrednost vrat »%.*s« v naslovu URI je izven obsega"

#: common/flatpak-uri.c:910
msgid "URI is not absolute, and no base URI was provided"
msgstr "Naslov URI ni absoluten naslov in ni podanega osnovnega naslova URI"

#: common/flatpak-usb.c:83
#, c-format
msgid "USB device query 'all' must not have data"
msgstr "Poizvedba naprave USB »all« ne sme vsebovati podatkov"

#: common/flatpak-usb.c:102
#, c-format
msgid "USB query rule 'cls' must be in the form CLASS:SUBCLASS or CLASS:*"
msgstr ""
"Pravilo poizvedbe USB »cls« mora biti v obliki RAZRED:PODRAZRED ali RAZRED:*"

#: common/flatpak-usb.c:111
#, c-format
msgid "Invalid USB class"
msgstr "Neveljaven razred USB"

#: common/flatpak-usb.c:125
#, c-format
msgid "Invalid USB subclass"
msgstr "Neveljaven podrazred USB"

#: common/flatpak-usb.c:141 common/flatpak-usb.c:148
#, c-format
msgid "USB query rule 'dev' must have a valid 4-digit hexadecimal product id"
msgstr ""
"Pravilo poizvedbe USB »dev« mora imeti veljaven 4-mestni šestnajstiški ID "
"izdelka"

#: common/flatpak-usb.c:164 common/flatpak-usb.c:171
#, c-format
msgid "USB query rule 'vnd' must have a valid 4-digit hexadecimal vendor id"
msgstr ""
"Pravilo poizvedbe USB »vnd« mora imeti veljavni 4-mestni šestnajstiški ID "
"proizvajalca"

#: common/flatpak-usb.c:205
#, c-format
msgid "USB device queries must be in the form TYPE:DATA"
msgstr "Poizvedbe za naprave USB morajo biti v obliki VRSTA:PODATKI"

#: common/flatpak-usb.c:225
#, c-format
msgid "Unknown USB query rule %s"
msgstr "Neznano pravilo poizvedbe USB %s"

#: common/flatpak-usb.c:248
#, c-format
msgid "Empty USB query"
msgstr "Prazna poizvedba USB"

#: common/flatpak-usb.c:274
#, c-format
msgid "Multiple USB query rules of the same type is not supported"
msgstr "Več pravil poizvedbe USB iste vrste ni podprtih"

#: common/flatpak-usb.c:283
#, c-format
msgid "'all' must not contain extra query rules"
msgstr "»all« ne sme vsebovati dodatnih pravil za poizvedbo"

#: common/flatpak-usb.c:291
#, c-format
msgid "USB queries with 'dev' must also specify vendors"
msgstr "Poizvedbe USB z »dev« morajo navesti tudi proizvajalca"

#: common/flatpak-utils.c:712
msgid "Glob can't match apps"
msgstr "Glob se ne more ujemati z aplikacijami"

#: common/flatpak-utils.c:737
msgid "Empty glob"
msgstr "Prazen glob"

#: common/flatpak-utils.c:756
msgid "Too many segments in glob"
msgstr "Preveč segmentov v glob-u"

#: common/flatpak-utils.c:777
#, c-format
msgid "Invalid glob character '%c'"
msgstr "Neveljaven znak glob »%c«"

#: common/flatpak-utils.c:831
#, c-format
msgid "Missing glob on line %d"
msgstr "Manjka glob v vrstici %d"

#: common/flatpak-utils.c:835
#, c-format
msgid "Trailing text on line %d"
msgstr "Sledilno besedilo v vrstici %d"

#: common/flatpak-utils.c:839
#, c-format
msgid "on line %d"
msgstr "v vrstici %d"

#: common/flatpak-utils.c:861
#, c-format
msgid "Unexpected word '%s' on line %d"
msgstr "Nepričakovana beseda »%s« v vrstici %d"

#: common/flatpak-utils.c:2118
#, c-format
msgid "Invalid require-flatpak argument %s"
msgstr "Neveljaven argument require-flatpak %s"

#: common/flatpak-utils.c:2128 common/flatpak-utils.c:2147
#, c-format
msgid "%s needs a later flatpak version (%s)"
msgstr "%s potrebuje novejšo različico Flatpak (%s)"

#: oci-authenticator/flatpak-oci-authenticator.c:291
msgid "Not a oci remote, missing summary.xa.oci-repository"
msgstr "Ni oddaljeni OCI, manjka summary.xa.oci-repository"

#: oci-authenticator/flatpak-oci-authenticator.c:477
msgid "Not a OCI remote"
msgstr "Ni oddaljeni OCI"

#: oci-authenticator/flatpak-oci-authenticator.c:488
msgid "Invalid token"
msgstr "Neveljaven žeton"

#: portal/flatpak-portal.c:2292
#, c-format
msgid "No portal support found"
msgstr "Podpore za portale ni moč najti"

#: portal/flatpak-portal.c:2298
msgid "Deny"
msgstr "Zavrni"

#: portal/flatpak-portal.c:2300
msgid "Update"
msgstr "Posodobi"

#: portal/flatpak-portal.c:2305
#, c-format
msgid "Update %s?"
msgstr "Želite posodobiti %s?"

#: portal/flatpak-portal.c:2317
msgid "The application wants to update itself."
msgstr "Aplikacija se želi posodobiti."

#: portal/flatpak-portal.c:2318
msgid "Update access can be changed any time from the privacy settings."
msgstr ""
"Dostop do posodobitev lahko kadarkoli spremenite iz nastavitev zasebnosti."

#: portal/flatpak-portal.c:2343
#, c-format
msgid "Application update not allowed"
msgstr "Posodobitev aplikacije ni dovoljena"

#: portal/flatpak-portal.c:2501
#, c-format
msgid "Self update not supported, new version requires new permissions"
msgstr "Samoposodobitev ni podprta, nova različica zahteva nova dovoljenja"

#: portal/flatpak-portal.c:2684 portal/flatpak-portal.c:2702
#, c-format
msgid "Update ended unexpectedly"
msgstr "Posodobitev se je nepričakovano končala"

#. SECURITY:
#. - Normal users need admin authentication to install software
#. system-wide.
#. - Note that we install polkit rules that allow local users
#. in the wheel group to install without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:23
msgid "Install signed application"
msgstr "Namesti podpisano aplikacijo"

#: system-helper/org.freedesktop.Flatpak.policy.in:24
#: system-helper/org.freedesktop.Flatpak.policy.in:42
msgid "Authentication is required to install software"
msgstr "Preverjanje pristnosti je potrebno za namestitev programske opreme"

#. SECURITY:
#. - Normal users need admin authentication to install software
#. system-wide.
#. - Note that we install polkit rules that allow local users
#. in the wheel group to install without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:41
msgid "Install signed runtime"
msgstr "Namestit podpisani izvajalnik"

#. SECURITY:
#. - Normal users do not require admin authentication to update an
#. app as the commit will be signed, and the action is required
#. to update the system when unattended.
#. - Changing this to anything other than 'yes' will break unattended
#. updates.
#: system-helper/org.freedesktop.Flatpak.policy.in:60
msgid "Update signed application"
msgstr "Posodobi podpisano aplikacijo"

#: system-helper/org.freedesktop.Flatpak.policy.in:61
#: system-helper/org.freedesktop.Flatpak.policy.in:80
msgid "Authentication is required to update software"
msgstr "Preverjanje pristnosti je potrebno za posodobitev programske opreme"

#. SECURITY:
#. - Normal users do not require admin authentication to update a
#. runtime as the commit will be signed, and the action is required
#. to update the system when unattended.
#. - Changing this to anything other than 'yes' will break unattended
#. updates.
#: system-helper/org.freedesktop.Flatpak.policy.in:79
msgid "Update signed runtime"
msgstr "Posodobi podpisani izvajalnik"

#. SECURITY:
#. - Normal users do not need authentication to update metadata
#. from signed repositories.
#: system-helper/org.freedesktop.Flatpak.policy.in:94
msgid "Update remote metadata"
msgstr "Posodobi oddaljene metapodatke"

#: system-helper/org.freedesktop.Flatpak.policy.in:95
msgid "Authentication is required to update remote info"
msgstr ""
"Preverjanje pristnosti je potrebno za posodobitev oddaljenih informacij"

#. SECURITY:
#. - Normal users do not need authentication to modify the
#. OSTree repository
#. - Note that we install polkit rules that allow local users
#. in the wheel group to modify repos without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:111
msgid "Update system repository"
msgstr "Posodobi sistemsko skladišče"

#: system-helper/org.freedesktop.Flatpak.policy.in:112
msgid "Authentication is required to modify a system repository"
msgstr ""
"Preverjanje pristnosti je potrebno za spreminjanje sistemskega skladišča"

#. SECURITY:
#. - Normal users need admin authentication to install software
#. system-wide.
#: system-helper/org.freedesktop.Flatpak.policy.in:126
msgid "Install bundle"
msgstr "Namesti sveženj"

#: system-helper/org.freedesktop.Flatpak.policy.in:127
msgid "Authentication is required to install software from $(path)"
msgstr ""
"Preverjanje pristnosti je potrebno za namestitev programske opreme iz $(path)"

#. SECURITY:
#. - Normal users need admin authentication to uninstall software
#. system-wide.
#. - Note that we install polkit rules that allow local users
#. in the wheel group to uninstall without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:144
msgid "Uninstall runtime"
msgstr "Odstrani izvajalnik"

#: system-helper/org.freedesktop.Flatpak.policy.in:145
msgid "Authentication is required to uninstall software"
msgstr "Preverjanje pristnosti je potrebno za odstranitev programske opreme"

#. SECURITY:
#. - Normal users need admin authentication to uninstall software
#. system-wide.
#. - Note that we install polkit rules that allow local users
#. in the wheel group to uninstall without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:161
msgid "Uninstall app"
msgstr "Odstrani aplikacijo"

#: system-helper/org.freedesktop.Flatpak.policy.in:162
msgid "Authentication is required to uninstall $(ref)"
msgstr "Preverjanje pristnosti je potrebno za odstranitev $(ref)"

#. SECURITY:
#. - Normal users need admin authentication to configure system-wide
#. software repositories.
#: system-helper/org.freedesktop.Flatpak.policy.in:177
msgid "Configure Remote"
msgstr "Prilagodi na daljavo"

#: system-helper/org.freedesktop.Flatpak.policy.in:178
msgid "Authentication is required to configure software repositories"
msgstr ""
"Preverjanje pristnosti je potrebno za prilagoditev skladišča programske "
"opreme"

#. SECURITY:
#. - Normal users need admin authentication to configure the system-wide
#. Flatpak installation.
#: system-helper/org.freedesktop.Flatpak.policy.in:192
msgid "Configure"
msgstr "Prilagodi"

#: system-helper/org.freedesktop.Flatpak.policy.in:193
msgid "Authentication is required to configure software installation"
msgstr ""
"Preverjanje pristnosti je potrebno za prilagoditev namestitve programske "
"opreme"

#. SECURITY:
#. - Normal users do not require admin authentication to update
#. appstream data as it will be signed, and the action is required
#. to update the system when unattended.
#. - Changing this to anything other than 'yes' will break unattended
#. updates.
#: system-helper/org.freedesktop.Flatpak.policy.in:210
msgid "Update appstream"
msgstr "Posodobi appstream"

#: system-helper/org.freedesktop.Flatpak.policy.in:211
msgid "Authentication is required to update information about software"
msgstr ""
"Preverjanje pristnosti je potrebno za posodobitev informacij o programski "
"opremi"

#. SECURITY:
#. - Normal users do not require admin authentication to update
#. metadata as it will be signed, and the action is required
#. to update the system when unattended.
#. - Changing this to anything other than 'yes' will break unattended
#. updates.
#: system-helper/org.freedesktop.Flatpak.policy.in:228
msgid "Update metadata"
msgstr "Posodobi metapodatke"

#: system-helper/org.freedesktop.Flatpak.policy.in:229
msgid "Authentication is required to update metadata"
msgstr "Preverjanje pristnosti je potrebno za posodobitev metapodatkov"

#. SECURITY:
#. - Authorisation to actually install software is controlled by
#. org.freedesktop.Flatpak.app-install.
#. - This action is checked after app-install, as it can only be done
#. once the app’s data (including its content rating) has been
#. downloaded.
#. - This action is checked to see if the installation should be allowed
#. based on whether the app being installed has content which doesn’t
#. comply with the user’s parental controls policy (the content is
#. ‘too extreme’).
#. - It is checked only if an app has too extreme content for the user
#. who is trying to install it (in which case, the app is ‘unsafe’).
#. - Typically, normal users will need admin permission to install apps
#. with extreme content; admins will be able to install it without
#. additional checks.
#. - In order to configure the policy so that admins can install safe and
#. unsafe software anywhere without authorisation, and non-admins can
#. install safe software in their user or system dirs without
#. authorisation, but need authorisation to install unsafe software
#. anywhere:
#. * Unconditionally return `yes` from `app-install`.
#. * Return `auth_admin` from `override-parental-controls` for users
#. not in `@privileged_group@`, and `yes` for users in it.
#. * Set the malcontent `is-{user,system}-installation-allowed`
#. properties of all non-admins’ parental controls policies to true.
#. - In order to configure the policy so that admins can install safe and
#. unsafe software anywhere without authorisation, and non-admins can
#. install safe software in their user dir without authorisation, but
#. need authorisation to install safe software in the system dir or to
#. install unsafe software anywhere:
#. * Unconditionally return `yes` from `app-install`.
#. * Return `auth_admin` from `override-parental-controls` for users
#. not in `@privileged_group@`, and `yes` for users in it.
#. * Set the malcontent `is-user-installation-allowed` property of all
#. non-admins’ parental controls policies to true.
#. * Set the malcontent `is-system-installation-allowed` property of
#. all non-admins’ parental controls policies to false.
#. - In order to configure the policy so that all users (including
#. admins) can install safe software anywhere without authorisation,
#. but need authorisation to install unsafe software anywhere (i.e.
#. applying parental controls to admins too):
#. * Unconditionally return `yes` from `app-install`.
#. * Unconditionally return `auth_admin` from `override-parental-controls`.
#. * Set the malcontent `is-user-installation-allowed` property of all
#. users’ parental controls policies to true.
#. * Set the malcontent `is-system-installation-allowed` property of
#. all users’ parental controls policies to true.
#: system-helper/org.freedesktop.Flatpak.policy.in:287
msgid "Override parental controls for installs"
msgstr "Preglasi starševski nadzor za namestitve"

#: system-helper/org.freedesktop.Flatpak.policy.in:288
msgid ""
"Authentication is required to install software which is restricted by your "
"parental controls policy"
msgstr ""
"Preverjanje pristnosti je potrebno za namestitev programske opreme, ki jo "
"omejuje pravilnik starševskega nadzora"

#. SECURITY:
#. - This is like org.freedesktop.Flatpak.override-parental-controls, but
#. it’s queried for app updates, whereas the former is queried for app
#. installs.
#. - As with the above action, this one is only queried if
#. org.freedesktop.Flatpak.app-update has allowed the app update, and
#. only if the app being updated has too extreme content for the user
#. who is trying to update it.
#. - The default policy for this is to *allow* updates to ‘too extreme’
#. apps by default, on the basis that having an out-of-date (i.e.
#. insecure or unsupported) app is a worse outcome than automatically
#. installing an update which has radically different content from the
#. version of the app which the parent originally vetted and installed.
#: system-helper/org.freedesktop.Flatpak.policy.in:313
msgid "Override parental controls for updates"
msgstr "Preglasi starševski nadzor za posodobitve"

#: system-helper/org.freedesktop.Flatpak.policy.in:314
msgid ""
"Authentication is required to update software which is restricted by your "
"parental controls policy"
msgstr ""
"Preverjanje pristnosti je potrebno za namestitev programske opreme, ki jo "
"omejujejo pravila starševskega nadzora"

===== ./po/tr.po =====
# Turkish translation for Flatpak.
# Copyright (C) 2017-2026 Flatpak's COPYRIGHT HOLDER
# This file is distributed under the same license as the flatpak package.
#
# Çağatay Yiğit Şahin <cyigitsahin@outlook.com>, 2017.
# Muhammet Kara <muhammetk@gmail.com>, 2017.
# Serdar Sağlam <teknomobil@yandex.com>, 2019.
# Emir SARI <emir_sari@icloud.com>, 2026
# Sabri Ünal <yakushabb@gmail.com>, 2022-2026.
# Emin Tufan Çetin <etcetin@gmail.com>, 2025-2026.
#
msgid ""
msgstr ""
"Project-Id-Version: Flatpak master\n"
"Report-Msgid-Bugs-To: https://github.com/flatpak/flatpak/issues\n"
"POT-Creation-Date: 2026-05-27 16:39+0200\n"
"PO-Revision-Date: 2026-04-18 08:00+0300\n"
"Last-Translator: Emin Tufan Çetin <etcetin@gmail.com>\n"
"Language-Team: Türkçe <takim@gnome.org.tr>\n"
"Language: tr\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
"X-Generator: Poedit 3.8\n"

#: app/flatpak-builtins-build-bundle.c:59
msgid "Export runtime instead of app"
msgstr "Uygulama yerine çalışma zamanını dışa aktar"

#: app/flatpak-builtins-build-bundle.c:60
msgid "Arch to bundle for"
msgstr "Paketleneceği mimari"

#: app/flatpak-builtins-build-bundle.c:60
#: app/flatpak-builtins-build-export.c:62 app/flatpak-builtins-build-init.c:53
#: app/flatpak-builtins-build-sign.c:42 app/flatpak-builtins-create-usb.c:46
#: app/flatpak-builtins-info.c:55 app/flatpak-builtins-install.c:67
#: app/flatpak-builtins-list.c:50 app/flatpak-builtins-make-current.c:38
#: app/flatpak-builtins-remote-info.c:54 app/flatpak-builtins-remote-ls.c:56
#: app/flatpak-builtins-run.c:158 app/flatpak-builtins-search.c:37
#: app/flatpak-builtins-uninstall.c:54 app/flatpak-builtins-update.c:56
msgid "ARCH"
msgstr "MİMARİ"

#: app/flatpak-builtins-build-bundle.c:61
msgid "URL for repo"
msgstr "Depo URLʼsi"

#: app/flatpak-builtins-build-bundle.c:61
#: app/flatpak-builtins-build-bundle.c:62
#: app/flatpak-builtins-build-update-repo.c:68
#: app/flatpak-builtins-build-update-repo.c:72
#: app/flatpak-builtins-build-update-repo.c:73
#: app/flatpak-builtins-history.c:69 app/flatpak-builtins-remote-add.c:80
#: app/flatpak-builtins-remote-add.c:81 app/flatpak-builtins-remote-add.c:85
#: app/flatpak-builtins-remote-list.c:53
#: app/flatpak-builtins-remote-modify.c:70
#: app/flatpak-builtins-remote-modify.c:85
#: app/flatpak-builtins-remote-modify.c:86
#: app/flatpak-builtins-remote-modify.c:90
msgid "URL"
msgstr "URL"

#: app/flatpak-builtins-build-bundle.c:62
msgid "URL for runtime flatpakrepo file"
msgstr "Çalışma zamanı flatpakrepo dosyası URLʼsi"

#: app/flatpak-builtins-build-bundle.c:63
msgid "Add GPG key from FILE (- for stdin)"
msgstr "DOSYA’dan GPG anahtarı ekle (stdin için -)"

#: app/flatpak-builtins-build-bundle.c:63 app/flatpak-builtins-build.c:54
#: app/flatpak-builtins-build-export.c:67
#: app/flatpak-builtins-build-update-repo.c:83
#: app/flatpak-builtins-install.c:81 app/flatpak-builtins-remote-add.c:84
#: app/flatpak-builtins-remote-add.c:86 app/flatpak-builtins-remote-modify.c:89
#: app/flatpak-builtins-remote-modify.c:92
msgid "FILE"
msgstr "DOSYA"

#: app/flatpak-builtins-build-bundle.c:64
msgid "GPG Key ID to sign the OCI image with"
msgstr "OCI görüntüsünün imzalanacağı GPG Anahtar Kimliği"

#: app/flatpak-builtins-build-bundle.c:64
#: app/flatpak-builtins-build-commit-from.c:68
#: app/flatpak-builtins-build-export.c:68
#: app/flatpak-builtins-build-import-bundle.c:49
#: app/flatpak-builtins-build-sign.c:44
#: app/flatpak-builtins-build-update-repo.c:84
msgid "KEY-ID"
msgstr "ANAHTAR-KİMLİĞİ"

#: app/flatpak-builtins-build-bundle.c:65
#: app/flatpak-builtins-build-commit-from.c:69
#: app/flatpak-builtins-build-export.c:71
#: app/flatpak-builtins-build-import-bundle.c:50
#: app/flatpak-builtins-build-sign.c:45
#: app/flatpak-builtins-build-update-repo.c:85
msgid "GPG Homedir to use when looking for keyrings"
msgstr "Anahtarlık aramak için GPG Evdizini"

#: app/flatpak-builtins-build-bundle.c:65
#: app/flatpak-builtins-build-commit-from.c:69
#: app/flatpak-builtins-build-export.c:71
#: app/flatpak-builtins-build-import-bundle.c:50
#: app/flatpak-builtins-build-sign.c:45
#: app/flatpak-builtins-build-update-repo.c:85
msgid "HOMEDIR"
msgstr "EVDİZİNİ"

#: app/flatpak-builtins-build-bundle.c:66
msgid "OSTree commit to create a delta bundle from"
msgstr "Delta paketi oluşturmak için OSTree işlemesi"

#: app/flatpak-builtins-build-bundle.c:66 app/flatpak-builtins-remote-info.c:55
#: app/flatpak-builtins-update.c:57
msgid "COMMIT"
msgstr "İŞLEME"

#: app/flatpak-builtins-build-bundle.c:67
msgid "Export oci image instead of flatpak bundle"
msgstr "Flatpak paketi yerine oci görüntüsü dışa aktar"

#: app/flatpak-builtins-build-bundle.c:70
msgid "How to compress OCI image layers (default: gzip)"
msgstr "OCI görüntü katmanlarının nasıl sıkıştırılacağı (öntanımlı: gzip)"

#: app/flatpak-builtins-build-bundle.c:634
msgid ""
"LOCATION FILENAME NAME [BRANCH] - Create a single file bundle from a local "
"repository"
msgstr "KONUM DOSYAADI AD [DAL] - Yerel depodan tek dosya paketi oluştur"

#: app/flatpak-builtins-build-bundle.c:641
msgid "LOCATION, FILENAME and NAME must be specified"
msgstr "KONUM, DOSYAADI ve AD belirtilmelidir"

#: app/flatpak-builtins-build-bundle.c:644
#: app/flatpak-builtins-build-export.c:844
#: app/flatpak-builtins-build-import-bundle.c:136
#: app/flatpak-builtins-build-init.c:217 app/flatpak-builtins-build-sign.c:76
#: app/flatpak-builtins-document-export.c:112
#: app/flatpak-builtins-document-info.c:75
#: app/flatpak-builtins-document-list.c:191
#: app/flatpak-builtins-document-unexport.c:70
#: app/flatpak-builtins-history.c:482 app/flatpak-builtins-info.c:130
#: app/flatpak-builtins-install.c:181 app/flatpak-builtins-install.c:234
#: app/flatpak-builtins-install.c:298 app/flatpak-builtins-list.c:419
#: app/flatpak-builtins-make-current.c:72 app/flatpak-builtins-override.c:73
#: app/flatpak-builtins-permission-list.c:162
#: app/flatpak-builtins-permission-remove.c:132
#: app/flatpak-builtins-remote-add.c:323
#: app/flatpak-builtins-remote-delete.c:68
#: app/flatpak-builtins-remote-list.c:241 app/flatpak-builtins-remote-ls.c:407
msgid "Too many arguments"
msgstr "Çok fazla argüman"

#: app/flatpak-builtins-build-bundle.c:659
#: app/flatpak-builtins-build-commit-from.c:338
#: app/flatpak-builtins-build-commit-from.c:351
#: app/flatpak-builtins-build-import-bundle.c:145
#, c-format
msgid "'%s' is not a valid repository"
msgstr "'%s' geçerli bir depo değil"

#: app/flatpak-builtins-build-bundle.c:663
#, c-format
msgid "'%s' is not a valid repository: "
msgstr "'%s' geçerli bir depo değil: "

#: app/flatpak-builtins-build-bundle.c:674 app/flatpak-builtins-build-sign.c:88
#: common/flatpak-dir.c:14293
#, c-format
msgid "'%s' is not a valid name: %s"
msgstr "'%s' geçerli bir ad değil: %s"

#: app/flatpak-builtins-build-bundle.c:677
#: app/flatpak-builtins-build-export.c:865 app/flatpak-builtins-build-sign.c:91
#: common/flatpak-dir.c:14299
#, c-format
msgid "'%s' is not a valid branch name: %s"
msgstr "'%s' geçerli bir dal adı değil: %s"

#: app/flatpak-builtins-build-bundle.c:691
#: app/flatpak-builtins-build-import-bundle.c:149
#: app/flatpak-builtins-build-init.c:281
#, c-format
msgid "'%s' is not a valid filename"
msgstr "'%s' geçerli bir dosya adı değil"

#: app/flatpak-builtins-build-bundle.c:706
msgid "--oci-layer-compress value must be gzip or zstd"
msgstr "--oci-layer-compress değeri gzip ya da zstd olmalıdır"

#: app/flatpak-builtins-build.c:49
msgid "Use Platform runtime rather than Sdk"
msgstr "Sdk yerine Platform çalışma zamanını kullan"

#: app/flatpak-builtins-build.c:50
msgid "Make destination readonly"
msgstr "Hedefi salt okunur yap"

#: app/flatpak-builtins-build.c:51
msgid "Add bind mount"
msgstr "Bağlama noktası ekle"

#: app/flatpak-builtins-build.c:51
msgid "DEST=SRC"
msgstr "HEDEF=KAYNAK"

#: app/flatpak-builtins-build.c:52
msgid "Start build in this directory"
msgstr "İnşaya bu dizinde başla"

#: app/flatpak-builtins-build.c:52 app/flatpak-builtins-build.c:53
#: app/flatpak-builtins-build-init.c:64 app/flatpak-builtins-run.c:160
msgid "DIR"
msgstr "DİZİN"

#: app/flatpak-builtins-build.c:53
msgid "Where to look for custom sdk dir (defaults to 'usr')"
msgstr "Özel sdk dizini için bakılacak yer ('usr' öntanımlıdır)"

#: app/flatpak-builtins-build.c:54 app/flatpak-builtins-build-export.c:67
msgid "Use alternative file for the metadata"
msgstr "Üst veri için alternatif dosya kullan"

#: app/flatpak-builtins-build.c:55 app/flatpak-builtins-run.c:177
msgid "Kill processes when the parent process dies"
msgstr "Ana işlem öldüğünde işlemleri sonlandır"

#: app/flatpak-builtins-build.c:56
msgid "Export application homedir directory to build"
msgstr "İnşa için uygulama evdizin dizinini dışa aktar"

#: app/flatpak-builtins-build.c:57 app/flatpak-builtins-run.c:165
msgid "Log session bus calls"
msgstr "Oturum veri yolu çağrılarını günlükle"

#: app/flatpak-builtins-build.c:58 app/flatpak-builtins-run.c:166
msgid "Log system bus calls"
msgstr "Sistem veri yolu çağrılarını günlükle"

#: app/flatpak-builtins-build.c:262
msgid "DIRECTORY [COMMAND [ARGUMENT…]] - Build in directory"
msgstr "DİZİN [KOMUT [ARGÜMAN…]] - Dizinde inşa et"

#: app/flatpak-builtins-build.c:285 app/flatpak-builtins-build-finish.c:656
msgid "DIRECTORY must be specified"
msgstr "DİZİN belirtilmelidir"

#: app/flatpak-builtins-build.c:296 app/flatpak-builtins-build-export.c:887
#, c-format
msgid "Build directory %s not initialized, use flatpak build-init"
msgstr "İnşa dizini %s ilklenmedi, flatpak build-init’i kullanın"

#: app/flatpak-builtins-build.c:315
msgid "metadata invalid, not application or runtime"
msgstr "üst veri geçersiz, uygulama ya da çalışma zamanı değil"

#: app/flatpak-builtins-build.c:446
#, c-format
msgid "No extension point matching %s in %s"
msgstr "%2$s içinde %1$s ile eşleşen uzantı noktası yok"

#: app/flatpak-builtins-build.c:635
#, c-format
msgid "Missing '=' in bind mount option '%s'"
msgstr "Bağlama noktası seçeneği '%s' içinde '=' eksik"

#: app/flatpak-builtins-build.c:679 common/flatpak-run.c:3961
#, c-format
msgid "Unable to start app"
msgstr "Uygulama başlatılamadı"

#: app/flatpak-builtins-build-commit-from.c:58
msgid "Source repo dir"
msgstr "Kaynak depo dizini"

#: app/flatpak-builtins-build-commit-from.c:58
msgid "SRC-REPO"
msgstr "KAYNAK-DEPO"

#: app/flatpak-builtins-build-commit-from.c:59
msgid "Source repo ref"
msgstr "Kaynak depo referansı"

#: app/flatpak-builtins-build-commit-from.c:59
msgid "SRC-REF"
msgstr "KAYNAK-REFERANS"

#: app/flatpak-builtins-build-commit-from.c:64
#: app/flatpak-builtins-build-export.c:60
msgid "One line subject"
msgstr "Tek satır konu"

#: app/flatpak-builtins-build-commit-from.c:64
#: app/flatpak-builtins-build-export.c:60
msgid "SUBJECT"
msgstr "KONU"

#: app/flatpak-builtins-build-commit-from.c:65
#: app/flatpak-builtins-build-export.c:61
msgid "Full description"
msgstr "Tüm açıklama"

#: app/flatpak-builtins-build-commit-from.c:65
#: app/flatpak-builtins-build-export.c:61
msgid "BODY"
msgstr "GÖVDE"

#: app/flatpak-builtins-build-commit-from.c:66
#: app/flatpak-builtins-build-export.c:64
#: app/flatpak-builtins-build-import-bundle.c:51
msgid "Update the appstream branch"
msgstr "Appstream dalını güncelle"

#: app/flatpak-builtins-build-commit-from.c:67
#: app/flatpak-builtins-build-export.c:65
#: app/flatpak-builtins-build-import-bundle.c:52
#: app/flatpak-builtins-build-update-repo.c:87
msgid "Don't update the summary"
msgstr "Özeti güncelleme"

#: app/flatpak-builtins-build-commit-from.c:68
#: app/flatpak-builtins-build-export.c:68
#: app/flatpak-builtins-build-import-bundle.c:49
#: app/flatpak-builtins-build-sign.c:44
msgid "GPG Key ID to sign the commit with"
msgstr "İşlemeyi imzalamak için GPG Anahtar Kimliği"

#: app/flatpak-builtins-build-commit-from.c:70
#: app/flatpak-builtins-build-export.c:73
msgid "Mark build as end-of-life"
msgstr "İnşayı ömrünü doldurdu olarak imle"

#: app/flatpak-builtins-build-commit-from.c:70
#: app/flatpak-builtins-build-export.c:73
msgid "REASON"
msgstr "NEDEN"

#: app/flatpak-builtins-build-commit-from.c:71
msgid ""
"Mark refs matching the OLDID prefix as end-of-life, to be replaced with the "
"given NEWID"
msgstr ""
"ESKİKİMLİK ön ekiyle eşleşen referansları, verilen YENİKİMLİK ile "
"değiştirilmek üzere ömrünü doldurdu olarak imle"

#: app/flatpak-builtins-build-commit-from.c:71
msgid "OLDID=NEWID"
msgstr "ESKİKİMLİK=YENİKİMLİK"

#: app/flatpak-builtins-build-commit-from.c:72
#: app/flatpak-builtins-build-export.c:75
msgid "Set type of token needed to install this commit"
msgstr "Bu işlemeyi kurmak için gereken jeton türünü belirle"

#: app/flatpak-builtins-build-commit-from.c:72
#: app/flatpak-builtins-build-export.c:75
msgid "VAL"
msgstr "DEĞER"

#: app/flatpak-builtins-build-commit-from.c:73
msgid "Override the timestamp of the commit (NOW for current time)"
msgstr "İşleme zaman damgasını geçeriz kıl (şimdiki zaman için NOW)"

#: app/flatpak-builtins-build-commit-from.c:73
#: app/flatpak-builtins-build-export.c:76
msgid "TIMESTAMP"
msgstr "ZAMANDAMGASI"

#: app/flatpak-builtins-build-commit-from.c:75
#: app/flatpak-builtins-build-export.c:80
#: app/flatpak-builtins-build-import-bundle.c:53
#: app/flatpak-builtins-build-update-repo.c:97
msgid "Don't generate a summary index"
msgstr "Özet indeksi oluşturma"

#: app/flatpak-builtins-build-commit-from.c:278
msgid "DST-REPO [DST-REF…] - Make a new commit from existing commits"
msgstr ""
"HEDEF-DEPO [HEDEF-REFERANS]… - Var olan işlemelere dayalı yeni işleme yap"

#: app/flatpak-builtins-build-commit-from.c:285
msgid "DST-REPO must be specified"
msgstr "HEDEF-DEPO belirtilmelidir"

#: app/flatpak-builtins-build-commit-from.c:293
msgid ""
"If --src-repo is not specified, exactly one destination ref must be specified"
msgstr ""
"--src-repo belirtilmemişse yalnızca tek bir hedef referans belirtilmelidir"

#: app/flatpak-builtins-build-commit-from.c:296
msgid ""
"If --src-ref is specified, exactly one destination ref must be specified"
msgstr ""
"--src-ref belirtilmişse, yalnızca tek bir hedef referans belirtilmelidir"

#: app/flatpak-builtins-build-commit-from.c:299
msgid "Either --src-repo or --src-ref must be specified"
msgstr "--src-repo ya da --src-ref belirtilmelidir"

#: app/flatpak-builtins-build-commit-from.c:315
msgid "Invalid argument format of use  --end-of-life-rebase=OLDID=NEWID"
msgstr ""
"Geçersiz argüman kullanım biçimi --end-of-life-rebase=ESKİKİMLİK=YENİKİMLİK"

#: app/flatpak-builtins-build-commit-from.c:321
#: app/flatpak-builtins-build-commit-from.c:324
#, c-format
msgid "Invalid name %s in --end-of-life-rebase"
msgstr "--end-of-life-rebase içinde geçersiz %s adı"

#: app/flatpak-builtins-build-commit-from.c:333
#: app/flatpak-builtins-build-export.c:1092
#, c-format
msgid "Could not parse '%s'"
msgstr "'%s' ayrıştırılamadı"

#: app/flatpak-builtins-build-commit-from.c:498
msgid "Can't commit from partial source commit"
msgstr "Kısmi kaynak işlemesinden işleme yapılamaz"

#: app/flatpak-builtins-build-commit-from.c:503
#, c-format
msgid "%s: no change\n"
msgstr "%s: değişiklik yok\n"

#: app/flatpak-builtins-build-export.c:62
msgid "Architecture to export for (must be host compatible)"
msgstr "Dışa aktarılacağı mimari (makineyle uyumlu olmalıdır)"

#: app/flatpak-builtins-build-export.c:63
msgid "Commit runtime (/usr), not /app"
msgstr "Çalışma zamanını (/usr) işle, /app’i değil"

#: app/flatpak-builtins-build-export.c:66
msgid "Use alternative directory for the files"
msgstr "Dosyalar için alternatif dizin kullan"

#: app/flatpak-builtins-build-export.c:66
msgid "SUBDIR"
msgstr "ALTDİZİN"

#: app/flatpak-builtins-build-export.c:69
msgid "Files to exclude"
msgstr "Dışlanacak dosyalar"

#: app/flatpak-builtins-build-export.c:69
#: app/flatpak-builtins-build-export.c:70
#: app/flatpak-builtins-build-update-repo.c:90
msgid "PATTERN"
msgstr "ÖRÜNTÜ"

#: app/flatpak-builtins-build-export.c:70
msgid "Excluded files to include"
msgstr "İçerilecek dışlanan dosyalar"

#: app/flatpak-builtins-build-export.c:74
msgid "Mark build as end-of-life, to be replaced with the given ID"
msgstr ""
"İnşayı, verilen kimlikle değiştirilmek üzere ömrünü doldurdu olarak imle"

#: app/flatpak-builtins-build-export.c:74
#: app/flatpak-builtins-document-list.c:49 app/flatpak-cli-transaction.c:1427
msgid "ID"
msgstr "KİMLİK"

#: app/flatpak-builtins-build-export.c:76
msgid "Override the timestamp of the commit"
msgstr "İşleme zaman damgasını geçersiz kıl"

#: app/flatpak-builtins-build-export.c:77
#: app/flatpak-builtins-build-update-repo.c:75
#: app/flatpak-builtins-remote-add.c:83 app/flatpak-builtins-remote-list.c:54
#: app/flatpak-builtins-remote-modify.c:88
msgid "Collection ID"
msgstr "Koleksiyon Kimliği"

#: app/flatpak-builtins-build-export.c:472
#, c-format
msgid "WARNING: Error running desktop-file-validate: %s\n"
msgstr "UYARI: desktop-file-validate çalıştırılırken hata: %s\n"

#: app/flatpak-builtins-build-export.c:480
#, c-format
msgid "WARNING: Error reading from desktop-file-validate: %s\n"
msgstr "UYARI: desktop-file-validate’den okunurken hata: %s\n"

#: app/flatpak-builtins-build-export.c:486
#, c-format
msgid "WARNING: Failed to validate desktop file %s: %s\n"
msgstr "UYARI: %s masaüstü dosyası doğrulanamadı: %s\n"

#: app/flatpak-builtins-build-export.c:513
#, c-format
msgid "WARNING: Can't find Exec key in %s: %s\n"
msgstr "UYARI: %s içinde Exec anahtarı bulunamadı: %s\n"

# Binary için İkili dosya çevirisi kullanıldı
#: app/flatpak-builtins-build-export.c:521
#: app/flatpak-builtins-build-export.c:614
#, c-format
msgid "WARNING: Binary not found for Exec line in %s: %s\n"
msgstr "UYARI: %s içinde Exec satırı için ikili dosya bulunamadı: %s\n"

#: app/flatpak-builtins-build-export.c:529
#, c-format
msgid "WARNING: Icon not matching app id in %s: %s\n"
msgstr "UYARI: Simge, %s içindeki uygulama kimliğiyle uyuşmuyor: %s\n"

#: app/flatpak-builtins-build-export.c:552
#, c-format
msgid "WARNING: Icon referenced in desktop file but not exported: %s\n"
msgstr ""
"UYARI: Simge, Masaüstü dosyasında başvurulmuş ancak dışa aktarılmadı: %s\n"

#: app/flatpak-builtins-build-export.c:719
#, c-format
msgid "Invalid uri type %s, only http/https supported"
msgstr "Geçersiz uri türü %s, yalnızca http/https destekli"

#: app/flatpak-builtins-build-export.c:737
#, c-format
msgid "Unable to find basename in %s, specify a name explicitly"
msgstr "%s içinde temel ad bulunamadı, doğrudan ad belirt"

#: app/flatpak-builtins-build-export.c:746
#, c-format
msgid "No slashes allowed in extra data name"
msgstr "Ek veri adında yan çizgi kullanılamaz"

#: app/flatpak-builtins-build-export.c:758
#, c-format
msgid "Invalid format for sha256 checksum: '%s'"
msgstr "Sha256 sağlama toplamı için geçersiz biçim: '%s'"

#: app/flatpak-builtins-build-export.c:768
#, c-format
msgid "Extra data sizes of zero not supported"
msgstr "Sıfır ek veri boyutu desteklenmemektedir"

#: app/flatpak-builtins-build-export.c:830
msgid ""
"LOCATION DIRECTORY [BRANCH] - Create a repository from a build directory"
msgstr "KONUM DİZİN [DAL] - İnşa dizininden yeni depo oluştur"

#: app/flatpak-builtins-build-export.c:838
msgid "LOCATION and DIRECTORY must be specified"
msgstr "KONUM ve DİZİN belirtilmelidir"

#: app/flatpak-builtins-build-export.c:859
#: app/flatpak-builtins-remote-add.c:327
#, c-format
msgid "‘%s’ is not a valid collection ID: %s"
msgstr "‘%s’ geçerli koleksiyon kimliği değil: %s"

#: app/flatpak-builtins-build-export.c:904
#: app/flatpak-builtins-build-finish.c:684
msgid "No name specified in the metadata"
msgstr "Üst veride ad belirtilmemiş"

#: app/flatpak-builtins-build-export.c:1166
#, c-format
msgid "Commit: %s\n"
msgstr "İşleme: %s\n"

#: app/flatpak-builtins-build-export.c:1167
#, c-format
msgid "Metadata Total: %u\n"
msgstr "Toplam Üst Veri: %u\n"

#: app/flatpak-builtins-build-export.c:1168
#, c-format
msgid "Metadata Written: %u\n"
msgstr "Yazılan Üst Veri: %u\n"

#: app/flatpak-builtins-build-export.c:1169
#, c-format
msgid "Content Total: %u\n"
msgstr "Toplam İçerik: %u\n"

#: app/flatpak-builtins-build-export.c:1170
#, c-format
msgid "Content Written: %u\n"
msgstr "Yazılan İçerik: %u\n"

#: app/flatpak-builtins-build-export.c:1171
#, c-format
msgid "Content Bytes Written:"
msgstr "Yazılan İçerik Baytları:"

#: app/flatpak-builtins-build-finish.c:52
msgid "Command to set"
msgstr "Ayarlanacak komut"

#: app/flatpak-builtins-build-finish.c:52 app/flatpak-builtins-run.c:159
#: app/flatpak-main.c:209
msgid "COMMAND"
msgstr "KOMUT"

#: app/flatpak-builtins-build-finish.c:53
msgid "Flatpak version to require"
msgstr "Gerektirilecek Flatpak sürümü"

#: app/flatpak-builtins-build-finish.c:53
msgid "MAJOR.MINOR.MICRO"
msgstr "BÜYÜK.KÜÇÜK.MİNİK"

#: app/flatpak-builtins-build-finish.c:54
msgid "Don't process exports"
msgstr "Dışa aktarmaları işleme"

#: app/flatpak-builtins-build-finish.c:55
msgid "Extra data info"
msgstr "Ek veri bilgisi"

#: app/flatpak-builtins-build-finish.c:56 app/flatpak-builtins-build-init.c:63
msgid "Add extension point info"
msgstr "Uzantı noktası bilgisi ekle"

#: app/flatpak-builtins-build-finish.c:56 app/flatpak-builtins-build-init.c:63
msgid "NAME=VARIABLE[=VALUE]"
msgstr "AD=DEĞİŞKEN[=DEĞER]"

#: app/flatpak-builtins-build-finish.c:57
msgid "Remove extension point info"
msgstr "Uzantı noktası bilgisi kaldır"

#: app/flatpak-builtins-build-finish.c:57
#: app/flatpak-builtins-build-update-repo.c:79 app/flatpak-builtins-info.c:58
#: app/flatpak-builtins-remote-add.c:88 app/flatpak-builtins-remote-modify.c:94
#: app/flatpak-main.c:182
msgid "NAME"
msgstr "AD"

#: app/flatpak-builtins-build-finish.c:58
msgid "Set extension priority (only for extensions)"
msgstr "Uzantı önceliğini belirle (yalnızca uzantılar için)"

#: app/flatpak-builtins-build-finish.c:58
msgid "VALUE"
msgstr "DEĞER"

#: app/flatpak-builtins-build-finish.c:59
msgid "Change the sdk used for the app"
msgstr "Uygulama için kullanılan SDKʼyi değiştir"

#: app/flatpak-builtins-build-finish.c:59
msgid "SDK"
msgstr "SDK"

#: app/flatpak-builtins-build-finish.c:60
msgid "Change the runtime used for the app"
msgstr "Uygulama için kullanılan çalışma zamanını değiştir"

#: app/flatpak-builtins-build-finish.c:60 app/flatpak-builtins-build-init.c:54
#: app/flatpak-builtins-list.c:53 app/flatpak-builtins-remote-ls.c:58
#: app/flatpak-builtins-run.c:163
msgid "RUNTIME"
msgstr "ÇALIŞMAZAMANI"

#: app/flatpak-builtins-build-finish.c:61
msgid "Set generic metadata option"
msgstr "Genel üst veri seçeneğini belirle"

#: app/flatpak-builtins-build-finish.c:61
msgid "GROUP=KEY[=VALUE]"
msgstr "GRUP=ANAHTAR[=DEĞER]"

#: app/flatpak-builtins-build-finish.c:62
msgid "Don't inherit permissions from runtime"
msgstr "Çalışma zamanından izinleri devralma"

#: app/flatpak-builtins-build-finish.c:155
#, c-format
msgid "Not exporting %s, wrong extension\n"
msgstr "%s dışa aktarılamıyor, yanlış uzantı\n"

#: app/flatpak-builtins-build-finish.c:163
#, c-format
msgid "Not exporting %s, non-allowed export filename\n"
msgstr "%s dışa aktarılamıyor, izin verilmeyen dışa aktarma dosya adı\n"

#: app/flatpak-builtins-build-finish.c:167
#, c-format
msgid "Exporting %s\n"
msgstr "%s dışa aktarılıyor\n"

#: app/flatpak-builtins-build-finish.c:440
#, c-format
msgid "More than one executable found\n"
msgstr "Birden çok yürütülebilir dosya bulundu\n"

#: app/flatpak-builtins-build-finish.c:451
#, c-format
msgid "Using %s as command\n"
msgstr "%s komut olarak kullanılıyor\n"

#: app/flatpak-builtins-build-finish.c:456
#, c-format
msgid "No executable found\n"
msgstr "Yürütülebilir bulunamadı\n"

#: app/flatpak-builtins-build-finish.c:511
#, c-format
msgid "Invalid --require-version argument: %s"
msgstr "Geçersiz --require-version argümanı: %s"

#: app/flatpak-builtins-build-finish.c:543
#, c-format
msgid "Too few elements in --extra-data argument %s"
msgstr "--extra-data argümanı %s’te çok az öge"

#: app/flatpak-builtins-build-finish.c:575
#, c-format
msgid ""
"Too few elements in --metadata argument %s, format should be "
"GROUP=KEY[=VALUE]]"
msgstr ""
"--metadata argümanı %s’te çok az öge, biçim GRUP=ANAHTAR[=DEĞER] olmalıdır"

#: app/flatpak-builtins-build-finish.c:597
#: app/flatpak-builtins-build-init.c:458
#, c-format
msgid ""
"Too few elements in --extension argument %s, format should be "
"NAME=VAR[=VALUE]"
msgstr ""
"--extension argümanı %s’te çok az öge, biçim AD=DEĞİŞKEN[=DEĞER] olmalıdır"

#: app/flatpak-builtins-build-finish.c:603
#: app/flatpak-builtins-build-init.c:461
#, c-format
msgid "Invalid extension name %s"
msgstr "Geçersiz uzantı adı %s"

#: app/flatpak-builtins-build-finish.c:646
msgid "DIRECTORY - Finalize a build directory"
msgstr "DİZİN - İnşa dizinini sonlandır"

#: app/flatpak-builtins-build-finish.c:668
#, c-format
msgid "Build directory %s not initialized"
msgstr "İnşa dizini %s ilklendirilmemiş"

#: app/flatpak-builtins-build-finish.c:689
#, c-format
msgid "Build directory %s already finalized"
msgstr "İnşa dizini %s zaten sonlandırılmış"

#: app/flatpak-builtins-build-finish.c:702
#, c-format
msgid "Please review the exported files and the metadata\n"
msgstr "Lütfen dışa aktarılmış dosyaları ve üst veriyi gözden geçirin\n"

#: app/flatpak-builtins-build-import-bundle.c:47
msgid "Override the ref used for the imported bundle"
msgstr "İçe aktarılan paket için kullanılan referansı geçersiz kıl"

#: app/flatpak-builtins-build-import-bundle.c:47
msgid "REF"
msgstr "REFERANS"

#: app/flatpak-builtins-build-import-bundle.c:48
msgid "Import oci image instead of flatpak bundle"
msgstr "Flatpak paketi yerine oci görüntüsü içe aktar"

#: app/flatpak-builtins-build-import-bundle.c:77
#: app/flatpak-builtins-build-import-bundle.c:105
#, c-format
msgid "Importing %s (%s)\n"
msgstr "%s içe aktarılıyor (%s)\n"

#: app/flatpak-builtins-build-import-bundle.c:126
msgid "LOCATION FILENAME - Import a file bundle into a local repository"
msgstr "KONUM DOSYAADI - Dosya paketini yerel depoya içe aktar"

#: app/flatpak-builtins-build-import-bundle.c:133
msgid "LOCATION and FILENAME must be specified"
msgstr "KONUM ve DOSYAADI belirtilmelidir"

#: app/flatpak-builtins-build-init.c:53 app/flatpak-builtins-info.c:55
#: app/flatpak-builtins-run.c:158
msgid "Arch to use"
msgstr "Kullanılacak mimari"

# var burada dizin adı.
#: app/flatpak-builtins-build-init.c:54
msgid "Initialize var from named runtime"
msgstr "var’ı adlandırılmış çalışma zamanından ilklendir"

#: app/flatpak-builtins-build-init.c:55
msgid "Initialize apps from named app"
msgstr "Uygulamaları adlandırılmış uygulamadan ilklendir"

#: app/flatpak-builtins-build-init.c:55
msgid "APP"
msgstr "UYGULAMA"

#: app/flatpak-builtins-build-init.c:56
msgid "Specify version for --base"
msgstr "--base için sürüm belirt"

#: app/flatpak-builtins-build-init.c:56 app/flatpak-builtins-run.c:164
msgid "VERSION"
msgstr "SÜRÜM"

#: app/flatpak-builtins-build-init.c:57
msgid "Include this base extension"
msgstr "Bu temel uzantısını içer"

#: app/flatpak-builtins-build-init.c:57 app/flatpak-builtins-build-init.c:62
msgid "EXTENSION"
msgstr "UZANTI"

#: app/flatpak-builtins-build-init.c:58
msgid "Extension tag to use if building extension"
msgstr "Uzantı inşa ediyorsanız kullanılacak uzantı etiketi"

#: app/flatpak-builtins-build-init.c:58
msgid "EXTENSION_TAG"
msgstr "UZANTI_ETİKETİ"

#: app/flatpak-builtins-build-init.c:59
msgid "Initialize /usr with a writable copy of the sdk"
msgstr "/usr’yi SDKʼnin yazılabilir bir kopyasıyla ilklendir"

#: app/flatpak-builtins-build-init.c:60
msgid "Specify the build type (app, runtime, extension)"
msgstr "İnşa türünü belirt (uygulama, çalışma zamanı, uzantı)"

#: app/flatpak-builtins-build-init.c:60
msgid "TYPE"
msgstr "TÜR"

#: app/flatpak-builtins-build-init.c:61
msgid "Add a tag"
msgstr "Etiket ekle"

#: app/flatpak-builtins-build-init.c:61
msgid "TAG"
msgstr "ETİKET"

#: app/flatpak-builtins-build-init.c:62
msgid "Include this sdk extension in /usr"
msgstr "Bu SDK uzantısını /usr’de içer"

#: app/flatpak-builtins-build-init.c:64
msgid "Where to store sdk (defaults to 'usr')"
msgstr "SDKʼnin saklanacağı yer ('usr' öntanımlıdır)"

#: app/flatpak-builtins-build-init.c:65
msgid "Re-initialize the sdk/var"
msgstr "Sdk/varʼı yeniden ilklendir"

#: app/flatpak-builtins-build-init.c:118
#, c-format
msgid "Requested extension %s/%s/%s is only partially installed"
msgstr "İstenen uzantı %s/%s/%s yalnızca kısmi kurulmuş"

#: app/flatpak-builtins-build-init.c:147
#, c-format
msgid "Requested extension %s/%s/%s not installed"
msgstr "İstenen uzantı %s/%s/%s kurulu değil"

#: app/flatpak-builtins-build-init.c:207
msgid ""
"DIRECTORY APPNAME SDK RUNTIME [BRANCH] - Initialize a directory for building"
msgstr ""
"DİZİN UYGULAMAADI SDK ÇALIŞMAORTAMI [DAL] - Bir dizini inşa için ilklendir"

#: app/flatpak-builtins-build-init.c:214
msgid "RUNTIME must be specified"
msgstr "ÇALIŞMAORTAMI belirtilmelidir"

#: app/flatpak-builtins-build-init.c:235
#, c-format
msgid "'%s' is not a valid build type name, use app, runtime or extension"
msgstr ""
"'%s' geçerli bir inşa türü adı değil, uygulama, çalışma zamanı ya da "
"uzantıyı kullan"

#: app/flatpak-builtins-build-init.c:241 app/flatpak-builtins-override.c:79
#, c-format
msgid "'%s' is not a valid application name: %s"
msgstr "'%s' geçerli bir uygulama adı değil: %s"

#: app/flatpak-builtins-build-init.c:295
#, c-format
msgid "Build directory %s already initialized"
msgstr "İnşa dizini %s zaten ilklendirilmiş"

#: app/flatpak-builtins-build-sign.c:42 app/flatpak-builtins-install.c:67
#: app/flatpak-builtins-remote-info.c:54
msgid "Arch to install for"
msgstr "Kurulacağı mimari"

#: app/flatpak-builtins-build-sign.c:43 app/flatpak-builtins-create-usb.c:48
#: app/flatpak-builtins-install.c:74 app/flatpak-builtins-remote-info.c:56
#: app/flatpak-builtins-uninstall.c:58 app/flatpak-builtins-update.c:64
msgid "Look for runtime with the specified name"
msgstr "Belirtilmiş adla çalışma zamanı ara"

#: app/flatpak-builtins-build-sign.c:66
msgid "LOCATION [ID [BRANCH]] - Sign an application or runtime"
msgstr "KONUM [KİMLİK [DAL]] - Uygulamayı ya da çalışma zamanını imzala"

#: app/flatpak-builtins-build-sign.c:73
#: app/flatpak-builtins-build-update-repo.c:499
#: app/flatpak-builtins-remote-add.c:320 app/flatpak-builtins-repo.c:739
msgid "LOCATION must be specified"
msgstr "KONUM belirtilmelidir"

#: app/flatpak-builtins-build-sign.c:94
msgid "No gpg key ids specified"
msgstr "Gpg anahtar kimliği belirtilmemiş"

#: app/flatpak-builtins-build-update-repo.c:68
msgid "Redirect this repo to a new URL"
msgstr "Bu depoyu yeni URL’ye yönlendir"

#: app/flatpak-builtins-build-update-repo.c:69
msgid "A nice name to use for this repository"
msgstr "Bu depo için kullanılacak güzel bir ad"

#: app/flatpak-builtins-build-update-repo.c:69
#: app/flatpak-builtins-remote-add.c:77 app/flatpak-builtins-remote-modify.c:82
msgid "TITLE"
msgstr "BAŞLIK"

#: app/flatpak-builtins-build-update-repo.c:70
msgid "A one-line comment for this repository"
msgstr "Bu depo için tek satırlık yorum"

#: app/flatpak-builtins-build-update-repo.c:70
#: app/flatpak-builtins-remote-add.c:78 app/flatpak-builtins-remote-modify.c:83
msgid "COMMENT"
msgstr "YORUM"

#: app/flatpak-builtins-build-update-repo.c:71
msgid "A full-paragraph description for this repository"
msgstr "Bu depo için tek paragraflık açıklama"

#: app/flatpak-builtins-build-update-repo.c:71
#: app/flatpak-builtins-remote-add.c:79 app/flatpak-builtins-remote-modify.c:84
msgid "DESCRIPTION"
msgstr "AÇIKLAMA"

#: app/flatpak-builtins-build-update-repo.c:72
msgid "URL for a website for this repository"
msgstr "Bu depo için web sitesi URL’si"

#: app/flatpak-builtins-build-update-repo.c:73
msgid "URL for an icon for this repository"
msgstr "Bu depo için simge URL’si"

#: app/flatpak-builtins-build-update-repo.c:74
msgid "Default branch to use for this repository"
msgstr "Bu depo için kullanılacak öntanımlı dal"

#: app/flatpak-builtins-build-update-repo.c:74
#: app/flatpak-builtins-remote-add.c:82 app/flatpak-builtins-remote-modify.c:87
#: app/flatpak-builtins-repo.c:713 app/flatpak-builtins-repo.c:714
#: app/flatpak-builtins-run.c:161
msgid "BRANCH"
msgstr "DAL"

#: app/flatpak-builtins-build-update-repo.c:75
#: app/flatpak-builtins-remote-add.c:83 app/flatpak-builtins-remote-modify.c:88
msgid "COLLECTION-ID"
msgstr "KOLEKSİYON-KİMLİĞİ"

#. Translators: A sideload is when you install from a local USB drive rather than the Internet.
#: app/flatpak-builtins-build-update-repo.c:77
msgid ""
"Permanently deploy collection ID to client remote configurations, only for "
"sideload support"
msgstr ""
"Koleksiyon kimliğini yalnızca yan kurulum desteği için istemci uzak "
"yapılandırmalarına kalıcı olarak dağıt"

#: app/flatpak-builtins-build-update-repo.c:78
msgid "Permanently deploy collection ID to client remote configurations"
msgstr ""
"Koleksiyon kimliğini istemci uzak yapılandırmalarına kalıcı olarak dağıt"

#: app/flatpak-builtins-build-update-repo.c:79
msgid "Name of authenticator for this repository"
msgstr "Bu depo için kimlik doğrulayıcının adı"

#: app/flatpak-builtins-build-update-repo.c:80
msgid "Autoinstall authenticator for this repository"
msgstr "Bu depo için kimlik doğrulayıcıyı kendiliğinden kur"

#: app/flatpak-builtins-build-update-repo.c:81
msgid "Don't autoinstall authenticator for this repository"
msgstr "Bu depo için kimlik doğrulayıcıyı kendiliğinden kurma"

#: app/flatpak-builtins-build-update-repo.c:82
#: app/flatpak-builtins-remote-add.c:89
msgid "Authenticator option"
msgstr "Kimlik doğrulayıcı seçeneği"

#: app/flatpak-builtins-build-update-repo.c:82
#: app/flatpak-builtins-remote-add.c:89 app/flatpak-builtins-remote-modify.c:95
msgid "KEY=VALUE"
msgstr "ANAHTAR=DEĞER"

#: app/flatpak-builtins-build-update-repo.c:83
msgid "Import new default GPG public key from FILE"
msgstr "Yeni öntanımlı GPG genel anahtarını DOSYA’dan içe aktar"

#: app/flatpak-builtins-build-update-repo.c:84
msgid "GPG Key ID to sign the summary with"
msgstr "Özetin imzalanacağı GPG anahtar kimliği"

#: app/flatpak-builtins-build-update-repo.c:86
msgid "Generate delta files"
msgstr "Delta dosyaları oluştur"

#: app/flatpak-builtins-build-update-repo.c:88
msgid "Don't update the appstream branch"
msgstr "Appstream dalını güncelleme"

#: app/flatpak-builtins-build-update-repo.c:89
msgid "Max parallel jobs when creating deltas (default: NUMCPUs)"
msgstr "Delta oluştururken en çok paralel iş (öntanımlı: NUMCPU’lar)"

#: app/flatpak-builtins-build-update-repo.c:89
msgid "NUM-JOBS"
msgstr "İŞ-SAYISI"

#: app/flatpak-builtins-build-update-repo.c:90
msgid "Don't create deltas matching refs"
msgstr "Referanslarla eşleşen deltalar oluşturma"

#: app/flatpak-builtins-build-update-repo.c:91
msgid "Prune unused objects"
msgstr "Kullanılmayan nesneleri buda"

#: app/flatpak-builtins-build-update-repo.c:92
msgid "Prune but don't actually remove anything"
msgstr "Buda ancak hiçbir şeyi gerçekte kaldırma"

#: app/flatpak-builtins-build-update-repo.c:93
msgid "Only traverse DEPTH parents for each commit (default: -1=infinite)"
msgstr ""
"Her işleme için yalnızca DERİNLİK ebeveynlerini çaprazla (öntanımlı: "
"-1=sonsuz)"

#: app/flatpak-builtins-build-update-repo.c:93
msgid "DEPTH"
msgstr "DERİNLİK"

#: app/flatpak-builtins-build-update-repo.c:223
#, c-format
msgid "Generating delta: %s (%.10s)\n"
msgstr "Delta oluşturuluyor: %s (%.10s)\n"

#: app/flatpak-builtins-build-update-repo.c:225
#, c-format
msgid "Generating delta: %s (%.10s-%.10s)\n"
msgstr "Delta oluşturuluyor: %s (%.10s-%.10s)\n"

#: app/flatpak-builtins-build-update-repo.c:233
#, c-format
msgid "Failed to generate delta %s (%.10s): "
msgstr "%s delta oluşturulamadı (%.10s): "

#: app/flatpak-builtins-build-update-repo.c:236
#, c-format
msgid "Failed to generate delta %s (%.10s-%.10s): "
msgstr "%s delta oluşturulamadı (%.10s-%.10s): "

#: app/flatpak-builtins-build-update-repo.c:492
msgid "LOCATION - Update repository metadata"
msgstr "KONUM - Depo üst verisini güncelle"

#: app/flatpak-builtins-build-update-repo.c:609
#, c-format
msgid "Updating appstream branch\n"
msgstr "Appstream dalı güncelleniyor\n"

#: app/flatpak-builtins-build-update-repo.c:638
#, c-format
msgid "Updating summary\n"
msgstr "Özet güncelleniyor\n"

#: app/flatpak-builtins-build-update-repo.c:664
#, c-format
msgid "Total objects: %u\n"
msgstr "Toplam nesne: %u\n"

#: app/flatpak-builtins-build-update-repo.c:666
#, c-format
msgid "No unreachable objects\n"
msgstr "Ulaşılamayan nesne yok\n"

#: app/flatpak-builtins-build-update-repo.c:668
#, c-format
msgid "Deleted %u objects, %s freed\n"
msgstr "%u nesne silindi, %s temizlendi\n"

#: app/flatpak-builtins-config.c:41
msgid "List configuration keys and values"
msgstr "Yapılandırma anahtarlarını ve değerlerini listele"

#: app/flatpak-builtins-config.c:42
msgid "Get configuration for KEY"
msgstr "ANAHTAR için yapılandırmayı getir"

#: app/flatpak-builtins-config.c:43
msgid "Set configuration for KEY to VALUE"
msgstr "ANAHTAR için yapılandırmayı DEĞER olarak belirle"

#: app/flatpak-builtins-config.c:44
msgid "Unset configuration for KEY"
msgstr "ANAHTAR için yapılandırmayı kaldır"

#: app/flatpak-builtins-config.c:149
#, c-format
msgid "'%s' does not look like a language/locale code"
msgstr "'%s' dil/yerel kodu gibi görünmüyor"

#: app/flatpak-builtins-config.c:172
#, c-format
msgid "'%s' does not look like a language code"
msgstr "'%s' dil kodu gibi görünmüyor"

#: app/flatpak-builtins-config.c:190
#, c-format
msgid "'%s' is not a valid value (use 'true' or 'false')"
msgstr "'%s' geçerli bir değer değil ('true' ya da 'false' kullanın)"

#: app/flatpak-builtins-config.c:262
#, c-format
msgid "Unknown configure key '%s'"
msgstr "Bilinmeyen yapılandırma anahtarı '%s'"

#: app/flatpak-builtins-config.c:284
msgid "Too many arguments for --list"
msgstr "--list için çok fazla argüman"

#: app/flatpak-builtins-config.c:314 app/flatpak-builtins-config.c:362
msgid "You must specify KEY"
msgstr "ANAHTAR belirtilmelidir"

#: app/flatpak-builtins-config.c:316
msgid "Too many arguments for --get"
msgstr "--get için çok fazla argüman"

#: app/flatpak-builtins-config.c:338
msgid "You must specify KEY and VALUE"
msgstr "ANAHTAR ve DEĞER belirtilmelidir"

#: app/flatpak-builtins-config.c:340
msgid "Too many arguments for --set"
msgstr "--set için çok fazla argüman"

#: app/flatpak-builtins-config.c:364
msgid "Too many arguments for --unset"
msgstr "--unset için çok fazla argüman"

#: app/flatpak-builtins-config.c:383
msgid "[KEY [VALUE]] - Manage configuration"
msgstr "[ANAHTAR [DEĞER]] - Yapılandırmayı yönet"

#: app/flatpak-builtins-config.c:394
msgid "Can only use one of --list, --get, --set or --unset"
msgstr ""
"--list, --get, --set ya da --unset içinden yalnızca biri kullanılabilir"

#: app/flatpak-builtins-config.c:408
msgid "Must specify one of --list, --get, --set or --unset"
msgstr "--list, --get, --set ya da --unset içinden birisi belirtilmelidir"

#: app/flatpak-builtins-create-usb.c:45 app/flatpak-builtins-install.c:75
#: app/flatpak-builtins-remote-info.c:57 app/flatpak-builtins-uninstall.c:59
#: app/flatpak-builtins-update.c:65
msgid "Look for app with the specified name"
msgstr "Belirtilmiş adla uygulama ara"

#: app/flatpak-builtins-create-usb.c:46
msgid "Arch to copy"
msgstr "Kopyalanacak mimari"

#: app/flatpak-builtins-create-usb.c:47
msgid "DEST"
msgstr "HEDEF"

#: app/flatpak-builtins-create-usb.c:49
msgid "Allow partial commits in the created repo"
msgstr "Oluşturulan depoda kısmi işlemelere izin ver"

#: app/flatpak-builtins-create-usb.c:125 app/flatpak-builtins-create-usb.c:165
#, c-format
msgid ""
"Warning: Related ref ‘%s’ is partially installed. Use --allow-partial to "
"suppress this message.\n"
msgstr ""
"Uyarı: İlgili referans ‘%s’ kısmen kuruldu. Bu iletiyi bastırmak için --"
"allow-partial kullanın.\n"

#: app/flatpak-builtins-create-usb.c:158
#, c-format
msgid "Warning: Omitting related ref ‘%s’ because it is not installed.\n"
msgstr "Uyarı: Kurulu olmadığı için ilgili ‘%s’ referansı atlanıyor.\n"

#: app/flatpak-builtins-create-usb.c:175
#, c-format
msgid ""
"Warning: Omitting related ref ‘%s’ because its remote ‘%s’ does not have a "
"collection ID set.\n"
msgstr ""
"Uyarı: Uzak ‘%2$s’ ayarlanmış koleksiyon kimliği içermediği için İlgili "
"‘%1$s’ referansı atlanıyor.\n"

#: app/flatpak-builtins-create-usb.c:187
#, c-format
msgid "Warning: Omitting related ref ‘%s’ because it's extra-data.\n"
msgstr ""
"Uyarı: Ek veri olduğu için ilgili ‘%s’ referansı atlanıyor.\n"
"\n"

#: app/flatpak-builtins-create-usb.c:262 app/flatpak-builtins-create-usb.c:637
#, c-format
msgid ""
"Remote ‘%s’ does not have a collection ID set, which is required for P2P "
"distribution of ‘%s’."
msgstr ""
"Uzak ‘%s’, ‘%s’ P2P dağıtımı için gerekli koleksiyon kimliğine sahip değil."

#: app/flatpak-builtins-create-usb.c:272
#, c-format
msgid "Warning: Omitting ref ‘%s’ (runtime of ‘%s’) because it's extra-data.\n"
msgstr ""
"Uyarı: Ek veri olduğu için ‘%s’ referansı (‘%s’ çalışma zamanı) atlanıyor.\n"

#: app/flatpak-builtins-create-usb.c:484
msgid "MOUNT-PATH [REF…] - Copy apps or runtimes onto removable media"
msgstr ""
"BAĞLANMA-YOLU [REFERANS…] - Uygulamaları ya da çalışma ortamlarını "
"taşınabilir ortama kopyala"

#: app/flatpak-builtins-create-usb.c:493
msgid "MOUNT-PATH and REF must be specified"
msgstr "BAĞLANMA-YOLU ve REFERANS belirtilmelidir"

#: app/flatpak-builtins-create-usb.c:607
#, c-format
msgid "Ref ‘%s’ found in multiple installations: %s. You must specify one."
msgstr ""
"‘%s’ referansı birden çok kurulumda bulundu: %s. Bir tane belirtmelisiniz."

#: app/flatpak-builtins-create-usb.c:620
#, c-format
msgid "Refs must all be in the same installation (found in %s and %s)."
msgstr "Referansların tümü aynı kurulumda olmalıdır (%s ve %s içinde bulundu)."

#: app/flatpak-builtins-create-usb.c:670
#, c-format
msgid ""
"Warning: Ref ‘%s’ is partially installed. Use --allow-partial to suppress "
"this message.\n"
msgstr ""
"Uyarı: Referans ‘%s’ kısmen kuruldu. Bu iletiyi bastırmak için --allow-"
"partial kullanın.\n"

#: app/flatpak-builtins-create-usb.c:681
#, c-format
msgid "Installed ref ‘%s’ is extra-data, and cannot be distributed offline"
msgstr "Kurulu referans ‘%s’ ek veri, ve çevrim dışı olarak dağıtılamaz"

#: app/flatpak-builtins-create-usb.c:721
#, c-format
msgid "Warning: Couldn't update repo metadata for remote ‘%s’: %s\n"
msgstr "Uyarı: Depo üst verisi ‘%s’ uzağı için güncellenemedi: %s\n"

#: app/flatpak-builtins-create-usb.c:751
#, c-format
msgid "Warning: Couldn't update appstream data for remote ‘%s’ arch ‘%s’: %s\n"
msgstr ""
"Uyarı: Uzak ‘%s’ mimari ‘%s’ için appstream verisi güncellenemedi: %s\n"

#. Print a warning if both appstream and appstream2 are missing
#: app/flatpak-builtins-create-usb.c:784
#, c-format
msgid ""
"Warning: Couldn't find appstream data for remote ‘%s’ arch ‘%s’: %s; %s\n"
msgstr ""
"Uyarı: Uzak ‘%s’ mimari ‘%s’ için appstream verisi bulunamadı: %s; %s\n"

#. Appstream2 is only for efficiency, so just print a debug message
#: app/flatpak-builtins-create-usb.c:790
#, c-format
msgid "Couldn't find appstream2 data for remote ‘%s’ arch ‘%s’: %s\n"
msgstr "Uzak ‘%s’ mimari ‘%s’ için appstream2 verisi bulunamadı: %s\n"

#: app/flatpak-builtins-document-export.c:62
msgid "Create a unique document reference"
msgstr "Bir eşsiz belge referansı oluştur"

#: app/flatpak-builtins-document-export.c:63
msgid "Make the document transient for the current session"
msgstr "Belgeyi geçerli oturum için geçici yap"

#: app/flatpak-builtins-document-export.c:64
msgid "Don't require the file to exist already"
msgstr "Belgenin zaten var olmasını gerektirme"

#: app/flatpak-builtins-document-export.c:65
msgid "Give the app read permissions"
msgstr "Uygulamaya okuma izinleri ver"

#: app/flatpak-builtins-document-export.c:66
msgid "Give the app write permissions"
msgstr "Uygulamaya yazma izinleri ver"

#: app/flatpak-builtins-document-export.c:67
msgid "Give the app delete permissions"
msgstr "Uygulamaya silme izinleri ver"

#: app/flatpak-builtins-document-export.c:68
msgid "Give the app permissions to grant further permissions"
msgstr "Uygulamaya daha çok izin tanıma izinleri ver"

#: app/flatpak-builtins-document-export.c:69
msgid "Revoke read permissions of the app"
msgstr "Uygulamanın okuma izinlerini geri çek"

#: app/flatpak-builtins-document-export.c:70
msgid "Revoke write permissions of the app"
msgstr "Uygulamanın yazma izinlerini geri çek"

#: app/flatpak-builtins-document-export.c:71
msgid "Revoke delete permissions of the app"
msgstr "Uygulamanın silme izinlerini geri çek"

#: app/flatpak-builtins-document-export.c:72
msgid "Revoke the permission to grant further permissions"
msgstr "Uygulamanın daha çok izin tanıma izinlerini geri çek"

#: app/flatpak-builtins-document-export.c:73
msgid "Add permissions for this app"
msgstr "Bu uygulama için izinler ekle"

#: app/flatpak-builtins-document-export.c:73
msgid "APPID"
msgstr "UYGULAMAKİMLİĞİ"

#: app/flatpak-builtins-document-export.c:100
msgid "FILE - Export a file to apps"
msgstr "DOSYA - Bir dosyayı uygulamalara dışa aktar"

#: app/flatpak-builtins-document-export.c:109
#: app/flatpak-builtins-document-info.c:72
#: app/flatpak-builtins-document-unexport.c:67
msgid "FILE must be specified"
msgstr "DOSYA belirtilmelidir"

#: app/flatpak-builtins-document-info.c:63
msgid "FILE - Get information about an exported file"
msgstr "DOSYA - Dışa aktarılmış belgeyle ilgili bilgi al"

#: app/flatpak-builtins-document-info.c:100
#: app/flatpak-builtins-document-unexport.c:94
#, c-format
msgid "Not exported\n"
msgstr "Dışa aktarılmamış\n"

#: app/flatpak-builtins-document-list.c:43 app/flatpak-builtins-history.c:53
#: app/flatpak-builtins-list.c:54 app/flatpak-builtins-ps.c:43
#: app/flatpak-builtins-remote-list.c:45 app/flatpak-builtins-remote-ls.c:59
#: app/flatpak-builtins-search.c:38
msgid "What information to show"
msgstr "Hangi bilgiler gösterilecek"

#: app/flatpak-builtins-document-list.c:43 app/flatpak-builtins-history.c:53
#: app/flatpak-builtins-list.c:54 app/flatpak-builtins-ps.c:43
#: app/flatpak-builtins-remote-list.c:45 app/flatpak-builtins-remote-ls.c:59
#: app/flatpak-builtins-search.c:38
msgid "FIELD,…"
msgstr "ALAN,…"

#: app/flatpak-builtins-document-list.c:44 app/flatpak-builtins-history.c:54
#: app/flatpak-builtins-list.c:52 app/flatpak-builtins-permission-list.c:43
#: app/flatpak-builtins-permission-show.c:43 app/flatpak-builtins-ps.c:44
#: app/flatpak-builtins-remote-list.c:46 app/flatpak-builtins-remote-ls.c:63
#: app/flatpak-builtins-repo.c:717 app/flatpak-builtins-search.c:39
msgid "Show output in JSON format"
msgstr "Çıktıyı JSON biçiminde göster"

#: app/flatpak-builtins-document-list.c:49
msgid "Show the document ID"
msgstr "Belge kimliğini göster"

#: app/flatpak-builtins-document-list.c:50
msgid "Path"
msgstr "Yol"

#: app/flatpak-builtins-document-list.c:50
#: app/flatpak-builtins-document-list.c:51
msgid "Show the document path"
msgstr "Belge yolunu göster"

#: app/flatpak-builtins-document-list.c:51 app/flatpak-builtins-list.c:66
#: app/flatpak-builtins-remote-ls.c:74
msgid "Origin"
msgstr "Köken"

#: app/flatpak-builtins-document-list.c:52 app/flatpak-builtins-history.c:62
#: app/flatpak-builtins-ps.c:52
msgid "Application"
msgstr "Uygulama"

#: app/flatpak-builtins-document-list.c:52
msgid "Show applications with permission"
msgstr "Uygulamaları izinleriyle birlikte göster"

#: app/flatpak-builtins-document-list.c:53
#: app/flatpak-builtins-permission-list.c:182
#: app/flatpak-builtins-permission-show.c:145
msgid "Permissions"
msgstr "İzinler"

#: app/flatpak-builtins-document-list.c:53
msgid "Show permissions for applications"
msgstr "Uygulamalar için izinleri göster"

#: app/flatpak-builtins-document-list.c:161
#, c-format
msgid "No documents found\n"
msgstr "Belge bulunamadı\n"

#: app/flatpak-builtins-document-list.c:180
msgid "[APPID] - List exported files"
msgstr "[UYGULAMAKİMLİĞİ] - Dışa aktarılmış dosyaları listele"

#: app/flatpak-builtins-document-unexport.c:43
msgid "Specify the document ID"
msgstr "Belge kimliğini belirt"

#: app/flatpak-builtins-document-unexport.c:58
msgid "FILE - Unexport a file to apps"
msgstr "DOSYA - Bir dosyayı uygulamalara dışa aktarma"

#: app/flatpak-builtins-enter.c:88
msgid "INSTANCE COMMAND [ARGUMENT…] - Run a command inside a running sandbox"
msgstr "ÖRNEK KOMUT [ARGÜMAN…] - Çalışan yalıtılmış alanda komut çalıştır"

#: app/flatpak-builtins-enter.c:111
msgid "INSTANCE and COMMAND must be specified"
msgstr "ÖRNEK ve KOMUT belirtilmelidir"

#: app/flatpak-builtins-enter.c:138
#, c-format
msgid "%s is neither a pid nor an application or instance ID"
msgstr "%s pid, uygulama adı ya da örnek kimliği değil"

#: app/flatpak-builtins-enter.c:144
msgid "entering not supported (need unprivileged user namespaces, or sudo -E)"
msgstr ""
"giriş desteklenmiyor (ayrıcalıksız kullanıcı ad alanları ya da sudo -E "
"gerekiyor)"

#: app/flatpak-builtins-enter.c:145
#, c-format
msgid "No such pid %s"
msgstr "%s diye bir pid yok"

#: app/flatpak-builtins-enter.c:158
msgid "Can't read cwd"
msgstr "cwd okunamadı"

#: app/flatpak-builtins-enter.c:163
msgid "Can't read root"
msgstr "root okunamadı"

#: app/flatpak-builtins-enter.c:191
#, c-format
msgid "Invalid %s namespace for pid %d"
msgstr "Pid %2$d için geçersiz %1$s ad alanı"

#: app/flatpak-builtins-enter.c:202
#, c-format
msgid "Invalid %s namespace for self"
msgstr "Kendi için geçersiz %s ad alanı"

#: app/flatpak-builtins-enter.c:216
#, c-format
msgid "Can't open %s namespace: %s"
msgstr "%s ad alanı açılamadı: %s"

#: app/flatpak-builtins-enter.c:226
msgid "entering not supported (need unprivileged user namespaces)"
msgstr "giriş desteklenmiyor (ayrıcalıksız kullanıcı ad alanları gerekiyor)"

#: app/flatpak-builtins-enter.c:227
#, c-format
msgid "Can't enter %s namespace: %s"
msgstr "%s ad alanına girilemedi: %s"

#: app/flatpak-builtins-enter.c:234
msgid "Can't chdir"
msgstr "chdir yapılamadı"

#: app/flatpak-builtins-enter.c:237
msgid "Can't chroot"
msgstr "chroot yapılamadı"

#: app/flatpak-builtins-enter.c:240
msgid "Can't switch gid"
msgstr "gid değiştirilemedi"

#: app/flatpak-builtins-enter.c:243
msgid "Can't switch uid"
msgstr "uid değiştirilemedi"

#: app/flatpak-builtins-history.c:50
msgid "Only show changes after TIME"
msgstr "Yalnızca ZAMAN tarihinden sonraki değişiklikleri göster"

#: app/flatpak-builtins-history.c:50 app/flatpak-builtins-history.c:51
msgid "TIME"
msgstr "ZAMAN"

#: app/flatpak-builtins-history.c:51
msgid "Only show changes before TIME"
msgstr "Yalnızca ZAMAN tarihinden önceki değişiklikleri göster"

#: app/flatpak-builtins-history.c:52
msgid "Show newest entries first"
msgstr "Önce en yeni girdileri göster"

#: app/flatpak-builtins-history.c:59
msgid "Time"
msgstr "Zaman"

#: app/flatpak-builtins-history.c:59
msgid "Show when the change happened"
msgstr "Değişikliğin ne zaman yapıldığını göster"

# İsim anlamında.
#: app/flatpak-builtins-history.c:60
msgid "Change"
msgstr "Değişiklik"

#: app/flatpak-builtins-history.c:60
msgid "Show the kind of change"
msgstr "Değişiklik türünü göster"

#: app/flatpak-builtins-history.c:61 app/flatpak-builtins-list.c:68
#: app/flatpak-builtins-remote-ls.c:75 app/flatpak-builtins-repo.c:335
msgid "Ref"
msgstr "Referans"

#: app/flatpak-builtins-history.c:61 app/flatpak-builtins-list.c:68
#: app/flatpak-builtins-remote-ls.c:75
msgid "Show the ref"
msgstr "Referansı göster"

#: app/flatpak-builtins-history.c:62
msgid "Show the application/runtime ID"
msgstr "Uygulama/çalışma zamanı kimliğini göster"

#: app/flatpak-builtins-history.c:63 app/flatpak-builtins-list.c:64
#: app/flatpak-builtins-ps.c:53 app/flatpak-builtins-remote-ls.c:73
#: app/flatpak-cli-transaction.c:1435
msgid "Arch"
msgstr "Mimari"

#: app/flatpak-builtins-history.c:63 app/flatpak-builtins-list.c:64
#: app/flatpak-builtins-ps.c:53 app/flatpak-builtins-remote-ls.c:73
msgid "Show the architecture"
msgstr "Mimariyi göster"

#: app/flatpak-builtins-history.c:64 app/flatpak-builtins-list.c:63
#: app/flatpak-builtins-ps.c:54 app/flatpak-builtins-remote-ls.c:72
#: app/flatpak-builtins-search.c:48 app/flatpak-cli-transaction.c:1438
msgid "Branch"
msgstr "Dal"

#: app/flatpak-builtins-history.c:64 app/flatpak-builtins-list.c:63
#: app/flatpak-builtins-remote-ls.c:72
msgid "Show the branch"
msgstr "Dalı göster"

#: app/flatpak-builtins-history.c:65 app/flatpak-builtins-list.c:67
msgid "Installation"
msgstr "Kurulum"

#: app/flatpak-builtins-history.c:65
msgid "Show the affected installation"
msgstr "Etkilenen kurulumları göster"

#: app/flatpak-builtins-history.c:66 app/flatpak-cli-transaction.c:1452
msgid "Remote"
msgstr "Uzak"

#: app/flatpak-builtins-history.c:66
msgid "Show the remote"
msgstr "Uzağı göster"

# İsim anlamında, fiil anlamında değil.
#: app/flatpak-builtins-history.c:67 app/flatpak-builtins-ps.c:55
#: app/flatpak-builtins-remote-ls.c:76
msgid "Commit"
msgstr "İşleme"

#: app/flatpak-builtins-history.c:67
msgid "Show the current commit"
msgstr "Geçerli işlemeyi göster"

#: app/flatpak-builtins-history.c:68
msgid "Old Commit"
msgstr "Eski İşleme"

#: app/flatpak-builtins-history.c:68
msgid "Show the previous commit"
msgstr "Önceki işlemeyi göster"

#: app/flatpak-builtins-history.c:69
msgid "Show the remote URL"
msgstr "Uzak URL’yi göster"

#: app/flatpak-builtins-history.c:70 app/flatpak-cli-transaction.c:700
msgid "User"
msgstr "Kullanıcı"

#: app/flatpak-builtins-history.c:70
msgid "Show the user doing the change"
msgstr "Değişikliği yapan kullanıcıyı göster"

#: app/flatpak-builtins-history.c:71
msgid "Tool"
msgstr "Araç"

#: app/flatpak-builtins-history.c:71
msgid "Show the tool that was used"
msgstr "Kullanılan aracı göster"

#: app/flatpak-builtins-history.c:72 app/flatpak-builtins-list.c:62
#: app/flatpak-builtins-remote-ls.c:71 app/flatpak-builtins-search.c:47
msgid "Version"
msgstr "Sürüm"

#: app/flatpak-builtins-history.c:72
msgid "Show the Flatpak version"
msgstr "Flatpak sürümünü göster"

#: app/flatpak-builtins-history.c:91
#, c-format
msgid "Failed to get journal data (%s): %s"
msgstr "Günlük verisi (%s) alınamadı: %s"

#: app/flatpak-builtins-history.c:146
#, c-format
msgid "Failed to open journal: %s"
msgstr "Günlük açılamadı: %s"

#: app/flatpak-builtins-history.c:153
#, c-format
msgid "Failed to add match to journal: %s"
msgstr "Eşleşme günlüğe eklenemedi: %s"

#: app/flatpak-builtins-history.c:471
msgid " - Show history"
msgstr " - Geçmişi göster"

#: app/flatpak-builtins-history.c:490
#, c-format
msgid "Failed to parse the --since option"
msgstr "--since seçeneği ayrıştırılamadı"

#: app/flatpak-builtins-history.c:501
#, c-format
msgid "Failed to parse the --until option"
msgstr "--until seçeneği ayrıştırılamadı"

#: app/flatpak-builtins-info.c:56
msgid "Show user installations"
msgstr "Kullanıcı kurulumlarını göster"

#: app/flatpak-builtins-info.c:57
msgid "Show system-wide installations"
msgstr "Sistem-geneli kurulumları göster"

#: app/flatpak-builtins-info.c:58
msgid "Show specific system-wide installations"
msgstr "Belirli sistem-geneli kurulumları göster"

#: app/flatpak-builtins-info.c:59 app/flatpak-builtins-remote-info.c:59
msgid "Show ref"
msgstr "Referansı göster"

#: app/flatpak-builtins-info.c:60 app/flatpak-builtins-remote-info.c:60
msgid "Show commit"
msgstr "İşlemeyi göster"

#: app/flatpak-builtins-info.c:61
msgid "Show origin"
msgstr "Kökeni göster"

#: app/flatpak-builtins-info.c:62
msgid "Show size"
msgstr "Boyut göster"

#: app/flatpak-builtins-info.c:63 app/flatpak-builtins-remote-info.c:62
msgid "Show metadata"
msgstr "Üst veri göster"

#: app/flatpak-builtins-info.c:64 app/flatpak-builtins-remote-info.c:63
msgid "Show runtime"
msgstr "Çalışma zamanı göster"

#: app/flatpak-builtins-info.c:65 app/flatpak-builtins-remote-info.c:64
msgid "Show sdk"
msgstr "Sdk göster"

#: app/flatpak-builtins-info.c:66
msgid "Show permissions"
msgstr "İzinleri göster"

#: app/flatpak-builtins-info.c:67
msgid "Query file access"
msgstr "Dosya erişimini sorgula"

#: app/flatpak-builtins-info.c:67 app/flatpak-builtins-install.c:82
#: app/flatpak-builtins-install.c:88 app/flatpak-builtins-preinstall.c:68
#: app/flatpak-builtins-run.c:182 app/flatpak-builtins-run.c:184
#: app/flatpak-builtins-update.c:67 app/flatpak-builtins-update.c:71
msgid "PATH"
msgstr "YOL"

#: app/flatpak-builtins-info.c:68
msgid "Show extensions"
msgstr "Uzantıları göster"

#: app/flatpak-builtins-info.c:69
msgid "Show location"
msgstr "Konumu göster"

#: app/flatpak-builtins-info.c:116
msgid "NAME [BRANCH] - Get info about an installed app or runtime"
msgstr ""
"AD [DAL] - Kurulu uygulamalar ve/veya çalışma ortamlarıyla ilgili bilgi al"

#: app/flatpak-builtins-info.c:123 app/flatpak-builtins-remote-add.c:317
#: app/flatpak-builtins-remote-delete.c:63
msgid "NAME must be specified"
msgstr "AD belirtilmelidir"

#: app/flatpak-builtins-info.c:196
msgid "ref not present in origin"
msgstr "referans kökende yok"

#: app/flatpak-builtins-info.c:211 app/flatpak-builtins-remote-info.c:217
#, c-format
msgid "Warning: Commit has no flatpak metadata\n"
msgstr "Uyarı: İşleme flatpak üst verisi içermiyor\n"

#: app/flatpak-builtins-info.c:217 app/flatpak-builtins-info.c:259
#: app/flatpak-builtins-info.c:455 app/flatpak-builtins-info.c:513
#: app/flatpak-builtins-remote-info.c:236
#: app/flatpak-builtins-remote-info.c:271
msgid "ID:"
msgstr "Kimlik:"

#: app/flatpak-builtins-info.c:218 app/flatpak-builtins-info.c:260
#: app/flatpak-builtins-remote-info.c:237
#: app/flatpak-builtins-remote-info.c:272
msgid "Ref:"
msgstr "Ref:"

#: app/flatpak-builtins-info.c:219 app/flatpak-builtins-info.c:261
#: app/flatpak-builtins-remote-info.c:238
#: app/flatpak-builtins-remote-info.c:273
msgid "Arch:"
msgstr "Mimari:"

#: app/flatpak-builtins-info.c:220 app/flatpak-builtins-info.c:262
#: app/flatpak-builtins-remote-info.c:239
#: app/flatpak-builtins-remote-info.c:274
msgid "Branch:"
msgstr "Dal:"

#: app/flatpak-builtins-info.c:222 app/flatpak-builtins-info.c:264
#: app/flatpak-builtins-remote-info.c:241
#: app/flatpak-builtins-remote-info.c:276
msgid "Version:"
msgstr "Sürüm:"

#: app/flatpak-builtins-info.c:224 app/flatpak-builtins-info.c:266
#: app/flatpak-builtins-remote-info.c:243
#: app/flatpak-builtins-remote-info.c:278
msgid "License:"
msgstr "Lisans:"

#: app/flatpak-builtins-info.c:226 app/flatpak-builtins-info.c:269
#: app/flatpak-builtins-remote-info.c:245
#: app/flatpak-builtins-remote-info.c:280
msgid "Collection:"
msgstr "Koleksiyon:"

#: app/flatpak-builtins-info.c:227 app/flatpak-builtins-info.c:270
#: app/flatpak-builtins-info.c:458 app/flatpak-builtins-info.c:516
msgid "Installation:"
msgstr "Kurulum:"

#: app/flatpak-builtins-info.c:228 app/flatpak-builtins-info.c:271
#: app/flatpak-builtins-info.c:459 app/flatpak-builtins-info.c:517
#: app/flatpak-builtins-remote-info.c:249
#: app/flatpak-builtins-remote-info.c:284
msgid "Installed Size:"
msgstr "Kurulu Boyut:"

#: app/flatpak-builtins-info.c:231 app/flatpak-builtins-info.c:279
#: app/flatpak-builtins-remote-info.c:252
#: app/flatpak-builtins-remote-info.c:288
msgid "Runtime:"
msgstr "Çalışma zamanı:"

#: app/flatpak-builtins-info.c:232 app/flatpak-builtins-info.c:288
#: app/flatpak-builtins-remote-info.c:253
#: app/flatpak-builtins-remote-info.c:293
msgid "Sdk:"
msgstr "Sdk:"

#: app/flatpak-builtins-info.c:235 app/flatpak-builtins-info.c:313
#: app/flatpak-builtins-remote-info.c:256
#: app/flatpak-builtins-remote-info.c:319
msgid "Date:"
msgstr "Tarih:"

#: app/flatpak-builtins-info.c:237 app/flatpak-builtins-info.c:311
#: app/flatpak-builtins-remote-info.c:258
#: app/flatpak-builtins-remote-info.c:317
msgid "Subject:"
msgstr "Konu:"

#: app/flatpak-builtins-info.c:240 app/flatpak-builtins-info.c:295
msgid "Active commit:"
msgstr "Etkin işleme:"

#: app/flatpak-builtins-info.c:241 app/flatpak-builtins-info.c:298
msgid "Latest commit:"
msgstr "Son işleme:"

#: app/flatpak-builtins-info.c:244 app/flatpak-builtins-info.c:303
#: app/flatpak-builtins-info.c:457 app/flatpak-builtins-info.c:515
#: app/flatpak-builtins-remote-info.c:259
#: app/flatpak-builtins-remote-info.c:298
msgid "Commit:"
msgstr "İşleme:"

#: app/flatpak-builtins-info.c:246 app/flatpak-builtins-info.c:308
#: app/flatpak-builtins-remote-info.c:261
#: app/flatpak-builtins-remote-info.c:303
msgid "Parent:"
msgstr "Üst:"

#: app/flatpak-builtins-info.c:248 app/flatpak-builtins-info.c:321
msgid "Alt-id:"
msgstr "Alternatif kimlik:"

#: app/flatpak-builtins-info.c:250 app/flatpak-builtins-info.c:325
#: app/flatpak-builtins-remote-info.c:263
#: app/flatpak-builtins-remote-info.c:308
msgid "End-of-life:"
msgstr "Ömrünü doldurdu:"

#: app/flatpak-builtins-info.c:252 app/flatpak-builtins-info.c:330
#: app/flatpak-builtins-remote-info.c:265
#: app/flatpak-builtins-remote-info.c:313
msgid "End-of-life-rebase:"
msgstr "Ömrünü doldurdu yeniden temellendirme:"

#: app/flatpak-builtins-info.c:254 app/flatpak-builtins-info.c:317
msgid "Subdirectories:"
msgstr "Alt dizinler:"

#: app/flatpak-builtins-info.c:255 app/flatpak-builtins-info.c:454
#: app/flatpak-builtins-info.c:512
msgid "Extension:"
msgstr "Uzantı:"

#: app/flatpak-builtins-info.c:267 app/flatpak-builtins-info.c:456
#: app/flatpak-builtins-info.c:514
msgid "Origin:"
msgstr "Köken:"

#: app/flatpak-builtins-info.c:460 app/flatpak-builtins-info.c:522
msgid "Subpaths:"
msgstr "Alt yollar:"

#: app/flatpak-builtins-info.c:478
msgid "unmaintained"
msgstr "bakımsız"

#: app/flatpak-builtins-info.c:480 app/flatpak-builtins-info.c:482
msgid "unknown"
msgstr "bilinmeyen"

#: app/flatpak-builtins-install.c:68 app/flatpak-builtins-preinstall.c:57
msgid "Don't pull, only install from local cache"
msgstr "Çekme, yalnızca yerel önbellekten kur"

#: app/flatpak-builtins-install.c:69 app/flatpak-builtins-preinstall.c:58
#: app/flatpak-builtins-update.c:60
msgid "Don't deploy, only download to local cache"
msgstr "Dağıtma, yalnızca yerel önbelleğe indir"

#: app/flatpak-builtins-install.c:70 app/flatpak-builtins-preinstall.c:59
msgid "Don't install related refs"
msgstr "İlişkili referansları kurma"

#: app/flatpak-builtins-install.c:71 app/flatpak-builtins-preinstall.c:60
#: app/flatpak-builtins-update.c:62
msgid "Don't verify/install runtime dependencies"
msgstr "Çalışma zamanı bağımlılıklarını doğrulama/kurma"

#: app/flatpak-builtins-install.c:72
msgid "Don't automatically pin explicit installs"
msgstr "Açık kurulumları kendiliğinden sabitleme"

#: app/flatpak-builtins-install.c:73 app/flatpak-builtins-preinstall.c:61
#: app/flatpak-builtins-update.c:63
msgid "Don't use static deltas"
msgstr "Durağan deltaları kullanma"

#: app/flatpak-builtins-install.c:76 app/flatpak-builtins-preinstall.c:62
msgid "Additionally install the SDK used to build the given refs"
msgstr "Verilen referansları oluşturmak için kullanılan SDKʼyi ek olarak kur"

#: app/flatpak-builtins-install.c:77 app/flatpak-builtins-preinstall.c:63
msgid ""
"Additionally install the debug info for the given refs and their dependencies"
msgstr ""
"Verilen referanslar ve bağımlılıkları için hata ayıklama bilgilerini ek "
"olarak kur"

#: app/flatpak-builtins-install.c:78
msgid "Assume LOCATION is a .flatpak single-file bundle"
msgstr "KONUM’un .flatpak tek dosya paketi olduğunu varsay"

#: app/flatpak-builtins-install.c:79
msgid "Assume LOCATION is a .flatpakref application description"
msgstr "KONUM’un .flatpakref uygulama açıklaması olduğunu varsay"

#: app/flatpak-builtins-install.c:80
msgid "Assume LOCATION is containers-transports(5) reference to an OCI image"
msgstr ""
"KONUM’un OCI görüntüsü için containers-transports(5) referansı olduğunu "
"varsay"

#: app/flatpak-builtins-install.c:81
msgid "Check bundle signatures with GPG key from FILE (- for stdin)"
msgstr "Paket imzalarını DOSYA’daki (stdin için -) GPG anahtarıyla denetle"

#: app/flatpak-builtins-install.c:82
msgid "Only install this subpath"
msgstr "Yalnızca bu alt yolu kur"

#: app/flatpak-builtins-install.c:83 app/flatpak-builtins-preinstall.c:64
#: app/flatpak-builtins-uninstall.c:63 app/flatpak-builtins-update.c:68
msgid "Automatically answer yes for all questions"
msgstr "Tüm soruları kendiliğinden evetle yanıtla"

#: app/flatpak-builtins-install.c:84 app/flatpak-builtins-preinstall.c:65
msgid "Uninstall first if already installed"
msgstr "Kurulu ise önce kaldır"

#: app/flatpak-builtins-install.c:85 app/flatpak-builtins-preinstall.c:66
#: app/flatpak-builtins-uninstall.c:64 app/flatpak-builtins-update.c:69
msgid "Produce minimal output and don't ask questions"
msgstr "En az çıktı üret ve soru sorma"

#: app/flatpak-builtins-install.c:86
msgid "Update install if already installed"
msgstr "Kurulu ise kurulumu güncelle"

#. Translators: A sideload is when you install from a local USB drive rather than the Internet.
#: app/flatpak-builtins-install.c:88 app/flatpak-builtins-preinstall.c:68
#: app/flatpak-builtins-update.c:71
msgid "Use this local repo for sideloads"
msgstr "Yan kurulumlar için bu yerel depoyu kullan"

#: app/flatpak-builtins-install.c:178
msgid "Bundle filename must be specified"
msgstr "Paket dosya adı belirtilmelidir"

#: app/flatpak-builtins-install.c:188
msgid "Remote bundles are not supported"
msgstr "Uzak paketler desteklenmemektedir"

#: app/flatpak-builtins-install.c:231
msgid "Filename or uri must be specified"
msgstr "Dosya adı veya uri belirtilmelidir"

#: app/flatpak-builtins-install.c:295
msgid "Image location must be specified"
msgstr "Görüntü konumu belirtilmelidir"

#: app/flatpak-builtins-install.c:345
msgid "[LOCATION/REMOTE] [REF…] - Install applications or runtimes"
msgstr "[KONUM/UZAK] [REFERANS…] - Uygulamalar veya çalışma ortamları kur"

#: app/flatpak-builtins-install.c:378
msgid "At least one REF must be specified"
msgstr "En az bir REFERANS belirtilmelidir"

#: app/flatpak-builtins-install.c:392
#, c-format
msgid "Looking for matches…\n"
msgstr "Eşleşmeler aranıyor…\n"

#: app/flatpak-builtins-install.c:513
#, c-format
msgid "No remote refs found for ‘%s’"
msgstr "‘%s’ için uzak referans bulunamadı"

#: app/flatpak-builtins-install.c:573 app/flatpak-builtins-uninstall.c:405
#: common/flatpak-ref-utils.c:689 common/flatpak-ref-utils.c:1595
#, c-format
msgid "Invalid branch %s: %s"
msgstr "Geçersiz dal %s: %s"

#: app/flatpak-builtins-install.c:606
#, c-format
msgid "Nothing matches %s in local repository for remote %s"
msgstr "Uzak %2$s için, %1$s yerel depodaki hiçbir şeyle eşleşmiyor"

#: app/flatpak-builtins-install.c:608
#, c-format
msgid "Nothing matches %s in remote %s"
msgstr "Uzak %2$s için, %1$s hiçbir şeyle eşleşmiyor"

#: app/flatpak-builtins-install.c:629
#, c-format
msgid "Skipping: %s\n"
msgstr "Atlanıyor: %s\n"

#: app/flatpak-builtins-kill.c:110
#, c-format
msgid "%s is not running"
msgstr "%s çalışmıyor"

#: app/flatpak-builtins-kill.c:136
msgid "INSTANCE - Stop a running application"
msgstr "ÖRNEK - Çalışan uygulamayı durdur"

#: app/flatpak-builtins-kill.c:144 app/flatpak-builtins-ps.c:256
msgid "Extra arguments given"
msgstr "Sağlanan ek argümanlar"

#: app/flatpak-builtins-kill.c:150
msgid "Must specify the app to kill"
msgstr "Öldürülecek uygulama belirtilmelidir"

#: app/flatpak-builtins-list.c:47
msgid "Show extra information"
msgstr "Ek bilgi göster"

#: app/flatpak-builtins-list.c:48
msgid "List installed runtimes"
msgstr "Kurulu çalışma ortamlarını listele"

#: app/flatpak-builtins-list.c:49
msgid "List installed applications"
msgstr "Kurulu uygulamaları listele"

#: app/flatpak-builtins-list.c:50
msgid "Arch to show"
msgstr "Gösterilecek mimari"

#: app/flatpak-builtins-list.c:51 app/flatpak-builtins-remote-ls.c:57
msgid "List all refs (including locale/debug)"
msgstr "Tüm referansları listele (yerel/hata ayıklama içerilir)"

#: app/flatpak-builtins-list.c:53 app/flatpak-builtins-remote-ls.c:58
msgid "List all applications using RUNTIME"
msgstr "ÇALIŞMA ORTAMINI kullanan tüm uygulamaları listele"

#: app/flatpak-builtins-list.c:59 app/flatpak-builtins-remote-list.c:51
#: app/flatpak-builtins-remote-ls.c:68 app/flatpak-builtins-search.c:44
msgid "Name"
msgstr "Ad"

#: app/flatpak-builtins-list.c:59 app/flatpak-builtins-remote-list.c:51
#: app/flatpak-builtins-remote-ls.c:68 app/flatpak-builtins-search.c:44
msgid "Show the name"
msgstr "Adı göster"

#: app/flatpak-builtins-list.c:60 app/flatpak-builtins-remote-list.c:60
#: app/flatpak-builtins-remote-ls.c:69 app/flatpak-builtins-search.c:45
msgid "Description"
msgstr "Açıklama"

#: app/flatpak-builtins-list.c:60 app/flatpak-builtins-remote-ls.c:69
#: app/flatpak-builtins-search.c:45
msgid "Show the description"
msgstr "Açıklamayı göster"

#: app/flatpak-builtins-list.c:61 app/flatpak-builtins-remote-ls.c:70
#: app/flatpak-builtins-search.c:46
msgid "Application ID"
msgstr "Uygulama Kimliği"

#: app/flatpak-builtins-list.c:61 app/flatpak-builtins-ps.c:52
#: app/flatpak-builtins-remote-ls.c:70 app/flatpak-builtins-search.c:46
msgid "Show the application ID"
msgstr "Uygulama kimliğini göster"

#: app/flatpak-builtins-list.c:62 app/flatpak-builtins-remote-ls.c:71
#: app/flatpak-builtins-search.c:47
msgid "Show the version"
msgstr "Sürümü göster"

#: app/flatpak-builtins-list.c:65 app/flatpak-builtins-ps.c:56
#: app/flatpak-builtins-remote-ls.c:77
msgid "Runtime"
msgstr "Çalışma zamanı"

#: app/flatpak-builtins-list.c:65
msgid "Show the used runtime"
msgstr "Kullanılan çalışma zamanını göster"

# Fuzzy: Durduğu yere bakmak lazım.
#: app/flatpak-builtins-list.c:66 app/flatpak-builtins-remote-ls.c:74
msgid "Show the origin remote"
msgstr "Uzak kökeni göster"

#: app/flatpak-builtins-list.c:67
msgid "Show the installation"
msgstr "Kurulumu göster"

#: app/flatpak-builtins-list.c:69
msgid "Active commit"
msgstr "Etkin işleme"

#: app/flatpak-builtins-list.c:69 app/flatpak-builtins-remote-ls.c:76
msgid "Show the active commit"
msgstr "Etkin işlemeyi göster"

#: app/flatpak-builtins-list.c:70
msgid "Latest commit"
msgstr "Son işleme"

#: app/flatpak-builtins-list.c:70
msgid "Show the latest commit"
msgstr "En son işlemeyi göster"

#: app/flatpak-builtins-list.c:71 app/flatpak-builtins-remote-ls.c:78
msgid "Installed size"
msgstr "Kurulu boyut"

#: app/flatpak-builtins-list.c:71 app/flatpak-builtins-remote-ls.c:78
msgid "Show the installed size"
msgstr "Kurulu boyutu göster"

#: app/flatpak-builtins-list.c:72 app/flatpak-builtins-remote-list.c:58
#: app/flatpak-builtins-remote-ls.c:80 app/flatpak-builtins-repo.c:340
msgid "Options"
msgstr "Seçenekler"

#: app/flatpak-builtins-list.c:72 app/flatpak-builtins-remote-list.c:58
#: app/flatpak-builtins-remote-ls.c:80
msgid "Show options"
msgstr "Seçenekleri göster"

#: app/flatpak-builtins-list.c:180
#, c-format
msgid "Unable to load details of %s: %s"
msgstr "%s ayrıntıları yüklenemedi: %s"

# ilk %s için iyelik kullanılmadı. Referansın türü belli değil.
#: app/flatpak-builtins-list.c:190
#, c-format
msgid "Unable to inspect current version of %s: %s"
msgstr "%s geçerli sürümü incelenemedi: %s"

#: app/flatpak-builtins-list.c:408
msgid " - List installed apps and/or runtimes"
msgstr " - Kurulu uygulamaları ve/veya çalışma ortamlarını listele"

#: app/flatpak-builtins-make-current.c:38
msgid "Arch to make current for"
msgstr "Geçerli yapılacak mimari"

#: app/flatpak-builtins-make-current.c:58
msgid "APP BRANCH - Make branch of application current"
msgstr "UYGULAMA DAL - Uygulamanın dalını geçerli yap"

#: app/flatpak-builtins-make-current.c:69 app/flatpak-builtins-run.c:260
msgid "APP must be specified"
msgstr "UYGULAMA belirtilmelidir"

#: app/flatpak-builtins-make-current.c:84
msgid "BRANCH must be specified"
msgstr "DAL belirtilmelidir"

#: app/flatpak-builtins-make-current.c:97
#, c-format
msgid "App %s branch %s is not installed"
msgstr "Uygulama %s dal %s kurulu değil"

#: app/flatpak-builtins-mask.c:42
msgid "Remove matching masks"
msgstr "Eşleşen maskeleri kaldır"

#: app/flatpak-builtins-mask.c:54
msgid ""
"[PATTERN…] - disable updates and automatic installation matching patterns"
msgstr ""
"[ÖRÜNTÜ…] - örüntülerle eşleşen güncellemeleri ve kendiliğinden kurulumları "
"devre dışı bırak"

#: app/flatpak-builtins-mask.c:73
#, c-format
msgid "No masked patterns\n"
msgstr "Maskelenen örüntü yok\n"

#: app/flatpak-builtins-mask.c:78
#, c-format
msgid "Masked patterns:\n"
msgstr "Maskelenen örüntüler:\n"

#: app/flatpak-builtins-override.c:42
msgid "Remove existing overrides"
msgstr "Var olan geçersiz kılmaları kaldır"

#: app/flatpak-builtins-override.c:43
msgid "Show existing overrides"
msgstr "Var olan geçersiz kılmaları göster"

#: app/flatpak-builtins-override.c:59
msgid "[APP] - Override settings [for application]"
msgstr "[UYGULAMA] - Ayarları geçersiz kıl [uygulama için]"

#: app/flatpak-builtins-permission-list.c:143
msgid "[TABLE] [ID] - List permissions"
msgstr "[TABLO] [KİMLİK] - İzinleri listele"

#: app/flatpak-builtins-permission-list.c:179
#: app/flatpak-builtins-permission-show.c:142
msgid "Table"
msgstr "Tablo"

#: app/flatpak-builtins-permission-list.c:180
#: app/flatpak-builtins-permission-show.c:143
msgid "Object"
msgstr "Nesne"

#: app/flatpak-builtins-permission-list.c:181
#: app/flatpak-builtins-permission-show.c:144
msgid "App"
msgstr "Uygulama"

#: app/flatpak-builtins-permission-list.c:183
#: app/flatpak-builtins-permission-show.c:146
msgid "Data"
msgstr "Veri"

#: app/flatpak-builtins-permission-remove.c:120
msgid "TABLE ID [APP_ID] - Remove item from permission store"
msgstr "TABLO KİMLİK [UYGULAMA_KİMLİĞİ] - Ögeyi izin deposundan kaldır"

#: app/flatpak-builtins-permission-remove.c:129
#: app/flatpak-builtins-permission-set.c:120
msgid "Too few arguments"
msgstr "Çok az argüman"

#: app/flatpak-builtins-permission-reset.c:43
msgid "Reset all permissions"
msgstr "Tüm izinleri sıfırla"

#: app/flatpak-builtins-permission-reset.c:144
msgid "APP_ID - Reset permissions for an app"
msgstr "UYGULAMA_KİMLİĞİ - Uygulama izinlerini sıfırla"

#: app/flatpak-builtins-permission-reset.c:153
#: app/flatpak-builtins-permission-show.c:124
msgid "Wrong number of arguments"
msgstr "Yanlış sayıda argüman"

#: app/flatpak-builtins-permission-set.c:42
msgid "Associate DATA with the entry"
msgstr "VERİ’yi girdiyle ilişkilendir"

#: app/flatpak-builtins-permission-set.c:42
msgid "DATA"
msgstr "VERİ"

#: app/flatpak-builtins-permission-set.c:111
msgid "TABLE ID APP_ID [PERMISSION...] - Set permissions"
msgstr "TABLO KİMLİK UYGULAMA_KİMLİĞİ [İZİN...] - İzinleri ayarla"

#: app/flatpak-builtins-permission-set.c:132
#, c-format
msgid "Failed to parse '%s' as GVariant: "
msgstr "'%s', GVariant olarak ayrıştırılamadı: "

#: app/flatpak-builtins-permission-show.c:115
msgid "APP_ID - Show permissions for an app"
msgstr "UYGULAMA_KİMLİĞİ - Uygulama izinlerini göster"

#: app/flatpak-builtins-pin.c:44
msgid "Remove matching pins"
msgstr "Eşleyen sabitlemeleri kaldır"

#: app/flatpak-builtins-pin.c:56
msgid "[PATTERN…] - disable automatic removal of runtimes matching patterns"
msgstr ""
"[ÖRÜNTÜ…] - örüntülerle eşleşen çalışma zamanlarının kendiliğinden "
"kaldırılmasını devre dışı bırak"

#: app/flatpak-builtins-pin.c:75
#, c-format
msgid "No pinned patterns\n"
msgstr "Sabitlenmiş örüntü yok\n"

#: app/flatpak-builtins-pin.c:80
#, c-format
msgid "Pinned patterns:\n"
msgstr "Sabitlenmiş örüntüler:\n"

#: app/flatpak-builtins-preinstall.c:80
msgid "- Install flatpaks that are part of the operating system"
msgstr "- İşletim sisteminin parçası olan flatpakları kur"

#: app/flatpak-builtins-preinstall.c:118
#, c-format
msgid "Nothing to do.\n"
msgstr "Yapacak bir şey yok.\n"

#: app/flatpak-builtins-ps.c:49
msgid "Instance"
msgstr "Örnek"

#: app/flatpak-builtins-ps.c:49
msgid "Show the instance ID"
msgstr "Örnek kimliğini göster"

#: app/flatpak-builtins-ps.c:50 app/flatpak-builtins-run.c:178
msgid "PID"
msgstr "PID"

#: app/flatpak-builtins-ps.c:50
msgid "Show the PID of the wrapper process"
msgstr "Sarıcı sürecin PID bilgisini göster"

#: app/flatpak-builtins-ps.c:51
msgid "Child-PID"
msgstr "Çocuk-PID"

#: app/flatpak-builtins-ps.c:51
msgid "Show the PID of the sandbox process"
msgstr "Yalıtılmış sürecin PID bilgisini göster"

#: app/flatpak-builtins-ps.c:54 app/flatpak-builtins-search.c:48
msgid "Show the application branch"
msgstr "Uygulama dalını göster"

#: app/flatpak-builtins-ps.c:55
msgid "Show the application commit"
msgstr "Uygulama işlemesini göster"

#: app/flatpak-builtins-ps.c:56
msgid "Show the runtime ID"
msgstr "Çalışma zamanı kimliğini göster"

# R. kelimesi Runtime kelimesinin kısaltması olması sebebiyle ÇZ (Çalışma Zamanı) olarak kullanıldı.
#: app/flatpak-builtins-ps.c:57
msgid "R.-Branch"
msgstr "ÇZ.-Dalı"

#: app/flatpak-builtins-ps.c:57
msgid "Show the runtime branch"
msgstr "Çalışma zamanı dalını göster"

# R. kelimesi Runtime kelimesinin kısaltması olması sebebiyle ÇZ (Çalışma Zamanı) olarak kullanıldı.
#: app/flatpak-builtins-ps.c:58
msgid "R.-Commit"
msgstr "ÇZ.-İşlemesi"

#: app/flatpak-builtins-ps.c:58
msgid "Show the runtime commit"
msgstr "Çalışma zamanı işlemesini göster"

#: app/flatpak-builtins-ps.c:59
msgid "Active"
msgstr "Etkin"

#: app/flatpak-builtins-ps.c:59
msgid "Show whether the app is active"
msgstr "Uygulamanın etkin olma durumunu göster"

#: app/flatpak-builtins-ps.c:60
msgid "Background"
msgstr "Arka plan"

#: app/flatpak-builtins-ps.c:60
msgid "Show whether the app is background"
msgstr "Uygulamanın arka planda olma durumunu göster"

#: app/flatpak-builtins-ps.c:246
msgid " - Enumerate running sandboxes"
msgstr " - Çalışan yalıtılmış alanları numaralandır"

#: app/flatpak-builtins-remote-add.c:66
msgid "Do nothing if the provided remote exists"
msgstr "Sağlanan uzak varsa hiçbir şey yapma"

#: app/flatpak-builtins-remote-add.c:67
msgid "LOCATION specifies a configuration file, not the repo location"
msgstr "KONUM yapılandırma dosyasını belirtir, depo konumunu değil"

#: app/flatpak-builtins-remote-add.c:72 app/flatpak-builtins-remote-modify.c:78
msgid "Disable GPG verification"
msgstr "GPG doğrulamayı devredışı bırak"

#: app/flatpak-builtins-remote-add.c:73 app/flatpak-builtins-remote-modify.c:79
msgid "Mark the remote as don't enumerate"
msgstr "Uzağı belirtilmemiş olarak işaretle"

#: app/flatpak-builtins-remote-add.c:74 app/flatpak-builtins-remote-modify.c:80
msgid "Mark the remote as don't use for deps"
msgstr "Uzağı bağımlılık için olarak işaretleme"

#: app/flatpak-builtins-remote-add.c:75 app/flatpak-builtins-remote-modify.c:81
msgid "Set priority (default 1, higher is more prioritized)"
msgstr "Öncelik belirle (öntanımlı 1, yüksek sayı daha öncelikli)"

#: app/flatpak-builtins-remote-add.c:75 app/flatpak-builtins-remote-modify.c:81
msgid "PRIORITY"
msgstr "ÖNCELİK"

#: app/flatpak-builtins-remote-add.c:76
msgid "The named subset to use for this remote"
msgstr "Bu uzak için kullanılacak adlandırılmış alt küme"

#: app/flatpak-builtins-remote-add.c:76 app/flatpak-builtins-remote-modify.c:71
msgid "SUBSET"
msgstr "ALTKÜME"

#: app/flatpak-builtins-remote-add.c:77 app/flatpak-builtins-remote-modify.c:82
msgid "A nice name to use for this remote"
msgstr "Bu uzak için kullanılacak güzel bir ad"

#: app/flatpak-builtins-remote-add.c:78 app/flatpak-builtins-remote-modify.c:83
msgid "A one-line comment for this remote"
msgstr "Bu depo için tek satırlık yorum"

#: app/flatpak-builtins-remote-add.c:79 app/flatpak-builtins-remote-modify.c:84
msgid "A full-paragraph description for this remote"
msgstr "Bu uzak için kullanılacak tek paragraflık açıklama"

#: app/flatpak-builtins-remote-add.c:80 app/flatpak-builtins-remote-modify.c:85
msgid "URL for a website for this remote"
msgstr "Bu uzak için web sitesi URL’si"

#: app/flatpak-builtins-remote-add.c:81 app/flatpak-builtins-remote-modify.c:86
msgid "URL for an icon for this remote"
msgstr "Bu uzak için simge URL’si"

#: app/flatpak-builtins-remote-add.c:82 app/flatpak-builtins-remote-modify.c:87
msgid "Default branch to use for this remote"
msgstr "Bu uzak için kullanılacak öntanımlı dal"

#: app/flatpak-builtins-remote-add.c:84 app/flatpak-builtins-remote-modify.c:89
msgid "Import GPG key from FILE (- for stdin)"
msgstr "DOSYA’dan GPG anahtarı içe aktar (stdin için -)"

#: app/flatpak-builtins-remote-add.c:85 app/flatpak-builtins-remote-modify.c:90
msgid "Load signatures from URL"
msgstr "URLʼden imza yükle"

#: app/flatpak-builtins-remote-add.c:86 app/flatpak-builtins-remote-modify.c:92
msgid "Set path to local filter FILE"
msgstr "Yerel süzgeç DOSYA yolunu belirle"

#: app/flatpak-builtins-remote-add.c:87 app/flatpak-builtins-remote-modify.c:93
msgid "Disable the remote"
msgstr "Uzağı devredışı bırak"

#: app/flatpak-builtins-remote-add.c:88 app/flatpak-builtins-remote-modify.c:94
msgid "Name of authenticator"
msgstr "Kimlik doğrulayıcının adı"

#: app/flatpak-builtins-remote-add.c:90 app/flatpak-builtins-remote-modify.c:96
msgid "Autoinstall authenticator"
msgstr "Kimlik doğrulayıcıyı kendiliğinden kur"

#: app/flatpak-builtins-remote-add.c:91 app/flatpak-builtins-remote-modify.c:97
msgid "Don't autoinstall authenticator"
msgstr "Kimlik doğrulayıcıyı kendiliğinden kurma"

#: app/flatpak-builtins-remote-add.c:92 app/flatpak-builtins-remote-modify.c:99
msgid "Don't follow the redirect set in the summary file"
msgstr "Özet dosyasındaki yönlendirme kümesini izleme"

#: app/flatpak-builtins-remote-add.c:261 app/flatpak-builtins-remote-add.c:268
#, c-format
msgid "Can't load uri %s: %s\n"
msgstr "Uri %s yüklenemedi: %s\n"

#: app/flatpak-builtins-remote-add.c:276 common/flatpak-dir.c:4643
#, c-format
msgid "Can't load file %s: %s\n"
msgstr "%s dosyası yüklenemedi: %s\n"

#: app/flatpak-builtins-remote-add.c:304
msgid "NAME LOCATION - Add a remote repository"
msgstr "AD KONUM - Uzak depo ekle"

#: app/flatpak-builtins-remote-add.c:331
msgid "GPG verification is required if collections are enabled"
msgstr "Koleksiyonlar etkinse GPG doğrulaması gerekir"

#: app/flatpak-builtins-remote-add.c:393
#, c-format
msgid "Remote %s already exists"
msgstr "Uzak %s zaten var"

#: app/flatpak-builtins-remote-add.c:405
#: app/flatpak-builtins-remote-modify.c:340
#, c-format
msgid "Invalid authenticator name %s"
msgstr "Geçersiz kimlik doğrulayıcı adı %s"

#: app/flatpak-builtins-remote-add.c:422
#, c-format
msgid "Warning: Could not update extra metadata for '%s': %s\n"
msgstr "Uyarı: '%s' için ek üst veri güncellenemedi: %s\n"

#: app/flatpak-builtins-remote-delete.c:39
msgid "Remove remote even if in use"
msgstr "Uzak, kullanılıyor olsa da kaldır"

#: app/flatpak-builtins-remote-delete.c:53
msgid "NAME - Delete a remote repository"
msgstr "AD - Uzak depoyu sil"

#: app/flatpak-builtins-remote-delete.c:100
#, c-format
msgid "The following refs are installed from remote '%s':"
msgstr "Aşağıdaki referanslar '%s' uzağından kuruldu:"

#: app/flatpak-builtins-remote-delete.c:101
msgid "Remove them?"
msgstr "Kaldırılsın mı?"

#: app/flatpak-builtins-remote-delete.c:103
#, c-format
msgid "Can't remove remote '%s' with installed refs"
msgstr "'%s' uzağı kurulu referanslarla kaldırılamıyor"

#: app/flatpak-builtins-remote-info.c:55
msgid "Commit to show info for"
msgstr "Bilgi için gösterilecek işleme"

#: app/flatpak-builtins-remote-info.c:58
msgid "Display log"
msgstr "Günlüğü göster"

#: app/flatpak-builtins-remote-info.c:61
msgid "Show parent"
msgstr "Ebeveyni göster"

#: app/flatpak-builtins-remote-info.c:65 app/flatpak-builtins-remote-ls.c:60
msgid "Use local caches even if they are stale"
msgstr "Eski olsalar bile yerel önbellekleri kullan"

#. Translators: A sideload is when you install from a local USB drive rather than the Internet.
#: app/flatpak-builtins-remote-info.c:67 app/flatpak-builtins-remote-ls.c:62
msgid "Only list refs available as sideloads"
msgstr "Yalnızca yan kurulum olarak kullanılabilen referansları listele"

#: app/flatpak-builtins-remote-info.c:114
msgid ""
" REMOTE REF - Show information about an application or runtime in a remote"
msgstr ""
" UZAK REFERANS - Uzaktaki uygulama ya da çalışma zamanıyla ilgili bilgileri "
"göster"

#: app/flatpak-builtins-remote-info.c:125
msgid "REMOTE and REF must be specified"
msgstr "UZAK ve REFERANS belirtilmelidir"

#: app/flatpak-builtins-remote-info.c:247
#: app/flatpak-builtins-remote-info.c:282
msgid "Download Size:"
msgstr "İndirme Boyutu:"

#: app/flatpak-builtins-remote-info.c:267
#: app/flatpak-builtins-remote-info.c:325
msgid "History:"
msgstr "Geçmiş:"

#: app/flatpak-builtins-remote-info.c:348
msgid " Commit:"
msgstr " İşleme:"

#: app/flatpak-builtins-remote-info.c:349
msgid " Subject:"
msgstr " Konu:"

#: app/flatpak-builtins-remote-info.c:350
msgid " Date:"
msgstr " Tarih:"

#: app/flatpak-builtins-remote-info.c:383
#, c-format
msgid "Warning: Commit %s has no flatpak metadata\n"
msgstr "Uyarı: %s işlemesi flatpak üst verisi içermiyor\n"

#: app/flatpak-builtins-remote-list.c:43
msgid "Show remote details"
msgstr "Uzak ayrıntılarını göster"

#: app/flatpak-builtins-remote-list.c:44
msgid "Show disabled remotes"
msgstr "Devredışı bırakılmış uzakları göster"

#: app/flatpak-builtins-remote-list.c:52
msgid "Title"
msgstr "Başlık"

#: app/flatpak-builtins-remote-list.c:52
msgid "Show the title"
msgstr "Başlığı göster"

#: app/flatpak-builtins-remote-list.c:53
msgid "Show the URL"
msgstr "URL’yi göster"

#: app/flatpak-builtins-remote-list.c:54
msgid "Show the collection ID"
msgstr "Koleksiyon kimliğini göster"

#: app/flatpak-builtins-remote-list.c:55 app/flatpak-builtins-repo.c:392
msgid "Subset"
msgstr "Alt küme"

#: app/flatpak-builtins-remote-list.c:55
msgid "Show the subset"
msgstr "Alt kümeyi göster"

#: app/flatpak-builtins-remote-list.c:56
msgid "Filter"
msgstr "Süzgeç"

#: app/flatpak-builtins-remote-list.c:56
msgid "Show filter file"
msgstr "Süzgeç dosyasını göster"

#: app/flatpak-builtins-remote-list.c:57
msgid "Priority"
msgstr "Öncelik"

#: app/flatpak-builtins-remote-list.c:57
msgid "Show the priority"
msgstr "Önceliği göster"

#: app/flatpak-builtins-remote-list.c:59
msgid "Comment"
msgstr "Yorum"

#: app/flatpak-builtins-remote-list.c:59
msgid "Show comment"
msgstr "Yorumu göster"

#: app/flatpak-builtins-remote-list.c:60
msgid "Show description"
msgstr "Açıklamayı göster"

#: app/flatpak-builtins-remote-list.c:61
msgid "Homepage"
msgstr "Ana sayfa"

#: app/flatpak-builtins-remote-list.c:61
msgid "Show homepage"
msgstr "Ana sayfayı göster"

#: app/flatpak-builtins-remote-list.c:62
msgid "Icon"
msgstr "Simge"

#: app/flatpak-builtins-remote-list.c:62
msgid "Show icon"
msgstr "Simge göster"

#: app/flatpak-builtins-remote-list.c:231
msgid " - List remote repositories"
msgstr " - Uzak depoları listele"

#: app/flatpak-builtins-remote-ls.c:52
msgid "Show arches and branches"
msgstr "Mimarileri ve dalları göster"

#: app/flatpak-builtins-remote-ls.c:53
msgid "Show only runtimes"
msgstr "Yalnızca çalışma zamanlarını göster"

#: app/flatpak-builtins-remote-ls.c:54
msgid "Show only apps"
msgstr "Yalnızca uygulamaları göster"

#: app/flatpak-builtins-remote-ls.c:55
msgid "Show only those where updates are available"
msgstr "Yalnızca güncellemeleri olanları göster"

#: app/flatpak-builtins-remote-ls.c:56
msgid "Limit to this arch (* for all)"
msgstr "Bu mimariyle kısıtla (tümü için *)"

#: app/flatpak-builtins-remote-ls.c:77
msgid "Show the runtime"
msgstr "Çalışma zamanını göster"

#: app/flatpak-builtins-remote-ls.c:79
msgid "Download size"
msgstr "İndirme boyutu"

#: app/flatpak-builtins-remote-ls.c:79
msgid "Show the download size"
msgstr "İndirme boyutunu göster"

#: app/flatpak-builtins-remote-ls.c:391
msgid " [REMOTE or URI] - Show available runtimes and applications"
msgstr ""
" [UZAK ya da URI] - Kullanılabilir çalışma zamanlarını ve uygulamaları göster"

#: app/flatpak-builtins-remote-modify.c:67
msgid "Enable GPG verification"
msgstr "GPG doğrulamayı etkinleştir"

#: app/flatpak-builtins-remote-modify.c:68
msgid "Mark the remote as enumerate"
msgstr "Uzağı belirtilmiş olarak işaretle"

#: app/flatpak-builtins-remote-modify.c:69
msgid "Mark the remote as used for dependencies"
msgstr "Uzağı bağımlılık için kullanılmış olarak işaretle"

#: app/flatpak-builtins-remote-modify.c:70
msgid "Set a new URL"
msgstr "Yeni URL belirle"

#: app/flatpak-builtins-remote-modify.c:71
msgid "Set a new subset to use"
msgstr "Yeni alt küme belirle"

#: app/flatpak-builtins-remote-modify.c:72
msgid "Enable the remote"
msgstr "Uzağı etkinleştir"

#: app/flatpak-builtins-remote-modify.c:73
msgid "Update extra metadata from the summary file"
msgstr "Özet dosyasından ek üst veri güncelle"

#: app/flatpak-builtins-remote-modify.c:91
msgid "Disable local filter"
msgstr "Yerel süzgeçleri devredışı bırak"

#: app/flatpak-builtins-remote-modify.c:95
msgid "Authenticator options"
msgstr "Kimlik doğrulayıcı seçenekleri"

#: app/flatpak-builtins-remote-modify.c:98
msgid "Follow the redirect set in the summary file"
msgstr "Özet dosyasındaki yönlendirme kümesini izle"

#: app/flatpak-builtins-remote-modify.c:306
msgid "NAME - Modify a remote repository"
msgstr "AD - Uzak depoyu düzenle"

#: app/flatpak-builtins-remote-modify.c:316
msgid "Remote NAME must be specified"
msgstr "Uzak AD belirtilmelidir"

#: app/flatpak-builtins-remote-modify.c:327
#, c-format
msgid "Updating extra metadata from remote summary for %s\n"
msgstr "%s için uzak özetinden ek üst veri güncelleniyor\n"

#: app/flatpak-builtins-remote-modify.c:330
#, c-format
msgid "Error updating extra metadata for '%s': %s\n"
msgstr "'%s' için ek üst veri güncellenirken hata: %s\n"

#: app/flatpak-builtins-remote-modify.c:331
#, c-format
msgid "Could not update extra metadata for %s"
msgstr "%s için ek üst veri güncellenemedi"

#: app/flatpak-builtins-repair.c:43
msgid "Don't make any changes"
msgstr "Hiçbir değişiklik yapma"

#: app/flatpak-builtins-repair.c:44
msgid "Reinstall all refs"
msgstr "Tüm referansları yeniden kur"

#: app/flatpak-builtins-repair.c:68
#, c-format
msgid "Object missing: %s.%s\n"
msgstr "Nesne yitik: %s.%s\n"

#: app/flatpak-builtins-repair.c:76
#, c-format
msgid "Object invalid: %s.%s\n"
msgstr "Nesne geçersiz: %s.%s\n"

# %s yerine uyarı mesajı geliyor
#: app/flatpak-builtins-repair.c:81
#, c-format
msgid "%s, deleting object\n"
msgstr "%s, nesne siliniyor\n"

#: app/flatpak-builtins-repair.c:146
#, c-format
msgid "Can't load object %s: %s\n"
msgstr "%s nesnesi yüklenemedi: %s\n"

# s1: checksum, s2: local_error->message
#: app/flatpak-builtins-repair.c:228
#, c-format
msgid "Commit invalid %s: %s\n"
msgstr "İşleme geçersiz %s: %s\n"

#: app/flatpak-builtins-repair.c:231
#, c-format
msgid "Deleting invalid commit %s: %s\n"
msgstr "%s geçersiz işlemesi siliniyor: %s\n"

#: app/flatpak-builtins-repair.c:261
#, c-format
msgid "Commit should be marked partial: %s\n"
msgstr "İşleme kısmi olarak işaretlenmelidir: %s\n"

#: app/flatpak-builtins-repair.c:264
#, c-format
msgid "Marking commit as partial: %s\n"
msgstr "İşleme kısmi olarak işaretleniyor: %s\n"

#: app/flatpak-builtins-repair.c:293
#, c-format
msgid "Problems loading data for %s: %s\n"
msgstr "%s için veri yüklenirken hata: %s\n"

#: app/flatpak-builtins-repair.c:306
#, c-format
msgid "Error reinstalling %s: %s\n"
msgstr "%s yeniden kurulurken hata: %s\n"

#: app/flatpak-builtins-repair.c:327
msgid "- Repair a flatpak installation"
msgstr "- Flatpak kurulumunu onar"

#: app/flatpak-builtins-repair.c:406
#, c-format
msgid "Removing non-deployed ref %s…\n"
msgstr "Dağıtılmamış referans %s kaldırılıyor…\n"

#: app/flatpak-builtins-repair.c:411
#, c-format
msgid "Skipping non-deployed ref %s…\n"
msgstr "Dağıtılmamış referans %s atlanıyor…\n"

#: app/flatpak-builtins-repair.c:429
#, c-format
msgid "[%d/%d] Verifying %s…\n"
msgstr "[%d/%d] %s doğrulanıyor…\n"

#: app/flatpak-builtins-repair.c:435
#, c-format
msgid "Dry run: "
msgstr "Kuru çalıştırma: "

#: app/flatpak-builtins-repair.c:440
#, c-format
msgid "Deleting ref %s due to missing objects\n"
msgstr "%s referansı eksik nesneler nedeniyle siliniyor\n"

#: app/flatpak-builtins-repair.c:444
#, c-format
msgid "Deleting ref %s due to invalid objects\n"
msgstr "%s referansı geçersiz nesneler nedeniyle siliniyor\n"

#: app/flatpak-builtins-repair.c:448
#, c-format
msgid "Deleting ref %s due to %d\n"
msgstr "%s referansı %d nedeniyle siliniyor\n"

#: app/flatpak-builtins-repair.c:464
#, c-format
msgid "Checking remotes...\n"
msgstr "Uzaklar denetleniyor...\n"

#: app/flatpak-builtins-repair.c:482
#, c-format
msgid "Remote %s for ref %s is missing\n"
msgstr "%2$s referansı için %1$s uzağı yitik\n"

#: app/flatpak-builtins-repair.c:484
#, c-format
msgid "Remote %s for ref %s is disabled\n"
msgstr "%2$s referansı için %1$s devre dışı\n"

#: app/flatpak-builtins-repair.c:490
#, c-format
msgid "Pruning objects\n"
msgstr "Nesneler budanıyor\n"

#: app/flatpak-builtins-repair.c:498
#, c-format
msgid "Erasing .removed\n"
msgstr ".removed siliniyor\n"

#: app/flatpak-builtins-repair.c:524
#, c-format
msgid "Reinstalling refs\n"
msgstr "Referanslar yeniden kuruluyor\n"

#: app/flatpak-builtins-repair.c:526
#, c-format
msgid "Reinstalling removed refs\n"
msgstr "Kaldırılan referanslar yeniden kuruluyor\n"

#: app/flatpak-builtins-repair.c:551
#, c-format
msgid "While removing appstream for %s: "
msgstr "%s için appstream kaldırılırken: "

#: app/flatpak-builtins-repair.c:558
#, c-format
msgid "While deploying appstream for %s: "
msgstr "%s için appstream dağıtılırken: "

#: app/flatpak-builtins-repo.c:106
#, c-format
msgid "Repo mode: %s\n"
msgstr "Depo kipi: %s\n"

#: app/flatpak-builtins-repo.c:113
#, c-format
msgid "Indexed summaries: %s\n"
msgstr "İndeksli özetler: %s\n"

#: app/flatpak-builtins-repo.c:113 app/flatpak-builtins-repo.c:139
#: app/flatpak-builtins-repo.c:172
msgid "true"
msgstr "doğru"

#: app/flatpak-builtins-repo.c:113 app/flatpak-builtins-repo.c:139
#: app/flatpak-builtins-repo.c:172
msgid "false"
msgstr "yanlış"

#: app/flatpak-builtins-repo.c:121
#, c-format
msgid "Subsummaries: "
msgstr "Alt özetler: "

#: app/flatpak-builtins-repo.c:136
#, c-format
msgid "Cache version: %d\n"
msgstr "Önbellek sürümü: %d\n"

#: app/flatpak-builtins-repo.c:139
#, c-format
msgid "Indexed deltas: %s\n"
msgstr "İndeksli deltalar: %s\n"

#: app/flatpak-builtins-repo.c:142
#, c-format
msgid "Title: %s\n"
msgstr "Başlık: %s\n"

#: app/flatpak-builtins-repo.c:145
#, c-format
msgid "Comment: %s\n"
msgstr "Yorum: %s\n"

#: app/flatpak-builtins-repo.c:148
#, c-format
msgid "Description: %s\n"
msgstr "Açıklama: %s\n"

#: app/flatpak-builtins-repo.c:151
#, c-format
msgid "Homepage: %s\n"
msgstr "Ana sayfa: %s\n"

#: app/flatpak-builtins-repo.c:154
#, c-format
msgid "Icon: %s\n"
msgstr "Simge: %s\n"

#: app/flatpak-builtins-repo.c:157
#, c-format
msgid "Collection ID: %s\n"
msgstr "Koleksiyon Kimliği: %s\n"

#: app/flatpak-builtins-repo.c:160
#, c-format
msgid "Default branch: %s\n"
msgstr "Öntanımlı dal: %s\n"

#: app/flatpak-builtins-repo.c:163
#, c-format
msgid "Redirect URL: %s\n"
msgstr "Yönlendirme URL’si: %s\n"

#: app/flatpak-builtins-repo.c:166
#, c-format
msgid "Deploy collection ID: %s\n"
msgstr "Kullanıcı kimliğini dağıt: %s\n"

#: app/flatpak-builtins-repo.c:169
#, c-format
msgid "Authenticator name: %s\n"
msgstr "Kimlik doğrulayıcı adı: %s\n"

#: app/flatpak-builtins-repo.c:172
#, c-format
msgid "Authenticator install: %s\n"
msgstr "Kimlik doğrulayıcı kur: %s\n"

#: app/flatpak-builtins-repo.c:180
#, c-format
msgid "GPG key hash: %s\n"
msgstr "GPG anahtar özeti: %s\n"

#: app/flatpak-builtins-repo.c:184
#, c-format
msgid "%zd summary branches\n"
msgstr "%zd özet dalları\n"

#: app/flatpak-builtins-repo.c:336
msgid "Installed"
msgstr "Kurulu"

#. Translators: Download is used here as a noun
#: app/flatpak-builtins-repo.c:338 app/flatpak-cli-transaction.c:1462
msgid "Download"
msgstr "İndirme"

#: app/flatpak-builtins-repo.c:339
msgid "Subsets"
msgstr "Alt kümeler"

# Özet anlamında kullanılmış.
# digest = ostree_checksum_from_bytes (checksum_bytes)
#: app/flatpak-builtins-repo.c:393
msgid "Digest"
msgstr "Özet"

#: app/flatpak-builtins-repo.c:394
msgid "History length"
msgstr "Geçmiş uzunluğu"

#: app/flatpak-builtins-repo.c:711
msgid "Print general information about the repository"
msgstr "Depoyla ilgili genel bilgileri yazdır"

#: app/flatpak-builtins-repo.c:712
msgid "List the branches in the repository"
msgstr "Arşivdeki dalları listele"

#: app/flatpak-builtins-repo.c:713
msgid "Print metadata for a branch"
msgstr "Dal için üst veriyi yazdır"

#: app/flatpak-builtins-repo.c:714
msgid "Show commits for a branch"
msgstr "Dal için işlemeleri göster"

#: app/flatpak-builtins-repo.c:715
msgid "Print information about the repo subsets"
msgstr "Depo alt kümeleriyle ilgili bilgileri yazdır"

#: app/flatpak-builtins-repo.c:716
msgid "Limit information to subsets with this prefix"
msgstr "Bilgileri bu ön ek ile alt kümelere sınırla"

#: app/flatpak-builtins-repo.c:732
msgid "LOCATION - Repository maintenance"
msgstr "KONUM - Arşiv bakım"

#: app/flatpak-builtins-run.c:159
msgid "Command to run"
msgstr "Çalıştırılacak komut"

#: app/flatpak-builtins-run.c:160
msgid "Directory to run the command in"
msgstr "Komutun çalıştırılacağı dizin"

#: app/flatpak-builtins-run.c:161
msgid "Branch to use"
msgstr "Kullanılacak dal"

#: app/flatpak-builtins-run.c:162
msgid "Use development runtime"
msgstr "Geliştirme çalışma zamanı kullan"

#: app/flatpak-builtins-run.c:163
msgid "Runtime to use"
msgstr "Kullanılacak çalışma zamanı"

#: app/flatpak-builtins-run.c:164
msgid "Runtime version to use"
msgstr "Kullanılacak çalışma zamanı sürümü"

#: app/flatpak-builtins-run.c:167
msgid "Log accessibility bus calls"
msgstr "Erişilebilirlik veri yolu çağrılarını günlükle"

#: app/flatpak-builtins-run.c:168
msgid "Don't proxy accessibility bus calls"
msgstr "Erişilebilirlik veri yolu çağrılarını vekil sunucu yapma"

#: app/flatpak-builtins-run.c:169
msgid "Proxy accessibility bus calls (default except when sandboxed)"
msgstr ""
"Erişilebilirlik veri yolu çağrılarını vekil sunucu yap (yalıtılmış alanlar "
"dışında öntanımlı)"

#: app/flatpak-builtins-run.c:170
msgid "Don't proxy session bus calls"
msgstr "Oturum veri yolu çağrılarını vekil sunucu yapma"

#: app/flatpak-builtins-run.c:171
msgid "Proxy session bus calls (default except when sandboxed)"
msgstr ""
"Oturum veri yolu çağrılarını vekil sunucu yap (yalıtılmış alanlar dışında "
"öntanımlı)"

#: app/flatpak-builtins-run.c:172
msgid "Don't start portals"
msgstr "Kapıları başlatma"

#: app/flatpak-builtins-run.c:173
msgid "Enable file forwarding"
msgstr "Dosya yönlendirmelerini etkinleştir"

#: app/flatpak-builtins-run.c:174
msgid "Run specified commit"
msgstr "Belirtilen işlemeyi çalıştır"

#: app/flatpak-builtins-run.c:175
msgid "Use specified runtime commit"
msgstr "Belirtilen çalışma zamanı işlemesini kullan"

#: app/flatpak-builtins-run.c:176
msgid "Run completely sandboxed"
msgstr "Tümüyle yalıtılmış olarak çalıştır"

#: app/flatpak-builtins-run.c:178
msgid "Use PID as parent pid for sharing namespaces"
msgstr "Ad alanlarını paylaşmak için PID’i ebeveyn PID olarak kullan"

#: app/flatpak-builtins-run.c:179
msgid "Make processes visible in parent namespace"
msgstr "Süreçleri üst ad alanında görünür yap"

#: app/flatpak-builtins-run.c:180
msgid "Share process ID namespace with parent"
msgstr "Süreç kimliği ad alanını ebeveynle paylaş"

#: app/flatpak-builtins-run.c:181
msgid "Write the instance ID to the given file descriptor"
msgstr "Örnek kimliğini belirtilen dosya tanımlayıcısına yaz"

#: app/flatpak-builtins-run.c:182
msgid "Use PATH instead of the app's /app"
msgstr "Uygulamanın /app dizini yerine YOL kullan"

#: app/flatpak-builtins-run.c:183
msgid "Use FD instead of the app's /app"
msgstr "Uygulamanın /app dizini yerine DT kullan"

# file descriptor kelimesinin kısaltması
#: app/flatpak-builtins-run.c:183 app/flatpak-builtins-run.c:185
#: app/flatpak-builtins-run.c:187 app/flatpak-builtins-run.c:188
#: common/flatpak-context.c:2672
msgid "FD"
msgstr "DT"

#: app/flatpak-builtins-run.c:184
msgid "Use PATH instead of the runtime's /usr"
msgstr "Çalışma zamanının /usr dizini yerine YOL kullan"

#: app/flatpak-builtins-run.c:185
msgid "Use FD instead of the runtime's /usr"
msgstr "Çalışma zamanının /usr dizini yerine DT kullan"

#: app/flatpak-builtins-run.c:186
msgid "Clear all outside environment variables"
msgstr "Tüm dış çevre değişkenlerini temizle"

#: app/flatpak-builtins-run.c:187
msgid ""
"Bind mount the file or directory referred to by FD to its canonicalized path"
msgstr "DT’nin andığı dosya ya da dizini, kanonik yoluna bağla"

#: app/flatpak-builtins-run.c:188
msgid ""
"Bind mount the file or directory referred to by FD read-only to its "
"canonicalized path"
msgstr "DT’nin andığı dosya ya da dizini, kanonik yoluna salt okunur bağla"

#: app/flatpak-builtins-run.c:219
msgid "APP [ARGUMENT…] - Run an app"
msgstr "UYGULAMA [ARGÜMAN…] - Uygulamayı çalıştır"

#: app/flatpak-builtins-run.c:370
#, c-format
msgid "runtime/%s/%s/%s not installed"
msgstr "çalışma zamanı/%s/%s/%s kurulu değil"

#: app/flatpak-builtins-run.c:419
msgid "app-fd and app-path cannot both be used"
msgstr "app-fd ve app-path aynı anda kullanılamaz"

#: app/flatpak-builtins-run.c:449
msgid "usr-fd and usr-path cannot both be used"
msgstr "usr-fd ve usr-path aynı anda kullanılamaz"

#: app/flatpak-builtins-search.c:37
msgid "Arch to search for"
msgstr "Aranacağı mimari"

#: app/flatpak-builtins-search.c:49
msgid "Remotes"
msgstr "Uzaklar"

#: app/flatpak-builtins-search.c:49
msgid "Show the remotes"
msgstr "Uzakları göster"

#: app/flatpak-builtins-search.c:244
msgid "TEXT - Search remote apps/runtimes for text"
msgstr "METİN - Uzak uygulamaları/çalışma zamanlarını metin için ara"

#: app/flatpak-builtins-search.c:255
msgid "TEXT must be specified"
msgstr "METİN belirtilmelidir"

#: app/flatpak-builtins-search.c:338
msgid "No matches found"
msgstr "Hiçbir sonuç bulunamadı"

#: app/flatpak-builtins-uninstall.c:54
msgid "Arch to uninstall"
msgstr "Kaldırılacak mimari"

#: app/flatpak-builtins-uninstall.c:55
msgid "Keep ref in local repository"
msgstr "Referansı yerel depoda sakla"

#: app/flatpak-builtins-uninstall.c:56
msgid "Don't uninstall related refs"
msgstr "İlişkili referansları kendiliğinden kaldırma"

#: app/flatpak-builtins-uninstall.c:57
msgid "Remove files even if running"
msgstr "Dosyaları çalışıyor olsalar da kaldır"

#: app/flatpak-builtins-uninstall.c:60
msgid "Uninstall all"
msgstr "Tümünü kaldır"

#: app/flatpak-builtins-uninstall.c:61
msgid "Uninstall unused"
msgstr "Kullanılmayanları kaldır"

#: app/flatpak-builtins-uninstall.c:62
msgid "Delete app data"
msgstr "Uygulama verilerini sil"

#: app/flatpak-builtins-uninstall.c:141
#, c-format
msgid "Delete data for %s?"
msgstr "%s verileri silinsin mi?"

#: app/flatpak-builtins-uninstall.c:220
#, c-format
msgid "Info: applications using the extension %s%s%s branch %s%s%s:\n"
msgstr "Bilgi: %s%s%s eklentisinin %s%s%s dalını kullanan uygulamalar:\n"

#: app/flatpak-builtins-uninstall.c:223
#, c-format
msgid "Info: applications using the runtime %s%s%s branch %s%s%s:\n"
msgstr "%s%s%s çalışma zamanının %s%s%s dalını kullanan uygulamalar:\n"

#: app/flatpak-builtins-uninstall.c:238
msgid "Really remove?"
msgstr "Gerçekten kaldırılsın mı?"

#: app/flatpak-builtins-uninstall.c:255
msgid "[REF…] - Uninstall applications or runtimes"
msgstr "[REFERANS…] - Uygulamaları veya çalışma zamanlarını kaldır"

#: app/flatpak-builtins-uninstall.c:264
msgid "Must specify at least one REF, --unused, --all or --delete-data"
msgstr ""
"En az bir REFERANS belirtilmelidir, --unused, --all ya da --delete-data"

#: app/flatpak-builtins-uninstall.c:267
msgid "Must not specify REFs when using --all"
msgstr "--all kullanılırken REFERANS belirtilmemelidir"

#: app/flatpak-builtins-uninstall.c:270
msgid "Must not specify REFs when using --unused"
msgstr "--unused kullanılırken REFERAN belirtilmemelidir"

#: app/flatpak-builtins-uninstall.c:336
#, c-format
msgid ""
"\n"
"These runtimes in installation '%s' are pinned and won't be removed; see "
"flatpak-pin(1):\n"
msgstr ""
"\n"
"'%s' kurulumundaki bu çalışma zamanları sabitlenmiş ve kaldırılmaz; bkz. "
"flatpak-pin(1):\n"

# Biraz bulanık oldu fakat sade oldu
#: app/flatpak-builtins-uninstall.c:370
#, c-format
msgid "Nothing unused to uninstall\n"
msgstr "Kaldırılacak kullanılmayan bir şey yok\n"

#: app/flatpak-builtins-uninstall.c:444
#, c-format
msgid "No installed refs found for ‘%s’"
msgstr "‘%s’ için benzer kurulu referanslar bulunamadı"

#: app/flatpak-builtins-uninstall.c:447
#, c-format
msgid " with arch ‘%s’"
msgstr " ‘%s’ mimarisi ile"

#: app/flatpak-builtins-uninstall.c:449
#, c-format
msgid " with branch ‘%s’"
msgstr " ‘%s’ dalı ile"

#: app/flatpak-builtins-uninstall.c:456
#, c-format
msgid "Warning: %s is not installed\n"
msgstr "Uyarı: %s kurulu değil\n"

#: app/flatpak-builtins-uninstall.c:490
#, c-format
msgid "None of the specified refs are installed"
msgstr "Belirtilen referansların hiçbiri kurulu değil"

#: app/flatpak-builtins-uninstall.c:599
#, c-format
msgid "No app data to delete\n"
msgstr "Silinecek uygulama verisi yok\n"

#: app/flatpak-builtins-update.c:56
msgid "Arch to update for"
msgstr "Güncelleneceği mimari"

#: app/flatpak-builtins-update.c:57
msgid "Commit to deploy"
msgstr "Dağıtılacak işleme"

#: app/flatpak-builtins-update.c:58
msgid "Remove old files even if running"
msgstr "Eski dosyaları çalışıyor olsalar da kaldır"

#: app/flatpak-builtins-update.c:59
msgid "Don't pull, only update from local cache"
msgstr "Çekme, yalnızca yerel önbellekten güncelle"

#: app/flatpak-builtins-update.c:61
msgid "Don't update related refs"
msgstr "İlişkili referansları güncelleme"

#: app/flatpak-builtins-update.c:66
msgid "Update appstream for remote"
msgstr "Appstream’i uzak için güncelle"

#: app/flatpak-builtins-update.c:67
msgid "Only update this subpath"
msgstr "Yalnızca bu alt yolu güncelle"

#: app/flatpak-builtins-update.c:90
msgid "[REF…] - Update applications or runtimes"
msgstr "[REFERANS…] - Uygulamaları ya da çalışma zamanlarını güncelle"

#: app/flatpak-builtins-update.c:121
msgid "With --commit, only one REF may be specified"
msgstr "--commit ile, tek bir REFERANS belirtilebilir"

#: app/flatpak-builtins-update.c:162
#, c-format
msgid "Looking for updates…\n"
msgstr "Güncellemeler aranıyor…\n"

#: app/flatpak-builtins-update.c:215
#, c-format
msgid "Unable to update %s: %s\n"
msgstr "%s güncellenemedi: %s\n"

#: app/flatpak-builtins-update.c:274
#, c-format
msgid "Nothing to update.\n"
msgstr "Güncellenecek bir şey yok.\n"

#: app/flatpak-builtins-utils.c:337
#, c-format
msgid ""
"Remote ‘%s’ found in multiple installations, unable to proceed in non-"
"interactive mode"
msgstr ""
"Uzak ‘%s’ birden çok kurulumda bulundu, etkileşimsiz kipte sürdürülemiyor"

#: app/flatpak-builtins-utils.c:346
#, c-format
msgid "Remote ‘%s’ found in multiple installations:"
msgstr "Uzak ‘%s’ birden çok kurulumda bulundu:"

#: app/flatpak-builtins-utils.c:347 app/flatpak-builtins-utils.c:442
#: app/flatpak-builtins-utils.c:538 app/flatpak-builtins-utils.c:540
#: app/flatpak-builtins-utils.c:598
msgid "Which do you want to use (0 to abort)?"
msgstr "Hangisini kurmak istiyorsunuz (vazgeçmek için 0)?"

#: app/flatpak-builtins-utils.c:349
#, c-format
msgid "No remote chosen to resolve ‘%s’ which exists in multiple installations"
msgstr "Birden çok kurulumda bulunan ‘%s’ çözümü için uzak seçilmedi"

# Vurgu ve netlik olması amacıyla komut tırnak içine alındı
#: app/flatpak-builtins-utils.c:358
#, c-format
msgid ""
"Remote \"%s\" not found\n"
"Hint: Use flatpak remote-add to add a remote"
msgstr ""
"Uzak \"%s\" bulunamadı\n"
"İpucu: Uzak eklemek için \"flatpak remote-add\" komutunu kullanın"

#: app/flatpak-builtins-utils.c:364
#, c-format
msgid "Remote \"%s\" not found in the %s installation"
msgstr "Uzak \"%s\", %s kurulumunda bulunamadı"

#: app/flatpak-builtins-utils.c:404
#, c-format
msgid "Multiple refs match ‘%s’, unable to proceed in non-interactive mode"
msgstr ""
"Birden çok referans ‘%s’ ile eşleşiyor, etkileşimsiz kipte sürdürülemiyor"

#. default to yes on Enter
#: app/flatpak-builtins-utils.c:430
#, c-format
msgid ""
"Found ref ‘%s’ in remote ‘%s’ (%s).\n"
"Use this ref?"
msgstr ""
"Referans ‘%s’ uzak ‘%s’ (%s) içinde bulundu.\n"
"Bu referans kullanılsın mı?"

#: app/flatpak-builtins-utils.c:434 app/flatpak-builtins-utils.c:444
#: app/flatpak-builtins-utils.c:522 app/flatpak-builtins-utils.c:543
#, c-format
msgid "No ref chosen to resolve matches for ‘%s’"
msgstr "‘%s’ eşleşmelerini çözmek için referans seçilmedi"

#: app/flatpak-builtins-utils.c:440
#, c-format
msgid "Similar refs found for ‘%s’ in remote ‘%s’ (%s):"
msgstr "‘%1$s’ için, ‘%2$s’ (%3$s) uzağında benzer referanslar bulundu:"

#: app/flatpak-builtins-utils.c:488
#, c-format
msgid ""
"Multiple installed refs match ‘%s’, unable to proceed in non-interactive mode"
msgstr ""
"Birden çok kurulu referans ‘%s’ ile eşleşiyor, etkileşimsiz kipte "
"sürdürülemiyor"

#. default to yes on Enter
#: app/flatpak-builtins-utils.c:518
#, c-format
msgid "Found installed ref ‘%s’ (%s). Is this correct?"
msgstr "Kurulu referans ‘%s’ (%s) bulundu. Bu doğru mu?"

#: app/flatpak-builtins-utils.c:534
#, c-format
msgid "All of the above"
msgstr "Üsttekilerin tümü"

#: app/flatpak-builtins-utils.c:535
#, c-format
msgid "Similar installed refs found for ‘%s’:"
msgstr "‘%s’ için benzer kurulu referanslar bulundu:"

#: app/flatpak-builtins-utils.c:579
#, c-format
msgid ""
"Multiple remotes have refs matching ‘%s’, unable to proceed in non-"
"interactive mode"
msgstr ""
"Birden çok uzağın ‘%s’ ile eşleşen referansları var, etkileşimsiz kipte "
"sürdürülemiyor"

#: app/flatpak-builtins-utils.c:597
#, c-format
msgid "Remotes found with refs similar to ‘%s’:"
msgstr "‘%s’ benzeri referansları olan uzaklar:"

#: app/flatpak-builtins-utils.c:600
#, c-format
msgid "No remote chosen to resolve matches for ‘%s’"
msgstr "‘%s’ eşleşmelerini çözmek için uzak seçilmedi"

#: app/flatpak-builtins-utils.c:696 app/flatpak-builtins-utils.c:699
#, c-format
msgid "Updating appstream data for user remote %s"
msgstr "Appstream verisi kullanıcı uzağı %s için güncelleniyor"

#: app/flatpak-builtins-utils.c:706 app/flatpak-builtins-utils.c:709
#, c-format
msgid "Updating appstream data for remote %s"
msgstr "Appstream verisi uzak %s için güncelleniyor"

#: app/flatpak-builtins-utils.c:717 app/flatpak-builtins-utils.c:719
msgid "Error updating"
msgstr "Güncelleme hatası"

#: app/flatpak-builtins-utils.c:755
#, c-format
msgid "Remote \"%s\" not found"
msgstr "Uzak \"%s\" bulunamadı"

#: app/flatpak-builtins-utils.c:796
#, c-format
msgid "Ambiguous suffix: '%s'."
msgstr "Belirsiz son ek: '%s'."

# Çeviri uyarısı sebebiyle değerler çevrilmedi
#. Translators: don't translate the values
#: app/flatpak-builtins-utils.c:798 app/flatpak-builtins-utils.c:813
msgid "Possible values are :s[tart], :m[iddle], :e[nd] or :f[ull]"
msgstr ""
"Kullanılabilir değerler :s[tart] (başlangıç), :m[iddle] (orta), :e[nd] (son) "
"ya da :f[ull] (tümü)"

#: app/flatpak-builtins-utils.c:811
#, c-format
msgid "Invalid suffix: '%s'."
msgstr "Geçersiz son ek: '%s'."

#: app/flatpak-builtins-utils.c:846
#, c-format
msgid "Ambiguous column: %s"
msgstr "Belirsiz sütun: %s"

#: app/flatpak-builtins-utils.c:859
#, c-format
msgid "Unknown column: %s"
msgstr "Bilinmeyen sütun '%s'"

#: app/flatpak-builtins-utils.c:917
msgid "Available columns:\n"
msgstr "Kullanılabilir sütunlar:\n"

#: app/flatpak-builtins-utils.c:927
msgid "Show all columns"
msgstr "Tüm sütunları göster"

#: app/flatpak-builtins-utils.c:928
msgid "Show available columns"
msgstr "Kullanılabilir sütunları göster"

#: app/flatpak-builtins-utils.c:931
msgid "Append :s[tart], :m[iddle], :e[nd] or :f[ull] to change ellipsization"
msgstr ""
"Elipsleştirmeyi değiştirmek için :s[tart] (başlangıç), :m[iddle] "
"(orta), :e[nd] (son) ya da :f[ull] (tümü) ekleyin"

#: app/flatpak-builtins-utils.c:1483
#, c-format
msgid "Unknown scheme in sideload location %s"
msgstr "%s yan kurulum konumunda bilinmeyen şema"

#: app/flatpak-cli-transaction.c:96 app/flatpak-cli-transaction.c:102
#, c-format
msgid "Required runtime for %s (%s) found in remote %s\n"
msgstr "%s (%s) için gerekli çalışma zamanı %s uzağında bulundu\n"

#: app/flatpak-cli-transaction.c:104
msgid "Do you want to install it?"
msgstr "Kurmak istiyor musunuz?"

#: app/flatpak-cli-transaction.c:110
#, c-format
msgid "Required runtime for %s (%s) found in remotes:"
msgstr "%s (%s) için gerekli çalışma zamanı uzaklarda bulundu:"

#: app/flatpak-cli-transaction.c:112
msgid "Which do you want to install (0 to abort)?"
msgstr "Hangisini kurmak istiyorsunuz (vazgeçmek için 0)?"

#: app/flatpak-cli-transaction.c:132
#, c-format
msgid "Configuring %s as new remote '%s'\n"
msgstr "%s yeni uzak '%s' olarak yapılandırılıyor\n"

#. default to yes on Enter
#: app/flatpak-cli-transaction.c:139
#, c-format
msgid ""
"The remote '%s', referred to by '%s' at location %s contains additional "
"applications.\n"
"Should the remote be kept for future installations?"
msgstr ""
"'%2$s' tarafından, %3$s konumunda belirlenen uzak '%1$s' ek uygulamalar "
"içeriyor.\n"
"Uzak gelecek kurulumlar için saklanmalı mı?"

#. default to yes on Enter
#: app/flatpak-cli-transaction.c:147
#, c-format
msgid ""
"The application %s depends on runtimes from:\n"
"  %s\n"
"Configure this as new remote '%s'"
msgstr ""
"%s uygulaması şuradan çalışma zamanlarına bağımlı:\n"
"  %s\n"
"Bunu yeni uzak '%s' olarak yapılandır"

# s burada saniye kelimesinin kısaltması olarak kullanılmış. sn şeklinde de kullanmak mümkün.
#. Formatted size/remaining time in seconds
#: app/flatpak-cli-transaction.c:321
#, c-format
msgid "%s/s%s%s"
msgstr "%s/sn%s%s"

#. Download progress percentage, use the appropriate
#. percent format for your language
#: app/flatpak-cli-transaction.c:359
#, c-format
msgid "%3d%%"
msgstr "%%%3d"

#: app/flatpak-cli-transaction.c:414
msgid "Installing…"
msgstr "Kuruluyor…"

#: app/flatpak-cli-transaction.c:416
#, c-format
msgid "Installing %d/%d…"
msgstr "Kuruluyor %d/%d…"

#: app/flatpak-cli-transaction.c:421
msgid "Updating…"
msgstr "Güncelleniyor…"

#: app/flatpak-cli-transaction.c:423
#, c-format
msgid "Updating %d/%d…"
msgstr "Güncelleniyor %d/%d…"

#: app/flatpak-cli-transaction.c:428
msgid "Uninstalling…"
msgstr "Kaldırılıyor…"

#: app/flatpak-cli-transaction.c:430
#, c-format
msgid "Uninstalling %d/%d…"
msgstr "Kaldırılıyor %d/%d…"

#: app/flatpak-cli-transaction.c:496 app/flatpak-quiet-transaction.c:161
#, c-format
msgid "Info: %s was skipped"
msgstr "Bilgi: %s atlandı"

#: app/flatpak-cli-transaction.c:519
#, c-format
msgid "Warning: %s%s%s already installed"
msgstr "Uyarı: %s%s%s zaten kurulu"

#: app/flatpak-cli-transaction.c:522
#, c-format
msgid "Error: %s%s%s already installed"
msgstr "Hata: %s%s%s zaten kurulu"

#: app/flatpak-cli-transaction.c:528
#, c-format
msgid "Warning: %s%s%s not installed"
msgstr "Uyarı: %s%s%s kurulu değil"

#: app/flatpak-cli-transaction.c:531
#, c-format
msgid "Error: %s%s%s not installed"
msgstr "Hata: %s%s%s kurulu değil"

#: app/flatpak-cli-transaction.c:537
#, c-format
msgid "Warning: %s%s%s needs a later flatpak version"
msgstr "Uyarı: %s%s%s daha üst bir flatpak sürümünü gerektiriyor"

#: app/flatpak-cli-transaction.c:540
#, c-format
msgid "Error: %s%s%s needs a later flatpak version"
msgstr "Hata: %s%s%s daha üst bir flatpak sürümünü gerektiriyor"

#: app/flatpak-cli-transaction.c:546
msgid "Warning: Not enough disk space to complete this operation"
msgstr "Uyarı: Bu işlemi tamamlamak için yeterli disk alanı yok"

#: app/flatpak-cli-transaction.c:548
msgid "Error: Not enough disk space to complete this operation"
msgstr "Hata: Bu işlemi tamamlamak için yeterli disk alanı yok"

#: app/flatpak-cli-transaction.c:553
#, c-format
msgid "Warning: %s"
msgstr "Uyarı: %s"

#: app/flatpak-cli-transaction.c:555
#, c-format
msgid "Error: %s"
msgstr "Hata: %s"

# flatpak_ref_get_name, rebased_to_ref, error->message
#: app/flatpak-cli-transaction.c:570
#, c-format
msgid "Failed to install %s%s%s: "
msgstr "%s%s%s kurulamadı: "

#: app/flatpak-cli-transaction.c:577
#, c-format
msgid "Failed to update %s%s%s: "
msgstr "%s%s%s güncellenemedi: "

# flatpak_ref_get_name, rebased_to_ref, error->message
#: app/flatpak-cli-transaction.c:584
#, c-format
msgid "Failed to install bundle %s%s%s: "
msgstr "%s%s%s paketi kurulamadı: "

#: app/flatpak-cli-transaction.c:591
#, c-format
msgid "Failed to uninstall %s%s%s: "
msgstr "%s%s%s kaldırılamadı: "

#: app/flatpak-cli-transaction.c:642
#, c-format
msgid "Authentication required for remote '%s'\n"
msgstr "Uzak '%s' için kimlik doğrulaması gerekiyor\n"

#: app/flatpak-cli-transaction.c:643
msgid "Open browser?"
msgstr "Tarayıcı açılsın mı?"

#: app/flatpak-cli-transaction.c:699
#, c-format
msgid "Login required remote %s (realm %s)\n"
msgstr "Oturum açma gerekli uzak %s (erişim alanı %s)\n"

#: app/flatpak-cli-transaction.c:704
msgid "Password"
msgstr "Parola"

#. Only runtimes can be pinned
#: app/flatpak-cli-transaction.c:759
#, c-format
msgid ""
"\n"
"Info: (pinned) runtime %s%s%s branch %s%s%s is end-of-life, in favor of "
"%s%s%s branch %s%s%s\n"
msgstr ""
"\n"
"Bilgi: (ilişik) çalışma zamanı %s%s%s dal %s%s%s ömrünü doldurdu, %s%s%s dal "
"%s%s%s yararına\n"

#: app/flatpak-cli-transaction.c:765
#, c-format
msgid ""
"\n"
"Info: runtime %s%s%s branch %s%s%s is end-of-life, in favor of %s%s%s branch "
"%s%s%s\n"
msgstr ""
"\n"
"Bilgi: Çalışma zamanı %s%s%s dal %s%s%s ömrünü doldurdu, %s%s%s dal %s%s%s "
"yararına\n"

#: app/flatpak-cli-transaction.c:768
#, c-format
msgid ""
"\n"
"Info: app %s%s%s branch %s%s%s is end-of-life, in favor of %s%s%s branch "
"%s%s%s\n"
msgstr ""
"\n"
"Bilgi: Uygulama %s%s%s dal %s%s%s ömrünü doldurdu, %s%s%s dal %s%s%s "
"yararına\n"

#. Only runtimes can be pinned
#: app/flatpak-cli-transaction.c:780
#, c-format
msgid ""
"\n"
"Info: (pinned) runtime %s%s%s branch %s%s%s is end-of-life, with reason:\n"
msgstr ""
"\n"
"Bilgi: (ilişik) çalışma zamanı %s%s%s dal %s%s%s ömrünü doldurdu şu "
"nedenle:\n"

#: app/flatpak-cli-transaction.c:786
#, c-format
msgid ""
"\n"
"Info: runtime %s%s%s branch %s%s%s is end-of-life, with reason:\n"
msgstr ""
"\n"
"Bilgi: Çalışma zamanı %s%s%s dal %s%s%s ömrünü doldurdu, şu nedenle:\n"

#: app/flatpak-cli-transaction.c:789
#, c-format
msgid ""
"\n"
"Info: app %s%s%s branch %s%s%s is end-of-life, with reason:\n"
msgstr ""
"\n"
"Bilgi: Uygulama %s%s%s dal %s%s%s ömrünü doldurdu, şu nedenle:\n"

#: app/flatpak-cli-transaction.c:963
#, c-format
msgid "Info: applications using this extension:\n"
msgstr "Bilgi: Eklentiyi kullanan uygulamalar:\n"

#: app/flatpak-cli-transaction.c:965
#, c-format
msgid "Info: applications using this runtime:\n"
msgstr "Bilgi: Çalışma zamanını kullanan uygulamalar:\n"

#: app/flatpak-cli-transaction.c:984
msgid "Replace?"
msgstr "Değiştirilsin mi?"

#: app/flatpak-cli-transaction.c:987 app/flatpak-quiet-transaction.c:247
#, c-format
msgid "Updating to rebased version\n"
msgstr "Yeniden temellendirilmiş sürüme güncelleniyor\n"

#: app/flatpak-cli-transaction.c:1011
#, c-format
msgid "Failed to rebase %s to %s: "
msgstr "%s, %s referansına yeniden temellendirilemedi: "

#: app/flatpak-cli-transaction.c:1277
#, c-format
msgid "New %s%s%s permissions:"
msgstr "Yeni %s%s%s izinleri:"

#: app/flatpak-cli-transaction.c:1279
#, c-format
msgid "%s%s%s permissions:"
msgstr "%s%s%s izinleri:"

#: app/flatpak-cli-transaction.c:1343
msgid "Warning: "
msgstr "Uyarı: "

# Operation kelimesinin kısaltması.
#. translators: This is short for operation, the title of a one-char column
#: app/flatpak-cli-transaction.c:1442
msgid "Op"
msgstr "İş"

#. Avoid resizing the download column too much,
#. * by making the title as long as typical content
#.
#: app/flatpak-cli-transaction.c:1458 app/flatpak-cli-transaction.c:1503
msgid "partial"
msgstr "kısmi"

#: app/flatpak-cli-transaction.c:1535
msgid "Proceed with these changes to the user installation?"
msgstr "Kullanıcı kurulumunda bu değişikliklerle sürdürülsün mü?"

#: app/flatpak-cli-transaction.c:1537
msgid "Proceed with these changes to the system installation?"
msgstr "Sistem kurulumunda bu değişikliklerle sürdürülsün mü?"

#: app/flatpak-cli-transaction.c:1539
#, c-format
msgid "Proceed with these changes to the %s?"
msgstr "%s değişiklikleriyle sürdürülsün mü?"

#: app/flatpak-cli-transaction.c:1711
msgid "Changes complete."
msgstr "Değişiklikler tamamlandı."

#: app/flatpak-cli-transaction.c:1713
msgid "Uninstall complete."
msgstr "Kaldırma işlemi tamamlandı."

#: app/flatpak-cli-transaction.c:1715
msgid "Installation complete."
msgstr "Kurulum tamamlandı."

#: app/flatpak-cli-transaction.c:1717
msgid "Updates complete."
msgstr "Güncellemeler tamamlandı."

#. For updates/!stop_on_first_error we already printed all errors so we make up
#. a different one.
#: app/flatpak-cli-transaction.c:1750
msgid "There were one or more errors"
msgstr "Bir veya daha çok hata oluştu"

#. translators: please keep the leading space
#: app/flatpak-main.c:76
msgid " Manage installed applications and runtimes"
msgstr " Kurulu uygulamaları ve çalışma zamanlarını yönet"

#: app/flatpak-main.c:77
msgid "Install an application or runtime"
msgstr "Uygulama ya da çalışma zamanı kur"

#: app/flatpak-main.c:78
msgid "Update an installed application or runtime"
msgstr "Kurulu uygulama ya da çalışma zamanı güncelle"

#: app/flatpak-main.c:81
msgid "Uninstall an installed application or runtime"
msgstr "Kurulu uygulama ya da çalışma zamanı kaldır"

#: app/flatpak-main.c:84
msgid "Mask out updates and automatic installation"
msgstr "Güncellemeleri ve kendiliğinden kurulumu maskele"

#: app/flatpak-main.c:85
msgid "Pin a runtime to prevent automatic removal"
msgstr "Kendiliğinden kaldırmayı önlemek için çalışma zamanını sabitle"

#: app/flatpak-main.c:86
msgid "List installed apps and/or runtimes"
msgstr "Kurulu uygulamaları ve/veya çalışma zamanlarını listele"

#: app/flatpak-main.c:87
msgid "Show info for installed app or runtime"
msgstr "Kurulu uygulama ya da çalışma zamanı için bilgi göster"

#: app/flatpak-main.c:88
msgid "Show history"
msgstr "Geçmişi göster"

#: app/flatpak-main.c:89
msgid "Configure flatpak"
msgstr "Flatpak’i yapılandır"

#: app/flatpak-main.c:90
msgid "Repair flatpak installation"
msgstr "Flatpak kurulumunu onar"

#: app/flatpak-main.c:91
msgid "Put applications or runtimes onto removable media"
msgstr "Uygulamaları ya da çalışma zamanlarını çıkarılabilir ortama yerleştir"

#: app/flatpak-main.c:92
msgid "Install flatpaks that are part of the operating system"
msgstr "İşletim sisteminin bir parçası olan flatpakları kur"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:95
msgid ""
"\n"
" Find applications and runtimes"
msgstr ""
"\n"
"Uygulamalar ve çalışma zamanları bul"

#: app/flatpak-main.c:96
msgid "Search for remote apps/runtimes"
msgstr "Uzak uygulamaları/çalışma zamanlarını ara"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:99
msgid ""
"\n"
" Manage running applications"
msgstr ""
"\n"
" Çalışan uygulamaları yönet"

#: app/flatpak-main.c:100
msgid "Run an application"
msgstr "Uygulama çalıştır"

#: app/flatpak-main.c:101
msgid "Override permissions for an application"
msgstr "Uygulama için izinleri geçersiz kıl"

#: app/flatpak-main.c:102
msgid "Specify default version to run"
msgstr "Çalıştırılacak öntanımlı sürümü belirt"

#: app/flatpak-main.c:103
msgid "Enter the namespace of a running application"
msgstr "Çalışan bir uygulamanın ad alanına gir"

#: app/flatpak-main.c:104
msgid "Enumerate running applications"
msgstr "Çalışan uygulamaları numaralandır"

#: app/flatpak-main.c:105
msgid "Stop a running application"
msgstr "Çalışan uygulamayı durdur"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:108
msgid ""
"\n"
" Manage file access"
msgstr ""
"\n"
"Dosya erişimini yönet"

#: app/flatpak-main.c:109
msgid "List exported files"
msgstr "Dışa aktarılmış dosyaları listele"

#: app/flatpak-main.c:110
msgid "Grant an application access to a specific file"
msgstr "Uygulamaya belirli bir dosyaya erişim tanı"

#: app/flatpak-main.c:111
msgid "Revoke access to a specific file"
msgstr "Belirli bir dosyaya erişimi geri çek"

#: app/flatpak-main.c:112
msgid "Show information about a specific file"
msgstr "Belirli bir dosyayla ilgili bilgi göster"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:116
msgid ""
"\n"
" Manage dynamic permissions"
msgstr ""
"\n"
"Dinamik izinleri yönet"

#: app/flatpak-main.c:117
msgid "List permissions"
msgstr "İzinleri listele"

#: app/flatpak-main.c:118
msgid "Remove item from permission store"
msgstr "Ögeyi izin deposundan kaldır"

#: app/flatpak-main.c:120
msgid "Set permissions"
msgstr "İzinleri belirle"

#: app/flatpak-main.c:121
msgid "Show app permissions"
msgstr "Uygulama izinlerini göster"

#: app/flatpak-main.c:122
msgid "Reset app permissions"
msgstr "Uygulama izinlerini sıfırla"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:125
msgid ""
"\n"
" Manage remote repositories"
msgstr ""
"\n"
" Uzak depoları yönet"

#: app/flatpak-main.c:126
msgid "List all configured remotes"
msgstr "Tüm yapılandırılmış uzakları listele"

#: app/flatpak-main.c:127
msgid "Add a new remote repository (by URL)"
msgstr "Yeni uzak depo ekle (URL’yle)"

#: app/flatpak-main.c:128
msgid "Modify properties of a configured remote"
msgstr "Yapılandırılmış uzağın özelliklerini düzenle"

#: app/flatpak-main.c:129
msgid "Delete a configured remote"
msgstr "Yapılandırılmış uzağı sil"

#: app/flatpak-main.c:131
msgid "List contents of a configured remote"
msgstr "Yapılandırılmış uzağın içeriklerini listele"

#: app/flatpak-main.c:132
msgid "Show information about a remote app or runtime"
msgstr "Uzak uygulama veya çalışma zamanıyla ilgili bilgi göster"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:135
msgid ""
"\n"
" Build applications"
msgstr ""
"\n"
" Uygulamaları inşa et"

#: app/flatpak-main.c:136
msgid "Initialize a directory for building"
msgstr "İnşa için bir dizini ilklendir"

#: app/flatpak-main.c:137
msgid "Run a build command inside the build dir"
msgstr "İnşa dizininde inşa komutu çalıştır"

#: app/flatpak-main.c:138
msgid "Finish a build dir for export"
msgstr "İnşa dizinini dışa aktarma için bitir"

#: app/flatpak-main.c:139
msgid "Export a build dir to a repository"
msgstr "İnşa dizinini depoya dışa aktar"

#: app/flatpak-main.c:140
msgid "Create a bundle file from a ref in a local repository"
msgstr "Yerel depodaki referanstan paket dosyası oluştur"

#: app/flatpak-main.c:141
msgid "Import a bundle file"
msgstr "Paket dosyasını içe aktar"

#: app/flatpak-main.c:142
msgid "Sign an application or runtime"
msgstr "Uygulamayı veya çalışma zamanını imzala"

#: app/flatpak-main.c:143
msgid "Update the summary file in a repository"
msgstr "Depodaki özet dosyasını güncelle"

#: app/flatpak-main.c:144
msgid "Create new commit based on existing ref"
msgstr "Var olan referansa dayalı yeni işleme oluştur"

#: app/flatpak-main.c:145
msgid "Show information about a repo"
msgstr "Depoyla ilgili bilgi göster"

#: app/flatpak-main.c:162
msgid "Show debug information, -vv for more detail"
msgstr "Hata ayıklama bilgisini göster, daha çok bilgi için -vv yaz"

#: app/flatpak-main.c:163
msgid "Show OSTree debug information"
msgstr "OSTree hata ayıklama bilgisini göster"

#: app/flatpak-main.c:169
msgid "Print version information and exit"
msgstr "Sürüm bilgisini yazdır ve çık"

#: app/flatpak-main.c:170
msgid "Print default arch and exit"
msgstr "Öntanımlı mimariyi yazdır ve çık"

#: app/flatpak-main.c:171
msgid "Print supported arches and exit"
msgstr "Desteklenen mimarileri yazdır ve çık"

#: app/flatpak-main.c:172
msgid "Print active gl drivers and exit"
msgstr "Etkin gl sürücülerini yazdır ve çık"

#: app/flatpak-main.c:173
msgid "Print paths for system installations and exit"
msgstr "Sistem kurulumlarının yollarını yazdır ve çık"

#: app/flatpak-main.c:174
msgid "Print the updated environment needed to run flatpaks"
msgstr "Flatpakleri çalıştırmak için gereken güncellenmiş ortamı yazdır"

#: app/flatpak-main.c:175
msgid "Only include the system installation with --print-updated-env"
msgstr "Yalnızca --print-updated-env ile sistem kurulumunu içer"

#: app/flatpak-main.c:180
msgid "Work on the user installation"
msgstr "Kullanıcı kurulumu üzerinde çalış"

#: app/flatpak-main.c:181
msgid "Work on the system-wide installation (default)"
msgstr "Sistem geneli kurulum üzerinde çalış (öntanımlı)"

#: app/flatpak-main.c:182
msgid "Work on a non-default system-wide installation"
msgstr "Sistem genelinde öntanımlı olmayan kurulum üzerinde çalış"

#: app/flatpak-main.c:212
msgid "Builtin Commands:"
msgstr "Yerleşik Komutlar:"

#: app/flatpak-main.c:298
#, c-format
msgid ""
"Note that the directories %s are not in the search path set by the "
"XDG_DATA_DIRS environment variable, so applications installed by Flatpak may "
"not appear on your desktop until the session is restarted."
msgstr ""
"%s dizinleri XDG_DATA_DIRS ortam değişkenince ayarlanan arama yolunda "
"olmadığından, Flatpak tarafından kurulan uygulamalar, oturum yeniden "
"başlatılana dek masa üstünüzde görünmeyebilir."

#: app/flatpak-main.c:312
#, c-format
msgid ""
"Note that the directory %s is not in the search path set by the "
"XDG_DATA_DIRS environment variable, so applications installed by Flatpak may "
"not appear on your desktop until the session is restarted."
msgstr ""
"%s dizini XDG_DATA_DIRS ortam değişkenince ayarlanan arama yolunda "
"olmadığından, Flatpak tarafından kurulan uygulamalar, oturum yeniden "
"başlatılana dek masa üstünüzde görünmeyebilir."

#: app/flatpak-main.c:381
msgid ""
"Refusing to operate under sudo with --user. Omit sudo to operate on the user "
"installation, or use a root shell to operate on the root user's installation."
msgstr ""
"sudo altında --user ile çalışma reddediliyor. Kullanıcı kurulumunda işlem "
"yapmak için ya sudo’yu atlayın ya da kök kullanıcının kurulumunda işlem "
"yapmak için kök kabuk kullanın."

#: app/flatpak-main.c:453
msgid ""
"Multiple installations specified for a command that works on one installation"
msgstr "Bir kurulumda çalışan komut için birden çok kurulum belirtildi"

#: app/flatpak-main.c:504 app/flatpak-main.c:697
#, c-format
msgid "See '%s --help'"
msgstr "Bakınız '%s --help'"

#: app/flatpak-main.c:706
#, c-format
msgid "'%s' is not a flatpak command. Did you mean '%s%s'?"
msgstr "'%s' flatpak komutu değil '%s%s' mi demek istediniz?"

#: app/flatpak-main.c:709
#, c-format
msgid "'%s' is not a flatpak command"
msgstr "'%s' flatpak komutu değil"

#: app/flatpak-main.c:824
msgid "No command specified"
msgstr "Komut belirtilmemiş"

#: app/flatpak-main.c:980
msgid "error:"
msgstr "hata:"

#: app/flatpak-quiet-transaction.c:77
#, c-format
msgid "Installing %s\n"
msgstr "Kuruluyor %s\n"

#: app/flatpak-quiet-transaction.c:81
#, c-format
msgid "Updating %s\n"
msgstr "Güncelleniyor %s\n"

#: app/flatpak-quiet-transaction.c:85
#, c-format
msgid "Uninstalling %s\n"
msgstr "Kaldırılıyor %s\n"

#: app/flatpak-quiet-transaction.c:107
#, c-format
msgid "Warning: Failed to install %s: %s\n"
msgstr "Uyarı: %s kurulamadı: %s\n"

#: app/flatpak-quiet-transaction.c:110
#, c-format
msgid "Error: Failed to install %s: %s\n"
msgstr "Hata: %s kurulamadı: %s\n"

#: app/flatpak-quiet-transaction.c:116
#, c-format
msgid "Warning: Failed to update %s: %s\n"
msgstr "Uyarı: %s güncellenemedi: %s\n"

#: app/flatpak-quiet-transaction.c:119
#, c-format
msgid "Error: Failed to update %s: %s\n"
msgstr "Hata: %s güncellenemedi: %s\n"

#: app/flatpak-quiet-transaction.c:125
#, c-format
msgid "Warning: Failed to install bundle %s: %s\n"
msgstr "Uyarı: %s paketi kaldırılamadı: %s\n"

#: app/flatpak-quiet-transaction.c:128
#, c-format
msgid "Error: Failed to install bundle %s: %s\n"
msgstr "Hata: %s paketi kurulamadı: %s\n"

#: app/flatpak-quiet-transaction.c:134
#, c-format
msgid "Warning: Failed to uninstall %s: %s\n"
msgstr "Uyarı: %s kaldırılamadı: %s\n"

#: app/flatpak-quiet-transaction.c:137
#, c-format
msgid "Error: Failed to uninstall %s: %s\n"
msgstr "Hata: %s kaldırılamadı: %s\n"

#: app/flatpak-quiet-transaction.c:166 common/flatpak-dir.c:11475
#, c-format
msgid "%s already installed"
msgstr "%s zaten kurulu"

#: app/flatpak-quiet-transaction.c:168 common/flatpak-dir.c:3622
#: common/flatpak-dir.c:4321 common/flatpak-dir.c:16968
#: common/flatpak-dir.c:17258 common/flatpak-dir-utils.c:166
#: common/flatpak-dir-utils.c:259 common/flatpak-transaction.c:2736
#: common/flatpak-transaction.c:2791
#, c-format
msgid "%s not installed"
msgstr "%s kurulu değil"

#: app/flatpak-quiet-transaction.c:170
#, c-format
msgid "%s needs a later flatpak version"
msgstr "%s daha üst bir flatpak sürümünü gerektiriyor"

#: app/flatpak-quiet-transaction.c:172
msgid "Not enough disk space to complete this operation"
msgstr "Bu işlemi tamamlamak için yeterli disk alanı yok"

#: app/flatpak-quiet-transaction.c:239
#, c-format
msgid "Info: %s is end-of-life, in favor of %s\n"
msgstr "Bilgi: %s ömrünü doldurdu, %s yararına\n"

#: app/flatpak-quiet-transaction.c:241
#, c-format
msgid "Info: %s is end-of-life, with reason: %s\n"
msgstr "Bilgi: %s ömrünü doldurdu, şu nedenle: %s\n"

#: app/flatpak-quiet-transaction.c:251
#, c-format
msgid "Failed to rebase %s to %s: %s\n"
msgstr "%s, %s referansına yeniden temellendirilemedi: %s\n"

#: common/flatpak-auth.c:58
#, c-format
msgid "No authenticator configured for remote `%s`"
msgstr "Uzak `%s` için kimlik doğrulayıcı yapılandırılmadı"

#: common/flatpak-context.c:637 common/flatpak-context.c:649
#, c-format
msgid "Invalid permission syntax: %s"
msgstr "Geçersiz izin söz dizimi: %s"

#: common/flatpak-context.c:1207
#, c-format
msgid "Unknown share type %s, valid types are: %s"
msgstr "Bilinmeyen paylaşım türü %s, geçerli türler: %s"

#: common/flatpak-context.c:1228
#, c-format
msgid "Unknown policy type %s, valid types are: %s"
msgstr "Bilinmeyen ilke türü %s, geçerli türler: %s"

#: common/flatpak-context.c:1266
#, c-format
msgid "Invalid dbus name %s"
msgstr "Geçersiz dbus adı %s"

#: common/flatpak-context.c:1279
#, c-format
msgid "Unknown socket type %s, valid types are: %s"
msgstr "Bilinmeyen yuva türü %s, geçerli türler: %s"

#: common/flatpak-context.c:1294
#, c-format
msgid "Unknown device type %s, valid types are: %s"
msgstr "Bilinmeyen aygıt türü %s, geçerli türler: %s"

#: common/flatpak-context.c:1308
#, c-format
msgid "Unknown feature type %s, valid types are: %s"
msgstr "Bilinmeyen özellik türü %s, geçerli türler: %s"

#: common/flatpak-context.c:1840
#, c-format
msgid "Filesystem location \"%s\" contains \"..\""
msgstr "Dosya sistemi konumu \"%s\", \"..\" içeriyor"

#: common/flatpak-context.c:1882
#, c-format
msgid ""
"--filesystem=/ is not available, use --filesystem=host for a similar result"
msgstr ""
"--filesystem=/ kullanılabilir değil, benzer sonuç için --filesystem=host "
"kullan"

# Cümlenin sonundaki kısım çevrilebilir konumlar değil.
#: common/flatpak-context.c:1916
#, c-format
msgid ""
"Unknown filesystem location %s, valid locations are: host, host-os, host-"
"etc, host-root, home, xdg-*[/…], ~/dir, /dir"
msgstr ""
"Bilinmeyen dosya sistemi konumu %s, geçerli konumlar: host, host-os, host-"
"etc, host-root, home, xdg-*[/…], ~/dir, /dir"

#: common/flatpak-context.c:2015
#, c-format
msgid "Invalid syntax for %s: %s"
msgstr "%s için geçersiz söz dizimi: %s"

#: common/flatpak-context.c:2142
#, c-format
msgid "fallback-x11 can not be conditional"
msgstr "fallback-x11 koşullu olamaz"

#: common/flatpak-context.c:2318
#, c-format
msgid "Invalid env format %s"
msgstr "Geçersiz env biçimi %s"

#: common/flatpak-context.c:2399
#, c-format
msgid "Environment variable name must not contain '=': %s"
msgstr "Ortam değişkeni adı '=' içeremez: %s"

#: common/flatpak-context.c:2527 common/flatpak-context.c:2535
#, c-format
msgid "--add-policy arguments must be in the form SUBSYSTEM.KEY=VALUE"
msgstr "--add-policy argümanları ALTSİSTEM.ANAHTAR=DEĞER biçiminde olmalıdır"

#: common/flatpak-context.c:2542
#, c-format
msgid "--add-policy values can't start with \"!\""
msgstr "--add-policy değerleri \"!\" ile başlayamaz"

#: common/flatpak-context.c:2567 common/flatpak-context.c:2575
#, c-format
msgid "--remove-policy arguments must be in the form SUBSYSTEM.KEY=VALUE"
msgstr ""
"--remove-policy argümanları ALTSİSTEM.ANAHTAR=DEĞER biçiminde olmalıdır"

#: common/flatpak-context.c:2582
#, c-format
msgid "--remove-policy values can't start with \"!\""
msgstr "--remove-policy değerleri \"!\" ile başlayamaz"

#: common/flatpak-context.c:2657
msgid "Share with host"
msgstr "Makineyle paylaş"

#: common/flatpak-context.c:2657 common/flatpak-context.c:2658
msgid "SHARE"
msgstr "PAYLAŞ"

#: common/flatpak-context.c:2658
msgid "Unshare with host"
msgstr "Makineyle paylaşma"

#: common/flatpak-context.c:2659
msgid "Require conditions to be met for a subsystem to get shared"
msgstr "Alt sistemin paylaşılması için koşulların karşılanmasını gerektir"

#: common/flatpak-context.c:2659
msgid "SHARE:CONDITION"
msgstr "PAYLAŞ:KOŞUL"

#: common/flatpak-context.c:2660
msgid "Expose socket to app"
msgstr "Yuvayı uygulamaya göster"

#: common/flatpak-context.c:2660 common/flatpak-context.c:2661
msgid "SOCKET"
msgstr "YUVA"

#: common/flatpak-context.c:2661
msgid "Don't expose socket to app"
msgstr "Yuvayı uygulamaya gösterme"

#: common/flatpak-context.c:2662
msgid "Require conditions to be met for a socket to get exposed"
msgstr "Yuvanın gösterilmesi için koşulların karşılanmasını gerektir"

#: common/flatpak-context.c:2662
msgid "SOCKET:CONDITION"
msgstr "YUVA:KOŞUL"

#: common/flatpak-context.c:2663
msgid "Expose device to app"
msgstr "Aygıtı uygulamaya göster"

#: common/flatpak-context.c:2663 common/flatpak-context.c:2664
msgid "DEVICE"
msgstr "AYGIT"

#: common/flatpak-context.c:2664
msgid "Don't expose device to app"
msgstr "Aygıtı uygulamaya gösterme"

#: common/flatpak-context.c:2665
msgid "Require conditions to be met for a device to get exposed"
msgstr "Aygıtın gösterilmesi için gerekli koşulların karşılanmasını gerektir"

#: common/flatpak-context.c:2665
msgid "DEVICE:CONDITION"
msgstr "AYGIT:KOŞUL"

#: common/flatpak-context.c:2666
msgid "Allow feature"
msgstr "Özelliğe izin ver"

#: common/flatpak-context.c:2666 common/flatpak-context.c:2667
msgid "FEATURE"
msgstr "ÖZELLİK"

#: common/flatpak-context.c:2667
msgid "Don't allow feature"
msgstr "Özelliğe izin verme"

#: common/flatpak-context.c:2668
msgid "Require conditions to be met for a feature to get allowed"
msgstr ""
"Özelliğe izin verilmesi için gerekli koşulların karşılanmasını gerektir"

#: common/flatpak-context.c:2668
msgid "FEATURE:CONDITION"
msgstr "ÖZELLİK:KOŞUL"

#: common/flatpak-context.c:2669
msgid "Expose filesystem to app (:ro for read-only)"
msgstr "Dosya sistemini uygulamaya göster (salt okuma için :ro)"

#: common/flatpak-context.c:2669
msgid "FILESYSTEM[:ro]"
msgstr "DOSYASİSTEMİ[:ro]"

#: common/flatpak-context.c:2670
msgid "Don't expose filesystem to app"
msgstr "Dosya sistemini uygulamaya gösterme"

#: common/flatpak-context.c:2670
msgid "FILESYSTEM"
msgstr "DOSYASİSTEMİ"

#: common/flatpak-context.c:2671
msgid "Set environment variable"
msgstr "Ortam değişkeni belirle"

#: common/flatpak-context.c:2671
msgid "VAR=VALUE"
msgstr "DEĞİŞKEN=DEĞER"

#: common/flatpak-context.c:2672
msgid "Read environment variables in env -0 format from FD"
msgstr "DT’den ortam değişkenlerini env -0 biçiminde oku"

#: common/flatpak-context.c:2673
msgid "Remove variable from environment"
msgstr "Değişkeni ortamdan kaldır"

#: common/flatpak-context.c:2673
msgid "VAR"
msgstr "DEĞİŞKEN"

#: common/flatpak-context.c:2674
msgid "Allow app to own name on the session bus"
msgstr "Uygulamanın oturum veri yolunda kendi adı olmasına izin ver"

#: common/flatpak-context.c:2674 common/flatpak-context.c:2675
#: common/flatpak-context.c:2676 common/flatpak-context.c:2677
#: common/flatpak-context.c:2678 common/flatpak-context.c:2679
#: common/flatpak-context.c:2680
msgid "DBUS_NAME"
msgstr "DBUS_ADI"

#: common/flatpak-context.c:2675
msgid "Allow app to talk to name on the session bus"
msgstr "Uygulamanın oturum veri yolunda adla konuşmasına izin ver"

#: common/flatpak-context.c:2676
msgid "Don't allow app to talk to name on the session bus"
msgstr "Uygulamanın oturum veri yolunda adla konuşmasına izin verme"

#: common/flatpak-context.c:2677
msgid "Allow app to own name on the system bus"
msgstr "Uygulamanın sistem veri yolunda kendi adı olmasına izin ver"

#: common/flatpak-context.c:2678
msgid "Allow app to talk to name on the system bus"
msgstr "Uygulamanın sistem veri yolunda adla konuşmasına izin ver"

#: common/flatpak-context.c:2679
msgid "Don't allow app to talk to name on the system bus"
msgstr "Uygulamanın sistem veri yolunda adla konuşmasına izin verme"

#: common/flatpak-context.c:2680
msgid "Allow app to own name on the a11y bus"
msgstr "Uygulamanın a11y veri yolunda kendi adına izin ver"

#: common/flatpak-context.c:2681
msgid "Add generic policy option"
msgstr "Genel ilke seçeneği ekle"

#: common/flatpak-context.c:2681 common/flatpak-context.c:2682
msgid "SUBSYSTEM.KEY=VALUE"
msgstr "ALTSİSTEM.ANAHTAR=DEĞER"

#: common/flatpak-context.c:2682
msgid "Remove generic policy option"
msgstr "Genel ilke seçeneğini kaldır"

#: common/flatpak-context.c:2683
msgid "Add USB device to enumerables"
msgstr "USB aygıtını numaralandırılabilirlere ekle"

#: common/flatpak-context.c:2683 common/flatpak-context.c:2684
msgid "VENDOR_ID:PRODUCT_ID"
msgstr "ÜRETİCİ_KİMLİĞİ:ÜRÜN_KİMLİĞİ"

#: common/flatpak-context.c:2684
msgid "Add USB device to hidden list"
msgstr "USB aygıtını gizli listeye ekle"

#: common/flatpak-context.c:2685
msgid "A list of USB devices that are enumerable"
msgstr "Numaralandırılabilir USB aygıtlarının listesi"

#: common/flatpak-context.c:2685
msgid "LIST"
msgstr "LİSTE"

#: common/flatpak-context.c:2686
msgid "File containing a list of USB devices to make enumerable"
msgstr ""
"Numaralandırılabilir hale getirilecek USB aygıtlarının listesini içeren dosya"

#: common/flatpak-context.c:2686 common/flatpak-context.c:2687
msgid "FILENAME"
msgstr "DOSYAADI"

#: common/flatpak-context.c:2687
msgid "Persist home directory subpath"
msgstr "Ev dizinini alt yolunu koru"

#. This is not needed/used anymore, so hidden, but we accept it for backwards compat
#: common/flatpak-context.c:2689
msgid "Don't require a running session (no cgroups creation)"
msgstr "Çalışan oturum gerektirme (cgroups yaratımı yok)"

#: common/flatpak-context.c:3718
#, c-format
msgid "Not replacing \"%s\" with tmpfs: %s"
msgstr "\"%s\" yolu tmpfs ile değiştirilmiyor: %s"

#: common/flatpak-context.c:3726
#, c-format
msgid "Not sharing \"%s\" with sandbox: %s"
msgstr "\"%s\" yolu yalıtılmış alan ile paylaşılmıyor: %s"

#. Even if the error is one that we would normally silence, like
#. * the path not existing, it seems reasonable to make more of a fuss
#. * about the home directory not existing or otherwise being unusable,
#. * so this is intentionally not using cannot_export()
#: common/flatpak-context.c:3828
#, c-format
msgid "Not allowing home directory access: %s"
msgstr "Ev dizini erişimine izin verilmiyor: %s"

#: common/flatpak-context.c:4062
#, c-format
msgid "Unable to provide a temporary home directory in the sandbox: %s"
msgstr "Yalıtılmış alanda geçici ev dizini sağlanamadı: %s"

#: common/flatpak-dir.c:442
#, c-format
msgid "Configured collection ID ‘%s’ not in summary file"
msgstr "Yapılandırılmış koleksiyon kimliği ‘%s’ özet dosyasında değil"

#: common/flatpak-dir.c:587
#, c-format
msgid "Unable to load summary from remote %s: %s"
msgstr "%s uzağından özet yüklenemedi: %s"

#: common/flatpak-dir.c:764 common/flatpak-dir.c:800 common/flatpak-dir.c:906
#, c-format
msgid "No such ref '%s' in remote %s"
msgstr "Uzak %2$s içinde '%1$s' referansı bulunamadı"

#: common/flatpak-dir.c:891 common/flatpak-dir.c:1051 common/flatpak-dir.c:1080
#: common/flatpak-dir.c:1092
#, c-format
msgid "No entry for %s in remote %s summary flatpak cache"
msgstr "Uzak %2$s özet flatpak önbelleğinde %1$s için girdi yok"

#: common/flatpak-dir.c:1069
#, c-format
msgid "No summary or Flatpak cache available for remote %s"
msgstr "%s uzağı için, Flatpak önbellek özeti yok"

#: common/flatpak-dir.c:1097
#, c-format
msgid "Missing xa.data in summary for remote %s"
msgstr "Uzak %s için özette xa.data eksik"

#: common/flatpak-dir.c:1103 common/flatpak-dir.c:1546
#, c-format
msgid "Unsupported summary version %d for remote %s"
msgstr "Uzak %2$s için desteklenmeyen özet sürümü %1$d"

#: common/flatpak-dir.c:1200
msgid "Remote OCI index has no registry uri"
msgstr "Uzak OCI indeksinde sicil uri’si yok"

#: common/flatpak-dir.c:1261
#, c-format
msgid "Couldn't find ref %s in remote %s"
msgstr "%s referansı %s uzağında bulunamadı"

#: common/flatpak-dir.c:1288 common/flatpak-dir.c:1381
#, fuzzy, c-format
msgid "Commit has no requested ref ‘%s’ in ref binding metadata (found: ‘%s’)"
msgstr "İşlemede, referans bağlama üst verilerinde istenen ‘%s’ referansı yok"

#: common/flatpak-dir.c:1413
#, c-format
msgid "Configured collection ID ‘%s’ not in binding metadata"
msgstr "Yapılandırılmış koleksiyon kimliği ‘%s’ bağlayıcı üst verilerde değil"

#: common/flatpak-dir.c:1449 common/flatpak-dir.c:5645
#, c-format
msgid "Couldn't find latest checksum for ref %s in remote %s"
msgstr "%2$s uzaklığında %1$s referansı için en son sağlama toplamı bulunamadı"

#: common/flatpak-dir.c:1516 common/flatpak-dir.c:1552
#, c-format
msgid "No entry for %s in remote %s summary flatpak sparse cache"
msgstr "Uzak '%2$s' özet flatpak seyrek önbelleğinde %1$s için girdi yok"

#: common/flatpak-dir.c:2540
#, c-format
msgid "Commit metadata for %s not matching expected metadata"
msgstr "%s işleme üst verisi beklenen üst verilerle eşleşmiyor"

#: common/flatpak-dir.c:2823
msgid "Unable to connect to system bus"
msgstr "Sistem veri yolunda bağlanamadı"

#: common/flatpak-dir.c:3419
msgid "User installation"
msgstr "Kullanıcı kurulumu"

#: common/flatpak-dir.c:3426
#, c-format
msgid "System (%s) installation"
msgstr "Sistem (%s) kurulumu"

#: common/flatpak-dir.c:3472
#, c-format
msgid "No overrides found for %s"
msgstr "%s için geçersiz kılma bulunamadı"

#: common/flatpak-dir.c:3625
#, c-format
msgid "%s (commit %s) not installed"
msgstr "%s (%s işlemesi) kurulu değil"

#: common/flatpak-dir.c:4650
#, c-format
msgid "Error parsing system flatpakrepo file for %s: %s"
msgstr "%s flatpakrepo dosyası ayrıştırılırken hata: %s"

#: common/flatpak-dir.c:4735
#, c-format
msgid "While opening repository %s: "
msgstr "%s deposu açılırken: "

#: common/flatpak-dir.c:5004
#, c-format
msgid "The config key %s is not set"
msgstr "Ayar anahtarı %s ayarlanmadı"

# key, pattern
#: common/flatpak-dir.c:5140
#, c-format
msgid "No current %s pattern matching %s"
msgstr "%2$s örüntüsüyle eşleyen %1$s yok"

#: common/flatpak-dir.c:5422
msgid "No appstream commit to deploy"
msgstr "Dağıtılacak appstream işlemesi yok"

#: common/flatpak-dir.c:5941 common/flatpak-dir.c:7266
#: common/flatpak-dir.c:10881 common/flatpak-dir.c:11618
msgid "Can't pull from untrusted non-gpg verified remote"
msgstr "Güvenilmeyen gpg olmayan doğrulanmış uzaktan çekilemez"

#: common/flatpak-dir.c:6376 common/flatpak-dir.c:6591
msgid "Extra data not supported for non-gpg-verified local system installs"
msgstr "non-gpg-verified yerel sistem kurulumları için ek veri desteklenmez"

# for edatı görmezden gelindi
#: common/flatpak-dir.c:6415 common/flatpak-dir.c:6782
#, c-format
msgid "Invalid checksum for extra data uri %s"
msgstr "Ek veri uri %s için sağlama toplamı geçersiz"

#: common/flatpak-dir.c:6424
#, c-format
msgid "Empty name for extra data uri %s"
msgstr "Ek veri uri’si %s için boş ad"

#: common/flatpak-dir.c:6432
#, c-format
msgid "Unsupported extra data uri %s"
msgstr "Desteklenmeyen ek veri uri’si %s"

#: common/flatpak-dir.c:6461
#, c-format
msgid "Failed to load local extra-data %s: %s"
msgstr "Yerel ek veri %s yüklenemedi: %s"

#: common/flatpak-dir.c:6469
#, c-format
msgid "Wrong size for extra-data %s"
msgstr "Ek veri %s için yanlış boyut"

#: common/flatpak-dir.c:6488
#, c-format
msgid "While downloading %s: "
msgstr "%s indirilirken: "

#: common/flatpak-dir.c:6498
#, c-format
msgid "Wrong size for extra data %s"
msgstr "Ek veri %s için yanlış boyut"

# for edatı görmezden gelindi
#: common/flatpak-dir.c:6507
#, c-format
msgid "Invalid checksum for extra data %s"
msgstr "Ek veri %s için sağlama toplamı geçersiz"

#: common/flatpak-dir.c:7096 common/flatpak-dir.c:7349
#, c-format
msgid "While pulling %s from remote %s: "
msgstr "%2$s uzağından %1$s çekerken: "

#: common/flatpak-dir.c:7290 common/flatpak-repo-utils.c:3886
msgid "GPG signatures found, but none are in trusted keyring"
msgstr "GPG imzaları bulundu, ancak hiçbiri güvenilir anahtarlıkta yok"

#: common/flatpak-dir.c:7307
#, c-format
msgid "Commit for ‘%s’ has no ref binding"
msgstr "‘%s’ için işleme referans bağlaması yok"

#: common/flatpak-dir.c:7312
#, c-format
msgid "Commit for ‘%s’ is not in expected bound refs: %s"
msgstr "‘%s’ için işleme, beklenen sınır referanslarında değil: %s"

#: common/flatpak-dir.c:7488
msgid "Only applications can be made current"
msgstr "Yalnızca uygulamalar geçerli yapılabilir"

#: common/flatpak-dir.c:8192
msgid "Not enough memory"
msgstr "Yeterli bellek yok"

#: common/flatpak-dir.c:8211
msgid "Failed to read from exported file"
msgstr "Dışa aktarılan dosyadan okunamadı"

#: common/flatpak-dir.c:8401
msgid "Error reading mimetype xml file"
msgstr "Mimetürü xml dosyası okunurken hata"

#: common/flatpak-dir.c:8406
msgid "Invalid mimetype xml file"
msgstr "Geçersiz mimetürü xml dosyası"

#: common/flatpak-dir.c:8492
#, c-format
msgid "D-Bus service file '%s' has wrong name"
msgstr "D-Bus hizmet dosyası '%s' adı yanlış"

#: common/flatpak-dir.c:8647
#, c-format
msgid "Invalid Exec argument %s"
msgstr "Geçersiz Exec argümanı %s"

#: common/flatpak-dir.c:9115
msgid "While getting detached metadata: "
msgstr "Ayrık üst veri alınırken: "

#: common/flatpak-dir.c:9120 common/flatpak-dir.c:9125
#: common/flatpak-dir.c:9129
msgid "Extra data missing in detached metadata"
msgstr "Ayrılmış üst veride ek veriler eksik"

#: common/flatpak-dir.c:9133
msgid "While creating extradir: "
msgstr "Ek dizin oluşturulurken: "

# for edatı görmezden gelindi
#: common/flatpak-dir.c:9154 common/flatpak-dir.c:9187
msgid "Invalid checksum for extra data"
msgstr "Ek veri sağlama toplamı geçersiz"

#: common/flatpak-dir.c:9183
msgid "Wrong size for extra data"
msgstr "Ek veri için yanlış boyut"

#: common/flatpak-dir.c:9196
#, c-format
msgid "While writing extra data file '%s': "
msgstr "Ek veri dosyası '%s' yazılırken: "

#: common/flatpak-dir.c:9204
#, c-format
msgid "Extra data %s missing in detached metadata"
msgstr "%s ek verisi ayrılmış üst verilerde eksik"

#: common/flatpak-dir.c:9278
#, c-format
msgid "Unable to get runtime key from metadata"
msgstr "Üst verilerden çalışma zamanı anahtarı alınamadı"

#: common/flatpak-dir.c:9402
#, c-format
msgid "apply_extra script failed, exit status %d"
msgstr "apply_extra betiği başarısız oldu, çıkış durumu %d"

#. Translators: The placeholder is for an app ref.
#: common/flatpak-dir.c:9591
#, c-format
msgid "Installing %s is not allowed by the policy set by your administrator"
msgstr "%s kurulumuna yöneticinizce ayarlanan ilke nedeniyle izin verilmiyor"

#: common/flatpak-dir.c:9690
#, c-format
msgid "While trying to resolve ref %s: "
msgstr "Referans %s çözülmeye çalışılırken: "

#: common/flatpak-dir.c:9702
#, c-format
msgid "%s is not available"
msgstr "%s kullanılabilir değil"

#: common/flatpak-dir.c:9714 common/flatpak-dir.c:11495
#, c-format
msgid "%s commit %s already installed"
msgstr "%s işleme %s zaten kurulu"

#: common/flatpak-dir.c:9721
msgid "Can't create deploy directory"
msgstr "Dağıtım dizini oluşturulamadı"

#: common/flatpak-dir.c:9729
#, c-format
msgid "Failed to read commit %s: "
msgstr "%s işlemesi okunamadı: "

#: common/flatpak-dir.c:9750
#, c-format
msgid "While trying to checkout %s into %s: "
msgstr "%s’i %s’e geçirmeye çalışırken: "

#: common/flatpak-dir.c:9769
msgid "While trying to checkout metadata subpath: "
msgstr "Üst veri alt dizini geçirilmeye çalışılırken: "

#: common/flatpak-dir.c:9801
#, c-format
msgid "While trying to checkout subpath ‘%s’: "
msgstr "‘%s’ alt yolu geçirilmeye çalışılırken: "

#: common/flatpak-dir.c:9811
msgid "While trying to remove existing extra dir: "
msgstr "Var olan ek dizini kaldırmaya çalışırken: "

#: common/flatpak-dir.c:9822
msgid "While trying to apply extra data: "
msgstr "Ek veriyi uygulamaya çalışırken: "

#: common/flatpak-dir.c:9849
#, c-format
msgid "Invalid commit ref %s: "
msgstr "Geçersiz işleme referansı %s: "

#: common/flatpak-dir.c:9857 common/flatpak-dir.c:9869
#, c-format
msgid "Deployed ref %s does not match commit (%s)"
msgstr "Dağıtılan referans %s işlemesiyle eşleşmiyor (%s)"

#: common/flatpak-dir.c:9863
#, c-format
msgid "Deployed ref %s branch does not match commit (%s)"
msgstr "Dağıtılan referans %s dalı işlemesiyle eşleşmiyor (%s)"

#: common/flatpak-dir.c:10125 common/flatpak-installation.c:1911
#, c-format
msgid "%s branch %s already installed"
msgstr "%s dalı %s zaten kurulu"

# S: mnt_dir
#: common/flatpak-dir.c:10985
#, c-format
msgid "Could not unmount revokefs-fuse filesystem at %s: "
msgstr "%s konumunda revokefs-fuse dosya sistemi bağlantısı kaldırılamadı : "

#: common/flatpak-dir.c:11289
#, c-format
msgid "This version of %s is already installed"
msgstr "%s’in bu sürümü zaten kurulu"

#: common/flatpak-dir.c:11302
#, c-format
msgid "Can't change remote during bundle install"
msgstr "Paket kurulumu sırasında uzak değiştirilemedi"

#: common/flatpak-dir.c:11571
msgid "Can't update to a specific commit without root permissions"
msgstr "Kök izinleri olmadan belirli işleme güncellenemez"

#: common/flatpak-dir.c:11852
#, c-format
msgid "Can't remove %s, it is needed for: %s"
msgstr "%s kaldırılamaz, şunun için gerekiyor: %s"

#: common/flatpak-dir.c:11912 common/flatpak-installation.c:2067
#, c-format
msgid "%s branch %s is not installed"
msgstr "%s dalı %s kurulu değil"

#: common/flatpak-dir.c:12165
#, c-format
msgid "%s commit %s not installed"
msgstr "%s işleme %s kurulu değil"

#: common/flatpak-dir.c:12501
#, c-format
msgid "Pruning repo failed: %s"
msgstr "Depo budanamadı: %s"

#: common/flatpak-dir.c:12669 common/flatpak-dir.c:12675
#, c-format
msgid "Failed to load filter '%s'"
msgstr "'%s' süzgeci yüklenemedi"

#: common/flatpak-dir.c:12681
#, c-format
msgid "Failed to parse filter '%s'"
msgstr "'%s' süzgeci ayrıştırılamadı"

#: common/flatpak-dir.c:12963
msgid "Failed to write summary cache: "
msgstr "Özet ön belleği yazılamadı: "

#: common/flatpak-dir.c:12982
#, c-format
msgid "No oci summary cached for remote '%s'"
msgstr "Uzak '%s' için oci özeti önbelleklenmedi"

#: common/flatpak-dir.c:13207
#, c-format
msgid "No cached summary for remote '%s'"
msgstr "Uzak '%s' için önbelleklenmiş özet yok"

#: common/flatpak-dir.c:13248
#, c-format
msgid "Invalid checksum for indexed summary %s read from %s"
msgstr "İndeksli özet %s için, %s dosyasından okunan sağlama toplamı geçersiz"

#: common/flatpak-dir.c:13321
#, c-format
msgid ""
"Remote listing for %s not available; server has no summary file. Check the "
"URL passed to remote-add was valid."
msgstr ""
"Uzak listeleme %s için kullanılabilir değil; sunucunun özet dosyası yok. "
"remote-add için kullanılan URL’nin doğruluğunu denetleyin."

#: common/flatpak-dir.c:13698
#, c-format
msgid "Invalid checksum for indexed summary %s for remote '%s'"
msgstr "Uzak '%2$s' içinde, indeksli özet %1$s için sağlama toplamı geçersiz"

# : sonrasında kullanılabilir dallar listeleniyor
#: common/flatpak-dir.c:14388
#, c-format
msgid "Multiple branches available for %s, you must specify one of: "
msgstr ""
"%s için birden çok kullanılabilir dal, şunlardan birisini belirtmelisiniz: "

#: common/flatpak-dir.c:14454
#, c-format
msgid "Nothing matches %s"
msgstr "%s için eşleşme yok"

# Bol %s içeren kısım referansın pek çok verisini içeriyor, bölmeye çalışmayın.
#: common/flatpak-dir.c:14562
#, c-format
msgid "Can't find ref %s%s%s%s%s"
msgstr "%s%s%s%s%s referansı bulunamadı"

#: common/flatpak-dir.c:14605
#, c-format
msgid "Error searching remote %s: %s"
msgstr "Uzak %s aranırken hata: %s"

#: common/flatpak-dir.c:14702
#, c-format
msgid "Error searching local repository: %s"
msgstr "Yerel depo aranırken hata: %s"

#: common/flatpak-dir.c:14839
#, c-format
msgid "%s/%s/%s not installed"
msgstr "%s/%s/%s kurulu değil"

#: common/flatpak-dir.c:15042
#, c-format
msgid "Could not find installation %s"
msgstr "%s kurulumu bulunamadı"

#: common/flatpak-dir.c:15612
#, c-format
msgid "Invalid file format, no %s group"
msgstr "Geçersiz dosya biçimi, %s grubu yok"

#: common/flatpak-dir.c:15617 common/flatpak-repo-utils.c:2836
#, c-format
msgid "Invalid version %s, only 1 supported"
msgstr "Geçersiz sürüm %s, yalnızca 1 destekli"

#: common/flatpak-dir.c:15622 common/flatpak-dir.c:15627
#, c-format
msgid "Invalid file format, no %s specified"
msgstr "Geçersiz dosya biçimi, %s belirtilmemiş"

#. Check some minimal size so we don't get crap
#: common/flatpak-dir.c:15647
msgid "Invalid file format, gpg key invalid"
msgstr "Geçersiz dosya biçimi, gpg anahtarı geçersiz"

#: common/flatpak-dir.c:15675 common/flatpak-repo-utils.c:2917
msgid "Collection ID requires GPG key to be provided"
msgstr "Koleksiyon kimliği, GPG anahtarı sağlanmasını gerektirir"

#: common/flatpak-dir.c:15718
#, c-format
msgid "Runtime %s, branch %s is already installed"
msgstr "Çalışma zamanı %s, dal %s zaten kurulu"

#: common/flatpak-dir.c:15719
#, c-format
msgid "App %s, branch %s is already installed"
msgstr "Uygulama %s, dal %s zaten kurulu"

#: common/flatpak-dir.c:15953
#, c-format
msgid "Can't remove remote '%s' with installed ref %s (at least)"
msgstr "Uzak '%s' %s kurulu referansıyla kaldırılamıyor (en azından)"

#: common/flatpak-dir.c:16058
#, c-format
msgid "Invalid character '/' in remote name: %s"
msgstr "Uzak adda geçersiz '/' karakteri: %s"

#: common/flatpak-dir.c:16064
#, c-format
msgid "No configuration for remote %s specified"
msgstr "Uzak %s için yapılandırma belirtilmedi"

#: common/flatpak-dir.c:17597
#, c-format
msgid "Skipping deletion of mirror ref (%s, %s)…\n"
msgstr "Yansı referans (%s, %s) silme atlanıyor…\n"

#: common/flatpak-exports.c:931
#, c-format
msgid "An absolute path is required"
msgstr "Mutlak yol gerekli"

#: common/flatpak-exports.c:948
#, c-format
msgid "Unable to open path \"%s\": %s"
msgstr "\"%s\" yolu açılamadı: %s"

#: common/flatpak-exports.c:955
#, c-format
msgid "Unable to get file type of \"%s\": %s"
msgstr "\"%s\" dosya türü alınamadı: %s"

#: common/flatpak-exports.c:964
#, c-format
msgid "File \"%s\" has unsupported type 0o%o"
msgstr "\"%s\" dosyası desteklenmeyen 0o%o türünde"

#: common/flatpak-exports.c:970
#, c-format
msgid "Unable to get filesystem information for \"%s\": %s"
msgstr "\"%s\" için dosya sistemi bilgisi alınamadı: %s"

#: common/flatpak-exports.c:980
#, c-format
msgid "Ignoring blocking autofs path \"%s\""
msgstr "\"%s\" autofs yolu engellemesi yok sayılıyor"

#: common/flatpak-exports.c:996 common/flatpak-exports.c:1009
#: common/flatpak-exports.c:1022
#, c-format
msgid "Path \"%s\" is reserved by Flatpak"
msgstr "\"%s\" yolu Flatpak tarafından ayrılmıştır"

#: common/flatpak-exports.c:1076
#, c-format
msgid "Unable to resolve symbolic link \"%s\": %s"
msgstr "\"%s\" sembolik bağlantı çözülemedi: %s"

#: common/flatpak-glib-backports.c:69
msgid "Empty string is not a number"
msgstr "Boş dize bir sayı değil"

#: common/flatpak-glib-backports.c:95
#, c-format
msgid "“%s” is not an unsigned number"
msgstr "“%s” işaretsiz bir sayı değil"

#: common/flatpak-glib-backports.c:105
#, c-format
msgid "Number “%s” is out of bounds [%s, %s]"
msgstr "“%s” sayısı sınırların dışında [%s, %s]"

#: common/flatpak-image-source.c:83
msgid "Only sha256 image checksums are supported"
msgstr "Yalnızca sha256 görüntü sağlama toplamları desteklenir"

#: common/flatpak-image-source.c:100 common/flatpak-image-source.c:108
msgid "Image is not a manifest"
msgstr "Görüntü manifesto değil"

#: common/flatpak-image-source.c:123
msgid "No org.flatpak.ref found in image"
msgstr "Görüntüde org.flatpak.ref bulunamadı"

#: common/flatpak-image-source.c:148
#, c-format
msgid "Ref '%s' not found in registry"
msgstr "Referans '%s' sicilde bulunamadı"

#: common/flatpak-image-source.c:157
msgid "Multiple images in registry, specify a ref with --ref"
msgstr "Sicilde birden çok görüntü, --ref’le bir referans belirt"

#: common/flatpak-installation.c:834
#, c-format
msgid "Ref %s not installed"
msgstr "%s feferansı kurulu değil"

#: common/flatpak-installation.c:875
#, c-format
msgid "App %s not installed"
msgstr "%s uygulaması kurulu değil"

#: common/flatpak-installation.c:1395
#, c-format
msgid "Remote '%s' already exists"
msgstr "Uzak '%s' zaten var"

#: common/flatpak-installation.c:1946
#, c-format
msgid "As requested, %s was only pulled, but not installed"
msgstr "İstendiği gibi, %s yalnızca çekildi, ancak kurulmadı"

#: common/flatpak-instance.c:533 common/flatpak-instance.c:687
#: common/flatpak-instance.c:728
#, c-format
msgid "Unable to create directory %s"
msgstr "%s dizini oluşturulamadı"

#: common/flatpak-instance.c:554
#, c-format
msgid "Unable to lock %s"
msgstr "%s kilitlenemedi"

#: common/flatpak-instance.c:627
#, c-format
msgid "Unable to create temporary directory in %s"
msgstr "%s içinde geçici dizin oluşturulamadı"

#: common/flatpak-instance.c:639
#, c-format
msgid "Unable to create file %s"
msgstr "%s dosyası oluşturulamadı"

#: common/flatpak-instance.c:646
#, c-format
msgid "Unable to update symbolic link %s/%s"
msgstr "Sembolik bağlantı %s/%s güncellenemedi"

#: common/flatpak-oci-registry.c:1197
msgid "Only Bearer authentication supported"
msgstr "Yalnızca Bearer kimlik doğrulaması deneniyor"

#: common/flatpak-oci-registry.c:1206
msgid "Only realm in authentication request"
msgstr "Kimlik doğrulama isteğinde tek erişim alanı"

#: common/flatpak-oci-registry.c:1213
msgid "Invalid realm in authentication request"
msgstr "Kimlik doğrulama isteğinde geçersiz erişim alanı"

#: common/flatpak-oci-registry.c:1283
#, c-format
msgid "Authorization failed: %s"
msgstr "Yetkilendirme başarısız oldu: %s"

#: common/flatpak-oci-registry.c:1285
msgid "Authorization failed"
msgstr "Yetkilendirme başarısız oldu"

#: common/flatpak-oci-registry.c:1289
#, c-format
msgid "Unexpected response status %d when requesting token: %s"
msgstr "Jeton istenirken beklenmedik yanıt durumu %d: %s"

#: common/flatpak-oci-registry.c:1300
msgid "Invalid authentication request response"
msgstr "Geçersiz kimlik doğrulama isteği yanıtı"

#: common/flatpak-oci-registry.c:1731
#, c-format
msgid "Flatpak was compiled without zstd support"
msgstr "Flatpak zstd desteksiz derlenmiş"

#: common/flatpak-oci-registry.c:1923 common/flatpak-oci-registry.c:1975
#: common/flatpak-oci-registry.c:2004 common/flatpak-oci-registry.c:2059
#: common/flatpak-oci-registry.c:2115 common/flatpak-oci-registry.c:2193
msgid "Invalid delta file format"
msgstr "Geçersiz delta dosya biçimi"

#: common/flatpak-oci-registry.c:3198 common/flatpak-oci-registry.c:3382
msgid "Invalid OCI image config"
msgstr "Geçersiz OCI görüntü ayarı"

#: common/flatpak-oci-registry.c:3260 common/flatpak-oci-registry.c:3531
#, c-format
msgid "Wrong layer checksum, expected %s, was %s"
msgstr "Yanlış katman sağlaması toplamı, beklenen %s, olan %s"

#: common/flatpak-oci-registry.c:3359
#, c-format
msgid "No ref specified for OCI image %s"
msgstr "OCI görüntüsü %s için referans belirtilmedi"

#: common/flatpak-oci-registry.c:3369
#, c-format
msgid "Wrong ref (%s) specified for OCI image %s, expected %s"
msgstr ""
"OCI görüntüsü %2$s için belirtilen referans (%1$s) yanlış, beklenen %3$s"

#: common/flatpak-progress.c:236
#, c-format
msgid "Downloading metadata: %u/(estimating) %s"
msgstr "Üst veriler indiriliyor: %u/(tahmini) %s"

#: common/flatpak-progress.c:260
#, c-format
msgid "Downloading: %s/%s"
msgstr "İndiriliyor: %s/%s"

#: common/flatpak-progress.c:280
#, c-format
msgid "Downloading extra data: %s/%s"
msgstr "Ek veriler indiriliyor: %s/%s"

#: common/flatpak-progress.c:285
#, c-format
msgid "Downloading files: %d/%d %s"
msgstr "Dosyalar indiriliyor: %d/%d %s"

#: common/flatpak-ref-utils.c:122
msgid "Name can't be empty"
msgstr "Ad boş olamaz"

#: common/flatpak-ref-utils.c:129
msgid "Name can't be longer than 255 characters"
msgstr "Ad 255 karakterden uzun olamaz"

#: common/flatpak-ref-utils.c:142
msgid "Name can't start with a period"
msgstr "Ad nokta ile başlayamaz"

#: common/flatpak-ref-utils.c:148
#, c-format
msgid "Name can't start with %c"
msgstr "Ad %c ile başlayamaz"

#: common/flatpak-ref-utils.c:164
msgid "Name can't end with a period"
msgstr "Ad nokta ile bitemez"

#: common/flatpak-ref-utils.c:171 common/flatpak-ref-utils.c:183
msgid "Only last name segment can contain -"
msgstr "Yalnızca son ad bölümü kısa çizgi içerebilir"

#: common/flatpak-ref-utils.c:174
#, c-format
msgid "Name segment can't start with %c"
msgstr "Ad bölümleri %c ile başlayamaz"

#: common/flatpak-ref-utils.c:186
#, c-format
msgid "Name can't contain %c"
msgstr "Ad %c içeremez"

#: common/flatpak-ref-utils.c:195
msgid "Names must contain at least 2 periods"
msgstr "Adlar en az 2 bölüm içermelidir"

#: common/flatpak-ref-utils.c:312
msgid "Arch can't be empty"
msgstr "Mimari boş olamaz"

#: common/flatpak-ref-utils.c:323
#, c-format
msgid "Arch can't contain %c"
msgstr "Mimari %c içeremez"

#: common/flatpak-ref-utils.c:385
msgid "Branch can't be empty"
msgstr "Dal boş olamaz"

#: common/flatpak-ref-utils.c:395
#, c-format
msgid "Branch can't start with %c"
msgstr "Dal %c ile başlayamaz"

#: common/flatpak-ref-utils.c:405
#, c-format
msgid "Branch can't contain %c"
msgstr "Dal %c içeremez"

#: common/flatpak-ref-utils.c:615 common/flatpak-ref-utils.c:865
msgid "Ref too long"
msgstr "Referans çok uzun"

#: common/flatpak-ref-utils.c:627
msgid "Invalid remote name"
msgstr "Geçersiz uzak adı"

#: common/flatpak-ref-utils.c:641
#, c-format
msgid "%s is not application or runtime"
msgstr "%s uygulama ya da çalışma zamanı değil"

#: common/flatpak-ref-utils.c:650 common/flatpak-ref-utils.c:667
#: common/flatpak-ref-utils.c:683
#, c-format
msgid "Wrong number of components in %s"
msgstr "Yanlış bileşen sayısı %s"

#: common/flatpak-ref-utils.c:656
#, c-format
msgid "Invalid name %.*s: %s"
msgstr "Geçersiz ad %.*s: %s"

#: common/flatpak-ref-utils.c:673
#, c-format
msgid "Invalid arch: %.*s: %s"
msgstr "Geçersiz mimari: %.*s: %s"

#: common/flatpak-ref-utils.c:816
#, c-format
msgid "Invalid name %s: %s"
msgstr "Geçersiz ad %s: %s"

#: common/flatpak-ref-utils.c:834
#, c-format
msgid "Invalid arch: %s: %s"
msgstr "Geçersiz mimari: %s: %s"

#: common/flatpak-ref-utils.c:853
#, c-format
msgid "Invalid branch: %s: %s"
msgstr "Geçersiz dal: %s: %s"

#: common/flatpak-ref-utils.c:962 common/flatpak-ref-utils.c:970
#: common/flatpak-ref-utils.c:978
#, c-format
msgid "Wrong number of components in partial ref %s"
msgstr "Kısmi referans %s içinde yanlış sayıda bileşen"

#: common/flatpak-ref-utils.c:1298
msgid " development platform"
msgstr " geliştirme platformu"

#: common/flatpak-ref-utils.c:1300
msgid " platform"
msgstr " platform"

#: common/flatpak-ref-utils.c:1302
msgid " application base"
msgstr " uygulama temeli"

#: common/flatpak-ref-utils.c:1305
msgid " debug symbols"
msgstr " hata ayıklama sembolleri"

#: common/flatpak-ref-utils.c:1307
msgid " sourcecode"
msgstr " kaynak kodu"

#: common/flatpak-ref-utils.c:1309
msgid " translations"
msgstr " çeviriler"

#: common/flatpak-ref-utils.c:1311
msgid " docs"
msgstr " belgeler"

#: common/flatpak-ref-utils.c:1578
#, c-format
msgid "Invalid id %s: %s"
msgstr "Geçersiz id %s: %s"

#: common/flatpak-remote.c:1216
#, c-format
msgid "Bad remote name: %s"
msgstr "Kötü uzak adı: %s"

#: common/flatpak-remote.c:1220
msgid "No URL specified"
msgstr "URL belirtilmemiş"

#: common/flatpak-remote.c:1266
msgid "GPG verification must be enabled when a collection ID is set"
msgstr "Koleksiyon kimliği ayarlandığında GPG doğrulaması etkinleştirilmelidir"

#: common/flatpak-repo-utils.c:344
#, c-format
msgid "No extra data sources"
msgstr "Ek veri kaynağı yok"

#: common/flatpak-repo-utils.c:2817
#, c-format
msgid "Invalid %s: Missing group ‘%s’"
msgstr "Geçersiz %s: Yitik grup ‘%s’"

#: common/flatpak-repo-utils.c:2826
#, c-format
msgid "Invalid %s: Missing key ‘%s’"
msgstr "Geçersiz %s: Yitik anahtar ‘%s’"

#: common/flatpak-repo-utils.c:2876
msgid "Invalid gpg key"
msgstr "Geçersiz gpg anahtarı"

#: common/flatpak-repo-utils.c:3217
#, c-format
msgid "Error copying 64x64 icon for component %s: %s\n"
msgstr "64x64 simge %s bileşeni için kopyalanırken hata: %s\n"

#: common/flatpak-repo-utils.c:3223
#, c-format
msgid "Error copying 128x128 icon for component %s: %s\n"
msgstr "128x128 simge %s bileşeni için kopyalanırken hata: %s\n"

#: common/flatpak-repo-utils.c:3362
#, c-format
msgid "%s is end-of-life, ignoring for appstream"
msgstr "%s end-of-life, appstream için yok sayılıyor"

#: common/flatpak-repo-utils.c:3397
#, c-format
msgid "No appstream data for %s: %s\n"
msgstr "%s için appstream verisi bulunamadı: %s\n"

#: common/flatpak-repo-utils.c:3744
msgid "Invalid bundle, no ref in metadata"
msgstr "Geçersiz paket, üst veride referans yok"

#: common/flatpak-repo-utils.c:3846
#, c-format
msgid "Collection ‘%s’ of bundle doesn’t match collection ‘%s’ of remote"
msgstr "Paket koleksiyonu ‘%s’ uzaktaki ‘%s’ koleksiyonuyla eşleşmiyor"

#: common/flatpak-repo-utils.c:3923
msgid "Metadata in header and app are inconsistent"
msgstr "Başlıktaki ve uygulamadaki üst veriler tutarsız"

#: common/flatpak-run.c:951
msgid "No systemd user session available, cgroups not available"
msgstr "Systemd kullanıcı oturumu yok, cgroups kullanılabilir değil"

#: common/flatpak-run.c:1496
msgid "Unable to allocate instance id"
msgstr "Örnek kimliği ayrılamadı"

#: common/flatpak-run.c:1632 common/flatpak-run.c:1641
#, c-format
msgid "Failed to open flatpak-info file: %s"
msgstr "flatpak-info dosyası açılamadı: %s"

#: common/flatpak-run.c:1668
#, c-format
msgid "Failed to open bwrapinfo.json file: %s"
msgstr "bwrapinfo.json dosyası açılamadı: %s"

#: common/flatpak-run.c:1689
#, c-format
msgid "Failed to write to instance id fd: %s"
msgstr "Örnek kimliği dt’ye yazılamadı: %s"

#: common/flatpak-run.c:2096
msgid "Initialize seccomp failed"
msgstr "Seccomp ilklendirme başarısız oldu"

#: common/flatpak-run.c:2135
#, c-format
msgid "Failed to add architecture to seccomp filter: %s"
msgstr "Seccomp süzgecine mimari eklenemedi: %s"

#: common/flatpak-run.c:2143
#, c-format
msgid "Failed to add multiarch architecture to seccomp filter: %s"
msgstr "Seccomp süzgecine multiarch mimarisi eklenemedi: %s"

#: common/flatpak-run.c:2175 common/flatpak-run.c:2192
#: common/flatpak-run.c:2214
#, c-format
msgid "Failed to block syscall %d: %s"
msgstr "Syscall %d engellenemedi: %s"

#: common/flatpak-run.c:2247
#, c-format
msgid "Failed to export bpf: %s"
msgstr "Bpf dışa aktarılamadı: %s"

#: common/flatpak-run.c:2587
#, c-format
msgid "Failed to open ‘%s’"
msgstr "‘%s’ açılamadı"

#: common/flatpak-run.c:2597
#, c-format
msgid ""
"Directory forwarding needs version 4 of the document portal (have version %d)"
msgstr ""
"Dizin yönlendirme, belge kapısının 4. sürümüne gereksinir (sürüm %d var)"

#: common/flatpak-run.c:2915
#, c-format
msgid "ldconfig failed, exit status %d"
msgstr "ldconfig başarısız oldu, çıkış durumu %d"

#: common/flatpak-run.c:2922
msgid "Can't open generated ld.so.cache"
msgstr "Oluşturulan ld.so.cache açılamadı"

#. Translators: The placeholder is for an app ref.
#: common/flatpak-run.c:3045
#, c-format
msgid "Running %s is not allowed by the policy set by your administrator"
msgstr ""
"%s çalıştırılmasına yöneticinizce ayarlanan ilke nedeniyle izin verilmiyor"

#: common/flatpak-run.c:3202
msgid ""
"\"flatpak run\" is not intended to be run as `sudo flatpak run`. Use `sudo "
"-i` or `su -l` instead and invoke \"flatpak run\" from inside the new shell."
msgstr ""
"\"flatpak run\", `sudo flatpak run` olarak çalıştırılmak üzere "
"tasarlanmamıştır. Bunun yerine `sudo -i` ya da `su -l`kullanın ve yeni "
"kabuğun içinden \"flatpak run\" komutunu çalıştırın."

# ilk %s previous_app_id_dir olup uygulamanın eski konumu anlanına gelmektedir.
#: common/flatpak-run.c:3413
#, c-format
msgid "Failed to migrate from %s: %s"
msgstr "%s konumundan taşınamadı: %s"

#: common/flatpak-run.c:3434
#, c-format
msgid "Failed to migrate old app data directory %s to new name %s: %s"
msgstr "Eski uygulama veri dizini %s, yeni %s adına taşınamadı: %s"

#: common/flatpak-run.c:3443
#, c-format
msgid "Failed to create symlink while migrating %s: %s"
msgstr "%s taşınırken sembolik bağlantı oluşturulamadı: %s"

#: common/flatpak-run-dbus.c:46
msgid "Failed to open app info file"
msgstr "Uygulama bilgi dosyası açılamadı"

#: common/flatpak-run-dbus.c:149
msgid "Unable to create sync pipe"
msgstr "Eşzamanlama veri yolu oluşturulamadı"

#: common/flatpak-run-dbus.c:185
msgid "Failed to sync with dbus proxy"
msgstr "Dbus vekiliyle eşzamanlanamadı"

#: common/flatpak-transaction.c:2275
#, c-format
msgid "Warning: Problem looking for related refs: %s"
msgstr "Uyarı: İlişkili referansları ararken sorun: %s"

#: common/flatpak-transaction.c:2493
#, c-format
msgid "The application %s requires the runtime %s which was not found"
msgstr "%s uygulaması bulunmayan %s çalışma zamanını gerektirir"

#: common/flatpak-transaction.c:2509
#, c-format
msgid "The application %s requires the runtime %s which is not installed"
msgstr "%s uygulaması kurulmamış %s çalışma zamanını gerektirir"

#: common/flatpak-transaction.c:2641
#, c-format
msgid "Can't uninstall %s which is needed by %s"
msgstr "%s kaldırılamıyor çünkü %s gereksiniyor"

#: common/flatpak-transaction.c:2740
#, c-format
msgid "Remote %s disabled, ignoring %s update"
msgstr "Uzak %s devredışı, %s güncellemesi yok sayılıyor"

#: common/flatpak-transaction.c:2773
#, c-format
msgid "%s is already installed"
msgstr "%s zaten kurulu"

#: common/flatpak-transaction.c:2776
#, c-format
msgid "%s is already installed from remote %s"
msgstr "%s, %s uzağından zaten kurulu"

#: common/flatpak-transaction.c:3120
#, c-format
msgid "Invalid .flatpakref: %s"
msgstr "Geçersiz .flatpakref: %s"

#: common/flatpak-transaction.c:3161
msgid "Warning: Could not mark already installed apps as preinstalled"
msgstr "Uyarı: Zaten kurulmuş uygulamalar önden-kurulu olarak imlenemedi"

#: common/flatpak-transaction.c:3382
#, c-format
msgid "Error updating remote metadata for '%s': %s"
msgstr "'%s' için uzak üst veri güncellenirken hata: %s"

#: common/flatpak-transaction.c:3885
#, c-format
msgid ""
"Warning: Treating remote fetch error as non-fatal since %s is already "
"installed: %s"
msgstr ""
"Uyarı: %s zaten kurulu olduğundan uzaktan alma hatası ölümcül kabul "
"edilmiyor: %s"

#: common/flatpak-transaction.c:4209
#, c-format
msgid "No authenticator installed for remote '%s'"
msgstr "Uzak `%s` için kimlik doğrulayıcı kurulmadı"

#: common/flatpak-transaction.c:4313 common/flatpak-transaction.c:4320
#, c-format
msgid "Failed to get tokens for ref: %s"
msgstr "Referans için jetonlar alınamadı: %s"

#: common/flatpak-transaction.c:4315 common/flatpak-transaction.c:4322
msgid "Failed to get tokens for ref"
msgstr "Referans için jetonlar alınamadı"

#: common/flatpak-transaction.c:4580
#, c-format
msgid "Ref %s from %s matches more than one transaction operation"
msgstr "%s referansı, %s uzağından birden çok aktarım işlemiyle eşleşiyor"

#: common/flatpak-transaction.c:4581 common/flatpak-transaction.c:4591
msgid "any remote"
msgstr "herhangi uzak"

#: common/flatpak-transaction.c:4590
#, c-format
msgid "No transaction operation found for ref %s from %s"
msgstr "%s referansı için %s uzağında aktarım işlemi bulunamadı"

#: common/flatpak-transaction.c:4713
#, c-format
msgid "Flatpakrepo URL %s not file, HTTP or HTTPS"
msgstr "%s Flatpakrepo URL’si dosya HTTP ya da HTTPS değil"

#: common/flatpak-transaction.c:4719
#, c-format
msgid "Can't load dependent file %s: "
msgstr "%s bağımlı dosyası yüklenemedi: "

#: common/flatpak-transaction.c:4727
#, c-format
msgid "Invalid .flatpakrepo: %s"
msgstr "Geçersiz .flatpakrepo: %s"

#: common/flatpak-transaction.c:5454
msgid "Transaction already executed"
msgstr "İşlem zaten yapıldı"

#: common/flatpak-transaction.c:5469
msgid ""
"Refusing to operate on a user installation as root! This can lead to "
"incorrect file ownership and permission errors."
msgstr ""
"Kullanıcı kurulumunda kök olarak çalışmayı reddetti! Bu, hatalı dosya "
"sahipliği ve izin hatalarına neden olabilir."

#: common/flatpak-transaction.c:5567 common/flatpak-transaction.c:5580
msgid "Aborted by user"
msgstr "Kullanıcıca vazgeçildi"

#: common/flatpak-transaction.c:5605
#, c-format
msgid "Skipping %s due to previous error"
msgstr "Önceki hata nedeniyle %s atlanıyor"

#: common/flatpak-transaction.c:5659
#, c-format
msgid "Aborted due to failure (%s)"
msgstr "Başarısızlık nedeniyle vazgeçildi (%s)"

#: common/flatpak-uri.c:118
#, no-c-format
msgid "Invalid %-encoding in URI"
msgstr "URI’de geçersiz %-kodlaması"

#: common/flatpak-uri.c:135
msgid "Illegal character in URI"
msgstr "URI’de geçersiz karakter"

#: common/flatpak-uri.c:169
msgid "Non-UTF-8 characters in URI"
msgstr "URI’de UTF-8 olmayan karakter"

#: common/flatpak-uri.c:275
#, c-format
msgid "Invalid IPv6 address ‘%.*s’ in URI"
msgstr "URI’de geçersiz IPv6 adresi ‘%.*s’"

#: common/flatpak-uri.c:330
#, c-format
msgid "Illegal encoded IP address ‘%.*s’ in URI"
msgstr "URI’de kural dışı kodlanmış IP adresi ‘%.*s’"

#: common/flatpak-uri.c:342
#, c-format
msgid "Illegal internationalized hostname ‘%.*s’ in URI"
msgstr "URI’de kural dışı uluslararasılaştırılmış ana makine adı ‘%.*s’"

#: common/flatpak-uri.c:374 common/flatpak-uri.c:386
#, c-format
msgid "Could not parse port ‘%.*s’ in URI"
msgstr "URI’deki ‘%.*s’ bağlantı noktası ayrıştırılamadı"

#: common/flatpak-uri.c:393
#, c-format
msgid "Port ‘%.*s’ in URI is out of range"
msgstr "URI’deki ‘%.*s’ bağlantı noktası kapsam dışında"

#: common/flatpak-uri.c:910
msgid "URI is not absolute, and no base URI was provided"
msgstr "URI mutlak değil ve temel URI sağlanmamış"

#: common/flatpak-usb.c:83
#, c-format
msgid "USB device query 'all' must not have data"
msgstr "USB aygıt sorgusu 'all' veri içermemelidir"

#: common/flatpak-usb.c:102
#, c-format
msgid "USB query rule 'cls' must be in the form CLASS:SUBCLASS or CLASS:*"
msgstr ""
"USB sorgu kuralı 'cls', SINIF:ALTSINIF ya da SINIF:* biçiminde olmalıdır"

#: common/flatpak-usb.c:111
#, c-format
msgid "Invalid USB class"
msgstr "Geçersiz USB sınıfı"

#: common/flatpak-usb.c:125
#, c-format
msgid "Invalid USB subclass"
msgstr "Geçersiz USB alt sınıfı"

#: common/flatpak-usb.c:141 common/flatpak-usb.c:148
#, c-format
msgid "USB query rule 'dev' must have a valid 4-digit hexadecimal product id"
msgstr ""
"'dev' USB sorgu kuralının geçerli 4 basamaklı onaltılık ürün kimliği "
"olmalıdır"

#: common/flatpak-usb.c:164 common/flatpak-usb.c:171
#, c-format
msgid "USB query rule 'vnd' must have a valid 4-digit hexadecimal vendor id"
msgstr ""
"'vnd' USB sorgu kuralının geçerli 4 basamaklı onaltılık üretici kimliği "
"olmalıdır"

#: common/flatpak-usb.c:205
#, c-format
msgid "USB device queries must be in the form TYPE:DATA"
msgstr "USB aygıt sorguları TÜR:VERİ şeklinde olmalıdır"

#: common/flatpak-usb.c:225
#, c-format
msgid "Unknown USB query rule %s"
msgstr "Bilinmeyen USB sorgu kuralı %s"

#: common/flatpak-usb.c:248
#, c-format
msgid "Empty USB query"
msgstr "Boş USB sorgusu"

#: common/flatpak-usb.c:274
#, c-format
msgid "Multiple USB query rules of the same type is not supported"
msgstr "Aynı türde birden çok USB sorgu kuralı desteklenmez"

#: common/flatpak-usb.c:283
#, c-format
msgid "'all' must not contain extra query rules"
msgstr "'all' ek sorgu kuralları içermemelidir"

#: common/flatpak-usb.c:291
#, c-format
msgid "USB queries with 'dev' must also specify vendors"
msgstr "'dev' içeren USB sorguları üreticileri de belirtmelidir"

#: common/flatpak-utils.c:712
msgid "Glob can't match apps"
msgstr "Glob uygulamalarla eşleşmiyor"

#: common/flatpak-utils.c:737
msgid "Empty glob"
msgstr "Glob boş"

#: common/flatpak-utils.c:756
msgid "Too many segments in glob"
msgstr "Glob’da çok fazla bölüm"

#: common/flatpak-utils.c:777
#, c-format
msgid "Invalid glob character '%c'"
msgstr "Geçersiz glob karakter '%c'"

#: common/flatpak-utils.c:831
#, c-format
msgid "Missing glob on line %d"
msgstr "%d. satırda yitik glob"

#: common/flatpak-utils.c:835
#, c-format
msgid "Trailing text on line %d"
msgstr "%d. satırda sondaki metin"

#: common/flatpak-utils.c:839
#, c-format
msgid "on line %d"
msgstr "%d. satırda"

#: common/flatpak-utils.c:861
#, c-format
msgid "Unexpected word '%s' on line %d"
msgstr "%2$d. satırda beklenmedik '%1$s' sözcüğü"

#: common/flatpak-utils.c:2118
#, c-format
msgid "Invalid require-flatpak argument %s"
msgstr "Geçersiz require-flatpak argümanı %s"

#: common/flatpak-utils.c:2128 common/flatpak-utils.c:2147
#, c-format
msgid "%s needs a later flatpak version (%s)"
msgstr "%s daha üst bir flatpak sürümünü gerektiriyor (%s)"

#: oci-authenticator/flatpak-oci-authenticator.c:291
msgid "Not a oci remote, missing summary.xa.oci-repository"
msgstr "Oci uzağı değil, summary.xa.oci-repository yitik"

#: oci-authenticator/flatpak-oci-authenticator.c:477
msgid "Not a OCI remote"
msgstr "OCI uzağı değil"

#: oci-authenticator/flatpak-oci-authenticator.c:488
msgid "Invalid token"
msgstr "Geçersiz jeton"

#: portal/flatpak-portal.c:2292
#, c-format
msgid "No portal support found"
msgstr "Kapı desteği bulunamadı"

#: portal/flatpak-portal.c:2298
msgid "Deny"
msgstr "Reddet"

#: portal/flatpak-portal.c:2300
msgid "Update"
msgstr "Güncelle"

#: portal/flatpak-portal.c:2305
#, c-format
msgid "Update %s?"
msgstr "%s güncellensin mi?"

#: portal/flatpak-portal.c:2317
msgid "The application wants to update itself."
msgstr "Uygulama kendisini güncellemek istiyor."

#: portal/flatpak-portal.c:2318
msgid "Update access can be changed any time from the privacy settings."
msgstr "Güncelleme erişimi, gizlilik ayarlarından her zaman değiştirilebilir."

#: portal/flatpak-portal.c:2343
#, c-format
msgid "Application update not allowed"
msgstr "Uygulama güncelleme izin verilmiyor"

#: portal/flatpak-portal.c:2501
#, c-format
msgid "Self update not supported, new version requires new permissions"
msgstr ""
"Kendini güncelleme desteklenmiyor, yeni sürüm yeni izinler gerektiriyor"

#: portal/flatpak-portal.c:2684 portal/flatpak-portal.c:2702
#, c-format
msgid "Update ended unexpectedly"
msgstr "Güncelleme beklenmeyen bir şekilde sonlandı"

#. SECURITY:
#. - Normal users need admin authentication to install software
#. system-wide.
#. - Note that we install polkit rules that allow local users
#. in the wheel group to install without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:23
msgid "Install signed application"
msgstr "İmzalı uygulama kur"

#: system-helper/org.freedesktop.Flatpak.policy.in:24
#: system-helper/org.freedesktop.Flatpak.policy.in:42
msgid "Authentication is required to install software"
msgstr "Yazılım kurmak için kimlik doğrulaması gerekiyor"

#. SECURITY:
#. - Normal users need admin authentication to install software
#. system-wide.
#. - Note that we install polkit rules that allow local users
#. in the wheel group to install without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:41
msgid "Install signed runtime"
msgstr "İmzalı çalışma zamanı kur"

#. SECURITY:
#. - Normal users do not require admin authentication to update an
#. app as the commit will be signed, and the action is required
#. to update the system when unattended.
#. - Changing this to anything other than 'yes' will break unattended
#. updates.
#: system-helper/org.freedesktop.Flatpak.policy.in:60
msgid "Update signed application"
msgstr "İmzalı uygulamayı güncelle"

#: system-helper/org.freedesktop.Flatpak.policy.in:61
#: system-helper/org.freedesktop.Flatpak.policy.in:80
msgid "Authentication is required to update software"
msgstr "Uygulama güncellemek için kimlik doğrulaması gerekiyor"

#. SECURITY:
#. - Normal users do not require admin authentication to update a
#. runtime as the commit will be signed, and the action is required
#. to update the system when unattended.
#. - Changing this to anything other than 'yes' will break unattended
#. updates.
#: system-helper/org.freedesktop.Flatpak.policy.in:79
msgid "Update signed runtime"
msgstr "İmzalı çalışma zamanını güncelle"

#. SECURITY:
#. - Normal users do not need authentication to update metadata
#. from signed repositories.
#: system-helper/org.freedesktop.Flatpak.policy.in:94
msgid "Update remote metadata"
msgstr "Uzaktaki üst veriyi güncelle"

#: system-helper/org.freedesktop.Flatpak.policy.in:95
msgid "Authentication is required to update remote info"
msgstr "Uzak bilgileri güncellemek için kimlik doğrulaması gerekiyor"

#. SECURITY:
#. - Normal users do not need authentication to modify the
#. OSTree repository
#. - Note that we install polkit rules that allow local users
#. in the wheel group to modify repos without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:111
msgid "Update system repository"
msgstr "Sistem deposunu güncelle"

#: system-helper/org.freedesktop.Flatpak.policy.in:112
msgid "Authentication is required to modify a system repository"
msgstr "Sistem deposunu değiştirmek için kimlik doğrulaması gerekiyor"

#. SECURITY:
#. - Normal users need admin authentication to install software
#. system-wide.
#: system-helper/org.freedesktop.Flatpak.policy.in:126
msgid "Install bundle"
msgstr "Paket kur"

#: system-helper/org.freedesktop.Flatpak.policy.in:127
msgid "Authentication is required to install software from $(path)"
msgstr "Yazılımı $(path) yolundan kurmak için kimlik doğrulaması gerekiyor"

#. SECURITY:
#. - Normal users need admin authentication to uninstall software
#. system-wide.
#. - Note that we install polkit rules that allow local users
#. in the wheel group to uninstall without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:144
msgid "Uninstall runtime"
msgstr "Çalışma zamanı kaldır"

#: system-helper/org.freedesktop.Flatpak.policy.in:145
msgid "Authentication is required to uninstall software"
msgstr "Yazılımı kaldırmak için kimlik doğrulaması gerekiyor"

#. SECURITY:
#. - Normal users need admin authentication to uninstall software
#. system-wide.
#. - Note that we install polkit rules that allow local users
#. in the wheel group to uninstall without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:161
msgid "Uninstall app"
msgstr "Uygulama kaldır"

#: system-helper/org.freedesktop.Flatpak.policy.in:162
msgid "Authentication is required to uninstall $(ref)"
msgstr "$(ref) kaldırmak için kimlik doğrulaması gerekiyor"

#. SECURITY:
#. - Normal users need admin authentication to configure system-wide
#. software repositories.
#: system-helper/org.freedesktop.Flatpak.policy.in:177
msgid "Configure Remote"
msgstr "Uzak Yapılandır"

#: system-helper/org.freedesktop.Flatpak.policy.in:178
msgid "Authentication is required to configure software repositories"
msgstr "Yazılım depolarını yapılandırmak için kimlik doğrulaması gerekiyor"

#. SECURITY:
#. - Normal users need admin authentication to configure the system-wide
#. Flatpak installation.
#: system-helper/org.freedesktop.Flatpak.policy.in:192
msgid "Configure"
msgstr "Yapılandır"

#: system-helper/org.freedesktop.Flatpak.policy.in:193
msgid "Authentication is required to configure software installation"
msgstr "Yazılım kurulumunu yapılandırmak için kimlik doğrulaması gerekiyor"

#. SECURITY:
#. - Normal users do not require admin authentication to update
#. appstream data as it will be signed, and the action is required
#. to update the system when unattended.
#. - Changing this to anything other than 'yes' will break unattended
#. updates.
#: system-helper/org.freedesktop.Flatpak.policy.in:210
msgid "Update appstream"
msgstr "Appstream’i güncelle"

#: system-helper/org.freedesktop.Flatpak.policy.in:211
msgid "Authentication is required to update information about software"
msgstr ""
"Yazılımla ilgili bilgileri güncellemek için kimlik doğrulaması gerekiyor"

#. SECURITY:
#. - Normal users do not require admin authentication to update
#. metadata as it will be signed, and the action is required
#. to update the system when unattended.
#. - Changing this to anything other than 'yes' will break unattended
#. updates.
#: system-helper/org.freedesktop.Flatpak.policy.in:228
msgid "Update metadata"
msgstr "Üst veriyi güncelle"

#: system-helper/org.freedesktop.Flatpak.policy.in:229
msgid "Authentication is required to update metadata"
msgstr "Üst verileri güncellemek için kimlik doğrulaması gerekiyor"

#. SECURITY:
#. - Authorisation to actually install software is controlled by
#. org.freedesktop.Flatpak.app-install.
#. - This action is checked after app-install, as it can only be done
#. once the app’s data (including its content rating) has been
#. downloaded.
#. - This action is checked to see if the installation should be allowed
#. based on whether the app being installed has content which doesn’t
#. comply with the user’s parental controls policy (the content is
#. ‘too extreme’).
#. - It is checked only if an app has too extreme content for the user
#. who is trying to install it (in which case, the app is ‘unsafe’).
#. - Typically, normal users will need admin permission to install apps
#. with extreme content; admins will be able to install it without
#. additional checks.
#. - In order to configure the policy so that admins can install safe and
#. unsafe software anywhere without authorisation, and non-admins can
#. install safe software in their user or system dirs without
#. authorisation, but need authorisation to install unsafe software
#. anywhere:
#. * Unconditionally return `yes` from `app-install`.
#. * Return `auth_admin` from `override-parental-controls` for users
#. not in `@privileged_group@`, and `yes` for users in it.
#. * Set the malcontent `is-{user,system}-installation-allowed`
#. properties of all non-admins’ parental controls policies to true.
#. - In order to configure the policy so that admins can install safe and
#. unsafe software anywhere without authorisation, and non-admins can
#. install safe software in their user dir without authorisation, but
#. need authorisation to install safe software in the system dir or to
#. install unsafe software anywhere:
#. * Unconditionally return `yes` from `app-install`.
#. * Return `auth_admin` from `override-parental-controls` for users
#. not in `@privileged_group@`, and `yes` for users in it.
#. * Set the malcontent `is-user-installation-allowed` property of all
#. non-admins’ parental controls policies to true.
#. * Set the malcontent `is-system-installation-allowed` property of
#. all non-admins’ parental controls policies to false.
#. - In order to configure the policy so that all users (including
#. admins) can install safe software anywhere without authorisation,
#. but need authorisation to install unsafe software anywhere (i.e.
#. applying parental controls to admins too):
#. * Unconditionally return `yes` from `app-install`.
#. * Unconditionally return `auth_admin` from `override-parental-controls`.
#. * Set the malcontent `is-user-installation-allowed` property of all
#. users’ parental controls policies to true.
#. * Set the malcontent `is-system-installation-allowed` property of
#. all users’ parental controls policies to true.
#: system-helper/org.freedesktop.Flatpak.policy.in:287
msgid "Override parental controls for installs"
msgstr "Kurulumlar için ebeveyn denetimlerini geçersiz kıl"

#: system-helper/org.freedesktop.Flatpak.policy.in:288
msgid ""
"Authentication is required to install software which is restricted by your "
"parental controls policy"
msgstr ""
"Ebeveyn denetim ilkesince kısıtlanan yazılımı kurmak için kimlik doğrulaması "
"gerekiyor"

#. SECURITY:
#. - This is like org.freedesktop.Flatpak.override-parental-controls, but
#. it’s queried for app updates, whereas the former is queried for app
#. installs.
#. - As with the above action, this one is only queried if
#. org.freedesktop.Flatpak.app-update has allowed the app update, and
#. only if the app being updated has too extreme content for the user
#. who is trying to update it.
#. - The default policy for this is to *allow* updates to ‘too extreme’
#. apps by default, on the basis that having an out-of-date (i.e.
#. insecure or unsupported) app is a worse outcome than automatically
#. installing an update which has radically different content from the
#. version of the app which the parent originally vetted and installed.
#: system-helper/org.freedesktop.Flatpak.policy.in:313
msgid "Override parental controls for updates"
msgstr "Güncellemeler için ebeveyn denetimlerini geçersiz kıl"

#: system-helper/org.freedesktop.Flatpak.policy.in:314
msgid ""
"Authentication is required to update software which is restricted by your "
"parental controls policy"
msgstr ""
"Ebeveyn denetim ilkesince kısıtlanan yazılımın güncellenmesi için kimlik "
"doğrulaması gerekiyor"

===== ./po/en_GB.po =====
# British English translation for flatpak.
# Copyright (C) 2019 flatpak's COPYRIGHT HOLDER
# This file is distributed under the same license as the flatpak package.
# Zander Brown <zbrown@gnome.org>, 2019.
#
msgid ""
msgstr ""
"Project-Id-Version: flatpak master\n"
"Report-Msgid-Bugs-To: https://github.com/flatpak/flatpak/issues\n"
"POT-Creation-Date: 2026-05-27 16:39+0200\n"
"PO-Revision-Date: 2019-08-24 23:27+0100\n"
"Last-Translator: Zander Brown <zbrown@gnome.org>\n"
"Language-Team: English - United Kingdom <en_GB@li.org>\n"
"Language: en_GB\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Generator: Gtranslator 3.32.1\n"

#: app/flatpak-builtins-build-bundle.c:59
msgid "Export runtime instead of app"
msgstr "Export runtime instead of app"

#: app/flatpak-builtins-build-bundle.c:60
msgid "Arch to bundle for"
msgstr "Arch to bundle for"

#: app/flatpak-builtins-build-bundle.c:60
#: app/flatpak-builtins-build-export.c:62 app/flatpak-builtins-build-init.c:53
#: app/flatpak-builtins-build-sign.c:42 app/flatpak-builtins-create-usb.c:46
#: app/flatpak-builtins-info.c:55 app/flatpak-builtins-install.c:67
#: app/flatpak-builtins-list.c:50 app/flatpak-builtins-make-current.c:38
#: app/flatpak-builtins-remote-info.c:54 app/flatpak-builtins-remote-ls.c:56
#: app/flatpak-builtins-run.c:158 app/flatpak-builtins-search.c:37
#: app/flatpak-builtins-uninstall.c:54 app/flatpak-builtins-update.c:56
msgid "ARCH"
msgstr "ARCH"

#: app/flatpak-builtins-build-bundle.c:61
#, fuzzy
msgid "URL for repo"
msgstr "Url for repo"

#: app/flatpak-builtins-build-bundle.c:61
#: app/flatpak-builtins-build-bundle.c:62
#: app/flatpak-builtins-build-update-repo.c:68
#: app/flatpak-builtins-build-update-repo.c:72
#: app/flatpak-builtins-build-update-repo.c:73
#: app/flatpak-builtins-history.c:69 app/flatpak-builtins-remote-add.c:80
#: app/flatpak-builtins-remote-add.c:81 app/flatpak-builtins-remote-add.c:85
#: app/flatpak-builtins-remote-list.c:53
#: app/flatpak-builtins-remote-modify.c:70
#: app/flatpak-builtins-remote-modify.c:85
#: app/flatpak-builtins-remote-modify.c:86
#: app/flatpak-builtins-remote-modify.c:90
msgid "URL"
msgstr "URL"

#: app/flatpak-builtins-build-bundle.c:62
#, fuzzy
msgid "URL for runtime flatpakrepo file"
msgstr "Url for runtime flatpakrepo file"

#: app/flatpak-builtins-build-bundle.c:63
msgid "Add GPG key from FILE (- for stdin)"
msgstr "Add GPG key from FILE (- for stdin)"

#: app/flatpak-builtins-build-bundle.c:63 app/flatpak-builtins-build.c:54
#: app/flatpak-builtins-build-export.c:67
#: app/flatpak-builtins-build-update-repo.c:83
#: app/flatpak-builtins-install.c:81 app/flatpak-builtins-remote-add.c:84
#: app/flatpak-builtins-remote-add.c:86 app/flatpak-builtins-remote-modify.c:89
#: app/flatpak-builtins-remote-modify.c:92
msgid "FILE"
msgstr "FILE"

#: app/flatpak-builtins-build-bundle.c:64
msgid "GPG Key ID to sign the OCI image with"
msgstr "GPG Key ID to sign the OCI image with"

#: app/flatpak-builtins-build-bundle.c:64
#: app/flatpak-builtins-build-commit-from.c:68
#: app/flatpak-builtins-build-export.c:68
#: app/flatpak-builtins-build-import-bundle.c:49
#: app/flatpak-builtins-build-sign.c:44
#: app/flatpak-builtins-build-update-repo.c:84
msgid "KEY-ID"
msgstr "KEY-ID"

#: app/flatpak-builtins-build-bundle.c:65
#: app/flatpak-builtins-build-commit-from.c:69
#: app/flatpak-builtins-build-export.c:71
#: app/flatpak-builtins-build-import-bundle.c:50
#: app/flatpak-builtins-build-sign.c:45
#: app/flatpak-builtins-build-update-repo.c:85
msgid "GPG Homedir to use when looking for keyrings"
msgstr "GPG Homedir to use when looking for keyrings"

#: app/flatpak-builtins-build-bundle.c:65
#: app/flatpak-builtins-build-commit-from.c:69
#: app/flatpak-builtins-build-export.c:71
#: app/flatpak-builtins-build-import-bundle.c:50
#: app/flatpak-builtins-build-sign.c:45
#: app/flatpak-builtins-build-update-repo.c:85
msgid "HOMEDIR"
msgstr "HOMEDIR"

#: app/flatpak-builtins-build-bundle.c:66
msgid "OSTree commit to create a delta bundle from"
msgstr "OSTree commit to create a delta bundle from"

#: app/flatpak-builtins-build-bundle.c:66 app/flatpak-builtins-remote-info.c:55
#: app/flatpak-builtins-update.c:57
msgid "COMMIT"
msgstr "COMMIT"

#: app/flatpak-builtins-build-bundle.c:67
msgid "Export oci image instead of flatpak bundle"
msgstr "Export oci image instead of flatpak bundle"

#: app/flatpak-builtins-build-bundle.c:70
msgid "How to compress OCI image layers (default: gzip)"
msgstr ""

#: app/flatpak-builtins-build-bundle.c:634
msgid ""
"LOCATION FILENAME NAME [BRANCH] - Create a single file bundle from a local "
"repository"
msgstr ""
"LOCATION FILENAME NAME [BRANCH] - Create a single file bundle from a local "
"repository"

#: app/flatpak-builtins-build-bundle.c:641
msgid "LOCATION, FILENAME and NAME must be specified"
msgstr "LOCATION, FILENAME and NAME must be specified"

#: app/flatpak-builtins-build-bundle.c:644
#: app/flatpak-builtins-build-export.c:844
#: app/flatpak-builtins-build-import-bundle.c:136
#: app/flatpak-builtins-build-init.c:217 app/flatpak-builtins-build-sign.c:76
#: app/flatpak-builtins-document-export.c:112
#: app/flatpak-builtins-document-info.c:75
#: app/flatpak-builtins-document-list.c:191
#: app/flatpak-builtins-document-unexport.c:70
#: app/flatpak-builtins-history.c:482 app/flatpak-builtins-info.c:130
#: app/flatpak-builtins-install.c:181 app/flatpak-builtins-install.c:234
#: app/flatpak-builtins-install.c:298 app/flatpak-builtins-list.c:419
#: app/flatpak-builtins-make-current.c:72 app/flatpak-builtins-override.c:73
#: app/flatpak-builtins-permission-list.c:162
#: app/flatpak-builtins-permission-remove.c:132
#: app/flatpak-builtins-remote-add.c:323
#: app/flatpak-builtins-remote-delete.c:68
#: app/flatpak-builtins-remote-list.c:241 app/flatpak-builtins-remote-ls.c:407
msgid "Too many arguments"
msgstr "Too many arguments"

#: app/flatpak-builtins-build-bundle.c:659
#: app/flatpak-builtins-build-commit-from.c:338
#: app/flatpak-builtins-build-commit-from.c:351
#: app/flatpak-builtins-build-import-bundle.c:145
#, c-format
msgid "'%s' is not a valid repository"
msgstr "'%s' is not a valid repository"

#: app/flatpak-builtins-build-bundle.c:663
#, c-format
msgid "'%s' is not a valid repository: "
msgstr "'%s' is not a valid repository: "

#: app/flatpak-builtins-build-bundle.c:674 app/flatpak-builtins-build-sign.c:88
#: common/flatpak-dir.c:14293
#, c-format
msgid "'%s' is not a valid name: %s"
msgstr "'%s' is not a valid name: %s"

#: app/flatpak-builtins-build-bundle.c:677
#: app/flatpak-builtins-build-export.c:865 app/flatpak-builtins-build-sign.c:91
#: common/flatpak-dir.c:14299
#, c-format
msgid "'%s' is not a valid branch name: %s"
msgstr "'%s' is not a valid branch name: %s"

#: app/flatpak-builtins-build-bundle.c:691
#: app/flatpak-builtins-build-import-bundle.c:149
#: app/flatpak-builtins-build-init.c:281
#, c-format
msgid "'%s' is not a valid filename"
msgstr "'%s' is not a valid filename"

#: app/flatpak-builtins-build-bundle.c:706
msgid "--oci-layer-compress value must be gzip or zstd"
msgstr ""

#: app/flatpak-builtins-build.c:49
msgid "Use Platform runtime rather than Sdk"
msgstr "Use Platform runtime rather than Sdk"

#: app/flatpak-builtins-build.c:50
msgid "Make destination readonly"
msgstr "Make destination readonly"

#: app/flatpak-builtins-build.c:51
msgid "Add bind mount"
msgstr "Add bind mount"

#: app/flatpak-builtins-build.c:51
msgid "DEST=SRC"
msgstr "DEST=SRC"

#: app/flatpak-builtins-build.c:52
msgid "Start build in this directory"
msgstr "Start build in this directory"

#: app/flatpak-builtins-build.c:52 app/flatpak-builtins-build.c:53
#: app/flatpak-builtins-build-init.c:64 app/flatpak-builtins-run.c:160
msgid "DIR"
msgstr "DIR"

#: app/flatpak-builtins-build.c:53
msgid "Where to look for custom sdk dir (defaults to 'usr')"
msgstr "Where to look for custom sdk dir (defaults to 'usr')"

#: app/flatpak-builtins-build.c:54 app/flatpak-builtins-build-export.c:67
msgid "Use alternative file for the metadata"
msgstr "Use alternative file for the metadata"

#: app/flatpak-builtins-build.c:55 app/flatpak-builtins-run.c:177
msgid "Kill processes when the parent process dies"
msgstr "Kill processes when the parent process dies"

#: app/flatpak-builtins-build.c:56
msgid "Export application homedir directory to build"
msgstr "Export application homedir directory to build"

#: app/flatpak-builtins-build.c:57 app/flatpak-builtins-run.c:165
msgid "Log session bus calls"
msgstr "Log session bus calls"

#: app/flatpak-builtins-build.c:58 app/flatpak-builtins-run.c:166
msgid "Log system bus calls"
msgstr "Log system bus calls"

#: app/flatpak-builtins-build.c:262
msgid "DIRECTORY [COMMAND [ARGUMENT…]] - Build in directory"
msgstr "DIRECTORY [COMMAND [ARGUMENT…]] - Build in directory"

#: app/flatpak-builtins-build.c:285 app/flatpak-builtins-build-finish.c:656
msgid "DIRECTORY must be specified"
msgstr "DIRECTORY must be specified"

#: app/flatpak-builtins-build.c:296 app/flatpak-builtins-build-export.c:887
#, c-format
msgid "Build directory %s not initialized, use flatpak build-init"
msgstr "Build directory %s not initialised, use flatpak build-init"

#: app/flatpak-builtins-build.c:315
msgid "metadata invalid, not application or runtime"
msgstr "metadata invalid, not application or runtime"

#: app/flatpak-builtins-build.c:446
#, c-format
msgid "No extension point matching %s in %s"
msgstr "No extension point matching %s in %s"

#: app/flatpak-builtins-build.c:635
#, c-format
msgid "Missing '=' in bind mount option '%s'"
msgstr "Missing '=' in bind mount option '%s'"

#: app/flatpak-builtins-build.c:679 common/flatpak-run.c:3961
#, c-format
msgid "Unable to start app"
msgstr "Unable to start app"

#: app/flatpak-builtins-build-commit-from.c:58
msgid "Source repo dir"
msgstr "Source repo dir"

#: app/flatpak-builtins-build-commit-from.c:58
msgid "SRC-REPO"
msgstr "SRC-REPO"

#: app/flatpak-builtins-build-commit-from.c:59
msgid "Source repo ref"
msgstr "Source repo ref"

#: app/flatpak-builtins-build-commit-from.c:59
msgid "SRC-REF"
msgstr "SRC-REF"

#: app/flatpak-builtins-build-commit-from.c:64
#: app/flatpak-builtins-build-export.c:60
msgid "One line subject"
msgstr "One line subject"

#: app/flatpak-builtins-build-commit-from.c:64
#: app/flatpak-builtins-build-export.c:60
msgid "SUBJECT"
msgstr "SUBJECT"

#: app/flatpak-builtins-build-commit-from.c:65
#: app/flatpak-builtins-build-export.c:61
msgid "Full description"
msgstr "Full description"

#: app/flatpak-builtins-build-commit-from.c:65
#: app/flatpak-builtins-build-export.c:61
msgid "BODY"
msgstr "BODY"

#: app/flatpak-builtins-build-commit-from.c:66
#: app/flatpak-builtins-build-export.c:64
#: app/flatpak-builtins-build-import-bundle.c:51
msgid "Update the appstream branch"
msgstr "Update the appstream branch"

#: app/flatpak-builtins-build-commit-from.c:67
#: app/flatpak-builtins-build-export.c:65
#: app/flatpak-builtins-build-import-bundle.c:52
#: app/flatpak-builtins-build-update-repo.c:87
msgid "Don't update the summary"
msgstr "Don't update the summary"

#: app/flatpak-builtins-build-commit-from.c:68
#: app/flatpak-builtins-build-export.c:68
#: app/flatpak-builtins-build-import-bundle.c:49
#: app/flatpak-builtins-build-sign.c:44
msgid "GPG Key ID to sign the commit with"
msgstr "GPG Key ID to sign the commit with"

#: app/flatpak-builtins-build-commit-from.c:70
#: app/flatpak-builtins-build-export.c:73
msgid "Mark build as end-of-life"
msgstr "Mark build as end-of-life"

#: app/flatpak-builtins-build-commit-from.c:70
#: app/flatpak-builtins-build-export.c:73
msgid "REASON"
msgstr "REASON"

#: app/flatpak-builtins-build-commit-from.c:71
msgid ""
"Mark refs matching the OLDID prefix as end-of-life, to be replaced with the "
"given NEWID"
msgstr ""
"Mark refs matching the OLDID prefix as end-of-life, to be replaced with the "
"given NEWID"

#: app/flatpak-builtins-build-commit-from.c:71
msgid "OLDID=NEWID"
msgstr "OLDID=NEWID"

#: app/flatpak-builtins-build-commit-from.c:72
#: app/flatpak-builtins-build-export.c:75
msgid "Set type of token needed to install this commit"
msgstr ""

#: app/flatpak-builtins-build-commit-from.c:72
#: app/flatpak-builtins-build-export.c:75
#, fuzzy
msgid "VAL"
msgstr "VALUE"

#: app/flatpak-builtins-build-commit-from.c:73
msgid "Override the timestamp of the commit (NOW for current time)"
msgstr "Override the timestamp of the commit (NOW for current time)"

#: app/flatpak-builtins-build-commit-from.c:73
#: app/flatpak-builtins-build-export.c:76
msgid "TIMESTAMP"
msgstr "TIMESTAMP"

#: app/flatpak-builtins-build-commit-from.c:75
#: app/flatpak-builtins-build-export.c:80
#: app/flatpak-builtins-build-import-bundle.c:53
#: app/flatpak-builtins-build-update-repo.c:97
#, fuzzy
msgid "Don't generate a summary index"
msgstr "Don't update the summary"

#: app/flatpak-builtins-build-commit-from.c:278
msgid "DST-REPO [DST-REF…] - Make a new commit from existing commits"
msgstr "DST-REPO [DST-REF…] - Make a new commit from existing commits"

#: app/flatpak-builtins-build-commit-from.c:285
msgid "DST-REPO must be specified"
msgstr "DST-REPO must be specified"

#: app/flatpak-builtins-build-commit-from.c:293
msgid ""
"If --src-repo is not specified, exactly one destination ref must be specified"
msgstr ""
"If --src-repo is not specified, exactly one destination ref must be specified"

#: app/flatpak-builtins-build-commit-from.c:296
msgid ""
"If --src-ref is specified, exactly one destination ref must be specified"
msgstr ""
"If --src-ref is specified, exactly one destination ref must be specified"

#: app/flatpak-builtins-build-commit-from.c:299
#, fuzzy
msgid "Either --src-repo or --src-ref must be specified"
msgstr "Either --src-repo or --src-ref must be specified."

#: app/flatpak-builtins-build-commit-from.c:315
msgid "Invalid argument format of use  --end-of-life-rebase=OLDID=NEWID"
msgstr "Invalid argument format of use  --end-of-life-rebase=OLDID=NEWID"

#: app/flatpak-builtins-build-commit-from.c:321
#: app/flatpak-builtins-build-commit-from.c:324
#, c-format
msgid "Invalid name %s in --end-of-life-rebase"
msgstr "Invalid name %s in --end-of-life-rebase"

#: app/flatpak-builtins-build-commit-from.c:333
#: app/flatpak-builtins-build-export.c:1092
#, c-format
msgid "Could not parse '%s'"
msgstr "Could not parse '%s'"

#: app/flatpak-builtins-build-commit-from.c:498
#, fuzzy
msgid "Can't commit from partial source commit"
msgstr "Can't commit from partial source commit."

#: app/flatpak-builtins-build-commit-from.c:503
#, c-format
msgid "%s: no change\n"
msgstr "%s: no change\n"

#: app/flatpak-builtins-build-export.c:62
msgid "Architecture to export for (must be host compatible)"
msgstr "Architecture to export for (must be host compatible)"

#: app/flatpak-builtins-build-export.c:63
msgid "Commit runtime (/usr), not /app"
msgstr "Commit runtime (/usr), not /app"

#: app/flatpak-builtins-build-export.c:66
msgid "Use alternative directory for the files"
msgstr "Use alternative directory for the files"

#: app/flatpak-builtins-build-export.c:66
msgid "SUBDIR"
msgstr "SUBDIR"

#: app/flatpak-builtins-build-export.c:69
msgid "Files to exclude"
msgstr "Files to exclude"

#: app/flatpak-builtins-build-export.c:69
#: app/flatpak-builtins-build-export.c:70
#: app/flatpak-builtins-build-update-repo.c:90
msgid "PATTERN"
msgstr "PATTERN"

#: app/flatpak-builtins-build-export.c:70
msgid "Excluded files to include"
msgstr "Excluded files to include"

#: app/flatpak-builtins-build-export.c:74
msgid "Mark build as end-of-life, to be replaced with the given ID"
msgstr "Mark build as end-of-life, to be replaced with the given ID"

#: app/flatpak-builtins-build-export.c:74
#: app/flatpak-builtins-document-list.c:49 app/flatpak-cli-transaction.c:1427
msgid "ID"
msgstr "ID"

#: app/flatpak-builtins-build-export.c:76
msgid "Override the timestamp of the commit"
msgstr "Override the timestamp of the commit"

#: app/flatpak-builtins-build-export.c:77
#: app/flatpak-builtins-build-update-repo.c:75
#: app/flatpak-builtins-remote-add.c:83 app/flatpak-builtins-remote-list.c:54
#: app/flatpak-builtins-remote-modify.c:88
msgid "Collection ID"
msgstr "Collection ID"

#: app/flatpak-builtins-build-export.c:472
#, c-format
msgid "WARNING: Error running desktop-file-validate: %s\n"
msgstr "WARNING: Error running desktop-file-validate: %s\n"

#: app/flatpak-builtins-build-export.c:480
#, c-format
msgid "WARNING: Error reading from desktop-file-validate: %s\n"
msgstr "WARNING: Error reading from desktop-file-validate: %s\n"

#: app/flatpak-builtins-build-export.c:486
#, c-format
msgid "WARNING: Failed to validate desktop file %s: %s\n"
msgstr "WARNING: Failed to validate desktop file %s: %s\n"

#: app/flatpak-builtins-build-export.c:513
#, c-format
msgid "WARNING: Can't find Exec key in %s: %s\n"
msgstr "WARNING: Can't find Exec key in %s: %s\n"

#: app/flatpak-builtins-build-export.c:521
#: app/flatpak-builtins-build-export.c:614
#, c-format
msgid "WARNING: Binary not found for Exec line in %s: %s\n"
msgstr "WARNING: Binary not found for Exec line in %s: %s\n"

#: app/flatpak-builtins-build-export.c:529
#, c-format
msgid "WARNING: Icon not matching app id in %s: %s\n"
msgstr "WARNING: Icon not matching app id in %s: %s\n"

#: app/flatpak-builtins-build-export.c:552
#, c-format
msgid "WARNING: Icon referenced in desktop file but not exported: %s\n"
msgstr "WARNING: Icon referenced in desktop file but not exported: %s\n"

#: app/flatpak-builtins-build-export.c:719
#, c-format
msgid "Invalid uri type %s, only http/https supported"
msgstr "Invalid uri type %s, only http/https supported"

#: app/flatpak-builtins-build-export.c:737
#, c-format
msgid "Unable to find basename in %s, specify a name explicitly"
msgstr "Unable to find basename in %s, specify a name explicitly"

#: app/flatpak-builtins-build-export.c:746
#, c-format
msgid "No slashes allowed in extra data name"
msgstr "No slashes allowed in extra data name"

#: app/flatpak-builtins-build-export.c:758
#, c-format
msgid "Invalid format for sha256 checksum: '%s'"
msgstr "Invalid format for sha256 checksum: '%s'"

#: app/flatpak-builtins-build-export.c:768
#, c-format
msgid "Extra data sizes of zero not supported"
msgstr "Extra data sizes of zero not supported"

#: app/flatpak-builtins-build-export.c:830
msgid ""
"LOCATION DIRECTORY [BRANCH] - Create a repository from a build directory"
msgstr ""
"LOCATION DIRECTORY [BRANCH] - Create a repository from a build directory"

#: app/flatpak-builtins-build-export.c:838
msgid "LOCATION and DIRECTORY must be specified"
msgstr "LOCATION and DIRECTORY must be specified"

#: app/flatpak-builtins-build-export.c:859
#: app/flatpak-builtins-remote-add.c:327
#, c-format
msgid "‘%s’ is not a valid collection ID: %s"
msgstr "‘%s’ is not a valid collection ID: %s"

#: app/flatpak-builtins-build-export.c:904
#: app/flatpak-builtins-build-finish.c:684
msgid "No name specified in the metadata"
msgstr "No name specified in the metadata"

#: app/flatpak-builtins-build-export.c:1166
#, c-format
msgid "Commit: %s\n"
msgstr "Commit: %s\n"

#: app/flatpak-builtins-build-export.c:1167
#, c-format
msgid "Metadata Total: %u\n"
msgstr "Metadata Total: %u\n"

#: app/flatpak-builtins-build-export.c:1168
#, c-format
msgid "Metadata Written: %u\n"
msgstr "Metadata Written: %u\n"

#: app/flatpak-builtins-build-export.c:1169
#, c-format
msgid "Content Total: %u\n"
msgstr "Content Total: %u\n"

#: app/flatpak-builtins-build-export.c:1170
#, c-format
msgid "Content Written: %u\n"
msgstr "Content Written: %u\n"

#: app/flatpak-builtins-build-export.c:1171
#, c-format
msgid "Content Bytes Written:"
msgstr "Content Bytes Written:"

#: app/flatpak-builtins-build-finish.c:52
msgid "Command to set"
msgstr "Command to set"

#: app/flatpak-builtins-build-finish.c:52 app/flatpak-builtins-run.c:159
#: app/flatpak-main.c:209
msgid "COMMAND"
msgstr "COMMAND"

#: app/flatpak-builtins-build-finish.c:53
msgid "Flatpak version to require"
msgstr "Flatpak version to require"

#: app/flatpak-builtins-build-finish.c:53
msgid "MAJOR.MINOR.MICRO"
msgstr "MAJOR.MINOR.MICRO"

#: app/flatpak-builtins-build-finish.c:54
msgid "Don't process exports"
msgstr "Don't process exports"

#: app/flatpak-builtins-build-finish.c:55
msgid "Extra data info"
msgstr "Extra data info"

#: app/flatpak-builtins-build-finish.c:56 app/flatpak-builtins-build-init.c:63
msgid "Add extension point info"
msgstr "Add extension point info"

#: app/flatpak-builtins-build-finish.c:56 app/flatpak-builtins-build-init.c:63
msgid "NAME=VARIABLE[=VALUE]"
msgstr "NAME=VARIABLE[=VALUE]"

#: app/flatpak-builtins-build-finish.c:57
msgid "Remove extension point info"
msgstr "Remove extension point info"

#: app/flatpak-builtins-build-finish.c:57
#: app/flatpak-builtins-build-update-repo.c:79 app/flatpak-builtins-info.c:58
#: app/flatpak-builtins-remote-add.c:88 app/flatpak-builtins-remote-modify.c:94
#: app/flatpak-main.c:182
msgid "NAME"
msgstr "NAME"

#: app/flatpak-builtins-build-finish.c:58
msgid "Set extension priority (only for extensions)"
msgstr "Set extension priority (only for extensions)"

#: app/flatpak-builtins-build-finish.c:58
msgid "VALUE"
msgstr "VALUE"

#: app/flatpak-builtins-build-finish.c:59
msgid "Change the sdk used for the app"
msgstr "Change the sdk used for the app"

#: app/flatpak-builtins-build-finish.c:59
msgid "SDK"
msgstr "SDK"

#: app/flatpak-builtins-build-finish.c:60
msgid "Change the runtime used for the app"
msgstr "Change the runtime used for the app"

#: app/flatpak-builtins-build-finish.c:60 app/flatpak-builtins-build-init.c:54
#: app/flatpak-builtins-list.c:53 app/flatpak-builtins-remote-ls.c:58
#: app/flatpak-builtins-run.c:163
msgid "RUNTIME"
msgstr "RUNTIME"

#: app/flatpak-builtins-build-finish.c:61
msgid "Set generic metadata option"
msgstr "Set generic metadata option"

#: app/flatpak-builtins-build-finish.c:61
msgid "GROUP=KEY[=VALUE]"
msgstr "GROUP=KEY[=VALUE]"

#: app/flatpak-builtins-build-finish.c:62
msgid "Don't inherit permissions from runtime"
msgstr "Don't inherit permissions from runtime"

#: app/flatpak-builtins-build-finish.c:155
#, c-format
msgid "Not exporting %s, wrong extension\n"
msgstr "Not exporting %s, wrong extension\n"

#: app/flatpak-builtins-build-finish.c:163
#, c-format
msgid "Not exporting %s, non-allowed export filename\n"
msgstr "Not exporting %s, non-allowed export filename\n"

#: app/flatpak-builtins-build-finish.c:167
#, c-format
msgid "Exporting %s\n"
msgstr "Exporting %s\n"

#: app/flatpak-builtins-build-finish.c:440
#, c-format
msgid "More than one executable found\n"
msgstr "More than one executable found\n"

#: app/flatpak-builtins-build-finish.c:451
#, c-format
msgid "Using %s as command\n"
msgstr "Using %s as command\n"

#: app/flatpak-builtins-build-finish.c:456
#, c-format
msgid "No executable found\n"
msgstr "No executable found\n"

#: app/flatpak-builtins-build-finish.c:511
#, c-format
msgid "Invalid --require-version argument: %s"
msgstr "Invalid --require-version argument: %s"

#: app/flatpak-builtins-build-finish.c:543
#, c-format
msgid "Too few elements in --extra-data argument %s"
msgstr "Too few elements in --extra-data argument %s"

#: app/flatpak-builtins-build-finish.c:575
#, c-format
msgid ""
"Too few elements in --metadata argument %s, format should be "
"GROUP=KEY[=VALUE]]"
msgstr ""
"Too few elements in --metadata argument %s, format should be "
"GROUP=KEY[=VALUE]]"

#: app/flatpak-builtins-build-finish.c:597
#: app/flatpak-builtins-build-init.c:458
#, c-format
msgid ""
"Too few elements in --extension argument %s, format should be "
"NAME=VAR[=VALUE]"
msgstr ""
"Too few elements in --extension argument %s, format should be "
"NAME=VAR[=VALUE]"

#: app/flatpak-builtins-build-finish.c:603
#: app/flatpak-builtins-build-init.c:461
#, fuzzy, c-format
msgid "Invalid extension name %s"
msgstr "Invalid dbus name %s"

#: app/flatpak-builtins-build-finish.c:646
msgid "DIRECTORY - Finalize a build directory"
msgstr "DIRECTORY - Finalise a build directory"

#: app/flatpak-builtins-build-finish.c:668
#, c-format
msgid "Build directory %s not initialized"
msgstr "Build directory %s not initialised"

#: app/flatpak-builtins-build-finish.c:689
#, c-format
msgid "Build directory %s already finalized"
msgstr "Build directory %s already finalised"

#: app/flatpak-builtins-build-finish.c:702
#, c-format
msgid "Please review the exported files and the metadata\n"
msgstr "Please review the exported files and the metadata\n"

#: app/flatpak-builtins-build-import-bundle.c:47
msgid "Override the ref used for the imported bundle"
msgstr "Override the ref used for the imported bundle"

#: app/flatpak-builtins-build-import-bundle.c:47
msgid "REF"
msgstr "REF"

#: app/flatpak-builtins-build-import-bundle.c:48
msgid "Import oci image instead of flatpak bundle"
msgstr "Import oci image instead of flatpak bundle"

#: app/flatpak-builtins-build-import-bundle.c:77
#: app/flatpak-builtins-build-import-bundle.c:105
#, c-format
msgid "Importing %s (%s)\n"
msgstr "Importing %s (%s)\n"

#: app/flatpak-builtins-build-import-bundle.c:126
msgid "LOCATION FILENAME - Import a file bundle into a local repository"
msgstr "LOCATION FILENAME - Import a file bundle into a local repository"

#: app/flatpak-builtins-build-import-bundle.c:133
msgid "LOCATION and FILENAME must be specified"
msgstr "LOCATION and FILENAME must be specified"

#: app/flatpak-builtins-build-init.c:53 app/flatpak-builtins-info.c:55
#: app/flatpak-builtins-run.c:158
msgid "Arch to use"
msgstr "Arch to use"

#: app/flatpak-builtins-build-init.c:54
msgid "Initialize var from named runtime"
msgstr "Initialise var from named runtime"

#: app/flatpak-builtins-build-init.c:55
msgid "Initialize apps from named app"
msgstr "Initialise apps from named app"

#: app/flatpak-builtins-build-init.c:55
msgid "APP"
msgstr "APP"

#: app/flatpak-builtins-build-init.c:56
msgid "Specify version for --base"
msgstr "Specify version for --base"

#: app/flatpak-builtins-build-init.c:56 app/flatpak-builtins-run.c:164
msgid "VERSION"
msgstr "VERSION"

#: app/flatpak-builtins-build-init.c:57
msgid "Include this base extension"
msgstr "Include this base extension"

#: app/flatpak-builtins-build-init.c:57 app/flatpak-builtins-build-init.c:62
msgid "EXTENSION"
msgstr "EXTENSION"

#: app/flatpak-builtins-build-init.c:58
msgid "Extension tag to use if building extension"
msgstr "Extension tag to use if building extension"

#: app/flatpak-builtins-build-init.c:58
msgid "EXTENSION_TAG"
msgstr "EXTENSION_TAG"

#: app/flatpak-builtins-build-init.c:59
msgid "Initialize /usr with a writable copy of the sdk"
msgstr "Initialise /usr with a writable copy of the sdk"

#: app/flatpak-builtins-build-init.c:60
msgid "Specify the build type (app, runtime, extension)"
msgstr "Specify the build type (app, runtime, extension)"

#: app/flatpak-builtins-build-init.c:60
msgid "TYPE"
msgstr "TYPE"

#: app/flatpak-builtins-build-init.c:61
msgid "Add a tag"
msgstr "Add a tag"

#: app/flatpak-builtins-build-init.c:61
msgid "TAG"
msgstr "TAG"

#: app/flatpak-builtins-build-init.c:62
msgid "Include this sdk extension in /usr"
msgstr "Include this sdk extension in /usr"

#: app/flatpak-builtins-build-init.c:64
msgid "Where to store sdk (defaults to 'usr')"
msgstr "Where to store sdk (defaults to 'usr')"

#: app/flatpak-builtins-build-init.c:65
msgid "Re-initialize the sdk/var"
msgstr "Re-initialise the sdk/var"

#: app/flatpak-builtins-build-init.c:118
#, fuzzy, c-format
msgid "Requested extension %s/%s/%s is only partially installed"
msgstr "Requested extension %s is only partially installed"

#: app/flatpak-builtins-build-init.c:147
#, fuzzy, c-format
msgid "Requested extension %s/%s/%s not installed"
msgstr "Requested extension %s not installed"

#: app/flatpak-builtins-build-init.c:207
msgid ""
"DIRECTORY APPNAME SDK RUNTIME [BRANCH] - Initialize a directory for building"
msgstr ""
"DIRECTORY APPNAME SDK RUNTIME [BRANCH] - Initialise a directory for building"

#: app/flatpak-builtins-build-init.c:214
msgid "RUNTIME must be specified"
msgstr "RUNTIME must be specified"

#: app/flatpak-builtins-build-init.c:235
#, c-format
msgid "'%s' is not a valid build type name, use app, runtime or extension"
msgstr "'%s' is not a valid build type name, use app, runtime or extension"

#: app/flatpak-builtins-build-init.c:241 app/flatpak-builtins-override.c:79
#, c-format
msgid "'%s' is not a valid application name: %s"
msgstr "'%s' is not a valid application name: %s"

#: app/flatpak-builtins-build-init.c:295
#, c-format
msgid "Build directory %s already initialized"
msgstr "Build directory %s already initialised"

#: app/flatpak-builtins-build-sign.c:42 app/flatpak-builtins-install.c:67
#: app/flatpak-builtins-remote-info.c:54
msgid "Arch to install for"
msgstr "Arch to install for"

#: app/flatpak-builtins-build-sign.c:43 app/flatpak-builtins-create-usb.c:48
#: app/flatpak-builtins-install.c:74 app/flatpak-builtins-remote-info.c:56
#: app/flatpak-builtins-uninstall.c:58 app/flatpak-builtins-update.c:64
msgid "Look for runtime with the specified name"
msgstr "Look for runtime with the specified name"

#: app/flatpak-builtins-build-sign.c:66
msgid "LOCATION [ID [BRANCH]] - Sign an application or runtime"
msgstr "LOCATION [ID [BRANCH]] - Sign an application or runtime"

#: app/flatpak-builtins-build-sign.c:73
#: app/flatpak-builtins-build-update-repo.c:499
#: app/flatpak-builtins-remote-add.c:320 app/flatpak-builtins-repo.c:739
msgid "LOCATION must be specified"
msgstr "LOCATION must be specified"

#: app/flatpak-builtins-build-sign.c:94
msgid "No gpg key ids specified"
msgstr "No gpg key ids specified"

#: app/flatpak-builtins-build-update-repo.c:68
msgid "Redirect this repo to a new URL"
msgstr "Redirect this repo to a new URL"

#: app/flatpak-builtins-build-update-repo.c:69
msgid "A nice name to use for this repository"
msgstr "A nice name to use for this repository"

#: app/flatpak-builtins-build-update-repo.c:69
#: app/flatpak-builtins-remote-add.c:77 app/flatpak-builtins-remote-modify.c:82
msgid "TITLE"
msgstr "TITLE"

#: app/flatpak-builtins-build-update-repo.c:70
msgid "A one-line comment for this repository"
msgstr "A one-line comment for this repository"

#: app/flatpak-builtins-build-update-repo.c:70
#: app/flatpak-builtins-remote-add.c:78 app/flatpak-builtins-remote-modify.c:83
msgid "COMMENT"
msgstr "COMMENT"

#: app/flatpak-builtins-build-update-repo.c:71
msgid "A full-paragraph description for this repository"
msgstr "A full-paragraph description for this repository"

#: app/flatpak-builtins-build-update-repo.c:71
#: app/flatpak-builtins-remote-add.c:79 app/flatpak-builtins-remote-modify.c:84
msgid "DESCRIPTION"
msgstr "DESCRIPTION"

#: app/flatpak-builtins-build-update-repo.c:72
msgid "URL for a website for this repository"
msgstr "URL for a website for this repository"

#: app/flatpak-builtins-build-update-repo.c:73
msgid "URL for an icon for this repository"
msgstr "URL for an icon for this repository"

#: app/flatpak-builtins-build-update-repo.c:74
msgid "Default branch to use for this repository"
msgstr "Default branch to use for this repository"

#: app/flatpak-builtins-build-update-repo.c:74
#: app/flatpak-builtins-remote-add.c:82 app/flatpak-builtins-remote-modify.c:87
#: app/flatpak-builtins-repo.c:713 app/flatpak-builtins-repo.c:714
#: app/flatpak-builtins-run.c:161
msgid "BRANCH"
msgstr "BRANCH"

#: app/flatpak-builtins-build-update-repo.c:75
#: app/flatpak-builtins-remote-add.c:83 app/flatpak-builtins-remote-modify.c:88
msgid "COLLECTION-ID"
msgstr "COLLECTION-ID"

#. Translators: A sideload is when you install from a local USB drive rather than the Internet.
#: app/flatpak-builtins-build-update-repo.c:77
#, fuzzy
msgid ""
"Permanently deploy collection ID to client remote configurations, only for "
"sideload support"
msgstr "Permanently deploy collection ID to client remote configurations"

#: app/flatpak-builtins-build-update-repo.c:78
msgid "Permanently deploy collection ID to client remote configurations"
msgstr "Permanently deploy collection ID to client remote configurations"

#: app/flatpak-builtins-build-update-repo.c:79
#, fuzzy
msgid "Name of authenticator for this repository"
msgstr "URL for an icon for this repository"

#: app/flatpak-builtins-build-update-repo.c:80
#, fuzzy
msgid "Autoinstall authenticator for this repository"
msgstr "URL for an icon for this repository"

#: app/flatpak-builtins-build-update-repo.c:81
#, fuzzy
msgid "Don't autoinstall authenticator for this repository"
msgstr "Default branch to use for this repository"

#: app/flatpak-builtins-build-update-repo.c:82
#: app/flatpak-builtins-remote-add.c:89
#, fuzzy
msgid "Authenticator option"
msgstr "Show options"

#: app/flatpak-builtins-build-update-repo.c:82
#: app/flatpak-builtins-remote-add.c:89 app/flatpak-builtins-remote-modify.c:95
#, fuzzy
msgid "KEY=VALUE"
msgstr "VALUE"

#: app/flatpak-builtins-build-update-repo.c:83
msgid "Import new default GPG public key from FILE"
msgstr "Import new default GPG public key from FILE"

#: app/flatpak-builtins-build-update-repo.c:84
msgid "GPG Key ID to sign the summary with"
msgstr "GPG Key ID to sign the summary with"

#: app/flatpak-builtins-build-update-repo.c:86
msgid "Generate delta files"
msgstr "Generate delta files"

#: app/flatpak-builtins-build-update-repo.c:88
msgid "Don't update the appstream branch"
msgstr "Don't update the appstream branch"

#: app/flatpak-builtins-build-update-repo.c:89
msgid "Max parallel jobs when creating deltas (default: NUMCPUs)"
msgstr "Max parallel jobs when creating deltas (default: NUMCPUs)"

#: app/flatpak-builtins-build-update-repo.c:89
msgid "NUM-JOBS"
msgstr "NUM-JOBS"

#: app/flatpak-builtins-build-update-repo.c:90
msgid "Don't create deltas matching refs"
msgstr "Don't create deltas matching refs"

#: app/flatpak-builtins-build-update-repo.c:91
msgid "Prune unused objects"
msgstr "Prune unused objects"

#: app/flatpak-builtins-build-update-repo.c:92
msgid "Prune but don't actually remove anything"
msgstr ""

#: app/flatpak-builtins-build-update-repo.c:93
msgid "Only traverse DEPTH parents for each commit (default: -1=infinite)"
msgstr "Only traverse DEPTH parents for each commit (default: -1=infinite)"

#: app/flatpak-builtins-build-update-repo.c:93
msgid "DEPTH"
msgstr "DEPTH"

#: app/flatpak-builtins-build-update-repo.c:223
#, c-format
msgid "Generating delta: %s (%.10s)\n"
msgstr "Generating delta: %s (%.10s)\n"

#: app/flatpak-builtins-build-update-repo.c:225
#, c-format
msgid "Generating delta: %s (%.10s-%.10s)\n"
msgstr "Generating delta: %s (%.10s-%.10s)\n"

#: app/flatpak-builtins-build-update-repo.c:233
#, c-format
msgid "Failed to generate delta %s (%.10s): "
msgstr "Failed to generate delta %s (%.10s): "

#: app/flatpak-builtins-build-update-repo.c:236
#, c-format
msgid "Failed to generate delta %s (%.10s-%.10s): "
msgstr "Failed to generate delta %s (%.10s-%.10s): "

#: app/flatpak-builtins-build-update-repo.c:492
msgid "LOCATION - Update repository metadata"
msgstr "LOCATION - Update repository metadata"

#: app/flatpak-builtins-build-update-repo.c:609
#, c-format
msgid "Updating appstream branch\n"
msgstr "Updating appstream branch\n"

#: app/flatpak-builtins-build-update-repo.c:638
#, c-format
msgid "Updating summary\n"
msgstr "Updating summary\n"

#: app/flatpak-builtins-build-update-repo.c:664
#, c-format
msgid "Total objects: %u\n"
msgstr "Total objects: %u\n"

#: app/flatpak-builtins-build-update-repo.c:666
#, c-format
msgid "No unreachable objects\n"
msgstr "No unreachable objects\n"

#: app/flatpak-builtins-build-update-repo.c:668
#, c-format
msgid "Deleted %u objects, %s freed\n"
msgstr "Deleted %u objects, %s freed\n"

#: app/flatpak-builtins-config.c:41
msgid "List configuration keys and values"
msgstr "List configuration keys and values"

#: app/flatpak-builtins-config.c:42
msgid "Get configuration for KEY"
msgstr "Get configuration for KEY"

#: app/flatpak-builtins-config.c:43
msgid "Set configuration for KEY to VALUE"
msgstr "Set configuration for KEY to VALUE"

#: app/flatpak-builtins-config.c:44
msgid "Unset configuration for KEY"
msgstr "Unset configuration for KEY"

#: app/flatpak-builtins-config.c:149
#, fuzzy, c-format
msgid "'%s' does not look like a language/locale code"
msgstr "'%s' does not look like a language code"

#: app/flatpak-builtins-config.c:172
#, c-format
msgid "'%s' does not look like a language code"
msgstr "'%s' does not look like a language code"

#: app/flatpak-builtins-config.c:190
#, fuzzy, c-format
msgid "'%s' is not a valid value (use 'true' or 'false')"
msgstr "'%s' is not a valid repository: "

#: app/flatpak-builtins-config.c:262
#, c-format
msgid "Unknown configure key '%s'"
msgstr "Unknown configure key '%s'"

#: app/flatpak-builtins-config.c:284
msgid "Too many arguments for --list"
msgstr "Too many arguments for --list"

#: app/flatpak-builtins-config.c:314 app/flatpak-builtins-config.c:362
msgid "You must specify KEY"
msgstr "You must specify KEY"

#: app/flatpak-builtins-config.c:316
msgid "Too many arguments for --get"
msgstr "Too many arguments for --get"

#: app/flatpak-builtins-config.c:338
msgid "You must specify KEY and VALUE"
msgstr "You must specify KEY and VALUE"

#: app/flatpak-builtins-config.c:340
msgid "Too many arguments for --set"
msgstr "Too many arguments for --set"

#: app/flatpak-builtins-config.c:364
msgid "Too many arguments for --unset"
msgstr "Too many arguments for --unset"

#: app/flatpak-builtins-config.c:383
msgid "[KEY [VALUE]] - Manage configuration"
msgstr "[KEY [VALUE]] - Manage configuration"

#: app/flatpak-builtins-config.c:394
msgid "Can only use one of --list, --get, --set or --unset"
msgstr "Can only use one of --list, --get, --set or --unset"

#: app/flatpak-builtins-config.c:408
msgid "Must specify one of --list, --get, --set or --unset"
msgstr "Must specify one of --list, --get, --set or --unset"

#: app/flatpak-builtins-create-usb.c:45 app/flatpak-builtins-install.c:75
#: app/flatpak-builtins-remote-info.c:57 app/flatpak-builtins-uninstall.c:59
#: app/flatpak-builtins-update.c:65
msgid "Look for app with the specified name"
msgstr "Look for app with the specified name"

#: app/flatpak-builtins-create-usb.c:46
msgid "Arch to copy"
msgstr "Arch to copy"

#: app/flatpak-builtins-create-usb.c:47
msgid "DEST"
msgstr "DEST"

#: app/flatpak-builtins-create-usb.c:49
msgid "Allow partial commits in the created repo"
msgstr ""

#: app/flatpak-builtins-create-usb.c:125 app/flatpak-builtins-create-usb.c:165
#, fuzzy, c-format
msgid ""
"Warning: Related ref ‘%s’ is partially installed. Use --allow-partial to "
"suppress this message.\n"
msgstr "Warning: Omitting related ref ‘%s’ because it is not installed.\n"

#: app/flatpak-builtins-create-usb.c:158
#, c-format
msgid "Warning: Omitting related ref ‘%s’ because it is not installed.\n"
msgstr "Warning: Omitting related ref ‘%s’ because it is not installed.\n"

#: app/flatpak-builtins-create-usb.c:175
#, c-format
msgid ""
"Warning: Omitting related ref ‘%s’ because its remote ‘%s’ does not have a "
"collection ID set.\n"
msgstr ""
"Warning: Omitting related ref ‘%s’ because its remote ‘%s’ does not have a "
"collection ID set.\n"

#: app/flatpak-builtins-create-usb.c:187
#, fuzzy, c-format
msgid "Warning: Omitting related ref ‘%s’ because it's extra-data.\n"
msgstr "Warning: Omitting related ref ‘%s’ because it is not installed.\n"

#: app/flatpak-builtins-create-usb.c:262 app/flatpak-builtins-create-usb.c:637
#, c-format
msgid ""
"Remote ‘%s’ does not have a collection ID set, which is required for P2P "
"distribution of ‘%s’."
msgstr ""
"Remote ‘%s’ does not have a collection ID set, which is required for P2P "
"distribution of ‘%s’."

#: app/flatpak-builtins-create-usb.c:272
#, fuzzy, c-format
msgid "Warning: Omitting ref ‘%s’ (runtime of ‘%s’) because it's extra-data.\n"
msgstr "Warning: Omitting related ref ‘%s’ because it is not installed.\n"

#: app/flatpak-builtins-create-usb.c:484
msgid "MOUNT-PATH [REF…] - Copy apps or runtimes onto removable media"
msgstr "MOUNT-PATH [REF…] - Copy apps or runtimes onto removable media"

#: app/flatpak-builtins-create-usb.c:493
msgid "MOUNT-PATH and REF must be specified"
msgstr "MOUNT-PATH and REF must be specified"

#: app/flatpak-builtins-create-usb.c:607
#, c-format
msgid "Ref ‘%s’ found in multiple installations: %s. You must specify one."
msgstr "Ref ‘%s’ found in multiple installations: %s. You must specify one."

#: app/flatpak-builtins-create-usb.c:620
#, c-format
msgid "Refs must all be in the same installation (found in %s and %s)."
msgstr "Refs must all be in the same installation (found in %s and %s)."

#: app/flatpak-builtins-create-usb.c:670
#, c-format
msgid ""
"Warning: Ref ‘%s’ is partially installed. Use --allow-partial to suppress "
"this message.\n"
msgstr ""

#: app/flatpak-builtins-create-usb.c:681
#, c-format
msgid "Installed ref ‘%s’ is extra-data, and cannot be distributed offline"
msgstr ""

#: app/flatpak-builtins-create-usb.c:721
#, c-format
msgid "Warning: Couldn't update repo metadata for remote ‘%s’: %s\n"
msgstr "Warning: Couldn't update repo metadata for remote ‘%s’: %s\n"

#: app/flatpak-builtins-create-usb.c:751
#, c-format
msgid "Warning: Couldn't update appstream data for remote ‘%s’ arch ‘%s’: %s\n"
msgstr ""
"Warning: Couldn't update appstream data for remote ‘%s’ arch ‘%s’: %s\n"

#. Print a warning if both appstream and appstream2 are missing
#: app/flatpak-builtins-create-usb.c:784
#, c-format
msgid ""
"Warning: Couldn't find appstream data for remote ‘%s’ arch ‘%s’: %s; %s\n"
msgstr ""
"Warning: Couldn't find appstream data for remote ‘%s’ arch ‘%s’: %s; %s\n"

#. Appstream2 is only for efficiency, so just print a debug message
#: app/flatpak-builtins-create-usb.c:790
#, c-format
msgid "Couldn't find appstream2 data for remote ‘%s’ arch ‘%s’: %s\n"
msgstr "Couldn't find appstream2 data for remote ‘%s’ arch ‘%s’: %s\n"

#: app/flatpak-builtins-document-export.c:62
msgid "Create a unique document reference"
msgstr "Create a unique document reference"

#: app/flatpak-builtins-document-export.c:63
msgid "Make the document transient for the current session"
msgstr "Make the document transient for the current session"

#: app/flatpak-builtins-document-export.c:64
msgid "Don't require the file to exist already"
msgstr "Don't require the file to exist already"

#: app/flatpak-builtins-document-export.c:65
msgid "Give the app read permissions"
msgstr "Give the app read permissions"

#: app/flatpak-builtins-document-export.c:66
msgid "Give the app write permissions"
msgstr "Give the app write permissions"

#: app/flatpak-builtins-document-export.c:67
msgid "Give the app delete permissions"
msgstr "Give the app delete permissions"

#: app/flatpak-builtins-document-export.c:68
msgid "Give the app permissions to grant further permissions"
msgstr "Give the app permissions to grant further permissions"

#: app/flatpak-builtins-document-export.c:69
msgid "Revoke read permissions of the app"
msgstr "Revoke read permissions of the app"

#: app/flatpak-builtins-document-export.c:70
msgid "Revoke write permissions of the app"
msgstr "Revoke write permissions of the app"

#: app/flatpak-builtins-document-export.c:71
msgid "Revoke delete permissions of the app"
msgstr "Revoke delete permissions of the app"

#: app/flatpak-builtins-document-export.c:72
msgid "Revoke the permission to grant further permissions"
msgstr "Revoke the permission to grant further permissions"

#: app/flatpak-builtins-document-export.c:73
msgid "Add permissions for this app"
msgstr "Add permissions for this app"

#: app/flatpak-builtins-document-export.c:73
msgid "APPID"
msgstr "APPID"

#: app/flatpak-builtins-document-export.c:100
msgid "FILE - Export a file to apps"
msgstr "FILE - Export a file to apps"

#: app/flatpak-builtins-document-export.c:109
#: app/flatpak-builtins-document-info.c:72
#: app/flatpak-builtins-document-unexport.c:67
msgid "FILE must be specified"
msgstr "FILE must be specified"

#: app/flatpak-builtins-document-info.c:63
msgid "FILE - Get information about an exported file"
msgstr "FILE - Get information about an exported file"

#: app/flatpak-builtins-document-info.c:100
#: app/flatpak-builtins-document-unexport.c:94
#, c-format
msgid "Not exported\n"
msgstr "Not exported\n"

#: app/flatpak-builtins-document-list.c:43 app/flatpak-builtins-history.c:53
#: app/flatpak-builtins-list.c:54 app/flatpak-builtins-ps.c:43
#: app/flatpak-builtins-remote-list.c:45 app/flatpak-builtins-remote-ls.c:59
#: app/flatpak-builtins-search.c:38
msgid "What information to show"
msgstr "What information to show"

#: app/flatpak-builtins-document-list.c:43 app/flatpak-builtins-history.c:53
#: app/flatpak-builtins-list.c:54 app/flatpak-builtins-ps.c:43
#: app/flatpak-builtins-remote-list.c:45 app/flatpak-builtins-remote-ls.c:59
#: app/flatpak-builtins-search.c:38
msgid "FIELD,…"
msgstr "FIELD,…"

#: app/flatpak-builtins-document-list.c:44 app/flatpak-builtins-history.c:54
#: app/flatpak-builtins-list.c:52 app/flatpak-builtins-permission-list.c:43
#: app/flatpak-builtins-permission-show.c:43 app/flatpak-builtins-ps.c:44
#: app/flatpak-builtins-remote-list.c:46 app/flatpak-builtins-remote-ls.c:63
#: app/flatpak-builtins-repo.c:717 app/flatpak-builtins-search.c:39
#, fuzzy
msgid "Show output in JSON format"
msgstr "Show extra information"

#: app/flatpak-builtins-document-list.c:49
msgid "Show the document ID"
msgstr "Show the document ID"

#: app/flatpak-builtins-document-list.c:50
msgid "Path"
msgstr "Path"

#: app/flatpak-builtins-document-list.c:50
#: app/flatpak-builtins-document-list.c:51
msgid "Show the document path"
msgstr "Show the document path"

#: app/flatpak-builtins-document-list.c:51 app/flatpak-builtins-list.c:66
#: app/flatpak-builtins-remote-ls.c:74
msgid "Origin"
msgstr "Origin"

#: app/flatpak-builtins-document-list.c:52 app/flatpak-builtins-history.c:62
#: app/flatpak-builtins-ps.c:52
msgid "Application"
msgstr "Application"

#: app/flatpak-builtins-document-list.c:52
msgid "Show applications with permission"
msgstr "Show applications with permission"

#: app/flatpak-builtins-document-list.c:53
#: app/flatpak-builtins-permission-list.c:182
#: app/flatpak-builtins-permission-show.c:145
msgid "Permissions"
msgstr "Permissions"

#: app/flatpak-builtins-document-list.c:53
msgid "Show permissions for applications"
msgstr "Show permissions for applications"

#: app/flatpak-builtins-document-list.c:161
#, fuzzy, c-format
msgid "No documents found\n"
msgstr "No matches found"

#: app/flatpak-builtins-document-list.c:180
msgid "[APPID] - List exported files"
msgstr "[APPID] - List exported files"

#: app/flatpak-builtins-document-unexport.c:43
#, fuzzy
msgid "Specify the document ID"
msgstr "Show the document ID"

#: app/flatpak-builtins-document-unexport.c:58
msgid "FILE - Unexport a file to apps"
msgstr "FILE - Unexport a file to apps"

#: app/flatpak-builtins-enter.c:88
#, fuzzy
msgid "INSTANCE COMMAND [ARGUMENT…] - Run a command inside a running sandbox"
msgstr ""
"INSTANCE [COMMAND [ARGUMENT…]] - Run a command inside a running sandbox"

#: app/flatpak-builtins-enter.c:111
msgid "INSTANCE and COMMAND must be specified"
msgstr "INSTANCE and COMMAND must be specified"

#: app/flatpak-builtins-enter.c:138
#, fuzzy, c-format
msgid "%s is neither a pid nor an application or instance ID"
msgstr "%s is neither a pid nor an application or instance ID"

#: app/flatpak-builtins-enter.c:144
msgid "entering not supported (need unprivileged user namespaces, or sudo -E)"
msgstr ""

#: app/flatpak-builtins-enter.c:145
#, c-format
msgid "No such pid %s"
msgstr "No such pid %s"

#: app/flatpak-builtins-enter.c:158
msgid "Can't read cwd"
msgstr "Can't read cwd"

#: app/flatpak-builtins-enter.c:163
msgid "Can't read root"
msgstr "Can't read root"

#: app/flatpak-builtins-enter.c:191
#, c-format
msgid "Invalid %s namespace for pid %d"
msgstr "Invalid %s namespace for pid %d"

#: app/flatpak-builtins-enter.c:202
#, c-format
msgid "Invalid %s namespace for self"
msgstr "Invalid %s namespace for self"

#: app/flatpak-builtins-enter.c:216
#, c-format
msgid "Can't open %s namespace: %s"
msgstr "Can't open %s namespace: %s"

#: app/flatpak-builtins-enter.c:226
msgid "entering not supported (need unprivileged user namespaces)"
msgstr ""

#: app/flatpak-builtins-enter.c:227
#, c-format
msgid "Can't enter %s namespace: %s"
msgstr "Can't enter %s namespace: %s"

#: app/flatpak-builtins-enter.c:234
msgid "Can't chdir"
msgstr "Can't chdir"

#: app/flatpak-builtins-enter.c:237
msgid "Can't chroot"
msgstr "Can't chroot"

#: app/flatpak-builtins-enter.c:240
msgid "Can't switch gid"
msgstr "Can't switch gid"

#: app/flatpak-builtins-enter.c:243
msgid "Can't switch uid"
msgstr "Can't switch uid"

#: app/flatpak-builtins-history.c:50
msgid "Only show changes after TIME"
msgstr "Only show changes after TIME"

#: app/flatpak-builtins-history.c:50 app/flatpak-builtins-history.c:51
msgid "TIME"
msgstr "TIME"

#: app/flatpak-builtins-history.c:51
msgid "Only show changes before TIME"
msgstr "Only show changes before TIME"

#: app/flatpak-builtins-history.c:52
msgid "Show newest entries first"
msgstr "Show newest entries first"

#: app/flatpak-builtins-history.c:59
msgid "Time"
msgstr "Time"

#: app/flatpak-builtins-history.c:59
msgid "Show when the change happened"
msgstr "Show when the change happened"

#: app/flatpak-builtins-history.c:60
msgid "Change"
msgstr "Change"

#: app/flatpak-builtins-history.c:60
msgid "Show the kind of change"
msgstr "Show the kind of change"

#: app/flatpak-builtins-history.c:61 app/flatpak-builtins-list.c:68
#: app/flatpak-builtins-remote-ls.c:75 app/flatpak-builtins-repo.c:335
msgid "Ref"
msgstr "Ref"

#: app/flatpak-builtins-history.c:61 app/flatpak-builtins-list.c:68
#: app/flatpak-builtins-remote-ls.c:75
msgid "Show the ref"
msgstr "Show the ref"

#: app/flatpak-builtins-history.c:62
msgid "Show the application/runtime ID"
msgstr "Show the application/runtime ID"

#: app/flatpak-builtins-history.c:63 app/flatpak-builtins-list.c:64
#: app/flatpak-builtins-ps.c:53 app/flatpak-builtins-remote-ls.c:73
#: app/flatpak-cli-transaction.c:1435
msgid "Arch"
msgstr "Arch"

#: app/flatpak-builtins-history.c:63 app/flatpak-builtins-list.c:64
#: app/flatpak-builtins-ps.c:53 app/flatpak-builtins-remote-ls.c:73
msgid "Show the architecture"
msgstr "Show the architecture"

#: app/flatpak-builtins-history.c:64 app/flatpak-builtins-list.c:63
#: app/flatpak-builtins-ps.c:54 app/flatpak-builtins-remote-ls.c:72
#: app/flatpak-builtins-search.c:48 app/flatpak-cli-transaction.c:1438
msgid "Branch"
msgstr "Branch"

#: app/flatpak-builtins-history.c:64 app/flatpak-builtins-list.c:63
#: app/flatpak-builtins-remote-ls.c:72
msgid "Show the branch"
msgstr "Show the branch"

#: app/flatpak-builtins-history.c:65 app/flatpak-builtins-list.c:67
msgid "Installation"
msgstr "Installation"

#: app/flatpak-builtins-history.c:65
msgid "Show the affected installation"
msgstr "Show the affected installation"

#: app/flatpak-builtins-history.c:66 app/flatpak-cli-transaction.c:1452
msgid "Remote"
msgstr "Remote"

#: app/flatpak-builtins-history.c:66
msgid "Show the remote"
msgstr "Show the remote"

#: app/flatpak-builtins-history.c:67 app/flatpak-builtins-ps.c:55
#: app/flatpak-builtins-remote-ls.c:76
msgid "Commit"
msgstr "Commit"

#: app/flatpak-builtins-history.c:67
msgid "Show the current commit"
msgstr "Show the current commit"

#: app/flatpak-builtins-history.c:68
msgid "Old Commit"
msgstr "Old Commit"

#: app/flatpak-builtins-history.c:68
msgid "Show the previous commit"
msgstr "Show the previous commit"

#: app/flatpak-builtins-history.c:69
msgid "Show the remote URL"
msgstr "Show the remote URL"

#: app/flatpak-builtins-history.c:70 app/flatpak-cli-transaction.c:700
msgid "User"
msgstr "User"

#: app/flatpak-builtins-history.c:70
msgid "Show the user doing the change"
msgstr "Show the user doing the change"

#: app/flatpak-builtins-history.c:71
msgid "Tool"
msgstr "Tool"

#: app/flatpak-builtins-history.c:71
msgid "Show the tool that was used"
msgstr "Show the tool that was used"

#: app/flatpak-builtins-history.c:72 app/flatpak-builtins-list.c:62
#: app/flatpak-builtins-remote-ls.c:71 app/flatpak-builtins-search.c:47
msgid "Version"
msgstr "Version"

#: app/flatpak-builtins-history.c:72
msgid "Show the Flatpak version"
msgstr "Show the Flatpak version"

#: app/flatpak-builtins-history.c:91
#, c-format
msgid "Failed to get journal data (%s): %s"
msgstr "Failed to get journal data (%s): %s"

#: app/flatpak-builtins-history.c:146
#, c-format
msgid "Failed to open journal: %s"
msgstr "Failed to open journal: %s"

#: app/flatpak-builtins-history.c:153
#, c-format
msgid "Failed to add match to journal: %s"
msgstr "Failed to add match to journal: %s"

#: app/flatpak-builtins-history.c:471
msgid " - Show history"
msgstr " - Show history"

#: app/flatpak-builtins-history.c:490
#, c-format
msgid "Failed to parse the --since option"
msgstr "Failed to parse the --since option"

#: app/flatpak-builtins-history.c:501
#, c-format
msgid "Failed to parse the --until option"
msgstr "Failed to parse the --until option"

#: app/flatpak-builtins-info.c:56
msgid "Show user installations"
msgstr "Show user installations"

#: app/flatpak-builtins-info.c:57
msgid "Show system-wide installations"
msgstr "Show system-wide installations"

#: app/flatpak-builtins-info.c:58
msgid "Show specific system-wide installations"
msgstr "Show specific system-wide installations"

#: app/flatpak-builtins-info.c:59 app/flatpak-builtins-remote-info.c:59
msgid "Show ref"
msgstr "Show ref"

#: app/flatpak-builtins-info.c:60 app/flatpak-builtins-remote-info.c:60
msgid "Show commit"
msgstr "Show commit"

#: app/flatpak-builtins-info.c:61
msgid "Show origin"
msgstr "Show origin"

#: app/flatpak-builtins-info.c:62
msgid "Show size"
msgstr "Show size"

#: app/flatpak-builtins-info.c:63 app/flatpak-builtins-remote-info.c:62
msgid "Show metadata"
msgstr "Show metadata"

#: app/flatpak-builtins-info.c:64 app/flatpak-builtins-remote-info.c:63
msgid "Show runtime"
msgstr "Show runtime"

#: app/flatpak-builtins-info.c:65 app/flatpak-builtins-remote-info.c:64
msgid "Show sdk"
msgstr "Show sdk"

#: app/flatpak-builtins-info.c:66
msgid "Show permissions"
msgstr "Show permissions"

#: app/flatpak-builtins-info.c:67
msgid "Query file access"
msgstr "Query file access"

#: app/flatpak-builtins-info.c:67 app/flatpak-builtins-install.c:82
#: app/flatpak-builtins-install.c:88 app/flatpak-builtins-preinstall.c:68
#: app/flatpak-builtins-run.c:182 app/flatpak-builtins-run.c:184
#: app/flatpak-builtins-update.c:67 app/flatpak-builtins-update.c:71
msgid "PATH"
msgstr "PATH"

#: app/flatpak-builtins-info.c:68
msgid "Show extensions"
msgstr "Show extensions"

#: app/flatpak-builtins-info.c:69
msgid "Show location"
msgstr "Show location"

#: app/flatpak-builtins-info.c:116
msgid "NAME [BRANCH] - Get info about an installed app or runtime"
msgstr "NAME [BRANCH] - Get info about an installed app or runtime"

#: app/flatpak-builtins-info.c:123 app/flatpak-builtins-remote-add.c:317
#: app/flatpak-builtins-remote-delete.c:63
msgid "NAME must be specified"
msgstr "NAME must be specified"

#: app/flatpak-builtins-info.c:196
msgid "ref not present in origin"
msgstr "ref not present in origin"

#: app/flatpak-builtins-info.c:211 app/flatpak-builtins-remote-info.c:217
#, c-format
msgid "Warning: Commit has no flatpak metadata\n"
msgstr "Warning: Commit has no flatpak metadata\n"

#: app/flatpak-builtins-info.c:217 app/flatpak-builtins-info.c:259
#: app/flatpak-builtins-info.c:455 app/flatpak-builtins-info.c:513
#: app/flatpak-builtins-remote-info.c:236
#: app/flatpak-builtins-remote-info.c:271
msgid "ID:"
msgstr "ID:"

#: app/flatpak-builtins-info.c:218 app/flatpak-builtins-info.c:260
#: app/flatpak-builtins-remote-info.c:237
#: app/flatpak-builtins-remote-info.c:272
msgid "Ref:"
msgstr "Ref:"

#: app/flatpak-builtins-info.c:219 app/flatpak-builtins-info.c:261
#: app/flatpak-builtins-remote-info.c:238
#: app/flatpak-builtins-remote-info.c:273
msgid "Arch:"
msgstr "Arch:"

#: app/flatpak-builtins-info.c:220 app/flatpak-builtins-info.c:262
#: app/flatpak-builtins-remote-info.c:239
#: app/flatpak-builtins-remote-info.c:274
msgid "Branch:"
msgstr "Branch:"

#: app/flatpak-builtins-info.c:222 app/flatpak-builtins-info.c:264
#: app/flatpak-builtins-remote-info.c:241
#: app/flatpak-builtins-remote-info.c:276
msgid "Version:"
msgstr "Version:"

#: app/flatpak-builtins-info.c:224 app/flatpak-builtins-info.c:266
#: app/flatpak-builtins-remote-info.c:243
#: app/flatpak-builtins-remote-info.c:278
msgid "License:"
msgstr "License:"

#: app/flatpak-builtins-info.c:226 app/flatpak-builtins-info.c:269
#: app/flatpak-builtins-remote-info.c:245
#: app/flatpak-builtins-remote-info.c:280
msgid "Collection:"
msgstr "Collection:"

#: app/flatpak-builtins-info.c:227 app/flatpak-builtins-info.c:270
#: app/flatpak-builtins-info.c:458 app/flatpak-builtins-info.c:516
msgid "Installation:"
msgstr "Installation:"

#: app/flatpak-builtins-info.c:228 app/flatpak-builtins-info.c:271
#: app/flatpak-builtins-info.c:459 app/flatpak-builtins-info.c:517
#: app/flatpak-builtins-remote-info.c:249
#: app/flatpak-builtins-remote-info.c:284
#, fuzzy
msgid "Installed Size:"
msgstr "Installed size"

#: app/flatpak-builtins-info.c:231 app/flatpak-builtins-info.c:279
#: app/flatpak-builtins-remote-info.c:252
#: app/flatpak-builtins-remote-info.c:288
msgid "Runtime:"
msgstr "Runtime:"

#: app/flatpak-builtins-info.c:232 app/flatpak-builtins-info.c:288
#: app/flatpak-builtins-remote-info.c:253
#: app/flatpak-builtins-remote-info.c:293
msgid "Sdk:"
msgstr "Sdk:"

#: app/flatpak-builtins-info.c:235 app/flatpak-builtins-info.c:313
#: app/flatpak-builtins-remote-info.c:256
#: app/flatpak-builtins-remote-info.c:319
msgid "Date:"
msgstr "Date:"

#: app/flatpak-builtins-info.c:237 app/flatpak-builtins-info.c:311
#: app/flatpak-builtins-remote-info.c:258
#: app/flatpak-builtins-remote-info.c:317
msgid "Subject:"
msgstr "Subject:"

#: app/flatpak-builtins-info.c:240 app/flatpak-builtins-info.c:295
msgid "Active commit:"
msgstr "Active commit:"

#: app/flatpak-builtins-info.c:241 app/flatpak-builtins-info.c:298
msgid "Latest commit:"
msgstr "Latest commit:"

#: app/flatpak-builtins-info.c:244 app/flatpak-builtins-info.c:303
#: app/flatpak-builtins-info.c:457 app/flatpak-builtins-info.c:515
#: app/flatpak-builtins-remote-info.c:259
#: app/flatpak-builtins-remote-info.c:298
msgid "Commit:"
msgstr "Commit:"

#: app/flatpak-builtins-info.c:246 app/flatpak-builtins-info.c:308
#: app/flatpak-builtins-remote-info.c:261
#: app/flatpak-builtins-remote-info.c:303
msgid "Parent:"
msgstr "Parent:"

#: app/flatpak-builtins-info.c:248 app/flatpak-builtins-info.c:321
msgid "Alt-id:"
msgstr "Alt-id:"

#: app/flatpak-builtins-info.c:250 app/flatpak-builtins-info.c:325
#: app/flatpak-builtins-remote-info.c:263
#: app/flatpak-builtins-remote-info.c:308
msgid "End-of-life:"
msgstr "End-of-life:"

#: app/flatpak-builtins-info.c:252 app/flatpak-builtins-info.c:330
#: app/flatpak-builtins-remote-info.c:265
#: app/flatpak-builtins-remote-info.c:313
msgid "End-of-life-rebase:"
msgstr "End-of-life-rebase:"

#: app/flatpak-builtins-info.c:254 app/flatpak-builtins-info.c:317
msgid "Subdirectories:"
msgstr "Subdirectories:"

#: app/flatpak-builtins-info.c:255 app/flatpak-builtins-info.c:454
#: app/flatpak-builtins-info.c:512
msgid "Extension:"
msgstr "Extension:"

#: app/flatpak-builtins-info.c:267 app/flatpak-builtins-info.c:456
#: app/flatpak-builtins-info.c:514
msgid "Origin:"
msgstr "Origin:"

#: app/flatpak-builtins-info.c:460 app/flatpak-builtins-info.c:522
msgid "Subpaths:"
msgstr "Subpaths:"

#: app/flatpak-builtins-info.c:478
msgid "unmaintained"
msgstr "unmaintained"

#: app/flatpak-builtins-info.c:480 app/flatpak-builtins-info.c:482
msgid "unknown"
msgstr "unknown"

#: app/flatpak-builtins-install.c:68 app/flatpak-builtins-preinstall.c:57
msgid "Don't pull, only install from local cache"
msgstr "Don't pull, only install from local cache"

#: app/flatpak-builtins-install.c:69 app/flatpak-builtins-preinstall.c:58
#: app/flatpak-builtins-update.c:60
msgid "Don't deploy, only download to local cache"
msgstr "Don't deploy, only download to local cache"

#: app/flatpak-builtins-install.c:70 app/flatpak-builtins-preinstall.c:59
msgid "Don't install related refs"
msgstr "Don't install related refs"

#: app/flatpak-builtins-install.c:71 app/flatpak-builtins-preinstall.c:60
#: app/flatpak-builtins-update.c:62
msgid "Don't verify/install runtime dependencies"
msgstr "Don't verify/install runtime dependencies"

#: app/flatpak-builtins-install.c:72
msgid "Don't automatically pin explicit installs"
msgstr ""

#: app/flatpak-builtins-install.c:73 app/flatpak-builtins-preinstall.c:61
#: app/flatpak-builtins-update.c:63
msgid "Don't use static deltas"
msgstr "Don't use static deltas"

#: app/flatpak-builtins-install.c:76 app/flatpak-builtins-preinstall.c:62
msgid "Additionally install the SDK used to build the given refs"
msgstr ""

#: app/flatpak-builtins-install.c:77 app/flatpak-builtins-preinstall.c:63
msgid ""
"Additionally install the debug info for the given refs and their dependencies"
msgstr ""

#: app/flatpak-builtins-install.c:78
msgid "Assume LOCATION is a .flatpak single-file bundle"
msgstr "Assume LOCATION is a .flatpak single-file bundle"

#: app/flatpak-builtins-install.c:79
msgid "Assume LOCATION is a .flatpakref application description"
msgstr "Assume LOCATION is a .flatpakref application description"

#: app/flatpak-builtins-install.c:80
msgid "Assume LOCATION is containers-transports(5) reference to an OCI image"
msgstr ""

#: app/flatpak-builtins-install.c:81
msgid "Check bundle signatures with GPG key from FILE (- for stdin)"
msgstr "Check bundle signatures with GPG key from FILE (- for stdin)"

#: app/flatpak-builtins-install.c:82
msgid "Only install this subpath"
msgstr "Only install this subpath"

#: app/flatpak-builtins-install.c:83 app/flatpak-builtins-preinstall.c:64
#: app/flatpak-builtins-uninstall.c:63 app/flatpak-builtins-update.c:68
msgid "Automatically answer yes for all questions"
msgstr "Automatically answer yes for all questions"

#: app/flatpak-builtins-install.c:84 app/flatpak-builtins-preinstall.c:65
msgid "Uninstall first if already installed"
msgstr "Uninstall first if already installed"

#: app/flatpak-builtins-install.c:85 app/flatpak-builtins-preinstall.c:66
#: app/flatpak-builtins-uninstall.c:64 app/flatpak-builtins-update.c:69
msgid "Produce minimal output and don't ask questions"
msgstr "Produce minimal output and don't ask questions"

#: app/flatpak-builtins-install.c:86
#, fuzzy
msgid "Update install if already installed"
msgstr "Uninstall first if already installed"

#. Translators: A sideload is when you install from a local USB drive rather than the Internet.
#: app/flatpak-builtins-install.c:88 app/flatpak-builtins-preinstall.c:68
#: app/flatpak-builtins-update.c:71
msgid "Use this local repo for sideloads"
msgstr ""

#: app/flatpak-builtins-install.c:178
msgid "Bundle filename must be specified"
msgstr "Bundle filename must be specified"

#: app/flatpak-builtins-install.c:188
msgid "Remote bundles are not supported"
msgstr "Remote bundles are not supported"

#: app/flatpak-builtins-install.c:231
msgid "Filename or uri must be specified"
msgstr "Filename or uri must be specified"

#: app/flatpak-builtins-install.c:295
#, fuzzy
msgid "Image location must be specified"
msgstr "At least one REF must be specified"

#: app/flatpak-builtins-install.c:345
msgid "[LOCATION/REMOTE] [REF…] - Install applications or runtimes"
msgstr "[LOCATION/REMOTE] [REF…] - Install applications or runtimes"

#: app/flatpak-builtins-install.c:378
msgid "At least one REF must be specified"
msgstr "At least one REF must be specified"

#: app/flatpak-builtins-install.c:392
#, c-format
msgid "Looking for matches…\n"
msgstr "Looking for matches…\n"

#: app/flatpak-builtins-install.c:513
#, fuzzy, c-format
msgid "No remote refs found for ‘%s’"
msgstr "No remote refs found similar to ‘%s’"

#: app/flatpak-builtins-install.c:573 app/flatpak-builtins-uninstall.c:405
#: common/flatpak-ref-utils.c:689 common/flatpak-ref-utils.c:1595
#, c-format
msgid "Invalid branch %s: %s"
msgstr "Invalid branch %s: %s"

#: app/flatpak-builtins-install.c:606
#, c-format
msgid "Nothing matches %s in local repository for remote %s"
msgstr "Nothing matches %s in local repository for remote %s"

#: app/flatpak-builtins-install.c:608
#, c-format
msgid "Nothing matches %s in remote %s"
msgstr "Nothing matches %s in remote %s"

#: app/flatpak-builtins-install.c:629
#, c-format
msgid "Skipping: %s\n"
msgstr "Skipping: %s\n"

#: app/flatpak-builtins-kill.c:110
#, fuzzy, c-format
msgid "%s is not running"
msgstr "%s is not running."

#: app/flatpak-builtins-kill.c:136
msgid "INSTANCE - Stop a running application"
msgstr "INSTANCE - Stop a running application"

#: app/flatpak-builtins-kill.c:144 app/flatpak-builtins-ps.c:256
msgid "Extra arguments given"
msgstr "Extra arguments given"

#: app/flatpak-builtins-kill.c:150
msgid "Must specify the app to kill"
msgstr "Must specify the app to kill"

#: app/flatpak-builtins-list.c:47
msgid "Show extra information"
msgstr "Show extra information"

#: app/flatpak-builtins-list.c:48
msgid "List installed runtimes"
msgstr "List installed runtimes"

#: app/flatpak-builtins-list.c:49
msgid "List installed applications"
msgstr "List installed applications"

#: app/flatpak-builtins-list.c:50
msgid "Arch to show"
msgstr "Arch to show"

#: app/flatpak-builtins-list.c:51 app/flatpak-builtins-remote-ls.c:57
msgid "List all refs (including locale/debug)"
msgstr "List all refs (including locale/debug)"

#: app/flatpak-builtins-list.c:53 app/flatpak-builtins-remote-ls.c:58
msgid "List all applications using RUNTIME"
msgstr "List all applications using RUNTIME"

#: app/flatpak-builtins-list.c:59 app/flatpak-builtins-remote-list.c:51
#: app/flatpak-builtins-remote-ls.c:68 app/flatpak-builtins-search.c:44
msgid "Name"
msgstr "Name"

#: app/flatpak-builtins-list.c:59 app/flatpak-builtins-remote-list.c:51
#: app/flatpak-builtins-remote-ls.c:68 app/flatpak-builtins-search.c:44
msgid "Show the name"
msgstr "Show the name"

#: app/flatpak-builtins-list.c:60 app/flatpak-builtins-remote-list.c:60
#: app/flatpak-builtins-remote-ls.c:69 app/flatpak-builtins-search.c:45
msgid "Description"
msgstr "Description"

#: app/flatpak-builtins-list.c:60 app/flatpak-builtins-remote-ls.c:69
#: app/flatpak-builtins-search.c:45
msgid "Show the description"
msgstr "Show the description"

#: app/flatpak-builtins-list.c:61 app/flatpak-builtins-remote-ls.c:70
#: app/flatpak-builtins-search.c:46
msgid "Application ID"
msgstr "Application ID"

#: app/flatpak-builtins-list.c:61 app/flatpak-builtins-ps.c:52
#: app/flatpak-builtins-remote-ls.c:70 app/flatpak-builtins-search.c:46
msgid "Show the application ID"
msgstr "Show the application ID"

#: app/flatpak-builtins-list.c:62 app/flatpak-builtins-remote-ls.c:71
#: app/flatpak-builtins-search.c:47
msgid "Show the version"
msgstr "Show the version"

#: app/flatpak-builtins-list.c:65 app/flatpak-builtins-ps.c:56
#: app/flatpak-builtins-remote-ls.c:77
msgid "Runtime"
msgstr "Runtime"

#: app/flatpak-builtins-list.c:65
msgid "Show the used runtime"
msgstr "Show the used runtime"

#: app/flatpak-builtins-list.c:66 app/flatpak-builtins-remote-ls.c:74
msgid "Show the origin remote"
msgstr "Show the origin remote"

#: app/flatpak-builtins-list.c:67
msgid "Show the installation"
msgstr "Show the installation"

#: app/flatpak-builtins-list.c:69
msgid "Active commit"
msgstr "Active commit"

#: app/flatpak-builtins-list.c:69 app/flatpak-builtins-remote-ls.c:76
msgid "Show the active commit"
msgstr "Show the active commit"

#: app/flatpak-builtins-list.c:70
msgid "Latest commit"
msgstr "Latest commit"

#: app/flatpak-builtins-list.c:70
msgid "Show the latest commit"
msgstr "Show the latest commit"

#: app/flatpak-builtins-list.c:71 app/flatpak-builtins-remote-ls.c:78
msgid "Installed size"
msgstr "Installed size"

#: app/flatpak-builtins-list.c:71 app/flatpak-builtins-remote-ls.c:78
msgid "Show the installed size"
msgstr "Show the installed size"

#: app/flatpak-builtins-list.c:72 app/flatpak-builtins-remote-list.c:58
#: app/flatpak-builtins-remote-ls.c:80 app/flatpak-builtins-repo.c:340
msgid "Options"
msgstr "Options"

#: app/flatpak-builtins-list.c:72 app/flatpak-builtins-remote-list.c:58
#: app/flatpak-builtins-remote-ls.c:80
msgid "Show options"
msgstr "Show options"

#: app/flatpak-builtins-list.c:180
#, fuzzy, c-format
msgid "Unable to load details of %s: %s"
msgstr "Unable to load metadata from remote %s: %s"

#: app/flatpak-builtins-list.c:190
#, fuzzy, c-format
msgid "Unable to inspect current version of %s: %s"
msgstr "Unable to create sync pipe"

#: app/flatpak-builtins-list.c:408
msgid " - List installed apps and/or runtimes"
msgstr " - List installed apps and/or runtimes"

#: app/flatpak-builtins-make-current.c:38
msgid "Arch to make current for"
msgstr "Arch to make current for"

#: app/flatpak-builtins-make-current.c:58
msgid "APP BRANCH - Make branch of application current"
msgstr "APP BRANCH - Make branch of application current"

#: app/flatpak-builtins-make-current.c:69 app/flatpak-builtins-run.c:260
msgid "APP must be specified"
msgstr "APP must be specified"

#: app/flatpak-builtins-make-current.c:84
msgid "BRANCH must be specified"
msgstr "BRANCH must be specified"

#: app/flatpak-builtins-make-current.c:97
#, c-format
msgid "App %s branch %s is not installed"
msgstr "App %s branch %s is not installed"

#: app/flatpak-builtins-mask.c:42
#, fuzzy
msgid "Remove matching masks"
msgstr "Remove them?"

#: app/flatpak-builtins-mask.c:54
msgid ""
"[PATTERN…] - disable updates and automatic installation matching patterns"
msgstr ""

#: app/flatpak-builtins-mask.c:73
#, c-format
msgid "No masked patterns\n"
msgstr ""

#: app/flatpak-builtins-mask.c:78
#, c-format
msgid "Masked patterns:\n"
msgstr ""

#: app/flatpak-builtins-override.c:42
msgid "Remove existing overrides"
msgstr "Remove existing overrides"

#: app/flatpak-builtins-override.c:43
msgid "Show existing overrides"
msgstr "Show existing overrides"

#: app/flatpak-builtins-override.c:59
msgid "[APP] - Override settings [for application]"
msgstr "[APP] - Override settings [for application]"

#: app/flatpak-builtins-permission-list.c:143
msgid "[TABLE] [ID] - List permissions"
msgstr "[TABLE] [ID] - List permissions"

#: app/flatpak-builtins-permission-list.c:179
#: app/flatpak-builtins-permission-show.c:142
msgid "Table"
msgstr "Table"

#: app/flatpak-builtins-permission-list.c:180
#: app/flatpak-builtins-permission-show.c:143
msgid "Object"
msgstr "Object"

#: app/flatpak-builtins-permission-list.c:181
#: app/flatpak-builtins-permission-show.c:144
msgid "App"
msgstr "App"

#: app/flatpak-builtins-permission-list.c:183
#: app/flatpak-builtins-permission-show.c:146
msgid "Data"
msgstr "Data"

#: app/flatpak-builtins-permission-remove.c:120
#, fuzzy
msgid "TABLE ID [APP_ID] - Remove item from permission store"
msgstr "TABLE ID - Remove item from permission store"

#: app/flatpak-builtins-permission-remove.c:129
#: app/flatpak-builtins-permission-set.c:120
msgid "Too few arguments"
msgstr "Too few arguments"

#: app/flatpak-builtins-permission-reset.c:43
msgid "Reset all permissions"
msgstr "Reset all permissions"

#: app/flatpak-builtins-permission-reset.c:144
msgid "APP_ID - Reset permissions for an app"
msgstr "APP_ID - Reset permissions for an app"

#: app/flatpak-builtins-permission-reset.c:153
#: app/flatpak-builtins-permission-show.c:124
msgid "Wrong number of arguments"
msgstr "Wrong number of arguments"

#: app/flatpak-builtins-permission-set.c:42
msgid "Associate DATA with the entry"
msgstr ""

#: app/flatpak-builtins-permission-set.c:42
msgid "DATA"
msgstr ""

#: app/flatpak-builtins-permission-set.c:111
#, fuzzy
msgid "TABLE ID APP_ID [PERMISSION...] - Set permissions"
msgstr "[TABLE] [ID] - List permissions"

#: app/flatpak-builtins-permission-set.c:132
#, fuzzy, c-format
msgid "Failed to parse '%s' as GVariant: "
msgstr "Failed to parse filter '%s'"

#: app/flatpak-builtins-permission-show.c:115
msgid "APP_ID - Show permissions for an app"
msgstr "APP_ID - Show permissions for an app"

#: app/flatpak-builtins-pin.c:44
#, fuzzy
msgid "Remove matching pins"
msgstr "Remove them?"

#: app/flatpak-builtins-pin.c:56
msgid "[PATTERN…] - disable automatic removal of runtimes matching patterns"
msgstr ""

#: app/flatpak-builtins-pin.c:75
#, c-format
msgid "No pinned patterns\n"
msgstr ""

#: app/flatpak-builtins-pin.c:80
#, c-format
msgid "Pinned patterns:\n"
msgstr ""

#: app/flatpak-builtins-preinstall.c:80
msgid "- Install flatpaks that are part of the operating system"
msgstr ""

#: app/flatpak-builtins-preinstall.c:118
#, c-format
msgid "Nothing to do.\n"
msgstr "Nothing to do.\n"

#: app/flatpak-builtins-ps.c:49
msgid "Instance"
msgstr "Instance"

#: app/flatpak-builtins-ps.c:49
msgid "Show the instance ID"
msgstr "Show the instance ID"

#: app/flatpak-builtins-ps.c:50 app/flatpak-builtins-run.c:178
msgid "PID"
msgstr "PID"

#: app/flatpak-builtins-ps.c:50
msgid "Show the PID of the wrapper process"
msgstr "Show the PID of the wrapper process"

#: app/flatpak-builtins-ps.c:51
msgid "Child-PID"
msgstr "Child-PID"

#: app/flatpak-builtins-ps.c:51
msgid "Show the PID of the sandbox process"
msgstr "Show the PID of the sandbox process"

#: app/flatpak-builtins-ps.c:54 app/flatpak-builtins-search.c:48
msgid "Show the application branch"
msgstr "Show the application branch"

#: app/flatpak-builtins-ps.c:55
msgid "Show the application commit"
msgstr "Show the application commit"

#: app/flatpak-builtins-ps.c:56
msgid "Show the runtime ID"
msgstr "Show the runtime ID"

#: app/flatpak-builtins-ps.c:57
msgid "R.-Branch"
msgstr "R.-Branch"

#: app/flatpak-builtins-ps.c:57
msgid "Show the runtime branch"
msgstr "Show the runtime branch"

#: app/flatpak-builtins-ps.c:58
msgid "R.-Commit"
msgstr "R.-Commit"

#: app/flatpak-builtins-ps.c:58
msgid "Show the runtime commit"
msgstr "Show the runtime commit"

#: app/flatpak-builtins-ps.c:59
#, fuzzy
msgid "Active"
msgstr "Active commit"

#: app/flatpak-builtins-ps.c:59
#, fuzzy
msgid "Show whether the app is active"
msgstr "Show when the change happened"

#: app/flatpak-builtins-ps.c:60
msgid "Background"
msgstr ""

#: app/flatpak-builtins-ps.c:60
#, fuzzy
msgid "Show whether the app is background"
msgstr "Show when the change happened"

#: app/flatpak-builtins-ps.c:246
msgid " - Enumerate running sandboxes"
msgstr " - Enumerate running sandboxes"

#: app/flatpak-builtins-remote-add.c:66
msgid "Do nothing if the provided remote exists"
msgstr "Do nothing if the provided remote exists"

#: app/flatpak-builtins-remote-add.c:67
msgid "LOCATION specifies a configuration file, not the repo location"
msgstr "LOCATION specifies a configuration file, not the repo location"

#: app/flatpak-builtins-remote-add.c:72 app/flatpak-builtins-remote-modify.c:78
msgid "Disable GPG verification"
msgstr "Disable GPG verification"

#: app/flatpak-builtins-remote-add.c:73 app/flatpak-builtins-remote-modify.c:79
msgid "Mark the remote as don't enumerate"
msgstr "Mark the remote as don't enumerate"

#: app/flatpak-builtins-remote-add.c:74 app/flatpak-builtins-remote-modify.c:80
msgid "Mark the remote as don't use for deps"
msgstr "Mark the remote as don't use for deps"

#: app/flatpak-builtins-remote-add.c:75 app/flatpak-builtins-remote-modify.c:81
msgid "Set priority (default 1, higher is more prioritized)"
msgstr "Set priority (default 1, higher is more prioritised)"

#: app/flatpak-builtins-remote-add.c:75 app/flatpak-builtins-remote-modify.c:81
msgid "PRIORITY"
msgstr "PRIORITY"

#: app/flatpak-builtins-remote-add.c:76
#, fuzzy
msgid "The named subset to use for this remote"
msgstr "A nice name to use for this remote"

#: app/flatpak-builtins-remote-add.c:76 app/flatpak-builtins-remote-modify.c:71
msgid "SUBSET"
msgstr ""

#: app/flatpak-builtins-remote-add.c:77 app/flatpak-builtins-remote-modify.c:82
msgid "A nice name to use for this remote"
msgstr "A nice name to use for this remote"

#: app/flatpak-builtins-remote-add.c:78 app/flatpak-builtins-remote-modify.c:83
msgid "A one-line comment for this remote"
msgstr "A one-line comment for this remote"

#: app/flatpak-builtins-remote-add.c:79 app/flatpak-builtins-remote-modify.c:84
msgid "A full-paragraph description for this remote"
msgstr "A full-paragraph description for this remote"

#: app/flatpak-builtins-remote-add.c:80 app/flatpak-builtins-remote-modify.c:85
msgid "URL for a website for this remote"
msgstr "URL for a website for this remote"

#: app/flatpak-builtins-remote-add.c:81 app/flatpak-builtins-remote-modify.c:86
msgid "URL for an icon for this remote"
msgstr "URL for an icon for this remote"

#: app/flatpak-builtins-remote-add.c:82 app/flatpak-builtins-remote-modify.c:87
msgid "Default branch to use for this remote"
msgstr "Default branch to use for this remote"

#: app/flatpak-builtins-remote-add.c:84 app/flatpak-builtins-remote-modify.c:89
msgid "Import GPG key from FILE (- for stdin)"
msgstr "Import GPG key from FILE (- for stdin)"

#: app/flatpak-builtins-remote-add.c:85 app/flatpak-builtins-remote-modify.c:90
msgid "Load signatures from URL"
msgstr ""

#: app/flatpak-builtins-remote-add.c:86 app/flatpak-builtins-remote-modify.c:92
msgid "Set path to local filter FILE"
msgstr "Set path to local filter FILE"

#: app/flatpak-builtins-remote-add.c:87 app/flatpak-builtins-remote-modify.c:93
msgid "Disable the remote"
msgstr "Disable the remote"

#: app/flatpak-builtins-remote-add.c:88 app/flatpak-builtins-remote-modify.c:94
msgid "Name of authenticator"
msgstr ""

#: app/flatpak-builtins-remote-add.c:90 app/flatpak-builtins-remote-modify.c:96
#, fuzzy
msgid "Autoinstall authenticator"
msgstr "Invalid dbus name %s"

#: app/flatpak-builtins-remote-add.c:91 app/flatpak-builtins-remote-modify.c:97
#, fuzzy
msgid "Don't autoinstall authenticator"
msgstr "Don't uninstall related refs"

#: app/flatpak-builtins-remote-add.c:92 app/flatpak-builtins-remote-modify.c:99
msgid "Don't follow the redirect set in the summary file"
msgstr ""

#: app/flatpak-builtins-remote-add.c:261 app/flatpak-builtins-remote-add.c:268
#, c-format
msgid "Can't load uri %s: %s\n"
msgstr "Can't load uri %s: %s\n"

#: app/flatpak-builtins-remote-add.c:276 common/flatpak-dir.c:4643
#, c-format
msgid "Can't load file %s: %s\n"
msgstr "Can't load file %s: %s\n"

#: app/flatpak-builtins-remote-add.c:304
msgid "NAME LOCATION - Add a remote repository"
msgstr "NAME LOCATION - Add a remote repository"

#: app/flatpak-builtins-remote-add.c:331
msgid "GPG verification is required if collections are enabled"
msgstr "GPG verification is required if collections are enabled"

#: app/flatpak-builtins-remote-add.c:393
#, c-format
msgid "Remote %s already exists"
msgstr "Remote %s already exists"

#: app/flatpak-builtins-remote-add.c:405
#: app/flatpak-builtins-remote-modify.c:340
#, fuzzy, c-format
msgid "Invalid authenticator name %s"
msgstr "Invalid dbus name %s"

#: app/flatpak-builtins-remote-add.c:422
#, c-format
msgid "Warning: Could not update extra metadata for '%s': %s\n"
msgstr "Warning: Could not update extra metadata for '%s': %s\n"

#: app/flatpak-builtins-remote-delete.c:39
msgid "Remove remote even if in use"
msgstr "Remove remote even if in use"

#: app/flatpak-builtins-remote-delete.c:53
msgid "NAME - Delete a remote repository"
msgstr "NAME - Delete a remote repository"

#: app/flatpak-builtins-remote-delete.c:100
#, c-format
msgid "The following refs are installed from remote '%s':"
msgstr "The following refs are installed from remote '%s':"

#: app/flatpak-builtins-remote-delete.c:101
msgid "Remove them?"
msgstr "Remove them?"

#: app/flatpak-builtins-remote-delete.c:103
#, c-format
msgid "Can't remove remote '%s' with installed refs"
msgstr "Can't remove remote '%s' with installed refs"

#: app/flatpak-builtins-remote-info.c:55
msgid "Commit to show info for"
msgstr "Commit to show info for"

#: app/flatpak-builtins-remote-info.c:58
msgid "Display log"
msgstr "Display log"

#: app/flatpak-builtins-remote-info.c:61
msgid "Show parent"
msgstr "Show parent"

#: app/flatpak-builtins-remote-info.c:65 app/flatpak-builtins-remote-ls.c:60
msgid "Use local caches even if they are stale"
msgstr "Use local caches even if they are stale"

#. Translators: A sideload is when you install from a local USB drive rather than the Internet.
#: app/flatpak-builtins-remote-info.c:67 app/flatpak-builtins-remote-ls.c:62
msgid "Only list refs available as sideloads"
msgstr ""

#: app/flatpak-builtins-remote-info.c:114
msgid ""
" REMOTE REF - Show information about an application or runtime in a remote"
msgstr ""
" REMOTE REF - Show information about an application or runtime in a remote"

#: app/flatpak-builtins-remote-info.c:125
msgid "REMOTE and REF must be specified"
msgstr "REMOTE and REF must be specified"

#: app/flatpak-builtins-remote-info.c:247
#: app/flatpak-builtins-remote-info.c:282
#, fuzzy
msgid "Download Size:"
msgstr "Download size"

#: app/flatpak-builtins-remote-info.c:267
#: app/flatpak-builtins-remote-info.c:325
msgid "History:"
msgstr "History:"

#: app/flatpak-builtins-remote-info.c:348
msgid " Commit:"
msgstr " Commit:"

#: app/flatpak-builtins-remote-info.c:349
msgid " Subject:"
msgstr " Subject:"

#: app/flatpak-builtins-remote-info.c:350
msgid " Date:"
msgstr " Date:"

#: app/flatpak-builtins-remote-info.c:383
#, c-format
msgid "Warning: Commit %s has no flatpak metadata\n"
msgstr "Warning: Commit %s has no flatpak metadata\n"

#: app/flatpak-builtins-remote-list.c:43
msgid "Show remote details"
msgstr "Show remote details"

#: app/flatpak-builtins-remote-list.c:44
msgid "Show disabled remotes"
msgstr "Show disabled remotes"

#: app/flatpak-builtins-remote-list.c:52
msgid "Title"
msgstr "Title"

#: app/flatpak-builtins-remote-list.c:52
msgid "Show the title"
msgstr "Show the title"

#: app/flatpak-builtins-remote-list.c:53
msgid "Show the URL"
msgstr "Show the URL"

#: app/flatpak-builtins-remote-list.c:54
msgid "Show the collection ID"
msgstr "Show the collection ID"

#: app/flatpak-builtins-remote-list.c:55 app/flatpak-builtins-repo.c:392
msgid "Subset"
msgstr ""

#: app/flatpak-builtins-remote-list.c:55
#, fuzzy
msgid "Show the subset"
msgstr "Show the ref"

#: app/flatpak-builtins-remote-list.c:56
msgid "Filter"
msgstr "Filter"

#: app/flatpak-builtins-remote-list.c:56
msgid "Show filter file"
msgstr "Show filter file"

#: app/flatpak-builtins-remote-list.c:57
msgid "Priority"
msgstr "Priority"

#: app/flatpak-builtins-remote-list.c:57
msgid "Show the priority"
msgstr "Show the priority"

#: app/flatpak-builtins-remote-list.c:59
msgid "Comment"
msgstr "Comment"

#: app/flatpak-builtins-remote-list.c:59
msgid "Show comment"
msgstr "Show comment"

#: app/flatpak-builtins-remote-list.c:60
msgid "Show description"
msgstr "Show description"

#: app/flatpak-builtins-remote-list.c:61
msgid "Homepage"
msgstr "Homepage"

#: app/flatpak-builtins-remote-list.c:61
msgid "Show homepage"
msgstr "Show homepage"

#: app/flatpak-builtins-remote-list.c:62
msgid "Icon"
msgstr "Icon"

#: app/flatpak-builtins-remote-list.c:62
msgid "Show icon"
msgstr "Show icon"

#: app/flatpak-builtins-remote-list.c:231
msgid " - List remote repositories"
msgstr " - List remote repositories"

#: app/flatpak-builtins-remote-ls.c:52
msgid "Show arches and branches"
msgstr "Show arches and branches"

#: app/flatpak-builtins-remote-ls.c:53
msgid "Show only runtimes"
msgstr "Show only runtimes"

#: app/flatpak-builtins-remote-ls.c:54
msgid "Show only apps"
msgstr "Show only apps"

#: app/flatpak-builtins-remote-ls.c:55
msgid "Show only those where updates are available"
msgstr "Show only those where updates are available"

#: app/flatpak-builtins-remote-ls.c:56
msgid "Limit to this arch (* for all)"
msgstr "Limit to this arch (* for all)"

#: app/flatpak-builtins-remote-ls.c:77
msgid "Show the runtime"
msgstr "Show the runtime"

#: app/flatpak-builtins-remote-ls.c:79
msgid "Download size"
msgstr "Download size"

#: app/flatpak-builtins-remote-ls.c:79
msgid "Show the download size"
msgstr "Show the download size"

#: app/flatpak-builtins-remote-ls.c:391
msgid " [REMOTE or URI] - Show available runtimes and applications"
msgstr " [REMOTE or URI] - Show available runtimes and applications"

#: app/flatpak-builtins-remote-modify.c:67
msgid "Enable GPG verification"
msgstr "Enable GPG verification"

#: app/flatpak-builtins-remote-modify.c:68
msgid "Mark the remote as enumerate"
msgstr "Mark the remote as enumerate"

#: app/flatpak-builtins-remote-modify.c:69
msgid "Mark the remote as used for dependencies"
msgstr "Mark the remote as used for dependencies"

#: app/flatpak-builtins-remote-modify.c:70
#, fuzzy
msgid "Set a new URL"
msgstr "Set a new url"

#: app/flatpak-builtins-remote-modify.c:71
#, fuzzy
msgid "Set a new subset to use"
msgstr "Set a new url"

#: app/flatpak-builtins-remote-modify.c:72
msgid "Enable the remote"
msgstr "Enable the remote"

#: app/flatpak-builtins-remote-modify.c:73
msgid "Update extra metadata from the summary file"
msgstr "Update extra metadata from the summary file"

#: app/flatpak-builtins-remote-modify.c:91
msgid "Disable local filter"
msgstr "Disable local filter"

#: app/flatpak-builtins-remote-modify.c:95
#, fuzzy
msgid "Authenticator options"
msgstr "Show options"

#: app/flatpak-builtins-remote-modify.c:98
#, fuzzy
msgid "Follow the redirect set in the summary file"
msgstr "Update extra metadata from the summary file"

#: app/flatpak-builtins-remote-modify.c:306
msgid "NAME - Modify a remote repository"
msgstr "NAME - Modify a remote repository"

#: app/flatpak-builtins-remote-modify.c:316
msgid "Remote NAME must be specified"
msgstr "Remote NAME must be specified"

#: app/flatpak-builtins-remote-modify.c:327
#, c-format
msgid "Updating extra metadata from remote summary for %s\n"
msgstr "Updating extra metadata from remote summary for %s\n"

#: app/flatpak-builtins-remote-modify.c:330
#, c-format
msgid "Error updating extra metadata for '%s': %s\n"
msgstr "Error updating extra metadata for '%s': %s\n"

#: app/flatpak-builtins-remote-modify.c:331
#, c-format
msgid "Could not update extra metadata for %s"
msgstr "Could not update extra metadata for %s"

#: app/flatpak-builtins-repair.c:43
msgid "Don't make any changes"
msgstr "Don't make any changes"

#: app/flatpak-builtins-repair.c:44
msgid "Reinstall all refs"
msgstr "Reinstall all refs"

#: app/flatpak-builtins-repair.c:68
#, c-format
msgid "Object missing: %s.%s\n"
msgstr "Object missing: %s.%s\n"

#: app/flatpak-builtins-repair.c:76
#, c-format
msgid "Object invalid: %s.%s\n"
msgstr "Object invalid: %s.%s\n"

#: app/flatpak-builtins-repair.c:81
#, c-format
msgid "%s, deleting object\n"
msgstr "%s, deleting object\n"

#: app/flatpak-builtins-repair.c:146
#, c-format
msgid "Can't load object %s: %s\n"
msgstr "Can't load object %s: %s\n"

#: app/flatpak-builtins-repair.c:228
#, fuzzy, c-format
msgid "Commit invalid %s: %s\n"
msgstr "Object invalid: %s.%s\n"

#: app/flatpak-builtins-repair.c:231
#, fuzzy, c-format
msgid "Deleting invalid commit %s: %s\n"
msgstr "Invalid commit ref %s: "

#: app/flatpak-builtins-repair.c:261
#, c-format
msgid "Commit should be marked partial: %s\n"
msgstr ""

#: app/flatpak-builtins-repair.c:264
#, c-format
msgid "Marking commit as partial: %s\n"
msgstr ""

#: app/flatpak-builtins-repair.c:293
#, c-format
msgid "Problems loading data for %s: %s\n"
msgstr "Problems loading data for %s: %s\n"

#: app/flatpak-builtins-repair.c:306
#, c-format
msgid "Error reinstalling %s: %s\n"
msgstr "Error reinstalling %s: %s\n"

#: app/flatpak-builtins-repair.c:327
msgid "- Repair a flatpak installation"
msgstr "- Repair a flatpak installation"

#: app/flatpak-builtins-repair.c:406
#, c-format
msgid "Removing non-deployed ref %s…\n"
msgstr "Removing non-deployed ref %s…\n"

#: app/flatpak-builtins-repair.c:411
#, c-format
msgid "Skipping non-deployed ref %s…\n"
msgstr "Skipping non-deployed ref %s…\n"

#: app/flatpak-builtins-repair.c:429
#, fuzzy, c-format
msgid "[%d/%d] Verifying %s…\n"
msgstr "Verifying %s…\n"

#: app/flatpak-builtins-repair.c:435
#, c-format
msgid "Dry run: "
msgstr ""

#: app/flatpak-builtins-repair.c:440
#, c-format
msgid "Deleting ref %s due to missing objects\n"
msgstr "Deleting ref %s due to missing objects\n"

#: app/flatpak-builtins-repair.c:444
#, c-format
msgid "Deleting ref %s due to invalid objects\n"
msgstr "Deleting ref %s due to invalid objects\n"

#: app/flatpak-builtins-repair.c:448
#, c-format
msgid "Deleting ref %s due to %d\n"
msgstr "Deleting ref %s due to %d\n"

#: app/flatpak-builtins-repair.c:464
#, c-format
msgid "Checking remotes...\n"
msgstr ""

#: app/flatpak-builtins-repair.c:482
#, c-format
msgid "Remote %s for ref %s is missing\n"
msgstr "Remote %s for ref %s is missing\n"

#: app/flatpak-builtins-repair.c:484
#, c-format
msgid "Remote %s for ref %s is disabled\n"
msgstr "Remote %s for ref %s is disabled\n"

#: app/flatpak-builtins-repair.c:490
#, c-format
msgid "Pruning objects\n"
msgstr "Pruning objects\n"

#: app/flatpak-builtins-repair.c:498
#, c-format
msgid "Erasing .removed\n"
msgstr "Erasing .removed\n"

#: app/flatpak-builtins-repair.c:524
#, c-format
msgid "Reinstalling refs\n"
msgstr "Reinstalling refs\n"

#: app/flatpak-builtins-repair.c:526
#, c-format
msgid "Reinstalling removed refs\n"
msgstr "Reinstalling removed refs\n"

#: app/flatpak-builtins-repair.c:551
#, c-format
msgid "While removing appstream for %s: "
msgstr "While removing appstream for %s: "

#: app/flatpak-builtins-repair.c:558
#, c-format
msgid "While deploying appstream for %s: "
msgstr "While deploying appstream for %s: "

#: app/flatpak-builtins-repo.c:106
#, c-format
msgid "Repo mode: %s\n"
msgstr "Repo mode: %s\n"

#: app/flatpak-builtins-repo.c:113
#, c-format
msgid "Indexed summaries: %s\n"
msgstr ""

#: app/flatpak-builtins-repo.c:113 app/flatpak-builtins-repo.c:139
#: app/flatpak-builtins-repo.c:172
msgid "true"
msgstr ""

#: app/flatpak-builtins-repo.c:113 app/flatpak-builtins-repo.c:139
#: app/flatpak-builtins-repo.c:172
msgid "false"
msgstr ""

#: app/flatpak-builtins-repo.c:121
#, c-format
msgid "Subsummaries: "
msgstr ""

#: app/flatpak-builtins-repo.c:136
#, c-format
msgid "Cache version: %d\n"
msgstr ""

#: app/flatpak-builtins-repo.c:139
#, c-format
msgid "Indexed deltas: %s\n"
msgstr ""

#: app/flatpak-builtins-repo.c:142
#, c-format
msgid "Title: %s\n"
msgstr "Title: %s\n"

#: app/flatpak-builtins-repo.c:145
#, c-format
msgid "Comment: %s\n"
msgstr "Comment: %s\n"

#: app/flatpak-builtins-repo.c:148
#, c-format
msgid "Description: %s\n"
msgstr "Description: %s\n"

#: app/flatpak-builtins-repo.c:151
#, c-format
msgid "Homepage: %s\n"
msgstr "Homepage: %s\n"

#: app/flatpak-builtins-repo.c:154
#, c-format
msgid "Icon: %s\n"
msgstr "Icon: %s\n"

#: app/flatpak-builtins-repo.c:157
#, c-format
msgid "Collection ID: %s\n"
msgstr "Collection ID: %s\n"

#: app/flatpak-builtins-repo.c:160
#, c-format
msgid "Default branch: %s\n"
msgstr "Default branch: %s\n"

#: app/flatpak-builtins-repo.c:163
#, c-format
msgid "Redirect URL: %s\n"
msgstr "Redirect URL: %s\n"

#: app/flatpak-builtins-repo.c:166
#, c-format
msgid "Deploy collection ID: %s\n"
msgstr "Deploy collection ID: %s\n"

#: app/flatpak-builtins-repo.c:169
#, fuzzy, c-format
msgid "Authenticator name: %s\n"
msgstr "Invalid dbus name %s"

#: app/flatpak-builtins-repo.c:172
#, fuzzy, c-format
msgid "Authenticator install: %s\n"
msgstr "Show options"

#: app/flatpak-builtins-repo.c:180
#, c-format
msgid "GPG key hash: %s\n"
msgstr "GPG key hash: %s\n"

#: app/flatpak-builtins-repo.c:184
#, fuzzy, c-format
msgid "%zd summary branches\n"
msgstr "%zd branches\n"

#: app/flatpak-builtins-repo.c:336
msgid "Installed"
msgstr "Installed"

#. Translators: Download is used here as a noun
#: app/flatpak-builtins-repo.c:338 app/flatpak-cli-transaction.c:1462
msgid "Download"
msgstr "Download"

#: app/flatpak-builtins-repo.c:339
msgid "Subsets"
msgstr ""

#: app/flatpak-builtins-repo.c:393
msgid "Digest"
msgstr ""

#: app/flatpak-builtins-repo.c:394
#, fuzzy
msgid "History length"
msgstr "History:"

#: app/flatpak-builtins-repo.c:711
msgid "Print general information about the repository"
msgstr "Print general information about the repository"

#: app/flatpak-builtins-repo.c:712
msgid "List the branches in the repository"
msgstr "List the branches in the repository"

#: app/flatpak-builtins-repo.c:713
msgid "Print metadata for a branch"
msgstr "Print metadata for a branch"

#: app/flatpak-builtins-repo.c:714
msgid "Show commits for a branch"
msgstr "Show commits for a branch"

#: app/flatpak-builtins-repo.c:715
#, fuzzy
msgid "Print information about the repo subsets"
msgstr "Print general information about the repository"

#: app/flatpak-builtins-repo.c:716
msgid "Limit information to subsets with this prefix"
msgstr ""

#: app/flatpak-builtins-repo.c:732
msgid "LOCATION - Repository maintenance"
msgstr "LOCATION - Repository maintenance"

#: app/flatpak-builtins-run.c:159
msgid "Command to run"
msgstr "Command to run"

#: app/flatpak-builtins-run.c:160
msgid "Directory to run the command in"
msgstr "Directory to run the command in"

#: app/flatpak-builtins-run.c:161
msgid "Branch to use"
msgstr "Branch to use"

#: app/flatpak-builtins-run.c:162
msgid "Use development runtime"
msgstr "Use development runtime"

#: app/flatpak-builtins-run.c:163
msgid "Runtime to use"
msgstr "Runtime to use"

#: app/flatpak-builtins-run.c:164
msgid "Runtime version to use"
msgstr "Runtime version to use"

#: app/flatpak-builtins-run.c:167
msgid "Log accessibility bus calls"
msgstr "Log accessibility bus calls"

#: app/flatpak-builtins-run.c:168
msgid "Don't proxy accessibility bus calls"
msgstr "Don't proxy accessibility bus calls"

#: app/flatpak-builtins-run.c:169
msgid "Proxy accessibility bus calls (default except when sandboxed)"
msgstr ""

#: app/flatpak-builtins-run.c:170
#, fuzzy
msgid "Don't proxy session bus calls"
msgstr "Don't proxy accessibility bus calls"

#: app/flatpak-builtins-run.c:171
msgid "Proxy session bus calls (default except when sandboxed)"
msgstr ""

#: app/flatpak-builtins-run.c:172
msgid "Don't start portals"
msgstr "Don't start portals"

#: app/flatpak-builtins-run.c:173
msgid "Enable file forwarding"
msgstr "Enable file forwarding"

#: app/flatpak-builtins-run.c:174
msgid "Run specified commit"
msgstr "Run specified commit"

#: app/flatpak-builtins-run.c:175
msgid "Use specified runtime commit"
msgstr "Use specified runtime commit"

#: app/flatpak-builtins-run.c:176
msgid "Run completely sandboxed"
msgstr "Run completely sandboxed"

#: app/flatpak-builtins-run.c:178
msgid "Use PID as parent pid for sharing namespaces"
msgstr ""

#: app/flatpak-builtins-run.c:179
msgid "Make processes visible in parent namespace"
msgstr ""

#: app/flatpak-builtins-run.c:180
msgid "Share process ID namespace with parent"
msgstr ""

#: app/flatpak-builtins-run.c:181
msgid "Write the instance ID to the given file descriptor"
msgstr ""

#: app/flatpak-builtins-run.c:182
msgid "Use PATH instead of the app's /app"
msgstr ""

#: app/flatpak-builtins-run.c:183
msgid "Use FD instead of the app's /app"
msgstr ""

#: app/flatpak-builtins-run.c:183 app/flatpak-builtins-run.c:185
#: app/flatpak-builtins-run.c:187 app/flatpak-builtins-run.c:188
#: common/flatpak-context.c:2672
msgid "FD"
msgstr ""

#: app/flatpak-builtins-run.c:184
msgid "Use PATH instead of the runtime's /usr"
msgstr ""

#: app/flatpak-builtins-run.c:185
msgid "Use FD instead of the runtime's /usr"
msgstr ""

#: app/flatpak-builtins-run.c:186
#, fuzzy
msgid "Clear all outside environment variables"
msgstr "Set environment variable"

#: app/flatpak-builtins-run.c:187
msgid ""
"Bind mount the file or directory referred to by FD to its canonicalized path"
msgstr ""

#: app/flatpak-builtins-run.c:188
msgid ""
"Bind mount the file or directory referred to by FD read-only to its "
"canonicalized path"
msgstr ""

#: app/flatpak-builtins-run.c:219
msgid "APP [ARGUMENT…] - Run an app"
msgstr "APP [ARGUMENT…] - Run an app"

#: app/flatpak-builtins-run.c:370
#, c-format
msgid "runtime/%s/%s/%s not installed"
msgstr "runtime/%s/%s/%s not installed"

#: app/flatpak-builtins-run.c:419
msgid "app-fd and app-path cannot both be used"
msgstr ""

#: app/flatpak-builtins-run.c:449
msgid "usr-fd and usr-path cannot both be used"
msgstr ""

#: app/flatpak-builtins-search.c:37
msgid "Arch to search for"
msgstr "Arch to search for"

#: app/flatpak-builtins-search.c:49
msgid "Remotes"
msgstr "Remotes"

#: app/flatpak-builtins-search.c:49
msgid "Show the remotes"
msgstr "Show the remotes"

#: app/flatpak-builtins-search.c:244
msgid "TEXT - Search remote apps/runtimes for text"
msgstr "TEXT - Search remote apps/runtimes for text"

#: app/flatpak-builtins-search.c:255
msgid "TEXT must be specified"
msgstr "TEXT must be specified"

#: app/flatpak-builtins-search.c:338
msgid "No matches found"
msgstr "No matches found"

#: app/flatpak-builtins-uninstall.c:54
msgid "Arch to uninstall"
msgstr "Arch to uninstall"

#: app/flatpak-builtins-uninstall.c:55
msgid "Keep ref in local repository"
msgstr "Keep ref in local repository"

#: app/flatpak-builtins-uninstall.c:56
msgid "Don't uninstall related refs"
msgstr "Don't uninstall related refs"

#: app/flatpak-builtins-uninstall.c:57
msgid "Remove files even if running"
msgstr "Remove files even if running"

#: app/flatpak-builtins-uninstall.c:60
msgid "Uninstall all"
msgstr "Uninstall all"

#: app/flatpak-builtins-uninstall.c:61
msgid "Uninstall unused"
msgstr "Uninstall unused"

#: app/flatpak-builtins-uninstall.c:62
msgid "Delete app data"
msgstr "Delete app data"

#: app/flatpak-builtins-uninstall.c:141
#, c-format
msgid "Delete data for %s?"
msgstr "Delete data for %s?"

#: app/flatpak-builtins-uninstall.c:220
#, c-format
msgid "Info: applications using the extension %s%s%s branch %s%s%s:\n"
msgstr ""

#: app/flatpak-builtins-uninstall.c:223
#, fuzzy, c-format
msgid "Info: applications using the runtime %s%s%s branch %s%s%s:\n"
msgstr ""
"\n"
" Finding applications and runtimes"

#: app/flatpak-builtins-uninstall.c:238
#, fuzzy
msgid "Really remove?"
msgstr "Remote"

#: app/flatpak-builtins-uninstall.c:255
#, fuzzy
msgid "[REF…] - Uninstall applications or runtimes"
msgstr "[REF…] - Update applications or runtimes"

#: app/flatpak-builtins-uninstall.c:264
msgid "Must specify at least one REF, --unused, --all or --delete-data"
msgstr "Must specify at least one REF, --unused, --all or --delete-data"

#: app/flatpak-builtins-uninstall.c:267
msgid "Must not specify REFs when using --all"
msgstr "Must not specify REFs when using --all"

#: app/flatpak-builtins-uninstall.c:270
msgid "Must not specify REFs when using --unused"
msgstr "Must not specify REFs when using --unused"

#: app/flatpak-builtins-uninstall.c:336
#, c-format
msgid ""
"\n"
"These runtimes in installation '%s' are pinned and won't be removed; see "
"flatpak-pin(1):\n"
msgstr ""

#: app/flatpak-builtins-uninstall.c:370
#, c-format
msgid "Nothing unused to uninstall\n"
msgstr "Nothing unused to uninstall\n"

#: app/flatpak-builtins-uninstall.c:444
#, fuzzy, c-format
msgid "No installed refs found for ‘%s’"
msgstr "Similar installed refs found for ‘%s’:"

#: app/flatpak-builtins-uninstall.c:447
#, c-format
msgid " with arch ‘%s’"
msgstr ""

#: app/flatpak-builtins-uninstall.c:449
#, c-format
msgid " with branch ‘%s’"
msgstr ""

#: app/flatpak-builtins-uninstall.c:456
#, fuzzy, c-format
msgid "Warning: %s is not installed\n"
msgstr "%s branch %s is not installed"

#: app/flatpak-builtins-uninstall.c:490
#, c-format
msgid "None of the specified refs are installed"
msgstr ""

#: app/flatpak-builtins-uninstall.c:599
#, c-format
msgid "No app data to delete\n"
msgstr ""

#: app/flatpak-builtins-update.c:56
msgid "Arch to update for"
msgstr "Arch to update for"

#: app/flatpak-builtins-update.c:57
msgid "Commit to deploy"
msgstr "Commit to deploy"

#: app/flatpak-builtins-update.c:58
msgid "Remove old files even if running"
msgstr "Remove old files even if running"

#: app/flatpak-builtins-update.c:59
msgid "Don't pull, only update from local cache"
msgstr "Don't pull, only update from local cache"

#: app/flatpak-builtins-update.c:61
msgid "Don't update related refs"
msgstr "Don't update related refs"

#: app/flatpak-builtins-update.c:66
msgid "Update appstream for remote"
msgstr "Update appstream for remote"

#: app/flatpak-builtins-update.c:67
msgid "Only update this subpath"
msgstr "Only update this subpath"

#: app/flatpak-builtins-update.c:90
msgid "[REF…] - Update applications or runtimes"
msgstr "[REF…] - Update applications or runtimes"

#: app/flatpak-builtins-update.c:121
#, fuzzy
msgid "With --commit, only one REF may be specified"
msgstr "At least one REF must be specified"

#: app/flatpak-builtins-update.c:162
#, c-format
msgid "Looking for updates…\n"
msgstr "Looking for updates…\n"

#: app/flatpak-builtins-update.c:215
#, c-format
msgid "Unable to update %s: %s\n"
msgstr "Unable to update %s: %s\n"

#: app/flatpak-builtins-update.c:274
#, fuzzy, c-format
msgid "Nothing to update.\n"
msgstr "Nothing to do.\n"

#: app/flatpak-builtins-utils.c:337
#, fuzzy, c-format
msgid ""
"Remote ‘%s’ found in multiple installations, unable to proceed in non-"
"interactive mode"
msgstr "Ref ‘%s’ found in multiple installations: %s. You must specify one."

#: app/flatpak-builtins-utils.c:346
#, c-format
msgid "Remote ‘%s’ found in multiple installations:"
msgstr "Remote ‘%s’ found in multiple installations:"

#: app/flatpak-builtins-utils.c:347 app/flatpak-builtins-utils.c:442
#: app/flatpak-builtins-utils.c:538 app/flatpak-builtins-utils.c:540
#: app/flatpak-builtins-utils.c:598
msgid "Which do you want to use (0 to abort)?"
msgstr "Which do you want to use (0 to abort)?"

#: app/flatpak-builtins-utils.c:349
#, c-format
msgid "No remote chosen to resolve ‘%s’ which exists in multiple installations"
msgstr ""
"No remote chosen to resolve ‘%s’ which exists in multiple installations"

#: app/flatpak-builtins-utils.c:358
#, c-format
msgid ""
"Remote \"%s\" not found\n"
"Hint: Use flatpak remote-add to add a remote"
msgstr ""

#: app/flatpak-builtins-utils.c:364
#, fuzzy, c-format
msgid "Remote \"%s\" not found in the %s installation"
msgstr "Remote ‘%s’ found in multiple installations:"

#: app/flatpak-builtins-utils.c:404
#, c-format
msgid "Multiple refs match ‘%s’, unable to proceed in non-interactive mode"
msgstr ""

#. default to yes on Enter
#: app/flatpak-builtins-utils.c:430
#, c-format
msgid ""
"Found ref ‘%s’ in remote ‘%s’ (%s).\n"
"Use this ref?"
msgstr ""
"Found ref ‘%s’ in remote ‘%s’ (%s).\n"
"Use this ref?"

#: app/flatpak-builtins-utils.c:434 app/flatpak-builtins-utils.c:444
#: app/flatpak-builtins-utils.c:522 app/flatpak-builtins-utils.c:543
#, c-format
msgid "No ref chosen to resolve matches for ‘%s’"
msgstr "No ref chosen to resolve matches for ‘%s’"

#: app/flatpak-builtins-utils.c:440
#, c-format
msgid "Similar refs found for ‘%s’ in remote ‘%s’ (%s):"
msgstr "Similar refs found for ‘%s’ in remote ‘%s’ (%s):"

#: app/flatpak-builtins-utils.c:488
#, c-format
msgid ""
"Multiple installed refs match ‘%s’, unable to proceed in non-interactive mode"
msgstr ""

#. default to yes on Enter
#: app/flatpak-builtins-utils.c:518
#, c-format
msgid "Found installed ref ‘%s’ (%s). Is this correct?"
msgstr "Found installed ref ‘%s’ (%s). Is this correct?"

#: app/flatpak-builtins-utils.c:534
#, c-format
msgid "All of the above"
msgstr "All of the above"

#: app/flatpak-builtins-utils.c:535
#, c-format
msgid "Similar installed refs found for ‘%s’:"
msgstr "Similar installed refs found for ‘%s’:"

#: app/flatpak-builtins-utils.c:579
#, c-format
msgid ""
"Multiple remotes have refs matching ‘%s’, unable to proceed in non-"
"interactive mode"
msgstr ""

#: app/flatpak-builtins-utils.c:597
#, c-format
msgid "Remotes found with refs similar to ‘%s’:"
msgstr "Remotes found with refs similar to ‘%s’:"

#: app/flatpak-builtins-utils.c:600
#, c-format
msgid "No remote chosen to resolve matches for ‘%s’"
msgstr "No remote chosen to resolve matches for ‘%s’"

#: app/flatpak-builtins-utils.c:696 app/flatpak-builtins-utils.c:699
#, c-format
msgid "Updating appstream data for user remote %s"
msgstr "Updating appstream data for user remote %s"

#: app/flatpak-builtins-utils.c:706 app/flatpak-builtins-utils.c:709
#, c-format
msgid "Updating appstream data for remote %s"
msgstr "Updating appstream data for remote %s"

#: app/flatpak-builtins-utils.c:717 app/flatpak-builtins-utils.c:719
msgid "Error updating"
msgstr "Error updating"

#: app/flatpak-builtins-utils.c:755
#, c-format
msgid "Remote \"%s\" not found"
msgstr "Remote \"%s\" not found"

#: app/flatpak-builtins-utils.c:796
#, c-format
msgid "Ambiguous suffix: '%s'."
msgstr "Ambiguous suffix: '%s'."

#. Translators: don't translate the values
#: app/flatpak-builtins-utils.c:798 app/flatpak-builtins-utils.c:813
msgid "Possible values are :s[tart], :m[iddle], :e[nd] or :f[ull]"
msgstr "Possible values are :s[tart], :m[iddle], :e[nd] or :f[ull]"

#: app/flatpak-builtins-utils.c:811
#, c-format
msgid "Invalid suffix: '%s'."
msgstr "Invalid suffix: '%s'."

#: app/flatpak-builtins-utils.c:846
#, c-format
msgid "Ambiguous column: %s"
msgstr "Ambiguous column: %s"

#: app/flatpak-builtins-utils.c:859
#, c-format
msgid "Unknown column: %s"
msgstr "Unknown column: %s"

#: app/flatpak-builtins-utils.c:917
msgid "Available columns:\n"
msgstr "Available columns:\n"

#: app/flatpak-builtins-utils.c:927
msgid "Show all columns"
msgstr "Show all columns"

#: app/flatpak-builtins-utils.c:928
msgid "Show available columns"
msgstr "Show available columns"

#: app/flatpak-builtins-utils.c:931
msgid "Append :s[tart], :m[iddle], :e[nd] or :f[ull] to change ellipsization"
msgstr "Append :s[tart], :m[iddle], :e[nd] or :f[ull] to change ellipsisation"

#: app/flatpak-builtins-utils.c:1483
#, c-format
msgid "Unknown scheme in sideload location %s"
msgstr ""

#: app/flatpak-cli-transaction.c:96 app/flatpak-cli-transaction.c:102
#, c-format
msgid "Required runtime for %s (%s) found in remote %s\n"
msgstr "Required runtime for %s (%s) found in remote %s\n"

#: app/flatpak-cli-transaction.c:104
msgid "Do you want to install it?"
msgstr "Do you want to install it?"

#: app/flatpak-cli-transaction.c:110
#, c-format
msgid "Required runtime for %s (%s) found in remotes:"
msgstr "Required runtime for %s (%s) found in remotes:"

#: app/flatpak-cli-transaction.c:112
msgid "Which do you want to install (0 to abort)?"
msgstr "Which do you want to install (0 to abort)?"

#: app/flatpak-cli-transaction.c:132
#, fuzzy, c-format
msgid "Configuring %s as new remote '%s'\n"
msgstr "Configuring %s as new remote '%s'"

#. default to yes on Enter
#: app/flatpak-cli-transaction.c:139
#, c-format
msgid ""
"The remote '%s', referred to by '%s' at location %s contains additional "
"applications.\n"
"Should the remote be kept for future installations?"
msgstr ""
"The remote '%s', referred to by '%s' at location %s contains additional "
"applications.\n"
"Should the remote be kept for future installations?"

#. default to yes on Enter
#: app/flatpak-cli-transaction.c:147
#, c-format
msgid ""
"The application %s depends on runtimes from:\n"
"  %s\n"
"Configure this as new remote '%s'"
msgstr ""
"The application %s depends on runtimes from:\n"
"  %s\n"
"Configure this as new remote '%s'"

#. Formatted size/remaining time in seconds
#: app/flatpak-cli-transaction.c:321
#, c-format
msgid "%s/s%s%s"
msgstr ""

#. Download progress percentage, use the appropriate
#. percent format for your language
#: app/flatpak-cli-transaction.c:359
#, c-format
msgid "%3d%%"
msgstr ""

#: app/flatpak-cli-transaction.c:414
msgid "Installing…"
msgstr "Installing…"

#: app/flatpak-cli-transaction.c:416
#, c-format
msgid "Installing %d/%d…"
msgstr "Installing %d/%d…"

#: app/flatpak-cli-transaction.c:421
msgid "Updating…"
msgstr "Updating…"

#: app/flatpak-cli-transaction.c:423
#, c-format
msgid "Updating %d/%d…"
msgstr "Updating %d/%d…"

#: app/flatpak-cli-transaction.c:428
msgid "Uninstalling…"
msgstr "Uninstalling…"

#: app/flatpak-cli-transaction.c:430
#, c-format
msgid "Uninstalling %d/%d…"
msgstr "Uninstalling %d/%d…"

#: app/flatpak-cli-transaction.c:496 app/flatpak-quiet-transaction.c:161
#, c-format
msgid "Info: %s was skipped"
msgstr "Info: %s was skipped"

#: app/flatpak-cli-transaction.c:519
#, fuzzy, c-format
msgid "Warning: %s%s%s already installed"
msgstr "%s already installed"

#: app/flatpak-cli-transaction.c:522
#, fuzzy, c-format
msgid "Error: %s%s%s already installed"
msgstr "%s already installed"

#: app/flatpak-cli-transaction.c:528
#, fuzzy, c-format
msgid "Warning: %s%s%s not installed"
msgstr "%s branch %s is not installed"

#: app/flatpak-cli-transaction.c:531
#, fuzzy, c-format
msgid "Error: %s%s%s not installed"
msgstr "%s/%s/%s not installed"

#: app/flatpak-cli-transaction.c:537
#, fuzzy, c-format
msgid "Warning: %s%s%s needs a later flatpak version"
msgstr "%s needs a later flatpak version"

#: app/flatpak-cli-transaction.c:540
#, fuzzy, c-format
msgid "Error: %s%s%s needs a later flatpak version"
msgstr "%s needs a later flatpak version"

#: app/flatpak-cli-transaction.c:546
#, fuzzy
msgid "Warning: Not enough disk space to complete this operation"
msgstr "Not enough disk space to complete this operation"

#: app/flatpak-cli-transaction.c:548
#, fuzzy
msgid "Error: Not enough disk space to complete this operation"
msgstr "Not enough disk space to complete this operation"

#: app/flatpak-cli-transaction.c:553
#, fuzzy, c-format
msgid "Warning: %s"
msgstr "Warning: "

#: app/flatpak-cli-transaction.c:555
#, fuzzy, c-format
msgid "Error: %s"
msgstr "Error:"

#: app/flatpak-cli-transaction.c:570
#, fuzzy, c-format
msgid "Failed to install %s%s%s: "
msgstr "Failed to rebase %s to %s: "

#: app/flatpak-cli-transaction.c:577
#, fuzzy, c-format
msgid "Failed to update %s%s%s: "
msgstr "Failed to %s %s: "

#: app/flatpak-cli-transaction.c:584
#, fuzzy, c-format
msgid "Failed to install bundle %s%s%s: "
msgstr "Failed to rebase %s to %s: "

#: app/flatpak-cli-transaction.c:591
#, fuzzy, c-format
msgid "Failed to uninstall %s%s%s: "
msgstr "Failed to rebase %s to %s: "

#: app/flatpak-cli-transaction.c:642
#, fuzzy, c-format
msgid "Authentication required for remote '%s'\n"
msgstr "Authentication is required to update remote info"

#: app/flatpak-cli-transaction.c:643
msgid "Open browser?"
msgstr ""

#: app/flatpak-cli-transaction.c:699
#, c-format
msgid "Login required remote %s (realm %s)\n"
msgstr ""

#: app/flatpak-cli-transaction.c:704
msgid "Password"
msgstr ""

#. Only runtimes can be pinned
#: app/flatpak-cli-transaction.c:759
#, fuzzy, c-format
msgid ""
"\n"
"Info: (pinned) runtime %s%s%s branch %s%s%s is end-of-life, in favor of "
"%s%s%s branch %s%s%s\n"
msgstr "Info: %s is end-of-life, in preference of %s\n"

#: app/flatpak-cli-transaction.c:765
#, fuzzy, c-format
msgid ""
"\n"
"Info: runtime %s%s%s branch %s%s%s is end-of-life, in favor of %s%s%s branch "
"%s%s%s\n"
msgstr "Info: %s is end-of-life, in preference of %s\n"

#: app/flatpak-cli-transaction.c:768
#, fuzzy, c-format
msgid ""
"\n"
"Info: app %s%s%s branch %s%s%s is end-of-life, in favor of %s%s%s branch "
"%s%s%s\n"
msgstr "Info: %s is end-of-life, in preference of %s\n"

#. Only runtimes can be pinned
#: app/flatpak-cli-transaction.c:780
#, fuzzy, c-format
msgid ""
"\n"
"Info: (pinned) runtime %s%s%s branch %s%s%s is end-of-life, with reason:\n"
msgstr "Info: %s is end-of-life, with reason: %s\n"

#: app/flatpak-cli-transaction.c:786
#, fuzzy, c-format
msgid ""
"\n"
"Info: runtime %s%s%s branch %s%s%s is end-of-life, with reason:\n"
msgstr "Info: %s is end-of-life, with reason: %s\n"

#: app/flatpak-cli-transaction.c:789
#, fuzzy, c-format
msgid ""
"\n"
"Info: app %s%s%s branch %s%s%s is end-of-life, with reason:\n"
msgstr "Info: %s is end-of-life, with reason: %s\n"

#: app/flatpak-cli-transaction.c:963
#, fuzzy, c-format
msgid "Info: applications using this extension:\n"
msgstr ""
"\n"
" Finding applications and runtimes"

#: app/flatpak-cli-transaction.c:965
#, fuzzy, c-format
msgid "Info: applications using this runtime:\n"
msgstr ""
"\n"
" Finding applications and runtimes"

#: app/flatpak-cli-transaction.c:984
msgid "Replace?"
msgstr ""

#: app/flatpak-cli-transaction.c:987 app/flatpak-quiet-transaction.c:247
#, c-format
msgid "Updating to rebased version\n"
msgstr "Updating to rebased version\n"

#: app/flatpak-cli-transaction.c:1011
#, c-format
msgid "Failed to rebase %s to %s: "
msgstr "Failed to rebase %s to %s: "

#: app/flatpak-cli-transaction.c:1277
#, fuzzy, c-format
msgid "New %s%s%s permissions:"
msgstr "New %s permissions:"

#: app/flatpak-cli-transaction.c:1279
#, fuzzy, c-format
msgid "%s%s%s permissions:"
msgstr "%s permissions:"

#: app/flatpak-cli-transaction.c:1343
msgid "Warning: "
msgstr "Warning: "

#. translators: This is short for operation, the title of a one-char column
#: app/flatpak-cli-transaction.c:1442
msgid "Op"
msgstr "Op"

#. Avoid resizing the download column too much,
#. * by making the title as long as typical content
#.
#: app/flatpak-cli-transaction.c:1458 app/flatpak-cli-transaction.c:1503
msgid "partial"
msgstr "partial"

#: app/flatpak-cli-transaction.c:1535
msgid "Proceed with these changes to the user installation?"
msgstr "Proceed with these changes to the user installation?"

#: app/flatpak-cli-transaction.c:1537
msgid "Proceed with these changes to the system installation?"
msgstr "Proceed with these changes to the system installation?"

#: app/flatpak-cli-transaction.c:1539
#, c-format
msgid "Proceed with these changes to the %s?"
msgstr "Proceed with these changes to the %s?"

#: app/flatpak-cli-transaction.c:1711
msgid "Changes complete."
msgstr "Changes complete."

#: app/flatpak-cli-transaction.c:1713
msgid "Uninstall complete."
msgstr "Uninstall complete."

#: app/flatpak-cli-transaction.c:1715
msgid "Installation complete."
msgstr "Installation complete."

#: app/flatpak-cli-transaction.c:1717
msgid "Updates complete."
msgstr "Updates complete."

#. For updates/!stop_on_first_error we already printed all errors so we make up
#. a different one.
#: app/flatpak-cli-transaction.c:1750
msgid "There were one or more errors"
msgstr "There were one or more errors"

#. translators: please keep the leading space
#: app/flatpak-main.c:76
msgid " Manage installed applications and runtimes"
msgstr " Manage installed applications and runtimes"

#: app/flatpak-main.c:77
msgid "Install an application or runtime"
msgstr "Install an application or runtime"

#: app/flatpak-main.c:78
msgid "Update an installed application or runtime"
msgstr "Update an installed application or runtime"

#: app/flatpak-main.c:81
msgid "Uninstall an installed application or runtime"
msgstr "Uninstall an installed application or runtime"

#: app/flatpak-main.c:84
msgid "Mask out updates and automatic installation"
msgstr ""

#: app/flatpak-main.c:85
msgid "Pin a runtime to prevent automatic removal"
msgstr ""

#: app/flatpak-main.c:86
msgid "List installed apps and/or runtimes"
msgstr "List installed apps and/or runtimes"

#: app/flatpak-main.c:87
msgid "Show info for installed app or runtime"
msgstr "Show info for installed app or runtime"

#: app/flatpak-main.c:88
msgid "Show history"
msgstr "Show history"

#: app/flatpak-main.c:89
msgid "Configure flatpak"
msgstr "Configure flatpak"

#: app/flatpak-main.c:90
msgid "Repair flatpak installation"
msgstr "Repair flatpak installation"

#: app/flatpak-main.c:91
msgid "Put applications or runtimes onto removable media"
msgstr "Put applications or runtimes onto removable media"

#: app/flatpak-main.c:92
msgid "Install flatpaks that are part of the operating system"
msgstr ""

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:95
#, fuzzy
msgid ""
"\n"
" Find applications and runtimes"
msgstr ""
"\n"
" Finding applications and runtimes"

#: app/flatpak-main.c:96
msgid "Search for remote apps/runtimes"
msgstr "Search for remote apps/runtimes"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:99
#, fuzzy
msgid ""
"\n"
" Manage running applications"
msgstr ""
"\n"
" Running applications"

#: app/flatpak-main.c:100
msgid "Run an application"
msgstr "Run an application"

#: app/flatpak-main.c:101
msgid "Override permissions for an application"
msgstr "Override permissions for an application"

#: app/flatpak-main.c:102
msgid "Specify default version to run"
msgstr "Specify default version to run"

#: app/flatpak-main.c:103
msgid "Enter the namespace of a running application"
msgstr "Enter the namespace of a running application"

#: app/flatpak-main.c:104
msgid "Enumerate running applications"
msgstr "Enumerate running applications"

#: app/flatpak-main.c:105
msgid "Stop a running application"
msgstr "Stop a running application"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:108
msgid ""
"\n"
" Manage file access"
msgstr ""
"\n"
" Manage file access"

#: app/flatpak-main.c:109
msgid "List exported files"
msgstr "List exported files"

#: app/flatpak-main.c:110
msgid "Grant an application access to a specific file"
msgstr "Grant an application access to a specific file"

#: app/flatpak-main.c:111
msgid "Revoke access to a specific file"
msgstr "Revoke access to a specific file"

#: app/flatpak-main.c:112
msgid "Show information about a specific file"
msgstr "Show information about a specific file"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:116
msgid ""
"\n"
" Manage dynamic permissions"
msgstr ""
"\n"
" Manage dynamic permissions"

#: app/flatpak-main.c:117
msgid "List permissions"
msgstr "List permissions"

#: app/flatpak-main.c:118
msgid "Remove item from permission store"
msgstr "Remove item from permission store"

#: app/flatpak-main.c:120
#, fuzzy
msgid "Set permissions"
msgstr "List permissions"

#: app/flatpak-main.c:121
msgid "Show app permissions"
msgstr "Show app permissions"

#: app/flatpak-main.c:122
msgid "Reset app permissions"
msgstr "Reset app permissions"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:125
msgid ""
"\n"
" Manage remote repositories"
msgstr ""
"\n"
" Manage remote repositories"

#: app/flatpak-main.c:126
msgid "List all configured remotes"
msgstr "List all configured remotes"

#: app/flatpak-main.c:127
msgid "Add a new remote repository (by URL)"
msgstr "Add a new remote repository (by URL)"

#: app/flatpak-main.c:128
msgid "Modify properties of a configured remote"
msgstr "Modify properties of a configured remote"

#: app/flatpak-main.c:129
msgid "Delete a configured remote"
msgstr "Delete a configured remote"

#: app/flatpak-main.c:131
msgid "List contents of a configured remote"
msgstr "List contents of a configured remote"

#: app/flatpak-main.c:132
msgid "Show information about a remote app or runtime"
msgstr "Show information about a remote app or runtime"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:135
msgid ""
"\n"
" Build applications"
msgstr ""
"\n"
" Build applications"

#: app/flatpak-main.c:136
msgid "Initialize a directory for building"
msgstr "Initialise a directory for building"

#: app/flatpak-main.c:137
msgid "Run a build command inside the build dir"
msgstr "Run a build command inside the build dir"

#: app/flatpak-main.c:138
msgid "Finish a build dir for export"
msgstr "Finish a build dir for export"

#: app/flatpak-main.c:139
msgid "Export a build dir to a repository"
msgstr "Export a build dir to a repository"

#: app/flatpak-main.c:140
msgid "Create a bundle file from a ref in a local repository"
msgstr "Create a bundle file from a ref in a local repository"

#: app/flatpak-main.c:141
msgid "Import a bundle file"
msgstr "Import a bundle file"

#: app/flatpak-main.c:142
msgid "Sign an application or runtime"
msgstr "Sign an application or runtime"

#: app/flatpak-main.c:143
msgid "Update the summary file in a repository"
msgstr "Update the summary file in a repository"

#: app/flatpak-main.c:144
msgid "Create new commit based on existing ref"
msgstr "Create new commit based on existing ref"

#: app/flatpak-main.c:145
msgid "Show information about a repo"
msgstr "Show information about a repo"

#: app/flatpak-main.c:162
msgid "Show debug information, -vv for more detail"
msgstr "Show debug information, -vv for more detail"

#: app/flatpak-main.c:163
msgid "Show OSTree debug information"
msgstr "Show OSTree debug information"

#: app/flatpak-main.c:169
msgid "Print version information and exit"
msgstr "Print version information and exit"

#: app/flatpak-main.c:170
msgid "Print default arch and exit"
msgstr "Print default arch and exit"

#: app/flatpak-main.c:171
msgid "Print supported arches and exit"
msgstr "Print supported arches and exit"

#: app/flatpak-main.c:172
msgid "Print active gl drivers and exit"
msgstr "Print active gl drivers and exit"

#: app/flatpak-main.c:173
msgid "Print paths for system installations and exit"
msgstr "Print paths for system installations and exit"

#: app/flatpak-main.c:174
msgid "Print the updated environment needed to run flatpaks"
msgstr ""

#: app/flatpak-main.c:175
msgid "Only include the system installation with --print-updated-env"
msgstr ""

#: app/flatpak-main.c:180
msgid "Work on the user installation"
msgstr "Work on the user installation"

#: app/flatpak-main.c:181
msgid "Work on the system-wide installation (default)"
msgstr "Work on the system-wide installation (default)"

#: app/flatpak-main.c:182
msgid "Work on a non-default system-wide installation"
msgstr "Work on a non-default system-wide installation"

#: app/flatpak-main.c:212
msgid "Builtin Commands:"
msgstr "Builtin Commands:"

#: app/flatpak-main.c:298
#, c-format
msgid ""
"Note that the directories %s are not in the search path set by the "
"XDG_DATA_DIRS environment variable, so applications installed by Flatpak may "
"not appear on your desktop until the session is restarted."
msgstr ""
"Note that the directories %s are not in the search path set by the "
"XDG_DATA_DIRS environment variable, so applications installed by Flatpak may "
"not appear on your desktop until the session is restarted."

#: app/flatpak-main.c:312
#, c-format
msgid ""
"Note that the directory %s is not in the search path set by the "
"XDG_DATA_DIRS environment variable, so applications installed by Flatpak may "
"not appear on your desktop until the session is restarted."
msgstr ""
"Note that the directory %s is not in the search path set by the "
"XDG_DATA_DIRS environment variable, so applications installed by Flatpak may "
"not appear on your desktop until the session is restarted."

#: app/flatpak-main.c:381
msgid ""
"Refusing to operate under sudo with --user. Omit sudo to operate on the user "
"installation, or use a root shell to operate on the root user's installation."
msgstr ""

#: app/flatpak-main.c:453
msgid ""
"Multiple installations specified for a command that works on one installation"
msgstr ""
"Multiple installations specified for a command that works on one installation"

#: app/flatpak-main.c:504 app/flatpak-main.c:697
#, c-format
msgid "See '%s --help'"
msgstr "See '%s --help'"

#: app/flatpak-main.c:706
#, fuzzy, c-format
msgid "'%s' is not a flatpak command. Did you mean '%s%s'?"
msgstr "'%s' is not a flatpak command. Did you mean '%s'?"

#: app/flatpak-main.c:709
#, c-format
msgid "'%s' is not a flatpak command"
msgstr "'%s' is not a flatpak command"

#: app/flatpak-main.c:824
msgid "No command specified"
msgstr "No command specified"

#: app/flatpak-main.c:980
msgid "error:"
msgstr "error:"

#: app/flatpak-quiet-transaction.c:77
#, c-format
msgid "Installing %s\n"
msgstr "Installing %s\n"

#: app/flatpak-quiet-transaction.c:81
#, c-format
msgid "Updating %s\n"
msgstr "Updating %s\n"

#: app/flatpak-quiet-transaction.c:85
#, c-format
msgid "Uninstalling %s\n"
msgstr "Uninstalling %s\n"

#: app/flatpak-quiet-transaction.c:107
#, fuzzy, c-format
msgid "Warning: Failed to install %s: %s\n"
msgstr "%s Failed to %s %s: %s\n"

#: app/flatpak-quiet-transaction.c:110
#, fuzzy, c-format
msgid "Error: Failed to install %s: %s\n"
msgstr "Error reinstalling %s: %s\n"

#: app/flatpak-quiet-transaction.c:116
#, fuzzy, c-format
msgid "Warning: Failed to update %s: %s\n"
msgstr "Unable to update %s: %s\n"

#: app/flatpak-quiet-transaction.c:119
#, fuzzy, c-format
msgid "Error: Failed to update %s: %s\n"
msgstr "Unable to update %s: %s\n"

#: app/flatpak-quiet-transaction.c:125
#, fuzzy, c-format
msgid "Warning: Failed to install bundle %s: %s\n"
msgstr "Failed to rebase %s to %s: %s\n"

#: app/flatpak-quiet-transaction.c:128
#, fuzzy, c-format
msgid "Error: Failed to install bundle %s: %s\n"
msgstr "Error reinstalling %s: %s\n"

#: app/flatpak-quiet-transaction.c:134
#, fuzzy, c-format
msgid "Warning: Failed to uninstall %s: %s\n"
msgstr "%s Failed to %s %s: %s\n"

#: app/flatpak-quiet-transaction.c:137
#, fuzzy, c-format
msgid "Error: Failed to uninstall %s: %s\n"
msgstr "Error reinstalling %s: %s\n"

#: app/flatpak-quiet-transaction.c:166 common/flatpak-dir.c:11475
#, c-format
msgid "%s already installed"
msgstr "%s already installed"

#: app/flatpak-quiet-transaction.c:168 common/flatpak-dir.c:3622
#: common/flatpak-dir.c:4321 common/flatpak-dir.c:16968
#: common/flatpak-dir.c:17258 common/flatpak-dir-utils.c:166
#: common/flatpak-dir-utils.c:259 common/flatpak-transaction.c:2736
#: common/flatpak-transaction.c:2791
#, c-format
msgid "%s not installed"
msgstr "%s not installed"

#: app/flatpak-quiet-transaction.c:170
#, c-format
msgid "%s needs a later flatpak version"
msgstr "%s needs a later flatpak version"

#: app/flatpak-quiet-transaction.c:172
msgid "Not enough disk space to complete this operation"
msgstr "Not enough disk space to complete this operation"

#: app/flatpak-quiet-transaction.c:239
#, fuzzy, c-format
msgid "Info: %s is end-of-life, in favor of %s\n"
msgstr "Info: %s is end-of-life, in preference of %s\n"

#: app/flatpak-quiet-transaction.c:241
#, c-format
msgid "Info: %s is end-of-life, with reason: %s\n"
msgstr "Info: %s is end-of-life, with reason: %s\n"

#: app/flatpak-quiet-transaction.c:251
#, c-format
msgid "Failed to rebase %s to %s: %s\n"
msgstr "Failed to rebase %s to %s: %s\n"

#: common/flatpak-auth.c:58
#, fuzzy, c-format
msgid "No authenticator configured for remote `%s`"
msgstr "Authentication is required to update remote info"

#: common/flatpak-context.c:637 common/flatpak-context.c:649
#, fuzzy, c-format
msgid "Invalid permission syntax: %s"
msgstr "Invalid dbus name %s"

#: common/flatpak-context.c:1207
#, c-format
msgid "Unknown share type %s, valid types are: %s"
msgstr "Unknown share type %s, valid types are: %s"

#: common/flatpak-context.c:1228
#, c-format
msgid "Unknown policy type %s, valid types are: %s"
msgstr "Unknown policy type %s, valid types are: %s"

#: common/flatpak-context.c:1266
#, c-format
msgid "Invalid dbus name %s"
msgstr "Invalid dbus name %s"

#: common/flatpak-context.c:1279
#, c-format
msgid "Unknown socket type %s, valid types are: %s"
msgstr "Unknown socket type %s, valid types are: %s"

#: common/flatpak-context.c:1294
#, c-format
msgid "Unknown device type %s, valid types are: %s"
msgstr "Unknown device type %s, valid types are: %s"

#: common/flatpak-context.c:1308
#, c-format
msgid "Unknown feature type %s, valid types are: %s"
msgstr "Unknown feature type %s, valid types are: %s"

#: common/flatpak-context.c:1840
#, c-format
msgid "Filesystem location \"%s\" contains \"..\""
msgstr ""

#: common/flatpak-context.c:1882
#, c-format
msgid ""
"--filesystem=/ is not available, use --filesystem=host for a similar result"
msgstr ""

#: common/flatpak-context.c:1916
#, fuzzy, c-format
msgid ""
"Unknown filesystem location %s, valid locations are: host, host-os, host-"
"etc, host-root, home, xdg-*[/…], ~/dir, /dir"
msgstr ""
"Unknown filesystem location %s, valid locations are: host, home, xdg-*[/…], "
"~/dir, /dir"

#: common/flatpak-context.c:2015
#, fuzzy, c-format
msgid "Invalid syntax for %s: %s"
msgstr "Invalid name %s: %s"

#: common/flatpak-context.c:2142
#, c-format
msgid "fallback-x11 can not be conditional"
msgstr ""

#: common/flatpak-context.c:2318
#, c-format
msgid "Invalid env format %s"
msgstr "Invalid env format %s"

#: common/flatpak-context.c:2399
#, c-format
msgid "Environment variable name must not contain '=': %s"
msgstr ""

#: common/flatpak-context.c:2527 common/flatpak-context.c:2535
#, c-format
msgid "--add-policy arguments must be in the form SUBSYSTEM.KEY=VALUE"
msgstr "--add-policy arguments must be in the form SUBSYSTEM.KEY=VALUE"

#: common/flatpak-context.c:2542
#, c-format
msgid "--add-policy values can't start with \"!\""
msgstr "--add-policy values can't start with \"!\""

#: common/flatpak-context.c:2567 common/flatpak-context.c:2575
#, c-format
msgid "--remove-policy arguments must be in the form SUBSYSTEM.KEY=VALUE"
msgstr "--remove-policy arguments must be in the form SUBSYSTEM.KEY=VALUE"

#: common/flatpak-context.c:2582
#, c-format
msgid "--remove-policy values can't start with \"!\""
msgstr "--remove-policy values can't start with \"!\""

#: common/flatpak-context.c:2657
msgid "Share with host"
msgstr "Share with host"

#: common/flatpak-context.c:2657 common/flatpak-context.c:2658
msgid "SHARE"
msgstr "SHARE"

#: common/flatpak-context.c:2658
msgid "Unshare with host"
msgstr "Unshare with host"

#: common/flatpak-context.c:2659
msgid "Require conditions to be met for a subsystem to get shared"
msgstr ""

#: common/flatpak-context.c:2659
msgid "SHARE:CONDITION"
msgstr ""

#: common/flatpak-context.c:2660
msgid "Expose socket to app"
msgstr "Expose socket to app"

#: common/flatpak-context.c:2660 common/flatpak-context.c:2661
msgid "SOCKET"
msgstr "SOCKET"

#: common/flatpak-context.c:2661
msgid "Don't expose socket to app"
msgstr "Don't expose socket to app"

#: common/flatpak-context.c:2662
msgid "Require conditions to be met for a socket to get exposed"
msgstr ""

#: common/flatpak-context.c:2662
msgid "SOCKET:CONDITION"
msgstr ""

#: common/flatpak-context.c:2663
msgid "Expose device to app"
msgstr "Expose device to app"

#: common/flatpak-context.c:2663 common/flatpak-context.c:2664
msgid "DEVICE"
msgstr "DEVICE"

#: common/flatpak-context.c:2664
msgid "Don't expose device to app"
msgstr "Don't expose device to app"

#: common/flatpak-context.c:2665
msgid "Require conditions to be met for a device to get exposed"
msgstr ""

#: common/flatpak-context.c:2665
msgid "DEVICE:CONDITION"
msgstr ""

#: common/flatpak-context.c:2666
msgid "Allow feature"
msgstr "Allow feature"

#: common/flatpak-context.c:2666 common/flatpak-context.c:2667
msgid "FEATURE"
msgstr "FEATURE"

#: common/flatpak-context.c:2667
msgid "Don't allow feature"
msgstr "Don't allow feature"

#: common/flatpak-context.c:2668
msgid "Require conditions to be met for a feature to get allowed"
msgstr ""

#: common/flatpak-context.c:2668
msgid "FEATURE:CONDITION"
msgstr ""

#: common/flatpak-context.c:2669
msgid "Expose filesystem to app (:ro for read-only)"
msgstr "Expose filesystem to app (:ro for read-only)"

#: common/flatpak-context.c:2669
msgid "FILESYSTEM[:ro]"
msgstr "FILESYSTEM[:ro]"

#: common/flatpak-context.c:2670
msgid "Don't expose filesystem to app"
msgstr "Don't expose filesystem to app"

#: common/flatpak-context.c:2670
msgid "FILESYSTEM"
msgstr "FILESYSTEM"

#: common/flatpak-context.c:2671
msgid "Set environment variable"
msgstr "Set environment variable"

#: common/flatpak-context.c:2671
msgid "VAR=VALUE"
msgstr "VAR=VALUE"

#: common/flatpak-context.c:2672
msgid "Read environment variables in env -0 format from FD"
msgstr ""

#: common/flatpak-context.c:2673
#, fuzzy
msgid "Remove variable from environment"
msgstr "Remove item from permission store"

#: common/flatpak-context.c:2673
#, fuzzy
msgid "VAR"
msgstr "VALUE"

#: common/flatpak-context.c:2674
msgid "Allow app to own name on the session bus"
msgstr "Allow app to own name on the session bus"

#: common/flatpak-context.c:2674 common/flatpak-context.c:2675
#: common/flatpak-context.c:2676 common/flatpak-context.c:2677
#: common/flatpak-context.c:2678 common/flatpak-context.c:2679
#: common/flatpak-context.c:2680
msgid "DBUS_NAME"
msgstr "DBUS_NAME"

#: common/flatpak-context.c:2675
msgid "Allow app to talk to name on the session bus"
msgstr "Allow app to talk to name on the session bus"

#: common/flatpak-context.c:2676
msgid "Don't allow app to talk to name on the session bus"
msgstr "Don't allow app to talk to name on the session bus"

#: common/flatpak-context.c:2677
msgid "Allow app to own name on the system bus"
msgstr "Allow app to own name on the system bus"

#: common/flatpak-context.c:2678
msgid "Allow app to talk to name on the system bus"
msgstr "Allow app to talk to name on the system bus"

#: common/flatpak-context.c:2679
msgid "Don't allow app to talk to name on the system bus"
msgstr "Don't allow app to talk to name on the system bus"

#: common/flatpak-context.c:2680
#, fuzzy
msgid "Allow app to own name on the a11y bus"
msgstr "Allow app to own name on the system bus"

#: common/flatpak-context.c:2681
msgid "Add generic policy option"
msgstr "Add generic policy option"

#: common/flatpak-context.c:2681 common/flatpak-context.c:2682
msgid "SUBSYSTEM.KEY=VALUE"
msgstr "SUBSYSTEM.KEY=VALUE"

#: common/flatpak-context.c:2682
msgid "Remove generic policy option"
msgstr "Remove generic policy option"

#: common/flatpak-context.c:2683
msgid "Add USB device to enumerables"
msgstr ""

#: common/flatpak-context.c:2683 common/flatpak-context.c:2684
msgid "VENDOR_ID:PRODUCT_ID"
msgstr ""

#: common/flatpak-context.c:2684
msgid "Add USB device to hidden list"
msgstr ""

#: common/flatpak-context.c:2685
msgid "A list of USB devices that are enumerable"
msgstr ""

#: common/flatpak-context.c:2685
msgid "LIST"
msgstr ""

#: common/flatpak-context.c:2686
msgid "File containing a list of USB devices to make enumerable"
msgstr ""

#: common/flatpak-context.c:2686 common/flatpak-context.c:2687
msgid "FILENAME"
msgstr "FILENAME"

#: common/flatpak-context.c:2687
#, fuzzy
msgid "Persist home directory subpath"
msgstr "Persist home directory"

#. This is not needed/used anymore, so hidden, but we accept it for backwards compat
#: common/flatpak-context.c:2689
msgid "Don't require a running session (no cgroups creation)"
msgstr "Don't require a running session (no cgroups creation)"

#: common/flatpak-context.c:3718
#, c-format
msgid "Not replacing \"%s\" with tmpfs: %s"
msgstr ""

#: common/flatpak-context.c:3726
#, c-format
msgid "Not sharing \"%s\" with sandbox: %s"
msgstr ""

#. Even if the error is one that we would normally silence, like
#. * the path not existing, it seems reasonable to make more of a fuss
#. * about the home directory not existing or otherwise being unusable,
#. * so this is intentionally not using cannot_export()
#: common/flatpak-context.c:3828
#, c-format
msgid "Not allowing home directory access: %s"
msgstr ""

#: common/flatpak-context.c:4062
#, fuzzy, c-format
msgid "Unable to provide a temporary home directory in the sandbox: %s"
msgstr "Can't create deploy directory"

#: common/flatpak-dir.c:442
#, c-format
msgid "Configured collection ID ‘%s’ not in summary file"
msgstr ""

#: common/flatpak-dir.c:587
#, c-format
msgid "Unable to load summary from remote %s: %s"
msgstr "Unable to load summary from remote %s: %s"

#: common/flatpak-dir.c:764 common/flatpak-dir.c:800 common/flatpak-dir.c:906
#, c-format
msgid "No such ref '%s' in remote %s"
msgstr "No such ref '%s' in remote %s"

#: common/flatpak-dir.c:891 common/flatpak-dir.c:1051 common/flatpak-dir.c:1080
#: common/flatpak-dir.c:1092
#, fuzzy, c-format
msgid "No entry for %s in remote %s summary flatpak cache"
msgstr "No entry for %s in remote '%s' summary flatpak cache "

#: common/flatpak-dir.c:1069
#, c-format
msgid "No summary or Flatpak cache available for remote %s"
msgstr "No summary or Flatpak cache available for remote %s"

#: common/flatpak-dir.c:1097
#, fuzzy, c-format
msgid "Missing xa.data in summary for remote %s"
msgstr "No oci summary cached for remote '%s'"

#: common/flatpak-dir.c:1103 common/flatpak-dir.c:1546
#, fuzzy, c-format
msgid "Unsupported summary version %d for remote %s"
msgstr "No summary cached for remote '%s'"

#: common/flatpak-dir.c:1200
msgid "Remote OCI index has no registry uri"
msgstr "Remote OCI index has no registry uri"

#: common/flatpak-dir.c:1261
#, fuzzy, c-format
msgid "Couldn't find ref %s in remote %s"
msgstr "Couldn't find latest checksum for ref %s in remote %s"

#: common/flatpak-dir.c:1288 common/flatpak-dir.c:1381
#, fuzzy, c-format
msgid "Commit has no requested ref ‘%s’ in ref binding metadata (found: ‘%s’)"
msgstr "Commit has no requested ref ‘%s’ in ref binding metadata"

#: common/flatpak-dir.c:1413
#, fuzzy, c-format
msgid "Configured collection ID ‘%s’ not in binding metadata"
msgstr "Commit has no requested ref ‘%s’ in ref binding metadata"

#: common/flatpak-dir.c:1449 common/flatpak-dir.c:5645
#, c-format
msgid "Couldn't find latest checksum for ref %s in remote %s"
msgstr "Couldn't find latest checksum for ref %s in remote %s"

#: common/flatpak-dir.c:1516 common/flatpak-dir.c:1552
#, fuzzy, c-format
msgid "No entry for %s in remote %s summary flatpak sparse cache"
msgstr "No entry for %s in remote summary flatpak sparse cache "

#: common/flatpak-dir.c:2540
#, c-format
msgid "Commit metadata for %s not matching expected metadata"
msgstr ""

#: common/flatpak-dir.c:2823
msgid "Unable to connect to system bus"
msgstr "Unable to connect to system bus"

#: common/flatpak-dir.c:3419
msgid "User installation"
msgstr "User installation"

#: common/flatpak-dir.c:3426
#, c-format
msgid "System (%s) installation"
msgstr "System (%s) installation"

#: common/flatpak-dir.c:3472
#, c-format
msgid "No overrides found for %s"
msgstr "No overrides found for %s"

#: common/flatpak-dir.c:3625
#, c-format
msgid "%s (commit %s) not installed"
msgstr "%s (commit %s) not installed"

#: common/flatpak-dir.c:4650
#, c-format
msgid "Error parsing system flatpakrepo file for %s: %s"
msgstr "Error parsing system flatpakrepo file for %s: %s"

#: common/flatpak-dir.c:4735
#, c-format
msgid "While opening repository %s: "
msgstr "While opening repository %s: "

#: common/flatpak-dir.c:5004
#, c-format
msgid "The config key %s is not set"
msgstr "The config key %s is not set"

#: common/flatpak-dir.c:5140
#, fuzzy, c-format
msgid "No current %s pattern matching %s"
msgstr "Don't create deltas matching refs"

#: common/flatpak-dir.c:5422
msgid "No appstream commit to deploy"
msgstr "No appstream commit to deploy"

#: common/flatpak-dir.c:5941 common/flatpak-dir.c:7266
#: common/flatpak-dir.c:10881 common/flatpak-dir.c:11618
msgid "Can't pull from untrusted non-gpg verified remote"
msgstr "Can't pull from untrusted non-gpg verified remote"

#: common/flatpak-dir.c:6376 common/flatpak-dir.c:6591
msgid "Extra data not supported for non-gpg-verified local system installs"
msgstr "Extra data not supported for non-gpg-verified local system installs"

#: common/flatpak-dir.c:6415 common/flatpak-dir.c:6782
#, c-format
msgid "Invalid checksum for extra data uri %s"
msgstr "Invalid checksum for extra data uri %s"

#: common/flatpak-dir.c:6424
#, c-format
msgid "Empty name for extra data uri %s"
msgstr "Empty name for extra data uri %s"

#: common/flatpak-dir.c:6432
#, c-format
msgid "Unsupported extra data uri %s"
msgstr "Unsupported extra data uri %s"

#: common/flatpak-dir.c:6461
#, c-format
msgid "Failed to load local extra-data %s: %s"
msgstr "Failed to load local extra-data %s: %s"

#: common/flatpak-dir.c:6469
#, c-format
msgid "Wrong size for extra-data %s"
msgstr "Wrong size for extra-data %s"

#: common/flatpak-dir.c:6488
#, c-format
msgid "While downloading %s: "
msgstr "While downloading %s: "

#: common/flatpak-dir.c:6498
#, c-format
msgid "Wrong size for extra data %s"
msgstr "Wrong size for extra data %s"

#: common/flatpak-dir.c:6507
#, c-format
msgid "Invalid checksum for extra data %s"
msgstr "Invalid checksum for extra data %s"

#: common/flatpak-dir.c:7096 common/flatpak-dir.c:7349
#, c-format
msgid "While pulling %s from remote %s: "
msgstr "While pulling %s from remote %s: "

#: common/flatpak-dir.c:7290 common/flatpak-repo-utils.c:3886
msgid "GPG signatures found, but none are in trusted keyring"
msgstr "GPG signatures found, but none are in trusted keyring"

#: common/flatpak-dir.c:7307
#, fuzzy, c-format
msgid "Commit for ‘%s’ has no ref binding"
msgstr "Commit has no requested ref ‘%s’ in ref binding metadata"

#: common/flatpak-dir.c:7312
#, c-format
msgid "Commit for ‘%s’ is not in expected bound refs: %s"
msgstr ""

#: common/flatpak-dir.c:7488
#, fuzzy
msgid "Only applications can be made current"
msgstr ""
"\n"
" Finding applications and runtimes"

#: common/flatpak-dir.c:8192
msgid "Not enough memory"
msgstr "Not enough memory"

#: common/flatpak-dir.c:8211
msgid "Failed to read from exported file"
msgstr "Failed to read from exported file"

#: common/flatpak-dir.c:8401
msgid "Error reading mimetype xml file"
msgstr "Error reading mimetype xml file"

#: common/flatpak-dir.c:8406
msgid "Invalid mimetype xml file"
msgstr "Invalid mimetype xml file"

#: common/flatpak-dir.c:8492
#, c-format
msgid "D-Bus service file '%s' has wrong name"
msgstr "D-Bus service file '%s' has wrong name"

#: common/flatpak-dir.c:8647
#, fuzzy, c-format
msgid "Invalid Exec argument %s"
msgstr "Invalid require-flatpak argument %s"

#: common/flatpak-dir.c:9115
msgid "While getting detached metadata: "
msgstr "While getting detached metadata: "

#: common/flatpak-dir.c:9120 common/flatpak-dir.c:9125
#: common/flatpak-dir.c:9129
msgid "Extra data missing in detached metadata"
msgstr "Extra data missing in detached metadata"

#: common/flatpak-dir.c:9133
msgid "While creating extradir: "
msgstr "While creating extradir: "

#: common/flatpak-dir.c:9154 common/flatpak-dir.c:9187
msgid "Invalid checksum for extra data"
msgstr "Invalid checksum for extra data"

#: common/flatpak-dir.c:9183
msgid "Wrong size for extra data"
msgstr "Wrong size for extra data"

#: common/flatpak-dir.c:9196
#, c-format
msgid "While writing extra data file '%s': "
msgstr "While writing extra data file '%s': "

#: common/flatpak-dir.c:9204
#, c-format
msgid "Extra data %s missing in detached metadata"
msgstr "Extra data %s missing in detached metadata"

#: common/flatpak-dir.c:9278
#, fuzzy, c-format
msgid "Unable to get runtime key from metadata"
msgstr "Use alternative file for the metadata"

#: common/flatpak-dir.c:9402
#, c-format
msgid "apply_extra script failed, exit status %d"
msgstr "apply_extra script failed, exit status %d"

#. Translators: The placeholder is for an app ref.
#: common/flatpak-dir.c:9591
#, c-format
msgid "Installing %s is not allowed by the policy set by your administrator"
msgstr ""

#: common/flatpak-dir.c:9690
#, c-format
msgid "While trying to resolve ref %s: "
msgstr "While trying to resolve ref %s: "

#: common/flatpak-dir.c:9702
#, c-format
msgid "%s is not available"
msgstr "%s is not available"

#: common/flatpak-dir.c:9714 common/flatpak-dir.c:11495
#, c-format
msgid "%s commit %s already installed"
msgstr "%s commit %s already installed"

#: common/flatpak-dir.c:9721
msgid "Can't create deploy directory"
msgstr "Can't create deploy directory"

#: common/flatpak-dir.c:9729
#, c-format
msgid "Failed to read commit %s: "
msgstr "Failed to read commit %s: "

#: common/flatpak-dir.c:9750
#, c-format
msgid "While trying to checkout %s into %s: "
msgstr "While trying to checkout %s into %s: "

#: common/flatpak-dir.c:9769
msgid "While trying to checkout metadata subpath: "
msgstr "While trying to checkout metadata subpath: "

#: common/flatpak-dir.c:9801
#, c-format
msgid "While trying to checkout subpath ‘%s’: "
msgstr "While trying to checkout subpath ‘%s’: "

#: common/flatpak-dir.c:9811
msgid "While trying to remove existing extra dir: "
msgstr "While trying to remove existing extra dir: "

#: common/flatpak-dir.c:9822
msgid "While trying to apply extra data: "
msgstr "While trying to apply extra data: "

#: common/flatpak-dir.c:9849
#, c-format
msgid "Invalid commit ref %s: "
msgstr "Invalid commit ref %s: "

#: common/flatpak-dir.c:9857 common/flatpak-dir.c:9869
#, c-format
msgid "Deployed ref %s does not match commit (%s)"
msgstr "Deployed ref %s does not match commit (%s)"

#: common/flatpak-dir.c:9863
#, c-format
msgid "Deployed ref %s branch does not match commit (%s)"
msgstr "Deployed ref %s branch does not match commit (%s)"

#: common/flatpak-dir.c:10125 common/flatpak-installation.c:1911
#, c-format
msgid "%s branch %s already installed"
msgstr "%s branch %s already installed"

#: common/flatpak-dir.c:10985
#, c-format
msgid "Could not unmount revokefs-fuse filesystem at %s: "
msgstr ""

#: common/flatpak-dir.c:11289
#, c-format
msgid "This version of %s is already installed"
msgstr "This version of %s is already installed"

#: common/flatpak-dir.c:11302
#, c-format
msgid "Can't change remote during bundle install"
msgstr "Can't change remote during bundle install"

#: common/flatpak-dir.c:11571
msgid "Can't update to a specific commit without root permissions"
msgstr "Can't update to a specific commit without root permissions"

#: common/flatpak-dir.c:11852
#, c-format
msgid "Can't remove %s, it is needed for: %s"
msgstr "Can't remove %s, it is needed for: %s"

#: common/flatpak-dir.c:11912 common/flatpak-installation.c:2067
#, c-format
msgid "%s branch %s is not installed"
msgstr "%s branch %s is not installed"

#: common/flatpak-dir.c:12165
#, c-format
msgid "%s commit %s not installed"
msgstr "%s commit %s not installed"

#: common/flatpak-dir.c:12501
#, c-format
msgid "Pruning repo failed: %s"
msgstr "Pruning repo failed: %s"

#: common/flatpak-dir.c:12669 common/flatpak-dir.c:12675
#, c-format
msgid "Failed to load filter '%s'"
msgstr "Failed to load filter '%s'"

#: common/flatpak-dir.c:12681
#, c-format
msgid "Failed to parse filter '%s'"
msgstr "Failed to parse filter '%s'"

#: common/flatpak-dir.c:12963
msgid "Failed to write summary cache: "
msgstr "Failed to write summary cache: "

#: common/flatpak-dir.c:12982
#, c-format
msgid "No oci summary cached for remote '%s'"
msgstr "No oci summary cached for remote '%s'"

#: common/flatpak-dir.c:13207
#, fuzzy, c-format
msgid "No cached summary for remote '%s'"
msgstr "No oci summary cached for remote '%s'"

#: common/flatpak-dir.c:13248
#, fuzzy, c-format
msgid "Invalid checksum for indexed summary %s read from %s"
msgstr "Invalid checksum for extra data %s"

#: common/flatpak-dir.c:13321
#, c-format
msgid ""
"Remote listing for %s not available; server has no summary file. Check the "
"URL passed to remote-add was valid."
msgstr ""
"Remote listing for %s not available; server has no summary file. Check the "
"URL passed to remote-add was valid."

#: common/flatpak-dir.c:13698
#, fuzzy, c-format
msgid "Invalid checksum for indexed summary %s for remote '%s'"
msgstr "Invalid checksum for extra data %s"

#: common/flatpak-dir.c:14388
#, c-format
msgid "Multiple branches available for %s, you must specify one of: "
msgstr "Multiple branches available for %s, you must specify one of: "

#: common/flatpak-dir.c:14454
#, c-format
msgid "Nothing matches %s"
msgstr "Nothing matches %s"

#: common/flatpak-dir.c:14562
#, c-format
msgid "Can't find ref %s%s%s%s%s"
msgstr "Can't find ref %s%s%s%s%s"

#: common/flatpak-dir.c:14605
#, c-format
msgid "Error searching remote %s: %s"
msgstr "Error searching remote %s: %s"

#: common/flatpak-dir.c:14702
#, c-format
msgid "Error searching local repository: %s"
msgstr "Error searching local repository: %s"

#: common/flatpak-dir.c:14839
#, c-format
msgid "%s/%s/%s not installed"
msgstr "%s/%s/%s not installed"

#: common/flatpak-dir.c:15042
#, c-format
msgid "Could not find installation %s"
msgstr "Could not find installation %s"

#: common/flatpak-dir.c:15612
#, c-format
msgid "Invalid file format, no %s group"
msgstr "Invalid file format, no %s group"

#: common/flatpak-dir.c:15617 common/flatpak-repo-utils.c:2836
#, c-format
msgid "Invalid version %s, only 1 supported"
msgstr "Invalid version %s, only 1 supported"

#: common/flatpak-dir.c:15622 common/flatpak-dir.c:15627
#, c-format
msgid "Invalid file format, no %s specified"
msgstr "Invalid file format, no %s specified"

#. Check some minimal size so we don't get crap
#: common/flatpak-dir.c:15647
msgid "Invalid file format, gpg key invalid"
msgstr "Invalid file format, gpg key invalid"

#: common/flatpak-dir.c:15675 common/flatpak-repo-utils.c:2917
msgid "Collection ID requires GPG key to be provided"
msgstr "Collection ID requires GPG key to be provided"

#: common/flatpak-dir.c:15718
#, c-format
msgid "Runtime %s, branch %s is already installed"
msgstr "Runtime %s, branch %s is already installed"

#: common/flatpak-dir.c:15719
#, c-format
msgid "App %s, branch %s is already installed"
msgstr "App %s, branch %s is already installed"

#: common/flatpak-dir.c:15953
#, c-format
msgid "Can't remove remote '%s' with installed ref %s (at least)"
msgstr "Can't remove remote '%s' with installed ref %s (at least)"

#: common/flatpak-dir.c:16058
#, c-format
msgid "Invalid character '/' in remote name: %s"
msgstr "Invalid character '/' in remote name: %s"

#: common/flatpak-dir.c:16064
#, c-format
msgid "No configuration for remote %s specified"
msgstr "No configuration for remote %s specified"

#: common/flatpak-dir.c:17597
#, fuzzy, c-format
msgid "Skipping deletion of mirror ref (%s, %s)…\n"
msgstr "Skipping non-deployed ref %s…\n"

#: common/flatpak-exports.c:931
#, c-format
msgid "An absolute path is required"
msgstr ""

#: common/flatpak-exports.c:948
#, fuzzy, c-format
msgid "Unable to open path \"%s\": %s"
msgstr "Unable to update %s: %s\n"

#: common/flatpak-exports.c:955
#, fuzzy, c-format
msgid "Unable to get file type of \"%s\": %s"
msgstr "Unable to create sync pipe"

#: common/flatpak-exports.c:964
#, c-format
msgid "File \"%s\" has unsupported type 0o%o"
msgstr ""

#: common/flatpak-exports.c:970
#, c-format
msgid "Unable to get filesystem information for \"%s\": %s"
msgstr ""

#: common/flatpak-exports.c:980
#, c-format
msgid "Ignoring blocking autofs path \"%s\""
msgstr ""

#: common/flatpak-exports.c:996 common/flatpak-exports.c:1009
#: common/flatpak-exports.c:1022
#, c-format
msgid "Path \"%s\" is reserved by Flatpak"
msgstr ""

#: common/flatpak-exports.c:1076
#, fuzzy, c-format
msgid "Unable to resolve symbolic link \"%s\": %s"
msgstr "Unable to update %s: %s\n"

#: common/flatpak-glib-backports.c:69
msgid "Empty string is not a number"
msgstr "Empty string is not a number"

#: common/flatpak-glib-backports.c:95
#, c-format
msgid "“%s” is not an unsigned number"
msgstr "“%s” is not an unsigned number"

#: common/flatpak-glib-backports.c:105
#, c-format
msgid "Number “%s” is out of bounds [%s, %s]"
msgstr "Number “%s” is out of bounds [%s, %s]"

#: common/flatpak-image-source.c:83
msgid "Only sha256 image checksums are supported"
msgstr ""

#: common/flatpak-image-source.c:100 common/flatpak-image-source.c:108
msgid "Image is not a manifest"
msgstr "Image is not a manifest"

#: common/flatpak-image-source.c:123
msgid "No org.flatpak.ref found in image"
msgstr ""

#: common/flatpak-image-source.c:148
#, c-format
msgid "Ref '%s' not found in registry"
msgstr "Ref '%s' not found in registry"

#: common/flatpak-image-source.c:157
msgid "Multiple images in registry, specify a ref with --ref"
msgstr "Multiple images in registry, specify a ref with --ref"

#: common/flatpak-installation.c:834
#, c-format
msgid "Ref %s not installed"
msgstr "Ref %s not installed"

#: common/flatpak-installation.c:875
#, c-format
msgid "App %s not installed"
msgstr "App %s not installed"

#: common/flatpak-installation.c:1395
#, c-format
msgid "Remote '%s' already exists"
msgstr "Remote '%s' already exists"

#: common/flatpak-installation.c:1946
#, c-format
msgid "As requested, %s was only pulled, but not installed"
msgstr "As requested, %s was only pulled, but not installed"

#: common/flatpak-instance.c:533 common/flatpak-instance.c:687
#: common/flatpak-instance.c:728
#, fuzzy, c-format
msgid "Unable to create directory %s"
msgstr "Unable to create sync pipe"

#: common/flatpak-instance.c:554
#, fuzzy, c-format
msgid "Unable to lock %s"
msgstr "Unable to lookup key ID %s: %d)"

#: common/flatpak-instance.c:627
#, fuzzy, c-format
msgid "Unable to create temporary directory in %s"
msgstr "Can't create deploy directory"

#: common/flatpak-instance.c:639
#, fuzzy, c-format
msgid "Unable to create file %s"
msgstr "Unable to create sync pipe"

#: common/flatpak-instance.c:646
#, fuzzy, c-format
msgid "Unable to update symbolic link %s/%s"
msgstr "Unable to update %s: %s\n"

#: common/flatpak-oci-registry.c:1197
msgid "Only Bearer authentication supported"
msgstr ""

#: common/flatpak-oci-registry.c:1206
#, fuzzy
msgid "Only realm in authentication request"
msgstr "Invalid dbus name %s"

#: common/flatpak-oci-registry.c:1213
#, fuzzy
msgid "Invalid realm in authentication request"
msgstr "Invalid dbus name %s"

#: common/flatpak-oci-registry.c:1283
#, fuzzy, c-format
msgid "Authorization failed: %s"
msgstr "Invalid dbus name %s"

#: common/flatpak-oci-registry.c:1285
msgid "Authorization failed"
msgstr ""

#: common/flatpak-oci-registry.c:1289
#, c-format
msgid "Unexpected response status %d when requesting token: %s"
msgstr ""

#: common/flatpak-oci-registry.c:1300
#, fuzzy
msgid "Invalid authentication request response"
msgstr "Invalid dbus name %s"

#: common/flatpak-oci-registry.c:1731
#, c-format
msgid "Flatpak was compiled without zstd support"
msgstr ""

#: common/flatpak-oci-registry.c:1923 common/flatpak-oci-registry.c:1975
#: common/flatpak-oci-registry.c:2004 common/flatpak-oci-registry.c:2059
#: common/flatpak-oci-registry.c:2115 common/flatpak-oci-registry.c:2193
#, fuzzy
msgid "Invalid delta file format"
msgstr "Invalid env format %s"

#: common/flatpak-oci-registry.c:3198 common/flatpak-oci-registry.c:3382
msgid "Invalid OCI image config"
msgstr ""

#: common/flatpak-oci-registry.c:3260 common/flatpak-oci-registry.c:3531
#, c-format
msgid "Wrong layer checksum, expected %s, was %s"
msgstr "Wrong layer checksum, expected %s, was %s"

#: common/flatpak-oci-registry.c:3359
#, c-format
msgid "No ref specified for OCI image %s"
msgstr "No ref specified for OCI image %s"

#: common/flatpak-oci-registry.c:3369
#, c-format
msgid "Wrong ref (%s) specified for OCI image %s, expected %s"
msgstr "Wrong ref (%s) specified for OCI image %s, expected %s"

#: common/flatpak-progress.c:236
#, c-format
msgid "Downloading metadata: %u/(estimating) %s"
msgstr "Downloading metadata: %u/(estimating) %s"

#: common/flatpak-progress.c:260
#, c-format
msgid "Downloading: %s/%s"
msgstr "Downloading: %s/%s"

#: common/flatpak-progress.c:280
#, c-format
msgid "Downloading extra data: %s/%s"
msgstr "Downloading extra data: %s/%s"

#: common/flatpak-progress.c:285
#, c-format
msgid "Downloading files: %d/%d %s"
msgstr "Downloading files: %d/%d %s"

#: common/flatpak-ref-utils.c:122
msgid "Name can't be empty"
msgstr "Name can't be empty"

#: common/flatpak-ref-utils.c:129
msgid "Name can't be longer than 255 characters"
msgstr "Name can't be longer than 255 characters"

#: common/flatpak-ref-utils.c:142
msgid "Name can't start with a period"
msgstr "Name can't start with a period"

#: common/flatpak-ref-utils.c:148
#, c-format
msgid "Name can't start with %c"
msgstr "Name can't start with %c"

#: common/flatpak-ref-utils.c:164
msgid "Name can't end with a period"
msgstr "Name can't end with a period"

#: common/flatpak-ref-utils.c:171 common/flatpak-ref-utils.c:183
msgid "Only last name segment can contain -"
msgstr "Only last name segment can contain -"

#: common/flatpak-ref-utils.c:174
#, c-format
msgid "Name segment can't start with %c"
msgstr "Name segment can't start with %c"

#: common/flatpak-ref-utils.c:186
#, c-format
msgid "Name can't contain %c"
msgstr "Name can't contain %c"

#: common/flatpak-ref-utils.c:195
msgid "Names must contain at least 2 periods"
msgstr "Names must contain at least 2 periods"

#: common/flatpak-ref-utils.c:312
#, fuzzy
msgid "Arch can't be empty"
msgstr "Branch can't be empty"

#: common/flatpak-ref-utils.c:323
#, fuzzy, c-format
msgid "Arch can't contain %c"
msgstr "Branch can't contain %c"

#: common/flatpak-ref-utils.c:385
msgid "Branch can't be empty"
msgstr "Branch can't be empty"

#: common/flatpak-ref-utils.c:395
#, c-format
msgid "Branch can't start with %c"
msgstr "Branch can't start with %c"

#: common/flatpak-ref-utils.c:405
#, c-format
msgid "Branch can't contain %c"
msgstr "Branch can't contain %c"

#: common/flatpak-ref-utils.c:615 common/flatpak-ref-utils.c:865
msgid "Ref too long"
msgstr ""

#: common/flatpak-ref-utils.c:627
#, fuzzy
msgid "Invalid remote name"
msgstr "Bad remote name: %s"

#: common/flatpak-ref-utils.c:641
#, c-format
msgid "%s is not application or runtime"
msgstr "%s is not application or runtime"

#: common/flatpak-ref-utils.c:650 common/flatpak-ref-utils.c:667
#: common/flatpak-ref-utils.c:683
#, c-format
msgid "Wrong number of components in %s"
msgstr "Wrong number of components in %s"

#: common/flatpak-ref-utils.c:656
#, fuzzy, c-format
msgid "Invalid name %.*s: %s"
msgstr "Invalid name %s: %s"

#: common/flatpak-ref-utils.c:673
#, fuzzy, c-format
msgid "Invalid arch: %.*s: %s"
msgstr "Invalid branch %s: %s"

#: common/flatpak-ref-utils.c:816
#, c-format
msgid "Invalid name %s: %s"
msgstr "Invalid name %s: %s"

#: common/flatpak-ref-utils.c:834
#, fuzzy, c-format
msgid "Invalid arch: %s: %s"
msgstr "Invalid branch %s: %s"

#: common/flatpak-ref-utils.c:853
#, fuzzy, c-format
msgid "Invalid branch: %s: %s"
msgstr "Invalid branch %s: %s"

#: common/flatpak-ref-utils.c:962 common/flatpak-ref-utils.c:970
#: common/flatpak-ref-utils.c:978
#, fuzzy, c-format
msgid "Wrong number of components in partial ref %s"
msgstr "Wrong number of components in runtime %s"

#: common/flatpak-ref-utils.c:1298
#, fuzzy
msgid " development platform"
msgstr "Use development runtime"

#: common/flatpak-ref-utils.c:1300
msgid " platform"
msgstr ""

#: common/flatpak-ref-utils.c:1302
#, fuzzy
msgid " application base"
msgstr "Application"

#: common/flatpak-ref-utils.c:1305
msgid " debug symbols"
msgstr ""

#: common/flatpak-ref-utils.c:1307
msgid " sourcecode"
msgstr ""

#: common/flatpak-ref-utils.c:1309
#, fuzzy
msgid " translations"
msgstr "Installation"

#: common/flatpak-ref-utils.c:1311
msgid " docs"
msgstr ""

#: common/flatpak-ref-utils.c:1578
#, c-format
msgid "Invalid id %s: %s"
msgstr "Invalid id %s: %s"

#: common/flatpak-remote.c:1216
#, c-format
msgid "Bad remote name: %s"
msgstr "Bad remote name: %s"

#: common/flatpak-remote.c:1220
#, fuzzy
msgid "No URL specified"
msgstr "No url specified"

#: common/flatpak-remote.c:1266
#, fuzzy
msgid "GPG verification must be enabled when a collection ID is set"
msgstr "GPG verification is required if collections are enabled"

#: common/flatpak-repo-utils.c:344
#, c-format
msgid "No extra data sources"
msgstr "No extra data sources"

#: common/flatpak-repo-utils.c:2817
#, c-format
msgid "Invalid %s: Missing group ‘%s’"
msgstr "Invalid %s: Missing group ‘%s’"

#: common/flatpak-repo-utils.c:2826
#, c-format
msgid "Invalid %s: Missing key ‘%s’"
msgstr "Invalid %s: Missing key ‘%s’"

#: common/flatpak-repo-utils.c:2876
msgid "Invalid gpg key"
msgstr "Invalid gpg key"

#: common/flatpak-repo-utils.c:3217
#, c-format
msgid "Error copying 64x64 icon for component %s: %s\n"
msgstr "Error copying 64x64 icon for component %s: %s\n"

#: common/flatpak-repo-utils.c:3223
#, c-format
msgid "Error copying 128x128 icon for component %s: %s\n"
msgstr "Error copying 128x128 icon for component %s: %s\n"

#: common/flatpak-repo-utils.c:3362
#, fuzzy, c-format
msgid "%s is end-of-life, ignoring for appstream"
msgstr "%s is end-of-life, ignoring\n"

#: common/flatpak-repo-utils.c:3397
#, c-format
msgid "No appstream data for %s: %s\n"
msgstr "No appstream data for %s: %s\n"

#: common/flatpak-repo-utils.c:3744
msgid "Invalid bundle, no ref in metadata"
msgstr "Invalid bundle, no ref in metadata"

#: common/flatpak-repo-utils.c:3846
#, c-format
msgid "Collection ‘%s’ of bundle doesn’t match collection ‘%s’ of remote"
msgstr "Collection ‘%s’ of bundle doesn’t match collection ‘%s’ of remote"

#: common/flatpak-repo-utils.c:3923
msgid "Metadata in header and app are inconsistent"
msgstr "Metadata in header and app are inconsistent"

#: common/flatpak-run.c:951
msgid "No systemd user session available, cgroups not available"
msgstr "No systemd user session available, cgroups not available"

#: common/flatpak-run.c:1496
msgid "Unable to allocate instance id"
msgstr "Unable to allocate instance id"

#: common/flatpak-run.c:1632 common/flatpak-run.c:1641
#, c-format
msgid "Failed to open flatpak-info file: %s"
msgstr "Failed to open flatpak-info file: %s"

#: common/flatpak-run.c:1668
#, c-format
msgid "Failed to open bwrapinfo.json file: %s"
msgstr "Failed to open bwrapinfo.json file: %s"

#: common/flatpak-run.c:1689
#, fuzzy, c-format
msgid "Failed to write to instance id fd: %s"
msgstr "Failed to write summary cache: "

#: common/flatpak-run.c:2096
msgid "Initialize seccomp failed"
msgstr "Initialise seccomp failed"

#: common/flatpak-run.c:2135
#, fuzzy, c-format
msgid "Failed to add architecture to seccomp filter: %s"
msgstr "Failed to add architecture to seccomp filter"

#: common/flatpak-run.c:2143
#, fuzzy, c-format
msgid "Failed to add multiarch architecture to seccomp filter: %s"
msgstr "Failed to add multiarch architecture to seccomp filter"

#: common/flatpak-run.c:2175 common/flatpak-run.c:2192
#: common/flatpak-run.c:2214
#, fuzzy, c-format
msgid "Failed to block syscall %d: %s"
msgstr "Failed to block syscall %d"

#: common/flatpak-run.c:2247
#, fuzzy, c-format
msgid "Failed to export bpf: %s"
msgstr "Failed to export bpf"

#: common/flatpak-run.c:2587
#, c-format
msgid "Failed to open ‘%s’"
msgstr "Failed to open ‘%s’"

#: common/flatpak-run.c:2597
#, c-format
msgid ""
"Directory forwarding needs version 4 of the document portal (have version %d)"
msgstr ""

#: common/flatpak-run.c:2915
#, c-format
msgid "ldconfig failed, exit status %d"
msgstr "ldconfig failed, exit status %d"

#: common/flatpak-run.c:2922
msgid "Can't open generated ld.so.cache"
msgstr "Can't open generated ld.so.cache"

#. Translators: The placeholder is for an app ref.
#: common/flatpak-run.c:3045
#, c-format
msgid "Running %s is not allowed by the policy set by your administrator"
msgstr ""

#: common/flatpak-run.c:3202
msgid ""
"\"flatpak run\" is not intended to be run as `sudo flatpak run`. Use `sudo "
"-i` or `su -l` instead and invoke \"flatpak run\" from inside the new shell."
msgstr ""

#: common/flatpak-run.c:3413
#, c-format
msgid "Failed to migrate from %s: %s"
msgstr "Failed to migrate from %s: %s"

#: common/flatpak-run.c:3434
#, c-format
msgid "Failed to migrate old app data directory %s to new name %s: %s"
msgstr "Failed to migrate old app data directory %s to new name %s: %s"

#: common/flatpak-run.c:3443
#, c-format
msgid "Failed to create symlink while migrating %s: %s"
msgstr "Failed to create symlink while migrating %s: %s"

#: common/flatpak-run-dbus.c:46
msgid "Failed to open app info file"
msgstr "Failed to open app info file"

#: common/flatpak-run-dbus.c:149
msgid "Unable to create sync pipe"
msgstr "Unable to create sync pipe"

#: common/flatpak-run-dbus.c:185
msgid "Failed to sync with dbus proxy"
msgstr "Failed to sync with dbus proxy"

#: common/flatpak-transaction.c:2275
#, c-format
msgid "Warning: Problem looking for related refs: %s"
msgstr "Warning: Problem looking for related refs: %s"

#: common/flatpak-transaction.c:2493
#, c-format
msgid "The application %s requires the runtime %s which was not found"
msgstr "The application %s requires the runtime %s which was not found"

#: common/flatpak-transaction.c:2509
#, c-format
msgid "The application %s requires the runtime %s which is not installed"
msgstr "The application %s requires the runtime %s which is not installed"

#: common/flatpak-transaction.c:2641
#, c-format
msgid "Can't uninstall %s which is needed by %s"
msgstr "Can't uninstall %s which is needed by %s"

#: common/flatpak-transaction.c:2740
#, c-format
msgid "Remote %s disabled, ignoring %s update"
msgstr "Remote %s disabled, ignoring %s update"

#: common/flatpak-transaction.c:2773
#, c-format
msgid "%s is already installed"
msgstr "%s is already installed"

#: common/flatpak-transaction.c:2776
#, c-format
msgid "%s is already installed from remote %s"
msgstr "%s is already installed from remote %s"

#: common/flatpak-transaction.c:3120
#, c-format
msgid "Invalid .flatpakref: %s"
msgstr "Invalid .flatpakref: %s"

#: common/flatpak-transaction.c:3161
msgid "Warning: Could not mark already installed apps as preinstalled"
msgstr ""

#: common/flatpak-transaction.c:3382
#, c-format
msgid "Error updating remote metadata for '%s': %s"
msgstr "Error updating remote metadata for '%s': %s"

#: common/flatpak-transaction.c:3885
#, c-format
msgid ""
"Warning: Treating remote fetch error as non-fatal since %s is already "
"installed: %s"
msgstr ""
"Warning: Treating remote fetch error as non-fatal since %s is already "
"installed: %s"

#: common/flatpak-transaction.c:4209
#, fuzzy, c-format
msgid "No authenticator installed for remote '%s'"
msgstr "Authentication is required to update remote info"

#: common/flatpak-transaction.c:4313 common/flatpak-transaction.c:4320
#, fuzzy, c-format
msgid "Failed to get tokens for ref: %s"
msgstr "Failed to determine parts from ref: %s"

#: common/flatpak-transaction.c:4315 common/flatpak-transaction.c:4322
#, fuzzy
msgid "Failed to get tokens for ref"
msgstr "Failed to determine parts from ref: %s"

#: common/flatpak-transaction.c:4580
#, c-format
msgid "Ref %s from %s matches more than one transaction operation"
msgstr ""

#: common/flatpak-transaction.c:4581 common/flatpak-transaction.c:4591
#, fuzzy
msgid "any remote"
msgstr "Remote"

#: common/flatpak-transaction.c:4590
#, c-format
msgid "No transaction operation found for ref %s from %s"
msgstr ""

#: common/flatpak-transaction.c:4713
#, fuzzy, c-format
msgid "Flatpakrepo URL %s not file, HTTP or HTTPS"
msgstr "Flatpakrepo URL %s not HTTP or HTTPS"

#: common/flatpak-transaction.c:4719
#, c-format
msgid "Can't load dependent file %s: "
msgstr "Can't load dependent file %s: "

#: common/flatpak-transaction.c:4727
#, c-format
msgid "Invalid .flatpakrepo: %s"
msgstr "Invalid .flatpakrepo: %s"

#: common/flatpak-transaction.c:5454
msgid "Transaction already executed"
msgstr "Transaction already executed"

#: common/flatpak-transaction.c:5469
msgid ""
"Refusing to operate on a user installation as root! This can lead to "
"incorrect file ownership and permission errors."
msgstr ""
"Refusing to operate on a user installation as root! This can lead to "
"incorrect file ownership and permission errors."

#: common/flatpak-transaction.c:5567 common/flatpak-transaction.c:5580
msgid "Aborted by user"
msgstr "Aborted by user"

#: common/flatpak-transaction.c:5605
#, c-format
msgid "Skipping %s due to previous error"
msgstr "Skipping %s due to previous error"

#: common/flatpak-transaction.c:5659
#, fuzzy, c-format
msgid "Aborted due to failure (%s)"
msgstr "Aborted due to failure (%s)"

#: common/flatpak-uri.c:118
#, fuzzy, no-c-format
msgid "Invalid %-encoding in URI"
msgstr "Invalid dbus name %s"

#: common/flatpak-uri.c:135
msgid "Illegal character in URI"
msgstr ""

#: common/flatpak-uri.c:169
msgid "Non-UTF-8 characters in URI"
msgstr ""

#: common/flatpak-uri.c:275
#, c-format
msgid "Invalid IPv6 address ‘%.*s’ in URI"
msgstr ""

#: common/flatpak-uri.c:330
#, c-format
msgid "Illegal encoded IP address ‘%.*s’ in URI"
msgstr ""

#: common/flatpak-uri.c:342
#, c-format
msgid "Illegal internationalized hostname ‘%.*s’ in URI"
msgstr ""

#: common/flatpak-uri.c:374 common/flatpak-uri.c:386
#, fuzzy, c-format
msgid "Could not parse port ‘%.*s’ in URI"
msgstr "Could not parse '%s'"

#: common/flatpak-uri.c:393
#, c-format
msgid "Port ‘%.*s’ in URI is out of range"
msgstr ""

#: common/flatpak-uri.c:910
msgid "URI is not absolute, and no base URI was provided"
msgstr ""

#: common/flatpak-usb.c:83
#, c-format
msgid "USB device query 'all' must not have data"
msgstr ""

#: common/flatpak-usb.c:102
#, c-format
msgid "USB query rule 'cls' must be in the form CLASS:SUBCLASS or CLASS:*"
msgstr ""

#: common/flatpak-usb.c:111
#, fuzzy, c-format
msgid "Invalid USB class"
msgstr "Invalid id %s: %s"

#: common/flatpak-usb.c:125
#, c-format
msgid "Invalid USB subclass"
msgstr ""

#: common/flatpak-usb.c:141 common/flatpak-usb.c:148
#, c-format
msgid "USB query rule 'dev' must have a valid 4-digit hexadecimal product id"
msgstr ""

#: common/flatpak-usb.c:164 common/flatpak-usb.c:171
#, c-format
msgid "USB query rule 'vnd' must have a valid 4-digit hexadecimal vendor id"
msgstr ""

#: common/flatpak-usb.c:205
#, c-format
msgid "USB device queries must be in the form TYPE:DATA"
msgstr ""

#: common/flatpak-usb.c:225
#, c-format
msgid "Unknown USB query rule %s"
msgstr ""

#: common/flatpak-usb.c:248
#, c-format
msgid "Empty USB query"
msgstr ""

#: common/flatpak-usb.c:274
#, c-format
msgid "Multiple USB query rules of the same type is not supported"
msgstr ""

#: common/flatpak-usb.c:283
#, c-format
msgid "'all' must not contain extra query rules"
msgstr ""

#: common/flatpak-usb.c:291
#, c-format
msgid "USB queries with 'dev' must also specify vendors"
msgstr ""

#: common/flatpak-utils.c:712
msgid "Glob can't match apps"
msgstr ""

#: common/flatpak-utils.c:737
msgid "Empty glob"
msgstr "Empty glob"

#: common/flatpak-utils.c:756
msgid "Too many segments in glob"
msgstr "Too many segments in glob"

#: common/flatpak-utils.c:777
#, c-format
msgid "Invalid glob character '%c'"
msgstr "Invalid glob character '%c'"

#: common/flatpak-utils.c:831
#, c-format
msgid "Missing glob on line %d"
msgstr "Missing glob on line %d"

#: common/flatpak-utils.c:835
#, c-format
msgid "Trailing text on line %d"
msgstr "Trailing text on line %d"

#: common/flatpak-utils.c:839
#, c-format
msgid "on line %d"
msgstr "on line %d"

#: common/flatpak-utils.c:861
#, c-format
msgid "Unexpected word '%s' on line %d"
msgstr "Unexpected word '%s' on line %d"

#: common/flatpak-utils.c:2118
#, c-format
msgid "Invalid require-flatpak argument %s"
msgstr "Invalid require-flatpak argument %s"

#: common/flatpak-utils.c:2128 common/flatpak-utils.c:2147
#, c-format
msgid "%s needs a later flatpak version (%s)"
msgstr "%s needs a later flatpak version (%s)"

#: oci-authenticator/flatpak-oci-authenticator.c:291
msgid "Not a oci remote, missing summary.xa.oci-repository"
msgstr ""

#: oci-authenticator/flatpak-oci-authenticator.c:477
msgid "Not a OCI remote"
msgstr ""

#: oci-authenticator/flatpak-oci-authenticator.c:488
#, fuzzy
msgid "Invalid token"
msgstr "Invalid gpg key"

#: portal/flatpak-portal.c:2292
#, fuzzy, c-format
msgid "No portal support found"
msgstr "No summary found"

#: portal/flatpak-portal.c:2298
msgid "Deny"
msgstr ""

#: portal/flatpak-portal.c:2300
#, fuzzy
msgid "Update"
msgstr "update"

#: portal/flatpak-portal.c:2305
#, fuzzy, c-format
msgid "Update %s?"
msgstr "Updating %s\n"

#: portal/flatpak-portal.c:2317
msgid "The application wants to update itself."
msgstr ""

#: portal/flatpak-portal.c:2318
msgid "Update access can be changed any time from the privacy settings."
msgstr ""

#: portal/flatpak-portal.c:2343
#, c-format
msgid "Application update not allowed"
msgstr ""

#: portal/flatpak-portal.c:2501
#, c-format
msgid "Self update not supported, new version requires new permissions"
msgstr ""

#: portal/flatpak-portal.c:2684 portal/flatpak-portal.c:2702
#, fuzzy, c-format
msgid "Update ended unexpectedly"
msgstr "Update signed runtime"

#. SECURITY:
#. - Normal users need admin authentication to install software
#. system-wide.
#. - Note that we install polkit rules that allow local users
#. in the wheel group to install without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:23
msgid "Install signed application"
msgstr "Install signed application"

#: system-helper/org.freedesktop.Flatpak.policy.in:24
#: system-helper/org.freedesktop.Flatpak.policy.in:42
msgid "Authentication is required to install software"
msgstr "Authentication is required to install software"

#. SECURITY:
#. - Normal users need admin authentication to install software
#. system-wide.
#. - Note that we install polkit rules that allow local users
#. in the wheel group to install without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:41
msgid "Install signed runtime"
msgstr "Install signed runtime"

#. SECURITY:
#. - Normal users do not require admin authentication to update an
#. app as the commit will be signed, and the action is required
#. to update the system when unattended.
#. - Changing this to anything other than 'yes' will break unattended
#. updates.
#: system-helper/org.freedesktop.Flatpak.policy.in:60
msgid "Update signed application"
msgstr "Update signed application"

#: system-helper/org.freedesktop.Flatpak.policy.in:61
#: system-helper/org.freedesktop.Flatpak.policy.in:80
msgid "Authentication is required to update software"
msgstr "Authentication is required to update software"

#. SECURITY:
#. - Normal users do not require admin authentication to update a
#. runtime as the commit will be signed, and the action is required
#. to update the system when unattended.
#. - Changing this to anything other than 'yes' will break unattended
#. updates.
#: system-helper/org.freedesktop.Flatpak.policy.in:79
msgid "Update signed runtime"
msgstr "Update signed runtime"

#. SECURITY:
#. - Normal users do not need authentication to update metadata
#. from signed repositories.
#: system-helper/org.freedesktop.Flatpak.policy.in:94
msgid "Update remote metadata"
msgstr "Update remote metadata"

#: system-helper/org.freedesktop.Flatpak.policy.in:95
msgid "Authentication is required to update remote info"
msgstr "Authentication is required to update remote info"

#. SECURITY:
#. - Normal users do not need authentication to modify the
#. OSTree repository
#. - Note that we install polkit rules that allow local users
#. in the wheel group to modify repos without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:111
msgid "Update system repository"
msgstr "Update system repository"

#: system-helper/org.freedesktop.Flatpak.policy.in:112
msgid "Authentication is required to modify a system repository"
msgstr "Authentication is required to modify a system repository"

#. SECURITY:
#. - Normal users need admin authentication to install software
#. system-wide.
#: system-helper/org.freedesktop.Flatpak.policy.in:126
msgid "Install bundle"
msgstr "Install bundle"

#: system-helper/org.freedesktop.Flatpak.policy.in:127
msgid "Authentication is required to install software from $(path)"
msgstr "Authentication is required to install software from $(path)"

#. SECURITY:
#. - Normal users need admin authentication to uninstall software
#. system-wide.
#. - Note that we install polkit rules that allow local users
#. in the wheel group to uninstall without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:144
msgid "Uninstall runtime"
msgstr "Uninstall runtime"

#: system-helper/org.freedesktop.Flatpak.policy.in:145
msgid "Authentication is required to uninstall software"
msgstr "Authentication is required to uninstall software"

#. SECURITY:
#. - Normal users need admin authentication to uninstall software
#. system-wide.
#. - Note that we install polkit rules that allow local users
#. in the wheel group to uninstall without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:161
msgid "Uninstall app"
msgstr "Uninstall app"

#: system-helper/org.freedesktop.Flatpak.policy.in:162
msgid "Authentication is required to uninstall $(ref)"
msgstr "Authentication is required to uninstall $(ref)"

#. SECURITY:
#. - Normal users need admin authentication to configure system-wide
#. software repositories.
#: system-helper/org.freedesktop.Flatpak.policy.in:177
msgid "Configure Remote"
msgstr "Configure Remote"

#: system-helper/org.freedesktop.Flatpak.policy.in:178
msgid "Authentication is required to configure software repositories"
msgstr "Authentication is required to configure software repositories"

#. SECURITY:
#. - Normal users need admin authentication to configure the system-wide
#. Flatpak installation.
#: system-helper/org.freedesktop.Flatpak.policy.in:192
msgid "Configure"
msgstr "Configure"

#: system-helper/org.freedesktop.Flatpak.policy.in:193
msgid "Authentication is required to configure software installation"
msgstr "Authentication is required to configure software installation"

#. SECURITY:
#. - Normal users do not require admin authentication to update
#. appstream data as it will be signed, and the action is required
#. to update the system when unattended.
#. - Changing this to anything other than 'yes' will break unattended
#. updates.
#: system-helper/org.freedesktop.Flatpak.policy.in:210
msgid "Update appstream"
msgstr "Update appstream"

#: system-helper/org.freedesktop.Flatpak.policy.in:211
msgid "Authentication is required to update information about software"
msgstr "Authentication is required to update information about software"

#. SECURITY:
#. - Normal users do not require admin authentication to update
#. metadata as it will be signed, and the action is required
#. to update the system when unattended.
#. - Changing this to anything other than 'yes' will break unattended
#. updates.
#: system-helper/org.freedesktop.Flatpak.policy.in:228
msgid "Update metadata"
msgstr "Update metadata"

#: system-helper/org.freedesktop.Flatpak.policy.in:229
msgid "Authentication is required to update metadata"
msgstr "Authentication is required to update metadata"

#. SECURITY:
#. - Authorisation to actually install software is controlled by
#. org.freedesktop.Flatpak.app-install.
#. - This action is checked after app-install, as it can only be done
#. once the app’s data (including its content rating) has been
#. downloaded.
#. - This action is checked to see if the installation should be allowed
#. based on whether the app being installed has content which doesn’t
#. comply with the user’s parental controls policy (the content is
#. ‘too extreme’).
#. - It is checked only if an app has too extreme content for the user
#. who is trying to install it (in which case, the app is ‘unsafe’).
#. - Typically, normal users will need admin permission to install apps
#. with extreme content; admins will be able to install it without
#. additional checks.
#. - In order to configure the policy so that admins can install safe and
#. unsafe software anywhere without authorisation, and non-admins can
#. install safe software in their user or system dirs without
#. authorisation, but need authorisation to install unsafe software
#. anywhere:
#. * Unconditionally return `yes` from `app-install`.
#. * Return `auth_admin` from `override-parental-controls` for users
#. not in `@privileged_group@`, and `yes` for users in it.
#. * Set the malcontent `is-{user,system}-installation-allowed`
#. properties of all non-admins’ parental controls policies to true.
#. - In order to configure the policy so that admins can install safe and
#. unsafe software anywhere without authorisation, and non-admins can
#. install safe software in their user dir without authorisation, but
#. need authorisation to install safe software in the system dir or to
#. install unsafe software anywhere:
#. * Unconditionally return `yes` from `app-install`.
#. * Return `auth_admin` from `override-parental-controls` for users
#. not in `@privileged_group@`, and `yes` for users in it.
#. * Set the malcontent `is-user-installation-allowed` property of all
#. non-admins’ parental controls policies to true.
#. * Set the malcontent `is-system-installation-allowed` property of
#. all non-admins’ parental controls policies to false.
#. - In order to configure the policy so that all users (including
#. admins) can install safe software anywhere without authorisation,
#. but need authorisation to install unsafe software anywhere (i.e.
#. applying parental controls to admins too):
#. * Unconditionally return `yes` from `app-install`.
#. * Unconditionally return `auth_admin` from `override-parental-controls`.
#. * Set the malcontent `is-user-installation-allowed` property of all
#. users’ parental controls policies to true.
#. * Set the malcontent `is-system-installation-allowed` property of
#. all users’ parental controls policies to true.
#: system-helper/org.freedesktop.Flatpak.policy.in:287
msgid "Override parental controls for installs"
msgstr ""

#: system-helper/org.freedesktop.Flatpak.policy.in:288
#, fuzzy
msgid ""
"Authentication is required to install software which is restricted by your "
"parental controls policy"
msgstr "Authentication is required to install software from $(path)"

#. SECURITY:
#. - This is like org.freedesktop.Flatpak.override-parental-controls, but
#. it’s queried for app updates, whereas the former is queried for app
#. installs.
#. - As with the above action, this one is only queried if
#. org.freedesktop.Flatpak.app-update has allowed the app update, and
#. only if the app being updated has too extreme content for the user
#. who is trying to update it.
#. - The default policy for this is to *allow* updates to ‘too extreme’
#. apps by default, on the basis that having an out-of-date (i.e.
#. insecure or unsupported) app is a worse outcome than automatically
#. installing an update which has radically different content from the
#. version of the app which the parent originally vetted and installed.
#: system-helper/org.freedesktop.Flatpak.policy.in:313
msgid "Override parental controls for updates"
msgstr ""

#: system-helper/org.freedesktop.Flatpak.policy.in:314
#, fuzzy
msgid ""
"Authentication is required to update software which is restricted by your "
"parental controls policy"
msgstr "Authentication is required to install software from $(path)"

#~ msgid "Installed:"
#~ msgstr "Installed:"

#~ msgid "Download:"
#~ msgstr "Download:"

#, c-format
#~ msgid "No gpg key found with ID %s (homedir: %s)"
#~ msgstr "No gpg key found with ID %s (homedir: %s)"

#, fuzzy, c-format
#~ msgid "Unable to lookup key ID %s: %d"
#~ msgstr "Unable to lookup key ID %s: %d)"

#, c-format
#~ msgid "Error signing commit: %d"
#~ msgstr "Error signing commit: %d"

#, c-format
#~ msgid ""
#~ "Found similar ref(s) for ‘%s’ in remote ‘%s’ (%s).\n"
#~ "Use this remote?"
#~ msgstr ""
#~ "Found similar ref(s) for ‘%s’ in remote ‘%s’ (%s).\n"
#~ "Use this remote?"

#, fuzzy, c-format
#~ msgid "No entry for %s in remote '%s' summary cache "
#~ msgstr "No entry for %s in remote '%s' summary flatpak cache "

#, fuzzy, c-format
#~ msgid "Failed to uninstall %s for rebase to %s: "
#~ msgstr "Failed to rebase %s to %s: "

#, fuzzy, c-format
#~ msgid "Failed to uninstall %s for rebase to %s: %s\n"
#~ msgstr "Failed to rebase %s to %s: %s\n"

#, fuzzy, c-format
#~ msgid "Unable to open directory %s"
#~ msgstr "Unable to connect to system bus"

#~ msgid "install"
#~ msgstr "install"

#~ msgid "update"
#~ msgstr "update"

#~ msgid "install bundle"
#~ msgstr "install bundle"

#~ msgid "uninstall"
#~ msgstr "uninstall"

#~ msgid "Warning:"
#~ msgstr "Warning:"

#, fuzzy
#~ msgid "runtime"
#~ msgstr "Runtime"

#, fuzzy
#~ msgid "app"
#~ msgstr "App"

#~ msgid "[REF…] - Uninstall an application"
#~ msgstr "[REF…] - Uninstall an application"

#, c-format
#~ msgid "Replace it with %s?"
#~ msgstr "Replace it with %s?"

#, c-format
#~ msgid "Invalid deployed ref %s: "
#~ msgstr "Invalid deployed ref %s: "

#, c-format
#~ msgid "Deployed ref %s kind does not match commit (%s)"
#~ msgstr "Deployed ref %s kind does not match commit (%s)"

#, c-format
#~ msgid "Deployed ref %s name does not match commit (%s)"
#~ msgstr "Deployed ref %s name does not match commit (%s)"

#, c-format
#~ msgid "Deployed ref %s arch does not match commit (%s)"
#~ msgstr "Deployed ref %s arch does not match commit (%s)"

#, c-format
#~ msgid "Failed to determine parts from ref: %s"
#~ msgstr "Failed to determine parts from ref: %s"

#, c-format
#~ msgid "Invalid arch %s"
#~ msgstr "Invalid arch %s"

#, fuzzy, c-format
#~ msgid "Related ref '%s' is only partially installed"
#~ msgstr "Requested extension %s is only partially installed"

#, fuzzy, c-format
#~ msgid "Ref '%s' is only partially installed"
#~ msgstr "Requested extension %s is only partially installed"

#, c-format
#~ msgid "No such ref (%s, %s) in remote %s"
#~ msgstr "No such ref (%s, %s) in remote %s"

#, c-format
#~ msgid "No flatpak cache in remote '%s' summary"
#~ msgstr "No flatpak cache in remote '%s' summary"

#, c-format
#~ msgid "No such ref (%s, %s) in remote %s or elsewhere"
#~ msgstr "No such ref (%s, %s) in remote %s or elsewhere"

#, c-format
#~ msgid "No remotes found which provide these refs: [%s]"
#~ msgstr "No remotes found which provide these refs: [%s]"

#, c-format
#~ msgid "No remotes found which provide the ref (%s, %s)"
#~ msgstr "No remotes found which provide the ref (%s, %s)"

#~ msgid "No summary found"
#~ msgstr "No summary found"

#, c-format
#~ msgid ""
#~ "GPG verification enabled, but no summary signatures found for remote '%s'"
#~ msgstr ""
#~ "GPG verification enabled, but no summary signatures found for remote '%s'"

#, c-format
#~ msgid ""
#~ "GPG signatures found for remote '%s', but none are in trusted keyring"
#~ msgstr ""
#~ "GPG signatures found for remote '%s', but none are in trusted keyring"

#~ msgid "Expected commit metadata to have ref binding information, found none"
#~ msgstr ""
#~ "Expected commit metadata to have ref binding information, found none"

#~ msgid ""
#~ "Expected commit metadata to have collection ID binding information, found "
#~ "none"
#~ msgstr ""
#~ "Expected commit metadata to have collection ID binding information, found "
#~ "none"

#, c-format
#~ msgid ""
#~ "Commit has collection ID ‘%s’ in collection binding metadata, while the "
#~ "remote it came from has collection ID ‘%s’"
#~ msgstr ""
#~ "Commit has collection ID ‘%s’ in collection binding metadata, while the "
#~ "remote it came from has collection ID ‘%s’"

#~ msgid "Deployed metadata does not match commit"
#~ msgstr "Deployed metadata does not match commit"

#, c-format
#~ msgid "No repo metadata cached for remote '%s'"
#~ msgstr "No repo metadata cached for remote '%s'"

#~ msgid "No metadata branch for OCI"
#~ msgstr "No metadata branch for OCI"

#, c-format
#~ msgid "Invalid group: %d"
#~ msgstr "Invalid group: %d"

#, c-format
#~ msgid "Warning: Can't find %s metadata for dependencies: %s"
#~ msgstr "Warning: Can't find %s metadata for dependencies: %s"

#~ msgid "Not running as root, may be unable to enter namespace"
#~ msgstr "Not running as root, may be unable to enter namespace"

#~ msgid "Default system installation"
#~ msgstr "Default system installation"

===== ./po/pt_BR.po =====
# Brazilian Portuguese translation for flatpak.
# Copyright (C) 2026 THE flatpak'S COPYRIGHT HOLDER
# This file is distributed under the same license as the flatpak package.
# Fábio Nogueira <fnogueira@gnome.org>, 2017.
# Bruno Lopes <brunolopesdsilv@gmail.com>, 2020-2021.
# Matheus Barbosa <mdpb.matheus@gmail.com>, 2022.
# Álvaro Burns <>, 2025.
# Rafael Fontenelle <rafaelff@gnome.org>, 2017-2026.
#
msgid ""
msgstr ""
"Project-Id-Version: flatpak main\n"
"Report-Msgid-Bugs-To: https://github.com/flatpak/flatpak/issues\n"
"POT-Creation-Date: 2026-05-27 16:39+0200\n"
"PO-Revision-Date: 2026-01-21 15:19-0300\n"
"Last-Translator: Rafael Fontenelle <rafaelff@gnome.org>\n"
"Language-Team: Brazilian Portuguese <https://br.gnome.org/traducao>\n"
"Language: pt_BR\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
"X-Generator: Gtranslator 49.0\n"

#: app/flatpak-builtins-build-bundle.c:59
msgid "Export runtime instead of app"
msgstr "Exporta runtime em vez do aplicativo"

#: app/flatpak-builtins-build-bundle.c:60
msgid "Arch to bundle for"
msgstr "Arquitetura para a qual será empacotada"

#: app/flatpak-builtins-build-bundle.c:60
#: app/flatpak-builtins-build-export.c:62 app/flatpak-builtins-build-init.c:53
#: app/flatpak-builtins-build-sign.c:42 app/flatpak-builtins-create-usb.c:46
#: app/flatpak-builtins-info.c:55 app/flatpak-builtins-install.c:67
#: app/flatpak-builtins-list.c:50 app/flatpak-builtins-make-current.c:38
#: app/flatpak-builtins-remote-info.c:54 app/flatpak-builtins-remote-ls.c:56
#: app/flatpak-builtins-run.c:158 app/flatpak-builtins-search.c:37
#: app/flatpak-builtins-uninstall.c:54 app/flatpak-builtins-update.c:56
msgid "ARCH"
msgstr "ARQUITETURA"

#: app/flatpak-builtins-build-bundle.c:61
msgid "URL for repo"
msgstr "URL para o repo"

#: app/flatpak-builtins-build-bundle.c:61
#: app/flatpak-builtins-build-bundle.c:62
#: app/flatpak-builtins-build-update-repo.c:68
#: app/flatpak-builtins-build-update-repo.c:72
#: app/flatpak-builtins-build-update-repo.c:73
#: app/flatpak-builtins-history.c:69 app/flatpak-builtins-remote-add.c:80
#: app/flatpak-builtins-remote-add.c:81 app/flatpak-builtins-remote-add.c:85
#: app/flatpak-builtins-remote-list.c:53
#: app/flatpak-builtins-remote-modify.c:70
#: app/flatpak-builtins-remote-modify.c:85
#: app/flatpak-builtins-remote-modify.c:86
#: app/flatpak-builtins-remote-modify.c:90
msgid "URL"
msgstr "URL"

#: app/flatpak-builtins-build-bundle.c:62
msgid "URL for runtime flatpakrepo file"
msgstr "URL para o arquivo de flatpakrepo de runtime"

#: app/flatpak-builtins-build-bundle.c:63
msgid "Add GPG key from FILE (- for stdin)"
msgstr "Adiciona uma chave GPG do ARQUIVO (- para stdin)"

#: app/flatpak-builtins-build-bundle.c:63 app/flatpak-builtins-build.c:54
#: app/flatpak-builtins-build-export.c:67
#: app/flatpak-builtins-build-update-repo.c:83
#: app/flatpak-builtins-install.c:81 app/flatpak-builtins-remote-add.c:84
#: app/flatpak-builtins-remote-add.c:86 app/flatpak-builtins-remote-modify.c:89
#: app/flatpak-builtins-remote-modify.c:92
msgid "FILE"
msgstr "ARQUIVO"

#: app/flatpak-builtins-build-bundle.c:64
msgid "GPG Key ID to sign the OCI image with"
msgstr "ID da chave GPG para assinar a imagem OCI"

#: app/flatpak-builtins-build-bundle.c:64
#: app/flatpak-builtins-build-commit-from.c:68
#: app/flatpak-builtins-build-export.c:68
#: app/flatpak-builtins-build-import-bundle.c:49
#: app/flatpak-builtins-build-sign.c:44
#: app/flatpak-builtins-build-update-repo.c:84
msgid "KEY-ID"
msgstr "ID-CHAVE"

#: app/flatpak-builtins-build-bundle.c:65
#: app/flatpak-builtins-build-commit-from.c:69
#: app/flatpak-builtins-build-export.c:71
#: app/flatpak-builtins-build-import-bundle.c:50
#: app/flatpak-builtins-build-sign.c:45
#: app/flatpak-builtins-build-update-repo.c:85
msgid "GPG Homedir to use when looking for keyrings"
msgstr "Diretório do GPG para usar quando estiver procurando por chaveiros"

#: app/flatpak-builtins-build-bundle.c:65
#: app/flatpak-builtins-build-commit-from.c:69
#: app/flatpak-builtins-build-export.c:71
#: app/flatpak-builtins-build-import-bundle.c:50
#: app/flatpak-builtins-build-sign.c:45
#: app/flatpak-builtins-build-update-repo.c:85
msgid "HOMEDIR"
msgstr "HOMEDIR"

#: app/flatpak-builtins-build-bundle.c:66
msgid "OSTree commit to create a delta bundle from"
msgstr "Commit OSTree para criar um pacote delta de"

#: app/flatpak-builtins-build-bundle.c:66 app/flatpak-builtins-remote-info.c:55
#: app/flatpak-builtins-update.c:57
msgid "COMMIT"
msgstr "COMMIT"

#: app/flatpak-builtins-build-bundle.c:67
msgid "Export oci image instead of flatpak bundle"
msgstr "Exporta a imagem oci em vez do pacote flatpak"

#: app/flatpak-builtins-build-bundle.c:70
msgid "How to compress OCI image layers (default: gzip)"
msgstr "Como comprimir camadas de image OCI (padrão: gzip)"

#: app/flatpak-builtins-build-bundle.c:634
msgid ""
"LOCATION FILENAME NAME [BRANCH] - Create a single file bundle from a local "
"repository"
msgstr ""
"LOCALIZAÇÃO ARQUIVO NOME [RAMO] – Cria um único arquivo de pacote de um "
"repositório local"

#: app/flatpak-builtins-build-bundle.c:641
msgid "LOCATION, FILENAME and NAME must be specified"
msgstr "LOCALIZAÇÃO, ARQUIVO e NOME devem ser especificados"

#: app/flatpak-builtins-build-bundle.c:644
#: app/flatpak-builtins-build-export.c:844
#: app/flatpak-builtins-build-import-bundle.c:136
#: app/flatpak-builtins-build-init.c:217 app/flatpak-builtins-build-sign.c:76
#: app/flatpak-builtins-document-export.c:112
#: app/flatpak-builtins-document-info.c:75
#: app/flatpak-builtins-document-list.c:191
#: app/flatpak-builtins-document-unexport.c:70
#: app/flatpak-builtins-history.c:482 app/flatpak-builtins-info.c:130
#: app/flatpak-builtins-install.c:181 app/flatpak-builtins-install.c:234
#: app/flatpak-builtins-install.c:298 app/flatpak-builtins-list.c:419
#: app/flatpak-builtins-make-current.c:72 app/flatpak-builtins-override.c:73
#: app/flatpak-builtins-permission-list.c:162
#: app/flatpak-builtins-permission-remove.c:132
#: app/flatpak-builtins-remote-add.c:323
#: app/flatpak-builtins-remote-delete.c:68
#: app/flatpak-builtins-remote-list.c:241 app/flatpak-builtins-remote-ls.c:407
msgid "Too many arguments"
msgstr "Número excessivo de argumentos"

#: app/flatpak-builtins-build-bundle.c:659
#: app/flatpak-builtins-build-commit-from.c:338
#: app/flatpak-builtins-build-commit-from.c:351
#: app/flatpak-builtins-build-import-bundle.c:145
#, c-format
msgid "'%s' is not a valid repository"
msgstr "“%s” não é um repositório válido"

#: app/flatpak-builtins-build-bundle.c:663
#, c-format
msgid "'%s' is not a valid repository: "
msgstr "“%s” não é um repositório válido: "

#: app/flatpak-builtins-build-bundle.c:674 app/flatpak-builtins-build-sign.c:88
#: common/flatpak-dir.c:14293
#, c-format
msgid "'%s' is not a valid name: %s"
msgstr "“%s” não é um nome válido: %s"

#: app/flatpak-builtins-build-bundle.c:677
#: app/flatpak-builtins-build-export.c:865 app/flatpak-builtins-build-sign.c:91
#: common/flatpak-dir.c:14299
#, c-format
msgid "'%s' is not a valid branch name: %s"
msgstr "“%s” não é um nome de ramo válido: %s"

#: app/flatpak-builtins-build-bundle.c:691
#: app/flatpak-builtins-build-import-bundle.c:149
#: app/flatpak-builtins-build-init.c:281
#, c-format
msgid "'%s' is not a valid filename"
msgstr "“%s” não é um nome de arquivo válido"

#: app/flatpak-builtins-build-bundle.c:706
msgid "--oci-layer-compress value must be gzip or zstd"
msgstr "O valor de --oci-layer-compress deve ser gzip ou zstd"

#: app/flatpak-builtins-build.c:49
msgid "Use Platform runtime rather than Sdk"
msgstr "Usa runtime Platform em vez de Sdk"

#: app/flatpak-builtins-build.c:50
msgid "Make destination readonly"
msgstr "Torna o destino somente leitura"

#: app/flatpak-builtins-build.c:51
msgid "Add bind mount"
msgstr "Adiciona montagem associativa (bind)"

#: app/flatpak-builtins-build.c:51
msgid "DEST=SRC"
msgstr "DEST=ORIG"

#: app/flatpak-builtins-build.c:52
msgid "Start build in this directory"
msgstr "Começa compilação neste diretório"

#: app/flatpak-builtins-build.c:52 app/flatpak-builtins-build.c:53
#: app/flatpak-builtins-build-init.c:64 app/flatpak-builtins-run.c:160
msgid "DIR"
msgstr "DIR"

#: app/flatpak-builtins-build.c:53
msgid "Where to look for custom sdk dir (defaults to 'usr')"
msgstr "Onde procurar por diretório de sdk personalizado (padrão é “usr”)"

#: app/flatpak-builtins-build.c:54 app/flatpak-builtins-build-export.c:67
msgid "Use alternative file for the metadata"
msgstr "Usa um arquivo alternativo para os metadados"

#: app/flatpak-builtins-build.c:55 app/flatpak-builtins-run.c:177
msgid "Kill processes when the parent process dies"
msgstr "Mata processos quando o processo pai morre"

#: app/flatpak-builtins-build.c:56
msgid "Export application homedir directory to build"
msgstr "Exporta o diretório homedir do aplicativo a compilar"

#: app/flatpak-builtins-build.c:57 app/flatpak-builtins-run.c:165
msgid "Log session bus calls"
msgstr "Registra o log das chamadas de barramento de sessão"

#: app/flatpak-builtins-build.c:58 app/flatpak-builtins-run.c:166
msgid "Log system bus calls"
msgstr "Registra o log das chamadas de barramento de sistema"

#: app/flatpak-builtins-build.c:262
msgid "DIRECTORY [COMMAND [ARGUMENT…]] - Build in directory"
msgstr "DIRETÓRIO [COMANDO [ARGUMENTO…]] – Compila no diretório"

#: app/flatpak-builtins-build.c:285 app/flatpak-builtins-build-finish.c:656
msgid "DIRECTORY must be specified"
msgstr "DIRETÓRIO deve ser especificado"

#: app/flatpak-builtins-build.c:296 app/flatpak-builtins-build-export.c:887
#, c-format
msgid "Build directory %s not initialized, use flatpak build-init"
msgstr "Diretório de compilação %s não inicializado, use flatpak build-init"

#: app/flatpak-builtins-build.c:315
msgid "metadata invalid, not application or runtime"
msgstr "metadados inválido, não é aplicativo ou runtime"

#: app/flatpak-builtins-build.c:446
#, c-format
msgid "No extension point matching %s in %s"
msgstr "Nenhum ponto de extensão correspondendo %s em %s"

#: app/flatpak-builtins-build.c:635
#, c-format
msgid "Missing '=' in bind mount option '%s'"
msgstr "Faltando “=” na opção de montagem associativa “%s”"

#: app/flatpak-builtins-build.c:679 common/flatpak-run.c:3961
#, c-format
msgid "Unable to start app"
msgstr "Não foi possível iniciar o aplicativo"

#: app/flatpak-builtins-build-commit-from.c:58
msgid "Source repo dir"
msgstr "Diretório de repositório fonte"

#: app/flatpak-builtins-build-commit-from.c:58
msgid "SRC-REPO"
msgstr "SRC-REPO"

#: app/flatpak-builtins-build-commit-from.c:59
msgid "Source repo ref"
msgstr "Ref de repositório fonte"

#: app/flatpak-builtins-build-commit-from.c:59
msgid "SRC-REF"
msgstr "SRC-REF"

#: app/flatpak-builtins-build-commit-from.c:64
#: app/flatpak-builtins-build-export.c:60
msgid "One line subject"
msgstr "Assunto em uma linha"

#: app/flatpak-builtins-build-commit-from.c:64
#: app/flatpak-builtins-build-export.c:60
msgid "SUBJECT"
msgstr "ASSUNTO"

#: app/flatpak-builtins-build-commit-from.c:65
#: app/flatpak-builtins-build-export.c:61
msgid "Full description"
msgstr "Descrição completa"

#: app/flatpak-builtins-build-commit-from.c:65
#: app/flatpak-builtins-build-export.c:61
msgid "BODY"
msgstr "CORPO"

#: app/flatpak-builtins-build-commit-from.c:66
#: app/flatpak-builtins-build-export.c:64
#: app/flatpak-builtins-build-import-bundle.c:51
msgid "Update the appstream branch"
msgstr "Atualiza o ramo de appstream"

#: app/flatpak-builtins-build-commit-from.c:67
#: app/flatpak-builtins-build-export.c:65
#: app/flatpak-builtins-build-import-bundle.c:52
#: app/flatpak-builtins-build-update-repo.c:87
msgid "Don't update the summary"
msgstr "Não atualiza o sumário"

#: app/flatpak-builtins-build-commit-from.c:68
#: app/flatpak-builtins-build-export.c:68
#: app/flatpak-builtins-build-import-bundle.c:49
#: app/flatpak-builtins-build-sign.c:44
msgid "GPG Key ID to sign the commit with"
msgstr "ID da chave GPG para assinar o commit"

#: app/flatpak-builtins-build-commit-from.c:70
#: app/flatpak-builtins-build-export.c:73
msgid "Mark build as end-of-life"
msgstr "Marca a compilação como fim de vida"

#: app/flatpak-builtins-build-commit-from.c:70
#: app/flatpak-builtins-build-export.c:73
msgid "REASON"
msgstr "MOTIVO"

#: app/flatpak-builtins-build-commit-from.c:71
msgid ""
"Mark refs matching the OLDID prefix as end-of-life, to be replaced with the "
"given NEWID"
msgstr ""
"Marca refs correspondentes ao prefixo de IDANTIGO como fim de vida, para "
"serem substituídos com o IDNOVO dado"

#: app/flatpak-builtins-build-commit-from.c:71
msgid "OLDID=NEWID"
msgstr "IDANTIGO=IDNOVO"

#: app/flatpak-builtins-build-commit-from.c:72
#: app/flatpak-builtins-build-export.c:75
msgid "Set type of token needed to install this commit"
msgstr "Define o tipo de token necessário para instalar este commit"

#: app/flatpak-builtins-build-commit-from.c:72
#: app/flatpak-builtins-build-export.c:75
msgid "VAL"
msgstr "VALOR"

#: app/flatpak-builtins-build-commit-from.c:73
msgid "Override the timestamp of the commit (NOW for current time)"
msgstr "Sobrepõe o carimbo de tempo do commit (NOW para o tempo atual)"

#: app/flatpak-builtins-build-commit-from.c:73
#: app/flatpak-builtins-build-export.c:76
msgid "TIMESTAMP"
msgstr "CARIMBO-DE-TEMPO"

#: app/flatpak-builtins-build-commit-from.c:75
#: app/flatpak-builtins-build-export.c:80
#: app/flatpak-builtins-build-import-bundle.c:53
#: app/flatpak-builtins-build-update-repo.c:97
msgid "Don't generate a summary index"
msgstr "Não gera um índice de resumo"

#: app/flatpak-builtins-build-commit-from.c:278
msgid "DST-REPO [DST-REF…] - Make a new commit from existing commits"
msgstr "DST-REPO [DST-REF…] – Faz um novo commit de commits existentes"

#: app/flatpak-builtins-build-commit-from.c:285
msgid "DST-REPO must be specified"
msgstr "DST-REPO deve ser especificado"

#: app/flatpak-builtins-build-commit-from.c:293
msgid ""
"If --src-repo is not specified, exactly one destination ref must be specified"
msgstr ""
"Se --src-repo não for especificado, exatamente uma ref destino deve ser "
"especificado"

#: app/flatpak-builtins-build-commit-from.c:296
msgid ""
"If --src-ref is specified, exactly one destination ref must be specified"
msgstr ""
"Se --src-ref for especificado, exatamente uma ref destino deve ser "
"especificado"

#: app/flatpak-builtins-build-commit-from.c:299
msgid "Either --src-repo or --src-ref must be specified"
msgstr "--src-repo ou --src-ref devem ser especificados"

#: app/flatpak-builtins-build-commit-from.c:315
msgid "Invalid argument format of use  --end-of-life-rebase=OLDID=NEWID"
msgstr ""
"Formato de argumento inválido para o uso de --end-of-life-"
"rebase=IDANTIGO=IDNOVO"

#: app/flatpak-builtins-build-commit-from.c:321
#: app/flatpak-builtins-build-commit-from.c:324
#, c-format
msgid "Invalid name %s in --end-of-life-rebase"
msgstr "Nome inválido %s em --end-of-life-rebase"

#: app/flatpak-builtins-build-commit-from.c:333
#: app/flatpak-builtins-build-export.c:1092
#, c-format
msgid "Could not parse '%s'"
msgstr "Não foi possível analisar “%s”"

#: app/flatpak-builtins-build-commit-from.c:498
msgid "Can't commit from partial source commit"
msgstr "Não foi possível fazer commit de commit fonte parcial"

#: app/flatpak-builtins-build-commit-from.c:503
#, c-format
msgid "%s: no change\n"
msgstr "%s: nenhuma alteração\n"

#: app/flatpak-builtins-build-export.c:62
msgid "Architecture to export for (must be host compatible)"
msgstr "Arquitetura alvo da exportação (deve ser compatível com o hospedeiro)"

#: app/flatpak-builtins-build-export.c:63
msgid "Commit runtime (/usr), not /app"
msgstr "Faz commit de runtime (/usr), não /app"

#: app/flatpak-builtins-build-export.c:66
msgid "Use alternative directory for the files"
msgstr "Usa o dicionário alternativo para os arquivo"

#: app/flatpak-builtins-build-export.c:66
msgid "SUBDIR"
msgstr "SUBDIR"

#: app/flatpak-builtins-build-export.c:69
msgid "Files to exclude"
msgstr "Arquivos para excluir"

#: app/flatpak-builtins-build-export.c:69
#: app/flatpak-builtins-build-export.c:70
#: app/flatpak-builtins-build-update-repo.c:90
msgid "PATTERN"
msgstr "PADRÃO"

#: app/flatpak-builtins-build-export.c:70
msgid "Excluded files to include"
msgstr "Arquivos excluídos para incluir"

#: app/flatpak-builtins-build-export.c:74
msgid "Mark build as end-of-life, to be replaced with the given ID"
msgstr "Marca a compilação como fim de vida, a ser substituída com o ID dado"

#: app/flatpak-builtins-build-export.c:74
#: app/flatpak-builtins-document-list.c:49 app/flatpak-cli-transaction.c:1427
msgid "ID"
msgstr "ID"

#: app/flatpak-builtins-build-export.c:76
msgid "Override the timestamp of the commit"
msgstr "Sobrepõe o carimbo de tempo do commit"

#: app/flatpak-builtins-build-export.c:77
#: app/flatpak-builtins-build-update-repo.c:75
#: app/flatpak-builtins-remote-add.c:83 app/flatpak-builtins-remote-list.c:54
#: app/flatpak-builtins-remote-modify.c:88
msgid "Collection ID"
msgstr "ID de coleção"

#: app/flatpak-builtins-build-export.c:472
#, c-format
msgid "WARNING: Error running desktop-file-validate: %s\n"
msgstr "AVISO: Erro ao executar desktop-file-validate: %s\n"

#: app/flatpak-builtins-build-export.c:480
#, c-format
msgid "WARNING: Error reading from desktop-file-validate: %s\n"
msgstr "AVISO: Erro ao ler de desktop-file-validate: %s\n"

#: app/flatpak-builtins-build-export.c:486
#, c-format
msgid "WARNING: Failed to validate desktop file %s: %s\n"
msgstr "AVISO: Falha ao validar o arquivo desktop %s: %s\n"

#: app/flatpak-builtins-build-export.c:513
#, c-format
msgid "WARNING: Can't find Exec key in %s: %s\n"
msgstr "AVISO: Não foi possível localizar a chave Exec em %s: %s\n"

#: app/flatpak-builtins-build-export.c:521
#: app/flatpak-builtins-build-export.c:614
#, c-format
msgid "WARNING: Binary not found for Exec line in %s: %s\n"
msgstr "AVISO: Binário não localizado para a linha Exec em %s: %s\n"

#: app/flatpak-builtins-build-export.c:529
#, c-format
msgid "WARNING: Icon not matching app id in %s: %s\n"
msgstr "AVISO: Ícone não correspondendo a id do aplicativo no %s: %s\n"

#: app/flatpak-builtins-build-export.c:552
#, c-format
msgid "WARNING: Icon referenced in desktop file but not exported: %s\n"
msgstr "AVISO: Ícone referenciado no arquivo desktop, mas não exportado: %s\n"

#: app/flatpak-builtins-build-export.c:719
#, c-format
msgid "Invalid uri type %s, only http/https supported"
msgstr "Tipo de uri inválida %s, há suporte apenas a http/https"

#: app/flatpak-builtins-build-export.c:737
#, c-format
msgid "Unable to find basename in %s, specify a name explicitly"
msgstr ""
"Não foi possível localizar o nome base em %s, especifique explicitamente um "
"nome base"

#: app/flatpak-builtins-build-export.c:746
#, c-format
msgid "No slashes allowed in extra data name"
msgstr "Nenhuma barra permitida no nome de dados extras"

#: app/flatpak-builtins-build-export.c:758
#, c-format
msgid "Invalid format for sha256 checksum: '%s'"
msgstr "Formato inválido para a soma de verificação sha256: “%s”"

#: app/flatpak-builtins-build-export.c:768
#, c-format
msgid "Extra data sizes of zero not supported"
msgstr "Tamanhos zerado de dados extras sem suporte"

#: app/flatpak-builtins-build-export.c:830
msgid ""
"LOCATION DIRECTORY [BRANCH] - Create a repository from a build directory"
msgstr ""
"LOCALIZAÇÃO DIRETÓRIO [RAMO] – Cria um repositório de um diretório de "
"compilação"

#: app/flatpak-builtins-build-export.c:838
msgid "LOCATION and DIRECTORY must be specified"
msgstr "LOCALIZAÇÃO e DIRETÓRIO devem ser especificados"

#: app/flatpak-builtins-build-export.c:859
#: app/flatpak-builtins-remote-add.c:327
#, c-format
msgid "‘%s’ is not a valid collection ID: %s"
msgstr "“%s” não é um ID de coleção válido: %s"

#: app/flatpak-builtins-build-export.c:904
#: app/flatpak-builtins-build-finish.c:684
msgid "No name specified in the metadata"
msgstr "Nenhum nome especificado nos metadados"

#: app/flatpak-builtins-build-export.c:1166
#, c-format
msgid "Commit: %s\n"
msgstr "Commit: %s\n"

#: app/flatpak-builtins-build-export.c:1167
#, c-format
msgid "Metadata Total: %u\n"
msgstr "Metadados totais: %u\n"

#: app/flatpak-builtins-build-export.c:1168
#, c-format
msgid "Metadata Written: %u\n"
msgstr "Metadados escritos: %u\n"

#: app/flatpak-builtins-build-export.c:1169
#, c-format
msgid "Content Total: %u\n"
msgstr "Conteúdo total: %u\n"

#: app/flatpak-builtins-build-export.c:1170
#, c-format
msgid "Content Written: %u\n"
msgstr "Conteúdo escrito: %u\n"

#: app/flatpak-builtins-build-export.c:1171
#, c-format
msgid "Content Bytes Written:"
msgstr "Conteúdo de bytes escritos:"

#: app/flatpak-builtins-build-finish.c:52
msgid "Command to set"
msgstr "Comando para definir"

#: app/flatpak-builtins-build-finish.c:52 app/flatpak-builtins-run.c:159
#: app/flatpak-main.c:209
msgid "COMMAND"
msgstr "COMANDO"

#: app/flatpak-builtins-build-finish.c:53
msgid "Flatpak version to require"
msgstr "Versão do Flatpak para exigir"

#: app/flatpak-builtins-build-finish.c:53
msgid "MAJOR.MINOR.MICRO"
msgstr "MAIOR.MENOR.MICRO"

#: app/flatpak-builtins-build-finish.c:54
msgid "Don't process exports"
msgstr "Não processa exportações"

#: app/flatpak-builtins-build-finish.c:55
msgid "Extra data info"
msgstr "Info de dados extras"

#: app/flatpak-builtins-build-finish.c:56 app/flatpak-builtins-build-init.c:63
msgid "Add extension point info"
msgstr "Adiciona info do ponto de extensão"

#: app/flatpak-builtins-build-finish.c:56 app/flatpak-builtins-build-init.c:63
msgid "NAME=VARIABLE[=VALUE]"
msgstr "NOME=VARIÁVEL[=VALOR]"

#: app/flatpak-builtins-build-finish.c:57
msgid "Remove extension point info"
msgstr "Remove info do ponto de extensão"

#: app/flatpak-builtins-build-finish.c:57
#: app/flatpak-builtins-build-update-repo.c:79 app/flatpak-builtins-info.c:58
#: app/flatpak-builtins-remote-add.c:88 app/flatpak-builtins-remote-modify.c:94
#: app/flatpak-main.c:182
msgid "NAME"
msgstr "NOME"

#: app/flatpak-builtins-build-finish.c:58
msgid "Set extension priority (only for extensions)"
msgstr "Define a prioridade da extensão (apenas para extensões)"

#: app/flatpak-builtins-build-finish.c:58
msgid "VALUE"
msgstr "VALOR"

#: app/flatpak-builtins-build-finish.c:59
msgid "Change the sdk used for the app"
msgstr "Altera o sdk usado para o aplicativo"

#: app/flatpak-builtins-build-finish.c:59
msgid "SDK"
msgstr "SDK"

#: app/flatpak-builtins-build-finish.c:60
msgid "Change the runtime used for the app"
msgstr "Altera o runtime usado para o aplicativo"

#: app/flatpak-builtins-build-finish.c:60 app/flatpak-builtins-build-init.c:54
#: app/flatpak-builtins-list.c:53 app/flatpak-builtins-remote-ls.c:58
#: app/flatpak-builtins-run.c:163
msgid "RUNTIME"
msgstr "RUNTIME"

#: app/flatpak-builtins-build-finish.c:61
msgid "Set generic metadata option"
msgstr "Define a opção de metadados genérica"

#: app/flatpak-builtins-build-finish.c:61
msgid "GROUP=KEY[=VALUE]"
msgstr "GRUPO=CHAVE[=VALOR]"

#: app/flatpak-builtins-build-finish.c:62
msgid "Don't inherit permissions from runtime"
msgstr "Não herda permissões do runtime"

#: app/flatpak-builtins-build-finish.c:155
#, c-format
msgid "Not exporting %s, wrong extension\n"
msgstr "Não exportando %s, extensão errada\n"

#: app/flatpak-builtins-build-finish.c:163
#, c-format
msgid "Not exporting %s, non-allowed export filename\n"
msgstr "Não exportando %s, nome de arquivo de exportação não permitido\n"

#: app/flatpak-builtins-build-finish.c:167
#, c-format
msgid "Exporting %s\n"
msgstr "Exportando %s\n"

#: app/flatpak-builtins-build-finish.c:440
#, c-format
msgid "More than one executable found\n"
msgstr "Mais de um executável localizado\n"

#: app/flatpak-builtins-build-finish.c:451
#, c-format
msgid "Using %s as command\n"
msgstr "Usando %s como comando\n"

#: app/flatpak-builtins-build-finish.c:456
#, c-format
msgid "No executable found\n"
msgstr "Nenhum executável localizado\n"

#: app/flatpak-builtins-build-finish.c:511
#, c-format
msgid "Invalid --require-version argument: %s"
msgstr "Argumento --require-version inválido: %s"

#: app/flatpak-builtins-build-finish.c:543
#, c-format
msgid "Too few elements in --extra-data argument %s"
msgstr "Elementos insuficientes no argumento de --extra-data %s"

#: app/flatpak-builtins-build-finish.c:575
#, c-format
msgid ""
"Too few elements in --metadata argument %s, format should be "
"GROUP=KEY[=VALUE]]"
msgstr ""
"Elementos insuficientes no argumento de --metadata %s, formato deve ser "
"GRUPO=CHAVE[=VALOR]"

#: app/flatpak-builtins-build-finish.c:597
#: app/flatpak-builtins-build-init.c:458
#, c-format
msgid ""
"Too few elements in --extension argument %s, format should be "
"NAME=VAR[=VALUE]"
msgstr ""
"Elementos insuficientes no argumento de --extension %s, formato deve ser "
"NOME=VAR[=VALOR]"

#: app/flatpak-builtins-build-finish.c:603
#: app/flatpak-builtins-build-init.c:461
#, c-format
msgid "Invalid extension name %s"
msgstr "Nome de extensão inválido %s"

#: app/flatpak-builtins-build-finish.c:646
msgid "DIRECTORY - Finalize a build directory"
msgstr "DIRETÓRIO – Finaliza um diretório de compilação"

#: app/flatpak-builtins-build-finish.c:668
#, c-format
msgid "Build directory %s not initialized"
msgstr "Diretório de compilação %s não inicializado"

#: app/flatpak-builtins-build-finish.c:689
#, c-format
msgid "Build directory %s already finalized"
msgstr "Diretório de compilação %s já finalizado"

#: app/flatpak-builtins-build-finish.c:702
#, c-format
msgid "Please review the exported files and the metadata\n"
msgstr "Por favor, reveja os arquivos exportados e os metadados\n"

#: app/flatpak-builtins-build-import-bundle.c:47
msgid "Override the ref used for the imported bundle"
msgstr "Sobrepõe a ref usada para o pacote importado"

#: app/flatpak-builtins-build-import-bundle.c:47
msgid "REF"
msgstr "REF"

#: app/flatpak-builtins-build-import-bundle.c:48
msgid "Import oci image instead of flatpak bundle"
msgstr "Importa a imagem oci em vez do pacote flatpak"

#: app/flatpak-builtins-build-import-bundle.c:77
#: app/flatpak-builtins-build-import-bundle.c:105
#, c-format
msgid "Importing %s (%s)\n"
msgstr "Importando %s (%s)\n"

#: app/flatpak-builtins-build-import-bundle.c:126
msgid "LOCATION FILENAME - Import a file bundle into a local repository"
msgstr ""
"LOCALIZAÇÃO ARQUIVO – Importa um arquivo de pacote para um repositório local"

#: app/flatpak-builtins-build-import-bundle.c:133
msgid "LOCATION and FILENAME must be specified"
msgstr "LOCALIZAÇÃO e ARQUIVO devem ser especificados"

#: app/flatpak-builtins-build-init.c:53 app/flatpak-builtins-info.c:55
#: app/flatpak-builtins-run.c:158
msgid "Arch to use"
msgstr "Arquitetura para usar"

#: app/flatpak-builtins-build-init.c:54
msgid "Initialize var from named runtime"
msgstr "Inicializa variável a partir do runtime nomeado"

#: app/flatpak-builtins-build-init.c:55
msgid "Initialize apps from named app"
msgstr "Inicializa aplicativos a partir do aplicativo nomeado"

#: app/flatpak-builtins-build-init.c:55
msgid "APP"
msgstr "APLICATIVO"

#: app/flatpak-builtins-build-init.c:56
msgid "Specify version for --base"
msgstr "Especifica a versão para --base"

#: app/flatpak-builtins-build-init.c:56 app/flatpak-builtins-run.c:164
msgid "VERSION"
msgstr "VERSÃO"

#: app/flatpak-builtins-build-init.c:57
msgid "Include this base extension"
msgstr "Inclui essa extensão base"

#: app/flatpak-builtins-build-init.c:57 app/flatpak-builtins-build-init.c:62
msgid "EXTENSION"
msgstr "EXTENSÃO"

#: app/flatpak-builtins-build-init.c:58
msgid "Extension tag to use if building extension"
msgstr "Etiqueta de extensão para usar se compilação extensão"

#: app/flatpak-builtins-build-init.c:58
msgid "EXTENSION_TAG"
msgstr "ETIQUETA_EXTENSÃO"

#: app/flatpak-builtins-build-init.c:59
msgid "Initialize /usr with a writable copy of the sdk"
msgstr "Inicializa /usr com uma cópia do sdk com permissão de escrita"

#: app/flatpak-builtins-build-init.c:60
msgid "Specify the build type (app, runtime, extension)"
msgstr "Especifica o tipo de compilação (app, runtime, extension)"

#: app/flatpak-builtins-build-init.c:60
msgid "TYPE"
msgstr "TIPO"

#: app/flatpak-builtins-build-init.c:61
msgid "Add a tag"
msgstr "Adiciona uma etiqueta"

#: app/flatpak-builtins-build-init.c:61
msgid "TAG"
msgstr "ETIQUETA"

#: app/flatpak-builtins-build-init.c:62
msgid "Include this sdk extension in /usr"
msgstr "Inclui essa extensão de sdk em /usr"

#: app/flatpak-builtins-build-init.c:64
msgid "Where to store sdk (defaults to 'usr')"
msgstr "Onde armazenar sdk (padrão é “usr”)"

#: app/flatpak-builtins-build-init.c:65
msgid "Re-initialize the sdk/var"
msgstr "Reinicializa o/a sdk/var"

#: app/flatpak-builtins-build-init.c:118
#, c-format
msgid "Requested extension %s/%s/%s is only partially installed"
msgstr "Extensão %s/%s/%s exigida está apenas parcialmente instalada"

#: app/flatpak-builtins-build-init.c:147
#, c-format
msgid "Requested extension %s/%s/%s not installed"
msgstr "Extensão %s/%s/%s exigida não está instalada"

#: app/flatpak-builtins-build-init.c:207
msgid ""
"DIRECTORY APPNAME SDK RUNTIME [BRANCH] - Initialize a directory for building"
msgstr ""
"DIRETÓRIO NOMEAPLICATIVO SDK RUNTIME [RAMO] – Inicializa um diretório para "
"compilação"

#: app/flatpak-builtins-build-init.c:214
msgid "RUNTIME must be specified"
msgstr "RUNTIME deve ser especificado"

#: app/flatpak-builtins-build-init.c:235
#, c-format
msgid "'%s' is not a valid build type name, use app, runtime or extension"
msgstr ""
"“%s” não é um nome de tipo de compilação válido, use app, runtime ou "
"extension"

#: app/flatpak-builtins-build-init.c:241 app/flatpak-builtins-override.c:79
#, c-format
msgid "'%s' is not a valid application name: %s"
msgstr "“%s” não é um nome de aplicativo válido: %s"

#: app/flatpak-builtins-build-init.c:295
#, c-format
msgid "Build directory %s already initialized"
msgstr "Diretório de compilação %s já inicializado"

#: app/flatpak-builtins-build-sign.c:42 app/flatpak-builtins-install.c:67
#: app/flatpak-builtins-remote-info.c:54
msgid "Arch to install for"
msgstr "Arquitetura para a qual será instalada"

#: app/flatpak-builtins-build-sign.c:43 app/flatpak-builtins-create-usb.c:48
#: app/flatpak-builtins-install.c:74 app/flatpak-builtins-remote-info.c:56
#: app/flatpak-builtins-uninstall.c:58 app/flatpak-builtins-update.c:64
msgid "Look for runtime with the specified name"
msgstr "Procura pelo runtime com o nome especificado"

#: app/flatpak-builtins-build-sign.c:66
msgid "LOCATION [ID [BRANCH]] - Sign an application or runtime"
msgstr "LOCALIZAÇÃO [ID [RAMO]] – Assina um aplicativo ou runtime"

#: app/flatpak-builtins-build-sign.c:73
#: app/flatpak-builtins-build-update-repo.c:499
#: app/flatpak-builtins-remote-add.c:320 app/flatpak-builtins-repo.c:739
msgid "LOCATION must be specified"
msgstr "LOCALIZAÇÃO deve ser especificada"

#: app/flatpak-builtins-build-sign.c:94
msgid "No gpg key ids specified"
msgstr "Nenhum id de chave gpg especificado"

#: app/flatpak-builtins-build-update-repo.c:68
msgid "Redirect this repo to a new URL"
msgstr "Redireciona esse repositório a uma nova URL"

#: app/flatpak-builtins-build-update-repo.c:69
msgid "A nice name to use for this repository"
msgstr "Um nome legal para usar para este repositório"

#: app/flatpak-builtins-build-update-repo.c:69
#: app/flatpak-builtins-remote-add.c:77 app/flatpak-builtins-remote-modify.c:82
msgid "TITLE"
msgstr "TÍTULO"

#: app/flatpak-builtins-build-update-repo.c:70
msgid "A one-line comment for this repository"
msgstr "Um comentário de uma linha para este repositório"

#: app/flatpak-builtins-build-update-repo.c:70
#: app/flatpak-builtins-remote-add.c:78 app/flatpak-builtins-remote-modify.c:83
msgid "COMMENT"
msgstr "COMENTÁRIO"

#: app/flatpak-builtins-build-update-repo.c:71
msgid "A full-paragraph description for this repository"
msgstr "Uma descrição de parágrafo completo para este repositório"

#: app/flatpak-builtins-build-update-repo.c:71
#: app/flatpak-builtins-remote-add.c:79 app/flatpak-builtins-remote-modify.c:84
msgid "DESCRIPTION"
msgstr "DESCRIÇÃO"

#: app/flatpak-builtins-build-update-repo.c:72
msgid "URL for a website for this repository"
msgstr "URL de um website para este repositório"

#: app/flatpak-builtins-build-update-repo.c:73
msgid "URL for an icon for this repository"
msgstr "URL de um ícone para este repositório"

#: app/flatpak-builtins-build-update-repo.c:74
msgid "Default branch to use for this repository"
msgstr "Ramo padrão para usar para este repositório"

#: app/flatpak-builtins-build-update-repo.c:74
#: app/flatpak-builtins-remote-add.c:82 app/flatpak-builtins-remote-modify.c:87
#: app/flatpak-builtins-repo.c:713 app/flatpak-builtins-repo.c:714
#: app/flatpak-builtins-run.c:161
msgid "BRANCH"
msgstr "RAMO"

#: app/flatpak-builtins-build-update-repo.c:75
#: app/flatpak-builtins-remote-add.c:83 app/flatpak-builtins-remote-modify.c:88
msgid "COLLECTION-ID"
msgstr "ID-COLEÇÃO"

#. Translators: A sideload is when you install from a local USB drive rather than the Internet.
#: app/flatpak-builtins-build-update-repo.c:77
msgid ""
"Permanently deploy collection ID to client remote configurations, only for "
"sideload support"
msgstr ""
"Implementa permanentemente ID de coleção em configurações remotas de "
"cliente, apenas para suporte a download local"

#: app/flatpak-builtins-build-update-repo.c:78
msgid "Permanently deploy collection ID to client remote configurations"
msgstr ""
"Implementa permanentemente ID de coleção em configurações remotas de cliente"

#: app/flatpak-builtins-build-update-repo.c:79
msgid "Name of authenticator for this repository"
msgstr "Nome do autenticador para este repositório"

#: app/flatpak-builtins-build-update-repo.c:80
msgid "Autoinstall authenticator for this repository"
msgstr "Instala automaticamente um autenticador para este repositório"

#: app/flatpak-builtins-build-update-repo.c:81
msgid "Don't autoinstall authenticator for this repository"
msgstr "Não instala automaticamente um autenticador para este repositório"

#: app/flatpak-builtins-build-update-repo.c:82
#: app/flatpak-builtins-remote-add.c:89
msgid "Authenticator option"
msgstr "Opção do autenticador"

#: app/flatpak-builtins-build-update-repo.c:82
#: app/flatpak-builtins-remote-add.c:89 app/flatpak-builtins-remote-modify.c:95
msgid "KEY=VALUE"
msgstr "CHAVE=VALOR"

#: app/flatpak-builtins-build-update-repo.c:83
msgid "Import new default GPG public key from FILE"
msgstr "Importa nova chave pública GPG padrão do ARQUIVO"

#: app/flatpak-builtins-build-update-repo.c:84
msgid "GPG Key ID to sign the summary with"
msgstr "ID da chave GPG para assinar o sumário"

#: app/flatpak-builtins-build-update-repo.c:86
msgid "Generate delta files"
msgstr "Gera arquivos delta"

#: app/flatpak-builtins-build-update-repo.c:88
msgid "Don't update the appstream branch"
msgstr "Não atualiza o ramo de appstream"

#: app/flatpak-builtins-build-update-repo.c:89
msgid "Max parallel jobs when creating deltas (default: NUMCPUs)"
msgstr "Máximo de trabalhos paralelos ao criar deltas (padrão: NUMCPUs)"

#: app/flatpak-builtins-build-update-repo.c:89
msgid "NUM-JOBS"
msgstr "NUM-TRABALHOS"

#: app/flatpak-builtins-build-update-repo.c:90
msgid "Don't create deltas matching refs"
msgstr "Não cria deltas correspondendo a refs"

#: app/flatpak-builtins-build-update-repo.c:91
msgid "Prune unused objects"
msgstr "Suprime objetos não usados"

#: app/flatpak-builtins-build-update-repo.c:92
msgid "Prune but don't actually remove anything"
msgstr "Suprime, mas não remove nada"

#: app/flatpak-builtins-build-update-repo.c:93
msgid "Only traverse DEPTH parents for each commit (default: -1=infinite)"
msgstr "Atravessa apenas NÍVEL pais para cada commit (padrão: -1=infinito)"

#: app/flatpak-builtins-build-update-repo.c:93
msgid "DEPTH"
msgstr "NÍVEL"

#: app/flatpak-builtins-build-update-repo.c:223
#, c-format
msgid "Generating delta: %s (%.10s)\n"
msgstr "Gerando delta: %s (%.10s)\n"

#: app/flatpak-builtins-build-update-repo.c:225
#, c-format
msgid "Generating delta: %s (%.10s-%.10s)\n"
msgstr "Gerando delta: %s (%.10s-%.10s)\n"

#: app/flatpak-builtins-build-update-repo.c:233
#, c-format
msgid "Failed to generate delta %s (%.10s): "
msgstr "Falha ao gerar delta %s (%.10s): "

#: app/flatpak-builtins-build-update-repo.c:236
#, c-format
msgid "Failed to generate delta %s (%.10s-%.10s): "
msgstr "Falha ao gerar delta %s (%.10s-%.10s): "

#: app/flatpak-builtins-build-update-repo.c:492
msgid "LOCATION - Update repository metadata"
msgstr "LOCALIZAÇÃO – Atualiza metadados de um repositório"

#: app/flatpak-builtins-build-update-repo.c:609
#, c-format
msgid "Updating appstream branch\n"
msgstr "Atualizando ramo do appstream\n"

#: app/flatpak-builtins-build-update-repo.c:638
#, c-format
msgid "Updating summary\n"
msgstr "Atualizando resumo\n"

#: app/flatpak-builtins-build-update-repo.c:664
#, c-format
msgid "Total objects: %u\n"
msgstr "Objetos totais: %u\n"

#: app/flatpak-builtins-build-update-repo.c:666
#, c-format
msgid "No unreachable objects\n"
msgstr "Nenhum objeto alcançável\n"

#: app/flatpak-builtins-build-update-repo.c:668
#, c-format
msgid "Deleted %u objects, %s freed\n"
msgstr "%u objetos excluídos, %s liberado\n"

#: app/flatpak-builtins-config.c:41
msgid "List configuration keys and values"
msgstr "Lista chaves e valores de configuração"

#: app/flatpak-builtins-config.c:42
msgid "Get configuration for KEY"
msgstr "Obtém configuração da CHAVE"

#: app/flatpak-builtins-config.c:43
msgid "Set configuration for KEY to VALUE"
msgstr "Define configuração da CHAVE para VALOR"

#: app/flatpak-builtins-config.c:44
msgid "Unset configuration for KEY"
msgstr "Remove configuração da CHAVE"

#: app/flatpak-builtins-config.c:149
#, c-format
msgid "'%s' does not look like a language/locale code"
msgstr "“%s” não parece ser um código de idioma/localidade"

#: app/flatpak-builtins-config.c:172
#, c-format
msgid "'%s' does not look like a language code"
msgstr "“%s” não se parece um código de idioma"

#: app/flatpak-builtins-config.c:190
#, c-format
msgid "'%s' is not a valid value (use 'true' or 'false')"
msgstr "“%s” não é um repositório válido (use “true” ou “false”)"

#: app/flatpak-builtins-config.c:262
#, c-format
msgid "Unknown configure key '%s'"
msgstr "Configuração de chave desconhecida “%s”"

#: app/flatpak-builtins-config.c:284
msgid "Too many arguments for --list"
msgstr "Número excessivo de argumentos para --list"

#: app/flatpak-builtins-config.c:314 app/flatpak-builtins-config.c:362
msgid "You must specify KEY"
msgstr "Você deve especificar CHAVE"

#: app/flatpak-builtins-config.c:316
msgid "Too many arguments for --get"
msgstr "Número excessivo de argumentos para --get"

#: app/flatpak-builtins-config.c:338
msgid "You must specify KEY and VALUE"
msgstr "Você deve especificar CHAVE e VALOR"

#: app/flatpak-builtins-config.c:340
msgid "Too many arguments for --set"
msgstr "Número excessivo de argumentos para --set"

#: app/flatpak-builtins-config.c:364
msgid "Too many arguments for --unset"
msgstr "Número excessivo de argumentos para --unset"

#: app/flatpak-builtins-config.c:383
msgid "[KEY [VALUE]] - Manage configuration"
msgstr "[CHAVE [VALOR]] – Gerencia configuração"

#: app/flatpak-builtins-config.c:394
msgid "Can only use one of --list, --get, --set or --unset"
msgstr "Pode usar apenas um entre --list, --get, --set ou --unset"

#: app/flatpak-builtins-config.c:408
msgid "Must specify one of --list, --get, --set or --unset"
msgstr "Deve-se especificar um entre --list, --get, --set ou --unset"

#: app/flatpak-builtins-create-usb.c:45 app/flatpak-builtins-install.c:75
#: app/flatpak-builtins-remote-info.c:57 app/flatpak-builtins-uninstall.c:59
#: app/flatpak-builtins-update.c:65
msgid "Look for app with the specified name"
msgstr "Procura pelo aplicativo com o nome especificado"

#: app/flatpak-builtins-create-usb.c:46
msgid "Arch to copy"
msgstr "Arquitetura para copiar"

#: app/flatpak-builtins-create-usb.c:47
msgid "DEST"
msgstr "DEST"

#: app/flatpak-builtins-create-usb.c:49
msgid "Allow partial commits in the created repo"
msgstr "Permite commits parciais no repositório criado"

#: app/flatpak-builtins-create-usb.c:125 app/flatpak-builtins-create-usb.c:165
#, c-format
msgid ""
"Warning: Related ref ‘%s’ is partially installed. Use --allow-partial to "
"suppress this message.\n"
msgstr ""
"Aviso: A ref “%s” relacionada está parcialmente instalada. Use --allow-"
"partial para suprimir esta mensagem.\n"

#: app/flatpak-builtins-create-usb.c:158
#, c-format
msgid "Warning: Omitting related ref ‘%s’ because it is not installed.\n"
msgstr "Aviso: Omitindo a ref “%s” relacionada porque não está instalada.\n"

#: app/flatpak-builtins-create-usb.c:175
#, c-format
msgid ""
"Warning: Omitting related ref ‘%s’ because its remote ‘%s’ does not have a "
"collection ID set.\n"
msgstr ""
"Aviso: Omitindo a ref “%s” relacionada porque seu remoto “%s” não tem um "
"conjunto de ID de coleção.\n"

#: app/flatpak-builtins-create-usb.c:187
#, c-format
msgid "Warning: Omitting related ref ‘%s’ because it's extra-data.\n"
msgstr "Aviso: Omitindo a ref “%s” relacionada porque é extra-data.\n"

#: app/flatpak-builtins-create-usb.c:262 app/flatpak-builtins-create-usb.c:637
#, c-format
msgid ""
"Remote ‘%s’ does not have a collection ID set, which is required for P2P "
"distribution of ‘%s’."
msgstr ""
"O remoto “%s” não tem um conjunto de ID de coleção, necessário para a "
"distribuição P2P de “%s”."

#: app/flatpak-builtins-create-usb.c:272
#, c-format
msgid "Warning: Omitting ref ‘%s’ (runtime of ‘%s’) because it's extra-data.\n"
msgstr "Aviso: Omitindo a ref “%s” (runtime de “%s”) porque é extra-data.\n"

#: app/flatpak-builtins-create-usb.c:484
msgid "MOUNT-PATH [REF…] - Copy apps or runtimes onto removable media"
msgstr "CAMINHO-MONT [REF…] – Copia apps ou runtimes em mídia removível"

#: app/flatpak-builtins-create-usb.c:493
msgid "MOUNT-PATH and REF must be specified"
msgstr "CAMINHO-MONT e REF devem ser especificados"

#: app/flatpak-builtins-create-usb.c:607
#, c-format
msgid "Ref ‘%s’ found in multiple installations: %s. You must specify one."
msgstr ""
"Ref “%s” localizada em várias instalações: %s. Você deve especificar uma."

#: app/flatpak-builtins-create-usb.c:620
#, c-format
msgid "Refs must all be in the same installation (found in %s and %s)."
msgstr ""
"As refs devem estar todas na mesma instalação (localizadas em %s e %s)."

#: app/flatpak-builtins-create-usb.c:670
#, c-format
msgid ""
"Warning: Ref ‘%s’ is partially installed. Use --allow-partial to suppress "
"this message.\n"
msgstr ""
"Aviso: A ref “%s” está parcialmente instalada. Use --allow-partial para "
"suprimir esta mensagem.\n"

#: app/flatpak-builtins-create-usb.c:681
#, c-format
msgid "Installed ref ‘%s’ is extra-data, and cannot be distributed offline"
msgstr "A ref “%s” instalada é extra-data e não pode ser distribuída offline"

#: app/flatpak-builtins-create-usb.c:721
#, c-format
msgid "Warning: Couldn't update repo metadata for remote ‘%s’: %s\n"
msgstr ""
"Aviso: Não foi possível atualizar metadados do repo para remoto “%s”: %s\n"

#: app/flatpak-builtins-create-usb.c:751
#, c-format
msgid "Warning: Couldn't update appstream data for remote ‘%s’ arch ‘%s’: %s\n"
msgstr ""
"Aviso: Não foi possível atualizar dados de appstream para remoto “%s” "
"arquitetura “%s”: %s\n"

#. Print a warning if both appstream and appstream2 are missing
#: app/flatpak-builtins-create-usb.c:784
#, c-format
msgid ""
"Warning: Couldn't find appstream data for remote ‘%s’ arch ‘%s’: %s; %s\n"
msgstr ""
"Aviso: Não foi possível localizar dados de appstream para remoto “%s” "
"arquitetura “%s”: %s; %s\n"

#. Appstream2 is only for efficiency, so just print a debug message
#: app/flatpak-builtins-create-usb.c:790
#, c-format
msgid "Couldn't find appstream2 data for remote ‘%s’ arch ‘%s’: %s\n"
msgstr ""
"Não foi possível localizar dados de appstream2 para remoto “%s” arquitetura "
"“%s”: %s\n"

#: app/flatpak-builtins-document-export.c:62
msgid "Create a unique document reference"
msgstr "Cria uma referência única de documento"

#: app/flatpak-builtins-document-export.c:63
msgid "Make the document transient for the current session"
msgstr "Faz o documento transiente para a sessão atual"

#: app/flatpak-builtins-document-export.c:64
msgid "Don't require the file to exist already"
msgstr "Não exige que o arquivo já exista"

#: app/flatpak-builtins-document-export.c:65
msgid "Give the app read permissions"
msgstr "Concede ao aplicativo permissões de leitura"

#: app/flatpak-builtins-document-export.c:66
msgid "Give the app write permissions"
msgstr "Concede ao aplicativo permissões de escrita"

#: app/flatpak-builtins-document-export.c:67
msgid "Give the app delete permissions"
msgstr "Concede ao aplicativo permissões de exclusão"

#: app/flatpak-builtins-document-export.c:68
msgid "Give the app permissions to grant further permissions"
msgstr "Concede ao aplicativo permissões para conceder permissões"

#: app/flatpak-builtins-document-export.c:69
msgid "Revoke read permissions of the app"
msgstr "Revoga permissões de leitura do aplicativo"

#: app/flatpak-builtins-document-export.c:70
msgid "Revoke write permissions of the app"
msgstr "Revoga permissões de escrita do aplicativo"

#: app/flatpak-builtins-document-export.c:71
msgid "Revoke delete permissions of the app"
msgstr "Revoga permissões de exclusão do aplicativo"

#: app/flatpak-builtins-document-export.c:72
msgid "Revoke the permission to grant further permissions"
msgstr "Revoga a permissão para conceder permissões"

#: app/flatpak-builtins-document-export.c:73
msgid "Add permissions for this app"
msgstr "Adiciona permissões para este aplicativo"

#: app/flatpak-builtins-document-export.c:73
msgid "APPID"
msgstr "APPID"

#: app/flatpak-builtins-document-export.c:100
msgid "FILE - Export a file to apps"
msgstr "ARQUIVO – Exporta um arquivo para aplicativos"

#: app/flatpak-builtins-document-export.c:109
#: app/flatpak-builtins-document-info.c:72
#: app/flatpak-builtins-document-unexport.c:67
msgid "FILE must be specified"
msgstr "ARQUIVO deve ser especificado"

#: app/flatpak-builtins-document-info.c:63
msgid "FILE - Get information about an exported file"
msgstr "ARQUIVO – Obtém informações sobre um arquivo exportado"

#: app/flatpak-builtins-document-info.c:100
#: app/flatpak-builtins-document-unexport.c:94
#, c-format
msgid "Not exported\n"
msgstr "Não exportado\n"

#: app/flatpak-builtins-document-list.c:43 app/flatpak-builtins-history.c:53
#: app/flatpak-builtins-list.c:54 app/flatpak-builtins-ps.c:43
#: app/flatpak-builtins-remote-list.c:45 app/flatpak-builtins-remote-ls.c:59
#: app/flatpak-builtins-search.c:38
msgid "What information to show"
msgstr "Quais informações mostrar"

#: app/flatpak-builtins-document-list.c:43 app/flatpak-builtins-history.c:53
#: app/flatpak-builtins-list.c:54 app/flatpak-builtins-ps.c:43
#: app/flatpak-builtins-remote-list.c:45 app/flatpak-builtins-remote-ls.c:59
#: app/flatpak-builtins-search.c:38
msgid "FIELD,…"
msgstr "CAMPO,…"

#: app/flatpak-builtins-document-list.c:44 app/flatpak-builtins-history.c:54
#: app/flatpak-builtins-list.c:52 app/flatpak-builtins-permission-list.c:43
#: app/flatpak-builtins-permission-show.c:43 app/flatpak-builtins-ps.c:44
#: app/flatpak-builtins-remote-list.c:46 app/flatpak-builtins-remote-ls.c:63
#: app/flatpak-builtins-repo.c:717 app/flatpak-builtins-search.c:39
msgid "Show output in JSON format"
msgstr "Mostra saída no formato JSON"

#: app/flatpak-builtins-document-list.c:49
msgid "Show the document ID"
msgstr "Mostra o ID do documento"

#: app/flatpak-builtins-document-list.c:50
msgid "Path"
msgstr "Caminho"

#: app/flatpak-builtins-document-list.c:50
#: app/flatpak-builtins-document-list.c:51
msgid "Show the document path"
msgstr "Mostra o caminho do documento"

#: app/flatpak-builtins-document-list.c:51 app/flatpak-builtins-list.c:66
#: app/flatpak-builtins-remote-ls.c:74
msgid "Origin"
msgstr "Origem"

#: app/flatpak-builtins-document-list.c:52 app/flatpak-builtins-history.c:62
#: app/flatpak-builtins-ps.c:52
msgid "Application"
msgstr "Aplicativo"

#: app/flatpak-builtins-document-list.c:52
msgid "Show applications with permission"
msgstr "Mostra aplicativos com permissão"

#: app/flatpak-builtins-document-list.c:53
#: app/flatpak-builtins-permission-list.c:182
#: app/flatpak-builtins-permission-show.c:145
msgid "Permissions"
msgstr "Permissões"

#: app/flatpak-builtins-document-list.c:53
msgid "Show permissions for applications"
msgstr "Mostra permissões para aplicativos"

#: app/flatpak-builtins-document-list.c:161
#, c-format
msgid "No documents found\n"
msgstr "Nenhum documento localizado\n"

#: app/flatpak-builtins-document-list.c:180
msgid "[APPID] - List exported files"
msgstr "[APPID] – Lista arquivos exportados"

#: app/flatpak-builtins-document-unexport.c:43
msgid "Specify the document ID"
msgstr "Especifica o ID do documento"

#: app/flatpak-builtins-document-unexport.c:58
msgid "FILE - Unexport a file to apps"
msgstr "ARQUIVO – Desfaz exportação de um arquivo para aplicativos"

#: app/flatpak-builtins-enter.c:88
msgid "INSTANCE COMMAND [ARGUMENT…] - Run a command inside a running sandbox"
msgstr ""
"INSTÂNCIA COMANDO [ARGUMENTO…] – Executa um comando dentro de uma caixa de "
"proteção"

#: app/flatpak-builtins-enter.c:111
msgid "INSTANCE and COMMAND must be specified"
msgstr "INSTÂNCIA e COMANDO devem ser especificados"

#: app/flatpak-builtins-enter.c:138
#, c-format
msgid "%s is neither a pid nor an application or instance ID"
msgstr "%s não é um pid nem um aplicativo ou ID de instância"

#: app/flatpak-builtins-enter.c:144
msgid "entering not supported (need unprivileged user namespaces, or sudo -E)"
msgstr ""
"entrada sem suporte (precisa de espaços de nome de usuário sem privilégios "
"ou sudo -E)"

#: app/flatpak-builtins-enter.c:145
#, c-format
msgid "No such pid %s"
msgstr "Pid inexistente %s"

#: app/flatpak-builtins-enter.c:158
msgid "Can't read cwd"
msgstr "Não foi possível ler cwd"

#: app/flatpak-builtins-enter.c:163
msgid "Can't read root"
msgstr "Não foi possível ler root"

#: app/flatpak-builtins-enter.c:191
#, c-format
msgid "Invalid %s namespace for pid %d"
msgstr "Espaço de nome inválido %s para pid %d"

#: app/flatpak-builtins-enter.c:202
#, c-format
msgid "Invalid %s namespace for self"
msgstr "Espaço de nome inválido %s para si próprio"

#: app/flatpak-builtins-enter.c:216
#, c-format
msgid "Can't open %s namespace: %s"
msgstr "Não foi possível abrir o espaço de nome %s: %s"

#: app/flatpak-builtins-enter.c:226
msgid "entering not supported (need unprivileged user namespaces)"
msgstr ""
"entrada sem suporte (precisa de espaços de nome de usuário sem privilégios)"

#: app/flatpak-builtins-enter.c:227
#, c-format
msgid "Can't enter %s namespace: %s"
msgstr "Não foi possível entrar no espaço de nome %s: %s"

#: app/flatpak-builtins-enter.c:234
msgid "Can't chdir"
msgstr "Não foi possível executar chdir"

#: app/flatpak-builtins-enter.c:237
msgid "Can't chroot"
msgstr "Não foi possível fazer chroot"

#: app/flatpak-builtins-enter.c:240
msgid "Can't switch gid"
msgstr "Não foi possível trocar o gid"

#: app/flatpak-builtins-enter.c:243
msgid "Can't switch uid"
msgstr "Não foi possível trocar o uid"

#: app/flatpak-builtins-history.c:50
msgid "Only show changes after TIME"
msgstr "Mostra alterações apenas após TEMPO"

#: app/flatpak-builtins-history.c:50 app/flatpak-builtins-history.c:51
msgid "TIME"
msgstr "Mostra alterações apenas após TEMPO"

#: app/flatpak-builtins-history.c:51
msgid "Only show changes before TIME"
msgstr "Mostra alterações apenas antes de TEMPO"

#: app/flatpak-builtins-history.c:52
msgid "Show newest entries first"
msgstr "Mostra entradas mais novas primeiro"

#: app/flatpak-builtins-history.c:59
msgid "Time"
msgstr "Tempo"

#: app/flatpak-builtins-history.c:59
msgid "Show when the change happened"
msgstr "Mostra quando as alterações ocorreram"

#: app/flatpak-builtins-history.c:60
msgid "Change"
msgstr "Alteração"

#: app/flatpak-builtins-history.c:60
msgid "Show the kind of change"
msgstr "Mostra o tipo de alteração"

#: app/flatpak-builtins-history.c:61 app/flatpak-builtins-list.c:68
#: app/flatpak-builtins-remote-ls.c:75 app/flatpak-builtins-repo.c:335
msgid "Ref"
msgstr "Ref"

#: app/flatpak-builtins-history.c:61 app/flatpak-builtins-list.c:68
#: app/flatpak-builtins-remote-ls.c:75
msgid "Show the ref"
msgstr "Mostra a ref"

#: app/flatpak-builtins-history.c:62
msgid "Show the application/runtime ID"
msgstr "Mostra o ID de aplicativo/runtime"

#: app/flatpak-builtins-history.c:63 app/flatpak-builtins-list.c:64
#: app/flatpak-builtins-ps.c:53 app/flatpak-builtins-remote-ls.c:73
#: app/flatpak-cli-transaction.c:1435
msgid "Arch"
msgstr "Arq."

#: app/flatpak-builtins-history.c:63 app/flatpak-builtins-list.c:64
#: app/flatpak-builtins-ps.c:53 app/flatpak-builtins-remote-ls.c:73
msgid "Show the architecture"
msgstr "Mostra a arquitetura"

#: app/flatpak-builtins-history.c:64 app/flatpak-builtins-list.c:63
#: app/flatpak-builtins-ps.c:54 app/flatpak-builtins-remote-ls.c:72
#: app/flatpak-builtins-search.c:48 app/flatpak-cli-transaction.c:1438
msgid "Branch"
msgstr "Ramo"

#: app/flatpak-builtins-history.c:64 app/flatpak-builtins-list.c:63
#: app/flatpak-builtins-remote-ls.c:72
msgid "Show the branch"
msgstr "Mostra o ramo"

#: app/flatpak-builtins-history.c:65 app/flatpak-builtins-list.c:67
msgid "Installation"
msgstr "Instalação"

#: app/flatpak-builtins-history.c:65
msgid "Show the affected installation"
msgstr "Mostra a instalação afetada"

#: app/flatpak-builtins-history.c:66 app/flatpak-cli-transaction.c:1452
msgid "Remote"
msgstr "Remoto"

#: app/flatpak-builtins-history.c:66
msgid "Show the remote"
msgstr "Mostra o remoto"

#: app/flatpak-builtins-history.c:67 app/flatpak-builtins-ps.c:55
#: app/flatpak-builtins-remote-ls.c:76
msgid "Commit"
msgstr "Commit"

#: app/flatpak-builtins-history.c:67
msgid "Show the current commit"
msgstr "Mostra o commit atual"

#: app/flatpak-builtins-history.c:68
msgid "Old Commit"
msgstr "Commit antigo"

#: app/flatpak-builtins-history.c:68
msgid "Show the previous commit"
msgstr "Mostra o commit anterior"

#: app/flatpak-builtins-history.c:69
msgid "Show the remote URL"
msgstr "Mostra o ID do remoto"

#: app/flatpak-builtins-history.c:70 app/flatpak-cli-transaction.c:700
msgid "User"
msgstr "Usuário"

#: app/flatpak-builtins-history.c:70
msgid "Show the user doing the change"
msgstr "Mostra o usuário fazendo a alteração"

#: app/flatpak-builtins-history.c:71
msgid "Tool"
msgstr "Ferramenta"

#: app/flatpak-builtins-history.c:71
msgid "Show the tool that was used"
msgstr "Mostra a ferramenta que foi usada"

#: app/flatpak-builtins-history.c:72 app/flatpak-builtins-list.c:62
#: app/flatpak-builtins-remote-ls.c:71 app/flatpak-builtins-search.c:47
msgid "Version"
msgstr "Versão"

#: app/flatpak-builtins-history.c:72
msgid "Show the Flatpak version"
msgstr "Mostra a versão do Flatpak"

#: app/flatpak-builtins-history.c:91
#, c-format
msgid "Failed to get journal data (%s): %s"
msgstr "Falha ao obter dados do journal (%s): %s"

#: app/flatpak-builtins-history.c:146
#, c-format
msgid "Failed to open journal: %s"
msgstr "Falha ao abrir journal: %s"

#: app/flatpak-builtins-history.c:153
#, c-format
msgid "Failed to add match to journal: %s"
msgstr "Falha ao adicionar correspondência ao journal: %s"

#: app/flatpak-builtins-history.c:471
msgid " - Show history"
msgstr " – Mostra histórico"

#: app/flatpak-builtins-history.c:490
#, c-format
msgid "Failed to parse the --since option"
msgstr "Falha ao analisar a opção --since"

#: app/flatpak-builtins-history.c:501
#, c-format
msgid "Failed to parse the --until option"
msgstr "Falha ao analisar a opção --until"

#: app/flatpak-builtins-info.c:56
msgid "Show user installations"
msgstr "Mostra instalações do usuário"

#: app/flatpak-builtins-info.c:57
msgid "Show system-wide installations"
msgstr "Mostra instalações do sistema"

#: app/flatpak-builtins-info.c:58
msgid "Show specific system-wide installations"
msgstr "Mostra instalações específicas do sistema"

#: app/flatpak-builtins-info.c:59 app/flatpak-builtins-remote-info.c:59
msgid "Show ref"
msgstr "Mostra a ref"

#: app/flatpak-builtins-info.c:60 app/flatpak-builtins-remote-info.c:60
msgid "Show commit"
msgstr "Mostra o commit"

#: app/flatpak-builtins-info.c:61
msgid "Show origin"
msgstr "Mostra a origem"

#: app/flatpak-builtins-info.c:62
msgid "Show size"
msgstr "Mostra o tamanho"

#: app/flatpak-builtins-info.c:63 app/flatpak-builtins-remote-info.c:62
msgid "Show metadata"
msgstr "Mostra os metadados"

#: app/flatpak-builtins-info.c:64 app/flatpak-builtins-remote-info.c:63
msgid "Show runtime"
msgstr "Mostra o runtime"

#: app/flatpak-builtins-info.c:65 app/flatpak-builtins-remote-info.c:64
msgid "Show sdk"
msgstr "Mostra o sdk"

#: app/flatpak-builtins-info.c:66
msgid "Show permissions"
msgstr "Mostra as permissões"

#: app/flatpak-builtins-info.c:67
msgid "Query file access"
msgstr "Consulta o acesso a arquivos"

#: app/flatpak-builtins-info.c:67 app/flatpak-builtins-install.c:82
#: app/flatpak-builtins-install.c:88 app/flatpak-builtins-preinstall.c:68
#: app/flatpak-builtins-run.c:182 app/flatpak-builtins-run.c:184
#: app/flatpak-builtins-update.c:67 app/flatpak-builtins-update.c:71
msgid "PATH"
msgstr "CAMINHO"

#: app/flatpak-builtins-info.c:68
msgid "Show extensions"
msgstr "Mostra as extensões"

#: app/flatpak-builtins-info.c:69
msgid "Show location"
msgstr "Mostra a localização"

#: app/flatpak-builtins-info.c:116
msgid "NAME [BRANCH] - Get info about an installed app or runtime"
msgstr ""
"NOME [RAMO] – Obtém informações sobre um aplicativo e/ou um runtime instalado"

#: app/flatpak-builtins-info.c:123 app/flatpak-builtins-remote-add.c:317
#: app/flatpak-builtins-remote-delete.c:63
msgid "NAME must be specified"
msgstr "NOME deve ser especificado"

#: app/flatpak-builtins-info.c:196
msgid "ref not present in origin"
msgstr "ref não presente na origem"

#: app/flatpak-builtins-info.c:211 app/flatpak-builtins-remote-info.c:217
#, c-format
msgid "Warning: Commit has no flatpak metadata\n"
msgstr "Aviso: O commit tem nenhum metadado de flatpak\n"

#: app/flatpak-builtins-info.c:217 app/flatpak-builtins-info.c:259
#: app/flatpak-builtins-info.c:455 app/flatpak-builtins-info.c:513
#: app/flatpak-builtins-remote-info.c:236
#: app/flatpak-builtins-remote-info.c:271
msgid "ID:"
msgstr "ID:"

#: app/flatpak-builtins-info.c:218 app/flatpak-builtins-info.c:260
#: app/flatpak-builtins-remote-info.c:237
#: app/flatpak-builtins-remote-info.c:272
msgid "Ref:"
msgstr "Ref:"

#: app/flatpak-builtins-info.c:219 app/flatpak-builtins-info.c:261
#: app/flatpak-builtins-remote-info.c:238
#: app/flatpak-builtins-remote-info.c:273
msgid "Arch:"
msgstr "Arq.:"

#: app/flatpak-builtins-info.c:220 app/flatpak-builtins-info.c:262
#: app/flatpak-builtins-remote-info.c:239
#: app/flatpak-builtins-remote-info.c:274
msgid "Branch:"
msgstr "Ramo:"

#: app/flatpak-builtins-info.c:222 app/flatpak-builtins-info.c:264
#: app/flatpak-builtins-remote-info.c:241
#: app/flatpak-builtins-remote-info.c:276
msgid "Version:"
msgstr "Versão:"

#: app/flatpak-builtins-info.c:224 app/flatpak-builtins-info.c:266
#: app/flatpak-builtins-remote-info.c:243
#: app/flatpak-builtins-remote-info.c:278
msgid "License:"
msgstr "Licença:"

#: app/flatpak-builtins-info.c:226 app/flatpak-builtins-info.c:269
#: app/flatpak-builtins-remote-info.c:245
#: app/flatpak-builtins-remote-info.c:280
msgid "Collection:"
msgstr "Coleção:"

#: app/flatpak-builtins-info.c:227 app/flatpak-builtins-info.c:270
#: app/flatpak-builtins-info.c:458 app/flatpak-builtins-info.c:516
msgid "Installation:"
msgstr "Instalação:"

#: app/flatpak-builtins-info.c:228 app/flatpak-builtins-info.c:271
#: app/flatpak-builtins-info.c:459 app/flatpak-builtins-info.c:517
#: app/flatpak-builtins-remote-info.c:249
#: app/flatpak-builtins-remote-info.c:284
msgid "Installed Size:"
msgstr "Tamanho instalado:"

#: app/flatpak-builtins-info.c:231 app/flatpak-builtins-info.c:279
#: app/flatpak-builtins-remote-info.c:252
#: app/flatpak-builtins-remote-info.c:288
msgid "Runtime:"
msgstr "Runtime:"

#: app/flatpak-builtins-info.c:232 app/flatpak-builtins-info.c:288
#: app/flatpak-builtins-remote-info.c:253
#: app/flatpak-builtins-remote-info.c:293
msgid "Sdk:"
msgstr "Sdk:"

#: app/flatpak-builtins-info.c:235 app/flatpak-builtins-info.c:313
#: app/flatpak-builtins-remote-info.c:256
#: app/flatpak-builtins-remote-info.c:319
msgid "Date:"
msgstr "Data:"

#: app/flatpak-builtins-info.c:237 app/flatpak-builtins-info.c:311
#: app/flatpak-builtins-remote-info.c:258
#: app/flatpak-builtins-remote-info.c:317
msgid "Subject:"
msgstr "Assunto:"

#: app/flatpak-builtins-info.c:240 app/flatpak-builtins-info.c:295
msgid "Active commit:"
msgstr "Commit ativo:"

#: app/flatpak-builtins-info.c:241 app/flatpak-builtins-info.c:298
msgid "Latest commit:"
msgstr "Último commit:"

#: app/flatpak-builtins-info.c:244 app/flatpak-builtins-info.c:303
#: app/flatpak-builtins-info.c:457 app/flatpak-builtins-info.c:515
#: app/flatpak-builtins-remote-info.c:259
#: app/flatpak-builtins-remote-info.c:298
msgid "Commit:"
msgstr "Commit:"

#: app/flatpak-builtins-info.c:246 app/flatpak-builtins-info.c:308
#: app/flatpak-builtins-remote-info.c:261
#: app/flatpak-builtins-remote-info.c:303
msgid "Parent:"
msgstr "Pai:"

#: app/flatpak-builtins-info.c:248 app/flatpak-builtins-info.c:321
msgid "Alt-id:"
msgstr "Alt-id:"

#: app/flatpak-builtins-info.c:250 app/flatpak-builtins-info.c:325
#: app/flatpak-builtins-remote-info.c:263
#: app/flatpak-builtins-remote-info.c:308
msgid "End-of-life:"
msgstr "Fim de vida:"

#: app/flatpak-builtins-info.c:252 app/flatpak-builtins-info.c:330
#: app/flatpak-builtins-remote-info.c:265
#: app/flatpak-builtins-remote-info.c:313
msgid "End-of-life-rebase:"
msgstr "Rebase de fim de vida:"

#: app/flatpak-builtins-info.c:254 app/flatpak-builtins-info.c:317
msgid "Subdirectories:"
msgstr "Subdiretórios:"

#: app/flatpak-builtins-info.c:255 app/flatpak-builtins-info.c:454
#: app/flatpak-builtins-info.c:512
msgid "Extension:"
msgstr "Extensões:"

#: app/flatpak-builtins-info.c:267 app/flatpak-builtins-info.c:456
#: app/flatpak-builtins-info.c:514
msgid "Origin:"
msgstr "Origem:"

#: app/flatpak-builtins-info.c:460 app/flatpak-builtins-info.c:522
msgid "Subpaths:"
msgstr "Subcaminhos:"

#: app/flatpak-builtins-info.c:478
msgid "unmaintained"
msgstr "sem mantenedor"

#: app/flatpak-builtins-info.c:480 app/flatpak-builtins-info.c:482
msgid "unknown"
msgstr "desconhecido"

#: app/flatpak-builtins-install.c:68 app/flatpak-builtins-preinstall.c:57
msgid "Don't pull, only install from local cache"
msgstr "Não faz pull, apenas instala do cache local"

#: app/flatpak-builtins-install.c:69 app/flatpak-builtins-preinstall.c:58
#: app/flatpak-builtins-update.c:60
msgid "Don't deploy, only download to local cache"
msgstr "Não implementa (deploy), apenas baixa para o cache local"

#: app/flatpak-builtins-install.c:70 app/flatpak-builtins-preinstall.c:59
msgid "Don't install related refs"
msgstr "Não instala refs relacionadas"

#: app/flatpak-builtins-install.c:71 app/flatpak-builtins-preinstall.c:60
#: app/flatpak-builtins-update.c:62
msgid "Don't verify/install runtime dependencies"
msgstr "Não verifica/instala dependências de runtime"

#: app/flatpak-builtins-install.c:72
msgid "Don't automatically pin explicit installs"
msgstr "Não fixar instalações explícitas automaticamente"

#: app/flatpak-builtins-install.c:73 app/flatpak-builtins-preinstall.c:61
#: app/flatpak-builtins-update.c:63
msgid "Don't use static deltas"
msgstr "Não usa deltas estáticos"

#: app/flatpak-builtins-install.c:76 app/flatpak-builtins-preinstall.c:62
msgid "Additionally install the SDK used to build the given refs"
msgstr "Adicionalmente, instala o SDK usado para compilar as refs dadas"

#: app/flatpak-builtins-install.c:77 app/flatpak-builtins-preinstall.c:63
msgid ""
"Additionally install the debug info for the given refs and their dependencies"
msgstr ""
"Adicionalmente, instala as informações de depuração para as refs dadas e "
"suas dependências"

#: app/flatpak-builtins-install.c:78
msgid "Assume LOCATION is a .flatpak single-file bundle"
msgstr "Presume LOCALIZAÇÃO como sendo um pacote de arquivo único .flatpak"

#: app/flatpak-builtins-install.c:79
msgid "Assume LOCATION is a .flatpakref application description"
msgstr "Presume LOCALIZAÇÃO como sendo uma descrição de aplicativo .flatpakref"

#: app/flatpak-builtins-install.c:80
msgid "Assume LOCATION is containers-transports(5) reference to an OCI image"
msgstr ""
"Presume que LOCALIZAÇÃO seja uma referência containers-transports(5) para "
"uma imagem OCI"

#: app/flatpak-builtins-install.c:81
msgid "Check bundle signatures with GPG key from FILE (- for stdin)"
msgstr "Verifica assinaturas de pacote com chave GPG do ARQUIVO (- para stdin)"

#: app/flatpak-builtins-install.c:82
msgid "Only install this subpath"
msgstr "Instala apenas esse subcaminho"

#: app/flatpak-builtins-install.c:83 app/flatpak-builtins-preinstall.c:64
#: app/flatpak-builtins-uninstall.c:63 app/flatpak-builtins-update.c:68
msgid "Automatically answer yes for all questions"
msgstr "Responde sim automaticamente para todas as perguntas"

#: app/flatpak-builtins-install.c:84 app/flatpak-builtins-preinstall.c:65
msgid "Uninstall first if already installed"
msgstr "Desinstala primeiro, se já instalado"

#: app/flatpak-builtins-install.c:85 app/flatpak-builtins-preinstall.c:66
#: app/flatpak-builtins-uninstall.c:64 app/flatpak-builtins-update.c:69
msgid "Produce minimal output and don't ask questions"
msgstr "Produz saída mínima e não faz perguntas"

#: app/flatpak-builtins-install.c:86
msgid "Update install if already installed"
msgstr "Atualiza instalação se já instalada"

#. Translators: A sideload is when you install from a local USB drive rather than the Internet.
#: app/flatpak-builtins-install.c:88 app/flatpak-builtins-preinstall.c:68
#: app/flatpak-builtins-update.c:71
msgid "Use this local repo for sideloads"
msgstr "Usa este repositório local para downloads locais"

#: app/flatpak-builtins-install.c:178
msgid "Bundle filename must be specified"
msgstr "Arquivo do pacote deve ser especificado"

#: app/flatpak-builtins-install.c:188
msgid "Remote bundles are not supported"
msgstr "Não há suporte a pacotes remotos"

#: app/flatpak-builtins-install.c:231
msgid "Filename or uri must be specified"
msgstr "Arquivo ou uri deve ser especificado"

#: app/flatpak-builtins-install.c:295
msgid "Image location must be specified"
msgstr "A localização da imagem deve ser especificada"

#: app/flatpak-builtins-install.c:345
msgid "[LOCATION/REMOTE] [REF…] - Install applications or runtimes"
msgstr "[LOCALIZAÇÃO/REMOTO] [REF…] – Instala aplicativos ou runtimes"

#: app/flatpak-builtins-install.c:378
msgid "At least one REF must be specified"
msgstr "Pelo menos um REF deve ser especificado"

#: app/flatpak-builtins-install.c:392
#, c-format
msgid "Looking for matches…\n"
msgstr "Procurando por correspondências…\n"

#: app/flatpak-builtins-install.c:513
#, c-format
msgid "No remote refs found for ‘%s’"
msgstr "Nenhuma ref de remoto localizada para “%s”"

#: app/flatpak-builtins-install.c:573 app/flatpak-builtins-uninstall.c:405
#: common/flatpak-ref-utils.c:689 common/flatpak-ref-utils.c:1595
#, c-format
msgid "Invalid branch %s: %s"
msgstr "Ramo inválido %s: %s"

#: app/flatpak-builtins-install.c:606
#, c-format
msgid "Nothing matches %s in local repository for remote %s"
msgstr "Nada corresponde a %s no repositório local para o remoto %s"

#: app/flatpak-builtins-install.c:608
#, c-format
msgid "Nothing matches %s in remote %s"
msgstr "Nada corresponde a %s no remoto %s"

#: app/flatpak-builtins-install.c:629
#, c-format
msgid "Skipping: %s\n"
msgstr "Ignorando: %s\n"

#: app/flatpak-builtins-kill.c:110
#, c-format
msgid "%s is not running"
msgstr "%s não está em execução"

#: app/flatpak-builtins-kill.c:136
msgid "INSTANCE - Stop a running application"
msgstr "INSTÂNCIA – Termina um aplicativo em execução"

#: app/flatpak-builtins-kill.c:144 app/flatpak-builtins-ps.c:256
msgid "Extra arguments given"
msgstr "Argumentos extras dados"

#: app/flatpak-builtins-kill.c:150
msgid "Must specify the app to kill"
msgstr "Deve-se especificar o aplicativo para matar"

#: app/flatpak-builtins-list.c:47
msgid "Show extra information"
msgstr "Mostra informações extras"

#: app/flatpak-builtins-list.c:48
msgid "List installed runtimes"
msgstr "Lista runtimes instalados"

#: app/flatpak-builtins-list.c:49
msgid "List installed applications"
msgstr "Lista aplicativos instalados"

#: app/flatpak-builtins-list.c:50
msgid "Arch to show"
msgstr "Arquitetura para mostrar"

#: app/flatpak-builtins-list.c:51 app/flatpak-builtins-remote-ls.c:57
msgid "List all refs (including locale/debug)"
msgstr "Lista todos as refs (incluindo localidade/depuração)"

#: app/flatpak-builtins-list.c:53 app/flatpak-builtins-remote-ls.c:58
msgid "List all applications using RUNTIME"
msgstr "Lista todos os aplicativos usando RUNTIME"

#: app/flatpak-builtins-list.c:59 app/flatpak-builtins-remote-list.c:51
#: app/flatpak-builtins-remote-ls.c:68 app/flatpak-builtins-search.c:44
msgid "Name"
msgstr "Nome"

#: app/flatpak-builtins-list.c:59 app/flatpak-builtins-remote-list.c:51
#: app/flatpak-builtins-remote-ls.c:68 app/flatpak-builtins-search.c:44
msgid "Show the name"
msgstr "Mostra o nome"

#: app/flatpak-builtins-list.c:60 app/flatpak-builtins-remote-list.c:60
#: app/flatpak-builtins-remote-ls.c:69 app/flatpak-builtins-search.c:45
msgid "Description"
msgstr "Descrição"

#: app/flatpak-builtins-list.c:60 app/flatpak-builtins-remote-ls.c:69
#: app/flatpak-builtins-search.c:45
msgid "Show the description"
msgstr "Mostra a descrição"

#: app/flatpak-builtins-list.c:61 app/flatpak-builtins-remote-ls.c:70
#: app/flatpak-builtins-search.c:46
msgid "Application ID"
msgstr "ID de aplicativo"

#: app/flatpak-builtins-list.c:61 app/flatpak-builtins-ps.c:52
#: app/flatpak-builtins-remote-ls.c:70 app/flatpak-builtins-search.c:46
msgid "Show the application ID"
msgstr "Mostra o ID de aplicativo"

#: app/flatpak-builtins-list.c:62 app/flatpak-builtins-remote-ls.c:71
#: app/flatpak-builtins-search.c:47
msgid "Show the version"
msgstr "Mostra a versão"

#: app/flatpak-builtins-list.c:65 app/flatpak-builtins-ps.c:56
#: app/flatpak-builtins-remote-ls.c:77
msgid "Runtime"
msgstr "Runtime"

#: app/flatpak-builtins-list.c:65
msgid "Show the used runtime"
msgstr "Mostra o runtime usado"

#: app/flatpak-builtins-list.c:66 app/flatpak-builtins-remote-ls.c:74
msgid "Show the origin remote"
msgstr "Mostra o remoto origem"

#: app/flatpak-builtins-list.c:67
msgid "Show the installation"
msgstr "Mostra a instalação"

#: app/flatpak-builtins-list.c:69
msgid "Active commit"
msgstr "Commit ativo"

#: app/flatpak-builtins-list.c:69 app/flatpak-builtins-remote-ls.c:76
msgid "Show the active commit"
msgstr "Mostra o commit ativo"

#: app/flatpak-builtins-list.c:70
msgid "Latest commit"
msgstr "Último commit"

#: app/flatpak-builtins-list.c:70
msgid "Show the latest commit"
msgstr "Mostra o último commit"

#: app/flatpak-builtins-list.c:71 app/flatpak-builtins-remote-ls.c:78
msgid "Installed size"
msgstr "Tamanho instalado"

#: app/flatpak-builtins-list.c:71 app/flatpak-builtins-remote-ls.c:78
msgid "Show the installed size"
msgstr "Mostra o tamanho instalado"

#: app/flatpak-builtins-list.c:72 app/flatpak-builtins-remote-list.c:58
#: app/flatpak-builtins-remote-ls.c:80 app/flatpak-builtins-repo.c:340
msgid "Options"
msgstr "Opções"

#: app/flatpak-builtins-list.c:72 app/flatpak-builtins-remote-list.c:58
#: app/flatpak-builtins-remote-ls.c:80
msgid "Show options"
msgstr "Mostra as opções"

#: app/flatpak-builtins-list.c:180
#, c-format
msgid "Unable to load details of %s: %s"
msgstr "Não foi possível carregar detalhes de %s: %s"

#: app/flatpak-builtins-list.c:190
#, c-format
msgid "Unable to inspect current version of %s: %s"
msgstr "Não foi possível inspecionar a versão atual de %s: %s"

#: app/flatpak-builtins-list.c:408
msgid " - List installed apps and/or runtimes"
msgstr " – Lista os aplicativos e/ou runtimes instalados"

#: app/flatpak-builtins-make-current.c:38
msgid "Arch to make current for"
msgstr "Arquitetura para a qual será tornada atual"

#: app/flatpak-builtins-make-current.c:58
msgid "APP BRANCH - Make branch of application current"
msgstr "APLICATIVO RAMO – Faz o ramo do aplicativo atual"

#: app/flatpak-builtins-make-current.c:69 app/flatpak-builtins-run.c:260
msgid "APP must be specified"
msgstr "APLICATIVO deve ser especificado"

#: app/flatpak-builtins-make-current.c:84
msgid "BRANCH must be specified"
msgstr "RAMO deve ser especificado"

#: app/flatpak-builtins-make-current.c:97
#, c-format
msgid "App %s branch %s is not installed"
msgstr "Aplicativo %s ramo %s não está instalado"

#: app/flatpak-builtins-mask.c:42
msgid "Remove matching masks"
msgstr "Remove máscaras correspondentes"

#: app/flatpak-builtins-mask.c:54
msgid ""
"[PATTERN…] - disable updates and automatic installation matching patterns"
msgstr ""
"[PADRÃO…] - desabilita atualizações e instalação automática correspondendo a "
"padrões"

#: app/flatpak-builtins-mask.c:73
#, c-format
msgid "No masked patterns\n"
msgstr "Nenhum padrão mascarado\n"

#: app/flatpak-builtins-mask.c:78
#, c-format
msgid "Masked patterns:\n"
msgstr "Padrões mascarados:\n"

#: app/flatpak-builtins-override.c:42
msgid "Remove existing overrides"
msgstr "Remove sobreposições existentes"

#: app/flatpak-builtins-override.c:43
msgid "Show existing overrides"
msgstr "Mostra sobreposições existentes"

#: app/flatpak-builtins-override.c:59
msgid "[APP] - Override settings [for application]"
msgstr "[APLICATIVO] – Sobrepõe as configurações [para um aplicativo]"

#: app/flatpak-builtins-permission-list.c:143
msgid "[TABLE] [ID] - List permissions"
msgstr "[TABELA] [ID] – Lista permissões"

#: app/flatpak-builtins-permission-list.c:179
#: app/flatpak-builtins-permission-show.c:142
msgid "Table"
msgstr "Tabela"

#: app/flatpak-builtins-permission-list.c:180
#: app/flatpak-builtins-permission-show.c:143
msgid "Object"
msgstr "Objeto"

#: app/flatpak-builtins-permission-list.c:181
#: app/flatpak-builtins-permission-show.c:144
msgid "App"
msgstr "App"

#: app/flatpak-builtins-permission-list.c:183
#: app/flatpak-builtins-permission-show.c:146
msgid "Data"
msgstr "Dados"

#: app/flatpak-builtins-permission-remove.c:120
msgid "TABLE ID [APP_ID] - Remove item from permission store"
msgstr "TABELA ID [APP_ID] – Remove item do armazenamento de permissão"

#: app/flatpak-builtins-permission-remove.c:129
#: app/flatpak-builtins-permission-set.c:120
msgid "Too few arguments"
msgstr "Número insuficiente de argumentos"

#: app/flatpak-builtins-permission-reset.c:43
msgid "Reset all permissions"
msgstr "Redefine todas as permissões"

#: app/flatpak-builtins-permission-reset.c:144
msgid "APP_ID - Reset permissions for an app"
msgstr "ID_APP – Redefine permissões para este aplicativo"

#: app/flatpak-builtins-permission-reset.c:153
#: app/flatpak-builtins-permission-show.c:124
msgid "Wrong number of arguments"
msgstr "Número incorreto de argumentos"

#: app/flatpak-builtins-permission-set.c:42
msgid "Associate DATA with the entry"
msgstr "Associa DADOS com a entrada"

#: app/flatpak-builtins-permission-set.c:42
msgid "DATA"
msgstr "DADOS"

#: app/flatpak-builtins-permission-set.c:111
msgid "TABLE ID APP_ID [PERMISSION...] - Set permissions"
msgstr "TABELA ID APP_ID [PERMISSÃO…] – Define permissões"

#: app/flatpak-builtins-permission-set.c:132
#, c-format
msgid "Failed to parse '%s' as GVariant: "
msgstr "Falha ao analisar “%s” como GVariant: "

#: app/flatpak-builtins-permission-show.c:115
msgid "APP_ID - Show permissions for an app"
msgstr "ID_APP – Mostra permissões para este aplicativo"

#: app/flatpak-builtins-pin.c:44
msgid "Remove matching pins"
msgstr "Remove as fixações correspondentes"

#: app/flatpak-builtins-pin.c:56
msgid "[PATTERN…] - disable automatic removal of runtimes matching patterns"
msgstr ""
"[PADRÃO…] - desabilita remoção automática de runtimes correspondendo a "
"padrões"

#: app/flatpak-builtins-pin.c:75
#, c-format
msgid "No pinned patterns\n"
msgstr "Nenhum padrão fixado\n"

#: app/flatpak-builtins-pin.c:80
#, c-format
msgid "Pinned patterns:\n"
msgstr "Padrões fixados:\n"

#: app/flatpak-builtins-preinstall.c:80
msgid "- Install flatpaks that are part of the operating system"
msgstr "- Instalar flatpaks que são parte do sistema operacional"

#: app/flatpak-builtins-preinstall.c:118
#, c-format
msgid "Nothing to do.\n"
msgstr "Nada para fazer.\n"

#: app/flatpak-builtins-ps.c:49
msgid "Instance"
msgstr "Instância"

#: app/flatpak-builtins-ps.c:49
msgid "Show the instance ID"
msgstr "Mostra o ID da instância"

#: app/flatpak-builtins-ps.c:50 app/flatpak-builtins-run.c:178
msgid "PID"
msgstr "PID"

#: app/flatpak-builtins-ps.c:50
msgid "Show the PID of the wrapper process"
msgstr "Mostra o PID do processo wrapper"

#: app/flatpak-builtins-ps.c:51
msgid "Child-PID"
msgstr "PID-Filho"

#: app/flatpak-builtins-ps.c:51
msgid "Show the PID of the sandbox process"
msgstr "Mostra o PID do processo da caixa de proteção"

#: app/flatpak-builtins-ps.c:54 app/flatpak-builtins-search.c:48
msgid "Show the application branch"
msgstr "Mostra o ramo do aplicativo"

#: app/flatpak-builtins-ps.c:55
msgid "Show the application commit"
msgstr "Mostra o commit de aplicativo"

#: app/flatpak-builtins-ps.c:56
msgid "Show the runtime ID"
msgstr "Mostra o ID de runtime"

#: app/flatpak-builtins-ps.c:57
msgid "R.-Branch"
msgstr "Ramo-R."

#: app/flatpak-builtins-ps.c:57
msgid "Show the runtime branch"
msgstr "Mostra o ramo do runtime"

#: app/flatpak-builtins-ps.c:58
msgid "R.-Commit"
msgstr "Commit-R."

#: app/flatpak-builtins-ps.c:58
msgid "Show the runtime commit"
msgstr "Mostra o commit de runtime"

#: app/flatpak-builtins-ps.c:59
msgid "Active"
msgstr "Ativo"

#: app/flatpak-builtins-ps.c:59
msgid "Show whether the app is active"
msgstr "Mostra se o aplicativo está ativo"

#: app/flatpak-builtins-ps.c:60
msgid "Background"
msgstr "Segundo plano"

#: app/flatpak-builtins-ps.c:60
msgid "Show whether the app is background"
msgstr "Mostra se o aplicativo está em segundo plano"

#: app/flatpak-builtins-ps.c:246
msgid " - Enumerate running sandboxes"
msgstr " – Enumera as caixas de proteção em execução"

#: app/flatpak-builtins-remote-add.c:66
msgid "Do nothing if the provided remote exists"
msgstr "Faz nada se o remoto fornecido existir"

#: app/flatpak-builtins-remote-add.c:67
msgid "LOCATION specifies a configuration file, not the repo location"
msgstr ""
"LOCALIZAÇÃO especifica um arquivo de configuração, não a localização do repo"

#: app/flatpak-builtins-remote-add.c:72 app/flatpak-builtins-remote-modify.c:78
msgid "Disable GPG verification"
msgstr "Desabilita verificação GPG"

#: app/flatpak-builtins-remote-add.c:73 app/flatpak-builtins-remote-modify.c:79
msgid "Mark the remote as don't enumerate"
msgstr "Marca o remoto como não enumerado"

#: app/flatpak-builtins-remote-add.c:74 app/flatpak-builtins-remote-modify.c:80
msgid "Mark the remote as don't use for deps"
msgstr "Marca o remoto como não usar para dependências"

#: app/flatpak-builtins-remote-add.c:75 app/flatpak-builtins-remote-modify.c:81
msgid "Set priority (default 1, higher is more prioritized)"
msgstr "Define prioridade (padrão 1, maior é mais prioritário)"

#: app/flatpak-builtins-remote-add.c:75 app/flatpak-builtins-remote-modify.c:81
msgid "PRIORITY"
msgstr "PRIORIDADE"

#: app/flatpak-builtins-remote-add.c:76
msgid "The named subset to use for this remote"
msgstr "O subconjunto nomeado a ser usado para este remoto"

#: app/flatpak-builtins-remote-add.c:76 app/flatpak-builtins-remote-modify.c:71
msgid "SUBSET"
msgstr "SUBCONJUNTO"

#: app/flatpak-builtins-remote-add.c:77 app/flatpak-builtins-remote-modify.c:82
msgid "A nice name to use for this remote"
msgstr "Um nome legal para usar para este remoto"

#: app/flatpak-builtins-remote-add.c:78 app/flatpak-builtins-remote-modify.c:83
msgid "A one-line comment for this remote"
msgstr "Um comentário de uma linha para este remoto"

#: app/flatpak-builtins-remote-add.c:79 app/flatpak-builtins-remote-modify.c:84
msgid "A full-paragraph description for this remote"
msgstr "Uma descrição de parágrafo completo para este remoto"

#: app/flatpak-builtins-remote-add.c:80 app/flatpak-builtins-remote-modify.c:85
msgid "URL for a website for this remote"
msgstr "URL para um website para este remoto"

#: app/flatpak-builtins-remote-add.c:81 app/flatpak-builtins-remote-modify.c:86
msgid "URL for an icon for this remote"
msgstr "URL para um ícone para este remoto"

#: app/flatpak-builtins-remote-add.c:82 app/flatpak-builtins-remote-modify.c:87
msgid "Default branch to use for this remote"
msgstr "Ramo padrão para usar para este remoto"

#: app/flatpak-builtins-remote-add.c:84 app/flatpak-builtins-remote-modify.c:89
msgid "Import GPG key from FILE (- for stdin)"
msgstr "Importa uma chave GPG do ARQUIVO (- para stdin)"

#: app/flatpak-builtins-remote-add.c:85 app/flatpak-builtins-remote-modify.c:90
msgid "Load signatures from URL"
msgstr "Carrega assinaturas da URL"

#: app/flatpak-builtins-remote-add.c:86 app/flatpak-builtins-remote-modify.c:92
msgid "Set path to local filter FILE"
msgstr "Define o caminho para o filtro local ARQUIVO"

#: app/flatpak-builtins-remote-add.c:87 app/flatpak-builtins-remote-modify.c:93
msgid "Disable the remote"
msgstr "Desabilita o remoto"

#: app/flatpak-builtins-remote-add.c:88 app/flatpak-builtins-remote-modify.c:94
msgid "Name of authenticator"
msgstr "Nome do autenticador"

#: app/flatpak-builtins-remote-add.c:90 app/flatpak-builtins-remote-modify.c:96
msgid "Autoinstall authenticator"
msgstr "Instala automaticamente autenticador"

#: app/flatpak-builtins-remote-add.c:91 app/flatpak-builtins-remote-modify.c:97
msgid "Don't autoinstall authenticator"
msgstr "Não instala automaticamente autenticador"

#: app/flatpak-builtins-remote-add.c:92 app/flatpak-builtins-remote-modify.c:99
msgid "Don't follow the redirect set in the summary file"
msgstr "Não segue o redirecionamento definido no arquivo de resumo"

#: app/flatpak-builtins-remote-add.c:261 app/flatpak-builtins-remote-add.c:268
#, c-format
msgid "Can't load uri %s: %s\n"
msgstr "Não foi possível carregar a uri %s: %s\n"

#: app/flatpak-builtins-remote-add.c:276 common/flatpak-dir.c:4643
#, c-format
msgid "Can't load file %s: %s\n"
msgstr "Não foi possível carregar o arquivo %s: %s\n"

#: app/flatpak-builtins-remote-add.c:304
msgid "NAME LOCATION - Add a remote repository"
msgstr "NOME LOCALIZAÇÃO – Adiciona um repositório remoto"

#: app/flatpak-builtins-remote-add.c:331
msgid "GPG verification is required if collections are enabled"
msgstr "Verificação GPG é exigida se coleções estiverem habilitadas"

#: app/flatpak-builtins-remote-add.c:393
#, c-format
msgid "Remote %s already exists"
msgstr "O remoto %s já existe"

#: app/flatpak-builtins-remote-add.c:405
#: app/flatpak-builtins-remote-modify.c:340
#, c-format
msgid "Invalid authenticator name %s"
msgstr "Nome de autenticador inválido %s"

#: app/flatpak-builtins-remote-add.c:422
#, c-format
msgid "Warning: Could not update extra metadata for '%s': %s\n"
msgstr "Aviso: Não foi possível atualizar metadados extras para “%s”: %s\n"

#: app/flatpak-builtins-remote-delete.c:39
msgid "Remove remote even if in use"
msgstr "Remove remoto ainda que ele esteja em uso"

#: app/flatpak-builtins-remote-delete.c:53
msgid "NAME - Delete a remote repository"
msgstr "NOME – Exclui um repositório remoto"

#: app/flatpak-builtins-remote-delete.c:100
#, c-format
msgid "The following refs are installed from remote '%s':"
msgstr "As seguintes refs já estão instaladas do remoto “%s”:"

#: app/flatpak-builtins-remote-delete.c:101
msgid "Remove them?"
msgstr "Removê-las?"

#: app/flatpak-builtins-remote-delete.c:103
#, c-format
msgid "Can't remove remote '%s' with installed refs"
msgstr "Não é possível remover o remoto “%s” com refs instaladas"

#: app/flatpak-builtins-remote-info.c:55
msgid "Commit to show info for"
msgstr "Commit para mostrar informações"

#: app/flatpak-builtins-remote-info.c:58
msgid "Display log"
msgstr "Exibe log"

#: app/flatpak-builtins-remote-info.c:61
msgid "Show parent"
msgstr "Mostra pai"

#: app/flatpak-builtins-remote-info.c:65 app/flatpak-builtins-remote-ls.c:60
msgid "Use local caches even if they are stale"
msgstr "Usa caches locais mesmo se eles estiverem velhos"

#. Translators: A sideload is when you install from a local USB drive rather than the Internet.
#: app/flatpak-builtins-remote-info.c:67 app/flatpak-builtins-remote-ls.c:62
msgid "Only list refs available as sideloads"
msgstr "Lista apenas refs disponíveis como downloads locais"

#: app/flatpak-builtins-remote-info.c:114
msgid ""
" REMOTE REF - Show information about an application or runtime in a remote"
msgstr ""
" REMOTO REF – Mostra informações sobre um aplicativo ou runtime em um remoto"

#: app/flatpak-builtins-remote-info.c:125
msgid "REMOTE and REF must be specified"
msgstr "REMOTO e REF devem ser especificados"

#: app/flatpak-builtins-remote-info.c:247
#: app/flatpak-builtins-remote-info.c:282
msgid "Download Size:"
msgstr "Tamanho do download:"

#: app/flatpak-builtins-remote-info.c:267
#: app/flatpak-builtins-remote-info.c:325
msgid "History:"
msgstr "Histórico:"

#: app/flatpak-builtins-remote-info.c:348
msgid " Commit:"
msgstr " Commit:"

#: app/flatpak-builtins-remote-info.c:349
msgid " Subject:"
msgstr " Assunto:"

#: app/flatpak-builtins-remote-info.c:350
msgid " Date:"
msgstr " Data:"

#: app/flatpak-builtins-remote-info.c:383
#, c-format
msgid "Warning: Commit %s has no flatpak metadata\n"
msgstr "Aviso: O commit %s tem nenhum metadado de flatpak\n"

#: app/flatpak-builtins-remote-list.c:43
msgid "Show remote details"
msgstr "Mostra os detalhes do remoto"

#: app/flatpak-builtins-remote-list.c:44
msgid "Show disabled remotes"
msgstr "Mostra remotos desabilitados"

#: app/flatpak-builtins-remote-list.c:52
msgid "Title"
msgstr "Título"

#: app/flatpak-builtins-remote-list.c:52
msgid "Show the title"
msgstr "Mostra o título"

#: app/flatpak-builtins-remote-list.c:53
msgid "Show the URL"
msgstr "Mostra a URL"

#: app/flatpak-builtins-remote-list.c:54
msgid "Show the collection ID"
msgstr "Mostra o ID da coleção"

#: app/flatpak-builtins-remote-list.c:55 app/flatpak-builtins-repo.c:392
msgid "Subset"
msgstr "Subconjunto"

#: app/flatpak-builtins-remote-list.c:55
msgid "Show the subset"
msgstr "Exibe o subconjunto"

#: app/flatpak-builtins-remote-list.c:56
msgid "Filter"
msgstr "Filtro"

#: app/flatpak-builtins-remote-list.c:56
msgid "Show filter file"
msgstr "Mostra o arquivo do filtro"

#: app/flatpak-builtins-remote-list.c:57
msgid "Priority"
msgstr "Prioridade"

#: app/flatpak-builtins-remote-list.c:57
msgid "Show the priority"
msgstr "Mostra a prioridade"

#: app/flatpak-builtins-remote-list.c:59
msgid "Comment"
msgstr "Comentário"

#: app/flatpak-builtins-remote-list.c:59
msgid "Show comment"
msgstr "Mostra comentário"

#: app/flatpak-builtins-remote-list.c:60
msgid "Show description"
msgstr "Mostra descrição"

#: app/flatpak-builtins-remote-list.c:61
msgid "Homepage"
msgstr "Página inicial"

#: app/flatpak-builtins-remote-list.c:61
msgid "Show homepage"
msgstr "Mostra página inicial"

#: app/flatpak-builtins-remote-list.c:62
msgid "Icon"
msgstr "Ícone"

#: app/flatpak-builtins-remote-list.c:62
msgid "Show icon"
msgstr "Mostra ícone"

#: app/flatpak-builtins-remote-list.c:231
msgid " - List remote repositories"
msgstr " – Lista repositórios remotos"

#: app/flatpak-builtins-remote-ls.c:52
msgid "Show arches and branches"
msgstr "Mostra arquiteturas e ramos"

#: app/flatpak-builtins-remote-ls.c:53
msgid "Show only runtimes"
msgstr "Mostra apenas runtimes"

#: app/flatpak-builtins-remote-ls.c:54
msgid "Show only apps"
msgstr "Mostra apenas aplicativos"

#: app/flatpak-builtins-remote-ls.c:55
msgid "Show only those where updates are available"
msgstr "Mostra apenas aqueles com atualizações disponíveis"

#: app/flatpak-builtins-remote-ls.c:56
msgid "Limit to this arch (* for all)"
msgstr "Limita a essa arquitetura (* para todas)"

#: app/flatpak-builtins-remote-ls.c:77
msgid "Show the runtime"
msgstr "Mostra o runtime"

#: app/flatpak-builtins-remote-ls.c:79
msgid "Download size"
msgstr "Tamanho baixado"

#: app/flatpak-builtins-remote-ls.c:79
msgid "Show the download size"
msgstr "Mostra o tamanho baixado"

#: app/flatpak-builtins-remote-ls.c:391
msgid " [REMOTE or URI] - Show available runtimes and applications"
msgstr " [REMOTO ou URI] – Mostra runtimes e aplicativos disponíveis"

#: app/flatpak-builtins-remote-modify.c:67
msgid "Enable GPG verification"
msgstr "Habilita verificação GPG"

#: app/flatpak-builtins-remote-modify.c:68
msgid "Mark the remote as enumerate"
msgstr "Marca o remoto como enumerado"

#: app/flatpak-builtins-remote-modify.c:69
msgid "Mark the remote as used for dependencies"
msgstr "Marca o repositório como usado para dependências"

#: app/flatpak-builtins-remote-modify.c:70
msgid "Set a new URL"
msgstr "Define uma nova URL"

#: app/flatpak-builtins-remote-modify.c:71
msgid "Set a new subset to use"
msgstr "Define um novo subconjunto para usar"

#: app/flatpak-builtins-remote-modify.c:72
msgid "Enable the remote"
msgstr "Habilita o remoto"

#: app/flatpak-builtins-remote-modify.c:73
msgid "Update extra metadata from the summary file"
msgstr "Atualiza metadados extras do arquivo de resumo"

#: app/flatpak-builtins-remote-modify.c:91
msgid "Disable local filter"
msgstr "Desabilita o filtro local"

#: app/flatpak-builtins-remote-modify.c:95
msgid "Authenticator options"
msgstr "Opções do autenticador"

#: app/flatpak-builtins-remote-modify.c:98
msgid "Follow the redirect set in the summary file"
msgstr "Segue o redirecionamento definido no arquivo de resumo"

#: app/flatpak-builtins-remote-modify.c:306
msgid "NAME - Modify a remote repository"
msgstr "NOME – Modifica um repositório remoto"

#: app/flatpak-builtins-remote-modify.c:316
msgid "Remote NAME must be specified"
msgstr "NOME remoto deve ser especificado"

#: app/flatpak-builtins-remote-modify.c:327
#, c-format
msgid "Updating extra metadata from remote summary for %s\n"
msgstr "Atualizando metadados extras para resumo de remoto para %s\n"

#: app/flatpak-builtins-remote-modify.c:330
#, c-format
msgid "Error updating extra metadata for '%s': %s\n"
msgstr "Erro ao atualizar metadados extras para “%s”: %s\n"

#: app/flatpak-builtins-remote-modify.c:331
#, c-format
msgid "Could not update extra metadata for %s"
msgstr "Não foi possível atualizar metadados extras para %s"

#: app/flatpak-builtins-repair.c:43
msgid "Don't make any changes"
msgstr "Não faz quaisquer alterações"

#: app/flatpak-builtins-repair.c:44
msgid "Reinstall all refs"
msgstr "Reinstala todas as refs"

#: app/flatpak-builtins-repair.c:68
#, c-format
msgid "Object missing: %s.%s\n"
msgstr "Faltando objeto: %s.%s\n"

#: app/flatpak-builtins-repair.c:76
#, c-format
msgid "Object invalid: %s.%s\n"
msgstr "Objeto inválido: %s.%s\n"

#: app/flatpak-builtins-repair.c:81
#, c-format
msgid "%s, deleting object\n"
msgstr "%s, excluindo objeto\n"

#: app/flatpak-builtins-repair.c:146
#, c-format
msgid "Can't load object %s: %s\n"
msgstr "Não foi possível carregar o objeto %s: %s\n"

#: app/flatpak-builtins-repair.c:228
#, c-format
msgid "Commit invalid %s: %s\n"
msgstr "Commit inválido: %s: %s\n"

#: app/flatpak-builtins-repair.c:231
#, c-format
msgid "Deleting invalid commit %s: %s\n"
msgstr "Excluindo commit inválido %s: %s\n"

#: app/flatpak-builtins-repair.c:261
#, c-format
msgid "Commit should be marked partial: %s\n"
msgstr "O commit deve ser marcado como parcial: %s\n"

#: app/flatpak-builtins-repair.c:264
#, c-format
msgid "Marking commit as partial: %s\n"
msgstr "Marcando commit como parcial: %s\n"

#: app/flatpak-builtins-repair.c:293
#, c-format
msgid "Problems loading data for %s: %s\n"
msgstr "Problemas ao carregar dados para %s: %s\n"

#: app/flatpak-builtins-repair.c:306
#, c-format
msgid "Error reinstalling %s: %s\n"
msgstr "Erro ao reinstalar %s: %s\n"

#: app/flatpak-builtins-repair.c:327
msgid "- Repair a flatpak installation"
msgstr "– Corrige uma instalação do flatpak"

#: app/flatpak-builtins-repair.c:406
#, c-format
msgid "Removing non-deployed ref %s…\n"
msgstr "Removendo ref não implantada %s…\n"

#: app/flatpak-builtins-repair.c:411
#, c-format
msgid "Skipping non-deployed ref %s…\n"
msgstr "Ignorando ref não implantada %s…\n"

#: app/flatpak-builtins-repair.c:429
#, c-format
msgid "[%d/%d] Verifying %s…\n"
msgstr "[%d/%d] Verificando %s…\n"

#: app/flatpak-builtins-repair.c:435
#, c-format
msgid "Dry run: "
msgstr "Simulação: "

#: app/flatpak-builtins-repair.c:440
#, c-format
msgid "Deleting ref %s due to missing objects\n"
msgstr "Excluindo ref %s por causa de objetos faltantes\n"

#: app/flatpak-builtins-repair.c:444
#, c-format
msgid "Deleting ref %s due to invalid objects\n"
msgstr "Excluindo ref %s devido a objetos inválidos\n"

#: app/flatpak-builtins-repair.c:448
#, c-format
msgid "Deleting ref %s due to %d\n"
msgstr "Excluindo ref %s devido a %d\n"

#: app/flatpak-builtins-repair.c:464
#, c-format
msgid "Checking remotes...\n"
msgstr "Verificando remotos...\n"

#: app/flatpak-builtins-repair.c:482
#, c-format
msgid "Remote %s for ref %s is missing\n"
msgstr "O remoto %s para ref %s está em falta\n"

#: app/flatpak-builtins-repair.c:484
#, c-format
msgid "Remote %s for ref %s is disabled\n"
msgstr "O remoto %s para ref %s está desabilitado\n"

#: app/flatpak-builtins-repair.c:490
#, c-format
msgid "Pruning objects\n"
msgstr "Suprimindo objetos\n"

#: app/flatpak-builtins-repair.c:498
#, c-format
msgid "Erasing .removed\n"
msgstr "Apagando .removed\n"

#: app/flatpak-builtins-repair.c:524
#, c-format
msgid "Reinstalling refs\n"
msgstr "Reinstalando refs\n"

#: app/flatpak-builtins-repair.c:526
#, c-format
msgid "Reinstalling removed refs\n"
msgstr "Reinstalando refs removidas\n"

#: app/flatpak-builtins-repair.c:551
#, c-format
msgid "While removing appstream for %s: "
msgstr "Ao remover appstream para %s: "

#: app/flatpak-builtins-repair.c:558
#, c-format
msgid "While deploying appstream for %s: "
msgstr "Ao implantar appstream para %s: "

#: app/flatpak-builtins-repo.c:106
#, c-format
msgid "Repo mode: %s\n"
msgstr "Modo repo: %s\n"

#: app/flatpak-builtins-repo.c:113
#, c-format
msgid "Indexed summaries: %s\n"
msgstr "Resumos indexados: %s\n"

#: app/flatpak-builtins-repo.c:113 app/flatpak-builtins-repo.c:139
#: app/flatpak-builtins-repo.c:172
msgid "true"
msgstr "verdadeiro"

#: app/flatpak-builtins-repo.c:113 app/flatpak-builtins-repo.c:139
#: app/flatpak-builtins-repo.c:172
msgid "false"
msgstr "falso"

#: app/flatpak-builtins-repo.c:121
#, c-format
msgid "Subsummaries: "
msgstr "Sub-resumos: "

#: app/flatpak-builtins-repo.c:136
#, c-format
msgid "Cache version: %d\n"
msgstr "Versão do cache: %d\n"

#: app/flatpak-builtins-repo.c:139
#, c-format
msgid "Indexed deltas: %s\n"
msgstr "Deltas indexados: %s\n"

#: app/flatpak-builtins-repo.c:142
#, c-format
msgid "Title: %s\n"
msgstr "Título: %s\n"

#: app/flatpak-builtins-repo.c:145
#, c-format
msgid "Comment: %s\n"
msgstr "Comentário: %s\n"

#: app/flatpak-builtins-repo.c:148
#, c-format
msgid "Description: %s\n"
msgstr "Descrição: %s\n"

#: app/flatpak-builtins-repo.c:151
#, c-format
msgid "Homepage: %s\n"
msgstr "Página inicial: %s\n"

#: app/flatpak-builtins-repo.c:154
#, c-format
msgid "Icon: %s\n"
msgstr "Ícone: %s\n"

#: app/flatpak-builtins-repo.c:157
#, c-format
msgid "Collection ID: %s\n"
msgstr "ID de coleção: %s\n"

#: app/flatpak-builtins-repo.c:160
#, c-format
msgid "Default branch: %s\n"
msgstr "Ramo padrão: %s\n"

#: app/flatpak-builtins-repo.c:163
#, c-format
msgid "Redirect URL: %s\n"
msgstr "URL de redirecionamento: %s\n"

#: app/flatpak-builtins-repo.c:166
#, c-format
msgid "Deploy collection ID: %s\n"
msgstr "ID de coleção de implementação: %s\n"

#: app/flatpak-builtins-repo.c:169
#, c-format
msgid "Authenticator name: %s\n"
msgstr "Nome do autenticador: %s\n"

#: app/flatpak-builtins-repo.c:172
#, c-format
msgid "Authenticator install: %s\n"
msgstr "Instalação do autenticador: %s\n"

#: app/flatpak-builtins-repo.c:180
#, c-format
msgid "GPG key hash: %s\n"
msgstr "Hash de chave GPG: %s\n"

#: app/flatpak-builtins-repo.c:184
#, c-format
msgid "%zd summary branches\n"
msgstr "%zd ramos de resumo\n"

#: app/flatpak-builtins-repo.c:336
msgid "Installed"
msgstr "Instalado"

#. Translators: Download is used here as a noun
#: app/flatpak-builtins-repo.c:338 app/flatpak-cli-transaction.c:1462
msgid "Download"
msgstr "Baixar"

#: app/flatpak-builtins-repo.c:339
msgid "Subsets"
msgstr "Subconjuntos"

#: app/flatpak-builtins-repo.c:393
msgid "Digest"
msgstr "Digest"

#: app/flatpak-builtins-repo.c:394
msgid "History length"
msgstr "Tamanho do histórico"

#: app/flatpak-builtins-repo.c:711
msgid "Print general information about the repository"
msgstr "Mostra informações gerais sobre um repositório"

#: app/flatpak-builtins-repo.c:712
msgid "List the branches in the repository"
msgstr "Lisa os ramos no repositório"

#: app/flatpak-builtins-repo.c:713
msgid "Print metadata for a branch"
msgstr "Mostra metadados para um ramo"

#: app/flatpak-builtins-repo.c:714
msgid "Show commits for a branch"
msgstr "Mostra commits para um ramo"

#: app/flatpak-builtins-repo.c:715
msgid "Print information about the repo subsets"
msgstr "Exibe informações sobre os subconjuntos de repo"

#: app/flatpak-builtins-repo.c:716
msgid "Limit information to subsets with this prefix"
msgstr "Limita as informações a subconjuntos com este prefixo"

#: app/flatpak-builtins-repo.c:732
msgid "LOCATION - Repository maintenance"
msgstr "LOCALIZAÇÃO – Manutenção de repositório"

#: app/flatpak-builtins-run.c:159
msgid "Command to run"
msgstr "Comando para executar"

#: app/flatpak-builtins-run.c:160
msgid "Directory to run the command in"
msgstr "Diretório para executar o comando"

#: app/flatpak-builtins-run.c:161
msgid "Branch to use"
msgstr "Ramo para usar"

#: app/flatpak-builtins-run.c:162
msgid "Use development runtime"
msgstr "Usa runtime de desenvolvimento"

#: app/flatpak-builtins-run.c:163
msgid "Runtime to use"
msgstr "Runtime para usar"

#: app/flatpak-builtins-run.c:164
msgid "Runtime version to use"
msgstr "Versão do runtime para usar"

#: app/flatpak-builtins-run.c:167
msgid "Log accessibility bus calls"
msgstr "Registra o log das chamadas de barramento de acessibilidade"

#: app/flatpak-builtins-run.c:168
msgid "Don't proxy accessibility bus calls"
msgstr "Não intermedeia chamadas de barramento de acessibilidade"

#: app/flatpak-builtins-run.c:169
msgid "Proxy accessibility bus calls (default except when sandboxed)"
msgstr ""
"Intermedeia chamadas de barramento de acessibilidade (padrão, exceto quando "
"em uma caixa de proteção)"

#: app/flatpak-builtins-run.c:170
msgid "Don't proxy session bus calls"
msgstr "Não intermedeia chamadas de barramento de sessão"

#: app/flatpak-builtins-run.c:171
msgid "Proxy session bus calls (default except when sandboxed)"
msgstr ""
"Intermedeia chamadas de barramento de sessão (padrão, exceto quando em uma "
"caixa de proteção)"

#: app/flatpak-builtins-run.c:172
msgid "Don't start portals"
msgstr "Não inicia portais"

#: app/flatpak-builtins-run.c:173
msgid "Enable file forwarding"
msgstr "Habilita encaminhamento de arquivo"

#: app/flatpak-builtins-run.c:174
msgid "Run specified commit"
msgstr "Executa o commit especificado"

#: app/flatpak-builtins-run.c:175
msgid "Use specified runtime commit"
msgstr "Usa o commit de runtime especificado"

#: app/flatpak-builtins-run.c:176
msgid "Run completely sandboxed"
msgstr "Executa totalmente em uma caixa de proteção"

#: app/flatpak-builtins-run.c:178
msgid "Use PID as parent pid for sharing namespaces"
msgstr "Usa PID como pid pai para compartilhamento de espaços de nome"

#: app/flatpak-builtins-run.c:179
msgid "Make processes visible in parent namespace"
msgstr "Torna os processos visíveis no espaço de nome pai"

#: app/flatpak-builtins-run.c:180
msgid "Share process ID namespace with parent"
msgstr "Compartilha espaço de nome de ID de processo com pai"

#: app/flatpak-builtins-run.c:181
msgid "Write the instance ID to the given file descriptor"
msgstr "Escreve o ID de instância para o descritor de arquivo dado"

#: app/flatpak-builtins-run.c:182
msgid "Use PATH instead of the app's /app"
msgstr "Usa PATH em vez do /app do aplicativo"

#: app/flatpak-builtins-run.c:183
#, fuzzy
msgid "Use FD instead of the app's /app"
msgstr "Usa PATH em vez do /app do aplicativo"

#: app/flatpak-builtins-run.c:183 app/flatpak-builtins-run.c:185
#: app/flatpak-builtins-run.c:187 app/flatpak-builtins-run.c:188
#: common/flatpak-context.c:2672
msgid "FD"
msgstr "FD"

#: app/flatpak-builtins-run.c:184
msgid "Use PATH instead of the runtime's /usr"
msgstr "Usa PATH em vez de /usr do runtime"

#: app/flatpak-builtins-run.c:185
#, fuzzy
msgid "Use FD instead of the runtime's /usr"
msgstr "Usa PATH em vez de /usr do runtime"

#: app/flatpak-builtins-run.c:186
msgid "Clear all outside environment variables"
msgstr "Remove definição de todas variáveis de ambiente externas"

#: app/flatpak-builtins-run.c:187
msgid ""
"Bind mount the file or directory referred to by FD to its canonicalized path"
msgstr ""

#: app/flatpak-builtins-run.c:188
msgid ""
"Bind mount the file or directory referred to by FD read-only to its "
"canonicalized path"
msgstr ""

#: app/flatpak-builtins-run.c:219
msgid "APP [ARGUMENT…] - Run an app"
msgstr "APLICATIVO [ARGUMENTO…] – Executa um aplicativo"

#: app/flatpak-builtins-run.c:370
#, c-format
msgid "runtime/%s/%s/%s not installed"
msgstr "runtime/%s/%s/%s não instalado"

#: app/flatpak-builtins-run.c:419
msgid "app-fd and app-path cannot both be used"
msgstr ""

#: app/flatpak-builtins-run.c:449
msgid "usr-fd and usr-path cannot both be used"
msgstr ""

#: app/flatpak-builtins-search.c:37
msgid "Arch to search for"
msgstr "Arquitetura para pesquisar por"

#: app/flatpak-builtins-search.c:49
msgid "Remotes"
msgstr "Remotos"

#: app/flatpak-builtins-search.c:49
msgid "Show the remotes"
msgstr "Mostra os remotos"

#: app/flatpak-builtins-search.c:244
msgid "TEXT - Search remote apps/runtimes for text"
msgstr "TEXTO – Pesquisa aplicativos/runtimes remotos para texto"

#: app/flatpak-builtins-search.c:255
msgid "TEXT must be specified"
msgstr "TEXTO deve ser especificado"

#: app/flatpak-builtins-search.c:338
msgid "No matches found"
msgstr "Nenhuma correspondência localizada"

#: app/flatpak-builtins-uninstall.c:54
msgid "Arch to uninstall"
msgstr "Arquitetura para desinstalar"

#: app/flatpak-builtins-uninstall.c:55
msgid "Keep ref in local repository"
msgstr "Mantém a ref no repositório local"

#: app/flatpak-builtins-uninstall.c:56
msgid "Don't uninstall related refs"
msgstr "Não desinstala as refs relacionadas"

#: app/flatpak-builtins-uninstall.c:57
msgid "Remove files even if running"
msgstr "Remove os arquivos ainda que estejam em execução"

#: app/flatpak-builtins-uninstall.c:60
msgid "Uninstall all"
msgstr "Desinstala todos"

#: app/flatpak-builtins-uninstall.c:61
msgid "Uninstall unused"
msgstr "Desinstala não usados"

#: app/flatpak-builtins-uninstall.c:62
msgid "Delete app data"
msgstr "Exclui dados do aplicativo"

#: app/flatpak-builtins-uninstall.c:141
#, c-format
msgid "Delete data for %s?"
msgstr "Excluir dados para %s?"

#: app/flatpak-builtins-uninstall.c:220
#, c-format
msgid "Info: applications using the extension %s%s%s branch %s%s%s:\n"
msgstr "Info: aplicativos que usam a extensão %s%s%s ramo %s%s%s:\n"

#: app/flatpak-builtins-uninstall.c:223
#, c-format
msgid "Info: applications using the runtime %s%s%s branch %s%s%s:\n"
msgstr "Info: aplicativos que usam o runtime %s%s%s ramo %s%s%s:\n"

#: app/flatpak-builtins-uninstall.c:238
msgid "Really remove?"
msgstr "Realmente remover?"

#: app/flatpak-builtins-uninstall.c:255
msgid "[REF…] - Uninstall applications or runtimes"
msgstr "[REF…] – Desinstala aplicativos ou runtimes"

#: app/flatpak-builtins-uninstall.c:264
msgid "Must specify at least one REF, --unused, --all or --delete-data"
msgstr "Deve especificar pelo menos uma REF, --unused, --all ou --delete-data"

#: app/flatpak-builtins-uninstall.c:267
msgid "Must not specify REFs when using --all"
msgstr "Não pode especificar REFs ao usar --all"

#: app/flatpak-builtins-uninstall.c:270
msgid "Must not specify REFs when using --unused"
msgstr "Não pode especificar REFs ao usar --unused"

#: app/flatpak-builtins-uninstall.c:336
#, c-format
msgid ""
"\n"
"These runtimes in installation '%s' are pinned and won't be removed; see "
"flatpak-pin(1):\n"
msgstr ""
"\n"
"Estes runtimes na instalação “%s” são fixados e não serão removidos; veja "
"flatpak-pin(1):\n"

#: app/flatpak-builtins-uninstall.c:370
#, c-format
msgid "Nothing unused to uninstall\n"
msgstr "Nada não usado para desinstalar\n"

#: app/flatpak-builtins-uninstall.c:444
#, c-format
msgid "No installed refs found for ‘%s’"
msgstr "Nenhuma ref instalada localizada para “%s”"

#: app/flatpak-builtins-uninstall.c:447
#, c-format
msgid " with arch ‘%s’"
msgstr " com arquitetura “%s”"

#: app/flatpak-builtins-uninstall.c:449
#, c-format
msgid " with branch ‘%s’"
msgstr " com ramo “%s”"

#: app/flatpak-builtins-uninstall.c:456
#, c-format
msgid "Warning: %s is not installed\n"
msgstr "Aviso: %s não está instalado\n"

#: app/flatpak-builtins-uninstall.c:490
#, c-format
msgid "None of the specified refs are installed"
msgstr "Nenhuma das refs especificadas estão instaladas"

#: app/flatpak-builtins-uninstall.c:599
#, c-format
msgid "No app data to delete\n"
msgstr "Nenhum dado de aplicativo para excluir\n"

#: app/flatpak-builtins-update.c:56
msgid "Arch to update for"
msgstr "Arquitetura para a qual será atualizada"

#: app/flatpak-builtins-update.c:57
msgid "Commit to deploy"
msgstr "Commit para implementar"

#: app/flatpak-builtins-update.c:58
msgid "Remove old files even if running"
msgstr "Remove arquivos antigos ainda que estejam em execução"

#: app/flatpak-builtins-update.c:59
msgid "Don't pull, only update from local cache"
msgstr "Não faz pull, apenas atualiza do cache local"

#: app/flatpak-builtins-update.c:61
msgid "Don't update related refs"
msgstr "Não atualiza as refs relacionadas"

#: app/flatpak-builtins-update.c:66
msgid "Update appstream for remote"
msgstr "Atualiza appstream para remoto"

#: app/flatpak-builtins-update.c:67
msgid "Only update this subpath"
msgstr "Atualiza apenas este subcaminho"

#: app/flatpak-builtins-update.c:90
msgid "[REF…] - Update applications or runtimes"
msgstr "[REF…] – Atualiza aplicativos ou runtimes"

#: app/flatpak-builtins-update.c:121
msgid "With --commit, only one REF may be specified"
msgstr "Com --commit, apenas um REF pode ser especificado"

#: app/flatpak-builtins-update.c:162
#, c-format
msgid "Looking for updates…\n"
msgstr "Procurando por atualizações…\n"

#: app/flatpak-builtins-update.c:215
#, c-format
msgid "Unable to update %s: %s\n"
msgstr "Não foi possível atualizar %s: %s\n"

#: app/flatpak-builtins-update.c:274
#, fuzzy, c-format
msgid "Nothing to update.\n"
msgstr "Nada para fazer.\n"

#: app/flatpak-builtins-utils.c:337
#, c-format
msgid ""
"Remote ‘%s’ found in multiple installations, unable to proceed in non-"
"interactive mode"
msgstr ""
"Remoto “%s” localizado em várias instalações, não foi possível continuar no "
"modo não interativo"

#: app/flatpak-builtins-utils.c:346
#, c-format
msgid "Remote ‘%s’ found in multiple installations:"
msgstr "O remoto “%s” foi localizado em várias instalações:"

#: app/flatpak-builtins-utils.c:347 app/flatpak-builtins-utils.c:442
#: app/flatpak-builtins-utils.c:538 app/flatpak-builtins-utils.c:540
#: app/flatpak-builtins-utils.c:598
msgid "Which do you want to use (0 to abort)?"
msgstr "Qual você deseja usar (0 para abortar)?"

#: app/flatpak-builtins-utils.c:349
#, c-format
msgid "No remote chosen to resolve ‘%s’ which exists in multiple installations"
msgstr ""
"Nenhum remoto escolhido para resolver “%s” que existe em várias instalações"

#: app/flatpak-builtins-utils.c:358
#, c-format
msgid ""
"Remote \"%s\" not found\n"
"Hint: Use flatpak remote-add to add a remote"
msgstr ""
"Remoto “%s” não localizado\n"
"Dica: Use flatpak remote-add para adicionar um remoto"

#: app/flatpak-builtins-utils.c:364
#, c-format
msgid "Remote \"%s\" not found in the %s installation"
msgstr "Remoto “%s” não localizado na instalação %s"

#: app/flatpak-builtins-utils.c:404
#, c-format
msgid "Multiple refs match ‘%s’, unable to proceed in non-interactive mode"
msgstr ""
"Várias refs correspondem a “%s”, não foi possível continuar no modo não "
"interativo"

#. default to yes on Enter
#: app/flatpak-builtins-utils.c:430
#, c-format
msgid ""
"Found ref ‘%s’ in remote ‘%s’ (%s).\n"
"Use this ref?"
msgstr ""
"Localizada ref “%s” em remoto “%s” (%s).\n"
"Usar essa ref?"

#: app/flatpak-builtins-utils.c:434 app/flatpak-builtins-utils.c:444
#: app/flatpak-builtins-utils.c:522 app/flatpak-builtins-utils.c:543
#, c-format
msgid "No ref chosen to resolve matches for ‘%s’"
msgstr "Nenhuma ref escolhida para resolver ocorrências para “%s”"

#: app/flatpak-builtins-utils.c:440
#, c-format
msgid "Similar refs found for ‘%s’ in remote ‘%s’ (%s):"
msgstr "Refs similares localizadas para “%s” no remoto “%s” (%s):"

#: app/flatpak-builtins-utils.c:488
#, c-format
msgid ""
"Multiple installed refs match ‘%s’, unable to proceed in non-interactive mode"
msgstr ""
"Várias refs instaladas correspondem a “%s”, não foi possível continuar no "
"modo não interativo"

#. default to yes on Enter
#: app/flatpak-builtins-utils.c:518
#, c-format
msgid "Found installed ref ‘%s’ (%s). Is this correct?"
msgstr "Localizada ref instalada “%s” (%s). Isso está correto?"

#: app/flatpak-builtins-utils.c:534
#, c-format
msgid "All of the above"
msgstr "Todas acima"

#: app/flatpak-builtins-utils.c:535
#, c-format
msgid "Similar installed refs found for ‘%s’:"
msgstr "Refs instaladas similares localizadas para “%s”:"

#: app/flatpak-builtins-utils.c:579
#, c-format
msgid ""
"Multiple remotes have refs matching ‘%s’, unable to proceed in non-"
"interactive mode"
msgstr ""
"Vários remotos instalados correspondem a “%s”, não foi possível continuar no "
"modo não interativo"

#: app/flatpak-builtins-utils.c:597
#, c-format
msgid "Remotes found with refs similar to ‘%s’:"
msgstr "Remotos localizados com refs similares a “%s”:"

#: app/flatpak-builtins-utils.c:600
#, c-format
msgid "No remote chosen to resolve matches for ‘%s’"
msgstr "Nenhum remoto escolhido para resolver ocorrências para “%s”"

#: app/flatpak-builtins-utils.c:696 app/flatpak-builtins-utils.c:699
#, c-format
msgid "Updating appstream data for user remote %s"
msgstr "Atualizando dados de appstream para remoto %s de usuário"

#: app/flatpak-builtins-utils.c:706 app/flatpak-builtins-utils.c:709
#, c-format
msgid "Updating appstream data for remote %s"
msgstr "Atualizando dados de appstream para remoto %s"

#: app/flatpak-builtins-utils.c:717 app/flatpak-builtins-utils.c:719
msgid "Error updating"
msgstr "Erro ao atualizar"

#: app/flatpak-builtins-utils.c:755
#, c-format
msgid "Remote \"%s\" not found"
msgstr "Remoto “%s” não localizado"

#: app/flatpak-builtins-utils.c:796
#, c-format
msgid "Ambiguous suffix: '%s'."
msgstr "Sufixo ambíguo: “%s”."

#. Translators: don't translate the values
#: app/flatpak-builtins-utils.c:798 app/flatpak-builtins-utils.c:813
msgid "Possible values are :s[tart], :m[iddle], :e[nd] or :f[ull]"
msgstr "Valores possíveis são :s[tart], :m[iddle], :e[nd] or :f[ull]"

#: app/flatpak-builtins-utils.c:811
#, c-format
msgid "Invalid suffix: '%s'."
msgstr "Sufixo inválido: “%s”."

#: app/flatpak-builtins-utils.c:846
#, c-format
msgid "Ambiguous column: %s"
msgstr "Coluna ambígua: %s"

#: app/flatpak-builtins-utils.c:859
#, c-format
msgid "Unknown column: %s"
msgstr "Coluna desconhecida: %s"

#: app/flatpak-builtins-utils.c:917
msgid "Available columns:\n"
msgstr "Colunas disponíveis:\n"

#: app/flatpak-builtins-utils.c:927
msgid "Show all columns"
msgstr "Mostra todas as colunas"

#: app/flatpak-builtins-utils.c:928
msgid "Show available columns"
msgstr "Mostra colunas disponíveis"

#: app/flatpak-builtins-utils.c:931
msgid "Append :s[tart], :m[iddle], :e[nd] or :f[ull] to change ellipsization"
msgstr ""
"Anexe :s[tart], :m[iddle], :e[nd] or :f[ull] para alterar como reticências "
"são aplicadas"

#: app/flatpak-builtins-utils.c:1483
#, c-format
msgid "Unknown scheme in sideload location %s"
msgstr "Esquema desconhecido no download local para %s"

#: app/flatpak-cli-transaction.c:96 app/flatpak-cli-transaction.c:102
#, c-format
msgid "Required runtime for %s (%s) found in remote %s\n"
msgstr "Runtime exigido para %s (%s) localizado no remoto %s\n"

#: app/flatpak-cli-transaction.c:104
msgid "Do you want to install it?"
msgstr "Você deseja instalá-lo?"

#: app/flatpak-cli-transaction.c:110
#, c-format
msgid "Required runtime for %s (%s) found in remotes:"
msgstr "Runtime exigido para %s (%s) localizado em remotos:"

#: app/flatpak-cli-transaction.c:112
msgid "Which do you want to install (0 to abort)?"
msgstr "Qual você deseja instalar (0 para abortar)?"

#: app/flatpak-cli-transaction.c:132
#, c-format
msgid "Configuring %s as new remote '%s'\n"
msgstr "Configurando %s como novo remoto “%s”\n"

#. default to yes on Enter
#: app/flatpak-cli-transaction.c:139
#, c-format
msgid ""
"The remote '%s', referred to by '%s' at location %s contains additional "
"applications.\n"
"Should the remote be kept for future installations?"
msgstr ""
"O remoto “%s”, referido por “%s” na localização %s contém aplicativos "
"adicionais.\n"
"O remoto deve ser mantido para instalações futuras?"

#. default to yes on Enter
#: app/flatpak-cli-transaction.c:147
#, c-format
msgid ""
"The application %s depends on runtimes from:\n"
"  %s\n"
"Configure this as new remote '%s'"
msgstr ""
"Esse aplicativo %s depende de runtimes de:\n"
"  %s\n"
"Configure esse como o novo remoto “%s”"

#. Formatted size/remaining time in seconds
#: app/flatpak-cli-transaction.c:321
#, c-format
msgid "%s/s%s%s"
msgstr "%s/s%s%s"

#. Download progress percentage, use the appropriate
#. percent format for your language
#: app/flatpak-cli-transaction.c:359
#, c-format
msgid "%3d%%"
msgstr "%3d%%"

#: app/flatpak-cli-transaction.c:414
msgid "Installing…"
msgstr "Instalando…"

#: app/flatpak-cli-transaction.c:416
#, c-format
msgid "Installing %d/%d…"
msgstr "Instalando %d/%d…"

#: app/flatpak-cli-transaction.c:421
msgid "Updating…"
msgstr "Atualizando…"

#: app/flatpak-cli-transaction.c:423
#, c-format
msgid "Updating %d/%d…"
msgstr "Atualizando %d/%d…"

#: app/flatpak-cli-transaction.c:428
msgid "Uninstalling…"
msgstr "Desinstalando…"

#: app/flatpak-cli-transaction.c:430
#, c-format
msgid "Uninstalling %d/%d…"
msgstr "Desinstalando %d/%d…"

#: app/flatpak-cli-transaction.c:496 app/flatpak-quiet-transaction.c:161
#, c-format
msgid "Info: %s was skipped"
msgstr "Info: %s foi ignorado"

#: app/flatpak-cli-transaction.c:519
#, c-format
msgid "Warning: %s%s%s already installed"
msgstr "Aviso: %s%s%s já instalado"

#: app/flatpak-cli-transaction.c:522
#, c-format
msgid "Error: %s%s%s already installed"
msgstr "Erro: %s%s%s já instalado"

#: app/flatpak-cli-transaction.c:528
#, c-format
msgid "Warning: %s%s%s not installed"
msgstr "Aviso: %s%s%s não está instalado"

#: app/flatpak-cli-transaction.c:531
#, c-format
msgid "Error: %s%s%s not installed"
msgstr "Erro: %s%s%s não instalado"

#: app/flatpak-cli-transaction.c:537
#, c-format
msgid "Warning: %s%s%s needs a later flatpak version"
msgstr "Aviso: %s%s%s precisa de uma versão posterior do flatpak"

#: app/flatpak-cli-transaction.c:540
#, c-format
msgid "Error: %s%s%s needs a later flatpak version"
msgstr "Erro: %s%s%s precisa de uma versão posterior do flatpak"

#: app/flatpak-cli-transaction.c:546
msgid "Warning: Not enough disk space to complete this operation"
msgstr "Aviso: Espaço em disco insuficiente para completar essa operação"

#: app/flatpak-cli-transaction.c:548
msgid "Error: Not enough disk space to complete this operation"
msgstr "Erro: Espaço em disco insuficiente para completar essa operação"

#: app/flatpak-cli-transaction.c:553
#, c-format
msgid "Warning: %s"
msgstr "Aviso: %s"

#: app/flatpak-cli-transaction.c:555
#, c-format
msgid "Error: %s"
msgstr "Erro: %s"

#: app/flatpak-cli-transaction.c:570
#, c-format
msgid "Failed to install %s%s%s: "
msgstr "Falha ao instalar %s%s%s: "

#: app/flatpak-cli-transaction.c:577
#, c-format
msgid "Failed to update %s%s%s: "
msgstr "Falha ao atualizar %s%s%s: "

#: app/flatpak-cli-transaction.c:584
#, c-format
msgid "Failed to install bundle %s%s%s: "
msgstr "Falha ao instalar o pacote %s%s%s: "

#: app/flatpak-cli-transaction.c:591
#, c-format
msgid "Failed to uninstall %s%s%s: "
msgstr "Falha ao desinstalar %s%s%s: "

#: app/flatpak-cli-transaction.c:642
#, c-format
msgid "Authentication required for remote '%s'\n"
msgstr "Autenticação necessária para remoto “%s”\n"

#: app/flatpak-cli-transaction.c:643
msgid "Open browser?"
msgstr "Abrir navegador?"

#: app/flatpak-cli-transaction.c:699
#, c-format
msgid "Login required remote %s (realm %s)\n"
msgstr "A autenticação exigiu o remoto %s (domínio %s)\n"

#: app/flatpak-cli-transaction.c:704
msgid "Password"
msgstr "Senha"

#. Only runtimes can be pinned
#: app/flatpak-cli-transaction.c:759
#, c-format
msgid ""
"\n"
"Info: (pinned) runtime %s%s%s branch %s%s%s is end-of-life, in favor of "
"%s%s%s branch %s%s%s\n"
msgstr ""
"\n"
"Info: (fixado) o runtime %s%s%s ramo %s%s%s chegou ao fim de vida, em favor "
"de %s%s%s ramo %s%s%s\n"

#: app/flatpak-cli-transaction.c:765
#, c-format
msgid ""
"\n"
"Info: runtime %s%s%s branch %s%s%s is end-of-life, in favor of %s%s%s branch "
"%s%s%s\n"
msgstr ""
"\n"
"Info: o runtime %s%s%s ramo %s%s%s chegou ao fim de vida, em favor de %s%s%s "
"ramo %s%s%s\n"

#: app/flatpak-cli-transaction.c:768
#, c-format
msgid ""
"\n"
"Info: app %s%s%s branch %s%s%s is end-of-life, in favor of %s%s%s branch "
"%s%s%s\n"
msgstr ""
"\n"
"Info: o aplicativo %s%s%s ramo %s%s%s chegou ao fim de vida, em favor de "
"%s%s%s ramo %s%s%s\n"

#. Only runtimes can be pinned
#: app/flatpak-cli-transaction.c:780
#, c-format
msgid ""
"\n"
"Info: (pinned) runtime %s%s%s branch %s%s%s is end-of-life, with reason:\n"
msgstr ""
"\n"
"Info: (fixado) o runtime %s%s%s ramo %s%s%s chegou ao fim de vida, com "
"motivo:\n"

#: app/flatpak-cli-transaction.c:786
#, c-format
msgid ""
"\n"
"Info: runtime %s%s%s branch %s%s%s is end-of-life, with reason:\n"
msgstr ""
"\n"
"Info: o runtime %s%s%s ramo %s%s%s chegou ao fim de vida, com motivo:\n"

#: app/flatpak-cli-transaction.c:789
#, c-format
msgid ""
"\n"
"Info: app %s%s%s branch %s%s%s is end-of-life, with reason:\n"
msgstr ""
"\n"
"Info: o aplicativo %s%s%s ramo %s%s%s chegou ao fim de vida, com motivo:\n"

#: app/flatpak-cli-transaction.c:963
#, c-format
msgid "Info: applications using this extension:\n"
msgstr "Info: aplicativos que usam este runtime:\n"

#: app/flatpak-cli-transaction.c:965
#, c-format
msgid "Info: applications using this runtime:\n"
msgstr "Info: aplicativos que usam este runtime:\n"

#: app/flatpak-cli-transaction.c:984
msgid "Replace?"
msgstr "Substituir?"

#: app/flatpak-cli-transaction.c:987 app/flatpak-quiet-transaction.c:247
#, c-format
msgid "Updating to rebased version\n"
msgstr "Atualizando para a versão após rebase\n"

#: app/flatpak-cli-transaction.c:1011
#, c-format
msgid "Failed to rebase %s to %s: "
msgstr "Falha ao realizar rebase de %s para %s: "

#: app/flatpak-cli-transaction.c:1277
#, c-format
msgid "New %s%s%s permissions:"
msgstr "Novas permissões de %s%s%s:"

#: app/flatpak-cli-transaction.c:1279
#, c-format
msgid "%s%s%s permissions:"
msgstr "Permissões de %s%s%s:"

#: app/flatpak-cli-transaction.c:1343
msgid "Warning: "
msgstr "Aviso: "

#. translators: This is short for operation, the title of a one-char column
#: app/flatpak-cli-transaction.c:1442
msgid "Op"
msgstr "Op"

#. Avoid resizing the download column too much,
#. * by making the title as long as typical content
#.
#: app/flatpak-cli-transaction.c:1458 app/flatpak-cli-transaction.c:1503
msgid "partial"
msgstr "parcial"

#: app/flatpak-cli-transaction.c:1535
msgid "Proceed with these changes to the user installation?"
msgstr "Prosseguir com essas alterações para a instalação de usuário?"

#: app/flatpak-cli-transaction.c:1537
msgid "Proceed with these changes to the system installation?"
msgstr "Prosseguir com essas alterações para a instalação da sistema?"

#: app/flatpak-cli-transaction.c:1539
#, c-format
msgid "Proceed with these changes to the %s?"
msgstr "Prosseguir com essas alterações ao %s?"

#: app/flatpak-cli-transaction.c:1711
msgid "Changes complete."
msgstr "Alterações concluídas."

#: app/flatpak-cli-transaction.c:1713
msgid "Uninstall complete."
msgstr "Desinstalação concluída."

#: app/flatpak-cli-transaction.c:1715
msgid "Installation complete."
msgstr "Instalação concluída."

#: app/flatpak-cli-transaction.c:1717
msgid "Updates complete."
msgstr "Atualização concluída."

#. For updates/!stop_on_first_error we already printed all errors so we make up
#. a different one.
#: app/flatpak-cli-transaction.c:1750
msgid "There were one or more errors"
msgstr "Houve um ou mais erros"

#. translators: please keep the leading space
#: app/flatpak-main.c:76
msgid " Manage installed applications and runtimes"
msgstr " Gerência de aplicativos e runtimes instalados"

#: app/flatpak-main.c:77
msgid "Install an application or runtime"
msgstr "Instala um aplicativo ou runtime"

#: app/flatpak-main.c:78
msgid "Update an installed application or runtime"
msgstr "Atualiza um aplicativo ou runtime instalado"

#: app/flatpak-main.c:81
msgid "Uninstall an installed application or runtime"
msgstr "Desinstala um aplicativo ou runtime instalado"

#: app/flatpak-main.c:84
msgid "Mask out updates and automatic installation"
msgstr "Mascara atualizações e instalação automática"

#: app/flatpak-main.c:85
msgid "Pin a runtime to prevent automatic removal"
msgstr "Fixa um runtime para evitar remoção automática"

#: app/flatpak-main.c:86
msgid "List installed apps and/or runtimes"
msgstr "Lista aplicativos e/ou runtimes instalados"

#: app/flatpak-main.c:87
msgid "Show info for installed app or runtime"
msgstr "Mostra informações do aplicativo ou runtime instalado"

#: app/flatpak-main.c:88
msgid "Show history"
msgstr "Mostra histórico"

#: app/flatpak-main.c:89
msgid "Configure flatpak"
msgstr "Configura o flatpak"

#: app/flatpak-main.c:90
msgid "Repair flatpak installation"
msgstr "Corrige instalação do flatpak"

#: app/flatpak-main.c:91
msgid "Put applications or runtimes onto removable media"
msgstr "Coloca aplicativos ou runtimes em mídia removível"

#: app/flatpak-main.c:92
msgid "Install flatpaks that are part of the operating system"
msgstr "Instala flatpaks que são parte do sistema operacional"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:95
msgid ""
"\n"
" Find applications and runtimes"
msgstr ""
"\n"
" Localiza aplicativos e runtimes"

#: app/flatpak-main.c:96
msgid "Search for remote apps/runtimes"
msgstr "Pesquisa por aplicativos/runtimes de remoto"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:99
msgid ""
"\n"
" Manage running applications"
msgstr ""
"\n"
" Gerencia execução de aplicativos"

#: app/flatpak-main.c:100
msgid "Run an application"
msgstr "Executa um aplicativo"

#: app/flatpak-main.c:101
msgid "Override permissions for an application"
msgstr "Sobrepõe as permissões para um aplicativo"

#: app/flatpak-main.c:102
msgid "Specify default version to run"
msgstr "Especifica a versão padrão para executar"

#: app/flatpak-main.c:103
msgid "Enter the namespace of a running application"
msgstr "Insere o espaço de nome de um aplicativo em execução"

#: app/flatpak-main.c:104
msgid "Enumerate running applications"
msgstr "Enumera aplicativos em execução"

#: app/flatpak-main.c:105
msgid "Stop a running application"
msgstr "Termina um aplicativo em execução"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:108
msgid ""
"\n"
" Manage file access"
msgstr ""
"\n"
" Gerência de acesso a arquivos"

#: app/flatpak-main.c:109
msgid "List exported files"
msgstr "Lista arquivos exportados"

#: app/flatpak-main.c:110
msgid "Grant an application access to a specific file"
msgstr "Concede a um aplicativo acesso a um arquivo específico"

#: app/flatpak-main.c:111
msgid "Revoke access to a specific file"
msgstr "Revoga o acesso a um arquivo específico"

#: app/flatpak-main.c:112
msgid "Show information about a specific file"
msgstr "Mostra informações sobre um arquivo específico"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:116
msgid ""
"\n"
" Manage dynamic permissions"
msgstr ""
"\n"
" Mostra permissões dinâmicas"

#: app/flatpak-main.c:117
msgid "List permissions"
msgstr "Lista permissões"

#: app/flatpak-main.c:118
msgid "Remove item from permission store"
msgstr "Remove item para armazenamento de permissão"

#: app/flatpak-main.c:120
msgid "Set permissions"
msgstr "Define permissões"

#: app/flatpak-main.c:121
msgid "Show app permissions"
msgstr "Mostra permissões de aplicativo"

#: app/flatpak-main.c:122
msgid "Reset app permissions"
msgstr "Redefine permissões de aplicativo"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:125
msgid ""
"\n"
" Manage remote repositories"
msgstr ""
"\n"
" Gerência de repositórios remotos"

#: app/flatpak-main.c:126
msgid "List all configured remotes"
msgstr "Lista todos os remotos configurados"

#: app/flatpak-main.c:127
msgid "Add a new remote repository (by URL)"
msgstr "Adiciona um novo repositório remoto (via URL)"

#: app/flatpak-main.c:128
msgid "Modify properties of a configured remote"
msgstr "Modifica as propriedades de um remoto configurado"

#: app/flatpak-main.c:129
msgid "Delete a configured remote"
msgstr "Exclui um remoto configurado"

#: app/flatpak-main.c:131
msgid "List contents of a configured remote"
msgstr "Lista o conteúdo de um remoto configurado"

#: app/flatpak-main.c:132
msgid "Show information about a remote app or runtime"
msgstr "Mostra informações sobre um aplicativo ou runtime de remoto"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:135
msgid ""
"\n"
" Build applications"
msgstr ""
"\n"
" Compilação de aplicativos"

#: app/flatpak-main.c:136
msgid "Initialize a directory for building"
msgstr "Inicializa um diretório para compilação"

#: app/flatpak-main.c:137
msgid "Run a build command inside the build dir"
msgstr "Executa um comando de compilar dentro do diretório de compilação"

#: app/flatpak-main.c:138
msgid "Finish a build dir for export"
msgstr "Finaliza um diretório de compilação para exportar"

#: app/flatpak-main.c:139
msgid "Export a build dir to a repository"
msgstr "Exporta um diretório de compilação para um repositório"

#: app/flatpak-main.c:140
msgid "Create a bundle file from a ref in a local repository"
msgstr "Cria um arquivo de pacote a partir de um ref em um repositório local"

#: app/flatpak-main.c:141
msgid "Import a bundle file"
msgstr "Importa um arquivo de pacote"

#: app/flatpak-main.c:142
msgid "Sign an application or runtime"
msgstr "Assina um aplicativo ou runtime"

#: app/flatpak-main.c:143
msgid "Update the summary file in a repository"
msgstr "Atualiza o arquivo de sumário num repositório"

#: app/flatpak-main.c:144
msgid "Create new commit based on existing ref"
msgstr "Cria um novo commit baseado numa ref existente"

#: app/flatpak-main.c:145
msgid "Show information about a repo"
msgstr "Mostra informações sobre um repo"

#: app/flatpak-main.c:162
msgid "Show debug information, -vv for more detail"
msgstr "Mostra informações de depuração, -vv para mais detalhes"

#: app/flatpak-main.c:163
msgid "Show OSTree debug information"
msgstr "Mostra informações de depuração do OSTree"

#: app/flatpak-main.c:169
msgid "Print version information and exit"
msgstr "Exibe informações sobre a versão e sai"

#: app/flatpak-main.c:170
msgid "Print default arch and exit"
msgstr "Exibe a arquitetura padrão e sai"

#: app/flatpak-main.c:171
msgid "Print supported arches and exit"
msgstr "Exibe arquiteturas para as quais há suporte e sai"

#: app/flatpak-main.c:172
msgid "Print active gl drivers and exit"
msgstr "Exibe drivers gl ativos e sai"

#: app/flatpak-main.c:173
msgid "Print paths for system installations and exit"
msgstr "Exibe caminhos para instalações do sistema e sai"

#: app/flatpak-main.c:174
msgid "Print the updated environment needed to run flatpaks"
msgstr "Exibe o ambiente atualizado necessário para executar flatpaks"

#: app/flatpak-main.c:175
msgid "Only include the system installation with --print-updated-env"
msgstr "Inclui apenas a instalação do sistema com --print-updated-env"

#: app/flatpak-main.c:180
msgid "Work on the user installation"
msgstr "Trabalha na instalação do usuário"

#: app/flatpak-main.c:181
msgid "Work on the system-wide installation (default)"
msgstr "Trabalha na instalação do sistema (padrão)"

#: app/flatpak-main.c:182
msgid "Work on a non-default system-wide installation"
msgstr "Trabalha em uma instalação não padrão de sistema"

#: app/flatpak-main.c:212
msgid "Builtin Commands:"
msgstr "Comandos embutidos:"

#: app/flatpak-main.c:298
#, c-format
msgid ""
"Note that the directories %s are not in the search path set by the "
"XDG_DATA_DIRS environment variable, so applications installed by Flatpak may "
"not appear on your desktop until the session is restarted."
msgstr ""
"Note que os diretórios %s não estão no caminho de pesquisa definido pela "
"variável de ambiente XDG_DATA_DIRS, portanto, os aplicativos instalados pelo "
"Flatpak podem não aparecer em sua área de trabalho até que a sessão seja "
"reiniciada."

#: app/flatpak-main.c:312
#, c-format
msgid ""
"Note that the directory %s is not in the search path set by the "
"XDG_DATA_DIRS environment variable, so applications installed by Flatpak may "
"not appear on your desktop until the session is restarted."
msgstr ""
"Note que o diretório %s não está no caminho de pesquisa definido pela "
"variável de ambiente XDG_DATA_DIRS, portanto, os aplicativos instalados pelo "
"Flatpak podem não aparecer em sua área de trabalho até que a sessão seja "
"reiniciada."

#: app/flatpak-main.c:381
msgid ""
"Refusing to operate under sudo with --user. Omit sudo to operate on the user "
"installation, or use a root shell to operate on the root user's installation."
msgstr ""
"Recusando-se a operar com sudo do --usuário. Retire o sudo para operar na "
"instalação do usuário, ou use o shell como root para operar na instalação do "
"usuário-root."

#: app/flatpak-main.c:453
msgid ""
"Multiple installations specified for a command that works on one installation"
msgstr ""
"Várias instalações especificadas para um comando que trabalha em uma "
"instalação"

#: app/flatpak-main.c:504 app/flatpak-main.c:697
#, c-format
msgid "See '%s --help'"
msgstr "Veja “%s --help”"

#: app/flatpak-main.c:706
#, c-format
msgid "'%s' is not a flatpak command. Did you mean '%s%s'?"
msgstr "“%s” não é um comando do flatpak. Você quis dizer “%s%s”?"

#: app/flatpak-main.c:709
#, c-format
msgid "'%s' is not a flatpak command"
msgstr "“%s” não é um comando do flatpak"

#: app/flatpak-main.c:824
msgid "No command specified"
msgstr "Nenhum comando especificado"

#: app/flatpak-main.c:980
msgid "error:"
msgstr "erro:"

#: app/flatpak-quiet-transaction.c:77
#, c-format
msgid "Installing %s\n"
msgstr "Instalando %s\n"

#: app/flatpak-quiet-transaction.c:81
#, c-format
msgid "Updating %s\n"
msgstr "Atualizando %s\n"

#: app/flatpak-quiet-transaction.c:85
#, c-format
msgid "Uninstalling %s\n"
msgstr "Desinstalando %s\n"

#: app/flatpak-quiet-transaction.c:107
#, c-format
msgid "Warning: Failed to install %s: %s\n"
msgstr "Aviso: Falha ao instalar %s: %s\n"

#: app/flatpak-quiet-transaction.c:110
#, c-format
msgid "Error: Failed to install %s: %s\n"
msgstr "Erro: Falha ao instalar %s: %s\n"

#: app/flatpak-quiet-transaction.c:116
#, c-format
msgid "Warning: Failed to update %s: %s\n"
msgstr "Aviso: Falha ao atualizar %s: %s\n"

#: app/flatpak-quiet-transaction.c:119
#, c-format
msgid "Error: Failed to update %s: %s\n"
msgstr "Erro: Falha ao atualizar %s: %s\n"

#: app/flatpak-quiet-transaction.c:125
#, c-format
msgid "Warning: Failed to install bundle %s: %s\n"
msgstr "Aviso: Falha ao instalar o pacote %s: %s\n"

#: app/flatpak-quiet-transaction.c:128
#, c-format
msgid "Error: Failed to install bundle %s: %s\n"
msgstr "Erro: Falha ao instalar o pacote %s: %s\n"

#: app/flatpak-quiet-transaction.c:134
#, c-format
msgid "Warning: Failed to uninstall %s: %s\n"
msgstr "Aviso: Falha ao desinstalar %s: %s\n"

#: app/flatpak-quiet-transaction.c:137
#, c-format
msgid "Error: Failed to uninstall %s: %s\n"
msgstr "Erro: Falha ao desinstalar %s: %s\n"

#: app/flatpak-quiet-transaction.c:166 common/flatpak-dir.c:11475
#, c-format
msgid "%s already installed"
msgstr "%s já instalado"

#: app/flatpak-quiet-transaction.c:168 common/flatpak-dir.c:3622
#: common/flatpak-dir.c:4321 common/flatpak-dir.c:16968
#: common/flatpak-dir.c:17258 common/flatpak-dir-utils.c:166
#: common/flatpak-dir-utils.c:259 common/flatpak-transaction.c:2736
#: common/flatpak-transaction.c:2791
#, c-format
msgid "%s not installed"
msgstr "%s não instalado"

#: app/flatpak-quiet-transaction.c:170
#, c-format
msgid "%s needs a later flatpak version"
msgstr "%s precisa de uma versão posterior do flatpak"

#: app/flatpak-quiet-transaction.c:172
msgid "Not enough disk space to complete this operation"
msgstr "Espaço em disco insuficiente para completar essa operação"

#: app/flatpak-quiet-transaction.c:239
#, c-format
msgid "Info: %s is end-of-life, in favor of %s\n"
msgstr "Info: %s está em fim de vida, em favor de %s\n"

#: app/flatpak-quiet-transaction.c:241
#, c-format
msgid "Info: %s is end-of-life, with reason: %s\n"
msgstr "Info: %s está em fim de vida, com motivo: %s\n"

#: app/flatpak-quiet-transaction.c:251
#, c-format
msgid "Failed to rebase %s to %s: %s\n"
msgstr "Falha ao realizar rebase de %s para %s: %s\n"

#: common/flatpak-auth.c:58
#, c-format
msgid "No authenticator configured for remote `%s`"
msgstr "Nenhum autenticador configurador para remoto “%s”"

#: common/flatpak-context.c:637 common/flatpak-context.c:649
#, c-format
msgid "Invalid permission syntax: %s"
msgstr "Sintaxe de permissão inválida: %s"

#: common/flatpak-context.c:1207
#, c-format
msgid "Unknown share type %s, valid types are: %s"
msgstr "Tipo de compartilhamento desconhecido %s, tipos válidos são: %s"

#: common/flatpak-context.c:1228
#, c-format
msgid "Unknown policy type %s, valid types are: %s"
msgstr "Tipo de política desconhecida %s, tipos válidos são: %s"

#: common/flatpak-context.c:1266
#, c-format
msgid "Invalid dbus name %s"
msgstr "Nome de dbus inválido %s"

#: common/flatpak-context.c:1279
#, c-format
msgid "Unknown socket type %s, valid types are: %s"
msgstr "Tipo de soquete desconhecido %s, tipos válidos são: %s"

#: common/flatpak-context.c:1294
#, c-format
msgid "Unknown device type %s, valid types are: %s"
msgstr "Tipo de dispositivo desconhecido %s, tipos válidos são: %s"

#: common/flatpak-context.c:1308
#, c-format
msgid "Unknown feature type %s, valid types are: %s"
msgstr "Tipo de recurso desconhecido %s, tipos válidos são: %s"

#: common/flatpak-context.c:1840
#, c-format
msgid "Filesystem location \"%s\" contains \"..\""
msgstr "A localização do sistema de arquivos “%s” contém “..”"

#: common/flatpak-context.c:1882
#, c-format
msgid ""
"--filesystem=/ is not available, use --filesystem=host for a similar result"
msgstr ""
"--filesystem=/ não está disponível, use --filesystem=host para um resultado "
"similar"

#: common/flatpak-context.c:1916
#, c-format
msgid ""
"Unknown filesystem location %s, valid locations are: host, host-os, host-"
"etc, host-root, home, xdg-*[/…], ~/dir, /dir"
msgstr ""
"Localização de sistema de arquivos desconhecida %s, localizações válidas "
"são: host, host-os, host-etc, host-root, home, xdg-*[/…], ~/dir, /dir"

#: common/flatpak-context.c:2015
#, c-format
msgid "Invalid syntax for %s: %s"
msgstr "Sintaxe inválida para %s: %s"

#: common/flatpak-context.c:2142
#, c-format
msgid "fallback-x11 can not be conditional"
msgstr "fallback-x11 não pode ser condicional"

#: common/flatpak-context.c:2318
#, c-format
msgid "Invalid env format %s"
msgstr "Formato de env inválido %s"

#: common/flatpak-context.c:2399
#, c-format
msgid "Environment variable name must not contain '=': %s"
msgstr "O nome de variável de ambiente não pode conter “=”: %s"

#: common/flatpak-context.c:2527 common/flatpak-context.c:2535
#, c-format
msgid "--add-policy arguments must be in the form SUBSYSTEM.KEY=VALUE"
msgstr ""
"Os argumentos de --add-policy devem estar no formato SUBSISTEMA.CHAVE=VALOR"

#: common/flatpak-context.c:2542
#, c-format
msgid "--add-policy values can't start with \"!\""
msgstr "os valores de --add-policy não podem iniciar com “!”"

#: common/flatpak-context.c:2567 common/flatpak-context.c:2575
#, c-format
msgid "--remove-policy arguments must be in the form SUBSYSTEM.KEY=VALUE"
msgstr ""
"Os argumentos de --remove-policy devem estar no formato "
"SUBSISTEMA.CHAVE=VALOR"

#: common/flatpak-context.c:2582
#, c-format
msgid "--remove-policy values can't start with \"!\""
msgstr "Os valores de --remove-policy não podem iniciar com “!”"

#: common/flatpak-context.c:2657
msgid "Share with host"
msgstr "Compartilha com o host"

#: common/flatpak-context.c:2657 common/flatpak-context.c:2658
msgid "SHARE"
msgstr "COMPARTILHAMENTO"

#: common/flatpak-context.c:2658
msgid "Unshare with host"
msgstr "Desfaz compartilhamento com o host"

#: common/flatpak-context.c:2659
msgid "Require conditions to be met for a subsystem to get shared"
msgstr ""
"Exige que condições sejam atendidas para um subsistema ser compartilhado"

#: common/flatpak-context.c:2659
msgid "SHARE:CONDITION"
msgstr "COMPARTILHAMENTO:CONDIÇÃO"

#: common/flatpak-context.c:2660
msgid "Expose socket to app"
msgstr "Expõe o soquete para o aplicativo"

#: common/flatpak-context.c:2660 common/flatpak-context.c:2661
msgid "SOCKET"
msgstr "SOQUETE"

#: common/flatpak-context.c:2661
msgid "Don't expose socket to app"
msgstr "Não expõe o soquete para o aplicativo"

#: common/flatpak-context.c:2662
msgid "Require conditions to be met for a socket to get exposed"
msgstr "Exige que condições sejam atendidas para um soquete ser exposto"

#: common/flatpak-context.c:2662
msgid "SOCKET:CONDITION"
msgstr "SOQUETE:CONDIÇÃO"

#: common/flatpak-context.c:2663
msgid "Expose device to app"
msgstr "Expõe o dispositivo para o aplicativo"

#: common/flatpak-context.c:2663 common/flatpak-context.c:2664
msgid "DEVICE"
msgstr "DISPOSITIVO"

#: common/flatpak-context.c:2664
msgid "Don't expose device to app"
msgstr "Não expõe o dispositivo para o aplicativo"

#: common/flatpak-context.c:2665
msgid "Require conditions to be met for a device to get exposed"
msgstr "Exige que condições sejam atendidas para um dispositivo ser exposto"

#: common/flatpak-context.c:2665
msgid "DEVICE:CONDITION"
msgstr "DISPOSITIVO:CONDIÇÃO"

#: common/flatpak-context.c:2666
msgid "Allow feature"
msgstr "Permite a funcionalidade"

#: common/flatpak-context.c:2666 common/flatpak-context.c:2667
msgid "FEATURE"
msgstr "FUNCIONALIDADE"

#: common/flatpak-context.c:2667
msgid "Don't allow feature"
msgstr "Não permite funcionalidade"

#: common/flatpak-context.c:2668
msgid "Require conditions to be met for a feature to get allowed"
msgstr ""
"Exige que condições sejam atendidas para uma funcionalidade ser exposta"

#: common/flatpak-context.c:2668
msgid "FEATURE:CONDITION"
msgstr "FUNCIONALIDADE:CONDIÇÃO"

#: common/flatpak-context.c:2669
msgid "Expose filesystem to app (:ro for read-only)"
msgstr ""
"Expõe o sistema de arquivos para o aplicativo (:ro para somente leitura)"

#: common/flatpak-context.c:2669
msgid "FILESYSTEM[:ro]"
msgstr "SISTEMA_DE_ARQUIVOS[:ro]"

#: common/flatpak-context.c:2670
msgid "Don't expose filesystem to app"
msgstr "Não expõe o sistema de arquivos para o aplicativo"

#: common/flatpak-context.c:2670
msgid "FILESYSTEM"
msgstr "SISTEMA_DE_ARQUIVOS"

#: common/flatpak-context.c:2671
msgid "Set environment variable"
msgstr "Define uma variável de ambiente"

#: common/flatpak-context.c:2671
msgid "VAR=VALUE"
msgstr "VAR=VALOR"

#: common/flatpak-context.c:2672
msgid "Read environment variables in env -0 format from FD"
msgstr "Lê as variáveis de ambiente no formato env -0 do FD"

#: common/flatpak-context.c:2673
msgid "Remove variable from environment"
msgstr "Remove a variável do ambiente"

#: common/flatpak-context.c:2673
msgid "VAR"
msgstr "VAR"

#: common/flatpak-context.c:2674
msgid "Allow app to own name on the session bus"
msgstr "Permite o aplicativo ter um nome no barramento de sessão"

#: common/flatpak-context.c:2674 common/flatpak-context.c:2675
#: common/flatpak-context.c:2676 common/flatpak-context.c:2677
#: common/flatpak-context.c:2678 common/flatpak-context.c:2679
#: common/flatpak-context.c:2680
msgid "DBUS_NAME"
msgstr "NOME_DBUS"

#: common/flatpak-context.c:2675
msgid "Allow app to talk to name on the session bus"
msgstr "Permite o aplicativo falar com um nome no barramento de sessão"

#: common/flatpak-context.c:2676
msgid "Don't allow app to talk to name on the session bus"
msgstr "Proíbe o aplicativo de falar com um nome no barramento de sessão"

#: common/flatpak-context.c:2677
msgid "Allow app to own name on the system bus"
msgstr "Permite o aplicativo ter um nome no barramento de sistema"

#: common/flatpak-context.c:2678
msgid "Allow app to talk to name on the system bus"
msgstr "Permite o aplicativo falar com um nome no barramento de sistema"

#: common/flatpak-context.c:2679
msgid "Don't allow app to talk to name on the system bus"
msgstr "Proíbe o aplicativo de falar com um nome no barramento de sistema"

#: common/flatpak-context.c:2680
msgid "Allow app to own name on the a11y bus"
msgstr "Permite o aplicativo ter o nome no barramento a11y"

#: common/flatpak-context.c:2681
msgid "Add generic policy option"
msgstr "Adiciona uma opção de política genérica"

#: common/flatpak-context.c:2681 common/flatpak-context.c:2682
msgid "SUBSYSTEM.KEY=VALUE"
msgstr "SUBSISTEMA.CHAVE=VALOR"

#: common/flatpak-context.c:2682
msgid "Remove generic policy option"
msgstr "Remove uma opção de política genérica"

#: common/flatpak-context.c:2683
msgid "Add USB device to enumerables"
msgstr "Adiciona um dispositivo USB para enumeráveis"

#: common/flatpak-context.c:2683 common/flatpak-context.c:2684
msgid "VENDOR_ID:PRODUCT_ID"
msgstr "ID_FORNECEDOR:ID_PRODUTO"

#: common/flatpak-context.c:2684
msgid "Add USB device to hidden list"
msgstr "Adiciona um dispositivo USB para lista oculta"

#: common/flatpak-context.c:2685
msgid "A list of USB devices that are enumerable"
msgstr "Uma lista de dispositivos USB que são enumeráveis"

#: common/flatpak-context.c:2685
msgid "LIST"
msgstr "LISTA"

#: common/flatpak-context.c:2686
msgid "File containing a list of USB devices to make enumerable"
msgstr "Arquivo contendo uma lista de dispositivos USB para fazer enumeráveis"

#: common/flatpak-context.c:2686 common/flatpak-context.c:2687
msgid "FILENAME"
msgstr "ARQUIVO"

#: common/flatpak-context.c:2687
msgid "Persist home directory subpath"
msgstr "Persiste o subcaminho do diretório pessoal"

#. This is not needed/used anymore, so hidden, but we accept it for backwards compat
#: common/flatpak-context.c:2689
msgid "Don't require a running session (no cgroups creation)"
msgstr "Não exige uma sessão em execução (sem criação de cgroups)"

#: common/flatpak-context.c:3718
#, c-format
msgid "Not replacing \"%s\" with tmpfs: %s"
msgstr "Não será substituído “%s” por tmpfs: %s"

#: common/flatpak-context.c:3726
#, c-format
msgid "Not sharing \"%s\" with sandbox: %s"
msgstr "Não será compartilhado “%s” com caixa de proteção: %s"

#. Even if the error is one that we would normally silence, like
#. * the path not existing, it seems reasonable to make more of a fuss
#. * about the home directory not existing or otherwise being unusable,
#. * so this is intentionally not using cannot_export()
#: common/flatpak-context.c:3828
#, c-format
msgid "Not allowing home directory access: %s"
msgstr "Não será permitido acesso ao diretório pessoal: %s"

#: common/flatpak-context.c:4062
#, c-format
msgid "Unable to provide a temporary home directory in the sandbox: %s"
msgstr ""
"Não foi possível fornecer um diretório pessoal temporário no sandbox: %s"

#: common/flatpak-dir.c:442
#, c-format
msgid "Configured collection ID ‘%s’ not in summary file"
msgstr "O ID de coleção “%s” configurado não está no arquivo de resumo"

#: common/flatpak-dir.c:587
#, c-format
msgid "Unable to load summary from remote %s: %s"
msgstr "Não foi possível carregar resumo do remoto %s: %s"

#: common/flatpak-dir.c:764 common/flatpak-dir.c:800 common/flatpak-dir.c:906
#, c-format
msgid "No such ref '%s' in remote %s"
msgstr "Ref inexistente “%s” no remoto %s"

#: common/flatpak-dir.c:891 common/flatpak-dir.c:1051 common/flatpak-dir.c:1080
#: common/flatpak-dir.c:1092
#, c-format
msgid "No entry for %s in remote %s summary flatpak cache"
msgstr "Nenhuma entrada para %s no cache de flatpak do sumário do remoto %s"

#: common/flatpak-dir.c:1069
#, c-format
msgid "No summary or Flatpak cache available for remote %s"
msgstr "Nenhum sumário ou cache do Flatpak disponível para o remoto %s"

#: common/flatpak-dir.c:1097
#, c-format
msgid "Missing xa.data in summary for remote %s"
msgstr "Faltando xa.data no resumo para %s remoto"

#: common/flatpak-dir.c:1103 common/flatpak-dir.c:1546
#, c-format
msgid "Unsupported summary version %d for remote %s"
msgstr "Versão de resumo %d não suportada para %s remoto"

#: common/flatpak-dir.c:1200
msgid "Remote OCI index has no registry uri"
msgstr "Índice de OCI remoto tem nenhuma uri de registro"

#: common/flatpak-dir.c:1261
#, c-format
msgid "Couldn't find ref %s in remote %s"
msgstr "Não foi possível localizar a ref %s no remoto %s"

#: common/flatpak-dir.c:1288 common/flatpak-dir.c:1381
#, fuzzy, c-format
msgid "Commit has no requested ref ‘%s’ in ref binding metadata (found: ‘%s’)"
msgstr ""
"O commit não tem solicitação de ref “%s” nos metadados de associação de ref"

#: common/flatpak-dir.c:1413
#, c-format
msgid "Configured collection ID ‘%s’ not in binding metadata"
msgstr "O ID de coleção “%s” configurado não está nos metadados de associação"

#: common/flatpak-dir.c:1449 common/flatpak-dir.c:5645
#, c-format
msgid "Couldn't find latest checksum for ref %s in remote %s"
msgstr ""
"Não foi possível localizar a última soma de verificação para a ref %s no "
"remoto %s"

#: common/flatpak-dir.c:1516 common/flatpak-dir.c:1552
#, c-format
msgid "No entry for %s in remote %s summary flatpak sparse cache"
msgstr ""
"Nenhuma entrada para %s no cache esparso de flatpak do resumo do remoto %s"

#: common/flatpak-dir.c:2540
#, c-format
msgid "Commit metadata for %s not matching expected metadata"
msgstr "Metadados do commit para %s não correspondem aos metadados esperados"

#: common/flatpak-dir.c:2823
msgid "Unable to connect to system bus"
msgstr "Não foi possível conectar ao barramento de sistema"

#: common/flatpak-dir.c:3419
msgid "User installation"
msgstr "Instalação do usuário"

#: common/flatpak-dir.c:3426
#, c-format
msgid "System (%s) installation"
msgstr "Instalação do sistema (%s)"

#: common/flatpak-dir.c:3472
#, c-format
msgid "No overrides found for %s"
msgstr "Nenhuma substituição localizada para %s"

#: common/flatpak-dir.c:3625
#, c-format
msgid "%s (commit %s) not installed"
msgstr "%s (commit %s) não instalado"

#: common/flatpak-dir.c:4650
#, c-format
msgid "Error parsing system flatpakrepo file for %s: %s"
msgstr "Erro ao analisar o arquivo de flatpakrepo de sistema para %s: %s"

#: common/flatpak-dir.c:4735
#, c-format
msgid "While opening repository %s: "
msgstr "Ao abrir o repositório %s: "

#: common/flatpak-dir.c:5004
#, c-format
msgid "The config key %s is not set"
msgstr "A chave de configuração %s não está definida"

#: common/flatpak-dir.c:5140
#, c-format
msgid "No current %s pattern matching %s"
msgstr "Nenhum padrão %s atual correspondendo a %s"

#: common/flatpak-dir.c:5422
msgid "No appstream commit to deploy"
msgstr "Nenhum commit de appstream para implementar"

#: common/flatpak-dir.c:5941 common/flatpak-dir.c:7266
#: common/flatpak-dir.c:10881 common/flatpak-dir.c:11618
msgid "Can't pull from untrusted non-gpg verified remote"
msgstr "Não foi possível obter de remoto sem gpg verificada e não confiado"

#: common/flatpak-dir.c:6376 common/flatpak-dir.c:6591
msgid "Extra data not supported for non-gpg-verified local system installs"
msgstr ""
"Sem suporte a dados extras para instalações de sistema local sem gpg "
"verificada"

#: common/flatpak-dir.c:6415 common/flatpak-dir.c:6782
#, c-format
msgid "Invalid checksum for extra data uri %s"
msgstr "Soma de verificação inválida para uri dados extras %s"

#: common/flatpak-dir.c:6424
#, c-format
msgid "Empty name for extra data uri %s"
msgstr "Nome vazio para uri de dados extras %s"

#: common/flatpak-dir.c:6432
#, c-format
msgid "Unsupported extra data uri %s"
msgstr "Sem suporte à uri de dados extras %s"

#: common/flatpak-dir.c:6461
#, c-format
msgid "Failed to load local extra-data %s: %s"
msgstr "Falha ao carregar extra-data local %s: %s"

#: common/flatpak-dir.c:6469
#, c-format
msgid "Wrong size for extra-data %s"
msgstr "Tamanho inválido para extra-data %s"

#: common/flatpak-dir.c:6488
#, c-format
msgid "While downloading %s: "
msgstr "Enquanto baixava %s: "

#: common/flatpak-dir.c:6498
#, c-format
msgid "Wrong size for extra data %s"
msgstr "Tamanho inválido para dados extras %s"

#: common/flatpak-dir.c:6507
#, c-format
msgid "Invalid checksum for extra data %s"
msgstr "Soma de verificação inválida para dados extras %s"

#: common/flatpak-dir.c:7096 common/flatpak-dir.c:7349
#, c-format
msgid "While pulling %s from remote %s: "
msgstr "Enquanto executava pull de %s a partir do remoto %s: "

#: common/flatpak-dir.c:7290 common/flatpak-repo-utils.c:3886
msgid "GPG signatures found, but none are in trusted keyring"
msgstr "Assinaturas GPG localizadas, mas nenhuma está no chaveiro de confiadas"

#: common/flatpak-dir.c:7307
#, c-format
msgid "Commit for ‘%s’ has no ref binding"
msgstr "O commit para “%s” tem nenhuma associação de ref"

#: common/flatpak-dir.c:7312
#, c-format
msgid "Commit for ‘%s’ is not in expected bound refs: %s"
msgstr "O commit para “%s” não está nas refs limites esperados: %s"

#: common/flatpak-dir.c:7488
msgid "Only applications can be made current"
msgstr "Apenas aplicativos podem ser atualizados"

#: common/flatpak-dir.c:8192
msgid "Not enough memory"
msgstr "Memória insuficiente"

#: common/flatpak-dir.c:8211
msgid "Failed to read from exported file"
msgstr "Falha ao ler do arquivo exportado"

#: common/flatpak-dir.c:8401
msgid "Error reading mimetype xml file"
msgstr "Erro ao ler o arquivo xml de tipo mime"

#: common/flatpak-dir.c:8406
msgid "Invalid mimetype xml file"
msgstr "Arquivo inválido de xml de tipo mim"

#: common/flatpak-dir.c:8492
#, c-format
msgid "D-Bus service file '%s' has wrong name"
msgstr "O arquivo de serviço D-Bus “%s” tem um nome errado"

#: common/flatpak-dir.c:8647
#, c-format
msgid "Invalid Exec argument %s"
msgstr "Exec com argumento inválido %s"

#: common/flatpak-dir.c:9115
msgid "While getting detached metadata: "
msgstr "Enquanto obtinha metadados destacados: "

#: common/flatpak-dir.c:9120 common/flatpak-dir.c:9125
#: common/flatpak-dir.c:9129
msgid "Extra data missing in detached metadata"
msgstr "Dados extras faltando nos metadados destacados"

#: common/flatpak-dir.c:9133
msgid "While creating extradir: "
msgstr "Enquanto criava extradir: "

#: common/flatpak-dir.c:9154 common/flatpak-dir.c:9187
msgid "Invalid checksum for extra data"
msgstr "Soma de verificação inválida para dados extras"

#: common/flatpak-dir.c:9183
msgid "Wrong size for extra data"
msgstr "Tamanho inválido para dados extras"

#: common/flatpak-dir.c:9196
#, c-format
msgid "While writing extra data file '%s': "
msgstr "Enquanto escrevia o arquivo de dados extras “%s”: "

#: common/flatpak-dir.c:9204
#, c-format
msgid "Extra data %s missing in detached metadata"
msgstr "Dados extras %s faltando nos metadados destacados"

#: common/flatpak-dir.c:9278
#, c-format
msgid "Unable to get runtime key from metadata"
msgstr "Não foi possível obter a chave da runtime pelos metadados"

#: common/flatpak-dir.c:9402
#, c-format
msgid "apply_extra script failed, exit status %d"
msgstr "script apply_extra falhou, status de saída %d"

#. Translators: The placeholder is for an app ref.
#: common/flatpak-dir.c:9591
#, c-format
msgid "Installing %s is not allowed by the policy set by your administrator"
msgstr "Instalar %s não é permitido pela política definida pelo administrador"

#: common/flatpak-dir.c:9690
#, c-format
msgid "While trying to resolve ref %s: "
msgstr "Enquanto tentava resolver ref %s: "

#: common/flatpak-dir.c:9702
#, c-format
msgid "%s is not available"
msgstr "%s não está disponível"

#: common/flatpak-dir.c:9714 common/flatpak-dir.c:11495
#, c-format
msgid "%s commit %s already installed"
msgstr "%s commit %s já está instalado"

#: common/flatpak-dir.c:9721
msgid "Can't create deploy directory"
msgstr "Não foi possível criar um diretório de deploy"

#: common/flatpak-dir.c:9729
#, c-format
msgid "Failed to read commit %s: "
msgstr "Falha ao ler commit %s: "

#: common/flatpak-dir.c:9750
#, c-format
msgid "While trying to checkout %s into %s: "
msgstr "Enquanto tentava fazer checkout de %s para %s: "

#: common/flatpak-dir.c:9769
msgid "While trying to checkout metadata subpath: "
msgstr "Enquanto tentava fazer checkout do subcaminho de metadados: "

#: common/flatpak-dir.c:9801
#, c-format
msgid "While trying to checkout subpath ‘%s’: "
msgstr "Enquanto tentava fazer checkout do subcaminho “%s”: "

#: common/flatpak-dir.c:9811
msgid "While trying to remove existing extra dir: "
msgstr "Enquanto tentava remover diretório extra existente: "

#: common/flatpak-dir.c:9822
msgid "While trying to apply extra data: "
msgstr "Enquanto tentava aplicar dados extras: "

#: common/flatpak-dir.c:9849
#, c-format
msgid "Invalid commit ref %s: "
msgstr "Ref de commit inválido %s: "

#: common/flatpak-dir.c:9857 common/flatpak-dir.c:9869
#, c-format
msgid "Deployed ref %s does not match commit (%s)"
msgstr "Ref implementado %s não coincide com o commit (%s)"

#: common/flatpak-dir.c:9863
#, c-format
msgid "Deployed ref %s branch does not match commit (%s)"
msgstr "O ramo da ref implementado %s não coincide com o commit (%s)"

#: common/flatpak-dir.c:10125 common/flatpak-installation.c:1911
#, c-format
msgid "%s branch %s already installed"
msgstr "%s ramo %s já está instalado"

#: common/flatpak-dir.c:10985
#, c-format
msgid "Could not unmount revokefs-fuse filesystem at %s: "
msgstr "Não foi possível desmontar o sistema de arquivos revokefs-fuse em %s: "

#: common/flatpak-dir.c:11289
#, c-format
msgid "This version of %s is already installed"
msgstr "Essa versão de %s já está instalada"

#: common/flatpak-dir.c:11302
#, c-format
msgid "Can't change remote during bundle install"
msgstr "Não é possível alterar remoto durante instalação de pacote"

#: common/flatpak-dir.c:11571
msgid "Can't update to a specific commit without root permissions"
msgstr ""
"Não é possível atualizar para um commit específico sem permissões de root"

#: common/flatpak-dir.c:11852
#, c-format
msgid "Can't remove %s, it is needed for: %s"
msgstr "Não foi possível remover %s, pois é necessário para: %s"

#: common/flatpak-dir.c:11912 common/flatpak-installation.c:2067
#, c-format
msgid "%s branch %s is not installed"
msgstr "%s ramo %s não está instalado"

#: common/flatpak-dir.c:12165
#, c-format
msgid "%s commit %s not installed"
msgstr "%s commit %s não instalado"

#: common/flatpak-dir.c:12501
#, c-format
msgid "Pruning repo failed: %s"
msgstr "A supressão de repositório falhou: %s"

#: common/flatpak-dir.c:12669 common/flatpak-dir.c:12675
#, c-format
msgid "Failed to load filter '%s'"
msgstr "Falha ao carregar o filtro “%s”"

#: common/flatpak-dir.c:12681
#, c-format
msgid "Failed to parse filter '%s'"
msgstr "Falha ao analisar o filtro “%s”"

#: common/flatpak-dir.c:12963
msgid "Failed to write summary cache: "
msgstr "Falha ao escrever cache de resumo: "

#: common/flatpak-dir.c:12982
#, c-format
msgid "No oci summary cached for remote '%s'"
msgstr "Nenhum resumo de oci em cache para o remoto “%s”"

#: common/flatpak-dir.c:13207
#, c-format
msgid "No cached summary for remote '%s'"
msgstr "Nenhum resumo em cache para “%s” remoto"

#: common/flatpak-dir.c:13248
#, c-format
msgid "Invalid checksum for indexed summary %s read from %s"
msgstr "Soma de verificação inválida para resumo indexado %s lido de %s"

#: common/flatpak-dir.c:13321
#, c-format
msgid ""
"Remote listing for %s not available; server has no summary file. Check the "
"URL passed to remote-add was valid."
msgstr ""
"Listagem de remoto para %s não disponível; o servidor não tem arquivo de "
"resumo. Certifique-se que a URL passada para remote-add é válida."

#: common/flatpak-dir.c:13698
#, c-format
msgid "Invalid checksum for indexed summary %s for remote '%s'"
msgstr "Soma de verificação inválida para resumo indexado %s para “%s” remoto"

#: common/flatpak-dir.c:14388
#, c-format
msgid "Multiple branches available for %s, you must specify one of: "
msgstr "Vários ramos disponíveis para %s, você deve especificar uma entre: "

#: common/flatpak-dir.c:14454
#, c-format
msgid "Nothing matches %s"
msgstr "Sem combinações com %s"

#: common/flatpak-dir.c:14562
#, c-format
msgid "Can't find ref %s%s%s%s%s"
msgstr "Não foi possível localizar ref %s%s%s%s%s"

#: common/flatpak-dir.c:14605
#, c-format
msgid "Error searching remote %s: %s"
msgstr "Erro ao pesquisar remoto %s: %s"

#: common/flatpak-dir.c:14702
#, c-format
msgid "Error searching local repository: %s"
msgstr "Erro ao pesquisar repositório local: %s"

#: common/flatpak-dir.c:14839
#, c-format
msgid "%s/%s/%s not installed"
msgstr "%s/%s/%s não instalado"

#: common/flatpak-dir.c:15042
#, c-format
msgid "Could not find installation %s"
msgstr "Não foi possível localizar instalação de %s"

#: common/flatpak-dir.c:15612
#, c-format
msgid "Invalid file format, no %s group"
msgstr "Formato de arquivo inválido, grupo %s inexistente"

#: common/flatpak-dir.c:15617 common/flatpak-repo-utils.c:2836
#, c-format
msgid "Invalid version %s, only 1 supported"
msgstr "Versão inválida %s, há suporte apenas a 1"

#: common/flatpak-dir.c:15622 common/flatpak-dir.c:15627
#, c-format
msgid "Invalid file format, no %s specified"
msgstr "Formato de arquivo inválido, nenhuma %s especificada"

#. Check some minimal size so we don't get crap
#: common/flatpak-dir.c:15647
msgid "Invalid file format, gpg key invalid"
msgstr "Formato de arquivo inválido, chave gpg inválida"

#: common/flatpak-dir.c:15675 common/flatpak-repo-utils.c:2917
msgid "Collection ID requires GPG key to be provided"
msgstr "ID de coleção requer que a chave GPG seja fornecida"

#: common/flatpak-dir.c:15718
#, c-format
msgid "Runtime %s, branch %s is already installed"
msgstr "Runtime %s, ramo %s já está instalado"

#: common/flatpak-dir.c:15719
#, c-format
msgid "App %s, branch %s is already installed"
msgstr "Aplicativo %s, ramo %s já está instalado"

#: common/flatpak-dir.c:15953
#, c-format
msgid "Can't remove remote '%s' with installed ref %s (at least)"
msgstr ""
"Não é possível remover o remoto “%s” com a ref %s instalada (pelo menos)"

#: common/flatpak-dir.c:16058
#, c-format
msgid "Invalid character '/' in remote name: %s"
msgstr "Caractere inválido “/” no nome do remoto: %s"

#: common/flatpak-dir.c:16064
#, c-format
msgid "No configuration for remote %s specified"
msgstr "Nenhuma configuração para o remoto %s especificado"

#: common/flatpak-dir.c:17597
#, c-format
msgid "Skipping deletion of mirror ref (%s, %s)…\n"
msgstr "Ignorando exclusão de ref espelho (%s, %s)…\n"

#: common/flatpak-exports.c:931
#, c-format
msgid "An absolute path is required"
msgstr "Um caminho absoluto é exigido"

#: common/flatpak-exports.c:948
#, c-format
msgid "Unable to open path \"%s\": %s"
msgstr "Não foi possível abrir o caminho “%s”: %s"

#: common/flatpak-exports.c:955
#, c-format
msgid "Unable to get file type of \"%s\": %s"
msgstr "Não foi possível obter o tipo de arquivo de “%s”: %s"

#: common/flatpak-exports.c:964
#, c-format
msgid "File \"%s\" has unsupported type 0o%o"
msgstr "O aplicativo “%s” tem o tipo não suportado 0o%o"

#: common/flatpak-exports.c:970
#, c-format
msgid "Unable to get filesystem information for \"%s\": %s"
msgstr ""
"Não foi possível obter as informações de sistema de arquivos para “%s”: %s"

#: common/flatpak-exports.c:980
#, c-format
msgid "Ignoring blocking autofs path \"%s\""
msgstr "Ignorando o bloqueio do caminho de autofs “%s”"

#: common/flatpak-exports.c:996 common/flatpak-exports.c:1009
#: common/flatpak-exports.c:1022
#, c-format
msgid "Path \"%s\" is reserved by Flatpak"
msgstr "O caminho \"%s\" está reservado pelo Flatpak"

#: common/flatpak-exports.c:1076
#, c-format
msgid "Unable to resolve symbolic link \"%s\": %s"
msgstr "Não foi possível resolver o link simbólico “%s”: %s"

#: common/flatpak-glib-backports.c:69
msgid "Empty string is not a number"
msgstr "A string vazia não é um número"

#: common/flatpak-glib-backports.c:95
#, c-format
msgid "“%s” is not an unsigned number"
msgstr "“%s” não é um número não assinado"

#: common/flatpak-glib-backports.c:105
#, c-format
msgid "Number “%s” is out of bounds [%s, %s]"
msgstr "O número “%s” está fora dos limites [%s, %s]"

#: common/flatpak-image-source.c:83
msgid "Only sha256 image checksums are supported"
msgstr "Somente somas de verificação de imagens sha256 são suportadas"

#: common/flatpak-image-source.c:100 common/flatpak-image-source.c:108
msgid "Image is not a manifest"
msgstr "A imagem não é um manifesto"

#: common/flatpak-image-source.c:123
msgid "No org.flatpak.ref found in image"
msgstr "Nenhum org.flatpak.ref localizado na imagem"

#: common/flatpak-image-source.c:148
#, c-format
msgid "Ref '%s' not found in registry"
msgstr "Ref “%s” não localizado no registro"

#: common/flatpak-image-source.c:157
msgid "Multiple images in registry, specify a ref with --ref"
msgstr "Várias imagens no registro, especifique uma ref com --ref"

#: common/flatpak-installation.c:834
#, c-format
msgid "Ref %s not installed"
msgstr "Ref %s não instalado"

#: common/flatpak-installation.c:875
#, c-format
msgid "App %s not installed"
msgstr "Aplicativo %s não instalado"

#: common/flatpak-installation.c:1395
#, c-format
msgid "Remote '%s' already exists"
msgstr "O remoto “%s” já existe"

#: common/flatpak-installation.c:1946
#, c-format
msgid "As requested, %s was only pulled, but not installed"
msgstr "Conforme requisitado, %s foi obtida, mas não instalada"

#: common/flatpak-instance.c:533 common/flatpak-instance.c:687
#: common/flatpak-instance.c:728
#, c-format
msgid "Unable to create directory %s"
msgstr "Não foi possível criar um diretório %s"

#: common/flatpak-instance.c:554
#, c-format
msgid "Unable to lock %s"
msgstr "Não foi possível travar %s"

#: common/flatpak-instance.c:627
#, c-format
msgid "Unable to create temporary directory in %s"
msgstr "Não foi possível criar um diretório temporário em %s"

#: common/flatpak-instance.c:639
#, c-format
msgid "Unable to create file %s"
msgstr "Não foi possível criar o arquivo %s"

#: common/flatpak-instance.c:646
#, c-format
msgid "Unable to update symbolic link %s/%s"
msgstr "Não foi possível atualizar o link simbólico %s/%s"

#: common/flatpak-oci-registry.c:1197
msgid "Only Bearer authentication supported"
msgstr "Há suporte apenas à autenticação via token (Bearer)"

#: common/flatpak-oci-registry.c:1206
msgid "Only realm in authentication request"
msgstr "Apenas reino na solicitação de autenticação"

#: common/flatpak-oci-registry.c:1213
msgid "Invalid realm in authentication request"
msgstr "Reino inválido na solicitação de autenticação"

#: common/flatpak-oci-registry.c:1283
#, c-format
msgid "Authorization failed: %s"
msgstr "Autorização falhou: %s"

#: common/flatpak-oci-registry.c:1285
msgid "Authorization failed"
msgstr "Autorização falhou"

#: common/flatpak-oci-registry.c:1289
#, c-format
msgid "Unexpected response status %d when requesting token: %s"
msgstr "Status de resposta inesperada %d ao solicitar token: %s"

#: common/flatpak-oci-registry.c:1300
msgid "Invalid authentication request response"
msgstr "Resposta inválida à solicitação de autenticação"

#: common/flatpak-oci-registry.c:1731
#, c-format
msgid "Flatpak was compiled without zstd support"
msgstr "Flatpak foi compilado sem suporte a zstd"

#: common/flatpak-oci-registry.c:1923 common/flatpak-oci-registry.c:1975
#: common/flatpak-oci-registry.c:2004 common/flatpak-oci-registry.c:2059
#: common/flatpak-oci-registry.c:2115 common/flatpak-oci-registry.c:2193
msgid "Invalid delta file format"
msgstr "Formato de arquivo delta inválido"

#: common/flatpak-oci-registry.c:3198 common/flatpak-oci-registry.c:3382
msgid "Invalid OCI image config"
msgstr "Configuração de imagem OCI inválida"

#: common/flatpak-oci-registry.c:3260 common/flatpak-oci-registry.c:3531
#, c-format
msgid "Wrong layer checksum, expected %s, was %s"
msgstr "Soma de verificação de camada errada, esperava %s, era %s"

#: common/flatpak-oci-registry.c:3359
#, c-format
msgid "No ref specified for OCI image %s"
msgstr "Nenhuma ref especificada para a imagem OCI %s"

#: common/flatpak-oci-registry.c:3369
#, c-format
msgid "Wrong ref (%s) specified for OCI image %s, expected %s"
msgstr "Ref errada (%s) especificada para a imagem OCI %s, esperava %s"

#: common/flatpak-progress.c:236
#, c-format
msgid "Downloading metadata: %u/(estimating) %s"
msgstr "Baixando metadados: %u/(estimando) %s"

#: common/flatpak-progress.c:260
#, c-format
msgid "Downloading: %s/%s"
msgstr "Baixando: %s/%s"

#: common/flatpak-progress.c:280
#, c-format
msgid "Downloading extra data: %s/%s"
msgstr "Baixando dados extras: %s/%s"

#: common/flatpak-progress.c:285
#, c-format
msgid "Downloading files: %d/%d %s"
msgstr "Baixando arquivos: %d/%d %s"

#: common/flatpak-ref-utils.c:122
msgid "Name can't be empty"
msgstr "Nome não pode estar vazio"

#: common/flatpak-ref-utils.c:129
msgid "Name can't be longer than 255 characters"
msgstr "Nome não pode ser maior que 255 caracteres"

#: common/flatpak-ref-utils.c:142
msgid "Name can't start with a period"
msgstr "Nome não pode iniciar com um ponto"

#: common/flatpak-ref-utils.c:148
#, c-format
msgid "Name can't start with %c"
msgstr "Nome não pode iniciar com %c"

#: common/flatpak-ref-utils.c:164
msgid "Name can't end with a period"
msgstr "Nome não pode terminar com um ponto"

#: common/flatpak-ref-utils.c:171 common/flatpak-ref-utils.c:183
msgid "Only last name segment can contain -"
msgstr "Apenas o último segmento de nome pode conter -"

#: common/flatpak-ref-utils.c:174
#, c-format
msgid "Name segment can't start with %c"
msgstr "Segmento de nome não pode iniciar com %c"

#: common/flatpak-ref-utils.c:186
#, c-format
msgid "Name can't contain %c"
msgstr "Nome não pode conter %c"

#: common/flatpak-ref-utils.c:195
msgid "Names must contain at least 2 periods"
msgstr "Nome deve conter pelo menos 2 pontos"

#: common/flatpak-ref-utils.c:312
msgid "Arch can't be empty"
msgstr "A arq. não pode estar vazia"

#: common/flatpak-ref-utils.c:323
#, c-format
msgid "Arch can't contain %c"
msgstr "A arq. não pode conter %c"

#: common/flatpak-ref-utils.c:385
msgid "Branch can't be empty"
msgstr "Ramos não podem estar vazios"

#: common/flatpak-ref-utils.c:395
#, c-format
msgid "Branch can't start with %c"
msgstr "Ramos não podem iniciar com %c"

#: common/flatpak-ref-utils.c:405
#, c-format
msgid "Branch can't contain %c"
msgstr "Ramos não podem conter %c"

#: common/flatpak-ref-utils.c:615 common/flatpak-ref-utils.c:865
msgid "Ref too long"
msgstr "Ref muito longa"

#: common/flatpak-ref-utils.c:627
msgid "Invalid remote name"
msgstr "Nome remoto inválido"

#: common/flatpak-ref-utils.c:641
#, c-format
msgid "%s is not application or runtime"
msgstr "%s não é um aplicativo ou runtime"

#: common/flatpak-ref-utils.c:650 common/flatpak-ref-utils.c:667
#: common/flatpak-ref-utils.c:683
#, c-format
msgid "Wrong number of components in %s"
msgstr "Número incorreto de componentes em %s"

#: common/flatpak-ref-utils.c:656
#, c-format
msgid "Invalid name %.*s: %s"
msgstr "Nome inválido %.*s: %s"

#: common/flatpak-ref-utils.c:673
#, c-format
msgid "Invalid arch: %.*s: %s"
msgstr "Arq. inválida: %.*s: %s"

#: common/flatpak-ref-utils.c:816
#, c-format
msgid "Invalid name %s: %s"
msgstr "Nome inválido %s: %s"

#: common/flatpak-ref-utils.c:834
#, c-format
msgid "Invalid arch: %s: %s"
msgstr "Arq. inválida: %s: %s"

#: common/flatpak-ref-utils.c:853
#, c-format
msgid "Invalid branch: %s: %s"
msgstr "Ramo inválido: %s: %s"

#: common/flatpak-ref-utils.c:962 common/flatpak-ref-utils.c:970
#: common/flatpak-ref-utils.c:978
#, c-format
msgid "Wrong number of components in partial ref %s"
msgstr "Número incorreto de componentes na ref parcial %s"

#: common/flatpak-ref-utils.c:1298
msgid " development platform"
msgstr " plataforma de desenvolvimento"

#: common/flatpak-ref-utils.c:1300
msgid " platform"
msgstr " plataforma"

#: common/flatpak-ref-utils.c:1302
msgid " application base"
msgstr " base de aplicação"

#: common/flatpak-ref-utils.c:1305
msgid " debug symbols"
msgstr " símbolos de depuração"

#: common/flatpak-ref-utils.c:1307
msgid " sourcecode"
msgstr " código-fonte"

#: common/flatpak-ref-utils.c:1309
msgid " translations"
msgstr " traduções"

#: common/flatpak-ref-utils.c:1311
msgid " docs"
msgstr " docs"

#: common/flatpak-ref-utils.c:1578
#, c-format
msgid "Invalid id %s: %s"
msgstr "ID inválido %s: %s"

#: common/flatpak-remote.c:1216
#, c-format
msgid "Bad remote name: %s"
msgstr "Nome inválido de remoto: %s"

#: common/flatpak-remote.c:1220
msgid "No URL specified"
msgstr "Nenhuma URL especificada"

#: common/flatpak-remote.c:1266
msgid "GPG verification must be enabled when a collection ID is set"
msgstr ""
"Verificação GPG deve estar habilitada quando um ID de coleção for definido"

#: common/flatpak-repo-utils.c:344
#, c-format
msgid "No extra data sources"
msgstr "Nenhuma fonte de dados extras"

#: common/flatpak-repo-utils.c:2817
#, c-format
msgid "Invalid %s: Missing group ‘%s’"
msgstr "%s inválido: Faltando grupo “%s”"

#: common/flatpak-repo-utils.c:2826
#, c-format
msgid "Invalid %s: Missing key ‘%s’"
msgstr "%s inválido: Faltando chave “%s”"

#: common/flatpak-repo-utils.c:2876
msgid "Invalid gpg key"
msgstr "Chave gpg inválida"

#: common/flatpak-repo-utils.c:3217
#, c-format
msgid "Error copying 64x64 icon for component %s: %s\n"
msgstr "Erro ao copiar ícone 64x64 para componente %s: %s\n"

#: common/flatpak-repo-utils.c:3223
#, c-format
msgid "Error copying 128x128 icon for component %s: %s\n"
msgstr "Erro ao copiar ícone 128x128 para componente %s: %s\n"

#: common/flatpak-repo-utils.c:3362
#, c-format
msgid "%s is end-of-life, ignoring for appstream"
msgstr "%s está em fim de vida, ignorando para appstream"

#: common/flatpak-repo-utils.c:3397
#, c-format
msgid "No appstream data for %s: %s\n"
msgstr "Nenhum dado de appstream para %s: %s\n"

#: common/flatpak-repo-utils.c:3744
msgid "Invalid bundle, no ref in metadata"
msgstr "Pacote inválido, nenhuma ref nos metadados"

#: common/flatpak-repo-utils.c:3846
#, c-format
msgid "Collection ‘%s’ of bundle doesn’t match collection ‘%s’ of remote"
msgstr "A coleção “%s” de pacotes não correspondem à coleção “%s” do remoto"

#: common/flatpak-repo-utils.c:3923
msgid "Metadata in header and app are inconsistent"
msgstr "Metadados no cabeçalho e aplicativo estão inconsistentes"

#: common/flatpak-run.c:951
msgid "No systemd user session available, cgroups not available"
msgstr ""
"Nenhuma sessão de usuário de systemd disponível, cgroups não disponível"

#: common/flatpak-run.c:1496
msgid "Unable to allocate instance id"
msgstr "Não foi possível alocar id de instância"

#: common/flatpak-run.c:1632 common/flatpak-run.c:1641
#, c-format
msgid "Failed to open flatpak-info file: %s"
msgstr "Falha ao abrir arquivo flatpak-info: %s"

#: common/flatpak-run.c:1668
#, c-format
msgid "Failed to open bwrapinfo.json file: %s"
msgstr "Falha ao abrir arquivo bwrapinfo.json: %s"

#: common/flatpak-run.c:1689
#, c-format
msgid "Failed to write to instance id fd: %s"
msgstr "Falha ao escrever no descritor de arquivo do ID de instância: %s"

#: common/flatpak-run.c:2096
msgid "Initialize seccomp failed"
msgstr "Inicialização de seccomp falhou"

#: common/flatpak-run.c:2135
#, c-format
msgid "Failed to add architecture to seccomp filter: %s"
msgstr "Falha ao adicionar arquitetura ao filtro seccomp: %s"

#: common/flatpak-run.c:2143
#, c-format
msgid "Failed to add multiarch architecture to seccomp filter: %s"
msgstr "Falha ao adicionar arquitetura multiarch ao filtro seccomp: %s"

#: common/flatpak-run.c:2175 common/flatpak-run.c:2192
#: common/flatpak-run.c:2214
#, c-format
msgid "Failed to block syscall %d: %s"
msgstr "Falha ao bloquear a chamada de sistema %d: %s"

#: common/flatpak-run.c:2247
#, c-format
msgid "Failed to export bpf: %s"
msgstr "Falha ao exportar bpf: %s"

#: common/flatpak-run.c:2587
#, c-format
msgid "Failed to open ‘%s’"
msgstr "Falha ao abrir “%s”"

#: common/flatpak-run.c:2597
#, c-format
msgid ""
"Directory forwarding needs version 4 of the document portal (have version %d)"
msgstr ""
"Encaminhamento de diretório precisa da versão 4 do portal de documento (tem "
"a versão %d)"

#: common/flatpak-run.c:2915
#, c-format
msgid "ldconfig failed, exit status %d"
msgstr "ldconfig falhou, status de saída %d"

#: common/flatpak-run.c:2922
msgid "Can't open generated ld.so.cache"
msgstr "Não foi possível abrir o ld.so.cache gerado"

#. Translators: The placeholder is for an app ref.
#: common/flatpak-run.c:3045
#, c-format
msgid "Running %s is not allowed by the policy set by your administrator"
msgstr ""
"A execução de %s não é permitida pela política definida pelo administrador"

#: common/flatpak-run.c:3202
msgid ""
"\"flatpak run\" is not intended to be run as `sudo flatpak run`. Use `sudo "
"-i` or `su -l` instead and invoke \"flatpak run\" from inside the new shell."
msgstr ""
"“flatpak run” não se destina a ser executado como `sudo flatpak run`, use "
"`sudo -i` ou `su -l` no lugar e invoque “flatpak run” de dentro do novo "
"shell."

#: common/flatpak-run.c:3413
#, c-format
msgid "Failed to migrate from %s: %s"
msgstr "Falha ao migrar de %s: %s"

#: common/flatpak-run.c:3434
#, c-format
msgid "Failed to migrate old app data directory %s to new name %s: %s"
msgstr ""
"Falha ao migrar o diretório de dados antigo %s do aplicativo para o novo "
"nome %s: %s"

#: common/flatpak-run.c:3443
#, c-format
msgid "Failed to create symlink while migrating %s: %s"
msgstr "Falha ao criar link simbólico ao migrar %s: %s"

#: common/flatpak-run-dbus.c:46
msgid "Failed to open app info file"
msgstr "Falha ao abrir arquivo de informação do aplicativo"

#: common/flatpak-run-dbus.c:149
msgid "Unable to create sync pipe"
msgstr "Não foi possível criar um pipe de sincronização"

#: common/flatpak-run-dbus.c:185
msgid "Failed to sync with dbus proxy"
msgstr "Falha ao sincronizar com proxy de dbus"

#: common/flatpak-transaction.c:2275
#, c-format
msgid "Warning: Problem looking for related refs: %s"
msgstr "Aviso: Problema ao procurar por refs relacionadas: %s"

#: common/flatpak-transaction.c:2493
#, c-format
msgid "The application %s requires the runtime %s which was not found"
msgstr "O aplicativo %s requer o runtime %s, que não foi localizado"

#: common/flatpak-transaction.c:2509
#, c-format
msgid "The application %s requires the runtime %s which is not installed"
msgstr "O aplicativo %s requer o runtime %s, que não está instalado"

#: common/flatpak-transaction.c:2641
#, c-format
msgid "Can't uninstall %s which is needed by %s"
msgstr "Não foi possível desinstalar %s, o qual é necessário para %s"

#: common/flatpak-transaction.c:2740
#, c-format
msgid "Remote %s disabled, ignoring %s update"
msgstr "Remoto %s desabilitado, ignorando atualização de %s"

#: common/flatpak-transaction.c:2773
#, c-format
msgid "%s is already installed"
msgstr "%s já está instalado"

#: common/flatpak-transaction.c:2776
#, c-format
msgid "%s is already installed from remote %s"
msgstr "%s já está instalada pelo remoto %s"

#: common/flatpak-transaction.c:3120
#, c-format
msgid "Invalid .flatpakref: %s"
msgstr ".flatpakref inválido: %s"

#: common/flatpak-transaction.c:3161
msgid "Warning: Could not mark already installed apps as preinstalled"
msgstr ""
"Aviso: Não foi possível marcar aplicativos já instalados como pré-instalados"

#: common/flatpak-transaction.c:3382
#, c-format
msgid "Error updating remote metadata for '%s': %s"
msgstr "Erro ao atualizar metadados de remoto para “%s”: %s"

#: common/flatpak-transaction.c:3885
#, c-format
msgid ""
"Warning: Treating remote fetch error as non-fatal since %s is already "
"installed: %s"
msgstr ""
"Aviso: Tratando erro de obtenção de remoto como não fatal, já que %s já está "
"instalado: %s"

#: common/flatpak-transaction.c:4209
#, c-format
msgid "No authenticator installed for remote '%s'"
msgstr "Nenhum autenticador instalado para remoto “%s”"

#: common/flatpak-transaction.c:4313 common/flatpak-transaction.c:4320
#, c-format
msgid "Failed to get tokens for ref: %s"
msgstr "Falha ao obter tokens para ref: %s"

#: common/flatpak-transaction.c:4315 common/flatpak-transaction.c:4322
msgid "Failed to get tokens for ref"
msgstr "Falha ao obter tokens para ref"

#: common/flatpak-transaction.c:4580
#, c-format
msgid "Ref %s from %s matches more than one transaction operation"
msgstr "A ref %s de %s corresponde a mais de uma operação de transação"

#: common/flatpak-transaction.c:4581 common/flatpak-transaction.c:4591
msgid "any remote"
msgstr "qualquer remoto"

#: common/flatpak-transaction.c:4590
#, c-format
msgid "No transaction operation found for ref %s from %s"
msgstr "Nenhuma operação de transação localizada para a ref %s de %s"

#: common/flatpak-transaction.c:4713
#, c-format
msgid "Flatpakrepo URL %s not file, HTTP or HTTPS"
msgstr "URL de Flatpakrepo %s não é arquivo, HTTP ou HTTPS"

#: common/flatpak-transaction.c:4719
#, c-format
msgid "Can't load dependent file %s: "
msgstr "Não foi possível carregar o arquivo dependente %s: "

#: common/flatpak-transaction.c:4727
#, c-format
msgid "Invalid .flatpakrepo: %s"
msgstr ".flatpakrepo inválido: %s"

#: common/flatpak-transaction.c:5454
msgid "Transaction already executed"
msgstr "Transação já executada"

#: common/flatpak-transaction.c:5469
msgid ""
"Refusing to operate on a user installation as root! This can lead to "
"incorrect file ownership and permission errors."
msgstr ""
"Recusando-se a operar em uma instalação de usuário como root! Isso pode "
"levar à propriedade incorreta do arquivo e a erros de permissão."

#: common/flatpak-transaction.c:5567 common/flatpak-transaction.c:5580
msgid "Aborted by user"
msgstr "Abortado pelo usuário"

#: common/flatpak-transaction.c:5605
#, c-format
msgid "Skipping %s due to previous error"
msgstr "Ignorando %s por causa do erro anterior"

#: common/flatpak-transaction.c:5659
#, c-format
msgid "Aborted due to failure (%s)"
msgstr "Abortado devido a falha (%s)"

#: common/flatpak-uri.c:118
#, no-c-format
msgid "Invalid %-encoding in URI"
msgstr "%-encoding inválido na URI"

#: common/flatpak-uri.c:135
msgid "Illegal character in URI"
msgstr "Caractere ilegal na URI"

#: common/flatpak-uri.c:169
msgid "Non-UTF-8 characters in URI"
msgstr "Caracteres não UTF-8 na URI"

#: common/flatpak-uri.c:275
#, c-format
msgid "Invalid IPv6 address ‘%.*s’ in URI"
msgstr "Endereço IPv6 inválido “%.*s” na URI"

#: common/flatpak-uri.c:330
#, c-format
msgid "Illegal encoded IP address ‘%.*s’ in URI"
msgstr "Endereço IP codificado ilegal “%.*s” na URI"

#: common/flatpak-uri.c:342
#, c-format
msgid "Illegal internationalized hostname ‘%.*s’ in URI"
msgstr "Nome de máquina internacionalizado ilegal “%.*s” na URI"

#: common/flatpak-uri.c:374 common/flatpak-uri.c:386
#, c-format
msgid "Could not parse port ‘%.*s’ in URI"
msgstr "Não foi possível analisar a porta “%.*s” na URI"

#: common/flatpak-uri.c:393
#, c-format
msgid "Port ‘%.*s’ in URI is out of range"
msgstr "Porta “%.*s” na URI está fora da faixa"

#: common/flatpak-uri.c:910
msgid "URI is not absolute, and no base URI was provided"
msgstr "A URI não é absoluta e nenhuma URI base foi fornecida"

#: common/flatpak-usb.c:83
#, c-format
msgid "USB device query 'all' must not have data"
msgstr "A consulta de dispositivo USB 'all' não deve ter dados"

#: common/flatpak-usb.c:102
#, c-format
msgid "USB query rule 'cls' must be in the form CLASS:SUBCLASS or CLASS:*"
msgstr ""
"A regra de consulta USB 'cls' deve estar no formato CLASSE:SUBCLASSE ou "
"CLASSE:*"

#: common/flatpak-usb.c:111
#, c-format
msgid "Invalid USB class"
msgstr "Classe USB inválida"

#: common/flatpak-usb.c:125
#, c-format
msgid "Invalid USB subclass"
msgstr "Subclasse USB inválida"

#: common/flatpak-usb.c:141 common/flatpak-usb.c:148
#, c-format
msgid "USB query rule 'dev' must have a valid 4-digit hexadecimal product id"
msgstr ""
"A regra de consulta USB 'dev' deve ter um ID de produto válido hexadecimal "
"de 4 dígitos"

#: common/flatpak-usb.c:164 common/flatpak-usb.c:171
#, c-format
msgid "USB query rule 'vnd' must have a valid 4-digit hexadecimal vendor id"
msgstr ""
"A regra de consulta USB 'vnd' deve ter um ID de fornecedor válido "
"hexadecimal de 4 dígitos"

#: common/flatpak-usb.c:205
#, c-format
msgid "USB device queries must be in the form TYPE:DATA"
msgstr "As consultas de dispositivos USB devem estar no formato TIPO:DADOS"

#: common/flatpak-usb.c:225
#, c-format
msgid "Unknown USB query rule %s"
msgstr "Regra de consulta USB desconhecida %s"

#: common/flatpak-usb.c:248
#, c-format
msgid "Empty USB query"
msgstr "Consulta USB vazia"

#: common/flatpak-usb.c:274
#, c-format
msgid "Multiple USB query rules of the same type is not supported"
msgstr "Várias regras de consulta USB do mesmo tipo não são suportadas"

#: common/flatpak-usb.c:283
#, c-format
msgid "'all' must not contain extra query rules"
msgstr "'all' não deve conter regras de consulta extras"

#: common/flatpak-usb.c:291
#, c-format
msgid "USB queries with 'dev' must also specify vendors"
msgstr "Consultas USB com 'dev' também devem especificar fornecedores"

#: common/flatpak-utils.c:712
msgid "Glob can't match apps"
msgstr "Glob não pode corresponder aplicativos"

#: common/flatpak-utils.c:737
msgid "Empty glob"
msgstr "Glob vazio"

#: common/flatpak-utils.c:756
msgid "Too many segments in glob"
msgstr "Número excessivo de argumentos no glob"

#: common/flatpak-utils.c:777
#, c-format
msgid "Invalid glob character '%c'"
msgstr "Caractere de glob “%c” inválido"

#: common/flatpak-utils.c:831
#, c-format
msgid "Missing glob on line %d"
msgstr "Faltando glob na linha %d"

#: common/flatpak-utils.c:835
#, c-format
msgid "Trailing text on line %d"
msgstr "Texto ao final na linha %d"

#: common/flatpak-utils.c:839
#, c-format
msgid "on line %d"
msgstr "na linha %d"

#: common/flatpak-utils.c:861
#, c-format
msgid "Unexpected word '%s' on line %d"
msgstr "Palavra inesperada “%s” na linha %d"

#: common/flatpak-utils.c:2118
#, c-format
msgid "Invalid require-flatpak argument %s"
msgstr "Argumento de require-flatpak inválido %s"

#: common/flatpak-utils.c:2128 common/flatpak-utils.c:2147
#, c-format
msgid "%s needs a later flatpak version (%s)"
msgstr "%s precisa de uma versão posterior do flatpak (%s)"

#: oci-authenticator/flatpak-oci-authenticator.c:291
msgid "Not a oci remote, missing summary.xa.oci-repository"
msgstr "Não é um remoto OCI, faltando summary.xa.oci-repository"

#: oci-authenticator/flatpak-oci-authenticator.c:477
msgid "Not a OCI remote"
msgstr "Não é um remoto OCI"

#: oci-authenticator/flatpak-oci-authenticator.c:488
msgid "Invalid token"
msgstr "Token inválido"

#: portal/flatpak-portal.c:2292
#, c-format
msgid "No portal support found"
msgstr "Não foi localizado suporte a portal"

#: portal/flatpak-portal.c:2298
msgid "Deny"
msgstr "Negar"

#: portal/flatpak-portal.c:2300
msgid "Update"
msgstr "Atualizar"

#: portal/flatpak-portal.c:2305
#, c-format
msgid "Update %s?"
msgstr "Atualizar %s?"

#: portal/flatpak-portal.c:2317
msgid "The application wants to update itself."
msgstr "O aplicativo deseja atualizar a si próprio."

#: portal/flatpak-portal.c:2318
msgid "Update access can be changed any time from the privacy settings."
msgstr ""
"Acesso a atualização pode ser alterado a qualquer momento a partir das "
"configurações de privacidade."

#: portal/flatpak-portal.c:2343
#, c-format
msgid "Application update not allowed"
msgstr "Atualização de aplicativo não permitida"

#: portal/flatpak-portal.c:2501
#, c-format
msgid "Self update not supported, new version requires new permissions"
msgstr "Sem suporte à autoatualização, nova versão requer novas permissões"

#: portal/flatpak-portal.c:2684 portal/flatpak-portal.c:2702
#, c-format
msgid "Update ended unexpectedly"
msgstr "Atualização encerrada inesperadamente"

#. SECURITY:
#. - Normal users need admin authentication to install software
#. system-wide.
#. - Note that we install polkit rules that allow local users
#. in the wheel group to install without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:23
msgid "Install signed application"
msgstr "Instalar aplicativo assinado"

#: system-helper/org.freedesktop.Flatpak.policy.in:24
#: system-helper/org.freedesktop.Flatpak.policy.in:42
msgid "Authentication is required to install software"
msgstr "Autenticação é necessária para instalar software"

#. SECURITY:
#. - Normal users need admin authentication to install software
#. system-wide.
#. - Note that we install polkit rules that allow local users
#. in the wheel group to install without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:41
msgid "Install signed runtime"
msgstr "Instalar runtime assinado"

#. SECURITY:
#. - Normal users do not require admin authentication to update an
#. app as the commit will be signed, and the action is required
#. to update the system when unattended.
#. - Changing this to anything other than 'yes' will break unattended
#. updates.
#: system-helper/org.freedesktop.Flatpak.policy.in:60
msgid "Update signed application"
msgstr "Atualizar aplicativo assinado"

#: system-helper/org.freedesktop.Flatpak.policy.in:61
#: system-helper/org.freedesktop.Flatpak.policy.in:80
msgid "Authentication is required to update software"
msgstr "Autenticação é necessária para atualizar software"

#. SECURITY:
#. - Normal users do not require admin authentication to update a
#. runtime as the commit will be signed, and the action is required
#. to update the system when unattended.
#. - Changing this to anything other than 'yes' will break unattended
#. updates.
#: system-helper/org.freedesktop.Flatpak.policy.in:79
msgid "Update signed runtime"
msgstr "Atualizar runtime assinado"

#. SECURITY:
#. - Normal users do not need authentication to update metadata
#. from signed repositories.
#: system-helper/org.freedesktop.Flatpak.policy.in:94
msgid "Update remote metadata"
msgstr "Atualizar metadados remotos"

#: system-helper/org.freedesktop.Flatpak.policy.in:95
msgid "Authentication is required to update remote info"
msgstr "Autenticação é necessária para atualizar informações de remoto"

#. SECURITY:
#. - Normal users do not need authentication to modify the
#. OSTree repository
#. - Note that we install polkit rules that allow local users
#. in the wheel group to modify repos without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:111
msgid "Update system repository"
msgstr "Atualiza repositório do sistema"

#: system-helper/org.freedesktop.Flatpak.policy.in:112
msgid "Authentication is required to modify a system repository"
msgstr "Autenticação é necessária para modificar um repositório de sistema"

#. SECURITY:
#. - Normal users need admin authentication to install software
#. system-wide.
#: system-helper/org.freedesktop.Flatpak.policy.in:126
msgid "Install bundle"
msgstr "Instalar pacote"

#: system-helper/org.freedesktop.Flatpak.policy.in:127
msgid "Authentication is required to install software from $(path)"
msgstr "Autenticação é necessária para instalar software de $(path)"

#. SECURITY:
#. - Normal users need admin authentication to uninstall software
#. system-wide.
#. - Note that we install polkit rules that allow local users
#. in the wheel group to uninstall without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:144
msgid "Uninstall runtime"
msgstr "Desinstalar runtime"

#: system-helper/org.freedesktop.Flatpak.policy.in:145
msgid "Authentication is required to uninstall software"
msgstr "Autenticação é necessária para desinstalar software"

#. SECURITY:
#. - Normal users need admin authentication to uninstall software
#. system-wide.
#. - Note that we install polkit rules that allow local users
#. in the wheel group to uninstall without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:161
msgid "Uninstall app"
msgstr "Desinstalar aplicativo"

#: system-helper/org.freedesktop.Flatpak.policy.in:162
msgid "Authentication is required to uninstall $(ref)"
msgstr "Autenticação é necessária para desinstalar $(ref)"

#. SECURITY:
#. - Normal users need admin authentication to configure system-wide
#. software repositories.
#: system-helper/org.freedesktop.Flatpak.policy.in:177
msgid "Configure Remote"
msgstr "Configurar remoto"

#: system-helper/org.freedesktop.Flatpak.policy.in:178
msgid "Authentication is required to configure software repositories"
msgstr "Autenticação é necessária para configurar os repositórios de software"

#. SECURITY:
#. - Normal users need admin authentication to configure the system-wide
#. Flatpak installation.
#: system-helper/org.freedesktop.Flatpak.policy.in:192
msgid "Configure"
msgstr "Configurar"

#: system-helper/org.freedesktop.Flatpak.policy.in:193
msgid "Authentication is required to configure software installation"
msgstr "Autenticação é necessária para configurar a instalação de software"

#. SECURITY:
#. - Normal users do not require admin authentication to update
#. appstream data as it will be signed, and the action is required
#. to update the system when unattended.
#. - Changing this to anything other than 'yes' will break unattended
#. updates.
#: system-helper/org.freedesktop.Flatpak.policy.in:210
msgid "Update appstream"
msgstr "Atualizar appstream"

#: system-helper/org.freedesktop.Flatpak.policy.in:211
msgid "Authentication is required to update information about software"
msgstr "Autenticação é necessária para atualizar informações sobre software"

#. SECURITY:
#. - Normal users do not require admin authentication to update
#. metadata as it will be signed, and the action is required
#. to update the system when unattended.
#. - Changing this to anything other than 'yes' will break unattended
#. updates.
#: system-helper/org.freedesktop.Flatpak.policy.in:228
msgid "Update metadata"
msgstr "Atualizar metadados"

#: system-helper/org.freedesktop.Flatpak.policy.in:229
msgid "Authentication is required to update metadata"
msgstr "Autenticação é necessária para atualizar metadados"

#. SECURITY:
#. - Authorisation to actually install software is controlled by
#. org.freedesktop.Flatpak.app-install.
#. - This action is checked after app-install, as it can only be done
#. once the app’s data (including its content rating) has been
#. downloaded.
#. - This action is checked to see if the installation should be allowed
#. based on whether the app being installed has content which doesn’t
#. comply with the user’s parental controls policy (the content is
#. ‘too extreme’).
#. - It is checked only if an app has too extreme content for the user
#. who is trying to install it (in which case, the app is ‘unsafe’).
#. - Typically, normal users will need admin permission to install apps
#. with extreme content; admins will be able to install it without
#. additional checks.
#. - In order to configure the policy so that admins can install safe and
#. unsafe software anywhere without authorisation, and non-admins can
#. install safe software in their user or system dirs without
#. authorisation, but need authorisation to install unsafe software
#. anywhere:
#. * Unconditionally return `yes` from `app-install`.
#. * Return `auth_admin` from `override-parental-controls` for users
#. not in `@privileged_group@`, and `yes` for users in it.
#. * Set the malcontent `is-{user,system}-installation-allowed`
#. properties of all non-admins’ parental controls policies to true.
#. - In order to configure the policy so that admins can install safe and
#. unsafe software anywhere without authorisation, and non-admins can
#. install safe software in their user dir without authorisation, but
#. need authorisation to install safe software in the system dir or to
#. install unsafe software anywhere:
#. * Unconditionally return `yes` from `app-install`.
#. * Return `auth_admin` from `override-parental-controls` for users
#. not in `@privileged_group@`, and `yes` for users in it.
#. * Set the malcontent `is-user-installation-allowed` property of all
#. non-admins’ parental controls policies to true.
#. * Set the malcontent `is-system-installation-allowed` property of
#. all non-admins’ parental controls policies to false.
#. - In order to configure the policy so that all users (including
#. admins) can install safe software anywhere without authorisation,
#. but need authorisation to install unsafe software anywhere (i.e.
#. applying parental controls to admins too):
#. * Unconditionally return `yes` from `app-install`.
#. * Unconditionally return `auth_admin` from `override-parental-controls`.
#. * Set the malcontent `is-user-installation-allowed` property of all
#. users’ parental controls policies to true.
#. * Set the malcontent `is-system-installation-allowed` property of
#. all users’ parental controls policies to true.
#: system-helper/org.freedesktop.Flatpak.policy.in:287
msgid "Override parental controls for installs"
msgstr "Sobrepor controle parental para instalação"

#: system-helper/org.freedesktop.Flatpak.policy.in:288
msgid ""
"Authentication is required to install software which is restricted by your "
"parental controls policy"
msgstr ""
"Autenticação é necessária para instalar software que está restrito por sua "
"política de controle parental"

#. SECURITY:
#. - This is like org.freedesktop.Flatpak.override-parental-controls, but
#. it’s queried for app updates, whereas the former is queried for app
#. installs.
#. - As with the above action, this one is only queried if
#. org.freedesktop.Flatpak.app-update has allowed the app update, and
#. only if the app being updated has too extreme content for the user
#. who is trying to update it.
#. - The default policy for this is to *allow* updates to ‘too extreme’
#. apps by default, on the basis that having an out-of-date (i.e.
#. insecure or unsupported) app is a worse outcome than automatically
#. installing an update which has radically different content from the
#. version of the app which the parent originally vetted and installed.
#: system-helper/org.freedesktop.Flatpak.policy.in:313
msgid "Override parental controls for updates"
msgstr "Sobrepor controle parental para atualizações"

#: system-helper/org.freedesktop.Flatpak.policy.in:314
msgid ""
"Authentication is required to update software which is restricted by your "
"parental controls policy"
msgstr ""
"Autenticação é necessária para atualizar software que está restrito por sua "
"política de controle parental"

#~ msgid "Installed:"
#~ msgstr "Instalado:"

#~ msgid "Download:"
#~ msgstr "Baixar:"

#, c-format
#~ msgid "No gpg key found with ID %s (homedir: %s)"
#~ msgstr "Nenhuma chave gpg localizada com ID %s (homedir: %s)"

#, c-format
#~ msgid "Unable to lookup key ID %s: %d"
#~ msgstr "Não foi possível procurar o ID de chave %s: %d"

#, c-format
#~ msgid "Error signing commit: %d"
#~ msgstr "Erro ao assinar o commit: %d"

#, c-format
#~ msgid ""
#~ "Found similar ref(s) for ‘%s’ in remote ‘%s’ (%s).\n"
#~ "Use this remote?"
#~ msgstr ""
#~ "Localizada(s) ref(s) similares para “%s” em remoto “%s” (%s).\n"
#~ "Usar esse remoto?"

#, c-format
#~ msgid "No entry for %s in remote '%s' summary cache "
#~ msgstr "Nenhuma entrada para %s no cache de resumo do remoto “%s” "

#, c-format
#~ msgid "Failed to uninstall %s for rebase to %s: "
#~ msgstr "Falha ao desinstalar %s para realizar rebase de %s: "

#, c-format
#~ msgid "Failed to uninstall %s for rebase to %s: %s\n"
#~ msgstr "Falha ao desinstalar %s para rebase de %s: %s\n"

#, c-format
#~ msgid "Unable to open directory %s"
#~ msgstr "Não foi possível abrir o diretório %s"

#~ msgid "install"
#~ msgstr "instalar"

#~ msgid "update"
#~ msgstr "atualizar"

#~ msgid "install bundle"
#~ msgstr "instalar pacote"

#~ msgid "uninstall"
#~ msgstr "desinstalar"

#~ msgid "(internal error, please report)"
#~ msgstr "(erro interno, por favor relate)"

#~ msgid "Warning:"
#~ msgstr "Aviso:"

#~ msgid "runtime"
#~ msgstr "runtime"

#~ msgid "app"
#~ msgstr "app"

# 1º %s: "Error:", "Warning:"
# 2º %s: op_type: "install", "update", etc.
# 3º %s: rref: name of a ref
# 4º %s: msg: some error/warning message
#, c-format
#~ msgid "%s Failed to %s %s: %s\n"
#~ msgstr "%s Falha ao %s %s: %s\n"

#~ msgid "[REF…] - Uninstall an application"
#~ msgstr "[REF…] – Desinstala um aplicativo"

#, c-format
#~ msgid "Replace it with %s?"
#~ msgstr "Substitui-lo por %s?"

#~ msgid "\"flatpak run\" is not intended to be ran with sudo"
#~ msgstr "“flatpak run” não se destina a ser executado com sudo"

#~ msgid "Invalid deployed ref %s: "
#~ msgstr "Ref implantado inválido %s: "

#~ msgid "Deployed ref %s kind does not match commit (%s)"
#~ msgstr "O tipo da ref implementado %s não coincide com o commit (%s)"

#~ msgid "Deployed ref %s name does not match commit (%s)"
#~ msgstr "O nome da ref implementado %s não coincide com o commit (%s)"

#~ msgid "Deployed ref %s arch does not match commit (%s)"
#~ msgstr "A arquitetura da ref implementado %s não coincide com o commit (%s)"

#~ msgid "Failed to determine parts from ref: %s"
#~ msgstr "Falha ao determinar partes da ref: %s"

#~ msgid "Invalid arch %s"
#~ msgstr "Arquitetura inválida %s"

#~ msgid "Related ref '%s' is only partially installed"
#~ msgstr "A ref “%s” relacionado está apenas parcialmente instalado"

#~ msgid "Ref '%s' is only partially installed"
#~ msgstr "A ref “%s” está apenas parcialmente instalado"

#~ msgid "No such ref (%s, %s) in remote %s"
#~ msgstr "Ref inexistente (%s, %s) no remoto %s"

#~ msgid "No flatpak cache in remote '%s' summary"
#~ msgstr "Nenhum cache de flatpak no sumário do remoto “%s”"

#~ msgid "No such ref (%s, %s) in remote %s or elsewhere"
#~ msgstr "Ref inexistente (%s, %s) no remoto %s ou em outro lugar"

#~ msgid "No remotes found which provide these refs: [%s]"
#~ msgstr "Nenhum remoto localizado que forneça esses refs: [%s]"

#~ msgid "No remotes found which provide the ref (%s, %s)"
#~ msgstr "Nenhum remoto localizado que forneça a ref (%s, %s)"

#~ msgid "No summary found"
#~ msgstr "Nenhum resumo localizado"

#~ msgid ""
#~ "GPG verification enabled, but no summary signatures found for remote '%s'"
#~ msgstr ""
#~ "Verificação GPG habilitada, mas nenhuma assinatura de resumo localizada "
#~ "para o remoto “%s”"

#~ msgid ""
#~ "GPG signatures found for remote '%s', but none are in trusted keyring"
#~ msgstr ""
#~ "Assinaturas GPG localizadas para o remoto “%s”, mas nenhuma está no "
#~ "chaveiro de confiadas"

#~ msgid "Expected commit metadata to have ref binding information, found none"
#~ msgstr ""
#~ "Esperava que metadados de commit tivessem informações de associação de "
#~ "ref, localizou nada"

#~ msgid ""
#~ "Expected commit metadata to have collection ID binding information, found "
#~ "none"
#~ msgstr ""
#~ "Esperava que metadados de commit tivessem informações de associação de ID "
#~ "da coleção, localizou nada"

#~ msgid ""
#~ "Commit has collection ID ‘%s’ in collection binding metadata, while the "
#~ "remote it came from has collection ID ‘%s’"
#~ msgstr ""
#~ "O commit possui ID de coleção “%s” nos metadados de associação de "
#~ "coleção, enquanto no remoto ele tem ID de coleção “%s”"

#~ msgid "Deployed metadata does not match commit"
#~ msgstr "Metadados implementados não coincidem com o commit"

#~ msgid "No repo metadata cached for remote '%s'"
#~ msgstr "Nenhum metadado de repositório em cache para o remoto “%s”"

#~ msgid "No metadata branch for OCI"
#~ msgstr "Nenhum ramo de metadados para OCI"

#~ msgid "Invalid group: %d"
#~ msgstr "Grupo inválido: %d"

#~ msgid "Warning: Can't find %s metadata for dependencies: %s"
#~ msgstr ""
#~ "Aviso: Não foi possível localizar metadados %s para dependências: %s"

#~ msgid "Use OCI labels instead of annotations"
#~ msgstr "Usa rótulos OCI em vez de anotações"

#~ msgid "OPTIONS"
#~ msgstr "OPÇÕES"

#~ msgid "Not running as root, may be unable to enter namespace"
#~ msgstr ""
#~ "Não executando como root, pode ser impossível entrar no espaço de nome"

#~ msgid "Default system installation"
#~ msgstr "Instalação padrão do sistema"

#~ msgid "No url specified in flatpakrepo file"
#~ msgstr "Nenhuma url especificada no arquivo flatpakrepo"

#~ msgid "0"
#~ msgstr "0"

#~ msgid "Location:"
#~ msgstr "Localização:"

#~ msgid "Architecture"
#~ msgstr "Arquitetura"

#~ msgid "Runtime Branch"
#~ msgstr "Ramo do runtime"

#~ msgid "Runtime Commit"
#~ msgstr "Commit do runtime"

#~ msgid "Installing for user: %s from %s\n"
#~ msgstr "Instalando para usuário: %s de %s\n"

#~ msgid "Installing: %s from %s\n"
#~ msgstr "Instalando: %s de %s\n"

#~ msgid "Updating for user: %s from %s\n"
#~ msgstr "Atualizando para usuário: %s de %s\n"

#~ msgid "Updating: %s from %s\n"
#~ msgstr "Atualizando: %s de %s\n"

#~ msgid "Installing for user: %s from bundle %s\n"
#~ msgstr "Instalando para usuário: %s do pacote %s\n"

#~ msgid "Installing: %s from bundle %s\n"
#~ msgstr "Instalando: %s do pacote %s\n"

#~ msgid "Uninstalling for user: %s\n"
#~ msgstr "Desinstalando para usuário: %s\n"

#~ msgid "No updates.\n"
#~ msgstr "Nenhuma atualização.\n"

#~ msgid "Now at %s.\n"
#~ msgstr "Agora em %s.\n"

#~ msgid "new file access"
#~ msgstr "novo acesso a arquivo"

#~ msgid "file access"
#~ msgstr "acesso a arquivo"

#~ msgid "new dbus access"
#~ msgstr "novo acesso a dbus"

#~ msgid "dbus access"
#~ msgstr "acesso a dbus"

#~ msgid "new dbus ownership"
#~ msgstr "nova propriedade dbus"

#~ msgid "dbus ownership"
#~ msgstr "propriedade dbus"

#~ msgid "new system dbus access"
#~ msgstr "novo acesso dbus de sistema"

#~ msgid "system dbus access"
#~ msgstr "acesso dbus de sistema"

#~ msgid "new system dbus ownership"
#~ msgstr "nova propriedade dbus de sistema"

#~ msgid "system dbus ownership"
#~ msgstr "propriedade dbus de sistema"

#~ msgid "new tags"
#~ msgstr "novas etiquetas"

#~ msgid "tags"
#~ msgstr "etiquetas"

#~ msgid "Uninstalling from %s:\n"
#~ msgstr "Desinstalando de %s:\n"

#~ msgid "Installing in %s:\n"
#~ msgstr "Instalando em %s:\n"

#~ msgid "Is this ok"
#~ msgstr "Isto está bom"

#~ msgid "Print OSTree debug information during command processing"
#~ msgstr ""
#~ "Exibe a informações de depuração da árvore do sistema durante o "
#~ "processamento de comandos"

#~ msgid "Unknown command '%s'"
#~ msgstr "Comando desconhecido “%s”"

#~ msgid "Invalid sha256 for extra data uri %s"
#~ msgstr "sha256 inválido para uri de dados extras %s"

#~ msgid "Invalid sha256 for extra data"
#~ msgstr "sha256 inválido para dados extras"

#~ msgid "%s branch already installed"
#~ msgstr "%s ramo já está instalado"

#~ msgid "%s branch %s not installed"
#~ msgstr "%s ramo %s não está instalado"

#~ msgid "Migrating %s to %s\n"
#~ msgstr "Migrando %s para %s\n"

#~ msgid "Extracting icons for component %s\n"
#~ msgstr "Extraindo ícones para o componente %s\n"

#~ msgid "Redirect collection ID: %s\n"
#~ msgstr "ID de coleção de redirecionamento: %s\n"

#~ msgid "Is this ok?"
#~ msgstr "Isto está bom?"

#~ msgid "Add OCI registry"
#~ msgstr "Adiciona registro OCI"

#~ msgid "Found in remote %s\n"
#~ msgstr "Localizado no remoto %s\n"

#~ msgid "Found in remote %s, do you want to install it?"
#~ msgstr "Localizado no remoto %s, você deseja instalá-lo?"

#~ msgid "Found in several remotes:\n"
#~ msgstr "Localizado em diversos remotos:\n"

#~ msgid "The required runtime %s was not found in a configured remote.\n"
#~ msgstr "O runtime exigido %s não foi localizado em um remoto configurado.\n"

#~ msgid "%s already installed, skipping\n"
#~ msgstr "%s já instalado, ignorando\n"

#~ msgid "fetch remote info"
#~ msgstr "obtém info de remoto"

#~ msgid "One or more operations failed"
#~ msgstr "Uma ou mais operações falharam"

#~ msgid ""
#~ "/var/tmp does not suport xattrs which is needed for system-wide "
#~ "installation as a user. FLATPAK_SYSTEM_CACHE_DIR can be used to set an "
#~ "alternative path."
#~ msgstr ""
#~ "/var/tmp não possui suporte a xattrs que é necessário para instalação "
#~ "para todo sistema como usuário. FLATPAK_SYSTEM_CACHE_DIR pode ser usado "
#~ "para definir um caminho alternativo."

#~ msgid "No ref information available in repository"
#~ msgstr "Nenhuma informação de ref disponível no repositório"

#~ msgid "Remote title not set"
#~ msgstr "Título remoto não definido"

#~ msgid "Remote default-branch not set"
#~ msgstr "Ramo padrão remoto não definido"

#~ msgid "Search specific system-wide installations"
#~ msgstr "Pesquisa instalações específicas do sistema"

#~ msgid "Failed to unlink temporary file"
#~ msgstr "Falha ao desvincular arquivo temporário"

#~ msgid "Post-Install %s"
#~ msgstr "Pós-instalação: %s"

===== ./po/sk.po =====
# Slovak translation for flatpak.
# Copyright (C) 2016 flatpak's COPYRIGHT HOLDER
# This file is distributed under the same license as the flatpak package.
# Dušan Kazik <prescott66@gmail.com>, 2017.
#
msgid ""
msgstr ""
"Project-Id-Version: flatpak master\n"
"Report-Msgid-Bugs-To: https://github.com/flatpak/flatpak/issues\n"
"POT-Creation-Date: 2026-05-27 16:39+0200\n"
"PO-Revision-Date: 2017-01-23 18:19+0100\n"
"Last-Translator: Dušan Kazik <prescott66@gmail.com>\n"
"Language-Team: Slovak <gnome-sk-list@gnome.org>\n"
"Language: sk\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=(n==1) ? 1 : (n>=2 && n<=4) ? 2 : 0;\n"
"X-Generator: Poedit 1.8.11\n"

#: app/flatpak-builtins-build-bundle.c:59
msgid "Export runtime instead of app"
msgstr "Exportuje prostredie namiesto aplikácie"

#: app/flatpak-builtins-build-bundle.c:60
msgid "Arch to bundle for"
msgstr ""

#: app/flatpak-builtins-build-bundle.c:60
#: app/flatpak-builtins-build-export.c:62 app/flatpak-builtins-build-init.c:53
#: app/flatpak-builtins-build-sign.c:42 app/flatpak-builtins-create-usb.c:46
#: app/flatpak-builtins-info.c:55 app/flatpak-builtins-install.c:67
#: app/flatpak-builtins-list.c:50 app/flatpak-builtins-make-current.c:38
#: app/flatpak-builtins-remote-info.c:54 app/flatpak-builtins-remote-ls.c:56
#: app/flatpak-builtins-run.c:158 app/flatpak-builtins-search.c:37
#: app/flatpak-builtins-uninstall.c:54 app/flatpak-builtins-update.c:56
msgid "ARCH"
msgstr "ARCHITEKTÚRA"

#: app/flatpak-builtins-build-bundle.c:61
#, fuzzy
msgid "URL for repo"
msgstr "Url pre repozitár"

#: app/flatpak-builtins-build-bundle.c:61
#: app/flatpak-builtins-build-bundle.c:62
#: app/flatpak-builtins-build-update-repo.c:68
#: app/flatpak-builtins-build-update-repo.c:72
#: app/flatpak-builtins-build-update-repo.c:73
#: app/flatpak-builtins-history.c:69 app/flatpak-builtins-remote-add.c:80
#: app/flatpak-builtins-remote-add.c:81 app/flatpak-builtins-remote-add.c:85
#: app/flatpak-builtins-remote-list.c:53
#: app/flatpak-builtins-remote-modify.c:70
#: app/flatpak-builtins-remote-modify.c:85
#: app/flatpak-builtins-remote-modify.c:86
#: app/flatpak-builtins-remote-modify.c:90
msgid "URL"
msgstr "URL"

#: app/flatpak-builtins-build-bundle.c:62
#, fuzzy
msgid "URL for runtime flatpakrepo file"
msgstr ""
"Chyba počas aktualizácie metaúdajov navyše pre „%s“: %s\n"
"\n"

#: app/flatpak-builtins-build-bundle.c:63
msgid "Add GPG key from FILE (- for stdin)"
msgstr "Pridá kľúč GPG zo SÚBORU (- pre štandardný vstup)"

#: app/flatpak-builtins-build-bundle.c:63 app/flatpak-builtins-build.c:54
#: app/flatpak-builtins-build-export.c:67
#: app/flatpak-builtins-build-update-repo.c:83
#: app/flatpak-builtins-install.c:81 app/flatpak-builtins-remote-add.c:84
#: app/flatpak-builtins-remote-add.c:86 app/flatpak-builtins-remote-modify.c:89
#: app/flatpak-builtins-remote-modify.c:92
msgid "FILE"
msgstr "SÚBOR"

#: app/flatpak-builtins-build-bundle.c:64
msgid "GPG Key ID to sign the OCI image with"
msgstr ""

#: app/flatpak-builtins-build-bundle.c:64
#: app/flatpak-builtins-build-commit-from.c:68
#: app/flatpak-builtins-build-export.c:68
#: app/flatpak-builtins-build-import-bundle.c:49
#: app/flatpak-builtins-build-sign.c:44
#: app/flatpak-builtins-build-update-repo.c:84
msgid "KEY-ID"
msgstr ""

#: app/flatpak-builtins-build-bundle.c:65
#: app/flatpak-builtins-build-commit-from.c:69
#: app/flatpak-builtins-build-export.c:71
#: app/flatpak-builtins-build-import-bundle.c:50
#: app/flatpak-builtins-build-sign.c:45
#: app/flatpak-builtins-build-update-repo.c:85
msgid "GPG Homedir to use when looking for keyrings"
msgstr ""

#: app/flatpak-builtins-build-bundle.c:65
#: app/flatpak-builtins-build-commit-from.c:69
#: app/flatpak-builtins-build-export.c:71
#: app/flatpak-builtins-build-import-bundle.c:50
#: app/flatpak-builtins-build-sign.c:45
#: app/flatpak-builtins-build-update-repo.c:85
msgid "HOMEDIR"
msgstr ""

#: app/flatpak-builtins-build-bundle.c:66
msgid "OSTree commit to create a delta bundle from"
msgstr ""

#: app/flatpak-builtins-build-bundle.c:66 app/flatpak-builtins-remote-info.c:55
#: app/flatpak-builtins-update.c:57
msgid "COMMIT"
msgstr "ZAČLENENIE"

#: app/flatpak-builtins-build-bundle.c:67
msgid "Export oci image instead of flatpak bundle"
msgstr ""

#: app/flatpak-builtins-build-bundle.c:70
msgid "How to compress OCI image layers (default: gzip)"
msgstr ""

#: app/flatpak-builtins-build-bundle.c:634
msgid ""
"LOCATION FILENAME NAME [BRANCH] - Create a single file bundle from a local "
"repository"
msgstr ""

#: app/flatpak-builtins-build-bundle.c:641
msgid "LOCATION, FILENAME and NAME must be specified"
msgstr ""

#: app/flatpak-builtins-build-bundle.c:644
#: app/flatpak-builtins-build-export.c:844
#: app/flatpak-builtins-build-import-bundle.c:136
#: app/flatpak-builtins-build-init.c:217 app/flatpak-builtins-build-sign.c:76
#: app/flatpak-builtins-document-export.c:112
#: app/flatpak-builtins-document-info.c:75
#: app/flatpak-builtins-document-list.c:191
#: app/flatpak-builtins-document-unexport.c:70
#: app/flatpak-builtins-history.c:482 app/flatpak-builtins-info.c:130
#: app/flatpak-builtins-install.c:181 app/flatpak-builtins-install.c:234
#: app/flatpak-builtins-install.c:298 app/flatpak-builtins-list.c:419
#: app/flatpak-builtins-make-current.c:72 app/flatpak-builtins-override.c:73
#: app/flatpak-builtins-permission-list.c:162
#: app/flatpak-builtins-permission-remove.c:132
#: app/flatpak-builtins-remote-add.c:323
#: app/flatpak-builtins-remote-delete.c:68
#: app/flatpak-builtins-remote-list.c:241 app/flatpak-builtins-remote-ls.c:407
msgid "Too many arguments"
msgstr "Príliš veľa parametrov"

#: app/flatpak-builtins-build-bundle.c:659
#: app/flatpak-builtins-build-commit-from.c:338
#: app/flatpak-builtins-build-commit-from.c:351
#: app/flatpak-builtins-build-import-bundle.c:145
#, c-format
msgid "'%s' is not a valid repository"
msgstr "„%s“ nie je platným repozitárom"

#: app/flatpak-builtins-build-bundle.c:663
#, fuzzy, c-format
msgid "'%s' is not a valid repository: "
msgstr "„%s“ nie je platným repozitárom"

#: app/flatpak-builtins-build-bundle.c:674 app/flatpak-builtins-build-sign.c:88
#: common/flatpak-dir.c:14293
#, c-format
msgid "'%s' is not a valid name: %s"
msgstr "„%s“ nie je platným názvom: %s"

#: app/flatpak-builtins-build-bundle.c:677
#: app/flatpak-builtins-build-export.c:865 app/flatpak-builtins-build-sign.c:91
#: common/flatpak-dir.c:14299
#, c-format
msgid "'%s' is not a valid branch name: %s"
msgstr "„%s“ nie je platným názvom vetvy: %s"

#: app/flatpak-builtins-build-bundle.c:691
#: app/flatpak-builtins-build-import-bundle.c:149
#: app/flatpak-builtins-build-init.c:281
#, fuzzy, c-format
msgid "'%s' is not a valid filename"
msgstr "„%s“ nie je platným názvom: %s"

#: app/flatpak-builtins-build-bundle.c:706
msgid "--oci-layer-compress value must be gzip or zstd"
msgstr ""

#: app/flatpak-builtins-build.c:49
msgid "Use Platform runtime rather than Sdk"
msgstr ""

#: app/flatpak-builtins-build.c:50
msgid "Make destination readonly"
msgstr ""

#: app/flatpak-builtins-build.c:51
msgid "Add bind mount"
msgstr "Pridá viazané pripojenie"

#: app/flatpak-builtins-build.c:51
msgid "DEST=SRC"
msgstr "CIEĽ=ZDROJ"

#: app/flatpak-builtins-build.c:52
msgid "Start build in this directory"
msgstr "Spustí zostavenie v tomto adresári"

#: app/flatpak-builtins-build.c:52 app/flatpak-builtins-build.c:53
#: app/flatpak-builtins-build-init.c:64 app/flatpak-builtins-run.c:160
msgid "DIR"
msgstr "ADRESÁR"

#: app/flatpak-builtins-build.c:53
msgid "Where to look for custom sdk dir (defaults to 'usr')"
msgstr ""

#: app/flatpak-builtins-build.c:54 app/flatpak-builtins-build-export.c:67
msgid "Use alternative file for the metadata"
msgstr "Použije alternatívny súbor pre metaúdaje"

#: app/flatpak-builtins-build.c:55 app/flatpak-builtins-run.c:177
msgid "Kill processes when the parent process dies"
msgstr ""

#: app/flatpak-builtins-build.c:56
msgid "Export application homedir directory to build"
msgstr ""

#: app/flatpak-builtins-build.c:57 app/flatpak-builtins-run.c:165
msgid "Log session bus calls"
msgstr ""

#: app/flatpak-builtins-build.c:58 app/flatpak-builtins-run.c:166
msgid "Log system bus calls"
msgstr ""

#: app/flatpak-builtins-build.c:262
#, fuzzy
msgid "DIRECTORY [COMMAND [ARGUMENT…]] - Build in directory"
msgstr "ADRESÁR [PRÍKAZ [parametre...]] - Zostavenie v adresári"

#: app/flatpak-builtins-build.c:285 app/flatpak-builtins-build-finish.c:656
msgid "DIRECTORY must be specified"
msgstr "ADRESÁR musí byť určený"

#: app/flatpak-builtins-build.c:296 app/flatpak-builtins-build-export.c:887
#, c-format
msgid "Build directory %s not initialized, use flatpak build-init"
msgstr ""

#: app/flatpak-builtins-build.c:315
#, fuzzy
msgid "metadata invalid, not application or runtime"
msgstr "Podpíše aplikáciu alebo prostredie"

#: app/flatpak-builtins-build.c:446
#, c-format
msgid "No extension point matching %s in %s"
msgstr ""

#: app/flatpak-builtins-build.c:635
#, c-format
msgid "Missing '=' in bind mount option '%s'"
msgstr ""

#: app/flatpak-builtins-build.c:679 common/flatpak-run.c:3961
#, c-format
msgid "Unable to start app"
msgstr "Nie je možné spustiť aplikáciu"

#: app/flatpak-builtins-build-commit-from.c:58
msgid "Source repo dir"
msgstr ""

#: app/flatpak-builtins-build-commit-from.c:58
msgid "SRC-REPO"
msgstr "ZDROJ-REPOZITÁR"

#: app/flatpak-builtins-build-commit-from.c:59
msgid "Source repo ref"
msgstr ""

#: app/flatpak-builtins-build-commit-from.c:59
msgid "SRC-REF"
msgstr ""

#: app/flatpak-builtins-build-commit-from.c:64
#: app/flatpak-builtins-build-export.c:60
msgid "One line subject"
msgstr "Predmet na jeden riadok"

#: app/flatpak-builtins-build-commit-from.c:64
#: app/flatpak-builtins-build-export.c:60
msgid "SUBJECT"
msgstr "PREDMET"

#: app/flatpak-builtins-build-commit-from.c:65
#: app/flatpak-builtins-build-export.c:61
msgid "Full description"
msgstr "Úplný popis"

#: app/flatpak-builtins-build-commit-from.c:65
#: app/flatpak-builtins-build-export.c:61
msgid "BODY"
msgstr "TELO"

#: app/flatpak-builtins-build-commit-from.c:66
#: app/flatpak-builtins-build-export.c:64
#: app/flatpak-builtins-build-import-bundle.c:51
msgid "Update the appstream branch"
msgstr ""

#: app/flatpak-builtins-build-commit-from.c:67
#: app/flatpak-builtins-build-export.c:65
#: app/flatpak-builtins-build-import-bundle.c:52
#: app/flatpak-builtins-build-update-repo.c:87
msgid "Don't update the summary"
msgstr ""

#: app/flatpak-builtins-build-commit-from.c:68
#: app/flatpak-builtins-build-export.c:68
#: app/flatpak-builtins-build-import-bundle.c:49
#: app/flatpak-builtins-build-sign.c:44
msgid "GPG Key ID to sign the commit with"
msgstr ""

#: app/flatpak-builtins-build-commit-from.c:70
#: app/flatpak-builtins-build-export.c:73
msgid "Mark build as end-of-life"
msgstr ""

#: app/flatpak-builtins-build-commit-from.c:70
#: app/flatpak-builtins-build-export.c:73
msgid "REASON"
msgstr ""

#: app/flatpak-builtins-build-commit-from.c:71
msgid ""
"Mark refs matching the OLDID prefix as end-of-life, to be replaced with the "
"given NEWID"
msgstr ""

#: app/flatpak-builtins-build-commit-from.c:71
msgid "OLDID=NEWID"
msgstr ""

#: app/flatpak-builtins-build-commit-from.c:72
#: app/flatpak-builtins-build-export.c:75
msgid "Set type of token needed to install this commit"
msgstr ""

#: app/flatpak-builtins-build-commit-from.c:72
#: app/flatpak-builtins-build-export.c:75
msgid "VAL"
msgstr ""

#: app/flatpak-builtins-build-commit-from.c:73
msgid "Override the timestamp of the commit (NOW for current time)"
msgstr ""

#: app/flatpak-builtins-build-commit-from.c:73
#: app/flatpak-builtins-build-export.c:76
msgid "TIMESTAMP"
msgstr ""

#: app/flatpak-builtins-build-commit-from.c:75
#: app/flatpak-builtins-build-export.c:80
#: app/flatpak-builtins-build-import-bundle.c:53
#: app/flatpak-builtins-build-update-repo.c:97
msgid "Don't generate a summary index"
msgstr ""

#: app/flatpak-builtins-build-commit-from.c:278
msgid "DST-REPO [DST-REF…] - Make a new commit from existing commits"
msgstr ""

#: app/flatpak-builtins-build-commit-from.c:285
msgid "DST-REPO must be specified"
msgstr ""

#: app/flatpak-builtins-build-commit-from.c:293
msgid ""
"If --src-repo is not specified, exactly one destination ref must be specified"
msgstr ""

#: app/flatpak-builtins-build-commit-from.c:296
msgid ""
"If --src-ref is specified, exactly one destination ref must be specified"
msgstr ""

#: app/flatpak-builtins-build-commit-from.c:299
#, fuzzy
msgid "Either --src-repo or --src-ref must be specified"
msgstr "Musí byť určený NÁZOV vzdialeného repozitára"

#: app/flatpak-builtins-build-commit-from.c:315
msgid "Invalid argument format of use  --end-of-life-rebase=OLDID=NEWID"
msgstr ""

#: app/flatpak-builtins-build-commit-from.c:321
#: app/flatpak-builtins-build-commit-from.c:324
#, c-format
msgid "Invalid name %s in --end-of-life-rebase"
msgstr ""

#: app/flatpak-builtins-build-commit-from.c:333
#: app/flatpak-builtins-build-export.c:1092
#, c-format
msgid "Could not parse '%s'"
msgstr ""

#: app/flatpak-builtins-build-commit-from.c:498
msgid "Can't commit from partial source commit"
msgstr ""

#: app/flatpak-builtins-build-commit-from.c:503
#, c-format
msgid "%s: no change\n"
msgstr ""

#: app/flatpak-builtins-build-export.c:62
msgid "Architecture to export for (must be host compatible)"
msgstr ""

#: app/flatpak-builtins-build-export.c:63
msgid "Commit runtime (/usr), not /app"
msgstr ""

#: app/flatpak-builtins-build-export.c:66
msgid "Use alternative directory for the files"
msgstr ""

#: app/flatpak-builtins-build-export.c:66
msgid "SUBDIR"
msgstr ""

#: app/flatpak-builtins-build-export.c:69
msgid "Files to exclude"
msgstr "Súbory na vylúčenie"

#: app/flatpak-builtins-build-export.c:69
#: app/flatpak-builtins-build-export.c:70
#: app/flatpak-builtins-build-update-repo.c:90
msgid "PATTERN"
msgstr "VZOR"

#: app/flatpak-builtins-build-export.c:70
msgid "Excluded files to include"
msgstr "Vylúčené súbory na zahrnutie"

#: app/flatpak-builtins-build-export.c:74
msgid "Mark build as end-of-life, to be replaced with the given ID"
msgstr ""

#: app/flatpak-builtins-build-export.c:74
#: app/flatpak-builtins-document-list.c:49 app/flatpak-cli-transaction.c:1427
msgid "ID"
msgstr ""

#: app/flatpak-builtins-build-export.c:76
msgid "Override the timestamp of the commit"
msgstr ""

#: app/flatpak-builtins-build-export.c:77
#: app/flatpak-builtins-build-update-repo.c:75
#: app/flatpak-builtins-remote-add.c:83 app/flatpak-builtins-remote-list.c:54
#: app/flatpak-builtins-remote-modify.c:88
msgid "Collection ID"
msgstr ""

#: app/flatpak-builtins-build-export.c:472
#, c-format
msgid "WARNING: Error running desktop-file-validate: %s\n"
msgstr ""

#: app/flatpak-builtins-build-export.c:480
#, c-format
msgid "WARNING: Error reading from desktop-file-validate: %s\n"
msgstr ""

#: app/flatpak-builtins-build-export.c:486
#, fuzzy, c-format
msgid "WARNING: Failed to validate desktop file %s: %s\n"
msgstr "Zlyhalo otvorenie súboru temp"

#: app/flatpak-builtins-build-export.c:513
#, c-format
msgid "WARNING: Can't find Exec key in %s: %s\n"
msgstr ""

#: app/flatpak-builtins-build-export.c:521
#: app/flatpak-builtins-build-export.c:614
#, c-format
msgid "WARNING: Binary not found for Exec line in %s: %s\n"
msgstr ""

#: app/flatpak-builtins-build-export.c:529
#, c-format
msgid "WARNING: Icon not matching app id in %s: %s\n"
msgstr ""

#: app/flatpak-builtins-build-export.c:552
#, c-format
msgid "WARNING: Icon referenced in desktop file but not exported: %s\n"
msgstr ""

#: app/flatpak-builtins-build-export.c:719
#, c-format
msgid "Invalid uri type %s, only http/https supported"
msgstr ""

#: app/flatpak-builtins-build-export.c:737
#, c-format
msgid "Unable to find basename in %s, specify a name explicitly"
msgstr ""

#: app/flatpak-builtins-build-export.c:746
#, c-format
msgid "No slashes allowed in extra data name"
msgstr ""

#: app/flatpak-builtins-build-export.c:758
#, c-format
msgid "Invalid format for sha256 checksum: '%s'"
msgstr ""

#: app/flatpak-builtins-build-export.c:768
#, c-format
msgid "Extra data sizes of zero not supported"
msgstr ""

#: app/flatpak-builtins-build-export.c:830
msgid ""
"LOCATION DIRECTORY [BRANCH] - Create a repository from a build directory"
msgstr ""

#: app/flatpak-builtins-build-export.c:838
msgid "LOCATION and DIRECTORY must be specified"
msgstr ""

#: app/flatpak-builtins-build-export.c:859
#: app/flatpak-builtins-remote-add.c:327
#, fuzzy, c-format
msgid "‘%s’ is not a valid collection ID: %s"
msgstr "„%s“ nie je platným názvom aplikácie: %s"

#: app/flatpak-builtins-build-export.c:904
#: app/flatpak-builtins-build-finish.c:684
msgid "No name specified in the metadata"
msgstr "Nie je určený žiadny názov v metaúdajoch"

#: app/flatpak-builtins-build-export.c:1166
#, c-format
msgid "Commit: %s\n"
msgstr ""

#: app/flatpak-builtins-build-export.c:1167
#, c-format
msgid "Metadata Total: %u\n"
msgstr ""

#: app/flatpak-builtins-build-export.c:1168
#, c-format
msgid "Metadata Written: %u\n"
msgstr ""

#: app/flatpak-builtins-build-export.c:1169
#, c-format
msgid "Content Total: %u\n"
msgstr ""

#: app/flatpak-builtins-build-export.c:1170
#, c-format
msgid "Content Written: %u\n"
msgstr ""

#: app/flatpak-builtins-build-export.c:1171
#, c-format
msgid "Content Bytes Written:"
msgstr ""

#: app/flatpak-builtins-build-finish.c:52
msgid "Command to set"
msgstr "Príkaz, ktorý sa má nastaviť"

#: app/flatpak-builtins-build-finish.c:52 app/flatpak-builtins-run.c:159
#: app/flatpak-main.c:209
msgid "COMMAND"
msgstr "PRÍKAZ"

#: app/flatpak-builtins-build-finish.c:53
msgid "Flatpak version to require"
msgstr ""

#: app/flatpak-builtins-build-finish.c:53
msgid "MAJOR.MINOR.MICRO"
msgstr ""

#: app/flatpak-builtins-build-finish.c:54
msgid "Don't process exports"
msgstr "Nespracuje exporty"

#: app/flatpak-builtins-build-finish.c:55
msgid "Extra data info"
msgstr "Informácie o údajoch navyše"

#: app/flatpak-builtins-build-finish.c:56 app/flatpak-builtins-build-init.c:63
msgid "Add extension point info"
msgstr ""

#: app/flatpak-builtins-build-finish.c:56 app/flatpak-builtins-build-init.c:63
msgid "NAME=VARIABLE[=VALUE]"
msgstr ""

#: app/flatpak-builtins-build-finish.c:57
msgid "Remove extension point info"
msgstr ""

#: app/flatpak-builtins-build-finish.c:57
#: app/flatpak-builtins-build-update-repo.c:79 app/flatpak-builtins-info.c:58
#: app/flatpak-builtins-remote-add.c:88 app/flatpak-builtins-remote-modify.c:94
#: app/flatpak-main.c:182
#, fuzzy
msgid "NAME"
msgstr "NÁZOV_SÚBORU"

#: app/flatpak-builtins-build-finish.c:58
msgid "Set extension priority (only for extensions)"
msgstr ""

#: app/flatpak-builtins-build-finish.c:58
msgid "VALUE"
msgstr ""

#: app/flatpak-builtins-build-finish.c:59
msgid "Change the sdk used for the app"
msgstr ""

#: app/flatpak-builtins-build-finish.c:59
msgid "SDK"
msgstr ""

#: app/flatpak-builtins-build-finish.c:60
msgid "Change the runtime used for the app"
msgstr ""

#: app/flatpak-builtins-build-finish.c:60 app/flatpak-builtins-build-init.c:54
#: app/flatpak-builtins-list.c:53 app/flatpak-builtins-remote-ls.c:58
#: app/flatpak-builtins-run.c:163
msgid "RUNTIME"
msgstr "PROSTREDIE"

#: app/flatpak-builtins-build-finish.c:61
msgid "Set generic metadata option"
msgstr ""

#: app/flatpak-builtins-build-finish.c:61
msgid "GROUP=KEY[=VALUE]"
msgstr ""

#: app/flatpak-builtins-build-finish.c:62
msgid "Don't inherit permissions from runtime"
msgstr ""

#: app/flatpak-builtins-build-finish.c:155
#, c-format
msgid "Not exporting %s, wrong extension\n"
msgstr ""

#: app/flatpak-builtins-build-finish.c:163
#, c-format
msgid "Not exporting %s, non-allowed export filename\n"
msgstr ""

#: app/flatpak-builtins-build-finish.c:167
#, fuzzy, c-format
msgid "Exporting %s\n"
msgstr "Aktualizovanie zhrnutia\n"

#: app/flatpak-builtins-build-finish.c:440
#, c-format
msgid "More than one executable found\n"
msgstr ""

#: app/flatpak-builtins-build-finish.c:451
#, c-format
msgid "Using %s as command\n"
msgstr ""

#: app/flatpak-builtins-build-finish.c:456
#, c-format
msgid "No executable found\n"
msgstr ""

#: app/flatpak-builtins-build-finish.c:511
#, c-format
msgid "Invalid --require-version argument: %s"
msgstr ""

#: app/flatpak-builtins-build-finish.c:543
#, c-format
msgid "Too few elements in --extra-data argument %s"
msgstr ""

#: app/flatpak-builtins-build-finish.c:575
#, c-format
msgid ""
"Too few elements in --metadata argument %s, format should be "
"GROUP=KEY[=VALUE]]"
msgstr ""

#: app/flatpak-builtins-build-finish.c:597
#: app/flatpak-builtins-build-init.c:458
#, c-format
msgid ""
"Too few elements in --extension argument %s, format should be "
"NAME=VAR[=VALUE]"
msgstr ""

#: app/flatpak-builtins-build-finish.c:603
#: app/flatpak-builtins-build-init.c:461
#, fuzzy, c-format
msgid "Invalid extension name %s"
msgstr "Neplatný identifikátor pid %s"

#: app/flatpak-builtins-build-finish.c:646
#, fuzzy
msgid "DIRECTORY - Finalize a build directory"
msgstr "ADRESÁR [PRÍKAZ [parametre...]] - Zostavenie v adresári"

#: app/flatpak-builtins-build-finish.c:668
#, c-format
msgid "Build directory %s not initialized"
msgstr "Adresár zostavenia %s nie je inicializovaný"

#: app/flatpak-builtins-build-finish.c:689
#, c-format
msgid "Build directory %s already finalized"
msgstr "Adresár zostavenia %s je už uzavretý"

#: app/flatpak-builtins-build-finish.c:702
#, c-format
msgid "Please review the exported files and the metadata\n"
msgstr ""

#: app/flatpak-builtins-build-import-bundle.c:47
msgid "Override the ref used for the imported bundle"
msgstr ""

#: app/flatpak-builtins-build-import-bundle.c:47
msgid "REF"
msgstr ""

#: app/flatpak-builtins-build-import-bundle.c:48
msgid "Import oci image instead of flatpak bundle"
msgstr ""

#: app/flatpak-builtins-build-import-bundle.c:77
#: app/flatpak-builtins-build-import-bundle.c:105
#, fuzzy, c-format
msgid "Importing %s (%s)\n"
msgstr "Aktualizovanie: %s z %s\n"

#: app/flatpak-builtins-build-import-bundle.c:126
msgid "LOCATION FILENAME - Import a file bundle into a local repository"
msgstr ""

#: app/flatpak-builtins-build-import-bundle.c:133
msgid "LOCATION and FILENAME must be specified"
msgstr ""

#: app/flatpak-builtins-build-init.c:53 app/flatpak-builtins-info.c:55
#: app/flatpak-builtins-run.c:158
msgid "Arch to use"
msgstr "Architektúra , ktorá sa má použiť"

#: app/flatpak-builtins-build-init.c:54
msgid "Initialize var from named runtime"
msgstr ""

#: app/flatpak-builtins-build-init.c:55
msgid "Initialize apps from named app"
msgstr ""

#: app/flatpak-builtins-build-init.c:55
msgid "APP"
msgstr "APLIKÁCIA"

#: app/flatpak-builtins-build-init.c:56
msgid "Specify version for --base"
msgstr ""

#: app/flatpak-builtins-build-init.c:56 app/flatpak-builtins-run.c:164
msgid "VERSION"
msgstr "VERZIA"

#: app/flatpak-builtins-build-init.c:57
msgid "Include this base extension"
msgstr "Zahrnie toto základné rozšírenie"

#: app/flatpak-builtins-build-init.c:57 app/flatpak-builtins-build-init.c:62
msgid "EXTENSION"
msgstr "ROZŠÍRENIE"

#: app/flatpak-builtins-build-init.c:58
msgid "Extension tag to use if building extension"
msgstr ""

#: app/flatpak-builtins-build-init.c:58
#, fuzzy
msgid "EXTENSION_TAG"
msgstr "ROZŠÍRENIE"

#: app/flatpak-builtins-build-init.c:59
msgid "Initialize /usr with a writable copy of the sdk"
msgstr ""

#: app/flatpak-builtins-build-init.c:60
msgid "Specify the build type (app, runtime, extension)"
msgstr ""

#: app/flatpak-builtins-build-init.c:60
msgid "TYPE"
msgstr ""

#: app/flatpak-builtins-build-init.c:61
msgid "Add a tag"
msgstr "Pridá značku"

#: app/flatpak-builtins-build-init.c:61
msgid "TAG"
msgstr "ZNAČKA"

#: app/flatpak-builtins-build-init.c:62
msgid "Include this sdk extension in /usr"
msgstr ""

#: app/flatpak-builtins-build-init.c:64
msgid "Where to store sdk (defaults to 'usr')"
msgstr ""

#: app/flatpak-builtins-build-init.c:65
msgid "Re-initialize the sdk/var"
msgstr ""

#: app/flatpak-builtins-build-init.c:118
#, fuzzy, c-format
msgid "Requested extension %s/%s/%s is only partially installed"
msgstr "Požadované rozšírenie %s je nainštalované iba čiastočne"

#: app/flatpak-builtins-build-init.c:147
#, fuzzy, c-format
msgid "Requested extension %s/%s/%s not installed"
msgstr "Požadované rozšírenie %s je nainštalované iba čiastočne"

#: app/flatpak-builtins-build-init.c:207
msgid ""
"DIRECTORY APPNAME SDK RUNTIME [BRANCH] - Initialize a directory for building"
msgstr ""

#: app/flatpak-builtins-build-init.c:214
msgid "RUNTIME must be specified"
msgstr "PROSTREDIE musí byť určené"

#: app/flatpak-builtins-build-init.c:235
#, c-format
msgid "'%s' is not a valid build type name, use app, runtime or extension"
msgstr ""

#: app/flatpak-builtins-build-init.c:241 app/flatpak-builtins-override.c:79
#, c-format
msgid "'%s' is not a valid application name: %s"
msgstr "„%s“ nie je platným názvom aplikácie: %s"

#: app/flatpak-builtins-build-init.c:295
#, c-format
msgid "Build directory %s already initialized"
msgstr "Adresár zostavenia %s je už inicializovaný"

#: app/flatpak-builtins-build-sign.c:42 app/flatpak-builtins-install.c:67
#: app/flatpak-builtins-remote-info.c:54
msgid "Arch to install for"
msgstr "Architektúra, pre ktorú sa má inštalovať"

#: app/flatpak-builtins-build-sign.c:43 app/flatpak-builtins-create-usb.c:48
#: app/flatpak-builtins-install.c:74 app/flatpak-builtins-remote-info.c:56
#: app/flatpak-builtins-uninstall.c:58 app/flatpak-builtins-update.c:64
msgid "Look for runtime with the specified name"
msgstr ""

#: app/flatpak-builtins-build-sign.c:66
#, fuzzy
msgid "LOCATION [ID [BRANCH]] - Sign an application or runtime"
msgstr "Podpíše aplikáciu alebo rozhranie"

#: app/flatpak-builtins-build-sign.c:73
#: app/flatpak-builtins-build-update-repo.c:499
#: app/flatpak-builtins-remote-add.c:320 app/flatpak-builtins-repo.c:739
msgid "LOCATION must be specified"
msgstr "UMIESTNENIE musí byť určené"

#: app/flatpak-builtins-build-sign.c:94
msgid "No gpg key ids specified"
msgstr ""

#: app/flatpak-builtins-build-update-repo.c:68
msgid "Redirect this repo to a new URL"
msgstr ""

#: app/flatpak-builtins-build-update-repo.c:69
msgid "A nice name to use for this repository"
msgstr ""

#: app/flatpak-builtins-build-update-repo.c:69
#: app/flatpak-builtins-remote-add.c:77 app/flatpak-builtins-remote-modify.c:82
msgid "TITLE"
msgstr "NÁZOV"

#: app/flatpak-builtins-build-update-repo.c:70
msgid "A one-line comment for this repository"
msgstr ""

#: app/flatpak-builtins-build-update-repo.c:70
#: app/flatpak-builtins-remote-add.c:78 app/flatpak-builtins-remote-modify.c:83
#, fuzzy
msgid "COMMENT"
msgstr "ZAČLENENIE"

#: app/flatpak-builtins-build-update-repo.c:71
msgid "A full-paragraph description for this repository"
msgstr ""

#: app/flatpak-builtins-build-update-repo.c:71
#: app/flatpak-builtins-remote-add.c:79 app/flatpak-builtins-remote-modify.c:84
msgid "DESCRIPTION"
msgstr ""

#: app/flatpak-builtins-build-update-repo.c:72
#, fuzzy
msgid "URL for a website for this repository"
msgstr "Exportuje adresár zostavenia do repozitára"

#: app/flatpak-builtins-build-update-repo.c:73
#, fuzzy
msgid "URL for an icon for this repository"
msgstr "Aktualizuje súbor zhrnutia v repozitári"

#: app/flatpak-builtins-build-update-repo.c:74
msgid "Default branch to use for this repository"
msgstr ""

#: app/flatpak-builtins-build-update-repo.c:74
#: app/flatpak-builtins-remote-add.c:82 app/flatpak-builtins-remote-modify.c:87
#: app/flatpak-builtins-repo.c:713 app/flatpak-builtins-repo.c:714
#: app/flatpak-builtins-run.c:161
msgid "BRANCH"
msgstr "VETVA"

#: app/flatpak-builtins-build-update-repo.c:75
#: app/flatpak-builtins-remote-add.c:83 app/flatpak-builtins-remote-modify.c:88
msgid "COLLECTION-ID"
msgstr ""

#. Translators: A sideload is when you install from a local USB drive rather than the Internet.
#: app/flatpak-builtins-build-update-repo.c:77
msgid ""
"Permanently deploy collection ID to client remote configurations, only for "
"sideload support"
msgstr ""

#: app/flatpak-builtins-build-update-repo.c:78
msgid "Permanently deploy collection ID to client remote configurations"
msgstr ""

#: app/flatpak-builtins-build-update-repo.c:79
#, fuzzy
msgid "Name of authenticator for this repository"
msgstr "Aktualizuje súbor zhrnutia v repozitári"

#: app/flatpak-builtins-build-update-repo.c:80
#, fuzzy
msgid "Autoinstall authenticator for this repository"
msgstr "Aktualizuje súbor zhrnutia v repozitári"

#: app/flatpak-builtins-build-update-repo.c:81
#, fuzzy
msgid "Don't autoinstall authenticator for this repository"
msgstr "Aktualizuje súbor zhrnutia v repozitári"

#: app/flatpak-builtins-build-update-repo.c:82
#: app/flatpak-builtins-remote-add.c:89
#, fuzzy
msgid "Authenticator option"
msgstr "Zobrazí voľby pomocníka"

#: app/flatpak-builtins-build-update-repo.c:82
#: app/flatpak-builtins-remote-add.c:89 app/flatpak-builtins-remote-modify.c:95
msgid "KEY=VALUE"
msgstr ""

#: app/flatpak-builtins-build-update-repo.c:83
msgid "Import new default GPG public key from FILE"
msgstr ""

#: app/flatpak-builtins-build-update-repo.c:84
msgid "GPG Key ID to sign the summary with"
msgstr ""

#: app/flatpak-builtins-build-update-repo.c:86
msgid "Generate delta files"
msgstr ""

#: app/flatpak-builtins-build-update-repo.c:88
msgid "Don't update the appstream branch"
msgstr ""

#: app/flatpak-builtins-build-update-repo.c:89
msgid "Max parallel jobs when creating deltas (default: NUMCPUs)"
msgstr ""

#: app/flatpak-builtins-build-update-repo.c:89
msgid "NUM-JOBS"
msgstr ""

#: app/flatpak-builtins-build-update-repo.c:90
msgid "Don't create deltas matching refs"
msgstr ""

#: app/flatpak-builtins-build-update-repo.c:91
msgid "Prune unused objects"
msgstr ""

#: app/flatpak-builtins-build-update-repo.c:92
msgid "Prune but don't actually remove anything"
msgstr ""

#: app/flatpak-builtins-build-update-repo.c:93
msgid "Only traverse DEPTH parents for each commit (default: -1=infinite)"
msgstr ""

#: app/flatpak-builtins-build-update-repo.c:93
msgid "DEPTH"
msgstr "HĹBKA"

#: app/flatpak-builtins-build-update-repo.c:223
#, c-format
msgid "Generating delta: %s (%.10s)\n"
msgstr "Generovanie delta súboru: %s (%.10s)\n"

#: app/flatpak-builtins-build-update-repo.c:225
#, c-format
msgid "Generating delta: %s (%.10s-%.10s)\n"
msgstr "Generovanie delta súboru: %s (%.10s-%.10s)\n"

#: app/flatpak-builtins-build-update-repo.c:233
#, fuzzy, c-format
msgid "Failed to generate delta %s (%.10s): "
msgstr "Zlyhalo generovanie delta súboru %s (%.10s): %s\n"

#: app/flatpak-builtins-build-update-repo.c:236
#, fuzzy, c-format
msgid "Failed to generate delta %s (%.10s-%.10s): "
msgstr "Zlyhalo generovanie delta súboru %s (%.10s-%.10s): %s\n"

#: app/flatpak-builtins-build-update-repo.c:492
msgid "LOCATION - Update repository metadata"
msgstr ""

#: app/flatpak-builtins-build-update-repo.c:609
#, c-format
msgid "Updating appstream branch\n"
msgstr ""

#: app/flatpak-builtins-build-update-repo.c:638
#, c-format
msgid "Updating summary\n"
msgstr "Aktualizovanie zhrnutia\n"

#: app/flatpak-builtins-build-update-repo.c:664
#, c-format
msgid "Total objects: %u\n"
msgstr "Objektov celkom: %u\n"

#: app/flatpak-builtins-build-update-repo.c:666
#, c-format
msgid "No unreachable objects\n"
msgstr ""

#: app/flatpak-builtins-build-update-repo.c:668
#, c-format
msgid "Deleted %u objects, %s freed\n"
msgstr "Odstránených %u objektov, %s uvoľnených\n"

#: app/flatpak-builtins-config.c:41
msgid "List configuration keys and values"
msgstr ""

#: app/flatpak-builtins-config.c:42
msgid "Get configuration for KEY"
msgstr ""

#: app/flatpak-builtins-config.c:43
msgid "Set configuration for KEY to VALUE"
msgstr ""

#: app/flatpak-builtins-config.c:44
msgid "Unset configuration for KEY"
msgstr ""

#: app/flatpak-builtins-config.c:149
#, c-format
msgid "'%s' does not look like a language/locale code"
msgstr ""

#: app/flatpak-builtins-config.c:172
#, c-format
msgid "'%s' does not look like a language code"
msgstr ""

#: app/flatpak-builtins-config.c:190
#, fuzzy, c-format
msgid "'%s' is not a valid value (use 'true' or 'false')"
msgstr "„%s“ nie je platným repozitárom"

#: app/flatpak-builtins-config.c:262
#, fuzzy, c-format
msgid "Unknown configure key '%s'"
msgstr "Neznámy príkaz „%s“"

#: app/flatpak-builtins-config.c:284
#, fuzzy
msgid "Too many arguments for --list"
msgstr "Príliš veľa parametrov"

#: app/flatpak-builtins-config.c:314 app/flatpak-builtins-config.c:362
#, fuzzy
msgid "You must specify KEY"
msgstr "NÁZOV musí byť určený"

#: app/flatpak-builtins-config.c:316
#, fuzzy
msgid "Too many arguments for --get"
msgstr "Príliš veľa parametrov"

#: app/flatpak-builtins-config.c:338
#, fuzzy
msgid "You must specify KEY and VALUE"
msgstr "NÁZOV musí byť určený"

#: app/flatpak-builtins-config.c:340
#, fuzzy
msgid "Too many arguments for --set"
msgstr "Príliš veľa parametrov"

#: app/flatpak-builtins-config.c:364
#, fuzzy
msgid "Too many arguments for --unset"
msgstr "Príliš veľa parametrov"

#: app/flatpak-builtins-config.c:383
msgid "[KEY [VALUE]] - Manage configuration"
msgstr ""

#: app/flatpak-builtins-config.c:394
msgid "Can only use one of --list, --get, --set or --unset"
msgstr ""

#: app/flatpak-builtins-config.c:408
msgid "Must specify one of --list, --get, --set or --unset"
msgstr ""

#: app/flatpak-builtins-create-usb.c:45 app/flatpak-builtins-install.c:75
#: app/flatpak-builtins-remote-info.c:57 app/flatpak-builtins-uninstall.c:59
#: app/flatpak-builtins-update.c:65
msgid "Look for app with the specified name"
msgstr ""

#: app/flatpak-builtins-create-usb.c:46
#, fuzzy
msgid "Arch to copy"
msgstr "Architektúra. ktorá sa má zobraziť"

#: app/flatpak-builtins-create-usb.c:47
#, fuzzy
msgid "DEST"
msgstr "CIEĽ=ZDROJ"

#: app/flatpak-builtins-create-usb.c:49
msgid "Allow partial commits in the created repo"
msgstr ""

#: app/flatpak-builtins-create-usb.c:125 app/flatpak-builtins-create-usb.c:165
#, c-format
msgid ""
"Warning: Related ref ‘%s’ is partially installed. Use --allow-partial to "
"suppress this message.\n"
msgstr ""

#: app/flatpak-builtins-create-usb.c:158
#, c-format
msgid "Warning: Omitting related ref ‘%s’ because it is not installed.\n"
msgstr ""

#: app/flatpak-builtins-create-usb.c:175
#, c-format
msgid ""
"Warning: Omitting related ref ‘%s’ because its remote ‘%s’ does not have a "
"collection ID set.\n"
msgstr ""

#: app/flatpak-builtins-create-usb.c:187
#, c-format
msgid "Warning: Omitting related ref ‘%s’ because it's extra-data.\n"
msgstr ""

#: app/flatpak-builtins-create-usb.c:262 app/flatpak-builtins-create-usb.c:637
#, c-format
msgid ""
"Remote ‘%s’ does not have a collection ID set, which is required for P2P "
"distribution of ‘%s’."
msgstr ""

#: app/flatpak-builtins-create-usb.c:272
#, c-format
msgid "Warning: Omitting ref ‘%s’ (runtime of ‘%s’) because it's extra-data.\n"
msgstr ""

#: app/flatpak-builtins-create-usb.c:484
msgid "MOUNT-PATH [REF…] - Copy apps or runtimes onto removable media"
msgstr ""

#: app/flatpak-builtins-create-usb.c:493
#, fuzzy
msgid "MOUNT-PATH and REF must be specified"
msgstr "ADRESÁR musí byť určený"

#: app/flatpak-builtins-create-usb.c:607
#, c-format
msgid "Ref ‘%s’ found in multiple installations: %s. You must specify one."
msgstr ""

#: app/flatpak-builtins-create-usb.c:620
#, c-format
msgid "Refs must all be in the same installation (found in %s and %s)."
msgstr ""

#: app/flatpak-builtins-create-usb.c:670
#, c-format
msgid ""
"Warning: Ref ‘%s’ is partially installed. Use --allow-partial to suppress "
"this message.\n"
msgstr ""

#: app/flatpak-builtins-create-usb.c:681
#, c-format
msgid "Installed ref ‘%s’ is extra-data, and cannot be distributed offline"
msgstr ""

#: app/flatpak-builtins-create-usb.c:721
#, fuzzy, c-format
msgid "Warning: Couldn't update repo metadata for remote ‘%s’: %s\n"
msgstr "Nepodarilo sa aktualizovať metaúdaje navyše pre %s"

#: app/flatpak-builtins-create-usb.c:751
#, fuzzy, c-format
msgid "Warning: Couldn't update appstream data for remote ‘%s’ arch ‘%s’: %s\n"
msgstr "Nepodarilo sa aktualizovať metaúdaje navyše pre %s"

#. Print a warning if both appstream and appstream2 are missing
#: app/flatpak-builtins-create-usb.c:784
#, fuzzy, c-format
msgid ""
"Warning: Couldn't find appstream data for remote ‘%s’ arch ‘%s’: %s; %s\n"
msgstr "Nepodarilo sa aktualizovať metaúdaje navyše pre %s"

#. Appstream2 is only for efficiency, so just print a debug message
#: app/flatpak-builtins-create-usb.c:790
#, fuzzy, c-format
msgid "Couldn't find appstream2 data for remote ‘%s’ arch ‘%s’: %s\n"
msgstr ""
"Chyba počas aktualizácie metaúdajov navyše pre „%s“: %s\n"
"\n"

#: app/flatpak-builtins-document-export.c:62
msgid "Create a unique document reference"
msgstr ""

#: app/flatpak-builtins-document-export.c:63
msgid "Make the document transient for the current session"
msgstr ""

#: app/flatpak-builtins-document-export.c:64
msgid "Don't require the file to exist already"
msgstr ""

#: app/flatpak-builtins-document-export.c:65
msgid "Give the app read permissions"
msgstr ""

#: app/flatpak-builtins-document-export.c:66
msgid "Give the app write permissions"
msgstr ""

#: app/flatpak-builtins-document-export.c:67
msgid "Give the app delete permissions"
msgstr ""

#: app/flatpak-builtins-document-export.c:68
msgid "Give the app permissions to grant further permissions"
msgstr ""

#: app/flatpak-builtins-document-export.c:69
msgid "Revoke read permissions of the app"
msgstr ""

#: app/flatpak-builtins-document-export.c:70
msgid "Revoke write permissions of the app"
msgstr ""

#: app/flatpak-builtins-document-export.c:71
msgid "Revoke delete permissions of the app"
msgstr ""

#: app/flatpak-builtins-document-export.c:72
msgid "Revoke the permission to grant further permissions"
msgstr ""

#: app/flatpak-builtins-document-export.c:73
msgid "Add permissions for this app"
msgstr ""

#: app/flatpak-builtins-document-export.c:73
msgid "APPID"
msgstr ""

#: app/flatpak-builtins-document-export.c:100
msgid "FILE - Export a file to apps"
msgstr ""

#: app/flatpak-builtins-document-export.c:109
#: app/flatpak-builtins-document-info.c:72
#: app/flatpak-builtins-document-unexport.c:67
msgid "FILE must be specified"
msgstr "SÚBOR musí byť určený"

#: app/flatpak-builtins-document-info.c:63
msgid "FILE - Get information about an exported file"
msgstr ""

#: app/flatpak-builtins-document-info.c:100
#: app/flatpak-builtins-document-unexport.c:94
#, c-format
msgid "Not exported\n"
msgstr "Neexportované\n"

#: app/flatpak-builtins-document-list.c:43 app/flatpak-builtins-history.c:53
#: app/flatpak-builtins-list.c:54 app/flatpak-builtins-ps.c:43
#: app/flatpak-builtins-remote-list.c:45 app/flatpak-builtins-remote-ls.c:59
#: app/flatpak-builtins-search.c:38
#, fuzzy
msgid "What information to show"
msgstr "Vypíše informácie o verzii a skončí"

#: app/flatpak-builtins-document-list.c:43 app/flatpak-builtins-history.c:53
#: app/flatpak-builtins-list.c:54 app/flatpak-builtins-ps.c:43
#: app/flatpak-builtins-remote-list.c:45 app/flatpak-builtins-remote-ls.c:59
#: app/flatpak-builtins-search.c:38
msgid "FIELD,…"
msgstr ""

#: app/flatpak-builtins-document-list.c:44 app/flatpak-builtins-history.c:54
#: app/flatpak-builtins-list.c:52 app/flatpak-builtins-permission-list.c:43
#: app/flatpak-builtins-permission-show.c:43 app/flatpak-builtins-ps.c:44
#: app/flatpak-builtins-remote-list.c:46 app/flatpak-builtins-remote-ls.c:63
#: app/flatpak-builtins-repo.c:717 app/flatpak-builtins-search.c:39
#, fuzzy
msgid "Show output in JSON format"
msgstr "Zobrazí voľby pomocníka"

#: app/flatpak-builtins-document-list.c:49
#, fuzzy
msgid "Show the document ID"
msgstr "Zobrazí referenciu"

#: app/flatpak-builtins-document-list.c:50
msgid "Path"
msgstr ""

#: app/flatpak-builtins-document-list.c:50
#: app/flatpak-builtins-document-list.c:51
#, fuzzy
msgid "Show the document path"
msgstr "Zobrazí referenciu"

#: app/flatpak-builtins-document-list.c:51 app/flatpak-builtins-list.c:66
#: app/flatpak-builtins-remote-ls.c:74
msgid "Origin"
msgstr ""

#: app/flatpak-builtins-document-list.c:52 app/flatpak-builtins-history.c:62
#: app/flatpak-builtins-ps.c:52
#, fuzzy
msgid "Application"
msgstr "Spustí aplikáciu"

#: app/flatpak-builtins-document-list.c:52
#, fuzzy
msgid "Show applications with permission"
msgstr "Zobrazí voľby pomocníka"

#: app/flatpak-builtins-document-list.c:53
#: app/flatpak-builtins-permission-list.c:182
#: app/flatpak-builtins-permission-show.c:145
#, fuzzy
msgid "Permissions"
msgstr "Zobrazí voľby pomocníka"

#: app/flatpak-builtins-document-list.c:53
#, fuzzy
msgid "Show permissions for applications"
msgstr "Zobrazí voľby pomocníka"

#: app/flatpak-builtins-document-list.c:161
#, fuzzy, c-format
msgid "No documents found\n"
msgstr "Nič nevyhovuje názvu %s"

#: app/flatpak-builtins-document-list.c:180
msgid "[APPID] - List exported files"
msgstr ""

#: app/flatpak-builtins-document-unexport.c:43
#, fuzzy
msgid "Specify the document ID"
msgstr "Zobrazí referenciu"

#: app/flatpak-builtins-document-unexport.c:58
msgid "FILE - Unexport a file to apps"
msgstr ""

#: app/flatpak-builtins-enter.c:88
msgid "INSTANCE COMMAND [ARGUMENT…] - Run a command inside a running sandbox"
msgstr ""

#: app/flatpak-builtins-enter.c:111
#, fuzzy
msgid "INSTANCE and COMMAND must be specified"
msgstr "UMIESTNENIE musí byť určené"

#: app/flatpak-builtins-enter.c:138
#, fuzzy, c-format
msgid "%s is neither a pid nor an application or instance ID"
msgstr "„%s“ nie je platným názvom aplikácie: %s"

#: app/flatpak-builtins-enter.c:144
msgid "entering not supported (need unprivileged user namespaces, or sudo -E)"
msgstr ""

#: app/flatpak-builtins-enter.c:145
#, c-format
msgid "No such pid %s"
msgstr "Identifikátor pid %s neexistuje"

#: app/flatpak-builtins-enter.c:158
msgid "Can't read cwd"
msgstr ""

#: app/flatpak-builtins-enter.c:163
msgid "Can't read root"
msgstr ""

#: app/flatpak-builtins-enter.c:191
#, c-format
msgid "Invalid %s namespace for pid %d"
msgstr ""

#: app/flatpak-builtins-enter.c:202
#, c-format
msgid "Invalid %s namespace for self"
msgstr ""

#: app/flatpak-builtins-enter.c:216
#, c-format
msgid "Can't open %s namespace: %s"
msgstr ""

#: app/flatpak-builtins-enter.c:226
msgid "entering not supported (need unprivileged user namespaces)"
msgstr ""

#: app/flatpak-builtins-enter.c:227
#, c-format
msgid "Can't enter %s namespace: %s"
msgstr ""

#: app/flatpak-builtins-enter.c:234
msgid "Can't chdir"
msgstr ""

#: app/flatpak-builtins-enter.c:237
msgid "Can't chroot"
msgstr ""

#: app/flatpak-builtins-enter.c:240
msgid "Can't switch gid"
msgstr ""

#: app/flatpak-builtins-enter.c:243
msgid "Can't switch uid"
msgstr ""

#: app/flatpak-builtins-history.c:50
msgid "Only show changes after TIME"
msgstr ""

#: app/flatpak-builtins-history.c:50 app/flatpak-builtins-history.c:51
#, fuzzy
msgid "TIME"
msgstr "PROSTREDIE"

#: app/flatpak-builtins-history.c:51
msgid "Only show changes before TIME"
msgstr ""

#: app/flatpak-builtins-history.c:52
#, fuzzy
msgid "Show newest entries first"
msgstr "Zobrazí voľby pomocníka"

#: app/flatpak-builtins-history.c:59
msgid "Time"
msgstr ""

#: app/flatpak-builtins-history.c:59
#, fuzzy
msgid "Show when the change happened"
msgstr "Zobrazí referenciu"

#: app/flatpak-builtins-history.c:60
msgid "Change"
msgstr ""

#: app/flatpak-builtins-history.c:60
msgid "Show the kind of change"
msgstr ""

#: app/flatpak-builtins-history.c:61 app/flatpak-builtins-list.c:68
#: app/flatpak-builtins-remote-ls.c:75 app/flatpak-builtins-repo.c:335
msgid "Ref"
msgstr ""

#: app/flatpak-builtins-history.c:61 app/flatpak-builtins-list.c:68
#: app/flatpak-builtins-remote-ls.c:75
#, fuzzy
msgid "Show the ref"
msgstr "Zobrazí referenciu"

#: app/flatpak-builtins-history.c:62
#, fuzzy
msgid "Show the application/runtime ID"
msgstr "Spustí aplikáciu"

#: app/flatpak-builtins-history.c:63 app/flatpak-builtins-list.c:64
#: app/flatpak-builtins-ps.c:53 app/flatpak-builtins-remote-ls.c:73
#: app/flatpak-cli-transaction.c:1435
msgid "Arch"
msgstr ""

#: app/flatpak-builtins-history.c:63 app/flatpak-builtins-list.c:64
#: app/flatpak-builtins-ps.c:53 app/flatpak-builtins-remote-ls.c:73
msgid "Show the architecture"
msgstr ""

#: app/flatpak-builtins-history.c:64 app/flatpak-builtins-list.c:63
#: app/flatpak-builtins-ps.c:54 app/flatpak-builtins-remote-ls.c:72
#: app/flatpak-builtins-search.c:48 app/flatpak-cli-transaction.c:1438
#, fuzzy
msgid "Branch"
msgstr "Vetva, ktorá sa má použiť"

#: app/flatpak-builtins-history.c:64 app/flatpak-builtins-list.c:63
#: app/flatpak-builtins-remote-ls.c:72
#, fuzzy
msgid "Show the branch"
msgstr "Zobrazí referenciu"

#: app/flatpak-builtins-history.c:65 app/flatpak-builtins-list.c:67
#, fuzzy
msgid "Installation"
msgstr "Inštalovanie: %s\n"

#: app/flatpak-builtins-history.c:65
#, fuzzy
msgid "Show the affected installation"
msgstr "Nepodarilo sa nájsť inštaláciu %s"

#: app/flatpak-builtins-history.c:66 app/flatpak-cli-transaction.c:1452
#, fuzzy
msgid "Remote"
msgstr "Žiadny vzdialený repozitár %s"

#: app/flatpak-builtins-history.c:66
#, fuzzy
msgid "Show the remote"
msgstr "Zobrazí referenciu"

#: app/flatpak-builtins-history.c:67 app/flatpak-builtins-ps.c:55
#: app/flatpak-builtins-remote-ls.c:76
msgid "Commit"
msgstr ""

#: app/flatpak-builtins-history.c:67
#, fuzzy
msgid "Show the current commit"
msgstr "Zobrazí referenciu"

#: app/flatpak-builtins-history.c:68
#, fuzzy
msgid "Old Commit"
msgstr "Zobrazí začlenenie"

#: app/flatpak-builtins-history.c:68
#, fuzzy
msgid "Show the previous commit"
msgstr "Zobrazí referenciu"

#: app/flatpak-builtins-history.c:69
#, fuzzy
msgid "Show the remote URL"
msgstr "Zobrazí referenciu"

#: app/flatpak-builtins-history.c:70 app/flatpak-cli-transaction.c:700
msgid "User"
msgstr ""

#: app/flatpak-builtins-history.c:70
#, fuzzy
msgid "Show the user doing the change"
msgstr "Zobrazí referenciu"

#: app/flatpak-builtins-history.c:71
msgid "Tool"
msgstr ""

#: app/flatpak-builtins-history.c:71
msgid "Show the tool that was used"
msgstr ""

#: app/flatpak-builtins-history.c:72 app/flatpak-builtins-list.c:62
#: app/flatpak-builtins-remote-ls.c:71 app/flatpak-builtins-search.c:47
msgid "Version"
msgstr ""

#: app/flatpak-builtins-history.c:72
#, fuzzy
msgid "Show the Flatpak version"
msgstr "Spustí aplikáciu"

#: app/flatpak-builtins-history.c:91
#, fuzzy, c-format
msgid "Failed to get journal data (%s): %s"
msgstr "Zlyhalo čítanie začlenenia %s: "

#: app/flatpak-builtins-history.c:146
#, fuzzy, c-format
msgid "Failed to open journal: %s"
msgstr "Zlyhalo otvorenie dočasného súboru flatpak-info"

#: app/flatpak-builtins-history.c:153
#, fuzzy, c-format
msgid "Failed to add match to journal: %s"
msgstr "Zlyhalo čítanie začlenenia %s: "

#: app/flatpak-builtins-history.c:471
msgid " - Show history"
msgstr ""

#: app/flatpak-builtins-history.c:490
#, c-format
msgid "Failed to parse the --since option"
msgstr ""

#: app/flatpak-builtins-history.c:501
#, c-format
msgid "Failed to parse the --until option"
msgstr ""

#: app/flatpak-builtins-info.c:56
msgid "Show user installations"
msgstr ""

#: app/flatpak-builtins-info.c:57
msgid "Show system-wide installations"
msgstr ""

#: app/flatpak-builtins-info.c:58
msgid "Show specific system-wide installations"
msgstr ""

#: app/flatpak-builtins-info.c:59 app/flatpak-builtins-remote-info.c:59
msgid "Show ref"
msgstr "Zobrazí referenciu"

#: app/flatpak-builtins-info.c:60 app/flatpak-builtins-remote-info.c:60
msgid "Show commit"
msgstr "Zobrazí začlenenie"

#: app/flatpak-builtins-info.c:61
msgid "Show origin"
msgstr "Zobrazí pôvod"

#: app/flatpak-builtins-info.c:62
#, fuzzy
msgid "Show size"
msgstr "Zobrazí referenciu"

#: app/flatpak-builtins-info.c:63 app/flatpak-builtins-remote-info.c:62
msgid "Show metadata"
msgstr ""

#: app/flatpak-builtins-info.c:64 app/flatpak-builtins-remote-info.c:63
#, fuzzy
msgid "Show runtime"
msgstr "Zobrazí referenciu"

#: app/flatpak-builtins-info.c:65 app/flatpak-builtins-remote-info.c:64
#, fuzzy
msgid "Show sdk"
msgstr "Zobrazí referenciu"

#: app/flatpak-builtins-info.c:66
#, fuzzy
msgid "Show permissions"
msgstr "Zobrazí voľby pomocníka"

#: app/flatpak-builtins-info.c:67
#, fuzzy
msgid "Query file access"
msgstr ""
"\n"
"Správa prístupu k súborom"

#: app/flatpak-builtins-info.c:67 app/flatpak-builtins-install.c:82
#: app/flatpak-builtins-install.c:88 app/flatpak-builtins-preinstall.c:68
#: app/flatpak-builtins-run.c:182 app/flatpak-builtins-run.c:184
#: app/flatpak-builtins-update.c:67 app/flatpak-builtins-update.c:71
msgid "PATH"
msgstr "CESTA"

#: app/flatpak-builtins-info.c:68
#, fuzzy
msgid "Show extensions"
msgstr "Zobrazí voľby pomocníka"

#: app/flatpak-builtins-info.c:69
#, fuzzy
msgid "Show location"
msgstr "Zobrazí voľby pomocníka"

#: app/flatpak-builtins-info.c:116
msgid "NAME [BRANCH] - Get info about an installed app or runtime"
msgstr ""

#: app/flatpak-builtins-info.c:123 app/flatpak-builtins-remote-add.c:317
#: app/flatpak-builtins-remote-delete.c:63
msgid "NAME must be specified"
msgstr "NÁZOV musí byť určený"

#: app/flatpak-builtins-info.c:196
msgid "ref not present in origin"
msgstr ""

#: app/flatpak-builtins-info.c:211 app/flatpak-builtins-remote-info.c:217
#, c-format
msgid "Warning: Commit has no flatpak metadata\n"
msgstr ""

#: app/flatpak-builtins-info.c:217 app/flatpak-builtins-info.c:259
#: app/flatpak-builtins-info.c:455 app/flatpak-builtins-info.c:513
#: app/flatpak-builtins-remote-info.c:236
#: app/flatpak-builtins-remote-info.c:271
msgid "ID:"
msgstr ""

#: app/flatpak-builtins-info.c:218 app/flatpak-builtins-info.c:260
#: app/flatpak-builtins-remote-info.c:237
#: app/flatpak-builtins-remote-info.c:272
msgid "Ref:"
msgstr ""

#: app/flatpak-builtins-info.c:219 app/flatpak-builtins-info.c:261
#: app/flatpak-builtins-remote-info.c:238
#: app/flatpak-builtins-remote-info.c:273
msgid "Arch:"
msgstr ""

#: app/flatpak-builtins-info.c:220 app/flatpak-builtins-info.c:262
#: app/flatpak-builtins-remote-info.c:239
#: app/flatpak-builtins-remote-info.c:274
#, fuzzy
msgid "Branch:"
msgstr "Vetva, ktorá sa má použiť"

#: app/flatpak-builtins-info.c:222 app/flatpak-builtins-info.c:264
#: app/flatpak-builtins-remote-info.c:241
#: app/flatpak-builtins-remote-info.c:276
#, fuzzy
msgid "Version:"
msgstr "Zobrazí voľby pomocníka"

#: app/flatpak-builtins-info.c:224 app/flatpak-builtins-info.c:266
#: app/flatpak-builtins-remote-info.c:243
#: app/flatpak-builtins-remote-info.c:278
msgid "License:"
msgstr ""

#: app/flatpak-builtins-info.c:226 app/flatpak-builtins-info.c:269
#: app/flatpak-builtins-remote-info.c:245
#: app/flatpak-builtins-remote-info.c:280
#, fuzzy
msgid "Collection:"
msgstr "Spustí aplikáciu"

#: app/flatpak-builtins-info.c:227 app/flatpak-builtins-info.c:270
#: app/flatpak-builtins-info.c:458 app/flatpak-builtins-info.c:516
#, fuzzy
msgid "Installation:"
msgstr "Inštalovanie: %s\n"

#: app/flatpak-builtins-info.c:228 app/flatpak-builtins-info.c:271
#: app/flatpak-builtins-info.c:459 app/flatpak-builtins-info.c:517
#: app/flatpak-builtins-remote-info.c:249
#: app/flatpak-builtins-remote-info.c:284
#, fuzzy
msgid "Installed Size:"
msgstr "Nainštalovanie podpísaného prostredia"

#: app/flatpak-builtins-info.c:231 app/flatpak-builtins-info.c:279
#: app/flatpak-builtins-remote-info.c:252
#: app/flatpak-builtins-remote-info.c:288
#, fuzzy
msgid "Runtime:"
msgstr "Prostredie. ktoré sa má použiť"

#: app/flatpak-builtins-info.c:232 app/flatpak-builtins-info.c:288
#: app/flatpak-builtins-remote-info.c:253
#: app/flatpak-builtins-remote-info.c:293
msgid "Sdk:"
msgstr ""

#: app/flatpak-builtins-info.c:235 app/flatpak-builtins-info.c:313
#: app/flatpak-builtins-remote-info.c:256
#: app/flatpak-builtins-remote-info.c:319
msgid "Date:"
msgstr ""

#: app/flatpak-builtins-info.c:237 app/flatpak-builtins-info.c:311
#: app/flatpak-builtins-remote-info.c:258
#: app/flatpak-builtins-remote-info.c:317
msgid "Subject:"
msgstr ""

#: app/flatpak-builtins-info.c:240 app/flatpak-builtins-info.c:295
msgid "Active commit:"
msgstr ""

#: app/flatpak-builtins-info.c:241 app/flatpak-builtins-info.c:298
msgid "Latest commit:"
msgstr ""

#: app/flatpak-builtins-info.c:244 app/flatpak-builtins-info.c:303
#: app/flatpak-builtins-info.c:457 app/flatpak-builtins-info.c:515
#: app/flatpak-builtins-remote-info.c:259
#: app/flatpak-builtins-remote-info.c:298
msgid "Commit:"
msgstr ""

#: app/flatpak-builtins-info.c:246 app/flatpak-builtins-info.c:308
#: app/flatpak-builtins-remote-info.c:261
#: app/flatpak-builtins-remote-info.c:303
msgid "Parent:"
msgstr ""

#: app/flatpak-builtins-info.c:248 app/flatpak-builtins-info.c:321
msgid "Alt-id:"
msgstr ""

#: app/flatpak-builtins-info.c:250 app/flatpak-builtins-info.c:325
#: app/flatpak-builtins-remote-info.c:263
#: app/flatpak-builtins-remote-info.c:308
msgid "End-of-life:"
msgstr ""

#: app/flatpak-builtins-info.c:252 app/flatpak-builtins-info.c:330
#: app/flatpak-builtins-remote-info.c:265
#: app/flatpak-builtins-remote-info.c:313
msgid "End-of-life-rebase:"
msgstr ""

#: app/flatpak-builtins-info.c:254 app/flatpak-builtins-info.c:317
msgid "Subdirectories:"
msgstr ""

#: app/flatpak-builtins-info.c:255 app/flatpak-builtins-info.c:454
#: app/flatpak-builtins-info.c:512
#, fuzzy
msgid "Extension:"
msgstr "Zobrazí voľby pomocníka"

#: app/flatpak-builtins-info.c:267 app/flatpak-builtins-info.c:456
#: app/flatpak-builtins-info.c:514
msgid "Origin:"
msgstr ""

#: app/flatpak-builtins-info.c:460 app/flatpak-builtins-info.c:522
msgid "Subpaths:"
msgstr ""

#: app/flatpak-builtins-info.c:478
msgid "unmaintained"
msgstr ""

#: app/flatpak-builtins-info.c:480 app/flatpak-builtins-info.c:482
msgid "unknown"
msgstr ""

#: app/flatpak-builtins-install.c:68 app/flatpak-builtins-preinstall.c:57
msgid "Don't pull, only install from local cache"
msgstr ""

#: app/flatpak-builtins-install.c:69 app/flatpak-builtins-preinstall.c:58
#: app/flatpak-builtins-update.c:60
msgid "Don't deploy, only download to local cache"
msgstr ""

#: app/flatpak-builtins-install.c:70 app/flatpak-builtins-preinstall.c:59
msgid "Don't install related refs"
msgstr ""

#: app/flatpak-builtins-install.c:71 app/flatpak-builtins-preinstall.c:60
#: app/flatpak-builtins-update.c:62
msgid "Don't verify/install runtime dependencies"
msgstr ""

#: app/flatpak-builtins-install.c:72
msgid "Don't automatically pin explicit installs"
msgstr ""

#: app/flatpak-builtins-install.c:73 app/flatpak-builtins-preinstall.c:61
#: app/flatpak-builtins-update.c:63
msgid "Don't use static deltas"
msgstr ""

#: app/flatpak-builtins-install.c:76 app/flatpak-builtins-preinstall.c:62
msgid "Additionally install the SDK used to build the given refs"
msgstr ""

#: app/flatpak-builtins-install.c:77 app/flatpak-builtins-preinstall.c:63
msgid ""
"Additionally install the debug info for the given refs and their dependencies"
msgstr ""

#: app/flatpak-builtins-install.c:78
msgid "Assume LOCATION is a .flatpak single-file bundle"
msgstr ""

#: app/flatpak-builtins-install.c:79
msgid "Assume LOCATION is a .flatpakref application description"
msgstr ""

#: app/flatpak-builtins-install.c:80
msgid "Assume LOCATION is containers-transports(5) reference to an OCI image"
msgstr ""

#: app/flatpak-builtins-install.c:81
msgid "Check bundle signatures with GPG key from FILE (- for stdin)"
msgstr ""

#: app/flatpak-builtins-install.c:82
msgid "Only install this subpath"
msgstr ""

#: app/flatpak-builtins-install.c:83 app/flatpak-builtins-preinstall.c:64
#: app/flatpak-builtins-uninstall.c:63 app/flatpak-builtins-update.c:68
msgid "Automatically answer yes for all questions"
msgstr ""

#: app/flatpak-builtins-install.c:84 app/flatpak-builtins-preinstall.c:65
#, fuzzy
msgid "Uninstall first if already installed"
msgstr "Aplikácia %s vetva %s je už nainštalovaná"

#: app/flatpak-builtins-install.c:85 app/flatpak-builtins-preinstall.c:66
#: app/flatpak-builtins-uninstall.c:64 app/flatpak-builtins-update.c:69
msgid "Produce minimal output and don't ask questions"
msgstr ""

#: app/flatpak-builtins-install.c:86
#, fuzzy
msgid "Update install if already installed"
msgstr "Aplikácia %s vetva %s je už nainštalovaná"

#. Translators: A sideload is when you install from a local USB drive rather than the Internet.
#: app/flatpak-builtins-install.c:88 app/flatpak-builtins-preinstall.c:68
#: app/flatpak-builtins-update.c:71
msgid "Use this local repo for sideloads"
msgstr ""

#: app/flatpak-builtins-install.c:178
msgid "Bundle filename must be specified"
msgstr "Názov súboru balíka musí byť určený"

#: app/flatpak-builtins-install.c:188
msgid "Remote bundles are not supported"
msgstr "Vzdialené balíky nie sú podporované"

#: app/flatpak-builtins-install.c:231
#, fuzzy
msgid "Filename or uri must be specified"
msgstr "Musí byť určený NÁZOV vzdialeného repozitára"

#: app/flatpak-builtins-install.c:295
#, fuzzy
msgid "Image location must be specified"
msgstr "ADRESÁR musí byť určený"

#: app/flatpak-builtins-install.c:345
#, fuzzy
msgid "[LOCATION/REMOTE] [REF…] - Install applications or runtimes"
msgstr "Podpíše aplikáciu alebo rozhranie"

#: app/flatpak-builtins-install.c:378
#, fuzzy
msgid "At least one REF must be specified"
msgstr "ADRESÁR musí byť určený"

#: app/flatpak-builtins-install.c:392
#, fuzzy, c-format
msgid "Looking for matches…\n"
msgstr "Žiadne aktualizácie.\n"

#: app/flatpak-builtins-install.c:513
#, c-format
msgid "No remote refs found for ‘%s’"
msgstr ""

#: app/flatpak-builtins-install.c:573 app/flatpak-builtins-uninstall.c:405
#: common/flatpak-ref-utils.c:689 common/flatpak-ref-utils.c:1595
#, fuzzy, c-format
msgid "Invalid branch %s: %s"
msgstr "„%s“ nie je platným názvom vetvy: %s"

#: app/flatpak-builtins-install.c:606
#, c-format
msgid "Nothing matches %s in local repository for remote %s"
msgstr ""

#: app/flatpak-builtins-install.c:608
#, fuzzy, c-format
msgid "Nothing matches %s in remote %s"
msgstr "Nič nevyhovuje názvu %s"

#: app/flatpak-builtins-install.c:629
#, fuzzy, c-format
msgid "Skipping: %s\n"
msgstr "Aktualizovanie zhrnutia\n"

#: app/flatpak-builtins-kill.c:110
#, fuzzy, c-format
msgid "%s is not running"
msgstr "Aplikácia %s nie je dostupná"

#: app/flatpak-builtins-kill.c:136
#, fuzzy
msgid "INSTANCE - Stop a running application"
msgstr ""
"\n"
"Spúšťanie aplikácií"

#: app/flatpak-builtins-kill.c:144 app/flatpak-builtins-ps.c:256
#, fuzzy
msgid "Extra arguments given"
msgstr "Informácie o údajoch navyše"

#: app/flatpak-builtins-kill.c:150
msgid "Must specify the app to kill"
msgstr ""

#: app/flatpak-builtins-list.c:47
#, fuzzy
msgid "Show extra information"
msgstr "Zobrazí voľby pomocníka"

#: app/flatpak-builtins-list.c:48
msgid "List installed runtimes"
msgstr "Vypíše zoznam nainštalovaných prostredí"

#: app/flatpak-builtins-list.c:49
msgid "List installed applications"
msgstr "Vypíše zoznam nainštalovaných aplikácií"

#: app/flatpak-builtins-list.c:50
msgid "Arch to show"
msgstr "Architektúra. ktorá sa má zobraziť"

#: app/flatpak-builtins-list.c:51 app/flatpak-builtins-remote-ls.c:57
msgid "List all refs (including locale/debug)"
msgstr ""

#: app/flatpak-builtins-list.c:53 app/flatpak-builtins-remote-ls.c:58
#, fuzzy
msgid "List all applications using RUNTIME"
msgstr "Vypíše zoznam nainštalovaných aplikácií"

#: app/flatpak-builtins-list.c:59 app/flatpak-builtins-remote-list.c:51
#: app/flatpak-builtins-remote-ls.c:68 app/flatpak-builtins-search.c:44
msgid "Name"
msgstr ""

#: app/flatpak-builtins-list.c:59 app/flatpak-builtins-remote-list.c:51
#: app/flatpak-builtins-remote-ls.c:68 app/flatpak-builtins-search.c:44
#, fuzzy
msgid "Show the name"
msgstr "Zobrazí referenciu"

#: app/flatpak-builtins-list.c:60 app/flatpak-builtins-remote-list.c:60
#: app/flatpak-builtins-remote-ls.c:69 app/flatpak-builtins-search.c:45
#, fuzzy
msgid "Description"
msgstr "Úplný popis"

#: app/flatpak-builtins-list.c:60 app/flatpak-builtins-remote-ls.c:69
#: app/flatpak-builtins-search.c:45
#, fuzzy
msgid "Show the description"
msgstr "Spustí aplikáciu"

#: app/flatpak-builtins-list.c:61 app/flatpak-builtins-remote-ls.c:70
#: app/flatpak-builtins-search.c:46
#, fuzzy
msgid "Application ID"
msgstr "Spustí aplikáciu"

#: app/flatpak-builtins-list.c:61 app/flatpak-builtins-ps.c:52
#: app/flatpak-builtins-remote-ls.c:70 app/flatpak-builtins-search.c:46
#, fuzzy
msgid "Show the application ID"
msgstr "Spustí aplikáciu"

#: app/flatpak-builtins-list.c:62 app/flatpak-builtins-remote-ls.c:71
#: app/flatpak-builtins-search.c:47
#, fuzzy
msgid "Show the version"
msgstr "Spustí aplikáciu"

#: app/flatpak-builtins-list.c:65 app/flatpak-builtins-ps.c:56
#: app/flatpak-builtins-remote-ls.c:77
#, fuzzy
msgid "Runtime"
msgstr "Prostredie. ktoré sa má použiť"

#: app/flatpak-builtins-list.c:65
#, fuzzy
msgid "Show the used runtime"
msgstr "Zobrazí referenciu"

#: app/flatpak-builtins-list.c:66 app/flatpak-builtins-remote-ls.c:74
#, fuzzy
msgid "Show the origin remote"
msgstr "Zobrazí pôvod"

#: app/flatpak-builtins-list.c:67
#, fuzzy
msgid "Show the installation"
msgstr "Nepodarilo sa nájsť inštaláciu %s"

#: app/flatpak-builtins-list.c:69
msgid "Active commit"
msgstr ""

#: app/flatpak-builtins-list.c:69 app/flatpak-builtins-remote-ls.c:76
#, fuzzy
msgid "Show the active commit"
msgstr "Zobrazí referenciu"

#: app/flatpak-builtins-list.c:70
msgid "Latest commit"
msgstr ""

#: app/flatpak-builtins-list.c:70
#, fuzzy
msgid "Show the latest commit"
msgstr "Zobrazí referenciu"

#: app/flatpak-builtins-list.c:71 app/flatpak-builtins-remote-ls.c:78
#, fuzzy
msgid "Installed size"
msgstr "Nainštalovanie podpísaného prostredia"

#: app/flatpak-builtins-list.c:71 app/flatpak-builtins-remote-ls.c:78
#, fuzzy
msgid "Show the installed size"
msgstr "Nainštalovanie podpísaného prostredia"

#: app/flatpak-builtins-list.c:72 app/flatpak-builtins-remote-list.c:58
#: app/flatpak-builtins-remote-ls.c:80 app/flatpak-builtins-repo.c:340
msgid "Options"
msgstr ""

#: app/flatpak-builtins-list.c:72 app/flatpak-builtins-remote-list.c:58
#: app/flatpak-builtins-remote-ls.c:80
#, fuzzy
msgid "Show options"
msgstr "Zobrazí voľby pomocníka"

#: app/flatpak-builtins-list.c:180
#, fuzzy, c-format
msgid "Unable to load details of %s: %s"
msgstr "Zlyhalo čítanie začlenenia %s: "

#: app/flatpak-builtins-list.c:190
#, fuzzy, c-format
msgid "Unable to inspect current version of %s: %s"
msgstr "Zlyhalo čítanie začlenenia %s: "

#: app/flatpak-builtins-list.c:408
msgid " - List installed apps and/or runtimes"
msgstr ""

#: app/flatpak-builtins-make-current.c:38
msgid "Arch to make current for"
msgstr ""

#: app/flatpak-builtins-make-current.c:58
msgid "APP BRANCH - Make branch of application current"
msgstr ""

#: app/flatpak-builtins-make-current.c:69 app/flatpak-builtins-run.c:260
msgid "APP must be specified"
msgstr ""

#: app/flatpak-builtins-make-current.c:84
msgid "BRANCH must be specified"
msgstr "VETVA musí byť určená"

#: app/flatpak-builtins-make-current.c:97
#, c-format
msgid "App %s branch %s is not installed"
msgstr ""

#: app/flatpak-builtins-mask.c:42
#, fuzzy
msgid "Remove matching masks"
msgstr "Žiadny vzdialený repozitár %s"

#: app/flatpak-builtins-mask.c:54
msgid ""
"[PATTERN…] - disable updates and automatic installation matching patterns"
msgstr ""

#: app/flatpak-builtins-mask.c:73
#, c-format
msgid "No masked patterns\n"
msgstr ""

#: app/flatpak-builtins-mask.c:78
#, c-format
msgid "Masked patterns:\n"
msgstr ""

#: app/flatpak-builtins-override.c:42
msgid "Remove existing overrides"
msgstr ""

#: app/flatpak-builtins-override.c:43
msgid "Show existing overrides"
msgstr ""

#: app/flatpak-builtins-override.c:59
msgid "[APP] - Override settings [for application]"
msgstr ""

#: app/flatpak-builtins-permission-list.c:143
msgid "[TABLE] [ID] - List permissions"
msgstr ""

#: app/flatpak-builtins-permission-list.c:179
#: app/flatpak-builtins-permission-show.c:142
msgid "Table"
msgstr ""

#: app/flatpak-builtins-permission-list.c:180
#: app/flatpak-builtins-permission-show.c:143
msgid "Object"
msgstr ""

#: app/flatpak-builtins-permission-list.c:181
#: app/flatpak-builtins-permission-show.c:144
msgid "App"
msgstr ""

#: app/flatpak-builtins-permission-list.c:183
#: app/flatpak-builtins-permission-show.c:146
msgid "Data"
msgstr ""

#: app/flatpak-builtins-permission-remove.c:120
msgid "TABLE ID [APP_ID] - Remove item from permission store"
msgstr ""

#: app/flatpak-builtins-permission-remove.c:129
#: app/flatpak-builtins-permission-set.c:120
#, fuzzy
msgid "Too few arguments"
msgstr "Príliš veľa parametrov"

#: app/flatpak-builtins-permission-reset.c:43
#, fuzzy
msgid "Reset all permissions"
msgstr "Zobrazí voľby pomocníka"

#: app/flatpak-builtins-permission-reset.c:144
msgid "APP_ID - Reset permissions for an app"
msgstr ""

#: app/flatpak-builtins-permission-reset.c:153
#: app/flatpak-builtins-permission-show.c:124
#, fuzzy
msgid "Wrong number of arguments"
msgstr "Príliš veľa parametrov"

#: app/flatpak-builtins-permission-set.c:42
msgid "Associate DATA with the entry"
msgstr ""

#: app/flatpak-builtins-permission-set.c:42
msgid "DATA"
msgstr ""

#: app/flatpak-builtins-permission-set.c:111
msgid "TABLE ID APP_ID [PERMISSION...] - Set permissions"
msgstr ""

#: app/flatpak-builtins-permission-set.c:132
#, fuzzy, c-format
msgid "Failed to parse '%s' as GVariant: "
msgstr "Zlyhalo čítanie začlenenia %s: "

#: app/flatpak-builtins-permission-show.c:115
#, fuzzy
msgid "APP_ID - Show permissions for an app"
msgstr "Zobrazí voľby pomocníka"

#: app/flatpak-builtins-pin.c:44
#, fuzzy
msgid "Remove matching pins"
msgstr "Žiadny vzdialený repozitár %s"

#: app/flatpak-builtins-pin.c:56
msgid "[PATTERN…] - disable automatic removal of runtimes matching patterns"
msgstr ""

#: app/flatpak-builtins-pin.c:75
#, c-format
msgid "No pinned patterns\n"
msgstr ""

#: app/flatpak-builtins-pin.c:80
#, c-format
msgid "Pinned patterns:\n"
msgstr ""

#: app/flatpak-builtins-preinstall.c:80
msgid "- Install flatpaks that are part of the operating system"
msgstr ""

#: app/flatpak-builtins-preinstall.c:118
#, fuzzy, c-format
msgid "Nothing to do.\n"
msgstr "Nič nevyhovuje názvu %s"

#: app/flatpak-builtins-ps.c:49
#, fuzzy
msgid "Instance"
msgstr "Nainštalovanie balíka"

#: app/flatpak-builtins-ps.c:49
#, fuzzy
msgid "Show the instance ID"
msgstr "Zobrazí referenciu"

#: app/flatpak-builtins-ps.c:50 app/flatpak-builtins-run.c:178
msgid "PID"
msgstr ""

#: app/flatpak-builtins-ps.c:50
msgid "Show the PID of the wrapper process"
msgstr ""

#: app/flatpak-builtins-ps.c:51
msgid "Child-PID"
msgstr ""

#: app/flatpak-builtins-ps.c:51
msgid "Show the PID of the sandbox process"
msgstr ""

#: app/flatpak-builtins-ps.c:54 app/flatpak-builtins-search.c:48
#, fuzzy
msgid "Show the application branch"
msgstr "Zobrazí voľby pomocníka"

#: app/flatpak-builtins-ps.c:55
#, fuzzy
msgid "Show the application commit"
msgstr "Zobrazí voľby pomocníka"

#: app/flatpak-builtins-ps.c:56
#, fuzzy
msgid "Show the runtime ID"
msgstr "Zobrazí referenciu"

#: app/flatpak-builtins-ps.c:57
#, fuzzy
msgid "R.-Branch"
msgstr "Vetva, ktorá sa má použiť"

#: app/flatpak-builtins-ps.c:57
#, fuzzy
msgid "Show the runtime branch"
msgstr "Zobrazí referenciu"

#: app/flatpak-builtins-ps.c:58
#, fuzzy
msgid "R.-Commit"
msgstr "Zobrazí začlenenie"

#: app/flatpak-builtins-ps.c:58
#, fuzzy
msgid "Show the runtime commit"
msgstr "Zobrazí referenciu"

#: app/flatpak-builtins-ps.c:59
msgid "Active"
msgstr ""

#: app/flatpak-builtins-ps.c:59
#, fuzzy
msgid "Show whether the app is active"
msgstr "Zobrazí referenciu"

#: app/flatpak-builtins-ps.c:60
msgid "Background"
msgstr ""

#: app/flatpak-builtins-ps.c:60
#, fuzzy
msgid "Show whether the app is background"
msgstr "Zobrazí referenciu"

#: app/flatpak-builtins-ps.c:246
msgid " - Enumerate running sandboxes"
msgstr ""

#: app/flatpak-builtins-remote-add.c:66
msgid "Do nothing if the provided remote exists"
msgstr "Nevykoná nič, ak poskytnutý vzdialený repozitár už existuje"

#: app/flatpak-builtins-remote-add.c:67
msgid "LOCATION specifies a configuration file, not the repo location"
msgstr ""

#: app/flatpak-builtins-remote-add.c:72 app/flatpak-builtins-remote-modify.c:78
msgid "Disable GPG verification"
msgstr "Zakáže overovanie pomocou GPG"

#: app/flatpak-builtins-remote-add.c:73 app/flatpak-builtins-remote-modify.c:79
msgid "Mark the remote as don't enumerate"
msgstr ""

#: app/flatpak-builtins-remote-add.c:74 app/flatpak-builtins-remote-modify.c:80
msgid "Mark the remote as don't use for deps"
msgstr ""

#: app/flatpak-builtins-remote-add.c:75 app/flatpak-builtins-remote-modify.c:81
msgid "Set priority (default 1, higher is more prioritized)"
msgstr ""
"Nastaví prioritu (predvolená hodnota je 1, vyššia hodnota znamená väčšiu "
"prioritu)"

#: app/flatpak-builtins-remote-add.c:75 app/flatpak-builtins-remote-modify.c:81
msgid "PRIORITY"
msgstr "PRIORITA"

#: app/flatpak-builtins-remote-add.c:76
msgid "The named subset to use for this remote"
msgstr ""

#: app/flatpak-builtins-remote-add.c:76 app/flatpak-builtins-remote-modify.c:71
msgid "SUBSET"
msgstr ""

#: app/flatpak-builtins-remote-add.c:77 app/flatpak-builtins-remote-modify.c:82
msgid "A nice name to use for this remote"
msgstr ""

#: app/flatpak-builtins-remote-add.c:78 app/flatpak-builtins-remote-modify.c:83
msgid "A one-line comment for this remote"
msgstr ""

#: app/flatpak-builtins-remote-add.c:79 app/flatpak-builtins-remote-modify.c:84
msgid "A full-paragraph description for this remote"
msgstr ""

#: app/flatpak-builtins-remote-add.c:80 app/flatpak-builtins-remote-modify.c:85
msgid "URL for a website for this remote"
msgstr ""

#: app/flatpak-builtins-remote-add.c:81 app/flatpak-builtins-remote-modify.c:86
msgid "URL for an icon for this remote"
msgstr ""

#: app/flatpak-builtins-remote-add.c:82 app/flatpak-builtins-remote-modify.c:87
msgid "Default branch to use for this remote"
msgstr ""

#: app/flatpak-builtins-remote-add.c:84 app/flatpak-builtins-remote-modify.c:89
msgid "Import GPG key from FILE (- for stdin)"
msgstr "Importuje kľúč GPG zo SÚBORU (- pre štandardný vstup)"

#: app/flatpak-builtins-remote-add.c:85 app/flatpak-builtins-remote-modify.c:90
msgid "Load signatures from URL"
msgstr ""

#: app/flatpak-builtins-remote-add.c:86 app/flatpak-builtins-remote-modify.c:92
msgid "Set path to local filter FILE"
msgstr ""

#: app/flatpak-builtins-remote-add.c:87 app/flatpak-builtins-remote-modify.c:93
msgid "Disable the remote"
msgstr "Zakáže vzdialený repozitár"

#: app/flatpak-builtins-remote-add.c:88 app/flatpak-builtins-remote-modify.c:94
msgid "Name of authenticator"
msgstr ""

#: app/flatpak-builtins-remote-add.c:90 app/flatpak-builtins-remote-modify.c:96
#, fuzzy
msgid "Autoinstall authenticator"
msgstr "Neplatný identifikátor pid %s"

#: app/flatpak-builtins-remote-add.c:91 app/flatpak-builtins-remote-modify.c:97
msgid "Don't autoinstall authenticator"
msgstr ""

#: app/flatpak-builtins-remote-add.c:92 app/flatpak-builtins-remote-modify.c:99
msgid "Don't follow the redirect set in the summary file"
msgstr ""

#: app/flatpak-builtins-remote-add.c:261 app/flatpak-builtins-remote-add.c:268
#, c-format
msgid "Can't load uri %s: %s\n"
msgstr ""

#: app/flatpak-builtins-remote-add.c:276 common/flatpak-dir.c:4643
#, c-format
msgid "Can't load file %s: %s\n"
msgstr ""

#: app/flatpak-builtins-remote-add.c:304
#, fuzzy
msgid "NAME LOCATION - Add a remote repository"
msgstr "NÁZOV [UMIESTNENIE] - Pridanie vzdialeného repozitára"

#: app/flatpak-builtins-remote-add.c:331
msgid "GPG verification is required if collections are enabled"
msgstr ""

#: app/flatpak-builtins-remote-add.c:393
#, c-format
msgid "Remote %s already exists"
msgstr "Vzdialený repozitár %s už existuje"

#: app/flatpak-builtins-remote-add.c:405
#: app/flatpak-builtins-remote-modify.c:340
#, fuzzy, c-format
msgid "Invalid authenticator name %s"
msgstr "Neplatný identifikátor pid %s"

#: app/flatpak-builtins-remote-add.c:422
#, fuzzy, c-format
msgid "Warning: Could not update extra metadata for '%s': %s\n"
msgstr "Nepodarilo sa aktualizovať metaúdaje navyše pre %s"

#: app/flatpak-builtins-remote-delete.c:39
msgid "Remove remote even if in use"
msgstr "Odstráni vzdialený repozitár, aj keď sa používa"

#: app/flatpak-builtins-remote-delete.c:53
msgid "NAME - Delete a remote repository"
msgstr ""

#: app/flatpak-builtins-remote-delete.c:100
#, fuzzy, c-format
msgid "The following refs are installed from remote '%s':"
msgstr "Aplikácia %s vetva %s je už nainštalovaná"

#: app/flatpak-builtins-remote-delete.c:101
#, fuzzy
msgid "Remove them?"
msgstr "Žiadny vzdialený repozitár %s"

#: app/flatpak-builtins-remote-delete.c:103
#, c-format
msgid "Can't remove remote '%s' with installed refs"
msgstr ""

#: app/flatpak-builtins-remote-info.c:55
msgid "Commit to show info for"
msgstr ""

#: app/flatpak-builtins-remote-info.c:58
msgid "Display log"
msgstr ""

#: app/flatpak-builtins-remote-info.c:61
#, fuzzy
msgid "Show parent"
msgstr "Zobrazí referenciu"

#: app/flatpak-builtins-remote-info.c:65 app/flatpak-builtins-remote-ls.c:60
msgid "Use local caches even if they are stale"
msgstr ""

#. Translators: A sideload is when you install from a local USB drive rather than the Internet.
#: app/flatpak-builtins-remote-info.c:67 app/flatpak-builtins-remote-ls.c:62
msgid "Only list refs available as sideloads"
msgstr ""

#: app/flatpak-builtins-remote-info.c:114
msgid ""
" REMOTE REF - Show information about an application or runtime in a remote"
msgstr ""

#: app/flatpak-builtins-remote-info.c:125
#, fuzzy
msgid "REMOTE and REF must be specified"
msgstr "ADRESÁR musí byť určený"

#: app/flatpak-builtins-remote-info.c:247
#: app/flatpak-builtins-remote-info.c:282
#, fuzzy
msgid "Download Size:"
msgstr "Zobrazí referenciu"

#: app/flatpak-builtins-remote-info.c:267
#: app/flatpak-builtins-remote-info.c:325
#, fuzzy
msgid "History:"
msgstr "Zobrazí začlenenie"

#: app/flatpak-builtins-remote-info.c:348
#, fuzzy
msgid " Commit:"
msgstr "Zobrazí začlenenie"

#: app/flatpak-builtins-remote-info.c:349
msgid " Subject:"
msgstr ""

#: app/flatpak-builtins-remote-info.c:350
msgid " Date:"
msgstr ""

#: app/flatpak-builtins-remote-info.c:383
#, c-format
msgid "Warning: Commit %s has no flatpak metadata\n"
msgstr ""

#: app/flatpak-builtins-remote-list.c:43
msgid "Show remote details"
msgstr ""

#: app/flatpak-builtins-remote-list.c:44
msgid "Show disabled remotes"
msgstr ""

#: app/flatpak-builtins-remote-list.c:52
msgid "Title"
msgstr ""

#: app/flatpak-builtins-remote-list.c:52
#, fuzzy
msgid "Show the title"
msgstr "Zobrazí referenciu"

#: app/flatpak-builtins-remote-list.c:53
#, fuzzy
msgid "Show the URL"
msgstr "Zobrazí referenciu"

#: app/flatpak-builtins-remote-list.c:54
#, fuzzy
msgid "Show the collection ID"
msgstr "Spustí aplikáciu"

#: app/flatpak-builtins-remote-list.c:55 app/flatpak-builtins-repo.c:392
msgid "Subset"
msgstr ""

#: app/flatpak-builtins-remote-list.c:55
#, fuzzy
msgid "Show the subset"
msgstr "Zobrazí referenciu"

#: app/flatpak-builtins-remote-list.c:56
msgid "Filter"
msgstr ""

#: app/flatpak-builtins-remote-list.c:56
#, fuzzy
msgid "Show filter file"
msgstr "Zobrazí referenciu"

#: app/flatpak-builtins-remote-list.c:57
msgid "Priority"
msgstr ""

#: app/flatpak-builtins-remote-list.c:57
#, fuzzy
msgid "Show the priority"
msgstr "Zobrazí referenciu"

#: app/flatpak-builtins-remote-list.c:59
#, fuzzy
msgid "Comment"
msgstr "Zobrazí začlenenie"

#: app/flatpak-builtins-remote-list.c:59
#, fuzzy
msgid "Show comment"
msgstr "Zobrazí začlenenie"

#: app/flatpak-builtins-remote-list.c:60
#, fuzzy
msgid "Show description"
msgstr "Spustí aplikáciu"

#: app/flatpak-builtins-remote-list.c:61
msgid "Homepage"
msgstr ""

#: app/flatpak-builtins-remote-list.c:61
#, fuzzy
msgid "Show homepage"
msgstr "Zobrazí referenciu"

#: app/flatpak-builtins-remote-list.c:62
msgid "Icon"
msgstr ""

#: app/flatpak-builtins-remote-list.c:62
#, fuzzy
msgid "Show icon"
msgstr "Zobrazí voľby pomocníka"

#: app/flatpak-builtins-remote-list.c:231
msgid " - List remote repositories"
msgstr ""

#: app/flatpak-builtins-remote-ls.c:52
msgid "Show arches and branches"
msgstr ""

#: app/flatpak-builtins-remote-ls.c:53
msgid "Show only runtimes"
msgstr ""

#: app/flatpak-builtins-remote-ls.c:54
msgid "Show only apps"
msgstr ""

#: app/flatpak-builtins-remote-ls.c:55
msgid "Show only those where updates are available"
msgstr ""

#: app/flatpak-builtins-remote-ls.c:56
msgid "Limit to this arch (* for all)"
msgstr ""

#: app/flatpak-builtins-remote-ls.c:77
#, fuzzy
msgid "Show the runtime"
msgstr "Zobrazí referenciu"

#: app/flatpak-builtins-remote-ls.c:79
#, fuzzy
msgid "Download size"
msgstr "Zobrazí referenciu"

#: app/flatpak-builtins-remote-ls.c:79
#, fuzzy
msgid "Show the download size"
msgstr "Zobrazí referenciu"

#: app/flatpak-builtins-remote-ls.c:391
msgid " [REMOTE or URI] - Show available runtimes and applications"
msgstr ""

#: app/flatpak-builtins-remote-modify.c:67
msgid "Enable GPG verification"
msgstr "Povolí overovanie pomocou GPG"

#: app/flatpak-builtins-remote-modify.c:68
msgid "Mark the remote as enumerate"
msgstr ""

#: app/flatpak-builtins-remote-modify.c:69
msgid "Mark the remote as used for dependencies"
msgstr ""

#: app/flatpak-builtins-remote-modify.c:70
#, fuzzy
msgid "Set a new URL"
msgstr "Nastaví novú url"

#: app/flatpak-builtins-remote-modify.c:71
#, fuzzy
msgid "Set a new subset to use"
msgstr "Nastaví novú url"

#: app/flatpak-builtins-remote-modify.c:72
msgid "Enable the remote"
msgstr "Povolí vzdialený repozitár"

#: app/flatpak-builtins-remote-modify.c:73
msgid "Update extra metadata from the summary file"
msgstr "Aktualizuje metaúdaje navyše zo súboru zhrnutia"

#: app/flatpak-builtins-remote-modify.c:91
msgid "Disable local filter"
msgstr ""

#: app/flatpak-builtins-remote-modify.c:95
#, fuzzy
msgid "Authenticator options"
msgstr "Zobrazí voľby pomocníka"

#: app/flatpak-builtins-remote-modify.c:98
#, fuzzy
msgid "Follow the redirect set in the summary file"
msgstr "Aktualizuje metaúdaje navyše zo súboru zhrnutia"

#: app/flatpak-builtins-remote-modify.c:306
msgid "NAME - Modify a remote repository"
msgstr "NÁZOV - Upraví vzdialený repozitár"

#: app/flatpak-builtins-remote-modify.c:316
msgid "Remote NAME must be specified"
msgstr "Musí byť určený NÁZOV vzdialeného repozitára"

#: app/flatpak-builtins-remote-modify.c:327
#, c-format
msgid "Updating extra metadata from remote summary for %s\n"
msgstr ""

#: app/flatpak-builtins-remote-modify.c:330
#, c-format
msgid "Error updating extra metadata for '%s': %s\n"
msgstr ""
"Chyba počas aktualizácie metaúdajov navyše pre „%s“: %s\n"
"\n"

#: app/flatpak-builtins-remote-modify.c:331
#, c-format
msgid "Could not update extra metadata for %s"
msgstr "Nepodarilo sa aktualizovať metaúdaje navyše pre %s"

#: app/flatpak-builtins-repair.c:43
msgid "Don't make any changes"
msgstr ""

#: app/flatpak-builtins-repair.c:44
#, fuzzy
msgid "Reinstall all refs"
msgstr "Odinštalovanie prostredia"

#: app/flatpak-builtins-repair.c:68
#, c-format
msgid "Object missing: %s.%s\n"
msgstr ""

#: app/flatpak-builtins-repair.c:76
#, c-format
msgid "Object invalid: %s.%s\n"
msgstr ""

#: app/flatpak-builtins-repair.c:81
#, c-format
msgid "%s, deleting object\n"
msgstr ""

#: app/flatpak-builtins-repair.c:146
#, fuzzy, c-format
msgid "Can't load object %s: %s\n"
msgstr "Objektov celkom: %u\n"

#: app/flatpak-builtins-repair.c:228
#, fuzzy, c-format
msgid "Commit invalid %s: %s\n"
msgstr "Neplatný identifikátor pid %s"

#: app/flatpak-builtins-repair.c:231
#, fuzzy, c-format
msgid "Deleting invalid commit %s: %s\n"
msgstr "Neplatný identifikátor pid %s"

#: app/flatpak-builtins-repair.c:261
#, c-format
msgid "Commit should be marked partial: %s\n"
msgstr ""

#: app/flatpak-builtins-repair.c:264
#, c-format
msgid "Marking commit as partial: %s\n"
msgstr ""

#: app/flatpak-builtins-repair.c:293
#, fuzzy, c-format
msgid "Problems loading data for %s: %s\n"
msgstr ""
"Chyba počas aktualizácie metaúdajov navyše pre „%s“: %s\n"
"\n"

#: app/flatpak-builtins-repair.c:306
#, fuzzy, c-format
msgid "Error reinstalling %s: %s\n"
msgstr "Inštalovanie: %s\n"

#: app/flatpak-builtins-repair.c:327
msgid "- Repair a flatpak installation"
msgstr ""

#: app/flatpak-builtins-repair.c:406
#, fuzzy, c-format
msgid "Removing non-deployed ref %s…\n"
msgstr "Neplatný identifikátor pid %s"

#: app/flatpak-builtins-repair.c:411
#, fuzzy, c-format
msgid "Skipping non-deployed ref %s…\n"
msgstr "Neplatný identifikátor pid %s"

#: app/flatpak-builtins-repair.c:429
#, c-format
msgid "[%d/%d] Verifying %s…\n"
msgstr ""

#: app/flatpak-builtins-repair.c:435
#, c-format
msgid "Dry run: "
msgstr ""

#: app/flatpak-builtins-repair.c:440
#, c-format
msgid "Deleting ref %s due to missing objects\n"
msgstr ""

#: app/flatpak-builtins-repair.c:444
#, c-format
msgid "Deleting ref %s due to invalid objects\n"
msgstr ""

#: app/flatpak-builtins-repair.c:448
#, c-format
msgid "Deleting ref %s due to %d\n"
msgstr ""

#: app/flatpak-builtins-repair.c:464
#, c-format
msgid "Checking remotes...\n"
msgstr ""

#: app/flatpak-builtins-repair.c:482
#, c-format
msgid "Remote %s for ref %s is missing\n"
msgstr ""

#: app/flatpak-builtins-repair.c:484
#, c-format
msgid "Remote %s for ref %s is disabled\n"
msgstr ""

#: app/flatpak-builtins-repair.c:490
#, c-format
msgid "Pruning objects\n"
msgstr ""

#: app/flatpak-builtins-repair.c:498
#, fuzzy, c-format
msgid "Erasing .removed\n"
msgstr "Inštalovanie: %s z %s\n"

#: app/flatpak-builtins-repair.c:524
#, fuzzy, c-format
msgid "Reinstalling refs\n"
msgstr "Inštalovanie: %s z %s\n"

#: app/flatpak-builtins-repair.c:526
#, fuzzy, c-format
msgid "Reinstalling removed refs\n"
msgstr "Inštalovanie: %s z %s\n"

#: app/flatpak-builtins-repair.c:551
#, fuzzy, c-format
msgid "While removing appstream for %s: "
msgstr "Počas otvárania repozitára %s: "

#: app/flatpak-builtins-repair.c:558
#, fuzzy, c-format
msgid "While deploying appstream for %s: "
msgstr "Počas otvárania repozitára %s: "

#: app/flatpak-builtins-repo.c:106
#, c-format
msgid "Repo mode: %s\n"
msgstr ""

#: app/flatpak-builtins-repo.c:113
#, c-format
msgid "Indexed summaries: %s\n"
msgstr ""

#: app/flatpak-builtins-repo.c:113 app/flatpak-builtins-repo.c:139
#: app/flatpak-builtins-repo.c:172
msgid "true"
msgstr ""

#: app/flatpak-builtins-repo.c:113 app/flatpak-builtins-repo.c:139
#: app/flatpak-builtins-repo.c:172
msgid "false"
msgstr ""

#: app/flatpak-builtins-repo.c:121
#, c-format
msgid "Subsummaries: "
msgstr ""

#: app/flatpak-builtins-repo.c:136
#, c-format
msgid "Cache version: %d\n"
msgstr ""

#: app/flatpak-builtins-repo.c:139
#, c-format
msgid "Indexed deltas: %s\n"
msgstr ""

#: app/flatpak-builtins-repo.c:142
#, c-format
msgid "Title: %s\n"
msgstr ""

#: app/flatpak-builtins-repo.c:145
#, fuzzy, c-format
msgid "Comment: %s\n"
msgstr "Príkaz, ktorý sa má nastaviť"

#: app/flatpak-builtins-repo.c:148
#, fuzzy, c-format
msgid "Description: %s\n"
msgstr "Úplný popis"

#: app/flatpak-builtins-repo.c:151
#, c-format
msgid "Homepage: %s\n"
msgstr ""

#: app/flatpak-builtins-repo.c:154
#, c-format
msgid "Icon: %s\n"
msgstr ""

#: app/flatpak-builtins-repo.c:157
#, c-format
msgid "Collection ID: %s\n"
msgstr ""

#: app/flatpak-builtins-repo.c:160
#, c-format
msgid "Default branch: %s\n"
msgstr ""

#: app/flatpak-builtins-repo.c:163
#, c-format
msgid "Redirect URL: %s\n"
msgstr ""

#: app/flatpak-builtins-repo.c:166
#, fuzzy, c-format
msgid "Deploy collection ID: %s\n"
msgstr "Spustí aplikáciu"

#: app/flatpak-builtins-repo.c:169
#, fuzzy, c-format
msgid "Authenticator name: %s\n"
msgstr "Neplatný identifikátor pid %s"

#: app/flatpak-builtins-repo.c:172
#, fuzzy, c-format
msgid "Authenticator install: %s\n"
msgstr "Zobrazí voľby pomocníka"

#: app/flatpak-builtins-repo.c:180
#, c-format
msgid "GPG key hash: %s\n"
msgstr ""

#: app/flatpak-builtins-repo.c:184
#, c-format
msgid "%zd summary branches\n"
msgstr ""

#: app/flatpak-builtins-repo.c:336
#, fuzzy
msgid "Installed"
msgstr "Nainštalovanie balíka"

#. Translators: Download is used here as a noun
#: app/flatpak-builtins-repo.c:338 app/flatpak-cli-transaction.c:1462
msgid "Download"
msgstr ""

#: app/flatpak-builtins-repo.c:339
msgid "Subsets"
msgstr ""

#: app/flatpak-builtins-repo.c:393
msgid "Digest"
msgstr ""

#: app/flatpak-builtins-repo.c:394
#, fuzzy
msgid "History length"
msgstr "Zobrazí začlenenie"

#: app/flatpak-builtins-repo.c:711
#, fuzzy
msgid "Print general information about the repository"
msgstr "Vypíše informácie o verzii a skončí"

#: app/flatpak-builtins-repo.c:712
#, fuzzy
msgid "List the branches in the repository"
msgstr "Aktualizuje súbor zhrnutia v repozitári"

#: app/flatpak-builtins-repo.c:713
msgid "Print metadata for a branch"
msgstr ""

#: app/flatpak-builtins-repo.c:714
#, fuzzy
msgid "Show commits for a branch"
msgstr "Zobrazí referenciu"

#: app/flatpak-builtins-repo.c:715
#, fuzzy
msgid "Print information about the repo subsets"
msgstr "Vypíše informácie o verzii a skončí"

#: app/flatpak-builtins-repo.c:716
msgid "Limit information to subsets with this prefix"
msgstr ""

#: app/flatpak-builtins-repo.c:732
msgid "LOCATION - Repository maintenance"
msgstr ""

#: app/flatpak-builtins-run.c:159
msgid "Command to run"
msgstr "Príkaz, ktorý sa má spustiť"

#: app/flatpak-builtins-run.c:160
msgid "Directory to run the command in"
msgstr ""

#: app/flatpak-builtins-run.c:161
msgid "Branch to use"
msgstr "Vetva, ktorá sa má použiť"

#: app/flatpak-builtins-run.c:162
msgid "Use development runtime"
msgstr "Použije vývojové prostredie"

#: app/flatpak-builtins-run.c:163
msgid "Runtime to use"
msgstr "Prostredie. ktoré sa má použiť"

#: app/flatpak-builtins-run.c:164
msgid "Runtime version to use"
msgstr "Verzia prostredia, ktoré sa má použiť"

#: app/flatpak-builtins-run.c:167
msgid "Log accessibility bus calls"
msgstr ""

#: app/flatpak-builtins-run.c:168
msgid "Don't proxy accessibility bus calls"
msgstr ""

#: app/flatpak-builtins-run.c:169
msgid "Proxy accessibility bus calls (default except when sandboxed)"
msgstr ""

#: app/flatpak-builtins-run.c:170
msgid "Don't proxy session bus calls"
msgstr ""

#: app/flatpak-builtins-run.c:171
msgid "Proxy session bus calls (default except when sandboxed)"
msgstr ""

#: app/flatpak-builtins-run.c:172
#, fuzzy
msgid "Don't start portals"
msgstr "Nespracuje exporty"

#: app/flatpak-builtins-run.c:173
msgid "Enable file forwarding"
msgstr ""

#: app/flatpak-builtins-run.c:174
msgid "Run specified commit"
msgstr ""

#: app/flatpak-builtins-run.c:175
#, fuzzy
msgid "Use specified runtime commit"
msgstr "Aktualizovanie podpísaného prostredia"

#: app/flatpak-builtins-run.c:176
msgid "Run completely sandboxed"
msgstr ""

#: app/flatpak-builtins-run.c:178
msgid "Use PID as parent pid for sharing namespaces"
msgstr ""

#: app/flatpak-builtins-run.c:179
msgid "Make processes visible in parent namespace"
msgstr ""

#: app/flatpak-builtins-run.c:180
msgid "Share process ID namespace with parent"
msgstr ""

#: app/flatpak-builtins-run.c:181
msgid "Write the instance ID to the given file descriptor"
msgstr ""

#: app/flatpak-builtins-run.c:182
msgid "Use PATH instead of the app's /app"
msgstr ""

#: app/flatpak-builtins-run.c:183
msgid "Use FD instead of the app's /app"
msgstr ""

#: app/flatpak-builtins-run.c:183 app/flatpak-builtins-run.c:185
#: app/flatpak-builtins-run.c:187 app/flatpak-builtins-run.c:188
#: common/flatpak-context.c:2672
msgid "FD"
msgstr ""

#: app/flatpak-builtins-run.c:184
msgid "Use PATH instead of the runtime's /usr"
msgstr ""

#: app/flatpak-builtins-run.c:185
msgid "Use FD instead of the runtime's /usr"
msgstr ""

#: app/flatpak-builtins-run.c:186
msgid "Clear all outside environment variables"
msgstr ""

#: app/flatpak-builtins-run.c:187
msgid ""
"Bind mount the file or directory referred to by FD to its canonicalized path"
msgstr ""

#: app/flatpak-builtins-run.c:188
msgid ""
"Bind mount the file or directory referred to by FD read-only to its "
"canonicalized path"
msgstr ""

#: app/flatpak-builtins-run.c:219
msgid "APP [ARGUMENT…] - Run an app"
msgstr ""

#: app/flatpak-builtins-run.c:370
#, fuzzy, c-format
msgid "runtime/%s/%s/%s not installed"
msgstr "Aplikácia %s %s nie je nainštalovaná"

#: app/flatpak-builtins-run.c:419
msgid "app-fd and app-path cannot both be used"
msgstr ""

#: app/flatpak-builtins-run.c:449
msgid "usr-fd and usr-path cannot both be used"
msgstr ""

#: app/flatpak-builtins-search.c:37
#, fuzzy
msgid "Arch to search for"
msgstr "Architektúra, pre ktorú sa má inštalovať"

#: app/flatpak-builtins-search.c:49
#, fuzzy
msgid "Remotes"
msgstr "Žiadny vzdialený repozitár %s"

#: app/flatpak-builtins-search.c:49
#, fuzzy
msgid "Show the remotes"
msgstr "Zobrazí referenciu"

#: app/flatpak-builtins-search.c:244
msgid "TEXT - Search remote apps/runtimes for text"
msgstr ""

#: app/flatpak-builtins-search.c:255
#, fuzzy
msgid "TEXT must be specified"
msgstr "NÁZOV musí byť určený"

#: app/flatpak-builtins-search.c:338
#, fuzzy
msgid "No matches found"
msgstr "Nič nevyhovuje názvu %s"

#: app/flatpak-builtins-uninstall.c:54
msgid "Arch to uninstall"
msgstr ""

#: app/flatpak-builtins-uninstall.c:55
msgid "Keep ref in local repository"
msgstr ""

#: app/flatpak-builtins-uninstall.c:56
msgid "Don't uninstall related refs"
msgstr ""

#: app/flatpak-builtins-uninstall.c:57
msgid "Remove files even if running"
msgstr ""

#: app/flatpak-builtins-uninstall.c:60
#, fuzzy
msgid "Uninstall all"
msgstr "Odinštalovanie prostredia"

#: app/flatpak-builtins-uninstall.c:61
#, fuzzy
msgid "Uninstall unused"
msgstr "Odinštalovanie prostredia"

#: app/flatpak-builtins-uninstall.c:62
msgid "Delete app data"
msgstr ""

#: app/flatpak-builtins-uninstall.c:141
#, c-format
msgid "Delete data for %s?"
msgstr ""

#: app/flatpak-builtins-uninstall.c:220
#, c-format
msgid "Info: applications using the extension %s%s%s branch %s%s%s:\n"
msgstr ""

#: app/flatpak-builtins-uninstall.c:223
#, fuzzy, c-format
msgid "Info: applications using the runtime %s%s%s branch %s%s%s:\n"
msgstr "Podpíše aplikáciu alebo prostredie"

#: app/flatpak-builtins-uninstall.c:238
#, fuzzy
msgid "Really remove?"
msgstr "Žiadny vzdialený repozitár %s"

#: app/flatpak-builtins-uninstall.c:255
#, fuzzy
msgid "[REF…] - Uninstall applications or runtimes"
msgstr "Podpíše aplikáciu alebo rozhranie"

#: app/flatpak-builtins-uninstall.c:264
msgid "Must specify at least one REF, --unused, --all or --delete-data"
msgstr ""

#: app/flatpak-builtins-uninstall.c:267
msgid "Must not specify REFs when using --all"
msgstr ""

#: app/flatpak-builtins-uninstall.c:270
msgid "Must not specify REFs when using --unused"
msgstr ""

#: app/flatpak-builtins-uninstall.c:336
#, c-format
msgid ""
"\n"
"These runtimes in installation '%s' are pinned and won't be removed; see "
"flatpak-pin(1):\n"
msgstr ""

#: app/flatpak-builtins-uninstall.c:370
#, c-format
msgid "Nothing unused to uninstall\n"
msgstr ""

#: app/flatpak-builtins-uninstall.c:444
#, c-format
msgid "No installed refs found for ‘%s’"
msgstr ""

#: app/flatpak-builtins-uninstall.c:447
#, c-format
msgid " with arch ‘%s’"
msgstr ""

#: app/flatpak-builtins-uninstall.c:449
#, c-format
msgid " with branch ‘%s’"
msgstr ""

#: app/flatpak-builtins-uninstall.c:456
#, fuzzy, c-format
msgid "Warning: %s is not installed\n"
msgstr "Aplikácia %s vetva %s nie je nainštalovaná"

#: app/flatpak-builtins-uninstall.c:490
#, c-format
msgid "None of the specified refs are installed"
msgstr ""

#: app/flatpak-builtins-uninstall.c:599
#, c-format
msgid "No app data to delete\n"
msgstr ""

#: app/flatpak-builtins-update.c:56
msgid "Arch to update for"
msgstr ""

#: app/flatpak-builtins-update.c:57
msgid "Commit to deploy"
msgstr ""

#: app/flatpak-builtins-update.c:58
msgid "Remove old files even if running"
msgstr ""

#: app/flatpak-builtins-update.c:59
msgid "Don't pull, only update from local cache"
msgstr ""

#: app/flatpak-builtins-update.c:61
msgid "Don't update related refs"
msgstr ""

#: app/flatpak-builtins-update.c:66
msgid "Update appstream for remote"
msgstr ""

#: app/flatpak-builtins-update.c:67
msgid "Only update this subpath"
msgstr ""

#: app/flatpak-builtins-update.c:90
#, fuzzy
msgid "[REF…] - Update applications or runtimes"
msgstr "Podpíše aplikáciu alebo rozhranie"

#: app/flatpak-builtins-update.c:121
#, fuzzy
msgid "With --commit, only one REF may be specified"
msgstr "ADRESÁR musí byť určený"

#: app/flatpak-builtins-update.c:162
#, fuzzy, c-format
msgid "Looking for updates…\n"
msgstr "Žiadne aktualizácie.\n"

#: app/flatpak-builtins-update.c:215
#, fuzzy, c-format
msgid "Unable to update %s: %s\n"
msgstr "Zlyhalo čítanie začlenenia %s: "

#: app/flatpak-builtins-update.c:274
#, fuzzy, c-format
msgid "Nothing to update.\n"
msgstr "Nič nevyhovuje názvu %s"

#: app/flatpak-builtins-utils.c:337
#, c-format
msgid ""
"Remote ‘%s’ found in multiple installations, unable to proceed in non-"
"interactive mode"
msgstr ""

#: app/flatpak-builtins-utils.c:346
#, c-format
msgid "Remote ‘%s’ found in multiple installations:"
msgstr ""

#: app/flatpak-builtins-utils.c:347 app/flatpak-builtins-utils.c:442
#: app/flatpak-builtins-utils.c:538 app/flatpak-builtins-utils.c:540
#: app/flatpak-builtins-utils.c:598
msgid "Which do you want to use (0 to abort)?"
msgstr ""

#: app/flatpak-builtins-utils.c:349
#, c-format
msgid "No remote chosen to resolve ‘%s’ which exists in multiple installations"
msgstr ""

#: app/flatpak-builtins-utils.c:358
#, c-format
msgid ""
"Remote \"%s\" not found\n"
"Hint: Use flatpak remote-add to add a remote"
msgstr ""

#: app/flatpak-builtins-utils.c:364
#, fuzzy, c-format
msgid "Remote \"%s\" not found in the %s installation"
msgstr "Nepodarilo sa nájsť inštaláciu %s"

#: app/flatpak-builtins-utils.c:404
#, c-format
msgid "Multiple refs match ‘%s’, unable to proceed in non-interactive mode"
msgstr ""

#. default to yes on Enter
#: app/flatpak-builtins-utils.c:430
#, c-format
msgid ""
"Found ref ‘%s’ in remote ‘%s’ (%s).\n"
"Use this ref?"
msgstr ""

#: app/flatpak-builtins-utils.c:434 app/flatpak-builtins-utils.c:444
#: app/flatpak-builtins-utils.c:522 app/flatpak-builtins-utils.c:543
#, c-format
msgid "No ref chosen to resolve matches for ‘%s’"
msgstr ""

#: app/flatpak-builtins-utils.c:440
#, c-format
msgid "Similar refs found for ‘%s’ in remote ‘%s’ (%s):"
msgstr ""

#: app/flatpak-builtins-utils.c:488
#, c-format
msgid ""
"Multiple installed refs match ‘%s’, unable to proceed in non-interactive mode"
msgstr ""

#. default to yes on Enter
#: app/flatpak-builtins-utils.c:518
#, c-format
msgid "Found installed ref ‘%s’ (%s). Is this correct?"
msgstr ""

#: app/flatpak-builtins-utils.c:534
#, c-format
msgid "All of the above"
msgstr ""

#: app/flatpak-builtins-utils.c:535
#, c-format
msgid "Similar installed refs found for ‘%s’:"
msgstr ""

#: app/flatpak-builtins-utils.c:579
#, c-format
msgid ""
"Multiple remotes have refs matching ‘%s’, unable to proceed in non-"
"interactive mode"
msgstr ""

#: app/flatpak-builtins-utils.c:597
#, c-format
msgid "Remotes found with refs similar to ‘%s’:"
msgstr ""

#: app/flatpak-builtins-utils.c:600
#, c-format
msgid "No remote chosen to resolve matches for ‘%s’"
msgstr ""

#: app/flatpak-builtins-utils.c:696 app/flatpak-builtins-utils.c:699
#, fuzzy, c-format
msgid "Updating appstream data for user remote %s"
msgstr ""
"Chyba počas aktualizácie metaúdajov navyše pre „%s“: %s\n"
"\n"

#: app/flatpak-builtins-utils.c:706 app/flatpak-builtins-utils.c:709
#, fuzzy, c-format
msgid "Updating appstream data for remote %s"
msgstr ""
"Chyba počas aktualizácie metaúdajov navyše pre „%s“: %s\n"
"\n"

#: app/flatpak-builtins-utils.c:717 app/flatpak-builtins-utils.c:719
#, fuzzy
msgid "Error updating"
msgstr "Aktualizovanie zhrnutia\n"

#: app/flatpak-builtins-utils.c:755
#, c-format
msgid "Remote \"%s\" not found"
msgstr ""

#: app/flatpak-builtins-utils.c:796
#, c-format
msgid "Ambiguous suffix: '%s'."
msgstr ""

#. Translators: don't translate the values
#: app/flatpak-builtins-utils.c:798 app/flatpak-builtins-utils.c:813
msgid "Possible values are :s[tart], :m[iddle], :e[nd] or :f[ull]"
msgstr ""

#: app/flatpak-builtins-utils.c:811
#, fuzzy, c-format
msgid "Invalid suffix: '%s'."
msgstr "Neplatný identifikátor pid %s"

#: app/flatpak-builtins-utils.c:846
#, c-format
msgid "Ambiguous column: %s"
msgstr ""

#: app/flatpak-builtins-utils.c:859
#, fuzzy, c-format
msgid "Unknown column: %s"
msgstr "Neznámy príkaz „%s“"

#: app/flatpak-builtins-utils.c:917
msgid "Available columns:\n"
msgstr ""

#: app/flatpak-builtins-utils.c:927
#, fuzzy
msgid "Show all columns"
msgstr "Zobrazí voľby pomocníka"

#: app/flatpak-builtins-utils.c:928
msgid "Show available columns"
msgstr ""

#: app/flatpak-builtins-utils.c:931
msgid "Append :s[tart], :m[iddle], :e[nd] or :f[ull] to change ellipsization"
msgstr ""

#: app/flatpak-builtins-utils.c:1483
#, c-format
msgid "Unknown scheme in sideload location %s"
msgstr ""

#: app/flatpak-cli-transaction.c:96 app/flatpak-cli-transaction.c:102
#, fuzzy, c-format
msgid "Required runtime for %s (%s) found in remote %s\n"
msgstr ""
"Požadované prostredie pre %s (%s) nie je nainštalované. Vyhľadáva sa...\n"

#: app/flatpak-cli-transaction.c:104
#, fuzzy
msgid "Do you want to install it?"
msgstr "Nájdené vo vzdialenom repozitári %s. Chcete vykonať inštaláciu?"

#: app/flatpak-cli-transaction.c:110
#, fuzzy, c-format
msgid "Required runtime for %s (%s) found in remotes:"
msgstr ""
"Požadované prostredie pre %s (%s) nie je nainštalované. Vyhľadáva sa...\n"

#: app/flatpak-cli-transaction.c:112
msgid "Which do you want to install (0 to abort)?"
msgstr ""

#: app/flatpak-cli-transaction.c:132
#, fuzzy, c-format
msgid "Configuring %s as new remote '%s'\n"
msgstr "Nedá sa nájsť %s vo vzdialenom repozitári %s"

#. default to yes on Enter
#: app/flatpak-cli-transaction.c:139
#, c-format
msgid ""
"The remote '%s', referred to by '%s' at location %s contains additional "
"applications.\n"
"Should the remote be kept for future installations?"
msgstr ""

#. default to yes on Enter
#: app/flatpak-cli-transaction.c:147
#, fuzzy, c-format
msgid ""
"The application %s depends on runtimes from:\n"
"  %s\n"
"Configure this as new remote '%s'"
msgstr ""
"Táto aplikácia závisí na prostredí z:\n"
"  %s\n"
"Konfigurovať ju ako nový vzdialený repozitár „%s“"

#. Formatted size/remaining time in seconds
#: app/flatpak-cli-transaction.c:321
#, c-format
msgid "%s/s%s%s"
msgstr ""

#. Download progress percentage, use the appropriate
#. percent format for your language
#: app/flatpak-cli-transaction.c:359
#, c-format
msgid "%3d%%"
msgstr ""

#: app/flatpak-cli-transaction.c:414
#, fuzzy
msgid "Installing…"
msgstr "Inštalovanie: %s\n"

#: app/flatpak-cli-transaction.c:416
#, fuzzy, c-format
msgid "Installing %d/%d…"
msgstr "Inštalovanie: %s\n"

#: app/flatpak-cli-transaction.c:421
msgid "Updating…"
msgstr ""

#: app/flatpak-cli-transaction.c:423
#, fuzzy, c-format
msgid "Updating %d/%d…"
msgstr "Aktualizovanie: %s z %s\n"

#: app/flatpak-cli-transaction.c:428
#, fuzzy
msgid "Uninstalling…"
msgstr "Inštalovanie: %s\n"

#: app/flatpak-cli-transaction.c:430
#, fuzzy, c-format
msgid "Uninstalling %d/%d…"
msgstr "Inštalovanie: %s\n"

#: app/flatpak-cli-transaction.c:496 app/flatpak-quiet-transaction.c:161
#, c-format
msgid "Info: %s was skipped"
msgstr ""

#: app/flatpak-cli-transaction.c:519
#, fuzzy, c-format
msgid "Warning: %s%s%s already installed"
msgstr "Aplikácia %s vetva %s je už nainštalovaná"

#: app/flatpak-cli-transaction.c:522
#, fuzzy, c-format
msgid "Error: %s%s%s already installed"
msgstr "Aplikácia %s vetva %s je už nainštalovaná"

#: app/flatpak-cli-transaction.c:528
#, fuzzy, c-format
msgid "Warning: %s%s%s not installed"
msgstr "Aplikácia %s vetva %s nie je nainštalovaná"

#: app/flatpak-cli-transaction.c:531
#, fuzzy, c-format
msgid "Error: %s%s%s not installed"
msgstr "Aplikácia %s %s nie je nainštalovaná"

#: app/flatpak-cli-transaction.c:537
#, fuzzy, c-format
msgid "Warning: %s%s%s needs a later flatpak version"
msgstr "Spustí aplikáciu"

#: app/flatpak-cli-transaction.c:540
#, fuzzy, c-format
msgid "Error: %s%s%s needs a later flatpak version"
msgstr "Spustí aplikáciu"

#: app/flatpak-cli-transaction.c:546
msgid "Warning: Not enough disk space to complete this operation"
msgstr ""

#: app/flatpak-cli-transaction.c:548
msgid "Error: Not enough disk space to complete this operation"
msgstr ""

#: app/flatpak-cli-transaction.c:553
#, c-format
msgid "Warning: %s"
msgstr ""

#: app/flatpak-cli-transaction.c:555
#, fuzzy, c-format
msgid "Error: %s"
msgstr "chyba:"

#: app/flatpak-cli-transaction.c:570
#, fuzzy, c-format
msgid "Failed to install %s%s%s: "
msgstr "Zlyhalo čítanie začlenenia %s: "

#: app/flatpak-cli-transaction.c:577
#, fuzzy, c-format
msgid "Failed to update %s%s%s: "
msgstr "Zlyhalo čítanie začlenenia %s: "

#: app/flatpak-cli-transaction.c:584
#, fuzzy, c-format
msgid "Failed to install bundle %s%s%s: "
msgstr "Zlyhalo čítanie začlenenia %s: "

#: app/flatpak-cli-transaction.c:591
#, fuzzy, c-format
msgid "Failed to uninstall %s%s%s: "
msgstr "Zlyhalo čítanie začlenenia %s: "

#: app/flatpak-cli-transaction.c:642
#, fuzzy, c-format
msgid "Authentication required for remote '%s'\n"
msgstr "Na aktualizáciu softvéru sa vyžaduje overenie totožnosti"

#: app/flatpak-cli-transaction.c:643
msgid "Open browser?"
msgstr ""

#: app/flatpak-cli-transaction.c:699
#, c-format
msgid "Login required remote %s (realm %s)\n"
msgstr ""

#: app/flatpak-cli-transaction.c:704
msgid "Password"
msgstr ""

#. Only runtimes can be pinned
#: app/flatpak-cli-transaction.c:759
#, c-format
msgid ""
"\n"
"Info: (pinned) runtime %s%s%s branch %s%s%s is end-of-life, in favor of "
"%s%s%s branch %s%s%s\n"
msgstr ""

#: app/flatpak-cli-transaction.c:765
#, c-format
msgid ""
"\n"
"Info: runtime %s%s%s branch %s%s%s is end-of-life, in favor of %s%s%s branch "
"%s%s%s\n"
msgstr ""

#: app/flatpak-cli-transaction.c:768
#, c-format
msgid ""
"\n"
"Info: app %s%s%s branch %s%s%s is end-of-life, in favor of %s%s%s branch "
"%s%s%s\n"
msgstr ""

#. Only runtimes can be pinned
#: app/flatpak-cli-transaction.c:780
#, c-format
msgid ""
"\n"
"Info: (pinned) runtime %s%s%s branch %s%s%s is end-of-life, with reason:\n"
msgstr ""

#: app/flatpak-cli-transaction.c:786
#, c-format
msgid ""
"\n"
"Info: runtime %s%s%s branch %s%s%s is end-of-life, with reason:\n"
msgstr ""

#: app/flatpak-cli-transaction.c:789
#, c-format
msgid ""
"\n"
"Info: app %s%s%s branch %s%s%s is end-of-life, with reason:\n"
msgstr ""

#: app/flatpak-cli-transaction.c:963
#, fuzzy, c-format
msgid "Info: applications using this extension:\n"
msgstr "Podpíše aplikáciu alebo prostredie"

#: app/flatpak-cli-transaction.c:965
#, fuzzy, c-format
msgid "Info: applications using this runtime:\n"
msgstr "Podpíše aplikáciu alebo prostredie"

#: app/flatpak-cli-transaction.c:984
msgid "Replace?"
msgstr ""

#: app/flatpak-cli-transaction.c:987 app/flatpak-quiet-transaction.c:247
#, c-format
msgid "Updating to rebased version\n"
msgstr ""

#: app/flatpak-cli-transaction.c:1011
#, fuzzy, c-format
msgid "Failed to rebase %s to %s: "
msgstr "Zlyhalo čítanie začlenenia %s: "

#: app/flatpak-cli-transaction.c:1277
#, fuzzy, c-format
msgid "New %s%s%s permissions:"
msgstr "Zobrazí voľby pomocníka"

#: app/flatpak-cli-transaction.c:1279
#, fuzzy, c-format
msgid "%s%s%s permissions:"
msgstr "Zobrazí voľby pomocníka"

#: app/flatpak-cli-transaction.c:1343
msgid "Warning: "
msgstr ""

#. translators: This is short for operation, the title of a one-char column
#: app/flatpak-cli-transaction.c:1442
msgid "Op"
msgstr ""

#. Avoid resizing the download column too much,
#. * by making the title as long as typical content
#.
#: app/flatpak-cli-transaction.c:1458 app/flatpak-cli-transaction.c:1503
msgid "partial"
msgstr ""

#: app/flatpak-cli-transaction.c:1535
#, fuzzy
msgid "Proceed with these changes to the user installation?"
msgstr "Nepodarilo sa nájsť inštaláciu %s"

#: app/flatpak-cli-transaction.c:1537
#, fuzzy
msgid "Proceed with these changes to the system installation?"
msgstr "Nepodarilo sa nájsť inštaláciu %s"

#: app/flatpak-cli-transaction.c:1539
#, fuzzy, c-format
msgid "Proceed with these changes to the %s?"
msgstr "Nepodarilo sa nájsť inštaláciu %s"

#: app/flatpak-cli-transaction.c:1711
msgid "Changes complete."
msgstr ""

#: app/flatpak-cli-transaction.c:1713
#, fuzzy
msgid "Uninstall complete."
msgstr "Odinštalovanie prostredia"

#: app/flatpak-cli-transaction.c:1715
#, fuzzy
msgid "Installation complete."
msgstr "Inštalovanie: %s\n"

#: app/flatpak-cli-transaction.c:1717
#, fuzzy
msgid "Updates complete."
msgstr "Použije alternatívny súbor pre metaúdaje"

#. For updates/!stop_on_first_error we already printed all errors so we make up
#. a different one.
#: app/flatpak-cli-transaction.c:1750
msgid "There were one or more errors"
msgstr ""

#. translators: please keep the leading space
#: app/flatpak-main.c:76
#, fuzzy
msgid " Manage installed applications and runtimes"
msgstr " Správa nainštalovaných aplikácií a prostredí"

#: app/flatpak-main.c:77
#, fuzzy
msgid "Install an application or runtime"
msgstr "Podpíše aplikáciu alebo rozhranie"

#: app/flatpak-main.c:78
msgid "Update an installed application or runtime"
msgstr ""

#: app/flatpak-main.c:81
msgid "Uninstall an installed application or runtime"
msgstr ""

#: app/flatpak-main.c:84
msgid "Mask out updates and automatic installation"
msgstr ""

#: app/flatpak-main.c:85
msgid "Pin a runtime to prevent automatic removal"
msgstr ""

#: app/flatpak-main.c:86
msgid "List installed apps and/or runtimes"
msgstr ""

#: app/flatpak-main.c:87
msgid "Show info for installed app or runtime"
msgstr ""

#: app/flatpak-main.c:88
#, fuzzy
msgid "Show history"
msgstr "Zobrazí začlenenie"

#: app/flatpak-main.c:89
#, fuzzy
msgid "Configure flatpak"
msgstr "Konfigurácia vzdialeného repozitára"

#: app/flatpak-main.c:90
msgid "Repair flatpak installation"
msgstr ""

#: app/flatpak-main.c:91
msgid "Put applications or runtimes onto removable media"
msgstr ""

#: app/flatpak-main.c:92
msgid "Install flatpaks that are part of the operating system"
msgstr ""

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:95
#, fuzzy
msgid ""
"\n"
" Find applications and runtimes"
msgstr "Podpíše aplikáciu alebo prostredie"

#: app/flatpak-main.c:96
msgid "Search for remote apps/runtimes"
msgstr ""

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:99
#, fuzzy
msgid ""
"\n"
" Manage running applications"
msgstr ""
"\n"
"Spúšťanie aplikácií"

#: app/flatpak-main.c:100
msgid "Run an application"
msgstr "Spustí aplikáciu"

#: app/flatpak-main.c:101
msgid "Override permissions for an application"
msgstr ""

#: app/flatpak-main.c:102
msgid "Specify default version to run"
msgstr ""

#: app/flatpak-main.c:103
msgid "Enter the namespace of a running application"
msgstr ""

#: app/flatpak-main.c:104
#, fuzzy
msgid "Enumerate running applications"
msgstr ""
"\n"
"Spúšťanie aplikácií"

#: app/flatpak-main.c:105
#, fuzzy
msgid "Stop a running application"
msgstr ""
"\n"
"Spúšťanie aplikácií"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:108
msgid ""
"\n"
" Manage file access"
msgstr ""
"\n"
"Správa prístupu k súborom"

#: app/flatpak-main.c:109
msgid "List exported files"
msgstr ""

#: app/flatpak-main.c:110
msgid "Grant an application access to a specific file"
msgstr "Udelí aplikácii prístup k určenému súboru"

#: app/flatpak-main.c:111
msgid "Revoke access to a specific file"
msgstr ""

#: app/flatpak-main.c:112
msgid "Show information about a specific file"
msgstr ""

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:116
#, fuzzy
msgid ""
"\n"
" Manage dynamic permissions"
msgstr "Zobrazí voľby pomocníka"

#: app/flatpak-main.c:117
#, fuzzy
msgid "List permissions"
msgstr "Zobrazí voľby pomocníka"

#: app/flatpak-main.c:118
msgid "Remove item from permission store"
msgstr ""

#: app/flatpak-main.c:120
#, fuzzy
msgid "Set permissions"
msgstr "Zobrazí voľby pomocníka"

#: app/flatpak-main.c:121
#, fuzzy
msgid "Show app permissions"
msgstr "Zobrazí voľby pomocníka"

#: app/flatpak-main.c:122
#, fuzzy
msgid "Reset app permissions"
msgstr "Zobrazí voľby pomocníka"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:125
msgid ""
"\n"
" Manage remote repositories"
msgstr ""
"\n"
"Správa vzdialených repozitárov"

#: app/flatpak-main.c:126
msgid "List all configured remotes"
msgstr "Zoznam všetkých konfigurovaných vzdialených repozitárov"

#: app/flatpak-main.c:127
msgid "Add a new remote repository (by URL)"
msgstr ""

#: app/flatpak-main.c:128
msgid "Modify properties of a configured remote"
msgstr ""

#: app/flatpak-main.c:129
msgid "Delete a configured remote"
msgstr ""

#: app/flatpak-main.c:131
msgid "List contents of a configured remote"
msgstr ""

#: app/flatpak-main.c:132
#, fuzzy
msgid "Show information about a remote app or runtime"
msgstr "Vypíše informácie o verzii a skončí"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:135
msgid ""
"\n"
" Build applications"
msgstr ""
"\n"
"Zostavenie aplikácií"

#: app/flatpak-main.c:136
msgid "Initialize a directory for building"
msgstr ""

#: app/flatpak-main.c:137
msgid "Run a build command inside the build dir"
msgstr ""

#: app/flatpak-main.c:138
msgid "Finish a build dir for export"
msgstr ""

#: app/flatpak-main.c:139
msgid "Export a build dir to a repository"
msgstr "Exportuje adresár zostavenia do repozitára"

#: app/flatpak-main.c:140
#, fuzzy
msgid "Create a bundle file from a ref in a local repository"
msgstr "Vytvorí balík z adresára zostavenia"

#: app/flatpak-main.c:141
msgid "Import a bundle file"
msgstr "Importuje súbor balíka"

#: app/flatpak-main.c:142
msgid "Sign an application or runtime"
msgstr "Podpíše aplikáciu alebo prostredie"

#: app/flatpak-main.c:143
msgid "Update the summary file in a repository"
msgstr "Aktualizuje súbor zhrnutia v repozitári"

#: app/flatpak-main.c:144
msgid "Create new commit based on existing ref"
msgstr ""

#: app/flatpak-main.c:145
#, fuzzy
msgid "Show information about a repo"
msgstr "Vypíše informácie o verzii a skončí"

#: app/flatpak-main.c:162
#, fuzzy
msgid "Show debug information, -vv for more detail"
msgstr "Vypíše ladiace informácie počas spracovávania príkazu"

#: app/flatpak-main.c:163
#, fuzzy
msgid "Show OSTree debug information"
msgstr "Zobrazí voľby pomocníka"

#: app/flatpak-main.c:169
msgid "Print version information and exit"
msgstr "Vypíše informácie o verzii a skončí"

#: app/flatpak-main.c:170
msgid "Print default arch and exit"
msgstr "Vypíše predvolenú architektúru a skončí"

#: app/flatpak-main.c:171
msgid "Print supported arches and exit"
msgstr "Vypíše podporované architektúry a skončí"

#: app/flatpak-main.c:172
#, fuzzy
msgid "Print active gl drivers and exit"
msgstr "Vypíše podporované architektúry a skončí"

#: app/flatpak-main.c:173
#, fuzzy
msgid "Print paths for system installations and exit"
msgstr "Vypíše informácie o verzii a skončí"

#: app/flatpak-main.c:174
msgid "Print the updated environment needed to run flatpaks"
msgstr ""

#: app/flatpak-main.c:175
msgid "Only include the system installation with --print-updated-env"
msgstr ""

#: app/flatpak-main.c:180
#, fuzzy
msgid "Work on the user installation"
msgstr "Nepodarilo sa nájsť inštaláciu %s"

#: app/flatpak-main.c:181
msgid "Work on the system-wide installation (default)"
msgstr ""

#: app/flatpak-main.c:182
msgid "Work on a non-default system-wide installation"
msgstr ""

#: app/flatpak-main.c:212
msgid "Builtin Commands:"
msgstr "Vstavané príkazy:"

#: app/flatpak-main.c:298
#, c-format
msgid ""
"Note that the directories %s are not in the search path set by the "
"XDG_DATA_DIRS environment variable, so applications installed by Flatpak may "
"not appear on your desktop until the session is restarted."
msgstr ""

#: app/flatpak-main.c:312
#, c-format
msgid ""
"Note that the directory %s is not in the search path set by the "
"XDG_DATA_DIRS environment variable, so applications installed by Flatpak may "
"not appear on your desktop until the session is restarted."
msgstr ""

#: app/flatpak-main.c:381
msgid ""
"Refusing to operate under sudo with --user. Omit sudo to operate on the user "
"installation, or use a root shell to operate on the root user's installation."
msgstr ""

#: app/flatpak-main.c:453
msgid ""
"Multiple installations specified for a command that works on one installation"
msgstr ""

#: app/flatpak-main.c:504 app/flatpak-main.c:697
#, c-format
msgid "See '%s --help'"
msgstr ""

#: app/flatpak-main.c:706
#, fuzzy, c-format
msgid "'%s' is not a flatpak command. Did you mean '%s%s'?"
msgstr "„%s“ nie je platným názvom aplikácie: %s"

#: app/flatpak-main.c:709
#, c-format
msgid "'%s' is not a flatpak command"
msgstr ""

#: app/flatpak-main.c:824
msgid "No command specified"
msgstr "Nebol určený žiadny príkaz"

#: app/flatpak-main.c:980
msgid "error:"
msgstr "chyba:"

#: app/flatpak-quiet-transaction.c:77
#, fuzzy, c-format
msgid "Installing %s\n"
msgstr "Inštalovanie: %s\n"

#: app/flatpak-quiet-transaction.c:81
#, fuzzy, c-format
msgid "Updating %s\n"
msgstr "Aktualizovanie zhrnutia\n"

#: app/flatpak-quiet-transaction.c:85
#, fuzzy, c-format
msgid "Uninstalling %s\n"
msgstr "Inštalovanie: %s z %s\n"

#: app/flatpak-quiet-transaction.c:107
#, fuzzy, c-format
msgid "Warning: Failed to install %s: %s\n"
msgstr "Zlyhalo čítanie začlenenia %s: "

#: app/flatpak-quiet-transaction.c:110
#, fuzzy, c-format
msgid "Error: Failed to install %s: %s\n"
msgstr "Inštalovanie: %s\n"

#: app/flatpak-quiet-transaction.c:116
#, fuzzy, c-format
msgid "Warning: Failed to update %s: %s\n"
msgstr "Zlyhalo čítanie začlenenia %s: "

#: app/flatpak-quiet-transaction.c:119
#, fuzzy, c-format
msgid "Error: Failed to update %s: %s\n"
msgstr "Zlyhalo čítanie začlenenia %s: "

#: app/flatpak-quiet-transaction.c:125
#, fuzzy, c-format
msgid "Warning: Failed to install bundle %s: %s\n"
msgstr "Zlyhalo čítanie začlenenia %s: "

#: app/flatpak-quiet-transaction.c:128
#, fuzzy, c-format
msgid "Error: Failed to install bundle %s: %s\n"
msgstr "Inštalovanie: %s\n"

#: app/flatpak-quiet-transaction.c:134
#, fuzzy, c-format
msgid "Warning: Failed to uninstall %s: %s\n"
msgstr "Zlyhalo čítanie začlenenia %s: "

#: app/flatpak-quiet-transaction.c:137
#, fuzzy, c-format
msgid "Error: Failed to uninstall %s: %s\n"
msgstr "Inštalovanie: %s\n"

#: app/flatpak-quiet-transaction.c:166 common/flatpak-dir.c:11475
#, fuzzy, c-format
msgid "%s already installed"
msgstr "Aplikácia %s vetva %s je už nainštalovaná"

#: app/flatpak-quiet-transaction.c:168 common/flatpak-dir.c:3622
#: common/flatpak-dir.c:4321 common/flatpak-dir.c:16968
#: common/flatpak-dir.c:17258 common/flatpak-dir-utils.c:166
#: common/flatpak-dir-utils.c:259 common/flatpak-transaction.c:2736
#: common/flatpak-transaction.c:2791
#, c-format
msgid "%s not installed"
msgstr ""

#: app/flatpak-quiet-transaction.c:170
#, fuzzy, c-format
msgid "%s needs a later flatpak version"
msgstr "Spustí aplikáciu"

#: app/flatpak-quiet-transaction.c:172
msgid "Not enough disk space to complete this operation"
msgstr ""

#: app/flatpak-quiet-transaction.c:239
#, c-format
msgid "Info: %s is end-of-life, in favor of %s\n"
msgstr ""

#: app/flatpak-quiet-transaction.c:241
#, c-format
msgid "Info: %s is end-of-life, with reason: %s\n"
msgstr ""

#: app/flatpak-quiet-transaction.c:251
#, fuzzy, c-format
msgid "Failed to rebase %s to %s: %s\n"
msgstr "Zlyhalo čítanie začlenenia %s: "

#: common/flatpak-auth.c:58
#, fuzzy, c-format
msgid "No authenticator configured for remote `%s`"
msgstr "Na aktualizáciu softvéru sa vyžaduje overenie totožnosti"

#: common/flatpak-context.c:637 common/flatpak-context.c:649
#, fuzzy, c-format
msgid "Invalid permission syntax: %s"
msgstr "Neplatný identifikátor pid %s"

#: common/flatpak-context.c:1207
#, c-format
msgid "Unknown share type %s, valid types are: %s"
msgstr ""

#: common/flatpak-context.c:1228
#, c-format
msgid "Unknown policy type %s, valid types are: %s"
msgstr ""

#: common/flatpak-context.c:1266
#, fuzzy, c-format
msgid "Invalid dbus name %s"
msgstr "Neplatný identifikátor pid %s"

#: common/flatpak-context.c:1279
#, c-format
msgid "Unknown socket type %s, valid types are: %s"
msgstr ""

#: common/flatpak-context.c:1294
#, c-format
msgid "Unknown device type %s, valid types are: %s"
msgstr ""

#: common/flatpak-context.c:1308
#, c-format
msgid "Unknown feature type %s, valid types are: %s"
msgstr ""

#: common/flatpak-context.c:1840
#, c-format
msgid "Filesystem location \"%s\" contains \"..\""
msgstr ""

#: common/flatpak-context.c:1882
#, c-format
msgid ""
"--filesystem=/ is not available, use --filesystem=host for a similar result"
msgstr ""

#: common/flatpak-context.c:1916
#, c-format
msgid ""
"Unknown filesystem location %s, valid locations are: host, host-os, host-"
"etc, host-root, home, xdg-*[/…], ~/dir, /dir"
msgstr ""

#: common/flatpak-context.c:2015
#, fuzzy, c-format
msgid "Invalid syntax for %s: %s"
msgstr "Neplatný identifikátor pid %s"

#: common/flatpak-context.c:2142
#, c-format
msgid "fallback-x11 can not be conditional"
msgstr ""

#: common/flatpak-context.c:2318
#, c-format
msgid "Invalid env format %s"
msgstr ""

#: common/flatpak-context.c:2399
#, c-format
msgid "Environment variable name must not contain '=': %s"
msgstr ""

#: common/flatpak-context.c:2527 common/flatpak-context.c:2535
#, c-format
msgid "--add-policy arguments must be in the form SUBSYSTEM.KEY=VALUE"
msgstr ""

#: common/flatpak-context.c:2542
#, c-format
msgid "--add-policy values can't start with \"!\""
msgstr ""

#: common/flatpak-context.c:2567 common/flatpak-context.c:2575
#, c-format
msgid "--remove-policy arguments must be in the form SUBSYSTEM.KEY=VALUE"
msgstr ""

#: common/flatpak-context.c:2582
#, c-format
msgid "--remove-policy values can't start with \"!\""
msgstr ""

#: common/flatpak-context.c:2657
msgid "Share with host"
msgstr "Zdieľa s hostiteľom"

#: common/flatpak-context.c:2657 common/flatpak-context.c:2658
msgid "SHARE"
msgstr ""

#: common/flatpak-context.c:2658
msgid "Unshare with host"
msgstr ""

#: common/flatpak-context.c:2659
msgid "Require conditions to be met for a subsystem to get shared"
msgstr ""

#: common/flatpak-context.c:2659
msgid "SHARE:CONDITION"
msgstr ""

#: common/flatpak-context.c:2660
msgid "Expose socket to app"
msgstr ""

#: common/flatpak-context.c:2660 common/flatpak-context.c:2661
msgid "SOCKET"
msgstr "SOKET"

#: common/flatpak-context.c:2661
msgid "Don't expose socket to app"
msgstr ""

#: common/flatpak-context.c:2662
msgid "Require conditions to be met for a socket to get exposed"
msgstr ""

#: common/flatpak-context.c:2662
msgid "SOCKET:CONDITION"
msgstr ""

#: common/flatpak-context.c:2663
msgid "Expose device to app"
msgstr ""

#: common/flatpak-context.c:2663 common/flatpak-context.c:2664
msgid "DEVICE"
msgstr "ZARIADENIE"

#: common/flatpak-context.c:2664
msgid "Don't expose device to app"
msgstr ""

#: common/flatpak-context.c:2665
msgid "Require conditions to be met for a device to get exposed"
msgstr ""

#: common/flatpak-context.c:2665
msgid "DEVICE:CONDITION"
msgstr ""

#: common/flatpak-context.c:2666
msgid "Allow feature"
msgstr "Umožní funkciu"

#: common/flatpak-context.c:2666 common/flatpak-context.c:2667
msgid "FEATURE"
msgstr "FUNKCIA"

#: common/flatpak-context.c:2667
msgid "Don't allow feature"
msgstr "Neumožní funkciu"

#: common/flatpak-context.c:2668
msgid "Require conditions to be met for a feature to get allowed"
msgstr ""

#: common/flatpak-context.c:2668
msgid "FEATURE:CONDITION"
msgstr ""

#: common/flatpak-context.c:2669
msgid "Expose filesystem to app (:ro for read-only)"
msgstr ""

#: common/flatpak-context.c:2669
msgid "FILESYSTEM[:ro]"
msgstr ""

#: common/flatpak-context.c:2670
msgid "Don't expose filesystem to app"
msgstr ""

#: common/flatpak-context.c:2670
msgid "FILESYSTEM"
msgstr "SYSTÉM_SÚBOROV"

#: common/flatpak-context.c:2671
msgid "Set environment variable"
msgstr ""

#: common/flatpak-context.c:2671
msgid "VAR=VALUE"
msgstr ""

#: common/flatpak-context.c:2672
msgid "Read environment variables in env -0 format from FD"
msgstr ""

#: common/flatpak-context.c:2673
msgid "Remove variable from environment"
msgstr ""

#: common/flatpak-context.c:2673
msgid "VAR"
msgstr ""

#: common/flatpak-context.c:2674
msgid "Allow app to own name on the session bus"
msgstr ""

#: common/flatpak-context.c:2674 common/flatpak-context.c:2675
#: common/flatpak-context.c:2676 common/flatpak-context.c:2677
#: common/flatpak-context.c:2678 common/flatpak-context.c:2679
#: common/flatpak-context.c:2680
msgid "DBUS_NAME"
msgstr "NÁZOV_DBUS"

#: common/flatpak-context.c:2675
msgid "Allow app to talk to name on the session bus"
msgstr ""

#: common/flatpak-context.c:2676
msgid "Don't allow app to talk to name on the session bus"
msgstr ""

#: common/flatpak-context.c:2677
msgid "Allow app to own name on the system bus"
msgstr ""

#: common/flatpak-context.c:2678
msgid "Allow app to talk to name on the system bus"
msgstr ""

#: common/flatpak-context.c:2679
msgid "Don't allow app to talk to name on the system bus"
msgstr ""

#: common/flatpak-context.c:2680
msgid "Allow app to own name on the a11y bus"
msgstr ""

#: common/flatpak-context.c:2681
msgid "Add generic policy option"
msgstr ""

#: common/flatpak-context.c:2681 common/flatpak-context.c:2682
msgid "SUBSYSTEM.KEY=VALUE"
msgstr ""

#: common/flatpak-context.c:2682
msgid "Remove generic policy option"
msgstr ""

#: common/flatpak-context.c:2683
msgid "Add USB device to enumerables"
msgstr ""

#: common/flatpak-context.c:2683 common/flatpak-context.c:2684
msgid "VENDOR_ID:PRODUCT_ID"
msgstr ""

#: common/flatpak-context.c:2684
msgid "Add USB device to hidden list"
msgstr ""

#: common/flatpak-context.c:2685
msgid "A list of USB devices that are enumerable"
msgstr ""

#: common/flatpak-context.c:2685
msgid "LIST"
msgstr ""

#: common/flatpak-context.c:2686
msgid "File containing a list of USB devices to make enumerable"
msgstr ""

#: common/flatpak-context.c:2686 common/flatpak-context.c:2687
msgid "FILENAME"
msgstr "NÁZOV_SÚBORU"

#: common/flatpak-context.c:2687
msgid "Persist home directory subpath"
msgstr ""

#. This is not needed/used anymore, so hidden, but we accept it for backwards compat
#: common/flatpak-context.c:2689
msgid "Don't require a running session (no cgroups creation)"
msgstr ""

#: common/flatpak-context.c:3718
#, c-format
msgid "Not replacing \"%s\" with tmpfs: %s"
msgstr ""

#: common/flatpak-context.c:3726
#, c-format
msgid "Not sharing \"%s\" with sandbox: %s"
msgstr ""

#. Even if the error is one that we would normally silence, like
#. * the path not existing, it seems reasonable to make more of a fuss
#. * about the home directory not existing or otherwise being unusable,
#. * so this is intentionally not using cannot_export()
#: common/flatpak-context.c:3828
#, c-format
msgid "Not allowing home directory access: %s"
msgstr ""

#: common/flatpak-context.c:4062
#, fuzzy, c-format
msgid "Unable to provide a temporary home directory in the sandbox: %s"
msgstr "Zlyhalo čítanie začlenenia %s: "

#: common/flatpak-dir.c:442
#, c-format
msgid "Configured collection ID ‘%s’ not in summary file"
msgstr ""

#: common/flatpak-dir.c:587
#, c-format
msgid "Unable to load summary from remote %s: %s"
msgstr ""

#: common/flatpak-dir.c:764 common/flatpak-dir.c:800 common/flatpak-dir.c:906
#, fuzzy, c-format
msgid "No such ref '%s' in remote %s"
msgstr "Nedá sa nájsť %s vo vzdialenom repozitári %s"

#: common/flatpak-dir.c:891 common/flatpak-dir.c:1051 common/flatpak-dir.c:1080
#: common/flatpak-dir.c:1092
#, c-format
msgid "No entry for %s in remote %s summary flatpak cache"
msgstr ""

#: common/flatpak-dir.c:1069
#, c-format
msgid "No summary or Flatpak cache available for remote %s"
msgstr ""

#: common/flatpak-dir.c:1097
#, fuzzy, c-format
msgid "Missing xa.data in summary for remote %s"
msgstr "Aplikácia %s vetva %s je už nainštalovaná"

#: common/flatpak-dir.c:1103 common/flatpak-dir.c:1546
#, fuzzy, c-format
msgid "Unsupported summary version %d for remote %s"
msgstr "Aplikácia %s vetva %s je už nainštalovaná"

#: common/flatpak-dir.c:1200
#, fuzzy
msgid "Remote OCI index has no registry uri"
msgstr "NÁZOV [UMIESTNENIE] - Pridanie vzdialeného repozitára"

#: common/flatpak-dir.c:1261
#, fuzzy, c-format
msgid "Couldn't find ref %s in remote %s"
msgstr "Nedá sa nájsť %s vo vzdialenom repozitári %s"

#: common/flatpak-dir.c:1288 common/flatpak-dir.c:1381
#, c-format
msgid "Commit has no requested ref ‘%s’ in ref binding metadata (found: ‘%s’)"
msgstr ""

#: common/flatpak-dir.c:1413
#, c-format
msgid "Configured collection ID ‘%s’ not in binding metadata"
msgstr ""

#: common/flatpak-dir.c:1449 common/flatpak-dir.c:5645
#, fuzzy, c-format
msgid "Couldn't find latest checksum for ref %s in remote %s"
msgstr "Nedá sa nájsť %s vo vzdialenom repozitári %s"

#: common/flatpak-dir.c:1516 common/flatpak-dir.c:1552
#, c-format
msgid "No entry for %s in remote %s summary flatpak sparse cache"
msgstr ""

#: common/flatpak-dir.c:2540
#, c-format
msgid "Commit metadata for %s not matching expected metadata"
msgstr ""

#: common/flatpak-dir.c:2823
msgid "Unable to connect to system bus"
msgstr ""

#: common/flatpak-dir.c:3419
#, fuzzy
msgid "User installation"
msgstr "Inštalovanie: %s\n"

#: common/flatpak-dir.c:3426
#, fuzzy, c-format
msgid "System (%s) installation"
msgstr "Inštalovanie: %s\n"

#: common/flatpak-dir.c:3472
#, c-format
msgid "No overrides found for %s"
msgstr ""

#: common/flatpak-dir.c:3625
#, fuzzy, c-format
msgid "%s (commit %s) not installed"
msgstr "Aplikácia %s %s nie je nainštalovaná"

#: common/flatpak-dir.c:4650
#, fuzzy, c-format
msgid "Error parsing system flatpakrepo file for %s: %s"
msgstr ""
"Chyba počas aktualizácie metaúdajov navyše pre „%s“: %s\n"
"\n"

#: common/flatpak-dir.c:4735
#, c-format
msgid "While opening repository %s: "
msgstr "Počas otvárania repozitára %s: "

#: common/flatpak-dir.c:5004
#, c-format
msgid "The config key %s is not set"
msgstr ""

#: common/flatpak-dir.c:5140
#, c-format
msgid "No current %s pattern matching %s"
msgstr ""

#: common/flatpak-dir.c:5422
msgid "No appstream commit to deploy"
msgstr ""

#: common/flatpak-dir.c:5941 common/flatpak-dir.c:7266
#: common/flatpak-dir.c:10881 common/flatpak-dir.c:11618
msgid "Can't pull from untrusted non-gpg verified remote"
msgstr ""

#: common/flatpak-dir.c:6376 common/flatpak-dir.c:6591
msgid "Extra data not supported for non-gpg-verified local system installs"
msgstr ""

#: common/flatpak-dir.c:6415 common/flatpak-dir.c:6782
#, fuzzy, c-format
msgid "Invalid checksum for extra data uri %s"
msgstr "Nesprávna veľkosť pre údaje navyše %s"

#: common/flatpak-dir.c:6424
#, c-format
msgid "Empty name for extra data uri %s"
msgstr ""

#: common/flatpak-dir.c:6432
#, c-format
msgid "Unsupported extra data uri %s"
msgstr ""

#: common/flatpak-dir.c:6461
#, fuzzy, c-format
msgid "Failed to load local extra-data %s: %s"
msgstr "Zlyhalo čítanie začlenenia %s: "

#: common/flatpak-dir.c:6469
#, fuzzy, c-format
msgid "Wrong size for extra-data %s"
msgstr "Nesprávna veľkosť pre údaje navyše %s"

#: common/flatpak-dir.c:6488
#, fuzzy, c-format
msgid "While downloading %s: "
msgstr "Počas otvárania repozitára %s: "

#: common/flatpak-dir.c:6498
#, c-format
msgid "Wrong size for extra data %s"
msgstr "Nesprávna veľkosť pre údaje navyše %s"

#: common/flatpak-dir.c:6507
#, c-format
msgid "Invalid checksum for extra data %s"
msgstr ""

#: common/flatpak-dir.c:7096 common/flatpak-dir.c:7349
#, c-format
msgid "While pulling %s from remote %s: "
msgstr ""

#: common/flatpak-dir.c:7290 common/flatpak-repo-utils.c:3886
msgid "GPG signatures found, but none are in trusted keyring"
msgstr ""

#: common/flatpak-dir.c:7307
#, c-format
msgid "Commit for ‘%s’ has no ref binding"
msgstr ""

#: common/flatpak-dir.c:7312
#, c-format
msgid "Commit for ‘%s’ is not in expected bound refs: %s"
msgstr ""

#: common/flatpak-dir.c:7488
#, fuzzy
msgid "Only applications can be made current"
msgstr "Podpíše aplikáciu alebo prostredie"

#: common/flatpak-dir.c:8192
msgid "Not enough memory"
msgstr "Nedostatok pamäte"

#: common/flatpak-dir.c:8211
msgid "Failed to read from exported file"
msgstr "Zlyhalo čítanie z exportovaného súboru"

#: common/flatpak-dir.c:8401
msgid "Error reading mimetype xml file"
msgstr ""

#: common/flatpak-dir.c:8406
msgid "Invalid mimetype xml file"
msgstr ""

#: common/flatpak-dir.c:8492
#, c-format
msgid "D-Bus service file '%s' has wrong name"
msgstr ""

#: common/flatpak-dir.c:8647
#, fuzzy, c-format
msgid "Invalid Exec argument %s"
msgstr "Neplatný identifikátor pid %s"

#: common/flatpak-dir.c:9115
msgid "While getting detached metadata: "
msgstr ""

#: common/flatpak-dir.c:9120 common/flatpak-dir.c:9125
#: common/flatpak-dir.c:9129
msgid "Extra data missing in detached metadata"
msgstr ""

#: common/flatpak-dir.c:9133
msgid "While creating extradir: "
msgstr ""

#: common/flatpak-dir.c:9154 common/flatpak-dir.c:9187
msgid "Invalid checksum for extra data"
msgstr ""

#: common/flatpak-dir.c:9183
msgid "Wrong size for extra data"
msgstr ""

#: common/flatpak-dir.c:9196
#, c-format
msgid "While writing extra data file '%s': "
msgstr ""

#: common/flatpak-dir.c:9204
#, c-format
msgid "Extra data %s missing in detached metadata"
msgstr ""

#: common/flatpak-dir.c:9278
#, fuzzy, c-format
msgid "Unable to get runtime key from metadata"
msgstr "Použije alternatívny súbor pre metaúdaje"

#: common/flatpak-dir.c:9402
#, c-format
msgid "apply_extra script failed, exit status %d"
msgstr ""

#. Translators: The placeholder is for an app ref.
#: common/flatpak-dir.c:9591
#, c-format
msgid "Installing %s is not allowed by the policy set by your administrator"
msgstr ""

#: common/flatpak-dir.c:9690
#, c-format
msgid "While trying to resolve ref %s: "
msgstr ""

#: common/flatpak-dir.c:9702
#, c-format
msgid "%s is not available"
msgstr "Aplikácia %s nie je dostupná"

#: common/flatpak-dir.c:9714 common/flatpak-dir.c:11495
#, fuzzy, c-format
msgid "%s commit %s already installed"
msgstr "Aplikácia %s vetva %s je už nainštalovaná"

#: common/flatpak-dir.c:9721
msgid "Can't create deploy directory"
msgstr ""

#: common/flatpak-dir.c:9729
#, c-format
msgid "Failed to read commit %s: "
msgstr "Zlyhalo čítanie začlenenia %s: "

#: common/flatpak-dir.c:9750
#, c-format
msgid "While trying to checkout %s into %s: "
msgstr ""

#: common/flatpak-dir.c:9769
msgid "While trying to checkout metadata subpath: "
msgstr ""

#: common/flatpak-dir.c:9801
#, c-format
msgid "While trying to checkout subpath ‘%s’: "
msgstr ""

#: common/flatpak-dir.c:9811
msgid "While trying to remove existing extra dir: "
msgstr "Počas pokusu o odstránenie existujúceho adresára navyše: "

#: common/flatpak-dir.c:9822
msgid "While trying to apply extra data: "
msgstr "Počas pokusu o aplikáciu údajov navyše: "

#: common/flatpak-dir.c:9849
#, fuzzy, c-format
msgid "Invalid commit ref %s: "
msgstr "Neplatný identifikátor pid %s"

#: common/flatpak-dir.c:9857 common/flatpak-dir.c:9869
#, c-format
msgid "Deployed ref %s does not match commit (%s)"
msgstr ""

#: common/flatpak-dir.c:9863
#, c-format
msgid "Deployed ref %s branch does not match commit (%s)"
msgstr ""

#: common/flatpak-dir.c:10125 common/flatpak-installation.c:1911
#, c-format
msgid "%s branch %s already installed"
msgstr "Aplikácia %s vetva %s je už nainštalovaná"

#: common/flatpak-dir.c:10985
#, c-format
msgid "Could not unmount revokefs-fuse filesystem at %s: "
msgstr ""

#: common/flatpak-dir.c:11289
#, c-format
msgid "This version of %s is already installed"
msgstr "Táto verzia aplikácie %s je už nainštalovaná"

#: common/flatpak-dir.c:11302
#, c-format
msgid "Can't change remote during bundle install"
msgstr ""

#: common/flatpak-dir.c:11571
msgid "Can't update to a specific commit without root permissions"
msgstr ""

#: common/flatpak-dir.c:11852
#, c-format
msgid "Can't remove %s, it is needed for: %s"
msgstr ""

#: common/flatpak-dir.c:11912 common/flatpak-installation.c:2067
#, c-format
msgid "%s branch %s is not installed"
msgstr "Aplikácia %s vetva %s nie je nainštalovaná"

#: common/flatpak-dir.c:12165
#, fuzzy, c-format
msgid "%s commit %s not installed"
msgstr "Aplikácia %s %s nie je nainštalovaná"

#: common/flatpak-dir.c:12501
#, c-format
msgid "Pruning repo failed: %s"
msgstr ""

#: common/flatpak-dir.c:12669 common/flatpak-dir.c:12675
#, fuzzy, c-format
msgid "Failed to load filter '%s'"
msgstr "Zlyhalo čítanie začlenenia %s: "

#: common/flatpak-dir.c:12681
#, fuzzy, c-format
msgid "Failed to parse filter '%s'"
msgstr "Zlyhalo čítanie začlenenia %s: "

#: common/flatpak-dir.c:12963
#, fuzzy
msgid "Failed to write summary cache: "
msgstr "Zlyhalo vytvorenie dočasného súboru"

#: common/flatpak-dir.c:12982
#, fuzzy, c-format
msgid "No oci summary cached for remote '%s'"
msgstr "Aplikácia %s vetva %s je už nainštalovaná"

#: common/flatpak-dir.c:13207
#, fuzzy, c-format
msgid "No cached summary for remote '%s'"
msgstr "Aplikácia %s vetva %s je už nainštalovaná"

#: common/flatpak-dir.c:13248
#, fuzzy, c-format
msgid "Invalid checksum for indexed summary %s read from %s"
msgstr "Nesprávna veľkosť pre údaje navyše %s"

#: common/flatpak-dir.c:13321
#, c-format
msgid ""
"Remote listing for %s not available; server has no summary file. Check the "
"URL passed to remote-add was valid."
msgstr ""

#: common/flatpak-dir.c:13698
#, fuzzy, c-format
msgid "Invalid checksum for indexed summary %s for remote '%s'"
msgstr "Nesprávna veľkosť pre údaje navyše %s"

#: common/flatpak-dir.c:14388
#, c-format
msgid "Multiple branches available for %s, you must specify one of: "
msgstr ""

#: common/flatpak-dir.c:14454
#, c-format
msgid "Nothing matches %s"
msgstr "Nič nevyhovuje názvu %s"

#: common/flatpak-dir.c:14562
#, fuzzy, c-format
msgid "Can't find ref %s%s%s%s%s"
msgstr "Nedá sa nájsť %s%s%s%s%s vo vzdialenom repozitári %s"

#: common/flatpak-dir.c:14605
#, c-format
msgid "Error searching remote %s: %s"
msgstr ""

#: common/flatpak-dir.c:14702
#, c-format
msgid "Error searching local repository: %s"
msgstr ""

#: common/flatpak-dir.c:14839
#, fuzzy, c-format
msgid "%s/%s/%s not installed"
msgstr "Aplikácia %s %s nie je nainštalovaná"

#: common/flatpak-dir.c:15042
#, c-format
msgid "Could not find installation %s"
msgstr "Nepodarilo sa nájsť inštaláciu %s"

#: common/flatpak-dir.c:15612
#, fuzzy, c-format
msgid "Invalid file format, no %s group"
msgstr "Neplatný identifikátor pid %s"

#: common/flatpak-dir.c:15617 common/flatpak-repo-utils.c:2836
#, c-format
msgid "Invalid version %s, only 1 supported"
msgstr ""

#: common/flatpak-dir.c:15622 common/flatpak-dir.c:15627
#, fuzzy, c-format
msgid "Invalid file format, no %s specified"
msgstr "Neplatný identifikátor pid %s"

#. Check some minimal size so we don't get crap
#: common/flatpak-dir.c:15647
#, fuzzy
msgid "Invalid file format, gpg key invalid"
msgstr "Neplatný identifikátor pid %s"

#: common/flatpak-dir.c:15675 common/flatpak-repo-utils.c:2917
msgid "Collection ID requires GPG key to be provided"
msgstr ""

#: common/flatpak-dir.c:15718
#, c-format
msgid "Runtime %s, branch %s is already installed"
msgstr "Prostredie %s, vetva %s je už nainštalovaná"

#: common/flatpak-dir.c:15719
#, c-format
msgid "App %s, branch %s is already installed"
msgstr "Aplikácia %s, vetva %s je už nainštalovaná"

#: common/flatpak-dir.c:15953
#, c-format
msgid "Can't remove remote '%s' with installed ref %s (at least)"
msgstr ""

#: common/flatpak-dir.c:16058
#, fuzzy, c-format
msgid "Invalid character '/' in remote name: %s"
msgstr "Nedá sa nájsť %s vo vzdialenom repozitári %s"

#: common/flatpak-dir.c:16064
#, c-format
msgid "No configuration for remote %s specified"
msgstr ""

#: common/flatpak-dir.c:17597
#, fuzzy, c-format
msgid "Skipping deletion of mirror ref (%s, %s)…\n"
msgstr "Neplatný identifikátor pid %s"

#: common/flatpak-exports.c:931
#, c-format
msgid "An absolute path is required"
msgstr ""

#: common/flatpak-exports.c:948
#, fuzzy, c-format
msgid "Unable to open path \"%s\": %s"
msgstr "Zlyhalo čítanie začlenenia %s: "

#: common/flatpak-exports.c:955
#, fuzzy, c-format
msgid "Unable to get file type of \"%s\": %s"
msgstr "Zlyhalo čítanie začlenenia %s: "

#: common/flatpak-exports.c:964
#, c-format
msgid "File \"%s\" has unsupported type 0o%o"
msgstr ""

#: common/flatpak-exports.c:970
#, c-format
msgid "Unable to get filesystem information for \"%s\": %s"
msgstr ""

#: common/flatpak-exports.c:980
#, c-format
msgid "Ignoring blocking autofs path \"%s\""
msgstr ""

#: common/flatpak-exports.c:996 common/flatpak-exports.c:1009
#: common/flatpak-exports.c:1022
#, c-format
msgid "Path \"%s\" is reserved by Flatpak"
msgstr ""

#: common/flatpak-exports.c:1076
#, fuzzy, c-format
msgid "Unable to resolve symbolic link \"%s\": %s"
msgstr "Zlyhalo čítanie začlenenia %s: "

#: common/flatpak-glib-backports.c:69
msgid "Empty string is not a number"
msgstr ""

#: common/flatpak-glib-backports.c:95
#, c-format
msgid "“%s” is not an unsigned number"
msgstr ""

#: common/flatpak-glib-backports.c:105
#, c-format
msgid "Number “%s” is out of bounds [%s, %s]"
msgstr ""

#: common/flatpak-image-source.c:83
msgid "Only sha256 image checksums are supported"
msgstr ""

#: common/flatpak-image-source.c:100 common/flatpak-image-source.c:108
msgid "Image is not a manifest"
msgstr ""

#: common/flatpak-image-source.c:123
msgid "No org.flatpak.ref found in image"
msgstr ""

#: common/flatpak-image-source.c:148
#, fuzzy, c-format
msgid "Ref '%s' not found in registry"
msgstr "„%s“ nie je platným repozitárom"

#: common/flatpak-image-source.c:157
msgid "Multiple images in registry, specify a ref with --ref"
msgstr ""

#: common/flatpak-installation.c:834
#, fuzzy, c-format
msgid "Ref %s not installed"
msgstr "Aplikácia %s %s nie je nainštalovaná"

#: common/flatpak-installation.c:875
#, fuzzy, c-format
msgid "App %s not installed"
msgstr "Aplikácia %s %s nie je nainštalovaná"

#: common/flatpak-installation.c:1395
#, fuzzy, c-format
msgid "Remote '%s' already exists"
msgstr "Vzdialený repozitár %s už existuje"

#: common/flatpak-installation.c:1946
#, fuzzy, c-format
msgid "As requested, %s was only pulled, but not installed"
msgstr "Požadované rozšírenie %s je nainštalované iba čiastočne"

#: common/flatpak-instance.c:533 common/flatpak-instance.c:687
#: common/flatpak-instance.c:728
#, fuzzy, c-format
msgid "Unable to create directory %s"
msgstr "Zlyhalo čítanie začlenenia %s: "

#: common/flatpak-instance.c:554
#, fuzzy, c-format
msgid "Unable to lock %s"
msgstr "Zlyhalo čítanie začlenenia %s: "

#: common/flatpak-instance.c:627
#, c-format
msgid "Unable to create temporary directory in %s"
msgstr ""

#: common/flatpak-instance.c:639
#, fuzzy, c-format
msgid "Unable to create file %s"
msgstr "Zlyhalo čítanie začlenenia %s: "

#: common/flatpak-instance.c:646
#, fuzzy, c-format
msgid "Unable to update symbolic link %s/%s"
msgstr "Zlyhalo čítanie začlenenia %s: "

#: common/flatpak-oci-registry.c:1197
msgid "Only Bearer authentication supported"
msgstr ""

#: common/flatpak-oci-registry.c:1206
#, fuzzy
msgid "Only realm in authentication request"
msgstr "Neplatný identifikátor pid %s"

#: common/flatpak-oci-registry.c:1213
#, fuzzy
msgid "Invalid realm in authentication request"
msgstr "Neplatný identifikátor pid %s"

#: common/flatpak-oci-registry.c:1283
#, fuzzy, c-format
msgid "Authorization failed: %s"
msgstr "Neplatný identifikátor pid %s"

#: common/flatpak-oci-registry.c:1285
msgid "Authorization failed"
msgstr ""

#: common/flatpak-oci-registry.c:1289
#, c-format
msgid "Unexpected response status %d when requesting token: %s"
msgstr ""

#: common/flatpak-oci-registry.c:1300
#, fuzzy
msgid "Invalid authentication request response"
msgstr "Neplatný identifikátor pid %s"

#: common/flatpak-oci-registry.c:1731
#, c-format
msgid "Flatpak was compiled without zstd support"
msgstr ""

#: common/flatpak-oci-registry.c:1923 common/flatpak-oci-registry.c:1975
#: common/flatpak-oci-registry.c:2004 common/flatpak-oci-registry.c:2059
#: common/flatpak-oci-registry.c:2115 common/flatpak-oci-registry.c:2193
#, fuzzy
msgid "Invalid delta file format"
msgstr "Neplatný identifikátor pid %s"

#: common/flatpak-oci-registry.c:3198 common/flatpak-oci-registry.c:3382
msgid "Invalid OCI image config"
msgstr ""

#: common/flatpak-oci-registry.c:3260 common/flatpak-oci-registry.c:3531
#, c-format
msgid "Wrong layer checksum, expected %s, was %s"
msgstr ""

#: common/flatpak-oci-registry.c:3359
#, c-format
msgid "No ref specified for OCI image %s"
msgstr ""

#: common/flatpak-oci-registry.c:3369
#, c-format
msgid "Wrong ref (%s) specified for OCI image %s, expected %s"
msgstr ""

#: common/flatpak-progress.c:236
#, fuzzy, c-format
msgid "Downloading metadata: %u/(estimating) %s"
msgstr "Zobrazí referenciu"

#: common/flatpak-progress.c:260
#, fuzzy, c-format
msgid "Downloading: %s/%s"
msgstr "Zobrazí referenciu"

#: common/flatpak-progress.c:280
#, fuzzy, c-format
msgid "Downloading extra data: %s/%s"
msgstr "Zobrazí referenciu"

#: common/flatpak-progress.c:285
#, fuzzy, c-format
msgid "Downloading files: %d/%d %s"
msgstr "Zobrazí referenciu"

#: common/flatpak-ref-utils.c:122
msgid "Name can't be empty"
msgstr ""

#: common/flatpak-ref-utils.c:129
msgid "Name can't be longer than 255 characters"
msgstr ""

#: common/flatpak-ref-utils.c:142
msgid "Name can't start with a period"
msgstr ""

#: common/flatpak-ref-utils.c:148
#, c-format
msgid "Name can't start with %c"
msgstr ""

#: common/flatpak-ref-utils.c:164
msgid "Name can't end with a period"
msgstr ""

#: common/flatpak-ref-utils.c:171 common/flatpak-ref-utils.c:183
msgid "Only last name segment can contain -"
msgstr ""

#: common/flatpak-ref-utils.c:174
#, c-format
msgid "Name segment can't start with %c"
msgstr ""

#: common/flatpak-ref-utils.c:186
#, c-format
msgid "Name can't contain %c"
msgstr ""

#: common/flatpak-ref-utils.c:195
msgid "Names must contain at least 2 periods"
msgstr ""

#: common/flatpak-ref-utils.c:312
msgid "Arch can't be empty"
msgstr ""

#: common/flatpak-ref-utils.c:323
#, c-format
msgid "Arch can't contain %c"
msgstr ""

#: common/flatpak-ref-utils.c:385
msgid "Branch can't be empty"
msgstr ""

#: common/flatpak-ref-utils.c:395
#, c-format
msgid "Branch can't start with %c"
msgstr ""

#: common/flatpak-ref-utils.c:405
#, c-format
msgid "Branch can't contain %c"
msgstr ""

#: common/flatpak-ref-utils.c:615 common/flatpak-ref-utils.c:865
msgid "Ref too long"
msgstr ""

#: common/flatpak-ref-utils.c:627
#, fuzzy
msgid "Invalid remote name"
msgstr "Žiadny vzdialený repozitár %s"

#: common/flatpak-ref-utils.c:641
#, fuzzy, c-format
msgid "%s is not application or runtime"
msgstr "Podpíše aplikáciu alebo prostredie"

#: common/flatpak-ref-utils.c:650 common/flatpak-ref-utils.c:667
#: common/flatpak-ref-utils.c:683
#, fuzzy, c-format
msgid "Wrong number of components in %s"
msgstr "Príliš veľa parametrov"

#: common/flatpak-ref-utils.c:656
#, fuzzy, c-format
msgid "Invalid name %.*s: %s"
msgstr "Neplatný identifikátor pid %s"

#: common/flatpak-ref-utils.c:673
#, fuzzy, c-format
msgid "Invalid arch: %.*s: %s"
msgstr "„%s“ nie je platným názvom vetvy: %s"

#: common/flatpak-ref-utils.c:816
#, fuzzy, c-format
msgid "Invalid name %s: %s"
msgstr "Neplatný identifikátor pid %s"

#: common/flatpak-ref-utils.c:834
#, fuzzy, c-format
msgid "Invalid arch: %s: %s"
msgstr "„%s“ nie je platným názvom vetvy: %s"

#: common/flatpak-ref-utils.c:853
#, fuzzy, c-format
msgid "Invalid branch: %s: %s"
msgstr "„%s“ nie je platným názvom vetvy: %s"

#: common/flatpak-ref-utils.c:962 common/flatpak-ref-utils.c:970
#: common/flatpak-ref-utils.c:978
#, fuzzy, c-format
msgid "Wrong number of components in partial ref %s"
msgstr "Príliš veľa parametrov"

#: common/flatpak-ref-utils.c:1298
#, fuzzy
msgid " development platform"
msgstr "Použije vývojové prostredie"

#: common/flatpak-ref-utils.c:1300
msgid " platform"
msgstr ""

#: common/flatpak-ref-utils.c:1302
#, fuzzy
msgid " application base"
msgstr "Spustí aplikáciu"

#: common/flatpak-ref-utils.c:1305
msgid " debug symbols"
msgstr ""

#: common/flatpak-ref-utils.c:1307
msgid " sourcecode"
msgstr ""

#: common/flatpak-ref-utils.c:1309
#, fuzzy
msgid " translations"
msgstr "Inštalovanie: %s\n"

#: common/flatpak-ref-utils.c:1311
msgid " docs"
msgstr ""

#: common/flatpak-ref-utils.c:1578
#, fuzzy, c-format
msgid "Invalid id %s: %s"
msgstr "Neplatný identifikátor pid %s"

#: common/flatpak-remote.c:1216
#, fuzzy, c-format
msgid "Bad remote name: %s"
msgstr "Žiadny vzdialený repozitár %s"

#: common/flatpak-remote.c:1220
#, fuzzy
msgid "No URL specified"
msgstr "Nebol určený žiadny príkaz"

#: common/flatpak-remote.c:1266
msgid "GPG verification must be enabled when a collection ID is set"
msgstr ""

#: common/flatpak-repo-utils.c:344
#, c-format
msgid "No extra data sources"
msgstr "Žiadne zdroje údajov navyše"

#: common/flatpak-repo-utils.c:2817
#, c-format
msgid "Invalid %s: Missing group ‘%s’"
msgstr ""

#: common/flatpak-repo-utils.c:2826
#, c-format
msgid "Invalid %s: Missing key ‘%s’"
msgstr ""

#: common/flatpak-repo-utils.c:2876
#, fuzzy
msgid "Invalid gpg key"
msgstr "Neplatný identifikátor pid %s"

#: common/flatpak-repo-utils.c:3217
#, fuzzy, c-format
msgid "Error copying 64x64 icon for component %s: %s\n"
msgstr "Aktualizovanie zhrnutia\n"

#: common/flatpak-repo-utils.c:3223
#, fuzzy, c-format
msgid "Error copying 128x128 icon for component %s: %s\n"
msgstr "Aktualizovanie zhrnutia\n"

#: common/flatpak-repo-utils.c:3362
#, c-format
msgid "%s is end-of-life, ignoring for appstream"
msgstr ""

#: common/flatpak-repo-utils.c:3397
#, fuzzy, c-format
msgid "No appstream data for %s: %s\n"
msgstr ""
"Chyba počas aktualizácie metaúdajov navyše pre „%s“: %s\n"
"\n"

#: common/flatpak-repo-utils.c:3744
#, fuzzy
msgid "Invalid bundle, no ref in metadata"
msgstr "Neplatný identifikátor pid %s"

#: common/flatpak-repo-utils.c:3846
#, c-format
msgid "Collection ‘%s’ of bundle doesn’t match collection ‘%s’ of remote"
msgstr ""

#: common/flatpak-repo-utils.c:3923
msgid "Metadata in header and app are inconsistent"
msgstr ""

#: common/flatpak-run.c:951
msgid "No systemd user session available, cgroups not available"
msgstr ""

#: common/flatpak-run.c:1496
msgid "Unable to allocate instance id"
msgstr ""

#: common/flatpak-run.c:1632 common/flatpak-run.c:1641
#, fuzzy, c-format
msgid "Failed to open flatpak-info file: %s"
msgstr "Zlyhalo otvorenie dočasného súboru flatpak-info"

#: common/flatpak-run.c:1668
#, fuzzy, c-format
msgid "Failed to open bwrapinfo.json file: %s"
msgstr "Zlyhalo otvorenie dočasného súboru flatpak-info"

#: common/flatpak-run.c:1689
#, fuzzy, c-format
msgid "Failed to write to instance id fd: %s"
msgstr "Zlyhalo vytvorenie dočasného súboru"

#: common/flatpak-run.c:2096
msgid "Initialize seccomp failed"
msgstr ""

#: common/flatpak-run.c:2135
#, fuzzy, c-format
msgid "Failed to add architecture to seccomp filter: %s"
msgstr "Zlyhal zápis dočasného súboru"

#: common/flatpak-run.c:2143
#, fuzzy, c-format
msgid "Failed to add multiarch architecture to seccomp filter: %s"
msgstr "Zlyhal zápis dočasného súboru"

#: common/flatpak-run.c:2175 common/flatpak-run.c:2192
#: common/flatpak-run.c:2214
#, fuzzy, c-format
msgid "Failed to block syscall %d: %s"
msgstr "Zlyhalo čítanie začlenenia %s: "

#: common/flatpak-run.c:2247
#, fuzzy, c-format
msgid "Failed to export bpf: %s"
msgstr "Zlyhalo čítanie z exportovaného súboru"

#: common/flatpak-run.c:2587
#, fuzzy, c-format
msgid "Failed to open ‘%s’"
msgstr "Zlyhalo otvorenie dočasného súboru flatpak-info"

#: common/flatpak-run.c:2597
#, c-format
msgid ""
"Directory forwarding needs version 4 of the document portal (have version %d)"
msgstr ""

#: common/flatpak-run.c:2915
#, c-format
msgid "ldconfig failed, exit status %d"
msgstr ""

#: common/flatpak-run.c:2922
msgid "Can't open generated ld.so.cache"
msgstr ""

#. Translators: The placeholder is for an app ref.
#: common/flatpak-run.c:3045
#, c-format
msgid "Running %s is not allowed by the policy set by your administrator"
msgstr ""

#: common/flatpak-run.c:3202
msgid ""
"\"flatpak run\" is not intended to be run as `sudo flatpak run`. Use `sudo "
"-i` or `su -l` instead and invoke \"flatpak run\" from inside the new shell."
msgstr ""

#: common/flatpak-run.c:3413
#, fuzzy, c-format
msgid "Failed to migrate from %s: %s"
msgstr "Zlyhalo čítanie začlenenia %s: "

#: common/flatpak-run.c:3434
#, c-format
msgid "Failed to migrate old app data directory %s to new name %s: %s"
msgstr ""

#: common/flatpak-run.c:3443
#, fuzzy, c-format
msgid "Failed to create symlink while migrating %s: %s"
msgstr "Zlyhalo čítanie začlenenia %s: "

#: common/flatpak-run-dbus.c:46
#, fuzzy
msgid "Failed to open app info file"
msgstr "Zlyhalo otvorenie súboru s informáciami o aplikácii: %s"

#: common/flatpak-run-dbus.c:149
msgid "Unable to create sync pipe"
msgstr ""

#: common/flatpak-run-dbus.c:185
msgid "Failed to sync with dbus proxy"
msgstr ""

#: common/flatpak-transaction.c:2275
#, c-format
msgid "Warning: Problem looking for related refs: %s"
msgstr ""

#: common/flatpak-transaction.c:2493
#, fuzzy, c-format
msgid "The application %s requires the runtime %s which was not found"
msgstr "Na inštaláciu softvéru sa vyžaduje overenie totožnosti"

#: common/flatpak-transaction.c:2509
#, fuzzy, c-format
msgid "The application %s requires the runtime %s which is not installed"
msgstr "Na inštaláciu softvéru sa vyžaduje overenie totožnosti"

#: common/flatpak-transaction.c:2641
#, c-format
msgid "Can't uninstall %s which is needed by %s"
msgstr ""

#: common/flatpak-transaction.c:2740
#, c-format
msgid "Remote %s disabled, ignoring %s update"
msgstr ""

#: common/flatpak-transaction.c:2773
#, fuzzy, c-format
msgid "%s is already installed"
msgstr "Aplikácia %s vetva %s je už nainštalovaná"

#: common/flatpak-transaction.c:2776
#, fuzzy, c-format
msgid "%s is already installed from remote %s"
msgstr "Aplikácia %s vetva %s je už nainštalovaná"

#: common/flatpak-transaction.c:3120
#, fuzzy, c-format
msgid "Invalid .flatpakref: %s"
msgstr "Neplatný identifikátor pid %s"

#: common/flatpak-transaction.c:3161
msgid "Warning: Could not mark already installed apps as preinstalled"
msgstr ""

#: common/flatpak-transaction.c:3382
#, fuzzy, c-format
msgid "Error updating remote metadata for '%s': %s"
msgstr ""
"Chyba počas aktualizácie metaúdajov navyše pre „%s“: %s\n"
"\n"

#: common/flatpak-transaction.c:3885
#, c-format
msgid ""
"Warning: Treating remote fetch error as non-fatal since %s is already "
"installed: %s"
msgstr ""

#: common/flatpak-transaction.c:4209
#, fuzzy, c-format
msgid "No authenticator installed for remote '%s'"
msgstr "Na aktualizáciu softvéru sa vyžaduje overenie totožnosti"

#: common/flatpak-transaction.c:4313 common/flatpak-transaction.c:4320
#, fuzzy, c-format
msgid "Failed to get tokens for ref: %s"
msgstr "Zlyhalo otvorenie súboru temp"

#: common/flatpak-transaction.c:4315 common/flatpak-transaction.c:4322
#, fuzzy
msgid "Failed to get tokens for ref"
msgstr "Zlyhalo otvorenie súboru temp"

#: common/flatpak-transaction.c:4580
#, c-format
msgid "Ref %s from %s matches more than one transaction operation"
msgstr ""

#: common/flatpak-transaction.c:4581 common/flatpak-transaction.c:4591
#, fuzzy
msgid "any remote"
msgstr "Žiadny vzdialený repozitár %s"

#: common/flatpak-transaction.c:4590
#, c-format
msgid "No transaction operation found for ref %s from %s"
msgstr ""

#: common/flatpak-transaction.c:4713
#, c-format
msgid "Flatpakrepo URL %s not file, HTTP or HTTPS"
msgstr ""

#: common/flatpak-transaction.c:4719
#, fuzzy, c-format
msgid "Can't load dependent file %s: "
msgstr "Objektov celkom: %u\n"

#: common/flatpak-transaction.c:4727
#, fuzzy, c-format
msgid "Invalid .flatpakrepo: %s"
msgstr "Neplatný identifikátor pid %s"

#: common/flatpak-transaction.c:5454
msgid "Transaction already executed"
msgstr ""

#: common/flatpak-transaction.c:5469
msgid ""
"Refusing to operate on a user installation as root! This can lead to "
"incorrect file ownership and permission errors."
msgstr ""

#: common/flatpak-transaction.c:5567 common/flatpak-transaction.c:5580
msgid "Aborted by user"
msgstr ""

#: common/flatpak-transaction.c:5605
#, c-format
msgid "Skipping %s due to previous error"
msgstr ""

#: common/flatpak-transaction.c:5659
#, c-format
msgid "Aborted due to failure (%s)"
msgstr ""

#: common/flatpak-uri.c:118
#, fuzzy, no-c-format
msgid "Invalid %-encoding in URI"
msgstr "Neplatný identifikátor pid %s"

#: common/flatpak-uri.c:135
msgid "Illegal character in URI"
msgstr ""

#: common/flatpak-uri.c:169
msgid "Non-UTF-8 characters in URI"
msgstr ""

#: common/flatpak-uri.c:275
#, c-format
msgid "Invalid IPv6 address ‘%.*s’ in URI"
msgstr ""

#: common/flatpak-uri.c:330
#, c-format
msgid "Illegal encoded IP address ‘%.*s’ in URI"
msgstr ""

#: common/flatpak-uri.c:342
#, c-format
msgid "Illegal internationalized hostname ‘%.*s’ in URI"
msgstr ""

#: common/flatpak-uri.c:374 common/flatpak-uri.c:386
#, c-format
msgid "Could not parse port ‘%.*s’ in URI"
msgstr ""

#: common/flatpak-uri.c:393
#, c-format
msgid "Port ‘%.*s’ in URI is out of range"
msgstr ""

#: common/flatpak-uri.c:910
msgid "URI is not absolute, and no base URI was provided"
msgstr ""

#: common/flatpak-usb.c:83
#, c-format
msgid "USB device query 'all' must not have data"
msgstr ""

#: common/flatpak-usb.c:102
#, c-format
msgid "USB query rule 'cls' must be in the form CLASS:SUBCLASS or CLASS:*"
msgstr ""

#: common/flatpak-usb.c:111
#, fuzzy, c-format
msgid "Invalid USB class"
msgstr "Neplatný identifikátor pid %s"

#: common/flatpak-usb.c:125
#, c-format
msgid "Invalid USB subclass"
msgstr ""

#: common/flatpak-usb.c:141 common/flatpak-usb.c:148
#, c-format
msgid "USB query rule 'dev' must have a valid 4-digit hexadecimal product id"
msgstr ""

#: common/flatpak-usb.c:164 common/flatpak-usb.c:171
#, c-format
msgid "USB query rule 'vnd' must have a valid 4-digit hexadecimal vendor id"
msgstr ""

#: common/flatpak-usb.c:205
#, c-format
msgid "USB device queries must be in the form TYPE:DATA"
msgstr ""

#: common/flatpak-usb.c:225
#, c-format
msgid "Unknown USB query rule %s"
msgstr ""

#: common/flatpak-usb.c:248
#, c-format
msgid "Empty USB query"
msgstr ""

#: common/flatpak-usb.c:274
#, c-format
msgid "Multiple USB query rules of the same type is not supported"
msgstr ""

#: common/flatpak-usb.c:283
#, c-format
msgid "'all' must not contain extra query rules"
msgstr ""

#: common/flatpak-usb.c:291
#, c-format
msgid "USB queries with 'dev' must also specify vendors"
msgstr ""

#: common/flatpak-utils.c:712
msgid "Glob can't match apps"
msgstr ""

#: common/flatpak-utils.c:737
msgid "Empty glob"
msgstr ""

#: common/flatpak-utils.c:756
#, fuzzy
msgid "Too many segments in glob"
msgstr "Príliš veľa parametrov"

#: common/flatpak-utils.c:777
#, fuzzy, c-format
msgid "Invalid glob character '%c'"
msgstr "Neplatný identifikátor pid %s"

#: common/flatpak-utils.c:831
#, c-format
msgid "Missing glob on line %d"
msgstr ""

#: common/flatpak-utils.c:835
#, c-format
msgid "Trailing text on line %d"
msgstr ""

#: common/flatpak-utils.c:839
#, c-format
msgid "on line %d"
msgstr ""

#: common/flatpak-utils.c:861
#, c-format
msgid "Unexpected word '%s' on line %d"
msgstr ""

#: common/flatpak-utils.c:2118
#, c-format
msgid "Invalid require-flatpak argument %s"
msgstr ""

#: common/flatpak-utils.c:2128 common/flatpak-utils.c:2147
#, c-format
msgid "%s needs a later flatpak version (%s)"
msgstr ""

#: oci-authenticator/flatpak-oci-authenticator.c:291
msgid "Not a oci remote, missing summary.xa.oci-repository"
msgstr ""

#: oci-authenticator/flatpak-oci-authenticator.c:477
msgid "Not a OCI remote"
msgstr ""

#: oci-authenticator/flatpak-oci-authenticator.c:488
#, fuzzy
msgid "Invalid token"
msgstr "Neplatný identifikátor pid %s"

#: portal/flatpak-portal.c:2292
#, fuzzy, c-format
msgid "No portal support found"
msgstr "Nič nevyhovuje názvu %s"

#: portal/flatpak-portal.c:2298
msgid "Deny"
msgstr ""

#: portal/flatpak-portal.c:2300
#, fuzzy
msgid "Update"
msgstr "Žiadne aktualizácie.\n"

#: portal/flatpak-portal.c:2305
#, fuzzy, c-format
msgid "Update %s?"
msgstr "Aktualizovanie zhrnutia\n"

#: portal/flatpak-portal.c:2317
msgid "The application wants to update itself."
msgstr ""

#: portal/flatpak-portal.c:2318
msgid "Update access can be changed any time from the privacy settings."
msgstr ""

#: portal/flatpak-portal.c:2343
#, c-format
msgid "Application update not allowed"
msgstr ""

#: portal/flatpak-portal.c:2501
#, c-format
msgid "Self update not supported, new version requires new permissions"
msgstr ""

#: portal/flatpak-portal.c:2684 portal/flatpak-portal.c:2702
#, fuzzy, c-format
msgid "Update ended unexpectedly"
msgstr "Aktualizovanie podpísaného prostredia"

#. SECURITY:
#. - Normal users need admin authentication to install software
#. system-wide.
#. - Note that we install polkit rules that allow local users
#. in the wheel group to install without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:23
msgid "Install signed application"
msgstr "Nainštalovanie podpísanej aplikácie"

#: system-helper/org.freedesktop.Flatpak.policy.in:24
#: system-helper/org.freedesktop.Flatpak.policy.in:42
#, fuzzy
msgid "Authentication is required to install software"
msgstr "Na aktualizáciu softvéru sa vyžaduje overenie totožnosti"

#. SECURITY:
#. - Normal users need admin authentication to install software
#. system-wide.
#. - Note that we install polkit rules that allow local users
#. in the wheel group to install without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:41
msgid "Install signed runtime"
msgstr "Nainštalovanie podpísaného prostredia"

#. SECURITY:
#. - Normal users do not require admin authentication to update an
#. app as the commit will be signed, and the action is required
#. to update the system when unattended.
#. - Changing this to anything other than 'yes' will break unattended
#. updates.
#: system-helper/org.freedesktop.Flatpak.policy.in:60
msgid "Update signed application"
msgstr "Aktualizovanie podpísanej aplikácie"

#: system-helper/org.freedesktop.Flatpak.policy.in:61
#: system-helper/org.freedesktop.Flatpak.policy.in:80
msgid "Authentication is required to update software"
msgstr "Na aktualizáciu softvéru sa vyžaduje overenie totožnosti"

#. SECURITY:
#. - Normal users do not require admin authentication to update a
#. runtime as the commit will be signed, and the action is required
#. to update the system when unattended.
#. - Changing this to anything other than 'yes' will break unattended
#. updates.
#: system-helper/org.freedesktop.Flatpak.policy.in:79
msgid "Update signed runtime"
msgstr "Aktualizovanie podpísaného prostredia"

#. SECURITY:
#. - Normal users do not need authentication to update metadata
#. from signed repositories.
#: system-helper/org.freedesktop.Flatpak.policy.in:94
#, fuzzy
msgid "Update remote metadata"
msgstr "Použije alternatívny súbor pre metaúdaje"

#: system-helper/org.freedesktop.Flatpak.policy.in:95
#, fuzzy
msgid "Authentication is required to update remote info"
msgstr "Na aktualizáciu softvéru sa vyžaduje overenie totožnosti"

#. SECURITY:
#. - Normal users do not need authentication to modify the
#. OSTree repository
#. - Note that we install polkit rules that allow local users
#. in the wheel group to modify repos without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:111
#, fuzzy
msgid "Update system repository"
msgstr "Aktualizuje súbor zhrnutia v repozitári"

#: system-helper/org.freedesktop.Flatpak.policy.in:112
#, fuzzy
msgid "Authentication is required to modify a system repository"
msgstr "Na aktualizáciu softvéru sa vyžaduje overenie totožnosti"

#. SECURITY:
#. - Normal users need admin authentication to install software
#. system-wide.
#: system-helper/org.freedesktop.Flatpak.policy.in:126
msgid "Install bundle"
msgstr "Nainštalovanie balíka"

#: system-helper/org.freedesktop.Flatpak.policy.in:127
#, fuzzy
msgid "Authentication is required to install software from $(path)"
msgstr "Na inštaláciu softvéru sa vyžaduje overenie totožnosti"

#. SECURITY:
#. - Normal users need admin authentication to uninstall software
#. system-wide.
#. - Note that we install polkit rules that allow local users
#. in the wheel group to uninstall without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:144
msgid "Uninstall runtime"
msgstr "Odinštalovanie prostredia"

#: system-helper/org.freedesktop.Flatpak.policy.in:145
#, fuzzy
msgid "Authentication is required to uninstall software"
msgstr "Na odinštalovanie softvéru sa vyžaduje overenie totožnosti"

#. SECURITY:
#. - Normal users need admin authentication to uninstall software
#. system-wide.
#. - Note that we install polkit rules that allow local users
#. in the wheel group to uninstall without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:161
#, fuzzy
msgid "Uninstall app"
msgstr "Odinštalovanie prostredia"

#: system-helper/org.freedesktop.Flatpak.policy.in:162
#, fuzzy
msgid "Authentication is required to uninstall $(ref)"
msgstr "Na odinštalovanie softvéru sa vyžaduje overenie totožnosti"

#. SECURITY:
#. - Normal users need admin authentication to configure system-wide
#. software repositories.
#: system-helper/org.freedesktop.Flatpak.policy.in:177
msgid "Configure Remote"
msgstr "Konfigurácia vzdialeného repozitára"

#: system-helper/org.freedesktop.Flatpak.policy.in:178
#, fuzzy
msgid "Authentication is required to configure software repositories"
msgstr ""
"Na konfiguráciu softvérových repozitárov sa vyžaduje overenie totožnosti"

#. SECURITY:
#. - Normal users need admin authentication to configure the system-wide
#. Flatpak installation.
#: system-helper/org.freedesktop.Flatpak.policy.in:192
#, fuzzy
msgid "Configure"
msgstr "Konfigurácia vzdialeného repozitára"

#: system-helper/org.freedesktop.Flatpak.policy.in:193
#, fuzzy
msgid "Authentication is required to configure software installation"
msgstr ""
"Na konfiguráciu softvérových repozitárov sa vyžaduje overenie totožnosti"

#. SECURITY:
#. - Normal users do not require admin authentication to update
#. appstream data as it will be signed, and the action is required
#. to update the system when unattended.
#. - Changing this to anything other than 'yes' will break unattended
#. updates.
#: system-helper/org.freedesktop.Flatpak.policy.in:210
msgid "Update appstream"
msgstr ""

#: system-helper/org.freedesktop.Flatpak.policy.in:211
#, fuzzy
msgid "Authentication is required to update information about software"
msgstr "Na aktualizáciu softvéru sa vyžaduje overenie totožnosti"

#. SECURITY:
#. - Normal users do not require admin authentication to update
#. metadata as it will be signed, and the action is required
#. to update the system when unattended.
#. - Changing this to anything other than 'yes' will break unattended
#. updates.
#: system-helper/org.freedesktop.Flatpak.policy.in:228
#, fuzzy
msgid "Update metadata"
msgstr "Použije alternatívny súbor pre metaúdaje"

#: system-helper/org.freedesktop.Flatpak.policy.in:229
#, fuzzy
msgid "Authentication is required to update metadata"
msgstr "Na aktualizáciu softvéru sa vyžaduje overenie totožnosti"

#. SECURITY:
#. - Authorisation to actually install software is controlled by
#. org.freedesktop.Flatpak.app-install.
#. - This action is checked after app-install, as it can only be done
#. once the app’s data (including its content rating) has been
#. downloaded.
#. - This action is checked to see if the installation should be allowed
#. based on whether the app being installed has content which doesn’t
#. comply with the user’s parental controls policy (the content is
#. ‘too extreme’).
#. - It is checked only if an app has too extreme content for the user
#. who is trying to install it (in which case, the app is ‘unsafe’).
#. - Typically, normal users will need admin permission to install apps
#. with extreme content; admins will be able to install it without
#. additional checks.
#. - In order to configure the policy so that admins can install safe and
#. unsafe software anywhere without authorisation, and non-admins can
#. install safe software in their user or system dirs without
#. authorisation, but need authorisation to install unsafe software
#. anywhere:
#. * Unconditionally return `yes` from `app-install`.
#. * Return `auth_admin` from `override-parental-controls` for users
#. not in `@privileged_group@`, and `yes` for users in it.
#. * Set the malcontent `is-{user,system}-installation-allowed`
#. properties of all non-admins’ parental controls policies to true.
#. - In order to configure the policy so that admins can install safe and
#. unsafe software anywhere without authorisation, and non-admins can
#. install safe software in their user dir without authorisation, but
#. need authorisation to install safe software in the system dir or to
#. install unsafe software anywhere:
#. * Unconditionally return `yes` from `app-install`.
#. * Return `auth_admin` from `override-parental-controls` for users
#. not in `@privileged_group@`, and `yes` for users in it.
#. * Set the malcontent `is-user-installation-allowed` property of all
#. non-admins’ parental controls policies to true.
#. * Set the malcontent `is-system-installation-allowed` property of
#. all non-admins’ parental controls policies to false.
#. - In order to configure the policy so that all users (including
#. admins) can install safe software anywhere without authorisation,
#. but need authorisation to install unsafe software anywhere (i.e.
#. applying parental controls to admins too):
#. * Unconditionally return `yes` from `app-install`.
#. * Unconditionally return `auth_admin` from `override-parental-controls`.
#. * Set the malcontent `is-user-installation-allowed` property of all
#. users’ parental controls policies to true.
#. * Set the malcontent `is-system-installation-allowed` property of
#. all users’ parental controls policies to true.
#: system-helper/org.freedesktop.Flatpak.policy.in:287
msgid "Override parental controls for installs"
msgstr ""

#: system-helper/org.freedesktop.Flatpak.policy.in:288
#, fuzzy
msgid ""
"Authentication is required to install software which is restricted by your "
"parental controls policy"
msgstr "Na inštaláciu softvéru sa vyžaduje overenie totožnosti"

#. SECURITY:
#. - This is like org.freedesktop.Flatpak.override-parental-controls, but
#. it’s queried for app updates, whereas the former is queried for app
#. installs.
#. - As with the above action, this one is only queried if
#. org.freedesktop.Flatpak.app-update has allowed the app update, and
#. only if the app being updated has too extreme content for the user
#. who is trying to update it.
#. - The default policy for this is to *allow* updates to ‘too extreme’
#. apps by default, on the basis that having an out-of-date (i.e.
#. insecure or unsupported) app is a worse outcome than automatically
#. installing an update which has radically different content from the
#. version of the app which the parent originally vetted and installed.
#: system-helper/org.freedesktop.Flatpak.policy.in:313
msgid "Override parental controls for updates"
msgstr ""

#: system-helper/org.freedesktop.Flatpak.policy.in:314
#, fuzzy
msgid ""
"Authentication is required to update software which is restricted by your "
"parental controls policy"
msgstr "Na inštaláciu softvéru sa vyžaduje overenie totožnosti"

#, fuzzy
#~ msgid "Installed:"
#~ msgstr "Nainštalovanie balíka"

#, fuzzy
#~ msgid "Download:"
#~ msgstr "Zobrazí referenciu"

#, fuzzy, c-format
#~ msgid "Unable to lookup key ID %s: %d"
#~ msgstr "Zlyhalo čítanie začlenenia %s: "

#, fuzzy, c-format
#~ msgid "Error signing commit: %d"
#~ msgstr "Inštalovanie: %s\n"

#, fuzzy, c-format
#~ msgid "Failed to uninstall %s for rebase to %s: "
#~ msgstr "Zlyhalo čítanie začlenenia %s: "

#, fuzzy, c-format
#~ msgid "Failed to uninstall %s for rebase to %s: %s\n"
#~ msgstr "Zlyhalo čítanie začlenenia %s: "

#, fuzzy, c-format
#~ msgid "Unable to open directory %s"
#~ msgstr "Zlyhalo otvorenie dočasného súboru flatpak-info"

#, fuzzy
#~ msgid "update"
#~ msgstr "Žiadne aktualizácie.\n"

#, fuzzy
#~ msgid "uninstall"
#~ msgstr "Odinštalovanie prostredia"

#, fuzzy
#~ msgid "runtime"
#~ msgstr "Prostredie. ktoré sa má použiť"

#, fuzzy
#~ msgid "[REF…] - Uninstall an application"
#~ msgstr "Inštalácia podpísanej aplikácie"

#, fuzzy, c-format
#~ msgid "Invalid deployed ref %s: "
#~ msgstr "Neplatný identifikátor pid %s"

#, fuzzy, c-format
#~ msgid "Failed to determine parts from ref: %s"
#~ msgstr "Zlyhalo otvorenie súboru temp"

#, fuzzy, c-format
#~ msgid "Invalid arch %s"
#~ msgstr "Neplatný identifikátor pid %s"

#, fuzzy, c-format
#~ msgid "Related ref '%s' is only partially installed"
#~ msgstr "Požadované rozšírenie %s je nainštalované iba čiastočne"

#, fuzzy, c-format
#~ msgid "Ref '%s' is only partially installed"
#~ msgstr "Požadované rozšírenie %s je nainštalované iba čiastočne"

#, fuzzy, c-format
#~ msgid "No such ref (%s, %s) in remote %s"
#~ msgstr "Nedá sa nájsť %s vo vzdialenom repozitári %s"

#, fuzzy, c-format
#~ msgid "No such ref (%s, %s) in remote %s or elsewhere"
#~ msgstr "Nedá sa nájsť %s vo vzdialenom repozitári %s"

#, fuzzy
#~ msgid "No summary found"
#~ msgstr "Nič nevyhovuje názvu %s"

#, fuzzy, c-format
#~ msgid "No repo metadata cached for remote '%s'"
#~ msgstr "Zlyhalo čítanie začlenenia %s: "

#, fuzzy, c-format
#~ msgid "Invalid group: %d"
#~ msgstr "Neplatný identifikátor pid %s"

#, fuzzy, c-format
#~ msgid "Warning: Can't find %s metadata for dependencies: %s"
#~ msgstr "Nepodarilo sa aktualizovať metaúdaje navyše pre %s"

#, fuzzy
#~ msgid "Default system installation"
#~ msgstr "Nepodarilo sa nájsť inštaláciu %s"

#, fuzzy
#~ msgid "%s branch already installed"
#~ msgstr "Aplikácia %s vetva %s je už nainštalovaná"

#~ msgid "%s branch %s not installed"
#~ msgstr "Aplikácia %s vetva %s nie je nainštalovaná"

#, fuzzy
#~ msgid "Print OSTree debug information during command processing"
#~ msgstr "Vypíše ladiace informácie počas spracovávania príkazu"

#~ msgid "Show help options"
#~ msgstr "Zobrazí voľby pomocníka"

#, fuzzy
#~ msgid "Architecture"
#~ msgstr "Architektúra , ktorá sa má použiť"

#, fuzzy
#~ msgid "Installing for user: %s from %s\n"
#~ msgstr "Inštalovanie: %s z %s\n"

#~ msgid "Installing: %s from %s\n"
#~ msgstr "Inštalovanie: %s z %s\n"

#, fuzzy
#~ msgid "Updating for user: %s from %s\n"
#~ msgstr "Aktualizovanie: %s z %s\n"

#~ msgid "Updating: %s from %s\n"
#~ msgstr "Aktualizovanie: %s z %s\n"

#, fuzzy
#~ msgid "Installing for user: %s from bundle %s\n"
#~ msgstr "Inštalovanie: %s z balíka %s\n"

#~ msgid "Installing: %s from bundle %s\n"
#~ msgstr "Inštalovanie: %s z balíka %s\n"

#, fuzzy
#~ msgid "Uninstalling for user: %s\n"
#~ msgstr "Inštalovanie: %s z %s\n"

#~ msgid "No updates.\n"
#~ msgstr "Žiadne aktualizácie.\n"

#~ msgid "Now at %s.\n"
#~ msgstr "Teraz na začlenení %s.\n"

#, fuzzy
#~ msgid "new file access"
#~ msgstr ""
#~ "\n"
#~ "Správa prístupu k súborom"

#, fuzzy
#~ msgid "file access"
#~ msgstr ""
#~ "\n"
#~ "Správa prístupu k súborom"

#, fuzzy
#~ msgid "Installing in %s:\n"
#~ msgstr "Inštalovanie: %s\n"

#, fuzzy
#~ msgid "Invalid .flatpakref"
#~ msgstr "Neplatný identifikátor pid %s"

#, fuzzy
#~ msgid "Authentication is required to install $(ref) from $(origin)"
#~ msgstr "Na inštaláciu softvéru sa vyžaduje overenie totožnosti"

#, fuzzy
#~ msgid "Authentication is required to update $(ref) from $(origin)"
#~ msgstr "Na aktualizáciu softvéru sa vyžaduje overenie totožnosti"

#, fuzzy
#~ msgid "Authentication is required to update the remote $(remote)"
#~ msgstr "Na aktualizáciu softvéru sa vyžaduje overenie totožnosti"

#, fuzzy
#~ msgid "Authentication is required to modify the remote $(remote)"
#~ msgstr "Na aktualizáciu softvéru sa vyžaduje overenie totožnosti"

#, fuzzy
#~ msgid "Authentication is required to configure the remote $(remote)"
#~ msgstr ""
#~ "Na konfiguráciu softvérových repozitárov sa vyžaduje overenie totožnosti"

#, fuzzy
#~ msgid "Runtime Branch"
#~ msgstr "Prostredie. ktoré sa má použiť"

#, fuzzy
#~ msgid "Runtime Commit"
#~ msgstr "Prostredie. ktoré sa má použiť"

#~ msgid "Unknown command '%s'"
#~ msgstr "Neznámy príkaz „%s“"

#, fuzzy
#~ msgid "Migrating %s to %s\n"
#~ msgstr "Aktualizovanie: %s z %s\n"

#, fuzzy
#~ msgid "Found in remote %s\n"
#~ msgstr "Nájdené v niekoľkých vzdialených repozitároch:\n"

#~ msgid "Found in several remotes:\n"
#~ msgstr "Nájdené v niekoľkých vzdialených repozitároch:\n"

#, fuzzy
#~ msgid "%s already installed, skipping\n"
#~ msgstr "Aplikácia %s vetva %s je už nainštalovaná"

#, fuzzy
#~ msgid "One or more operations failed"
#~ msgstr "Jedna alebo viacero aktualizácií zlyhali"

#, fuzzy
#~ msgid "No ref information available in repository"
#~ msgstr "Vypíše informácie o verzii a skončí"

#, fuzzy
#~ msgid "Remote default-branch not set"
#~ msgstr "Vypíše predvolenú architektúru a skončí"

#, fuzzy
#~ msgid "Post-Install %s"
#~ msgstr "Inštalovanie: %s\n"

#~ msgid "'%s' is not a valid runtime name: %s"
#~ msgstr "„%s“ nie je platným názvom prostredia: %s"

#, fuzzy
#~ msgid "'%s' is not a valid sdk name: %s"
#~ msgstr "„%s“ nie je platným názvom"

#, fuzzy
#~ msgid "OCI repo Filename or uri must be specified"
#~ msgstr "Musí byť určený NÁZOV vzdialeného repozitára"

===== ./po/meson.build =====
# Copyright 2022 Collabora Ltd.
# SPDX-License-Identifier: LGPL-2.1-or-later

i18n.gettext(
  'flatpak',
  preset: 'glib',
  args: [
    '--msgid-bugs-address=https://github.com/flatpak/flatpak/issues',
  ],
)

===== ./po/pt.po =====
# Portuguese translation for flatpak.
# Copyright (C) 2022 THE flatpak'S COPYRIGHT HOLDER
# This file is distributed under the same license as the flatpak package.
#
# Translators:
# Hugo Carvalho <hugokarvalho@hotmail.com>, 2022.
#
msgid ""
msgstr ""
"Project-Id-Version: flatpak main\n"
"Report-Msgid-Bugs-To: https://github.com/flatpak/flatpak/issues\n"
"POT-Creation-Date: 2026-05-27 16:39+0200\n"
"PO-Revision-Date: 2022-05-20 17:54+0100\n"
"Last-Translator: Hugo Carvalho <hugokarvalho@hotmail.com>\n"
"Language-Team: Portuguese\n"
"Language: pt\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Generator: Poedit 3.0.1\n"

#: app/flatpak-builtins-build-bundle.c:59
msgid "Export runtime instead of app"
msgstr "Exporta runtime em vez da aplicação"

#: app/flatpak-builtins-build-bundle.c:60
msgid "Arch to bundle for"
msgstr "Arquitetura para a qual será empacotada"

#: app/flatpak-builtins-build-bundle.c:60
#: app/flatpak-builtins-build-export.c:62 app/flatpak-builtins-build-init.c:53
#: app/flatpak-builtins-build-sign.c:42 app/flatpak-builtins-create-usb.c:46
#: app/flatpak-builtins-info.c:55 app/flatpak-builtins-install.c:67
#: app/flatpak-builtins-list.c:50 app/flatpak-builtins-make-current.c:38
#: app/flatpak-builtins-remote-info.c:54 app/flatpak-builtins-remote-ls.c:56
#: app/flatpak-builtins-run.c:158 app/flatpak-builtins-search.c:37
#: app/flatpak-builtins-uninstall.c:54 app/flatpak-builtins-update.c:56
msgid "ARCH"
msgstr "ARQUITETURA"

#: app/flatpak-builtins-build-bundle.c:61
#, fuzzy
msgid "URL for repo"
msgstr "Url para o repo"

#: app/flatpak-builtins-build-bundle.c:61
#: app/flatpak-builtins-build-bundle.c:62
#: app/flatpak-builtins-build-update-repo.c:68
#: app/flatpak-builtins-build-update-repo.c:72
#: app/flatpak-builtins-build-update-repo.c:73
#: app/flatpak-builtins-history.c:69 app/flatpak-builtins-remote-add.c:80
#: app/flatpak-builtins-remote-add.c:81 app/flatpak-builtins-remote-add.c:85
#: app/flatpak-builtins-remote-list.c:53
#: app/flatpak-builtins-remote-modify.c:70
#: app/flatpak-builtins-remote-modify.c:85
#: app/flatpak-builtins-remote-modify.c:86
#: app/flatpak-builtins-remote-modify.c:90
msgid "URL"
msgstr "URL"

#: app/flatpak-builtins-build-bundle.c:62
#, fuzzy
msgid "URL for runtime flatpakrepo file"
msgstr "Url para o ficheiro de flatpakrepo de runtime"

#: app/flatpak-builtins-build-bundle.c:63
msgid "Add GPG key from FILE (- for stdin)"
msgstr "Adiciona uma chave GPG do FICHEIRO (- para stdin)"

#: app/flatpak-builtins-build-bundle.c:63 app/flatpak-builtins-build.c:54
#: app/flatpak-builtins-build-export.c:67
#: app/flatpak-builtins-build-update-repo.c:83
#: app/flatpak-builtins-install.c:81 app/flatpak-builtins-remote-add.c:84
#: app/flatpak-builtins-remote-add.c:86 app/flatpak-builtins-remote-modify.c:89
#: app/flatpak-builtins-remote-modify.c:92
msgid "FILE"
msgstr "FICHEIRO"

#: app/flatpak-builtins-build-bundle.c:64
msgid "GPG Key ID to sign the OCI image with"
msgstr "ID da chave GPG para assinar a imagem OCI"

#: app/flatpak-builtins-build-bundle.c:64
#: app/flatpak-builtins-build-commit-from.c:68
#: app/flatpak-builtins-build-export.c:68
#: app/flatpak-builtins-build-import-bundle.c:49
#: app/flatpak-builtins-build-sign.c:44
#: app/flatpak-builtins-build-update-repo.c:84
msgid "KEY-ID"
msgstr "ID-CHAVE"

#: app/flatpak-builtins-build-bundle.c:65
#: app/flatpak-builtins-build-commit-from.c:69
#: app/flatpak-builtins-build-export.c:71
#: app/flatpak-builtins-build-import-bundle.c:50
#: app/flatpak-builtins-build-sign.c:45
#: app/flatpak-builtins-build-update-repo.c:85
msgid "GPG Homedir to use when looking for keyrings"
msgstr "Diretório do GPG para usar quando estiver à procura por chaveiros"

#: app/flatpak-builtins-build-bundle.c:65
#: app/flatpak-builtins-build-commit-from.c:69
#: app/flatpak-builtins-build-export.c:71
#: app/flatpak-builtins-build-import-bundle.c:50
#: app/flatpak-builtins-build-sign.c:45
#: app/flatpak-builtins-build-update-repo.c:85
msgid "HOMEDIR"
msgstr "HOMEDIR"

#: app/flatpak-builtins-build-bundle.c:66
msgid "OSTree commit to create a delta bundle from"
msgstr "Commit OSTree para criar um pacote delta de"

#: app/flatpak-builtins-build-bundle.c:66 app/flatpak-builtins-remote-info.c:55
#: app/flatpak-builtins-update.c:57
msgid "COMMIT"
msgstr "COMMIT"

#: app/flatpak-builtins-build-bundle.c:67
msgid "Export oci image instead of flatpak bundle"
msgstr "Exporta a imagem oci em vez do pacote flatpak"

#: app/flatpak-builtins-build-bundle.c:70
msgid "How to compress OCI image layers (default: gzip)"
msgstr ""

#: app/flatpak-builtins-build-bundle.c:634
msgid ""
"LOCATION FILENAME NAME [BRANCH] - Create a single file bundle from a local "
"repository"
msgstr ""
"LOCALIZAÇÃO ARQUIVO NOME [RAMO] – Cria um único ficheiro de pacote de um "
"repositório local"

#: app/flatpak-builtins-build-bundle.c:641
msgid "LOCATION, FILENAME and NAME must be specified"
msgstr "LOCALIZAÇÃO, ARQUIVO e NOME devem ser especificados"

#: app/flatpak-builtins-build-bundle.c:644
#: app/flatpak-builtins-build-export.c:844
#: app/flatpak-builtins-build-import-bundle.c:136
#: app/flatpak-builtins-build-init.c:217 app/flatpak-builtins-build-sign.c:76
#: app/flatpak-builtins-document-export.c:112
#: app/flatpak-builtins-document-info.c:75
#: app/flatpak-builtins-document-list.c:191
#: app/flatpak-builtins-document-unexport.c:70
#: app/flatpak-builtins-history.c:482 app/flatpak-builtins-info.c:130
#: app/flatpak-builtins-install.c:181 app/flatpak-builtins-install.c:234
#: app/flatpak-builtins-install.c:298 app/flatpak-builtins-list.c:419
#: app/flatpak-builtins-make-current.c:72 app/flatpak-builtins-override.c:73
#: app/flatpak-builtins-permission-list.c:162
#: app/flatpak-builtins-permission-remove.c:132
#: app/flatpak-builtins-remote-add.c:323
#: app/flatpak-builtins-remote-delete.c:68
#: app/flatpak-builtins-remote-list.c:241 app/flatpak-builtins-remote-ls.c:407
msgid "Too many arguments"
msgstr "Número excessivo de argumentos"

#: app/flatpak-builtins-build-bundle.c:659
#: app/flatpak-builtins-build-commit-from.c:338
#: app/flatpak-builtins-build-commit-from.c:351
#: app/flatpak-builtins-build-import-bundle.c:145
#, c-format
msgid "'%s' is not a valid repository"
msgstr "“%s” não é um repositório válido"

#: app/flatpak-builtins-build-bundle.c:663
#, c-format
msgid "'%s' is not a valid repository: "
msgstr "“%s” não é um repositório válido: "

#: app/flatpak-builtins-build-bundle.c:674 app/flatpak-builtins-build-sign.c:88
#: common/flatpak-dir.c:14293
#, c-format
msgid "'%s' is not a valid name: %s"
msgstr "“%s” não é um nome válido: %s"

#: app/flatpak-builtins-build-bundle.c:677
#: app/flatpak-builtins-build-export.c:865 app/flatpak-builtins-build-sign.c:91
#: common/flatpak-dir.c:14299
#, c-format
msgid "'%s' is not a valid branch name: %s"
msgstr "“%s” não é um nome de ramo válido: %s"

#: app/flatpak-builtins-build-bundle.c:691
#: app/flatpak-builtins-build-import-bundle.c:149
#: app/flatpak-builtins-build-init.c:281
#, c-format
msgid "'%s' is not a valid filename"
msgstr "“%s” não é um nome de ficheiro válido"

#: app/flatpak-builtins-build-bundle.c:706
msgid "--oci-layer-compress value must be gzip or zstd"
msgstr ""

#: app/flatpak-builtins-build.c:49
msgid "Use Platform runtime rather than Sdk"
msgstr "Usa runtime Platform em vez de Sdk"

#: app/flatpak-builtins-build.c:50
msgid "Make destination readonly"
msgstr "Torna o destino somente leitura"

#: app/flatpak-builtins-build.c:51
msgid "Add bind mount"
msgstr "Adiciona montagem associativa (bind)"

#: app/flatpak-builtins-build.c:51
msgid "DEST=SRC"
msgstr "DEST=ORIG"

#: app/flatpak-builtins-build.c:52
msgid "Start build in this directory"
msgstr "Começa compilação neste diretório"

#: app/flatpak-builtins-build.c:52 app/flatpak-builtins-build.c:53
#: app/flatpak-builtins-build-init.c:64 app/flatpak-builtins-run.c:160
msgid "DIR"
msgstr "DIR"

#: app/flatpak-builtins-build.c:53
msgid "Where to look for custom sdk dir (defaults to 'usr')"
msgstr "Onde procurar por diretório de sdk personalizado (padrão é “usr”)"

#: app/flatpak-builtins-build.c:54 app/flatpak-builtins-build-export.c:67
msgid "Use alternative file for the metadata"
msgstr "Usa um ficheiro alternativo para os metadados"

#: app/flatpak-builtins-build.c:55 app/flatpak-builtins-run.c:177
msgid "Kill processes when the parent process dies"
msgstr "Mata processos quando o processo pai morre"

#: app/flatpak-builtins-build.c:56
msgid "Export application homedir directory to build"
msgstr "Exporta o diretório homedir da aplicação a compilar"

#: app/flatpak-builtins-build.c:57 app/flatpak-builtins-run.c:165
msgid "Log session bus calls"
msgstr "Registra o log das chamadas de barramento de sessão"

#: app/flatpak-builtins-build.c:58 app/flatpak-builtins-run.c:166
msgid "Log system bus calls"
msgstr "Registra o log das chamadas de barramento de sistema"

#: app/flatpak-builtins-build.c:262
msgid "DIRECTORY [COMMAND [ARGUMENT…]] - Build in directory"
msgstr "DIRETÓRIO [COMANDO [ARGUMENTO…]] – Compila no diretório"

#: app/flatpak-builtins-build.c:285 app/flatpak-builtins-build-finish.c:656
msgid "DIRECTORY must be specified"
msgstr "DIRETÓRIO deve ser especificado"

#: app/flatpak-builtins-build.c:296 app/flatpak-builtins-build-export.c:887
#, c-format
msgid "Build directory %s not initialized, use flatpak build-init"
msgstr "Diretório de compilação %s não inicializado, use flatpak build-init"

#: app/flatpak-builtins-build.c:315
msgid "metadata invalid, not application or runtime"
msgstr "metadados inválido, não é aplicação ou runtime"

#: app/flatpak-builtins-build.c:446
#, c-format
msgid "No extension point matching %s in %s"
msgstr "Nenhum ponto de extensão correspondendo %s em %s"

#: app/flatpak-builtins-build.c:635
#, c-format
msgid "Missing '=' in bind mount option '%s'"
msgstr "Em falta “=” na opção de montagem associativa “%s”"

#: app/flatpak-builtins-build.c:679 common/flatpak-run.c:3961
#, c-format
msgid "Unable to start app"
msgstr "Não foi possível iniciar a aplicação"

#: app/flatpak-builtins-build-commit-from.c:58
msgid "Source repo dir"
msgstr "Diretório de repositório fonte"

#: app/flatpak-builtins-build-commit-from.c:58
msgid "SRC-REPO"
msgstr "SRC-REPO"

#: app/flatpak-builtins-build-commit-from.c:59
msgid "Source repo ref"
msgstr "Ref de repositório fonte"

#: app/flatpak-builtins-build-commit-from.c:59
msgid "SRC-REF"
msgstr "SRC-REF"

#: app/flatpak-builtins-build-commit-from.c:64
#: app/flatpak-builtins-build-export.c:60
msgid "One line subject"
msgstr "Assunto em uma linha"

#: app/flatpak-builtins-build-commit-from.c:64
#: app/flatpak-builtins-build-export.c:60
msgid "SUBJECT"
msgstr "ASSUNTO"

#: app/flatpak-builtins-build-commit-from.c:65
#: app/flatpak-builtins-build-export.c:61
msgid "Full description"
msgstr "Descrição completa"

#: app/flatpak-builtins-build-commit-from.c:65
#: app/flatpak-builtins-build-export.c:61
msgid "BODY"
msgstr "CORPO"

#: app/flatpak-builtins-build-commit-from.c:66
#: app/flatpak-builtins-build-export.c:64
#: app/flatpak-builtins-build-import-bundle.c:51
msgid "Update the appstream branch"
msgstr "Atualiza o ramo de appstream"

#: app/flatpak-builtins-build-commit-from.c:67
#: app/flatpak-builtins-build-export.c:65
#: app/flatpak-builtins-build-import-bundle.c:52
#: app/flatpak-builtins-build-update-repo.c:87
msgid "Don't update the summary"
msgstr "Não atualiza o sumário"

#: app/flatpak-builtins-build-commit-from.c:68
#: app/flatpak-builtins-build-export.c:68
#: app/flatpak-builtins-build-import-bundle.c:49
#: app/flatpak-builtins-build-sign.c:44
msgid "GPG Key ID to sign the commit with"
msgstr "ID da chave GPG para assinar o commit"

#: app/flatpak-builtins-build-commit-from.c:70
#: app/flatpak-builtins-build-export.c:73
msgid "Mark build as end-of-life"
msgstr "Marca a compilação como fim de vida"

#: app/flatpak-builtins-build-commit-from.c:70
#: app/flatpak-builtins-build-export.c:73
msgid "REASON"
msgstr "MOTIVO"

#: app/flatpak-builtins-build-commit-from.c:71
msgid ""
"Mark refs matching the OLDID prefix as end-of-life, to be replaced with the "
"given NEWID"
msgstr ""
"Marca refs correspondentes ao prefixo de IDANTIGO como fim de vida, para "
"serem substituídos com o IDNOVO dado"

#: app/flatpak-builtins-build-commit-from.c:71
msgid "OLDID=NEWID"
msgstr "IDANTIGO=IDNOVO"

#: app/flatpak-builtins-build-commit-from.c:72
#: app/flatpak-builtins-build-export.c:75
msgid "Set type of token needed to install this commit"
msgstr "Define o tipo de token necessário para instalar este commit"

#: app/flatpak-builtins-build-commit-from.c:72
#: app/flatpak-builtins-build-export.c:75
msgid "VAL"
msgstr "VALOR"

#: app/flatpak-builtins-build-commit-from.c:73
msgid "Override the timestamp of the commit (NOW for current time)"
msgstr "Sobrepõe o carimbo de tempo do commit (NOW para o tempo atual)"

#: app/flatpak-builtins-build-commit-from.c:73
#: app/flatpak-builtins-build-export.c:76
msgid "TIMESTAMP"
msgstr "CARIMBO-DE-TEMPO"

#: app/flatpak-builtins-build-commit-from.c:75
#: app/flatpak-builtins-build-export.c:80
#: app/flatpak-builtins-build-import-bundle.c:53
#: app/flatpak-builtins-build-update-repo.c:97
msgid "Don't generate a summary index"
msgstr "Não gera um índice de resumo"

#: app/flatpak-builtins-build-commit-from.c:278
msgid "DST-REPO [DST-REF…] - Make a new commit from existing commits"
msgstr "DST-REPO [DST-REF…] – Faz um novo commit de commits existentes"

#: app/flatpak-builtins-build-commit-from.c:285
msgid "DST-REPO must be specified"
msgstr "DST-REPO deve ser especificado"

#: app/flatpak-builtins-build-commit-from.c:293
msgid ""
"If --src-repo is not specified, exactly one destination ref must be specified"
msgstr ""
"Se --src-repo não for especificado, exatamente uma ref destino deve ser "
"especificado"

#: app/flatpak-builtins-build-commit-from.c:296
msgid ""
"If --src-ref is specified, exactly one destination ref must be specified"
msgstr ""
"Se --src-ref for especificado, exatamente uma ref destino deve ser "
"especificado"

#: app/flatpak-builtins-build-commit-from.c:299
msgid "Either --src-repo or --src-ref must be specified"
msgstr "--src-repo ou --src-ref devem ser especificados"

#: app/flatpak-builtins-build-commit-from.c:315
msgid "Invalid argument format of use  --end-of-life-rebase=OLDID=NEWID"
msgstr ""
"Formato de argumento inválido para o uso de --end-of-life-"
"rebase=IDANTIGO=IDNOVO"

#: app/flatpak-builtins-build-commit-from.c:321
#: app/flatpak-builtins-build-commit-from.c:324
#, c-format
msgid "Invalid name %s in --end-of-life-rebase"
msgstr "Nome inválido %s em --end-of-life-rebase"

#: app/flatpak-builtins-build-commit-from.c:333
#: app/flatpak-builtins-build-export.c:1092
#, c-format
msgid "Could not parse '%s'"
msgstr "Não foi possível analisar “%s”"

#: app/flatpak-builtins-build-commit-from.c:498
msgid "Can't commit from partial source commit"
msgstr "Não foi possível fazer commit de commit fonte parcial"

#: app/flatpak-builtins-build-commit-from.c:503
#, c-format
msgid "%s: no change\n"
msgstr "%s: nenhuma alteração\n"

#: app/flatpak-builtins-build-export.c:62
msgid "Architecture to export for (must be host compatible)"
msgstr "Arquitetura alvo da exportação (deve ser compatível com o hospedeiro)"

#: app/flatpak-builtins-build-export.c:63
msgid "Commit runtime (/usr), not /app"
msgstr "Faz commit de runtime (/usr), não /app"

#: app/flatpak-builtins-build-export.c:66
msgid "Use alternative directory for the files"
msgstr "Usa o dicionário alternativo para os ficheiros"

#: app/flatpak-builtins-build-export.c:66
msgid "SUBDIR"
msgstr "SUBDIR"

#: app/flatpak-builtins-build-export.c:69
msgid "Files to exclude"
msgstr "Ficheiros a excluir"

#: app/flatpak-builtins-build-export.c:69
#: app/flatpak-builtins-build-export.c:70
#: app/flatpak-builtins-build-update-repo.c:90
msgid "PATTERN"
msgstr "PADRÃO"

#: app/flatpak-builtins-build-export.c:70
msgid "Excluded files to include"
msgstr "Ficheiros excluídos a incluir"

#: app/flatpak-builtins-build-export.c:74
msgid "Mark build as end-of-life, to be replaced with the given ID"
msgstr "Marca a compilação como fim de vida, a ser substituída com o ID dado"

#: app/flatpak-builtins-build-export.c:74
#: app/flatpak-builtins-document-list.c:49 app/flatpak-cli-transaction.c:1427
msgid "ID"
msgstr "ID"

#: app/flatpak-builtins-build-export.c:76
msgid "Override the timestamp of the commit"
msgstr "Sobrepõe o carimbo de tempo do commit"

#: app/flatpak-builtins-build-export.c:77
#: app/flatpak-builtins-build-update-repo.c:75
#: app/flatpak-builtins-remote-add.c:83 app/flatpak-builtins-remote-list.c:54
#: app/flatpak-builtins-remote-modify.c:88
msgid "Collection ID"
msgstr "ID de coleção"

#: app/flatpak-builtins-build-export.c:472
#, c-format
msgid "WARNING: Error running desktop-file-validate: %s\n"
msgstr "AVISO: Erro ao executar desktop-file-validate: %s\n"

#: app/flatpak-builtins-build-export.c:480
#, c-format
msgid "WARNING: Error reading from desktop-file-validate: %s\n"
msgstr "AVISO: Erro ao ler de desktop-file-validate: %s\n"

#: app/flatpak-builtins-build-export.c:486
#, c-format
msgid "WARNING: Failed to validate desktop file %s: %s\n"
msgstr "AVISO: Falha ao validar o ficheiro desktop %s: %s\n"

#: app/flatpak-builtins-build-export.c:513
#, c-format
msgid "WARNING: Can't find Exec key in %s: %s\n"
msgstr "AVISO: Não foi possível localizar a chave Exec em %s: %s\n"

#: app/flatpak-builtins-build-export.c:521
#: app/flatpak-builtins-build-export.c:614
#, c-format
msgid "WARNING: Binary not found for Exec line in %s: %s\n"
msgstr "AVISO: Binário não localizado para a linha Exec em %s: %s\n"

#: app/flatpak-builtins-build-export.c:529
#, c-format
msgid "WARNING: Icon not matching app id in %s: %s\n"
msgstr "AVISO: Ícone não correspondendo a id da aplicação no %s: %s\n"

#: app/flatpak-builtins-build-export.c:552
#, c-format
msgid "WARNING: Icon referenced in desktop file but not exported: %s\n"
msgstr "AVISO: Ícone referenciado no ficheiro desktop, mas não exportado: %s\n"

#: app/flatpak-builtins-build-export.c:719
#, c-format
msgid "Invalid uri type %s, only http/https supported"
msgstr "Tipo de uri inválida %s, há suporte apenas a http/https"

#: app/flatpak-builtins-build-export.c:737
#, c-format
msgid "Unable to find basename in %s, specify a name explicitly"
msgstr ""
"Não foi possível localizar o nome base em %s, especifique explicitamente um "
"nome base"

#: app/flatpak-builtins-build-export.c:746
#, c-format
msgid "No slashes allowed in extra data name"
msgstr "Nenhuma barra permitida no nome de dados extras"

#: app/flatpak-builtins-build-export.c:758
#, c-format
msgid "Invalid format for sha256 checksum: '%s'"
msgstr "Formato inválido para a soma de verificação sha256: “%s”"

#: app/flatpak-builtins-build-export.c:768
#, c-format
msgid "Extra data sizes of zero not supported"
msgstr "Tamanhos zerado de dados extras sem suporte"

#: app/flatpak-builtins-build-export.c:830
msgid ""
"LOCATION DIRECTORY [BRANCH] - Create a repository from a build directory"
msgstr ""
"LOCALIZAÇÃO DIRETÓRIO [RAMO] – Cria um repositório de um diretório de "
"compilação"

#: app/flatpak-builtins-build-export.c:838
msgid "LOCATION and DIRECTORY must be specified"
msgstr "LOCALIZAÇÃO e DIRETÓRIO devem ser especificados"

#: app/flatpak-builtins-build-export.c:859
#: app/flatpak-builtins-remote-add.c:327
#, c-format
msgid "‘%s’ is not a valid collection ID: %s"
msgstr "“%s” não é um ID de coleção válido: %s"

#: app/flatpak-builtins-build-export.c:904
#: app/flatpak-builtins-build-finish.c:684
msgid "No name specified in the metadata"
msgstr "Nenhum nome especificado nos metadados"

#: app/flatpak-builtins-build-export.c:1166
#, c-format
msgid "Commit: %s\n"
msgstr "Commit: %s\n"

#: app/flatpak-builtins-build-export.c:1167
#, c-format
msgid "Metadata Total: %u\n"
msgstr "Metadados totais: %u\n"

#: app/flatpak-builtins-build-export.c:1168
#, c-format
msgid "Metadata Written: %u\n"
msgstr "Metadados escritos: %u\n"

#: app/flatpak-builtins-build-export.c:1169
#, c-format
msgid "Content Total: %u\n"
msgstr "Conteúdo total: %u\n"

#: app/flatpak-builtins-build-export.c:1170
#, c-format
msgid "Content Written: %u\n"
msgstr "Conteúdo escrito: %u\n"

#: app/flatpak-builtins-build-export.c:1171
#, c-format
msgid "Content Bytes Written:"
msgstr "Conteúdo de bytes escritos:"

#: app/flatpak-builtins-build-finish.c:52
msgid "Command to set"
msgstr "Comando para definir"

#: app/flatpak-builtins-build-finish.c:52 app/flatpak-builtins-run.c:159
#: app/flatpak-main.c:209
msgid "COMMAND"
msgstr "COMANDO"

#: app/flatpak-builtins-build-finish.c:53
msgid "Flatpak version to require"
msgstr "Versão do Flatpak para exigir"

#: app/flatpak-builtins-build-finish.c:53
msgid "MAJOR.MINOR.MICRO"
msgstr "MAIOR.MENOR.MICRO"

#: app/flatpak-builtins-build-finish.c:54
msgid "Don't process exports"
msgstr "Não processa exportações"

#: app/flatpak-builtins-build-finish.c:55
msgid "Extra data info"
msgstr "Info de dados extras"

#: app/flatpak-builtins-build-finish.c:56 app/flatpak-builtins-build-init.c:63
msgid "Add extension point info"
msgstr "Adiciona info do ponto de extensão"

#: app/flatpak-builtins-build-finish.c:56 app/flatpak-builtins-build-init.c:63
msgid "NAME=VARIABLE[=VALUE]"
msgstr "NOME=VARIÁVEL[=VALOR]"

#: app/flatpak-builtins-build-finish.c:57
msgid "Remove extension point info"
msgstr "Remove info do ponto de extensão"

#: app/flatpak-builtins-build-finish.c:57
#: app/flatpak-builtins-build-update-repo.c:79 app/flatpak-builtins-info.c:58
#: app/flatpak-builtins-remote-add.c:88 app/flatpak-builtins-remote-modify.c:94
#: app/flatpak-main.c:182
msgid "NAME"
msgstr "NOME"

#: app/flatpak-builtins-build-finish.c:58
msgid "Set extension priority (only for extensions)"
msgstr "Define a prioridade da extensão (apenas para extensões)"

#: app/flatpak-builtins-build-finish.c:58
msgid "VALUE"
msgstr "VALOR"

#: app/flatpak-builtins-build-finish.c:59
msgid "Change the sdk used for the app"
msgstr "Altera o sdk usado para a aplicação"

#: app/flatpak-builtins-build-finish.c:59
msgid "SDK"
msgstr "SDK"

#: app/flatpak-builtins-build-finish.c:60
msgid "Change the runtime used for the app"
msgstr "Altera o runtime usado para a aplicação"

#: app/flatpak-builtins-build-finish.c:60 app/flatpak-builtins-build-init.c:54
#: app/flatpak-builtins-list.c:53 app/flatpak-builtins-remote-ls.c:58
#: app/flatpak-builtins-run.c:163
msgid "RUNTIME"
msgstr "RUNTIME"

#: app/flatpak-builtins-build-finish.c:61
msgid "Set generic metadata option"
msgstr "Define a opção de metadados genérica"

#: app/flatpak-builtins-build-finish.c:61
msgid "GROUP=KEY[=VALUE]"
msgstr "GRUPO=CHAVE[=VALOR]"

#: app/flatpak-builtins-build-finish.c:62
msgid "Don't inherit permissions from runtime"
msgstr "Não herda permissões do runtime"

#: app/flatpak-builtins-build-finish.c:155
#, c-format
msgid "Not exporting %s, wrong extension\n"
msgstr "Não exportando %s, extensão errada\n"

#: app/flatpak-builtins-build-finish.c:163
#, c-format
msgid "Not exporting %s, non-allowed export filename\n"
msgstr "Não exportando %s, nome de ficheiro de exportação não permitido\n"

#: app/flatpak-builtins-build-finish.c:167
#, c-format
msgid "Exporting %s\n"
msgstr "Exportando %s\n"

#: app/flatpak-builtins-build-finish.c:440
#, c-format
msgid "More than one executable found\n"
msgstr "Mais de um executável localizado\n"

#: app/flatpak-builtins-build-finish.c:451
#, c-format
msgid "Using %s as command\n"
msgstr "Usando %s como comando\n"

#: app/flatpak-builtins-build-finish.c:456
#, c-format
msgid "No executable found\n"
msgstr "Nenhum executável localizado\n"

#: app/flatpak-builtins-build-finish.c:511
#, c-format
msgid "Invalid --require-version argument: %s"
msgstr "Argumento --require-version inválido: %s"

#: app/flatpak-builtins-build-finish.c:543
#, c-format
msgid "Too few elements in --extra-data argument %s"
msgstr "Elementos insuficientes no argumento de --extra-data %s"

#: app/flatpak-builtins-build-finish.c:575
#, c-format
msgid ""
"Too few elements in --metadata argument %s, format should be "
"GROUP=KEY[=VALUE]]"
msgstr ""
"Elementos insuficientes no argumento de --metadata %s, formato deve ser "
"GRUPO=CHAVE[=VALOR]"

#: app/flatpak-builtins-build-finish.c:597
#: app/flatpak-builtins-build-init.c:458
#, c-format
msgid ""
"Too few elements in --extension argument %s, format should be "
"NAME=VAR[=VALUE]"
msgstr ""
"Elementos insuficientes no argumento de --extension %s, formato deve ser "
"NOME=VAR[=VALOR]"

#: app/flatpak-builtins-build-finish.c:603
#: app/flatpak-builtins-build-init.c:461
#, c-format
msgid "Invalid extension name %s"
msgstr "Nome de extensão inválido %s"

#: app/flatpak-builtins-build-finish.c:646
msgid "DIRECTORY - Finalize a build directory"
msgstr "DIRETÓRIO – Finaliza um diretório de compilação"

#: app/flatpak-builtins-build-finish.c:668
#, c-format
msgid "Build directory %s not initialized"
msgstr "Diretório de compilação %s não inicializado"

#: app/flatpak-builtins-build-finish.c:689
#, c-format
msgid "Build directory %s already finalized"
msgstr "Diretório de compilação %s já finalizado"

#: app/flatpak-builtins-build-finish.c:702
#, c-format
msgid "Please review the exported files and the metadata\n"
msgstr "Por favor, reveja os ficheiros exportados e os metadados\n"

#: app/flatpak-builtins-build-import-bundle.c:47
msgid "Override the ref used for the imported bundle"
msgstr "Sobrepõe a ref usada para o pacote importado"

#: app/flatpak-builtins-build-import-bundle.c:47
msgid "REF"
msgstr "REF"

#: app/flatpak-builtins-build-import-bundle.c:48
msgid "Import oci image instead of flatpak bundle"
msgstr "Importa a imagem oci em vez do pacote flatpak"

#: app/flatpak-builtins-build-import-bundle.c:77
#: app/flatpak-builtins-build-import-bundle.c:105
#, c-format
msgid "Importing %s (%s)\n"
msgstr "Importando %s (%s)\n"

#: app/flatpak-builtins-build-import-bundle.c:126
msgid "LOCATION FILENAME - Import a file bundle into a local repository"
msgstr ""
"LOCALIZAÇÃO FICHEIRO – Importa um ficheiro de pacote para um repositório "
"local"

#: app/flatpak-builtins-build-import-bundle.c:133
msgid "LOCATION and FILENAME must be specified"
msgstr "LOCALIZAÇÃO e ARQUIVO devem ser especificados"

#: app/flatpak-builtins-build-init.c:53 app/flatpak-builtins-info.c:55
#: app/flatpak-builtins-run.c:158
msgid "Arch to use"
msgstr "Arquitetura para usar"

#: app/flatpak-builtins-build-init.c:54
msgid "Initialize var from named runtime"
msgstr "Inicializa variável a partir do runtime nomeado"

#: app/flatpak-builtins-build-init.c:55
msgid "Initialize apps from named app"
msgstr "Inicializa aplicações a partir da aplicação nomeado"

#: app/flatpak-builtins-build-init.c:55
msgid "APP"
msgstr "APLICATIVO"

#: app/flatpak-builtins-build-init.c:56
msgid "Specify version for --base"
msgstr "Especifica a versão para --base"

#: app/flatpak-builtins-build-init.c:56 app/flatpak-builtins-run.c:164
msgid "VERSION"
msgstr "VERSÃO"

#: app/flatpak-builtins-build-init.c:57
msgid "Include this base extension"
msgstr "Inclui essa extensão base"

#: app/flatpak-builtins-build-init.c:57 app/flatpak-builtins-build-init.c:62
msgid "EXTENSION"
msgstr "EXTENSÃO"

#: app/flatpak-builtins-build-init.c:58
msgid "Extension tag to use if building extension"
msgstr "Etiqueta de extensão para usar se compilação extensão"

#: app/flatpak-builtins-build-init.c:58
msgid "EXTENSION_TAG"
msgstr "ETIQUETA_EXTENSÃO"

#: app/flatpak-builtins-build-init.c:59
msgid "Initialize /usr with a writable copy of the sdk"
msgstr "Inicializa /usr com uma cópia do sdk com permissão de escrita"

#: app/flatpak-builtins-build-init.c:60
msgid "Specify the build type (app, runtime, extension)"
msgstr "Especifica o tipo de compilação (app, runtime, extension)"

#: app/flatpak-builtins-build-init.c:60
msgid "TYPE"
msgstr "TIPO"

#: app/flatpak-builtins-build-init.c:61
msgid "Add a tag"
msgstr "Adiciona uma etiqueta"

#: app/flatpak-builtins-build-init.c:61
msgid "TAG"
msgstr "ETIQUETA"

#: app/flatpak-builtins-build-init.c:62
msgid "Include this sdk extension in /usr"
msgstr "Inclui essa extensão de sdk em /usr"

#: app/flatpak-builtins-build-init.c:64
msgid "Where to store sdk (defaults to 'usr')"
msgstr "Onde armazenar sdk (padrão é “usr”)"

#: app/flatpak-builtins-build-init.c:65
msgid "Re-initialize the sdk/var"
msgstr "Reinicializa o/a sdk/var"

#: app/flatpak-builtins-build-init.c:118
#, fuzzy, c-format
msgid "Requested extension %s/%s/%s is only partially installed"
msgstr "Extensão %s exigida está apenas parcialmente instalada"

#: app/flatpak-builtins-build-init.c:147
#, fuzzy, c-format
msgid "Requested extension %s/%s/%s not installed"
msgstr "Extensão %s exigida não está instalada"

#: app/flatpak-builtins-build-init.c:207
msgid ""
"DIRECTORY APPNAME SDK RUNTIME [BRANCH] - Initialize a directory for building"
msgstr ""
"DIRETÓRIO NOMEAPLICATIVO SDK RUNTIME [RAMO] – Inicializa um diretório para "
"compilação"

#: app/flatpak-builtins-build-init.c:214
msgid "RUNTIME must be specified"
msgstr "RUNTIME deve ser especificado"

#: app/flatpak-builtins-build-init.c:235
#, c-format
msgid "'%s' is not a valid build type name, use app, runtime or extension"
msgstr ""
"“%s” não é um nome de tipo de compilação válido, use app, runtime ou "
"extension"

#: app/flatpak-builtins-build-init.c:241 app/flatpak-builtins-override.c:79
#, c-format
msgid "'%s' is not a valid application name: %s"
msgstr "“%s” não é um nome de aplicação válido: %s"

#: app/flatpak-builtins-build-init.c:295
#, c-format
msgid "Build directory %s already initialized"
msgstr "Diretório de compilação %s já inicializado"

#: app/flatpak-builtins-build-sign.c:42 app/flatpak-builtins-install.c:67
#: app/flatpak-builtins-remote-info.c:54
msgid "Arch to install for"
msgstr "Arquitetura para a qual será instalada"

#: app/flatpak-builtins-build-sign.c:43 app/flatpak-builtins-create-usb.c:48
#: app/flatpak-builtins-install.c:74 app/flatpak-builtins-remote-info.c:56
#: app/flatpak-builtins-uninstall.c:58 app/flatpak-builtins-update.c:64
msgid "Look for runtime with the specified name"
msgstr "Procura pelo runtime com o nome especificado"

#: app/flatpak-builtins-build-sign.c:66
msgid "LOCATION [ID [BRANCH]] - Sign an application or runtime"
msgstr "LOCALIZAÇÃO [ID [RAMO]] – Assina uma aplicação ou runtime"

#: app/flatpak-builtins-build-sign.c:73
#: app/flatpak-builtins-build-update-repo.c:499
#: app/flatpak-builtins-remote-add.c:320 app/flatpak-builtins-repo.c:739
msgid "LOCATION must be specified"
msgstr "LOCALIZAÇÃO deve ser especificada"

#: app/flatpak-builtins-build-sign.c:94
msgid "No gpg key ids specified"
msgstr "Nenhum id de chave gpg especificado"

#: app/flatpak-builtins-build-update-repo.c:68
msgid "Redirect this repo to a new URL"
msgstr "Redireciona este repositório a um novo URL"

#: app/flatpak-builtins-build-update-repo.c:69
msgid "A nice name to use for this repository"
msgstr "Um nome legal para usar para este repositório"

#: app/flatpak-builtins-build-update-repo.c:69
#: app/flatpak-builtins-remote-add.c:77 app/flatpak-builtins-remote-modify.c:82
msgid "TITLE"
msgstr "TÍTULO"

#: app/flatpak-builtins-build-update-repo.c:70
msgid "A one-line comment for this repository"
msgstr "Um comentário de uma linha para este repositório"

#: app/flatpak-builtins-build-update-repo.c:70
#: app/flatpak-builtins-remote-add.c:78 app/flatpak-builtins-remote-modify.c:83
msgid "COMMENT"
msgstr "COMENTÁRIO"

#: app/flatpak-builtins-build-update-repo.c:71
msgid "A full-paragraph description for this repository"
msgstr "Uma descrição de parágrafo completo para este repositório"

#: app/flatpak-builtins-build-update-repo.c:71
#: app/flatpak-builtins-remote-add.c:79 app/flatpak-builtins-remote-modify.c:84
msgid "DESCRIPTION"
msgstr "DESCRIÇÃO"

#: app/flatpak-builtins-build-update-repo.c:72
msgid "URL for a website for this repository"
msgstr "URL de um website para este repositório"

#: app/flatpak-builtins-build-update-repo.c:73
msgid "URL for an icon for this repository"
msgstr "URL de um ícone para este repositório"

#: app/flatpak-builtins-build-update-repo.c:74
msgid "Default branch to use for this repository"
msgstr "Ramo padrão para usar para este repositório"

#: app/flatpak-builtins-build-update-repo.c:74
#: app/flatpak-builtins-remote-add.c:82 app/flatpak-builtins-remote-modify.c:87
#: app/flatpak-builtins-repo.c:713 app/flatpak-builtins-repo.c:714
#: app/flatpak-builtins-run.c:161
msgid "BRANCH"
msgstr "RAMO"

#: app/flatpak-builtins-build-update-repo.c:75
#: app/flatpak-builtins-remote-add.c:83 app/flatpak-builtins-remote-modify.c:88
msgid "COLLECTION-ID"
msgstr "ID-COLEÇÃO"

#. Translators: A sideload is when you install from a local USB drive rather than the Internet.
#: app/flatpak-builtins-build-update-repo.c:77
msgid ""
"Permanently deploy collection ID to client remote configurations, only for "
"sideload support"
msgstr ""
"Implementa permanentemente ID de coleção em configurações remotas de "
"cliente, apenas para suporte a download local"

#: app/flatpak-builtins-build-update-repo.c:78
msgid "Permanently deploy collection ID to client remote configurations"
msgstr ""
"Implementa permanentemente ID de coleção em configurações remotas de cliente"

#: app/flatpak-builtins-build-update-repo.c:79
msgid "Name of authenticator for this repository"
msgstr "Nome do autenticador para este repositório"

#: app/flatpak-builtins-build-update-repo.c:80
msgid "Autoinstall authenticator for this repository"
msgstr "Instala automaticamente um autenticador para este repositório"

#: app/flatpak-builtins-build-update-repo.c:81
msgid "Don't autoinstall authenticator for this repository"
msgstr "Não instala automaticamente um autenticador para este repositório"

#: app/flatpak-builtins-build-update-repo.c:82
#: app/flatpak-builtins-remote-add.c:89
msgid "Authenticator option"
msgstr "Opção do autenticador"

#: app/flatpak-builtins-build-update-repo.c:82
#: app/flatpak-builtins-remote-add.c:89 app/flatpak-builtins-remote-modify.c:95
msgid "KEY=VALUE"
msgstr "CHAVE=VALOR"

#: app/flatpak-builtins-build-update-repo.c:83
msgid "Import new default GPG public key from FILE"
msgstr "Importa nova chave pública GPG padrão do ARQUIVO"

#: app/flatpak-builtins-build-update-repo.c:84
msgid "GPG Key ID to sign the summary with"
msgstr "ID da chave GPG para assinar o sumário"

#: app/flatpak-builtins-build-update-repo.c:86
msgid "Generate delta files"
msgstr "Gera ficheiros delta"

#: app/flatpak-builtins-build-update-repo.c:88
msgid "Don't update the appstream branch"
msgstr "Não atualiza o ramo de appstream"

#: app/flatpak-builtins-build-update-repo.c:89
msgid "Max parallel jobs when creating deltas (default: NUMCPUs)"
msgstr "Máximo de trabalhos paralelos ao criar deltas (padrão: NUMCPUs)"

#: app/flatpak-builtins-build-update-repo.c:89
msgid "NUM-JOBS"
msgstr "NUM-TRABALHOS"

#: app/flatpak-builtins-build-update-repo.c:90
msgid "Don't create deltas matching refs"
msgstr "Não cria deltas correspondendo a refs"

#: app/flatpak-builtins-build-update-repo.c:91
msgid "Prune unused objects"
msgstr "Suprime objetos não usados"

#: app/flatpak-builtins-build-update-repo.c:92
msgid "Prune but don't actually remove anything"
msgstr "Suprime, mas não remove nada"

#: app/flatpak-builtins-build-update-repo.c:93
msgid "Only traverse DEPTH parents for each commit (default: -1=infinite)"
msgstr "Atravessa apenas NÍVEL pais para cada commit (padrão: -1=infinito)"

#: app/flatpak-builtins-build-update-repo.c:93
msgid "DEPTH"
msgstr "NÍVEL"

#: app/flatpak-builtins-build-update-repo.c:223
#, c-format
msgid "Generating delta: %s (%.10s)\n"
msgstr "Gerando delta: %s (%.10s)\n"

#: app/flatpak-builtins-build-update-repo.c:225
#, c-format
msgid "Generating delta: %s (%.10s-%.10s)\n"
msgstr "Gerando delta: %s (%.10s-%.10s)\n"

#: app/flatpak-builtins-build-update-repo.c:233
#, c-format
msgid "Failed to generate delta %s (%.10s): "
msgstr "Falha ao gerar delta %s (%.10s): "

#: app/flatpak-builtins-build-update-repo.c:236
#, c-format
msgid "Failed to generate delta %s (%.10s-%.10s): "
msgstr "Falha ao gerar delta %s (%.10s-%.10s): "

#: app/flatpak-builtins-build-update-repo.c:492
msgid "LOCATION - Update repository metadata"
msgstr "LOCALIZAÇÃO – Atualiza metadados de um repositório"

#: app/flatpak-builtins-build-update-repo.c:609
#, c-format
msgid "Updating appstream branch\n"
msgstr "A atualizar ramo do appstream\n"

#: app/flatpak-builtins-build-update-repo.c:638
#, c-format
msgid "Updating summary\n"
msgstr "A atualizar resumo\n"

#: app/flatpak-builtins-build-update-repo.c:664
#, c-format
msgid "Total objects: %u\n"
msgstr "Objetos totais: %u\n"

#: app/flatpak-builtins-build-update-repo.c:666
#, c-format
msgid "No unreachable objects\n"
msgstr "Nenhum objeto alcançável\n"

#: app/flatpak-builtins-build-update-repo.c:668
#, c-format
msgid "Deleted %u objects, %s freed\n"
msgstr "%u objetos excluídos, %s liberado\n"

#: app/flatpak-builtins-config.c:41
msgid "List configuration keys and values"
msgstr "Lista chaves e valores de configuração"

#: app/flatpak-builtins-config.c:42
msgid "Get configuration for KEY"
msgstr "Obtém configuração da CHAVE"

#: app/flatpak-builtins-config.c:43
msgid "Set configuration for KEY to VALUE"
msgstr "Define configuração da CHAVE para VALOR"

#: app/flatpak-builtins-config.c:44
msgid "Unset configuration for KEY"
msgstr "Remove configuração da CHAVE"

#: app/flatpak-builtins-config.c:149
#, c-format
msgid "'%s' does not look like a language/locale code"
msgstr "“%s” não parece ser um código de idioma/localidade"

#: app/flatpak-builtins-config.c:172
#, c-format
msgid "'%s' does not look like a language code"
msgstr "“%s” não se parece um código de idioma"

#: app/flatpak-builtins-config.c:190
#, fuzzy, c-format
msgid "'%s' is not a valid value (use 'true' or 'false')"
msgstr "“%s” não é um repositório válido: "

#: app/flatpak-builtins-config.c:262
#, c-format
msgid "Unknown configure key '%s'"
msgstr "Configuração de chave desconhecida “%s”"

#: app/flatpak-builtins-config.c:284
msgid "Too many arguments for --list"
msgstr "Número excessivo de argumentos para --list"

#: app/flatpak-builtins-config.c:314 app/flatpak-builtins-config.c:362
msgid "You must specify KEY"
msgstr "Você deve especificar CHAVE"

#: app/flatpak-builtins-config.c:316
msgid "Too many arguments for --get"
msgstr "Número excessivo de argumentos para --get"

#: app/flatpak-builtins-config.c:338
msgid "You must specify KEY and VALUE"
msgstr "Você deve especificar CHAVE e VALOR"

#: app/flatpak-builtins-config.c:340
msgid "Too many arguments for --set"
msgstr "Número excessivo de argumentos para --set"

#: app/flatpak-builtins-config.c:364
msgid "Too many arguments for --unset"
msgstr "Número excessivo de argumentos para --unset"

#: app/flatpak-builtins-config.c:383
msgid "[KEY [VALUE]] - Manage configuration"
msgstr "[CHAVE [VALOR]] – Gerencia configuração"

#: app/flatpak-builtins-config.c:394
msgid "Can only use one of --list, --get, --set or --unset"
msgstr "Pode usar apenas um entre --list, --get, --set ou --unset"

#: app/flatpak-builtins-config.c:408
msgid "Must specify one of --list, --get, --set or --unset"
msgstr "Deve-se especificar um entre --list, --get, --set ou --unset"

#: app/flatpak-builtins-create-usb.c:45 app/flatpak-builtins-install.c:75
#: app/flatpak-builtins-remote-info.c:57 app/flatpak-builtins-uninstall.c:59
#: app/flatpak-builtins-update.c:65
msgid "Look for app with the specified name"
msgstr "Procura pela aplicação com o nome especificado"

#: app/flatpak-builtins-create-usb.c:46
msgid "Arch to copy"
msgstr "Arquitetura para copiar"

#: app/flatpak-builtins-create-usb.c:47
msgid "DEST"
msgstr "DEST"

#: app/flatpak-builtins-create-usb.c:49
msgid "Allow partial commits in the created repo"
msgstr "Permite commits parciais no repositório criado"

#: app/flatpak-builtins-create-usb.c:125 app/flatpak-builtins-create-usb.c:165
#, c-format
msgid ""
"Warning: Related ref ‘%s’ is partially installed. Use --allow-partial to "
"suppress this message.\n"
msgstr ""
"Aviso: A ref “%s” relacionada está parcialmente instalada. Use --allow-"
"partial para suprimir esta mensagem.\n"

#: app/flatpak-builtins-create-usb.c:158
#, c-format
msgid "Warning: Omitting related ref ‘%s’ because it is not installed.\n"
msgstr "Aviso: Omitindo a ref “%s” relacionada porque não está instalada.\n"

#: app/flatpak-builtins-create-usb.c:175
#, c-format
msgid ""
"Warning: Omitting related ref ‘%s’ because its remote ‘%s’ does not have a "
"collection ID set.\n"
msgstr ""
"Aviso: Omitindo a ref “%s” relacionada porque seu remoto “%s” não tem um "
"conjunto de ID de coleção.\n"

#: app/flatpak-builtins-create-usb.c:187
#, c-format
msgid "Warning: Omitting related ref ‘%s’ because it's extra-data.\n"
msgstr "Aviso: Omitindo a ref “%s” relacionada porque é extra-data.\n"

#: app/flatpak-builtins-create-usb.c:262 app/flatpak-builtins-create-usb.c:637
#, c-format
msgid ""
"Remote ‘%s’ does not have a collection ID set, which is required for P2P "
"distribution of ‘%s’."
msgstr ""
"O remoto “%s” não tem um conjunto de ID de coleção, necessário para a "
"distribuição P2P de “%s”."

#: app/flatpak-builtins-create-usb.c:272
#, c-format
msgid "Warning: Omitting ref ‘%s’ (runtime of ‘%s’) because it's extra-data.\n"
msgstr "Aviso: Omitindo a ref “%s” (runtime de “%s”) porque é extra-data.\n"

#: app/flatpak-builtins-create-usb.c:484
msgid "MOUNT-PATH [REF…] - Copy apps or runtimes onto removable media"
msgstr "CAMINHO-MONT [REF…] – Copia apps ou runtimes em mídia removível"

#: app/flatpak-builtins-create-usb.c:493
msgid "MOUNT-PATH and REF must be specified"
msgstr "CAMINHO-MONT e REF devem ser especificados"

#: app/flatpak-builtins-create-usb.c:607
#, c-format
msgid "Ref ‘%s’ found in multiple installations: %s. You must specify one."
msgstr ""
"Ref “%s” localizada em várias instalações: %s. Você deve especificar uma."

#: app/flatpak-builtins-create-usb.c:620
#, c-format
msgid "Refs must all be in the same installation (found in %s and %s)."
msgstr ""
"As refs devem estar todas na mesma instalação (localizadas em %s e %s)."

#: app/flatpak-builtins-create-usb.c:670
#, c-format
msgid ""
"Warning: Ref ‘%s’ is partially installed. Use --allow-partial to suppress "
"this message.\n"
msgstr ""
"Aviso: A ref “%s” está parcialmente instalada. Use --allow-partial para "
"suprimir esta mensagem.\n"

#: app/flatpak-builtins-create-usb.c:681
#, c-format
msgid "Installed ref ‘%s’ is extra-data, and cannot be distributed offline"
msgstr "A ref “%s” instalada é extra-data e não pode ser distribuída offline"

#: app/flatpak-builtins-create-usb.c:721
#, c-format
msgid "Warning: Couldn't update repo metadata for remote ‘%s’: %s\n"
msgstr ""
"Aviso: Não foi possível atualizar metadados do repo para remoto “%s”: %s\n"

#: app/flatpak-builtins-create-usb.c:751
#, c-format
msgid "Warning: Couldn't update appstream data for remote ‘%s’ arch ‘%s’: %s\n"
msgstr ""
"Aviso: Não foi possível atualizar dados de appstream para remoto “%s” "
"arquitetura “%s”: %s\n"

#. Print a warning if both appstream and appstream2 are missing
#: app/flatpak-builtins-create-usb.c:784
#, c-format
msgid ""
"Warning: Couldn't find appstream data for remote ‘%s’ arch ‘%s’: %s; %s\n"
msgstr ""
"Aviso: Não foi possível localizar dados de appstream para remoto “%s” "
"arquitetura “%s”: %s; %s\n"

#. Appstream2 is only for efficiency, so just print a debug message
#: app/flatpak-builtins-create-usb.c:790
#, c-format
msgid "Couldn't find appstream2 data for remote ‘%s’ arch ‘%s’: %s\n"
msgstr ""
"Não foi possível localizar dados de appstream para remoto “%s” arquitetura "
"“%s”: %s\n"

#: app/flatpak-builtins-document-export.c:62
msgid "Create a unique document reference"
msgstr "Cria uma referência única de documento"

#: app/flatpak-builtins-document-export.c:63
msgid "Make the document transient for the current session"
msgstr "Faz o documento transiente para a sessão atual"

#: app/flatpak-builtins-document-export.c:64
msgid "Don't require the file to exist already"
msgstr "Não exige que o ficheiro já exista"

#: app/flatpak-builtins-document-export.c:65
msgid "Give the app read permissions"
msgstr "Concede à aplicação permissões de leitura"

#: app/flatpak-builtins-document-export.c:66
msgid "Give the app write permissions"
msgstr "Concede à aplicação permissões de gravar"

#: app/flatpak-builtins-document-export.c:67
msgid "Give the app delete permissions"
msgstr "Concede à aplicação permissões de eliminar"

#: app/flatpak-builtins-document-export.c:68
msgid "Give the app permissions to grant further permissions"
msgstr "Concede à aplicação permissões para conceder permissões"

#: app/flatpak-builtins-document-export.c:69
msgid "Revoke read permissions of the app"
msgstr "Revoga permissões de leitura da aplicação"

#: app/flatpak-builtins-document-export.c:70
msgid "Revoke write permissions of the app"
msgstr "Revoga permissões de gravar da aplicação"

#: app/flatpak-builtins-document-export.c:71
msgid "Revoke delete permissions of the app"
msgstr "Revoga permissões de eliminar da aplicação"

#: app/flatpak-builtins-document-export.c:72
msgid "Revoke the permission to grant further permissions"
msgstr "Revoga a permissão para conceder permissões"

#: app/flatpak-builtins-document-export.c:73
msgid "Add permissions for this app"
msgstr "Adiciona permissões para esta aplicação"

#: app/flatpak-builtins-document-export.c:73
msgid "APPID"
msgstr "APPID"

#: app/flatpak-builtins-document-export.c:100
msgid "FILE - Export a file to apps"
msgstr "FICHEIRO – Exporta um ficheiro para aplicações"

#: app/flatpak-builtins-document-export.c:109
#: app/flatpak-builtins-document-info.c:72
#: app/flatpak-builtins-document-unexport.c:67
msgid "FILE must be specified"
msgstr "ARQUIVO deve ser especificado"

#: app/flatpak-builtins-document-info.c:63
msgid "FILE - Get information about an exported file"
msgstr "ARQUIVO – Obtém informações sobre um ficheiro exportado"

#: app/flatpak-builtins-document-info.c:100
#: app/flatpak-builtins-document-unexport.c:94
#, c-format
msgid "Not exported\n"
msgstr "Não exportado\n"

#: app/flatpak-builtins-document-list.c:43 app/flatpak-builtins-history.c:53
#: app/flatpak-builtins-list.c:54 app/flatpak-builtins-ps.c:43
#: app/flatpak-builtins-remote-list.c:45 app/flatpak-builtins-remote-ls.c:59
#: app/flatpak-builtins-search.c:38
msgid "What information to show"
msgstr "Quais informações mostrar"

#: app/flatpak-builtins-document-list.c:43 app/flatpak-builtins-history.c:53
#: app/flatpak-builtins-list.c:54 app/flatpak-builtins-ps.c:43
#: app/flatpak-builtins-remote-list.c:45 app/flatpak-builtins-remote-ls.c:59
#: app/flatpak-builtins-search.c:38
msgid "FIELD,…"
msgstr "CAMPO,…"

#: app/flatpak-builtins-document-list.c:44 app/flatpak-builtins-history.c:54
#: app/flatpak-builtins-list.c:52 app/flatpak-builtins-permission-list.c:43
#: app/flatpak-builtins-permission-show.c:43 app/flatpak-builtins-ps.c:44
#: app/flatpak-builtins-remote-list.c:46 app/flatpak-builtins-remote-ls.c:63
#: app/flatpak-builtins-repo.c:717 app/flatpak-builtins-search.c:39
#, fuzzy
msgid "Show output in JSON format"
msgstr "Mostra informações extras"

#: app/flatpak-builtins-document-list.c:49
msgid "Show the document ID"
msgstr "Mostra o ID do documento"

#: app/flatpak-builtins-document-list.c:50
msgid "Path"
msgstr "Caminho"

#: app/flatpak-builtins-document-list.c:50
#: app/flatpak-builtins-document-list.c:51
msgid "Show the document path"
msgstr "Mostra o caminho do documento"

#: app/flatpak-builtins-document-list.c:51 app/flatpak-builtins-list.c:66
#: app/flatpak-builtins-remote-ls.c:74
msgid "Origin"
msgstr "Origem"

#: app/flatpak-builtins-document-list.c:52 app/flatpak-builtins-history.c:62
#: app/flatpak-builtins-ps.c:52
msgid "Application"
msgstr "Aplicativo"

#: app/flatpak-builtins-document-list.c:52
msgid "Show applications with permission"
msgstr "Mostra aplicações com permissão"

#: app/flatpak-builtins-document-list.c:53
#: app/flatpak-builtins-permission-list.c:182
#: app/flatpak-builtins-permission-show.c:145
msgid "Permissions"
msgstr "Permissões"

#: app/flatpak-builtins-document-list.c:53
msgid "Show permissions for applications"
msgstr "Mostra permissões para aplicações"

#: app/flatpak-builtins-document-list.c:161
#, fuzzy, c-format
msgid "No documents found\n"
msgstr "Nenhuma correspondência localizada"

#: app/flatpak-builtins-document-list.c:180
msgid "[APPID] - List exported files"
msgstr "[APPID] – Lista ficheiros exportados"

#: app/flatpak-builtins-document-unexport.c:43
msgid "Specify the document ID"
msgstr "Especifica o ID do documento"

#: app/flatpak-builtins-document-unexport.c:58
msgid "FILE - Unexport a file to apps"
msgstr "FICHEIRO – Desfaz exportação de um ficheiro para aplicações"

#: app/flatpak-builtins-enter.c:88
msgid "INSTANCE COMMAND [ARGUMENT…] - Run a command inside a running sandbox"
msgstr ""
"INSTÂNCIA COMANDO [ARGUMENTO…] – Executa um comando dentro de uma caixa de "
"proteção"

#: app/flatpak-builtins-enter.c:111
msgid "INSTANCE and COMMAND must be specified"
msgstr "INSTÂNCIA e COMANDO devem ser especificados"

#: app/flatpak-builtins-enter.c:138
#, c-format
msgid "%s is neither a pid nor an application or instance ID"
msgstr "%s não é um pid nem uma aplicação ou ID de instância"

#: app/flatpak-builtins-enter.c:144
msgid "entering not supported (need unprivileged user namespaces, or sudo -E)"
msgstr ""
"entrada sem suporte (precisa de espaços de nome de utilizador sem "
"privilégios ou sudo -E)"

#: app/flatpak-builtins-enter.c:145
#, c-format
msgid "No such pid %s"
msgstr "Pid inexistente %s"

#: app/flatpak-builtins-enter.c:158
msgid "Can't read cwd"
msgstr "Não foi possível ler cwd"

#: app/flatpak-builtins-enter.c:163
msgid "Can't read root"
msgstr "Não foi possível ler root"

#: app/flatpak-builtins-enter.c:191
#, c-format
msgid "Invalid %s namespace for pid %d"
msgstr "Espaço de nome inválido %s para pid %d"

#: app/flatpak-builtins-enter.c:202
#, c-format
msgid "Invalid %s namespace for self"
msgstr "Espaço de nome inválido %s para si próprio"

#: app/flatpak-builtins-enter.c:216
#, c-format
msgid "Can't open %s namespace: %s"
msgstr "Não foi possível abrir o espaço de nome %s: %s"

#: app/flatpak-builtins-enter.c:226
msgid "entering not supported (need unprivileged user namespaces)"
msgstr ""
"entrada sem suporte (precisa de espaços de nome de utilizador sem "
"privilégios)"

#: app/flatpak-builtins-enter.c:227
#, c-format
msgid "Can't enter %s namespace: %s"
msgstr "Não foi possível entrar no espaço de nome %s: %s"

#: app/flatpak-builtins-enter.c:234
msgid "Can't chdir"
msgstr "Não foi possível executar chdir"

#: app/flatpak-builtins-enter.c:237
msgid "Can't chroot"
msgstr "Não foi possível fazer chroot"

#: app/flatpak-builtins-enter.c:240
msgid "Can't switch gid"
msgstr "Não foi possível trocar o gid"

#: app/flatpak-builtins-enter.c:243
msgid "Can't switch uid"
msgstr "Não foi possível trocar o uid"

#: app/flatpak-builtins-history.c:50
msgid "Only show changes after TIME"
msgstr "Mostra alterações apenas após TEMPO"

#: app/flatpak-builtins-history.c:50 app/flatpak-builtins-history.c:51
msgid "TIME"
msgstr "Mostra alterações apenas após TEMPO"

#: app/flatpak-builtins-history.c:51
msgid "Only show changes before TIME"
msgstr "Mostra alterações apenas antes de TEMPO"

#: app/flatpak-builtins-history.c:52
msgid "Show newest entries first"
msgstr "Mostra entradas mais novas primeiro"

#: app/flatpak-builtins-history.c:59
msgid "Time"
msgstr "Tempo"

#: app/flatpak-builtins-history.c:59
msgid "Show when the change happened"
msgstr "Mostra quando as alterações ocorreram"

#: app/flatpak-builtins-history.c:60
msgid "Change"
msgstr "Alteração"

#: app/flatpak-builtins-history.c:60
msgid "Show the kind of change"
msgstr "Mostra o tipo de alteração"

#: app/flatpak-builtins-history.c:61 app/flatpak-builtins-list.c:68
#: app/flatpak-builtins-remote-ls.c:75 app/flatpak-builtins-repo.c:335
msgid "Ref"
msgstr "Ref"

#: app/flatpak-builtins-history.c:61 app/flatpak-builtins-list.c:68
#: app/flatpak-builtins-remote-ls.c:75
msgid "Show the ref"
msgstr "Mostra a ref"

#: app/flatpak-builtins-history.c:62
msgid "Show the application/runtime ID"
msgstr "Mostra o ID de aplicação/runtime"

#: app/flatpak-builtins-history.c:63 app/flatpak-builtins-list.c:64
#: app/flatpak-builtins-ps.c:53 app/flatpak-builtins-remote-ls.c:73
#: app/flatpak-cli-transaction.c:1435
msgid "Arch"
msgstr "Arch"

#: app/flatpak-builtins-history.c:63 app/flatpak-builtins-list.c:64
#: app/flatpak-builtins-ps.c:53 app/flatpak-builtins-remote-ls.c:73
msgid "Show the architecture"
msgstr "Mostra a arquitetura"

#: app/flatpak-builtins-history.c:64 app/flatpak-builtins-list.c:63
#: app/flatpak-builtins-ps.c:54 app/flatpak-builtins-remote-ls.c:72
#: app/flatpak-builtins-search.c:48 app/flatpak-cli-transaction.c:1438
msgid "Branch"
msgstr "Ramo"

#: app/flatpak-builtins-history.c:64 app/flatpak-builtins-list.c:63
#: app/flatpak-builtins-remote-ls.c:72
msgid "Show the branch"
msgstr "Mostra o ramo"

#: app/flatpak-builtins-history.c:65 app/flatpak-builtins-list.c:67
msgid "Installation"
msgstr "Instalação"

#: app/flatpak-builtins-history.c:65
msgid "Show the affected installation"
msgstr "Mostra a instalação afetada"

#: app/flatpak-builtins-history.c:66 app/flatpak-cli-transaction.c:1452
msgid "Remote"
msgstr "Remoto"

#: app/flatpak-builtins-history.c:66
msgid "Show the remote"
msgstr "Mostra o remoto"

#: app/flatpak-builtins-history.c:67 app/flatpak-builtins-ps.c:55
#: app/flatpak-builtins-remote-ls.c:76
msgid "Commit"
msgstr "Commit"

#: app/flatpak-builtins-history.c:67
msgid "Show the current commit"
msgstr "Mostra o commit atual"

#: app/flatpak-builtins-history.c:68
msgid "Old Commit"
msgstr "Commit antigo"

#: app/flatpak-builtins-history.c:68
msgid "Show the previous commit"
msgstr "Mostra o commit anterior"

#: app/flatpak-builtins-history.c:69
msgid "Show the remote URL"
msgstr "Mostra o ID do remoto"

#: app/flatpak-builtins-history.c:70 app/flatpak-cli-transaction.c:700
msgid "User"
msgstr "Usuário"

#: app/flatpak-builtins-history.c:70
msgid "Show the user doing the change"
msgstr "Mostra o utilizador a efetuar a alteração"

#: app/flatpak-builtins-history.c:71
msgid "Tool"
msgstr "Ferramenta"

#: app/flatpak-builtins-history.c:71
msgid "Show the tool that was used"
msgstr "Mostra a ferramenta que foi usada"

#: app/flatpak-builtins-history.c:72 app/flatpak-builtins-list.c:62
#: app/flatpak-builtins-remote-ls.c:71 app/flatpak-builtins-search.c:47
msgid "Version"
msgstr "Versão"

#: app/flatpak-builtins-history.c:72
msgid "Show the Flatpak version"
msgstr "Mostra a versão do Flatpak"

#: app/flatpak-builtins-history.c:91
#, c-format
msgid "Failed to get journal data (%s): %s"
msgstr "Falha ao obter dados do journal (%s): %s"

#: app/flatpak-builtins-history.c:146
#, c-format
msgid "Failed to open journal: %s"
msgstr "Falha ao abrir journal: %s"

#: app/flatpak-builtins-history.c:153
#, c-format
msgid "Failed to add match to journal: %s"
msgstr "Falha ao adicionar correspondência ao journal: %s"

#: app/flatpak-builtins-history.c:471
msgid " - Show history"
msgstr " – Mostra histórico"

#: app/flatpak-builtins-history.c:490
#, c-format
msgid "Failed to parse the --since option"
msgstr "Falha ao analisar a opção --since"

#: app/flatpak-builtins-history.c:501
#, c-format
msgid "Failed to parse the --until option"
msgstr "Falha ao analisar a opção --until"

#: app/flatpak-builtins-info.c:56
msgid "Show user installations"
msgstr "Mostra instalações do utilizador"

#: app/flatpak-builtins-info.c:57
msgid "Show system-wide installations"
msgstr "Mostra instalações do sistema"

#: app/flatpak-builtins-info.c:58
msgid "Show specific system-wide installations"
msgstr "Mostra instalações específicas do sistema"

#: app/flatpak-builtins-info.c:59 app/flatpak-builtins-remote-info.c:59
msgid "Show ref"
msgstr "Mostra a ref"

#: app/flatpak-builtins-info.c:60 app/flatpak-builtins-remote-info.c:60
msgid "Show commit"
msgstr "Mostra o commit"

#: app/flatpak-builtins-info.c:61
msgid "Show origin"
msgstr "Mostra a origem"

#: app/flatpak-builtins-info.c:62
msgid "Show size"
msgstr "Mostra o tamanho"

#: app/flatpak-builtins-info.c:63 app/flatpak-builtins-remote-info.c:62
msgid "Show metadata"
msgstr "Mostra os metadados"

#: app/flatpak-builtins-info.c:64 app/flatpak-builtins-remote-info.c:63
msgid "Show runtime"
msgstr "Mostra o runtime"

#: app/flatpak-builtins-info.c:65 app/flatpak-builtins-remote-info.c:64
msgid "Show sdk"
msgstr "Mostra o sdk"

#: app/flatpak-builtins-info.c:66
msgid "Show permissions"
msgstr "Mostra as permissões"

#: app/flatpak-builtins-info.c:67
msgid "Query file access"
msgstr "Consulta o acesso a ficheiros"

#: app/flatpak-builtins-info.c:67 app/flatpak-builtins-install.c:82
#: app/flatpak-builtins-install.c:88 app/flatpak-builtins-preinstall.c:68
#: app/flatpak-builtins-run.c:182 app/flatpak-builtins-run.c:184
#: app/flatpak-builtins-update.c:67 app/flatpak-builtins-update.c:71
msgid "PATH"
msgstr "CAMINHO"

#: app/flatpak-builtins-info.c:68
msgid "Show extensions"
msgstr "Mostra as extensões"

#: app/flatpak-builtins-info.c:69
msgid "Show location"
msgstr "Mostra a localização"

#: app/flatpak-builtins-info.c:116
msgid "NAME [BRANCH] - Get info about an installed app or runtime"
msgstr ""
"NOME [RAMO] – Obtém informações sobre uma aplicação e/ou um runtime instalado"

#: app/flatpak-builtins-info.c:123 app/flatpak-builtins-remote-add.c:317
#: app/flatpak-builtins-remote-delete.c:63
msgid "NAME must be specified"
msgstr "NOME deve ser especificado"

#: app/flatpak-builtins-info.c:196
msgid "ref not present in origin"
msgstr "ref não presente na origem"

#: app/flatpak-builtins-info.c:211 app/flatpak-builtins-remote-info.c:217
#, c-format
msgid "Warning: Commit has no flatpak metadata\n"
msgstr "Aviso: O commit tem nenhum metadado de flatpak\n"

#: app/flatpak-builtins-info.c:217 app/flatpak-builtins-info.c:259
#: app/flatpak-builtins-info.c:455 app/flatpak-builtins-info.c:513
#: app/flatpak-builtins-remote-info.c:236
#: app/flatpak-builtins-remote-info.c:271
msgid "ID:"
msgstr "ID:"

#: app/flatpak-builtins-info.c:218 app/flatpak-builtins-info.c:260
#: app/flatpak-builtins-remote-info.c:237
#: app/flatpak-builtins-remote-info.c:272
msgid "Ref:"
msgstr "Ref:"

#: app/flatpak-builtins-info.c:219 app/flatpak-builtins-info.c:261
#: app/flatpak-builtins-remote-info.c:238
#: app/flatpak-builtins-remote-info.c:273
msgid "Arch:"
msgstr "Arq.:"

#: app/flatpak-builtins-info.c:220 app/flatpak-builtins-info.c:262
#: app/flatpak-builtins-remote-info.c:239
#: app/flatpak-builtins-remote-info.c:274
msgid "Branch:"
msgstr "Ramo:"

#: app/flatpak-builtins-info.c:222 app/flatpak-builtins-info.c:264
#: app/flatpak-builtins-remote-info.c:241
#: app/flatpak-builtins-remote-info.c:276
msgid "Version:"
msgstr "Versão:"

#: app/flatpak-builtins-info.c:224 app/flatpak-builtins-info.c:266
#: app/flatpak-builtins-remote-info.c:243
#: app/flatpak-builtins-remote-info.c:278
msgid "License:"
msgstr "Licença:"

#: app/flatpak-builtins-info.c:226 app/flatpak-builtins-info.c:269
#: app/flatpak-builtins-remote-info.c:245
#: app/flatpak-builtins-remote-info.c:280
msgid "Collection:"
msgstr "Coleção:"

#: app/flatpak-builtins-info.c:227 app/flatpak-builtins-info.c:270
#: app/flatpak-builtins-info.c:458 app/flatpak-builtins-info.c:516
msgid "Installation:"
msgstr "Instalação:"

#: app/flatpak-builtins-info.c:228 app/flatpak-builtins-info.c:271
#: app/flatpak-builtins-info.c:459 app/flatpak-builtins-info.c:517
#: app/flatpak-builtins-remote-info.c:249
#: app/flatpak-builtins-remote-info.c:284
#, fuzzy
msgid "Installed Size:"
msgstr "Tamanho instalado:"

#: app/flatpak-builtins-info.c:231 app/flatpak-builtins-info.c:279
#: app/flatpak-builtins-remote-info.c:252
#: app/flatpak-builtins-remote-info.c:288
msgid "Runtime:"
msgstr "Runtime:"

#: app/flatpak-builtins-info.c:232 app/flatpak-builtins-info.c:288
#: app/flatpak-builtins-remote-info.c:253
#: app/flatpak-builtins-remote-info.c:293
msgid "Sdk:"
msgstr "Sdk:"

#: app/flatpak-builtins-info.c:235 app/flatpak-builtins-info.c:313
#: app/flatpak-builtins-remote-info.c:256
#: app/flatpak-builtins-remote-info.c:319
msgid "Date:"
msgstr "Data:"

#: app/flatpak-builtins-info.c:237 app/flatpak-builtins-info.c:311
#: app/flatpak-builtins-remote-info.c:258
#: app/flatpak-builtins-remote-info.c:317
msgid "Subject:"
msgstr "Assunto:"

#: app/flatpak-builtins-info.c:240 app/flatpak-builtins-info.c:295
msgid "Active commit:"
msgstr "Commit ativo:"

#: app/flatpak-builtins-info.c:241 app/flatpak-builtins-info.c:298
msgid "Latest commit:"
msgstr "Último commit:"

#: app/flatpak-builtins-info.c:244 app/flatpak-builtins-info.c:303
#: app/flatpak-builtins-info.c:457 app/flatpak-builtins-info.c:515
#: app/flatpak-builtins-remote-info.c:259
#: app/flatpak-builtins-remote-info.c:298
msgid "Commit:"
msgstr "Commit:"

#: app/flatpak-builtins-info.c:246 app/flatpak-builtins-info.c:308
#: app/flatpak-builtins-remote-info.c:261
#: app/flatpak-builtins-remote-info.c:303
msgid "Parent:"
msgstr "Pai:"

#: app/flatpak-builtins-info.c:248 app/flatpak-builtins-info.c:321
msgid "Alt-id:"
msgstr "Alt-id:"

#: app/flatpak-builtins-info.c:250 app/flatpak-builtins-info.c:325
#: app/flatpak-builtins-remote-info.c:263
#: app/flatpak-builtins-remote-info.c:308
msgid "End-of-life:"
msgstr "Fim de vida:"

#: app/flatpak-builtins-info.c:252 app/flatpak-builtins-info.c:330
#: app/flatpak-builtins-remote-info.c:265
#: app/flatpak-builtins-remote-info.c:313
msgid "End-of-life-rebase:"
msgstr "Rebase de fim de vida:"

#: app/flatpak-builtins-info.c:254 app/flatpak-builtins-info.c:317
msgid "Subdirectories:"
msgstr "Subdiretórios:"

#: app/flatpak-builtins-info.c:255 app/flatpak-builtins-info.c:454
#: app/flatpak-builtins-info.c:512
msgid "Extension:"
msgstr "Extensões:"

#: app/flatpak-builtins-info.c:267 app/flatpak-builtins-info.c:456
#: app/flatpak-builtins-info.c:514
msgid "Origin:"
msgstr "Origem:"

#: app/flatpak-builtins-info.c:460 app/flatpak-builtins-info.c:522
msgid "Subpaths:"
msgstr "Subcaminhos:"

#: app/flatpak-builtins-info.c:478
msgid "unmaintained"
msgstr "sem mantenedor"

#: app/flatpak-builtins-info.c:480 app/flatpak-builtins-info.c:482
msgid "unknown"
msgstr "desconhecido"

#: app/flatpak-builtins-install.c:68 app/flatpak-builtins-preinstall.c:57
msgid "Don't pull, only install from local cache"
msgstr "Não faz pull, apenas instala do cache local"

#: app/flatpak-builtins-install.c:69 app/flatpak-builtins-preinstall.c:58
#: app/flatpak-builtins-update.c:60
msgid "Don't deploy, only download to local cache"
msgstr "Não implementa (deploy), apenas baixa para o cache local"

#: app/flatpak-builtins-install.c:70 app/flatpak-builtins-preinstall.c:59
msgid "Don't install related refs"
msgstr "Não instala refs relacionadas"

#: app/flatpak-builtins-install.c:71 app/flatpak-builtins-preinstall.c:60
#: app/flatpak-builtins-update.c:62
msgid "Don't verify/install runtime dependencies"
msgstr "Não verifica/instala dependências de runtime"

#: app/flatpak-builtins-install.c:72
msgid "Don't automatically pin explicit installs"
msgstr "Não fixar instalações explícitas automaticamente"

#: app/flatpak-builtins-install.c:73 app/flatpak-builtins-preinstall.c:61
#: app/flatpak-builtins-update.c:63
msgid "Don't use static deltas"
msgstr "Não usa deltas estáticos"

#: app/flatpak-builtins-install.c:76 app/flatpak-builtins-preinstall.c:62
msgid "Additionally install the SDK used to build the given refs"
msgstr ""

#: app/flatpak-builtins-install.c:77 app/flatpak-builtins-preinstall.c:63
msgid ""
"Additionally install the debug info for the given refs and their dependencies"
msgstr ""

#: app/flatpak-builtins-install.c:78
msgid "Assume LOCATION is a .flatpak single-file bundle"
msgstr "Presume LOCALIZAÇÃO como sendo um pacote de ficheiro único .flatpak"

#: app/flatpak-builtins-install.c:79
msgid "Assume LOCATION is a .flatpakref application description"
msgstr "Presume LOCALIZAÇÃO como sendo uma descrição de aplicação .flatpakref"

#: app/flatpak-builtins-install.c:80
msgid "Assume LOCATION is containers-transports(5) reference to an OCI image"
msgstr ""

#: app/flatpak-builtins-install.c:81
msgid "Check bundle signatures with GPG key from FILE (- for stdin)"
msgstr "Verifica assinaturas de pacote com chave GPG do ARQUIVO (- para stdin)"

#: app/flatpak-builtins-install.c:82
msgid "Only install this subpath"
msgstr "Instala apenas este subcaminho"

#: app/flatpak-builtins-install.c:83 app/flatpak-builtins-preinstall.c:64
#: app/flatpak-builtins-uninstall.c:63 app/flatpak-builtins-update.c:68
msgid "Automatically answer yes for all questions"
msgstr "Responde sim automaticamente para todas as perguntas"

#: app/flatpak-builtins-install.c:84 app/flatpak-builtins-preinstall.c:65
msgid "Uninstall first if already installed"
msgstr "Desinstala primeiro, se já instalado"

#: app/flatpak-builtins-install.c:85 app/flatpak-builtins-preinstall.c:66
#: app/flatpak-builtins-uninstall.c:64 app/flatpak-builtins-update.c:69
msgid "Produce minimal output and don't ask questions"
msgstr "Produz saída mínima e não faz perguntas"

#: app/flatpak-builtins-install.c:86
msgid "Update install if already installed"
msgstr "Atualiza instalação se já instalada"

#. Translators: A sideload is when you install from a local USB drive rather than the Internet.
#: app/flatpak-builtins-install.c:88 app/flatpak-builtins-preinstall.c:68
#: app/flatpak-builtins-update.c:71
msgid "Use this local repo for sideloads"
msgstr "Usa este repositório local para transferências locais"

#: app/flatpak-builtins-install.c:178
msgid "Bundle filename must be specified"
msgstr "Ficheiro do pacote deve ser especificado"

#: app/flatpak-builtins-install.c:188
msgid "Remote bundles are not supported"
msgstr "Não há suporte a pacotes remotos"

#: app/flatpak-builtins-install.c:231
msgid "Filename or uri must be specified"
msgstr "Ficheiro ou uri deve ser especificado"

#: app/flatpak-builtins-install.c:295
#, fuzzy
msgid "Image location must be specified"
msgstr "Pelo menos um REF deve ser especificado"

#: app/flatpak-builtins-install.c:345
msgid "[LOCATION/REMOTE] [REF…] - Install applications or runtimes"
msgstr "[LOCALIZAÇÃO/REMOTO] [REF…] – Instala aplicações ou runtimes"

#: app/flatpak-builtins-install.c:378
msgid "At least one REF must be specified"
msgstr "Pelo menos um REF deve ser especificado"

#: app/flatpak-builtins-install.c:392
#, c-format
msgid "Looking for matches…\n"
msgstr "A procurar por correspondências…\n"

#: app/flatpak-builtins-install.c:513
#, fuzzy, c-format
msgid "No remote refs found for ‘%s’"
msgstr "Nenhuma ref de remoto localizada similar a “%s”"

#: app/flatpak-builtins-install.c:573 app/flatpak-builtins-uninstall.c:405
#: common/flatpak-ref-utils.c:689 common/flatpak-ref-utils.c:1595
#, c-format
msgid "Invalid branch %s: %s"
msgstr "Ramo inválido %s: %s"

#: app/flatpak-builtins-install.c:606
#, c-format
msgid "Nothing matches %s in local repository for remote %s"
msgstr "Nada corresponde a %s no repositório local para o remoto %s"

#: app/flatpak-builtins-install.c:608
#, c-format
msgid "Nothing matches %s in remote %s"
msgstr "Nada corresponde a %s no remoto %s"

#: app/flatpak-builtins-install.c:629
#, c-format
msgid "Skipping: %s\n"
msgstr "Ignorando: %s\n"

#: app/flatpak-builtins-kill.c:110
#, c-format
msgid "%s is not running"
msgstr "%s não está em execução"

#: app/flatpak-builtins-kill.c:136
msgid "INSTANCE - Stop a running application"
msgstr "INSTÂNCIA – Termina uma aplicação em execução"

#: app/flatpak-builtins-kill.c:144 app/flatpak-builtins-ps.c:256
msgid "Extra arguments given"
msgstr "Argumentos extras dados"

#: app/flatpak-builtins-kill.c:150
msgid "Must specify the app to kill"
msgstr "Deve-se especificar a aplicação para terminar"

#: app/flatpak-builtins-list.c:47
msgid "Show extra information"
msgstr "Mostra informações extras"

#: app/flatpak-builtins-list.c:48
msgid "List installed runtimes"
msgstr "Lista runtimes instalados"

#: app/flatpak-builtins-list.c:49
msgid "List installed applications"
msgstr "Lista aplicações instaladas"

#: app/flatpak-builtins-list.c:50
msgid "Arch to show"
msgstr "Arquitetura para mostrar"

#: app/flatpak-builtins-list.c:51 app/flatpak-builtins-remote-ls.c:57
msgid "List all refs (including locale/debug)"
msgstr "Lista todos os refs (incluindo localidade/depuração)"

#: app/flatpak-builtins-list.c:53 app/flatpak-builtins-remote-ls.c:58
msgid "List all applications using RUNTIME"
msgstr "Lista todas as aplicações usando RUNTIME"

#: app/flatpak-builtins-list.c:59 app/flatpak-builtins-remote-list.c:51
#: app/flatpak-builtins-remote-ls.c:68 app/flatpak-builtins-search.c:44
msgid "Name"
msgstr "Nome"

#: app/flatpak-builtins-list.c:59 app/flatpak-builtins-remote-list.c:51
#: app/flatpak-builtins-remote-ls.c:68 app/flatpak-builtins-search.c:44
msgid "Show the name"
msgstr "Mostra o nome"

#: app/flatpak-builtins-list.c:60 app/flatpak-builtins-remote-list.c:60
#: app/flatpak-builtins-remote-ls.c:69 app/flatpak-builtins-search.c:45
msgid "Description"
msgstr "Descrição"

#: app/flatpak-builtins-list.c:60 app/flatpak-builtins-remote-ls.c:69
#: app/flatpak-builtins-search.c:45
msgid "Show the description"
msgstr "Mostra a descrição"

#: app/flatpak-builtins-list.c:61 app/flatpak-builtins-remote-ls.c:70
#: app/flatpak-builtins-search.c:46
msgid "Application ID"
msgstr "ID de aplicação"

#: app/flatpak-builtins-list.c:61 app/flatpak-builtins-ps.c:52
#: app/flatpak-builtins-remote-ls.c:70 app/flatpak-builtins-search.c:46
msgid "Show the application ID"
msgstr "Mostra o ID de aplicação"

#: app/flatpak-builtins-list.c:62 app/flatpak-builtins-remote-ls.c:71
#: app/flatpak-builtins-search.c:47
msgid "Show the version"
msgstr "Mostra a versão"

#: app/flatpak-builtins-list.c:65 app/flatpak-builtins-ps.c:56
#: app/flatpak-builtins-remote-ls.c:77
msgid "Runtime"
msgstr "Runtime"

#: app/flatpak-builtins-list.c:65
msgid "Show the used runtime"
msgstr "Mostra o runtime usado"

#: app/flatpak-builtins-list.c:66 app/flatpak-builtins-remote-ls.c:74
msgid "Show the origin remote"
msgstr "Mostra o remoto origem"

#: app/flatpak-builtins-list.c:67
msgid "Show the installation"
msgstr "Mostra a instalação"

#: app/flatpak-builtins-list.c:69
msgid "Active commit"
msgstr "Commit ativo"

#: app/flatpak-builtins-list.c:69 app/flatpak-builtins-remote-ls.c:76
msgid "Show the active commit"
msgstr "Mostra o commit ativo"

#: app/flatpak-builtins-list.c:70
msgid "Latest commit"
msgstr "Último commit"

#: app/flatpak-builtins-list.c:70
msgid "Show the latest commit"
msgstr "Mostra o último commit"

#: app/flatpak-builtins-list.c:71 app/flatpak-builtins-remote-ls.c:78
msgid "Installed size"
msgstr "Tamanho instalado"

#: app/flatpak-builtins-list.c:71 app/flatpak-builtins-remote-ls.c:78
msgid "Show the installed size"
msgstr "Mostra o tamanho instalado"

#: app/flatpak-builtins-list.c:72 app/flatpak-builtins-remote-list.c:58
#: app/flatpak-builtins-remote-ls.c:80 app/flatpak-builtins-repo.c:340
msgid "Options"
msgstr "Opções"

#: app/flatpak-builtins-list.c:72 app/flatpak-builtins-remote-list.c:58
#: app/flatpak-builtins-remote-ls.c:80
msgid "Show options"
msgstr "Mostra as opções"

#: app/flatpak-builtins-list.c:180
#, fuzzy, c-format
msgid "Unable to load details of %s: %s"
msgstr "Não foi possível carregar metadados do remoto %s: %s"

#: app/flatpak-builtins-list.c:190
#, fuzzy, c-format
msgid "Unable to inspect current version of %s: %s"
msgstr "Não foi possível criar o ficheiro %s"

#: app/flatpak-builtins-list.c:408
msgid " - List installed apps and/or runtimes"
msgstr " – Lista as aplicações e/ou runtimes instalados"

#: app/flatpak-builtins-make-current.c:38
msgid "Arch to make current for"
msgstr "Arquitetura para a qual será tornada atual"

#: app/flatpak-builtins-make-current.c:58
msgid "APP BRANCH - Make branch of application current"
msgstr "APLICAÇÃO RAMO – Faz o ramo da aplicação atual"

#: app/flatpak-builtins-make-current.c:69 app/flatpak-builtins-run.c:260
msgid "APP must be specified"
msgstr "APLICATIVO deve ser especificado"

#: app/flatpak-builtins-make-current.c:84
msgid "BRANCH must be specified"
msgstr "RAMO deve ser especificado"

#: app/flatpak-builtins-make-current.c:97
#, c-format
msgid "App %s branch %s is not installed"
msgstr "Aplicativo %s ramo %s não está instalado"

#: app/flatpak-builtins-mask.c:42
msgid "Remove matching masks"
msgstr "Remove máscaras correspondentes"

#: app/flatpak-builtins-mask.c:54
msgid ""
"[PATTERN…] - disable updates and automatic installation matching patterns"
msgstr ""
"[PADRÃO…] - desativa atualizações e instalação automática correspondendo a "
"padrões"

#: app/flatpak-builtins-mask.c:73
#, c-format
msgid "No masked patterns\n"
msgstr "Nenhum padrão mascarado\n"

#: app/flatpak-builtins-mask.c:78
#, c-format
msgid "Masked patterns:\n"
msgstr "Padrões mascarados:\n"

#: app/flatpak-builtins-override.c:42
msgid "Remove existing overrides"
msgstr "Remove sobreposições existentes"

#: app/flatpak-builtins-override.c:43
msgid "Show existing overrides"
msgstr "Mostra sobreposições existentes"

#: app/flatpak-builtins-override.c:59
msgid "[APP] - Override settings [for application]"
msgstr "[APLICATIVO] – Sobrepõe as configurações [para uma aplicação]"

#: app/flatpak-builtins-permission-list.c:143
msgid "[TABLE] [ID] - List permissions"
msgstr "[TABELA] [ID] – Lista permissões"

#: app/flatpak-builtins-permission-list.c:179
#: app/flatpak-builtins-permission-show.c:142
msgid "Table"
msgstr "Tabela"

#: app/flatpak-builtins-permission-list.c:180
#: app/flatpak-builtins-permission-show.c:143
msgid "Object"
msgstr "Objeto"

#: app/flatpak-builtins-permission-list.c:181
#: app/flatpak-builtins-permission-show.c:144
msgid "App"
msgstr "App"

#: app/flatpak-builtins-permission-list.c:183
#: app/flatpak-builtins-permission-show.c:146
msgid "Data"
msgstr "Dados"

#: app/flatpak-builtins-permission-remove.c:120
msgid "TABLE ID [APP_ID] - Remove item from permission store"
msgstr "TABELA ID [APP_ID] – Remove item do armazenamento de permissão"

#: app/flatpak-builtins-permission-remove.c:129
#: app/flatpak-builtins-permission-set.c:120
msgid "Too few arguments"
msgstr "Número insuficiente de argumentos"

#: app/flatpak-builtins-permission-reset.c:43
msgid "Reset all permissions"
msgstr "Redefine todas as permissões"

#: app/flatpak-builtins-permission-reset.c:144
msgid "APP_ID - Reset permissions for an app"
msgstr "ID_APP – Redefine permissões para esta aplicação"

#: app/flatpak-builtins-permission-reset.c:153
#: app/flatpak-builtins-permission-show.c:124
msgid "Wrong number of arguments"
msgstr "Número incorreto de argumentos"

#: app/flatpak-builtins-permission-set.c:42
msgid "Associate DATA with the entry"
msgstr "Associa DADOS com a entrada"

#: app/flatpak-builtins-permission-set.c:42
msgid "DATA"
msgstr "DADOS"

#: app/flatpak-builtins-permission-set.c:111
msgid "TABLE ID APP_ID [PERMISSION...] - Set permissions"
msgstr "TABELA ID APP_ID [PERMISSÃO…] – Define permissões"

#: app/flatpak-builtins-permission-set.c:132
#, c-format
msgid "Failed to parse '%s' as GVariant: "
msgstr "Falha ao analisar “%s” como GVariant: "

#: app/flatpak-builtins-permission-show.c:115
msgid "APP_ID - Show permissions for an app"
msgstr "ID_APP – Mostra permissões para esta aplicação"

#: app/flatpak-builtins-pin.c:44
msgid "Remove matching pins"
msgstr "Remove as fixações correspondentes"

#: app/flatpak-builtins-pin.c:56
msgid "[PATTERN…] - disable automatic removal of runtimes matching patterns"
msgstr ""
"[PADRÃO…] - desativa remoção automática de runtimes correspondendo a padrões"

#: app/flatpak-builtins-pin.c:75
#, c-format
msgid "No pinned patterns\n"
msgstr "Nenhum padrão fixado\n"

#: app/flatpak-builtins-pin.c:80
#, c-format
msgid "Pinned patterns:\n"
msgstr "Padrões fixados:\n"

#: app/flatpak-builtins-preinstall.c:80
msgid "- Install flatpaks that are part of the operating system"
msgstr ""

#: app/flatpak-builtins-preinstall.c:118
#, c-format
msgid "Nothing to do.\n"
msgstr "Nada para fazer.\n"

#: app/flatpak-builtins-ps.c:49
msgid "Instance"
msgstr "Instância"

#: app/flatpak-builtins-ps.c:49
msgid "Show the instance ID"
msgstr "Mostra o ID da instância"

#: app/flatpak-builtins-ps.c:50 app/flatpak-builtins-run.c:178
msgid "PID"
msgstr "PID"

#: app/flatpak-builtins-ps.c:50
msgid "Show the PID of the wrapper process"
msgstr "Mostra o PID do processo wrapper"

#: app/flatpak-builtins-ps.c:51
msgid "Child-PID"
msgstr "PID-Filho"

#: app/flatpak-builtins-ps.c:51
msgid "Show the PID of the sandbox process"
msgstr "Mostra o PID do processo da caixa de proteção"

#: app/flatpak-builtins-ps.c:54 app/flatpak-builtins-search.c:48
msgid "Show the application branch"
msgstr "Mostra o ramo da aplicação"

#: app/flatpak-builtins-ps.c:55
msgid "Show the application commit"
msgstr "Mostra o commit de aplicação"

#: app/flatpak-builtins-ps.c:56
msgid "Show the runtime ID"
msgstr "Mostra o ID de runtime"

#: app/flatpak-builtins-ps.c:57
msgid "R.-Branch"
msgstr "R.-Branch"

#: app/flatpak-builtins-ps.c:57
msgid "Show the runtime branch"
msgstr "Mostra o ramo do runtime"

#: app/flatpak-builtins-ps.c:58
msgid "R.-Commit"
msgstr "R.-Commit"

#: app/flatpak-builtins-ps.c:58
msgid "Show the runtime commit"
msgstr "Mostra o commit de runtime"

#: app/flatpak-builtins-ps.c:59
msgid "Active"
msgstr "Ativo"

#: app/flatpak-builtins-ps.c:59
msgid "Show whether the app is active"
msgstr "Mostra se a aplicação está ativa"

#: app/flatpak-builtins-ps.c:60
msgid "Background"
msgstr "Segundo plano"

#: app/flatpak-builtins-ps.c:60
msgid "Show whether the app is background"
msgstr "Mostra se a aplicação está em segundo plano"

#: app/flatpak-builtins-ps.c:246
msgid " - Enumerate running sandboxes"
msgstr " – Enumera as caixas de proteção em execução"

#: app/flatpak-builtins-remote-add.c:66
msgid "Do nothing if the provided remote exists"
msgstr "Faz nada se o remoto fornecido existir"

#: app/flatpak-builtins-remote-add.c:67
msgid "LOCATION specifies a configuration file, not the repo location"
msgstr ""
"LOCALIZAÇÃO especifica um ficheiro de configuração, não a localização do repo"

#: app/flatpak-builtins-remote-add.c:72 app/flatpak-builtins-remote-modify.c:78
msgid "Disable GPG verification"
msgstr "Desabilita verificação GPG"

#: app/flatpak-builtins-remote-add.c:73 app/flatpak-builtins-remote-modify.c:79
msgid "Mark the remote as don't enumerate"
msgstr "Marca o remoto como não enumerado"

#: app/flatpak-builtins-remote-add.c:74 app/flatpak-builtins-remote-modify.c:80
msgid "Mark the remote as don't use for deps"
msgstr "Marca o remoto como não usar para dependências"

#: app/flatpak-builtins-remote-add.c:75 app/flatpak-builtins-remote-modify.c:81
msgid "Set priority (default 1, higher is more prioritized)"
msgstr "Define prioridade (padrão 1, maior é mais prioritário)"

#: app/flatpak-builtins-remote-add.c:75 app/flatpak-builtins-remote-modify.c:81
msgid "PRIORITY"
msgstr "PRIORIDADE"

#: app/flatpak-builtins-remote-add.c:76
msgid "The named subset to use for this remote"
msgstr "O subconjunto nomeado a ser usado para este remoto"

#: app/flatpak-builtins-remote-add.c:76 app/flatpak-builtins-remote-modify.c:71
msgid "SUBSET"
msgstr "SUBCONJUNTO"

#: app/flatpak-builtins-remote-add.c:77 app/flatpak-builtins-remote-modify.c:82
msgid "A nice name to use for this remote"
msgstr "Um nome legal para usar para este remoto"

#: app/flatpak-builtins-remote-add.c:78 app/flatpak-builtins-remote-modify.c:83
msgid "A one-line comment for this remote"
msgstr "Um comentário de uma linha para este remoto"

#: app/flatpak-builtins-remote-add.c:79 app/flatpak-builtins-remote-modify.c:84
msgid "A full-paragraph description for this remote"
msgstr "Uma descrição de parágrafo completo para este remoto"

#: app/flatpak-builtins-remote-add.c:80 app/flatpak-builtins-remote-modify.c:85
msgid "URL for a website for this remote"
msgstr "URL para um website para este remoto"

#: app/flatpak-builtins-remote-add.c:81 app/flatpak-builtins-remote-modify.c:86
msgid "URL for an icon for this remote"
msgstr "URL para um ícone para este remoto"

#: app/flatpak-builtins-remote-add.c:82 app/flatpak-builtins-remote-modify.c:87
msgid "Default branch to use for this remote"
msgstr "Ramo padrão para usar para este remoto"

#: app/flatpak-builtins-remote-add.c:84 app/flatpak-builtins-remote-modify.c:89
msgid "Import GPG key from FILE (- for stdin)"
msgstr "Importa uma chave GPG do ARQUIVO (- para stdin)"

#: app/flatpak-builtins-remote-add.c:85 app/flatpak-builtins-remote-modify.c:90
msgid "Load signatures from URL"
msgstr ""

#: app/flatpak-builtins-remote-add.c:86 app/flatpak-builtins-remote-modify.c:92
msgid "Set path to local filter FILE"
msgstr "Define o caminho para o filtro local ARQUIVO"

#: app/flatpak-builtins-remote-add.c:87 app/flatpak-builtins-remote-modify.c:93
msgid "Disable the remote"
msgstr "Desabilita o remoto"

#: app/flatpak-builtins-remote-add.c:88 app/flatpak-builtins-remote-modify.c:94
msgid "Name of authenticator"
msgstr "Nome do autenticador"

#: app/flatpak-builtins-remote-add.c:90 app/flatpak-builtins-remote-modify.c:96
msgid "Autoinstall authenticator"
msgstr "Instala automaticamente autenticador"

#: app/flatpak-builtins-remote-add.c:91 app/flatpak-builtins-remote-modify.c:97
msgid "Don't autoinstall authenticator"
msgstr "Não instala automaticamente autenticador"

#: app/flatpak-builtins-remote-add.c:92 app/flatpak-builtins-remote-modify.c:99
msgid "Don't follow the redirect set in the summary file"
msgstr "Não segue o redirecionamento definido no ficheiro de resumo"

#: app/flatpak-builtins-remote-add.c:261 app/flatpak-builtins-remote-add.c:268
#, c-format
msgid "Can't load uri %s: %s\n"
msgstr "Não foi possível carregar a uri %s: %s\n"

#: app/flatpak-builtins-remote-add.c:276 common/flatpak-dir.c:4643
#, c-format
msgid "Can't load file %s: %s\n"
msgstr "Não foi possível carregar o ficheiro %s: %s\n"

#: app/flatpak-builtins-remote-add.c:304
msgid "NAME LOCATION - Add a remote repository"
msgstr "NOME LOCALIZAÇÃO – Adiciona um repositório remoto"

#: app/flatpak-builtins-remote-add.c:331
msgid "GPG verification is required if collections are enabled"
msgstr "Verificação GPG é exigida se coleções estiverem habilitadas"

#: app/flatpak-builtins-remote-add.c:393
#, c-format
msgid "Remote %s already exists"
msgstr "O remoto %s já existe"

#: app/flatpak-builtins-remote-add.c:405
#: app/flatpak-builtins-remote-modify.c:340
#, c-format
msgid "Invalid authenticator name %s"
msgstr "Nome de autenticador inválido %s"

#: app/flatpak-builtins-remote-add.c:422
#, c-format
msgid "Warning: Could not update extra metadata for '%s': %s\n"
msgstr "Aviso: Não foi possível atualizar metadados extras para “%s”: %s\n"

#: app/flatpak-builtins-remote-delete.c:39
msgid "Remove remote even if in use"
msgstr "Remove remoto ainda que ele esteja em uso"

#: app/flatpak-builtins-remote-delete.c:53
msgid "NAME - Delete a remote repository"
msgstr "NOME – Elimina um repositório remoto"

#: app/flatpak-builtins-remote-delete.c:100
#, c-format
msgid "The following refs are installed from remote '%s':"
msgstr "As seguintes refs já estão instaladas do remoto “%s”:"

#: app/flatpak-builtins-remote-delete.c:101
msgid "Remove them?"
msgstr "Removê-las?"

#: app/flatpak-builtins-remote-delete.c:103
#, c-format
msgid "Can't remove remote '%s' with installed refs"
msgstr "Não é possível remover o remoto “%s” com refs instaladas"

#: app/flatpak-builtins-remote-info.c:55
msgid "Commit to show info for"
msgstr "Commit para mostrar informações"

#: app/flatpak-builtins-remote-info.c:58
msgid "Display log"
msgstr "Mostra o registo"

#: app/flatpak-builtins-remote-info.c:61
msgid "Show parent"
msgstr "Mostrar pasta principal"

#: app/flatpak-builtins-remote-info.c:65 app/flatpak-builtins-remote-ls.c:60
msgid "Use local caches even if they are stale"
msgstr "Usa caches locais mesmo se eles estiverem velhos"

#. Translators: A sideload is when you install from a local USB drive rather than the Internet.
#: app/flatpak-builtins-remote-info.c:67 app/flatpak-builtins-remote-ls.c:62
msgid "Only list refs available as sideloads"
msgstr "Lista apenas refs disponíveis como downloads locais"

#: app/flatpak-builtins-remote-info.c:114
msgid ""
" REMOTE REF - Show information about an application or runtime in a remote"
msgstr ""
" REMOTO REF – Mostra informações sobre uma aplicação ou runtime em um remoto"

#: app/flatpak-builtins-remote-info.c:125
msgid "REMOTE and REF must be specified"
msgstr "REMOTO e REF devem ser especificados"

#: app/flatpak-builtins-remote-info.c:247
#: app/flatpak-builtins-remote-info.c:282
#, fuzzy
msgid "Download Size:"
msgstr "Tamanho baixado:"

#: app/flatpak-builtins-remote-info.c:267
#: app/flatpak-builtins-remote-info.c:325
msgid "History:"
msgstr "Histórico:"

#: app/flatpak-builtins-remote-info.c:348
msgid " Commit:"
msgstr " Commit:"

#: app/flatpak-builtins-remote-info.c:349
msgid " Subject:"
msgstr " Assunto:"

#: app/flatpak-builtins-remote-info.c:350
msgid " Date:"
msgstr " Data:"

#: app/flatpak-builtins-remote-info.c:383
#, c-format
msgid "Warning: Commit %s has no flatpak metadata\n"
msgstr "Aviso: O commit %s tem nenhum metadado de flatpak\n"

#: app/flatpak-builtins-remote-list.c:43
msgid "Show remote details"
msgstr "Mostra os detalhes do remoto"

#: app/flatpak-builtins-remote-list.c:44
msgid "Show disabled remotes"
msgstr "Mostra remotos desativados"

#: app/flatpak-builtins-remote-list.c:52
msgid "Title"
msgstr "Título"

#: app/flatpak-builtins-remote-list.c:52
msgid "Show the title"
msgstr "Mostra o título"

#: app/flatpak-builtins-remote-list.c:53
msgid "Show the URL"
msgstr "Mostra o URL"

#: app/flatpak-builtins-remote-list.c:54
msgid "Show the collection ID"
msgstr "Mostra o ID da coleção"

#: app/flatpak-builtins-remote-list.c:55 app/flatpak-builtins-repo.c:392
msgid "Subset"
msgstr "Subconjunto"

#: app/flatpak-builtins-remote-list.c:55
msgid "Show the subset"
msgstr "Mostra o subconjunto"

#: app/flatpak-builtins-remote-list.c:56
msgid "Filter"
msgstr "Filtro"

#: app/flatpak-builtins-remote-list.c:56
msgid "Show filter file"
msgstr "Mostra o ficheiro do filtro"

#: app/flatpak-builtins-remote-list.c:57
msgid "Priority"
msgstr "Prioridade"

#: app/flatpak-builtins-remote-list.c:57
msgid "Show the priority"
msgstr "Mostra a prioridade"

#: app/flatpak-builtins-remote-list.c:59
msgid "Comment"
msgstr "Comentário"

#: app/flatpak-builtins-remote-list.c:59
msgid "Show comment"
msgstr "Mostra comentário"

#: app/flatpak-builtins-remote-list.c:60
msgid "Show description"
msgstr "Mostra descrição"

#: app/flatpak-builtins-remote-list.c:61
msgid "Homepage"
msgstr "Página inicial"

#: app/flatpak-builtins-remote-list.c:61
msgid "Show homepage"
msgstr "Mostra página inicial"

#: app/flatpak-builtins-remote-list.c:62
msgid "Icon"
msgstr "Ícone"

#: app/flatpak-builtins-remote-list.c:62
msgid "Show icon"
msgstr "Mostra ícone"

#: app/flatpak-builtins-remote-list.c:231
msgid " - List remote repositories"
msgstr " – Lista repositórios remotos"

#: app/flatpak-builtins-remote-ls.c:52
msgid "Show arches and branches"
msgstr "Mostra arquiteturas e ramos"

#: app/flatpak-builtins-remote-ls.c:53
msgid "Show only runtimes"
msgstr "Mostra apenas runtimes"

#: app/flatpak-builtins-remote-ls.c:54
msgid "Show only apps"
msgstr "Mostra apenas aplicações"

#: app/flatpak-builtins-remote-ls.c:55
msgid "Show only those where updates are available"
msgstr "Mostra apenas aqueles com atualizações disponíveis"

#: app/flatpak-builtins-remote-ls.c:56
msgid "Limit to this arch (* for all)"
msgstr "Limita a essa arquitetura (* para todas)"

#: app/flatpak-builtins-remote-ls.c:77
msgid "Show the runtime"
msgstr "Mostra o runtime"

#: app/flatpak-builtins-remote-ls.c:79
msgid "Download size"
msgstr "Tamanho baixado"

#: app/flatpak-builtins-remote-ls.c:79
msgid "Show the download size"
msgstr "Mostra o tamanho baixado"

#: app/flatpak-builtins-remote-ls.c:391
msgid " [REMOTE or URI] - Show available runtimes and applications"
msgstr " [REMOTO ou URI] – Mostra runtimes e aplicações disponíveis"

#: app/flatpak-builtins-remote-modify.c:67
msgid "Enable GPG verification"
msgstr "Ativar verificação GPG"

#: app/flatpak-builtins-remote-modify.c:68
msgid "Mark the remote as enumerate"
msgstr "Marca o remoto como enumerado"

#: app/flatpak-builtins-remote-modify.c:69
msgid "Mark the remote as used for dependencies"
msgstr "Marca o repositório como usado para dependências"

#: app/flatpak-builtins-remote-modify.c:70
#, fuzzy
msgid "Set a new URL"
msgstr "Define um novo url"

#: app/flatpak-builtins-remote-modify.c:71
msgid "Set a new subset to use"
msgstr "Define um novo subconjunto para usar"

#: app/flatpak-builtins-remote-modify.c:72
msgid "Enable the remote"
msgstr "Habilita o remoto"

#: app/flatpak-builtins-remote-modify.c:73
msgid "Update extra metadata from the summary file"
msgstr "Atualiza metadados extras do ficheiro de resumo"

#: app/flatpak-builtins-remote-modify.c:91
msgid "Disable local filter"
msgstr "Desabilita o filtro local"

#: app/flatpak-builtins-remote-modify.c:95
msgid "Authenticator options"
msgstr "Opções do autenticador"

#: app/flatpak-builtins-remote-modify.c:98
msgid "Follow the redirect set in the summary file"
msgstr "Segue o redirecionamento definido no ficheiro de resumo"

#: app/flatpak-builtins-remote-modify.c:306
msgid "NAME - Modify a remote repository"
msgstr "NOME – Modifica um repositório remoto"

#: app/flatpak-builtins-remote-modify.c:316
msgid "Remote NAME must be specified"
msgstr "NOME remoto deve ser especificado"

#: app/flatpak-builtins-remote-modify.c:327
#, c-format
msgid "Updating extra metadata from remote summary for %s\n"
msgstr "A atualizar metadados extras para resumo de remoto para %s\n"

#: app/flatpak-builtins-remote-modify.c:330
#, c-format
msgid "Error updating extra metadata for '%s': %s\n"
msgstr "Erro ao atualizar metadados extras para “%s”: %s\n"

#: app/flatpak-builtins-remote-modify.c:331
#, c-format
msgid "Could not update extra metadata for %s"
msgstr "Não foi possível atualizar metadados extras para %s"

#: app/flatpak-builtins-repair.c:43
msgid "Don't make any changes"
msgstr "Não faz quaisquer alterações"

#: app/flatpak-builtins-repair.c:44
msgid "Reinstall all refs"
msgstr "Reinstala todas as refs"

#: app/flatpak-builtins-repair.c:68
#, c-format
msgid "Object missing: %s.%s\n"
msgstr "Faltando objeto: %s.%s\n"

#: app/flatpak-builtins-repair.c:76
#, c-format
msgid "Object invalid: %s.%s\n"
msgstr "Objeto inválido: %s.%s\n"

#: app/flatpak-builtins-repair.c:81
#, c-format
msgid "%s, deleting object\n"
msgstr "%s, a eliminar objeto\n"

#: app/flatpak-builtins-repair.c:146
#, c-format
msgid "Can't load object %s: %s\n"
msgstr "Não foi possível carregar o objeto %s: %s\n"

#: app/flatpak-builtins-repair.c:228
#, c-format
msgid "Commit invalid %s: %s\n"
msgstr "Commit inválido: %s: %s\n"

#: app/flatpak-builtins-repair.c:231
#, c-format
msgid "Deleting invalid commit %s: %s\n"
msgstr "A eliminar commit inválido %s: %s\n"

#: app/flatpak-builtins-repair.c:261
#, c-format
msgid "Commit should be marked partial: %s\n"
msgstr "O commit deve ser marcado como parcial: %s\n"

#: app/flatpak-builtins-repair.c:264
#, c-format
msgid "Marking commit as partial: %s\n"
msgstr "A marcar commit como parcial: %s\n"

#: app/flatpak-builtins-repair.c:293
#, c-format
msgid "Problems loading data for %s: %s\n"
msgstr "Problemas ao carregar dados para %s: %s\n"

#: app/flatpak-builtins-repair.c:306
#, c-format
msgid "Error reinstalling %s: %s\n"
msgstr "Erro ao reinstalar %s: %s\n"

#: app/flatpak-builtins-repair.c:327
msgid "- Repair a flatpak installation"
msgstr "– Corrige uma instalação do flatpak"

#: app/flatpak-builtins-repair.c:406
#, c-format
msgid "Removing non-deployed ref %s…\n"
msgstr "A remover ref não implantada %s…\n"

#: app/flatpak-builtins-repair.c:411
#, c-format
msgid "Skipping non-deployed ref %s…\n"
msgstr "A ignorar ref não implantada %s…\n"

#: app/flatpak-builtins-repair.c:429
#, c-format
msgid "[%d/%d] Verifying %s…\n"
msgstr "[%d/%d] A verificar %s…\n"

#: app/flatpak-builtins-repair.c:435
#, c-format
msgid "Dry run: "
msgstr "Simulação: "

#: app/flatpak-builtins-repair.c:440
#, c-format
msgid "Deleting ref %s due to missing objects\n"
msgstr "A eliminar ref %s por causa de objetos em falta\n"

#: app/flatpak-builtins-repair.c:444
#, c-format
msgid "Deleting ref %s due to invalid objects\n"
msgstr "A eliminar ref %s devido a objetos inválidos\n"

#: app/flatpak-builtins-repair.c:448
#, c-format
msgid "Deleting ref %s due to %d\n"
msgstr "A eliminar ref %s devido a %d\n"

#: app/flatpak-builtins-repair.c:464
#, c-format
msgid "Checking remotes...\n"
msgstr "A verificar remotos...\n"

#: app/flatpak-builtins-repair.c:482
#, c-format
msgid "Remote %s for ref %s is missing\n"
msgstr "O remoto %s para ref %s está em falta\n"

#: app/flatpak-builtins-repair.c:484
#, c-format
msgid "Remote %s for ref %s is disabled\n"
msgstr "O remoto %s para ref %s está desativado\n"

#: app/flatpak-builtins-repair.c:490
#, c-format
msgid "Pruning objects\n"
msgstr "A suprimir objetos\n"

#: app/flatpak-builtins-repair.c:498
#, c-format
msgid "Erasing .removed\n"
msgstr "A apagar .removed\n"

#: app/flatpak-builtins-repair.c:524
#, c-format
msgid "Reinstalling refs\n"
msgstr "A reinstalar refs\n"

#: app/flatpak-builtins-repair.c:526
#, c-format
msgid "Reinstalling removed refs\n"
msgstr "A reinstalar refs removidas\n"

#: app/flatpak-builtins-repair.c:551
#, c-format
msgid "While removing appstream for %s: "
msgstr "Ao remover appstream para %s: "

#: app/flatpak-builtins-repair.c:558
#, c-format
msgid "While deploying appstream for %s: "
msgstr "Ao implantar appstream para %s: "

#: app/flatpak-builtins-repo.c:106
#, c-format
msgid "Repo mode: %s\n"
msgstr "Modo repo: %s\n"

#: app/flatpak-builtins-repo.c:113
#, c-format
msgid "Indexed summaries: %s\n"
msgstr "Resumos indexados: %s\n"

#: app/flatpak-builtins-repo.c:113 app/flatpak-builtins-repo.c:139
#: app/flatpak-builtins-repo.c:172
msgid "true"
msgstr "verdadeiro"

#: app/flatpak-builtins-repo.c:113 app/flatpak-builtins-repo.c:139
#: app/flatpak-builtins-repo.c:172
msgid "false"
msgstr "falso"

#: app/flatpak-builtins-repo.c:121
#, c-format
msgid "Subsummaries: "
msgstr "Sub-resumos: "

#: app/flatpak-builtins-repo.c:136
#, c-format
msgid "Cache version: %d\n"
msgstr "Versão do cache: %d\n"

#: app/flatpak-builtins-repo.c:139
#, c-format
msgid "Indexed deltas: %s\n"
msgstr "Deltas indexados: %s\n"

#: app/flatpak-builtins-repo.c:142
#, c-format
msgid "Title: %s\n"
msgstr "Título: %s\n"

#: app/flatpak-builtins-repo.c:145
#, c-format
msgid "Comment: %s\n"
msgstr "Comentário: %s\n"

#: app/flatpak-builtins-repo.c:148
#, c-format
msgid "Description: %s\n"
msgstr "Descrição: %s\n"

#: app/flatpak-builtins-repo.c:151
#, c-format
msgid "Homepage: %s\n"
msgstr "Página inicial: %s\n"

#: app/flatpak-builtins-repo.c:154
#, c-format
msgid "Icon: %s\n"
msgstr "Ícone: %s\n"

#: app/flatpak-builtins-repo.c:157
#, c-format
msgid "Collection ID: %s\n"
msgstr "ID de coleção: %s\n"

#: app/flatpak-builtins-repo.c:160
#, c-format
msgid "Default branch: %s\n"
msgstr "Ramo padrão: %s\n"

#: app/flatpak-builtins-repo.c:163
#, c-format
msgid "Redirect URL: %s\n"
msgstr "URL de redirecionamento: %s\n"

#: app/flatpak-builtins-repo.c:166
#, c-format
msgid "Deploy collection ID: %s\n"
msgstr "ID de coleção de implementação: %s\n"

#: app/flatpak-builtins-repo.c:169
#, c-format
msgid "Authenticator name: %s\n"
msgstr "Nome do autenticador: %s\n"

#: app/flatpak-builtins-repo.c:172
#, c-format
msgid "Authenticator install: %s\n"
msgstr "Instalação do autenticador: %s\n"

#: app/flatpak-builtins-repo.c:180
#, c-format
msgid "GPG key hash: %s\n"
msgstr "Hash de chave GPG: %s\n"

#: app/flatpak-builtins-repo.c:184
#, c-format
msgid "%zd summary branches\n"
msgstr "%zd ramos de resumo\n"

#: app/flatpak-builtins-repo.c:336
msgid "Installed"
msgstr "Instalado"

#. Translators: Download is used here as a noun
#: app/flatpak-builtins-repo.c:338 app/flatpak-cli-transaction.c:1462
msgid "Download"
msgstr "Transferir"

#: app/flatpak-builtins-repo.c:339
msgid "Subsets"
msgstr "Subconjuntos"

#: app/flatpak-builtins-repo.c:393
msgid "Digest"
msgstr "Digest"

#: app/flatpak-builtins-repo.c:394
msgid "History length"
msgstr "Tamanho do histórico"

#: app/flatpak-builtins-repo.c:711
msgid "Print general information about the repository"
msgstr "Mostra informações gerais sobre um repositório"

#: app/flatpak-builtins-repo.c:712
msgid "List the branches in the repository"
msgstr "Lisa os ramos no repositório"

#: app/flatpak-builtins-repo.c:713
msgid "Print metadata for a branch"
msgstr "Mostra metadados para um ramo"

#: app/flatpak-builtins-repo.c:714
msgid "Show commits for a branch"
msgstr "Mostra commits para um ramo"

#: app/flatpak-builtins-repo.c:715
msgid "Print information about the repo subsets"
msgstr "Mostra informações sobre os subconjuntos de repo"

#: app/flatpak-builtins-repo.c:716
msgid "Limit information to subsets with this prefix"
msgstr "Limita as informações a subconjuntos com este prefixo"

#: app/flatpak-builtins-repo.c:732
msgid "LOCATION - Repository maintenance"
msgstr "LOCALIZAÇÃO – Manutenção de repositório"

#: app/flatpak-builtins-run.c:159
msgid "Command to run"
msgstr "Comando para executar"

#: app/flatpak-builtins-run.c:160
msgid "Directory to run the command in"
msgstr "Diretório para executar o comando"

#: app/flatpak-builtins-run.c:161
msgid "Branch to use"
msgstr "Ramo a usar"

#: app/flatpak-builtins-run.c:162
msgid "Use development runtime"
msgstr "Usa runtime de desenvolvimento"

#: app/flatpak-builtins-run.c:163
msgid "Runtime to use"
msgstr "Runtime a usar"

#: app/flatpak-builtins-run.c:164
msgid "Runtime version to use"
msgstr "Versão do runtime a usar"

#: app/flatpak-builtins-run.c:167
msgid "Log accessibility bus calls"
msgstr "Regista as chamadas de barramento de acessibilidade"

#: app/flatpak-builtins-run.c:168
msgid "Don't proxy accessibility bus calls"
msgstr "Não intermedeia chamadas de barramento de acessibilidade"

#: app/flatpak-builtins-run.c:169
msgid "Proxy accessibility bus calls (default except when sandboxed)"
msgstr ""
"Intermedeia chamadas de barramento de acessibilidade (padrão, exceto quando "
"em uma caixa de proteção)"

#: app/flatpak-builtins-run.c:170
msgid "Don't proxy session bus calls"
msgstr "Não intermedeia chamadas de barramento de sessão"

#: app/flatpak-builtins-run.c:171
msgid "Proxy session bus calls (default except when sandboxed)"
msgstr ""
"Intermedeia chamadas de barramento de sessão (padrão, exceto quando em uma "
"caixa de proteção)"

#: app/flatpak-builtins-run.c:172
msgid "Don't start portals"
msgstr "Não inicia portais"

#: app/flatpak-builtins-run.c:173
msgid "Enable file forwarding"
msgstr "Ativar encaminhamento de ficheiro"

#: app/flatpak-builtins-run.c:174
msgid "Run specified commit"
msgstr "Executa o commit especificado"

#: app/flatpak-builtins-run.c:175
msgid "Use specified runtime commit"
msgstr "Usa o commit de runtime especificado"

#: app/flatpak-builtins-run.c:176
msgid "Run completely sandboxed"
msgstr "Executa totalmente em uma caixa de proteção"

#: app/flatpak-builtins-run.c:178
msgid "Use PID as parent pid for sharing namespaces"
msgstr "Usa PID como pid pai para compartilhamento de espaços de nome"

#: app/flatpak-builtins-run.c:179
msgid "Make processes visible in parent namespace"
msgstr "Torna os processos visíveis no espaço de nome pai"

#: app/flatpak-builtins-run.c:180
msgid "Share process ID namespace with parent"
msgstr "Partilha espaço de nome de ID de processo com principal"

#: app/flatpak-builtins-run.c:181
msgid "Write the instance ID to the given file descriptor"
msgstr "Escreve o ID de instância para o descritor de ficheiro dado"

#: app/flatpak-builtins-run.c:182
msgid "Use PATH instead of the app's /app"
msgstr "Usa PATH em vez do /app da aplicação"

#: app/flatpak-builtins-run.c:183
#, fuzzy
msgid "Use FD instead of the app's /app"
msgstr "Usa PATH em vez do /app da aplicação"

#: app/flatpak-builtins-run.c:183 app/flatpak-builtins-run.c:185
#: app/flatpak-builtins-run.c:187 app/flatpak-builtins-run.c:188
#: common/flatpak-context.c:2672
msgid "FD"
msgstr "FD"

#: app/flatpak-builtins-run.c:184
msgid "Use PATH instead of the runtime's /usr"
msgstr "Usa PATH em vez de /usr do runtime"

#: app/flatpak-builtins-run.c:185
#, fuzzy
msgid "Use FD instead of the runtime's /usr"
msgstr "Usa PATH em vez de /usr do runtime"

#: app/flatpak-builtins-run.c:186
#, fuzzy
msgid "Clear all outside environment variables"
msgstr "Define uma variável de ambiente"

#: app/flatpak-builtins-run.c:187
msgid ""
"Bind mount the file or directory referred to by FD to its canonicalized path"
msgstr ""

#: app/flatpak-builtins-run.c:188
msgid ""
"Bind mount the file or directory referred to by FD read-only to its "
"canonicalized path"
msgstr ""

#: app/flatpak-builtins-run.c:219
msgid "APP [ARGUMENT…] - Run an app"
msgstr "APLICAÇÃO [ARGUMENTO…] – Executa umA APLICAÇÃO"

#: app/flatpak-builtins-run.c:370
#, c-format
msgid "runtime/%s/%s/%s not installed"
msgstr "runtime/%s/%s/%s não instalado"

#: app/flatpak-builtins-run.c:419
msgid "app-fd and app-path cannot both be used"
msgstr ""

#: app/flatpak-builtins-run.c:449
msgid "usr-fd and usr-path cannot both be used"
msgstr ""

#: app/flatpak-builtins-search.c:37
msgid "Arch to search for"
msgstr "Arquitetura para pesquisar por"

#: app/flatpak-builtins-search.c:49
msgid "Remotes"
msgstr "Remotos"

#: app/flatpak-builtins-search.c:49
msgid "Show the remotes"
msgstr "Mostra os remotos"

#: app/flatpak-builtins-search.c:244
msgid "TEXT - Search remote apps/runtimes for text"
msgstr "TEXTO – Pesquisa aplicações/runtimes remotos para texto"

#: app/flatpak-builtins-search.c:255
msgid "TEXT must be specified"
msgstr "TEXTO deve ser especificado"

#: app/flatpak-builtins-search.c:338
msgid "No matches found"
msgstr "Nenhuma correspondência localizada"

#: app/flatpak-builtins-uninstall.c:54
msgid "Arch to uninstall"
msgstr "Arquitetura para desinstalar"

#: app/flatpak-builtins-uninstall.c:55
msgid "Keep ref in local repository"
msgstr "Mantém a ref no repositório local"

#: app/flatpak-builtins-uninstall.c:56
msgid "Don't uninstall related refs"
msgstr "Não desinstala as refs relacionadas"

#: app/flatpak-builtins-uninstall.c:57
msgid "Remove files even if running"
msgstr "Remove os ficheiros ainda que estejam em execução"

#: app/flatpak-builtins-uninstall.c:60
msgid "Uninstall all"
msgstr "Desinstala todos"

#: app/flatpak-builtins-uninstall.c:61
msgid "Uninstall unused"
msgstr "Desinstala não usados"

#: app/flatpak-builtins-uninstall.c:62
msgid "Delete app data"
msgstr "Elimina dados da aplicação"

#: app/flatpak-builtins-uninstall.c:141
#, c-format
msgid "Delete data for %s?"
msgstr "Eliminar dados para %s?"

#: app/flatpak-builtins-uninstall.c:220
#, c-format
msgid "Info: applications using the extension %s%s%s branch %s%s%s:\n"
msgstr ""

#: app/flatpak-builtins-uninstall.c:223
#, fuzzy, c-format
msgid "Info: applications using the runtime %s%s%s branch %s%s%s:\n"
msgstr "Aplicações que usam este runtime:\n"

#: app/flatpak-builtins-uninstall.c:238
#, fuzzy
msgid "Really remove?"
msgstr "Remoto"

#: app/flatpak-builtins-uninstall.c:255
#, fuzzy
msgid "[REF…] - Uninstall applications or runtimes"
msgstr "[REF…] – Atualiza aplicações ou runtimes"

#: app/flatpak-builtins-uninstall.c:264
msgid "Must specify at least one REF, --unused, --all or --delete-data"
msgstr "Deve especificar pelo menos uma REF, --unused, --all ou --delete-data"

#: app/flatpak-builtins-uninstall.c:267
msgid "Must not specify REFs when using --all"
msgstr "Não pode especificar REFs ao usar --all"

#: app/flatpak-builtins-uninstall.c:270
msgid "Must not specify REFs when using --unused"
msgstr "Não pode especificar REFs ao usar --unused"

#: app/flatpak-builtins-uninstall.c:336
#, c-format
msgid ""
"\n"
"These runtimes in installation '%s' are pinned and won't be removed; see "
"flatpak-pin(1):\n"
msgstr ""
"\n"
"Estes runtimes na instalação “%s” são fixados e não serão removidos; veja "
"flatpak-pin(1):\n"

#: app/flatpak-builtins-uninstall.c:370
#, c-format
msgid "Nothing unused to uninstall\n"
msgstr "Nada não usado para desinstalar\n"

#: app/flatpak-builtins-uninstall.c:444
#, fuzzy, c-format
msgid "No installed refs found for ‘%s’"
msgstr "Refs instaladas similares localizadas para “%s”:"

#: app/flatpak-builtins-uninstall.c:447
#, c-format
msgid " with arch ‘%s’"
msgstr ""

#: app/flatpak-builtins-uninstall.c:449
#, c-format
msgid " with branch ‘%s’"
msgstr ""

#: app/flatpak-builtins-uninstall.c:456
#, c-format
msgid "Warning: %s is not installed\n"
msgstr "Aviso: %s não está instalado\n"

#: app/flatpak-builtins-uninstall.c:490
#, c-format
msgid "None of the specified refs are installed"
msgstr ""

#: app/flatpak-builtins-uninstall.c:599
#, c-format
msgid "No app data to delete\n"
msgstr ""

#: app/flatpak-builtins-update.c:56
msgid "Arch to update for"
msgstr "Arquitetura para a qual será atualizada"

#: app/flatpak-builtins-update.c:57
msgid "Commit to deploy"
msgstr "Commit para implementar"

#: app/flatpak-builtins-update.c:58
msgid "Remove old files even if running"
msgstr "Remove ficheiros antigos ainda que estejam em execução"

#: app/flatpak-builtins-update.c:59
msgid "Don't pull, only update from local cache"
msgstr "Não faz pull, apenas atualiza do cache local"

#: app/flatpak-builtins-update.c:61
msgid "Don't update related refs"
msgstr "Não atualiza as refs relacionadas"

#: app/flatpak-builtins-update.c:66
msgid "Update appstream for remote"
msgstr "Atualiza appstream para remoto"

#: app/flatpak-builtins-update.c:67
msgid "Only update this subpath"
msgstr "Atualiza apenas este subcaminho"

#: app/flatpak-builtins-update.c:90
msgid "[REF…] - Update applications or runtimes"
msgstr "[REF…] – Atualiza aplicações ou runtimes"

#: app/flatpak-builtins-update.c:121
msgid "With --commit, only one REF may be specified"
msgstr "Com --commit, apenas um REF pode ser especificado"

#: app/flatpak-builtins-update.c:162
#, c-format
msgid "Looking for updates…\n"
msgstr "A procurar por atualizações…\n"

#: app/flatpak-builtins-update.c:215
#, c-format
msgid "Unable to update %s: %s\n"
msgstr "Não foi possível atualizar %s: %s\n"

#: app/flatpak-builtins-update.c:274
#, fuzzy, c-format
msgid "Nothing to update.\n"
msgstr "Nada para fazer.\n"

#: app/flatpak-builtins-utils.c:337
#, fuzzy, c-format
msgid ""
"Remote ‘%s’ found in multiple installations, unable to proceed in non-"
"interactive mode"
msgstr ""
"Ref “%s” localizada em várias instalações: %s. Você deve especificar uma."

#: app/flatpak-builtins-utils.c:346
#, c-format
msgid "Remote ‘%s’ found in multiple installations:"
msgstr "O remoto “%s” foi localizado em várias instalações:"

#: app/flatpak-builtins-utils.c:347 app/flatpak-builtins-utils.c:442
#: app/flatpak-builtins-utils.c:538 app/flatpak-builtins-utils.c:540
#: app/flatpak-builtins-utils.c:598
msgid "Which do you want to use (0 to abort)?"
msgstr "Qual QUER usar (0 para abortar)?"

#: app/flatpak-builtins-utils.c:349
#, c-format
msgid "No remote chosen to resolve ‘%s’ which exists in multiple installations"
msgstr ""
"Nenhum remoto escolhido para resolver “%s” que existe em várias instalações"

#: app/flatpak-builtins-utils.c:358
#, c-format
msgid ""
"Remote \"%s\" not found\n"
"Hint: Use flatpak remote-add to add a remote"
msgstr ""
"Remoto “%s” não localizado\n"
"Dica: Use flatpak remote-add para adicionar um remoto"

#: app/flatpak-builtins-utils.c:364
#, c-format
msgid "Remote \"%s\" not found in the %s installation"
msgstr "Remoto “%s” não localizado na instalação %s"

#: app/flatpak-builtins-utils.c:404
#, c-format
msgid "Multiple refs match ‘%s’, unable to proceed in non-interactive mode"
msgstr ""

#. default to yes on Enter
#: app/flatpak-builtins-utils.c:430
#, c-format
msgid ""
"Found ref ‘%s’ in remote ‘%s’ (%s).\n"
"Use this ref?"
msgstr ""
"Localizada ref “%s” em remoto “%s” (%s).\n"
"Usar essa ref?"

#: app/flatpak-builtins-utils.c:434 app/flatpak-builtins-utils.c:444
#: app/flatpak-builtins-utils.c:522 app/flatpak-builtins-utils.c:543
#, c-format
msgid "No ref chosen to resolve matches for ‘%s’"
msgstr "Nenhuma ref escolhida para resolver ocorrências para “%s”"

#: app/flatpak-builtins-utils.c:440
#, c-format
msgid "Similar refs found for ‘%s’ in remote ‘%s’ (%s):"
msgstr "Refs similares localizadas para “%s” no remoto “%s” (%s):"

#: app/flatpak-builtins-utils.c:488
#, c-format
msgid ""
"Multiple installed refs match ‘%s’, unable to proceed in non-interactive mode"
msgstr ""

#. default to yes on Enter
#: app/flatpak-builtins-utils.c:518
#, c-format
msgid "Found installed ref ‘%s’ (%s). Is this correct?"
msgstr "Localizada ref instalada “%s” (%s). Isso está correto?"

#: app/flatpak-builtins-utils.c:534
#, c-format
msgid "All of the above"
msgstr "Todas acima"

#: app/flatpak-builtins-utils.c:535
#, c-format
msgid "Similar installed refs found for ‘%s’:"
msgstr "Refs instaladas similares localizadas para “%s”:"

#: app/flatpak-builtins-utils.c:579
#, c-format
msgid ""
"Multiple remotes have refs matching ‘%s’, unable to proceed in non-"
"interactive mode"
msgstr ""

#: app/flatpak-builtins-utils.c:597
#, c-format
msgid "Remotes found with refs similar to ‘%s’:"
msgstr "Remotos localizados com refs similares a “%s”:"

#: app/flatpak-builtins-utils.c:600
#, c-format
msgid "No remote chosen to resolve matches for ‘%s’"
msgstr "Nenhum remoto escolhido para resolver ocorrências para “%s”"

#: app/flatpak-builtins-utils.c:696 app/flatpak-builtins-utils.c:699
#, c-format
msgid "Updating appstream data for user remote %s"
msgstr "A atualizar dados de appstream para remoto %s de utilizador"

#: app/flatpak-builtins-utils.c:706 app/flatpak-builtins-utils.c:709
#, c-format
msgid "Updating appstream data for remote %s"
msgstr "A atualizar dados de appstream para remoto %s"

#: app/flatpak-builtins-utils.c:717 app/flatpak-builtins-utils.c:719
msgid "Error updating"
msgstr "Erro ao atualizar"

#: app/flatpak-builtins-utils.c:755
#, c-format
msgid "Remote \"%s\" not found"
msgstr "Remoto “%s” não localizado"

#: app/flatpak-builtins-utils.c:796
#, c-format
msgid "Ambiguous suffix: '%s'."
msgstr "Sufixo ambíguo: “%s”."

#. Translators: don't translate the values
#: app/flatpak-builtins-utils.c:798 app/flatpak-builtins-utils.c:813
msgid "Possible values are :s[tart], :m[iddle], :e[nd] or :f[ull]"
msgstr "Valores possíveis são :s[tart], :m[iddle], :e[nd] or :f[ull]"

#: app/flatpak-builtins-utils.c:811
#, c-format
msgid "Invalid suffix: '%s'."
msgstr "Sufixo inválido: “%s”."

#: app/flatpak-builtins-utils.c:846
#, c-format
msgid "Ambiguous column: %s"
msgstr "Coluna ambígua: %s"

#: app/flatpak-builtins-utils.c:859
#, c-format
msgid "Unknown column: %s"
msgstr "Coluna desconhecida: %s"

#: app/flatpak-builtins-utils.c:917
msgid "Available columns:\n"
msgstr "Colunas disponíveis:\n"

#: app/flatpak-builtins-utils.c:927
msgid "Show all columns"
msgstr "Mostra todas as colunas"

#: app/flatpak-builtins-utils.c:928
msgid "Show available columns"
msgstr "Mostra colunas disponíveis"

#: app/flatpak-builtins-utils.c:931
msgid "Append :s[tart], :m[iddle], :e[nd] or :f[ull] to change ellipsization"
msgstr ""
"Anexe :s[tart], :m[iddle], :e[nd] or :f[ull] para alterar como reticências "
"são aplicadas"

#: app/flatpak-builtins-utils.c:1483
#, c-format
msgid "Unknown scheme in sideload location %s"
msgstr ""

#: app/flatpak-cli-transaction.c:96 app/flatpak-cli-transaction.c:102
#, c-format
msgid "Required runtime for %s (%s) found in remote %s\n"
msgstr "Runtime exigido para %s (%s) localizado no remoto %s\n"

#: app/flatpak-cli-transaction.c:104
msgid "Do you want to install it?"
msgstr "Quer instalá-lo?"

#: app/flatpak-cli-transaction.c:110
#, c-format
msgid "Required runtime for %s (%s) found in remotes:"
msgstr "Runtime exigido para %s (%s) localizado em remotos:"

#: app/flatpak-cli-transaction.c:112
msgid "Which do you want to install (0 to abort)?"
msgstr "Qual quer instalar (0 para abortar)?"

#: app/flatpak-cli-transaction.c:132
#, c-format
msgid "Configuring %s as new remote '%s'\n"
msgstr "Configurando %s como novo remoto “%s”\n"

#. default to yes on Enter
#: app/flatpak-cli-transaction.c:139
#, c-format
msgid ""
"The remote '%s', referred to by '%s' at location %s contains additional "
"applications.\n"
"Should the remote be kept for future installations?"
msgstr ""
"O remoto “%s”, referido por “%s” na localização %s contém aplicações "
"adicionais.\n"
"O remoto deve ser mantido para instalações futuras?"

#. default to yes on Enter
#: app/flatpak-cli-transaction.c:147
#, c-format
msgid ""
"The application %s depends on runtimes from:\n"
"  %s\n"
"Configure this as new remote '%s'"
msgstr ""
"A aplicação %s depende de runtimes de:\n"
"  %s\n"
"Configure este como o novo remoto “%s”"

#. Formatted size/remaining time in seconds
#: app/flatpak-cli-transaction.c:321
#, c-format
msgid "%s/s%s%s"
msgstr ""

#. Download progress percentage, use the appropriate
#. percent format for your language
#: app/flatpak-cli-transaction.c:359
#, c-format
msgid "%3d%%"
msgstr ""

#: app/flatpak-cli-transaction.c:414
msgid "Installing…"
msgstr "Instalando…"

#: app/flatpak-cli-transaction.c:416
#, c-format
msgid "Installing %d/%d…"
msgstr "A instalar %d/%d…"

#: app/flatpak-cli-transaction.c:421
msgid "Updating…"
msgstr "A atualizar…"

#: app/flatpak-cli-transaction.c:423
#, c-format
msgid "Updating %d/%d…"
msgstr "A atualizar %d/%d…"

#: app/flatpak-cli-transaction.c:428
msgid "Uninstalling…"
msgstr "A desinstalar…"

#: app/flatpak-cli-transaction.c:430
#, c-format
msgid "Uninstalling %d/%d…"
msgstr "A desinstalar %d/%d…"

#: app/flatpak-cli-transaction.c:496 app/flatpak-quiet-transaction.c:161
#, c-format
msgid "Info: %s was skipped"
msgstr "Info: %s foi ignorado"

#: app/flatpak-cli-transaction.c:519
#, fuzzy, c-format
msgid "Warning: %s%s%s already installed"
msgstr "%s já instalado"

#: app/flatpak-cli-transaction.c:522
#, fuzzy, c-format
msgid "Error: %s%s%s already installed"
msgstr "%s já instalado"

#: app/flatpak-cli-transaction.c:528
#, fuzzy, c-format
msgid "Warning: %s%s%s not installed"
msgstr "Aviso: %s não está instalado\n"

#: app/flatpak-cli-transaction.c:531
#, fuzzy, c-format
msgid "Error: %s%s%s not installed"
msgstr "%s/%s/%s não instalado"

#: app/flatpak-cli-transaction.c:537
#, fuzzy, c-format
msgid "Warning: %s%s%s needs a later flatpak version"
msgstr "%s precisa de uma versão posterior do flatpak"

#: app/flatpak-cli-transaction.c:540
#, fuzzy, c-format
msgid "Error: %s%s%s needs a later flatpak version"
msgstr "%s precisa de uma versão posterior do flatpak"

#: app/flatpak-cli-transaction.c:546
#, fuzzy
msgid "Warning: Not enough disk space to complete this operation"
msgstr "Espaço em disco insuficiente para concluir esta operação"

#: app/flatpak-cli-transaction.c:548
#, fuzzy
msgid "Error: Not enough disk space to complete this operation"
msgstr "Espaço em disco insuficiente para concluir esta operação"

#: app/flatpak-cli-transaction.c:553
#, fuzzy, c-format
msgid "Warning: %s"
msgstr "Aviso: "

#: app/flatpak-cli-transaction.c:555
#, fuzzy, c-format
msgid "Error: %s"
msgstr "Erro:"

#: app/flatpak-cli-transaction.c:570
#, fuzzy, c-format
msgid "Failed to install %s%s%s: "
msgstr "Falha ao desinstalar %s para realizar rebase de %s: "

#: app/flatpak-cli-transaction.c:577
#, fuzzy, c-format
msgid "Failed to update %s%s%s: "
msgstr "Falha ao %s %s: "

#: app/flatpak-cli-transaction.c:584
#, fuzzy, c-format
msgid "Failed to install bundle %s%s%s: "
msgstr "Falha ao desinstalar %s para realizar rebase de %s: "

#: app/flatpak-cli-transaction.c:591
#, fuzzy, c-format
msgid "Failed to uninstall %s%s%s: "
msgstr "Falha ao desinstalar %s para realizar rebase de %s: "

#: app/flatpak-cli-transaction.c:642
#, c-format
msgid "Authentication required for remote '%s'\n"
msgstr "Autenticação necessária para remoto “%s”\n"

#: app/flatpak-cli-transaction.c:643
msgid "Open browser?"
msgstr "Abrir navegador?"

#: app/flatpak-cli-transaction.c:699
#, c-format
msgid "Login required remote %s (realm %s)\n"
msgstr "A autenticação exigiu o remoto %s (domínio %s)\n"

#: app/flatpak-cli-transaction.c:704
msgid "Password"
msgstr "Palavra-passe"

#. Only runtimes can be pinned
#: app/flatpak-cli-transaction.c:759
#, fuzzy, c-format
msgid ""
"\n"
"Info: (pinned) runtime %s%s%s branch %s%s%s is end-of-life, in favor of "
"%s%s%s branch %s%s%s\n"
msgstr "Info: (afixado) %s//%s está em fim de suporte, em favor de %s\n"

#: app/flatpak-cli-transaction.c:765
#, fuzzy, c-format
msgid ""
"\n"
"Info: runtime %s%s%s branch %s%s%s is end-of-life, in favor of %s%s%s branch "
"%s%s%s\n"
msgstr "Info: %s//%s está em fim de vida, em favor de %s\n"

#: app/flatpak-cli-transaction.c:768
#, fuzzy, c-format
msgid ""
"\n"
"Info: app %s%s%s branch %s%s%s is end-of-life, in favor of %s%s%s branch "
"%s%s%s\n"
msgstr "Info: %s//%s está em fim de vida, em favor de %s\n"

#. Only runtimes can be pinned
#: app/flatpak-cli-transaction.c:780
#, fuzzy, c-format
msgid ""
"\n"
"Info: (pinned) runtime %s%s%s branch %s%s%s is end-of-life, with reason:\n"
msgstr "Info: (fixado) %s//%s está em fim de vida, com motivo:\n"

#: app/flatpak-cli-transaction.c:786
#, fuzzy, c-format
msgid ""
"\n"
"Info: runtime %s%s%s branch %s%s%s is end-of-life, with reason:\n"
msgstr "Info: %s//%s está em fim de suporte, com motivo:\n"

#: app/flatpak-cli-transaction.c:789
#, fuzzy, c-format
msgid ""
"\n"
"Info: app %s%s%s branch %s%s%s is end-of-life, with reason:\n"
msgstr "Info: %s//%s está em fim de suporte, com motivo:\n"

#: app/flatpak-cli-transaction.c:963
#, fuzzy, c-format
msgid "Info: applications using this extension:\n"
msgstr "Aplicações que usam este runtime:\n"

#: app/flatpak-cli-transaction.c:965
#, fuzzy, c-format
msgid "Info: applications using this runtime:\n"
msgstr "Aplicações que usam este runtime:\n"

#: app/flatpak-cli-transaction.c:984
msgid "Replace?"
msgstr ""

#: app/flatpak-cli-transaction.c:987 app/flatpak-quiet-transaction.c:247
#, c-format
msgid "Updating to rebased version\n"
msgstr "A atualizar para a versão após rebase\n"

#: app/flatpak-cli-transaction.c:1011
#, c-format
msgid "Failed to rebase %s to %s: "
msgstr "Falha ao realizar rebase de %s para %s: "

#: app/flatpak-cli-transaction.c:1277
#, fuzzy, c-format
msgid "New %s%s%s permissions:"
msgstr "Novas %s permissões:"

#: app/flatpak-cli-transaction.c:1279
#, fuzzy, c-format
msgid "%s%s%s permissions:"
msgstr "%s permissões:"

#: app/flatpak-cli-transaction.c:1343
msgid "Warning: "
msgstr "Aviso: "

#. translators: This is short for operation, the title of a one-char column
#: app/flatpak-cli-transaction.c:1442
msgid "Op"
msgstr "Op"

#. Avoid resizing the download column too much,
#. * by making the title as long as typical content
#.
#: app/flatpak-cli-transaction.c:1458 app/flatpak-cli-transaction.c:1503
msgid "partial"
msgstr "parcial"

#: app/flatpak-cli-transaction.c:1535
msgid "Proceed with these changes to the user installation?"
msgstr "Prosseguir com estas alterações para a instalação de utilizador?"

#: app/flatpak-cli-transaction.c:1537
msgid "Proceed with these changes to the system installation?"
msgstr "Prosseguir com essas alterações para a instalação da sistema?"

#: app/flatpak-cli-transaction.c:1539
#, c-format
msgid "Proceed with these changes to the %s?"
msgstr "Prosseguir com essas alterações ao %s?"

#: app/flatpak-cli-transaction.c:1711
msgid "Changes complete."
msgstr "Alterações concluídas."

#: app/flatpak-cli-transaction.c:1713
msgid "Uninstall complete."
msgstr "Desinstalação concluída."

#: app/flatpak-cli-transaction.c:1715
msgid "Installation complete."
msgstr "Instalação concluída."

#: app/flatpak-cli-transaction.c:1717
msgid "Updates complete."
msgstr "Atualização concluída."

#. For updates/!stop_on_first_error we already printed all errors so we make up
#. a different one.
#: app/flatpak-cli-transaction.c:1750
msgid "There were one or more errors"
msgstr "Houve um ou mais erros"

#. translators: please keep the leading space
#: app/flatpak-main.c:76
msgid " Manage installed applications and runtimes"
msgstr " Gestão de aplicações e runtimes instalados"

#: app/flatpak-main.c:77
msgid "Install an application or runtime"
msgstr "Instala uma aplicação ou runtime"

#: app/flatpak-main.c:78
msgid "Update an installed application or runtime"
msgstr "Atualiza uma aplicação ou runtime instalado"

#: app/flatpak-main.c:81
msgid "Uninstall an installed application or runtime"
msgstr "Desinstala uma aplicação ou runtime instalado"

#: app/flatpak-main.c:84
msgid "Mask out updates and automatic installation"
msgstr "Mascara atualizações e instalação automática"

#: app/flatpak-main.c:85
msgid "Pin a runtime to prevent automatic removal"
msgstr "Afixa um runtime para evitar remoção automática"

#: app/flatpak-main.c:86
msgid "List installed apps and/or runtimes"
msgstr "Lista aplicações e/ou runtimes instalados"

#: app/flatpak-main.c:87
msgid "Show info for installed app or runtime"
msgstr "Mostra informação da aplicação ou runtime instalado"

#: app/flatpak-main.c:88
msgid "Show history"
msgstr "Mostra histórico"

#: app/flatpak-main.c:89
msgid "Configure flatpak"
msgstr "Configura o flatpak"

#: app/flatpak-main.c:90
msgid "Repair flatpak installation"
msgstr "Corrige instalação do flatpak"

#: app/flatpak-main.c:91
msgid "Put applications or runtimes onto removable media"
msgstr "Coloca aplicações ou runtimes em suporte removível"

#: app/flatpak-main.c:92
msgid "Install flatpaks that are part of the operating system"
msgstr ""

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:95
msgid ""
"\n"
" Find applications and runtimes"
msgstr ""
"\n"
" Localiza aplicações e runtimes"

#: app/flatpak-main.c:96
msgid "Search for remote apps/runtimes"
msgstr "Pesquisa por aplicações/runtimes de remoto"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:99
msgid ""
"\n"
" Manage running applications"
msgstr ""
"\n"
" Gere execução de aplicações"

#: app/flatpak-main.c:100
msgid "Run an application"
msgstr "Executa uma aplicação"

#: app/flatpak-main.c:101
msgid "Override permissions for an application"
msgstr "Sobrepõe as permissões para uma aplicação"

#: app/flatpak-main.c:102
msgid "Specify default version to run"
msgstr "Especifica a versão padrão para executar"

#: app/flatpak-main.c:103
msgid "Enter the namespace of a running application"
msgstr "Insere o espaço de nome de uma aplicação em execução"

#: app/flatpak-main.c:104
msgid "Enumerate running applications"
msgstr "Enumera aplicações em execução"

#: app/flatpak-main.c:105
msgid "Stop a running application"
msgstr "Termina uma aplicação em execução"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:108
msgid ""
"\n"
" Manage file access"
msgstr ""
"\n"
" Gestão de acesso a ficheiros"

#: app/flatpak-main.c:109
msgid "List exported files"
msgstr "Lista ficheiros exportados"

#: app/flatpak-main.c:110
msgid "Grant an application access to a specific file"
msgstr "Concede a uma aplicação acesso a um ficheiro específico"

#: app/flatpak-main.c:111
msgid "Revoke access to a specific file"
msgstr "Revoga o acesso a um ficheiro específico"

#: app/flatpak-main.c:112
msgid "Show information about a specific file"
msgstr "Mostra informações sobre um ficheiro específico"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:116
msgid ""
"\n"
" Manage dynamic permissions"
msgstr ""
"\n"
" Mostra permissões dinâmicas"

#: app/flatpak-main.c:117
msgid "List permissions"
msgstr "Lista permissões"

#: app/flatpak-main.c:118
msgid "Remove item from permission store"
msgstr "Remove item para armazenamento de permissão"

#: app/flatpak-main.c:120
msgid "Set permissions"
msgstr "Define permissões"

#: app/flatpak-main.c:121
msgid "Show app permissions"
msgstr "Mostra permissões de aplicação"

#: app/flatpak-main.c:122
msgid "Reset app permissions"
msgstr "Redefine permissões de aplicação"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:125
msgid ""
"\n"
" Manage remote repositories"
msgstr ""
"\n"
" Gestão de repositórios remotos"

#: app/flatpak-main.c:126
msgid "List all configured remotes"
msgstr "Lista todos os remotos configurados"

#: app/flatpak-main.c:127
msgid "Add a new remote repository (by URL)"
msgstr "Adiciona um novo repositório remoto (via URL)"

#: app/flatpak-main.c:128
msgid "Modify properties of a configured remote"
msgstr "Modifica as propriedades de um remoto configurado"

#: app/flatpak-main.c:129
msgid "Delete a configured remote"
msgstr "Elimina um remoto configurado"

#: app/flatpak-main.c:131
msgid "List contents of a configured remote"
msgstr "Lista o conteúdo de um remoto configurado"

#: app/flatpak-main.c:132
msgid "Show information about a remote app or runtime"
msgstr "Mostra informação sobre uma aplicação ou runtime de remoto"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:135
msgid ""
"\n"
" Build applications"
msgstr ""
"\n"
" Compilação de aplicações"

#: app/flatpak-main.c:136
msgid "Initialize a directory for building"
msgstr "Inicializa um diretório para compilação"

#: app/flatpak-main.c:137
msgid "Run a build command inside the build dir"
msgstr "Executa um comando de compilar dentro do diretório de compilação"

#: app/flatpak-main.c:138
msgid "Finish a build dir for export"
msgstr "Finaliza um diretório de compilação para exportar"

#: app/flatpak-main.c:139
msgid "Export a build dir to a repository"
msgstr "Exporta um diretório de compilação para um repositório"

#: app/flatpak-main.c:140
msgid "Create a bundle file from a ref in a local repository"
msgstr "Cria um ficheiro de pacote a partir de um ref em um repositório local"

#: app/flatpak-main.c:141
msgid "Import a bundle file"
msgstr "Importa um ficheiro de pacote"

#: app/flatpak-main.c:142
msgid "Sign an application or runtime"
msgstr "Assina um aplicação ou runtime"

#: app/flatpak-main.c:143
msgid "Update the summary file in a repository"
msgstr "Atualiza o ficheiro de sumário num repositório"

#: app/flatpak-main.c:144
msgid "Create new commit based on existing ref"
msgstr "Cria um novo commit baseado numa ref existente"

#: app/flatpak-main.c:145
msgid "Show information about a repo"
msgstr "Mostra informações sobre um repo"

#: app/flatpak-main.c:162
msgid "Show debug information, -vv for more detail"
msgstr "Mostra informações de depuração, -vv para mais detalhes"

#: app/flatpak-main.c:163
msgid "Show OSTree debug information"
msgstr "Mostra informações de depuração do OSTree"

#: app/flatpak-main.c:169
msgid "Print version information and exit"
msgstr "Mostra informações sobre a versão e sai"

#: app/flatpak-main.c:170
msgid "Print default arch and exit"
msgstr "Mostra a arquitetura padrão e sai"

#: app/flatpak-main.c:171
msgid "Print supported arches and exit"
msgstr "Mostra arquiteturas para as quais há suporte e sai"

#: app/flatpak-main.c:172
msgid "Print active gl drivers and exit"
msgstr "Mostra drivers gl ativos e sai"

#: app/flatpak-main.c:173
msgid "Print paths for system installations and exit"
msgstr "Mostra caminhos para instalações do sistema e sai"

#: app/flatpak-main.c:174
msgid "Print the updated environment needed to run flatpaks"
msgstr "Mostra o ambiente atualizado necessário para executar flatpaks"

#: app/flatpak-main.c:175
msgid "Only include the system installation with --print-updated-env"
msgstr "Inclui apenas a instalação do sistema com --print-updated-env"

#: app/flatpak-main.c:180
msgid "Work on the user installation"
msgstr "Trabalha na instalação do utilizador"

#: app/flatpak-main.c:181
msgid "Work on the system-wide installation (default)"
msgstr "Trabalha na instalação do sistema (padrão)"

#: app/flatpak-main.c:182
msgid "Work on a non-default system-wide installation"
msgstr "Trabalha em uma instalação não padrão de sistema"

#: app/flatpak-main.c:212
msgid "Builtin Commands:"
msgstr "Comandos embutidos:"

#: app/flatpak-main.c:298
#, c-format
msgid ""
"Note that the directories %s are not in the search path set by the "
"XDG_DATA_DIRS environment variable, so applications installed by Flatpak may "
"not appear on your desktop until the session is restarted."
msgstr ""
"Note que os diretórios %s não estão no caminho de pesquisa definido pela "
"variável de ambiente XDG_DATA_DIRS, portanto, as aplicações instaladas pelo "
"Flatpak podem não aparecer na sua área de trabalho até que a sessão seja "
"reiniciada."

#: app/flatpak-main.c:312
#, c-format
msgid ""
"Note that the directory %s is not in the search path set by the "
"XDG_DATA_DIRS environment variable, so applications installed by Flatpak may "
"not appear on your desktop until the session is restarted."
msgstr ""
"Note que o diretório %s não está no caminho de pesquisa definido pela "
"variável de ambiente XDG_DATA_DIRS, portanto, as aplicações instaladas pelo "
"Flatpak podem não aparecer na sua área de trabalho até que a sessão seja "
"reiniciada."

#: app/flatpak-main.c:381
msgid ""
"Refusing to operate under sudo with --user. Omit sudo to operate on the user "
"installation, or use a root shell to operate on the root user's installation."
msgstr ""
"Recusando-se a operar com sudo do --utilizador. Retire o sudo para operar na "
"instalação do utilizador, ou use o shell como root para operar na instalação "
"do utilizador-root."

#: app/flatpak-main.c:453
msgid ""
"Multiple installations specified for a command that works on one installation"
msgstr ""
"Várias instalações especificadas para um comando que trabalha em uma "
"instalação"

#: app/flatpak-main.c:504 app/flatpak-main.c:697
#, c-format
msgid "See '%s --help'"
msgstr "Veja “%s --help”"

#: app/flatpak-main.c:706
#, c-format
msgid "'%s' is not a flatpak command. Did you mean '%s%s'?"
msgstr "'%s' não é um comando do flatpak. Quis dizer '%s%s'?"

#: app/flatpak-main.c:709
#, c-format
msgid "'%s' is not a flatpak command"
msgstr "“%s” não é um comando do flatpak"

#: app/flatpak-main.c:824
msgid "No command specified"
msgstr "Nenhum comando especificado"

#: app/flatpak-main.c:980
msgid "error:"
msgstr "erro:"

#: app/flatpak-quiet-transaction.c:77
#, c-format
msgid "Installing %s\n"
msgstr "A instalar %s\n"

#: app/flatpak-quiet-transaction.c:81
#, c-format
msgid "Updating %s\n"
msgstr "A atualizar %s\n"

#: app/flatpak-quiet-transaction.c:85
#, c-format
msgid "Uninstalling %s\n"
msgstr "A desinstalar %s\n"

#: app/flatpak-quiet-transaction.c:107
#, fuzzy, c-format
msgid "Warning: Failed to install %s: %s\n"
msgstr "Aviso: Falha ao %s %s: %s\n"

#: app/flatpak-quiet-transaction.c:110
#, fuzzy, c-format
msgid "Error: Failed to install %s: %s\n"
msgstr "Erro: Falha ao %s %s: %s\n"

#: app/flatpak-quiet-transaction.c:116
#, fuzzy, c-format
msgid "Warning: Failed to update %s: %s\n"
msgstr "Aviso: Falha ao %s %s: %s\n"

#: app/flatpak-quiet-transaction.c:119
#, fuzzy, c-format
msgid "Error: Failed to update %s: %s\n"
msgstr "Erro: Falha ao %s %s: %s\n"

#: app/flatpak-quiet-transaction.c:125
#, fuzzy, c-format
msgid "Warning: Failed to install bundle %s: %s\n"
msgstr "Aviso: Falha ao %s %s: %s\n"

#: app/flatpak-quiet-transaction.c:128
#, fuzzy, c-format
msgid "Error: Failed to install bundle %s: %s\n"
msgstr "Erro: Falha ao %s %s: %s\n"

#: app/flatpak-quiet-transaction.c:134
#, fuzzy, c-format
msgid "Warning: Failed to uninstall %s: %s\n"
msgstr "Aviso: Falha ao %s %s: %s\n"

#: app/flatpak-quiet-transaction.c:137
#, fuzzy, c-format
msgid "Error: Failed to uninstall %s: %s\n"
msgstr "Erro: Falha ao %s %s: %s\n"

#: app/flatpak-quiet-transaction.c:166 common/flatpak-dir.c:11475
#, c-format
msgid "%s already installed"
msgstr "%s já instalado"

#: app/flatpak-quiet-transaction.c:168 common/flatpak-dir.c:3622
#: common/flatpak-dir.c:4321 common/flatpak-dir.c:16968
#: common/flatpak-dir.c:17258 common/flatpak-dir-utils.c:166
#: common/flatpak-dir-utils.c:259 common/flatpak-transaction.c:2736
#: common/flatpak-transaction.c:2791
#, c-format
msgid "%s not installed"
msgstr "%s não instalado"

#: app/flatpak-quiet-transaction.c:170
#, c-format
msgid "%s needs a later flatpak version"
msgstr "%s precisa de uma versão posterior do flatpak"

#: app/flatpak-quiet-transaction.c:172
msgid "Not enough disk space to complete this operation"
msgstr "Espaço em disco insuficiente para concluir esta operação"

#: app/flatpak-quiet-transaction.c:239
#, c-format
msgid "Info: %s is end-of-life, in favor of %s\n"
msgstr "Info: %s está em fim de vida, em favor de %s\n"

#: app/flatpak-quiet-transaction.c:241
#, c-format
msgid "Info: %s is end-of-life, with reason: %s\n"
msgstr "Info: %s está em fim de vida, com motivo: %s\n"

#: app/flatpak-quiet-transaction.c:251
#, c-format
msgid "Failed to rebase %s to %s: %s\n"
msgstr "Falha ao realizar rebase de %s para %s: %s\n"

#: common/flatpak-auth.c:58
#, c-format
msgid "No authenticator configured for remote `%s`"
msgstr "Nenhum autenticador configurador para remoto “%s”"

#: common/flatpak-context.c:637 common/flatpak-context.c:649
#, fuzzy, c-format
msgid "Invalid permission syntax: %s"
msgstr "Nome de extensão inválido %s"

#: common/flatpak-context.c:1207
#, c-format
msgid "Unknown share type %s, valid types are: %s"
msgstr "Tipo de partilha desconhecida %s, tipos válidos são: %s"

#: common/flatpak-context.c:1228
#, c-format
msgid "Unknown policy type %s, valid types are: %s"
msgstr "Tipo de política desconhecida %s, tipos válidos são: %s"

#: common/flatpak-context.c:1266
#, c-format
msgid "Invalid dbus name %s"
msgstr "Nome de dbus inválido %s"

#: common/flatpak-context.c:1279
#, c-format
msgid "Unknown socket type %s, valid types are: %s"
msgstr "Tipo de socket desconhecido %s, tipos válidos são: %s"

#: common/flatpak-context.c:1294
#, c-format
msgid "Unknown device type %s, valid types are: %s"
msgstr "Tipo de dispositivo desconhecido %s, tipos válidos são: %s"

#: common/flatpak-context.c:1308
#, c-format
msgid "Unknown feature type %s, valid types are: %s"
msgstr "Tipo de recurso desconhecido %s, tipos válidos são: %s"

#: common/flatpak-context.c:1840
#, c-format
msgid "Filesystem location \"%s\" contains \"..\""
msgstr "A localização do sistema de ficheiros “%s” contém “..”"

#: common/flatpak-context.c:1882
#, c-format
msgid ""
"--filesystem=/ is not available, use --filesystem=host for a similar result"
msgstr ""
"--filesystem=/ não está disponível, use --filesystem=host para um resultado "
"similar"

#: common/flatpak-context.c:1916
#, fuzzy, c-format
msgid ""
"Unknown filesystem location %s, valid locations are: host, host-os, host-"
"etc, host-root, home, xdg-*[/…], ~/dir, /dir"
msgstr ""
"Localização de sistema de ficheiros desconhecida %s, localizações válidas "
"são: host, host-os, host-etc, home, xdg-*[/…], ~/dir, /dir"

#: common/flatpak-context.c:2015
#, fuzzy, c-format
msgid "Invalid syntax for %s: %s"
msgstr "Nome inválido %s: %s"

#: common/flatpak-context.c:2142
#, c-format
msgid "fallback-x11 can not be conditional"
msgstr ""

#: common/flatpak-context.c:2318
#, c-format
msgid "Invalid env format %s"
msgstr "Formato de env inválido %s"

#: common/flatpak-context.c:2399
#, c-format
msgid "Environment variable name must not contain '=': %s"
msgstr "O nome de variável de ambiente não pode conter “=”: %s"

#: common/flatpak-context.c:2527 common/flatpak-context.c:2535
#, c-format
msgid "--add-policy arguments must be in the form SUBSYSTEM.KEY=VALUE"
msgstr ""
"Os argumentos de --add-policy devem estar no formato SUBSISTEMA.CHAVE=VALOR"

#: common/flatpak-context.c:2542
#, c-format
msgid "--add-policy values can't start with \"!\""
msgstr "os valores de --add-policy não podem iniciar com “!”"

#: common/flatpak-context.c:2567 common/flatpak-context.c:2575
#, c-format
msgid "--remove-policy arguments must be in the form SUBSYSTEM.KEY=VALUE"
msgstr ""
"Os argumentos de --remove-policy devem estar no formato "
"SUBSISTEMA.CHAVE=VALOR"

#: common/flatpak-context.c:2582
#, c-format
msgid "--remove-policy values can't start with \"!\""
msgstr "Os valores de --remove-policy não podem iniciar com “!”"

#: common/flatpak-context.c:2657
msgid "Share with host"
msgstr "Partilha com o host"

#: common/flatpak-context.c:2657 common/flatpak-context.c:2658
msgid "SHARE"
msgstr "PARTILHA"

#: common/flatpak-context.c:2658
msgid "Unshare with host"
msgstr "Desfaz partilha com o host"

#: common/flatpak-context.c:2659
msgid "Require conditions to be met for a subsystem to get shared"
msgstr ""

#: common/flatpak-context.c:2659
msgid "SHARE:CONDITION"
msgstr ""

#: common/flatpak-context.c:2660
msgid "Expose socket to app"
msgstr "Expõe o socket para a aplicação"

#: common/flatpak-context.c:2660 common/flatpak-context.c:2661
msgid "SOCKET"
msgstr "SOCKET"

#: common/flatpak-context.c:2661
msgid "Don't expose socket to app"
msgstr "Não expõe o socket para a aplicação"

#: common/flatpak-context.c:2662
msgid "Require conditions to be met for a socket to get exposed"
msgstr ""

#: common/flatpak-context.c:2662
msgid "SOCKET:CONDITION"
msgstr ""

#: common/flatpak-context.c:2663
msgid "Expose device to app"
msgstr "Expõe o dispositivo para a aplicação"

#: common/flatpak-context.c:2663 common/flatpak-context.c:2664
msgid "DEVICE"
msgstr "DISPOSITIVO"

#: common/flatpak-context.c:2664
msgid "Don't expose device to app"
msgstr "Não expõe o dispositivo para a aplicação"

#: common/flatpak-context.c:2665
msgid "Require conditions to be met for a device to get exposed"
msgstr ""

#: common/flatpak-context.c:2665
msgid "DEVICE:CONDITION"
msgstr ""

#: common/flatpak-context.c:2666
msgid "Allow feature"
msgstr "Permite a funcionalidade"

#: common/flatpak-context.c:2666 common/flatpak-context.c:2667
msgid "FEATURE"
msgstr "FUNCIONALIDADE"

#: common/flatpak-context.c:2667
msgid "Don't allow feature"
msgstr "Não permite funcionalidade"

#: common/flatpak-context.c:2668
msgid "Require conditions to be met for a feature to get allowed"
msgstr ""

#: common/flatpak-context.c:2668
msgid "FEATURE:CONDITION"
msgstr ""

#: common/flatpak-context.c:2669
msgid "Expose filesystem to app (:ro for read-only)"
msgstr ""
"Expõe o sistema de ficheiros para a aplicação (:ro para apenas leitura)"

#: common/flatpak-context.c:2669
msgid "FILESYSTEM[:ro]"
msgstr "SISTEMA_DE_FICHEIROS[:ro]"

#: common/flatpak-context.c:2670
msgid "Don't expose filesystem to app"
msgstr "Não expõe o sistema de ficheiros para a aplicação"

#: common/flatpak-context.c:2670
msgid "FILESYSTEM"
msgstr "SISTEMA_DE_FICHEIROS"

#: common/flatpak-context.c:2671
msgid "Set environment variable"
msgstr "Define uma variável de ambiente"

#: common/flatpak-context.c:2671
msgid "VAR=VALUE"
msgstr "VAR=VALOR"

#: common/flatpak-context.c:2672
msgid "Read environment variables in env -0 format from FD"
msgstr "Lê as variáveis de ambiente no formato env -0 do FD"

#: common/flatpak-context.c:2673
msgid "Remove variable from environment"
msgstr "Remove a variável do ambiente"

#: common/flatpak-context.c:2673
msgid "VAR"
msgstr "VAR"

#: common/flatpak-context.c:2674
msgid "Allow app to own name on the session bus"
msgstr "Permite a aplicação ter um nome no barramento de sessão"

#: common/flatpak-context.c:2674 common/flatpak-context.c:2675
#: common/flatpak-context.c:2676 common/flatpak-context.c:2677
#: common/flatpak-context.c:2678 common/flatpak-context.c:2679
#: common/flatpak-context.c:2680
msgid "DBUS_NAME"
msgstr "NOME_DBUS"

#: common/flatpak-context.c:2675
msgid "Allow app to talk to name on the session bus"
msgstr "Permite a aplicação falar com um nome no barramento de sessão"

#: common/flatpak-context.c:2676
msgid "Don't allow app to talk to name on the session bus"
msgstr "Proíbe a aplicação de falar com um nome no barramento de sessão"

#: common/flatpak-context.c:2677
msgid "Allow app to own name on the system bus"
msgstr "Permite a aplicação ter um nome no barramento de sistema"

#: common/flatpak-context.c:2678
msgid "Allow app to talk to name on the system bus"
msgstr "Permite a aplicação falar com um nome no barramento de sistema"

#: common/flatpak-context.c:2679
msgid "Don't allow app to talk to name on the system bus"
msgstr "Proíbe a aplicação de falar com um nome no barramento de sistema"

#: common/flatpak-context.c:2680
#, fuzzy
msgid "Allow app to own name on the a11y bus"
msgstr "Permite a aplicação ter um nome no barramento de sistema"

#: common/flatpak-context.c:2681
msgid "Add generic policy option"
msgstr "Adiciona uma opção de política genérica"

#: common/flatpak-context.c:2681 common/flatpak-context.c:2682
msgid "SUBSYSTEM.KEY=VALUE"
msgstr "SUBSISTEMA.CHAVE=VALOR"

#: common/flatpak-context.c:2682
msgid "Remove generic policy option"
msgstr "Remove uma opção de política genérica"

#: common/flatpak-context.c:2683
msgid "Add USB device to enumerables"
msgstr ""

#: common/flatpak-context.c:2683 common/flatpak-context.c:2684
msgid "VENDOR_ID:PRODUCT_ID"
msgstr ""

#: common/flatpak-context.c:2684
msgid "Add USB device to hidden list"
msgstr ""

#: common/flatpak-context.c:2685
msgid "A list of USB devices that are enumerable"
msgstr ""

#: common/flatpak-context.c:2685
msgid "LIST"
msgstr ""

#: common/flatpak-context.c:2686
msgid "File containing a list of USB devices to make enumerable"
msgstr ""

#: common/flatpak-context.c:2686 common/flatpak-context.c:2687
msgid "FILENAME"
msgstr "ARQUIVO"

#: common/flatpak-context.c:2687
msgid "Persist home directory subpath"
msgstr "Persiste o subcaminho do diretório pessoal"

#. This is not needed/used anymore, so hidden, but we accept it for backwards compat
#: common/flatpak-context.c:2689
msgid "Don't require a running session (no cgroups creation)"
msgstr "Não exige uma sessão em execução (sem criação de cgroups)"

#: common/flatpak-context.c:3718
#, c-format
msgid "Not replacing \"%s\" with tmpfs: %s"
msgstr ""

#: common/flatpak-context.c:3726
#, c-format
msgid "Not sharing \"%s\" with sandbox: %s"
msgstr ""

#. Even if the error is one that we would normally silence, like
#. * the path not existing, it seems reasonable to make more of a fuss
#. * about the home directory not existing or otherwise being unusable,
#. * so this is intentionally not using cannot_export()
#: common/flatpak-context.c:3828
#, c-format
msgid "Not allowing home directory access: %s"
msgstr ""

#: common/flatpak-context.c:4062
#, fuzzy, c-format
msgid "Unable to provide a temporary home directory in the sandbox: %s"
msgstr "Não foi possível criar um diretório temporário em %s"

#: common/flatpak-dir.c:442
#, c-format
msgid "Configured collection ID ‘%s’ not in summary file"
msgstr "O ID de coleção “%s” configurado não está no ficheiro de resumo"

#: common/flatpak-dir.c:587
#, c-format
msgid "Unable to load summary from remote %s: %s"
msgstr "Não foi possível carregar resumo do remoto %s: %s"

#: common/flatpak-dir.c:764 common/flatpak-dir.c:800 common/flatpak-dir.c:906
#, c-format
msgid "No such ref '%s' in remote %s"
msgstr "Ref inexistente “%s” no remoto %s"

#: common/flatpak-dir.c:891 common/flatpak-dir.c:1051 common/flatpak-dir.c:1080
#: common/flatpak-dir.c:1092
#, fuzzy, c-format
msgid "No entry for %s in remote %s summary flatpak cache"
msgstr "Nenhuma entrada para %s no cache de flatpak do sumário do remoto '%s' "

#: common/flatpak-dir.c:1069
#, c-format
msgid "No summary or Flatpak cache available for remote %s"
msgstr "Nenhum sumário ou cache do Flatpak disponível para o remoto %s"

#: common/flatpak-dir.c:1097
#, c-format
msgid "Missing xa.data in summary for remote %s"
msgstr "Faltando xa.data no resumo para %s remoto"

#: common/flatpak-dir.c:1103 common/flatpak-dir.c:1546
#, c-format
msgid "Unsupported summary version %d for remote %s"
msgstr "Versão de resumo %d não suportada para %s remoto"

#: common/flatpak-dir.c:1200
msgid "Remote OCI index has no registry uri"
msgstr "Índice de OCI remoto tem nenhuma uri de registro"

#: common/flatpak-dir.c:1261
#, c-format
msgid "Couldn't find ref %s in remote %s"
msgstr "Não foi possível localizar o ref %s no remoto %s"

#: common/flatpak-dir.c:1288 common/flatpak-dir.c:1381
#, fuzzy, c-format
msgid "Commit has no requested ref ‘%s’ in ref binding metadata (found: ‘%s’)"
msgstr ""
"O commit não tem solicitação de ref “%s” nos metadados de associação de ref"

#: common/flatpak-dir.c:1413
#, c-format
msgid "Configured collection ID ‘%s’ not in binding metadata"
msgstr "O ID de coleção “%s” configurado não está nos metadados de associação"

#: common/flatpak-dir.c:1449 common/flatpak-dir.c:5645
#, c-format
msgid "Couldn't find latest checksum for ref %s in remote %s"
msgstr ""
"Não foi possível localizar a última soma de verificação para o ref %s no "
"remoto %s"

#: common/flatpak-dir.c:1516 common/flatpak-dir.c:1552
#, c-format
msgid "No entry for %s in remote %s summary flatpak sparse cache"
msgstr ""
"Nenhuma entrada para %s no cache esparso de flatpak do resumo do remoto %s"

#: common/flatpak-dir.c:2540
#, c-format
msgid "Commit metadata for %s not matching expected metadata"
msgstr "Metadados do commit para %s não correspondem aos metadados esperados"

#: common/flatpak-dir.c:2823
msgid "Unable to connect to system bus"
msgstr "Não foi possível conectar ao barramento de sistema"

#: common/flatpak-dir.c:3419
msgid "User installation"
msgstr "Instalação do utilizador"

#: common/flatpak-dir.c:3426
#, c-format
msgid "System (%s) installation"
msgstr "Instalação do sistema (%s)"

#: common/flatpak-dir.c:3472
#, c-format
msgid "No overrides found for %s"
msgstr "Nenhuma substituição localizada para %s"

#: common/flatpak-dir.c:3625
#, c-format
msgid "%s (commit %s) not installed"
msgstr "%s (commit %s) não instalado"

#: common/flatpak-dir.c:4650
#, c-format
msgid "Error parsing system flatpakrepo file for %s: %s"
msgstr "Erro ao analisar o ficheiro de flatpakrepo de sistema para %s: %s"

#: common/flatpak-dir.c:4735
#, c-format
msgid "While opening repository %s: "
msgstr "Ao abrir o repositório %s: "

#: common/flatpak-dir.c:5004
#, c-format
msgid "The config key %s is not set"
msgstr "A chave de configuração %s não está definida"

#: common/flatpak-dir.c:5140
#, c-format
msgid "No current %s pattern matching %s"
msgstr "Nenhum padrão %s atual correspondendo a %s"

#: common/flatpak-dir.c:5422
msgid "No appstream commit to deploy"
msgstr "Nenhum commit de appstream para implementar"

#: common/flatpak-dir.c:5941 common/flatpak-dir.c:7266
#: common/flatpak-dir.c:10881 common/flatpak-dir.c:11618
msgid "Can't pull from untrusted non-gpg verified remote"
msgstr "Não foi possível obter de remoto sem gpg verificada e não confiado"

#: common/flatpak-dir.c:6376 common/flatpak-dir.c:6591
msgid "Extra data not supported for non-gpg-verified local system installs"
msgstr ""
"Sem suporte a dados extras para instalações de sistema local sem gpg "
"verificada"

#: common/flatpak-dir.c:6415 common/flatpak-dir.c:6782
#, c-format
msgid "Invalid checksum for extra data uri %s"
msgstr "Soma de verificação inválida para uri dados extras %s"

#: common/flatpak-dir.c:6424
#, c-format
msgid "Empty name for extra data uri %s"
msgstr "Nome vazio para uri de dados extras %s"

#: common/flatpak-dir.c:6432
#, c-format
msgid "Unsupported extra data uri %s"
msgstr "Sem suporte à uri de dados extras %s"

#: common/flatpak-dir.c:6461
#, c-format
msgid "Failed to load local extra-data %s: %s"
msgstr "Falha ao carregar extra-data local %s: %s"

#: common/flatpak-dir.c:6469
#, c-format
msgid "Wrong size for extra-data %s"
msgstr "Tamanho inválido para extra-data %s"

#: common/flatpak-dir.c:6488
#, c-format
msgid "While downloading %s: "
msgstr "Enquanto baixava %s: "

#: common/flatpak-dir.c:6498
#, c-format
msgid "Wrong size for extra data %s"
msgstr "Tamanho inválido para dados extras %s"

#: common/flatpak-dir.c:6507
#, c-format
msgid "Invalid checksum for extra data %s"
msgstr "Checksum inválida para dados extras %s"

#: common/flatpak-dir.c:7096 common/flatpak-dir.c:7349
#, c-format
msgid "While pulling %s from remote %s: "
msgstr "Enquanto executava pull de %s a partir do remoto %s: "

#: common/flatpak-dir.c:7290 common/flatpak-repo-utils.c:3886
msgid "GPG signatures found, but none are in trusted keyring"
msgstr "Assinaturas GPG localizadas, mas nenhuma está no chaveiro de confiadas"

#: common/flatpak-dir.c:7307
#, c-format
msgid "Commit for ‘%s’ has no ref binding"
msgstr "O commit para “%s” tem nenhuma associação de ref"

#: common/flatpak-dir.c:7312
#, c-format
msgid "Commit for ‘%s’ is not in expected bound refs: %s"
msgstr "O commit para “%s” não está nos refs limites esperados: %s"

#: common/flatpak-dir.c:7488
msgid "Only applications can be made current"
msgstr "Apenas aplicações podem ser atualizados"

#: common/flatpak-dir.c:8192
msgid "Not enough memory"
msgstr "Memória insuficiente"

#: common/flatpak-dir.c:8211
msgid "Failed to read from exported file"
msgstr "Falha ao ler do ficheiro exportado"

#: common/flatpak-dir.c:8401
msgid "Error reading mimetype xml file"
msgstr "Erro ao ler o ficheiro xml de tipo mime"

#: common/flatpak-dir.c:8406
msgid "Invalid mimetype xml file"
msgstr "Ficheiro inválido de xml de tipo mim"

#: common/flatpak-dir.c:8492
#, c-format
msgid "D-Bus service file '%s' has wrong name"
msgstr "O ficheiro de serviço D-Bus “%s” tem um nome errado"

#: common/flatpak-dir.c:8647
#, c-format
msgid "Invalid Exec argument %s"
msgstr "Exec com argumento inválido %s"

#: common/flatpak-dir.c:9115
msgid "While getting detached metadata: "
msgstr "Enquanto obtinha metadados destacados: "

#: common/flatpak-dir.c:9120 common/flatpak-dir.c:9125
#: common/flatpak-dir.c:9129
msgid "Extra data missing in detached metadata"
msgstr "Dados extras em falta nos metadados destacados"

#: common/flatpak-dir.c:9133
msgid "While creating extradir: "
msgstr "Enquanto criava extradir: "

#: common/flatpak-dir.c:9154 common/flatpak-dir.c:9187
msgid "Invalid checksum for extra data"
msgstr "Soma de verificação inválida para dados extras"

#: common/flatpak-dir.c:9183
msgid "Wrong size for extra data"
msgstr "Tamanho inválido para dados extras"

#: common/flatpak-dir.c:9196
#, c-format
msgid "While writing extra data file '%s': "
msgstr "Enquanto escrevia o ficheiro de dados extras “%s”: "

#: common/flatpak-dir.c:9204
#, c-format
msgid "Extra data %s missing in detached metadata"
msgstr "Dados extras %s em falta nos metadados destacados"

#: common/flatpak-dir.c:9278
#, fuzzy, c-format
msgid "Unable to get runtime key from metadata"
msgstr "Usa um ficheiro alternativo para os metadados"

#: common/flatpak-dir.c:9402
#, c-format
msgid "apply_extra script failed, exit status %d"
msgstr "script apply_extra falhou, status de saída %d"

#. Translators: The placeholder is for an app ref.
#: common/flatpak-dir.c:9591
#, c-format
msgid "Installing %s is not allowed by the policy set by your administrator"
msgstr "Instalar %s não é permitido pela política definida pelo administrador"

#: common/flatpak-dir.c:9690
#, c-format
msgid "While trying to resolve ref %s: "
msgstr "Enquanto tentava resolver ref %s: "

#: common/flatpak-dir.c:9702
#, c-format
msgid "%s is not available"
msgstr "%s não está disponível"

#: common/flatpak-dir.c:9714 common/flatpak-dir.c:11495
#, c-format
msgid "%s commit %s already installed"
msgstr "%s commit %s já está instalado"

#: common/flatpak-dir.c:9721
msgid "Can't create deploy directory"
msgstr "Não foi possível criar um diretório de deploy"

#: common/flatpak-dir.c:9729
#, c-format
msgid "Failed to read commit %s: "
msgstr "Falha ao ler commit %s: "

#: common/flatpak-dir.c:9750
#, c-format
msgid "While trying to checkout %s into %s: "
msgstr "Enquanto tentava fazer checkout de %s para %s: "

#: common/flatpak-dir.c:9769
msgid "While trying to checkout metadata subpath: "
msgstr "Enquanto tentava fazer checkout do subcaminho de metadados: "

#: common/flatpak-dir.c:9801
#, c-format
msgid "While trying to checkout subpath ‘%s’: "
msgstr "Enquanto tentava fazer checkout do subcaminho “%s”: "

#: common/flatpak-dir.c:9811
msgid "While trying to remove existing extra dir: "
msgstr "Enquanto tentava remover diretório extra existente: "

#: common/flatpak-dir.c:9822
msgid "While trying to apply extra data: "
msgstr "Enquanto tentava aplicar dados extras: "

#: common/flatpak-dir.c:9849
#, c-format
msgid "Invalid commit ref %s: "
msgstr "Ref de commit inválido %s: "

#: common/flatpak-dir.c:9857 common/flatpak-dir.c:9869
#, c-format
msgid "Deployed ref %s does not match commit (%s)"
msgstr "Ref implementado %s não coincide com o commit (%s)"

#: common/flatpak-dir.c:9863
#, c-format
msgid "Deployed ref %s branch does not match commit (%s)"
msgstr "O ramo do ref implementado %s não coincide com o commit (%s)"

#: common/flatpak-dir.c:10125 common/flatpak-installation.c:1911
#, c-format
msgid "%s branch %s already installed"
msgstr "%s ramo %s já está instalado"

#: common/flatpak-dir.c:10985
#, c-format
msgid "Could not unmount revokefs-fuse filesystem at %s: "
msgstr ""
"Não foi possível desmontar o sistema de ficheiros revokefs-fuse em %s: "

#: common/flatpak-dir.c:11289
#, c-format
msgid "This version of %s is already installed"
msgstr "Essa versão de %s já está instalada"

#: common/flatpak-dir.c:11302
#, c-format
msgid "Can't change remote during bundle install"
msgstr "Não é possível alterar remoto durante instalação de pacote"

#: common/flatpak-dir.c:11571
msgid "Can't update to a specific commit without root permissions"
msgstr ""
"Não é possível atualizar para um commit específico sem permissões de root"

#: common/flatpak-dir.c:11852
#, c-format
msgid "Can't remove %s, it is needed for: %s"
msgstr "Não foi possível remover %s, pois é necessário para: %s"

#: common/flatpak-dir.c:11912 common/flatpak-installation.c:2067
#, c-format
msgid "%s branch %s is not installed"
msgstr "%s ramo %s não está instalado"

#: common/flatpak-dir.c:12165
#, c-format
msgid "%s commit %s not installed"
msgstr "%s commit %s não instalado"

#: common/flatpak-dir.c:12501
#, c-format
msgid "Pruning repo failed: %s"
msgstr "A supressão de repositório falhou: %s"

#: common/flatpak-dir.c:12669 common/flatpak-dir.c:12675
#, c-format
msgid "Failed to load filter '%s'"
msgstr "Falha ao carregar o filtro “%s”"

#: common/flatpak-dir.c:12681
#, c-format
msgid "Failed to parse filter '%s'"
msgstr "Falha ao analisar o filtro “%s”"

#: common/flatpak-dir.c:12963
msgid "Failed to write summary cache: "
msgstr "Falha ao escrever cache de resumo: "

#: common/flatpak-dir.c:12982
#, c-format
msgid "No oci summary cached for remote '%s'"
msgstr "Nenhum resumo de oci em cache para o remoto “%s”"

#: common/flatpak-dir.c:13207
#, c-format
msgid "No cached summary for remote '%s'"
msgstr "Nenhum resumo em cache para “%s” remoto"

#: common/flatpak-dir.c:13248
#, c-format
msgid "Invalid checksum for indexed summary %s read from %s"
msgstr "Soma de verificação inválida para resumo indexado %s lido de %s"

#: common/flatpak-dir.c:13321
#, c-format
msgid ""
"Remote listing for %s not available; server has no summary file. Check the "
"URL passed to remote-add was valid."
msgstr ""
"Listagem de remoto para %s não disponível; o servidor não tem ficheiro de "
"resumo. Certifique-se que o URL passado para remote-add é válida."

#: common/flatpak-dir.c:13698
#, c-format
msgid "Invalid checksum for indexed summary %s for remote '%s'"
msgstr "Soma de verificação inválida para resumo indexado %s para “%s” remoto"

#: common/flatpak-dir.c:14388
#, c-format
msgid "Multiple branches available for %s, you must specify one of: "
msgstr "Vários ramos disponíveis para %s, você deve especificar uma entre: "

#: common/flatpak-dir.c:14454
#, c-format
msgid "Nothing matches %s"
msgstr "Sem combinações com %s"

#: common/flatpak-dir.c:14562
#, c-format
msgid "Can't find ref %s%s%s%s%s"
msgstr "Não foi possível localizar ref %s%s%s%s%s"

#: common/flatpak-dir.c:14605
#, c-format
msgid "Error searching remote %s: %s"
msgstr "Erro ao pesquisar remoto %s: %s"

#: common/flatpak-dir.c:14702
#, c-format
msgid "Error searching local repository: %s"
msgstr "Erro ao pesquisar repositório local: %s"

#: common/flatpak-dir.c:14839
#, c-format
msgid "%s/%s/%s not installed"
msgstr "%s/%s/%s não instalado"

#: common/flatpak-dir.c:15042
#, c-format
msgid "Could not find installation %s"
msgstr "Não foi possível localizar instalação de %s"

#: common/flatpak-dir.c:15612
#, c-format
msgid "Invalid file format, no %s group"
msgstr "Formato de ficheiro inválido, grupo %s inexistente"

#: common/flatpak-dir.c:15617 common/flatpak-repo-utils.c:2836
#, c-format
msgid "Invalid version %s, only 1 supported"
msgstr "Versão inválida %s, há suporte apenas a 1"

#: common/flatpak-dir.c:15622 common/flatpak-dir.c:15627
#, c-format
msgid "Invalid file format, no %s specified"
msgstr "Formato de ficheiro inválido, nenhuma %s especificada"

#. Check some minimal size so we don't get crap
#: common/flatpak-dir.c:15647
msgid "Invalid file format, gpg key invalid"
msgstr "Formato de ficheiro inválido, chave gpg inválida"

#: common/flatpak-dir.c:15675 common/flatpak-repo-utils.c:2917
msgid "Collection ID requires GPG key to be provided"
msgstr "ID de coleção requer que a chave GPG seja fornecida"

#: common/flatpak-dir.c:15718
#, c-format
msgid "Runtime %s, branch %s is already installed"
msgstr "Runtime %s, ramo %s já está instalado"

#: common/flatpak-dir.c:15719
#, c-format
msgid "App %s, branch %s is already installed"
msgstr "Aplicativo %s, ramo %s já está instalado"

#: common/flatpak-dir.c:15953
#, c-format
msgid "Can't remove remote '%s' with installed ref %s (at least)"
msgstr ""
"Não é possível remover o remoto “%s” com a ref %s instalada (pelo menos)"

#: common/flatpak-dir.c:16058
#, c-format
msgid "Invalid character '/' in remote name: %s"
msgstr "Caractere inválido “/” no nome do remoto: %s"

#: common/flatpak-dir.c:16064
#, c-format
msgid "No configuration for remote %s specified"
msgstr "Nenhuma configuração para o remoto %s especificado"

#: common/flatpak-dir.c:17597
#, c-format
msgid "Skipping deletion of mirror ref (%s, %s)…\n"
msgstr "Ignorando exclusão de ref espelho (%s, %s)…\n"

#: common/flatpak-exports.c:931
#, c-format
msgid "An absolute path is required"
msgstr ""

#: common/flatpak-exports.c:948
#, fuzzy, c-format
msgid "Unable to open path \"%s\": %s"
msgstr "Não foi possível atualizar %s: %s\n"

#: common/flatpak-exports.c:955
#, fuzzy, c-format
msgid "Unable to get file type of \"%s\": %s"
msgstr "Não foi possível criar o ficheiro %s"

#: common/flatpak-exports.c:964
#, c-format
msgid "File \"%s\" has unsupported type 0o%o"
msgstr ""

#: common/flatpak-exports.c:970
#, c-format
msgid "Unable to get filesystem information for \"%s\": %s"
msgstr ""

#: common/flatpak-exports.c:980
#, c-format
msgid "Ignoring blocking autofs path \"%s\""
msgstr ""

#: common/flatpak-exports.c:996 common/flatpak-exports.c:1009
#: common/flatpak-exports.c:1022
#, c-format
msgid "Path \"%s\" is reserved by Flatpak"
msgstr ""

#: common/flatpak-exports.c:1076
#, fuzzy, c-format
msgid "Unable to resolve symbolic link \"%s\": %s"
msgstr "Não foi possível atualizar o link simbólico %s/%s"

#: common/flatpak-glib-backports.c:69
msgid "Empty string is not a number"
msgstr "A string vazia não é um número"

#: common/flatpak-glib-backports.c:95
#, c-format
msgid "“%s” is not an unsigned number"
msgstr "“%s” não é um número não assinado"

#: common/flatpak-glib-backports.c:105
#, c-format
msgid "Number “%s” is out of bounds [%s, %s]"
msgstr "O número “%s” está fora dos limites [%s, %s]"

#: common/flatpak-image-source.c:83
msgid "Only sha256 image checksums are supported"
msgstr ""

#: common/flatpak-image-source.c:100 common/flatpak-image-source.c:108
msgid "Image is not a manifest"
msgstr "A imagem não é um manifesto"

#: common/flatpak-image-source.c:123
msgid "No org.flatpak.ref found in image"
msgstr ""

#: common/flatpak-image-source.c:148
#, c-format
msgid "Ref '%s' not found in registry"
msgstr "Ref “%s” não localizado no registro"

#: common/flatpak-image-source.c:157
msgid "Multiple images in registry, specify a ref with --ref"
msgstr "Várias imagens no registro, especifique uma ref com --ref"

#: common/flatpak-installation.c:834
#, c-format
msgid "Ref %s not installed"
msgstr "Ref %s não instalado"

#: common/flatpak-installation.c:875
#, c-format
msgid "App %s not installed"
msgstr "Aplicativo %s não instalado"

#: common/flatpak-installation.c:1395
#, c-format
msgid "Remote '%s' already exists"
msgstr "O remoto “%s” já existe"

#: common/flatpak-installation.c:1946
#, c-format
msgid "As requested, %s was only pulled, but not installed"
msgstr "Conforme requisitado, %s foi obtida, mas não instalada"

#: common/flatpak-instance.c:533 common/flatpak-instance.c:687
#: common/flatpak-instance.c:728
#, c-format
msgid "Unable to create directory %s"
msgstr "Não foi possível criar um diretório %s"

#: common/flatpak-instance.c:554
#, c-format
msgid "Unable to lock %s"
msgstr "Não foi possível travar %s"

#: common/flatpak-instance.c:627
#, c-format
msgid "Unable to create temporary directory in %s"
msgstr "Não foi possível criar um diretório temporário em %s"

#: common/flatpak-instance.c:639
#, c-format
msgid "Unable to create file %s"
msgstr "Não foi possível criar o ficheiro %s"

#: common/flatpak-instance.c:646
#, c-format
msgid "Unable to update symbolic link %s/%s"
msgstr "Não foi possível atualizar o link simbólico %s/%s"

#: common/flatpak-oci-registry.c:1197
msgid "Only Bearer authentication supported"
msgstr "Há suporte apenas à autenticação via token (Bearer)"

#: common/flatpak-oci-registry.c:1206
msgid "Only realm in authentication request"
msgstr "Apenas reino na solicitação de autenticação"

#: common/flatpak-oci-registry.c:1213
msgid "Invalid realm in authentication request"
msgstr "Reino inválido na solicitação de autenticação"

#: common/flatpak-oci-registry.c:1283
#, c-format
msgid "Authorization failed: %s"
msgstr "Autorização falhou: %s"

#: common/flatpak-oci-registry.c:1285
msgid "Authorization failed"
msgstr "Autorização falhou"

#: common/flatpak-oci-registry.c:1289
#, c-format
msgid "Unexpected response status %d when requesting token: %s"
msgstr "Status de resposta inesperada %d ao solicitar token: %s"

#: common/flatpak-oci-registry.c:1300
msgid "Invalid authentication request response"
msgstr "Resposta inválida à solicitação de autenticação"

#: common/flatpak-oci-registry.c:1731
#, c-format
msgid "Flatpak was compiled without zstd support"
msgstr ""

#: common/flatpak-oci-registry.c:1923 common/flatpak-oci-registry.c:1975
#: common/flatpak-oci-registry.c:2004 common/flatpak-oci-registry.c:2059
#: common/flatpak-oci-registry.c:2115 common/flatpak-oci-registry.c:2193
msgid "Invalid delta file format"
msgstr "Formato de ficheiro delta inválido"

#: common/flatpak-oci-registry.c:3198 common/flatpak-oci-registry.c:3382
msgid "Invalid OCI image config"
msgstr "Configuração de imagem OCI inválida"

#: common/flatpak-oci-registry.c:3260 common/flatpak-oci-registry.c:3531
#, c-format
msgid "Wrong layer checksum, expected %s, was %s"
msgstr "Soma de verificação de camada errada, esperava %s, era %s"

#: common/flatpak-oci-registry.c:3359
#, c-format
msgid "No ref specified for OCI image %s"
msgstr "Nenhuma ref especificada para a imagem OCI %s"

#: common/flatpak-oci-registry.c:3369
#, c-format
msgid "Wrong ref (%s) specified for OCI image %s, expected %s"
msgstr "Ref incorreta (%s) especificada para a imagem OCI %s, esperava %s"

#: common/flatpak-progress.c:236
#, c-format
msgid "Downloading metadata: %u/(estimating) %s"
msgstr "Baixando metadados: %u/(estimando) %s"

#: common/flatpak-progress.c:260
#, c-format
msgid "Downloading: %s/%s"
msgstr "Baixando: %s/%s"

#: common/flatpak-progress.c:280
#, c-format
msgid "Downloading extra data: %s/%s"
msgstr "Baixando dados extras: %s/%s"

#: common/flatpak-progress.c:285
#, c-format
msgid "Downloading files: %d/%d %s"
msgstr "Baixando ficheiros: %d/%d %s"

#: common/flatpak-ref-utils.c:122
msgid "Name can't be empty"
msgstr "Nome não pode estar vazio"

#: common/flatpak-ref-utils.c:129
msgid "Name can't be longer than 255 characters"
msgstr "Nome não pode ser maior que 255 caracteres"

#: common/flatpak-ref-utils.c:142
msgid "Name can't start with a period"
msgstr "Nome não pode iniciar com um ponto"

#: common/flatpak-ref-utils.c:148
#, c-format
msgid "Name can't start with %c"
msgstr "Nome não pode iniciar com %c"

#: common/flatpak-ref-utils.c:164
msgid "Name can't end with a period"
msgstr "Nome não pode terminar com um ponto"

#: common/flatpak-ref-utils.c:171 common/flatpak-ref-utils.c:183
msgid "Only last name segment can contain -"
msgstr "Apenas o último segmento de nome pode conter -"

#: common/flatpak-ref-utils.c:174
#, c-format
msgid "Name segment can't start with %c"
msgstr "Segmento de nome não pode iniciar com %c"

#: common/flatpak-ref-utils.c:186
#, c-format
msgid "Name can't contain %c"
msgstr "Nome não pode conter %c"

#: common/flatpak-ref-utils.c:195
msgid "Names must contain at least 2 periods"
msgstr "Nome deve conter pelo menos 2 pontos"

#: common/flatpak-ref-utils.c:312
msgid "Arch can't be empty"
msgstr "A arq. não pode estar vazia"

#: common/flatpak-ref-utils.c:323
#, c-format
msgid "Arch can't contain %c"
msgstr "A arq. não pode conter %c"

#: common/flatpak-ref-utils.c:385
msgid "Branch can't be empty"
msgstr "Ramos não podem estar vazios"

#: common/flatpak-ref-utils.c:395
#, c-format
msgid "Branch can't start with %c"
msgstr "Ramos não podem iniciar com %c"

#: common/flatpak-ref-utils.c:405
#, c-format
msgid "Branch can't contain %c"
msgstr "Ramos não podem conter %c"

#: common/flatpak-ref-utils.c:615 common/flatpak-ref-utils.c:865
msgid "Ref too long"
msgstr "Ref muito longa"

#: common/flatpak-ref-utils.c:627
msgid "Invalid remote name"
msgstr "Nome remoto inválido"

#: common/flatpak-ref-utils.c:641
#, c-format
msgid "%s is not application or runtime"
msgstr "%s não é uma aplicação ou runtime"

#: common/flatpak-ref-utils.c:650 common/flatpak-ref-utils.c:667
#: common/flatpak-ref-utils.c:683
#, c-format
msgid "Wrong number of components in %s"
msgstr "Número incorreto de componentes em %s"

#: common/flatpak-ref-utils.c:656
#, c-format
msgid "Invalid name %.*s: %s"
msgstr "Nome inválido %.*s: %s"

#: common/flatpak-ref-utils.c:673
#, c-format
msgid "Invalid arch: %.*s: %s"
msgstr "Arq. inválida: %.*s: %s"

#: common/flatpak-ref-utils.c:816
#, c-format
msgid "Invalid name %s: %s"
msgstr "Nome inválido %s: %s"

#: common/flatpak-ref-utils.c:834
#, c-format
msgid "Invalid arch: %s: %s"
msgstr "Arq. inválida: %s: %s"

#: common/flatpak-ref-utils.c:853
#, c-format
msgid "Invalid branch: %s: %s"
msgstr "Ramo inválido: %s: %s"

#: common/flatpak-ref-utils.c:962 common/flatpak-ref-utils.c:970
#: common/flatpak-ref-utils.c:978
#, c-format
msgid "Wrong number of components in partial ref %s"
msgstr "Número incorreto de componentes no ref parcial %s"

#: common/flatpak-ref-utils.c:1298
msgid " development platform"
msgstr " plataforma de desenvolvimento"

#: common/flatpak-ref-utils.c:1300
msgid " platform"
msgstr " plataforma"

#: common/flatpak-ref-utils.c:1302
msgid " application base"
msgstr " base de aplicação"

#: common/flatpak-ref-utils.c:1305
msgid " debug symbols"
msgstr " símbolos de depuração"

#: common/flatpak-ref-utils.c:1307
msgid " sourcecode"
msgstr " código-fonte"

#: common/flatpak-ref-utils.c:1309
msgid " translations"
msgstr " traduções"

#: common/flatpak-ref-utils.c:1311
msgid " docs"
msgstr " docs"

#: common/flatpak-ref-utils.c:1578
#, c-format
msgid "Invalid id %s: %s"
msgstr "ID inválido %s: %s"

#: common/flatpak-remote.c:1216
#, c-format
msgid "Bad remote name: %s"
msgstr "Nome inválido de remoto: %s"

#: common/flatpak-remote.c:1220
#, fuzzy
msgid "No URL specified"
msgstr "Nenhum url especificado"

#: common/flatpak-remote.c:1266
msgid "GPG verification must be enabled when a collection ID is set"
msgstr ""
"Verificação GPG deve estar habilitada quando um ID de coleção for definido"

#: common/flatpak-repo-utils.c:344
#, c-format
msgid "No extra data sources"
msgstr "Nenhuma fonte de dados extras"

#: common/flatpak-repo-utils.c:2817
#, c-format
msgid "Invalid %s: Missing group ‘%s’"
msgstr "%s inválido: Faltando grupo “%s”"

#: common/flatpak-repo-utils.c:2826
#, c-format
msgid "Invalid %s: Missing key ‘%s’"
msgstr "%s inválido: Faltando chave “%s”"

#: common/flatpak-repo-utils.c:2876
msgid "Invalid gpg key"
msgstr "Chave gpg inválida"

#: common/flatpak-repo-utils.c:3217
#, c-format
msgid "Error copying 64x64 icon for component %s: %s\n"
msgstr "Erro ao copiar ícone 64x64 para componente %s: %s\n"

#: common/flatpak-repo-utils.c:3223
#, c-format
msgid "Error copying 128x128 icon for component %s: %s\n"
msgstr "Erro ao copiar ícone 128x128 para componente %s: %s\n"

#: common/flatpak-repo-utils.c:3362
#, c-format
msgid "%s is end-of-life, ignoring for appstream"
msgstr "%s está em fim de vida, a ignorar para appstream"

#: common/flatpak-repo-utils.c:3397
#, c-format
msgid "No appstream data for %s: %s\n"
msgstr "Nenhum dado de appstream para %s: %s\n"

#: common/flatpak-repo-utils.c:3744
msgid "Invalid bundle, no ref in metadata"
msgstr "Pacote inválido, nenhuma ref nos metadados"

#: common/flatpak-repo-utils.c:3846
#, c-format
msgid "Collection ‘%s’ of bundle doesn’t match collection ‘%s’ of remote"
msgstr "A coleção “%s” de pacotes não correspondem à coleção “%s” do remoto"

#: common/flatpak-repo-utils.c:3923
msgid "Metadata in header and app are inconsistent"
msgstr "Metadados no cabeçalho e aplicação estão inconsistentes"

#: common/flatpak-run.c:951
msgid "No systemd user session available, cgroups not available"
msgstr ""
"Nenhuma sessão de utilizador de systemd disponível, cgroups não disponível"

#: common/flatpak-run.c:1496
msgid "Unable to allocate instance id"
msgstr "Não foi possível alocar id de instância"

#: common/flatpak-run.c:1632 common/flatpak-run.c:1641
#, c-format
msgid "Failed to open flatpak-info file: %s"
msgstr "Falha ao abrir ficheiro flatpak-info: %s"

#: common/flatpak-run.c:1668
#, c-format
msgid "Failed to open bwrapinfo.json file: %s"
msgstr "Falha ao abrir ficheiro bwrapinfo.json: %s"

#: common/flatpak-run.c:1689
#, c-format
msgid "Failed to write to instance id fd: %s"
msgstr "Falha ao escrever no descritor de ficheiro do ID de instância: %s"

#: common/flatpak-run.c:2096
msgid "Initialize seccomp failed"
msgstr "Inicialização de seccomp falhou"

#: common/flatpak-run.c:2135
#, c-format
msgid "Failed to add architecture to seccomp filter: %s"
msgstr "Falha ao adicionar arquitetura ao filtro seccomp: %s"

#: common/flatpak-run.c:2143
#, c-format
msgid "Failed to add multiarch architecture to seccomp filter: %s"
msgstr "Falha ao adicionar arquitetura multiarch ao filtro seccomp: %s"

#: common/flatpak-run.c:2175 common/flatpak-run.c:2192
#: common/flatpak-run.c:2214
#, c-format
msgid "Failed to block syscall %d: %s"
msgstr "Falha ao bloquear a chamada de sistema %d: %s"

#: common/flatpak-run.c:2247
#, c-format
msgid "Failed to export bpf: %s"
msgstr "Falha ao exportar bpf: %s"

#: common/flatpak-run.c:2587
#, c-format
msgid "Failed to open ‘%s’"
msgstr "Falha ao abrir “%s”"

#: common/flatpak-run.c:2597
#, c-format
msgid ""
"Directory forwarding needs version 4 of the document portal (have version %d)"
msgstr ""

#: common/flatpak-run.c:2915
#, c-format
msgid "ldconfig failed, exit status %d"
msgstr "ldconfig falhou, status de saída %d"

#: common/flatpak-run.c:2922
msgid "Can't open generated ld.so.cache"
msgstr "Não foi possível abrir o ld.so.cache gerado"

#. Translators: The placeholder is for an app ref.
#: common/flatpak-run.c:3045
#, c-format
msgid "Running %s is not allowed by the policy set by your administrator"
msgstr ""
"A execução de %s não é permitida pela política definida pelo administrador"

#: common/flatpak-run.c:3202
msgid ""
"\"flatpak run\" is not intended to be run as `sudo flatpak run`. Use `sudo "
"-i` or `su -l` instead and invoke \"flatpak run\" from inside the new shell."
msgstr ""
"“flatpak run” não se destina a ser executado como `sudo flatpak run`, use "
"`sudo -i` ou `su -l` no lugar e invoque “flatpak run” de dentro do novo "
"shell."

#: common/flatpak-run.c:3413
#, c-format
msgid "Failed to migrate from %s: %s"
msgstr "Falha ao migrar de %s: %s"

#: common/flatpak-run.c:3434
#, c-format
msgid "Failed to migrate old app data directory %s to new name %s: %s"
msgstr ""
"Falha ao migrar o diretório de dados antigo %s da aplicação para o novo nome "
"%s: %s"

#: common/flatpak-run.c:3443
#, c-format
msgid "Failed to create symlink while migrating %s: %s"
msgstr "Falha ao criar link simbólico ao migrar %s: %s"

#: common/flatpak-run-dbus.c:46
msgid "Failed to open app info file"
msgstr "Falha ao abrir ficheiro de informação da aplicação"

#: common/flatpak-run-dbus.c:149
msgid "Unable to create sync pipe"
msgstr "Não foi possível criar um pipe de sincronização"

#: common/flatpak-run-dbus.c:185
msgid "Failed to sync with dbus proxy"
msgstr "Falha ao sincronizar com proxy de dbus"

#: common/flatpak-transaction.c:2275
#, c-format
msgid "Warning: Problem looking for related refs: %s"
msgstr "Aviso: Problema ao procurar por refs relacionadas: %s"

#: common/flatpak-transaction.c:2493
#, c-format
msgid "The application %s requires the runtime %s which was not found"
msgstr "A aplicação %s requer o runtime %s, que não foi localizado"

#: common/flatpak-transaction.c:2509
#, c-format
msgid "The application %s requires the runtime %s which is not installed"
msgstr "A aplicação %s requer o runtime %s, que não está instalado"

#: common/flatpak-transaction.c:2641
#, c-format
msgid "Can't uninstall %s which is needed by %s"
msgstr "Não foi possível desinstalar %s, o qual é necessário para %s"

#: common/flatpak-transaction.c:2740
#, c-format
msgid "Remote %s disabled, ignoring %s update"
msgstr "Remoto %s desativado, a ignorar atualização de %s"

#: common/flatpak-transaction.c:2773
#, c-format
msgid "%s is already installed"
msgstr "%s já está instalado"

#: common/flatpak-transaction.c:2776
#, c-format
msgid "%s is already installed from remote %s"
msgstr "%s já está instalada pelo remoto %s"

#: common/flatpak-transaction.c:3120
#, c-format
msgid "Invalid .flatpakref: %s"
msgstr ".flatpakref inválido: %s"

#: common/flatpak-transaction.c:3161
msgid "Warning: Could not mark already installed apps as preinstalled"
msgstr ""

#: common/flatpak-transaction.c:3382
#, c-format
msgid "Error updating remote metadata for '%s': %s"
msgstr "Erro ao atualizar metadados de remoto para “%s”: %s"

#: common/flatpak-transaction.c:3885
#, c-format
msgid ""
"Warning: Treating remote fetch error as non-fatal since %s is already "
"installed: %s"
msgstr ""
"Aviso: Tratando erro de obtenção de remoto como não fatal, já que %s já está "
"instalado: %s"

#: common/flatpak-transaction.c:4209
#, c-format
msgid "No authenticator installed for remote '%s'"
msgstr "Nenhum autenticador instalado para remoto “%s”"

#: common/flatpak-transaction.c:4313 common/flatpak-transaction.c:4320
#, c-format
msgid "Failed to get tokens for ref: %s"
msgstr "Falha ao obter tokens para ref: %s"

#: common/flatpak-transaction.c:4315 common/flatpak-transaction.c:4322
msgid "Failed to get tokens for ref"
msgstr "Falha ao obter tokens para ref"

#: common/flatpak-transaction.c:4580
#, c-format
msgid "Ref %s from %s matches more than one transaction operation"
msgstr ""

#: common/flatpak-transaction.c:4581 common/flatpak-transaction.c:4591
#, fuzzy
msgid "any remote"
msgstr "Remoto"

#: common/flatpak-transaction.c:4590
#, c-format
msgid "No transaction operation found for ref %s from %s"
msgstr ""

#: common/flatpak-transaction.c:4713
#, c-format
msgid "Flatpakrepo URL %s not file, HTTP or HTTPS"
msgstr "URL de Flatpakrepo %s não é ficheiro, HTTP ou HTTPS"

#: common/flatpak-transaction.c:4719
#, c-format
msgid "Can't load dependent file %s: "
msgstr "Não foi possível carregar o ficheiro dependente %s: "

#: common/flatpak-transaction.c:4727
#, c-format
msgid "Invalid .flatpakrepo: %s"
msgstr ".flatpakrepo inválido: %s"

#: common/flatpak-transaction.c:5454
msgid "Transaction already executed"
msgstr "Transação já executada"

#: common/flatpak-transaction.c:5469
msgid ""
"Refusing to operate on a user installation as root! This can lead to "
"incorrect file ownership and permission errors."
msgstr ""
"Recusando-se a operar em uma instalação de utilizador como root! Isso pode "
"levar à propriedade incorreta do ficheiro e a erros de permissão."

#: common/flatpak-transaction.c:5567 common/flatpak-transaction.c:5580
msgid "Aborted by user"
msgstr "Abortado pelo utilizador"

#: common/flatpak-transaction.c:5605
#, c-format
msgid "Skipping %s due to previous error"
msgstr "Ignorando %s por causa do erro anterior"

#: common/flatpak-transaction.c:5659
#, c-format
msgid "Aborted due to failure (%s)"
msgstr "Abortado devido a falha (%s)"

#: common/flatpak-uri.c:118
#, fuzzy, no-c-format
msgid "Invalid %-encoding in URI"
msgstr "Nome de extensão inválido %s"

#: common/flatpak-uri.c:135
msgid "Illegal character in URI"
msgstr ""

#: common/flatpak-uri.c:169
msgid "Non-UTF-8 characters in URI"
msgstr ""

#: common/flatpak-uri.c:275
#, c-format
msgid "Invalid IPv6 address ‘%.*s’ in URI"
msgstr ""

#: common/flatpak-uri.c:330
#, c-format
msgid "Illegal encoded IP address ‘%.*s’ in URI"
msgstr ""

#: common/flatpak-uri.c:342
#, c-format
msgid "Illegal internationalized hostname ‘%.*s’ in URI"
msgstr ""

#: common/flatpak-uri.c:374 common/flatpak-uri.c:386
#, fuzzy, c-format
msgid "Could not parse port ‘%.*s’ in URI"
msgstr "Não foi possível analisar “%s”"

#: common/flatpak-uri.c:393
#, c-format
msgid "Port ‘%.*s’ in URI is out of range"
msgstr ""

#: common/flatpak-uri.c:910
msgid "URI is not absolute, and no base URI was provided"
msgstr ""

#: common/flatpak-usb.c:83
#, c-format
msgid "USB device query 'all' must not have data"
msgstr ""

#: common/flatpak-usb.c:102
#, c-format
msgid "USB query rule 'cls' must be in the form CLASS:SUBCLASS or CLASS:*"
msgstr ""

#: common/flatpak-usb.c:111
#, fuzzy, c-format
msgid "Invalid USB class"
msgstr "ID inválido %s: %s"

#: common/flatpak-usb.c:125
#, c-format
msgid "Invalid USB subclass"
msgstr ""

#: common/flatpak-usb.c:141 common/flatpak-usb.c:148
#, c-format
msgid "USB query rule 'dev' must have a valid 4-digit hexadecimal product id"
msgstr ""

#: common/flatpak-usb.c:164 common/flatpak-usb.c:171
#, c-format
msgid "USB query rule 'vnd' must have a valid 4-digit hexadecimal vendor id"
msgstr ""

#: common/flatpak-usb.c:205
#, c-format
msgid "USB device queries must be in the form TYPE:DATA"
msgstr ""

#: common/flatpak-usb.c:225
#, c-format
msgid "Unknown USB query rule %s"
msgstr ""

#: common/flatpak-usb.c:248
#, c-format
msgid "Empty USB query"
msgstr ""

#: common/flatpak-usb.c:274
#, c-format
msgid "Multiple USB query rules of the same type is not supported"
msgstr ""

#: common/flatpak-usb.c:283
#, c-format
msgid "'all' must not contain extra query rules"
msgstr ""

#: common/flatpak-usb.c:291
#, c-format
msgid "USB queries with 'dev' must also specify vendors"
msgstr ""

#: common/flatpak-utils.c:712
msgid "Glob can't match apps"
msgstr "Glob não pode corresponder aplicações"

#: common/flatpak-utils.c:737
msgid "Empty glob"
msgstr "Glob vazio"

#: common/flatpak-utils.c:756
msgid "Too many segments in glob"
msgstr "Número excessivo de argumentos no glob"

#: common/flatpak-utils.c:777
#, c-format
msgid "Invalid glob character '%c'"
msgstr "Caractere de glob “%c” inválido"

#: common/flatpak-utils.c:831
#, c-format
msgid "Missing glob on line %d"
msgstr "Faltando glob na linha %d"

#: common/flatpak-utils.c:835
#, c-format
msgid "Trailing text on line %d"
msgstr "Texto ao final na linha %d"

#: common/flatpak-utils.c:839
#, c-format
msgid "on line %d"
msgstr "na linha %d"

#: common/flatpak-utils.c:861
#, c-format
msgid "Unexpected word '%s' on line %d"
msgstr "Palavra inesperada “%s” na linha %d"

#: common/flatpak-utils.c:2118
#, c-format
msgid "Invalid require-flatpak argument %s"
msgstr "Argumento de require-flatpak inválido %s"

#: common/flatpak-utils.c:2128 common/flatpak-utils.c:2147
#, c-format
msgid "%s needs a later flatpak version (%s)"
msgstr "%s precisa de uma versão posterior do flatpak (%s)"

#: oci-authenticator/flatpak-oci-authenticator.c:291
msgid "Not a oci remote, missing summary.xa.oci-repository"
msgstr "Não é um remoto OCI, em falta summary.xa.oci-repository"

#: oci-authenticator/flatpak-oci-authenticator.c:477
msgid "Not a OCI remote"
msgstr "Não é um remoto OCI"

#: oci-authenticator/flatpak-oci-authenticator.c:488
msgid "Invalid token"
msgstr "Token inválido"

#: portal/flatpak-portal.c:2292
#, c-format
msgid "No portal support found"
msgstr "Não foi localizado suporte a portal"

#: portal/flatpak-portal.c:2298
msgid "Deny"
msgstr "Negar"

#: portal/flatpak-portal.c:2300
msgid "Update"
msgstr "Atualizar"

#: portal/flatpak-portal.c:2305
#, c-format
msgid "Update %s?"
msgstr "Atualizar %s?"

#: portal/flatpak-portal.c:2317
msgid "The application wants to update itself."
msgstr "A aplicação quer atualizar-se si própria."

#: portal/flatpak-portal.c:2318
msgid "Update access can be changed any time from the privacy settings."
msgstr ""
"Acesso a atualização pode ser alterado a qualquer momento a partir das "
"configurações de privacidade."

#: portal/flatpak-portal.c:2343
#, c-format
msgid "Application update not allowed"
msgstr "Atualização de aplicação não permitida"

#: portal/flatpak-portal.c:2501
#, c-format
msgid "Self update not supported, new version requires new permissions"
msgstr "Sem suporte à autoatualização, nova versão requer novas permissões"

#: portal/flatpak-portal.c:2684 portal/flatpak-portal.c:2702
#, c-format
msgid "Update ended unexpectedly"
msgstr "Atualização encerrada inesperadamente"

#. SECURITY:
#. - Normal users need admin authentication to install software
#. system-wide.
#. - Note that we install polkit rules that allow local users
#. in the wheel group to install without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:23
msgid "Install signed application"
msgstr "Instalar aplicação assinada"

#: system-helper/org.freedesktop.Flatpak.policy.in:24
#: system-helper/org.freedesktop.Flatpak.policy.in:42
msgid "Authentication is required to install software"
msgstr "Autenticação é necessária para instalar software"

#. SECURITY:
#. - Normal users need admin authentication to install software
#. system-wide.
#. - Note that we install polkit rules that allow local users
#. in the wheel group to install without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:41
msgid "Install signed runtime"
msgstr "Instalar runtime assinado"

#. SECURITY:
#. - Normal users do not require admin authentication to update an
#. app as the commit will be signed, and the action is required
#. to update the system when unattended.
#. - Changing this to anything other than 'yes' will break unattended
#. updates.
#: system-helper/org.freedesktop.Flatpak.policy.in:60
msgid "Update signed application"
msgstr "Atualizar aplicação assinada"

#: system-helper/org.freedesktop.Flatpak.policy.in:61
#: system-helper/org.freedesktop.Flatpak.policy.in:80
msgid "Authentication is required to update software"
msgstr "Autenticação é necessária para atualizar software"

#. SECURITY:
#. - Normal users do not require admin authentication to update a
#. runtime as the commit will be signed, and the action is required
#. to update the system when unattended.
#. - Changing this to anything other than 'yes' will break unattended
#. updates.
#: system-helper/org.freedesktop.Flatpak.policy.in:79
msgid "Update signed runtime"
msgstr "Atualizar runtime assinado"

#. SECURITY:
#. - Normal users do not need authentication to update metadata
#. from signed repositories.
#: system-helper/org.freedesktop.Flatpak.policy.in:94
msgid "Update remote metadata"
msgstr "Atualizar metadados remotos"

#: system-helper/org.freedesktop.Flatpak.policy.in:95
msgid "Authentication is required to update remote info"
msgstr "Autenticação é necessária para atualizar informações de remoto"

#. SECURITY:
#. - Normal users do not need authentication to modify the
#. OSTree repository
#. - Note that we install polkit rules that allow local users
#. in the wheel group to modify repos without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:111
msgid "Update system repository"
msgstr "Atualiza repositório do sistema"

#: system-helper/org.freedesktop.Flatpak.policy.in:112
msgid "Authentication is required to modify a system repository"
msgstr "Autenticação é necessária para modificar um repositório de sistema"

#. SECURITY:
#. - Normal users need admin authentication to install software
#. system-wide.
#: system-helper/org.freedesktop.Flatpak.policy.in:126
msgid "Install bundle"
msgstr "Instalar pacote"

#: system-helper/org.freedesktop.Flatpak.policy.in:127
msgid "Authentication is required to install software from $(path)"
msgstr "Autenticação é necessária para instalar software de $(path)"

#. SECURITY:
#. - Normal users need admin authentication to uninstall software
#. system-wide.
#. - Note that we install polkit rules that allow local users
#. in the wheel group to uninstall without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:144
msgid "Uninstall runtime"
msgstr "Desinstalar runtime"

#: system-helper/org.freedesktop.Flatpak.policy.in:145
msgid "Authentication is required to uninstall software"
msgstr "Autenticação é necessária para desinstalar software"

#. SECURITY:
#. - Normal users need admin authentication to uninstall software
#. system-wide.
#. - Note that we install polkit rules that allow local users
#. in the wheel group to uninstall without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:161
msgid "Uninstall app"
msgstr "Desinstalar aplicação"

#: system-helper/org.freedesktop.Flatpak.policy.in:162
msgid "Authentication is required to uninstall $(ref)"
msgstr "Autenticação é necessária para desinstalar $(ref)"

#. SECURITY:
#. - Normal users need admin authentication to configure system-wide
#. software repositories.
#: system-helper/org.freedesktop.Flatpak.policy.in:177
msgid "Configure Remote"
msgstr "Configurar remoto"

#: system-helper/org.freedesktop.Flatpak.policy.in:178
msgid "Authentication is required to configure software repositories"
msgstr "Autenticação é necessária para configurar os repositórios de software"

#. SECURITY:
#. - Normal users need admin authentication to configure the system-wide
#. Flatpak installation.
#: system-helper/org.freedesktop.Flatpak.policy.in:192
msgid "Configure"
msgstr "Configurar"

#: system-helper/org.freedesktop.Flatpak.policy.in:193
msgid "Authentication is required to configure software installation"
msgstr "Autenticação é necessária para configurar a instalação de software"

#. SECURITY:
#. - Normal users do not require admin authentication to update
#. appstream data as it will be signed, and the action is required
#. to update the system when unattended.
#. - Changing this to anything other than 'yes' will break unattended
#. updates.
#: system-helper/org.freedesktop.Flatpak.policy.in:210
msgid "Update appstream"
msgstr "Atualizar appstream"

#: system-helper/org.freedesktop.Flatpak.policy.in:211
msgid "Authentication is required to update information about software"
msgstr "Autenticação é necessária para atualizar informações sobre software"

#. SECURITY:
#. - Normal users do not require admin authentication to update
#. metadata as it will be signed, and the action is required
#. to update the system when unattended.
#. - Changing this to anything other than 'yes' will break unattended
#. updates.
#: system-helper/org.freedesktop.Flatpak.policy.in:228
msgid "Update metadata"
msgstr "Atualizar metadados"

#: system-helper/org.freedesktop.Flatpak.policy.in:229
msgid "Authentication is required to update metadata"
msgstr "Autenticação é necessária para atualizar metadados"

#. SECURITY:
#. - Authorisation to actually install software is controlled by
#. org.freedesktop.Flatpak.app-install.
#. - This action is checked after app-install, as it can only be done
#. once the app’s data (including its content rating) has been
#. downloaded.
#. - This action is checked to see if the installation should be allowed
#. based on whether the app being installed has content which doesn’t
#. comply with the user’s parental controls policy (the content is
#. ‘too extreme’).
#. - It is checked only if an app has too extreme content for the user
#. who is trying to install it (in which case, the app is ‘unsafe’).
#. - Typically, normal users will need admin permission to install apps
#. with extreme content; admins will be able to install it without
#. additional checks.
#. - In order to configure the policy so that admins can install safe and
#. unsafe software anywhere without authorisation, and non-admins can
#. install safe software in their user or system dirs without
#. authorisation, but need authorisation to install unsafe software
#. anywhere:
#. * Unconditionally return `yes` from `app-install`.
#. * Return `auth_admin` from `override-parental-controls` for users
#. not in `@privileged_group@`, and `yes` for users in it.
#. * Set the malcontent `is-{user,system}-installation-allowed`
#. properties of all non-admins’ parental controls policies to true.
#. - In order to configure the policy so that admins can install safe and
#. unsafe software anywhere without authorisation, and non-admins can
#. install safe software in their user dir without authorisation, but
#. need authorisation to install safe software in the system dir or to
#. install unsafe software anywhere:
#. * Unconditionally return `yes` from `app-install`.
#. * Return `auth_admin` from `override-parental-controls` for users
#. not in `@privileged_group@`, and `yes` for users in it.
#. * Set the malcontent `is-user-installation-allowed` property of all
#. non-admins’ parental controls policies to true.
#. * Set the malcontent `is-system-installation-allowed` property of
#. all non-admins’ parental controls policies to false.
#. - In order to configure the policy so that all users (including
#. admins) can install safe software anywhere without authorisation,
#. but need authorisation to install unsafe software anywhere (i.e.
#. applying parental controls to admins too):
#. * Unconditionally return `yes` from `app-install`.
#. * Unconditionally return `auth_admin` from `override-parental-controls`.
#. * Set the malcontent `is-user-installation-allowed` property of all
#. users’ parental controls policies to true.
#. * Set the malcontent `is-system-installation-allowed` property of
#. all users’ parental controls policies to true.
#: system-helper/org.freedesktop.Flatpak.policy.in:287
#, fuzzy
msgid "Override parental controls for installs"
msgstr "Sobrepor controlo parental"

#: system-helper/org.freedesktop.Flatpak.policy.in:288
msgid ""
"Authentication is required to install software which is restricted by your "
"parental controls policy"
msgstr ""
"Autenticação é necessária para instalar software que está restrito por sua "
"política de controlo parental"

#. SECURITY:
#. - This is like org.freedesktop.Flatpak.override-parental-controls, but
#. it’s queried for app updates, whereas the former is queried for app
#. installs.
#. - As with the above action, this one is only queried if
#. org.freedesktop.Flatpak.app-update has allowed the app update, and
#. only if the app being updated has too extreme content for the user
#. who is trying to update it.
#. - The default policy for this is to *allow* updates to ‘too extreme’
#. apps by default, on the basis that having an out-of-date (i.e.
#. insecure or unsupported) app is a worse outcome than automatically
#. installing an update which has radically different content from the
#. version of the app which the parent originally vetted and installed.
#: system-helper/org.freedesktop.Flatpak.policy.in:313
#, fuzzy
msgid "Override parental controls for updates"
msgstr "Sobrepor controlo parental"

#: system-helper/org.freedesktop.Flatpak.policy.in:314
#, fuzzy
msgid ""
"Authentication is required to update software which is restricted by your "
"parental controls policy"
msgstr ""
"Autenticação é necessária para instalar software que está restrito por sua "
"política de controlo parental"

#~ msgid "Installed:"
#~ msgstr "Instalado:"

#~ msgid "Download:"
#~ msgstr "Baixar:"

#, c-format
#~ msgid "No gpg key found with ID %s (homedir: %s)"
#~ msgstr "Nenhuma chave gpg localizada com ID %s (homedir: %s)"

#, fuzzy, c-format
#~ msgid "Unable to lookup key ID %s: %d"
#~ msgstr "Não foi possível procurar o ID de chave %s: %d"

#, c-format
#~ msgid "Error signing commit: %d"
#~ msgstr "Erro ao assinar o commit: %d"

#, c-format
#~ msgid ""
#~ "Found similar ref(s) for ‘%s’ in remote ‘%s’ (%s).\n"
#~ "Use this remote?"
#~ msgstr ""
#~ "Localizada(s) ref(s) similares para “%s” em remoto “%s” (%s).\n"
#~ "Usar este remoto?"

#, c-format
#~ msgid "No entry for %s in remote '%s' summary cache "
#~ msgstr "Nenhuma entrada para %s no cache de resumo do remoto “%s” "

#, c-format
#~ msgid "Failed to uninstall %s for rebase to %s: "
#~ msgstr "Falha ao desinstalar %s para realizar rebase de %s: "

#, c-format
#~ msgid "Failed to uninstall %s for rebase to %s: %s\n"
#~ msgstr "Falha ao desinstalar %s para rebase de %s: %s\n"

#, c-format
#~ msgid "Unable to open directory %s"
#~ msgstr "Não foi possível abrir o diretório %s"

#~ msgid "install"
#~ msgstr "instalar"

#~ msgid "update"
#~ msgstr "atualizar"

#~ msgid "install bundle"
#~ msgstr "instalar pacote"

#~ msgid "uninstall"
#~ msgstr "desinstalar"

#~ msgid "(internal error, please report)"
#~ msgstr "(erro interno, reporte)"

#~ msgid "Warning:"
#~ msgstr "Aviso:"

#, fuzzy
#~ msgid "runtime"
#~ msgstr "Runtime"

#, fuzzy
#~ msgid "app"
#~ msgstr "App"

# 1º %s: "Error:", "Warning:"
# 2º %s: op_type: "install", "update", etc.
# 3º %s: rref: name of a ref
# 4º %s: msg: some error/warning message
#, c-format
#~ msgid "%s Failed to %s %s: %s\n"
#~ msgstr "%s Falha ao %s %s: %s\n"

#~ msgid "[REF…] - Uninstall an application"
#~ msgstr "[REF…] – Desinstala uma aplicação"

#, c-format
#~ msgid "Replace it with %s?"
#~ msgstr "Substitui-lo por %s?"

#~ msgid "\"flatpak run\" is not intended to be ran with sudo"
#~ msgstr "“flatpak run” não se destina a ser executado com sudo"

#~ msgid "Invalid deployed ref %s: "
#~ msgstr "Ref implantado inválido %s: "

#~ msgid "Deployed ref %s kind does not match commit (%s)"
#~ msgstr "O tipo do ref implementado %s não coincide com o commit (%s)"

#~ msgid "Deployed ref %s name does not match commit (%s)"
#~ msgstr "O nome do ref implementado %s não coincide com o commit (%s)"

#~ msgid "Deployed ref %s arch does not match commit (%s)"
#~ msgstr "A arquitetura do ref implementado %s não coincide com o commit (%s)"

#~ msgid "Failed to determine parts from ref: %s"
#~ msgstr "Falha ao determinar partes do ref: %s"

#~ msgid "Invalid arch %s"
#~ msgstr "Arquitetura inválida %s"

#~ msgid "Related ref '%s' is only partially installed"
#~ msgstr "O ref “%s” relacionado está apenas parcialmente instalado"

#~ msgid "Ref '%s' is only partially installed"
#~ msgstr "O ref “%s” está apenas parcialmente instalado"

#~ msgid "No such ref (%s, %s) in remote %s"
#~ msgstr "Ref inexistente (%s, %s) no remoto %s"

#~ msgid "No flatpak cache in remote '%s' summary"
#~ msgstr "Nenhum cache de flatpak no sumário do remoto “%s”"

#~ msgid "No such ref (%s, %s) in remote %s or elsewhere"
#~ msgstr "Ref inexistente (%s, %s) no remoto %s ou em outro lugar"

#~ msgid "No remotes found which provide these refs: [%s]"
#~ msgstr "Nenhum remoto localizado que forneça esses refs: [%s]"

#~ msgid "No remotes found which provide the ref (%s, %s)"
#~ msgstr "Nenhum remoto localizado que forneça o ref (%s, %s)"

#~ msgid "No summary found"
#~ msgstr "Nenhum resumo localizado"

#~ msgid ""
#~ "GPG verification enabled, but no summary signatures found for remote '%s'"
#~ msgstr ""
#~ "Verificação GPG habilitada, mas nenhuma assinatura de resumo localizada "
#~ "para o remoto “%s”"

#~ msgid ""
#~ "GPG signatures found for remote '%s', but none are in trusted keyring"
#~ msgstr ""
#~ "Assinaturas GPG localizadas para o remoto “%s”, mas nenhuma está no "
#~ "chaveiro de confiadas"

#~ msgid "Expected commit metadata to have ref binding information, found none"
#~ msgstr ""
#~ "Esperava que metadados de commit tivessem informações de associação de "
#~ "ref, localizou nada"

#~ msgid ""
#~ "Expected commit metadata to have collection ID binding information, found "
#~ "none"
#~ msgstr ""
#~ "Esperava que metadados de commit tivessem informações de associação de ID "
#~ "da coleção, localizou nada"

#~ msgid ""
#~ "Commit has collection ID ‘%s’ in collection binding metadata, while the "
#~ "remote it came from has collection ID ‘%s’"
#~ msgstr ""
#~ "O commit possui ID de coleção “%s” nos metadados de associação de "
#~ "coleção, enquanto no remoto ele tem ID de coleção “%s”"

#~ msgid "Deployed metadata does not match commit"
#~ msgstr "Metadados implementados não coincidem com o commit"

#~ msgid "No repo metadata cached for remote '%s'"
#~ msgstr "Nenhum metadado de repositório em cache para o remoto “%s”"

#~ msgid "No metadata branch for OCI"
#~ msgstr "Nenhum ramo de metadados para OCI"

#~ msgid "Invalid group: %d"
#~ msgstr "Grupo inválido: %d"

#~ msgid "Warning: Can't find %s metadata for dependencies: %s"
#~ msgstr ""
#~ "Aviso: Não foi possível localizar metadados %s para dependências: %s"

#~ msgid "Use OCI labels instead of annotations"
#~ msgstr "Usa rótulos OCI em vez de anotações"

#~ msgid "OPTIONS"
#~ msgstr "OPÇÕES"

#~ msgid "Not running as root, may be unable to enter namespace"
#~ msgstr ""
#~ "Não executando como root, pode ser impossível entrar no espaço de nome"

#~ msgid "Default system installation"
#~ msgstr "Instalação padrão do sistema"

#~ msgid "No url specified in flatpakrepo file"
#~ msgstr "Nenhuma url especificada no arquivo flatpakrepo"

#~ msgid "0"
#~ msgstr "0"

#~ msgid "Location:"
#~ msgstr "Localização:"

#~ msgid "Architecture"
#~ msgstr "Arquitetura"

#~ msgid "Runtime Branch"
#~ msgstr "Ramo do runtime"

#~ msgid "Runtime Commit"
#~ msgstr "Commit do runtime"

#~ msgid "Installing for user: %s from %s\n"
#~ msgstr "Instalando para usuário: %s de %s\n"

#~ msgid "Installing: %s from %s\n"
#~ msgstr "Instalando: %s de %s\n"

#~ msgid "Updating for user: %s from %s\n"
#~ msgstr "Atualizando para usuário: %s de %s\n"

#~ msgid "Updating: %s from %s\n"
#~ msgstr "Atualizando: %s de %s\n"

#~ msgid "Installing for user: %s from bundle %s\n"
#~ msgstr "Instalando para usuário: %s do pacote %s\n"

#~ msgid "Installing: %s from bundle %s\n"
#~ msgstr "Instalando: %s do pacote %s\n"

#~ msgid "Uninstalling for user: %s\n"
#~ msgstr "Desinstalando para usuário: %s\n"

#~ msgid "No updates.\n"
#~ msgstr "Nenhuma atualização.\n"

#~ msgid "Now at %s.\n"
#~ msgstr "Agora em %s.\n"

#~ msgid "new file access"
#~ msgstr "novo acesso a arquivo"

#~ msgid "file access"
#~ msgstr "acesso a arquivo"

#~ msgid "new dbus access"
#~ msgstr "novo acesso a dbus"

#~ msgid "dbus access"
#~ msgstr "acesso a dbus"

#~ msgid "new dbus ownership"
#~ msgstr "nova propriedade dbus"

#~ msgid "dbus ownership"
#~ msgstr "propriedade dbus"

#~ msgid "new system dbus access"
#~ msgstr "novo acesso dbus de sistema"

#~ msgid "system dbus access"
#~ msgstr "acesso dbus de sistema"

#~ msgid "new system dbus ownership"
#~ msgstr "nova propriedade dbus de sistema"

#~ msgid "system dbus ownership"
#~ msgstr "propriedade dbus de sistema"

#~ msgid "new tags"
#~ msgstr "novas etiquetas"

#~ msgid "tags"
#~ msgstr "etiquetas"

#~ msgid "Uninstalling from %s:\n"
#~ msgstr "Desinstalando de %s:\n"

#~ msgid "Installing in %s:\n"
#~ msgstr "Instalando em %s:\n"

#~ msgid "Is this ok"
#~ msgstr "Isto está bom"

#~ msgid "Print OSTree debug information during command processing"
#~ msgstr ""
#~ "Exibe a informações de depuração da árvore do sistema durante o "
#~ "processamento de comandos"

#~ msgid "Unknown command '%s'"
#~ msgstr "Comando desconhecido “%s”"

#~ msgid "Invalid sha256 for extra data uri %s"
#~ msgstr "sha256 inválido para uri de dados extras %s"

#~ msgid "Invalid sha256 for extra data"
#~ msgstr "sha256 inválido para dados extras"

#~ msgid "%s branch already installed"
#~ msgstr "%s ramo já está instalado"

#~ msgid "%s branch %s not installed"
#~ msgstr "%s ramo %s não está instalado"

#~ msgid "Migrating %s to %s\n"
#~ msgstr "Migrando %s para %s\n"

#~ msgid "Extracting icons for component %s\n"
#~ msgstr "Extraindo ícones para o componente %s\n"

#~ msgid "Redirect collection ID: %s\n"
#~ msgstr "ID de coleção de redirecionamento: %s\n"

#~ msgid "Is this ok?"
#~ msgstr "Isto está bom?"

#~ msgid "Add OCI registry"
#~ msgstr "Adiciona registro OCI"

#~ msgid "Found in remote %s\n"
#~ msgstr "Localizado no remoto %s\n"

#~ msgid "Found in remote %s, do you want to install it?"
#~ msgstr "Localizado no remoto %s, você deseja instalá-lo?"

#~ msgid "Found in several remotes:\n"
#~ msgstr "Localizado em diversos remotos:\n"

#~ msgid "The required runtime %s was not found in a configured remote.\n"
#~ msgstr "O runtime exigido %s não foi localizado em um remoto configurado.\n"

#~ msgid "%s already installed, skipping\n"
#~ msgstr "%s já instalado, ignorando\n"

#~ msgid "fetch remote info"
#~ msgstr "obtém info de remoto"

#~ msgid "One or more operations failed"
#~ msgstr "Uma ou mais operações falharam"

#~ msgid ""
#~ "/var/tmp does not suport xattrs which is needed for system-wide "
#~ "installation as a user. FLATPAK_SYSTEM_CACHE_DIR can be used to set an "
#~ "alternative path."
#~ msgstr ""
#~ "/var/tmp não possui suporte a xattrs que é necessário para instalação "
#~ "para todo sistema como usuário. FLATPAK_SYSTEM_CACHE_DIR pode ser usado "
#~ "para definir um caminho alternativo."

#~ msgid "No ref information available in repository"
#~ msgstr "Nenhuma informação de ref disponível no repositório"

#~ msgid "Remote title not set"
#~ msgstr "Título remoto não definido"

#~ msgid "Remote default-branch not set"
#~ msgstr "Ramo padrão remoto não definido"

#~ msgid "Search specific system-wide installations"
#~ msgstr "Pesquisa instalações específicas do sistema"

#~ msgid "Failed to unlink temporary file"
#~ msgstr "Falha ao desvincular arquivo temporário"

#~ msgid "Post-Install %s"
#~ msgstr "Pós-instalação: %s"

===== ./po/hu.po =====
# Hungarian translation for flatpak.
# Copyright (C) 2016, 2017, 2018 Free Software Foundation, Inc.
# This file is distributed under the same license as the flatpak package.
#
# Balázs Úr <urbalazs@gmail.com>, 2016, 2017, 2018.
# Gabor Kelemen <kelemeng at ubuntu dot com>, 2016.
msgid ""
msgstr ""
"Project-Id-Version: flatpak master\n"
"Report-Msgid-Bugs-To: https://github.com/flatpak/flatpak/issues\n"
"POT-Creation-Date: 2026-05-27 16:39+0200\n"
"PO-Revision-Date: 2018-03-10 00:00+0100\n"
"Last-Translator: Balázs Úr <urbalazs@gmail.com>\n"
"Language-Team: Hungarian <openscope at googlegroups dot com>\n"
"Language: hu\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Generator: Lokalize 2.0\n"

#: app/flatpak-builtins-build-bundle.c:59
msgid "Export runtime instead of app"
msgstr "Futtatókörnyezet exportálása az alkalmazás helyett"

#: app/flatpak-builtins-build-bundle.c:60
msgid "Arch to bundle for"
msgstr "Csomagolás ezen architektúrához"

#: app/flatpak-builtins-build-bundle.c:60
#: app/flatpak-builtins-build-export.c:62 app/flatpak-builtins-build-init.c:53
#: app/flatpak-builtins-build-sign.c:42 app/flatpak-builtins-create-usb.c:46
#: app/flatpak-builtins-info.c:55 app/flatpak-builtins-install.c:67
#: app/flatpak-builtins-list.c:50 app/flatpak-builtins-make-current.c:38
#: app/flatpak-builtins-remote-info.c:54 app/flatpak-builtins-remote-ls.c:56
#: app/flatpak-builtins-run.c:158 app/flatpak-builtins-search.c:37
#: app/flatpak-builtins-uninstall.c:54 app/flatpak-builtins-update.c:56
msgid "ARCH"
msgstr "ARCHITEKTÚRA"

#: app/flatpak-builtins-build-bundle.c:61
#, fuzzy
msgid "URL for repo"
msgstr "URL a tárolóhoz"

#: app/flatpak-builtins-build-bundle.c:61
#: app/flatpak-builtins-build-bundle.c:62
#: app/flatpak-builtins-build-update-repo.c:68
#: app/flatpak-builtins-build-update-repo.c:72
#: app/flatpak-builtins-build-update-repo.c:73
#: app/flatpak-builtins-history.c:69 app/flatpak-builtins-remote-add.c:80
#: app/flatpak-builtins-remote-add.c:81 app/flatpak-builtins-remote-add.c:85
#: app/flatpak-builtins-remote-list.c:53
#: app/flatpak-builtins-remote-modify.c:70
#: app/flatpak-builtins-remote-modify.c:85
#: app/flatpak-builtins-remote-modify.c:86
#: app/flatpak-builtins-remote-modify.c:90
msgid "URL"
msgstr "URL"

#: app/flatpak-builtins-build-bundle.c:62
#, fuzzy
msgid "URL for runtime flatpakrepo file"
msgstr "URL a futtatókörnyezet flatpaktároló fájlhoz"

#: app/flatpak-builtins-build-bundle.c:63
msgid "Add GPG key from FILE (- for stdin)"
msgstr "GPG kulcs hozzáadása a FÁJLBÓL (- a szabványos bemenethez)"

#: app/flatpak-builtins-build-bundle.c:63 app/flatpak-builtins-build.c:54
#: app/flatpak-builtins-build-export.c:67
#: app/flatpak-builtins-build-update-repo.c:83
#: app/flatpak-builtins-install.c:81 app/flatpak-builtins-remote-add.c:84
#: app/flatpak-builtins-remote-add.c:86 app/flatpak-builtins-remote-modify.c:89
#: app/flatpak-builtins-remote-modify.c:92
msgid "FILE"
msgstr "FÁJL"

#: app/flatpak-builtins-build-bundle.c:64
msgid "GPG Key ID to sign the OCI image with"
msgstr "GPG kulcsazonosító az OCI-lemezkép aláírásához"

#: app/flatpak-builtins-build-bundle.c:64
#: app/flatpak-builtins-build-commit-from.c:68
#: app/flatpak-builtins-build-export.c:68
#: app/flatpak-builtins-build-import-bundle.c:49
#: app/flatpak-builtins-build-sign.c:44
#: app/flatpak-builtins-build-update-repo.c:84
msgid "KEY-ID"
msgstr "KULCSAZONOSÍTÓ"

#: app/flatpak-builtins-build-bundle.c:65
#: app/flatpak-builtins-build-commit-from.c:69
#: app/flatpak-builtins-build-export.c:71
#: app/flatpak-builtins-build-import-bundle.c:50
#: app/flatpak-builtins-build-sign.c:45
#: app/flatpak-builtins-build-update-repo.c:85
msgid "GPG Homedir to use when looking for keyrings"
msgstr "A kulcstartók keresésekor használandó GPG saját könyvtár"

#: app/flatpak-builtins-build-bundle.c:65
#: app/flatpak-builtins-build-commit-from.c:69
#: app/flatpak-builtins-build-export.c:71
#: app/flatpak-builtins-build-import-bundle.c:50
#: app/flatpak-builtins-build-sign.c:45
#: app/flatpak-builtins-build-update-repo.c:85
msgid "HOMEDIR"
msgstr "SAJÁTKÖNYVTÁR"

#: app/flatpak-builtins-build-bundle.c:66
msgid "OSTree commit to create a delta bundle from"
msgstr "OSTree kommit egy deltacsomag előállításához ebből:"

#: app/flatpak-builtins-build-bundle.c:66 app/flatpak-builtins-remote-info.c:55
#: app/flatpak-builtins-update.c:57
msgid "COMMIT"
msgstr "KOMMIT"

#: app/flatpak-builtins-build-bundle.c:67
msgid "Export oci image instead of flatpak bundle"
msgstr "Egy OCI-lemezkép exportálása flatpak csomag helyett"

#: app/flatpak-builtins-build-bundle.c:70
msgid "How to compress OCI image layers (default: gzip)"
msgstr ""

#: app/flatpak-builtins-build-bundle.c:634
msgid ""
"LOCATION FILENAME NAME [BRANCH] - Create a single file bundle from a local "
"repository"
msgstr ""
"HELY FÁJLNÉV NÉV [ÁG] - Egyetlen fájlcsomag létrehozása helyi tárolóból"

#: app/flatpak-builtins-build-bundle.c:641
msgid "LOCATION, FILENAME and NAME must be specified"
msgstr "A HELY, FÁJLNÉV és NÉV megadása kötelező"

#: app/flatpak-builtins-build-bundle.c:644
#: app/flatpak-builtins-build-export.c:844
#: app/flatpak-builtins-build-import-bundle.c:136
#: app/flatpak-builtins-build-init.c:217 app/flatpak-builtins-build-sign.c:76
#: app/flatpak-builtins-document-export.c:112
#: app/flatpak-builtins-document-info.c:75
#: app/flatpak-builtins-document-list.c:191
#: app/flatpak-builtins-document-unexport.c:70
#: app/flatpak-builtins-history.c:482 app/flatpak-builtins-info.c:130
#: app/flatpak-builtins-install.c:181 app/flatpak-builtins-install.c:234
#: app/flatpak-builtins-install.c:298 app/flatpak-builtins-list.c:419
#: app/flatpak-builtins-make-current.c:72 app/flatpak-builtins-override.c:73
#: app/flatpak-builtins-permission-list.c:162
#: app/flatpak-builtins-permission-remove.c:132
#: app/flatpak-builtins-remote-add.c:323
#: app/flatpak-builtins-remote-delete.c:68
#: app/flatpak-builtins-remote-list.c:241 app/flatpak-builtins-remote-ls.c:407
msgid "Too many arguments"
msgstr "Túl sok argumentum"

#: app/flatpak-builtins-build-bundle.c:659
#: app/flatpak-builtins-build-commit-from.c:338
#: app/flatpak-builtins-build-commit-from.c:351
#: app/flatpak-builtins-build-import-bundle.c:145
#, c-format
msgid "'%s' is not a valid repository"
msgstr "A(z) „%s” nem érvényes tároló"

#: app/flatpak-builtins-build-bundle.c:663
#, fuzzy, c-format
msgid "'%s' is not a valid repository: "
msgstr "A(z) „%s” nem érvényes tároló"

#: app/flatpak-builtins-build-bundle.c:674 app/flatpak-builtins-build-sign.c:88
#: common/flatpak-dir.c:14293
#, c-format
msgid "'%s' is not a valid name: %s"
msgstr "A(z) „%s” nem érvényes név: %s"

#: app/flatpak-builtins-build-bundle.c:677
#: app/flatpak-builtins-build-export.c:865 app/flatpak-builtins-build-sign.c:91
#: common/flatpak-dir.c:14299
#, c-format
msgid "'%s' is not a valid branch name: %s"
msgstr "A(z) „%s” nem érvényes ágnév: %s"

#: app/flatpak-builtins-build-bundle.c:691
#: app/flatpak-builtins-build-import-bundle.c:149
#: app/flatpak-builtins-build-init.c:281
#, fuzzy, c-format
msgid "'%s' is not a valid filename"
msgstr "A(z) „%s” nem érvényes név: %s"

#: app/flatpak-builtins-build-bundle.c:706
msgid "--oci-layer-compress value must be gzip or zstd"
msgstr ""

#: app/flatpak-builtins-build.c:49
msgid "Use Platform runtime rather than Sdk"
msgstr "Platform futtatókörnyezet használata az Sdk helyett"

#: app/flatpak-builtins-build.c:50
msgid "Make destination readonly"
msgstr "Cél írásvédetté tétele"

#: app/flatpak-builtins-build.c:51
msgid "Add bind mount"
msgstr "Kötési csatolás hozzáadása"

#: app/flatpak-builtins-build.c:51
msgid "DEST=SRC"
msgstr "CÉL=FORRÁS"

#: app/flatpak-builtins-build.c:52
msgid "Start build in this directory"
msgstr "Összeállítás indítása ebben a könyvtárban"

#: app/flatpak-builtins-build.c:52 app/flatpak-builtins-build.c:53
#: app/flatpak-builtins-build-init.c:64 app/flatpak-builtins-run.c:160
msgid "DIR"
msgstr "KÖNYVTÁR"

#: app/flatpak-builtins-build.c:53
msgid "Where to look for custom sdk dir (defaults to 'usr')"
msgstr "Hol keresse az egyéni sdk könyvtárat (alapértelmezetten „usr”)"

#: app/flatpak-builtins-build.c:54 app/flatpak-builtins-build-export.c:67
msgid "Use alternative file for the metadata"
msgstr "Alternatív fájl használata a metaadatokhoz"

#: app/flatpak-builtins-build.c:55 app/flatpak-builtins-run.c:177
msgid "Kill processes when the parent process dies"
msgstr "Folyamatok kilövése, ha a szülőfolyamat véget ér"

#: app/flatpak-builtins-build.c:56
msgid "Export application homedir directory to build"
msgstr "Az alkalmazás saját könyvtárának exportálása az összeállításba"

#: app/flatpak-builtins-build.c:57 app/flatpak-builtins-run.c:165
msgid "Log session bus calls"
msgstr "Munkamenetbusz-hívások naplózása"

#: app/flatpak-builtins-build.c:58 app/flatpak-builtins-run.c:166
msgid "Log system bus calls"
msgstr "Rendszerbusz-hívások naplózása"

#: app/flatpak-builtins-build.c:262
#, fuzzy
msgid "DIRECTORY [COMMAND [ARGUMENT…]] - Build in directory"
msgstr "KÖNYVTÁR [PARANCS [argumentumok…]] - Összeállítás a könyvtárban"

#: app/flatpak-builtins-build.c:285 app/flatpak-builtins-build-finish.c:656
msgid "DIRECTORY must be specified"
msgstr "A KÖNYVTÁR megadása kötelező"

#: app/flatpak-builtins-build.c:296 app/flatpak-builtins-build-export.c:887
#, c-format
msgid "Build directory %s not initialized, use flatpak build-init"
msgstr ""
"A(z) „%s” összeállítási könyvtár nincs előkészítve, a flatpak összeállítás-"
"előkészítő használata"

#: app/flatpak-builtins-build.c:315
msgid "metadata invalid, not application or runtime"
msgstr "a metaadat érvénytelen, nem alkalmazás vagy futtatókörnyezet"

#: app/flatpak-builtins-build.c:446
#, c-format
msgid "No extension point matching %s in %s"
msgstr "Nincs %s illeszkedésű kiterjesztéspont ebben: %s"

#: app/flatpak-builtins-build.c:635
#, c-format
msgid "Missing '=' in bind mount option '%s'"
msgstr "Hiányzó „=” a(z) „%s” kötési csatolás kapcsolóban"

#: app/flatpak-builtins-build.c:679 common/flatpak-run.c:3961
#, c-format
msgid "Unable to start app"
msgstr "Nem indítható el az alkalmazás"

#: app/flatpak-builtins-build-commit-from.c:58
msgid "Source repo dir"
msgstr "Forrástároló könyvtár"

#: app/flatpak-builtins-build-commit-from.c:58
msgid "SRC-REPO"
msgstr "FORRÁS-TÁROLÓ"

#: app/flatpak-builtins-build-commit-from.c:59
msgid "Source repo ref"
msgstr "Forrástároló hivatkozás"

#: app/flatpak-builtins-build-commit-from.c:59
msgid "SRC-REF"
msgstr "FORRÁS-HIVATKOZÁS"

#: app/flatpak-builtins-build-commit-from.c:64
#: app/flatpak-builtins-build-export.c:60
msgid "One line subject"
msgstr "Egysoros tárgy"

#: app/flatpak-builtins-build-commit-from.c:64
#: app/flatpak-builtins-build-export.c:60
msgid "SUBJECT"
msgstr "TÁRGY"

#: app/flatpak-builtins-build-commit-from.c:65
#: app/flatpak-builtins-build-export.c:61
msgid "Full description"
msgstr "Teljes leírás"

#: app/flatpak-builtins-build-commit-from.c:65
#: app/flatpak-builtins-build-export.c:61
msgid "BODY"
msgstr "TÖRZS"

#: app/flatpak-builtins-build-commit-from.c:66
#: app/flatpak-builtins-build-export.c:64
#: app/flatpak-builtins-build-import-bundle.c:51
msgid "Update the appstream branch"
msgstr "Az AppStream ág frissítése"

#: app/flatpak-builtins-build-commit-from.c:67
#: app/flatpak-builtins-build-export.c:65
#: app/flatpak-builtins-build-import-bundle.c:52
#: app/flatpak-builtins-build-update-repo.c:87
msgid "Don't update the summary"
msgstr "Ne frissítse az összegzést"

#: app/flatpak-builtins-build-commit-from.c:68
#: app/flatpak-builtins-build-export.c:68
#: app/flatpak-builtins-build-import-bundle.c:49
#: app/flatpak-builtins-build-sign.c:44
msgid "GPG Key ID to sign the commit with"
msgstr "GPG kulcsazonosító a kommit aláírásához"

#: app/flatpak-builtins-build-commit-from.c:70
#: app/flatpak-builtins-build-export.c:73
msgid "Mark build as end-of-life"
msgstr ""

#: app/flatpak-builtins-build-commit-from.c:70
#: app/flatpak-builtins-build-export.c:73
msgid "REASON"
msgstr ""

#: app/flatpak-builtins-build-commit-from.c:71
msgid ""
"Mark refs matching the OLDID prefix as end-of-life, to be replaced with the "
"given NEWID"
msgstr ""

#: app/flatpak-builtins-build-commit-from.c:71
msgid "OLDID=NEWID"
msgstr ""

#: app/flatpak-builtins-build-commit-from.c:72
#: app/flatpak-builtins-build-export.c:75
msgid "Set type of token needed to install this commit"
msgstr ""

#: app/flatpak-builtins-build-commit-from.c:72
#: app/flatpak-builtins-build-export.c:75
#, fuzzy
msgid "VAL"
msgstr "VÁLTOZÓ=ÉRTÉK"

#: app/flatpak-builtins-build-commit-from.c:73
#, fuzzy
msgid "Override the timestamp of the commit (NOW for current time)"
msgstr "A kommit időbélyegének felülírása"

#: app/flatpak-builtins-build-commit-from.c:73
#: app/flatpak-builtins-build-export.c:76
#, fuzzy
msgid "TIMESTAMP"
msgstr "ISO-8601-IDŐBÉLYEG"

#: app/flatpak-builtins-build-commit-from.c:75
#: app/flatpak-builtins-build-export.c:80
#: app/flatpak-builtins-build-import-bundle.c:53
#: app/flatpak-builtins-build-update-repo.c:97
#, fuzzy
msgid "Don't generate a summary index"
msgstr "Ne frissítse az összegzést"

#: app/flatpak-builtins-build-commit-from.c:278
#, fuzzy
msgid "DST-REPO [DST-REF…] - Make a new commit from existing commits"
msgstr ""
"CÉL-TÁROLÓ [CÉL-HIVATKOZÁS]… - Új kommit készítése a meglévő kommitok alapján"

#: app/flatpak-builtins-build-commit-from.c:285
msgid "DST-REPO must be specified"
msgstr "A CÉL-TÁROLÓ megadása kötelező"

#: app/flatpak-builtins-build-commit-from.c:293
msgid ""
"If --src-repo is not specified, exactly one destination ref must be specified"
msgstr ""
"Ha a --src-repo nincs megadva, akkor pontosan egy célhivatkozást kell megadni"

#: app/flatpak-builtins-build-commit-from.c:296
msgid ""
"If --src-ref is specified, exactly one destination ref must be specified"
msgstr ""
"Ha a --src-ref meg van adva, akkor pontosan egy célhivatkozást kell megadni"

#: app/flatpak-builtins-build-commit-from.c:299
#, fuzzy
msgid "Either --src-repo or --src-ref must be specified"
msgstr "Vagy a --src-repo, vagy a --src-ref megadása kötelező."

#: app/flatpak-builtins-build-commit-from.c:315
msgid "Invalid argument format of use  --end-of-life-rebase=OLDID=NEWID"
msgstr ""

#: app/flatpak-builtins-build-commit-from.c:321
#: app/flatpak-builtins-build-commit-from.c:324
#, c-format
msgid "Invalid name %s in --end-of-life-rebase"
msgstr ""

#: app/flatpak-builtins-build-commit-from.c:333
#: app/flatpak-builtins-build-export.c:1092
#, c-format
msgid "Could not parse '%s'"
msgstr ""

#: app/flatpak-builtins-build-commit-from.c:498
#, fuzzy
msgid "Can't commit from partial source commit"
msgstr "Nem lehet kommitolni részleges forráskommitból."

#: app/flatpak-builtins-build-commit-from.c:503
#, c-format
msgid "%s: no change\n"
msgstr "%s: nincs változás\n"

#: app/flatpak-builtins-build-export.c:62
msgid "Architecture to export for (must be host compatible)"
msgstr "Architektúra az exportáláshoz (a gazdával kompatibilisnek kell lennie)"

#: app/flatpak-builtins-build-export.c:63
msgid "Commit runtime (/usr), not /app"
msgstr "Futtatókörnyezet kommitolása (/usr), a /app helyett"

#: app/flatpak-builtins-build-export.c:66
msgid "Use alternative directory for the files"
msgstr "Alternatív könyvtár használata a fájlokhoz"

#: app/flatpak-builtins-build-export.c:66
msgid "SUBDIR"
msgstr "ALKÖNYVTÁR"

#: app/flatpak-builtins-build-export.c:69
msgid "Files to exclude"
msgstr "Kizárandó fájlok"

#: app/flatpak-builtins-build-export.c:69
#: app/flatpak-builtins-build-export.c:70
#: app/flatpak-builtins-build-update-repo.c:90
msgid "PATTERN"
msgstr "MINTA"

#: app/flatpak-builtins-build-export.c:70
msgid "Excluded files to include"
msgstr "Felvenni kívánt kizárt fájlok"

#: app/flatpak-builtins-build-export.c:74
msgid "Mark build as end-of-life, to be replaced with the given ID"
msgstr ""

#: app/flatpak-builtins-build-export.c:74
#: app/flatpak-builtins-document-list.c:49 app/flatpak-cli-transaction.c:1427
#, fuzzy
msgid "ID"
msgstr "Azonosító:"

#: app/flatpak-builtins-build-export.c:76
msgid "Override the timestamp of the commit"
msgstr "A kommit időbélyegének felülírása"

#: app/flatpak-builtins-build-export.c:77
#: app/flatpak-builtins-build-update-repo.c:75
#: app/flatpak-builtins-remote-add.c:83 app/flatpak-builtins-remote-list.c:54
#: app/flatpak-builtins-remote-modify.c:88
msgid "Collection ID"
msgstr "Gyűjteményazonosító"

#: app/flatpak-builtins-build-export.c:472
#, c-format
msgid "WARNING: Error running desktop-file-validate: %s\n"
msgstr "FIGYELMEZTETÉS: Hiba a desktop-file-validate futtatásakor: %s\n"

#: app/flatpak-builtins-build-export.c:480
#, c-format
msgid "WARNING: Error reading from desktop-file-validate: %s\n"
msgstr ""
"FIGYELMEZTETÉS: Hiba a desktop-file-validate kimenetének olvasásakor: %s\n"

#: app/flatpak-builtins-build-export.c:486
#, c-format
msgid "WARNING: Failed to validate desktop file %s: %s\n"
msgstr "FIGYELMEZTETÉS: Nem sikerült ellenőrizni a(z) %s asztali fájlt: %s\n"

#: app/flatpak-builtins-build-export.c:513
#, c-format
msgid "WARNING: Can't find Exec key in %s: %s\n"
msgstr "FIGYELMEZTETÉS: Nem található itt az Exec kulcs: %s: %s\n"

#: app/flatpak-builtins-build-export.c:521
#: app/flatpak-builtins-build-export.c:614
#, c-format
msgid "WARNING: Binary not found for Exec line in %s: %s\n"
msgstr ""
"FIGYELMEZTETÉS: Nem található itt az Exec sorban megadott bináris: %s: %s\n"

#: app/flatpak-builtins-build-export.c:529
#, c-format
msgid "WARNING: Icon not matching app id in %s: %s\n"
msgstr ""
"FIGYELMEZTETÉS: Nem egyezik az itt megadott ikon alkalmazásazonosítóval: %s: "
"%s\n"

#: app/flatpak-builtins-build-export.c:552
#, c-format
msgid "WARNING: Icon referenced in desktop file but not exported: %s\n"
msgstr ""
"FIGYELMEZTETÉS: Az ikon hivatkozva van az asztali fájlban, de nincs "
"exportálva: %s\n"

#: app/flatpak-builtins-build-export.c:719
#, c-format
msgid "Invalid uri type %s, only http/https supported"
msgstr "Érvénytelen URI-típus (%s), csak a http/https támogatott"

#: app/flatpak-builtins-build-export.c:737
#, c-format
msgid "Unable to find basename in %s, specify a name explicitly"
msgstr ""
"Nem sikerült megtalálni az alapnevet ebben: %s, pontosan adja meg a nevet"

#: app/flatpak-builtins-build-export.c:746
#, c-format
msgid "No slashes allowed in extra data name"
msgstr "A perjelek nem engedélyezettek a további adatok névében"

#: app/flatpak-builtins-build-export.c:758
#, c-format
msgid "Invalid format for sha256 checksum: '%s'"
msgstr "Érvénytelen formátum az sha256 ellenőrzőösszegnél: „%s”"

#: app/flatpak-builtins-build-export.c:768
#, c-format
msgid "Extra data sizes of zero not supported"
msgstr "Nulla méretű további adatméret nem támogatott"

#: app/flatpak-builtins-build-export.c:830
msgid ""
"LOCATION DIRECTORY [BRANCH] - Create a repository from a build directory"
msgstr "HELY KÖNYVTÁR [ÁG] - Tároló létrehozása egy összeállítási könyvtárból"

#: app/flatpak-builtins-build-export.c:838
msgid "LOCATION and DIRECTORY must be specified"
msgstr "A HELY és KÖNYVTÁR megadása kötelező"

#: app/flatpak-builtins-build-export.c:859
#: app/flatpak-builtins-remote-add.c:327
#, c-format
msgid "‘%s’ is not a valid collection ID: %s"
msgstr "A(z) „%s” nem érvényes gyűjteményazonosító: %s"

#: app/flatpak-builtins-build-export.c:904
#: app/flatpak-builtins-build-finish.c:684
msgid "No name specified in the metadata"
msgstr "Nincs név megadva a metaadatokban"

#: app/flatpak-builtins-build-export.c:1166
#, c-format
msgid "Commit: %s\n"
msgstr "Kommit: %s\n"

#: app/flatpak-builtins-build-export.c:1167
#, c-format
msgid "Metadata Total: %u\n"
msgstr "Metaadatok összesen: %u\n"

#: app/flatpak-builtins-build-export.c:1168
#, c-format
msgid "Metadata Written: %u\n"
msgstr "Kiírt metaadatok: %u\n"

#: app/flatpak-builtins-build-export.c:1169
#, c-format
msgid "Content Total: %u\n"
msgstr "Tartalom összesen: %u\n"

#: app/flatpak-builtins-build-export.c:1170
#, c-format
msgid "Content Written: %u\n"
msgstr "Kiírt tartalom: %u\n"

#: app/flatpak-builtins-build-export.c:1171
#, c-format
msgid "Content Bytes Written:"
msgstr "Kiírt tartalom bájtokban:"

#: app/flatpak-builtins-build-finish.c:52
msgid "Command to set"
msgstr "Beállítandó parancs"

#: app/flatpak-builtins-build-finish.c:52 app/flatpak-builtins-run.c:159
#: app/flatpak-main.c:209
msgid "COMMAND"
msgstr "PARANCS"

#: app/flatpak-builtins-build-finish.c:53
msgid "Flatpak version to require"
msgstr "A szükséges flatpak-verzió"

#: app/flatpak-builtins-build-finish.c:53
msgid "MAJOR.MINOR.MICRO"
msgstr "FŐ.KISEBB.APRÓ"

#: app/flatpak-builtins-build-finish.c:54
msgid "Don't process exports"
msgstr "Ne dolgozza fel az exportokat"

#: app/flatpak-builtins-build-finish.c:55
msgid "Extra data info"
msgstr "További adatinformációk"

#: app/flatpak-builtins-build-finish.c:56 app/flatpak-builtins-build-init.c:63
msgid "Add extension point info"
msgstr "Kiterjesztéspont-információk hozzáadása"

#: app/flatpak-builtins-build-finish.c:56 app/flatpak-builtins-build-init.c:63
msgid "NAME=VARIABLE[=VALUE]"
msgstr "NÉV=VÁLTOZÓ[=ÉRTÉK]"

#: app/flatpak-builtins-build-finish.c:57
#, fuzzy
msgid "Remove extension point info"
msgstr "Kiterjesztéspont-információk hozzáadása"

#: app/flatpak-builtins-build-finish.c:57
#: app/flatpak-builtins-build-update-repo.c:79 app/flatpak-builtins-info.c:58
#: app/flatpak-builtins-remote-add.c:88 app/flatpak-builtins-remote-modify.c:94
#: app/flatpak-main.c:182
msgid "NAME"
msgstr "NÉV"

#: app/flatpak-builtins-build-finish.c:58
msgid "Set extension priority (only for extensions)"
msgstr "Kiterjesztés prioritás beállítása (csak kiterjesztésekhez)"

#: app/flatpak-builtins-build-finish.c:58
#, fuzzy
msgid "VALUE"
msgstr "VÁLTOZÓ=ÉRTÉK"

#: app/flatpak-builtins-build-finish.c:59
msgid "Change the sdk used for the app"
msgstr "Az alkalmazáshoz használt sdk megváltoztatása"

#: app/flatpak-builtins-build-finish.c:59
msgid "SDK"
msgstr "SDK"

#: app/flatpak-builtins-build-finish.c:60
msgid "Change the runtime used for the app"
msgstr "Az alkalmazáshoz használt futtatókörnyezet megváltoztatása"

#: app/flatpak-builtins-build-finish.c:60 app/flatpak-builtins-build-init.c:54
#: app/flatpak-builtins-list.c:53 app/flatpak-builtins-remote-ls.c:58
#: app/flatpak-builtins-run.c:163
msgid "RUNTIME"
msgstr "FUTTATÓKÖRNYEZET"

#: app/flatpak-builtins-build-finish.c:61
msgid "Set generic metadata option"
msgstr "Általános metaadat lehetőség beállítása"

#: app/flatpak-builtins-build-finish.c:61
msgid "GROUP=KEY[=VALUE]"
msgstr "CSOPORT=KULCS[=ÉRTÉK]"

#: app/flatpak-builtins-build-finish.c:62
#, fuzzy
msgid "Don't inherit permissions from runtime"
msgstr "Az alkalmazás írási jogosultságának visszavonása"

#: app/flatpak-builtins-build-finish.c:155
#, fuzzy, c-format
msgid "Not exporting %s, wrong extension\n"
msgstr "A(z) %s nem kerül exportálásra, hibás előtag\n"

#: app/flatpak-builtins-build-finish.c:163
#, fuzzy, c-format
msgid "Not exporting %s, non-allowed export filename\n"
msgstr "A(z) %s nem kerül exportálásra, hibás előtag\n"

#: app/flatpak-builtins-build-finish.c:167
#, c-format
msgid "Exporting %s\n"
msgstr "%s exportálása\n"

#: app/flatpak-builtins-build-finish.c:440
#, c-format
msgid "More than one executable found\n"
msgstr "Több mint egy futtatható állomány található\n"

#: app/flatpak-builtins-build-finish.c:451
#, c-format
msgid "Using %s as command\n"
msgstr "A(z) %s használata parancsként\n"

#: app/flatpak-builtins-build-finish.c:456
#, c-format
msgid "No executable found\n"
msgstr "Nem található futtatható állomány\n"

#: app/flatpak-builtins-build-finish.c:511
#, fuzzy, c-format
msgid "Invalid --require-version argument: %s"
msgstr "Érvénytelen require-flatpak argumentum: %s\n"

#: app/flatpak-builtins-build-finish.c:543
#, c-format
msgid "Too few elements in --extra-data argument %s"
msgstr "Túl kevés elem a(z) %s --extra-data argumentumban"

#: app/flatpak-builtins-build-finish.c:575
#, c-format
msgid ""
"Too few elements in --metadata argument %s, format should be "
"GROUP=KEY[=VALUE]]"
msgstr ""
"Túl kevés elem a(z) %s --metadata argumentumban, a formátumnak "
"CSOPORT=KULCS[=ÉRTÉK] alakban kell lennie"

#: app/flatpak-builtins-build-finish.c:597
#: app/flatpak-builtins-build-init.c:458
#, c-format
msgid ""
"Too few elements in --extension argument %s, format should be "
"NAME=VAR[=VALUE]"
msgstr ""
"Túl kevés elem a(z) %s --extension argumentumban, a formátumnak "
"NÉV=VÁLTOZÓ[=ÉRTÉK] alakban kell lennie"

#: app/flatpak-builtins-build-finish.c:603
#: app/flatpak-builtins-build-init.c:461
#, fuzzy, c-format
msgid "Invalid extension name %s"
msgstr "Ismeretlen %s D-Bus név\n"

#: app/flatpak-builtins-build-finish.c:646
msgid "DIRECTORY - Finalize a build directory"
msgstr "KÖNYVTÁR - Egy összeállítási könyvtár befejezése"

#: app/flatpak-builtins-build-finish.c:668
#, c-format
msgid "Build directory %s not initialized"
msgstr "A(z) „%s” összeállítási könyvtár nincs előkészítve"

#: app/flatpak-builtins-build-finish.c:689
#, c-format
msgid "Build directory %s already finalized"
msgstr "A(z) „%s” összeállítási könyvtár már be lett fejezve"

#: app/flatpak-builtins-build-finish.c:702
#, c-format
msgid "Please review the exported files and the metadata\n"
msgstr "Nézze át az exportált fájlokat és a metaadatokat\n"

#: app/flatpak-builtins-build-import-bundle.c:47
msgid "Override the ref used for the imported bundle"
msgstr "Az importált csomaghoz használt hivatkozás felülbírálása"

#: app/flatpak-builtins-build-import-bundle.c:47
msgid "REF"
msgstr "HIVATKOZÁS"

#: app/flatpak-builtins-build-import-bundle.c:48
msgid "Import oci image instead of flatpak bundle"
msgstr "Egy OCI-lemezkép importálása flatpak csomag helyett"

#: app/flatpak-builtins-build-import-bundle.c:77
#: app/flatpak-builtins-build-import-bundle.c:105
#, c-format
msgid "Importing %s (%s)\n"
msgstr "%s importálása (%s)\n"

#: app/flatpak-builtins-build-import-bundle.c:126
msgid "LOCATION FILENAME - Import a file bundle into a local repository"
msgstr "HELY FÁJLNÉV - Egy fájlcsomag importálása egy helyi tárolóba"

#: app/flatpak-builtins-build-import-bundle.c:133
msgid "LOCATION and FILENAME must be specified"
msgstr "A HELY és FÁJLNÉV megadása kötelező"

#: app/flatpak-builtins-build-init.c:53 app/flatpak-builtins-info.c:55
#: app/flatpak-builtins-run.c:158
msgid "Arch to use"
msgstr "Használandó architektúra"

#: app/flatpak-builtins-build-init.c:54
msgid "Initialize var from named runtime"
msgstr "Változó előkészítése egy elnevezett futtatókörnyezetből"

#: app/flatpak-builtins-build-init.c:55
msgid "Initialize apps from named app"
msgstr "Alkalmazások előkészítése egy elnevezett alkalmazásból"

#: app/flatpak-builtins-build-init.c:55
msgid "APP"
msgstr "ALKALMAZÁS"

#: app/flatpak-builtins-build-init.c:56
msgid "Specify version for --base"
msgstr "Verzió megadása a --base kapcsolóhoz"

#: app/flatpak-builtins-build-init.c:56 app/flatpak-builtins-run.c:164
msgid "VERSION"
msgstr "VERZIÓ"

#: app/flatpak-builtins-build-init.c:57
msgid "Include this base extension"
msgstr "Ezen alapkiterjesztés felvétele"

#: app/flatpak-builtins-build-init.c:57 app/flatpak-builtins-build-init.c:62
msgid "EXTENSION"
msgstr "KITERJESZTÉS"

#: app/flatpak-builtins-build-init.c:58
msgid "Extension tag to use if building extension"
msgstr ""

#: app/flatpak-builtins-build-init.c:58
#, fuzzy
msgid "EXTENSION_TAG"
msgstr "KITERJESZTÉS"

#: app/flatpak-builtins-build-init.c:59
msgid "Initialize /usr with a writable copy of the sdk"
msgstr "Az /usr előkészítése az sdk írható másolatával"

#: app/flatpak-builtins-build-init.c:60
msgid "Specify the build type (app, runtime, extension)"
msgstr ""
"Az összeállítás-típus megadása (alkalmazás, futtatókörnyezet, kiterjesztés)"

#: app/flatpak-builtins-build-init.c:60
msgid "TYPE"
msgstr "TÍPUS"

#: app/flatpak-builtins-build-init.c:61
msgid "Add a tag"
msgstr "Címke hozzáadása"

#: app/flatpak-builtins-build-init.c:61
msgid "TAG"
msgstr "CÍMKE"

#: app/flatpak-builtins-build-init.c:62
msgid "Include this sdk extension in /usr"
msgstr "Ezen sdk kiterjesztés felvétele az /usr könyvtárba"

#: app/flatpak-builtins-build-init.c:64
msgid "Where to store sdk (defaults to 'usr')"
msgstr "Hol tárolja az sdk-t (alapértelmezetten „usr”)"

#: app/flatpak-builtins-build-init.c:65
msgid "Re-initialize the sdk/var"
msgstr "Az sdk vagy változó újra előkészítése"

#: app/flatpak-builtins-build-init.c:118
#, fuzzy, c-format
msgid "Requested extension %s/%s/%s is only partially installed"
msgstr "A kért %s kiterjesztés csak részlegesen van telepítve"

#: app/flatpak-builtins-build-init.c:147
#, fuzzy, c-format
msgid "Requested extension %s/%s/%s not installed"
msgstr "A szükséges %s kiterjesztés nincs telepítve"

#: app/flatpak-builtins-build-init.c:207
msgid ""
"DIRECTORY APPNAME SDK RUNTIME [BRANCH] - Initialize a directory for building"
msgstr ""
"KÖNYVTÁR ALKALMAZÁSNÉV SDK FUTTATÓKÖRNYEZET [ÁG] - Könyvtár előkészítése az "
"összeállításhoz"

#: app/flatpak-builtins-build-init.c:214
msgid "RUNTIME must be specified"
msgstr "A FUTTATÓKÖRNYEZET megadása kötelező"

#: app/flatpak-builtins-build-init.c:235
#, c-format
msgid "'%s' is not a valid build type name, use app, runtime or extension"
msgstr ""
"A(z) „%s” nem érvényes összeállítás-típus név, alkalmazás, futtatókörnyezet "
"vagy kiterjesztés használata szükséges"

#: app/flatpak-builtins-build-init.c:241 app/flatpak-builtins-override.c:79
#, c-format
msgid "'%s' is not a valid application name: %s"
msgstr "A(z) „%s” nem érvényes alkalmazásnév: %s"

#: app/flatpak-builtins-build-init.c:295
#, c-format
msgid "Build directory %s already initialized"
msgstr "A(z) „%s” összeállítási könyvtár már elő van készítve"

#: app/flatpak-builtins-build-sign.c:42 app/flatpak-builtins-install.c:67
#: app/flatpak-builtins-remote-info.c:54
msgid "Arch to install for"
msgstr "Telepítés ezen architektúrára"

#: app/flatpak-builtins-build-sign.c:43 app/flatpak-builtins-create-usb.c:48
#: app/flatpak-builtins-install.c:74 app/flatpak-builtins-remote-info.c:56
#: app/flatpak-builtins-uninstall.c:58 app/flatpak-builtins-update.c:64
msgid "Look for runtime with the specified name"
msgstr "A megadott nevű futtatókörnyezet keresése"

#: app/flatpak-builtins-build-sign.c:66
msgid "LOCATION [ID [BRANCH]] - Sign an application or runtime"
msgstr "HELY [AZONOSÍTÓ [ÁG]] - Egy alkalmazás vagy futtatókörnyezet aláírása"

#: app/flatpak-builtins-build-sign.c:73
#: app/flatpak-builtins-build-update-repo.c:499
#: app/flatpak-builtins-remote-add.c:320 app/flatpak-builtins-repo.c:739
msgid "LOCATION must be specified"
msgstr "A HELY megadása kötelező"

#: app/flatpak-builtins-build-sign.c:94
msgid "No gpg key ids specified"
msgstr "Nincsenek megadva GPG kulcsazonosítók"

#: app/flatpak-builtins-build-update-repo.c:68
msgid "Redirect this repo to a new URL"
msgstr "Ezen tároló átirányítása egy új URL-re"

#: app/flatpak-builtins-build-update-repo.c:69
msgid "A nice name to use for this repository"
msgstr "Egy szép, ehhez a tárolóhoz használandó név"

#: app/flatpak-builtins-build-update-repo.c:69
#: app/flatpak-builtins-remote-add.c:77 app/flatpak-builtins-remote-modify.c:82
msgid "TITLE"
msgstr "CÍM"

#: app/flatpak-builtins-build-update-repo.c:70
#, fuzzy
msgid "A one-line comment for this repository"
msgstr "Egy szép, ehhez a tárolóhoz használandó név"

#: app/flatpak-builtins-build-update-repo.c:70
#: app/flatpak-builtins-remote-add.c:78 app/flatpak-builtins-remote-modify.c:83
#, fuzzy
msgid "COMMENT"
msgstr "KOMMIT"

#: app/flatpak-builtins-build-update-repo.c:71
#, fuzzy
msgid "A full-paragraph description for this repository"
msgstr "Ehhez a tárolóhoz használandó alapértelmezett ág"

#: app/flatpak-builtins-build-update-repo.c:71
#: app/flatpak-builtins-remote-add.c:79 app/flatpak-builtins-remote-modify.c:84
msgid "DESCRIPTION"
msgstr ""

#: app/flatpak-builtins-build-update-repo.c:72
#, fuzzy
msgid "URL for a website for this repository"
msgstr "Egy szép, ehhez a tárolóhoz használandó név"

#: app/flatpak-builtins-build-update-repo.c:73
#, fuzzy
msgid "URL for an icon for this repository"
msgstr "Egy szép, ehhez a tárolóhoz használandó név"

#: app/flatpak-builtins-build-update-repo.c:74
msgid "Default branch to use for this repository"
msgstr "Ehhez a tárolóhoz használandó alapértelmezett ág"

#: app/flatpak-builtins-build-update-repo.c:74
#: app/flatpak-builtins-remote-add.c:82 app/flatpak-builtins-remote-modify.c:87
#: app/flatpak-builtins-repo.c:713 app/flatpak-builtins-repo.c:714
#: app/flatpak-builtins-run.c:161
msgid "BRANCH"
msgstr "ÁG"

#: app/flatpak-builtins-build-update-repo.c:75
#: app/flatpak-builtins-remote-add.c:83 app/flatpak-builtins-remote-modify.c:88
msgid "COLLECTION-ID"
msgstr "GYŰJTEMÉNY-AZONOSÍTÓ"

#. Translators: A sideload is when you install from a local USB drive rather than the Internet.
#: app/flatpak-builtins-build-update-repo.c:77
#, fuzzy
msgid ""
"Permanently deploy collection ID to client remote configurations, only for "
"sideload support"
msgstr ""
"Gyűjteményazonosítók állandó beállítása az ügyfél távoli tároló "
"beállításaiban"

#: app/flatpak-builtins-build-update-repo.c:78
msgid "Permanently deploy collection ID to client remote configurations"
msgstr ""
"Gyűjteményazonosítók állandó beállítása az ügyfél távoli tároló "
"beállításaiban"

#: app/flatpak-builtins-build-update-repo.c:79
#, fuzzy
msgid "Name of authenticator for this repository"
msgstr "Egy szép, ehhez a tárolóhoz használandó név"

#: app/flatpak-builtins-build-update-repo.c:80
#, fuzzy
msgid "Autoinstall authenticator for this repository"
msgstr "Egy szép, ehhez a tárolóhoz használandó név"

#: app/flatpak-builtins-build-update-repo.c:81
#, fuzzy
msgid "Don't autoinstall authenticator for this repository"
msgstr "Ehhez a tárolóhoz használandó alapértelmezett ág"

#: app/flatpak-builtins-build-update-repo.c:82
#: app/flatpak-builtins-remote-add.c:89
#, fuzzy
msgid "Authenticator option"
msgstr "Súgólehetőségek megjelenítése"

#: app/flatpak-builtins-build-update-repo.c:82
#: app/flatpak-builtins-remote-add.c:89 app/flatpak-builtins-remote-modify.c:95
#, fuzzy
msgid "KEY=VALUE"
msgstr "VÁLTOZÓ=ÉRTÉK"

#: app/flatpak-builtins-build-update-repo.c:83
msgid "Import new default GPG public key from FILE"
msgstr "Új alapértelmezett GPG nyilvános kulcs importálása FÁJLBÓL"

#: app/flatpak-builtins-build-update-repo.c:84
msgid "GPG Key ID to sign the summary with"
msgstr "GPG kulcsazonosító az összegzés aláírásához"

#: app/flatpak-builtins-build-update-repo.c:86
msgid "Generate delta files"
msgstr "Delta fájlok előállítása"

#: app/flatpak-builtins-build-update-repo.c:88
#, fuzzy
msgid "Don't update the appstream branch"
msgstr "Az AppStream ág frissítése"

#: app/flatpak-builtins-build-update-repo.c:89
msgid "Max parallel jobs when creating deltas (default: NUMCPUs)"
msgstr ""

#: app/flatpak-builtins-build-update-repo.c:89
msgid "NUM-JOBS"
msgstr ""

#: app/flatpak-builtins-build-update-repo.c:90
#, fuzzy
msgid "Don't create deltas matching refs"
msgstr "Ne frissítse a kapcsolódó hivatkozásokat"

#: app/flatpak-builtins-build-update-repo.c:91
msgid "Prune unused objects"
msgstr "Nem használt objektumok törlése"

#: app/flatpak-builtins-build-update-repo.c:92
msgid "Prune but don't actually remove anything"
msgstr ""

#: app/flatpak-builtins-build-update-repo.c:93
msgid "Only traverse DEPTH parents for each commit (default: -1=infinite)"
msgstr ""
"Csak MÉLYSÉG szülők bejárása az egyes kommitoknál (alapértelmezett: -1 = "
"végtelen)"

#: app/flatpak-builtins-build-update-repo.c:93
msgid "DEPTH"
msgstr "MÉLYSÉG"

#: app/flatpak-builtins-build-update-repo.c:223
#, c-format
msgid "Generating delta: %s (%.10s)\n"
msgstr "Delta előállítása: %s (%.10s)\n"

#: app/flatpak-builtins-build-update-repo.c:225
#, c-format
msgid "Generating delta: %s (%.10s-%.10s)\n"
msgstr "Delta előállítása: %s (%.10s-%.10s)\n"

#: app/flatpak-builtins-build-update-repo.c:233
#, c-format
msgid "Failed to generate delta %s (%.10s): "
msgstr "Nem sikerült a(z) %s (%.10s) delta előállítása: "

#: app/flatpak-builtins-build-update-repo.c:236
#, c-format
msgid "Failed to generate delta %s (%.10s-%.10s): "
msgstr "Nem sikerült a(z) %s (%.10s-%.10s) delta előállítása: "

#: app/flatpak-builtins-build-update-repo.c:492
msgid "LOCATION - Update repository metadata"
msgstr "HELY - Tároló metaadatainak frissítése"

#: app/flatpak-builtins-build-update-repo.c:609
#, c-format
msgid "Updating appstream branch\n"
msgstr "Az AppStream ág frissítése\n"

#: app/flatpak-builtins-build-update-repo.c:638
#, c-format
msgid "Updating summary\n"
msgstr "Összegzés frissítése\n"

#: app/flatpak-builtins-build-update-repo.c:664
#, c-format
msgid "Total objects: %u\n"
msgstr "Objektumok összesen: %u\n"

#: app/flatpak-builtins-build-update-repo.c:666
#, c-format
msgid "No unreachable objects\n"
msgstr "Nincsenek elérhetetlen objektumok\n"

#: app/flatpak-builtins-build-update-repo.c:668
#, c-format
msgid "Deleted %u objects, %s freed\n"
msgstr "%u objektum törölve, %s felszabadítva\n"

#: app/flatpak-builtins-config.c:41
msgid "List configuration keys and values"
msgstr "A konfigurációs kulcsok és értékek listája"

#: app/flatpak-builtins-config.c:42
msgid "Get configuration for KEY"
msgstr "Konfiguráció lekérése a KULCShoz"

#: app/flatpak-builtins-config.c:43
msgid "Set configuration for KEY to VALUE"
msgstr "A konfigurációs KULCS beállítása az ÉRTÉKre"

#: app/flatpak-builtins-config.c:44
msgid "Unset configuration for KEY"
msgstr "KULCS konfigurációs értékének eltávolítása"

#: app/flatpak-builtins-config.c:149
#, c-format
msgid "'%s' does not look like a language/locale code"
msgstr ""

#: app/flatpak-builtins-config.c:172
#, c-format
msgid "'%s' does not look like a language code"
msgstr ""

#: app/flatpak-builtins-config.c:190
#, fuzzy, c-format
msgid "'%s' is not a valid value (use 'true' or 'false')"
msgstr "A(z) „%s” nem érvényes tároló"

#: app/flatpak-builtins-config.c:262
#, c-format
msgid "Unknown configure key '%s'"
msgstr "Ismeretlen „%s” konfigurációs kulcs"

#: app/flatpak-builtins-config.c:284
#, fuzzy
msgid "Too many arguments for --list"
msgstr "Túl sok argumentum"

#: app/flatpak-builtins-config.c:314 app/flatpak-builtins-config.c:362
#, fuzzy
msgid "You must specify KEY"
msgstr "Meg kell adnia egy kulcsot"

#: app/flatpak-builtins-config.c:316
#, fuzzy
msgid "Too many arguments for --get"
msgstr "Túl sok argumentum"

#: app/flatpak-builtins-config.c:338
#, fuzzy
msgid "You must specify KEY and VALUE"
msgstr "Meg kell adnia egy kulcsot"

#: app/flatpak-builtins-config.c:340
#, fuzzy
msgid "Too many arguments for --set"
msgstr "Túl sok argumentum"

#: app/flatpak-builtins-config.c:364
#, fuzzy
msgid "Too many arguments for --unset"
msgstr "Túl sok argumentum"

#: app/flatpak-builtins-config.c:383
msgid "[KEY [VALUE]] - Manage configuration"
msgstr "[KULCS [ÉRTÉK]] – Konfiguráció kezelése"

#: app/flatpak-builtins-config.c:394
#, fuzzy
msgid "Can only use one of --list, --get, --set or --unset"
msgstr "Meg kell adnia a --list, --get, --set vagy --unset egyikét"

#: app/flatpak-builtins-config.c:408
msgid "Must specify one of --list, --get, --set or --unset"
msgstr "Meg kell adnia a --list, --get, --set vagy --unset egyikét"

#: app/flatpak-builtins-create-usb.c:45 app/flatpak-builtins-install.c:75
#: app/flatpak-builtins-remote-info.c:57 app/flatpak-builtins-uninstall.c:59
#: app/flatpak-builtins-update.c:65
msgid "Look for app with the specified name"
msgstr "Alkalmazás keresése a megadott névvel"

#: app/flatpak-builtins-create-usb.c:46
#, fuzzy
msgid "Arch to copy"
msgstr "Megjelenítendő architektúra"

#: app/flatpak-builtins-create-usb.c:47
#, fuzzy
msgid "DEST"
msgstr "CÉL=FORRÁS"

#: app/flatpak-builtins-create-usb.c:49
msgid "Allow partial commits in the created repo"
msgstr ""

#: app/flatpak-builtins-create-usb.c:125 app/flatpak-builtins-create-usb.c:165
#, c-format
msgid ""
"Warning: Related ref ‘%s’ is partially installed. Use --allow-partial to "
"suppress this message.\n"
msgstr ""

#: app/flatpak-builtins-create-usb.c:158
#, c-format
msgid "Warning: Omitting related ref ‘%s’ because it is not installed.\n"
msgstr ""

#: app/flatpak-builtins-create-usb.c:175
#, c-format
msgid ""
"Warning: Omitting related ref ‘%s’ because its remote ‘%s’ does not have a "
"collection ID set.\n"
msgstr ""

#: app/flatpak-builtins-create-usb.c:187
#, c-format
msgid "Warning: Omitting related ref ‘%s’ because it's extra-data.\n"
msgstr ""

#: app/flatpak-builtins-create-usb.c:262 app/flatpak-builtins-create-usb.c:637
#, c-format
msgid ""
"Remote ‘%s’ does not have a collection ID set, which is required for P2P "
"distribution of ‘%s’."
msgstr ""

#: app/flatpak-builtins-create-usb.c:272
#, c-format
msgid "Warning: Omitting ref ‘%s’ (runtime of ‘%s’) because it's extra-data.\n"
msgstr ""

#: app/flatpak-builtins-create-usb.c:484
msgid "MOUNT-PATH [REF…] - Copy apps or runtimes onto removable media"
msgstr ""

#: app/flatpak-builtins-create-usb.c:493
#, fuzzy
msgid "MOUNT-PATH and REF must be specified"
msgstr "A TÁVOLI és HIVATKOZÁS megadása kötelező"

#: app/flatpak-builtins-create-usb.c:607
#, fuzzy, c-format
msgid "Ref ‘%s’ found in multiple installations: %s. You must specify one."
msgstr "A(z) „%s” távoli tároló több telepítésben is megtalálható:\n"

#: app/flatpak-builtins-create-usb.c:620
#, c-format
msgid "Refs must all be in the same installation (found in %s and %s)."
msgstr ""

#: app/flatpak-builtins-create-usb.c:670
#, c-format
msgid ""
"Warning: Ref ‘%s’ is partially installed. Use --allow-partial to suppress "
"this message.\n"
msgstr ""

#: app/flatpak-builtins-create-usb.c:681
#, c-format
msgid "Installed ref ‘%s’ is extra-data, and cannot be distributed offline"
msgstr ""

#: app/flatpak-builtins-create-usb.c:721
#, fuzzy, c-format
msgid "Warning: Couldn't update repo metadata for remote ‘%s’: %s\n"
msgstr ""
"Figyelmeztetése Nem sikerült frissíteni a(z) %s további metaadatait: %s\n"

#: app/flatpak-builtins-create-usb.c:751
#, fuzzy, c-format
msgid "Warning: Couldn't update appstream data for remote ‘%s’ arch ‘%s’: %s\n"
msgstr "Figyelmeztetés: a függőségek nem találhatóak: %s\n"

#. Print a warning if both appstream and appstream2 are missing
#: app/flatpak-builtins-create-usb.c:784
#, fuzzy, c-format
msgid ""
"Warning: Couldn't find appstream data for remote ‘%s’ arch ‘%s’: %s; %s\n"
msgstr "Figyelmeztetés: a függőségek nem találhatóak: %s\n"

#. Appstream2 is only for efficiency, so just print a debug message
#: app/flatpak-builtins-create-usb.c:790
#, fuzzy, c-format
msgid "Couldn't find appstream2 data for remote ‘%s’ arch ‘%s’: %s\n"
msgstr "Az appstream adatok frissítése a(z) %s távoli tárolóhoz\n"

#: app/flatpak-builtins-document-export.c:62
msgid "Create a unique document reference"
msgstr "Egyedi dokumentumhivatkozás létrehozása"

#: app/flatpak-builtins-document-export.c:63
msgid "Make the document transient for the current session"
msgstr "A dokumentum átmenetivé tétele a jelenlegi munkamenethez"

#: app/flatpak-builtins-document-export.c:64
msgid "Don't require the file to exist already"
msgstr "Ne követelje meg, hogy a fájl már létezzen"

#: app/flatpak-builtins-document-export.c:65
msgid "Give the app read permissions"
msgstr "Olvasási jogosultság adása az alkalmazásnak"

#: app/flatpak-builtins-document-export.c:66
msgid "Give the app write permissions"
msgstr "Írási jogosultság adása az alkalmazásnak"

#: app/flatpak-builtins-document-export.c:67
msgid "Give the app delete permissions"
msgstr "Törlési jogosultság adása az alkalmazásnak"

#: app/flatpak-builtins-document-export.c:68
msgid "Give the app permissions to grant further permissions"
msgstr ""
"További jogosultságok adására vonatkozó jogosultság adása az alkalmazásnak"

#: app/flatpak-builtins-document-export.c:69
msgid "Revoke read permissions of the app"
msgstr "Az alkalmazás olvasási jogosultságának visszavonása"

#: app/flatpak-builtins-document-export.c:70
msgid "Revoke write permissions of the app"
msgstr "Az alkalmazás írási jogosultságának visszavonása"

#: app/flatpak-builtins-document-export.c:71
msgid "Revoke delete permissions of the app"
msgstr "Az alkalmazás törlési jogosultságának visszavonása"

#: app/flatpak-builtins-document-export.c:72
msgid "Revoke the permission to grant further permissions"
msgstr "További jogosultságok adására vonatkozó jogosultság visszavonása"

#: app/flatpak-builtins-document-export.c:73
msgid "Add permissions for this app"
msgstr "Jogosultságok hozzáadása ehhez az alkalmazáshoz"

#: app/flatpak-builtins-document-export.c:73
msgid "APPID"
msgstr "ALKALMAZÁSAZONOSÍTÓ"

#: app/flatpak-builtins-document-export.c:100
msgid "FILE - Export a file to apps"
msgstr "FÁJL - Fájl exportálása az alkalmazásokba"

#: app/flatpak-builtins-document-export.c:109
#: app/flatpak-builtins-document-info.c:72
#: app/flatpak-builtins-document-unexport.c:67
msgid "FILE must be specified"
msgstr "A FÁJL megadása kötelező"

#: app/flatpak-builtins-document-info.c:63
msgid "FILE - Get information about an exported file"
msgstr "FÁJL - Információk lekérése egy exportált fájlról"

#: app/flatpak-builtins-document-info.c:100
#: app/flatpak-builtins-document-unexport.c:94
#, c-format
msgid "Not exported\n"
msgstr "Nincs exportálva\n"

#: app/flatpak-builtins-document-list.c:43 app/flatpak-builtins-history.c:53
#: app/flatpak-builtins-list.c:54 app/flatpak-builtins-ps.c:43
#: app/flatpak-builtins-remote-list.c:45 app/flatpak-builtins-remote-ls.c:59
#: app/flatpak-builtins-search.c:38
#, fuzzy
msgid "What information to show"
msgstr "Információk kiírása egy tárolóról"

#: app/flatpak-builtins-document-list.c:43 app/flatpak-builtins-history.c:53
#: app/flatpak-builtins-list.c:54 app/flatpak-builtins-ps.c:43
#: app/flatpak-builtins-remote-list.c:45 app/flatpak-builtins-remote-ls.c:59
#: app/flatpak-builtins-search.c:38
msgid "FIELD,…"
msgstr ""

#: app/flatpak-builtins-document-list.c:44 app/flatpak-builtins-history.c:54
#: app/flatpak-builtins-list.c:52 app/flatpak-builtins-permission-list.c:43
#: app/flatpak-builtins-permission-show.c:43 app/flatpak-builtins-ps.c:44
#: app/flatpak-builtins-remote-list.c:46 app/flatpak-builtins-remote-ls.c:63
#: app/flatpak-builtins-repo.c:717 app/flatpak-builtins-search.c:39
#, fuzzy
msgid "Show output in JSON format"
msgstr "További információk megjelenítése"

#: app/flatpak-builtins-document-list.c:49
#, fuzzy
msgid "Show the document ID"
msgstr "Csak futtatókörnyezetek megjelenítése"

#: app/flatpak-builtins-document-list.c:50
msgid "Path"
msgstr ""

#: app/flatpak-builtins-document-list.c:50
#: app/flatpak-builtins-document-list.c:51
#, fuzzy
msgid "Show the document path"
msgstr "Csak futtatókörnyezetek megjelenítése"

#: app/flatpak-builtins-document-list.c:51 app/flatpak-builtins-list.c:66
#: app/flatpak-builtins-remote-ls.c:74
msgid "Origin"
msgstr "Eredet"

#: app/flatpak-builtins-document-list.c:52 app/flatpak-builtins-history.c:62
#: app/flatpak-builtins-ps.c:52
#, fuzzy
msgid "Application"
msgstr "Alkalmazásazonosító"

#: app/flatpak-builtins-document-list.c:52
#, fuzzy
msgid "Show applications with permission"
msgstr "Jogosultságok megjelenítése"

#: app/flatpak-builtins-document-list.c:53
#: app/flatpak-builtins-permission-list.c:182
#: app/flatpak-builtins-permission-show.c:145
#, fuzzy
msgid "Permissions"
msgstr "Jogosultságok megjelenítése"

#: app/flatpak-builtins-document-list.c:53
#, fuzzy
msgid "Show permissions for applications"
msgstr "Jogosultságok felülbírálása egy alkalmazásnál"

#: app/flatpak-builtins-document-list.c:161
#, fuzzy, c-format
msgid "No documents found\n"
msgstr "Nincs találat"

#: app/flatpak-builtins-document-list.c:180
msgid "[APPID] - List exported files"
msgstr "[ALKALMAZÁSAZONOSÍTÓ] - Exportált fájlok felsorolása"

#: app/flatpak-builtins-document-unexport.c:43
#, fuzzy
msgid "Specify the document ID"
msgstr "Csak futtatókörnyezetek megjelenítése"

#: app/flatpak-builtins-document-unexport.c:58
msgid "FILE - Unexport a file to apps"
msgstr "FÁJL - Fájl alkalmazásokba exportálásának visszavonása"

#: app/flatpak-builtins-enter.c:88
#, fuzzy
msgid "INSTANCE COMMAND [ARGUMENT…] - Run a command inside a running sandbox"
msgstr ""
"HOMOKOZÓS-PID [PARANCS [argumentumok…]] - Parancs futtatása egy futó "
"homokozón belül"

#: app/flatpak-builtins-enter.c:111
#, fuzzy
msgid "INSTANCE and COMMAND must be specified"
msgstr "A HOMOKOZÓS-PID és PARANCS megadása kötelező"

#: app/flatpak-builtins-enter.c:138
#, fuzzy, c-format
msgid "%s is neither a pid nor an application or instance ID"
msgstr "A(z) „%s” nem érvényes alkalmazásnév: %s"

#: app/flatpak-builtins-enter.c:144
msgid "entering not supported (need unprivileged user namespaces, or sudo -E)"
msgstr ""

#: app/flatpak-builtins-enter.c:145
#, c-format
msgid "No such pid %s"
msgstr "Nincs ilyen PID: %s"

#: app/flatpak-builtins-enter.c:158
msgid "Can't read cwd"
msgstr "A cwd nem olvasható"

#: app/flatpak-builtins-enter.c:163
msgid "Can't read root"
msgstr "A root nem olvasható"

#: app/flatpak-builtins-enter.c:191
#, c-format
msgid "Invalid %s namespace for pid %d"
msgstr "Érvénytelen %s névtér a(z) %d pid-hez"

#: app/flatpak-builtins-enter.c:202
#, c-format
msgid "Invalid %s namespace for self"
msgstr "Érvénytelen %s névtér saját magához"

#: app/flatpak-builtins-enter.c:216
#, c-format
msgid "Can't open %s namespace: %s"
msgstr "Nem lehet megnyitni a(z) %s névteret: %s"

#: app/flatpak-builtins-enter.c:226
msgid "entering not supported (need unprivileged user namespaces)"
msgstr ""

#: app/flatpak-builtins-enter.c:227
#, c-format
msgid "Can't enter %s namespace: %s"
msgstr "Nem lehet belépni a(z) %s névtérbe: %s"

#: app/flatpak-builtins-enter.c:234
msgid "Can't chdir"
msgstr "A chdir sikertelen"

#: app/flatpak-builtins-enter.c:237
msgid "Can't chroot"
msgstr "A chroot sikertelen"

#: app/flatpak-builtins-enter.c:240
msgid "Can't switch gid"
msgstr "Nem állítható át a GID"

#: app/flatpak-builtins-enter.c:243
msgid "Can't switch uid"
msgstr "Nem állítható át az UID"

#: app/flatpak-builtins-history.c:50
msgid "Only show changes after TIME"
msgstr ""

#: app/flatpak-builtins-history.c:50 app/flatpak-builtins-history.c:51
#, fuzzy
msgid "TIME"
msgstr "FUTTATÓKÖRNYEZET"

#: app/flatpak-builtins-history.c:51
msgid "Only show changes before TIME"
msgstr ""

#: app/flatpak-builtins-history.c:52
#, fuzzy
msgid "Show newest entries first"
msgstr "Kiterjesztések megjelenítése"

#: app/flatpak-builtins-history.c:59
msgid "Time"
msgstr ""

#: app/flatpak-builtins-history.c:59
#, fuzzy
msgid "Show when the change happened"
msgstr "Csak futtatókörnyezetek megjelenítése"

#: app/flatpak-builtins-history.c:60
msgid "Change"
msgstr ""

#: app/flatpak-builtins-history.c:60
msgid "Show the kind of change"
msgstr ""

#: app/flatpak-builtins-history.c:61 app/flatpak-builtins-list.c:68
#: app/flatpak-builtins-remote-ls.c:75 app/flatpak-builtins-repo.c:335
msgid "Ref"
msgstr "Hivatkozás"

#: app/flatpak-builtins-history.c:61 app/flatpak-builtins-list.c:68
#: app/flatpak-builtins-remote-ls.c:75
#, fuzzy
msgid "Show the ref"
msgstr "Hivatkozás megjelenítése"

#: app/flatpak-builtins-history.c:62
#, fuzzy
msgid "Show the application/runtime ID"
msgstr "Alkalmazásazonosító"

#: app/flatpak-builtins-history.c:63 app/flatpak-builtins-list.c:64
#: app/flatpak-builtins-ps.c:53 app/flatpak-builtins-remote-ls.c:73
#: app/flatpak-cli-transaction.c:1435
#, fuzzy
msgid "Arch"
msgstr "Architektúra:"

#: app/flatpak-builtins-history.c:63 app/flatpak-builtins-list.c:64
#: app/flatpak-builtins-ps.c:53 app/flatpak-builtins-remote-ls.c:73
msgid "Show the architecture"
msgstr ""

#: app/flatpak-builtins-history.c:64 app/flatpak-builtins-list.c:63
#: app/flatpak-builtins-ps.c:54 app/flatpak-builtins-remote-ls.c:72
#: app/flatpak-builtins-search.c:48 app/flatpak-cli-transaction.c:1438
msgid "Branch"
msgstr "Ág"

#: app/flatpak-builtins-history.c:64 app/flatpak-builtins-list.c:63
#: app/flatpak-builtins-remote-ls.c:72
#, fuzzy
msgid "Show the branch"
msgstr "Csak futtatókörnyezetek megjelenítése"

#: app/flatpak-builtins-history.c:65 app/flatpak-builtins-list.c:67
#, fuzzy
msgid "Installation"
msgstr "Telepítve"

#: app/flatpak-builtins-history.c:65
#, fuzzy
msgid "Show the affected installation"
msgstr "Felhasználói telepítések megjelenítése"

#: app/flatpak-builtins-history.c:66 app/flatpak-cli-transaction.c:1452
#, fuzzy
msgid "Remote"
msgstr "Távoli tárolók"

#: app/flatpak-builtins-history.c:66
#, fuzzy
msgid "Show the remote"
msgstr "Letiltott távoliak megjelenítése"

#: app/flatpak-builtins-history.c:67 app/flatpak-builtins-ps.c:55
#: app/flatpak-builtins-remote-ls.c:76
msgid "Commit"
msgstr "Kommit"

#: app/flatpak-builtins-history.c:67
#, fuzzy
msgid "Show the current commit"
msgstr "Csak futtatókörnyezetek megjelenítése"

#: app/flatpak-builtins-history.c:68
#, fuzzy
msgid "Old Commit"
msgstr " Kommit:"

#: app/flatpak-builtins-history.c:68
#, fuzzy
msgid "Show the previous commit"
msgstr "Csak futtatókörnyezetek megjelenítése"

#: app/flatpak-builtins-history.c:69
#, fuzzy
msgid "Show the remote URL"
msgstr "Csak futtatókörnyezetek megjelenítése"

#: app/flatpak-builtins-history.c:70 app/flatpak-cli-transaction.c:700
msgid "User"
msgstr ""

#: app/flatpak-builtins-history.c:70
#, fuzzy
msgid "Show the user doing the change"
msgstr "Csak futtatókörnyezetek megjelenítése"

#: app/flatpak-builtins-history.c:71
msgid "Tool"
msgstr ""

#: app/flatpak-builtins-history.c:71
msgid "Show the tool that was used"
msgstr ""

#: app/flatpak-builtins-history.c:72 app/flatpak-builtins-list.c:62
#: app/flatpak-builtins-remote-ls.c:71 app/flatpak-builtins-search.c:47
msgid "Version"
msgstr "Verzió"

#: app/flatpak-builtins-history.c:72
#, fuzzy
msgid "Show the Flatpak version"
msgstr "Alkalmazásazonosító"

#: app/flatpak-builtins-history.c:91
#, fuzzy, c-format
msgid "Failed to get journal data (%s): %s"
msgstr "Nem sikerült a(z) %s helyi további adat betöltése: %s"

#: app/flatpak-builtins-history.c:146
#, fuzzy, c-format
msgid "Failed to open journal: %s"
msgstr "Nem sikerült megnyitni a flatpak-információs átmeneti fájlt: %s"

#: app/flatpak-builtins-history.c:153
#, fuzzy, c-format
msgid "Failed to add match to journal: %s"
msgstr "Nem sikerült a(z) %s helyi további adat betöltése: %s"

#: app/flatpak-builtins-history.c:471
msgid " - Show history"
msgstr ""

#: app/flatpak-builtins-history.c:490
#, fuzzy, c-format
msgid "Failed to parse the --since option"
msgstr "Nem hozható létre szinkronizálási cső"

#: app/flatpak-builtins-history.c:501
#, c-format
msgid "Failed to parse the --until option"
msgstr ""

#: app/flatpak-builtins-info.c:56
msgid "Show user installations"
msgstr "Felhasználói telepítések megjelenítése"

#: app/flatpak-builtins-info.c:57
msgid "Show system-wide installations"
msgstr "Rendszerszintű telepítések megjelenítése"

#: app/flatpak-builtins-info.c:58
msgid "Show specific system-wide installations"
msgstr "Bizonyos rendszerszintű telepítések megjelenítése"

#: app/flatpak-builtins-info.c:59 app/flatpak-builtins-remote-info.c:59
msgid "Show ref"
msgstr "Hivatkozás megjelenítése"

#: app/flatpak-builtins-info.c:60 app/flatpak-builtins-remote-info.c:60
msgid "Show commit"
msgstr "Kommit megjelenítése"

#: app/flatpak-builtins-info.c:61
msgid "Show origin"
msgstr "Eredet megjelenítése"

#: app/flatpak-builtins-info.c:62
msgid "Show size"
msgstr "Méret megjelenítése"

#: app/flatpak-builtins-info.c:63 app/flatpak-builtins-remote-info.c:62
msgid "Show metadata"
msgstr "Metaadatok megjelenítése"

#: app/flatpak-builtins-info.c:64 app/flatpak-builtins-remote-info.c:63
#, fuzzy
msgid "Show runtime"
msgstr "Csak futtatókörnyezetek megjelenítése"

#: app/flatpak-builtins-info.c:65 app/flatpak-builtins-remote-info.c:64
#, fuzzy
msgid "Show sdk"
msgstr "Méret megjelenítése"

#: app/flatpak-builtins-info.c:66
msgid "Show permissions"
msgstr "Jogosultságok megjelenítése"

#: app/flatpak-builtins-info.c:67
msgid "Query file access"
msgstr "Fájlhozzáférés lekérése"

#: app/flatpak-builtins-info.c:67 app/flatpak-builtins-install.c:82
#: app/flatpak-builtins-install.c:88 app/flatpak-builtins-preinstall.c:68
#: app/flatpak-builtins-run.c:182 app/flatpak-builtins-run.c:184
#: app/flatpak-builtins-update.c:67 app/flatpak-builtins-update.c:71
msgid "PATH"
msgstr "ÚTVONAL"

#: app/flatpak-builtins-info.c:68
msgid "Show extensions"
msgstr "Kiterjesztések megjelenítése"

#: app/flatpak-builtins-info.c:69
#, fuzzy
msgid "Show location"
msgstr "Súgólehetőségek megjelenítése"

#: app/flatpak-builtins-info.c:116
#, fuzzy
msgid "NAME [BRANCH] - Get info about an installed app or runtime"
msgstr ""
"NÉV [ÁG] - Információk lekérése a telepített alkalmazásról és/vagy "
"futtatókörnyezetről"

#: app/flatpak-builtins-info.c:123 app/flatpak-builtins-remote-add.c:317
#: app/flatpak-builtins-remote-delete.c:63
msgid "NAME must be specified"
msgstr "A NÉV megadása kötelező"

#: app/flatpak-builtins-info.c:196
msgid "ref not present in origin"
msgstr "a hivatkozás nincs jelen az eredetben"

#: app/flatpak-builtins-info.c:211 app/flatpak-builtins-remote-info.c:217
#, c-format
msgid "Warning: Commit has no flatpak metadata\n"
msgstr "Figyelmeztetés: a kommitnak nincs flatpak metaadata\n"

#: app/flatpak-builtins-info.c:217 app/flatpak-builtins-info.c:259
#: app/flatpak-builtins-info.c:455 app/flatpak-builtins-info.c:513
#: app/flatpak-builtins-remote-info.c:236
#: app/flatpak-builtins-remote-info.c:271
msgid "ID:"
msgstr "Azonosító:"

#: app/flatpak-builtins-info.c:218 app/flatpak-builtins-info.c:260
#: app/flatpak-builtins-remote-info.c:237
#: app/flatpak-builtins-remote-info.c:272
msgid "Ref:"
msgstr "Hivatkozás:"

#: app/flatpak-builtins-info.c:219 app/flatpak-builtins-info.c:261
#: app/flatpak-builtins-remote-info.c:238
#: app/flatpak-builtins-remote-info.c:273
msgid "Arch:"
msgstr "Architektúra:"

#: app/flatpak-builtins-info.c:220 app/flatpak-builtins-info.c:262
#: app/flatpak-builtins-remote-info.c:239
#: app/flatpak-builtins-remote-info.c:274
msgid "Branch:"
msgstr "Ág:"

#: app/flatpak-builtins-info.c:222 app/flatpak-builtins-info.c:264
#: app/flatpak-builtins-remote-info.c:241
#: app/flatpak-builtins-remote-info.c:276
#, fuzzy
msgid "Version:"
msgstr "Verzió"

#: app/flatpak-builtins-info.c:224 app/flatpak-builtins-info.c:266
#: app/flatpak-builtins-remote-info.c:243
#: app/flatpak-builtins-remote-info.c:278
msgid "License:"
msgstr ""

#: app/flatpak-builtins-info.c:226 app/flatpak-builtins-info.c:269
#: app/flatpak-builtins-remote-info.c:245
#: app/flatpak-builtins-remote-info.c:280
#, fuzzy
msgid "Collection:"
msgstr "Gyűjteményazonosító:"

#: app/flatpak-builtins-info.c:227 app/flatpak-builtins-info.c:270
#: app/flatpak-builtins-info.c:458 app/flatpak-builtins-info.c:516
#, fuzzy
msgid "Installation:"
msgstr "Telepítve"

#: app/flatpak-builtins-info.c:228 app/flatpak-builtins-info.c:271
#: app/flatpak-builtins-info.c:459 app/flatpak-builtins-info.c:517
#: app/flatpak-builtins-remote-info.c:249
#: app/flatpak-builtins-remote-info.c:284
#, fuzzy
msgid "Installed Size:"
msgstr "Telepített méret:"

#: app/flatpak-builtins-info.c:231 app/flatpak-builtins-info.c:279
#: app/flatpak-builtins-remote-info.c:252
#: app/flatpak-builtins-remote-info.c:288
msgid "Runtime:"
msgstr "Futtatókörnyezet:"

#: app/flatpak-builtins-info.c:232 app/flatpak-builtins-info.c:288
#: app/flatpak-builtins-remote-info.c:253
#: app/flatpak-builtins-remote-info.c:293
msgid "Sdk:"
msgstr ""

#: app/flatpak-builtins-info.c:235 app/flatpak-builtins-info.c:313
#: app/flatpak-builtins-remote-info.c:256
#: app/flatpak-builtins-remote-info.c:319
msgid "Date:"
msgstr "Dátum:"

#: app/flatpak-builtins-info.c:237 app/flatpak-builtins-info.c:311
#: app/flatpak-builtins-remote-info.c:258
#: app/flatpak-builtins-remote-info.c:317
msgid "Subject:"
msgstr "Tárgy:"

#: app/flatpak-builtins-info.c:240 app/flatpak-builtins-info.c:295
msgid "Active commit:"
msgstr "Aktív kommit:"

#: app/flatpak-builtins-info.c:241 app/flatpak-builtins-info.c:298
msgid "Latest commit:"
msgstr "Legutolsó kommit:"

#: app/flatpak-builtins-info.c:244 app/flatpak-builtins-info.c:303
#: app/flatpak-builtins-info.c:457 app/flatpak-builtins-info.c:515
#: app/flatpak-builtins-remote-info.c:259
#: app/flatpak-builtins-remote-info.c:298
msgid "Commit:"
msgstr "Kommit:"

#: app/flatpak-builtins-info.c:246 app/flatpak-builtins-info.c:308
#: app/flatpak-builtins-remote-info.c:261
#: app/flatpak-builtins-remote-info.c:303
msgid "Parent:"
msgstr "Szülő:"

#: app/flatpak-builtins-info.c:248 app/flatpak-builtins-info.c:321
#, fuzzy
msgid "Alt-id:"
msgstr "alternatív azonosító:"

#: app/flatpak-builtins-info.c:250 app/flatpak-builtins-info.c:325
#: app/flatpak-builtins-remote-info.c:263
#: app/flatpak-builtins-remote-info.c:308
msgid "End-of-life:"
msgstr ""

#: app/flatpak-builtins-info.c:252 app/flatpak-builtins-info.c:330
#: app/flatpak-builtins-remote-info.c:265
#: app/flatpak-builtins-remote-info.c:313
msgid "End-of-life-rebase:"
msgstr ""

#: app/flatpak-builtins-info.c:254 app/flatpak-builtins-info.c:317
#, fuzzy
msgid "Subdirectories:"
msgstr "Telepített alkönyvtárak:"

#: app/flatpak-builtins-info.c:255 app/flatpak-builtins-info.c:454
#: app/flatpak-builtins-info.c:512
msgid "Extension:"
msgstr "Kiterjesztés:"

#: app/flatpak-builtins-info.c:267 app/flatpak-builtins-info.c:456
#: app/flatpak-builtins-info.c:514
msgid "Origin:"
msgstr "Eredet:"

#: app/flatpak-builtins-info.c:460 app/flatpak-builtins-info.c:522
msgid "Subpaths:"
msgstr "Alútvonalak:"

#: app/flatpak-builtins-info.c:478
msgid "unmaintained"
msgstr ""

#: app/flatpak-builtins-info.c:480 app/flatpak-builtins-info.c:482
msgid "unknown"
msgstr ""

#: app/flatpak-builtins-install.c:68 app/flatpak-builtins-preinstall.c:57
msgid "Don't pull, only install from local cache"
msgstr "Ne kérje le, csak telepítse a helyi gyorsítótárból"

#: app/flatpak-builtins-install.c:69 app/flatpak-builtins-preinstall.c:58
#: app/flatpak-builtins-update.c:60
msgid "Don't deploy, only download to local cache"
msgstr "Ne telepítse, csak töltse le a helyi gyorsítótárba"

#: app/flatpak-builtins-install.c:70 app/flatpak-builtins-preinstall.c:59
msgid "Don't install related refs"
msgstr "Ne telepítse a kapcsolódó hivatkozásokat"

#: app/flatpak-builtins-install.c:71 app/flatpak-builtins-preinstall.c:60
#: app/flatpak-builtins-update.c:62
msgid "Don't verify/install runtime dependencies"
msgstr "Ne ellenőrizze/telepítse a futtatókörnyezet függőségeit"

#: app/flatpak-builtins-install.c:72
msgid "Don't automatically pin explicit installs"
msgstr ""

#: app/flatpak-builtins-install.c:73 app/flatpak-builtins-preinstall.c:61
#: app/flatpak-builtins-update.c:63
msgid "Don't use static deltas"
msgstr "Ne használjon statikus deltákat"

#: app/flatpak-builtins-install.c:76 app/flatpak-builtins-preinstall.c:62
msgid "Additionally install the SDK used to build the given refs"
msgstr ""

#: app/flatpak-builtins-install.c:77 app/flatpak-builtins-preinstall.c:63
msgid ""
"Additionally install the debug info for the given refs and their dependencies"
msgstr ""

#: app/flatpak-builtins-install.c:78
msgid "Assume LOCATION is a .flatpak single-file bundle"
msgstr "Feltételezzük, hogy a HELY egy .flatpak önálló fájlból álló csomag"

#: app/flatpak-builtins-install.c:79
msgid "Assume LOCATION is a .flatpakref application description"
msgstr "Feltételezzük, hogy a HELY egy .flatpakref alkalmazás-leírás"

#: app/flatpak-builtins-install.c:80
msgid "Assume LOCATION is containers-transports(5) reference to an OCI image"
msgstr ""

#: app/flatpak-builtins-install.c:81
msgid "Check bundle signatures with GPG key from FILE (- for stdin)"
msgstr ""
"Csomag aláírásának ellenőrzése GPG kulccsal a FÁJLBÓL (- a szabványos "
"bemenethez)"

#: app/flatpak-builtins-install.c:82
msgid "Only install this subpath"
msgstr "Csak ezen alútvonal telepítése"

#: app/flatpak-builtins-install.c:83 app/flatpak-builtins-preinstall.c:64
#: app/flatpak-builtins-uninstall.c:63 app/flatpak-builtins-update.c:68
msgid "Automatically answer yes for all questions"
msgstr "Automatikusan válaszoljon igennel minden kérdésre"

#: app/flatpak-builtins-install.c:84 app/flatpak-builtins-preinstall.c:65
msgid "Uninstall first if already installed"
msgstr "Eltávolítás először, ha már telepítve van"

#: app/flatpak-builtins-install.c:85 app/flatpak-builtins-preinstall.c:66
#: app/flatpak-builtins-uninstall.c:64 app/flatpak-builtins-update.c:69
msgid "Produce minimal output and don't ask questions"
msgstr ""

#: app/flatpak-builtins-install.c:86
#, fuzzy
msgid "Update install if already installed"
msgstr "Eltávolítás először, ha már telepítve van"

#. Translators: A sideload is when you install from a local USB drive rather than the Internet.
#: app/flatpak-builtins-install.c:88 app/flatpak-builtins-preinstall.c:68
#: app/flatpak-builtins-update.c:71
msgid "Use this local repo for sideloads"
msgstr ""

#: app/flatpak-builtins-install.c:178
msgid "Bundle filename must be specified"
msgstr "A csomagfájlnév megadása kötelező"

#: app/flatpak-builtins-install.c:188
msgid "Remote bundles are not supported"
msgstr "A távoli csomagok nem támogatottak"

#: app/flatpak-builtins-install.c:231
msgid "Filename or uri must be specified"
msgstr "A fájlnév vagy URI megadása kötelező"

#: app/flatpak-builtins-install.c:295
#, fuzzy
msgid "Image location must be specified"
msgstr "A TÁVOLI és HIVATKOZÁS megadása kötelező"

#: app/flatpak-builtins-install.c:345
#, fuzzy
msgid "[LOCATION/REMOTE] [REF…] - Install applications or runtimes"
msgstr ""
"HELY/TÁVOLI [HIVATKOZÁS…] - Alkalmazások vagy futtatókörnyezetek telepítése"

#: app/flatpak-builtins-install.c:378
#, fuzzy
msgid "At least one REF must be specified"
msgstr "A TÁVOLI és HIVATKOZÁS megadása kötelező"

#: app/flatpak-builtins-install.c:392
#, fuzzy, c-format
msgid "Looking for matches…\n"
msgstr "Frissítések keresése…\n"

#: app/flatpak-builtins-install.c:513
#, fuzzy, c-format
msgid "No remote refs found for ‘%s’"
msgstr "Nem találhatók felülbírálások ehhez: %s"

#: app/flatpak-builtins-install.c:573 app/flatpak-builtins-uninstall.c:405
#: common/flatpak-ref-utils.c:689 common/flatpak-ref-utils.c:1595
#, fuzzy, c-format
msgid "Invalid branch %s: %s"
msgstr "Alapértelmezett ág: %s\n"

#: app/flatpak-builtins-install.c:606
#, fuzzy, c-format
msgid "Nothing matches %s in local repository for remote %s"
msgstr "Hiba a helyi tárolóban keresésnél: %s"

#: app/flatpak-builtins-install.c:608
#, fuzzy, c-format
msgid "Nothing matches %s in remote %s"
msgstr "Semmi sem egyezik: %s"

#: app/flatpak-builtins-install.c:629
#, fuzzy, c-format
msgid "Skipping: %s\n"
msgstr "%s exportálása\n"

#: app/flatpak-builtins-kill.c:110
#, fuzzy, c-format
msgid "%s is not running"
msgstr "A(z) %s nem érhető el"

#: app/flatpak-builtins-kill.c:136
#, fuzzy
msgid "INSTANCE - Stop a running application"
msgstr ""
"\n"
" Futó alkalmazások"

#: app/flatpak-builtins-kill.c:144 app/flatpak-builtins-ps.c:256
#, fuzzy
msgid "Extra arguments given"
msgstr "További adatinformációk"

#: app/flatpak-builtins-kill.c:150
#, fuzzy
msgid "Must specify the app to kill"
msgstr "Meg kell adnia a kulcsot és az értéket is"

#: app/flatpak-builtins-list.c:47
msgid "Show extra information"
msgstr "További információk megjelenítése"

#: app/flatpak-builtins-list.c:48
msgid "List installed runtimes"
msgstr "Telepített futtatókörnyezetek felsorolása"

#: app/flatpak-builtins-list.c:49
msgid "List installed applications"
msgstr "Telepített alkalmazások felsorolása"

#: app/flatpak-builtins-list.c:50
msgid "Arch to show"
msgstr "Megjelenítendő architektúra"

#: app/flatpak-builtins-list.c:51 app/flatpak-builtins-remote-ls.c:57
msgid "List all refs (including locale/debug)"
msgstr ""
"Összes hivatkozás felsorolása (területi beállítás és hibakeresési elemekkel "
"együtt)"

#: app/flatpak-builtins-list.c:53 app/flatpak-builtins-remote-ls.c:58
#, fuzzy
msgid "List all applications using RUNTIME"
msgstr "Telepített alkalmazások felsorolása"

#: app/flatpak-builtins-list.c:59 app/flatpak-builtins-remote-list.c:51
#: app/flatpak-builtins-remote-ls.c:68 app/flatpak-builtins-search.c:44
msgid "Name"
msgstr "Név"

#: app/flatpak-builtins-list.c:59 app/flatpak-builtins-remote-list.c:51
#: app/flatpak-builtins-remote-ls.c:68 app/flatpak-builtins-search.c:44
#, fuzzy
msgid "Show the name"
msgstr "Csak futtatókörnyezetek megjelenítése"

#: app/flatpak-builtins-list.c:60 app/flatpak-builtins-remote-list.c:60
#: app/flatpak-builtins-remote-ls.c:69 app/flatpak-builtins-search.c:45
msgid "Description"
msgstr "Leírás"

#: app/flatpak-builtins-list.c:60 app/flatpak-builtins-remote-ls.c:69
#: app/flatpak-builtins-search.c:45
#, fuzzy
msgid "Show the description"
msgstr "Alkalmazásazonosító"

#: app/flatpak-builtins-list.c:61 app/flatpak-builtins-remote-ls.c:70
#: app/flatpak-builtins-search.c:46
msgid "Application ID"
msgstr "Alkalmazásazonosító"

#: app/flatpak-builtins-list.c:61 app/flatpak-builtins-ps.c:52
#: app/flatpak-builtins-remote-ls.c:70 app/flatpak-builtins-search.c:46
#, fuzzy
msgid "Show the application ID"
msgstr "Alkalmazásazonosító"

#: app/flatpak-builtins-list.c:62 app/flatpak-builtins-remote-ls.c:71
#: app/flatpak-builtins-search.c:47
#, fuzzy
msgid "Show the version"
msgstr "Alkalmazásazonosító"

#: app/flatpak-builtins-list.c:65 app/flatpak-builtins-ps.c:56
#: app/flatpak-builtins-remote-ls.c:77
#, fuzzy
msgid "Runtime"
msgstr "Futtatókörnyezet:"

#: app/flatpak-builtins-list.c:65
#, fuzzy
msgid "Show the used runtime"
msgstr "Csak futtatókörnyezetek megjelenítése"

#: app/flatpak-builtins-list.c:66 app/flatpak-builtins-remote-ls.c:74
#, fuzzy
msgid "Show the origin remote"
msgstr "Eredet megjelenítése"

#: app/flatpak-builtins-list.c:67
#, fuzzy
msgid "Show the installation"
msgstr "Felhasználói telepítések megjelenítése"

#: app/flatpak-builtins-list.c:69
msgid "Active commit"
msgstr "Aktív kommit"

#: app/flatpak-builtins-list.c:69 app/flatpak-builtins-remote-ls.c:76
#, fuzzy
msgid "Show the active commit"
msgstr "Csak futtatókörnyezetek megjelenítése"

#: app/flatpak-builtins-list.c:70
msgid "Latest commit"
msgstr "Legutolsó kommit"

#: app/flatpak-builtins-list.c:70
#, fuzzy
msgid "Show the latest commit"
msgstr "Csak futtatókörnyezetek megjelenítése"

#: app/flatpak-builtins-list.c:71 app/flatpak-builtins-remote-ls.c:78
msgid "Installed size"
msgstr "Telepített méret"

#: app/flatpak-builtins-list.c:71 app/flatpak-builtins-remote-ls.c:78
#, fuzzy
msgid "Show the installed size"
msgstr "Telepített méret"

#: app/flatpak-builtins-list.c:72 app/flatpak-builtins-remote-list.c:58
#: app/flatpak-builtins-remote-ls.c:80 app/flatpak-builtins-repo.c:340
msgid "Options"
msgstr "Beállítások"

#: app/flatpak-builtins-list.c:72 app/flatpak-builtins-remote-list.c:58
#: app/flatpak-builtins-remote-ls.c:80
#, fuzzy
msgid "Show options"
msgstr "Súgólehetőségek megjelenítése"

#: app/flatpak-builtins-list.c:180
#, fuzzy, c-format
msgid "Unable to load details of %s: %s"
msgstr "További metaadatok frissítése a(z) %s távoli összegzéséből\n"

#: app/flatpak-builtins-list.c:190
#, fuzzy, c-format
msgid "Unable to inspect current version of %s: %s"
msgstr "Nem hozható létre szinkronizálási cső"

#: app/flatpak-builtins-list.c:408
msgid " - List installed apps and/or runtimes"
msgstr " - Telepített alkalmazások és/vagy futtatókörnyezetek felsorolása"

#: app/flatpak-builtins-make-current.c:38
msgid "Arch to make current for"
msgstr "Aktuálissá tétel ezen architektúrára"

#: app/flatpak-builtins-make-current.c:58
msgid "APP BRANCH - Make branch of application current"
msgstr "ALKALMAZÁS ÁG - Az alkalmazás ágának aktuálissá tétele"

#: app/flatpak-builtins-make-current.c:69 app/flatpak-builtins-run.c:260
msgid "APP must be specified"
msgstr "Az ALKALMAZÁS megadása kötelező"

#: app/flatpak-builtins-make-current.c:84
msgid "BRANCH must be specified"
msgstr "Az ÁG megadása kötelező"

#: app/flatpak-builtins-make-current.c:97
#, c-format
msgid "App %s branch %s is not installed"
msgstr "A(z) %s alkalmazás, %s ág nincs telepítve"

#: app/flatpak-builtins-mask.c:42
#, fuzzy
msgid "Remove matching masks"
msgstr "Távoli tárolók"

#: app/flatpak-builtins-mask.c:54
msgid ""
"[PATTERN…] - disable updates and automatic installation matching patterns"
msgstr ""

#: app/flatpak-builtins-mask.c:73
#, c-format
msgid "No masked patterns\n"
msgstr ""

#: app/flatpak-builtins-mask.c:78
#, c-format
msgid "Masked patterns:\n"
msgstr ""

#: app/flatpak-builtins-override.c:42
msgid "Remove existing overrides"
msgstr ""

#: app/flatpak-builtins-override.c:43
msgid "Show existing overrides"
msgstr ""

#: app/flatpak-builtins-override.c:59
msgid "[APP] - Override settings [for application]"
msgstr "[ALKALMAZÁS] – Beállítások felülbírálása az alkalmazáshoz"

#: app/flatpak-builtins-permission-list.c:143
msgid "[TABLE] [ID] - List permissions"
msgstr ""

#: app/flatpak-builtins-permission-list.c:179
#: app/flatpak-builtins-permission-show.c:142
msgid "Table"
msgstr ""

#: app/flatpak-builtins-permission-list.c:180
#: app/flatpak-builtins-permission-show.c:143
#, fuzzy
msgid "Object"
msgstr "Tárgy:"

#: app/flatpak-builtins-permission-list.c:181
#: app/flatpak-builtins-permission-show.c:144
msgid "App"
msgstr ""

#: app/flatpak-builtins-permission-list.c:183
#: app/flatpak-builtins-permission-show.c:146
msgid "Data"
msgstr ""

#: app/flatpak-builtins-permission-remove.c:120
#, fuzzy
msgid "TABLE ID [APP_ID] - Remove item from permission store"
msgstr "Az alkalmazás írási jogosultságának visszavonása"

#: app/flatpak-builtins-permission-remove.c:129
#: app/flatpak-builtins-permission-set.c:120
#, fuzzy
msgid "Too few arguments"
msgstr "Túl sok argumentum"

#: app/flatpak-builtins-permission-reset.c:43
#, fuzzy
msgid "Reset all permissions"
msgstr "Jogosultságok megjelenítése"

#: app/flatpak-builtins-permission-reset.c:144
#, fuzzy
msgid "APP_ID - Reset permissions for an app"
msgstr "Jogosultságok hozzáadása ehhez az alkalmazáshoz"

#: app/flatpak-builtins-permission-reset.c:153
#: app/flatpak-builtins-permission-show.c:124
#, fuzzy
msgid "Wrong number of arguments"
msgstr "Túl sok argumentum"

#: app/flatpak-builtins-permission-set.c:42
msgid "Associate DATA with the entry"
msgstr ""

#: app/flatpak-builtins-permission-set.c:42
msgid "DATA"
msgstr ""

#: app/flatpak-builtins-permission-set.c:111
msgid "TABLE ID APP_ID [PERMISSION...] - Set permissions"
msgstr ""

#: app/flatpak-builtins-permission-set.c:132
#, fuzzy, c-format
msgid "Failed to parse '%s' as GVariant: "
msgstr "Nem sikerült olvasni a(z) %s kommitot: "

#: app/flatpak-builtins-permission-show.c:115
#, fuzzy
msgid "APP_ID - Show permissions for an app"
msgstr "Jogosultságok hozzáadása ehhez az alkalmazáshoz"

#: app/flatpak-builtins-pin.c:44
#, fuzzy
msgid "Remove matching pins"
msgstr "Távoli tárolók"

#: app/flatpak-builtins-pin.c:56
msgid "[PATTERN…] - disable automatic removal of runtimes matching patterns"
msgstr ""

#: app/flatpak-builtins-pin.c:75
#, c-format
msgid "No pinned patterns\n"
msgstr ""

#: app/flatpak-builtins-pin.c:80
#, c-format
msgid "Pinned patterns:\n"
msgstr ""

#: app/flatpak-builtins-preinstall.c:80
msgid "- Install flatpaks that are part of the operating system"
msgstr ""

#: app/flatpak-builtins-preinstall.c:118
#, fuzzy, c-format
msgid "Nothing to do.\n"
msgstr "Semmi sem egyezik: %s"

#: app/flatpak-builtins-ps.c:49
#, fuzzy
msgid "Instance"
msgstr "Telepítve"

#: app/flatpak-builtins-ps.c:49
#, fuzzy
msgid "Show the instance ID"
msgstr "Csak futtatókörnyezetek megjelenítése"

#: app/flatpak-builtins-ps.c:50 app/flatpak-builtins-run.c:178
#, fuzzy
msgid "PID"
msgstr "ALKALMAZÁSAZONOSÍTÓ"

#: app/flatpak-builtins-ps.c:50
msgid "Show the PID of the wrapper process"
msgstr ""

#: app/flatpak-builtins-ps.c:51
msgid "Child-PID"
msgstr ""

#: app/flatpak-builtins-ps.c:51
msgid "Show the PID of the sandbox process"
msgstr ""

#: app/flatpak-builtins-ps.c:54 app/flatpak-builtins-search.c:48
#, fuzzy
msgid "Show the application branch"
msgstr "Architektúrák és ágak megjelenítése"

#: app/flatpak-builtins-ps.c:55
#, fuzzy
msgid "Show the application commit"
msgstr "Súgólehetőségek megjelenítése"

#: app/flatpak-builtins-ps.c:56
#, fuzzy
msgid "Show the runtime ID"
msgstr "Csak futtatókörnyezetek megjelenítése"

#: app/flatpak-builtins-ps.c:57
#, fuzzy
msgid "R.-Branch"
msgstr "Ág"

#: app/flatpak-builtins-ps.c:57
#, fuzzy
msgid "Show the runtime branch"
msgstr "Csak futtatókörnyezetek megjelenítése"

#: app/flatpak-builtins-ps.c:58
#, fuzzy
msgid "R.-Commit"
msgstr "Kommit"

#: app/flatpak-builtins-ps.c:58
#, fuzzy
msgid "Show the runtime commit"
msgstr "Csak futtatókörnyezetek megjelenítése"

#: app/flatpak-builtins-ps.c:59
#, fuzzy
msgid "Active"
msgstr "Aktív kommit"

#: app/flatpak-builtins-ps.c:59
#, fuzzy
msgid "Show whether the app is active"
msgstr "Csak futtatókörnyezetek megjelenítése"

#: app/flatpak-builtins-ps.c:60
msgid "Background"
msgstr ""

#: app/flatpak-builtins-ps.c:60
#, fuzzy
msgid "Show whether the app is background"
msgstr "Csak futtatókörnyezetek megjelenítése"

#: app/flatpak-builtins-ps.c:246
msgid " - Enumerate running sandboxes"
msgstr ""

#: app/flatpak-builtins-remote-add.c:66
msgid "Do nothing if the provided remote exists"
msgstr "Ne tegyen semmit, ha a megadott távoli létezik"

#: app/flatpak-builtins-remote-add.c:67
msgid "LOCATION specifies a configuration file, not the repo location"
msgstr "A HELY egy beállítófájlt határoz meg, nem a tároló helyét"

#: app/flatpak-builtins-remote-add.c:72 app/flatpak-builtins-remote-modify.c:78
msgid "Disable GPG verification"
msgstr "GPG ellenőrzés letiltása"

#: app/flatpak-builtins-remote-add.c:73 app/flatpak-builtins-remote-modify.c:79
msgid "Mark the remote as don't enumerate"
msgstr "A távoli megjelölése nem felsorolandóként"

#: app/flatpak-builtins-remote-add.c:74 app/flatpak-builtins-remote-modify.c:80
msgid "Mark the remote as don't use for deps"
msgstr "A távoli megjelölése függőségekhez nem használtként"

#: app/flatpak-builtins-remote-add.c:75 app/flatpak-builtins-remote-modify.c:81
msgid "Set priority (default 1, higher is more prioritized)"
msgstr ""
"Prioritás beállítása (alapértelmezetten 1, a magasabb nagyobb prioritású)"

#: app/flatpak-builtins-remote-add.c:75 app/flatpak-builtins-remote-modify.c:81
msgid "PRIORITY"
msgstr "PRIORITÁS"

#: app/flatpak-builtins-remote-add.c:76
#, fuzzy
msgid "The named subset to use for this remote"
msgstr "Egy szép, ehhez a távolihoz használandó név"

#: app/flatpak-builtins-remote-add.c:76 app/flatpak-builtins-remote-modify.c:71
msgid "SUBSET"
msgstr ""

#: app/flatpak-builtins-remote-add.c:77 app/flatpak-builtins-remote-modify.c:82
msgid "A nice name to use for this remote"
msgstr "Egy szép, ehhez a távolihoz használandó név"

#: app/flatpak-builtins-remote-add.c:78 app/flatpak-builtins-remote-modify.c:83
#, fuzzy
msgid "A one-line comment for this remote"
msgstr "Egy szép, ehhez a távolihoz használandó név"

#: app/flatpak-builtins-remote-add.c:79 app/flatpak-builtins-remote-modify.c:84
#, fuzzy
msgid "A full-paragraph description for this remote"
msgstr "Ehhez a tárolóhoz használandó alapértelmezett ág"

#: app/flatpak-builtins-remote-add.c:80 app/flatpak-builtins-remote-modify.c:85
#, fuzzy
msgid "URL for a website for this remote"
msgstr "Egy szép, ehhez a távolihoz használandó név"

#: app/flatpak-builtins-remote-add.c:81 app/flatpak-builtins-remote-modify.c:86
#, fuzzy
msgid "URL for an icon for this remote"
msgstr "Ehhez a tárolóhoz használandó alapértelmezett ág"

#: app/flatpak-builtins-remote-add.c:82 app/flatpak-builtins-remote-modify.c:87
msgid "Default branch to use for this remote"
msgstr "Ehhez a tárolóhoz használandó alapértelmezett ág"

#: app/flatpak-builtins-remote-add.c:84 app/flatpak-builtins-remote-modify.c:89
msgid "Import GPG key from FILE (- for stdin)"
msgstr "GPG kulcs importálása a FÁJLBÓL (- a szabványos bemenethez)"

#: app/flatpak-builtins-remote-add.c:85 app/flatpak-builtins-remote-modify.c:90
msgid "Load signatures from URL"
msgstr ""

#: app/flatpak-builtins-remote-add.c:86 app/flatpak-builtins-remote-modify.c:92
msgid "Set path to local filter FILE"
msgstr ""

#: app/flatpak-builtins-remote-add.c:87 app/flatpak-builtins-remote-modify.c:93
msgid "Disable the remote"
msgstr "A távoli letiltása"

#: app/flatpak-builtins-remote-add.c:88 app/flatpak-builtins-remote-modify.c:94
msgid "Name of authenticator"
msgstr ""

#: app/flatpak-builtins-remote-add.c:90 app/flatpak-builtins-remote-modify.c:96
#, fuzzy
msgid "Autoinstall authenticator"
msgstr "Ismeretlen %s D-Bus név\n"

#: app/flatpak-builtins-remote-add.c:91 app/flatpak-builtins-remote-modify.c:97
#, fuzzy
msgid "Don't autoinstall authenticator"
msgstr "Ne távolítsa el a kapcsolódó hivatkozásokat"

#: app/flatpak-builtins-remote-add.c:92 app/flatpak-builtins-remote-modify.c:99
msgid "Don't follow the redirect set in the summary file"
msgstr ""

#: app/flatpak-builtins-remote-add.c:261 app/flatpak-builtins-remote-add.c:268
#, c-format
msgid "Can't load uri %s: %s\n"
msgstr "Nem lehet betölteni a(z) %s URI-t: %s\n"

#: app/flatpak-builtins-remote-add.c:276 common/flatpak-dir.c:4643
#, c-format
msgid "Can't load file %s: %s\n"
msgstr "Nem lehet betölteni a(z) %s fájlt: %s\n"

#: app/flatpak-builtins-remote-add.c:304
msgid "NAME LOCATION - Add a remote repository"
msgstr "NÉV HELY - Egy távoli tároló hozzáadása"

#: app/flatpak-builtins-remote-add.c:331
msgid "GPG verification is required if collections are enabled"
msgstr "GPG ellenőrzés szükséges, ha a gyűjtemények engedélyezettek"

#: app/flatpak-builtins-remote-add.c:393
#, c-format
msgid "Remote %s already exists"
msgstr "A távoli %s már létezik"

#: app/flatpak-builtins-remote-add.c:405
#: app/flatpak-builtins-remote-modify.c:340
#, fuzzy, c-format
msgid "Invalid authenticator name %s"
msgstr "Ismeretlen %s D-Bus név\n"

#: app/flatpak-builtins-remote-add.c:422
#, c-format
msgid "Warning: Could not update extra metadata for '%s': %s\n"
msgstr ""
"Figyelmeztetése Nem sikerült frissíteni a(z) %s további metaadatait: %s\n"

#: app/flatpak-builtins-remote-delete.c:39
msgid "Remove remote even if in use"
msgstr "Távoli eltávolítása akkor is, ha használatban van"

#: app/flatpak-builtins-remote-delete.c:53
msgid "NAME - Delete a remote repository"
msgstr "NÉV - Egy távoli tároló törlése"

#: app/flatpak-builtins-remote-delete.c:100
#, fuzzy, c-format
msgid "The following refs are installed from remote '%s':"
msgstr "A(z) %s már telepítve lett egy másik távoli tárolóból (%s)"

#: app/flatpak-builtins-remote-delete.c:101
#, fuzzy
msgid "Remove them?"
msgstr "Távoli tárolók"

#: app/flatpak-builtins-remote-delete.c:103
#, c-format
msgid "Can't remove remote '%s' with installed refs"
msgstr ""

#: app/flatpak-builtins-remote-info.c:55
msgid "Commit to show info for"
msgstr "Kommit, amelyhez meg kell jeleníteni az információt"

#: app/flatpak-builtins-remote-info.c:58
msgid "Display log"
msgstr "Napló megjelenítése"

#: app/flatpak-builtins-remote-info.c:61
msgid "Show parent"
msgstr "Szülő megjelenítése"

#: app/flatpak-builtins-remote-info.c:65 app/flatpak-builtins-remote-ls.c:60
msgid "Use local caches even if they are stale"
msgstr ""

#. Translators: A sideload is when you install from a local USB drive rather than the Internet.
#: app/flatpak-builtins-remote-info.c:67 app/flatpak-builtins-remote-ls.c:62
msgid "Only list refs available as sideloads"
msgstr ""

#: app/flatpak-builtins-remote-info.c:114
msgid ""
" REMOTE REF - Show information about an application or runtime in a remote"
msgstr ""
" TÁVOLI HIVATKOZÁS – Információk megjelenítése az alkalmazásról vagy "
"futtatókörnyezetről a távoli tárolóban"

#: app/flatpak-builtins-remote-info.c:125
msgid "REMOTE and REF must be specified"
msgstr "A TÁVOLI és HIVATKOZÁS megadása kötelező"

#: app/flatpak-builtins-remote-info.c:247
#: app/flatpak-builtins-remote-info.c:282
#, fuzzy
msgid "Download Size:"
msgstr "Letöltési méret:"

#: app/flatpak-builtins-remote-info.c:267
#: app/flatpak-builtins-remote-info.c:325
#, fuzzy
msgid "History:"
msgstr "Előzmények:\n"

#: app/flatpak-builtins-remote-info.c:348
msgid " Commit:"
msgstr " Kommit:"

#: app/flatpak-builtins-remote-info.c:349
msgid " Subject:"
msgstr " Tárgy:"

#: app/flatpak-builtins-remote-info.c:350
msgid " Date:"
msgstr " Dátum:"

#: app/flatpak-builtins-remote-info.c:383
#, c-format
msgid "Warning: Commit %s has no flatpak metadata\n"
msgstr "Figyelmeztetés: a(z) %s kommitnak nincs flatpak metaadata\n"

#: app/flatpak-builtins-remote-list.c:43
msgid "Show remote details"
msgstr "Távoli részleteinek megjelenítése"

#: app/flatpak-builtins-remote-list.c:44
msgid "Show disabled remotes"
msgstr "Letiltott távoliak megjelenítése"

#: app/flatpak-builtins-remote-list.c:52
msgid "Title"
msgstr "Cím"

#: app/flatpak-builtins-remote-list.c:52
#, fuzzy
msgid "Show the title"
msgstr "Csak futtatókörnyezetek megjelenítése"

#: app/flatpak-builtins-remote-list.c:53
#, fuzzy
msgid "Show the URL"
msgstr "Hivatkozás megjelenítése"

#: app/flatpak-builtins-remote-list.c:54
#, fuzzy
msgid "Show the collection ID"
msgstr "Alkalmazásazonosító"

#: app/flatpak-builtins-remote-list.c:55 app/flatpak-builtins-repo.c:392
msgid "Subset"
msgstr ""

#: app/flatpak-builtins-remote-list.c:55
#, fuzzy
msgid "Show the subset"
msgstr "Hivatkozás megjelenítése"

#: app/flatpak-builtins-remote-list.c:56
msgid "Filter"
msgstr ""

#: app/flatpak-builtins-remote-list.c:56
#, fuzzy
msgid "Show filter file"
msgstr "Csak futtatókörnyezetek megjelenítése"

#: app/flatpak-builtins-remote-list.c:57
msgid "Priority"
msgstr "Prioritás"

#: app/flatpak-builtins-remote-list.c:57
#, fuzzy
msgid "Show the priority"
msgstr "Csak futtatókörnyezetek megjelenítése"

#: app/flatpak-builtins-remote-list.c:59
#, fuzzy
msgid "Comment"
msgstr "Kommit"

#: app/flatpak-builtins-remote-list.c:59
#, fuzzy
msgid "Show comment"
msgstr "Kommit megjelenítése"

#: app/flatpak-builtins-remote-list.c:60
#, fuzzy
msgid "Show description"
msgstr "Alkalmazásazonosító"

#: app/flatpak-builtins-remote-list.c:61
msgid "Homepage"
msgstr ""

#: app/flatpak-builtins-remote-list.c:61
#, fuzzy
msgid "Show homepage"
msgstr "Csak futtatókörnyezetek megjelenítése"

#: app/flatpak-builtins-remote-list.c:62
msgid "Icon"
msgstr ""

#: app/flatpak-builtins-remote-list.c:62
#, fuzzy
msgid "Show icon"
msgstr "Súgólehetőségek megjelenítése"

#: app/flatpak-builtins-remote-list.c:231
msgid " - List remote repositories"
msgstr " - Távoli tárolók felsorolása"

#: app/flatpak-builtins-remote-ls.c:52
msgid "Show arches and branches"
msgstr "Architektúrák és ágak megjelenítése"

#: app/flatpak-builtins-remote-ls.c:53
msgid "Show only runtimes"
msgstr "Csak futtatókörnyezetek megjelenítése"

#: app/flatpak-builtins-remote-ls.c:54
msgid "Show only apps"
msgstr "Csak alkalmazások megjelenítése"

#: app/flatpak-builtins-remote-ls.c:55
msgid "Show only those where updates are available"
msgstr "Csak azok megjelenítése, ahol frissítések érhetők el"

#: app/flatpak-builtins-remote-ls.c:56
msgid "Limit to this arch (* for all)"
msgstr "Korlátozás erre az architektúrára (* az összeshez)"

#: app/flatpak-builtins-remote-ls.c:77
#, fuzzy
msgid "Show the runtime"
msgstr "Csak futtatókörnyezetek megjelenítése"

#: app/flatpak-builtins-remote-ls.c:79
msgid "Download size"
msgstr "Letöltési méret"

#: app/flatpak-builtins-remote-ls.c:79
#, fuzzy
msgid "Show the download size"
msgstr "Letöltési méret"

#: app/flatpak-builtins-remote-ls.c:391
#, fuzzy
msgid " [REMOTE or URI] - Show available runtimes and applications"
msgstr " [TÁVOLI] – Elérhető futtatókörnyezetek és alkalmazások megjelenítése"

#: app/flatpak-builtins-remote-modify.c:67
msgid "Enable GPG verification"
msgstr "GPG ellenőrzés engedélyezése"

#: app/flatpak-builtins-remote-modify.c:68
msgid "Mark the remote as enumerate"
msgstr "A távoli megjelölése felsorolásként"

#: app/flatpak-builtins-remote-modify.c:69
msgid "Mark the remote as used for dependencies"
msgstr "A távoli megjelölése függőségekhez használtként"

#: app/flatpak-builtins-remote-modify.c:70
#, fuzzy
msgid "Set a new URL"
msgstr "Új URL beállítása"

#: app/flatpak-builtins-remote-modify.c:71
#, fuzzy
msgid "Set a new subset to use"
msgstr "Új URL beállítása"

#: app/flatpak-builtins-remote-modify.c:72
msgid "Enable the remote"
msgstr "A távoli engedélyezése"

#: app/flatpak-builtins-remote-modify.c:73
msgid "Update extra metadata from the summary file"
msgstr "További metaadatok frissítése az összegzőfájlból"

#: app/flatpak-builtins-remote-modify.c:91
msgid "Disable local filter"
msgstr ""

#: app/flatpak-builtins-remote-modify.c:95
#, fuzzy
msgid "Authenticator options"
msgstr "Súgólehetőségek megjelenítése"

#: app/flatpak-builtins-remote-modify.c:98
#, fuzzy
msgid "Follow the redirect set in the summary file"
msgstr "További metaadatok frissítése az összegzőfájlból"

#: app/flatpak-builtins-remote-modify.c:306
msgid "NAME - Modify a remote repository"
msgstr "NÉV - Egy távoli tároló módosítása"

#: app/flatpak-builtins-remote-modify.c:316
msgid "Remote NAME must be specified"
msgstr "A távoli NÉV megadása kötelező"

#: app/flatpak-builtins-remote-modify.c:327
#, c-format
msgid "Updating extra metadata from remote summary for %s\n"
msgstr "További metaadatok frissítése a(z) %s távoli összegzéséből\n"

#: app/flatpak-builtins-remote-modify.c:330
#, c-format
msgid "Error updating extra metadata for '%s': %s\n"
msgstr "Hiba a(z) „%s” további metaadatainak frissítéskor: %s\n"

#: app/flatpak-builtins-remote-modify.c:331
#, c-format
msgid "Could not update extra metadata for %s"
msgstr "Nem sikerült frissíteni a(z) %s további metaadatait"

#: app/flatpak-builtins-repair.c:43
msgid "Don't make any changes"
msgstr ""

#: app/flatpak-builtins-repair.c:44
#, fuzzy
msgid "Reinstall all refs"
msgstr "Alkalmazás eltávolítása"

#: app/flatpak-builtins-repair.c:68
#, c-format
msgid "Object missing: %s.%s\n"
msgstr ""

#: app/flatpak-builtins-repair.c:76
#, c-format
msgid "Object invalid: %s.%s\n"
msgstr ""

#: app/flatpak-builtins-repair.c:81
#, c-format
msgid "%s, deleting object\n"
msgstr ""

#: app/flatpak-builtins-repair.c:146
#, fuzzy, c-format
msgid "Can't load object %s: %s\n"
msgstr "Nem lehet betölteni a(z) %s fájlt: %s\n"

#: app/flatpak-builtins-repair.c:228
#, fuzzy, c-format
msgid "Commit invalid %s: %s\n"
msgstr "Érvénytelen %s pid"

#: app/flatpak-builtins-repair.c:231
#, fuzzy, c-format
msgid "Deleting invalid commit %s: %s\n"
msgstr "Érvénytelen %s kommithivatkozás: "

#: app/flatpak-builtins-repair.c:261
#, c-format
msgid "Commit should be marked partial: %s\n"
msgstr ""

#: app/flatpak-builtins-repair.c:264
#, c-format
msgid "Marking commit as partial: %s\n"
msgstr ""

#: app/flatpak-builtins-repair.c:293
#, fuzzy, c-format
msgid "Problems loading data for %s: %s\n"
msgstr "Az appstream adatok frissítése a(z) %s távoli tárolóhoz\n"

#: app/flatpak-builtins-repair.c:306
#, fuzzy, c-format
msgid "Error reinstalling %s: %s\n"
msgstr "Eltávolítás: %s\n"

#: app/flatpak-builtins-repair.c:327
#, fuzzy
msgid "- Repair a flatpak installation"
msgstr "Felhasználói telepítések megjelenítése"

#: app/flatpak-builtins-repair.c:406
#, fuzzy, c-format
msgid "Removing non-deployed ref %s…\n"
msgstr "Érvénytelen %s üzembe állított hivatkozás:"

#: app/flatpak-builtins-repair.c:411
#, fuzzy, c-format
msgid "Skipping non-deployed ref %s…\n"
msgstr "Érvénytelen %s üzembe állított hivatkozás:"

#: app/flatpak-builtins-repair.c:429
#, c-format
msgid "[%d/%d] Verifying %s…\n"
msgstr ""

#: app/flatpak-builtins-repair.c:435
#, c-format
msgid "Dry run: "
msgstr ""

#: app/flatpak-builtins-repair.c:440
#, c-format
msgid "Deleting ref %s due to missing objects\n"
msgstr ""

#: app/flatpak-builtins-repair.c:444
#, c-format
msgid "Deleting ref %s due to invalid objects\n"
msgstr ""

#: app/flatpak-builtins-repair.c:448
#, c-format
msgid "Deleting ref %s due to %d\n"
msgstr ""

#: app/flatpak-builtins-repair.c:464
#, c-format
msgid "Checking remotes...\n"
msgstr ""

#: app/flatpak-builtins-repair.c:482
#, c-format
msgid "Remote %s for ref %s is missing\n"
msgstr ""

#: app/flatpak-builtins-repair.c:484
#, c-format
msgid "Remote %s for ref %s is disabled\n"
msgstr ""

#: app/flatpak-builtins-repair.c:490
#, fuzzy, c-format
msgid "Pruning objects\n"
msgstr "Nem használt objektumok törlése"

#: app/flatpak-builtins-repair.c:498
#, fuzzy, c-format
msgid "Erasing .removed\n"
msgstr "Ne telepítse a kapcsolódó hivatkozásokat"

#: app/flatpak-builtins-repair.c:524
#, fuzzy, c-format
msgid "Reinstalling refs\n"
msgstr "Ne telepítse a kapcsolódó hivatkozásokat"

#: app/flatpak-builtins-repair.c:526
#, fuzzy, c-format
msgid "Reinstalling removed refs\n"
msgstr "Ne telepítse a kapcsolódó hivatkozásokat"

#: app/flatpak-builtins-repair.c:551
#, fuzzy, c-format
msgid "While removing appstream for %s: "
msgstr "A(z) %s tároló megnyitása közben: "

#: app/flatpak-builtins-repair.c:558
#, fuzzy, c-format
msgid "While deploying appstream for %s: "
msgstr "A(z) %s tároló megnyitása közben: "

#: app/flatpak-builtins-repo.c:106
#, c-format
msgid "Repo mode: %s\n"
msgstr ""

#: app/flatpak-builtins-repo.c:113
#, c-format
msgid "Indexed summaries: %s\n"
msgstr ""

#: app/flatpak-builtins-repo.c:113 app/flatpak-builtins-repo.c:139
#: app/flatpak-builtins-repo.c:172
msgid "true"
msgstr ""

#: app/flatpak-builtins-repo.c:113 app/flatpak-builtins-repo.c:139
#: app/flatpak-builtins-repo.c:172
msgid "false"
msgstr ""

#: app/flatpak-builtins-repo.c:121
#, c-format
msgid "Subsummaries: "
msgstr ""

#: app/flatpak-builtins-repo.c:136
#, c-format
msgid "Cache version: %d\n"
msgstr ""

#: app/flatpak-builtins-repo.c:139
#, c-format
msgid "Indexed deltas: %s\n"
msgstr ""

#: app/flatpak-builtins-repo.c:142
#, c-format
msgid "Title: %s\n"
msgstr "Cím: %s\n"

#: app/flatpak-builtins-repo.c:145
#, fuzzy, c-format
msgid "Comment: %s\n"
msgstr "Kommit: %s\n"

#: app/flatpak-builtins-repo.c:148
#, fuzzy, c-format
msgid "Description: %s\n"
msgstr "Leírás"

#: app/flatpak-builtins-repo.c:151
#, c-format
msgid "Homepage: %s\n"
msgstr ""

#: app/flatpak-builtins-repo.c:154
#, fuzzy, c-format
msgid "Icon: %s\n"
msgstr "Kommit: %s\n"

#: app/flatpak-builtins-repo.c:157
#, c-format
msgid "Collection ID: %s\n"
msgstr "Gyűjteményazonosító: %s\n"

#: app/flatpak-builtins-repo.c:160
#, c-format
msgid "Default branch: %s\n"
msgstr "Alapértelmezett ág: %s\n"

#: app/flatpak-builtins-repo.c:163
#, c-format
msgid "Redirect URL: %s\n"
msgstr "URL átirányítás: %s\n"

#: app/flatpak-builtins-repo.c:166
#, fuzzy, c-format
msgid "Deploy collection ID: %s\n"
msgstr "Gyűjteményazonosító: %s\n"

#: app/flatpak-builtins-repo.c:169
#, fuzzy, c-format
msgid "Authenticator name: %s\n"
msgstr "Ismeretlen %s D-Bus név\n"

#: app/flatpak-builtins-repo.c:172
#, fuzzy, c-format
msgid "Authenticator install: %s\n"
msgstr "Súgólehetőségek megjelenítése"

#: app/flatpak-builtins-repo.c:180
#, c-format
msgid "GPG key hash: %s\n"
msgstr "GPG kulcs ujjlenyomat: %s\n"

#: app/flatpak-builtins-repo.c:184
#, fuzzy, c-format
msgid "%zd summary branches\n"
msgstr "%zd ág\n"

#: app/flatpak-builtins-repo.c:336
msgid "Installed"
msgstr "Telepítve"

#. Translators: Download is used here as a noun
#: app/flatpak-builtins-repo.c:338 app/flatpak-cli-transaction.c:1462
msgid "Download"
msgstr "Letöltés"

#: app/flatpak-builtins-repo.c:339
msgid "Subsets"
msgstr ""

#: app/flatpak-builtins-repo.c:393
msgid "Digest"
msgstr ""

#: app/flatpak-builtins-repo.c:394
#, fuzzy
msgid "History length"
msgstr "Előzmények:\n"

#: app/flatpak-builtins-repo.c:711
msgid "Print general information about the repository"
msgstr "Általános információk kiírása a tárolóról"

#: app/flatpak-builtins-repo.c:712
msgid "List the branches in the repository"
msgstr "A tárolóban lévő ágak felsorolása"

#: app/flatpak-builtins-repo.c:713
msgid "Print metadata for a branch"
msgstr "Egy ág metaadatainak kiírása"

#: app/flatpak-builtins-repo.c:714
#, fuzzy
msgid "Show commits for a branch"
msgstr "Architektúrák és ágak megjelenítése"

#: app/flatpak-builtins-repo.c:715
#, fuzzy
msgid "Print information about the repo subsets"
msgstr "Általános információk kiírása a tárolóról"

#: app/flatpak-builtins-repo.c:716
msgid "Limit information to subsets with this prefix"
msgstr ""

#: app/flatpak-builtins-repo.c:732
msgid "LOCATION - Repository maintenance"
msgstr "HELY - Tároló karbantartása"

#: app/flatpak-builtins-run.c:159
msgid "Command to run"
msgstr "Futtatandó parancs"

#: app/flatpak-builtins-run.c:160
msgid "Directory to run the command in"
msgstr ""

#: app/flatpak-builtins-run.c:161
msgid "Branch to use"
msgstr "Használandó ág"

#: app/flatpak-builtins-run.c:162
msgid "Use development runtime"
msgstr "Fejlesztői futtatókörnyezet használata"

#: app/flatpak-builtins-run.c:163
msgid "Runtime to use"
msgstr "Használandó futtatókörnyezet"

#: app/flatpak-builtins-run.c:164
msgid "Runtime version to use"
msgstr "Használandó futtatókörnyezet-verzió"

#: app/flatpak-builtins-run.c:167
msgid "Log accessibility bus calls"
msgstr "Akadálymentesítési busz hívások naplózása"

#: app/flatpak-builtins-run.c:168
#, fuzzy
msgid "Don't proxy accessibility bus calls"
msgstr "Akadálymentesítési busz hívások naplózása"

#: app/flatpak-builtins-run.c:169
msgid "Proxy accessibility bus calls (default except when sandboxed)"
msgstr ""

#: app/flatpak-builtins-run.c:170
#, fuzzy
msgid "Don't proxy session bus calls"
msgstr "Akadálymentesítési busz hívások naplózása"

#: app/flatpak-builtins-run.c:171
msgid "Proxy session bus calls (default except when sandboxed)"
msgstr ""

#: app/flatpak-builtins-run.c:172
#, fuzzy
msgid "Don't start portals"
msgstr "Ne használjon statikus deltákat"

#: app/flatpak-builtins-run.c:173
msgid "Enable file forwarding"
msgstr "Fájltovábbítás engedélyezése"

#: app/flatpak-builtins-run.c:174
#, fuzzy
msgid "Run specified commit"
msgstr "Aktív kommit"

#: app/flatpak-builtins-run.c:175
#, fuzzy
msgid "Use specified runtime commit"
msgstr "Aláírt futtatókörnyezet frissítése"

#: app/flatpak-builtins-run.c:176
msgid "Run completely sandboxed"
msgstr ""

#: app/flatpak-builtins-run.c:178
msgid "Use PID as parent pid for sharing namespaces"
msgstr ""

#: app/flatpak-builtins-run.c:179
msgid "Make processes visible in parent namespace"
msgstr ""

#: app/flatpak-builtins-run.c:180
msgid "Share process ID namespace with parent"
msgstr ""

#: app/flatpak-builtins-run.c:181
msgid "Write the instance ID to the given file descriptor"
msgstr ""

#: app/flatpak-builtins-run.c:182
msgid "Use PATH instead of the app's /app"
msgstr ""

#: app/flatpak-builtins-run.c:183
msgid "Use FD instead of the app's /app"
msgstr ""

#: app/flatpak-builtins-run.c:183 app/flatpak-builtins-run.c:185
#: app/flatpak-builtins-run.c:187 app/flatpak-builtins-run.c:188
#: common/flatpak-context.c:2672
msgid "FD"
msgstr ""

#: app/flatpak-builtins-run.c:184
msgid "Use PATH instead of the runtime's /usr"
msgstr ""

#: app/flatpak-builtins-run.c:185
msgid "Use FD instead of the runtime's /usr"
msgstr ""

#: app/flatpak-builtins-run.c:186
#, fuzzy
msgid "Clear all outside environment variables"
msgstr "Környezeti változó beállítása"

#: app/flatpak-builtins-run.c:187
msgid ""
"Bind mount the file or directory referred to by FD to its canonicalized path"
msgstr ""

#: app/flatpak-builtins-run.c:188
msgid ""
"Bind mount the file or directory referred to by FD read-only to its "
"canonicalized path"
msgstr ""

#: app/flatpak-builtins-run.c:219
#, fuzzy
msgid "APP [ARGUMENT…] - Run an app"
msgstr "ALKALMAZÁS [argumentumok…] - Alkalmazás futtatása"

#: app/flatpak-builtins-run.c:370
#, fuzzy, c-format
msgid "runtime/%s/%s/%s not installed"
msgstr "A(z) %s %s nincs telepítve"

#: app/flatpak-builtins-run.c:419
msgid "app-fd and app-path cannot both be used"
msgstr ""

#: app/flatpak-builtins-run.c:449
msgid "usr-fd and usr-path cannot both be used"
msgstr ""

#: app/flatpak-builtins-search.c:37
#, fuzzy
msgid "Arch to search for"
msgstr "Telepítés ezen architektúrára"

#: app/flatpak-builtins-search.c:49
msgid "Remotes"
msgstr "Távoli tárolók"

#: app/flatpak-builtins-search.c:49
#, fuzzy
msgid "Show the remotes"
msgstr "Letiltott távoliak megjelenítése"

#: app/flatpak-builtins-search.c:244
msgid "TEXT - Search remote apps/runtimes for text"
msgstr ""
"SZÖVEG – Távoli alkalmazások vagy futtatókörnyezetek keresése a szöveghez"

#: app/flatpak-builtins-search.c:255
msgid "TEXT must be specified"
msgstr "A SZÖVEG megadása kötelező"

#: app/flatpak-builtins-search.c:338
msgid "No matches found"
msgstr "Nincs találat"

#: app/flatpak-builtins-uninstall.c:54
msgid "Arch to uninstall"
msgstr "Eltávolítandó architektúra"

#: app/flatpak-builtins-uninstall.c:55
msgid "Keep ref in local repository"
msgstr "Hivatkozás megtartása a helyi tárolóban"

#: app/flatpak-builtins-uninstall.c:56
msgid "Don't uninstall related refs"
msgstr "Ne távolítsa el a kapcsolódó hivatkozásokat"

#: app/flatpak-builtins-uninstall.c:57
msgid "Remove files even if running"
msgstr "Fájlok eltávolítása akkor is, ha futnak"

#: app/flatpak-builtins-uninstall.c:60
#, fuzzy
msgid "Uninstall all"
msgstr "Alkalmazás eltávolítása"

#: app/flatpak-builtins-uninstall.c:61
#, fuzzy
msgid "Uninstall unused"
msgstr "Futtatókörnyezet eltávolítása"

#: app/flatpak-builtins-uninstall.c:62
msgid "Delete app data"
msgstr ""

#: app/flatpak-builtins-uninstall.c:141
#, c-format
msgid "Delete data for %s?"
msgstr ""

#: app/flatpak-builtins-uninstall.c:220
#, c-format
msgid "Info: applications using the extension %s%s%s branch %s%s%s:\n"
msgstr ""

#: app/flatpak-builtins-uninstall.c:223
#, fuzzy, c-format
msgid "Info: applications using the runtime %s%s%s branch %s%s%s:\n"
msgstr ""
"\n"
"Alkalmazás és futtatókörnyezet keresése"

#: app/flatpak-builtins-uninstall.c:238
#, fuzzy
msgid "Really remove?"
msgstr "Távoli tárolók"

#: app/flatpak-builtins-uninstall.c:255
#, fuzzy
msgid "[REF…] - Uninstall applications or runtimes"
msgstr "[HIVATKOZÁS…] – Alkalmazások vagy futtatókörnyezetek frissítése"

#: app/flatpak-builtins-uninstall.c:264
#, fuzzy
msgid "Must specify at least one REF, --unused, --all or --delete-data"
msgstr "Legalább egy HIVATKOZÁS megadása kötelező"

#: app/flatpak-builtins-uninstall.c:267
msgid "Must not specify REFs when using --all"
msgstr ""

#: app/flatpak-builtins-uninstall.c:270
msgid "Must not specify REFs when using --unused"
msgstr ""

#: app/flatpak-builtins-uninstall.c:336
#, c-format
msgid ""
"\n"
"These runtimes in installation '%s' are pinned and won't be removed; see "
"flatpak-pin(1):\n"
msgstr ""

#: app/flatpak-builtins-uninstall.c:370
#, fuzzy, c-format
msgid "Nothing unused to uninstall\n"
msgstr "Eltávolítandó architektúra"

#: app/flatpak-builtins-uninstall.c:444
#, fuzzy, c-format
msgid "No installed refs found for ‘%s’"
msgstr "Nem találhatók felülbírálások ehhez: %s"

#: app/flatpak-builtins-uninstall.c:447
#, c-format
msgid " with arch ‘%s’"
msgstr ""

#: app/flatpak-builtins-uninstall.c:449
#, c-format
msgid " with branch ‘%s’"
msgstr ""

#: app/flatpak-builtins-uninstall.c:456
#, fuzzy, c-format
msgid "Warning: %s is not installed\n"
msgstr "A(z) %s %s ág nincs telepítve"

#: app/flatpak-builtins-uninstall.c:490
#, c-format
msgid "None of the specified refs are installed"
msgstr ""

#: app/flatpak-builtins-uninstall.c:599
#, c-format
msgid "No app data to delete\n"
msgstr ""

#: app/flatpak-builtins-update.c:56
msgid "Arch to update for"
msgstr "Frissítés ezen architektúrára"

#: app/flatpak-builtins-update.c:57
msgid "Commit to deploy"
msgstr "Telepítendő kommit"

#: app/flatpak-builtins-update.c:58
msgid "Remove old files even if running"
msgstr "Régi fájlok eltávolítása akkor is, ha futnak"

#: app/flatpak-builtins-update.c:59
msgid "Don't pull, only update from local cache"
msgstr "Ne kérje le, csak frissítse a helyi gyorsítótárból"

#: app/flatpak-builtins-update.c:61
msgid "Don't update related refs"
msgstr "Ne frissítse a kapcsolódó hivatkozásokat"

#: app/flatpak-builtins-update.c:66
msgid "Update appstream for remote"
msgstr "Az AppStream frissítése a távolihoz"

#: app/flatpak-builtins-update.c:67
msgid "Only update this subpath"
msgstr "Csak ezen alútvonal frissítése"

#: app/flatpak-builtins-update.c:90
#, fuzzy
msgid "[REF…] - Update applications or runtimes"
msgstr "[HIVATKOZÁS…] – Alkalmazások vagy futtatókörnyezetek frissítése"

#: app/flatpak-builtins-update.c:121
#, fuzzy
msgid "With --commit, only one REF may be specified"
msgstr "A TÁVOLI és HIVATKOZÁS megadása kötelező"

#: app/flatpak-builtins-update.c:162
#, fuzzy, c-format
msgid "Looking for updates…\n"
msgstr "Frissítések keresése…\n"

#: app/flatpak-builtins-update.c:215
#, fuzzy, c-format
msgid "Unable to update %s: %s\n"
msgstr "A(z) %s lekérése közben a(z) %s távoliról: "

#: app/flatpak-builtins-update.c:274
#, fuzzy, c-format
msgid "Nothing to update.\n"
msgstr "Semmi sem egyezik: %s"

#: app/flatpak-builtins-utils.c:337
#, fuzzy, c-format
msgid ""
"Remote ‘%s’ found in multiple installations, unable to proceed in non-"
"interactive mode"
msgstr "A(z) „%s” távoli tároló több telepítésben is megtalálható:\n"

#: app/flatpak-builtins-utils.c:346
#, fuzzy, c-format
msgid "Remote ‘%s’ found in multiple installations:"
msgstr "A(z) „%s” távoli tároló több telepítésben is megtalálható:\n"

#: app/flatpak-builtins-utils.c:347 app/flatpak-builtins-utils.c:442
#: app/flatpak-builtins-utils.c:538 app/flatpak-builtins-utils.c:540
#: app/flatpak-builtins-utils.c:598
msgid "Which do you want to use (0 to abort)?"
msgstr "Melyiket szeretné használni (0 a megszakításhoz)?"

#: app/flatpak-builtins-utils.c:349
#, c-format
msgid "No remote chosen to resolve ‘%s’ which exists in multiple installations"
msgstr ""
"Nem lett távoli tároló kiválasztva a(z) „%s” feloldásához, amely több "
"telepítésben is létezik"

#: app/flatpak-builtins-utils.c:358
#, c-format
msgid ""
"Remote \"%s\" not found\n"
"Hint: Use flatpak remote-add to add a remote"
msgstr ""

#: app/flatpak-builtins-utils.c:364
#, fuzzy, c-format
msgid "Remote \"%s\" not found in the %s installation"
msgstr "A(z) „%s” távoli tároló több telepítésben is megtalálható:\n"

#: app/flatpak-builtins-utils.c:404
#, c-format
msgid "Multiple refs match ‘%s’, unable to proceed in non-interactive mode"
msgstr ""

#. default to yes on Enter
#: app/flatpak-builtins-utils.c:430
#, c-format
msgid ""
"Found ref ‘%s’ in remote ‘%s’ (%s).\n"
"Use this ref?"
msgstr ""

#: app/flatpak-builtins-utils.c:434 app/flatpak-builtins-utils.c:444
#: app/flatpak-builtins-utils.c:522 app/flatpak-builtins-utils.c:543
#, c-format
msgid "No ref chosen to resolve matches for ‘%s’"
msgstr ""

#: app/flatpak-builtins-utils.c:440
#, c-format
msgid "Similar refs found for ‘%s’ in remote ‘%s’ (%s):"
msgstr ""

#: app/flatpak-builtins-utils.c:488
#, c-format
msgid ""
"Multiple installed refs match ‘%s’, unable to proceed in non-interactive mode"
msgstr ""

#. default to yes on Enter
#: app/flatpak-builtins-utils.c:518
#, c-format
msgid "Found installed ref ‘%s’ (%s). Is this correct?"
msgstr ""

#: app/flatpak-builtins-utils.c:534
#, c-format
msgid "All of the above"
msgstr ""

#: app/flatpak-builtins-utils.c:535
#, c-format
msgid "Similar installed refs found for ‘%s’:"
msgstr ""

#: app/flatpak-builtins-utils.c:579
#, c-format
msgid ""
"Multiple remotes have refs matching ‘%s’, unable to proceed in non-"
"interactive mode"
msgstr ""

#: app/flatpak-builtins-utils.c:597
#, c-format
msgid "Remotes found with refs similar to ‘%s’:"
msgstr ""

#: app/flatpak-builtins-utils.c:600
#, c-format
msgid "No remote chosen to resolve matches for ‘%s’"
msgstr ""

#: app/flatpak-builtins-utils.c:696 app/flatpak-builtins-utils.c:699
#, fuzzy, c-format
msgid "Updating appstream data for user remote %s"
msgstr "Az appstream adatok frissítése a felhasználó %s távoli tárolójához\n"

#: app/flatpak-builtins-utils.c:706 app/flatpak-builtins-utils.c:709
#, fuzzy, c-format
msgid "Updating appstream data for remote %s"
msgstr "Az appstream adatok frissítése a(z) %s távoli tárolóhoz\n"

#: app/flatpak-builtins-utils.c:717 app/flatpak-builtins-utils.c:719
#, fuzzy
msgid "Error updating"
msgstr "Hiba a frissítéskor: %s\n"

#: app/flatpak-builtins-utils.c:755
#, c-format
msgid "Remote \"%s\" not found"
msgstr "A(z) „%s” távoli tároló nem található"

#: app/flatpak-builtins-utils.c:796
#, c-format
msgid "Ambiguous suffix: '%s'."
msgstr ""

#. Translators: don't translate the values
#: app/flatpak-builtins-utils.c:798 app/flatpak-builtins-utils.c:813
msgid "Possible values are :s[tart], :m[iddle], :e[nd] or :f[ull]"
msgstr ""

#: app/flatpak-builtins-utils.c:811
#, fuzzy, c-format
msgid "Invalid suffix: '%s'."
msgstr "Érvénytelen %s pid"

#: app/flatpak-builtins-utils.c:846
#, c-format
msgid "Ambiguous column: %s"
msgstr ""

#: app/flatpak-builtins-utils.c:859
#, fuzzy, c-format
msgid "Unknown column: %s"
msgstr "Ismeretlen „%s” parancs"

#: app/flatpak-builtins-utils.c:917
msgid "Available columns:\n"
msgstr ""

#: app/flatpak-builtins-utils.c:927
#, fuzzy
msgid "Show all columns"
msgstr "Súgólehetőségek megjelenítése"

#: app/flatpak-builtins-utils.c:928
#, fuzzy
msgid "Show available columns"
msgstr "Letiltott távoliak megjelenítése"

#: app/flatpak-builtins-utils.c:931
msgid "Append :s[tart], :m[iddle], :e[nd] or :f[ull] to change ellipsization"
msgstr ""

#: app/flatpak-builtins-utils.c:1483
#, c-format
msgid "Unknown scheme in sideload location %s"
msgstr ""

#: app/flatpak-cli-transaction.c:96 app/flatpak-cli-transaction.c:102
#, fuzzy, c-format
msgid "Required runtime for %s (%s) found in remote %s\n"
msgstr "A(z) %s (%s) szükséges futtatókörnyezete nincs telepítve, keresés…\n"

#: app/flatpak-cli-transaction.c:104
#, fuzzy
msgid "Do you want to install it?"
msgstr "Melyiket szeretné telepíteni (0 a megszakításhoz)?"

#: app/flatpak-cli-transaction.c:110
#, fuzzy, c-format
msgid "Required runtime for %s (%s) found in remotes:"
msgstr "A(z) %s (%s) szükséges futtatókörnyezete nincs telepítve, keresés…\n"

#: app/flatpak-cli-transaction.c:112
msgid "Which do you want to install (0 to abort)?"
msgstr "Melyiket szeretné telepíteni (0 a megszakításhoz)?"

#: app/flatpak-cli-transaction.c:132
#, fuzzy, c-format
msgid "Configuring %s as new remote '%s'\n"
msgstr "A(z) %s beállítása mint új távoli „%s”"

#. default to yes on Enter
#: app/flatpak-cli-transaction.c:139
#, fuzzy, c-format
msgid ""
"The remote '%s', referred to by '%s' at location %s contains additional "
"applications.\n"
"Should the remote be kept for future installations?"
msgstr ""
"A(z) „%s” távoli tároló, a(z) %s helyen további alkalmazásokat tartalmaz.\n"
"Megmaradjon a távoli tároló a jövőbeli telepítésekhez?"

#. default to yes on Enter
#: app/flatpak-cli-transaction.c:147
#, fuzzy, c-format
msgid ""
"The application %s depends on runtimes from:\n"
"  %s\n"
"Configure this as new remote '%s'"
msgstr ""
"Ez az alkalmazás a következőkből való futtatókörnyezetektől függ:\n"
"  %s\n"
"Ennek beállítása mint új távoli „%s”"

#. Formatted size/remaining time in seconds
#: app/flatpak-cli-transaction.c:321
#, c-format
msgid "%s/s%s%s"
msgstr ""

#. Download progress percentage, use the appropriate
#. percent format for your language
#: app/flatpak-cli-transaction.c:359
#, c-format
msgid "%3d%%"
msgstr ""

#: app/flatpak-cli-transaction.c:414
#, fuzzy
msgid "Installing…"
msgstr "Telepítve"

#: app/flatpak-cli-transaction.c:416
#, fuzzy, c-format
msgid "Installing %d/%d…"
msgstr "Eltávolítás: %s\n"

#: app/flatpak-cli-transaction.c:421
msgid "Updating…"
msgstr ""

#: app/flatpak-cli-transaction.c:423
#, fuzzy, c-format
msgid "Updating %d/%d…"
msgstr "Frissítés: %s innen: %s\n"

#: app/flatpak-cli-transaction.c:428
#, fuzzy
msgid "Uninstalling…"
msgstr "Eltávolítás: %s\n"

#: app/flatpak-cli-transaction.c:430
#, fuzzy, c-format
msgid "Uninstalling %d/%d…"
msgstr "Eltávolítás: %s\n"

#: app/flatpak-cli-transaction.c:496 app/flatpak-quiet-transaction.c:161
#, c-format
msgid "Info: %s was skipped"
msgstr ""

#: app/flatpak-cli-transaction.c:519
#, fuzzy, c-format
msgid "Warning: %s%s%s already installed"
msgstr "A(z) %s kommit %s már telepítve van"

#: app/flatpak-cli-transaction.c:522
#, fuzzy, c-format
msgid "Error: %s%s%s already installed"
msgstr "A(z) %s kommit %s már telepítve van"

#: app/flatpak-cli-transaction.c:528
#, fuzzy, c-format
msgid "Warning: %s%s%s not installed"
msgstr "A(z) %s %s ág nincs telepítve"

#: app/flatpak-cli-transaction.c:531
#, fuzzy, c-format
msgid "Error: %s%s%s not installed"
msgstr "A(z) %s %s nincs telepítve"

#: app/flatpak-cli-transaction.c:537
#, fuzzy, c-format
msgid "Warning: %s%s%s needs a later flatpak version"
msgstr "A(z) %s egy későbbi flatpak verziót (%s) igényel"

#: app/flatpak-cli-transaction.c:540
#, fuzzy, c-format
msgid "Error: %s%s%s needs a later flatpak version"
msgstr "A(z) %s egy későbbi flatpak verziót (%s) igényel"

#: app/flatpak-cli-transaction.c:546
msgid "Warning: Not enough disk space to complete this operation"
msgstr ""

#: app/flatpak-cli-transaction.c:548
msgid "Error: Not enough disk space to complete this operation"
msgstr ""

#: app/flatpak-cli-transaction.c:553
#, c-format
msgid "Warning: %s"
msgstr ""

#: app/flatpak-cli-transaction.c:555
#, fuzzy, c-format
msgid "Error: %s"
msgstr "hiba:"

#: app/flatpak-cli-transaction.c:570
#, fuzzy, c-format
msgid "Failed to install %s%s%s: "
msgstr "Hiba: %s %s sikertelen: %s\n"

#: app/flatpak-cli-transaction.c:577
#, fuzzy, c-format
msgid "Failed to update %s%s%s: "
msgstr "Hiba: %s %s sikertelen: %s\n"

#: app/flatpak-cli-transaction.c:584
#, fuzzy, c-format
msgid "Failed to install bundle %s%s%s: "
msgstr "Hiba: %s %s sikertelen: %s\n"

#: app/flatpak-cli-transaction.c:591
#, fuzzy, c-format
msgid "Failed to uninstall %s%s%s: "
msgstr "Hiba: %s %s sikertelen: %s\n"

#: app/flatpak-cli-transaction.c:642
#, fuzzy, c-format
msgid "Authentication required for remote '%s'\n"
msgstr "Hitelesítés szükséges a szoftver frissítéséhez"

#: app/flatpak-cli-transaction.c:643
msgid "Open browser?"
msgstr ""

#: app/flatpak-cli-transaction.c:699
#, c-format
msgid "Login required remote %s (realm %s)\n"
msgstr ""

#: app/flatpak-cli-transaction.c:704
msgid "Password"
msgstr ""

#. Only runtimes can be pinned
#: app/flatpak-cli-transaction.c:759
#, c-format
msgid ""
"\n"
"Info: (pinned) runtime %s%s%s branch %s%s%s is end-of-life, in favor of "
"%s%s%s branch %s%s%s\n"
msgstr ""

#: app/flatpak-cli-transaction.c:765
#, c-format
msgid ""
"\n"
"Info: runtime %s%s%s branch %s%s%s is end-of-life, in favor of %s%s%s branch "
"%s%s%s\n"
msgstr ""

#: app/flatpak-cli-transaction.c:768
#, c-format
msgid ""
"\n"
"Info: app %s%s%s branch %s%s%s is end-of-life, in favor of %s%s%s branch "
"%s%s%s\n"
msgstr ""

#. Only runtimes can be pinned
#: app/flatpak-cli-transaction.c:780
#, c-format
msgid ""
"\n"
"Info: (pinned) runtime %s%s%s branch %s%s%s is end-of-life, with reason:\n"
msgstr ""

#: app/flatpak-cli-transaction.c:786
#, c-format
msgid ""
"\n"
"Info: runtime %s%s%s branch %s%s%s is end-of-life, with reason:\n"
msgstr ""

#: app/flatpak-cli-transaction.c:789
#, c-format
msgid ""
"\n"
"Info: app %s%s%s branch %s%s%s is end-of-life, with reason:\n"
msgstr ""

#: app/flatpak-cli-transaction.c:963
#, fuzzy, c-format
msgid "Info: applications using this extension:\n"
msgstr ""
"\n"
"Alkalmazás és futtatókörnyezet keresése"

#: app/flatpak-cli-transaction.c:965
#, fuzzy, c-format
msgid "Info: applications using this runtime:\n"
msgstr ""
"\n"
"Alkalmazás és futtatókörnyezet keresése"

#: app/flatpak-cli-transaction.c:984
msgid "Replace?"
msgstr ""

#: app/flatpak-cli-transaction.c:987 app/flatpak-quiet-transaction.c:247
#, fuzzy, c-format
msgid "Updating to rebased version\n"
msgstr "Az AppStream ág frissítése\n"

#: app/flatpak-cli-transaction.c:1011
#, fuzzy, c-format
msgid "Failed to rebase %s to %s: "
msgstr "Hiba: %s %s sikertelen: %s\n"

#: app/flatpak-cli-transaction.c:1277
#, fuzzy, c-format
msgid "New %s%s%s permissions:"
msgstr "Jogosultságok megjelenítése"

#: app/flatpak-cli-transaction.c:1279
#, fuzzy, c-format
msgid "%s%s%s permissions:"
msgstr "Jogosultságok megjelenítése"

#: app/flatpak-cli-transaction.c:1343
msgid "Warning: "
msgstr ""

#. translators: This is short for operation, the title of a one-char column
#: app/flatpak-cli-transaction.c:1442
msgid "Op"
msgstr ""

#. Avoid resizing the download column too much,
#. * by making the title as long as typical content
#.
#: app/flatpak-cli-transaction.c:1458 app/flatpak-cli-transaction.c:1503
msgid "partial"
msgstr ""

#: app/flatpak-cli-transaction.c:1535
#, fuzzy
msgid "Proceed with these changes to the user installation?"
msgstr "Felhasználói telepítések megjelenítése"

#: app/flatpak-cli-transaction.c:1537
#, fuzzy
msgid "Proceed with these changes to the system installation?"
msgstr "Felhasználói telepítések megjelenítése"

#: app/flatpak-cli-transaction.c:1539
#, fuzzy, c-format
msgid "Proceed with these changes to the %s?"
msgstr "Felhasználói telepítések megjelenítése"

#: app/flatpak-cli-transaction.c:1711
msgid "Changes complete."
msgstr ""

#: app/flatpak-cli-transaction.c:1713
#, fuzzy
msgid "Uninstall complete."
msgstr "Alkalmazás eltávolítása"

#: app/flatpak-cli-transaction.c:1715
#, fuzzy
msgid "Installation complete."
msgstr "Telepítve"

#: app/flatpak-cli-transaction.c:1717
#, fuzzy
msgid "Updates complete."
msgstr "Távoli metaadatok frissítése"

#. For updates/!stop_on_first_error we already printed all errors so we make up
#. a different one.
#: app/flatpak-cli-transaction.c:1750
msgid "There were one or more errors"
msgstr ""

#. translators: please keep the leading space
#: app/flatpak-main.c:76
#, fuzzy
msgid " Manage installed applications and runtimes"
msgstr " Telepített alkalmazások és futtatókörnyezetek kezelése"

#: app/flatpak-main.c:77
msgid "Install an application or runtime"
msgstr "Egy alkalmazás vagy futtatókörnyezet telepítése"

#: app/flatpak-main.c:78
msgid "Update an installed application or runtime"
msgstr "Telepített alkalmazás vagy futtatókörnyezet frissítése"

#: app/flatpak-main.c:81
msgid "Uninstall an installed application or runtime"
msgstr "Telepített alkalmazás vagy futtatókörnyezet eltávolítása"

#: app/flatpak-main.c:84
msgid "Mask out updates and automatic installation"
msgstr ""

#: app/flatpak-main.c:85
msgid "Pin a runtime to prevent automatic removal"
msgstr ""

#: app/flatpak-main.c:86
msgid "List installed apps and/or runtimes"
msgstr "Telepített alkalmazások és/vagy futtatókörnyezetek felsorolása"

#: app/flatpak-main.c:87
msgid "Show info for installed app or runtime"
msgstr ""
"Információk megjelenítése a telepített alkalmazáshoz vagy futtatókörnyezethez"

#: app/flatpak-main.c:88
#, fuzzy
msgid "Show history"
msgstr "Kommit megjelenítése"

#: app/flatpak-main.c:89
msgid "Configure flatpak"
msgstr "Flatpak beállítása"

#: app/flatpak-main.c:90
#, fuzzy
msgid "Repair flatpak installation"
msgstr "Felhasználói telepítések megjelenítése"

#: app/flatpak-main.c:91
msgid "Put applications or runtimes onto removable media"
msgstr ""

#: app/flatpak-main.c:92
msgid "Install flatpaks that are part of the operating system"
msgstr ""

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:95
#, fuzzy
msgid ""
"\n"
" Find applications and runtimes"
msgstr ""
"\n"
"Alkalmazás és futtatókörnyezet keresése"

#: app/flatpak-main.c:96
msgid "Search for remote apps/runtimes"
msgstr "Távoli alkalmazások vagy futtatókörnyezetek keresése"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:99
#, fuzzy
msgid ""
"\n"
" Manage running applications"
msgstr ""
"\n"
" Futó alkalmazások"

#: app/flatpak-main.c:100
msgid "Run an application"
msgstr "Alkalmazás futtatása"

#: app/flatpak-main.c:101
msgid "Override permissions for an application"
msgstr "Jogosultságok felülbírálása egy alkalmazásnál"

#: app/flatpak-main.c:102
msgid "Specify default version to run"
msgstr "Alapértelmezett verzió megadása a futtatáshoz"

#: app/flatpak-main.c:103
msgid "Enter the namespace of a running application"
msgstr "Futó alkalmazás névterének megadása"

#: app/flatpak-main.c:104
#, fuzzy
msgid "Enumerate running applications"
msgstr ""
"\n"
" Futó alkalmazások"

#: app/flatpak-main.c:105
#, fuzzy
msgid "Stop a running application"
msgstr ""
"\n"
" Futó alkalmazások"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:108
msgid ""
"\n"
" Manage file access"
msgstr ""
"\n"
" Fájlhozzáférés kezelése"

#: app/flatpak-main.c:109
msgid "List exported files"
msgstr "Exportált fájlok felsorolása"

#: app/flatpak-main.c:110
msgid "Grant an application access to a specific file"
msgstr "Hozzáférés adása egy alkalmazásnak egy bizonyos fájlhoz"

#: app/flatpak-main.c:111
msgid "Revoke access to a specific file"
msgstr "Hozzáférés visszavonása egy bizonyos fájlhoz"

#: app/flatpak-main.c:112
msgid "Show information about a specific file"
msgstr "Információk megjelenítése egy bizonyos fájlról"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:116
#, fuzzy
msgid ""
"\n"
" Manage dynamic permissions"
msgstr "Jogosultságok megjelenítése"

#: app/flatpak-main.c:117
#, fuzzy
msgid "List permissions"
msgstr "Jogosultságok megjelenítése"

#: app/flatpak-main.c:118
#, fuzzy
msgid "Remove item from permission store"
msgstr "Az alkalmazás írási jogosultságának visszavonása"

#: app/flatpak-main.c:120
#, fuzzy
msgid "Set permissions"
msgstr "Jogosultságok megjelenítése"

#: app/flatpak-main.c:121
#, fuzzy
msgid "Show app permissions"
msgstr "Jogosultságok megjelenítése"

#: app/flatpak-main.c:122
#, fuzzy
msgid "Reset app permissions"
msgstr "Jogosultságok megjelenítése"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:125
msgid ""
"\n"
" Manage remote repositories"
msgstr ""
"\n"
" Távoli tárolók kezelése"

#: app/flatpak-main.c:126
msgid "List all configured remotes"
msgstr "Az összes beállított távoli felsorolása"

#: app/flatpak-main.c:127
msgid "Add a new remote repository (by URL)"
msgstr "Új távoli tároló hozzáadása (URL alapján)"

#: app/flatpak-main.c:128
msgid "Modify properties of a configured remote"
msgstr "Beállított távoli tulajdonságainak módosítása"

#: app/flatpak-main.c:129
msgid "Delete a configured remote"
msgstr "Beállított távoli törlése"

#: app/flatpak-main.c:131
msgid "List contents of a configured remote"
msgstr "Beállított távoli tartalmának felsorolása"

#: app/flatpak-main.c:132
msgid "Show information about a remote app or runtime"
msgstr ""
"Információk megjelenítése a távoli alkalmazáshoz vagy futtatókörnyezethez"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:135
msgid ""
"\n"
" Build applications"
msgstr ""
"\n"
" Alkalmazások összeállítása"

#: app/flatpak-main.c:136
msgid "Initialize a directory for building"
msgstr "Könyvtár előkészítése az összeállításhoz"

#: app/flatpak-main.c:137
msgid "Run a build command inside the build dir"
msgstr "Összeállítási parancs futtatása az összeállítási könyvtáron belül"

#: app/flatpak-main.c:138
msgid "Finish a build dir for export"
msgstr "Összeállítási könyvtár befejezése exportáláshoz"

#: app/flatpak-main.c:139
msgid "Export a build dir to a repository"
msgstr "Összeállítási könyvtár exportálása tárolóba"

#: app/flatpak-main.c:140
msgid "Create a bundle file from a ref in a local repository"
msgstr "Csomagfájl létrehozása egy hivatkozásból egy helyi tárolóban"

#: app/flatpak-main.c:141
msgid "Import a bundle file"
msgstr "Csomagfájl importálása"

#: app/flatpak-main.c:142
msgid "Sign an application or runtime"
msgstr "Alkalmazás vagy futtatókörnyezet aláírása"

#: app/flatpak-main.c:143
msgid "Update the summary file in a repository"
msgstr "Az összegzőfájl frissítése egy tárolóban"

#: app/flatpak-main.c:144
msgid "Create new commit based on existing ref"
msgstr "Új kommit létrehozása meglévő hivatkozás alapján"

#: app/flatpak-main.c:145
#, fuzzy
msgid "Show information about a repo"
msgstr "Információk kiírása egy tárolóról"

#: app/flatpak-main.c:162
#, fuzzy
msgid "Show debug information, -vv for more detail"
msgstr ""
"Hibakeresési információk kiírása a parancsfeldolgozás közben, -vv a több "
"részlethez"

#: app/flatpak-main.c:163
#, fuzzy
msgid "Show OSTree debug information"
msgstr "További információk megjelenítése"

#: app/flatpak-main.c:169
msgid "Print version information and exit"
msgstr "Verzióinformációk kiírása és kilépés"

#: app/flatpak-main.c:170
msgid "Print default arch and exit"
msgstr "Alapértelmezett architektúra kiírása és kilépés"

#: app/flatpak-main.c:171
msgid "Print supported arches and exit"
msgstr "Támogatott architektúrák kiírása és kilépés"

#: app/flatpak-main.c:172
msgid "Print active gl drivers and exit"
msgstr "Aktív gl illesztőprogramok kiírása és kilépés"

#: app/flatpak-main.c:173
#, fuzzy
msgid "Print paths for system installations and exit"
msgstr "Verzióinformációk kiírása és kilépés"

#: app/flatpak-main.c:174
msgid "Print the updated environment needed to run flatpaks"
msgstr ""

#: app/flatpak-main.c:175
msgid "Only include the system installation with --print-updated-env"
msgstr ""

#: app/flatpak-main.c:180
#, fuzzy
msgid "Work on the user installation"
msgstr "Munkavégzés a felhasználói telepítéseken"

#: app/flatpak-main.c:181
#, fuzzy
msgid "Work on the system-wide installation (default)"
msgstr "Munkavégzés a rendszerszintű telepítéseken (alapértelmezett)"

#: app/flatpak-main.c:182
#, fuzzy
msgid "Work on a non-default system-wide installation"
msgstr "Munkavégzés adott rendszerszintű telepítés(ek)en"

#: app/flatpak-main.c:212
msgid "Builtin Commands:"
msgstr "Beépített parancsok:"

#: app/flatpak-main.c:298
#, c-format
msgid ""
"Note that the directories %s are not in the search path set by the "
"XDG_DATA_DIRS environment variable, so applications installed by Flatpak may "
"not appear on your desktop until the session is restarted."
msgstr ""

#: app/flatpak-main.c:312
#, c-format
msgid ""
"Note that the directory %s is not in the search path set by the "
"XDG_DATA_DIRS environment variable, so applications installed by Flatpak may "
"not appear on your desktop until the session is restarted."
msgstr ""

#: app/flatpak-main.c:381
msgid ""
"Refusing to operate under sudo with --user. Omit sudo to operate on the user "
"installation, or use a root shell to operate on the root user's installation."
msgstr ""

#: app/flatpak-main.c:453
#, fuzzy
msgid ""
"Multiple installations specified for a command that works on one installation"
msgstr ""
"Az --installation kapcsoló többször volt használva egy olyan parancsnál, "
"amely csak egy telepítésnél működik"

#: app/flatpak-main.c:504 app/flatpak-main.c:697
#, c-format
msgid "See '%s --help'"
msgstr ""

#: app/flatpak-main.c:706
#, fuzzy, c-format
msgid "'%s' is not a flatpak command. Did you mean '%s%s'?"
msgstr "A(z) „%s” nem érvényes alkalmazásnév: %s"

#: app/flatpak-main.c:709
#, c-format
msgid "'%s' is not a flatpak command"
msgstr ""

#: app/flatpak-main.c:824
msgid "No command specified"
msgstr "Nincs parancs megadva"

#: app/flatpak-main.c:980
msgid "error:"
msgstr "hiba:"

#: app/flatpak-quiet-transaction.c:77
#, fuzzy, c-format
msgid "Installing %s\n"
msgstr "Telepítés: %s\n"

#: app/flatpak-quiet-transaction.c:81
#, fuzzy, c-format
msgid "Updating %s\n"
msgstr "Összegzés frissítése\n"

#: app/flatpak-quiet-transaction.c:85
#, fuzzy, c-format
msgid "Uninstalling %s\n"
msgstr "Telepítés: %s innen: %s\n"

#: app/flatpak-quiet-transaction.c:107
#, fuzzy, c-format
msgid "Warning: Failed to install %s: %s\n"
msgstr "Figyelmeztetés: %s %s sikertelen: %s\n"

#: app/flatpak-quiet-transaction.c:110
#, fuzzy, c-format
msgid "Error: Failed to install %s: %s\n"
msgstr "Hiba: %s %s sikertelen: %s\n"

#: app/flatpak-quiet-transaction.c:116
#, fuzzy, c-format
msgid "Warning: Failed to update %s: %s\n"
msgstr "Figyelmeztetés: %s %s sikertelen: %s\n"

#: app/flatpak-quiet-transaction.c:119
#, fuzzy, c-format
msgid "Error: Failed to update %s: %s\n"
msgstr "Hiba: %s %s sikertelen: %s\n"

#: app/flatpak-quiet-transaction.c:125
#, fuzzy, c-format
msgid "Warning: Failed to install bundle %s: %s\n"
msgstr "Figyelmeztetés: %s %s sikertelen: %s\n"

#: app/flatpak-quiet-transaction.c:128
#, fuzzy, c-format
msgid "Error: Failed to install bundle %s: %s\n"
msgstr "Hiba: %s %s sikertelen: %s\n"

#: app/flatpak-quiet-transaction.c:134
#, fuzzy, c-format
msgid "Warning: Failed to uninstall %s: %s\n"
msgstr "Figyelmeztetés: %s %s sikertelen: %s\n"

#: app/flatpak-quiet-transaction.c:137
#, fuzzy, c-format
msgid "Error: Failed to uninstall %s: %s\n"
msgstr "Hiba: %s %s sikertelen: %s\n"

#: app/flatpak-quiet-transaction.c:166 common/flatpak-dir.c:11475
#, fuzzy, c-format
msgid "%s already installed"
msgstr "A(z) %s kommit %s már telepítve van"

#: app/flatpak-quiet-transaction.c:168 common/flatpak-dir.c:3622
#: common/flatpak-dir.c:4321 common/flatpak-dir.c:16968
#: common/flatpak-dir.c:17258 common/flatpak-dir-utils.c:166
#: common/flatpak-dir-utils.c:259 common/flatpak-transaction.c:2736
#: common/flatpak-transaction.c:2791
#, c-format
msgid "%s not installed"
msgstr "A(z) %s nincs telepítve"

#: app/flatpak-quiet-transaction.c:170
#, fuzzy, c-format
msgid "%s needs a later flatpak version"
msgstr "A(z) %s egy későbbi flatpak verziót (%s) igényel"

#: app/flatpak-quiet-transaction.c:172
msgid "Not enough disk space to complete this operation"
msgstr ""

#: app/flatpak-quiet-transaction.c:239
#, c-format
msgid "Info: %s is end-of-life, in favor of %s\n"
msgstr ""

#: app/flatpak-quiet-transaction.c:241
#, c-format
msgid "Info: %s is end-of-life, with reason: %s\n"
msgstr ""

#: app/flatpak-quiet-transaction.c:251
#, fuzzy, c-format
msgid "Failed to rebase %s to %s: %s\n"
msgstr "Hiba: %s %s sikertelen: %s\n"

#: common/flatpak-auth.c:58
#, fuzzy, c-format
msgid "No authenticator configured for remote `%s`"
msgstr "Hitelesítés szükséges a szoftver frissítéséhez"

#: common/flatpak-context.c:637 common/flatpak-context.c:649
#, fuzzy, c-format
msgid "Invalid permission syntax: %s"
msgstr "Ismeretlen %s D-Bus név\n"

#: common/flatpak-context.c:1207
#, c-format
msgid "Unknown share type %s, valid types are: %s"
msgstr "Ismeretlen %s megosztástípus, az érvényes típusok: %s"

#: common/flatpak-context.c:1228
#, c-format
msgid "Unknown policy type %s, valid types are: %s"
msgstr "Ismeretlen %s házirendtípus, az érvényes típusok: %s"

#: common/flatpak-context.c:1266
#, fuzzy, c-format
msgid "Invalid dbus name %s"
msgstr "Ismeretlen %s D-Bus név\n"

#: common/flatpak-context.c:1279
#, c-format
msgid "Unknown socket type %s, valid types are: %s"
msgstr "Ismeretlen %s foglalattípus, az érvényes típusok: %s"

#: common/flatpak-context.c:1294
#, c-format
msgid "Unknown device type %s, valid types are: %s"
msgstr "Ismeretlen %s eszköztípus, az érvényes típusok: %s"

#: common/flatpak-context.c:1308
#, c-format
msgid "Unknown feature type %s, valid types are: %s"
msgstr "Ismeretlen %s jellemzőtípus, az érvényes típusok: %s"

#: common/flatpak-context.c:1840
#, c-format
msgid "Filesystem location \"%s\" contains \"..\""
msgstr ""

#: common/flatpak-context.c:1882
#, c-format
msgid ""
"--filesystem=/ is not available, use --filesystem=host for a similar result"
msgstr ""

#: common/flatpak-context.c:1916
#, fuzzy, c-format
msgid ""
"Unknown filesystem location %s, valid locations are: host, host-os, host-"
"etc, host-root, home, xdg-*[/…], ~/dir, /dir"
msgstr ""
"Ismeretlen %s fájlrendszer hely, az érvényes típusok: gép, saját könyvtár, "
"xdg-*[/...], ~/könyvtár, /könyvtár"

#: common/flatpak-context.c:2015
#, fuzzy, c-format
msgid "Invalid syntax for %s: %s"
msgstr "Ismeretlen %s D-Bus név\n"

#: common/flatpak-context.c:2142
#, c-format
msgid "fallback-x11 can not be conditional"
msgstr ""

#: common/flatpak-context.c:2318
#, c-format
msgid "Invalid env format %s"
msgstr "Érvénytelen %s env formátum"

#: common/flatpak-context.c:2399
#, c-format
msgid "Environment variable name must not contain '=': %s"
msgstr ""

#: common/flatpak-context.c:2527 common/flatpak-context.c:2535
#, c-format
msgid "--add-policy arguments must be in the form SUBSYSTEM.KEY=VALUE"
msgstr ""

#: common/flatpak-context.c:2542
#, c-format
msgid "--add-policy values can't start with \"!\""
msgstr ""

#: common/flatpak-context.c:2567 common/flatpak-context.c:2575
#, c-format
msgid "--remove-policy arguments must be in the form SUBSYSTEM.KEY=VALUE"
msgstr ""

#: common/flatpak-context.c:2582
#, c-format
msgid "--remove-policy values can't start with \"!\""
msgstr ""

#: common/flatpak-context.c:2657
msgid "Share with host"
msgstr "Megosztás a gazdagéppel"

#: common/flatpak-context.c:2657 common/flatpak-context.c:2658
msgid "SHARE"
msgstr "MEGOSZTÁS"

#: common/flatpak-context.c:2658
msgid "Unshare with host"
msgstr "Megosztás megszüntetése a gazdagéppel"

#: common/flatpak-context.c:2659
msgid "Require conditions to be met for a subsystem to get shared"
msgstr ""

#: common/flatpak-context.c:2659
msgid "SHARE:CONDITION"
msgstr ""

#: common/flatpak-context.c:2660
msgid "Expose socket to app"
msgstr "Foglalat elérhetővé tétele az alkalmazásnak"

#: common/flatpak-context.c:2660 common/flatpak-context.c:2661
msgid "SOCKET"
msgstr "FOGLALAT"

#: common/flatpak-context.c:2661
msgid "Don't expose socket to app"
msgstr "Ne tegye elérhetővé a foglalatot az alkalmazásnak"

#: common/flatpak-context.c:2662
msgid "Require conditions to be met for a socket to get exposed"
msgstr ""

#: common/flatpak-context.c:2662
msgid "SOCKET:CONDITION"
msgstr ""

#: common/flatpak-context.c:2663
msgid "Expose device to app"
msgstr "Eszköz elérhetővé tétele az alkalmazásnak"

#: common/flatpak-context.c:2663 common/flatpak-context.c:2664
msgid "DEVICE"
msgstr "ESZKÖZ"

#: common/flatpak-context.c:2664
msgid "Don't expose device to app"
msgstr "Ne tegye elérhetővé az eszközt az alkalmazásnak"

#: common/flatpak-context.c:2665
msgid "Require conditions to be met for a device to get exposed"
msgstr ""

#: common/flatpak-context.c:2665
msgid "DEVICE:CONDITION"
msgstr ""

#: common/flatpak-context.c:2666
msgid "Allow feature"
msgstr "Jellemző engedélyezése"

#: common/flatpak-context.c:2666 common/flatpak-context.c:2667
msgid "FEATURE"
msgstr "JELLEMZŐ"

#: common/flatpak-context.c:2667
msgid "Don't allow feature"
msgstr "Ne engedélyezze a jellemzőt"

#: common/flatpak-context.c:2668
msgid "Require conditions to be met for a feature to get allowed"
msgstr ""

#: common/flatpak-context.c:2668
msgid "FEATURE:CONDITION"
msgstr ""

#: common/flatpak-context.c:2669
msgid "Expose filesystem to app (:ro for read-only)"
msgstr ""
"Fájlrendszer elérhetővé tétele az alkalmazásnak (:ro a csak olvashatóhoz)"

#: common/flatpak-context.c:2669
msgid "FILESYSTEM[:ro]"
msgstr "FÁJLRENDSZER[:ro]"

#: common/flatpak-context.c:2670
msgid "Don't expose filesystem to app"
msgstr "Ne tegye elérhetővé a fájlrendszert az alkalmazásnak"

#: common/flatpak-context.c:2670
msgid "FILESYSTEM"
msgstr "FÁJLRENDSZER"

#: common/flatpak-context.c:2671
msgid "Set environment variable"
msgstr "Környezeti változó beállítása"

#: common/flatpak-context.c:2671
msgid "VAR=VALUE"
msgstr "VÁLTOZÓ=ÉRTÉK"

#: common/flatpak-context.c:2672
msgid "Read environment variables in env -0 format from FD"
msgstr ""

#: common/flatpak-context.c:2673
#, fuzzy
msgid "Remove variable from environment"
msgstr "Az alkalmazás írási jogosultságának visszavonása"

#: common/flatpak-context.c:2673
#, fuzzy
msgid "VAR"
msgstr "VÁLTOZÓ=ÉRTÉK"

#: common/flatpak-context.c:2674
msgid "Allow app to own name on the session bus"
msgstr "Név birtoklásának lehetővé tétele az alkalmazásnak a munkamenetbuszon"

#: common/flatpak-context.c:2674 common/flatpak-context.c:2675
#: common/flatpak-context.c:2676 common/flatpak-context.c:2677
#: common/flatpak-context.c:2678 common/flatpak-context.c:2679
#: common/flatpak-context.c:2680
msgid "DBUS_NAME"
msgstr "DBUS_NÉV"

#: common/flatpak-context.c:2675
msgid "Allow app to talk to name on the session bus"
msgstr ""
"A névhez való beszéd lehetővé tétele az alkalmazásnak a munkamenetbuszon"

#: common/flatpak-context.c:2676
#, fuzzy
msgid "Don't allow app to talk to name on the session bus"
msgstr ""
"A névhez való beszéd lehetővé tétele az alkalmazásnak a munkamenetbuszon"

#: common/flatpak-context.c:2677
msgid "Allow app to own name on the system bus"
msgstr "Név birtoklásának lehetővé tétele az alkalmazásnak a rendszerbuszon"

#: common/flatpak-context.c:2678
msgid "Allow app to talk to name on the system bus"
msgstr "A névhez való beszéd lehetővé tétele az alkalmazásnak a rendszerbuszon"

#: common/flatpak-context.c:2679
#, fuzzy
msgid "Don't allow app to talk to name on the system bus"
msgstr "A névhez való beszéd lehetővé tétele az alkalmazásnak a rendszerbuszon"

#: common/flatpak-context.c:2680
#, fuzzy
msgid "Allow app to own name on the a11y bus"
msgstr "Név birtoklásának lehetővé tétele az alkalmazásnak a rendszerbuszon"

#: common/flatpak-context.c:2681
msgid "Add generic policy option"
msgstr "Általános irányelv-lehetőség hozzáadása"

#: common/flatpak-context.c:2681 common/flatpak-context.c:2682
msgid "SUBSYSTEM.KEY=VALUE"
msgstr "ALRENDSZER.KULCS=ÉRTÉK"

#: common/flatpak-context.c:2682
msgid "Remove generic policy option"
msgstr "Általános irányelv-lehetőség eltávolítása"

#: common/flatpak-context.c:2683
msgid "Add USB device to enumerables"
msgstr ""

#: common/flatpak-context.c:2683 common/flatpak-context.c:2684
msgid "VENDOR_ID:PRODUCT_ID"
msgstr ""

#: common/flatpak-context.c:2684
msgid "Add USB device to hidden list"
msgstr ""

#: common/flatpak-context.c:2685
msgid "A list of USB devices that are enumerable"
msgstr ""

#: common/flatpak-context.c:2685
msgid "LIST"
msgstr ""

#: common/flatpak-context.c:2686
msgid "File containing a list of USB devices to make enumerable"
msgstr ""

#: common/flatpak-context.c:2686 common/flatpak-context.c:2687
msgid "FILENAME"
msgstr "FÁJLNÉV"

#: common/flatpak-context.c:2687
#, fuzzy
msgid "Persist home directory subpath"
msgstr "Saját könyvtár megőrzése"

#. This is not needed/used anymore, so hidden, but we accept it for backwards compat
#: common/flatpak-context.c:2689
msgid "Don't require a running session (no cgroups creation)"
msgstr "Ne követeljen meg egy futó munkamenetet (nincs cgroups létrehozás)"

#: common/flatpak-context.c:3718
#, c-format
msgid "Not replacing \"%s\" with tmpfs: %s"
msgstr ""

#: common/flatpak-context.c:3726
#, c-format
msgid "Not sharing \"%s\" with sandbox: %s"
msgstr ""

#. Even if the error is one that we would normally silence, like
#. * the path not existing, it seems reasonable to make more of a fuss
#. * about the home directory not existing or otherwise being unusable,
#. * so this is intentionally not using cannot_export()
#: common/flatpak-context.c:3828
#, c-format
msgid "Not allowing home directory access: %s"
msgstr ""

#: common/flatpak-context.c:4062
#, fuzzy, c-format
msgid "Unable to provide a temporary home directory in the sandbox: %s"
msgstr "Nem lehet létrehozni a telepítési könyvtárat"

#: common/flatpak-dir.c:442
#, c-format
msgid "Configured collection ID ‘%s’ not in summary file"
msgstr ""

#: common/flatpak-dir.c:587
#, fuzzy, c-format
msgid "Unable to load summary from remote %s: %s"
msgstr "A(z) %s lekérése közben a(z) %s távoliról: "

#: common/flatpak-dir.c:764 common/flatpak-dir.c:800 common/flatpak-dir.c:906
#, fuzzy, c-format
msgid "No such ref '%s' in remote %s"
msgstr "A(z) %s nem található a(z) %s távoliban"

#: common/flatpak-dir.c:891 common/flatpak-dir.c:1051 common/flatpak-dir.c:1080
#: common/flatpak-dir.c:1092
#, fuzzy, c-format
msgid "No entry for %s in remote %s summary flatpak cache"
msgstr ""
"Nincs bejegyzés a(z) %s esetén a távoli összegzés flatpak gyorsítótárban "

#: common/flatpak-dir.c:1069
#, fuzzy, c-format
msgid "No summary or Flatpak cache available for remote %s"
msgstr "Nincs flatpak gyorsítótár a távoli összegzésben"

#: common/flatpak-dir.c:1097
#, fuzzy, c-format
msgid "Missing xa.data in summary for remote %s"
msgstr "Nincs flatpak gyorsítótár a távoli összegzésben"

#: common/flatpak-dir.c:1103 common/flatpak-dir.c:1546
#, fuzzy, c-format
msgid "Unsupported summary version %d for remote %s"
msgstr "Nincs flatpak gyorsítótár a távoli összegzésben"

#: common/flatpak-dir.c:1200
msgid "Remote OCI index has no registry uri"
msgstr "A távoli OCI indexnek nincs regisztrációs URI-ja"

#: common/flatpak-dir.c:1261
#, fuzzy, c-format
msgid "Couldn't find ref %s in remote %s"
msgstr ""
"Nem sikerült megtalálni a legújabb verziót a(z) %s hivatkozáshoz a(z) %s "
"távoliból: %s\n"

#: common/flatpak-dir.c:1288 common/flatpak-dir.c:1381
#, c-format
msgid "Commit has no requested ref ‘%s’ in ref binding metadata (found: ‘%s’)"
msgstr ""

#: common/flatpak-dir.c:1413
#, c-format
msgid "Configured collection ID ‘%s’ not in binding metadata"
msgstr ""

#: common/flatpak-dir.c:1449 common/flatpak-dir.c:5645
#, fuzzy, c-format
msgid "Couldn't find latest checksum for ref %s in remote %s"
msgstr ""
"Nem sikerült megtalálni a legújabb verziót a(z) %s hivatkozáshoz a(z) %s "
"távoliból: %s\n"

#: common/flatpak-dir.c:1516 common/flatpak-dir.c:1552
#, fuzzy, c-format
msgid "No entry for %s in remote %s summary flatpak sparse cache"
msgstr ""
"Nincs bejegyzés a(z) %s esetén a távoli összegzés flatpak gyorsítótárban "

#: common/flatpak-dir.c:2540
#, c-format
msgid "Commit metadata for %s not matching expected metadata"
msgstr ""

#: common/flatpak-dir.c:2823
#, fuzzy
msgid "Unable to connect to system bus"
msgstr "Név birtoklásának lehetővé tétele az alkalmazásnak a rendszerbuszon"

#: common/flatpak-dir.c:3419
#, fuzzy
msgid "User installation"
msgstr "Felhasználói telepítések megjelenítése"

#: common/flatpak-dir.c:3426
#, fuzzy, c-format
msgid "System (%s) installation"
msgstr "Felhasználói telepítések megjelenítése"

#: common/flatpak-dir.c:3472
#, c-format
msgid "No overrides found for %s"
msgstr "Nem találhatók felülbírálások ehhez: %s"

#: common/flatpak-dir.c:3625
#, fuzzy, c-format
msgid "%s (commit %s) not installed"
msgstr "A(z) %s %s nincs telepítve"

#: common/flatpak-dir.c:4650
#, fuzzy, c-format
msgid "Error parsing system flatpakrepo file for %s: %s"
msgstr "Hiba a(z) „%s” távoli metaadatainak frissítéskor: %s\n"

#: common/flatpak-dir.c:4735
#, c-format
msgid "While opening repository %s: "
msgstr "A(z) %s tároló megnyitása közben: "

#: common/flatpak-dir.c:5004
#, c-format
msgid "The config key %s is not set"
msgstr ""

#: common/flatpak-dir.c:5140
#, fuzzy, c-format
msgid "No current %s pattern matching %s"
msgstr "Ne frissítse a kapcsolódó hivatkozásokat"

#: common/flatpak-dir.c:5422
#, fuzzy
msgid "No appstream commit to deploy"
msgstr "Telepítendő kommit"

#: common/flatpak-dir.c:5941 common/flatpak-dir.c:7266
#: common/flatpak-dir.c:10881 common/flatpak-dir.c:11618
msgid "Can't pull from untrusted non-gpg verified remote"
msgstr ""

#: common/flatpak-dir.c:6376 common/flatpak-dir.c:6591
msgid "Extra data not supported for non-gpg-verified local system installs"
msgstr ""

#: common/flatpak-dir.c:6415 common/flatpak-dir.c:6782
#, fuzzy, c-format
msgid "Invalid checksum for extra data uri %s"
msgstr "Érvénytelen ellenőrzőösszeg a(z) %s további adatnál"

#: common/flatpak-dir.c:6424
#, c-format
msgid "Empty name for extra data uri %s"
msgstr "Üres név a további adat URI-nál: %s"

#: common/flatpak-dir.c:6432
#, c-format
msgid "Unsupported extra data uri %s"
msgstr "Nem támogatott további adat URI: %s"

#: common/flatpak-dir.c:6461
#, c-format
msgid "Failed to load local extra-data %s: %s"
msgstr "Nem sikerült a(z) %s helyi további adat betöltése: %s"

#: common/flatpak-dir.c:6469
#, c-format
msgid "Wrong size for extra-data %s"
msgstr "Hibás méret a(z) %s további adatnál"

#: common/flatpak-dir.c:6488
#, c-format
msgid "While downloading %s: "
msgstr "A(z) %s letöltése közben: "

#: common/flatpak-dir.c:6498
#, c-format
msgid "Wrong size for extra data %s"
msgstr "Hibás méret a(z) %s további adatnál"

#: common/flatpak-dir.c:6507
#, c-format
msgid "Invalid checksum for extra data %s"
msgstr "Érvénytelen ellenőrzőösszeg a(z) %s további adatnál"

#: common/flatpak-dir.c:7096 common/flatpak-dir.c:7349
#, c-format
msgid "While pulling %s from remote %s: "
msgstr "A(z) %s lekérése közben a(z) %s távoliról: "

#: common/flatpak-dir.c:7290 common/flatpak-repo-utils.c:3886
msgid "GPG signatures found, but none are in trusted keyring"
msgstr ""

#: common/flatpak-dir.c:7307
#, c-format
msgid "Commit for ‘%s’ has no ref binding"
msgstr ""

#: common/flatpak-dir.c:7312
#, c-format
msgid "Commit for ‘%s’ is not in expected bound refs: %s"
msgstr ""

#: common/flatpak-dir.c:7488
#, fuzzy
msgid "Only applications can be made current"
msgstr ""
"\n"
"Alkalmazás és futtatókörnyezet keresése"

#: common/flatpak-dir.c:8192
msgid "Not enough memory"
msgstr "Nincs elég memória"

#: common/flatpak-dir.c:8211
msgid "Failed to read from exported file"
msgstr "Nem sikerült olvasni az exportált fájlból"

#: common/flatpak-dir.c:8401
msgid "Error reading mimetype xml file"
msgstr "Hiba a MIME-típus XML-fájl olvasásakor"

#: common/flatpak-dir.c:8406
msgid "Invalid mimetype xml file"
msgstr "Érvénytelen MIME-típus XML-fájl"

#: common/flatpak-dir.c:8492
#, c-format
msgid "D-Bus service file '%s' has wrong name"
msgstr ""

#: common/flatpak-dir.c:8647
#, fuzzy, c-format
msgid "Invalid Exec argument %s"
msgstr "Érvénytelen require-flatpak argumentum: %s\n"

#: common/flatpak-dir.c:9115
msgid "While getting detached metadata: "
msgstr "A különálló metaadatok lekérése közben: "

#: common/flatpak-dir.c:9120 common/flatpak-dir.c:9125
#: common/flatpak-dir.c:9129
#, fuzzy
msgid "Extra data missing in detached metadata"
msgstr "A különálló metaadatok lekérése közben: "

#: common/flatpak-dir.c:9133
msgid "While creating extradir: "
msgstr "A további könyvtár létrehozása közben: "

#: common/flatpak-dir.c:9154 common/flatpak-dir.c:9187
msgid "Invalid checksum for extra data"
msgstr "Érvénytelen ellenőrzőösszeg a további adatnál"

#: common/flatpak-dir.c:9183
msgid "Wrong size for extra data"
msgstr "Hibás méret a további adatnál"

#: common/flatpak-dir.c:9196
#, c-format
msgid "While writing extra data file '%s': "
msgstr "A(z) „%s” további adatfájl írása közben: "

#: common/flatpak-dir.c:9204
#, fuzzy, c-format
msgid "Extra data %s missing in detached metadata"
msgstr "A különálló metaadatok lekérése közben: "

#: common/flatpak-dir.c:9278
#, fuzzy, c-format
msgid "Unable to get runtime key from metadata"
msgstr "Alternatív fájl használata a metaadatokhoz"

#: common/flatpak-dir.c:9402
#, c-format
msgid "apply_extra script failed, exit status %d"
msgstr "Az apply_extra parancsfájl sikertelen, kilépési állapot: %d"

#. Translators: The placeholder is for an app ref.
#: common/flatpak-dir.c:9591
#, c-format
msgid "Installing %s is not allowed by the policy set by your administrator"
msgstr ""

#: common/flatpak-dir.c:9690
#, c-format
msgid "While trying to resolve ref %s: "
msgstr "A(z) %s hivatkozás feloldására tett kísérlet közben: "

#: common/flatpak-dir.c:9702
#, c-format
msgid "%s is not available"
msgstr "A(z) %s nem érhető el"

#: common/flatpak-dir.c:9714 common/flatpak-dir.c:11495
#, c-format
msgid "%s commit %s already installed"
msgstr "A(z) %s kommit %s már telepítve van"

#: common/flatpak-dir.c:9721
msgid "Can't create deploy directory"
msgstr "Nem lehet létrehozni a telepítési könyvtárat"

#: common/flatpak-dir.c:9729
#, c-format
msgid "Failed to read commit %s: "
msgstr "Nem sikerült olvasni a(z) %s kommitot: "

#: common/flatpak-dir.c:9750
#, c-format
msgid "While trying to checkout %s into %s: "
msgstr "A(z) %s -> %s átváltására tett kísérlet közben: "

#: common/flatpak-dir.c:9769
msgid "While trying to checkout metadata subpath: "
msgstr "A metaadatok alútvonalának átváltására tett kísérlet közben: "

#: common/flatpak-dir.c:9801
#, fuzzy, c-format
msgid "While trying to checkout subpath ‘%s’: "
msgstr "A(z) %s -> %s átváltására tett kísérlet közben: "

#: common/flatpak-dir.c:9811
msgid "While trying to remove existing extra dir: "
msgstr "A meglévő további könyvtár eltávolítására tett kísérlet közben: "

#: common/flatpak-dir.c:9822
msgid "While trying to apply extra data: "
msgstr "A további adatok alkalmazására tett kísérlet közben: "

#: common/flatpak-dir.c:9849
#, c-format
msgid "Invalid commit ref %s: "
msgstr "Érvénytelen %s kommithivatkozás: "

#: common/flatpak-dir.c:9857 common/flatpak-dir.c:9869
#, c-format
msgid "Deployed ref %s does not match commit (%s)"
msgstr "Az üzembe állított %s hivatkozás nem egyezik a kommittal (%s)"

#: common/flatpak-dir.c:9863
#, c-format
msgid "Deployed ref %s branch does not match commit (%s)"
msgstr "Az üzembe állított %s ág nem egyezik a kommittal (%s)"

#: common/flatpak-dir.c:10125 common/flatpak-installation.c:1911
#, c-format
msgid "%s branch %s already installed"
msgstr "A(z) %s %s ág már telepítve van"

#: common/flatpak-dir.c:10985
#, c-format
msgid "Could not unmount revokefs-fuse filesystem at %s: "
msgstr ""

#: common/flatpak-dir.c:11289
#, c-format
msgid "This version of %s is already installed"
msgstr "A(z) %s ezen verziója már telepítve van"

#: common/flatpak-dir.c:11302
#, c-format
msgid "Can't change remote during bundle install"
msgstr "Nem lehet megváltoztatni a távolit csomagtelepítés közben"

#: common/flatpak-dir.c:11571
msgid "Can't update to a specific commit without root permissions"
msgstr ""

#: common/flatpak-dir.c:11852
#, c-format
msgid "Can't remove %s, it is needed for: %s"
msgstr ""

#: common/flatpak-dir.c:11912 common/flatpak-installation.c:2067
#, c-format
msgid "%s branch %s is not installed"
msgstr "A(z) %s %s ág nincs telepítve"

#: common/flatpak-dir.c:12165
#, fuzzy, c-format
msgid "%s commit %s not installed"
msgstr "A(z) %s %s nincs telepítve"

#: common/flatpak-dir.c:12501
#, c-format
msgid "Pruning repo failed: %s"
msgstr "A tároló nyesése meghiúsult: %s"

#: common/flatpak-dir.c:12669 common/flatpak-dir.c:12675
#, fuzzy, c-format
msgid "Failed to load filter '%s'"
msgstr "Nem sikerült olvasni a(z) %s kommitot: "

#: common/flatpak-dir.c:12681
#, fuzzy, c-format
msgid "Failed to parse filter '%s'"
msgstr "Nem sikerült olvasni a(z) %s kommitot: "

#: common/flatpak-dir.c:12963
#, fuzzy
msgid "Failed to write summary cache: "
msgstr "Nem sikerült olvasni a(z) %s kommitot: "

#: common/flatpak-dir.c:12982
#, fuzzy, c-format
msgid "No oci summary cached for remote '%s'"
msgstr "Nincs flatpak gyorsítótár a távoli összegzésben"

#: common/flatpak-dir.c:13207
#, fuzzy, c-format
msgid "No cached summary for remote '%s'"
msgstr "Nincs flatpak gyorsítótár a távoli összegzésben"

#: common/flatpak-dir.c:13248
#, fuzzy, c-format
msgid "Invalid checksum for indexed summary %s read from %s"
msgstr "Érvénytelen ellenőrzőösszeg a(z) %s további adatnál"

#: common/flatpak-dir.c:13321
#, c-format
msgid ""
"Remote listing for %s not available; server has no summary file. Check the "
"URL passed to remote-add was valid."
msgstr ""

#: common/flatpak-dir.c:13698
#, fuzzy, c-format
msgid "Invalid checksum for indexed summary %s for remote '%s'"
msgstr "Érvénytelen ellenőrzőösszeg a(z) %s további adatnál"

#: common/flatpak-dir.c:14388
#, c-format
msgid "Multiple branches available for %s, you must specify one of: "
msgstr "Több ág is elérhető ehhez: %s, meg kell adnia az egyiket:"

#: common/flatpak-dir.c:14454
#, c-format
msgid "Nothing matches %s"
msgstr "Semmi sem egyezik: %s"

#: common/flatpak-dir.c:14562
#, c-format
msgid "Can't find ref %s%s%s%s%s"
msgstr "A(z) %s%s%s%s%s hivatkozás nem található"

#: common/flatpak-dir.c:14605
#, c-format
msgid "Error searching remote %s: %s"
msgstr "Hiba a távoli %s tárolóban keresésnél: %s"

#: common/flatpak-dir.c:14702
#, c-format
msgid "Error searching local repository: %s"
msgstr "Hiba a helyi tárolóban keresésnél: %s"

#: common/flatpak-dir.c:14839
#, fuzzy, c-format
msgid "%s/%s/%s not installed"
msgstr "A(z) %s %s nincs telepítve"

#: common/flatpak-dir.c:15042
#, c-format
msgid "Could not find installation %s"
msgstr "Nem található a telepítési %s"

#: common/flatpak-dir.c:15612
#, fuzzy, c-format
msgid "Invalid file format, no %s group"
msgstr "Érvénytelen fájlformátum"

#: common/flatpak-dir.c:15617 common/flatpak-repo-utils.c:2836
#, c-format
msgid "Invalid version %s, only 1 supported"
msgstr "Érvénytelen verzió (%s), csak egy támogatott"

#: common/flatpak-dir.c:15622 common/flatpak-dir.c:15627
#, fuzzy, c-format
msgid "Invalid file format, no %s specified"
msgstr "Érvénytelen fájlformátum"

#. Check some minimal size so we don't get crap
#: common/flatpak-dir.c:15647
#, fuzzy
msgid "Invalid file format, gpg key invalid"
msgstr "Érvénytelen fájlformátum"

#: common/flatpak-dir.c:15675 common/flatpak-repo-utils.c:2917
msgid "Collection ID requires GPG key to be provided"
msgstr ""

#: common/flatpak-dir.c:15718
#, c-format
msgid "Runtime %s, branch %s is already installed"
msgstr "A(z) %s futtatókörnyezet, %s ág már telepítve van"

#: common/flatpak-dir.c:15719
#, c-format
msgid "App %s, branch %s is already installed"
msgstr "A(z) %s alkalmazás, %s ág már telepítve van"

#: common/flatpak-dir.c:15953
#, c-format
msgid "Can't remove remote '%s' with installed ref %s (at least)"
msgstr ""

#: common/flatpak-dir.c:16058
#, fuzzy, c-format
msgid "Invalid character '/' in remote name: %s"
msgstr "A(z) %s nem található a(z) %s távoliban"

#: common/flatpak-dir.c:16064
#, c-format
msgid "No configuration for remote %s specified"
msgstr ""

#: common/flatpak-dir.c:17597
#, fuzzy, c-format
msgid "Skipping deletion of mirror ref (%s, %s)…\n"
msgstr "Érvénytelen %s üzembe állított hivatkozás:"

#: common/flatpak-exports.c:931
#, c-format
msgid "An absolute path is required"
msgstr ""

#: common/flatpak-exports.c:948
#, fuzzy, c-format
msgid "Unable to open path \"%s\": %s"
msgstr "A(z) %s lekérése közben a(z) %s távoliról: "

#: common/flatpak-exports.c:955
#, fuzzy, c-format
msgid "Unable to get file type of \"%s\": %s"
msgstr "Nem hozható létre szinkronizálási cső"

#: common/flatpak-exports.c:964
#, c-format
msgid "File \"%s\" has unsupported type 0o%o"
msgstr ""

#: common/flatpak-exports.c:970
#, c-format
msgid "Unable to get filesystem information for \"%s\": %s"
msgstr ""

#: common/flatpak-exports.c:980
#, c-format
msgid "Ignoring blocking autofs path \"%s\""
msgstr ""

#: common/flatpak-exports.c:996 common/flatpak-exports.c:1009
#: common/flatpak-exports.c:1022
#, c-format
msgid "Path \"%s\" is reserved by Flatpak"
msgstr ""

#: common/flatpak-exports.c:1076
#, fuzzy, c-format
msgid "Unable to resolve symbolic link \"%s\": %s"
msgstr "A(z) %s lekérése közben a(z) %s távoliról: "

#: common/flatpak-glib-backports.c:69
msgid "Empty string is not a number"
msgstr ""

#: common/flatpak-glib-backports.c:95
#, c-format
msgid "“%s” is not an unsigned number"
msgstr ""

#: common/flatpak-glib-backports.c:105
#, c-format
msgid "Number “%s” is out of bounds [%s, %s]"
msgstr ""

#: common/flatpak-image-source.c:83
msgid "Only sha256 image checksums are supported"
msgstr ""

#: common/flatpak-image-source.c:100 common/flatpak-image-source.c:108
msgid "Image is not a manifest"
msgstr ""

#: common/flatpak-image-source.c:123
msgid "No org.flatpak.ref found in image"
msgstr ""

#: common/flatpak-image-source.c:148
#, c-format
msgid "Ref '%s' not found in registry"
msgstr "A(z) „%s” hivatkozás nem található a regisztrációs adatbázisban"

#: common/flatpak-image-source.c:157
msgid "Multiple images in registry, specify a ref with --ref"
msgstr ""
"Több lemezkép van a regisztrációs adatbázisban, adjon meg egy hivatkozást a "
"--ref használatával"

#: common/flatpak-installation.c:834
#, fuzzy, c-format
msgid "Ref %s not installed"
msgstr "A(z) %s nincs telepítve"

#: common/flatpak-installation.c:875
#, fuzzy, c-format
msgid "App %s not installed"
msgstr "A(z) %s nincs telepítve"

#: common/flatpak-installation.c:1395
#, fuzzy, c-format
msgid "Remote '%s' already exists"
msgstr "A távoli %s már létezik"

#: common/flatpak-installation.c:1946
#, fuzzy, c-format
msgid "As requested, %s was only pulled, but not installed"
msgstr "A kért %s kiterjesztés csak részlegesen van telepítve"

#: common/flatpak-instance.c:533 common/flatpak-instance.c:687
#: common/flatpak-instance.c:728
#, fuzzy, c-format
msgid "Unable to create directory %s"
msgstr "Nem hozható létre szinkronizálási cső"

#: common/flatpak-instance.c:554
#, fuzzy, c-format
msgid "Unable to lock %s"
msgstr "Nem hozható létre szinkronizálási cső"

#: common/flatpak-instance.c:627
#, fuzzy, c-format
msgid "Unable to create temporary directory in %s"
msgstr "Nem lehet létrehozni a telepítési könyvtárat"

#: common/flatpak-instance.c:639
#, fuzzy, c-format
msgid "Unable to create file %s"
msgstr "Nem hozható létre szinkronizálási cső"

#: common/flatpak-instance.c:646
#, fuzzy, c-format
msgid "Unable to update symbolic link %s/%s"
msgstr "A(z) %s lekérése közben a(z) %s távoliról: "

#: common/flatpak-oci-registry.c:1197
msgid "Only Bearer authentication supported"
msgstr ""

#: common/flatpak-oci-registry.c:1206
#, fuzzy
msgid "Only realm in authentication request"
msgstr "Ismeretlen %s D-Bus név\n"

#: common/flatpak-oci-registry.c:1213
#, fuzzy
msgid "Invalid realm in authentication request"
msgstr "Ismeretlen %s D-Bus név\n"

#: common/flatpak-oci-registry.c:1283
#, fuzzy, c-format
msgid "Authorization failed: %s"
msgstr "Ismeretlen %s D-Bus név\n"

#: common/flatpak-oci-registry.c:1285
msgid "Authorization failed"
msgstr ""

#: common/flatpak-oci-registry.c:1289
#, c-format
msgid "Unexpected response status %d when requesting token: %s"
msgstr ""

#: common/flatpak-oci-registry.c:1300
#, fuzzy
msgid "Invalid authentication request response"
msgstr "Ismeretlen %s D-Bus név\n"

#: common/flatpak-oci-registry.c:1731
#, c-format
msgid "Flatpak was compiled without zstd support"
msgstr ""

#: common/flatpak-oci-registry.c:1923 common/flatpak-oci-registry.c:1975
#: common/flatpak-oci-registry.c:2004 common/flatpak-oci-registry.c:2059
#: common/flatpak-oci-registry.c:2115 common/flatpak-oci-registry.c:2193
#, fuzzy
msgid "Invalid delta file format"
msgstr "Érvénytelen fájlformátum"

#: common/flatpak-oci-registry.c:3198 common/flatpak-oci-registry.c:3382
msgid "Invalid OCI image config"
msgstr ""

#: common/flatpak-oci-registry.c:3260 common/flatpak-oci-registry.c:3531
#, c-format
msgid "Wrong layer checksum, expected %s, was %s"
msgstr ""

#: common/flatpak-oci-registry.c:3359
#, c-format
msgid "No ref specified for OCI image %s"
msgstr ""

#: common/flatpak-oci-registry.c:3369
#, c-format
msgid "Wrong ref (%s) specified for OCI image %s, expected %s"
msgstr ""

#: common/flatpak-progress.c:236
#, c-format
msgid "Downloading metadata: %u/(estimating) %s"
msgstr "Metaadatok letöltése: %u/%s (becslés)"

#: common/flatpak-progress.c:260
#, c-format
msgid "Downloading: %s/%s"
msgstr "Letöltés: %s/%s"

#: common/flatpak-progress.c:280
#, c-format
msgid "Downloading extra data: %s/%s"
msgstr "További adatok letöltése: %s/%s"

#: common/flatpak-progress.c:285
#, c-format
msgid "Downloading files: %d/%d %s"
msgstr "Fájlok letöltése: %d/%d %s"

#: common/flatpak-ref-utils.c:122
msgid "Name can't be empty"
msgstr ""

#: common/flatpak-ref-utils.c:129
msgid "Name can't be longer than 255 characters"
msgstr ""

#: common/flatpak-ref-utils.c:142
msgid "Name can't start with a period"
msgstr ""

#: common/flatpak-ref-utils.c:148
#, c-format
msgid "Name can't start with %c"
msgstr ""

#: common/flatpak-ref-utils.c:164
msgid "Name can't end with a period"
msgstr ""

#: common/flatpak-ref-utils.c:171 common/flatpak-ref-utils.c:183
msgid "Only last name segment can contain -"
msgstr ""

#: common/flatpak-ref-utils.c:174
#, c-format
msgid "Name segment can't start with %c"
msgstr ""

#: common/flatpak-ref-utils.c:186
#, c-format
msgid "Name can't contain %c"
msgstr ""

#: common/flatpak-ref-utils.c:195
msgid "Names must contain at least 2 periods"
msgstr ""

#: common/flatpak-ref-utils.c:312
msgid "Arch can't be empty"
msgstr ""

#: common/flatpak-ref-utils.c:323
#, c-format
msgid "Arch can't contain %c"
msgstr ""

#: common/flatpak-ref-utils.c:385
msgid "Branch can't be empty"
msgstr ""

#: common/flatpak-ref-utils.c:395
#, c-format
msgid "Branch can't start with %c"
msgstr ""

#: common/flatpak-ref-utils.c:405
#, c-format
msgid "Branch can't contain %c"
msgstr ""

#: common/flatpak-ref-utils.c:615 common/flatpak-ref-utils.c:865
msgid "Ref too long"
msgstr ""

#: common/flatpak-ref-utils.c:627
#, fuzzy
msgid "Invalid remote name"
msgstr "A(z) %s nem található a(z) %s távoliban"

#: common/flatpak-ref-utils.c:641
#, fuzzy, c-format
msgid "%s is not application or runtime"
msgstr "Alkalmazás vagy futtatókörnyezet aláírása"

#: common/flatpak-ref-utils.c:650 common/flatpak-ref-utils.c:667
#: common/flatpak-ref-utils.c:683
#, fuzzy, c-format
msgid "Wrong number of components in %s"
msgstr "Túl sok argumentum"

#: common/flatpak-ref-utils.c:656
#, fuzzy, c-format
msgid "Invalid name %.*s: %s"
msgstr "Ismeretlen %s D-Bus név\n"

#: common/flatpak-ref-utils.c:673
#, fuzzy, c-format
msgid "Invalid arch: %.*s: %s"
msgstr "Alapértelmezett ág: %s\n"

#: common/flatpak-ref-utils.c:816
#, fuzzy, c-format
msgid "Invalid name %s: %s"
msgstr "Ismeretlen %s D-Bus név\n"

#: common/flatpak-ref-utils.c:834
#, fuzzy, c-format
msgid "Invalid arch: %s: %s"
msgstr "Alapértelmezett ág: %s\n"

#: common/flatpak-ref-utils.c:853
#, fuzzy, c-format
msgid "Invalid branch: %s: %s"
msgstr "Alapértelmezett ág: %s\n"

#: common/flatpak-ref-utils.c:962 common/flatpak-ref-utils.c:970
#: common/flatpak-ref-utils.c:978
#, fuzzy, c-format
msgid "Wrong number of components in partial ref %s"
msgstr "Túl sok argumentum"

#: common/flatpak-ref-utils.c:1298
#, fuzzy
msgid " development platform"
msgstr "Fejlesztői futtatókörnyezet használata"

#: common/flatpak-ref-utils.c:1300
msgid " platform"
msgstr ""

#: common/flatpak-ref-utils.c:1302
#, fuzzy
msgid " application base"
msgstr "Alkalmazásazonosító"

#: common/flatpak-ref-utils.c:1305
msgid " debug symbols"
msgstr ""

#: common/flatpak-ref-utils.c:1307
msgid " sourcecode"
msgstr ""

#: common/flatpak-ref-utils.c:1309
#, fuzzy
msgid " translations"
msgstr "Telepítve"

#: common/flatpak-ref-utils.c:1311
msgid " docs"
msgstr ""

#: common/flatpak-ref-utils.c:1578
#, fuzzy, c-format
msgid "Invalid id %s: %s"
msgstr "Érvénytelen %s pid"

#: common/flatpak-remote.c:1216
#, fuzzy, c-format
msgid "Bad remote name: %s"
msgstr "A(z) %s nem található a(z) %s távoliban"

#: common/flatpak-remote.c:1220
#, fuzzy
msgid "No URL specified"
msgstr "Nincs parancs megadva"

#: common/flatpak-remote.c:1266
#, fuzzy
msgid "GPG verification must be enabled when a collection ID is set"
msgstr "GPG ellenőrzés szükséges, ha a gyűjtemények engedélyezettek"

#: common/flatpak-repo-utils.c:344
#, c-format
msgid "No extra data sources"
msgstr "Nincsenek további adatforrások"

#: common/flatpak-repo-utils.c:2817
#, c-format
msgid "Invalid %s: Missing group ‘%s’"
msgstr ""

#: common/flatpak-repo-utils.c:2826
#, c-format
msgid "Invalid %s: Missing key ‘%s’"
msgstr ""

#: common/flatpak-repo-utils.c:2876
msgid "Invalid gpg key"
msgstr "Érvénytelen gpg kulcs"

#: common/flatpak-repo-utils.c:3217
#, fuzzy, c-format
msgid "Error copying 64x64 icon for component %s: %s\n"
msgstr "Hiba a migráció során: %s\n"

#: common/flatpak-repo-utils.c:3223
#, fuzzy, c-format
msgid "Error copying 128x128 icon for component %s: %s\n"
msgstr "Hiba a migráció során: %s\n"

#: common/flatpak-repo-utils.c:3362
#, c-format
msgid "%s is end-of-life, ignoring for appstream"
msgstr ""

#: common/flatpak-repo-utils.c:3397
#, fuzzy, c-format
msgid "No appstream data for %s: %s\n"
msgstr "Az appstream adatok frissítése a(z) %s távoli tárolóhoz\n"

#: common/flatpak-repo-utils.c:3744
#, fuzzy
msgid "Invalid bundle, no ref in metadata"
msgstr "Érvénytelen ellenőrzőösszeg a további adatnál"

#: common/flatpak-repo-utils.c:3846
#, c-format
msgid "Collection ‘%s’ of bundle doesn’t match collection ‘%s’ of remote"
msgstr ""

#: common/flatpak-repo-utils.c:3923
msgid "Metadata in header and app are inconsistent"
msgstr ""

#: common/flatpak-run.c:951
msgid "No systemd user session available, cgroups not available"
msgstr ""

#: common/flatpak-run.c:1496
#, fuzzy
msgid "Unable to allocate instance id"
msgstr "Nem hozható létre szinkronizálási cső"

#: common/flatpak-run.c:1632 common/flatpak-run.c:1641
#, fuzzy, c-format
msgid "Failed to open flatpak-info file: %s"
msgstr "Nem sikerült megnyitni a flatpak-információs átmeneti fájlt: %s"

#: common/flatpak-run.c:1668
#, fuzzy, c-format
msgid "Failed to open bwrapinfo.json file: %s"
msgstr "Nem sikerült megnyitni a flatpak-információs átmeneti fájlt: %s"

#: common/flatpak-run.c:1689
#, fuzzy, c-format
msgid "Failed to write to instance id fd: %s"
msgstr "Nem sikerült olvasni a(z) %s kommitot: "

#: common/flatpak-run.c:2096
#, fuzzy
msgid "Initialize seccomp failed"
msgstr "Alkalmazások előkészítése egy elnevezett alkalmazásból"

#: common/flatpak-run.c:2135
#, fuzzy, c-format
msgid "Failed to add architecture to seccomp filter: %s"
msgstr "Nem sikerült a(z) %s helyi további adat betöltése: %s"

#: common/flatpak-run.c:2143
#, fuzzy, c-format
msgid "Failed to add multiarch architecture to seccomp filter: %s"
msgstr "Nem sikerült a(z) %s helyi további adat betöltése: %s"

#: common/flatpak-run.c:2175 common/flatpak-run.c:2192
#: common/flatpak-run.c:2214
#, fuzzy, c-format
msgid "Failed to block syscall %d: %s"
msgstr "Hiba: %s %s sikertelen: %s\n"

#: common/flatpak-run.c:2247
#, fuzzy, c-format
msgid "Failed to export bpf: %s"
msgstr "Nem sikerült olvasni az exportált fájlból"

#: common/flatpak-run.c:2587
#, fuzzy, c-format
msgid "Failed to open ‘%s’"
msgstr "Nem sikerült megnyitni a flatpak-információs átmeneti fájlt: %s"

#: common/flatpak-run.c:2597
#, c-format
msgid ""
"Directory forwarding needs version 4 of the document portal (have version %d)"
msgstr ""

#: common/flatpak-run.c:2915
#, c-format
msgid "ldconfig failed, exit status %d"
msgstr "ldconfig meghiúsult, kilépési állapot: %d"

#: common/flatpak-run.c:2922
#, fuzzy
msgid "Can't open generated ld.so.cache"
msgstr "Nem lehet megnyitni a(z) %s névteret: %s"

#. Translators: The placeholder is for an app ref.
#: common/flatpak-run.c:3045
#, c-format
msgid "Running %s is not allowed by the policy set by your administrator"
msgstr ""

#: common/flatpak-run.c:3202
msgid ""
"\"flatpak run\" is not intended to be run as `sudo flatpak run`. Use `sudo "
"-i` or `su -l` instead and invoke \"flatpak run\" from inside the new shell."
msgstr ""

#: common/flatpak-run.c:3413
#, fuzzy, c-format
msgid "Failed to migrate from %s: %s"
msgstr "Nem sikerült olvasni a(z) %s kommitot: "

#: common/flatpak-run.c:3434
#, c-format
msgid "Failed to migrate old app data directory %s to new name %s: %s"
msgstr ""

#: common/flatpak-run.c:3443
#, fuzzy, c-format
msgid "Failed to create symlink while migrating %s: %s"
msgstr "Nem sikerült olvasni a(z) %s kommitot: "

#: common/flatpak-run-dbus.c:46
#, fuzzy
msgid "Failed to open app info file"
msgstr "Nem sikerült megnyitni az alkalmazás-információs fájlt: %s"

#: common/flatpak-run-dbus.c:149
msgid "Unable to create sync pipe"
msgstr "Nem hozható létre szinkronizálási cső"

#: common/flatpak-run-dbus.c:185
msgid "Failed to sync with dbus proxy"
msgstr "Nem sikerült szinkronizálni a dbus proxyval"

#: common/flatpak-transaction.c:2275
#, fuzzy, c-format
msgid "Warning: Problem looking for related refs: %s"
msgstr "Figyelmeztetés: hiba a kapcsolódó hivatkozások keresésekor: %s\n"

#: common/flatpak-transaction.c:2493
#, fuzzy, c-format
msgid "The application %s requires the runtime %s which was not found"
msgstr "A(z) %s alkalmazás, %s ág nincs telepítve"

#: common/flatpak-transaction.c:2509
#, fuzzy, c-format
msgid "The application %s requires the runtime %s which is not installed"
msgstr "A(z) %s alkalmazás, %s ág nincs telepítve"

#: common/flatpak-transaction.c:2641
#, c-format
msgid "Can't uninstall %s which is needed by %s"
msgstr ""

#: common/flatpak-transaction.c:2740
#, c-format
msgid "Remote %s disabled, ignoring %s update"
msgstr "A(z) %s távoli le van tiltva, %s frissítésének mellőzése"

#: common/flatpak-transaction.c:2773
#, fuzzy, c-format
msgid "%s is already installed"
msgstr "A(z) %s kommit %s már telepítve van"

#: common/flatpak-transaction.c:2776
#, fuzzy, c-format
msgid "%s is already installed from remote %s"
msgstr "A(z) %s már telepítve lett egy másik távoli tárolóból (%s)"

#: common/flatpak-transaction.c:3120
#, fuzzy, c-format
msgid "Invalid .flatpakref: %s"
msgstr "Érvénytelen require-flatpak argumentum: %s\n"

#: common/flatpak-transaction.c:3161
msgid "Warning: Could not mark already installed apps as preinstalled"
msgstr ""

#: common/flatpak-transaction.c:3382
#, fuzzy, c-format
msgid "Error updating remote metadata for '%s': %s"
msgstr "Hiba a(z) „%s” távoli metaadatainak frissítéskor: %s\n"

#: common/flatpak-transaction.c:3885
#, c-format
msgid ""
"Warning: Treating remote fetch error as non-fatal since %s is already "
"installed: %s"
msgstr ""

#: common/flatpak-transaction.c:4209
#, fuzzy, c-format
msgid "No authenticator installed for remote '%s'"
msgstr "Hitelesítés szükséges a szoftver frissítéséhez"

#: common/flatpak-transaction.c:4313 common/flatpak-transaction.c:4320
#, fuzzy, c-format
msgid "Failed to get tokens for ref: %s"
msgstr "Nem sikerült megnyitni az átmeneti fájlt: %s"

#: common/flatpak-transaction.c:4315 common/flatpak-transaction.c:4322
#, fuzzy
msgid "Failed to get tokens for ref"
msgstr "Nem sikerült megnyitni az átmeneti fájlt: %s"

#: common/flatpak-transaction.c:4580
#, c-format
msgid "Ref %s from %s matches more than one transaction operation"
msgstr ""

#: common/flatpak-transaction.c:4581 common/flatpak-transaction.c:4591
#, fuzzy
msgid "any remote"
msgstr "Távoli tárolók"

#: common/flatpak-transaction.c:4590
#, c-format
msgid "No transaction operation found for ref %s from %s"
msgstr ""

#: common/flatpak-transaction.c:4713
#, c-format
msgid "Flatpakrepo URL %s not file, HTTP or HTTPS"
msgstr ""

#: common/flatpak-transaction.c:4719
#, fuzzy, c-format
msgid "Can't load dependent file %s: "
msgstr "Nem lehet betölteni a(z) %s fájlt: %s\n"

#: common/flatpak-transaction.c:4727
#, fuzzy, c-format
msgid "Invalid .flatpakrepo: %s"
msgstr "Érvénytelen require-flatpak argumentum: %s\n"

#: common/flatpak-transaction.c:5454
msgid "Transaction already executed"
msgstr ""

#: common/flatpak-transaction.c:5469
msgid ""
"Refusing to operate on a user installation as root! This can lead to "
"incorrect file ownership and permission errors."
msgstr ""

#: common/flatpak-transaction.c:5567 common/flatpak-transaction.c:5580
msgid "Aborted by user"
msgstr ""

#: common/flatpak-transaction.c:5605
#, c-format
msgid "Skipping %s due to previous error"
msgstr ""

#: common/flatpak-transaction.c:5659
#, c-format
msgid "Aborted due to failure (%s)"
msgstr ""

#: common/flatpak-uri.c:118
#, fuzzy, no-c-format
msgid "Invalid %-encoding in URI"
msgstr "Ismeretlen %s D-Bus név\n"

#: common/flatpak-uri.c:135
msgid "Illegal character in URI"
msgstr ""

#: common/flatpak-uri.c:169
msgid "Non-UTF-8 characters in URI"
msgstr ""

#: common/flatpak-uri.c:275
#, c-format
msgid "Invalid IPv6 address ‘%.*s’ in URI"
msgstr ""

#: common/flatpak-uri.c:330
#, c-format
msgid "Illegal encoded IP address ‘%.*s’ in URI"
msgstr ""

#: common/flatpak-uri.c:342
#, c-format
msgid "Illegal internationalized hostname ‘%.*s’ in URI"
msgstr ""

#: common/flatpak-uri.c:374 common/flatpak-uri.c:386
#, c-format
msgid "Could not parse port ‘%.*s’ in URI"
msgstr ""

#: common/flatpak-uri.c:393
#, c-format
msgid "Port ‘%.*s’ in URI is out of range"
msgstr ""

#: common/flatpak-uri.c:910
msgid "URI is not absolute, and no base URI was provided"
msgstr ""

#: common/flatpak-usb.c:83
#, c-format
msgid "USB device query 'all' must not have data"
msgstr ""

#: common/flatpak-usb.c:102
#, c-format
msgid "USB query rule 'cls' must be in the form CLASS:SUBCLASS or CLASS:*"
msgstr ""

#: common/flatpak-usb.c:111
#, fuzzy, c-format
msgid "Invalid USB class"
msgstr "Érvénytelen %s pid"

#: common/flatpak-usb.c:125
#, c-format
msgid "Invalid USB subclass"
msgstr ""

#: common/flatpak-usb.c:141 common/flatpak-usb.c:148
#, c-format
msgid "USB query rule 'dev' must have a valid 4-digit hexadecimal product id"
msgstr ""

#: common/flatpak-usb.c:164 common/flatpak-usb.c:171
#, c-format
msgid "USB query rule 'vnd' must have a valid 4-digit hexadecimal vendor id"
msgstr ""

#: common/flatpak-usb.c:205
#, c-format
msgid "USB device queries must be in the form TYPE:DATA"
msgstr ""

#: common/flatpak-usb.c:225
#, c-format
msgid "Unknown USB query rule %s"
msgstr ""

#: common/flatpak-usb.c:248
#, c-format
msgid "Empty USB query"
msgstr ""

#: common/flatpak-usb.c:274
#, c-format
msgid "Multiple USB query rules of the same type is not supported"
msgstr ""

#: common/flatpak-usb.c:283
#, c-format
msgid "'all' must not contain extra query rules"
msgstr ""

#: common/flatpak-usb.c:291
#, c-format
msgid "USB queries with 'dev' must also specify vendors"
msgstr ""

#: common/flatpak-utils.c:712
msgid "Glob can't match apps"
msgstr ""

#: common/flatpak-utils.c:737
msgid "Empty glob"
msgstr ""

#: common/flatpak-utils.c:756
#, fuzzy
msgid "Too many segments in glob"
msgstr "Túl sok argumentum"

#: common/flatpak-utils.c:777
#, fuzzy, c-format
msgid "Invalid glob character '%c'"
msgstr "Érvénytelen %s pid"

#: common/flatpak-utils.c:831
#, c-format
msgid "Missing glob on line %d"
msgstr ""

#: common/flatpak-utils.c:835
#, c-format
msgid "Trailing text on line %d"
msgstr ""

#: common/flatpak-utils.c:839
#, c-format
msgid "on line %d"
msgstr ""

#: common/flatpak-utils.c:861
#, c-format
msgid "Unexpected word '%s' on line %d"
msgstr ""

#: common/flatpak-utils.c:2118
#, fuzzy, c-format
msgid "Invalid require-flatpak argument %s"
msgstr "Érvénytelen require-flatpak argumentum: %s\n"

#: common/flatpak-utils.c:2128 common/flatpak-utils.c:2147
#, c-format
msgid "%s needs a later flatpak version (%s)"
msgstr "A(z) %s egy későbbi flatpak verziót (%s) igényel"

#: oci-authenticator/flatpak-oci-authenticator.c:291
msgid "Not a oci remote, missing summary.xa.oci-repository"
msgstr ""

#: oci-authenticator/flatpak-oci-authenticator.c:477
msgid "Not a OCI remote"
msgstr ""

#: oci-authenticator/flatpak-oci-authenticator.c:488
#, fuzzy
msgid "Invalid token"
msgstr "Érvénytelen gpg kulcs"

#: portal/flatpak-portal.c:2292
#, fuzzy, c-format
msgid "No portal support found"
msgstr "Nincs találat"

#: portal/flatpak-portal.c:2298
msgid "Deny"
msgstr ""

#: portal/flatpak-portal.c:2300
#, fuzzy
msgid "Update"
msgstr "frissítés"

#: portal/flatpak-portal.c:2305
#, fuzzy, c-format
msgid "Update %s?"
msgstr "Összegzés frissítése\n"

#: portal/flatpak-portal.c:2317
msgid "The application wants to update itself."
msgstr ""

#: portal/flatpak-portal.c:2318
msgid "Update access can be changed any time from the privacy settings."
msgstr ""

#: portal/flatpak-portal.c:2343
#, c-format
msgid "Application update not allowed"
msgstr ""

#: portal/flatpak-portal.c:2501
#, c-format
msgid "Self update not supported, new version requires new permissions"
msgstr ""

#: portal/flatpak-portal.c:2684 portal/flatpak-portal.c:2702
#, fuzzy, c-format
msgid "Update ended unexpectedly"
msgstr "Aláírt futtatókörnyezet frissítése"

#. SECURITY:
#. - Normal users need admin authentication to install software
#. system-wide.
#. - Note that we install polkit rules that allow local users
#. in the wheel group to install without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:23
msgid "Install signed application"
msgstr "Aláírt alkalmazás telepítése"

#: system-helper/org.freedesktop.Flatpak.policy.in:24
#: system-helper/org.freedesktop.Flatpak.policy.in:42
#, fuzzy
msgid "Authentication is required to install software"
msgstr "Hitelesítés szükséges a szoftver frissítéséhez"

#. SECURITY:
#. - Normal users need admin authentication to install software
#. system-wide.
#. - Note that we install polkit rules that allow local users
#. in the wheel group to install without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:41
msgid "Install signed runtime"
msgstr "Aláírt futtatókörnyezet telepítése"

#. SECURITY:
#. - Normal users do not require admin authentication to update an
#. app as the commit will be signed, and the action is required
#. to update the system when unattended.
#. - Changing this to anything other than 'yes' will break unattended
#. updates.
#: system-helper/org.freedesktop.Flatpak.policy.in:60
msgid "Update signed application"
msgstr "Aláírt alkalmazás frissítése"

#: system-helper/org.freedesktop.Flatpak.policy.in:61
#: system-helper/org.freedesktop.Flatpak.policy.in:80
msgid "Authentication is required to update software"
msgstr "Hitelesítés szükséges a szoftver frissítéséhez"

#. SECURITY:
#. - Normal users do not require admin authentication to update a
#. runtime as the commit will be signed, and the action is required
#. to update the system when unattended.
#. - Changing this to anything other than 'yes' will break unattended
#. updates.
#: system-helper/org.freedesktop.Flatpak.policy.in:79
msgid "Update signed runtime"
msgstr "Aláírt futtatókörnyezet frissítése"

#. SECURITY:
#. - Normal users do not need authentication to update metadata
#. from signed repositories.
#: system-helper/org.freedesktop.Flatpak.policy.in:94
msgid "Update remote metadata"
msgstr "Távoli metaadatok frissítése"

#: system-helper/org.freedesktop.Flatpak.policy.in:95
#, fuzzy
msgid "Authentication is required to update remote info"
msgstr "Hitelesítés szükséges a szoftver frissítéséhez"

#. SECURITY:
#. - Normal users do not need authentication to modify the
#. OSTree repository
#. - Note that we install polkit rules that allow local users
#. in the wheel group to modify repos without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:111
msgid "Update system repository"
msgstr "Rendszertároló frissítése"

#: system-helper/org.freedesktop.Flatpak.policy.in:112
#, fuzzy
msgid "Authentication is required to modify a system repository"
msgstr "Hitelesítés szükséges a rendszertároló frissítéséhez"

#. SECURITY:
#. - Normal users need admin authentication to install software
#. system-wide.
#: system-helper/org.freedesktop.Flatpak.policy.in:126
msgid "Install bundle"
msgstr "Csomag telepítése"

#: system-helper/org.freedesktop.Flatpak.policy.in:127
#, fuzzy
msgid "Authentication is required to install software from $(path)"
msgstr "Hitelesítés szükséges a szoftver telepítéséhez"

#. SECURITY:
#. - Normal users need admin authentication to uninstall software
#. system-wide.
#. - Note that we install polkit rules that allow local users
#. in the wheel group to uninstall without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:144
msgid "Uninstall runtime"
msgstr "Futtatókörnyezet eltávolítása"

#: system-helper/org.freedesktop.Flatpak.policy.in:145
#, fuzzy
msgid "Authentication is required to uninstall software"
msgstr "Hitelesítés szükséges a szoftver eltávolításához"

#. SECURITY:
#. - Normal users need admin authentication to uninstall software
#. system-wide.
#. - Note that we install polkit rules that allow local users
#. in the wheel group to uninstall without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:161
msgid "Uninstall app"
msgstr "Alkalmazás eltávolítása"

#: system-helper/org.freedesktop.Flatpak.policy.in:162
#, fuzzy
msgid "Authentication is required to uninstall $(ref)"
msgstr "Hitelesítés szükséges a szoftver eltávolításához"

#. SECURITY:
#. - Normal users need admin authentication to configure system-wide
#. software repositories.
#: system-helper/org.freedesktop.Flatpak.policy.in:177
msgid "Configure Remote"
msgstr "Távoli beállítása"

#: system-helper/org.freedesktop.Flatpak.policy.in:178
#, fuzzy
msgid "Authentication is required to configure software repositories"
msgstr "Hitelesítés szükséges a szoftvertelepítés beállításához"

#. SECURITY:
#. - Normal users need admin authentication to configure the system-wide
#. Flatpak installation.
#: system-helper/org.freedesktop.Flatpak.policy.in:192
msgid "Configure"
msgstr "Beállítás"

#: system-helper/org.freedesktop.Flatpak.policy.in:193
msgid "Authentication is required to configure software installation"
msgstr "Hitelesítés szükséges a szoftvertelepítés beállításához"

#. SECURITY:
#. - Normal users do not require admin authentication to update
#. appstream data as it will be signed, and the action is required
#. to update the system when unattended.
#. - Changing this to anything other than 'yes' will break unattended
#. updates.
#: system-helper/org.freedesktop.Flatpak.policy.in:210
msgid "Update appstream"
msgstr "AppStream frissítése"

#: system-helper/org.freedesktop.Flatpak.policy.in:211
#, fuzzy
msgid "Authentication is required to update information about software"
msgstr "Hitelesítés szükséges a távoli információk frissítéséhez"

#. SECURITY:
#. - Normal users do not require admin authentication to update
#. metadata as it will be signed, and the action is required
#. to update the system when unattended.
#. - Changing this to anything other than 'yes' will break unattended
#. updates.
#: system-helper/org.freedesktop.Flatpak.policy.in:228
#, fuzzy
msgid "Update metadata"
msgstr "Távoli metaadatok frissítése"

#: system-helper/org.freedesktop.Flatpak.policy.in:229
#, fuzzy
msgid "Authentication is required to update metadata"
msgstr "Hitelesítés szükséges a szoftver frissítéséhez"

#. SECURITY:
#. - Authorisation to actually install software is controlled by
#. org.freedesktop.Flatpak.app-install.
#. - This action is checked after app-install, as it can only be done
#. once the app’s data (including its content rating) has been
#. downloaded.
#. - This action is checked to see if the installation should be allowed
#. based on whether the app being installed has content which doesn’t
#. comply with the user’s parental controls policy (the content is
#. ‘too extreme’).
#. - It is checked only if an app has too extreme content for the user
#. who is trying to install it (in which case, the app is ‘unsafe’).
#. - Typically, normal users will need admin permission to install apps
#. with extreme content; admins will be able to install it without
#. additional checks.
#. - In order to configure the policy so that admins can install safe and
#. unsafe software anywhere without authorisation, and non-admins can
#. install safe software in their user or system dirs without
#. authorisation, but need authorisation to install unsafe software
#. anywhere:
#. * Unconditionally return `yes` from `app-install`.
#. * Return `auth_admin` from `override-parental-controls` for users
#. not in `@privileged_group@`, and `yes` for users in it.
#. * Set the malcontent `is-{user,system}-installation-allowed`
#. properties of all non-admins’ parental controls policies to true.
#. - In order to configure the policy so that admins can install safe and
#. unsafe software anywhere without authorisation, and non-admins can
#. install safe software in their user dir without authorisation, but
#. need authorisation to install safe software in the system dir or to
#. install unsafe software anywhere:
#. * Unconditionally return `yes` from `app-install`.
#. * Return `auth_admin` from `override-parental-controls` for users
#. not in `@privileged_group@`, and `yes` for users in it.
#. * Set the malcontent `is-user-installation-allowed` property of all
#. non-admins’ parental controls policies to true.
#. * Set the malcontent `is-system-installation-allowed` property of
#. all non-admins’ parental controls policies to false.
#. - In order to configure the policy so that all users (including
#. admins) can install safe software anywhere without authorisation,
#. but need authorisation to install unsafe software anywhere (i.e.
#. applying parental controls to admins too):
#. * Unconditionally return `yes` from `app-install`.
#. * Unconditionally return `auth_admin` from `override-parental-controls`.
#. * Set the malcontent `is-user-installation-allowed` property of all
#. users’ parental controls policies to true.
#. * Set the malcontent `is-system-installation-allowed` property of
#. all users’ parental controls policies to true.
#: system-helper/org.freedesktop.Flatpak.policy.in:287
msgid "Override parental controls for installs"
msgstr ""

#: system-helper/org.freedesktop.Flatpak.policy.in:288
#, fuzzy
msgid ""
"Authentication is required to install software which is restricted by your "
"parental controls policy"
msgstr "Hitelesítés szükséges a szoftver telepítéséhez"

#. SECURITY:
#. - This is like org.freedesktop.Flatpak.override-parental-controls, but
#. it’s queried for app updates, whereas the former is queried for app
#. installs.
#. - As with the above action, this one is only queried if
#. org.freedesktop.Flatpak.app-update has allowed the app update, and
#. only if the app being updated has too extreme content for the user
#. who is trying to update it.
#. - The default policy for this is to *allow* updates to ‘too extreme’
#. apps by default, on the basis that having an out-of-date (i.e.
#. insecure or unsupported) app is a worse outcome than automatically
#. installing an update which has radically different content from the
#. version of the app which the parent originally vetted and installed.
#: system-helper/org.freedesktop.Flatpak.policy.in:313
msgid "Override parental controls for updates"
msgstr ""

#: system-helper/org.freedesktop.Flatpak.policy.in:314
#, fuzzy
msgid ""
"Authentication is required to update software which is restricted by your "
"parental controls policy"
msgstr "Hitelesítés szükséges a szoftver telepítéséhez"

#, fuzzy
#~ msgid "Installed:"
#~ msgstr "Telepítve"

#, fuzzy
#~ msgid "Download:"
#~ msgstr "Letöltés"

#, fuzzy, c-format
#~ msgid "Unable to lookup key ID %s: %d"
#~ msgstr "A(z) %s lekérése közben a(z) %s távoliról: "

#, fuzzy, c-format
#~ msgid "Error signing commit: %d"
#~ msgstr "Hiba a migráció során: %s\n"

#, fuzzy, c-format
#~ msgid "No entry for %s in remote '%s' summary cache "
#~ msgstr ""
#~ "Nincs bejegyzés a(z) %s esetén a távoli összegzés flatpak gyorsítótárban "

#, fuzzy, c-format
#~ msgid "Failed to uninstall %s for rebase to %s: "
#~ msgstr "Hiba: %s %s sikertelen: %s\n"

#, fuzzy, c-format
#~ msgid "Failed to uninstall %s for rebase to %s: %s\n"
#~ msgstr "Hiba: %s %s sikertelen: %s\n"

#, fuzzy, c-format
#~ msgid "Unable to open directory %s"
#~ msgstr "Név birtoklásának lehetővé tétele az alkalmazásnak a rendszerbuszon"

#~ msgid "install"
#~ msgstr "telepítés"

#~ msgid "update"
#~ msgstr "frissítés"

#~ msgid "install bundle"
#~ msgstr "csomag telepítése"

#, fuzzy
#~ msgid "uninstall"
#~ msgstr "telepítés"

#, fuzzy
#~ msgid "runtime"
#~ msgstr "Futtatókörnyezet:"

#, fuzzy, c-format
#~ msgid "%s Failed to %s %s: %s\n"
#~ msgstr "Hiba: %s %s sikertelen: %s\n"

#, fuzzy
#~ msgid "[REF…] - Uninstall an application"
#~ msgstr "HIVATKOZÁS… - Alkalmazás eltávolítása"

#, c-format
#~ msgid "Invalid deployed ref %s: "
#~ msgstr "Érvénytelen %s üzembe állított hivatkozás:"

#, c-format
#~ msgid "Deployed ref %s kind does not match commit (%s)"
#~ msgstr "Az üzembe állított %s típus nem egyezik a kommittal (%s)"

#, c-format
#~ msgid "Deployed ref %s name does not match commit (%s)"
#~ msgstr "Az üzembe állított %s név nem egyezik a kommittal (%s)"

#, c-format
#~ msgid "Deployed ref %s arch does not match commit (%s)"
#~ msgstr "Az üzembe állított %s architektúra nem egyezik a kommittal (%s)"

#, fuzzy, c-format
#~ msgid "Failed to determine parts from ref: %s"
#~ msgstr "Nem sikerült megnyitni az átmeneti fájlt: %s"

#, fuzzy, c-format
#~ msgid "Invalid arch %s"
#~ msgstr "Érvénytelen %s pid"

#, fuzzy, c-format
#~ msgid "Related ref '%s' is only partially installed"
#~ msgstr "A kért %s kiterjesztés csak részlegesen van telepítve"

#, fuzzy, c-format
#~ msgid "Ref '%s' is only partially installed"
#~ msgstr "A kért %s kiterjesztés csak részlegesen van telepítve"

#, fuzzy, c-format
#~ msgid "No such ref (%s, %s) in remote %s"
#~ msgstr "A(z) %s nem található a(z) %s távoliban"

#, fuzzy, c-format
#~ msgid "No flatpak cache in remote '%s' summary"
#~ msgstr "Nincs flatpak gyorsítótár a távoli összegzésben"

#, fuzzy, c-format
#~ msgid "No such ref (%s, %s) in remote %s or elsewhere"
#~ msgstr "A(z) %s nem található a(z) %s távoliban"

#, fuzzy
#~ msgid "No summary found"
#~ msgstr "Nincs találat"

#~ msgid "Deployed metadata does not match commit"
#~ msgstr "Az üzembe állított metaadatok nem egyeznek a kommittal"

#, fuzzy, c-format
#~ msgid "No repo metadata cached for remote '%s'"
#~ msgstr "Nincs flatpak gyorsítótár a távoli összegzésben"

#, fuzzy
#~ msgid "No metadata branch for OCI"
#~ msgstr "Egy ág metaadatainak kiírása"

#, fuzzy, c-format
#~ msgid "Invalid group: %d"
#~ msgstr "Érvénytelen %s pid"

#, fuzzy, c-format
#~ msgid "Warning: Can't find %s metadata for dependencies: %s"
#~ msgstr "Figyelmeztetés: a függőségek nem találhatóak: %s\n"

#~ msgid "Not running as root, may be unable to enter namespace"
#~ msgstr ""
#~ "Nem root felhasználóként fut, lehet hogy nem fog tudni belépni a névtérbe"

#, fuzzy
#~ msgid "Default system installation"
#~ msgstr "Rendszerszintű telepítések megjelenítése"

#~ msgid "No url specified in flatpakrepo file"
#~ msgstr "Nincs URL megadva a flatpaktároló fájlban"

#, fuzzy
#~ msgid "%s branch already installed"
#~ msgstr "A(z) %s %s ág már telepítve van"

#~ msgid "%s branch %s not installed"
#~ msgstr "A(z) %s %s ág nincs telepítve"

#~ msgid "0"
#~ msgstr "0"

#~ msgid "Print OSTree debug information during command processing"
#~ msgstr "OSTree hibakeresési információk kiírása a parancsfeldolgozás közben"

#~ msgid "Show help options"
#~ msgstr "Súgólehetőségek megjelenítése"

#, fuzzy
#~ msgid "Architecture"
#~ msgstr "Használandó architektúra"

#~ msgid "Location:"
#~ msgstr "Hely:"

#~ msgid "Installing for user: %s from %s\n"
#~ msgstr "Telepítés a felhasználónak: %s innen: %s\n"

#~ msgid "Installing: %s from %s\n"
#~ msgstr "Telepítés: %s innen: %s\n"

#~ msgid "Updating for user: %s from %s\n"
#~ msgstr "Frissítés a felhasználónak: %s innen: %s\n"

#~ msgid "Updating: %s from %s\n"
#~ msgstr "Frissítés: %s innen: %s\n"

#~ msgid "Installing for user: %s from bundle %s\n"
#~ msgstr "Telepítés a felhasználónak: %s ebből a csomagból: %s\n"

#~ msgid "Installing: %s from bundle %s\n"
#~ msgstr "Telepítés: %s ebből a csomagból: %s\n"

#, fuzzy
#~ msgid "Uninstalling for user: %s\n"
#~ msgstr "Telepítés a felhasználónak: %s innen: %s\n"

#~ msgid "No updates.\n"
#~ msgstr "Nincsenek frissítések.\n"

#~ msgid "Now at %s.\n"
#~ msgstr "Most: %s.\n"

#, fuzzy
#~ msgid "new file access"
#~ msgstr "Fájlhozzáférés lekérése"

#, fuzzy
#~ msgid "file access"
#~ msgstr "Fájlhozzáférés lekérése"

#, fuzzy
#~ msgid "new system dbus access"
#~ msgstr "Rendszerbusz-hívások naplózása"

#, fuzzy
#~ msgid "system dbus access"
#~ msgstr "Rendszerbusz-hívások naplózása"

#, fuzzy
#~ msgid "Installing in %s:\n"
#~ msgstr "Telepítés: %s\n"

#, fuzzy
#~ msgid "Invalid .flatpakref"
#~ msgstr "Érvénytelen gpg kulcs"

#, fuzzy
#~ msgid "Authentication is required to install $(ref) from $(origin)"
#~ msgstr "Hitelesítés szükséges a szoftver telepítéséhez"

#, fuzzy
#~ msgid "Authentication is required to update $(ref) from $(origin)"
#~ msgstr "Hitelesítés szükséges a távoli információk frissítéséhez"

#, fuzzy
#~ msgid "Authentication is required to update the remote $(remote)"
#~ msgstr "Hitelesítés szükséges a távoli információk frissítéséhez"

#, fuzzy
#~ msgid "Authentication is required to modify the remote $(remote)"
#~ msgstr "Hitelesítés szükséges a távoli információk frissítéséhez"

#, fuzzy
#~ msgid "Authentication is required to configure the remote $(remote)"
#~ msgstr "Hitelesítés szükséges a szoftvertárolók beállításához"

#, fuzzy
#~ msgid "Runtime Branch"
#~ msgstr "Futtatókörnyezet:"

#, fuzzy
#~ msgid "Runtime Commit"
#~ msgstr "Aktív kommit"

#~ msgid "Unknown command '%s'"
#~ msgstr "Ismeretlen „%s” parancs"

#~ msgid "Migrating %s to %s\n"
#~ msgstr "%s migrálása ide: %s\n"

#~ msgid "Error during migration: %s\n"
#~ msgstr "Hiba a migráció során: %s\n"

#~ msgid "Redirect collection ID: %s\n"
#~ msgstr "Gyűjteményazonosító átirányítás: %s\n"

#~ msgid "Invalid sha256 for extra data uri %s"
#~ msgstr "Érvénytelen sha256 a további adat URI-nál: %s"

#~ msgid "Invalid sha256 for extra data"
#~ msgstr "Érvénytelen sha256 a további adatnál"

#~ msgid "Add OCI registry"
#~ msgstr "OCI regisztrációs adatbázis hozzáadása"

#~ msgid "Found in remote %s\n"
#~ msgstr "Megtalálva a(z) %s távoli tárolóban\n"

#~ msgid "Found in remote %s, do you want to install it?"
#~ msgstr "Megtalálható a(z) %s távoliban, szeretné telepíteni?"

#~ msgid "Found in several remotes:\n"
#~ msgstr "Megtalálható számos távoliban:\n"

#~ msgid "The required runtime %s was not found in a configured remote.\n"
#~ msgstr ""
#~ "A szükséges %s futtatókörnyezet nem található a beállított távoliban.\n"

#~ msgid "%s already installed, skipping\n"
#~ msgstr "A(z) %s már telepítve van, kihagyás\n"

#~ msgid "One or more operations failed"
#~ msgstr "Egy vagy több művelet sikertelen"

#~ msgid "No ref information available in repository"
#~ msgstr "Nem érhetőek el hivatkozásinformációk a tárolóban"

#~ msgid "Remote title not set"
#~ msgstr "A távoli cím nincs beállítva"

#~ msgid "Remote default-branch not set"
#~ msgstr "A távoli alapértelmezett ág nincs beállítva"

===== ./po/eo.po =====
# Esperanto translation for flatpak.
# Copyright (C) 2026 flatpak's COPYRIGHT HOLDER
# This file is distributed under the same license as the flatpak package.
# Kristjan SCHMIDT <kristjan.schmidt@googlemail.com>, 2026.
#
msgid ""
msgstr ""
"Project-Id-Version: flatpak master\n"
"Report-Msgid-Bugs-To: https://github.com/flatpak/flatpak/issues\n"
"POT-Creation-Date: 2026-05-27 16:39+0200\n"
"PO-Revision-Date: 2026-03-20 11:07+0100\n"
"Last-Translator: Kristjan SCHMIDT <kristjan.schmidt@googlemail.com>\n"
"Language-Team: Esperanto <gnome-eo-list@gnome.org>\n"
"Language: eo\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Generator: Gtranslator 49.0\n"

#: app/flatpak-builtins-build-bundle.c:59
msgid "Export runtime instead of app"
msgstr "Eksporti rultempon anstataŭ aplikaĵon"

#: app/flatpak-builtins-build-bundle.c:60
msgid "Arch to bundle for"
msgstr "Arko al pakaĵo por"

#: app/flatpak-builtins-build-bundle.c:60
#: app/flatpak-builtins-build-export.c:62 app/flatpak-builtins-build-init.c:53
#: app/flatpak-builtins-build-sign.c:42 app/flatpak-builtins-create-usb.c:46
#: app/flatpak-builtins-info.c:55 app/flatpak-builtins-install.c:67
#: app/flatpak-builtins-list.c:50 app/flatpak-builtins-make-current.c:38
#: app/flatpak-builtins-remote-info.c:54 app/flatpak-builtins-remote-ls.c:56
#: app/flatpak-builtins-run.c:158 app/flatpak-builtins-search.c:37
#: app/flatpak-builtins-uninstall.c:54 app/flatpak-builtins-update.c:56
msgid "ARCH"
msgstr "ARCH"

#: app/flatpak-builtins-build-bundle.c:61
msgid "URL for repo"
msgstr "URL por repo"

#: app/flatpak-builtins-build-bundle.c:61
#: app/flatpak-builtins-build-bundle.c:62
#: app/flatpak-builtins-build-update-repo.c:68
#: app/flatpak-builtins-build-update-repo.c:72
#: app/flatpak-builtins-build-update-repo.c:73
#: app/flatpak-builtins-history.c:69 app/flatpak-builtins-remote-add.c:80
#: app/flatpak-builtins-remote-add.c:81 app/flatpak-builtins-remote-add.c:85
#: app/flatpak-builtins-remote-list.c:53
#: app/flatpak-builtins-remote-modify.c:70
#: app/flatpak-builtins-remote-modify.c:85
#: app/flatpak-builtins-remote-modify.c:86
#: app/flatpak-builtins-remote-modify.c:90
msgid "URL"
msgstr "URL"

#: app/flatpak-builtins-build-bundle.c:62
msgid "URL for runtime flatpakrepo file"
msgstr "URL por rultempa flatpakrepo-dosiero"

#: app/flatpak-builtins-build-bundle.c:63
msgid "Add GPG key from FILE (- for stdin)"
msgstr "Aldoni GPG-ŝlosilon el DOSIERO (- por stdin)"

#: app/flatpak-builtins-build-bundle.c:63 app/flatpak-builtins-build.c:54
#: app/flatpak-builtins-build-export.c:67
#: app/flatpak-builtins-build-update-repo.c:83
#: app/flatpak-builtins-install.c:81 app/flatpak-builtins-remote-add.c:84
#: app/flatpak-builtins-remote-add.c:86 app/flatpak-builtins-remote-modify.c:89
#: app/flatpak-builtins-remote-modify.c:92
msgid "FILE"
msgstr "DOSIERO"

#: app/flatpak-builtins-build-bundle.c:64
msgid "GPG Key ID to sign the OCI image with"
msgstr "GPG Key ID por subskribi la OCI-bildon per"

#: app/flatpak-builtins-build-bundle.c:64
#: app/flatpak-builtins-build-commit-from.c:68
#: app/flatpak-builtins-build-export.c:68
#: app/flatpak-builtins-build-import-bundle.c:49
#: app/flatpak-builtins-build-sign.c:44
#: app/flatpak-builtins-build-update-repo.c:84
msgid "KEY-ID"
msgstr "KEY-ID"

#: app/flatpak-builtins-build-bundle.c:65
#: app/flatpak-builtins-build-commit-from.c:69
#: app/flatpak-builtins-build-export.c:71
#: app/flatpak-builtins-build-import-bundle.c:50
#: app/flatpak-builtins-build-sign.c:45
#: app/flatpak-builtins-build-update-repo.c:85
msgid "GPG Homedir to use when looking for keyrings"
msgstr "GPG Homedir por uzi kiam vi serĉas ŝlosilringojn"

#: app/flatpak-builtins-build-bundle.c:65
#: app/flatpak-builtins-build-commit-from.c:69
#: app/flatpak-builtins-build-export.c:71
#: app/flatpak-builtins-build-import-bundle.c:50
#: app/flatpak-builtins-build-sign.c:45
#: app/flatpak-builtins-build-update-repo.c:85
msgid "HOMEDIR"
msgstr "HOMEDIR"

#: app/flatpak-builtins-build-bundle.c:66
msgid "OSTree commit to create a delta bundle from"
msgstr "OSTree kompromitas krei deltan pakaĵon el"

#: app/flatpak-builtins-build-bundle.c:66 app/flatpak-builtins-remote-info.c:55
#: app/flatpak-builtins-update.c:57
msgid "COMMIT"
msgstr "COMMIT"

#: app/flatpak-builtins-build-bundle.c:67
msgid "Export oci image instead of flatpak bundle"
msgstr "Eksporti oci-bildon anstataŭ flatpak-faskon"

#: app/flatpak-builtins-build-bundle.c:70
msgid "How to compress OCI image layers (default: gzip)"
msgstr "Kiel kunpremi OCI-bildtavolojn (defaŭlte: gzip)"

#: app/flatpak-builtins-build-bundle.c:634
msgid ""
"LOCATION FILENAME NAME [BRANCH] - Create a single file bundle from a local "
"repository"
msgstr ""
"LOKO DOSIERONOMO [BRANĈO] - Krei ununuran dosierpakaĵon el loka deponejo"

#: app/flatpak-builtins-build-bundle.c:641
msgid "LOCATION, FILENAME and NAME must be specified"
msgstr "LOKO, FILENAME kaj NAME devas esti specifitaj"

#: app/flatpak-builtins-build-bundle.c:644
#: app/flatpak-builtins-build-export.c:844
#: app/flatpak-builtins-build-import-bundle.c:136
#: app/flatpak-builtins-build-init.c:217 app/flatpak-builtins-build-sign.c:76
#: app/flatpak-builtins-document-export.c:112
#: app/flatpak-builtins-document-info.c:75
#: app/flatpak-builtins-document-list.c:191
#: app/flatpak-builtins-document-unexport.c:70
#: app/flatpak-builtins-history.c:482 app/flatpak-builtins-info.c:130
#: app/flatpak-builtins-install.c:181 app/flatpak-builtins-install.c:234
#: app/flatpak-builtins-install.c:298 app/flatpak-builtins-list.c:419
#: app/flatpak-builtins-make-current.c:72 app/flatpak-builtins-override.c:73
#: app/flatpak-builtins-permission-list.c:162
#: app/flatpak-builtins-permission-remove.c:132
#: app/flatpak-builtins-remote-add.c:323
#: app/flatpak-builtins-remote-delete.c:68
#: app/flatpak-builtins-remote-list.c:241 app/flatpak-builtins-remote-ls.c:407
msgid "Too many arguments"
msgstr "Tro da argumentoj"

#: app/flatpak-builtins-build-bundle.c:659
#: app/flatpak-builtins-build-commit-from.c:338
#: app/flatpak-builtins-build-commit-from.c:351
#: app/flatpak-builtins-build-import-bundle.c:145
#, c-format
msgid "'%s' is not a valid repository"
msgstr "'%s' ne estas valida deponejo"

#: app/flatpak-builtins-build-bundle.c:663
#, c-format
msgid "'%s' is not a valid repository: "
msgstr "'%s' ne estas valida deponejo:"

#: app/flatpak-builtins-build-bundle.c:674 app/flatpak-builtins-build-sign.c:88
#: common/flatpak-dir.c:14293
#, c-format
msgid "'%s' is not a valid name: %s"
msgstr "'%s' ne estas valida nomo: %s"

#: app/flatpak-builtins-build-bundle.c:677
#: app/flatpak-builtins-build-export.c:865 app/flatpak-builtins-build-sign.c:91
#: common/flatpak-dir.c:14299
#, c-format
msgid "'%s' is not a valid branch name: %s"
msgstr "'%s' ne estas valida filionomo: %s"

#: app/flatpak-builtins-build-bundle.c:691
#: app/flatpak-builtins-build-import-bundle.c:149
#: app/flatpak-builtins-build-init.c:281
#, c-format
msgid "'%s' is not a valid filename"
msgstr "'%s' ne estas valida dosiernomo"

#: app/flatpak-builtins-build-bundle.c:706
msgid "--oci-layer-compress value must be gzip or zstd"
msgstr "--oci-layer-compress valoro devas esti gzip aŭ zstd"

#: app/flatpak-builtins-build.c:49
msgid "Use Platform runtime rather than Sdk"
msgstr "Uzi la rultempon de Platformo anstataŭ Sdk"

#: app/flatpak-builtins-build.c:50
msgid "Make destination readonly"
msgstr "Fari celon nur legebla"

#: app/flatpak-builtins-build.c:51
msgid "Add bind mount"
msgstr "Aldoni bind-monton"

#: app/flatpak-builtins-build.c:51
msgid "DEST=SRC"
msgstr "DEST=SRC"

#: app/flatpak-builtins-build.c:52
msgid "Start build in this directory"
msgstr "Komenci konstrui en ĉi tiu dosierujo"

#: app/flatpak-builtins-build.c:52 app/flatpak-builtins-build.c:53
#: app/flatpak-builtins-build-init.c:64 app/flatpak-builtins-run.c:160
msgid "DIR"
msgstr "DIR"

#: app/flatpak-builtins-build.c:53
msgid "Where to look for custom sdk dir (defaults to 'usr')"
msgstr "Kie serĉi kutiman sdk-diraĵon (defaŭlte al 'usr')"

#: app/flatpak-builtins-build.c:54 app/flatpak-builtins-build-export.c:67
msgid "Use alternative file for the metadata"
msgstr "Uzi alternativan dosieron por la metadatumoj"

#: app/flatpak-builtins-build.c:55 app/flatpak-builtins-run.c:177
msgid "Kill processes when the parent process dies"
msgstr "Mortigi procezojn kiam la gepatra procezo mortas"

#: app/flatpak-builtins-build.c:56
msgid "Export application homedir directory to build"
msgstr "Elporti aplikaĵon homedir-dosierujon por konstrui"

#: app/flatpak-builtins-build.c:57 app/flatpak-builtins-run.c:165
msgid "Log session bus calls"
msgstr "Ensaluti sesiajn busvokojn"

#: app/flatpak-builtins-build.c:58 app/flatpak-builtins-run.c:166
msgid "Log system bus calls"
msgstr "Ensaluti sistemajn busalvokojn"

#: app/flatpak-builtins-build.c:262
msgid "DIRECTORY [COMMAND [ARGUMENT…]] - Build in directory"
msgstr "DIRECTORY [KOMANDO [ARGUMENTO...]] - Konstrui en dosierujo"

#: app/flatpak-builtins-build.c:285 app/flatpak-builtins-build-finish.c:656
msgid "DIRECTORY must be specified"
msgstr "DIRECTORY devas esti specifita"

#: app/flatpak-builtins-build.c:296 app/flatpak-builtins-build-export.c:887
#, c-format
msgid "Build directory %s not initialized, use flatpak build-init"
msgstr "Konstrua dosierujo %s ne pravigita, uzi flatpak build-init"

#: app/flatpak-builtins-build.c:315
msgid "metadata invalid, not application or runtime"
msgstr "metadatenoj nevalidaj, ne aplikaĵo aŭ rultempo"

#: app/flatpak-builtins-build.c:446
#, c-format
msgid "No extension point matching %s in %s"
msgstr "Neniu etendpunkto kongrua kun %s en %s"

#: app/flatpak-builtins-build.c:635
#, c-format
msgid "Missing '=' in bind mount option '%s'"
msgstr "Mankas '=' en bind munta opcio '%s'"

#: app/flatpak-builtins-build.c:679 common/flatpak-run.c:3961
#, c-format
msgid "Unable to start app"
msgstr "Ne eblas lanĉi la apon"

#: app/flatpak-builtins-build-commit-from.c:58
msgid "Source repo dir"
msgstr "Font-repo dir"

#: app/flatpak-builtins-build-commit-from.c:58
msgid "SRC-REPO"
msgstr "SRC-REPO"

#: app/flatpak-builtins-build-commit-from.c:59
msgid "Source repo ref"
msgstr "Fonta deponejo ref"

#: app/flatpak-builtins-build-commit-from.c:59
msgid "SRC-REF"
msgstr "SRC-REF"

#: app/flatpak-builtins-build-commit-from.c:64
#: app/flatpak-builtins-build-export.c:60
msgid "One line subject"
msgstr "Unulinia temo"

#: app/flatpak-builtins-build-commit-from.c:64
#: app/flatpak-builtins-build-export.c:60
msgid "SUBJECT"
msgstr "SUBJECT"

#: app/flatpak-builtins-build-commit-from.c:65
#: app/flatpak-builtins-build-export.c:61
msgid "Full description"
msgstr "Plena priskribo"

#: app/flatpak-builtins-build-commit-from.c:65
#: app/flatpak-builtins-build-export.c:61
msgid "BODY"
msgstr "BODY"

#: app/flatpak-builtins-build-commit-from.c:66
#: app/flatpak-builtins-build-export.c:64
#: app/flatpak-builtins-build-import-bundle.c:51
msgid "Update the appstream branch"
msgstr "Ĝisdatigi la branĉon de appstream"

#: app/flatpak-builtins-build-commit-from.c:67
#: app/flatpak-builtins-build-export.c:65
#: app/flatpak-builtins-build-import-bundle.c:52
#: app/flatpak-builtins-build-update-repo.c:87
msgid "Don't update the summary"
msgstr "Ne ĝisdatigi la resumon"

#: app/flatpak-builtins-build-commit-from.c:68
#: app/flatpak-builtins-build-export.c:68
#: app/flatpak-builtins-build-import-bundle.c:49
#: app/flatpak-builtins-build-sign.c:44
msgid "GPG Key ID to sign the commit with"
msgstr "GPG-Ŝlosila ID por subskribi la kompromison"

#: app/flatpak-builtins-build-commit-from.c:70
#: app/flatpak-builtins-build-export.c:73
msgid "Mark build as end-of-life"
msgstr "Marki konstruon kiel finon de vivo"

#: app/flatpak-builtins-build-commit-from.c:70
#: app/flatpak-builtins-build-export.c:73
msgid "REASON"
msgstr "REASON"

#: app/flatpak-builtins-build-commit-from.c:71
msgid ""
"Mark refs matching the OLDID prefix as end-of-life, to be replaced with the "
"given NEWID"
msgstr ""
"Marki refs kongruantajn la OLDID-prefikson kiel finon de vivo, por esti "
"anstataŭigitaj per la donita NEWID"

#: app/flatpak-builtins-build-commit-from.c:71
msgid "OLDID=NEWID"
msgstr "OLDID=NOVA"

#: app/flatpak-builtins-build-commit-from.c:72
#: app/flatpak-builtins-build-export.c:75
msgid "Set type of token needed to install this commit"
msgstr "Agordi tipon de ĵetono necesa por instali ĉi tiun kommit"

#: app/flatpak-builtins-build-commit-from.c:72
#: app/flatpak-builtins-build-export.c:75
msgid "VAL"
msgstr "VALUE"

#: app/flatpak-builtins-build-commit-from.c:73
msgid "Override the timestamp of the commit (NOW for current time)"
msgstr "Anstataŭigi la tempomarkon de la transdono (NUN por la nuna tempo)"

#: app/flatpak-builtins-build-commit-from.c:73
#: app/flatpak-builtins-build-export.c:76
msgid "TIMESTAMP"
msgstr "TIMESTAMP"

#: app/flatpak-builtins-build-commit-from.c:75
#: app/flatpak-builtins-build-export.c:80
#: app/flatpak-builtins-build-import-bundle.c:53
#: app/flatpak-builtins-build-update-repo.c:97
msgid "Don't generate a summary index"
msgstr "Ne ĝisdatigi la resumon"

#: app/flatpak-builtins-build-commit-from.c:278
msgid "DST-REPO [DST-REF…] - Make a new commit from existing commits"
msgstr "DST-REPO [DST-REF...] - Fari novan kommit el ekzistantaj kommits"

#: app/flatpak-builtins-build-commit-from.c:285
msgid "DST-REPO must be specified"
msgstr "DST-REPO devas esti specifita"

#: app/flatpak-builtins-build-commit-from.c:293
msgid ""
"If --src-repo is not specified, exactly one destination ref must be specified"
msgstr ""
"Se --src-repo ne estas specifita, precize unu celreferenco devas esti "
"specifita"

#: app/flatpak-builtins-build-commit-from.c:296
msgid ""
"If --src-ref is specified, exactly one destination ref must be specified"
msgstr "Se --src-ref estas specifita, precize unu celref devas esti specifita"

#: app/flatpak-builtins-build-commit-from.c:299
msgid "Either --src-repo or --src-ref must be specified"
msgstr "Aŭ --src-repo aŭ --src-ref devas esti specifitaj."

#: app/flatpak-builtins-build-commit-from.c:315
msgid "Invalid argument format of use  --end-of-life-rebase=OLDID=NEWID"
msgstr "Nevalida argumentformato de uzo --end-of-life-rebase=OLDID=NEWID"

#: app/flatpak-builtins-build-commit-from.c:321
#: app/flatpak-builtins-build-commit-from.c:324
#, c-format
msgid "Invalid name %s in --end-of-life-rebase"
msgstr "Nevalida nomo %s en --end-of-life-rebase"

#: app/flatpak-builtins-build-commit-from.c:333
#: app/flatpak-builtins-build-export.c:1092
#, c-format
msgid "Could not parse '%s'"
msgstr "Ne eblis analizi '%s'"

#: app/flatpak-builtins-build-commit-from.c:498
msgid "Can't commit from partial source commit"
msgstr "Ne povas fari de parta fonto."

#: app/flatpak-builtins-build-commit-from.c:503
#, c-format
msgid "%s: no change\n"
msgstr "%s: neniu ŝanĝo\n"

#: app/flatpak-builtins-build-export.c:62
msgid "Architecture to export for (must be host compatible)"
msgstr "Arkitekturo por eksporti (devas esti gastiganto kongrua)"

#: app/flatpak-builtins-build-export.c:63
msgid "Commit runtime (/usr), not /app"
msgstr "Fari rultempon (/usr), ne /app"

#: app/flatpak-builtins-build-export.c:66
msgid "Use alternative directory for the files"
msgstr "Uzi alternativan dosierujon por la dosieroj"

#: app/flatpak-builtins-build-export.c:66
msgid "SUBDIR"
msgstr "SUBDIR"

#: app/flatpak-builtins-build-export.c:69
msgid "Files to exclude"
msgstr "Dosieroj por ekskludi"

#: app/flatpak-builtins-build-export.c:69
#: app/flatpak-builtins-build-export.c:70
#: app/flatpak-builtins-build-update-repo.c:90
msgid "PATTERN"
msgstr "PATTERN"

#: app/flatpak-builtins-build-export.c:70
msgid "Excluded files to include"
msgstr "Ekskluditaj dosieroj por inkluzivi"

#: app/flatpak-builtins-build-export.c:74
msgid "Mark build as end-of-life, to be replaced with the given ID"
msgstr ""
"Marki konstruaĵon kiel finon de vivo, por esti anstataŭigita per la donita "
"identigilo"

#: app/flatpak-builtins-build-export.c:74
#: app/flatpak-builtins-document-list.c:49 app/flatpak-cli-transaction.c:1427
msgid "ID"
msgstr "ID"

#: app/flatpak-builtins-build-export.c:76
msgid "Override the timestamp of the commit"
msgstr "Anstataŭigi la tempomarkon de la kommit"

#: app/flatpak-builtins-build-export.c:77
#: app/flatpak-builtins-build-update-repo.c:75
#: app/flatpak-builtins-remote-add.c:83 app/flatpak-builtins-remote-list.c:54
#: app/flatpak-builtins-remote-modify.c:88
msgid "Collection ID"
msgstr "Kolekta ID"

#: app/flatpak-builtins-build-export.c:472
#, c-format
msgid "WARNING: Error running desktop-file-validate: %s\n"
msgstr "AVERTO: Eraro pri funkciado de desktop-file-validate: %s\n"

#: app/flatpak-builtins-build-export.c:480
#, c-format
msgid "WARNING: Error reading from desktop-file-validate: %s\n"
msgstr "AVERTO: Eraro legante el desktop-file-validate: %s\n"

#: app/flatpak-builtins-build-export.c:486
#, c-format
msgid "WARNING: Failed to validate desktop file %s: %s\n"
msgstr "AVERTO: Malsukcesis validigi labortablan dosieron %s: %s\n"

#: app/flatpak-builtins-build-export.c:513
#, c-format
msgid "WARNING: Can't find Exec key in %s: %s\n"
msgstr "AVERTO: Ne povas trovi Exec-ŝlosilon en %s: %s\n"

#: app/flatpak-builtins-build-export.c:521
#: app/flatpak-builtins-build-export.c:614
#, c-format
msgid "WARNING: Binary not found for Exec line in %s: %s\n"
msgstr "AVERTO: Binaro ne trovita por Exec-linio en %s: %s\n"

#: app/flatpak-builtins-build-export.c:529
#, c-format
msgid "WARNING: Icon not matching app id in %s: %s\n"
msgstr "AVERTO: Ikono ne kongruas kun la idilo de la aplikaĵo en %s: %s\n"

#: app/flatpak-builtins-build-export.c:552
#, c-format
msgid "WARNING: Icon referenced in desktop file but not exported: %s\n"
msgstr ""
"AVERTO: Ikono referencita en labortabla dosiero sed ne eksportita: %s\n"

#: app/flatpak-builtins-build-export.c:719
#, c-format
msgid "Invalid uri type %s, only http/https supported"
msgstr "Nevalida uri-tipo %s, nur http/https subtenata"

#: app/flatpak-builtins-build-export.c:737
#, c-format
msgid "Unable to find basename in %s, specify a name explicitly"
msgstr "Ne eblas trovi baznomon en %s, specifi nomon eksplicite"

#: app/flatpak-builtins-build-export.c:746
#, c-format
msgid "No slashes allowed in extra data name"
msgstr "Neniuj oblikvoj permesitaj en kroma datuma nomo"

#: app/flatpak-builtins-build-export.c:758
#, c-format
msgid "Invalid format for sha256 checksum: '%s'"
msgstr "Nevalida formato por sha256-kontrolsumo: '%s'"

#: app/flatpak-builtins-build-export.c:768
#, c-format
msgid "Extra data sizes of zero not supported"
msgstr "Kromaj datumgrandoj de nulo ne subtenataj"

#: app/flatpak-builtins-build-export.c:830
msgid ""
"LOCATION DIRECTORY [BRANCH] - Create a repository from a build directory"
msgstr "LOKA DOSIERO [BRANĈO] - Krei deponejon el konstrua dosierujo"

#: app/flatpak-builtins-build-export.c:838
msgid "LOCATION and DIRECTORY must be specified"
msgstr "LOKO kaj ADRESARO devas esti precizigitaj"

#: app/flatpak-builtins-build-export.c:859
#: app/flatpak-builtins-remote-add.c:327
#, c-format
msgid "‘%s’ is not a valid collection ID: %s"
msgstr "‘%s’ ne estas valida kolekto ID: %s"

#: app/flatpak-builtins-build-export.c:904
#: app/flatpak-builtins-build-finish.c:684
msgid "No name specified in the metadata"
msgstr "Neniu nomo specifita en la metadatenoj"

#: app/flatpak-builtins-build-export.c:1166
#, c-format
msgid "Commit: %s\n"
msgstr "Faru: %s\n"

#: app/flatpak-builtins-build-export.c:1167
#, c-format
msgid "Metadata Total: %u\n"
msgstr "Sumo de metadatumoj: %u\n"

#: app/flatpak-builtins-build-export.c:1168
#, c-format
msgid "Metadata Written: %u\n"
msgstr "Metadatumoj Skribita: %u\n"

#: app/flatpak-builtins-build-export.c:1169
#, c-format
msgid "Content Total: %u\n"
msgstr "Enhavo Sumo: %u\n"

#: app/flatpak-builtins-build-export.c:1170
#, c-format
msgid "Content Written: %u\n"
msgstr "Enhavo Skribita: %u\n"

#: app/flatpak-builtins-build-export.c:1171
#, c-format
msgid "Content Bytes Written:"
msgstr "Enhavaj bajtoj skribitaj:"

#: app/flatpak-builtins-build-finish.c:52
msgid "Command to set"
msgstr "Komando por agordi"

#: app/flatpak-builtins-build-finish.c:52 app/flatpak-builtins-run.c:159
#: app/flatpak-main.c:209
msgid "COMMAND"
msgstr "COMMAND"

#: app/flatpak-builtins-build-finish.c:53
msgid "Flatpak version to require"
msgstr "Flatpak-versio por postuli"

#: app/flatpak-builtins-build-finish.c:53
msgid "MAJOR.MINOR.MICRO"
msgstr "MAJOR.MINOR.MICRO"

#: app/flatpak-builtins-build-finish.c:54
msgid "Don't process exports"
msgstr "Ne prilabori eksportaĵojn"

#: app/flatpak-builtins-build-finish.c:55
msgid "Extra data info"
msgstr "Kromaj datumoj informoj"

#: app/flatpak-builtins-build-finish.c:56 app/flatpak-builtins-build-init.c:63
msgid "Add extension point info"
msgstr "Aldoni informojn pri etendpunkto"

#: app/flatpak-builtins-build-finish.c:56 app/flatpak-builtins-build-init.c:63
msgid "NAME=VARIABLE[=VALUE]"
msgstr "NOMO=VARIABLE[=VALO]"

#: app/flatpak-builtins-build-finish.c:57
msgid "Remove extension point info"
msgstr "Forigi informojn pri etendpunkto"

#: app/flatpak-builtins-build-finish.c:57
#: app/flatpak-builtins-build-update-repo.c:79 app/flatpak-builtins-info.c:58
#: app/flatpak-builtins-remote-add.c:88 app/flatpak-builtins-remote-modify.c:94
#: app/flatpak-main.c:182
msgid "NAME"
msgstr "NAME"

#: app/flatpak-builtins-build-finish.c:58
msgid "Set extension priority (only for extensions)"
msgstr "Agordi etendan prioritaton (nur por etendaĵoj)"

#: app/flatpak-builtins-build-finish.c:58
msgid "VALUE"
msgstr "VALUE"

#: app/flatpak-builtins-build-finish.c:59
msgid "Change the sdk used for the app"
msgstr "Ŝanĝi la sdk uzatan por la programo"

#: app/flatpak-builtins-build-finish.c:59
msgid "SDK"
msgstr "SDK"

#: app/flatpak-builtins-build-finish.c:60
msgid "Change the runtime used for the app"
msgstr "Ŝanĝi la rultempon uzatan por la programo"

#: app/flatpak-builtins-build-finish.c:60 app/flatpak-builtins-build-init.c:54
#: app/flatpak-builtins-list.c:53 app/flatpak-builtins-remote-ls.c:58
#: app/flatpak-builtins-run.c:163
msgid "RUNTIME"
msgstr "RUNTIME"

#: app/flatpak-builtins-build-finish.c:61
msgid "Set generic metadata option"
msgstr "Agordi ĝeneralajn metadatumojn"

#: app/flatpak-builtins-build-finish.c:61
msgid "GROUP=KEY[=VALUE]"
msgstr "GRUPO=ŝlosilo[=VALO]"

#: app/flatpak-builtins-build-finish.c:62
msgid "Don't inherit permissions from runtime"
msgstr "Ne heredi permesojn de rultempo"

#: app/flatpak-builtins-build-finish.c:155
#, c-format
msgid "Not exporting %s, wrong extension\n"
msgstr "Ne eksportante %s, malĝusta etendo\n"

#: app/flatpak-builtins-build-finish.c:163
#, c-format
msgid "Not exporting %s, non-allowed export filename\n"
msgstr "Ne eksportante %s, nepermesata eksporta dosiernomo\n"

#: app/flatpak-builtins-build-finish.c:167
#, c-format
msgid "Exporting %s\n"
msgstr "Eksportante %s\n"

#: app/flatpak-builtins-build-finish.c:440
#, c-format
msgid "More than one executable found\n"
msgstr "Pli ol unu ekzekutebla trovita\n"

#: app/flatpak-builtins-build-finish.c:451
#, c-format
msgid "Using %s as command\n"
msgstr "Uzante %s kiel komandon\n"

#: app/flatpak-builtins-build-finish.c:456
#, c-format
msgid "No executable found\n"
msgstr "Neniu ekzekutebla trovita\n"

#: app/flatpak-builtins-build-finish.c:511
#, c-format
msgid "Invalid --require-version argument: %s"
msgstr "Nevalida --require-version argumento: %s"

#: app/flatpak-builtins-build-finish.c:543
#, c-format
msgid "Too few elements in --extra-data argument %s"
msgstr "Tro malmultaj elementoj en --extra-data argumento %s"

#: app/flatpak-builtins-build-finish.c:575
#, c-format
msgid ""
"Too few elements in --metadata argument %s, format should be "
"GROUP=KEY[=VALUE]]"
msgstr ""
"Tro malmultaj elementoj en --metadata argumento %s, formato devus esti "
"GROUP=KEY[=VALUE]]"

#: app/flatpak-builtins-build-finish.c:597
#: app/flatpak-builtins-build-init.c:458
#, c-format
msgid ""
"Too few elements in --extension argument %s, format should be "
"NAME=VAR[=VALUE]"
msgstr ""
"Tro malmultaj elementoj en --extension argumento %s, formato devus esti "
"NAME=VAR[=VALUE]"

#: app/flatpak-builtins-build-finish.c:603
#: app/flatpak-builtins-build-init.c:461
#, c-format
msgid "Invalid extension name %s"
msgstr "Nevalida dbus-nomo %s"

#: app/flatpak-builtins-build-finish.c:646
msgid "DIRECTORY - Finalize a build directory"
msgstr "DIRECTORY - Finigi konstruan dosierujon"

#: app/flatpak-builtins-build-finish.c:668
#, c-format
msgid "Build directory %s not initialized"
msgstr "Konstrua dosierujo %s ne pravigita"

#: app/flatpak-builtins-build-finish.c:689
#, c-format
msgid "Build directory %s already finalized"
msgstr "Konstrua dosierujo %s jam finpretigita"

#: app/flatpak-builtins-build-finish.c:702
#, c-format
msgid "Please review the exported files and the metadata\n"
msgstr "Bonvolu revizii la eksportitajn dosierojn kaj la metadatumojn\n"

#: app/flatpak-builtins-build-import-bundle.c:47
msgid "Override the ref used for the imported bundle"
msgstr "Anstataŭigi la refon uzatan por la enportita pakaĵo"

#: app/flatpak-builtins-build-import-bundle.c:47
msgid "REF"
msgstr "REF"

#: app/flatpak-builtins-build-import-bundle.c:48
msgid "Import oci image instead of flatpak bundle"
msgstr "Enporti oci-bildon anstataŭ flatpak-faskon"

#: app/flatpak-builtins-build-import-bundle.c:77
#: app/flatpak-builtins-build-import-bundle.c:105
#, c-format
msgid "Importing %s (%s)\n"
msgstr "Enportado de %s (%s)\n"

#: app/flatpak-builtins-build-import-bundle.c:126
msgid "LOCATION FILENAME - Import a file bundle into a local repository"
msgstr "LOCATION FILENAME - Enporti dosierpakaĵon en lokan deponejon"

#: app/flatpak-builtins-build-import-bundle.c:133
msgid "LOCATION and FILENAME must be specified"
msgstr "LOCATION kaj FILENAME devas esti specifitaj"

#: app/flatpak-builtins-build-init.c:53 app/flatpak-builtins-info.c:55
#: app/flatpak-builtins-run.c:158
msgid "Arch to use"
msgstr "Arko por uzi"

#: app/flatpak-builtins-build-init.c:54
msgid "Initialize var from named runtime"
msgstr "Inicialigi var de nomita rultempo"

#: app/flatpak-builtins-build-init.c:55
msgid "Initialize apps from named app"
msgstr "Komenci aplikaĵojn de nomita aplikaĵo"

#: app/flatpak-builtins-build-init.c:55
msgid "APP"
msgstr "APP"

#: app/flatpak-builtins-build-init.c:56
msgid "Specify version for --base"
msgstr "Specifi version por --base"

#: app/flatpak-builtins-build-init.c:56 app/flatpak-builtins-run.c:164
msgid "VERSION"
msgstr "VERSION"

#: app/flatpak-builtins-build-init.c:57
msgid "Include this base extension"
msgstr "Inkluzivi ĉi tiun bazan etendon"

#: app/flatpak-builtins-build-init.c:57 app/flatpak-builtins-build-init.c:62
msgid "EXTENSION"
msgstr "EXTENSION"

#: app/flatpak-builtins-build-init.c:58
msgid "Extension tag to use if building extension"
msgstr "Etenda etikedo por uzi se konstruas etendon"

#: app/flatpak-builtins-build-init.c:58
msgid "EXTENSION_TAG"
msgstr "EXTENSION_TAG"

#: app/flatpak-builtins-build-init.c:59
msgid "Initialize /usr with a writable copy of the sdk"
msgstr "Komenci /usr per skribebla kopio de la sdk"

#: app/flatpak-builtins-build-init.c:60
msgid "Specify the build type (app, runtime, extension)"
msgstr "Indiki la konstrutipon (aplikaĵo, rultempo, etendaĵo)"

#: app/flatpak-builtins-build-init.c:60
msgid "TYPE"
msgstr "TYPE"

#: app/flatpak-builtins-build-init.c:61
msgid "Add a tag"
msgstr "Aldoni etikedon"

#: app/flatpak-builtins-build-init.c:61
msgid "TAG"
msgstr "TAG"

#: app/flatpak-builtins-build-init.c:62
msgid "Include this sdk extension in /usr"
msgstr "Enmeti ĉi tiun sdk-etendon en /usr"

#: app/flatpak-builtins-build-init.c:64
msgid "Where to store sdk (defaults to 'usr')"
msgstr "Kie stoki sdk (defaŭlte al 'usr')"

#: app/flatpak-builtins-build-init.c:65
msgid "Re-initialize the sdk/var"
msgstr "Rekomencigi la sdk/var"

#: app/flatpak-builtins-build-init.c:118
#, c-format
msgid "Requested extension %s/%s/%s is only partially installed"
msgstr "La petita etendo %s/%s/%s estas nur parte instalita"

#: app/flatpak-builtins-build-init.c:147
#, c-format
msgid "Requested extension %s/%s/%s not installed"
msgstr "Petita etendo %s/%s/%s ne instalita"

#: app/flatpak-builtins-build-init.c:207
msgid ""
"DIRECTORY APPNAME SDK RUNTIME [BRANCH] - Initialize a directory for building"
msgstr ""
"DIRECTORY APPNAME SDK RUNTIME [BRANCH] - Komenci dosierujon por konstruado"

#: app/flatpak-builtins-build-init.c:214
msgid "RUNTIME must be specified"
msgstr "RUNTIME devas esti specifita"

#: app/flatpak-builtins-build-init.c:235
#, c-format
msgid "'%s' is not a valid build type name, use app, runtime or extension"
msgstr "'%s' ne estas valida konstrutipa nomo, uzi apon, rultempon aŭ etendon"

#: app/flatpak-builtins-build-init.c:241 app/flatpak-builtins-override.c:79
#, c-format
msgid "'%s' is not a valid application name: %s"
msgstr "'%s' ne estas valida aplika nomo: %s"

#: app/flatpak-builtins-build-init.c:295
#, c-format
msgid "Build directory %s already initialized"
msgstr "Konstrua dosierujo %s jam pravigita"

#: app/flatpak-builtins-build-sign.c:42 app/flatpak-builtins-install.c:67
#: app/flatpak-builtins-remote-info.c:54
msgid "Arch to install for"
msgstr "Arko por instali"

#: app/flatpak-builtins-build-sign.c:43 app/flatpak-builtins-create-usb.c:48
#: app/flatpak-builtins-install.c:74 app/flatpak-builtins-remote-info.c:56
#: app/flatpak-builtins-uninstall.c:58 app/flatpak-builtins-update.c:64
msgid "Look for runtime with the specified name"
msgstr "Serĉi rultempon kun la specifita nomo"

#: app/flatpak-builtins-build-sign.c:66
msgid "LOCATION [ID [BRANCH]] - Sign an application or runtime"
msgstr "LOKO [ID [ID [BRANĈO]] - Subskribi aplikaĵon aŭ rultempon"

#: app/flatpak-builtins-build-sign.c:73
#: app/flatpak-builtins-build-update-repo.c:499
#: app/flatpak-builtins-remote-add.c:320 app/flatpak-builtins-repo.c:739
msgid "LOCATION must be specified"
msgstr "LOKO devas esti precizigita"

#: app/flatpak-builtins-build-sign.c:94
msgid "No gpg key ids specified"
msgstr "Neniuj gpg-ŝlosilidentigiloj specifitaj"

#: app/flatpak-builtins-build-update-repo.c:68
msgid "Redirect this repo to a new URL"
msgstr "Redirektas ĉi tiun deponejon al nova URL"

#: app/flatpak-builtins-build-update-repo.c:69
msgid "A nice name to use for this repository"
msgstr "Bela nomo uzinda por ĉi tiu deponejo"

#: app/flatpak-builtins-build-update-repo.c:69
#: app/flatpak-builtins-remote-add.c:77 app/flatpak-builtins-remote-modify.c:82
msgid "TITLE"
msgstr "TITLE"

#: app/flatpak-builtins-build-update-repo.c:70
msgid "A one-line comment for this repository"
msgstr "Unulinia komento por ĉi tiu deponejo"

#: app/flatpak-builtins-build-update-repo.c:70
#: app/flatpak-builtins-remote-add.c:78 app/flatpak-builtins-remote-modify.c:83
msgid "COMMENT"
msgstr "COMMENT"

#: app/flatpak-builtins-build-update-repo.c:71
msgid "A full-paragraph description for this repository"
msgstr "Plena alinea priskribo por ĉi tiu deponejo"

#: app/flatpak-builtins-build-update-repo.c:71
#: app/flatpak-builtins-remote-add.c:79 app/flatpak-builtins-remote-modify.c:84
msgid "DESCRIPTION"
msgstr "DESCRIPTION"

#: app/flatpak-builtins-build-update-repo.c:72
msgid "URL for a website for this repository"
msgstr "URL por retejo por ĉi tiu deponejo"

#: app/flatpak-builtins-build-update-repo.c:73
msgid "URL for an icon for this repository"
msgstr "URL por ikono por ĉi tiu deponejo"

#: app/flatpak-builtins-build-update-repo.c:74
msgid "Default branch to use for this repository"
msgstr "Defaŭlta branĉo uzinda por ĉi tiu deponejo"

#: app/flatpak-builtins-build-update-repo.c:74
#: app/flatpak-builtins-remote-add.c:82 app/flatpak-builtins-remote-modify.c:87
#: app/flatpak-builtins-repo.c:713 app/flatpak-builtins-repo.c:714
#: app/flatpak-builtins-run.c:161
msgid "BRANCH"
msgstr "BRANCH"

#: app/flatpak-builtins-build-update-repo.c:75
#: app/flatpak-builtins-remote-add.c:83 app/flatpak-builtins-remote-modify.c:88
msgid "COLLECTION-ID"
msgstr "COLLECTION-ID"

#. Translators: A sideload is when you install from a local USB drive rather than the Internet.
#: app/flatpak-builtins-build-update-repo.c:77
msgid ""
"Permanently deploy collection ID to client remote configurations, only for "
"sideload support"
msgstr "Konstante deploji kolekton-identigilon al klientaj foraj agordoj"

#: app/flatpak-builtins-build-update-repo.c:78
msgid "Permanently deploy collection ID to client remote configurations"
msgstr "Konstante deploji kolekton-identigilon al klientaj foraj agordoj"

#: app/flatpak-builtins-build-update-repo.c:79
msgid "Name of authenticator for this repository"
msgstr "URL por ikono por ĉi tiu deponejo"

#: app/flatpak-builtins-build-update-repo.c:80
msgid "Autoinstall authenticator for this repository"
msgstr "URL por ikono por ĉi tiu deponejo"

#: app/flatpak-builtins-build-update-repo.c:81
msgid "Don't autoinstall authenticator for this repository"
msgstr "Defaŭlta branĉo uzinda por ĉi tiu deponejo"

#: app/flatpak-builtins-build-update-repo.c:82
#: app/flatpak-builtins-remote-add.c:89
msgid "Authenticator option"
msgstr "Montri eblojn"

#: app/flatpak-builtins-build-update-repo.c:82
#: app/flatpak-builtins-remote-add.c:89 app/flatpak-builtins-remote-modify.c:95
msgid "KEY=VALUE"
msgstr "VALUE"

#: app/flatpak-builtins-build-update-repo.c:83
msgid "Import new default GPG public key from FILE"
msgstr "Enporti novan defaŭltan publikan ŝlosilon de GPG el DOSIERO"

#: app/flatpak-builtins-build-update-repo.c:84
msgid "GPG Key ID to sign the summary with"
msgstr "GPG-Ŝlosila ID por subskribi la resumon"

#: app/flatpak-builtins-build-update-repo.c:86
msgid "Generate delta files"
msgstr "Generi deltajn dosierojn"

#: app/flatpak-builtins-build-update-repo.c:88
msgid "Don't update the appstream branch"
msgstr "Ne ĝisdatigi la branĉon de appstream"

#: app/flatpak-builtins-build-update-repo.c:89
msgid "Max parallel jobs when creating deltas (default: NUMCPUs)"
msgstr "Maksimumaj paralelaj laboroj dum kreado de deltoj (defaŭlte: NUMCPUoj)"

#: app/flatpak-builtins-build-update-repo.c:89
msgid "NUM-JOBS"
msgstr "NUM-JOBS"

#: app/flatpak-builtins-build-update-repo.c:90
msgid "Don't create deltas matching refs"
msgstr "Ne krei deltajn kongruajn referencojn"

#: app/flatpak-builtins-build-update-repo.c:91
msgid "Prune unused objects"
msgstr "Pritondi neuzatajn objektojn"

#: app/flatpak-builtins-build-update-repo.c:92
msgid "Prune but don't actually remove anything"
msgstr "Pritondi sed efektive ne forigi ion ajn"

#: app/flatpak-builtins-build-update-repo.c:93
msgid "Only traverse DEPTH parents for each commit (default: -1=infinite)"
msgstr "Nur trapasi DEPTH-gepatrojn por ĉiu transdono (defaŭlte: -1=senfina)"

#: app/flatpak-builtins-build-update-repo.c:93
msgid "DEPTH"
msgstr "DEPTH"

#: app/flatpak-builtins-build-update-repo.c:223
#, c-format
msgid "Generating delta: %s (%.10s)\n"
msgstr "Genera delto: %s (%.10s)\n"

#: app/flatpak-builtins-build-update-repo.c:225
#, c-format
msgid "Generating delta: %s (%.10s-%.10s)\n"
msgstr "Genera delto: Z%s (%.10s-%.10s)\n"

#: app/flatpak-builtins-build-update-repo.c:233
#, c-format
msgid "Failed to generate delta %s (%.10s): "
msgstr "Malsukcesis generi delta %s (%.10s):"

#: app/flatpak-builtins-build-update-repo.c:236
#, c-format
msgid "Failed to generate delta %s (%.10s-%.10s): "
msgstr "Malsukcesis generi delta %s (%.10s-%.10s):"

#: app/flatpak-builtins-build-update-repo.c:492
msgid "LOCATION - Update repository metadata"
msgstr "LOKO - Ĝisdatigi metadatumojn de deponejo"

#: app/flatpak-builtins-build-update-repo.c:609
#, c-format
msgid "Updating appstream branch\n"
msgstr "Ĝisdatigi filion de appstream\n"

#: app/flatpak-builtins-build-update-repo.c:638
#, c-format
msgid "Updating summary\n"
msgstr "Ĝisdatiganta resumon\n"

#: app/flatpak-builtins-build-update-repo.c:664
#, c-format
msgid "Total objects: %u\n"
msgstr "Sumaj objektoj: %u\n"

#: app/flatpak-builtins-build-update-repo.c:666
#, c-format
msgid "No unreachable objects\n"
msgstr "Neniuj neatingeblaj objektoj\n"

#: app/flatpak-builtins-build-update-repo.c:668
#, c-format
msgid "Deleted %u objects, %s freed\n"
msgstr "Forigitaj %u objektoj, %s liberigitaj\n"

#: app/flatpak-builtins-config.c:41
msgid "List configuration keys and values"
msgstr "Listo de agordaj ŝlosiloj kaj valoroj"

#: app/flatpak-builtins-config.c:42
msgid "Get configuration for KEY"
msgstr "Akiri agordon por KEY"

#: app/flatpak-builtins-config.c:43
msgid "Set configuration for KEY to VALUE"
msgstr "Agordi agordon por KEY al VALUE"

#: app/flatpak-builtins-config.c:44
msgid "Unset configuration for KEY"
msgstr "Malŝalti agordon por KEY"

#: app/flatpak-builtins-config.c:149
#, c-format
msgid "'%s' does not look like a language/locale code"
msgstr "'%s' ne aspektas kiel lingvokodo"

#: app/flatpak-builtins-config.c:172
#, c-format
msgid "'%s' does not look like a language code"
msgstr "'%s' ne aspektas kiel lingvokodo"

#: app/flatpak-builtins-config.c:190
#, c-format
msgid "'%s' is not a valid value (use 'true' or 'false')"
msgstr "'%s' ne estas valida deponejo:"

#: app/flatpak-builtins-config.c:262
#, c-format
msgid "Unknown configure key '%s'"
msgstr "Nekonata agorda ŝlosilo '%s'"

#: app/flatpak-builtins-config.c:284
msgid "Too many arguments for --list"
msgstr "Tro da argumentoj por --list"

#: app/flatpak-builtins-config.c:314 app/flatpak-builtins-config.c:362
msgid "You must specify KEY"
msgstr "Vi devas specifi KEY"

#: app/flatpak-builtins-config.c:316
msgid "Too many arguments for --get"
msgstr "Tro da argumentoj por --get"

#: app/flatpak-builtins-config.c:338
msgid "You must specify KEY and VALUE"
msgstr "Vi devas specifi KEY kaj VALUE"

#: app/flatpak-builtins-config.c:340
msgid "Too many arguments for --set"
msgstr "Tro da argumentoj por --set"

#: app/flatpak-builtins-config.c:364
msgid "Too many arguments for --unset"
msgstr "Tro da argumentoj por --unset"

#: app/flatpak-builtins-config.c:383
msgid "[KEY [VALUE]] - Manage configuration"
msgstr "[KEY [VALUE]] - Administri agordon"

#: app/flatpak-builtins-config.c:394
msgid "Can only use one of --list, --get, --set or --unset"
msgstr "Povas uzi nur unu el --list, --get, --set aŭ --unset"

#: app/flatpak-builtins-config.c:408
msgid "Must specify one of --list, --get, --set or --unset"
msgstr "Devas specifi unu el --list, --get, --set aŭ --unset"

#: app/flatpak-builtins-create-usb.c:45 app/flatpak-builtins-install.c:75
#: app/flatpak-builtins-remote-info.c:57 app/flatpak-builtins-uninstall.c:59
#: app/flatpak-builtins-update.c:65
msgid "Look for app with the specified name"
msgstr "Serĉi apon kun la specifita nomo"

#: app/flatpak-builtins-create-usb.c:46
msgid "Arch to copy"
msgstr "Arko por kopii"

#: app/flatpak-builtins-create-usb.c:47
msgid "DEST"
msgstr "DEST"

#: app/flatpak-builtins-create-usb.c:49
msgid "Allow partial commits in the created repo"
msgstr "Permesi partajn komitojn en la kreita deponejo"

#: app/flatpak-builtins-create-usb.c:125 app/flatpak-builtins-create-usb.c:165
#, c-format
msgid ""
"Warning: Related ref ‘%s’ is partially installed. Use --allow-partial to "
"suppress this message.\n"
msgstr "Averto: Forlasante rilatan ref '%s' ĉar ĝi ne estas instalita.\n"

#: app/flatpak-builtins-create-usb.c:158
#, c-format
msgid "Warning: Omitting related ref ‘%s’ because it is not installed.\n"
msgstr "Averto: Forlasante rilatan ref '%s' ĉar ĝi ne estas instalita.\n"

#: app/flatpak-builtins-create-usb.c:175
#, c-format
msgid ""
"Warning: Omitting related ref ‘%s’ because its remote ‘%s’ does not have a "
"collection ID set.\n"
msgstr ""
"Averto: Forlasante rilatan ref '%s' ĉar ĝia fora '%s' ne havas kolekto-"
"identigilon agordita.\n"

#: app/flatpak-builtins-create-usb.c:187
#, c-format
msgid "Warning: Omitting related ref ‘%s’ because it's extra-data.\n"
msgstr "Averto: Forlasante rilatan ref '%s' ĉar ĝi ne estas instalita.\n"

#: app/flatpak-builtins-create-usb.c:262 app/flatpak-builtins-create-usb.c:637
#, c-format
msgid ""
"Remote ‘%s’ does not have a collection ID set, which is required for P2P "
"distribution of ‘%s’."
msgstr ""
"Fora '%s' ne havas kolekton-identigilon, kiu estas postulata por P2P-"
"distribuo de '%s'."

#: app/flatpak-builtins-create-usb.c:272
#, c-format
msgid "Warning: Omitting ref ‘%s’ (runtime of ‘%s’) because it's extra-data.\n"
msgstr ""
"Averto: Preteratentante referencon '%s' (rultempo de '%s') ĉar ĝi estas "
"ekstra-dato.\n"

#: app/flatpak-builtins-create-usb.c:484
msgid "MOUNT-PATH [REF…] - Copy apps or runtimes onto removable media"
msgstr ""
"MOUNT-PATH [REF...] - Kopii programojn aŭ rultempojn sur forpreneblajn "
"rimedojn"

#: app/flatpak-builtins-create-usb.c:493
msgid "MOUNT-PATH and REF must be specified"
msgstr "MOUNT-PATH kaj REF devas esti specifitaj"

#: app/flatpak-builtins-create-usb.c:607
#, c-format
msgid "Ref ‘%s’ found in multiple installations: %s. You must specify one."
msgstr "Ref '%s' trovita en pluraj instalaĵoj: %s. Vi devas specifi unu."

#: app/flatpak-builtins-create-usb.c:620
#, c-format
msgid "Refs must all be in the same installation (found in %s and %s)."
msgstr "Refs devas ĉiuj esti en la sama instalaĵo (trovebla en %s kaj %s)."

#: app/flatpak-builtins-create-usb.c:670
#, c-format
msgid ""
"Warning: Ref ‘%s’ is partially installed. Use --allow-partial to suppress "
"this message.\n"
msgstr ""
"Averto: Ref '%s' estas parte instalita. Uzu --allow-partial por subpremi ĉi "
"tiun mesaĝon.\n"

#: app/flatpak-builtins-create-usb.c:681
#, c-format
msgid "Installed ref ‘%s’ is extra-data, and cannot be distributed offline"
msgstr ""
"Instalita ref '%s' estas kromdatumo, kaj ne povas esti distribuita eksterrete"

#: app/flatpak-builtins-create-usb.c:721
#, c-format
msgid "Warning: Couldn't update repo metadata for remote ‘%s’: %s\n"
msgstr "Averto: Ne eblis ĝisdatigi repo-metadatenojn por fora '%s': %s\n"

#: app/flatpak-builtins-create-usb.c:751
#, c-format
msgid "Warning: Couldn't update appstream data for remote ‘%s’ arch ‘%s’: %s\n"
msgstr ""
"Averto: Ne eblis ĝisdatigi datenojn de la aplikaĵo por fora '%s' arko '%s': "
"%s\n"

#. Print a warning if both appstream and appstream2 are missing
#: app/flatpak-builtins-create-usb.c:784
#, c-format
msgid ""
"Warning: Couldn't find appstream data for remote ‘%s’ arch ‘%s’: %s; %s\n"
msgstr ""
"Averto: Ne eblis trovi datenojn de aplikfluo por fora '%s' arko '%s': %s; "
"%s\n"

#. Appstream2 is only for efficiency, so just print a debug message
#: app/flatpak-builtins-create-usb.c:790
#, c-format
msgid "Couldn't find appstream2 data for remote ‘%s’ arch ‘%s’: %s\n"
msgstr "Ne eblis trovi datumojn de appstream2 por fora '%s' arko '%s': %s\n"

#: app/flatpak-builtins-document-export.c:62
msgid "Create a unique document reference"
msgstr "Krei unikan dokumentan referencon"

#: app/flatpak-builtins-document-export.c:63
msgid "Make the document transient for the current session"
msgstr "Fari la dokumenton pasema por la nuna sesio"

#: app/flatpak-builtins-document-export.c:64
msgid "Don't require the file to exist already"
msgstr "Ne postulu, ke la dosiero jam ekzistus"

#: app/flatpak-builtins-document-export.c:65
msgid "Give the app read permissions"
msgstr "Doni al la aplikaĵo legi permesojn"

#: app/flatpak-builtins-document-export.c:66
msgid "Give the app write permissions"
msgstr "Doni al la aplikaĵo skribi permesojn"

#: app/flatpak-builtins-document-export.c:67
msgid "Give the app delete permissions"
msgstr "Doni al la apo forigi permesojn"

#: app/flatpak-builtins-document-export.c:68
msgid "Give the app permissions to grant further permissions"
msgstr "Doni al la aplikaĵo permesojn por doni pliajn permesojn"

#: app/flatpak-builtins-document-export.c:69
msgid "Revoke read permissions of the app"
msgstr "Revoki legajn permesojn de la programo"

#: app/flatpak-builtins-document-export.c:70
msgid "Revoke write permissions of the app"
msgstr "Revoki skribajn permesojn de la programo"

#: app/flatpak-builtins-document-export.c:71
msgid "Revoke delete permissions of the app"
msgstr "Revoki forigi permesojn de la programo"

#: app/flatpak-builtins-document-export.c:72
msgid "Revoke the permission to grant further permissions"
msgstr "Nuligi la permeson doni pliajn permesojn"

#: app/flatpak-builtins-document-export.c:73
msgid "Add permissions for this app"
msgstr "Aldoni permesojn por ĉi tiu programo"

#: app/flatpak-builtins-document-export.c:73
msgid "APPID"
msgstr "APPID"

#: app/flatpak-builtins-document-export.c:100
msgid "FILE - Export a file to apps"
msgstr "DOSIERO - Elporti dosieron al programoj"

#: app/flatpak-builtins-document-export.c:109
#: app/flatpak-builtins-document-info.c:72
#: app/flatpak-builtins-document-unexport.c:67
msgid "FILE must be specified"
msgstr "DOSIERO devas esti specifita"

#: app/flatpak-builtins-document-info.c:63
msgid "FILE - Get information about an exported file"
msgstr "DOSIERO - Akiri informojn pri eksportita dosiero"

#: app/flatpak-builtins-document-info.c:100
#: app/flatpak-builtins-document-unexport.c:94
#, c-format
msgid "Not exported\n"
msgstr "Ne eksportita\n"

#: app/flatpak-builtins-document-list.c:43 app/flatpak-builtins-history.c:53
#: app/flatpak-builtins-list.c:54 app/flatpak-builtins-ps.c:43
#: app/flatpak-builtins-remote-list.c:45 app/flatpak-builtins-remote-ls.c:59
#: app/flatpak-builtins-search.c:38
msgid "What information to show"
msgstr "Kiajn informojn montri"

#: app/flatpak-builtins-document-list.c:43 app/flatpak-builtins-history.c:53
#: app/flatpak-builtins-list.c:54 app/flatpak-builtins-ps.c:43
#: app/flatpak-builtins-remote-list.c:45 app/flatpak-builtins-remote-ls.c:59
#: app/flatpak-builtins-search.c:38
msgid "FIELD,…"
msgstr "KAMPO,…"

#: app/flatpak-builtins-document-list.c:44 app/flatpak-builtins-history.c:54
#: app/flatpak-builtins-list.c:52 app/flatpak-builtins-permission-list.c:43
#: app/flatpak-builtins-permission-show.c:43 app/flatpak-builtins-ps.c:44
#: app/flatpak-builtins-remote-list.c:46 app/flatpak-builtins-remote-ls.c:63
#: app/flatpak-builtins-repo.c:717 app/flatpak-builtins-search.c:39
msgid "Show output in JSON format"
msgstr "Montri kromajn informojn"

#: app/flatpak-builtins-document-list.c:49
msgid "Show the document ID"
msgstr "Montri la dokumentidentigilon"

#: app/flatpak-builtins-document-list.c:50
msgid "Path"
msgstr "Vojo"

#: app/flatpak-builtins-document-list.c:50
#: app/flatpak-builtins-document-list.c:51
msgid "Show the document path"
msgstr "Montri la dokumentvojon"

#: app/flatpak-builtins-document-list.c:51 app/flatpak-builtins-list.c:66
#: app/flatpak-builtins-remote-ls.c:74
msgid "Origin"
msgstr "Origino"

#: app/flatpak-builtins-document-list.c:52 app/flatpak-builtins-history.c:62
#: app/flatpak-builtins-ps.c:52
msgid "Application"
msgstr "Apliko"

#: app/flatpak-builtins-document-list.c:52
msgid "Show applications with permission"
msgstr "Montri aplikaĵojn kun permeso"

#: app/flatpak-builtins-document-list.c:53
#: app/flatpak-builtins-permission-list.c:182
#: app/flatpak-builtins-permission-show.c:145
msgid "Permissions"
msgstr "Permesoj"

#: app/flatpak-builtins-document-list.c:53
msgid "Show permissions for applications"
msgstr "Montri permesojn por aplikoj"

#: app/flatpak-builtins-document-list.c:161
#, c-format
msgid "No documents found\n"
msgstr "Neniuj dokumentoj trovitaj\n"

#: app/flatpak-builtins-document-list.c:180
msgid "[APPID] - List exported files"
msgstr "[APPID] - Listo de eksportitaj dosieroj"

#: app/flatpak-builtins-document-unexport.c:43
msgid "Specify the document ID"
msgstr "Montri la dokumentidentigilon"

#: app/flatpak-builtins-document-unexport.c:58
msgid "FILE - Unexport a file to apps"
msgstr "DOSIERO - Malelporti dosieron al programoj"

#: app/flatpak-builtins-enter.c:88
msgid "INSTANCE COMMAND [ARGUMENT…] - Run a command inside a running sandbox"
msgstr ""
"INSTANCE [KOMANDO [ARGUMENTO...]] - Ruli komandon en funkcianta sablokesto"

#: app/flatpak-builtins-enter.c:111
msgid "INSTANCE and COMMAND must be specified"
msgstr "INSTANCE kaj COMMAND devas esti specifitaj"

#: app/flatpak-builtins-enter.c:138
#, c-format
msgid "%s is neither a pid nor an application or instance ID"
msgstr "%s estas nek pid nek aplikaĵo aŭ ekzempla ID"

#: app/flatpak-builtins-enter.c:144
msgid "entering not supported (need unprivileged user namespaces, or sudo -E)"
msgstr ""
"enigo ne subtenata (bezonas senprivilegiajn uzantnomspacojn, aŭ sudo -E)"

#: app/flatpak-builtins-enter.c:145
#, c-format
msgid "No such pid %s"
msgstr "Ne tia pid %s"

#: app/flatpak-builtins-enter.c:158
msgid "Can't read cwd"
msgstr "Ne povas legi cwd"

#: app/flatpak-builtins-enter.c:163
msgid "Can't read root"
msgstr "Ne povas legi radikon"

#: app/flatpak-builtins-enter.c:191
#, c-format
msgid "Invalid %s namespace for pid %d"
msgstr "Nevalida %s nomspaco por pid %d"

#: app/flatpak-builtins-enter.c:202
#, c-format
msgid "Invalid %s namespace for self"
msgstr "Nevalida %s nomspaco por mem"

#: app/flatpak-builtins-enter.c:216
#, c-format
msgid "Can't open %s namespace: %s"
msgstr "Ne povas malfermi %s nomspacon: %s"

#: app/flatpak-builtins-enter.c:226
msgid "entering not supported (need unprivileged user namespaces)"
msgstr "enigo ne subtenata (bezonas senprivilegiajn uzantnomspacojn)"

#: app/flatpak-builtins-enter.c:227
#, c-format
msgid "Can't enter %s namespace: %s"
msgstr "Ne povas enigi %s nomspacon: %s"

#: app/flatpak-builtins-enter.c:234
msgid "Can't chdir"
msgstr "Ne povas chdir"

#: app/flatpak-builtins-enter.c:237
msgid "Can't chroot"
msgstr "Ne povas chroot"

#: app/flatpak-builtins-enter.c:240
msgid "Can't switch gid"
msgstr "Ne povas ŝanĝi gid"

#: app/flatpak-builtins-enter.c:243
msgid "Can't switch uid"
msgstr "Ne povas ŝanĝi uid"

#: app/flatpak-builtins-history.c:50
msgid "Only show changes after TIME"
msgstr "Montri ŝanĝojn nur post TIME"

#: app/flatpak-builtins-history.c:50 app/flatpak-builtins-history.c:51
msgid "TIME"
msgstr "TIME"

#: app/flatpak-builtins-history.c:51
msgid "Only show changes before TIME"
msgstr "Montri ŝanĝojn nur antaŭ TIME"

#: app/flatpak-builtins-history.c:52
msgid "Show newest entries first"
msgstr "Montri plej novajn enskribojn unue"

#: app/flatpak-builtins-history.c:59
msgid "Time"
msgstr "Tempo"

#: app/flatpak-builtins-history.c:59
msgid "Show when the change happened"
msgstr "Montri kiam la ŝanĝo okazis"

#: app/flatpak-builtins-history.c:60
msgid "Change"
msgstr "Ŝanĝi"

#: app/flatpak-builtins-history.c:60
msgid "Show the kind of change"
msgstr "Montri la specon de ŝanĝo"

#: app/flatpak-builtins-history.c:61 app/flatpak-builtins-list.c:68
#: app/flatpak-builtins-remote-ls.c:75 app/flatpak-builtins-repo.c:335
msgid "Ref"
msgstr "Ref"

#: app/flatpak-builtins-history.c:61 app/flatpak-builtins-list.c:68
#: app/flatpak-builtins-remote-ls.c:75
msgid "Show the ref"
msgstr "Montri la ref"

#: app/flatpak-builtins-history.c:62
msgid "Show the application/runtime ID"
msgstr "Montri la aplikaĵon/rultempan ID"

#: app/flatpak-builtins-history.c:63 app/flatpak-builtins-list.c:64
#: app/flatpak-builtins-ps.c:53 app/flatpak-builtins-remote-ls.c:73
#: app/flatpak-cli-transaction.c:1435
msgid "Arch"
msgstr "Arch"

#: app/flatpak-builtins-history.c:63 app/flatpak-builtins-list.c:64
#: app/flatpak-builtins-ps.c:53 app/flatpak-builtins-remote-ls.c:73
msgid "Show the architecture"
msgstr "Montri la arkitekturon"

#: app/flatpak-builtins-history.c:64 app/flatpak-builtins-list.c:63
#: app/flatpak-builtins-ps.c:54 app/flatpak-builtins-remote-ls.c:72
#: app/flatpak-builtins-search.c:48 app/flatpak-cli-transaction.c:1438
msgid "Branch"
msgstr "Branĉo"

#: app/flatpak-builtins-history.c:64 app/flatpak-builtins-list.c:63
#: app/flatpak-builtins-remote-ls.c:72
msgid "Show the branch"
msgstr "Montri la branĉon"

#: app/flatpak-builtins-history.c:65 app/flatpak-builtins-list.c:67
msgid "Installation"
msgstr "Instalado"

#: app/flatpak-builtins-history.c:65
msgid "Show the affected installation"
msgstr "Montri la tuŝitan instaladon"

#: app/flatpak-builtins-history.c:66 app/flatpak-cli-transaction.c:1452
msgid "Remote"
msgstr "Malproksima"

#: app/flatpak-builtins-history.c:66
msgid "Show the remote"
msgstr "Montri la telemanieron"

#: app/flatpak-builtins-history.c:67 app/flatpak-builtins-ps.c:55
#: app/flatpak-builtins-remote-ls.c:76
msgid "Commit"
msgstr "Engaĝiĝu"

#: app/flatpak-builtins-history.c:67
msgid "Show the current commit"
msgstr "Montri la nunan transdonon"

#: app/flatpak-builtins-history.c:68
msgid "Old Commit"
msgstr "Old Commit"

#: app/flatpak-builtins-history.c:68
msgid "Show the previous commit"
msgstr "Montri la antaŭan devontigon"

#: app/flatpak-builtins-history.c:69
msgid "Show the remote URL"
msgstr "Montri la foran URL"

#: app/flatpak-builtins-history.c:70 app/flatpak-cli-transaction.c:700
msgid "User"
msgstr "Uzanto"

#: app/flatpak-builtins-history.c:70
msgid "Show the user doing the change"
msgstr "Montri la uzanton farantan la ŝanĝon"

#: app/flatpak-builtins-history.c:71
msgid "Tool"
msgstr "Ilo"

#: app/flatpak-builtins-history.c:71
msgid "Show the tool that was used"
msgstr "Montri la ilon kiu estis uzita"

#: app/flatpak-builtins-history.c:72 app/flatpak-builtins-list.c:62
#: app/flatpak-builtins-remote-ls.c:71 app/flatpak-builtins-search.c:47
msgid "Version"
msgstr "Versio"

#: app/flatpak-builtins-history.c:72
msgid "Show the Flatpak version"
msgstr "Montri la Flatpak-version"

#: app/flatpak-builtins-history.c:91
#, c-format
msgid "Failed to get journal data (%s): %s"
msgstr "Malsukcesis akiri ĵurnalan datumojn (%s): %s"

#: app/flatpak-builtins-history.c:146
#, c-format
msgid "Failed to open journal: %s"
msgstr "Malsukcesis malfermi ĵurnalon: %s"

#: app/flatpak-builtins-history.c:153
#, c-format
msgid "Failed to add match to journal: %s"
msgstr "Malsukcesis aldoni kongruon al ĵurnalo: %s"

#: app/flatpak-builtins-history.c:471
msgid " - Show history"
msgstr "- Montri historion"

#: app/flatpak-builtins-history.c:490
#, c-format
msgid "Failed to parse the --since option"
msgstr "Malsukcesis analizi la opcion --since"

#: app/flatpak-builtins-history.c:501
#, c-format
msgid "Failed to parse the --until option"
msgstr "Malsukcesis analizi la opcion --ĝis"

#: app/flatpak-builtins-info.c:56
msgid "Show user installations"
msgstr "Montri uzantinstalaĵojn"

#: app/flatpak-builtins-info.c:57
msgid "Show system-wide installations"
msgstr "Montri tutsistemajn instalaĵojn"

#: app/flatpak-builtins-info.c:58
msgid "Show specific system-wide installations"
msgstr "Montri specifajn tutsistemajn instalaĵojn"

#: app/flatpak-builtins-info.c:59 app/flatpak-builtins-remote-info.c:59
msgid "Show ref"
msgstr "Montri ref"

#: app/flatpak-builtins-info.c:60 app/flatpak-builtins-remote-info.c:60
msgid "Show commit"
msgstr "Montri komision"

#: app/flatpak-builtins-info.c:61
msgid "Show origin"
msgstr "Montri originon"

#: app/flatpak-builtins-info.c:62
msgid "Show size"
msgstr "Montri grandecon"

#: app/flatpak-builtins-info.c:63 app/flatpak-builtins-remote-info.c:62
msgid "Show metadata"
msgstr "Montri metadatenojn"

#: app/flatpak-builtins-info.c:64 app/flatpak-builtins-remote-info.c:63
msgid "Show runtime"
msgstr "Montri rultempon"

#: app/flatpak-builtins-info.c:65 app/flatpak-builtins-remote-info.c:64
msgid "Show sdk"
msgstr "Montri sdk"

#: app/flatpak-builtins-info.c:66
msgid "Show permissions"
msgstr "Montri permesojn"

#: app/flatpak-builtins-info.c:67
msgid "Query file access"
msgstr "Demandi dosiero-aliron"

#: app/flatpak-builtins-info.c:67 app/flatpak-builtins-install.c:82
#: app/flatpak-builtins-install.c:88 app/flatpak-builtins-preinstall.c:68
#: app/flatpak-builtins-run.c:182 app/flatpak-builtins-run.c:184
#: app/flatpak-builtins-update.c:67 app/flatpak-builtins-update.c:71
msgid "PATH"
msgstr "PATH"

#: app/flatpak-builtins-info.c:68
msgid "Show extensions"
msgstr "Montri etendaĵojn"

#: app/flatpak-builtins-info.c:69
msgid "Show location"
msgstr "Montri lokon"

#: app/flatpak-builtins-info.c:116
msgid "NAME [BRANCH] - Get info about an installed app or runtime"
msgstr "NOMO [BRANCH] - Akiri informojn pri instalita aplikaĵo aŭ rultempo"

#: app/flatpak-builtins-info.c:123 app/flatpak-builtins-remote-add.c:317
#: app/flatpak-builtins-remote-delete.c:63
msgid "NAME must be specified"
msgstr "NOMO devas esti specifita"

#: app/flatpak-builtins-info.c:196
msgid "ref not present in origin"
msgstr "ref ne ĉeestanta en origino"

#: app/flatpak-builtins-info.c:211 app/flatpak-builtins-remote-info.c:217
#, c-format
msgid "Warning: Commit has no flatpak metadata\n"
msgstr "Averto: Commit ne havas metadatumojn de flatpak\n"

#: app/flatpak-builtins-info.c:217 app/flatpak-builtins-info.c:259
#: app/flatpak-builtins-info.c:455 app/flatpak-builtins-info.c:513
#: app/flatpak-builtins-remote-info.c:236
#: app/flatpak-builtins-remote-info.c:271
msgid "ID:"
msgstr "ID:"

#: app/flatpak-builtins-info.c:218 app/flatpak-builtins-info.c:260
#: app/flatpak-builtins-remote-info.c:237
#: app/flatpak-builtins-remote-info.c:272
msgid "Ref:"
msgstr "Ref:"

#: app/flatpak-builtins-info.c:219 app/flatpak-builtins-info.c:261
#: app/flatpak-builtins-remote-info.c:238
#: app/flatpak-builtins-remote-info.c:273
msgid "Arch:"
msgstr "Arko:"

#: app/flatpak-builtins-info.c:220 app/flatpak-builtins-info.c:262
#: app/flatpak-builtins-remote-info.c:239
#: app/flatpak-builtins-remote-info.c:274
msgid "Branch:"
msgstr "Branĉo:"

#: app/flatpak-builtins-info.c:222 app/flatpak-builtins-info.c:264
#: app/flatpak-builtins-remote-info.c:241
#: app/flatpak-builtins-remote-info.c:276
msgid "Version:"
msgstr "Versio:"

#: app/flatpak-builtins-info.c:224 app/flatpak-builtins-info.c:266
#: app/flatpak-builtins-remote-info.c:243
#: app/flatpak-builtins-remote-info.c:278
msgid "License:"
msgstr "Licenco:"

#: app/flatpak-builtins-info.c:226 app/flatpak-builtins-info.c:269
#: app/flatpak-builtins-remote-info.c:245
#: app/flatpak-builtins-remote-info.c:280
msgid "Collection:"
msgstr "Kolekto:"

#: app/flatpak-builtins-info.c:227 app/flatpak-builtins-info.c:270
#: app/flatpak-builtins-info.c:458 app/flatpak-builtins-info.c:516
msgid "Installation:"
msgstr "Instalado:"

#: app/flatpak-builtins-info.c:228 app/flatpak-builtins-info.c:271
#: app/flatpak-builtins-info.c:459 app/flatpak-builtins-info.c:517
#: app/flatpak-builtins-remote-info.c:249
#: app/flatpak-builtins-remote-info.c:284
msgid "Installed Size:"
msgstr "Instalita grandeco"

#: app/flatpak-builtins-info.c:231 app/flatpak-builtins-info.c:279
#: app/flatpak-builtins-remote-info.c:252
#: app/flatpak-builtins-remote-info.c:288
msgid "Runtime:"
msgstr "Rultempo:"

#: app/flatpak-builtins-info.c:232 app/flatpak-builtins-info.c:288
#: app/flatpak-builtins-remote-info.c:253
#: app/flatpak-builtins-remote-info.c:293
msgid "Sdk:"
msgstr "Sdk:"

#: app/flatpak-builtins-info.c:235 app/flatpak-builtins-info.c:313
#: app/flatpak-builtins-remote-info.c:256
#: app/flatpak-builtins-remote-info.c:319
msgid "Date:"
msgstr "Dato:"

#: app/flatpak-builtins-info.c:237 app/flatpak-builtins-info.c:311
#: app/flatpak-builtins-remote-info.c:258
#: app/flatpak-builtins-remote-info.c:317
msgid "Subject:"
msgstr "Temo:"

#: app/flatpak-builtins-info.c:240 app/flatpak-builtins-info.c:295
msgid "Active commit:"
msgstr "Aktiva kompromiso:"

#: app/flatpak-builtins-info.c:241 app/flatpak-builtins-info.c:298
msgid "Latest commit:"
msgstr "Plej lasta kompromiso:"

#: app/flatpak-builtins-info.c:244 app/flatpak-builtins-info.c:303
#: app/flatpak-builtins-info.c:457 app/flatpak-builtins-info.c:515
#: app/flatpak-builtins-remote-info.c:259
#: app/flatpak-builtins-remote-info.c:298
msgid "Commit:"
msgstr "Faru:"

#: app/flatpak-builtins-info.c:246 app/flatpak-builtins-info.c:308
#: app/flatpak-builtins-remote-info.c:261
#: app/flatpak-builtins-remote-info.c:303
msgid "Parent:"
msgstr "Gepatro:"

#: app/flatpak-builtins-info.c:248 app/flatpak-builtins-info.c:321
msgid "Alt-id:"
msgstr "Alt-id:"

#: app/flatpak-builtins-info.c:250 app/flatpak-builtins-info.c:325
#: app/flatpak-builtins-remote-info.c:263
#: app/flatpak-builtins-remote-info.c:308
msgid "End-of-life:"
msgstr "Fino de vivo:"

#: app/flatpak-builtins-info.c:252 app/flatpak-builtins-info.c:330
#: app/flatpak-builtins-remote-info.c:265
#: app/flatpak-builtins-remote-info.c:313
msgid "End-of-life-rebase:"
msgstr "Rebazo de fino de vivo:"

#: app/flatpak-builtins-info.c:254 app/flatpak-builtins-info.c:317
msgid "Subdirectories:"
msgstr "Subdosierujoj:"

#: app/flatpak-builtins-info.c:255 app/flatpak-builtins-info.c:454
#: app/flatpak-builtins-info.c:512
msgid "Extension:"
msgstr "Etendo:"

#: app/flatpak-builtins-info.c:267 app/flatpak-builtins-info.c:456
#: app/flatpak-builtins-info.c:514
msgid "Origin:"
msgstr "Origino:"

#: app/flatpak-builtins-info.c:460 app/flatpak-builtins-info.c:522
msgid "Subpaths:"
msgstr "Subvojoj:"

#: app/flatpak-builtins-info.c:478
msgid "unmaintained"
msgstr "neprizorgita"

#: app/flatpak-builtins-info.c:480 app/flatpak-builtins-info.c:482
msgid "unknown"
msgstr "nekonata"

#: app/flatpak-builtins-install.c:68 app/flatpak-builtins-preinstall.c:57
msgid "Don't pull, only install from local cache"
msgstr "Ne tiri, nur instali el loka kaŝmemoro"

#: app/flatpak-builtins-install.c:69 app/flatpak-builtins-preinstall.c:58
#: app/flatpak-builtins-update.c:60
msgid "Don't deploy, only download to local cache"
msgstr "Ne disfaldu, nur elŝuti al loka kaŝmemoro"

#: app/flatpak-builtins-install.c:70 app/flatpak-builtins-preinstall.c:59
msgid "Don't install related refs"
msgstr "Ne instali rilatajn referencojn"

#: app/flatpak-builtins-install.c:71 app/flatpak-builtins-preinstall.c:60
#: app/flatpak-builtins-update.c:62
msgid "Don't verify/install runtime dependencies"
msgstr "Ne konfirmi/instali rultempajn dependecojn"

#: app/flatpak-builtins-install.c:72
msgid "Don't automatically pin explicit installs"
msgstr "Ne aŭtomate alpingli eksplicitajn instalojn"

#: app/flatpak-builtins-install.c:73 app/flatpak-builtins-preinstall.c:61
#: app/flatpak-builtins-update.c:63
msgid "Don't use static deltas"
msgstr "Ne uzi senmovajn deltojn"

#: app/flatpak-builtins-install.c:76 app/flatpak-builtins-preinstall.c:62
msgid "Additionally install the SDK used to build the given refs"
msgstr "Aldone instali la SDK uzatan por konstrui la donitajn referencojn"

#: app/flatpak-builtins-install.c:77 app/flatpak-builtins-preinstall.c:63
msgid ""
"Additionally install the debug info for the given refs and their dependencies"
msgstr ""
"Aldone instali la sencimigan informon por la donitaj referencoj kaj iliaj "
"dependecoj"

#: app/flatpak-builtins-install.c:78
msgid "Assume LOCATION is a .flatpak single-file bundle"
msgstr "Supozi LOKO estas .flatpak unudosiera pakaĵo"

#: app/flatpak-builtins-install.c:79
msgid "Assume LOCATION is a .flatpakref application description"
msgstr "Supozi LOKO estas .flatpakref aplika priskribo"

#: app/flatpak-builtins-install.c:80
msgid "Assume LOCATION is containers-transports(5) reference to an OCI image"
msgstr "Supozi LOKO estas ujoj-transportoj(5) referenco al OCI-bildo"

#: app/flatpak-builtins-install.c:81
msgid "Check bundle signatures with GPG key from FILE (- for stdin)"
msgstr "Kontroli pakajn subskribojn per GPG-ŝlosilo el DOSIERO (- por stdin)"

#: app/flatpak-builtins-install.c:82
msgid "Only install this subpath"
msgstr "Nur instali ĉi tiun subvojon"

#: app/flatpak-builtins-install.c:83 app/flatpak-builtins-preinstall.c:64
#: app/flatpak-builtins-uninstall.c:63 app/flatpak-builtins-update.c:68
msgid "Automatically answer yes for all questions"
msgstr "Aŭtomate respondi jes por ĉiuj demandoj"

#: app/flatpak-builtins-install.c:84 app/flatpak-builtins-preinstall.c:65
msgid "Uninstall first if already installed"
msgstr "Unue malinstali se jam instalite"

#: app/flatpak-builtins-install.c:85 app/flatpak-builtins-preinstall.c:66
#: app/flatpak-builtins-uninstall.c:64 app/flatpak-builtins-update.c:69
msgid "Produce minimal output and don't ask questions"
msgstr "Produkti minimuman produktadon kaj ne fari demandojn"

#: app/flatpak-builtins-install.c:86
msgid "Update install if already installed"
msgstr "Unue malinstali se jam instalite"

#. Translators: A sideload is when you install from a local USB drive rather than the Internet.
#: app/flatpak-builtins-install.c:88 app/flatpak-builtins-preinstall.c:68
#: app/flatpak-builtins-update.c:71
msgid "Use this local repo for sideloads"
msgstr "Uzi ĉi tiun lokan repo por flankŝarĝoj"

#: app/flatpak-builtins-install.c:178
msgid "Bundle filename must be specified"
msgstr "Paka dosiernomo devas esti specifita"

#: app/flatpak-builtins-install.c:188
msgid "Remote bundles are not supported"
msgstr "Foraj pakaĵoj ne estas subtenataj"

#: app/flatpak-builtins-install.c:231
msgid "Filename or uri must be specified"
msgstr "Dosiernomo aŭ uri devas esti specifitaj"

#: app/flatpak-builtins-install.c:295
msgid "Image location must be specified"
msgstr "Almenaŭ unu REF devas esti specifita"

#: app/flatpak-builtins-install.c:345
msgid "[LOCATION/REMOTE] [REF…] - Install applications or runtimes"
msgstr "[LOKIO/FORTA] [REF...] - Instali aplikaĵojn aŭ rultempojn"

#: app/flatpak-builtins-install.c:378
msgid "At least one REF must be specified"
msgstr "Almenaŭ unu REF devas esti specifita"

#: app/flatpak-builtins-install.c:392
#, c-format
msgid "Looking for matches…\n"
msgstr "Serĉante alumetojn...\n"

#: app/flatpak-builtins-install.c:513
#, c-format
msgid "No remote refs found for ‘%s’"
msgstr "Neniuj malproksimaj referencoj trovitaj similaj al '%s'"

#: app/flatpak-builtins-install.c:573 app/flatpak-builtins-uninstall.c:405
#: common/flatpak-ref-utils.c:689 common/flatpak-ref-utils.c:1595
#, c-format
msgid "Invalid branch %s: %s"
msgstr "Nevalida branĉo %s: %s"

#: app/flatpak-builtins-install.c:606
#, c-format
msgid "Nothing matches %s in local repository for remote %s"
msgstr "Nenio kongruas kun %s en loka deponejo por fora %s"

#: app/flatpak-builtins-install.c:608
#, c-format
msgid "Nothing matches %s in remote %s"
msgstr "Nenio kongruas kun %s en fora %s"

#: app/flatpak-builtins-install.c:629
#, c-format
msgid "Skipping: %s\n"
msgstr "Preterpasi: %s\n"

#: app/flatpak-builtins-kill.c:110
#, c-format
msgid "%s is not running"
msgstr "%s ne funkcias."

#: app/flatpak-builtins-kill.c:136
msgid "INSTANCE - Stop a running application"
msgstr "INSTANCE - Ĉesigi funkciantan aplikaĵon"

#: app/flatpak-builtins-kill.c:144 app/flatpak-builtins-ps.c:256
msgid "Extra arguments given"
msgstr "Kromaj argumentoj donitaj"

#: app/flatpak-builtins-kill.c:150
msgid "Must specify the app to kill"
msgstr "Devas specifi la apon por mortigi"

#: app/flatpak-builtins-list.c:47
msgid "Show extra information"
msgstr "Montri kromajn informojn"

#: app/flatpak-builtins-list.c:48
msgid "List installed runtimes"
msgstr "Listigi instalitajn rultempojn"

#: app/flatpak-builtins-list.c:49
msgid "List installed applications"
msgstr "Listigi instalitajn aplikojn"

#: app/flatpak-builtins-list.c:50
msgid "Arch to show"
msgstr "Arko por montri"

#: app/flatpak-builtins-list.c:51 app/flatpak-builtins-remote-ls.c:57
msgid "List all refs (including locale/debug)"
msgstr "Listigi ĉiujn referencojn (inkluzive de loka/sencimigo)"

#: app/flatpak-builtins-list.c:53 app/flatpak-builtins-remote-ls.c:58
msgid "List all applications using RUNTIME"
msgstr "Listigi ĉiujn aplikojn uzante RUNTIME"

#: app/flatpak-builtins-list.c:59 app/flatpak-builtins-remote-list.c:51
#: app/flatpak-builtins-remote-ls.c:68 app/flatpak-builtins-search.c:44
msgid "Name"
msgstr "Nomo"

#: app/flatpak-builtins-list.c:59 app/flatpak-builtins-remote-list.c:51
#: app/flatpak-builtins-remote-ls.c:68 app/flatpak-builtins-search.c:44
msgid "Show the name"
msgstr "Montri la nomon"

#: app/flatpak-builtins-list.c:60 app/flatpak-builtins-remote-list.c:60
#: app/flatpak-builtins-remote-ls.c:69 app/flatpak-builtins-search.c:45
msgid "Description"
msgstr "Priskribo"

#: app/flatpak-builtins-list.c:60 app/flatpak-builtins-remote-ls.c:69
#: app/flatpak-builtins-search.c:45
msgid "Show the description"
msgstr "Montri la priskribon"

#: app/flatpak-builtins-list.c:61 app/flatpak-builtins-remote-ls.c:70
#: app/flatpak-builtins-search.c:46
msgid "Application ID"
msgstr "Aplika ID"

#: app/flatpak-builtins-list.c:61 app/flatpak-builtins-ps.c:52
#: app/flatpak-builtins-remote-ls.c:70 app/flatpak-builtins-search.c:46
msgid "Show the application ID"
msgstr "Montri la aplikan ID"

#: app/flatpak-builtins-list.c:62 app/flatpak-builtins-remote-ls.c:71
#: app/flatpak-builtins-search.c:47
msgid "Show the version"
msgstr "Montri la version"

#: app/flatpak-builtins-list.c:65 app/flatpak-builtins-ps.c:56
#: app/flatpak-builtins-remote-ls.c:77
msgid "Runtime"
msgstr "Runtime"

#: app/flatpak-builtins-list.c:65
msgid "Show the used runtime"
msgstr "Montri la uzatan rultempon"

#: app/flatpak-builtins-list.c:66 app/flatpak-builtins-remote-ls.c:74
msgid "Show the origin remote"
msgstr "Montri la originforan foron"

#: app/flatpak-builtins-list.c:67
msgid "Show the installation"
msgstr "Montri la instaladon"

#: app/flatpak-builtins-list.c:69
msgid "Active commit"
msgstr "Aktiva kompromiso"

#: app/flatpak-builtins-list.c:69 app/flatpak-builtins-remote-ls.c:76
msgid "Show the active commit"
msgstr "Montri la aktivan devontigon"

#: app/flatpak-builtins-list.c:70
msgid "Latest commit"
msgstr "Plej lasta kompromiso"

#: app/flatpak-builtins-list.c:70
msgid "Show the latest commit"
msgstr "Montri la plej novan kompromiton"

#: app/flatpak-builtins-list.c:71 app/flatpak-builtins-remote-ls.c:78
msgid "Installed size"
msgstr "Instalita grandeco"

#: app/flatpak-builtins-list.c:71 app/flatpak-builtins-remote-ls.c:78
msgid "Show the installed size"
msgstr "Montri la instalitan grandecon"

#: app/flatpak-builtins-list.c:72 app/flatpak-builtins-remote-list.c:58
#: app/flatpak-builtins-remote-ls.c:80 app/flatpak-builtins-repo.c:340
msgid "Options"
msgstr "Opcioj"

#: app/flatpak-builtins-list.c:72 app/flatpak-builtins-remote-list.c:58
#: app/flatpak-builtins-remote-ls.c:80
msgid "Show options"
msgstr "Montri eblojn"

#: app/flatpak-builtins-list.c:180
#, c-format
msgid "Unable to load details of %s: %s"
msgstr "Ne eblas ŝargi metadatenojn de fora %s: %s"

#: app/flatpak-builtins-list.c:190
#, c-format
msgid "Unable to inspect current version of %s: %s"
msgstr "Ne eblas inspekti nunan version de %s: %s"

#: app/flatpak-builtins-list.c:408
msgid " - List installed apps and/or runtimes"
msgstr "- Listigi instalitajn programojn kaj/aŭ rultempojn"

#: app/flatpak-builtins-make-current.c:38
msgid "Arch to make current for"
msgstr "Arko por fari fluon"

#: app/flatpak-builtins-make-current.c:58
msgid "APP BRANCH - Make branch of application current"
msgstr "APP BRANCH - Fari branĉon de aplikaĵo aktuala"

#: app/flatpak-builtins-make-current.c:69 app/flatpak-builtins-run.c:260
msgid "APP must be specified"
msgstr "APP devas esti specifita"

#: app/flatpak-builtins-make-current.c:84
msgid "BRANCH must be specified"
msgstr "BRANĈO devas esti precizigita"

#: app/flatpak-builtins-make-current.c:97
#, c-format
msgid "App %s branch %s is not installed"
msgstr "Apo %s branĉo %s ne estas instalita"

#: app/flatpak-builtins-mask.c:42
msgid "Remove matching masks"
msgstr "Ĉu forigi ilin?"

#: app/flatpak-builtins-mask.c:54
msgid ""
"[PATTERN…] - disable updates and automatic installation matching patterns"
msgstr ""
"[PATTERN...] - malebligi ĝisdatigojn kaj aŭtomatajn instalaĵojn kongruajn "
"ŝablonojn"

#: app/flatpak-builtins-mask.c:73
#, c-format
msgid "No masked patterns\n"
msgstr "Neniuj maskitaj ŝablonoj\n"

#: app/flatpak-builtins-mask.c:78
#, c-format
msgid "Masked patterns:\n"
msgstr "Maskitaj ŝablonoj:\n"

#: app/flatpak-builtins-override.c:42
msgid "Remove existing overrides"
msgstr "Forigi ekzistantajn anstataŭojn"

#: app/flatpak-builtins-override.c:43
msgid "Show existing overrides"
msgstr "Montri ekzistantajn anstataŭojn"

#: app/flatpak-builtins-override.c:59
msgid "[APP] - Override settings [for application]"
msgstr "[APP] - Anstataŭigi agordojn [por aplikaĵo]"

#: app/flatpak-builtins-permission-list.c:143
msgid "[TABLE] [ID] - List permissions"
msgstr "[TABLO] [ID] - Listo de permesoj"

#: app/flatpak-builtins-permission-list.c:179
#: app/flatpak-builtins-permission-show.c:142
msgid "Table"
msgstr "Tablo"

#: app/flatpak-builtins-permission-list.c:180
#: app/flatpak-builtins-permission-show.c:143
msgid "Object"
msgstr "Objekto"

#: app/flatpak-builtins-permission-list.c:181
#: app/flatpak-builtins-permission-show.c:144
msgid "App"
msgstr "App"

#: app/flatpak-builtins-permission-list.c:183
#: app/flatpak-builtins-permission-show.c:146
msgid "Data"
msgstr "Datumoj"

#: app/flatpak-builtins-permission-remove.c:120
msgid "TABLE ID [APP_ID] - Remove item from permission store"
msgstr "TABLA ID - Forigi objekton el permesa vendejo"

#: app/flatpak-builtins-permission-remove.c:129
#: app/flatpak-builtins-permission-set.c:120
msgid "Too few arguments"
msgstr "Tro malmultaj argumentoj"

#: app/flatpak-builtins-permission-reset.c:43
msgid "Reset all permissions"
msgstr "Restarigi ĉiujn permesojn"

#: app/flatpak-builtins-permission-reset.c:144
msgid "APP_ID - Reset permissions for an app"
msgstr "APP_ID - Restarigi permesojn por programo"

#: app/flatpak-builtins-permission-reset.c:153
#: app/flatpak-builtins-permission-show.c:124
msgid "Wrong number of arguments"
msgstr "Malĝusta nombro da argumentoj"

#: app/flatpak-builtins-permission-set.c:42
msgid "Associate DATA with the entry"
msgstr "Asocii DATUJN kun la eniro"

#: app/flatpak-builtins-permission-set.c:42
msgid "DATA"
msgstr "DATA"

#: app/flatpak-builtins-permission-set.c:111
msgid "TABLE ID APP_ID [PERMISSION...] - Set permissions"
msgstr "[TABLO] [ID] - Listo de permesoj"

#: app/flatpak-builtins-permission-set.c:132
#, c-format
msgid "Failed to parse '%s' as GVariant: "
msgstr "Malsukcesis analizi filtrilon '%s'"

#: app/flatpak-builtins-permission-show.c:115
msgid "APP_ID - Show permissions for an app"
msgstr "APP_ID - Montri permesojn por aplikaĵo"

#: app/flatpak-builtins-pin.c:44
msgid "Remove matching pins"
msgstr "Ĉu forigi ilin?"

#: app/flatpak-builtins-pin.c:56
msgid "[PATTERN…] - disable automatic removal of runtimes matching patterns"
msgstr ""
"[PATTERN...] - malebligi aŭtomatan forigon de rultempoj kongruaj ŝablonoj"

#: app/flatpak-builtins-pin.c:75
#, c-format
msgid "No pinned patterns\n"
msgstr "Neniuj alpinglitaj ŝablonoj\n"

#: app/flatpak-builtins-pin.c:80
#, c-format
msgid "Pinned patterns:\n"
msgstr "Alpinglitaj ŝablonoj:\n"

#: app/flatpak-builtins-preinstall.c:80
msgid "- Install flatpaks that are part of the operating system"
msgstr "- Instali flatpakaĵojn kiuj estas parto de la operaciumo"

#: app/flatpak-builtins-preinstall.c:118
#, c-format
msgid "Nothing to do.\n"
msgstr "Nenio farenda.\n"

#: app/flatpak-builtins-ps.c:49
msgid "Instance"
msgstr "Kazo"

#: app/flatpak-builtins-ps.c:49
msgid "Show the instance ID"
msgstr "Montri la instantan ID"

#: app/flatpak-builtins-ps.c:50 app/flatpak-builtins-run.c:178
msgid "PID"
msgstr "PID"

#: app/flatpak-builtins-ps.c:50
msgid "Show the PID of the wrapper process"
msgstr "Montri la PID de la envolvaĵprocezo"

#: app/flatpak-builtins-ps.c:51
msgid "Child-PID"
msgstr "Infano-PID"

#: app/flatpak-builtins-ps.c:51
msgid "Show the PID of the sandbox process"
msgstr "Montri la PID de la sandbox-procezo"

#: app/flatpak-builtins-ps.c:54 app/flatpak-builtins-search.c:48
msgid "Show the application branch"
msgstr "Montri la aplikan branĉon"

#: app/flatpak-builtins-ps.c:55
msgid "Show the application commit"
msgstr "Montri la aplikaĵon"

#: app/flatpak-builtins-ps.c:56
msgid "Show the runtime ID"
msgstr "Montri la rultempan ID"

#: app/flatpak-builtins-ps.c:57
msgid "R.-Branch"
msgstr "R.-Branĉo"

#: app/flatpak-builtins-ps.c:57
msgid "Show the runtime branch"
msgstr "Montri la rultempan branĉon"

#: app/flatpak-builtins-ps.c:58
msgid "R.-Commit"
msgstr "R.-Engaĝiĝu"

#: app/flatpak-builtins-ps.c:58
msgid "Show the runtime commit"
msgstr "Montri la rultempan komision"

#: app/flatpak-builtins-ps.c:59
msgid "Active"
msgstr "Aktiva kompromiso"

#: app/flatpak-builtins-ps.c:59
msgid "Show whether the app is active"
msgstr "Montri kiam la ŝanĝo okazis"

#: app/flatpak-builtins-ps.c:60
msgid "Background"
msgstr "Fono"

#: app/flatpak-builtins-ps.c:60
msgid "Show whether the app is background"
msgstr "Montri kiam la ŝanĝo okazis"

#: app/flatpak-builtins-ps.c:246
msgid " - Enumerate running sandboxes"
msgstr "- Nombri kurantajn sablokestojn"

#: app/flatpak-builtins-remote-add.c:66
msgid "Do nothing if the provided remote exists"
msgstr "Fari nenion se la provizita telecomando ekzistas"

#: app/flatpak-builtins-remote-add.c:67
msgid "LOCATION specifies a configuration file, not the repo location"
msgstr "LOKO specifas agordan dosieron, ne la deponejo"

#: app/flatpak-builtins-remote-add.c:72 app/flatpak-builtins-remote-modify.c:78
msgid "Disable GPG verification"
msgstr "Malebligi GPG-konfirmon"

#: app/flatpak-builtins-remote-add.c:73 app/flatpak-builtins-remote-modify.c:79
msgid "Mark the remote as don't enumerate"
msgstr "Marki la teleilon kiel ne listigu"

#: app/flatpak-builtins-remote-add.c:74 app/flatpak-builtins-remote-modify.c:80
msgid "Mark the remote as don't use for deps"
msgstr "Marki la teleilon kiel ne uzi por dep"

#: app/flatpak-builtins-remote-add.c:75 app/flatpak-builtins-remote-modify.c:81
msgid "Set priority (default 1, higher is more prioritized)"
msgstr "Agordi prioritaton (defaŭlte 1, pli alta estas pli prioritatita)"

#: app/flatpak-builtins-remote-add.c:75 app/flatpak-builtins-remote-modify.c:81
msgid "PRIORITY"
msgstr "PRIORITY"

#: app/flatpak-builtins-remote-add.c:76
msgid "The named subset to use for this remote"
msgstr "Bela nomo uzinda por ĉi tiu telecomando"

#: app/flatpak-builtins-remote-add.c:76 app/flatpak-builtins-remote-modify.c:71
msgid "SUBSET"
msgstr "SUBSET"

#: app/flatpak-builtins-remote-add.c:77 app/flatpak-builtins-remote-modify.c:82
msgid "A nice name to use for this remote"
msgstr "Bela nomo uzinda por ĉi tiu telecomando"

#: app/flatpak-builtins-remote-add.c:78 app/flatpak-builtins-remote-modify.c:83
msgid "A one-line comment for this remote"
msgstr "Unulinia komento por ĉi tiu telecomando"

#: app/flatpak-builtins-remote-add.c:79 app/flatpak-builtins-remote-modify.c:84
msgid "A full-paragraph description for this remote"
msgstr "Plena alinea priskribo por ĉi tiu fora"

#: app/flatpak-builtins-remote-add.c:80 app/flatpak-builtins-remote-modify.c:85
msgid "URL for a website for this remote"
msgstr "URL por retejo por ĉi tiu fora"

#: app/flatpak-builtins-remote-add.c:81 app/flatpak-builtins-remote-modify.c:86
msgid "URL for an icon for this remote"
msgstr "URL por ikono por ĉi tiu telecomando"

#: app/flatpak-builtins-remote-add.c:82 app/flatpak-builtins-remote-modify.c:87
msgid "Default branch to use for this remote"
msgstr "Defaŭlta branĉo uzinda por ĉi tiu fora"

#: app/flatpak-builtins-remote-add.c:84 app/flatpak-builtins-remote-modify.c:89
msgid "Import GPG key from FILE (- for stdin)"
msgstr "Enporti GPG-ŝlosilon el DOSIERO (- por stdin)"

#: app/flatpak-builtins-remote-add.c:85 app/flatpak-builtins-remote-modify.c:90
msgid "Load signatures from URL"
msgstr "Ŝarĝi subskribojn de URL"

#: app/flatpak-builtins-remote-add.c:86 app/flatpak-builtins-remote-modify.c:92
msgid "Set path to local filter FILE"
msgstr "Agordi vojon al loka filtrila DOSIERO"

#: app/flatpak-builtins-remote-add.c:87 app/flatpak-builtins-remote-modify.c:93
msgid "Disable the remote"
msgstr "Malŝalti la telecomandilon"

#: app/flatpak-builtins-remote-add.c:88 app/flatpak-builtins-remote-modify.c:94
msgid "Name of authenticator"
msgstr "Nomo de aŭtentikigilo"

#: app/flatpak-builtins-remote-add.c:90 app/flatpak-builtins-remote-modify.c:96
msgid "Autoinstall authenticator"
msgstr "Nevalida dbus-nomo %s"

#: app/flatpak-builtins-remote-add.c:91 app/flatpak-builtins-remote-modify.c:97
msgid "Don't autoinstall authenticator"
msgstr "Ne malinstali rilatajn referencojn"

#: app/flatpak-builtins-remote-add.c:92 app/flatpak-builtins-remote-modify.c:99
msgid "Don't follow the redirect set in the summary file"
msgstr "Ne sekvi la alidirektilon fiksitan en la resuma dosiero"

#: app/flatpak-builtins-remote-add.c:261 app/flatpak-builtins-remote-add.c:268
#, c-format
msgid "Can't load uri %s: %s\n"
msgstr "Ne povas ŝargi uri %s: %s\n"

#: app/flatpak-builtins-remote-add.c:276 common/flatpak-dir.c:4643
#, c-format
msgid "Can't load file %s: %s\n"
msgstr "Ne povas ŝargi dosieron %s: %s\n"

#: app/flatpak-builtins-remote-add.c:304
msgid "NAME LOCATION - Add a remote repository"
msgstr "NOMO LOKO - Aldoni malproksiman deponejon"

#: app/flatpak-builtins-remote-add.c:331
msgid "GPG verification is required if collections are enabled"
msgstr "GPG-konfirmo estas postulata se kolektoj estas ebligitaj"

#: app/flatpak-builtins-remote-add.c:393
#, c-format
msgid "Remote %s already exists"
msgstr "Fora %s jam ekzistas"

#: app/flatpak-builtins-remote-add.c:405
#: app/flatpak-builtins-remote-modify.c:340
#, c-format
msgid "Invalid authenticator name %s"
msgstr "Nevalida dbus-nomo %s"

#: app/flatpak-builtins-remote-add.c:422
#, c-format
msgid "Warning: Could not update extra metadata for '%s': %s\n"
msgstr "Averto: Ne eblis ĝisdatigi kromajn metadatenojn por '%s': %s\n"

#: app/flatpak-builtins-remote-delete.c:39
msgid "Remove remote even if in use"
msgstr "Forigi telerilon eĉ se estas uzata"

#: app/flatpak-builtins-remote-delete.c:53
msgid "NAME - Delete a remote repository"
msgstr "NOMO - Forigi foran deponejon"

#: app/flatpak-builtins-remote-delete.c:100
#, c-format
msgid "The following refs are installed from remote '%s':"
msgstr "La sekvaj referencoj estas instalitaj de fora '%s':"

#: app/flatpak-builtins-remote-delete.c:101
msgid "Remove them?"
msgstr "Ĉu forigi ilin?"

#: app/flatpak-builtins-remote-delete.c:103
#, c-format
msgid "Can't remove remote '%s' with installed refs"
msgstr "Ne povas forigi fora '%s' kun instalitaj referencoj"

#: app/flatpak-builtins-remote-info.c:55
msgid "Commit to show info for"
msgstr "Engaĝiĝi montri informojn por"

#: app/flatpak-builtins-remote-info.c:58
msgid "Display log"
msgstr "Montri protokolon"

#: app/flatpak-builtins-remote-info.c:61
msgid "Show parent"
msgstr "Montri gepatron"

#: app/flatpak-builtins-remote-info.c:65 app/flatpak-builtins-remote-ls.c:60
msgid "Use local caches even if they are stale"
msgstr "Uzi lokajn kaŝmemorojn eĉ se ili estas malnoviĝintaj"

#. Translators: A sideload is when you install from a local USB drive rather than the Internet.
#: app/flatpak-builtins-remote-info.c:67 app/flatpak-builtins-remote-ls.c:62
msgid "Only list refs available as sideloads"
msgstr "Nur listaj referencoj haveblaj kiel flankŝarĝoj"

#: app/flatpak-builtins-remote-info.c:114
msgid ""
" REMOTE REF - Show information about an application or runtime in a remote"
msgstr "REMOTE REF - Montri informojn pri aplikaĵo aŭ rultempo en fora"

#: app/flatpak-builtins-remote-info.c:125
msgid "REMOTE and REF must be specified"
msgstr "REMOTE kaj REF devas esti specifitaj"

#: app/flatpak-builtins-remote-info.c:247
#: app/flatpak-builtins-remote-info.c:282
msgid "Download Size:"
msgstr "Elŝuta grandeco"

#: app/flatpak-builtins-remote-info.c:267
#: app/flatpak-builtins-remote-info.c:325
msgid "History:"
msgstr "Historio:"

#: app/flatpak-builtins-remote-info.c:348
msgid " Commit:"
msgstr "Faru:"

#: app/flatpak-builtins-remote-info.c:349
msgid " Subject:"
msgstr "Temo:"

#: app/flatpak-builtins-remote-info.c:350
msgid " Date:"
msgstr "Dato:"

#: app/flatpak-builtins-remote-info.c:383
#, c-format
msgid "Warning: Commit %s has no flatpak metadata\n"
msgstr "Averto: Fari %s ne havas metadatumojn de flatpak\n"

#: app/flatpak-builtins-remote-list.c:43
msgid "Show remote details"
msgstr "Montri forajn detalojn"

#: app/flatpak-builtins-remote-list.c:44
msgid "Show disabled remotes"
msgstr "Montri malfunkciigitajn teleremotojn"

#: app/flatpak-builtins-remote-list.c:52
msgid "Title"
msgstr "Titolo"

#: app/flatpak-builtins-remote-list.c:52
msgid "Show the title"
msgstr "Montri la titolon"

#: app/flatpak-builtins-remote-list.c:53
msgid "Show the URL"
msgstr "Montri la URL"

#: app/flatpak-builtins-remote-list.c:54
msgid "Show the collection ID"
msgstr "Montri la kolekton ID"

#: app/flatpak-builtins-remote-list.c:55 app/flatpak-builtins-repo.c:392
msgid "Subset"
msgstr "Subaro"

#: app/flatpak-builtins-remote-list.c:55
msgid "Show the subset"
msgstr "Montri la ref"

#: app/flatpak-builtins-remote-list.c:56
msgid "Filter"
msgstr "Filtrilo"

#: app/flatpak-builtins-remote-list.c:56
msgid "Show filter file"
msgstr "Montri filtrilan dosieron"

#: app/flatpak-builtins-remote-list.c:57
msgid "Priority"
msgstr "Prioritato"

#: app/flatpak-builtins-remote-list.c:57
msgid "Show the priority"
msgstr "Montri la prioritaton"

#: app/flatpak-builtins-remote-list.c:59
msgid "Comment"
msgstr "Komento"

#: app/flatpak-builtins-remote-list.c:59
msgid "Show comment"
msgstr "Montri komenton"

#: app/flatpak-builtins-remote-list.c:60
msgid "Show description"
msgstr "Montri priskribon"

#: app/flatpak-builtins-remote-list.c:61
msgid "Homepage"
msgstr "Hejmpaĝo"

#: app/flatpak-builtins-remote-list.c:61
msgid "Show homepage"
msgstr "Montri hejmpaĝon"

#: app/flatpak-builtins-remote-list.c:62
msgid "Icon"
msgstr "Ikono"

#: app/flatpak-builtins-remote-list.c:62
msgid "Show icon"
msgstr "Montri ikonon"

#: app/flatpak-builtins-remote-list.c:231
msgid " - List remote repositories"
msgstr "- Listigi forajn deponejojn"

#: app/flatpak-builtins-remote-ls.c:52
msgid "Show arches and branches"
msgstr "Montri arkojn kaj branĉojn"

#: app/flatpak-builtins-remote-ls.c:53
msgid "Show only runtimes"
msgstr "Montri nur rultempojn"

#: app/flatpak-builtins-remote-ls.c:54
msgid "Show only apps"
msgstr "Montri nur apojn"

#: app/flatpak-builtins-remote-ls.c:55
msgid "Show only those where updates are available"
msgstr "Montri nur tiujn, kie ĝisdatigoj estas disponeblaj"

#: app/flatpak-builtins-remote-ls.c:56
msgid "Limit to this arch (* for all)"
msgstr "Limigi al ĉi tiu arko (* por ĉiuj)"

#: app/flatpak-builtins-remote-ls.c:77
msgid "Show the runtime"
msgstr "Montri la rultempon"

#: app/flatpak-builtins-remote-ls.c:79
msgid "Download size"
msgstr "Elŝuta grandeco"

#: app/flatpak-builtins-remote-ls.c:79
msgid "Show the download size"
msgstr "Montri la elŝutan grandecon"

#: app/flatpak-builtins-remote-ls.c:391
msgid " [REMOTE or URI] - Show available runtimes and applications"
msgstr "[REMOTO aŭ URI] - Montri disponeblajn rultempojn kaj aplikaĵojn"

#: app/flatpak-builtins-remote-modify.c:67
msgid "Enable GPG verification"
msgstr "Ebligi GPG-kontrolon"

#: app/flatpak-builtins-remote-modify.c:68
msgid "Mark the remote as enumerate"
msgstr "Marki la telerilon kiel listigi"

#: app/flatpak-builtins-remote-modify.c:69
msgid "Mark the remote as used for dependencies"
msgstr "Marki la teleremolon kiel uzatan por dependecoj"

#: app/flatpak-builtins-remote-modify.c:70
msgid "Set a new URL"
msgstr "Agordi novan URL"

#: app/flatpak-builtins-remote-modify.c:71
msgid "Set a new subset to use"
msgstr "Agordi novan URL"

#: app/flatpak-builtins-remote-modify.c:72
msgid "Enable the remote"
msgstr "Ebligi la telemanieron"

#: app/flatpak-builtins-remote-modify.c:73
msgid "Update extra metadata from the summary file"
msgstr "Ĝisdatigi kromajn metadatumojn de la resuma dosiero"

#: app/flatpak-builtins-remote-modify.c:91
msgid "Disable local filter"
msgstr "Malebligi lokan filtrilon"

#: app/flatpak-builtins-remote-modify.c:95
msgid "Authenticator options"
msgstr "Montri eblojn"

#: app/flatpak-builtins-remote-modify.c:98
msgid "Follow the redirect set in the summary file"
msgstr "Ĝisdatigi kromajn metadatumojn de la resuma dosiero"

#: app/flatpak-builtins-remote-modify.c:306
msgid "NAME - Modify a remote repository"
msgstr "NOMO - Modifi foran deponejon"

#: app/flatpak-builtins-remote-modify.c:316
msgid "Remote NAME must be specified"
msgstr "Fora NOMO devas esti specifita"

#: app/flatpak-builtins-remote-modify.c:327
#, c-format
msgid "Updating extra metadata from remote summary for %s\n"
msgstr "Ĝisdatigante kromajn metadatenojn de fora resumo por %s\n"

#: app/flatpak-builtins-remote-modify.c:330
#, c-format
msgid "Error updating extra metadata for '%s': %s\n"
msgstr "Eraro dum ĝisdatigo de kromaj metadatenoj por '%s': %s\n"

#: app/flatpak-builtins-remote-modify.c:331
#, c-format
msgid "Could not update extra metadata for %s"
msgstr "Ne eblis ĝisdatigi kromajn metadatenojn por %s"

#: app/flatpak-builtins-repair.c:43
msgid "Don't make any changes"
msgstr "Ne fari ajnajn ŝanĝojn"

#: app/flatpak-builtins-repair.c:44
msgid "Reinstall all refs"
msgstr "Reinstali ĉiujn refojn"

#: app/flatpak-builtins-repair.c:68
#, c-format
msgid "Object missing: %s.%s\n"
msgstr "Objekto mankas: %s.%s\n"

#: app/flatpak-builtins-repair.c:76
#, c-format
msgid "Object invalid: %s.%s\n"
msgstr "Objekto nevalida: %s.%s\n"

#: app/flatpak-builtins-repair.c:81
#, c-format
msgid "%s, deleting object\n"
msgstr "%s, forigo de objekto\n"

#: app/flatpak-builtins-repair.c:146
#, c-format
msgid "Can't load object %s: %s\n"
msgstr "Ne povas ŝargi objekton %s: %s\n"

#: app/flatpak-builtins-repair.c:228
#, c-format
msgid "Commit invalid %s: %s\n"
msgstr "Objekto nevalida: %s.%s\n"

#: app/flatpak-builtins-repair.c:231
#, c-format
msgid "Deleting invalid commit %s: %s\n"
msgstr "Forigas nevalidan faraĵon %s: %s\n"

#: app/flatpak-builtins-repair.c:261
#, c-format
msgid "Commit should be marked partial: %s\n"
msgstr "Commit devus esti markita parta: %s\n"

#: app/flatpak-builtins-repair.c:264
#, c-format
msgid "Marking commit as partial: %s\n"
msgstr "Markado de kompromiso kiel parta: %s\n"

#: app/flatpak-builtins-repair.c:293
#, c-format
msgid "Problems loading data for %s: %s\n"
msgstr "Problemoj dum ŝarĝo de datumoj por %s: %s\n"

#: app/flatpak-builtins-repair.c:306
#, c-format
msgid "Error reinstalling %s: %s\n"
msgstr "Eraro dum reinstalo de %s: %s\n"

#: app/flatpak-builtins-repair.c:327
msgid "- Repair a flatpak installation"
msgstr "- Ripari instaladon de flatpak"

#: app/flatpak-builtins-repair.c:406
#, c-format
msgid "Removing non-deployed ref %s…\n"
msgstr "Forigante ne-deplojitan ref %s...\n"

#: app/flatpak-builtins-repair.c:411
#, c-format
msgid "Skipping non-deployed ref %s…\n"
msgstr "Preterpasi ne-deplojitan ref %s...\n"

#: app/flatpak-builtins-repair.c:429
#, c-format
msgid "[%d/%d] Verifying %s…\n"
msgstr "[%d/%d] Kontrolante %s…\n"

#: app/flatpak-builtins-repair.c:435
#, c-format
msgid "Dry run: "
msgstr "Seka kurado:"

#: app/flatpak-builtins-repair.c:440
#, c-format
msgid "Deleting ref %s due to missing objects\n"
msgstr "Forigo de ref %s pro mankantaj objektoj\n"

#: app/flatpak-builtins-repair.c:444
#, c-format
msgid "Deleting ref %s due to invalid objects\n"
msgstr "Forigo de ref %s pro nevalidaj objektoj\n"

#: app/flatpak-builtins-repair.c:448
#, c-format
msgid "Deleting ref %s due to %d\n"
msgstr "Forigo de ref %s pro %d\n"

#: app/flatpak-builtins-repair.c:464
#, c-format
msgid "Checking remotes...\n"
msgstr "Kontrolante telefakojn...\n"

#: app/flatpak-builtins-repair.c:482
#, c-format
msgid "Remote %s for ref %s is missing\n"
msgstr "Fora %s por ref %s mankas\n"

#: app/flatpak-builtins-repair.c:484
#, c-format
msgid "Remote %s for ref %s is disabled\n"
msgstr "Fora %s por ref %s estas malŝaltita\n"

#: app/flatpak-builtins-repair.c:490
#, c-format
msgid "Pruning objects\n"
msgstr "Pritondi objektojn\n"

#: app/flatpak-builtins-repair.c:498
#, c-format
msgid "Erasing .removed\n"
msgstr "Forigo .forigita\n"

#: app/flatpak-builtins-repair.c:524
#, c-format
msgid "Reinstalling refs\n"
msgstr "Reinstalante refs\n"

#: app/flatpak-builtins-repair.c:526
#, c-format
msgid "Reinstalling removed refs\n"
msgstr "Reinstalante forigitajn referencojn\n"

#: app/flatpak-builtins-repair.c:551
#, c-format
msgid "While removing appstream for %s: "
msgstr "Dum forigo de appstream por %s:"

#: app/flatpak-builtins-repair.c:558
#, c-format
msgid "While deploying appstream for %s: "
msgstr "Dum deplojado de appstream por %s:"

#: app/flatpak-builtins-repo.c:106
#, c-format
msgid "Repo mode: %s\n"
msgstr "Repo-reĝimo: %s\n"

#: app/flatpak-builtins-repo.c:113
#, c-format
msgid "Indexed summaries: %s\n"
msgstr "Indeksitaj resumoj: %s\n"

#: app/flatpak-builtins-repo.c:113 app/flatpak-builtins-repo.c:139
#: app/flatpak-builtins-repo.c:172
msgid "true"
msgstr "vera"

#: app/flatpak-builtins-repo.c:113 app/flatpak-builtins-repo.c:139
#: app/flatpak-builtins-repo.c:172
msgid "false"
msgstr "malvera"

#: app/flatpak-builtins-repo.c:121
#, c-format
msgid "Subsummaries: "
msgstr "Subresumoj:"

#: app/flatpak-builtins-repo.c:136
#, c-format
msgid "Cache version: %d\n"
msgstr "Cache versio: %d\n"

#: app/flatpak-builtins-repo.c:139
#, c-format
msgid "Indexed deltas: %s\n"
msgstr "Indeksitaj deltoj: %s\n"

#: app/flatpak-builtins-repo.c:142
#, c-format
msgid "Title: %s\n"
msgstr "Titolo: %s\n"

#: app/flatpak-builtins-repo.c:145
#, c-format
msgid "Comment: %s\n"
msgstr "Komento: %s\n"

#: app/flatpak-builtins-repo.c:148
#, c-format
msgid "Description: %s\n"
msgstr "Priskribo: %s\n"

#: app/flatpak-builtins-repo.c:151
#, c-format
msgid "Homepage: %s\n"
msgstr "Hejmpaĝo: %s\n"

#: app/flatpak-builtins-repo.c:154
#, c-format
msgid "Icon: %s\n"
msgstr "Ikono: %s\n"

#: app/flatpak-builtins-repo.c:157
#, c-format
msgid "Collection ID: %s\n"
msgstr "Kolekto ID: %s\n"

#: app/flatpak-builtins-repo.c:160
#, c-format
msgid "Default branch: %s\n"
msgstr "Defaŭlta branĉo: %s\n"

#: app/flatpak-builtins-repo.c:163
#, c-format
msgid "Redirect URL: %s\n"
msgstr "Redirekta URL: %s\n"

#: app/flatpak-builtins-repo.c:166
#, c-format
msgid "Deploy collection ID: %s\n"
msgstr "Deploji kolekto ID: %s\n"

#: app/flatpak-builtins-repo.c:169
#, c-format
msgid "Authenticator name: %s\n"
msgstr "Aŭtentikigilnomo: %s\n"

#: app/flatpak-builtins-repo.c:172
#, c-format
msgid "Authenticator install: %s\n"
msgstr "Aŭtentikigil-instalado: %s\n"

#: app/flatpak-builtins-repo.c:180
#, c-format
msgid "GPG key hash: %s\n"
msgstr "GPG-ŝlosilo hash: %s\n"

#: app/flatpak-builtins-repo.c:184
#, c-format
msgid "%zd summary branches\n"
msgstr "%zd branĉoj\n"

#: app/flatpak-builtins-repo.c:336
msgid "Installed"
msgstr "Instalita"

#. Translators: Download is used here as a noun
#: app/flatpak-builtins-repo.c:338 app/flatpak-cli-transaction.c:1462
msgid "Download"
msgstr "Elŝutu"

#: app/flatpak-builtins-repo.c:339
msgid "Subsets"
msgstr "Subaroj"

#: app/flatpak-builtins-repo.c:393
msgid "Digest"
msgstr "Digesto"

#: app/flatpak-builtins-repo.c:394
msgid "History length"
msgstr "Historio:"

#: app/flatpak-builtins-repo.c:711
msgid "Print general information about the repository"
msgstr "Presi ĝeneralajn informojn pri la deponejo"

#: app/flatpak-builtins-repo.c:712
msgid "List the branches in the repository"
msgstr "Listigi la branĉojn en la deponejo"

#: app/flatpak-builtins-repo.c:713
msgid "Print metadata for a branch"
msgstr "Presi metadatenojn por branĉo"

#: app/flatpak-builtins-repo.c:714
msgid "Show commits for a branch"
msgstr "Montri komitojn por branĉo"

#: app/flatpak-builtins-repo.c:715
msgid "Print information about the repo subsets"
msgstr "Presi ĝeneralajn informojn pri la deponejo"

#: app/flatpak-builtins-repo.c:716
msgid "Limit information to subsets with this prefix"
msgstr "Limigi informojn al subaroj kun ĉi tiu prefikso"

#: app/flatpak-builtins-repo.c:732
msgid "LOCATION - Repository maintenance"
msgstr "LOKO - Deponejo prizorgado"

#: app/flatpak-builtins-run.c:159
msgid "Command to run"
msgstr "Ordono kuri"

#: app/flatpak-builtins-run.c:160
msgid "Directory to run the command in"
msgstr "Dosierujo por ruli la komandon en"

#: app/flatpak-builtins-run.c:161
msgid "Branch to use"
msgstr "Branĉo por uzi"

#: app/flatpak-builtins-run.c:162
msgid "Use development runtime"
msgstr "Uzi evoluan rultempon"

#: app/flatpak-builtins-run.c:163
msgid "Runtime to use"
msgstr "Rultempo por uzi"

#: app/flatpak-builtins-run.c:164
msgid "Runtime version to use"
msgstr "Rultempa versio por uzi"

#: app/flatpak-builtins-run.c:167
msgid "Log accessibility bus calls"
msgstr "Ensaluti alireblajn busvokojn"

#: app/flatpak-builtins-run.c:168
msgid "Don't proxy accessibility bus calls"
msgstr "Ne prokuri alireblajn busalvokojn"

#: app/flatpak-builtins-run.c:169
msgid "Proxy accessibility bus calls (default except when sandboxed)"
msgstr "Prokuraj alireblaj busvokoj (defaŭlte krom kiam sablokesto)"

#: app/flatpak-builtins-run.c:170
msgid "Don't proxy session bus calls"
msgstr "Ne prokuri alireblajn busalvokojn"

#: app/flatpak-builtins-run.c:171
msgid "Proxy session bus calls (default except when sandboxed)"
msgstr "Prokura-sesiobusvokoj (defaŭlte krom kiam sablokesto)"

#: app/flatpak-builtins-run.c:172
msgid "Don't start portals"
msgstr "Ne lanĉi portalojn"

#: app/flatpak-builtins-run.c:173
msgid "Enable file forwarding"
msgstr "Ebligi dosiersendadon"

#: app/flatpak-builtins-run.c:174
msgid "Run specified commit"
msgstr "Ruli specifitan kommit"

#: app/flatpak-builtins-run.c:175
msgid "Use specified runtime commit"
msgstr "Uzi specifitan rultempokomiton"

#: app/flatpak-builtins-run.c:176
msgid "Run completely sandboxed"
msgstr "Kuri tute sandboxed"

#: app/flatpak-builtins-run.c:178
msgid "Use PID as parent pid for sharing namespaces"
msgstr "Uzi PID kiel gepatran pid por kunhavi nomspacojn"

#: app/flatpak-builtins-run.c:179
msgid "Make processes visible in parent namespace"
msgstr "Fari procezojn videblaj en gepatra nomspaco"

#: app/flatpak-builtins-run.c:180
msgid "Share process ID namespace with parent"
msgstr "Kunhavigi procezan ID-nomspacon kun gepatro"

#: app/flatpak-builtins-run.c:181
msgid "Write the instance ID to the given file descriptor"
msgstr "Skribi la instantan ID al la donita dosierpriskribilo"

#: app/flatpak-builtins-run.c:182
msgid "Use PATH instead of the app's /app"
msgstr "Uzi PATH anstataŭ la /app de la programo"

#: app/flatpak-builtins-run.c:183
#, fuzzy
msgid "Use FD instead of the app's /app"
msgstr "Uzi PATH anstataŭ la /app de la programo"

#: app/flatpak-builtins-run.c:183 app/flatpak-builtins-run.c:185
#: app/flatpak-builtins-run.c:187 app/flatpak-builtins-run.c:188
#: common/flatpak-context.c:2672
msgid "FD"
msgstr "FD"

#: app/flatpak-builtins-run.c:184
msgid "Use PATH instead of the runtime's /usr"
msgstr "Uzi PATH anstataŭ la rultempo /usr"

#: app/flatpak-builtins-run.c:185
#, fuzzy
msgid "Use FD instead of the runtime's /usr"
msgstr "Uzi PATH anstataŭ la rultempo /usr"

#: app/flatpak-builtins-run.c:186
msgid "Clear all outside environment variables"
msgstr "Agordi mediovariablon"

#: app/flatpak-builtins-run.c:187
msgid ""
"Bind mount the file or directory referred to by FD to its canonicalized path"
msgstr ""

#: app/flatpak-builtins-run.c:188
msgid ""
"Bind mount the file or directory referred to by FD read-only to its "
"canonicalized path"
msgstr ""

#: app/flatpak-builtins-run.c:219
msgid "APP [ARGUMENT…] - Run an app"
msgstr "APP [ARGUMENTO...] - Ruli apon"

#: app/flatpak-builtins-run.c:370
#, c-format
msgid "runtime/%s/%s/%s not installed"
msgstr "rultempo/%s/%s/%s ne instalita"

#: app/flatpak-builtins-run.c:419
msgid "app-fd and app-path cannot both be used"
msgstr ""

#: app/flatpak-builtins-run.c:449
msgid "usr-fd and usr-path cannot both be used"
msgstr ""

#: app/flatpak-builtins-search.c:37
msgid "Arch to search for"
msgstr "Arko por serĉi"

#: app/flatpak-builtins-search.c:49
msgid "Remotes"
msgstr "Remotoj"

#: app/flatpak-builtins-search.c:49
msgid "Show the remotes"
msgstr "Montri la telerojn"

#: app/flatpak-builtins-search.c:244
msgid "TEXT - Search remote apps/runtimes for text"
msgstr "TEKSTO - Serĉi forajn programojn/rultempojn por teksto"

#: app/flatpak-builtins-search.c:255
msgid "TEXT must be specified"
msgstr "TEKSTO devas esti specifita"

#: app/flatpak-builtins-search.c:338
msgid "No matches found"
msgstr "Neniuj kongruoj trovitaj"

#: app/flatpak-builtins-uninstall.c:54
msgid "Arch to uninstall"
msgstr "Arch por malinstali"

#: app/flatpak-builtins-uninstall.c:55
msgid "Keep ref in local repository"
msgstr "Konservi ref en loka deponejo"

#: app/flatpak-builtins-uninstall.c:56
msgid "Don't uninstall related refs"
msgstr "Ne malinstali rilatajn referencojn"

#: app/flatpak-builtins-uninstall.c:57
msgid "Remove files even if running"
msgstr "Forigi dosierojn eĉ se funkcias"

#: app/flatpak-builtins-uninstall.c:60
msgid "Uninstall all"
msgstr "Malinstali ĉion"

#: app/flatpak-builtins-uninstall.c:61
msgid "Uninstall unused"
msgstr "Malinstali neuzatan"

#: app/flatpak-builtins-uninstall.c:62
msgid "Delete app data"
msgstr "Forigi aplikajn datumojn"

#: app/flatpak-builtins-uninstall.c:141
#, c-format
msgid "Delete data for %s?"
msgstr "Ĉu forigi datumojn por %s?"

#: app/flatpak-builtins-uninstall.c:220
#, c-format
msgid "Info: applications using the extension %s%s%s branch %s%s%s:\n"
msgstr "Informoj: aplikaĵoj uzante la etendon %s%s%s branĉo %s%s%s:\n"

#: app/flatpak-builtins-uninstall.c:223
#, c-format
msgid "Info: applications using the runtime %s%s%s branch %s%s%s:\n"
msgstr "Informo: aplikaĵoj uzantaj la rultemon %s%s%s branĉon %s%s%s:\n"

#: app/flatpak-builtins-uninstall.c:238
msgid "Really remove?"
msgstr "Malproksima"

#: app/flatpak-builtins-uninstall.c:255
msgid "[REF…] - Uninstall applications or runtimes"
msgstr "[REF...] - Ĝisdatigi aplikaĵojn aŭ rultempojn"

#: app/flatpak-builtins-uninstall.c:264
msgid "Must specify at least one REF, --unused, --all or --delete-data"
msgstr "Devas specifi almenaŭ unu REF, --unused, --all aŭ --delete-data"

#: app/flatpak-builtins-uninstall.c:267
msgid "Must not specify REFs when using --all"
msgstr "Ne devas specifi REFojn kiam oni uzas --all"

#: app/flatpak-builtins-uninstall.c:270
msgid "Must not specify REFs when using --unused"
msgstr "Ne devas specifi REFojn kiam oni uzas --unused"

#: app/flatpak-builtins-uninstall.c:336
#, c-format
msgid ""
"\n"
"These runtimes in installation '%s' are pinned and won't be removed; see "
"flatpak-pin(1):\n"
msgstr ""
"\n"
"Ĉi tiuj rultempoj en instalo '%s' estas alpinglitaj kaj ne estos forigitaj; "
"vidi flatpak-pin(1):\n"

#: app/flatpak-builtins-uninstall.c:370
#, c-format
msgid "Nothing unused to uninstall\n"
msgstr "Nenio neuzata por malinstali\n"

#: app/flatpak-builtins-uninstall.c:444
#, c-format
msgid "No installed refs found for ‘%s’"
msgstr "Similaj instalitaj referencoj trovitaj por '%s':"

#: app/flatpak-builtins-uninstall.c:447
#, c-format
msgid " with arch ‘%s’"
msgstr "kun arko ‘%s’"

#: app/flatpak-builtins-uninstall.c:449
#, c-format
msgid " with branch ‘%s’"
msgstr "kun branĉo ‘%s’"

#: app/flatpak-builtins-uninstall.c:456
#, c-format
msgid "Warning: %s is not installed\n"
msgstr "Averto: %s ne estas instalita\n"

#: app/flatpak-builtins-uninstall.c:490
#, c-format
msgid "None of the specified refs are installed"
msgstr "Neniu el la specifitaj referencoj estas instalita"

#: app/flatpak-builtins-uninstall.c:599
#, c-format
msgid "No app data to delete\n"
msgstr "Neniuj aplikaj datumoj por forigi\n"

#: app/flatpak-builtins-update.c:56
msgid "Arch to update for"
msgstr "Arko por ĝisdatigi"

#: app/flatpak-builtins-update.c:57
msgid "Commit to deploy"
msgstr "Engaĝiĝi por deploji"

#: app/flatpak-builtins-update.c:58
msgid "Remove old files even if running"
msgstr "Forigi malnovajn dosierojn eĉ se funkcias"

#: app/flatpak-builtins-update.c:59
msgid "Don't pull, only update from local cache"
msgstr "Ne tiru, nur ĝisdatigi el loka kaŝmemoro"

#: app/flatpak-builtins-update.c:61
msgid "Don't update related refs"
msgstr "Ne ĝisdatigi rilatajn referencojn"

#: app/flatpak-builtins-update.c:66
msgid "Update appstream for remote"
msgstr "Ĝisdatigi appstream por fora"

#: app/flatpak-builtins-update.c:67
msgid "Only update this subpath"
msgstr "Ĝisdatigi nur ĉi tiun subvojon"

#: app/flatpak-builtins-update.c:90
msgid "[REF…] - Update applications or runtimes"
msgstr "[REF...] - Ĝisdatigi aplikaĵojn aŭ rultempojn"

#: app/flatpak-builtins-update.c:121
msgid "With --commit, only one REF may be specified"
msgstr "Almenaŭ unu REF devas esti specifita"

#: app/flatpak-builtins-update.c:162
#, c-format
msgid "Looking for updates…\n"
msgstr "Serĉante ĝisdatigojn...\n"

#: app/flatpak-builtins-update.c:215
#, c-format
msgid "Unable to update %s: %s\n"
msgstr "Ne eblas ĝisdatigi %s: %s\n"

#: app/flatpak-builtins-update.c:274
#, c-format
msgid "Nothing to update.\n"
msgstr "Nenio farenda.\n"

#: app/flatpak-builtins-utils.c:337
#, c-format
msgid ""
"Remote ‘%s’ found in multiple installations, unable to proceed in non-"
"interactive mode"
msgstr ""
"Fora ‘%s’ trovita en pluraj instalaĵoj, ne eblas daŭrigi en neinteraga reĝimo"

#: app/flatpak-builtins-utils.c:346
#, c-format
msgid "Remote ‘%s’ found in multiple installations:"
msgstr "Fora '%s' trovita en pluraj instalaĵoj:"

#: app/flatpak-builtins-utils.c:347 app/flatpak-builtins-utils.c:442
#: app/flatpak-builtins-utils.c:538 app/flatpak-builtins-utils.c:540
#: app/flatpak-builtins-utils.c:598
msgid "Which do you want to use (0 to abort)?"
msgstr "Kiun vi volas uzi (0 por ĉesigi)?"

#: app/flatpak-builtins-utils.c:349
#, c-format
msgid "No remote chosen to resolve ‘%s’ which exists in multiple installations"
msgstr ""
"Neniu teleilo elektita por solvi '%s' kiu ekzistas en pluraj instalaĵoj"

#: app/flatpak-builtins-utils.c:358
#, c-format
msgid ""
"Remote \"%s\" not found\n"
"Hint: Use flatpak remote-add to add a remote"
msgstr ""
"Fora \"%s\" ne trovita\n"
"Konsilo: Uzi flatpak remote-add por aldoni telecomandilon"

#: app/flatpak-builtins-utils.c:364
#, c-format
msgid "Remote \"%s\" not found in the %s installation"
msgstr "Fora \"%s\" ne trovita en la instalaĵo %s"

#: app/flatpak-builtins-utils.c:404
#, c-format
msgid "Multiple refs match ‘%s’, unable to proceed in non-interactive mode"
msgstr ""
"Multoblaj referencoj kongruas kun '%s', ne povas daŭrigi en ne-interaga "
"reĝimo"

#. default to yes on Enter
#: app/flatpak-builtins-utils.c:430
#, c-format
msgid ""
"Found ref ‘%s’ in remote ‘%s’ (%s).\n"
"Use this ref?"
msgstr ""
"Trovita ref '%s' en fora '%s' (%s).\n"
"Ĉu uzi ĉi tiun refon?"

#: app/flatpak-builtins-utils.c:434 app/flatpak-builtins-utils.c:444
#: app/flatpak-builtins-utils.c:522 app/flatpak-builtins-utils.c:543
#, c-format
msgid "No ref chosen to resolve matches for ‘%s’"
msgstr "Neniu referenco elektita por solvi matĉojn por '%s'"

#: app/flatpak-builtins-utils.c:440
#, c-format
msgid "Similar refs found for ‘%s’ in remote ‘%s’ (%s):"
msgstr "Similaj referencoj trovitaj por '%s' en fora '%s' (%s):"

#: app/flatpak-builtins-utils.c:488
#, c-format
msgid ""
"Multiple installed refs match ‘%s’, unable to proceed in non-interactive mode"
msgstr ""
"Multoblaj instalitaj referencoj kongruas kun '%s', ne povas daŭrigi en ne-"
"interaga reĝimo"

#. default to yes on Enter
#: app/flatpak-builtins-utils.c:518
#, c-format
msgid "Found installed ref ‘%s’ (%s). Is this correct?"
msgstr "Trovita instalita ref '%s' (%s). Ĉu ĉi tio estas ĝusta?"

#: app/flatpak-builtins-utils.c:534
#, c-format
msgid "All of the above"
msgstr "Ĉio el la supre"

#: app/flatpak-builtins-utils.c:535
#, c-format
msgid "Similar installed refs found for ‘%s’:"
msgstr "Similaj instalitaj referencoj trovitaj por '%s':"

#: app/flatpak-builtins-utils.c:579
#, c-format
msgid ""
"Multiple remotes have refs matching ‘%s’, unable to proceed in non-"
"interactive mode"
msgstr ""
"Multoblaj telefroloj havas referencojn kongruajn kun '%s', nekapablaj "
"daŭrigi en ne-interaga reĝimo"

#: app/flatpak-builtins-utils.c:597
#, c-format
msgid "Remotes found with refs similar to ‘%s’:"
msgstr "Telefonoj trovitaj kun referencoj similaj al '%s':"

#: app/flatpak-builtins-utils.c:600
#, c-format
msgid "No remote chosen to resolve matches for ‘%s’"
msgstr "Neniu teleilo elektita por solvi kongruojn por '%s'"

#: app/flatpak-builtins-utils.c:696 app/flatpak-builtins-utils.c:699
#, c-format
msgid "Updating appstream data for user remote %s"
msgstr "Ĝisdatigante aplikaĵfluajn datumojn por fora uzanto %s"

#: app/flatpak-builtins-utils.c:706 app/flatpak-builtins-utils.c:709
#, c-format
msgid "Updating appstream data for remote %s"
msgstr "Ĝisdatigante datenojn de aplikfluo por fora %s"

#: app/flatpak-builtins-utils.c:717 app/flatpak-builtins-utils.c:719
msgid "Error updating"
msgstr "Eraro dum ĝisdatigo"

#: app/flatpak-builtins-utils.c:755
#, c-format
msgid "Remote \"%s\" not found"
msgstr "Fora \"%s\" ne trovita"

#: app/flatpak-builtins-utils.c:796
#, c-format
msgid "Ambiguous suffix: '%s'."
msgstr "Ambigua sufikso: '%s'."

#. Translators: don't translate the values
#: app/flatpak-builtins-utils.c:798 app/flatpak-builtins-utils.c:813
msgid "Possible values are :s[tart], :m[iddle], :e[nd] or :f[ull]"
msgstr "Eblaj valoroj estas :s[tart], :m[iddle], :e[nd] aŭ :f[ull]"

#: app/flatpak-builtins-utils.c:811
#, c-format
msgid "Invalid suffix: '%s'."
msgstr "Nevalida sufikso: '%s'."

#: app/flatpak-builtins-utils.c:846
#, c-format
msgid "Ambiguous column: %s"
msgstr "Ambigua kolumno: %s"

#: app/flatpak-builtins-utils.c:859
#, c-format
msgid "Unknown column: %s"
msgstr "Nekonata kolumno: %s"

#: app/flatpak-builtins-utils.c:917
msgid "Available columns:\n"
msgstr "Disponeblaj kolumnoj:\n"

#: app/flatpak-builtins-utils.c:927
msgid "Show all columns"
msgstr "Montri ĉiujn kolumnojn"

#: app/flatpak-builtins-utils.c:928
msgid "Show available columns"
msgstr "Montri disponeblajn kolumnojn"

#: app/flatpak-builtins-utils.c:931
msgid "Append :s[tart], :m[iddle], :e[nd] or :f[ull] to change ellipsization"
msgstr "Aldoni :s[tart], :m[iddle], :e[nd] aŭ :f[ull] por ŝanĝi elipson"

#: app/flatpak-builtins-utils.c:1483
#, c-format
msgid "Unknown scheme in sideload location %s"
msgstr "Nekonata skemo en flankŝarĝa loko %s"

#: app/flatpak-cli-transaction.c:96 app/flatpak-cli-transaction.c:102
#, c-format
msgid "Required runtime for %s (%s) found in remote %s\n"
msgstr "Bezonata rultempo por %s (%s) trovita en fora %s\n"

#: app/flatpak-cli-transaction.c:104
msgid "Do you want to install it?"
msgstr "Ĉu vi volas instali ĝin?"

#: app/flatpak-cli-transaction.c:110
#, c-format
msgid "Required runtime for %s (%s) found in remotes:"
msgstr "Bezonata rultempo por Z%s (%s) trovita en teleremotoj:"

#: app/flatpak-cli-transaction.c:112
msgid "Which do you want to install (0 to abort)?"
msgstr "Kiun vi volas instali (0 por ĉesigi)?"

#: app/flatpak-cli-transaction.c:132
#, c-format
msgid "Configuring %s as new remote '%s'\n"
msgstr "Agordante %s kiel nova fora '%s'\n"

#. default to yes on Enter
#: app/flatpak-cli-transaction.c:139
#, c-format
msgid ""
"The remote '%s', referred to by '%s' at location %s contains additional "
"applications.\n"
"Should the remote be kept for future installations?"
msgstr ""
"La fora '%s', referita per '%s' ĉe loko %s enhavas pliajn aplikaĵojn.\n"
"Ĉu la telecomando estu konservita por estontaj instalaĵoj?"

#. default to yes on Enter
#: app/flatpak-cli-transaction.c:147
#, c-format
msgid ""
"The application %s depends on runtimes from:\n"
"  %s\n"
"Configure this as new remote '%s'"
msgstr ""
"La aplikaĵo %s dependas de rultempoj de:\n"
"%s\n"
"Agordi ĉi tion kiel novan fora '%s'"

#. Formatted size/remaining time in seconds
#: app/flatpak-cli-transaction.c:321
#, c-format
msgid "%s/s%s%s"
msgstr "%s/s%s%s"

#. Download progress percentage, use the appropriate
#. percent format for your language
#: app/flatpak-cli-transaction.c:359
#, c-format
msgid "%3d%%"
msgstr "%3d%%"

#: app/flatpak-cli-transaction.c:414
msgid "Installing…"
msgstr "Instalante…"

#: app/flatpak-cli-transaction.c:416
#, c-format
msgid "Installing %d/%d…"
msgstr "Instalante %d/%d..."

#: app/flatpak-cli-transaction.c:421
msgid "Updating…"
msgstr "Ĝisdatigante…"

#: app/flatpak-cli-transaction.c:423
#, c-format
msgid "Updating %d/%d…"
msgstr "Ĝisdatigante %d/%d..."

#: app/flatpak-cli-transaction.c:428
msgid "Uninstalling…"
msgstr "Malinstalante…"

#: app/flatpak-cli-transaction.c:430
#, c-format
msgid "Uninstalling %d/%d…"
msgstr "Malinstalante %d/%d..."

#: app/flatpak-cli-transaction.c:496 app/flatpak-quiet-transaction.c:161
#, c-format
msgid "Info: %s was skipped"
msgstr "Informoj: %s estis preterlasita"

#: app/flatpak-cli-transaction.c:519
#, c-format
msgid "Warning: %s%s%s already installed"
msgstr "Averto: %s%s%s jam instalita"

#: app/flatpak-cli-transaction.c:522
#, c-format
msgid "Error: %s%s%s already installed"
msgstr "Eraro: %s%s%s jam instalita"

#: app/flatpak-cli-transaction.c:528
#, c-format
msgid "Warning: %s%s%s not installed"
msgstr "Averto: %s%s%s ne instalita"

#: app/flatpak-cli-transaction.c:531
#, c-format
msgid "Error: %s%s%s not installed"
msgstr "%s/%s/%s ne instalita"

#: app/flatpak-cli-transaction.c:537
#, c-format
msgid "Warning: %s%s%s needs a later flatpak version"
msgstr "Averto: %s%s%s bezonas pli postan flatpak-version"

#: app/flatpak-cli-transaction.c:540
#, c-format
msgid "Error: %s%s%s needs a later flatpak version"
msgstr "Eraro: %s%s%s bezonas pli postan flatpak-version"

#: app/flatpak-cli-transaction.c:546
msgid "Warning: Not enough disk space to complete this operation"
msgstr "Ne sufiĉa diskospaco por plenumi ĉi tiun operacion"

#: app/flatpak-cli-transaction.c:548
msgid "Error: Not enough disk space to complete this operation"
msgstr "Ne sufiĉa diskospaco por plenumi ĉi tiun operacion"

#: app/flatpak-cli-transaction.c:553
#, c-format
msgid "Warning: %s"
msgstr "Averto: %s"

#: app/flatpak-cli-transaction.c:555
#, c-format
msgid "Error: %s"
msgstr "Eraro: %s"

#: app/flatpak-cli-transaction.c:570
#, c-format
msgid "Failed to install %s%s%s: "
msgstr "Malsukcesis instali %s%s%s: "

#: app/flatpak-cli-transaction.c:577
#, c-format
msgid "Failed to update %s%s%s: "
msgstr "Malsukcesis ĝisdatigi %s%s%s: "

#: app/flatpak-cli-transaction.c:584
#, c-format
msgid "Failed to install bundle %s%s%s: "
msgstr "Malsukcesis instali pakon %s%s%s: "

#: app/flatpak-cli-transaction.c:591
#, c-format
msgid "Failed to uninstall %s%s%s: "
msgstr "Malsukcesis malinstali %s%s%s: "

#: app/flatpak-cli-transaction.c:642
#, c-format
msgid "Authentication required for remote '%s'\n"
msgstr "Aŭtentikigo necesa por fora '%s'\n"

#: app/flatpak-cli-transaction.c:643
msgid "Open browser?"
msgstr "Ĉu malfermi retumilon?"

#: app/flatpak-cli-transaction.c:699
#, c-format
msgid "Login required remote %s (realm %s)\n"
msgstr "Ensaluti bezonata fora %s (sfero %s)\n"

#: app/flatpak-cli-transaction.c:704
msgid "Password"
msgstr "Pasvorto"

#. Only runtimes can be pinned
#: app/flatpak-cli-transaction.c:759
#, c-format
msgid ""
"\n"
"Info: (pinned) runtime %s%s%s branch %s%s%s is end-of-life, in favor of "
"%s%s%s branch %s%s%s\n"
msgstr ""
"\n"
"Informo: (pinita) rultempa %s%s%s branĉo %s%s%s estas fino de vivo, "
"anstataŭita de %s%s%s branĉo %s%s%s\n"

#: app/flatpak-cli-transaction.c:765
#, c-format
msgid ""
"\n"
"Info: runtime %s%s%s branch %s%s%s is end-of-life, in favor of %s%s%s branch "
"%s%s%s\n"
msgstr ""
"\n"
"Informo: rultempa %s%s%s branĉo %s%s%s estas fino de vivo, anstataŭita de "
"%s%s%s branĉo %s%s%s\n"

#: app/flatpak-cli-transaction.c:768
#, c-format
msgid ""
"\n"
"Info: app %s%s%s branch %s%s%s is end-of-life, in favor of %s%s%s branch "
"%s%s%s\n"
msgstr ""
"\n"
"Informo: apliko %s%s%s branĉo %s%s%s estas fino de vivo, anstataŭita de "
"%s%s%s branĉo %s%s%s\n"

#. Only runtimes can be pinned
#: app/flatpak-cli-transaction.c:780
#, c-format
msgid ""
"\n"
"Info: (pinned) runtime %s%s%s branch %s%s%s is end-of-life, with reason:\n"
msgstr ""
"\n"
"Informo: (pinita) rultempa %s%s%s branĉo %s%s%s estas fino de vivo, kun "
"kialo:\n"

#: app/flatpak-cli-transaction.c:786
#, c-format
msgid ""
"\n"
"Info: runtime %s%s%s branch %s%s%s is end-of-life, with reason:\n"
msgstr ""
"\n"
"Informo: rultempa %s%s%s branĉo %s%s%s estas fino de vivo, kun kialo:\n"

#: app/flatpak-cli-transaction.c:789
#, c-format
msgid ""
"\n"
"Info: app %s%s%s branch %s%s%s is end-of-life, with reason:\n"
msgstr ""
"\n"
"Informo: apliko %s%s%s branĉo %s%s%s estas fino de vivo, kun kialo:\n"

#: app/flatpak-cli-transaction.c:963
#, c-format
msgid "Info: applications using this extension:\n"
msgstr "Informo: aplikaĵoj uzantaj ĉi tiun etendon:\n"

#: app/flatpak-cli-transaction.c:965
#, c-format
msgid "Info: applications using this runtime:\n"
msgstr "Informo: aplikaĵoj uzantaj ĉi tiun rultemon:\n"

#: app/flatpak-cli-transaction.c:984
msgid "Replace?"
msgstr "Anstataŭigi?"

#: app/flatpak-cli-transaction.c:987 app/flatpak-quiet-transaction.c:247
#, c-format
msgid "Updating to rebased version\n"
msgstr "Ĝisdatigo al rebazita versio\n"

#: app/flatpak-cli-transaction.c:1011
#, c-format
msgid "Failed to rebase %s to %s: "
msgstr "Malsukcesis rebazi %s al %s:"

#: app/flatpak-cli-transaction.c:1277
#, c-format
msgid "New %s%s%s permissions:"
msgstr "Novaj %s%s%s-permesoj:"

#: app/flatpak-cli-transaction.c:1279
#, c-format
msgid "%s%s%s permissions:"
msgstr "%s%s%s-permesoj:"

#: app/flatpak-cli-transaction.c:1343
msgid "Warning: "
msgstr "Averto:"

#. translators: This is short for operation, the title of a one-char column
#: app/flatpak-cli-transaction.c:1442
msgid "Op"
msgstr "Op"

#. Avoid resizing the download column too much,
#. * by making the title as long as typical content
#.
#: app/flatpak-cli-transaction.c:1458 app/flatpak-cli-transaction.c:1503
msgid "partial"
msgstr "parta"

#: app/flatpak-cli-transaction.c:1535
msgid "Proceed with these changes to the user installation?"
msgstr "Ĉu daŭrigi ĉi tiujn ŝanĝojn al la uzanta instalado?"

#: app/flatpak-cli-transaction.c:1537
msgid "Proceed with these changes to the system installation?"
msgstr "Ĉu daŭrigi ĉi tiujn ŝanĝojn al la sisteminstalado?"

#: app/flatpak-cli-transaction.c:1539
#, c-format
msgid "Proceed with these changes to the %s?"
msgstr "Ĉu daŭrigi ĉi tiujn ŝanĝojn al la %s?"

#: app/flatpak-cli-transaction.c:1711
msgid "Changes complete."
msgstr "Ŝanĝoj finiĝis."

#: app/flatpak-cli-transaction.c:1713
msgid "Uninstall complete."
msgstr "Malinstalo kompleta."

#: app/flatpak-cli-transaction.c:1715
msgid "Installation complete."
msgstr "Instalado kompleta."

#: app/flatpak-cli-transaction.c:1717
msgid "Updates complete."
msgstr "Ĝisdatigoj finiĝis."

#. For updates/!stop_on_first_error we already printed all errors so we make up
#. a different one.
#: app/flatpak-cli-transaction.c:1750
msgid "There were one or more errors"
msgstr "Estis unu aŭ pluraj eraroj"

#. translators: please keep the leading space
#: app/flatpak-main.c:76
msgid " Manage installed applications and runtimes"
msgstr "Administri instalitajn aplikojn kaj rultempojn"

#: app/flatpak-main.c:77
msgid "Install an application or runtime"
msgstr "Instali aplikaĵon aŭ rultempon"

#: app/flatpak-main.c:78
msgid "Update an installed application or runtime"
msgstr "Ĝisdatigi instalitan aplikaĵon aŭ rultempon"

#: app/flatpak-main.c:81
msgid "Uninstall an installed application or runtime"
msgstr "Malinstali instalitan aplikaĵon aŭ rultempon"

#: app/flatpak-main.c:84
msgid "Mask out updates and automatic installation"
msgstr "Maski ĝisdatigojn kaj aŭtomatan instaladon"

#: app/flatpak-main.c:85
msgid "Pin a runtime to prevent automatic removal"
msgstr "Alpingli rultempon por malhelpi aŭtomatan forigon"

#: app/flatpak-main.c:86
msgid "List installed apps and/or runtimes"
msgstr "Listigi instalitajn programojn kaj/aŭ rultempojn"

#: app/flatpak-main.c:87
msgid "Show info for installed app or runtime"
msgstr "Montri informojn por instalita aplikaĵo aŭ rultempo"

#: app/flatpak-main.c:88
msgid "Show history"
msgstr "Montri historion"

#: app/flatpak-main.c:89
msgid "Configure flatpak"
msgstr "Agordi flatpak"

#: app/flatpak-main.c:90
msgid "Repair flatpak installation"
msgstr "Ripari instaladon de flatpak"

#: app/flatpak-main.c:91
msgid "Put applications or runtimes onto removable media"
msgstr "Meti aplikojn aŭ rultempojn sur forpreneblajn rimedojn"

#: app/flatpak-main.c:92
msgid "Install flatpaks that are part of the operating system"
msgstr "Instali flatpakaĵojn kiuj estas parto de la operaciumo"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:95
msgid ""
"\n"
" Find applications and runtimes"
msgstr ""
"\n"
"Trovi aplikojn kaj rultempojn"

#: app/flatpak-main.c:96
msgid "Search for remote apps/runtimes"
msgstr "Serĉi forajn programojn/rultempojn"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:99
msgid ""
"\n"
" Manage running applications"
msgstr ""
"\n"
"Kuranta aplikojn"

#: app/flatpak-main.c:100
msgid "Run an application"
msgstr "Ruli aplikaĵon"

#: app/flatpak-main.c:101
msgid "Override permissions for an application"
msgstr "Anstataŭigi permesojn por aplikaĵo"

#: app/flatpak-main.c:102
msgid "Specify default version to run"
msgstr "Specifi defaŭltan version por ruliĝi"

#: app/flatpak-main.c:103
msgid "Enter the namespace of a running application"
msgstr "Enigi la nomspacon de funkcianta aplikaĵo"

#: app/flatpak-main.c:104
msgid "Enumerate running applications"
msgstr "Nombri kurantajn aplikojn"

#: app/flatpak-main.c:105
msgid "Stop a running application"
msgstr "Ĉesi ruliĝantan aplikaĵon"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:108
msgid ""
"\n"
" Manage file access"
msgstr ""
"\n"
"Administri dosiero-aliron"

#: app/flatpak-main.c:109
msgid "List exported files"
msgstr "Listo de eksportitaj dosieroj"

#: app/flatpak-main.c:110
msgid "Grant an application access to a specific file"
msgstr "Doni aplikan aliron al specifa dosiero"

#: app/flatpak-main.c:111
msgid "Revoke access to a specific file"
msgstr "Nuligi aliron al specifa dosiero"

#: app/flatpak-main.c:112
msgid "Show information about a specific file"
msgstr "Montri informojn pri specifa dosiero"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:116
msgid ""
"\n"
" Manage dynamic permissions"
msgstr ""
"\n"
"Administri dinamikajn permesojn"

#: app/flatpak-main.c:117
msgid "List permissions"
msgstr "Listo de permesoj"

#: app/flatpak-main.c:118
msgid "Remove item from permission store"
msgstr "Forigi objekton de permesa vendejo"

#: app/flatpak-main.c:120
msgid "Set permissions"
msgstr "Listo de permesoj"

#: app/flatpak-main.c:121
msgid "Show app permissions"
msgstr "Montri aplikajn permesojn"

#: app/flatpak-main.c:122
msgid "Reset app permissions"
msgstr "Restarigi aplikajn permesojn"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:125
msgid ""
"\n"
" Manage remote repositories"
msgstr ""
"\n"
"Administri forajn deponejojn"

#: app/flatpak-main.c:126
msgid "List all configured remotes"
msgstr "Listigi ĉiujn agorditajn teleremotojn"

#: app/flatpak-main.c:127
msgid "Add a new remote repository (by URL)"
msgstr "Aldoni novan foran deponejon (per URL)"

#: app/flatpak-main.c:128
msgid "Modify properties of a configured remote"
msgstr "Modifi ecojn de agordita fora"

#: app/flatpak-main.c:129
msgid "Delete a configured remote"
msgstr "Forigu agordita telecomando"

#: app/flatpak-main.c:131
msgid "List contents of a configured remote"
msgstr "Listigi enhavon de agordita fora"

#: app/flatpak-main.c:132
msgid "Show information about a remote app or runtime"
msgstr "Montri informojn pri fora aplikaĵo aŭ rultempo"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:135
msgid ""
"\n"
" Build applications"
msgstr ""
"\n"
"Konstrui aplikojn"

#: app/flatpak-main.c:136
msgid "Initialize a directory for building"
msgstr "Komenci dosierujon por konstrui"

#: app/flatpak-main.c:137
msgid "Run a build command inside the build dir"
msgstr "Ruli konstrukomandon ene de la konstrudirektoro"

#: app/flatpak-main.c:138
msgid "Finish a build dir for export"
msgstr "Fini konstrudirektoron por eksporto"

#: app/flatpak-main.c:139
msgid "Export a build dir to a repository"
msgstr "Elporti konstrudirektoron al deponejo"

#: app/flatpak-main.c:140
msgid "Create a bundle file from a ref in a local repository"
msgstr "Krei pakdosieron de ref en loka deponejo"

#: app/flatpak-main.c:141
msgid "Import a bundle file"
msgstr "Enporti pakdosieron"

#: app/flatpak-main.c:142
msgid "Sign an application or runtime"
msgstr "Subskribi aplikaĵon aŭ rultempon"

#: app/flatpak-main.c:143
msgid "Update the summary file in a repository"
msgstr "Ĝisdatigi la resuman dosieron en deponejo"

#: app/flatpak-main.c:144
msgid "Create new commit based on existing ref"
msgstr "Krei novan kommit surbaze de ekzistanta ref"

#: app/flatpak-main.c:145
msgid "Show information about a repo"
msgstr "Montri informojn pri repo"

#: app/flatpak-main.c:162
msgid "Show debug information, -vv for more detail"
msgstr "Montri sencimigan informon, -vv por pliaj detaloj"

#: app/flatpak-main.c:163
msgid "Show OSTree debug information"
msgstr "Montri OSTree-sencimigan informon"

#: app/flatpak-main.c:169
msgid "Print version information and exit"
msgstr "Presi versio-informojn kaj eliru"

#: app/flatpak-main.c:170
msgid "Print default arch and exit"
msgstr "Presi defaŭltan arkon kaj eliru"

#: app/flatpak-main.c:171
msgid "Print supported arches and exit"
msgstr "Presi subtenatajn arkojn kaj eliron"

#: app/flatpak-main.c:172
msgid "Print active gl drivers and exit"
msgstr "Presi aktivajn gl-ŝoforojn kaj eliru"

#: app/flatpak-main.c:173
msgid "Print paths for system installations and exit"
msgstr "Presi vojojn por sistemaj instalaĵoj kaj eliro"

#: app/flatpak-main.c:174
msgid "Print the updated environment needed to run flatpaks"
msgstr "Presi la ĝisdatigitan medion necesan por ruli flatpakojn"

#: app/flatpak-main.c:175
msgid "Only include the system installation with --print-updated-env"
msgstr "Nur inkluzivi la sisteminstaladon per --print-updated-env"

#: app/flatpak-main.c:180
msgid "Work on the user installation"
msgstr "Labori pri la uzanta instalado"

#: app/flatpak-main.c:181
msgid "Work on the system-wide installation (default)"
msgstr "Labori pri la tutsistema instalado (defaŭlte)"

#: app/flatpak-main.c:182
msgid "Work on a non-default system-wide installation"
msgstr "Labori pri ne-defaŭlta tutsistema instalaĵo"

#: app/flatpak-main.c:212
msgid "Builtin Commands:"
msgstr "Enkonstruitaj Komandoj:"

#: app/flatpak-main.c:298
#, c-format
msgid ""
"Note that the directories %s are not in the search path set by the "
"XDG_DATA_DIRS environment variable, so applications installed by Flatpak may "
"not appear on your desktop until the session is restarted."
msgstr ""
"Notu, ke la dosierujoj %s ne estas en la serĉvojo agordita de la "
"mediovariablo XDG_DATA_DIRS, do aplikaĵoj instalitaj de Flatpak eble ne "
"aperos sur via labortablo ĝis la sesio estas rekomencita."

#: app/flatpak-main.c:312
#, c-format
msgid ""
"Note that the directory %s is not in the search path set by the "
"XDG_DATA_DIRS environment variable, so applications installed by Flatpak may "
"not appear on your desktop until the session is restarted."
msgstr ""
"Notu, ke la dosierujo %s ne estas en la serĉvojo agordita de la "
"mediovariablo XDG_DATA_DIRS, do aplikaĵoj instalitaj de Flatpak eble ne "
"aperos sur via labortablo ĝis la sesio estas rekomencita."

#: app/flatpak-main.c:381
msgid ""
"Refusing to operate under sudo with --user. Omit sudo to operate on the user "
"installation, or use a root shell to operate on the root user's installation."
msgstr ""
"Rifuzo funkcii sub sudo kun --user. Forlasi sudo por funkcii sur la "
"instalaĵo de la uzanto, aŭ uzi radikan ŝelon por funkcii sur la instalaĵo de "
"la radika uzanto."

#: app/flatpak-main.c:453
msgid ""
"Multiple installations specified for a command that works on one installation"
msgstr ""
"Multoblaj instalaĵoj specifitaj por komando kiu funkcias sur unu instalado"

#: app/flatpak-main.c:504 app/flatpak-main.c:697
#, c-format
msgid "See '%s --help'"
msgstr "Vidi '%s --help'"

#: app/flatpak-main.c:706
#, c-format
msgid "'%s' is not a flatpak command. Did you mean '%s%s'?"
msgstr "'%s' ne estas flatpak-komando. Ĉu vi volis diri '%s%s'?"

#: app/flatpak-main.c:709
#, c-format
msgid "'%s' is not a flatpak command"
msgstr "'%s' ne estas flatpak-komando"

#: app/flatpak-main.c:824
msgid "No command specified"
msgstr "Neniu komando specifita"

#: app/flatpak-main.c:980
msgid "error:"
msgstr "eraro:"

#: app/flatpak-quiet-transaction.c:77
#, c-format
msgid "Installing %s\n"
msgstr "Instalante %s\n"

#: app/flatpak-quiet-transaction.c:81
#, c-format
msgid "Updating %s\n"
msgstr "Ĝisdatigas %s\n"

#: app/flatpak-quiet-transaction.c:85
#, c-format
msgid "Uninstalling %s\n"
msgstr "Malinstalante %s\n"

#: app/flatpak-quiet-transaction.c:107
#, c-format
msgid "Warning: Failed to install %s: %s\n"
msgstr "Averto: Malsukcesis instali %s: %s\n"

#: app/flatpak-quiet-transaction.c:110
#, c-format
msgid "Error: Failed to install %s: %s\n"
msgstr "Eraro dum reinstalo de %s: %s\n"

#: app/flatpak-quiet-transaction.c:116
#, c-format
msgid "Warning: Failed to update %s: %s\n"
msgstr "Ne eblas ĝisdatigi %s: %s\n"

#: app/flatpak-quiet-transaction.c:119
#, c-format
msgid "Error: Failed to update %s: %s\n"
msgstr "Ne eblas ĝisdatigi %s: %s\n"

#: app/flatpak-quiet-transaction.c:125
#, c-format
msgid "Warning: Failed to install bundle %s: %s\n"
msgstr "Averto: Malsukcesis instali pakon %s: %s\n"

#: app/flatpak-quiet-transaction.c:128
#, c-format
msgid "Error: Failed to install bundle %s: %s\n"
msgstr "Eraro dum reinstalo de %s: %s\n"

#: app/flatpak-quiet-transaction.c:134
#, c-format
msgid "Warning: Failed to uninstall %s: %s\n"
msgstr "Averto: Malsukcesis malinstali %s: %s\n"

#: app/flatpak-quiet-transaction.c:137
#, c-format
msgid "Error: Failed to uninstall %s: %s\n"
msgstr "Eraro dum reinstalo de %s: %s\n"

#: app/flatpak-quiet-transaction.c:166 common/flatpak-dir.c:11475
#, c-format
msgid "%s already installed"
msgstr "%s jam instalita"

#: app/flatpak-quiet-transaction.c:168 common/flatpak-dir.c:3622
#: common/flatpak-dir.c:4321 common/flatpak-dir.c:16968
#: common/flatpak-dir.c:17258 common/flatpak-dir-utils.c:166
#: common/flatpak-dir-utils.c:259 common/flatpak-transaction.c:2736
#: common/flatpak-transaction.c:2791
#, c-format
msgid "%s not installed"
msgstr "%s ne instalita"

#: app/flatpak-quiet-transaction.c:170
#, c-format
msgid "%s needs a later flatpak version"
msgstr "%s bezonas pli postan flatpak-version"

#: app/flatpak-quiet-transaction.c:172
msgid "Not enough disk space to complete this operation"
msgstr "Ne sufiĉa diskospaco por plenumi ĉi tiun operacion"

#: app/flatpak-quiet-transaction.c:239
#, c-format
msgid "Info: %s is end-of-life, in favor of %s\n"
msgstr "Informoj: %s estas fino de vivo, prefere de %s\n"

#: app/flatpak-quiet-transaction.c:241
#, c-format
msgid "Info: %s is end-of-life, with reason: %s\n"
msgstr "Info: %s estas fino de vivo, kun kialo: %s\n"

#: app/flatpak-quiet-transaction.c:251
#, c-format
msgid "Failed to rebase %s to %s: %s\n"
msgstr "Malsukcesis rebazi %s al %s: %s\n"

#: common/flatpak-auth.c:58
#, c-format
msgid "No authenticator configured for remote `%s`"
msgstr "Neniu aŭtentikigilo agordita por fora `%s`"

#: common/flatpak-context.c:637 common/flatpak-context.c:649
#, c-format
msgid "Invalid permission syntax: %s"
msgstr "Nevalida dbus-nomo %s"

#: common/flatpak-context.c:1207
#, c-format
msgid "Unknown share type %s, valid types are: %s"
msgstr "Nekonata akcia tipo %s, validaj tipoj estas: %s"

#: common/flatpak-context.c:1228
#, c-format
msgid "Unknown policy type %s, valid types are: %s"
msgstr "Nekonata politika tipo %s, validaj tipoj estas: %s"

#: common/flatpak-context.c:1266
#, c-format
msgid "Invalid dbus name %s"
msgstr "Nevalida dbus-nomo %s"

#: common/flatpak-context.c:1279
#, c-format
msgid "Unknown socket type %s, valid types are: %s"
msgstr "Nekonata ingotipo %s, validaj tipoj estas: %s"

#: common/flatpak-context.c:1294
#, c-format
msgid "Unknown device type %s, valid types are: %s"
msgstr "Nekonata aparato tipo %s, validaj tipoj estas: %s"

#: common/flatpak-context.c:1308
#, c-format
msgid "Unknown feature type %s, valid types are: %s"
msgstr "Nekonata trajtotipo %s, validaj tipoj estas: %s"

#: common/flatpak-context.c:1840
#, c-format
msgid "Filesystem location \"%s\" contains \"..\""
msgstr "Dosiersistemloko \"%s\" enhavas \"..\""

#: common/flatpak-context.c:1882
#, c-format
msgid ""
"--filesystem=/ is not available, use --filesystem=host for a similar result"
msgstr ""
"--filesystem=/ ne disponeblas, uzi --filesystem=gastiganton por simila "
"rezulto"

#: common/flatpak-context.c:1916
#, c-format
msgid ""
"Unknown filesystem location %s, valid locations are: host, host-os, host-"
"etc, host-root, home, xdg-*[/…], ~/dir, /dir"
msgstr ""
"Nekonata dosiersistemloko %s, validaj lokoj estas: gastiganto, hejmo, xdg-"
"*[/...], ~/dir, /dir"

#: common/flatpak-context.c:2015
#, c-format
msgid "Invalid syntax for %s: %s"
msgstr "Nevalida nomo %s: %s"

#: common/flatpak-context.c:2142
#, c-format
msgid "fallback-x11 can not be conditional"
msgstr "fallback-x11 ne povas esti kondiĉa"

#: common/flatpak-context.c:2318
#, c-format
msgid "Invalid env format %s"
msgstr "Nevalida env-formato %s"

#: common/flatpak-context.c:2399
#, c-format
msgid "Environment variable name must not contain '=': %s"
msgstr "Nomo de mediovariablo ne devas enhavi '=': %s"

#: common/flatpak-context.c:2527 common/flatpak-context.c:2535
#, c-format
msgid "--add-policy arguments must be in the form SUBSYSTEM.KEY=VALUE"
msgstr "--add-policy-argumentoj devas esti en la formo SUBSYSTEM.KEY=VALUE"

#: common/flatpak-context.c:2542
#, c-format
msgid "--add-policy values can't start with \"!\""
msgstr "--add-policy-valoroj ne povas komenci per \"!\""

#: common/flatpak-context.c:2567 common/flatpak-context.c:2575
#, c-format
msgid "--remove-policy arguments must be in the form SUBSYSTEM.KEY=VALUE"
msgstr "--remove-policy argumentoj devas esti en la formo SUBSYSTEM.KEY=VALUE"

#: common/flatpak-context.c:2582
#, c-format
msgid "--remove-policy values can't start with \"!\""
msgstr "--remove-policy valoroj ne povas komenci per \"!\""

#: common/flatpak-context.c:2657
msgid "Share with host"
msgstr "Kunhavigi kun gastiganto"

#: common/flatpak-context.c:2657 common/flatpak-context.c:2658
msgid "SHARE"
msgstr "SHARE"

#: common/flatpak-context.c:2658
msgid "Unshare with host"
msgstr "Maldividi kun gastiganto"

#: common/flatpak-context.c:2659
msgid "Require conditions to be met for a subsystem to get shared"
msgstr "Postuli kondiĉojn esti plenumita por subsistemo esti dividita"

#: common/flatpak-context.c:2659
msgid "SHARE:CONDITION"
msgstr "SHARE:CONDITION"

#: common/flatpak-context.c:2660
msgid "Expose socket to app"
msgstr "Eksponi ingon al app"

#: common/flatpak-context.c:2660 common/flatpak-context.c:2661
msgid "SOCKET"
msgstr "SOCKET"

#: common/flatpak-context.c:2661
msgid "Don't expose socket to app"
msgstr "Ne elmontri ingon al app"

#: common/flatpak-context.c:2662
msgid "Require conditions to be met for a socket to get exposed"
msgstr "Postuli kondiĉojn por esti plenumitaj por ke ingo elmontriĝu"

#: common/flatpak-context.c:2662
msgid "SOCKET:CONDITION"
msgstr "SOCKET:CONDITION"

#: common/flatpak-context.c:2663
msgid "Expose device to app"
msgstr "Ekspozi aparaton al app"

#: common/flatpak-context.c:2663 common/flatpak-context.c:2664
msgid "DEVICE"
msgstr "DEVICE"

#: common/flatpak-context.c:2664
msgid "Don't expose device to app"
msgstr "Ne elmontri aparaton al app"

#: common/flatpak-context.c:2665
msgid "Require conditions to be met for a device to get exposed"
msgstr "Postuli kondiĉojn por esti plenumita por aparato esti elmontrita"

#: common/flatpak-context.c:2665
msgid "DEVICE:CONDITION"
msgstr "DEVICE:CONDITION"

#: common/flatpak-context.c:2666
msgid "Allow feature"
msgstr "Permesi funkcion"

#: common/flatpak-context.c:2666 common/flatpak-context.c:2667
msgid "FEATURE"
msgstr "FEATURE"

#: common/flatpak-context.c:2667
msgid "Don't allow feature"
msgstr "Ne permesi funkcion"

#: common/flatpak-context.c:2668
msgid "Require conditions to be met for a feature to get allowed"
msgstr "Postuli kondiĉojn por esti plenumita por funkcio esti permesita"

#: common/flatpak-context.c:2668
msgid "FEATURE:CONDITION"
msgstr "FEATURE:CONDITION"

#: common/flatpak-context.c:2669
msgid "Expose filesystem to app (:ro for read-only)"
msgstr "Eksponi dosiersistemon al aplikaĵo (:ro por nurlegebla)"

#: common/flatpak-context.c:2669
msgid "FILESYSTEM[:ro]"
msgstr "FILESISTO[:ro]"

#: common/flatpak-context.c:2670
msgid "Don't expose filesystem to app"
msgstr "Ne elmontri dosiersistemon al app"

#: common/flatpak-context.c:2670
msgid "FILESYSTEM"
msgstr "FILESYSTEM"

#: common/flatpak-context.c:2671
msgid "Set environment variable"
msgstr "Agordi mediovariablon"

#: common/flatpak-context.c:2671
msgid "VAR=VALUE"
msgstr "VAR=VALORO"

#: common/flatpak-context.c:2672
msgid "Read environment variables in env -0 format from FD"
msgstr "Legi mediovariablojn en env -0 formato de FD"

#: common/flatpak-context.c:2673
msgid "Remove variable from environment"
msgstr "Forigi objekton de permesa vendejo"

#: common/flatpak-context.c:2673
msgid "VAR"
msgstr "VALUE"

#: common/flatpak-context.c:2674
msgid "Allow app to own name on the session bus"
msgstr "Permesi al aplikaĵo posedi nomon sur la sesiobuso"

#: common/flatpak-context.c:2674 common/flatpak-context.c:2675
#: common/flatpak-context.c:2676 common/flatpak-context.c:2677
#: common/flatpak-context.c:2678 common/flatpak-context.c:2679
#: common/flatpak-context.c:2680
msgid "DBUS_NAME"
msgstr "DBUS_NAME"

#: common/flatpak-context.c:2675
msgid "Allow app to talk to name on the session bus"
msgstr "Permesi al app paroli kun nomo sur la sesiobuso"

#: common/flatpak-context.c:2676
msgid "Don't allow app to talk to name on the session bus"
msgstr "Ne permesi al aplikaĵo paroli kun nomo sur la sesiobuso"

#: common/flatpak-context.c:2677
msgid "Allow app to own name on the system bus"
msgstr "Permesi al app posedi nomon sur la sistema buso"

#: common/flatpak-context.c:2678
msgid "Allow app to talk to name on the system bus"
msgstr "Permesi al app paroli kun nomo sur la sistema buso"

#: common/flatpak-context.c:2679
msgid "Don't allow app to talk to name on the system bus"
msgstr "Ne permesi al aplikaĵo paroli kun nomo sur la sistema buso"

#: common/flatpak-context.c:2680
msgid "Allow app to own name on the a11y bus"
msgstr "Permesi al app posedi nomon sur la sistema buso"

#: common/flatpak-context.c:2681
msgid "Add generic policy option"
msgstr "Aldoni ĝeneralan politikan opcion"

#: common/flatpak-context.c:2681 common/flatpak-context.c:2682
msgid "SUBSYSTEM.KEY=VALUE"
msgstr "SUBSYSTEM.KEY=VALORO"

#: common/flatpak-context.c:2682
msgid "Remove generic policy option"
msgstr "Forigi ĝeneralan politikan opcion"

#: common/flatpak-context.c:2683
msgid "Add USB device to enumerables"
msgstr "Aldoni USB-aparaton al kalkuleblaj"

#: common/flatpak-context.c:2683 common/flatpak-context.c:2684
msgid "VENDOR_ID:PRODUCT_ID"
msgstr "VENDOR_ID:PRODUCT_ID"

#: common/flatpak-context.c:2684
msgid "Add USB device to hidden list"
msgstr "Aldoni USB-aparaton al kaŝita listo"

#: common/flatpak-context.c:2685
msgid "A list of USB devices that are enumerable"
msgstr "Listo de USB-aparatoj kiuj estas listeblaj"

#: common/flatpak-context.c:2685
msgid "LIST"
msgstr "LIST"

#: common/flatpak-context.c:2686
msgid "File containing a list of USB devices to make enumerable"
msgstr "Dosiero enhavanta liston de USB-aparatoj por fari enumeblan"

#: common/flatpak-context.c:2686 common/flatpak-context.c:2687
msgid "FILENAME"
msgstr "FILENAME"

#: common/flatpak-context.c:2687
msgid "Persist home directory subpath"
msgstr "Daŭri hejman dosierujon"

#. This is not needed/used anymore, so hidden, but we accept it for backwards compat
#: common/flatpak-context.c:2689
msgid "Don't require a running session (no cgroups creation)"
msgstr "Ne postulas kurantan sesion (neniu cgroup-kreado)"

#: common/flatpak-context.c:3718
#, c-format
msgid "Not replacing \"%s\" with tmpfs: %s"
msgstr "Ne anstataŭigante \"%s\" per tmpfs: %s"

#: common/flatpak-context.c:3726
#, c-format
msgid "Not sharing \"%s\" with sandbox: %s"
msgstr "Ne kundividante \"%s\" kun sablokesto: %s"

#. Even if the error is one that we would normally silence, like
#. * the path not existing, it seems reasonable to make more of a fuss
#. * about the home directory not existing or otherwise being unusable,
#. * so this is intentionally not using cannot_export()
#: common/flatpak-context.c:3828
#, c-format
msgid "Not allowing home directory access: %s"
msgstr "Ne permesante aliron al hejma dosierujo: %s"

#: common/flatpak-context.c:4062
#, c-format
msgid "Unable to provide a temporary home directory in the sandbox: %s"
msgstr "Ne eblas provizi provizoran hejmdosierujon en la sablokesto: %s"

#: common/flatpak-dir.c:442
#, c-format
msgid "Configured collection ID ‘%s’ not in summary file"
msgstr "Agordita kolekto ID '%s' ne en resuma dosiero"

#: common/flatpak-dir.c:587
#, c-format
msgid "Unable to load summary from remote %s: %s"
msgstr "Ne eblas ŝargi resumon de fora %s: %s"

#: common/flatpak-dir.c:764 common/flatpak-dir.c:800 common/flatpak-dir.c:906
#, c-format
msgid "No such ref '%s' in remote %s"
msgstr "Ne tia ref '%s' en fora %s"

#: common/flatpak-dir.c:891 common/flatpak-dir.c:1051 common/flatpak-dir.c:1080
#: common/flatpak-dir.c:1092
#, c-format
msgid "No entry for %s in remote %s summary flatpak cache"
msgstr "Neniu eniro por %s en fora '%s' resuma flatpakkaŝmemoro"

#: common/flatpak-dir.c:1069
#, c-format
msgid "No summary or Flatpak cache available for remote %s"
msgstr "Neniu resumo aŭ Flatpak-kaŝmemoro havebla por fora %s"

#: common/flatpak-dir.c:1097
#, c-format
msgid "Missing xa.data in summary for remote %s"
msgstr "Neniu oci-resumo konservita por fora '%s'"

#: common/flatpak-dir.c:1103 common/flatpak-dir.c:1546
#, c-format
msgid "Unsupported summary version %d for remote %s"
msgstr "Nesubtenata resumversio %d por fora %s"

#: common/flatpak-dir.c:1200
msgid "Remote OCI index has no registry uri"
msgstr "Fora OCI-indekso ne havas registran uri"

#: common/flatpak-dir.c:1261
#, c-format
msgid "Couldn't find ref %s in remote %s"
msgstr "Ne eblis trovi la plej novan kontrolsumon por ref Z%s en fora Z%s"

#: common/flatpak-dir.c:1288 common/flatpak-dir.c:1381
#, fuzzy, c-format
msgid "Commit has no requested ref ‘%s’ in ref binding metadata (found: ‘%s’)"
msgstr "Commit havas neniun petitan refon '%s' en ref-ligaj metadatenoj"

#: common/flatpak-dir.c:1413
#, c-format
msgid "Configured collection ID ‘%s’ not in binding metadata"
msgstr "Commit havas neniun petitan refon '%s' en ref-ligaj metadatenoj"

#: common/flatpak-dir.c:1449 common/flatpak-dir.c:5645
#, c-format
msgid "Couldn't find latest checksum for ref %s in remote %s"
msgstr "Ne eblis trovi la plej novan kontrolsumon por ref Z%s en fora Z%s"

#: common/flatpak-dir.c:1516 common/flatpak-dir.c:1552
#, c-format
msgid "No entry for %s in remote %s summary flatpak sparse cache"
msgstr "Neniu eniro por %s en fora %s resumo flatpak maldensa kaŝmemoro"

#: common/flatpak-dir.c:2540
#, c-format
msgid "Commit metadata for %s not matching expected metadata"
msgstr "Enmeti metadatenojn por %s ne kongruas kun atendataj metadatenoj"

#: common/flatpak-dir.c:2823
msgid "Unable to connect to system bus"
msgstr "Ne eblas konektiĝi al sistema buso"

#: common/flatpak-dir.c:3419
msgid "User installation"
msgstr "Instalado de uzanto"

#: common/flatpak-dir.c:3426
#, c-format
msgid "System (%s) installation"
msgstr "Sistemo (%s) instalado"

#: common/flatpak-dir.c:3472
#, c-format
msgid "No overrides found for %s"
msgstr "Neniuj anstataŭaĵoj trovitaj por %s"

#: common/flatpak-dir.c:3625
#, c-format
msgid "%s (commit %s) not installed"
msgstr "%s (kommit %s) ne instalita"

#: common/flatpak-dir.c:4650
#, c-format
msgid "Error parsing system flatpakrepo file for %s: %s"
msgstr "Eraro analizante la flatpakrepo-dosieron de la sistemo por %s: %s"

#: common/flatpak-dir.c:4735
#, c-format
msgid "While opening repository %s: "
msgstr "Malfermante deponejon %s:"

#: common/flatpak-dir.c:5004
#, c-format
msgid "The config key %s is not set"
msgstr "La agorda ŝlosilo %s ne estas agordita"

#: common/flatpak-dir.c:5140
#, c-format
msgid "No current %s pattern matching %s"
msgstr "Neniu aktuala %s ŝablono kongrua kun %s"

#: common/flatpak-dir.c:5422
msgid "No appstream commit to deploy"
msgstr "Neniu appstream kompromitas deploji"

#: common/flatpak-dir.c:5941 common/flatpak-dir.c:7266
#: common/flatpak-dir.c:10881 common/flatpak-dir.c:11618
msgid "Can't pull from untrusted non-gpg verified remote"
msgstr "Ne povas tiri de nefidinda ne-gpg kontrolita fora"

#: common/flatpak-dir.c:6376 common/flatpak-dir.c:6591
msgid "Extra data not supported for non-gpg-verified local system installs"
msgstr ""
"Kromaj datumoj ne subtenataj por ne-gpg-kontrolitaj lokaj sistemaj instaloj"

#: common/flatpak-dir.c:6415 common/flatpak-dir.c:6782
#, c-format
msgid "Invalid checksum for extra data uri %s"
msgstr "Nevalida ĉeksumo por kromaj datumoj uri %s"

#: common/flatpak-dir.c:6424
#, c-format
msgid "Empty name for extra data uri %s"
msgstr "Malplena nomo por kromaj datumoj uri %s"

#: common/flatpak-dir.c:6432
#, c-format
msgid "Unsupported extra data uri %s"
msgstr "Nesubtenataj kromaj datumoj uri %s"

#: common/flatpak-dir.c:6461
#, c-format
msgid "Failed to load local extra-data %s: %s"
msgstr "Malsukcesis ŝargi lokajn kromdatumojn %s: %s"

#: common/flatpak-dir.c:6469
#, c-format
msgid "Wrong size for extra-data %s"
msgstr "Malĝusta grandeco por kromdatumoj %s"

#: common/flatpak-dir.c:6488
#, c-format
msgid "While downloading %s: "
msgstr "Dum elŝuto de Z%s:"

#: common/flatpak-dir.c:6498
#, c-format
msgid "Wrong size for extra data %s"
msgstr "Malĝusta grandeco por kromaj datumoj %s"

#: common/flatpak-dir.c:6507
#, c-format
msgid "Invalid checksum for extra data %s"
msgstr "Nevalida ĉeksumo por kromaj datumoj %s"

#: common/flatpak-dir.c:7096 common/flatpak-dir.c:7349
#, c-format
msgid "While pulling %s from remote %s: "
msgstr "Tirante %s de fora %s:"

#: common/flatpak-dir.c:7290 common/flatpak-repo-utils.c:3886
msgid "GPG signatures found, but none are in trusted keyring"
msgstr "GPG-subskriboj trovitaj, sed neniu estas en fidinda ŝlosilringo"

#: common/flatpak-dir.c:7307
#, c-format
msgid "Commit for ‘%s’ has no ref binding"
msgstr "Commit havas neniun petitan refon '%s' en ref-ligaj metadatenoj"

#: common/flatpak-dir.c:7312
#, c-format
msgid "Commit for ‘%s’ is not in expected bound refs: %s"
msgstr "Devota por '%s' ne estas en atendataj ligitaj referencoj: %s"

#: common/flatpak-dir.c:7488
msgid "Only applications can be made current"
msgstr "Nur aplikaĵoj povas esti aktualigataj"

#: common/flatpak-dir.c:8192
msgid "Not enough memory"
msgstr "Ne sufiĉa memoro"

#: common/flatpak-dir.c:8211
msgid "Failed to read from exported file"
msgstr "Malsukcesis legi el eksportita dosiero"

#: common/flatpak-dir.c:8401
msgid "Error reading mimetype xml file"
msgstr "Eraro legante mimetype xml-dosieron"

#: common/flatpak-dir.c:8406
msgid "Invalid mimetype xml file"
msgstr "Nevalida mimetype xml-dosiero"

#: common/flatpak-dir.c:8492
#, c-format
msgid "D-Bus service file '%s' has wrong name"
msgstr "D-Bus-servodosiero '%s' havas malĝustan nomon"

#: common/flatpak-dir.c:8647
#, c-format
msgid "Invalid Exec argument %s"
msgstr "Nevalida postul-flatpak argumento %s"

#: common/flatpak-dir.c:9115
msgid "While getting detached metadata: "
msgstr "Dum akiro de malfiksitaj metadatenoj:"

#: common/flatpak-dir.c:9120 common/flatpak-dir.c:9125
#: common/flatpak-dir.c:9129
msgid "Extra data missing in detached metadata"
msgstr "Kromaj datumoj mankas en dekroĉitaj metadatenoj"

#: common/flatpak-dir.c:9133
msgid "While creating extradir: "
msgstr "Dum kreado de ekstradir:"

#: common/flatpak-dir.c:9154 common/flatpak-dir.c:9187
msgid "Invalid checksum for extra data"
msgstr "Nevalida ĉeksumo por kromaj datumoj"

#: common/flatpak-dir.c:9183
msgid "Wrong size for extra data"
msgstr "Malĝusta grandeco por kromaj datumoj"

#: common/flatpak-dir.c:9196
#, c-format
msgid "While writing extra data file '%s': "
msgstr "Dum skribado de ekstra datuma dosiero '%s':"

#: common/flatpak-dir.c:9204
#, c-format
msgid "Extra data %s missing in detached metadata"
msgstr "Ekstraj datumoj %s mankas en seigitaj metadatenoj"

#: common/flatpak-dir.c:9278
#, c-format
msgid "Unable to get runtime key from metadata"
msgstr "Uzi alternativan dosieron por la metadatumoj"

#: common/flatpak-dir.c:9402
#, c-format
msgid "apply_extra script failed, exit status %d"
msgstr "apply_extra skripto malsukcesis, elira stato %d"

#. Translators: The placeholder is for an app ref.
#: common/flatpak-dir.c:9591
#, c-format
msgid "Installing %s is not allowed by the policy set by your administrator"
msgstr ""
"Instali %s ne estas permesita de la politiko fiksita de via administranto"

#: common/flatpak-dir.c:9690
#, c-format
msgid "While trying to resolve ref %s: "
msgstr "Dum vi provas solvi ref %s:"

#: common/flatpak-dir.c:9702
#, c-format
msgid "%s is not available"
msgstr "%s ne haveblas"

#: common/flatpak-dir.c:9714 common/flatpak-dir.c:11495
#, c-format
msgid "%s commit %s already installed"
msgstr "%s kommit %s jam instalita"

#: common/flatpak-dir.c:9721
msgid "Can't create deploy directory"
msgstr "Ne povas krei deplojan dosierujon"

#: common/flatpak-dir.c:9729
#, c-format
msgid "Failed to read commit %s: "
msgstr "Malsukcesis legi commit %s:"

#: common/flatpak-dir.c:9750
#, c-format
msgid "While trying to checkout %s into %s: "
msgstr "Dum vi provas kontroli %s en %s:"

#: common/flatpak-dir.c:9769
msgid "While trying to checkout metadata subpath: "
msgstr "Dum vi provas kontroli la subvojon de metadatumoj:"

#: common/flatpak-dir.c:9801
#, c-format
msgid "While trying to checkout subpath ‘%s’: "
msgstr "Dum vi provas kontroli la subvojon '%s':"

#: common/flatpak-dir.c:9811
msgid "While trying to remove existing extra dir: "
msgstr "Dum vi provas forigi ekzistantan kroman diraĵon:"

#: common/flatpak-dir.c:9822
msgid "While trying to apply extra data: "
msgstr "Dum vi provas apliki kromajn datumojn:"

#: common/flatpak-dir.c:9849
#, c-format
msgid "Invalid commit ref %s: "
msgstr "Nevalida kompromisa ref %s:"

#: common/flatpak-dir.c:9857 common/flatpak-dir.c:9869
#, c-format
msgid "Deployed ref %s does not match commit (%s)"
msgstr "Deplojita ref %s ne kongruas kun commit (%s)"

#: common/flatpak-dir.c:9863
#, c-format
msgid "Deployed ref %s branch does not match commit (%s)"
msgstr "Deplojita ref %s-branĉo ne kongruas kun commit (%s)"

#: common/flatpak-dir.c:10125 common/flatpak-installation.c:1911
#, c-format
msgid "%s branch %s already installed"
msgstr "%s branĉo %s jam instalita"

#: common/flatpak-dir.c:10985
#, c-format
msgid "Could not unmount revokefs-fuse filesystem at %s: "
msgstr "Ne eblis malmunti revokefs-fuse dosiersistemon ĉe %s:"

#: common/flatpak-dir.c:11289
#, c-format
msgid "This version of %s is already installed"
msgstr "Ĉi tiu versio de %s jam estas instalita"

#: common/flatpak-dir.c:11302
#, c-format
msgid "Can't change remote during bundle install"
msgstr "Ne povas ŝanĝi telerdistancon dum pakinstalado"

#: common/flatpak-dir.c:11571
msgid "Can't update to a specific commit without root permissions"
msgstr "Ne povas ĝisdatigi al specifa transdono sen radikaj permesoj"

#: common/flatpak-dir.c:11852
#, c-format
msgid "Can't remove %s, it is needed for: %s"
msgstr "Ne povas forigi %s, ĝi estas bezonata por: %s"

#: common/flatpak-dir.c:11912 common/flatpak-installation.c:2067
#, c-format
msgid "%s branch %s is not installed"
msgstr "%s branĉo %s ne estas instalita"

#: common/flatpak-dir.c:12165
#, c-format
msgid "%s commit %s not installed"
msgstr "%s kommit %s ne instalita"

#: common/flatpak-dir.c:12501
#, c-format
msgid "Pruning repo failed: %s"
msgstr "Pritondado de repo malsukcesis: %s"

#: common/flatpak-dir.c:12669 common/flatpak-dir.c:12675
#, c-format
msgid "Failed to load filter '%s'"
msgstr "Malsukcesis ŝargi filtrilon '%s'"

#: common/flatpak-dir.c:12681
#, c-format
msgid "Failed to parse filter '%s'"
msgstr "Malsukcesis analizi filtrilon '%s'"

#: common/flatpak-dir.c:12963
msgid "Failed to write summary cache: "
msgstr "Malsukcesis skribi resuman kaŝmemoron:"

#: common/flatpak-dir.c:12982
#, c-format
msgid "No oci summary cached for remote '%s'"
msgstr "Neniu oci-resumo konservita por fora '%s'"

#: common/flatpak-dir.c:13207
#, c-format
msgid "No cached summary for remote '%s'"
msgstr "Neniu oci-resumo konservita por fora '%s'"

#: common/flatpak-dir.c:13248
#, c-format
msgid "Invalid checksum for indexed summary %s read from %s"
msgstr "Nevalida ĉeksumo por indeksita resumo %s legita el %s"

#: common/flatpak-dir.c:13321
#, c-format
msgid ""
"Remote listing for %s not available; server has no summary file. Check the "
"URL passed to remote-add was valid."
msgstr ""
"Fora listo por %s ne havebla; servilo ne havas resuman dosieron. Kontrolu, "
"ke la URL transdonita al remote-add estis valida."

#: common/flatpak-dir.c:13698
#, c-format
msgid "Invalid checksum for indexed summary %s for remote '%s'"
msgstr "Nevalida ĉeksumo por indeksita resumo %s por fora '%s'"

#: common/flatpak-dir.c:14388
#, c-format
msgid "Multiple branches available for %s, you must specify one of: "
msgstr "Pluraj branĉoj disponeblaj por %s, vi devas specifi unu el:"

#: common/flatpak-dir.c:14454
#, c-format
msgid "Nothing matches %s"
msgstr "Nenio kongruas kun %s"

#: common/flatpak-dir.c:14562
#, c-format
msgid "Can't find ref %s%s%s%s%s"
msgstr "Ne povas trovi ref Z%s%s%s%s%s"

#: common/flatpak-dir.c:14605
#, c-format
msgid "Error searching remote %s: %s"
msgstr "Eraro serĉante fora %s: %s"

#: common/flatpak-dir.c:14702
#, c-format
msgid "Error searching local repository: %s"
msgstr "Eraro serĉante lokan deponejon: %s"

#: common/flatpak-dir.c:14839
#, c-format
msgid "%s/%s/%s not installed"
msgstr "%s/%s/%s ne instalita"

#: common/flatpak-dir.c:15042
#, c-format
msgid "Could not find installation %s"
msgstr "Ne eblis trovi instalaĵon %s"

#: common/flatpak-dir.c:15612
#, c-format
msgid "Invalid file format, no %s group"
msgstr "Nevalida dosierformato, neniu %s grupo"

#: common/flatpak-dir.c:15617 common/flatpak-repo-utils.c:2836
#, c-format
msgid "Invalid version %s, only 1 supported"
msgstr "Nevalida versio %s, nur 1 subtenata"

#: common/flatpak-dir.c:15622 common/flatpak-dir.c:15627
#, c-format
msgid "Invalid file format, no %s specified"
msgstr "Nevalida dosierformato, neniu %s specifita"

#. Check some minimal size so we don't get crap
#: common/flatpak-dir.c:15647
msgid "Invalid file format, gpg key invalid"
msgstr "Nevalida dosierformato, gpg-ŝlosilo nevalida"

#: common/flatpak-dir.c:15675 common/flatpak-repo-utils.c:2917
msgid "Collection ID requires GPG key to be provided"
msgstr "Kolekta ID postulas GPG-ŝlosilon esti provizita"

#: common/flatpak-dir.c:15718
#, c-format
msgid "Runtime %s, branch %s is already installed"
msgstr "Runtime %s, branĉo %s jam estas instalita"

#: common/flatpak-dir.c:15719
#, c-format
msgid "App %s, branch %s is already installed"
msgstr "Apo %s, branĉo %s jam estas instalita"

#: common/flatpak-dir.c:15953
#, c-format
msgid "Can't remove remote '%s' with installed ref %s (at least)"
msgstr "Ne povas forigi fora '%s' kun instalita ref %s (almenaŭ)"

#: common/flatpak-dir.c:16058
#, c-format
msgid "Invalid character '/' in remote name: %s"
msgstr "Nevalida signo '/' en fora nomo: %s"

#: common/flatpak-dir.c:16064
#, c-format
msgid "No configuration for remote %s specified"
msgstr "Neniu agordo por fora %s specifita"

#: common/flatpak-dir.c:17597
#, c-format
msgid "Skipping deletion of mirror ref (%s, %s)…\n"
msgstr "Preterpasante forigan de spegul-ref (%s, %s)…\n"

#: common/flatpak-exports.c:931
#, c-format
msgid "An absolute path is required"
msgstr "Absoluta vojo estas postulata"

#: common/flatpak-exports.c:948
#, c-format
msgid "Unable to open path \"%s\": %s"
msgstr "Ne eblas malfermi vojon \"%s\": %s"

#: common/flatpak-exports.c:955
#, c-format
msgid "Unable to get file type of \"%s\": %s"
msgstr "Ne eblas akiri dosier-tipon de \"%s\": %s"

#: common/flatpak-exports.c:964
#, c-format
msgid "File \"%s\" has unsupported type 0o%o"
msgstr "Dosiero \"%s\" havas nesubtenan tipon 0o%o"

#: common/flatpak-exports.c:970
#, c-format
msgid "Unable to get filesystem information for \"%s\": %s"
msgstr "Ne eblas ricevi dosiersistemenformojn por \"%s\": %s"

#: common/flatpak-exports.c:980
#, c-format
msgid "Ignoring blocking autofs path \"%s\""
msgstr "Ignorante blokadon de aŭtofs vojo \"%s\""

#: common/flatpak-exports.c:996 common/flatpak-exports.c:1009
#: common/flatpak-exports.c:1022
#, c-format
msgid "Path \"%s\" is reserved by Flatpak"
msgstr "Vojo \"%s\" estas rezervita de Flatpak"

#: common/flatpak-exports.c:1076
#, c-format
msgid "Unable to resolve symbolic link \"%s\": %s"
msgstr "Ne eblas solvi simbolan ligilon \"%s\": %s"

#: common/flatpak-glib-backports.c:69
msgid "Empty string is not a number"
msgstr "Malplena ĉeno ne estas nombro"

#: common/flatpak-glib-backports.c:95
#, c-format
msgid "“%s” is not an unsigned number"
msgstr "“%s” ne estas nesubskribita numero"

#: common/flatpak-glib-backports.c:105
#, c-format
msgid "Number “%s” is out of bounds [%s, %s]"
msgstr "Numero \"%s\" estas ekster limoj [%s, %s]"

#: common/flatpak-image-source.c:83
msgid "Only sha256 image checksums are supported"
msgstr "Nur sha256 bildaj kontrolsumoj estas subtenataj"

#: common/flatpak-image-source.c:100 common/flatpak-image-source.c:108
msgid "Image is not a manifest"
msgstr "Bildo ne estas manifesto"

#: common/flatpak-image-source.c:123
msgid "No org.flatpak.ref found in image"
msgstr "Neniu org.flatpak.ref trovita en bildo"

#: common/flatpak-image-source.c:148
#, c-format
msgid "Ref '%s' not found in registry"
msgstr "Ref '%s' ne trovita en registro"

#: common/flatpak-image-source.c:157
msgid "Multiple images in registry, specify a ref with --ref"
msgstr "Multoblaj bildoj en registro, specifi ref per --ref"

#: common/flatpak-installation.c:834
#, c-format
msgid "Ref %s not installed"
msgstr "Ref %s ne instalita"

#: common/flatpak-installation.c:875
#, c-format
msgid "App %s not installed"
msgstr "Apliko %s ne instalita"

#: common/flatpak-installation.c:1395
#, c-format
msgid "Remote '%s' already exists"
msgstr "Fora '%s' jam ekzistas"

#: common/flatpak-installation.c:1946
#, c-format
msgid "As requested, %s was only pulled, but not installed"
msgstr "Kiel postulite, %s estis nur tirita, sed ne instalita"

#: common/flatpak-instance.c:533 common/flatpak-instance.c:687
#: common/flatpak-instance.c:728
#, c-format
msgid "Unable to create directory %s"
msgstr "Ne eblas krei dosierujon %s"

#: common/flatpak-instance.c:554
#, c-format
msgid "Unable to lock %s"
msgstr "Ne eblas ŝlosi %s"

#: common/flatpak-instance.c:627
#, c-format
msgid "Unable to create temporary directory in %s"
msgstr "Ne eblas krei provizoran dosierujon en %s"

#: common/flatpak-instance.c:639
#, c-format
msgid "Unable to create file %s"
msgstr "Ne eblas krei dosieron %s"

#: common/flatpak-instance.c:646
#, c-format
msgid "Unable to update symbolic link %s/%s"
msgstr "Ne eblas ĝisdatigi simbolan ligilon %s/%s"

#: common/flatpak-oci-registry.c:1197
msgid "Only Bearer authentication supported"
msgstr "Nur Bearer-aŭtentikigo subtenata"

#: common/flatpak-oci-registry.c:1206
msgid "Only realm in authentication request"
msgstr "Nevalida dbus-nomo %s"

#: common/flatpak-oci-registry.c:1213
msgid "Invalid realm in authentication request"
msgstr "Nevalida dbus-nomo %s"

#: common/flatpak-oci-registry.c:1283
#, c-format
msgid "Authorization failed: %s"
msgstr "Nevalida dbus-nomo %s"

#: common/flatpak-oci-registry.c:1285
msgid "Authorization failed"
msgstr "Rajtigo malsukcesis"

#: common/flatpak-oci-registry.c:1289
#, c-format
msgid "Unexpected response status %d when requesting token: %s"
msgstr "Neatendita responda stato %d dum petado de ĵetono: %s"

#: common/flatpak-oci-registry.c:1300
msgid "Invalid authentication request response"
msgstr "Nevalida dbus-nomo %s"

#: common/flatpak-oci-registry.c:1731
#, c-format
msgid "Flatpak was compiled without zstd support"
msgstr "Flatpak estis kompilita sen zstd-subteno"

#: common/flatpak-oci-registry.c:1923 common/flatpak-oci-registry.c:1975
#: common/flatpak-oci-registry.c:2004 common/flatpak-oci-registry.c:2059
#: common/flatpak-oci-registry.c:2115 common/flatpak-oci-registry.c:2193
msgid "Invalid delta file format"
msgstr "Nevalida env-formato %s"

#: common/flatpak-oci-registry.c:3198 common/flatpak-oci-registry.c:3382
msgid "Invalid OCI image config"
msgstr "Nevalida OCI-bilda agordo"

#: common/flatpak-oci-registry.c:3260 common/flatpak-oci-registry.c:3531
#, c-format
msgid "Wrong layer checksum, expected %s, was %s"
msgstr "Malĝusta tavola kontrolsumo, atendita %s, estis %s"

#: common/flatpak-oci-registry.c:3359
#, c-format
msgid "No ref specified for OCI image %s"
msgstr "Neniu ref specifita por OCI-bildo %s"

#: common/flatpak-oci-registry.c:3369
#, c-format
msgid "Wrong ref (%s) specified for OCI image %s, expected %s"
msgstr "Malĝusta ref (%s) specifita por OCI-bildo %s, atendita %s"

#: common/flatpak-progress.c:236
#, c-format
msgid "Downloading metadata: %u/(estimating) %s"
msgstr "Elŝuto de metadatenoj: %u/(taksado) %s"

#: common/flatpak-progress.c:260
#, c-format
msgid "Downloading: %s/%s"
msgstr "Elŝuto: %s/%s"

#: common/flatpak-progress.c:280
#, c-format
msgid "Downloading extra data: %s/%s"
msgstr "Elŝutante kromajn datumojn: %s/%s"

#: common/flatpak-progress.c:285
#, c-format
msgid "Downloading files: %d/%d %s"
msgstr "Elŝutante dosierojn: %d/%d %s"

#: common/flatpak-ref-utils.c:122
msgid "Name can't be empty"
msgstr "Nomo ne povas esti malplena"

#: common/flatpak-ref-utils.c:129
msgid "Name can't be longer than 255 characters"
msgstr "Nomo ne povas esti pli longa ol 255 signoj"

#: common/flatpak-ref-utils.c:142
msgid "Name can't start with a period"
msgstr "Nomo ne povas komenci per punkto"

#: common/flatpak-ref-utils.c:148
#, c-format
msgid "Name can't start with %c"
msgstr "Nomo ne povas komenci per %c"

#: common/flatpak-ref-utils.c:164
msgid "Name can't end with a period"
msgstr "Nomo ne povas finiĝi per punkto"

#: common/flatpak-ref-utils.c:171 common/flatpak-ref-utils.c:183
msgid "Only last name segment can contain -"
msgstr "Nur familinoma segmento povas enhavi -"

#: common/flatpak-ref-utils.c:174
#, c-format
msgid "Name segment can't start with %c"
msgstr "Nomsegmento ne povas komenci per %c"

#: common/flatpak-ref-utils.c:186
#, c-format
msgid "Name can't contain %c"
msgstr "Nomo ne povas enhavi %c"

#: common/flatpak-ref-utils.c:195
msgid "Names must contain at least 2 periods"
msgstr "Nomoj devas enhavi almenaŭ 2 punktojn"

#: common/flatpak-ref-utils.c:312
msgid "Arch can't be empty"
msgstr "Branĉo ne povas esti malplena"

#: common/flatpak-ref-utils.c:323
#, c-format
msgid "Arch can't contain %c"
msgstr "Branĉo ne povas enhavi %c"

#: common/flatpak-ref-utils.c:385
msgid "Branch can't be empty"
msgstr "Branĉo ne povas esti malplena"

#: common/flatpak-ref-utils.c:395
#, c-format
msgid "Branch can't start with %c"
msgstr "Branĉo ne povas komenci per %c"

#: common/flatpak-ref-utils.c:405
#, c-format
msgid "Branch can't contain %c"
msgstr "Branĉo ne povas enhavi %c"

#: common/flatpak-ref-utils.c:615 common/flatpak-ref-utils.c:865
msgid "Ref too long"
msgstr "Ref tro longa"

#: common/flatpak-ref-utils.c:627
msgid "Invalid remote name"
msgstr "Malbona fora nomo: %s"

#: common/flatpak-ref-utils.c:641
#, c-format
msgid "%s is not application or runtime"
msgstr "%s ne estas aplikaĵo aŭ rultempo"

#: common/flatpak-ref-utils.c:650 common/flatpak-ref-utils.c:667
#: common/flatpak-ref-utils.c:683
#, c-format
msgid "Wrong number of components in %s"
msgstr "Malĝusta nombro da komponantoj en %s"

#: common/flatpak-ref-utils.c:656
#, c-format
msgid "Invalid name %.*s: %s"
msgstr "Nevalida nomo %.*s: %s"

#: common/flatpak-ref-utils.c:673
#, c-format
msgid "Invalid arch: %.*s: %s"
msgstr "Nevalida arkitekturo: %.*s: %s"

#: common/flatpak-ref-utils.c:816
#, c-format
msgid "Invalid name %s: %s"
msgstr "Nevalida nomo %s: %s"

#: common/flatpak-ref-utils.c:834
#, c-format
msgid "Invalid arch: %s: %s"
msgstr "Nevalida branĉo %s: %s"

#: common/flatpak-ref-utils.c:853
#, c-format
msgid "Invalid branch: %s: %s"
msgstr "Nevalida branĉo %s: %s"

#: common/flatpak-ref-utils.c:962 common/flatpak-ref-utils.c:970
#: common/flatpak-ref-utils.c:978
#, c-format
msgid "Wrong number of components in partial ref %s"
msgstr "Malĝusta nombro da komponantoj en rultempo %s"

#: common/flatpak-ref-utils.c:1298
msgid " development platform"
msgstr "Uzi evoluan rultempon"

#: common/flatpak-ref-utils.c:1300
msgid " platform"
msgstr "platformo"

#: common/flatpak-ref-utils.c:1302
msgid " application base"
msgstr "Apliko"

#: common/flatpak-ref-utils.c:1305
msgid " debug symbols"
msgstr "sencimigaj simboloj"

#: common/flatpak-ref-utils.c:1307
msgid " sourcecode"
msgstr "fontkodo"

#: common/flatpak-ref-utils.c:1309
msgid " translations"
msgstr "Instalado"

#: common/flatpak-ref-utils.c:1311
msgid " docs"
msgstr "dokumentoj"

#: common/flatpak-ref-utils.c:1578
#, c-format
msgid "Invalid id %s: %s"
msgstr "Nevalida identigilo %s: %s"

#: common/flatpak-remote.c:1216
#, c-format
msgid "Bad remote name: %s"
msgstr "Malbona fora nomo: %s"

#: common/flatpak-remote.c:1220
msgid "No URL specified"
msgstr "Neniu URL specifita"

#: common/flatpak-remote.c:1266
msgid "GPG verification must be enabled when a collection ID is set"
msgstr "GPG-konfirmo estas postulata se kolektoj estas ebligitaj"

#: common/flatpak-repo-utils.c:344
#, c-format
msgid "No extra data sources"
msgstr "Neniuj kromaj datumfontoj"

#: common/flatpak-repo-utils.c:2817
#, c-format
msgid "Invalid %s: Missing group ‘%s’"
msgstr "Nevalida Z%s: Mankas grupo '%s'"

#: common/flatpak-repo-utils.c:2826
#, c-format
msgid "Invalid %s: Missing key ‘%s’"
msgstr "Nevalida Z%s: mankas ŝlosilo '%s'"

#: common/flatpak-repo-utils.c:2876
msgid "Invalid gpg key"
msgstr "Nevalida gpg-ŝlosilo"

#: common/flatpak-repo-utils.c:3217
#, c-format
msgid "Error copying 64x64 icon for component %s: %s\n"
msgstr "Eraro kopiante 64x64 ikonon por komponanto %s: %s\n"

#: common/flatpak-repo-utils.c:3223
#, c-format
msgid "Error copying 128x128 icon for component %s: %s\n"
msgstr "Eraro kopiante 128x128 ikonon por komponanto %s: %s\n"

#: common/flatpak-repo-utils.c:3362
#, c-format
msgid "%s is end-of-life, ignoring for appstream"
msgstr "%s estas fino de vivo, ignorante por appstream"

#: common/flatpak-repo-utils.c:3397
#, c-format
msgid "No appstream data for %s: %s\n"
msgstr "Neniuj datenoj pri appstream por %s: %s\n"

#: common/flatpak-repo-utils.c:3744
msgid "Invalid bundle, no ref in metadata"
msgstr "Nevalida pakaĵo, neniu ref en metadatumoj"

#: common/flatpak-repo-utils.c:3846
#, c-format
msgid "Collection ‘%s’ of bundle doesn’t match collection ‘%s’ of remote"
msgstr "Kolekto '%s' de pakaĵo ne kongruas kun kolekto '%s' de fora"

#: common/flatpak-repo-utils.c:3923
msgid "Metadata in header and app are inconsistent"
msgstr "Metadatumoj en kaplinio kaj aplikaĵo estas malkonsekvencaj"

#: common/flatpak-run.c:951
msgid "No systemd user session available, cgroups not available"
msgstr "Neniu systemd uzantsesio havebla, cgroups ne havebla"

#: common/flatpak-run.c:1496
msgid "Unable to allocate instance id"
msgstr "Ne eblas asigni ekzempleridentigilon"

#: common/flatpak-run.c:1632 common/flatpak-run.c:1641
#, c-format
msgid "Failed to open flatpak-info file: %s"
msgstr "Malsukcesis malfermi flatpak-info-dosieron: %s"

#: common/flatpak-run.c:1668
#, c-format
msgid "Failed to open bwrapinfo.json file: %s"
msgstr "Malsukcesis malfermi bwrapinfo.json dosieron: %s"

#: common/flatpak-run.c:1689
#, c-format
msgid "Failed to write to instance id fd: %s"
msgstr "Malsukcesis skribi al instance-id fd: %s"

#: common/flatpak-run.c:2096
msgid "Initialize seccomp failed"
msgstr "Inicialigi seccomp malsukcesis"

#: common/flatpak-run.c:2135
#, c-format
msgid "Failed to add architecture to seccomp filter: %s"
msgstr "Malsukcesis aldoni arkitekturon al seccomp-filtrilo: %s"

#: common/flatpak-run.c:2143
#, c-format
msgid "Failed to add multiarch architecture to seccomp filter: %s"
msgstr "Malsukcesis aldoni plurarka arkitekturon al seccomp-filtrilo: %s"

#: common/flatpak-run.c:2175 common/flatpak-run.c:2192
#: common/flatpak-run.c:2214
#, c-format
msgid "Failed to block syscall %d: %s"
msgstr "Malsukcesis bloki sistemovokon %d: %s"

#: common/flatpak-run.c:2247
#, c-format
msgid "Failed to export bpf: %s"
msgstr "Malsukcesis eksporti bpf: %s"

#: common/flatpak-run.c:2587
#, c-format
msgid "Failed to open ‘%s’"
msgstr "Malsukcesis malfermi '%s'"

#: common/flatpak-run.c:2597
#, c-format
msgid ""
"Directory forwarding needs version 4 of the document portal (have version %d)"
msgstr ""
"Adresaro plusendado bezonas version 4 de la dokumentportalo (havi version %d)"

#: common/flatpak-run.c:2915
#, c-format
msgid "ldconfig failed, exit status %d"
msgstr "ldconfig malsukcesis, elira stato %d"

#: common/flatpak-run.c:2922
msgid "Can't open generated ld.so.cache"
msgstr "Ne povas malfermi generitan ld.so.cache"

#. Translators: The placeholder is for an app ref.
#: common/flatpak-run.c:3045
#, c-format
msgid "Running %s is not allowed by the policy set by your administrator"
msgstr "Ruli %s ne estas permesita de la politiko fiksita de via administranto"

#: common/flatpak-run.c:3202
msgid ""
"\"flatpak run\" is not intended to be run as `sudo flatpak run`. Use `sudo "
"-i` or `su -l` instead and invoke \"flatpak run\" from inside the new shell."
msgstr ""
"\"flatpak run\" ne intencas esti rulita kiel `sudo flatpak run`. Uzi `sudo "
"-i` aŭ `su -l` anstataŭe kaj alvoki \"flatpak run\" de ene de la nova ŝelo."

#: common/flatpak-run.c:3413
#, c-format
msgid "Failed to migrate from %s: %s"
msgstr "Malsukcesis migri de %s: %s"

#: common/flatpak-run.c:3434
#, c-format
msgid "Failed to migrate old app data directory %s to new name %s: %s"
msgstr ""
"Malsukcesis migri malnovan datumdosierujon de la aplikaĵo %s al nova nomo "
"%s: %s"

#: common/flatpak-run.c:3443
#, c-format
msgid "Failed to create symlink while migrating %s: %s"
msgstr "Malsukcesis krei simbolligon dum migrado de %s: %s"

#: common/flatpak-run-dbus.c:46
msgid "Failed to open app info file"
msgstr "Malsukcesis malfermi aplikan informodosieron"

#: common/flatpak-run-dbus.c:149
msgid "Unable to create sync pipe"
msgstr "Ne eblas krei sinkronigan tubon"

#: common/flatpak-run-dbus.c:185
msgid "Failed to sync with dbus proxy"
msgstr "Malsukcesis sinkronigi kun dbus-prokurilo"

#: common/flatpak-transaction.c:2275
#, c-format
msgid "Warning: Problem looking for related refs: %s"
msgstr "Averto: Problemo serĉante rilatajn referencojn: %s"

#: common/flatpak-transaction.c:2493
#, c-format
msgid "The application %s requires the runtime %s which was not found"
msgstr "La aplikaĵo %s postulas la rultempon %s kiu ne estis trovita"

#: common/flatpak-transaction.c:2509
#, c-format
msgid "The application %s requires the runtime %s which is not installed"
msgstr "La aplikaĵo %s postulas la rultempon %s kiu ne estas instalita"

#: common/flatpak-transaction.c:2641
#, c-format
msgid "Can't uninstall %s which is needed by %s"
msgstr "Ne povas malinstali %s kiu estas bezonata de %s"

#: common/flatpak-transaction.c:2740
#, c-format
msgid "Remote %s disabled, ignoring %s update"
msgstr "Fora %s malŝaltita, ignorante %s ĝisdatigon"

#: common/flatpak-transaction.c:2773
#, c-format
msgid "%s is already installed"
msgstr "%s jam estas instalita"

#: common/flatpak-transaction.c:2776
#, c-format
msgid "%s is already installed from remote %s"
msgstr "%s jam estas instalita de fora %s"

#: common/flatpak-transaction.c:3120
#, c-format
msgid "Invalid .flatpakref: %s"
msgstr "Nevalida .flatpakref: %s"

#: common/flatpak-transaction.c:3161
msgid "Warning: Could not mark already installed apps as preinstalled"
msgstr ""
"Averto: Ne eblis marki jam instalitajn programojn kiel antaŭinstalitajn"

#: common/flatpak-transaction.c:3382
#, c-format
msgid "Error updating remote metadata for '%s': %s"
msgstr "Eraro dum ĝisdatigo de foraj metadatenoj por '%s': %s"

#: common/flatpak-transaction.c:3885
#, c-format
msgid ""
"Warning: Treating remote fetch error as non-fatal since %s is already "
"installed: %s"
msgstr ""
"Averto: Traktante eraron de fora alporto kiel ne mortiga ĉar %s jam estas "
"instalita: %s"

#: common/flatpak-transaction.c:4209
#, c-format
msgid "No authenticator installed for remote '%s'"
msgstr "Neniu aŭtentikigilo instalita por fora '%s'"

#: common/flatpak-transaction.c:4313 common/flatpak-transaction.c:4320
#, c-format
msgid "Failed to get tokens for ref: %s"
msgstr "Malsukcesis determini partojn de ref: %s"

#: common/flatpak-transaction.c:4315 common/flatpak-transaction.c:4322
msgid "Failed to get tokens for ref"
msgstr "Malsukcesis determini partojn de ref: %s"

#: common/flatpak-transaction.c:4580
#, c-format
msgid "Ref %s from %s matches more than one transaction operation"
msgstr "Ref %s de %s kongruas kun pli ol unu transakcia operacio"

#: common/flatpak-transaction.c:4581 common/flatpak-transaction.c:4591
msgid "any remote"
msgstr "Malproksima"

#: common/flatpak-transaction.c:4590
#, c-format
msgid "No transaction operation found for ref %s from %s"
msgstr "Neniu transakcia operacio trovita por ref %s de %s"

#: common/flatpak-transaction.c:4713
#, c-format
msgid "Flatpakrepo URL %s not file, HTTP or HTTPS"
msgstr "Flatpakrepo URL %s ne HTTP aŭ HTTPS"

#: common/flatpak-transaction.c:4719
#, c-format
msgid "Can't load dependent file %s: "
msgstr "Ne povas ŝargi dependan dosieron %s:"

#: common/flatpak-transaction.c:4727
#, c-format
msgid "Invalid .flatpakrepo: %s"
msgstr "Nevalida .flatpakrepo: %s"

#: common/flatpak-transaction.c:5454
msgid "Transaction already executed"
msgstr "Transakcio jam efektivigita"

#: common/flatpak-transaction.c:5469
msgid ""
"Refusing to operate on a user installation as root! This can lead to "
"incorrect file ownership and permission errors."
msgstr ""
"Rifuzo funkcii sur uzanta instalado kiel radiko! Ĉi tio povas konduki al "
"malĝusta dosierposedo kaj permesaj eraroj."

#: common/flatpak-transaction.c:5567 common/flatpak-transaction.c:5580
msgid "Aborted by user"
msgstr "Abortita de uzanto"

#: common/flatpak-transaction.c:5605
#, c-format
msgid "Skipping %s due to previous error"
msgstr "Preterpasi %s pro antaŭa eraro"

#: common/flatpak-transaction.c:5659
#, c-format
msgid "Aborted due to failure (%s)"
msgstr "Ĉesigita pro fiasko (%s)"

#: common/flatpak-uri.c:118
#, no-c-format
msgid "Invalid %-encoding in URI"
msgstr "Nevalida dbus-nomo %s"

#: common/flatpak-uri.c:135
msgid "Illegal character in URI"
msgstr "Kontraŭleĝa signo en URI"

#: common/flatpak-uri.c:169
msgid "Non-UTF-8 characters in URI"
msgstr "Ne-UTF-8-signoj en URI"

#: common/flatpak-uri.c:275
#, c-format
msgid "Invalid IPv6 address ‘%.*s’ in URI"
msgstr "Nevalida IPv6-adreso ‘%.*s’ en URI"

#: common/flatpak-uri.c:330
#, c-format
msgid "Illegal encoded IP address ‘%.*s’ in URI"
msgstr "Kontraŭleĝa kodita IP-adreso ‘%.*s’ en URI"

#: common/flatpak-uri.c:342
#, c-format
msgid "Illegal internationalized hostname ‘%.*s’ in URI"
msgstr "Kontraŭleĝa internaciigita gastiga nomo '%.*s' en URI"

#: common/flatpak-uri.c:374 common/flatpak-uri.c:386
#, c-format
msgid "Could not parse port ‘%.*s’ in URI"
msgstr "Ne eblis analizi pordon ‘%.*s’ en URI"

#: common/flatpak-uri.c:393
#, c-format
msgid "Port ‘%.*s’ in URI is out of range"
msgstr "Haveno '%.*s' en URI estas ekster intervalo"

#: common/flatpak-uri.c:910
msgid "URI is not absolute, and no base URI was provided"
msgstr "URI ne estas absoluta, kaj neniu baza URI estis disponigita"

#: common/flatpak-usb.c:83
#, c-format
msgid "USB device query 'all' must not have data"
msgstr "Demando pri USB-aparato 'ĉiuj' ne devas havi datumojn"

#: common/flatpak-usb.c:102
#, c-format
msgid "USB query rule 'cls' must be in the form CLASS:SUBCLASS or CLASS:*"
msgstr ""
"USB-demanda regulo 'cls' devas esti en la formo KLASO:SUBKLASO aŭ KLASO:*"

#: common/flatpak-usb.c:111
#, c-format
msgid "Invalid USB class"
msgstr "Nevalida USB-klaso"

#: common/flatpak-usb.c:125
#, c-format
msgid "Invalid USB subclass"
msgstr "Nevalida USB-subklaso"

#: common/flatpak-usb.c:141 common/flatpak-usb.c:148
#, c-format
msgid "USB query rule 'dev' must have a valid 4-digit hexadecimal product id"
msgstr ""
"USB-demanda regulo 'dev' devas havi validan 4-ciferan deksesuma "
"produktidentigilo"

#: common/flatpak-usb.c:164 common/flatpak-usb.c:171
#, c-format
msgid "USB query rule 'vnd' must have a valid 4-digit hexadecimal vendor id"
msgstr ""
"USB-demanda regulo 'vnd' devas havi validan 4-ciferan deksesuman vendistan "
"identigilon"

#: common/flatpak-usb.c:205
#, c-format
msgid "USB device queries must be in the form TYPE:DATA"
msgstr "Demandoj pri USB-aparatoj devas esti en la formo TYPE:DATA"

#: common/flatpak-usb.c:225
#, c-format
msgid "Unknown USB query rule %s"
msgstr "Nekonata USB-demanda regulo %s"

#: common/flatpak-usb.c:248
#, c-format
msgid "Empty USB query"
msgstr "Malplena USB-demando"

#: common/flatpak-usb.c:274
#, c-format
msgid "Multiple USB query rules of the same type is not supported"
msgstr "Multoblaj USB-demandaj reguloj de la sama tipo ne estas subtenataj"

#: common/flatpak-usb.c:283
#, c-format
msgid "'all' must not contain extra query rules"
msgstr "'ĉio' ne devas enhavi kromajn demandregulojn"

#: common/flatpak-usb.c:291
#, c-format
msgid "USB queries with 'dev' must also specify vendors"
msgstr "USB-demandoj kun 'dev' ankaŭ devas specifi vendistojn"

#: common/flatpak-utils.c:712
msgid "Glob can't match apps"
msgstr "Glob ne povas kongrui kun aplikaĵoj"

#: common/flatpak-utils.c:737
msgid "Empty glob"
msgstr "Malplena globo"

#: common/flatpak-utils.c:756
msgid "Too many segments in glob"
msgstr "Tro da segmentoj en globo"

#: common/flatpak-utils.c:777
#, c-format
msgid "Invalid glob character '%c'"
msgstr "Nevalida globa signo '%c'"

#: common/flatpak-utils.c:831
#, c-format
msgid "Missing glob on line %d"
msgstr "Mankas globo en linio %d"

#: common/flatpak-utils.c:835
#, c-format
msgid "Trailing text on line %d"
msgstr "Malantaŭa teksto en linio %d"

#: common/flatpak-utils.c:839
#, c-format
msgid "on line %d"
msgstr "en linio %d"

#: common/flatpak-utils.c:861
#, c-format
msgid "Unexpected word '%s' on line %d"
msgstr "Neatendita vorto '%s' en linio %d"

#: common/flatpak-utils.c:2118
#, c-format
msgid "Invalid require-flatpak argument %s"
msgstr "Nevalida postul-flatpak argumento %s"

#: common/flatpak-utils.c:2128 common/flatpak-utils.c:2147
#, c-format
msgid "%s needs a later flatpak version (%s)"
msgstr "%s bezonas pli postan flatpak-version (%s)"

#: oci-authenticator/flatpak-oci-authenticator.c:291
msgid "Not a oci remote, missing summary.xa.oci-repository"
msgstr "Ne oci fora, mankas summary.xa.oci-repository"

#: oci-authenticator/flatpak-oci-authenticator.c:477
msgid "Not a OCI remote"
msgstr "Ne OCI-forilo"

#: oci-authenticator/flatpak-oci-authenticator.c:488
msgid "Invalid token"
msgstr "Nevalida gpg-ŝlosilo"

#: portal/flatpak-portal.c:2292
#, c-format
msgid "No portal support found"
msgstr "Neniu resumo trovita"

#: portal/flatpak-portal.c:2298
msgid "Deny"
msgstr "Nei"

#: portal/flatpak-portal.c:2300
msgid "Update"
msgstr "ĝisdatigo"

#: portal/flatpak-portal.c:2305
#, c-format
msgid "Update %s?"
msgstr "Ĝisdatigi %s?"

#: portal/flatpak-portal.c:2317
msgid "The application wants to update itself."
msgstr "La aplikaĵo volas ĝisdatigi sin."

#: portal/flatpak-portal.c:2318
msgid "Update access can be changed any time from the privacy settings."
msgstr "Ĝisdatigita aliro povas esti ŝanĝita iam ajn de la privateca agordo."

#: portal/flatpak-portal.c:2343
#, c-format
msgid "Application update not allowed"
msgstr "Ĝisdatigo de aplikaĵo ne estas permesita"

#: portal/flatpak-portal.c:2501
#, c-format
msgid "Self update not supported, new version requires new permissions"
msgstr ""
"Mem-ĝisdatigo ne estas subtenata, nova versio postulas novajn permesojn"

#: portal/flatpak-portal.c:2684 portal/flatpak-portal.c:2702
#, c-format
msgid "Update ended unexpectedly"
msgstr "Ĝisdatigi subskribitan rultempon"

#. SECURITY:
#. - Normal users need admin authentication to install software
#. system-wide.
#. - Note that we install polkit rules that allow local users
#. in the wheel group to install without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:23
msgid "Install signed application"
msgstr "Instali subskribitan aplikaĵon"

#: system-helper/org.freedesktop.Flatpak.policy.in:24
#: system-helper/org.freedesktop.Flatpak.policy.in:42
msgid "Authentication is required to install software"
msgstr "Aŭtentikigo estas bezonata por instali programaron"

#. SECURITY:
#. - Normal users need admin authentication to install software
#. system-wide.
#. - Note that we install polkit rules that allow local users
#. in the wheel group to install without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:41
msgid "Install signed runtime"
msgstr "Instali subskribitan rultempon"

#. SECURITY:
#. - Normal users do not require admin authentication to update an
#. app as the commit will be signed, and the action is required
#. to update the system when unattended.
#. - Changing this to anything other than 'yes' will break unattended
#. updates.
#: system-helper/org.freedesktop.Flatpak.policy.in:60
msgid "Update signed application"
msgstr "Ĝisdatigi subskribitan aplikaĵon"

#: system-helper/org.freedesktop.Flatpak.policy.in:61
#: system-helper/org.freedesktop.Flatpak.policy.in:80
msgid "Authentication is required to update software"
msgstr "Aŭtentikigo estas necesa por ĝisdatigi programaron"

#. SECURITY:
#. - Normal users do not require admin authentication to update a
#. runtime as the commit will be signed, and the action is required
#. to update the system when unattended.
#. - Changing this to anything other than 'yes' will break unattended
#. updates.
#: system-helper/org.freedesktop.Flatpak.policy.in:79
msgid "Update signed runtime"
msgstr "Ĝisdatigi subskribitan rultempon"

#. SECURITY:
#. - Normal users do not need authentication to update metadata
#. from signed repositories.
#: system-helper/org.freedesktop.Flatpak.policy.in:94
msgid "Update remote metadata"
msgstr "Ĝisdatigi forajn metadatumojn"

#: system-helper/org.freedesktop.Flatpak.policy.in:95
msgid "Authentication is required to update remote info"
msgstr "Aŭtentikigo estas necesa por ĝisdatigi forajn informojn"

#. SECURITY:
#. - Normal users do not need authentication to modify the
#. OSTree repository
#. - Note that we install polkit rules that allow local users
#. in the wheel group to modify repos without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:111
msgid "Update system repository"
msgstr "Ĝisdatigi sisteman deponejon"

#: system-helper/org.freedesktop.Flatpak.policy.in:112
msgid "Authentication is required to modify a system repository"
msgstr "Aŭtentikigo estas postulata por modifi sisteman deponejon"

#. SECURITY:
#. - Normal users need admin authentication to install software
#. system-wide.
#: system-helper/org.freedesktop.Flatpak.policy.in:126
msgid "Install bundle"
msgstr "Instali pakaĵon"

#: system-helper/org.freedesktop.Flatpak.policy.in:127
msgid "Authentication is required to install software from $(path)"
msgstr "Aŭtentigo estas bezonata por instali programaron de $(pado)"

#. SECURITY:
#. - Normal users need admin authentication to uninstall software
#. system-wide.
#. - Note that we install polkit rules that allow local users
#. in the wheel group to uninstall without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:144
msgid "Uninstall runtime"
msgstr "Malinstali rultempon"

#: system-helper/org.freedesktop.Flatpak.policy.in:145
msgid "Authentication is required to uninstall software"
msgstr "Aŭtentikigo estas necesa por malinstali programaron"

#. SECURITY:
#. - Normal users need admin authentication to uninstall software
#. system-wide.
#. - Note that we install polkit rules that allow local users
#. in the wheel group to uninstall without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:161
msgid "Uninstall app"
msgstr "Malinstali la apon"

#: system-helper/org.freedesktop.Flatpak.policy.in:162
msgid "Authentication is required to uninstall $(ref)"
msgstr "Aŭtentigo estas bezonata por malinstali $(ref)"

#. SECURITY:
#. - Normal users need admin authentication to configure system-wide
#. software repositories.
#: system-helper/org.freedesktop.Flatpak.policy.in:177
msgid "Configure Remote"
msgstr "Agordi Remote"

#: system-helper/org.freedesktop.Flatpak.policy.in:178
msgid "Authentication is required to configure software repositories"
msgstr "Aŭtentikigo estas postulata por agordi programarajn deponejojn"

#. SECURITY:
#. - Normal users need admin authentication to configure the system-wide
#. Flatpak installation.
#: system-helper/org.freedesktop.Flatpak.policy.in:192
msgid "Configure"
msgstr "Agordi"

#: system-helper/org.freedesktop.Flatpak.policy.in:193
msgid "Authentication is required to configure software installation"
msgstr "Aŭtentikigo estas necesa por agordi programaran instaladon"

#. SECURITY:
#. - Normal users do not require admin authentication to update
#. appstream data as it will be signed, and the action is required
#. to update the system when unattended.
#. - Changing this to anything other than 'yes' will break unattended
#. updates.
#: system-helper/org.freedesktop.Flatpak.policy.in:210
msgid "Update appstream"
msgstr "Ĝisdatigi appstream"

#: system-helper/org.freedesktop.Flatpak.policy.in:211
msgid "Authentication is required to update information about software"
msgstr "Aŭtentikigo estas necesa por ĝisdatigi informojn pri programaro"

#. SECURITY:
#. - Normal users do not require admin authentication to update
#. metadata as it will be signed, and the action is required
#. to update the system when unattended.
#. - Changing this to anything other than 'yes' will break unattended
#. updates.
#: system-helper/org.freedesktop.Flatpak.policy.in:228
msgid "Update metadata"
msgstr "Ĝisdatigi metadatenojn"

#: system-helper/org.freedesktop.Flatpak.policy.in:229
msgid "Authentication is required to update metadata"
msgstr "Aŭtentikigo estas necesa por ĝisdatigi metadatenojn"

#. SECURITY:
#. - Authorisation to actually install software is controlled by
#. org.freedesktop.Flatpak.app-install.
#. - This action is checked after app-install, as it can only be done
#. once the app’s data (including its content rating) has been
#. downloaded.
#. - This action is checked to see if the installation should be allowed
#. based on whether the app being installed has content which doesn’t
#. comply with the user’s parental controls policy (the content is
#. ‘too extreme’).
#. - It is checked only if an app has too extreme content for the user
#. who is trying to install it (in which case, the app is ‘unsafe’).
#. - Typically, normal users will need admin permission to install apps
#. with extreme content; admins will be able to install it without
#. additional checks.
#. - In order to configure the policy so that admins can install safe and
#. unsafe software anywhere without authorisation, and non-admins can
#. install safe software in their user or system dirs without
#. authorisation, but need authorisation to install unsafe software
#. anywhere:
#. * Unconditionally return `yes` from `app-install`.
#. * Return `auth_admin` from `override-parental-controls` for users
#. not in `@privileged_group@`, and `yes` for users in it.
#. * Set the malcontent `is-{user,system}-installation-allowed`
#. properties of all non-admins’ parental controls policies to true.
#. - In order to configure the policy so that admins can install safe and
#. unsafe software anywhere without authorisation, and non-admins can
#. install safe software in their user dir without authorisation, but
#. need authorisation to install safe software in the system dir or to
#. install unsafe software anywhere:
#. * Unconditionally return `yes` from `app-install`.
#. * Return `auth_admin` from `override-parental-controls` for users
#. not in `@privileged_group@`, and `yes` for users in it.
#. * Set the malcontent `is-user-installation-allowed` property of all
#. non-admins’ parental controls policies to true.
#. * Set the malcontent `is-system-installation-allowed` property of
#. all non-admins’ parental controls policies to false.
#. - In order to configure the policy so that all users (including
#. admins) can install safe software anywhere without authorisation,
#. but need authorisation to install unsafe software anywhere (i.e.
#. applying parental controls to admins too):
#. * Unconditionally return `yes` from `app-install`.
#. * Unconditionally return `auth_admin` from `override-parental-controls`.
#. * Set the malcontent `is-user-installation-allowed` property of all
#. users’ parental controls policies to true.
#. * Set the malcontent `is-system-installation-allowed` property of
#. all users’ parental controls policies to true.
#: system-helper/org.freedesktop.Flatpak.policy.in:287
msgid "Override parental controls for installs"
msgstr "Anstataŭigi gepatrajn kontrolojn por instaloj"

#: system-helper/org.freedesktop.Flatpak.policy.in:288
msgid ""
"Authentication is required to install software which is restricted by your "
"parental controls policy"
msgstr "Aŭtentigo estas bezonata por instali programaron de $(pado)"

#. SECURITY:
#. - This is like org.freedesktop.Flatpak.override-parental-controls, but
#. it’s queried for app updates, whereas the former is queried for app
#. installs.
#. - As with the above action, this one is only queried if
#. org.freedesktop.Flatpak.app-update has allowed the app update, and
#. only if the app being updated has too extreme content for the user
#. who is trying to update it.
#. - The default policy for this is to *allow* updates to ‘too extreme’
#. apps by default, on the basis that having an out-of-date (i.e.
#. insecure or unsupported) app is a worse outcome than automatically
#. installing an update which has radically different content from the
#. version of the app which the parent originally vetted and installed.
#: system-helper/org.freedesktop.Flatpak.policy.in:313
msgid "Override parental controls for updates"
msgstr "Anstataŭigi gepatrajn kontrolojn por ĝisdatigoj"

#: system-helper/org.freedesktop.Flatpak.policy.in:314
msgid ""
"Authentication is required to update software which is restricted by your "
"parental controls policy"
msgstr "Aŭtentigo estas bezonata por instali programaron de $(pado)"

===== ./po/zh_CN.po =====
# Chinese (China) translation for flatpak.
# Copyright (C) 2021 flatpak's COPYRIGHT HOLDER
# This file is distributed under the same license as the flatpak package.
# lumingzh <lumingzh@qq.com>, 2021-2026.
#
msgid ""
msgstr ""
"Project-Id-Version: flatpak master\n"
"Report-Msgid-Bugs-To: https://github.com/flatpak/flatpak/issues\n"
"POT-Creation-Date: 2026-05-27 16:39+0200\n"
"PO-Revision-Date: 2026-05-26 09:21+0800\n"
"Last-Translator: lumingzh <lumingzh@qq.com>\n"
"Language-Team: Chinese (China) <i18n-zh@googlegroups.com>\n"
"Language: zh_CN\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
"X-Generator: Gtranslator 50.0\n"

#: app/flatpak-builtins-build-bundle.c:59
msgid "Export runtime instead of app"
msgstr "导出运行时而不是应用"

#: app/flatpak-builtins-build-bundle.c:60
msgid "Arch to bundle for"
msgstr "要打包的架构"

#: app/flatpak-builtins-build-bundle.c:60
#: app/flatpak-builtins-build-export.c:62 app/flatpak-builtins-build-init.c:53
#: app/flatpak-builtins-build-sign.c:42 app/flatpak-builtins-create-usb.c:46
#: app/flatpak-builtins-info.c:55 app/flatpak-builtins-install.c:67
#: app/flatpak-builtins-list.c:50 app/flatpak-builtins-make-current.c:38
#: app/flatpak-builtins-remote-info.c:54 app/flatpak-builtins-remote-ls.c:56
#: app/flatpak-builtins-run.c:158 app/flatpak-builtins-search.c:37
#: app/flatpak-builtins-uninstall.c:54 app/flatpak-builtins-update.c:56
msgid "ARCH"
msgstr "架构"

#: app/flatpak-builtins-build-bundle.c:61
msgid "URL for repo"
msgstr "仓库网址"

#: app/flatpak-builtins-build-bundle.c:61
#: app/flatpak-builtins-build-bundle.c:62
#: app/flatpak-builtins-build-update-repo.c:68
#: app/flatpak-builtins-build-update-repo.c:72
#: app/flatpak-builtins-build-update-repo.c:73
#: app/flatpak-builtins-history.c:69 app/flatpak-builtins-remote-add.c:80
#: app/flatpak-builtins-remote-add.c:81 app/flatpak-builtins-remote-add.c:85
#: app/flatpak-builtins-remote-list.c:53
#: app/flatpak-builtins-remote-modify.c:70
#: app/flatpak-builtins-remote-modify.c:85
#: app/flatpak-builtins-remote-modify.c:86
#: app/flatpak-builtins-remote-modify.c:90
msgid "URL"
msgstr "网址"

#: app/flatpak-builtins-build-bundle.c:62
msgid "URL for runtime flatpakrepo file"
msgstr "运行时 flatpakrepo 文件的网址"

#: app/flatpak-builtins-build-bundle.c:63
msgid "Add GPG key from FILE (- for stdin)"
msgstr "从文件添加 GPG 密钥（- 用于 stdin）"

#: app/flatpak-builtins-build-bundle.c:63 app/flatpak-builtins-build.c:54
#: app/flatpak-builtins-build-export.c:67
#: app/flatpak-builtins-build-update-repo.c:83
#: app/flatpak-builtins-install.c:81 app/flatpak-builtins-remote-add.c:84
#: app/flatpak-builtins-remote-add.c:86 app/flatpak-builtins-remote-modify.c:89
#: app/flatpak-builtins-remote-modify.c:92
msgid "FILE"
msgstr "文件"

#: app/flatpak-builtins-build-bundle.c:64
msgid "GPG Key ID to sign the OCI image with"
msgstr "签名 OCI 映像使用的 GPG 密钥身份标识"

#: app/flatpak-builtins-build-bundle.c:64
#: app/flatpak-builtins-build-commit-from.c:68
#: app/flatpak-builtins-build-export.c:68
#: app/flatpak-builtins-build-import-bundle.c:49
#: app/flatpak-builtins-build-sign.c:44
#: app/flatpak-builtins-build-update-repo.c:84
msgid "KEY-ID"
msgstr "KEY-ID"

#: app/flatpak-builtins-build-bundle.c:65
#: app/flatpak-builtins-build-commit-from.c:69
#: app/flatpak-builtins-build-export.c:71
#: app/flatpak-builtins-build-import-bundle.c:50
#: app/flatpak-builtins-build-sign.c:45
#: app/flatpak-builtins-build-update-repo.c:85
msgid "GPG Homedir to use when looking for keyrings"
msgstr "查找密钥环时使用的 GPG 主目录"

#: app/flatpak-builtins-build-bundle.c:65
#: app/flatpak-builtins-build-commit-from.c:69
#: app/flatpak-builtins-build-export.c:71
#: app/flatpak-builtins-build-import-bundle.c:50
#: app/flatpak-builtins-build-sign.c:45
#: app/flatpak-builtins-build-update-repo.c:85
msgid "HOMEDIR"
msgstr "主目录"

#: app/flatpak-builtins-build-bundle.c:66
msgid "OSTree commit to create a delta bundle from"
msgstr "创建增量包使用的 OSTree 提交"

#: app/flatpak-builtins-build-bundle.c:66 app/flatpak-builtins-remote-info.c:55
#: app/flatpak-builtins-update.c:57
msgid "COMMIT"
msgstr "提交"

#: app/flatpak-builtins-build-bundle.c:67
msgid "Export oci image instead of flatpak bundle"
msgstr "导出 OCI 映像而不是 flatpak 捆绑包"

#: app/flatpak-builtins-build-bundle.c:70
msgid "How to compress OCI image layers (default: gzip)"
msgstr "压缩 OCI 映像层的方式（默认：gzip）"

#: app/flatpak-builtins-build-bundle.c:634
msgid ""
"LOCATION FILENAME NAME [BRANCH] - Create a single file bundle from a local "
"repository"
msgstr "位置 文件名 名称 [分支] - 从本地仓库创建单文件捆绑包"

#: app/flatpak-builtins-build-bundle.c:641
msgid "LOCATION, FILENAME and NAME must be specified"
msgstr "必须指定位置、文件名和名称"

#: app/flatpak-builtins-build-bundle.c:644
#: app/flatpak-builtins-build-export.c:844
#: app/flatpak-builtins-build-import-bundle.c:136
#: app/flatpak-builtins-build-init.c:217 app/flatpak-builtins-build-sign.c:76
#: app/flatpak-builtins-document-export.c:112
#: app/flatpak-builtins-document-info.c:75
#: app/flatpak-builtins-document-list.c:191
#: app/flatpak-builtins-document-unexport.c:70
#: app/flatpak-builtins-history.c:482 app/flatpak-builtins-info.c:130
#: app/flatpak-builtins-install.c:181 app/flatpak-builtins-install.c:234
#: app/flatpak-builtins-install.c:298 app/flatpak-builtins-list.c:419
#: app/flatpak-builtins-make-current.c:72 app/flatpak-builtins-override.c:73
#: app/flatpak-builtins-permission-list.c:162
#: app/flatpak-builtins-permission-remove.c:132
#: app/flatpak-builtins-remote-add.c:323
#: app/flatpak-builtins-remote-delete.c:68
#: app/flatpak-builtins-remote-list.c:241 app/flatpak-builtins-remote-ls.c:407
msgid "Too many arguments"
msgstr "参数太多"

#: app/flatpak-builtins-build-bundle.c:659
#: app/flatpak-builtins-build-commit-from.c:338
#: app/flatpak-builtins-build-commit-from.c:351
#: app/flatpak-builtins-build-import-bundle.c:145
#, c-format
msgid "'%s' is not a valid repository"
msgstr "“%s”不是有效的仓库"

#: app/flatpak-builtins-build-bundle.c:663
#, c-format
msgid "'%s' is not a valid repository: "
msgstr "“%s”不是有效的仓库："

#: app/flatpak-builtins-build-bundle.c:674 app/flatpak-builtins-build-sign.c:88
#: common/flatpak-dir.c:14293
#, c-format
msgid "'%s' is not a valid name: %s"
msgstr "“%s”不是有效的名称：%s"

#: app/flatpak-builtins-build-bundle.c:677
#: app/flatpak-builtins-build-export.c:865 app/flatpak-builtins-build-sign.c:91
#: common/flatpak-dir.c:14299
#, c-format
msgid "'%s' is not a valid branch name: %s"
msgstr "“%s”不是有效的分支名称：%s"

#: app/flatpak-builtins-build-bundle.c:691
#: app/flatpak-builtins-build-import-bundle.c:149
#: app/flatpak-builtins-build-init.c:281
#, c-format
msgid "'%s' is not a valid filename"
msgstr "“%s”不是有效的文件名"

#: app/flatpak-builtins-build-bundle.c:706
msgid "--oci-layer-compress value must be gzip or zstd"
msgstr "--oci-layer-compress 的值必须为 gzip 或 zstd"

#: app/flatpak-builtins-build.c:49
msgid "Use Platform runtime rather than Sdk"
msgstr "使用平台运行时而不是 SDK"

#: app/flatpak-builtins-build.c:50
msgid "Make destination readonly"
msgstr "使目标只读"

#: app/flatpak-builtins-build.c:51
msgid "Add bind mount"
msgstr "添加绑定挂载"

#: app/flatpak-builtins-build.c:51
msgid "DEST=SRC"
msgstr "DEST=SRC"

#: app/flatpak-builtins-build.c:52
msgid "Start build in this directory"
msgstr "在该目录开始构建"

#: app/flatpak-builtins-build.c:52 app/flatpak-builtins-build.c:53
#: app/flatpak-builtins-build-init.c:64 app/flatpak-builtins-run.c:160
msgid "DIR"
msgstr "目录"

#: app/flatpak-builtins-build.c:53
msgid "Where to look for custom sdk dir (defaults to 'usr')"
msgstr "在哪里查找自定义 SDK 目录（默认“usr”）"

#: app/flatpak-builtins-build.c:54 app/flatpak-builtins-build-export.c:67
msgid "Use alternative file for the metadata"
msgstr "为元数据使用替代文件"

#: app/flatpak-builtins-build.c:55 app/flatpak-builtins-run.c:177
msgid "Kill processes when the parent process dies"
msgstr "父进程死亡时杀死进程"

#: app/flatpak-builtins-build.c:56
msgid "Export application homedir directory to build"
msgstr "导出应用主目录以构建"

#: app/flatpak-builtins-build.c:57 app/flatpak-builtins-run.c:165
msgid "Log session bus calls"
msgstr "日志会话总线调用"

#: app/flatpak-builtins-build.c:58 app/flatpak-builtins-run.c:166
msgid "Log system bus calls"
msgstr "日志系统总线调用"

#: app/flatpak-builtins-build.c:262
msgid "DIRECTORY [COMMAND [ARGUMENT…]] - Build in directory"
msgstr "目录 [命令 [参数…]] - 在目录中构建"

#: app/flatpak-builtins-build.c:285 app/flatpak-builtins-build-finish.c:656
msgid "DIRECTORY must be specified"
msgstr "必须指定目录"

#: app/flatpak-builtins-build.c:296 app/flatpak-builtins-build-export.c:887
#, c-format
msgid "Build directory %s not initialized, use flatpak build-init"
msgstr "构建目录 %s 未初始化，使用 flatpak build-init"

#: app/flatpak-builtins-build.c:315
msgid "metadata invalid, not application or runtime"
msgstr "元数据无效，不是应用或运行时"

#: app/flatpak-builtins-build.c:446
#, c-format
msgid "No extension point matching %s in %s"
msgstr "在 %2$s 中没有匹配 %1$s 的扩展点"

#: app/flatpak-builtins-build.c:635
#, c-format
msgid "Missing '=' in bind mount option '%s'"
msgstr "在绑定挂载选项“%s”中缺少“=”"

#: app/flatpak-builtins-build.c:679 common/flatpak-run.c:3961
#, c-format
msgid "Unable to start app"
msgstr "无法启动应用"

#: app/flatpak-builtins-build-commit-from.c:58
msgid "Source repo dir"
msgstr "源仓库目录"

#: app/flatpak-builtins-build-commit-from.c:58
msgid "SRC-REPO"
msgstr "SRC-REPO"

#: app/flatpak-builtins-build-commit-from.c:59
msgid "Source repo ref"
msgstr "源仓库引用"

#: app/flatpak-builtins-build-commit-from.c:59
msgid "SRC-REF"
msgstr "SRC-REF"

#: app/flatpak-builtins-build-commit-from.c:64
#: app/flatpak-builtins-build-export.c:60
msgid "One line subject"
msgstr "单行主题"

#: app/flatpak-builtins-build-commit-from.c:64
#: app/flatpak-builtins-build-export.c:60
msgid "SUBJECT"
msgstr "主题"

#: app/flatpak-builtins-build-commit-from.c:65
#: app/flatpak-builtins-build-export.c:61
msgid "Full description"
msgstr "完整描述"

#: app/flatpak-builtins-build-commit-from.c:65
#: app/flatpak-builtins-build-export.c:61
msgid "BODY"
msgstr "正文"

#: app/flatpak-builtins-build-commit-from.c:66
#: app/flatpak-builtins-build-export.c:64
#: app/flatpak-builtins-build-import-bundle.c:51
msgid "Update the appstream branch"
msgstr "更新 appstream 分支"

#: app/flatpak-builtins-build-commit-from.c:67
#: app/flatpak-builtins-build-export.c:65
#: app/flatpak-builtins-build-import-bundle.c:52
#: app/flatpak-builtins-build-update-repo.c:87
msgid "Don't update the summary"
msgstr "不更新摘要"

#: app/flatpak-builtins-build-commit-from.c:68
#: app/flatpak-builtins-build-export.c:68
#: app/flatpak-builtins-build-import-bundle.c:49
#: app/flatpak-builtins-build-sign.c:44
msgid "GPG Key ID to sign the commit with"
msgstr "签署提交时使用的 GPG 密钥身份标识"

#: app/flatpak-builtins-build-commit-from.c:70
#: app/flatpak-builtins-build-export.c:73
msgid "Mark build as end-of-life"
msgstr "将构建标记为寿命完结"

#: app/flatpak-builtins-build-commit-from.c:70
#: app/flatpak-builtins-build-export.c:73
msgid "REASON"
msgstr "原因"

#: app/flatpak-builtins-build-commit-from.c:71
msgid ""
"Mark refs matching the OLDID prefix as end-of-life, to be replaced with the "
"given NEWID"
msgstr "将匹配旧身份标识的引用标记为寿命完结，使用给定的新身份标识进行替换"

#: app/flatpak-builtins-build-commit-from.c:71
msgid "OLDID=NEWID"
msgstr "OLDID=NEWID"

#: app/flatpak-builtins-build-commit-from.c:72
#: app/flatpak-builtins-build-export.c:75
msgid "Set type of token needed to install this commit"
msgstr "设置安装该提交需要的令牌类型"

#: app/flatpak-builtins-build-commit-from.c:72
#: app/flatpak-builtins-build-export.c:75
msgid "VAL"
msgstr "值"

#: app/flatpak-builtins-build-commit-from.c:73
msgid "Override the timestamp of the commit (NOW for current time)"
msgstr "覆盖提交的时间戳（NOW 为当前时间）"

#: app/flatpak-builtins-build-commit-from.c:73
#: app/flatpak-builtins-build-export.c:76
msgid "TIMESTAMP"
msgstr "时间戳"

#: app/flatpak-builtins-build-commit-from.c:75
#: app/flatpak-builtins-build-export.c:80
#: app/flatpak-builtins-build-import-bundle.c:53
#: app/flatpak-builtins-build-update-repo.c:97
msgid "Don't generate a summary index"
msgstr "不生成摘要索引"

#: app/flatpak-builtins-build-commit-from.c:278
msgid "DST-REPO [DST-REF…] - Make a new commit from existing commits"
msgstr "DST-REPO [DST-REF…] - 从现有提交中创建新提交"

#: app/flatpak-builtins-build-commit-from.c:285
msgid "DST-REPO must be specified"
msgstr "必须指定 DST-REPO"

#: app/flatpak-builtins-build-commit-from.c:293
msgid ""
"If --src-repo is not specified, exactly one destination ref must be specified"
msgstr "如果 --src-repo 没有指定，则必须指定绝对的目标引用"

#: app/flatpak-builtins-build-commit-from.c:296
msgid ""
"If --src-ref is specified, exactly one destination ref must be specified"
msgstr "如果 --src-ref 没有指定，则必须指定绝对的目标引用"

#: app/flatpak-builtins-build-commit-from.c:299
msgid "Either --src-repo or --src-ref must be specified"
msgstr "必须指定 --src-repo 或 --src-ref"

#: app/flatpak-builtins-build-commit-from.c:315
msgid "Invalid argument format of use  --end-of-life-rebase=OLDID=NEWID"
msgstr "无效的参数使用格式 --end-of-life-rebase=OLDID=NEWID"

#: app/flatpak-builtins-build-commit-from.c:321
#: app/flatpak-builtins-build-commit-from.c:324
#, c-format
msgid "Invalid name %s in --end-of-life-rebase"
msgstr "--end-of-life-rebase 中存在无效名称 %s"

#: app/flatpak-builtins-build-commit-from.c:333
#: app/flatpak-builtins-build-export.c:1092
#, c-format
msgid "Could not parse '%s'"
msgstr "无法解析“%s”"

#: app/flatpak-builtins-build-commit-from.c:498
msgid "Can't commit from partial source commit"
msgstr "无法从部分源记录中提交"

#: app/flatpak-builtins-build-commit-from.c:503
#, c-format
msgid "%s: no change\n"
msgstr "%s：无变化\n"

#: app/flatpak-builtins-build-export.c:62
msgid "Architecture to export for (must be host compatible)"
msgstr "要导出的架构（必须与主机兼容）"

#: app/flatpak-builtins-build-export.c:63
msgid "Commit runtime (/usr), not /app"
msgstr "提交运行时（/usr），不是 /app"

#: app/flatpak-builtins-build-export.c:66
msgid "Use alternative directory for the files"
msgstr "为文件使用替代目录"

#: app/flatpak-builtins-build-export.c:66
msgid "SUBDIR"
msgstr "子目录"

#: app/flatpak-builtins-build-export.c:69
msgid "Files to exclude"
msgstr "要排除的文件"

#: app/flatpak-builtins-build-export.c:69
#: app/flatpak-builtins-build-export.c:70
#: app/flatpak-builtins-build-update-repo.c:90
msgid "PATTERN"
msgstr "匹配模式"

#: app/flatpak-builtins-build-export.c:70
msgid "Excluded files to include"
msgstr "要包含的排除文件"

#: app/flatpak-builtins-build-export.c:74
msgid "Mark build as end-of-life, to be replaced with the given ID"
msgstr "将构建标记为寿命完结，使用给定的身份标识进行替换"

#: app/flatpak-builtins-build-export.c:74
#: app/flatpak-builtins-document-list.c:49 app/flatpak-cli-transaction.c:1427
msgid "ID"
msgstr "ID"

#: app/flatpak-builtins-build-export.c:76
msgid "Override the timestamp of the commit"
msgstr "覆盖提交的时间戳"

#: app/flatpak-builtins-build-export.c:77
#: app/flatpak-builtins-build-update-repo.c:75
#: app/flatpak-builtins-remote-add.c:83 app/flatpak-builtins-remote-list.c:54
#: app/flatpak-builtins-remote-modify.c:88
msgid "Collection ID"
msgstr "集合标识"

#: app/flatpak-builtins-build-export.c:472
#, c-format
msgid "WARNING: Error running desktop-file-validate: %s\n"
msgstr "警告：运行 desktop-file-validate 时出错：%s\n"

#: app/flatpak-builtins-build-export.c:480
#, c-format
msgid "WARNING: Error reading from desktop-file-validate: %s\n"
msgstr "警告：从 desktop-file-validate 读取时出错：%s\n"

#: app/flatpak-builtins-build-export.c:486
#, c-format
msgid "WARNING: Failed to validate desktop file %s: %s\n"
msgstr "警告：校验桌面文件 %s 时失败：%s\n"

#: app/flatpak-builtins-build-export.c:513
#, c-format
msgid "WARNING: Can't find Exec key in %s: %s\n"
msgstr "警告：在 %s 中无法找到运行密钥：%s\n"

#: app/flatpak-builtins-build-export.c:521
#: app/flatpak-builtins-build-export.c:614
#, c-format
msgid "WARNING: Binary not found for Exec line in %s: %s\n"
msgstr "警告：在 %s 中未找到要运行的二进制文件：%s\n"

#: app/flatpak-builtins-build-export.c:529
#, c-format
msgid "WARNING: Icon not matching app id in %s: %s\n"
msgstr "警告：图标与 %s 中的应用标识不匹配：%s\n"

#: app/flatpak-builtins-build-export.c:552
#, c-format
msgid "WARNING: Icon referenced in desktop file but not exported: %s\n"
msgstr "警告：桌面文件中引用的图标未导出：%s\n"

#: app/flatpak-builtins-build-export.c:719
#, c-format
msgid "Invalid uri type %s, only http/https supported"
msgstr "无效的网址类型 %s，仅支持 http/https"

#: app/flatpak-builtins-build-export.c:737
#, c-format
msgid "Unable to find basename in %s, specify a name explicitly"
msgstr "在 %s 中找不到基本名称，请明确指定名称"

#: app/flatpak-builtins-build-export.c:746
#, c-format
msgid "No slashes allowed in extra data name"
msgstr "在额外数据名称中不允许有斜线符号"

#: app/flatpak-builtins-build-export.c:758
#, c-format
msgid "Invalid format for sha256 checksum: '%s'"
msgstr "SHA256 校验和的格式无效：“%s”"

#: app/flatpak-builtins-build-export.c:768
#, c-format
msgid "Extra data sizes of zero not supported"
msgstr "不支持零的额外数据大小"

#: app/flatpak-builtins-build-export.c:830
msgid ""
"LOCATION DIRECTORY [BRANCH] - Create a repository from a build directory"
msgstr "位置 目录 [分支] - 从构建目录创建仓库"

#: app/flatpak-builtins-build-export.c:838
msgid "LOCATION and DIRECTORY must be specified"
msgstr "必须指定位置和目录"

#: app/flatpak-builtins-build-export.c:859
#: app/flatpak-builtins-remote-add.c:327
#, c-format
msgid "‘%s’ is not a valid collection ID: %s"
msgstr "“%s”不是有效的集合标识：%s"

#: app/flatpak-builtins-build-export.c:904
#: app/flatpak-builtins-build-finish.c:684
msgid "No name specified in the metadata"
msgstr "在元数据中未指定名称"

#: app/flatpak-builtins-build-export.c:1166
#, c-format
msgid "Commit: %s\n"
msgstr "提交：%s\n"

#: app/flatpak-builtins-build-export.c:1167
#, c-format
msgid "Metadata Total: %u\n"
msgstr "元数据总计：%u\n"

#: app/flatpak-builtins-build-export.c:1168
#, c-format
msgid "Metadata Written: %u\n"
msgstr "写入的元数据：%u\n"

#: app/flatpak-builtins-build-export.c:1169
#, c-format
msgid "Content Total: %u\n"
msgstr "内容总计：%u\n"

#: app/flatpak-builtins-build-export.c:1170
#, c-format
msgid "Content Written: %u\n"
msgstr "写入内容：%u\n"

#: app/flatpak-builtins-build-export.c:1171
#, c-format
msgid "Content Bytes Written:"
msgstr "写入内容字节："

#: app/flatpak-builtins-build-finish.c:52
msgid "Command to set"
msgstr "要设置的命令"

#: app/flatpak-builtins-build-finish.c:52 app/flatpak-builtins-run.c:159
#: app/flatpak-main.c:209
msgid "COMMAND"
msgstr "命令"

#: app/flatpak-builtins-build-finish.c:53
msgid "Flatpak version to require"
msgstr "Flatpak 版本要求"

#: app/flatpak-builtins-build-finish.c:53
msgid "MAJOR.MINOR.MICRO"
msgstr "MAJOR.MINOR.MICRO"

#: app/flatpak-builtins-build-finish.c:54
msgid "Don't process exports"
msgstr "不处理导出"

#: app/flatpak-builtins-build-finish.c:55
msgid "Extra data info"
msgstr "额外数据信息"

#: app/flatpak-builtins-build-finish.c:56 app/flatpak-builtins-build-init.c:63
msgid "Add extension point info"
msgstr "添加扩展点信息"

#: app/flatpak-builtins-build-finish.c:56 app/flatpak-builtins-build-init.c:63
msgid "NAME=VARIABLE[=VALUE]"
msgstr "NAME=VARIABLE[=VALUE]"

#: app/flatpak-builtins-build-finish.c:57
msgid "Remove extension point info"
msgstr "移除扩展点信息"

#: app/flatpak-builtins-build-finish.c:57
#: app/flatpak-builtins-build-update-repo.c:79 app/flatpak-builtins-info.c:58
#: app/flatpak-builtins-remote-add.c:88 app/flatpak-builtins-remote-modify.c:94
#: app/flatpak-main.c:182
msgid "NAME"
msgstr "名称"

#: app/flatpak-builtins-build-finish.c:58
msgid "Set extension priority (only for extensions)"
msgstr "设置扩展优先级（仅用于扩展）"

#: app/flatpak-builtins-build-finish.c:58
msgid "VALUE"
msgstr "值"

#: app/flatpak-builtins-build-finish.c:59
msgid "Change the sdk used for the app"
msgstr "更改用于应用的 SDK"

#: app/flatpak-builtins-build-finish.c:59
msgid "SDK"
msgstr "SDK"

#: app/flatpak-builtins-build-finish.c:60
msgid "Change the runtime used for the app"
msgstr "更改用于应用的运行时"

#: app/flatpak-builtins-build-finish.c:60 app/flatpak-builtins-build-init.c:54
#: app/flatpak-builtins-list.c:53 app/flatpak-builtins-remote-ls.c:58
#: app/flatpak-builtins-run.c:163
msgid "RUNTIME"
msgstr "运行时"

#: app/flatpak-builtins-build-finish.c:61
msgid "Set generic metadata option"
msgstr "设置常规元数据选项"

#: app/flatpak-builtins-build-finish.c:61
msgid "GROUP=KEY[=VALUE]"
msgstr "组=密钥[=值]"

#: app/flatpak-builtins-build-finish.c:62
msgid "Don't inherit permissions from runtime"
msgstr "不要从运行时继承权限"

#: app/flatpak-builtins-build-finish.c:155
#, c-format
msgid "Not exporting %s, wrong extension\n"
msgstr ""
"无法导出 %s，扩展错误\n"
"\n"

#: app/flatpak-builtins-build-finish.c:163
#, c-format
msgid "Not exporting %s, non-allowed export filename\n"
msgstr "无法导出 %s，不允许的导出文件名\n"

#: app/flatpak-builtins-build-finish.c:167
#, c-format
msgid "Exporting %s\n"
msgstr "正在导出 %s\n"

#: app/flatpak-builtins-build-finish.c:440
#, c-format
msgid "More than one executable found\n"
msgstr "找到多个可执行文件\n"

#: app/flatpak-builtins-build-finish.c:451
#, c-format
msgid "Using %s as command\n"
msgstr "使用 %s 作为命令\n"

#: app/flatpak-builtins-build-finish.c:456
#, c-format
msgid "No executable found\n"
msgstr "未发现可执行文件\n"

#: app/flatpak-builtins-build-finish.c:511
#, c-format
msgid "Invalid --require-version argument: %s"
msgstr "无效的 --require-version 参数：%s"

#: app/flatpak-builtins-build-finish.c:543
#, c-format
msgid "Too few elements in --extra-data argument %s"
msgstr "--extra-data 参数 %s 中的元素太少"

#: app/flatpak-builtins-build-finish.c:575
#, c-format
msgid ""
"Too few elements in --metadata argument %s, format should be "
"GROUP=KEY[=VALUE]]"
msgstr "--metadata 参数 %s 中的元素太少，格式应为：组=密钥[=值]"

#: app/flatpak-builtins-build-finish.c:597
#: app/flatpak-builtins-build-init.c:458
#, c-format
msgid ""
"Too few elements in --extension argument %s, format should be "
"NAME=VAR[=VALUE]"
msgstr "--extension 参数 %s 中的元素太少，格式应为：名称=变量[=值]"

#: app/flatpak-builtins-build-finish.c:603
#: app/flatpak-builtins-build-init.c:461
#, c-format
msgid "Invalid extension name %s"
msgstr "无效的扩展名称 %s"

#: app/flatpak-builtins-build-finish.c:646
msgid "DIRECTORY - Finalize a build directory"
msgstr "目录 - 完成构建目录"

#: app/flatpak-builtins-build-finish.c:668
#, c-format
msgid "Build directory %s not initialized"
msgstr "构建目录 %s 未初始化"

#: app/flatpak-builtins-build-finish.c:689
#, c-format
msgid "Build directory %s already finalized"
msgstr "构建目录 %s 已完成"

#: app/flatpak-builtins-build-finish.c:702
#, c-format
msgid "Please review the exported files and the metadata\n"
msgstr "请审阅导出的文件和元数据\n"

#: app/flatpak-builtins-build-import-bundle.c:47
msgid "Override the ref used for the imported bundle"
msgstr "覆盖用于导入包的引用"

#: app/flatpak-builtins-build-import-bundle.c:47
msgid "REF"
msgstr "引用"

#: app/flatpak-builtins-build-import-bundle.c:48
msgid "Import oci image instead of flatpak bundle"
msgstr "导入 OCI 映像而不是 flatpak 捆绑包"

#: app/flatpak-builtins-build-import-bundle.c:77
#: app/flatpak-builtins-build-import-bundle.c:105
#, c-format
msgid "Importing %s (%s)\n"
msgstr "正在导入 %s（%s）\n"

#: app/flatpak-builtins-build-import-bundle.c:126
msgid "LOCATION FILENAME - Import a file bundle into a local repository"
msgstr "位置 文件名 - 导入文件捆绑包至本地仓库"

#: app/flatpak-builtins-build-import-bundle.c:133
msgid "LOCATION and FILENAME must be specified"
msgstr "必须指定位置和文件名"

#: app/flatpak-builtins-build-init.c:53 app/flatpak-builtins-info.c:55
#: app/flatpak-builtins-run.c:158
msgid "Arch to use"
msgstr "要使用的架构"

#: app/flatpak-builtins-build-init.c:54
msgid "Initialize var from named runtime"
msgstr "从已命名的运行时初始化变量"

#: app/flatpak-builtins-build-init.c:55
msgid "Initialize apps from named app"
msgstr "从已命名的应用初始化应用"

#: app/flatpak-builtins-build-init.c:55
msgid "APP"
msgstr "应用"

#: app/flatpak-builtins-build-init.c:56
msgid "Specify version for --base"
msgstr "为 --base 指定版本"

#: app/flatpak-builtins-build-init.c:56 app/flatpak-builtins-run.c:164
msgid "VERSION"
msgstr "版本"

#: app/flatpak-builtins-build-init.c:57
msgid "Include this base extension"
msgstr "包含该基础扩展"

#: app/flatpak-builtins-build-init.c:57 app/flatpak-builtins-build-init.c:62
msgid "EXTENSION"
msgstr "扩展"

#: app/flatpak-builtins-build-init.c:58
msgid "Extension tag to use if building extension"
msgstr "构建扩展时使用的扩展标签"

#: app/flatpak-builtins-build-init.c:58
msgid "EXTENSION_TAG"
msgstr "EXTENSION_TAG"

#: app/flatpak-builtins-build-init.c:59
msgid "Initialize /usr with a writable copy of the sdk"
msgstr "使用 SDK 的可写副本初始化 /usr"

#: app/flatpak-builtins-build-init.c:60
msgid "Specify the build type (app, runtime, extension)"
msgstr "指定构建类型（app, runtime, extension）"

#: app/flatpak-builtins-build-init.c:60
msgid "TYPE"
msgstr "类型"

#: app/flatpak-builtins-build-init.c:61
msgid "Add a tag"
msgstr "添加标签"

#: app/flatpak-builtins-build-init.c:61
msgid "TAG"
msgstr "标签"

#: app/flatpak-builtins-build-init.c:62
msgid "Include this sdk extension in /usr"
msgstr "在 /usr 中包含该 SDK 扩展"

#: app/flatpak-builtins-build-init.c:64
msgid "Where to store sdk (defaults to 'usr')"
msgstr "在哪里存储 SDK（默认“usr”）"

#: app/flatpak-builtins-build-init.c:65
msgid "Re-initialize the sdk/var"
msgstr "重新初始化 SDK/变量"

#: app/flatpak-builtins-build-init.c:118
#, c-format
msgid "Requested extension %s/%s/%s is only partially installed"
msgstr "请求的扩展 %s/%s/%s 仅安装了部分"

#: app/flatpak-builtins-build-init.c:147
#, c-format
msgid "Requested extension %s/%s/%s not installed"
msgstr "请求的扩展 %s/%s/%s 未安装"

#: app/flatpak-builtins-build-init.c:207
msgid ""
"DIRECTORY APPNAME SDK RUNTIME [BRANCH] - Initialize a directory for building"
msgstr "目录 应用名称 SDK 运行时 [分支] - 为构建初始化目录"

#: app/flatpak-builtins-build-init.c:214
msgid "RUNTIME must be specified"
msgstr "必须指定运行时"

#: app/flatpak-builtins-build-init.c:235
#, c-format
msgid "'%s' is not a valid build type name, use app, runtime or extension"
msgstr "“%s”不是有效的构建类型名称，使用 app, runtime 或 extension"

#: app/flatpak-builtins-build-init.c:241 app/flatpak-builtins-override.c:79
#, c-format
msgid "'%s' is not a valid application name: %s"
msgstr "“%s”不是有效的应用名称：%s"

#: app/flatpak-builtins-build-init.c:295
#, c-format
msgid "Build directory %s already initialized"
msgstr "构建目录 %s 已初始化"

#: app/flatpak-builtins-build-sign.c:42 app/flatpak-builtins-install.c:67
#: app/flatpak-builtins-remote-info.c:54
msgid "Arch to install for"
msgstr "安装目标的架构"

#: app/flatpak-builtins-build-sign.c:43 app/flatpak-builtins-create-usb.c:48
#: app/flatpak-builtins-install.c:74 app/flatpak-builtins-remote-info.c:56
#: app/flatpak-builtins-uninstall.c:58 app/flatpak-builtins-update.c:64
msgid "Look for runtime with the specified name"
msgstr "使用指定名称查找运行时"

#: app/flatpak-builtins-build-sign.c:66
msgid "LOCATION [ID [BRANCH]] - Sign an application or runtime"
msgstr "位置 [身份标识 [分支]] - 签名应用或运行时"

#: app/flatpak-builtins-build-sign.c:73
#: app/flatpak-builtins-build-update-repo.c:499
#: app/flatpak-builtins-remote-add.c:320 app/flatpak-builtins-repo.c:739
msgid "LOCATION must be specified"
msgstr "必须指定位置"

#: app/flatpak-builtins-build-sign.c:94
msgid "No gpg key ids specified"
msgstr "未指定 GPG 密钥身份标识"

#: app/flatpak-builtins-build-update-repo.c:68
msgid "Redirect this repo to a new URL"
msgstr "将该仓库重定向至新网址"

#: app/flatpak-builtins-build-update-repo.c:69
msgid "A nice name to use for this repository"
msgstr "用于该仓库的好名字"

#: app/flatpak-builtins-build-update-repo.c:69
#: app/flatpak-builtins-remote-add.c:77 app/flatpak-builtins-remote-modify.c:82
msgid "TITLE"
msgstr "标题"

#: app/flatpak-builtins-build-update-repo.c:70
msgid "A one-line comment for this repository"
msgstr "用于该仓库的单行注释"

#: app/flatpak-builtins-build-update-repo.c:70
#: app/flatpak-builtins-remote-add.c:78 app/flatpak-builtins-remote-modify.c:83
msgid "COMMENT"
msgstr "注释"

#: app/flatpak-builtins-build-update-repo.c:71
msgid "A full-paragraph description for this repository"
msgstr "用于该仓库的完整分段描述"

#: app/flatpak-builtins-build-update-repo.c:71
#: app/flatpak-builtins-remote-add.c:79 app/flatpak-builtins-remote-modify.c:84
msgid "DESCRIPTION"
msgstr "描述"

#: app/flatpak-builtins-build-update-repo.c:72
msgid "URL for a website for this repository"
msgstr "用于该仓库的网站网址"

#: app/flatpak-builtins-build-update-repo.c:73
msgid "URL for an icon for this repository"
msgstr "用于该仓库的图标网址"

#: app/flatpak-builtins-build-update-repo.c:74
msgid "Default branch to use for this repository"
msgstr "用于该仓库的默认分支"

#: app/flatpak-builtins-build-update-repo.c:74
#: app/flatpak-builtins-remote-add.c:82 app/flatpak-builtins-remote-modify.c:87
#: app/flatpak-builtins-repo.c:713 app/flatpak-builtins-repo.c:714
#: app/flatpak-builtins-run.c:161
msgid "BRANCH"
msgstr "分支"

#: app/flatpak-builtins-build-update-repo.c:75
#: app/flatpak-builtins-remote-add.c:83 app/flatpak-builtins-remote-modify.c:88
msgid "COLLECTION-ID"
msgstr "COLLECTION-ID"

#. Translators: A sideload is when you install from a local USB drive rather than the Internet.
#: app/flatpak-builtins-build-update-repo.c:77
msgid ""
"Permanently deploy collection ID to client remote configurations, only for "
"sideload support"
msgstr "将集合身份标识永久部署到客户端远程配置，仅用于侧载支持"

#: app/flatpak-builtins-build-update-repo.c:78
msgid "Permanently deploy collection ID to client remote configurations"
msgstr "将集合身份标识永久部署到客户端远程配置"

#: app/flatpak-builtins-build-update-repo.c:79
msgid "Name of authenticator for this repository"
msgstr "用于该仓库的身份验证器名称"

#: app/flatpak-builtins-build-update-repo.c:80
msgid "Autoinstall authenticator for this repository"
msgstr "为该仓库自动安装身份验证器"

#: app/flatpak-builtins-build-update-repo.c:81
msgid "Don't autoinstall authenticator for this repository"
msgstr "不要为该仓库自动安装身份验证器"

#: app/flatpak-builtins-build-update-repo.c:82
#: app/flatpak-builtins-remote-add.c:89
msgid "Authenticator option"
msgstr "身份验证器选项"

#: app/flatpak-builtins-build-update-repo.c:82
#: app/flatpak-builtins-remote-add.c:89 app/flatpak-builtins-remote-modify.c:95
msgid "KEY=VALUE"
msgstr "KEY=VALUE"

#: app/flatpak-builtins-build-update-repo.c:83
msgid "Import new default GPG public key from FILE"
msgstr "从文件导入新的默认 GPG 公钥"

#: app/flatpak-builtins-build-update-repo.c:84
msgid "GPG Key ID to sign the summary with"
msgstr "用于签名摘要的 GPG 密钥标识"

#: app/flatpak-builtins-build-update-repo.c:86
msgid "Generate delta files"
msgstr "生成增量文件"

#: app/flatpak-builtins-build-update-repo.c:88
msgid "Don't update the appstream branch"
msgstr "不更新 appstream 分支"

#: app/flatpak-builtins-build-update-repo.c:89
msgid "Max parallel jobs when creating deltas (default: NUMCPUs)"
msgstr "创建增量时的最大并行作业数量（默认：处理器数量）"

#: app/flatpak-builtins-build-update-repo.c:89
msgid "NUM-JOBS"
msgstr "NUM-JOBS"

#: app/flatpak-builtins-build-update-repo.c:90
msgid "Don't create deltas matching refs"
msgstr "不创建匹配引用的增量"

#: app/flatpak-builtins-build-update-repo.c:91
msgid "Prune unused objects"
msgstr "修剪未使用的对象"

#: app/flatpak-builtins-build-update-repo.c:92
msgid "Prune but don't actually remove anything"
msgstr "修剪但并不真正移除任何东西"

#: app/flatpak-builtins-build-update-repo.c:93
msgid "Only traverse DEPTH parents for each commit (default: -1=infinite)"
msgstr "为每次提交仅遍历的上级深度（默认：-1=infinite）"

#: app/flatpak-builtins-build-update-repo.c:93
msgid "DEPTH"
msgstr "深度"

#: app/flatpak-builtins-build-update-repo.c:223
#, c-format
msgid "Generating delta: %s (%.10s)\n"
msgstr "生成增量：%s（%.10s）\n"

#: app/flatpak-builtins-build-update-repo.c:225
#, c-format
msgid "Generating delta: %s (%.10s-%.10s)\n"
msgstr "生成增量：%s（%.10s-%.10s）\n"

#: app/flatpak-builtins-build-update-repo.c:233
#, c-format
msgid "Failed to generate delta %s (%.10s): "
msgstr "生成增量 %s 失败（%.10s）："

#: app/flatpak-builtins-build-update-repo.c:236
#, c-format
msgid "Failed to generate delta %s (%.10s-%.10s): "
msgstr "生成增量 %s 失败（%.10s-%.10s）："

#: app/flatpak-builtins-build-update-repo.c:492
msgid "LOCATION - Update repository metadata"
msgstr "位置 - 更新仓库元数据"

#: app/flatpak-builtins-build-update-repo.c:609
#, c-format
msgid "Updating appstream branch\n"
msgstr "更新 appstream 分支\n"

#: app/flatpak-builtins-build-update-repo.c:638
#, c-format
msgid "Updating summary\n"
msgstr "更新摘要\n"

#: app/flatpak-builtins-build-update-repo.c:664
#, c-format
msgid "Total objects: %u\n"
msgstr "对象总计：%u\n"

#: app/flatpak-builtins-build-update-repo.c:666
#, c-format
msgid "No unreachable objects\n"
msgstr "没有无法访问的对象\n"

#: app/flatpak-builtins-build-update-repo.c:668
#, c-format
msgid "Deleted %u objects, %s freed\n"
msgstr "已删除 %u 个对象，已释放 %s\n"

#: app/flatpak-builtins-config.c:41
msgid "List configuration keys and values"
msgstr "列出配置键和值"

#: app/flatpak-builtins-config.c:42
msgid "Get configuration for KEY"
msgstr "获取键的配置"

#: app/flatpak-builtins-config.c:43
msgid "Set configuration for KEY to VALUE"
msgstr "将键的配置设置为值"

#: app/flatpak-builtins-config.c:44
msgid "Unset configuration for KEY"
msgstr "取消对键的配置"

#: app/flatpak-builtins-config.c:149
#, c-format
msgid "'%s' does not look like a language/locale code"
msgstr "“%s”看起来不像是语言/地区代码"

#: app/flatpak-builtins-config.c:172
#, c-format
msgid "'%s' does not look like a language code"
msgstr "“%s”看起来不像是语言代码"

#: app/flatpak-builtins-config.c:190
#, c-format
msgid "'%s' is not a valid value (use 'true' or 'false')"
msgstr "“%s”不是有效值（使用“true”或“false”）"

#: app/flatpak-builtins-config.c:262
#, c-format
msgid "Unknown configure key '%s'"
msgstr "未知的配置键“%s”"

#: app/flatpak-builtins-config.c:284
msgid "Too many arguments for --list"
msgstr "--list 的参数过多"

#: app/flatpak-builtins-config.c:314 app/flatpak-builtins-config.c:362
msgid "You must specify KEY"
msgstr "您必须指定键"

#: app/flatpak-builtins-config.c:316
msgid "Too many arguments for --get"
msgstr "--get 的参数过多"

#: app/flatpak-builtins-config.c:338
msgid "You must specify KEY and VALUE"
msgstr "您必须指定键和值"

#: app/flatpak-builtins-config.c:340
msgid "Too many arguments for --set"
msgstr "--set 的参数过多"

#: app/flatpak-builtins-config.c:364
msgid "Too many arguments for --unset"
msgstr "--unset 的参数过多"

#: app/flatpak-builtins-config.c:383
msgid "[KEY [VALUE]] - Manage configuration"
msgstr "[键 [值]] - 管理配置"

#: app/flatpak-builtins-config.c:394
msgid "Can only use one of --list, --get, --set or --unset"
msgstr "只能使用 --list、--get、--set 或 --unset 之一"

#: app/flatpak-builtins-config.c:408
msgid "Must specify one of --list, --get, --set or --unset"
msgstr "必须指定 --list、--get、--set 或 --unset 之一"

#: app/flatpak-builtins-create-usb.c:45 app/flatpak-builtins-install.c:75
#: app/flatpak-builtins-remote-info.c:57 app/flatpak-builtins-uninstall.c:59
#: app/flatpak-builtins-update.c:65
msgid "Look for app with the specified name"
msgstr "用指定名称查找应用"

#: app/flatpak-builtins-create-usb.c:46
msgid "Arch to copy"
msgstr "要复制的架构"

#: app/flatpak-builtins-create-usb.c:47
msgid "DEST"
msgstr "目标"

#: app/flatpak-builtins-create-usb.c:49
msgid "Allow partial commits in the created repo"
msgstr "允许在创建的仓库中部分提交"

#: app/flatpak-builtins-create-usb.c:125 app/flatpak-builtins-create-usb.c:165
#, c-format
msgid ""
"Warning: Related ref ‘%s’ is partially installed. Use --allow-partial to "
"suppress this message.\n"
msgstr "警告：相关引用“%s”是部分安装。使用 --allow-partial 隐藏该消息。\n"

#: app/flatpak-builtins-create-usb.c:158
#, c-format
msgid "Warning: Omitting related ref ‘%s’ because it is not installed.\n"
msgstr "警告：由于相关引用“%s”未安装而对其省略。\n"

#: app/flatpak-builtins-create-usb.c:175
#, c-format
msgid ""
"Warning: Omitting related ref ‘%s’ because its remote ‘%s’ does not have a "
"collection ID set.\n"
msgstr "警告：由于相关引用“%s”的远程仓库“%s”没有设置集合标识而对其省略。\n"

#: app/flatpak-builtins-create-usb.c:187
#, c-format
msgid "Warning: Omitting related ref ‘%s’ because it's extra-data.\n"
msgstr "警告：由于相关引用“%s”是额外数据而对其省略。\n"

#: app/flatpak-builtins-create-usb.c:262 app/flatpak-builtins-create-usb.c:637
#, c-format
msgid ""
"Remote ‘%s’ does not have a collection ID set, which is required for P2P "
"distribution of ‘%s’."
msgstr "远程仓库“%s”没有设置对“%s”进行 P2P 发行所需的集合标识。"

#: app/flatpak-builtins-create-usb.c:272
#, c-format
msgid "Warning: Omitting ref ‘%s’ (runtime of ‘%s’) because it's extra-data.\n"
msgstr "警告：由于引用“%s”（“%s”的运行时）是额外数据而对其省略。\n"

#: app/flatpak-builtins-create-usb.c:484
msgid "MOUNT-PATH [REF…] - Copy apps or runtimes onto removable media"
msgstr "MOUNT-PATH [引用…] - 将应用或运行时复制到可移动媒体上"

#: app/flatpak-builtins-create-usb.c:493
msgid "MOUNT-PATH and REF must be specified"
msgstr "必须指定 MOUNT-PATH 和引用"

#: app/flatpak-builtins-create-usb.c:607
#, c-format
msgid "Ref ‘%s’ found in multiple installations: %s. You must specify one."
msgstr "在多个安装中发现引用“%s”：%s。您必须指定一个。"

#: app/flatpak-builtins-create-usb.c:620
#, c-format
msgid "Refs must all be in the same installation (found in %s and %s)."
msgstr "引用必须全部位于同一安装中（在 %s 和 %s 中找到）。"

#: app/flatpak-builtins-create-usb.c:670
#, c-format
msgid ""
"Warning: Ref ‘%s’ is partially installed. Use --allow-partial to suppress "
"this message.\n"
msgstr "警告：引用“%s”是部分安装。使用 --allow-partial 隐藏该消息。\n"

#: app/flatpak-builtins-create-usb.c:681
#, c-format
msgid "Installed ref ‘%s’ is extra-data, and cannot be distributed offline"
msgstr "已安装引用“%s”是额外数据，且无法离线发行"

#: app/flatpak-builtins-create-usb.c:721
#, c-format
msgid "Warning: Couldn't update repo metadata for remote ‘%s’: %s\n"
msgstr "警告：无法为远程仓库“%s”更新仓库元数据：%s\n"

#: app/flatpak-builtins-create-usb.c:751
#, c-format
msgid "Warning: Couldn't update appstream data for remote ‘%s’ arch ‘%s’: %s\n"
msgstr "警告：无法为远程仓库“%s”架构“%s”更新 appstream 数据：%s\n"

#. Print a warning if both appstream and appstream2 are missing
#: app/flatpak-builtins-create-usb.c:784
#, c-format
msgid ""
"Warning: Couldn't find appstream data for remote ‘%s’ arch ‘%s’: %s; %s\n"
msgstr "警告：无法找到用于远程仓库“%s”架构“%s”的 appstream 数据：%s；%s\n"

#. Appstream2 is only for efficiency, so just print a debug message
#: app/flatpak-builtins-create-usb.c:790
#, c-format
msgid "Couldn't find appstream2 data for remote ‘%s’ arch ‘%s’: %s\n"
msgstr "无法找到用于远程仓库“%s”架构“%s”的 appstream2 数据：%s\n"

#: app/flatpak-builtins-document-export.c:62
msgid "Create a unique document reference"
msgstr "创建唯一的文档引用"

#: app/flatpak-builtins-document-export.c:63
msgid "Make the document transient for the current session"
msgstr "使文档在当前会话中处于临时状态"

#: app/flatpak-builtins-document-export.c:64
msgid "Don't require the file to exist already"
msgstr "不需要文件已经存在"

#: app/flatpak-builtins-document-export.c:65
msgid "Give the app read permissions"
msgstr "授予应用读取权限"

#: app/flatpak-builtins-document-export.c:66
msgid "Give the app write permissions"
msgstr "授予应用写入权限"

#: app/flatpak-builtins-document-export.c:67
msgid "Give the app delete permissions"
msgstr "授予应用删除权限"

#: app/flatpak-builtins-document-export.c:68
msgid "Give the app permissions to grant further permissions"
msgstr "授予应用权限以同意更多权限"

#: app/flatpak-builtins-document-export.c:69
msgid "Revoke read permissions of the app"
msgstr "撤消应用的读取权限"

#: app/flatpak-builtins-document-export.c:70
msgid "Revoke write permissions of the app"
msgstr "撤销应用的写入权限"

#: app/flatpak-builtins-document-export.c:71
msgid "Revoke delete permissions of the app"
msgstr "撤消应用的删除权限"

#: app/flatpak-builtins-document-export.c:72
msgid "Revoke the permission to grant further permissions"
msgstr "撤消该权限以同意更多权限"

#: app/flatpak-builtins-document-export.c:73
msgid "Add permissions for this app"
msgstr "为此应用添加权限"

#: app/flatpak-builtins-document-export.c:73
msgid "APPID"
msgstr "应用标识"

#: app/flatpak-builtins-document-export.c:100
msgid "FILE - Export a file to apps"
msgstr "文件 - 导出文件到应用"

#: app/flatpak-builtins-document-export.c:109
#: app/flatpak-builtins-document-info.c:72
#: app/flatpak-builtins-document-unexport.c:67
msgid "FILE must be specified"
msgstr "必须指定文件"

#: app/flatpak-builtins-document-info.c:63
msgid "FILE - Get information about an exported file"
msgstr "文件 - 获取关于导出文件的信息"

#: app/flatpak-builtins-document-info.c:100
#: app/flatpak-builtins-document-unexport.c:94
#, c-format
msgid "Not exported\n"
msgstr "未导出\n"

#: app/flatpak-builtins-document-list.c:43 app/flatpak-builtins-history.c:53
#: app/flatpak-builtins-list.c:54 app/flatpak-builtins-ps.c:43
#: app/flatpak-builtins-remote-list.c:45 app/flatpak-builtins-remote-ls.c:59
#: app/flatpak-builtins-search.c:38
msgid "What information to show"
msgstr "显示什么信息"

#: app/flatpak-builtins-document-list.c:43 app/flatpak-builtins-history.c:53
#: app/flatpak-builtins-list.c:54 app/flatpak-builtins-ps.c:43
#: app/flatpak-builtins-remote-list.c:45 app/flatpak-builtins-remote-ls.c:59
#: app/flatpak-builtins-search.c:38
msgid "FIELD,…"
msgstr "领域,…"

#: app/flatpak-builtins-document-list.c:44 app/flatpak-builtins-history.c:54
#: app/flatpak-builtins-list.c:52 app/flatpak-builtins-permission-list.c:43
#: app/flatpak-builtins-permission-show.c:43 app/flatpak-builtins-ps.c:44
#: app/flatpak-builtins-remote-list.c:46 app/flatpak-builtins-remote-ls.c:63
#: app/flatpak-builtins-repo.c:717 app/flatpak-builtins-search.c:39
msgid "Show output in JSON format"
msgstr "以 JSON 格式显示输出"

#: app/flatpak-builtins-document-list.c:49
msgid "Show the document ID"
msgstr "显示文档标识"

#: app/flatpak-builtins-document-list.c:50
msgid "Path"
msgstr "路径"

#: app/flatpak-builtins-document-list.c:50
#: app/flatpak-builtins-document-list.c:51
msgid "Show the document path"
msgstr "显示文档路径"

#: app/flatpak-builtins-document-list.c:51 app/flatpak-builtins-list.c:66
#: app/flatpak-builtins-remote-ls.c:74
msgid "Origin"
msgstr "来源"

#: app/flatpak-builtins-document-list.c:52 app/flatpak-builtins-history.c:62
#: app/flatpak-builtins-ps.c:52
msgid "Application"
msgstr "应用程序"

#: app/flatpak-builtins-document-list.c:52
msgid "Show applications with permission"
msgstr "显示获得权限的应用"

#: app/flatpak-builtins-document-list.c:53
#: app/flatpak-builtins-permission-list.c:182
#: app/flatpak-builtins-permission-show.c:145
msgid "Permissions"
msgstr "权限"

#: app/flatpak-builtins-document-list.c:53
msgid "Show permissions for applications"
msgstr "显示应用程序的权限"

#: app/flatpak-builtins-document-list.c:161
#, c-format
msgid "No documents found\n"
msgstr "未找到文档\n"

#: app/flatpak-builtins-document-list.c:180
msgid "[APPID] - List exported files"
msgstr "[应用标识] - 列出导出的文件"

#: app/flatpak-builtins-document-unexport.c:43
msgid "Specify the document ID"
msgstr "指定文档标识"

#: app/flatpak-builtins-document-unexport.c:58
msgid "FILE - Unexport a file to apps"
msgstr "文件 - 取消导出文件到应用"

#: app/flatpak-builtins-enter.c:88
msgid "INSTANCE COMMAND [ARGUMENT…] - Run a command inside a running sandbox"
msgstr "实例 命令 [参数…] - 在正在运行的沙箱中运行命令"

#: app/flatpak-builtins-enter.c:111
msgid "INSTANCE and COMMAND must be specified"
msgstr "必须指定实例和命令"

#: app/flatpak-builtins-enter.c:138
#, c-format
msgid "%s is neither a pid nor an application or instance ID"
msgstr "%s 既不是进程标识也不是应用或实例标识"

#: app/flatpak-builtins-enter.c:144
msgid "entering not supported (need unprivileged user namespaces, or sudo -E)"
msgstr "不支持进入（需要无特权用户命名空间或 sudo -E）"

#: app/flatpak-builtins-enter.c:145
#, c-format
msgid "No such pid %s"
msgstr "没有这样的进程标识 %s"

#: app/flatpak-builtins-enter.c:158
msgid "Can't read cwd"
msgstr "无法读取 cwd"

#: app/flatpak-builtins-enter.c:163
msgid "Can't read root"
msgstr "无法读取 root"

#: app/flatpak-builtins-enter.c:191
#, c-format
msgid "Invalid %s namespace for pid %d"
msgstr "进程标识 %2$d 的 %1$s 命名空间无效"

#: app/flatpak-builtins-enter.c:202
#, c-format
msgid "Invalid %s namespace for self"
msgstr "自身的 %s 命名空间无效"

#: app/flatpak-builtins-enter.c:216
#, c-format
msgid "Can't open %s namespace: %s"
msgstr "无法打开 %s 命名空间：%s"

#: app/flatpak-builtins-enter.c:226
msgid "entering not supported (need unprivileged user namespaces)"
msgstr "不支持进入（需要无特权用户命名空间）"

#: app/flatpak-builtins-enter.c:227
#, c-format
msgid "Can't enter %s namespace: %s"
msgstr "无法进入 %s 命名空间：%s"

#: app/flatpak-builtins-enter.c:234
msgid "Can't chdir"
msgstr "无法 chdir"

#: app/flatpak-builtins-enter.c:237
msgid "Can't chroot"
msgstr "无法 chroot"

#: app/flatpak-builtins-enter.c:240
msgid "Can't switch gid"
msgstr "无法切换 gid"

#: app/flatpak-builtins-enter.c:243
msgid "Can't switch uid"
msgstr "无法切换 uid"

#: app/flatpak-builtins-history.c:50
msgid "Only show changes after TIME"
msgstr "仅显示该时间之后的更改"

#: app/flatpak-builtins-history.c:50 app/flatpak-builtins-history.c:51
msgid "TIME"
msgstr "时间"

#: app/flatpak-builtins-history.c:51
msgid "Only show changes before TIME"
msgstr "仅显示该时间之前的更改"

#: app/flatpak-builtins-history.c:52
msgid "Show newest entries first"
msgstr "优先显示最新条目"

#: app/flatpak-builtins-history.c:59
msgid "Time"
msgstr "时间"

#: app/flatpak-builtins-history.c:59
msgid "Show when the change happened"
msgstr "显示发生更改的时间"

#: app/flatpak-builtins-history.c:60
msgid "Change"
msgstr "修改"

#: app/flatpak-builtins-history.c:60
msgid "Show the kind of change"
msgstr "显示更改的类型"

#: app/flatpak-builtins-history.c:61 app/flatpak-builtins-list.c:68
#: app/flatpak-builtins-remote-ls.c:75 app/flatpak-builtins-repo.c:335
msgid "Ref"
msgstr "引用"

#: app/flatpak-builtins-history.c:61 app/flatpak-builtins-list.c:68
#: app/flatpak-builtins-remote-ls.c:75
msgid "Show the ref"
msgstr "显示引用"

#: app/flatpak-builtins-history.c:62
msgid "Show the application/runtime ID"
msgstr "显示应用/运行时标识"

#: app/flatpak-builtins-history.c:63 app/flatpak-builtins-list.c:64
#: app/flatpak-builtins-ps.c:53 app/flatpak-builtins-remote-ls.c:73
#: app/flatpak-cli-transaction.c:1435
msgid "Arch"
msgstr "架构"

#: app/flatpak-builtins-history.c:63 app/flatpak-builtins-list.c:64
#: app/flatpak-builtins-ps.c:53 app/flatpak-builtins-remote-ls.c:73
msgid "Show the architecture"
msgstr "显示架构"

#: app/flatpak-builtins-history.c:64 app/flatpak-builtins-list.c:63
#: app/flatpak-builtins-ps.c:54 app/flatpak-builtins-remote-ls.c:72
#: app/flatpak-builtins-search.c:48 app/flatpak-cli-transaction.c:1438
msgid "Branch"
msgstr "分支"

#: app/flatpak-builtins-history.c:64 app/flatpak-builtins-list.c:63
#: app/flatpak-builtins-remote-ls.c:72
msgid "Show the branch"
msgstr "显示分支"

#: app/flatpak-builtins-history.c:65 app/flatpak-builtins-list.c:67
msgid "Installation"
msgstr "安装"

#: app/flatpak-builtins-history.c:65
msgid "Show the affected installation"
msgstr "显示受影响的安装"

#: app/flatpak-builtins-history.c:66 app/flatpak-cli-transaction.c:1452
msgid "Remote"
msgstr "远程"

#: app/flatpak-builtins-history.c:66
msgid "Show the remote"
msgstr "显示远程仓库"

#: app/flatpak-builtins-history.c:67 app/flatpak-builtins-ps.c:55
#: app/flatpak-builtins-remote-ls.c:76
msgid "Commit"
msgstr "提交"

#: app/flatpak-builtins-history.c:67
msgid "Show the current commit"
msgstr "显示当前提交"

#: app/flatpak-builtins-history.c:68
msgid "Old Commit"
msgstr "旧提交"

#: app/flatpak-builtins-history.c:68
msgid "Show the previous commit"
msgstr "显示上一次提交"

#: app/flatpak-builtins-history.c:69
msgid "Show the remote URL"
msgstr "显示远程仓库网址"

#: app/flatpak-builtins-history.c:70 app/flatpak-cli-transaction.c:700
msgid "User"
msgstr "用户"

#: app/flatpak-builtins-history.c:70
msgid "Show the user doing the change"
msgstr "显示进行更改的用户"

#: app/flatpak-builtins-history.c:71
msgid "Tool"
msgstr "工具"

#: app/flatpak-builtins-history.c:71
msgid "Show the tool that was used"
msgstr "显示曾经使用的工具"

#: app/flatpak-builtins-history.c:72 app/flatpak-builtins-list.c:62
#: app/flatpak-builtins-remote-ls.c:71 app/flatpak-builtins-search.c:47
msgid "Version"
msgstr "版本"

#: app/flatpak-builtins-history.c:72
msgid "Show the Flatpak version"
msgstr "显示 Flatpak 版本"

#: app/flatpak-builtins-history.c:91
#, c-format
msgid "Failed to get journal data (%s): %s"
msgstr "获取日志数据失败（%s）：%s"

#: app/flatpak-builtins-history.c:146
#, c-format
msgid "Failed to open journal: %s"
msgstr "打开日志失败：%s"

#: app/flatpak-builtins-history.c:153
#, c-format
msgid "Failed to add match to journal: %s"
msgstr "无法将匹配项添加到日志：%s"

#: app/flatpak-builtins-history.c:471
msgid " - Show history"
msgstr " - 显示历史"

#: app/flatpak-builtins-history.c:490
#, c-format
msgid "Failed to parse the --since option"
msgstr "解析 --since 选项失败"

#: app/flatpak-builtins-history.c:501
#, c-format
msgid "Failed to parse the --until option"
msgstr "解析 --until 选项失败"

#: app/flatpak-builtins-info.c:56
msgid "Show user installations"
msgstr "显示用户级安装"

#: app/flatpak-builtins-info.c:57
msgid "Show system-wide installations"
msgstr "显示系统级安装"

#: app/flatpak-builtins-info.c:58
msgid "Show specific system-wide installations"
msgstr "显示指定的系统级安装"

#: app/flatpak-builtins-info.c:59 app/flatpak-builtins-remote-info.c:59
msgid "Show ref"
msgstr "显示引用"

#: app/flatpak-builtins-info.c:60 app/flatpak-builtins-remote-info.c:60
msgid "Show commit"
msgstr "显示提交"

#: app/flatpak-builtins-info.c:61
msgid "Show origin"
msgstr "显示来源"

#: app/flatpak-builtins-info.c:62
msgid "Show size"
msgstr "显示大小"

#: app/flatpak-builtins-info.c:63 app/flatpak-builtins-remote-info.c:62
msgid "Show metadata"
msgstr "显示元数据"

#: app/flatpak-builtins-info.c:64 app/flatpak-builtins-remote-info.c:63
msgid "Show runtime"
msgstr "显示运行时"

#: app/flatpak-builtins-info.c:65 app/flatpak-builtins-remote-info.c:64
msgid "Show sdk"
msgstr "显示 SDK"

#: app/flatpak-builtins-info.c:66
msgid "Show permissions"
msgstr "显示权限"

#: app/flatpak-builtins-info.c:67
msgid "Query file access"
msgstr "查询文件访问"

#: app/flatpak-builtins-info.c:67 app/flatpak-builtins-install.c:82
#: app/flatpak-builtins-install.c:88 app/flatpak-builtins-preinstall.c:68
#: app/flatpak-builtins-run.c:182 app/flatpak-builtins-run.c:184
#: app/flatpak-builtins-update.c:67 app/flatpak-builtins-update.c:71
msgid "PATH"
msgstr "路径"

#: app/flatpak-builtins-info.c:68
msgid "Show extensions"
msgstr "显示扩展"

#: app/flatpak-builtins-info.c:69
msgid "Show location"
msgstr "显示位置"

#: app/flatpak-builtins-info.c:116
msgid "NAME [BRANCH] - Get info about an installed app or runtime"
msgstr "名称 [分支] - 获取关于已安装应用或运行时的信息"

#: app/flatpak-builtins-info.c:123 app/flatpak-builtins-remote-add.c:317
#: app/flatpak-builtins-remote-delete.c:63
msgid "NAME must be specified"
msgstr "必须指定名称"

#: app/flatpak-builtins-info.c:196
msgid "ref not present in origin"
msgstr "引用在来源中不存在"

#: app/flatpak-builtins-info.c:211 app/flatpak-builtins-remote-info.c:217
#, c-format
msgid "Warning: Commit has no flatpak metadata\n"
msgstr "警告：提交中没有 flatpak 元数据\n"

#: app/flatpak-builtins-info.c:217 app/flatpak-builtins-info.c:259
#: app/flatpak-builtins-info.c:455 app/flatpak-builtins-info.c:513
#: app/flatpak-builtins-remote-info.c:236
#: app/flatpak-builtins-remote-info.c:271
msgid "ID:"
msgstr "标识："

#: app/flatpak-builtins-info.c:218 app/flatpak-builtins-info.c:260
#: app/flatpak-builtins-remote-info.c:237
#: app/flatpak-builtins-remote-info.c:272
msgid "Ref:"
msgstr "引用："

#: app/flatpak-builtins-info.c:219 app/flatpak-builtins-info.c:261
#: app/flatpak-builtins-remote-info.c:238
#: app/flatpak-builtins-remote-info.c:273
msgid "Arch:"
msgstr "架构："

#: app/flatpak-builtins-info.c:220 app/flatpak-builtins-info.c:262
#: app/flatpak-builtins-remote-info.c:239
#: app/flatpak-builtins-remote-info.c:274
msgid "Branch:"
msgstr "分支："

#: app/flatpak-builtins-info.c:222 app/flatpak-builtins-info.c:264
#: app/flatpak-builtins-remote-info.c:241
#: app/flatpak-builtins-remote-info.c:276
msgid "Version:"
msgstr "版本："

#: app/flatpak-builtins-info.c:224 app/flatpak-builtins-info.c:266
#: app/flatpak-builtins-remote-info.c:243
#: app/flatpak-builtins-remote-info.c:278
msgid "License:"
msgstr "许可证："

#: app/flatpak-builtins-info.c:226 app/flatpak-builtins-info.c:269
#: app/flatpak-builtins-remote-info.c:245
#: app/flatpak-builtins-remote-info.c:280
msgid "Collection:"
msgstr "集合："

#: app/flatpak-builtins-info.c:227 app/flatpak-builtins-info.c:270
#: app/flatpak-builtins-info.c:458 app/flatpak-builtins-info.c:516
msgid "Installation:"
msgstr "安装："

#: app/flatpak-builtins-info.c:228 app/flatpak-builtins-info.c:271
#: app/flatpak-builtins-info.c:459 app/flatpak-builtins-info.c:517
#: app/flatpak-builtins-remote-info.c:249
#: app/flatpak-builtins-remote-info.c:284
msgid "Installed Size:"
msgstr "安装大小："

#: app/flatpak-builtins-info.c:231 app/flatpak-builtins-info.c:279
#: app/flatpak-builtins-remote-info.c:252
#: app/flatpak-builtins-remote-info.c:288
msgid "Runtime:"
msgstr "运行时："

#: app/flatpak-builtins-info.c:232 app/flatpak-builtins-info.c:288
#: app/flatpak-builtins-remote-info.c:253
#: app/flatpak-builtins-remote-info.c:293
msgid "Sdk:"
msgstr "SDK："

#: app/flatpak-builtins-info.c:235 app/flatpak-builtins-info.c:313
#: app/flatpak-builtins-remote-info.c:256
#: app/flatpak-builtins-remote-info.c:319
msgid "Date:"
msgstr "日期："

#: app/flatpak-builtins-info.c:237 app/flatpak-builtins-info.c:311
#: app/flatpak-builtins-remote-info.c:258
#: app/flatpak-builtins-remote-info.c:317
msgid "Subject:"
msgstr "主题："

#: app/flatpak-builtins-info.c:240 app/flatpak-builtins-info.c:295
msgid "Active commit:"
msgstr "激活提交："

#: app/flatpak-builtins-info.c:241 app/flatpak-builtins-info.c:298
msgid "Latest commit:"
msgstr "最新提交："

#: app/flatpak-builtins-info.c:244 app/flatpak-builtins-info.c:303
#: app/flatpak-builtins-info.c:457 app/flatpak-builtins-info.c:515
#: app/flatpak-builtins-remote-info.c:259
#: app/flatpak-builtins-remote-info.c:298
msgid "Commit:"
msgstr "提交："

#: app/flatpak-builtins-info.c:246 app/flatpak-builtins-info.c:308
#: app/flatpak-builtins-remote-info.c:261
#: app/flatpak-builtins-remote-info.c:303
msgid "Parent:"
msgstr "上级："

#: app/flatpak-builtins-info.c:248 app/flatpak-builtins-info.c:321
msgid "Alt-id:"
msgstr "替代标识："

#: app/flatpak-builtins-info.c:250 app/flatpak-builtins-info.c:325
#: app/flatpak-builtins-remote-info.c:263
#: app/flatpak-builtins-remote-info.c:308
msgid "End-of-life:"
msgstr "寿命完结："

#: app/flatpak-builtins-info.c:252 app/flatpak-builtins-info.c:330
#: app/flatpak-builtins-remote-info.c:265
#: app/flatpak-builtins-remote-info.c:313
msgid "End-of-life-rebase:"
msgstr "报废的基础系统："

#: app/flatpak-builtins-info.c:254 app/flatpak-builtins-info.c:317
msgid "Subdirectories:"
msgstr "子目录："

#: app/flatpak-builtins-info.c:255 app/flatpak-builtins-info.c:454
#: app/flatpak-builtins-info.c:512
msgid "Extension:"
msgstr "扩展："

#: app/flatpak-builtins-info.c:267 app/flatpak-builtins-info.c:456
#: app/flatpak-builtins-info.c:514
msgid "Origin:"
msgstr "来源："

#: app/flatpak-builtins-info.c:460 app/flatpak-builtins-info.c:522
msgid "Subpaths:"
msgstr "子路径："

#: app/flatpak-builtins-info.c:478
msgid "unmaintained"
msgstr "无人维护"

#: app/flatpak-builtins-info.c:480 app/flatpak-builtins-info.c:482
msgid "unknown"
msgstr "未知"

#: app/flatpak-builtins-install.c:68 app/flatpak-builtins-preinstall.c:57
msgid "Don't pull, only install from local cache"
msgstr "不要提取，仅从本地缓存安装"

#: app/flatpak-builtins-install.c:69 app/flatpak-builtins-preinstall.c:58
#: app/flatpak-builtins-update.c:60
msgid "Don't deploy, only download to local cache"
msgstr "不要部署，仅下载到本地缓存"

#: app/flatpak-builtins-install.c:70 app/flatpak-builtins-preinstall.c:59
msgid "Don't install related refs"
msgstr "不要安装相关的引用"

#: app/flatpak-builtins-install.c:71 app/flatpak-builtins-preinstall.c:60
#: app/flatpak-builtins-update.c:62
msgid "Don't verify/install runtime dependencies"
msgstr "不要验证/安装运行时依赖"

#: app/flatpak-builtins-install.c:72
msgid "Don't automatically pin explicit installs"
msgstr "不要自动置顶明确的安装"

#: app/flatpak-builtins-install.c:73 app/flatpak-builtins-preinstall.c:61
#: app/flatpak-builtins-update.c:63
msgid "Don't use static deltas"
msgstr "不要使用静态增量"

#: app/flatpak-builtins-install.c:76 app/flatpak-builtins-preinstall.c:62
msgid "Additionally install the SDK used to build the given refs"
msgstr "附带安装用于构建给定引用的 SDK"

#: app/flatpak-builtins-install.c:77 app/flatpak-builtins-preinstall.c:63
msgid ""
"Additionally install the debug info for the given refs and their dependencies"
msgstr "另外 为给定的引用及其依赖安装调试信息包"

#: app/flatpak-builtins-install.c:78
msgid "Assume LOCATION is a .flatpak single-file bundle"
msgstr "假定位置是 .flatpak 单文件捆绑包"

#: app/flatpak-builtins-install.c:79
msgid "Assume LOCATION is a .flatpakref application description"
msgstr "假定位置是 .flatpakref 应用描述"

#: app/flatpak-builtins-install.c:80
msgid "Assume LOCATION is containers-transports(5) reference to an OCI image"
msgstr "假定位置是引用至 OCI 映像的 containers-transports(5)"

#: app/flatpak-builtins-install.c:81
msgid "Check bundle signatures with GPG key from FILE (- for stdin)"
msgstr "用来自文件（- 用于 stdin）的 GPG 密钥检查捆绑包签名"

#: app/flatpak-builtins-install.c:82
msgid "Only install this subpath"
msgstr "仅安装此子路径"

#: app/flatpak-builtins-install.c:83 app/flatpak-builtins-preinstall.c:64
#: app/flatpak-builtins-uninstall.c:63 app/flatpak-builtins-update.c:68
msgid "Automatically answer yes for all questions"
msgstr "对所有问题自动回答是"

#: app/flatpak-builtins-install.c:84 app/flatpak-builtins-preinstall.c:65
msgid "Uninstall first if already installed"
msgstr "如果已安装会先卸载"

#: app/flatpak-builtins-install.c:85 app/flatpak-builtins-preinstall.c:66
#: app/flatpak-builtins-uninstall.c:64 app/flatpak-builtins-update.c:69
msgid "Produce minimal output and don't ask questions"
msgstr "显示最少的输出信息且不会询问问题"

#: app/flatpak-builtins-install.c:86
msgid "Update install if already installed"
msgstr "如果已经安装会更新安装"

#. Translators: A sideload is when you install from a local USB drive rather than the Internet.
#: app/flatpak-builtins-install.c:88 app/flatpak-builtins-preinstall.c:68
#: app/flatpak-builtins-update.c:71
msgid "Use this local repo for sideloads"
msgstr "对侧载使用该本地仓库"

#: app/flatpak-builtins-install.c:178
msgid "Bundle filename must be specified"
msgstr "必须指定捆绑包文件名"

#: app/flatpak-builtins-install.c:188
msgid "Remote bundles are not supported"
msgstr "不支持远程捆绑包"

#: app/flatpak-builtins-install.c:231
msgid "Filename or uri must be specified"
msgstr "必须指定文件名或网址"

#: app/flatpak-builtins-install.c:295
msgid "Image location must be specified"
msgstr "必须指定映像位置"

#: app/flatpak-builtins-install.c:345
msgid "[LOCATION/REMOTE] [REF…] - Install applications or runtimes"
msgstr "[位置/远程] [引用…] - 安装应用程序或运行时"

#: app/flatpak-builtins-install.c:378
msgid "At least one REF must be specified"
msgstr "必须至少指定一个引用"

#: app/flatpak-builtins-install.c:392
#, c-format
msgid "Looking for matches…\n"
msgstr "寻找匹配项…\n"

#: app/flatpak-builtins-install.c:513
#, c-format
msgid "No remote refs found for ‘%s’"
msgstr "未发现用于“%s”的远程引用"

#: app/flatpak-builtins-install.c:573 app/flatpak-builtins-uninstall.c:405
#: common/flatpak-ref-utils.c:689 common/flatpak-ref-utils.c:1595
#, c-format
msgid "Invalid branch %s: %s"
msgstr "无效的分支 %s：%s"

#: app/flatpak-builtins-install.c:606
#, c-format
msgid "Nothing matches %s in local repository for remote %s"
msgstr "未在用于远程仓库 %2$s 的本地仓库中发现 %1$s 的匹配项"

#: app/flatpak-builtins-install.c:608
#, c-format
msgid "Nothing matches %s in remote %s"
msgstr "未在远程仓库 %2$s 中发现 %1$s 的匹配项"

#: app/flatpak-builtins-install.c:629
#, c-format
msgid "Skipping: %s\n"
msgstr "正在跳过：%s\n"

#: app/flatpak-builtins-kill.c:110
#, c-format
msgid "%s is not running"
msgstr "%s 未在运行"

#: app/flatpak-builtins-kill.c:136
msgid "INSTANCE - Stop a running application"
msgstr "实例 - 停止正在运行的应用"

#: app/flatpak-builtins-kill.c:144 app/flatpak-builtins-ps.c:256
msgid "Extra arguments given"
msgstr "给出的额外参数"

#: app/flatpak-builtins-kill.c:150
msgid "Must specify the app to kill"
msgstr "必须指定要杀死的应用"

#: app/flatpak-builtins-list.c:47
msgid "Show extra information"
msgstr "显示额外信息"

#: app/flatpak-builtins-list.c:48
msgid "List installed runtimes"
msgstr "列出已安装的运行时"

#: app/flatpak-builtins-list.c:49
msgid "List installed applications"
msgstr "列出已安装的应用"

#: app/flatpak-builtins-list.c:50
msgid "Arch to show"
msgstr "要显示的架构"

#: app/flatpak-builtins-list.c:51 app/flatpak-builtins-remote-ls.c:57
msgid "List all refs (including locale/debug)"
msgstr "列出所有引用（包括本地化/调试）"

#: app/flatpak-builtins-list.c:53 app/flatpak-builtins-remote-ls.c:58
msgid "List all applications using RUNTIME"
msgstr "列出所有使用指定运行时的应用"

#: app/flatpak-builtins-list.c:59 app/flatpak-builtins-remote-list.c:51
#: app/flatpak-builtins-remote-ls.c:68 app/flatpak-builtins-search.c:44
msgid "Name"
msgstr "名称"

#: app/flatpak-builtins-list.c:59 app/flatpak-builtins-remote-list.c:51
#: app/flatpak-builtins-remote-ls.c:68 app/flatpak-builtins-search.c:44
msgid "Show the name"
msgstr "显示名字"

#: app/flatpak-builtins-list.c:60 app/flatpak-builtins-remote-list.c:60
#: app/flatpak-builtins-remote-ls.c:69 app/flatpak-builtins-search.c:45
msgid "Description"
msgstr "描述"

#: app/flatpak-builtins-list.c:60 app/flatpak-builtins-remote-ls.c:69
#: app/flatpak-builtins-search.c:45
msgid "Show the description"
msgstr "显示说明"

#: app/flatpak-builtins-list.c:61 app/flatpak-builtins-remote-ls.c:70
#: app/flatpak-builtins-search.c:46
msgid "Application ID"
msgstr "应用程序 ID"

#: app/flatpak-builtins-list.c:61 app/flatpak-builtins-ps.c:52
#: app/flatpak-builtins-remote-ls.c:70 app/flatpak-builtins-search.c:46
msgid "Show the application ID"
msgstr "显示应用程序标识"

#: app/flatpak-builtins-list.c:62 app/flatpak-builtins-remote-ls.c:71
#: app/flatpak-builtins-search.c:47
msgid "Show the version"
msgstr "显示版本"

#: app/flatpak-builtins-list.c:65 app/flatpak-builtins-ps.c:56
#: app/flatpak-builtins-remote-ls.c:77
msgid "Runtime"
msgstr "运行时"

#: app/flatpak-builtins-list.c:65
msgid "Show the used runtime"
msgstr "显示使用的运行时"

#: app/flatpak-builtins-list.c:66 app/flatpak-builtins-remote-ls.c:74
msgid "Show the origin remote"
msgstr "显示来源的远程仓库"

#: app/flatpak-builtins-list.c:67
msgid "Show the installation"
msgstr "显示安装"

#: app/flatpak-builtins-list.c:69
msgid "Active commit"
msgstr "激活提交"

#: app/flatpak-builtins-list.c:69 app/flatpak-builtins-remote-ls.c:76
msgid "Show the active commit"
msgstr "显示激活的提交"

#: app/flatpak-builtins-list.c:70
msgid "Latest commit"
msgstr "最新提交"

#: app/flatpak-builtins-list.c:70
msgid "Show the latest commit"
msgstr "显示最新的提交"

#: app/flatpak-builtins-list.c:71 app/flatpak-builtins-remote-ls.c:78
msgid "Installed size"
msgstr "安装大小"

#: app/flatpak-builtins-list.c:71 app/flatpak-builtins-remote-ls.c:78
msgid "Show the installed size"
msgstr "显示安装后的大小"

#: app/flatpak-builtins-list.c:72 app/flatpak-builtins-remote-list.c:58
#: app/flatpak-builtins-remote-ls.c:80 app/flatpak-builtins-repo.c:340
msgid "Options"
msgstr "选项"

#: app/flatpak-builtins-list.c:72 app/flatpak-builtins-remote-list.c:58
#: app/flatpak-builtins-remote-ls.c:80
msgid "Show options"
msgstr "显示选项"

#: app/flatpak-builtins-list.c:180
#, c-format
msgid "Unable to load details of %s: %s"
msgstr "无法加载 %s 的详情：%s"

#: app/flatpak-builtins-list.c:190
#, c-format
msgid "Unable to inspect current version of %s: %s"
msgstr "无法检查 %s 的当前版本：%s"

#: app/flatpak-builtins-list.c:408
msgid " - List installed apps and/or runtimes"
msgstr " - 列出已安装的应用和/或运行时"

#: app/flatpak-builtins-make-current.c:38
msgid "Arch to make current for"
msgstr "要使之成为当前运行的架构"

#: app/flatpak-builtins-make-current.c:58
msgid "APP BRANCH - Make branch of application current"
msgstr "应用 分支 - 使指定分支的应用成为当前运行的"

#: app/flatpak-builtins-make-current.c:69 app/flatpak-builtins-run.c:260
msgid "APP must be specified"
msgstr "必须指定应用"

#: app/flatpak-builtins-make-current.c:84
msgid "BRANCH must be specified"
msgstr "必须指定分支"

#: app/flatpak-builtins-make-current.c:97
#, c-format
msgid "App %s branch %s is not installed"
msgstr "未安装应用 %s 的分支 %s"

#: app/flatpak-builtins-mask.c:42
msgid "Remove matching masks"
msgstr "移除匹配项屏蔽"

#: app/flatpak-builtins-mask.c:54
msgid ""
"[PATTERN…] - disable updates and automatic installation matching patterns"
msgstr "[匹配模式…] - 禁用更新和自动安装匹配模式"

#: app/flatpak-builtins-mask.c:73
#, c-format
msgid "No masked patterns\n"
msgstr "没有屏蔽的匹配模式\n"

#: app/flatpak-builtins-mask.c:78
#, c-format
msgid "Masked patterns:\n"
msgstr "屏蔽的匹配模式：\n"

#: app/flatpak-builtins-override.c:42
msgid "Remove existing overrides"
msgstr "移除现存覆盖"

#: app/flatpak-builtins-override.c:43
msgid "Show existing overrides"
msgstr "显示现存覆盖"

#: app/flatpak-builtins-override.c:59
msgid "[APP] - Override settings [for application]"
msgstr "[应用] - 覆盖设置 [用于应用]"

#: app/flatpak-builtins-permission-list.c:143
msgid "[TABLE] [ID] - List permissions"
msgstr "[表格] [标识] - 列出权限"

#: app/flatpak-builtins-permission-list.c:179
#: app/flatpak-builtins-permission-show.c:142
msgid "Table"
msgstr "表格"

#: app/flatpak-builtins-permission-list.c:180
#: app/flatpak-builtins-permission-show.c:143
msgid "Object"
msgstr "对象"

#: app/flatpak-builtins-permission-list.c:181
#: app/flatpak-builtins-permission-show.c:144
msgid "App"
msgstr "应用"

#: app/flatpak-builtins-permission-list.c:183
#: app/flatpak-builtins-permission-show.c:146
msgid "Data"
msgstr "数据"

#: app/flatpak-builtins-permission-remove.c:120
msgid "TABLE ID [APP_ID] - Remove item from permission store"
msgstr "表格 标识 [应用标识] - 从权限存储中移除项目"

#: app/flatpak-builtins-permission-remove.c:129
#: app/flatpak-builtins-permission-set.c:120
msgid "Too few arguments"
msgstr "参数太少"

#: app/flatpak-builtins-permission-reset.c:43
msgid "Reset all permissions"
msgstr "重置所有权限"

#: app/flatpak-builtins-permission-reset.c:144
msgid "APP_ID - Reset permissions for an app"
msgstr "应用标识 - 重置指定应用的权限"

#: app/flatpak-builtins-permission-reset.c:153
#: app/flatpak-builtins-permission-show.c:124
msgid "Wrong number of arguments"
msgstr "参数数量错误"

#: app/flatpak-builtins-permission-set.c:42
msgid "Associate DATA with the entry"
msgstr "将数据与条目相关联"

#: app/flatpak-builtins-permission-set.c:42
msgid "DATA"
msgstr "数据"

#: app/flatpak-builtins-permission-set.c:111
msgid "TABLE ID APP_ID [PERMISSION...] - Set permissions"
msgstr "表格 标识 应用标识 [权限…] - 设置权限"

#: app/flatpak-builtins-permission-set.c:132
#, c-format
msgid "Failed to parse '%s' as GVariant: "
msgstr "将“%s”作为 GVariant 解析失败："

#: app/flatpak-builtins-permission-show.c:115
msgid "APP_ID - Show permissions for an app"
msgstr "应用标识 - 显示指定应用的权限"

#: app/flatpak-builtins-pin.c:44
msgid "Remove matching pins"
msgstr "移除匹配的置顶"

#: app/flatpak-builtins-pin.c:56
msgid "[PATTERN…] - disable automatic removal of runtimes matching patterns"
msgstr "[匹配模式…] - 禁用对匹配匹配模式的运行时的自动移除"

#: app/flatpak-builtins-pin.c:75
#, c-format
msgid "No pinned patterns\n"
msgstr "没有置顶的匹配模式\n"

#: app/flatpak-builtins-pin.c:80
#, c-format
msgid "Pinned patterns:\n"
msgstr "置顶的匹配模式：\n"

#: app/flatpak-builtins-preinstall.c:80
msgid "- Install flatpaks that are part of the operating system"
msgstr "- 安装视为操作系统一部分的 flatpak"

#: app/flatpak-builtins-preinstall.c:118
#, c-format
msgid "Nothing to do.\n"
msgstr "无事可做。\n"

#: app/flatpak-builtins-ps.c:49
msgid "Instance"
msgstr "实例"

#: app/flatpak-builtins-ps.c:49
msgid "Show the instance ID"
msgstr "显示实例标识"

#: app/flatpak-builtins-ps.c:50 app/flatpak-builtins-run.c:178
msgid "PID"
msgstr "PID"

#: app/flatpak-builtins-ps.c:50
msgid "Show the PID of the wrapper process"
msgstr "显示封装器进程的进程标识"

#: app/flatpak-builtins-ps.c:51
msgid "Child-PID"
msgstr "子-PID"

#: app/flatpak-builtins-ps.c:51
msgid "Show the PID of the sandbox process"
msgstr "显示沙盒进程的进程标识"

#: app/flatpak-builtins-ps.c:54 app/flatpak-builtins-search.c:48
msgid "Show the application branch"
msgstr "显示应用程序分支"

#: app/flatpak-builtins-ps.c:55
msgid "Show the application commit"
msgstr "显示应用程序提交"

#: app/flatpak-builtins-ps.c:56
msgid "Show the runtime ID"
msgstr "显示运行时标识"

#: app/flatpak-builtins-ps.c:57
msgid "R.-Branch"
msgstr "R.-分支"

#: app/flatpak-builtins-ps.c:57
msgid "Show the runtime branch"
msgstr "显示运行时分支"

#: app/flatpak-builtins-ps.c:58
msgid "R.-Commit"
msgstr "R.-提交"

#: app/flatpak-builtins-ps.c:58
msgid "Show the runtime commit"
msgstr "显示运行时提交"

#: app/flatpak-builtins-ps.c:59
msgid "Active"
msgstr "活动"

#: app/flatpak-builtins-ps.c:59
msgid "Show whether the app is active"
msgstr "显示应用是否处于活动状态"

#: app/flatpak-builtins-ps.c:60
msgid "Background"
msgstr "背景"

#: app/flatpak-builtins-ps.c:60
msgid "Show whether the app is background"
msgstr "显示应用是否处于后台状态"

#: app/flatpak-builtins-ps.c:246
msgid " - Enumerate running sandboxes"
msgstr " - 列出正在运行的沙盒"

#: app/flatpak-builtins-remote-add.c:66
msgid "Do nothing if the provided remote exists"
msgstr "如果提供的远程仓库不存在则不进行任何操作"

#: app/flatpak-builtins-remote-add.c:67
msgid "LOCATION specifies a configuration file, not the repo location"
msgstr "该位置指定的是配置文件，不是仓库位置"

#: app/flatpak-builtins-remote-add.c:72 app/flatpak-builtins-remote-modify.c:78
msgid "Disable GPG verification"
msgstr "禁用 GPG 校验"

#: app/flatpak-builtins-remote-add.c:73 app/flatpak-builtins-remote-modify.c:79
msgid "Mark the remote as don't enumerate"
msgstr "将该远程仓库标记为不被列举"

#: app/flatpak-builtins-remote-add.c:74 app/flatpak-builtins-remote-modify.c:80
msgid "Mark the remote as don't use for deps"
msgstr "将该远程仓库标记为不被用于依赖"

#: app/flatpak-builtins-remote-add.c:75 app/flatpak-builtins-remote-modify.c:81
msgid "Set priority (default 1, higher is more prioritized)"
msgstr "设置优先级（默认 1，越高越优先）"

#: app/flatpak-builtins-remote-add.c:75 app/flatpak-builtins-remote-modify.c:81
msgid "PRIORITY"
msgstr "优先级"

#: app/flatpak-builtins-remote-add.c:76
msgid "The named subset to use for this remote"
msgstr "用于该远程仓库的已命名子集"

#: app/flatpak-builtins-remote-add.c:76 app/flatpak-builtins-remote-modify.c:71
msgid "SUBSET"
msgstr "子集"

#: app/flatpak-builtins-remote-add.c:77 app/flatpak-builtins-remote-modify.c:82
msgid "A nice name to use for this remote"
msgstr "用于该远程仓库的好名字"

#: app/flatpak-builtins-remote-add.c:78 app/flatpak-builtins-remote-modify.c:83
msgid "A one-line comment for this remote"
msgstr "用于该远程仓库的单行注释"

#: app/flatpak-builtins-remote-add.c:79 app/flatpak-builtins-remote-modify.c:84
msgid "A full-paragraph description for this remote"
msgstr "用于该远程仓库的完整分段描述"

#: app/flatpak-builtins-remote-add.c:80 app/flatpak-builtins-remote-modify.c:85
msgid "URL for a website for this remote"
msgstr "用于该远程仓库的网站地址"

#: app/flatpak-builtins-remote-add.c:81 app/flatpak-builtins-remote-modify.c:86
msgid "URL for an icon for this remote"
msgstr "用于该远程仓库的图标网址"

#: app/flatpak-builtins-remote-add.c:82 app/flatpak-builtins-remote-modify.c:87
msgid "Default branch to use for this remote"
msgstr "用于该远程仓库的默认分支"

#: app/flatpak-builtins-remote-add.c:84 app/flatpak-builtins-remote-modify.c:89
msgid "Import GPG key from FILE (- for stdin)"
msgstr "从文件导入 GPG 密钥（- 用于 stdin）"

#: app/flatpak-builtins-remote-add.c:85 app/flatpak-builtins-remote-modify.c:90
msgid "Load signatures from URL"
msgstr "从 URL 加载签名"

#: app/flatpak-builtins-remote-add.c:86 app/flatpak-builtins-remote-modify.c:92
msgid "Set path to local filter FILE"
msgstr "设置本地筛选器文件的路径"

#: app/flatpak-builtins-remote-add.c:87 app/flatpak-builtins-remote-modify.c:93
msgid "Disable the remote"
msgstr "禁用该远程仓库"

#: app/flatpak-builtins-remote-add.c:88 app/flatpak-builtins-remote-modify.c:94
msgid "Name of authenticator"
msgstr "身份验证器名称"

#: app/flatpak-builtins-remote-add.c:90 app/flatpak-builtins-remote-modify.c:96
msgid "Autoinstall authenticator"
msgstr "自动安装身份验证器"

#: app/flatpak-builtins-remote-add.c:91 app/flatpak-builtins-remote-modify.c:97
msgid "Don't autoinstall authenticator"
msgstr "不要自动安装身份验证器"

#: app/flatpak-builtins-remote-add.c:92 app/flatpak-builtins-remote-modify.c:99
msgid "Don't follow the redirect set in the summary file"
msgstr "不要跟随摘要文件中设置的重定向"

#: app/flatpak-builtins-remote-add.c:261 app/flatpak-builtins-remote-add.c:268
#, c-format
msgid "Can't load uri %s: %s\n"
msgstr "无法加载网址 %s：%s\n"

#: app/flatpak-builtins-remote-add.c:276 common/flatpak-dir.c:4643
#, c-format
msgid "Can't load file %s: %s\n"
msgstr "无法加载文件 %s：%s\n"

#: app/flatpak-builtins-remote-add.c:304
msgid "NAME LOCATION - Add a remote repository"
msgstr "名称 位置 - 添加远程仓库"

#: app/flatpak-builtins-remote-add.c:331
msgid "GPG verification is required if collections are enabled"
msgstr "如果启用了集合则需要 GPG 校验"

#: app/flatpak-builtins-remote-add.c:393
#, c-format
msgid "Remote %s already exists"
msgstr "远程仓库 %s 已经存在"

#: app/flatpak-builtins-remote-add.c:405
#: app/flatpak-builtins-remote-modify.c:340
#, c-format
msgid "Invalid authenticator name %s"
msgstr "无效的验证器名称 %s"

#: app/flatpak-builtins-remote-add.c:422
#, c-format
msgid "Warning: Could not update extra metadata for '%s': %s\n"
msgstr "警告：无法为“%s”更新额外元数据：%s\n"

#: app/flatpak-builtins-remote-delete.c:39
msgid "Remove remote even if in use"
msgstr "即使在使用中也要移除远程仓库"

#: app/flatpak-builtins-remote-delete.c:53
msgid "NAME - Delete a remote repository"
msgstr "名称 - 删除远程仓库"

#: app/flatpak-builtins-remote-delete.c:100
#, c-format
msgid "The following refs are installed from remote '%s':"
msgstr "下列引用是从远程仓库“%s”安装的："

#: app/flatpak-builtins-remote-delete.c:101
msgid "Remove them?"
msgstr "移除它们吗？"

#: app/flatpak-builtins-remote-delete.c:103
#, c-format
msgid "Can't remove remote '%s' with installed refs"
msgstr "无法移除具有已安装引用的远程仓库“%s”"

#: app/flatpak-builtins-remote-info.c:55
msgid "Commit to show info for"
msgstr "提交显示信息于"

#: app/flatpak-builtins-remote-info.c:58
msgid "Display log"
msgstr "显示日志"

#: app/flatpak-builtins-remote-info.c:61
msgid "Show parent"
msgstr "显示上级"

#: app/flatpak-builtins-remote-info.c:65 app/flatpak-builtins-remote-ls.c:60
msgid "Use local caches even if they are stale"
msgstr "即使它们是陈旧的仍要使用本地缓存"

#. Translators: A sideload is when you install from a local USB drive rather than the Internet.
#: app/flatpak-builtins-remote-info.c:67 app/flatpak-builtins-remote-ls.c:62
msgid "Only list refs available as sideloads"
msgstr "仅列出作为侧载可用的引用"

#: app/flatpak-builtins-remote-info.c:114
msgid ""
" REMOTE REF - Show information about an application or runtime in a remote"
msgstr " 远程仓库 引用 - 显示远程仓库中应用或运行时的有关信息"

#: app/flatpak-builtins-remote-info.c:125
msgid "REMOTE and REF must be specified"
msgstr "必须指定远程仓库和引用"

#: app/flatpak-builtins-remote-info.c:247
#: app/flatpak-builtins-remote-info.c:282
msgid "Download Size:"
msgstr "下载大小："

#: app/flatpak-builtins-remote-info.c:267
#: app/flatpak-builtins-remote-info.c:325
msgid "History:"
msgstr "历史："

#: app/flatpak-builtins-remote-info.c:348
msgid " Commit:"
msgstr " 提交："

#: app/flatpak-builtins-remote-info.c:349
msgid " Subject:"
msgstr " 主题："

#: app/flatpak-builtins-remote-info.c:350
msgid " Date:"
msgstr " 日期："

#: app/flatpak-builtins-remote-info.c:383
#, c-format
msgid "Warning: Commit %s has no flatpak metadata\n"
msgstr "警告：提交 %s 没有 flatpak 元数据\n"

#: app/flatpak-builtins-remote-list.c:43
msgid "Show remote details"
msgstr "显示远程仓库详情"

#: app/flatpak-builtins-remote-list.c:44
msgid "Show disabled remotes"
msgstr "显示禁用的远程仓库"

#: app/flatpak-builtins-remote-list.c:52
msgid "Title"
msgstr "标题"

#: app/flatpak-builtins-remote-list.c:52
msgid "Show the title"
msgstr "显示标题"

#: app/flatpak-builtins-remote-list.c:53
msgid "Show the URL"
msgstr "显示网址"

#: app/flatpak-builtins-remote-list.c:54
msgid "Show the collection ID"
msgstr "显示集合标识"

#: app/flatpak-builtins-remote-list.c:55 app/flatpak-builtins-repo.c:392
msgid "Subset"
msgstr "子集"

#: app/flatpak-builtins-remote-list.c:55
msgid "Show the subset"
msgstr "显示子集"

#: app/flatpak-builtins-remote-list.c:56
msgid "Filter"
msgstr "筛选器"

#: app/flatpak-builtins-remote-list.c:56
msgid "Show filter file"
msgstr "显示筛选器文件"

#: app/flatpak-builtins-remote-list.c:57
msgid "Priority"
msgstr "优先级"

#: app/flatpak-builtins-remote-list.c:57
msgid "Show the priority"
msgstr "显示优先级"

#: app/flatpak-builtins-remote-list.c:59
msgid "Comment"
msgstr "注释"

#: app/flatpak-builtins-remote-list.c:59
msgid "Show comment"
msgstr "显示评论"

#: app/flatpak-builtins-remote-list.c:60
msgid "Show description"
msgstr "显示说明"

#: app/flatpak-builtins-remote-list.c:61
msgid "Homepage"
msgstr "主页"

#: app/flatpak-builtins-remote-list.c:61
msgid "Show homepage"
msgstr "显示首页"

#: app/flatpak-builtins-remote-list.c:62
msgid "Icon"
msgstr "图标"

#: app/flatpak-builtins-remote-list.c:62
msgid "Show icon"
msgstr "显示图示"

#: app/flatpak-builtins-remote-list.c:231
msgid " - List remote repositories"
msgstr " - 列出远程仓库"

#: app/flatpak-builtins-remote-ls.c:52
msgid "Show arches and branches"
msgstr "显示架构和分支"

#: app/flatpak-builtins-remote-ls.c:53
msgid "Show only runtimes"
msgstr "仅显示运行时"

#: app/flatpak-builtins-remote-ls.c:54
msgid "Show only apps"
msgstr "仅显示应用"

#: app/flatpak-builtins-remote-ls.c:55
msgid "Show only those where updates are available"
msgstr "仅显示有可用更新的"

#: app/flatpak-builtins-remote-ls.c:56
msgid "Limit to this arch (* for all)"
msgstr "限制为该架构（* 为全部）"

#: app/flatpak-builtins-remote-ls.c:77
msgid "Show the runtime"
msgstr "显示运行时"

#: app/flatpak-builtins-remote-ls.c:79
msgid "Download size"
msgstr "下载大小"

#: app/flatpak-builtins-remote-ls.c:79
msgid "Show the download size"
msgstr "显示下载大小"

#: app/flatpak-builtins-remote-ls.c:391
msgid " [REMOTE or URI] - Show available runtimes and applications"
msgstr " [远程仓库或网址] - 显示可用的运行时和应用程序"

#: app/flatpak-builtins-remote-modify.c:67
msgid "Enable GPG verification"
msgstr "启用 GPG 校验"

#: app/flatpak-builtins-remote-modify.c:68
msgid "Mark the remote as enumerate"
msgstr "将该远程仓库标记为枚举的"

#: app/flatpak-builtins-remote-modify.c:69
msgid "Mark the remote as used for dependencies"
msgstr "将该远程仓库标记为用于依赖"

#: app/flatpak-builtins-remote-modify.c:70
msgid "Set a new URL"
msgstr "设置新网址"

#: app/flatpak-builtins-remote-modify.c:71
msgid "Set a new subset to use"
msgstr "设置要使用的新子集"

#: app/flatpak-builtins-remote-modify.c:72
msgid "Enable the remote"
msgstr "启用该远程仓库"

#: app/flatpak-builtins-remote-modify.c:73
msgid "Update extra metadata from the summary file"
msgstr "从摘要文件更新额外元数据"

#: app/flatpak-builtins-remote-modify.c:91
msgid "Disable local filter"
msgstr "禁用本地筛选器"

#: app/flatpak-builtins-remote-modify.c:95
msgid "Authenticator options"
msgstr "身份验证器选项"

#: app/flatpak-builtins-remote-modify.c:98
msgid "Follow the redirect set in the summary file"
msgstr "跟随摘要文件中的重定向设置"

#: app/flatpak-builtins-remote-modify.c:306
msgid "NAME - Modify a remote repository"
msgstr "名称 - 编辑远程仓库"

#: app/flatpak-builtins-remote-modify.c:316
msgid "Remote NAME must be specified"
msgstr "必须指定远程仓库名称"

#: app/flatpak-builtins-remote-modify.c:327
#, c-format
msgid "Updating extra metadata from remote summary for %s\n"
msgstr "正在从 %s 的远程仓库摘要更新额外元数据\n"

#: app/flatpak-builtins-remote-modify.c:330
#, c-format
msgid "Error updating extra metadata for '%s': %s\n"
msgstr "为“%s”更新额外元数据时出错：%s\n"

#: app/flatpak-builtins-remote-modify.c:331
#, c-format
msgid "Could not update extra metadata for %s"
msgstr "无法为 %s 更新额外元数据"

#: app/flatpak-builtins-repair.c:43
msgid "Don't make any changes"
msgstr "不要做任何修改"

#: app/flatpak-builtins-repair.c:44
msgid "Reinstall all refs"
msgstr "重新安装所有引用"

#: app/flatpak-builtins-repair.c:68
#, c-format
msgid "Object missing: %s.%s\n"
msgstr "对象缺失：%s.%s\n"

#: app/flatpak-builtins-repair.c:76
#, c-format
msgid "Object invalid: %s.%s\n"
msgstr "对象无效：%s.%s\n"

#: app/flatpak-builtins-repair.c:81
#, c-format
msgid "%s, deleting object\n"
msgstr "%s，正在删除对象\n"

#: app/flatpak-builtins-repair.c:146
#, c-format
msgid "Can't load object %s: %s\n"
msgstr "无法加载对象 %s：%s\n"

#: app/flatpak-builtins-repair.c:228
#, c-format
msgid "Commit invalid %s: %s\n"
msgstr "无效的提交 %s：%s\n"

#: app/flatpak-builtins-repair.c:231
#, c-format
msgid "Deleting invalid commit %s: %s\n"
msgstr "正在删除无效的提交 %s：%s\n"

#: app/flatpak-builtins-repair.c:261
#, c-format
msgid "Commit should be marked partial: %s\n"
msgstr "提交应被标记为部分的：%s\n"

#: app/flatpak-builtins-repair.c:264
#, c-format
msgid "Marking commit as partial: %s\n"
msgstr "正在标记提交为部分的：%s\n"

#: app/flatpak-builtins-repair.c:293
#, c-format
msgid "Problems loading data for %s: %s\n"
msgstr "为 %s 加载数据时出现问题：%s\n"

#: app/flatpak-builtins-repair.c:306
#, c-format
msgid "Error reinstalling %s: %s\n"
msgstr "重新安装 %s 时出错：%s\n"

#: app/flatpak-builtins-repair.c:327
msgid "- Repair a flatpak installation"
msgstr "- 修复 flatpak 安装"

#: app/flatpak-builtins-repair.c:406
#, c-format
msgid "Removing non-deployed ref %s…\n"
msgstr "正在移除非部署的引用 %s…\n"

#: app/flatpak-builtins-repair.c:411
#, c-format
msgid "Skipping non-deployed ref %s…\n"
msgstr "正在跳过非部署的引用 %s…\n"

#: app/flatpak-builtins-repair.c:429
#, c-format
msgid "[%d/%d] Verifying %s…\n"
msgstr "[%d/%d] 正在校验 %s…\n"

#: app/flatpak-builtins-repair.c:435
#, c-format
msgid "Dry run: "
msgstr "演练："

#: app/flatpak-builtins-repair.c:440
#, c-format
msgid "Deleting ref %s due to missing objects\n"
msgstr "由于缺失对象正在删除引用 %s\n"

#: app/flatpak-builtins-repair.c:444
#, c-format
msgid "Deleting ref %s due to invalid objects\n"
msgstr "由于无效对象正在删除引用 %s\n"

#: app/flatpak-builtins-repair.c:448
#, c-format
msgid "Deleting ref %s due to %d\n"
msgstr "由于 %2$d 正在删除引用 %1$s\n"

#: app/flatpak-builtins-repair.c:464
#, c-format
msgid "Checking remotes...\n"
msgstr "正在检查远程仓库…\n"

#: app/flatpak-builtins-repair.c:482
#, c-format
msgid "Remote %s for ref %s is missing\n"
msgstr "引用 %2$s 的远程仓库 %1$s 缺失\n"

#: app/flatpak-builtins-repair.c:484
#, c-format
msgid "Remote %s for ref %s is disabled\n"
msgstr "引用 %2$s 的远程仓库 %1$s 已禁用\n"

#: app/flatpak-builtins-repair.c:490
#, c-format
msgid "Pruning objects\n"
msgstr "正在修剪对象\n"

#: app/flatpak-builtins-repair.c:498
#, c-format
msgid "Erasing .removed\n"
msgstr "正在擦除 .removed\n"

#: app/flatpak-builtins-repair.c:524
#, c-format
msgid "Reinstalling refs\n"
msgstr "重新安装引用\n"

#: app/flatpak-builtins-repair.c:526
#, c-format
msgid "Reinstalling removed refs\n"
msgstr "重新安装已移除的引用\n"

#: app/flatpak-builtins-repair.c:551
#, c-format
msgid "While removing appstream for %s: "
msgstr "正在移除 %s 的 appstream 时："

#: app/flatpak-builtins-repair.c:558
#, c-format
msgid "While deploying appstream for %s: "
msgstr "正在部署 %s 的 appstream 时："

#: app/flatpak-builtins-repo.c:106
#, c-format
msgid "Repo mode: %s\n"
msgstr "仓库模式：%s\n"

#: app/flatpak-builtins-repo.c:113
#, c-format
msgid "Indexed summaries: %s\n"
msgstr "索引的摘要：%s\n"

#: app/flatpak-builtins-repo.c:113 app/flatpak-builtins-repo.c:139
#: app/flatpak-builtins-repo.c:172
msgid "true"
msgstr "正确的"

#: app/flatpak-builtins-repo.c:113 app/flatpak-builtins-repo.c:139
#: app/flatpak-builtins-repo.c:172
msgid "false"
msgstr "失败的"

#: app/flatpak-builtins-repo.c:121
#, c-format
msgid "Subsummaries: "
msgstr "子摘要："

#: app/flatpak-builtins-repo.c:136
#, c-format
msgid "Cache version: %d\n"
msgstr "缓存版本：%d\n"

#: app/flatpak-builtins-repo.c:139
#, c-format
msgid "Indexed deltas: %s\n"
msgstr "索引的增量：%s\n"

#: app/flatpak-builtins-repo.c:142
#, c-format
msgid "Title: %s\n"
msgstr "标题：%s\n"

#: app/flatpak-builtins-repo.c:145
#, c-format
msgid "Comment: %s\n"
msgstr "评论：%s\n"

#: app/flatpak-builtins-repo.c:148
#, c-format
msgid "Description: %s\n"
msgstr "描述：%s\n"

#: app/flatpak-builtins-repo.c:151
#, c-format
msgid "Homepage: %s\n"
msgstr "主页：%s\n"

#: app/flatpak-builtins-repo.c:154
#, c-format
msgid "Icon: %s\n"
msgstr "图标：%s\n"

#: app/flatpak-builtins-repo.c:157
#, c-format
msgid "Collection ID: %s\n"
msgstr "集合标识：%s\n"

#: app/flatpak-builtins-repo.c:160
#, c-format
msgid "Default branch: %s\n"
msgstr "默认分支：%s\n"

#: app/flatpak-builtins-repo.c:163
#, c-format
msgid "Redirect URL: %s\n"
msgstr "重定向网址：%s\n"

#: app/flatpak-builtins-repo.c:166
#, c-format
msgid "Deploy collection ID: %s\n"
msgstr "部署集合标识：%s\n"

#: app/flatpak-builtins-repo.c:169
#, c-format
msgid "Authenticator name: %s\n"
msgstr "身份验证器名称：%s\n"

#: app/flatpak-builtins-repo.c:172
#, c-format
msgid "Authenticator install: %s\n"
msgstr "身份验证器安装：%s\n"

#: app/flatpak-builtins-repo.c:180
#, c-format
msgid "GPG key hash: %s\n"
msgstr "GPG 密钥哈希：%s\n"

#: app/flatpak-builtins-repo.c:184
#, c-format
msgid "%zd summary branches\n"
msgstr "%zd 摘要分支\n"

#: app/flatpak-builtins-repo.c:336
msgid "Installed"
msgstr "已安装"

#. Translators: Download is used here as a noun
#: app/flatpak-builtins-repo.c:338 app/flatpak-cli-transaction.c:1462
msgid "Download"
msgstr "下载"

#: app/flatpak-builtins-repo.c:339
msgid "Subsets"
msgstr "子集"

#: app/flatpak-builtins-repo.c:393
msgid "Digest"
msgstr "摘要"

#: app/flatpak-builtins-repo.c:394
msgid "History length"
msgstr "历史长度"

#: app/flatpak-builtins-repo.c:711
msgid "Print general information about the repository"
msgstr "显示有关仓库的常规信息"

#: app/flatpak-builtins-repo.c:712
msgid "List the branches in the repository"
msgstr "列出仓库中的分支"

#: app/flatpak-builtins-repo.c:713
msgid "Print metadata for a branch"
msgstr "显示分支的元数据"

#: app/flatpak-builtins-repo.c:714
msgid "Show commits for a branch"
msgstr "显示分支的提交"

#: app/flatpak-builtins-repo.c:715
msgid "Print information about the repo subsets"
msgstr "显示有关仓库子集的信息"

#: app/flatpak-builtins-repo.c:716
msgid "Limit information to subsets with this prefix"
msgstr "限制为带有该前缀的子集的信息"

#: app/flatpak-builtins-repo.c:732
msgid "LOCATION - Repository maintenance"
msgstr "位置 - 仓库维护"

#: app/flatpak-builtins-run.c:159
msgid "Command to run"
msgstr "要运行的命令"

#: app/flatpak-builtins-run.c:160
msgid "Directory to run the command in"
msgstr "要在其中运行命令的目录"

#: app/flatpak-builtins-run.c:161
msgid "Branch to use"
msgstr "要使用的分支"

#: app/flatpak-builtins-run.c:162
msgid "Use development runtime"
msgstr "使用开发运行时"

#: app/flatpak-builtins-run.c:163
msgid "Runtime to use"
msgstr "要使用的运行时"

#: app/flatpak-builtins-run.c:164
msgid "Runtime version to use"
msgstr "要使用的运行时版本"

#: app/flatpak-builtins-run.c:167
msgid "Log accessibility bus calls"
msgstr "日志可访问性总线调用"

#: app/flatpak-builtins-run.c:168
msgid "Don't proxy accessibility bus calls"
msgstr "不要代理可访问性总线调用"

#: app/flatpak-builtins-run.c:169
msgid "Proxy accessibility bus calls (default except when sandboxed)"
msgstr "代理可访问性总线调用（沙盒以外情况下默认）"

#: app/flatpak-builtins-run.c:170
msgid "Don't proxy session bus calls"
msgstr "不要代理会话总线调用"

#: app/flatpak-builtins-run.c:171
msgid "Proxy session bus calls (default except when sandboxed)"
msgstr "代理会话总线调用（沙盒以外情况下默认）"

#: app/flatpak-builtins-run.c:172
msgid "Don't start portals"
msgstr "不要启动传送门"

#: app/flatpak-builtins-run.c:173
msgid "Enable file forwarding"
msgstr "启用文件转发"

#: app/flatpak-builtins-run.c:174
msgid "Run specified commit"
msgstr "运行指定的提交"

#: app/flatpak-builtins-run.c:175
msgid "Use specified runtime commit"
msgstr "使用指定的运行时提交"

#: app/flatpak-builtins-run.c:176
msgid "Run completely sandboxed"
msgstr "完全沙盒运行"

#: app/flatpak-builtins-run.c:178
msgid "Use PID as parent pid for sharing namespaces"
msgstr "使用 PID 作为共享命名空间的上级进程标识"

#: app/flatpak-builtins-run.c:179
msgid "Make processes visible in parent namespace"
msgstr "使进程在上级命名空间中可见"

#: app/flatpak-builtins-run.c:180
msgid "Share process ID namespace with parent"
msgstr "与上级共享进程标识命名空间"

#: app/flatpak-builtins-run.c:181
msgid "Write the instance ID to the given file descriptor"
msgstr "将实例标识写入到给定的文件描述符"

#: app/flatpak-builtins-run.c:182
msgid "Use PATH instead of the app's /app"
msgstr "使用路径替代应用的 /app"

#: app/flatpak-builtins-run.c:183
msgid "Use FD instead of the app's /app"
msgstr "使用 FD 替代应用的 /app"

#: app/flatpak-builtins-run.c:183 app/flatpak-builtins-run.c:185
#: app/flatpak-builtins-run.c:187 app/flatpak-builtins-run.c:188
#: common/flatpak-context.c:2672
msgid "FD"
msgstr "FD"

#: app/flatpak-builtins-run.c:184
msgid "Use PATH instead of the runtime's /usr"
msgstr "使用路径替代运行时的 /usr"

#: app/flatpak-builtins-run.c:185
msgid "Use FD instead of the runtime's /usr"
msgstr "使用 FD 替代运行时的 /usr"

#: app/flatpak-builtins-run.c:186
msgid "Clear all outside environment variables"
msgstr "清除所有外部环境变量"

#: app/flatpak-builtins-run.c:187
msgid ""
"Bind mount the file or directory referred to by FD to its canonicalized path"
msgstr "将 FD 所指的文件或目录绑定挂载到其自身的规范化路径上"

#: app/flatpak-builtins-run.c:188
msgid ""
"Bind mount the file or directory referred to by FD read-only to its "
"canonicalized path"
msgstr "将 FD 所指的文件或目录以只读方式绑定挂载到其自身的规范化路径上"

#: app/flatpak-builtins-run.c:219
msgid "APP [ARGUMENT…] - Run an app"
msgstr "应用 [参数…] - 运行应用"

#: app/flatpak-builtins-run.c:370
#, c-format
msgid "runtime/%s/%s/%s not installed"
msgstr "运行时 /%s/%s/%s 未安装"

#: app/flatpak-builtins-run.c:419
msgid "app-fd and app-path cannot both be used"
msgstr "无法同时使用 app-fd 和 app-path"

#: app/flatpak-builtins-run.c:449
msgid "usr-fd and usr-path cannot both be used"
msgstr "无法同时使用 usr-fd 和 usr-path"

#: app/flatpak-builtins-search.c:37
msgid "Arch to search for"
msgstr "要搜索的架构"

#: app/flatpak-builtins-search.c:49
msgid "Remotes"
msgstr "远程仓库"

#: app/flatpak-builtins-search.c:49
msgid "Show the remotes"
msgstr "显示远程仓库"

#: app/flatpak-builtins-search.c:244
msgid "TEXT - Search remote apps/runtimes for text"
msgstr "文字 - 搜索含指定文字的远程应用/运行时"

#: app/flatpak-builtins-search.c:255
msgid "TEXT must be specified"
msgstr "必须指定文字"

#: app/flatpak-builtins-search.c:338
msgid "No matches found"
msgstr "找不到匹配项"

#: app/flatpak-builtins-uninstall.c:54
msgid "Arch to uninstall"
msgstr "要卸载的架构"

#: app/flatpak-builtins-uninstall.c:55
msgid "Keep ref in local repository"
msgstr "将引用保存在本地仓库中"

#: app/flatpak-builtins-uninstall.c:56
msgid "Don't uninstall related refs"
msgstr "不要卸载相关引用"

#: app/flatpak-builtins-uninstall.c:57
msgid "Remove files even if running"
msgstr "即使正在运行仍移除文件"

#: app/flatpak-builtins-uninstall.c:60
msgid "Uninstall all"
msgstr "全部卸载"

#: app/flatpak-builtins-uninstall.c:61
msgid "Uninstall unused"
msgstr "卸载未使用的"

#: app/flatpak-builtins-uninstall.c:62
msgid "Delete app data"
msgstr "删除应用数据"

#: app/flatpak-builtins-uninstall.c:141
#, c-format
msgid "Delete data for %s?"
msgstr "删除 %s 的数据吗？"

#: app/flatpak-builtins-uninstall.c:220
#, c-format
msgid "Info: applications using the extension %s%s%s branch %s%s%s:\n"
msgstr "信息：使用扩展 %s%s%s 分支 %s%s%s 的应用程序：\n"

#: app/flatpak-builtins-uninstall.c:223
#, c-format
msgid "Info: applications using the runtime %s%s%s branch %s%s%s:\n"
msgstr "信息：使用运行时 %s%s%s 分支 %s%s%s 的应用程序：\n"

#: app/flatpak-builtins-uninstall.c:238
msgid "Really remove?"
msgstr "确定移除吗？"

#: app/flatpak-builtins-uninstall.c:255
msgid "[REF…] - Uninstall applications or runtimes"
msgstr "[引用…] - 卸载应用程序或运行时"

#: app/flatpak-builtins-uninstall.c:264
msgid "Must specify at least one REF, --unused, --all or --delete-data"
msgstr "必须至少指定一个引用、--unused、--all 或 --delete-data"

#: app/flatpak-builtins-uninstall.c:267
msgid "Must not specify REFs when using --all"
msgstr "使用 --all 时不能指定引用"

#: app/flatpak-builtins-uninstall.c:270
msgid "Must not specify REFs when using --unused"
msgstr "使用 --unused 时不能指定引用"

#: app/flatpak-builtins-uninstall.c:336
#, c-format
msgid ""
"\n"
"These runtimes in installation '%s' are pinned and won't be removed; see "
"flatpak-pin(1):\n"
msgstr ""
"\n"
"这些运行时在安装“%s”中是置顶的且不会被移除；查阅 flatpak-pin(1)：\n"

#: app/flatpak-builtins-uninstall.c:370
#, c-format
msgid "Nothing unused to uninstall\n"
msgstr "无可卸载的未使用项目\n"

#: app/flatpak-builtins-uninstall.c:444
#, c-format
msgid "No installed refs found for ‘%s’"
msgstr "未找到用于“%s”的已安装引用"

#: app/flatpak-builtins-uninstall.c:447
#, c-format
msgid " with arch ‘%s’"
msgstr "‘%s’ 架构"

#: app/flatpak-builtins-uninstall.c:449
#, c-format
msgid " with branch ‘%s’"
msgstr "‘%s’ 分支"

#: app/flatpak-builtins-uninstall.c:456
#, c-format
msgid "Warning: %s is not installed\n"
msgstr "警告：%s 未安装\n"

#: app/flatpak-builtins-uninstall.c:490
#, c-format
msgid "None of the specified refs are installed"
msgstr "指定的引用都没有安装"

#: app/flatpak-builtins-uninstall.c:599
#, c-format
msgid "No app data to delete\n"
msgstr "无可删除的应用数据\n"

#: app/flatpak-builtins-update.c:56
msgid "Arch to update for"
msgstr "要更新的架构"

#: app/flatpak-builtins-update.c:57
msgid "Commit to deploy"
msgstr "要部署的提交"

#: app/flatpak-builtins-update.c:58
msgid "Remove old files even if running"
msgstr "即使正在运行仍删除旧文件"

#: app/flatpak-builtins-update.c:59
msgid "Don't pull, only update from local cache"
msgstr "不要远程提取，仅从本地缓存更新"

#: app/flatpak-builtins-update.c:61
msgid "Don't update related refs"
msgstr "不要更新相关引用"

#: app/flatpak-builtins-update.c:66
msgid "Update appstream for remote"
msgstr "为远程仓库更新 appstream"

#: app/flatpak-builtins-update.c:67
msgid "Only update this subpath"
msgstr "仅更新此子路径"

#: app/flatpak-builtins-update.c:90
msgid "[REF…] - Update applications or runtimes"
msgstr "[引用…] - 更新应用程序或运行时"

#: app/flatpak-builtins-update.c:121
msgid "With --commit, only one REF may be specified"
msgstr "带有 --commit，仅可指定一个引用"

#: app/flatpak-builtins-update.c:162
#, c-format
msgid "Looking for updates…\n"
msgstr "正在查找更新…\n"

#: app/flatpak-builtins-update.c:215
#, c-format
msgid "Unable to update %s: %s\n"
msgstr "无法更新 %s：%s\n"

#: app/flatpak-builtins-update.c:274
#, c-format
msgid "Nothing to update.\n"
msgstr "没有更新。\n"

#: app/flatpak-builtins-utils.c:337
#, c-format
msgid ""
"Remote ‘%s’ found in multiple installations, unable to proceed in non-"
"interactive mode"
msgstr "在多个安装中发现远程仓库“%s”，无法在非交互模式中继续"

#: app/flatpak-builtins-utils.c:346
#, c-format
msgid "Remote ‘%s’ found in multiple installations:"
msgstr "在多个安装中发现远程仓库“%s”："

#: app/flatpak-builtins-utils.c:347 app/flatpak-builtins-utils.c:442
#: app/flatpak-builtins-utils.c:538 app/flatpak-builtins-utils.c:540
#: app/flatpak-builtins-utils.c:598
msgid "Which do you want to use (0 to abort)?"
msgstr "您要使用哪个（0 为放弃）？"

#: app/flatpak-builtins-utils.c:349
#, c-format
msgid "No remote chosen to resolve ‘%s’ which exists in multiple installations"
msgstr "没有选择远程仓库以解决存在于多个安装中的“%s”"

#: app/flatpak-builtins-utils.c:358
#, c-format
msgid ""
"Remote \"%s\" not found\n"
"Hint: Use flatpak remote-add to add a remote"
msgstr ""
"未找到远程仓库“%s”\n"
"提示：使用 flatpak remote-add 来添加远程仓库"

#: app/flatpak-builtins-utils.c:364
#, c-format
msgid "Remote \"%s\" not found in the %s installation"
msgstr "在 %2$s 安装中未发现远程仓库“%1$s”"

#: app/flatpak-builtins-utils.c:404
#, c-format
msgid "Multiple refs match ‘%s’, unable to proceed in non-interactive mode"
msgstr "多个引用与“%s”匹配，无法在非交互模式中继续"

#. default to yes on Enter
#: app/flatpak-builtins-utils.c:430
#, c-format
msgid ""
"Found ref ‘%s’ in remote ‘%s’ (%s).\n"
"Use this ref?"
msgstr ""
"在远程仓库“%2$s”（%3$s）中找到引用“%1$s”。\n"
"使用该引用吗？"

#: app/flatpak-builtins-utils.c:434 app/flatpak-builtins-utils.c:444
#: app/flatpak-builtins-utils.c:522 app/flatpak-builtins-utils.c:543
#, c-format
msgid "No ref chosen to resolve matches for ‘%s’"
msgstr "未选择引用来解决“%s”的匹配项"

#: app/flatpak-builtins-utils.c:440
#, c-format
msgid "Similar refs found for ‘%s’ in remote ‘%s’ (%s):"
msgstr "在远程仓库“%2$s”（%3$s）中找到与“%1$s”相似的引用："

#: app/flatpak-builtins-utils.c:488
#, c-format
msgid ""
"Multiple installed refs match ‘%s’, unable to proceed in non-interactive mode"
msgstr "多个已安装引用与“%s”匹配，无法在非交互模式中继续"

#. default to yes on Enter
#: app/flatpak-builtins-utils.c:518
#, c-format
msgid "Found installed ref ‘%s’ (%s). Is this correct?"
msgstr "找到已安装的引用“%s”（%s）。这结果正确吗？"

#: app/flatpak-builtins-utils.c:534
#, c-format
msgid "All of the above"
msgstr "上面全部"

#: app/flatpak-builtins-utils.c:535
#, c-format
msgid "Similar installed refs found for ‘%s’:"
msgstr "找到与“%s”相似的已安装引用："

#: app/flatpak-builtins-utils.c:579
#, c-format
msgid ""
"Multiple remotes have refs matching ‘%s’, unable to proceed in non-"
"interactive mode"
msgstr "多个远程仓库都有与“%s”匹配的引用，无法在非交互模式中继续"

#: app/flatpak-builtins-utils.c:597
#, c-format
msgid "Remotes found with refs similar to ‘%s’:"
msgstr "找到具有与“%s”相似引用的远程仓库："

#: app/flatpak-builtins-utils.c:600
#, c-format
msgid "No remote chosen to resolve matches for ‘%s’"
msgstr "未选择远程仓库以解决“%s”的匹配项"

#: app/flatpak-builtins-utils.c:696 app/flatpak-builtins-utils.c:699
#, c-format
msgid "Updating appstream data for user remote %s"
msgstr "正在为用户远程仓库 %s 更新 appstream 数据"

#: app/flatpak-builtins-utils.c:706 app/flatpak-builtins-utils.c:709
#, c-format
msgid "Updating appstream data for remote %s"
msgstr "正在为远程仓库 %s 更新 appstream 数据"

#: app/flatpak-builtins-utils.c:717 app/flatpak-builtins-utils.c:719
msgid "Error updating"
msgstr "更新时出错"

#: app/flatpak-builtins-utils.c:755
#, c-format
msgid "Remote \"%s\" not found"
msgstr "未找到远程仓库“%s”"

#: app/flatpak-builtins-utils.c:796
#, c-format
msgid "Ambiguous suffix: '%s'."
msgstr "后缀不明确：“%s”。"

#. Translators: don't translate the values
#: app/flatpak-builtins-utils.c:798 app/flatpak-builtins-utils.c:813
msgid "Possible values are :s[tart], :m[iddle], :e[nd] or :f[ull]"
msgstr "可能的值为 :s[tart]、:m[iddle]、:e[nd] 或 :f[ull]"

#: app/flatpak-builtins-utils.c:811
#, c-format
msgid "Invalid suffix: '%s'."
msgstr "无效后缀：“%s”。"

#: app/flatpak-builtins-utils.c:846
#, c-format
msgid "Ambiguous column: %s"
msgstr "列不明确：%s"

#: app/flatpak-builtins-utils.c:859
#, c-format
msgid "Unknown column: %s"
msgstr "未知列：%s"

#: app/flatpak-builtins-utils.c:917
msgid "Available columns:\n"
msgstr "可用列：\n"

#: app/flatpak-builtins-utils.c:927
msgid "Show all columns"
msgstr "显示所有列"

#: app/flatpak-builtins-utils.c:928
msgid "Show available columns"
msgstr "显示可用列"

#: app/flatpak-builtins-utils.c:931
msgid "Append :s[tart], :m[iddle], :e[nd] or :f[ull] to change ellipsization"
msgstr "附加 :s[tart]、:m[iddle]、:e[nd] 或 :f[ull] 以更改文字省略位置"

#: app/flatpak-builtins-utils.c:1483
#, c-format
msgid "Unknown scheme in sideload location %s"
msgstr "侧载位置中有未知方案 %s"

#: app/flatpak-cli-transaction.c:96 app/flatpak-cli-transaction.c:102
#, c-format
msgid "Required runtime for %s (%s) found in remote %s\n"
msgstr "在远程仓库 %3$s 中找到 %1$s（%2$s）需要的运行时\n"

#: app/flatpak-cli-transaction.c:104
msgid "Do you want to install it?"
msgstr "您想要安装它吗？"

#: app/flatpak-cli-transaction.c:110
#, c-format
msgid "Required runtime for %s (%s) found in remotes:"
msgstr "在远程仓库中找到 %s（%s）需要的运行时："

#: app/flatpak-cli-transaction.c:112
msgid "Which do you want to install (0 to abort)?"
msgstr "您要安装哪个（0 为放弃）？"

#: app/flatpak-cli-transaction.c:132
#, c-format
msgid "Configuring %s as new remote '%s'\n"
msgstr "将 %s 配置为新的远程仓库“%s”\n"

#. default to yes on Enter
#: app/flatpak-cli-transaction.c:139
#, c-format
msgid ""
"The remote '%s', referred to by '%s' at location %s contains additional "
"applications.\n"
"Should the remote be kept for future installations?"
msgstr ""
"由位于 %3$s 的“%2$s”指向的远程仓库“%1$s”包含额外的应用程序。\n"
"要保留该远程仓库以用于未来的安装吗？"

#. default to yes on Enter
#: app/flatpak-cli-transaction.c:147
#, c-format
msgid ""
"The application %s depends on runtimes from:\n"
"  %s\n"
"Configure this as new remote '%s'"
msgstr ""
"应用程序 %s 依赖的运行时来自于：\n"
"  %s\n"
"将其配置为新的远程仓库“%s”"

#. Formatted size/remaining time in seconds
#: app/flatpak-cli-transaction.c:321
#, c-format
msgid "%s/s%s%s"
msgstr "%s/s%s%s"

#. Download progress percentage, use the appropriate
#. percent format for your language
#: app/flatpak-cli-transaction.c:359
#, c-format
msgid "%3d%%"
msgstr "%3d%%"

#: app/flatpak-cli-transaction.c:414
msgid "Installing…"
msgstr "正在安装…"

#: app/flatpak-cli-transaction.c:416
#, c-format
msgid "Installing %d/%d…"
msgstr "正在安装 %d/%d…"

#: app/flatpak-cli-transaction.c:421
msgid "Updating…"
msgstr "正在更新…"

#: app/flatpak-cli-transaction.c:423
#, c-format
msgid "Updating %d/%d…"
msgstr "正在更新 %d/%d…"

#: app/flatpak-cli-transaction.c:428
msgid "Uninstalling…"
msgstr "正在卸载…"

#: app/flatpak-cli-transaction.c:430
#, c-format
msgid "Uninstalling %d/%d…"
msgstr "正在卸载 %d/%d…"

#: app/flatpak-cli-transaction.c:496 app/flatpak-quiet-transaction.c:161
#, c-format
msgid "Info: %s was skipped"
msgstr "信息：%s 已跳过"

#: app/flatpak-cli-transaction.c:519
#, c-format
msgid "Warning: %s%s%s already installed"
msgstr "警告：%s%s%s 已安装"

#: app/flatpak-cli-transaction.c:522
#, c-format
msgid "Error: %s%s%s already installed"
msgstr "错误：%s%s%s 已安装"

#: app/flatpak-cli-transaction.c:528
#, c-format
msgid "Warning: %s%s%s not installed"
msgstr "警告：%s%s%s 未安装"

#: app/flatpak-cli-transaction.c:531
#, c-format
msgid "Error: %s%s%s not installed"
msgstr "错误：%s%s%s 未安装"

#: app/flatpak-cli-transaction.c:537
#, c-format
msgid "Warning: %s%s%s needs a later flatpak version"
msgstr "警告：%s%s%s 需要更高的 flatpak 版本"

#: app/flatpak-cli-transaction.c:540
#, c-format
msgid "Error: %s%s%s needs a later flatpak version"
msgstr "错误：%s%s%s 需要更高的 flatpak 版本"

#: app/flatpak-cli-transaction.c:546
msgid "Warning: Not enough disk space to complete this operation"
msgstr "警告：没有足够的硬盘空间以完成该操作"

#: app/flatpak-cli-transaction.c:548
msgid "Error: Not enough disk space to complete this operation"
msgstr "错误：没有足够的硬盘空间以完成该操作"

#: app/flatpak-cli-transaction.c:553
#, c-format
msgid "Warning: %s"
msgstr "警告：%s"

#: app/flatpak-cli-transaction.c:555
#, c-format
msgid "Error: %s"
msgstr "错误：%s"

#: app/flatpak-cli-transaction.c:570
#, c-format
msgid "Failed to install %s%s%s: "
msgstr "安装 %s%s%s 失败："

#: app/flatpak-cli-transaction.c:577
#, c-format
msgid "Failed to update %s%s%s: "
msgstr "更新 %s%s%s 失败"

#: app/flatpak-cli-transaction.c:584
#, c-format
msgid "Failed to install bundle %s%s%s: "
msgstr "安装捆绑包 %s%s%s 失败："

#: app/flatpak-cli-transaction.c:591
#, c-format
msgid "Failed to uninstall %s%s%s: "
msgstr "卸载 %s%s%s 失败："

#: app/flatpak-cli-transaction.c:642
#, c-format
msgid "Authentication required for remote '%s'\n"
msgstr "远程仓库“%s”需要身份验证\n"

#: app/flatpak-cli-transaction.c:643
msgid "Open browser?"
msgstr "打开浏览器吗？"

#: app/flatpak-cli-transaction.c:699
#, c-format
msgid "Login required remote %s (realm %s)\n"
msgstr "需要登录的远程仓库 %s（域 %s）\n"

#: app/flatpak-cli-transaction.c:704
msgid "Password"
msgstr "密码"

#. Only runtimes can be pinned
#: app/flatpak-cli-transaction.c:759
#, c-format
msgid ""
"\n"
"Info: (pinned) runtime %s%s%s branch %s%s%s is end-of-life, in favor of "
"%s%s%s branch %s%s%s\n"
msgstr ""
"\n"
"信息：（已置顶）运行时 %s%s%s 分支 %s%s%s 已结束生命周期，替代为 %s%s%s 分支 "
"%s%s%s\n"

#: app/flatpak-cli-transaction.c:765
#, c-format
msgid ""
"\n"
"Info: runtime %s%s%s branch %s%s%s is end-of-life, in favor of %s%s%s branch "
"%s%s%s\n"
msgstr ""
"\n"
"信息：运行时 %s%s%s 分支 %s%s%s 已结束生命周期，替代为 %s%s%s 分支 %s%s%s\n"

#: app/flatpak-cli-transaction.c:768
#, c-format
msgid ""
"\n"
"Info: app %s%s%s branch %s%s%s is end-of-life, in favor of %s%s%s branch "
"%s%s%s\n"
msgstr ""
"\n"
"信息：应用 %s%s%s 分支 %s%s%s 已结束生命周期，替代为 %s%s%s 分支 %s%s%s\n"

#. Only runtimes can be pinned
#: app/flatpak-cli-transaction.c:780
#, c-format
msgid ""
"\n"
"Info: (pinned) runtime %s%s%s branch %s%s%s is end-of-life, with reason:\n"
msgstr ""
"\n"
"信息：（已置顶）运行时 %s%s%s 分支 %s%s%s 已结束生命周期，原因：\n"

#: app/flatpak-cli-transaction.c:786
#, c-format
msgid ""
"\n"
"Info: runtime %s%s%s branch %s%s%s is end-of-life, with reason:\n"
msgstr ""
"\n"
"信息：运行时 %s%s%s 分支 %s%s%s 已结束生命周期，原因：\n"

#: app/flatpak-cli-transaction.c:789
#, c-format
msgid ""
"\n"
"Info: app %s%s%s branch %s%s%s is end-of-life, with reason:\n"
msgstr ""
"\n"
"信息：应用 %s%s%s 分支 %s%s%s 已结束生命周期，原因：\n"

#: app/flatpak-cli-transaction.c:963
#, c-format
msgid "Info: applications using this extension:\n"
msgstr "信息：使用该扩展的应用程序：\n"

#: app/flatpak-cli-transaction.c:965
#, c-format
msgid "Info: applications using this runtime:\n"
msgstr "信息：使用该运行时的应用程序：\n"

#: app/flatpak-cli-transaction.c:984
msgid "Replace?"
msgstr "替换吗？"

#: app/flatpak-cli-transaction.c:987 app/flatpak-quiet-transaction.c:247
#, c-format
msgid "Updating to rebased version\n"
msgstr "正在更新到重新建基版本\n"

#: app/flatpak-cli-transaction.c:1011
#, c-format
msgid "Failed to rebase %s to %s: "
msgstr "重新建基 %s 至 %s 失败："

#: app/flatpak-cli-transaction.c:1277
#, c-format
msgid "New %s%s%s permissions:"
msgstr "新的 %s%s%s 权限："

#: app/flatpak-cli-transaction.c:1279
#, c-format
msgid "%s%s%s permissions:"
msgstr "%s%s%s 权限："

#: app/flatpak-cli-transaction.c:1343
msgid "Warning: "
msgstr "警告："

#. translators: This is short for operation, the title of a one-char column
#: app/flatpak-cli-transaction.c:1442
msgid "Op"
msgstr "操作"

#. Avoid resizing the download column too much,
#. * by making the title as long as typical content
#.
#: app/flatpak-cli-transaction.c:1458 app/flatpak-cli-transaction.c:1503
msgid "partial"
msgstr "部分的"

#: app/flatpak-cli-transaction.c:1535
msgid "Proceed with these changes to the user installation?"
msgstr "继续对用户安装进行这些更改吗？"

#: app/flatpak-cli-transaction.c:1537
msgid "Proceed with these changes to the system installation?"
msgstr "继续对系统安装进行这些更改吗？"

#: app/flatpak-cli-transaction.c:1539
#, c-format
msgid "Proceed with these changes to the %s?"
msgstr "继续对 %s 进行这些更改吗？"

#: app/flatpak-cli-transaction.c:1711
msgid "Changes complete."
msgstr "更改完成。"

#: app/flatpak-cli-transaction.c:1713
msgid "Uninstall complete."
msgstr "卸载完成。"

#: app/flatpak-cli-transaction.c:1715
msgid "Installation complete."
msgstr "安装完成。"

#: app/flatpak-cli-transaction.c:1717
msgid "Updates complete."
msgstr "更新完成。"

#. For updates/!stop_on_first_error we already printed all errors so we make up
#. a different one.
#: app/flatpak-cli-transaction.c:1750
msgid "There were one or more errors"
msgstr "存在一个或多个错误"

#. translators: please keep the leading space
#: app/flatpak-main.c:76
msgid " Manage installed applications and runtimes"
msgstr " 管理已安装的应用程序和运行时"

#: app/flatpak-main.c:77
msgid "Install an application or runtime"
msgstr "安装应用程序或运行时"

#: app/flatpak-main.c:78
msgid "Update an installed application or runtime"
msgstr "更新已安装的应用程序或运行时"

#: app/flatpak-main.c:81
msgid "Uninstall an installed application or runtime"
msgstr "卸载已安装的应用程序或运行时"

#: app/flatpak-main.c:84
msgid "Mask out updates and automatic installation"
msgstr "屏蔽更新和自动安装"

#: app/flatpak-main.c:85
msgid "Pin a runtime to prevent automatic removal"
msgstr "置顶运行时以避免自动移除"

#: app/flatpak-main.c:86
msgid "List installed apps and/or runtimes"
msgstr "列出已安装的应用和/或运行时"

#: app/flatpak-main.c:87
msgid "Show info for installed app or runtime"
msgstr "显示已安装应用或运行时的信息"

#: app/flatpak-main.c:88
msgid "Show history"
msgstr "显示历史"

#: app/flatpak-main.c:89
msgid "Configure flatpak"
msgstr "配置 flatpak"

#: app/flatpak-main.c:90
msgid "Repair flatpak installation"
msgstr "修复 flatpak 安装"

#: app/flatpak-main.c:91
msgid "Put applications or runtimes onto removable media"
msgstr "将应用程序或运行时放到可移动媒体上"

#: app/flatpak-main.c:92
msgid "Install flatpaks that are part of the operating system"
msgstr "安装视为操作系统一部分的 flatpak"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:95
msgid ""
"\n"
" Find applications and runtimes"
msgstr ""
"\n"
"查找应用程序和运行时"

#: app/flatpak-main.c:96
msgid "Search for remote apps/runtimes"
msgstr "搜索远程仓库的应用/运行时"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:99
msgid ""
"\n"
" Manage running applications"
msgstr ""
"\n"
"管理正在运行的应用程序"

#: app/flatpak-main.c:100
msgid "Run an application"
msgstr "运行应用程序"

#: app/flatpak-main.c:101
msgid "Override permissions for an application"
msgstr "覆盖应用程序的权限"

#: app/flatpak-main.c:102
msgid "Specify default version to run"
msgstr "指定要运行的默认版本"

#: app/flatpak-main.c:103
msgid "Enter the namespace of a running application"
msgstr "进入正在运行应用程序的命名空间"

#: app/flatpak-main.c:104
msgid "Enumerate running applications"
msgstr "列举正在运行的应用程序"

#: app/flatpak-main.c:105
msgid "Stop a running application"
msgstr "停止正在运行的应用程序"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:108
msgid ""
"\n"
" Manage file access"
msgstr ""
"\n"
"管理文件访问"

#: app/flatpak-main.c:109
msgid "List exported files"
msgstr "列出导出的文件"

#: app/flatpak-main.c:110
msgid "Grant an application access to a specific file"
msgstr "同意应用程序对特定文件的访问"

#: app/flatpak-main.c:111
msgid "Revoke access to a specific file"
msgstr "撤消对特定文件的访问"

#: app/flatpak-main.c:112
msgid "Show information about a specific file"
msgstr "显示有关特定文件的信息"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:116
msgid ""
"\n"
" Manage dynamic permissions"
msgstr ""
"\n"
"管理动态权限"

#: app/flatpak-main.c:117
msgid "List permissions"
msgstr "列出权限"

#: app/flatpak-main.c:118
msgid "Remove item from permission store"
msgstr "从权限存储中移除项目"

#: app/flatpak-main.c:120
msgid "Set permissions"
msgstr "设置权限"

#: app/flatpak-main.c:121
msgid "Show app permissions"
msgstr "显示应用权限"

#: app/flatpak-main.c:122
msgid "Reset app permissions"
msgstr "重置应用权限"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:125
msgid ""
"\n"
" Manage remote repositories"
msgstr ""
"\n"
"管理远程仓库"

#: app/flatpak-main.c:126
msgid "List all configured remotes"
msgstr "列出所有已配置的远程仓库"

#: app/flatpak-main.c:127
msgid "Add a new remote repository (by URL)"
msgstr "添加新的远程仓库（通过网址）"

#: app/flatpak-main.c:128
msgid "Modify properties of a configured remote"
msgstr "修改已配置远程仓库的属性"

#: app/flatpak-main.c:129
msgid "Delete a configured remote"
msgstr "删除已配置的远程仓库"

#: app/flatpak-main.c:131
msgid "List contents of a configured remote"
msgstr "列出已配置远程仓库的内容"

#: app/flatpak-main.c:132
msgid "Show information about a remote app or runtime"
msgstr "显示远程仓库中应用或运行时的有关信息"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:135
msgid ""
"\n"
" Build applications"
msgstr ""
"\n"
"构建应用程序"

#: app/flatpak-main.c:136
msgid "Initialize a directory for building"
msgstr "初始化用于构建的目录"

#: app/flatpak-main.c:137
msgid "Run a build command inside the build dir"
msgstr "在构建目录中运行构建命令"

#: app/flatpak-main.c:138
msgid "Finish a build dir for export"
msgstr "完成导出的构建目录"

#: app/flatpak-main.c:139
msgid "Export a build dir to a repository"
msgstr "将构建目录导出到仓库"

#: app/flatpak-main.c:140
msgid "Create a bundle file from a ref in a local repository"
msgstr "从本地仓库中的引用创建捆绑包文件"

#: app/flatpak-main.c:141
msgid "Import a bundle file"
msgstr "导入捆绑包文件"

#: app/flatpak-main.c:142
msgid "Sign an application or runtime"
msgstr "签署应用程序或运行时"

#: app/flatpak-main.c:143
msgid "Update the summary file in a repository"
msgstr "更新仓库中的摘要文件"

#: app/flatpak-main.c:144
msgid "Create new commit based on existing ref"
msgstr "基于现有引用创建新的提交"

#: app/flatpak-main.c:145
msgid "Show information about a repo"
msgstr "显示仓库的有关信息"

#: app/flatpak-main.c:162
msgid "Show debug information, -vv for more detail"
msgstr "显示调试信息，-vv 显示更多详情"

#: app/flatpak-main.c:163
msgid "Show OSTree debug information"
msgstr "显示 OSTree 调试信息"

#: app/flatpak-main.c:169
msgid "Print version information and exit"
msgstr "打印版本信息并退出"

#: app/flatpak-main.c:170
msgid "Print default arch and exit"
msgstr "显示默认架构并退出"

#: app/flatpak-main.c:171
msgid "Print supported arches and exit"
msgstr "显示支持架构并退出"

#: app/flatpak-main.c:172
msgid "Print active gl drivers and exit"
msgstr "显示激活 gl 驱动并退出"

#: app/flatpak-main.c:173
msgid "Print paths for system installations and exit"
msgstr "显示系统安装路径并退出"

#: app/flatpak-main.c:174
msgid "Print the updated environment needed to run flatpaks"
msgstr "显示运行 flatpak 应用所需的已更新环境"

#: app/flatpak-main.c:175
msgid "Only include the system installation with --print-updated-env"
msgstr "仅包含带有 --print-updated-env 的系统安装"

#: app/flatpak-main.c:180
msgid "Work on the user installation"
msgstr "用于用户级安装"

#: app/flatpak-main.c:181
msgid "Work on the system-wide installation (default)"
msgstr "用于系统级安装（默认）"

#: app/flatpak-main.c:182
msgid "Work on a non-default system-wide installation"
msgstr "用于非默认系统级安装"

#: app/flatpak-main.c:212
msgid "Builtin Commands:"
msgstr "内置命令："

#: app/flatpak-main.c:298
#, c-format
msgid ""
"Note that the directories %s are not in the search path set by the "
"XDG_DATA_DIRS environment variable, so applications installed by Flatpak may "
"not appear on your desktop until the session is restarted."
msgstr ""
"请注意 %s 目录不在由 XDG_DATA_DIRS 环境变量设置的搜索路径中，因此通过 "
"Flatpak 安装的应用在会话重启前可能不会出现在您的桌面。"

#: app/flatpak-main.c:312
#, c-format
msgid ""
"Note that the directory %s is not in the search path set by the "
"XDG_DATA_DIRS environment variable, so applications installed by Flatpak may "
"not appear on your desktop until the session is restarted."
msgstr ""
"请注意 %s 目录不在由 XDG_DATA_DIRS 环境变量设置的搜索路径中，因此通过 "
"Flatpak 安装的应用在会话重启前可能不会出现在您的桌面。"

#: app/flatpak-main.c:381
msgid ""
"Refusing to operate under sudo with --user. Omit sudo to operate on the user "
"installation, or use a root shell to operate on the root user's installation."
msgstr ""
"拒绝在 sudo 下带 --user 操作。在用户级安装时删去 sudo，或者在根用户级安装时使"
"用根 shell 操作。"

#: app/flatpak-main.c:453
msgid ""
"Multiple installations specified for a command that works on one installation"
msgstr "为在用于一个安装的命令指定了多个安装"

#: app/flatpak-main.c:504 app/flatpak-main.c:697
#, c-format
msgid "See '%s --help'"
msgstr "参见“%s --help”"

#: app/flatpak-main.c:706
#, c-format
msgid "'%s' is not a flatpak command. Did you mean '%s%s'?"
msgstr "“%s”不是 flatpak 命令。您的意思是“%s%s”吗？"

#: app/flatpak-main.c:709
#, c-format
msgid "'%s' is not a flatpak command"
msgstr "“%s”不是 flatpak 命令"

#: app/flatpak-main.c:824
msgid "No command specified"
msgstr "未指定命令"

#: app/flatpak-main.c:980
msgid "error:"
msgstr "错误："

#: app/flatpak-quiet-transaction.c:77
#, c-format
msgid "Installing %s\n"
msgstr "正在安装 %s\n"

#: app/flatpak-quiet-transaction.c:81
#, c-format
msgid "Updating %s\n"
msgstr "正在更新 %s\n"

#: app/flatpak-quiet-transaction.c:85
#, c-format
msgid "Uninstalling %s\n"
msgstr "正在卸载 %s\n"

#: app/flatpak-quiet-transaction.c:107
#, c-format
msgid "Warning: Failed to install %s: %s\n"
msgstr "警告：安装 %s 失败：%s\n"

#: app/flatpak-quiet-transaction.c:110
#, c-format
msgid "Error: Failed to install %s: %s\n"
msgstr "错误：安装 %s 失败：%s\n"

#: app/flatpak-quiet-transaction.c:116
#, c-format
msgid "Warning: Failed to update %s: %s\n"
msgstr "警告：更新 %s 失败：%s\n"

#: app/flatpak-quiet-transaction.c:119
#, c-format
msgid "Error: Failed to update %s: %s\n"
msgstr "错误：更新 %s 失败：%s\n"

#: app/flatpak-quiet-transaction.c:125
#, c-format
msgid "Warning: Failed to install bundle %s: %s\n"
msgstr "警告：安装捆绑包 %s 失败：%s\n"

#: app/flatpak-quiet-transaction.c:128
#, c-format
msgid "Error: Failed to install bundle %s: %s\n"
msgstr "错误：安装捆绑包 %s 失败：%s\n"

#: app/flatpak-quiet-transaction.c:134
#, c-format
msgid "Warning: Failed to uninstall %s: %s\n"
msgstr "警告：卸载 %s 失败：%s\n"

#: app/flatpak-quiet-transaction.c:137
#, c-format
msgid "Error: Failed to uninstall %s: %s\n"
msgstr "错误：卸载 %s 失败：%s\n"

#: app/flatpak-quiet-transaction.c:166 common/flatpak-dir.c:11475
#, c-format
msgid "%s already installed"
msgstr "%s 已安装"

#: app/flatpak-quiet-transaction.c:168 common/flatpak-dir.c:3622
#: common/flatpak-dir.c:4321 common/flatpak-dir.c:16968
#: common/flatpak-dir.c:17258 common/flatpak-dir-utils.c:166
#: common/flatpak-dir-utils.c:259 common/flatpak-transaction.c:2736
#: common/flatpak-transaction.c:2791
#, c-format
msgid "%s not installed"
msgstr "%s 未安装"

#: app/flatpak-quiet-transaction.c:170
#, c-format
msgid "%s needs a later flatpak version"
msgstr "%s 需要更高的 flatpak 版本"

#: app/flatpak-quiet-transaction.c:172
msgid "Not enough disk space to complete this operation"
msgstr "没有足够的硬盘空间以完成该操作"

#: app/flatpak-quiet-transaction.c:239
#, c-format
msgid "Info: %s is end-of-life, in favor of %s\n"
msgstr "信息：%s 寿命完结，使用 %s\n"

#: app/flatpak-quiet-transaction.c:241
#, c-format
msgid "Info: %s is end-of-life, with reason: %s\n"
msgstr "信息：%s 寿命完结，原因为：%s\n"

#: app/flatpak-quiet-transaction.c:251
#, c-format
msgid "Failed to rebase %s to %s: %s\n"
msgstr "无法将 %s 重新建基于 %s：%s\n"

#: common/flatpak-auth.c:58
#, c-format
msgid "No authenticator configured for remote `%s`"
msgstr "没有为远程仓库“%s”配置的身份验证器"

#: common/flatpak-context.c:637 common/flatpak-context.c:649
#, c-format
msgid "Invalid permission syntax: %s"
msgstr "无效的权限语法：%s"

#: common/flatpak-context.c:1207
#, c-format
msgid "Unknown share type %s, valid types are: %s"
msgstr "未知共享类型 %s，有效的类型为：%s"

#: common/flatpak-context.c:1228
#, c-format
msgid "Unknown policy type %s, valid types are: %s"
msgstr "未知策略类型 %s，有效的类型为：%s"

#: common/flatpak-context.c:1266
#, c-format
msgid "Invalid dbus name %s"
msgstr "无效的 dbus 名称 %s"

#: common/flatpak-context.c:1279
#, c-format
msgid "Unknown socket type %s, valid types are: %s"
msgstr "未知套接字类型 %s，有效的类型为：%s"

#: common/flatpak-context.c:1294
#, c-format
msgid "Unknown device type %s, valid types are: %s"
msgstr "未知设备类型 %s，有效的类型为：%s"

#: common/flatpak-context.c:1308
#, c-format
msgid "Unknown feature type %s, valid types are: %s"
msgstr "未知功能类型 %s，有效的类型为：%s"

#: common/flatpak-context.c:1840
#, c-format
msgid "Filesystem location \"%s\" contains \"..\""
msgstr "文件系统位置“%s”包含“..”"

#: common/flatpak-context.c:1882
#, c-format
msgid ""
"--filesystem=/ is not available, use --filesystem=host for a similar result"
msgstr "--filesystem=/ 不可用，使用 --filesystem=host 获得相似结果"

#: common/flatpak-context.c:1916
#, c-format
msgid ""
"Unknown filesystem location %s, valid locations are: host, host-os, host-"
"etc, host-root, home, xdg-*[/…], ~/dir, /dir"
msgstr ""
"未知文件系统位置 %s，有效的位置为：host、host-os、host-etc、host-root、home、"
"xdg-*[/…]、~/dir、/dir"

#: common/flatpak-context.c:2015
#, c-format
msgid "Invalid syntax for %s: %s"
msgstr "无效的 %s 语法：%s"

#: common/flatpak-context.c:2142
#, c-format
msgid "fallback-x11 can not be conditional"
msgstr "fallback-x11 无法成为条件性的"

#: common/flatpak-context.c:2318
#, c-format
msgid "Invalid env format %s"
msgstr "无效的环境格式 %s"

#: common/flatpak-context.c:2399
#, c-format
msgid "Environment variable name must not contain '=': %s"
msgstr "环境变量名称不能包含“=”：%s"

#: common/flatpak-context.c:2527 common/flatpak-context.c:2535
#, c-format
msgid "--add-policy arguments must be in the form SUBSYSTEM.KEY=VALUE"
msgstr "--add-policy 参数的格式必须为 SUBSYSTEM.KEY=VALUE"

#: common/flatpak-context.c:2542
#, c-format
msgid "--add-policy values can't start with \"!\""
msgstr "--add-policy 值不能以“!”开头"

#: common/flatpak-context.c:2567 common/flatpak-context.c:2575
#, c-format
msgid "--remove-policy arguments must be in the form SUBSYSTEM.KEY=VALUE"
msgstr "--remove-policy 参数的格式必须为 SUBSYSTEM.KEY=VALUE"

#: common/flatpak-context.c:2582
#, c-format
msgid "--remove-policy values can't start with \"!\""
msgstr "--remove-policy 值不能以“!”开头"

#: common/flatpak-context.c:2657
msgid "Share with host"
msgstr "与主机共享"

#: common/flatpak-context.c:2657 common/flatpak-context.c:2658
msgid "SHARE"
msgstr "共享"

#: common/flatpak-context.c:2658
msgid "Unshare with host"
msgstr "取消与主机共享"

#: common/flatpak-context.c:2659
msgid "Require conditions to be met for a subsystem to get shared"
msgstr "子系统共享需要相匹配的条件"

#: common/flatpak-context.c:2659
msgid "SHARE:CONDITION"
msgstr "共享:条件"

#: common/flatpak-context.c:2660
msgid "Expose socket to app"
msgstr "将套接字暴露给应用"

#: common/flatpak-context.c:2660 common/flatpak-context.c:2661
msgid "SOCKET"
msgstr "套接字"

#: common/flatpak-context.c:2661
msgid "Don't expose socket to app"
msgstr "不要将套接字暴露给应用"

#: common/flatpak-context.c:2662
msgid "Require conditions to be met for a socket to get exposed"
msgstr "要暴露的套接字需要相匹配的条件"

#: common/flatpak-context.c:2662
msgid "SOCKET:CONDITION"
msgstr "套接字:条件"

#: common/flatpak-context.c:2663
msgid "Expose device to app"
msgstr "将设备暴露给应用"

#: common/flatpak-context.c:2663 common/flatpak-context.c:2664
msgid "DEVICE"
msgstr "设备"

#: common/flatpak-context.c:2664
msgid "Don't expose device to app"
msgstr "不要将设备暴露给应用"

#: common/flatpak-context.c:2665
msgid "Require conditions to be met for a device to get exposed"
msgstr "要暴露的设备需要相匹配的条件"

#: common/flatpak-context.c:2665
msgid "DEVICE:CONDITION"
msgstr "设备:条件"

#: common/flatpak-context.c:2666
msgid "Allow feature"
msgstr "允许功能"

#: common/flatpak-context.c:2666 common/flatpak-context.c:2667
msgid "FEATURE"
msgstr "功能"

#: common/flatpak-context.c:2667
msgid "Don't allow feature"
msgstr "不允许功能"

#: common/flatpak-context.c:2668
msgid "Require conditions to be met for a feature to get allowed"
msgstr "允许某功能需要相匹配的条件"

#: common/flatpak-context.c:2668
msgid "FEATURE:CONDITION"
msgstr "功能:条件"

#: common/flatpak-context.c:2669
msgid "Expose filesystem to app (:ro for read-only)"
msgstr "将文件系统暴露给应用（:ro 为只读）"

#: common/flatpak-context.c:2669
msgid "FILESYSTEM[:ro]"
msgstr "文件系统[:ro]"

#: common/flatpak-context.c:2670
msgid "Don't expose filesystem to app"
msgstr "不要将文件系统暴露给应用"

#: common/flatpak-context.c:2670
msgid "FILESYSTEM"
msgstr "文件系统"

#: common/flatpak-context.c:2671
msgid "Set environment variable"
msgstr "设置环境变量"

#: common/flatpak-context.c:2671
msgid "VAR=VALUE"
msgstr "VAR=VALUE"

#: common/flatpak-context.c:2672
msgid "Read environment variables in env -0 format from FD"
msgstr "以 env -0 格式从 FD 读取环境变量"

#: common/flatpak-context.c:2673
msgid "Remove variable from environment"
msgstr "从环境中移除变量"

#: common/flatpak-context.c:2673
msgid "VAR"
msgstr "变量"

#: common/flatpak-context.c:2674
msgid "Allow app to own name on the session bus"
msgstr "允许应用在会话总线上拥有名称"

#: common/flatpak-context.c:2674 common/flatpak-context.c:2675
#: common/flatpak-context.c:2676 common/flatpak-context.c:2677
#: common/flatpak-context.c:2678 common/flatpak-context.c:2679
#: common/flatpak-context.c:2680
msgid "DBUS_NAME"
msgstr "DBUS_NAME"

#: common/flatpak-context.c:2675
msgid "Allow app to talk to name on the session bus"
msgstr "允许应用与会话总线上的名字对话"

#: common/flatpak-context.c:2676
msgid "Don't allow app to talk to name on the session bus"
msgstr "不允许应用与会话总线上的名字对话"

#: common/flatpak-context.c:2677
msgid "Allow app to own name on the system bus"
msgstr "允许应用在系统总线上拥有自己的名称"

#: common/flatpak-context.c:2678
msgid "Allow app to talk to name on the system bus"
msgstr "允许应用与系统总线上的名字对话"

#: common/flatpak-context.c:2679
msgid "Don't allow app to talk to name on the system bus"
msgstr "不允许应用与系统总线上的名字对话"

#: common/flatpak-context.c:2680
msgid "Allow app to own name on the a11y bus"
msgstr "允许应用在无障碍总线上拥有名称"

#: common/flatpak-context.c:2681
msgid "Add generic policy option"
msgstr "添加常规策略选项"

#: common/flatpak-context.c:2681 common/flatpak-context.c:2682
msgid "SUBSYSTEM.KEY=VALUE"
msgstr "SUBSYSTEM.KEY=VALUE"

#: common/flatpak-context.c:2682
msgid "Remove generic policy option"
msgstr "移除常规策略选项"

#: common/flatpak-context.c:2683
msgid "Add USB device to enumerables"
msgstr "添加 USB 设备至可枚举列表"

#: common/flatpak-context.c:2683 common/flatpak-context.c:2684
msgid "VENDOR_ID:PRODUCT_ID"
msgstr "VENDOR_ID:PRODUCT_ID"

#: common/flatpak-context.c:2684
msgid "Add USB device to hidden list"
msgstr "添加 USB 设备至隐藏列表"

#: common/flatpak-context.c:2685
msgid "A list of USB devices that are enumerable"
msgstr "可枚举的 USB 设备列表"

#: common/flatpak-context.c:2685
msgid "LIST"
msgstr "列表"

#: common/flatpak-context.c:2686
msgid "File containing a list of USB devices to make enumerable"
msgstr "包含可使其枚举的 USB 设备列表的文件"

#: common/flatpak-context.c:2686 common/flatpak-context.c:2687
msgid "FILENAME"
msgstr "文件名"

#: common/flatpak-context.c:2687
msgid "Persist home directory subpath"
msgstr "保留主目录子路径"

#. This is not needed/used anymore, so hidden, but we accept it for backwards compat
#: common/flatpak-context.c:2689
msgid "Don't require a running session (no cgroups creation)"
msgstr "不要求正在运行的会话（不创建 cgroups）"

#: common/flatpak-context.c:3718
#, c-format
msgid "Not replacing \"%s\" with tmpfs: %s"
msgstr "不用 tmpfs 替代“%s”：%s"

#: common/flatpak-context.c:3726
#, c-format
msgid "Not sharing \"%s\" with sandbox: %s"
msgstr "不与沙盒共享“%s”：%s"

#. Even if the error is one that we would normally silence, like
#. * the path not existing, it seems reasonable to make more of a fuss
#. * about the home directory not existing or otherwise being unusable,
#. * so this is intentionally not using cannot_export()
#: common/flatpak-context.c:3828
#, c-format
msgid "Not allowing home directory access: %s"
msgstr "不允许访问主目录：%s"

#: common/flatpak-context.c:4062
#, c-format
msgid "Unable to provide a temporary home directory in the sandbox: %s"
msgstr "无法在沙盒中提供临时主目录：%s"

#: common/flatpak-dir.c:442
#, c-format
msgid "Configured collection ID ‘%s’ not in summary file"
msgstr "已配置的集合标识“%s”不在摘要文件中"

#: common/flatpak-dir.c:587
#, c-format
msgid "Unable to load summary from remote %s: %s"
msgstr "无法从远程仓库 %s 加载摘要：%s"

#: common/flatpak-dir.c:764 common/flatpak-dir.c:800 common/flatpak-dir.c:906
#, c-format
msgid "No such ref '%s' in remote %s"
msgstr "在远程仓库 %2$s 中没有引用“%1$s”"

#: common/flatpak-dir.c:891 common/flatpak-dir.c:1051 common/flatpak-dir.c:1080
#: common/flatpak-dir.c:1092
#, c-format
msgid "No entry for %s in remote %s summary flatpak cache"
msgstr "在远程仓库 %2$s 摘要 flatpak 缓存中没有 %1$s 的条目"

#: common/flatpak-dir.c:1069
#, c-format
msgid "No summary or Flatpak cache available for remote %s"
msgstr "远程仓库 %s 没有可用的摘要或 Flatpak 缓存"

#: common/flatpak-dir.c:1097
#, c-format
msgid "Missing xa.data in summary for remote %s"
msgstr "远程仓库 %s 的摘要中缺失 xa.data"

#: common/flatpak-dir.c:1103 common/flatpak-dir.c:1546
#, c-format
msgid "Unsupported summary version %d for remote %s"
msgstr "不支持用于远程仓库 %2$s 的摘要版本 %1$d"

#: common/flatpak-dir.c:1200
msgid "Remote OCI index has no registry uri"
msgstr "远程 OCI 索引没有注册网址"

#: common/flatpak-dir.c:1261
#, c-format
msgid "Couldn't find ref %s in remote %s"
msgstr "在远程仓库 %2$s 中无法找到引用 %1$s"

#: common/flatpak-dir.c:1288 common/flatpak-dir.c:1381
#, c-format
msgid "Commit has no requested ref ‘%s’ in ref binding metadata (found: ‘%s’)"
msgstr "提交在引用绑定元数据中没有请求的引用“%s”（找到：“%s”）"

#: common/flatpak-dir.c:1413
#, c-format
msgid "Configured collection ID ‘%s’ not in binding metadata"
msgstr "已配置的集合标识“%s”不在绑定元数据中"

#: common/flatpak-dir.c:1449 common/flatpak-dir.c:5645
#, c-format
msgid "Couldn't find latest checksum for ref %s in remote %s"
msgstr "无法在远程仓库 %2$s 中找到引用 %1$s 的最新校验和"

#: common/flatpak-dir.c:1516 common/flatpak-dir.c:1552
#, c-format
msgid "No entry for %s in remote %s summary flatpak sparse cache"
msgstr "在远程仓库 %2$s 摘要 flatpak 解析缓存中没有 %1$s 的条目"

#: common/flatpak-dir.c:2540
#, c-format
msgid "Commit metadata for %s not matching expected metadata"
msgstr "用于 %s 的提交元数据与预期不匹配"

#: common/flatpak-dir.c:2823
msgid "Unable to connect to system bus"
msgstr "无法连接到系统总线"

#: common/flatpak-dir.c:3419
msgid "User installation"
msgstr "用户级安装"

#: common/flatpak-dir.c:3426
#, c-format
msgid "System (%s) installation"
msgstr "系统级（%s）安装"

#: common/flatpak-dir.c:3472
#, c-format
msgid "No overrides found for %s"
msgstr "找不到 %s 的覆盖"

#: common/flatpak-dir.c:3625
#, c-format
msgid "%s (commit %s) not installed"
msgstr "%s（提交 %s）未安装"

#: common/flatpak-dir.c:4650
#, c-format
msgid "Error parsing system flatpakrepo file for %s: %s"
msgstr "解析 %s 的系统 flatpakrepo 文件时出错：%s"

#: common/flatpak-dir.c:4735
#, c-format
msgid "While opening repository %s: "
msgstr "打开仓库 %s 时："

#: common/flatpak-dir.c:5004
#, c-format
msgid "The config key %s is not set"
msgstr "未设置配置密钥 %s"

#: common/flatpak-dir.c:5140
#, c-format
msgid "No current %s pattern matching %s"
msgstr "当前 %s 没有匹配模式 %s"

#: common/flatpak-dir.c:5422
msgid "No appstream commit to deploy"
msgstr "没有 appstream 提交可部署"

#: common/flatpak-dir.c:5941 common/flatpak-dir.c:7266
#: common/flatpak-dir.c:10881 common/flatpak-dir.c:11618
msgid "Can't pull from untrusted non-gpg verified remote"
msgstr "无法从不信任的无 GPG 校验的远程仓库提取"

#: common/flatpak-dir.c:6376 common/flatpak-dir.c:6591
msgid "Extra data not supported for non-gpg-verified local system installs"
msgstr "无 GPG 校验的本地系统级安装不支持额外数据"

#: common/flatpak-dir.c:6415 common/flatpak-dir.c:6782
#, c-format
msgid "Invalid checksum for extra data uri %s"
msgstr "额外数据网址 %s 校验和无效"

#: common/flatpak-dir.c:6424
#, c-format
msgid "Empty name for extra data uri %s"
msgstr "额外数据网址 %s 的空白名称"

#: common/flatpak-dir.c:6432
#, c-format
msgid "Unsupported extra data uri %s"
msgstr "不支持的额外数据网址 %s"

#: common/flatpak-dir.c:6461
#, c-format
msgid "Failed to load local extra-data %s: %s"
msgstr "加载本地额外数据 %s 失败：%s"

#: common/flatpak-dir.c:6469
#, c-format
msgid "Wrong size for extra-data %s"
msgstr "额外数据 %s 的大小错误"

#: common/flatpak-dir.c:6488
#, c-format
msgid "While downloading %s: "
msgstr "下载 %s 时："

#: common/flatpak-dir.c:6498
#, c-format
msgid "Wrong size for extra data %s"
msgstr "额外数据 %s 的大小错误"

#: common/flatpak-dir.c:6507
#, c-format
msgid "Invalid checksum for extra data %s"
msgstr "额外数据 %s 的校验和无效"

#: common/flatpak-dir.c:7096 common/flatpak-dir.c:7349
#, c-format
msgid "While pulling %s from remote %s: "
msgstr "从远程仓库 %2$s 提取 %1$s 时："

#: common/flatpak-dir.c:7290 common/flatpak-repo-utils.c:3886
msgid "GPG signatures found, but none are in trusted keyring"
msgstr "找到 GPG 签名，但都不在信任的密钥环中"

#: common/flatpak-dir.c:7307
#, c-format
msgid "Commit for ‘%s’ has no ref binding"
msgstr "“%s”的提交没有引用绑定"

#: common/flatpak-dir.c:7312
#, c-format
msgid "Commit for ‘%s’ is not in expected bound refs: %s"
msgstr "“%s”的提交不在预期的绑定引用中：%s"

#: common/flatpak-dir.c:7488
msgid "Only applications can be made current"
msgstr "仅应用程序可被作为当前"

#: common/flatpak-dir.c:8192
msgid "Not enough memory"
msgstr "内存不足"

#: common/flatpak-dir.c:8211
msgid "Failed to read from exported file"
msgstr "从导出的文件读取失败"

#: common/flatpak-dir.c:8401
msgid "Error reading mimetype xml file"
msgstr "读取 mimetype xml 文件时出错"

#: common/flatpak-dir.c:8406
msgid "Invalid mimetype xml file"
msgstr "无效的 mimetype xml 文件"

#: common/flatpak-dir.c:8492
#, c-format
msgid "D-Bus service file '%s' has wrong name"
msgstr "D-Bus 服务文件“%s”名称错误"

#: common/flatpak-dir.c:8647
#, c-format
msgid "Invalid Exec argument %s"
msgstr "无效的执行参数 %s"

#: common/flatpak-dir.c:9115
msgid "While getting detached metadata: "
msgstr "获取分离的元数据时："

#: common/flatpak-dir.c:9120 common/flatpak-dir.c:9125
#: common/flatpak-dir.c:9129
msgid "Extra data missing in detached metadata"
msgstr "分离的元数据中缺少额外的数据"

#: common/flatpak-dir.c:9133
msgid "While creating extradir: "
msgstr "创建 extradir 时："

#: common/flatpak-dir.c:9154 common/flatpak-dir.c:9187
msgid "Invalid checksum for extra data"
msgstr "额外数据的校验和无效"

#: common/flatpak-dir.c:9183
msgid "Wrong size for extra data"
msgstr "额外数据的大小错误"

#: common/flatpak-dir.c:9196
#, c-format
msgid "While writing extra data file '%s': "
msgstr "写入额外数据文件“%s”时："

#: common/flatpak-dir.c:9204
#, c-format
msgid "Extra data %s missing in detached metadata"
msgstr "分离的元数据中缺少额外的数据 %s"

#: common/flatpak-dir.c:9278
#, c-format
msgid "Unable to get runtime key from metadata"
msgstr "无法从元数据获取运行时密钥"

#: common/flatpak-dir.c:9402
#, c-format
msgid "apply_extra script failed, exit status %d"
msgstr "apply_extra 脚本失败，退出状态为 %d"

#. Translators: The placeholder is for an app ref.
#: common/flatpak-dir.c:9591
#, c-format
msgid "Installing %s is not allowed by the policy set by your administrator"
msgstr "您的管理员设置的策略不允许安装 %s"

#: common/flatpak-dir.c:9690
#, c-format
msgid "While trying to resolve ref %s: "
msgstr "尝试解决引用 %s 时："

#: common/flatpak-dir.c:9702
#, c-format
msgid "%s is not available"
msgstr "%s 不可用"

#: common/flatpak-dir.c:9714 common/flatpak-dir.c:11495
#, c-format
msgid "%s commit %s already installed"
msgstr "%s 提交 %s 已安装"

#: common/flatpak-dir.c:9721
msgid "Can't create deploy directory"
msgstr "无法创建部署目录"

#: common/flatpak-dir.c:9729
#, c-format
msgid "Failed to read commit %s: "
msgstr "读取提交 %s 失败："

#: common/flatpak-dir.c:9750
#, c-format
msgid "While trying to checkout %s into %s: "
msgstr "尝试检验 %s 至 %s 时："

#: common/flatpak-dir.c:9769
msgid "While trying to checkout metadata subpath: "
msgstr "尝试检验元数据子路径时："

#: common/flatpak-dir.c:9801
#, c-format
msgid "While trying to checkout subpath ‘%s’: "
msgstr "尝试检验子路径“%s”时："

#: common/flatpak-dir.c:9811
msgid "While trying to remove existing extra dir: "
msgstr "尝试移除现存额外目录时："

#: common/flatpak-dir.c:9822
msgid "While trying to apply extra data: "
msgstr "尝试应用额外数据时："

#: common/flatpak-dir.c:9849
#, c-format
msgid "Invalid commit ref %s: "
msgstr "无效的提交引用 %s："

#: common/flatpak-dir.c:9857 common/flatpak-dir.c:9869
#, c-format
msgid "Deployed ref %s does not match commit (%s)"
msgstr "已部署的引用 %s 不匹配提交（%s）"

#: common/flatpak-dir.c:9863
#, c-format
msgid "Deployed ref %s branch does not match commit (%s)"
msgstr "已部署的引用 %s 分支不匹配提交（%s）"

#: common/flatpak-dir.c:10125 common/flatpak-installation.c:1911
#, c-format
msgid "%s branch %s already installed"
msgstr "%s 分支 %s 已安装"

#: common/flatpak-dir.c:10985
#, c-format
msgid "Could not unmount revokefs-fuse filesystem at %s: "
msgstr "无法取消挂载位于 %s 的 revokefs-fuse 文件系统："

#: common/flatpak-dir.c:11289
#, c-format
msgid "This version of %s is already installed"
msgstr "此版本的 %s 已安装"

#: common/flatpak-dir.c:11302
#, c-format
msgid "Can't change remote during bundle install"
msgstr "捆绑包安装期间无法更改远程仓库"

#: common/flatpak-dir.c:11571
msgid "Can't update to a specific commit without root permissions"
msgstr "没有 root 权限无法更新至指定提交"

#: common/flatpak-dir.c:11852
#, c-format
msgid "Can't remove %s, it is needed for: %s"
msgstr "无法移除 %s，需要它的有：%s"

#: common/flatpak-dir.c:11912 common/flatpak-installation.c:2067
#, c-format
msgid "%s branch %s is not installed"
msgstr "%s 分支 %s 未安装"

#: common/flatpak-dir.c:12165
#, c-format
msgid "%s commit %s not installed"
msgstr "%s 提交 %s 未安装"

#: common/flatpak-dir.c:12501
#, c-format
msgid "Pruning repo failed: %s"
msgstr "修剪仓库失败：%s"

#: common/flatpak-dir.c:12669 common/flatpak-dir.c:12675
#, c-format
msgid "Failed to load filter '%s'"
msgstr "加载筛选器“%s”失败"

#: common/flatpak-dir.c:12681
#, c-format
msgid "Failed to parse filter '%s'"
msgstr "解析筛选器“%s”失败"

#: common/flatpak-dir.c:12963
msgid "Failed to write summary cache: "
msgstr "写入摘要缓存失败："

#: common/flatpak-dir.c:12982
#, c-format
msgid "No oci summary cached for remote '%s'"
msgstr "远程仓库“%s”没有已缓存的 OCI 摘要"

#: common/flatpak-dir.c:13207
#, c-format
msgid "No cached summary for remote '%s'"
msgstr "远程仓库“%s”没有已缓存的摘要"

#: common/flatpak-dir.c:13248
#, c-format
msgid "Invalid checksum for indexed summary %s read from %s"
msgstr "从“%2$s”读取的已索引摘要 %1$s 的校验和无效"

#: common/flatpak-dir.c:13321
#, c-format
msgid ""
"Remote listing for %s not available; server has no summary file. Check the "
"URL passed to remote-add was valid."
msgstr ""
"%s 的远程列表不可用；服务器没有摘要文件。请检查传递给 remote-add 的网址是否有"
"效。"

#: common/flatpak-dir.c:13698
#, c-format
msgid "Invalid checksum for indexed summary %s for remote '%s'"
msgstr "远程仓库“%2$s”的已索引摘要 %1$s 的校验和无效"

#: common/flatpak-dir.c:14388
#, c-format
msgid "Multiple branches available for %s, you must specify one of: "
msgstr "%s 有多个可用分支，您必须指定一个："

#: common/flatpak-dir.c:14454
#, c-format
msgid "Nothing matches %s"
msgstr "没有 %s 的匹配项"

#: common/flatpak-dir.c:14562
#, c-format
msgid "Can't find ref %s%s%s%s%s"
msgstr "无法找到引用 %s%s%s%s%s"

#: common/flatpak-dir.c:14605
#, c-format
msgid "Error searching remote %s: %s"
msgstr "搜索远程仓库 %s 时出错：%s"

#: common/flatpak-dir.c:14702
#, c-format
msgid "Error searching local repository: %s"
msgstr "搜索本地仓库时出错：%s"

#: common/flatpak-dir.c:14839
#, c-format
msgid "%s/%s/%s not installed"
msgstr "%s/%s/%s 未安装"

#: common/flatpak-dir.c:15042
#, c-format
msgid "Could not find installation %s"
msgstr "无法找到安装 %s"

#: common/flatpak-dir.c:15612
#, c-format
msgid "Invalid file format, no %s group"
msgstr "无效的文件格式，没有 %s 组"

#: common/flatpak-dir.c:15617 common/flatpak-repo-utils.c:2836
#, c-format
msgid "Invalid version %s, only 1 supported"
msgstr "无效的版本 %s，仅支持 1"

#: common/flatpak-dir.c:15622 common/flatpak-dir.c:15627
#, c-format
msgid "Invalid file format, no %s specified"
msgstr "无效的文件格式，没有指定 %s"

#. Check some minimal size so we don't get crap
#: common/flatpak-dir.c:15647
msgid "Invalid file format, gpg key invalid"
msgstr "无效的文件格式，GPG 密钥无效"

#: common/flatpak-dir.c:15675 common/flatpak-repo-utils.c:2917
msgid "Collection ID requires GPG key to be provided"
msgstr "集合标识要求提供 GPG 密钥"

#: common/flatpak-dir.c:15718
#, c-format
msgid "Runtime %s, branch %s is already installed"
msgstr "运行时 %s、分支 %s 已安装"

#: common/flatpak-dir.c:15719
#, c-format
msgid "App %s, branch %s is already installed"
msgstr "应用 %s、分支 %s 已安装"

#: common/flatpak-dir.c:15953
#, c-format
msgid "Can't remove remote '%s' with installed ref %s (at least)"
msgstr "无法移除具有已安装引用 %2$s（至少）的远程仓库“%1$s”"

#: common/flatpak-dir.c:16058
#, c-format
msgid "Invalid character '/' in remote name: %s"
msgstr "远程仓库名称中有无效字符“/”：%s"

#: common/flatpak-dir.c:16064
#, c-format
msgid "No configuration for remote %s specified"
msgstr "没有为远程仓库 %s 指定配置"

#: common/flatpak-dir.c:17597
#, c-format
msgid "Skipping deletion of mirror ref (%s, %s)…\n"
msgstr "正在跳过删除镜像引用（%s，%s）…\n"

#: common/flatpak-exports.c:931
#, c-format
msgid "An absolute path is required"
msgstr "需要绝对路径"

#: common/flatpak-exports.c:948
#, c-format
msgid "Unable to open path \"%s\": %s"
msgstr "无法打开路径“%s”：%s"

#: common/flatpak-exports.c:955
#, c-format
msgid "Unable to get file type of \"%s\": %s"
msgstr "无法获取“%s”的文件类型：%s"

#: common/flatpak-exports.c:964
#, c-format
msgid "File \"%s\" has unsupported type 0o%o"
msgstr "文件“%s”具有不支持的类型 0o%o"

#: common/flatpak-exports.c:970
#, c-format
msgid "Unable to get filesystem information for \"%s\": %s"
msgstr "无法获取“%s”的文件系统信息：%s"

#: common/flatpak-exports.c:980
#, c-format
msgid "Ignoring blocking autofs path \"%s\""
msgstr "正在忽略阻塞的 autofs 路径“%s”"

#: common/flatpak-exports.c:996 common/flatpak-exports.c:1009
#: common/flatpak-exports.c:1022
#, c-format
msgid "Path \"%s\" is reserved by Flatpak"
msgstr "路径“%s”已被 Flatpak 预订"

#: common/flatpak-exports.c:1076
#, c-format
msgid "Unable to resolve symbolic link \"%s\": %s"
msgstr "无法解析符号链接“%s”：%s"

#: common/flatpak-glib-backports.c:69
msgid "Empty string is not a number"
msgstr "空字符串不是数字"

#: common/flatpak-glib-backports.c:95
#, c-format
msgid "“%s” is not an unsigned number"
msgstr "“%s”不是未签名的数字"

#: common/flatpak-glib-backports.c:105
#, c-format
msgid "Number “%s” is out of bounds [%s, %s]"
msgstr "数字“%s”超出范围 [%s, %s]"

#: common/flatpak-image-source.c:83
msgid "Only sha256 image checksums are supported"
msgstr "仅支持 SHA256 映像校验和"

#: common/flatpak-image-source.c:100 common/flatpak-image-source.c:108
msgid "Image is not a manifest"
msgstr "映像不是清单"

#: common/flatpak-image-source.c:123
msgid "No org.flatpak.ref found in image"
msgstr "未在映像中找到 org.flatpak.ref"

#: common/flatpak-image-source.c:148
#, c-format
msgid "Ref '%s' not found in registry"
msgstr "在注册表中未发现引用“%s”"

#: common/flatpak-image-source.c:157
msgid "Multiple images in registry, specify a ref with --ref"
msgstr "注册表中有多个映像，使用 --ref 指定一个引用"

#: common/flatpak-installation.c:834
#, c-format
msgid "Ref %s not installed"
msgstr "引用 %s 未安装"

#: common/flatpak-installation.c:875
#, c-format
msgid "App %s not installed"
msgstr "应用 %s 未安装"

#: common/flatpak-installation.c:1395
#, c-format
msgid "Remote '%s' already exists"
msgstr "远程仓库“%s”已存在"

#: common/flatpak-installation.c:1946
#, c-format
msgid "As requested, %s was only pulled, but not installed"
msgstr "根据请求，%s 仅被提取，没有安装"

#: common/flatpak-instance.c:533 common/flatpak-instance.c:687
#: common/flatpak-instance.c:728
#, c-format
msgid "Unable to create directory %s"
msgstr "无法创建目录 %s"

#: common/flatpak-instance.c:554
#, c-format
msgid "Unable to lock %s"
msgstr "无法锁定 %s"

#: common/flatpak-instance.c:627
#, c-format
msgid "Unable to create temporary directory in %s"
msgstr "无法在 %s 中创建临时目录"

#: common/flatpak-instance.c:639
#, c-format
msgid "Unable to create file %s"
msgstr "无法创建文件 %s"

#: common/flatpak-instance.c:646
#, c-format
msgid "Unable to update symbolic link %s/%s"
msgstr "无法更新符号链接 %s/%s"

#: common/flatpak-oci-registry.c:1197
msgid "Only Bearer authentication supported"
msgstr "仅支持 Bearer 身份验证"

#: common/flatpak-oci-registry.c:1206
msgid "Only realm in authentication request"
msgstr "身份验证中仅请求领域"

#: common/flatpak-oci-registry.c:1213
msgid "Invalid realm in authentication request"
msgstr "身份验证中请求的领域无效"

#: common/flatpak-oci-registry.c:1283
#, c-format
msgid "Authorization failed: %s"
msgstr "身份验证失败：%s"

#: common/flatpak-oci-registry.c:1285
msgid "Authorization failed"
msgstr "身份验证失败"

#: common/flatpak-oci-registry.c:1289
#, c-format
msgid "Unexpected response status %d when requesting token: %s"
msgstr "请求令牌时遇到意料之外的响应状态 %d：%s"

#: common/flatpak-oci-registry.c:1300
msgid "Invalid authentication request response"
msgstr "无效的身份验证请求响应"

#: common/flatpak-oci-registry.c:1731
#, c-format
msgid "Flatpak was compiled without zstd support"
msgstr "Flatpak 编译时未开启 zstd 支持"

#: common/flatpak-oci-registry.c:1923 common/flatpak-oci-registry.c:1975
#: common/flatpak-oci-registry.c:2004 common/flatpak-oci-registry.c:2059
#: common/flatpak-oci-registry.c:2115 common/flatpak-oci-registry.c:2193
msgid "Invalid delta file format"
msgstr "无效的增量文件格式"

#: common/flatpak-oci-registry.c:3198 common/flatpak-oci-registry.c:3382
msgid "Invalid OCI image config"
msgstr "无效的 OCI 映像配置"

#: common/flatpak-oci-registry.c:3260 common/flatpak-oci-registry.c:3531
#, c-format
msgid "Wrong layer checksum, expected %s, was %s"
msgstr "错误的层校验和，预期为 %s，实际为 %s"

#: common/flatpak-oci-registry.c:3359
#, c-format
msgid "No ref specified for OCI image %s"
msgstr "没有为 OCI 映像 %s 指定引用"

#: common/flatpak-oci-registry.c:3369
#, c-format
msgid "Wrong ref (%s) specified for OCI image %s, expected %s"
msgstr "为 OCI 映像 %2$s 指定了错误的引用（%1$s），预期为 %3$s"

#: common/flatpak-progress.c:236
#, c-format
msgid "Downloading metadata: %u/(estimating) %s"
msgstr "正在下载元数据：%u/（估计）%s"

#: common/flatpak-progress.c:260
#, c-format
msgid "Downloading: %s/%s"
msgstr "正在下载：%s/%s"

#: common/flatpak-progress.c:280
#, c-format
msgid "Downloading extra data: %s/%s"
msgstr "正在下载额外数据：%s/%s"

#: common/flatpak-progress.c:285
#, c-format
msgid "Downloading files: %d/%d %s"
msgstr "正在下载文件：%d/%d %s"

#: common/flatpak-ref-utils.c:122
msgid "Name can't be empty"
msgstr "名称不能为空"

#: common/flatpak-ref-utils.c:129
msgid "Name can't be longer than 255 characters"
msgstr "名称不能超过 255 个字符"

#: common/flatpak-ref-utils.c:142
msgid "Name can't start with a period"
msgstr "名称不能以句号开头"

#: common/flatpak-ref-utils.c:148
#, c-format
msgid "Name can't start with %c"
msgstr "名称不能以 %c 开头"

#: common/flatpak-ref-utils.c:164
msgid "Name can't end with a period"
msgstr "名称不能以句号结尾"

#: common/flatpak-ref-utils.c:171 common/flatpak-ref-utils.c:183
msgid "Only last name segment can contain -"
msgstr "只有姓氏段可以包含 -"

#: common/flatpak-ref-utils.c:174
#, c-format
msgid "Name segment can't start with %c"
msgstr "名称段不能以 %c 开头"

#: common/flatpak-ref-utils.c:186
#, c-format
msgid "Name can't contain %c"
msgstr "名称不能包含 %c"

#: common/flatpak-ref-utils.c:195
msgid "Names must contain at least 2 periods"
msgstr "名称必须包含至少两个句点"

#: common/flatpak-ref-utils.c:312
msgid "Arch can't be empty"
msgstr "架构不能为空"

#: common/flatpak-ref-utils.c:323
#, c-format
msgid "Arch can't contain %c"
msgstr "架构不能包含 %c"

#: common/flatpak-ref-utils.c:385
msgid "Branch can't be empty"
msgstr "分支不能为空"

#: common/flatpak-ref-utils.c:395
#, c-format
msgid "Branch can't start with %c"
msgstr "分支不能以 %c 开头"

#: common/flatpak-ref-utils.c:405
#, c-format
msgid "Branch can't contain %c"
msgstr "分支不能包含 %c"

#: common/flatpak-ref-utils.c:615 common/flatpak-ref-utils.c:865
msgid "Ref too long"
msgstr "引用太长了"

#: common/flatpak-ref-utils.c:627
msgid "Invalid remote name"
msgstr "无效的远程仓库名称"

#: common/flatpak-ref-utils.c:641
#, c-format
msgid "%s is not application or runtime"
msgstr "%s 不是应用程序或运行时"

#: common/flatpak-ref-utils.c:650 common/flatpak-ref-utils.c:667
#: common/flatpak-ref-utils.c:683
#, c-format
msgid "Wrong number of components in %s"
msgstr "%s 中组件数量错误"

#: common/flatpak-ref-utils.c:656
#, c-format
msgid "Invalid name %.*s: %s"
msgstr "无效名称 %.*s: %s"

#: common/flatpak-ref-utils.c:673
#, c-format
msgid "Invalid arch: %.*s: %s"
msgstr "无效架构：%.*s: %s"

#: common/flatpak-ref-utils.c:816
#, c-format
msgid "Invalid name %s: %s"
msgstr "无效名称 %s: %s"

#: common/flatpak-ref-utils.c:834
#, c-format
msgid "Invalid arch: %s: %s"
msgstr "无效架构：%s: %s"

#: common/flatpak-ref-utils.c:853
#, c-format
msgid "Invalid branch: %s: %s"
msgstr "无效分支：%s: %s"

#: common/flatpak-ref-utils.c:962 common/flatpak-ref-utils.c:970
#: common/flatpak-ref-utils.c:978
#, c-format
msgid "Wrong number of components in partial ref %s"
msgstr "部分引用 %s 中组件数量错误"

#: common/flatpak-ref-utils.c:1298
msgid " development platform"
msgstr " 开发平台"

#: common/flatpak-ref-utils.c:1300
msgid " platform"
msgstr " 平台"

#: common/flatpak-ref-utils.c:1302
msgid " application base"
msgstr " 应用程序基础"

#: common/flatpak-ref-utils.c:1305
msgid " debug symbols"
msgstr " 调试符号"

#: common/flatpak-ref-utils.c:1307
msgid " sourcecode"
msgstr " 源代码"

#: common/flatpak-ref-utils.c:1309
msgid " translations"
msgstr " 翻译"

#: common/flatpak-ref-utils.c:1311
msgid " docs"
msgstr " 文档"

#: common/flatpak-ref-utils.c:1578
#, c-format
msgid "Invalid id %s: %s"
msgstr "无效标识 %s: %s"

#: common/flatpak-remote.c:1216
#, c-format
msgid "Bad remote name: %s"
msgstr "不好的远程仓库名称：%s"

#: common/flatpak-remote.c:1220
msgid "No URL specified"
msgstr "未指定网址"

#: common/flatpak-remote.c:1266
msgid "GPG verification must be enabled when a collection ID is set"
msgstr "设置集合标识时必须启用 GPG 校验"

#: common/flatpak-repo-utils.c:344
#, c-format
msgid "No extra data sources"
msgstr "没有额外的数据源"

#: common/flatpak-repo-utils.c:2817
#, c-format
msgid "Invalid %s: Missing group ‘%s’"
msgstr "无效的 %s：缺失“%s”组"

#: common/flatpak-repo-utils.c:2826
#, c-format
msgid "Invalid %s: Missing key ‘%s’"
msgstr "无效的 %s：缺失“%s”键"

#: common/flatpak-repo-utils.c:2876
msgid "Invalid gpg key"
msgstr "无效的 GPG 密钥"

#: common/flatpak-repo-utils.c:3217
#, c-format
msgid "Error copying 64x64 icon for component %s: %s\n"
msgstr "复制组件 %s 的 64x64 图标时出错：%s\n"

#: common/flatpak-repo-utils.c:3223
#, c-format
msgid "Error copying 128x128 icon for component %s: %s\n"
msgstr "复制组件 %s 的 128x128 图标时出错：%s\n"

#: common/flatpak-repo-utils.c:3362
#, c-format
msgid "%s is end-of-life, ignoring for appstream"
msgstr "%s 寿命完结，将为 appstream 忽略"

#: common/flatpak-repo-utils.c:3397
#, c-format
msgid "No appstream data for %s: %s\n"
msgstr "没有 %s 的 appstream 数据：%s\n"

#: common/flatpak-repo-utils.c:3744
msgid "Invalid bundle, no ref in metadata"
msgstr "无效捆绑包，元数据中没有引用"

#: common/flatpak-repo-utils.c:3846
#, c-format
msgid "Collection ‘%s’ of bundle doesn’t match collection ‘%s’ of remote"
msgstr "捆绑包集合“%s”不匹配远程仓库的集合“%s”"

#: common/flatpak-repo-utils.c:3923
msgid "Metadata in header and app are inconsistent"
msgstr "标头和应用中的元数据不一致"

#: common/flatpak-run.c:951
msgid "No systemd user session available, cgroups not available"
msgstr "没有可用的 systemd 用户会话，cgroups 不可用"

#: common/flatpak-run.c:1496
msgid "Unable to allocate instance id"
msgstr "无法分配实例标识"

#: common/flatpak-run.c:1632 common/flatpak-run.c:1641
#, c-format
msgid "Failed to open flatpak-info file: %s"
msgstr "打开 flatpak-info 文件失败：%s"

#: common/flatpak-run.c:1668
#, c-format
msgid "Failed to open bwrapinfo.json file: %s"
msgstr "打开 bwrapinfo.json 文件失败：%s"

#: common/flatpak-run.c:1689
#, c-format
msgid "Failed to write to instance id fd: %s"
msgstr "写入实例标识 FD 失败：%s"

#: common/flatpak-run.c:2096
msgid "Initialize seccomp failed"
msgstr "初始化 seccomp 失败"

#: common/flatpak-run.c:2135
#, c-format
msgid "Failed to add architecture to seccomp filter: %s"
msgstr "将架构添加到 seccomp 筛选器失败：%s"

#: common/flatpak-run.c:2143
#, c-format
msgid "Failed to add multiarch architecture to seccomp filter: %s"
msgstr "将多体系结构添加到 seccomp 筛选器失败：%s"

#: common/flatpak-run.c:2175 common/flatpak-run.c:2192
#: common/flatpak-run.c:2214
#, c-format
msgid "Failed to block syscall %d: %s"
msgstr "封锁系统调用 %d 失败：%s"

#: common/flatpak-run.c:2247
#, c-format
msgid "Failed to export bpf: %s"
msgstr "导出 bpf 失败：%s"

#: common/flatpak-run.c:2587
#, c-format
msgid "Failed to open ‘%s’"
msgstr "打开“%s”失败"

#: common/flatpak-run.c:2597
#, c-format
msgid ""
"Directory forwarding needs version 4 of the document portal (have version %d)"
msgstr "目录转发需要版本 4 的文档门户（拥有版本 %d）"

#: common/flatpak-run.c:2915
#, c-format
msgid "ldconfig failed, exit status %d"
msgstr "ldconfig 失败，退出状态为 %d"

#: common/flatpak-run.c:2922
msgid "Can't open generated ld.so.cache"
msgstr "无法打开生成的 ld.so.cache"

#. Translators: The placeholder is for an app ref.
#: common/flatpak-run.c:3045
#, c-format
msgid "Running %s is not allowed by the policy set by your administrator"
msgstr "您的管理员设置的策略不允许运行 %s"

#: common/flatpak-run.c:3202
msgid ""
"\"flatpak run\" is not intended to be run as `sudo flatpak run`. Use `sudo "
"-i` or `su -l` instead and invoke \"flatpak run\" from inside the new shell."
msgstr ""
"“flatpak run”不是设计为以“sudo flatpak run”运行的。使用“sudo -i”或者“su -l”代"
"替且从新的 shell 内部调用“flatpak run”。"

#: common/flatpak-run.c:3413
#, c-format
msgid "Failed to migrate from %s: %s"
msgstr "从 %s 迁移失败：%s"

#: common/flatpak-run.c:3434
#, c-format
msgid "Failed to migrate old app data directory %s to new name %s: %s"
msgstr "将旧应用数据目录 %s 迁移至新名称 %s 失败：%s"

#: common/flatpak-run.c:3443
#, c-format
msgid "Failed to create symlink while migrating %s: %s"
msgstr "迁移 %s 时创建符号链接失败：%s"

#: common/flatpak-run-dbus.c:46
msgid "Failed to open app info file"
msgstr "打开应用信息文件失败"

#: common/flatpak-run-dbus.c:149
msgid "Unable to create sync pipe"
msgstr "无法创建同步管道"

#: common/flatpak-run-dbus.c:185
msgid "Failed to sync with dbus proxy"
msgstr "与 dbus 代理同步失败"

#: common/flatpak-transaction.c:2275
#, c-format
msgid "Warning: Problem looking for related refs: %s"
msgstr "警告：查找相关引用时遇到问题：%s"

#: common/flatpak-transaction.c:2493
#, c-format
msgid "The application %s requires the runtime %s which was not found"
msgstr "应用程序 %s 需要的运行时 %s 未找到"

#: common/flatpak-transaction.c:2509
#, c-format
msgid "The application %s requires the runtime %s which is not installed"
msgstr "应用程序 %s 需要的运行时 %s 未安装"

#: common/flatpak-transaction.c:2641
#, c-format
msgid "Can't uninstall %s which is needed by %s"
msgstr "无法卸载 %2$s 需要的 %1$s"

#: common/flatpak-transaction.c:2740
#, c-format
msgid "Remote %s disabled, ignoring %s update"
msgstr "远程仓库 %s 被禁用，将忽略 %s 更新"

#: common/flatpak-transaction.c:2773
#, c-format
msgid "%s is already installed"
msgstr "%s 已安装"

#: common/flatpak-transaction.c:2776
#, c-format
msgid "%s is already installed from remote %s"
msgstr "已经从远程仓库 %2$s 安装了 %1$s"

#: common/flatpak-transaction.c:3120
#, c-format
msgid "Invalid .flatpakref: %s"
msgstr "无效的 .flatpakref：%s"

#: common/flatpak-transaction.c:3161
msgid "Warning: Could not mark already installed apps as preinstalled"
msgstr "警告：无法将已经安装的应用标记为预安装的"

#: common/flatpak-transaction.c:3382
#, c-format
msgid "Error updating remote metadata for '%s': %s"
msgstr "更新“%s”的远程仓库元数据时出错：%s"

#: common/flatpak-transaction.c:3885
#, c-format
msgid ""
"Warning: Treating remote fetch error as non-fatal since %s is already "
"installed: %s"
msgstr "警告：既然 %s 已经安装将把远程获取错误作为非致命性错误处理：%s"

#: common/flatpak-transaction.c:4209
#, c-format
msgid "No authenticator installed for remote '%s'"
msgstr "没有为远程仓库“%s”安装身份验证器"

#: common/flatpak-transaction.c:4313 common/flatpak-transaction.c:4320
#, c-format
msgid "Failed to get tokens for ref: %s"
msgstr "为引用获取令牌失败：%s"

#: common/flatpak-transaction.c:4315 common/flatpak-transaction.c:4322
msgid "Failed to get tokens for ref"
msgstr "为引用获取令牌失败"

#: common/flatpak-transaction.c:4580
#, c-format
msgid "Ref %s from %s matches more than one transaction operation"
msgstr "来自 %2$s 的引用 %1$s 匹配了多于一个处理操作"

#: common/flatpak-transaction.c:4581 common/flatpak-transaction.c:4591
msgid "any remote"
msgstr "任何远程仓库"

#: common/flatpak-transaction.c:4590
#, c-format
msgid "No transaction operation found for ref %s from %s"
msgstr "未发现用于来自 %2$s 应用 %1$s 的处理操作"

#: common/flatpak-transaction.c:4713
#, c-format
msgid "Flatpakrepo URL %s not file, HTTP or HTTPS"
msgstr "Flatpakrepo 网址 %s 不是文件、HTTP 或 HTTPS"

#: common/flatpak-transaction.c:4719
#, c-format
msgid "Can't load dependent file %s: "
msgstr "无法加载依赖文件 %s："

#: common/flatpak-transaction.c:4727
#, c-format
msgid "Invalid .flatpakrepo: %s"
msgstr "无效的 .flatpakrepo：%s"

#: common/flatpak-transaction.c:5454
msgid "Transaction already executed"
msgstr "事务已被执行"

#: common/flatpak-transaction.c:5469
msgid ""
"Refusing to operate on a user installation as root! This can lead to "
"incorrect file ownership and permission errors."
msgstr "拒绝以 root 执行用户级安装！这会导致错误的文件归属和权限错误。"

#: common/flatpak-transaction.c:5567 common/flatpak-transaction.c:5580
msgid "Aborted by user"
msgstr "被用户中止"

#: common/flatpak-transaction.c:5605
#, c-format
msgid "Skipping %s due to previous error"
msgstr "由于先前的错误，正在跳过 %s"

#: common/flatpak-transaction.c:5659
#, c-format
msgid "Aborted due to failure (%s)"
msgstr "因失败而中止（%s）"

#: common/flatpak-uri.c:118
#, no-c-format
msgid "Invalid %-encoding in URI"
msgstr "URI 中无效的 %-编码"

#: common/flatpak-uri.c:135
msgid "Illegal character in URI"
msgstr "URI 中有非法字符"

#: common/flatpak-uri.c:169
msgid "Non-UTF-8 characters in URI"
msgstr "URI 中存在非 UTF-8 字符"

#: common/flatpak-uri.c:275
#, c-format
msgid "Invalid IPv6 address ‘%.*s’ in URI"
msgstr "URI 中无效的 IPv6 地址“%.*s”"

#: common/flatpak-uri.c:330
#, c-format
msgid "Illegal encoded IP address ‘%.*s’ in URI"
msgstr "URI 中有编码方式非法的 IP 地址“%.*s”"

#: common/flatpak-uri.c:342
#, c-format
msgid "Illegal internationalized hostname ‘%.*s’ in URI"
msgstr "URI 中有非法的国际化主机名“%.*s”"

#: common/flatpak-uri.c:374 common/flatpak-uri.c:386
#, c-format
msgid "Could not parse port ‘%.*s’ in URI"
msgstr "无法解析 URI 中的端口“%.*s”"

#: common/flatpak-uri.c:393
#, c-format
msgid "Port ‘%.*s’ in URI is out of range"
msgstr "URI 中的端口“%.*s”超出范围"

#: common/flatpak-uri.c:910
msgid "URI is not absolute, and no base URI was provided"
msgstr "URI 不是绝对路径，且未提供基础 URI"

#: common/flatpak-usb.c:83
#, c-format
msgid "USB device query 'all' must not have data"
msgstr "USB 设备查询“all”不能具有数据"

#: common/flatpak-usb.c:102
#, c-format
msgid "USB query rule 'cls' must be in the form CLASS:SUBCLASS or CLASS:*"
msgstr "USB 查询规则“cls”必须为 CLASS:SUBCLASS 或 CLASS:* 的形式"

#: common/flatpak-usb.c:111
#, c-format
msgid "Invalid USB class"
msgstr "无效的 USB 类"

#: common/flatpak-usb.c:125
#, c-format
msgid "Invalid USB subclass"
msgstr "无效的 USB 子类"

#: common/flatpak-usb.c:141 common/flatpak-usb.c:148
#, c-format
msgid "USB query rule 'dev' must have a valid 4-digit hexadecimal product id"
msgstr "USB 查询规则“dev”必须具有有效的 4 位数 16 进制产品标识符"

#: common/flatpak-usb.c:164 common/flatpak-usb.c:171
#, c-format
msgid "USB query rule 'vnd' must have a valid 4-digit hexadecimal vendor id"
msgstr "USB 查询规则“vnd”必须具有有效的 4 位数 16 进制厂商标识符"

#: common/flatpak-usb.c:205
#, c-format
msgid "USB device queries must be in the form TYPE:DATA"
msgstr "USB 设备查询必须为 TYPE:DATA 的形式"

#: common/flatpak-usb.c:225
#, c-format
msgid "Unknown USB query rule %s"
msgstr "未知的 USB 查询规则 %s"

#: common/flatpak-usb.c:248
#, c-format
msgid "Empty USB query"
msgstr "空的 USB 查询"

#: common/flatpak-usb.c:274
#, c-format
msgid "Multiple USB query rules of the same type is not supported"
msgstr "不支持同一类型的多 USB 查询规则"

#: common/flatpak-usb.c:283
#, c-format
msgid "'all' must not contain extra query rules"
msgstr "“all”不能包含额外查询规则"

#: common/flatpak-usb.c:291
#, c-format
msgid "USB queries with 'dev' must also specify vendors"
msgstr "使用“dev”的 USB 查询必须同时指定厂商"

#: common/flatpak-utils.c:712
msgid "Glob can't match apps"
msgstr "Glob 无法匹配应用"

#: common/flatpak-utils.c:737
msgid "Empty glob"
msgstr "空白 glob"

#: common/flatpak-utils.c:756
msgid "Too many segments in glob"
msgstr "Glob 中太多分段"

#: common/flatpak-utils.c:777
#, c-format
msgid "Invalid glob character '%c'"
msgstr "无效的 glob 字符“%c”"

#: common/flatpak-utils.c:831
#, c-format
msgid "Missing glob on line %d"
msgstr "第 %d 行缺失 glob"

#: common/flatpak-utils.c:835
#, c-format
msgid "Trailing text on line %d"
msgstr "第 %d 行的拖尾文字"

#: common/flatpak-utils.c:839
#, c-format
msgid "on line %d"
msgstr "在第 %d 行"

#: common/flatpak-utils.c:861
#, c-format
msgid "Unexpected word '%s' on line %d"
msgstr "第 %2$d 行的意外词语“%1$s”"

#: common/flatpak-utils.c:2118
#, c-format
msgid "Invalid require-flatpak argument %s"
msgstr "无效的 require-flatpak 参数 %s"

#: common/flatpak-utils.c:2128 common/flatpak-utils.c:2147
#, c-format
msgid "%s needs a later flatpak version (%s)"
msgstr "%s 需要更新的 flatpak 版本（%s）"

#: oci-authenticator/flatpak-oci-authenticator.c:291
msgid "Not a oci remote, missing summary.xa.oci-repository"
msgstr "不是 OCI 远程仓库，缺失 summary.xa.oci-repository"

#: oci-authenticator/flatpak-oci-authenticator.c:477
msgid "Not a OCI remote"
msgstr "不是 OCI 远程仓库"

#: oci-authenticator/flatpak-oci-authenticator.c:488
msgid "Invalid token"
msgstr "无效的令牌"

#: portal/flatpak-portal.c:2292
#, c-format
msgid "No portal support found"
msgstr "未发现传送门支持"

#: portal/flatpak-portal.c:2298
msgid "Deny"
msgstr "拒绝"

#: portal/flatpak-portal.c:2300
msgid "Update"
msgstr "更新"

#: portal/flatpak-portal.c:2305
#, c-format
msgid "Update %s?"
msgstr "更新 %s 吗？"

#: portal/flatpak-portal.c:2317
msgid "The application wants to update itself."
msgstr "该应用程序想要更新自身。"

#: portal/flatpak-portal.c:2318
msgid "Update access can be changed any time from the privacy settings."
msgstr "您可以随时通过隐私设置更改更新访问。"

#: portal/flatpak-portal.c:2343
#, c-format
msgid "Application update not allowed"
msgstr "不允许更新应用程序"

#: portal/flatpak-portal.c:2501
#, c-format
msgid "Self update not supported, new version requires new permissions"
msgstr "不支持自我更新，新版本需要新的权限"

#: portal/flatpak-portal.c:2684 portal/flatpak-portal.c:2702
#, c-format
msgid "Update ended unexpectedly"
msgstr "更新意外结束"

#. SECURITY:
#. - Normal users need admin authentication to install software
#. system-wide.
#. - Note that we install polkit rules that allow local users
#. in the wheel group to install without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:23
msgid "Install signed application"
msgstr "安装签名的应用程序"

#: system-helper/org.freedesktop.Flatpak.policy.in:24
#: system-helper/org.freedesktop.Flatpak.policy.in:42
msgid "Authentication is required to install software"
msgstr "安装软件需要身份验证"

#. SECURITY:
#. - Normal users need admin authentication to install software
#. system-wide.
#. - Note that we install polkit rules that allow local users
#. in the wheel group to install without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:41
msgid "Install signed runtime"
msgstr "安装签名的运行时"

#. SECURITY:
#. - Normal users do not require admin authentication to update an
#. app as the commit will be signed, and the action is required
#. to update the system when unattended.
#. - Changing this to anything other than 'yes' will break unattended
#. updates.
#: system-helper/org.freedesktop.Flatpak.policy.in:60
msgid "Update signed application"
msgstr "更新签名的应用程序"

#: system-helper/org.freedesktop.Flatpak.policy.in:61
#: system-helper/org.freedesktop.Flatpak.policy.in:80
msgid "Authentication is required to update software"
msgstr "更新软件需要身份验证"

#. SECURITY:
#. - Normal users do not require admin authentication to update a
#. runtime as the commit will be signed, and the action is required
#. to update the system when unattended.
#. - Changing this to anything other than 'yes' will break unattended
#. updates.
#: system-helper/org.freedesktop.Flatpak.policy.in:79
msgid "Update signed runtime"
msgstr "更新签名的运行时"

#. SECURITY:
#. - Normal users do not need authentication to update metadata
#. from signed repositories.
#: system-helper/org.freedesktop.Flatpak.policy.in:94
msgid "Update remote metadata"
msgstr "更新远程仓库元数据"

#: system-helper/org.freedesktop.Flatpak.policy.in:95
msgid "Authentication is required to update remote info"
msgstr "更新远程仓库信息需要身份验证"

#. SECURITY:
#. - Normal users do not need authentication to modify the
#. OSTree repository
#. - Note that we install polkit rules that allow local users
#. in the wheel group to modify repos without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:111
msgid "Update system repository"
msgstr "更新系统仓库"

#: system-helper/org.freedesktop.Flatpak.policy.in:112
msgid "Authentication is required to modify a system repository"
msgstr "修改系统仓库需要身份验证"

#. SECURITY:
#. - Normal users need admin authentication to install software
#. system-wide.
#: system-helper/org.freedesktop.Flatpak.policy.in:126
msgid "Install bundle"
msgstr "安装捆绑包"

#: system-helper/org.freedesktop.Flatpak.policy.in:127
msgid "Authentication is required to install software from $(path)"
msgstr "从 $(path) 安装软件需要身份验证"

#. SECURITY:
#. - Normal users need admin authentication to uninstall software
#. system-wide.
#. - Note that we install polkit rules that allow local users
#. in the wheel group to uninstall without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:144
msgid "Uninstall runtime"
msgstr "卸载运行时"

#: system-helper/org.freedesktop.Flatpak.policy.in:145
msgid "Authentication is required to uninstall software"
msgstr "卸载软件需要身份验证"

#. SECURITY:
#. - Normal users need admin authentication to uninstall software
#. system-wide.
#. - Note that we install polkit rules that allow local users
#. in the wheel group to uninstall without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:161
msgid "Uninstall app"
msgstr "卸载应用"

#: system-helper/org.freedesktop.Flatpak.policy.in:162
msgid "Authentication is required to uninstall $(ref)"
msgstr "卸载 $(ref) 需要身份验证"

#. SECURITY:
#. - Normal users need admin authentication to configure system-wide
#. software repositories.
#: system-helper/org.freedesktop.Flatpak.policy.in:177
msgid "Configure Remote"
msgstr "配置远程仓库"

#: system-helper/org.freedesktop.Flatpak.policy.in:178
msgid "Authentication is required to configure software repositories"
msgstr "配置软件仓库需要身份验证"

#. SECURITY:
#. - Normal users need admin authentication to configure the system-wide
#. Flatpak installation.
#: system-helper/org.freedesktop.Flatpak.policy.in:192
msgid "Configure"
msgstr "配置"

#: system-helper/org.freedesktop.Flatpak.policy.in:193
msgid "Authentication is required to configure software installation"
msgstr "配置软件安装需要身份验证"

#. SECURITY:
#. - Normal users do not require admin authentication to update
#. appstream data as it will be signed, and the action is required
#. to update the system when unattended.
#. - Changing this to anything other than 'yes' will break unattended
#. updates.
#: system-helper/org.freedesktop.Flatpak.policy.in:210
msgid "Update appstream"
msgstr "更新 appstream"

#: system-helper/org.freedesktop.Flatpak.policy.in:211
msgid "Authentication is required to update information about software"
msgstr "更新软件信息需要身份验证"

#. SECURITY:
#. - Normal users do not require admin authentication to update
#. metadata as it will be signed, and the action is required
#. to update the system when unattended.
#. - Changing this to anything other than 'yes' will break unattended
#. updates.
#: system-helper/org.freedesktop.Flatpak.policy.in:228
msgid "Update metadata"
msgstr "更新元数据"

#: system-helper/org.freedesktop.Flatpak.policy.in:229
msgid "Authentication is required to update metadata"
msgstr "更新元数据需要身份验证"

#. SECURITY:
#. - Authorisation to actually install software is controlled by
#. org.freedesktop.Flatpak.app-install.
#. - This action is checked after app-install, as it can only be done
#. once the app’s data (including its content rating) has been
#. downloaded.
#. - This action is checked to see if the installation should be allowed
#. based on whether the app being installed has content which doesn’t
#. comply with the user’s parental controls policy (the content is
#. ‘too extreme’).
#. - It is checked only if an app has too extreme content for the user
#. who is trying to install it (in which case, the app is ‘unsafe’).
#. - Typically, normal users will need admin permission to install apps
#. with extreme content; admins will be able to install it without
#. additional checks.
#. - In order to configure the policy so that admins can install safe and
#. unsafe software anywhere without authorisation, and non-admins can
#. install safe software in their user or system dirs without
#. authorisation, but need authorisation to install unsafe software
#. anywhere:
#. * Unconditionally return `yes` from `app-install`.
#. * Return `auth_admin` from `override-parental-controls` for users
#. not in `@privileged_group@`, and `yes` for users in it.
#. * Set the malcontent `is-{user,system}-installation-allowed`
#. properties of all non-admins’ parental controls policies to true.
#. - In order to configure the policy so that admins can install safe and
#. unsafe software anywhere without authorisation, and non-admins can
#. install safe software in their user dir without authorisation, but
#. need authorisation to install safe software in the system dir or to
#. install unsafe software anywhere:
#. * Unconditionally return `yes` from `app-install`.
#. * Return `auth_admin` from `override-parental-controls` for users
#. not in `@privileged_group@`, and `yes` for users in it.
#. * Set the malcontent `is-user-installation-allowed` property of all
#. non-admins’ parental controls policies to true.
#. * Set the malcontent `is-system-installation-allowed` property of
#. all non-admins’ parental controls policies to false.
#. - In order to configure the policy so that all users (including
#. admins) can install safe software anywhere without authorisation,
#. but need authorisation to install unsafe software anywhere (i.e.
#. applying parental controls to admins too):
#. * Unconditionally return `yes` from `app-install`.
#. * Unconditionally return `auth_admin` from `override-parental-controls`.
#. * Set the malcontent `is-user-installation-allowed` property of all
#. users’ parental controls policies to true.
#. * Set the malcontent `is-system-installation-allowed` property of
#. all users’ parental controls policies to true.
#: system-helper/org.freedesktop.Flatpak.policy.in:287
msgid "Override parental controls for installs"
msgstr "为安装覆盖家长控制"

#: system-helper/org.freedesktop.Flatpak.policy.in:288
msgid ""
"Authentication is required to install software which is restricted by your "
"parental controls policy"
msgstr "安装受您的家长控制策略限制的软件需要身份验证"

#. SECURITY:
#. - This is like org.freedesktop.Flatpak.override-parental-controls, but
#. it’s queried for app updates, whereas the former is queried for app
#. installs.
#. - As with the above action, this one is only queried if
#. org.freedesktop.Flatpak.app-update has allowed the app update, and
#. only if the app being updated has too extreme content for the user
#. who is trying to update it.
#. - The default policy for this is to *allow* updates to ‘too extreme’
#. apps by default, on the basis that having an out-of-date (i.e.
#. insecure or unsupported) app is a worse outcome than automatically
#. installing an update which has radically different content from the
#. version of the app which the parent originally vetted and installed.
#: system-helper/org.freedesktop.Flatpak.policy.in:313
msgid "Override parental controls for updates"
msgstr "为更新覆盖家长控制"

#: system-helper/org.freedesktop.Flatpak.policy.in:314
msgid ""
"Authentication is required to update software which is restricted by your "
"parental controls policy"
msgstr "更新受您的家长控制策略限制的软件需要身份验证"

#~ msgid "Installed:"
#~ msgstr "已安装："

#~ msgid "Download:"
#~ msgstr "下载："

#, c-format
#~ msgid "No gpg key found with ID %s (homedir: %s)"
#~ msgstr "未找到身份标识 %s 的 GPG 密钥（主目录：%s）"

#, c-format
#~ msgid "Unable to lookup key ID %s: %d"
#~ msgstr "无法查找密钥标识 %s：%d"

#, c-format
#~ msgid "Error signing commit: %d"
#~ msgstr "签署提交时出错：%d"

#, c-format
#~ msgid ""
#~ "Found similar ref(s) for ‘%s’ in remote ‘%s’ (%s).\n"
#~ "Use this remote?"
#~ msgstr ""
#~ "在远程仓库“%2$s”（%3$s）中找到与“%1$s”相似的引用。\n"
#~ "使用该远程仓库吗？"

#, c-format
#~ msgid "No entry for %s in remote '%s' summary cache "
#~ msgstr "在远程仓库“%2$s”摘要缓存中没有 %1$s 的条目 "

#, c-format
#~ msgid "Failed to uninstall %s for rebase to %s: "
#~ msgstr "卸载 %s 以重新建基于 %s 失败："

#, c-format
#~ msgid "Failed to uninstall %s for rebase to %s: %s\n"
#~ msgstr "卸载 %s 以重新建基于 %s 失败：%s\n"

#, c-format
#~ msgid "Unable to open directory %s"
#~ msgstr "无法打开目录 %s"

#~ msgid "install"
#~ msgstr "安装"

#~ msgid "update"
#~ msgstr "更新"

#~ msgid "install bundle"
#~ msgstr "安装捆绑包"

#~ msgid "uninstall"
#~ msgstr "卸载"

#~ msgid "(internal error, please report)"
#~ msgstr "（内部错误，请报告）"

#~ msgid "Warning:"
#~ msgstr "警告："

#, c-format
#~ msgid "%s%s%s branch %s%s%s"
#~ msgstr "%s%s%s 分支 %s%s%s"

#, fuzzy
#~ msgid "runtime"
#~ msgstr "运行时"

#, fuzzy
#~ msgid "app"
#~ msgstr "应用"

#~ msgid "[REF…] - Uninstall an application"
#~ msgstr "[引用…] - 卸载应用程序"

#, c-format
#~ msgid "Replace it with %s?"
#~ msgstr "将其替换为 %s 吗？"

===== ./po/oc.po =====
msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: https://github.com/flatpak/flatpak/issues\n"
"POT-Creation-Date: 2026-05-27 16:39+0200\n"
"PO-Revision-Date: 2023-03-14 20:45+0100\n"
"Last-Translator: Quentin PAGÈS\n"
"Language-Team: \n"
"Language: oc\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: Poedit 3.2.2\n"
"X-Poedit-Basepath: .\n"

#: app/flatpak-builtins-build-bundle.c:59
msgid "Export runtime instead of app"
msgstr ""

#: app/flatpak-builtins-build-bundle.c:60
msgid "Arch to bundle for"
msgstr ""

#: app/flatpak-builtins-build-bundle.c:60
#: app/flatpak-builtins-build-export.c:62 app/flatpak-builtins-build-init.c:53
#: app/flatpak-builtins-build-sign.c:42 app/flatpak-builtins-create-usb.c:46
#: app/flatpak-builtins-info.c:55 app/flatpak-builtins-install.c:67
#: app/flatpak-builtins-list.c:50 app/flatpak-builtins-make-current.c:38
#: app/flatpak-builtins-remote-info.c:54 app/flatpak-builtins-remote-ls.c:56
#: app/flatpak-builtins-run.c:158 app/flatpak-builtins-search.c:37
#: app/flatpak-builtins-uninstall.c:54 app/flatpak-builtins-update.c:56
msgid "ARCH"
msgstr "ARCH"

#: app/flatpak-builtins-build-bundle.c:61
msgid "URL for repo"
msgstr ""

#: app/flatpak-builtins-build-bundle.c:61
#: app/flatpak-builtins-build-bundle.c:62
#: app/flatpak-builtins-build-update-repo.c:68
#: app/flatpak-builtins-build-update-repo.c:72
#: app/flatpak-builtins-build-update-repo.c:73
#: app/flatpak-builtins-history.c:69 app/flatpak-builtins-remote-add.c:80
#: app/flatpak-builtins-remote-add.c:81 app/flatpak-builtins-remote-add.c:85
#: app/flatpak-builtins-remote-list.c:53
#: app/flatpak-builtins-remote-modify.c:70
#: app/flatpak-builtins-remote-modify.c:85
#: app/flatpak-builtins-remote-modify.c:86
#: app/flatpak-builtins-remote-modify.c:90
msgid "URL"
msgstr "URL"

#: app/flatpak-builtins-build-bundle.c:62
msgid "URL for runtime flatpakrepo file"
msgstr ""

#: app/flatpak-builtins-build-bundle.c:63
msgid "Add GPG key from FILE (- for stdin)"
msgstr ""

#: app/flatpak-builtins-build-bundle.c:63 app/flatpak-builtins-build.c:54
#: app/flatpak-builtins-build-export.c:67
#: app/flatpak-builtins-build-update-repo.c:83
#: app/flatpak-builtins-install.c:81 app/flatpak-builtins-remote-add.c:84
#: app/flatpak-builtins-remote-add.c:86 app/flatpak-builtins-remote-modify.c:89
#: app/flatpak-builtins-remote-modify.c:92
msgid "FILE"
msgstr "FICHIÈR"

#: app/flatpak-builtins-build-bundle.c:64
msgid "GPG Key ID to sign the OCI image with"
msgstr ""

#: app/flatpak-builtins-build-bundle.c:64
#: app/flatpak-builtins-build-commit-from.c:68
#: app/flatpak-builtins-build-export.c:68
#: app/flatpak-builtins-build-import-bundle.c:49
#: app/flatpak-builtins-build-sign.c:44
#: app/flatpak-builtins-build-update-repo.c:84
msgid "KEY-ID"
msgstr ""

#: app/flatpak-builtins-build-bundle.c:65
#: app/flatpak-builtins-build-commit-from.c:69
#: app/flatpak-builtins-build-export.c:71
#: app/flatpak-builtins-build-import-bundle.c:50
#: app/flatpak-builtins-build-sign.c:45
#: app/flatpak-builtins-build-update-repo.c:85
msgid "GPG Homedir to use when looking for keyrings"
msgstr ""

#: app/flatpak-builtins-build-bundle.c:65
#: app/flatpak-builtins-build-commit-from.c:69
#: app/flatpak-builtins-build-export.c:71
#: app/flatpak-builtins-build-import-bundle.c:50
#: app/flatpak-builtins-build-sign.c:45
#: app/flatpak-builtins-build-update-repo.c:85
msgid "HOMEDIR"
msgstr ""

#: app/flatpak-builtins-build-bundle.c:66
msgid "OSTree commit to create a delta bundle from"
msgstr ""

#: app/flatpak-builtins-build-bundle.c:66 app/flatpak-builtins-remote-info.c:55
#: app/flatpak-builtins-update.c:57
msgid "COMMIT"
msgstr ""

#: app/flatpak-builtins-build-bundle.c:67
msgid "Export oci image instead of flatpak bundle"
msgstr ""

#: app/flatpak-builtins-build-bundle.c:70
msgid "How to compress OCI image layers (default: gzip)"
msgstr ""

#: app/flatpak-builtins-build-bundle.c:634
msgid ""
"LOCATION FILENAME NAME [BRANCH] - Create a single file bundle from a local "
"repository"
msgstr ""

#: app/flatpak-builtins-build-bundle.c:641
msgid "LOCATION, FILENAME and NAME must be specified"
msgstr ""

#: app/flatpak-builtins-build-bundle.c:644
#: app/flatpak-builtins-build-export.c:844
#: app/flatpak-builtins-build-import-bundle.c:136
#: app/flatpak-builtins-build-init.c:217 app/flatpak-builtins-build-sign.c:76
#: app/flatpak-builtins-document-export.c:112
#: app/flatpak-builtins-document-info.c:75
#: app/flatpak-builtins-document-list.c:191
#: app/flatpak-builtins-document-unexport.c:70
#: app/flatpak-builtins-history.c:482 app/flatpak-builtins-info.c:130
#: app/flatpak-builtins-install.c:181 app/flatpak-builtins-install.c:234
#: app/flatpak-builtins-install.c:298 app/flatpak-builtins-list.c:419
#: app/flatpak-builtins-make-current.c:72 app/flatpak-builtins-override.c:73
#: app/flatpak-builtins-permission-list.c:162
#: app/flatpak-builtins-permission-remove.c:132
#: app/flatpak-builtins-remote-add.c:323
#: app/flatpak-builtins-remote-delete.c:68
#: app/flatpak-builtins-remote-list.c:241 app/flatpak-builtins-remote-ls.c:407
msgid "Too many arguments"
msgstr "Tròp d'arguments"

#: app/flatpak-builtins-build-bundle.c:659
#: app/flatpak-builtins-build-commit-from.c:338
#: app/flatpak-builtins-build-commit-from.c:351
#: app/flatpak-builtins-build-import-bundle.c:145
#, c-format
msgid "'%s' is not a valid repository"
msgstr "« %s » es pas un repertòri valid"

#: app/flatpak-builtins-build-bundle.c:663
#, c-format
msgid "'%s' is not a valid repository: "
msgstr "« %s » es pas un repertòri valid : "

#: app/flatpak-builtins-build-bundle.c:674 app/flatpak-builtins-build-sign.c:88
#: common/flatpak-dir.c:14293
#, c-format
msgid "'%s' is not a valid name: %s"
msgstr "« %s » es pas un nom valid : %s"

#: app/flatpak-builtins-build-bundle.c:677
#: app/flatpak-builtins-build-export.c:865 app/flatpak-builtins-build-sign.c:91
#: common/flatpak-dir.c:14299
#, c-format
msgid "'%s' is not a valid branch name: %s"
msgstr "« %s » es pas un nom de branca valid : %s"

#: app/flatpak-builtins-build-bundle.c:691
#: app/flatpak-builtins-build-import-bundle.c:149
#: app/flatpak-builtins-build-init.c:281
#, c-format
msgid "'%s' is not a valid filename"
msgstr "« %s » es pas un nom de fichièr valid"

#: app/flatpak-builtins-build-bundle.c:706
msgid "--oci-layer-compress value must be gzip or zstd"
msgstr ""

#: app/flatpak-builtins-build.c:49
msgid "Use Platform runtime rather than Sdk"
msgstr ""

#: app/flatpak-builtins-build.c:50
msgid "Make destination readonly"
msgstr "Far venir la destinacion en lectura sola"

#: app/flatpak-builtins-build.c:51
msgid "Add bind mount"
msgstr ""

#: app/flatpak-builtins-build.c:51
msgid "DEST=SRC"
msgstr "DEST=SRC"

#: app/flatpak-builtins-build.c:52
msgid "Start build in this directory"
msgstr ""

#: app/flatpak-builtins-build.c:52 app/flatpak-builtins-build.c:53
#: app/flatpak-builtins-build-init.c:64 app/flatpak-builtins-run.c:160
msgid "DIR"
msgstr "DIR"

#: app/flatpak-builtins-build.c:53
msgid "Where to look for custom sdk dir (defaults to 'usr')"
msgstr ""

#: app/flatpak-builtins-build.c:54 app/flatpak-builtins-build-export.c:67
msgid "Use alternative file for the metadata"
msgstr ""

#: app/flatpak-builtins-build.c:55 app/flatpak-builtins-run.c:177
msgid "Kill processes when the parent process dies"
msgstr ""

#: app/flatpak-builtins-build.c:56
msgid "Export application homedir directory to build"
msgstr ""

#: app/flatpak-builtins-build.c:57 app/flatpak-builtins-run.c:165
msgid "Log session bus calls"
msgstr ""

#: app/flatpak-builtins-build.c:58 app/flatpak-builtins-run.c:166
msgid "Log system bus calls"
msgstr ""

#: app/flatpak-builtins-build.c:262
msgid "DIRECTORY [COMMAND [ARGUMENT…]] - Build in directory"
msgstr ""

#: app/flatpak-builtins-build.c:285 app/flatpak-builtins-build-finish.c:656
msgid "DIRECTORY must be specified"
msgstr ""

#: app/flatpak-builtins-build.c:296 app/flatpak-builtins-build-export.c:887
#, c-format
msgid "Build directory %s not initialized, use flatpak build-init"
msgstr ""

#: app/flatpak-builtins-build.c:315
msgid "metadata invalid, not application or runtime"
msgstr ""

#: app/flatpak-builtins-build.c:446
#, c-format
msgid "No extension point matching %s in %s"
msgstr ""

#: app/flatpak-builtins-build.c:635
#, c-format
msgid "Missing '=' in bind mount option '%s'"
msgstr ""

#: app/flatpak-builtins-build.c:679 common/flatpak-run.c:3961
#, c-format
msgid "Unable to start app"
msgstr ""

#: app/flatpak-builtins-build-commit-from.c:58
msgid "Source repo dir"
msgstr ""

#: app/flatpak-builtins-build-commit-from.c:58
msgid "SRC-REPO"
msgstr ""

#: app/flatpak-builtins-build-commit-from.c:59
msgid "Source repo ref"
msgstr ""

#: app/flatpak-builtins-build-commit-from.c:59
msgid "SRC-REF"
msgstr ""

#: app/flatpak-builtins-build-commit-from.c:64
#: app/flatpak-builtins-build-export.c:60
msgid "One line subject"
msgstr ""

#: app/flatpak-builtins-build-commit-from.c:64
#: app/flatpak-builtins-build-export.c:60
msgid "SUBJECT"
msgstr "SUBJÈCTE"

#: app/flatpak-builtins-build-commit-from.c:65
#: app/flatpak-builtins-build-export.c:61
msgid "Full description"
msgstr "Descripcion complèta"

#: app/flatpak-builtins-build-commit-from.c:65
#: app/flatpak-builtins-build-export.c:61
msgid "BODY"
msgstr "CÒS"

#: app/flatpak-builtins-build-commit-from.c:66
#: app/flatpak-builtins-build-export.c:64
#: app/flatpak-builtins-build-import-bundle.c:51
msgid "Update the appstream branch"
msgstr ""

#: app/flatpak-builtins-build-commit-from.c:67
#: app/flatpak-builtins-build-export.c:65
#: app/flatpak-builtins-build-import-bundle.c:52
#: app/flatpak-builtins-build-update-repo.c:87
msgid "Don't update the summary"
msgstr ""

#: app/flatpak-builtins-build-commit-from.c:68
#: app/flatpak-builtins-build-export.c:68
#: app/flatpak-builtins-build-import-bundle.c:49
#: app/flatpak-builtins-build-sign.c:44
msgid "GPG Key ID to sign the commit with"
msgstr ""

#: app/flatpak-builtins-build-commit-from.c:70
#: app/flatpak-builtins-build-export.c:73
msgid "Mark build as end-of-life"
msgstr ""

#: app/flatpak-builtins-build-commit-from.c:70
#: app/flatpak-builtins-build-export.c:73
msgid "REASON"
msgstr "RAISON"

#: app/flatpak-builtins-build-commit-from.c:71
msgid ""
"Mark refs matching the OLDID prefix as end-of-life, to be replaced with the "
"given NEWID"
msgstr ""

#: app/flatpak-builtins-build-commit-from.c:71
msgid "OLDID=NEWID"
msgstr ""

#: app/flatpak-builtins-build-commit-from.c:72
#: app/flatpak-builtins-build-export.c:75
msgid "Set type of token needed to install this commit"
msgstr ""

#: app/flatpak-builtins-build-commit-from.c:72
#: app/flatpak-builtins-build-export.c:75
msgid "VAL"
msgstr "VAL"

#: app/flatpak-builtins-build-commit-from.c:73
msgid "Override the timestamp of the commit (NOW for current time)"
msgstr ""

#: app/flatpak-builtins-build-commit-from.c:73
#: app/flatpak-builtins-build-export.c:76
msgid "TIMESTAMP"
msgstr "Orodatatge"

#: app/flatpak-builtins-build-commit-from.c:75
#: app/flatpak-builtins-build-export.c:80
#: app/flatpak-builtins-build-import-bundle.c:53
#: app/flatpak-builtins-build-update-repo.c:97
msgid "Don't generate a summary index"
msgstr "Generar pas d’indèx d’ensenhador"

#: app/flatpak-builtins-build-commit-from.c:278
msgid "DST-REPO [DST-REF…] - Make a new commit from existing commits"
msgstr ""

#: app/flatpak-builtins-build-commit-from.c:285
msgid "DST-REPO must be specified"
msgstr ""

#: app/flatpak-builtins-build-commit-from.c:293
msgid ""
"If --src-repo is not specified, exactly one destination ref must be specified"
msgstr ""

#: app/flatpak-builtins-build-commit-from.c:296
msgid ""
"If --src-ref is specified, exactly one destination ref must be specified"
msgstr ""

#: app/flatpak-builtins-build-commit-from.c:299
msgid "Either --src-repo or --src-ref must be specified"
msgstr ""

#: app/flatpak-builtins-build-commit-from.c:315
msgid "Invalid argument format of use  --end-of-life-rebase=OLDID=NEWID"
msgstr ""

#: app/flatpak-builtins-build-commit-from.c:321
#: app/flatpak-builtins-build-commit-from.c:324
#, c-format
msgid "Invalid name %s in --end-of-life-rebase"
msgstr ""

#: app/flatpak-builtins-build-commit-from.c:333
#: app/flatpak-builtins-build-export.c:1092
#, c-format
msgid "Could not parse '%s'"
msgstr "Impossible d'analisar « %s »"

#: app/flatpak-builtins-build-commit-from.c:498
msgid "Can't commit from partial source commit"
msgstr ""

#: app/flatpak-builtins-build-commit-from.c:503
#, c-format
msgid "%s: no change\n"
msgstr "%s : cap de modificacion\n"

#: app/flatpak-builtins-build-export.c:62
msgid "Architecture to export for (must be host compatible)"
msgstr ""

#: app/flatpak-builtins-build-export.c:63
msgid "Commit runtime (/usr), not /app"
msgstr ""

#: app/flatpak-builtins-build-export.c:66
msgid "Use alternative directory for the files"
msgstr ""

#: app/flatpak-builtins-build-export.c:66
msgid "SUBDIR"
msgstr ""

#: app/flatpak-builtins-build-export.c:69
msgid "Files to exclude"
msgstr "Fichièrs d’exclure"

#: app/flatpak-builtins-build-export.c:69
#: app/flatpak-builtins-build-export.c:70
#: app/flatpak-builtins-build-update-repo.c:90
msgid "PATTERN"
msgstr "MOTIU"

#: app/flatpak-builtins-build-export.c:70
msgid "Excluded files to include"
msgstr "Fichièrs excluses d’inclure"

#: app/flatpak-builtins-build-export.c:74
msgid "Mark build as end-of-life, to be replaced with the given ID"
msgstr ""

#: app/flatpak-builtins-build-export.c:74
#: app/flatpak-builtins-document-list.c:49 app/flatpak-cli-transaction.c:1427
msgid "ID"
msgstr "ID"

#: app/flatpak-builtins-build-export.c:76
msgid "Override the timestamp of the commit"
msgstr ""

#: app/flatpak-builtins-build-export.c:77
#: app/flatpak-builtins-build-update-repo.c:75
#: app/flatpak-builtins-remote-add.c:83 app/flatpak-builtins-remote-list.c:54
#: app/flatpak-builtins-remote-modify.c:88
msgid "Collection ID"
msgstr "ID de colleccion"

#: app/flatpak-builtins-build-export.c:472
#, c-format
msgid "WARNING: Error running desktop-file-validate: %s\n"
msgstr ""

#: app/flatpak-builtins-build-export.c:480
#, c-format
msgid "WARNING: Error reading from desktop-file-validate: %s\n"
msgstr ""

#: app/flatpak-builtins-build-export.c:486
#, c-format
msgid "WARNING: Failed to validate desktop file %s: %s\n"
msgstr ""

#: app/flatpak-builtins-build-export.c:513
#, c-format
msgid "WARNING: Can't find Exec key in %s: %s\n"
msgstr ""

#: app/flatpak-builtins-build-export.c:521
#: app/flatpak-builtins-build-export.c:614
#, c-format
msgid "WARNING: Binary not found for Exec line in %s: %s\n"
msgstr ""

#: app/flatpak-builtins-build-export.c:529
#, c-format
msgid "WARNING: Icon not matching app id in %s: %s\n"
msgstr ""

#: app/flatpak-builtins-build-export.c:552
#, c-format
msgid "WARNING: Icon referenced in desktop file but not exported: %s\n"
msgstr ""

#: app/flatpak-builtins-build-export.c:719
#, c-format
msgid "Invalid uri type %s, only http/https supported"
msgstr ""

#: app/flatpak-builtins-build-export.c:737
#, c-format
msgid "Unable to find basename in %s, specify a name explicitly"
msgstr ""

#: app/flatpak-builtins-build-export.c:746
#, c-format
msgid "No slashes allowed in extra data name"
msgstr ""

#: app/flatpak-builtins-build-export.c:758
#, c-format
msgid "Invalid format for sha256 checksum: '%s'"
msgstr ""

#: app/flatpak-builtins-build-export.c:768
#, c-format
msgid "Extra data sizes of zero not supported"
msgstr ""

#: app/flatpak-builtins-build-export.c:830
msgid ""
"LOCATION DIRECTORY [BRANCH] - Create a repository from a build directory"
msgstr ""

#: app/flatpak-builtins-build-export.c:838
msgid "LOCATION and DIRECTORY must be specified"
msgstr ""

#: app/flatpak-builtins-build-export.c:859
#: app/flatpak-builtins-remote-add.c:327
#, c-format
msgid "‘%s’ is not a valid collection ID: %s"
msgstr ""

#: app/flatpak-builtins-build-export.c:904
#: app/flatpak-builtins-build-finish.c:684
msgid "No name specified in the metadata"
msgstr ""

#: app/flatpak-builtins-build-export.c:1166
#, c-format
msgid "Commit: %s\n"
msgstr ""

#: app/flatpak-builtins-build-export.c:1167
#, c-format
msgid "Metadata Total: %u\n"
msgstr ""

#: app/flatpak-builtins-build-export.c:1168
#, c-format
msgid "Metadata Written: %u\n"
msgstr ""

#: app/flatpak-builtins-build-export.c:1169
#, c-format
msgid "Content Total: %u\n"
msgstr ""

#: app/flatpak-builtins-build-export.c:1170
#, c-format
msgid "Content Written: %u\n"
msgstr ""

#: app/flatpak-builtins-build-export.c:1171
#, c-format
msgid "Content Bytes Written:"
msgstr ""

#: app/flatpak-builtins-build-finish.c:52
msgid "Command to set"
msgstr ""

#: app/flatpak-builtins-build-finish.c:52 app/flatpak-builtins-run.c:159
#: app/flatpak-main.c:209
msgid "COMMAND"
msgstr "COMANDA"

#: app/flatpak-builtins-build-finish.c:53
msgid "Flatpak version to require"
msgstr "Version de Flatpak de requerir"

#: app/flatpak-builtins-build-finish.c:53
msgid "MAJOR.MINOR.MICRO"
msgstr "MAJORA.MINORA.MICRO"

#: app/flatpak-builtins-build-finish.c:54
msgid "Don't process exports"
msgstr ""

#: app/flatpak-builtins-build-finish.c:55
msgid "Extra data info"
msgstr "Info de donadas suplementàrias"

#: app/flatpak-builtins-build-finish.c:56 app/flatpak-builtins-build-init.c:63
msgid "Add extension point info"
msgstr ""

#: app/flatpak-builtins-build-finish.c:56 app/flatpak-builtins-build-init.c:63
msgid "NAME=VARIABLE[=VALUE]"
msgstr ""

#: app/flatpak-builtins-build-finish.c:57
msgid "Remove extension point info"
msgstr ""

#: app/flatpak-builtins-build-finish.c:57
#: app/flatpak-builtins-build-update-repo.c:79 app/flatpak-builtins-info.c:58
#: app/flatpak-builtins-remote-add.c:88 app/flatpak-builtins-remote-modify.c:94
#: app/flatpak-main.c:182
msgid "NAME"
msgstr "NOM"

#: app/flatpak-builtins-build-finish.c:58
msgid "Set extension priority (only for extensions)"
msgstr ""

#: app/flatpak-builtins-build-finish.c:58
msgid "VALUE"
msgstr "VALOR"

#: app/flatpak-builtins-build-finish.c:59
msgid "Change the sdk used for the app"
msgstr ""

#: app/flatpak-builtins-build-finish.c:59
msgid "SDK"
msgstr ""

#: app/flatpak-builtins-build-finish.c:60
msgid "Change the runtime used for the app"
msgstr ""

#: app/flatpak-builtins-build-finish.c:60 app/flatpak-builtins-build-init.c:54
#: app/flatpak-builtins-list.c:53 app/flatpak-builtins-remote-ls.c:58
#: app/flatpak-builtins-run.c:163
msgid "RUNTIME"
msgstr ""

#: app/flatpak-builtins-build-finish.c:61
msgid "Set generic metadata option"
msgstr ""

#: app/flatpak-builtins-build-finish.c:61
msgid "GROUP=KEY[=VALUE]"
msgstr ""

#: app/flatpak-builtins-build-finish.c:62
msgid "Don't inherit permissions from runtime"
msgstr ""

#: app/flatpak-builtins-build-finish.c:155
#, c-format
msgid "Not exporting %s, wrong extension\n"
msgstr ""

#: app/flatpak-builtins-build-finish.c:163
#, c-format
msgid "Not exporting %s, non-allowed export filename\n"
msgstr ""

#: app/flatpak-builtins-build-finish.c:167
#, c-format
msgid "Exporting %s\n"
msgstr "Exportacion %s\n"

#: app/flatpak-builtins-build-finish.c:440
#, c-format
msgid "More than one executable found\n"
msgstr ""

#: app/flatpak-builtins-build-finish.c:451
#, c-format
msgid "Using %s as command\n"
msgstr ""

#: app/flatpak-builtins-build-finish.c:456
#, c-format
msgid "No executable found\n"
msgstr "Cap d’executable pas trobat\n"

#: app/flatpak-builtins-build-finish.c:511
#, c-format
msgid "Invalid --require-version argument: %s"
msgstr ""

#: app/flatpak-builtins-build-finish.c:543
#, c-format
msgid "Too few elements in --extra-data argument %s"
msgstr ""

#: app/flatpak-builtins-build-finish.c:575
#, c-format
msgid ""
"Too few elements in --metadata argument %s, format should be "
"GROUP=KEY[=VALUE]]"
msgstr ""

#: app/flatpak-builtins-build-finish.c:597
#: app/flatpak-builtins-build-init.c:458
#, c-format
msgid ""
"Too few elements in --extension argument %s, format should be "
"NAME=VAR[=VALUE]"
msgstr ""

#: app/flatpak-builtins-build-finish.c:603
#: app/flatpak-builtins-build-init.c:461
#, c-format
msgid "Invalid extension name %s"
msgstr ""

#: app/flatpak-builtins-build-finish.c:646
msgid "DIRECTORY - Finalize a build directory"
msgstr ""

#: app/flatpak-builtins-build-finish.c:668
#, c-format
msgid "Build directory %s not initialized"
msgstr ""

#: app/flatpak-builtins-build-finish.c:689
#, c-format
msgid "Build directory %s already finalized"
msgstr ""

#: app/flatpak-builtins-build-finish.c:702
#, c-format
msgid "Please review the exported files and the metadata\n"
msgstr ""

#: app/flatpak-builtins-build-import-bundle.c:47
msgid "Override the ref used for the imported bundle"
msgstr ""

#: app/flatpak-builtins-build-import-bundle.c:47
msgid "REF"
msgstr ""

#: app/flatpak-builtins-build-import-bundle.c:48
msgid "Import oci image instead of flatpak bundle"
msgstr ""

#: app/flatpak-builtins-build-import-bundle.c:77
#: app/flatpak-builtins-build-import-bundle.c:105
#, c-format
msgid "Importing %s (%s)\n"
msgstr ""

#: app/flatpak-builtins-build-import-bundle.c:126
msgid "LOCATION FILENAME - Import a file bundle into a local repository"
msgstr ""

#: app/flatpak-builtins-build-import-bundle.c:133
msgid "LOCATION and FILENAME must be specified"
msgstr ""

#: app/flatpak-builtins-build-init.c:53 app/flatpak-builtins-info.c:55
#: app/flatpak-builtins-run.c:158
msgid "Arch to use"
msgstr ""

#: app/flatpak-builtins-build-init.c:54
msgid "Initialize var from named runtime"
msgstr ""

#: app/flatpak-builtins-build-init.c:55
msgid "Initialize apps from named app"
msgstr ""

#: app/flatpak-builtins-build-init.c:55
msgid "APP"
msgstr ""

#: app/flatpak-builtins-build-init.c:56
msgid "Specify version for --base"
msgstr ""

#: app/flatpak-builtins-build-init.c:56 app/flatpak-builtins-run.c:164
msgid "VERSION"
msgstr "VERSION"

#: app/flatpak-builtins-build-init.c:57
msgid "Include this base extension"
msgstr ""

#: app/flatpak-builtins-build-init.c:57 app/flatpak-builtins-build-init.c:62
msgid "EXTENSION"
msgstr "EXTENSION"

#: app/flatpak-builtins-build-init.c:58
msgid "Extension tag to use if building extension"
msgstr ""

#: app/flatpak-builtins-build-init.c:58
msgid "EXTENSION_TAG"
msgstr ""

#: app/flatpak-builtins-build-init.c:59
msgid "Initialize /usr with a writable copy of the sdk"
msgstr ""

#: app/flatpak-builtins-build-init.c:60
msgid "Specify the build type (app, runtime, extension)"
msgstr ""

#: app/flatpak-builtins-build-init.c:60
msgid "TYPE"
msgstr "TIPE"

#: app/flatpak-builtins-build-init.c:61
msgid "Add a tag"
msgstr "Apondre una etiqueta"

#: app/flatpak-builtins-build-init.c:61
msgid "TAG"
msgstr "ETIQUETA"

#: app/flatpak-builtins-build-init.c:62
msgid "Include this sdk extension in /usr"
msgstr ""

#: app/flatpak-builtins-build-init.c:64
msgid "Where to store sdk (defaults to 'usr')"
msgstr ""

#: app/flatpak-builtins-build-init.c:65
msgid "Re-initialize the sdk/var"
msgstr ""

#: app/flatpak-builtins-build-init.c:118
#, fuzzy, c-format
msgid "Requested extension %s/%s/%s is only partially installed"
msgstr "Requested extension %s is only partially installed"

#: app/flatpak-builtins-build-init.c:147
#, c-format
msgid "Requested extension %s/%s/%s not installed"
msgstr ""

#: app/flatpak-builtins-build-init.c:207
msgid ""
"DIRECTORY APPNAME SDK RUNTIME [BRANCH] - Initialize a directory for building"
msgstr ""

#: app/flatpak-builtins-build-init.c:214
msgid "RUNTIME must be specified"
msgstr ""

#: app/flatpak-builtins-build-init.c:235
#, c-format
msgid "'%s' is not a valid build type name, use app, runtime or extension"
msgstr ""

#: app/flatpak-builtins-build-init.c:241 app/flatpak-builtins-override.c:79
#, c-format
msgid "'%s' is not a valid application name: %s"
msgstr ""

#: app/flatpak-builtins-build-init.c:295
#, c-format
msgid "Build directory %s already initialized"
msgstr ""

#: app/flatpak-builtins-build-sign.c:42 app/flatpak-builtins-install.c:67
#: app/flatpak-builtins-remote-info.c:54
msgid "Arch to install for"
msgstr ""

#: app/flatpak-builtins-build-sign.c:43 app/flatpak-builtins-create-usb.c:48
#: app/flatpak-builtins-install.c:74 app/flatpak-builtins-remote-info.c:56
#: app/flatpak-builtins-uninstall.c:58 app/flatpak-builtins-update.c:64
msgid "Look for runtime with the specified name"
msgstr ""

#: app/flatpak-builtins-build-sign.c:66
msgid "LOCATION [ID [BRANCH]] - Sign an application or runtime"
msgstr ""

#: app/flatpak-builtins-build-sign.c:73
#: app/flatpak-builtins-build-update-repo.c:499
#: app/flatpak-builtins-remote-add.c:320 app/flatpak-builtins-repo.c:739
msgid "LOCATION must be specified"
msgstr ""

#: app/flatpak-builtins-build-sign.c:94
msgid "No gpg key ids specified"
msgstr ""

#: app/flatpak-builtins-build-update-repo.c:68
msgid "Redirect this repo to a new URL"
msgstr ""

#: app/flatpak-builtins-build-update-repo.c:69
msgid "A nice name to use for this repository"
msgstr ""

#: app/flatpak-builtins-build-update-repo.c:69
#: app/flatpak-builtins-remote-add.c:77 app/flatpak-builtins-remote-modify.c:82
msgid "TITLE"
msgstr "TÍTOL"

#: app/flatpak-builtins-build-update-repo.c:70
msgid "A one-line comment for this repository"
msgstr ""

#: app/flatpak-builtins-build-update-repo.c:70
#: app/flatpak-builtins-remote-add.c:78 app/flatpak-builtins-remote-modify.c:83
msgid "COMMENT"
msgstr "COMENTARI"

#: app/flatpak-builtins-build-update-repo.c:71
msgid "A full-paragraph description for this repository"
msgstr ""

#: app/flatpak-builtins-build-update-repo.c:71
#: app/flatpak-builtins-remote-add.c:79 app/flatpak-builtins-remote-modify.c:84
msgid "DESCRIPTION"
msgstr "DESCRIPTION"

#: app/flatpak-builtins-build-update-repo.c:72
msgid "URL for a website for this repository"
msgstr ""

#: app/flatpak-builtins-build-update-repo.c:73
msgid "URL for an icon for this repository"
msgstr ""

#: app/flatpak-builtins-build-update-repo.c:74
msgid "Default branch to use for this repository"
msgstr ""

#: app/flatpak-builtins-build-update-repo.c:74
#: app/flatpak-builtins-remote-add.c:82 app/flatpak-builtins-remote-modify.c:87
#: app/flatpak-builtins-repo.c:713 app/flatpak-builtins-repo.c:714
#: app/flatpak-builtins-run.c:161
msgid "BRANCH"
msgstr "BRANCA"

#: app/flatpak-builtins-build-update-repo.c:75
#: app/flatpak-builtins-remote-add.c:83 app/flatpak-builtins-remote-modify.c:88
msgid "COLLECTION-ID"
msgstr ""

#. Translators: A sideload is when you install from a local USB drive rather than the Internet.
#: app/flatpak-builtins-build-update-repo.c:77
msgid ""
"Permanently deploy collection ID to client remote configurations, only for "
"sideload support"
msgstr ""

#: app/flatpak-builtins-build-update-repo.c:78
msgid "Permanently deploy collection ID to client remote configurations"
msgstr ""

#: app/flatpak-builtins-build-update-repo.c:79
msgid "Name of authenticator for this repository"
msgstr ""

#: app/flatpak-builtins-build-update-repo.c:80
msgid "Autoinstall authenticator for this repository"
msgstr ""

#: app/flatpak-builtins-build-update-repo.c:81
msgid "Don't autoinstall authenticator for this repository"
msgstr ""

#: app/flatpak-builtins-build-update-repo.c:82
#: app/flatpak-builtins-remote-add.c:89
msgid "Authenticator option"
msgstr ""

#: app/flatpak-builtins-build-update-repo.c:82
#: app/flatpak-builtins-remote-add.c:89 app/flatpak-builtins-remote-modify.c:95
msgid "KEY=VALUE"
msgstr "CLAU=VALOR"

#: app/flatpak-builtins-build-update-repo.c:83
msgid "Import new default GPG public key from FILE"
msgstr ""

#: app/flatpak-builtins-build-update-repo.c:84
msgid "GPG Key ID to sign the summary with"
msgstr ""

#: app/flatpak-builtins-build-update-repo.c:86
msgid "Generate delta files"
msgstr ""

#: app/flatpak-builtins-build-update-repo.c:88
msgid "Don't update the appstream branch"
msgstr ""

#: app/flatpak-builtins-build-update-repo.c:89
msgid "Max parallel jobs when creating deltas (default: NUMCPUs)"
msgstr ""

#: app/flatpak-builtins-build-update-repo.c:89
msgid "NUM-JOBS"
msgstr ""

#: app/flatpak-builtins-build-update-repo.c:90
msgid "Don't create deltas matching refs"
msgstr ""

#: app/flatpak-builtins-build-update-repo.c:91
msgid "Prune unused objects"
msgstr ""

#: app/flatpak-builtins-build-update-repo.c:92
msgid "Prune but don't actually remove anything"
msgstr ""

#: app/flatpak-builtins-build-update-repo.c:93
msgid "Only traverse DEPTH parents for each commit (default: -1=infinite)"
msgstr ""

#: app/flatpak-builtins-build-update-repo.c:93
msgid "DEPTH"
msgstr ""

#: app/flatpak-builtins-build-update-repo.c:223
#, c-format
msgid "Generating delta: %s (%.10s)\n"
msgstr ""

#: app/flatpak-builtins-build-update-repo.c:225
#, c-format
msgid "Generating delta: %s (%.10s-%.10s)\n"
msgstr ""

#: app/flatpak-builtins-build-update-repo.c:233
#, c-format
msgid "Failed to generate delta %s (%.10s): "
msgstr ""

#: app/flatpak-builtins-build-update-repo.c:236
#, c-format
msgid "Failed to generate delta %s (%.10s-%.10s): "
msgstr ""

#: app/flatpak-builtins-build-update-repo.c:492
msgid "LOCATION - Update repository metadata"
msgstr ""

#: app/flatpak-builtins-build-update-repo.c:609
#, c-format
msgid "Updating appstream branch\n"
msgstr ""

#: app/flatpak-builtins-build-update-repo.c:638
#, c-format
msgid "Updating summary\n"
msgstr ""

#: app/flatpak-builtins-build-update-repo.c:664
#, c-format
msgid "Total objects: %u\n"
msgstr ""

#: app/flatpak-builtins-build-update-repo.c:666
#, c-format
msgid "No unreachable objects\n"
msgstr ""

#: app/flatpak-builtins-build-update-repo.c:668
#, c-format
msgid "Deleted %u objects, %s freed\n"
msgstr ""

#: app/flatpak-builtins-config.c:41
msgid "List configuration keys and values"
msgstr ""

#: app/flatpak-builtins-config.c:42
msgid "Get configuration for KEY"
msgstr ""

#: app/flatpak-builtins-config.c:43
msgid "Set configuration for KEY to VALUE"
msgstr ""

#: app/flatpak-builtins-config.c:44
msgid "Unset configuration for KEY"
msgstr ""

#: app/flatpak-builtins-config.c:149
#, c-format
msgid "'%s' does not look like a language/locale code"
msgstr ""

#: app/flatpak-builtins-config.c:172
#, c-format
msgid "'%s' does not look like a language code"
msgstr ""

#: app/flatpak-builtins-config.c:190
#, fuzzy, c-format
msgid "'%s' is not a valid value (use 'true' or 'false')"
msgstr "« %s » es pas un repertòri valid : "

#: app/flatpak-builtins-config.c:262
#, c-format
msgid "Unknown configure key '%s'"
msgstr ""

#: app/flatpak-builtins-config.c:284
msgid "Too many arguments for --list"
msgstr ""

#: app/flatpak-builtins-config.c:314 app/flatpak-builtins-config.c:362
msgid "You must specify KEY"
msgstr ""

#: app/flatpak-builtins-config.c:316
msgid "Too many arguments for --get"
msgstr ""

#: app/flatpak-builtins-config.c:338
msgid "You must specify KEY and VALUE"
msgstr ""

#: app/flatpak-builtins-config.c:340
msgid "Too many arguments for --set"
msgstr ""

#: app/flatpak-builtins-config.c:364
msgid "Too many arguments for --unset"
msgstr ""

#: app/flatpak-builtins-config.c:383
msgid "[KEY [VALUE]] - Manage configuration"
msgstr ""

#: app/flatpak-builtins-config.c:394
msgid "Can only use one of --list, --get, --set or --unset"
msgstr ""

#: app/flatpak-builtins-config.c:408
msgid "Must specify one of --list, --get, --set or --unset"
msgstr ""

#: app/flatpak-builtins-create-usb.c:45 app/flatpak-builtins-install.c:75
#: app/flatpak-builtins-remote-info.c:57 app/flatpak-builtins-uninstall.c:59
#: app/flatpak-builtins-update.c:65
msgid "Look for app with the specified name"
msgstr ""

#: app/flatpak-builtins-create-usb.c:46
msgid "Arch to copy"
msgstr ""

#: app/flatpak-builtins-create-usb.c:47
msgid "DEST"
msgstr "DEST"

#: app/flatpak-builtins-create-usb.c:49
msgid "Allow partial commits in the created repo"
msgstr ""

#: app/flatpak-builtins-create-usb.c:125 app/flatpak-builtins-create-usb.c:165
#, c-format
msgid ""
"Warning: Related ref ‘%s’ is partially installed. Use --allow-partial to "
"suppress this message.\n"
msgstr ""

#: app/flatpak-builtins-create-usb.c:158
#, c-format
msgid "Warning: Omitting related ref ‘%s’ because it is not installed.\n"
msgstr ""

#: app/flatpak-builtins-create-usb.c:175
#, c-format
msgid ""
"Warning: Omitting related ref ‘%s’ because its remote ‘%s’ does not have a "
"collection ID set.\n"
msgstr ""

#: app/flatpak-builtins-create-usb.c:187
#, c-format
msgid "Warning: Omitting related ref ‘%s’ because it's extra-data.\n"
msgstr ""

#: app/flatpak-builtins-create-usb.c:262 app/flatpak-builtins-create-usb.c:637
#, c-format
msgid ""
"Remote ‘%s’ does not have a collection ID set, which is required for P2P "
"distribution of ‘%s’."
msgstr ""

#: app/flatpak-builtins-create-usb.c:272
#, c-format
msgid "Warning: Omitting ref ‘%s’ (runtime of ‘%s’) because it's extra-data.\n"
msgstr ""

#: app/flatpak-builtins-create-usb.c:484
msgid "MOUNT-PATH [REF…] - Copy apps or runtimes onto removable media"
msgstr ""

#: app/flatpak-builtins-create-usb.c:493
msgid "MOUNT-PATH and REF must be specified"
msgstr ""

#: app/flatpak-builtins-create-usb.c:607
#, c-format
msgid "Ref ‘%s’ found in multiple installations: %s. You must specify one."
msgstr ""

#: app/flatpak-builtins-create-usb.c:620
#, c-format
msgid "Refs must all be in the same installation (found in %s and %s)."
msgstr ""

#: app/flatpak-builtins-create-usb.c:670
#, c-format
msgid ""
"Warning: Ref ‘%s’ is partially installed. Use --allow-partial to suppress "
"this message.\n"
msgstr ""

#: app/flatpak-builtins-create-usb.c:681
#, c-format
msgid "Installed ref ‘%s’ is extra-data, and cannot be distributed offline"
msgstr ""

#: app/flatpak-builtins-create-usb.c:721
#, c-format
msgid "Warning: Couldn't update repo metadata for remote ‘%s’: %s\n"
msgstr ""

#: app/flatpak-builtins-create-usb.c:751
#, c-format
msgid "Warning: Couldn't update appstream data for remote ‘%s’ arch ‘%s’: %s\n"
msgstr ""

#. Print a warning if both appstream and appstream2 are missing
#: app/flatpak-builtins-create-usb.c:784
#, c-format
msgid ""
"Warning: Couldn't find appstream data for remote ‘%s’ arch ‘%s’: %s; %s\n"
msgstr ""

#. Appstream2 is only for efficiency, so just print a debug message
#: app/flatpak-builtins-create-usb.c:790
#, c-format
msgid "Couldn't find appstream2 data for remote ‘%s’ arch ‘%s’: %s\n"
msgstr ""

#: app/flatpak-builtins-document-export.c:62
msgid "Create a unique document reference"
msgstr ""

#: app/flatpak-builtins-document-export.c:63
msgid "Make the document transient for the current session"
msgstr ""

#: app/flatpak-builtins-document-export.c:64
msgid "Don't require the file to exist already"
msgstr ""

#: app/flatpak-builtins-document-export.c:65
msgid "Give the app read permissions"
msgstr ""

#: app/flatpak-builtins-document-export.c:66
msgid "Give the app write permissions"
msgstr ""

#: app/flatpak-builtins-document-export.c:67
msgid "Give the app delete permissions"
msgstr ""

#: app/flatpak-builtins-document-export.c:68
msgid "Give the app permissions to grant further permissions"
msgstr ""

#: app/flatpak-builtins-document-export.c:69
msgid "Revoke read permissions of the app"
msgstr ""

#: app/flatpak-builtins-document-export.c:70
msgid "Revoke write permissions of the app"
msgstr ""

#: app/flatpak-builtins-document-export.c:71
msgid "Revoke delete permissions of the app"
msgstr ""

#: app/flatpak-builtins-document-export.c:72
msgid "Revoke the permission to grant further permissions"
msgstr ""

#: app/flatpak-builtins-document-export.c:73
msgid "Add permissions for this app"
msgstr ""

#: app/flatpak-builtins-document-export.c:73
msgid "APPID"
msgstr "APPID"

#: app/flatpak-builtins-document-export.c:100
msgid "FILE - Export a file to apps"
msgstr ""

#: app/flatpak-builtins-document-export.c:109
#: app/flatpak-builtins-document-info.c:72
#: app/flatpak-builtins-document-unexport.c:67
msgid "FILE must be specified"
msgstr ""

#: app/flatpak-builtins-document-info.c:63
msgid "FILE - Get information about an exported file"
msgstr ""

#: app/flatpak-builtins-document-info.c:100
#: app/flatpak-builtins-document-unexport.c:94
#, c-format
msgid "Not exported\n"
msgstr ""

#: app/flatpak-builtins-document-list.c:43 app/flatpak-builtins-history.c:53
#: app/flatpak-builtins-list.c:54 app/flatpak-builtins-ps.c:43
#: app/flatpak-builtins-remote-list.c:45 app/flatpak-builtins-remote-ls.c:59
#: app/flatpak-builtins-search.c:38
msgid "What information to show"
msgstr ""

#: app/flatpak-builtins-document-list.c:43 app/flatpak-builtins-history.c:53
#: app/flatpak-builtins-list.c:54 app/flatpak-builtins-ps.c:43
#: app/flatpak-builtins-remote-list.c:45 app/flatpak-builtins-remote-ls.c:59
#: app/flatpak-builtins-search.c:38
msgid "FIELD,…"
msgstr ""

#: app/flatpak-builtins-document-list.c:44 app/flatpak-builtins-history.c:54
#: app/flatpak-builtins-list.c:52 app/flatpak-builtins-permission-list.c:43
#: app/flatpak-builtins-permission-show.c:43 app/flatpak-builtins-ps.c:44
#: app/flatpak-builtins-remote-list.c:46 app/flatpak-builtins-remote-ls.c:63
#: app/flatpak-builtins-repo.c:717 app/flatpak-builtins-search.c:39
#, fuzzy
msgid "Show output in JSON format"
msgstr "Aficha las opcions de l'ajuda"

#: app/flatpak-builtins-document-list.c:49
msgid "Show the document ID"
msgstr ""

#: app/flatpak-builtins-document-list.c:50
msgid "Path"
msgstr "Emplaçament"

#: app/flatpak-builtins-document-list.c:50
#: app/flatpak-builtins-document-list.c:51
msgid "Show the document path"
msgstr ""

#: app/flatpak-builtins-document-list.c:51 app/flatpak-builtins-list.c:66
#: app/flatpak-builtins-remote-ls.c:74
msgid "Origin"
msgstr "Origina"

#: app/flatpak-builtins-document-list.c:52 app/flatpak-builtins-history.c:62
#: app/flatpak-builtins-ps.c:52
msgid "Application"
msgstr "Aplicacion"

#: app/flatpak-builtins-document-list.c:52
msgid "Show applications with permission"
msgstr ""

#: app/flatpak-builtins-document-list.c:53
#: app/flatpak-builtins-permission-list.c:182
#: app/flatpak-builtins-permission-show.c:145
msgid "Permissions"
msgstr "Permissions"

#: app/flatpak-builtins-document-list.c:53
msgid "Show permissions for applications"
msgstr ""

#: app/flatpak-builtins-document-list.c:161
#, fuzzy, c-format
msgid "No documents found\n"
msgstr "Cap de correspondéncia pas trobada"

#: app/flatpak-builtins-document-list.c:180
msgid "[APPID] - List exported files"
msgstr ""

#: app/flatpak-builtins-document-unexport.c:43
msgid "Specify the document ID"
msgstr ""

#: app/flatpak-builtins-document-unexport.c:58
msgid "FILE - Unexport a file to apps"
msgstr ""

#: app/flatpak-builtins-enter.c:88
msgid "INSTANCE COMMAND [ARGUMENT…] - Run a command inside a running sandbox"
msgstr ""

#: app/flatpak-builtins-enter.c:111
msgid "INSTANCE and COMMAND must be specified"
msgstr ""

#: app/flatpak-builtins-enter.c:138
#, c-format
msgid "%s is neither a pid nor an application or instance ID"
msgstr ""

#: app/flatpak-builtins-enter.c:144
msgid "entering not supported (need unprivileged user namespaces, or sudo -E)"
msgstr ""

#: app/flatpak-builtins-enter.c:145
#, c-format
msgid "No such pid %s"
msgstr ""

#: app/flatpak-builtins-enter.c:158
msgid "Can't read cwd"
msgstr ""

#: app/flatpak-builtins-enter.c:163
msgid "Can't read root"
msgstr ""

#: app/flatpak-builtins-enter.c:191
#, c-format
msgid "Invalid %s namespace for pid %d"
msgstr ""

#: app/flatpak-builtins-enter.c:202
#, c-format
msgid "Invalid %s namespace for self"
msgstr ""

#: app/flatpak-builtins-enter.c:216
#, c-format
msgid "Can't open %s namespace: %s"
msgstr ""

#: app/flatpak-builtins-enter.c:226
msgid "entering not supported (need unprivileged user namespaces)"
msgstr ""

#: app/flatpak-builtins-enter.c:227
#, c-format
msgid "Can't enter %s namespace: %s"
msgstr ""

#: app/flatpak-builtins-enter.c:234
msgid "Can't chdir"
msgstr ""

#: app/flatpak-builtins-enter.c:237
msgid "Can't chroot"
msgstr ""

#: app/flatpak-builtins-enter.c:240
msgid "Can't switch gid"
msgstr ""

#: app/flatpak-builtins-enter.c:243
msgid "Can't switch uid"
msgstr ""

#: app/flatpak-builtins-history.c:50
msgid "Only show changes after TIME"
msgstr ""

#: app/flatpak-builtins-history.c:50 app/flatpak-builtins-history.c:51
msgid "TIME"
msgstr "ORA"

#: app/flatpak-builtins-history.c:51
msgid "Only show changes before TIME"
msgstr ""

#: app/flatpak-builtins-history.c:52
msgid "Show newest entries first"
msgstr ""

#: app/flatpak-builtins-history.c:59
msgid "Time"
msgstr "Ora"

#: app/flatpak-builtins-history.c:59
msgid "Show when the change happened"
msgstr ""

#: app/flatpak-builtins-history.c:60
msgid "Change"
msgstr "Cambiar"

#: app/flatpak-builtins-history.c:60
msgid "Show the kind of change"
msgstr ""

#: app/flatpak-builtins-history.c:61 app/flatpak-builtins-list.c:68
#: app/flatpak-builtins-remote-ls.c:75 app/flatpak-builtins-repo.c:335
msgid "Ref"
msgstr ""

#: app/flatpak-builtins-history.c:61 app/flatpak-builtins-list.c:68
#: app/flatpak-builtins-remote-ls.c:75
msgid "Show the ref"
msgstr ""

#: app/flatpak-builtins-history.c:62
msgid "Show the application/runtime ID"
msgstr ""

#: app/flatpak-builtins-history.c:63 app/flatpak-builtins-list.c:64
#: app/flatpak-builtins-ps.c:53 app/flatpak-builtins-remote-ls.c:73
#: app/flatpak-cli-transaction.c:1435
msgid "Arch"
msgstr ""

#: app/flatpak-builtins-history.c:63 app/flatpak-builtins-list.c:64
#: app/flatpak-builtins-ps.c:53 app/flatpak-builtins-remote-ls.c:73
msgid "Show the architecture"
msgstr ""

#: app/flatpak-builtins-history.c:64 app/flatpak-builtins-list.c:63
#: app/flatpak-builtins-ps.c:54 app/flatpak-builtins-remote-ls.c:72
#: app/flatpak-builtins-search.c:48 app/flatpak-cli-transaction.c:1438
msgid "Branch"
msgstr "Branca"

#: app/flatpak-builtins-history.c:64 app/flatpak-builtins-list.c:63
#: app/flatpak-builtins-remote-ls.c:72
msgid "Show the branch"
msgstr ""

#: app/flatpak-builtins-history.c:65 app/flatpak-builtins-list.c:67
msgid "Installation"
msgstr "Installacion"

#: app/flatpak-builtins-history.c:65
msgid "Show the affected installation"
msgstr ""

#: app/flatpak-builtins-history.c:66 app/flatpak-cli-transaction.c:1452
msgid "Remote"
msgstr "Distant"

#: app/flatpak-builtins-history.c:66
msgid "Show the remote"
msgstr ""

#: app/flatpak-builtins-history.c:67 app/flatpak-builtins-ps.c:55
#: app/flatpak-builtins-remote-ls.c:76
msgid "Commit"
msgstr "Commit"

#: app/flatpak-builtins-history.c:67
msgid "Show the current commit"
msgstr ""

#: app/flatpak-builtins-history.c:68
msgid "Old Commit"
msgstr ""

#: app/flatpak-builtins-history.c:68
msgid "Show the previous commit"
msgstr ""

#: app/flatpak-builtins-history.c:69
msgid "Show the remote URL"
msgstr ""

#: app/flatpak-builtins-history.c:70 app/flatpak-cli-transaction.c:700
msgid "User"
msgstr "Utilizaire"

#: app/flatpak-builtins-history.c:70
msgid "Show the user doing the change"
msgstr ""

#: app/flatpak-builtins-history.c:71
msgid "Tool"
msgstr "Aisina"

#: app/flatpak-builtins-history.c:71
msgid "Show the tool that was used"
msgstr ""

#: app/flatpak-builtins-history.c:72 app/flatpak-builtins-list.c:62
#: app/flatpak-builtins-remote-ls.c:71 app/flatpak-builtins-search.c:47
msgid "Version"
msgstr "Version"

#: app/flatpak-builtins-history.c:72
msgid "Show the Flatpak version"
msgstr ""

#: app/flatpak-builtins-history.c:91
#, c-format
msgid "Failed to get journal data (%s): %s"
msgstr ""

#: app/flatpak-builtins-history.c:146
#, c-format
msgid "Failed to open journal: %s"
msgstr ""

#: app/flatpak-builtins-history.c:153
#, c-format
msgid "Failed to add match to journal: %s"
msgstr ""

#: app/flatpak-builtins-history.c:471
msgid " - Show history"
msgstr " - Mostrar l’istoric"

#: app/flatpak-builtins-history.c:490
#, c-format
msgid "Failed to parse the --since option"
msgstr ""

#: app/flatpak-builtins-history.c:501
#, c-format
msgid "Failed to parse the --until option"
msgstr ""

#: app/flatpak-builtins-info.c:56
msgid "Show user installations"
msgstr "Mostrar las installacions utilizaire"

#: app/flatpak-builtins-info.c:57
msgid "Show system-wide installations"
msgstr "Mostrar las installacions per tot lo sistèma"

#: app/flatpak-builtins-info.c:58
msgid "Show specific system-wide installations"
msgstr ""

#: app/flatpak-builtins-info.c:59 app/flatpak-builtins-remote-info.c:59
msgid "Show ref"
msgstr "Mostrar la referéncia"

#: app/flatpak-builtins-info.c:60 app/flatpak-builtins-remote-info.c:60
msgid "Show commit"
msgstr ""

#: app/flatpak-builtins-info.c:61
msgid "Show origin"
msgstr "Mostrar l’origina"

#: app/flatpak-builtins-info.c:62
msgid "Show size"
msgstr "Afichar la talha"

#: app/flatpak-builtins-info.c:63 app/flatpak-builtins-remote-info.c:62
msgid "Show metadata"
msgstr "Mostrar las metadonadas"

#: app/flatpak-builtins-info.c:64 app/flatpak-builtins-remote-info.c:63
msgid "Show runtime"
msgstr ""

#: app/flatpak-builtins-info.c:65 app/flatpak-builtins-remote-info.c:64
msgid "Show sdk"
msgstr ""

#: app/flatpak-builtins-info.c:66
msgid "Show permissions"
msgstr "Mostrar las permissions"

#: app/flatpak-builtins-info.c:67
msgid "Query file access"
msgstr ""

#: app/flatpak-builtins-info.c:67 app/flatpak-builtins-install.c:82
#: app/flatpak-builtins-install.c:88 app/flatpak-builtins-preinstall.c:68
#: app/flatpak-builtins-run.c:182 app/flatpak-builtins-run.c:184
#: app/flatpak-builtins-update.c:67 app/flatpak-builtins-update.c:71
msgid "PATH"
msgstr ""

#: app/flatpak-builtins-info.c:68
msgid "Show extensions"
msgstr "Mostrar las extensions"

#: app/flatpak-builtins-info.c:69
msgid "Show location"
msgstr "Mostrar l’emplaçament"

#: app/flatpak-builtins-info.c:116
msgid "NAME [BRANCH] - Get info about an installed app or runtime"
msgstr ""

#: app/flatpak-builtins-info.c:123 app/flatpak-builtins-remote-add.c:317
#: app/flatpak-builtins-remote-delete.c:63
msgid "NAME must be specified"
msgstr ""

#: app/flatpak-builtins-info.c:196
msgid "ref not present in origin"
msgstr ""

#: app/flatpak-builtins-info.c:211 app/flatpak-builtins-remote-info.c:217
#, c-format
msgid "Warning: Commit has no flatpak metadata\n"
msgstr ""

#: app/flatpak-builtins-info.c:217 app/flatpak-builtins-info.c:259
#: app/flatpak-builtins-info.c:455 app/flatpak-builtins-info.c:513
#: app/flatpak-builtins-remote-info.c:236
#: app/flatpak-builtins-remote-info.c:271
msgid "ID:"
msgstr "Identificant :"

#: app/flatpak-builtins-info.c:218 app/flatpak-builtins-info.c:260
#: app/flatpak-builtins-remote-info.c:237
#: app/flatpak-builtins-remote-info.c:272
msgid "Ref:"
msgstr "Referéncia :"

#: app/flatpak-builtins-info.c:219 app/flatpak-builtins-info.c:261
#: app/flatpak-builtins-remote-info.c:238
#: app/flatpak-builtins-remote-info.c:273
msgid "Arch:"
msgstr "Arquitectura :"

#: app/flatpak-builtins-info.c:220 app/flatpak-builtins-info.c:262
#: app/flatpak-builtins-remote-info.c:239
#: app/flatpak-builtins-remote-info.c:274
msgid "Branch:"
msgstr "Branca :"

#: app/flatpak-builtins-info.c:222 app/flatpak-builtins-info.c:264
#: app/flatpak-builtins-remote-info.c:241
#: app/flatpak-builtins-remote-info.c:276
msgid "Version:"
msgstr "Version :"

#: app/flatpak-builtins-info.c:224 app/flatpak-builtins-info.c:266
#: app/flatpak-builtins-remote-info.c:243
#: app/flatpak-builtins-remote-info.c:278
msgid "License:"
msgstr "Licéncia :"

#: app/flatpak-builtins-info.c:226 app/flatpak-builtins-info.c:269
#: app/flatpak-builtins-remote-info.c:245
#: app/flatpak-builtins-remote-info.c:280
msgid "Collection:"
msgstr "Colleccion :"

#: app/flatpak-builtins-info.c:227 app/flatpak-builtins-info.c:270
#: app/flatpak-builtins-info.c:458 app/flatpak-builtins-info.c:516
msgid "Installation:"
msgstr "Installacion :"

#: app/flatpak-builtins-info.c:228 app/flatpak-builtins-info.c:271
#: app/flatpak-builtins-info.c:459 app/flatpak-builtins-info.c:517
#: app/flatpak-builtins-remote-info.c:249
#: app/flatpak-builtins-remote-info.c:284
#, fuzzy
msgid "Installed Size:"
msgstr "Talha installada"

#: app/flatpak-builtins-info.c:231 app/flatpak-builtins-info.c:279
#: app/flatpak-builtins-remote-info.c:252
#: app/flatpak-builtins-remote-info.c:288
msgid "Runtime:"
msgstr "Environament d’execucion :"

#: app/flatpak-builtins-info.c:232 app/flatpak-builtins-info.c:288
#: app/flatpak-builtins-remote-info.c:253
#: app/flatpak-builtins-remote-info.c:293
msgid "Sdk:"
msgstr ""

#: app/flatpak-builtins-info.c:235 app/flatpak-builtins-info.c:313
#: app/flatpak-builtins-remote-info.c:256
#: app/flatpak-builtins-remote-info.c:319
msgid "Date:"
msgstr "Data :"

#: app/flatpak-builtins-info.c:237 app/flatpak-builtins-info.c:311
#: app/flatpak-builtins-remote-info.c:258
#: app/flatpak-builtins-remote-info.c:317
msgid "Subject:"
msgstr "Subjècte :"

#: app/flatpak-builtins-info.c:240 app/flatpak-builtins-info.c:295
msgid "Active commit:"
msgstr ""

#: app/flatpak-builtins-info.c:241 app/flatpak-builtins-info.c:298
msgid "Latest commit:"
msgstr ""

#: app/flatpak-builtins-info.c:244 app/flatpak-builtins-info.c:303
#: app/flatpak-builtins-info.c:457 app/flatpak-builtins-info.c:515
#: app/flatpak-builtins-remote-info.c:259
#: app/flatpak-builtins-remote-info.c:298
msgid "Commit:"
msgstr "Commit :"

#: app/flatpak-builtins-info.c:246 app/flatpak-builtins-info.c:308
#: app/flatpak-builtins-remote-info.c:261
#: app/flatpak-builtins-remote-info.c:303
msgid "Parent:"
msgstr "Parent :"

#: app/flatpak-builtins-info.c:248 app/flatpak-builtins-info.c:321
msgid "Alt-id:"
msgstr ""

#: app/flatpak-builtins-info.c:250 app/flatpak-builtins-info.c:325
#: app/flatpak-builtins-remote-info.c:263
#: app/flatpak-builtins-remote-info.c:308
msgid "End-of-life:"
msgstr "Fin de vida :"

#: app/flatpak-builtins-info.c:252 app/flatpak-builtins-info.c:330
#: app/flatpak-builtins-remote-info.c:265
#: app/flatpak-builtins-remote-info.c:313
msgid "End-of-life-rebase:"
msgstr ""

#: app/flatpak-builtins-info.c:254 app/flatpak-builtins-info.c:317
msgid "Subdirectories:"
msgstr ""

#: app/flatpak-builtins-info.c:255 app/flatpak-builtins-info.c:454
#: app/flatpak-builtins-info.c:512
msgid "Extension:"
msgstr "Extension :"

#: app/flatpak-builtins-info.c:267 app/flatpak-builtins-info.c:456
#: app/flatpak-builtins-info.c:514
msgid "Origin:"
msgstr "Origina :"

#: app/flatpak-builtins-info.c:460 app/flatpak-builtins-info.c:522
msgid "Subpaths:"
msgstr ""

#: app/flatpak-builtins-info.c:478
msgid "unmaintained"
msgstr ""

#: app/flatpak-builtins-info.c:480 app/flatpak-builtins-info.c:482
msgid "unknown"
msgstr "desconegut"

#: app/flatpak-builtins-install.c:68 app/flatpak-builtins-preinstall.c:57
msgid "Don't pull, only install from local cache"
msgstr ""

#: app/flatpak-builtins-install.c:69 app/flatpak-builtins-preinstall.c:58
#: app/flatpak-builtins-update.c:60
msgid "Don't deploy, only download to local cache"
msgstr ""

#: app/flatpak-builtins-install.c:70 app/flatpak-builtins-preinstall.c:59
msgid "Don't install related refs"
msgstr ""

#: app/flatpak-builtins-install.c:71 app/flatpak-builtins-preinstall.c:60
#: app/flatpak-builtins-update.c:62
msgid "Don't verify/install runtime dependencies"
msgstr ""

#: app/flatpak-builtins-install.c:72
msgid "Don't automatically pin explicit installs"
msgstr ""

#: app/flatpak-builtins-install.c:73 app/flatpak-builtins-preinstall.c:61
#: app/flatpak-builtins-update.c:63
msgid "Don't use static deltas"
msgstr ""

#: app/flatpak-builtins-install.c:76 app/flatpak-builtins-preinstall.c:62
msgid "Additionally install the SDK used to build the given refs"
msgstr ""

#: app/flatpak-builtins-install.c:77 app/flatpak-builtins-preinstall.c:63
msgid ""
"Additionally install the debug info for the given refs and their dependencies"
msgstr ""

#: app/flatpak-builtins-install.c:78
msgid "Assume LOCATION is a .flatpak single-file bundle"
msgstr ""

#: app/flatpak-builtins-install.c:79
msgid "Assume LOCATION is a .flatpakref application description"
msgstr ""

#: app/flatpak-builtins-install.c:80
msgid "Assume LOCATION is containers-transports(5) reference to an OCI image"
msgstr ""

#: app/flatpak-builtins-install.c:81
msgid "Check bundle signatures with GPG key from FILE (- for stdin)"
msgstr ""

#: app/flatpak-builtins-install.c:82
msgid "Only install this subpath"
msgstr ""

#: app/flatpak-builtins-install.c:83 app/flatpak-builtins-preinstall.c:64
#: app/flatpak-builtins-uninstall.c:63 app/flatpak-builtins-update.c:68
msgid "Automatically answer yes for all questions"
msgstr ""

#: app/flatpak-builtins-install.c:84 app/flatpak-builtins-preinstall.c:65
msgid "Uninstall first if already installed"
msgstr ""

#: app/flatpak-builtins-install.c:85 app/flatpak-builtins-preinstall.c:66
#: app/flatpak-builtins-uninstall.c:64 app/flatpak-builtins-update.c:69
msgid "Produce minimal output and don't ask questions"
msgstr ""

#: app/flatpak-builtins-install.c:86
msgid "Update install if already installed"
msgstr ""

#. Translators: A sideload is when you install from a local USB drive rather than the Internet.
#: app/flatpak-builtins-install.c:88 app/flatpak-builtins-preinstall.c:68
#: app/flatpak-builtins-update.c:71
msgid "Use this local repo for sideloads"
msgstr ""

#: app/flatpak-builtins-install.c:178
msgid "Bundle filename must be specified"
msgstr ""

#: app/flatpak-builtins-install.c:188
msgid "Remote bundles are not supported"
msgstr ""

#: app/flatpak-builtins-install.c:231
msgid "Filename or uri must be specified"
msgstr ""

#: app/flatpak-builtins-install.c:295
msgid "Image location must be specified"
msgstr ""

#: app/flatpak-builtins-install.c:345
msgid "[LOCATION/REMOTE] [REF…] - Install applications or runtimes"
msgstr ""

#: app/flatpak-builtins-install.c:378
msgid "At least one REF must be specified"
msgstr ""

#: app/flatpak-builtins-install.c:392
#, c-format
msgid "Looking for matches…\n"
msgstr "Recèrca de correspondéncias…\n"

#: app/flatpak-builtins-install.c:513
#, c-format
msgid "No remote refs found for ‘%s’"
msgstr ""

#: app/flatpak-builtins-install.c:573 app/flatpak-builtins-uninstall.c:405
#: common/flatpak-ref-utils.c:689 common/flatpak-ref-utils.c:1595
#, c-format
msgid "Invalid branch %s: %s"
msgstr "Branca invalida %s: %s"

#: app/flatpak-builtins-install.c:606
#, c-format
msgid "Nothing matches %s in local repository for remote %s"
msgstr ""

#: app/flatpak-builtins-install.c:608
#, c-format
msgid "Nothing matches %s in remote %s"
msgstr ""

#: app/flatpak-builtins-install.c:629
#, c-format
msgid "Skipping: %s\n"
msgstr "Passant : %s\n"

#: app/flatpak-builtins-kill.c:110
#, c-format
msgid "%s is not running"
msgstr "%s es pas en execucion"

#: app/flatpak-builtins-kill.c:136
msgid "INSTANCE - Stop a running application"
msgstr ""

#: app/flatpak-builtins-kill.c:144 app/flatpak-builtins-ps.c:256
msgid "Extra arguments given"
msgstr ""

#: app/flatpak-builtins-kill.c:150
msgid "Must specify the app to kill"
msgstr ""

#: app/flatpak-builtins-list.c:47
msgid "Show extra information"
msgstr "Aficha las opcions de l'ajuda"

#: app/flatpak-builtins-list.c:48
msgid "List installed runtimes"
msgstr ""

#: app/flatpak-builtins-list.c:49
msgid "List installed applications"
msgstr ""

#: app/flatpak-builtins-list.c:50
msgid "Arch to show"
msgstr ""

#: app/flatpak-builtins-list.c:51 app/flatpak-builtins-remote-ls.c:57
msgid "List all refs (including locale/debug)"
msgstr ""

#: app/flatpak-builtins-list.c:53 app/flatpak-builtins-remote-ls.c:58
msgid "List all applications using RUNTIME"
msgstr ""

#: app/flatpak-builtins-list.c:59 app/flatpak-builtins-remote-list.c:51
#: app/flatpak-builtins-remote-ls.c:68 app/flatpak-builtins-search.c:44
msgid "Name"
msgstr "Nom"

#: app/flatpak-builtins-list.c:59 app/flatpak-builtins-remote-list.c:51
#: app/flatpak-builtins-remote-ls.c:68 app/flatpak-builtins-search.c:44
msgid "Show the name"
msgstr "Afichar lo nom"

#: app/flatpak-builtins-list.c:60 app/flatpak-builtins-remote-list.c:60
#: app/flatpak-builtins-remote-ls.c:69 app/flatpak-builtins-search.c:45
msgid "Description"
msgstr "Descripcion"

#: app/flatpak-builtins-list.c:60 app/flatpak-builtins-remote-ls.c:69
#: app/flatpak-builtins-search.c:45
msgid "Show the description"
msgstr "Afichar la descripcion"

#: app/flatpak-builtins-list.c:61 app/flatpak-builtins-remote-ls.c:70
#: app/flatpak-builtins-search.c:46
msgid "Application ID"
msgstr "ID de l'aplicacion"

#: app/flatpak-builtins-list.c:61 app/flatpak-builtins-ps.c:52
#: app/flatpak-builtins-remote-ls.c:70 app/flatpak-builtins-search.c:46
msgid "Show the application ID"
msgstr "Afichar l’ID de l’aplicacion"

#: app/flatpak-builtins-list.c:62 app/flatpak-builtins-remote-ls.c:71
#: app/flatpak-builtins-search.c:47
msgid "Show the version"
msgstr "Afichar la version"

#: app/flatpak-builtins-list.c:65 app/flatpak-builtins-ps.c:56
#: app/flatpak-builtins-remote-ls.c:77
msgid "Runtime"
msgstr "Environament d’execucion"

#: app/flatpak-builtins-list.c:65
msgid "Show the used runtime"
msgstr ""

#: app/flatpak-builtins-list.c:66 app/flatpak-builtins-remote-ls.c:74
msgid "Show the origin remote"
msgstr ""

#: app/flatpak-builtins-list.c:67
msgid "Show the installation"
msgstr "Afichar l’installacion"

#: app/flatpak-builtins-list.c:69
msgid "Active commit"
msgstr "Commit actiu"

#: app/flatpak-builtins-list.c:69 app/flatpak-builtins-remote-ls.c:76
msgid "Show the active commit"
msgstr ""

#: app/flatpak-builtins-list.c:70
msgid "Latest commit"
msgstr "Darrièr commit"

#: app/flatpak-builtins-list.c:70
msgid "Show the latest commit"
msgstr ""

#: app/flatpak-builtins-list.c:71 app/flatpak-builtins-remote-ls.c:78
msgid "Installed size"
msgstr "Talha installada"

#: app/flatpak-builtins-list.c:71 app/flatpak-builtins-remote-ls.c:78
msgid "Show the installed size"
msgstr ""

#: app/flatpak-builtins-list.c:72 app/flatpak-builtins-remote-list.c:58
#: app/flatpak-builtins-remote-ls.c:80 app/flatpak-builtins-repo.c:340
msgid "Options"
msgstr "Opcions"

#: app/flatpak-builtins-list.c:72 app/flatpak-builtins-remote-list.c:58
#: app/flatpak-builtins-remote-ls.c:80
msgid "Show options"
msgstr "Afichar las opcions"

#: app/flatpak-builtins-list.c:180
#, fuzzy, c-format
msgid "Unable to load details of %s: %s"
msgstr "Unable to load metadata from remote %s: %s"

#: app/flatpak-builtins-list.c:190
#, fuzzy, c-format
msgid "Unable to inspect current version of %s: %s"
msgstr "Unable to load metadata from remote %s: %s"

#: app/flatpak-builtins-list.c:408
msgid " - List installed apps and/or runtimes"
msgstr ""

#: app/flatpak-builtins-make-current.c:38
msgid "Arch to make current for"
msgstr ""

#: app/flatpak-builtins-make-current.c:58
msgid "APP BRANCH - Make branch of application current"
msgstr ""

#: app/flatpak-builtins-make-current.c:69 app/flatpak-builtins-run.c:260
msgid "APP must be specified"
msgstr ""

#: app/flatpak-builtins-make-current.c:84
msgid "BRANCH must be specified"
msgstr ""

#: app/flatpak-builtins-make-current.c:97
#, c-format
msgid "App %s branch %s is not installed"
msgstr ""

#: app/flatpak-builtins-mask.c:42
msgid "Remove matching masks"
msgstr ""

#: app/flatpak-builtins-mask.c:54
msgid ""
"[PATTERN…] - disable updates and automatic installation matching patterns"
msgstr ""

#: app/flatpak-builtins-mask.c:73
#, c-format
msgid "No masked patterns\n"
msgstr ""

#: app/flatpak-builtins-mask.c:78
#, c-format
msgid "Masked patterns:\n"
msgstr ""

#: app/flatpak-builtins-override.c:42
msgid "Remove existing overrides"
msgstr ""

#: app/flatpak-builtins-override.c:43
msgid "Show existing overrides"
msgstr ""

#: app/flatpak-builtins-override.c:59
msgid "[APP] - Override settings [for application]"
msgstr ""

#: app/flatpak-builtins-permission-list.c:143
msgid "[TABLE] [ID] - List permissions"
msgstr ""

#: app/flatpak-builtins-permission-list.c:179
#: app/flatpak-builtins-permission-show.c:142
msgid "Table"
msgstr "Tablèu"

#: app/flatpak-builtins-permission-list.c:180
#: app/flatpak-builtins-permission-show.c:143
msgid "Object"
msgstr "Objècte"

#: app/flatpak-builtins-permission-list.c:181
#: app/flatpak-builtins-permission-show.c:144
msgid "App"
msgstr ""

#: app/flatpak-builtins-permission-list.c:183
#: app/flatpak-builtins-permission-show.c:146
msgid "Data"
msgstr "Donadas"

#: app/flatpak-builtins-permission-remove.c:120
msgid "TABLE ID [APP_ID] - Remove item from permission store"
msgstr ""

#: app/flatpak-builtins-permission-remove.c:129
#: app/flatpak-builtins-permission-set.c:120
msgid "Too few arguments"
msgstr ""

#: app/flatpak-builtins-permission-reset.c:43
msgid "Reset all permissions"
msgstr ""

#: app/flatpak-builtins-permission-reset.c:144
msgid "APP_ID - Reset permissions for an app"
msgstr ""

#: app/flatpak-builtins-permission-reset.c:153
#: app/flatpak-builtins-permission-show.c:124
msgid "Wrong number of arguments"
msgstr "Nombre d'arguments incorrècte"

#: app/flatpak-builtins-permission-set.c:42
msgid "Associate DATA with the entry"
msgstr ""

#: app/flatpak-builtins-permission-set.c:42
msgid "DATA"
msgstr ""

#: app/flatpak-builtins-permission-set.c:111
msgid "TABLE ID APP_ID [PERMISSION...] - Set permissions"
msgstr ""

#: app/flatpak-builtins-permission-set.c:132
#, c-format
msgid "Failed to parse '%s' as GVariant: "
msgstr ""

#: app/flatpak-builtins-permission-show.c:115
msgid "APP_ID - Show permissions for an app"
msgstr ""

#: app/flatpak-builtins-pin.c:44
msgid "Remove matching pins"
msgstr ""

#: app/flatpak-builtins-pin.c:56
msgid "[PATTERN…] - disable automatic removal of runtimes matching patterns"
msgstr ""

#: app/flatpak-builtins-pin.c:75
#, c-format
msgid "No pinned patterns\n"
msgstr ""

#: app/flatpak-builtins-pin.c:80
#, c-format
msgid "Pinned patterns:\n"
msgstr ""

#: app/flatpak-builtins-preinstall.c:80
msgid "- Install flatpaks that are part of the operating system"
msgstr ""

#: app/flatpak-builtins-preinstall.c:118
#, c-format
msgid "Nothing to do.\n"
msgstr "Pas res a far.\n"

#: app/flatpak-builtins-ps.c:49
msgid "Instance"
msgstr "Instància"

#: app/flatpak-builtins-ps.c:49
msgid "Show the instance ID"
msgstr ""

#: app/flatpak-builtins-ps.c:50 app/flatpak-builtins-run.c:178
msgid "PID"
msgstr "PID"

#: app/flatpak-builtins-ps.c:50
msgid "Show the PID of the wrapper process"
msgstr ""

#: app/flatpak-builtins-ps.c:51
msgid "Child-PID"
msgstr ""

#: app/flatpak-builtins-ps.c:51
msgid "Show the PID of the sandbox process"
msgstr ""

#: app/flatpak-builtins-ps.c:54 app/flatpak-builtins-search.c:48
msgid "Show the application branch"
msgstr ""

#: app/flatpak-builtins-ps.c:55
msgid "Show the application commit"
msgstr ""

#: app/flatpak-builtins-ps.c:56
msgid "Show the runtime ID"
msgstr ""

#: app/flatpak-builtins-ps.c:57
msgid "R.-Branch"
msgstr ""

#: app/flatpak-builtins-ps.c:57
msgid "Show the runtime branch"
msgstr ""

#: app/flatpak-builtins-ps.c:58
msgid "R.-Commit"
msgstr ""

#: app/flatpak-builtins-ps.c:58
msgid "Show the runtime commit"
msgstr ""

#: app/flatpak-builtins-ps.c:59
msgid "Active"
msgstr "Actiu"

#: app/flatpak-builtins-ps.c:59
msgid "Show whether the app is active"
msgstr ""

#: app/flatpak-builtins-ps.c:60
msgid "Background"
msgstr "Rèireplan"

#: app/flatpak-builtins-ps.c:60
msgid "Show whether the app is background"
msgstr ""

#: app/flatpak-builtins-ps.c:246
msgid " - Enumerate running sandboxes"
msgstr ""

#: app/flatpak-builtins-remote-add.c:66
msgid "Do nothing if the provided remote exists"
msgstr ""

#: app/flatpak-builtins-remote-add.c:67
msgid "LOCATION specifies a configuration file, not the repo location"
msgstr ""

#: app/flatpak-builtins-remote-add.c:72 app/flatpak-builtins-remote-modify.c:78
msgid "Disable GPG verification"
msgstr ""

#: app/flatpak-builtins-remote-add.c:73 app/flatpak-builtins-remote-modify.c:79
msgid "Mark the remote as don't enumerate"
msgstr ""

#: app/flatpak-builtins-remote-add.c:74 app/flatpak-builtins-remote-modify.c:80
msgid "Mark the remote as don't use for deps"
msgstr ""

#: app/flatpak-builtins-remote-add.c:75 app/flatpak-builtins-remote-modify.c:81
msgid "Set priority (default 1, higher is more prioritized)"
msgstr ""

#: app/flatpak-builtins-remote-add.c:75 app/flatpak-builtins-remote-modify.c:81
msgid "PRIORITY"
msgstr "PRIORITAT"

#: app/flatpak-builtins-remote-add.c:76
msgid "The named subset to use for this remote"
msgstr ""

#: app/flatpak-builtins-remote-add.c:76 app/flatpak-builtins-remote-modify.c:71
msgid "SUBSET"
msgstr ""

#: app/flatpak-builtins-remote-add.c:77 app/flatpak-builtins-remote-modify.c:82
msgid "A nice name to use for this remote"
msgstr ""

#: app/flatpak-builtins-remote-add.c:78 app/flatpak-builtins-remote-modify.c:83
msgid "A one-line comment for this remote"
msgstr ""

#: app/flatpak-builtins-remote-add.c:79 app/flatpak-builtins-remote-modify.c:84
msgid "A full-paragraph description for this remote"
msgstr ""

#: app/flatpak-builtins-remote-add.c:80 app/flatpak-builtins-remote-modify.c:85
msgid "URL for a website for this remote"
msgstr ""

#: app/flatpak-builtins-remote-add.c:81 app/flatpak-builtins-remote-modify.c:86
msgid "URL for an icon for this remote"
msgstr ""

#: app/flatpak-builtins-remote-add.c:82 app/flatpak-builtins-remote-modify.c:87
msgid "Default branch to use for this remote"
msgstr ""

#: app/flatpak-builtins-remote-add.c:84 app/flatpak-builtins-remote-modify.c:89
msgid "Import GPG key from FILE (- for stdin)"
msgstr ""

#: app/flatpak-builtins-remote-add.c:85 app/flatpak-builtins-remote-modify.c:90
msgid "Load signatures from URL"
msgstr ""

#: app/flatpak-builtins-remote-add.c:86 app/flatpak-builtins-remote-modify.c:92
msgid "Set path to local filter FILE"
msgstr ""

#: app/flatpak-builtins-remote-add.c:87 app/flatpak-builtins-remote-modify.c:93
msgid "Disable the remote"
msgstr ""

#: app/flatpak-builtins-remote-add.c:88 app/flatpak-builtins-remote-modify.c:94
msgid "Name of authenticator"
msgstr ""

#: app/flatpak-builtins-remote-add.c:90 app/flatpak-builtins-remote-modify.c:96
msgid "Autoinstall authenticator"
msgstr ""

#: app/flatpak-builtins-remote-add.c:91 app/flatpak-builtins-remote-modify.c:97
msgid "Don't autoinstall authenticator"
msgstr ""

#: app/flatpak-builtins-remote-add.c:92 app/flatpak-builtins-remote-modify.c:99
msgid "Don't follow the redirect set in the summary file"
msgstr ""

#: app/flatpak-builtins-remote-add.c:261 app/flatpak-builtins-remote-add.c:268
#, c-format
msgid "Can't load uri %s: %s\n"
msgstr ""

#: app/flatpak-builtins-remote-add.c:276 common/flatpak-dir.c:4643
#, c-format
msgid "Can't load file %s: %s\n"
msgstr ""

#: app/flatpak-builtins-remote-add.c:304
msgid "NAME LOCATION - Add a remote repository"
msgstr ""

#: app/flatpak-builtins-remote-add.c:331
msgid "GPG verification is required if collections are enabled"
msgstr ""

#: app/flatpak-builtins-remote-add.c:393
#, c-format
msgid "Remote %s already exists"
msgstr ""

#: app/flatpak-builtins-remote-add.c:405
#: app/flatpak-builtins-remote-modify.c:340
#, c-format
msgid "Invalid authenticator name %s"
msgstr ""

#: app/flatpak-builtins-remote-add.c:422
#, c-format
msgid "Warning: Could not update extra metadata for '%s': %s\n"
msgstr ""

#: app/flatpak-builtins-remote-delete.c:39
msgid "Remove remote even if in use"
msgstr ""

#: app/flatpak-builtins-remote-delete.c:53
msgid "NAME - Delete a remote repository"
msgstr ""

#: app/flatpak-builtins-remote-delete.c:100
#, c-format
msgid "The following refs are installed from remote '%s':"
msgstr ""

#: app/flatpak-builtins-remote-delete.c:101
msgid "Remove them?"
msgstr ""

#: app/flatpak-builtins-remote-delete.c:103
#, c-format
msgid "Can't remove remote '%s' with installed refs"
msgstr ""

#: app/flatpak-builtins-remote-info.c:55
msgid "Commit to show info for"
msgstr ""

#: app/flatpak-builtins-remote-info.c:58
msgid "Display log"
msgstr ""

#: app/flatpak-builtins-remote-info.c:61
msgid "Show parent"
msgstr "Mostrar lo parent"

#: app/flatpak-builtins-remote-info.c:65 app/flatpak-builtins-remote-ls.c:60
msgid "Use local caches even if they are stale"
msgstr ""

#. Translators: A sideload is when you install from a local USB drive rather than the Internet.
#: app/flatpak-builtins-remote-info.c:67 app/flatpak-builtins-remote-ls.c:62
msgid "Only list refs available as sideloads"
msgstr ""

#: app/flatpak-builtins-remote-info.c:114
msgid ""
" REMOTE REF - Show information about an application or runtime in a remote"
msgstr ""

#: app/flatpak-builtins-remote-info.c:125
msgid "REMOTE and REF must be specified"
msgstr ""

#: app/flatpak-builtins-remote-info.c:247
#: app/flatpak-builtins-remote-info.c:282
#, fuzzy
msgid "Download Size:"
msgstr "Talha del telecargament"

#: app/flatpak-builtins-remote-info.c:267
#: app/flatpak-builtins-remote-info.c:325
msgid "History:"
msgstr "Istoric :"

#: app/flatpak-builtins-remote-info.c:348
msgid " Commit:"
msgstr ""

#: app/flatpak-builtins-remote-info.c:349
msgid " Subject:"
msgstr " Subjècte :"

#: app/flatpak-builtins-remote-info.c:350
msgid " Date:"
msgstr " Data :"

#: app/flatpak-builtins-remote-info.c:383
#, c-format
msgid "Warning: Commit %s has no flatpak metadata\n"
msgstr ""

#: app/flatpak-builtins-remote-list.c:43
msgid "Show remote details"
msgstr ""

#: app/flatpak-builtins-remote-list.c:44
msgid "Show disabled remotes"
msgstr ""

#: app/flatpak-builtins-remote-list.c:52
msgid "Title"
msgstr "Títol"

#: app/flatpak-builtins-remote-list.c:52
msgid "Show the title"
msgstr "Mostrar lo títol"

#: app/flatpak-builtins-remote-list.c:53
msgid "Show the URL"
msgstr "Mostrar l’URL"

#: app/flatpak-builtins-remote-list.c:54
msgid "Show the collection ID"
msgstr "Mostrar l’ID de la colleccion"

#: app/flatpak-builtins-remote-list.c:55 app/flatpak-builtins-repo.c:392
msgid "Subset"
msgstr ""

#: app/flatpak-builtins-remote-list.c:55
msgid "Show the subset"
msgstr ""

#: app/flatpak-builtins-remote-list.c:56
msgid "Filter"
msgstr "Filtre"

#: app/flatpak-builtins-remote-list.c:56
msgid "Show filter file"
msgstr ""

#: app/flatpak-builtins-remote-list.c:57
msgid "Priority"
msgstr "Prioritat"

#: app/flatpak-builtins-remote-list.c:57
msgid "Show the priority"
msgstr "Mostrar la prioritat"

#: app/flatpak-builtins-remote-list.c:59
msgid "Comment"
msgstr "Comentari"

#: app/flatpak-builtins-remote-list.c:59
msgid "Show comment"
msgstr "Mostrar lo comentari"

#: app/flatpak-builtins-remote-list.c:60
msgid "Show description"
msgstr "Mostrar la descripcion"

#: app/flatpak-builtins-remote-list.c:61
msgid "Homepage"
msgstr "Pagina d’acuèlh"

#: app/flatpak-builtins-remote-list.c:61
msgid "Show homepage"
msgstr "Mostrar la pagina d'acuèlh"

#: app/flatpak-builtins-remote-list.c:62
msgid "Icon"
msgstr "Icòna"

#: app/flatpak-builtins-remote-list.c:62
msgid "Show icon"
msgstr "Afichar l'icòna"

#: app/flatpak-builtins-remote-list.c:231
msgid " - List remote repositories"
msgstr ""

#: app/flatpak-builtins-remote-ls.c:52
msgid "Show arches and branches"
msgstr ""

#: app/flatpak-builtins-remote-ls.c:53
msgid "Show only runtimes"
msgstr ""

#: app/flatpak-builtins-remote-ls.c:54
msgid "Show only apps"
msgstr ""

#: app/flatpak-builtins-remote-ls.c:55
msgid "Show only those where updates are available"
msgstr ""

#: app/flatpak-builtins-remote-ls.c:56
msgid "Limit to this arch (* for all)"
msgstr ""

#: app/flatpak-builtins-remote-ls.c:77
msgid "Show the runtime"
msgstr ""

#: app/flatpak-builtins-remote-ls.c:79
msgid "Download size"
msgstr "Talha del telecargament"

#: app/flatpak-builtins-remote-ls.c:79
msgid "Show the download size"
msgstr "Mostrar la talha de telecargament"

#: app/flatpak-builtins-remote-ls.c:391
msgid " [REMOTE or URI] - Show available runtimes and applications"
msgstr ""

#: app/flatpak-builtins-remote-modify.c:67
msgid "Enable GPG verification"
msgstr "Activar la verificacion GPG"

#: app/flatpak-builtins-remote-modify.c:68
msgid "Mark the remote as enumerate"
msgstr ""

#: app/flatpak-builtins-remote-modify.c:69
msgid "Mark the remote as used for dependencies"
msgstr ""

#: app/flatpak-builtins-remote-modify.c:70
#, fuzzy
msgid "Set a new URL"
msgstr "Definir una URL novèla"

#: app/flatpak-builtins-remote-modify.c:71
msgid "Set a new subset to use"
msgstr ""

#: app/flatpak-builtins-remote-modify.c:72
msgid "Enable the remote"
msgstr ""

#: app/flatpak-builtins-remote-modify.c:73
msgid "Update extra metadata from the summary file"
msgstr ""

#: app/flatpak-builtins-remote-modify.c:91
msgid "Disable local filter"
msgstr ""

#: app/flatpak-builtins-remote-modify.c:95
msgid "Authenticator options"
msgstr ""

#: app/flatpak-builtins-remote-modify.c:98
msgid "Follow the redirect set in the summary file"
msgstr ""

#: app/flatpak-builtins-remote-modify.c:306
msgid "NAME - Modify a remote repository"
msgstr ""

#: app/flatpak-builtins-remote-modify.c:316
msgid "Remote NAME must be specified"
msgstr ""

#: app/flatpak-builtins-remote-modify.c:327
#, c-format
msgid "Updating extra metadata from remote summary for %s\n"
msgstr ""

#: app/flatpak-builtins-remote-modify.c:330
#, c-format
msgid "Error updating extra metadata for '%s': %s\n"
msgstr ""

#: app/flatpak-builtins-remote-modify.c:331
#, c-format
msgid "Could not update extra metadata for %s"
msgstr ""

#: app/flatpak-builtins-repair.c:43
msgid "Don't make any changes"
msgstr ""

#: app/flatpak-builtins-repair.c:44
msgid "Reinstall all refs"
msgstr ""

#: app/flatpak-builtins-repair.c:68
#, c-format
msgid "Object missing: %s.%s\n"
msgstr ""

#: app/flatpak-builtins-repair.c:76
#, c-format
msgid "Object invalid: %s.%s\n"
msgstr ""

#: app/flatpak-builtins-repair.c:81
#, c-format
msgid "%s, deleting object\n"
msgstr ""

#: app/flatpak-builtins-repair.c:146
#, c-format
msgid "Can't load object %s: %s\n"
msgstr ""

#: app/flatpak-builtins-repair.c:228
#, c-format
msgid "Commit invalid %s: %s\n"
msgstr ""

#: app/flatpak-builtins-repair.c:231
#, c-format
msgid "Deleting invalid commit %s: %s\n"
msgstr ""

#: app/flatpak-builtins-repair.c:261
#, c-format
msgid "Commit should be marked partial: %s\n"
msgstr ""

#: app/flatpak-builtins-repair.c:264
#, c-format
msgid "Marking commit as partial: %s\n"
msgstr ""

#: app/flatpak-builtins-repair.c:293
#, c-format
msgid "Problems loading data for %s: %s\n"
msgstr ""

#: app/flatpak-builtins-repair.c:306
#, c-format
msgid "Error reinstalling %s: %s\n"
msgstr ""

#: app/flatpak-builtins-repair.c:327
msgid "- Repair a flatpak installation"
msgstr ""

#: app/flatpak-builtins-repair.c:406
#, c-format
msgid "Removing non-deployed ref %s…\n"
msgstr ""

#: app/flatpak-builtins-repair.c:411
#, c-format
msgid "Skipping non-deployed ref %s…\n"
msgstr ""

#: app/flatpak-builtins-repair.c:429
#, c-format
msgid "[%d/%d] Verifying %s…\n"
msgstr ""

#: app/flatpak-builtins-repair.c:435
#, c-format
msgid "Dry run: "
msgstr ""

#: app/flatpak-builtins-repair.c:440
#, c-format
msgid "Deleting ref %s due to missing objects\n"
msgstr ""

#: app/flatpak-builtins-repair.c:444
#, c-format
msgid "Deleting ref %s due to invalid objects\n"
msgstr ""

#: app/flatpak-builtins-repair.c:448
#, c-format
msgid "Deleting ref %s due to %d\n"
msgstr ""

#: app/flatpak-builtins-repair.c:464
#, c-format
msgid "Checking remotes...\n"
msgstr ""

#: app/flatpak-builtins-repair.c:482
#, c-format
msgid "Remote %s for ref %s is missing\n"
msgstr ""

#: app/flatpak-builtins-repair.c:484
#, c-format
msgid "Remote %s for ref %s is disabled\n"
msgstr ""

#: app/flatpak-builtins-repair.c:490
#, c-format
msgid "Pruning objects\n"
msgstr ""

#: app/flatpak-builtins-repair.c:498
#, c-format
msgid "Erasing .removed\n"
msgstr ""

#: app/flatpak-builtins-repair.c:524
#, c-format
msgid "Reinstalling refs\n"
msgstr ""

#: app/flatpak-builtins-repair.c:526
#, c-format
msgid "Reinstalling removed refs\n"
msgstr ""

#: app/flatpak-builtins-repair.c:551
#, c-format
msgid "While removing appstream for %s: "
msgstr ""

#: app/flatpak-builtins-repair.c:558
#, c-format
msgid "While deploying appstream for %s: "
msgstr ""

#: app/flatpak-builtins-repo.c:106
#, c-format
msgid "Repo mode: %s\n"
msgstr ""

#: app/flatpak-builtins-repo.c:113
#, c-format
msgid "Indexed summaries: %s\n"
msgstr ""

#: app/flatpak-builtins-repo.c:113 app/flatpak-builtins-repo.c:139
#: app/flatpak-builtins-repo.c:172
msgid "true"
msgstr "true"

#: app/flatpak-builtins-repo.c:113 app/flatpak-builtins-repo.c:139
#: app/flatpak-builtins-repo.c:172
msgid "false"
msgstr "false"

#: app/flatpak-builtins-repo.c:121
#, c-format
msgid "Subsummaries: "
msgstr ""

#: app/flatpak-builtins-repo.c:136
#, c-format
msgid "Cache version: %d\n"
msgstr ""

#: app/flatpak-builtins-repo.c:139
#, c-format
msgid "Indexed deltas: %s\n"
msgstr ""

#: app/flatpak-builtins-repo.c:142
#, c-format
msgid "Title: %s\n"
msgstr "Títol : %s\n"

#: app/flatpak-builtins-repo.c:145
#, c-format
msgid "Comment: %s\n"
msgstr "Comentari : %s\n"

#: app/flatpak-builtins-repo.c:148
#, c-format
msgid "Description: %s\n"
msgstr "Descripcion : %s\n"

#: app/flatpak-builtins-repo.c:151
#, c-format
msgid "Homepage: %s\n"
msgstr "Pagina d'acuèlh : %s\n"

#: app/flatpak-builtins-repo.c:154
#, c-format
msgid "Icon: %s\n"
msgstr "Icòna : %s\n"

#: app/flatpak-builtins-repo.c:157
#, c-format
msgid "Collection ID: %s\n"
msgstr ""

#: app/flatpak-builtins-repo.c:160
#, c-format
msgid "Default branch: %s\n"
msgstr ""

#: app/flatpak-builtins-repo.c:163
#, c-format
msgid "Redirect URL: %s\n"
msgstr ""

#: app/flatpak-builtins-repo.c:166
#, c-format
msgid "Deploy collection ID: %s\n"
msgstr ""

#: app/flatpak-builtins-repo.c:169
#, c-format
msgid "Authenticator name: %s\n"
msgstr ""

#: app/flatpak-builtins-repo.c:172
#, c-format
msgid "Authenticator install: %s\n"
msgstr ""

#: app/flatpak-builtins-repo.c:180
#, c-format
msgid "GPG key hash: %s\n"
msgstr ""

#: app/flatpak-builtins-repo.c:184
#, c-format
msgid "%zd summary branches\n"
msgstr ""

#: app/flatpak-builtins-repo.c:336
msgid "Installed"
msgstr "Installat"

#. Translators: Download is used here as a noun
#: app/flatpak-builtins-repo.c:338 app/flatpak-cli-transaction.c:1462
msgid "Download"
msgstr "Telecargar"

#: app/flatpak-builtins-repo.c:339
msgid "Subsets"
msgstr ""

#: app/flatpak-builtins-repo.c:393
msgid "Digest"
msgstr ""

#: app/flatpak-builtins-repo.c:394
msgid "History length"
msgstr ""

#: app/flatpak-builtins-repo.c:711
msgid "Print general information about the repository"
msgstr ""

#: app/flatpak-builtins-repo.c:712
msgid "List the branches in the repository"
msgstr ""

#: app/flatpak-builtins-repo.c:713
msgid "Print metadata for a branch"
msgstr ""

#: app/flatpak-builtins-repo.c:714
msgid "Show commits for a branch"
msgstr ""

#: app/flatpak-builtins-repo.c:715
msgid "Print information about the repo subsets"
msgstr ""

#: app/flatpak-builtins-repo.c:716
msgid "Limit information to subsets with this prefix"
msgstr ""

#: app/flatpak-builtins-repo.c:732
msgid "LOCATION - Repository maintenance"
msgstr ""

#: app/flatpak-builtins-run.c:159
msgid "Command to run"
msgstr ""

#: app/flatpak-builtins-run.c:160
msgid "Directory to run the command in"
msgstr ""

#: app/flatpak-builtins-run.c:161
msgid "Branch to use"
msgstr ""

#: app/flatpak-builtins-run.c:162
msgid "Use development runtime"
msgstr ""

#: app/flatpak-builtins-run.c:163
msgid "Runtime to use"
msgstr ""

#: app/flatpak-builtins-run.c:164
msgid "Runtime version to use"
msgstr ""

#: app/flatpak-builtins-run.c:167
msgid "Log accessibility bus calls"
msgstr ""

#: app/flatpak-builtins-run.c:168
msgid "Don't proxy accessibility bus calls"
msgstr ""

#: app/flatpak-builtins-run.c:169
msgid "Proxy accessibility bus calls (default except when sandboxed)"
msgstr ""

#: app/flatpak-builtins-run.c:170
msgid "Don't proxy session bus calls"
msgstr ""

#: app/flatpak-builtins-run.c:171
msgid "Proxy session bus calls (default except when sandboxed)"
msgstr ""

#: app/flatpak-builtins-run.c:172
msgid "Don't start portals"
msgstr ""

#: app/flatpak-builtins-run.c:173
msgid "Enable file forwarding"
msgstr ""

#: app/flatpak-builtins-run.c:174
msgid "Run specified commit"
msgstr ""

#: app/flatpak-builtins-run.c:175
msgid "Use specified runtime commit"
msgstr ""

#: app/flatpak-builtins-run.c:176
msgid "Run completely sandboxed"
msgstr ""

#: app/flatpak-builtins-run.c:178
msgid "Use PID as parent pid for sharing namespaces"
msgstr ""

#: app/flatpak-builtins-run.c:179
msgid "Make processes visible in parent namespace"
msgstr ""

#: app/flatpak-builtins-run.c:180
msgid "Share process ID namespace with parent"
msgstr ""

#: app/flatpak-builtins-run.c:181
msgid "Write the instance ID to the given file descriptor"
msgstr ""

#: app/flatpak-builtins-run.c:182
msgid "Use PATH instead of the app's /app"
msgstr ""

#: app/flatpak-builtins-run.c:183
msgid "Use FD instead of the app's /app"
msgstr ""

#: app/flatpak-builtins-run.c:183 app/flatpak-builtins-run.c:185
#: app/flatpak-builtins-run.c:187 app/flatpak-builtins-run.c:188
#: common/flatpak-context.c:2672
msgid "FD"
msgstr ""

#: app/flatpak-builtins-run.c:184
msgid "Use PATH instead of the runtime's /usr"
msgstr ""

#: app/flatpak-builtins-run.c:185
msgid "Use FD instead of the runtime's /usr"
msgstr ""

#: app/flatpak-builtins-run.c:186
msgid "Clear all outside environment variables"
msgstr ""

#: app/flatpak-builtins-run.c:187
msgid ""
"Bind mount the file or directory referred to by FD to its canonicalized path"
msgstr ""

#: app/flatpak-builtins-run.c:188
msgid ""
"Bind mount the file or directory referred to by FD read-only to its "
"canonicalized path"
msgstr ""

#: app/flatpak-builtins-run.c:219
msgid "APP [ARGUMENT…] - Run an app"
msgstr ""

#: app/flatpak-builtins-run.c:370
#, c-format
msgid "runtime/%s/%s/%s not installed"
msgstr ""

#: app/flatpak-builtins-run.c:419
msgid "app-fd and app-path cannot both be used"
msgstr ""

#: app/flatpak-builtins-run.c:449
msgid "usr-fd and usr-path cannot both be used"
msgstr ""

#: app/flatpak-builtins-search.c:37
msgid "Arch to search for"
msgstr ""

#: app/flatpak-builtins-search.c:49
msgid "Remotes"
msgstr "Distants"

#: app/flatpak-builtins-search.c:49
msgid "Show the remotes"
msgstr ""

#: app/flatpak-builtins-search.c:244
msgid "TEXT - Search remote apps/runtimes for text"
msgstr ""

#: app/flatpak-builtins-search.c:255
msgid "TEXT must be specified"
msgstr ""

#: app/flatpak-builtins-search.c:338
msgid "No matches found"
msgstr "Cap de correspondéncia pas trobada"

#: app/flatpak-builtins-uninstall.c:54
msgid "Arch to uninstall"
msgstr ""

#: app/flatpak-builtins-uninstall.c:55
msgid "Keep ref in local repository"
msgstr ""

#: app/flatpak-builtins-uninstall.c:56
msgid "Don't uninstall related refs"
msgstr ""

#: app/flatpak-builtins-uninstall.c:57
msgid "Remove files even if running"
msgstr ""

#: app/flatpak-builtins-uninstall.c:60
msgid "Uninstall all"
msgstr "Tot desinstallar"

#: app/flatpak-builtins-uninstall.c:61
msgid "Uninstall unused"
msgstr ""

#: app/flatpak-builtins-uninstall.c:62
msgid "Delete app data"
msgstr ""

#: app/flatpak-builtins-uninstall.c:141
#, c-format
msgid "Delete data for %s?"
msgstr ""

#: app/flatpak-builtins-uninstall.c:220
#, c-format
msgid "Info: applications using the extension %s%s%s branch %s%s%s:\n"
msgstr ""

#: app/flatpak-builtins-uninstall.c:223
#, c-format
msgid "Info: applications using the runtime %s%s%s branch %s%s%s:\n"
msgstr ""

#: app/flatpak-builtins-uninstall.c:238
msgid "Really remove?"
msgstr "Suprimir vertadièrament ?"

#: app/flatpak-builtins-uninstall.c:255
msgid "[REF…] - Uninstall applications or runtimes"
msgstr ""

#: app/flatpak-builtins-uninstall.c:264
msgid "Must specify at least one REF, --unused, --all or --delete-data"
msgstr ""

#: app/flatpak-builtins-uninstall.c:267
msgid "Must not specify REFs when using --all"
msgstr ""

#: app/flatpak-builtins-uninstall.c:270
msgid "Must not specify REFs when using --unused"
msgstr ""

#: app/flatpak-builtins-uninstall.c:336
#, c-format
msgid ""
"\n"
"These runtimes in installation '%s' are pinned and won't be removed; see "
"flatpak-pin(1):\n"
msgstr ""

#: app/flatpak-builtins-uninstall.c:370
#, c-format
msgid "Nothing unused to uninstall\n"
msgstr ""

#: app/flatpak-builtins-uninstall.c:444
#, c-format
msgid "No installed refs found for ‘%s’"
msgstr ""

#: app/flatpak-builtins-uninstall.c:447
#, c-format
msgid " with arch ‘%s’"
msgstr ""

#: app/flatpak-builtins-uninstall.c:449
#, c-format
msgid " with branch ‘%s’"
msgstr ""

#: app/flatpak-builtins-uninstall.c:456
#, c-format
msgid "Warning: %s is not installed\n"
msgstr ""

#: app/flatpak-builtins-uninstall.c:490
#, c-format
msgid "None of the specified refs are installed"
msgstr ""

#: app/flatpak-builtins-uninstall.c:599
#, c-format
msgid "No app data to delete\n"
msgstr ""

#: app/flatpak-builtins-update.c:56
msgid "Arch to update for"
msgstr ""

#: app/flatpak-builtins-update.c:57
msgid "Commit to deploy"
msgstr ""

#: app/flatpak-builtins-update.c:58
msgid "Remove old files even if running"
msgstr ""

#: app/flatpak-builtins-update.c:59
msgid "Don't pull, only update from local cache"
msgstr ""

#: app/flatpak-builtins-update.c:61
msgid "Don't update related refs"
msgstr ""

#: app/flatpak-builtins-update.c:66
msgid "Update appstream for remote"
msgstr ""

#: app/flatpak-builtins-update.c:67
msgid "Only update this subpath"
msgstr ""

#: app/flatpak-builtins-update.c:90
msgid "[REF…] - Update applications or runtimes"
msgstr ""

#: app/flatpak-builtins-update.c:121
msgid "With --commit, only one REF may be specified"
msgstr ""

#: app/flatpak-builtins-update.c:162
#, c-format
msgid "Looking for updates…\n"
msgstr "Recèrca de novèlas mesas a jorn…\n"

#: app/flatpak-builtins-update.c:215
#, c-format
msgid "Unable to update %s: %s\n"
msgstr ""

#: app/flatpak-builtins-update.c:274
#, fuzzy, c-format
msgid "Nothing to update.\n"
msgstr "Pas res a far.\n"

#: app/flatpak-builtins-utils.c:337
#, c-format
msgid ""
"Remote ‘%s’ found in multiple installations, unable to proceed in non-"
"interactive mode"
msgstr ""

#: app/flatpak-builtins-utils.c:346
#, c-format
msgid "Remote ‘%s’ found in multiple installations:"
msgstr ""

#: app/flatpak-builtins-utils.c:347 app/flatpak-builtins-utils.c:442
#: app/flatpak-builtins-utils.c:538 app/flatpak-builtins-utils.c:540
#: app/flatpak-builtins-utils.c:598
msgid "Which do you want to use (0 to abort)?"
msgstr "Quin volètz utilizar (0 per abandonar) ?"

#: app/flatpak-builtins-utils.c:349
#, c-format
msgid "No remote chosen to resolve ‘%s’ which exists in multiple installations"
msgstr ""

#: app/flatpak-builtins-utils.c:358
#, c-format
msgid ""
"Remote \"%s\" not found\n"
"Hint: Use flatpak remote-add to add a remote"
msgstr ""

#: app/flatpak-builtins-utils.c:364
#, c-format
msgid "Remote \"%s\" not found in the %s installation"
msgstr ""

#: app/flatpak-builtins-utils.c:404
#, c-format
msgid "Multiple refs match ‘%s’, unable to proceed in non-interactive mode"
msgstr ""

#. default to yes on Enter
#: app/flatpak-builtins-utils.c:430
#, c-format
msgid ""
"Found ref ‘%s’ in remote ‘%s’ (%s).\n"
"Use this ref?"
msgstr ""

#: app/flatpak-builtins-utils.c:434 app/flatpak-builtins-utils.c:444
#: app/flatpak-builtins-utils.c:522 app/flatpak-builtins-utils.c:543
#, c-format
msgid "No ref chosen to resolve matches for ‘%s’"
msgstr ""

#: app/flatpak-builtins-utils.c:440
#, c-format
msgid "Similar refs found for ‘%s’ in remote ‘%s’ (%s):"
msgstr ""

#: app/flatpak-builtins-utils.c:488
#, c-format
msgid ""
"Multiple installed refs match ‘%s’, unable to proceed in non-interactive mode"
msgstr ""

#. default to yes on Enter
#: app/flatpak-builtins-utils.c:518
#, c-format
msgid "Found installed ref ‘%s’ (%s). Is this correct?"
msgstr ""

#: app/flatpak-builtins-utils.c:534
#, c-format
msgid "All of the above"
msgstr ""

#: app/flatpak-builtins-utils.c:535
#, c-format
msgid "Similar installed refs found for ‘%s’:"
msgstr ""

#: app/flatpak-builtins-utils.c:579
#, c-format
msgid ""
"Multiple remotes have refs matching ‘%s’, unable to proceed in non-"
"interactive mode"
msgstr ""

#: app/flatpak-builtins-utils.c:597
#, c-format
msgid "Remotes found with refs similar to ‘%s’:"
msgstr ""

#: app/flatpak-builtins-utils.c:600
#, c-format
msgid "No remote chosen to resolve matches for ‘%s’"
msgstr ""

#: app/flatpak-builtins-utils.c:696 app/flatpak-builtins-utils.c:699
#, c-format
msgid "Updating appstream data for user remote %s"
msgstr ""

#: app/flatpak-builtins-utils.c:706 app/flatpak-builtins-utils.c:709
#, c-format
msgid "Updating appstream data for remote %s"
msgstr ""

#: app/flatpak-builtins-utils.c:717 app/flatpak-builtins-utils.c:719
msgid "Error updating"
msgstr "Error pendent la mesa a jorn"

#: app/flatpak-builtins-utils.c:755
#, c-format
msgid "Remote \"%s\" not found"
msgstr ""

#: app/flatpak-builtins-utils.c:796
#, c-format
msgid "Ambiguous suffix: '%s'."
msgstr ""

#. Translators: don't translate the values
#: app/flatpak-builtins-utils.c:798 app/flatpak-builtins-utils.c:813
msgid "Possible values are :s[tart], :m[iddle], :e[nd] or :f[ull]"
msgstr ""

#: app/flatpak-builtins-utils.c:811
#, c-format
msgid "Invalid suffix: '%s'."
msgstr ""

#: app/flatpak-builtins-utils.c:846
#, c-format
msgid "Ambiguous column: %s"
msgstr ""

#: app/flatpak-builtins-utils.c:859
#, c-format
msgid "Unknown column: %s"
msgstr ""

#: app/flatpak-builtins-utils.c:917
msgid "Available columns:\n"
msgstr "Colomnas disponiblas :\n"

#: app/flatpak-builtins-utils.c:927
msgid "Show all columns"
msgstr "Mostrar totas las colomnas"

#: app/flatpak-builtins-utils.c:928
msgid "Show available columns"
msgstr "Afichar las colomnas disponiblas"

#: app/flatpak-builtins-utils.c:931
msgid "Append :s[tart], :m[iddle], :e[nd] or :f[ull] to change ellipsization"
msgstr ""

#: app/flatpak-builtins-utils.c:1483
#, c-format
msgid "Unknown scheme in sideload location %s"
msgstr ""

#: app/flatpak-cli-transaction.c:96 app/flatpak-cli-transaction.c:102
#, c-format
msgid "Required runtime for %s (%s) found in remote %s\n"
msgstr ""

#: app/flatpak-cli-transaction.c:104
msgid "Do you want to install it?"
msgstr "Lo volètz vertadièrament installar ?"

#: app/flatpak-cli-transaction.c:110
#, c-format
msgid "Required runtime for %s (%s) found in remotes:"
msgstr ""

#: app/flatpak-cli-transaction.c:112
msgid "Which do you want to install (0 to abort)?"
msgstr ""

#: app/flatpak-cli-transaction.c:132
#, c-format
msgid "Configuring %s as new remote '%s'\n"
msgstr ""

#. default to yes on Enter
#: app/flatpak-cli-transaction.c:139
#, c-format
msgid ""
"The remote '%s', referred to by '%s' at location %s contains additional "
"applications.\n"
"Should the remote be kept for future installations?"
msgstr ""

#. default to yes on Enter
#: app/flatpak-cli-transaction.c:147
#, c-format
msgid ""
"The application %s depends on runtimes from:\n"
"  %s\n"
"Configure this as new remote '%s'"
msgstr ""

#. Formatted size/remaining time in seconds
#: app/flatpak-cli-transaction.c:321
#, c-format
msgid "%s/s%s%s"
msgstr ""

#. Download progress percentage, use the appropriate
#. percent format for your language
#: app/flatpak-cli-transaction.c:359
#, c-format
msgid "%3d%%"
msgstr ""

#: app/flatpak-cli-transaction.c:414
msgid "Installing…"
msgstr "Installacion…"

#: app/flatpak-cli-transaction.c:416
#, c-format
msgid "Installing %d/%d…"
msgstr "Installacion %d/%d…"

#: app/flatpak-cli-transaction.c:421
msgid "Updating…"
msgstr "Mesa a jorn…"

#: app/flatpak-cli-transaction.c:423
#, c-format
msgid "Updating %d/%d…"
msgstr "Mesa a jorn %d/%d…"

#: app/flatpak-cli-transaction.c:428
msgid "Uninstalling…"
msgstr "Desinstallacion…"

#: app/flatpak-cli-transaction.c:430
#, c-format
msgid "Uninstalling %d/%d…"
msgstr "Desinstallacion %d/%d…"

#: app/flatpak-cli-transaction.c:496 app/flatpak-quiet-transaction.c:161
#, c-format
msgid "Info: %s was skipped"
msgstr ""

#: app/flatpak-cli-transaction.c:519
#, c-format
msgid "Warning: %s%s%s already installed"
msgstr "Avertiment : %s%s%s ja installat"

#: app/flatpak-cli-transaction.c:522
#, c-format
msgid "Error: %s%s%s already installed"
msgstr "Error : %s%s%s ja installat"

#: app/flatpak-cli-transaction.c:528
#, c-format
msgid "Warning: %s%s%s not installed"
msgstr "Avertiment : %s%s%s es pas installat"

#: app/flatpak-cli-transaction.c:531
#, c-format
msgid "Error: %s%s%s not installed"
msgstr "Error : %s%s%s es pas installat"

#: app/flatpak-cli-transaction.c:537
#, c-format
msgid "Warning: %s%s%s needs a later flatpak version"
msgstr ""

#: app/flatpak-cli-transaction.c:540
#, c-format
msgid "Error: %s%s%s needs a later flatpak version"
msgstr ""

#: app/flatpak-cli-transaction.c:546
msgid "Warning: Not enough disk space to complete this operation"
msgstr "Avertiment : pas pro d’espaci disc per acabar aquesta operacion"

#: app/flatpak-cli-transaction.c:548
msgid "Error: Not enough disk space to complete this operation"
msgstr "Error : pas pro d’espaci disc per acabar aquesta operacion"

#: app/flatpak-cli-transaction.c:553
#, c-format
msgid "Warning: %s"
msgstr "Avertiment : %s"

#: app/flatpak-cli-transaction.c:555
#, c-format
msgid "Error: %s"
msgstr "Error : %s"

#: app/flatpak-cli-transaction.c:570
#, c-format
msgid "Failed to install %s%s%s: "
msgstr ""

#: app/flatpak-cli-transaction.c:577
#, c-format
msgid "Failed to update %s%s%s: "
msgstr ""

#: app/flatpak-cli-transaction.c:584
#, c-format
msgid "Failed to install bundle %s%s%s: "
msgstr ""

#: app/flatpak-cli-transaction.c:591
#, c-format
msgid "Failed to uninstall %s%s%s: "
msgstr ""

#: app/flatpak-cli-transaction.c:642
#, c-format
msgid "Authentication required for remote '%s'\n"
msgstr ""

#: app/flatpak-cli-transaction.c:643
msgid "Open browser?"
msgstr "Dobrir lo navegador ?"

#: app/flatpak-cli-transaction.c:699
#, c-format
msgid "Login required remote %s (realm %s)\n"
msgstr ""

#: app/flatpak-cli-transaction.c:704
msgid "Password"
msgstr "Senhal"

#. Only runtimes can be pinned
#: app/flatpak-cli-transaction.c:759
#, c-format
msgid ""
"\n"
"Info: (pinned) runtime %s%s%s branch %s%s%s is end-of-life, in favor of "
"%s%s%s branch %s%s%s\n"
msgstr ""

#: app/flatpak-cli-transaction.c:765
#, c-format
msgid ""
"\n"
"Info: runtime %s%s%s branch %s%s%s is end-of-life, in favor of %s%s%s branch "
"%s%s%s\n"
msgstr ""

#: app/flatpak-cli-transaction.c:768
#, c-format
msgid ""
"\n"
"Info: app %s%s%s branch %s%s%s is end-of-life, in favor of %s%s%s branch "
"%s%s%s\n"
msgstr ""

#. Only runtimes can be pinned
#: app/flatpak-cli-transaction.c:780
#, c-format
msgid ""
"\n"
"Info: (pinned) runtime %s%s%s branch %s%s%s is end-of-life, with reason:\n"
msgstr ""

#: app/flatpak-cli-transaction.c:786
#, c-format
msgid ""
"\n"
"Info: runtime %s%s%s branch %s%s%s is end-of-life, with reason:\n"
msgstr ""

#: app/flatpak-cli-transaction.c:789
#, c-format
msgid ""
"\n"
"Info: app %s%s%s branch %s%s%s is end-of-life, with reason:\n"
msgstr ""

#: app/flatpak-cli-transaction.c:963
#, c-format
msgid "Info: applications using this extension:\n"
msgstr ""

#: app/flatpak-cli-transaction.c:965
#, c-format
msgid "Info: applications using this runtime:\n"
msgstr ""

#: app/flatpak-cli-transaction.c:984
msgid "Replace?"
msgstr "Remplaçar ?"

#: app/flatpak-cli-transaction.c:987 app/flatpak-quiet-transaction.c:247
#, c-format
msgid "Updating to rebased version\n"
msgstr ""

#: app/flatpak-cli-transaction.c:1011
#, c-format
msgid "Failed to rebase %s to %s: "
msgstr ""

#: app/flatpak-cli-transaction.c:1277
#, c-format
msgid "New %s%s%s permissions:"
msgstr "Novèlas permissions %s%s%s :"

#: app/flatpak-cli-transaction.c:1279
#, c-format
msgid "%s%s%s permissions:"
msgstr "permissions %s%s%s :"

#: app/flatpak-cli-transaction.c:1343
msgid "Warning: "
msgstr "Avertiment : "

#. translators: This is short for operation, the title of a one-char column
#: app/flatpak-cli-transaction.c:1442
msgid "Op"
msgstr ""

#. Avoid resizing the download column too much,
#. * by making the title as long as typical content
#.
#: app/flatpak-cli-transaction.c:1458 app/flatpak-cli-transaction.c:1503
msgid "partial"
msgstr "parcial"

#: app/flatpak-cli-transaction.c:1535
msgid "Proceed with these changes to the user installation?"
msgstr ""
"Contunhar amb aquelas modificacions de l’installacion de l’utilizaire ?"

#: app/flatpak-cli-transaction.c:1537
msgid "Proceed with these changes to the system installation?"
msgstr ""

#: app/flatpak-cli-transaction.c:1539
#, c-format
msgid "Proceed with these changes to the %s?"
msgstr ""

#: app/flatpak-cli-transaction.c:1711
msgid "Changes complete."
msgstr "Modificacions realizadas."

#: app/flatpak-cli-transaction.c:1713
msgid "Uninstall complete."
msgstr "Desinstallacion efectuada."

#: app/flatpak-cli-transaction.c:1715
msgid "Installation complete."
msgstr "Installacion acabada."

#: app/flatpak-cli-transaction.c:1717
msgid "Updates complete."
msgstr "Mesas a jorn terminadas."

#. For updates/!stop_on_first_error we already printed all errors so we make up
#. a different one.
#: app/flatpak-cli-transaction.c:1750
msgid "There were one or more errors"
msgstr ""

#. translators: please keep the leading space
#: app/flatpak-main.c:76
msgid " Manage installed applications and runtimes"
msgstr ""

#: app/flatpak-main.c:77
msgid "Install an application or runtime"
msgstr ""

#: app/flatpak-main.c:78
msgid "Update an installed application or runtime"
msgstr ""

#: app/flatpak-main.c:81
msgid "Uninstall an installed application or runtime"
msgstr ""

#: app/flatpak-main.c:84
msgid "Mask out updates and automatic installation"
msgstr ""

#: app/flatpak-main.c:85
msgid "Pin a runtime to prevent automatic removal"
msgstr ""

#: app/flatpak-main.c:86
msgid "List installed apps and/or runtimes"
msgstr ""

#: app/flatpak-main.c:87
msgid "Show info for installed app or runtime"
msgstr ""

#: app/flatpak-main.c:88
msgid "Show history"
msgstr "Mostrar l’istoric"

#: app/flatpak-main.c:89
msgid "Configure flatpak"
msgstr "Configurar flatpak"

#: app/flatpak-main.c:90
msgid "Repair flatpak installation"
msgstr ""

#: app/flatpak-main.c:91
msgid "Put applications or runtimes onto removable media"
msgstr ""

#: app/flatpak-main.c:92
msgid "Install flatpaks that are part of the operating system"
msgstr ""

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:95
msgid ""
"\n"
" Find applications and runtimes"
msgstr ""

#: app/flatpak-main.c:96
msgid "Search for remote apps/runtimes"
msgstr ""

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:99
msgid ""
"\n"
" Manage running applications"
msgstr ""

#: app/flatpak-main.c:100
msgid "Run an application"
msgstr "Executar una aplicacion"

#: app/flatpak-main.c:101
msgid "Override permissions for an application"
msgstr ""

#: app/flatpak-main.c:102
msgid "Specify default version to run"
msgstr ""

#: app/flatpak-main.c:103
msgid "Enter the namespace of a running application"
msgstr ""

#: app/flatpak-main.c:104
msgid "Enumerate running applications"
msgstr ""

#: app/flatpak-main.c:105
msgid "Stop a running application"
msgstr ""

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:108
msgid ""
"\n"
" Manage file access"
msgstr ""

#: app/flatpak-main.c:109
msgid "List exported files"
msgstr ""

#: app/flatpak-main.c:110
msgid "Grant an application access to a specific file"
msgstr ""

#: app/flatpak-main.c:111
msgid "Revoke access to a specific file"
msgstr ""

#: app/flatpak-main.c:112
msgid "Show information about a specific file"
msgstr ""

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:116
msgid ""
"\n"
" Manage dynamic permissions"
msgstr ""

#: app/flatpak-main.c:117
msgid "List permissions"
msgstr "Listar las autorizacions"

#: app/flatpak-main.c:118
msgid "Remove item from permission store"
msgstr ""

#: app/flatpak-main.c:120
msgid "Set permissions"
msgstr "Definir las autorizacions"

#: app/flatpak-main.c:121
msgid "Show app permissions"
msgstr "Afichar las autorizacions de l’aplicacion"

#: app/flatpak-main.c:122
msgid "Reset app permissions"
msgstr "Reïnicializar las autorizacions de l’aplicacion"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:125
msgid ""
"\n"
" Manage remote repositories"
msgstr ""

#: app/flatpak-main.c:126
msgid "List all configured remotes"
msgstr ""

#: app/flatpak-main.c:127
msgid "Add a new remote repository (by URL)"
msgstr ""

#: app/flatpak-main.c:128
msgid "Modify properties of a configured remote"
msgstr ""

#: app/flatpak-main.c:129
msgid "Delete a configured remote"
msgstr ""

#: app/flatpak-main.c:131
msgid "List contents of a configured remote"
msgstr ""

#: app/flatpak-main.c:132
msgid "Show information about a remote app or runtime"
msgstr ""

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:135
msgid ""
"\n"
" Build applications"
msgstr ""
"\n"
"Construire las aplicacions"

#: app/flatpak-main.c:136
msgid "Initialize a directory for building"
msgstr ""

#: app/flatpak-main.c:137
msgid "Run a build command inside the build dir"
msgstr ""

#: app/flatpak-main.c:138
msgid "Finish a build dir for export"
msgstr ""

#: app/flatpak-main.c:139
msgid "Export a build dir to a repository"
msgstr ""

#: app/flatpak-main.c:140
msgid "Create a bundle file from a ref in a local repository"
msgstr ""

#: app/flatpak-main.c:141
msgid "Import a bundle file"
msgstr ""

#: app/flatpak-main.c:142
msgid "Sign an application or runtime"
msgstr ""

#: app/flatpak-main.c:143
msgid "Update the summary file in a repository"
msgstr ""

#: app/flatpak-main.c:144
msgid "Create new commit based on existing ref"
msgstr ""

#: app/flatpak-main.c:145
msgid "Show information about a repo"
msgstr ""

#: app/flatpak-main.c:162
msgid "Show debug information, -vv for more detail"
msgstr ""

#: app/flatpak-main.c:163
msgid "Show OSTree debug information"
msgstr ""

#: app/flatpak-main.c:169
msgid "Print version information and exit"
msgstr "Imprimir las informacions de version e quitar"

#: app/flatpak-main.c:170
msgid "Print default arch and exit"
msgstr ""

#: app/flatpak-main.c:171
msgid "Print supported arches and exit"
msgstr ""

#: app/flatpak-main.c:172
msgid "Print active gl drivers and exit"
msgstr ""

#: app/flatpak-main.c:173
msgid "Print paths for system installations and exit"
msgstr ""

#: app/flatpak-main.c:174
msgid "Print the updated environment needed to run flatpaks"
msgstr ""

#: app/flatpak-main.c:175
msgid "Only include the system installation with --print-updated-env"
msgstr ""

#: app/flatpak-main.c:180
msgid "Work on the user installation"
msgstr ""

#: app/flatpak-main.c:181
msgid "Work on the system-wide installation (default)"
msgstr ""

#: app/flatpak-main.c:182
msgid "Work on a non-default system-wide installation"
msgstr ""

#: app/flatpak-main.c:212
msgid "Builtin Commands:"
msgstr ""

#: app/flatpak-main.c:298
#, c-format
msgid ""
"Note that the directories %s are not in the search path set by the "
"XDG_DATA_DIRS environment variable, so applications installed by Flatpak may "
"not appear on your desktop until the session is restarted."
msgstr ""

#: app/flatpak-main.c:312
#, c-format
msgid ""
"Note that the directory %s is not in the search path set by the "
"XDG_DATA_DIRS environment variable, so applications installed by Flatpak may "
"not appear on your desktop until the session is restarted."
msgstr ""

#: app/flatpak-main.c:381
msgid ""
"Refusing to operate under sudo with --user. Omit sudo to operate on the user "
"installation, or use a root shell to operate on the root user's installation."
msgstr ""

#: app/flatpak-main.c:453
msgid ""
"Multiple installations specified for a command that works on one installation"
msgstr ""

#: app/flatpak-main.c:504 app/flatpak-main.c:697
#, c-format
msgid "See '%s --help'"
msgstr "Consultar « %s --help »"

#: app/flatpak-main.c:706
#, c-format
msgid "'%s' is not a flatpak command. Did you mean '%s%s'?"
msgstr "« %s » es pas una comanda flatpak. Voliatz dire « %s%s » ?"

#: app/flatpak-main.c:709
#, c-format
msgid "'%s' is not a flatpak command"
msgstr "« %s » es pas una comanda flatpak"

#: app/flatpak-main.c:824
msgid "No command specified"
msgstr "Cap de comanda es pas estada precisada"

#: app/flatpak-main.c:980
msgid "error:"
msgstr "error :"

#: app/flatpak-quiet-transaction.c:77
#, c-format
msgid "Installing %s\n"
msgstr "Installacion de %s\n"

#: app/flatpak-quiet-transaction.c:81
#, c-format
msgid "Updating %s\n"
msgstr "Actualizacion de %s\n"

#: app/flatpak-quiet-transaction.c:85
#, c-format
msgid "Uninstalling %s\n"
msgstr "Desinstallacion de %s\n"

#: app/flatpak-quiet-transaction.c:107
#, c-format
msgid "Warning: Failed to install %s: %s\n"
msgstr ""

#: app/flatpak-quiet-transaction.c:110
#, c-format
msgid "Error: Failed to install %s: %s\n"
msgstr ""

#: app/flatpak-quiet-transaction.c:116
#, c-format
msgid "Warning: Failed to update %s: %s\n"
msgstr ""

#: app/flatpak-quiet-transaction.c:119
#, c-format
msgid "Error: Failed to update %s: %s\n"
msgstr ""

#: app/flatpak-quiet-transaction.c:125
#, c-format
msgid "Warning: Failed to install bundle %s: %s\n"
msgstr ""

#: app/flatpak-quiet-transaction.c:128
#, c-format
msgid "Error: Failed to install bundle %s: %s\n"
msgstr ""

#: app/flatpak-quiet-transaction.c:134
#, c-format
msgid "Warning: Failed to uninstall %s: %s\n"
msgstr ""

#: app/flatpak-quiet-transaction.c:137
#, c-format
msgid "Error: Failed to uninstall %s: %s\n"
msgstr ""

#: app/flatpak-quiet-transaction.c:166 common/flatpak-dir.c:11475
#, c-format
msgid "%s already installed"
msgstr "%s ja installat"

#: app/flatpak-quiet-transaction.c:168 common/flatpak-dir.c:3622
#: common/flatpak-dir.c:4321 common/flatpak-dir.c:16968
#: common/flatpak-dir.c:17258 common/flatpak-dir-utils.c:166
#: common/flatpak-dir-utils.c:259 common/flatpak-transaction.c:2736
#: common/flatpak-transaction.c:2791
#, c-format
msgid "%s not installed"
msgstr "%s es pas installat"

#: app/flatpak-quiet-transaction.c:170
#, c-format
msgid "%s needs a later flatpak version"
msgstr ""

#: app/flatpak-quiet-transaction.c:172
msgid "Not enough disk space to complete this operation"
msgstr "Memòria insufisenta per acabar l'operacion"

#: app/flatpak-quiet-transaction.c:239
#, c-format
msgid "Info: %s is end-of-life, in favor of %s\n"
msgstr ""

#: app/flatpak-quiet-transaction.c:241
#, c-format
msgid "Info: %s is end-of-life, with reason: %s\n"
msgstr ""

#: app/flatpak-quiet-transaction.c:251
#, c-format
msgid "Failed to rebase %s to %s: %s\n"
msgstr ""

#: common/flatpak-auth.c:58
#, c-format
msgid "No authenticator configured for remote `%s`"
msgstr ""

#: common/flatpak-context.c:637 common/flatpak-context.c:649
#, fuzzy, c-format
msgid "Invalid permission syntax: %s"
msgstr "Branca invalida %s: %s"

#: common/flatpak-context.c:1207
#, c-format
msgid "Unknown share type %s, valid types are: %s"
msgstr ""

#: common/flatpak-context.c:1228
#, c-format
msgid "Unknown policy type %s, valid types are: %s"
msgstr ""

#: common/flatpak-context.c:1266
#, c-format
msgid "Invalid dbus name %s"
msgstr ""

#: common/flatpak-context.c:1279
#, c-format
msgid "Unknown socket type %s, valid types are: %s"
msgstr ""

#: common/flatpak-context.c:1294
#, c-format
msgid "Unknown device type %s, valid types are: %s"
msgstr ""

#: common/flatpak-context.c:1308
#, c-format
msgid "Unknown feature type %s, valid types are: %s"
msgstr ""

#: common/flatpak-context.c:1840
#, c-format
msgid "Filesystem location \"%s\" contains \"..\""
msgstr ""

#: common/flatpak-context.c:1882
#, c-format
msgid ""
"--filesystem=/ is not available, use --filesystem=host for a similar result"
msgstr ""

#: common/flatpak-context.c:1916
#, c-format
msgid ""
"Unknown filesystem location %s, valid locations are: host, host-os, host-"
"etc, host-root, home, xdg-*[/…], ~/dir, /dir"
msgstr ""

#: common/flatpak-context.c:2015
#, fuzzy, c-format
msgid "Invalid syntax for %s: %s"
msgstr "Nom invalid %s : %s"

#: common/flatpak-context.c:2142
#, c-format
msgid "fallback-x11 can not be conditional"
msgstr ""

#: common/flatpak-context.c:2318
#, c-format
msgid "Invalid env format %s"
msgstr ""

#: common/flatpak-context.c:2399
#, c-format
msgid "Environment variable name must not contain '=': %s"
msgstr ""

#: common/flatpak-context.c:2527 common/flatpak-context.c:2535
#, c-format
msgid "--add-policy arguments must be in the form SUBSYSTEM.KEY=VALUE"
msgstr ""

#: common/flatpak-context.c:2542
#, c-format
msgid "--add-policy values can't start with \"!\""
msgstr ""

#: common/flatpak-context.c:2567 common/flatpak-context.c:2575
#, c-format
msgid "--remove-policy arguments must be in the form SUBSYSTEM.KEY=VALUE"
msgstr ""

#: common/flatpak-context.c:2582
#, c-format
msgid "--remove-policy values can't start with \"!\""
msgstr ""

#: common/flatpak-context.c:2657
msgid "Share with host"
msgstr ""

#: common/flatpak-context.c:2657 common/flatpak-context.c:2658
msgid "SHARE"
msgstr "PARTEJAR"

#: common/flatpak-context.c:2658
msgid "Unshare with host"
msgstr ""

#: common/flatpak-context.c:2659
msgid "Require conditions to be met for a subsystem to get shared"
msgstr ""

#: common/flatpak-context.c:2659
msgid "SHARE:CONDITION"
msgstr ""

#: common/flatpak-context.c:2660
msgid "Expose socket to app"
msgstr ""

#: common/flatpak-context.c:2660 common/flatpak-context.c:2661
msgid "SOCKET"
msgstr ""

#: common/flatpak-context.c:2661
msgid "Don't expose socket to app"
msgstr ""

#: common/flatpak-context.c:2662
msgid "Require conditions to be met for a socket to get exposed"
msgstr ""

#: common/flatpak-context.c:2662
msgid "SOCKET:CONDITION"
msgstr ""

#: common/flatpak-context.c:2663
msgid "Expose device to app"
msgstr ""

#: common/flatpak-context.c:2663 common/flatpak-context.c:2664
msgid "DEVICE"
msgstr "PERIFERIC"

#: common/flatpak-context.c:2664
msgid "Don't expose device to app"
msgstr ""

#: common/flatpak-context.c:2665
msgid "Require conditions to be met for a device to get exposed"
msgstr ""

#: common/flatpak-context.c:2665
msgid "DEVICE:CONDITION"
msgstr ""

#: common/flatpak-context.c:2666
msgid "Allow feature"
msgstr ""

#: common/flatpak-context.c:2666 common/flatpak-context.c:2667
msgid "FEATURE"
msgstr "FONCTIONALITAT"

#: common/flatpak-context.c:2667
msgid "Don't allow feature"
msgstr ""

#: common/flatpak-context.c:2668
msgid "Require conditions to be met for a feature to get allowed"
msgstr ""

#: common/flatpak-context.c:2668
msgid "FEATURE:CONDITION"
msgstr ""

#: common/flatpak-context.c:2669
msgid "Expose filesystem to app (:ro for read-only)"
msgstr ""

#: common/flatpak-context.c:2669
msgid "FILESYSTEM[:ro]"
msgstr ""

#: common/flatpak-context.c:2670
msgid "Don't expose filesystem to app"
msgstr ""

#: common/flatpak-context.c:2670
msgid "FILESYSTEM"
msgstr ""

#: common/flatpak-context.c:2671
msgid "Set environment variable"
msgstr ""

#: common/flatpak-context.c:2671
msgid "VAR=VALUE"
msgstr "VAR=VALOR"

#: common/flatpak-context.c:2672
msgid "Read environment variables in env -0 format from FD"
msgstr ""

#: common/flatpak-context.c:2673
msgid "Remove variable from environment"
msgstr ""

#: common/flatpak-context.c:2673
msgid "VAR"
msgstr "VAR"

#: common/flatpak-context.c:2674
msgid "Allow app to own name on the session bus"
msgstr ""

#: common/flatpak-context.c:2674 common/flatpak-context.c:2675
#: common/flatpak-context.c:2676 common/flatpak-context.c:2677
#: common/flatpak-context.c:2678 common/flatpak-context.c:2679
#: common/flatpak-context.c:2680
msgid "DBUS_NAME"
msgstr ""

#: common/flatpak-context.c:2675
msgid "Allow app to talk to name on the session bus"
msgstr ""

#: common/flatpak-context.c:2676
msgid "Don't allow app to talk to name on the session bus"
msgstr ""

#: common/flatpak-context.c:2677
msgid "Allow app to own name on the system bus"
msgstr ""

#: common/flatpak-context.c:2678
msgid "Allow app to talk to name on the system bus"
msgstr ""

#: common/flatpak-context.c:2679
msgid "Don't allow app to talk to name on the system bus"
msgstr ""

#: common/flatpak-context.c:2680
msgid "Allow app to own name on the a11y bus"
msgstr ""

#: common/flatpak-context.c:2681
msgid "Add generic policy option"
msgstr ""

#: common/flatpak-context.c:2681 common/flatpak-context.c:2682
msgid "SUBSYSTEM.KEY=VALUE"
msgstr ""

#: common/flatpak-context.c:2682
msgid "Remove generic policy option"
msgstr ""

#: common/flatpak-context.c:2683
msgid "Add USB device to enumerables"
msgstr ""

#: common/flatpak-context.c:2683 common/flatpak-context.c:2684
msgid "VENDOR_ID:PRODUCT_ID"
msgstr ""

#: common/flatpak-context.c:2684
msgid "Add USB device to hidden list"
msgstr ""

#: common/flatpak-context.c:2685
msgid "A list of USB devices that are enumerable"
msgstr ""

#: common/flatpak-context.c:2685
msgid "LIST"
msgstr ""

#: common/flatpak-context.c:2686
msgid "File containing a list of USB devices to make enumerable"
msgstr ""

#: common/flatpak-context.c:2686 common/flatpak-context.c:2687
msgid "FILENAME"
msgstr ""

#: common/flatpak-context.c:2687
msgid "Persist home directory subpath"
msgstr ""

#. This is not needed/used anymore, so hidden, but we accept it for backwards compat
#: common/flatpak-context.c:2689
msgid "Don't require a running session (no cgroups creation)"
msgstr ""

#: common/flatpak-context.c:3718
#, c-format
msgid "Not replacing \"%s\" with tmpfs: %s"
msgstr ""

#: common/flatpak-context.c:3726
#, c-format
msgid "Not sharing \"%s\" with sandbox: %s"
msgstr ""

#. Even if the error is one that we would normally silence, like
#. * the path not existing, it seems reasonable to make more of a fuss
#. * about the home directory not existing or otherwise being unusable,
#. * so this is intentionally not using cannot_export()
#: common/flatpak-context.c:3828
#, c-format
msgid "Not allowing home directory access: %s"
msgstr ""

#: common/flatpak-context.c:4062
#, c-format
msgid "Unable to provide a temporary home directory in the sandbox: %s"
msgstr ""

#: common/flatpak-dir.c:442
#, c-format
msgid "Configured collection ID ‘%s’ not in summary file"
msgstr ""

#: common/flatpak-dir.c:587
#, c-format
msgid "Unable to load summary from remote %s: %s"
msgstr ""

#: common/flatpak-dir.c:764 common/flatpak-dir.c:800 common/flatpak-dir.c:906
#, c-format
msgid "No such ref '%s' in remote %s"
msgstr ""

#: common/flatpak-dir.c:891 common/flatpak-dir.c:1051 common/flatpak-dir.c:1080
#: common/flatpak-dir.c:1092
#, fuzzy, c-format
msgid "No entry for %s in remote %s summary flatpak cache"
msgstr "No flatpak cache in remote '%s' summary"

#: common/flatpak-dir.c:1069
#, c-format
msgid "No summary or Flatpak cache available for remote %s"
msgstr ""

#: common/flatpak-dir.c:1097
#, c-format
msgid "Missing xa.data in summary for remote %s"
msgstr ""

#: common/flatpak-dir.c:1103 common/flatpak-dir.c:1546
#, c-format
msgid "Unsupported summary version %d for remote %s"
msgstr ""

#: common/flatpak-dir.c:1200
msgid "Remote OCI index has no registry uri"
msgstr ""

#: common/flatpak-dir.c:1261
#, c-format
msgid "Couldn't find ref %s in remote %s"
msgstr ""

#: common/flatpak-dir.c:1288 common/flatpak-dir.c:1381
#, c-format
msgid "Commit has no requested ref ‘%s’ in ref binding metadata (found: ‘%s’)"
msgstr ""

#: common/flatpak-dir.c:1413
#, c-format
msgid "Configured collection ID ‘%s’ not in binding metadata"
msgstr ""

#: common/flatpak-dir.c:1449 common/flatpak-dir.c:5645
#, c-format
msgid "Couldn't find latest checksum for ref %s in remote %s"
msgstr ""

#: common/flatpak-dir.c:1516 common/flatpak-dir.c:1552
#, fuzzy, c-format
msgid "No entry for %s in remote %s summary flatpak sparse cache"
msgstr "No flatpak cache in remote '%s' summary"

#: common/flatpak-dir.c:2540
#, c-format
msgid "Commit metadata for %s not matching expected metadata"
msgstr ""

#: common/flatpak-dir.c:2823
msgid "Unable to connect to system bus"
msgstr ""

#: common/flatpak-dir.c:3419
msgid "User installation"
msgstr "Installacion per l’utilizaire"

#: common/flatpak-dir.c:3426
#, c-format
msgid "System (%s) installation"
msgstr ""

#: common/flatpak-dir.c:3472
#, c-format
msgid "No overrides found for %s"
msgstr ""

#: common/flatpak-dir.c:3625
#, c-format
msgid "%s (commit %s) not installed"
msgstr ""

#: common/flatpak-dir.c:4650
#, c-format
msgid "Error parsing system flatpakrepo file for %s: %s"
msgstr ""

#: common/flatpak-dir.c:4735
#, c-format
msgid "While opening repository %s: "
msgstr ""

#: common/flatpak-dir.c:5004
#, c-format
msgid "The config key %s is not set"
msgstr ""

#: common/flatpak-dir.c:5140
#, c-format
msgid "No current %s pattern matching %s"
msgstr ""

#: common/flatpak-dir.c:5422
msgid "No appstream commit to deploy"
msgstr ""

#: common/flatpak-dir.c:5941 common/flatpak-dir.c:7266
#: common/flatpak-dir.c:10881 common/flatpak-dir.c:11618
msgid "Can't pull from untrusted non-gpg verified remote"
msgstr ""

#: common/flatpak-dir.c:6376 common/flatpak-dir.c:6591
msgid "Extra data not supported for non-gpg-verified local system installs"
msgstr ""

#: common/flatpak-dir.c:6415 common/flatpak-dir.c:6782
#, c-format
msgid "Invalid checksum for extra data uri %s"
msgstr ""

#: common/flatpak-dir.c:6424
#, c-format
msgid "Empty name for extra data uri %s"
msgstr ""

#: common/flatpak-dir.c:6432
#, c-format
msgid "Unsupported extra data uri %s"
msgstr ""

#: common/flatpak-dir.c:6461
#, c-format
msgid "Failed to load local extra-data %s: %s"
msgstr ""

#: common/flatpak-dir.c:6469
#, c-format
msgid "Wrong size for extra-data %s"
msgstr ""

#: common/flatpak-dir.c:6488
#, c-format
msgid "While downloading %s: "
msgstr ""

#: common/flatpak-dir.c:6498
#, c-format
msgid "Wrong size for extra data %s"
msgstr ""

#: common/flatpak-dir.c:6507
#, c-format
msgid "Invalid checksum for extra data %s"
msgstr ""

#: common/flatpak-dir.c:7096 common/flatpak-dir.c:7349
#, c-format
msgid "While pulling %s from remote %s: "
msgstr ""

#: common/flatpak-dir.c:7290 common/flatpak-repo-utils.c:3886
msgid "GPG signatures found, but none are in trusted keyring"
msgstr ""

#: common/flatpak-dir.c:7307
#, c-format
msgid "Commit for ‘%s’ has no ref binding"
msgstr ""

#: common/flatpak-dir.c:7312
#, c-format
msgid "Commit for ‘%s’ is not in expected bound refs: %s"
msgstr ""

#: common/flatpak-dir.c:7488
msgid "Only applications can be made current"
msgstr ""

#: common/flatpak-dir.c:8192
msgid "Not enough memory"
msgstr "Pas pro de memòria"

#: common/flatpak-dir.c:8211
msgid "Failed to read from exported file"
msgstr ""

#: common/flatpak-dir.c:8401
msgid "Error reading mimetype xml file"
msgstr ""

#: common/flatpak-dir.c:8406
msgid "Invalid mimetype xml file"
msgstr ""

#: common/flatpak-dir.c:8492
#, c-format
msgid "D-Bus service file '%s' has wrong name"
msgstr ""

#: common/flatpak-dir.c:8647
#, fuzzy, c-format
msgid "Invalid Exec argument %s"
msgstr "Invalid group: %d"

#: common/flatpak-dir.c:9115
msgid "While getting detached metadata: "
msgstr ""

#: common/flatpak-dir.c:9120 common/flatpak-dir.c:9125
#: common/flatpak-dir.c:9129
msgid "Extra data missing in detached metadata"
msgstr ""

#: common/flatpak-dir.c:9133
msgid "While creating extradir: "
msgstr ""

#: common/flatpak-dir.c:9154 common/flatpak-dir.c:9187
msgid "Invalid checksum for extra data"
msgstr ""

#: common/flatpak-dir.c:9183
msgid "Wrong size for extra data"
msgstr ""

#: common/flatpak-dir.c:9196
#, c-format
msgid "While writing extra data file '%s': "
msgstr ""

#: common/flatpak-dir.c:9204
#, c-format
msgid "Extra data %s missing in detached metadata"
msgstr ""

#: common/flatpak-dir.c:9278
#, c-format
msgid "Unable to get runtime key from metadata"
msgstr ""

#: common/flatpak-dir.c:9402
#, c-format
msgid "apply_extra script failed, exit status %d"
msgstr ""

#. Translators: The placeholder is for an app ref.
#: common/flatpak-dir.c:9591
#, c-format
msgid "Installing %s is not allowed by the policy set by your administrator"
msgstr ""

#: common/flatpak-dir.c:9690
#, c-format
msgid "While trying to resolve ref %s: "
msgstr ""

#: common/flatpak-dir.c:9702
#, c-format
msgid "%s is not available"
msgstr ""

#: common/flatpak-dir.c:9714 common/flatpak-dir.c:11495
#, c-format
msgid "%s commit %s already installed"
msgstr ""

#: common/flatpak-dir.c:9721
msgid "Can't create deploy directory"
msgstr ""

#: common/flatpak-dir.c:9729
#, c-format
msgid "Failed to read commit %s: "
msgstr ""

#: common/flatpak-dir.c:9750
#, c-format
msgid "While trying to checkout %s into %s: "
msgstr ""

#: common/flatpak-dir.c:9769
msgid "While trying to checkout metadata subpath: "
msgstr ""

#: common/flatpak-dir.c:9801
#, c-format
msgid "While trying to checkout subpath ‘%s’: "
msgstr ""

#: common/flatpak-dir.c:9811
msgid "While trying to remove existing extra dir: "
msgstr ""

#: common/flatpak-dir.c:9822
msgid "While trying to apply extra data: "
msgstr ""

#: common/flatpak-dir.c:9849
#, c-format
msgid "Invalid commit ref %s: "
msgstr ""

#: common/flatpak-dir.c:9857 common/flatpak-dir.c:9869
#, c-format
msgid "Deployed ref %s does not match commit (%s)"
msgstr ""

#: common/flatpak-dir.c:9863
#, c-format
msgid "Deployed ref %s branch does not match commit (%s)"
msgstr ""

#: common/flatpak-dir.c:10125 common/flatpak-installation.c:1911
#, c-format
msgid "%s branch %s already installed"
msgstr ""

#: common/flatpak-dir.c:10985
#, c-format
msgid "Could not unmount revokefs-fuse filesystem at %s: "
msgstr ""

#: common/flatpak-dir.c:11289
#, c-format
msgid "This version of %s is already installed"
msgstr ""

#: common/flatpak-dir.c:11302
#, c-format
msgid "Can't change remote during bundle install"
msgstr ""

#: common/flatpak-dir.c:11571
msgid "Can't update to a specific commit without root permissions"
msgstr ""

#: common/flatpak-dir.c:11852
#, c-format
msgid "Can't remove %s, it is needed for: %s"
msgstr ""

#: common/flatpak-dir.c:11912 common/flatpak-installation.c:2067
#, c-format
msgid "%s branch %s is not installed"
msgstr ""

#: common/flatpak-dir.c:12165
#, c-format
msgid "%s commit %s not installed"
msgstr ""

#: common/flatpak-dir.c:12501
#, c-format
msgid "Pruning repo failed: %s"
msgstr ""

#: common/flatpak-dir.c:12669 common/flatpak-dir.c:12675
#, c-format
msgid "Failed to load filter '%s'"
msgstr ""

#: common/flatpak-dir.c:12681
#, c-format
msgid "Failed to parse filter '%s'"
msgstr ""

#: common/flatpak-dir.c:12963
msgid "Failed to write summary cache: "
msgstr ""

#: common/flatpak-dir.c:12982
#, c-format
msgid "No oci summary cached for remote '%s'"
msgstr ""

#: common/flatpak-dir.c:13207
#, fuzzy, c-format
msgid "No cached summary for remote '%s'"
msgstr "No repo metadata cached for remote '%s'"

#: common/flatpak-dir.c:13248
#, c-format
msgid "Invalid checksum for indexed summary %s read from %s"
msgstr ""

#: common/flatpak-dir.c:13321
#, c-format
msgid ""
"Remote listing for %s not available; server has no summary file. Check the "
"URL passed to remote-add was valid."
msgstr ""

#: common/flatpak-dir.c:13698
#, c-format
msgid "Invalid checksum for indexed summary %s for remote '%s'"
msgstr ""

#: common/flatpak-dir.c:14388
#, c-format
msgid "Multiple branches available for %s, you must specify one of: "
msgstr ""

#: common/flatpak-dir.c:14454
#, c-format
msgid "Nothing matches %s"
msgstr "Cap de correspondéncia per %s"

#: common/flatpak-dir.c:14562
#, c-format
msgid "Can't find ref %s%s%s%s%s"
msgstr ""

#: common/flatpak-dir.c:14605
#, c-format
msgid "Error searching remote %s: %s"
msgstr ""

#: common/flatpak-dir.c:14702
#, c-format
msgid "Error searching local repository: %s"
msgstr ""

#: common/flatpak-dir.c:14839
#, c-format
msgid "%s/%s/%s not installed"
msgstr "%s/%s/%s pas installat"

#: common/flatpak-dir.c:15042
#, c-format
msgid "Could not find installation %s"
msgstr "Impossible de trobar l'installacion %s"

#: common/flatpak-dir.c:15612
#, c-format
msgid "Invalid file format, no %s group"
msgstr ""

#: common/flatpak-dir.c:15617 common/flatpak-repo-utils.c:2836
#, c-format
msgid "Invalid version %s, only 1 supported"
msgstr ""

#: common/flatpak-dir.c:15622 common/flatpak-dir.c:15627
#, c-format
msgid "Invalid file format, no %s specified"
msgstr ""

#. Check some minimal size so we don't get crap
#: common/flatpak-dir.c:15647
msgid "Invalid file format, gpg key invalid"
msgstr ""

#: common/flatpak-dir.c:15675 common/flatpak-repo-utils.c:2917
msgid "Collection ID requires GPG key to be provided"
msgstr ""

#: common/flatpak-dir.c:15718
#, c-format
msgid "Runtime %s, branch %s is already installed"
msgstr ""

#: common/flatpak-dir.c:15719
#, c-format
msgid "App %s, branch %s is already installed"
msgstr ""

#: common/flatpak-dir.c:15953
#, c-format
msgid "Can't remove remote '%s' with installed ref %s (at least)"
msgstr ""

#: common/flatpak-dir.c:16058
#, c-format
msgid "Invalid character '/' in remote name: %s"
msgstr ""

#: common/flatpak-dir.c:16064
#, c-format
msgid "No configuration for remote %s specified"
msgstr ""

#: common/flatpak-dir.c:17597
#, c-format
msgid "Skipping deletion of mirror ref (%s, %s)…\n"
msgstr ""

#: common/flatpak-exports.c:931
#, c-format
msgid "An absolute path is required"
msgstr ""

#: common/flatpak-exports.c:948
#, fuzzy, c-format
msgid "Unable to open path \"%s\": %s"
msgstr "Unable to load metadata from remote %s: %s"

#: common/flatpak-exports.c:955
#, fuzzy, c-format
msgid "Unable to get file type of \"%s\": %s"
msgstr "Unable to load metadata from remote %s: %s"

#: common/flatpak-exports.c:964
#, c-format
msgid "File \"%s\" has unsupported type 0o%o"
msgstr ""

#: common/flatpak-exports.c:970
#, c-format
msgid "Unable to get filesystem information for \"%s\": %s"
msgstr ""

#: common/flatpak-exports.c:980
#, c-format
msgid "Ignoring blocking autofs path \"%s\""
msgstr ""

#: common/flatpak-exports.c:996 common/flatpak-exports.c:1009
#: common/flatpak-exports.c:1022
#, c-format
msgid "Path \"%s\" is reserved by Flatpak"
msgstr ""

#: common/flatpak-exports.c:1076
#, c-format
msgid "Unable to resolve symbolic link \"%s\": %s"
msgstr ""

#: common/flatpak-glib-backports.c:69
msgid "Empty string is not a number"
msgstr "Una cadena voida es pas un nombre"

#: common/flatpak-glib-backports.c:95
#, c-format
msgid "“%s” is not an unsigned number"
msgstr "« %s » es pas un nombre pas signat"

#: common/flatpak-glib-backports.c:105
#, c-format
msgid "Number “%s” is out of bounds [%s, %s]"
msgstr "Lo nombre « %s » es fòra limits [%s, %s]"

#: common/flatpak-image-source.c:83
msgid "Only sha256 image checksums are supported"
msgstr ""

#: common/flatpak-image-source.c:100 common/flatpak-image-source.c:108
msgid "Image is not a manifest"
msgstr ""

#: common/flatpak-image-source.c:123
msgid "No org.flatpak.ref found in image"
msgstr ""

#: common/flatpak-image-source.c:148
#, c-format
msgid "Ref '%s' not found in registry"
msgstr ""

#: common/flatpak-image-source.c:157
msgid "Multiple images in registry, specify a ref with --ref"
msgstr ""

#: common/flatpak-installation.c:834
#, c-format
msgid "Ref %s not installed"
msgstr ""

#: common/flatpak-installation.c:875
#, c-format
msgid "App %s not installed"
msgstr ""

#: common/flatpak-installation.c:1395
#, c-format
msgid "Remote '%s' already exists"
msgstr ""

#: common/flatpak-installation.c:1946
#, c-format
msgid "As requested, %s was only pulled, but not installed"
msgstr ""

#: common/flatpak-instance.c:533 common/flatpak-instance.c:687
#: common/flatpak-instance.c:728
#, c-format
msgid "Unable to create directory %s"
msgstr ""

#: common/flatpak-instance.c:554
#, c-format
msgid "Unable to lock %s"
msgstr ""

#: common/flatpak-instance.c:627
#, c-format
msgid "Unable to create temporary directory in %s"
msgstr ""

#: common/flatpak-instance.c:639
#, c-format
msgid "Unable to create file %s"
msgstr ""

#: common/flatpak-instance.c:646
#, c-format
msgid "Unable to update symbolic link %s/%s"
msgstr ""

#: common/flatpak-oci-registry.c:1197
msgid "Only Bearer authentication supported"
msgstr ""

#: common/flatpak-oci-registry.c:1206
msgid "Only realm in authentication request"
msgstr ""

#: common/flatpak-oci-registry.c:1213
msgid "Invalid realm in authentication request"
msgstr ""

#: common/flatpak-oci-registry.c:1283
#, c-format
msgid "Authorization failed: %s"
msgstr ""

#: common/flatpak-oci-registry.c:1285
msgid "Authorization failed"
msgstr "Error d'autorizacion"

#: common/flatpak-oci-registry.c:1289
#, c-format
msgid "Unexpected response status %d when requesting token: %s"
msgstr ""

#: common/flatpak-oci-registry.c:1300
msgid "Invalid authentication request response"
msgstr ""

#: common/flatpak-oci-registry.c:1731
#, c-format
msgid "Flatpak was compiled without zstd support"
msgstr ""

#: common/flatpak-oci-registry.c:1923 common/flatpak-oci-registry.c:1975
#: common/flatpak-oci-registry.c:2004 common/flatpak-oci-registry.c:2059
#: common/flatpak-oci-registry.c:2115 common/flatpak-oci-registry.c:2193
msgid "Invalid delta file format"
msgstr ""

#: common/flatpak-oci-registry.c:3198 common/flatpak-oci-registry.c:3382
msgid "Invalid OCI image config"
msgstr ""

#: common/flatpak-oci-registry.c:3260 common/flatpak-oci-registry.c:3531
#, c-format
msgid "Wrong layer checksum, expected %s, was %s"
msgstr ""

#: common/flatpak-oci-registry.c:3359
#, c-format
msgid "No ref specified for OCI image %s"
msgstr ""

#: common/flatpak-oci-registry.c:3369
#, c-format
msgid "Wrong ref (%s) specified for OCI image %s, expected %s"
msgstr ""

#: common/flatpak-progress.c:236
#, c-format
msgid "Downloading metadata: %u/(estimating) %s"
msgstr ""

#: common/flatpak-progress.c:260
#, c-format
msgid "Downloading: %s/%s"
msgstr ""

#: common/flatpak-progress.c:280
#, c-format
msgid "Downloading extra data: %s/%s"
msgstr ""

#: common/flatpak-progress.c:285
#, c-format
msgid "Downloading files: %d/%d %s"
msgstr ""

#: common/flatpak-ref-utils.c:122
msgid "Name can't be empty"
msgstr ""

#: common/flatpak-ref-utils.c:129
msgid "Name can't be longer than 255 characters"
msgstr ""

#: common/flatpak-ref-utils.c:142
msgid "Name can't start with a period"
msgstr ""

#: common/flatpak-ref-utils.c:148
#, c-format
msgid "Name can't start with %c"
msgstr ""

#: common/flatpak-ref-utils.c:164
msgid "Name can't end with a period"
msgstr ""

#: common/flatpak-ref-utils.c:171 common/flatpak-ref-utils.c:183
msgid "Only last name segment can contain -"
msgstr ""

#: common/flatpak-ref-utils.c:174
#, c-format
msgid "Name segment can't start with %c"
msgstr ""

#: common/flatpak-ref-utils.c:186
#, c-format
msgid "Name can't contain %c"
msgstr ""

#: common/flatpak-ref-utils.c:195
msgid "Names must contain at least 2 periods"
msgstr ""

#: common/flatpak-ref-utils.c:312
msgid "Arch can't be empty"
msgstr ""

#: common/flatpak-ref-utils.c:323
#, c-format
msgid "Arch can't contain %c"
msgstr ""

#: common/flatpak-ref-utils.c:385
msgid "Branch can't be empty"
msgstr ""

#: common/flatpak-ref-utils.c:395
#, c-format
msgid "Branch can't start with %c"
msgstr ""

#: common/flatpak-ref-utils.c:405
#, c-format
msgid "Branch can't contain %c"
msgstr ""

#: common/flatpak-ref-utils.c:615 common/flatpak-ref-utils.c:865
msgid "Ref too long"
msgstr ""

#: common/flatpak-ref-utils.c:627
#, fuzzy
msgid "Invalid remote name"
msgstr "Invalid group: %d"

#: common/flatpak-ref-utils.c:641
#, c-format
msgid "%s is not application or runtime"
msgstr ""

#: common/flatpak-ref-utils.c:650 common/flatpak-ref-utils.c:667
#: common/flatpak-ref-utils.c:683
#, c-format
msgid "Wrong number of components in %s"
msgstr ""

#: common/flatpak-ref-utils.c:656
#, c-format
msgid "Invalid name %.*s: %s"
msgstr ""

#: common/flatpak-ref-utils.c:673
#, fuzzy, c-format
msgid "Invalid arch: %.*s: %s"
msgstr "Invalid group: %d"

#: common/flatpak-ref-utils.c:816
#, c-format
msgid "Invalid name %s: %s"
msgstr "Nom invalid %s : %s"

#: common/flatpak-ref-utils.c:834
#, c-format
msgid "Invalid arch: %s: %s"
msgstr "Branca invalida : %s %s"

#: common/flatpak-ref-utils.c:853
#, fuzzy, c-format
msgid "Invalid branch: %s: %s"
msgstr "Invalid group: %d"

#: common/flatpak-ref-utils.c:962 common/flatpak-ref-utils.c:970
#: common/flatpak-ref-utils.c:978
#, fuzzy, c-format
msgid "Wrong number of components in partial ref %s"
msgstr "Nombre d'arguments incorrècte"

#: common/flatpak-ref-utils.c:1298
msgid " development platform"
msgstr " platafòrma de desvolopament"

#: common/flatpak-ref-utils.c:1300
msgid " platform"
msgstr " platafòrmas"

#: common/flatpak-ref-utils.c:1302
msgid " application base"
msgstr " aplicacion de basa"

#: common/flatpak-ref-utils.c:1305
msgid " debug symbols"
msgstr ""

#: common/flatpak-ref-utils.c:1307
msgid " sourcecode"
msgstr " còdi font"

#: common/flatpak-ref-utils.c:1309
msgid " translations"
msgstr " traduccions"

#: common/flatpak-ref-utils.c:1311
msgid " docs"
msgstr ""

#: common/flatpak-ref-utils.c:1578
#, c-format
msgid "Invalid id %s: %s"
msgstr ""

#: common/flatpak-remote.c:1216
#, c-format
msgid "Bad remote name: %s"
msgstr ""

#: common/flatpak-remote.c:1220
#, fuzzy
msgid "No URL specified"
msgstr "Cap d’url pas especificada"

#: common/flatpak-remote.c:1266
msgid "GPG verification must be enabled when a collection ID is set"
msgstr ""

#: common/flatpak-repo-utils.c:344
#, c-format
msgid "No extra data sources"
msgstr "Cap de fonts de donadas suplementàrias"

#: common/flatpak-repo-utils.c:2817
#, c-format
msgid "Invalid %s: Missing group ‘%s’"
msgstr ""

#: common/flatpak-repo-utils.c:2826
#, c-format
msgid "Invalid %s: Missing key ‘%s’"
msgstr ""

#: common/flatpak-repo-utils.c:2876
msgid "Invalid gpg key"
msgstr "Clau gpg invalida"

#: common/flatpak-repo-utils.c:3217
#, c-format
msgid "Error copying 64x64 icon for component %s: %s\n"
msgstr ""

#: common/flatpak-repo-utils.c:3223
#, c-format
msgid "Error copying 128x128 icon for component %s: %s\n"
msgstr ""

#: common/flatpak-repo-utils.c:3362
#, c-format
msgid "%s is end-of-life, ignoring for appstream"
msgstr ""

#: common/flatpak-repo-utils.c:3397
#, c-format
msgid "No appstream data for %s: %s\n"
msgstr ""

#: common/flatpak-repo-utils.c:3744
msgid "Invalid bundle, no ref in metadata"
msgstr ""

#: common/flatpak-repo-utils.c:3846
#, c-format
msgid "Collection ‘%s’ of bundle doesn’t match collection ‘%s’ of remote"
msgstr ""

#: common/flatpak-repo-utils.c:3923
msgid "Metadata in header and app are inconsistent"
msgstr ""

#: common/flatpak-run.c:951
msgid "No systemd user session available, cgroups not available"
msgstr ""

#: common/flatpak-run.c:1496
msgid "Unable to allocate instance id"
msgstr ""

#: common/flatpak-run.c:1632 common/flatpak-run.c:1641
#, c-format
msgid "Failed to open flatpak-info file: %s"
msgstr ""

#: common/flatpak-run.c:1668
#, c-format
msgid "Failed to open bwrapinfo.json file: %s"
msgstr ""

#: common/flatpak-run.c:1689
#, c-format
msgid "Failed to write to instance id fd: %s"
msgstr ""

#: common/flatpak-run.c:2096
msgid "Initialize seccomp failed"
msgstr ""

#: common/flatpak-run.c:2135
#, c-format
msgid "Failed to add architecture to seccomp filter: %s"
msgstr ""

#: common/flatpak-run.c:2143
#, c-format
msgid "Failed to add multiarch architecture to seccomp filter: %s"
msgstr ""

#: common/flatpak-run.c:2175 common/flatpak-run.c:2192
#: common/flatpak-run.c:2214
#, c-format
msgid "Failed to block syscall %d: %s"
msgstr ""

#: common/flatpak-run.c:2247
#, c-format
msgid "Failed to export bpf: %s"
msgstr ""

#: common/flatpak-run.c:2587
#, c-format
msgid "Failed to open ‘%s’"
msgstr ""

#: common/flatpak-run.c:2597
#, c-format
msgid ""
"Directory forwarding needs version 4 of the document portal (have version %d)"
msgstr ""

#: common/flatpak-run.c:2915
#, c-format
msgid "ldconfig failed, exit status %d"
msgstr ""

#: common/flatpak-run.c:2922
msgid "Can't open generated ld.so.cache"
msgstr ""

#. Translators: The placeholder is for an app ref.
#: common/flatpak-run.c:3045
#, c-format
msgid "Running %s is not allowed by the policy set by your administrator"
msgstr ""

#: common/flatpak-run.c:3202
msgid ""
"\"flatpak run\" is not intended to be run as `sudo flatpak run`. Use `sudo "
"-i` or `su -l` instead and invoke \"flatpak run\" from inside the new shell."
msgstr ""

#: common/flatpak-run.c:3413
#, c-format
msgid "Failed to migrate from %s: %s"
msgstr ""

#: common/flatpak-run.c:3434
#, c-format
msgid "Failed to migrate old app data directory %s to new name %s: %s"
msgstr ""

#: common/flatpak-run.c:3443
#, c-format
msgid "Failed to create symlink while migrating %s: %s"
msgstr ""

#: common/flatpak-run-dbus.c:46
msgid "Failed to open app info file"
msgstr ""

#: common/flatpak-run-dbus.c:149
msgid "Unable to create sync pipe"
msgstr ""

#: common/flatpak-run-dbus.c:185
msgid "Failed to sync with dbus proxy"
msgstr ""

#: common/flatpak-transaction.c:2275
#, c-format
msgid "Warning: Problem looking for related refs: %s"
msgstr ""

#: common/flatpak-transaction.c:2493
#, c-format
msgid "The application %s requires the runtime %s which was not found"
msgstr ""

#: common/flatpak-transaction.c:2509
#, c-format
msgid "The application %s requires the runtime %s which is not installed"
msgstr ""

#: common/flatpak-transaction.c:2641
#, c-format
msgid "Can't uninstall %s which is needed by %s"
msgstr ""

#: common/flatpak-transaction.c:2740
#, c-format
msgid "Remote %s disabled, ignoring %s update"
msgstr ""

#: common/flatpak-transaction.c:2773
#, c-format
msgid "%s is already installed"
msgstr "%s es ja installat"

#: common/flatpak-transaction.c:2776
#, c-format
msgid "%s is already installed from remote %s"
msgstr ""

#: common/flatpak-transaction.c:3120
#, c-format
msgid "Invalid .flatpakref: %s"
msgstr ""

#: common/flatpak-transaction.c:3161
msgid "Warning: Could not mark already installed apps as preinstalled"
msgstr ""

#: common/flatpak-transaction.c:3382
#, c-format
msgid "Error updating remote metadata for '%s': %s"
msgstr ""

#: common/flatpak-transaction.c:3885
#, c-format
msgid ""
"Warning: Treating remote fetch error as non-fatal since %s is already "
"installed: %s"
msgstr ""

#: common/flatpak-transaction.c:4209
#, c-format
msgid "No authenticator installed for remote '%s'"
msgstr ""

#: common/flatpak-transaction.c:4313 common/flatpak-transaction.c:4320
#, c-format
msgid "Failed to get tokens for ref: %s"
msgstr ""

#: common/flatpak-transaction.c:4315 common/flatpak-transaction.c:4322
msgid "Failed to get tokens for ref"
msgstr ""

#: common/flatpak-transaction.c:4580
#, c-format
msgid "Ref %s from %s matches more than one transaction operation"
msgstr ""

#: common/flatpak-transaction.c:4581 common/flatpak-transaction.c:4591
#, fuzzy
msgid "any remote"
msgstr "Distant"

#: common/flatpak-transaction.c:4590
#, c-format
msgid "No transaction operation found for ref %s from %s"
msgstr ""

#: common/flatpak-transaction.c:4713
#, c-format
msgid "Flatpakrepo URL %s not file, HTTP or HTTPS"
msgstr ""

#: common/flatpak-transaction.c:4719
#, c-format
msgid "Can't load dependent file %s: "
msgstr ""

#: common/flatpak-transaction.c:4727
#, c-format
msgid "Invalid .flatpakrepo: %s"
msgstr ""

#: common/flatpak-transaction.c:5454
msgid "Transaction already executed"
msgstr ""

#: common/flatpak-transaction.c:5469
msgid ""
"Refusing to operate on a user installation as root! This can lead to "
"incorrect file ownership and permission errors."
msgstr ""

#: common/flatpak-transaction.c:5567 common/flatpak-transaction.c:5580
msgid "Aborted by user"
msgstr "Abandonat per l’utilizaire"

#: common/flatpak-transaction.c:5605
#, c-format
msgid "Skipping %s due to previous error"
msgstr ""

#: common/flatpak-transaction.c:5659
#, c-format
msgid "Aborted due to failure (%s)"
msgstr ""

#: common/flatpak-uri.c:118
#, no-c-format
msgid "Invalid %-encoding in URI"
msgstr "%-encoding invalid dins l'URI"

#: common/flatpak-uri.c:135
msgid "Illegal character in URI"
msgstr "Caractèr defendut dins l’URI"

#: common/flatpak-uri.c:169
msgid "Non-UTF-8 characters in URI"
msgstr "Caractèrs non-UTF-8 dins l'URI"

#: common/flatpak-uri.c:275
#, c-format
msgid "Invalid IPv6 address ‘%.*s’ in URI"
msgstr "Adreça IPv6 invalida « %.*s » dins l’URI"

#: common/flatpak-uri.c:330
#, c-format
msgid "Illegal encoded IP address ‘%.*s’ in URI"
msgstr ""

#: common/flatpak-uri.c:342
#, c-format
msgid "Illegal internationalized hostname ‘%.*s’ in URI"
msgstr ""

#: common/flatpak-uri.c:374 common/flatpak-uri.c:386
#, c-format
msgid "Could not parse port ‘%.*s’ in URI"
msgstr "Impossible d’analisar lo pòrt « %.*s » dins l’URI"

#: common/flatpak-uri.c:393
#, c-format
msgid "Port ‘%.*s’ in URI is out of range"
msgstr "Lo pòrt « %.*s » dins l’URI es fòra plaja"

#: common/flatpak-uri.c:910
msgid "URI is not absolute, and no base URI was provided"
msgstr "L'URI es pas absoluda, e cap d'URI de basa es pas estada provesida"

#: common/flatpak-usb.c:83
#, c-format
msgid "USB device query 'all' must not have data"
msgstr ""

#: common/flatpak-usb.c:102
#, c-format
msgid "USB query rule 'cls' must be in the form CLASS:SUBCLASS or CLASS:*"
msgstr ""

#: common/flatpak-usb.c:111
#, fuzzy, c-format
msgid "Invalid USB class"
msgstr "Nom invalid %s : %s"

#: common/flatpak-usb.c:125
#, c-format
msgid "Invalid USB subclass"
msgstr ""

#: common/flatpak-usb.c:141 common/flatpak-usb.c:148
#, c-format
msgid "USB query rule 'dev' must have a valid 4-digit hexadecimal product id"
msgstr ""

#: common/flatpak-usb.c:164 common/flatpak-usb.c:171
#, c-format
msgid "USB query rule 'vnd' must have a valid 4-digit hexadecimal vendor id"
msgstr ""

#: common/flatpak-usb.c:205
#, c-format
msgid "USB device queries must be in the form TYPE:DATA"
msgstr ""

#: common/flatpak-usb.c:225
#, c-format
msgid "Unknown USB query rule %s"
msgstr ""

#: common/flatpak-usb.c:248
#, c-format
msgid "Empty USB query"
msgstr ""

#: common/flatpak-usb.c:274
#, c-format
msgid "Multiple USB query rules of the same type is not supported"
msgstr ""

#: common/flatpak-usb.c:283
#, c-format
msgid "'all' must not contain extra query rules"
msgstr ""

#: common/flatpak-usb.c:291
#, c-format
msgid "USB queries with 'dev' must also specify vendors"
msgstr ""

#: common/flatpak-utils.c:712
msgid "Glob can't match apps"
msgstr ""

#: common/flatpak-utils.c:737
msgid "Empty glob"
msgstr ""

#: common/flatpak-utils.c:756
msgid "Too many segments in glob"
msgstr ""

#: common/flatpak-utils.c:777
#, c-format
msgid "Invalid glob character '%c'"
msgstr ""

#: common/flatpak-utils.c:831
#, c-format
msgid "Missing glob on line %d"
msgstr ""

#: common/flatpak-utils.c:835
#, c-format
msgid "Trailing text on line %d"
msgstr ""

#: common/flatpak-utils.c:839
#, c-format
msgid "on line %d"
msgstr "a la linha %d"

#: common/flatpak-utils.c:861
#, c-format
msgid "Unexpected word '%s' on line %d"
msgstr ""

#: common/flatpak-utils.c:2118
#, c-format
msgid "Invalid require-flatpak argument %s"
msgstr ""

#: common/flatpak-utils.c:2128 common/flatpak-utils.c:2147
#, c-format
msgid "%s needs a later flatpak version (%s)"
msgstr ""

#: oci-authenticator/flatpak-oci-authenticator.c:291
msgid "Not a oci remote, missing summary.xa.oci-repository"
msgstr ""

#: oci-authenticator/flatpak-oci-authenticator.c:477
msgid "Not a OCI remote"
msgstr ""

#: oci-authenticator/flatpak-oci-authenticator.c:488
msgid "Invalid token"
msgstr "Geton invalid"

#: portal/flatpak-portal.c:2292
#, c-format
msgid "No portal support found"
msgstr ""

#: portal/flatpak-portal.c:2298
msgid "Deny"
msgstr "Refusar"

#: portal/flatpak-portal.c:2300
msgid "Update"
msgstr "Metre a jorn"

#: portal/flatpak-portal.c:2305
#, c-format
msgid "Update %s?"
msgstr "Metre a jorn %s ?"

#: portal/flatpak-portal.c:2317
msgid "The application wants to update itself."
msgstr ""

#: portal/flatpak-portal.c:2318
msgid "Update access can be changed any time from the privacy settings."
msgstr ""

#: portal/flatpak-portal.c:2343
#, c-format
msgid "Application update not allowed"
msgstr ""

#: portal/flatpak-portal.c:2501
#, c-format
msgid "Self update not supported, new version requires new permissions"
msgstr ""

#: portal/flatpak-portal.c:2684 portal/flatpak-portal.c:2702
#, c-format
msgid "Update ended unexpectedly"
msgstr ""

#. SECURITY:
#. - Normal users need admin authentication to install software
#. system-wide.
#. - Note that we install polkit rules that allow local users
#. in the wheel group to install without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:23
msgid "Install signed application"
msgstr ""

#: system-helper/org.freedesktop.Flatpak.policy.in:24
#: system-helper/org.freedesktop.Flatpak.policy.in:42
msgid "Authentication is required to install software"
msgstr ""

#. SECURITY:
#. - Normal users need admin authentication to install software
#. system-wide.
#. - Note that we install polkit rules that allow local users
#. in the wheel group to install without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:41
msgid "Install signed runtime"
msgstr ""

#. SECURITY:
#. - Normal users do not require admin authentication to update an
#. app as the commit will be signed, and the action is required
#. to update the system when unattended.
#. - Changing this to anything other than 'yes' will break unattended
#. updates.
#: system-helper/org.freedesktop.Flatpak.policy.in:60
msgid "Update signed application"
msgstr ""

#: system-helper/org.freedesktop.Flatpak.policy.in:61
#: system-helper/org.freedesktop.Flatpak.policy.in:80
msgid "Authentication is required to update software"
msgstr ""

#. SECURITY:
#. - Normal users do not require admin authentication to update a
#. runtime as the commit will be signed, and the action is required
#. to update the system when unattended.
#. - Changing this to anything other than 'yes' will break unattended
#. updates.
#: system-helper/org.freedesktop.Flatpak.policy.in:79
msgid "Update signed runtime"
msgstr ""

#. SECURITY:
#. - Normal users do not need authentication to update metadata
#. from signed repositories.
#: system-helper/org.freedesktop.Flatpak.policy.in:94
msgid "Update remote metadata"
msgstr ""

#: system-helper/org.freedesktop.Flatpak.policy.in:95
msgid "Authentication is required to update remote info"
msgstr ""

#. SECURITY:
#. - Normal users do not need authentication to modify the
#. OSTree repository
#. - Note that we install polkit rules that allow local users
#. in the wheel group to modify repos without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:111
msgid "Update system repository"
msgstr ""

#: system-helper/org.freedesktop.Flatpak.policy.in:112
msgid "Authentication is required to modify a system repository"
msgstr ""

#. SECURITY:
#. - Normal users need admin authentication to install software
#. system-wide.
#: system-helper/org.freedesktop.Flatpak.policy.in:126
msgid "Install bundle"
msgstr ""

#: system-helper/org.freedesktop.Flatpak.policy.in:127
msgid "Authentication is required to install software from $(path)"
msgstr ""

#. SECURITY:
#. - Normal users need admin authentication to uninstall software
#. system-wide.
#. - Note that we install polkit rules that allow local users
#. in the wheel group to uninstall without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:144
msgid "Uninstall runtime"
msgstr ""

#: system-helper/org.freedesktop.Flatpak.policy.in:145
msgid "Authentication is required to uninstall software"
msgstr ""

#. SECURITY:
#. - Normal users need admin authentication to uninstall software
#. system-wide.
#. - Note that we install polkit rules that allow local users
#. in the wheel group to uninstall without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:161
msgid "Uninstall app"
msgstr ""

#: system-helper/org.freedesktop.Flatpak.policy.in:162
msgid "Authentication is required to uninstall $(ref)"
msgstr ""

#. SECURITY:
#. - Normal users need admin authentication to configure system-wide
#. software repositories.
#: system-helper/org.freedesktop.Flatpak.policy.in:177
msgid "Configure Remote"
msgstr ""

#: system-helper/org.freedesktop.Flatpak.policy.in:178
msgid "Authentication is required to configure software repositories"
msgstr ""

#. SECURITY:
#. - Normal users need admin authentication to configure the system-wide
#. Flatpak installation.
#: system-helper/org.freedesktop.Flatpak.policy.in:192
msgid "Configure"
msgstr "Configurar"

#: system-helper/org.freedesktop.Flatpak.policy.in:193
msgid "Authentication is required to configure software installation"
msgstr ""

#. SECURITY:
#. - Normal users do not require admin authentication to update
#. appstream data as it will be signed, and the action is required
#. to update the system when unattended.
#. - Changing this to anything other than 'yes' will break unattended
#. updates.
#: system-helper/org.freedesktop.Flatpak.policy.in:210
msgid "Update appstream"
msgstr ""

#: system-helper/org.freedesktop.Flatpak.policy.in:211
msgid "Authentication is required to update information about software"
msgstr ""

#. SECURITY:
#. - Normal users do not require admin authentication to update
#. metadata as it will be signed, and the action is required
#. to update the system when unattended.
#. - Changing this to anything other than 'yes' will break unattended
#. updates.
#: system-helper/org.freedesktop.Flatpak.policy.in:228
msgid "Update metadata"
msgstr "Actualizar las metadonadas"

#: system-helper/org.freedesktop.Flatpak.policy.in:229
msgid "Authentication is required to update metadata"
msgstr ""

#. SECURITY:
#. - Authorisation to actually install software is controlled by
#. org.freedesktop.Flatpak.app-install.
#. - This action is checked after app-install, as it can only be done
#. once the app’s data (including its content rating) has been
#. downloaded.
#. - This action is checked to see if the installation should be allowed
#. based on whether the app being installed has content which doesn’t
#. comply with the user’s parental controls policy (the content is
#. ‘too extreme’).
#. - It is checked only if an app has too extreme content for the user
#. who is trying to install it (in which case, the app is ‘unsafe’).
#. - Typically, normal users will need admin permission to install apps
#. with extreme content; admins will be able to install it without
#. additional checks.
#. - In order to configure the policy so that admins can install safe and
#. unsafe software anywhere without authorisation, and non-admins can
#. install safe software in their user or system dirs without
#. authorisation, but need authorisation to install unsafe software
#. anywhere:
#. * Unconditionally return `yes` from `app-install`.
#. * Return `auth_admin` from `override-parental-controls` for users
#. not in `@privileged_group@`, and `yes` for users in it.
#. * Set the malcontent `is-{user,system}-installation-allowed`
#. properties of all non-admins’ parental controls policies to true.
#. - In order to configure the policy so that admins can install safe and
#. unsafe software anywhere without authorisation, and non-admins can
#. install safe software in their user dir without authorisation, but
#. need authorisation to install safe software in the system dir or to
#. install unsafe software anywhere:
#. * Unconditionally return `yes` from `app-install`.
#. * Return `auth_admin` from `override-parental-controls` for users
#. not in `@privileged_group@`, and `yes` for users in it.
#. * Set the malcontent `is-user-installation-allowed` property of all
#. non-admins’ parental controls policies to true.
#. * Set the malcontent `is-system-installation-allowed` property of
#. all non-admins’ parental controls policies to false.
#. - In order to configure the policy so that all users (including
#. admins) can install safe software anywhere without authorisation,
#. but need authorisation to install unsafe software anywhere (i.e.
#. applying parental controls to admins too):
#. * Unconditionally return `yes` from `app-install`.
#. * Unconditionally return `auth_admin` from `override-parental-controls`.
#. * Set the malcontent `is-user-installation-allowed` property of all
#. users’ parental controls policies to true.
#. * Set the malcontent `is-system-installation-allowed` property of
#. all users’ parental controls policies to true.
#: system-helper/org.freedesktop.Flatpak.policy.in:287
msgid "Override parental controls for installs"
msgstr ""

#: system-helper/org.freedesktop.Flatpak.policy.in:288
msgid ""
"Authentication is required to install software which is restricted by your "
"parental controls policy"
msgstr ""

#. SECURITY:
#. - This is like org.freedesktop.Flatpak.override-parental-controls, but
#. it’s queried for app updates, whereas the former is queried for app
#. installs.
#. - As with the above action, this one is only queried if
#. org.freedesktop.Flatpak.app-update has allowed the app update, and
#. only if the app being updated has too extreme content for the user
#. who is trying to update it.
#. - The default policy for this is to *allow* updates to ‘too extreme’
#. apps by default, on the basis that having an out-of-date (i.e.
#. insecure or unsupported) app is a worse outcome than automatically
#. installing an update which has radically different content from the
#. version of the app which the parent originally vetted and installed.
#: system-helper/org.freedesktop.Flatpak.policy.in:313
msgid "Override parental controls for updates"
msgstr ""

#: system-helper/org.freedesktop.Flatpak.policy.in:314
msgid ""
"Authentication is required to update software which is restricted by your "
"parental controls policy"
msgstr ""

#~ msgid "Installed:"
#~ msgstr "Installat :"

#~ msgid "Download:"
#~ msgstr "Telecargar :"

#, fuzzy, c-format
#~ msgid "No entry for %s in remote '%s' summary cache "
#~ msgstr "No flatpak cache in remote '%s' summary"

#~ msgid "install"
#~ msgstr "installar"

#~ msgid "update"
#~ msgstr "mesa a jorn"

#~ msgid "uninstall"
#~ msgstr "desinstallar"

#~ msgid "Warning:"
#~ msgstr "Avertiment:"

#, fuzzy
#~ msgid "runtime"
#~ msgstr "Environament d’execucion"

#~ msgid "Replace it with %s?"
#~ msgstr "Lo remplaçar per « %s » ?"

#, fuzzy
#~ msgid "Ref '%s' is only partially installed"
#~ msgstr "Requested extension %s is only partially installed"

#~ msgid "No such ref (%s, %s) in remote %s"
#~ msgstr "No such ref (%s, %s) in remote %s"

#~ msgid "No such ref (%s, %s) in remote %s or elsewhere"
#~ msgstr "No such ref (%s, %s) in remote %s or elsewhere"

#~ msgid "No remotes found which provide these refs: [%s]"
#~ msgstr "No remotes found which provide these refs: [%s]"

#~ msgid "No remotes found which provide the ref (%s, %s)"
#~ msgstr "No remotes found which provide the ref (%s, %s)"

#~ msgid "No summary found"
#~ msgstr "No summary found"

#~ msgid ""
#~ "GPG verification enabled, but no summary signatures found for remote '%s'"
#~ msgstr ""
#~ "GPG verification enabled, but no summary signatures found for remote '%s'"

#~ msgid ""
#~ "GPG signatures found for remote '%s', but none are in trusted keyring"
#~ msgstr ""
#~ "GPG signatures found for remote '%s', but none are in trusted keyring"

#~ msgid "Expected commit metadata to have ref binding information, found none"
#~ msgstr ""
#~ "Expected commit metadata to have ref binding information, found none"

#~ msgid ""
#~ "Expected commit metadata to have collection ID binding information, found "
#~ "none"
#~ msgstr ""
#~ "Expected commit metadata to have collection ID binding information, found "
#~ "none"

#~ msgid ""
#~ "Commit has collection ID ‘%s’ in collection binding metadata, while the "
#~ "remote it came from has collection ID ‘%s’"
#~ msgstr ""
#~ "Commit has collection ID ‘%s’ in collection binding metadata, while the "
#~ "remote it came from has collection ID ‘%s’"

#~ msgid "Deployed metadata does not match commit"
#~ msgstr "Deployed metadata does not match commit"

#~ msgid "No metadata branch for OCI"
#~ msgstr "No metadata branch for OCI"

#~ msgid "Warning: Can't find %s metadata for dependencies: %s"
#~ msgstr "Warning: Can't find %s metadata for dependencies: %s"

#~ msgid "Not running as root, may be unable to enter namespace"
#~ msgstr "Not running as root, may be unable to enter namespace"

#~ msgid "Default system installation"
#~ msgstr "Default system installation"

===== ./po/ru.po =====
# Russian translation for flatpak.
# Copyright (C) 2016 flatpak's COPYRIGHT HOLDER
# This file is distributed under the same license as the flatpak package.
#
# Roman Kharin <romiq.kh@gmail.com>, 2017.
# Артемий Судаков <finziyr@yandex.ru>, 2020.
# Дмитрий <dmitrydmitry761@gmail.com>, 2023.
# Вячеслав Гурин <slavkaplay6@gmail.com>, 2025.
#
msgid ""
msgstr ""
"Project-Id-Version: flatpak master\n"
"Report-Msgid-Bugs-To: https://github.com/flatpak/flatpak/issues\n"
"POT-Creation-Date: 2026-05-27 16:39+0200\n"
"PO-Revision-Date: 2025-08-11 14:17+0800\n"
"Last-Translator: Vyacheslav Gurin <slavkaplay6@gmail.com>\n"
"Language-Team: Russian <gnome-cyr@gnome.org>\n"
"Language: ru\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && "
"n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
"X-Generator: Poedit 3.0.1\n"

#: app/flatpak-builtins-build-bundle.c:59
msgid "Export runtime instead of app"
msgstr "Экспортировать среду выполнения вместо приложения"

#: app/flatpak-builtins-build-bundle.c:60
msgid "Arch to bundle for"
msgstr "Архитектура для пакета"

#: app/flatpak-builtins-build-bundle.c:60
#: app/flatpak-builtins-build-export.c:62 app/flatpak-builtins-build-init.c:53
#: app/flatpak-builtins-build-sign.c:42 app/flatpak-builtins-create-usb.c:46
#: app/flatpak-builtins-info.c:55 app/flatpak-builtins-install.c:67
#: app/flatpak-builtins-list.c:50 app/flatpak-builtins-make-current.c:38
#: app/flatpak-builtins-remote-info.c:54 app/flatpak-builtins-remote-ls.c:56
#: app/flatpak-builtins-run.c:158 app/flatpak-builtins-search.c:37
#: app/flatpak-builtins-uninstall.c:54 app/flatpak-builtins-update.c:56
msgid "ARCH"
msgstr "АРХИТЕКТУРА"

#: app/flatpak-builtins-build-bundle.c:61
#, fuzzy
msgid "URL for repo"
msgstr "URL репозитория"

#: app/flatpak-builtins-build-bundle.c:61
#: app/flatpak-builtins-build-bundle.c:62
#: app/flatpak-builtins-build-update-repo.c:68
#: app/flatpak-builtins-build-update-repo.c:72
#: app/flatpak-builtins-build-update-repo.c:73
#: app/flatpak-builtins-history.c:69 app/flatpak-builtins-remote-add.c:80
#: app/flatpak-builtins-remote-add.c:81 app/flatpak-builtins-remote-add.c:85
#: app/flatpak-builtins-remote-list.c:53
#: app/flatpak-builtins-remote-modify.c:70
#: app/flatpak-builtins-remote-modify.c:85
#: app/flatpak-builtins-remote-modify.c:86
#: app/flatpak-builtins-remote-modify.c:90
msgid "URL"
msgstr "URL"

#: app/flatpak-builtins-build-bundle.c:62
#, fuzzy
msgid "URL for runtime flatpakrepo file"
msgstr "URL файла flatpakrepo среды выполнения"

#: app/flatpak-builtins-build-bundle.c:63
msgid "Add GPG key from FILE (- for stdin)"
msgstr "Добавить ключ GPG из ФАЙЛА (- из стандартного потока ввода)"

#: app/flatpak-builtins-build-bundle.c:63 app/flatpak-builtins-build.c:54
#: app/flatpak-builtins-build-export.c:67
#: app/flatpak-builtins-build-update-repo.c:83
#: app/flatpak-builtins-install.c:81 app/flatpak-builtins-remote-add.c:84
#: app/flatpak-builtins-remote-add.c:86 app/flatpak-builtins-remote-modify.c:89
#: app/flatpak-builtins-remote-modify.c:92
msgid "FILE"
msgstr "ФАЙЛ"

#: app/flatpak-builtins-build-bundle.c:64
msgid "GPG Key ID to sign the OCI image with"
msgstr "ID Ключа GPG для подписи образа OCI"

#: app/flatpak-builtins-build-bundle.c:64
#: app/flatpak-builtins-build-commit-from.c:68
#: app/flatpak-builtins-build-export.c:68
#: app/flatpak-builtins-build-import-bundle.c:49
#: app/flatpak-builtins-build-sign.c:44
#: app/flatpak-builtins-build-update-repo.c:84
msgid "KEY-ID"
msgstr "ID-КЛЮЧА"

#: app/flatpak-builtins-build-bundle.c:65
#: app/flatpak-builtins-build-commit-from.c:69
#: app/flatpak-builtins-build-export.c:71
#: app/flatpak-builtins-build-import-bundle.c:50
#: app/flatpak-builtins-build-sign.c:45
#: app/flatpak-builtins-build-update-repo.c:85
msgid "GPG Homedir to use when looking for keyrings"
msgstr "Домашний каталог GPG для поиска связок ключей"

#: app/flatpak-builtins-build-bundle.c:65
#: app/flatpak-builtins-build-commit-from.c:69
#: app/flatpak-builtins-build-export.c:71
#: app/flatpak-builtins-build-import-bundle.c:50
#: app/flatpak-builtins-build-sign.c:45
#: app/flatpak-builtins-build-update-repo.c:85
msgid "HOMEDIR"
msgstr "ДОМАШНИЙ_КАТАЛОГ"

#: app/flatpak-builtins-build-bundle.c:66
msgid "OSTree commit to create a delta bundle from"
msgstr "Коммит OSTree для создания дельта-пакета из"

#: app/flatpak-builtins-build-bundle.c:66 app/flatpak-builtins-remote-info.c:55
#: app/flatpak-builtins-update.c:57
msgid "COMMIT"
msgstr "КОММИТ"

#: app/flatpak-builtins-build-bundle.c:67
msgid "Export oci image instead of flatpak bundle"
msgstr "Экспортировать образ oci вместо пакета flatpak"

#: app/flatpak-builtins-build-bundle.c:70
msgid "How to compress OCI image layers (default: gzip)"
msgstr ""

#: app/flatpak-builtins-build-bundle.c:634
msgid ""
"LOCATION FILENAME NAME [BRANCH] - Create a single file bundle from a local "
"repository"
msgstr ""
"ПУТЬ ИМЯ_ФАЙЛА ИМЯ [ВЕТВЬ] - Создать один файл с пакетом из локального "
"репозитория"

#: app/flatpak-builtins-build-bundle.c:641
msgid "LOCATION, FILENAME and NAME must be specified"
msgstr "Должны быть указаны ПУТЬ, ИМЯ_ФАЙЛА и ИМЯ"

#: app/flatpak-builtins-build-bundle.c:644
#: app/flatpak-builtins-build-export.c:844
#: app/flatpak-builtins-build-import-bundle.c:136
#: app/flatpak-builtins-build-init.c:217 app/flatpak-builtins-build-sign.c:76
#: app/flatpak-builtins-document-export.c:112
#: app/flatpak-builtins-document-info.c:75
#: app/flatpak-builtins-document-list.c:191
#: app/flatpak-builtins-document-unexport.c:70
#: app/flatpak-builtins-history.c:482 app/flatpak-builtins-info.c:130
#: app/flatpak-builtins-install.c:181 app/flatpak-builtins-install.c:234
#: app/flatpak-builtins-install.c:298 app/flatpak-builtins-list.c:419
#: app/flatpak-builtins-make-current.c:72 app/flatpak-builtins-override.c:73
#: app/flatpak-builtins-permission-list.c:162
#: app/flatpak-builtins-permission-remove.c:132
#: app/flatpak-builtins-remote-add.c:323
#: app/flatpak-builtins-remote-delete.c:68
#: app/flatpak-builtins-remote-list.c:241 app/flatpak-builtins-remote-ls.c:407
msgid "Too many arguments"
msgstr "Слишком много аргументов"

#: app/flatpak-builtins-build-bundle.c:659
#: app/flatpak-builtins-build-commit-from.c:338
#: app/flatpak-builtins-build-commit-from.c:351
#: app/flatpak-builtins-build-import-bundle.c:145
#, c-format
msgid "'%s' is not a valid repository"
msgstr "'%s' не является корректным репозиторием"

#: app/flatpak-builtins-build-bundle.c:663
#, c-format
msgid "'%s' is not a valid repository: "
msgstr "'%s' не является корректным репозиторием: "

#: app/flatpak-builtins-build-bundle.c:674 app/flatpak-builtins-build-sign.c:88
#: common/flatpak-dir.c:14293
#, c-format
msgid "'%s' is not a valid name: %s"
msgstr "'%s' не является корректным именем: %s"

#: app/flatpak-builtins-build-bundle.c:677
#: app/flatpak-builtins-build-export.c:865 app/flatpak-builtins-build-sign.c:91
#: common/flatpak-dir.c:14299
#, c-format
msgid "'%s' is not a valid branch name: %s"
msgstr "'%s' не является корректным именем ветви: %s"

#: app/flatpak-builtins-build-bundle.c:691
#: app/flatpak-builtins-build-import-bundle.c:149
#: app/flatpak-builtins-build-init.c:281
#, c-format
msgid "'%s' is not a valid filename"
msgstr "'%s' не является корректным именем файла"

#: app/flatpak-builtins-build-bundle.c:706
msgid "--oci-layer-compress value must be gzip or zstd"
msgstr ""

#: app/flatpak-builtins-build.c:49
msgid "Use Platform runtime rather than Sdk"
msgstr "Использовать обычную среду выполнения вместо отладочной"

#: app/flatpak-builtins-build.c:50
msgid "Make destination readonly"
msgstr "Сделать доступной только для чтения"

#: app/flatpak-builtins-build.c:51
msgid "Add bind mount"
msgstr "Добавить связанную точку монтирования"

#: app/flatpak-builtins-build.c:51
msgid "DEST=SRC"
msgstr "НАЗНАЧЕНИЕ=ИСТОЧНИК"

#: app/flatpak-builtins-build.c:52
msgid "Start build in this directory"
msgstr "Начать сборку в указанном каталоге"

#: app/flatpak-builtins-build.c:52 app/flatpak-builtins-build.c:53
#: app/flatpak-builtins-build-init.c:64 app/flatpak-builtins-run.c:160
msgid "DIR"
msgstr "КАТАЛОГ"

#: app/flatpak-builtins-build.c:53
msgid "Where to look for custom sdk dir (defaults to 'usr')"
msgstr "Где искать модифицированный каталог sdk (по умолчанию 'usr')"

#: app/flatpak-builtins-build.c:54 app/flatpak-builtins-build-export.c:67
msgid "Use alternative file for the metadata"
msgstr "Использовать другой файл метаданных"

#: app/flatpak-builtins-build.c:55 app/flatpak-builtins-run.c:177
msgid "Kill processes when the parent process dies"
msgstr "Убить процессы, когда родительский процесс умирает"

#: app/flatpak-builtins-build.c:56
msgid "Export application homedir directory to build"
msgstr "Экспортировать домашний каталог приложения для сборки"

#: app/flatpak-builtins-build.c:57 app/flatpak-builtins-run.c:165
msgid "Log session bus calls"
msgstr "Журналировать вызовы пользовательской шины"

#: app/flatpak-builtins-build.c:58 app/flatpak-builtins-run.c:166
msgid "Log system bus calls"
msgstr "Журналировать вызовы системной шины"

#: app/flatpak-builtins-build.c:262
msgid "DIRECTORY [COMMAND [ARGUMENT…]] - Build in directory"
msgstr "КАТАЛОГ [КОМАНДА [параметры...]] - Сборка в каталоге"

#: app/flatpak-builtins-build.c:285 app/flatpak-builtins-build-finish.c:656
msgid "DIRECTORY must be specified"
msgstr "Должен быть указан КАТАЛОГ"

#: app/flatpak-builtins-build.c:296 app/flatpak-builtins-build-export.c:887
#, c-format
msgid "Build directory %s not initialized, use flatpak build-init"
msgstr ""
"Каталог сборки %s не инициализирован, воспользуйтесь flatpak build-init"

#: app/flatpak-builtins-build.c:315
msgid "metadata invalid, not application or runtime"
msgstr ""
"некорректные метаданные, не является ни приложением, ни средой выполнения"

#: app/flatpak-builtins-build.c:446
#, c-format
msgid "No extension point matching %s in %s"
msgstr "Не найдена точка расширения, подходящая для %s в %s"

#: app/flatpak-builtins-build.c:635
#, c-format
msgid "Missing '=' in bind mount option '%s'"
msgstr "Отсутствует '=' в параметре связанного монтирования '%s'"

#: app/flatpak-builtins-build.c:679 common/flatpak-run.c:3961
#, c-format
msgid "Unable to start app"
msgstr "Невозможно запустить приложение"

#: app/flatpak-builtins-build-commit-from.c:58
msgid "Source repo dir"
msgstr "Каталог репозитория-источника"

#: app/flatpak-builtins-build-commit-from.c:58
msgid "SRC-REPO"
msgstr "ИСТ-РЕПО"

#: app/flatpak-builtins-build-commit-from.c:59
msgid "Source repo ref"
msgstr "Ссылка репозитория-источника"

#: app/flatpak-builtins-build-commit-from.c:59
msgid "SRC-REF"
msgstr "ИСТ-ССЫЛ"

#: app/flatpak-builtins-build-commit-from.c:64
#: app/flatpak-builtins-build-export.c:60
msgid "One line subject"
msgstr "Тема в одну строку"

#: app/flatpak-builtins-build-commit-from.c:64
#: app/flatpak-builtins-build-export.c:60
msgid "SUBJECT"
msgstr "ТЕМА"

#: app/flatpak-builtins-build-commit-from.c:65
#: app/flatpak-builtins-build-export.c:61
msgid "Full description"
msgstr "Полное описание"

#: app/flatpak-builtins-build-commit-from.c:65
#: app/flatpak-builtins-build-export.c:61
msgid "BODY"
msgstr "СОДЕРЖИМОЕ"

#: app/flatpak-builtins-build-commit-from.c:66
#: app/flatpak-builtins-build-export.c:64
#: app/flatpak-builtins-build-import-bundle.c:51
msgid "Update the appstream branch"
msgstr "Обновить ветвь appstream"

#: app/flatpak-builtins-build-commit-from.c:67
#: app/flatpak-builtins-build-export.c:65
#: app/flatpak-builtins-build-import-bundle.c:52
#: app/flatpak-builtins-build-update-repo.c:87
msgid "Don't update the summary"
msgstr "Не обновлять сводную информацию"

#: app/flatpak-builtins-build-commit-from.c:68
#: app/flatpak-builtins-build-export.c:68
#: app/flatpak-builtins-build-import-bundle.c:49
#: app/flatpak-builtins-build-sign.c:44
msgid "GPG Key ID to sign the commit with"
msgstr "ID ключа GPG для подписи коммита"

#: app/flatpak-builtins-build-commit-from.c:70
#: app/flatpak-builtins-build-export.c:73
msgid "Mark build as end-of-life"
msgstr "Пометить сборку как окончившую срок поддержки"

#: app/flatpak-builtins-build-commit-from.c:70
#: app/flatpak-builtins-build-export.c:73
msgid "REASON"
msgstr "ПРИЧИНА"

#: app/flatpak-builtins-build-commit-from.c:71
msgid ""
"Mark refs matching the OLDID prefix as end-of-life, to be replaced with the "
"given NEWID"
msgstr ""
"Пометить ссылки, совпадающие с префиксом СТАР_ID, как заменённые на НОВ_ID и "
"более не поддерживаемые"

#: app/flatpak-builtins-build-commit-from.c:71
msgid "OLDID=NEWID"
msgstr "СТАР_ID=НОВ_ID"

#: app/flatpak-builtins-build-commit-from.c:72
#: app/flatpak-builtins-build-export.c:75
msgid "Set type of token needed to install this commit"
msgstr "Задать тип токена, нужного для установки данного коммита"

#: app/flatpak-builtins-build-commit-from.c:72
#: app/flatpak-builtins-build-export.c:75
msgid "VAL"
msgstr "ЗНАЧ"

#: app/flatpak-builtins-build-commit-from.c:73
msgid "Override the timestamp of the commit (NOW for current time)"
msgstr "Переназначить отметку времени коммита (NOW для текущего времени)"

#: app/flatpak-builtins-build-commit-from.c:73
#: app/flatpak-builtins-build-export.c:76
msgid "TIMESTAMP"
msgstr "ВРЕМ_МЕТКА"

#: app/flatpak-builtins-build-commit-from.c:75
#: app/flatpak-builtins-build-export.c:80
#: app/flatpak-builtins-build-import-bundle.c:53
#: app/flatpak-builtins-build-update-repo.c:97
msgid "Don't generate a summary index"
msgstr "Не создавать индекс сводки"

#: app/flatpak-builtins-build-commit-from.c:278
msgid "DST-REPO [DST-REF…] - Make a new commit from existing commits"
msgstr ""
"НАЗН-РЕПО [НАЗН-ССЫЛКА]... - Сделать новый коммит на основе существующеих "
"коммитов"

#: app/flatpak-builtins-build-commit-from.c:285
msgid "DST-REPO must be specified"
msgstr "Должен быть указан НАЗН-РЕПО"

#: app/flatpak-builtins-build-commit-from.c:293
msgid ""
"If --src-repo is not specified, exactly one destination ref must be specified"
msgstr ""
"Если --src-repo не задана, должна быть указана ровно одна ссылка назначения"

#: app/flatpak-builtins-build-commit-from.c:296
msgid ""
"If --src-ref is specified, exactly one destination ref must be specified"
msgstr ""
"Если --src-ref задана, должна быть указана ровно одна ссылка назначения"

#: app/flatpak-builtins-build-commit-from.c:299
msgid "Either --src-repo or --src-ref must be specified"
msgstr "Необходимо указать либо --src-repo, либо --src-ref"

#: app/flatpak-builtins-build-commit-from.c:315
msgid "Invalid argument format of use  --end-of-life-rebase=OLDID=NEWID"
msgstr "Неверный формат аргумента для --end-of-life-rebase=СТАР_ID=НОВ_ID"

#: app/flatpak-builtins-build-commit-from.c:321
#: app/flatpak-builtins-build-commit-from.c:324
#, c-format
msgid "Invalid name %s in --end-of-life-rebase"
msgstr "Неверное имя %s в --end-of-life-rebase"

#: app/flatpak-builtins-build-commit-from.c:333
#: app/flatpak-builtins-build-export.c:1092
#, c-format
msgid "Could not parse '%s'"
msgstr "Невозможно разобрать '%s'"

#: app/flatpak-builtins-build-commit-from.c:498
msgid "Can't commit from partial source commit"
msgstr "Невозможно сделать коммит из частичного исходного коммита"

#: app/flatpak-builtins-build-commit-from.c:503
#, c-format
msgid "%s: no change\n"
msgstr "%s: не изменено\n"

#: app/flatpak-builtins-build-export.c:62
msgid "Architecture to export for (must be host compatible)"
msgstr "Имя архитектуры для экспорта (должна быть совместима с хостом)"

#: app/flatpak-builtins-build-export.c:63
msgid "Commit runtime (/usr), not /app"
msgstr "Зафиксировать среду выполнения (/usr), не /app"

#: app/flatpak-builtins-build-export.c:66
msgid "Use alternative directory for the files"
msgstr "Использовать другой каталог для файлов"

#: app/flatpak-builtins-build-export.c:66
msgid "SUBDIR"
msgstr "ПОДКАТАЛОГ"

#: app/flatpak-builtins-build-export.c:69
msgid "Files to exclude"
msgstr "Исключить файлы"

#: app/flatpak-builtins-build-export.c:69
#: app/flatpak-builtins-build-export.c:70
#: app/flatpak-builtins-build-update-repo.c:90
msgid "PATTERN"
msgstr "ШАБЛОН"

#: app/flatpak-builtins-build-export.c:70
msgid "Excluded files to include"
msgstr "Исключенные файлы для добавления"

#: app/flatpak-builtins-build-export.c:74
msgid "Mark build as end-of-life, to be replaced with the given ID"
msgstr "Отметить сборку как заменённую указанным ID и более не поддерживаемую"

#: app/flatpak-builtins-build-export.c:74
#: app/flatpak-builtins-document-list.c:49 app/flatpak-cli-transaction.c:1427
msgid "ID"
msgstr "ID"

#: app/flatpak-builtins-build-export.c:76
msgid "Override the timestamp of the commit"
msgstr "Переназначить отметку времени коммита"

#: app/flatpak-builtins-build-export.c:77
#: app/flatpak-builtins-build-update-repo.c:75
#: app/flatpak-builtins-remote-add.c:83 app/flatpak-builtins-remote-list.c:54
#: app/flatpak-builtins-remote-modify.c:88
msgid "Collection ID"
msgstr "ID коллекции"

#: app/flatpak-builtins-build-export.c:472
#, c-format
msgid "WARNING: Error running desktop-file-validate: %s\n"
msgstr "ПРЕДУПРЕЖДЕНИЕ: Ошибка выполнения desktop-file-validate: %s\n"

#: app/flatpak-builtins-build-export.c:480
#, c-format
msgid "WARNING: Error reading from desktop-file-validate: %s\n"
msgstr "ПРЕДУПРЕЖДЕНИЕ: Ошибка чтения из desktop-file-validate: %s\n"

#: app/flatpak-builtins-build-export.c:486
#, c-format
msgid "WARNING: Failed to validate desktop file %s: %s\n"
msgstr "ПРЕДУПРЕЖДЕНИЕ: Ошибка при проверке файла desktop %s: %s\n"

#: app/flatpak-builtins-build-export.c:513
#, c-format
msgid "WARNING: Can't find Exec key in %s: %s\n"
msgstr "ПРЕДУПРЕЖДЕНИЕ: не найден Exec ключ в %s: %s\n"

#: app/flatpak-builtins-build-export.c:521
#: app/flatpak-builtins-build-export.c:614
#, c-format
msgid "WARNING: Binary not found for Exec line in %s: %s\n"
msgstr ""
"ПРЕДУПРЕЖДЕНИЕ: программа %s, указанная в строке Exec, не найдена: %s\n"

#: app/flatpak-builtins-build-export.c:529
#, c-format
msgid "WARNING: Icon not matching app id in %s: %s\n"
msgstr "ПРЕДУПРЕЖДЕНИЕ: иконка %s не совпадает с ID приложения: %s\n"

#: app/flatpak-builtins-build-export.c:552
#, c-format
msgid "WARNING: Icon referenced in desktop file but not exported: %s\n"
msgstr ""
"ПРЕДУПРЕЖДЕНИЕ: иконка прописана в файле desktop, но не экспортирована: %s\n"

#: app/flatpak-builtins-build-export.c:719
#, c-format
msgid "Invalid uri type %s, only http/https supported"
msgstr "Некорректный тип uri %s, поддерживается только http/https"

#: app/flatpak-builtins-build-export.c:737
#, c-format
msgid "Unable to find basename in %s, specify a name explicitly"
msgstr "Невозможно найти базовое имя в %s, укажите его"

#: app/flatpak-builtins-build-export.c:746
#, c-format
msgid "No slashes allowed in extra data name"
msgstr ""
"Не разрешается использовать символ '/' в названии дополнительных данных"

#: app/flatpak-builtins-build-export.c:758
#, c-format
msgid "Invalid format for sha256 checksum: '%s'"
msgstr "Неверный формат контрольной суммы sha256: '%s'"

#: app/flatpak-builtins-build-export.c:768
#, c-format
msgid "Extra data sizes of zero not supported"
msgstr "Дополнительные данные нулевого размера не поддерживаются"

#: app/flatpak-builtins-build-export.c:830
msgid ""
"LOCATION DIRECTORY [BRANCH] - Create a repository from a build directory"
msgstr "ПУТЬ КАТАЛОГ [ВЕТВЬ] - Создать репозиторий из каталога сборки"

#: app/flatpak-builtins-build-export.c:838
msgid "LOCATION and DIRECTORY must be specified"
msgstr "Должны быть указаны ПУТЬ и КАТАЛОГ"

#: app/flatpak-builtins-build-export.c:859
#: app/flatpak-builtins-remote-add.c:327
#, c-format
msgid "‘%s’ is not a valid collection ID: %s"
msgstr "'%s' не является корректным ID коллекции: %s"

#: app/flatpak-builtins-build-export.c:904
#: app/flatpak-builtins-build-finish.c:684
msgid "No name specified in the metadata"
msgstr "Не указано имя в метаданных"

#: app/flatpak-builtins-build-export.c:1166
#, c-format
msgid "Commit: %s\n"
msgstr "Коммит: %s\n"

#: app/flatpak-builtins-build-export.c:1167
#, c-format
msgid "Metadata Total: %u\n"
msgstr "Всего метаданных: %u\n"

#: app/flatpak-builtins-build-export.c:1168
#, c-format
msgid "Metadata Written: %u\n"
msgstr "Записано метаданных: %u\n"

#: app/flatpak-builtins-build-export.c:1169
#, c-format
msgid "Content Total: %u\n"
msgstr "Всего данных: %u\n"

#: app/flatpak-builtins-build-export.c:1170
#, c-format
msgid "Content Written: %u\n"
msgstr "Данных записано: %u\n"

#: app/flatpak-builtins-build-export.c:1171
#, c-format
msgid "Content Bytes Written:"
msgstr "Байтов контента записано:"

#: app/flatpak-builtins-build-finish.c:52
msgid "Command to set"
msgstr "Указать команду"

#: app/flatpak-builtins-build-finish.c:52 app/flatpak-builtins-run.c:159
#: app/flatpak-main.c:209
msgid "COMMAND"
msgstr "КОМАНДА"

#: app/flatpak-builtins-build-finish.c:53
msgid "Flatpak version to require"
msgstr "Какую версию flatpak требовать"

#: app/flatpak-builtins-build-finish.c:53
msgid "MAJOR.MINOR.MICRO"
msgstr "ЗНАЧИТЕЛЬНАЯ.МИНОРНАЯ.МИКРО"

#: app/flatpak-builtins-build-finish.c:54
msgid "Don't process exports"
msgstr "Не обрабатывать экспортируемое"

#: app/flatpak-builtins-build-finish.c:55
msgid "Extra data info"
msgstr "Информация о дополнительных данных"

#: app/flatpak-builtins-build-finish.c:56 app/flatpak-builtins-build-init.c:63
msgid "Add extension point info"
msgstr "Добавить информацию о точке расширения"

#: app/flatpak-builtins-build-finish.c:56 app/flatpak-builtins-build-init.c:63
msgid "NAME=VARIABLE[=VALUE]"
msgstr "ИМЯ=ПЕРЕМЕННАЯ[=ЗНАЧЕНИЕ]"

#: app/flatpak-builtins-build-finish.c:57
msgid "Remove extension point info"
msgstr "Удалить информацию о точке расширения"

#: app/flatpak-builtins-build-finish.c:57
#: app/flatpak-builtins-build-update-repo.c:79 app/flatpak-builtins-info.c:58
#: app/flatpak-builtins-remote-add.c:88 app/flatpak-builtins-remote-modify.c:94
#: app/flatpak-main.c:182
msgid "NAME"
msgstr "ИМЯ"

#: app/flatpak-builtins-build-finish.c:58
msgid "Set extension priority (only for extensions)"
msgstr "Установить приоритет расширения (только для расширений)"

#: app/flatpak-builtins-build-finish.c:58
msgid "VALUE"
msgstr "ЗНАЧЕНИЕ"

#: app/flatpak-builtins-build-finish.c:59
msgid "Change the sdk used for the app"
msgstr "Заменить sdk, используемый приложением"

#: app/flatpak-builtins-build-finish.c:59
msgid "SDK"
msgstr "SDK"

#: app/flatpak-builtins-build-finish.c:60
msgid "Change the runtime used for the app"
msgstr "Заменить среду выполнения, используемую приложением"

#: app/flatpak-builtins-build-finish.c:60 app/flatpak-builtins-build-init.c:54
#: app/flatpak-builtins-list.c:53 app/flatpak-builtins-remote-ls.c:58
#: app/flatpak-builtins-run.c:163
msgid "RUNTIME"
msgstr "СРЕДА_ВЫПОЛНЕНИЯ"

#: app/flatpak-builtins-build-finish.c:61
msgid "Set generic metadata option"
msgstr "Установить параметр обобщенной политики"

#: app/flatpak-builtins-build-finish.c:61
msgid "GROUP=KEY[=VALUE]"
msgstr "ГРУППА=КЛЮЧ[=ЗНАЧЕНИЕ]"

#: app/flatpak-builtins-build-finish.c:62
msgid "Don't inherit permissions from runtime"
msgstr "Не наследовать разрешения из среды выполнения"

#: app/flatpak-builtins-build-finish.c:155
#, c-format
msgid "Not exporting %s, wrong extension\n"
msgstr "Не экспортируется %s, некорректное расширение\n"

#: app/flatpak-builtins-build-finish.c:163
#, c-format
msgid "Not exporting %s, non-allowed export filename\n"
msgstr "Не экспортируется %s, не разрешенное имя файла\n"

#: app/flatpak-builtins-build-finish.c:167
#, c-format
msgid "Exporting %s\n"
msgstr "Экспортирую %s\n"

#: app/flatpak-builtins-build-finish.c:440
#, c-format
msgid "More than one executable found\n"
msgstr "Найдено больше одного исполняемого файла\n"

#: app/flatpak-builtins-build-finish.c:451
#, c-format
msgid "Using %s as command\n"
msgstr "Использовать %s как команду\n"

#: app/flatpak-builtins-build-finish.c:456
#, c-format
msgid "No executable found\n"
msgstr "Не найдено исполняемых файлов\n"

#: app/flatpak-builtins-build-finish.c:511
#, c-format
msgid "Invalid --require-version argument: %s"
msgstr "Неверный аргумент --require-version: %s"

#: app/flatpak-builtins-build-finish.c:543
#, c-format
msgid "Too few elements in --extra-data argument %s"
msgstr "Слишком мало элементов у параметра --extra-data %s"

#: app/flatpak-builtins-build-finish.c:575
#, c-format
msgid ""
"Too few elements in --metadata argument %s, format should be "
"GROUP=KEY[=VALUE]]"
msgstr ""
"Слишком мало элементов в аргументе --metadata %s, формат должен иметь вид "
"ГРУППА=КЛЮЧ[=ЗНАЧЕНИЕ]"

#: app/flatpak-builtins-build-finish.c:597
#: app/flatpak-builtins-build-init.c:458
#, c-format
msgid ""
"Too few elements in --extension argument %s, format should be "
"NAME=VAR[=VALUE]"
msgstr ""
"Слишком мало элементов в аргументе --extension %s, формат должен иметь вид "
"ИМЯ=ПЕРЕМЕННАЯ[=ЗНАЧЕНИЕ]"

#: app/flatpak-builtins-build-finish.c:603
#: app/flatpak-builtins-build-init.c:461
#, c-format
msgid "Invalid extension name %s"
msgstr "Некорректное имя расширения %s"

#: app/flatpak-builtins-build-finish.c:646
msgid "DIRECTORY - Finalize a build directory"
msgstr "КАТАЛОГ - Финализировать каталог сборки"

#: app/flatpak-builtins-build-finish.c:668
#, c-format
msgid "Build directory %s not initialized"
msgstr "Каталог сборки %s не инициализирован"

#: app/flatpak-builtins-build-finish.c:689
#, c-format
msgid "Build directory %s already finalized"
msgstr "Каталог сборки %s уже финализирован"

#: app/flatpak-builtins-build-finish.c:702
#, c-format
msgid "Please review the exported files and the metadata\n"
msgstr "Пожалуйста, перепроверьте экспортированные файлы и метаданные\n"

#: app/flatpak-builtins-build-import-bundle.c:47
msgid "Override the ref used for the imported bundle"
msgstr "Переопределить ссылку на импортированный пакет"

#: app/flatpak-builtins-build-import-bundle.c:47
msgid "REF"
msgstr "ССЫЛКА"

#: app/flatpak-builtins-build-import-bundle.c:48
msgid "Import oci image instead of flatpak bundle"
msgstr "Импортировать образ oci вместо пакета flatpak"

#: app/flatpak-builtins-build-import-bundle.c:77
#: app/flatpak-builtins-build-import-bundle.c:105
#, c-format
msgid "Importing %s (%s)\n"
msgstr "Импорт: %s (%s)\n"

#: app/flatpak-builtins-build-import-bundle.c:126
msgid "LOCATION FILENAME - Import a file bundle into a local repository"
msgstr "ПУТЬ ИМЯ_ФАЙЛА - Импортировать файл с пакетом в локальный репозиторий"

#: app/flatpak-builtins-build-import-bundle.c:133
msgid "LOCATION and FILENAME must be specified"
msgstr "Должны быть указаны ПУТЬ и ИМЯ_ФАЙЛА"

#: app/flatpak-builtins-build-init.c:53 app/flatpak-builtins-info.c:55
#: app/flatpak-builtins-run.c:158
msgid "Arch to use"
msgstr "Используемая архитектура"

#: app/flatpak-builtins-build-init.c:54
msgid "Initialize var from named runtime"
msgstr "Инициализировать переменую из названной среды выполнения"

#: app/flatpak-builtins-build-init.c:55
msgid "Initialize apps from named app"
msgstr "Инициализировать приложения из названного приложения"

#: app/flatpak-builtins-build-init.c:55
msgid "APP"
msgstr "ПРИЛОЖЕНИЕ"

#: app/flatpak-builtins-build-init.c:56
msgid "Specify version for --base"
msgstr "Версия приложения для параметра --base"

#: app/flatpak-builtins-build-init.c:56 app/flatpak-builtins-run.c:164
msgid "VERSION"
msgstr "ВЕРСИЯ"

#: app/flatpak-builtins-build-init.c:57
msgid "Include this base extension"
msgstr "Включить указанное базовое расширение"

#: app/flatpak-builtins-build-init.c:57 app/flatpak-builtins-build-init.c:62
msgid "EXTENSION"
msgstr "РАСШИРЕНИЕ"

#: app/flatpak-builtins-build-init.c:58
msgid "Extension tag to use if building extension"
msgstr "Метка расширения для использования в случае сборки расширения"

#: app/flatpak-builtins-build-init.c:58
msgid "EXTENSION_TAG"
msgstr "МЕТКА_РАСШИРЕНИЯ"

#: app/flatpak-builtins-build-init.c:59
msgid "Initialize /usr with a writable copy of the sdk"
msgstr "Инициализировать каталог /usr с доступной для записи копией sdk"

#: app/flatpak-builtins-build-init.c:60
msgid "Specify the build type (app, runtime, extension)"
msgstr "Укажите тип сборки (app, runtime, extension)"

#: app/flatpak-builtins-build-init.c:60
msgid "TYPE"
msgstr "ТИП"

#: app/flatpak-builtins-build-init.c:61
msgid "Add a tag"
msgstr "Добавить метку"

#: app/flatpak-builtins-build-init.c:61
msgid "TAG"
msgstr "МЕТКА"

#: app/flatpak-builtins-build-init.c:62
msgid "Include this sdk extension in /usr"
msgstr "Включить указанное расширение sdk в каталог /usr"

#: app/flatpak-builtins-build-init.c:64
msgid "Where to store sdk (defaults to 'usr')"
msgstr "Путь к sdk (по умолчанию 'usr')"

#: app/flatpak-builtins-build-init.c:65
msgid "Re-initialize the sdk/var"
msgstr "Переинициализировать sdk/окружение"

#: app/flatpak-builtins-build-init.c:118
#, c-format
msgid "Requested extension %s/%s/%s is only partially installed"
msgstr "Требуемое расширение %s/%s/%s установлено частично"

#: app/flatpak-builtins-build-init.c:147
#, c-format
msgid "Requested extension %s/%s/%s not installed"
msgstr "Требуемое расширение %s/%s/%s не установлено"

#: app/flatpak-builtins-build-init.c:207
msgid ""
"DIRECTORY APPNAME SDK RUNTIME [BRANCH] - Initialize a directory for building"
msgstr ""
"КАТАЛОГ ИМЯ_ПРИЛОЖЕНИЯ SDK СРЕДА_ВЫП [ВЕТВЬ] - Инициализировать каталог для "
"сборки"

#: app/flatpak-builtins-build-init.c:214
msgid "RUNTIME must be specified"
msgstr "Должна быть указана СРЕДА_ВЫП"

#: app/flatpak-builtins-build-init.c:235
#, c-format
msgid "'%s' is not a valid build type name, use app, runtime or extension"
msgstr ""
"'%s' не является корректным именем для типа сборки, укажите приложение, "
"среду выполнения или расширение"

#: app/flatpak-builtins-build-init.c:241 app/flatpak-builtins-override.c:79
#, c-format
msgid "'%s' is not a valid application name: %s"
msgstr "'%s' не является корректным именем приложения: %s"

#: app/flatpak-builtins-build-init.c:295
#, c-format
msgid "Build directory %s already initialized"
msgstr "Каталог сборки %s уже инициализирован"

#: app/flatpak-builtins-build-sign.c:42 app/flatpak-builtins-install.c:67
#: app/flatpak-builtins-remote-info.c:54
msgid "Arch to install for"
msgstr "Архитектура для установки"

#: app/flatpak-builtins-build-sign.c:43 app/flatpak-builtins-create-usb.c:48
#: app/flatpak-builtins-install.c:74 app/flatpak-builtins-remote-info.c:56
#: app/flatpak-builtins-uninstall.c:58 app/flatpak-builtins-update.c:64
msgid "Look for runtime with the specified name"
msgstr "Искать среду выполнения с указанным именем"

#: app/flatpak-builtins-build-sign.c:66
msgid "LOCATION [ID [BRANCH]] - Sign an application or runtime"
msgstr "ПУТЬ [ID [ВЕТВЬ]] - Подписать приложение или среду выполнения"

#: app/flatpak-builtins-build-sign.c:73
#: app/flatpak-builtins-build-update-repo.c:499
#: app/flatpak-builtins-remote-add.c:320 app/flatpak-builtins-repo.c:739
msgid "LOCATION must be specified"
msgstr "Должен быть указан ПУТЬ"

#: app/flatpak-builtins-build-sign.c:94
msgid "No gpg key ids specified"
msgstr "Ключ/ключи GPG не указаны"

#: app/flatpak-builtins-build-update-repo.c:68
msgid "Redirect this repo to a new URL"
msgstr "Перенаправить этот репозиторий на новый адрес"

#: app/flatpak-builtins-build-update-repo.c:69
msgid "A nice name to use for this repository"
msgstr "Красивое имя для репозитория"

#: app/flatpak-builtins-build-update-repo.c:69
#: app/flatpak-builtins-remote-add.c:77 app/flatpak-builtins-remote-modify.c:82
msgid "TITLE"
msgstr "ЗАГОЛОВОК"

#: app/flatpak-builtins-build-update-repo.c:70
msgid "A one-line comment for this repository"
msgstr "Комментарий к этому репозиторию в одну строку"

#: app/flatpak-builtins-build-update-repo.c:70
#: app/flatpak-builtins-remote-add.c:78 app/flatpak-builtins-remote-modify.c:83
msgid "COMMENT"
msgstr "КОММЕНТАРИЙ"

#: app/flatpak-builtins-build-update-repo.c:71
msgid "A full-paragraph description for this repository"
msgstr "Полное описание этого репозитория"

#: app/flatpak-builtins-build-update-repo.c:71
#: app/flatpak-builtins-remote-add.c:79 app/flatpak-builtins-remote-modify.c:84
msgid "DESCRIPTION"
msgstr "ОПИСАНИЕ"

#: app/flatpak-builtins-build-update-repo.c:72
msgid "URL for a website for this repository"
msgstr "URL веб-сайта этого репозитория"

#: app/flatpak-builtins-build-update-repo.c:73
msgid "URL for an icon for this repository"
msgstr "URL логотипа этого репозитория"

#: app/flatpak-builtins-build-update-repo.c:74
msgid "Default branch to use for this repository"
msgstr "Ветвь по умолчанию для репозитория"

#: app/flatpak-builtins-build-update-repo.c:74
#: app/flatpak-builtins-remote-add.c:82 app/flatpak-builtins-remote-modify.c:87
#: app/flatpak-builtins-repo.c:713 app/flatpak-builtins-repo.c:714
#: app/flatpak-builtins-run.c:161
msgid "BRANCH"
msgstr "ВЕТВЬ"

#: app/flatpak-builtins-build-update-repo.c:75
#: app/flatpak-builtins-remote-add.c:83 app/flatpak-builtins-remote-modify.c:88
msgid "COLLECTION-ID"
msgstr "ID-КОЛЛЕКЦИИ"

#. Translators: A sideload is when you install from a local USB drive rather than the Internet.
#: app/flatpak-builtins-build-update-repo.c:77
msgid ""
"Permanently deploy collection ID to client remote configurations, only for "
"sideload support"
msgstr ""
"Постоянно загружать ID коллекции в клиентские удаленные конфигурации, только "
"для поддержки параллельной загрузки"

#: app/flatpak-builtins-build-update-repo.c:78
msgid "Permanently deploy collection ID to client remote configurations"
msgstr "Постоянно загружать ID коллекции в клиентские удаленные конфигурации"

#: app/flatpak-builtins-build-update-repo.c:79
msgid "Name of authenticator for this repository"
msgstr "Имя аутентификатора для этого репозитория"

#: app/flatpak-builtins-build-update-repo.c:80
msgid "Autoinstall authenticator for this repository"
msgstr "Автоматически установливать аутентификатор для этого репозитория"

#: app/flatpak-builtins-build-update-repo.c:81
msgid "Don't autoinstall authenticator for this repository"
msgstr "Не установливать автоматически аутентификатор для этого репозитория"

#: app/flatpak-builtins-build-update-repo.c:82
#: app/flatpak-builtins-remote-add.c:89
msgid "Authenticator option"
msgstr "Параметр аутентификатора"

#: app/flatpak-builtins-build-update-repo.c:82
#: app/flatpak-builtins-remote-add.c:89 app/flatpak-builtins-remote-modify.c:95
msgid "KEY=VALUE"
msgstr "КЛЮЧ=ЗНАЧЕНИЕ"

#: app/flatpak-builtins-build-update-repo.c:83
msgid "Import new default GPG public key from FILE"
msgstr ""
"Импортировать новый используемый по умолчанию публичный ключ GPG из ФАЙЛА"

#: app/flatpak-builtins-build-update-repo.c:84
msgid "GPG Key ID to sign the summary with"
msgstr "ID Ключа GPG для подписи сводной информации"

#: app/flatpak-builtins-build-update-repo.c:86
msgid "Generate delta files"
msgstr "Создать дельта файлы"

#: app/flatpak-builtins-build-update-repo.c:88
msgid "Don't update the appstream branch"
msgstr "Не обновлять ветвь appstream"

#: app/flatpak-builtins-build-update-repo.c:89
msgid "Max parallel jobs when creating deltas (default: NUMCPUs)"
msgstr ""
"Максимальное число параллельных задач при создании дельт (по умолчанию: "
"число ЦПУ)"

#: app/flatpak-builtins-build-update-repo.c:89
msgid "NUM-JOBS"
msgstr "КОЛИЧЕСТВО-ЗАДАЧ"

#: app/flatpak-builtins-build-update-repo.c:90
msgid "Don't create deltas matching refs"
msgstr "Не создавать дельты, совпадающие со ссылками"

#: app/flatpak-builtins-build-update-repo.c:91
msgid "Prune unused objects"
msgstr "Очистить неиспользуемые объекты"

#: app/flatpak-builtins-build-update-repo.c:92
msgid "Prune but don't actually remove anything"
msgstr "Очистить, но ничего не удалять"

#: app/flatpak-builtins-build-update-repo.c:93
msgid "Only traverse DEPTH parents for each commit (default: -1=infinite)"
msgstr ""
"Обходить только родителей DEPTH для каждого коммита (по умолчанию: "
"-1=бесконечное количество)."

#: app/flatpak-builtins-build-update-repo.c:93
msgid "DEPTH"
msgstr "ГЛУБИНА"

#: app/flatpak-builtins-build-update-repo.c:223
#, c-format
msgid "Generating delta: %s (%.10s)\n"
msgstr "Создание дельты: %s (%.10s)\n"

#: app/flatpak-builtins-build-update-repo.c:225
#, c-format
msgid "Generating delta: %s (%.10s-%.10s)\n"
msgstr "Создание дельты: %s (%.10s-%.10s)\n"

#: app/flatpak-builtins-build-update-repo.c:233
#, c-format
msgid "Failed to generate delta %s (%.10s): "
msgstr "Ошибка при создании дельты %s (%.10s): "

#: app/flatpak-builtins-build-update-repo.c:236
#, c-format
msgid "Failed to generate delta %s (%.10s-%.10s): "
msgstr "Ошибка при создании дельты %s (%.10s-%.10s): "

#: app/flatpak-builtins-build-update-repo.c:492
msgid "LOCATION - Update repository metadata"
msgstr "ПУТЬ - Обновить метаданные репозитория"

#: app/flatpak-builtins-build-update-repo.c:609
#, c-format
msgid "Updating appstream branch\n"
msgstr "Обновление ветви appstream\n"

#: app/flatpak-builtins-build-update-repo.c:638
#, c-format
msgid "Updating summary\n"
msgstr "Обновление сводной информации\n"

#: app/flatpak-builtins-build-update-repo.c:664
#, c-format
msgid "Total objects: %u\n"
msgstr "Всего объектов: %u\n"

#: app/flatpak-builtins-build-update-repo.c:666
#, c-format
msgid "No unreachable objects\n"
msgstr "Нет недоступных объектов\n"

#: app/flatpak-builtins-build-update-repo.c:668
#, c-format
msgid "Deleted %u objects, %s freed\n"
msgstr "Удалено %u объектов, %s освобождено\n"

#: app/flatpak-builtins-config.c:41
msgid "List configuration keys and values"
msgstr "Список конфигурационных ключей и значений"

#: app/flatpak-builtins-config.c:42
msgid "Get configuration for KEY"
msgstr "Получить конфигурацию для КЛЮЧА"

#: app/flatpak-builtins-config.c:43
msgid "Set configuration for KEY to VALUE"
msgstr "Установить конфигурацию для КЛЮЧА в ЗНАЧЕНИЕ"

#: app/flatpak-builtins-config.c:44
msgid "Unset configuration for KEY"
msgstr "Удалить конфигурацию КЛЮЧА"

#: app/flatpak-builtins-config.c:149
#, c-format
msgid "'%s' does not look like a language/locale code"
msgstr "'%s' не выглядит как код локали/языка"

#: app/flatpak-builtins-config.c:172
#, c-format
msgid "'%s' does not look like a language code"
msgstr "'%s' не выглядит как язык кода"

#: app/flatpak-builtins-config.c:190
#, fuzzy, c-format
msgid "'%s' is not a valid value (use 'true' or 'false')"
msgstr "'%s' не является корректным репозиторием: "

#: app/flatpak-builtins-config.c:262
#, c-format
msgid "Unknown configure key '%s'"
msgstr "Неизвестный конфигурационный ключ '%s'"

#: app/flatpak-builtins-config.c:284
msgid "Too many arguments for --list"
msgstr "Слишком много аргументов для --list"

#: app/flatpak-builtins-config.c:314 app/flatpak-builtins-config.c:362
msgid "You must specify KEY"
msgstr "Должен быть указан КЛЮЧ"

#: app/flatpak-builtins-config.c:316
msgid "Too many arguments for --get"
msgstr "Слишком много аргументов для --get"

#: app/flatpak-builtins-config.c:338
msgid "You must specify KEY and VALUE"
msgstr "Должны быть указаны КЛЮЧ И ЗНАЧЕНИЕ"

#: app/flatpak-builtins-config.c:340
msgid "Too many arguments for --set"
msgstr "Слишком много аргументов для --set"

#: app/flatpak-builtins-config.c:364
msgid "Too many arguments for --unset"
msgstr "Слишком много аргументов для --unset"

#: app/flatpak-builtins-config.c:383
msgid "[KEY [VALUE]] - Manage configuration"
msgstr "[КЛЮЧ [ЗНАЧЕНИЕ]] - Управление конфигурацией"

#: app/flatpak-builtins-config.c:394
msgid "Can only use one of --list, --get, --set or --unset"
msgstr "Можно использовать только одно из --list, --get, --set или --unset"

#: app/flatpak-builtins-config.c:408
msgid "Must specify one of --list, --get, --set or --unset"
msgstr "Необходимо указать одно из --list, --get, --set или --unset"

#: app/flatpak-builtins-create-usb.c:45 app/flatpak-builtins-install.c:75
#: app/flatpak-builtins-remote-info.c:57 app/flatpak-builtins-uninstall.c:59
#: app/flatpak-builtins-update.c:65
msgid "Look for app with the specified name"
msgstr "Искать приложение с указанным именем"

#: app/flatpak-builtins-create-usb.c:46
msgid "Arch to copy"
msgstr "Архитектура для копирования"

#: app/flatpak-builtins-create-usb.c:47
msgid "DEST"
msgstr "НАЗНАЧЕНИЕ"

#: app/flatpak-builtins-create-usb.c:49
msgid "Allow partial commits in the created repo"
msgstr "Разрешить частичные коммиты в созданном репозитории"

#: app/flatpak-builtins-create-usb.c:125 app/flatpak-builtins-create-usb.c:165
#, c-format
msgid ""
"Warning: Related ref ‘%s’ is partially installed. Use --allow-partial to "
"suppress this message.\n"
msgstr ""
"Предупреждение: Связанная ссылка '%s' установлена частично. Используйте --"
"allow-partial, чтобы скрыть это сообщение.\n"

#: app/flatpak-builtins-create-usb.c:158
#, c-format
msgid "Warning: Omitting related ref ‘%s’ because it is not installed.\n"
msgstr ""
"Предупреждение: Пропуск связанной ссылки ‘%s’, так как она не установлена.\n"

#: app/flatpak-builtins-create-usb.c:175
#, c-format
msgid ""
"Warning: Omitting related ref ‘%s’ because its remote ‘%s’ does not have a "
"collection ID set.\n"
msgstr ""
"Предупреждение: Пропуск связанной ссылки ‘%s’, так как у её удалённого "
"репозитория ‘%s’ не указан ID коллекции.\n"

#: app/flatpak-builtins-create-usb.c:187
#, c-format
msgid "Warning: Omitting related ref ‘%s’ because it's extra-data.\n"
msgstr ""
"Предупреждение: пропуск связанной ссылки '%s', потому что это extra-data.\n"

#: app/flatpak-builtins-create-usb.c:262 app/flatpak-builtins-create-usb.c:637
#, c-format
msgid ""
"Remote ‘%s’ does not have a collection ID set, which is required for P2P "
"distribution of ‘%s’."
msgstr ""
"У удалённого репозитория ‘%s’ не указан ID коллекции, который требуется для "
"распространения ‘%s’ с помощью P2P."

#: app/flatpak-builtins-create-usb.c:272
#, c-format
msgid "Warning: Omitting ref ‘%s’ (runtime of ‘%s’) because it's extra-data.\n"
msgstr ""
"Предупреждение: Пропуск ссылки '%s' (среда выполнения для ‘%s’), потому что "
"это extra-data.\n"

#: app/flatpak-builtins-create-usb.c:484
msgid "MOUNT-PATH [REF…] - Copy apps or runtimes onto removable media"
msgstr ""
"ПУТЬ-МОНТ [ССЫЛКА…] - Скопировать приложения или среды выполнения на съёмный "
"носитель"

#: app/flatpak-builtins-create-usb.c:493
msgid "MOUNT-PATH and REF must be specified"
msgstr "ПУТЬ-МОНТ и ССЫЛКА должны быть указаны"

#: app/flatpak-builtins-create-usb.c:607
#, c-format
msgid "Ref ‘%s’ found in multiple installations: %s. You must specify one."
msgstr ""
"Ссылка ‘%s’ найдена в нескольких установках: %s. Вы должны указать одну."

#: app/flatpak-builtins-create-usb.c:620
#, c-format
msgid "Refs must all be in the same installation (found in %s and %s)."
msgstr "Все ссылки должны быть в одном месте установки (найдено в %s и %s)."

#: app/flatpak-builtins-create-usb.c:670
#, c-format
msgid ""
"Warning: Ref ‘%s’ is partially installed. Use --allow-partial to suppress "
"this message.\n"
msgstr ""
"Предупреждение: Ссылка '%s' установлена частично. Используйте --allow-"
"partial, чтобы убрать это сообщение.\n"

#: app/flatpak-builtins-create-usb.c:681
#, c-format
msgid "Installed ref ‘%s’ is extra-data, and cannot be distributed offline"
msgstr ""
"Установленная ссылка ‘%s’ является extra-data и не может распространяться "
"оффлайн"

#: app/flatpak-builtins-create-usb.c:721
#, c-format
msgid "Warning: Couldn't update repo metadata for remote ‘%s’: %s\n"
msgstr ""
"Предупреждение: Невозможно обновить метаданные для удалённого репозитория "
"‘%s’: %s\n"

#: app/flatpak-builtins-create-usb.c:751
#, c-format
msgid "Warning: Couldn't update appstream data for remote ‘%s’ arch ‘%s’: %s\n"
msgstr ""
"Предупреждение: Невозможно обновить данные appstream для удалённого "
"репозитория ‘%s’ архитектуры ‘%s’: %s\n"

#. Print a warning if both appstream and appstream2 are missing
#: app/flatpak-builtins-create-usb.c:784
#, c-format
msgid ""
"Warning: Couldn't find appstream data for remote ‘%s’ arch ‘%s’: %s; %s\n"
msgstr ""
"Предупреждение: Не найдены данные appstream для удалённого репозитория ‘%s’ "
"архитектуры ‘%s’: %s; %s\n"

#. Appstream2 is only for efficiency, so just print a debug message
#: app/flatpak-builtins-create-usb.c:790
#, c-format
msgid "Couldn't find appstream2 data for remote ‘%s’ arch ‘%s’: %s\n"
msgstr ""
"Не найдены данные appstream2 для удалённого репозитория ‘%s’ архитектуры "
"‘%s’: %s\n"

#: app/flatpak-builtins-document-export.c:62
msgid "Create a unique document reference"
msgstr "Создать уникальную ссылку на документ"

#: app/flatpak-builtins-document-export.c:63
msgid "Make the document transient for the current session"
msgstr "Сделать документ временным для текущей сессии"

#: app/flatpak-builtins-document-export.c:64
msgid "Don't require the file to exist already"
msgstr "Не требовать чтобы файл уже существовал"

#: app/flatpak-builtins-document-export.c:65
msgid "Give the app read permissions"
msgstr "Дать приложению право на чтение"

#: app/flatpak-builtins-document-export.c:66
msgid "Give the app write permissions"
msgstr "Дать приложению право на запись"

#: app/flatpak-builtins-document-export.c:67
msgid "Give the app delete permissions"
msgstr "Дать приложению право на удаление"

#: app/flatpak-builtins-document-export.c:68
msgid "Give the app permissions to grant further permissions"
msgstr "Дать приложению право на изменение разрешений"

#: app/flatpak-builtins-document-export.c:69
msgid "Revoke read permissions of the app"
msgstr "Отозвать у приложения право на чтение"

#: app/flatpak-builtins-document-export.c:70
msgid "Revoke write permissions of the app"
msgstr "Отозвать у приложения право на запись"

#: app/flatpak-builtins-document-export.c:71
msgid "Revoke delete permissions of the app"
msgstr "Отозвать у приложения право на удаление"

#: app/flatpak-builtins-document-export.c:72
msgid "Revoke the permission to grant further permissions"
msgstr "Отозвать у приложения право на изменение разрешений"

#: app/flatpak-builtins-document-export.c:73
msgid "Add permissions for this app"
msgstr "Добавить разрешения приложению"

#: app/flatpak-builtins-document-export.c:73
msgid "APPID"
msgstr "ID_ПРИЛ"

#: app/flatpak-builtins-document-export.c:100
msgid "FILE - Export a file to apps"
msgstr "ФАЙЛ - Экспортировать файл приложениям"

#: app/flatpak-builtins-document-export.c:109
#: app/flatpak-builtins-document-info.c:72
#: app/flatpak-builtins-document-unexport.c:67
msgid "FILE must be specified"
msgstr "Должно быть указано ИМЯ_ФАЙЛА"

#: app/flatpak-builtins-document-info.c:63
msgid "FILE - Get information about an exported file"
msgstr "ФАЙЛ - Получить информацию об экспортированном файле"

#: app/flatpak-builtins-document-info.c:100
#: app/flatpak-builtins-document-unexport.c:94
#, c-format
msgid "Not exported\n"
msgstr "Не экспортировано\n"

#: app/flatpak-builtins-document-list.c:43 app/flatpak-builtins-history.c:53
#: app/flatpak-builtins-list.c:54 app/flatpak-builtins-ps.c:43
#: app/flatpak-builtins-remote-list.c:45 app/flatpak-builtins-remote-ls.c:59
#: app/flatpak-builtins-search.c:38
msgid "What information to show"
msgstr "Какую информацию показывать"

#: app/flatpak-builtins-document-list.c:43 app/flatpak-builtins-history.c:53
#: app/flatpak-builtins-list.c:54 app/flatpak-builtins-ps.c:43
#: app/flatpak-builtins-remote-list.c:45 app/flatpak-builtins-remote-ls.c:59
#: app/flatpak-builtins-search.c:38
msgid "FIELD,…"
msgstr "ПОЛЕ,…"

#: app/flatpak-builtins-document-list.c:44 app/flatpak-builtins-history.c:54
#: app/flatpak-builtins-list.c:52 app/flatpak-builtins-permission-list.c:43
#: app/flatpak-builtins-permission-show.c:43 app/flatpak-builtins-ps.c:44
#: app/flatpak-builtins-remote-list.c:46 app/flatpak-builtins-remote-ls.c:63
#: app/flatpak-builtins-repo.c:717 app/flatpak-builtins-search.c:39
#, fuzzy
msgid "Show output in JSON format"
msgstr "Показать дополнительную информацию"

#: app/flatpak-builtins-document-list.c:49
msgid "Show the document ID"
msgstr "Показать ID документа"

#: app/flatpak-builtins-document-list.c:50
msgid "Path"
msgstr "Путь"

#: app/flatpak-builtins-document-list.c:50
#: app/flatpak-builtins-document-list.c:51
msgid "Show the document path"
msgstr "Показать путь к документу"

#: app/flatpak-builtins-document-list.c:51 app/flatpak-builtins-list.c:66
#: app/flatpak-builtins-remote-ls.c:74
msgid "Origin"
msgstr "Источник"

#: app/flatpak-builtins-document-list.c:52 app/flatpak-builtins-history.c:62
#: app/flatpak-builtins-ps.c:52
msgid "Application"
msgstr "Приложение"

#: app/flatpak-builtins-document-list.c:52
msgid "Show applications with permission"
msgstr "Показать приложения с разрешением"

#: app/flatpak-builtins-document-list.c:53
#: app/flatpak-builtins-permission-list.c:182
#: app/flatpak-builtins-permission-show.c:145
msgid "Permissions"
msgstr "Разрешения"

#: app/flatpak-builtins-document-list.c:53
msgid "Show permissions for applications"
msgstr "Показать разрешения для приложения"

#: app/flatpak-builtins-document-list.c:161
#, c-format
msgid "No documents found\n"
msgstr "Документы не найдены\n"

#: app/flatpak-builtins-document-list.c:180
msgid "[APPID] - List exported files"
msgstr "[ID_ПРИЛ] - Показать список экспортированных файлов"

#: app/flatpak-builtins-document-unexport.c:43
msgid "Specify the document ID"
msgstr "Указать ID документа"

#: app/flatpak-builtins-document-unexport.c:58
msgid "FILE - Unexport a file to apps"
msgstr "ФАЙЛ - Убрать файл из экспортрованных"

#: app/flatpak-builtins-enter.c:88
msgid "INSTANCE COMMAND [ARGUMENT…] - Run a command inside a running sandbox"
msgstr ""
"ЭКЗЕМПЛЯР [КОМАНДА [АРГУМЕНТЫ...]] - Выполнить команду внутри запущенной "
"песочницы"

#: app/flatpak-builtins-enter.c:111
msgid "INSTANCE and COMMAND must be specified"
msgstr "Должны быть указаны ЭКЗЕМПЛЯР и КОМАНДА"

#: app/flatpak-builtins-enter.c:138
#, c-format
msgid "%s is neither a pid nor an application or instance ID"
msgstr "'%s' не является ни ID процесса, ни ID приложения или экземпляра"

#: app/flatpak-builtins-enter.c:144
msgid "entering not supported (need unprivileged user namespaces, or sudo -E)"
msgstr ""
"вход не поддерживается (требуются непривилегированные пространства имён или "
"sudo -E)"

#: app/flatpak-builtins-enter.c:145
#, c-format
msgid "No such pid %s"
msgstr "Нет такого процесса %s"

#: app/flatpak-builtins-enter.c:158
msgid "Can't read cwd"
msgstr "Невозможно прочитать текущий каталог"

#: app/flatpak-builtins-enter.c:163
msgid "Can't read root"
msgstr "Невозможно прочитать корневой каталог"

#: app/flatpak-builtins-enter.c:191
#, c-format
msgid "Invalid %s namespace for pid %d"
msgstr "Некорректное пространство имён %s для процесса %d"

#: app/flatpak-builtins-enter.c:202
#, c-format
msgid "Invalid %s namespace for self"
msgstr "Неверное %s пространство имён для текущего процесса"

#: app/flatpak-builtins-enter.c:216
#, c-format
msgid "Can't open %s namespace: %s"
msgstr "Невозможно открыть пространство имён %s: %s"

#: app/flatpak-builtins-enter.c:226
msgid "entering not supported (need unprivileged user namespaces)"
msgstr ""
"вход не поддерживается (требуются непривилегированные пространства имен "
"пользователей)"

#: app/flatpak-builtins-enter.c:227
#, c-format
msgid "Can't enter %s namespace: %s"
msgstr "Невозможно войти в пространство имён %s: %s"

#: app/flatpak-builtins-enter.c:234
msgid "Can't chdir"
msgstr "Невозможно сменить текущий каталог"

#: app/flatpak-builtins-enter.c:237
msgid "Can't chroot"
msgstr "Невозможно сменить корневой каталог"

#: app/flatpak-builtins-enter.c:240
msgid "Can't switch gid"
msgstr "Невозможно изменить группу пользователя"

#: app/flatpak-builtins-enter.c:243
msgid "Can't switch uid"
msgstr "Невозможно сменить пользователя"

#: app/flatpak-builtins-history.c:50
msgid "Only show changes after TIME"
msgstr "Показать изменения после ВРЕМЕНИ"

#: app/flatpak-builtins-history.c:50 app/flatpak-builtins-history.c:51
msgid "TIME"
msgstr "ВРЕМЯ"

#: app/flatpak-builtins-history.c:51
msgid "Only show changes before TIME"
msgstr "Показать изменеиия перед ВРЕМЕНЕМ"

#: app/flatpak-builtins-history.c:52
msgid "Show newest entries first"
msgstr "Показать новые элементы первыми"

#: app/flatpak-builtins-history.c:59
msgid "Time"
msgstr "Время"

#: app/flatpak-builtins-history.c:59
msgid "Show when the change happened"
msgstr "Показать, когда произошло изменение"

#: app/flatpak-builtins-history.c:60
msgid "Change"
msgstr "Изменение"

#: app/flatpak-builtins-history.c:60
msgid "Show the kind of change"
msgstr "Показать вид изменений"

#: app/flatpak-builtins-history.c:61 app/flatpak-builtins-list.c:68
#: app/flatpak-builtins-remote-ls.c:75 app/flatpak-builtins-repo.c:335
msgid "Ref"
msgstr "Ссылка"

#: app/flatpak-builtins-history.c:61 app/flatpak-builtins-list.c:68
#: app/flatpak-builtins-remote-ls.c:75
msgid "Show the ref"
msgstr "Показать ссылки"

#: app/flatpak-builtins-history.c:62
msgid "Show the application/runtime ID"
msgstr "Показать ID приложения/среды выполнения"

#: app/flatpak-builtins-history.c:63 app/flatpak-builtins-list.c:64
#: app/flatpak-builtins-ps.c:53 app/flatpak-builtins-remote-ls.c:73
#: app/flatpak-cli-transaction.c:1435
msgid "Arch"
msgstr "Архитектура"

#: app/flatpak-builtins-history.c:63 app/flatpak-builtins-list.c:64
#: app/flatpak-builtins-ps.c:53 app/flatpak-builtins-remote-ls.c:73
msgid "Show the architecture"
msgstr "Показать архитектуру"

#: app/flatpak-builtins-history.c:64 app/flatpak-builtins-list.c:63
#: app/flatpak-builtins-ps.c:54 app/flatpak-builtins-remote-ls.c:72
#: app/flatpak-builtins-search.c:48 app/flatpak-cli-transaction.c:1438
msgid "Branch"
msgstr "Ветвь"

#: app/flatpak-builtins-history.c:64 app/flatpak-builtins-list.c:63
#: app/flatpak-builtins-remote-ls.c:72
msgid "Show the branch"
msgstr "Показать ветвь"

#: app/flatpak-builtins-history.c:65 app/flatpak-builtins-list.c:67
msgid "Installation"
msgstr "Тип установки"

#: app/flatpak-builtins-history.c:65
msgid "Show the affected installation"
msgstr "Показать затронутую установку"

#: app/flatpak-builtins-history.c:66 app/flatpak-cli-transaction.c:1452
msgid "Remote"
msgstr "Удалённый репозиторий"

#: app/flatpak-builtins-history.c:66
msgid "Show the remote"
msgstr "Показать удалённый репозиторий"

#: app/flatpak-builtins-history.c:67 app/flatpak-builtins-ps.c:55
#: app/flatpak-builtins-remote-ls.c:76
msgid "Commit"
msgstr "Коммит"

#: app/flatpak-builtins-history.c:67
msgid "Show the current commit"
msgstr "Показать текущий коммит"

#: app/flatpak-builtins-history.c:68
msgid "Old Commit"
msgstr "Устаревший коммит"

#: app/flatpak-builtins-history.c:68
msgid "Show the previous commit"
msgstr "Показать предыдущий коммит"

#: app/flatpak-builtins-history.c:69
msgid "Show the remote URL"
msgstr "Показать URL удалённого репозитория"

#: app/flatpak-builtins-history.c:70 app/flatpak-cli-transaction.c:700
msgid "User"
msgstr "Пользователь"

#: app/flatpak-builtins-history.c:70
msgid "Show the user doing the change"
msgstr "Показать пользователя, вносящего изменения"

#: app/flatpak-builtins-history.c:71
msgid "Tool"
msgstr "Инструментарий"

#: app/flatpak-builtins-history.c:71
msgid "Show the tool that was used"
msgstr "Показать используемый инструментарий"

#: app/flatpak-builtins-history.c:72 app/flatpak-builtins-list.c:62
#: app/flatpak-builtins-remote-ls.c:71 app/flatpak-builtins-search.c:47
msgid "Version"
msgstr "Версия"

#: app/flatpak-builtins-history.c:72
msgid "Show the Flatpak version"
msgstr "Показать версию Flatpak"

#: app/flatpak-builtins-history.c:91
#, c-format
msgid "Failed to get journal data (%s): %s"
msgstr "Ошибка получения данных журнала (%s): %s"

#: app/flatpak-builtins-history.c:146
#, c-format
msgid "Failed to open journal: %s"
msgstr "Ошибка открытия журнала: %s"

#: app/flatpak-builtins-history.c:153
#, c-format
msgid "Failed to add match to journal: %s"
msgstr "Ошибка добавления совпадения в журнал: %s"

#: app/flatpak-builtins-history.c:471
msgid " - Show history"
msgstr " - Показать историю"

#: app/flatpak-builtins-history.c:490
#, c-format
msgid "Failed to parse the --since option"
msgstr "Ошибка разбора параметра --since"

#: app/flatpak-builtins-history.c:501
#, c-format
msgid "Failed to parse the --until option"
msgstr "Ошибка разбора параметра --until"

#: app/flatpak-builtins-info.c:56
msgid "Show user installations"
msgstr "Показать установленное только для пользователя"

#: app/flatpak-builtins-info.c:57
msgid "Show system-wide installations"
msgstr "Показать установленное для всех пользователей"

#: app/flatpak-builtins-info.c:58
msgid "Show specific system-wide installations"
msgstr "Показать установленное в указанном каталоге"

#: app/flatpak-builtins-info.c:59 app/flatpak-builtins-remote-info.c:59
msgid "Show ref"
msgstr "Показать ссылки"

#: app/flatpak-builtins-info.c:60 app/flatpak-builtins-remote-info.c:60
msgid "Show commit"
msgstr "Показать коммит"

#: app/flatpak-builtins-info.c:61
msgid "Show origin"
msgstr "Показать происхождение"

#: app/flatpak-builtins-info.c:62
msgid "Show size"
msgstr "Показать размер"

#: app/flatpak-builtins-info.c:63 app/flatpak-builtins-remote-info.c:62
msgid "Show metadata"
msgstr "Показать метаданные"

#: app/flatpak-builtins-info.c:64 app/flatpak-builtins-remote-info.c:63
msgid "Show runtime"
msgstr "Показать среды выполнения"

#: app/flatpak-builtins-info.c:65 app/flatpak-builtins-remote-info.c:64
msgid "Show sdk"
msgstr "Показать sdk"

#: app/flatpak-builtins-info.c:66
msgid "Show permissions"
msgstr "Показать разрешения"

#: app/flatpak-builtins-info.c:67
msgid "Query file access"
msgstr "Управление доступом к файлам"

#: app/flatpak-builtins-info.c:67 app/flatpak-builtins-install.c:82
#: app/flatpak-builtins-install.c:88 app/flatpak-builtins-preinstall.c:68
#: app/flatpak-builtins-run.c:182 app/flatpak-builtins-run.c:184
#: app/flatpak-builtins-update.c:67 app/flatpak-builtins-update.c:71
msgid "PATH"
msgstr "ПУТЬ"

#: app/flatpak-builtins-info.c:68
msgid "Show extensions"
msgstr "Показать расширения"

#: app/flatpak-builtins-info.c:69
msgid "Show location"
msgstr "Показать расположение"

#: app/flatpak-builtins-info.c:116
msgid "NAME [BRANCH] - Get info about an installed app or runtime"
msgstr ""
"ИМЯ [ВЕТВЬ] - Получить информацию об установленном приложении или среде "
"выполнения"

#: app/flatpak-builtins-info.c:123 app/flatpak-builtins-remote-add.c:317
#: app/flatpak-builtins-remote-delete.c:63
msgid "NAME must be specified"
msgstr "Должно быть указано ИМЯ"

#: app/flatpak-builtins-info.c:196
msgid "ref not present in origin"
msgstr "ссылка отсутствует в источнике"

#: app/flatpak-builtins-info.c:211 app/flatpak-builtins-remote-info.c:217
#, c-format
msgid "Warning: Commit has no flatpak metadata\n"
msgstr "Предупреждение: коммиит не содержит метаданных Flatpak\n"

#: app/flatpak-builtins-info.c:217 app/flatpak-builtins-info.c:259
#: app/flatpak-builtins-info.c:455 app/flatpak-builtins-info.c:513
#: app/flatpak-builtins-remote-info.c:236
#: app/flatpak-builtins-remote-info.c:271
msgid "ID:"
msgstr "ID:"

#: app/flatpak-builtins-info.c:218 app/flatpak-builtins-info.c:260
#: app/flatpak-builtins-remote-info.c:237
#: app/flatpak-builtins-remote-info.c:272
msgid "Ref:"
msgstr "Ссылка:"

#: app/flatpak-builtins-info.c:219 app/flatpak-builtins-info.c:261
#: app/flatpak-builtins-remote-info.c:238
#: app/flatpak-builtins-remote-info.c:273
msgid "Arch:"
msgstr "Архитектура:"

#: app/flatpak-builtins-info.c:220 app/flatpak-builtins-info.c:262
#: app/flatpak-builtins-remote-info.c:239
#: app/flatpak-builtins-remote-info.c:274
msgid "Branch:"
msgstr "Ветвь:"

#: app/flatpak-builtins-info.c:222 app/flatpak-builtins-info.c:264
#: app/flatpak-builtins-remote-info.c:241
#: app/flatpak-builtins-remote-info.c:276
msgid "Version:"
msgstr "Версия:"

#: app/flatpak-builtins-info.c:224 app/flatpak-builtins-info.c:266
#: app/flatpak-builtins-remote-info.c:243
#: app/flatpak-builtins-remote-info.c:278
msgid "License:"
msgstr "Лицензия:"

#: app/flatpak-builtins-info.c:226 app/flatpak-builtins-info.c:269
#: app/flatpak-builtins-remote-info.c:245
#: app/flatpak-builtins-remote-info.c:280
msgid "Collection:"
msgstr "Коллекция:"

#: app/flatpak-builtins-info.c:227 app/flatpak-builtins-info.c:270
#: app/flatpak-builtins-info.c:458 app/flatpak-builtins-info.c:516
msgid "Installation:"
msgstr "Установка:"

#: app/flatpak-builtins-info.c:228 app/flatpak-builtins-info.c:271
#: app/flatpak-builtins-info.c:459 app/flatpak-builtins-info.c:517
#: app/flatpak-builtins-remote-info.c:249
#: app/flatpak-builtins-remote-info.c:284
#, fuzzy
msgid "Installed Size:"
msgstr "Установленный размер"

#: app/flatpak-builtins-info.c:231 app/flatpak-builtins-info.c:279
#: app/flatpak-builtins-remote-info.c:252
#: app/flatpak-builtins-remote-info.c:288
msgid "Runtime:"
msgstr "Среда выполнения:"

#: app/flatpak-builtins-info.c:232 app/flatpak-builtins-info.c:288
#: app/flatpak-builtins-remote-info.c:253
#: app/flatpak-builtins-remote-info.c:293
msgid "Sdk:"
msgstr "Sdk:"

#: app/flatpak-builtins-info.c:235 app/flatpak-builtins-info.c:313
#: app/flatpak-builtins-remote-info.c:256
#: app/flatpak-builtins-remote-info.c:319
msgid "Date:"
msgstr "Дата:"

#: app/flatpak-builtins-info.c:237 app/flatpak-builtins-info.c:311
#: app/flatpak-builtins-remote-info.c:258
#: app/flatpak-builtins-remote-info.c:317
msgid "Subject:"
msgstr "Заголовок:"

#: app/flatpak-builtins-info.c:240 app/flatpak-builtins-info.c:295
msgid "Active commit:"
msgstr "Активный коммит:"

#: app/flatpak-builtins-info.c:241 app/flatpak-builtins-info.c:298
msgid "Latest commit:"
msgstr "Последний коммит:"

#: app/flatpak-builtins-info.c:244 app/flatpak-builtins-info.c:303
#: app/flatpak-builtins-info.c:457 app/flatpak-builtins-info.c:515
#: app/flatpak-builtins-remote-info.c:259
#: app/flatpak-builtins-remote-info.c:298
msgid "Commit:"
msgstr "Коммит:"

#: app/flatpak-builtins-info.c:246 app/flatpak-builtins-info.c:308
#: app/flatpak-builtins-remote-info.c:261
#: app/flatpak-builtins-remote-info.c:303
msgid "Parent:"
msgstr "Родитель:"

#: app/flatpak-builtins-info.c:248 app/flatpak-builtins-info.c:321
msgid "Alt-id:"
msgstr "Альт-ID:"

#: app/flatpak-builtins-info.c:250 app/flatpak-builtins-info.c:325
#: app/flatpak-builtins-remote-info.c:263
#: app/flatpak-builtins-remote-info.c:308
msgid "End-of-life:"
msgstr "Конец-поддержки:"

#: app/flatpak-builtins-info.c:252 app/flatpak-builtins-info.c:330
#: app/flatpak-builtins-remote-info.c:265
#: app/flatpak-builtins-remote-info.c:313
msgid "End-of-life-rebase:"
msgstr "Конец-поддержки-замена:"

#: app/flatpak-builtins-info.c:254 app/flatpak-builtins-info.c:317
msgid "Subdirectories:"
msgstr "Поддиректории:"

#: app/flatpak-builtins-info.c:255 app/flatpak-builtins-info.c:454
#: app/flatpak-builtins-info.c:512
msgid "Extension:"
msgstr "Расширение:"

#: app/flatpak-builtins-info.c:267 app/flatpak-builtins-info.c:456
#: app/flatpak-builtins-info.c:514
msgid "Origin:"
msgstr "Источник:"

#: app/flatpak-builtins-info.c:460 app/flatpak-builtins-info.c:522
msgid "Subpaths:"
msgstr "Подпути:"

#: app/flatpak-builtins-info.c:478
msgid "unmaintained"
msgstr "не-сопровождается"

#: app/flatpak-builtins-info.c:480 app/flatpak-builtins-info.c:482
msgid "unknown"
msgstr "неизвестно"

#: app/flatpak-builtins-install.c:68 app/flatpak-builtins-preinstall.c:57
msgid "Don't pull, only install from local cache"
msgstr ""
"Не обращаться к репозиторию, вместо этого установить из локального кеша"

#: app/flatpak-builtins-install.c:69 app/flatpak-builtins-preinstall.c:58
#: app/flatpak-builtins-update.c:60
msgid "Don't deploy, only download to local cache"
msgstr "Не начинать установку, вместо этого скачать только в кеш"

#: app/flatpak-builtins-install.c:70 app/flatpak-builtins-preinstall.c:59
msgid "Don't install related refs"
msgstr "Не устанавливать связанные ссылки"

#: app/flatpak-builtins-install.c:71 app/flatpak-builtins-preinstall.c:60
#: app/flatpak-builtins-update.c:62
msgid "Don't verify/install runtime dependencies"
msgstr "Не проверять и не устанавливать зависимости среды выполнения"

#: app/flatpak-builtins-install.c:72
msgid "Don't automatically pin explicit installs"
msgstr "Не закреплять автоматически установленное явно"

#: app/flatpak-builtins-install.c:73 app/flatpak-builtins-preinstall.c:61
#: app/flatpak-builtins-update.c:63
msgid "Don't use static deltas"
msgstr "Не использовать статические дельты"

#: app/flatpak-builtins-install.c:76 app/flatpak-builtins-preinstall.c:62
msgid "Additionally install the SDK used to build the given refs"
msgstr "Дополнительно установить SDK, используемый для создания данных ссылок"

#: app/flatpak-builtins-install.c:77 app/flatpak-builtins-preinstall.c:63
msgid ""
"Additionally install the debug info for the given refs and their dependencies"
msgstr ""
"Дополнительно установить отладочную информацию для заданных ссылок и их "
"зависимостей"

#: app/flatpak-builtins-install.c:78
msgid "Assume LOCATION is a .flatpak single-file bundle"
msgstr "ПУТЬ является файлом с пакетом"

#: app/flatpak-builtins-install.c:79
msgid "Assume LOCATION is a .flatpakref application description"
msgstr "ПУТЬ является описанием приложения в формате .flatpakref"

#: app/flatpak-builtins-install.c:80
msgid "Assume LOCATION is containers-transports(5) reference to an OCI image"
msgstr ""

#: app/flatpak-builtins-install.c:81
msgid "Check bundle signatures with GPG key from FILE (- for stdin)"
msgstr "Проверять подписи пакета ключом GPG из ФАЙЛА (- из стандартного ввода)"

#: app/flatpak-builtins-install.c:82
msgid "Only install this subpath"
msgstr "Установить только указанный подкаталог"

#: app/flatpak-builtins-install.c:83 app/flatpak-builtins-preinstall.c:64
#: app/flatpak-builtins-uninstall.c:63 app/flatpak-builtins-update.c:68
msgid "Automatically answer yes for all questions"
msgstr "Автоматически отвечать да на все вопросы"

#: app/flatpak-builtins-install.c:84 app/flatpak-builtins-preinstall.c:65
msgid "Uninstall first if already installed"
msgstr "Сперва удалить, если уже установлено"

#: app/flatpak-builtins-install.c:85 app/flatpak-builtins-preinstall.c:66
#: app/flatpak-builtins-uninstall.c:64 app/flatpak-builtins-update.c:69
msgid "Produce minimal output and don't ask questions"
msgstr "Выводить минимум информации и не задавать вопросов"

#: app/flatpak-builtins-install.c:86
msgid "Update install if already installed"
msgstr "Обновить, если уже установлено"

#. Translators: A sideload is when you install from a local USB drive rather than the Internet.
#: app/flatpak-builtins-install.c:88 app/flatpak-builtins-preinstall.c:68
#: app/flatpak-builtins-update.c:71
msgid "Use this local repo for sideloads"
msgstr "Использовать этот репозиторий для параллельной загрузки"

#: app/flatpak-builtins-install.c:178
msgid "Bundle filename must be specified"
msgstr "Должно быть указано имя файла с пакетом"

#: app/flatpak-builtins-install.c:188
msgid "Remote bundles are not supported"
msgstr "Пакеты из удалённых репозиториев не поддерживаются"

#: app/flatpak-builtins-install.c:231
msgid "Filename or uri must be specified"
msgstr "Должно быть указано имя файла или адрес"

#: app/flatpak-builtins-install.c:295
#, fuzzy
msgid "Image location must be specified"
msgstr "Должна быть указана хотя бы одна ССЫЛКА"

#: app/flatpak-builtins-install.c:345
msgid "[LOCATION/REMOTE] [REF…] - Install applications or runtimes"
msgstr ""
"[ПУТЬ/УДАЛЁННЫЙ_РЕПО] [ССЫЛКА…] - Установить приложения или среды выполнения"

#: app/flatpak-builtins-install.c:378
msgid "At least one REF must be specified"
msgstr "Должна быть указана хотя бы одна ССЫЛКА"

#: app/flatpak-builtins-install.c:392
#, c-format
msgid "Looking for matches…\n"
msgstr "Поиск совпадений…\n"

#: app/flatpak-builtins-install.c:513
#, c-format
msgid "No remote refs found for ‘%s’"
msgstr "Для '%s' не найдено удаленных ссылок"

#: app/flatpak-builtins-install.c:573 app/flatpak-builtins-uninstall.c:405
#: common/flatpak-ref-utils.c:689 common/flatpak-ref-utils.c:1595
#, c-format
msgid "Invalid branch %s: %s"
msgstr "Некорректная ветвь %s: %s"

#: app/flatpak-builtins-install.c:606
#, c-format
msgid "Nothing matches %s in local repository for remote %s"
msgstr "Нет совпадений с %s в локальном репозитории для удалённого %s"

#: app/flatpak-builtins-install.c:608
#, c-format
msgid "Nothing matches %s in remote %s"
msgstr "Нет совпадений с %s в удалённом репозитории %s"

#: app/flatpak-builtins-install.c:629
#, c-format
msgid "Skipping: %s\n"
msgstr "Пропуск: %s\n"

#: app/flatpak-builtins-kill.c:110
#, c-format
msgid "%s is not running"
msgstr "%s не запущен"

#: app/flatpak-builtins-kill.c:136
msgid "INSTANCE - Stop a running application"
msgstr "ЭКЗЕМПЛЯР - Завершить запущенное приложение"

#: app/flatpak-builtins-kill.c:144 app/flatpak-builtins-ps.c:256
msgid "Extra arguments given"
msgstr "Переданы лишние аргументы"

#: app/flatpak-builtins-kill.c:150
msgid "Must specify the app to kill"
msgstr "Нужно указать приложение для принудительного завершения"

#: app/flatpak-builtins-list.c:47
msgid "Show extra information"
msgstr "Показать дополнительную информацию"

#: app/flatpak-builtins-list.c:48
msgid "List installed runtimes"
msgstr "Показать установленные среды выполнения"

#: app/flatpak-builtins-list.c:49
msgid "List installed applications"
msgstr "Показать установленные приложения"

#: app/flatpak-builtins-list.c:50
msgid "Arch to show"
msgstr "Показать указанную архитектуру"

#: app/flatpak-builtins-list.c:51 app/flatpak-builtins-remote-ls.c:57
msgid "List all refs (including locale/debug)"
msgstr "Перечислить все ссылки (включая локализации и отладочные)"

#: app/flatpak-builtins-list.c:53 app/flatpak-builtins-remote-ls.c:58
msgid "List all applications using RUNTIME"
msgstr "Показать приложения, использующие СРЕДУ_ВЫПОЛНЕНИЯ"

#: app/flatpak-builtins-list.c:59 app/flatpak-builtins-remote-list.c:51
#: app/flatpak-builtins-remote-ls.c:68 app/flatpak-builtins-search.c:44
msgid "Name"
msgstr "Имя"

#: app/flatpak-builtins-list.c:59 app/flatpak-builtins-remote-list.c:51
#: app/flatpak-builtins-remote-ls.c:68 app/flatpak-builtins-search.c:44
msgid "Show the name"
msgstr "Показать имя"

#: app/flatpak-builtins-list.c:60 app/flatpak-builtins-remote-list.c:60
#: app/flatpak-builtins-remote-ls.c:69 app/flatpak-builtins-search.c:45
msgid "Description"
msgstr "Описание"

#: app/flatpak-builtins-list.c:60 app/flatpak-builtins-remote-ls.c:69
#: app/flatpak-builtins-search.c:45
msgid "Show the description"
msgstr "Показать описание"

#: app/flatpak-builtins-list.c:61 app/flatpak-builtins-remote-ls.c:70
#: app/flatpak-builtins-search.c:46
msgid "Application ID"
msgstr "ID Приложения"

#: app/flatpak-builtins-list.c:61 app/flatpak-builtins-ps.c:52
#: app/flatpak-builtins-remote-ls.c:70 app/flatpak-builtins-search.c:46
msgid "Show the application ID"
msgstr "Показать ID приложения"

#: app/flatpak-builtins-list.c:62 app/flatpak-builtins-remote-ls.c:71
#: app/flatpak-builtins-search.c:47
msgid "Show the version"
msgstr "Показать версию"

#: app/flatpak-builtins-list.c:65 app/flatpak-builtins-ps.c:56
#: app/flatpak-builtins-remote-ls.c:77
msgid "Runtime"
msgstr "Среда выполнения"

#: app/flatpak-builtins-list.c:65
msgid "Show the used runtime"
msgstr "Показать используемую среду выполнения"

#: app/flatpak-builtins-list.c:66 app/flatpak-builtins-remote-ls.c:74
msgid "Show the origin remote"
msgstr "Показать удалённый репозиторий источника"

#: app/flatpak-builtins-list.c:67
msgid "Show the installation"
msgstr "Показать установку"

#: app/flatpak-builtins-list.c:69
msgid "Active commit"
msgstr "Активный коммит"

#: app/flatpak-builtins-list.c:69 app/flatpak-builtins-remote-ls.c:76
msgid "Show the active commit"
msgstr "Показать активный коммит"

#: app/flatpak-builtins-list.c:70
msgid "Latest commit"
msgstr "Последний коммит"

#: app/flatpak-builtins-list.c:70
msgid "Show the latest commit"
msgstr "Показать последний коммит"

#: app/flatpak-builtins-list.c:71 app/flatpak-builtins-remote-ls.c:78
msgid "Installed size"
msgstr "Установленный размер"

#: app/flatpak-builtins-list.c:71 app/flatpak-builtins-remote-ls.c:78
msgid "Show the installed size"
msgstr "Показать установленный размер"

#: app/flatpak-builtins-list.c:72 app/flatpak-builtins-remote-list.c:58
#: app/flatpak-builtins-remote-ls.c:80 app/flatpak-builtins-repo.c:340
msgid "Options"
msgstr "Параметры"

#: app/flatpak-builtins-list.c:72 app/flatpak-builtins-remote-list.c:58
#: app/flatpak-builtins-remote-ls.c:80
msgid "Show options"
msgstr "Показать параметры"

#: app/flatpak-builtins-list.c:180
#, c-format
msgid "Unable to load details of %s: %s"
msgstr "Не удалось загрузить сведения о %s: %s"

#: app/flatpak-builtins-list.c:190
#, c-format
msgid "Unable to inspect current version of %s: %s"
msgstr "Невозможно проверить текущую версию %s: %s"

#: app/flatpak-builtins-list.c:408
msgid " - List installed apps and/or runtimes"
msgstr " - Показать список установленных приложений и/или сред выполнения"

#: app/flatpak-builtins-make-current.c:38
msgid "Arch to make current for"
msgstr "Архитектура, которая станет текущей для"

#: app/flatpak-builtins-make-current.c:58
msgid "APP BRANCH - Make branch of application current"
msgstr "ПРИЛОЖЕНИЕ ВЕТВЬ - Сделать ветвь приложения текущей"

#: app/flatpak-builtins-make-current.c:69 app/flatpak-builtins-run.c:260
msgid "APP must be specified"
msgstr "Должно быть указано ПРИЛОЖЕНИЕ"

#: app/flatpak-builtins-make-current.c:84
msgid "BRANCH must be specified"
msgstr "Должна быть указана ВЕТВЬ"

#: app/flatpak-builtins-make-current.c:97
#, c-format
msgid "App %s branch %s is not installed"
msgstr "Приложение %s ветви %s не установлено"

#: app/flatpak-builtins-mask.c:42
msgid "Remove matching masks"
msgstr "Удалить соответствующие маски"

#: app/flatpak-builtins-mask.c:54
msgid ""
"[PATTERN…] - disable updates and automatic installation matching patterns"
msgstr ""
"[ШАБЛОН…] - отключить обновления и автоматическую установку для подходящего "
"под шаблон"

#: app/flatpak-builtins-mask.c:73
#, c-format
msgid "No masked patterns\n"
msgstr "Нет замаскированных шаблонов\n"

#: app/flatpak-builtins-mask.c:78
#, c-format
msgid "Masked patterns:\n"
msgstr "Замаскированные шаблоны:\n"

#: app/flatpak-builtins-override.c:42
msgid "Remove existing overrides"
msgstr "Удалить существующие переопределения"

#: app/flatpak-builtins-override.c:43
msgid "Show existing overrides"
msgstr "Показать существующие переопределения"

#: app/flatpak-builtins-override.c:59
msgid "[APP] - Override settings [for application]"
msgstr "ПРИЛОЖЕНИЕ - Переопределить настройки [для приложения]"

#: app/flatpak-builtins-permission-list.c:143
msgid "[TABLE] [ID] - List permissions"
msgstr "[ТАБЛИЦА] [ID] - Показать список разрешений"

#: app/flatpak-builtins-permission-list.c:179
#: app/flatpak-builtins-permission-show.c:142
msgid "Table"
msgstr "Таблица"

#: app/flatpak-builtins-permission-list.c:180
#: app/flatpak-builtins-permission-show.c:143
msgid "Object"
msgstr "Объект"

#: app/flatpak-builtins-permission-list.c:181
#: app/flatpak-builtins-permission-show.c:144
msgid "App"
msgstr "Приложение"

#: app/flatpak-builtins-permission-list.c:183
#: app/flatpak-builtins-permission-show.c:146
msgid "Data"
msgstr "Данные"

#: app/flatpak-builtins-permission-remove.c:120
msgid "TABLE ID [APP_ID] - Remove item from permission store"
msgstr "ТАБЛИЦА ID [ID_ПРИЛ] - Удалить запись из хранилища разрешений"

#: app/flatpak-builtins-permission-remove.c:129
#: app/flatpak-builtins-permission-set.c:120
msgid "Too few arguments"
msgstr "Слишком мало аргументов"

#: app/flatpak-builtins-permission-reset.c:43
msgid "Reset all permissions"
msgstr "Сбросить все разрешения"

#: app/flatpak-builtins-permission-reset.c:144
msgid "APP_ID - Reset permissions for an app"
msgstr "ID_ПРИЛОЖЕНИЯ - Сбросить разрешения для приложения"

#: app/flatpak-builtins-permission-reset.c:153
#: app/flatpak-builtins-permission-show.c:124
msgid "Wrong number of arguments"
msgstr "Неверное количество аргмументов"

#: app/flatpak-builtins-permission-set.c:42
msgid "Associate DATA with the entry"
msgstr "Связать ДАННЫЕ с записью"

#: app/flatpak-builtins-permission-set.c:42
msgid "DATA"
msgstr "ДАННЫЕ"

#: app/flatpak-builtins-permission-set.c:111
msgid "TABLE ID APP_ID [PERMISSION...] - Set permissions"
msgstr "ТАБЛИЦА ID ID_ПРИЛ [РАЗРЕШЕНИЯ...] - Установить разрешения"

#: app/flatpak-builtins-permission-set.c:132
#, c-format
msgid "Failed to parse '%s' as GVariant: "
msgstr "Не удалось разобрать '%s' как GVariant: "

#: app/flatpak-builtins-permission-show.c:115
msgid "APP_ID - Show permissions for an app"
msgstr "ID_ПРИЛ - Показать разрешения для приложения"

#: app/flatpak-builtins-pin.c:44
msgid "Remove matching pins"
msgstr "Удалить соответствующие закрепления"

#: app/flatpak-builtins-pin.c:56
msgid "[PATTERN…] - disable automatic removal of runtimes matching patterns"
msgstr ""
"[ШАБЛОН…] - отключить автоудаление сред выполнения, подходящих под шаблонны"

#: app/flatpak-builtins-pin.c:75
#, c-format
msgid "No pinned patterns\n"
msgstr "Нет закреплённых шаблонов\n"

#: app/flatpak-builtins-pin.c:80
#, c-format
msgid "Pinned patterns:\n"
msgstr "Закреплённые шаблоны:\n"

#: app/flatpak-builtins-preinstall.c:80
msgid "- Install flatpaks that are part of the operating system"
msgstr ""

#: app/flatpak-builtins-preinstall.c:118
#, c-format
msgid "Nothing to do.\n"
msgstr "Нечего выполнять.\n"

#: app/flatpak-builtins-ps.c:49
msgid "Instance"
msgstr "Экземпляр"

#: app/flatpak-builtins-ps.c:49
msgid "Show the instance ID"
msgstr "Показать ID экземпляра"

#: app/flatpak-builtins-ps.c:50 app/flatpak-builtins-run.c:178
msgid "PID"
msgstr "PID"

#: app/flatpak-builtins-ps.c:50
msgid "Show the PID of the wrapper process"
msgstr "Показать PID обёртки"

#: app/flatpak-builtins-ps.c:51
msgid "Child-PID"
msgstr "PID потомка"

#: app/flatpak-builtins-ps.c:51
msgid "Show the PID of the sandbox process"
msgstr "Показать PID песочницы"

#: app/flatpak-builtins-ps.c:54 app/flatpak-builtins-search.c:48
msgid "Show the application branch"
msgstr "Показать ветвь приложения"

#: app/flatpak-builtins-ps.c:55
msgid "Show the application commit"
msgstr "Показать коммит приложения"

#: app/flatpak-builtins-ps.c:56
msgid "Show the runtime ID"
msgstr "Показать ID среды выполнения"

#: app/flatpak-builtins-ps.c:57
msgid "R.-Branch"
msgstr "Ветвь среды"

#: app/flatpak-builtins-ps.c:57
msgid "Show the runtime branch"
msgstr "Показать ветвь среды выполнения"

#: app/flatpak-builtins-ps.c:58
msgid "R.-Commit"
msgstr "Коммит среды"

#: app/flatpak-builtins-ps.c:58
msgid "Show the runtime commit"
msgstr "Показать коммит среды выполнения"

#: app/flatpak-builtins-ps.c:59
msgid "Active"
msgstr "Активно"

#: app/flatpak-builtins-ps.c:59
msgid "Show whether the app is active"
msgstr "Показать, активно ли приложение"

#: app/flatpak-builtins-ps.c:60
msgid "Background"
msgstr "Фоновое"

#: app/flatpak-builtins-ps.c:60
msgid "Show whether the app is background"
msgstr "Показать, работает ли приложение в фоне"

#: app/flatpak-builtins-ps.c:246
msgid " - Enumerate running sandboxes"
msgstr " - Перечислить работающие песочницы"

#: app/flatpak-builtins-remote-add.c:66
msgid "Do nothing if the provided remote exists"
msgstr "Ничего не делать если удалённый репозиторий уже существует"

#: app/flatpak-builtins-remote-add.c:67
msgid "LOCATION specifies a configuration file, not the repo location"
msgstr "ПУТЬ указывает на файл с конфигурацией, а не на репозиторий"

#: app/flatpak-builtins-remote-add.c:72 app/flatpak-builtins-remote-modify.c:78
msgid "Disable GPG verification"
msgstr "Отключить проверку GPG"

#: app/flatpak-builtins-remote-add.c:73 app/flatpak-builtins-remote-modify.c:79
msgid "Mark the remote as don't enumerate"
msgstr "Пометить удалённый репозиторий как не просматриваемый"

#: app/flatpak-builtins-remote-add.c:74 app/flatpak-builtins-remote-modify.c:80
msgid "Mark the remote as don't use for deps"
msgstr ""
"Пометить удалённый репозиторий как не используемый для поиска зависимостей"

#: app/flatpak-builtins-remote-add.c:75 app/flatpak-builtins-remote-modify.c:81
msgid "Set priority (default 1, higher is more prioritized)"
msgstr "Установить приоритет (по умолчанию 1, чем больше тем выше приоритет)"

#: app/flatpak-builtins-remote-add.c:75 app/flatpak-builtins-remote-modify.c:81
msgid "PRIORITY"
msgstr "ПРИОРИТЕТ"

#: app/flatpak-builtins-remote-add.c:76
msgid "The named subset to use for this remote"
msgstr "Именованное подмножество для данного удалённого репозитория"

#: app/flatpak-builtins-remote-add.c:76 app/flatpak-builtins-remote-modify.c:71
msgid "SUBSET"
msgstr "ПОДМНОЖЕСТВО"

#: app/flatpak-builtins-remote-add.c:77 app/flatpak-builtins-remote-modify.c:82
msgid "A nice name to use for this remote"
msgstr "Красивое имя для удалённого репозитория"

#: app/flatpak-builtins-remote-add.c:78 app/flatpak-builtins-remote-modify.c:83
msgid "A one-line comment for this remote"
msgstr "Однострочный комментарий для этого удалённого репозитория"

#: app/flatpak-builtins-remote-add.c:79 app/flatpak-builtins-remote-modify.c:84
msgid "A full-paragraph description for this remote"
msgstr "Полное описание для удалённого репозитория"

#: app/flatpak-builtins-remote-add.c:80 app/flatpak-builtins-remote-modify.c:85
msgid "URL for a website for this remote"
msgstr "URL веб-сайта для этого удалённого репозитория"

#: app/flatpak-builtins-remote-add.c:81 app/flatpak-builtins-remote-modify.c:86
msgid "URL for an icon for this remote"
msgstr "URL логотипа для этого удалённого репозитория"

#: app/flatpak-builtins-remote-add.c:82 app/flatpak-builtins-remote-modify.c:87
msgid "Default branch to use for this remote"
msgstr "Ветвь по-умолчанию для этого удалённого репозитория"

#: app/flatpak-builtins-remote-add.c:84 app/flatpak-builtins-remote-modify.c:89
msgid "Import GPG key from FILE (- for stdin)"
msgstr "Импортировать ключ GPG из ФАЙЛА (- для стандартного потока ввода)"

#: app/flatpak-builtins-remote-add.c:85 app/flatpak-builtins-remote-modify.c:90
msgid "Load signatures from URL"
msgstr ""

#: app/flatpak-builtins-remote-add.c:86 app/flatpak-builtins-remote-modify.c:92
msgid "Set path to local filter FILE"
msgstr "Указать путь к ФАЙЛУ локального фильтра"

#: app/flatpak-builtins-remote-add.c:87 app/flatpak-builtins-remote-modify.c:93
msgid "Disable the remote"
msgstr "Отключить удалённый репозиторий"

#: app/flatpak-builtins-remote-add.c:88 app/flatpak-builtins-remote-modify.c:94
msgid "Name of authenticator"
msgstr "Имя аутентификатора"

#: app/flatpak-builtins-remote-add.c:90 app/flatpak-builtins-remote-modify.c:96
msgid "Autoinstall authenticator"
msgstr "Автоматически устанавливать аутентификатор"

#: app/flatpak-builtins-remote-add.c:91 app/flatpak-builtins-remote-modify.c:97
msgid "Don't autoinstall authenticator"
msgstr "Не устанавливать аутентификатор автоматически"

#: app/flatpak-builtins-remote-add.c:92 app/flatpak-builtins-remote-modify.c:99
msgid "Don't follow the redirect set in the summary file"
msgstr "Не следовать перенаправлению, заданному в файле сводки"

#: app/flatpak-builtins-remote-add.c:261 app/flatpak-builtins-remote-add.c:268
#, c-format
msgid "Can't load uri %s: %s\n"
msgstr "Не удалось загрузить адрес %s: %s\n"

#: app/flatpak-builtins-remote-add.c:276 common/flatpak-dir.c:4643
#, c-format
msgid "Can't load file %s: %s\n"
msgstr "Не удалось загрузить файл %s: %s\n"

#: app/flatpak-builtins-remote-add.c:304
msgid "NAME LOCATION - Add a remote repository"
msgstr "ИМЯ ПУТЬ - Добавить удалённый репозиторий"

#: app/flatpak-builtins-remote-add.c:331
msgid "GPG verification is required if collections are enabled"
msgstr "Проверка GPG обязательна, если коллекции включены"

#: app/flatpak-builtins-remote-add.c:393
#, c-format
msgid "Remote %s already exists"
msgstr "Удалённый репозиторий %s уже существует"

#: app/flatpak-builtins-remote-add.c:405
#: app/flatpak-builtins-remote-modify.c:340
#, c-format
msgid "Invalid authenticator name %s"
msgstr "Некорректное имя аутентификатора %s"

#: app/flatpak-builtins-remote-add.c:422
#, c-format
msgid "Warning: Could not update extra metadata for '%s': %s\n"
msgstr ""
"Предупреждение: Не удалось обновить дополнительные метаданные для '%s': %s\n"

#: app/flatpak-builtins-remote-delete.c:39
msgid "Remove remote even if in use"
msgstr "Удалить удаленный репозиторий даже если он используется"

#: app/flatpak-builtins-remote-delete.c:53
msgid "NAME - Delete a remote repository"
msgstr "ИМЯ - Удалить репозиторий"

#: app/flatpak-builtins-remote-delete.c:100
#, c-format
msgid "The following refs are installed from remote '%s':"
msgstr "Следующие ссылки установлены из удаленного репозитория '%s':"

#: app/flatpak-builtins-remote-delete.c:101
msgid "Remove them?"
msgstr "Удалить их?"

#: app/flatpak-builtins-remote-delete.c:103
#, c-format
msgid "Can't remove remote '%s' with installed refs"
msgstr "Невозможно удалить репозиторий '%s' с установленными ссылками"

#: app/flatpak-builtins-remote-info.c:55
msgid "Commit to show info for"
msgstr "Показать информацию для указанного коммита"

#: app/flatpak-builtins-remote-info.c:58
msgid "Display log"
msgstr "Показать журнал"

#: app/flatpak-builtins-remote-info.c:61
msgid "Show parent"
msgstr "Показать родителя"

#: app/flatpak-builtins-remote-info.c:65 app/flatpak-builtins-remote-ls.c:60
msgid "Use local caches even if they are stale"
msgstr "Использовать локальный кэш, даже если он устарел"

#. Translators: A sideload is when you install from a local USB drive rather than the Internet.
#: app/flatpak-builtins-remote-info.c:67 app/flatpak-builtins-remote-ls.c:62
msgid "Only list refs available as sideloads"
msgstr "Список ссылок, доступных только для параллельной загрузки"

#: app/flatpak-builtins-remote-info.c:114
msgid ""
" REMOTE REF - Show information about an application or runtime in a remote"
msgstr ""
" УДАЛЁННЫЙ_РЕПО ССЫЛКА - Показать информацию о приложении или среде "
"выполнения в удалённом репозитории"

#: app/flatpak-builtins-remote-info.c:125
msgid "REMOTE and REF must be specified"
msgstr "Должны быть указаны УДАЛЁННЫЙ_РЕПО и ССЫЛКА"

#: app/flatpak-builtins-remote-info.c:247
#: app/flatpak-builtins-remote-info.c:282
#, fuzzy
msgid "Download Size:"
msgstr "Размер загрузки"

#: app/flatpak-builtins-remote-info.c:267
#: app/flatpak-builtins-remote-info.c:325
msgid "History:"
msgstr "История:"

#: app/flatpak-builtins-remote-info.c:348
msgid " Commit:"
msgstr " Коммит:"

#: app/flatpak-builtins-remote-info.c:349
msgid " Subject:"
msgstr " Тема:"

#: app/flatpak-builtins-remote-info.c:350
msgid " Date:"
msgstr " Дата:"

#: app/flatpak-builtins-remote-info.c:383
#, c-format
msgid "Warning: Commit %s has no flatpak metadata\n"
msgstr "Предупреждение: Коммит %s не содержит метаданных flatpak\n"

#: app/flatpak-builtins-remote-list.c:43
msgid "Show remote details"
msgstr "Показать подробности про удалённый репозиторий"

#: app/flatpak-builtins-remote-list.c:44
msgid "Show disabled remotes"
msgstr "Показать отключённые удалённые репозитории"

#: app/flatpak-builtins-remote-list.c:52
msgid "Title"
msgstr "Заголовок"

#: app/flatpak-builtins-remote-list.c:52
msgid "Show the title"
msgstr "Показать заголовок"

#: app/flatpak-builtins-remote-list.c:53
msgid "Show the URL"
msgstr "Показать адрес"

#: app/flatpak-builtins-remote-list.c:54
msgid "Show the collection ID"
msgstr "Показать ID коллекции"

#: app/flatpak-builtins-remote-list.c:55 app/flatpak-builtins-repo.c:392
msgid "Subset"
msgstr "Подмножество"

#: app/flatpak-builtins-remote-list.c:55
msgid "Show the subset"
msgstr "Показать подмножество"

#: app/flatpak-builtins-remote-list.c:56
msgid "Filter"
msgstr "Фильтр"

#: app/flatpak-builtins-remote-list.c:56
msgid "Show filter file"
msgstr "Показать файл фильтра"

#: app/flatpak-builtins-remote-list.c:57
msgid "Priority"
msgstr "Приоритет"

#: app/flatpak-builtins-remote-list.c:57
msgid "Show the priority"
msgstr "Показать приоритет"

#: app/flatpak-builtins-remote-list.c:59
msgid "Comment"
msgstr "Комментарий"

#: app/flatpak-builtins-remote-list.c:59
msgid "Show comment"
msgstr "Показать комментарий"

#: app/flatpak-builtins-remote-list.c:60
msgid "Show description"
msgstr "Показать описание"

#: app/flatpak-builtins-remote-list.c:61
msgid "Homepage"
msgstr "Домашняя страница"

#: app/flatpak-builtins-remote-list.c:61
msgid "Show homepage"
msgstr "Показать домашнюю страницу"

#: app/flatpak-builtins-remote-list.c:62
msgid "Icon"
msgstr "Значок"

#: app/flatpak-builtins-remote-list.c:62
msgid "Show icon"
msgstr "Показать значок"

#: app/flatpak-builtins-remote-list.c:231
msgid " - List remote repositories"
msgstr " - Показать удалённые репозитории"

#: app/flatpak-builtins-remote-ls.c:52
msgid "Show arches and branches"
msgstr "Показать архитектуры и ветви"

#: app/flatpak-builtins-remote-ls.c:53
msgid "Show only runtimes"
msgstr "Показать только среды исполнения"

#: app/flatpak-builtins-remote-ls.c:54
msgid "Show only apps"
msgstr "Показать только приложения"

#: app/flatpak-builtins-remote-ls.c:55
msgid "Show only those where updates are available"
msgstr "Показать элементы с доступными обновлениями"

#: app/flatpak-builtins-remote-ls.c:56
msgid "Limit to this arch (* for all)"
msgstr "Показать только указанные архитектуры (* для всех)"

#: app/flatpak-builtins-remote-ls.c:77
msgid "Show the runtime"
msgstr "Показать среду выполнения"

#: app/flatpak-builtins-remote-ls.c:79
msgid "Download size"
msgstr "Размер загрузки"

#: app/flatpak-builtins-remote-ls.c:79
msgid "Show the download size"
msgstr "Показать размер загрузки"

#: app/flatpak-builtins-remote-ls.c:391
msgid " [REMOTE or URI] - Show available runtimes and applications"
msgstr ""
" [УДАЛЁННЫЙ_РЕПО или URI] - Показать доступные среды выполнения и приложения"

#: app/flatpak-builtins-remote-modify.c:67
msgid "Enable GPG verification"
msgstr "Включить проверку GPG"

#: app/flatpak-builtins-remote-modify.c:68
msgid "Mark the remote as enumerate"
msgstr "Пометить удалённый репозиторий как просматриваемый"

#: app/flatpak-builtins-remote-modify.c:69
msgid "Mark the remote as used for dependencies"
msgstr ""
"Пометить удалённый репозиторий как используемый для поиска зависимостей"

#: app/flatpak-builtins-remote-modify.c:70
#, fuzzy
msgid "Set a new URL"
msgstr "Указать новый адрес url"

#: app/flatpak-builtins-remote-modify.c:71
msgid "Set a new subset to use"
msgstr "Задать новое подмножество"

#: app/flatpak-builtins-remote-modify.c:72
msgid "Enable the remote"
msgstr "Включить удалённый репозиторий"

#: app/flatpak-builtins-remote-modify.c:73
msgid "Update extra metadata from the summary file"
msgstr ""
"Обновить метаданные дополнительных данных из файла со сводной информацией"

#: app/flatpak-builtins-remote-modify.c:91
msgid "Disable local filter"
msgstr "Отключить локальный фильтр"

#: app/flatpak-builtins-remote-modify.c:95
msgid "Authenticator options"
msgstr "Параметры аутентификатора"

#: app/flatpak-builtins-remote-modify.c:98
msgid "Follow the redirect set in the summary file"
msgstr "Следовать перенаправлению, указанному в файле сводки"

#: app/flatpak-builtins-remote-modify.c:306
msgid "NAME - Modify a remote repository"
msgstr "ИМЯ - Изменить удалённый репозиторий"

#: app/flatpak-builtins-remote-modify.c:316
msgid "Remote NAME must be specified"
msgstr "Должно быть указано ИМЯ для удалённого репозитория"

#: app/flatpak-builtins-remote-modify.c:327
#, c-format
msgid "Updating extra metadata from remote summary for %s\n"
msgstr ""
"Обновление метаданных дополнительных данных из файла со сводной информацией "
"в удалённом репозитории для %s\n"

#: app/flatpak-builtins-remote-modify.c:330
#, c-format
msgid "Error updating extra metadata for '%s': %s\n"
msgstr "Ошибка при обновлении метаданных дополнительных данных для '%s': %s\n"

#: app/flatpak-builtins-remote-modify.c:331
#, c-format
msgid "Could not update extra metadata for %s"
msgstr "Не удалось обновить дополнительные метаданные для %s"

#: app/flatpak-builtins-repair.c:43
msgid "Don't make any changes"
msgstr "Не вносить никаких изменений"

#: app/flatpak-builtins-repair.c:44
msgid "Reinstall all refs"
msgstr "Переустановить все ссылки"

#: app/flatpak-builtins-repair.c:68
#, c-format
msgid "Object missing: %s.%s\n"
msgstr "Объект отсутствует: %s.%s\n"

#: app/flatpak-builtins-repair.c:76
#, c-format
msgid "Object invalid: %s.%s\n"
msgstr "Объект недействителен: %s.%s\n"

#: app/flatpak-builtins-repair.c:81
#, c-format
msgid "%s, deleting object\n"
msgstr "%s, удаление объекта\n"

#: app/flatpak-builtins-repair.c:146
#, c-format
msgid "Can't load object %s: %s\n"
msgstr "Невозможно загрузить объект %s: %s\n"

#: app/flatpak-builtins-repair.c:228
#, c-format
msgid "Commit invalid %s: %s\n"
msgstr "Коммит недействителен %s: %s\n"

#: app/flatpak-builtins-repair.c:231
#, c-format
msgid "Deleting invalid commit %s: %s\n"
msgstr "Удаление недействительного коммита %s: %s\n"

#: app/flatpak-builtins-repair.c:261
#, c-format
msgid "Commit should be marked partial: %s\n"
msgstr "Коммит должен быть помечен как частичный: %s\n"

#: app/flatpak-builtins-repair.c:264
#, c-format
msgid "Marking commit as partial: %s\n"
msgstr "Пометка коммита как частичного: %s\n"

#: app/flatpak-builtins-repair.c:293
#, c-format
msgid "Problems loading data for %s: %s\n"
msgstr "Проблемы при загрузке данных для %s: %s\n"

#: app/flatpak-builtins-repair.c:306
#, c-format
msgid "Error reinstalling %s: %s\n"
msgstr "Ошибка при переустановке %s: %s\n"

#: app/flatpak-builtins-repair.c:327
msgid "- Repair a flatpak installation"
msgstr "- Исправить установку flatpak"

#: app/flatpak-builtins-repair.c:406
#, c-format
msgid "Removing non-deployed ref %s…\n"
msgstr "Удаление неразвёрнутой ссылки %s…\n"

#: app/flatpak-builtins-repair.c:411
#, c-format
msgid "Skipping non-deployed ref %s…\n"
msgstr "Пропуск неразвёрнутой ссылки %s…\n"

#: app/flatpak-builtins-repair.c:429
#, c-format
msgid "[%d/%d] Verifying %s…\n"
msgstr "[%d/%d] Проверяется %s...\n"

#: app/flatpak-builtins-repair.c:435
#, c-format
msgid "Dry run: "
msgstr "Пробный запуск: "

#: app/flatpak-builtins-repair.c:440
#, c-format
msgid "Deleting ref %s due to missing objects\n"
msgstr "Удаление ссылки %s из-за отсутствующих объектов\n"

#: app/flatpak-builtins-repair.c:444
#, c-format
msgid "Deleting ref %s due to invalid objects\n"
msgstr "Удаление ссылки %s из-за недействительных объектов\n"

#: app/flatpak-builtins-repair.c:448
#, c-format
msgid "Deleting ref %s due to %d\n"
msgstr "Удаление ссылки %s из-за %d\n"

#: app/flatpak-builtins-repair.c:464
#, c-format
msgid "Checking remotes...\n"
msgstr "Проверка удалённых репозиториев...\n"

#: app/flatpak-builtins-repair.c:482
#, c-format
msgid "Remote %s for ref %s is missing\n"
msgstr "Удаленный репозиторий %s для ссылки %s отсутствует\n"

#: app/flatpak-builtins-repair.c:484
#, c-format
msgid "Remote %s for ref %s is disabled\n"
msgstr "Удалённый репозиторий %s для ссылки %s отключён\n"

#: app/flatpak-builtins-repair.c:490
#, c-format
msgid "Pruning objects\n"
msgstr "Очистка объектов\n"

#: app/flatpak-builtins-repair.c:498
#, c-format
msgid "Erasing .removed\n"
msgstr "Удаление .removed\n"

#: app/flatpak-builtins-repair.c:524
#, c-format
msgid "Reinstalling refs\n"
msgstr "Переустановка ссылок\n"

#: app/flatpak-builtins-repair.c:526
#, c-format
msgid "Reinstalling removed refs\n"
msgstr "Переустановка удалённых ссылок\n"

#: app/flatpak-builtins-repair.c:551
#, c-format
msgid "While removing appstream for %s: "
msgstr "Во время удаления appstream для %s: "

#: app/flatpak-builtins-repair.c:558
#, c-format
msgid "While deploying appstream for %s: "
msgstr "Во время развёртывания appstream для %s: "

#: app/flatpak-builtins-repo.c:106
#, c-format
msgid "Repo mode: %s\n"
msgstr "Режим репозитория: %s\n"

#: app/flatpak-builtins-repo.c:113
#, c-format
msgid "Indexed summaries: %s\n"
msgstr "Индексированные сводки: %s\n"

#: app/flatpak-builtins-repo.c:113 app/flatpak-builtins-repo.c:139
#: app/flatpak-builtins-repo.c:172
msgid "true"
msgstr "true"

#: app/flatpak-builtins-repo.c:113 app/flatpak-builtins-repo.c:139
#: app/flatpak-builtins-repo.c:172
msgid "false"
msgstr "false"

#: app/flatpak-builtins-repo.c:121
#, c-format
msgid "Subsummaries: "
msgstr "Дочерние сводки: "

#: app/flatpak-builtins-repo.c:136
#, c-format
msgid "Cache version: %d\n"
msgstr "Версия кэша: %d\n"

#: app/flatpak-builtins-repo.c:139
#, c-format
msgid "Indexed deltas: %s\n"
msgstr "Индексированные дельты: %s\n"

#: app/flatpak-builtins-repo.c:142
#, c-format
msgid "Title: %s\n"
msgstr "Заголовок: %s\n"

#: app/flatpak-builtins-repo.c:145
#, c-format
msgid "Comment: %s\n"
msgstr "Комментарий: %s\n"

#: app/flatpak-builtins-repo.c:148
#, c-format
msgid "Description: %s\n"
msgstr "Описание: %s\n"

#: app/flatpak-builtins-repo.c:151
#, c-format
msgid "Homepage: %s\n"
msgstr "Домашняя страница: %s\n"

#: app/flatpak-builtins-repo.c:154
#, c-format
msgid "Icon: %s\n"
msgstr "Значок: %s\n"

#: app/flatpak-builtins-repo.c:157
#, c-format
msgid "Collection ID: %s\n"
msgstr "ID коллекции: %s\n"

#: app/flatpak-builtins-repo.c:160
#, c-format
msgid "Default branch: %s\n"
msgstr "Ветвь по-умолчанию: %s\n"

#: app/flatpak-builtins-repo.c:163
#, c-format
msgid "Redirect URL: %s\n"
msgstr "Адрес перенаправления: %s\n"

#: app/flatpak-builtins-repo.c:166
#, c-format
msgid "Deploy collection ID: %s\n"
msgstr "ID коллекции развертывания: %s\n"

#: app/flatpak-builtins-repo.c:169
#, c-format
msgid "Authenticator name: %s\n"
msgstr "Имя аутентификатора: %s\n"

#: app/flatpak-builtins-repo.c:172
#, c-format
msgid "Authenticator install: %s\n"
msgstr "Установка аутентификатора: %s\n"

#: app/flatpak-builtins-repo.c:180
#, c-format
msgid "GPG key hash: %s\n"
msgstr "Хеш ключа GPG: %s\n"

#: app/flatpak-builtins-repo.c:184
#, c-format
msgid "%zd summary branches\n"
msgstr "%zd итоговые ветви\n"

#: app/flatpak-builtins-repo.c:336
msgid "Installed"
msgstr "Установлено"

#. Translators: Download is used here as a noun
#: app/flatpak-builtins-repo.c:338 app/flatpak-cli-transaction.c:1462
msgid "Download"
msgstr "Загрузка"

#: app/flatpak-builtins-repo.c:339
msgid "Subsets"
msgstr "Подмножества"

#: app/flatpak-builtins-repo.c:393
msgid "Digest"
msgstr "Дайджест"

#: app/flatpak-builtins-repo.c:394
msgid "History length"
msgstr "Длина истории"

#: app/flatpak-builtins-repo.c:711
msgid "Print general information about the repository"
msgstr "Вывести общую информацию о репозитории"

#: app/flatpak-builtins-repo.c:712
msgid "List the branches in the repository"
msgstr "Список ветвей в репозитории"

#: app/flatpak-builtins-repo.c:713
msgid "Print metadata for a branch"
msgstr "Вывести метаданные для ветви"

#: app/flatpak-builtins-repo.c:714
msgid "Show commits for a branch"
msgstr "Показать коммиты для ветви"

#: app/flatpak-builtins-repo.c:715
msgid "Print information about the repo subsets"
msgstr "Вывести информацию о подмножествах в репозитории"

#: app/flatpak-builtins-repo.c:716
msgid "Limit information to subsets with this prefix"
msgstr "Ограничить информацию подмножествами с данным префиксом"

#: app/flatpak-builtins-repo.c:732
msgid "LOCATION - Repository maintenance"
msgstr "ПУТЬ - Сопровождение репозитория"

#: app/flatpak-builtins-run.c:159
msgid "Command to run"
msgstr "Команда для запуска"

#: app/flatpak-builtins-run.c:160
msgid "Directory to run the command in"
msgstr "Каталог, в котором запустить команду"

#: app/flatpak-builtins-run.c:161
msgid "Branch to use"
msgstr "Ветвь для использования"

#: app/flatpak-builtins-run.c:162
msgid "Use development runtime"
msgstr "Использовать среду выполнения для разработчиков"

#: app/flatpak-builtins-run.c:163
msgid "Runtime to use"
msgstr "Используемая среда выполнения"

#: app/flatpak-builtins-run.c:164
msgid "Runtime version to use"
msgstr "Версия среды выполнения"

#: app/flatpak-builtins-run.c:167
msgid "Log accessibility bus calls"
msgstr "Журналировать вызовы шины универсального доступа"

#: app/flatpak-builtins-run.c:168
msgid "Don't proxy accessibility bus calls"
msgstr "Не проксировать вызовы шины универсального доступа"

#: app/flatpak-builtins-run.c:169
msgid "Proxy accessibility bus calls (default except when sandboxed)"
msgstr ""
"Проксировать вызовы шины универсального доступа (по-умолчанию, если не "
"включена изоляция)"

#: app/flatpak-builtins-run.c:170
msgid "Don't proxy session bus calls"
msgstr "Не проксировать вызовы пользовательской шины"

#: app/flatpak-builtins-run.c:171
msgid "Proxy session bus calls (default except when sandboxed)"
msgstr ""
"Проксировать вызовы пользовательской шины (по-умолчанию, если не включена "
"изоляция)"

#: app/flatpak-builtins-run.c:172
msgid "Don't start portals"
msgstr "Не запускать порталы"

#: app/flatpak-builtins-run.c:173
msgid "Enable file forwarding"
msgstr "Включить проброс файлов"

#: app/flatpak-builtins-run.c:174
msgid "Run specified commit"
msgstr "Запустить указанный коммит"

#: app/flatpak-builtins-run.c:175
msgid "Use specified runtime commit"
msgstr "Использовать указанный коммит среды выполнения"

#: app/flatpak-builtins-run.c:176
msgid "Run completely sandboxed"
msgstr "Запустить полностью изолированным"

#: app/flatpak-builtins-run.c:178
msgid "Use PID as parent pid for sharing namespaces"
msgstr ""
"Использовать ID_ПРОЦЕССА как номер процесса для совместного использования "
"пространств имен"

#: app/flatpak-builtins-run.c:179
msgid "Make processes visible in parent namespace"
msgstr "Сделать процессы видимыми в родительском пространстве имен"

#: app/flatpak-builtins-run.c:180
msgid "Share process ID namespace with parent"
msgstr "Использовать общее с родителем пространство имён ID процессов"

#: app/flatpak-builtins-run.c:181
msgid "Write the instance ID to the given file descriptor"
msgstr "Записать ID экземпляра в указанный файловый дескриптор"

#: app/flatpak-builtins-run.c:182
msgid "Use PATH instead of the app's /app"
msgstr "Использовать ПУТЬ вместо /app приложения"

#: app/flatpak-builtins-run.c:183
#, fuzzy
msgid "Use FD instead of the app's /app"
msgstr "Использовать ПУТЬ вместо /app приложения"

#: app/flatpak-builtins-run.c:183 app/flatpak-builtins-run.c:185
#: app/flatpak-builtins-run.c:187 app/flatpak-builtins-run.c:188
#: common/flatpak-context.c:2672
msgid "FD"
msgstr "ДЕСКРИПТОР"

#: app/flatpak-builtins-run.c:184
msgid "Use PATH instead of the runtime's /usr"
msgstr "Использовать ПУТЬ вместо /usr среды выполнения"

#: app/flatpak-builtins-run.c:185
#, fuzzy
msgid "Use FD instead of the runtime's /usr"
msgstr "Использовать ПУТЬ вместо /usr среды выполнения"

#: app/flatpak-builtins-run.c:186
#, fuzzy
msgid "Clear all outside environment variables"
msgstr "Установить переменную окружения"

#: app/flatpak-builtins-run.c:187
msgid ""
"Bind mount the file or directory referred to by FD to its canonicalized path"
msgstr ""

#: app/flatpak-builtins-run.c:188
msgid ""
"Bind mount the file or directory referred to by FD read-only to its "
"canonicalized path"
msgstr ""

#: app/flatpak-builtins-run.c:219
msgid "APP [ARGUMENT…] - Run an app"
msgstr "ПРИЛОЖЕНИЕ [АРГУМЕНТ…] - Запустить приложение"

#: app/flatpak-builtins-run.c:370
#, c-format
msgid "runtime/%s/%s/%s not installed"
msgstr "runtime/%s/%s/%s не установлено"

#: app/flatpak-builtins-run.c:419
msgid "app-fd and app-path cannot both be used"
msgstr ""

#: app/flatpak-builtins-run.c:449
msgid "usr-fd and usr-path cannot both be used"
msgstr ""

#: app/flatpak-builtins-search.c:37
msgid "Arch to search for"
msgstr "Искать указанную архитектуру"

#: app/flatpak-builtins-search.c:49
msgid "Remotes"
msgstr "Удаленные репозитории"

#: app/flatpak-builtins-search.c:49
msgid "Show the remotes"
msgstr "Показать удалённые репозитории"

#: app/flatpak-builtins-search.c:244
msgid "TEXT - Search remote apps/runtimes for text"
msgstr "ТЕКСТ - Искать удалённые приложения/среды по тексту"

#: app/flatpak-builtins-search.c:255
msgid "TEXT must be specified"
msgstr "ТЕКСТ должен быть указан"

#: app/flatpak-builtins-search.c:338
msgid "No matches found"
msgstr "Совпадений не найдено"

#: app/flatpak-builtins-uninstall.c:54
msgid "Arch to uninstall"
msgstr "Удаляемая архитектура"

#: app/flatpak-builtins-uninstall.c:55
msgid "Keep ref in local repository"
msgstr "Сохранить ссылку в локальном репозитории"

#: app/flatpak-builtins-uninstall.c:56
msgid "Don't uninstall related refs"
msgstr "Не удалять связанные ссылки"

#: app/flatpak-builtins-uninstall.c:57
msgid "Remove files even if running"
msgstr "Удалять файлы даже если запущено"

#: app/flatpak-builtins-uninstall.c:60
msgid "Uninstall all"
msgstr "Удалить всё"

#: app/flatpak-builtins-uninstall.c:61
msgid "Uninstall unused"
msgstr "Удалить неиспользуемое"

#: app/flatpak-builtins-uninstall.c:62
msgid "Delete app data"
msgstr "Удалить данные приложения"

#: app/flatpak-builtins-uninstall.c:141
#, c-format
msgid "Delete data for %s?"
msgstr "Удалить данные для %s?"

#: app/flatpak-builtins-uninstall.c:220
#, c-format
msgid "Info: applications using the extension %s%s%s branch %s%s%s:\n"
msgstr "Информация: приложения, использующие расширение %s%s%s ветвь %s%s%s:\n"

#: app/flatpak-builtins-uninstall.c:223
#, c-format
msgid "Info: applications using the runtime %s%s%s branch %s%s%s:\n"
msgstr ""
"Информация: приложения, использующие среду выполнения %s%s%s ветвь %s%s%s:\n"

#: app/flatpak-builtins-uninstall.c:238
msgid "Really remove?"
msgstr "Действительно удалить?"

#: app/flatpak-builtins-uninstall.c:255
msgid "[REF…] - Uninstall applications or runtimes"
msgstr "[ССЫЛКА…] - Удалить приложения или среды выполнения"

#: app/flatpak-builtins-uninstall.c:264
msgid "Must specify at least one REF, --unused, --all or --delete-data"
msgstr ""
"Должна быть указана как минимум одна ССЫЛКА, --unused, --all или --delete-"
"data"

#: app/flatpak-builtins-uninstall.c:267
msgid "Must not specify REFs when using --all"
msgstr "ССЫЛКИ не должны быть указаны по время использования --all"

#: app/flatpak-builtins-uninstall.c:270
msgid "Must not specify REFs when using --unused"
msgstr "ССЫЛКИ не должны быть указаны во время использования --unused"

#: app/flatpak-builtins-uninstall.c:336
#, c-format
msgid ""
"\n"
"These runtimes in installation '%s' are pinned and won't be removed; see "
"flatpak-pin(1):\n"
msgstr ""
"\n"
"Эти среды выполнения в установке '%s' закреплены и не будут удалены; см. "
"flatpak-pin(1):\n"

#: app/flatpak-builtins-uninstall.c:370
#, c-format
msgid "Nothing unused to uninstall\n"
msgstr "Нет неиспользуемого для удаления\n"

#: app/flatpak-builtins-uninstall.c:444
#, c-format
msgid "No installed refs found for ‘%s’"
msgstr "Для '%s' не найдено установленных ссылок"

#: app/flatpak-builtins-uninstall.c:447
#, c-format
msgid " with arch ‘%s’"
msgstr " с архитектурой '%s'"

#: app/flatpak-builtins-uninstall.c:449
#, c-format
msgid " with branch ‘%s’"
msgstr " с ветвью '%s'"

#: app/flatpak-builtins-uninstall.c:456
#, c-format
msgid "Warning: %s is not installed\n"
msgstr "Предупреждение: %s не установлено\n"

#: app/flatpak-builtins-uninstall.c:490
#, c-format
msgid "None of the specified refs are installed"
msgstr "Ни одна из указанных ссылок не установлена"

#: app/flatpak-builtins-uninstall.c:599
#, c-format
msgid "No app data to delete\n"
msgstr "Нет данных приложения для удаления\n"

#: app/flatpak-builtins-update.c:56
msgid "Arch to update for"
msgstr "Обновляемая архитектура"

#: app/flatpak-builtins-update.c:57
msgid "Commit to deploy"
msgstr "Коммит для развёртывания"

#: app/flatpak-builtins-update.c:58
msgid "Remove old files even if running"
msgstr "Удалять старые файлы даже если запущено"

#: app/flatpak-builtins-update.c:59
msgid "Don't pull, only update from local cache"
msgstr "Не скачивать, обновлять только из локального кеша"

#: app/flatpak-builtins-update.c:61
msgid "Don't update related refs"
msgstr "Не обновлять связанные ссылки"

#: app/flatpak-builtins-update.c:66
msgid "Update appstream for remote"
msgstr "Обновить appstream для удалённого репозитория"

#: app/flatpak-builtins-update.c:67
msgid "Only update this subpath"
msgstr "Обновлять только указанный подкаталог"

#: app/flatpak-builtins-update.c:90
msgid "[REF…] - Update applications or runtimes"
msgstr "[ССЫЛКА…] - Обновить приложения или среды выполнения"

#: app/flatpak-builtins-update.c:121
msgid "With --commit, only one REF may be specified"
msgstr "При указании --commit, должна быть указана хотя бы одна ССЫЛКА"

#: app/flatpak-builtins-update.c:162
#, c-format
msgid "Looking for updates…\n"
msgstr "Поиск обновлений…\n"

#: app/flatpak-builtins-update.c:215
#, c-format
msgid "Unable to update %s: %s\n"
msgstr "Не удалось обновить %s: %s\n"

#: app/flatpak-builtins-update.c:274
#, fuzzy, c-format
msgid "Nothing to update.\n"
msgstr "Нечего выполнять.\n"

#: app/flatpak-builtins-utils.c:337
#, fuzzy, c-format
msgid ""
"Remote ‘%s’ found in multiple installations, unable to proceed in non-"
"interactive mode"
msgstr ""
"Ссылка ‘%s’ найдена в нескольких установках: %s. Вы должны указать одну."

#: app/flatpak-builtins-utils.c:346
#, c-format
msgid "Remote ‘%s’ found in multiple installations:"
msgstr "Удалённый репозиторий ‘%s’ найден в нескольких установках:"

#: app/flatpak-builtins-utils.c:347 app/flatpak-builtins-utils.c:442
#: app/flatpak-builtins-utils.c:538 app/flatpak-builtins-utils.c:540
#: app/flatpak-builtins-utils.c:598
msgid "Which do you want to use (0 to abort)?"
msgstr "Какой вы хотите использовать (0 - отмена)?"

#: app/flatpak-builtins-utils.c:349
#, c-format
msgid "No remote chosen to resolve ‘%s’ which exists in multiple installations"
msgstr ""
"Не выбран удаленный репозиторий для разрешения '%s', который существует в "
"нескольких местах"

#: app/flatpak-builtins-utils.c:358
#, c-format
msgid ""
"Remote \"%s\" not found\n"
"Hint: Use flatpak remote-add to add a remote"
msgstr ""
"Удаленный репозиторий '%s' не найден\n"
"Подсказка: Используйте flatpak remote-add для добавления удаленного "
"репозитория"

#: app/flatpak-builtins-utils.c:364
#, c-format
msgid "Remote \"%s\" not found in the %s installation"
msgstr "Удаленный репозиторий '%s' не найден в месте %s"

#: app/flatpak-builtins-utils.c:404
#, c-format
msgid "Multiple refs match ‘%s’, unable to proceed in non-interactive mode"
msgstr ""

#. default to yes on Enter
#: app/flatpak-builtins-utils.c:430
#, c-format
msgid ""
"Found ref ‘%s’ in remote ‘%s’ (%s).\n"
"Use this ref?"
msgstr ""
"Найдена ссылка '%s' в репозитории '%s' (%s).\n"
"Использовать эту ссылку?"

#: app/flatpak-builtins-utils.c:434 app/flatpak-builtins-utils.c:444
#: app/flatpak-builtins-utils.c:522 app/flatpak-builtins-utils.c:543
#, c-format
msgid "No ref chosen to resolve matches for ‘%s’"
msgstr "Не выбрана ссылка для разрешения совпадений '%s'"

#: app/flatpak-builtins-utils.c:440
#, c-format
msgid "Similar refs found for ‘%s’ in remote ‘%s’ (%s):"
msgstr "Похожие ссылки для '%s' найдены в репозитории '%s' (%s):"

#: app/flatpak-builtins-utils.c:488
#, c-format
msgid ""
"Multiple installed refs match ‘%s’, unable to proceed in non-interactive mode"
msgstr ""

#. default to yes on Enter
#: app/flatpak-builtins-utils.c:518
#, c-format
msgid "Found installed ref ‘%s’ (%s). Is this correct?"
msgstr "Найдена установленная ссылка '%s' (%s). Она верна?"

#: app/flatpak-builtins-utils.c:534
#, c-format
msgid "All of the above"
msgstr "Все вышеперечисленное"

#: app/flatpak-builtins-utils.c:535
#, c-format
msgid "Similar installed refs found for ‘%s’:"
msgstr "Похожие установочные ссылки, найденные для '%s':"

#: app/flatpak-builtins-utils.c:579
#, c-format
msgid ""
"Multiple remotes have refs matching ‘%s’, unable to proceed in non-"
"interactive mode"
msgstr ""

#: app/flatpak-builtins-utils.c:597
#, c-format
msgid "Remotes found with refs similar to ‘%s’:"
msgstr "Репозитории со ссылками, похожими на '%s':"

#: app/flatpak-builtins-utils.c:600
#, c-format
msgid "No remote chosen to resolve matches for ‘%s’"
msgstr "Не выбран репозиторий для получения результатов '%s'"

#: app/flatpak-builtins-utils.c:696 app/flatpak-builtins-utils.c:699
#, c-format
msgid "Updating appstream data for user remote %s"
msgstr ""
"Обновление данных appstream для пользовательского удалённого репозитория %s"

#: app/flatpak-builtins-utils.c:706 app/flatpak-builtins-utils.c:709
#, c-format
msgid "Updating appstream data for remote %s"
msgstr "Обновление данных appstream для удалённого репозитория %s"

#: app/flatpak-builtins-utils.c:717 app/flatpak-builtins-utils.c:719
msgid "Error updating"
msgstr "Ошибка обновления"

#: app/flatpak-builtins-utils.c:755
#, c-format
msgid "Remote \"%s\" not found"
msgstr "Репозиторий '%s' не найден"

#: app/flatpak-builtins-utils.c:796
#, c-format
msgid "Ambiguous suffix: '%s'."
msgstr "Неоднозначный суффикс: '%s'."

#. Translators: don't translate the values
#: app/flatpak-builtins-utils.c:798 app/flatpak-builtins-utils.c:813
msgid "Possible values are :s[tart], :m[iddle], :e[nd] or :f[ull]"
msgstr "Возможные значения: :s[tart], :m[iddle], :e[nd] или :f[ull]"

#: app/flatpak-builtins-utils.c:811
#, c-format
msgid "Invalid suffix: '%s'."
msgstr "Неверный суффикс '%s'."

#: app/flatpak-builtins-utils.c:846
#, c-format
msgid "Ambiguous column: %s"
msgstr "Неоднозначный столбец: %s"

#: app/flatpak-builtins-utils.c:859
#, c-format
msgid "Unknown column: %s"
msgstr "Неизвестный столбец '%s'"

#: app/flatpak-builtins-utils.c:917
msgid "Available columns:\n"
msgstr "Доступные столбцы:\n"

#: app/flatpak-builtins-utils.c:927
msgid "Show all columns"
msgstr "Показать все столбцы"

#: app/flatpak-builtins-utils.c:928
msgid "Show available columns"
msgstr "Показать доступные столбцы"

#: app/flatpak-builtins-utils.c:931
msgid "Append :s[tart], :m[iddle], :e[nd] or :f[ull] to change ellipsization"
msgstr "Добавьте :s[tart], :m[iddle], :e[nd], :f[ull] для изменения эллепсии"

#: app/flatpak-builtins-utils.c:1483
#, c-format
msgid "Unknown scheme in sideload location %s"
msgstr ""

#: app/flatpak-cli-transaction.c:96 app/flatpak-cli-transaction.c:102
#, c-format
msgid "Required runtime for %s (%s) found in remote %s\n"
msgstr ""
"Требуемая среда выполнения для %s (%s) найдена в удалённом репозитории %s\n"

#: app/flatpak-cli-transaction.c:104
msgid "Do you want to install it?"
msgstr "Хотите установить её?"

#: app/flatpak-cli-transaction.c:110
#, c-format
msgid "Required runtime for %s (%s) found in remotes:"
msgstr ""
"Требуемая среда выполнения для %s (%s) найдена в следующих репозиториях:"

#: app/flatpak-cli-transaction.c:112
msgid "Which do you want to install (0 to abort)?"
msgstr "Которую версию установить (0 - отмена)?"

#: app/flatpak-cli-transaction.c:132
#, c-format
msgid "Configuring %s as new remote '%s'\n"
msgstr "Настройка %s как новый удаленный репозиторий '%s'\n"

#. default to yes on Enter
#: app/flatpak-cli-transaction.c:139
#, c-format
msgid ""
"The remote '%s', referred to by '%s' at location %s contains additional "
"applications.\n"
"Should the remote be kept for future installations?"
msgstr ""
"Удаленный репозиторий '%s', на который ссылается '%s' располагающийся в %s "
"содержит дополнительные приложения.\n"
"Должен ли этот репозиторий использоваться для будущих установок?"

#. default to yes on Enter
#: app/flatpak-cli-transaction.c:147
#, c-format
msgid ""
"The application %s depends on runtimes from:\n"
"  %s\n"
"Configure this as new remote '%s'"
msgstr ""
"Приложение %s зависит от сред выполнения из:\n"
"  %s\n"
"Добавить его как новый удалённый репозиторий '%s'"

#. Formatted size/remaining time in seconds
#: app/flatpak-cli-transaction.c:321
#, c-format
msgid "%s/s%s%s"
msgstr ""

#. Download progress percentage, use the appropriate
#. percent format for your language
#: app/flatpak-cli-transaction.c:359
#, c-format
msgid "%3d%%"
msgstr ""

#: app/flatpak-cli-transaction.c:414
msgid "Installing…"
msgstr "Установка…"

#: app/flatpak-cli-transaction.c:416
#, c-format
msgid "Installing %d/%d…"
msgstr "Установка %d/%d…"

#: app/flatpak-cli-transaction.c:421
msgid "Updating…"
msgstr "Обновление…"

#: app/flatpak-cli-transaction.c:423
#, c-format
msgid "Updating %d/%d…"
msgstr "Обновление: %d/%d…"

#: app/flatpak-cli-transaction.c:428
msgid "Uninstalling…"
msgstr "Удаление…"

#: app/flatpak-cli-transaction.c:430
#, c-format
msgid "Uninstalling %d/%d…"
msgstr "Удаление %d/%d…"

#: app/flatpak-cli-transaction.c:496 app/flatpak-quiet-transaction.c:161
#, c-format
msgid "Info: %s was skipped"
msgstr "Информация: %s был пропущен"

#: app/flatpak-cli-transaction.c:519
#, c-format
msgid "Warning: %s%s%s already installed"
msgstr "Предупреждение: %s%s%s уже установлено"

#: app/flatpak-cli-transaction.c:522
#, c-format
msgid "Error: %s%s%s already installed"
msgstr "Ошибка: %s%s%s уже установлено"

#: app/flatpak-cli-transaction.c:528
#, c-format
msgid "Warning: %s%s%s not installed"
msgstr "Предупреждение: %s%s%s не установлено"

#: app/flatpak-cli-transaction.c:531
#, c-format
msgid "Error: %s%s%s not installed"
msgstr "Ошибка: %s%s%s не установлено"

#: app/flatpak-cli-transaction.c:537
#, c-format
msgid "Warning: %s%s%s needs a later flatpak version"
msgstr "Предупреждение: %s%s%s требует более новую версию flatpak"

#: app/flatpak-cli-transaction.c:540
#, c-format
msgid "Error: %s%s%s needs a later flatpak version"
msgstr "Ошибка: %s%s%s требует более новую версию flatpak"

#: app/flatpak-cli-transaction.c:546
msgid "Warning: Not enough disk space to complete this operation"
msgstr ""
"Предупреждение: недостаточно места на диске для завершения этой операции"

#: app/flatpak-cli-transaction.c:548
msgid "Error: Not enough disk space to complete this operation"
msgstr "Ошибка: недостаточно места на диске для завершения этой операции"

#: app/flatpak-cli-transaction.c:553
#, c-format
msgid "Warning: %s"
msgstr "Предупреждение: %s"

#: app/flatpak-cli-transaction.c:555
#, c-format
msgid "Error: %s"
msgstr "Ошибка: %s"

#: app/flatpak-cli-transaction.c:570
#, c-format
msgid "Failed to install %s%s%s: "
msgstr "Не удалось установить %s%s%s: "

#: app/flatpak-cli-transaction.c:577
#, c-format
msgid "Failed to update %s%s%s: "
msgstr "Не удалось обновить %s%s%s: "

#: app/flatpak-cli-transaction.c:584
#, c-format
msgid "Failed to install bundle %s%s%s: "
msgstr "Не удалось установить пакет %s%s%s: "

#: app/flatpak-cli-transaction.c:591
#, c-format
msgid "Failed to uninstall %s%s%s: "
msgstr "Не удалось удалить %s%s%s: "

#: app/flatpak-cli-transaction.c:642
#, c-format
msgid "Authentication required for remote '%s'\n"
msgstr "Требуется авторизация для обновления удаленной информации о '%s'\n"

#: app/flatpak-cli-transaction.c:643
msgid "Open browser?"
msgstr "Открыть в браузере?"

#: app/flatpak-cli-transaction.c:699
#, c-format
msgid "Login required remote %s (realm %s)\n"
msgstr "Удаленному репозиторию %s необходим логин (область %s)\n"

#: app/flatpak-cli-transaction.c:704
msgid "Password"
msgstr "Пароль"

#. Only runtimes can be pinned
#: app/flatpak-cli-transaction.c:759
#, c-format
msgid ""
"\n"
"Info: (pinned) runtime %s%s%s branch %s%s%s is end-of-life, in favor of "
"%s%s%s branch %s%s%s\n"
msgstr ""
"\n"
"Информация: (закрепленная) среда выполнения %s%s%s ветвь %s%s%s конец срока "
"поддержки, в пользу %s%s%s ветвь %s%s%s\n"

#: app/flatpak-cli-transaction.c:765
#, c-format
msgid ""
"\n"
"Info: runtime %s%s%s branch %s%s%s is end-of-life, in favor of %s%s%s branch "
"%s%s%s\n"
msgstr ""
"\n"
"Информация: среда выполнения %s%s%s ветвь %s%s%s конец срока поддержки, в "
"пользу %s%s%s ветвь %s%s%s\n"

#: app/flatpak-cli-transaction.c:768
#, c-format
msgid ""
"\n"
"Info: app %s%s%s branch %s%s%s is end-of-life, in favor of %s%s%s branch "
"%s%s%s\n"
msgstr ""
"\n"
"Информация: приложение %s%s%s ветвь %s%s%s конец срока поддержки, в пользу "
"%s%s%s ветвь %s%s%s\n"

#. Only runtimes can be pinned
#: app/flatpak-cli-transaction.c:780
#, c-format
msgid ""
"\n"
"Info: (pinned) runtime %s%s%s branch %s%s%s is end-of-life, with reason:\n"
msgstr ""
"\n"
"Информация: (закрепленная) среда выполнения %s%s%s ветвь %s%s%s конец срока "
"поддержки по причине:\n"

#: app/flatpak-cli-transaction.c:786
#, c-format
msgid ""
"\n"
"Info: runtime %s%s%s branch %s%s%s is end-of-life, with reason:\n"
msgstr ""
"\n"
"Информация: среда выполнения %s%s%s ветвь %s%s%s конец срока поддержки по "
"причине:\n"

#: app/flatpak-cli-transaction.c:789
#, c-format
msgid ""
"\n"
"Info: app %s%s%s branch %s%s%s is end-of-life, with reason:\n"
msgstr ""
"\n"
"Информация: приложение %s%s%s ветвь %s%s%s конец срока поддержки по "
"причине:\n"

#: app/flatpak-cli-transaction.c:963
#, c-format
msgid "Info: applications using this extension:\n"
msgstr "Информация: приложения, использующие это расширение:\n"

#: app/flatpak-cli-transaction.c:965
#, c-format
msgid "Info: applications using this runtime:\n"
msgstr "Информация: приложения, использующие эту среду выполнения:\n"

#: app/flatpak-cli-transaction.c:984
msgid "Replace?"
msgstr "Заменить?"

#: app/flatpak-cli-transaction.c:987 app/flatpak-quiet-transaction.c:247
#, c-format
msgid "Updating to rebased version\n"
msgstr "Обновление перебазированной версии\n"

#: app/flatpak-cli-transaction.c:1011
#, c-format
msgid "Failed to rebase %s to %s: "
msgstr "Ошибка: Не удалось перезбазировать %s в %s: "

#: app/flatpak-cli-transaction.c:1277
#, c-format
msgid "New %s%s%s permissions:"
msgstr "Новые разрешения %s%s%s:"

#: app/flatpak-cli-transaction.c:1279
#, c-format
msgid "%s%s%s permissions:"
msgstr "Разрешения %s%s%s:"

#: app/flatpak-cli-transaction.c:1343
msgid "Warning: "
msgstr "Предупреждение: "

#. translators: This is short for operation, the title of a one-char column
#: app/flatpak-cli-transaction.c:1442
msgid "Op"
msgstr "Оп"

#. Avoid resizing the download column too much,
#. * by making the title as long as typical content
#.
#: app/flatpak-cli-transaction.c:1458 app/flatpak-cli-transaction.c:1503
msgid "partial"
msgstr "частично"

#: app/flatpak-cli-transaction.c:1535
msgid "Proceed with these changes to the user installation?"
msgstr "Перейти к пользовательской установке с этими изменениями?"

#: app/flatpak-cli-transaction.c:1537
msgid "Proceed with these changes to the system installation?"
msgstr "Перейти к системной установке с этими изменениями?"

#: app/flatpak-cli-transaction.c:1539
#, c-format
msgid "Proceed with these changes to the %s?"
msgstr "Перейти к %s с этими изменениями?"

#: app/flatpak-cli-transaction.c:1711
msgid "Changes complete."
msgstr "Изменения внесены."

#: app/flatpak-cli-transaction.c:1713
msgid "Uninstall complete."
msgstr "Удаление завершено."

#: app/flatpak-cli-transaction.c:1715
msgid "Installation complete."
msgstr "Установка завершена."

#: app/flatpak-cli-transaction.c:1717
msgid "Updates complete."
msgstr "Обновление завершено."

#. For updates/!stop_on_first_error we already printed all errors so we make up
#. a different one.
#: app/flatpak-cli-transaction.c:1750
msgid "There were one or more errors"
msgstr "Произошла одна или более ошибок"

#. translators: please keep the leading space
#: app/flatpak-main.c:76
msgid " Manage installed applications and runtimes"
msgstr " Управление установленными приложениями и средами выполнения"

#: app/flatpak-main.c:77
msgid "Install an application or runtime"
msgstr "Установить приложение или среду выполнения"

#: app/flatpak-main.c:78
msgid "Update an installed application or runtime"
msgstr "Обновить установленное приложение или среду выполнения"

#: app/flatpak-main.c:81
msgid "Uninstall an installed application or runtime"
msgstr "Удалить установленное приложение или среду выполнения"

#: app/flatpak-main.c:84
msgid "Mask out updates and automatic installation"
msgstr "Маскировать обновления и автоматическую установку"

#: app/flatpak-main.c:85
msgid "Pin a runtime to prevent automatic removal"
msgstr "Закрепить среду исполнения для предотвращения автоудаления"

#: app/flatpak-main.c:86
msgid "List installed apps and/or runtimes"
msgstr "Показать список установленных приложений и/или сред выполнения"

#: app/flatpak-main.c:87
msgid "Show info for installed app or runtime"
msgstr "Показать информацию об установленных приложениях или средах выполнения"

#: app/flatpak-main.c:88
msgid "Show history"
msgstr "Показать историю"

#: app/flatpak-main.c:89
msgid "Configure flatpak"
msgstr "Настроить flatpak"

#: app/flatpak-main.c:90
msgid "Repair flatpak installation"
msgstr "Исправить установку flatpak"

#: app/flatpak-main.c:91
msgid "Put applications or runtimes onto removable media"
msgstr "Поместить приложения или среды выполнения на съемный носитель"

#: app/flatpak-main.c:92
msgid "Install flatpaks that are part of the operating system"
msgstr ""

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:95
msgid ""
"\n"
" Find applications and runtimes"
msgstr ""
"\n"
"Поиск приложений или сред выполнения"

#: app/flatpak-main.c:96
msgid "Search for remote apps/runtimes"
msgstr "Поиск удаленных репозиториев/сред выполнения"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:99
msgid ""
"\n"
" Manage running applications"
msgstr ""
"\n"
" Управление запуском приложений"

#: app/flatpak-main.c:100
msgid "Run an application"
msgstr "Запустить приложение"

#: app/flatpak-main.c:101
msgid "Override permissions for an application"
msgstr "Переопределить разрешения для приложения"

#: app/flatpak-main.c:102
msgid "Specify default version to run"
msgstr "Указать версию по умолчанию для запуска"

#: app/flatpak-main.c:103
msgid "Enter the namespace of a running application"
msgstr "Войти в пространство имён запущенного приложения"

#: app/flatpak-main.c:104
msgid "Enumerate running applications"
msgstr "Перечислить запущенные приложения"

#: app/flatpak-main.c:105
msgid "Stop a running application"
msgstr "Приостановить запущенное приложение"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:108
msgid ""
"\n"
" Manage file access"
msgstr ""
"\n"
" Управление доступом к файлам"

#: app/flatpak-main.c:109
msgid "List exported files"
msgstr "Список экспортированных файлов"

#: app/flatpak-main.c:110
msgid "Grant an application access to a specific file"
msgstr "Разрешить доступ приложения к указанному файлу"

#: app/flatpak-main.c:111
msgid "Revoke access to a specific file"
msgstr "Отозвать разрешение на доступ к указанному файлу"

#: app/flatpak-main.c:112
msgid "Show information about a specific file"
msgstr "Показать информацию об указанном файле"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:116
msgid ""
"\n"
" Manage dynamic permissions"
msgstr ""
"\n"
"Изменить динамические разрешения"

#: app/flatpak-main.c:117
msgid "List permissions"
msgstr "Список разрешений"

#: app/flatpak-main.c:118
msgid "Remove item from permission store"
msgstr "Отозвать у приложения право на запись"

#: app/flatpak-main.c:120
msgid "Set permissions"
msgstr "Установить разрешения"

#: app/flatpak-main.c:121
msgid "Show app permissions"
msgstr "Показать разрешения приложения"

#: app/flatpak-main.c:122
msgid "Reset app permissions"
msgstr "Восстановить разрешения приложения"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:125
msgid ""
"\n"
" Manage remote repositories"
msgstr ""
"\n"
" Управление удалёнными репозиториями"

#: app/flatpak-main.c:126
msgid "List all configured remotes"
msgstr "Список всех настроенных удалённых репозиториев"

#: app/flatpak-main.c:127
msgid "Add a new remote repository (by URL)"
msgstr "Добавить новый удалённый репозиторий (по АДРЕСУ)"

#: app/flatpak-main.c:128
msgid "Modify properties of a configured remote"
msgstr "Изменить свойства настроенного удалённого репозитория"

#: app/flatpak-main.c:129
msgid "Delete a configured remote"
msgstr "Удалить настроенный удалённый репозиторий"

#: app/flatpak-main.c:131
msgid "List contents of a configured remote"
msgstr "Список содержимого удалённого репозитория"

#: app/flatpak-main.c:132
msgid "Show information about a remote app or runtime"
msgstr "Показать информацию об установленных приложениях или средах выполнения"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:135
msgid ""
"\n"
" Build applications"
msgstr ""
"\n"
" Сборка приложений"

#: app/flatpak-main.c:136
msgid "Initialize a directory for building"
msgstr "Инициализировать каталог для сборки"

#: app/flatpak-main.c:137
msgid "Run a build command inside the build dir"
msgstr "Запустить команду сборки в каталоге сборки"

#: app/flatpak-main.c:138
msgid "Finish a build dir for export"
msgstr "Финализировать каталог сборки для экспорта"

#: app/flatpak-main.c:139
msgid "Export a build dir to a repository"
msgstr "Экспортировать из каталога сборки в репозиторий"

#: app/flatpak-main.c:140
msgid "Create a bundle file from a ref in a local repository"
msgstr "Создать файл с пакетом из каталога сборки локального репозитория"

#: app/flatpak-main.c:141
msgid "Import a bundle file"
msgstr "Импортировать файл с пакетом"

#: app/flatpak-main.c:142
msgid "Sign an application or runtime"
msgstr "Подписать приложение или среду выполнения"

#: app/flatpak-main.c:143
msgid "Update the summary file in a repository"
msgstr "Обновить файл со сводной информацией в репозитории"

#: app/flatpak-main.c:144
msgid "Create new commit based on existing ref"
msgstr "Создать новый коммит на базе существующей ссылки"

#: app/flatpak-main.c:145
msgid "Show information about a repo"
msgstr "Получить информацию о репозитории"

#: app/flatpak-main.c:162
msgid "Show debug information, -vv for more detail"
msgstr "Показать отладочную информацию, -vv для подробных деталей"

#: app/flatpak-main.c:163
msgid "Show OSTree debug information"
msgstr "Показать отладочную информацию OSTree"

#: app/flatpak-main.c:169
msgid "Print version information and exit"
msgstr "Вывести информацию о версии и выйти"

#: app/flatpak-main.c:170
msgid "Print default arch and exit"
msgstr "Вывести архитектуру по умолчанию и выйти"

#: app/flatpak-main.c:171
msgid "Print supported arches and exit"
msgstr "Вывести поддерживаемые архитектуры и выйти"

#: app/flatpak-main.c:172
msgid "Print active gl drivers and exit"
msgstr "Показать версию графических драйверов и выйти"

#: app/flatpak-main.c:173
msgid "Print paths for system installations and exit"
msgstr "Вывести информацию о версии и выйти"

#: app/flatpak-main.c:174
msgid "Print the updated environment needed to run flatpaks"
msgstr ""
"Вывести обновлённые переменные окружения, необходимые для запуска приложений "
"flatpak"

#: app/flatpak-main.c:175
msgid "Only include the system installation with --print-updated-env"
msgstr "Включить в --print-updated-env только системные установки"

#: app/flatpak-main.c:180
msgid "Work on the user installation"
msgstr "Работать с пользовательскими установками"

#: app/flatpak-main.c:181
msgid "Work on the system-wide installation (default)"
msgstr "Работать с установками для всех пользователей (по умолчанию)"

#: app/flatpak-main.c:182
msgid "Work on a non-default system-wide installation"
msgstr "Работать с установками для всех пользователей (без умолчаний)"

#: app/flatpak-main.c:212
msgid "Builtin Commands:"
msgstr "Встроенные команды:"

#: app/flatpak-main.c:298
#, c-format
msgid ""
"Note that the directories %s are not in the search path set by the "
"XDG_DATA_DIRS environment variable, so applications installed by Flatpak may "
"not appear on your desktop until the session is restarted."
msgstr ""
"Обратите внимание, что каталоги %s не находятся по пути поиска, заданном "
"переменной окружения XDG_DATA_DIRS, поэтому приложения, установленные "
"Flatpak, могут не отображаться на рабочем столе, пока сеанс не будет "
"перезапущен."

#: app/flatpak-main.c:312
#, c-format
msgid ""
"Note that the directory %s is not in the search path set by the "
"XDG_DATA_DIRS environment variable, so applications installed by Flatpak may "
"not appear on your desktop until the session is restarted."
msgstr ""
"Обратите внимание, что каталог %s не находится по пути поиска, заданном "
"переменной окружения XDG_DATA_DIRS, поэтому приложения, установленные "
"Flatpak, могут не отображаться на вашем рабочем столе до перезапуска сеанса."

#: app/flatpak-main.c:381
msgid ""
"Refusing to operate under sudo with --user. Omit sudo to operate on the user "
"installation, or use a root shell to operate on the root user's installation."
msgstr ""
"Отказ от работы под sudo с параметром --user. Откажитесь от sudo для работы "
"с установкой пользователя, или используйте оболочку root для работы с "
"установкой пользователя root."

#: app/flatpak-main.c:453
msgid ""
"Multiple installations specified for a command that works on one installation"
msgstr ""
"Для одной команды, работающей с одной установкой, указано несколько установок"

#: app/flatpak-main.c:504 app/flatpak-main.c:697
#, c-format
msgid "See '%s --help'"
msgstr "См '%s --help'"

#: app/flatpak-main.c:706
#, c-format
msgid "'%s' is not a flatpak command. Did you mean '%s%s'?"
msgstr "'%s' не является командой flatpak. Вы имели в виду '%s%s'?"

#: app/flatpak-main.c:709
#, c-format
msgid "'%s' is not a flatpak command"
msgstr "'%s' не является командой flatpak"

#: app/flatpak-main.c:824
msgid "No command specified"
msgstr "Команда не указана"

#: app/flatpak-main.c:980
msgid "error:"
msgstr "ошибка:"

#: app/flatpak-quiet-transaction.c:77
#, c-format
msgid "Installing %s\n"
msgstr "Установка %s\n"

#: app/flatpak-quiet-transaction.c:81
#, c-format
msgid "Updating %s\n"
msgstr "Обновление %s\n"

#: app/flatpak-quiet-transaction.c:85
#, c-format
msgid "Uninstalling %s\n"
msgstr "Удаление %s\n"

#: app/flatpak-quiet-transaction.c:107
#, c-format
msgid "Warning: Failed to install %s: %s\n"
msgstr "Предупреждение: не удалось установить %s: %s\n"

#: app/flatpak-quiet-transaction.c:110
#, c-format
msgid "Error: Failed to install %s: %s\n"
msgstr "Ошибка: не удалось установить %s: %s\n"

#: app/flatpak-quiet-transaction.c:116
#, c-format
msgid "Warning: Failed to update %s: %s\n"
msgstr "Предупреждение: не удалось обновить %s: %s\n"

#: app/flatpak-quiet-transaction.c:119
#, c-format
msgid "Error: Failed to update %s: %s\n"
msgstr "Ошибка: не удалось обновить %s: %s\n"

#: app/flatpak-quiet-transaction.c:125
#, c-format
msgid "Warning: Failed to install bundle %s: %s\n"
msgstr "Предупреждение: не удалось установить пакет %s: %s\n"

#: app/flatpak-quiet-transaction.c:128
#, c-format
msgid "Error: Failed to install bundle %s: %s\n"
msgstr "Ошибка: не удалось установить пакет %s: %s\n"

#: app/flatpak-quiet-transaction.c:134
#, c-format
msgid "Warning: Failed to uninstall %s: %s\n"
msgstr "Предупреждение: не удалось удалить %s: %s\n"

#: app/flatpak-quiet-transaction.c:137
#, c-format
msgid "Error: Failed to uninstall %s: %s\n"
msgstr "Ошибка: не удалось удалить %s: %s\n"

#: app/flatpak-quiet-transaction.c:166 common/flatpak-dir.c:11475
#, c-format
msgid "%s already installed"
msgstr "%s уже установлен"

#: app/flatpak-quiet-transaction.c:168 common/flatpak-dir.c:3622
#: common/flatpak-dir.c:4321 common/flatpak-dir.c:16968
#: common/flatpak-dir.c:17258 common/flatpak-dir-utils.c:166
#: common/flatpak-dir-utils.c:259 common/flatpak-transaction.c:2736
#: common/flatpak-transaction.c:2791
#, c-format
msgid "%s not installed"
msgstr "%s не установлен"

#: app/flatpak-quiet-transaction.c:170
#, c-format
msgid "%s needs a later flatpak version"
msgstr "%s требует более новую версию flatpak"

#: app/flatpak-quiet-transaction.c:172
msgid "Not enough disk space to complete this operation"
msgstr "Недостаточно места на диске для завершения этой операции"

#: app/flatpak-quiet-transaction.c:239
#, c-format
msgid "Info: %s is end-of-life, in favor of %s\n"
msgstr "Информация: конец срока поддержки %s наступает в пользу %s\n"

#: app/flatpak-quiet-transaction.c:241
#, c-format
msgid "Info: %s is end-of-life, with reason: %s\n"
msgstr "Информация: конец срока поддержки %s наступает из-за %s\n"

#: app/flatpak-quiet-transaction.c:251
#, c-format
msgid "Failed to rebase %s to %s: %s\n"
msgstr "Не удалось перебазировать %s в %s: %s\n"

#: common/flatpak-auth.c:58
#, c-format
msgid "No authenticator configured for remote `%s`"
msgstr "Аутентификатор для удаленного репозитория '%s' не настроен"

#: common/flatpak-context.c:637 common/flatpak-context.c:649
#, fuzzy, c-format
msgid "Invalid permission syntax: %s"
msgstr "Некорректное имя расширения %s"

#: common/flatpak-context.c:1207
#, c-format
msgid "Unknown share type %s, valid types are: %s"
msgstr "Неизвестный тип общего каталога %s, доступные типы: %s"

#: common/flatpak-context.c:1228
#, c-format
msgid "Unknown policy type %s, valid types are: %s"
msgstr "Неизвестный тип политики %s, доступные типы: %s"

#: common/flatpak-context.c:1266
#, c-format
msgid "Invalid dbus name %s"
msgstr "Некорректное имя dbus %s"

#: common/flatpak-context.c:1279
#, c-format
msgid "Unknown socket type %s, valid types are: %s"
msgstr "Неизвестный тип сокета %s, доступные типы: %s"

#: common/flatpak-context.c:1294
#, c-format
msgid "Unknown device type %s, valid types are: %s"
msgstr "Неизвестный тип устройства %s, доступные типы: %s"

#: common/flatpak-context.c:1308
#, c-format
msgid "Unknown feature type %s, valid types are: %s"
msgstr "Неизвестный тип функционала %s, доступные типы: %s"

#: common/flatpak-context.c:1840
#, c-format
msgid "Filesystem location \"%s\" contains \"..\""
msgstr "Путь \"%s\" файловой системы содержит \"..\""

#: common/flatpak-context.c:1882
#, c-format
msgid ""
"--filesystem=/ is not available, use --filesystem=host for a similar result"
msgstr ""
"--filesystem=/ не поддерживается, используйте --filesystem=host для "
"получения схожего результата"

#: common/flatpak-context.c:1916
#, fuzzy, c-format
msgid ""
"Unknown filesystem location %s, valid locations are: host, host-os, host-"
"etc, host-root, home, xdg-*[/…], ~/dir, /dir"
msgstr ""
"Неизвестный путь файловой системы %s, доступные типы: host, host-os, host-"
"etc, home, xdg-*[/…], ~/dir, /dir"

#: common/flatpak-context.c:2015
#, fuzzy, c-format
msgid "Invalid syntax for %s: %s"
msgstr "Некорректное имя %s: %s"

#: common/flatpak-context.c:2142
#, c-format
msgid "fallback-x11 can not be conditional"
msgstr ""

#: common/flatpak-context.c:2318
#, c-format
msgid "Invalid env format %s"
msgstr "Неверный формат переменной окружения %s"

#: common/flatpak-context.c:2399
#, c-format
msgid "Environment variable name must not contain '=': %s"
msgstr "Имя переменной окружения не должно содежать'=': %s"

#: common/flatpak-context.c:2527 common/flatpak-context.c:2535
#, c-format
msgid "--add-policy arguments must be in the form SUBSYSTEM.KEY=VALUE"
msgstr "Аргмуенты --add-policy должны быть в форме ПОДСИСТЕМА.КЛЮЧ=ЗНАЧЕНИЕ"

#: common/flatpak-context.c:2542
#, c-format
msgid "--add-policy values can't start with \"!\""
msgstr "Значения --add-policy не могут начинаться с '!'"

#: common/flatpak-context.c:2567 common/flatpak-context.c:2575
#, c-format
msgid "--remove-policy arguments must be in the form SUBSYSTEM.KEY=VALUE"
msgstr "Аргмуенты --remove-policy должны быть в форме ПОДСИСТЕМА.КЛЮЧ=ЗНАЧЕНИЕ"

#: common/flatpak-context.c:2582
#, c-format
msgid "--remove-policy values can't start with \"!\""
msgstr "Значения --remove-policy не могут начинаться с '!'"

#: common/flatpak-context.c:2657
msgid "Share with host"
msgstr "Добавить общий каталог с хостом"

#: common/flatpak-context.c:2657 common/flatpak-context.c:2658
msgid "SHARE"
msgstr "ОБЩ_КАТАЛОГ"

#: common/flatpak-context.c:2658
msgid "Unshare with host"
msgstr "Убрать общий каталог с хостом"

#: common/flatpak-context.c:2659
msgid "Require conditions to be met for a subsystem to get shared"
msgstr ""

#: common/flatpak-context.c:2659
msgid "SHARE:CONDITION"
msgstr ""

#: common/flatpak-context.c:2660
msgid "Expose socket to app"
msgstr "Пробросить сокет приложению"

#: common/flatpak-context.c:2660 common/flatpak-context.c:2661
msgid "SOCKET"
msgstr "СОКЕТ"

#: common/flatpak-context.c:2661
msgid "Don't expose socket to app"
msgstr "Убрать проброс сокета приложению"

#: common/flatpak-context.c:2662
msgid "Require conditions to be met for a socket to get exposed"
msgstr ""

#: common/flatpak-context.c:2662
msgid "SOCKET:CONDITION"
msgstr ""

#: common/flatpak-context.c:2663
msgid "Expose device to app"
msgstr "Пробросить устройство приложению"

#: common/flatpak-context.c:2663 common/flatpak-context.c:2664
msgid "DEVICE"
msgstr "УСТРОЙСТВО"

#: common/flatpak-context.c:2664
msgid "Don't expose device to app"
msgstr "Убрать проброс устройства приложению"

#: common/flatpak-context.c:2665
msgid "Require conditions to be met for a device to get exposed"
msgstr ""

#: common/flatpak-context.c:2665
msgid "DEVICE:CONDITION"
msgstr ""

#: common/flatpak-context.c:2666
msgid "Allow feature"
msgstr "Разрешить использовать этот функционал"

#: common/flatpak-context.c:2666 common/flatpak-context.c:2667
msgid "FEATURE"
msgstr "ФУНКЦИОНАЛ"

#: common/flatpak-context.c:2667
msgid "Don't allow feature"
msgstr "Запретить использование этого функционала"

#: common/flatpak-context.c:2668
msgid "Require conditions to be met for a feature to get allowed"
msgstr ""

#: common/flatpak-context.c:2668
msgid "FEATURE:CONDITION"
msgstr ""

#: common/flatpak-context.c:2669
msgid "Expose filesystem to app (:ro for read-only)"
msgstr "Пробросить файловую систему приложению (:ro только для чтения)"

#: common/flatpak-context.c:2669
msgid "FILESYSTEM[:ro]"
msgstr "ФАЙЛ_СИСТЕМА[:ro]"

#: common/flatpak-context.c:2670
msgid "Don't expose filesystem to app"
msgstr "Не пробрасывать файловую систему для приложения"

#: common/flatpak-context.c:2670
msgid "FILESYSTEM"
msgstr "ФАЙЛ_СИСТЕМА"

#: common/flatpak-context.c:2671
msgid "Set environment variable"
msgstr "Установить переменную окружения"

#: common/flatpak-context.c:2671
msgid "VAR=VALUE"
msgstr "ПЕРЕМЕННАЯ=ЗНАЧЕНИЕ"

#: common/flatpak-context.c:2672
msgid "Read environment variables in env -0 format from FD"
msgstr "Читать переменные окружения в формате env -0 из ДЕСКРИПТОРа"

#: common/flatpak-context.c:2673
msgid "Remove variable from environment"
msgstr "Удалить переменную из окружения"

#: common/flatpak-context.c:2673
msgid "VAR"
msgstr "ПЕРЕМЕННАЯ"

#: common/flatpak-context.c:2674
msgid "Allow app to own name on the session bus"
msgstr "Разрешить приложению владеть именем на сессионной шине"

#: common/flatpak-context.c:2674 common/flatpak-context.c:2675
#: common/flatpak-context.c:2676 common/flatpak-context.c:2677
#: common/flatpak-context.c:2678 common/flatpak-context.c:2679
#: common/flatpak-context.c:2680
msgid "DBUS_NAME"
msgstr "ИМЯ_DBUS"

#: common/flatpak-context.c:2675
msgid "Allow app to talk to name on the session bus"
msgstr "Разрешить приложению обмениваться с именем используя сессионную шину"

#: common/flatpak-context.c:2676
msgid "Don't allow app to talk to name on the session bus"
msgstr "Запрещать приложению обмениваться с именем используя сессионную шину"

#: common/flatpak-context.c:2677
msgid "Allow app to own name on the system bus"
msgstr "Разрешить приложению владеть именем используя системную шину"

#: common/flatpak-context.c:2678
msgid "Allow app to talk to name on the system bus"
msgstr "Разрешить приложению обмениваться с именем используя системную шину"

#: common/flatpak-context.c:2679
msgid "Don't allow app to talk to name on the system bus"
msgstr "Запретить приложению обмениваться с именем используя системную шину"

#: common/flatpak-context.c:2680
msgid "Allow app to own name on the a11y bus"
msgstr "Разрешить приложению владеть именем на шине специальных возможностей"

#: common/flatpak-context.c:2681
msgid "Add generic policy option"
msgstr "Добавить параметр обобщенной политики"

#: common/flatpak-context.c:2681 common/flatpak-context.c:2682
msgid "SUBSYSTEM.KEY=VALUE"
msgstr "ПОДСИСТЕМА.КЛЮЧ=ЗНАЧЕНИЕ"

#: common/flatpak-context.c:2682
msgid "Remove generic policy option"
msgstr "Удалить параметр обобщенной политики"

#: common/flatpak-context.c:2683
msgid "Add USB device to enumerables"
msgstr "Добавить USB-устройство в список доступных"

#: common/flatpak-context.c:2683 common/flatpak-context.c:2684
msgid "VENDOR_ID:PRODUCT_ID"
msgstr "VENDOR_ID:PRODUCT_ID"

#: common/flatpak-context.c:2684
msgid "Add USB device to hidden list"
msgstr "Добавить USB-устройство в список скрытых"

#: common/flatpak-context.c:2685
msgid "A list of USB devices that are enumerable"
msgstr "Список доступных USB-устройств"

#: common/flatpak-context.c:2685
msgid "LIST"
msgstr "СПИСОК"

#: common/flatpak-context.c:2686
msgid "File containing a list of USB devices to make enumerable"
msgstr "Файл, содержащий список доступных USB-устройств"

#: common/flatpak-context.c:2686 common/flatpak-context.c:2687
msgid "FILENAME"
msgstr "ИМЯ_ФАЙЛА"

#: common/flatpak-context.c:2687
msgid "Persist home directory subpath"
msgstr "Постоянный путь к домашнему каталогу"

#. This is not needed/used anymore, so hidden, but we accept it for backwards compat
#: common/flatpak-context.c:2689
msgid "Don't require a running session (no cgroups creation)"
msgstr "Не требует запуска сеанса (создание cgroups не требуется)"

#: common/flatpak-context.c:3718
#, c-format
msgid "Not replacing \"%s\" with tmpfs: %s"
msgstr "Не заменять \"%s\" на tmpfs: %s"

#: common/flatpak-context.c:3726
#, c-format
msgid "Not sharing \"%s\" with sandbox: %s"
msgstr "Не делиться \"%s\" с песочницей: %s"

#. Even if the error is one that we would normally silence, like
#. * the path not existing, it seems reasonable to make more of a fuss
#. * about the home directory not existing or otherwise being unusable,
#. * so this is intentionally not using cannot_export()
#: common/flatpak-context.c:3828
#, c-format
msgid "Not allowing home directory access: %s"
msgstr "Запретить доступ к домашнему каталогу: %s"

#: common/flatpak-context.c:4062
#, c-format
msgid "Unable to provide a temporary home directory in the sandbox: %s"
msgstr "Не удалось указать временный домашний каталог в песочнице: %s"

#: common/flatpak-dir.c:442
#, c-format
msgid "Configured collection ID ‘%s’ not in summary file"
msgstr "Заданный ID коллекции \"%s\" отсутствует в файле сводки"

#: common/flatpak-dir.c:587
#, c-format
msgid "Unable to load summary from remote %s: %s"
msgstr "Невозможно загрузить сводку с удаленного репозитория %s: %s"

#: common/flatpak-dir.c:764 common/flatpak-dir.c:800 common/flatpak-dir.c:906
#, c-format
msgid "No such ref '%s' in remote %s"
msgstr "Ссылки %s в удалённом репозитории %s не существует"

#: common/flatpak-dir.c:891 common/flatpak-dir.c:1051 common/flatpak-dir.c:1080
#: common/flatpak-dir.c:1092
#, c-format
msgid "No entry for %s in remote %s summary flatpak cache"
msgstr "Нет записи для «%s» в кэше сводки удалённого репозитория «%s»"

#: common/flatpak-dir.c:1069
#, c-format
msgid "No summary or Flatpak cache available for remote %s"
msgstr "Отсутствует сводка пути к кэшу Flatpak в удаленном репозитории %s"

#: common/flatpak-dir.c:1097
#, c-format
msgid "Missing xa.data in summary for remote %s"
msgstr "Отсутствует xa.data в сводке удалённого репозитория %s"

#: common/flatpak-dir.c:1103 common/flatpak-dir.c:1546
#, c-format
msgid "Unsupported summary version %d for remote %s"
msgstr "Неподдерживаемая версия %d сводки в удалённом репозитории %s"

#: common/flatpak-dir.c:1200
msgid "Remote OCI index has no registry uri"
msgstr "Удаленный индекс OCI не является регистрационным uri"

#: common/flatpak-dir.c:1261
#, c-format
msgid "Couldn't find ref %s in remote %s"
msgstr "Не удалось найти ссылку %s в удаленном репозитории %s"

#: common/flatpak-dir.c:1288 common/flatpak-dir.c:1381
#, fuzzy, c-format
msgid "Commit has no requested ref ‘%s’ in ref binding metadata (found: ‘%s’)"
msgstr "В коммите нет запрошенной ссылки '%s' в метаданных привязки ссылки"

#: common/flatpak-dir.c:1413
#, c-format
msgid "Configured collection ID ‘%s’ not in binding metadata"
msgstr "Заданный ID коллекции ‘%s’ отсутствует в связанных метаданных"

#: common/flatpak-dir.c:1449 common/flatpak-dir.c:5645
#, c-format
msgid "Couldn't find latest checksum for ref %s in remote %s"
msgstr ""
"Не удалось найти последнюю хеш-сумму для ссылки %s в удаленном репозитории %s"

#: common/flatpak-dir.c:1516 common/flatpak-dir.c:1552
#, c-format
msgid "No entry for %s in remote %s summary flatpak sparse cache"
msgstr ""
"Нет записи для %s в удаленном репозитории %s в сводной информации кэша "
"flatpak"

#: common/flatpak-dir.c:2540
#, c-format
msgid "Commit metadata for %s not matching expected metadata"
msgstr "Коммит метаданных для %s не соответствует ожидаемым метаданным"

#: common/flatpak-dir.c:2823
msgid "Unable to connect to system bus"
msgstr "Не удается подключиться к системой шине"

#: common/flatpak-dir.c:3419
msgid "User installation"
msgstr "Пользовательская установка"

#: common/flatpak-dir.c:3426
#, c-format
msgid "System (%s) installation"
msgstr "Системная (%s) установка"

#: common/flatpak-dir.c:3472
#, c-format
msgid "No overrides found for %s"
msgstr "Перезаписей для %s не найдено"

#: common/flatpak-dir.c:3625
#, c-format
msgid "%s (commit %s) not installed"
msgstr "%s (коммит %s) не установлен"

#: common/flatpak-dir.c:4650
#, c-format
msgid "Error parsing system flatpakrepo file for %s: %s"
msgstr "Ошибка разборка системного файла flatpakrepo %s: %s"

#: common/flatpak-dir.c:4735
#, c-format
msgid "While opening repository %s: "
msgstr "Во время открытия репозитория %s: "

#: common/flatpak-dir.c:5004
#, c-format
msgid "The config key %s is not set"
msgstr "Ключ конфигурации %s не задан"

#: common/flatpak-dir.c:5140
#, c-format
msgid "No current %s pattern matching %s"
msgstr "Нет текущих %s, подходящих под шаблон %s"

#: common/flatpak-dir.c:5422
msgid "No appstream commit to deploy"
msgstr "Отсутствует коммит для развёртывания"

#: common/flatpak-dir.c:5941 common/flatpak-dir.c:7266
#: common/flatpak-dir.c:10881 common/flatpak-dir.c:11618
msgid "Can't pull from untrusted non-gpg verified remote"
msgstr ""
"Не могу получить(запулить) данные с ненадежного, не проверенного gpg "
"репозитория"

#: common/flatpak-dir.c:6376 common/flatpak-dir.c:6591
msgid "Extra data not supported for non-gpg-verified local system installs"
msgstr ""
"Дополнительные данные не поддерживаются для локальных систем без проверки gpg"

#: common/flatpak-dir.c:6415 common/flatpak-dir.c:6782
#, c-format
msgid "Invalid checksum for extra data uri %s"
msgstr "Некорректная контрольная сумма дополнительных данных по адресу %s"

#: common/flatpak-dir.c:6424
#, c-format
msgid "Empty name for extra data uri %s"
msgstr "Пустое имя для дополнительных данных по адресу %s"

#: common/flatpak-dir.c:6432
#, c-format
msgid "Unsupported extra data uri %s"
msgstr "Не поддерживаемые дополнительные данные по адресу %s"

#: common/flatpak-dir.c:6461
#, c-format
msgid "Failed to load local extra-data %s: %s"
msgstr "Не удалось загрузить локальные дополнительные данные %s: %s"

#: common/flatpak-dir.c:6469
#, c-format
msgid "Wrong size for extra-data %s"
msgstr "Неверный размер для дополнительных данных %s"

#: common/flatpak-dir.c:6488
#, c-format
msgid "While downloading %s: "
msgstr "Во время загрузки %s: "

#: common/flatpak-dir.c:6498
#, c-format
msgid "Wrong size for extra data %s"
msgstr "Неправильный размер дополнительных данных по адресу %s"

#: common/flatpak-dir.c:6507
#, c-format
msgid "Invalid checksum for extra data %s"
msgstr "Некорректная контрольная сумма дополнительных данных по адресу %s"

#: common/flatpak-dir.c:7096 common/flatpak-dir.c:7349
#, c-format
msgid "While pulling %s from remote %s: "
msgstr "Во время получения %s из удалённого репозитория %s: "

#: common/flatpak-dir.c:7290 common/flatpak-repo-utils.c:3886
msgid "GPG signatures found, but none are in trusted keyring"
msgstr ""
"Найдены подписи GPG, но ни одна из них не находится в доверенном брелке"

#: common/flatpak-dir.c:7307
#, c-format
msgid "Commit for ‘%s’ has no ref binding"
msgstr "Коммит для '%s' не имеет привязки к ссылке"

#: common/flatpak-dir.c:7312
#, c-format
msgid "Commit for ‘%s’ is not in expected bound refs: %s"
msgstr "Коммит для '%s' не соответствует ожидаемым ссылкам: %s"

#: common/flatpak-dir.c:7488
msgid "Only applications can be made current"
msgstr "Текущими можно сделать только приложения"

#: common/flatpak-dir.c:8192
msgid "Not enough memory"
msgstr "Не достаточно памяти"

#: common/flatpak-dir.c:8211
msgid "Failed to read from exported file"
msgstr "Ошибка чтения из экспортированного файла"

#: common/flatpak-dir.c:8401
msgid "Error reading mimetype xml file"
msgstr "Ошибка чтения MIME типа xml файла"

#: common/flatpak-dir.c:8406
msgid "Invalid mimetype xml file"
msgstr "Некорректный MIME тип xml файла"

#: common/flatpak-dir.c:8492
#, c-format
msgid "D-Bus service file '%s' has wrong name"
msgstr "У сервисного файла D-Bus '%s' некорректное имя"

#: common/flatpak-dir.c:8647
#, c-format
msgid "Invalid Exec argument %s"
msgstr "Неверный аргумент для Exec %s"

#: common/flatpak-dir.c:9115
msgid "While getting detached metadata: "
msgstr "Во время получения отсоединённых метаданных: "

#: common/flatpak-dir.c:9120 common/flatpak-dir.c:9125
#: common/flatpak-dir.c:9129
msgid "Extra data missing in detached metadata"
msgstr "Дополнительные данные отсутствуют в отдельных метаданных"

#: common/flatpak-dir.c:9133
msgid "While creating extradir: "
msgstr "Во время создания каталога с дополнительными данными: "

#: common/flatpak-dir.c:9154 common/flatpak-dir.c:9187
msgid "Invalid checksum for extra data"
msgstr "Некорректная контрольная сумма для дополнительных данных"

#: common/flatpak-dir.c:9183
msgid "Wrong size for extra data"
msgstr "Некорректный размер дополнительных данных"

#: common/flatpak-dir.c:9196
#, c-format
msgid "While writing extra data file '%s': "
msgstr "Во время записи в файл дополнительных данных '%s': "

#: common/flatpak-dir.c:9204
#, c-format
msgid "Extra data %s missing in detached metadata"
msgstr "В отдельных метаданных отсутствуют отдельные данные %s"

#: common/flatpak-dir.c:9278
#, c-format
msgid "Unable to get runtime key from metadata"
msgstr "Не удалось получить ключ среды выполнения из метаданных"

#: common/flatpak-dir.c:9402
#, c-format
msgid "apply_extra script failed, exit status %d"
msgstr "скрипт apply_extra завершился с ошибкой %d"

#. Translators: The placeholder is for an app ref.
#: common/flatpak-dir.c:9591
#, c-format
msgid "Installing %s is not allowed by the policy set by your administrator"
msgstr "Установка %s запрещена политикой, установленной вашим администратором"

#: common/flatpak-dir.c:9690
#, c-format
msgid "While trying to resolve ref %s: "
msgstr "Во время поиска назначения ссылки %s: "

#: common/flatpak-dir.c:9702
#, c-format
msgid "%s is not available"
msgstr "%s не доступно"

#: common/flatpak-dir.c:9714 common/flatpak-dir.c:11495
#, c-format
msgid "%s commit %s already installed"
msgstr "%s коммит %s уже установлен"

#: common/flatpak-dir.c:9721
msgid "Can't create deploy directory"
msgstr "Невозможно создать каталог для развёртывания"

#: common/flatpak-dir.c:9729
#, c-format
msgid "Failed to read commit %s: "
msgstr "Ошибка чтения коммита %s: "

#: common/flatpak-dir.c:9750
#, c-format
msgid "While trying to checkout %s into %s: "
msgstr "Во время получения %s в %s: "

#: common/flatpak-dir.c:9769
msgid "While trying to checkout metadata subpath: "
msgstr "Во время получения метаданных подкаталога "

#: common/flatpak-dir.c:9801
#, c-format
msgid "While trying to checkout subpath ‘%s’: "
msgstr "Во врмея попытки проверить подпуть '%s': "

#: common/flatpak-dir.c:9811
msgid "While trying to remove existing extra dir: "
msgstr "Во время удаления существующего каталога с дополнительными данными: "

#: common/flatpak-dir.c:9822
msgid "While trying to apply extra data: "
msgstr "Во время применения дополнительных данных: "

#: common/flatpak-dir.c:9849
#, c-format
msgid "Invalid commit ref %s: "
msgstr "Неверная ссылка на коммит %s: "

#: common/flatpak-dir.c:9857 common/flatpak-dir.c:9869
#, c-format
msgid "Deployed ref %s does not match commit (%s)"
msgstr "Развернутая ссылка %s не соответствует коммиту (%s)"

#: common/flatpak-dir.c:9863
#, c-format
msgid "Deployed ref %s branch does not match commit (%s)"
msgstr "Развернутая ссылка %s ветви не соответствует коммиту (%s)"

#: common/flatpak-dir.c:10125 common/flatpak-installation.c:1911
#, c-format
msgid "%s branch %s already installed"
msgstr "%s ветвь %s уже установлена"

#: common/flatpak-dir.c:10985
#, c-format
msgid "Could not unmount revokefs-fuse filesystem at %s: "
msgstr "Не удалось отмонтировать файловую систему revokefs-fuse от %s: "

#: common/flatpak-dir.c:11289
#, c-format
msgid "This version of %s is already installed"
msgstr "Указанная версия %s уже установлена"

#: common/flatpak-dir.c:11302
#, c-format
msgid "Can't change remote during bundle install"
msgstr "Невозможно изменить удалённый репозиторий во время установки пакета"

#: common/flatpak-dir.c:11571
msgid "Can't update to a specific commit without root permissions"
msgstr "Невозможно обновить конкретный коммит без прав root"

#: common/flatpak-dir.c:11852
#, c-format
msgid "Can't remove %s, it is needed for: %s"
msgstr "Невозможно удалить %s, она нужна для: %s"

#: common/flatpak-dir.c:11912 common/flatpak-installation.c:2067
#, c-format
msgid "%s branch %s is not installed"
msgstr "%s ветвь %s не установлена"

#: common/flatpak-dir.c:12165
#, c-format
msgid "%s commit %s not installed"
msgstr "%s коммита %s не установлен"

#: common/flatpak-dir.c:12501
#, c-format
msgid "Pruning repo failed: %s"
msgstr "Не удалось удалить репозиторий: %s"

#: common/flatpak-dir.c:12669 common/flatpak-dir.c:12675
#, c-format
msgid "Failed to load filter '%s'"
msgstr "Не удалось загрузить фильтр '%s'"

#: common/flatpak-dir.c:12681
#, c-format
msgid "Failed to parse filter '%s'"
msgstr "Не удалось проанализировать фильтр '%s'"

#: common/flatpak-dir.c:12963
msgid "Failed to write summary cache: "
msgstr "Не удалось записать сводный кеш: "

#: common/flatpak-dir.c:12982
#, c-format
msgid "No oci summary cached for remote '%s'"
msgstr "Нет сводки кешированного oci удаленного репозитория '%s'"

#: common/flatpak-dir.c:13207
#, c-format
msgid "No cached summary for remote '%s'"
msgstr "Нет кэшированной сводки для удаленного репозитория '%s'"

#: common/flatpak-dir.c:13248
#, c-format
msgid "Invalid checksum for indexed summary %s read from %s"
msgstr ""
"Неверная контрольная сумма для индексированной сводки %s, считанной из %s"

#: common/flatpak-dir.c:13321
#, c-format
msgid ""
"Remote listing for %s not available; server has no summary file. Check the "
"URL passed to remote-add was valid."
msgstr ""
"Удаленный список для %s недоступен; На сервере нет сводного файла. "
"Проверьте, что URL, переданный удаленному добавлению, действителен."

#: common/flatpak-dir.c:13698
#, c-format
msgid "Invalid checksum for indexed summary %s for remote '%s'"
msgstr ""
"Некорректная контрольная сумма индексированной сводки %s для удалённого "
"репозитория '%s'"

#: common/flatpak-dir.c:14388
#, c-format
msgid "Multiple branches available for %s, you must specify one of: "
msgstr "Для %s доступно несколько ветвей, необходимо указать одну из: "

#: common/flatpak-dir.c:14454
#, c-format
msgid "Nothing matches %s"
msgstr "Совпадений не обнаружено %s"

#: common/flatpak-dir.c:14562
#, c-format
msgid "Can't find ref %s%s%s%s%s"
msgstr "Невозможно найти ссылку %s%s%s%s%s"

#: common/flatpak-dir.c:14605
#, c-format
msgid "Error searching remote %s: %s"
msgstr "Не удалось выполнить поиск по репозиторию %s: %s"

#: common/flatpak-dir.c:14702
#, c-format
msgid "Error searching local repository: %s"
msgstr "Не удалось выполнить поиск по локальному репозиторию: %s"

#: common/flatpak-dir.c:14839
#, c-format
msgid "%s/%s/%s not installed"
msgstr "%s/%s/%s не установлено"

#: common/flatpak-dir.c:15042
#, c-format
msgid "Could not find installation %s"
msgstr "Не возможно найти %s в установленных"

#: common/flatpak-dir.c:15612
#, c-format
msgid "Invalid file format, no %s group"
msgstr "Неверный формат файла, отсутствие %s группы"

#: common/flatpak-dir.c:15617 common/flatpak-repo-utils.c:2836
#, c-format
msgid "Invalid version %s, only 1 supported"
msgstr "Неверная версия %s, поддерживается только 1"

#: common/flatpak-dir.c:15622 common/flatpak-dir.c:15627
#, c-format
msgid "Invalid file format, no %s specified"
msgstr "Неверный формат файла, %s не указан"

#. Check some minimal size so we don't get crap
#: common/flatpak-dir.c:15647
msgid "Invalid file format, gpg key invalid"
msgstr "Неверный формат файла, неверный ключ gpg"

#: common/flatpak-dir.c:15675 common/flatpak-repo-utils.c:2917
msgid "Collection ID requires GPG key to be provided"
msgstr "ID коллекции требует предоставления ключа GPG"

#: common/flatpak-dir.c:15718
#, c-format
msgid "Runtime %s, branch %s is already installed"
msgstr "Среда выполнения %s, ветвь %s уже установлена"

#: common/flatpak-dir.c:15719
#, c-format
msgid "App %s, branch %s is already installed"
msgstr "Приложение %s, ветвь %s уже установлена"

#: common/flatpak-dir.c:15953
#, c-format
msgid "Can't remove remote '%s' with installed ref %s (at least)"
msgstr ""
"Не удалось удалить удаленный репозиторий '%s' с установленной ссылкой %s "
"(как минимум)"

#: common/flatpak-dir.c:16058
#, c-format
msgid "Invalid character '/' in remote name: %s"
msgstr "Недопустимый символ '/' в имени удалённого репозитория: %s"

#: common/flatpak-dir.c:16064
#, c-format
msgid "No configuration for remote %s specified"
msgstr "Не указана конфигурация для удаленного репозитория %s"

#: common/flatpak-dir.c:17597
#, c-format
msgid "Skipping deletion of mirror ref (%s, %s)…\n"
msgstr "Пропуск удаления зеркальной ссылки (%s,%s)…\n"

#: common/flatpak-exports.c:931
#, c-format
msgid "An absolute path is required"
msgstr "Требуется абсолютный путь"

#: common/flatpak-exports.c:948
#, c-format
msgid "Unable to open path \"%s\": %s"
msgstr "Не удалось открыть путь \"%s\": %s"

#: common/flatpak-exports.c:955
#, c-format
msgid "Unable to get file type of \"%s\": %s"
msgstr "Не удалось получить тип файла \"%s\": %s"

#: common/flatpak-exports.c:964
#, c-format
msgid "File \"%s\" has unsupported type 0o%o"
msgstr "Файл \"%s\" имеет неподдерживаемый тип 0o%o"

#: common/flatpak-exports.c:970
#, c-format
msgid "Unable to get filesystem information for \"%s\": %s"
msgstr "Не удалось получить информацию о файловой системе для \"%s\": %s"

#: common/flatpak-exports.c:980
#, c-format
msgid "Ignoring blocking autofs path \"%s\""
msgstr "Игнорирование блокировки пути autofs \"%s\""

#: common/flatpak-exports.c:996 common/flatpak-exports.c:1009
#: common/flatpak-exports.c:1022
#, c-format
msgid "Path \"%s\" is reserved by Flatpak"
msgstr "Путь \"%s\" зарезервирован Flatpak"

#: common/flatpak-exports.c:1076
#, c-format
msgid "Unable to resolve symbolic link \"%s\": %s"
msgstr "Не удалось разрешить символическую ссылку \"%s\": %s"

#: common/flatpak-glib-backports.c:69
msgid "Empty string is not a number"
msgstr "Пустая строка не является числом"

#: common/flatpak-glib-backports.c:95
#, c-format
msgid "“%s” is not an unsigned number"
msgstr "“%s” не является положительным числом"

#: common/flatpak-glib-backports.c:105
#, c-format
msgid "Number “%s” is out of bounds [%s, %s]"
msgstr "Число '%s' выходит за пределы допустимых значений [%s, %s]"

#: common/flatpak-image-source.c:83
msgid "Only sha256 image checksums are supported"
msgstr ""

#: common/flatpak-image-source.c:100 common/flatpak-image-source.c:108
msgid "Image is not a manifest"
msgstr "Изображение не является манифестом"

#: common/flatpak-image-source.c:123
msgid "No org.flatpak.ref found in image"
msgstr ""

#: common/flatpak-image-source.c:148
#, c-format
msgid "Ref '%s' not found in registry"
msgstr "Ссылка '%s' не найдена в реестре"

#: common/flatpak-image-source.c:157
msgid "Multiple images in registry, specify a ref with --ref"
msgstr "Множество изображений в реестре, укажите ссылку с помощью --ref"

#: common/flatpak-installation.c:834
#, c-format
msgid "Ref %s not installed"
msgstr "Ссылка %s не установлена"

#: common/flatpak-installation.c:875
#, c-format
msgid "App %s not installed"
msgstr "Приложение %s не установлено"

#: common/flatpak-installation.c:1395
#, c-format
msgid "Remote '%s' already exists"
msgstr "Удалённый репозиторий '%s' уже существует"

#: common/flatpak-installation.c:1946
#, c-format
msgid "As requested, %s was only pulled, but not installed"
msgstr ""
"Требуемое расширение %s было получено(запуленно), но не было установлено"

#: common/flatpak-instance.c:533 common/flatpak-instance.c:687
#: common/flatpak-instance.c:728
#, c-format
msgid "Unable to create directory %s"
msgstr "Невозможно создать каталог %s"

#: common/flatpak-instance.c:554
#, c-format
msgid "Unable to lock %s"
msgstr "Невозможно заблокировать %s"

#: common/flatpak-instance.c:627
#, c-format
msgid "Unable to create temporary directory in %s"
msgstr "Невозможно создать временный каталог в %s"

#: common/flatpak-instance.c:639
#, c-format
msgid "Unable to create file %s"
msgstr "Невозможно создать файл %s"

#: common/flatpak-instance.c:646
#, c-format
msgid "Unable to update symbolic link %s/%s"
msgstr "Невозможно обновить символьную ссылку %s/%s"

#: common/flatpak-oci-registry.c:1197
msgid "Only Bearer authentication supported"
msgstr "Поддерживается аутентификация только типа Bearer"

#: common/flatpak-oci-registry.c:1206
msgid "Only realm in authentication request"
msgstr "В запросе аутентификации только область"

#: common/flatpak-oci-registry.c:1213
msgid "Invalid realm in authentication request"
msgstr "Некорректная область в запросе аутентификации"

#: common/flatpak-oci-registry.c:1283
#, c-format
msgid "Authorization failed: %s"
msgstr "Авторизация не удалась: %s"

#: common/flatpak-oci-registry.c:1285
msgid "Authorization failed"
msgstr "Авторизация не удалась"

#: common/flatpak-oci-registry.c:1289
#, c-format
msgid "Unexpected response status %d when requesting token: %s"
msgstr "Неожиданный код состояния %d в ответе на запрос токена: %s"

#: common/flatpak-oci-registry.c:1300
msgid "Invalid authentication request response"
msgstr "Неверный ответ на запрос аутентификации"

#: common/flatpak-oci-registry.c:1731
#, c-format
msgid "Flatpak was compiled without zstd support"
msgstr ""

#: common/flatpak-oci-registry.c:1923 common/flatpak-oci-registry.c:1975
#: common/flatpak-oci-registry.c:2004 common/flatpak-oci-registry.c:2059
#: common/flatpak-oci-registry.c:2115 common/flatpak-oci-registry.c:2193
msgid "Invalid delta file format"
msgstr "Неверный формат файлы дельты"

#: common/flatpak-oci-registry.c:3198 common/flatpak-oci-registry.c:3382
msgid "Invalid OCI image config"
msgstr "Некорректная конфигурация образа OCI"

#: common/flatpak-oci-registry.c:3260 common/flatpak-oci-registry.c:3531
#, c-format
msgid "Wrong layer checksum, expected %s, was %s"
msgstr "Неправильный слой контрольных сумм, ожидалось %s, было %s"

#: common/flatpak-oci-registry.c:3359
#, c-format
msgid "No ref specified for OCI image %s"
msgstr "Ссылка для изображения OCI %s не указана"

#: common/flatpak-oci-registry.c:3369
#, c-format
msgid "Wrong ref (%s) specified for OCI image %s, expected %s"
msgstr "Неправильная ссылка (%s) указана для OCI изображения %s, ожидалось %s"

#: common/flatpak-progress.c:236
#, c-format
msgid "Downloading metadata: %u/(estimating) %s"
msgstr "Загрузка метаданных: %u/(оценка) %s"

#: common/flatpak-progress.c:260
#, c-format
msgid "Downloading: %s/%s"
msgstr "Загрузка: %s/%s"

#: common/flatpak-progress.c:280
#, c-format
msgid "Downloading extra data: %s/%s"
msgstr "Загрузка дополнительных данных: %s/%s"

#: common/flatpak-progress.c:285
#, c-format
msgid "Downloading files: %d/%d %s"
msgstr "Загрузка файлов: %d/%d %s"

#: common/flatpak-ref-utils.c:122
msgid "Name can't be empty"
msgstr "Имя не должно быть пустым"

#: common/flatpak-ref-utils.c:129
msgid "Name can't be longer than 255 characters"
msgstr "Имя не должно быть больше 255 символов"

#: common/flatpak-ref-utils.c:142
msgid "Name can't start with a period"
msgstr "Имя не должно начинаться с точки"

#: common/flatpak-ref-utils.c:148
#, c-format
msgid "Name can't start with %c"
msgstr "Имя не должно начинаться с %c"

#: common/flatpak-ref-utils.c:164
msgid "Name can't end with a period"
msgstr "Имя не должно заканчиваться точкой"

#: common/flatpak-ref-utils.c:171 common/flatpak-ref-utils.c:183
msgid "Only last name segment can contain -"
msgstr "Только последняя часть имени может содержать -"

#: common/flatpak-ref-utils.c:174
#, c-format
msgid "Name segment can't start with %c"
msgstr "Часть имени не должна начинаться с %c"

#: common/flatpak-ref-utils.c:186
#, c-format
msgid "Name can't contain %c"
msgstr "Имя не должно содержать %c"

#: common/flatpak-ref-utils.c:195
msgid "Names must contain at least 2 periods"
msgstr "Имена должны содержать как минимум две точки"

#: common/flatpak-ref-utils.c:312
msgid "Arch can't be empty"
msgstr "Архитектура не может быть пустой"

#: common/flatpak-ref-utils.c:323
#, c-format
msgid "Arch can't contain %c"
msgstr "Архитектура не может содержать %c"

#: common/flatpak-ref-utils.c:385
msgid "Branch can't be empty"
msgstr "Ветвь не должна быть пустой"

#: common/flatpak-ref-utils.c:395
#, c-format
msgid "Branch can't start with %c"
msgstr "Ветвь не должна начинаться с %c"

#: common/flatpak-ref-utils.c:405
#, c-format
msgid "Branch can't contain %c"
msgstr "Ветвь не должна содержать %c"

#: common/flatpak-ref-utils.c:615 common/flatpak-ref-utils.c:865
msgid "Ref too long"
msgstr "Ссылка слишком длинная"

#: common/flatpak-ref-utils.c:627
msgid "Invalid remote name"
msgstr "Неправильное имя удаленного репозитория"

#: common/flatpak-ref-utils.c:641
#, c-format
msgid "%s is not application or runtime"
msgstr "%s не является именем приложения или среды запуска"

#: common/flatpak-ref-utils.c:650 common/flatpak-ref-utils.c:667
#: common/flatpak-ref-utils.c:683
#, c-format
msgid "Wrong number of components in %s"
msgstr "Неверное количество компонентов в %s"

#: common/flatpak-ref-utils.c:656
#, c-format
msgid "Invalid name %.*s: %s"
msgstr "Некорректное имя %.*s: %s"

#: common/flatpak-ref-utils.c:673
#, c-format
msgid "Invalid arch: %.*s: %s"
msgstr "Некорректная архитектура: %.*s: %s"

#: common/flatpak-ref-utils.c:816
#, c-format
msgid "Invalid name %s: %s"
msgstr "Некорректное имя %s: %s"

#: common/flatpak-ref-utils.c:834
#, c-format
msgid "Invalid arch: %s: %s"
msgstr "Некорректная архитектура: %s: %s"

#: common/flatpak-ref-utils.c:853
#, c-format
msgid "Invalid branch: %s: %s"
msgstr "Некорректная ветвь: %s: %s"

#: common/flatpak-ref-utils.c:962 common/flatpak-ref-utils.c:970
#: common/flatpak-ref-utils.c:978
#, c-format
msgid "Wrong number of components in partial ref %s"
msgstr "Неверное количество компонентов в частичной ссылке %s"

#: common/flatpak-ref-utils.c:1298
msgid " development platform"
msgstr " среда разработки"

#: common/flatpak-ref-utils.c:1300
msgid " platform"
msgstr " платформа"

#: common/flatpak-ref-utils.c:1302
msgid " application base"
msgstr " базовое приложение"

#: common/flatpak-ref-utils.c:1305
msgid " debug symbols"
msgstr " отладочные символы"

#: common/flatpak-ref-utils.c:1307
msgid " sourcecode"
msgstr " исходный код"

#: common/flatpak-ref-utils.c:1309
msgid " translations"
msgstr " переводы"

#: common/flatpak-ref-utils.c:1311
msgid " docs"
msgstr " документация"

#: common/flatpak-ref-utils.c:1578
#, c-format
msgid "Invalid id %s: %s"
msgstr "Некорректный ID %s: %s"

#: common/flatpak-remote.c:1216
#, c-format
msgid "Bad remote name: %s"
msgstr "Неправильное имя удаленного репозитория: %s"

#: common/flatpak-remote.c:1220
#, fuzzy
msgid "No URL specified"
msgstr "Адрес не указан"

#: common/flatpak-remote.c:1266
msgid "GPG verification must be enabled when a collection ID is set"
msgstr "Проверка GPG должна быть включена, когда установлен ID коллекции"

#: common/flatpak-repo-utils.c:344
#, c-format
msgid "No extra data sources"
msgstr "Нет источников дополнительных данных"

#: common/flatpak-repo-utils.c:2817
#, c-format
msgid "Invalid %s: Missing group ‘%s’"
msgstr "Некорректный %s: Пропущена группа '%s'"

#: common/flatpak-repo-utils.c:2826
#, c-format
msgid "Invalid %s: Missing key ‘%s’"
msgstr "Некорректный %s: Пропущен ключ '%s'"

#: common/flatpak-repo-utils.c:2876
msgid "Invalid gpg key"
msgstr "Некорректный ключ gpg"

#: common/flatpak-repo-utils.c:3217
#, c-format
msgid "Error copying 64x64 icon for component %s: %s\n"
msgstr "Ошибка копирования иконки 64x64 для компонента %s: %s\n"

#: common/flatpak-repo-utils.c:3223
#, c-format
msgid "Error copying 128x128 icon for component %s: %s\n"
msgstr "Ошибка копирования иконки 128x128 для компонента %s: %s\n"

#: common/flatpak-repo-utils.c:3362
#, c-format
msgid "%s is end-of-life, ignoring for appstream"
msgstr "срок поддержки %s закончился, игнорируется для appstream"

#: common/flatpak-repo-utils.c:3397
#, c-format
msgid "No appstream data for %s: %s\n"
msgstr "Нет appstream данных для %s: %s\n"

#: common/flatpak-repo-utils.c:3744
msgid "Invalid bundle, no ref in metadata"
msgstr "Некорректный пакет, отсутствует ссылка на метаданные"

#: common/flatpak-repo-utils.c:3846
#, c-format
msgid "Collection ‘%s’ of bundle doesn’t match collection ‘%s’ of remote"
msgstr ""
"Коллекция '%s' пакета не соответствует коллекции '%s' удаленного репозитория"

#: common/flatpak-repo-utils.c:3923
msgid "Metadata in header and app are inconsistent"
msgstr "Метаданные в заголовке и приложении несовместимы"

#: common/flatpak-run.c:951
msgid "No systemd user session available, cgroups not available"
msgstr "Отсутствует пользовательская сессия systemd, cgroups недоступны"

#: common/flatpak-run.c:1496
msgid "Unable to allocate instance id"
msgstr "Невозможно выделить идентификатор экземпляра"

#: common/flatpak-run.c:1632 common/flatpak-run.c:1641
#, c-format
msgid "Failed to open flatpak-info file: %s"
msgstr "Не удалось открыть файл flatpak-info: %s"

#: common/flatpak-run.c:1668
#, c-format
msgid "Failed to open bwrapinfo.json file: %s"
msgstr "Не удалось открыть файл bwrapinfo.json: %s"

#: common/flatpak-run.c:1689
#, c-format
msgid "Failed to write to instance id fd: %s"
msgstr "Не удалось записать файловый дескриптор с ID экземпляра: %s"

#: common/flatpak-run.c:2096
msgid "Initialize seccomp failed"
msgstr "Не удалось инициализировать seccomp"

#: common/flatpak-run.c:2135
#, c-format
msgid "Failed to add architecture to seccomp filter: %s"
msgstr "Не удалось добавить архитектуру в фильтр seccomp: %s"

#: common/flatpak-run.c:2143
#, c-format
msgid "Failed to add multiarch architecture to seccomp filter: %s"
msgstr "Не удалось добавить многоархивную архитектуру к фильтру seccomp: %s"

#: common/flatpak-run.c:2175 common/flatpak-run.c:2192
#: common/flatpak-run.c:2214
#, c-format
msgid "Failed to block syscall %d: %s"
msgstr "Не удалось заблокировать системный вызов %d: %s"

#: common/flatpak-run.c:2247
#, c-format
msgid "Failed to export bpf: %s"
msgstr "Не удалось экспортировать bpf: %s"

#: common/flatpak-run.c:2587
#, c-format
msgid "Failed to open ‘%s’"
msgstr "Не удалось открыть '%s'"

#: common/flatpak-run.c:2597
#, c-format
msgid ""
"Directory forwarding needs version 4 of the document portal (have version %d)"
msgstr ""
"Для перенаправления каталога требуется портал документов версии 4 "
"(установлена версия %d)"

#: common/flatpak-run.c:2915
#, c-format
msgid "ldconfig failed, exit status %d"
msgstr "ошибка ldconfig, статус ошибки %d"

#: common/flatpak-run.c:2922
msgid "Can't open generated ld.so.cache"
msgstr "Невозможно открыть сгенерированный файл ld.so.cache"

#. Translators: The placeholder is for an app ref.
#: common/flatpak-run.c:3045
#, c-format
msgid "Running %s is not allowed by the policy set by your administrator"
msgstr "Запуск %s не разрешен политикой, установленной вашим администратором"

#: common/flatpak-run.c:3202
msgid ""
"\"flatpak run\" is not intended to be run as `sudo flatpak run`. Use `sudo "
"-i` or `su -l` instead and invoke \"flatpak run\" from inside the new shell."
msgstr ""
"\"flatpak run\" не предназначен для запуска как `sudo flatpak run`. Вместо "
"этого используйте `sudo -i` или `su -l` и вызывайте \"flatpak run\" из новой "
"оболочки."

#: common/flatpak-run.c:3413
#, c-format
msgid "Failed to migrate from %s: %s"
msgstr "Не удалось перенести с %s: %s"

#: common/flatpak-run.c:3434
#, c-format
msgid "Failed to migrate old app data directory %s to new name %s: %s"
msgstr ""
"Не удалось переместить старую папку с данными приложения %s в папку с новым "
"именем %s: %s"

#: common/flatpak-run.c:3443
#, c-format
msgid "Failed to create symlink while migrating %s: %s"
msgstr "Не удалось создать символическую ссылку при переносе %s: %s"

#: common/flatpak-run-dbus.c:46
msgid "Failed to open app info file"
msgstr "Ошибка при открытии файла с информацией приложения"

#: common/flatpak-run-dbus.c:149
msgid "Unable to create sync pipe"
msgstr "Невозможно создать канал синхронизации"

#: common/flatpak-run-dbus.c:185
msgid "Failed to sync with dbus proxy"
msgstr "Ошибка при синхронизации с прокси dbus"

#: common/flatpak-transaction.c:2275
#, c-format
msgid "Warning: Problem looking for related refs: %s"
msgstr "Предупреждение: Проблема при поиске связанных ссылок: %s"

#: common/flatpak-transaction.c:2493
#, c-format
msgid "The application %s requires the runtime %s which was not found"
msgstr "Приложение %s требует среду выполнения %s, которую не удалось найти"

#: common/flatpak-transaction.c:2509
#, c-format
msgid "The application %s requires the runtime %s which is not installed"
msgstr "Приложение %s требует среду выполнения %s, которая не установлена"

#: common/flatpak-transaction.c:2641
#, c-format
msgid "Can't uninstall %s which is needed by %s"
msgstr "Невозможно удалить %s который нуждается в %s"

#: common/flatpak-transaction.c:2740
#, c-format
msgid "Remote %s disabled, ignoring %s update"
msgstr "Удалённый репозиторий %s отключен, обновление %s пропущено"

#: common/flatpak-transaction.c:2773
#, c-format
msgid "%s is already installed"
msgstr "%s уже установлен"

#: common/flatpak-transaction.c:2776
#, c-format
msgid "%s is already installed from remote %s"
msgstr "%s уже установлен из репозитория %s"

#: common/flatpak-transaction.c:3120
#, c-format
msgid "Invalid .flatpakref: %s"
msgstr "Неверный .flatpakref: %s"

#: common/flatpak-transaction.c:3161
msgid "Warning: Could not mark already installed apps as preinstalled"
msgstr ""

#: common/flatpak-transaction.c:3382
#, c-format
msgid "Error updating remote metadata for '%s': %s"
msgstr "Ошибка при обновлении метаданных для '%s': %s"

#: common/flatpak-transaction.c:3885
#, c-format
msgid ""
"Warning: Treating remote fetch error as non-fatal since %s is already "
"installed: %s"
msgstr ""
"Предупреждение: обработка ошибки удаленной выборки как нефатальной, "
"поскольку %s уже установлен: %s"

#: common/flatpak-transaction.c:4209
#, c-format
msgid "No authenticator installed for remote '%s'"
msgstr "Нет аутентификатора для удаленного репозитория '%s'"

#: common/flatpak-transaction.c:4313 common/flatpak-transaction.c:4320
#, c-format
msgid "Failed to get tokens for ref: %s"
msgstr "Не удалось получить токены для ссылки: %s"

#: common/flatpak-transaction.c:4315 common/flatpak-transaction.c:4322
msgid "Failed to get tokens for ref"
msgstr "Не удалось получить токены для ссылки"

#: common/flatpak-transaction.c:4580
#, c-format
msgid "Ref %s from %s matches more than one transaction operation"
msgstr "Ссылка %s из %s соответствует более чем одной транзакционной операции"

#: common/flatpak-transaction.c:4581 common/flatpak-transaction.c:4591
msgid "any remote"
msgstr "любой удаленный репозиторий"

#: common/flatpak-transaction.c:4590
#, c-format
msgid "No transaction operation found for ref %s from %s"
msgstr "Не найдена операция транзакции для ссылки %s из %s"

#: common/flatpak-transaction.c:4713
#, c-format
msgid "Flatpakrepo URL %s not file, HTTP or HTTPS"
msgstr "URL Flatpakrepo %s не файл, HTTP или HTTPS"

#: common/flatpak-transaction.c:4719
#, c-format
msgid "Can't load dependent file %s: "
msgstr "Не удается загрузить зависимый файл %s: "

#: common/flatpak-transaction.c:4727
#, c-format
msgid "Invalid .flatpakrepo: %s"
msgstr "Неверный .flatpakrepo: %s"

#: common/flatpak-transaction.c:5454
msgid "Transaction already executed"
msgstr "Транзакция уже выполнена"

#: common/flatpak-transaction.c:5469
msgid ""
"Refusing to operate on a user installation as root! This can lead to "
"incorrect file ownership and permission errors."
msgstr ""
"Отказ от работы на пользовательской установке от имени пользователя root! "
"Это может привести к поломке прав файлов и ошибкам разрешений."

#: common/flatpak-transaction.c:5567 common/flatpak-transaction.c:5580
msgid "Aborted by user"
msgstr "Прервано пользователем"

#: common/flatpak-transaction.c:5605
#, c-format
msgid "Skipping %s due to previous error"
msgstr "Пропуск %s из-за предыдущей ошибки"

#: common/flatpak-transaction.c:5659
#, c-format
msgid "Aborted due to failure (%s)"
msgstr "Прервано из-за ошибки (%s)"

#: common/flatpak-uri.c:118
#, no-c-format
msgid "Invalid %-encoding in URI"
msgstr "Неверная %-кодировка в URI"

#: common/flatpak-uri.c:135
msgid "Illegal character in URI"
msgstr "Недопустимый символ в URI"

#: common/flatpak-uri.c:169
msgid "Non-UTF-8 characters in URI"
msgstr "Не UTF-8 символы в URI"

#: common/flatpak-uri.c:275
#, c-format
msgid "Invalid IPv6 address ‘%.*s’ in URI"
msgstr "Недопустимый IPv6 адрес ‘%.*s’ в URI"

#: common/flatpak-uri.c:330
#, c-format
msgid "Illegal encoded IP address ‘%.*s’ in URI"
msgstr "Недопустимый закодированный IP адрес ‘%.*s’ в URI"

#: common/flatpak-uri.c:342
#, c-format
msgid "Illegal internationalized hostname ‘%.*s’ in URI"
msgstr "Недопустимое интернациональное имя хоста ‘%.*s’ в URI"

#: common/flatpak-uri.c:374 common/flatpak-uri.c:386
#, c-format
msgid "Could not parse port ‘%.*s’ in URI"
msgstr "Невозможно разобрать порт ‘%.*s’ в URI"

#: common/flatpak-uri.c:393
#, c-format
msgid "Port ‘%.*s’ in URI is out of range"
msgstr "Порт '%.*s' в URI находится вне диапазона"

#: common/flatpak-uri.c:910
msgid "URI is not absolute, and no base URI was provided"
msgstr "URI не абсолютный, и базовый URI не указан"

#: common/flatpak-usb.c:83
#, c-format
msgid "USB device query 'all' must not have data"
msgstr "Запрос USB-устройства «all» не должен содержать данные"

#: common/flatpak-usb.c:102
#, c-format
msgid "USB query rule 'cls' must be in the form CLASS:SUBCLASS or CLASS:*"
msgstr ""
"Правило запроса USB «cls» должно быть в формате CLASS:SUBCLASS или CLASS:*"

#: common/flatpak-usb.c:111
#, c-format
msgid "Invalid USB class"
msgstr "Недопустимый класс USB"

#: common/flatpak-usb.c:125
#, c-format
msgid "Invalid USB subclass"
msgstr "Недопустимый подкласс USB"

#: common/flatpak-usb.c:141 common/flatpak-usb.c:148
#, c-format
msgid "USB query rule 'dev' must have a valid 4-digit hexadecimal product id"
msgstr ""
"Правило запроса USB «dev» должно содержать действительный 4-значный "
"шестнадцатеричный идентификатор продукта"

#: common/flatpak-usb.c:164 common/flatpak-usb.c:171
#, c-format
msgid "USB query rule 'vnd' must have a valid 4-digit hexadecimal vendor id"
msgstr ""
"Правило запроса USB «vnd» должно содержать действительный 4-значный "
"шестнадцатеричный идентификатор производителя"

#: common/flatpak-usb.c:205
#, c-format
msgid "USB device queries must be in the form TYPE:DATA"
msgstr "Запросы USB-устройств должны быть в формате TYPE:DATA"

#: common/flatpak-usb.c:225
#, c-format
msgid "Unknown USB query rule %s"
msgstr "Неизвестное правило запроса USB: %s"

#: common/flatpak-usb.c:248
#, c-format
msgid "Empty USB query"
msgstr "Пустой запрос USB"

#: common/flatpak-usb.c:274
#, c-format
msgid "Multiple USB query rules of the same type is not supported"
msgstr "Несколько правил запроса USB одного типа не поддерживаются"

#: common/flatpak-usb.c:283
#, c-format
msgid "'all' must not contain extra query rules"
msgstr "Правило «all» не должно содержать дополнительных правил запроса"

#: common/flatpak-usb.c:291
#, c-format
msgid "USB queries with 'dev' must also specify vendors"
msgstr "В запросах USB с «dev» также должны быть указаны производители"

#: common/flatpak-utils.c:712
msgid "Glob can't match apps"
msgstr "Glob не может соответствовать приложениям"

#: common/flatpak-utils.c:737
msgid "Empty glob"
msgstr "Пустой glob"

#: common/flatpak-utils.c:756
msgid "Too many segments in glob"
msgstr "Слишком много частей в glob'е"

#: common/flatpak-utils.c:777
#, c-format
msgid "Invalid glob character '%c'"
msgstr "Недопустимый знак '%c' в glob'е"

#: common/flatpak-utils.c:831
#, c-format
msgid "Missing glob on line %d"
msgstr "Пропущен glob на строке %d"

#: common/flatpak-utils.c:835
#, c-format
msgid "Trailing text on line %d"
msgstr "Завершающий текст в строке %d"

#: common/flatpak-utils.c:839
#, c-format
msgid "on line %d"
msgstr "на строке %d"

#: common/flatpak-utils.c:861
#, c-format
msgid "Unexpected word '%s' on line %d"
msgstr "Неожиданное слово '%s' на строке %d"

#: common/flatpak-utils.c:2118
#, c-format
msgid "Invalid require-flatpak argument %s"
msgstr "Неверный аргумент require-flatpak %s"

#: common/flatpak-utils.c:2128 common/flatpak-utils.c:2147
#, c-format
msgid "%s needs a later flatpak version (%s)"
msgstr "%s требует более новую версию flatpak (%s)"

#: oci-authenticator/flatpak-oci-authenticator.c:291
msgid "Not a oci remote, missing summary.xa.oci-repository"
msgstr ""
"Не является удалённым репозиторием OCI, отсутствует summary.xa.oci-repository"

#: oci-authenticator/flatpak-oci-authenticator.c:477
msgid "Not a OCI remote"
msgstr "Не является удалённым репозиторием OCI"

#: oci-authenticator/flatpak-oci-authenticator.c:488
msgid "Invalid token"
msgstr "Некорректный токен"

#: portal/flatpak-portal.c:2292
#, c-format
msgid "No portal support found"
msgstr "Поддержки порталов не обнаружено"

#: portal/flatpak-portal.c:2298
msgid "Deny"
msgstr "Отклонить"

#: portal/flatpak-portal.c:2300
msgid "Update"
msgstr "Обновить"

#: portal/flatpak-portal.c:2305
#, c-format
msgid "Update %s?"
msgstr "Обновить %s?"

#: portal/flatpak-portal.c:2317
msgid "The application wants to update itself."
msgstr "Приложение хочет обновить себя."

#: portal/flatpak-portal.c:2318
msgid "Update access can be changed any time from the privacy settings."
msgstr ""
"Доступ к обновлению можно изменить в любое время из настроек "
"конфиденциальности."

#: portal/flatpak-portal.c:2343
#, c-format
msgid "Application update not allowed"
msgstr "Обновления приложений не разрешены"

#: portal/flatpak-portal.c:2501
#, c-format
msgid "Self update not supported, new version requires new permissions"
msgstr ""
"Самостоятельное обновление не поддерживается, новая версия требует новых "
"разрешений"

#: portal/flatpak-portal.c:2684 portal/flatpak-portal.c:2702
#, c-format
msgid "Update ended unexpectedly"
msgstr "Обновление закончилось неожиданно"

#. SECURITY:
#. - Normal users need admin authentication to install software
#. system-wide.
#. - Note that we install polkit rules that allow local users
#. in the wheel group to install without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:23
msgid "Install signed application"
msgstr "Установить подписанное приложение"

#: system-helper/org.freedesktop.Flatpak.policy.in:24
#: system-helper/org.freedesktop.Flatpak.policy.in:42
msgid "Authentication is required to install software"
msgstr "Требуется авторизация для установки программ"

#. SECURITY:
#. - Normal users need admin authentication to install software
#. system-wide.
#. - Note that we install polkit rules that allow local users
#. in the wheel group to install without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:41
msgid "Install signed runtime"
msgstr "Установить подписанную среду выполнения"

#. SECURITY:
#. - Normal users do not require admin authentication to update an
#. app as the commit will be signed, and the action is required
#. to update the system when unattended.
#. - Changing this to anything other than 'yes' will break unattended
#. updates.
#: system-helper/org.freedesktop.Flatpak.policy.in:60
msgid "Update signed application"
msgstr "Обновить подписанное приложение"

#: system-helper/org.freedesktop.Flatpak.policy.in:61
#: system-helper/org.freedesktop.Flatpak.policy.in:80
msgid "Authentication is required to update software"
msgstr "Требуется авторизация для обновления программ"

#. SECURITY:
#. - Normal users do not require admin authentication to update a
#. runtime as the commit will be signed, and the action is required
#. to update the system when unattended.
#. - Changing this to anything other than 'yes' will break unattended
#. updates.
#: system-helper/org.freedesktop.Flatpak.policy.in:79
msgid "Update signed runtime"
msgstr "Обновить подписанную среду выполнения"

#. SECURITY:
#. - Normal users do not need authentication to update metadata
#. from signed repositories.
#: system-helper/org.freedesktop.Flatpak.policy.in:94
msgid "Update remote metadata"
msgstr "Обновить удаленные метаданные"

#: system-helper/org.freedesktop.Flatpak.policy.in:95
msgid "Authentication is required to update remote info"
msgstr "Требуется авторизация для обновления удаленной информации"

#. SECURITY:
#. - Normal users do not need authentication to modify the
#. OSTree repository
#. - Note that we install polkit rules that allow local users
#. in the wheel group to modify repos without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:111
msgid "Update system repository"
msgstr "Обновить системный репозиторий"

#: system-helper/org.freedesktop.Flatpak.policy.in:112
msgid "Authentication is required to modify a system repository"
msgstr "Требуется авторизация для изменения системного репозитория"

#. SECURITY:
#. - Normal users need admin authentication to install software
#. system-wide.
#: system-helper/org.freedesktop.Flatpak.policy.in:126
msgid "Install bundle"
msgstr "Установить пакет"

#: system-helper/org.freedesktop.Flatpak.policy.in:127
msgid "Authentication is required to install software from $(path)"
msgstr "Требуется авторизация для установки программ из $(path)"

#. SECURITY:
#. - Normal users need admin authentication to uninstall software
#. system-wide.
#. - Note that we install polkit rules that allow local users
#. in the wheel group to uninstall without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:144
msgid "Uninstall runtime"
msgstr "Удалить среду выполнения"

#: system-helper/org.freedesktop.Flatpak.policy.in:145
msgid "Authentication is required to uninstall software"
msgstr "Требуется авторизация для удаления программ"

#. SECURITY:
#. - Normal users need admin authentication to uninstall software
#. system-wide.
#. - Note that we install polkit rules that allow local users
#. in the wheel group to uninstall without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:161
msgid "Uninstall app"
msgstr "Удалить программу"

#: system-helper/org.freedesktop.Flatpak.policy.in:162
msgid "Authentication is required to uninstall $(ref)"
msgstr "Требуется авторизация для удаления ${ref}"

#. SECURITY:
#. - Normal users need admin authentication to configure system-wide
#. software repositories.
#: system-helper/org.freedesktop.Flatpak.policy.in:177
msgid "Configure Remote"
msgstr "Настроить удалённый репозиторий"

#: system-helper/org.freedesktop.Flatpak.policy.in:178
msgid "Authentication is required to configure software repositories"
msgstr "Требуется авторизация для настройки репозиториев программ"

#. SECURITY:
#. - Normal users need admin authentication to configure the system-wide
#. Flatpak installation.
#: system-helper/org.freedesktop.Flatpak.policy.in:192
msgid "Configure"
msgstr "Настроить"

#: system-helper/org.freedesktop.Flatpak.policy.in:193
msgid "Authentication is required to configure software installation"
msgstr "Требуется авторизация для настройки установки программ"

#. SECURITY:
#. - Normal users do not require admin authentication to update
#. appstream data as it will be signed, and the action is required
#. to update the system when unattended.
#. - Changing this to anything other than 'yes' will break unattended
#. updates.
#: system-helper/org.freedesktop.Flatpak.policy.in:210
msgid "Update appstream"
msgstr "Обновить appstream"

#: system-helper/org.freedesktop.Flatpak.policy.in:211
msgid "Authentication is required to update information about software"
msgstr "Требуется авторизация для обновления информации о программах"

#. SECURITY:
#. - Normal users do not require admin authentication to update
#. metadata as it will be signed, and the action is required
#. to update the system when unattended.
#. - Changing this to anything other than 'yes' will break unattended
#. updates.
#: system-helper/org.freedesktop.Flatpak.policy.in:228
msgid "Update metadata"
msgstr "Обновить метаданные репозитория"

#: system-helper/org.freedesktop.Flatpak.policy.in:229
msgid "Authentication is required to update metadata"
msgstr "Требуется авторизация для обновления метаданных"

#. SECURITY:
#. - Authorisation to actually install software is controlled by
#. org.freedesktop.Flatpak.app-install.
#. - This action is checked after app-install, as it can only be done
#. once the app’s data (including its content rating) has been
#. downloaded.
#. - This action is checked to see if the installation should be allowed
#. based on whether the app being installed has content which doesn’t
#. comply with the user’s parental controls policy (the content is
#. ‘too extreme’).
#. - It is checked only if an app has too extreme content for the user
#. who is trying to install it (in which case, the app is ‘unsafe’).
#. - Typically, normal users will need admin permission to install apps
#. with extreme content; admins will be able to install it without
#. additional checks.
#. - In order to configure the policy so that admins can install safe and
#. unsafe software anywhere without authorisation, and non-admins can
#. install safe software in their user or system dirs without
#. authorisation, but need authorisation to install unsafe software
#. anywhere:
#. * Unconditionally return `yes` from `app-install`.
#. * Return `auth_admin` from `override-parental-controls` for users
#. not in `@privileged_group@`, and `yes` for users in it.
#. * Set the malcontent `is-{user,system}-installation-allowed`
#. properties of all non-admins’ parental controls policies to true.
#. - In order to configure the policy so that admins can install safe and
#. unsafe software anywhere without authorisation, and non-admins can
#. install safe software in their user dir without authorisation, but
#. need authorisation to install safe software in the system dir or to
#. install unsafe software anywhere:
#. * Unconditionally return `yes` from `app-install`.
#. * Return `auth_admin` from `override-parental-controls` for users
#. not in `@privileged_group@`, and `yes` for users in it.
#. * Set the malcontent `is-user-installation-allowed` property of all
#. non-admins’ parental controls policies to true.
#. * Set the malcontent `is-system-installation-allowed` property of
#. all non-admins’ parental controls policies to false.
#. - In order to configure the policy so that all users (including
#. admins) can install safe software anywhere without authorisation,
#. but need authorisation to install unsafe software anywhere (i.e.
#. applying parental controls to admins too):
#. * Unconditionally return `yes` from `app-install`.
#. * Unconditionally return `auth_admin` from `override-parental-controls`.
#. * Set the malcontent `is-user-installation-allowed` property of all
#. users’ parental controls policies to true.
#. * Set the malcontent `is-system-installation-allowed` property of
#. all users’ parental controls policies to true.
#: system-helper/org.freedesktop.Flatpak.policy.in:287
msgid "Override parental controls for installs"
msgstr "Переопределить родительский контроль для установок"

#: system-helper/org.freedesktop.Flatpak.policy.in:288
msgid ""
"Authentication is required to install software which is restricted by your "
"parental controls policy"
msgstr ""
"Для установки программного обеспечения требуется аутентификация, которая "
"ограничена вашей политикой родительского контроля"

#. SECURITY:
#. - This is like org.freedesktop.Flatpak.override-parental-controls, but
#. it’s queried for app updates, whereas the former is queried for app
#. installs.
#. - As with the above action, this one is only queried if
#. org.freedesktop.Flatpak.app-update has allowed the app update, and
#. only if the app being updated has too extreme content for the user
#. who is trying to update it.
#. - The default policy for this is to *allow* updates to ‘too extreme’
#. apps by default, on the basis that having an out-of-date (i.e.
#. insecure or unsupported) app is a worse outcome than automatically
#. installing an update which has radically different content from the
#. version of the app which the parent originally vetted and installed.
#: system-helper/org.freedesktop.Flatpak.policy.in:313
msgid "Override parental controls for updates"
msgstr "Переопределить родительский контроль для обновлений"

#: system-helper/org.freedesktop.Flatpak.policy.in:314
msgid ""
"Authentication is required to update software which is restricted by your "
"parental controls policy"
msgstr ""
"Требуется аутентификация для обновления программного обеспечения, "
"ограниченного вашей политикой родительского контроля"

#~ msgid "Installed:"
#~ msgstr "Установлено:"

#~ msgid "Download:"
#~ msgstr "Загрузить:"

#, c-format
#~ msgid "No gpg key found with ID %s (homedir: %s)"
#~ msgstr "Ключ gpg с идентификатором %s не найден (homedir: %s)"

#, c-format
#~ msgid "Unable to lookup key ID %s: %d"
#~ msgstr "Невозможно найти ID ключа %s: %d"

#, c-format
#~ msgid "Error signing commit: %d"
#~ msgstr "Ошибка подписи коммита: %d"

#, c-format
#~ msgid ""
#~ "Found similar ref(s) for ‘%s’ in remote ‘%s’ (%s).\n"
#~ "Use this remote?"
#~ msgstr ""
#~ "Найдена одна или более ссылок, похожих на '%s', в репозитории '%s' (%s).\n"
#~ "Использовать этот репозиторий?"

#, c-format
#~ msgid "No entry for %s in remote '%s' summary cache "
#~ msgstr "Нет записи для %s в кэше сводки удаленного репозитория '%s' "

#, c-format
#~ msgid "Failed to uninstall %s for rebase to %s: "
#~ msgstr "Не удалось удалить %s для перебазирования в %s: "

#, c-format
#~ msgid "Failed to uninstall %s for rebase to %s: %s\n"
#~ msgstr "Не удалось удалить %s для перебазирования в %s: %s\n"

#, c-format
#~ msgid "Unable to open directory %s"
#~ msgstr "Невозможно открыть каталог %s"

#~ msgid "install"
#~ msgstr "установить"

#~ msgid "update"
#~ msgstr "обновить"

#~ msgid "install bundle"
#~ msgstr "установить пакет"

#~ msgid "uninstall"
#~ msgstr "удалить"

#~ msgid "(internal error, please report)"
#~ msgstr "(внутренняя ошибка; пожалуйста, сообщите об этом)"

#~ msgid "Warning:"
#~ msgstr "Предупреждение:"

#, c-format
#~ msgid "%s%s%s branch %s%s%s"
#~ msgstr "%s%s%s ветвь %s%s%s"

#~ msgid "(pinned) "
#~ msgstr "(прикреплено) "

#~ msgid "runtime"
#~ msgstr "среда исполнения"

#~ msgid "app"
#~ msgstr "приложение"

#~ msgid "[REF…] - Uninstall an application"
#~ msgstr "[ССЫЛКА…] - Удалить приложение"

#, c-format
#~ msgid "Replace it with %s?"
#~ msgstr "Заменить его на %s?"

===== ./po/sr.po =====
# Serbian translation for flatpak.
# Copyright (C) 2026 flatpak's COPYRIGHT HOLDER
# This file is distributed under the same license as the flatpak package.
# Марко Костић <marko.m.kostic@gmail.com>,  2026.
#
msgid ""
msgstr ""
"Project-Id-Version: flatpak main\n"
"Report-Msgid-Bugs-To: https://github.com/flatpak/flatpak/issues\n"
"POT-Creation-Date: 2026-05-27 16:39+0200\n"
"PO-Revision-Date: 2026-03-20 00:01+0100\n"
"Last-Translator: Марко М. Костић <marko.m.kostic@gmail.com>\n"
"Language-Team: Serbian <Serbian>\n"
"Language: sr\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=4; plural=n==1? 3 : n%10==1 && n%100!=11 ? 0 : "
"n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
"X-Generator: Poedit 3.9\n"

#: app/flatpak-builtins-build-bundle.c:59
msgid "Export runtime instead of app"
msgstr "Извези извршно окружење уместо програма"

#: app/flatpak-builtins-build-bundle.c:60
msgid "Arch to bundle for"
msgstr "Архитектура свежња"

#: app/flatpak-builtins-build-bundle.c:60
#: app/flatpak-builtins-build-export.c:62 app/flatpak-builtins-build-init.c:53
#: app/flatpak-builtins-build-sign.c:42 app/flatpak-builtins-create-usb.c:46
#: app/flatpak-builtins-info.c:55 app/flatpak-builtins-install.c:67
#: app/flatpak-builtins-list.c:50 app/flatpak-builtins-make-current.c:38
#: app/flatpak-builtins-remote-info.c:54 app/flatpak-builtins-remote-ls.c:56
#: app/flatpak-builtins-run.c:158 app/flatpak-builtins-search.c:37
#: app/flatpak-builtins-uninstall.c:54 app/flatpak-builtins-update.c:56
msgid "ARCH"
msgstr "АРХИТЕКТУРА"

#: app/flatpak-builtins-build-bundle.c:61
msgid "URL for repo"
msgstr "Адреса за ризницу"

#: app/flatpak-builtins-build-bundle.c:61
#: app/flatpak-builtins-build-bundle.c:62
#: app/flatpak-builtins-build-update-repo.c:68
#: app/flatpak-builtins-build-update-repo.c:72
#: app/flatpak-builtins-build-update-repo.c:73
#: app/flatpak-builtins-history.c:69 app/flatpak-builtins-remote-add.c:80
#: app/flatpak-builtins-remote-add.c:81 app/flatpak-builtins-remote-add.c:85
#: app/flatpak-builtins-remote-list.c:53
#: app/flatpak-builtins-remote-modify.c:70
#: app/flatpak-builtins-remote-modify.c:85
#: app/flatpak-builtins-remote-modify.c:86
#: app/flatpak-builtins-remote-modify.c:90
msgid "URL"
msgstr "АДРЕСА"

#: app/flatpak-builtins-build-bundle.c:62
msgid "URL for runtime flatpakrepo file"
msgstr "Адреса за „flatpakrepo“ датотеку извршног окружења"

#: app/flatpak-builtins-build-bundle.c:63
msgid "Add GPG key from FILE (- for stdin)"
msgstr "Додај ГПГ кључ из ДАТОТЕКЕ (- за стандардни улаз)"

#: app/flatpak-builtins-build-bundle.c:63 app/flatpak-builtins-build.c:54
#: app/flatpak-builtins-build-export.c:67
#: app/flatpak-builtins-build-update-repo.c:83
#: app/flatpak-builtins-install.c:81 app/flatpak-builtins-remote-add.c:84
#: app/flatpak-builtins-remote-add.c:86 app/flatpak-builtins-remote-modify.c:89
#: app/flatpak-builtins-remote-modify.c:92
msgid "FILE"
msgstr "ДАТОТЕКА"

#: app/flatpak-builtins-build-bundle.c:64
msgid "GPG Key ID to sign the OCI image with"
msgstr "ИД ГПГ кључа за потписивање ОЦИ одраза"

#: app/flatpak-builtins-build-bundle.c:64
#: app/flatpak-builtins-build-commit-from.c:68
#: app/flatpak-builtins-build-export.c:68
#: app/flatpak-builtins-build-import-bundle.c:49
#: app/flatpak-builtins-build-sign.c:44
#: app/flatpak-builtins-build-update-repo.c:84
msgid "KEY-ID"
msgstr "ИБ-КЉУЧА"

#: app/flatpak-builtins-build-bundle.c:65
#: app/flatpak-builtins-build-commit-from.c:69
#: app/flatpak-builtins-build-export.c:71
#: app/flatpak-builtins-build-import-bundle.c:50
#: app/flatpak-builtins-build-sign.c:45
#: app/flatpak-builtins-build-update-repo.c:85
msgid "GPG Homedir to use when looking for keyrings"
msgstr "ГПГ лични директоријум за коришћење при тражењу привезака"

#: app/flatpak-builtins-build-bundle.c:65
#: app/flatpak-builtins-build-commit-from.c:69
#: app/flatpak-builtins-build-export.c:71
#: app/flatpak-builtins-build-import-bundle.c:50
#: app/flatpak-builtins-build-sign.c:45
#: app/flatpak-builtins-build-update-repo.c:85
msgid "HOMEDIR"
msgstr "ЛИЧНИДИР"

#: app/flatpak-builtins-build-bundle.c:66
msgid "OSTree commit to create a delta bundle from"
msgstr "„OSTree“ предаја за стварање делта свежња"

#: app/flatpak-builtins-build-bundle.c:66 app/flatpak-builtins-remote-info.c:55
#: app/flatpak-builtins-update.c:57
msgid "COMMIT"
msgstr "ПРЕДАЈА"

#: app/flatpak-builtins-build-bundle.c:67
msgid "Export oci image instead of flatpak bundle"
msgstr "Извези ОЦИ одраз уместо флетпек свежња"

#: app/flatpak-builtins-build-bundle.c:70
msgid "How to compress OCI image layers (default: gzip)"
msgstr "Како сажимати слојеве ОЦИ одраза (подразумевано: gzip)"

#: app/flatpak-builtins-build-bundle.c:634
msgid ""
"LOCATION FILENAME NAME [BRANCH] - Create a single file bundle from a local "
"repository"
msgstr ""
"МЕСТО НАЗИВ_ДАТОТЕКЕ НАЗИВ [ГРАНА] - направи свежањ од једне датотеке из "
"локалне ризнице"

#: app/flatpak-builtins-build-bundle.c:641
msgid "LOCATION, FILENAME and NAME must be specified"
msgstr "МЕСТО, НАЗИВ_ДАТОТЕКЕ и НАЗИВ морају бити наведени"

#: app/flatpak-builtins-build-bundle.c:644
#: app/flatpak-builtins-build-export.c:844
#: app/flatpak-builtins-build-import-bundle.c:136
#: app/flatpak-builtins-build-init.c:217 app/flatpak-builtins-build-sign.c:76
#: app/flatpak-builtins-document-export.c:112
#: app/flatpak-builtins-document-info.c:75
#: app/flatpak-builtins-document-list.c:191
#: app/flatpak-builtins-document-unexport.c:70
#: app/flatpak-builtins-history.c:482 app/flatpak-builtins-info.c:130
#: app/flatpak-builtins-install.c:181 app/flatpak-builtins-install.c:234
#: app/flatpak-builtins-install.c:298 app/flatpak-builtins-list.c:419
#: app/flatpak-builtins-make-current.c:72 app/flatpak-builtins-override.c:73
#: app/flatpak-builtins-permission-list.c:162
#: app/flatpak-builtins-permission-remove.c:132
#: app/flatpak-builtins-remote-add.c:323
#: app/flatpak-builtins-remote-delete.c:68
#: app/flatpak-builtins-remote-list.c:241 app/flatpak-builtins-remote-ls.c:407
msgid "Too many arguments"
msgstr "Превише аргумената"

#: app/flatpak-builtins-build-bundle.c:659
#: app/flatpak-builtins-build-commit-from.c:338
#: app/flatpak-builtins-build-commit-from.c:351
#: app/flatpak-builtins-build-import-bundle.c:145
#, c-format
msgid "'%s' is not a valid repository"
msgstr "„%s“ није исправна ризница"

#: app/flatpak-builtins-build-bundle.c:663
#, c-format
msgid "'%s' is not a valid repository: "
msgstr "'%s' није исправна ризница: "

#: app/flatpak-builtins-build-bundle.c:674 app/flatpak-builtins-build-sign.c:88
#: common/flatpak-dir.c:14293
#, c-format
msgid "'%s' is not a valid name: %s"
msgstr "'%s' није исправан назив: %s"

#: app/flatpak-builtins-build-bundle.c:677
#: app/flatpak-builtins-build-export.c:865 app/flatpak-builtins-build-sign.c:91
#: common/flatpak-dir.c:14299
#, c-format
msgid "'%s' is not a valid branch name: %s"
msgstr "'%s' није исправан назив гране: %s"

#: app/flatpak-builtins-build-bundle.c:691
#: app/flatpak-builtins-build-import-bundle.c:149
#: app/flatpak-builtins-build-init.c:281
#, c-format
msgid "'%s' is not a valid filename"
msgstr "'%s' није исправан назив датотеке"

#: app/flatpak-builtins-build-bundle.c:706
msgid "--oci-layer-compress value must be gzip or zstd"
msgstr "вредност за --oci-layer-compress мора бити gzip или zstd"

#: app/flatpak-builtins-build.c:49
msgid "Use Platform runtime rather than Sdk"
msgstr "Користи извршно окружење платформе уместо СДК-а"

#: app/flatpak-builtins-build.c:50
msgid "Make destination readonly"
msgstr "Учини одредиште само за читање"

#: app/flatpak-builtins-build.c:51
msgid "Add bind mount"
msgstr "Додај повезано качење"

#: app/flatpak-builtins-build.c:51
msgid "DEST=SRC"
msgstr "ОДРЕДИШТЕ=ИЗВОР"

#: app/flatpak-builtins-build.c:52
msgid "Start build in this directory"
msgstr "Покрени изградњу у овом директоријуму"

#: app/flatpak-builtins-build.c:52 app/flatpak-builtins-build.c:53
#: app/flatpak-builtins-build-init.c:64 app/flatpak-builtins-run.c:160
msgid "DIR"
msgstr "ДИР"

#: app/flatpak-builtins-build.c:53
msgid "Where to look for custom sdk dir (defaults to 'usr')"
msgstr "Где тражити прилагођени сдк дир (подразумева се „usr“)"

#: app/flatpak-builtins-build.c:54 app/flatpak-builtins-build-export.c:67
msgid "Use alternative file for the metadata"
msgstr "Користи алтернативну датотеку за метаподатке"

#: app/flatpak-builtins-build.c:55 app/flatpak-builtins-run.c:177
msgid "Kill processes when the parent process dies"
msgstr "Убиј процесе када родитељски процес умре"

#: app/flatpak-builtins-build.c:56
msgid "Export application homedir directory to build"
msgstr "Извези директоријум личног директоријума програма за изградњу"

#: app/flatpak-builtins-build.c:57 app/flatpak-builtins-run.c:165
msgid "Log session bus calls"
msgstr "Бележи позиве сабирнице сесије"

#: app/flatpak-builtins-build.c:58 app/flatpak-builtins-run.c:166
msgid "Log system bus calls"
msgstr "Бележи позиве системске сабирнице"

#: app/flatpak-builtins-build.c:262
msgid "DIRECTORY [COMMAND [ARGUMENT…]] - Build in directory"
msgstr "ДИРЕКТОРИЈУМ [НАРЕДБА [АРГУМЕНТ…]] - Изгради у директоријуму"

#: app/flatpak-builtins-build.c:285 app/flatpak-builtins-build-finish.c:656
msgid "DIRECTORY must be specified"
msgstr "ДИРЕКТОРИЈУМ мора бити наведен"

#: app/flatpak-builtins-build.c:296 app/flatpak-builtins-build-export.c:887
#, c-format
msgid "Build directory %s not initialized, use flatpak build-init"
msgstr "Директоријум изградње %s није покренут, користите flatpak build-init"

#: app/flatpak-builtins-build.c:315
msgid "metadata invalid, not application or runtime"
msgstr "метаподаци су неисправни, нису програм или извршно окружење"

#: app/flatpak-builtins-build.c:446
#, c-format
msgid "No extension point matching %s in %s"
msgstr "Нема тачке проширења која се подудара са %s у %s"

#: app/flatpak-builtins-build.c:635
#, c-format
msgid "Missing '=' in bind mount option '%s'"
msgstr "Недостаје „=“ у опцији повезивања качења „%s“"

#: app/flatpak-builtins-build.c:679 common/flatpak-run.c:3961
#, c-format
msgid "Unable to start app"
msgstr "Не могу да покренем програм"

#: app/flatpak-builtins-build-commit-from.c:58
msgid "Source repo dir"
msgstr "Фасцикла изворне ризнице"

#: app/flatpak-builtins-build-commit-from.c:58
msgid "SRC-REPO"
msgstr "ИЗВОРНА-РИЗНИЦА"

#: app/flatpak-builtins-build-commit-from.c:59
msgid "Source repo ref"
msgstr "Упутница изворне ризнице"

#: app/flatpak-builtins-build-commit-from.c:59
msgid "SRC-REF"
msgstr "ИЗВОРНА-УПУТНИЦА"

#: app/flatpak-builtins-build-commit-from.c:64
#: app/flatpak-builtins-build-export.c:60
msgid "One line subject"
msgstr "Једноредни наслов"

#: app/flatpak-builtins-build-commit-from.c:64
#: app/flatpak-builtins-build-export.c:60
msgid "SUBJECT"
msgstr "НАСЛОВ"

#: app/flatpak-builtins-build-commit-from.c:65
#: app/flatpak-builtins-build-export.c:61
msgid "Full description"
msgstr "Потпун опис"

#: app/flatpak-builtins-build-commit-from.c:65
#: app/flatpak-builtins-build-export.c:61
msgid "BODY"
msgstr "ТЕЛО"

#: app/flatpak-builtins-build-commit-from.c:66
#: app/flatpak-builtins-build-export.c:64
#: app/flatpak-builtins-build-import-bundle.c:51
msgid "Update the appstream branch"
msgstr "Ажурирајте грану „appstream“"

#: app/flatpak-builtins-build-commit-from.c:67
#: app/flatpak-builtins-build-export.c:65
#: app/flatpak-builtins-build-import-bundle.c:52
#: app/flatpak-builtins-build-update-repo.c:87
msgid "Don't update the summary"
msgstr "Не ажурирајте сажетак"

#: app/flatpak-builtins-build-commit-from.c:68
#: app/flatpak-builtins-build-export.c:68
#: app/flatpak-builtins-build-import-bundle.c:49
#: app/flatpak-builtins-build-sign.c:44
msgid "GPG Key ID to sign the commit with"
msgstr "ИД ГПГ кључа за потписивање предаје"

#: app/flatpak-builtins-build-commit-from.c:70
#: app/flatpak-builtins-build-export.c:73
msgid "Mark build as end-of-life"
msgstr "Означите изградњу као застарелу"

#: app/flatpak-builtins-build-commit-from.c:70
#: app/flatpak-builtins-build-export.c:73
msgid "REASON"
msgstr "РАЗЛОГ"

#: app/flatpak-builtins-build-commit-from.c:71
msgid ""
"Mark refs matching the OLDID prefix as end-of-life, to be replaced with the "
"given NEWID"
msgstr ""
"Означите упутнице које се подударају са префиксом СТАРИ_ИД као застареле, да "
"би биле замењене датим НОВИ_ИД"

#: app/flatpak-builtins-build-commit-from.c:71
msgid "OLDID=NEWID"
msgstr "СТАРИ_ИД=НОВИ_ИД"

#: app/flatpak-builtins-build-commit-from.c:72
#: app/flatpak-builtins-build-export.c:75
msgid "Set type of token needed to install this commit"
msgstr "Поставите врсту жетона потребног за инсталацију ове предаје"

#: app/flatpak-builtins-build-commit-from.c:72
#: app/flatpak-builtins-build-export.c:75
msgid "VAL"
msgstr "ВРЕД"

#: app/flatpak-builtins-build-commit-from.c:73
msgid "Override the timestamp of the commit (NOW for current time)"
msgstr "Преклопи временску ознаку предаје (NOW за тренутно време)"

#: app/flatpak-builtins-build-commit-from.c:73
#: app/flatpak-builtins-build-export.c:76
msgid "TIMESTAMP"
msgstr "ВРЕМЕНСКА-ОЗНАКА"

#: app/flatpak-builtins-build-commit-from.c:75
#: app/flatpak-builtins-build-export.c:80
#: app/flatpak-builtins-build-import-bundle.c:53
#: app/flatpak-builtins-build-update-repo.c:97
msgid "Don't generate a summary index"
msgstr "Не стварај индекс сажетка"

#: app/flatpak-builtins-build-commit-from.c:278
msgid "DST-REPO [DST-REF…] - Make a new commit from existing commits"
msgstr ""
"ОДРЕДИШНА-РИЗНИЦА [ОДРЕДИШНА-УПУТНИЦА…] - Направи нову предају из постојећих "
"предаја"

#: app/flatpak-builtins-build-commit-from.c:285
msgid "DST-REPO must be specified"
msgstr "ОДРЕДИШНА-РИЗНИЦА мора бити наведена"

#: app/flatpak-builtins-build-commit-from.c:293
msgid ""
"If --src-repo is not specified, exactly one destination ref must be specified"
msgstr ""
"Ако --src-repo није наведено, мора бити наведена тачно једна одредишна "
"упутница"

#: app/flatpak-builtins-build-commit-from.c:296
msgid ""
"If --src-ref is specified, exactly one destination ref must be specified"
msgstr ""
"Ако је --src-ref наведено, мора бити наведена тачно једна одредишна упутница"

#: app/flatpak-builtins-build-commit-from.c:299
msgid "Either --src-repo or --src-ref must be specified"
msgstr "Мора бити наведено или --src-repo или --src-ref"

#: app/flatpak-builtins-build-commit-from.c:315
msgid "Invalid argument format of use  --end-of-life-rebase=OLDID=NEWID"
msgstr ""
"Неисправан облик аргумента за коришћење --end-of-life-rebase=СТАРИ_ИД=НОВИ_ИД"

#: app/flatpak-builtins-build-commit-from.c:321
#: app/flatpak-builtins-build-commit-from.c:324
#, c-format
msgid "Invalid name %s in --end-of-life-rebase"
msgstr "Неисправан назив %s у --end-of-life-rebase"

#: app/flatpak-builtins-build-commit-from.c:333
#: app/flatpak-builtins-build-export.c:1092
#, c-format
msgid "Could not parse '%s'"
msgstr "Не могу да обрадим „%s“"

#: app/flatpak-builtins-build-commit-from.c:498
msgid "Can't commit from partial source commit"
msgstr "Не могу да извршим предају из делимичне изворне предаје"

#: app/flatpak-builtins-build-commit-from.c:503
#, c-format
msgid "%s: no change\n"
msgstr "%s: нема измена\n"

#: app/flatpak-builtins-build-export.c:62
msgid "Architecture to export for (must be host compatible)"
msgstr "Архитектура за коју се извози (мора бити сагласна са домаћином)"

#: app/flatpak-builtins-build-export.c:63
msgid "Commit runtime (/usr), not /app"
msgstr "Предај извршно окружење (/usr), а не /app"

#: app/flatpak-builtins-build-export.c:66
msgid "Use alternative directory for the files"
msgstr "Користи алтернативни директоријум за датотеке"

#: app/flatpak-builtins-build-export.c:66
msgid "SUBDIR"
msgstr "ПОДДИРЕКТОРИЈУМ"

#: app/flatpak-builtins-build-export.c:69
msgid "Files to exclude"
msgstr "Датотеке за изузимање"

#: app/flatpak-builtins-build-export.c:69
#: app/flatpak-builtins-build-export.c:70
#: app/flatpak-builtins-build-update-repo.c:90
msgid "PATTERN"
msgstr "ОБРАЗАЦ"

#: app/flatpak-builtins-build-export.c:70
msgid "Excluded files to include"
msgstr "Искључене датотеке за укључивање"

#: app/flatpak-builtins-build-export.c:74
msgid "Mark build as end-of-life, to be replaced with the given ID"
msgstr "Означи изградњу као крај века трајања, да буде замењена датим ИБ-ом"

#: app/flatpak-builtins-build-export.c:74
#: app/flatpak-builtins-document-list.c:49 app/flatpak-cli-transaction.c:1427
msgid "ID"
msgstr "ИБ"

#: app/flatpak-builtins-build-export.c:76
msgid "Override the timestamp of the commit"
msgstr "Преклопи временску ознаку предаје"

#: app/flatpak-builtins-build-export.c:77
#: app/flatpak-builtins-build-update-repo.c:75
#: app/flatpak-builtins-remote-add.c:83 app/flatpak-builtins-remote-list.c:54
#: app/flatpak-builtins-remote-modify.c:88
msgid "Collection ID"
msgstr "ИБ збирке"

#: app/flatpak-builtins-build-export.c:472
#, c-format
msgid "WARNING: Error running desktop-file-validate: %s\n"
msgstr "УПОЗОРЕЊЕ: Грешка при покретању „desktop-file-validate“: %s\n"

#: app/flatpak-builtins-build-export.c:480
#, c-format
msgid "WARNING: Error reading from desktop-file-validate: %s\n"
msgstr "УПОЗОРЕЊЕ: Грешка при читању из „desktop-file-validate“: %s\n"

#: app/flatpak-builtins-build-export.c:486
#, c-format
msgid "WARNING: Failed to validate desktop file %s: %s\n"
msgstr "УПОЗОРЕЊЕ: Нисам успео да потврдим датотеку радне површи „%s“: %s\n"

#: app/flatpak-builtins-build-export.c:513
#, c-format
msgid "WARNING: Can't find Exec key in %s: %s\n"
msgstr "УПОЗОРЕЊЕ: Не могу да пронађем кључ „Exec“ у „%s“: %s\n"

#: app/flatpak-builtins-build-export.c:521
#: app/flatpak-builtins-build-export.c:614
#, c-format
msgid "WARNING: Binary not found for Exec line in %s: %s\n"
msgstr ""
"УПОЗОРЕЊЕ: Извршна датотека није пронађена за линију „Exec“ у „%s“: %s\n"

#: app/flatpak-builtins-build-export.c:529
#, c-format
msgid "WARNING: Icon not matching app id in %s: %s\n"
msgstr "УПОЗОРЕЊЕ: Иконица се не подудара са ИБ-ом програма у „%s“: %s\n"

#: app/flatpak-builtins-build-export.c:552
#, c-format
msgid "WARNING: Icon referenced in desktop file but not exported: %s\n"
msgstr ""
"УПОЗОРЕЊЕ: Иконица на коју се упућује у датотеци радне површи али није "
"извезена: %s\n"

#: app/flatpak-builtins-build-export.c:719
#, c-format
msgid "Invalid uri type %s, only http/https supported"
msgstr "Неисправна врста адресе „%s“, само су http/https подржани"

#: app/flatpak-builtins-build-export.c:737
#, c-format
msgid "Unable to find basename in %s, specify a name explicitly"
msgstr "Не могу да пронађем основни назив у „%s“, наведи назив експлицитно"

#: app/flatpak-builtins-build-export.c:746
#, c-format
msgid "No slashes allowed in extra data name"
msgstr "Косе црте нису дозвољене у називу додатних података"

#: app/flatpak-builtins-build-export.c:758
#, c-format
msgid "Invalid format for sha256 checksum: '%s'"
msgstr "Неисправан формат за sha256 суму провере: „%s“"

#: app/flatpak-builtins-build-export.c:768
#, c-format
msgid "Extra data sizes of zero not supported"
msgstr "Величине додатних података од нуле нису подржане"

#: app/flatpak-builtins-build-export.c:830
msgid ""
"LOCATION DIRECTORY [BRANCH] - Create a repository from a build directory"
msgstr "МЕСТО ДИРЕКТОРИЈУМ [ГРАНА] - Направи ризницу из директоријума изградње"

#: app/flatpak-builtins-build-export.c:838
msgid "LOCATION and DIRECTORY must be specified"
msgstr "МЕСТО и ДИРЕКТОРИЈУМ морају бити наведени"

#: app/flatpak-builtins-build-export.c:859
#: app/flatpak-builtins-remote-add.c:327
#, c-format
msgid "‘%s’ is not a valid collection ID: %s"
msgstr "„%s“ није исправан ИБ збирке: %s"

#: app/flatpak-builtins-build-export.c:904
#: app/flatpak-builtins-build-finish.c:684
msgid "No name specified in the metadata"
msgstr "Није наведен назив у метаподацима"

#: app/flatpak-builtins-build-export.c:1166
#, c-format
msgid "Commit: %s\n"
msgstr "Урезивање: %s\n"

#: app/flatpak-builtins-build-export.c:1167
#, c-format
msgid "Metadata Total: %u\n"
msgstr "Укупно метаподатака: %u\n"

#: app/flatpak-builtins-build-export.c:1168
#, c-format
msgid "Metadata Written: %u\n"
msgstr "Уписано метаподатака: %u\n"

#: app/flatpak-builtins-build-export.c:1169
#, c-format
msgid "Content Total: %u\n"
msgstr "Укупно садржаја: %u\n"

#: app/flatpak-builtins-build-export.c:1170
#, c-format
msgid "Content Written: %u\n"
msgstr "Уписано садржаја: %u\n"

#: app/flatpak-builtins-build-export.c:1171
#, c-format
msgid "Content Bytes Written:"
msgstr "Уписано бајтова садржаја:"

#: app/flatpak-builtins-build-finish.c:52
msgid "Command to set"
msgstr "Наредба за постављање"

#: app/flatpak-builtins-build-finish.c:52 app/flatpak-builtins-run.c:159
#: app/flatpak-main.c:209
msgid "COMMAND"
msgstr "НАРЕДБА"

#: app/flatpak-builtins-build-finish.c:53
msgid "Flatpak version to require"
msgstr "Тражи Флетпек издање"

#: app/flatpak-builtins-build-finish.c:53
msgid "MAJOR.MINOR.MICRO"
msgstr "ГЛАВНИ.СПОРЕДНИ.МИКРО"

#: app/flatpak-builtins-build-finish.c:54
msgid "Don't process exports"
msgstr "Не обрађуј извозе"

#: app/flatpak-builtins-build-finish.c:55
msgid "Extra data info"
msgstr "Подаци о додатним подацима"

#: app/flatpak-builtins-build-finish.c:56 app/flatpak-builtins-build-init.c:63
msgid "Add extension point info"
msgstr "Додај податке о тачки проширења"

#: app/flatpak-builtins-build-finish.c:56 app/flatpak-builtins-build-init.c:63
msgid "NAME=VARIABLE[=VALUE]"
msgstr "НАЗИВ=ПРОМЕНЉИВА[=ВРЕДНОСТ]"

#: app/flatpak-builtins-build-finish.c:57
msgid "Remove extension point info"
msgstr "Уклони податке о тачки проширења"

#: app/flatpak-builtins-build-finish.c:57
#: app/flatpak-builtins-build-update-repo.c:79 app/flatpak-builtins-info.c:58
#: app/flatpak-builtins-remote-add.c:88 app/flatpak-builtins-remote-modify.c:94
#: app/flatpak-main.c:182
msgid "NAME"
msgstr "НАЗИВ"

#: app/flatpak-builtins-build-finish.c:58
msgid "Set extension priority (only for extensions)"
msgstr "Постави приоритет проширења (само за проширења)"

#: app/flatpak-builtins-build-finish.c:58
msgid "VALUE"
msgstr "ВРЕДНОСТ"

#: app/flatpak-builtins-build-finish.c:59
msgid "Change the sdk used for the app"
msgstr "Промени СДК који користи програм"

#: app/flatpak-builtins-build-finish.c:59
msgid "SDK"
msgstr "СДК"

#: app/flatpak-builtins-build-finish.c:60
msgid "Change the runtime used for the app"
msgstr "Измените извршно окружење које користи апликација"

#: app/flatpak-builtins-build-finish.c:60 app/flatpak-builtins-build-init.c:54
#: app/flatpak-builtins-list.c:53 app/flatpak-builtins-remote-ls.c:58
#: app/flatpak-builtins-run.c:163
msgid "RUNTIME"
msgstr "ИЗВРШНО ОКРУЖЕЊЕ"

#: app/flatpak-builtins-build-finish.c:61
msgid "Set generic metadata option"
msgstr "Поставите општу опцију метаподатака"

#: app/flatpak-builtins-build-finish.c:61
msgid "GROUP=KEY[=VALUE]"
msgstr "ГРУПА=КЉУЧ[=ВРЕДНОСТ]"

#: app/flatpak-builtins-build-finish.c:62
msgid "Don't inherit permissions from runtime"
msgstr "Не наслеђуј овлашћења из извршног окружења"

#: app/flatpak-builtins-build-finish.c:155
#, c-format
msgid "Not exporting %s, wrong extension\n"
msgstr "Не извозим %s, погрешан наставак\n"

#: app/flatpak-builtins-build-finish.c:163
#, c-format
msgid "Not exporting %s, non-allowed export filename\n"
msgstr "Не извозим %s, недозвољен назив датотеке за извоз\n"

#: app/flatpak-builtins-build-finish.c:167
#, c-format
msgid "Exporting %s\n"
msgstr "Извозим %s\n"

#: app/flatpak-builtins-build-finish.c:440
#, c-format
msgid "More than one executable found\n"
msgstr "Пронађено је више од једне извршне датотеке\n"

#: app/flatpak-builtins-build-finish.c:451
#, c-format
msgid "Using %s as command\n"
msgstr "Користим %s као наредбу\n"

#: app/flatpak-builtins-build-finish.c:456
#, c-format
msgid "No executable found\n"
msgstr "Није пронађена ниједна извршна датотека\n"

#: app/flatpak-builtins-build-finish.c:511
#, c-format
msgid "Invalid --require-version argument: %s"
msgstr "Неисправан аргумент за --require-version: %s"

#: app/flatpak-builtins-build-finish.c:543
#, c-format
msgid "Too few elements in --extra-data argument %s"
msgstr "Премало елемената у аргументу --extra-data %s"

#: app/flatpak-builtins-build-finish.c:575
#, c-format
msgid ""
"Too few elements in --metadata argument %s, format should be "
"GROUP=KEY[=VALUE]]"
msgstr ""
"Премало елемената у аргументу --metadata %s, формат треба да буде "
"ГРУПА=КЉУЧ[=ВРЕДНОСТ]]"

#: app/flatpak-builtins-build-finish.c:597
#: app/flatpak-builtins-build-init.c:458
#, c-format
msgid ""
"Too few elements in --extension argument %s, format should be "
"NAME=VAR[=VALUE]"
msgstr ""
"Премало елемената у аргументу --extension %s, формат треба да буде "
"НАЗИВ=ПРОМ[=ВРЕДНОСТ]"

#: app/flatpak-builtins-build-finish.c:603
#: app/flatpak-builtins-build-init.c:461
#, c-format
msgid "Invalid extension name %s"
msgstr "Неисправан назив проширења %s"

#: app/flatpak-builtins-build-finish.c:646
msgid "DIRECTORY - Finalize a build directory"
msgstr "ДИРЕКТОРИЈУМ - Заврши директоријум изградње"

#: app/flatpak-builtins-build-finish.c:668
#, c-format
msgid "Build directory %s not initialized"
msgstr "Директоријум изградње %s није покренут"

#: app/flatpak-builtins-build-finish.c:689
#, c-format
msgid "Build directory %s already finalized"
msgstr "Директоријум изградње %s је већ завршен"

#: app/flatpak-builtins-build-finish.c:702
#, c-format
msgid "Please review the exported files and the metadata\n"
msgstr "Прегледајте извезене датотеке и метаподатке\n"

#: app/flatpak-builtins-build-import-bundle.c:47
msgid "Override the ref used for the imported bundle"
msgstr "Препиши реф који се користи за увезени комплет"

#: app/flatpak-builtins-build-import-bundle.c:47
msgid "REF"
msgstr "РЕФ"

#: app/flatpak-builtins-build-import-bundle.c:48
msgid "Import oci image instead of flatpak bundle"
msgstr "Увези OCI одраз уместо флетпек комплета"

#: app/flatpak-builtins-build-import-bundle.c:77
#: app/flatpak-builtins-build-import-bundle.c:105
#, c-format
msgid "Importing %s (%s)\n"
msgstr "Увозим „%s“ (%s)\n"

#: app/flatpak-builtins-build-import-bundle.c:126
msgid "LOCATION FILENAME - Import a file bundle into a local repository"
msgstr "МЕСТО ДАТОТЕКА - Увези датотеку комплета у локалну ризницу"

#: app/flatpak-builtins-build-import-bundle.c:133
msgid "LOCATION and FILENAME must be specified"
msgstr "МЕСТО и ДАТОТЕКА морају бити наведени"

#: app/flatpak-builtins-build-init.c:53 app/flatpak-builtins-info.c:55
#: app/flatpak-builtins-run.c:158
msgid "Arch to use"
msgstr "Архитектура за коришћење"

#: app/flatpak-builtins-build-init.c:54
msgid "Initialize var from named runtime"
msgstr "Покрени „var“ из именованог извршног окружења"

#: app/flatpak-builtins-build-init.c:55
msgid "Initialize apps from named app"
msgstr "Покрени програме из именованог програма"

#: app/flatpak-builtins-build-init.c:55
msgid "APP"
msgstr "ПРОГРАМ"

#: app/flatpak-builtins-build-init.c:56
msgid "Specify version for --base"
msgstr "Наведите издање за „--base“"

#: app/flatpak-builtins-build-init.c:56 app/flatpak-builtins-run.c:164
msgid "VERSION"
msgstr "ИЗДАЊЕ"

#: app/flatpak-builtins-build-init.c:57
msgid "Include this base extension"
msgstr "Укључи ово основно проширење"

#: app/flatpak-builtins-build-init.c:57 app/flatpak-builtins-build-init.c:62
msgid "EXTENSION"
msgstr "ПРОШИРЕЊЕ"

#: app/flatpak-builtins-build-init.c:58
msgid "Extension tag to use if building extension"
msgstr "Ознака проширења за коришћење ако се изграђује проширење"

#: app/flatpak-builtins-build-init.c:58
msgid "EXTENSION_TAG"
msgstr "ОЗНАКА_ПРОШИРЕЊА"

#: app/flatpak-builtins-build-init.c:59
msgid "Initialize /usr with a writable copy of the sdk"
msgstr "Покрени „/usr“ са уписивим умношком СДК-а"

#: app/flatpak-builtins-build-init.c:60
msgid "Specify the build type (app, runtime, extension)"
msgstr "Наведите врсту изградње (app, runtime, extension)"

#: app/flatpak-builtins-build-init.c:60
msgid "TYPE"
msgstr "ВРСТА"

#: app/flatpak-builtins-build-init.c:61
msgid "Add a tag"
msgstr "Додај ознаку"

#: app/flatpak-builtins-build-init.c:61
msgid "TAG"
msgstr "ОЗНАКА"

#: app/flatpak-builtins-build-init.c:62
msgid "Include this sdk extension in /usr"
msgstr "Укључи ово сдк проширење у /usr"

#: app/flatpak-builtins-build-init.c:64
msgid "Where to store sdk (defaults to 'usr')"
msgstr "Где сместити сдк (подразумевано је „usr“)"

#: app/flatpak-builtins-build-init.c:65
msgid "Re-initialize the sdk/var"
msgstr "Поново покрени sdk/var"

#: app/flatpak-builtins-build-init.c:118
#, c-format
msgid "Requested extension %s/%s/%s is only partially installed"
msgstr "Тражено проширење %s/%s/%s је само делимично инсталирано"

#: app/flatpak-builtins-build-init.c:147
#, c-format
msgid "Requested extension %s/%s/%s not installed"
msgstr "Тражено проширење %s/%s/%s није инсталирано"

#: app/flatpak-builtins-build-init.c:207
msgid ""
"DIRECTORY APPNAME SDK RUNTIME [BRANCH] - Initialize a directory for building"
msgstr ""
"ДИРЕКТОРИЈУМ НАЗИВПРОГРАМА СДК ИЗВРШНООКРУЖЕЊЕ [ГРАНА] - Покрени "
"директоријум за изградњу"

#: app/flatpak-builtins-build-init.c:214
msgid "RUNTIME must be specified"
msgstr "ИЗВРШНООКРУЖЕЊЕ мора бити наведено"

#: app/flatpak-builtins-build-init.c:235
#, c-format
msgid "'%s' is not a valid build type name, use app, runtime or extension"
msgstr ""
"„%s“ није исправан назив врсте изградње, користите „app“ (програм), "
"„runtime“ (извршно окружење) или „extension“ (проширење)"

#: app/flatpak-builtins-build-init.c:241 app/flatpak-builtins-override.c:79
#, c-format
msgid "'%s' is not a valid application name: %s"
msgstr "„%s“ није исправан назив програма: %s"

#: app/flatpak-builtins-build-init.c:295
#, c-format
msgid "Build directory %s already initialized"
msgstr "Директоријум изградње %s је већ покренут"

#: app/flatpak-builtins-build-sign.c:42 app/flatpak-builtins-install.c:67
#: app/flatpak-builtins-remote-info.c:54
msgid "Arch to install for"
msgstr "Архитектура за коју се инсталира"

#: app/flatpak-builtins-build-sign.c:43 app/flatpak-builtins-create-usb.c:48
#: app/flatpak-builtins-install.c:74 app/flatpak-builtins-remote-info.c:56
#: app/flatpak-builtins-uninstall.c:58 app/flatpak-builtins-update.c:64
msgid "Look for runtime with the specified name"
msgstr "Тражи извршно окружење са наведеним називом"

#: app/flatpak-builtins-build-sign.c:66
msgid "LOCATION [ID [BRANCH]] - Sign an application or runtime"
msgstr "МЕСТО [ИД [ГРАНА]] - Потпиши програм или извршно окружење"

#: app/flatpak-builtins-build-sign.c:73
#: app/flatpak-builtins-build-update-repo.c:499
#: app/flatpak-builtins-remote-add.c:320 app/flatpak-builtins-repo.c:739
msgid "LOCATION must be specified"
msgstr "МЕСТО мора бити наведено"

#: app/flatpak-builtins-build-sign.c:94
msgid "No gpg key ids specified"
msgstr "Нису наведени иб-ови гпг кључа"

#: app/flatpak-builtins-build-update-repo.c:68
msgid "Redirect this repo to a new URL"
msgstr "Преусмери ову ризницу на нову адресу"

#: app/flatpak-builtins-build-update-repo.c:69
msgid "A nice name to use for this repository"
msgstr "Леп назив који ће се користити за ову ризницу"

#: app/flatpak-builtins-build-update-repo.c:69
#: app/flatpak-builtins-remote-add.c:77 app/flatpak-builtins-remote-modify.c:82
msgid "TITLE"
msgstr "НАСЛОВ"

#: app/flatpak-builtins-build-update-repo.c:70
msgid "A one-line comment for this repository"
msgstr "Коментар у једном реду за ову ризницу"

#: app/flatpak-builtins-build-update-repo.c:70
#: app/flatpak-builtins-remote-add.c:78 app/flatpak-builtins-remote-modify.c:83
msgid "COMMENT"
msgstr "ПРИМЕДБА"

#: app/flatpak-builtins-build-update-repo.c:71
msgid "A full-paragraph description for this repository"
msgstr "Потпуни опис пасуса за ову ризницу"

#: app/flatpak-builtins-build-update-repo.c:71
#: app/flatpak-builtins-remote-add.c:79 app/flatpak-builtins-remote-modify.c:84
msgid "DESCRIPTION"
msgstr "ОПИС"

#: app/flatpak-builtins-build-update-repo.c:72
msgid "URL for a website for this repository"
msgstr "Адреса веб странице за ову ризницу"

#: app/flatpak-builtins-build-update-repo.c:73
msgid "URL for an icon for this repository"
msgstr "Адреса иконице за ову ризницу"

#: app/flatpak-builtins-build-update-repo.c:74
msgid "Default branch to use for this repository"
msgstr "Подразумевана грана која се користи за ову ризницу"

#: app/flatpak-builtins-build-update-repo.c:74
#: app/flatpak-builtins-remote-add.c:82 app/flatpak-builtins-remote-modify.c:87
#: app/flatpak-builtins-repo.c:713 app/flatpak-builtins-repo.c:714
#: app/flatpak-builtins-run.c:161
msgid "BRANCH"
msgstr "ГРАНА"

#: app/flatpak-builtins-build-update-repo.c:75
#: app/flatpak-builtins-remote-add.c:83 app/flatpak-builtins-remote-modify.c:88
msgid "COLLECTION-ID"
msgstr "ИБ-ЗБИРКЕ"

#. Translators: A sideload is when you install from a local USB drive rather than the Internet.
#: app/flatpak-builtins-build-update-repo.c:77
msgid ""
"Permanently deploy collection ID to client remote configurations, only for "
"sideload support"
msgstr ""
"Трајно пусти ИБ збирке у удаљена подешавања клијента, само за подршку бочног "
"учитавања"

#: app/flatpak-builtins-build-update-repo.c:78
msgid "Permanently deploy collection ID to client remote configurations"
msgstr "Трајно пусти ИБ збирке у удаљена подешавања клијента"

#: app/flatpak-builtins-build-update-repo.c:79
msgid "Name of authenticator for this repository"
msgstr "Назив потврђивача за ову ризницу"

#: app/flatpak-builtins-build-update-repo.c:80
msgid "Autoinstall authenticator for this repository"
msgstr "Самостално инсталирај потврђивач за ову ризницу"

#: app/flatpak-builtins-build-update-repo.c:81
msgid "Don't autoinstall authenticator for this repository"
msgstr "Не инсталирај самостално потврђивач за ову ризницу"

#: app/flatpak-builtins-build-update-repo.c:82
#: app/flatpak-builtins-remote-add.c:89
msgid "Authenticator option"
msgstr "Опција потврђивача"

#: app/flatpak-builtins-build-update-repo.c:82
#: app/flatpak-builtins-remote-add.c:89 app/flatpak-builtins-remote-modify.c:95
msgid "KEY=VALUE"
msgstr "КЉУЧ=ВРЕДНОСТ"

#: app/flatpak-builtins-build-update-repo.c:83
msgid "Import new default GPG public key from FILE"
msgstr "Увези нови подразумевани ГПГ јавни кључ из ДАТОТЕКЕ"

#: app/flatpak-builtins-build-update-repo.c:84
msgid "GPG Key ID to sign the summary with"
msgstr "ИБ ГПГ кључа којим ће се потписати сажетак"

#: app/flatpak-builtins-build-update-repo.c:86
msgid "Generate delta files"
msgstr "Направи делта датотеке"

#: app/flatpak-builtins-build-update-repo.c:88
msgid "Don't update the appstream branch"
msgstr "Не ажурирај грану апстрима"

#: app/flatpak-builtins-build-update-repo.c:89
msgid "Max parallel jobs when creating deltas (default: NUMCPUs)"
msgstr ""
"Највећи број паралелних послова при стварању делти (подразумевано: NUMCPUs)"

#: app/flatpak-builtins-build-update-repo.c:89
msgid "NUM-JOBS"
msgstr "БРОЈ-ПОСЛОВА"

#: app/flatpak-builtins-build-update-repo.c:90
msgid "Don't create deltas matching refs"
msgstr "Не прави делте које се подударају са референцама"

#: app/flatpak-builtins-build-update-repo.c:91
msgid "Prune unused objects"
msgstr "Очисти некоришћене објекте"

#: app/flatpak-builtins-build-update-repo.c:92
msgid "Prune but don't actually remove anything"
msgstr "Очисти али не уклањај ништа заправо"

#: app/flatpak-builtins-build-update-repo.c:93
msgid "Only traverse DEPTH parents for each commit (default: -1=infinite)"
msgstr ""
"Пређи само DEPTH родитеља за сваку предају (подразумевано: -1=бесконачно)"

#: app/flatpak-builtins-build-update-repo.c:93
msgid "DEPTH"
msgstr "ДУБИНА"

#: app/flatpak-builtins-build-update-repo.c:223
#, c-format
msgid "Generating delta: %s (%.10s)\n"
msgstr "Стварам делту: %s (%.10s)\n"

#: app/flatpak-builtins-build-update-repo.c:225
#, c-format
msgid "Generating delta: %s (%.10s-%.10s)\n"
msgstr "Стварам делту: %s (%.10s-%.10s)\n"

#: app/flatpak-builtins-build-update-repo.c:233
#, c-format
msgid "Failed to generate delta %s (%.10s): "
msgstr "Нисам успео да створим делту %s (%.10s): "

#: app/flatpak-builtins-build-update-repo.c:236
#, c-format
msgid "Failed to generate delta %s (%.10s-%.10s): "
msgstr "Нисам успео да створим делту %s (%.10s-%.10s): "

#: app/flatpak-builtins-build-update-repo.c:492
msgid "LOCATION - Update repository metadata"
msgstr "МЕСТО - Ажурирај метаподатке ризнице"

#: app/flatpak-builtins-build-update-repo.c:609
#, c-format
msgid "Updating appstream branch\n"
msgstr "Ажурирам appstream грану\n"

#: app/flatpak-builtins-build-update-repo.c:638
#, c-format
msgid "Updating summary\n"
msgstr "Ажурирам сажетак\n"

#: app/flatpak-builtins-build-update-repo.c:664
#, c-format
msgid "Total objects: %u\n"
msgstr "Укупно објеката: %u\n"

#: app/flatpak-builtins-build-update-repo.c:666
#, c-format
msgid "No unreachable objects\n"
msgstr "Нема недоступних објеката\n"

#: app/flatpak-builtins-build-update-repo.c:668
#, c-format
msgid "Deleted %u objects, %s freed\n"
msgstr "Обрисано је %u објеката, %s је ослобођено\n"

#: app/flatpak-builtins-config.c:41
msgid "List configuration keys and values"
msgstr "Испиши кључеве и вредности подешавања"

#: app/flatpak-builtins-config.c:42
msgid "Get configuration for KEY"
msgstr "Добави подешавање за КЉУЧ"

#: app/flatpak-builtins-config.c:43
msgid "Set configuration for KEY to VALUE"
msgstr "Постави подешавање за КЉУЧ на ВРЕДНОСТ"

#: app/flatpak-builtins-config.c:44
msgid "Unset configuration for KEY"
msgstr "Поништи подешавање за КЉУЧ"

#: app/flatpak-builtins-config.c:149
#, c-format
msgid "'%s' does not look like a language/locale code"
msgstr "'%s' не изгледа као код језика/локалитета"

#: app/flatpak-builtins-config.c:172
#, c-format
msgid "'%s' does not look like a language code"
msgstr "'%s' не изгледа као код језика"

#: app/flatpak-builtins-config.c:190
#, c-format
msgid "'%s' is not a valid value (use 'true' or 'false')"
msgstr "'%s' није исправна вредност (користите „true“ или „false“)"

#: app/flatpak-builtins-config.c:262
#, c-format
msgid "Unknown configure key '%s'"
msgstr "Непознат кључ подешавања „%s“"

#: app/flatpak-builtins-config.c:284
msgid "Too many arguments for --list"
msgstr "Превише аргумената за --list"

#: app/flatpak-builtins-config.c:314 app/flatpak-builtins-config.c:362
msgid "You must specify KEY"
msgstr "Морате навести КЉУЧ"

#: app/flatpak-builtins-config.c:316
msgid "Too many arguments for --get"
msgstr "Превише аргумената за --get"

#: app/flatpak-builtins-config.c:338
msgid "You must specify KEY and VALUE"
msgstr "Морате навести КЉУЧ и ВРЕДНОСТ"

#: app/flatpak-builtins-config.c:340
msgid "Too many arguments for --set"
msgstr "Превише аргумената за --set"

#: app/flatpak-builtins-config.c:364
msgid "Too many arguments for --unset"
msgstr "Превише аргумената за --unset"

#: app/flatpak-builtins-config.c:383
msgid "[KEY [VALUE]] - Manage configuration"
msgstr "[КЉУЧ [ВРЕДНОСТ]] - Управљање подешавањима"

#: app/flatpak-builtins-config.c:394
msgid "Can only use one of --list, --get, --set or --unset"
msgstr "Може се користити само једно од --list, --get, --set или --unset"

#: app/flatpak-builtins-config.c:408
msgid "Must specify one of --list, --get, --set or --unset"
msgstr "Мора се навести једно од --list, --get, --set или --unset"

#: app/flatpak-builtins-create-usb.c:45 app/flatpak-builtins-install.c:75
#: app/flatpak-builtins-remote-info.c:57 app/flatpak-builtins-uninstall.c:59
#: app/flatpak-builtins-update.c:65
msgid "Look for app with the specified name"
msgstr "Тражи програм са наведеним називом"

#: app/flatpak-builtins-create-usb.c:46
msgid "Arch to copy"
msgstr "Архитектура за умножавање"

#: app/flatpak-builtins-create-usb.c:47
msgid "DEST"
msgstr "ОДРЕДИШТЕ"

#: app/flatpak-builtins-create-usb.c:49
msgid "Allow partial commits in the created repo"
msgstr "Дозволи делимична предавања у направљеној ризници"

#: app/flatpak-builtins-create-usb.c:125 app/flatpak-builtins-create-usb.c:165
#, c-format
msgid ""
"Warning: Related ref ‘%s’ is partially installed. Use --allow-partial to "
"suppress this message.\n"
msgstr ""
"Упозорење: Повезана упутница „%s“ је делимично инсталирана. Користите --"
"allow-partial да потиснете ову поруку.\n"

#: app/flatpak-builtins-create-usb.c:158
#, c-format
msgid "Warning: Omitting related ref ‘%s’ because it is not installed.\n"
msgstr "Упозорење: Изостављам повезану упутницу „%s“ јер није инсталирана.\n"

#: app/flatpak-builtins-create-usb.c:175
#, c-format
msgid ""
"Warning: Omitting related ref ‘%s’ because its remote ‘%s’ does not have a "
"collection ID set.\n"
msgstr ""
"Упозорење: Изостављам повезану упутницу „%s“ јер њена удаљена ризница „%s“ "
"нема постављен ИД збирке.\n"

#: app/flatpak-builtins-create-usb.c:187
#, c-format
msgid "Warning: Omitting related ref ‘%s’ because it's extra-data.\n"
msgstr ""
"Упозорење: Изостављам повезану референцу „%s“ јер су то додатни подаци.\n"

#: app/flatpak-builtins-create-usb.c:262 app/flatpak-builtins-create-usb.c:637
#, c-format
msgid ""
"Remote ‘%s’ does not have a collection ID set, which is required for P2P "
"distribution of ‘%s’."
msgstr ""
"Удаљена ризница „%s“ нема постављен ИД збирке, што је неопходно за П2П "
"дистрибуцију „%s“."

#: app/flatpak-builtins-create-usb.c:272
#, c-format
msgid "Warning: Omitting ref ‘%s’ (runtime of ‘%s’) because it's extra-data.\n"
msgstr ""
"Упозорење: Изостављам референцу „%s“ (извршно окружење за „%s“) јер су то "
"додатни подаци.\n"

#: app/flatpak-builtins-create-usb.c:484
msgid "MOUNT-PATH [REF…] - Copy apps or runtimes onto removable media"
msgstr ""
"ПУТАЊА-КАЧЕЊА [РЕФ…] - Копирајте програме или извршна окружења на уклоњиве "
"медије"

#: app/flatpak-builtins-create-usb.c:493
msgid "MOUNT-PATH and REF must be specified"
msgstr "ПУТАЊА-КАЧЕЊА и РЕФ морају бити наведени"

#: app/flatpak-builtins-create-usb.c:607
#, c-format
msgid "Ref ‘%s’ found in multiple installations: %s. You must specify one."
msgstr ""
"Референца „%s“ је пронађена у више инсталација: %s. Морате навести једну."

#: app/flatpak-builtins-create-usb.c:620
#, c-format
msgid "Refs must all be in the same installation (found in %s and %s)."
msgstr "Све референце морају бити у истој инсталацији (пронађене у %s и %s)."

#: app/flatpak-builtins-create-usb.c:670
#, c-format
msgid ""
"Warning: Ref ‘%s’ is partially installed. Use --allow-partial to suppress "
"this message.\n"
msgstr ""
"Упозорење: Референца „%s“ је делимично инсталирана. Користите --allow-"
"partial да потиснете ову поруку.\n"

#: app/flatpak-builtins-create-usb.c:681
#, c-format
msgid "Installed ref ‘%s’ is extra-data, and cannot be distributed offline"
msgstr ""
"Инсталирана референца „%s“ су додатни подаци и не може се дистрибуирати ван "
"мреже"

#: app/flatpak-builtins-create-usb.c:721
#, c-format
msgid "Warning: Couldn't update repo metadata for remote ‘%s’: %s\n"
msgstr ""
"Упозорење: Не могу да ажурирам метаподатке ризнице за удаљену локацију „%s“: "
"%s\n"

#: app/flatpak-builtins-create-usb.c:751
#, c-format
msgid "Warning: Couldn't update appstream data for remote ‘%s’ arch ‘%s’: %s\n"
msgstr ""
"Упозорење: Не могу да ажурирам appstream податке за удаљену локацију „%s“ "
"архитектуре „%s“: %s\n"

#. Print a warning if both appstream and appstream2 are missing
#: app/flatpak-builtins-create-usb.c:784
#, c-format
msgid ""
"Warning: Couldn't find appstream data for remote ‘%s’ arch ‘%s’: %s; %s\n"
msgstr ""
"Упозорење: Не могу да пронађем appstream податке за удаљену локацију „%s“ "
"архитектуре „%s“: %s; %s\n"

#. Appstream2 is only for efficiency, so just print a debug message
#: app/flatpak-builtins-create-usb.c:790
#, c-format
msgid "Couldn't find appstream2 data for remote ‘%s’ arch ‘%s’: %s\n"
msgstr ""
"Не могу да пронађем appstream2 податке за удаљену локацију „%s“ архитектуре "
"„%s“: %s\n"

#: app/flatpak-builtins-document-export.c:62
msgid "Create a unique document reference"
msgstr "Направите јединствену референцу документа"

#: app/flatpak-builtins-document-export.c:63
msgid "Make the document transient for the current session"
msgstr "Учините документ привременим за текућу сесију"

#: app/flatpak-builtins-document-export.c:64
msgid "Don't require the file to exist already"
msgstr "Не захтевајте да датотека већ постоји"

#: app/flatpak-builtins-document-export.c:65
msgid "Give the app read permissions"
msgstr "Дајте програму овлашћења за читање"

#: app/flatpak-builtins-document-export.c:66
msgid "Give the app write permissions"
msgstr "Дајте програму овлашћења за писање"

#: app/flatpak-builtins-document-export.c:67
msgid "Give the app delete permissions"
msgstr "Дајте програму овлашћења за брисање"

#: app/flatpak-builtins-document-export.c:68
msgid "Give the app permissions to grant further permissions"
msgstr "Дајте програму овлашћења да додељује даља овлашћења"

#: app/flatpak-builtins-document-export.c:69
msgid "Revoke read permissions of the app"
msgstr "Опозови овлашћења програма за читање"

#: app/flatpak-builtins-document-export.c:70
msgid "Revoke write permissions of the app"
msgstr "Опозови овлашћења програма за писање"

#: app/flatpak-builtins-document-export.c:71
msgid "Revoke delete permissions of the app"
msgstr "Опозови овлашћења програма за брисање"

#: app/flatpak-builtins-document-export.c:72
msgid "Revoke the permission to grant further permissions"
msgstr "Опозови овлашћење за додељивање даљих овлашћења"

#: app/flatpak-builtins-document-export.c:73
msgid "Add permissions for this app"
msgstr "Додај овлашћења за овај програм"

#: app/flatpak-builtins-document-export.c:73
msgid "APPID"
msgstr "ИБПРОГРАМА"

#: app/flatpak-builtins-document-export.c:100
msgid "FILE - Export a file to apps"
msgstr "ДАТОТЕКА - Извези датотеку у програме"

#: app/flatpak-builtins-document-export.c:109
#: app/flatpak-builtins-document-info.c:72
#: app/flatpak-builtins-document-unexport.c:67
msgid "FILE must be specified"
msgstr "ДАТОТЕКА мора бити наведена"

#: app/flatpak-builtins-document-info.c:63
msgid "FILE - Get information about an exported file"
msgstr "ДАТОТЕКА - Добави податке о извезеној датотеци"

#: app/flatpak-builtins-document-info.c:100
#: app/flatpak-builtins-document-unexport.c:94
#, c-format
msgid "Not exported\n"
msgstr "Није извезено\n"

#: app/flatpak-builtins-document-list.c:43 app/flatpak-builtins-history.c:53
#: app/flatpak-builtins-list.c:54 app/flatpak-builtins-ps.c:43
#: app/flatpak-builtins-remote-list.c:45 app/flatpak-builtins-remote-ls.c:59
#: app/flatpak-builtins-search.c:38
msgid "What information to show"
msgstr "Које податке приказати"

#: app/flatpak-builtins-document-list.c:43 app/flatpak-builtins-history.c:53
#: app/flatpak-builtins-list.c:54 app/flatpak-builtins-ps.c:43
#: app/flatpak-builtins-remote-list.c:45 app/flatpak-builtins-remote-ls.c:59
#: app/flatpak-builtins-search.c:38
msgid "FIELD,…"
msgstr "ПОЉЕ,…"

#: app/flatpak-builtins-document-list.c:44 app/flatpak-builtins-history.c:54
#: app/flatpak-builtins-list.c:52 app/flatpak-builtins-permission-list.c:43
#: app/flatpak-builtins-permission-show.c:43 app/flatpak-builtins-ps.c:44
#: app/flatpak-builtins-remote-list.c:46 app/flatpak-builtins-remote-ls.c:63
#: app/flatpak-builtins-repo.c:717 app/flatpak-builtins-search.c:39
msgid "Show output in JSON format"
msgstr "Прикажи излаз у JSON формату"

#: app/flatpak-builtins-document-list.c:49
msgid "Show the document ID"
msgstr "Прикажи ИД документа"

#: app/flatpak-builtins-document-list.c:50
msgid "Path"
msgstr "Путања"

#: app/flatpak-builtins-document-list.c:50
#: app/flatpak-builtins-document-list.c:51
msgid "Show the document path"
msgstr "Прикажи путању документа"

#: app/flatpak-builtins-document-list.c:51 app/flatpak-builtins-list.c:66
#: app/flatpak-builtins-remote-ls.c:74
msgid "Origin"
msgstr "Порекло"

#: app/flatpak-builtins-document-list.c:52 app/flatpak-builtins-history.c:62
#: app/flatpak-builtins-ps.c:52
msgid "Application"
msgstr "Програм"

#: app/flatpak-builtins-document-list.c:52
msgid "Show applications with permission"
msgstr "Прикажи програме са овлашћењем"

#: app/flatpak-builtins-document-list.c:53
#: app/flatpak-builtins-permission-list.c:182
#: app/flatpak-builtins-permission-show.c:145
msgid "Permissions"
msgstr "Овлашћења"

#: app/flatpak-builtins-document-list.c:53
msgid "Show permissions for applications"
msgstr "Прикажи овлашћења за програме"

#: app/flatpak-builtins-document-list.c:161
#, c-format
msgid "No documents found\n"
msgstr "Нису пронађени документи\n"

#: app/flatpak-builtins-document-list.c:180
msgid "[APPID] - List exported files"
msgstr "[ИБПРОГРАМА] - Списак извезених датотека"

#: app/flatpak-builtins-document-unexport.c:43
msgid "Specify the document ID"
msgstr "Наведите ИБ документа"

#: app/flatpak-builtins-document-unexport.c:58
msgid "FILE - Unexport a file to apps"
msgstr "ДАТОТЕКА - Поништи извоз датотеке у програме"

#: app/flatpak-builtins-enter.c:88
msgid "INSTANCE COMMAND [ARGUMENT…] - Run a command inside a running sandbox"
msgstr ""
"ПРИМЕРАК НАРЕДБА [АРГУМЕНТ…] - Покрените наредбу унутар покренуте изолације "
"(sandbox)"

#: app/flatpak-builtins-enter.c:111
msgid "INSTANCE and COMMAND must be specified"
msgstr "ПРИМЕРАК и НАРЕДБА морају бити наведени"

#: app/flatpak-builtins-enter.c:138
#, c-format
msgid "%s is neither a pid nor an application or instance ID"
msgstr "%s није ни пид ни ИБ програма или примерка"

#: app/flatpak-builtins-enter.c:144
msgid "entering not supported (need unprivileged user namespaces, or sudo -E)"
msgstr ""
"улазак није подржан (потребни су неповлашћени кориснички именски простори, "
"или sudo -E)"

#: app/flatpak-builtins-enter.c:145
#, c-format
msgid "No such pid %s"
msgstr "Нема таквог пид-а %s"

#: app/flatpak-builtins-enter.c:158
msgid "Can't read cwd"
msgstr "Не могу да прочитам cwd"

#: app/flatpak-builtins-enter.c:163
msgid "Can't read root"
msgstr "Не могу да прочитам root"

#: app/flatpak-builtins-enter.c:191
#, c-format
msgid "Invalid %s namespace for pid %d"
msgstr "Неисправан %s именски простор за пид %d"

#: app/flatpak-builtins-enter.c:202
#, c-format
msgid "Invalid %s namespace for self"
msgstr "Неисправан %s именски простор за себе"

#: app/flatpak-builtins-enter.c:216
#, c-format
msgid "Can't open %s namespace: %s"
msgstr "Не могу да отворим %s именски простор: %s"

#: app/flatpak-builtins-enter.c:226
msgid "entering not supported (need unprivileged user namespaces)"
msgstr ""
"улазак није подржан (потребни су неповлашћени кориснички именски простори)"

#: app/flatpak-builtins-enter.c:227
#, c-format
msgid "Can't enter %s namespace: %s"
msgstr "Не могу да уђем у %s именски простор: %s"

#: app/flatpak-builtins-enter.c:234
msgid "Can't chdir"
msgstr "Не могу да извршим chdir"

#: app/flatpak-builtins-enter.c:237
msgid "Can't chroot"
msgstr "Не могу да извршим chroot"

#: app/flatpak-builtins-enter.c:240
msgid "Can't switch gid"
msgstr "Не могу да променим gid"

#: app/flatpak-builtins-enter.c:243
msgid "Can't switch uid"
msgstr "Не могу да променим ЈИБ"

#: app/flatpak-builtins-history.c:50
msgid "Only show changes after TIME"
msgstr "Прикажи само измене након ВРЕМЕНА"

#: app/flatpak-builtins-history.c:50 app/flatpak-builtins-history.c:51
msgid "TIME"
msgstr "ВРЕМЕ"

#: app/flatpak-builtins-history.c:51
msgid "Only show changes before TIME"
msgstr "Прикажи само измене пре ВРЕМЕНА"

#: app/flatpak-builtins-history.c:52
msgid "Show newest entries first"
msgstr "Прикажи прво најновије уносе"

#: app/flatpak-builtins-history.c:59
msgid "Time"
msgstr "Време"

#: app/flatpak-builtins-history.c:59
msgid "Show when the change happened"
msgstr "Прикажи када се измена догодила"

#: app/flatpak-builtins-history.c:60
msgid "Change"
msgstr "Измена"

#: app/flatpak-builtins-history.c:60
msgid "Show the kind of change"
msgstr "Прикажи врсту измене"

#: app/flatpak-builtins-history.c:61 app/flatpak-builtins-list.c:68
#: app/flatpak-builtins-remote-ls.c:75 app/flatpak-builtins-repo.c:335
msgid "Ref"
msgstr "Упутница"

#: app/flatpak-builtins-history.c:61 app/flatpak-builtins-list.c:68
#: app/flatpak-builtins-remote-ls.c:75
msgid "Show the ref"
msgstr "Прикажи упутницу"

#: app/flatpak-builtins-history.c:62
msgid "Show the application/runtime ID"
msgstr "Прикажи ИБ програма/извршног окружења"

#: app/flatpak-builtins-history.c:63 app/flatpak-builtins-list.c:64
#: app/flatpak-builtins-ps.c:53 app/flatpak-builtins-remote-ls.c:73
#: app/flatpak-cli-transaction.c:1435
msgid "Arch"
msgstr "Архитектура"

#: app/flatpak-builtins-history.c:63 app/flatpak-builtins-list.c:64
#: app/flatpak-builtins-ps.c:53 app/flatpak-builtins-remote-ls.c:73
msgid "Show the architecture"
msgstr "Прикажи архитектуру"

#: app/flatpak-builtins-history.c:64 app/flatpak-builtins-list.c:63
#: app/flatpak-builtins-ps.c:54 app/flatpak-builtins-remote-ls.c:72
#: app/flatpak-builtins-search.c:48 app/flatpak-cli-transaction.c:1438
msgid "Branch"
msgstr "Грана"

#: app/flatpak-builtins-history.c:64 app/flatpak-builtins-list.c:63
#: app/flatpak-builtins-remote-ls.c:72
msgid "Show the branch"
msgstr "Прикажи грану"

#: app/flatpak-builtins-history.c:65 app/flatpak-builtins-list.c:67
msgid "Installation"
msgstr "Инсталација"

#: app/flatpak-builtins-history.c:65
msgid "Show the affected installation"
msgstr "Прикажи захваћену инсталацију"

#: app/flatpak-builtins-history.c:66 app/flatpak-cli-transaction.c:1452
msgid "Remote"
msgstr "Удаљено"

#: app/flatpak-builtins-history.c:66
msgid "Show the remote"
msgstr "Прикажи удаљено"

#: app/flatpak-builtins-history.c:67 app/flatpak-builtins-ps.c:55
#: app/flatpak-builtins-remote-ls.c:76
msgid "Commit"
msgstr "Предаја"

#: app/flatpak-builtins-history.c:67
msgid "Show the current commit"
msgstr "Прикажи тренутну предају"

#: app/flatpak-builtins-history.c:68
msgid "Old Commit"
msgstr "Стара предаја"

#: app/flatpak-builtins-history.c:68
msgid "Show the previous commit"
msgstr "Прикажи претходну предају"

#: app/flatpak-builtins-history.c:69
msgid "Show the remote URL"
msgstr "Прикажи удаљену адресу (URL)"

#: app/flatpak-builtins-history.c:70 app/flatpak-cli-transaction.c:700
msgid "User"
msgstr "Корисник"

#: app/flatpak-builtins-history.c:70
msgid "Show the user doing the change"
msgstr "Прикажи корисника који је извршио измену"

#: app/flatpak-builtins-history.c:71
msgid "Tool"
msgstr "Алат"

#: app/flatpak-builtins-history.c:71
msgid "Show the tool that was used"
msgstr "Прикажи алат који је коришћен"

#: app/flatpak-builtins-history.c:72 app/flatpak-builtins-list.c:62
#: app/flatpak-builtins-remote-ls.c:71 app/flatpak-builtins-search.c:47
msgid "Version"
msgstr "Издање"

#: app/flatpak-builtins-history.c:72
msgid "Show the Flatpak version"
msgstr "Прикажи издање Флетпека"

#: app/flatpak-builtins-history.c:91
#, c-format
msgid "Failed to get journal data (%s): %s"
msgstr "Нисам успео да добавим податке дневника (%s): %s"

#: app/flatpak-builtins-history.c:146
#, c-format
msgid "Failed to open journal: %s"
msgstr "Нисам успео да отворим дневник: %s"

#: app/flatpak-builtins-history.c:153
#, c-format
msgid "Failed to add match to journal: %s"
msgstr "Нисам успео да додам поклапање у дневник: %s"

#: app/flatpak-builtins-history.c:471
msgid " - Show history"
msgstr " - Прикажи историјат"

#: app/flatpak-builtins-history.c:490
#, c-format
msgid "Failed to parse the --since option"
msgstr "Нисам успео да обрадим опцију „--since“"

#: app/flatpak-builtins-history.c:501
#, c-format
msgid "Failed to parse the --until option"
msgstr "Нисам успео да обрадим опцију „--until“"

#: app/flatpak-builtins-info.c:56
msgid "Show user installations"
msgstr "Прикажи корисничке инсталације"

#: app/flatpak-builtins-info.c:57
msgid "Show system-wide installations"
msgstr "Прикажи системске инсталације"

#: app/flatpak-builtins-info.c:58
msgid "Show specific system-wide installations"
msgstr "Прикажи специфичне системске инсталације"

#: app/flatpak-builtins-info.c:59 app/flatpak-builtins-remote-info.c:59
msgid "Show ref"
msgstr "Прикажи референцу"

#: app/flatpak-builtins-info.c:60 app/flatpak-builtins-remote-info.c:60
msgid "Show commit"
msgstr "Прикажи предају"

#: app/flatpak-builtins-info.c:61
msgid "Show origin"
msgstr "Прикажи порекло"

#: app/flatpak-builtins-info.c:62
msgid "Show size"
msgstr "Прикажи величину"

#: app/flatpak-builtins-info.c:63 app/flatpak-builtins-remote-info.c:62
msgid "Show metadata"
msgstr "Прикажи метаподатке"

#: app/flatpak-builtins-info.c:64 app/flatpak-builtins-remote-info.c:63
msgid "Show runtime"
msgstr "Прикажи извршно окружење"

#: app/flatpak-builtins-info.c:65 app/flatpak-builtins-remote-info.c:64
msgid "Show sdk"
msgstr "Прикажи СДК"

#: app/flatpak-builtins-info.c:66
msgid "Show permissions"
msgstr "Прикажи овлашћења"

#: app/flatpak-builtins-info.c:67
msgid "Query file access"
msgstr "Упит за приступ датотеци"

#: app/flatpak-builtins-info.c:67 app/flatpak-builtins-install.c:82
#: app/flatpak-builtins-install.c:88 app/flatpak-builtins-preinstall.c:68
#: app/flatpak-builtins-run.c:182 app/flatpak-builtins-run.c:184
#: app/flatpak-builtins-update.c:67 app/flatpak-builtins-update.c:71
msgid "PATH"
msgstr "ПУТАЊА"

#: app/flatpak-builtins-info.c:68
msgid "Show extensions"
msgstr "Прикажи проширења"

#: app/flatpak-builtins-info.c:69
msgid "Show location"
msgstr "Прикажи место"

#: app/flatpak-builtins-info.c:116
msgid "NAME [BRANCH] - Get info about an installed app or runtime"
msgstr ""
"НАЗИВ [ГРАНА] - Добави податке о инсталираном програму или извршном окружењу"

#: app/flatpak-builtins-info.c:123 app/flatpak-builtins-remote-add.c:317
#: app/flatpak-builtins-remote-delete.c:63
msgid "NAME must be specified"
msgstr "НАЗИВ мора бити наведен"

#: app/flatpak-builtins-info.c:196
msgid "ref not present in origin"
msgstr "упут није присутан у пореклу"

#: app/flatpak-builtins-info.c:211 app/flatpak-builtins-remote-info.c:217
#, c-format
msgid "Warning: Commit has no flatpak metadata\n"
msgstr "Упозорење: Предаја нема флетпек метаподатке\n"

#: app/flatpak-builtins-info.c:217 app/flatpak-builtins-info.c:259
#: app/flatpak-builtins-info.c:455 app/flatpak-builtins-info.c:513
#: app/flatpak-builtins-remote-info.c:236
#: app/flatpak-builtins-remote-info.c:271
msgid "ID:"
msgstr "ИБ:"

#: app/flatpak-builtins-info.c:218 app/flatpak-builtins-info.c:260
#: app/flatpak-builtins-remote-info.c:237
#: app/flatpak-builtins-remote-info.c:272
msgid "Ref:"
msgstr "Упут:"

#: app/flatpak-builtins-info.c:219 app/flatpak-builtins-info.c:261
#: app/flatpak-builtins-remote-info.c:238
#: app/flatpak-builtins-remote-info.c:273
msgid "Arch:"
msgstr "Архитектура:"

#: app/flatpak-builtins-info.c:220 app/flatpak-builtins-info.c:262
#: app/flatpak-builtins-remote-info.c:239
#: app/flatpak-builtins-remote-info.c:274
msgid "Branch:"
msgstr "Грана:"

#: app/flatpak-builtins-info.c:222 app/flatpak-builtins-info.c:264
#: app/flatpak-builtins-remote-info.c:241
#: app/flatpak-builtins-remote-info.c:276
msgid "Version:"
msgstr "Издање:"

#: app/flatpak-builtins-info.c:224 app/flatpak-builtins-info.c:266
#: app/flatpak-builtins-remote-info.c:243
#: app/flatpak-builtins-remote-info.c:278
msgid "License:"
msgstr "Лиценца:"

#: app/flatpak-builtins-info.c:226 app/flatpak-builtins-info.c:269
#: app/flatpak-builtins-remote-info.c:245
#: app/flatpak-builtins-remote-info.c:280
msgid "Collection:"
msgstr "Збирка:"

#: app/flatpak-builtins-info.c:227 app/flatpak-builtins-info.c:270
#: app/flatpak-builtins-info.c:458 app/flatpak-builtins-info.c:516
msgid "Installation:"
msgstr "Инсталација:"

#: app/flatpak-builtins-info.c:228 app/flatpak-builtins-info.c:271
#: app/flatpak-builtins-info.c:459 app/flatpak-builtins-info.c:517
#: app/flatpak-builtins-remote-info.c:249
#: app/flatpak-builtins-remote-info.c:284
msgid "Installed Size:"
msgstr "Величина инсталираног:"

#: app/flatpak-builtins-info.c:231 app/flatpak-builtins-info.c:279
#: app/flatpak-builtins-remote-info.c:252
#: app/flatpak-builtins-remote-info.c:288
msgid "Runtime:"
msgstr "Извршно окружење:"

#: app/flatpak-builtins-info.c:232 app/flatpak-builtins-info.c:288
#: app/flatpak-builtins-remote-info.c:253
#: app/flatpak-builtins-remote-info.c:293
msgid "Sdk:"
msgstr "СДК:"

#: app/flatpak-builtins-info.c:235 app/flatpak-builtins-info.c:313
#: app/flatpak-builtins-remote-info.c:256
#: app/flatpak-builtins-remote-info.c:319
msgid "Date:"
msgstr "Датум:"

#: app/flatpak-builtins-info.c:237 app/flatpak-builtins-info.c:311
#: app/flatpak-builtins-remote-info.c:258
#: app/flatpak-builtins-remote-info.c:317
msgid "Subject:"
msgstr "Тема:"

#: app/flatpak-builtins-info.c:240 app/flatpak-builtins-info.c:295
msgid "Active commit:"
msgstr "Активна предаја:"

#: app/flatpak-builtins-info.c:241 app/flatpak-builtins-info.c:298
msgid "Latest commit:"
msgstr "Најновија предаја:"

#: app/flatpak-builtins-info.c:244 app/flatpak-builtins-info.c:303
#: app/flatpak-builtins-info.c:457 app/flatpak-builtins-info.c:515
#: app/flatpak-builtins-remote-info.c:259
#: app/flatpak-builtins-remote-info.c:298
msgid "Commit:"
msgstr "Предаја:"

#: app/flatpak-builtins-info.c:246 app/flatpak-builtins-info.c:308
#: app/flatpak-builtins-remote-info.c:261
#: app/flatpak-builtins-remote-info.c:303
msgid "Parent:"
msgstr "Родитељ:"

#: app/flatpak-builtins-info.c:248 app/flatpak-builtins-info.c:321
msgid "Alt-id:"
msgstr "Алт-ид:"

#: app/flatpak-builtins-info.c:250 app/flatpak-builtins-info.c:325
#: app/flatpak-builtins-remote-info.c:263
#: app/flatpak-builtins-remote-info.c:308
msgid "End-of-life:"
msgstr "Крај животног века:"

#: app/flatpak-builtins-info.c:252 app/flatpak-builtins-info.c:330
#: app/flatpak-builtins-remote-info.c:265
#: app/flatpak-builtins-remote-info.c:313
msgid "End-of-life-rebase:"
msgstr "Поновно заснивање за крај животног века:"

#: app/flatpak-builtins-info.c:254 app/flatpak-builtins-info.c:317
msgid "Subdirectories:"
msgstr "Поддиректоријуми:"

#: app/flatpak-builtins-info.c:255 app/flatpak-builtins-info.c:454
#: app/flatpak-builtins-info.c:512
msgid "Extension:"
msgstr "Проширење:"

#: app/flatpak-builtins-info.c:267 app/flatpak-builtins-info.c:456
#: app/flatpak-builtins-info.c:514
msgid "Origin:"
msgstr "Порекло:"

#: app/flatpak-builtins-info.c:460 app/flatpak-builtins-info.c:522
msgid "Subpaths:"
msgstr "Подпутање:"

#: app/flatpak-builtins-info.c:478
msgid "unmaintained"
msgstr "неодржавано"

#: app/flatpak-builtins-info.c:480 app/flatpak-builtins-info.c:482
msgid "unknown"
msgstr "непознато"

#: app/flatpak-builtins-install.c:68 app/flatpak-builtins-preinstall.c:57
msgid "Don't pull, only install from local cache"
msgstr "Не повлачи, само инсталирај из локалне оставе"

#: app/flatpak-builtins-install.c:69 app/flatpak-builtins-preinstall.c:58
#: app/flatpak-builtins-update.c:60
msgid "Don't deploy, only download to local cache"
msgstr "Не пуштај, само преузми у локалну оставу"

#: app/flatpak-builtins-install.c:70 app/flatpak-builtins-preinstall.c:59
msgid "Don't install related refs"
msgstr "Не инсталирај повезане референце"

#: app/flatpak-builtins-install.c:71 app/flatpak-builtins-preinstall.c:60
#: app/flatpak-builtins-update.c:62
msgid "Don't verify/install runtime dependencies"
msgstr "Не проверавај/инсталирај зависности извршног окружења"

#: app/flatpak-builtins-install.c:72
msgid "Don't automatically pin explicit installs"
msgstr "Не прибадај аутоматски изричите инсталације"

#: app/flatpak-builtins-install.c:73 app/flatpak-builtins-preinstall.c:61
#: app/flatpak-builtins-update.c:63
msgid "Don't use static deltas"
msgstr "Не користи статичке делте"

#: app/flatpak-builtins-install.c:76 app/flatpak-builtins-preinstall.c:62
msgid "Additionally install the SDK used to build the given refs"
msgstr "Додатно инсталирај СДК коришћен за изградњу датих референци"

#: app/flatpak-builtins-install.c:77 app/flatpak-builtins-preinstall.c:63
msgid ""
"Additionally install the debug info for the given refs and their dependencies"
msgstr ""
"Додатно инсталирај податке за прочишћавање за дате референце и њихове "
"зависности"

#: app/flatpak-builtins-install.c:78
msgid "Assume LOCATION is a .flatpak single-file bundle"
msgstr "Претпостави да је МЕСТО .flatpak комплет у једној датотеци"

#: app/flatpak-builtins-install.c:79
msgid "Assume LOCATION is a .flatpakref application description"
msgstr "Претпостави да је МЕСТО .flatpakref опис програма"

#: app/flatpak-builtins-install.c:80
msgid "Assume LOCATION is containers-transports(5) reference to an OCI image"
msgstr ""
"Претпостави да је МЕСТО containers-transports(5) референца на OCI одраз"

#: app/flatpak-builtins-install.c:81
msgid "Check bundle signatures with GPG key from FILE (- for stdin)"
msgstr "Провери потписе комплета ГПГ кључем из ДАТОТЕКЕ (- за стандардни улаз)"

#: app/flatpak-builtins-install.c:82
msgid "Only install this subpath"
msgstr "Инсталирај само ову подпутању"

#: app/flatpak-builtins-install.c:83 app/flatpak-builtins-preinstall.c:64
#: app/flatpak-builtins-uninstall.c:63 app/flatpak-builtins-update.c:68
msgid "Automatically answer yes for all questions"
msgstr "Аутоматски одговори потврдно на сва питања"

#: app/flatpak-builtins-install.c:84 app/flatpak-builtins-preinstall.c:65
msgid "Uninstall first if already installed"
msgstr "Прво уклони ако је већ инсталирано"

#: app/flatpak-builtins-install.c:85 app/flatpak-builtins-preinstall.c:66
#: app/flatpak-builtins-uninstall.c:64 app/flatpak-builtins-update.c:69
msgid "Produce minimal output and don't ask questions"
msgstr "Произведи минималан излаз и не постављај питања"

#: app/flatpak-builtins-install.c:86
msgid "Update install if already installed"
msgstr "Ажурирај инсталацију ако је већ инсталирано"

#. Translators: A sideload is when you install from a local USB drive rather than the Internet.
#: app/flatpak-builtins-install.c:88 app/flatpak-builtins-preinstall.c:68
#: app/flatpak-builtins-update.c:71
msgid "Use this local repo for sideloads"
msgstr "Користи ову локалну ризницу за спољно учитавање"

#: app/flatpak-builtins-install.c:178
msgid "Bundle filename must be specified"
msgstr "Назив датотеке комплета мора бити наведен"

#: app/flatpak-builtins-install.c:188
msgid "Remote bundles are not supported"
msgstr "Удаљени пакети нису подржани"

#: app/flatpak-builtins-install.c:231
msgid "Filename or uri must be specified"
msgstr "Морате навести назив датотеке или адресу"

#: app/flatpak-builtins-install.c:295
msgid "Image location must be specified"
msgstr "Морате навести место слике"

#: app/flatpak-builtins-install.c:345
msgid "[LOCATION/REMOTE] [REF…] - Install applications or runtimes"
msgstr "[МЕСТО/УДАЉЕНО] [УПУТ…] - Инсталирајте програме или извршна окружења"

#: app/flatpak-builtins-install.c:378
msgid "At least one REF must be specified"
msgstr "Морате навести барем један УПУТ"

#: app/flatpak-builtins-install.c:392
#, c-format
msgid "Looking for matches…\n"
msgstr "Тражим поклапања…\n"

#: app/flatpak-builtins-install.c:513
#, c-format
msgid "No remote refs found for ‘%s’"
msgstr "Нису пронађени удаљени упути за „%s“"

#: app/flatpak-builtins-install.c:573 app/flatpak-builtins-uninstall.c:405
#: common/flatpak-ref-utils.c:689 common/flatpak-ref-utils.c:1595
#, c-format
msgid "Invalid branch %s: %s"
msgstr "Неисправна грана %s: %s"

#: app/flatpak-builtins-install.c:606
#, c-format
msgid "Nothing matches %s in local repository for remote %s"
msgstr "Ништа се не поклапа са %s у локалној ризници за удаљени %s"

#: app/flatpak-builtins-install.c:608
#, c-format
msgid "Nothing matches %s in remote %s"
msgstr "Ништа се не поклапа са %s у удаљеном %s"

#: app/flatpak-builtins-install.c:629
#, c-format
msgid "Skipping: %s\n"
msgstr "Прескачем: %s\n"

#: app/flatpak-builtins-kill.c:110
#, c-format
msgid "%s is not running"
msgstr "%s није покренут"

#: app/flatpak-builtins-kill.c:136
msgid "INSTANCE - Stop a running application"
msgstr "ПРИМЕРАК - Зауставите покренути програм"

#: app/flatpak-builtins-kill.c:144 app/flatpak-builtins-ps.c:256
msgid "Extra arguments given"
msgstr "Дати су додатни аргументи"

#: app/flatpak-builtins-kill.c:150
msgid "Must specify the app to kill"
msgstr "Морате навести програм који желите да убијете"

#: app/flatpak-builtins-list.c:47
msgid "Show extra information"
msgstr "Прикажи додатне податке"

#: app/flatpak-builtins-list.c:48
msgid "List installed runtimes"
msgstr "Испиши инсталирана извршна окружења"

#: app/flatpak-builtins-list.c:49
msgid "List installed applications"
msgstr "Испиши инсталиране програме"

#: app/flatpak-builtins-list.c:50
msgid "Arch to show"
msgstr "Архитектура за приказ"

#: app/flatpak-builtins-list.c:51 app/flatpak-builtins-remote-ls.c:57
msgid "List all refs (including locale/debug)"
msgstr "Испиши све упуте (укључујући језик/исправљање грешака)"

#: app/flatpak-builtins-list.c:53 app/flatpak-builtins-remote-ls.c:58
msgid "List all applications using RUNTIME"
msgstr "Испиши све програме који користе ИЗВРШНО ОКРУЖЕЊЕ"

#: app/flatpak-builtins-list.c:59 app/flatpak-builtins-remote-list.c:51
#: app/flatpak-builtins-remote-ls.c:68 app/flatpak-builtins-search.c:44
msgid "Name"
msgstr "Назив"

#: app/flatpak-builtins-list.c:59 app/flatpak-builtins-remote-list.c:51
#: app/flatpak-builtins-remote-ls.c:68 app/flatpak-builtins-search.c:44
msgid "Show the name"
msgstr "Прикажи назив"

#: app/flatpak-builtins-list.c:60 app/flatpak-builtins-remote-list.c:60
#: app/flatpak-builtins-remote-ls.c:69 app/flatpak-builtins-search.c:45
msgid "Description"
msgstr "Опис"

#: app/flatpak-builtins-list.c:60 app/flatpak-builtins-remote-ls.c:69
#: app/flatpak-builtins-search.c:45
msgid "Show the description"
msgstr "Прикажи опис"

#: app/flatpak-builtins-list.c:61 app/flatpak-builtins-remote-ls.c:70
#: app/flatpak-builtins-search.c:46
msgid "Application ID"
msgstr "ИД програма"

#: app/flatpak-builtins-list.c:61 app/flatpak-builtins-ps.c:52
#: app/flatpak-builtins-remote-ls.c:70 app/flatpak-builtins-search.c:46
msgid "Show the application ID"
msgstr "Прикажи ИД програма"

#: app/flatpak-builtins-list.c:62 app/flatpak-builtins-remote-ls.c:71
#: app/flatpak-builtins-search.c:47
msgid "Show the version"
msgstr "Прикажи издање"

#: app/flatpak-builtins-list.c:65 app/flatpak-builtins-ps.c:56
#: app/flatpak-builtins-remote-ls.c:77
msgid "Runtime"
msgstr "Извршно окружење"

#: app/flatpak-builtins-list.c:65
msgid "Show the used runtime"
msgstr "Прикажи коришћено извршно окружење"

#: app/flatpak-builtins-list.c:66 app/flatpak-builtins-remote-ls.c:74
msgid "Show the origin remote"
msgstr "Прикажи изворни удаљени сервер"

#: app/flatpak-builtins-list.c:67
msgid "Show the installation"
msgstr "Прикажи инсталацију"

#: app/flatpak-builtins-list.c:69
msgid "Active commit"
msgstr "Активна предаја"

#: app/flatpak-builtins-list.c:69 app/flatpak-builtins-remote-ls.c:76
msgid "Show the active commit"
msgstr "Прикажи активну предају"

#: app/flatpak-builtins-list.c:70
msgid "Latest commit"
msgstr "Последња предаја"

#: app/flatpak-builtins-list.c:70
msgid "Show the latest commit"
msgstr "Прикажи последњу предају"

#: app/flatpak-builtins-list.c:71 app/flatpak-builtins-remote-ls.c:78
msgid "Installed size"
msgstr "Величина инсталираног"

#: app/flatpak-builtins-list.c:71 app/flatpak-builtins-remote-ls.c:78
msgid "Show the installed size"
msgstr "Прикажи величину инсталираног"

#: app/flatpak-builtins-list.c:72 app/flatpak-builtins-remote-list.c:58
#: app/flatpak-builtins-remote-ls.c:80 app/flatpak-builtins-repo.c:340
msgid "Options"
msgstr "Опције"

#: app/flatpak-builtins-list.c:72 app/flatpak-builtins-remote-list.c:58
#: app/flatpak-builtins-remote-ls.c:80
msgid "Show options"
msgstr "Прикажи опције"

#: app/flatpak-builtins-list.c:180
#, c-format
msgid "Unable to load details of %s: %s"
msgstr "Не могу да учитам детаље за %s: %s"

#: app/flatpak-builtins-list.c:190
#, c-format
msgid "Unable to inspect current version of %s: %s"
msgstr "Не могу да проверим тренутно издање од %s: %s"

#: app/flatpak-builtins-list.c:408
msgid " - List installed apps and/or runtimes"
msgstr " - Испиши инсталиране програме и/или извршна окружења"

#: app/flatpak-builtins-make-current.c:38
msgid "Arch to make current for"
msgstr "Архитектура која се поставља као тренутна за"

#: app/flatpak-builtins-make-current.c:58
msgid "APP BRANCH - Make branch of application current"
msgstr "ПРОГРАМ ГРАНА - Постави грану програма као тренутну"

#: app/flatpak-builtins-make-current.c:69 app/flatpak-builtins-run.c:260
msgid "APP must be specified"
msgstr "ПРОГРАМ мора бити наведен"

#: app/flatpak-builtins-make-current.c:84
msgid "BRANCH must be specified"
msgstr "ГРАНА мора бити наведена"

#: app/flatpak-builtins-make-current.c:97
#, c-format
msgid "App %s branch %s is not installed"
msgstr "Програм %s грана %s није инсталиран"

#: app/flatpak-builtins-mask.c:42
msgid "Remove matching masks"
msgstr "Уклони одговарајуће маске"

#: app/flatpak-builtins-mask.c:54
msgid ""
"[PATTERN…] - disable updates and automatic installation matching patterns"
msgstr ""
"[ОБРАЗАЦ…] - онемогући ажурирања и аутоматску инсталацију за одговарајуће "
"обрасце"

#: app/flatpak-builtins-mask.c:73
#, c-format
msgid "No masked patterns\n"
msgstr "Нема маскираних образаца\n"

#: app/flatpak-builtins-mask.c:78
#, c-format
msgid "Masked patterns:\n"
msgstr "Маскирани обрасци:\n"

#: app/flatpak-builtins-override.c:42
msgid "Remove existing overrides"
msgstr "Уклони постојећа преписивања"

#: app/flatpak-builtins-override.c:43
msgid "Show existing overrides"
msgstr "Прикажи постојећа преписивања"

#: app/flatpak-builtins-override.c:59
msgid "[APP] - Override settings [for application]"
msgstr "[ПРОГРАМ] - Препиши подешавања [за програм]"

#: app/flatpak-builtins-permission-list.c:143
msgid "[TABLE] [ID] - List permissions"
msgstr "[ТАБЕЛА] [ИБ] - Испиши овлашћења"

#: app/flatpak-builtins-permission-list.c:179
#: app/flatpak-builtins-permission-show.c:142
msgid "Table"
msgstr "Табела"

#: app/flatpak-builtins-permission-list.c:180
#: app/flatpak-builtins-permission-show.c:143
msgid "Object"
msgstr "Објекат"

#: app/flatpak-builtins-permission-list.c:181
#: app/flatpak-builtins-permission-show.c:144
msgid "App"
msgstr "Програм"

#: app/flatpak-builtins-permission-list.c:183
#: app/flatpak-builtins-permission-show.c:146
msgid "Data"
msgstr "Подаци"

#: app/flatpak-builtins-permission-remove.c:120
msgid "TABLE ID [APP_ID] - Remove item from permission store"
msgstr "ТАБЕЛА ИД [ИД_ПРОГРАМА] - Уклоните ставку из складишта овлашћења"

#: app/flatpak-builtins-permission-remove.c:129
#: app/flatpak-builtins-permission-set.c:120
msgid "Too few arguments"
msgstr "Премало аргумената"

#: app/flatpak-builtins-permission-reset.c:43
msgid "Reset all permissions"
msgstr "Поништи сва овлашћења"

#: app/flatpak-builtins-permission-reset.c:144
msgid "APP_ID - Reset permissions for an app"
msgstr "ИД_ПРОГРАМА - Поништи овлашћења за програм"

#: app/flatpak-builtins-permission-reset.c:153
#: app/flatpak-builtins-permission-show.c:124
msgid "Wrong number of arguments"
msgstr "Погрешан број аргумената"

#: app/flatpak-builtins-permission-set.c:42
msgid "Associate DATA with the entry"
msgstr "Придружи ПОДАТКЕ са уносом"

#: app/flatpak-builtins-permission-set.c:42
msgid "DATA"
msgstr "ПОДАЦИ"

#: app/flatpak-builtins-permission-set.c:111
msgid "TABLE ID APP_ID [PERMISSION...] - Set permissions"
msgstr "ТАБЕЛА ИД ИД_ПРОГРАМА [ОВЛАШЋЕЊЕ...] - Постави овлашћења"

#: app/flatpak-builtins-permission-set.c:132
#, c-format
msgid "Failed to parse '%s' as GVariant: "
msgstr "Нисам успео да обрадим „%s“ као Г-варијант: "

#: app/flatpak-builtins-permission-show.c:115
msgid "APP_ID - Show permissions for an app"
msgstr "ИД_ПРОГРАМА - Прикажи овлашћења за програм"

#: app/flatpak-builtins-pin.c:44
msgid "Remove matching pins"
msgstr "Уклони подударне прикаче"

#: app/flatpak-builtins-pin.c:56
msgid "[PATTERN…] - disable automatic removal of runtimes matching patterns"
msgstr ""
"[ОБРАЗАЦ…] - онемогући аутоматско уклањање извршних окружења која се "
"подударају са обрасцима"

#: app/flatpak-builtins-pin.c:75
#, c-format
msgid "No pinned patterns\n"
msgstr "Нема прикачених образаца\n"

#: app/flatpak-builtins-pin.c:80
#, c-format
msgid "Pinned patterns:\n"
msgstr "Прикачени обрасци:\n"

#: app/flatpak-builtins-preinstall.c:80
msgid "- Install flatpaks that are part of the operating system"
msgstr "- Инсталирај флатпаке који су део оперативног система"

#: app/flatpak-builtins-preinstall.c:118
#, c-format
msgid "Nothing to do.\n"
msgstr "Ништа за урадити.\n"

#: app/flatpak-builtins-ps.c:49
msgid "Instance"
msgstr "Примерак"

#: app/flatpak-builtins-ps.c:49
msgid "Show the instance ID"
msgstr "Прикажи ИД примерка"

#: app/flatpak-builtins-ps.c:50 app/flatpak-builtins-run.c:178
msgid "PID"
msgstr "ПИД"

#: app/flatpak-builtins-ps.c:50
msgid "Show the PID of the wrapper process"
msgstr "Прикажи ПИД процеса омотача"

#: app/flatpak-builtins-ps.c:51
msgid "Child-PID"
msgstr "Дете-ПИД"

#: app/flatpak-builtins-ps.c:51
msgid "Show the PID of the sandbox process"
msgstr "Прикажи ПИД процеса изолације"

#: app/flatpak-builtins-ps.c:54 app/flatpak-builtins-search.c:48
msgid "Show the application branch"
msgstr "Прикажи грану програма"

#: app/flatpak-builtins-ps.c:55
msgid "Show the application commit"
msgstr "Прикажи предају програма"

#: app/flatpak-builtins-ps.c:56
msgid "Show the runtime ID"
msgstr "Прикажи ИБ извршног окружења"

#: app/flatpak-builtins-ps.c:57
msgid "R.-Branch"
msgstr "И.-Грана"

#: app/flatpak-builtins-ps.c:57
msgid "Show the runtime branch"
msgstr "Прикажи грану извршног окружења"

#: app/flatpak-builtins-ps.c:58
msgid "R.-Commit"
msgstr "И.-Предаја"

#: app/flatpak-builtins-ps.c:58
msgid "Show the runtime commit"
msgstr "Прикажи предају извршног окружења"

#: app/flatpak-builtins-ps.c:59
msgid "Active"
msgstr "Активно"

#: app/flatpak-builtins-ps.c:59
msgid "Show whether the app is active"
msgstr "Прикажи да ли је програм активан"

#: app/flatpak-builtins-ps.c:60
msgid "Background"
msgstr "Позадина"

#: app/flatpak-builtins-ps.c:60
msgid "Show whether the app is background"
msgstr "Прикажи да ли је програм у позадини"

#: app/flatpak-builtins-ps.c:246
msgid " - Enumerate running sandboxes"
msgstr " - Наброј покренуте изолације"

#: app/flatpak-builtins-remote-add.c:66
msgid "Do nothing if the provided remote exists"
msgstr "Не ради ништа ако наведени удаљени извор већ постоји"

#: app/flatpak-builtins-remote-add.c:67
msgid "LOCATION specifies a configuration file, not the repo location"
msgstr "МЕСТО наводи датотеку подешавања, а не место ризнице"

#: app/flatpak-builtins-remote-add.c:72 app/flatpak-builtins-remote-modify.c:78
msgid "Disable GPG verification"
msgstr "Онемогући ГПГ проверу"

#: app/flatpak-builtins-remote-add.c:73 app/flatpak-builtins-remote-modify.c:79
msgid "Mark the remote as don't enumerate"
msgstr "Означи удаљени извор да се не набраја"

#: app/flatpak-builtins-remote-add.c:74 app/flatpak-builtins-remote-modify.c:80
msgid "Mark the remote as don't use for deps"
msgstr "Означи удаљени извор да се не користи за зависности"

#: app/flatpak-builtins-remote-add.c:75 app/flatpak-builtins-remote-modify.c:81
msgid "Set priority (default 1, higher is more prioritized)"
msgstr "Постави приоритет (подразумевано 1, већи има већу предност)"

#: app/flatpak-builtins-remote-add.c:75 app/flatpak-builtins-remote-modify.c:81
msgid "PRIORITY"
msgstr "Важност"

#: app/flatpak-builtins-remote-add.c:76
msgid "The named subset to use for this remote"
msgstr "Именовани подскуп за коришћење за ову удаљену везу"

#: app/flatpak-builtins-remote-add.c:76 app/flatpak-builtins-remote-modify.c:71
msgid "SUBSET"
msgstr "ПОДСКУП"

#: app/flatpak-builtins-remote-add.c:77 app/flatpak-builtins-remote-modify.c:82
msgid "A nice name to use for this remote"
msgstr "Лепо име за коришћење за ову удаљену везу"

#: app/flatpak-builtins-remote-add.c:78 app/flatpak-builtins-remote-modify.c:83
msgid "A one-line comment for this remote"
msgstr "Коментар у једном реду за ову удаљену везу"

#: app/flatpak-builtins-remote-add.c:79 app/flatpak-builtins-remote-modify.c:84
msgid "A full-paragraph description for this remote"
msgstr "Опис у пуном пасусу за ову удаљену везу"

#: app/flatpak-builtins-remote-add.c:80 app/flatpak-builtins-remote-modify.c:85
msgid "URL for a website for this remote"
msgstr "Адреса веб странице за ову удаљену везу"

#: app/flatpak-builtins-remote-add.c:81 app/flatpak-builtins-remote-modify.c:86
msgid "URL for an icon for this remote"
msgstr "Адреса иконице за ову удаљену везу"

#: app/flatpak-builtins-remote-add.c:82 app/flatpak-builtins-remote-modify.c:87
msgid "Default branch to use for this remote"
msgstr "Подразумевана грана за коришћење за ову удаљену везу"

#: app/flatpak-builtins-remote-add.c:84 app/flatpak-builtins-remote-modify.c:89
msgid "Import GPG key from FILE (- for stdin)"
msgstr "Увези ГПГ кључ из ДАТОТЕКЕ (- за стдин)"

#: app/flatpak-builtins-remote-add.c:85 app/flatpak-builtins-remote-modify.c:90
msgid "Load signatures from URL"
msgstr "Учитај потписе са АДРЕСЕ"

#: app/flatpak-builtins-remote-add.c:86 app/flatpak-builtins-remote-modify.c:92
msgid "Set path to local filter FILE"
msgstr "Постави путању до локалне ДАТОТЕКЕ филтера"

#: app/flatpak-builtins-remote-add.c:87 app/flatpak-builtins-remote-modify.c:93
msgid "Disable the remote"
msgstr "Онемогући удаљену везу"

#: app/flatpak-builtins-remote-add.c:88 app/flatpak-builtins-remote-modify.c:94
msgid "Name of authenticator"
msgstr "Име потврђивача"

#: app/flatpak-builtins-remote-add.c:90 app/flatpak-builtins-remote-modify.c:96
msgid "Autoinstall authenticator"
msgstr "Самостално инсталирај потврђивач"

#: app/flatpak-builtins-remote-add.c:91 app/flatpak-builtins-remote-modify.c:97
msgid "Don't autoinstall authenticator"
msgstr "Немој самостално инсталирати потврђивач"

#: app/flatpak-builtins-remote-add.c:92 app/flatpak-builtins-remote-modify.c:99
msgid "Don't follow the redirect set in the summary file"
msgstr "Немој пратити преусмеравање постављено у датотеци сажетка"

#: app/flatpak-builtins-remote-add.c:261 app/flatpak-builtins-remote-add.c:268
#, c-format
msgid "Can't load uri %s: %s\n"
msgstr "Не могу да учитам адресу %s: %s\n"

#: app/flatpak-builtins-remote-add.c:276 common/flatpak-dir.c:4643
#, c-format
msgid "Can't load file %s: %s\n"
msgstr "Не могу да учитам датотеку %s: %s\n"

#: app/flatpak-builtins-remote-add.c:304
msgid "NAME LOCATION - Add a remote repository"
msgstr "ИМЕ МЕСТО - Додај удаљену ризницу"

#: app/flatpak-builtins-remote-add.c:331
msgid "GPG verification is required if collections are enabled"
msgstr "ГПГ потврда је потребна ако су омогућене збирке"

#: app/flatpak-builtins-remote-add.c:393
#, c-format
msgid "Remote %s already exists"
msgstr "Удаљена ризница „%s“ већ постоји"

#: app/flatpak-builtins-remote-add.c:405
#: app/flatpak-builtins-remote-modify.c:340
#, c-format
msgid "Invalid authenticator name %s"
msgstr "Неисправно име потврђивача „%s“"

#: app/flatpak-builtins-remote-add.c:422
#, c-format
msgid "Warning: Could not update extra metadata for '%s': %s\n"
msgstr "Упозорење: Не могу да ажурирам додатне метаподатке за „%s“: %s\n"

#: app/flatpak-builtins-remote-delete.c:39
msgid "Remove remote even if in use"
msgstr "Уклони удаљену ризницу чак и ако је у употреби"

#: app/flatpak-builtins-remote-delete.c:53
msgid "NAME - Delete a remote repository"
msgstr "ИМЕ - Брише удаљену ризницу"

#: app/flatpak-builtins-remote-delete.c:100
#, c-format
msgid "The following refs are installed from remote '%s':"
msgstr "Следеће референце су инсталиране са удаљене ризнице „%s“:"

#: app/flatpak-builtins-remote-delete.c:101
msgid "Remove them?"
msgstr "Да их уклоним?"

#: app/flatpak-builtins-remote-delete.c:103
#, c-format
msgid "Can't remove remote '%s' with installed refs"
msgstr "Не могу да уклоним удаљену ризницу „%s“ са инсталираним референцама"

#: app/flatpak-builtins-remote-info.c:55
msgid "Commit to show info for"
msgstr "Комит за који се приказују подаци"

#: app/flatpak-builtins-remote-info.c:58
msgid "Display log"
msgstr "Прикажи дневник"

#: app/flatpak-builtins-remote-info.c:61
msgid "Show parent"
msgstr "Прикажи родитеља"

#: app/flatpak-builtins-remote-info.c:65 app/flatpak-builtins-remote-ls.c:60
msgid "Use local caches even if they are stale"
msgstr "Користи локалне оставе чак и ако су застареле"

#. Translators: A sideload is when you install from a local USB drive rather than the Internet.
#: app/flatpak-builtins-remote-info.c:67 app/flatpak-builtins-remote-ls.c:62
msgid "Only list refs available as sideloads"
msgstr "Излистај само референце доступне за спољно инсталирање"

#: app/flatpak-builtins-remote-info.c:114
msgid ""
" REMOTE REF - Show information about an application or runtime in a remote"
msgstr ""
" УДАЉЕНА_РИЗНИЦА РЕФЕРЕНЦА - Приказује податке о програму или извршном "
"окружењу у удаљеној ризници"

#: app/flatpak-builtins-remote-info.c:125
msgid "REMOTE and REF must be specified"
msgstr "УДАЉЕНА_РИЗНИЦА и РЕФЕРЕНЦА морају бити наведени"

#: app/flatpak-builtins-remote-info.c:247
#: app/flatpak-builtins-remote-info.c:282
msgid "Download Size:"
msgstr "Величина преузимања:"

#: app/flatpak-builtins-remote-info.c:267
#: app/flatpak-builtins-remote-info.c:325
msgid "History:"
msgstr "Историјат:"

#: app/flatpak-builtins-remote-info.c:348
msgid " Commit:"
msgstr " Комит:"

#: app/flatpak-builtins-remote-info.c:349
msgid " Subject:"
msgstr " Тема:"

#: app/flatpak-builtins-remote-info.c:350
msgid " Date:"
msgstr " Датум:"

#: app/flatpak-builtins-remote-info.c:383
#, c-format
msgid "Warning: Commit %s has no flatpak metadata\n"
msgstr "Упозорење: Предаја %s нема флетпек метаподатке\n"

#: app/flatpak-builtins-remote-list.c:43
msgid "Show remote details"
msgstr "Прикажи детаље удаљене ризнице"

#: app/flatpak-builtins-remote-list.c:44
msgid "Show disabled remotes"
msgstr "Прикажи онемогућене удаљене ризнице"

#: app/flatpak-builtins-remote-list.c:52
msgid "Title"
msgstr "Наслов"

#: app/flatpak-builtins-remote-list.c:52
msgid "Show the title"
msgstr "Прикажи наслов"

#: app/flatpak-builtins-remote-list.c:53
msgid "Show the URL"
msgstr "Прикажи адресу"

#: app/flatpak-builtins-remote-list.c:54
msgid "Show the collection ID"
msgstr "Прикажи ИБ збирке"

#: app/flatpak-builtins-remote-list.c:55 app/flatpak-builtins-repo.c:392
msgid "Subset"
msgstr "Подскуп"

#: app/flatpak-builtins-remote-list.c:55
msgid "Show the subset"
msgstr "Прикажи подскуп"

#: app/flatpak-builtins-remote-list.c:56
msgid "Filter"
msgstr "Филтер"

#: app/flatpak-builtins-remote-list.c:56
msgid "Show filter file"
msgstr "Прикажи датотеку филтера"

#: app/flatpak-builtins-remote-list.c:57
msgid "Priority"
msgstr "Важност"

#: app/flatpak-builtins-remote-list.c:57
msgid "Show the priority"
msgstr "Прикажи важност"

#: app/flatpak-builtins-remote-list.c:59
msgid "Comment"
msgstr "Напомена"

#: app/flatpak-builtins-remote-list.c:59
msgid "Show comment"
msgstr "Прикажи напомену"

#: app/flatpak-builtins-remote-list.c:60
msgid "Show description"
msgstr "Прикажи опис"

#: app/flatpak-builtins-remote-list.c:61
msgid "Homepage"
msgstr "Почетна страница"

#: app/flatpak-builtins-remote-list.c:61
msgid "Show homepage"
msgstr "Прикажи почетну страницу"

#: app/flatpak-builtins-remote-list.c:62
msgid "Icon"
msgstr "Иконица"

#: app/flatpak-builtins-remote-list.c:62
msgid "Show icon"
msgstr "Прикажи иконицу"

#: app/flatpak-builtins-remote-list.c:231
msgid " - List remote repositories"
msgstr " - Списак удаљених ризница"

#: app/flatpak-builtins-remote-ls.c:52
msgid "Show arches and branches"
msgstr "Прикажи архитектуре и гране"

#: app/flatpak-builtins-remote-ls.c:53
msgid "Show only runtimes"
msgstr "Прикажи само извршна окружења"

#: app/flatpak-builtins-remote-ls.c:54
msgid "Show only apps"
msgstr "Прикажи само програме"

#: app/flatpak-builtins-remote-ls.c:55
msgid "Show only those where updates are available"
msgstr "Прикажи само оне за које су доступна ажурирања"

#: app/flatpak-builtins-remote-ls.c:56
msgid "Limit to this arch (* for all)"
msgstr "Ограничи на ову архитектуру (* за све)"

#: app/flatpak-builtins-remote-ls.c:77
msgid "Show the runtime"
msgstr "Прикажи извршно окружење"

#: app/flatpak-builtins-remote-ls.c:79
msgid "Download size"
msgstr "Величина преузимања"

#: app/flatpak-builtins-remote-ls.c:79
msgid "Show the download size"
msgstr "Прикажи величину преузимања"

#: app/flatpak-builtins-remote-ls.c:391
msgid " [REMOTE or URI] - Show available runtimes and applications"
msgstr " [УДАЉЕНО или УРИ] - Прикажи доступна извршна окружења и програме"

#: app/flatpak-builtins-remote-modify.c:67
msgid "Enable GPG verification"
msgstr "Омогући ГПГ проверу"

#: app/flatpak-builtins-remote-modify.c:68
msgid "Mark the remote as enumerate"
msgstr "Означи удаљено место за набрајање"

#: app/flatpak-builtins-remote-modify.c:69
msgid "Mark the remote as used for dependencies"
msgstr "Означи удаљено место као коришћено за зависности"

#: app/flatpak-builtins-remote-modify.c:70
msgid "Set a new URL"
msgstr "Постави нову адресу (URL)"

#: app/flatpak-builtins-remote-modify.c:71
msgid "Set a new subset to use"
msgstr "Постави нови подскуп за коришћење"

#: app/flatpak-builtins-remote-modify.c:72
msgid "Enable the remote"
msgstr "Омогући удаљено место"

#: app/flatpak-builtins-remote-modify.c:73
msgid "Update extra metadata from the summary file"
msgstr "Ажурирај додатне метаподатке из датотеке сажетка"

#: app/flatpak-builtins-remote-modify.c:91
msgid "Disable local filter"
msgstr "Онемогући локални филтер"

#: app/flatpak-builtins-remote-modify.c:95
msgid "Authenticator options"
msgstr "Опције потврђивача идентитета"

#: app/flatpak-builtins-remote-modify.c:98
msgid "Follow the redirect set in the summary file"
msgstr "Прати преусмеравање постављено в датотеци сажетка"

#: app/flatpak-builtins-remote-modify.c:306
msgid "NAME - Modify a remote repository"
msgstr "ИМЕ - Измени удаљену ризницу"

#: app/flatpak-builtins-remote-modify.c:316
msgid "Remote NAME must be specified"
msgstr "Мора се навести НАЗИВ удаљеног места"

#: app/flatpak-builtins-remote-modify.c:327
#, c-format
msgid "Updating extra metadata from remote summary for %s\n"
msgstr "Ажурирам додатне метаподатке из удаљеног сажетка за „%s“\n"

#: app/flatpak-builtins-remote-modify.c:330
#, c-format
msgid "Error updating extra metadata for '%s': %s\n"
msgstr "Грешка ажурирања додатних метаподатака за „%s“: %s\n"

#: app/flatpak-builtins-remote-modify.c:331
#, c-format
msgid "Could not update extra metadata for %s"
msgstr "Не могу да ажурирам додатне метаподатке за „%s“"

#: app/flatpak-builtins-repair.c:43
msgid "Don't make any changes"
msgstr "Не прави никакве измене"

#: app/flatpak-builtins-repair.c:44
msgid "Reinstall all refs"
msgstr "Поново инсталирај све референце"

#: app/flatpak-builtins-repair.c:68
#, c-format
msgid "Object missing: %s.%s\n"
msgstr "Недостаје објекат: %s.%s\n"

#: app/flatpak-builtins-repair.c:76
#, c-format
msgid "Object invalid: %s.%s\n"
msgstr "Неисправан објекат: %s.%s\n"

#: app/flatpak-builtins-repair.c:81
#, c-format
msgid "%s, deleting object\n"
msgstr "%s, бришем објекат\n"

#: app/flatpak-builtins-repair.c:146
#, c-format
msgid "Can't load object %s: %s\n"
msgstr "Не могу да учитам објекат %s: %s\n"

#: app/flatpak-builtins-repair.c:228
#, c-format
msgid "Commit invalid %s: %s\n"
msgstr "Неисправна предаја %s: %s\n"

#: app/flatpak-builtins-repair.c:231
#, c-format
msgid "Deleting invalid commit %s: %s\n"
msgstr "Бришем неисправну предају %s: %s\n"

#: app/flatpak-builtins-repair.c:261
#, c-format
msgid "Commit should be marked partial: %s\n"
msgstr "Предаја би требало да буде означена као делимична: %s\n"

#: app/flatpak-builtins-repair.c:264
#, c-format
msgid "Marking commit as partial: %s\n"
msgstr "Означавам предају као делимичну: %s\n"

#: app/flatpak-builtins-repair.c:293
#, c-format
msgid "Problems loading data for %s: %s\n"
msgstr "Проблеми при учитавању података за %s: %s\n"

#: app/flatpak-builtins-repair.c:306
#, c-format
msgid "Error reinstalling %s: %s\n"
msgstr "Грешка при поновној инсталацији %s: %s\n"

#: app/flatpak-builtins-repair.c:327
msgid "- Repair a flatpak installation"
msgstr "- Поправи флетпек инсталацију"

#: app/flatpak-builtins-repair.c:406
#, c-format
msgid "Removing non-deployed ref %s…\n"
msgstr "Уклањам непостављену референцу %s…\n"

#: app/flatpak-builtins-repair.c:411
#, c-format
msgid "Skipping non-deployed ref %s…\n"
msgstr "Прескачем непостављену референцу %s…\n"

#: app/flatpak-builtins-repair.c:429
#, c-format
msgid "[%d/%d] Verifying %s…\n"
msgstr "[%d/%d] Проверавам %s…\n"

#: app/flatpak-builtins-repair.c:435
#, c-format
msgid "Dry run: "
msgstr "Пробно покретање: "

#: app/flatpak-builtins-repair.c:440
#, c-format
msgid "Deleting ref %s due to missing objects\n"
msgstr "Бришем референцу %s због објеката који недостају\n"

#: app/flatpak-builtins-repair.c:444
#, c-format
msgid "Deleting ref %s due to invalid objects\n"
msgstr "Бришем референцу %s због неисправних објеката\n"

#: app/flatpak-builtins-repair.c:448
#, c-format
msgid "Deleting ref %s due to %d\n"
msgstr "Бришем референцу %s због %d\n"

#: app/flatpak-builtins-repair.c:464
#, c-format
msgid "Checking remotes...\n"
msgstr "Проверавам удаљена места...\n"

#: app/flatpak-builtins-repair.c:482
#, c-format
msgid "Remote %s for ref %s is missing\n"
msgstr "Недостаје удаљено место %s за референцу %s\n"

#: app/flatpak-builtins-repair.c:484
#, c-format
msgid "Remote %s for ref %s is disabled\n"
msgstr "Удаљено место %s за референцу %s је онемогућено\n"

#: app/flatpak-builtins-repair.c:490
#, c-format
msgid "Pruning objects\n"
msgstr "Чистим објекте\n"

#: app/flatpak-builtins-repair.c:498
#, c-format
msgid "Erasing .removed\n"
msgstr "Бришем .removed\n"

#: app/flatpak-builtins-repair.c:524
#, c-format
msgid "Reinstalling refs\n"
msgstr "Поново инсталирам референце\n"

#: app/flatpak-builtins-repair.c:526
#, c-format
msgid "Reinstalling removed refs\n"
msgstr "Поново инсталирам уклоњене референце\n"

#: app/flatpak-builtins-repair.c:551
#, c-format
msgid "While removing appstream for %s: "
msgstr "Приликом уклањања апстрима за %s: "

#: app/flatpak-builtins-repair.c:558
#, c-format
msgid "While deploying appstream for %s: "
msgstr "Приликом размештања апстрима за %s: "

#: app/flatpak-builtins-repo.c:106
#, c-format
msgid "Repo mode: %s\n"
msgstr "Режим ризнице: %s\n"

#: app/flatpak-builtins-repo.c:113
#, c-format
msgid "Indexed summaries: %s\n"
msgstr "Индексирани сажеци: %s\n"

#: app/flatpak-builtins-repo.c:113 app/flatpak-builtins-repo.c:139
#: app/flatpak-builtins-repo.c:172
msgid "true"
msgstr "тачно"

#: app/flatpak-builtins-repo.c:113 app/flatpak-builtins-repo.c:139
#: app/flatpak-builtins-repo.c:172
msgid "false"
msgstr "нетачно"

#: app/flatpak-builtins-repo.c:121
#, c-format
msgid "Subsummaries: "
msgstr "Подсажеци: "

#: app/flatpak-builtins-repo.c:136
#, c-format
msgid "Cache version: %d\n"
msgstr "Издање оставе: %d\n"

#: app/flatpak-builtins-repo.c:139
#, c-format
msgid "Indexed deltas: %s\n"
msgstr "Индексиране разлике: %s\n"

#: app/flatpak-builtins-repo.c:142
#, c-format
msgid "Title: %s\n"
msgstr "Наслов: %s\n"

#: app/flatpak-builtins-repo.c:145
#, c-format
msgid "Comment: %s\n"
msgstr "Напомена: %s\r\n"

#: app/flatpak-builtins-repo.c:148
#, c-format
msgid "Description: %s\n"
msgstr "Опис: %s\n"

#: app/flatpak-builtins-repo.c:151
#, c-format
msgid "Homepage: %s\n"
msgstr "Веб страница: %s\n"

#: app/flatpak-builtins-repo.c:154
#, c-format
msgid "Icon: %s\n"
msgstr "Иконица: %s\n"

#: app/flatpak-builtins-repo.c:157
#, c-format
msgid "Collection ID: %s\n"
msgstr "ИБ збирке: %s\n"

#: app/flatpak-builtins-repo.c:160
#, c-format
msgid "Default branch: %s\n"
msgstr "Подразумевана грана: %s\n"

#: app/flatpak-builtins-repo.c:163
#, c-format
msgid "Redirect URL: %s\n"
msgstr "Адреса преусмерења: %s\n"

#: app/flatpak-builtins-repo.c:166
#, c-format
msgid "Deploy collection ID: %s\n"
msgstr "ИБ збирке за пуштање: %s\n"

#: app/flatpak-builtins-repo.c:169
#, c-format
msgid "Authenticator name: %s\n"
msgstr "Назив потврђивача: %s\n"

#: app/flatpak-builtins-repo.c:172
#, c-format
msgid "Authenticator install: %s\n"
msgstr "Инсталација потврђивача: %s\n"

#: app/flatpak-builtins-repo.c:180
#, c-format
msgid "GPG key hash: %s\n"
msgstr "Хеш ГПГ кључа: %s\n"

#: app/flatpak-builtins-repo.c:184
#, c-format
msgid "%zd summary branches\n"
msgstr "%zd грана сажетка\n"

#: app/flatpak-builtins-repo.c:336
msgid "Installed"
msgstr "Инсталирано"

#. Translators: Download is used here as a noun
#: app/flatpak-builtins-repo.c:338 app/flatpak-cli-transaction.c:1462
msgid "Download"
msgstr "Преузимање"

#: app/flatpak-builtins-repo.c:339
msgid "Subsets"
msgstr "Подскупови"

#: app/flatpak-builtins-repo.c:393
msgid "Digest"
msgstr "Дигест"

#: app/flatpak-builtins-repo.c:394
msgid "History length"
msgstr "Дужина историјата"

#: app/flatpak-builtins-repo.c:711
msgid "Print general information about the repository"
msgstr "Испиши опште податке о ризници"

#: app/flatpak-builtins-repo.c:712
msgid "List the branches in the repository"
msgstr "Испиши гране у ризници"

#: app/flatpak-builtins-repo.c:713
msgid "Print metadata for a branch"
msgstr "Испиши метаподатке за грану"

#: app/flatpak-builtins-repo.c:714
msgid "Show commits for a branch"
msgstr "Прикажи предавања за грану"

#: app/flatpak-builtins-repo.c:715
msgid "Print information about the repo subsets"
msgstr "Испиши податке о подскуповима ризнице"

#: app/flatpak-builtins-repo.c:716
msgid "Limit information to subsets with this prefix"
msgstr "Ограничи податке на подскупове са овим префиксом"

#: app/flatpak-builtins-repo.c:732
msgid "LOCATION - Repository maintenance"
msgstr "МЕСТО - Одржавање ризнице"

#: app/flatpak-builtins-run.c:159
msgid "Command to run"
msgstr "Наредба за покретање"

#: app/flatpak-builtins-run.c:160
msgid "Directory to run the command in"
msgstr "Директоријум у коме се покреће наредба"

#: app/flatpak-builtins-run.c:161
msgid "Branch to use"
msgstr "Грана за коришћење"

#: app/flatpak-builtins-run.c:162
msgid "Use development runtime"
msgstr "Користи развојно извршно окружење"

#: app/flatpak-builtins-run.c:163
msgid "Runtime to use"
msgstr "Извршно окружење за коришћење"

#: app/flatpak-builtins-run.c:164
msgid "Runtime version to use"
msgstr "Издање извршног окружења за коришћење"

#: app/flatpak-builtins-run.c:167
msgid "Log accessibility bus calls"
msgstr "Бележи позиве сабирнице приступачности"

#: app/flatpak-builtins-run.c:168
msgid "Don't proxy accessibility bus calls"
msgstr "Не користи посредника за позиве сабирнице приступачности"

#: app/flatpak-builtins-run.c:169
msgid "Proxy accessibility bus calls (default except when sandboxed)"
msgstr ""
"Користи посредника за позиве сабирнице приступачности (подразумевано осим у "
"изолацији)"

#: app/flatpak-builtins-run.c:170
msgid "Don't proxy session bus calls"
msgstr "Не користи посредника за позиве сабирнице сесије"

#: app/flatpak-builtins-run.c:171
msgid "Proxy session bus calls (default except when sandboxed)"
msgstr ""
"Користи посредника за позиве сабирнице сесије (подразумевано осим у "
"изолацији)"

#: app/flatpak-builtins-run.c:172
msgid "Don't start portals"
msgstr "Не покрећи портале"

#: app/flatpak-builtins-run.c:173
msgid "Enable file forwarding"
msgstr "Омогући прослеђивање датотека"

#: app/flatpak-builtins-run.c:174
msgid "Run specified commit"
msgstr "Покрени наведену предају"

#: app/flatpak-builtins-run.c:175
msgid "Use specified runtime commit"
msgstr "Користи наведену предају извршног окружења"

#: app/flatpak-builtins-run.c:176
msgid "Run completely sandboxed"
msgstr "Покрени потпуно у изолацији"

#: app/flatpak-builtins-run.c:178
msgid "Use PID as parent pid for sharing namespaces"
msgstr "Користи ПИД као родитељски ПИД за дељење именских простора"

#: app/flatpak-builtins-run.c:179
msgid "Make processes visible in parent namespace"
msgstr "Учини процесе видљивим у родитељском именском простору"

#: app/flatpak-builtins-run.c:180
msgid "Share process ID namespace with parent"
msgstr "Дели именски простор ИБ-а процеса са родитељем"

#: app/flatpak-builtins-run.c:181
msgid "Write the instance ID to the given file descriptor"
msgstr "Упиши ИБ примерка у дати описник датотеке"

#: app/flatpak-builtins-run.c:182
msgid "Use PATH instead of the app's /app"
msgstr "Користи ПУТАЊУ уместо „/app“ програма"

#: app/flatpak-builtins-run.c:183
#, fuzzy
msgid "Use FD instead of the app's /app"
msgstr "Користи ПУТАЊУ уместо „/app“ програма"

#: app/flatpak-builtins-run.c:183 app/flatpak-builtins-run.c:185
#: app/flatpak-builtins-run.c:187 app/flatpak-builtins-run.c:188
#: common/flatpak-context.c:2672
msgid "FD"
msgstr "ОД"

#: app/flatpak-builtins-run.c:184
msgid "Use PATH instead of the runtime's /usr"
msgstr "Користи ПУТАЊУ уместо „/usr“ извршног окружења"

#: app/flatpak-builtins-run.c:185
#, fuzzy
msgid "Use FD instead of the runtime's /usr"
msgstr "Користи ПУТАЊУ уместо „/usr“ извршног окружења"

#: app/flatpak-builtins-run.c:186
msgid "Clear all outside environment variables"
msgstr "Очисти све спољне променљиве окружења"

#: app/flatpak-builtins-run.c:187
msgid ""
"Bind mount the file or directory referred to by FD to its canonicalized path"
msgstr ""

#: app/flatpak-builtins-run.c:188
msgid ""
"Bind mount the file or directory referred to by FD read-only to its "
"canonicalized path"
msgstr ""

#: app/flatpak-builtins-run.c:219
msgid "APP [ARGUMENT…] - Run an app"
msgstr "ПРОГРАМ [АРГУМЕНТ…] - Покрени програм"

#: app/flatpak-builtins-run.c:370
#, c-format
msgid "runtime/%s/%s/%s not installed"
msgstr "извршно окружење „%s/%s/%s“ није инсталирано"

#: app/flatpak-builtins-run.c:419
msgid "app-fd and app-path cannot both be used"
msgstr ""

#: app/flatpak-builtins-run.c:449
msgid "usr-fd and usr-path cannot both be used"
msgstr ""

#: app/flatpak-builtins-search.c:37
msgid "Arch to search for"
msgstr "Архитектура за претрагу"

#: app/flatpak-builtins-search.c:49
msgid "Remotes"
msgstr "Удаљена места"

#: app/flatpak-builtins-search.c:49
msgid "Show the remotes"
msgstr "Прикажи удаљена места"

#: app/flatpak-builtins-search.c:244
msgid "TEXT - Search remote apps/runtimes for text"
msgstr "ТЕКСТ - Претражи удаљене програме/извршна окружења за текстом"

#: app/flatpak-builtins-search.c:255
msgid "TEXT must be specified"
msgstr "ТЕКСТ мора бити наведен"

#: app/flatpak-builtins-search.c:338
msgid "No matches found"
msgstr "Нису пронађена поклапања"

#: app/flatpak-builtins-uninstall.c:54
msgid "Arch to uninstall"
msgstr "Архитектура за уклањање"

#: app/flatpak-builtins-uninstall.c:55
msgid "Keep ref in local repository"
msgstr "Задржи референцу у локалној ризници"

#: app/flatpak-builtins-uninstall.c:56
msgid "Don't uninstall related refs"
msgstr "Не уклањај повезане референце"

#: app/flatpak-builtins-uninstall.c:57
msgid "Remove files even if running"
msgstr "Уклони датотеке чак и ако су покренуте"

#: app/flatpak-builtins-uninstall.c:60
msgid "Uninstall all"
msgstr "Уклони све"

#: app/flatpak-builtins-uninstall.c:61
msgid "Uninstall unused"
msgstr "Уклони некоришћено"

#: app/flatpak-builtins-uninstall.c:62
msgid "Delete app data"
msgstr "Обриши податке програма"

#: app/flatpak-builtins-uninstall.c:141
#, c-format
msgid "Delete data for %s?"
msgstr "Обрисати податке за %s?"

#: app/flatpak-builtins-uninstall.c:220
#, c-format
msgid "Info: applications using the extension %s%s%s branch %s%s%s:\n"
msgstr "Инфо: програми који користе проширење %s%s%s грана %s%s%s:\n"

#: app/flatpak-builtins-uninstall.c:223
#, c-format
msgid "Info: applications using the runtime %s%s%s branch %s%s%s:\n"
msgstr "Инфо: програми који користе извршно окружење %s%s%s грана %s%s%s:\n"

#: app/flatpak-builtins-uninstall.c:238
msgid "Really remove?"
msgstr "Заиста уклонити?"

#: app/flatpak-builtins-uninstall.c:255
msgid "[REF…] - Uninstall applications or runtimes"
msgstr "[REF…] - Уклони програме или извршна окружења"

#: app/flatpak-builtins-uninstall.c:264
msgid "Must specify at least one REF, --unused, --all or --delete-data"
msgstr "Морате навести бар један REF, --unused, --all или --delete-data"

#: app/flatpak-builtins-uninstall.c:267
msgid "Must not specify REFs when using --all"
msgstr "Не смете наводити REF-ове када користите --all"

#: app/flatpak-builtins-uninstall.c:270
msgid "Must not specify REFs when using --unused"
msgstr "Не смете наводити REF-ове када користите --unused"

#: app/flatpak-builtins-uninstall.c:336
#, c-format
msgid ""
"\n"
"These runtimes in installation '%s' are pinned and won't be removed; see "
"flatpak-pin(1):\n"
msgstr ""
"\n"
"Ова извршна окружења у инсталацији „%s“ су закачена и неће бити уклоњена; "
"погледајте flatpak-pin(1):\n"

#: app/flatpak-builtins-uninstall.c:370
#, c-format
msgid "Nothing unused to uninstall\n"
msgstr "Нема некоришћених ствари за уклањање\n"

#: app/flatpak-builtins-uninstall.c:444
#, c-format
msgid "No installed refs found for ‘%s’"
msgstr "Нису пронађени инсталирани REF-ови за „%s“"

#: app/flatpak-builtins-uninstall.c:447
#, c-format
msgid " with arch ‘%s’"
msgstr " са архитектуром „%s“"

#: app/flatpak-builtins-uninstall.c:449
#, c-format
msgid " with branch ‘%s’"
msgstr " са граном „%s“"

#: app/flatpak-builtins-uninstall.c:456
#, c-format
msgid "Warning: %s is not installed\n"
msgstr "Упозорење: %s није инсталиран\n"

#: app/flatpak-builtins-uninstall.c:490
#, c-format
msgid "None of the specified refs are installed"
msgstr "Ниједан од наведених REF-ова није инсталиран"

#: app/flatpak-builtins-uninstall.c:599
#, c-format
msgid "No app data to delete\n"
msgstr "Нема података програма за брисање\n"

#: app/flatpak-builtins-update.c:56
msgid "Arch to update for"
msgstr "Архитектура за коју се ажурира"

#: app/flatpak-builtins-update.c:57
msgid "Commit to deploy"
msgstr "Уградња за пуштање"

#: app/flatpak-builtins-update.c:58
msgid "Remove old files even if running"
msgstr "Уклони старе датотеке чак и ако су покренуте"

#: app/flatpak-builtins-update.c:59
msgid "Don't pull, only update from local cache"
msgstr "Не повлачи, само ажурирај из локалне оставе"

#: app/flatpak-builtins-update.c:61
msgid "Don't update related refs"
msgstr "Немојте ажурирати повезане референце"

#: app/flatpak-builtins-update.c:66
msgid "Update appstream for remote"
msgstr "Ажурирајте апстрим за удаљено место"

#: app/flatpak-builtins-update.c:67
msgid "Only update this subpath"
msgstr "Ажурирајте само ову подпутању"

#: app/flatpak-builtins-update.c:90
msgid "[REF…] - Update applications or runtimes"
msgstr "[РЕФ…] - Ажурирајте програме или извршна окружења"

#: app/flatpak-builtins-update.c:121
msgid "With --commit, only one REF may be specified"
msgstr "Уз --commit, може се навести само једна РЕФ"

#: app/flatpak-builtins-update.c:162
#, c-format
msgid "Looking for updates…\n"
msgstr "Тражим ажурирања…\n"

#: app/flatpak-builtins-update.c:215
#, c-format
msgid "Unable to update %s: %s\n"
msgstr "Не могу да ажурирам %s: %s\n"

#: app/flatpak-builtins-update.c:274
#, c-format
msgid "Nothing to update.\n"
msgstr "Нема ништа за ажурирање.\n"

#: app/flatpak-builtins-utils.c:337
#, c-format
msgid ""
"Remote ‘%s’ found in multiple installations, unable to proceed in non-"
"interactive mode"
msgstr ""
"Удаљено место „%s“ је пронађено у више инсталација, не могу да наставим у "
"немеђудејственом режиму"

#: app/flatpak-builtins-utils.c:346
#, c-format
msgid "Remote ‘%s’ found in multiple installations:"
msgstr "Удаљено место „%s“ је пронађено у више инсталација:"

#: app/flatpak-builtins-utils.c:347 app/flatpak-builtins-utils.c:442
#: app/flatpak-builtins-utils.c:538 app/flatpak-builtins-utils.c:540
#: app/flatpak-builtins-utils.c:598
msgid "Which do you want to use (0 to abort)?"
msgstr "Који желите да користите (0 за прекид)?"

#: app/flatpak-builtins-utils.c:349
#, c-format
msgid "No remote chosen to resolve ‘%s’ which exists in multiple installations"
msgstr ""
"Није изабрано удаљено место за разрешавање „%s“ које постоји у више "
"инсталација"

#: app/flatpak-builtins-utils.c:358
#, c-format
msgid ""
"Remote \"%s\" not found\n"
"Hint: Use flatpak remote-add to add a remote"
msgstr ""
"Удаљено место „%s“ није пронађено\n"
"Савет: Користите „flatpak remote-add“ да додате удаљено место"

#: app/flatpak-builtins-utils.c:364
#, c-format
msgid "Remote \"%s\" not found in the %s installation"
msgstr "Удаљено место „%s“ није пронађено у инсталацији %s"

#: app/flatpak-builtins-utils.c:404
#, c-format
msgid "Multiple refs match ‘%s’, unable to proceed in non-interactive mode"
msgstr ""
"Више референци се поклапа са „%s“, не могу да наставим у немеђудејственом "
"режиму"

#. default to yes on Enter
#: app/flatpak-builtins-utils.c:430
#, c-format
msgid ""
"Found ref ‘%s’ in remote ‘%s’ (%s).\n"
"Use this ref?"
msgstr ""
"Пронађена је референца „%s“ на удаљеном месту „%s“ (%s).\n"
"Да ли да користим ову референцу?"

#: app/flatpak-builtins-utils.c:434 app/flatpak-builtins-utils.c:444
#: app/flatpak-builtins-utils.c:522 app/flatpak-builtins-utils.c:543
#, c-format
msgid "No ref chosen to resolve matches for ‘%s’"
msgstr "Није изабрана референца за разрешавање поклапања за „%s“"

#: app/flatpak-builtins-utils.c:440
#, c-format
msgid "Similar refs found for ‘%s’ in remote ‘%s’ (%s):"
msgstr "Сличне референце су пронађене за „%s“ на удаљеном месту „%s“ (%s):"

#: app/flatpak-builtins-utils.c:488
#, c-format
msgid ""
"Multiple installed refs match ‘%s’, unable to proceed in non-interactive mode"
msgstr ""
"Више инсталираних референци се поклапа са „%s“, не могу да наставим у "
"немеђудејственом режиму"

#. default to yes on Enter
#: app/flatpak-builtins-utils.c:518
#, c-format
msgid "Found installed ref ‘%s’ (%s). Is this correct?"
msgstr "Пронађена је инсталирана референца „%s“ (%s). Да ли је ово исправно?"

#: app/flatpak-builtins-utils.c:534
#, c-format
msgid "All of the above"
msgstr "Све изнад"

#: app/flatpak-builtins-utils.c:535
#, c-format
msgid "Similar installed refs found for ‘%s’:"
msgstr "Пронађене су сличне инсталиране референце за „%s“:"

#: app/flatpak-builtins-utils.c:579
#, c-format
msgid ""
"Multiple remotes have refs matching ‘%s’, unable to proceed in non-"
"interactive mode"
msgstr ""
"Више удаљених извора има референце које се подударају са „%s“, није могуће "
"наставити у неинтерактивном режиму"

#: app/flatpak-builtins-utils.c:597
#, c-format
msgid "Remotes found with refs similar to ‘%s’:"
msgstr "Пронађени су удаљени извори са референцама сличним „%s“:"

#: app/flatpak-builtins-utils.c:600
#, c-format
msgid "No remote chosen to resolve matches for ‘%s’"
msgstr "Није изабран удаљени извор за решавање поклапања за „%s“"

#: app/flatpak-builtins-utils.c:696 app/flatpak-builtins-utils.c:699
#, c-format
msgid "Updating appstream data for user remote %s"
msgstr "Ажурирам appstream податке за кориснички удаљени извор %s"

#: app/flatpak-builtins-utils.c:706 app/flatpak-builtins-utils.c:709
#, c-format
msgid "Updating appstream data for remote %s"
msgstr "Ажурирам appstream податке за удаљени извор %s"

#: app/flatpak-builtins-utils.c:717 app/flatpak-builtins-utils.c:719
msgid "Error updating"
msgstr "Грешка при ажурирању"

#: app/flatpak-builtins-utils.c:755
#, c-format
msgid "Remote \"%s\" not found"
msgstr "Удаљени извор „%s“ није пронађен"

#: app/flatpak-builtins-utils.c:796
#, c-format
msgid "Ambiguous suffix: '%s'."
msgstr "Нејасан суфикс: „%s“."

#. Translators: don't translate the values
#: app/flatpak-builtins-utils.c:798 app/flatpak-builtins-utils.c:813
msgid "Possible values are :s[tart], :m[iddle], :e[nd] or :f[ull]"
msgstr "Могуће вредности су :s[tart], :m[iddle], :e[nd] или :f[ull]"

#: app/flatpak-builtins-utils.c:811
#, c-format
msgid "Invalid suffix: '%s'."
msgstr "Неисправан суфикс: „%s“."

#: app/flatpak-builtins-utils.c:846
#, c-format
msgid "Ambiguous column: %s"
msgstr "Нејасна колона: %s"

#: app/flatpak-builtins-utils.c:859
#, c-format
msgid "Unknown column: %s"
msgstr "Непозната колона: %s"

#: app/flatpak-builtins-utils.c:917
msgid "Available columns:\n"
msgstr "Доступне колоне:\n"

#: app/flatpak-builtins-utils.c:927
msgid "Show all columns"
msgstr "Прикажи све колоне"

#: app/flatpak-builtins-utils.c:928
msgid "Show available columns"
msgstr "Прикажи доступне колоне"

#: app/flatpak-builtins-utils.c:931
msgid "Append :s[tart], :m[iddle], :e[nd] or :f[ull] to change ellipsization"
msgstr ""
"Додајте :s[tart], :m[iddle], :e[nd] или :f[ull] да бисте променили скраћивање"

#: app/flatpak-builtins-utils.c:1483
#, c-format
msgid "Unknown scheme in sideload location %s"
msgstr "Непозната шема на месту за бочно учитавање %s"

#: app/flatpak-cli-transaction.c:96 app/flatpak-cli-transaction.c:102
#, c-format
msgid "Required runtime for %s (%s) found in remote %s\n"
msgstr ""
"Потребно извршно окружење за %s (%s) је пронађено на удаљеном извору %s\n"

#: app/flatpak-cli-transaction.c:104
msgid "Do you want to install it?"
msgstr "Да ли желите да га инсталирате?"

#: app/flatpak-cli-transaction.c:110
#, c-format
msgid "Required runtime for %s (%s) found in remotes:"
msgstr "Потребно извршно окружење за %s (%s) је нађено у удаљеним изворима:"

#: app/flatpak-cli-transaction.c:112
msgid "Which do you want to install (0 to abort)?"
msgstr "Које желите да инсталирате (0 за одустајање)?"

#: app/flatpak-cli-transaction.c:132
#, c-format
msgid "Configuring %s as new remote '%s'\n"
msgstr "Подешавам %s као нови удаљени извор „%s“\n"

#. default to yes on Enter
#: app/flatpak-cli-transaction.c:139
#, c-format
msgid ""
"The remote '%s', referred to by '%s' at location %s contains additional "
"applications.\n"
"Should the remote be kept for future installations?"
msgstr ""
"Удаљени извор „%s“, на који упућује „%s“ на месту %s, садржи додатне "
"програме.\n"
"Да ли треба задржати овај удаљени извор за будуће инсталације?"

#. default to yes on Enter
#: app/flatpak-cli-transaction.c:147
#, c-format
msgid ""
"The application %s depends on runtimes from:\n"
"  %s\n"
"Configure this as new remote '%s'"
msgstr ""
"Програм %s зависи од извршних окружења са:\n"
"  %s\n"
"Подеси ово као нови удаљени извор „%s“"

#. Formatted size/remaining time in seconds
#: app/flatpak-cli-transaction.c:321
#, c-format
msgid "%s/s%s%s"
msgstr "%s/с%s%s"

#. Download progress percentage, use the appropriate
#. percent format for your language
#: app/flatpak-cli-transaction.c:359
#, c-format
msgid "%3d%%"
msgstr "%3d%%"

#: app/flatpak-cli-transaction.c:414
msgid "Installing…"
msgstr "Инсталирам…"

#: app/flatpak-cli-transaction.c:416
#, c-format
msgid "Installing %d/%d…"
msgstr "Инсталирам %d/%d…"

#: app/flatpak-cli-transaction.c:421
msgid "Updating…"
msgstr "Ажурирам…"

#: app/flatpak-cli-transaction.c:423
#, c-format
msgid "Updating %d/%d…"
msgstr "Ажурирам %d/%d…"

#: app/flatpak-cli-transaction.c:428
msgid "Uninstalling…"
msgstr "Уклањам…"

#: app/flatpak-cli-transaction.c:430
#, c-format
msgid "Uninstalling %d/%d…"
msgstr "Уклањам %d/%d…"

#: app/flatpak-cli-transaction.c:496 app/flatpak-quiet-transaction.c:161
#, c-format
msgid "Info: %s was skipped"
msgstr "Инфо: %s је прескочено"

#: app/flatpak-cli-transaction.c:519
#, c-format
msgid "Warning: %s%s%s already installed"
msgstr "Упозорење: %s%s%s је већ инсталирано"

#: app/flatpak-cli-transaction.c:522
#, c-format
msgid "Error: %s%s%s already installed"
msgstr "Грешка: %s%s%s је већ инсталирано"

#: app/flatpak-cli-transaction.c:528
#, c-format
msgid "Warning: %s%s%s not installed"
msgstr "Упозорење: %s%s%s није инсталирано"

#: app/flatpak-cli-transaction.c:531
#, c-format
msgid "Error: %s%s%s not installed"
msgstr "Грешка: %s%s%s није инсталирано"

#: app/flatpak-cli-transaction.c:537
#, c-format
msgid "Warning: %s%s%s needs a later flatpak version"
msgstr "Упозорење: %s%s%s захтева новије издање Флетпека"

#: app/flatpak-cli-transaction.c:540
#, c-format
msgid "Error: %s%s%s needs a later flatpak version"
msgstr "Грешка: %s%s%s захтева новије издање флетпека"

#: app/flatpak-cli-transaction.c:546
msgid "Warning: Not enough disk space to complete this operation"
msgstr "Упозорење: Нема довољно простора на диску за завршетак ове радње"

#: app/flatpak-cli-transaction.c:548
msgid "Error: Not enough disk space to complete this operation"
msgstr "Грешка: Нема довољно простора на диску за завршетак ове радње"

#: app/flatpak-cli-transaction.c:553
#, c-format
msgid "Warning: %s"
msgstr "Упозорење: %s"

#: app/flatpak-cli-transaction.c:555
#, c-format
msgid "Error: %s"
msgstr "Грешка: %s"

#: app/flatpak-cli-transaction.c:570
#, c-format
msgid "Failed to install %s%s%s: "
msgstr "Нисам успео да инсталирам %s%s%s: "

#: app/flatpak-cli-transaction.c:577
#, c-format
msgid "Failed to update %s%s%s: "
msgstr "Нисам успео да ажурирам %s%s%s: "

#: app/flatpak-cli-transaction.c:584
#, c-format
msgid "Failed to install bundle %s%s%s: "
msgstr "Нисам успео да инсталирам пакет %s%s%s: "

#: app/flatpak-cli-transaction.c:591
#, c-format
msgid "Failed to uninstall %s%s%s: "
msgstr "Нисам успео да уклоним %s%s%s: "

#: app/flatpak-cli-transaction.c:642
#, c-format
msgid "Authentication required for remote '%s'\n"
msgstr "Потребна је потврда идентитета за удаљено место „%s“\n"

#: app/flatpak-cli-transaction.c:643
msgid "Open browser?"
msgstr "Да отворим прегледник?"

#: app/flatpak-cli-transaction.c:699
#, c-format
msgid "Login required remote %s (realm %s)\n"
msgstr "Потребна је пријава за удаљено место %s (подручје %s)\n"

#: app/flatpak-cli-transaction.c:704
msgid "Password"
msgstr "Лозинка"

#. Only runtimes can be pinned
#: app/flatpak-cli-transaction.c:759
#, c-format
msgid ""
"\n"
"Info: (pinned) runtime %s%s%s branch %s%s%s is end-of-life, in favor of "
"%s%s%s branch %s%s%s\n"
msgstr ""
"\n"
"Инфо: (прикачено) извршно окружење %s%s%s грана %s%s%s је застарело, у "
"корист %s%s%s гране %s%s%s\n"

#: app/flatpak-cli-transaction.c:765
#, c-format
msgid ""
"\n"
"Info: runtime %s%s%s branch %s%s%s is end-of-life, in favor of %s%s%s branch "
"%s%s%s\n"
msgstr ""
"\n"
"Инфо: извршно окружење %s%s%s грана %s%s%s је застарело, у корист %s%s%s "
"гране %s%s%s\n"

#: app/flatpak-cli-transaction.c:768
#, c-format
msgid ""
"\n"
"Info: app %s%s%s branch %s%s%s is end-of-life, in favor of %s%s%s branch "
"%s%s%s\n"
msgstr ""
"\n"
"Инфо: програм %s%s%s грана %s%s%s је застарео, у корист %s%s%s гране %s%s%s\n"

#. Only runtimes can be pinned
#: app/flatpak-cli-transaction.c:780
#, c-format
msgid ""
"\n"
"Info: (pinned) runtime %s%s%s branch %s%s%s is end-of-life, with reason:\n"
msgstr ""
"\n"
"Инфо: (прикачено) извршно окружење %s%s%s грана %s%s%s је застарело, са "
"разлогом:\n"

#: app/flatpak-cli-transaction.c:786
#, c-format
msgid ""
"\n"
"Info: runtime %s%s%s branch %s%s%s is end-of-life, with reason:\n"
msgstr ""
"\n"
"Инфо: извршно окружење %s%s%s грана %s%s%s је застарело, са разлогом:\n"

#: app/flatpak-cli-transaction.c:789
#, c-format
msgid ""
"\n"
"Info: app %s%s%s branch %s%s%s is end-of-life, with reason:\n"
msgstr ""
"\n"
"Инфо: програм %s%s%s грана %s%s%s је застарео, са разлогом:\n"

#: app/flatpak-cli-transaction.c:963
#, c-format
msgid "Info: applications using this extension:\n"
msgstr "Инфо: програми који користе ово проширење:\n"

#: app/flatpak-cli-transaction.c:965
#, c-format
msgid "Info: applications using this runtime:\n"
msgstr "Инфо: програми који користе ово извршно окружење:\n"

#: app/flatpak-cli-transaction.c:984
msgid "Replace?"
msgstr "Заменити?"

#: app/flatpak-cli-transaction.c:987 app/flatpak-quiet-transaction.c:247
#, c-format
msgid "Updating to rebased version\n"
msgstr "Надградња на пребазирано издање\n"

#: app/flatpak-cli-transaction.c:1011
#, c-format
msgid "Failed to rebase %s to %s: "
msgstr "Нисам успео да пребазирам „%s“ на „%s“: "

#: app/flatpak-cli-transaction.c:1277
#, c-format
msgid "New %s%s%s permissions:"
msgstr "Нова %s%s%s овлашћења:"

#: app/flatpak-cli-transaction.c:1279
#, c-format
msgid "%s%s%s permissions:"
msgstr "%s%s%s овлашћења:"

#: app/flatpak-cli-transaction.c:1343
msgid "Warning: "
msgstr "Упозорење: "

#. translators: This is short for operation, the title of a one-char column
#: app/flatpak-cli-transaction.c:1442
msgid "Op"
msgstr "Рд"

#. Avoid resizing the download column too much,
#. * by making the title as long as typical content
#.
#: app/flatpak-cli-transaction.c:1458 app/flatpak-cli-transaction.c:1503
msgid "partial"
msgstr "делимично"

#: app/flatpak-cli-transaction.c:1535
msgid "Proceed with these changes to the user installation?"
msgstr "Наставити са овим изменама у корисничкој инсталацији?"

#: app/flatpak-cli-transaction.c:1537
msgid "Proceed with these changes to the system installation?"
msgstr "Наставити са овим изменама у системској инсталацији?"

#: app/flatpak-cli-transaction.c:1539
#, c-format
msgid "Proceed with these changes to the %s?"
msgstr "Наставити са овим изменама у „%s“?"

#: app/flatpak-cli-transaction.c:1711
msgid "Changes complete."
msgstr "Измене су завршене."

#: app/flatpak-cli-transaction.c:1713
msgid "Uninstall complete."
msgstr "Деинсталација је завршена."

#: app/flatpak-cli-transaction.c:1715
msgid "Installation complete."
msgstr "Инсталирање је завршено."

#: app/flatpak-cli-transaction.c:1717
msgid "Updates complete."
msgstr "Ажурирања су завршена."

#. For updates/!stop_on_first_error we already printed all errors so we make up
#. a different one.
#: app/flatpak-cli-transaction.c:1750
msgid "There were one or more errors"
msgstr "Дошло је до једне или више грешака"

#. translators: please keep the leading space
#: app/flatpak-main.c:76
msgid " Manage installed applications and runtimes"
msgstr " Управљајте инсталираним програмима и извршним окружењима"

#: app/flatpak-main.c:77
msgid "Install an application or runtime"
msgstr "Инсталирајте програм или извршно окружење"

#: app/flatpak-main.c:78
msgid "Update an installed application or runtime"
msgstr "Ажурирајте инсталирани програм или извршно окружење"

#: app/flatpak-main.c:81
msgid "Uninstall an installed application or runtime"
msgstr "Уклоните инсталирани програм или извршно окружење"

#: app/flatpak-main.c:84
msgid "Mask out updates and automatic installation"
msgstr "Маскирајте ажурирања и самосталну инсталацију"

#: app/flatpak-main.c:85
msgid "Pin a runtime to prevent automatic removal"
msgstr "Забодите извршно окружење како бисте спречили самостално уклањање"

#: app/flatpak-main.c:86
msgid "List installed apps and/or runtimes"
msgstr "Излистајте инсталиране програме и/или извршна окружења"

#: app/flatpak-main.c:87
msgid "Show info for installed app or runtime"
msgstr "Прикажите податке о инсталираном програму или извршном окружењу"

#: app/flatpak-main.c:88
msgid "Show history"
msgstr "Прикажите историјат"

#: app/flatpak-main.c:89
msgid "Configure flatpak"
msgstr "Подеси флетпек"

#: app/flatpak-main.c:90
msgid "Repair flatpak installation"
msgstr "Поправи флетпек инсталацију"

#: app/flatpak-main.c:91
msgid "Put applications or runtimes onto removable media"
msgstr "Ставите програме или извршна окружења на уклоњиве медије"

#: app/flatpak-main.c:92
msgid "Install flatpaks that are part of the operating system"
msgstr "Инсталирајте флатпаке који су део оперативног система"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:95
msgid ""
"\n"
" Find applications and runtimes"
msgstr ""
"\n"
" Пронађите програме и извршна окружења"

#: app/flatpak-main.c:96
msgid "Search for remote apps/runtimes"
msgstr "Потражите удаљене програме/извршна окружења"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:99
msgid ""
"\n"
" Manage running applications"
msgstr ""
"\n"
" Управљајте покренутим програмима"

#: app/flatpak-main.c:100
msgid "Run an application"
msgstr "Покрените програм"

#: app/flatpak-main.c:101
msgid "Override permissions for an application"
msgstr "Превазиђите овлашћења за програм"

#: app/flatpak-main.c:102
msgid "Specify default version to run"
msgstr "Наведите подразумевано издање за покретање"

#: app/flatpak-main.c:103
msgid "Enter the namespace of a running application"
msgstr "Унесите именски простор покренутог програма"

#: app/flatpak-main.c:104
msgid "Enumerate running applications"
msgstr "Набројте покренуте програме"

#: app/flatpak-main.c:105
msgid "Stop a running application"
msgstr "Зауставите покренути програм"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:108
msgid ""
"\n"
" Manage file access"
msgstr ""
"\n"
" Управљајте приступом датотекама"

#: app/flatpak-main.c:109
msgid "List exported files"
msgstr "Излистајте извезене датотеке"

#: app/flatpak-main.c:110
msgid "Grant an application access to a specific file"
msgstr "Дозволите програму приступ одређеној датотеци"

#: app/flatpak-main.c:111
msgid "Revoke access to a specific file"
msgstr "Опозови приступ одређеној датотеци"

#: app/flatpak-main.c:112
msgid "Show information about a specific file"
msgstr "Прикажи податке о одређеној датотеци"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:116
msgid ""
"\n"
" Manage dynamic permissions"
msgstr ""
"\n"
" Управљај динамичким овлашћењима"

#: app/flatpak-main.c:117
msgid "List permissions"
msgstr "Списак овлашћења"

#: app/flatpak-main.c:118
msgid "Remove item from permission store"
msgstr "Уклони ставку из складишта овлашћења"

#: app/flatpak-main.c:120
msgid "Set permissions"
msgstr "Постави овлашћења"

#: app/flatpak-main.c:121
msgid "Show app permissions"
msgstr "Прикажи овлашћења програма"

#: app/flatpak-main.c:122
msgid "Reset app permissions"
msgstr "Поништи овлашћења програма"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:125
msgid ""
"\n"
" Manage remote repositories"
msgstr ""
"\n"
" Управљај удаљеним ризницама"

#: app/flatpak-main.c:126
msgid "List all configured remotes"
msgstr "Списак свих подешених удаљених места"

#: app/flatpak-main.c:127
msgid "Add a new remote repository (by URL)"
msgstr "Додај нову удаљену ризницу (преко адресе)"

#: app/flatpak-main.c:128
msgid "Modify properties of a configured remote"
msgstr "Измени својства подешеног удаљеног места"

#: app/flatpak-main.c:129
msgid "Delete a configured remote"
msgstr "Обриши подешено удаљено место"

#: app/flatpak-main.c:131
msgid "List contents of a configured remote"
msgstr "Списак садржаја подешеног удаљеног места"

#: app/flatpak-main.c:132
msgid "Show information about a remote app or runtime"
msgstr "Прикажи податке о удаљеном програму или извршном окружењу"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:135
msgid ""
"\n"
" Build applications"
msgstr ""
"\n"
" Изгради програме"

#: app/flatpak-main.c:136
msgid "Initialize a directory for building"
msgstr "Покрени директоријум за изградњу"

#: app/flatpak-main.c:137
msgid "Run a build command inside the build dir"
msgstr "Покрени наредбу изградње унутар директоријума за изградњу"

#: app/flatpak-main.c:138
msgid "Finish a build dir for export"
msgstr "Заврши директоријум изградње за извоз"

#: app/flatpak-main.c:139
msgid "Export a build dir to a repository"
msgstr "Извези директоријум изградње у ризницу"

#: app/flatpak-main.c:140
msgid "Create a bundle file from a ref in a local repository"
msgstr "Направите датотеку пакета из упуте у локалној ризници"

#: app/flatpak-main.c:141
msgid "Import a bundle file"
msgstr "Увезите датотеку пакета"

#: app/flatpak-main.c:142
msgid "Sign an application or runtime"
msgstr "Потпишите програм или извршно окружење"

#: app/flatpak-main.c:143
msgid "Update the summary file in a repository"
msgstr "Ажурирајте датотеку сажетка у ризници"

#: app/flatpak-main.c:144
msgid "Create new commit based on existing ref"
msgstr "Направите нову предају на основу постојеће упуте"

#: app/flatpak-main.c:145
msgid "Show information about a repo"
msgstr "Прикажите податке о ризници"

#: app/flatpak-main.c:162
msgid "Show debug information, -vv for more detail"
msgstr "Прикажите податке за уклањање грешака, -vv за више детаља"

#: app/flatpak-main.c:163
msgid "Show OSTree debug information"
msgstr "Прикажите OSTree податке за уклањање грешака"

#: app/flatpak-main.c:169
msgid "Print version information and exit"
msgstr "Испишите податке о издању и изађите"

#: app/flatpak-main.c:170
msgid "Print default arch and exit"
msgstr "Испишите подразумевану архитектуру и изађите"

#: app/flatpak-main.c:171
msgid "Print supported arches and exit"
msgstr "Испишите подржане архитектуре и изађите"

#: app/flatpak-main.c:172
msgid "Print active gl drivers and exit"
msgstr "Испишите активне gl управљачке програме и изађите"

#: app/flatpak-main.c:173
msgid "Print paths for system installations and exit"
msgstr "Испишите путање за системске инсталације и изађите"

#: app/flatpak-main.c:174
msgid "Print the updated environment needed to run flatpaks"
msgstr "Испишите ажурирано окружење потребно за покретање флетпекова"

#: app/flatpak-main.c:175
msgid "Only include the system installation with --print-updated-env"
msgstr "Укључите само системску инсталацију уз --print-updated-env"

#: app/flatpak-main.c:180
msgid "Work on the user installation"
msgstr "Радите на корисничкој инсталацији"

#: app/flatpak-main.c:181
msgid "Work on the system-wide installation (default)"
msgstr "Радите на системској инсталацији (подразумевано)"

#: app/flatpak-main.c:182
msgid "Work on a non-default system-wide installation"
msgstr "Радите на неподразумеваној системској инсталацији"

#: app/flatpak-main.c:212
msgid "Builtin Commands:"
msgstr "Уграђене наредбе:"

#: app/flatpak-main.c:298
#, c-format
msgid ""
"Note that the directories %s are not in the search path set by the "
"XDG_DATA_DIRS environment variable, so applications installed by Flatpak may "
"not appear on your desktop until the session is restarted."
msgstr ""
"Имајте на уму да директоријуми %s нису у путањи претраге коју поставља "
"променљива окружења XDG_DATA_DIRS, тако да се програми инсталирани Флетпеком "
"можда неће појавити на вашој радној површи док се сесија поново не покрене."

#: app/flatpak-main.c:312
#, c-format
msgid ""
"Note that the directory %s is not in the search path set by the "
"XDG_DATA_DIRS environment variable, so applications installed by Flatpak may "
"not appear on your desktop until the session is restarted."
msgstr ""
"Бележите да се директоријум %s не налази у путањи претраге коју поставља "
"променљива окружења XDG_DATA_DIRS, тако да се програми инсталирани Флетпеком "
"можда неће појавити на вашој радној површи све док се сесија поново не "
"покрене."

#: app/flatpak-main.c:381
msgid ""
"Refusing to operate under sudo with --user. Omit sudo to operate on the user "
"installation, or use a root shell to operate on the root user's installation."
msgstr ""
"Одбијам рад под sudo-ом са --user. Изоставите sudo за рад на корисничкој "
"инсталацији, или користите администраторску шкољку (root shell) за рад на "
"системској инсталацији."

#: app/flatpak-main.c:453
msgid ""
"Multiple installations specified for a command that works on one installation"
msgstr ""
"Наведено је више инсталација за наредбу која ради на једној инсталацији"

#: app/flatpak-main.c:504 app/flatpak-main.c:697
#, c-format
msgid "See '%s --help'"
msgstr "Погледајте „%s --help“"

#: app/flatpak-main.c:706
#, c-format
msgid "'%s' is not a flatpak command. Did you mean '%s%s'?"
msgstr "„%s“ није наредба Флетпека. Да ли сте мислили на „%s%s“?"

#: app/flatpak-main.c:709
#, c-format
msgid "'%s' is not a flatpak command"
msgstr "„%s“ није наредба Флетпека"

#: app/flatpak-main.c:824
msgid "No command specified"
msgstr "Није наведена наредба"

#: app/flatpak-main.c:980
msgid "error:"
msgstr "грешка:"

#: app/flatpak-quiet-transaction.c:77
#, c-format
msgid "Installing %s\n"
msgstr "Инсталирам %s\n"

#: app/flatpak-quiet-transaction.c:81
#, c-format
msgid "Updating %s\n"
msgstr "Ажурирам %s\n"

#: app/flatpak-quiet-transaction.c:85
#, c-format
msgid "Uninstalling %s\n"
msgstr "Уклањам %s\n"

#: app/flatpak-quiet-transaction.c:107
#, c-format
msgid "Warning: Failed to install %s: %s\n"
msgstr "Упозорење: Нисам успео да инсталирам %s: %s\n"

#: app/flatpak-quiet-transaction.c:110
#, c-format
msgid "Error: Failed to install %s: %s\n"
msgstr "Грешка: Нисам успео да инсталирам %s: %s\n"

#: app/flatpak-quiet-transaction.c:116
#, c-format
msgid "Warning: Failed to update %s: %s\n"
msgstr "Упозорење: Нисам успео да ажурирам %s: %s\n"

#: app/flatpak-quiet-transaction.c:119
#, c-format
msgid "Error: Failed to update %s: %s\n"
msgstr "Грешка: Нисам успео да ажурирам %s: %s\n"

#: app/flatpak-quiet-transaction.c:125
#, c-format
msgid "Warning: Failed to install bundle %s: %s\n"
msgstr "Упозорење: Нисам успео да инсталирам комплет %s: %s\n"

#: app/flatpak-quiet-transaction.c:128
#, c-format
msgid "Error: Failed to install bundle %s: %s\n"
msgstr "Грешка: Нисам успео да инсталирам комплет %s: %s\n"

#: app/flatpak-quiet-transaction.c:134
#, c-format
msgid "Warning: Failed to uninstall %s: %s\n"
msgstr "Упозорење: Нисам успео да уклоним %s: %s\n"

#: app/flatpak-quiet-transaction.c:137
#, c-format
msgid "Error: Failed to uninstall %s: %s\n"
msgstr "Грешка: Нисам успео да уклоним %s: %s\n"

#: app/flatpak-quiet-transaction.c:166 common/flatpak-dir.c:11475
#, c-format
msgid "%s already installed"
msgstr "%s је већ инсталиран"

#: app/flatpak-quiet-transaction.c:168 common/flatpak-dir.c:3622
#: common/flatpak-dir.c:4321 common/flatpak-dir.c:16968
#: common/flatpak-dir.c:17258 common/flatpak-dir-utils.c:166
#: common/flatpak-dir-utils.c:259 common/flatpak-transaction.c:2736
#: common/flatpak-transaction.c:2791
#, c-format
msgid "%s not installed"
msgstr "%s није инсталиран"

#: app/flatpak-quiet-transaction.c:170
#, c-format
msgid "%s needs a later flatpak version"
msgstr "%s захтева новије издање флетпека"

#: app/flatpak-quiet-transaction.c:172
msgid "Not enough disk space to complete this operation"
msgstr "Нема довољно простора на диску за завршетак ове радње"

#: app/flatpak-quiet-transaction.c:239
#, c-format
msgid "Info: %s is end-of-life, in favor of %s\n"
msgstr "Инфо: %s је на крају века трајања, у корист %s\n"

#: app/flatpak-quiet-transaction.c:241
#, c-format
msgid "Info: %s is end-of-life, with reason: %s\n"
msgstr "Инфо: %s је на крају века трајања, са разлогом: %s\n"

#: app/flatpak-quiet-transaction.c:251
#, c-format
msgid "Failed to rebase %s to %s: %s\n"
msgstr "Нисам успео да пребацим %s на %s: %s\n"

#: common/flatpak-auth.c:58
#, c-format
msgid "No authenticator configured for remote `%s`"
msgstr "Није подешен потврђивач за удаљени „%s“"

#: common/flatpak-context.c:637 common/flatpak-context.c:649
#, c-format
msgid "Invalid permission syntax: %s"
msgstr "Неисправна синтакса овлашћења: %s"

#: common/flatpak-context.c:1207
#, c-format
msgid "Unknown share type %s, valid types are: %s"
msgstr "Непозната врста дељења %s, исправне врсте су: %s"

#: common/flatpak-context.c:1228
#, c-format
msgid "Unknown policy type %s, valid types are: %s"
msgstr "Непозната врста политике %s, исправне врсте су: %s"

#: common/flatpak-context.c:1266
#, c-format
msgid "Invalid dbus name %s"
msgstr "Неисправан д-сабирница назив %s"

#: common/flatpak-context.c:1279
#, c-format
msgid "Unknown socket type %s, valid types are: %s"
msgstr "Непозната врста утичнице %s, исправне врсте су: %s"

#: common/flatpak-context.c:1294
#, c-format
msgid "Unknown device type %s, valid types are: %s"
msgstr "Непозната врста уређаја %s, исправне врсте су: %s"

#: common/flatpak-context.c:1308
#, c-format
msgid "Unknown feature type %s, valid types are: %s"
msgstr "Непозната врста функције %s, исправне врсте су: %s"

#: common/flatpak-context.c:1840
#, c-format
msgid "Filesystem location \"%s\" contains \"..\""
msgstr "Место система датотека „%s“ садржи „..“"

#: common/flatpak-context.c:1882
#, c-format
msgid ""
"--filesystem=/ is not available, use --filesystem=host for a similar result"
msgstr ""
"--filesystem=/ није доступно, користите --filesystem=host за сличан резултат"

#: common/flatpak-context.c:1916
#, c-format
msgid ""
"Unknown filesystem location %s, valid locations are: host, host-os, host-"
"etc, host-root, home, xdg-*[/…], ~/dir, /dir"
msgstr ""
"Непознато место система датотека %s, исправна места су: host, host-os, host-"
"etc, host-root, home, xdg-*[/…], ~/dir, /dir"

#: common/flatpak-context.c:2015
#, c-format
msgid "Invalid syntax for %s: %s"
msgstr "Неисправна синтакса за %s: %s"

#: common/flatpak-context.c:2142
#, c-format
msgid "fallback-x11 can not be conditional"
msgstr "fallback-x11 не може бити условно"

#: common/flatpak-context.c:2318
#, c-format
msgid "Invalid env format %s"
msgstr "Неисправан формат окружења %s"

#: common/flatpak-context.c:2399
#, c-format
msgid "Environment variable name must not contain '=': %s"
msgstr "Име променљиве окружења не сме да садржи „=“: %s"

#: common/flatpak-context.c:2527 common/flatpak-context.c:2535
#, c-format
msgid "--add-policy arguments must be in the form SUBSYSTEM.KEY=VALUE"
msgstr ""
"Аргументи за „--add-policy“ морају бити у облику ПОДСИСТЕМ.КЉУЧ=ВРЕДНОСТ"

#: common/flatpak-context.c:2542
#, c-format
msgid "--add-policy values can't start with \"!\""
msgstr "Вредности за „--add-policy“ не могу почињати са „!“"

#: common/flatpak-context.c:2567 common/flatpak-context.c:2575
#, c-format
msgid "--remove-policy arguments must be in the form SUBSYSTEM.KEY=VALUE"
msgstr ""
"Аргументи за „--remove-policy“ морају бити у облику ПОДСИСТЕМ.КЉУЧ=ВРЕДНОСТ"

#: common/flatpak-context.c:2582
#, c-format
msgid "--remove-policy values can't start with \"!\""
msgstr "Вредности за „--remove-policy“ не могу почињати са „!“"

#: common/flatpak-context.c:2657
msgid "Share with host"
msgstr "Дели са домаћином"

#: common/flatpak-context.c:2657 common/flatpak-context.c:2658
msgid "SHARE"
msgstr "ДЕЛИ"

#: common/flatpak-context.c:2658
msgid "Unshare with host"
msgstr "Престани да делиш са домаћином"

#: common/flatpak-context.c:2659
msgid "Require conditions to be met for a subsystem to get shared"
msgstr "Захтевај испуњење услова да би се подсистем делио"

#: common/flatpak-context.c:2659
msgid "SHARE:CONDITION"
msgstr "ДЕЛИ:УСЛОВ"

#: common/flatpak-context.c:2660
msgid "Expose socket to app"
msgstr "Изложи прикључницу програму"

#: common/flatpak-context.c:2660 common/flatpak-context.c:2661
msgid "SOCKET"
msgstr "ПРИКЉУЧНИЦА"

#: common/flatpak-context.c:2661
msgid "Don't expose socket to app"
msgstr "Не излажи прикључницу програму"

#: common/flatpak-context.c:2662
msgid "Require conditions to be met for a socket to get exposed"
msgstr "Захтевај испуњење услова да би се прикључница изложила"

#: common/flatpak-context.c:2662
msgid "SOCKET:CONDITION"
msgstr "ПРИКЉУЧНИЦА:УСЛОВ"

#: common/flatpak-context.c:2663
msgid "Expose device to app"
msgstr "Изложи уређај програму"

#: common/flatpak-context.c:2663 common/flatpak-context.c:2664
msgid "DEVICE"
msgstr "УРЕЂАЈ"

#: common/flatpak-context.c:2664
msgid "Don't expose device to app"
msgstr "Не излажи уређај програму"

#: common/flatpak-context.c:2665
msgid "Require conditions to be met for a device to get exposed"
msgstr "Захтевај испуњење услова да би се уређај изложио"

#: common/flatpak-context.c:2665
msgid "DEVICE:CONDITION"
msgstr "УРЕЂАЈ:УСЛОВ"

#: common/flatpak-context.c:2666
msgid "Allow feature"
msgstr "Дозволи функцију"

#: common/flatpak-context.c:2666 common/flatpak-context.c:2667
msgid "FEATURE"
msgstr "ФУНКЦИЈА"

#: common/flatpak-context.c:2667
msgid "Don't allow feature"
msgstr "Не дозволи функцију"

#: common/flatpak-context.c:2668
msgid "Require conditions to be met for a feature to get allowed"
msgstr "Захтевај испуњавање услова да би функција била дозвољена"

#: common/flatpak-context.c:2668
msgid "FEATURE:CONDITION"
msgstr "ФУНКЦИЈА:УСЛОВ"

#: common/flatpak-context.c:2669
msgid "Expose filesystem to app (:ro for read-only)"
msgstr "Изложи систем датотека програму (:ro за само за читање)"

#: common/flatpak-context.c:2669
msgid "FILESYSTEM[:ro]"
msgstr "СИСТЕМ_ДАТОТЕКА[:ro]"

#: common/flatpak-context.c:2670
msgid "Don't expose filesystem to app"
msgstr "Не излажи систем датотека програму"

#: common/flatpak-context.c:2670
msgid "FILESYSTEM"
msgstr "СИСТЕМ_ДАТОТЕКА"

#: common/flatpak-context.c:2671
msgid "Set environment variable"
msgstr "Постави променљиву окружења"

#: common/flatpak-context.c:2671
msgid "VAR=VALUE"
msgstr "ПРОМ=ВРЕДНОСТ"

#: common/flatpak-context.c:2672
msgid "Read environment variables in env -0 format from FD"
msgstr "Читај променљиве окружења у формату „env -0“ из ОД-а"

#: common/flatpak-context.c:2673
msgid "Remove variable from environment"
msgstr "Уклони променљиву из окружења"

#: common/flatpak-context.c:2673
msgid "VAR"
msgstr "ПРОМ"

#: common/flatpak-context.c:2674
msgid "Allow app to own name on the session bus"
msgstr "Дозволи програму да поседује име на сесијској сабирници"

#: common/flatpak-context.c:2674 common/flatpak-context.c:2675
#: common/flatpak-context.c:2676 common/flatpak-context.c:2677
#: common/flatpak-context.c:2678 common/flatpak-context.c:2679
#: common/flatpak-context.c:2680
msgid "DBUS_NAME"
msgstr "DBUS_ИМЕ"

#: common/flatpak-context.c:2675
msgid "Allow app to talk to name on the session bus"
msgstr "Дозволи програму да комуницира са именом на сесијској сабирници"

#: common/flatpak-context.c:2676
msgid "Don't allow app to talk to name on the session bus"
msgstr "Не дозволи програму да комуницира са именом на сесијској сабирници"

#: common/flatpak-context.c:2677
msgid "Allow app to own name on the system bus"
msgstr "Дозволи програму да поседује име на системској сабирници"

#: common/flatpak-context.c:2678
msgid "Allow app to talk to name on the system bus"
msgstr "Дозволи програму да комуницира са називом на системској сабирници"

#: common/flatpak-context.c:2679
msgid "Don't allow app to talk to name on the system bus"
msgstr "Не дозволи програму да комуницира са називом на системској сабирници"

#: common/flatpak-context.c:2680
msgid "Allow app to own name on the a11y bus"
msgstr "Дозволи програму да поседује назив на a11y сабирници"

#: common/flatpak-context.c:2681
msgid "Add generic policy option"
msgstr "Додај општу опцију смернице"

#: common/flatpak-context.c:2681 common/flatpak-context.c:2682
msgid "SUBSYSTEM.KEY=VALUE"
msgstr "ПОДСИСТЕМ.КЉУЧ=ВРЕДНОСТ"

#: common/flatpak-context.c:2682
msgid "Remove generic policy option"
msgstr "Уклони општу опцију смернице"

#: common/flatpak-context.c:2683
msgid "Add USB device to enumerables"
msgstr "Додај УСБ уређај у набројиве"

#: common/flatpak-context.c:2683 common/flatpak-context.c:2684
msgid "VENDOR_ID:PRODUCT_ID"
msgstr "ИД_ПРОДАВЦА:ИД_ПРОИЗВОДА"

#: common/flatpak-context.c:2684
msgid "Add USB device to hidden list"
msgstr "Додај УСБ уређај на списак скривених"

#: common/flatpak-context.c:2685
msgid "A list of USB devices that are enumerable"
msgstr "Списак УСБ уређаја који се могу набројати"

#: common/flatpak-context.c:2685
msgid "LIST"
msgstr "СПИСАК"

#: common/flatpak-context.c:2686
msgid "File containing a list of USB devices to make enumerable"
msgstr "Датотека која садржи списак УСБ уређаја за набрајање"

#: common/flatpak-context.c:2686 common/flatpak-context.c:2687
msgid "FILENAME"
msgstr "НАЗИВ_ДАТОТЕКЕ"

#: common/flatpak-context.c:2687
msgid "Persist home directory subpath"
msgstr "Задржи подпутању личног директоријума"

#. This is not needed/used anymore, so hidden, but we accept it for backwards compat
#: common/flatpak-context.c:2689
msgid "Don't require a running session (no cgroups creation)"
msgstr "Не захтевај покренуту сесију (без стварања ц-група)"

#: common/flatpak-context.c:3718
#, c-format
msgid "Not replacing \"%s\" with tmpfs: %s"
msgstr "Не замењујем „%s“ са tmpfs-ом: %s"

#: common/flatpak-context.c:3726
#, c-format
msgid "Not sharing \"%s\" with sandbox: %s"
msgstr "Не делим „%s“ са изолацијом (sandbox): %s"

#. Even if the error is one that we would normally silence, like
#. * the path not existing, it seems reasonable to make more of a fuss
#. * about the home directory not existing or otherwise being unusable,
#. * so this is intentionally not using cannot_export()
#: common/flatpak-context.c:3828
#, c-format
msgid "Not allowing home directory access: %s"
msgstr "Не дозвољавам приступ личном директоријуму: %s"

#: common/flatpak-context.c:4062
#, c-format
msgid "Unable to provide a temporary home directory in the sandbox: %s"
msgstr "Нисам успео да обезбедим привремени лични директоријум у изолацији: %s"

#: common/flatpak-dir.c:442
#, c-format
msgid "Configured collection ID ‘%s’ not in summary file"
msgstr "Подешени ИД збирке „%s“ није у датотеци сажетка"

#: common/flatpak-dir.c:587
#, c-format
msgid "Unable to load summary from remote %s: %s"
msgstr "Не могу да учитам сажетак са удаљеног места %s: %s"

#: common/flatpak-dir.c:764 common/flatpak-dir.c:800 common/flatpak-dir.c:906
#, c-format
msgid "No such ref '%s' in remote %s"
msgstr "Нема такве референце „%s“ на удаљеном месту %s"

#: common/flatpak-dir.c:891 common/flatpak-dir.c:1051 common/flatpak-dir.c:1080
#: common/flatpak-dir.c:1092
#, c-format
msgid "No entry for %s in remote %s summary flatpak cache"
msgstr "Нема уноса за %s у кешу сажетка флетпека на удаљеном месту %s"

#: common/flatpak-dir.c:1069
#, c-format
msgid "No summary or Flatpak cache available for remote %s"
msgstr "Није доступан сажетак нити флетпек кеш за удаљено место %s"

#: common/flatpak-dir.c:1097
#, c-format
msgid "Missing xa.data in summary for remote %s"
msgstr "Недостаје „xa.data“ у сажетку за удаљено место %s"

#: common/flatpak-dir.c:1103 common/flatpak-dir.c:1546
#, c-format
msgid "Unsupported summary version %d for remote %s"
msgstr "Неподржано издање сажетка %d за удаљено место %s"

#: common/flatpak-dir.c:1200
msgid "Remote OCI index has no registry uri"
msgstr "Удаљени OCI индекс нема адресу регистра"

#: common/flatpak-dir.c:1261
#, c-format
msgid "Couldn't find ref %s in remote %s"
msgstr "Не могу да пронађем референцу %s на удаљеном месту %s"

#: common/flatpak-dir.c:1288 common/flatpak-dir.c:1381
#, fuzzy, c-format
msgid "Commit has no requested ref ‘%s’ in ref binding metadata (found: ‘%s’)"
msgstr ""
"Предаја нема захтевану референцу „%s“ у метаподацима везивања референци"

#: common/flatpak-dir.c:1413
#, c-format
msgid "Configured collection ID ‘%s’ not in binding metadata"
msgstr "Подешени ИД збирке „%s“ није у метаподацима везивања"

#: common/flatpak-dir.c:1449 common/flatpak-dir.c:5645
#, c-format
msgid "Couldn't find latest checksum for ref %s in remote %s"
msgstr ""
"Не могу да пронађем последњу суму провере за референцу %s на удаљеном месту "
"%s"

#: common/flatpak-dir.c:1516 common/flatpak-dir.c:1552
#, c-format
msgid "No entry for %s in remote %s summary flatpak sparse cache"
msgstr "Нема уноса за %s у ретком кешу сажетка флетпека на удаљеном месту %s"

#: common/flatpak-dir.c:2540
#, c-format
msgid "Commit metadata for %s not matching expected metadata"
msgstr "Метаподаци предаје за %s се не подударају са очекиваним метаподацима"

#: common/flatpak-dir.c:2823
msgid "Unable to connect to system bus"
msgstr "Не могу да се повежем на системску сабирницу"

#: common/flatpak-dir.c:3419
msgid "User installation"
msgstr "Корисничка инсталација"

#: common/flatpak-dir.c:3426
#, c-format
msgid "System (%s) installation"
msgstr "Системска (%s) инсталација"

#: common/flatpak-dir.c:3472
#, c-format
msgid "No overrides found for %s"
msgstr "Нису пронађена преписивања за %s"

#: common/flatpak-dir.c:3625
#, c-format
msgid "%s (commit %s) not installed"
msgstr "%s (предаја %s) није инсталиран"

#: common/flatpak-dir.c:4650
#, c-format
msgid "Error parsing system flatpakrepo file for %s: %s"
msgstr "Грешка приликом обраде системске „flatpakrepo“ датотеке за %s: %s"

#: common/flatpak-dir.c:4735
#, c-format
msgid "While opening repository %s: "
msgstr "Приликом отварања ризнице %s: "

#: common/flatpak-dir.c:5004
#, c-format
msgid "The config key %s is not set"
msgstr "Кључ подешавања %s није постављен"

#: common/flatpak-dir.c:5140
#, c-format
msgid "No current %s pattern matching %s"
msgstr "Нема тренутног %s обрасца који се поклапа са %s"

#: common/flatpak-dir.c:5422
msgid "No appstream commit to deploy"
msgstr "Нема appstream предаје за примену"

#: common/flatpak-dir.c:5941 common/flatpak-dir.c:7266
#: common/flatpak-dir.c:10881 common/flatpak-dir.c:11618
msgid "Can't pull from untrusted non-gpg verified remote"
msgstr ""
"Не могу да повучем са неповерљиве удаљене локације која није потврђена GPG-ом"

#: common/flatpak-dir.c:6376 common/flatpak-dir.c:6591
msgid "Extra data not supported for non-gpg-verified local system installs"
msgstr ""
"Додатни подаци нису подржани за локалне системске инсталације које нису "
"потврђене GPG-ом"

#: common/flatpak-dir.c:6415 common/flatpak-dir.c:6782
#, c-format
msgid "Invalid checksum for extra data uri %s"
msgstr "Неисправна сума провере за адресу (URI) додатних података %s"

#: common/flatpak-dir.c:6424
#, c-format
msgid "Empty name for extra data uri %s"
msgstr "Празан назив за адресу (URI) додатних података %s"

#: common/flatpak-dir.c:6432
#, c-format
msgid "Unsupported extra data uri %s"
msgstr "Неподржана адреса (URI) додатних података %s"

#: common/flatpak-dir.c:6461
#, c-format
msgid "Failed to load local extra-data %s: %s"
msgstr "Нисам успео да учитам локалне додатне податке %s: %s"

#: common/flatpak-dir.c:6469
#, c-format
msgid "Wrong size for extra-data %s"
msgstr "Погрешна величина за додатне податке %s"

#: common/flatpak-dir.c:6488
#, c-format
msgid "While downloading %s: "
msgstr "Приликом преузимања %s: "

#: common/flatpak-dir.c:6498
#, c-format
msgid "Wrong size for extra data %s"
msgstr "Погрешна величина за додатне податке %s"

#: common/flatpak-dir.c:6507
#, c-format
msgid "Invalid checksum for extra data %s"
msgstr "Неисправна сума провере за додатне податке %s"

#: common/flatpak-dir.c:7096 common/flatpak-dir.c:7349
#, c-format
msgid "While pulling %s from remote %s: "
msgstr "Приликом повлачења %s са удаљене локације %s: "

#: common/flatpak-dir.c:7290 common/flatpak-repo-utils.c:3886
msgid "GPG signatures found, but none are in trusted keyring"
msgstr "GPG потписи су пронађени, али ниједан није у поверљивом привеску"

#: common/flatpak-dir.c:7307
#, c-format
msgid "Commit for ‘%s’ has no ref binding"
msgstr "Предаја за „%s“ нема везу са референцом (ref)"

#: common/flatpak-dir.c:7312
#, c-format
msgid "Commit for ‘%s’ is not in expected bound refs: %s"
msgstr "Предаја за „%s“ није у очекиваним везаним референцама: %s"

#: common/flatpak-dir.c:7488
msgid "Only applications can be made current"
msgstr "Само програми могу бити постављени као тренутни"

#: common/flatpak-dir.c:8192
msgid "Not enough memory"
msgstr "Нема довољно меморије"

#: common/flatpak-dir.c:8211
msgid "Failed to read from exported file"
msgstr "Нисам успео да прочитам из извезене датотеке"

#: common/flatpak-dir.c:8401
msgid "Error reading mimetype xml file"
msgstr "Грешка читања XML датотеке миме-врсте"

#: common/flatpak-dir.c:8406
msgid "Invalid mimetype xml file"
msgstr "Неисправна XML датотека миме-врсте"

#: common/flatpak-dir.c:8492
#, c-format
msgid "D-Bus service file '%s' has wrong name"
msgstr "Датотека D-Bus услуге „%s“ има погрешан назив"

#: common/flatpak-dir.c:8647
#, c-format
msgid "Invalid Exec argument %s"
msgstr "Неисправан аргумент извршавања %s"

#: common/flatpak-dir.c:9115
msgid "While getting detached metadata: "
msgstr "Приликом добављања издвојених метаподатака: "

#: common/flatpak-dir.c:9120 common/flatpak-dir.c:9125
#: common/flatpak-dir.c:9129
msgid "Extra data missing in detached metadata"
msgstr "Недостају додатни подаци у издвојеним метаподацима"

#: common/flatpak-dir.c:9133
msgid "While creating extradir: "
msgstr "Приликом прављења додатног директоријума: "

#: common/flatpak-dir.c:9154 common/flatpak-dir.c:9187
msgid "Invalid checksum for extra data"
msgstr "Неисправна сума провере за додатне податке"

#: common/flatpak-dir.c:9183
msgid "Wrong size for extra data"
msgstr "Погрешна величина за додатне податке"

#: common/flatpak-dir.c:9196
#, c-format
msgid "While writing extra data file '%s': "
msgstr "Приликом записивања датотеке додатних података „%s“: "

#: common/flatpak-dir.c:9204
#, c-format
msgid "Extra data %s missing in detached metadata"
msgstr "Додатни подаци %s недостају у издвојеним метаподатацима"

#: common/flatpak-dir.c:9278
#, c-format
msgid "Unable to get runtime key from metadata"
msgstr "Не могу да добавим кључ извршног окружења из метаподатака"

#: common/flatpak-dir.c:9402
#, c-format
msgid "apply_extra script failed, exit status %d"
msgstr "Скрипта „apply_extra“ није успела, излазно стање је %d"

#. Translators: The placeholder is for an app ref.
#: common/flatpak-dir.c:9591
#, c-format
msgid "Installing %s is not allowed by the policy set by your administrator"
msgstr ""
"Инсталирање %s није дозвољено политиком коју је поставио ваш администратор"

#: common/flatpak-dir.c:9690
#, c-format
msgid "While trying to resolve ref %s: "
msgstr "Приликом покушаја разрешавања упута %s: "

#: common/flatpak-dir.c:9702
#, c-format
msgid "%s is not available"
msgstr "%s није доступно"

#: common/flatpak-dir.c:9714 common/flatpak-dir.c:11495
#, c-format
msgid "%s commit %s already installed"
msgstr "%s предаја %s је већ инсталирана"

#: common/flatpak-dir.c:9721
msgid "Can't create deploy directory"
msgstr "Не могу да направим директоријум за пуштање у рад"

#: common/flatpak-dir.c:9729
#, c-format
msgid "Failed to read commit %s: "
msgstr "Нисам успео да прочитам предају %s: "

#: common/flatpak-dir.c:9750
#, c-format
msgid "While trying to checkout %s into %s: "
msgstr "Приликом покушаја овере %s у %s: "

#: common/flatpak-dir.c:9769
msgid "While trying to checkout metadata subpath: "
msgstr "Приликом покушаја провере подпутање метаподатака: "

#: common/flatpak-dir.c:9801
#, c-format
msgid "While trying to checkout subpath ‘%s’: "
msgstr "Приликом покушаја провере подпутање „%s“: "

#: common/flatpak-dir.c:9811
msgid "While trying to remove existing extra dir: "
msgstr "Приликом покушаја уклањања постојећег додатног директоријума: "

#: common/flatpak-dir.c:9822
msgid "While trying to apply extra data: "
msgstr "Приликом покушаја примене додатних података: "

#: common/flatpak-dir.c:9849
#, c-format
msgid "Invalid commit ref %s: "
msgstr "Неисправна упутница предаје %s: "

#: common/flatpak-dir.c:9857 common/flatpak-dir.c:9869
#, c-format
msgid "Deployed ref %s does not match commit (%s)"
msgstr "Развијена упутница %s се не поклапа са предајом (%s)"

#: common/flatpak-dir.c:9863
#, c-format
msgid "Deployed ref %s branch does not match commit (%s)"
msgstr "Грана развијене упутнице %s се не поклапа са предајом (%s)"

#: common/flatpak-dir.c:10125 common/flatpak-installation.c:1911
#, c-format
msgid "%s branch %s already installed"
msgstr "%s грана %s је већ инсталирана"

#: common/flatpak-dir.c:10985
#, c-format
msgid "Could not unmount revokefs-fuse filesystem at %s: "
msgstr "Не могу да откачим revokefs-fuse систем датотека на %s: "

#: common/flatpak-dir.c:11289
#, c-format
msgid "This version of %s is already installed"
msgstr "Ово издање %s је већ инсталирано"

#: common/flatpak-dir.c:11302
#, c-format
msgid "Can't change remote during bundle install"
msgstr "Не могу да изменим удаљену везу током инсталације пакета"

#: common/flatpak-dir.c:11571
msgid "Can't update to a specific commit without root permissions"
msgstr ""
"Не могу да ажурирам на одређену предају без администраторских овлашћења"

#: common/flatpak-dir.c:11852
#, c-format
msgid "Can't remove %s, it is needed for: %s"
msgstr "Не могу да уклоним %s, потребан је за: %s"

#: common/flatpak-dir.c:11912 common/flatpak-installation.c:2067
#, c-format
msgid "%s branch %s is not installed"
msgstr "%s грана %s није инсталирана"

#: common/flatpak-dir.c:12165
#, c-format
msgid "%s commit %s not installed"
msgstr "%s предаја %s није инсталирана"

#: common/flatpak-dir.c:12501
#, c-format
msgid "Pruning repo failed: %s"
msgstr "Чишћење ризнице није успело: %s"

#: common/flatpak-dir.c:12669 common/flatpak-dir.c:12675
#, c-format
msgid "Failed to load filter '%s'"
msgstr "Нисам успео да учитам филтер „%s“"

#: common/flatpak-dir.c:12681
#, c-format
msgid "Failed to parse filter '%s'"
msgstr "Нисам успео да обрадим филтер „%s“"

#: common/flatpak-dir.c:12963
msgid "Failed to write summary cache: "
msgstr "Нисам успео да упишем кеш сажетка: "

#: common/flatpak-dir.c:12982
#, c-format
msgid "No oci summary cached for remote '%s'"
msgstr "Нема кешираног oci сажетка за удаљену везу „%s“"

#: common/flatpak-dir.c:13207
#, c-format
msgid "No cached summary for remote '%s'"
msgstr "Нема кешираног сажетка за удаљени извор „%s“"

#: common/flatpak-dir.c:13248
#, c-format
msgid "Invalid checksum for indexed summary %s read from %s"
msgstr "Неисправна сума провере за индексирани сажетак %s прочитан из %s"

#: common/flatpak-dir.c:13321
#, c-format
msgid ""
"Remote listing for %s not available; server has no summary file. Check the "
"URL passed to remote-add was valid."
msgstr ""
"Удаљени списак за %s није доступан; сервер нема датотеку сажетка. Проверите "
"да ли је адреса прослеђена на „remote-add“ исправна."

#: common/flatpak-dir.c:13698
#, c-format
msgid "Invalid checksum for indexed summary %s for remote '%s'"
msgstr ""
"Неисправна сума провере за индексирани сажетак %s за удаљени извор „%s“"

#: common/flatpak-dir.c:14388
#, c-format
msgid "Multiple branches available for %s, you must specify one of: "
msgstr "Доступно је више грана за %s, морате навести једну од: "

#: common/flatpak-dir.c:14454
#, c-format
msgid "Nothing matches %s"
msgstr "Ништа се не поклапа са %s"

#: common/flatpak-dir.c:14562
#, c-format
msgid "Can't find ref %s%s%s%s%s"
msgstr "Не могу да нађем референцу %s%s%s%s%s"

#: common/flatpak-dir.c:14605
#, c-format
msgid "Error searching remote %s: %s"
msgstr "Грешка претраживања удаљеног извора %s: %s"

#: common/flatpak-dir.c:14702
#, c-format
msgid "Error searching local repository: %s"
msgstr "Грешка претраживања локалне ризнице: %s"

#: common/flatpak-dir.c:14839
#, c-format
msgid "%s/%s/%s not installed"
msgstr "%s/%s/%s није инсталирано"

#: common/flatpak-dir.c:15042
#, c-format
msgid "Could not find installation %s"
msgstr "Не могу да нађем инсталацију %s"

#: common/flatpak-dir.c:15612
#, c-format
msgid "Invalid file format, no %s group"
msgstr "Неисправан формат датотеке, нема групе %s"

#: common/flatpak-dir.c:15617 common/flatpak-repo-utils.c:2836
#, c-format
msgid "Invalid version %s, only 1 supported"
msgstr "Неисправно издање %s, подржано је само 1"

#: common/flatpak-dir.c:15622 common/flatpak-dir.c:15627
#, c-format
msgid "Invalid file format, no %s specified"
msgstr "Неисправан формат датотеке, није наведено %s"

#. Check some minimal size so we don't get crap
#: common/flatpak-dir.c:15647
msgid "Invalid file format, gpg key invalid"
msgstr "Неисправан формат датотеке, гпг кључ је неисправан"

#: common/flatpak-dir.c:15675 common/flatpak-repo-utils.c:2917
msgid "Collection ID requires GPG key to be provided"
msgstr "ИД збирке захтева да се достави ГПГ кључ"

#: common/flatpak-dir.c:15718
#, c-format
msgid "Runtime %s, branch %s is already installed"
msgstr "Извршно окружење %s, грана %s је већ инсталирана"

#: common/flatpak-dir.c:15719
#, c-format
msgid "App %s, branch %s is already installed"
msgstr "Програм %s, грана %s је већ инсталирана"

#: common/flatpak-dir.c:15953
#, c-format
msgid "Can't remove remote '%s' with installed ref %s (at least)"
msgstr ""
"Не могу да уклоним удаљени извор „%s“ са инсталираном референцом %s (барем)"

#: common/flatpak-dir.c:16058
#, c-format
msgid "Invalid character '/' in remote name: %s"
msgstr "Неисправан знак „/“ у називу удаљеног извора: %s"

#: common/flatpak-dir.c:16064
#, c-format
msgid "No configuration for remote %s specified"
msgstr "Није наведено подешавање за удаљени %s"

#: common/flatpak-dir.c:17597
#, c-format
msgid "Skipping deletion of mirror ref (%s, %s)…\n"
msgstr "Прескачем брисање одраза упуте (%s, %s)…\n"

#: common/flatpak-exports.c:931
#, c-format
msgid "An absolute path is required"
msgstr "Потребна је апсолутна путања"

#: common/flatpak-exports.c:948
#, c-format
msgid "Unable to open path \"%s\": %s"
msgstr "Не могу да отворим путању „%s“: %s"

#: common/flatpak-exports.c:955
#, c-format
msgid "Unable to get file type of \"%s\": %s"
msgstr "Не могу да добавим врсту датотеке за „%s“: %s"

#: common/flatpak-exports.c:964
#, c-format
msgid "File \"%s\" has unsupported type 0o%o"
msgstr "Датотека „%s“ има неподржану врсту 0o%o"

#: common/flatpak-exports.c:970
#, c-format
msgid "Unable to get filesystem information for \"%s\": %s"
msgstr "Не могу да добавим податке о систему датотека за „%s“: %s"

#: common/flatpak-exports.c:980
#, c-format
msgid "Ignoring blocking autofs path \"%s\""
msgstr "Занемарујем блокирајућу „autofs“ путању „%s“"

#: common/flatpak-exports.c:996 common/flatpak-exports.c:1009
#: common/flatpak-exports.c:1022
#, c-format
msgid "Path \"%s\" is reserved by Flatpak"
msgstr "Путања „%s“ је резервисана за Флетпек"

#: common/flatpak-exports.c:1076
#, c-format
msgid "Unable to resolve symbolic link \"%s\": %s"
msgstr "Не могу да разрешим симболичку везу „%s“: %s"

#: common/flatpak-glib-backports.c:69
msgid "Empty string is not a number"
msgstr "Празна ниска није број"

#: common/flatpak-glib-backports.c:95
#, c-format
msgid "“%s” is not an unsigned number"
msgstr "„%s“ није непотписани број"

#: common/flatpak-glib-backports.c:105
#, c-format
msgid "Number “%s” is out of bounds [%s, %s]"
msgstr "Број „%s“ је изван граница [%s, %s]"

#: common/flatpak-image-source.c:83
msgid "Only sha256 image checksums are supported"
msgstr "Подржане су само „sha256“ суме провере одраза"

#: common/flatpak-image-source.c:100 common/flatpak-image-source.c:108
msgid "Image is not a manifest"
msgstr "Одраз није манифест"

#: common/flatpak-image-source.c:123
msgid "No org.flatpak.ref found in image"
msgstr "Није пронађен „org.flatpak.ref“ у одразу"

#: common/flatpak-image-source.c:148
#, c-format
msgid "Ref '%s' not found in registry"
msgstr "Упута „%s“ није пронађена у регистру"

#: common/flatpak-image-source.c:157
msgid "Multiple images in registry, specify a ref with --ref"
msgstr "Више одраза у регистру, наведите упуту помоћу „--ref“"

#: common/flatpak-installation.c:834
#, c-format
msgid "Ref %s not installed"
msgstr "Упута %s није инсталирана"

#: common/flatpak-installation.c:875
#, c-format
msgid "App %s not installed"
msgstr "Програм %s није инсталиран"

#: common/flatpak-installation.c:1395
#, c-format
msgid "Remote '%s' already exists"
msgstr "Удаљени извор „%s“ већ постоји"

#: common/flatpak-installation.c:1946
#, c-format
msgid "As requested, %s was only pulled, but not installed"
msgstr "Као што је захтевано, %s је само преузет, али не и инсталиран"

#: common/flatpak-instance.c:533 common/flatpak-instance.c:687
#: common/flatpak-instance.c:728
#, c-format
msgid "Unable to create directory %s"
msgstr "Не могу да направим директоријум %s"

#: common/flatpak-instance.c:554
#, c-format
msgid "Unable to lock %s"
msgstr "Не могу да закључам %s"

#: common/flatpak-instance.c:627
#, c-format
msgid "Unable to create temporary directory in %s"
msgstr "Не могу да направим привремени директоријум у %s"

#: common/flatpak-instance.c:639
#, c-format
msgid "Unable to create file %s"
msgstr "Не могу да направим датотеку %s"

#: common/flatpak-instance.c:646
#, c-format
msgid "Unable to update symbolic link %s/%s"
msgstr "Не могу да ажурирам симболичку везу %s/%s"

#: common/flatpak-oci-registry.c:1197
msgid "Only Bearer authentication supported"
msgstr "Подржана је само „Bearer“ потврда идентитета"

#: common/flatpak-oci-registry.c:1206
msgid "Only realm in authentication request"
msgstr "Само подручје у захтеву за потврду идентитета"

#: common/flatpak-oci-registry.c:1213
msgid "Invalid realm in authentication request"
msgstr "Неисправно подручје у захтеву за потврду идентитета"

#: common/flatpak-oci-registry.c:1283
#, c-format
msgid "Authorization failed: %s"
msgstr "Овлашћивање није успело: %s"

#: common/flatpak-oci-registry.c:1285
msgid "Authorization failed"
msgstr "Овлашћивање није успело"

#: common/flatpak-oci-registry.c:1289
#, c-format
msgid "Unexpected response status %d when requesting token: %s"
msgstr "Неочекиван статус одговора %d приликом захтевања скупине: %s"

#: common/flatpak-oci-registry.c:1300
msgid "Invalid authentication request response"
msgstr "Неисправан одговор на захтев за потврду идентитета"

#: common/flatpak-oci-registry.c:1731
#, c-format
msgid "Flatpak was compiled without zstd support"
msgstr "Флатпек је компајлиран без подршке за zstd"

#: common/flatpak-oci-registry.c:1923 common/flatpak-oci-registry.c:1975
#: common/flatpak-oci-registry.c:2004 common/flatpak-oci-registry.c:2059
#: common/flatpak-oci-registry.c:2115 common/flatpak-oci-registry.c:2193
msgid "Invalid delta file format"
msgstr "Неисправан облик делта датотеке"

#: common/flatpak-oci-registry.c:3198 common/flatpak-oci-registry.c:3382
msgid "Invalid OCI image config"
msgstr "Неисправно подешавање OCI одраза"

#: common/flatpak-oci-registry.c:3260 common/flatpak-oci-registry.c:3531
#, c-format
msgid "Wrong layer checksum, expected %s, was %s"
msgstr "Погрешна сума провере слоја, очекивана је %s, а добијена је %s"

#: common/flatpak-oci-registry.c:3359
#, c-format
msgid "No ref specified for OCI image %s"
msgstr "Није наведена референца за OCI одраз %s"

#: common/flatpak-oci-registry.c:3369
#, c-format
msgid "Wrong ref (%s) specified for OCI image %s, expected %s"
msgstr "Наведена је погрешна референца (%s) за OCI одраз %s, очекивана је %s"

#: common/flatpak-progress.c:236
#, c-format
msgid "Downloading metadata: %u/(estimating) %s"
msgstr "Преузимање метаподатака: %u/(процењујем) %s"

#: common/flatpak-progress.c:260
#, c-format
msgid "Downloading: %s/%s"
msgstr "Преузимање: %s/%s"

#: common/flatpak-progress.c:280
#, c-format
msgid "Downloading extra data: %s/%s"
msgstr "Преузимање додатних података: %s/%s"

#: common/flatpak-progress.c:285
#, c-format
msgid "Downloading files: %d/%d %s"
msgstr "Преузимање датотека: %d/%d %s"

#: common/flatpak-ref-utils.c:122
msgid "Name can't be empty"
msgstr "Назив не може бити празан"

#: common/flatpak-ref-utils.c:129
msgid "Name can't be longer than 255 characters"
msgstr "Назив не може бити дужи од 255 знакова"

#: common/flatpak-ref-utils.c:142
msgid "Name can't start with a period"
msgstr "Назив не може почињати тачком"

#: common/flatpak-ref-utils.c:148
#, c-format
msgid "Name can't start with %c"
msgstr "Назив не може почињати са %c"

#: common/flatpak-ref-utils.c:164
msgid "Name can't end with a period"
msgstr "Назив не може завршавати тачком"

#: common/flatpak-ref-utils.c:171 common/flatpak-ref-utils.c:183
msgid "Only last name segment can contain -"
msgstr "Само последњи део назива може садржати -"

#: common/flatpak-ref-utils.c:174
#, c-format
msgid "Name segment can't start with %c"
msgstr "Део назива не може почињати са %c"

#: common/flatpak-ref-utils.c:186
#, c-format
msgid "Name can't contain %c"
msgstr "Назив не може садржати %c"

#: common/flatpak-ref-utils.c:195
msgid "Names must contain at least 2 periods"
msgstr "Називи морају садржати барем 2 тачке"

#: common/flatpak-ref-utils.c:312
msgid "Arch can't be empty"
msgstr "Архитектура не може бити празна"

#: common/flatpak-ref-utils.c:323
#, c-format
msgid "Arch can't contain %c"
msgstr "Архитектура не може садржати %c"

#: common/flatpak-ref-utils.c:385
msgid "Branch can't be empty"
msgstr "Грана не може бити празна"

#: common/flatpak-ref-utils.c:395
#, c-format
msgid "Branch can't start with %c"
msgstr "Грана не може почињати са %c"

#: common/flatpak-ref-utils.c:405
#, c-format
msgid "Branch can't contain %c"
msgstr "Грана не може садржати %c"

#: common/flatpak-ref-utils.c:615 common/flatpak-ref-utils.c:865
msgid "Ref too long"
msgstr "Упутница је предугачка"

#: common/flatpak-ref-utils.c:627
msgid "Invalid remote name"
msgstr "Неисправан назив удаљеног извора"

#: common/flatpak-ref-utils.c:641
#, c-format
msgid "%s is not application or runtime"
msgstr "%s није програм нити извршно окружење"

#: common/flatpak-ref-utils.c:650 common/flatpak-ref-utils.c:667
#: common/flatpak-ref-utils.c:683
#, c-format
msgid "Wrong number of components in %s"
msgstr "Погрешан број компоненти у %s"

#: common/flatpak-ref-utils.c:656
#, c-format
msgid "Invalid name %.*s: %s"
msgstr "Неисправан назив %.*s: %s"

#: common/flatpak-ref-utils.c:673
#, c-format
msgid "Invalid arch: %.*s: %s"
msgstr "Неисправна архитектура: %.*s: %s"

#: common/flatpak-ref-utils.c:816
#, c-format
msgid "Invalid name %s: %s"
msgstr "Неисправан назив %s: %s"

#: common/flatpak-ref-utils.c:834
#, c-format
msgid "Invalid arch: %s: %s"
msgstr "Неисправна архитектура: %s: %s"

#: common/flatpak-ref-utils.c:853
#, c-format
msgid "Invalid branch: %s: %s"
msgstr "Неисправна грана: %s: %s"

#: common/flatpak-ref-utils.c:962 common/flatpak-ref-utils.c:970
#: common/flatpak-ref-utils.c:978
#, c-format
msgid "Wrong number of components in partial ref %s"
msgstr "Погрешан број компоненти у делимичној референци %s"

#: common/flatpak-ref-utils.c:1298
msgid " development platform"
msgstr " развојна платформа"

#: common/flatpak-ref-utils.c:1300
msgid " platform"
msgstr " платформа"

#: common/flatpak-ref-utils.c:1302
msgid " application base"
msgstr " основа програма"

#: common/flatpak-ref-utils.c:1305
msgid " debug symbols"
msgstr " симболи за исправљање грешака"

#: common/flatpak-ref-utils.c:1307
msgid " sourcecode"
msgstr " изворни код"

#: common/flatpak-ref-utils.c:1309
msgid " translations"
msgstr " преводи"

#: common/flatpak-ref-utils.c:1311
msgid " docs"
msgstr " документација"

#: common/flatpak-ref-utils.c:1578
#, c-format
msgid "Invalid id %s: %s"
msgstr "Неисправан ид %s: %s"

#: common/flatpak-remote.c:1216
#, c-format
msgid "Bad remote name: %s"
msgstr "Лош назив удаљеног места: %s"

#: common/flatpak-remote.c:1220
msgid "No URL specified"
msgstr "Није наведена адреса"

#: common/flatpak-remote.c:1266
msgid "GPG verification must be enabled when a collection ID is set"
msgstr "ГПГ провера мора бити омогућена када је подешен ИД збирке"

#: common/flatpak-repo-utils.c:344
#, c-format
msgid "No extra data sources"
msgstr "Нема додатних извора података"

#: common/flatpak-repo-utils.c:2817
#, c-format
msgid "Invalid %s: Missing group ‘%s’"
msgstr "Неисправан %s: Недостаје група „%s“"

#: common/flatpak-repo-utils.c:2826
#, c-format
msgid "Invalid %s: Missing key ‘%s’"
msgstr "Неисправан %s: Недостаје кључ „%s“"

#: common/flatpak-repo-utils.c:2876
msgid "Invalid gpg key"
msgstr "Неисправан ГПГ кључ"

#: common/flatpak-repo-utils.c:3217
#, c-format
msgid "Error copying 64x64 icon for component %s: %s\n"
msgstr "Грешка при умножавању иконице 64x64 за компоненту %s: %s\n"

#: common/flatpak-repo-utils.c:3223
#, c-format
msgid "Error copying 128x128 icon for component %s: %s\n"
msgstr "Грешка при умножавању иконице 128x128 за компоненту %s: %s\n"

#: common/flatpak-repo-utils.c:3362
#, c-format
msgid "%s is end-of-life, ignoring for appstream"
msgstr "%s је на крају животног века, занемарујем за апстрим"

#: common/flatpak-repo-utils.c:3397
#, c-format
msgid "No appstream data for %s: %s\n"
msgstr "Нема апстрим података за %s: %s\n"

#: common/flatpak-repo-utils.c:3744
msgid "Invalid bundle, no ref in metadata"
msgstr "Неисправан комплет, нема упуте у метаподацима"

#: common/flatpak-repo-utils.c:3846
#, c-format
msgid "Collection ‘%s’ of bundle doesn’t match collection ‘%s’ of remote"
msgstr "Збирка „%s“ комплета се не поклапа са збирком „%s“ удаљеног места"

#: common/flatpak-repo-utils.c:3923
msgid "Metadata in header and app are inconsistent"
msgstr "Метаподаци у заглављу и програму су недоследни"

#: common/flatpak-run.c:951
msgid "No systemd user session available, cgroups not available"
msgstr "Корисничка сесија система-д није доступна, ц-групе нису доступне"

#: common/flatpak-run.c:1496
msgid "Unable to allocate instance id"
msgstr "Не могу да доделим ИБ примерка"

#: common/flatpak-run.c:1632 common/flatpak-run.c:1641
#, c-format
msgid "Failed to open flatpak-info file: %s"
msgstr "Није успело отварање датотеке „flatpak-info“: %s"

#: common/flatpak-run.c:1668
#, c-format
msgid "Failed to open bwrapinfo.json file: %s"
msgstr "Није успело отварање датотеке „bwrapinfo.json“: %s"

#: common/flatpak-run.c:1689
#, c-format
msgid "Failed to write to instance id fd: %s"
msgstr "Није успело писање у ФД ИБ-а примерка: %s"

#: common/flatpak-run.c:2096
msgid "Initialize seccomp failed"
msgstr "Покретање seccomp-a није успело"

#: common/flatpak-run.c:2135
#, c-format
msgid "Failed to add architecture to seccomp filter: %s"
msgstr "Није успело додавање архитектуре у филтер seccomp-a: %s"

#: common/flatpak-run.c:2143
#, c-format
msgid "Failed to add multiarch architecture to seccomp filter: %s"
msgstr "Није успело додавање мултиарх архитектуре у филтер seccomp-a: %s"

#: common/flatpak-run.c:2175 common/flatpak-run.c:2192
#: common/flatpak-run.c:2214
#, c-format
msgid "Failed to block syscall %d: %s"
msgstr "Није успело блокирање системског позива %d: %s"

#: common/flatpak-run.c:2247
#, c-format
msgid "Failed to export bpf: %s"
msgstr "Није успело извожење бпф-а: %s"

#: common/flatpak-run.c:2587
#, c-format
msgid "Failed to open ‘%s’"
msgstr "Нисам успео да отворим „%s“"

#: common/flatpak-run.c:2597
#, c-format
msgid ""
"Directory forwarding needs version 4 of the document portal (have version %d)"
msgstr ""
"Прослеђивање директоријума захтева издање 4 портала докумената (имате издање "
"%d)"

#: common/flatpak-run.c:2915
#, c-format
msgid "ldconfig failed, exit status %d"
msgstr "„ldconfig“ није успео, излазно стање %d"

#: common/flatpak-run.c:2922
msgid "Can't open generated ld.so.cache"
msgstr "Не могу да отворим створену „ld.so.cache“ оставу"

#. Translators: The placeholder is for an app ref.
#: common/flatpak-run.c:3045
#, c-format
msgid "Running %s is not allowed by the policy set by your administrator"
msgstr ""
"Покретање „%s“ није дозвољено политиком коју је поставио ваш администратор"

#: common/flatpak-run.c:3202
msgid ""
"\"flatpak run\" is not intended to be run as `sudo flatpak run`. Use `sudo "
"-i` or `su -l` instead and invoke \"flatpak run\" from inside the new shell."
msgstr ""
"„flatpak run“ није предвиђен за покретање као „sudo flatpak run“. Користите "
"„sudo -i“ или „su -l“ уместо тога и позовите „flatpak run“ унутар нове "
"шкољке."

#: common/flatpak-run.c:3413
#, c-format
msgid "Failed to migrate from %s: %s"
msgstr "Нисам успео да преселим са %s: %s"

#: common/flatpak-run.c:3434
#, c-format
msgid "Failed to migrate old app data directory %s to new name %s: %s"
msgstr ""
"Нисам успео да преселим стари директоријум података програма %s у нови назив "
"%s: %s"

#: common/flatpak-run.c:3443
#, c-format
msgid "Failed to create symlink while migrating %s: %s"
msgstr "Нисам успео да направим симболичку везу приликом пресељења %s: %s"

#: common/flatpak-run-dbus.c:46
msgid "Failed to open app info file"
msgstr "Нисам успео да отворим датотеку са подацима о програму"

#: common/flatpak-run-dbus.c:149
msgid "Unable to create sync pipe"
msgstr "Не могу да направим спојку за усклађивање"

#: common/flatpak-run-dbus.c:185
msgid "Failed to sync with dbus proxy"
msgstr "Нисам успео да се ускладим са d-bus посредником"

#: common/flatpak-transaction.c:2275
#, c-format
msgid "Warning: Problem looking for related refs: %s"
msgstr "Упозорење: Проблем при тражењу повезаних референци: %s"

#: common/flatpak-transaction.c:2493
#, c-format
msgid "The application %s requires the runtime %s which was not found"
msgstr "Програм %s захтева извршно окружење %s које није пронађено"

#: common/flatpak-transaction.c:2509
#, c-format
msgid "The application %s requires the runtime %s which is not installed"
msgstr "Програм %s захтева извршно окружење %s које није инсталирано"

#: common/flatpak-transaction.c:2641
#, c-format
msgid "Can't uninstall %s which is needed by %s"
msgstr "Не могу да уклоним %s који је потребан програму %s"

#: common/flatpak-transaction.c:2740
#, c-format
msgid "Remote %s disabled, ignoring %s update"
msgstr "Удаљено место %s је онемогућено, занемарујем освежење за %s"

#: common/flatpak-transaction.c:2773
#, c-format
msgid "%s is already installed"
msgstr "%s је већ инсталиран"

#: common/flatpak-transaction.c:2776
#, c-format
msgid "%s is already installed from remote %s"
msgstr "%s је већ инсталиран са удаљеног места %s"

#: common/flatpak-transaction.c:3120
#, c-format
msgid "Invalid .flatpakref: %s"
msgstr "Неисправан .flatpakref: %s"

#: common/flatpak-transaction.c:3161
msgid "Warning: Could not mark already installed apps as preinstalled"
msgstr ""
"Упозорење: Не могу да означим већ инсталиране програме као преинсталиране"

#: common/flatpak-transaction.c:3382
#, c-format
msgid "Error updating remote metadata for '%s': %s"
msgstr "Грешка при ажурирању удаљених метаподатака за „%s“: %s"

#: common/flatpak-transaction.c:3885
#, c-format
msgid ""
"Warning: Treating remote fetch error as non-fatal since %s is already "
"installed: %s"
msgstr ""
"Упозорење: Сматрам грешку добавиљања са удаљеног места не-кобном јер је %s "
"већ инсталиран: %s"

#: common/flatpak-transaction.c:4209
#, c-format
msgid "No authenticator installed for remote '%s'"
msgstr "Није инсталиран потврђивач за удаљено место „%s“"

#: common/flatpak-transaction.c:4313 common/flatpak-transaction.c:4320
#, c-format
msgid "Failed to get tokens for ref: %s"
msgstr "Нисам успео да добавим токен за референцу: %s"

#: common/flatpak-transaction.c:4315 common/flatpak-transaction.c:4322
msgid "Failed to get tokens for ref"
msgstr "Нисам успео да добавим токен за референцу"

#: common/flatpak-transaction.c:4580
#, c-format
msgid "Ref %s from %s matches more than one transaction operation"
msgstr "Референца %s са %s се поклапа са више од једне радње преноса"

#: common/flatpak-transaction.c:4581 common/flatpak-transaction.c:4591
msgid "any remote"
msgstr "било које удаљено место"

#: common/flatpak-transaction.c:4590
#, c-format
msgid "No transaction operation found for ref %s from %s"
msgstr "Није пронађена радња преноса за референцу %s са %s"

#: common/flatpak-transaction.c:4713
#, c-format
msgid "Flatpakrepo URL %s not file, HTTP or HTTPS"
msgstr "Адреса flatpakrepo-а %s није датотека, ХТТП или ХТТПС"

#: common/flatpak-transaction.c:4719
#, c-format
msgid "Can't load dependent file %s: "
msgstr "Не могу да учитам зависну датотеку %s: "

#: common/flatpak-transaction.c:4727
#, c-format
msgid "Invalid .flatpakrepo: %s"
msgstr "Неисправан .flatpakrepo: %s"

#: common/flatpak-transaction.c:5454
msgid "Transaction already executed"
msgstr "Пренос је већ извршен"

#: common/flatpak-transaction.c:5469
msgid ""
"Refusing to operate on a user installation as root! This can lead to "
"incorrect file ownership and permission errors."
msgstr ""
"Одбијам да радим на корисничкој инсталацији као администратор (root)! Ово "
"може довести до нетачног власништва над датотекама и грешака у овлашћењима."

#: common/flatpak-transaction.c:5567 common/flatpak-transaction.c:5580
msgid "Aborted by user"
msgstr "Прекинуо корисник"

#: common/flatpak-transaction.c:5605
#, c-format
msgid "Skipping %s due to previous error"
msgstr "Прескачем %s због претходне грешке"

#: common/flatpak-transaction.c:5659
#, c-format
msgid "Aborted due to failure (%s)"
msgstr "Прекинуто због неуспеха (%s)"

#: common/flatpak-uri.c:118
#, no-c-format
msgid "Invalid %-encoding in URI"
msgstr "Неисправно %-кодирање у адреси (URI)"

#: common/flatpak-uri.c:135
msgid "Illegal character in URI"
msgstr "Недозвољени знак у адреси (URI)"

#: common/flatpak-uri.c:169
msgid "Non-UTF-8 characters in URI"
msgstr "Не-УТФ-8 знакови у адреси (URI)"

#: common/flatpak-uri.c:275
#, c-format
msgid "Invalid IPv6 address ‘%.*s’ in URI"
msgstr "Неисправна IPv6 адреса „%.*s“ у УРИ-ју"

#: common/flatpak-uri.c:330
#, c-format
msgid "Illegal encoded IP address ‘%.*s’ in URI"
msgstr "Недозвољена кодирана IP адреса „%.*s“ у УРИ-ју"

#: common/flatpak-uri.c:342
#, c-format
msgid "Illegal internationalized hostname ‘%.*s’ in URI"
msgstr "Недозвољен интернационализован назив домаћина „%.*s“ у УРИ-ју"

#: common/flatpak-uri.c:374 common/flatpak-uri.c:386
#, c-format
msgid "Could not parse port ‘%.*s’ in URI"
msgstr "Не могу да обрадим прикључник „%.*s“ у УРИ-ју"

#: common/flatpak-uri.c:393
#, c-format
msgid "Port ‘%.*s’ in URI is out of range"
msgstr "Прикључник „%.*s“ у УРИ-ју је изван опсега"

#: common/flatpak-uri.c:910
msgid "URI is not absolute, and no base URI was provided"
msgstr "УРИ није апсолутан, а основни УРИ није достављен"

#: common/flatpak-usb.c:83
#, c-format
msgid "USB device query 'all' must not have data"
msgstr "Упит USB уређаја „all“ не сме имати податке"

#: common/flatpak-usb.c:102
#, c-format
msgid "USB query rule 'cls' must be in the form CLASS:SUBCLASS or CLASS:*"
msgstr "USB правило упита „cls“ мора бити у облику CLASS:SUBCLASS или CLASS:*"

#: common/flatpak-usb.c:111
#, c-format
msgid "Invalid USB class"
msgstr "Неисправан USB разред"

#: common/flatpak-usb.c:125
#, c-format
msgid "Invalid USB subclass"
msgstr "Неисправан USB подразред"

#: common/flatpak-usb.c:141 common/flatpak-usb.c:148
#, c-format
msgid "USB query rule 'dev' must have a valid 4-digit hexadecimal product id"
msgstr ""
"USB правило упита „dev“ мора имати исправан 4-цифрени хексадецимални ИД "
"производа"

#: common/flatpak-usb.c:164 common/flatpak-usb.c:171
#, c-format
msgid "USB query rule 'vnd' must have a valid 4-digit hexadecimal vendor id"
msgstr ""
"USB правило упита „vnd“ мора имати исправан 4-цифрени хексадецимални ИД "
"продавца"

#: common/flatpak-usb.c:205
#, c-format
msgid "USB device queries must be in the form TYPE:DATA"
msgstr "Упити USB уређаја морају бити у облику TYPE:DATA"

#: common/flatpak-usb.c:225
#, c-format
msgid "Unknown USB query rule %s"
msgstr "Непознато USB правило упита %s"

#: common/flatpak-usb.c:248
#, c-format
msgid "Empty USB query"
msgstr "Празан USB упит"

#: common/flatpak-usb.c:274
#, c-format
msgid "Multiple USB query rules of the same type is not supported"
msgstr "Вишеструка USB правила упита исте врсте нису подржана"

#: common/flatpak-usb.c:283
#, c-format
msgid "'all' must not contain extra query rules"
msgstr "„all“ не сме да садржи додатна правила упита"

#: common/flatpak-usb.c:291
#, c-format
msgid "USB queries with 'dev' must also specify vendors"
msgstr "USB упити са „dev“ морају такође навести продавце"

#: common/flatpak-utils.c:712
msgid "Glob can't match apps"
msgstr "Глоб не може да поклопи програме"

#: common/flatpak-utils.c:737
msgid "Empty glob"
msgstr "Празан глоб"

#: common/flatpak-utils.c:756
msgid "Too many segments in glob"
msgstr "Превише делова у глобу"

#: common/flatpak-utils.c:777
#, c-format
msgid "Invalid glob character '%c'"
msgstr "Неисправан знак глоба „%c“"

#: common/flatpak-utils.c:831
#, c-format
msgid "Missing glob on line %d"
msgstr "Недостаје глоб у %d. реду"

#: common/flatpak-utils.c:835
#, c-format
msgid "Trailing text on line %d"
msgstr "Вишак текста у %d. реду"

#: common/flatpak-utils.c:839
#, c-format
msgid "on line %d"
msgstr "у %d. реду"

#: common/flatpak-utils.c:861
#, c-format
msgid "Unexpected word '%s' on line %d"
msgstr "Неочекивана реч „%s“ у %d. реду"

#: common/flatpak-utils.c:2118
#, c-format
msgid "Invalid require-flatpak argument %s"
msgstr "Неисправан аргумент „require-flatpak“ %s"

#: common/flatpak-utils.c:2128 common/flatpak-utils.c:2147
#, c-format
msgid "%s needs a later flatpak version (%s)"
msgstr "%s захтева новије издање Флетпека (%s)"

#: oci-authenticator/flatpak-oci-authenticator.c:291
msgid "Not a oci remote, missing summary.xa.oci-repository"
msgstr "Није OCI удаљена веза, недостаје „summary.xa.oci-repository“"

#: oci-authenticator/flatpak-oci-authenticator.c:477
msgid "Not a OCI remote"
msgstr "Није OCI удаљена веза"

#: oci-authenticator/flatpak-oci-authenticator.c:488
msgid "Invalid token"
msgstr "Неисправна скупина"

#: portal/flatpak-portal.c:2292
#, c-format
msgid "No portal support found"
msgstr "Није пронађена подршка за портал"

#: portal/flatpak-portal.c:2298
msgid "Deny"
msgstr "Одбиј"

#: portal/flatpak-portal.c:2300
msgid "Update"
msgstr "Ажурирај"

#: portal/flatpak-portal.c:2305
#, c-format
msgid "Update %s?"
msgstr "Ажурирати %s?"

#: portal/flatpak-portal.c:2317
msgid "The application wants to update itself."
msgstr "Програм жели да се ажурира."

#: portal/flatpak-portal.c:2318
msgid "Update access can be changed any time from the privacy settings."
msgstr ""
"Приступ ажурирању се може променити у било ком тренутку у подешавањима "
"приватности."

#: portal/flatpak-portal.c:2343
#, c-format
msgid "Application update not allowed"
msgstr "Ажурирање програма није дозвољено"

#: portal/flatpak-portal.c:2501
#, c-format
msgid "Self update not supported, new version requires new permissions"
msgstr "Самоажурирање није подржано, ново издање захтева нова овлашћења"

#: portal/flatpak-portal.c:2684 portal/flatpak-portal.c:2702
#, c-format
msgid "Update ended unexpectedly"
msgstr "Ажурирање је неочекивано завршено"

#. SECURITY:
#. - Normal users need admin authentication to install software
#. system-wide.
#. - Note that we install polkit rules that allow local users
#. in the wheel group to install without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:23
msgid "Install signed application"
msgstr "Инсталирај потписани програм"

#: system-helper/org.freedesktop.Flatpak.policy.in:24
#: system-helper/org.freedesktop.Flatpak.policy.in:42
msgid "Authentication is required to install software"
msgstr "Потребна је потврда идентитета за инсталирање софтвера"

#. SECURITY:
#. - Normal users need admin authentication to install software
#. system-wide.
#. - Note that we install polkit rules that allow local users
#. in the wheel group to install without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:41
msgid "Install signed runtime"
msgstr "Инсталирај потписано извршно окружење"

#. SECURITY:
#. - Normal users do not require admin authentication to update an
#. app as the commit will be signed, and the action is required
#. to update the system when unattended.
#. - Changing this to anything other than 'yes' will break unattended
#. updates.
#: system-helper/org.freedesktop.Flatpak.policy.in:60
msgid "Update signed application"
msgstr "Ажурирај потписани програм"

#: system-helper/org.freedesktop.Flatpak.policy.in:61
#: system-helper/org.freedesktop.Flatpak.policy.in:80
msgid "Authentication is required to update software"
msgstr "Потребна је потврда идентитета за ажурирање софтвера"

#. SECURITY:
#. - Normal users do not require admin authentication to update a
#. runtime as the commit will be signed, and the action is required
#. to update the system when unattended.
#. - Changing this to anything other than 'yes' will break unattended
#. updates.
#: system-helper/org.freedesktop.Flatpak.policy.in:79
msgid "Update signed runtime"
msgstr "Ажурирај потписано извршно окружење"

#. SECURITY:
#. - Normal users do not need authentication to update metadata
#. from signed repositories.
#: system-helper/org.freedesktop.Flatpak.policy.in:94
msgid "Update remote metadata"
msgstr "Ажурирај удаљене метаподатке"

#: system-helper/org.freedesktop.Flatpak.policy.in:95
msgid "Authentication is required to update remote info"
msgstr "Потребна је потврда идентитета за ажурирање удаљених података"

#. SECURITY:
#. - Normal users do not need authentication to modify the
#. OSTree repository
#. - Note that we install polkit rules that allow local users
#. in the wheel group to modify repos without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:111
msgid "Update system repository"
msgstr "Ажурирај системску ризницу"

#: system-helper/org.freedesktop.Flatpak.policy.in:112
msgid "Authentication is required to modify a system repository"
msgstr "Потребна је потврда идентитета за измену системске ризнице"

#. SECURITY:
#. - Normal users need admin authentication to install software
#. system-wide.
#: system-helper/org.freedesktop.Flatpak.policy.in:126
msgid "Install bundle"
msgstr "Инсталирај пакет"

#: system-helper/org.freedesktop.Flatpak.policy.in:127
msgid "Authentication is required to install software from $(path)"
msgstr "Потребна је потврда идентитета за инсталирање софтвера из $(path)"

#. SECURITY:
#. - Normal users need admin authentication to uninstall software
#. system-wide.
#. - Note that we install polkit rules that allow local users
#. in the wheel group to uninstall without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:144
msgid "Uninstall runtime"
msgstr "Уклони извршно окружење"

#: system-helper/org.freedesktop.Flatpak.policy.in:145
msgid "Authentication is required to uninstall software"
msgstr "Потребна је потврда идентитета за уклањање софтвера"

#. SECURITY:
#. - Normal users need admin authentication to uninstall software
#. system-wide.
#. - Note that we install polkit rules that allow local users
#. in the wheel group to uninstall without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:161
msgid "Uninstall app"
msgstr "Деинсталирај програм"

#: system-helper/org.freedesktop.Flatpak.policy.in:162
msgid "Authentication is required to uninstall $(ref)"
msgstr "Потребна је потврда идентитета за уклањање $(ref)"

#. SECURITY:
#. - Normal users need admin authentication to configure system-wide
#. software repositories.
#: system-helper/org.freedesktop.Flatpak.policy.in:177
msgid "Configure Remote"
msgstr "Подеси удаљену везу"

#: system-helper/org.freedesktop.Flatpak.policy.in:178
msgid "Authentication is required to configure software repositories"
msgstr "Потребна је потврда идентитета за подешавање ризница софтвера"

#. SECURITY:
#. - Normal users need admin authentication to configure the system-wide
#. Flatpak installation.
#: system-helper/org.freedesktop.Flatpak.policy.in:192
msgid "Configure"
msgstr "Подеси"

#: system-helper/org.freedesktop.Flatpak.policy.in:193
msgid "Authentication is required to configure software installation"
msgstr "Потребна је потврда идентитета за подешавање инсталације софтвера"

#. SECURITY:
#. - Normal users do not require admin authentication to update
#. appstream data as it will be signed, and the action is required
#. to update the system when unattended.
#. - Changing this to anything other than 'yes' will break unattended
#. updates.
#: system-helper/org.freedesktop.Flatpak.policy.in:210
msgid "Update appstream"
msgstr "Ажурирај „appstream“"

#: system-helper/org.freedesktop.Flatpak.policy.in:211
msgid "Authentication is required to update information about software"
msgstr "Потребна је потврда идентитета за ажурирање података о софтверу"

#. SECURITY:
#. - Normal users do not require admin authentication to update
#. metadata as it will be signed, and the action is required
#. to update the system when unattended.
#. - Changing this to anything other than 'yes' will break unattended
#. updates.
#: system-helper/org.freedesktop.Flatpak.policy.in:228
msgid "Update metadata"
msgstr "Ажурирај метаподатке"

#: system-helper/org.freedesktop.Flatpak.policy.in:229
msgid "Authentication is required to update metadata"
msgstr "Потребна је потврда идентитета за ажурирање метаподатака"

#. SECURITY:
#. - Authorisation to actually install software is controlled by
#. org.freedesktop.Flatpak.app-install.
#. - This action is checked after app-install, as it can only be done
#. once the app’s data (including its content rating) has been
#. downloaded.
#. - This action is checked to see if the installation should be allowed
#. based on whether the app being installed has content which doesn’t
#. comply with the user’s parental controls policy (the content is
#. ‘too extreme’).
#. - It is checked only if an app has too extreme content for the user
#. who is trying to install it (in which case, the app is ‘unsafe’).
#. - Typically, normal users will need admin permission to install apps
#. with extreme content; admins will be able to install it without
#. additional checks.
#. - In order to configure the policy so that admins can install safe and
#. unsafe software anywhere without authorisation, and non-admins can
#. install safe software in their user or system dirs without
#. authorisation, but need authorisation to install unsafe software
#. anywhere:
#. * Unconditionally return `yes` from `app-install`.
#. * Return `auth_admin` from `override-parental-controls` for users
#. not in `@privileged_group@`, and `yes` for users in it.
#. * Set the malcontent `is-{user,system}-installation-allowed`
#. properties of all non-admins’ parental controls policies to true.
#. - In order to configure the policy so that admins can install safe and
#. unsafe software anywhere without authorisation, and non-admins can
#. install safe software in their user dir without authorisation, but
#. need authorisation to install safe software in the system dir or to
#. install unsafe software anywhere:
#. * Unconditionally return `yes` from `app-install`.
#. * Return `auth_admin` from `override-parental-controls` for users
#. not in `@privileged_group@`, and `yes` for users in it.
#. * Set the malcontent `is-user-installation-allowed` property of all
#. non-admins’ parental controls policies to true.
#. * Set the malcontent `is-system-installation-allowed` property of
#. all non-admins’ parental controls policies to false.
#. - In order to configure the policy so that all users (including
#. admins) can install safe software anywhere without authorisation,
#. but need authorisation to install unsafe software anywhere (i.e.
#. applying parental controls to admins too):
#. * Unconditionally return `yes` from `app-install`.
#. * Unconditionally return `auth_admin` from `override-parental-controls`.
#. * Set the malcontent `is-user-installation-allowed` property of all
#. users’ parental controls policies to true.
#. * Set the malcontent `is-system-installation-allowed` property of
#. all users’ parental controls policies to true.
#: system-helper/org.freedesktop.Flatpak.policy.in:287
msgid "Override parental controls for installs"
msgstr "Премости родитељски надзор за инсталације"

#: system-helper/org.freedesktop.Flatpak.policy.in:288
msgid ""
"Authentication is required to install software which is restricted by your "
"parental controls policy"
msgstr ""
"Потребна је потврда идентитета за инсталирање софтвера који је ограничен "
"вашим родитељским надзором"

#. SECURITY:
#. - This is like org.freedesktop.Flatpak.override-parental-controls, but
#. it’s queried for app updates, whereas the former is queried for app
#. installs.
#. - As with the above action, this one is only queried if
#. org.freedesktop.Flatpak.app-update has allowed the app update, and
#. only if the app being updated has too extreme content for the user
#. who is trying to update it.
#. - The default policy for this is to *allow* updates to ‘too extreme’
#. apps by default, on the basis that having an out-of-date (i.e.
#. insecure or unsupported) app is a worse outcome than automatically
#. installing an update which has radically different content from the
#. version of the app which the parent originally vetted and installed.
#: system-helper/org.freedesktop.Flatpak.policy.in:313
msgid "Override parental controls for updates"
msgstr "Премости родитељски надзор за ажурирања"

#: system-helper/org.freedesktop.Flatpak.policy.in:314
msgid ""
"Authentication is required to update software which is restricted by your "
"parental controls policy"
msgstr ""
"Потребна је потврда идентитета за ажурирање софтвера који је ограничен вашим "
"родитељским надзором"

===== ./po/es.po =====
# Spanish translation for flatpak.
# Copyright (C) 2017 THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the flatpak package.
# Aitor González Fernández <reimashi@gmail.com>, 2017.
# Rodrigo Lledó <rodhos92@gmail.com>, 2020.
# Daniel Mustieles <daniel.mustieles@gmail.com>, 2020.
#
msgid ""
msgstr ""
"Project-Id-Version: flatpak master\n"
"Report-Msgid-Bugs-To: https://github.com/flatpak/flatpak/issues\n"
"POT-Creation-Date: 2026-05-27 16:39+0200\n"
"PO-Revision-Date: 2023-02-12 21:33+0100\n"
"Last-Translator: Rodrigo Lledó Milanca <rodhos92@gmail.com>\n"
"Language-Team: Spanish - Spain <gnome-es-list@gnome.org>\n"
"Language: es\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Generator: Poedit 3.2.2\n"

#: app/flatpak-builtins-build-bundle.c:59
msgid "Export runtime instead of app"
msgstr "Exportar la rutina en tiempo de ejecución en lugar de la aplicación"

#: app/flatpak-builtins-build-bundle.c:60
msgid "Arch to bundle for"
msgstr "Arquitectura para la que empaquetar"

#: app/flatpak-builtins-build-bundle.c:60
#: app/flatpak-builtins-build-export.c:62 app/flatpak-builtins-build-init.c:53
#: app/flatpak-builtins-build-sign.c:42 app/flatpak-builtins-create-usb.c:46
#: app/flatpak-builtins-info.c:55 app/flatpak-builtins-install.c:67
#: app/flatpak-builtins-list.c:50 app/flatpak-builtins-make-current.c:38
#: app/flatpak-builtins-remote-info.c:54 app/flatpak-builtins-remote-ls.c:56
#: app/flatpak-builtins-run.c:158 app/flatpak-builtins-search.c:37
#: app/flatpak-builtins-uninstall.c:54 app/flatpak-builtins-update.c:56
msgid "ARCH"
msgstr "ARQUITECTURA"

#: app/flatpak-builtins-build-bundle.c:61
#, fuzzy
msgid "URL for repo"
msgstr "Url del repositorio"

#: app/flatpak-builtins-build-bundle.c:61
#: app/flatpak-builtins-build-bundle.c:62
#: app/flatpak-builtins-build-update-repo.c:68
#: app/flatpak-builtins-build-update-repo.c:72
#: app/flatpak-builtins-build-update-repo.c:73
#: app/flatpak-builtins-history.c:69 app/flatpak-builtins-remote-add.c:80
#: app/flatpak-builtins-remote-add.c:81 app/flatpak-builtins-remote-add.c:85
#: app/flatpak-builtins-remote-list.c:53
#: app/flatpak-builtins-remote-modify.c:70
#: app/flatpak-builtins-remote-modify.c:85
#: app/flatpak-builtins-remote-modify.c:86
#: app/flatpak-builtins-remote-modify.c:90
msgid "URL"
msgstr "URL"

#: app/flatpak-builtins-build-bundle.c:62
#, fuzzy
msgid "URL for runtime flatpakrepo file"
msgstr "Url del archivo flatpakrepo la rutina en tiempo de ejecución"

#: app/flatpak-builtins-build-bundle.c:63
msgid "Add GPG key from FILE (- for stdin)"
msgstr "Añadir clave GPG desde ARCHIVO (- para stdin)"

#: app/flatpak-builtins-build-bundle.c:63 app/flatpak-builtins-build.c:54
#: app/flatpak-builtins-build-export.c:67
#: app/flatpak-builtins-build-update-repo.c:83
#: app/flatpak-builtins-install.c:81 app/flatpak-builtins-remote-add.c:84
#: app/flatpak-builtins-remote-add.c:86 app/flatpak-builtins-remote-modify.c:89
#: app/flatpak-builtins-remote-modify.c:92
msgid "FILE"
msgstr "ARCHIVO"

#: app/flatpak-builtins-build-bundle.c:64
msgid "GPG Key ID to sign the OCI image with"
msgstr "ID de la clave GPG con la que firmar la imagen OCI"

#: app/flatpak-builtins-build-bundle.c:64
#: app/flatpak-builtins-build-commit-from.c:68
#: app/flatpak-builtins-build-export.c:68
#: app/flatpak-builtins-build-import-bundle.c:49
#: app/flatpak-builtins-build-sign.c:44
#: app/flatpak-builtins-build-update-repo.c:84
msgid "KEY-ID"
msgstr "ID-CLAVE"

# "Llaveros" is the literal translate of keyrings, but in spanish don't mean exactly the same in software slang. A more correct translation would be "repositorios de claves" that means "key repositories".
#: app/flatpak-builtins-build-bundle.c:65
#: app/flatpak-builtins-build-commit-from.c:69
#: app/flatpak-builtins-build-export.c:71
#: app/flatpak-builtins-build-import-bundle.c:50
#: app/flatpak-builtins-build-sign.c:45
#: app/flatpak-builtins-build-update-repo.c:85
msgid "GPG Homedir to use when looking for keyrings"
msgstr "Carpeta de inicio de GPG que usar al buscar depósitos de claves"

#: app/flatpak-builtins-build-bundle.c:65
#: app/flatpak-builtins-build-commit-from.c:69
#: app/flatpak-builtins-build-export.c:71
#: app/flatpak-builtins-build-import-bundle.c:50
#: app/flatpak-builtins-build-sign.c:45
#: app/flatpak-builtins-build-update-repo.c:85
msgid "HOMEDIR"
msgstr "CARPETA_DE_INICIO"

#: app/flatpak-builtins-build-bundle.c:66
msgid "OSTree commit to create a delta bundle from"
msgstr "Commit de OSTree desde el que crear un paquete de diferencias"

#: app/flatpak-builtins-build-bundle.c:66 app/flatpak-builtins-remote-info.c:55
#: app/flatpak-builtins-update.c:57
msgid "COMMIT"
msgstr "COMMIT"

#: app/flatpak-builtins-build-bundle.c:67
msgid "Export oci image instead of flatpak bundle"
msgstr "Exportar una imagen oci en lugar de un paquete flatpak"

#: app/flatpak-builtins-build-bundle.c:70
msgid "How to compress OCI image layers (default: gzip)"
msgstr ""

#: app/flatpak-builtins-build-bundle.c:634
msgid ""
"LOCATION FILENAME NAME [BRANCH] - Create a single file bundle from a local "
"repository"
msgstr ""
"UBICACIÓN NOMBRE_ARCHIVO NOMBRE [RAMA] - Crear un paquete único desde un "
"repositorio local"

#: app/flatpak-builtins-build-bundle.c:641
msgid "LOCATION, FILENAME and NAME must be specified"
msgstr "Se deben especificar UBICACIÓN, NOMBRE_ARCHIVO y NOMBRE"

#: app/flatpak-builtins-build-bundle.c:644
#: app/flatpak-builtins-build-export.c:844
#: app/flatpak-builtins-build-import-bundle.c:136
#: app/flatpak-builtins-build-init.c:217 app/flatpak-builtins-build-sign.c:76
#: app/flatpak-builtins-document-export.c:112
#: app/flatpak-builtins-document-info.c:75
#: app/flatpak-builtins-document-list.c:191
#: app/flatpak-builtins-document-unexport.c:70
#: app/flatpak-builtins-history.c:482 app/flatpak-builtins-info.c:130
#: app/flatpak-builtins-install.c:181 app/flatpak-builtins-install.c:234
#: app/flatpak-builtins-install.c:298 app/flatpak-builtins-list.c:419
#: app/flatpak-builtins-make-current.c:72 app/flatpak-builtins-override.c:73
#: app/flatpak-builtins-permission-list.c:162
#: app/flatpak-builtins-permission-remove.c:132
#: app/flatpak-builtins-remote-add.c:323
#: app/flatpak-builtins-remote-delete.c:68
#: app/flatpak-builtins-remote-list.c:241 app/flatpak-builtins-remote-ls.c:407
msgid "Too many arguments"
msgstr "Demasiados argumentos"

#: app/flatpak-builtins-build-bundle.c:659
#: app/flatpak-builtins-build-commit-from.c:338
#: app/flatpak-builtins-build-commit-from.c:351
#: app/flatpak-builtins-build-import-bundle.c:145
#, c-format
msgid "'%s' is not a valid repository"
msgstr "«%s» no es un repositorio válido"

#: app/flatpak-builtins-build-bundle.c:663
#, c-format
msgid "'%s' is not a valid repository: "
msgstr "«%s» no es un repositorio válido: "

#: app/flatpak-builtins-build-bundle.c:674 app/flatpak-builtins-build-sign.c:88
#: common/flatpak-dir.c:14293
#, c-format
msgid "'%s' is not a valid name: %s"
msgstr "«%s» no es un nombre válido: %s"

#: app/flatpak-builtins-build-bundle.c:677
#: app/flatpak-builtins-build-export.c:865 app/flatpak-builtins-build-sign.c:91
#: common/flatpak-dir.c:14299
#, c-format
msgid "'%s' is not a valid branch name: %s"
msgstr "«%s» no es un nombre de rama válido: %s"

#: app/flatpak-builtins-build-bundle.c:691
#: app/flatpak-builtins-build-import-bundle.c:149
#: app/flatpak-builtins-build-init.c:281
#, c-format
msgid "'%s' is not a valid filename"
msgstr "«%s» no es un nombre de archivo válido"

#: app/flatpak-builtins-build-bundle.c:706
msgid "--oci-layer-compress value must be gzip or zstd"
msgstr ""

#: app/flatpak-builtins-build.c:49
msgid "Use Platform runtime rather than Sdk"
msgstr ""
"Usar la rutina en tiempo de ejecución de la plataforma en lugar del Sdk"

#: app/flatpak-builtins-build.c:50
msgid "Make destination readonly"
msgstr "Hacer que el destino sea de sólo lectura"

#: app/flatpak-builtins-build.c:51
msgid "Add bind mount"
msgstr "Añadir punto de montaje"

#: app/flatpak-builtins-build.c:51
msgid "DEST=SRC"
msgstr "DEST=ORIG"

#: app/flatpak-builtins-build.c:52
msgid "Start build in this directory"
msgstr "Iniciar la compilación en esta carpeta"

#: app/flatpak-builtins-build.c:52 app/flatpak-builtins-build.c:53
#: app/flatpak-builtins-build-init.c:64 app/flatpak-builtins-run.c:160
msgid "DIR"
msgstr "CARPETA"

#: app/flatpak-builtins-build.c:53
msgid "Where to look for custom sdk dir (defaults to 'usr')"
msgstr "Donde buscar la carpeta personalizada de SDK (predeterminado: «usr»)"

#: app/flatpak-builtins-build.c:54 app/flatpak-builtins-build-export.c:67
msgid "Use alternative file for the metadata"
msgstr "Usar un archivo alternativo para los metadatos"

#: app/flatpak-builtins-build.c:55 app/flatpak-builtins-run.c:177
msgid "Kill processes when the parent process dies"
msgstr "Matar los procesos cuando el proceso padre muere"

#: app/flatpak-builtins-build.c:56
msgid "Export application homedir directory to build"
msgstr "Exportar la carpeta de inicio de la aplicación que construir"

#: app/flatpak-builtins-build.c:57 app/flatpak-builtins-run.c:165
msgid "Log session bus calls"
msgstr "Llamadas al bus de registro de sesión"

#: app/flatpak-builtins-build.c:58 app/flatpak-builtins-run.c:166
msgid "Log system bus calls"
msgstr "Llamadas al bus de registro de sistema"

#: app/flatpak-builtins-build.c:262
msgid "DIRECTORY [COMMAND [ARGUMENT…]] - Build in directory"
msgstr "CARPETA [COMANDO [ARGUMENTO…]] - Compilar en la carpeta"

#: app/flatpak-builtins-build.c:285 app/flatpak-builtins-build-finish.c:656
msgid "DIRECTORY must be specified"
msgstr "Se debe especificar la CARPETA"

#: app/flatpak-builtins-build.c:296 app/flatpak-builtins-build-export.c:887
#, c-format
msgid "Build directory %s not initialized, use flatpak build-init"
msgstr ""
"La carpeta de compilación %s no está inicializada, use el comando flatpak "
"build-init"

#: app/flatpak-builtins-build.c:315
msgid "metadata invalid, not application or runtime"
msgstr "metadatos no válidos, sin aplicación o «runtime»"

#: app/flatpak-builtins-build.c:446
#, c-format
msgid "No extension point matching %s in %s"
msgstr "No hay un punto de extensión que coincida con %s en %s"

#: app/flatpak-builtins-build.c:635
#, c-format
msgid "Missing '=' in bind mount option '%s'"
msgstr "Falta un «=» en las opciones del punto de montaje «%s»"

#: app/flatpak-builtins-build.c:679 common/flatpak-run.c:3961
#, c-format
msgid "Unable to start app"
msgstr "No se pudo iniciar la aplicación"

#: app/flatpak-builtins-build-commit-from.c:58
msgid "Source repo dir"
msgstr "Carpeta del repositorio de código fuente"

#: app/flatpak-builtins-build-commit-from.c:58
msgid "SRC-REPO"
msgstr "SRC-REPO"

#: app/flatpak-builtins-build-commit-from.c:59
msgid "Source repo ref"
msgstr "Referencia del repositorio de código fuente"

#: app/flatpak-builtins-build-commit-from.c:59
msgid "SRC-REF"
msgstr "SRC-REF"

#: app/flatpak-builtins-build-commit-from.c:64
#: app/flatpak-builtins-build-export.c:60
msgid "One line subject"
msgstr "Tema en una línea"

#: app/flatpak-builtins-build-commit-from.c:64
#: app/flatpak-builtins-build-export.c:60
msgid "SUBJECT"
msgstr "TEMA"

#: app/flatpak-builtins-build-commit-from.c:65
#: app/flatpak-builtins-build-export.c:61
msgid "Full description"
msgstr "Descripción completa"

#: app/flatpak-builtins-build-commit-from.c:65
#: app/flatpak-builtins-build-export.c:61
msgid "BODY"
msgstr "CUERPO"

#: app/flatpak-builtins-build-commit-from.c:66
#: app/flatpak-builtins-build-export.c:64
#: app/flatpak-builtins-build-import-bundle.c:51
msgid "Update the appstream branch"
msgstr "Actualizar la rama de appstream"

#: app/flatpak-builtins-build-commit-from.c:67
#: app/flatpak-builtins-build-export.c:65
#: app/flatpak-builtins-build-import-bundle.c:52
#: app/flatpak-builtins-build-update-repo.c:87
msgid "Don't update the summary"
msgstr "No actualizar el resumen"

#: app/flatpak-builtins-build-commit-from.c:68
#: app/flatpak-builtins-build-export.c:68
#: app/flatpak-builtins-build-import-bundle.c:49
#: app/flatpak-builtins-build-sign.c:44
msgid "GPG Key ID to sign the commit with"
msgstr "ID de la clave GPG con la que firmar el«commit»"

#: app/flatpak-builtins-build-commit-from.c:70
#: app/flatpak-builtins-build-export.c:73
msgid "Mark build as end-of-life"
msgstr "Marcar la versión como fin de ciclo"

#: app/flatpak-builtins-build-commit-from.c:70
#: app/flatpak-builtins-build-export.c:73
msgid "REASON"
msgstr "RAZÓN"

#: app/flatpak-builtins-build-commit-from.c:71
msgid ""
"Mark refs matching the OLDID prefix as end-of-life, to be replaced with the "
"given NEWID"
msgstr ""
"Hacer que las referencias que coinciden con el prefijo OLDID como fin de "
"ciclo se reemplacen con el NEWID dado"

#: app/flatpak-builtins-build-commit-from.c:71
msgid "OLDID=NEWID"
msgstr "OLDID=NEWID"

#: app/flatpak-builtins-build-commit-from.c:72
#: app/flatpak-builtins-build-export.c:75
msgid "Set type of token needed to install this commit"
msgstr "Establecer el tipo de testigo necesario para instalar este «commit»"

#: app/flatpak-builtins-build-commit-from.c:72
#: app/flatpak-builtins-build-export.c:75
msgid "VAL"
msgstr "VAL"

#: app/flatpak-builtins-build-commit-from.c:73
msgid "Override the timestamp of the commit (NOW for current time)"
msgstr "Sobrescribir la marca de tiempo del «commit» (NOW para la hora actual)"

#: app/flatpak-builtins-build-commit-from.c:73
#: app/flatpak-builtins-build-export.c:76
msgid "TIMESTAMP"
msgstr "MARCA_DE_TIEMPO"

#: app/flatpak-builtins-build-commit-from.c:75
#: app/flatpak-builtins-build-export.c:80
#: app/flatpak-builtins-build-import-bundle.c:53
#: app/flatpak-builtins-build-update-repo.c:97
msgid "Don't generate a summary index"
msgstr "No generar un índice de resumen"

#: app/flatpak-builtins-build-commit-from.c:278
msgid "DST-REPO [DST-REF…] - Make a new commit from existing commits"
msgstr ""
"REPO-DEST [REF-DEST…] - Realiza un «commit» nuevo basado en en los «commit» "
"existentes"

#: app/flatpak-builtins-build-commit-from.c:285
msgid "DST-REPO must be specified"
msgstr "Se debe especificar REPO-DEST"

#: app/flatpak-builtins-build-commit-from.c:293
msgid ""
"If --src-repo is not specified, exactly one destination ref must be specified"
msgstr ""
"Si no se especifica --src-repo, se debe especificar exactamente una "
"referencia de destino"

#: app/flatpak-builtins-build-commit-from.c:296
msgid ""
"If --src-ref is specified, exactly one destination ref must be specified"
msgstr ""
"Si se especifica --src-ref, se debe especificar exactamente una referencia "
"de destino"

#: app/flatpak-builtins-build-commit-from.c:299
msgid "Either --src-repo or --src-ref must be specified"
msgstr "Se debe especificar --src-repo o -src-ref"

#: app/flatpak-builtins-build-commit-from.c:315
msgid "Invalid argument format of use  --end-of-life-rebase=OLDID=NEWID"
msgstr ""
"Formato de argumento no válido usado en  --end-of-life-"
"rebase=IDANTERIOR=IDNUEVO"

#: app/flatpak-builtins-build-commit-from.c:321
#: app/flatpak-builtins-build-commit-from.c:324
#, c-format
msgid "Invalid name %s in --end-of-life-rebase"
msgstr "Nombre %s no válido en --end-of-life-rebase"

#: app/flatpak-builtins-build-commit-from.c:333
#: app/flatpak-builtins-build-export.c:1092
#, c-format
msgid "Could not parse '%s'"
msgstr "No se pudo analizar «%s»"

#: app/flatpak-builtins-build-commit-from.c:498
msgid "Can't commit from partial source commit"
msgstr ""
"No se puede hacer un «commit» a partir de otro «commit» de fuente parcial"

#: app/flatpak-builtins-build-commit-from.c:503
#, c-format
msgid "%s: no change\n"
msgstr "%s: sin cambios\n"

#: app/flatpak-builtins-build-export.c:62
msgid "Architecture to export for (must be host compatible)"
msgstr "Arquitectura en la que exportar (debe ser compatible con el anfitrión)"

#: app/flatpak-builtins-build-export.c:63
msgid "Commit runtime (/usr), not /app"
msgstr "«Runtime» del «commit» (/usr), no /app"

#: app/flatpak-builtins-build-export.c:66
msgid "Use alternative directory for the files"
msgstr "Usar un carpeta alternativa para estos archivos"

#: app/flatpak-builtins-build-export.c:66
msgid "SUBDIR"
msgstr "SUBCARPETA"

#: app/flatpak-builtins-build-export.c:69
msgid "Files to exclude"
msgstr "Archivos que excluir"

#: app/flatpak-builtins-build-export.c:69
#: app/flatpak-builtins-build-export.c:70
#: app/flatpak-builtins-build-update-repo.c:90
msgid "PATTERN"
msgstr "PATRÓN"

#: app/flatpak-builtins-build-export.c:70
msgid "Excluded files to include"
msgstr "Archivos excluidos que incluir"

#: app/flatpak-builtins-build-export.c:74
msgid "Mark build as end-of-life, to be replaced with the given ID"
msgstr "Marcar la versión como fin de ciclo para reemplazarla con el ID dado"

#: app/flatpak-builtins-build-export.c:74
#: app/flatpak-builtins-document-list.c:49 app/flatpak-cli-transaction.c:1427
msgid "ID"
msgstr "ID"

#: app/flatpak-builtins-build-export.c:76
msgid "Override the timestamp of the commit"
msgstr "Sobrescribir la marca en tiempo del «commit»"

#: app/flatpak-builtins-build-export.c:77
#: app/flatpak-builtins-build-update-repo.c:75
#: app/flatpak-builtins-remote-add.c:83 app/flatpak-builtins-remote-list.c:54
#: app/flatpak-builtins-remote-modify.c:88
msgid "Collection ID"
msgstr "ID de la colección"

#: app/flatpak-builtins-build-export.c:472
#, c-format
msgid "WARNING: Error running desktop-file-validate: %s\n"
msgstr "ADVERTENCIA: error al ejecutar desktop-file-validate: %s\n"

#: app/flatpak-builtins-build-export.c:480
#, c-format
msgid "WARNING: Error reading from desktop-file-validate: %s\n"
msgstr "ADVERTENCIA: error al leer de desktop-file-validate: %s\n"

#: app/flatpak-builtins-build-export.c:486
#, c-format
msgid "WARNING: Failed to validate desktop file %s: %s\n"
msgstr "ADVERTENCIA: error al validar el archivo desktop %s: %s\n"

#: app/flatpak-builtins-build-export.c:513
#, c-format
msgid "WARNING: Can't find Exec key in %s: %s\n"
msgstr "ADVERTENCIA: no se puede encontrar la clave Exec en %s: %s\n"

#: app/flatpak-builtins-build-export.c:521
#: app/flatpak-builtins-build-export.c:614
#, c-format
msgid "WARNING: Binary not found for Exec line in %s: %s\n"
msgstr "ADVERTENCIA: no se encontró el binario de la línea Exec en %s: %s\n"

#: app/flatpak-builtins-build-export.c:529
#, c-format
msgid "WARNING: Icon not matching app id in %s: %s\n"
msgstr ""
"ADVERTENCIA: el icono no coincide con el ID de la aplicación en %s: %s\n"

#: app/flatpak-builtins-build-export.c:552
#, c-format
msgid "WARNING: Icon referenced in desktop file but not exported: %s\n"
msgstr ""
"ADVERTENCIA: icono referenciado en el archivo desktop pero no exportado: %s\n"

#: app/flatpak-builtins-build-export.c:719
#, c-format
msgid "Invalid uri type %s, only http/https supported"
msgstr "Tipo de URI %s no válido, solo se soporta http/https"

#: app/flatpak-builtins-build-export.c:737
#, c-format
msgid "Unable to find basename in %s, specify a name explicitly"
msgstr ""
"No se puede encontrar el nombre de base en %s, especifique un nombre "
"explícitamente"

#: app/flatpak-builtins-build-export.c:746
#, c-format
msgid "No slashes allowed in extra data name"
msgstr "No se permiten barras en el nombre de los datos adicionales"

#: app/flatpak-builtins-build-export.c:758
#, c-format
msgid "Invalid format for sha256 checksum: '%s'"
msgstr "Formato no válido de la suma de verificación sha256: «%s»"

#: app/flatpak-builtins-build-export.c:768
#, c-format
msgid "Extra data sizes of zero not supported"
msgstr "Los datos adicionales no pueden tener tamaño 0"

#: app/flatpak-builtins-build-export.c:830
msgid ""
"LOCATION DIRECTORY [BRANCH] - Create a repository from a build directory"
msgstr ""
"UBICACIÓN CARPETA [RAMA] - Crea un repositorio desde una carpeta de "
"compilación"

#: app/flatpak-builtins-build-export.c:838
msgid "LOCATION and DIRECTORY must be specified"
msgstr "Se debe especificar UBICACIÓN y CARPETA"

#: app/flatpak-builtins-build-export.c:859
#: app/flatpak-builtins-remote-add.c:327
#, c-format
msgid "‘%s’ is not a valid collection ID: %s"
msgstr "«%s» no es un ID de colección válido: %s"

#: app/flatpak-builtins-build-export.c:904
#: app/flatpak-builtins-build-finish.c:684
msgid "No name specified in the metadata"
msgstr "No se ha especificado un nombre en los metadatos"

#: app/flatpak-builtins-build-export.c:1166
#, c-format
msgid "Commit: %s\n"
msgstr "Commit: %s\n"

#: app/flatpak-builtins-build-export.c:1167
#, c-format
msgid "Metadata Total: %u\n"
msgstr "Metadatos totales: %u\n"

#: app/flatpak-builtins-build-export.c:1168
#, c-format
msgid "Metadata Written: %u\n"
msgstr "Metadatos escritos: %u\n"

#: app/flatpak-builtins-build-export.c:1169
#, c-format
msgid "Content Total: %u\n"
msgstr "Contenido total: %u\n"

#: app/flatpak-builtins-build-export.c:1170
#, c-format
msgid "Content Written: %u\n"
msgstr "Contenido escrito: %u\n"

#: app/flatpak-builtins-build-export.c:1171
#, c-format
msgid "Content Bytes Written:"
msgstr "Bytes de contenido escritos:"

#: app/flatpak-builtins-build-finish.c:52
msgid "Command to set"
msgstr "Comando que establecer"

#: app/flatpak-builtins-build-finish.c:52 app/flatpak-builtins-run.c:159
#: app/flatpak-main.c:209
msgid "COMMAND"
msgstr "COMANDO"

#: app/flatpak-builtins-build-finish.c:53
msgid "Flatpak version to require"
msgstr "Versión de Flatpak requerida"

#: app/flatpak-builtins-build-finish.c:53
msgid "MAJOR.MINOR.MICRO"
msgstr "MAYOR.MENOR.MICRO"

#: app/flatpak-builtins-build-finish.c:54
msgid "Don't process exports"
msgstr "No procesar las exportaciones"

#: app/flatpak-builtins-build-finish.c:55
msgid "Extra data info"
msgstr "Información de datos adicionales"

#: app/flatpak-builtins-build-finish.c:56 app/flatpak-builtins-build-init.c:63
msgid "Add extension point info"
msgstr "Añadir información del punto de extensión"

#: app/flatpak-builtins-build-finish.c:56 app/flatpak-builtins-build-init.c:63
msgid "NAME=VARIABLE[=VALUE]"
msgstr "NOMBRE=VARIABLE[=VALOR]"

#: app/flatpak-builtins-build-finish.c:57
msgid "Remove extension point info"
msgstr "Quitar la información del punto de extensión"

#: app/flatpak-builtins-build-finish.c:57
#: app/flatpak-builtins-build-update-repo.c:79 app/flatpak-builtins-info.c:58
#: app/flatpak-builtins-remote-add.c:88 app/flatpak-builtins-remote-modify.c:94
#: app/flatpak-main.c:182
msgid "NAME"
msgstr "NOMBRE"

#: app/flatpak-builtins-build-finish.c:58
msgid "Set extension priority (only for extensions)"
msgstr "Establecer la prioridad de la extensión (sólo para extensiones)"

#: app/flatpak-builtins-build-finish.c:58
msgid "VALUE"
msgstr "VALOR"

#: app/flatpak-builtins-build-finish.c:59
msgid "Change the sdk used for the app"
msgstr "Cambiar el SDK usado por la aplicación"

#: app/flatpak-builtins-build-finish.c:59
msgid "SDK"
msgstr "SDK"

#: app/flatpak-builtins-build-finish.c:60
msgid "Change the runtime used for the app"
msgstr "Cambiar la rutina en tiempo de ejecución usado por la aplicación"

#: app/flatpak-builtins-build-finish.c:60 app/flatpak-builtins-build-init.c:54
#: app/flatpak-builtins-list.c:53 app/flatpak-builtins-remote-ls.c:58
#: app/flatpak-builtins-run.c:163
msgid "RUNTIME"
msgstr "RUNTIME"

#: app/flatpak-builtins-build-finish.c:61
msgid "Set generic metadata option"
msgstr "Establecer la opción de metadatos genéricos"

#: app/flatpak-builtins-build-finish.c:61
msgid "GROUP=KEY[=VALUE]"
msgstr "GRUPO=CLAVE[=VALOR]"

#: app/flatpak-builtins-build-finish.c:62
msgid "Don't inherit permissions from runtime"
msgstr "No heredar permisos de la rutina en tiempo de ejecución"

#: app/flatpak-builtins-build-finish.c:155
#, c-format
msgid "Not exporting %s, wrong extension\n"
msgstr "No se está exportando %s, extensión incorrecta\n"

#: app/flatpak-builtins-build-finish.c:163
#, c-format
msgid "Not exporting %s, non-allowed export filename\n"
msgstr ""
"No se está exportando %s, nombre de archivo de exportación no permitido\n"

#: app/flatpak-builtins-build-finish.c:167
#, c-format
msgid "Exporting %s\n"
msgstr "Exportando %s\n"

#: app/flatpak-builtins-build-finish.c:440
#, c-format
msgid "More than one executable found\n"
msgstr "Se ha encontrado más de un ejecutable\n"

#: app/flatpak-builtins-build-finish.c:451
#, c-format
msgid "Using %s as command\n"
msgstr "Usar %s como comando\n"

#: app/flatpak-builtins-build-finish.c:456
#, c-format
msgid "No executable found\n"
msgstr "No se ha encontrado ningún ejecutable\n"

#: app/flatpak-builtins-build-finish.c:511
#, c-format
msgid "Invalid --require-version argument: %s"
msgstr "Argumento %s de --require-version no válido"

#: app/flatpak-builtins-build-finish.c:543
#, c-format
msgid "Too few elements in --extra-data argument %s"
msgstr "No hay suficientes elementos en el argumento --extra-data %s"

#: app/flatpak-builtins-build-finish.c:575
#, c-format
msgid ""
"Too few elements in --metadata argument %s, format should be "
"GROUP=KEY[=VALUE]]"
msgstr ""
"No hay suficientes elementos en el argumento de --metadata %s, el formato "
"debe ser GRUPO=CLAVE[=VALOR]"

#: app/flatpak-builtins-build-finish.c:597
#: app/flatpak-builtins-build-init.c:458
#, c-format
msgid ""
"Too few elements in --extension argument %s, format should be "
"NAME=VAR[=VALUE]"
msgstr ""
"No hay suficientes elementos en el argumento de --extension %s, el formato "
"debe ser NOMBRE=VARIABLE[=VALOR]"

#: app/flatpak-builtins-build-finish.c:603
#: app/flatpak-builtins-build-init.c:461
#, c-format
msgid "Invalid extension name %s"
msgstr "Nombre de extensión %s no válido"

#: app/flatpak-builtins-build-finish.c:646
msgid "DIRECTORY - Finalize a build directory"
msgstr "CARPETA - Finalizar un carpeta de compilación"

#: app/flatpak-builtins-build-finish.c:668
#, c-format
msgid "Build directory %s not initialized"
msgstr "La carpeta de compilación %s no está inicializada"

#: app/flatpak-builtins-build-finish.c:689
#, c-format
msgid "Build directory %s already finalized"
msgstr "La carpeta de compilación %s ya estaba finalizada"

#: app/flatpak-builtins-build-finish.c:702
#, c-format
msgid "Please review the exported files and the metadata\n"
msgstr "Revise los archivos exportados y los metadatos\n"

#: app/flatpak-builtins-build-import-bundle.c:47
msgid "Override the ref used for the imported bundle"
msgstr "Sobrescribir la referencia usada en el paquete importado"

#: app/flatpak-builtins-build-import-bundle.c:47
msgid "REF"
msgstr "REFERENCIA"

#: app/flatpak-builtins-build-import-bundle.c:48
msgid "Import oci image instead of flatpak bundle"
msgstr "Importar la imagen OCI en lugar del paquete flatpak"

#: app/flatpak-builtins-build-import-bundle.c:77
#: app/flatpak-builtins-build-import-bundle.c:105
#, c-format
msgid "Importing %s (%s)\n"
msgstr "Importando %s: (%s)\n"

#: app/flatpak-builtins-build-import-bundle.c:126
msgid "LOCATION FILENAME - Import a file bundle into a local repository"
msgstr "UBICACIÓN NOMBRE_ARCHIVO - Importa un paquete al repositorio local"

#: app/flatpak-builtins-build-import-bundle.c:133
msgid "LOCATION and FILENAME must be specified"
msgstr "Se debe especificar UBICACIÓN y NOMBRE_ARCHIVO"

#: app/flatpak-builtins-build-init.c:53 app/flatpak-builtins-info.c:55
#: app/flatpak-builtins-run.c:158
msgid "Arch to use"
msgstr "Arquitectura que usar"

#: app/flatpak-builtins-build-init.c:54
msgid "Initialize var from named runtime"
msgstr ""
"Inicializar la variable desde la rutina en tiempo de ejecución especificada"

#: app/flatpak-builtins-build-init.c:55
msgid "Initialize apps from named app"
msgstr "Inicializar aplicaciones desde la aplicación especificada"

#: app/flatpak-builtins-build-init.c:55
msgid "APP"
msgstr "APLICACIÓN"

#: app/flatpak-builtins-build-init.c:56
msgid "Specify version for --base"
msgstr "Especifica una versión para --base"

#: app/flatpak-builtins-build-init.c:56 app/flatpak-builtins-run.c:164
msgid "VERSION"
msgstr "VERSIÓN"

#: app/flatpak-builtins-build-init.c:57
msgid "Include this base extension"
msgstr "Incluir esta extensión base"

#: app/flatpak-builtins-build-init.c:57 app/flatpak-builtins-build-init.c:62
msgid "EXTENSION"
msgstr "EXTENSIÓN"

#: app/flatpak-builtins-build-init.c:58
msgid "Extension tag to use if building extension"
msgstr "Etiqueta de extensión que usar al construir una extensión"

#: app/flatpak-builtins-build-init.c:58
msgid "EXTENSION_TAG"
msgstr "ETIQUETA_EXTENSIÓN"

#: app/flatpak-builtins-build-init.c:59
msgid "Initialize /usr with a writable copy of the sdk"
msgstr "Inicializar /usr con una copia con permisos de escritura del SDK"

#: app/flatpak-builtins-build-init.c:60
msgid "Specify the build type (app, runtime, extension)"
msgstr "Especificar el tipo de compilación (aplicación, «runtime», extensión)"

#: app/flatpak-builtins-build-init.c:60
msgid "TYPE"
msgstr "TIPO"

#: app/flatpak-builtins-build-init.c:61
msgid "Add a tag"
msgstr "Añadir una etiqueta"

#: app/flatpak-builtins-build-init.c:61
msgid "TAG"
msgstr "ETIQUETA"

#: app/flatpak-builtins-build-init.c:62
msgid "Include this sdk extension in /usr"
msgstr "Incluir la extensión de este SDK en /usr"

#: app/flatpak-builtins-build-init.c:64
msgid "Where to store sdk (defaults to 'usr')"
msgstr "Dónde almacenar el SDK (predeterminado en «usr»)"

#: app/flatpak-builtins-build-init.c:65
msgid "Re-initialize the sdk/var"
msgstr "Reinicializar el sdk/variable"

#: app/flatpak-builtins-build-init.c:118
#, c-format
msgid "Requested extension %s/%s/%s is only partially installed"
msgstr "La extensión %s/%s/%s requerida solo está instalada parcialmente"

#: app/flatpak-builtins-build-init.c:147
#, c-format
msgid "Requested extension %s/%s/%s not installed"
msgstr "La extensión %s/%s/%s requerida no está instalada"

#: app/flatpak-builtins-build-init.c:207
msgid ""
"DIRECTORY APPNAME SDK RUNTIME [BRANCH] - Initialize a directory for building"
msgstr ""
"CARPETA NOMBRE_APLICACIÓN SDK «RUNTIME» [RAMA] - Inicializa una carpeta de "
"compilación"

#: app/flatpak-builtins-build-init.c:214
msgid "RUNTIME must be specified"
msgstr "Se debe especificar un «RUNTIME»"

#: app/flatpak-builtins-build-init.c:235
#, c-format
msgid "'%s' is not a valid build type name, use app, runtime or extension"
msgstr ""
"«%s» no es un tipo de compilación válido, use aplicación, «runtime» o "
"extensión"

#: app/flatpak-builtins-build-init.c:241 app/flatpak-builtins-override.c:79
#, c-format
msgid "'%s' is not a valid application name: %s"
msgstr "«%s» no es un nombre de aplicación valido: %s"

#: app/flatpak-builtins-build-init.c:295
#, c-format
msgid "Build directory %s already initialized"
msgstr "La carpeta de compilación %s ya está inicializada"

#: app/flatpak-builtins-build-sign.c:42 app/flatpak-builtins-install.c:67
#: app/flatpak-builtins-remote-info.c:54
msgid "Arch to install for"
msgstr "Arquitectura en la que instalar"

#: app/flatpak-builtins-build-sign.c:43 app/flatpak-builtins-create-usb.c:48
#: app/flatpak-builtins-install.c:74 app/flatpak-builtins-remote-info.c:56
#: app/flatpak-builtins-uninstall.c:58 app/flatpak-builtins-update.c:64
msgid "Look for runtime with the specified name"
msgstr "Buscar un «runtime» con el nombre especificado"

#: app/flatpak-builtins-build-sign.c:66
msgid "LOCATION [ID [BRANCH]] - Sign an application or runtime"
msgstr "UBICACIÓN [ID [RAMA]] - Firma una aplicación o «runtime»"

#: app/flatpak-builtins-build-sign.c:73
#: app/flatpak-builtins-build-update-repo.c:499
#: app/flatpak-builtins-remote-add.c:320 app/flatpak-builtins-repo.c:739
msgid "LOCATION must be specified"
msgstr "Se debe especificar la UBICACIÓN"

#: app/flatpak-builtins-build-sign.c:94
msgid "No gpg key ids specified"
msgstr "No se han especificado los ids de las claves GPG"

#: app/flatpak-builtins-build-update-repo.c:68
msgid "Redirect this repo to a new URL"
msgstr "Redirige este repositorio a una nueva URL"

#: app/flatpak-builtins-build-update-repo.c:69
msgid "A nice name to use for this repository"
msgstr "Un buen nombre para usar en este repositorio"

#: app/flatpak-builtins-build-update-repo.c:69
#: app/flatpak-builtins-remote-add.c:77 app/flatpak-builtins-remote-modify.c:82
msgid "TITLE"
msgstr "TÍTULO"

#: app/flatpak-builtins-build-update-repo.c:70
msgid "A one-line comment for this repository"
msgstr "Un comentario de una línea para este repositorio"

#: app/flatpak-builtins-build-update-repo.c:70
#: app/flatpak-builtins-remote-add.c:78 app/flatpak-builtins-remote-modify.c:83
msgid "COMMENT"
msgstr "COMENTARIO"

#: app/flatpak-builtins-build-update-repo.c:71
msgid "A full-paragraph description for this repository"
msgstr "Una descripción completa de este repositorio"

#: app/flatpak-builtins-build-update-repo.c:71
#: app/flatpak-builtins-remote-add.c:79 app/flatpak-builtins-remote-modify.c:84
msgid "DESCRIPTION"
msgstr "DESCRIPCIÓN"

#: app/flatpak-builtins-build-update-repo.c:72
msgid "URL for a website for this repository"
msgstr "URL del sitio web de este repositorio"

#: app/flatpak-builtins-build-update-repo.c:73
msgid "URL for an icon for this repository"
msgstr "URL del icono de este repositorio"

#: app/flatpak-builtins-build-update-repo.c:74
msgid "Default branch to use for this repository"
msgstr "Rama predeterminada que usar en este repositorio"

#: app/flatpak-builtins-build-update-repo.c:74
#: app/flatpak-builtins-remote-add.c:82 app/flatpak-builtins-remote-modify.c:87
#: app/flatpak-builtins-repo.c:713 app/flatpak-builtins-repo.c:714
#: app/flatpak-builtins-run.c:161
msgid "BRANCH"
msgstr "RAMA"

#: app/flatpak-builtins-build-update-repo.c:75
#: app/flatpak-builtins-remote-add.c:83 app/flatpak-builtins-remote-modify.c:88
msgid "COLLECTION-ID"
msgstr "ID-COLECCIÓN"

#. Translators: A sideload is when you install from a local USB drive rather than the Internet.
#: app/flatpak-builtins-build-update-repo.c:77
msgid ""
"Permanently deploy collection ID to client remote configurations, only for "
"sideload support"
msgstr ""
"Desplegar de forma permanente el ID de colección en las configuraciones "
"remotas del cliente, solo para soporte de USB"

#: app/flatpak-builtins-build-update-repo.c:78
msgid "Permanently deploy collection ID to client remote configurations"
msgstr ""
"Desplegar de forma permanente el ID de colección en las configuraciones "
"remotas del cliente"

#: app/flatpak-builtins-build-update-repo.c:79
msgid "Name of authenticator for this repository"
msgstr "Nombre del autenticador para este repositorio"

#: app/flatpak-builtins-build-update-repo.c:80
msgid "Autoinstall authenticator for this repository"
msgstr "Instalar automáticamente el autenticador para este repositorio"

#: app/flatpak-builtins-build-update-repo.c:81
msgid "Don't autoinstall authenticator for this repository"
msgstr "No instalar automáticamente el autenticador para este repositorio"

#: app/flatpak-builtins-build-update-repo.c:82
#: app/flatpak-builtins-remote-add.c:89
msgid "Authenticator option"
msgstr "Opción del autenticador"

#: app/flatpak-builtins-build-update-repo.c:82
#: app/flatpak-builtins-remote-add.c:89 app/flatpak-builtins-remote-modify.c:95
msgid "KEY=VALUE"
msgstr "CLAVE=VALOR"

#: app/flatpak-builtins-build-update-repo.c:83
msgid "Import new default GPG public key from FILE"
msgstr "Importar una nueva clave pública GPG predeterminada desde un ARCHIVO"

#: app/flatpak-builtins-build-update-repo.c:84
msgid "GPG Key ID to sign the summary with"
msgstr "ID de la clave GPG con la que firmar el resumen"

#: app/flatpak-builtins-build-update-repo.c:86
msgid "Generate delta files"
msgstr "Generar archivos de diferencias"

#: app/flatpak-builtins-build-update-repo.c:88
msgid "Don't update the appstream branch"
msgstr "No actualizar la rama de «appstream»"

#: app/flatpak-builtins-build-update-repo.c:89
msgid "Max parallel jobs when creating deltas (default: NUMCPUs)"
msgstr ""
"Número máximo de trabajos en paralelo al crear diferencias (predeterminado: "
"NUMCPUs)"

#: app/flatpak-builtins-build-update-repo.c:89
msgid "NUM-JOBS"
msgstr "NUM_TRABAJOS"

#: app/flatpak-builtins-build-update-repo.c:90
msgid "Don't create deltas matching refs"
msgstr "No crear diferencias que coincidan con las referencias"

#: app/flatpak-builtins-build-update-repo.c:91
msgid "Prune unused objects"
msgstr "Eliminar objetos no usados"

#: app/flatpak-builtins-build-update-repo.c:92
msgid "Prune but don't actually remove anything"
msgstr "Podar pero sin quitar nada"

#: app/flatpak-builtins-build-update-repo.c:93
msgid "Only traverse DEPTH parents for each commit (default: -1=infinite)"
msgstr ""
"Solo recorrer padres de PROFUNDIDAD para cada «commit» (predeterminado: "
"-1=infinitos)"

#: app/flatpak-builtins-build-update-repo.c:93
msgid "DEPTH"
msgstr "PROFUNDIDAD"

#: app/flatpak-builtins-build-update-repo.c:223
#, c-format
msgid "Generating delta: %s (%.10s)\n"
msgstr "Generando diferencia: %s (%.10s)\n"

#: app/flatpak-builtins-build-update-repo.c:225
#, c-format
msgid "Generating delta: %s (%.10s-%.10s)\n"
msgstr "Generando diferencia: %s (%.10s-%.10s)\n"

#: app/flatpak-builtins-build-update-repo.c:233
#, c-format
msgid "Failed to generate delta %s (%.10s): "
msgstr "Falló al generar la diferencia %s (%.10s): "

#: app/flatpak-builtins-build-update-repo.c:236
#, c-format
msgid "Failed to generate delta %s (%.10s-%.10s): "
msgstr "Fallo al generar la diferencia %s (%.10s-%.10s): "

#: app/flatpak-builtins-build-update-repo.c:492
msgid "LOCATION - Update repository metadata"
msgstr "UBICACIÓN - actualizar los metadatos del repositorio"

#: app/flatpak-builtins-build-update-repo.c:609
#, c-format
msgid "Updating appstream branch\n"
msgstr "Actualizando rama de «appstream»\n"

#: app/flatpak-builtins-build-update-repo.c:638
#, c-format
msgid "Updating summary\n"
msgstr "Actualizando resumen\n"

#: app/flatpak-builtins-build-update-repo.c:664
#, c-format
msgid "Total objects: %u\n"
msgstr "Objetos totales: %u\n"

#: app/flatpak-builtins-build-update-repo.c:666
#, c-format
msgid "No unreachable objects\n"
msgstr "No hay objetos inaccesibles\n"

#: app/flatpak-builtins-build-update-repo.c:668
#, c-format
msgid "Deleted %u objects, %s freed\n"
msgstr "%u objetos eliminados, %s liberados\n"

#: app/flatpak-builtins-config.c:41
msgid "List configuration keys and values"
msgstr "Listar las claves y valores de configuración"

#: app/flatpak-builtins-config.c:42
msgid "Get configuration for KEY"
msgstr "Obtener la configuración de CLAVE"

#: app/flatpak-builtins-config.c:43
msgid "Set configuration for KEY to VALUE"
msgstr "Establecer VALOR de configuración para CLAVE"

#: app/flatpak-builtins-config.c:44
msgid "Unset configuration for KEY"
msgstr "Quitar la configuración de CLAVE"

#: app/flatpak-builtins-config.c:149
#, c-format
msgid "'%s' does not look like a language/locale code"
msgstr "«%s» no es un código de idioma o configuración regional"

#: app/flatpak-builtins-config.c:172
#, c-format
msgid "'%s' does not look like a language code"
msgstr "«%s» no es un código de idioma"

#: app/flatpak-builtins-config.c:190
#, fuzzy, c-format
msgid "'%s' is not a valid value (use 'true' or 'false')"
msgstr "«%s» no es un repositorio válido: "

#: app/flatpak-builtins-config.c:262
#, c-format
msgid "Unknown configure key '%s'"
msgstr "Clave de configuración «%s» desconocida"

#: app/flatpak-builtins-config.c:284
msgid "Too many arguments for --list"
msgstr "Demasiados argumentos para --list"

#: app/flatpak-builtins-config.c:314 app/flatpak-builtins-config.c:362
msgid "You must specify KEY"
msgstr "Se debe especificar la CLAVE"

#: app/flatpak-builtins-config.c:316
msgid "Too many arguments for --get"
msgstr "Demasiados argumentos para --get"

#: app/flatpak-builtins-config.c:338
msgid "You must specify KEY and VALUE"
msgstr "Se debe especificar la CLAVE y el VALOR"

#: app/flatpak-builtins-config.c:340
msgid "Too many arguments for --set"
msgstr "Demasiados argumentos para --set"

#: app/flatpak-builtins-config.c:364
msgid "Too many arguments for --unset"
msgstr "Demasiados argumentos para --unset"

#: app/flatpak-builtins-config.c:383
msgid "[KEY [VALUE]] - Manage configuration"
msgstr "[CLAVE [VALOR]] - gestionar configuración"

#: app/flatpak-builtins-config.c:394
msgid "Can only use one of --list, --get, --set or --unset"
msgstr "Sólo se puede usar uno de estos: --list, --get, --set o --unset"

#: app/flatpak-builtins-config.c:408
msgid "Must specify one of --list, --get, --set or --unset"
msgstr "Debe especificar uno de estos: --list, --get, --set o --unset"

#: app/flatpak-builtins-create-usb.c:45 app/flatpak-builtins-install.c:75
#: app/flatpak-builtins-remote-info.c:57 app/flatpak-builtins-uninstall.c:59
#: app/flatpak-builtins-update.c:65
msgid "Look for app with the specified name"
msgstr "Buscar una aplicación con el nombre especifico"

#: app/flatpak-builtins-create-usb.c:46
msgid "Arch to copy"
msgstr "Arquitectura que copiar"

#: app/flatpak-builtins-create-usb.c:47
msgid "DEST"
msgstr "DEST"

#: app/flatpak-builtins-create-usb.c:49
msgid "Allow partial commits in the created repo"
msgstr "Permitir «commit»s parciales en el repositorio creado"

#: app/flatpak-builtins-create-usb.c:125 app/flatpak-builtins-create-usb.c:165
#, c-format
msgid ""
"Warning: Related ref ‘%s’ is partially installed. Use --allow-partial to "
"suppress this message.\n"
msgstr ""
"Advertencia: la referencia «%s» relacionada está parcialmente instalada. Use "
"--allow-partial para eliminar este mensaje.\n"

#: app/flatpak-builtins-create-usb.c:158
#, c-format
msgid "Warning: Omitting related ref ‘%s’ because it is not installed.\n"
msgstr ""
"Advertencia: omitiendo la referencia «%s» relacionada porque no está "
"instalada.\n"

#: app/flatpak-builtins-create-usb.c:175
#, c-format
msgid ""
"Warning: Omitting related ref ‘%s’ because its remote ‘%s’ does not have a "
"collection ID set.\n"
msgstr ""
"Advertencia: omitiendo la referencia «%s» relacionada porque su «%s» remota "
"no tiene establecido un ID de colección.\n"

#: app/flatpak-builtins-create-usb.c:187
#, c-format
msgid "Warning: Omitting related ref ‘%s’ because it's extra-data.\n"
msgstr ""
"Advertencia: omitiendo la referencia «%s» relacionada porque son datos "
"adicionales.\n"

#: app/flatpak-builtins-create-usb.c:262 app/flatpak-builtins-create-usb.c:637
#, c-format
msgid ""
"Remote ‘%s’ does not have a collection ID set, which is required for P2P "
"distribution of ‘%s’."
msgstr ""
"La rama «%s» remota no tiene establecido un ID de colección, necesario para "
"la distribución P2P de «%s»."

#: app/flatpak-builtins-create-usb.c:272
#, c-format
msgid "Warning: Omitting ref ‘%s’ (runtime of ‘%s’) because it's extra-data.\n"
msgstr ""
"Advertencia: omitiendo la referencia «%s» (tiempo de ejecución de «%s») "
"porque son datos adicionales.\n"

#: app/flatpak-builtins-create-usb.c:484
msgid "MOUNT-PATH [REF…] - Copy apps or runtimes onto removable media"
msgstr ""
"PUNTO_DE_MONTAJE [REFERENCIA…] - copiar aplicaciones o rutinas en tiempo de "
"ejecución en medios extraíbles"

#: app/flatpak-builtins-create-usb.c:493
msgid "MOUNT-PATH and REF must be specified"
msgstr "Se debe especificar PUNTO_DE_MONTAJE y REFERENCIA"

#: app/flatpak-builtins-create-usb.c:607
#, c-format
msgid "Ref ‘%s’ found in multiple installations: %s. You must specify one."
msgstr ""
"Se encontró la referencia «%s» en varias instalaciones: %s. Debe especificar "
"una."

#: app/flatpak-builtins-create-usb.c:620
#, c-format
msgid "Refs must all be in the same installation (found in %s and %s)."
msgstr ""
"Las referencias deben estar todas en la misma instalación (encontrada en %s "
"y %s)"

#: app/flatpak-builtins-create-usb.c:670
#, c-format
msgid ""
"Warning: Ref ‘%s’ is partially installed. Use --allow-partial to suppress "
"this message.\n"
msgstr ""
"Advertencia: la referencia «%s» está parcialmente instalada. Use --allow-"
"partial para eliminar este mensaje.\n"

#: app/flatpak-builtins-create-usb.c:681
#, c-format
msgid "Installed ref ‘%s’ is extra-data, and cannot be distributed offline"
msgstr ""
"La referencia instalada «%s» es un dato adicional y no se puede distribuir "
"sin conexión"

#: app/flatpak-builtins-create-usb.c:721
#, c-format
msgid "Warning: Couldn't update repo metadata for remote ‘%s’: %s\n"
msgstr ""
"Advertencia: no se pudieron actualizar los metadatos del repositorio «%s»: "
"%s\n"

#: app/flatpak-builtins-create-usb.c:751
#, c-format
msgid "Warning: Couldn't update appstream data for remote ‘%s’ arch ‘%s’: %s\n"
msgstr ""
"Advertencia: no se pudieron actualizar los datos de appstream para el "
"repositorio remoto «%s», arquitectura «%s»: %s\n"

#. Print a warning if both appstream and appstream2 are missing
#: app/flatpak-builtins-create-usb.c:784
#, c-format
msgid ""
"Warning: Couldn't find appstream data for remote ‘%s’ arch ‘%s’: %s; %s\n"
msgstr ""
"Advertencia: no se pudieron encontrar los datos de appstream para el "
"repositorio remoto «%s», arquitectura «%s»: %s, %s\n"

#. Appstream2 is only for efficiency, so just print a debug message
#: app/flatpak-builtins-create-usb.c:790
#, c-format
msgid "Couldn't find appstream2 data for remote ‘%s’ arch ‘%s’: %s\n"
msgstr ""
"No se pudieron encontrar los datos de appstream2 para el repositorio remoto "
"%s, arquitectura «%s»: %s\n"

#: app/flatpak-builtins-document-export.c:62
msgid "Create a unique document reference"
msgstr "Crear una referencia única de documento"

#: app/flatpak-builtins-document-export.c:63
msgid "Make the document transient for the current session"
msgstr "Hacer el documento transitorio para la sesión actual"

#: app/flatpak-builtins-document-export.c:64
msgid "Don't require the file to exist already"
msgstr "No requerir que el archivo exista"

#: app/flatpak-builtins-document-export.c:65
msgid "Give the app read permissions"
msgstr "Dar permisos de lectura a la aplicación"

#: app/flatpak-builtins-document-export.c:66
msgid "Give the app write permissions"
msgstr "Dar permisos de escritura a la aplicación"

#: app/flatpak-builtins-document-export.c:67
msgid "Give the app delete permissions"
msgstr "Dar permisos de eliminación a la aplicación"

#: app/flatpak-builtins-document-export.c:68
msgid "Give the app permissions to grant further permissions"
msgstr "Dar permisos a la aplicación para conceder permisos adicionales"

#: app/flatpak-builtins-document-export.c:69
msgid "Revoke read permissions of the app"
msgstr "Revocar los permisos de lectura de la aplicación"

#: app/flatpak-builtins-document-export.c:70
msgid "Revoke write permissions of the app"
msgstr "Revocar los permisos de escritura de la aplicación"

#: app/flatpak-builtins-document-export.c:71
msgid "Revoke delete permissions of the app"
msgstr "Revocar los permisos de eliminación de la aplicación"

#: app/flatpak-builtins-document-export.c:72
msgid "Revoke the permission to grant further permissions"
msgstr ""
"Revocar los permisos de la aplicación para conceder permisos adicionales"

#: app/flatpak-builtins-document-export.c:73
msgid "Add permissions for this app"
msgstr "Añadir permisos a esta aplicación"

#: app/flatpak-builtins-document-export.c:73
msgid "APPID"
msgstr "ID_APLICACIÓN"

#: app/flatpak-builtins-document-export.c:100
msgid "FILE - Export a file to apps"
msgstr "ARCHIVO - Exportar un archivo en las aplicaciones"

#: app/flatpak-builtins-document-export.c:109
#: app/flatpak-builtins-document-info.c:72
#: app/flatpak-builtins-document-unexport.c:67
msgid "FILE must be specified"
msgstr "Se debe especificar el ARCHIVO"

#: app/flatpak-builtins-document-info.c:63
msgid "FILE - Get information about an exported file"
msgstr "ARCHIVO - Obtiene información sobre un archivo exportado"

#: app/flatpak-builtins-document-info.c:100
#: app/flatpak-builtins-document-unexport.c:94
#, c-format
msgid "Not exported\n"
msgstr "No exportado\n"

#: app/flatpak-builtins-document-list.c:43 app/flatpak-builtins-history.c:53
#: app/flatpak-builtins-list.c:54 app/flatpak-builtins-ps.c:43
#: app/flatpak-builtins-remote-list.c:45 app/flatpak-builtins-remote-ls.c:59
#: app/flatpak-builtins-search.c:38
msgid "What information to show"
msgstr "Qué información mostrar"

#: app/flatpak-builtins-document-list.c:43 app/flatpak-builtins-history.c:53
#: app/flatpak-builtins-list.c:54 app/flatpak-builtins-ps.c:43
#: app/flatpak-builtins-remote-list.c:45 app/flatpak-builtins-remote-ls.c:59
#: app/flatpak-builtins-search.c:38
msgid "FIELD,…"
msgstr "CAMPO,…"

#: app/flatpak-builtins-document-list.c:44 app/flatpak-builtins-history.c:54
#: app/flatpak-builtins-list.c:52 app/flatpak-builtins-permission-list.c:43
#: app/flatpak-builtins-permission-show.c:43 app/flatpak-builtins-ps.c:44
#: app/flatpak-builtins-remote-list.c:46 app/flatpak-builtins-remote-ls.c:63
#: app/flatpak-builtins-repo.c:717 app/flatpak-builtins-search.c:39
#, fuzzy
msgid "Show output in JSON format"
msgstr "Mostrar información adicional"

#: app/flatpak-builtins-document-list.c:49
msgid "Show the document ID"
msgstr "Mostrar el ID del documento"

#: app/flatpak-builtins-document-list.c:50
msgid "Path"
msgstr "Ruta"

#: app/flatpak-builtins-document-list.c:50
#: app/flatpak-builtins-document-list.c:51
msgid "Show the document path"
msgstr "Mostrar la ruta del documento"

#: app/flatpak-builtins-document-list.c:51 app/flatpak-builtins-list.c:66
#: app/flatpak-builtins-remote-ls.c:74
msgid "Origin"
msgstr "Origen"

#: app/flatpak-builtins-document-list.c:52 app/flatpak-builtins-history.c:62
#: app/flatpak-builtins-ps.c:52
msgid "Application"
msgstr "Aplicación"

#: app/flatpak-builtins-document-list.c:52
msgid "Show applications with permission"
msgstr "Mostrar aplicaciones con permisos"

#: app/flatpak-builtins-document-list.c:53
#: app/flatpak-builtins-permission-list.c:182
#: app/flatpak-builtins-permission-show.c:145
msgid "Permissions"
msgstr "Permisos"

#: app/flatpak-builtins-document-list.c:53
msgid "Show permissions for applications"
msgstr "Mostrar permisos de las aplicaciones"

#: app/flatpak-builtins-document-list.c:161
#, fuzzy, c-format
msgid "No documents found\n"
msgstr "Ninguna coincidencia"

#: app/flatpak-builtins-document-list.c:180
msgid "[APPID] - List exported files"
msgstr "[ID_APLICACIÓN] - Obtiene una lista de los archivos exportados"

#: app/flatpak-builtins-document-unexport.c:43
msgid "Specify the document ID"
msgstr "Especifique el ID del documento"

#: app/flatpak-builtins-document-unexport.c:58
msgid "FILE - Unexport a file to apps"
msgstr "ARCHIVO - Elimina la exportación de un archivo a las aplicaciones"

#: app/flatpak-builtins-enter.c:88
msgid "INSTANCE COMMAND [ARGUMENT…] - Run a command inside a running sandbox"
msgstr ""
"INSTANCIA [COMANDO [ARGUMENTO…]] - Ejecuta un comando dentro de una entorno "
"aislado en ejecución"

#: app/flatpak-builtins-enter.c:111
msgid "INSTANCE and COMMAND must be specified"
msgstr "Se deben especificar INSTANCIA y COMANDO"

#: app/flatpak-builtins-enter.c:138
#, c-format
msgid "%s is neither a pid nor an application or instance ID"
msgstr "%s no es un PID ni una aplicación o ID de instancia valido"

#: app/flatpak-builtins-enter.c:144
msgid "entering not supported (need unprivileged user namespaces, or sudo -E)"
msgstr ""
"entrada no soportada (se necesitan nombres de espacios de usuario sin "
"privilegios o sudo -E)"

#: app/flatpak-builtins-enter.c:145
#, c-format
msgid "No such pid %s"
msgstr "No existe el PID %s"

#: app/flatpak-builtins-enter.c:158
msgid "Can't read cwd"
msgstr "No se puede leer cwd"

#: app/flatpak-builtins-enter.c:163
msgid "Can't read root"
msgstr "No se puede leer root"

#: app/flatpak-builtins-enter.c:191
#, c-format
msgid "Invalid %s namespace for pid %d"
msgstr "Espacio de nombres %s no válido para el PID %d"

#: app/flatpak-builtins-enter.c:202
#, c-format
msgid "Invalid %s namespace for self"
msgstr "Espacio de nombres %s no válido para sí mismo"

#: app/flatpak-builtins-enter.c:216
#, c-format
msgid "Can't open %s namespace: %s"
msgstr "No se puede abrir el espacio de nombres %s: %s"

#: app/flatpak-builtins-enter.c:226
msgid "entering not supported (need unprivileged user namespaces)"
msgstr ""
"entrada no soportada (se necesitan nombres de espacios de usuario sin "
"privilegios)"

#: app/flatpak-builtins-enter.c:227
#, c-format
msgid "Can't enter %s namespace: %s"
msgstr "No se puede entrar al espacio de nombres %s: %s"

#: app/flatpak-builtins-enter.c:234
msgid "Can't chdir"
msgstr "No se puede hacer chdir"

#: app/flatpak-builtins-enter.c:237
msgid "Can't chroot"
msgstr "No se puede hacer chroot"

#: app/flatpak-builtins-enter.c:240
msgid "Can't switch gid"
msgstr "No se puede cambiar el GID"

#: app/flatpak-builtins-enter.c:243
msgid "Can't switch uid"
msgstr "No se puede cambiar el UID"

#: app/flatpak-builtins-history.c:50
msgid "Only show changes after TIME"
msgstr "Mostrar cambios sólo después de HORA"

#: app/flatpak-builtins-history.c:50 app/flatpak-builtins-history.c:51
msgid "TIME"
msgstr "HORA"

#: app/flatpak-builtins-history.c:51
msgid "Only show changes before TIME"
msgstr "Mostrar cambios sólo antes de HORA"

#: app/flatpak-builtins-history.c:52
msgid "Show newest entries first"
msgstr "Mostrar las entradas nuevas primero"

#: app/flatpak-builtins-history.c:59
msgid "Time"
msgstr "Hora"

#: app/flatpak-builtins-history.c:59
msgid "Show when the change happened"
msgstr "Mostrar cuándo ha ocurrido el cambio"

#: app/flatpak-builtins-history.c:60
msgid "Change"
msgstr "Cambio"

#: app/flatpak-builtins-history.c:60
msgid "Show the kind of change"
msgstr "Mostrar el tipo de cambio"

#: app/flatpak-builtins-history.c:61 app/flatpak-builtins-list.c:68
#: app/flatpak-builtins-remote-ls.c:75 app/flatpak-builtins-repo.c:335
msgid "Ref"
msgstr "Referencia"

#: app/flatpak-builtins-history.c:61 app/flatpak-builtins-list.c:68
#: app/flatpak-builtins-remote-ls.c:75
msgid "Show the ref"
msgstr "Mostrar la referencia"

#: app/flatpak-builtins-history.c:62
msgid "Show the application/runtime ID"
msgstr "Mostrar el ID de aplicación/rutina en tiempo de ejecución"

#: app/flatpak-builtins-history.c:63 app/flatpak-builtins-list.c:64
#: app/flatpak-builtins-ps.c:53 app/flatpak-builtins-remote-ls.c:73
#: app/flatpak-cli-transaction.c:1435
msgid "Arch"
msgstr "Arquitectura"

#: app/flatpak-builtins-history.c:63 app/flatpak-builtins-list.c:64
#: app/flatpak-builtins-ps.c:53 app/flatpak-builtins-remote-ls.c:73
msgid "Show the architecture"
msgstr "Mostrar la arquitectura"

#: app/flatpak-builtins-history.c:64 app/flatpak-builtins-list.c:63
#: app/flatpak-builtins-ps.c:54 app/flatpak-builtins-remote-ls.c:72
#: app/flatpak-builtins-search.c:48 app/flatpak-cli-transaction.c:1438
msgid "Branch"
msgstr "Rama"

#: app/flatpak-builtins-history.c:64 app/flatpak-builtins-list.c:63
#: app/flatpak-builtins-remote-ls.c:72
msgid "Show the branch"
msgstr "Mostrar la rama"

#: app/flatpak-builtins-history.c:65 app/flatpak-builtins-list.c:67
msgid "Installation"
msgstr "Instalación"

#: app/flatpak-builtins-history.c:65
msgid "Show the affected installation"
msgstr "Mostrar la instalación afectada"

#: app/flatpak-builtins-history.c:66 app/flatpak-cli-transaction.c:1452
msgid "Remote"
msgstr "Remoto"

#: app/flatpak-builtins-history.c:66
msgid "Show the remote"
msgstr "Mostrar los repositorios remotos"

#: app/flatpak-builtins-history.c:67 app/flatpak-builtins-ps.c:55
#: app/flatpak-builtins-remote-ls.c:76
msgid "Commit"
msgstr "Commit"

#: app/flatpak-builtins-history.c:67
msgid "Show the current commit"
msgstr "Mostrar el «commit» actual"

#: app/flatpak-builtins-history.c:68
msgid "Old Commit"
msgstr "«Commit» antiguo"

#: app/flatpak-builtins-history.c:68
msgid "Show the previous commit"
msgstr "Mostrar el «commit» anterior"

#: app/flatpak-builtins-history.c:69
msgid "Show the remote URL"
msgstr "Mostrar el URL  del repositorio remoto"

#: app/flatpak-builtins-history.c:70 app/flatpak-cli-transaction.c:700
msgid "User"
msgstr "Usuario"

#: app/flatpak-builtins-history.c:70
msgid "Show the user doing the change"
msgstr "Mostrar al usuario que hace el cambio"

#: app/flatpak-builtins-history.c:71
msgid "Tool"
msgstr "Herramienta"

#: app/flatpak-builtins-history.c:71
msgid "Show the tool that was used"
msgstr "Mostrar la herramienta que se ha usado"

#: app/flatpak-builtins-history.c:72 app/flatpak-builtins-list.c:62
#: app/flatpak-builtins-remote-ls.c:71 app/flatpak-builtins-search.c:47
msgid "Version"
msgstr "Versión"

#: app/flatpak-builtins-history.c:72
msgid "Show the Flatpak version"
msgstr "Mostrar la versión de Flatpak"

#: app/flatpak-builtins-history.c:91
#, c-format
msgid "Failed to get journal data (%s): %s"
msgstr "Fallo al obtener los datos de la bitácora (%s): %s"

#: app/flatpak-builtins-history.c:146
#, c-format
msgid "Failed to open journal: %s"
msgstr "Fallo al abrir la bitácora: %s"

#: app/flatpak-builtins-history.c:153
#, c-format
msgid "Failed to add match to journal: %s"
msgstr "Fallo al añadir la coincidencia a la bitácora: %s"

#: app/flatpak-builtins-history.c:471
msgid " - Show history"
msgstr " - Mostrar histórico"

#: app/flatpak-builtins-history.c:490
#, c-format
msgid "Failed to parse the --since option"
msgstr "Falló al analizar la opción --since"

#: app/flatpak-builtins-history.c:501
#, c-format
msgid "Failed to parse the --until option"
msgstr "Falló al analizar la opción --until"

#: app/flatpak-builtins-info.c:56
msgid "Show user installations"
msgstr "Mostrar instalaciones del usuario"

#: app/flatpak-builtins-info.c:57
msgid "Show system-wide installations"
msgstr "Mostrar instalaciones del sistema"

#: app/flatpak-builtins-info.c:58
msgid "Show specific system-wide installations"
msgstr "Mostrar instalaciones especificas del sistema"

#: app/flatpak-builtins-info.c:59 app/flatpak-builtins-remote-info.c:59
msgid "Show ref"
msgstr "Mostrar referencia"

#: app/flatpak-builtins-info.c:60 app/flatpak-builtins-remote-info.c:60
msgid "Show commit"
msgstr "Mostrar «commit»"

#: app/flatpak-builtins-info.c:61
msgid "Show origin"
msgstr "Mostrar origen"

#: app/flatpak-builtins-info.c:62
msgid "Show size"
msgstr "Mostrar tamaño"

#: app/flatpak-builtins-info.c:63 app/flatpak-builtins-remote-info.c:62
msgid "Show metadata"
msgstr "Mostrar metadatos"

#: app/flatpak-builtins-info.c:64 app/flatpak-builtins-remote-info.c:63
msgid "Show runtime"
msgstr "Mostrar rutina en tiempo de ejecución"

#: app/flatpak-builtins-info.c:65 app/flatpak-builtins-remote-info.c:64
msgid "Show sdk"
msgstr "Mostrar sdk"

#: app/flatpak-builtins-info.c:66
msgid "Show permissions"
msgstr "Mostrar permisos"

#: app/flatpak-builtins-info.c:67
msgid "Query file access"
msgstr "Consultar el acceso a archivos"

#: app/flatpak-builtins-info.c:67 app/flatpak-builtins-install.c:82
#: app/flatpak-builtins-install.c:88 app/flatpak-builtins-preinstall.c:68
#: app/flatpak-builtins-run.c:182 app/flatpak-builtins-run.c:184
#: app/flatpak-builtins-update.c:67 app/flatpak-builtins-update.c:71
msgid "PATH"
msgstr "RUTA"

#: app/flatpak-builtins-info.c:68
msgid "Show extensions"
msgstr "Mostrar extensiones"

#: app/flatpak-builtins-info.c:69
msgid "Show location"
msgstr "Mostrar ubicación"

#: app/flatpak-builtins-info.c:116
msgid "NAME [BRANCH] - Get info about an installed app or runtime"
msgstr ""
"NOMBRE [RAMA] - Obtener información sobre una aplicación y/o rutina en "
"tiempo de ejecución instalada"

#: app/flatpak-builtins-info.c:123 app/flatpak-builtins-remote-add.c:317
#: app/flatpak-builtins-remote-delete.c:63
msgid "NAME must be specified"
msgstr "Se debe especificar el NOMBRE"

#: app/flatpak-builtins-info.c:196
msgid "ref not present in origin"
msgstr "referencia no presente en el origen"

#: app/flatpak-builtins-info.c:211 app/flatpak-builtins-remote-info.c:217
#, c-format
msgid "Warning: Commit has no flatpak metadata\n"
msgstr "Advertencia: el «commir» no tiene metadatos de flatpak\n"

#: app/flatpak-builtins-info.c:217 app/flatpak-builtins-info.c:259
#: app/flatpak-builtins-info.c:455 app/flatpak-builtins-info.c:513
#: app/flatpak-builtins-remote-info.c:236
#: app/flatpak-builtins-remote-info.c:271
msgid "ID:"
msgstr "ID:"

#: app/flatpak-builtins-info.c:218 app/flatpak-builtins-info.c:260
#: app/flatpak-builtins-remote-info.c:237
#: app/flatpak-builtins-remote-info.c:272
msgid "Ref:"
msgstr "Referencia:"

#: app/flatpak-builtins-info.c:219 app/flatpak-builtins-info.c:261
#: app/flatpak-builtins-remote-info.c:238
#: app/flatpak-builtins-remote-info.c:273
msgid "Arch:"
msgstr "Arquitectura:"

#: app/flatpak-builtins-info.c:220 app/flatpak-builtins-info.c:262
#: app/flatpak-builtins-remote-info.c:239
#: app/flatpak-builtins-remote-info.c:274
msgid "Branch:"
msgstr "Rama:"

#: app/flatpak-builtins-info.c:222 app/flatpak-builtins-info.c:264
#: app/flatpak-builtins-remote-info.c:241
#: app/flatpak-builtins-remote-info.c:276
msgid "Version:"
msgstr "Versión:"

#: app/flatpak-builtins-info.c:224 app/flatpak-builtins-info.c:266
#: app/flatpak-builtins-remote-info.c:243
#: app/flatpak-builtins-remote-info.c:278
msgid "License:"
msgstr "Licencia:"

#: app/flatpak-builtins-info.c:226 app/flatpak-builtins-info.c:269
#: app/flatpak-builtins-remote-info.c:245
#: app/flatpak-builtins-remote-info.c:280
msgid "Collection:"
msgstr "Colección:"

#: app/flatpak-builtins-info.c:227 app/flatpak-builtins-info.c:270
#: app/flatpak-builtins-info.c:458 app/flatpak-builtins-info.c:516
msgid "Installation:"
msgstr "Instalación:"

#: app/flatpak-builtins-info.c:228 app/flatpak-builtins-info.c:271
#: app/flatpak-builtins-info.c:459 app/flatpak-builtins-info.c:517
#: app/flatpak-builtins-remote-info.c:249
#: app/flatpak-builtins-remote-info.c:284
#, fuzzy
msgid "Installed Size:"
msgstr "Tamaño de la instalación:"

#: app/flatpak-builtins-info.c:231 app/flatpak-builtins-info.c:279
#: app/flatpak-builtins-remote-info.c:252
#: app/flatpak-builtins-remote-info.c:288
msgid "Runtime:"
msgstr "Tiempo de ejecución:"

#: app/flatpak-builtins-info.c:232 app/flatpak-builtins-info.c:288
#: app/flatpak-builtins-remote-info.c:253
#: app/flatpak-builtins-remote-info.c:293
msgid "Sdk:"
msgstr "Sdk:"

#: app/flatpak-builtins-info.c:235 app/flatpak-builtins-info.c:313
#: app/flatpak-builtins-remote-info.c:256
#: app/flatpak-builtins-remote-info.c:319
msgid "Date:"
msgstr "Fecha:"

#: app/flatpak-builtins-info.c:237 app/flatpak-builtins-info.c:311
#: app/flatpak-builtins-remote-info.c:258
#: app/flatpak-builtins-remote-info.c:317
msgid "Subject:"
msgstr "Asunto:"

#: app/flatpak-builtins-info.c:240 app/flatpak-builtins-info.c:295
msgid "Active commit:"
msgstr "«Commit» activo:"

#: app/flatpak-builtins-info.c:241 app/flatpak-builtins-info.c:298
msgid "Latest commit:"
msgstr "Ultimo «commit»:"

#: app/flatpak-builtins-info.c:244 app/flatpak-builtins-info.c:303
#: app/flatpak-builtins-info.c:457 app/flatpak-builtins-info.c:515
#: app/flatpak-builtins-remote-info.c:259
#: app/flatpak-builtins-remote-info.c:298
msgid "Commit:"
msgstr "Commit:"

#: app/flatpak-builtins-info.c:246 app/flatpak-builtins-info.c:308
#: app/flatpak-builtins-remote-info.c:261
#: app/flatpak-builtins-remote-info.c:303
msgid "Parent:"
msgstr "Padre:"

#: app/flatpak-builtins-info.c:248 app/flatpak-builtins-info.c:321
msgid "Alt-id:"
msgstr "ID-alternativo:"

#: app/flatpak-builtins-info.c:250 app/flatpak-builtins-info.c:325
#: app/flatpak-builtins-remote-info.c:263
#: app/flatpak-builtins-remote-info.c:308
msgid "End-of-life:"
msgstr "Fin del ciclo de vida:"

#: app/flatpak-builtins-info.c:252 app/flatpak-builtins-info.c:330
#: app/flatpak-builtins-remote-info.c:265
#: app/flatpak-builtins-remote-info.c:313
msgid "End-of-life-rebase:"
msgstr "Rebasar ciclo de vida:"

#: app/flatpak-builtins-info.c:254 app/flatpak-builtins-info.c:317
msgid "Subdirectories:"
msgstr "Subcarpetas:"

#: app/flatpak-builtins-info.c:255 app/flatpak-builtins-info.c:454
#: app/flatpak-builtins-info.c:512
msgid "Extension:"
msgstr "Extensión:"

#: app/flatpak-builtins-info.c:267 app/flatpak-builtins-info.c:456
#: app/flatpak-builtins-info.c:514
msgid "Origin:"
msgstr "Origen:"

#: app/flatpak-builtins-info.c:460 app/flatpak-builtins-info.c:522
msgid "Subpaths:"
msgstr "Subcarpetas:"

#: app/flatpak-builtins-info.c:478
msgid "unmaintained"
msgstr "sin mantenimiento"

#: app/flatpak-builtins-info.c:480 app/flatpak-builtins-info.c:482
msgid "unknown"
msgstr "desconocido"

#: app/flatpak-builtins-install.c:68 app/flatpak-builtins-preinstall.c:57
msgid "Don't pull, only install from local cache"
msgstr "No actualizar, solo instalar del caché local"

#: app/flatpak-builtins-install.c:69 app/flatpak-builtins-preinstall.c:58
#: app/flatpak-builtins-update.c:60
msgid "Don't deploy, only download to local cache"
msgstr "No desplegar, solo descargar al caché local"

#: app/flatpak-builtins-install.c:70 app/flatpak-builtins-preinstall.c:59
msgid "Don't install related refs"
msgstr "No instalar referencias relacionadas"

#: app/flatpak-builtins-install.c:71 app/flatpak-builtins-preinstall.c:60
#: app/flatpak-builtins-update.c:62
msgid "Don't verify/install runtime dependencies"
msgstr ""
"No verificar/instalar las dependencias de la rutina en tiempo de ejecución"

#: app/flatpak-builtins-install.c:72
msgid "Don't automatically pin explicit installs"
msgstr "No fijar automáticamente la instalaciones explícitas"

#: app/flatpak-builtins-install.c:73 app/flatpak-builtins-preinstall.c:61
#: app/flatpak-builtins-update.c:63
msgid "Don't use static deltas"
msgstr "No usar diferencias estáticas"

#: app/flatpak-builtins-install.c:76 app/flatpak-builtins-preinstall.c:62
msgid "Additionally install the SDK used to build the given refs"
msgstr "Además, instalar el SDK utilizado para construir las referencias dadas"

#: app/flatpak-builtins-install.c:77 app/flatpak-builtins-preinstall.c:63
msgid ""
"Additionally install the debug info for the given refs and their dependencies"
msgstr ""
"Además, instalar la información de depuración para las referencias dadas y "
"sus dependencias"

#: app/flatpak-builtins-install.c:78
msgid "Assume LOCATION is a .flatpak single-file bundle"
msgstr "Asumir que UBICACIÓN es un paquete .flatpak de un solo archivo"

#: app/flatpak-builtins-install.c:79
msgid "Assume LOCATION is a .flatpakref application description"
msgstr "Asumir que UBICACIÓN es una descripción de aplicación .flatpakref"

#: app/flatpak-builtins-install.c:80
msgid "Assume LOCATION is containers-transports(5) reference to an OCI image"
msgstr ""

#: app/flatpak-builtins-install.c:81
msgid "Check bundle signatures with GPG key from FILE (- for stdin)"
msgstr ""
"Comprobar las firmas del paquete con las claves GPG del ARCHIVO (- para "
"stdin)"

#: app/flatpak-builtins-install.c:82
msgid "Only install this subpath"
msgstr "Solo instalar esta subruta"

#: app/flatpak-builtins-install.c:83 app/flatpak-builtins-preinstall.c:64
#: app/flatpak-builtins-uninstall.c:63 app/flatpak-builtins-update.c:68
msgid "Automatically answer yes for all questions"
msgstr "Responder si automáticamente a todas las preguntas"

#: app/flatpak-builtins-install.c:84 app/flatpak-builtins-preinstall.c:65
msgid "Uninstall first if already installed"
msgstr "Desinstalar primero si ya está instalado"

#: app/flatpak-builtins-install.c:85 app/flatpak-builtins-preinstall.c:66
#: app/flatpak-builtins-uninstall.c:64 app/flatpak-builtins-update.c:69
msgid "Produce minimal output and don't ask questions"
msgstr "Producir una salida mínima y no hacer preguntas"

#: app/flatpak-builtins-install.c:86
msgid "Update install if already installed"
msgstr "Actualizar la instalación si ya está instalado"

#. Translators: A sideload is when you install from a local USB drive rather than the Internet.
#: app/flatpak-builtins-install.c:88 app/flatpak-builtins-preinstall.c:68
#: app/flatpak-builtins-update.c:71
msgid "Use this local repo for sideloads"
msgstr "Usar este repositorio local para instalaciones desde USB"

#: app/flatpak-builtins-install.c:178
msgid "Bundle filename must be specified"
msgstr "Se debe especificar el nombre de archivo del paquete"

#: app/flatpak-builtins-install.c:188
msgid "Remote bundles are not supported"
msgstr "Los paquetes remotos no están soportados"

#: app/flatpak-builtins-install.c:231
msgid "Filename or uri must be specified"
msgstr "Se debe especificar el nombre de archivo o el uri"

#: app/flatpak-builtins-install.c:295
#, fuzzy
msgid "Image location must be specified"
msgstr "Se debe especificar al menos una REFERENCIA"

#: app/flatpak-builtins-install.c:345
msgid "[LOCATION/REMOTE] [REF…] - Install applications or runtimes"
msgstr ""
"[UBICACIÓN/REMOTO] [REFERENCIA…] - Instala aplicaciones o rutinas en tiempo "
"de ejecución"

#: app/flatpak-builtins-install.c:378
msgid "At least one REF must be specified"
msgstr "Se debe especificar al menos una REFERENCIA"

#: app/flatpak-builtins-install.c:392
#, c-format
msgid "Looking for matches…\n"
msgstr "Buscando coincidencias…\n"

#: app/flatpak-builtins-install.c:513
#, c-format
msgid "No remote refs found for ‘%s’"
msgstr "No se encontraron referencias remotas para «%s»"

#: app/flatpak-builtins-install.c:573 app/flatpak-builtins-uninstall.c:405
#: common/flatpak-ref-utils.c:689 common/flatpak-ref-utils.c:1595
#, c-format
msgid "Invalid branch %s: %s"
msgstr "Rama «%s» no válida: %s"

#: app/flatpak-builtins-install.c:606
#, c-format
msgid "Nothing matches %s in local repository for remote %s"
msgstr "Nada coincide con %s en el repositorio local de la rama remota %s"

#: app/flatpak-builtins-install.c:608
#, c-format
msgid "Nothing matches %s in remote %s"
msgstr "Nada coincide con %s en la rama remota %s"

#: app/flatpak-builtins-install.c:629
#, c-format
msgid "Skipping: %s\n"
msgstr "Saltando: %s\n"

#: app/flatpak-builtins-kill.c:110
#, c-format
msgid "%s is not running"
msgstr "%s no se está ejecutando"

#: app/flatpak-builtins-kill.c:136
msgid "INSTANCE - Stop a running application"
msgstr "INSTANCIA - Detiene una aplicación en ejecución"

#: app/flatpak-builtins-kill.c:144 app/flatpak-builtins-ps.c:256
msgid "Extra arguments given"
msgstr "Se han dado argumentos adicionales"

#: app/flatpak-builtins-kill.c:150
msgid "Must specify the app to kill"
msgstr "Se debe especificar la aplicación que matar"

#: app/flatpak-builtins-list.c:47
msgid "Show extra information"
msgstr "Mostrar información adicional"

#: app/flatpak-builtins-list.c:48
msgid "List installed runtimes"
msgstr "Listar las rutinas en tiempo de ejecución instaladas"

#: app/flatpak-builtins-list.c:49
msgid "List installed applications"
msgstr "Listar las aplicaciones instaladas"

#: app/flatpak-builtins-list.c:50
msgid "Arch to show"
msgstr "Arquitectura que mostrar"

#: app/flatpak-builtins-list.c:51 app/flatpak-builtins-remote-ls.c:57
msgid "List all refs (including locale/debug)"
msgstr "Listar todas las referencias (incluyendo región/depuración)"

#: app/flatpak-builtins-list.c:53 app/flatpak-builtins-remote-ls.c:58
msgid "List all applications using RUNTIME"
msgstr "Listar todas las aplicaciones que usan RUNTIME"

#: app/flatpak-builtins-list.c:59 app/flatpak-builtins-remote-list.c:51
#: app/flatpak-builtins-remote-ls.c:68 app/flatpak-builtins-search.c:44
msgid "Name"
msgstr "Nombre"

#: app/flatpak-builtins-list.c:59 app/flatpak-builtins-remote-list.c:51
#: app/flatpak-builtins-remote-ls.c:68 app/flatpak-builtins-search.c:44
msgid "Show the name"
msgstr "Mostrar el nombre"

#: app/flatpak-builtins-list.c:60 app/flatpak-builtins-remote-list.c:60
#: app/flatpak-builtins-remote-ls.c:69 app/flatpak-builtins-search.c:45
msgid "Description"
msgstr "Descripción"

#: app/flatpak-builtins-list.c:60 app/flatpak-builtins-remote-ls.c:69
#: app/flatpak-builtins-search.c:45
msgid "Show the description"
msgstr "Mostrar la descripción"

#: app/flatpak-builtins-list.c:61 app/flatpak-builtins-remote-ls.c:70
#: app/flatpak-builtins-search.c:46
msgid "Application ID"
msgstr "ID de aplicación"

#: app/flatpak-builtins-list.c:61 app/flatpak-builtins-ps.c:52
#: app/flatpak-builtins-remote-ls.c:70 app/flatpak-builtins-search.c:46
msgid "Show the application ID"
msgstr "Mostrar ID de aplicación"

#: app/flatpak-builtins-list.c:62 app/flatpak-builtins-remote-ls.c:71
#: app/flatpak-builtins-search.c:47
msgid "Show the version"
msgstr "Mostrar la versión"

#: app/flatpak-builtins-list.c:65 app/flatpak-builtins-ps.c:56
#: app/flatpak-builtins-remote-ls.c:77
msgid "Runtime"
msgstr "Runtime"

#: app/flatpak-builtins-list.c:65
msgid "Show the used runtime"
msgstr "Mostrar la rutina en tiempo de ejecución usada"

#: app/flatpak-builtins-list.c:66 app/flatpak-builtins-remote-ls.c:74
msgid "Show the origin remote"
msgstr "Mostrar la rama remota de origen"

#: app/flatpak-builtins-list.c:67
msgid "Show the installation"
msgstr "Mostrar la instalación"

#: app/flatpak-builtins-list.c:69
msgid "Active commit"
msgstr "«Commit» activo"

#: app/flatpak-builtins-list.c:69 app/flatpak-builtins-remote-ls.c:76
msgid "Show the active commit"
msgstr "Mostrar el «commit» activo"

#: app/flatpak-builtins-list.c:70
msgid "Latest commit"
msgstr "Último «commit»"

#: app/flatpak-builtins-list.c:70
msgid "Show the latest commit"
msgstr "Mostrar el último «commit»"

#: app/flatpak-builtins-list.c:71 app/flatpak-builtins-remote-ls.c:78
msgid "Installed size"
msgstr "Tamaño de la instalación"

#: app/flatpak-builtins-list.c:71 app/flatpak-builtins-remote-ls.c:78
msgid "Show the installed size"
msgstr "Mostrar el tamaño de la instalación"

#: app/flatpak-builtins-list.c:72 app/flatpak-builtins-remote-list.c:58
#: app/flatpak-builtins-remote-ls.c:80 app/flatpak-builtins-repo.c:340
msgid "Options"
msgstr "Opciones"

#: app/flatpak-builtins-list.c:72 app/flatpak-builtins-remote-list.c:58
#: app/flatpak-builtins-remote-ls.c:80
msgid "Show options"
msgstr "Mostrar las opciones"

#: app/flatpak-builtins-list.c:180
#, fuzzy, c-format
msgid "Unable to load details of %s: %s"
msgstr ""
"Actualizando los metadatos adicionales desde el resumen remoto para %s\n"

#: app/flatpak-builtins-list.c:190
#, fuzzy, c-format
msgid "Unable to inspect current version of %s: %s"
msgstr "No se puede obtener el tipo de archivo de «%s»: %s"

#: app/flatpak-builtins-list.c:408
msgid " - List installed apps and/or runtimes"
msgstr ""
" - Listar las aplicaciones y/o rutinas en tiempo de ejecución instaladas"

#: app/flatpak-builtins-make-current.c:38
msgid "Arch to make current for"
msgstr "Arquitectura que hacer actual"

#: app/flatpak-builtins-make-current.c:58
msgid "APP BRANCH - Make branch of application current"
msgstr "APLICACIÓN RAMA - Establece la rama de la aplicación que usar"

#: app/flatpak-builtins-make-current.c:69 app/flatpak-builtins-run.c:260
msgid "APP must be specified"
msgstr "Se debe especificar APLICACIÓN"

#: app/flatpak-builtins-make-current.c:84
msgid "BRANCH must be specified"
msgstr "Se debe especificar RAMA"

#: app/flatpak-builtins-make-current.c:97
#, c-format
msgid "App %s branch %s is not installed"
msgstr "La aplicación %s de la rama %s no está instalada"

#: app/flatpak-builtins-mask.c:42
msgid "Remove matching masks"
msgstr "Eliminar las máscaras que coincidan"

#: app/flatpak-builtins-mask.c:54
msgid ""
"[PATTERN…] - disable updates and automatic installation matching patterns"
msgstr ""
"[PATRÓN…] - desactivar actualizaciones e instalaciones automáticas que "
"coincidan con los patrones"

#: app/flatpak-builtins-mask.c:73
#, c-format
msgid "No masked patterns\n"
msgstr "No hay patrones enmascarados\n"

#: app/flatpak-builtins-mask.c:78
#, c-format
msgid "Masked patterns:\n"
msgstr "Patrones enmascarados:\n"

#: app/flatpak-builtins-override.c:42
msgid "Remove existing overrides"
msgstr "Eliminar los reemplazos existentes"

#: app/flatpak-builtins-override.c:43
msgid "Show existing overrides"
msgstr "Mostrar los reemplazos existentes"

#: app/flatpak-builtins-override.c:59
msgid "[APP] - Override settings [for application]"
msgstr "[APLICACIÓN] - Reemplazar configuraciones [de aplicación]"

#: app/flatpak-builtins-permission-list.c:143
msgid "[TABLE] [ID] - List permissions"
msgstr "[TABLA] [ID] - Listar permisos"

#: app/flatpak-builtins-permission-list.c:179
#: app/flatpak-builtins-permission-show.c:142
msgid "Table"
msgstr "Tabla"

#: app/flatpak-builtins-permission-list.c:180
#: app/flatpak-builtins-permission-show.c:143
msgid "Object"
msgstr "Objeto"

#: app/flatpak-builtins-permission-list.c:181
#: app/flatpak-builtins-permission-show.c:144
msgid "App"
msgstr "Aplicación"

#: app/flatpak-builtins-permission-list.c:183
#: app/flatpak-builtins-permission-show.c:146
msgid "Data"
msgstr "Datos"

#: app/flatpak-builtins-permission-remove.c:120
msgid "TABLE ID [APP_ID] - Remove item from permission store"
msgstr "TABLA ID [ID_APLICACIÓN] - Elimina un elemento del almacén de permisos"

#: app/flatpak-builtins-permission-remove.c:129
#: app/flatpak-builtins-permission-set.c:120
msgid "Too few arguments"
msgstr "No hay suficientes argumentos"

#: app/flatpak-builtins-permission-reset.c:43
msgid "Reset all permissions"
msgstr "Restablecer todos los permisos"

#: app/flatpak-builtins-permission-reset.c:144
msgid "APP_ID - Reset permissions for an app"
msgstr "ID_APLICACIÓN - Restablece los permisos de una aplicación"

#: app/flatpak-builtins-permission-reset.c:153
#: app/flatpak-builtins-permission-show.c:124
msgid "Wrong number of arguments"
msgstr "Número erróneo de argumentos"

#: app/flatpak-builtins-permission-set.c:42
msgid "Associate DATA with the entry"
msgstr "Asociar DATOS con la entrada"

#: app/flatpak-builtins-permission-set.c:42
msgid "DATA"
msgstr "DATOS"

#: app/flatpak-builtins-permission-set.c:111
msgid "TABLE ID APP_ID [PERMISSION...] - Set permissions"
msgstr "TABLA ID ID_APLICACIÓN [PERMISO…] - Establecer permisos"

#: app/flatpak-builtins-permission-set.c:132
#, c-format
msgid "Failed to parse '%s' as GVariant: "
msgstr "Falló al analizar «%s» como GVariant: "

#: app/flatpak-builtins-permission-show.c:115
msgid "APP_ID - Show permissions for an app"
msgstr "ID_APLICACIÓN - Mostrar los permisos de una aplicación"

#: app/flatpak-builtins-pin.c:44
msgid "Remove matching pins"
msgstr "Eliminar los fijadores que coincidan"

#: app/flatpak-builtins-pin.c:56
msgid "[PATTERN…] - disable automatic removal of runtimes matching patterns"
msgstr ""
"[PATRÓN…] - desactivar la eliminación automática de rutinas en tiempo de "
"ejecución que coincidan con los patrones"

#: app/flatpak-builtins-pin.c:75
#, c-format
msgid "No pinned patterns\n"
msgstr "Patrones sin fijar\n"

#: app/flatpak-builtins-pin.c:80
#, c-format
msgid "Pinned patterns:\n"
msgstr "Patrones fijados:\n"

#: app/flatpak-builtins-preinstall.c:80
msgid "- Install flatpaks that are part of the operating system"
msgstr ""

#: app/flatpak-builtins-preinstall.c:118
#, c-format
msgid "Nothing to do.\n"
msgstr "Nada que hacer.\n"

#: app/flatpak-builtins-ps.c:49
msgid "Instance"
msgstr "Instancia"

#: app/flatpak-builtins-ps.c:49
msgid "Show the instance ID"
msgstr "Mostrar ID de instancia"

#: app/flatpak-builtins-ps.c:50 app/flatpak-builtins-run.c:178
msgid "PID"
msgstr "PID"

#: app/flatpak-builtins-ps.c:50
msgid "Show the PID of the wrapper process"
msgstr "Mostrar el PID del proceso contenedor"

#: app/flatpak-builtins-ps.c:51
msgid "Child-PID"
msgstr "PID-hijo"

#: app/flatpak-builtins-ps.c:51
msgid "Show the PID of the sandbox process"
msgstr "Mostrar el PID del proceso del entorno aislado"

#: app/flatpak-builtins-ps.c:54 app/flatpak-builtins-search.c:48
msgid "Show the application branch"
msgstr "Mostrar la rama de la aplicación"

#: app/flatpak-builtins-ps.c:55
msgid "Show the application commit"
msgstr "Mostrar el «commit» de la aplicación"

#: app/flatpak-builtins-ps.c:56
msgid "Show the runtime ID"
msgstr "Mostrar ID de la rutina en tiempo de ejecución"

#: app/flatpak-builtins-ps.c:57
msgid "R.-Branch"
msgstr "R.-Rama"

#: app/flatpak-builtins-ps.c:57
msgid "Show the runtime branch"
msgstr "Mostrar la rama de la rutina en tiempo de ejecución"

#: app/flatpak-builtins-ps.c:58
msgid "R.-Commit"
msgstr "R.-Commit"

#: app/flatpak-builtins-ps.c:58
msgid "Show the runtime commit"
msgstr "Mostrar el «commit» de la rutina en tiempo de ejecución"

#: app/flatpak-builtins-ps.c:59
msgid "Active"
msgstr "Activa"

#: app/flatpak-builtins-ps.c:59
msgid "Show whether the app is active"
msgstr "Mostrar si la aplicación está activa"

#: app/flatpak-builtins-ps.c:60
msgid "Background"
msgstr "Segundo plano"

#: app/flatpak-builtins-ps.c:60
msgid "Show whether the app is background"
msgstr "Mostrar si la aplicación está en segundo plano"

#: app/flatpak-builtins-ps.c:246
msgid " - Enumerate running sandboxes"
msgstr " - Enumerar los entornos aislados en ejecución"

#: app/flatpak-builtins-remote-add.c:66
msgid "Do nothing if the provided remote exists"
msgstr "No hacer nada si el repositorio remoto dado ya existe"

#: app/flatpak-builtins-remote-add.c:67
msgid "LOCATION specifies a configuration file, not the repo location"
msgstr ""
"UBICACIÓN establece un archivo de configuración, no la ubicación del "
"repositorio"

#: app/flatpak-builtins-remote-add.c:72 app/flatpak-builtins-remote-modify.c:78
msgid "Disable GPG verification"
msgstr "Desactivar la verificación GPG"

#: app/flatpak-builtins-remote-add.c:73 app/flatpak-builtins-remote-modify.c:79
msgid "Mark the remote as don't enumerate"
msgstr "Establecer el remoto como «no enumerar»"

#: app/flatpak-builtins-remote-add.c:74 app/flatpak-builtins-remote-modify.c:80
msgid "Mark the remote as don't use for deps"
msgstr "Establecer el remoto como «no usar para las dependencias»"

#: app/flatpak-builtins-remote-add.c:75 app/flatpak-builtins-remote-modify.c:81
msgid "Set priority (default 1, higher is more prioritized)"
msgstr ""
"Establecer prioridad (1 predeterminado, mayor prioridad cuanto más alto)"

#: app/flatpak-builtins-remote-add.c:75 app/flatpak-builtins-remote-modify.c:81
msgid "PRIORITY"
msgstr "PRIORIDAD"

#: app/flatpak-builtins-remote-add.c:76
msgid "The named subset to use for this remote"
msgstr "El subconjunto nombrado que usar para este remoto"

#: app/flatpak-builtins-remote-add.c:76 app/flatpak-builtins-remote-modify.c:71
msgid "SUBSET"
msgstr "SUBCONJUNTO"

#: app/flatpak-builtins-remote-add.c:77 app/flatpak-builtins-remote-modify.c:82
msgid "A nice name to use for this remote"
msgstr "Un buen nombre que usar en este repositorio remoto"

#: app/flatpak-builtins-remote-add.c:78 app/flatpak-builtins-remote-modify.c:83
msgid "A one-line comment for this remote"
msgstr "Un comentario de una línea para este repositorio remoto"

#: app/flatpak-builtins-remote-add.c:79 app/flatpak-builtins-remote-modify.c:84
msgid "A full-paragraph description for this remote"
msgstr "Una descripción completa de este repositorio remoto"

#: app/flatpak-builtins-remote-add.c:80 app/flatpak-builtins-remote-modify.c:85
msgid "URL for a website for this remote"
msgstr "URL del sitio web de este repositorio remoto"

#: app/flatpak-builtins-remote-add.c:81 app/flatpak-builtins-remote-modify.c:86
msgid "URL for an icon for this remote"
msgstr "URL del icono de este repositorio remoto"

#: app/flatpak-builtins-remote-add.c:82 app/flatpak-builtins-remote-modify.c:87
msgid "Default branch to use for this remote"
msgstr "Rama predeterminada que usar en este repositorio remoto"

#: app/flatpak-builtins-remote-add.c:84 app/flatpak-builtins-remote-modify.c:89
msgid "Import GPG key from FILE (- for stdin)"
msgstr "Importar la clave GPG desde un ARCHIVO (- para stdin)"

#: app/flatpak-builtins-remote-add.c:85 app/flatpak-builtins-remote-modify.c:90
msgid "Load signatures from URL"
msgstr ""

#: app/flatpak-builtins-remote-add.c:86 app/flatpak-builtins-remote-modify.c:92
msgid "Set path to local filter FILE"
msgstr "Establecer la ruta al ARCHIVO de filtro local"

#: app/flatpak-builtins-remote-add.c:87 app/flatpak-builtins-remote-modify.c:93
msgid "Disable the remote"
msgstr "Desactivar el repositorio remoto"

#: app/flatpak-builtins-remote-add.c:88 app/flatpak-builtins-remote-modify.c:94
msgid "Name of authenticator"
msgstr "Nombre del autenticador"

#: app/flatpak-builtins-remote-add.c:90 app/flatpak-builtins-remote-modify.c:96
msgid "Autoinstall authenticator"
msgstr "Instalar el autenticador automáticamente"

#: app/flatpak-builtins-remote-add.c:91 app/flatpak-builtins-remote-modify.c:97
msgid "Don't autoinstall authenticator"
msgstr "No instalar el autenticador automáticamente"

#: app/flatpak-builtins-remote-add.c:92 app/flatpak-builtins-remote-modify.c:99
msgid "Don't follow the redirect set in the summary file"
msgstr "No seguir la redirección establecida en el archivo de resumen"

#: app/flatpak-builtins-remote-add.c:261 app/flatpak-builtins-remote-add.c:268
#, c-format
msgid "Can't load uri %s: %s\n"
msgstr "No se puede cargar el uri %s: %s\n"

#: app/flatpak-builtins-remote-add.c:276 common/flatpak-dir.c:4643
#, c-format
msgid "Can't load file %s: %s\n"
msgstr "No se puede cargar el archivo %s: %s\n"

#: app/flatpak-builtins-remote-add.c:304
msgid "NAME LOCATION - Add a remote repository"
msgstr "NOMBRE UBICACIÓN - Añadir un repositorio remoto"

#: app/flatpak-builtins-remote-add.c:331
msgid "GPG verification is required if collections are enabled"
msgstr "La verificación GPG es obligatoria si las colecciones están activadas"

#: app/flatpak-builtins-remote-add.c:393
#, c-format
msgid "Remote %s already exists"
msgstr "El repositorio remoto %s ya existe"

#: app/flatpak-builtins-remote-add.c:405
#: app/flatpak-builtins-remote-modify.c:340
#, c-format
msgid "Invalid authenticator name %s"
msgstr "Nombre de autenticador %s no válido"

#: app/flatpak-builtins-remote-add.c:422
#, c-format
msgid "Warning: Could not update extra metadata for '%s': %s\n"
msgstr ""
"Advertencia: no se pueden actualizar los metadatos adicionales para «%s»: "
"%s\n"

#: app/flatpak-builtins-remote-delete.c:39
msgid "Remove remote even if in use"
msgstr "Eliminar el repositorio remoto incluso si está en uso"

#: app/flatpak-builtins-remote-delete.c:53
msgid "NAME - Delete a remote repository"
msgstr "NOMBRE - Borra un repositorio remoto"

#: app/flatpak-builtins-remote-delete.c:100
#, c-format
msgid "The following refs are installed from remote '%s':"
msgstr ""
"Las referencias siguientes están instaladas desde el repositorio remoto «%s»:"

#: app/flatpak-builtins-remote-delete.c:101
msgid "Remove them?"
msgstr "¿Eliminarlas?"

#: app/flatpak-builtins-remote-delete.c:103
#, c-format
msgid "Can't remove remote '%s' with installed refs"
msgstr ""
"No se puede eliminar el repositorio remoto «%s» con las referencias "
"instaladas"

#: app/flatpak-builtins-remote-info.c:55
msgid "Commit to show info for"
msgstr "«Commit» para el que mostrar información"

#: app/flatpak-builtins-remote-info.c:58
msgid "Display log"
msgstr "Mostrar registro"

#: app/flatpak-builtins-remote-info.c:61
msgid "Show parent"
msgstr "Mostrar padre"

#: app/flatpak-builtins-remote-info.c:65 app/flatpak-builtins-remote-ls.c:60
msgid "Use local caches even if they are stale"
msgstr "Usar cachés locales incluso si están obsoletos"

#. Translators: A sideload is when you install from a local USB drive rather than the Internet.
#: app/flatpak-builtins-remote-info.c:67 app/flatpak-builtins-remote-ls.c:62
msgid "Only list refs available as sideloads"
msgstr "Solo listar referencias disponibles como instalación local por USB"

#: app/flatpak-builtins-remote-info.c:114
msgid ""
" REMOTE REF - Show information about an application or runtime in a remote"
msgstr ""
" REMOTO REF - Muestra información sobre una aplicación o rutina en tiempo de "
"ejecución en un repositorio remoto"

#: app/flatpak-builtins-remote-info.c:125
msgid "REMOTE and REF must be specified"
msgstr "Se debe especificar REMOTO y REFERENCIA"

#: app/flatpak-builtins-remote-info.c:247
#: app/flatpak-builtins-remote-info.c:282
#, fuzzy
msgid "Download Size:"
msgstr "Tamaño de la descarga"

#: app/flatpak-builtins-remote-info.c:267
#: app/flatpak-builtins-remote-info.c:325
msgid "History:"
msgstr "Histórico:"

#: app/flatpak-builtins-remote-info.c:348
msgid " Commit:"
msgstr " Commit:"

#: app/flatpak-builtins-remote-info.c:349
msgid " Subject:"
msgstr " Asunto:"

#: app/flatpak-builtins-remote-info.c:350
msgid " Date:"
msgstr " Fecha:"

#: app/flatpak-builtins-remote-info.c:383
#, c-format
msgid "Warning: Commit %s has no flatpak metadata\n"
msgstr "Advertencia: el «commit» %s no tiene metadatos flatpak\n"

#: app/flatpak-builtins-remote-list.c:43
msgid "Show remote details"
msgstr "Mostrar detalles del repositorio remoto"

#: app/flatpak-builtins-remote-list.c:44
msgid "Show disabled remotes"
msgstr "Mostrar repositorios remotos desactivados"

#: app/flatpak-builtins-remote-list.c:52
msgid "Title"
msgstr "Título"

#: app/flatpak-builtins-remote-list.c:52
msgid "Show the title"
msgstr "Mostrar el título"

#: app/flatpak-builtins-remote-list.c:53
msgid "Show the URL"
msgstr "Mostrar la URL"

#: app/flatpak-builtins-remote-list.c:54
msgid "Show the collection ID"
msgstr "Mostrar la ID de colección"

#: app/flatpak-builtins-remote-list.c:55 app/flatpak-builtins-repo.c:392
msgid "Subset"
msgstr "Subconjunto"

#: app/flatpak-builtins-remote-list.c:55
msgid "Show the subset"
msgstr "Mostrar el subconjunto"

#: app/flatpak-builtins-remote-list.c:56
msgid "Filter"
msgstr "Filtro"

#: app/flatpak-builtins-remote-list.c:56
msgid "Show filter file"
msgstr "Mostrar el archivo de filtro"

#: app/flatpak-builtins-remote-list.c:57
msgid "Priority"
msgstr "Prioridad"

#: app/flatpak-builtins-remote-list.c:57
msgid "Show the priority"
msgstr "Mostrar la prioridad"

#: app/flatpak-builtins-remote-list.c:59
msgid "Comment"
msgstr "Comentario"

#: app/flatpak-builtins-remote-list.c:59
msgid "Show comment"
msgstr "Mostrar comentario"

#: app/flatpak-builtins-remote-list.c:60
msgid "Show description"
msgstr "Mostrar descripción"

#: app/flatpak-builtins-remote-list.c:61
msgid "Homepage"
msgstr "Página de inicio"

#: app/flatpak-builtins-remote-list.c:61
msgid "Show homepage"
msgstr "Mostrar la página de inicio"

#: app/flatpak-builtins-remote-list.c:62
msgid "Icon"
msgstr "Icono"

#: app/flatpak-builtins-remote-list.c:62
msgid "Show icon"
msgstr "Mostrar icono"

#: app/flatpak-builtins-remote-list.c:231
msgid " - List remote repositories"
msgstr " - Mostrar lista de repositorios remotos"

#: app/flatpak-builtins-remote-ls.c:52
msgid "Show arches and branches"
msgstr "Mostrar arquitecturas y ramas"

#: app/flatpak-builtins-remote-ls.c:53
msgid "Show only runtimes"
msgstr "Mostrar solo rutinas en tiempo de ejecución"

#: app/flatpak-builtins-remote-ls.c:54
msgid "Show only apps"
msgstr "Mostrar solo aplicaciones"

#: app/flatpak-builtins-remote-ls.c:55
msgid "Show only those where updates are available"
msgstr "Mostrar solo los que tienen actualizaciones disponibles"

#: app/flatpak-builtins-remote-ls.c:56
msgid "Limit to this arch (* for all)"
msgstr "Limitar a esta arquitectura (* para mostrar todas)"

#: app/flatpak-builtins-remote-ls.c:77
msgid "Show the runtime"
msgstr "Mostrar la rutina en tiempo de ejecución"

#: app/flatpak-builtins-remote-ls.c:79
msgid "Download size"
msgstr "Tamaño de la descarga"

#: app/flatpak-builtins-remote-ls.c:79
msgid "Show the download size"
msgstr "Mostrar el tamaño de la descarga"

#: app/flatpak-builtins-remote-ls.c:391
msgid " [REMOTE or URI] - Show available runtimes and applications"
msgstr ""
" [REMOTO o URI] - Mostrar rutinas en tiempo de ejecución y aplicaciones "
"disponibles"

#: app/flatpak-builtins-remote-modify.c:67
msgid "Enable GPG verification"
msgstr "Activar la verificación GPG"

#: app/flatpak-builtins-remote-modify.c:68
msgid "Mark the remote as enumerate"
msgstr "Establecer el repositorio remoto como enumerar"

#: app/flatpak-builtins-remote-modify.c:69
msgid "Mark the remote as used for dependencies"
msgstr "Establecer el repositorio remoto como usado por las dependencias"

#: app/flatpak-builtins-remote-modify.c:70
#, fuzzy
msgid "Set a new URL"
msgstr "Establecer una url nueva"

#: app/flatpak-builtins-remote-modify.c:71
msgid "Set a new subset to use"
msgstr "Establecer un subconjunto nuevo que usar"

#: app/flatpak-builtins-remote-modify.c:72
msgid "Enable the remote"
msgstr "Activar el repositorio remoto"

#: app/flatpak-builtins-remote-modify.c:73
msgid "Update extra metadata from the summary file"
msgstr "Actualizar los metadatos adicionales desde el archivo de resumen"

#: app/flatpak-builtins-remote-modify.c:91
msgid "Disable local filter"
msgstr "Desactivar el filtro local"

#: app/flatpak-builtins-remote-modify.c:95
msgid "Authenticator options"
msgstr "Opciones del autenticador"

#: app/flatpak-builtins-remote-modify.c:98
msgid "Follow the redirect set in the summary file"
msgstr "Seguir la redirección establecida en el archivo de resumen"

#: app/flatpak-builtins-remote-modify.c:306
msgid "NAME - Modify a remote repository"
msgstr "NOMBRE - Modificar un repositorio remoto"

#: app/flatpak-builtins-remote-modify.c:316
msgid "Remote NAME must be specified"
msgstr "Se debe especificar el NOMBRE del repositorio remoto"

#: app/flatpak-builtins-remote-modify.c:327
#, c-format
msgid "Updating extra metadata from remote summary for %s\n"
msgstr ""
"Actualizando los metadatos adicionales desde el resumen del repositorio "
"remoto para %s\n"

#: app/flatpak-builtins-remote-modify.c:330
#, c-format
msgid "Error updating extra metadata for '%s': %s\n"
msgstr "Error al actualizar los metadatos adicionales para «%s»: %s\n"

#: app/flatpak-builtins-remote-modify.c:331
#, c-format
msgid "Could not update extra metadata for %s"
msgstr "No se han podido actualizar los metadatos adicionales para %s"

#: app/flatpak-builtins-repair.c:43
msgid "Don't make any changes"
msgstr "No hacer ningún cambio"

#: app/flatpak-builtins-repair.c:44
msgid "Reinstall all refs"
msgstr "Reinstalar todas las referencias"

#: app/flatpak-builtins-repair.c:68
#, c-format
msgid "Object missing: %s.%s\n"
msgstr "Falta un objeto: %s.%s\n"

#: app/flatpak-builtins-repair.c:76
#, c-format
msgid "Object invalid: %s.%s\n"
msgstr "Objeto no válido %s.%s\n"

#: app/flatpak-builtins-repair.c:81
#, c-format
msgid "%s, deleting object\n"
msgstr "%s, eliminando objeto\n"

#: app/flatpak-builtins-repair.c:146
#, c-format
msgid "Can't load object %s: %s\n"
msgstr "No se puede cargar el objeto %s: %s\n"

#: app/flatpak-builtins-repair.c:228
#, c-format
msgid "Commit invalid %s: %s\n"
msgstr "Confirmación no válida %s: %s\n"

#: app/flatpak-builtins-repair.c:231
#, c-format
msgid "Deleting invalid commit %s: %s\n"
msgstr "Eliminando confirmación no válida %s: %s\n"

#: app/flatpak-builtins-repair.c:261
#, c-format
msgid "Commit should be marked partial: %s\n"
msgstr "La confirmación debe marcarse como parcial: %s\n"

#: app/flatpak-builtins-repair.c:264
#, c-format
msgid "Marking commit as partial: %s\n"
msgstr "Marcando confirmación como parcial: %s\n"

#: app/flatpak-builtins-repair.c:293
#, c-format
msgid "Problems loading data for %s: %s\n"
msgstr "Problemas al cargar los datos de %s: %s\n"

#: app/flatpak-builtins-repair.c:306
#, c-format
msgid "Error reinstalling %s: %s\n"
msgstr "Error al reinstalar %s: %s\n"

#: app/flatpak-builtins-repair.c:327
msgid "- Repair a flatpak installation"
msgstr "- Reparar una instalación de flatpak"

#: app/flatpak-builtins-repair.c:406
#, c-format
msgid "Removing non-deployed ref %s…\n"
msgstr "Quitando la ref no implementada %s…\n"

#: app/flatpak-builtins-repair.c:411
#, c-format
msgid "Skipping non-deployed ref %s…\n"
msgstr "Saltando la ref no implementada %s…\n"

#: app/flatpak-builtins-repair.c:429
#, c-format
msgid "[%d/%d] Verifying %s…\n"
msgstr "[%d/%d] Verificando %s…\n"

#: app/flatpak-builtins-repair.c:435
#, c-format
msgid "Dry run: "
msgstr "Ejecución en seco: "

#: app/flatpak-builtins-repair.c:440
#, c-format
msgid "Deleting ref %s due to missing objects\n"
msgstr "Eliminando la ref %s debido a que faltan objetos\n"

#: app/flatpak-builtins-repair.c:444
#, c-format
msgid "Deleting ref %s due to invalid objects\n"
msgstr "Eliminando la ref %s debido a objetos no válidos\n"

#: app/flatpak-builtins-repair.c:448
#, c-format
msgid "Deleting ref %s due to %d\n"
msgstr "Eliminando la ref %s debido a %d\n"

#: app/flatpak-builtins-repair.c:464
#, c-format
msgid "Checking remotes...\n"
msgstr "Comprobando remotos...\n"

#: app/flatpak-builtins-repair.c:482
#, c-format
msgid "Remote %s for ref %s is missing\n"
msgstr "Falta el remoto %s de la ref %s\n"

#: app/flatpak-builtins-repair.c:484
#, c-format
msgid "Remote %s for ref %s is disabled\n"
msgstr "El remoto %s para la ref %s está desactivado\n"

#: app/flatpak-builtins-repair.c:490
#, c-format
msgid "Pruning objects\n"
msgstr "Podando objetos\n"

#: app/flatpak-builtins-repair.c:498
#, c-format
msgid "Erasing .removed\n"
msgstr "Eliminando .removed\n"

#: app/flatpak-builtins-repair.c:524
#, c-format
msgid "Reinstalling refs\n"
msgstr "Reinstalando referencias\n"

#: app/flatpak-builtins-repair.c:526
#, c-format
msgid "Reinstalling removed refs\n"
msgstr "Reinstalando referencias eliminadas\n"

#: app/flatpak-builtins-repair.c:551
#, c-format
msgid "While removing appstream for %s: "
msgstr "Al eliminar appstream para %s: "

#: app/flatpak-builtins-repair.c:558
#, c-format
msgid "While deploying appstream for %s: "
msgstr "Al desplegar appstream para %s: "

#: app/flatpak-builtins-repo.c:106
#, c-format
msgid "Repo mode: %s\n"
msgstr "Modo repo: %s\n"

#: app/flatpak-builtins-repo.c:113
#, c-format
msgid "Indexed summaries: %s\n"
msgstr "Resúmenes indexados : %s\n"

#: app/flatpak-builtins-repo.c:113 app/flatpak-builtins-repo.c:139
#: app/flatpak-builtins-repo.c:172
msgid "true"
msgstr "cierto"

#: app/flatpak-builtins-repo.c:113 app/flatpak-builtins-repo.c:139
#: app/flatpak-builtins-repo.c:172
msgid "false"
msgstr "falso"

#: app/flatpak-builtins-repo.c:121
#, c-format
msgid "Subsummaries: "
msgstr "Subresúmenes: "

#: app/flatpak-builtins-repo.c:136
#, c-format
msgid "Cache version: %d\n"
msgstr "Versión de caché: %d\n"

#: app/flatpak-builtins-repo.c:139
#, c-format
msgid "Indexed deltas: %s\n"
msgstr "Deltas indexadas: %s\n"

#: app/flatpak-builtins-repo.c:142
#, c-format
msgid "Title: %s\n"
msgstr "Título: %s\n"

#: app/flatpak-builtins-repo.c:145
#, c-format
msgid "Comment: %s\n"
msgstr "Comentario: %s\n"

#: app/flatpak-builtins-repo.c:148
#, c-format
msgid "Description: %s\n"
msgstr "Descripción: %s\n"

#: app/flatpak-builtins-repo.c:151
#, c-format
msgid "Homepage: %s\n"
msgstr "Página principal: %s\n"

#: app/flatpak-builtins-repo.c:154
#, c-format
msgid "Icon: %s\n"
msgstr "Icono: %s\n"

#: app/flatpak-builtins-repo.c:157
#, c-format
msgid "Collection ID: %s\n"
msgstr "ID de colección: %s\n"

#: app/flatpak-builtins-repo.c:160
#, c-format
msgid "Default branch: %s\n"
msgstr "Rama predeterminada: %s\n"

#: app/flatpak-builtins-repo.c:163
#, c-format
msgid "Redirect URL: %s\n"
msgstr "Redireccionar URL: %s\n"

#: app/flatpak-builtins-repo.c:166
#, c-format
msgid "Deploy collection ID: %s\n"
msgstr "Implementar ID de colección: %s\n"

#: app/flatpak-builtins-repo.c:169
#, c-format
msgid "Authenticator name: %s\n"
msgstr "Nombre del autenticador: %s\n"

#: app/flatpak-builtins-repo.c:172
#, c-format
msgid "Authenticator install: %s\n"
msgstr "Instalación del autenticador: %s\n"

#: app/flatpak-builtins-repo.c:180
#, c-format
msgid "GPG key hash: %s\n"
msgstr "Hash de clave GPG: %s\n"

#: app/flatpak-builtins-repo.c:184
#, c-format
msgid "%zd summary branches\n"
msgstr "Ramas de resumen %zd\n"

#: app/flatpak-builtins-repo.c:336
msgid "Installed"
msgstr "Instalada"

#. Translators: Download is used here as a noun
#: app/flatpak-builtins-repo.c:338 app/flatpak-cli-transaction.c:1462
msgid "Download"
msgstr "Descarga"

#: app/flatpak-builtins-repo.c:339
msgid "Subsets"
msgstr "Subconjuntos"

#: app/flatpak-builtins-repo.c:393
msgid "Digest"
msgstr "Resumen"

#: app/flatpak-builtins-repo.c:394
msgid "History length"
msgstr "Longitud de histórico"

#: app/flatpak-builtins-repo.c:711
msgid "Print general information about the repository"
msgstr "Imprime información general acerca del repositorio"

#: app/flatpak-builtins-repo.c:712
msgid "List the branches in the repository"
msgstr "Mostrar una lista de las ramas en el repositorio"

#: app/flatpak-builtins-repo.c:713
msgid "Print metadata for a branch"
msgstr "Imprime los metadatos de una rama"

#: app/flatpak-builtins-repo.c:714
msgid "Show commits for a branch"
msgstr "Mostrar los commits de una rama"

#: app/flatpak-builtins-repo.c:715
msgid "Print information about the repo subsets"
msgstr "Imprime información acerca de los subconjuntos del repo"

#: app/flatpak-builtins-repo.c:716
msgid "Limit information to subsets with this prefix"
msgstr "Limitar información a los subconjuntos con este prefijo"

#: app/flatpak-builtins-repo.c:732
msgid "LOCATION - Repository maintenance"
msgstr "UBICACIÓN - Mantenimiento del repositorio"

#: app/flatpak-builtins-run.c:159
msgid "Command to run"
msgstr "Comando a ejecutar"

#: app/flatpak-builtins-run.c:160
msgid "Directory to run the command in"
msgstr "Carpeta en la que ejecutar el comando"

#: app/flatpak-builtins-run.c:161
msgid "Branch to use"
msgstr "Rama a usar"

#: app/flatpak-builtins-run.c:162
msgid "Use development runtime"
msgstr "Usar tiempo de ejecución de desarrollo"

#: app/flatpak-builtins-run.c:163
msgid "Runtime to use"
msgstr "Tiempo de ejecución a usar"

#: app/flatpak-builtins-run.c:164
msgid "Runtime version to use"
msgstr "Versión en tiempo de ejecución a usar"

#: app/flatpak-builtins-run.c:167
msgid "Log accessibility bus calls"
msgstr "Llamadas al bus de registro de accesibilidad"

#: app/flatpak-builtins-run.c:168
msgid "Don't proxy accessibility bus calls"
msgstr "No usar proxy en las llamadas al bus de accesibilidad"

#: app/flatpak-builtins-run.c:169
msgid "Proxy accessibility bus calls (default except when sandboxed)"
msgstr ""
"Llamadas del bus de accesibilidad del proxy (predeterminado, excepto cuando "
"está en un espacio aislado)"

#: app/flatpak-builtins-run.c:170
msgid "Don't proxy session bus calls"
msgstr "No usar proxy en las llamadas al bus de sesión"

#: app/flatpak-builtins-run.c:171
msgid "Proxy session bus calls (default except when sandboxed)"
msgstr ""
"Llamadas del bus de sesión del proxy (predeterminado, excepto cuando está en "
"un espacio aislado)"

#: app/flatpak-builtins-run.c:172
msgid "Don't start portals"
msgstr "No iniciar portales"

#: app/flatpak-builtins-run.c:173
msgid "Enable file forwarding"
msgstr "Habilitar el reenvío de archivos"

#: app/flatpak-builtins-run.c:174
msgid "Run specified commit"
msgstr "Ejecutar el commit especificado"

#: app/flatpak-builtins-run.c:175
msgid "Use specified runtime commit"
msgstr "Usar el commit en tiempo de ejecución especificado"

#: app/flatpak-builtins-run.c:176
msgid "Run completely sandboxed"
msgstr "Ejecutar completamente aislado"

#: app/flatpak-builtins-run.c:178
msgid "Use PID as parent pid for sharing namespaces"
msgstr "Usar PID como pid principal para compartir espacios de nombre"

#: app/flatpak-builtins-run.c:179
msgid "Make processes visible in parent namespace"
msgstr "Hacer visibles los procesos en el espacio de nombres principal"

#: app/flatpak-builtins-run.c:180
msgid "Share process ID namespace with parent"
msgstr "Compartir el espacio de nombres del ID de proceso con el principal"

#: app/flatpak-builtins-run.c:181
msgid "Write the instance ID to the given file descriptor"
msgstr "Escribir el ID de la instancia en el descriptor de archivo dado"

#: app/flatpak-builtins-run.c:182
msgid "Use PATH instead of the app's /app"
msgstr "Usar RUTA en lugar de /app de la aplicación"

#: app/flatpak-builtins-run.c:183
#, fuzzy
msgid "Use FD instead of the app's /app"
msgstr "Usar RUTA en lugar de /app de la aplicación"

#: app/flatpak-builtins-run.c:183 app/flatpak-builtins-run.c:185
#: app/flatpak-builtins-run.c:187 app/flatpak-builtins-run.c:188
#: common/flatpak-context.c:2672
msgid "FD"
msgstr "FD"

#: app/flatpak-builtins-run.c:184
msgid "Use PATH instead of the runtime's /usr"
msgstr "Usar RUTA en lugar de /usr del ejecutable"

#: app/flatpak-builtins-run.c:185
#, fuzzy
msgid "Use FD instead of the runtime's /usr"
msgstr "Usar RUTA en lugar de /usr del ejecutable"

#: app/flatpak-builtins-run.c:186
#, fuzzy
msgid "Clear all outside environment variables"
msgstr "Establecer variable de entorno"

#: app/flatpak-builtins-run.c:187
msgid ""
"Bind mount the file or directory referred to by FD to its canonicalized path"
msgstr ""

#: app/flatpak-builtins-run.c:188
msgid ""
"Bind mount the file or directory referred to by FD read-only to its "
"canonicalized path"
msgstr ""

#: app/flatpak-builtins-run.c:219
msgid "APP [ARGUMENT…] - Run an app"
msgstr "APL [ARGUMENTO…] - Ejecuta una aplicación"

#: app/flatpak-builtins-run.c:370
#, c-format
msgid "runtime/%s/%s/%s not installed"
msgstr "runtime/%s/%s/%s no instalado"

#: app/flatpak-builtins-run.c:419
msgid "app-fd and app-path cannot both be used"
msgstr ""

#: app/flatpak-builtins-run.c:449
msgid "usr-fd and usr-path cannot both be used"
msgstr ""

#: app/flatpak-builtins-search.c:37
msgid "Arch to search for"
msgstr "Arquitectura que buscar"

#: app/flatpak-builtins-search.c:49
msgid "Remotes"
msgstr "Remotos"

#: app/flatpak-builtins-search.c:49
msgid "Show the remotes"
msgstr "Mostrar los remotos"

#: app/flatpak-builtins-search.c:244
msgid "TEXT - Search remote apps/runtimes for text"
msgstr "TEXTO - Buscar aplicaciones o ejecutables para el texto"

#: app/flatpak-builtins-search.c:255
msgid "TEXT must be specified"
msgstr "Se debe especificar TEXTO"

#: app/flatpak-builtins-search.c:338
msgid "No matches found"
msgstr "Ninguna coincidencia"

#: app/flatpak-builtins-uninstall.c:54
msgid "Arch to uninstall"
msgstr "Arquitectura a desinstalar"

#: app/flatpak-builtins-uninstall.c:55
msgid "Keep ref in local repository"
msgstr "Mantener referencia en el repositorio local"

#: app/flatpak-builtins-uninstall.c:56
msgid "Don't uninstall related refs"
msgstr "No desinstalar referencias relacionadas"

#: app/flatpak-builtins-uninstall.c:57
msgid "Remove files even if running"
msgstr "Eliminar archivos aún si se encuentra en ejecución"

#: app/flatpak-builtins-uninstall.c:60
msgid "Uninstall all"
msgstr "Desinstalar todo"

#: app/flatpak-builtins-uninstall.c:61
msgid "Uninstall unused"
msgstr "Desinstalar no usadas"

#: app/flatpak-builtins-uninstall.c:62
msgid "Delete app data"
msgstr "Eliminar los datos de la aplicación"

#: app/flatpak-builtins-uninstall.c:141
#, c-format
msgid "Delete data for %s?"
msgstr "¿Eliminar los datos de %s?"

#: app/flatpak-builtins-uninstall.c:220
#, c-format
msgid "Info: applications using the extension %s%s%s branch %s%s%s:\n"
msgstr "Info: aplicaciones que usan la extensión %s%s%s rama %s%s%s:\n"

#: app/flatpak-builtins-uninstall.c:223
#, c-format
msgid "Info: applications using the runtime %s%s%s branch %s%s%s:\n"
msgstr ""
"Info: aplicaciones que usan el tiempo de ejecución %s%s%s rama %s%s%s:\n"

#: app/flatpak-builtins-uninstall.c:238
msgid "Really remove?"
msgstr "¿Realmente quiere eliminar?"

#: app/flatpak-builtins-uninstall.c:255
msgid "[REF…] - Uninstall applications or runtimes"
msgstr "[REF…] - Desinstalar aplicaciones o tiempos de ejecución"

#: app/flatpak-builtins-uninstall.c:264
msgid "Must specify at least one REF, --unused, --all or --delete-data"
msgstr "Se debe especificar al menos una REF, --unused, --all o --delete-data"

#: app/flatpak-builtins-uninstall.c:267
msgid "Must not specify REFs when using --all"
msgstr "No se deben especificar REFs al usar --all"

#: app/flatpak-builtins-uninstall.c:270
msgid "Must not specify REFs when using --unused"
msgstr "No se deben especificar REFs al usar --unused"

#: app/flatpak-builtins-uninstall.c:336
#, c-format
msgid ""
"\n"
"These runtimes in installation '%s' are pinned and won't be removed; see "
"flatpak-pin(1):\n"
msgstr ""
"\n"
"Estos ejecutables en la instalación «%s» están fijados y no se eliminarán. "
"Consulte flatpak-pin(1):\n"

#: app/flatpak-builtins-uninstall.c:370
#, c-format
msgid "Nothing unused to uninstall\n"
msgstr "Nada sin usar que desinstalar\n"

#: app/flatpak-builtins-uninstall.c:444
#, c-format
msgid "No installed refs found for ‘%s’"
msgstr "No se encontraron refs instaladas para «%s»"

#: app/flatpak-builtins-uninstall.c:447
#, c-format
msgid " with arch ‘%s’"
msgstr " con arquitectura «%s»"

#: app/flatpak-builtins-uninstall.c:449
#, c-format
msgid " with branch ‘%s’"
msgstr " con rama «%s»"

#: app/flatpak-builtins-uninstall.c:456
#, c-format
msgid "Warning: %s is not installed\n"
msgstr "Advertencia: %s no está instalada\n"

#: app/flatpak-builtins-uninstall.c:490
#, c-format
msgid "None of the specified refs are installed"
msgstr "Ninguna de las referencias especificadas está instalada"

#: app/flatpak-builtins-uninstall.c:599
#, c-format
msgid "No app data to delete\n"
msgstr ""

#: app/flatpak-builtins-update.c:56
msgid "Arch to update for"
msgstr "Arquitectura a actualizar"

#: app/flatpak-builtins-update.c:57
msgid "Commit to deploy"
msgstr "Commit a desplegar"

#: app/flatpak-builtins-update.c:58
msgid "Remove old files even if running"
msgstr "Eliminar archivos antiguos aún si se encuentra en ejecución"

#: app/flatpak-builtins-update.c:59
msgid "Don't pull, only update from local cache"
msgstr "No hacer pull, solo actualizar del caché local"

#: app/flatpak-builtins-update.c:61
msgid "Don't update related refs"
msgstr "No actualizar referencias relacionadas"

#: app/flatpak-builtins-update.c:66
msgid "Update appstream for remote"
msgstr "Actualizar appstream para un repositorio remoto"

#: app/flatpak-builtins-update.c:67
msgid "Only update this subpath"
msgstr "Solo actualizar este subcarpeta"

#: app/flatpak-builtins-update.c:90
msgid "[REF…] - Update applications or runtimes"
msgstr "[REF…] - Actualiza aplicaciones o tiempos de ejecución"

#: app/flatpak-builtins-update.c:121
msgid "With --commit, only one REF may be specified"
msgstr "Con --commit, solo se puede especificar un REF"

#: app/flatpak-builtins-update.c:162
#, c-format
msgid "Looking for updates…\n"
msgstr "Buscando actualizaciones…\n"

#: app/flatpak-builtins-update.c:215
#, c-format
msgid "Unable to update %s: %s\n"
msgstr "No se puede actualizar %s: %s\n"

#: app/flatpak-builtins-update.c:274
#, fuzzy, c-format
msgid "Nothing to update.\n"
msgstr "Nada que hacer.\n"

#: app/flatpak-builtins-utils.c:337
#, fuzzy, c-format
msgid ""
"Remote ‘%s’ found in multiple installations, unable to proceed in non-"
"interactive mode"
msgstr ""
"Se encontró la referencia «%s» en varias instalaciones: %s. Debe especificar "
"una."

#: app/flatpak-builtins-utils.c:346
#, c-format
msgid "Remote ‘%s’ found in multiple installations:"
msgstr "Se encontró el remoto «%s» en varias instalaciones:"

#: app/flatpak-builtins-utils.c:347 app/flatpak-builtins-utils.c:442
#: app/flatpak-builtins-utils.c:538 app/flatpak-builtins-utils.c:540
#: app/flatpak-builtins-utils.c:598
msgid "Which do you want to use (0 to abort)?"
msgstr "¿Cuál quiere usar (0 para abortar)?"

#: app/flatpak-builtins-utils.c:349
#, c-format
msgid "No remote chosen to resolve ‘%s’ which exists in multiple installations"
msgstr ""
"No se eligió un remoto para resolver «%s» que existe en varias instalaciones"

#: app/flatpak-builtins-utils.c:358
#, c-format
msgid ""
"Remote \"%s\" not found\n"
"Hint: Use flatpak remote-add to add a remote"
msgstr ""
"No se encontró el remoto «%s»\n"
"Pista: Use flatpak remote-add para añadir un remoto"

#: app/flatpak-builtins-utils.c:364
#, c-format
msgid "Remote \"%s\" not found in the %s installation"
msgstr "El remoto «%s» no se encontró en la instalación %s"

#: app/flatpak-builtins-utils.c:404
#, c-format
msgid "Multiple refs match ‘%s’, unable to proceed in non-interactive mode"
msgstr ""

#. default to yes on Enter
#: app/flatpak-builtins-utils.c:430
#, c-format
msgid ""
"Found ref ‘%s’ in remote ‘%s’ (%s).\n"
"Use this ref?"
msgstr ""
"Se encontró la ref. «%s» en el remoto «%s» (%s).\n"
"¿Usar esta ref.?"

#: app/flatpak-builtins-utils.c:434 app/flatpak-builtins-utils.c:444
#: app/flatpak-builtins-utils.c:522 app/flatpak-builtins-utils.c:543
#, c-format
msgid "No ref chosen to resolve matches for ‘%s’"
msgstr "No se eligió una ref. para resolver las coincidencias de «%s»"

#: app/flatpak-builtins-utils.c:440
#, c-format
msgid "Similar refs found for ‘%s’ in remote ‘%s’ (%s):"
msgstr "Se encontraron refs. similares de «%s» en el remoto «%s» (%s):"

#: app/flatpak-builtins-utils.c:488
#, c-format
msgid ""
"Multiple installed refs match ‘%s’, unable to proceed in non-interactive mode"
msgstr ""

#. default to yes on Enter
#: app/flatpak-builtins-utils.c:518
#, c-format
msgid "Found installed ref ‘%s’ (%s). Is this correct?"
msgstr "Se encontró la ref «%s» instalada (%s). ¿Es correcto?"

#: app/flatpak-builtins-utils.c:534
#, c-format
msgid "All of the above"
msgstr "Todo lo anterior"

#: app/flatpak-builtins-utils.c:535
#, c-format
msgid "Similar installed refs found for ‘%s’:"
msgstr "Se encontraron refs similares instaladas para «%s»:"

#: app/flatpak-builtins-utils.c:579
#, c-format
msgid ""
"Multiple remotes have refs matching ‘%s’, unable to proceed in non-"
"interactive mode"
msgstr ""

#: app/flatpak-builtins-utils.c:597
#, c-format
msgid "Remotes found with refs similar to ‘%s’:"
msgstr "Se encontraron remotos con refs similares a «%s»:"

#: app/flatpak-builtins-utils.c:600
#, c-format
msgid "No remote chosen to resolve matches for ‘%s’"
msgstr "No se eligió un remoto para resolver las coincidencias de «%s»"

#: app/flatpak-builtins-utils.c:696 app/flatpak-builtins-utils.c:699
#, c-format
msgid "Updating appstream data for user remote %s"
msgstr "Actualizando datos de appstream para el remoto de usuario %s"

#: app/flatpak-builtins-utils.c:706 app/flatpak-builtins-utils.c:709
#, c-format
msgid "Updating appstream data for remote %s"
msgstr "Actualizando appstream para el repositorio remoto %s"

#: app/flatpak-builtins-utils.c:717 app/flatpak-builtins-utils.c:719
msgid "Error updating"
msgstr "Error al actualizar"

#: app/flatpak-builtins-utils.c:755
#, c-format
msgid "Remote \"%s\" not found"
msgstr "El remoto «%s» no se encontró"

#: app/flatpak-builtins-utils.c:796
#, c-format
msgid "Ambiguous suffix: '%s'."
msgstr "Sufijo ambiguo: «%s»."

#. Translators: don't translate the values
#: app/flatpak-builtins-utils.c:798 app/flatpak-builtins-utils.c:813
msgid "Possible values are :s[tart], :m[iddle], :e[nd] or :f[ull]"
msgstr "Los valores posibles son :s[tart], :m[iddle], :e[nd] o :f[ull]"

#: app/flatpak-builtins-utils.c:811
#, c-format
msgid "Invalid suffix: '%s'."
msgstr "Sufijo no válido: «%s»."

#: app/flatpak-builtins-utils.c:846
#, c-format
msgid "Ambiguous column: %s"
msgstr "Columna ambigua: %s"

#: app/flatpak-builtins-utils.c:859
#, c-format
msgid "Unknown column: %s"
msgstr "Columna desconocida: %s"

#: app/flatpak-builtins-utils.c:917
msgid "Available columns:\n"
msgstr "Columnas disponibles:\n"

#: app/flatpak-builtins-utils.c:927
msgid "Show all columns"
msgstr "Mostrar todas las columnas"

#: app/flatpak-builtins-utils.c:928
msgid "Show available columns"
msgstr "Mostrar columnas disponibles"

#: app/flatpak-builtins-utils.c:931
msgid "Append :s[tart], :m[iddle], :e[nd] or :f[ull] to change ellipsization"
msgstr ""
"Adjuntar :s[tart], :m[iddle], :e[nd] o :f[ull] para cambiar la elipsización"

#: app/flatpak-builtins-utils.c:1483
#, c-format
msgid "Unknown scheme in sideload location %s"
msgstr ""

#: app/flatpak-cli-transaction.c:96 app/flatpak-cli-transaction.c:102
#, c-format
msgid "Required runtime for %s (%s) found in remote %s\n"
msgstr "Tiempo de ejecución requerido para %s (%s) encontrado en remoto %s\n"

#: app/flatpak-cli-transaction.c:104
msgid "Do you want to install it?"
msgstr "¿Quiere instalarlo?"

#: app/flatpak-cli-transaction.c:110
#, c-format
msgid "Required runtime for %s (%s) found in remotes:"
msgstr "Tiempo de ejecución requerido para %s (%s) encontrado en remotos:"

#: app/flatpak-cli-transaction.c:112
msgid "Which do you want to install (0 to abort)?"
msgstr "¿Cual quieres instalar (0 para abortar)?"

#: app/flatpak-cli-transaction.c:132
#, c-format
msgid "Configuring %s as new remote '%s'\n"
msgstr "Configurando %s como un nuevo remoto «%s»\n"

#. default to yes on Enter
#: app/flatpak-cli-transaction.c:139
#, c-format
msgid ""
"The remote '%s', referred to by '%s' at location %s contains additional "
"applications.\n"
"Should the remote be kept for future installations?"
msgstr ""
"El remoto «%s», referido como «%s» en la ubicación %s contiene aplicaciones "
"adicionales.\n"
"¿Se debe guardar el remoto para futuras instalaciones?"

#. default to yes on Enter
#: app/flatpak-cli-transaction.c:147
#, c-format
msgid ""
"The application %s depends on runtimes from:\n"
"  %s\n"
"Configure this as new remote '%s'"
msgstr ""
"La aplicación %s depende de los tiempos de ejecución de:\n"
"  %s\n"
"Configure esto como un nuevo remoto «%s»"

#. Formatted size/remaining time in seconds
#: app/flatpak-cli-transaction.c:321
#, c-format
msgid "%s/s%s%s"
msgstr ""

#. Download progress percentage, use the appropriate
#. percent format for your language
#: app/flatpak-cli-transaction.c:359
#, c-format
msgid "%3d%%"
msgstr ""

#: app/flatpak-cli-transaction.c:414
msgid "Installing…"
msgstr "Instalando…"

#: app/flatpak-cli-transaction.c:416
#, c-format
msgid "Installing %d/%d…"
msgstr "Instalando %d/%d…"

#: app/flatpak-cli-transaction.c:421
msgid "Updating…"
msgstr "Actualizando…"

#: app/flatpak-cli-transaction.c:423
#, c-format
msgid "Updating %d/%d…"
msgstr "Actualizando %d/%d…"

#: app/flatpak-cli-transaction.c:428
msgid "Uninstalling…"
msgstr "Desinstalando…"

#: app/flatpak-cli-transaction.c:430
#, c-format
msgid "Uninstalling %d/%d…"
msgstr "Desinstalando %d/%d…"

#: app/flatpak-cli-transaction.c:496 app/flatpak-quiet-transaction.c:161
#, c-format
msgid "Info: %s was skipped"
msgstr "Info: se saltó %s"

#: app/flatpak-cli-transaction.c:519
#, c-format
msgid "Warning: %s%s%s already installed"
msgstr "Aviso: %s%s%s ya está instalado"

#: app/flatpak-cli-transaction.c:522
#, c-format
msgid "Error: %s%s%s already installed"
msgstr "Error: %s%s%s ya está instalado"

#: app/flatpak-cli-transaction.c:528
#, c-format
msgid "Warning: %s%s%s not installed"
msgstr "Advertencia: %s%s%s no está instalado"

#: app/flatpak-cli-transaction.c:531
#, c-format
msgid "Error: %s%s%s not installed"
msgstr "Error: %s%s%s no instalado"

#: app/flatpak-cli-transaction.c:537
#, c-format
msgid "Warning: %s%s%s needs a later flatpak version"
msgstr "Aviso: %s%s%s necesita una versión de flatpak superior"

#: app/flatpak-cli-transaction.c:540
#, c-format
msgid "Error: %s%s%s needs a later flatpak version"
msgstr "Error: %s%s%s necesita una versión de flatpak superior"

#: app/flatpak-cli-transaction.c:546
msgid "Warning: Not enough disk space to complete this operation"
msgstr ""
"Aviso: No hay espacio de disco suficiente para completar esta operación"

#: app/flatpak-cli-transaction.c:548
msgid "Error: Not enough disk space to complete this operation"
msgstr ""
"Error: No hay espacio de disco suficiente para completar esta operación"

#: app/flatpak-cli-transaction.c:553
#, c-format
msgid "Warning: %s"
msgstr "Advertencia: %s"

#: app/flatpak-cli-transaction.c:555
#, c-format
msgid "Error: %s"
msgstr "Error: %s"

#: app/flatpak-cli-transaction.c:570
#, c-format
msgid "Failed to install %s%s%s: "
msgstr "Fallo al instalar %s%s%s: "

#: app/flatpak-cli-transaction.c:577
#, c-format
msgid "Failed to update %s%s%s: "
msgstr "Fallo al actualizar %s%s%s: "

#: app/flatpak-cli-transaction.c:584
#, c-format
msgid "Failed to install bundle %s%s%s: "
msgstr "Fallo al instalar el paquete %s%s%s: "

#: app/flatpak-cli-transaction.c:591
#, c-format
msgid "Failed to uninstall %s%s%s: "
msgstr "Fallo al desinstalar %s%s%s: "

#: app/flatpak-cli-transaction.c:642
#, c-format
msgid "Authentication required for remote '%s'\n"
msgstr "Se necesita autenticación para el remoto «%s»\n"

#: app/flatpak-cli-transaction.c:643
msgid "Open browser?"
msgstr "¿Abrir el navegador?"

#: app/flatpak-cli-transaction.c:699
#, c-format
msgid "Login required remote %s (realm %s)\n"
msgstr "El inicio de sesión requiere el remoto %s (ámbito %s)\n"

#: app/flatpak-cli-transaction.c:704
msgid "Password"
msgstr "Contraseña"

#. Only runtimes can be pinned
#: app/flatpak-cli-transaction.c:759
#, c-format
msgid ""
"\n"
"Info: (pinned) runtime %s%s%s branch %s%s%s is end-of-life, in favor of "
"%s%s%s branch %s%s%s\n"
msgstr ""
"\n"
"Info: el tiempo de ejecución (fijado) %s%s%s rama %s%s%s terminó su vida "
"útil, en favor de %s%s%s rama %s%s%s\n"

#: app/flatpak-cli-transaction.c:765
#, c-format
msgid ""
"\n"
"Info: runtime %s%s%s branch %s%s%s is end-of-life, in favor of %s%s%s branch "
"%s%s%s\n"
msgstr ""
"\n"
"Info: el tiempo de ejecución %s%s%s rama %s%s%s terminó su vida útil, en "
"favor de %s%s%s rama %s%s%s\n"

#: app/flatpak-cli-transaction.c:768
#, c-format
msgid ""
"\n"
"Info: app %s%s%s branch %s%s%s is end-of-life, in favor of %s%s%s branch "
"%s%s%s\n"
msgstr ""
"\n"
"Info: la aplicación %s%s%s rama %s%s%s terminó su vida útil, en favor de "
"%s%s%s rama %s%s%s\n"

#. Only runtimes can be pinned
#: app/flatpak-cli-transaction.c:780
#, c-format
msgid ""
"\n"
"Info: (pinned) runtime %s%s%s branch %s%s%s is end-of-life, with reason:\n"
msgstr ""
"\n"
"Info: el tiempo de ejecución (fijado) %s%s%s rama %s%s%s terminó su vida "
"útil, con motivo:\n"

#: app/flatpak-cli-transaction.c:786
#, c-format
msgid ""
"\n"
"Info: runtime %s%s%s branch %s%s%s is end-of-life, with reason:\n"
msgstr ""
"\n"
"Info: el tiempo de ejecución %s%s%s rama %s%s%s terminó su vida útil, con "
"motivo:\n"

#: app/flatpak-cli-transaction.c:789
#, c-format
msgid ""
"\n"
"Info: app %s%s%s branch %s%s%s is end-of-life, with reason:\n"
msgstr ""
"\n"
"Info: la aplicación %s%s%s rama %s%s%s terminó su vida útil, con motivo:\n"

#: app/flatpak-cli-transaction.c:963
#, c-format
msgid "Info: applications using this extension:\n"
msgstr "Info: aplicaciones que usan esta extensión:\n"

#: app/flatpak-cli-transaction.c:965
#, c-format
msgid "Info: applications using this runtime:\n"
msgstr "Info: aplicaciones que usan este tiempo de ejecución:\n"

#: app/flatpak-cli-transaction.c:984
msgid "Replace?"
msgstr "¿Reemplazar?"

#: app/flatpak-cli-transaction.c:987 app/flatpak-quiet-transaction.c:247
#, c-format
msgid "Updating to rebased version\n"
msgstr "Actualizando a la versión rebasada\n"

#: app/flatpak-cli-transaction.c:1011
#, c-format
msgid "Failed to rebase %s to %s: "
msgstr "Fallo al rebasar %s a %s: "

#: app/flatpak-cli-transaction.c:1277
#, c-format
msgid "New %s%s%s permissions:"
msgstr "Permisos nuevos de %s%s%s:"

#: app/flatpak-cli-transaction.c:1279
#, c-format
msgid "%s%s%s permissions:"
msgstr "Permisos de %s%s%s:"

#: app/flatpak-cli-transaction.c:1343
msgid "Warning: "
msgstr "Advertencia: "

#. translators: This is short for operation, the title of a one-char column
#: app/flatpak-cli-transaction.c:1442
msgid "Op"
msgstr "Op"

#. Avoid resizing the download column too much,
#. * by making the title as long as typical content
#.
#: app/flatpak-cli-transaction.c:1458 app/flatpak-cli-transaction.c:1503
msgid "partial"
msgstr "parcial"

#: app/flatpak-cli-transaction.c:1535
msgid "Proceed with these changes to the user installation?"
msgstr "¿Proceder con estos cambios en la instalación del usuario?"

#: app/flatpak-cli-transaction.c:1537
msgid "Proceed with these changes to the system installation?"
msgstr "¿Proceder con estos cambios en la instalación del sistema?"

#: app/flatpak-cli-transaction.c:1539
#, c-format
msgid "Proceed with these changes to the %s?"
msgstr "¿Proceder con estos cambios en la instalación de %s?"

#: app/flatpak-cli-transaction.c:1711
msgid "Changes complete."
msgstr "Cambios completados."

#: app/flatpak-cli-transaction.c:1713
msgid "Uninstall complete."
msgstr "Desinstalación completada."

#: app/flatpak-cli-transaction.c:1715
msgid "Installation complete."
msgstr "Instalación completada."

#: app/flatpak-cli-transaction.c:1717
msgid "Updates complete."
msgstr "Actualizaciones completadas."

#. For updates/!stop_on_first_error we already printed all errors so we make up
#. a different one.
#: app/flatpak-cli-transaction.c:1750
msgid "There were one or more errors"
msgstr "Hubo uno o más errores"

#. translators: please keep the leading space
#: app/flatpak-main.c:76
msgid " Manage installed applications and runtimes"
msgstr " Administra las aplicaciones instaladas y ejecutables"

#: app/flatpak-main.c:77
msgid "Install an application or runtime"
msgstr "Instalar una aplicación o tiempo de ejecución"

#: app/flatpak-main.c:78
msgid "Update an installed application or runtime"
msgstr "Actualizar una aplicación o tiempo de ejecución"

#: app/flatpak-main.c:81
msgid "Uninstall an installed application or runtime"
msgstr "Desinstalar una aplicación o tiempo de ejecución instalado"

#: app/flatpak-main.c:84
msgid "Mask out updates and automatic installation"
msgstr "Ocultar las actualizaciones y la instalación automática"

#: app/flatpak-main.c:85
msgid "Pin a runtime to prevent automatic removal"
msgstr "Fijar un ejecutable para evitar la eliminación automática"

#: app/flatpak-main.c:86
msgid "List installed apps and/or runtimes"
msgstr "Mostrar lista de aplicaciones y/o tiempos de ejecución instalados"

#: app/flatpak-main.c:87
msgid "Show info for installed app or runtime"
msgstr ""
"Mostrar información de las aplicaciones o tiempos de ejecución instalados"

#: app/flatpak-main.c:88
msgid "Show history"
msgstr "Mostrar histórico"

#: app/flatpak-main.c:89
msgid "Configure flatpak"
msgstr "Configurar flatpak"

#: app/flatpak-main.c:90
msgid "Repair flatpak installation"
msgstr "Reparar la instalación de flatpak"

#: app/flatpak-main.c:91
msgid "Put applications or runtimes onto removable media"
msgstr "Colocar aplicaciones o ejecutables en medios extraíbles"

#: app/flatpak-main.c:92
msgid "Install flatpaks that are part of the operating system"
msgstr ""

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:95
msgid ""
"\n"
" Find applications and runtimes"
msgstr ""
"\n"
"Encontrar aplicaciones y ejecutables"

#: app/flatpak-main.c:96
msgid "Search for remote apps/runtimes"
msgstr "Buscar aplicaciones o ejecutables remotos"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:99
msgid ""
"\n"
" Manage running applications"
msgstr ""
"\n"
"Administrar las aplicaciones en ejecución"

#: app/flatpak-main.c:100
msgid "Run an application"
msgstr "Ejecutar una aplicación"

#: app/flatpak-main.c:101
msgid "Override permissions for an application"
msgstr "Sobrescribir permisos para una aplicación"

#: app/flatpak-main.c:102
msgid "Specify default version to run"
msgstr "Especificar la versión por defecto a ejecutar"

#: app/flatpak-main.c:103
msgid "Enter the namespace of a running application"
msgstr "Introduce el espacio de nombres de una aplicación en ejecución"

#: app/flatpak-main.c:104
msgid "Enumerate running applications"
msgstr "Enumerar las aplicaciones en ejecución"

#: app/flatpak-main.c:105
msgid "Stop a running application"
msgstr "Detener una aplicación en ejecución"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:108
msgid ""
"\n"
" Manage file access"
msgstr ""
"\n"
" Administrar el acceso a archivos"

#: app/flatpak-main.c:109
msgid "List exported files"
msgstr "Mostrar una lista de los archivos exportados"

#: app/flatpak-main.c:110
msgid "Grant an application access to a specific file"
msgstr "Conceder a una aplicación acceso a un archivo específico"

#: app/flatpak-main.c:111
msgid "Revoke access to a specific file"
msgstr "Revocar acceso a un archivo específico"

#: app/flatpak-main.c:112
msgid "Show information about a specific file"
msgstr "Mostrar información sobre un archivo específico"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:116
msgid ""
"\n"
" Manage dynamic permissions"
msgstr ""
"\n"
"Administrar permisos dinámicos"

#: app/flatpak-main.c:117
msgid "List permissions"
msgstr "Listar permisos"

#: app/flatpak-main.c:118
msgid "Remove item from permission store"
msgstr "Quitar elemento del almacén de permisos"

#: app/flatpak-main.c:120
msgid "Set permissions"
msgstr "Establecer permisos"

#: app/flatpak-main.c:121
msgid "Show app permissions"
msgstr "Mostrar permisos de la aplicación"

#: app/flatpak-main.c:122
msgid "Reset app permissions"
msgstr "Restablecer los permisos de la aplicación"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:125
msgid ""
"\n"
" Manage remote repositories"
msgstr ""
"\n"
" Administrar repositorios remotos"

#: app/flatpak-main.c:126
msgid "List all configured remotes"
msgstr "Obtener lista de todos los repositorios remotos configurados"

#: app/flatpak-main.c:127
msgid "Add a new remote repository (by URL)"
msgstr "Añadir un nuevo repositorio (por URL)"

#: app/flatpak-main.c:128
msgid "Modify properties of a configured remote"
msgstr "Modificar las propiedades de un repositorio remoto configurado"

#: app/flatpak-main.c:129
msgid "Delete a configured remote"
msgstr "Eliminar un repositorio remoto configurado"

#: app/flatpak-main.c:131
msgid "List contents of a configured remote"
msgstr ""
"Obtener una lista de los contenidos de un repositorio remoto configurado"

#: app/flatpak-main.c:132
msgid "Show information about a remote app or runtime"
msgstr "Mostrar información sobre una aplicación o ejecutable remoto"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:135
msgid ""
"\n"
" Build applications"
msgstr ""
"\n"
"Compilar aplicaciones"

#: app/flatpak-main.c:136
msgid "Initialize a directory for building"
msgstr "Inicializar un carpeta para compilar"

#: app/flatpak-main.c:137
msgid "Run a build command inside the build dir"
msgstr "Ejecutar un comando de compilación dentro del carpeta de compilación"

#: app/flatpak-main.c:138
msgid "Finish a build dir for export"
msgstr "Finalizar un carpeta de compilación para exportar"

#: app/flatpak-main.c:139
msgid "Export a build dir to a repository"
msgstr "Exportar un carpeta de compilación a un repositorio"

#: app/flatpak-main.c:140
msgid "Create a bundle file from a ref in a local repository"
msgstr ""
"Crear un archivo de paquete desde una referencia en un repositorio local"

#: app/flatpak-main.c:141
msgid "Import a bundle file"
msgstr "Importar un archivo de paquete"

#: app/flatpak-main.c:142
msgid "Sign an application or runtime"
msgstr "Firmar una aplicación o «runtime»"

#: app/flatpak-main.c:143
msgid "Update the summary file in a repository"
msgstr "Actualizar el archivo de resumen en un repositorio"

#: app/flatpak-main.c:144
msgid "Create new commit based on existing ref"
msgstr "Crear un nuevo«commit» basado un en una referencia existente"

#: app/flatpak-main.c:145
msgid "Show information about a repo"
msgstr "Mostrar información sobre un repositorio"

#: app/flatpak-main.c:162
msgid "Show debug information, -vv for more detail"
msgstr "Mostrar información de depuración, -vv para más detalles"

#: app/flatpak-main.c:163
msgid "Show OSTree debug information"
msgstr "Mostrar información de depuración de OSTree"

#: app/flatpak-main.c:169
msgid "Print version information and exit"
msgstr "Imprimir la información de la versión y salir"

#: app/flatpak-main.c:170
msgid "Print default arch and exit"
msgstr "Imprimir la arquitectura por defecto y salir"

#: app/flatpak-main.c:171
msgid "Print supported arches and exit"
msgstr "Imprimir las arquitecturas soportadas y salir"

#: app/flatpak-main.c:172
msgid "Print active gl drivers and exit"
msgstr "Imprimir los drivers gl activos y salir"

#: app/flatpak-main.c:173
msgid "Print paths for system installations and exit"
msgstr "Imprimir las rutas de las instalaciones del sistema y salir"

#: app/flatpak-main.c:174
msgid "Print the updated environment needed to run flatpaks"
msgstr "Mostrar el entorno actualizado necesario para ejecutar flatpaks"

#: app/flatpak-main.c:175
msgid "Only include the system installation with --print-updated-env"
msgstr "Incluir solo la instalación del sistema con --print-updated-env"

#: app/flatpak-main.c:180
msgid "Work on the user installation"
msgstr "Trabajar en la instalación del usuario"

#: app/flatpak-main.c:181
msgid "Work on the system-wide installation (default)"
msgstr "Trabajar en la instalación para todo el sistema (predeterminado)"

#: app/flatpak-main.c:182
msgid "Work on a non-default system-wide installation"
msgstr ""
"Trabajar en una instalación para todo el sistema que no es la predeterminada"

#: app/flatpak-main.c:212
msgid "Builtin Commands:"
msgstr "Comandos Incorporados:"

#: app/flatpak-main.c:298
#, c-format
msgid ""
"Note that the directories %s are not in the search path set by the "
"XDG_DATA_DIRS environment variable, so applications installed by Flatpak may "
"not appear on your desktop until the session is restarted."
msgstr ""
"Tenga en cuenta que las carpetas %s no se encuentran en la ruta de búsqueda "
"establecida por la variable de entorno XDG_DATA_DIRS, por lo que es posible "
"que las aplicaciones instaladas por Flatpak no aparezcan en su escritorio "
"hasta que se reinicie la sesión."

#: app/flatpak-main.c:312
#, c-format
msgid ""
"Note that the directory %s is not in the search path set by the "
"XDG_DATA_DIRS environment variable, so applications installed by Flatpak may "
"not appear on your desktop until the session is restarted."
msgstr ""
"Tenga en cuenta que la carpeta %s no se encuentra en la ruta de búsqueda "
"establecida por la variable de entorno XDG_DATA_DIRS, por lo que es posible "
"que las aplicaciones instaladas por Flatpak no aparezcan en su escritorio "
"hasta que se reinicie la sesión."

#: app/flatpak-main.c:381
msgid ""
"Refusing to operate under sudo with --user. Omit sudo to operate on the user "
"installation, or use a root shell to operate on the root user's installation."
msgstr ""
"Negándose a operar bajo sudo con --user. Omita sudo para operar en la "
"instalación del usuario, o use un shell raíz para operar en la instalación "
"del usuario raíz."

#: app/flatpak-main.c:453
msgid ""
"Multiple installations specified for a command that works on one installation"
msgstr ""
"Varias instalaciones especificadas para un comando que funcionan en una "
"instalación"

#: app/flatpak-main.c:504 app/flatpak-main.c:697
#, c-format
msgid "See '%s --help'"
msgstr "Consulte «%s --help»"

#: app/flatpak-main.c:706
#, c-format
msgid "'%s' is not a flatpak command. Did you mean '%s%s'?"
msgstr "«%s» no es un comando de flatpak. ¿Quiso decir «%s%s»?"

#: app/flatpak-main.c:709
#, c-format
msgid "'%s' is not a flatpak command"
msgstr "«%s» no es un comando de flatpak"

#: app/flatpak-main.c:824
msgid "No command specified"
msgstr "Comando no especificado"

#: app/flatpak-main.c:980
msgid "error:"
msgstr "error:"

#: app/flatpak-quiet-transaction.c:77
#, c-format
msgid "Installing %s\n"
msgstr "Instalando %s\n"

#: app/flatpak-quiet-transaction.c:81
#, c-format
msgid "Updating %s\n"
msgstr "Actualizando %s\n"

#: app/flatpak-quiet-transaction.c:85
#, c-format
msgid "Uninstalling %s\n"
msgstr "Desinstalando %s\n"

#: app/flatpak-quiet-transaction.c:107
#, c-format
msgid "Warning: Failed to install %s: %s\n"
msgstr "Aviso: Fallo al instalar %s: %s\n"

#: app/flatpak-quiet-transaction.c:110
#, c-format
msgid "Error: Failed to install %s: %s\n"
msgstr "Error: Fallo al instalar %s: %s\n"

#: app/flatpak-quiet-transaction.c:116
#, c-format
msgid "Warning: Failed to update %s: %s\n"
msgstr "Aviso: Fallo al actualizar %s: %s\n"

#: app/flatpak-quiet-transaction.c:119
#, c-format
msgid "Error: Failed to update %s: %s\n"
msgstr "Error: Fallo al actualizar %s: %s\n"

#: app/flatpak-quiet-transaction.c:125
#, c-format
msgid "Warning: Failed to install bundle %s: %s\n"
msgstr "Aviso: Fallo al instalar el paquete %s: %s\n"

#: app/flatpak-quiet-transaction.c:128
#, c-format
msgid "Error: Failed to install bundle %s: %s\n"
msgstr "Error: Fallo al instalar el paquete %s: %s\n"

#: app/flatpak-quiet-transaction.c:134
#, c-format
msgid "Warning: Failed to uninstall %s: %s\n"
msgstr "Aviso: Fallo al desinstalar %s: %s\n"

#: app/flatpak-quiet-transaction.c:137
#, c-format
msgid "Error: Failed to uninstall %s: %s\n"
msgstr "Error: Fallo al desinstalar %s: %s\n"

#: app/flatpak-quiet-transaction.c:166 common/flatpak-dir.c:11475
#, c-format
msgid "%s already installed"
msgstr "%s ya está instalado"

#: app/flatpak-quiet-transaction.c:168 common/flatpak-dir.c:3622
#: common/flatpak-dir.c:4321 common/flatpak-dir.c:16968
#: common/flatpak-dir.c:17258 common/flatpak-dir-utils.c:166
#: common/flatpak-dir-utils.c:259 common/flatpak-transaction.c:2736
#: common/flatpak-transaction.c:2791
#, c-format
msgid "%s not installed"
msgstr "%s no está instalado"

#: app/flatpak-quiet-transaction.c:170
#, c-format
msgid "%s needs a later flatpak version"
msgstr "%s necesita una versión de flatpak superior"

#: app/flatpak-quiet-transaction.c:172
msgid "Not enough disk space to complete this operation"
msgstr "No hay espacio de disco suficiente para completar esta operación"

#: app/flatpak-quiet-transaction.c:239
#, c-format
msgid "Info: %s is end-of-life, in favor of %s\n"
msgstr "Info: %s terminó su vida útil, en favor de %s\n"

#: app/flatpak-quiet-transaction.c:241
#, c-format
msgid "Info: %s is end-of-life, with reason: %s\n"
msgstr "Info: %s terminó su vida útil, con motivo: %s\n"

#: app/flatpak-quiet-transaction.c:251
#, c-format
msgid "Failed to rebase %s to %s: %s\n"
msgstr "Fallo al rebasar %s a %s: %s\n"

#: common/flatpak-auth.c:58
#, c-format
msgid "No authenticator configured for remote `%s`"
msgstr "No se configuró un autenticador para el remoto «%s»"

#: common/flatpak-context.c:637 common/flatpak-context.c:649
#, fuzzy, c-format
msgid "Invalid permission syntax: %s"
msgstr "Nombre de extensión %s no válido"

#: common/flatpak-context.c:1207
#, c-format
msgid "Unknown share type %s, valid types are: %s"
msgstr "Tipo de recurso compartido %s no válido, los tipos válidos son: %s"

#: common/flatpak-context.c:1228
#, c-format
msgid "Unknown policy type %s, valid types are: %s"
msgstr "Tipo de póliza  %s no válida, los tipos válidos son: %s"

#: common/flatpak-context.c:1266
#, c-format
msgid "Invalid dbus name %s"
msgstr "El nombre de dbus %s no es válido"

#: common/flatpak-context.c:1279
#, c-format
msgid "Unknown socket type %s, valid types are: %s"
msgstr "Tipo de socket desconocido %s, los tipos válidos son: %s"

#: common/flatpak-context.c:1294
#, c-format
msgid "Unknown device type %s, valid types are: %s"
msgstr "Tipo de dispositivo desconocido %s, los tipos válidos son: %s"

#: common/flatpak-context.c:1308
#, c-format
msgid "Unknown feature type %s, valid types are: %s"
msgstr "Tipo de característica desconocido %s, los tipos válidos son: %s"

#: common/flatpak-context.c:1840
#, c-format
msgid "Filesystem location \"%s\" contains \"..\""
msgstr "La ubicación de archivos del sistema «%s» contiene «..»"

#: common/flatpak-context.c:1882
#, c-format
msgid ""
"--filesystem=/ is not available, use --filesystem=host for a similar result"
msgstr ""
"--filesystem=/ no está disponible, use --filesystem=host para obtener un "
"resultado similar"

#: common/flatpak-context.c:1916
#, fuzzy, c-format
msgid ""
"Unknown filesystem location %s, valid locations are: host, host-os, host-"
"etc, host-root, home, xdg-*[/…], ~/dir, /dir"
msgstr ""
"Ubicación desconocida del sistema de archivos %s, las rutas válidas son: "
"host, host-os, host-etc, home, xdg-*[/…], ~/dir, /dir"

#: common/flatpak-context.c:2015
#, fuzzy, c-format
msgid "Invalid syntax for %s: %s"
msgstr "Nombre %s no válido: %s"

#: common/flatpak-context.c:2142
#, c-format
msgid "fallback-x11 can not be conditional"
msgstr ""

#: common/flatpak-context.c:2318
#, c-format
msgid "Invalid env format %s"
msgstr "Formato de entorno no válido %s"

#: common/flatpak-context.c:2399
#, c-format
msgid "Environment variable name must not contain '=': %s"
msgstr "El nombre de la variable de entorno no debe contener «=»: %s"

#: common/flatpak-context.c:2527 common/flatpak-context.c:2535
#, c-format
msgid "--add-policy arguments must be in the form SUBSYSTEM.KEY=VALUE"
msgstr ""
"Los argumentos de --add-policy deben tener el formato SUBSYSTEM.KEY=VALOR"

#: common/flatpak-context.c:2542
#, c-format
msgid "--add-policy values can't start with \"!\""
msgstr "Los valores de --add-policy no pueden comenzar con «!»"

#: common/flatpak-context.c:2567 common/flatpak-context.c:2575
#, c-format
msgid "--remove-policy arguments must be in the form SUBSYSTEM.KEY=VALUE"
msgstr ""
"Los argumentos de --remove-policy deben tener el formato SUBSYSTEM.KEY=VALOR"

#: common/flatpak-context.c:2582
#, c-format
msgid "--remove-policy values can't start with \"!\""
msgstr "Los valores de --remove-policy no pueden comenzar con «!»"

#: common/flatpak-context.c:2657
msgid "Share with host"
msgstr "Compartir con el huesped"

#: common/flatpak-context.c:2657 common/flatpak-context.c:2658
msgid "SHARE"
msgstr "COMPARTIR"

#: common/flatpak-context.c:2658
msgid "Unshare with host"
msgstr "Dejar de compartir con el huesped"

#: common/flatpak-context.c:2659
msgid "Require conditions to be met for a subsystem to get shared"
msgstr ""

#: common/flatpak-context.c:2659
msgid "SHARE:CONDITION"
msgstr ""

#: common/flatpak-context.c:2660
msgid "Expose socket to app"
msgstr "Exponer socket a la aplicación"

#: common/flatpak-context.c:2660 common/flatpak-context.c:2661
msgid "SOCKET"
msgstr "SOCKET"

#: common/flatpak-context.c:2661
msgid "Don't expose socket to app"
msgstr "No exponer socket a la aplicación"

#: common/flatpak-context.c:2662
msgid "Require conditions to be met for a socket to get exposed"
msgstr ""

#: common/flatpak-context.c:2662
msgid "SOCKET:CONDITION"
msgstr ""

#: common/flatpak-context.c:2663
msgid "Expose device to app"
msgstr "Exponer dispositivo a la aplicación"

#: common/flatpak-context.c:2663 common/flatpak-context.c:2664
msgid "DEVICE"
msgstr "DISPOSITIVO"

#: common/flatpak-context.c:2664
msgid "Don't expose device to app"
msgstr "No exponer dispositivo a la aplicación"

#: common/flatpak-context.c:2665
msgid "Require conditions to be met for a device to get exposed"
msgstr ""

#: common/flatpak-context.c:2665
msgid "DEVICE:CONDITION"
msgstr ""

#: common/flatpak-context.c:2666
msgid "Allow feature"
msgstr "Permitir característica"

#: common/flatpak-context.c:2666 common/flatpak-context.c:2667
msgid "FEATURE"
msgstr "CARACTERÍSTICA"

#: common/flatpak-context.c:2667
msgid "Don't allow feature"
msgstr "No permitir característica"

#: common/flatpak-context.c:2668
msgid "Require conditions to be met for a feature to get allowed"
msgstr ""

#: common/flatpak-context.c:2668
msgid "FEATURE:CONDITION"
msgstr ""

#: common/flatpak-context.c:2669
msgid "Expose filesystem to app (:ro for read-only)"
msgstr ""
"Exponer los archivos del sistema a la aplicación (:ro solo en modo lectura)"

#: common/flatpak-context.c:2669
msgid "FILESYSTEM[:ro]"
msgstr "SISTEMA_ARCHIVOS[:ro]"

#: common/flatpak-context.c:2670
msgid "Don't expose filesystem to app"
msgstr "No exponer los archivos del sistema a la aplicación"

#: common/flatpak-context.c:2670
msgid "FILESYSTEM"
msgstr "SISTEMA_ARCHIVOS"

#: common/flatpak-context.c:2671
msgid "Set environment variable"
msgstr "Establecer variable de entorno"

#: common/flatpak-context.c:2671
msgid "VAR=VALUE"
msgstr "VARIABLE=VALOR"

#: common/flatpak-context.c:2672
msgid "Read environment variables in env -0 format from FD"
msgstr "Leer variables de entorno en formato env -0 desde FD"

#: common/flatpak-context.c:2673
msgid "Remove variable from environment"
msgstr "Eliminar la variable del entorno"

#: common/flatpak-context.c:2673
msgid "VAR"
msgstr "VAR"

#: common/flatpak-context.c:2674
msgid "Allow app to own name on the session bus"
msgstr "Permitir que la aplicación tenga nombre propio en el bus de sesión"

#: common/flatpak-context.c:2674 common/flatpak-context.c:2675
#: common/flatpak-context.c:2676 common/flatpak-context.c:2677
#: common/flatpak-context.c:2678 common/flatpak-context.c:2679
#: common/flatpak-context.c:2680
msgid "DBUS_NAME"
msgstr "NOMBRE_DBUS"

#: common/flatpak-context.c:2675
msgid "Allow app to talk to name on the session bus"
msgstr "Permitir a la aplicación hablar con un nombre en el bus de sesión"

#: common/flatpak-context.c:2676
msgid "Don't allow app to talk to name on the session bus"
msgstr "No permitir que la aplicación hable con el nombre en el bus de sesión"

#: common/flatpak-context.c:2677
msgid "Allow app to own name on the system bus"
msgstr "Permitir que la aplicación tenga nombre propio en el bus de sistema"

#: common/flatpak-context.c:2678
msgid "Allow app to talk to name on the system bus"
msgstr "Permitir a la aplicación hablar con un nombre en el bus de sistema"

#: common/flatpak-context.c:2679
msgid "Don't allow app to talk to name on the system bus"
msgstr ""
"No permitir que la aplicación hable con el nombre en el bus del sistema"

#: common/flatpak-context.c:2680
#, fuzzy
msgid "Allow app to own name on the a11y bus"
msgstr "Permitir que la aplicación tenga nombre propio en el bus de sistema"

#: common/flatpak-context.c:2681
msgid "Add generic policy option"
msgstr "Añadir opción de póliza genérica"

#: common/flatpak-context.c:2681 common/flatpak-context.c:2682
msgid "SUBSYSTEM.KEY=VALUE"
msgstr "SUBSISTEMA.CLAVE=VALOR"

#: common/flatpak-context.c:2682
msgid "Remove generic policy option"
msgstr "Eliminar opción de póliza genérica"

#: common/flatpak-context.c:2683
msgid "Add USB device to enumerables"
msgstr ""

#: common/flatpak-context.c:2683 common/flatpak-context.c:2684
msgid "VENDOR_ID:PRODUCT_ID"
msgstr ""

#: common/flatpak-context.c:2684
msgid "Add USB device to hidden list"
msgstr ""

#: common/flatpak-context.c:2685
msgid "A list of USB devices that are enumerable"
msgstr ""

#: common/flatpak-context.c:2685
msgid "LIST"
msgstr ""

#: common/flatpak-context.c:2686
msgid "File containing a list of USB devices to make enumerable"
msgstr ""

#: common/flatpak-context.c:2686 common/flatpak-context.c:2687
msgid "FILENAME"
msgstr "NOMBRE_ARCHIVO"

#: common/flatpak-context.c:2687
msgid "Persist home directory subpath"
msgstr "Subruta de la carpeta de inicio con persistencia"

#. This is not needed/used anymore, so hidden, but we accept it for backwards compat
#: common/flatpak-context.c:2689
msgid "Don't require a running session (no cgroups creation)"
msgstr "No requerir una sesión en ejecución (no se crearán cgroups)"

#: common/flatpak-context.c:3718
#, c-format
msgid "Not replacing \"%s\" with tmpfs: %s"
msgstr "No se reemplaza «%s» con tmpfs: %s"

#: common/flatpak-context.c:3726
#, c-format
msgid "Not sharing \"%s\" with sandbox: %s"
msgstr "No se comparte «%s» con el sandbox: %s"

#. Even if the error is one that we would normally silence, like
#. * the path not existing, it seems reasonable to make more of a fuss
#. * about the home directory not existing or otherwise being unusable,
#. * so this is intentionally not using cannot_export()
#: common/flatpak-context.c:3828
#, c-format
msgid "Not allowing home directory access: %s"
msgstr "No se permite el acceso a la carpeta de inicio: %s"

#: common/flatpak-context.c:4062
#, c-format
msgid "Unable to provide a temporary home directory in the sandbox: %s"
msgstr ""
"No se puede proporcionar una carpeta de inicio temporal en el espacio "
"aislado: %s"

#: common/flatpak-dir.c:442
#, c-format
msgid "Configured collection ID ‘%s’ not in summary file"
msgstr "El ID de colección configurado «%s» no está en el archivo de resumen"

#: common/flatpak-dir.c:587
#, c-format
msgid "Unable to load summary from remote %s: %s"
msgstr "No se puede cargar el resumen del remoto %s: %s"

#: common/flatpak-dir.c:764 common/flatpak-dir.c:800 common/flatpak-dir.c:906
#, c-format
msgid "No such ref '%s' in remote %s"
msgstr "No se encontró la ref. «%s» en el remoto %s"

#: common/flatpak-dir.c:891 common/flatpak-dir.c:1051 common/flatpak-dir.c:1080
#: common/flatpak-dir.c:1092
#, fuzzy, c-format
msgid "No entry for %s in remote %s summary flatpak cache"
msgstr ""
"No hay entrada para %s en la caché de Flatpak de resumen del remoto «%s» "

#: common/flatpak-dir.c:1069
#, c-format
msgid "No summary or Flatpak cache available for remote %s"
msgstr "No hay resumen o caché de Flatpak disponible para el remoto %s"

#: common/flatpak-dir.c:1097
#, c-format
msgid "Missing xa.data in summary for remote %s"
msgstr "Falta xa.data en el resumen para el remoto %s"

#: common/flatpak-dir.c:1103 common/flatpak-dir.c:1546
#, c-format
msgid "Unsupported summary version %d for remote %s"
msgstr "Versión resumida no admitida %d para el remoto %s"

#: common/flatpak-dir.c:1200
msgid "Remote OCI index has no registry uri"
msgstr "El índice OCI remoto no tiene registro uri"

#: common/flatpak-dir.c:1261
#, c-format
msgid "Couldn't find ref %s in remote %s"
msgstr "No se puede la ref %s en el remoto %s"

#: common/flatpak-dir.c:1288 common/flatpak-dir.c:1381
#, fuzzy, c-format
msgid "Commit has no requested ref ‘%s’ in ref binding metadata (found: ‘%s’)"
msgstr ""
"La confirmación no tiene la referencia solicitada «%s» en los metadatos de "
"enlace de referencia"

#: common/flatpak-dir.c:1413
#, c-format
msgid "Configured collection ID ‘%s’ not in binding metadata"
msgstr "El ID de colección configurado «%s» no está en los metadatos de enlace"

#: common/flatpak-dir.c:1449 common/flatpak-dir.c:5645
#, c-format
msgid "Couldn't find latest checksum for ref %s in remote %s"
msgstr ""
"No se pudo encontrar la última suma de comprobación de la referencia %s en "
"el repositorio remoto %s"

#: common/flatpak-dir.c:1516 common/flatpak-dir.c:1552
#, c-format
msgid "No entry for %s in remote %s summary flatpak sparse cache"
msgstr ""
"No hay entrada para %s en el resumen de caché escasa de flatpak en el remoto "
"%s"

#: common/flatpak-dir.c:2540
#, c-format
msgid "Commit metadata for %s not matching expected metadata"
msgstr ""
"Los metadatos de la confirmación para %s no coinciden con los metadatos "
"esperados"

#: common/flatpak-dir.c:2823
msgid "Unable to connect to system bus"
msgstr "No se puede conectar con el bus del sistema"

#: common/flatpak-dir.c:3419
msgid "User installation"
msgstr "Instalación del usuario"

#: common/flatpak-dir.c:3426
#, c-format
msgid "System (%s) installation"
msgstr "Instalación del sistema (%s)"

#: common/flatpak-dir.c:3472
#, c-format
msgid "No overrides found for %s"
msgstr "No se han encontrado anulaciones para %s"

#: common/flatpak-dir.c:3625
#, c-format
msgid "%s (commit %s) not installed"
msgstr "%s (confirmación %s) no instalada"

#: common/flatpak-dir.c:4650
#, c-format
msgid "Error parsing system flatpakrepo file for %s: %s"
msgstr "Error al actualizar los metados adicionales para «%s»: %s"

#: common/flatpak-dir.c:4735
#, c-format
msgid "While opening repository %s: "
msgstr "Mientras se abría el repositorio %s: "

#: common/flatpak-dir.c:5004
#, c-format
msgid "The config key %s is not set"
msgstr "La clave de configuración %s no está establecida"

#: common/flatpak-dir.c:5140
#, c-format
msgid "No current %s pattern matching %s"
msgstr "Ningún patrón %s actual coincide con %s"

#: common/flatpak-dir.c:5422
msgid "No appstream commit to deploy"
msgstr "No hay una confirmación de appstream que implementar"

#: common/flatpak-dir.c:5941 common/flatpak-dir.c:7266
#: common/flatpak-dir.c:10881 common/flatpak-dir.c:11618
msgid "Can't pull from untrusted non-gpg verified remote"
msgstr ""
"No se puede extraer desde un remoto verificado no gpg que no es de confianza"

#: common/flatpak-dir.c:6376 common/flatpak-dir.c:6591
msgid "Extra data not supported for non-gpg-verified local system installs"
msgstr ""
"No se admiten datos adicionales para instalaciones de sistemas locales no "
"verificadas por gpg"

#: common/flatpak-dir.c:6415 common/flatpak-dir.c:6782
#, c-format
msgid "Invalid checksum for extra data uri %s"
msgstr "Suma de verificación no válida en los datos adicionales de uri %s"

#: common/flatpak-dir.c:6424
#, c-format
msgid "Empty name for extra data uri %s"
msgstr "Nombre vacío para los datos adicionales de la uri %s"

#: common/flatpak-dir.c:6432
#, c-format
msgid "Unsupported extra data uri %s"
msgstr "Uri de datos adicionales no soportada %s"

#: common/flatpak-dir.c:6461
#, c-format
msgid "Failed to load local extra-data %s: %s"
msgstr "Fallo al cargar los datos adicionales locales %s: %s"

#: common/flatpak-dir.c:6469
#, c-format
msgid "Wrong size for extra-data %s"
msgstr "Tamaño incorrecto en los datos adicionales %s"

#: common/flatpak-dir.c:6488
#, c-format
msgid "While downloading %s: "
msgstr "Mientras se descargan %s: "

#: common/flatpak-dir.c:6498
#, c-format
msgid "Wrong size for extra data %s"
msgstr "Tamaño incorrecto en los datos adicionales %s"

#: common/flatpak-dir.c:6507
#, c-format
msgid "Invalid checksum for extra data %s"
msgstr "Suma de verificación no válida en los datos adicionales %s"

#: common/flatpak-dir.c:7096 common/flatpak-dir.c:7349
#, c-format
msgid "While pulling %s from remote %s: "
msgstr "Mientras se está cargando %s desde el repositorio remoto %s: "

#: common/flatpak-dir.c:7290 common/flatpak-repo-utils.c:3886
msgid "GPG signatures found, but none are in trusted keyring"
msgstr ""
"Se encontraron firmas GPG, pero ninguna está en un llavero de confianza"

#: common/flatpak-dir.c:7307
#, c-format
msgid "Commit for ‘%s’ has no ref binding"
msgstr "La confirmación de «%s» no tiene enlace de referencia"

#: common/flatpak-dir.c:7312
#, c-format
msgid "Commit for ‘%s’ is not in expected bound refs: %s"
msgstr ""
"La confirmación de «%s» no está en las referencias enlazadas esperadas: %s"

#: common/flatpak-dir.c:7488
msgid "Only applications can be made current"
msgstr "Solo las aplicaciones pueden actualizarse"

#: common/flatpak-dir.c:8192
msgid "Not enough memory"
msgstr "No hay suficiente memoria"

#: common/flatpak-dir.c:8211
msgid "Failed to read from exported file"
msgstr "Fallo al leer desde un archivo exportado"

#: common/flatpak-dir.c:8401
msgid "Error reading mimetype xml file"
msgstr "Error al leer un archivo de tipo mime XML"

#: common/flatpak-dir.c:8406
msgid "Invalid mimetype xml file"
msgstr "Archivo de tipo mime XML no válido"

#: common/flatpak-dir.c:8492
#, c-format
msgid "D-Bus service file '%s' has wrong name"
msgstr "El archivo de servicio D-Bus «%s» tiene un nombre incorrecto"

#: common/flatpak-dir.c:8647
#, c-format
msgid "Invalid Exec argument %s"
msgstr "Argumento de Exec no válido %s"

#: common/flatpak-dir.c:9115
msgid "While getting detached metadata: "
msgstr "Al obtener metadatos individuales: "

#: common/flatpak-dir.c:9120 common/flatpak-dir.c:9125
#: common/flatpak-dir.c:9129
msgid "Extra data missing in detached metadata"
msgstr "Faltan datos adicionales en los metadatos separados"

#: common/flatpak-dir.c:9133
msgid "While creating extradir: "
msgstr "Al crear carpetas adicionales: "

#: common/flatpak-dir.c:9154 common/flatpak-dir.c:9187
msgid "Invalid checksum for extra data"
msgstr "Firma de verificación incorrecta para los datos adicionales"

#: common/flatpak-dir.c:9183
msgid "Wrong size for extra data"
msgstr "Tamaño  incorrecto para los datos adicionales"

#: common/flatpak-dir.c:9196
#, c-format
msgid "While writing extra data file '%s': "
msgstr "Al escribir el archivo de datos adicionales «%s»: "

#: common/flatpak-dir.c:9204
#, c-format
msgid "Extra data %s missing in detached metadata"
msgstr "Faltan los datos adicionales %s en los metadatos separados"

#: common/flatpak-dir.c:9278
#, fuzzy, c-format
msgid "Unable to get runtime key from metadata"
msgstr "Usar un archivo alternativo para los metadatos"

#: common/flatpak-dir.c:9402
#, c-format
msgid "apply_extra script failed, exit status %d"
msgstr "Ha fallado el script apply_extra, código de error %d"

#. Translators: The placeholder is for an app ref.
#: common/flatpak-dir.c:9591
#, c-format
msgid "Installing %s is not allowed by the policy set by your administrator"
msgstr "La política establecida por su administrador no permite instalar %s"

#: common/flatpak-dir.c:9690
#, c-format
msgid "While trying to resolve ref %s: "
msgstr "Mientras se intentan resolver las referencias %s: "

#: common/flatpak-dir.c:9702
#, c-format
msgid "%s is not available"
msgstr "%s no está disponible"

#: common/flatpak-dir.c:9714 common/flatpak-dir.c:11495
#, c-format
msgid "%s commit %s already installed"
msgstr "%s «commit» %s ya está instalado"

#: common/flatpak-dir.c:9721
msgid "Can't create deploy directory"
msgstr "No se puede crear el carpeta de despliegue"

#: common/flatpak-dir.c:9729
#, c-format
msgid "Failed to read commit %s: "
msgstr "Error al leer el«commit» %s: "

#: common/flatpak-dir.c:9750
#, c-format
msgid "While trying to checkout %s into %s: "
msgstr "Al intentar revisar %s en %s: "

#: common/flatpak-dir.c:9769
msgid "While trying to checkout metadata subpath: "
msgstr "Al intentar revisar el subcarpeta de metadatos: "

#: common/flatpak-dir.c:9801
#, c-format
msgid "While trying to checkout subpath ‘%s’: "
msgstr "Al intentar revisar la subruta «%s»: "

#: common/flatpak-dir.c:9811
msgid "While trying to remove existing extra dir: "
msgstr "Al intentar eliminar la carpeta extra existente: "

#: common/flatpak-dir.c:9822
msgid "While trying to apply extra data: "
msgstr "Al intentar aplicar datos adicionales: "

#: common/flatpak-dir.c:9849
#, c-format
msgid "Invalid commit ref %s: "
msgstr "Referencia de confirmación %s no válida: "

#: common/flatpak-dir.c:9857 common/flatpak-dir.c:9869
#, c-format
msgid "Deployed ref %s does not match commit (%s)"
msgstr "La referencias desplegadas %s no coinciden con el«commit» (%s)"

#: common/flatpak-dir.c:9863
#, c-format
msgid "Deployed ref %s branch does not match commit (%s)"
msgstr ""
"La rama de referencia %s implementada no coincide con la confirmación (%s)"

#: common/flatpak-dir.c:10125 common/flatpak-installation.c:1911
#, c-format
msgid "%s branch %s already installed"
msgstr "%s rama %s ya se encuentra instalada"

#: common/flatpak-dir.c:10985
#, c-format
msgid "Could not unmount revokefs-fuse filesystem at %s: "
msgstr "No se pudo desmontar el sistema de archivos revokefs-fuse en %s: "

#: common/flatpak-dir.c:11289
#, c-format
msgid "This version of %s is already installed"
msgstr "Esta versión de %s ya está instalada"

#: common/flatpak-dir.c:11302
#, c-format
msgid "Can't change remote during bundle install"
msgstr ""
"No se puede cambiar el repositorio remoto durante la instalación de un "
"paquete"

#: common/flatpak-dir.c:11571
msgid "Can't update to a specific commit without root permissions"
msgstr ""
"No se puede actualizar a una confirmación específica sin permisos de root"

#: common/flatpak-dir.c:11852
#, c-format
msgid "Can't remove %s, it is needed for: %s"
msgstr "No se puede eliminar %s, es necesario para: %s"

#: common/flatpak-dir.c:11912 common/flatpak-installation.c:2067
#, c-format
msgid "%s branch %s is not installed"
msgstr "%s rama %s no está instalada"

#: common/flatpak-dir.c:12165
#, c-format
msgid "%s commit %s not installed"
msgstr "Confirmación %s %s no instalada"

#: common/flatpak-dir.c:12501
#, c-format
msgid "Pruning repo failed: %s"
msgstr "Error al podar el repositorio: %s"

#: common/flatpak-dir.c:12669 common/flatpak-dir.c:12675
#, c-format
msgid "Failed to load filter '%s'"
msgstr "Fallo al cargar el filtro «%s»"

#: common/flatpak-dir.c:12681
#, c-format
msgid "Failed to parse filter '%s'"
msgstr "Fallo al analizar el filtro «%s»"

#: common/flatpak-dir.c:12963
msgid "Failed to write summary cache: "
msgstr "Error al escribir la caché de resumen: "

#: common/flatpak-dir.c:12982
#, c-format
msgid "No oci summary cached for remote '%s'"
msgstr "No se almacenó en caché ningún resumen de oci para el remoto «%s»"

#: common/flatpak-dir.c:13207
#, c-format
msgid "No cached summary for remote '%s'"
msgstr "No se almacenó en caché ningún resumen para el remoto «%s»"

#: common/flatpak-dir.c:13248
#, c-format
msgid "Invalid checksum for indexed summary %s read from %s"
msgstr "Suma de comprobación no válida para el resumen indexado %s leído de %s"

#: common/flatpak-dir.c:13321
#, c-format
msgid ""
"Remote listing for %s not available; server has no summary file. Check the "
"URL passed to remote-add was valid."
msgstr ""
"Lista remota para %s no disponible. El servidor no tiene un archivo de "
"resumen. Verifique que la URL pasada a remote-add sea válida."

#: common/flatpak-dir.c:13698
#, c-format
msgid "Invalid checksum for indexed summary %s for remote '%s'"
msgstr ""
"Suma de verificación no válida del resumen indexado %s para el remoto «%s»"

#: common/flatpak-dir.c:14388
#, c-format
msgid "Multiple branches available for %s, you must specify one of: "
msgstr "Múltiples ramas disponibles para %s, debe especificar una de estas: "

#: common/flatpak-dir.c:14454
#, c-format
msgid "Nothing matches %s"
msgstr "Ninguna coincidencia %s"

#: common/flatpak-dir.c:14562
#, c-format
msgid "Can't find ref %s%s%s%s%s"
msgstr "No se puede encontrar la referencia %s%s%s%s%s"

#: common/flatpak-dir.c:14605
#, c-format
msgid "Error searching remote %s: %s"
msgstr "Error al buscar el remoto %s: %s"

#: common/flatpak-dir.c:14702
#, c-format
msgid "Error searching local repository: %s"
msgstr "Error al buscar en el repositorio local: %s"

#: common/flatpak-dir.c:14839
#, c-format
msgid "%s/%s/%s not installed"
msgstr "%s/%s/%s no instalado"

#: common/flatpak-dir.c:15042
#, c-format
msgid "Could not find installation %s"
msgstr "No se pudo encontrar la instalación %s"

#: common/flatpak-dir.c:15612
#, c-format
msgid "Invalid file format, no %s group"
msgstr "Formato de archivo no válido, no hay grupo %s"

#: common/flatpak-dir.c:15617 common/flatpak-repo-utils.c:2836
#, c-format
msgid "Invalid version %s, only 1 supported"
msgstr "Versión no válida %s, solo se admite 1"

#: common/flatpak-dir.c:15622 common/flatpak-dir.c:15627
#, c-format
msgid "Invalid file format, no %s specified"
msgstr "Formato de archivo no válido, no se especificó %s"

#. Check some minimal size so we don't get crap
#: common/flatpak-dir.c:15647
msgid "Invalid file format, gpg key invalid"
msgstr "Formato de archivo no válido, clave gpg no válida"

#: common/flatpak-dir.c:15675 common/flatpak-repo-utils.c:2917
msgid "Collection ID requires GPG key to be provided"
msgstr "El ID de la colección requiere que se proporcione la clave GPG"

#: common/flatpak-dir.c:15718
#, c-format
msgid "Runtime %s, branch %s is already installed"
msgstr "El tiempo de ejecución %s, rama %s ya se encuentra instalado"

#: common/flatpak-dir.c:15719
#, c-format
msgid "App %s, branch %s is already installed"
msgstr "La aplicación %s, rama %s ya se encuentra instalada"

#: common/flatpak-dir.c:15953
#, c-format
msgid "Can't remove remote '%s' with installed ref %s (at least)"
msgstr ""
"No se puede eliminar el remoto «%s» con la referencia %s instalada (al menos)"

#: common/flatpak-dir.c:16058
#, c-format
msgid "Invalid character '/' in remote name: %s"
msgstr "Carácter «/» no válido en el nombre remoto: %s"

#: common/flatpak-dir.c:16064
#, c-format
msgid "No configuration for remote %s specified"
msgstr "No se especificó ninguna configuración para el remoto %s"

#: common/flatpak-dir.c:17597
#, c-format
msgid "Skipping deletion of mirror ref (%s, %s)…\n"
msgstr "Saltándose la eliminación de la referencia espejo (%s, %s)…\n"

#: common/flatpak-exports.c:931
#, c-format
msgid "An absolute path is required"
msgstr "Se requiere una ruta absoluta"

#: common/flatpak-exports.c:948
#, c-format
msgid "Unable to open path \"%s\": %s"
msgstr "No se puede abrir la ruta «%s»: %s"

#: common/flatpak-exports.c:955
#, c-format
msgid "Unable to get file type of \"%s\": %s"
msgstr "No se puede obtener el tipo de archivo de «%s»: %s"

#: common/flatpak-exports.c:964
#, c-format
msgid "File \"%s\" has unsupported type 0o%o"
msgstr "El archivo «%s» tiene un tipo no soportado 0o%o"

#: common/flatpak-exports.c:970
#, c-format
msgid "Unable to get filesystem information for \"%s\": %s"
msgstr ""
"No se pudo obtener la información del sistema de archivos para «%s»: %s"

#: common/flatpak-exports.c:980
#, c-format
msgid "Ignoring blocking autofs path \"%s\""
msgstr "Ignorando el bloqueo de ruta autofs «%s»"

#: common/flatpak-exports.c:996 common/flatpak-exports.c:1009
#: common/flatpak-exports.c:1022
#, c-format
msgid "Path \"%s\" is reserved by Flatpak"
msgstr "La ruta «%s» está reservada por Flatpak"

#: common/flatpak-exports.c:1076
#, c-format
msgid "Unable to resolve symbolic link \"%s\": %s"
msgstr "No se puede resolver el enlace simbólico «%s»: %s"

#: common/flatpak-glib-backports.c:69
msgid "Empty string is not a number"
msgstr "La cadena vacía no es un número"

#: common/flatpak-glib-backports.c:95
#, c-format
msgid "“%s” is not an unsigned number"
msgstr "«%s» no es un número sin signo"

#: common/flatpak-glib-backports.c:105
#, c-format
msgid "Number “%s” is out of bounds [%s, %s]"
msgstr "El número «%s» está fuera de los límites [%s, %s]"

#: common/flatpak-image-source.c:83
msgid "Only sha256 image checksums are supported"
msgstr ""

#: common/flatpak-image-source.c:100 common/flatpak-image-source.c:108
msgid "Image is not a manifest"
msgstr "La imagen no es un manifiesto"

#: common/flatpak-image-source.c:123
msgid "No org.flatpak.ref found in image"
msgstr ""

#: common/flatpak-image-source.c:148
#, c-format
msgid "Ref '%s' not found in registry"
msgstr "La referencia «%s» no está en el registro"

#: common/flatpak-image-source.c:157
msgid "Multiple images in registry, specify a ref with --ref"
msgstr ""
"Hay múltiples imágenes en el registro, especifique una referencia con --ref"

#: common/flatpak-installation.c:834
#, c-format
msgid "Ref %s not installed"
msgstr "Referencia %s no instalada"

#: common/flatpak-installation.c:875
#, c-format
msgid "App %s not installed"
msgstr "Aplicación %s no instalada"

#: common/flatpak-installation.c:1395
#, c-format
msgid "Remote '%s' already exists"
msgstr "El remoto «%s» ya existe"

#: common/flatpak-installation.c:1946
#, c-format
msgid "As requested, %s was only pulled, but not installed"
msgstr "Según lo solicitado, %s solo se extrajo, pero no se instaló"

#: common/flatpak-instance.c:533 common/flatpak-instance.c:687
#: common/flatpak-instance.c:728
#, c-format
msgid "Unable to create directory %s"
msgstr "No se puede crear la carpeta %s"

#: common/flatpak-instance.c:554
#, c-format
msgid "Unable to lock %s"
msgstr "No se puede bloquear %s"

#: common/flatpak-instance.c:627
#, c-format
msgid "Unable to create temporary directory in %s"
msgstr "No se puede crear una carpeta temporal en %s"

#: common/flatpak-instance.c:639
#, c-format
msgid "Unable to create file %s"
msgstr "No se puede crear el archivo %s"

#: common/flatpak-instance.c:646
#, c-format
msgid "Unable to update symbolic link %s/%s"
msgstr "No se puede actualizar el enlace simbólico %s/%s"

#: common/flatpak-oci-registry.c:1197
msgid "Only Bearer authentication supported"
msgstr "Solo se admite la autenticación de portador"

#: common/flatpak-oci-registry.c:1206
msgid "Only realm in authentication request"
msgstr "Nombre dbus no válido: %s"

#: common/flatpak-oci-registry.c:1213
msgid "Invalid realm in authentication request"
msgstr "Nombre dbus no válido: %s"

#: common/flatpak-oci-registry.c:1283
#, c-format
msgid "Authorization failed: %s"
msgstr "Nombre dbus no válido: %s"

#: common/flatpak-oci-registry.c:1285
msgid "Authorization failed"
msgstr "Autorización fallida"

#: common/flatpak-oci-registry.c:1289
#, c-format
msgid "Unexpected response status %d when requesting token: %s"
msgstr "Estado de respuesta inesperado %d al solicitar el token: %s"

#: common/flatpak-oci-registry.c:1300
msgid "Invalid authentication request response"
msgstr "Nombre dbus no válido: %s"

#: common/flatpak-oci-registry.c:1731
#, c-format
msgid "Flatpak was compiled without zstd support"
msgstr ""

#: common/flatpak-oci-registry.c:1923 common/flatpak-oci-registry.c:1975
#: common/flatpak-oci-registry.c:2004 common/flatpak-oci-registry.c:2059
#: common/flatpak-oci-registry.c:2115 common/flatpak-oci-registry.c:2193
msgid "Invalid delta file format"
msgstr "Formato de archivo delta no válido"

#: common/flatpak-oci-registry.c:3198 common/flatpak-oci-registry.c:3382
msgid "Invalid OCI image config"
msgstr "Configuración de imagen OCI no válida"

#: common/flatpak-oci-registry.c:3260 common/flatpak-oci-registry.c:3531
#, c-format
msgid "Wrong layer checksum, expected %s, was %s"
msgstr "Suma de comprobación de capa incorrecta, se esperaba %s, se obtuvo %s"

#: common/flatpak-oci-registry.c:3359
#, c-format
msgid "No ref specified for OCI image %s"
msgstr "No se especificó ninguna referencia para la imagen OCI %s"

#: common/flatpak-oci-registry.c:3369
#, c-format
msgid "Wrong ref (%s) specified for OCI image %s, expected %s"
msgstr "Ref incorrecta (%s) especificada para la imagen OCI %s, se esperaba %s"

#: common/flatpak-progress.c:236
#, c-format
msgid "Downloading metadata: %u/(estimating) %s"
msgstr "Descargando metadatos: %u/(estimando) %s"

#: common/flatpak-progress.c:260
#, c-format
msgid "Downloading: %s/%s"
msgstr "Descargando: %s/%s"

#: common/flatpak-progress.c:280
#, c-format
msgid "Downloading extra data: %s/%s"
msgstr "Descargando datos adicionales: %s/%s"

#: common/flatpak-progress.c:285
#, c-format
msgid "Downloading files: %d/%d %s"
msgstr "Descargando archivos: %d/%d %s"

#: common/flatpak-ref-utils.c:122
msgid "Name can't be empty"
msgstr "El nombre no puede estar vacío"

#: common/flatpak-ref-utils.c:129
msgid "Name can't be longer than 255 characters"
msgstr "El nombre no puede tener más de 255 caracteres"

#: common/flatpak-ref-utils.c:142
msgid "Name can't start with a period"
msgstr "El nombre no puede comenzar con un punto"

#: common/flatpak-ref-utils.c:148
#, c-format
msgid "Name can't start with %c"
msgstr "El nombre no puede comenzar con %c"

#: common/flatpak-ref-utils.c:164
msgid "Name can't end with a period"
msgstr "El nombre no puede terminar con un punto"

#: common/flatpak-ref-utils.c:171 common/flatpak-ref-utils.c:183
msgid "Only last name segment can contain -"
msgstr "Solo el segmento de apellido puede contener -"

#: common/flatpak-ref-utils.c:174
#, c-format
msgid "Name segment can't start with %c"
msgstr "El segmento de nombre no puede comenzar con %c"

#: common/flatpak-ref-utils.c:186
#, c-format
msgid "Name can't contain %c"
msgstr "El nombre no puede contener %c"

#: common/flatpak-ref-utils.c:195
msgid "Names must contain at least 2 periods"
msgstr "Los nombres deben contener al menos 2 puntos"

#: common/flatpak-ref-utils.c:312
msgid "Arch can't be empty"
msgstr "La arquitectura no puede estar vacía"

#: common/flatpak-ref-utils.c:323
#, c-format
msgid "Arch can't contain %c"
msgstr "La arquitectura no puede contener %c"

#: common/flatpak-ref-utils.c:385
msgid "Branch can't be empty"
msgstr "La rama no puede estar vacía"

#: common/flatpak-ref-utils.c:395
#, c-format
msgid "Branch can't start with %c"
msgstr "La rama no puede empezar con %c"

#: common/flatpak-ref-utils.c:405
#, c-format
msgid "Branch can't contain %c"
msgstr "La rama no puede contener %c"

#: common/flatpak-ref-utils.c:615 common/flatpak-ref-utils.c:865
msgid "Ref too long"
msgstr "Referencia demasiado larga"

#: common/flatpak-ref-utils.c:627
msgid "Invalid remote name"
msgstr "Nombre de remoto no válido"

#: common/flatpak-ref-utils.c:641
#, c-format
msgid "%s is not application or runtime"
msgstr "%s no es una aplicación o tiempo de ejecución"

#: common/flatpak-ref-utils.c:650 common/flatpak-ref-utils.c:667
#: common/flatpak-ref-utils.c:683
#, c-format
msgid "Wrong number of components in %s"
msgstr "Número incorrecto de componentes en %s"

#: common/flatpak-ref-utils.c:656
#, c-format
msgid "Invalid name %.*s: %s"
msgstr "Nombre %.*s no válido: %s"

#: common/flatpak-ref-utils.c:673
#, c-format
msgid "Invalid arch: %.*s: %s"
msgstr "Arquitectura no válida: %.*s: %s"

#: common/flatpak-ref-utils.c:816
#, c-format
msgid "Invalid name %s: %s"
msgstr "Nombre %s no válido: %s"

#: common/flatpak-ref-utils.c:834
#, c-format
msgid "Invalid arch: %s: %s"
msgstr "Arquitectura no válida: %s: %s"

#: common/flatpak-ref-utils.c:853
#, c-format
msgid "Invalid branch: %s: %s"
msgstr "Rama no válida: %s: %s"

#: common/flatpak-ref-utils.c:962 common/flatpak-ref-utils.c:970
#: common/flatpak-ref-utils.c:978
#, c-format
msgid "Wrong number of components in partial ref %s"
msgstr "Número erróneo de componentes en la referencia parcial %s"

#: common/flatpak-ref-utils.c:1298
msgid " development platform"
msgstr " plataforma de desarrollo"

#: common/flatpak-ref-utils.c:1300
msgid " platform"
msgstr " plataforma"

#: common/flatpak-ref-utils.c:1302
msgid " application base"
msgstr " base de aplicación"

#: common/flatpak-ref-utils.c:1305
msgid " debug symbols"
msgstr " símbolos de depuración"

#: common/flatpak-ref-utils.c:1307
msgid " sourcecode"
msgstr " código fuente"

#: common/flatpak-ref-utils.c:1309
msgid " translations"
msgstr " traducciones"

#: common/flatpak-ref-utils.c:1311
msgid " docs"
msgstr " docs"

#: common/flatpak-ref-utils.c:1578
#, c-format
msgid "Invalid id %s: %s"
msgstr "Id %s no válido: %s"

#: common/flatpak-remote.c:1216
#, c-format
msgid "Bad remote name: %s"
msgstr "Nombre de remoto defectuoso: %s"

#: common/flatpak-remote.c:1220
#, fuzzy
msgid "No URL specified"
msgstr "No se ha especificado una url"

#: common/flatpak-remote.c:1266
msgid "GPG verification must be enabled when a collection ID is set"
msgstr ""
"La verificación GPG debe estar activada cuando se establece una ID de "
"colección"

#: common/flatpak-repo-utils.c:344
#, c-format
msgid "No extra data sources"
msgstr "Sin orígenes de datos adicionales"

#: common/flatpak-repo-utils.c:2817
#, c-format
msgid "Invalid %s: Missing group ‘%s’"
msgstr "%s no válido: falta el grupo «%s»"

#: common/flatpak-repo-utils.c:2826
#, c-format
msgid "Invalid %s: Missing key ‘%s’"
msgstr "%s no válido: falta la clave «%s»"

#: common/flatpak-repo-utils.c:2876
msgid "Invalid gpg key"
msgstr "Clave GPG no válida"

#: common/flatpak-repo-utils.c:3217
#, c-format
msgid "Error copying 64x64 icon for component %s: %s\n"
msgstr "Error al copiar el ícono de 64x64 para el componente %s: %s\n"

#: common/flatpak-repo-utils.c:3223
#, c-format
msgid "Error copying 128x128 icon for component %s: %s\n"
msgstr "Error al copiar el ícono de 128x128 para el componente %s: %s\n"

#: common/flatpak-repo-utils.c:3362
#, c-format
msgid "%s is end-of-life, ignoring for appstream"
msgstr ""
"%s está al final de su vida útil, ignorando en el flujo de aplicaciones"

#: common/flatpak-repo-utils.c:3397
#, c-format
msgid "No appstream data for %s: %s\n"
msgstr "No hay datos de appstream  para %s: %s\n"

#: common/flatpak-repo-utils.c:3744
msgid "Invalid bundle, no ref in metadata"
msgstr "Paquete no válido, sin referencia en los metadatos"

#: common/flatpak-repo-utils.c:3846
#, c-format
msgid "Collection ‘%s’ of bundle doesn’t match collection ‘%s’ of remote"
msgstr ""
"La colección «%s» del paquete no coincide con la colección «%s» del remoto"

#: common/flatpak-repo-utils.c:3923
msgid "Metadata in header and app are inconsistent"
msgstr "Los metadatos en el encabezado y la aplicación son inconsistentes"

#: common/flatpak-run.c:951
msgid "No systemd user session available, cgroups not available"
msgstr ""
"No hay sesión de usuario de systemd disponible, cgroups no está disponible"

#: common/flatpak-run.c:1496
msgid "Unable to allocate instance id"
msgstr "No se puede asignar el id de instancia"

#: common/flatpak-run.c:1632 common/flatpak-run.c:1641
#, c-format
msgid "Failed to open flatpak-info file: %s"
msgstr "Fallo al abrir el archivo flatpak-info: %s"

#: common/flatpak-run.c:1668
#, c-format
msgid "Failed to open bwrapinfo.json file: %s"
msgstr "Fallo al abrir el archivo bwrapinfo.json: %s"

#: common/flatpak-run.c:1689
#, c-format
msgid "Failed to write to instance id fd: %s"
msgstr "No se pudo escribir en el ID de instancia fd: %s"

#: common/flatpak-run.c:2096
msgid "Initialize seccomp failed"
msgstr "Error al inicializar seccomp"

#: common/flatpak-run.c:2135
#, c-format
msgid "Failed to add architecture to seccomp filter: %s"
msgstr "Error al agregar arquitectura al filtro seccomp: %s"

#: common/flatpak-run.c:2143
#, c-format
msgid "Failed to add multiarch architecture to seccomp filter: %s"
msgstr "No se pudo agregar la arquitectura multiarch al filtro seccomp: %s"

#: common/flatpak-run.c:2175 common/flatpak-run.c:2192
#: common/flatpak-run.c:2214
#, c-format
msgid "Failed to block syscall %d: %s"
msgstr "No se pudo bloquear la llamada al sistema %d: %s"

#: common/flatpak-run.c:2247
#, c-format
msgid "Failed to export bpf: %s"
msgstr "Fallo al exportar bpf: %s"

#: common/flatpak-run.c:2587
#, c-format
msgid "Failed to open ‘%s’"
msgstr "Fallo al abrir «%s»"

#: common/flatpak-run.c:2597
#, c-format
msgid ""
"Directory forwarding needs version 4 of the document portal (have version %d)"
msgstr ""

#: common/flatpak-run.c:2915
#, c-format
msgid "ldconfig failed, exit status %d"
msgstr "ldconfig falló, estado de salida %d"

#: common/flatpak-run.c:2922
msgid "Can't open generated ld.so.cache"
msgstr "No se puede abrir el ld.so.cache generado"

#. Translators: The placeholder is for an app ref.
#: common/flatpak-run.c:3045
#, c-format
msgid "Running %s is not allowed by the policy set by your administrator"
msgstr "La política establecida por su administrador no permite ejecutar %s"

#: common/flatpak-run.c:3202
msgid ""
"\"flatpak run\" is not intended to be run as `sudo flatpak run`. Use `sudo "
"-i` or `su -l` instead and invoke \"flatpak run\" from inside the new shell."
msgstr ""
"«flatpak run» no está diseñado para ejecutarse como «sudo flatpak run». Use "
"«sudo -i» o «su -l» en su lugar e invoque «flatpak run» desde dentro del "
"nuevo shell."

#: common/flatpak-run.c:3413
#, c-format
msgid "Failed to migrate from %s: %s"
msgstr "Fallo al migrar desde %s: %s"

#: common/flatpak-run.c:3434
#, c-format
msgid "Failed to migrate old app data directory %s to new name %s: %s"
msgstr ""
"Error al migrar la carpeta de datos de la aplicación anterior %s al nuevo "
"nombre %s: %s"

#: common/flatpak-run.c:3443
#, c-format
msgid "Failed to create symlink while migrating %s: %s"
msgstr "Fallo al crear el enlace simbólico durante la migración de %s: %s"

#: common/flatpak-run-dbus.c:46
msgid "Failed to open app info file"
msgstr "Fallo al abrir el archivo de información de la aplicación"

#: common/flatpak-run-dbus.c:149
msgid "Unable to create sync pipe"
msgstr "Ha sido imposible crear una tubería sincronizada"

#: common/flatpak-run-dbus.c:185
msgid "Failed to sync with dbus proxy"
msgstr "Fallo al sincronizar con el proxy de dbus"

#: common/flatpak-transaction.c:2275
#, c-format
msgid "Warning: Problem looking for related refs: %s"
msgstr "Aviso: Problema al buscar referencias relacionadas: %s"

#: common/flatpak-transaction.c:2493
#, c-format
msgid "The application %s requires the runtime %s which was not found"
msgstr "La aplicación %s requiere el tiempo de ejecución %s que no se encontró"

#: common/flatpak-transaction.c:2509
#, c-format
msgid "The application %s requires the runtime %s which is not installed"
msgstr ""
"La aplicación %s requiere el tiempo de ejecución %s que no está instalado"

#: common/flatpak-transaction.c:2641
#, c-format
msgid "Can't uninstall %s which is needed by %s"
msgstr "No se puede desinstalar %s que %s necesita"

#: common/flatpak-transaction.c:2740
#, c-format
msgid "Remote %s disabled, ignoring %s update"
msgstr ""
"El repositorio remoto %s está deshabilitado, ignorando la actualización %s"

#: common/flatpak-transaction.c:2773
#, c-format
msgid "%s is already installed"
msgstr "%s ya está instalado"

#: common/flatpak-transaction.c:2776
#, c-format
msgid "%s is already installed from remote %s"
msgstr "%s ya fue instalado desde el remoto %s"

#: common/flatpak-transaction.c:3120
#, c-format
msgid "Invalid .flatpakref: %s"
msgstr ".flatpakref no válido: %s"

#: common/flatpak-transaction.c:3161
msgid "Warning: Could not mark already installed apps as preinstalled"
msgstr ""

#: common/flatpak-transaction.c:3382
#, c-format
msgid "Error updating remote metadata for '%s': %s"
msgstr "Error al actualizar los metadatos del remoto para «%s»: %s"

#: common/flatpak-transaction.c:3885
#, c-format
msgid ""
"Warning: Treating remote fetch error as non-fatal since %s is already "
"installed: %s"
msgstr ""
"Advertencia: Tratando el error de recuperación remota como no fatal ya que "
"%s ya está instalado: %s"

#: common/flatpak-transaction.c:4209
#, c-format
msgid "No authenticator installed for remote '%s'"
msgstr "No se ha instalado un autenticador para el remoto «%s»"

#: common/flatpak-transaction.c:4313 common/flatpak-transaction.c:4320
#, c-format
msgid "Failed to get tokens for ref: %s"
msgstr "Fallo al obtener identificadores para la referencia: %s"

#: common/flatpak-transaction.c:4315 common/flatpak-transaction.c:4322
msgid "Failed to get tokens for ref"
msgstr "Fallo al obtener identificadores para la referencia"

#: common/flatpak-transaction.c:4580
#, c-format
msgid "Ref %s from %s matches more than one transaction operation"
msgstr "Ref %s de %s coincide con más de una operación de transacción"

#: common/flatpak-transaction.c:4581 common/flatpak-transaction.c:4591
msgid "any remote"
msgstr "cualquier remoto"

#: common/flatpak-transaction.c:4590
#, c-format
msgid "No transaction operation found for ref %s from %s"
msgstr ""
"No se encontró ninguna operación de transacción para la referencia %s de %s"

#: common/flatpak-transaction.c:4713
#, c-format
msgid "Flatpakrepo URL %s not file, HTTP or HTTPS"
msgstr "Flatpakrepo URL %s no archivo, HTTP o HTTPS"

#: common/flatpak-transaction.c:4719
#, c-format
msgid "Can't load dependent file %s: "
msgstr "No se puede cargar el archivo dependiente %s: "

#: common/flatpak-transaction.c:4727
#, c-format
msgid "Invalid .flatpakrepo: %s"
msgstr ".flatpakrepo no válido: %s"

#: common/flatpak-transaction.c:5454
msgid "Transaction already executed"
msgstr "La transacción ya se ejecutó"

#: common/flatpak-transaction.c:5469
msgid ""
"Refusing to operate on a user installation as root! This can lead to "
"incorrect file ownership and permission errors."
msgstr ""
"¡Negándose a operar en una instalación de usuario como root! Esto puede dar "
"lugar a una propiedad incorrecta del archivo y errores de permiso."

#: common/flatpak-transaction.c:5567 common/flatpak-transaction.c:5580
msgid "Aborted by user"
msgstr "Abortado por el usuario"

#: common/flatpak-transaction.c:5605
#, c-format
msgid "Skipping %s due to previous error"
msgstr "Saltando %s debido al error anterior"

#: common/flatpak-transaction.c:5659
#, c-format
msgid "Aborted due to failure (%s)"
msgstr "Abortado debido a fallo (%s)"

#: common/flatpak-uri.c:118
#, no-c-format
msgid "Invalid %-encoding in URI"
msgstr "%-encoding no válido en URI"

#: common/flatpak-uri.c:135
msgid "Illegal character in URI"
msgstr "Carácter ilegal en URI"

#: common/flatpak-uri.c:169
msgid "Non-UTF-8 characters in URI"
msgstr "Caracteres no UTF-8 en URI"

#: common/flatpak-uri.c:275
#, c-format
msgid "Invalid IPv6 address ‘%.*s’ in URI"
msgstr "Dirección IPv6 no válida «%.*s» en URI"

#: common/flatpak-uri.c:330
#, c-format
msgid "Illegal encoded IP address ‘%.*s’ in URI"
msgstr "Dirección IP codificada ilegal «%.*s» en URI"

#: common/flatpak-uri.c:342
#, c-format
msgid "Illegal internationalized hostname ‘%.*s’ in URI"
msgstr "Nombre de host internacionalizado ilegal «%.*s» en URI"

#: common/flatpak-uri.c:374 common/flatpak-uri.c:386
#, c-format
msgid "Could not parse port ‘%.*s’ in URI"
msgstr "No se pudo analizar el puerto «%.*s» en URI"

#: common/flatpak-uri.c:393
#, c-format
msgid "Port ‘%.*s’ in URI is out of range"
msgstr "El puerto «%.*s» en URI está fuera de rango"

#: common/flatpak-uri.c:910
msgid "URI is not absolute, and no base URI was provided"
msgstr "El URI no es absoluto y no se proporcionó ningún URI base"

#: common/flatpak-usb.c:83
#, c-format
msgid "USB device query 'all' must not have data"
msgstr ""

#: common/flatpak-usb.c:102
#, c-format
msgid "USB query rule 'cls' must be in the form CLASS:SUBCLASS or CLASS:*"
msgstr ""

#: common/flatpak-usb.c:111
#, fuzzy, c-format
msgid "Invalid USB class"
msgstr "Id %s no válido: %s"

#: common/flatpak-usb.c:125
#, c-format
msgid "Invalid USB subclass"
msgstr ""

#: common/flatpak-usb.c:141 common/flatpak-usb.c:148
#, c-format
msgid "USB query rule 'dev' must have a valid 4-digit hexadecimal product id"
msgstr ""

#: common/flatpak-usb.c:164 common/flatpak-usb.c:171
#, c-format
msgid "USB query rule 'vnd' must have a valid 4-digit hexadecimal vendor id"
msgstr ""

#: common/flatpak-usb.c:205
#, c-format
msgid "USB device queries must be in the form TYPE:DATA"
msgstr ""

#: common/flatpak-usb.c:225
#, c-format
msgid "Unknown USB query rule %s"
msgstr ""

#: common/flatpak-usb.c:248
#, c-format
msgid "Empty USB query"
msgstr ""

#: common/flatpak-usb.c:274
#, c-format
msgid "Multiple USB query rules of the same type is not supported"
msgstr ""

#: common/flatpak-usb.c:283
#, c-format
msgid "'all' must not contain extra query rules"
msgstr ""

#: common/flatpak-usb.c:291
#, c-format
msgid "USB queries with 'dev' must also specify vendors"
msgstr ""

#: common/flatpak-utils.c:712
msgid "Glob can't match apps"
msgstr "El glob no puede coincidir con las aplicaciones"

#: common/flatpak-utils.c:737
msgid "Empty glob"
msgstr "Glob vacío"

#: common/flatpak-utils.c:756
msgid "Too many segments in glob"
msgstr "Demasiados argumentos en el glob"

#: common/flatpak-utils.c:777
#, c-format
msgid "Invalid glob character '%c'"
msgstr "Caracter de glob «%c» no válido"

#: common/flatpak-utils.c:831
#, c-format
msgid "Missing glob on line %d"
msgstr "Falta un glob en la línea %d"

#: common/flatpak-utils.c:835
#, c-format
msgid "Trailing text on line %d"
msgstr "Texto final en la línea %d"

#: common/flatpak-utils.c:839
#, c-format
msgid "on line %d"
msgstr "en la línea %d"

#: common/flatpak-utils.c:861
#, c-format
msgid "Unexpected word '%s' on line %d"
msgstr "Palabra «%s» inesperada en la línea %d"

#: common/flatpak-utils.c:2118
#, c-format
msgid "Invalid require-flatpak argument %s"
msgstr "Argumento de require-flatpak no válido %s"

#: common/flatpak-utils.c:2128 common/flatpak-utils.c:2147
#, c-format
msgid "%s needs a later flatpak version (%s)"
msgstr "%s necesita una versión de flatpak superior (%s)"

#: oci-authenticator/flatpak-oci-authenticator.c:291
msgid "Not a oci remote, missing summary.xa.oci-repository"
msgstr "No es un oci remoto, falta summary.xa.oci-repository"

#: oci-authenticator/flatpak-oci-authenticator.c:477
msgid "Not a OCI remote"
msgstr "No es un remoto OCI"

#: oci-authenticator/flatpak-oci-authenticator.c:488
msgid "Invalid token"
msgstr "Token no válido"

#: portal/flatpak-portal.c:2292
#, c-format
msgid "No portal support found"
msgstr "No se encontró soporte de portal"

#: portal/flatpak-portal.c:2298
msgid "Deny"
msgstr "Denegar"

#: portal/flatpak-portal.c:2300
msgid "Update"
msgstr "Actualizar"

#: portal/flatpak-portal.c:2305
#, c-format
msgid "Update %s?"
msgstr "¿Actualizar %s?"

#: portal/flatpak-portal.c:2317
msgid "The application wants to update itself."
msgstr "La aplicación necesita actualizarse."

#: portal/flatpak-portal.c:2318
msgid "Update access can be changed any time from the privacy settings."
msgstr ""
"El acceso a la actualización se puede cambiar desde la configuración de "
"privacidad."

#: portal/flatpak-portal.c:2343
#, c-format
msgid "Application update not allowed"
msgstr "No se permite actualizar la aplicación"

#: portal/flatpak-portal.c:2501
#, c-format
msgid "Self update not supported, new version requires new permissions"
msgstr ""
"No se permite la actualización automática, la versión nueva requiere nuevos "
"permisos"

#: portal/flatpak-portal.c:2684 portal/flatpak-portal.c:2702
#, c-format
msgid "Update ended unexpectedly"
msgstr "La actualización finalizó inesperadamente"

#. SECURITY:
#. - Normal users need admin authentication to install software
#. system-wide.
#. - Note that we install polkit rules that allow local users
#. in the wheel group to install without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:23
msgid "Install signed application"
msgstr "Instalar aplicación firmada"

#: system-helper/org.freedesktop.Flatpak.policy.in:24
#: system-helper/org.freedesktop.Flatpak.policy.in:42
msgid "Authentication is required to install software"
msgstr "Se requiere autenticación para instalar el software"

#. SECURITY:
#. - Normal users need admin authentication to install software
#. system-wide.
#. - Note that we install polkit rules that allow local users
#. in the wheel group to install without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:41
msgid "Install signed runtime"
msgstr "Instalar tiempo de ejecución firmado"

#. SECURITY:
#. - Normal users do not require admin authentication to update an
#. app as the commit will be signed, and the action is required
#. to update the system when unattended.
#. - Changing this to anything other than 'yes' will break unattended
#. updates.
#: system-helper/org.freedesktop.Flatpak.policy.in:60
msgid "Update signed application"
msgstr "Actualizar aplicación firmada"

#: system-helper/org.freedesktop.Flatpak.policy.in:61
#: system-helper/org.freedesktop.Flatpak.policy.in:80
msgid "Authentication is required to update software"
msgstr "La autentificación es obligatoria para actualizar un programa"

#. SECURITY:
#. - Normal users do not require admin authentication to update a
#. runtime as the commit will be signed, and the action is required
#. to update the system when unattended.
#. - Changing this to anything other than 'yes' will break unattended
#. updates.
#: system-helper/org.freedesktop.Flatpak.policy.in:79
msgid "Update signed runtime"
msgstr "Actualizar tiempo de ejecución firmado"

#. SECURITY:
#. - Normal users do not need authentication to update metadata
#. from signed repositories.
#: system-helper/org.freedesktop.Flatpak.policy.in:94
msgid "Update remote metadata"
msgstr "Actualizar metadatos remotos"

#: system-helper/org.freedesktop.Flatpak.policy.in:95
msgid "Authentication is required to update remote info"
msgstr "Se requiere autenticación para actualizar la información remota"

#. SECURITY:
#. - Normal users do not need authentication to modify the
#. OSTree repository
#. - Note that we install polkit rules that allow local users
#. in the wheel group to modify repos without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:111
msgid "Update system repository"
msgstr "Actualizar el repositorio del sistema"

#: system-helper/org.freedesktop.Flatpak.policy.in:112
msgid "Authentication is required to modify a system repository"
msgstr "Se requiere autenticación para modificar un repositorio del sistema"

#. SECURITY:
#. - Normal users need admin authentication to install software
#. system-wide.
#: system-helper/org.freedesktop.Flatpak.policy.in:126
msgid "Install bundle"
msgstr "Instalar paquete"

#: system-helper/org.freedesktop.Flatpak.policy.in:127
msgid "Authentication is required to install software from $(path)"
msgstr "Se requiere autenticación para instalar software desde $(path)"

#. SECURITY:
#. - Normal users need admin authentication to uninstall software
#. system-wide.
#. - Note that we install polkit rules that allow local users
#. in the wheel group to uninstall without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:144
msgid "Uninstall runtime"
msgstr "Desinstalar tiempo de ejecución"

#: system-helper/org.freedesktop.Flatpak.policy.in:145
msgid "Authentication is required to uninstall software"
msgstr "Se requiere autenticación para desinstalar el software"

#. SECURITY:
#. - Normal users need admin authentication to uninstall software
#. system-wide.
#. - Note that we install polkit rules that allow local users
#. in the wheel group to uninstall without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:161
msgid "Uninstall app"
msgstr "Desinstalar aplicación"

#: system-helper/org.freedesktop.Flatpak.policy.in:162
msgid "Authentication is required to uninstall $(ref)"
msgstr "Se requiere autenticación para desinstalar $(ref)"

#. SECURITY:
#. - Normal users need admin authentication to configure system-wide
#. software repositories.
#: system-helper/org.freedesktop.Flatpak.policy.in:177
msgid "Configure Remote"
msgstr "Configurar Repositorio Remoto"

#: system-helper/org.freedesktop.Flatpak.policy.in:178
msgid "Authentication is required to configure software repositories"
msgstr "Se requiere autenticación para configurar repositorios de software"

#. SECURITY:
#. - Normal users need admin authentication to configure the system-wide
#. Flatpak installation.
#: system-helper/org.freedesktop.Flatpak.policy.in:192
msgid "Configure"
msgstr "Configurar"

#: system-helper/org.freedesktop.Flatpak.policy.in:193
msgid "Authentication is required to configure software installation"
msgstr "Se requiere autenticación para configurar la instalación del software"

#. SECURITY:
#. - Normal users do not require admin authentication to update
#. appstream data as it will be signed, and the action is required
#. to update the system when unattended.
#. - Changing this to anything other than 'yes' will break unattended
#. updates.
#: system-helper/org.freedesktop.Flatpak.policy.in:210
msgid "Update appstream"
msgstr "Actualizar appstream"

#: system-helper/org.freedesktop.Flatpak.policy.in:211
msgid "Authentication is required to update information about software"
msgstr ""
"Se requiere autenticación para actualizar la información sobre el software"

#. SECURITY:
#. - Normal users do not require admin authentication to update
#. metadata as it will be signed, and the action is required
#. to update the system when unattended.
#. - Changing this to anything other than 'yes' will break unattended
#. updates.
#: system-helper/org.freedesktop.Flatpak.policy.in:228
msgid "Update metadata"
msgstr "Actualizar metadatos"

#: system-helper/org.freedesktop.Flatpak.policy.in:229
msgid "Authentication is required to update metadata"
msgstr "La autentificación es obligatoria para actualizar los metadatos"

#. SECURITY:
#. - Authorisation to actually install software is controlled by
#. org.freedesktop.Flatpak.app-install.
#. - This action is checked after app-install, as it can only be done
#. once the app’s data (including its content rating) has been
#. downloaded.
#. - This action is checked to see if the installation should be allowed
#. based on whether the app being installed has content which doesn’t
#. comply with the user’s parental controls policy (the content is
#. ‘too extreme’).
#. - It is checked only if an app has too extreme content for the user
#. who is trying to install it (in which case, the app is ‘unsafe’).
#. - Typically, normal users will need admin permission to install apps
#. with extreme content; admins will be able to install it without
#. additional checks.
#. - In order to configure the policy so that admins can install safe and
#. unsafe software anywhere without authorisation, and non-admins can
#. install safe software in their user or system dirs without
#. authorisation, but need authorisation to install unsafe software
#. anywhere:
#. * Unconditionally return `yes` from `app-install`.
#. * Return `auth_admin` from `override-parental-controls` for users
#. not in `@privileged_group@`, and `yes` for users in it.
#. * Set the malcontent `is-{user,system}-installation-allowed`
#. properties of all non-admins’ parental controls policies to true.
#. - In order to configure the policy so that admins can install safe and
#. unsafe software anywhere without authorisation, and non-admins can
#. install safe software in their user dir without authorisation, but
#. need authorisation to install safe software in the system dir or to
#. install unsafe software anywhere:
#. * Unconditionally return `yes` from `app-install`.
#. * Return `auth_admin` from `override-parental-controls` for users
#. not in `@privileged_group@`, and `yes` for users in it.
#. * Set the malcontent `is-user-installation-allowed` property of all
#. non-admins’ parental controls policies to true.
#. * Set the malcontent `is-system-installation-allowed` property of
#. all non-admins’ parental controls policies to false.
#. - In order to configure the policy so that all users (including
#. admins) can install safe software anywhere without authorisation,
#. but need authorisation to install unsafe software anywhere (i.e.
#. applying parental controls to admins too):
#. * Unconditionally return `yes` from `app-install`.
#. * Unconditionally return `auth_admin` from `override-parental-controls`.
#. * Set the malcontent `is-user-installation-allowed` property of all
#. users’ parental controls policies to true.
#. * Set the malcontent `is-system-installation-allowed` property of
#. all users’ parental controls policies to true.
#: system-helper/org.freedesktop.Flatpak.policy.in:287
#, fuzzy
msgid "Override parental controls for installs"
msgstr "Desactivar control parental"

#: system-helper/org.freedesktop.Flatpak.policy.in:288
msgid ""
"Authentication is required to install software which is restricted by your "
"parental controls policy"
msgstr ""
"La autentificación es obligatoria para instalar un programa que está "
"restringido por su política de control parental"

#. SECURITY:
#. - This is like org.freedesktop.Flatpak.override-parental-controls, but
#. it’s queried for app updates, whereas the former is queried for app
#. installs.
#. - As with the above action, this one is only queried if
#. org.freedesktop.Flatpak.app-update has allowed the app update, and
#. only if the app being updated has too extreme content for the user
#. who is trying to update it.
#. - The default policy for this is to *allow* updates to ‘too extreme’
#. apps by default, on the basis that having an out-of-date (i.e.
#. insecure or unsupported) app is a worse outcome than automatically
#. installing an update which has radically different content from the
#. version of the app which the parent originally vetted and installed.
#: system-helper/org.freedesktop.Flatpak.policy.in:313
#, fuzzy
msgid "Override parental controls for updates"
msgstr "Desactivar control parental"

#: system-helper/org.freedesktop.Flatpak.policy.in:314
#, fuzzy
msgid ""
"Authentication is required to update software which is restricted by your "
"parental controls policy"
msgstr ""
"La autentificación es obligatoria para instalar un programa que está "
"restringido por su política de control parental"

#~ msgid "Installed:"
#~ msgstr "Instalada:"

#~ msgid "Download:"
#~ msgstr "Descarga:"

#, c-format
#~ msgid "No gpg key found with ID %s (homedir: %s)"
#~ msgstr "No se encontró ninguna clave gpg con ID %s (homedir: %s)"

#, c-format
#~ msgid "Unable to lookup key ID %s: %d"
#~ msgstr "No se puede buscar el ID de clave %s: %d"

#, c-format
#~ msgid "Error signing commit: %d"
#~ msgstr "Error al firmar la confirmación: %d"

#, c-format
#~ msgid ""
#~ "Found similar ref(s) for ‘%s’ in remote ‘%s’ (%s).\n"
#~ "Use this remote?"
#~ msgstr ""
#~ "Se encontraron ref(s) similares instaladas para «%s» en el remoto «%s» "
#~ "(%s).\n"
#~ "¿Usar este remoto?"

#, c-format
#~ msgid "No entry for %s in remote '%s' summary cache "
#~ msgstr "No hay entrada para %s en la caché de resumen del remoto «%s» "

#, c-format
#~ msgid "Failed to uninstall %s for rebase to %s: "
#~ msgstr "Fallo al desinstalar %s para rebasar a %s: "

#, c-format
#~ msgid "Failed to uninstall %s for rebase to %s: %s\n"
#~ msgstr "Fallo al desinstalar %s para rebasar a %s: %s\n"

#, c-format
#~ msgid "Unable to open directory %s"
#~ msgstr "No se puede abrir la carpeta %s"

#~ msgid "install"
#~ msgstr "instalar"

#~ msgid "update"
#~ msgstr "actualizar"

#~ msgid "install bundle"
#~ msgstr "instalar paquete"

#~ msgid "uninstall"
#~ msgstr "desinstalar"

#~ msgid "(internal error, please report)"
#~ msgstr "(error interno, envíe un informe)"

#~ msgid "Warning:"
#~ msgstr "Advertencia:"

#, fuzzy
#~ msgid "runtime"
#~ msgstr "Runtime"

#, fuzzy
#~ msgid "app"
#~ msgstr "Aplicación"

#, fuzzy, c-format
#~ msgid "%s Failed to %s %s: %s\n"
#~ msgstr "Error: Fallo al %s %s: %s\n"

#~ msgid "[REF…] - Uninstall an application"
#~ msgstr "[REF…] - Desinstala una aplicación"

#, c-format
#~ msgid "Replace it with %s?"
#~ msgstr "¿Reemplazarlo con %s?"

#, fuzzy
#~ msgid "Invalid deployed ref %s: "
#~ msgstr "PID %s no válido"

#, fuzzy
#~ msgid "Deployed ref %s kind does not match commit (%s)"
#~ msgstr "La referencias desplegadas %s no coinciden con el«commit» (%s)"

#, fuzzy
#~ msgid "Deployed ref %s name does not match commit (%s)"
#~ msgstr "La referencias desplegadas %s no coinciden con el«commit» (%s)"

#, fuzzy
#~ msgid "Deployed ref %s arch does not match commit (%s)"
#~ msgstr "La referencias desplegadas %s no coinciden con el«commit» (%s)"

#, fuzzy
#~ msgid "Failed to determine parts from ref: %s"
#~ msgstr "Fallo al abrir un archivo temporal: %s"

#, fuzzy
#~ msgid "Invalid arch %s"
#~ msgstr "PID %s no válido"

#, fuzzy
#~ msgid "Related ref '%s' is only partially installed"
#~ msgstr "La extensión %s requerida solo está instalada parcialmente"

#, fuzzy
#~ msgid "Ref '%s' is only partially installed"
#~ msgstr "La extensión %s requerida solo está instalada parcialmente"

#, fuzzy
#~ msgid "No such ref (%s, %s) in remote %s"
#~ msgstr "No se puede encontrar %s en el repositorio remoto %s"

#, fuzzy
#~ msgid "No flatpak cache in remote '%s' summary"
#~ msgstr "No hay un caché de flatpak en el repositorio remoto"

#, fuzzy
#~ msgid "No such ref (%s, %s) in remote %s or elsewhere"
#~ msgstr "No se puede encontrar %s en el repositorio remoto %s"

#, fuzzy
#~ msgid "No summary found"
#~ msgstr "Ninguna coincidencia %s"

#~ msgid "Deployed metadata does not match commit"
#~ msgstr "Los metadatos no coinciden con el commit"

#, fuzzy
#~ msgid "No repo metadata cached for remote '%s'"
#~ msgstr "No hay un caché de flatpak en el repositorio remoto"

#, fuzzy
#~ msgid "No metadata branch for OCI"
#~ msgstr "Imprime los metadatos de una rama"

#, fuzzy
#~ msgid "Invalid group: %d"
#~ msgstr "PID %s inválido"

#, fuzzy
#~ msgid "Warning: Can't find %s metadata for dependencies: %s"
#~ msgstr ""
#~ "Aviso: No se pueden actualizar los metadatos adicionales para '%s': %s\n"

#~ msgid "Not running as root, may be unable to enter namespace"
#~ msgstr ""
#~ "No se está ejecutando como root, puede ser imposible entrar al espacio de "
#~ "nombres"

#, fuzzy
#~ msgid "Default system installation"
#~ msgstr "Mostrar instalaciones del sistema"

#~ msgid "No url specified in flatpakrepo file"
#~ msgstr "No se ha especificado una url en el archivo flatpakrepo"

#, fuzzy
#~ msgid "%s branch already installed"
#~ msgstr "%s rama %s ya se encuentra instalada"

#~ msgid "%s branch %s not installed"
#~ msgstr "%s rama %s no instalada"

#~ msgid "Print OSTree debug information during command processing"
#~ msgstr ""
#~ "Imprimir información de depuración de OSTree durante el procesado del "
#~ "comando"

#~ msgid "Show help options"
#~ msgstr "Mostrar las opciones de ayuda"

#, fuzzy
#~ msgid "Architecture"
#~ msgstr "Arquitectura a usar"

#~ msgid "Location:"
#~ msgstr "Localización:"

#, fuzzy
#~ msgid "Installing for user: %s from %s\n"
#~ msgstr "Instalando: %s desde %s\n"

#~ msgid "Installing: %s from %s\n"
#~ msgstr "Instalando: %s desde %s\n"

#, fuzzy
#~ msgid "Updating for user: %s from %s\n"
#~ msgstr ""
#~ "Actualizando: %s desde\n"
#~ " %s\n"

#~ msgid "Updating: %s from %s\n"
#~ msgstr ""
#~ "Actualizando: %s desde\n"
#~ " %s\n"

#, fuzzy
#~ msgid "Installing for user: %s from bundle %s\n"
#~ msgstr "Instalando: %s desde el paquete %s\n"

#~ msgid "Installing: %s from bundle %s\n"
#~ msgstr "Instalando: %s desde el paquete %s\n"

#, fuzzy
#~ msgid "Uninstalling for user: %s\n"
#~ msgstr "Instalando: %s desde %s\n"

#~ msgid "No updates.\n"
#~ msgstr "Sin actualizaciones.\n"

#~ msgid "Now at %s.\n"
#~ msgstr "Ahora a las %s.\n"

#, fuzzy
#~ msgid "new file access"
#~ msgstr ""
#~ "\n"
#~ " Administrar el acceso a archivos"

#, fuzzy
#~ msgid "file access"
#~ msgstr ""
#~ "\n"
#~ " Administrar el acceso a archivos"

#, fuzzy
#~ msgid "new system dbus access"
#~ msgstr "Llamadas al bus de registro de sistema"

#, fuzzy
#~ msgid "system dbus access"
#~ msgstr "Llamadas al bus de registro de sistema"

#, fuzzy
#~ msgid "Installing in %s:\n"
#~ msgstr "Instalando: %s\n"

#, fuzzy
#~ msgid "Invalid .flatpakref"
#~ msgstr "PID %s inválido"

#, fuzzy
#~ msgid "Authentication is required to install $(ref) from $(origin)"
#~ msgstr "La autentificación es obligatoria para instalar un programa"

#, fuzzy
#~ msgid "Authentication is required to update $(ref) from $(origin)"
#~ msgstr ""
#~ "La autentificación es obligatoria para actualizar la información remota"

#, fuzzy
#~ msgid "Authentication is required to update the remote $(remote)"
#~ msgstr ""
#~ "La autentificación es obligatoria para actualizar la información remota"

#, fuzzy
#~ msgid "Authentication is required to modify the remote $(remote)"
#~ msgstr ""
#~ "La autentificación es obligatoria para actualizar la información remota"

#, fuzzy
#~ msgid "Authentication is required to configure the remote $(remote)"
#~ msgstr ""
#~ "La autentificación es obligatoria para configurar repositorio de software"

#, fuzzy
#~ msgid "Runtime Branch"
#~ msgstr "Runtime:"

#, fuzzy
#~ msgid "Runtime Commit"
#~ msgstr "Commit activo"

#~ msgid "Unknown command '%s'"
#~ msgstr "Comando desconocido '%s'"

#, fuzzy
#~ msgid "Migrating %s to %s\n"
#~ msgstr ""
#~ "Actualizando: %s desde\n"
#~ " %s\n"

#, fuzzy
#~ msgid "Error during migration: %s\n"
#~ msgstr "Error: Fallo al %s %s: %s\n"

#, fuzzy
#~ msgid "Redirect collection ID: %s\n"
#~ msgstr "ID de colección"

#~ msgid "Invalid sha256 for extra data uri %s"
#~ msgstr ""
#~ "Suma de verificación sha256 inválida para los datos adicionales de la uri "
#~ "%s"

#~ msgid "Invalid sha256 for extra data"
#~ msgstr "Suma de verificación sha256 inválida para los datos adicionales"

#~ msgid "Add OCI registry"
#~ msgstr "Añadir registro OCI"

#, fuzzy
#~ msgid "Found in remote %s\n"
#~ msgstr "Encontrado en varios repositorios remotos:\n"

#~ msgid "Found in remote %s, do you want to install it?"
#~ msgstr "%s encontrado en repositorio remoto, quieres instalarlo?"

#~ msgid "Found in several remotes:\n"
#~ msgstr "Encontrado en varios repositorios remotos:\n"

#~ msgid "The required runtime %s was not found in a configured remote.\n"
#~ msgstr ""
#~ "El tiempo de ejecución %s requerido no se ha podido encontrar en un "
#~ "repositorio remoto de entre los configurados.\n"

#~ msgid "%s already installed, skipping\n"
#~ msgstr "%s ya está instalado, ignorando\n"

#~ msgid "One or more operations failed"
#~ msgstr "Han fallado una o más operaciones"

#~ msgid "No ref information available in repository"
#~ msgstr "Información de referencia no disponible en el repositorio"

#~ msgid "Remote title not set"
#~ msgstr "Titulo de repositorio remoto no establecido"

#~ msgid "Remote default-branch not set"
#~ msgstr "Rama por defecto del repositorio remoto no establecida"

#, fuzzy
#~ msgid "Search specific system-wide installations"
#~ msgstr "Mostrar instalaciones especificas del sistema"

#~ msgid "Failed to unlink temporary file"
#~ msgstr "Fallo al desvincular un archivo temporal"

#~ msgid "Post-Install %s"
#~ msgstr "Post instalación %s"

===== ./po/ro.po =====
# Romanian translation for flatpak.
# Copyright (C) 2020 flatpak's COPYRIGHT HOLDER
# This file is distributed under the same license as the flatpak package.
# Florentina Mușat <emryslokadottir@gmail.com>, 2020.
#
msgid ""
msgstr ""
"Project-Id-Version: flatpak master\n"
"Report-Msgid-Bugs-To: https://github.com/flatpak/flatpak/issues\n"
"POT-Creation-Date: 2026-05-27 16:39+0200\n"
"PO-Revision-Date: 2020-07-02 15:35+0200\n"
"Last-Translator: Florentina Mușat <florentina [dot] musat [dot] 28 [at] "
"gmail [dot] com>\n"
"Language-Team: Romanian <gnomero-list@lists.sourceforge.net>\n"
"Language: ro\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=(n==1 ? 0 : (n==0 || (n%100 > 0 && n%100 < "
"20)) ? 1 : 2);;\n"
"X-Generator: Poedit 2.3.1\n"

#: app/flatpak-builtins-build-bundle.c:59
msgid "Export runtime instead of app"
msgstr "Exportă executarea în locul aplicației"

#: app/flatpak-builtins-build-bundle.c:60
msgid "Arch to bundle for"
msgstr "Arhitectura pentru care se împachetează"

#: app/flatpak-builtins-build-bundle.c:60
#: app/flatpak-builtins-build-export.c:62 app/flatpak-builtins-build-init.c:53
#: app/flatpak-builtins-build-sign.c:42 app/flatpak-builtins-create-usb.c:46
#: app/flatpak-builtins-info.c:55 app/flatpak-builtins-install.c:67
#: app/flatpak-builtins-list.c:50 app/flatpak-builtins-make-current.c:38
#: app/flatpak-builtins-remote-info.c:54 app/flatpak-builtins-remote-ls.c:56
#: app/flatpak-builtins-run.c:158 app/flatpak-builtins-search.c:37
#: app/flatpak-builtins-uninstall.c:54 app/flatpak-builtins-update.c:56
msgid "ARCH"
msgstr "ARHI"

#: app/flatpak-builtins-build-bundle.c:61
#, fuzzy
msgid "URL for repo"
msgstr "Url pentru deposit"

#: app/flatpak-builtins-build-bundle.c:61
#: app/flatpak-builtins-build-bundle.c:62
#: app/flatpak-builtins-build-update-repo.c:68
#: app/flatpak-builtins-build-update-repo.c:72
#: app/flatpak-builtins-build-update-repo.c:73
#: app/flatpak-builtins-history.c:69 app/flatpak-builtins-remote-add.c:80
#: app/flatpak-builtins-remote-add.c:81 app/flatpak-builtins-remote-add.c:85
#: app/flatpak-builtins-remote-list.c:53
#: app/flatpak-builtins-remote-modify.c:70
#: app/flatpak-builtins-remote-modify.c:85
#: app/flatpak-builtins-remote-modify.c:86
#: app/flatpak-builtins-remote-modify.c:90
msgid "URL"
msgstr "URL"

#: app/flatpak-builtins-build-bundle.c:62
#, fuzzy
msgid "URL for runtime flatpakrepo file"
msgstr "Url pentru fișierul depozit flatpak de executare"

#: app/flatpak-builtins-build-bundle.c:63
msgid "Add GPG key from FILE (- for stdin)"
msgstr "Adaugă o cheie GPG de la FIȘIER (- pentru stdin)"

#: app/flatpak-builtins-build-bundle.c:63 app/flatpak-builtins-build.c:54
#: app/flatpak-builtins-build-export.c:67
#: app/flatpak-builtins-build-update-repo.c:83
#: app/flatpak-builtins-install.c:81 app/flatpak-builtins-remote-add.c:84
#: app/flatpak-builtins-remote-add.c:86 app/flatpak-builtins-remote-modify.c:89
#: app/flatpak-builtins-remote-modify.c:92
msgid "FILE"
msgstr "FIȘIER"

#: app/flatpak-builtins-build-bundle.c:64
msgid "GPG Key ID to sign the OCI image with"
msgstr "ID-ul cheii GPG cu care se semnează imaginea OCI"

#: app/flatpak-builtins-build-bundle.c:64
#: app/flatpak-builtins-build-commit-from.c:68
#: app/flatpak-builtins-build-export.c:68
#: app/flatpak-builtins-build-import-bundle.c:49
#: app/flatpak-builtins-build-sign.c:44
#: app/flatpak-builtins-build-update-repo.c:84
msgid "KEY-ID"
msgstr "ID-CHEIE"

#: app/flatpak-builtins-build-bundle.c:65
#: app/flatpak-builtins-build-commit-from.c:69
#: app/flatpak-builtins-build-export.c:71
#: app/flatpak-builtins-build-import-bundle.c:50
#: app/flatpak-builtins-build-sign.c:45
#: app/flatpak-builtins-build-update-repo.c:85
msgid "GPG Homedir to use when looking for keyrings"
msgstr "Directorul personal GPG de utilizat când se caută după inele de chei"

#: app/flatpak-builtins-build-bundle.c:65
#: app/flatpak-builtins-build-commit-from.c:69
#: app/flatpak-builtins-build-export.c:71
#: app/flatpak-builtins-build-import-bundle.c:50
#: app/flatpak-builtins-build-sign.c:45
#: app/flatpak-builtins-build-update-repo.c:85
msgid "HOMEDIR"
msgstr "DIRPERSONAL"

#: app/flatpak-builtins-build-bundle.c:66
msgid "OSTree commit to create a delta bundle from"
msgstr "Comitul OSTree de la care se creează un pachet delta"

#: app/flatpak-builtins-build-bundle.c:66 app/flatpak-builtins-remote-info.c:55
#: app/flatpak-builtins-update.c:57
msgid "COMMIT"
msgstr "COMIT"

#: app/flatpak-builtins-build-bundle.c:67
msgid "Export oci image instead of flatpak bundle"
msgstr "Exportă imaginea oci în locul pachetului flatpak"

#: app/flatpak-builtins-build-bundle.c:70
msgid "How to compress OCI image layers (default: gzip)"
msgstr ""

#: app/flatpak-builtins-build-bundle.c:634
msgid ""
"LOCATION FILENAME NAME [BRANCH] - Create a single file bundle from a local "
"repository"
msgstr ""
"LOCAȚIE NUMEFIȘIER NUME [RAMURĂ] - Creează un singur pachet de fișier de la "
"un depozit local"

#: app/flatpak-builtins-build-bundle.c:641
msgid "LOCATION, FILENAME and NAME must be specified"
msgstr "LOCAȚIA, NUMEFIȘIER și NUME trebuie specificate"

#: app/flatpak-builtins-build-bundle.c:644
#: app/flatpak-builtins-build-export.c:844
#: app/flatpak-builtins-build-import-bundle.c:136
#: app/flatpak-builtins-build-init.c:217 app/flatpak-builtins-build-sign.c:76
#: app/flatpak-builtins-document-export.c:112
#: app/flatpak-builtins-document-info.c:75
#: app/flatpak-builtins-document-list.c:191
#: app/flatpak-builtins-document-unexport.c:70
#: app/flatpak-builtins-history.c:482 app/flatpak-builtins-info.c:130
#: app/flatpak-builtins-install.c:181 app/flatpak-builtins-install.c:234
#: app/flatpak-builtins-install.c:298 app/flatpak-builtins-list.c:419
#: app/flatpak-builtins-make-current.c:72 app/flatpak-builtins-override.c:73
#: app/flatpak-builtins-permission-list.c:162
#: app/flatpak-builtins-permission-remove.c:132
#: app/flatpak-builtins-remote-add.c:323
#: app/flatpak-builtins-remote-delete.c:68
#: app/flatpak-builtins-remote-list.c:241 app/flatpak-builtins-remote-ls.c:407
msgid "Too many arguments"
msgstr "Prea multe argumente"

#: app/flatpak-builtins-build-bundle.c:659
#: app/flatpak-builtins-build-commit-from.c:338
#: app/flatpak-builtins-build-commit-from.c:351
#: app/flatpak-builtins-build-import-bundle.c:145
#, c-format
msgid "'%s' is not a valid repository"
msgstr "„%s” nu este un depozit valid"

#: app/flatpak-builtins-build-bundle.c:663
#, c-format
msgid "'%s' is not a valid repository: "
msgstr "„%s” nu este un depozit valid: "

#: app/flatpak-builtins-build-bundle.c:674 app/flatpak-builtins-build-sign.c:88
#: common/flatpak-dir.c:14293
#, c-format
msgid "'%s' is not a valid name: %s"
msgstr "„%s” nu este un nume valid: %s"

#: app/flatpak-builtins-build-bundle.c:677
#: app/flatpak-builtins-build-export.c:865 app/flatpak-builtins-build-sign.c:91
#: common/flatpak-dir.c:14299
#, c-format
msgid "'%s' is not a valid branch name: %s"
msgstr "„%s” nu este un nume de ramură valid: %s"

#: app/flatpak-builtins-build-bundle.c:691
#: app/flatpak-builtins-build-import-bundle.c:149
#: app/flatpak-builtins-build-init.c:281
#, c-format
msgid "'%s' is not a valid filename"
msgstr "„%s” nu este un nume de fișier valid"

#: app/flatpak-builtins-build-bundle.c:706
msgid "--oci-layer-compress value must be gzip or zstd"
msgstr ""

#: app/flatpak-builtins-build.c:49
msgid "Use Platform runtime rather than Sdk"
msgstr "Utilizează executarea platformei decât Sdk"

#: app/flatpak-builtins-build.c:50
msgid "Make destination readonly"
msgstr "Face destinația protejată la scriere"

#: app/flatpak-builtins-build.c:51
msgid "Add bind mount"
msgstr "Adaugă montarea de legătură"

#: app/flatpak-builtins-build.c:51
msgid "DEST=SRC"
msgstr "DEST=SRC"

#: app/flatpak-builtins-build.c:52
msgid "Start build in this directory"
msgstr "Începe generarea în acest director"

#: app/flatpak-builtins-build.c:52 app/flatpak-builtins-build.c:53
#: app/flatpak-builtins-build-init.c:64 app/flatpak-builtins-run.c:160
msgid "DIR"
msgstr "DIR"

#: app/flatpak-builtins-build.c:53
msgid "Where to look for custom sdk dir (defaults to 'usr')"
msgstr ""
"Unde să se caute pentru directoare sdk personalizate (implicite pentru „usr”)"

#: app/flatpak-builtins-build.c:54 app/flatpak-builtins-build-export.c:67
msgid "Use alternative file for the metadata"
msgstr "Utilizează fișierul alternativ pentru datele meta"

#: app/flatpak-builtins-build.c:55 app/flatpak-builtins-run.c:177
msgid "Kill processes when the parent process dies"
msgstr "Omoară procesele când procesul superior moare"

#: app/flatpak-builtins-build.c:56
msgid "Export application homedir directory to build"
msgstr "Exportă directorul dirpersonal al aplicației la generare"

#: app/flatpak-builtins-build.c:57 app/flatpak-builtins-run.c:165
msgid "Log session bus calls"
msgstr "Înregistrează apelurile magistralei sesiunii"

#: app/flatpak-builtins-build.c:58 app/flatpak-builtins-run.c:166
msgid "Log system bus calls"
msgstr "Înregistrează apelurile magistralei sistemului"

#: app/flatpak-builtins-build.c:262
msgid "DIRECTORY [COMMAND [ARGUMENT…]] - Build in directory"
msgstr "DIRECTOR [COMANDĂ [ARGUMENT…]] - Generează în director"

#: app/flatpak-builtins-build.c:285 app/flatpak-builtins-build-finish.c:656
msgid "DIRECTORY must be specified"
msgstr "DIRECTOR trebuie specificat"

#: app/flatpak-builtins-build.c:296 app/flatpak-builtins-build-export.c:887
#, c-format
msgid "Build directory %s not initialized, use flatpak build-init"
msgstr ""
"Directorul de generare %s nu este inițializat, utilizați build-init flatpak"

#: app/flatpak-builtins-build.c:315
msgid "metadata invalid, not application or runtime"
msgstr "date meta nevalide, nu este aplicație sau executare"

#: app/flatpak-builtins-build.c:446
#, c-format
msgid "No extension point matching %s in %s"
msgstr "Nu există un punct de extensie care potrivește %s în %s"

#: app/flatpak-builtins-build.c:635
#, c-format
msgid "Missing '=' in bind mount option '%s'"
msgstr "Lipsește „=” în opțiunea de montare de legătură „%s”"

#: app/flatpak-builtins-build.c:679 common/flatpak-run.c:3961
#, c-format
msgid "Unable to start app"
msgstr "Nu se poate porni aplicația"

#: app/flatpak-builtins-build-commit-from.c:58
msgid "Source repo dir"
msgstr "Directorul de depozit al sursei"

#: app/flatpak-builtins-build-commit-from.c:58
msgid "SRC-REPO"
msgstr "DEPOZIT-SRC"

#: app/flatpak-builtins-build-commit-from.c:59
msgid "Source repo ref"
msgstr "Referința depozitului sursă"

#: app/flatpak-builtins-build-commit-from.c:59
msgid "SRC-REF"
msgstr "REF-SRC"

#: app/flatpak-builtins-build-commit-from.c:64
#: app/flatpak-builtins-build-export.c:60
msgid "One line subject"
msgstr "Subiect pe o linie"

#: app/flatpak-builtins-build-commit-from.c:64
#: app/flatpak-builtins-build-export.c:60
msgid "SUBJECT"
msgstr "SUBIECT"

#: app/flatpak-builtins-build-commit-from.c:65
#: app/flatpak-builtins-build-export.c:61
msgid "Full description"
msgstr "Descriere completă"

#: app/flatpak-builtins-build-commit-from.c:65
#: app/flatpak-builtins-build-export.c:61
msgid "BODY"
msgstr "CORP"

#: app/flatpak-builtins-build-commit-from.c:66
#: app/flatpak-builtins-build-export.c:64
#: app/flatpak-builtins-build-import-bundle.c:51
msgid "Update the appstream branch"
msgstr "Actualizează ramura appstream"

#: app/flatpak-builtins-build-commit-from.c:67
#: app/flatpak-builtins-build-export.c:65
#: app/flatpak-builtins-build-import-bundle.c:52
#: app/flatpak-builtins-build-update-repo.c:87
msgid "Don't update the summary"
msgstr "Nu actualiza rezumatul"

#: app/flatpak-builtins-build-commit-from.c:68
#: app/flatpak-builtins-build-export.c:68
#: app/flatpak-builtins-build-import-bundle.c:49
#: app/flatpak-builtins-build-sign.c:44
msgid "GPG Key ID to sign the commit with"
msgstr "ID-ul cheii GPG cu care să se semneze comitul"

#: app/flatpak-builtins-build-commit-from.c:70
#: app/flatpak-builtins-build-export.c:73
msgid "Mark build as end-of-life"
msgstr "Marchează generarea ca sfârșit de fișier"

#: app/flatpak-builtins-build-commit-from.c:70
#: app/flatpak-builtins-build-export.c:73
msgid "REASON"
msgstr "MOTIV"

#: app/flatpak-builtins-build-commit-from.c:71
msgid ""
"Mark refs matching the OLDID prefix as end-of-life, to be replaced with the "
"given NEWID"
msgstr ""
"Marchează referințele care se potrivesc cu prefixul IDVECHI ca sfârșit de "
"fișier, pentru a fi înlocuit cu IDNOU dat"

#: app/flatpak-builtins-build-commit-from.c:71
msgid "OLDID=NEWID"
msgstr "IDVECHI=IDNOU"

#: app/flatpak-builtins-build-commit-from.c:72
#: app/flatpak-builtins-build-export.c:75
msgid "Set type of token needed to install this commit"
msgstr "Stabilește tipul de jeton necesar pentru a instala acest comit"

#: app/flatpak-builtins-build-commit-from.c:72
#: app/flatpak-builtins-build-export.c:75
msgid "VAL"
msgstr "VAL"

#: app/flatpak-builtins-build-commit-from.c:73
msgid "Override the timestamp of the commit (NOW for current time)"
msgstr "Suprascrie datarea comitului (ACUM pentru timpul curent)"

#: app/flatpak-builtins-build-commit-from.c:73
#: app/flatpak-builtins-build-export.c:76
msgid "TIMESTAMP"
msgstr "DATARE"

#: app/flatpak-builtins-build-commit-from.c:75
#: app/flatpak-builtins-build-export.c:80
#: app/flatpak-builtins-build-import-bundle.c:53
#: app/flatpak-builtins-build-update-repo.c:97
#, fuzzy
msgid "Don't generate a summary index"
msgstr "Nu actualiza rezumatul"

#: app/flatpak-builtins-build-commit-from.c:278
msgid "DST-REPO [DST-REF…] - Make a new commit from existing commits"
msgstr ""
"DEPO-DST [REF-DST…] - Alcătuiește un comit nou din comiturile existente"

#: app/flatpak-builtins-build-commit-from.c:285
msgid "DST-REPO must be specified"
msgstr "DEPO-DST trebuie specificat"

#: app/flatpak-builtins-build-commit-from.c:293
msgid ""
"If --src-repo is not specified, exactly one destination ref must be specified"
msgstr ""
"Dacă --src-repo nu este specificat, trebuie specificat exact o ref de "
"destinație"

#: app/flatpak-builtins-build-commit-from.c:296
msgid ""
"If --src-ref is specified, exactly one destination ref must be specified"
msgstr ""
"Dacă --src-ref este specificat, trebuie specificat exact o ref de destinație"

#: app/flatpak-builtins-build-commit-from.c:299
msgid "Either --src-repo or --src-ref must be specified"
msgstr "Ori --src-repo ori --src-ref trebuie specificat"

#: app/flatpak-builtins-build-commit-from.c:315
msgid "Invalid argument format of use  --end-of-life-rebase=OLDID=NEWID"
msgstr ""
"Format de argument nevalid de utilizat  --end-of-life-rebase=IDVECHI=IDNOU"

#: app/flatpak-builtins-build-commit-from.c:321
#: app/flatpak-builtins-build-commit-from.c:324
#, c-format
msgid "Invalid name %s in --end-of-life-rebase"
msgstr "Nume nevalid %s în --end-of-life-rebase"

#: app/flatpak-builtins-build-commit-from.c:333
#: app/flatpak-builtins-build-export.c:1092
#, c-format
msgid "Could not parse '%s'"
msgstr "Nu s-a putut parsa „%s”"

#: app/flatpak-builtins-build-commit-from.c:498
msgid "Can't commit from partial source commit"
msgstr "Nu se poate comite de la comitul de sursă parțial"

#: app/flatpak-builtins-build-commit-from.c:503
#, c-format
msgid "%s: no change\n"
msgstr "%s: nicio schimbare\n"

#: app/flatpak-builtins-build-export.c:62
msgid "Architecture to export for (must be host compatible)"
msgstr ""
"Arhitectura pentru care se exportă (trebuie să fie compatibilă cu gazda)"

#: app/flatpak-builtins-build-export.c:63
msgid "Commit runtime (/usr), not /app"
msgstr "Executarea de comit (/usr), nu /app"

#: app/flatpak-builtins-build-export.c:66
msgid "Use alternative directory for the files"
msgstr "Utilizează directorul alternativ pentru fișiere"

#: app/flatpak-builtins-build-export.c:66
msgid "SUBDIR"
msgstr "SUBDIR"

#: app/flatpak-builtins-build-export.c:69
msgid "Files to exclude"
msgstr "Fișiere de exclus"

#: app/flatpak-builtins-build-export.c:69
#: app/flatpak-builtins-build-export.c:70
#: app/flatpak-builtins-build-update-repo.c:90
msgid "PATTERN"
msgstr "MODEL"

#: app/flatpak-builtins-build-export.c:70
msgid "Excluded files to include"
msgstr "Fișiere excluse de inclus"

#: app/flatpak-builtins-build-export.c:74
msgid "Mark build as end-of-life, to be replaced with the given ID"
msgstr ""
"Marchează generarea ca sfârșit-de-fișier, pentru a fi înlocuit cu ID-ul dat"

#: app/flatpak-builtins-build-export.c:74
#: app/flatpak-builtins-document-list.c:49 app/flatpak-cli-transaction.c:1427
msgid "ID"
msgstr "ID"

#: app/flatpak-builtins-build-export.c:76
msgid "Override the timestamp of the commit"
msgstr "Suprascrie datarea comitului"

#: app/flatpak-builtins-build-export.c:77
#: app/flatpak-builtins-build-update-repo.c:75
#: app/flatpak-builtins-remote-add.c:83 app/flatpak-builtins-remote-list.c:54
#: app/flatpak-builtins-remote-modify.c:88
msgid "Collection ID"
msgstr "ID colecție"

#: app/flatpak-builtins-build-export.c:472
#, c-format
msgid "WARNING: Error running desktop-file-validate: %s\n"
msgstr "AVERTISMENT: Eroare la rularea desktop-file-validate: %s\n"

#: app/flatpak-builtins-build-export.c:480
#, c-format
msgid "WARNING: Error reading from desktop-file-validate: %s\n"
msgstr "AVERTISMENT: Eroare la citirea de la desktop-file-validate: %s\n"

#: app/flatpak-builtins-build-export.c:486
#, c-format
msgid "WARNING: Failed to validate desktop file %s: %s\n"
msgstr "AVERTISTMENT: Nu s-a putut valida fișierul desktop %s: %s\n"

#: app/flatpak-builtins-build-export.c:513
#, c-format
msgid "WARNING: Can't find Exec key in %s: %s\n"
msgstr "AVERTISMENT: Nu se poate găsi cheia exec în %s: %s\n"

#: app/flatpak-builtins-build-export.c:521
#: app/flatpak-builtins-build-export.c:614
#, c-format
msgid "WARNING: Binary not found for Exec line in %s: %s\n"
msgstr "AVERTISMENT: Nu s-a putut găsi binarul pentru linia Exec în %s: %s\n"

#: app/flatpak-builtins-build-export.c:529
#, c-format
msgid "WARNING: Icon not matching app id in %s: %s\n"
msgstr "AVERTISMENT: Iconița nu se potrivește id-ului aplicației în %s: %s\n"

#: app/flatpak-builtins-build-export.c:552
#, c-format
msgid "WARNING: Icon referenced in desktop file but not exported: %s\n"
msgstr ""
"AVERTISMENT: Iconița este referită în fișierul desktop dar nu este "
"exportată: %s\n"

#: app/flatpak-builtins-build-export.c:719
#, c-format
msgid "Invalid uri type %s, only http/https supported"
msgstr "Tip uri nevalid %s, doar http/https suportate"

#: app/flatpak-builtins-build-export.c:737
#, c-format
msgid "Unable to find basename in %s, specify a name explicitly"
msgstr "Nu se poate găsi numele de bază în %s, specificați un nume explicit"

#: app/flatpak-builtins-build-export.c:746
#, c-format
msgid "No slashes allowed in extra data name"
msgstr "Nu sunt permise barele oblice în numele de date extra"

#: app/flatpak-builtins-build-export.c:758
#, c-format
msgid "Invalid format for sha256 checksum: '%s'"
msgstr "Format nevalid pentru suma de control sha256: „%s”"

#: app/flatpak-builtins-build-export.c:768
#, c-format
msgid "Extra data sizes of zero not supported"
msgstr "Dimensiunile de date extra de zero nu sunt suportate"

#: app/flatpak-builtins-build-export.c:830
msgid ""
"LOCATION DIRECTORY [BRANCH] - Create a repository from a build directory"
msgstr ""
"LOCAȚIE DIRECTOR [RAMURĂ] - Creează un depozit de la un director de generare"

#: app/flatpak-builtins-build-export.c:838
msgid "LOCATION and DIRECTORY must be specified"
msgstr "LOCAȚIA și DIRECTORUL trebuie specificate"

#: app/flatpak-builtins-build-export.c:859
#: app/flatpak-builtins-remote-add.c:327
#, c-format
msgid "‘%s’ is not a valid collection ID: %s"
msgstr "„%s” nu este un ID de colecție valid: %s"

#: app/flatpak-builtins-build-export.c:904
#: app/flatpak-builtins-build-finish.c:684
msgid "No name specified in the metadata"
msgstr "Nu există niciun nume specificat în datele meta"

#: app/flatpak-builtins-build-export.c:1166
#, c-format
msgid "Commit: %s\n"
msgstr "Comit: %s\n"

#: app/flatpak-builtins-build-export.c:1167
#, c-format
msgid "Metadata Total: %u\n"
msgstr "Date meta totale: %u\n"

#: app/flatpak-builtins-build-export.c:1168
#, c-format
msgid "Metadata Written: %u\n"
msgstr "Date meta scrise: %u\n"

#: app/flatpak-builtins-build-export.c:1169
#, c-format
msgid "Content Total: %u\n"
msgstr "Total conținut: %u\n"

#: app/flatpak-builtins-build-export.c:1170
#, c-format
msgid "Content Written: %u\n"
msgstr "Conținut scris: %u\n"

#: app/flatpak-builtins-build-export.c:1171
#, c-format
msgid "Content Bytes Written:"
msgstr "Octeți de conținut scriși:"

#: app/flatpak-builtins-build-finish.c:52
msgid "Command to set"
msgstr "Comanda de stabilit"

#: app/flatpak-builtins-build-finish.c:52 app/flatpak-builtins-run.c:159
#: app/flatpak-main.c:209
msgid "COMMAND"
msgstr "COMANDĂ"

#: app/flatpak-builtins-build-finish.c:53
msgid "Flatpak version to require"
msgstr "Versiunea Flatpak de cerut"

#: app/flatpak-builtins-build-finish.c:53
msgid "MAJOR.MINOR.MICRO"
msgstr "MAJOR.MINOR.MICRO"

#: app/flatpak-builtins-build-finish.c:54
msgid "Don't process exports"
msgstr "Nu procesa exporturile"

#: app/flatpak-builtins-build-finish.c:55
msgid "Extra data info"
msgstr "Informații de date extra"

#: app/flatpak-builtins-build-finish.c:56 app/flatpak-builtins-build-init.c:63
msgid "Add extension point info"
msgstr "Adaugă informații de punct de extensie"

#: app/flatpak-builtins-build-finish.c:56 app/flatpak-builtins-build-init.c:63
msgid "NAME=VARIABLE[=VALUE]"
msgstr "NUME=VARIABILĂ[=VALOARE]"

#: app/flatpak-builtins-build-finish.c:57
msgid "Remove extension point info"
msgstr "Elimină informațiile de punct de extensie"

#: app/flatpak-builtins-build-finish.c:57
#: app/flatpak-builtins-build-update-repo.c:79 app/flatpak-builtins-info.c:58
#: app/flatpak-builtins-remote-add.c:88 app/flatpak-builtins-remote-modify.c:94
#: app/flatpak-main.c:182
msgid "NAME"
msgstr "NUME"

#: app/flatpak-builtins-build-finish.c:58
msgid "Set extension priority (only for extensions)"
msgstr "Stabilește prioritatea extensiei (doar pentru extensii)"

#: app/flatpak-builtins-build-finish.c:58
msgid "VALUE"
msgstr "VALOARE"

#: app/flatpak-builtins-build-finish.c:59
msgid "Change the sdk used for the app"
msgstr "Modifică sdk-ul utilizat pentru această aplicație"

#: app/flatpak-builtins-build-finish.c:59
msgid "SDK"
msgstr "SDK"

#: app/flatpak-builtins-build-finish.c:60
msgid "Change the runtime used for the app"
msgstr "Modifică executarea utilizată pentru aplicație"

#: app/flatpak-builtins-build-finish.c:60 app/flatpak-builtins-build-init.c:54
#: app/flatpak-builtins-list.c:53 app/flatpak-builtins-remote-ls.c:58
#: app/flatpak-builtins-run.c:163
msgid "RUNTIME"
msgstr "EXECUTARE"

#: app/flatpak-builtins-build-finish.c:61
msgid "Set generic metadata option"
msgstr "Stabilește opțiunea generică a datelor meta"

#: app/flatpak-builtins-build-finish.c:61
msgid "GROUP=KEY[=VALUE]"
msgstr "GRUP=CHEIE[=VALOARE]"

#: app/flatpak-builtins-build-finish.c:62
msgid "Don't inherit permissions from runtime"
msgstr "Nu moșteni permisiunile de la executare"

#: app/flatpak-builtins-build-finish.c:155
#, c-format
msgid "Not exporting %s, wrong extension\n"
msgstr "Nu se exportă %s, extensie greșită\n"

#: app/flatpak-builtins-build-finish.c:163
#, c-format
msgid "Not exporting %s, non-allowed export filename\n"
msgstr "Nu se exportă %s, nume de fișier de exportare nepermis\n"

#: app/flatpak-builtins-build-finish.c:167
#, c-format
msgid "Exporting %s\n"
msgstr "Se exportă %s\n"

#: app/flatpak-builtins-build-finish.c:440
#, c-format
msgid "More than one executable found\n"
msgstr "Mai mult de un executabil găsit\n"

#: app/flatpak-builtins-build-finish.c:451
#, c-format
msgid "Using %s as command\n"
msgstr "Se utilizează %s ca și comandă\n"

#: app/flatpak-builtins-build-finish.c:456
#, c-format
msgid "No executable found\n"
msgstr "Nu s-a găsit niciun executabil\n"

#: app/flatpak-builtins-build-finish.c:511
#, c-format
msgid "Invalid --require-version argument: %s"
msgstr "Argument --require-version nevalid: %s"

#: app/flatpak-builtins-build-finish.c:543
#, c-format
msgid "Too few elements in --extra-data argument %s"
msgstr "Prea puține elemente în argumentul --extra-data %s"

#: app/flatpak-builtins-build-finish.c:575
#, c-format
msgid ""
"Too few elements in --metadata argument %s, format should be "
"GROUP=KEY[=VALUE]]"
msgstr ""
"Prea puține elemente în argumentul --metadata %s, formatul ar trebui să fie "
"GRUP=CHEIE[=VALOARE]]"

#: app/flatpak-builtins-build-finish.c:597
#: app/flatpak-builtins-build-init.c:458
#, c-format
msgid ""
"Too few elements in --extension argument %s, format should be "
"NAME=VAR[=VALUE]"
msgstr ""
"Prea puține elemente în argumentul --extension %s, formatul ar trebui să fie "
"NUME=VAR[=VALOARE]"

#: app/flatpak-builtins-build-finish.c:603
#: app/flatpak-builtins-build-init.c:461
#, fuzzy, c-format
msgid "Invalid extension name %s"
msgstr "Nume de autentificator %s nevalid"

#: app/flatpak-builtins-build-finish.c:646
msgid "DIRECTORY - Finalize a build directory"
msgstr "DIRECTOR - Finalizează un director de generare"

#: app/flatpak-builtins-build-finish.c:668
#, c-format
msgid "Build directory %s not initialized"
msgstr "Directorul de generare %s nu este inițializat"

#: app/flatpak-builtins-build-finish.c:689
#, c-format
msgid "Build directory %s already finalized"
msgstr "Directorul de generare %s este deja finalizat"

#: app/flatpak-builtins-build-finish.c:702
#, c-format
msgid "Please review the exported files and the metadata\n"
msgstr "Revizuiți fișierele exportate și datele meta\n"

#: app/flatpak-builtins-build-import-bundle.c:47
msgid "Override the ref used for the imported bundle"
msgstr "Suprascrie ref-ul utilizat pentru pachetul importat"

#: app/flatpak-builtins-build-import-bundle.c:47
msgid "REF"
msgstr "REF"

#: app/flatpak-builtins-build-import-bundle.c:48
msgid "Import oci image instead of flatpak bundle"
msgstr "Importă imaginea oci în locul pachetului flatpak"

#: app/flatpak-builtins-build-import-bundle.c:77
#: app/flatpak-builtins-build-import-bundle.c:105
#, c-format
msgid "Importing %s (%s)\n"
msgstr "Se importă %s (%s)\n"

#: app/flatpak-builtins-build-import-bundle.c:126
msgid "LOCATION FILENAME - Import a file bundle into a local repository"
msgstr "LOCAȚIE NUMEFIȘIER - Importă un pachet de fișier într-un depozit local"

#: app/flatpak-builtins-build-import-bundle.c:133
msgid "LOCATION and FILENAME must be specified"
msgstr "LOCAȚIE și NUMEFIȘIER trebuie specificate"

#: app/flatpak-builtins-build-init.c:53 app/flatpak-builtins-info.c:55
#: app/flatpak-builtins-run.c:158
msgid "Arch to use"
msgstr "Arhitectura de utilizat"

#: app/flatpak-builtins-build-init.c:54
msgid "Initialize var from named runtime"
msgstr "Inițializează var de la executarea numită"

#: app/flatpak-builtins-build-init.c:55
msgid "Initialize apps from named app"
msgstr "Inițializează aplicațiile de la aplicația numită"

#: app/flatpak-builtins-build-init.c:55
msgid "APP"
msgstr "APP"

#: app/flatpak-builtins-build-init.c:56
msgid "Specify version for --base"
msgstr "Specifică versiunea pentru --base"

#: app/flatpak-builtins-build-init.c:56 app/flatpak-builtins-run.c:164
msgid "VERSION"
msgstr "VERSIUNE"

#: app/flatpak-builtins-build-init.c:57
msgid "Include this base extension"
msgstr "Include această extensie de bază"

#: app/flatpak-builtins-build-init.c:57 app/flatpak-builtins-build-init.c:62
msgid "EXTENSION"
msgstr "EXTENSIE"

#: app/flatpak-builtins-build-init.c:58
msgid "Extension tag to use if building extension"
msgstr "Eticheta de extensie de utilizat dacă se generează extensia"

#: app/flatpak-builtins-build-init.c:58
msgid "EXTENSION_TAG"
msgstr "ETICHETĂ_EXTENSIE"

#: app/flatpak-builtins-build-init.c:59
msgid "Initialize /usr with a writable copy of the sdk"
msgstr "Inițializează /usr cu o copie inscriptibilă a sdk-ului"

#: app/flatpak-builtins-build-init.c:60
msgid "Specify the build type (app, runtime, extension)"
msgstr "Specifică tipul de generare (aplicație, executare, extensie)"

#: app/flatpak-builtins-build-init.c:60
msgid "TYPE"
msgstr "TIP"

#: app/flatpak-builtins-build-init.c:61
msgid "Add a tag"
msgstr "Adaugă o etichetă"

#: app/flatpak-builtins-build-init.c:61
msgid "TAG"
msgstr "TAG"

#: app/flatpak-builtins-build-init.c:62
msgid "Include this sdk extension in /usr"
msgstr "Include această extensie sdk în /usr"

#: app/flatpak-builtins-build-init.c:64
msgid "Where to store sdk (defaults to 'usr')"
msgstr "Unde să se stocheze sdk-ul (implicit la „usr”)"

#: app/flatpak-builtins-build-init.c:65
msgid "Re-initialize the sdk/var"
msgstr "Reinițializează sdk/var"

#: app/flatpak-builtins-build-init.c:118
#, fuzzy, c-format
msgid "Requested extension %s/%s/%s is only partially installed"
msgstr "Extensia cerută %s este doar parțial instalată"

#: app/flatpak-builtins-build-init.c:147
#, fuzzy, c-format
msgid "Requested extension %s/%s/%s not installed"
msgstr "Extensia cerută %s nu este instalată"

#: app/flatpak-builtins-build-init.c:207
msgid ""
"DIRECTORY APPNAME SDK RUNTIME [BRANCH] - Initialize a directory for building"
msgstr ""
"DIRECTOR NUMEAPLICAȚIE SDK EXECUTARE [RAMURĂ] - Inițializează un director "
"pentru generare"

#: app/flatpak-builtins-build-init.c:214
msgid "RUNTIME must be specified"
msgstr "EXECUTARE trebuie specificat"

#: app/flatpak-builtins-build-init.c:235
#, c-format
msgid "'%s' is not a valid build type name, use app, runtime or extension"
msgstr ""
"„%s” nu este un nume de tip de executare valid, utilizați aplicație, "
"executare sau extensie"

#: app/flatpak-builtins-build-init.c:241 app/flatpak-builtins-override.c:79
#, c-format
msgid "'%s' is not a valid application name: %s"
msgstr "„%s nu este un nume de aplicație valid: %s"

#: app/flatpak-builtins-build-init.c:295
#, c-format
msgid "Build directory %s already initialized"
msgstr "Directorul de generare %s este deja inițializat"

#: app/flatpak-builtins-build-sign.c:42 app/flatpak-builtins-install.c:67
#: app/flatpak-builtins-remote-info.c:54
msgid "Arch to install for"
msgstr "Arhitectura pentru care se instalează"

#: app/flatpak-builtins-build-sign.c:43 app/flatpak-builtins-create-usb.c:48
#: app/flatpak-builtins-install.c:74 app/flatpak-builtins-remote-info.c:56
#: app/flatpak-builtins-uninstall.c:58 app/flatpak-builtins-update.c:64
msgid "Look for runtime with the specified name"
msgstr "Caută după o executare cu numele specificat"

#: app/flatpak-builtins-build-sign.c:66
msgid "LOCATION [ID [BRANCH]] - Sign an application or runtime"
msgstr "LOCAȚIE [ID [RAMURĂ]] - Semnează o aplicație sau executare"

#: app/flatpak-builtins-build-sign.c:73
#: app/flatpak-builtins-build-update-repo.c:499
#: app/flatpak-builtins-remote-add.c:320 app/flatpak-builtins-repo.c:739
msgid "LOCATION must be specified"
msgstr "LOCAȚIA trebuie specificată"

#: app/flatpak-builtins-build-sign.c:94
msgid "No gpg key ids specified"
msgstr "Nu este specificat niciun id de cheie gpg"

#: app/flatpak-builtins-build-update-repo.c:68
msgid "Redirect this repo to a new URL"
msgstr "Redirectează acest depozit la un URL nou"

#: app/flatpak-builtins-build-update-repo.c:69
msgid "A nice name to use for this repository"
msgstr "Un nume drăguț de utilizat pentru acest depozit"

#: app/flatpak-builtins-build-update-repo.c:69
#: app/flatpak-builtins-remote-add.c:77 app/flatpak-builtins-remote-modify.c:82
msgid "TITLE"
msgstr "TITLU"

#: app/flatpak-builtins-build-update-repo.c:70
msgid "A one-line comment for this repository"
msgstr "Un comentariu de o linie pentru acest depozit"

#: app/flatpak-builtins-build-update-repo.c:70
#: app/flatpak-builtins-remote-add.c:78 app/flatpak-builtins-remote-modify.c:83
msgid "COMMENT"
msgstr "COMENTARIU"

#: app/flatpak-builtins-build-update-repo.c:71
msgid "A full-paragraph description for this repository"
msgstr "O descriere de un paragraf complet pentru acest depozit"

#: app/flatpak-builtins-build-update-repo.c:71
#: app/flatpak-builtins-remote-add.c:79 app/flatpak-builtins-remote-modify.c:84
msgid "DESCRIPTION"
msgstr "DESCRIERE"

#: app/flatpak-builtins-build-update-repo.c:72
msgid "URL for a website for this repository"
msgstr "URL pentru o pagină web pentru acest depozit"

#: app/flatpak-builtins-build-update-repo.c:73
msgid "URL for an icon for this repository"
msgstr "URL pentru o iconiță pentru acest depozit"

#: app/flatpak-builtins-build-update-repo.c:74
msgid "Default branch to use for this repository"
msgstr "Ramura implicită de utilizat pentru acest depozit"

#: app/flatpak-builtins-build-update-repo.c:74
#: app/flatpak-builtins-remote-add.c:82 app/flatpak-builtins-remote-modify.c:87
#: app/flatpak-builtins-repo.c:713 app/flatpak-builtins-repo.c:714
#: app/flatpak-builtins-run.c:161
msgid "BRANCH"
msgstr "RAMURĂ"

#: app/flatpak-builtins-build-update-repo.c:75
#: app/flatpak-builtins-remote-add.c:83 app/flatpak-builtins-remote-modify.c:88
msgid "COLLECTION-ID"
msgstr "ID-COLECȚIE"

#. Translators: A sideload is when you install from a local USB drive rather than the Internet.
#: app/flatpak-builtins-build-update-repo.c:77
msgid ""
"Permanently deploy collection ID to client remote configurations, only for "
"sideload support"
msgstr ""
"Implementați permanent ID-ul de colecție la configurările de la distanță ale "
"clientului, doar pentru suport de încărcare laterală"

#: app/flatpak-builtins-build-update-repo.c:78
msgid "Permanently deploy collection ID to client remote configurations"
msgstr ""
"Implementați permanent ID-ul colecției la configurările de la distanță ale "
"clientului"

#: app/flatpak-builtins-build-update-repo.c:79
msgid "Name of authenticator for this repository"
msgstr "Numele autentificatorului pentru acest depozit"

#: app/flatpak-builtins-build-update-repo.c:80
msgid "Autoinstall authenticator for this repository"
msgstr "Instalează automat autentificatorul pentru acest depozit"

#: app/flatpak-builtins-build-update-repo.c:81
msgid "Don't autoinstall authenticator for this repository"
msgstr "Nu instala automat autentificatorul pentru acest depozit"

#: app/flatpak-builtins-build-update-repo.c:82
#: app/flatpak-builtins-remote-add.c:89
msgid "Authenticator option"
msgstr "Opțiune autentificator"

#: app/flatpak-builtins-build-update-repo.c:82
#: app/flatpak-builtins-remote-add.c:89 app/flatpak-builtins-remote-modify.c:95
msgid "KEY=VALUE"
msgstr "CHEIE=VALOARE"

#: app/flatpak-builtins-build-update-repo.c:83
msgid "Import new default GPG public key from FILE"
msgstr "Importă cheia publică GPG implicită nouă de la FIȘIER"

#: app/flatpak-builtins-build-update-repo.c:84
msgid "GPG Key ID to sign the summary with"
msgstr "ID-ul cheii GPG cu care să se semneze rezumatul"

#: app/flatpak-builtins-build-update-repo.c:86
msgid "Generate delta files"
msgstr "Generează fișierele delta"

#: app/flatpak-builtins-build-update-repo.c:88
msgid "Don't update the appstream branch"
msgstr "Nu actualiza ramura appstream"

#: app/flatpak-builtins-build-update-repo.c:89
msgid "Max parallel jobs when creating deltas (default: NUMCPUs)"
msgstr ""
"Numărul maxim de sarcini paralele atunci când se creează deltele (implicit: "
"NUMCPU-uri)"

#: app/flatpak-builtins-build-update-repo.c:89
msgid "NUM-JOBS"
msgstr "NUMĂR-SARCINI"

#: app/flatpak-builtins-build-update-repo.c:90
msgid "Don't create deltas matching refs"
msgstr "Nu crea delte care se potrivesc cu ref-uri"

#: app/flatpak-builtins-build-update-repo.c:91
msgid "Prune unused objects"
msgstr "Elimină obiectele neutilizate"

#: app/flatpak-builtins-build-update-repo.c:92
msgid "Prune but don't actually remove anything"
msgstr ""

#: app/flatpak-builtins-build-update-repo.c:93
msgid "Only traverse DEPTH parents for each commit (default: -1=infinite)"
msgstr ""
"Traversează doar superiorii în ADÂNCIME pentru fiecare comit (implicit "
"-1=infinit)"

#: app/flatpak-builtins-build-update-repo.c:93
msgid "DEPTH"
msgstr "ADÂNCIME"

#: app/flatpak-builtins-build-update-repo.c:223
#, c-format
msgid "Generating delta: %s (%.10s)\n"
msgstr "Se generează delta: %s (%.10s)\n"

#: app/flatpak-builtins-build-update-repo.c:225
#, c-format
msgid "Generating delta: %s (%.10s-%.10s)\n"
msgstr "Se generează delta: %s (%.10s-%.10s)\n"

#: app/flatpak-builtins-build-update-repo.c:233
#, c-format
msgid "Failed to generate delta %s (%.10s): "
msgstr "Nu s-a putut genera delta %s (%.10s): "

#: app/flatpak-builtins-build-update-repo.c:236
#, c-format
msgid "Failed to generate delta %s (%.10s-%.10s): "
msgstr "Nu s-a putut genera delta %s (%.10s-%.10s): "

#: app/flatpak-builtins-build-update-repo.c:492
msgid "LOCATION - Update repository metadata"
msgstr "LOCAȚIE - Actualizează datele meta ale depozitului"

#: app/flatpak-builtins-build-update-repo.c:609
#, c-format
msgid "Updating appstream branch\n"
msgstr "Se actualizează ramura appstream\n"

#: app/flatpak-builtins-build-update-repo.c:638
#, c-format
msgid "Updating summary\n"
msgstr "Se actualizează rezumatul\n"

#: app/flatpak-builtins-build-update-repo.c:664
#, c-format
msgid "Total objects: %u\n"
msgstr "Obiecte totale: %u\n"

#: app/flatpak-builtins-build-update-repo.c:666
#, c-format
msgid "No unreachable objects\n"
msgstr "Nu sunt obiecte de neatins\n"

#: app/flatpak-builtins-build-update-repo.c:668
#, c-format
msgid "Deleted %u objects, %s freed\n"
msgstr "S-au șters %u obiecte, s-a eliberat %s\n"

#: app/flatpak-builtins-config.c:41
msgid "List configuration keys and values"
msgstr "Listează cheile și valorile de configurare"

#: app/flatpak-builtins-config.c:42
msgid "Get configuration for KEY"
msgstr "Obține configurarea pentru CHEIA"

#: app/flatpak-builtins-config.c:43
msgid "Set configuration for KEY to VALUE"
msgstr "Stabilește configurarea pentru CHEIA la VALOAREA"

#: app/flatpak-builtins-config.c:44
msgid "Unset configuration for KEY"
msgstr "Deselectează configurarea pentru CHEIA"

#: app/flatpak-builtins-config.c:149
#, c-format
msgid "'%s' does not look like a language/locale code"
msgstr "„%s” nu arată ca un cod de limbă/localizare"

#: app/flatpak-builtins-config.c:172
#, c-format
msgid "'%s' does not look like a language code"
msgstr "„%s” nu arată ca un cod de limbă"

#: app/flatpak-builtins-config.c:190
#, fuzzy, c-format
msgid "'%s' is not a valid value (use 'true' or 'false')"
msgstr "„%s” nu este un depozit valid: "

#: app/flatpak-builtins-config.c:262
#, c-format
msgid "Unknown configure key '%s'"
msgstr "Cheie de configurare necunoscută „%s”"

#: app/flatpak-builtins-config.c:284
msgid "Too many arguments for --list"
msgstr "Prea multe argumente pentru --list"

#: app/flatpak-builtins-config.c:314 app/flatpak-builtins-config.c:362
msgid "You must specify KEY"
msgstr "Trebuie să specificați CHEIA"

#: app/flatpak-builtins-config.c:316
msgid "Too many arguments for --get"
msgstr "Prea multe argumente pentru --get"

#: app/flatpak-builtins-config.c:338
msgid "You must specify KEY and VALUE"
msgstr "Trebuie să specificați CHEIA și VALOAREA"

#: app/flatpak-builtins-config.c:340
msgid "Too many arguments for --set"
msgstr "Prea multe argumente pentru --set"

#: app/flatpak-builtins-config.c:364
msgid "Too many arguments for --unset"
msgstr "Prea multe argumente pentru --unset"

#: app/flatpak-builtins-config.c:383
msgid "[KEY [VALUE]] - Manage configuration"
msgstr "[CHEIE [VALOARE]] - Gestionează configurarea"

#: app/flatpak-builtins-config.c:394
msgid "Can only use one of --list, --get, --set or --unset"
msgstr "Se poate utiliza doar una dintre --list, --get, --set sau --unset"

#: app/flatpak-builtins-config.c:408
msgid "Must specify one of --list, --get, --set or --unset"
msgstr "Trebuie să specificați una dintre --list, --get, --set sau --unset"

#: app/flatpak-builtins-create-usb.c:45 app/flatpak-builtins-install.c:75
#: app/flatpak-builtins-remote-info.c:57 app/flatpak-builtins-uninstall.c:59
#: app/flatpak-builtins-update.c:65
msgid "Look for app with the specified name"
msgstr "Caută după aplicația cu numele specificat"

#: app/flatpak-builtins-create-usb.c:46
msgid "Arch to copy"
msgstr "Arhitectura de copiat"

#: app/flatpak-builtins-create-usb.c:47
msgid "DEST"
msgstr "DEST"

#: app/flatpak-builtins-create-usb.c:49
msgid "Allow partial commits in the created repo"
msgstr "Permite comiturile parțiale în depozitul creat"

#: app/flatpak-builtins-create-usb.c:125 app/flatpak-builtins-create-usb.c:165
#, c-format
msgid ""
"Warning: Related ref ‘%s’ is partially installed. Use --allow-partial to "
"suppress this message.\n"
msgstr ""
"Avertisment: Ref-ul aferent „%s” este instalat parțial. Utilizați --allow-"
"partial pentru a suprima acest mesaj.\n"

#: app/flatpak-builtins-create-usb.c:158
#, c-format
msgid "Warning: Omitting related ref ‘%s’ because it is not installed.\n"
msgstr ""
"Avertisment: Se omite ref-ului asociat „%s” pentru că nu este instalat.\n"

#: app/flatpak-builtins-create-usb.c:175
#, c-format
msgid ""
"Warning: Omitting related ref ‘%s’ because its remote ‘%s’ does not have a "
"collection ID set.\n"
msgstr ""
"Avertisment: Se omite ref-ul asociat „%s” pentru că „%s” de la distanță nu "
"are stabilit un ID de colecție.\n"

#: app/flatpak-builtins-create-usb.c:187
#, fuzzy, c-format
msgid "Warning: Omitting related ref ‘%s’ because it's extra-data.\n"
msgstr ""
"Avertisment: Se omite ref-ului asociat „%s” pentru că nu este instalat.\n"

#: app/flatpak-builtins-create-usb.c:262 app/flatpak-builtins-create-usb.c:637
#, c-format
msgid ""
"Remote ‘%s’ does not have a collection ID set, which is required for P2P "
"distribution of ‘%s’."
msgstr ""
"„%s” de la distanță nu are stabilit un ID de colecție, care este necesar "
"pentru distribuția P2P a „%s”."

#: app/flatpak-builtins-create-usb.c:272
#, fuzzy, c-format
msgid "Warning: Omitting ref ‘%s’ (runtime of ‘%s’) because it's extra-data.\n"
msgstr ""
"Avertisment: Se omite ref-ului asociat „%s” pentru că nu este instalat.\n"

#: app/flatpak-builtins-create-usb.c:484
msgid "MOUNT-PATH [REF…] - Copy apps or runtimes onto removable media"
msgstr ""
"CALE-MONTARE [REF…] - Copiază aplicațiile sau executările pe media detașabile"

#: app/flatpak-builtins-create-usb.c:493
msgid "MOUNT-PATH and REF must be specified"
msgstr "CALE-MONTARE și REF trebuie specificate"

#: app/flatpak-builtins-create-usb.c:607
#, c-format
msgid "Ref ‘%s’ found in multiple installations: %s. You must specify one."
msgstr ""
"Ref-ul „%s” a fost găsit în instalări multiple: %s. Trebuie să specificați "
"una."

#: app/flatpak-builtins-create-usb.c:620
#, c-format
msgid "Refs must all be in the same installation (found in %s and %s)."
msgstr ""
"Ref-urile trebuie toate să fie în aceeași instalare (a fost găsit în %s și "
"%s)."

#: app/flatpak-builtins-create-usb.c:670
#, c-format
msgid ""
"Warning: Ref ‘%s’ is partially installed. Use --allow-partial to suppress "
"this message.\n"
msgstr ""
"Avertisment: Ref-ul „%s” este instalat parțial. Utilizați --allow-partial "
"pentru a suprima acest mesaj.\n"

#: app/flatpak-builtins-create-usb.c:681
#, c-format
msgid "Installed ref ‘%s’ is extra-data, and cannot be distributed offline"
msgstr ""

#: app/flatpak-builtins-create-usb.c:721
#, c-format
msgid "Warning: Couldn't update repo metadata for remote ‘%s’: %s\n"
msgstr ""
"Avertisment: Nu s-au putut actualiza datele meta ale depozitului pentru „%s” "
"de la distanță: %s\n"

#: app/flatpak-builtins-create-usb.c:751
#, c-format
msgid "Warning: Couldn't update appstream data for remote ‘%s’ arch ‘%s’: %s\n"
msgstr ""
"Avertisment: Nu s-au putut actualiza datele appstream pentru „%s” de la "
"distanță, arhitectura „%s”: %s\n"

#. Print a warning if both appstream and appstream2 are missing
#: app/flatpak-builtins-create-usb.c:784
#, c-format
msgid ""
"Warning: Couldn't find appstream data for remote ‘%s’ arch ‘%s’: %s; %s\n"
msgstr ""
"Avertisment: Nu s-au putut găsi datele appstream pentru „%s” de la distanță, "
"arhitectura „%s”: %s; %s\n"

#. Appstream2 is only for efficiency, so just print a debug message
#: app/flatpak-builtins-create-usb.c:790
#, c-format
msgid "Couldn't find appstream2 data for remote ‘%s’ arch ‘%s’: %s\n"
msgstr ""
"Nu s-au putut găsi datele appstream2 pentru „%s” de la distanță, arhitectura "
"„%s”: %s\n"

#: app/flatpak-builtins-document-export.c:62
msgid "Create a unique document reference"
msgstr "Creează o referință de document unică"

#: app/flatpak-builtins-document-export.c:63
msgid "Make the document transient for the current session"
msgstr "Faceți documentul tranzitoriu pentru sesiunea corectă"

#: app/flatpak-builtins-document-export.c:64
msgid "Don't require the file to exist already"
msgstr "Nu necesita ca fișierul să existe deja"

#: app/flatpak-builtins-document-export.c:65
msgid "Give the app read permissions"
msgstr "Dați aplicației permisiuni de citire"

#: app/flatpak-builtins-document-export.c:66
msgid "Give the app write permissions"
msgstr "Dați aplicației permisiuni de scriere"

#: app/flatpak-builtins-document-export.c:67
msgid "Give the app delete permissions"
msgstr "Dați aplicației permisiuni de ștergere"

#: app/flatpak-builtins-document-export.c:68
msgid "Give the app permissions to grant further permissions"
msgstr "Dați aplicației permisiuni pentru a acord permisiuni suplimentare"

#: app/flatpak-builtins-document-export.c:69
msgid "Revoke read permissions of the app"
msgstr "Revocă permisiunile de citire ale aplicației"

#: app/flatpak-builtins-document-export.c:70
msgid "Revoke write permissions of the app"
msgstr "Revocă permisiunile de scriere ale aplicației"

#: app/flatpak-builtins-document-export.c:71
msgid "Revoke delete permissions of the app"
msgstr "Revocă permisiunile de ștergere ale aplicației"

#: app/flatpak-builtins-document-export.c:72
msgid "Revoke the permission to grant further permissions"
msgstr "Revocă permisiunile pentru a acorda permisiuni suplimentare"

#: app/flatpak-builtins-document-export.c:73
msgid "Add permissions for this app"
msgstr "Adaugă permisiuni pentru această aplicație"

#: app/flatpak-builtins-document-export.c:73
msgid "APPID"
msgstr "APPID"

#: app/flatpak-builtins-document-export.c:100
msgid "FILE - Export a file to apps"
msgstr "FIȘIER - Exportă un fișier la aplicații"

#: app/flatpak-builtins-document-export.c:109
#: app/flatpak-builtins-document-info.c:72
#: app/flatpak-builtins-document-unexport.c:67
msgid "FILE must be specified"
msgstr "FIȘIERUL trebuie specificat"

#: app/flatpak-builtins-document-info.c:63
msgid "FILE - Get information about an exported file"
msgstr "FIȘIER - Obțineți informații despre un fișier exportat"

#: app/flatpak-builtins-document-info.c:100
#: app/flatpak-builtins-document-unexport.c:94
#, c-format
msgid "Not exported\n"
msgstr "Nu este exportat\n"

#: app/flatpak-builtins-document-list.c:43 app/flatpak-builtins-history.c:53
#: app/flatpak-builtins-list.c:54 app/flatpak-builtins-ps.c:43
#: app/flatpak-builtins-remote-list.c:45 app/flatpak-builtins-remote-ls.c:59
#: app/flatpak-builtins-search.c:38
msgid "What information to show"
msgstr "Ce informații să fie arătate"

#: app/flatpak-builtins-document-list.c:43 app/flatpak-builtins-history.c:53
#: app/flatpak-builtins-list.c:54 app/flatpak-builtins-ps.c:43
#: app/flatpak-builtins-remote-list.c:45 app/flatpak-builtins-remote-ls.c:59
#: app/flatpak-builtins-search.c:38
msgid "FIELD,…"
msgstr "CÂMP,…"

#: app/flatpak-builtins-document-list.c:44 app/flatpak-builtins-history.c:54
#: app/flatpak-builtins-list.c:52 app/flatpak-builtins-permission-list.c:43
#: app/flatpak-builtins-permission-show.c:43 app/flatpak-builtins-ps.c:44
#: app/flatpak-builtins-remote-list.c:46 app/flatpak-builtins-remote-ls.c:63
#: app/flatpak-builtins-repo.c:717 app/flatpak-builtins-search.c:39
#, fuzzy
msgid "Show output in JSON format"
msgstr "Arată informațiile suplimentare"

#: app/flatpak-builtins-document-list.c:49
msgid "Show the document ID"
msgstr "Arată ID-ul documentului"

#: app/flatpak-builtins-document-list.c:50
msgid "Path"
msgstr "Cale"

#: app/flatpak-builtins-document-list.c:50
#: app/flatpak-builtins-document-list.c:51
msgid "Show the document path"
msgstr "Arată calea documentului"

#: app/flatpak-builtins-document-list.c:51 app/flatpak-builtins-list.c:66
#: app/flatpak-builtins-remote-ls.c:74
msgid "Origin"
msgstr "Origine"

#: app/flatpak-builtins-document-list.c:52 app/flatpak-builtins-history.c:62
#: app/flatpak-builtins-ps.c:52
msgid "Application"
msgstr "Aplicație"

#: app/flatpak-builtins-document-list.c:52
msgid "Show applications with permission"
msgstr "Arată aplicațiile cu permisiune"

#: app/flatpak-builtins-document-list.c:53
#: app/flatpak-builtins-permission-list.c:182
#: app/flatpak-builtins-permission-show.c:145
msgid "Permissions"
msgstr "Permisiuni"

#: app/flatpak-builtins-document-list.c:53
msgid "Show permissions for applications"
msgstr "Arată permisiunile pentru aplicații"

#: app/flatpak-builtins-document-list.c:161
#, fuzzy, c-format
msgid "No documents found\n"
msgstr "Nu s-au găsit potriviri"

#: app/flatpak-builtins-document-list.c:180
msgid "[APPID] - List exported files"
msgstr "[IDAPLICAȚIE] - Listează fișierele exportate"

#: app/flatpak-builtins-document-unexport.c:43
#, fuzzy
msgid "Specify the document ID"
msgstr "Arată ID-ul documentului"

#: app/flatpak-builtins-document-unexport.c:58
msgid "FILE - Unexport a file to apps"
msgstr "FILE - Nu mai exportă un fișier la aplicații"

#: app/flatpak-builtins-enter.c:88
msgid "INSTANCE COMMAND [ARGUMENT…] - Run a command inside a running sandbox"
msgstr ""
"INSTANȚĂ COMANDĂ [ARGUMENT…] - Rulează o comandă înăuntrul unui sandbox care "
"rulează"

#: app/flatpak-builtins-enter.c:111
msgid "INSTANCE and COMMAND must be specified"
msgstr "INSTANȚA și COMANDA trebuie specificate"

#: app/flatpak-builtins-enter.c:138
#, c-format
msgid "%s is neither a pid nor an application or instance ID"
msgstr "%s nu este nici un pid nici o aplicație sau un ID de instanță"

#: app/flatpak-builtins-enter.c:144
msgid "entering not supported (need unprivileged user namespaces, or sudo -E)"
msgstr ""
"introducerea nu este suportată (este nevoie de nume de spații ale "
"utilizatorului neprivilegiate, sau sudo -E)"

#: app/flatpak-builtins-enter.c:145
#, c-format
msgid "No such pid %s"
msgstr "Nu există niciun pid %s"

#: app/flatpak-builtins-enter.c:158
msgid "Can't read cwd"
msgstr "Nu se poate citi cwd"

#: app/flatpak-builtins-enter.c:163
msgid "Can't read root"
msgstr "Nu se poate citi root"

#: app/flatpak-builtins-enter.c:191
#, c-format
msgid "Invalid %s namespace for pid %d"
msgstr "Spațiu de nume nevalid %s pentru pid-ul %d"

#: app/flatpak-builtins-enter.c:202
#, c-format
msgid "Invalid %s namespace for self"
msgstr "Spațiu de nume nevalid %s pentru self"

#: app/flatpak-builtins-enter.c:216
#, c-format
msgid "Can't open %s namespace: %s"
msgstr "Nu se poate deschide spațiul de nume %s: %s"

#: app/flatpak-builtins-enter.c:226
msgid "entering not supported (need unprivileged user namespaces)"
msgstr ""
"introducerea nu este suportată (este nevoie de spații de nume de utilizator "
"neprivilegiate)"

#: app/flatpak-builtins-enter.c:227
#, c-format
msgid "Can't enter %s namespace: %s"
msgstr "Nu se poate introduce spațiul de nume %s: %s"

#: app/flatpak-builtins-enter.c:234
msgid "Can't chdir"
msgstr "Nu se poate chdir"

#: app/flatpak-builtins-enter.c:237
msgid "Can't chroot"
msgstr "Nu se poate chroot"

#: app/flatpak-builtins-enter.c:240
msgid "Can't switch gid"
msgstr "Nu se poate interschimba gid-ul"

#: app/flatpak-builtins-enter.c:243
msgid "Can't switch uid"
msgstr "Nu se poate interschimba uid-ul"

#: app/flatpak-builtins-history.c:50
msgid "Only show changes after TIME"
msgstr "Arată modificările doar după TIMP"

#: app/flatpak-builtins-history.c:50 app/flatpak-builtins-history.c:51
msgid "TIME"
msgstr "TIMP"

#: app/flatpak-builtins-history.c:51
msgid "Only show changes before TIME"
msgstr "Arată modificările doar înainte de TIMP"

#: app/flatpak-builtins-history.c:52
msgid "Show newest entries first"
msgstr "Arată intrările noi mai întâi"

#: app/flatpak-builtins-history.c:59
msgid "Time"
msgstr "Timp"

#: app/flatpak-builtins-history.c:59
msgid "Show when the change happened"
msgstr "Arată când s-a întâmplat modificarea"

#: app/flatpak-builtins-history.c:60
msgid "Change"
msgstr "Schimbă"

#: app/flatpak-builtins-history.c:60
msgid "Show the kind of change"
msgstr "Arată tipul de modificare"

#: app/flatpak-builtins-history.c:61 app/flatpak-builtins-list.c:68
#: app/flatpak-builtins-remote-ls.c:75 app/flatpak-builtins-repo.c:335
msgid "Ref"
msgstr "Ref"

#: app/flatpak-builtins-history.c:61 app/flatpak-builtins-list.c:68
#: app/flatpak-builtins-remote-ls.c:75
msgid "Show the ref"
msgstr "Arată ref-ul"

#: app/flatpak-builtins-history.c:62
msgid "Show the application/runtime ID"
msgstr "Arată ID-urile de aplicație/executare"

#: app/flatpak-builtins-history.c:63 app/flatpak-builtins-list.c:64
#: app/flatpak-builtins-ps.c:53 app/flatpak-builtins-remote-ls.c:73
#: app/flatpak-cli-transaction.c:1435
msgid "Arch"
msgstr "Arhitectură"

#: app/flatpak-builtins-history.c:63 app/flatpak-builtins-list.c:64
#: app/flatpak-builtins-ps.c:53 app/flatpak-builtins-remote-ls.c:73
msgid "Show the architecture"
msgstr "Arată arhitectura"

#: app/flatpak-builtins-history.c:64 app/flatpak-builtins-list.c:63
#: app/flatpak-builtins-ps.c:54 app/flatpak-builtins-remote-ls.c:72
#: app/flatpak-builtins-search.c:48 app/flatpak-cli-transaction.c:1438
msgid "Branch"
msgstr "Ramură"

#: app/flatpak-builtins-history.c:64 app/flatpak-builtins-list.c:63
#: app/flatpak-builtins-remote-ls.c:72
msgid "Show the branch"
msgstr "Arată ramura"

#: app/flatpak-builtins-history.c:65 app/flatpak-builtins-list.c:67
msgid "Installation"
msgstr "Loc de instalare"

#: app/flatpak-builtins-history.c:65
msgid "Show the affected installation"
msgstr "Arată instalarea afectată"

#: app/flatpak-builtins-history.c:66 app/flatpak-cli-transaction.c:1452
msgid "Remote"
msgstr "Locație la distanță"

#: app/flatpak-builtins-history.c:66
msgid "Show the remote"
msgstr "Arată depozitul de la distanță"

#: app/flatpak-builtins-history.c:67 app/flatpak-builtins-ps.c:55
#: app/flatpak-builtins-remote-ls.c:76
msgid "Commit"
msgstr "Comite"

#: app/flatpak-builtins-history.c:67
msgid "Show the current commit"
msgstr "Arată comitul curent"

#: app/flatpak-builtins-history.c:68
msgid "Old Commit"
msgstr "Comitul vechi"

#: app/flatpak-builtins-history.c:68
msgid "Show the previous commit"
msgstr "Arată comitul anterior"

#: app/flatpak-builtins-history.c:69
msgid "Show the remote URL"
msgstr "Arată URL-ul de la distanță"

#: app/flatpak-builtins-history.c:70 app/flatpak-cli-transaction.c:700
msgid "User"
msgstr "Utilizator"

#: app/flatpak-builtins-history.c:70
msgid "Show the user doing the change"
msgstr "Arată utilizatorul care face modificarea"

#: app/flatpak-builtins-history.c:71
msgid "Tool"
msgstr "Unealtă"

#: app/flatpak-builtins-history.c:71
msgid "Show the tool that was used"
msgstr "Arată unealta care a fost utilizată"

#: app/flatpak-builtins-history.c:72 app/flatpak-builtins-list.c:62
#: app/flatpak-builtins-remote-ls.c:71 app/flatpak-builtins-search.c:47
msgid "Version"
msgstr "Versiune"

#: app/flatpak-builtins-history.c:72
msgid "Show the Flatpak version"
msgstr "Arată versiunea Flatpak"

#: app/flatpak-builtins-history.c:91
#, c-format
msgid "Failed to get journal data (%s): %s"
msgstr "Nu s-au putut obține datele jurnalului (%s): %s"

#: app/flatpak-builtins-history.c:146
#, c-format
msgid "Failed to open journal: %s"
msgstr "Nu s-a putut deschide jurnalul: %s"

#: app/flatpak-builtins-history.c:153
#, c-format
msgid "Failed to add match to journal: %s"
msgstr "Nu s-a putut adăuga potrivirea la jurnal: %s"

#: app/flatpak-builtins-history.c:471
msgid " - Show history"
msgstr " - Arată istoricul"

#: app/flatpak-builtins-history.c:490
#, c-format
msgid "Failed to parse the --since option"
msgstr "Nu s-a putut parsa opțiunea --since"

#: app/flatpak-builtins-history.c:501
#, c-format
msgid "Failed to parse the --until option"
msgstr "Nu s-a putut parsa opțiunea --until"

#: app/flatpak-builtins-info.c:56
msgid "Show user installations"
msgstr "Arată instalările utilizatorului"

#: app/flatpak-builtins-info.c:57
msgid "Show system-wide installations"
msgstr "Arată instalările la nivelul întregului sistem"

#: app/flatpak-builtins-info.c:58
msgid "Show specific system-wide installations"
msgstr "Arată instalări specifice la nivelul întregului sistem"

#: app/flatpak-builtins-info.c:59 app/flatpak-builtins-remote-info.c:59
msgid "Show ref"
msgstr "Arată ref-ul"

#: app/flatpak-builtins-info.c:60 app/flatpak-builtins-remote-info.c:60
msgid "Show commit"
msgstr "Arată comitul"

#: app/flatpak-builtins-info.c:61
msgid "Show origin"
msgstr "Arată originea"

#: app/flatpak-builtins-info.c:62
msgid "Show size"
msgstr "Arată dimensiunea"

#: app/flatpak-builtins-info.c:63 app/flatpak-builtins-remote-info.c:62
msgid "Show metadata"
msgstr "Arată datele meta"

#: app/flatpak-builtins-info.c:64 app/flatpak-builtins-remote-info.c:63
msgid "Show runtime"
msgstr "Arată executarea"

#: app/flatpak-builtins-info.c:65 app/flatpak-builtins-remote-info.c:64
msgid "Show sdk"
msgstr "Arată sdk-ul"

#: app/flatpak-builtins-info.c:66
msgid "Show permissions"
msgstr "Arată permisiunile"

#: app/flatpak-builtins-info.c:67
msgid "Query file access"
msgstr "Interoghează accesul la fișiere"

#: app/flatpak-builtins-info.c:67 app/flatpak-builtins-install.c:82
#: app/flatpak-builtins-install.c:88 app/flatpak-builtins-preinstall.c:68
#: app/flatpak-builtins-run.c:182 app/flatpak-builtins-run.c:184
#: app/flatpak-builtins-update.c:67 app/flatpak-builtins-update.c:71
msgid "PATH"
msgstr "CALE"

#: app/flatpak-builtins-info.c:68
msgid "Show extensions"
msgstr "Arată extensiile"

#: app/flatpak-builtins-info.c:69
msgid "Show location"
msgstr "Arată locația"

#: app/flatpak-builtins-info.c:116
msgid "NAME [BRANCH] - Get info about an installed app or runtime"
msgstr ""
"NUME [RAMURĂ] - Obține informații despre o aplicație instalată sau o "
"executare"

#: app/flatpak-builtins-info.c:123 app/flatpak-builtins-remote-add.c:317
#: app/flatpak-builtins-remote-delete.c:63
msgid "NAME must be specified"
msgstr "NUMELE trebuie specificat"

#: app/flatpak-builtins-info.c:196
msgid "ref not present in origin"
msgstr "ref-ul nu este prezent în origine"

#: app/flatpak-builtins-info.c:211 app/flatpak-builtins-remote-info.c:217
#, c-format
msgid "Warning: Commit has no flatpak metadata\n"
msgstr "Avertisment: Comitul nu are date meta flatpak\n"

#: app/flatpak-builtins-info.c:217 app/flatpak-builtins-info.c:259
#: app/flatpak-builtins-info.c:455 app/flatpak-builtins-info.c:513
#: app/flatpak-builtins-remote-info.c:236
#: app/flatpak-builtins-remote-info.c:271
msgid "ID:"
msgstr "ID:"

#: app/flatpak-builtins-info.c:218 app/flatpak-builtins-info.c:260
#: app/flatpak-builtins-remote-info.c:237
#: app/flatpak-builtins-remote-info.c:272
msgid "Ref:"
msgstr "Ref:"

#: app/flatpak-builtins-info.c:219 app/flatpak-builtins-info.c:261
#: app/flatpak-builtins-remote-info.c:238
#: app/flatpak-builtins-remote-info.c:273
msgid "Arch:"
msgstr "Arhitectură:"

#: app/flatpak-builtins-info.c:220 app/flatpak-builtins-info.c:262
#: app/flatpak-builtins-remote-info.c:239
#: app/flatpak-builtins-remote-info.c:274
msgid "Branch:"
msgstr "Ramura:"

#: app/flatpak-builtins-info.c:222 app/flatpak-builtins-info.c:264
#: app/flatpak-builtins-remote-info.c:241
#: app/flatpak-builtins-remote-info.c:276
msgid "Version:"
msgstr "Versiune:"

#: app/flatpak-builtins-info.c:224 app/flatpak-builtins-info.c:266
#: app/flatpak-builtins-remote-info.c:243
#: app/flatpak-builtins-remote-info.c:278
msgid "License:"
msgstr "Licență:"

#: app/flatpak-builtins-info.c:226 app/flatpak-builtins-info.c:269
#: app/flatpak-builtins-remote-info.c:245
#: app/flatpak-builtins-remote-info.c:280
msgid "Collection:"
msgstr "Colecție:"

#: app/flatpak-builtins-info.c:227 app/flatpak-builtins-info.c:270
#: app/flatpak-builtins-info.c:458 app/flatpak-builtins-info.c:516
msgid "Installation:"
msgstr "Instalare:"

#: app/flatpak-builtins-info.c:228 app/flatpak-builtins-info.c:271
#: app/flatpak-builtins-info.c:459 app/flatpak-builtins-info.c:517
#: app/flatpak-builtins-remote-info.c:249
#: app/flatpak-builtins-remote-info.c:284
#, fuzzy
msgid "Installed Size:"
msgstr "Dimensiunea instalată"

#: app/flatpak-builtins-info.c:231 app/flatpak-builtins-info.c:279
#: app/flatpak-builtins-remote-info.c:252
#: app/flatpak-builtins-remote-info.c:288
msgid "Runtime:"
msgstr "Executare:"

#: app/flatpak-builtins-info.c:232 app/flatpak-builtins-info.c:288
#: app/flatpak-builtins-remote-info.c:253
#: app/flatpak-builtins-remote-info.c:293
msgid "Sdk:"
msgstr "Sdk:"

#: app/flatpak-builtins-info.c:235 app/flatpak-builtins-info.c:313
#: app/flatpak-builtins-remote-info.c:256
#: app/flatpak-builtins-remote-info.c:319
msgid "Date:"
msgstr "Data:"

#: app/flatpak-builtins-info.c:237 app/flatpak-builtins-info.c:311
#: app/flatpak-builtins-remote-info.c:258
#: app/flatpak-builtins-remote-info.c:317
msgid "Subject:"
msgstr "Subiect:"

#: app/flatpak-builtins-info.c:240 app/flatpak-builtins-info.c:295
msgid "Active commit:"
msgstr "Comit activ:"

#: app/flatpak-builtins-info.c:241 app/flatpak-builtins-info.c:298
msgid "Latest commit:"
msgstr "Ultimul comit:"

#: app/flatpak-builtins-info.c:244 app/flatpak-builtins-info.c:303
#: app/flatpak-builtins-info.c:457 app/flatpak-builtins-info.c:515
#: app/flatpak-builtins-remote-info.c:259
#: app/flatpak-builtins-remote-info.c:298
msgid "Commit:"
msgstr "Comit:"

#: app/flatpak-builtins-info.c:246 app/flatpak-builtins-info.c:308
#: app/flatpak-builtins-remote-info.c:261
#: app/flatpak-builtins-remote-info.c:303
msgid "Parent:"
msgstr "Superior:"

#: app/flatpak-builtins-info.c:248 app/flatpak-builtins-info.c:321
msgid "Alt-id:"
msgstr "ID-alternativ:"

#: app/flatpak-builtins-info.c:250 app/flatpak-builtins-info.c:325
#: app/flatpak-builtins-remote-info.c:263
#: app/flatpak-builtins-remote-info.c:308
msgid "End-of-life:"
msgstr "Sfârșit-de-viață:"

#: app/flatpak-builtins-info.c:252 app/flatpak-builtins-info.c:330
#: app/flatpak-builtins-remote-info.c:265
#: app/flatpak-builtins-remote-info.c:313
msgid "End-of-life-rebase:"
msgstr "Sfârșit-de-viață-rebase:"

#: app/flatpak-builtins-info.c:254 app/flatpak-builtins-info.c:317
msgid "Subdirectories:"
msgstr "Subdirectoare:"

#: app/flatpak-builtins-info.c:255 app/flatpak-builtins-info.c:454
#: app/flatpak-builtins-info.c:512
msgid "Extension:"
msgstr "Extensii:"

#: app/flatpak-builtins-info.c:267 app/flatpak-builtins-info.c:456
#: app/flatpak-builtins-info.c:514
msgid "Origin:"
msgstr "Origine:"

#: app/flatpak-builtins-info.c:460 app/flatpak-builtins-info.c:522
msgid "Subpaths:"
msgstr "Subcăi:"

#: app/flatpak-builtins-info.c:478
msgid "unmaintained"
msgstr "neîntreținute"

#: app/flatpak-builtins-info.c:480 app/flatpak-builtins-info.c:482
msgid "unknown"
msgstr "necunoscută"

#: app/flatpak-builtins-install.c:68 app/flatpak-builtins-preinstall.c:57
msgid "Don't pull, only install from local cache"
msgstr "Nu trage, doar instalează de la cache-ul local"

#: app/flatpak-builtins-install.c:69 app/flatpak-builtins-preinstall.c:58
#: app/flatpak-builtins-update.c:60
msgid "Don't deploy, only download to local cache"
msgstr "Nu implementa, doar descarcă de la cache-ul local"

#: app/flatpak-builtins-install.c:70 app/flatpak-builtins-preinstall.c:59
msgid "Don't install related refs"
msgstr "Nu instala ref-urile asociate"

#: app/flatpak-builtins-install.c:71 app/flatpak-builtins-preinstall.c:60
#: app/flatpak-builtins-update.c:62
msgid "Don't verify/install runtime dependencies"
msgstr "Nu verifica/instala dependențele executării"

#: app/flatpak-builtins-install.c:72
msgid "Don't automatically pin explicit installs"
msgstr ""

#: app/flatpak-builtins-install.c:73 app/flatpak-builtins-preinstall.c:61
#: app/flatpak-builtins-update.c:63
msgid "Don't use static deltas"
msgstr "Nu utiliza delta-uri statice"

#: app/flatpak-builtins-install.c:76 app/flatpak-builtins-preinstall.c:62
msgid "Additionally install the SDK used to build the given refs"
msgstr ""

#: app/flatpak-builtins-install.c:77 app/flatpak-builtins-preinstall.c:63
msgid ""
"Additionally install the debug info for the given refs and their dependencies"
msgstr ""

#: app/flatpak-builtins-install.c:78
msgid "Assume LOCATION is a .flatpak single-file bundle"
msgstr "Presupune că LOCAȚIA este un pachet dintr-un singur fișier .flatpak"

#: app/flatpak-builtins-install.c:79
msgid "Assume LOCATION is a .flatpakref application description"
msgstr "Presupune că LOCAȚIA este o descriere de aplicație .flatpakref"

#: app/flatpak-builtins-install.c:80
msgid "Assume LOCATION is containers-transports(5) reference to an OCI image"
msgstr ""

#: app/flatpak-builtins-install.c:81
msgid "Check bundle signatures with GPG key from FILE (- for stdin)"
msgstr ""
"Verifică semnăturile pachetului cu cheia GPG de la FIȘIER (- pentru stdin)"

#: app/flatpak-builtins-install.c:82
msgid "Only install this subpath"
msgstr "Instalează doar această subcale"

#: app/flatpak-builtins-install.c:83 app/flatpak-builtins-preinstall.c:64
#: app/flatpak-builtins-uninstall.c:63 app/flatpak-builtins-update.c:68
msgid "Automatically answer yes for all questions"
msgstr "Răspunde cu da automat la toate întrebările"

#: app/flatpak-builtins-install.c:84 app/flatpak-builtins-preinstall.c:65
msgid "Uninstall first if already installed"
msgstr "Dezinstalați mai întâi dacă este deja instalat"

#: app/flatpak-builtins-install.c:85 app/flatpak-builtins-preinstall.c:66
#: app/flatpak-builtins-uninstall.c:64 app/flatpak-builtins-update.c:69
msgid "Produce minimal output and don't ask questions"
msgstr "Produce ieșire minimă și nu pune întrebări"

#: app/flatpak-builtins-install.c:86
msgid "Update install if already installed"
msgstr "Actualizează instalarea dacă este deja instalat"

#. Translators: A sideload is when you install from a local USB drive rather than the Internet.
#: app/flatpak-builtins-install.c:88 app/flatpak-builtins-preinstall.c:68
#: app/flatpak-builtins-update.c:71
msgid "Use this local repo for sideloads"
msgstr "Utilizează acest depozit local pentru încărcările laterale"

#: app/flatpak-builtins-install.c:178
msgid "Bundle filename must be specified"
msgstr "Numele de fișier al pachetului trebuie specificat"

#: app/flatpak-builtins-install.c:188
msgid "Remote bundles are not supported"
msgstr "Pachetele de la distanță nu sunt suportate"

#: app/flatpak-builtins-install.c:231
msgid "Filename or uri must be specified"
msgstr "Numele de fișier sau uri trebuie specificat"

#: app/flatpak-builtins-install.c:295
#, fuzzy
msgid "Image location must be specified"
msgstr "Cel puțin o REF trebuie specificată"

#: app/flatpak-builtins-install.c:345
msgid "[LOCATION/REMOTE] [REF…] - Install applications or runtimes"
msgstr "[LOCAȚIE/LA DISTANȚĂ] [REF…] - Instalează aplicații sau executări"

#: app/flatpak-builtins-install.c:378
msgid "At least one REF must be specified"
msgstr "Cel puțin o REF trebuie specificată"

#: app/flatpak-builtins-install.c:392
#, c-format
msgid "Looking for matches…\n"
msgstr "Se caută după potriviri…\n"

#: app/flatpak-builtins-install.c:513
#, fuzzy, c-format
msgid "No remote refs found for ‘%s’"
msgstr "Nu s-au găsit ref-uri similare cu „%s”"

#: app/flatpak-builtins-install.c:573 app/flatpak-builtins-uninstall.c:405
#: common/flatpak-ref-utils.c:689 common/flatpak-ref-utils.c:1595
#, c-format
msgid "Invalid branch %s: %s"
msgstr "Ramură nevalidă %s: %s"

#: app/flatpak-builtins-install.c:606
#, c-format
msgid "Nothing matches %s in local repository for remote %s"
msgstr ""
"Nimic nu se potrivește cu %s în depozitul local pentru %s de la distanță"

#: app/flatpak-builtins-install.c:608
#, c-format
msgid "Nothing matches %s in remote %s"
msgstr "Nimic nu se potrivește cu %s în %s de la distanță"

#: app/flatpak-builtins-install.c:629
#, c-format
msgid "Skipping: %s\n"
msgstr "Se omite: %s\n"

#: app/flatpak-builtins-kill.c:110
#, c-format
msgid "%s is not running"
msgstr "%s nu rulează"

#: app/flatpak-builtins-kill.c:136
msgid "INSTANCE - Stop a running application"
msgstr "INSTANȚĂ - Oprește o aplicație care rulează"

#: app/flatpak-builtins-kill.c:144 app/flatpak-builtins-ps.c:256
msgid "Extra arguments given"
msgstr "Argumente extra date"

#: app/flatpak-builtins-kill.c:150
msgid "Must specify the app to kill"
msgstr "Trebuie să specificați aplicația de omorât"

#: app/flatpak-builtins-list.c:47
msgid "Show extra information"
msgstr "Arată informațiile suplimentare"

#: app/flatpak-builtins-list.c:48
msgid "List installed runtimes"
msgstr "Listează executările instalate"

#: app/flatpak-builtins-list.c:49
msgid "List installed applications"
msgstr "Listează aplicațiile instalate"

#: app/flatpak-builtins-list.c:50
msgid "Arch to show"
msgstr "Arhitectura de arătat"

#: app/flatpak-builtins-list.c:51 app/flatpak-builtins-remote-ls.c:57
msgid "List all refs (including locale/debug)"
msgstr "Listează toate ref-urile (inclusiv cele locale/de depanare)"

#: app/flatpak-builtins-list.c:53 app/flatpak-builtins-remote-ls.c:58
msgid "List all applications using RUNTIME"
msgstr "Listează toate aplicațiile utilizând EXECUTARE"

#: app/flatpak-builtins-list.c:59 app/flatpak-builtins-remote-list.c:51
#: app/flatpak-builtins-remote-ls.c:68 app/flatpak-builtins-search.c:44
msgid "Name"
msgstr "Nume"

#: app/flatpak-builtins-list.c:59 app/flatpak-builtins-remote-list.c:51
#: app/flatpak-builtins-remote-ls.c:68 app/flatpak-builtins-search.c:44
msgid "Show the name"
msgstr "Arată numele"

#: app/flatpak-builtins-list.c:60 app/flatpak-builtins-remote-list.c:60
#: app/flatpak-builtins-remote-ls.c:69 app/flatpak-builtins-search.c:45
msgid "Description"
msgstr "Descriere"

#: app/flatpak-builtins-list.c:60 app/flatpak-builtins-remote-ls.c:69
#: app/flatpak-builtins-search.c:45
msgid "Show the description"
msgstr "Arată descrierea"

#: app/flatpak-builtins-list.c:61 app/flatpak-builtins-remote-ls.c:70
#: app/flatpak-builtins-search.c:46
msgid "Application ID"
msgstr "ID aplicație"

#: app/flatpak-builtins-list.c:61 app/flatpak-builtins-ps.c:52
#: app/flatpak-builtins-remote-ls.c:70 app/flatpak-builtins-search.c:46
msgid "Show the application ID"
msgstr "Arată ID-ul aplicației"

#: app/flatpak-builtins-list.c:62 app/flatpak-builtins-remote-ls.c:71
#: app/flatpak-builtins-search.c:47
msgid "Show the version"
msgstr "Arată versiunea"

#: app/flatpak-builtins-list.c:65 app/flatpak-builtins-ps.c:56
#: app/flatpak-builtins-remote-ls.c:77
msgid "Runtime"
msgstr "Executare"

#: app/flatpak-builtins-list.c:65
msgid "Show the used runtime"
msgstr "Arată executarea utilizată"

#: app/flatpak-builtins-list.c:66 app/flatpak-builtins-remote-ls.c:74
msgid "Show the origin remote"
msgstr "Arată originea de la distanță"

#: app/flatpak-builtins-list.c:67
msgid "Show the installation"
msgstr "Arată instalarea"

#: app/flatpak-builtins-list.c:69
msgid "Active commit"
msgstr "Comitul activ"

#: app/flatpak-builtins-list.c:69 app/flatpak-builtins-remote-ls.c:76
msgid "Show the active commit"
msgstr "Arată comitul activ"

#: app/flatpak-builtins-list.c:70
msgid "Latest commit"
msgstr "Ultimul comit"

#: app/flatpak-builtins-list.c:70
msgid "Show the latest commit"
msgstr "Arată ultimul comit"

#: app/flatpak-builtins-list.c:71 app/flatpak-builtins-remote-ls.c:78
msgid "Installed size"
msgstr "Dimensiunea instalată"

#: app/flatpak-builtins-list.c:71 app/flatpak-builtins-remote-ls.c:78
msgid "Show the installed size"
msgstr "Arată dimensiunea instalată"

#: app/flatpak-builtins-list.c:72 app/flatpak-builtins-remote-list.c:58
#: app/flatpak-builtins-remote-ls.c:80 app/flatpak-builtins-repo.c:340
msgid "Options"
msgstr "Opțiuni"

#: app/flatpak-builtins-list.c:72 app/flatpak-builtins-remote-list.c:58
#: app/flatpak-builtins-remote-ls.c:80
msgid "Show options"
msgstr "Arată opțiunile"

#: app/flatpak-builtins-list.c:180
#, fuzzy, c-format
msgid "Unable to load details of %s: %s"
msgstr "Nu se poate crea linia de asamblare de sincronizare"

#: app/flatpak-builtins-list.c:190
#, fuzzy, c-format
msgid "Unable to inspect current version of %s: %s"
msgstr "Nu se poate crea linia de asamblare de sincronizare"

#: app/flatpak-builtins-list.c:408
msgid " - List installed apps and/or runtimes"
msgstr " - Listează aplicațiile instalate și/sau executările"

#: app/flatpak-builtins-make-current.c:38
msgid "Arch to make current for"
msgstr "Arhitectura pentru care se face curentă"

#: app/flatpak-builtins-make-current.c:58
msgid "APP BRANCH - Make branch of application current"
msgstr "RAMURĂ APLICAȚIE - Faceți ramura aplicației curentă"

#: app/flatpak-builtins-make-current.c:69 app/flatpak-builtins-run.c:260
msgid "APP must be specified"
msgstr "APLICAȚIA trebuie specificată"

#: app/flatpak-builtins-make-current.c:84
msgid "BRANCH must be specified"
msgstr "RAMURA trebuie specificată"

#: app/flatpak-builtins-make-current.c:97
#, c-format
msgid "App %s branch %s is not installed"
msgstr "Aplicația %s ramura %s nu este instalată"

#: app/flatpak-builtins-mask.c:42
msgid "Remove matching masks"
msgstr "Elimină măștile care se potrivesc"

#: app/flatpak-builtins-mask.c:54
msgid ""
"[PATTERN…] - disable updates and automatic installation matching patterns"
msgstr ""
"[MODEL…] - dezactivează modelele de potrivire ale actualizărilor și "
"instalărilor automate"

#: app/flatpak-builtins-mask.c:73
#, c-format
msgid "No masked patterns\n"
msgstr "Nu sunt modele mascate\n"

#: app/flatpak-builtins-mask.c:78
#, c-format
msgid "Masked patterns:\n"
msgstr "Modele mascate:\n"

#: app/flatpak-builtins-override.c:42
msgid "Remove existing overrides"
msgstr "Elimină suprascrierile existente"

#: app/flatpak-builtins-override.c:43
msgid "Show existing overrides"
msgstr "Arată suprascrierile existente"

#: app/flatpak-builtins-override.c:59
msgid "[APP] - Override settings [for application]"
msgstr "[APLICAȚIE] - Suprascrie configurările [pentru aplicație]"

#: app/flatpak-builtins-permission-list.c:143
msgid "[TABLE] [ID] - List permissions"
msgstr "[TABEL] [ID] - Listează permisiunile"

#: app/flatpak-builtins-permission-list.c:179
#: app/flatpak-builtins-permission-show.c:142
msgid "Table"
msgstr "Tabel"

#: app/flatpak-builtins-permission-list.c:180
#: app/flatpak-builtins-permission-show.c:143
msgid "Object"
msgstr "Obiect"

#: app/flatpak-builtins-permission-list.c:181
#: app/flatpak-builtins-permission-show.c:144
msgid "App"
msgstr "Aplicație"

#: app/flatpak-builtins-permission-list.c:183
#: app/flatpak-builtins-permission-show.c:146
msgid "Data"
msgstr "Date"

#: app/flatpak-builtins-permission-remove.c:120
msgid "TABLE ID [APP_ID] - Remove item from permission store"
msgstr ""
"ID TABEL [ID_APLICAȚIE] - Elimină elementul de la stocarea permisiunilor"

#: app/flatpak-builtins-permission-remove.c:129
#: app/flatpak-builtins-permission-set.c:120
msgid "Too few arguments"
msgstr "Prea puține argumente"

#: app/flatpak-builtins-permission-reset.c:43
msgid "Reset all permissions"
msgstr "Restabilește toate permisiunile"

#: app/flatpak-builtins-permission-reset.c:144
msgid "APP_ID - Reset permissions for an app"
msgstr "ID_APLICAȚIE - Restabilește permisiunile pentru o aplicație"

#: app/flatpak-builtins-permission-reset.c:153
#: app/flatpak-builtins-permission-show.c:124
msgid "Wrong number of arguments"
msgstr "Număr greșit de argumente"

#: app/flatpak-builtins-permission-set.c:42
msgid "Associate DATA with the entry"
msgstr "Asociază DATELE cu intrarea"

#: app/flatpak-builtins-permission-set.c:42
msgid "DATA"
msgstr "DATE"

#: app/flatpak-builtins-permission-set.c:111
msgid "TABLE ID APP_ID [PERMISSION...] - Set permissions"
msgstr "ID TABEL ID_APLICAȚIE [PERMISIUNE...] - Stabilește permisiunile"

#: app/flatpak-builtins-permission-set.c:132
#, c-format
msgid "Failed to parse '%s' as GVariant: "
msgstr "Nu s-a putut pasa „%s” ca GVariant: "

#: app/flatpak-builtins-permission-show.c:115
msgid "APP_ID - Show permissions for an app"
msgstr "ID_APLICAȚIE - Arată permisiunile pentru o aplicație"

#: app/flatpak-builtins-pin.c:44
#, fuzzy
msgid "Remove matching pins"
msgstr "Elimină măștile care se potrivesc"

#: app/flatpak-builtins-pin.c:56
#, fuzzy
msgid "[PATTERN…] - disable automatic removal of runtimes matching patterns"
msgstr ""
"[MODEL…] - dezactivează modelele de potrivire ale actualizărilor și "
"instalărilor automate"

#: app/flatpak-builtins-pin.c:75
#, fuzzy, c-format
msgid "No pinned patterns\n"
msgstr "Nu sunt modele mascate\n"

#: app/flatpak-builtins-pin.c:80
#, fuzzy, c-format
msgid "Pinned patterns:\n"
msgstr "Modele mascate:\n"

#: app/flatpak-builtins-preinstall.c:80
msgid "- Install flatpaks that are part of the operating system"
msgstr ""

#: app/flatpak-builtins-preinstall.c:118
#, c-format
msgid "Nothing to do.\n"
msgstr "Nimic de făcut.\n"

#: app/flatpak-builtins-ps.c:49
msgid "Instance"
msgstr "Instanță"

#: app/flatpak-builtins-ps.c:49
msgid "Show the instance ID"
msgstr "Arată ID-ul instanței"

#: app/flatpak-builtins-ps.c:50 app/flatpak-builtins-run.c:178
msgid "PID"
msgstr "PID"

#: app/flatpak-builtins-ps.c:50
msgid "Show the PID of the wrapper process"
msgstr "Arată PID-ul procesului de invelitoare"

#: app/flatpak-builtins-ps.c:51
msgid "Child-PID"
msgstr "PID-inferior"

#: app/flatpak-builtins-ps.c:51
msgid "Show the PID of the sandbox process"
msgstr "Arată PID-ul procesului de sandbox"

#: app/flatpak-builtins-ps.c:54 app/flatpak-builtins-search.c:48
msgid "Show the application branch"
msgstr "Arată ramura aplicației"

#: app/flatpak-builtins-ps.c:55
msgid "Show the application commit"
msgstr "Arată comitul aplicației"

#: app/flatpak-builtins-ps.c:56
msgid "Show the runtime ID"
msgstr "Arată ID-ul executării"

#: app/flatpak-builtins-ps.c:57
msgid "R.-Branch"
msgstr "Ramura-E"

#: app/flatpak-builtins-ps.c:57
msgid "Show the runtime branch"
msgstr "Arată ramura de executare"

#: app/flatpak-builtins-ps.c:58
msgid "R.-Commit"
msgstr "Comit-E"

#: app/flatpak-builtins-ps.c:58
msgid "Show the runtime commit"
msgstr "Arată comitul de executare"

#: app/flatpak-builtins-ps.c:59
msgid "Active"
msgstr "Activ"

#: app/flatpak-builtins-ps.c:59
msgid "Show whether the app is active"
msgstr "Arată dacă aplicația este activă"

#: app/flatpak-builtins-ps.c:60
msgid "Background"
msgstr "Fundal"

#: app/flatpak-builtins-ps.c:60
msgid "Show whether the app is background"
msgstr "Arată dacă aplicația este fundal"

#: app/flatpak-builtins-ps.c:246
msgid " - Enumerate running sandboxes"
msgstr " - Enumerați sandbox-urile care rulează"

#: app/flatpak-builtins-remote-add.c:66
msgid "Do nothing if the provided remote exists"
msgstr "Nu face nimic dacă depozitul de la distanță furnizat există"

#: app/flatpak-builtins-remote-add.c:67
msgid "LOCATION specifies a configuration file, not the repo location"
msgstr "LOCAȚIA specifică un fișier de configurare, nu locația depozitului"

#: app/flatpak-builtins-remote-add.c:72 app/flatpak-builtins-remote-modify.c:78
msgid "Disable GPG verification"
msgstr "Dezactivează verificarea GPG"

#: app/flatpak-builtins-remote-add.c:73 app/flatpak-builtins-remote-modify.c:79
msgid "Mark the remote as don't enumerate"
msgstr "Marchează depozitul de la distanță ca nu enumerați"

#: app/flatpak-builtins-remote-add.c:74 app/flatpak-builtins-remote-modify.c:80
msgid "Mark the remote as don't use for deps"
msgstr "Marchează depozitul de la distanță ca nu utilizați pentru depozite"

#: app/flatpak-builtins-remote-add.c:75 app/flatpak-builtins-remote-modify.c:81
msgid "Set priority (default 1, higher is more prioritized)"
msgstr "Stabiliți prioritatea (implicit 1, mai mare este mai prioritat)"

#: app/flatpak-builtins-remote-add.c:75 app/flatpak-builtins-remote-modify.c:81
msgid "PRIORITY"
msgstr "PRIORITATE"

#: app/flatpak-builtins-remote-add.c:76
#, fuzzy
msgid "The named subset to use for this remote"
msgstr "Un nume drăguț de utilizat pentru acest depozit de la distanță"

#: app/flatpak-builtins-remote-add.c:76 app/flatpak-builtins-remote-modify.c:71
msgid "SUBSET"
msgstr ""

#: app/flatpak-builtins-remote-add.c:77 app/flatpak-builtins-remote-modify.c:82
msgid "A nice name to use for this remote"
msgstr "Un nume drăguț de utilizat pentru acest depozit de la distanță"

#: app/flatpak-builtins-remote-add.c:78 app/flatpak-builtins-remote-modify.c:83
msgid "A one-line comment for this remote"
msgstr ""
"Un comentariu pe o singură linie de utilizat pentru acest depozit de la "
"distanță"

#: app/flatpak-builtins-remote-add.c:79 app/flatpak-builtins-remote-modify.c:84
msgid "A full-paragraph description for this remote"
msgstr "O descriere de un paragraf complet pentru acest depozit de la distanță"

#: app/flatpak-builtins-remote-add.c:80 app/flatpak-builtins-remote-modify.c:85
msgid "URL for a website for this remote"
msgstr "URL-ul pentru un site web pentru acest depozit de la distanță"

#: app/flatpak-builtins-remote-add.c:81 app/flatpak-builtins-remote-modify.c:86
msgid "URL for an icon for this remote"
msgstr "URL-ul pentru o iconiță pentru acest depozit de la distanță"

#: app/flatpak-builtins-remote-add.c:82 app/flatpak-builtins-remote-modify.c:87
msgid "Default branch to use for this remote"
msgstr "Ramura implicită de utilizat pentru acest depozit de la distanță"

#: app/flatpak-builtins-remote-add.c:84 app/flatpak-builtins-remote-modify.c:89
msgid "Import GPG key from FILE (- for stdin)"
msgstr "Importă cheia GPG de la FIȘIER (- pentru stdin)"

#: app/flatpak-builtins-remote-add.c:85 app/flatpak-builtins-remote-modify.c:90
msgid "Load signatures from URL"
msgstr ""

#: app/flatpak-builtins-remote-add.c:86 app/flatpak-builtins-remote-modify.c:92
msgid "Set path to local filter FILE"
msgstr "Stabilește calea către FIȘIERUL filtru local"

#: app/flatpak-builtins-remote-add.c:87 app/flatpak-builtins-remote-modify.c:93
msgid "Disable the remote"
msgstr "Dezactivează depozitul de la distanță"

#: app/flatpak-builtins-remote-add.c:88 app/flatpak-builtins-remote-modify.c:94
msgid "Name of authenticator"
msgstr "Numele autentificatorului"

#: app/flatpak-builtins-remote-add.c:90 app/flatpak-builtins-remote-modify.c:96
msgid "Autoinstall authenticator"
msgstr "Instalează automat autentificatorul"

#: app/flatpak-builtins-remote-add.c:91 app/flatpak-builtins-remote-modify.c:97
msgid "Don't autoinstall authenticator"
msgstr "Nu instala automat autentificatorul"

#: app/flatpak-builtins-remote-add.c:92 app/flatpak-builtins-remote-modify.c:99
msgid "Don't follow the redirect set in the summary file"
msgstr "Nu urmări redirectarea stabilită în fișierul rezumat"

#: app/flatpak-builtins-remote-add.c:261 app/flatpak-builtins-remote-add.c:268
#, c-format
msgid "Can't load uri %s: %s\n"
msgstr "Nu se poate încărca uri-ul %s: %s\n"

#: app/flatpak-builtins-remote-add.c:276 common/flatpak-dir.c:4643
#, c-format
msgid "Can't load file %s: %s\n"
msgstr "Nu se poate încărca fișierul %s: %s\n"

#: app/flatpak-builtins-remote-add.c:304
msgid "NAME LOCATION - Add a remote repository"
msgstr "NUME LOCAȚIE - Adaugă un depozit de la distanță"

#: app/flatpak-builtins-remote-add.c:331
msgid "GPG verification is required if collections are enabled"
msgstr "Verificarea GPG este necesară dacă sunt activate colecțiile"

#: app/flatpak-builtins-remote-add.c:393
#, c-format
msgid "Remote %s already exists"
msgstr "Depozitul de la distanță %s deja există"

#: app/flatpak-builtins-remote-add.c:405
#: app/flatpak-builtins-remote-modify.c:340
#, c-format
msgid "Invalid authenticator name %s"
msgstr "Nume de autentificator %s nevalid"

#: app/flatpak-builtins-remote-add.c:422
#, c-format
msgid "Warning: Could not update extra metadata for '%s': %s\n"
msgstr "Avertisment: Nu se pot actualiza datele meta extra pentru „%s”: %s\n"

#: app/flatpak-builtins-remote-delete.c:39
msgid "Remove remote even if in use"
msgstr "Elimină depozitul de la distanță chiar și dacă este în uz"

#: app/flatpak-builtins-remote-delete.c:53
msgid "NAME - Delete a remote repository"
msgstr "NUME - Șterge un depozit de la distanță"

#: app/flatpak-builtins-remote-delete.c:100
#, c-format
msgid "The following refs are installed from remote '%s':"
msgstr ""
"Următoarele ref-uri sunt instalate de la depozitul de la distanță „%s”:"

#: app/flatpak-builtins-remote-delete.c:101
msgid "Remove them?"
msgstr "Le eliminați?"

#: app/flatpak-builtins-remote-delete.c:103
#, c-format
msgid "Can't remove remote '%s' with installed refs"
msgstr ""
"Nu se poate elimina depozitul de la distanță „%s” cu ref-urile instalate"

#: app/flatpak-builtins-remote-info.c:55
msgid "Commit to show info for"
msgstr "Comitul pentru care se arată informațiile"

#: app/flatpak-builtins-remote-info.c:58
msgid "Display log"
msgstr "Afișează istoricul"

#: app/flatpak-builtins-remote-info.c:61
msgid "Show parent"
msgstr "Arată superiorul"

#: app/flatpak-builtins-remote-info.c:65 app/flatpak-builtins-remote-ls.c:60
msgid "Use local caches even if they are stale"
msgstr "Utilizează cache-uri locale chiar dacă sunt învechite"

#. Translators: A sideload is when you install from a local USB drive rather than the Internet.
#: app/flatpak-builtins-remote-info.c:67 app/flatpak-builtins-remote-ls.c:62
msgid "Only list refs available as sideloads"
msgstr "Listează doar ref-urile disponibile ca încărcări laterale"

#: app/flatpak-builtins-remote-info.c:114
msgid ""
" REMOTE REF - Show information about an application or runtime in a remote"
msgstr ""
" REF DE LA DISTANȚĂ - Arată informațiile despre o aplicație sau o executare "
"într-un depozit de la distanță"

#: app/flatpak-builtins-remote-info.c:125
msgid "REMOTE and REF must be specified"
msgstr "DE LA DISTANȚĂ și REF trebuie specificate"

#: app/flatpak-builtins-remote-info.c:247
#: app/flatpak-builtins-remote-info.c:282
#, fuzzy
msgid "Download Size:"
msgstr "Dimensiunea descărcării"

#: app/flatpak-builtins-remote-info.c:267
#: app/flatpak-builtins-remote-info.c:325
msgid "History:"
msgstr "Istoric:"

#: app/flatpak-builtins-remote-info.c:348
msgid " Commit:"
msgstr " Comit:"

#: app/flatpak-builtins-remote-info.c:349
msgid " Subject:"
msgstr " Subiect:"

#: app/flatpak-builtins-remote-info.c:350
msgid " Date:"
msgstr " Dată:"

#: app/flatpak-builtins-remote-info.c:383
#, c-format
msgid "Warning: Commit %s has no flatpak metadata\n"
msgstr "Avertisment: Comitul %s nu are date meta flatpak\n"

#: app/flatpak-builtins-remote-list.c:43
msgid "Show remote details"
msgstr "Arată detaliile depozitului de la distanță"

#: app/flatpak-builtins-remote-list.c:44
msgid "Show disabled remotes"
msgstr "Arată depozitele de la distanță dezactivate"

#: app/flatpak-builtins-remote-list.c:52
msgid "Title"
msgstr "Titlu"

#: app/flatpak-builtins-remote-list.c:52
msgid "Show the title"
msgstr "Arată titlul"

#: app/flatpak-builtins-remote-list.c:53
msgid "Show the URL"
msgstr "Arată URL-ul"

#: app/flatpak-builtins-remote-list.c:54
msgid "Show the collection ID"
msgstr "Arată ID-ul colecției"

#: app/flatpak-builtins-remote-list.c:55 app/flatpak-builtins-repo.c:392
msgid "Subset"
msgstr ""

#: app/flatpak-builtins-remote-list.c:55
#, fuzzy
msgid "Show the subset"
msgstr "Arată ref-ul"

#: app/flatpak-builtins-remote-list.c:56
msgid "Filter"
msgstr "Filtrează"

#: app/flatpak-builtins-remote-list.c:56
msgid "Show filter file"
msgstr "Arată fișierul filtrului"

#: app/flatpak-builtins-remote-list.c:57
msgid "Priority"
msgstr "Prioritate"

#: app/flatpak-builtins-remote-list.c:57
msgid "Show the priority"
msgstr "Arată prioritatea"

#: app/flatpak-builtins-remote-list.c:59
msgid "Comment"
msgstr "Comentariu"

#: app/flatpak-builtins-remote-list.c:59
msgid "Show comment"
msgstr "Arată comentariul"

#: app/flatpak-builtins-remote-list.c:60
msgid "Show description"
msgstr "Afișează descriere"

#: app/flatpak-builtins-remote-list.c:61
msgid "Homepage"
msgstr "Pagină principală"

#: app/flatpak-builtins-remote-list.c:61
msgid "Show homepage"
msgstr "Arată pagina personală"

#: app/flatpak-builtins-remote-list.c:62
msgid "Icon"
msgstr "Iconiță"

#: app/flatpak-builtins-remote-list.c:62
msgid "Show icon"
msgstr "Arată o iconiță"

#: app/flatpak-builtins-remote-list.c:231
msgid " - List remote repositories"
msgstr " - Listează depozitele de la distanță"

#: app/flatpak-builtins-remote-ls.c:52
msgid "Show arches and branches"
msgstr "Arată arhitecturile și ramurile"

#: app/flatpak-builtins-remote-ls.c:53
msgid "Show only runtimes"
msgstr "Arată doar executările"

#: app/flatpak-builtins-remote-ls.c:54
msgid "Show only apps"
msgstr "Arată doar aplicațiile"

#: app/flatpak-builtins-remote-ls.c:55
msgid "Show only those where updates are available"
msgstr "Arată-le doar pe acelea pentru care sunt disponibile actualizări"

#: app/flatpak-builtins-remote-ls.c:56
msgid "Limit to this arch (* for all)"
msgstr "Limitează la această arhitectură (* pentru toate)"

#: app/flatpak-builtins-remote-ls.c:77
msgid "Show the runtime"
msgstr "Arată executarea"

#: app/flatpak-builtins-remote-ls.c:79
msgid "Download size"
msgstr "Dimensiunea descărcării"

#: app/flatpak-builtins-remote-ls.c:79
msgid "Show the download size"
msgstr "Arată dimensiunea descărcării"

#: app/flatpak-builtins-remote-ls.c:391
msgid " [REMOTE or URI] - Show available runtimes and applications"
msgstr ""
" [DE LA DISTANȚĂ sau URI] - Arată executările și aplicațiile disponibile"

#: app/flatpak-builtins-remote-modify.c:67
msgid "Enable GPG verification"
msgstr "Activează verificarea GPG"

#: app/flatpak-builtins-remote-modify.c:68
msgid "Mark the remote as enumerate"
msgstr "Marchează depozitul de la distanță ca enumerează"

#: app/flatpak-builtins-remote-modify.c:69
msgid "Mark the remote as used for dependencies"
msgstr "Marchează depozitul de la distanță ca utilizat pentru dependențe"

#: app/flatpak-builtins-remote-modify.c:70
#, fuzzy
msgid "Set a new URL"
msgstr "Stabilește un url nou"

#: app/flatpak-builtins-remote-modify.c:71
#, fuzzy
msgid "Set a new subset to use"
msgstr "Stabilește un url nou"

#: app/flatpak-builtins-remote-modify.c:72
msgid "Enable the remote"
msgstr "Activează depozitul de la distanță"

#: app/flatpak-builtins-remote-modify.c:73
msgid "Update extra metadata from the summary file"
msgstr "Actualizează datele meta extra de la fișierul rezumat"

#: app/flatpak-builtins-remote-modify.c:91
msgid "Disable local filter"
msgstr "Dezactivează filtrul local"

#: app/flatpak-builtins-remote-modify.c:95
msgid "Authenticator options"
msgstr "Opțiuni autentificator"

#: app/flatpak-builtins-remote-modify.c:98
msgid "Follow the redirect set in the summary file"
msgstr "Urmărește redirectarea stabilită în fișierul rezumat"

#: app/flatpak-builtins-remote-modify.c:306
msgid "NAME - Modify a remote repository"
msgstr "NUME- Modifică un depozit de la distanță"

#: app/flatpak-builtins-remote-modify.c:316
msgid "Remote NAME must be specified"
msgstr "NUMELE depozitului de la distanță trebuie specificat"

#: app/flatpak-builtins-remote-modify.c:327
#, c-format
msgid "Updating extra metadata from remote summary for %s\n"
msgstr ""
"Se actualizează datele meta extra de la rezumatul depozitului de la distanță "
"pentru %s\n"

#: app/flatpak-builtins-remote-modify.c:330
#, c-format
msgid "Error updating extra metadata for '%s': %s\n"
msgstr "Eroare la actualizarea datelor meta extra pentru „%s”: %s\n"

#: app/flatpak-builtins-remote-modify.c:331
#, c-format
msgid "Could not update extra metadata for %s"
msgstr "Nu s-au putut actualiza datele meta extra pentru %s"

#: app/flatpak-builtins-repair.c:43
msgid "Don't make any changes"
msgstr "Nu face nicio modificare"

#: app/flatpak-builtins-repair.c:44
msgid "Reinstall all refs"
msgstr "Reinstalează toate ref-urile"

#: app/flatpak-builtins-repair.c:68
#, c-format
msgid "Object missing: %s.%s\n"
msgstr "Obiectul lipsește: %s.%s\n"

#: app/flatpak-builtins-repair.c:76
#, c-format
msgid "Object invalid: %s.%s\n"
msgstr "Obiect nevalid: %s.%s\n"

#: app/flatpak-builtins-repair.c:81
#, c-format
msgid "%s, deleting object\n"
msgstr "%s, se șterge obiectul\n"

#: app/flatpak-builtins-repair.c:146
#, c-format
msgid "Can't load object %s: %s\n"
msgstr "Nu se poate încărca obiectul %s: %s\n"

#: app/flatpak-builtins-repair.c:228
#, fuzzy, c-format
msgid "Commit invalid %s: %s\n"
msgstr "Obiect nevalid: %s.%s\n"

#: app/flatpak-builtins-repair.c:231
#, fuzzy, c-format
msgid "Deleting invalid commit %s: %s\n"
msgstr "Ref de comit %s nevalid: "

#: app/flatpak-builtins-repair.c:261
#, c-format
msgid "Commit should be marked partial: %s\n"
msgstr ""

#: app/flatpak-builtins-repair.c:264
#, c-format
msgid "Marking commit as partial: %s\n"
msgstr ""

#: app/flatpak-builtins-repair.c:293
#, c-format
msgid "Problems loading data for %s: %s\n"
msgstr "Probleme la încărcarea datelor pentru %s: %s\n"

#: app/flatpak-builtins-repair.c:306
#, c-format
msgid "Error reinstalling %s: %s\n"
msgstr "Eroare la reinstalarea %s: %s\n"

#: app/flatpak-builtins-repair.c:327
msgid "- Repair a flatpak installation"
msgstr "- Repară o instalare flatpak"

#: app/flatpak-builtins-repair.c:406
#, c-format
msgid "Removing non-deployed ref %s…\n"
msgstr "Se elimină ref-ul nedesfășurat %s…\n"

#: app/flatpak-builtins-repair.c:411
#, c-format
msgid "Skipping non-deployed ref %s…\n"
msgstr "Se omite ref-ul nedesfășurat %s…\n"

#: app/flatpak-builtins-repair.c:429
#, fuzzy, c-format
msgid "[%d/%d] Verifying %s…\n"
msgstr "Se verifică %s…\n"

#: app/flatpak-builtins-repair.c:435
#, c-format
msgid "Dry run: "
msgstr ""

#: app/flatpak-builtins-repair.c:440
#, c-format
msgid "Deleting ref %s due to missing objects\n"
msgstr "Se șterge ref-ul %s din cauza obiectelor care lipsesc\n"

#: app/flatpak-builtins-repair.c:444
#, c-format
msgid "Deleting ref %s due to invalid objects\n"
msgstr "Se șterge ref-ul %s din cauza obiectelor nevalide\n"

#: app/flatpak-builtins-repair.c:448
#, c-format
msgid "Deleting ref %s due to %d\n"
msgstr "Se șterge ref-ul %s din cauza la %d\n"

#: app/flatpak-builtins-repair.c:464
#, c-format
msgid "Checking remotes...\n"
msgstr ""

#: app/flatpak-builtins-repair.c:482
#, c-format
msgid "Remote %s for ref %s is missing\n"
msgstr "Depozitul de la distanță %s pentru ref-ul %s lipsește\n"

#: app/flatpak-builtins-repair.c:484
#, c-format
msgid "Remote %s for ref %s is disabled\n"
msgstr "Depozitul de la distanță %s pentru ref-ul %s este dezactivat\n"

#: app/flatpak-builtins-repair.c:490
#, c-format
msgid "Pruning objects\n"
msgstr "Se elimină obiectele\n"

#: app/flatpak-builtins-repair.c:498
#, c-format
msgid "Erasing .removed\n"
msgstr "Se șterge .removed\n"

#: app/flatpak-builtins-repair.c:524
#, c-format
msgid "Reinstalling refs\n"
msgstr "Se reinstalarează ref-urile\n"

#: app/flatpak-builtins-repair.c:526
#, c-format
msgid "Reinstalling removed refs\n"
msgstr "Se reinstalează ref-urile eliminate\n"

#: app/flatpak-builtins-repair.c:551
#, c-format
msgid "While removing appstream for %s: "
msgstr "În timpul eliminării appstream pentru %s: "

#: app/flatpak-builtins-repair.c:558
#, c-format
msgid "While deploying appstream for %s: "
msgstr "În timpul desfășurării appstream pentru %s: "

#: app/flatpak-builtins-repo.c:106
#, c-format
msgid "Repo mode: %s\n"
msgstr "Mod depozit: %s\n"

#: app/flatpak-builtins-repo.c:113
#, c-format
msgid "Indexed summaries: %s\n"
msgstr ""

#: app/flatpak-builtins-repo.c:113 app/flatpak-builtins-repo.c:139
#: app/flatpak-builtins-repo.c:172
msgid "true"
msgstr "adevărat"

#: app/flatpak-builtins-repo.c:113 app/flatpak-builtins-repo.c:139
#: app/flatpak-builtins-repo.c:172
msgid "false"
msgstr "fals"

#: app/flatpak-builtins-repo.c:121
#, c-format
msgid "Subsummaries: "
msgstr ""

#: app/flatpak-builtins-repo.c:136
#, c-format
msgid "Cache version: %d\n"
msgstr ""

#: app/flatpak-builtins-repo.c:139
#, c-format
msgid "Indexed deltas: %s\n"
msgstr ""

#: app/flatpak-builtins-repo.c:142
#, c-format
msgid "Title: %s\n"
msgstr "Titlu: %s\n"

#: app/flatpak-builtins-repo.c:145
#, c-format
msgid "Comment: %s\n"
msgstr "Comentariu: %s\n"

#: app/flatpak-builtins-repo.c:148
#, c-format
msgid "Description: %s\n"
msgstr "Descriere: %s\n"

#: app/flatpak-builtins-repo.c:151
#, c-format
msgid "Homepage: %s\n"
msgstr "Pagină principală: %s\n"

#: app/flatpak-builtins-repo.c:154
#, c-format
msgid "Icon: %s\n"
msgstr "Iconiță: %s\n"

#: app/flatpak-builtins-repo.c:157
#, c-format
msgid "Collection ID: %s\n"
msgstr "ID colecție: %s\n"

#: app/flatpak-builtins-repo.c:160
#, c-format
msgid "Default branch: %s\n"
msgstr "Ramura implicită: %s\n"

#: app/flatpak-builtins-repo.c:163
#, c-format
msgid "Redirect URL: %s\n"
msgstr "URL de redirectare: %s\n"

#: app/flatpak-builtins-repo.c:166
#, c-format
msgid "Deploy collection ID: %s\n"
msgstr "Desfășoară ID-ul de colecție: %s\n"

#: app/flatpak-builtins-repo.c:169
#, c-format
msgid "Authenticator name: %s\n"
msgstr "Nume de autentificare: %s\n"

#: app/flatpak-builtins-repo.c:172
#, c-format
msgid "Authenticator install: %s\n"
msgstr "Instalarea de autentificator: %s\n"

#: app/flatpak-builtins-repo.c:180
#, c-format
msgid "GPG key hash: %s\n"
msgstr "Valoare de dispersie a cheii GPG: %s\n"

#: app/flatpak-builtins-repo.c:184
#, fuzzy, c-format
msgid "%zd summary branches\n"
msgstr "ramuri %zd\n"

#: app/flatpak-builtins-repo.c:336
msgid "Installed"
msgstr "Instalat"

#. Translators: Download is used here as a noun
#: app/flatpak-builtins-repo.c:338 app/flatpak-cli-transaction.c:1462
msgid "Download"
msgstr "Descarcă"

#: app/flatpak-builtins-repo.c:339
msgid "Subsets"
msgstr ""

#: app/flatpak-builtins-repo.c:393
msgid "Digest"
msgstr ""

#: app/flatpak-builtins-repo.c:394
#, fuzzy
msgid "History length"
msgstr "Istoric:"

#: app/flatpak-builtins-repo.c:711
msgid "Print general information about the repository"
msgstr "Tipărește informații generale despre depozit"

#: app/flatpak-builtins-repo.c:712
msgid "List the branches in the repository"
msgstr "Listează ramurile din depozit"

#: app/flatpak-builtins-repo.c:713
msgid "Print metadata for a branch"
msgstr "Tipărește datele meta pentru o ramură"

#: app/flatpak-builtins-repo.c:714
msgid "Show commits for a branch"
msgstr "Arată comiturile pentru o ramură"

#: app/flatpak-builtins-repo.c:715
#, fuzzy
msgid "Print information about the repo subsets"
msgstr "Tipărește informații generale despre depozit"

#: app/flatpak-builtins-repo.c:716
msgid "Limit information to subsets with this prefix"
msgstr ""

#: app/flatpak-builtins-repo.c:732
msgid "LOCATION - Repository maintenance"
msgstr "LOCAȚIE - Mentenanță depozit"

#: app/flatpak-builtins-run.c:159
msgid "Command to run"
msgstr "Comanda de rulat"

#: app/flatpak-builtins-run.c:160
msgid "Directory to run the command in"
msgstr "Directorul în care să se ruleze comanda"

#: app/flatpak-builtins-run.c:161
msgid "Branch to use"
msgstr "Ramura de utilizat"

#: app/flatpak-builtins-run.c:162
msgid "Use development runtime"
msgstr "Utilizează executarea de dezvoltare"

#: app/flatpak-builtins-run.c:163
msgid "Runtime to use"
msgstr "Executarea de utilizat"

#: app/flatpak-builtins-run.c:164
msgid "Runtime version to use"
msgstr "Versiunea de executare de utilizat"

#: app/flatpak-builtins-run.c:167
msgid "Log accessibility bus calls"
msgstr "Înregistrează apelurile magistralei de accesibilitate"

#: app/flatpak-builtins-run.c:168
msgid "Don't proxy accessibility bus calls"
msgstr "Nu face proxy pentru apelurile de magistrală de accesibilitate"

#: app/flatpak-builtins-run.c:169
msgid "Proxy accessibility bus calls (default except when sandboxed)"
msgstr ""
"Proxy pentru apelurile de magistrală de accesibilitate (implicit cu excepția "
"când se află într-un sandbox)"

#: app/flatpak-builtins-run.c:170
msgid "Don't proxy session bus calls"
msgstr "Nu face proxy pentru apelurile de magistrală a sesiunii"

#: app/flatpak-builtins-run.c:171
msgid "Proxy session bus calls (default except when sandboxed)"
msgstr ""
"Proxy pentru apelurile de magistrală a sesiunii (implicit cu excepția când "
"se află într-un sandbox)"

#: app/flatpak-builtins-run.c:172
msgid "Don't start portals"
msgstr "Nu pornește portalurile"

#: app/flatpak-builtins-run.c:173
msgid "Enable file forwarding"
msgstr "Activează înaintarea fișierelor"

#: app/flatpak-builtins-run.c:174
msgid "Run specified commit"
msgstr "Rulează comitul specificat"

#: app/flatpak-builtins-run.c:175
msgid "Use specified runtime commit"
msgstr "Utilizează comitul de executare specificat"

#: app/flatpak-builtins-run.c:176
msgid "Run completely sandboxed"
msgstr "Rulează complet în sandbox"

#: app/flatpak-builtins-run.c:178
msgid "Use PID as parent pid for sharing namespaces"
msgstr "Utilizează PID-ul ca pid superior pentru partajarea spațiilor de nume"

#: app/flatpak-builtins-run.c:179
msgid "Make processes visible in parent namespace"
msgstr "Faceți procesele vizibile în spațiul de nume superior"

#: app/flatpak-builtins-run.c:180
msgid "Share process ID namespace with parent"
msgstr ""

#: app/flatpak-builtins-run.c:181
msgid "Write the instance ID to the given file descriptor"
msgstr "Scrieți ID-ul instanței la descriptorul de fișier dat"

#: app/flatpak-builtins-run.c:182
msgid "Use PATH instead of the app's /app"
msgstr ""

#: app/flatpak-builtins-run.c:183
msgid "Use FD instead of the app's /app"
msgstr ""

#: app/flatpak-builtins-run.c:183 app/flatpak-builtins-run.c:185
#: app/flatpak-builtins-run.c:187 app/flatpak-builtins-run.c:188
#: common/flatpak-context.c:2672
msgid "FD"
msgstr ""

#: app/flatpak-builtins-run.c:184
msgid "Use PATH instead of the runtime's /usr"
msgstr ""

#: app/flatpak-builtins-run.c:185
msgid "Use FD instead of the runtime's /usr"
msgstr ""

#: app/flatpak-builtins-run.c:186
#, fuzzy
msgid "Clear all outside environment variables"
msgstr "Stabilește variabila de mediu"

#: app/flatpak-builtins-run.c:187
msgid ""
"Bind mount the file or directory referred to by FD to its canonicalized path"
msgstr ""

#: app/flatpak-builtins-run.c:188
msgid ""
"Bind mount the file or directory referred to by FD read-only to its "
"canonicalized path"
msgstr ""

#: app/flatpak-builtins-run.c:219
msgid "APP [ARGUMENT…] - Run an app"
msgstr "APLICAȚIE [ARGUMENT…] - Rulează o aplicație"

#: app/flatpak-builtins-run.c:370
#, c-format
msgid "runtime/%s/%s/%s not installed"
msgstr "executarea/%s/%s/%s nu este instalată"

#: app/flatpak-builtins-run.c:419
msgid "app-fd and app-path cannot both be used"
msgstr ""

#: app/flatpak-builtins-run.c:449
msgid "usr-fd and usr-path cannot both be used"
msgstr ""

#: app/flatpak-builtins-search.c:37
msgid "Arch to search for"
msgstr "Arhitectura după care se caută"

#: app/flatpak-builtins-search.c:49
msgid "Remotes"
msgstr "Locații la distanță"

#: app/flatpak-builtins-search.c:49
msgid "Show the remotes"
msgstr "Arată depozitele de la distanță"

#: app/flatpak-builtins-search.c:244
msgid "TEXT - Search remote apps/runtimes for text"
msgstr "TEXT - Caută aplicații/executări de la distanță pentru text"

#: app/flatpak-builtins-search.c:255
msgid "TEXT must be specified"
msgstr "TEXTUL trebuie specificat"

#: app/flatpak-builtins-search.c:338
msgid "No matches found"
msgstr "Nu s-au găsit potriviri"

#: app/flatpak-builtins-uninstall.c:54
msgid "Arch to uninstall"
msgstr "Arhitectură de dezinstalat"

#: app/flatpak-builtins-uninstall.c:55
msgid "Keep ref in local repository"
msgstr "Păstrează ref-ul în depozitul local"

#: app/flatpak-builtins-uninstall.c:56
msgid "Don't uninstall related refs"
msgstr "Nu dezinstala ref-urile legate"

#: app/flatpak-builtins-uninstall.c:57
msgid "Remove files even if running"
msgstr "Elimină fișierele chiar dacă rulează"

#: app/flatpak-builtins-uninstall.c:60
msgid "Uninstall all"
msgstr "Dezinstalează toate"

#: app/flatpak-builtins-uninstall.c:61
msgid "Uninstall unused"
msgstr "Dezinstalează neutilizate"

#: app/flatpak-builtins-uninstall.c:62
msgid "Delete app data"
msgstr "Șterge datele aplicațiilor"

#: app/flatpak-builtins-uninstall.c:141
#, c-format
msgid "Delete data for %s?"
msgstr "Ștergeți datele pentru %s?"

#: app/flatpak-builtins-uninstall.c:220
#, c-format
msgid "Info: applications using the extension %s%s%s branch %s%s%s:\n"
msgstr ""

#: app/flatpak-builtins-uninstall.c:223
#, fuzzy, c-format
msgid "Info: applications using the runtime %s%s%s branch %s%s%s:\n"
msgstr ""
"\n"
"Se caută aplicații și executări"

#: app/flatpak-builtins-uninstall.c:238
#, fuzzy
msgid "Really remove?"
msgstr "Locație la distanță"

#: app/flatpak-builtins-uninstall.c:255
#, fuzzy
msgid "[REF…] - Uninstall applications or runtimes"
msgstr "[REF…] - Actualizează aplicațiile sau executările"

#: app/flatpak-builtins-uninstall.c:264
msgid "Must specify at least one REF, --unused, --all or --delete-data"
msgstr ""
"Trebuie să specificați cel puțin o REF, --unused, --all sau --delete-data"

#: app/flatpak-builtins-uninstall.c:267
msgid "Must not specify REFs when using --all"
msgstr "Nu trebuie să specificați REF-uri când se utilizează --all"

#: app/flatpak-builtins-uninstall.c:270
msgid "Must not specify REFs when using --unused"
msgstr "Nu trebuie să specificați REF-uri când se utilizează --unused"

#: app/flatpak-builtins-uninstall.c:336
#, c-format
msgid ""
"\n"
"These runtimes in installation '%s' are pinned and won't be removed; see "
"flatpak-pin(1):\n"
msgstr ""

#: app/flatpak-builtins-uninstall.c:370
#, c-format
msgid "Nothing unused to uninstall\n"
msgstr "Nimic neutilizat de dezinstalat\n"

#: app/flatpak-builtins-uninstall.c:444
#, fuzzy, c-format
msgid "No installed refs found for ‘%s’"
msgstr "Ref-uri instalate similare găsite pentru „%s”:"

#: app/flatpak-builtins-uninstall.c:447
#, c-format
msgid " with arch ‘%s’"
msgstr ""

#: app/flatpak-builtins-uninstall.c:449
#, c-format
msgid " with branch ‘%s’"
msgstr ""

#: app/flatpak-builtins-uninstall.c:456
#, c-format
msgid "Warning: %s is not installed\n"
msgstr "Avertisment: %s nu este instalat\n"

#: app/flatpak-builtins-uninstall.c:490
#, c-format
msgid "None of the specified refs are installed"
msgstr ""

#: app/flatpak-builtins-uninstall.c:599
#, c-format
msgid "No app data to delete\n"
msgstr ""

#: app/flatpak-builtins-update.c:56
msgid "Arch to update for"
msgstr "Arhitectura pentru care se actualizează"

#: app/flatpak-builtins-update.c:57
msgid "Commit to deploy"
msgstr "Comit de desfășurat"

#: app/flatpak-builtins-update.c:58
msgid "Remove old files even if running"
msgstr "Elimină fișierele vechi chiar dacă rulează"

#: app/flatpak-builtins-update.c:59
msgid "Don't pull, only update from local cache"
msgstr "Nu trage, doar actualizează de la cache-ul local"

#: app/flatpak-builtins-update.c:61
msgid "Don't update related refs"
msgstr "Nu actualiza ref-urile legate"

#: app/flatpak-builtins-update.c:66
msgid "Update appstream for remote"
msgstr "Actualizează appstream pentru depozitul de la distanță"

#: app/flatpak-builtins-update.c:67
msgid "Only update this subpath"
msgstr "Actualizează doar pentru această subcale"

#: app/flatpak-builtins-update.c:90
msgid "[REF…] - Update applications or runtimes"
msgstr "[REF…] - Actualizează aplicațiile sau executările"

#: app/flatpak-builtins-update.c:121
msgid "With --commit, only one REF may be specified"
msgstr "Cu --commit, doar un REF poate fi specificat"

#: app/flatpak-builtins-update.c:162
#, c-format
msgid "Looking for updates…\n"
msgstr "Se caută după actualizări…\n"

#: app/flatpak-builtins-update.c:215
#, c-format
msgid "Unable to update %s: %s\n"
msgstr "Nu se poate actualiza %s: %s\n"

#: app/flatpak-builtins-update.c:274
#, fuzzy, c-format
msgid "Nothing to update.\n"
msgstr "Nimic de făcut.\n"

#: app/flatpak-builtins-utils.c:337
#, fuzzy, c-format
msgid ""
"Remote ‘%s’ found in multiple installations, unable to proceed in non-"
"interactive mode"
msgstr ""
"Ref-ul „%s” a fost găsit în instalări multiple: %s. Trebuie să specificați "
"una."

#: app/flatpak-builtins-utils.c:346
#, c-format
msgid "Remote ‘%s’ found in multiple installations:"
msgstr "Depozitul de la distanță „%s” a fost găsit în instalări multiple:"

#: app/flatpak-builtins-utils.c:347 app/flatpak-builtins-utils.c:442
#: app/flatpak-builtins-utils.c:538 app/flatpak-builtins-utils.c:540
#: app/flatpak-builtins-utils.c:598
msgid "Which do you want to use (0 to abort)?"
msgstr "Pe care doriți să-l utilizați (0 pentru a renunța)?"

#: app/flatpak-builtins-utils.c:349
#, c-format
msgid "No remote chosen to resolve ‘%s’ which exists in multiple installations"
msgstr ""
"Niciun depozit de la distanță nu a fost ales pentru a rezolva „%s” care "
"există în instalări multiple"

#: app/flatpak-builtins-utils.c:358
#, c-format
msgid ""
"Remote \"%s\" not found\n"
"Hint: Use flatpak remote-add to add a remote"
msgstr ""
"Depozitul de la distanță „%s” nu a fost găsit\n"
"Indiciu: Utilizați adăugarea la distanță flatpak pentru a adăuga un depozit "
"de la distanță"

#: app/flatpak-builtins-utils.c:364
#, c-format
msgid "Remote \"%s\" not found in the %s installation"
msgstr "Depozitul de la distanță „%s” nu a fost găsit în instalarea %s"

#: app/flatpak-builtins-utils.c:404
#, c-format
msgid "Multiple refs match ‘%s’, unable to proceed in non-interactive mode"
msgstr ""

#. default to yes on Enter
#: app/flatpak-builtins-utils.c:430
#, c-format
msgid ""
"Found ref ‘%s’ in remote ‘%s’ (%s).\n"
"Use this ref?"
msgstr ""
"A fost găsit ref-ul „%s” în depozitul de la distanță „%s” (%s).\n"
"Utilizați acest ref?"

#: app/flatpak-builtins-utils.c:434 app/flatpak-builtins-utils.c:444
#: app/flatpak-builtins-utils.c:522 app/flatpak-builtins-utils.c:543
#, c-format
msgid "No ref chosen to resolve matches for ‘%s’"
msgstr "Niciun ref ales pentru a rezolva potrivirile pentru „%s”"

#: app/flatpak-builtins-utils.c:440
#, c-format
msgid "Similar refs found for ‘%s’ in remote ‘%s’ (%s):"
msgstr ""
"Ref-uri similare găsite pentru „%s” în depozitul de la distanță „%s” (%s):"

#: app/flatpak-builtins-utils.c:488
#, c-format
msgid ""
"Multiple installed refs match ‘%s’, unable to proceed in non-interactive mode"
msgstr ""

#. default to yes on Enter
#: app/flatpak-builtins-utils.c:518
#, c-format
msgid "Found installed ref ‘%s’ (%s). Is this correct?"
msgstr "S-a găsit instalat ref-ul „%s” (%s). Este corect?"

#: app/flatpak-builtins-utils.c:534
#, c-format
msgid "All of the above"
msgstr "Toate cele de mai sus"

#: app/flatpak-builtins-utils.c:535
#, c-format
msgid "Similar installed refs found for ‘%s’:"
msgstr "Ref-uri instalate similare găsite pentru „%s”:"

#: app/flatpak-builtins-utils.c:579
#, c-format
msgid ""
"Multiple remotes have refs matching ‘%s’, unable to proceed in non-"
"interactive mode"
msgstr ""

#: app/flatpak-builtins-utils.c:597
#, c-format
msgid "Remotes found with refs similar to ‘%s’:"
msgstr "Au fost găsite depozite de la distanță cu ref-uri similare cu „%s”:"

#: app/flatpak-builtins-utils.c:600
#, c-format
msgid "No remote chosen to resolve matches for ‘%s’"
msgstr ""
"Niciun depozit de la distanță nu a fost ales pentru a rezolva potrivirile "
"pentru „%s”"

#: app/flatpak-builtins-utils.c:696 app/flatpak-builtins-utils.c:699
#, c-format
msgid "Updating appstream data for user remote %s"
msgstr ""
"Se actualizează datele appstream pentru depozitul de la distanță al "
"utilizatorului %s"

#: app/flatpak-builtins-utils.c:706 app/flatpak-builtins-utils.c:709
#, c-format
msgid "Updating appstream data for remote %s"
msgstr "Se actualizează datele appstream pentru depozitul de la distanță %s"

#: app/flatpak-builtins-utils.c:717 app/flatpak-builtins-utils.c:719
msgid "Error updating"
msgstr "Eroare la actualizare"

#: app/flatpak-builtins-utils.c:755
#, c-format
msgid "Remote \"%s\" not found"
msgstr "Depozitul de la distanță „%s” nu s-a găsit"

#: app/flatpak-builtins-utils.c:796
#, c-format
msgid "Ambiguous suffix: '%s'."
msgstr "Sufix ambiguu: „%s”."

#. Translators: don't translate the values
#: app/flatpak-builtins-utils.c:798 app/flatpak-builtins-utils.c:813
msgid "Possible values are :s[tart], :m[iddle], :e[nd] or :f[ull]"
msgstr "Valorile posibile sunt: :s[tart], :m[iddle], :e[nd] or :f[ull]"

#: app/flatpak-builtins-utils.c:811
#, c-format
msgid "Invalid suffix: '%s'."
msgstr "Sufix nevalid: „%s”."

#: app/flatpak-builtins-utils.c:846
#, c-format
msgid "Ambiguous column: %s"
msgstr "Coloană ambiguă: %s"

#: app/flatpak-builtins-utils.c:859
#, c-format
msgid "Unknown column: %s"
msgstr "Coloană necunoscută: %s"

#: app/flatpak-builtins-utils.c:917
msgid "Available columns:\n"
msgstr "Coloane disponibile:\n"

#: app/flatpak-builtins-utils.c:927
msgid "Show all columns"
msgstr "Arată toate coloanele"

#: app/flatpak-builtins-utils.c:928
msgid "Show available columns"
msgstr "Arată coloanele disponibile"

#: app/flatpak-builtins-utils.c:931
msgid "Append :s[tart], :m[iddle], :e[nd] or :f[ull] to change ellipsization"
msgstr ""
"Adăugați :s[tart], :m[iddle], :e[nd] or :f[ull] pentru a modifica elipsarea"

#: app/flatpak-builtins-utils.c:1483
#, c-format
msgid "Unknown scheme in sideload location %s"
msgstr ""

#: app/flatpak-cli-transaction.c:96 app/flatpak-cli-transaction.c:102
#, c-format
msgid "Required runtime for %s (%s) found in remote %s\n"
msgstr ""
"Executare necesară pentru %s (%s) găsită în depozitul de la distanță %s\n"

#: app/flatpak-cli-transaction.c:104
msgid "Do you want to install it?"
msgstr "Doriți să o instalați?"

#: app/flatpak-cli-transaction.c:110
#, c-format
msgid "Required runtime for %s (%s) found in remotes:"
msgstr "Executare necesară pentru %s (%s) găsită în depozitele de la distanță:"

#: app/flatpak-cli-transaction.c:112
msgid "Which do you want to install (0 to abort)?"
msgstr "Pe care doriți să o instalați (0 pentru a renunța)?"

#: app/flatpak-cli-transaction.c:132
#, fuzzy, c-format
msgid "Configuring %s as new remote '%s'\n"
msgstr "Se configurează %s ca depozitul de la distanță nou „%s”"

#. default to yes on Enter
#: app/flatpak-cli-transaction.c:139
#, c-format
msgid ""
"The remote '%s', referred to by '%s' at location %s contains additional "
"applications.\n"
"Should the remote be kept for future installations?"
msgstr ""
"Depozitul de la distanță „%s”, referit de „%s” la locația %s conține "
"aplicații suplimentare.\n"
"Ar trebui păstrat depozitul de la distanță pentru instalări viitoare?"

#. default to yes on Enter
#: app/flatpak-cli-transaction.c:147
#, c-format
msgid ""
"The application %s depends on runtimes from:\n"
"  %s\n"
"Configure this as new remote '%s'"
msgstr ""
"Aplicația %s depinde de executări de la:\n"
"  %s\n"
"Configurează aceasta ca depozit de la distanță nou „%s”"

#. Formatted size/remaining time in seconds
#: app/flatpak-cli-transaction.c:321
#, c-format
msgid "%s/s%s%s"
msgstr ""

#. Download progress percentage, use the appropriate
#. percent format for your language
#: app/flatpak-cli-transaction.c:359
#, c-format
msgid "%3d%%"
msgstr ""

#: app/flatpak-cli-transaction.c:414
msgid "Installing…"
msgstr "Se instalează…"

#: app/flatpak-cli-transaction.c:416
#, c-format
msgid "Installing %d/%d…"
msgstr "Se instalează %d/%d…"

#: app/flatpak-cli-transaction.c:421
msgid "Updating…"
msgstr "Se actualizează…"

#: app/flatpak-cli-transaction.c:423
#, c-format
msgid "Updating %d/%d…"
msgstr "Se actualizează %d/%d…"

#: app/flatpak-cli-transaction.c:428
msgid "Uninstalling…"
msgstr "Se dezinstalează…"

#: app/flatpak-cli-transaction.c:430
#, c-format
msgid "Uninstalling %d/%d…"
msgstr "Se dezinstalează %d/%d…"

#: app/flatpak-cli-transaction.c:496 app/flatpak-quiet-transaction.c:161
#, c-format
msgid "Info: %s was skipped"
msgstr "Informații: %s a fost omis"

#: app/flatpak-cli-transaction.c:519
#, fuzzy, c-format
msgid "Warning: %s%s%s already installed"
msgstr "%s este deja instalat"

#: app/flatpak-cli-transaction.c:522
#, fuzzy, c-format
msgid "Error: %s%s%s already installed"
msgstr "%s este deja instalat"

#: app/flatpak-cli-transaction.c:528
#, fuzzy, c-format
msgid "Warning: %s%s%s not installed"
msgstr "Avertisment: %s nu este instalat\n"

#: app/flatpak-cli-transaction.c:531
#, fuzzy, c-format
msgid "Error: %s%s%s not installed"
msgstr "%s/%s/%s nu este instalat"

#: app/flatpak-cli-transaction.c:537
#, fuzzy, c-format
msgid "Warning: %s%s%s needs a later flatpak version"
msgstr "%s are nevoie de o versiune ulterioară flatpak"

#: app/flatpak-cli-transaction.c:540
#, fuzzy, c-format
msgid "Error: %s%s%s needs a later flatpak version"
msgstr "%s are nevoie de o versiune ulterioară flatpak"

#: app/flatpak-cli-transaction.c:546
#, fuzzy
msgid "Warning: Not enough disk space to complete this operation"
msgstr "Nu există destul spațiu pe disc pentru a completa această operație"

#: app/flatpak-cli-transaction.c:548
#, fuzzy
msgid "Error: Not enough disk space to complete this operation"
msgstr "Nu există destul spațiu pe disc pentru a completa această operație"

#: app/flatpak-cli-transaction.c:553
#, fuzzy, c-format
msgid "Warning: %s"
msgstr "Avertisment: "

#: app/flatpak-cli-transaction.c:555
#, fuzzy, c-format
msgid "Error: %s"
msgstr "Eroare:"

#: app/flatpak-cli-transaction.c:570
#, fuzzy, c-format
msgid "Failed to install %s%s%s: "
msgstr "Nu s-a putut face rebase %s la %s: "

#: app/flatpak-cli-transaction.c:577
#, fuzzy, c-format
msgid "Failed to update %s%s%s: "
msgstr "Nu s-a putut să %s %s: "

#: app/flatpak-cli-transaction.c:584
#, fuzzy, c-format
msgid "Failed to install bundle %s%s%s: "
msgstr "Nu s-a putut face rebase %s la %s: "

#: app/flatpak-cli-transaction.c:591
#, fuzzy, c-format
msgid "Failed to uninstall %s%s%s: "
msgstr "Nu s-a putut face rebase %s la %s: "

#: app/flatpak-cli-transaction.c:642
#, c-format
msgid "Authentication required for remote '%s'\n"
msgstr "Autentificarea necesară pentru depozitul de la distanță „%s”\n"

#: app/flatpak-cli-transaction.c:643
msgid "Open browser?"
msgstr "Deschideți navigatorul?"

#: app/flatpak-cli-transaction.c:699
#, c-format
msgid "Login required remote %s (realm %s)\n"
msgstr ""
"Autentificarea este necesară pentru depozitul de la distanță %s (domeniul "
"%s)\n"

#: app/flatpak-cli-transaction.c:704
msgid "Password"
msgstr "Parolă"

#. Only runtimes can be pinned
#: app/flatpak-cli-transaction.c:759
#, fuzzy, c-format
msgid ""
"\n"
"Info: (pinned) runtime %s%s%s branch %s%s%s is end-of-life, in favor of "
"%s%s%s branch %s%s%s\n"
msgstr "Informații: %s este sfârșit-de-viață, în favoarea a %s\n"

#: app/flatpak-cli-transaction.c:765
#, fuzzy, c-format
msgid ""
"\n"
"Info: runtime %s%s%s branch %s%s%s is end-of-life, in favor of %s%s%s branch "
"%s%s%s\n"
msgstr "Informații: %s este sfârșit-de-viață, în favoarea a %s\n"

#: app/flatpak-cli-transaction.c:768
#, fuzzy, c-format
msgid ""
"\n"
"Info: app %s%s%s branch %s%s%s is end-of-life, in favor of %s%s%s branch "
"%s%s%s\n"
msgstr "Informații: %s este sfârșit-de-viață, în favoarea a %s\n"

#. Only runtimes can be pinned
#: app/flatpak-cli-transaction.c:780
#, fuzzy, c-format
msgid ""
"\n"
"Info: (pinned) runtime %s%s%s branch %s%s%s is end-of-life, with reason:\n"
msgstr "Informații: %s este sfârșit-de-viață, cu motivul: %s\n"

#: app/flatpak-cli-transaction.c:786
#, fuzzy, c-format
msgid ""
"\n"
"Info: runtime %s%s%s branch %s%s%s is end-of-life, with reason:\n"
msgstr "Informații: %s este sfârșit-de-viață, cu motivul: %s\n"

#: app/flatpak-cli-transaction.c:789
#, fuzzy, c-format
msgid ""
"\n"
"Info: app %s%s%s branch %s%s%s is end-of-life, with reason:\n"
msgstr "Informații: %s este sfârșit-de-viață, cu motivul: %s\n"

#: app/flatpak-cli-transaction.c:963
#, fuzzy, c-format
msgid "Info: applications using this extension:\n"
msgstr ""
"\n"
"Se caută aplicații și executări"

#: app/flatpak-cli-transaction.c:965
#, fuzzy, c-format
msgid "Info: applications using this runtime:\n"
msgstr ""
"\n"
"Se caută aplicații și executări"

#: app/flatpak-cli-transaction.c:984
msgid "Replace?"
msgstr ""

#: app/flatpak-cli-transaction.c:987 app/flatpak-quiet-transaction.c:247
#, c-format
msgid "Updating to rebased version\n"
msgstr "Se actualizează versiunea rebased\n"

#: app/flatpak-cli-transaction.c:1011
#, c-format
msgid "Failed to rebase %s to %s: "
msgstr "Nu s-a putut face rebase %s la %s: "

#: app/flatpak-cli-transaction.c:1277
#, fuzzy, c-format
msgid "New %s%s%s permissions:"
msgstr "Permisiuni %s noi:"

#: app/flatpak-cli-transaction.c:1279
#, fuzzy, c-format
msgid "%s%s%s permissions:"
msgstr "Permisiuni %s:"

#: app/flatpak-cli-transaction.c:1343
msgid "Warning: "
msgstr "Avertisment: "

#. translators: This is short for operation, the title of a one-char column
#: app/flatpak-cli-transaction.c:1442
msgid "Op"
msgstr "Op"

#. Avoid resizing the download column too much,
#. * by making the title as long as typical content
#.
#: app/flatpak-cli-transaction.c:1458 app/flatpak-cli-transaction.c:1503
msgid "partial"
msgstr "parțial"

#: app/flatpak-cli-transaction.c:1535
msgid "Proceed with these changes to the user installation?"
msgstr "Procedați cu aceste modificări la instalarea utilizatorului?"

#: app/flatpak-cli-transaction.c:1537
msgid "Proceed with these changes to the system installation?"
msgstr "Procedați cu aceste modificări la instalarea sistemului?"

#: app/flatpak-cli-transaction.c:1539
#, c-format
msgid "Proceed with these changes to the %s?"
msgstr "Procedați cu aceste modificări la %s?"

#: app/flatpak-cli-transaction.c:1711
msgid "Changes complete."
msgstr "Modificări complete."

#: app/flatpak-cli-transaction.c:1713
msgid "Uninstall complete."
msgstr "Dezinstalare completă."

#: app/flatpak-cli-transaction.c:1715
msgid "Installation complete."
msgstr "Instalare completă."

#: app/flatpak-cli-transaction.c:1717
msgid "Updates complete."
msgstr "Actualizări complete."

#. For updates/!stop_on_first_error we already printed all errors so we make up
#. a different one.
#: app/flatpak-cli-transaction.c:1750
msgid "There were one or more errors"
msgstr "Au fost una sau mai multe erori"

#. translators: please keep the leading space
#: app/flatpak-main.c:76
msgid " Manage installed applications and runtimes"
msgstr " Gestionează aplicațiile și executările instalate"

#: app/flatpak-main.c:77
msgid "Install an application or runtime"
msgstr "Instalează o aplicație sau executare"

#: app/flatpak-main.c:78
msgid "Update an installed application or runtime"
msgstr "Actualizează o aplicație sau executare instalată"

#: app/flatpak-main.c:81
msgid "Uninstall an installed application or runtime"
msgstr "Dezinstalează o aplicație sau executare instalată"

#: app/flatpak-main.c:84
msgid "Mask out updates and automatic installation"
msgstr "Maschează actualizările și instalarea automată"

#: app/flatpak-main.c:85
msgid "Pin a runtime to prevent automatic removal"
msgstr ""

#: app/flatpak-main.c:86
msgid "List installed apps and/or runtimes"
msgstr "Listează aplicațiile și/sau executările instalate"

#: app/flatpak-main.c:87
msgid "Show info for installed app or runtime"
msgstr "Arată informațiile pentru aplicația sau executarea instalată"

#: app/flatpak-main.c:88
msgid "Show history"
msgstr "Arată istoricul"

#: app/flatpak-main.c:89
msgid "Configure flatpak"
msgstr "Configurează flatpak"

#: app/flatpak-main.c:90
msgid "Repair flatpak installation"
msgstr "Repară instalarea flatpak"

#: app/flatpak-main.c:91
msgid "Put applications or runtimes onto removable media"
msgstr "Plasează aplicațiile sau executările pe medii detașabile"

#: app/flatpak-main.c:92
msgid "Install flatpaks that are part of the operating system"
msgstr ""

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:95
#, fuzzy
msgid ""
"\n"
" Find applications and runtimes"
msgstr ""
"\n"
"Se caută aplicații și executări"

#: app/flatpak-main.c:96
msgid "Search for remote apps/runtimes"
msgstr "Caută pentru aplicații/executări de la distanță"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:99
#, fuzzy
msgid ""
"\n"
" Manage running applications"
msgstr ""
"\n"
"Se rulează aplicațiile"

#: app/flatpak-main.c:100
msgid "Run an application"
msgstr "Rulează o aplicație"

#: app/flatpak-main.c:101
msgid "Override permissions for an application"
msgstr "Suprascrie permisiunile pentru o aplicație"

#: app/flatpak-main.c:102
msgid "Specify default version to run"
msgstr "Specifică versiunea implicită de rulat"

#: app/flatpak-main.c:103
msgid "Enter the namespace of a running application"
msgstr "Introduceți un spațiu de nume a unei aplicații care rulează"

#: app/flatpak-main.c:104
msgid "Enumerate running applications"
msgstr "Enumeră aplicațiile care rulează"

#: app/flatpak-main.c:105
msgid "Stop a running application"
msgstr "Oprește o aplicație care rulează"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:108
msgid ""
"\n"
" Manage file access"
msgstr ""
"\n"
"Gestionează accesul fișierelor"

#: app/flatpak-main.c:109
msgid "List exported files"
msgstr "Listează fișierele exportate"

#: app/flatpak-main.c:110
msgid "Grant an application access to a specific file"
msgstr "Acordă unei aplicații acces la un fișier specific"

#: app/flatpak-main.c:111
msgid "Revoke access to a specific file"
msgstr "Revocă accesul la un fișier specific"

#: app/flatpak-main.c:112
msgid "Show information about a specific file"
msgstr "Arată informațiile despre un fișier specific"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:116
msgid ""
"\n"
" Manage dynamic permissions"
msgstr ""
"\n"
"Gestionează permisiunile dinamice"

#: app/flatpak-main.c:117
msgid "List permissions"
msgstr "Listează permisiunile"

#: app/flatpak-main.c:118
msgid "Remove item from permission store"
msgstr "Elimină elementul de la stocarea permisiunilor"

#: app/flatpak-main.c:120
msgid "Set permissions"
msgstr "Stabilește permisiunile"

#: app/flatpak-main.c:121
msgid "Show app permissions"
msgstr "Arată permisiunile aplicației"

#: app/flatpak-main.c:122
msgid "Reset app permissions"
msgstr "Restabilește permisiunile aplicației"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:125
msgid ""
"\n"
" Manage remote repositories"
msgstr ""
"\n"
"Gestionează depozitele de la distanță"

#: app/flatpak-main.c:126
msgid "List all configured remotes"
msgstr "Listează toate depozitele de la distanță configurate"

#: app/flatpak-main.c:127
msgid "Add a new remote repository (by URL)"
msgstr "Adaugă un depozit de la distanță nou (după URL)"

#: app/flatpak-main.c:128
msgid "Modify properties of a configured remote"
msgstr "Modifică proprietățile unui depozit de la distanță configurat"

#: app/flatpak-main.c:129
msgid "Delete a configured remote"
msgstr "Șterge un depozit de la distanță configurat"

#: app/flatpak-main.c:131
msgid "List contents of a configured remote"
msgstr "Listează conținutul unui depozit de la distanță configurat"

#: app/flatpak-main.c:132
msgid "Show information about a remote app or runtime"
msgstr "Arată informațiile despre o aplicație sau executare de la distanță"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:135
msgid ""
"\n"
" Build applications"
msgstr ""
"\n"
"Generează aplicații"

#: app/flatpak-main.c:136
msgid "Initialize a directory for building"
msgstr "Inițializează un director pentru generare"

#: app/flatpak-main.c:137
msgid "Run a build command inside the build dir"
msgstr "Rulează o comandă de generare înăuntrul directorului de generare"

#: app/flatpak-main.c:138
msgid "Finish a build dir for export"
msgstr "Termină un director de generare pentru exportare"

#: app/flatpak-main.c:139
msgid "Export a build dir to a repository"
msgstr "Exportă un director de generare la un depozit"

#: app/flatpak-main.c:140
msgid "Create a bundle file from a ref in a local repository"
msgstr "Creează un fișier pachet de la o ref într-un depozit local"

#: app/flatpak-main.c:141
msgid "Import a bundle file"
msgstr "Importă un fișier pachet"

#: app/flatpak-main.c:142
msgid "Sign an application or runtime"
msgstr "Semnează o aplicație sau o executare"

#: app/flatpak-main.c:143
msgid "Update the summary file in a repository"
msgstr "Actualizează fișierul rezumat într-un depozit"

#: app/flatpak-main.c:144
msgid "Create new commit based on existing ref"
msgstr "Creează un comit nou bazat pe o ref existentă"

#: app/flatpak-main.c:145
msgid "Show information about a repo"
msgstr "Arată informațiile despre un depozit"

#: app/flatpak-main.c:162
msgid "Show debug information, -vv for more detail"
msgstr "Arată informațiile de depanare, -vv pentru mai multe detalii"

#: app/flatpak-main.c:163
msgid "Show OSTree debug information"
msgstr "Arată informațiile de depanare OSTree"

#: app/flatpak-main.c:169
msgid "Print version information and exit"
msgstr "Tipărește informațiile de versiune și ieși"

#: app/flatpak-main.c:170
msgid "Print default arch and exit"
msgstr "Tipărește arhitectura implicită și ieși"

#: app/flatpak-main.c:171
msgid "Print supported arches and exit"
msgstr "Tipărește arhitecturile suportate și ieși"

#: app/flatpak-main.c:172
msgid "Print active gl drivers and exit"
msgstr "Tipărește driverele gl active și ieși"

#: app/flatpak-main.c:173
msgid "Print paths for system installations and exit"
msgstr "Tipărește căile pentru instalările de sistem și ieși"

#: app/flatpak-main.c:174
msgid "Print the updated environment needed to run flatpaks"
msgstr ""

#: app/flatpak-main.c:175
msgid "Only include the system installation with --print-updated-env"
msgstr ""

#: app/flatpak-main.c:180
msgid "Work on the user installation"
msgstr "Lucrează la instalarea utilizatorului"

#: app/flatpak-main.c:181
msgid "Work on the system-wide installation (default)"
msgstr "Lucrează la instalarea la nivel de sistem (implicit)"

#: app/flatpak-main.c:182
msgid "Work on a non-default system-wide installation"
msgstr "Lucrează la o instalarea la nivel de sistem neimplicită"

#: app/flatpak-main.c:212
msgid "Builtin Commands:"
msgstr "Comenzi integrate:"

#: app/flatpak-main.c:298
#, c-format
msgid ""
"Note that the directories %s are not in the search path set by the "
"XDG_DATA_DIRS environment variable, so applications installed by Flatpak may "
"not appear on your desktop until the session is restarted."
msgstr ""
"Observați că directoarele %s nu sunt în calea de căutare stabilită de "
"variabila de mediu XDG_DATA_DIRS, deci aplicațiile instalate de Flatpak pot "
"să nu apară pe desktop până ce sesiunea este repornită."

#: app/flatpak-main.c:312
#, c-format
msgid ""
"Note that the directory %s is not in the search path set by the "
"XDG_DATA_DIRS environment variable, so applications installed by Flatpak may "
"not appear on your desktop until the session is restarted."
msgstr ""
"Observați că directorul %s nu este în calea de căutare stabilită de "
"variabila de mediu XDG_DATA_DIRS, deci aplicațiile instalate de Flapak pot "
"să nu apară pe desktop până ce sesiunea este repornită."

#: app/flatpak-main.c:381
msgid ""
"Refusing to operate under sudo with --user. Omit sudo to operate on the user "
"installation, or use a root shell to operate on the root user's installation."
msgstr ""

#: app/flatpak-main.c:453
msgid ""
"Multiple installations specified for a command that works on one installation"
msgstr ""
"Instalări multiple specificate pentru o comandă care funcționează pe o "
"instalare"

#: app/flatpak-main.c:504 app/flatpak-main.c:697
#, c-format
msgid "See '%s --help'"
msgstr "Consultați „%s --help”"

#: app/flatpak-main.c:706
#, c-format
msgid "'%s' is not a flatpak command. Did you mean '%s%s'?"
msgstr "„%s” nu este o comandă flatpak. Ați vrut să spuneți „%s%s”?"

#: app/flatpak-main.c:709
#, c-format
msgid "'%s' is not a flatpak command"
msgstr "„%s” nu este o comandă flatpak"

#: app/flatpak-main.c:824
msgid "No command specified"
msgstr "Nu s-a specificat nicio comandă"

#: app/flatpak-main.c:980
msgid "error:"
msgstr "error:"

#: app/flatpak-quiet-transaction.c:77
#, c-format
msgid "Installing %s\n"
msgstr "Se instalează %s\n"

#: app/flatpak-quiet-transaction.c:81
#, c-format
msgid "Updating %s\n"
msgstr "Se actualizează %s\n"

#: app/flatpak-quiet-transaction.c:85
#, c-format
msgid "Uninstalling %s\n"
msgstr "Se dezinstalează %s\n"

#: app/flatpak-quiet-transaction.c:107
#, fuzzy, c-format
msgid "Warning: Failed to install %s: %s\n"
msgstr "%s Nu s-a putut %s %s: %s\n"

#: app/flatpak-quiet-transaction.c:110
#, fuzzy, c-format
msgid "Error: Failed to install %s: %s\n"
msgstr "Eroare la reinstalarea %s: %s\n"

#: app/flatpak-quiet-transaction.c:116
#, fuzzy, c-format
msgid "Warning: Failed to update %s: %s\n"
msgstr "Nu se poate actualiza %s: %s\n"

#: app/flatpak-quiet-transaction.c:119
#, fuzzy, c-format
msgid "Error: Failed to update %s: %s\n"
msgstr "Nu se poate actualiza %s: %s\n"

#: app/flatpak-quiet-transaction.c:125
#, fuzzy, c-format
msgid "Warning: Failed to install bundle %s: %s\n"
msgstr "Nu s-a putut face rebase %s la %s: %s\n"

#: app/flatpak-quiet-transaction.c:128
#, fuzzy, c-format
msgid "Error: Failed to install bundle %s: %s\n"
msgstr "Eroare la reinstalarea %s: %s\n"

#: app/flatpak-quiet-transaction.c:134
#, fuzzy, c-format
msgid "Warning: Failed to uninstall %s: %s\n"
msgstr "%s Nu s-a putut %s %s: %s\n"

#: app/flatpak-quiet-transaction.c:137
#, fuzzy, c-format
msgid "Error: Failed to uninstall %s: %s\n"
msgstr "Eroare la reinstalarea %s: %s\n"

#: app/flatpak-quiet-transaction.c:166 common/flatpak-dir.c:11475
#, c-format
msgid "%s already installed"
msgstr "%s este deja instalat"

#: app/flatpak-quiet-transaction.c:168 common/flatpak-dir.c:3622
#: common/flatpak-dir.c:4321 common/flatpak-dir.c:16968
#: common/flatpak-dir.c:17258 common/flatpak-dir-utils.c:166
#: common/flatpak-dir-utils.c:259 common/flatpak-transaction.c:2736
#: common/flatpak-transaction.c:2791
#, c-format
msgid "%s not installed"
msgstr "%s nu este instalat"

#: app/flatpak-quiet-transaction.c:170
#, c-format
msgid "%s needs a later flatpak version"
msgstr "%s are nevoie de o versiune ulterioară flatpak"

#: app/flatpak-quiet-transaction.c:172
msgid "Not enough disk space to complete this operation"
msgstr "Nu există destul spațiu pe disc pentru a completa această operație"

#: app/flatpak-quiet-transaction.c:239
#, c-format
msgid "Info: %s is end-of-life, in favor of %s\n"
msgstr "Informații: %s este sfârșit-de-viață, în favoarea a %s\n"

#: app/flatpak-quiet-transaction.c:241
#, c-format
msgid "Info: %s is end-of-life, with reason: %s\n"
msgstr "Informații: %s este sfârșit-de-viață, cu motivul: %s\n"

#: app/flatpak-quiet-transaction.c:251
#, c-format
msgid "Failed to rebase %s to %s: %s\n"
msgstr "Nu s-a putut face rebase %s la %s: %s\n"

#: common/flatpak-auth.c:58
#, c-format
msgid "No authenticator configured for remote `%s`"
msgstr ""
"Nu s-a configurat niciun autentificator pentru depozitul de la distanță „%s”"

#: common/flatpak-context.c:637 common/flatpak-context.c:649
#, fuzzy, c-format
msgid "Invalid permission syntax: %s"
msgstr "Nume de autentificator %s nevalid"

#: common/flatpak-context.c:1207
#, c-format
msgid "Unknown share type %s, valid types are: %s"
msgstr "Tip de partajare necunoscut %s, tipurile valide sunt: %s"

#: common/flatpak-context.c:1228
#, c-format
msgid "Unknown policy type %s, valid types are: %s"
msgstr "Tip de politică necunoscută %s, tipurile valide sunt: %s"

#: common/flatpak-context.c:1266
#, c-format
msgid "Invalid dbus name %s"
msgstr "Nume dbus nevalid %s"

#: common/flatpak-context.c:1279
#, c-format
msgid "Unknown socket type %s, valid types are: %s"
msgstr "Tip de soclu necunoscut %s, tipurile valide sunt: %s"

#: common/flatpak-context.c:1294
#, c-format
msgid "Unknown device type %s, valid types are: %s"
msgstr "Tip de dispozitiv necunoscut %s, tipurile valide sunt: %s"

#: common/flatpak-context.c:1308
#, c-format
msgid "Unknown feature type %s, valid types are: %s"
msgstr "Tip de funcționalitate necunoscut %s, tipurile valide sunt: %s"

#: common/flatpak-context.c:1840
#, c-format
msgid "Filesystem location \"%s\" contains \"..\""
msgstr ""

#: common/flatpak-context.c:1882
#, c-format
msgid ""
"--filesystem=/ is not available, use --filesystem=host for a similar result"
msgstr ""

#: common/flatpak-context.c:1916
#, fuzzy, c-format
msgid ""
"Unknown filesystem location %s, valid locations are: host, host-os, host-"
"etc, host-root, home, xdg-*[/…], ~/dir, /dir"
msgstr ""
"Locație de sistem de fișiere necunoscută %s locațiile valide sunt: host-os, "
"host-etc, home, xdg-*[/…], ~/dir, /dir"

#: common/flatpak-context.c:2015
#, fuzzy, c-format
msgid "Invalid syntax for %s: %s"
msgstr "Nume nevalid %s: %s"

#: common/flatpak-context.c:2142
#, c-format
msgid "fallback-x11 can not be conditional"
msgstr ""

#: common/flatpak-context.c:2318
#, c-format
msgid "Invalid env format %s"
msgstr "Format env nevalid %s"

#: common/flatpak-context.c:2399
#, c-format
msgid "Environment variable name must not contain '=': %s"
msgstr ""

#: common/flatpak-context.c:2527 common/flatpak-context.c:2535
#, c-format
msgid "--add-policy arguments must be in the form SUBSYSTEM.KEY=VALUE"
msgstr ""
"Argumentele --add-policy trebuie să fie sub forma CHEIE.SUBSISTEM=VALOARE"

#: common/flatpak-context.c:2542
#, c-format
msgid "--add-policy values can't start with \"!\""
msgstr "Valorile --add-policy nu pot începe cu „!”"

#: common/flatpak-context.c:2567 common/flatpak-context.c:2575
#, c-format
msgid "--remove-policy arguments must be in the form SUBSYSTEM.KEY=VALUE"
msgstr ""
"Argumentele --remove-policy trebuie să fie sub forma CHEIE.SUBSISTEM=VALOARE"

#: common/flatpak-context.c:2582
#, c-format
msgid "--remove-policy values can't start with \"!\""
msgstr "Valorile --remove-policy nu pot începe cu „!”"

#: common/flatpak-context.c:2657
msgid "Share with host"
msgstr "Partajează cu gazda"

#: common/flatpak-context.c:2657 common/flatpak-context.c:2658
msgid "SHARE"
msgstr "PARTAJEAZĂ"

#: common/flatpak-context.c:2658
msgid "Unshare with host"
msgstr "Anulați partajarea cu gazda"

#: common/flatpak-context.c:2659
msgid "Require conditions to be met for a subsystem to get shared"
msgstr ""

#: common/flatpak-context.c:2659
msgid "SHARE:CONDITION"
msgstr ""

#: common/flatpak-context.c:2660
msgid "Expose socket to app"
msgstr "Expune soclul la aplicație"

#: common/flatpak-context.c:2660 common/flatpak-context.c:2661
msgid "SOCKET"
msgstr "SOCLU"

#: common/flatpak-context.c:2661
msgid "Don't expose socket to app"
msgstr "Nu expune soclul la aplicație"

#: common/flatpak-context.c:2662
msgid "Require conditions to be met for a socket to get exposed"
msgstr ""

#: common/flatpak-context.c:2662
msgid "SOCKET:CONDITION"
msgstr ""

#: common/flatpak-context.c:2663
msgid "Expose device to app"
msgstr "Expune dispozitivul la aplicație"

#: common/flatpak-context.c:2663 common/flatpak-context.c:2664
msgid "DEVICE"
msgstr "DISPOZITIV"

#: common/flatpak-context.c:2664
msgid "Don't expose device to app"
msgstr "Nu expune dispozitivul la aplicație"

#: common/flatpak-context.c:2665
msgid "Require conditions to be met for a device to get exposed"
msgstr ""

#: common/flatpak-context.c:2665
msgid "DEVICE:CONDITION"
msgstr ""

#: common/flatpak-context.c:2666
msgid "Allow feature"
msgstr "Permite funcționalitatea"

#: common/flatpak-context.c:2666 common/flatpak-context.c:2667
msgid "FEATURE"
msgstr "FUNCȚIONALITATE"

#: common/flatpak-context.c:2667
msgid "Don't allow feature"
msgstr "Nu permite funcționalitatea"

#: common/flatpak-context.c:2668
msgid "Require conditions to be met for a feature to get allowed"
msgstr ""

#: common/flatpak-context.c:2668
msgid "FEATURE:CONDITION"
msgstr ""

#: common/flatpak-context.c:2669
msgid "Expose filesystem to app (:ro for read-only)"
msgstr "Expune sistemul de fișiere la aplicație (:ro pentru doar citire)"

#: common/flatpak-context.c:2669
msgid "FILESYSTEM[:ro]"
msgstr "SISTEMFIȘIERE[:ro]"

#: common/flatpak-context.c:2670
msgid "Don't expose filesystem to app"
msgstr "Nu expune sistemul de fișiere la aplicație"

#: common/flatpak-context.c:2670
msgid "FILESYSTEM"
msgstr "SISTEMFIȘIERE"

#: common/flatpak-context.c:2671
msgid "Set environment variable"
msgstr "Stabilește variabila de mediu"

#: common/flatpak-context.c:2671
msgid "VAR=VALUE"
msgstr "VAR=VALOARE"

#: common/flatpak-context.c:2672
msgid "Read environment variables in env -0 format from FD"
msgstr ""

#: common/flatpak-context.c:2673
#, fuzzy
msgid "Remove variable from environment"
msgstr "Elimină elementul de la stocarea permisiunilor"

#: common/flatpak-context.c:2673
#, fuzzy
msgid "VAR"
msgstr "VAL"

#: common/flatpak-context.c:2674
msgid "Allow app to own name on the session bus"
msgstr "Permite aplicației să posede un nume la magistrala sesiunii"

#: common/flatpak-context.c:2674 common/flatpak-context.c:2675
#: common/flatpak-context.c:2676 common/flatpak-context.c:2677
#: common/flatpak-context.c:2678 common/flatpak-context.c:2679
#: common/flatpak-context.c:2680
msgid "DBUS_NAME"
msgstr "NUME_DBUS"

#: common/flatpak-context.c:2675
msgid "Allow app to talk to name on the session bus"
msgstr "Permite aplicației să vorbească numelui la magistrala sesiunii"

#: common/flatpak-context.c:2676
msgid "Don't allow app to talk to name on the session bus"
msgstr "Nu permite aplicației să vorbească numelui la magistrala sesiunii"

#: common/flatpak-context.c:2677
msgid "Allow app to own name on the system bus"
msgstr "Permite aplicației să posede un nume la magistrala sistemului"

#: common/flatpak-context.c:2678
msgid "Allow app to talk to name on the system bus"
msgstr "Permite aplicației să vorbească numelui la magistrala sistemului"

#: common/flatpak-context.c:2679
msgid "Don't allow app to talk to name on the system bus"
msgstr "Nu permite aplicației să vorbească numelui la magistrala sistemului"

#: common/flatpak-context.c:2680
#, fuzzy
msgid "Allow app to own name on the a11y bus"
msgstr "Permite aplicației să posede un nume la magistrala sistemului"

#: common/flatpak-context.c:2681
msgid "Add generic policy option"
msgstr "Adaugă o opțiune de politică generică"

#: common/flatpak-context.c:2681 common/flatpak-context.c:2682
msgid "SUBSYSTEM.KEY=VALUE"
msgstr "CHEIE.SUBSISTEM=VALOARE"

#: common/flatpak-context.c:2682
msgid "Remove generic policy option"
msgstr "Elimină opțiunea de politică generică"

#: common/flatpak-context.c:2683
msgid "Add USB device to enumerables"
msgstr ""

#: common/flatpak-context.c:2683 common/flatpak-context.c:2684
msgid "VENDOR_ID:PRODUCT_ID"
msgstr ""

#: common/flatpak-context.c:2684
msgid "Add USB device to hidden list"
msgstr ""

#: common/flatpak-context.c:2685
msgid "A list of USB devices that are enumerable"
msgstr ""

#: common/flatpak-context.c:2685
msgid "LIST"
msgstr ""

#: common/flatpak-context.c:2686
msgid "File containing a list of USB devices to make enumerable"
msgstr ""

#: common/flatpak-context.c:2686 common/flatpak-context.c:2687
msgid "FILENAME"
msgstr "NUME FIȘIER"

#: common/flatpak-context.c:2687
msgid "Persist home directory subpath"
msgstr "Persistă subcalea directorului personal"

#. This is not needed/used anymore, so hidden, but we accept it for backwards compat
#: common/flatpak-context.c:2689
msgid "Don't require a running session (no cgroups creation)"
msgstr "Nu necesită o sesiune care rulează (nicio creare de cgroups)"

#: common/flatpak-context.c:3718
#, c-format
msgid "Not replacing \"%s\" with tmpfs: %s"
msgstr ""

#: common/flatpak-context.c:3726
#, c-format
msgid "Not sharing \"%s\" with sandbox: %s"
msgstr ""

#. Even if the error is one that we would normally silence, like
#. * the path not existing, it seems reasonable to make more of a fuss
#. * about the home directory not existing or otherwise being unusable,
#. * so this is intentionally not using cannot_export()
#: common/flatpak-context.c:3828
#, c-format
msgid "Not allowing home directory access: %s"
msgstr ""

#: common/flatpak-context.c:4062
#, fuzzy, c-format
msgid "Unable to provide a temporary home directory in the sandbox: %s"
msgstr "Nu se poate crea directorul de implementare"

#: common/flatpak-dir.c:442
#, c-format
msgid "Configured collection ID ‘%s’ not in summary file"
msgstr ""

#: common/flatpak-dir.c:587
#, c-format
msgid "Unable to load summary from remote %s: %s"
msgstr "Nu se poate încărca rezumatul de la depozitul de la distanță %s: %s"

#: common/flatpak-dir.c:764 common/flatpak-dir.c:800 common/flatpak-dir.c:906
#, c-format
msgid "No such ref '%s' in remote %s"
msgstr "Niciun astfel de ref „%s” în depozitul de la distanță %s"

#: common/flatpak-dir.c:891 common/flatpak-dir.c:1051 common/flatpak-dir.c:1080
#: common/flatpak-dir.c:1092
#, fuzzy, c-format
msgid "No entry for %s in remote %s summary flatpak cache"
msgstr ""
"Nicio intrare pentru %s în cache-ul flatpak al rezumatului de la distanță "
"„%s” "

#: common/flatpak-dir.c:1069
#, c-format
msgid "No summary or Flatpak cache available for remote %s"
msgstr ""
"Niciun rezumat sau cache Flatpak disponibil pentru depozitul de la distanță "
"%s"

#: common/flatpak-dir.c:1097
#, fuzzy, c-format
msgid "Missing xa.data in summary for remote %s"
msgstr "Niciun rezumat oci cache-uit pentru depozitul de la distanță „%s”"

#: common/flatpak-dir.c:1103 common/flatpak-dir.c:1546
#, fuzzy, c-format
msgid "Unsupported summary version %d for remote %s"
msgstr "Niciun rezumat cache-uit pentru depozitul de la distanță „%s”"

#: common/flatpak-dir.c:1200
msgid "Remote OCI index has no registry uri"
msgstr "Indexul OCI de la distanță nu are niciun uri de registru"

#: common/flatpak-dir.c:1261
#, c-format
msgid "Couldn't find ref %s in remote %s"
msgstr "Nu s-a putut găsi ref-ul %s în depozitul de la distanță %s"

#: common/flatpak-dir.c:1288 common/flatpak-dir.c:1381
#, fuzzy, c-format
msgid "Commit has no requested ref ‘%s’ in ref binding metadata (found: ‘%s’)"
msgstr ""
"Comitul nu are nicio ref „%s” cerută în datele meta de legare a ref-ului"

#: common/flatpak-dir.c:1413
#, fuzzy, c-format
msgid "Configured collection ID ‘%s’ not in binding metadata"
msgstr ""
"Comitul nu are nicio ref „%s” cerută în datele meta de legare a ref-ului"

#: common/flatpak-dir.c:1449 common/flatpak-dir.c:5645
#, c-format
msgid "Couldn't find latest checksum for ref %s in remote %s"
msgstr ""
"Nu s-a putut găsi suma de control cea mai recentă pentru ref-ul %s în "
"depozitul de la distanță %s"

#: common/flatpak-dir.c:1516 common/flatpak-dir.c:1552
#, fuzzy, c-format
msgid "No entry for %s in remote %s summary flatpak sparse cache"
msgstr ""
"Nicio intrare pentru %s în cache-ul rar flatpak de rezumat de la distanță "

#: common/flatpak-dir.c:2540
#, c-format
msgid "Commit metadata for %s not matching expected metadata"
msgstr ""
"Datele meta de comit pentru %s nu se potrivesc cu datele meta așteptate"

#: common/flatpak-dir.c:2823
msgid "Unable to connect to system bus"
msgstr "Nu se poate conecta la magistrala sistemului"

#: common/flatpak-dir.c:3419
msgid "User installation"
msgstr "Instalarea utilizatorului"

#: common/flatpak-dir.c:3426
#, c-format
msgid "System (%s) installation"
msgstr "Instalare (%s) de sistem"

#: common/flatpak-dir.c:3472
#, c-format
msgid "No overrides found for %s"
msgstr "Nicio suprascriere găsită pentru %s"

#: common/flatpak-dir.c:3625
#, c-format
msgid "%s (commit %s) not installed"
msgstr "%s (comitul %s) nu este instalat"

#: common/flatpak-dir.c:4650
#, c-format
msgid "Error parsing system flatpakrepo file for %s: %s"
msgstr "Eroare la parsarea depozitului flatpak de sistem pentru %s: %s"

#: common/flatpak-dir.c:4735
#, c-format
msgid "While opening repository %s: "
msgstr "În timpul deschiderii depozitului %s: "

#: common/flatpak-dir.c:5004
#, c-format
msgid "The config key %s is not set"
msgstr "Cheia de configurare %s nu este stabilită"

#: common/flatpak-dir.c:5140
#, fuzzy, c-format
msgid "No current %s pattern matching %s"
msgstr "Nu există o mască curentă care se potrivește cu %s"

#: common/flatpak-dir.c:5422
msgid "No appstream commit to deploy"
msgstr "Niciun comit de appstream de implementat"

#: common/flatpak-dir.c:5941 common/flatpak-dir.c:7266
#: common/flatpak-dir.c:10881 common/flatpak-dir.c:11618
msgid "Can't pull from untrusted non-gpg verified remote"
msgstr ""
"Nu se poate trage de la depozitul de la distanță verificat ne-gpg în care nu "
"este încredere"

#: common/flatpak-dir.c:6376 common/flatpak-dir.c:6591
msgid "Extra data not supported for non-gpg-verified local system installs"
msgstr ""
"Datele extra nu sunt suportate pentru instalări de sistem locale "
"neverificate-gpg"

#: common/flatpak-dir.c:6415 common/flatpak-dir.c:6782
#, c-format
msgid "Invalid checksum for extra data uri %s"
msgstr "Sumă de control nevalidă pentru uri-ul de date extra %s"

#: common/flatpak-dir.c:6424
#, c-format
msgid "Empty name for extra data uri %s"
msgstr "Nume gol pentru uri-ul de date extra %s"

#: common/flatpak-dir.c:6432
#, c-format
msgid "Unsupported extra data uri %s"
msgstr "Uri de date extra %s nesuportat"

#: common/flatpak-dir.c:6461
#, c-format
msgid "Failed to load local extra-data %s: %s"
msgstr "Nu s-au putut încărca datele extra locale %s: %s"

#: common/flatpak-dir.c:6469
#, c-format
msgid "Wrong size for extra-data %s"
msgstr "Dimensiune greșită pentru datele extra %s"

#: common/flatpak-dir.c:6488
#, c-format
msgid "While downloading %s: "
msgstr "În timpul descărcării %s: "

#: common/flatpak-dir.c:6498
#, c-format
msgid "Wrong size for extra data %s"
msgstr "Dimensiune greșită pentru datele extra %s"

#: common/flatpak-dir.c:6507
#, c-format
msgid "Invalid checksum for extra data %s"
msgstr "Sumă de control nevalidă pentru datele extra %s"

#: common/flatpak-dir.c:7096 common/flatpak-dir.c:7349
#, c-format
msgid "While pulling %s from remote %s: "
msgstr "În timpul tragerii %s de la depozitul de la distanță %s: "

#: common/flatpak-dir.c:7290 common/flatpak-repo-utils.c:3886
msgid "GPG signatures found, but none are in trusted keyring"
msgstr ""
"S-au găsit semnăturile GPG, dar niciuna nu este într-un inel de chei de "
"încredere"

#: common/flatpak-dir.c:7307
#, c-format
msgid "Commit for ‘%s’ has no ref binding"
msgstr "Comitul pentru „%s” nu are nicio legătură ref"

#: common/flatpak-dir.c:7312
#, c-format
msgid "Commit for ‘%s’ is not in expected bound refs: %s"
msgstr "Comitul pentru „%s” nu se află în ref-urile de legătură așteptate: %s"

#: common/flatpak-dir.c:7488
#, fuzzy
msgid "Only applications can be made current"
msgstr ""
"\n"
"Se caută aplicații și executări"

#: common/flatpak-dir.c:8192
msgid "Not enough memory"
msgstr "Nu există memorie suficientă"

#: common/flatpak-dir.c:8211
msgid "Failed to read from exported file"
msgstr "Nu s-a putut citi de la fișierul exportat"

#: common/flatpak-dir.c:8401
msgid "Error reading mimetype xml file"
msgstr "Eroare la citirea fișierul xml de tip mime"

#: common/flatpak-dir.c:8406
msgid "Invalid mimetype xml file"
msgstr "Fișier xml de tip mime nevalid"

#: common/flatpak-dir.c:8492
#, c-format
msgid "D-Bus service file '%s' has wrong name"
msgstr "Fișierul de serviciu D-Bus „%s” are numele greșit"

#: common/flatpak-dir.c:8647
#, fuzzy, c-format
msgid "Invalid Exec argument %s"
msgstr "Argument require-flatpak nevalid %s"

#: common/flatpak-dir.c:9115
msgid "While getting detached metadata: "
msgstr "În timpul obținerii datelor meta detașate: "

#: common/flatpak-dir.c:9120 common/flatpak-dir.c:9125
#: common/flatpak-dir.c:9129
msgid "Extra data missing in detached metadata"
msgstr "Datele extra care lipsesc în datele meta detașate"

#: common/flatpak-dir.c:9133
msgid "While creating extradir: "
msgstr "În timpul creării directorului extra: "

#: common/flatpak-dir.c:9154 common/flatpak-dir.c:9187
msgid "Invalid checksum for extra data"
msgstr "Sumă de control nevalidă pentru datele extra"

#: common/flatpak-dir.c:9183
msgid "Wrong size for extra data"
msgstr "Dimensiune greșită pentru datele extra"

#: common/flatpak-dir.c:9196
#, c-format
msgid "While writing extra data file '%s': "
msgstr "În timp ce se scrie fișierul de date extra „%s”: "

#: common/flatpak-dir.c:9204
#, c-format
msgid "Extra data %s missing in detached metadata"
msgstr "Datele extra %s lipsesc în datele extra detașate"

#: common/flatpak-dir.c:9278
#, fuzzy, c-format
msgid "Unable to get runtime key from metadata"
msgstr "Utilizează fișierul alternativ pentru datele meta"

#: common/flatpak-dir.c:9402
#, c-format
msgid "apply_extra script failed, exit status %d"
msgstr "scriptul apply_extra a eșuat, starea de ieșire %d"

#. Translators: The placeholder is for an app ref.
#: common/flatpak-dir.c:9591
#, c-format
msgid "Installing %s is not allowed by the policy set by your administrator"
msgstr ""
"Instalarea %s nu este permisă de setul de politici de către administrator"

#: common/flatpak-dir.c:9690
#, c-format
msgid "While trying to resolve ref %s: "
msgstr "În timpul încercării de rezolvare a ref-ului %s: "

#: common/flatpak-dir.c:9702
#, c-format
msgid "%s is not available"
msgstr "%s nu este disponibil"

#: common/flatpak-dir.c:9714 common/flatpak-dir.c:11495
#, c-format
msgid "%s commit %s already installed"
msgstr "%s comitul %s este deja instalat"

#: common/flatpak-dir.c:9721
msgid "Can't create deploy directory"
msgstr "Nu se poate crea directorul de implementare"

#: common/flatpak-dir.c:9729
#, c-format
msgid "Failed to read commit %s: "
msgstr "Nu s-a putut citi comitul %s: "

#: common/flatpak-dir.c:9750
#, c-format
msgid "While trying to checkout %s into %s: "
msgstr "În timpul încercării de a face checkout %s în %s: "

#: common/flatpak-dir.c:9769
msgid "While trying to checkout metadata subpath: "
msgstr "În timpul încercării de a face checkout al subcăii de date meta: "

#: common/flatpak-dir.c:9801
#, c-format
msgid "While trying to checkout subpath ‘%s’: "
msgstr "În timpul încercării de a face checkout al subcăii „%s”: "

#: common/flatpak-dir.c:9811
msgid "While trying to remove existing extra dir: "
msgstr "În timpul încercării de a elimina directorul extra existent: "

#: common/flatpak-dir.c:9822
msgid "While trying to apply extra data: "
msgstr "În timpul încercării de aplicare a datelor extra: "

#: common/flatpak-dir.c:9849
#, c-format
msgid "Invalid commit ref %s: "
msgstr "Ref de comit %s nevalid: "

#: common/flatpak-dir.c:9857 common/flatpak-dir.c:9869
#, c-format
msgid "Deployed ref %s does not match commit (%s)"
msgstr "Ref-ul implementat %s nu se potrivește cu comitul (%s)"

#: common/flatpak-dir.c:9863
#, c-format
msgid "Deployed ref %s branch does not match commit (%s)"
msgstr "Ramura ref-ului implementat %s nu se potrivește cu comitul (%s)"

#: common/flatpak-dir.c:10125 common/flatpak-installation.c:1911
#, c-format
msgid "%s branch %s already installed"
msgstr "%s ramura %s este deja instalată"

#: common/flatpak-dir.c:10985
#, c-format
msgid "Could not unmount revokefs-fuse filesystem at %s: "
msgstr "Nu s-a putut demonta sistemul de fișiere revokefs-fuse la %s: "

#: common/flatpak-dir.c:11289
#, c-format
msgid "This version of %s is already installed"
msgstr "Această versiune a %s este deja instalată"

#: common/flatpak-dir.c:11302
#, c-format
msgid "Can't change remote during bundle install"
msgstr ""
"Nu se poate modifica depozitul de la distanță în timpul instalării unui "
"pachet"

#: common/flatpak-dir.c:11571
msgid "Can't update to a specific commit without root permissions"
msgstr "Nu se poate actualiza la un comit specific fără permisiuni root"

#: common/flatpak-dir.c:11852
#, c-format
msgid "Can't remove %s, it is needed for: %s"
msgstr "Nu se poate elimina %s, acesta este necesar pentru: %s"

#: common/flatpak-dir.c:11912 common/flatpak-installation.c:2067
#, c-format
msgid "%s branch %s is not installed"
msgstr "%s ramura %s nu este instalată"

#: common/flatpak-dir.c:12165
#, c-format
msgid "%s commit %s not installed"
msgstr "%s comitul %s nu este instalat"

#: common/flatpak-dir.c:12501
#, c-format
msgid "Pruning repo failed: %s"
msgstr "Eliminarea depozitului a eșuat: %s"

#: common/flatpak-dir.c:12669 common/flatpak-dir.c:12675
#, c-format
msgid "Failed to load filter '%s'"
msgstr "Nu s-a putut încărca filtrul „%s”"

#: common/flatpak-dir.c:12681
#, c-format
msgid "Failed to parse filter '%s'"
msgstr "Nu s-a putut parsa filtrul „%s”"

#: common/flatpak-dir.c:12963
msgid "Failed to write summary cache: "
msgstr "Nu s-a putut scrie cache-ul rezumatului: "

#: common/flatpak-dir.c:12982
#, c-format
msgid "No oci summary cached for remote '%s'"
msgstr "Niciun rezumat oci cache-uit pentru depozitul de la distanță „%s”"

#: common/flatpak-dir.c:13207
#, fuzzy, c-format
msgid "No cached summary for remote '%s'"
msgstr "Niciun rezumat oci cache-uit pentru depozitul de la distanță „%s”"

#: common/flatpak-dir.c:13248
#, fuzzy, c-format
msgid "Invalid checksum for indexed summary %s read from %s"
msgstr "Sumă de control nevalidă pentru datele extra %s"

#: common/flatpak-dir.c:13321
#, c-format
msgid ""
"Remote listing for %s not available; server has no summary file. Check the "
"URL passed to remote-add was valid."
msgstr ""
"Listarea de la distanță pentru %s nu este disponibilă; serverul nu are "
"niciun fișier de rezumat. Verificați dacă a fost valid URL-ul trecut la "
"remote-add."

#: common/flatpak-dir.c:13698
#, fuzzy, c-format
msgid "Invalid checksum for indexed summary %s for remote '%s'"
msgstr "Sumă de control nevalidă pentru datele extra %s"

#: common/flatpak-dir.c:14388
#, c-format
msgid "Multiple branches available for %s, you must specify one of: "
msgstr ""
"Ramuri multiple disponibile pentru %s, trebuie să specificați una dintre: "

#: common/flatpak-dir.c:14454
#, c-format
msgid "Nothing matches %s"
msgstr "Nimic nu se potrivește cu %s"

#: common/flatpak-dir.c:14562
#, c-format
msgid "Can't find ref %s%s%s%s%s"
msgstr "Nu se poate găsi ref-ul %s%s%s%s%s"

#: common/flatpak-dir.c:14605
#, c-format
msgid "Error searching remote %s: %s"
msgstr "Eroare la căutarea depozitului de la distanță %s: %s"

#: common/flatpak-dir.c:14702
#, c-format
msgid "Error searching local repository: %s"
msgstr "Eroare la căutarea depozitului local: %s"

#: common/flatpak-dir.c:14839
#, c-format
msgid "%s/%s/%s not installed"
msgstr "%s/%s/%s nu este instalat"

#: common/flatpak-dir.c:15042
#, c-format
msgid "Could not find installation %s"
msgstr "Nu se poate găsi instalarea %s"

#: common/flatpak-dir.c:15612
#, c-format
msgid "Invalid file format, no %s group"
msgstr "Format de fișier nevalid, niciun grup %s"

#: common/flatpak-dir.c:15617 common/flatpak-repo-utils.c:2836
#, c-format
msgid "Invalid version %s, only 1 supported"
msgstr "Versiune nevalidă %s, doar 1 suportat"

#: common/flatpak-dir.c:15622 common/flatpak-dir.c:15627
#, c-format
msgid "Invalid file format, no %s specified"
msgstr "Format de fișier nevalid, niciun %s specificat"

#. Check some minimal size so we don't get crap
#: common/flatpak-dir.c:15647
msgid "Invalid file format, gpg key invalid"
msgstr "Format de fișier nevalid, cheie gpg nevalidă"

#: common/flatpak-dir.c:15675 common/flatpak-repo-utils.c:2917
msgid "Collection ID requires GPG key to be provided"
msgstr "ID-ul colecției necesită furnizarea cheii GPG"

#: common/flatpak-dir.c:15718
#, c-format
msgid "Runtime %s, branch %s is already installed"
msgstr "Executarea %s, ramura %s este deja instalată"

#: common/flatpak-dir.c:15719
#, c-format
msgid "App %s, branch %s is already installed"
msgstr "Aplicația %s, ramura %s este deja instalată"

#: common/flatpak-dir.c:15953
#, c-format
msgid "Can't remove remote '%s' with installed ref %s (at least)"
msgstr ""
"Nu se poate elimina depozitul de la distanță „%s” cu ref-ul instalat %s (cel "
"puțin)"

#: common/flatpak-dir.c:16058
#, c-format
msgid "Invalid character '/' in remote name: %s"
msgstr "Caracter nevalid „/” în numele depozitului de la distanță: %s"

#: common/flatpak-dir.c:16064
#, c-format
msgid "No configuration for remote %s specified"
msgstr "Nu s-a specificat nicio configurare pentru depozitul de la distanță %s"

#: common/flatpak-dir.c:17597
#, c-format
msgid "Skipping deletion of mirror ref (%s, %s)…\n"
msgstr "Se omite ștergerea oglinzii ref-ului (%s, %s)…\n"

#: common/flatpak-exports.c:931
#, c-format
msgid "An absolute path is required"
msgstr ""

#: common/flatpak-exports.c:948
#, fuzzy, c-format
msgid "Unable to open path \"%s\": %s"
msgstr "Nu se poate actualiza %s: %s\n"

#: common/flatpak-exports.c:955
#, fuzzy, c-format
msgid "Unable to get file type of \"%s\": %s"
msgstr "Nu se poate crea linia de asamblare de sincronizare"

#: common/flatpak-exports.c:964
#, c-format
msgid "File \"%s\" has unsupported type 0o%o"
msgstr ""

#: common/flatpak-exports.c:970
#, c-format
msgid "Unable to get filesystem information for \"%s\": %s"
msgstr ""

#: common/flatpak-exports.c:980
#, c-format
msgid "Ignoring blocking autofs path \"%s\""
msgstr ""

#: common/flatpak-exports.c:996 common/flatpak-exports.c:1009
#: common/flatpak-exports.c:1022
#, c-format
msgid "Path \"%s\" is reserved by Flatpak"
msgstr ""

#: common/flatpak-exports.c:1076
#, fuzzy, c-format
msgid "Unable to resolve symbolic link \"%s\": %s"
msgstr "Nu se poate actualiza %s: %s\n"

#: common/flatpak-glib-backports.c:69
msgid "Empty string is not a number"
msgstr "Șirul gol nu este un număr"

#: common/flatpak-glib-backports.c:95
#, c-format
msgid "“%s” is not an unsigned number"
msgstr "„%s” nu este un număr pozitiv"

#: common/flatpak-glib-backports.c:105
#, c-format
msgid "Number “%s” is out of bounds [%s, %s]"
msgstr "Numărul „%s” se află în afara intervalului [%s, %s]"

#: common/flatpak-image-source.c:83
msgid "Only sha256 image checksums are supported"
msgstr ""

#: common/flatpak-image-source.c:100 common/flatpak-image-source.c:108
msgid "Image is not a manifest"
msgstr "Imaginea nu este un manifest"

#: common/flatpak-image-source.c:123
msgid "No org.flatpak.ref found in image"
msgstr ""

#: common/flatpak-image-source.c:148
#, c-format
msgid "Ref '%s' not found in registry"
msgstr "Ref-ul „%s” nu s-a găsit în registru"

#: common/flatpak-image-source.c:157
msgid "Multiple images in registry, specify a ref with --ref"
msgstr "Imagini multiple în registru, specificați o ref cu --ref"

#: common/flatpak-installation.c:834
#, c-format
msgid "Ref %s not installed"
msgstr "Ref-ul %s nu este instalat"

#: common/flatpak-installation.c:875
#, c-format
msgid "App %s not installed"
msgstr "Aplicația %s nu este instalată"

#: common/flatpak-installation.c:1395
#, c-format
msgid "Remote '%s' already exists"
msgstr "Depozitul de la distanță „%s” deja există"

#: common/flatpak-installation.c:1946
#, c-format
msgid "As requested, %s was only pulled, but not installed"
msgstr "După cum s-a cerut, %s a fost doar tras, da nu și instalat"

#: common/flatpak-instance.c:533 common/flatpak-instance.c:687
#: common/flatpak-instance.c:728
#, fuzzy, c-format
msgid "Unable to create directory %s"
msgstr "Nu se poate crea linia de asamblare de sincronizare"

#: common/flatpak-instance.c:554
#, fuzzy, c-format
msgid "Unable to lock %s"
msgstr "Nu se poate găsi ID-ul cheii %s: %d)"

#: common/flatpak-instance.c:627
#, fuzzy, c-format
msgid "Unable to create temporary directory in %s"
msgstr "Nu se poate crea directorul de implementare"

#: common/flatpak-instance.c:639
#, fuzzy, c-format
msgid "Unable to create file %s"
msgstr "Nu se poate crea linia de asamblare de sincronizare"

#: common/flatpak-instance.c:646
#, fuzzy, c-format
msgid "Unable to update symbolic link %s/%s"
msgstr "Nu se poate actualiza %s: %s\n"

#: common/flatpak-oci-registry.c:1197
msgid "Only Bearer authentication supported"
msgstr "Doar autentificarea Bearer este suportată"

#: common/flatpak-oci-registry.c:1206
msgid "Only realm in authentication request"
msgstr "Doar domeniul în cererea de autentificare"

#: common/flatpak-oci-registry.c:1213
msgid "Invalid realm in authentication request"
msgstr "Domeniu nevalid în cererea de autentificare"

#: common/flatpak-oci-registry.c:1283
#, c-format
msgid "Authorization failed: %s"
msgstr "Autorizarea a eșuat: %s"

#: common/flatpak-oci-registry.c:1285
msgid "Authorization failed"
msgstr "Autorizarea a eșuat"

#: common/flatpak-oci-registry.c:1289
#, c-format
msgid "Unexpected response status %d when requesting token: %s"
msgstr "Stare de răspuns neașteptată %d când se cere jetonul: %s"

#: common/flatpak-oci-registry.c:1300
msgid "Invalid authentication request response"
msgstr "Răspuns de cerere de autentificare nevalid"

#: common/flatpak-oci-registry.c:1731
#, c-format
msgid "Flatpak was compiled without zstd support"
msgstr ""

#: common/flatpak-oci-registry.c:1923 common/flatpak-oci-registry.c:1975
#: common/flatpak-oci-registry.c:2004 common/flatpak-oci-registry.c:2059
#: common/flatpak-oci-registry.c:2115 common/flatpak-oci-registry.c:2193
msgid "Invalid delta file format"
msgstr "Format de fișier delta nevalid"

#: common/flatpak-oci-registry.c:3198 common/flatpak-oci-registry.c:3382
msgid "Invalid OCI image config"
msgstr "Configurare de imagine OCI nevalidă"

#: common/flatpak-oci-registry.c:3260 common/flatpak-oci-registry.c:3531
#, c-format
msgid "Wrong layer checksum, expected %s, was %s"
msgstr "Sumă de control a stratului greșită, s-a așteptat %s, a fost %s"

#: common/flatpak-oci-registry.c:3359
#, c-format
msgid "No ref specified for OCI image %s"
msgstr "Nu s-a specificat niciun ref pentru imaginea OCI %s"

#: common/flatpak-oci-registry.c:3369
#, c-format
msgid "Wrong ref (%s) specified for OCI image %s, expected %s"
msgstr "Ref greșit (%s) specificat pentru imaginea OCI %s, s-a așteptat %s"

#: common/flatpak-progress.c:236
#, c-format
msgid "Downloading metadata: %u/(estimating) %s"
msgstr "Se descarcă datele meta: %u/(se estimează) %s"

#: common/flatpak-progress.c:260
#, c-format
msgid "Downloading: %s/%s"
msgstr "Se descarcă: %s/%s"

#: common/flatpak-progress.c:280
#, c-format
msgid "Downloading extra data: %s/%s"
msgstr "Se descarcă datele extra: %s/%s"

#: common/flatpak-progress.c:285
#, c-format
msgid "Downloading files: %d/%d %s"
msgstr "Se descarcă fișierele: %d/%d %s"

#: common/flatpak-ref-utils.c:122
msgid "Name can't be empty"
msgstr "Numele nu poate fi gol"

#: common/flatpak-ref-utils.c:129
msgid "Name can't be longer than 255 characters"
msgstr "Numele nu poate fi mai lung decât 255 de caractere"

#: common/flatpak-ref-utils.c:142
msgid "Name can't start with a period"
msgstr "Numele nu poate începe cu un punct"

#: common/flatpak-ref-utils.c:148
#, c-format
msgid "Name can't start with %c"
msgstr "Numele nu poate începe cu %c"

#: common/flatpak-ref-utils.c:164
msgid "Name can't end with a period"
msgstr "Numele nu poate să se termine cu un punct"

#: common/flatpak-ref-utils.c:171 common/flatpak-ref-utils.c:183
msgid "Only last name segment can contain -"
msgstr "Doar ultimul segment al numelui poate să conțină -"

#: common/flatpak-ref-utils.c:174
#, c-format
msgid "Name segment can't start with %c"
msgstr "Segmentul numelui nu poate să înceapă cu %c"

#: common/flatpak-ref-utils.c:186
#, c-format
msgid "Name can't contain %c"
msgstr "Numele nu poate să conțină %c"

#: common/flatpak-ref-utils.c:195
msgid "Names must contain at least 2 periods"
msgstr "Numele trebuie să conțină cel puțin 2 puncte"

#: common/flatpak-ref-utils.c:312
#, fuzzy
msgid "Arch can't be empty"
msgstr "Ramura nu poate fi goală"

#: common/flatpak-ref-utils.c:323
#, fuzzy, c-format
msgid "Arch can't contain %c"
msgstr "Ramura nu poate să conțină %c"

#: common/flatpak-ref-utils.c:385
msgid "Branch can't be empty"
msgstr "Ramura nu poate fi goală"

#: common/flatpak-ref-utils.c:395
#, c-format
msgid "Branch can't start with %c"
msgstr "Ramura nu poate începe cu %c"

#: common/flatpak-ref-utils.c:405
#, c-format
msgid "Branch can't contain %c"
msgstr "Ramura nu poate să conțină %c"

#: common/flatpak-ref-utils.c:615 common/flatpak-ref-utils.c:865
msgid "Ref too long"
msgstr ""

#: common/flatpak-ref-utils.c:627
#, fuzzy
msgid "Invalid remote name"
msgstr "Nume al depozitului de la distanță greșit: %s"

#: common/flatpak-ref-utils.c:641
#, c-format
msgid "%s is not application or runtime"
msgstr "%s nu este aplicație sau executare"

#: common/flatpak-ref-utils.c:650 common/flatpak-ref-utils.c:667
#: common/flatpak-ref-utils.c:683
#, c-format
msgid "Wrong number of components in %s"
msgstr "Număr de componente greșit în %s"

#: common/flatpak-ref-utils.c:656
#, fuzzy, c-format
msgid "Invalid name %.*s: %s"
msgstr "Nume nevalid %s: %s"

#: common/flatpak-ref-utils.c:673
#, fuzzy, c-format
msgid "Invalid arch: %.*s: %s"
msgstr "Ramură nevalidă %s: %s"

#: common/flatpak-ref-utils.c:816
#, c-format
msgid "Invalid name %s: %s"
msgstr "Nume nevalid %s: %s"

#: common/flatpak-ref-utils.c:834
#, fuzzy, c-format
msgid "Invalid arch: %s: %s"
msgstr "Ramură nevalidă %s: %s"

#: common/flatpak-ref-utils.c:853
#, fuzzy, c-format
msgid "Invalid branch: %s: %s"
msgstr "Ramură nevalidă %s: %s"

#: common/flatpak-ref-utils.c:962 common/flatpak-ref-utils.c:970
#: common/flatpak-ref-utils.c:978
#, fuzzy, c-format
msgid "Wrong number of components in partial ref %s"
msgstr "Număr de componente greșit în executarea %s"

#: common/flatpak-ref-utils.c:1298
#, fuzzy
msgid " development platform"
msgstr "Utilizează executarea de dezvoltare"

#: common/flatpak-ref-utils.c:1300
msgid " platform"
msgstr ""

#: common/flatpak-ref-utils.c:1302
#, fuzzy
msgid " application base"
msgstr "Aplicație"

#: common/flatpak-ref-utils.c:1305
msgid " debug symbols"
msgstr ""

#: common/flatpak-ref-utils.c:1307
msgid " sourcecode"
msgstr ""

#: common/flatpak-ref-utils.c:1309
#, fuzzy
msgid " translations"
msgstr "Loc de instalare"

#: common/flatpak-ref-utils.c:1311
msgid " docs"
msgstr ""

#: common/flatpak-ref-utils.c:1578
#, c-format
msgid "Invalid id %s: %s"
msgstr "ID nevalid %s: %s"

#: common/flatpak-remote.c:1216
#, c-format
msgid "Bad remote name: %s"
msgstr "Nume al depozitului de la distanță greșit: %s"

#: common/flatpak-remote.c:1220
#, fuzzy
msgid "No URL specified"
msgstr "Niciun url specificat"

#: common/flatpak-remote.c:1266
msgid "GPG verification must be enabled when a collection ID is set"
msgstr ""
"Verificarea GPG trebuie să fie activată când un ID de colecție este stabilit"

#: common/flatpak-repo-utils.c:344
#, c-format
msgid "No extra data sources"
msgstr "Nu sunt surse de date extra"

#: common/flatpak-repo-utils.c:2817
#, c-format
msgid "Invalid %s: Missing group ‘%s’"
msgstr "%s nevalid: Lipsește grupul „%s”"

#: common/flatpak-repo-utils.c:2826
#, c-format
msgid "Invalid %s: Missing key ‘%s’"
msgstr "%s nevalid: Lipsește cheia „%s”"

#: common/flatpak-repo-utils.c:2876
msgid "Invalid gpg key"
msgstr "Cheie gpg nevalidă"

#: common/flatpak-repo-utils.c:3217
#, c-format
msgid "Error copying 64x64 icon for component %s: %s\n"
msgstr "Eroare la copierea iconiței 64x64 pentru componenta %s: %s\n"

#: common/flatpak-repo-utils.c:3223
#, c-format
msgid "Error copying 128x128 icon for component %s: %s\n"
msgstr "Eroare la copierea iconiței 128x128 pentru componenta %s: %s\n"

#: common/flatpak-repo-utils.c:3362
#, fuzzy, c-format
msgid "%s is end-of-life, ignoring for appstream"
msgstr "%s este sfârșit-de-fișier, se ignoră\n"

#: common/flatpak-repo-utils.c:3397
#, c-format
msgid "No appstream data for %s: %s\n"
msgstr "Nu sunt date appstream pentru %s: %s\n"

#: common/flatpak-repo-utils.c:3744
msgid "Invalid bundle, no ref in metadata"
msgstr "Pachet nevalid, nu există ref în datele meta"

#: common/flatpak-repo-utils.c:3846
#, c-format
msgid "Collection ‘%s’ of bundle doesn’t match collection ‘%s’ of remote"
msgstr ""
"Colecția „%s” a pachetului nu se potrivește cu colecția „%s” a depozitului "
"de la distanță"

#: common/flatpak-repo-utils.c:3923
msgid "Metadata in header and app are inconsistent"
msgstr "Datele meta din antet și aplicație nu sunt consistente"

#: common/flatpak-run.c:951
msgid "No systemd user session available, cgroups not available"
msgstr ""
"Nu este disponibilă nicio sesiune de utilizator systemd, cgroups nu sunt "
"disponibile"

#: common/flatpak-run.c:1496
msgid "Unable to allocate instance id"
msgstr "Nu se poate aloca id-ul de instanță"

#: common/flatpak-run.c:1632 common/flatpak-run.c:1641
#, c-format
msgid "Failed to open flatpak-info file: %s"
msgstr "Nu s-a putut deschide fișierul de informații flatpak: %s"

#: common/flatpak-run.c:1668
#, c-format
msgid "Failed to open bwrapinfo.json file: %s"
msgstr "Nu s-a putut deschide fișierul bwrapinfo.json: %s"

#: common/flatpak-run.c:1689
#, c-format
msgid "Failed to write to instance id fd: %s"
msgstr "Nu s-a putut scrie id-ul instanței fd: %s"

#: common/flatpak-run.c:2096
msgid "Initialize seccomp failed"
msgstr "Inițializarea seccomp a eșuat"

#: common/flatpak-run.c:2135
#, fuzzy, c-format
msgid "Failed to add architecture to seccomp filter: %s"
msgstr "Nu s-a putut adăuga arhitectura la filtrul seccomp"

#: common/flatpak-run.c:2143
#, fuzzy, c-format
msgid "Failed to add multiarch architecture to seccomp filter: %s"
msgstr "Nu s-a putut adăuga arhitectura multi-arhitectură la filtrul seccomp"

#: common/flatpak-run.c:2175 common/flatpak-run.c:2192
#: common/flatpak-run.c:2214
#, fuzzy, c-format
msgid "Failed to block syscall %d: %s"
msgstr "Nu s-a putut bloca syscall-ul %d"

#: common/flatpak-run.c:2247
#, fuzzy, c-format
msgid "Failed to export bpf: %s"
msgstr "Nu s-a putut exporta bpf"

#: common/flatpak-run.c:2587
#, c-format
msgid "Failed to open ‘%s’"
msgstr "Nu s-a putut deschide „%s”"

#: common/flatpak-run.c:2597
#, c-format
msgid ""
"Directory forwarding needs version 4 of the document portal (have version %d)"
msgstr ""

#: common/flatpak-run.c:2915
#, c-format
msgid "ldconfig failed, exit status %d"
msgstr "idconfig a eșuat, stare de ieșire %d"

#: common/flatpak-run.c:2922
msgid "Can't open generated ld.so.cache"
msgstr "Nu s-a putut deschide ld.so.cache generat"

#. Translators: The placeholder is for an app ref.
#: common/flatpak-run.c:3045
#, c-format
msgid "Running %s is not allowed by the policy set by your administrator"
msgstr ""
"Rularea %s nu este permisă de politica stabilită de către administrator"

#: common/flatpak-run.c:3202
msgid ""
"\"flatpak run\" is not intended to be run as `sudo flatpak run`. Use `sudo "
"-i` or `su -l` instead and invoke \"flatpak run\" from inside the new shell."
msgstr ""

#: common/flatpak-run.c:3413
#, c-format
msgid "Failed to migrate from %s: %s"
msgstr "Nu s-a putut migra de la %s: %s"

#: common/flatpak-run.c:3434
#, c-format
msgid "Failed to migrate old app data directory %s to new name %s: %s"
msgstr ""
"Nu s-a putut migra directorul vechi de date %s al aplicației la numele nou "
"%s: %s"

#: common/flatpak-run.c:3443
#, c-format
msgid "Failed to create symlink while migrating %s: %s"
msgstr "Nu s-a putut crea legătura simbolică în timpul migrării %s: %s"

#: common/flatpak-run-dbus.c:46
msgid "Failed to open app info file"
msgstr "Nu s-a putut deschide fișierul de informații ale aplicației"

#: common/flatpak-run-dbus.c:149
msgid "Unable to create sync pipe"
msgstr "Nu se poate crea linia de asamblare de sincronizare"

#: common/flatpak-run-dbus.c:185
msgid "Failed to sync with dbus proxy"
msgstr "Nu s-a putut sincroniza cu proxy-ul dbus"

#: common/flatpak-transaction.c:2275
#, c-format
msgid "Warning: Problem looking for related refs: %s"
msgstr "Avertisment: A apărut o problemă la căutarea pentru ref-uri legate: %s"

#: common/flatpak-transaction.c:2493
#, c-format
msgid "The application %s requires the runtime %s which was not found"
msgstr "Aplicația %s necesită executarea %s care nu a fost găsită"

#: common/flatpak-transaction.c:2509
#, c-format
msgid "The application %s requires the runtime %s which is not installed"
msgstr "Aplicația %s necesită executarea %s care nu este instalată"

#: common/flatpak-transaction.c:2641
#, c-format
msgid "Can't uninstall %s which is needed by %s"
msgstr "Nu se poate dezinstala %s care este necesar pentru %s"

#: common/flatpak-transaction.c:2740
#, c-format
msgid "Remote %s disabled, ignoring %s update"
msgstr ""
"Depozitul de la distanță %s a fost dezactivat, se ignoră actualizarea %s"

#: common/flatpak-transaction.c:2773
#, c-format
msgid "%s is already installed"
msgstr "%s este deja instalat"

#: common/flatpak-transaction.c:2776
#, c-format
msgid "%s is already installed from remote %s"
msgstr "%s este deja instalat pentru depozitul de la distanță %s"

#: common/flatpak-transaction.c:3120
#, c-format
msgid "Invalid .flatpakref: %s"
msgstr ".flatpakref nevalid: %s"

#: common/flatpak-transaction.c:3161
msgid "Warning: Could not mark already installed apps as preinstalled"
msgstr ""

#: common/flatpak-transaction.c:3382
#, c-format
msgid "Error updating remote metadata for '%s': %s"
msgstr "Eroare la actualizarea datelor meta de la distanță pentru „%s”: %s"

#: common/flatpak-transaction.c:3885
#, c-format
msgid ""
"Warning: Treating remote fetch error as non-fatal since %s is already "
"installed: %s"
msgstr ""
"Avertisment: Tratarea erorii de preluare a depozitului de la distanță ca "
"nefatală deoarece %s este deja instalat: %s"

#: common/flatpak-transaction.c:4209
#, c-format
msgid "No authenticator installed for remote '%s'"
msgstr "Niciun autentificator instalat pentru depozitul de la distanță „%s”"

#: common/flatpak-transaction.c:4313 common/flatpak-transaction.c:4320
#, c-format
msgid "Failed to get tokens for ref: %s"
msgstr "Nu s-au putut obține jetoanele pentru ref: %s"

#: common/flatpak-transaction.c:4315 common/flatpak-transaction.c:4322
msgid "Failed to get tokens for ref"
msgstr "Nu s-au putut obține jetoanele pentru ref"

#: common/flatpak-transaction.c:4580
#, c-format
msgid "Ref %s from %s matches more than one transaction operation"
msgstr ""

#: common/flatpak-transaction.c:4581 common/flatpak-transaction.c:4591
#, fuzzy
msgid "any remote"
msgstr "Locație la distanță"

#: common/flatpak-transaction.c:4590
#, c-format
msgid "No transaction operation found for ref %s from %s"
msgstr ""

#: common/flatpak-transaction.c:4713
#, c-format
msgid "Flatpakrepo URL %s not file, HTTP or HTTPS"
msgstr "URL-ul Flatpakrepo %s nu este un fișier, HTTP, sau HTTPS"

#: common/flatpak-transaction.c:4719
#, c-format
msgid "Can't load dependent file %s: "
msgstr "Nu se poate încărca fișierul dependent %s: "

#: common/flatpak-transaction.c:4727
#, c-format
msgid "Invalid .flatpakrepo: %s"
msgstr ".flatpakrepo nevalid: %s"

#: common/flatpak-transaction.c:5454
msgid "Transaction already executed"
msgstr "Tranzacția este deja executată"

#: common/flatpak-transaction.c:5469
msgid ""
"Refusing to operate on a user installation as root! This can lead to "
"incorrect file ownership and permission errors."
msgstr ""
"Se refuză operarea pe o instalare a utilizatorului ca root! Aceasta poate "
"duce la proprietate incorectă de fișiere și erori de permisiune."

#: common/flatpak-transaction.c:5567 common/flatpak-transaction.c:5580
msgid "Aborted by user"
msgstr "Anulat de utilizator"

#: common/flatpak-transaction.c:5605
#, c-format
msgid "Skipping %s due to previous error"
msgstr "Se omite %s din cauza erorii anterioare"

#: common/flatpak-transaction.c:5659
#, fuzzy, c-format
msgid "Aborted due to failure (%s)"
msgstr "Anulat din cauza eșecului"

#: common/flatpak-uri.c:118
#, fuzzy, no-c-format
msgid "Invalid %-encoding in URI"
msgstr "Nume de autentificator %s nevalid"

#: common/flatpak-uri.c:135
msgid "Illegal character in URI"
msgstr ""

#: common/flatpak-uri.c:169
msgid "Non-UTF-8 characters in URI"
msgstr ""

#: common/flatpak-uri.c:275
#, c-format
msgid "Invalid IPv6 address ‘%.*s’ in URI"
msgstr ""

#: common/flatpak-uri.c:330
#, c-format
msgid "Illegal encoded IP address ‘%.*s’ in URI"
msgstr ""

#: common/flatpak-uri.c:342
#, c-format
msgid "Illegal internationalized hostname ‘%.*s’ in URI"
msgstr ""

#: common/flatpak-uri.c:374 common/flatpak-uri.c:386
#, fuzzy, c-format
msgid "Could not parse port ‘%.*s’ in URI"
msgstr "Nu s-a putut parsa „%s”"

#: common/flatpak-uri.c:393
#, c-format
msgid "Port ‘%.*s’ in URI is out of range"
msgstr ""

#: common/flatpak-uri.c:910
msgid "URI is not absolute, and no base URI was provided"
msgstr ""

#: common/flatpak-usb.c:83
#, c-format
msgid "USB device query 'all' must not have data"
msgstr ""

#: common/flatpak-usb.c:102
#, c-format
msgid "USB query rule 'cls' must be in the form CLASS:SUBCLASS or CLASS:*"
msgstr ""

#: common/flatpak-usb.c:111
#, fuzzy, c-format
msgid "Invalid USB class"
msgstr "ID nevalid %s: %s"

#: common/flatpak-usb.c:125
#, c-format
msgid "Invalid USB subclass"
msgstr ""

#: common/flatpak-usb.c:141 common/flatpak-usb.c:148
#, c-format
msgid "USB query rule 'dev' must have a valid 4-digit hexadecimal product id"
msgstr ""

#: common/flatpak-usb.c:164 common/flatpak-usb.c:171
#, c-format
msgid "USB query rule 'vnd' must have a valid 4-digit hexadecimal vendor id"
msgstr ""

#: common/flatpak-usb.c:205
#, c-format
msgid "USB device queries must be in the form TYPE:DATA"
msgstr ""

#: common/flatpak-usb.c:225
#, c-format
msgid "Unknown USB query rule %s"
msgstr ""

#: common/flatpak-usb.c:248
#, c-format
msgid "Empty USB query"
msgstr ""

#: common/flatpak-usb.c:274
#, c-format
msgid "Multiple USB query rules of the same type is not supported"
msgstr ""

#: common/flatpak-usb.c:283
#, c-format
msgid "'all' must not contain extra query rules"
msgstr ""

#: common/flatpak-usb.c:291
#, c-format
msgid "USB queries with 'dev' must also specify vendors"
msgstr ""

#: common/flatpak-utils.c:712
msgid "Glob can't match apps"
msgstr ""

#: common/flatpak-utils.c:737
msgid "Empty glob"
msgstr "Glob gol"

#: common/flatpak-utils.c:756
msgid "Too many segments in glob"
msgstr "Prea multe segmente în glob"

#: common/flatpak-utils.c:777
#, c-format
msgid "Invalid glob character '%c'"
msgstr "Caracter de glob nevalid „%c”"

#: common/flatpak-utils.c:831
#, c-format
msgid "Missing glob on line %d"
msgstr "Glob care lipsește la linia %d"

#: common/flatpak-utils.c:835
#, c-format
msgid "Trailing text on line %d"
msgstr "Text de urmărire la linia %d"

#: common/flatpak-utils.c:839
#, c-format
msgid "on line %d"
msgstr "la linia %d"

#: common/flatpak-utils.c:861
#, c-format
msgid "Unexpected word '%s' on line %d"
msgstr "Cuvânt neașteptat „%s” pe linia %d"

#: common/flatpak-utils.c:2118
#, c-format
msgid "Invalid require-flatpak argument %s"
msgstr "Argument require-flatpak nevalid %s"

#: common/flatpak-utils.c:2128 common/flatpak-utils.c:2147
#, c-format
msgid "%s needs a later flatpak version (%s)"
msgstr "%s are nevoie de o versiune ulterioară flatpak (%s)"

#: oci-authenticator/flatpak-oci-authenticator.c:291
msgid "Not a oci remote, missing summary.xa.oci-repository"
msgstr ""
"Nu este un depozit de la distanță oci, lipsește summary.xa.oci-repository"

#: oci-authenticator/flatpak-oci-authenticator.c:477
msgid "Not a OCI remote"
msgstr "Nu este un depozit de la distanță OCI"

#: oci-authenticator/flatpak-oci-authenticator.c:488
msgid "Invalid token"
msgstr "Jeton nevalid"

#: portal/flatpak-portal.c:2292
#, c-format
msgid "No portal support found"
msgstr "Nu s-a găsit niciun suport pentru portal"

#: portal/flatpak-portal.c:2298
msgid "Deny"
msgstr "Refuză"

#: portal/flatpak-portal.c:2300
msgid "Update"
msgstr "Actualizează"

#: portal/flatpak-portal.c:2305
#, c-format
msgid "Update %s?"
msgstr "Actualizați %s?"

#: portal/flatpak-portal.c:2317
msgid "The application wants to update itself."
msgstr "Aplicația vrea să se actualizeze."

#: portal/flatpak-portal.c:2318
msgid "Update access can be changed any time from the privacy settings."
msgstr ""
"Accesul pentru actualizare poate fi modificat oricând din setările de "
"confidențialitate."

#: portal/flatpak-portal.c:2343
#, c-format
msgid "Application update not allowed"
msgstr "Actualizarea aplicației nu este permisă"

#: portal/flatpak-portal.c:2501
#, c-format
msgid "Self update not supported, new version requires new permissions"
msgstr ""
"Actualizarea de sine nu este suportată, versiunea nouă necesită permisiuni "
"noi"

#: portal/flatpak-portal.c:2684 portal/flatpak-portal.c:2702
#, c-format
msgid "Update ended unexpectedly"
msgstr "Actualizarea s-a terminat neașteptat"

#. SECURITY:
#. - Normal users need admin authentication to install software
#. system-wide.
#. - Note that we install polkit rules that allow local users
#. in the wheel group to install without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:23
msgid "Install signed application"
msgstr "Instalează aplicația semnată"

#: system-helper/org.freedesktop.Flatpak.policy.in:24
#: system-helper/org.freedesktop.Flatpak.policy.in:42
msgid "Authentication is required to install software"
msgstr "Autentificarea este necesară pentru a instala software"

#. SECURITY:
#. - Normal users need admin authentication to install software
#. system-wide.
#. - Note that we install polkit rules that allow local users
#. in the wheel group to install without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:41
msgid "Install signed runtime"
msgstr "Instalează executarea semnată"

#. SECURITY:
#. - Normal users do not require admin authentication to update an
#. app as the commit will be signed, and the action is required
#. to update the system when unattended.
#. - Changing this to anything other than 'yes' will break unattended
#. updates.
#: system-helper/org.freedesktop.Flatpak.policy.in:60
msgid "Update signed application"
msgstr "Actualizează aplicația semnată"

#: system-helper/org.freedesktop.Flatpak.policy.in:61
#: system-helper/org.freedesktop.Flatpak.policy.in:80
msgid "Authentication is required to update software"
msgstr "Autentificarea este necesară pentru a actualiza software-ul"

#. SECURITY:
#. - Normal users do not require admin authentication to update a
#. runtime as the commit will be signed, and the action is required
#. to update the system when unattended.
#. - Changing this to anything other than 'yes' will break unattended
#. updates.
#: system-helper/org.freedesktop.Flatpak.policy.in:79
msgid "Update signed runtime"
msgstr "Actualizează executarea semnată"

#. SECURITY:
#. - Normal users do not need authentication to update metadata
#. from signed repositories.
#: system-helper/org.freedesktop.Flatpak.policy.in:94
msgid "Update remote metadata"
msgstr "Actualizează datele meta ale depozitului de la distanță"

#: system-helper/org.freedesktop.Flatpak.policy.in:95
msgid "Authentication is required to update remote info"
msgstr ""
"Autentificarea este necesară pentru a actualiza informațiile depozitului de "
"la distanță"

#. SECURITY:
#. - Normal users do not need authentication to modify the
#. OSTree repository
#. - Note that we install polkit rules that allow local users
#. in the wheel group to modify repos without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:111
msgid "Update system repository"
msgstr "Actualizează un depozit al sistemului"

#: system-helper/org.freedesktop.Flatpak.policy.in:112
msgid "Authentication is required to modify a system repository"
msgstr ""
"Autentificarea este necesară pentru a modifica un depozit al sistemului"

#. SECURITY:
#. - Normal users need admin authentication to install software
#. system-wide.
#: system-helper/org.freedesktop.Flatpak.policy.in:126
msgid "Install bundle"
msgstr "Instalează pachetul"

#: system-helper/org.freedesktop.Flatpak.policy.in:127
msgid "Authentication is required to install software from $(path)"
msgstr "Autentificarea este necesară pentru a instala software de la $(path)"

#. SECURITY:
#. - Normal users need admin authentication to uninstall software
#. system-wide.
#. - Note that we install polkit rules that allow local users
#. in the wheel group to uninstall without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:144
msgid "Uninstall runtime"
msgstr "Dezinstalează executarea"

#: system-helper/org.freedesktop.Flatpak.policy.in:145
msgid "Authentication is required to uninstall software"
msgstr "Autentificarea este necesară pentru a dezinstala software"

#. SECURITY:
#. - Normal users need admin authentication to uninstall software
#. system-wide.
#. - Note that we install polkit rules that allow local users
#. in the wheel group to uninstall without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:161
msgid "Uninstall app"
msgstr "Dezinstalează aplicația"

#: system-helper/org.freedesktop.Flatpak.policy.in:162
msgid "Authentication is required to uninstall $(ref)"
msgstr "Autentificarea este necesară pentru a dezinstala $(ref)"

#. SECURITY:
#. - Normal users need admin authentication to configure system-wide
#. software repositories.
#: system-helper/org.freedesktop.Flatpak.policy.in:177
msgid "Configure Remote"
msgstr "Configurează depozitul de la distanță"

#: system-helper/org.freedesktop.Flatpak.policy.in:178
msgid "Authentication is required to configure software repositories"
msgstr "Autentificarea este necesară pentru a configura depozitele de software"

#. SECURITY:
#. - Normal users need admin authentication to configure the system-wide
#. Flatpak installation.
#: system-helper/org.freedesktop.Flatpak.policy.in:192
msgid "Configure"
msgstr "Configurează"

#: system-helper/org.freedesktop.Flatpak.policy.in:193
msgid "Authentication is required to configure software installation"
msgstr "Autentificarea este necesară pentru a configura instalarea de software"

#. SECURITY:
#. - Normal users do not require admin authentication to update
#. appstream data as it will be signed, and the action is required
#. to update the system when unattended.
#. - Changing this to anything other than 'yes' will break unattended
#. updates.
#: system-helper/org.freedesktop.Flatpak.policy.in:210
msgid "Update appstream"
msgstr "Actualizează appstream"

#: system-helper/org.freedesktop.Flatpak.policy.in:211
msgid "Authentication is required to update information about software"
msgstr ""
"Autentificarea este necesară pentru a actualiza informațiile despre software"

#. SECURITY:
#. - Normal users do not require admin authentication to update
#. metadata as it will be signed, and the action is required
#. to update the system when unattended.
#. - Changing this to anything other than 'yes' will break unattended
#. updates.
#: system-helper/org.freedesktop.Flatpak.policy.in:228
msgid "Update metadata"
msgstr "Actualizează datele meta"

#: system-helper/org.freedesktop.Flatpak.policy.in:229
msgid "Authentication is required to update metadata"
msgstr "Autentificarea este necesară pentru a actualiza datele meta"

#. SECURITY:
#. - Authorisation to actually install software is controlled by
#. org.freedesktop.Flatpak.app-install.
#. - This action is checked after app-install, as it can only be done
#. once the app’s data (including its content rating) has been
#. downloaded.
#. - This action is checked to see if the installation should be allowed
#. based on whether the app being installed has content which doesn’t
#. comply with the user’s parental controls policy (the content is
#. ‘too extreme’).
#. - It is checked only if an app has too extreme content for the user
#. who is trying to install it (in which case, the app is ‘unsafe’).
#. - Typically, normal users will need admin permission to install apps
#. with extreme content; admins will be able to install it without
#. additional checks.
#. - In order to configure the policy so that admins can install safe and
#. unsafe software anywhere without authorisation, and non-admins can
#. install safe software in their user or system dirs without
#. authorisation, but need authorisation to install unsafe software
#. anywhere:
#. * Unconditionally return `yes` from `app-install`.
#. * Return `auth_admin` from `override-parental-controls` for users
#. not in `@privileged_group@`, and `yes` for users in it.
#. * Set the malcontent `is-{user,system}-installation-allowed`
#. properties of all non-admins’ parental controls policies to true.
#. - In order to configure the policy so that admins can install safe and
#. unsafe software anywhere without authorisation, and non-admins can
#. install safe software in their user dir without authorisation, but
#. need authorisation to install safe software in the system dir or to
#. install unsafe software anywhere:
#. * Unconditionally return `yes` from `app-install`.
#. * Return `auth_admin` from `override-parental-controls` for users
#. not in `@privileged_group@`, and `yes` for users in it.
#. * Set the malcontent `is-user-installation-allowed` property of all
#. non-admins’ parental controls policies to true.
#. * Set the malcontent `is-system-installation-allowed` property of
#. all non-admins’ parental controls policies to false.
#. - In order to configure the policy so that all users (including
#. admins) can install safe software anywhere without authorisation,
#. but need authorisation to install unsafe software anywhere (i.e.
#. applying parental controls to admins too):
#. * Unconditionally return `yes` from `app-install`.
#. * Unconditionally return `auth_admin` from `override-parental-controls`.
#. * Set the malcontent `is-user-installation-allowed` property of all
#. users’ parental controls policies to true.
#. * Set the malcontent `is-system-installation-allowed` property of
#. all users’ parental controls policies to true.
#: system-helper/org.freedesktop.Flatpak.policy.in:287
#, fuzzy
msgid "Override parental controls for installs"
msgstr "Suprascrie controlul parental"

#: system-helper/org.freedesktop.Flatpak.policy.in:288
msgid ""
"Authentication is required to install software which is restricted by your "
"parental controls policy"
msgstr ""
"Autentificarea este necesară pentru a instala software care este "
"restricționat de politica de control parental"

#. SECURITY:
#. - This is like org.freedesktop.Flatpak.override-parental-controls, but
#. it’s queried for app updates, whereas the former is queried for app
#. installs.
#. - As with the above action, this one is only queried if
#. org.freedesktop.Flatpak.app-update has allowed the app update, and
#. only if the app being updated has too extreme content for the user
#. who is trying to update it.
#. - The default policy for this is to *allow* updates to ‘too extreme’
#. apps by default, on the basis that having an out-of-date (i.e.
#. insecure or unsupported) app is a worse outcome than automatically
#. installing an update which has radically different content from the
#. version of the app which the parent originally vetted and installed.
#: system-helper/org.freedesktop.Flatpak.policy.in:313
#, fuzzy
msgid "Override parental controls for updates"
msgstr "Suprascrie controlul parental"

#: system-helper/org.freedesktop.Flatpak.policy.in:314
#, fuzzy
msgid ""
"Authentication is required to update software which is restricted by your "
"parental controls policy"
msgstr ""
"Autentificarea este necesară pentru a instala software care este "
"restricționat de politica de control parental"

#~ msgid "Installed:"
#~ msgstr "Instalat:"

#~ msgid "Download:"
#~ msgstr "Descărcare:"

#, c-format
#~ msgid "No gpg key found with ID %s (homedir: %s)"
#~ msgstr "Nu s-a găsit nicio cheie gpg cu ID-ul %s (directorul personal: %s)"

#, fuzzy, c-format
#~ msgid "Unable to lookup key ID %s: %d"
#~ msgstr "Nu se poate găsi ID-ul cheii %s: %d)"

#, c-format
#~ msgid "Error signing commit: %d"
#~ msgstr "Eroare la semnarea comitului: %d"

#, c-format
#~ msgid ""
#~ "Found similar ref(s) for ‘%s’ in remote ‘%s’ (%s).\n"
#~ "Use this remote?"
#~ msgstr ""
#~ "S-au găsit ref-(uri) similare pentru „%s” în depozitul de la distanță "
#~ "„%s” (%s).\n"
#~ "Utilizați acest depozit de la distanță?"

#, fuzzy, c-format
#~ msgid "No entry for %s in remote '%s' summary cache "
#~ msgstr ""
#~ "Nicio intrare pentru %s în cache-ul flatpak al rezumatului de la distanță "
#~ "„%s” "

#, fuzzy, c-format
#~ msgid "Failed to uninstall %s for rebase to %s: "
#~ msgstr "Nu s-a putut face rebase %s la %s: "

#, fuzzy, c-format
#~ msgid "Failed to uninstall %s for rebase to %s: %s\n"
#~ msgstr "Nu s-a putut face rebase %s la %s: %s\n"

#, fuzzy, c-format
#~ msgid "Unable to open directory %s"
#~ msgstr "Nu se poate conecta la magistrala sistemului"

#~ msgid "install"
#~ msgstr "instalează"

#~ msgid "update"
#~ msgstr "actualizează"

#~ msgid "install bundle"
#~ msgstr "instalează pachetul"

#~ msgid "uninstall"
#~ msgstr "dezinstalează"

#~ msgid "(internal error, please report)"
#~ msgstr "(eroare internă, raportați)"

#~ msgid "Warning:"
#~ msgstr "Avertisment:"

#, fuzzy
#~ msgid "runtime"
#~ msgstr "Executare"

#, fuzzy
#~ msgid "app"
#~ msgstr "Aplicație"

#~ msgid "[REF…] - Uninstall an application"
#~ msgstr "[REF…] - Dezinstalează o aplicație"

#, c-format
#~ msgid "Replace it with %s?"
#~ msgstr "Îl înlocuiți cu %s?"

#~ msgid "\"flatpak run\" is not intended to be ran with sudo"
#~ msgstr "„flatpak run” nu este intenționat să fie rulat cu sudo"

#, c-format
#~ msgid "Invalid deployed ref %s: "
#~ msgstr "Ref implementat %s nevalid: "

#, c-format
#~ msgid "Deployed ref %s kind does not match commit (%s)"
#~ msgstr "Tipul ref-ului implementat %s nu se potrivește cu comitul (%s)"

#, c-format
#~ msgid "Deployed ref %s name does not match commit (%s)"
#~ msgstr "Numele ref-ului implementat %s nu se potrivește cu comitul (%s)"

#, c-format
#~ msgid "Deployed ref %s arch does not match commit (%s)"
#~ msgstr ""
#~ "Arhitectura ref-ului implementat %s nu se potrivește cu comitul (%s)"

#, c-format
#~ msgid "Failed to determine parts from ref: %s"
#~ msgstr "Nu s-au putut determina părțile de la ref-ul: %s"

#, c-format
#~ msgid "Invalid arch %s"
#~ msgstr "Arhitectură nevalidă %s"

#~ msgid "Related ref '%s' is only partially installed"
#~ msgstr "Ref-ul asociat „%s” este doar parțial instalat"

#~ msgid "Ref '%s' is only partially installed"
#~ msgstr "Ref-ul „%s” este doar parțial instalat"

===== ./po/ka.po =====
# Georgian translation for flatpak.
# Copyright (C) 2023 flatpak authors.
# This file is distributed under the same license as the flatpak package.
# Ekaterine Papava <papava.e@gtu.ge>, 2023-2025.
#
msgid ""
msgstr ""
"Project-Id-Version: flatpak git\n"
"Report-Msgid-Bugs-To: https://github.com/flatpak/flatpak/issues\n"
"POT-Creation-Date: 2026-05-27 16:39+0200\n"
"PO-Revision-Date: 2025-04-03 10:16+0200\n"
"Last-Translator: Ekaterine Papava <papava.e@gtu.ge>\n"
"Language-Team: Georgian <(nothing)>\n"
"Language: ka\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Generator: Poedit 3.5\n"

#: app/flatpak-builtins-build-bundle.c:59
msgid "Export runtime instead of app"
msgstr "აპის მაგიერ გაშვების გარემოს გატანა"

#: app/flatpak-builtins-build-bundle.c:60
msgid "Arch to bundle for"
msgstr "ასაგების პაკეტის არქიტექტურა"

#: app/flatpak-builtins-build-bundle.c:60
#: app/flatpak-builtins-build-export.c:62 app/flatpak-builtins-build-init.c:53
#: app/flatpak-builtins-build-sign.c:42 app/flatpak-builtins-create-usb.c:46
#: app/flatpak-builtins-info.c:55 app/flatpak-builtins-install.c:67
#: app/flatpak-builtins-list.c:50 app/flatpak-builtins-make-current.c:38
#: app/flatpak-builtins-remote-info.c:54 app/flatpak-builtins-remote-ls.c:56
#: app/flatpak-builtins-run.c:158 app/flatpak-builtins-search.c:37
#: app/flatpak-builtins-uninstall.c:54 app/flatpak-builtins-update.c:56
msgid "ARCH"
msgstr "არქიტექტურა"

#: app/flatpak-builtins-build-bundle.c:61
#, fuzzy
msgid "URL for repo"
msgstr "რეპოზიტორიის ბმული"

#: app/flatpak-builtins-build-bundle.c:61
#: app/flatpak-builtins-build-bundle.c:62
#: app/flatpak-builtins-build-update-repo.c:68
#: app/flatpak-builtins-build-update-repo.c:72
#: app/flatpak-builtins-build-update-repo.c:73
#: app/flatpak-builtins-history.c:69 app/flatpak-builtins-remote-add.c:80
#: app/flatpak-builtins-remote-add.c:81 app/flatpak-builtins-remote-add.c:85
#: app/flatpak-builtins-remote-list.c:53
#: app/flatpak-builtins-remote-modify.c:70
#: app/flatpak-builtins-remote-modify.c:85
#: app/flatpak-builtins-remote-modify.c:86
#: app/flatpak-builtins-remote-modify.c:90
msgid "URL"
msgstr "ბმული"

#: app/flatpak-builtins-build-bundle.c:62
#, fuzzy
msgid "URL for runtime flatpakrepo file"
msgstr "გაშვების გარემოს flatpakrepo ფაილის ბმული"

#: app/flatpak-builtins-build-bundle.c:63
msgid "Add GPG key from FILE (- for stdin)"
msgstr "GPG გასაღების მითითებული ფაილიდან დამატება (stdin-სთვის გამოიყენეთ -)"

#: app/flatpak-builtins-build-bundle.c:63 app/flatpak-builtins-build.c:54
#: app/flatpak-builtins-build-export.c:67
#: app/flatpak-builtins-build-update-repo.c:83
#: app/flatpak-builtins-install.c:81 app/flatpak-builtins-remote-add.c:84
#: app/flatpak-builtins-remote-add.c:86 app/flatpak-builtins-remote-modify.c:89
#: app/flatpak-builtins-remote-modify.c:92
msgid "FILE"
msgstr "FILE"

#: app/flatpak-builtins-build-bundle.c:64
msgid "GPG Key ID to sign the OCI image with"
msgstr "GPG გასაღების ID-ი OCI ასლის ხელმოსაწერად"

#: app/flatpak-builtins-build-bundle.c:64
#: app/flatpak-builtins-build-commit-from.c:68
#: app/flatpak-builtins-build-export.c:68
#: app/flatpak-builtins-build-import-bundle.c:49
#: app/flatpak-builtins-build-sign.c:44
#: app/flatpak-builtins-build-update-repo.c:84
msgid "KEY-ID"
msgstr "გასაღები-ID"

#: app/flatpak-builtins-build-bundle.c:65
#: app/flatpak-builtins-build-commit-from.c:69
#: app/flatpak-builtins-build-export.c:71
#: app/flatpak-builtins-build-import-bundle.c:50
#: app/flatpak-builtins-build-sign.c:45
#: app/flatpak-builtins-build-update-repo.c:85
msgid "GPG Homedir to use when looking for keyrings"
msgstr "GPG Gomedir-ი ბრასლეტების ძებნისას გამოსაყენებლად"

#: app/flatpak-builtins-build-bundle.c:65
#: app/flatpak-builtins-build-commit-from.c:69
#: app/flatpak-builtins-build-export.c:71
#: app/flatpak-builtins-build-import-bundle.c:50
#: app/flatpak-builtins-build-sign.c:45
#: app/flatpak-builtins-build-update-repo.c:85
msgid "HOMEDIR"
msgstr "HOMEDIR"

#: app/flatpak-builtins-build-bundle.c:66
msgid "OSTree commit to create a delta bundle from"
msgstr "OSTree-ის კომიტი დელტა პაკეტის შესაქმნელად"

#: app/flatpak-builtins-build-bundle.c:66 app/flatpak-builtins-remote-info.c:55
#: app/flatpak-builtins-update.c:57
msgid "COMMIT"
msgstr "COMMIT"

#: app/flatpak-builtins-build-bundle.c:67
msgid "Export oci image instead of flatpak bundle"
msgstr "Flatpak-ის პაკეტის მაგიერ OCI ასლის გატანა"

#: app/flatpak-builtins-build-bundle.c:70
msgid "How to compress OCI image layers (default: gzip)"
msgstr ""

#: app/flatpak-builtins-build-bundle.c:634
msgid ""
"LOCATION FILENAME NAME [BRANCH] - Create a single file bundle from a local "
"repository"
msgstr ""
"მდებარეობა ფაილისსახელი სახელი [ბრენჩი] - ლოკალური რეპოზიტორიიდან "
"ერთფაილიანი პაკეტის შექმნა"

#: app/flatpak-builtins-build-bundle.c:641
msgid "LOCATION, FILENAME and NAME must be specified"
msgstr "მდებარეობის, ფაილის სახელის და სახელის მითითება აუცილებელია"

#: app/flatpak-builtins-build-bundle.c:644
#: app/flatpak-builtins-build-export.c:844
#: app/flatpak-builtins-build-import-bundle.c:136
#: app/flatpak-builtins-build-init.c:217 app/flatpak-builtins-build-sign.c:76
#: app/flatpak-builtins-document-export.c:112
#: app/flatpak-builtins-document-info.c:75
#: app/flatpak-builtins-document-list.c:191
#: app/flatpak-builtins-document-unexport.c:70
#: app/flatpak-builtins-history.c:482 app/flatpak-builtins-info.c:130
#: app/flatpak-builtins-install.c:181 app/flatpak-builtins-install.c:234
#: app/flatpak-builtins-install.c:298 app/flatpak-builtins-list.c:419
#: app/flatpak-builtins-make-current.c:72 app/flatpak-builtins-override.c:73
#: app/flatpak-builtins-permission-list.c:162
#: app/flatpak-builtins-permission-remove.c:132
#: app/flatpak-builtins-remote-add.c:323
#: app/flatpak-builtins-remote-delete.c:68
#: app/flatpak-builtins-remote-list.c:241 app/flatpak-builtins-remote-ls.c:407
msgid "Too many arguments"
msgstr "მეტისმეტად ბევრი არგუმენტი"

#: app/flatpak-builtins-build-bundle.c:659
#: app/flatpak-builtins-build-commit-from.c:338
#: app/flatpak-builtins-build-commit-from.c:351
#: app/flatpak-builtins-build-import-bundle.c:145
#, c-format
msgid "'%s' is not a valid repository"
msgstr "'%s' არასწორი რეპოზიტორიაა"

#: app/flatpak-builtins-build-bundle.c:663
#, c-format
msgid "'%s' is not a valid repository: "
msgstr "'%s' არასწორი რეპოზიტორიაა: "

#: app/flatpak-builtins-build-bundle.c:674 app/flatpak-builtins-build-sign.c:88
#: common/flatpak-dir.c:14293
#, c-format
msgid "'%s' is not a valid name: %s"
msgstr "'%s' არასწორი სახელია: %s"

#: app/flatpak-builtins-build-bundle.c:677
#: app/flatpak-builtins-build-export.c:865 app/flatpak-builtins-build-sign.c:91
#: common/flatpak-dir.c:14299
#, c-format
msgid "'%s' is not a valid branch name: %s"
msgstr "'%s' ბრენჩის არასწორი სახელია: %s"

#: app/flatpak-builtins-build-bundle.c:691
#: app/flatpak-builtins-build-import-bundle.c:149
#: app/flatpak-builtins-build-init.c:281
#, c-format
msgid "'%s' is not a valid filename"
msgstr "'%s' არასწორი ფაილის სახელია"

#: app/flatpak-builtins-build-bundle.c:706
msgid "--oci-layer-compress value must be gzip or zstd"
msgstr ""

#: app/flatpak-builtins-build.c:49
msgid "Use Platform runtime rather than Sdk"
msgstr "SDK-ის მაგიერ პლატფორმის გაშვების გარემოს გამოყენება"

#: app/flatpak-builtins-build.c:50
msgid "Make destination readonly"
msgstr "სამიზნის მხოლოდ-წაკითხვის რეჟიმზე გადართვა"

#: app/flatpak-builtins-build.c:51
msgid "Add bind mount"
msgstr "მიბმული მიმაგრების დამატება"

#: app/flatpak-builtins-build.c:51
msgid "DEST=SRC"
msgstr "DEST=SRC"

#: app/flatpak-builtins-build.c:52
msgid "Start build in this directory"
msgstr "აგების ამ საქაღალდეში დაწყება"

#: app/flatpak-builtins-build.c:52 app/flatpak-builtins-build.c:53
#: app/flatpak-builtins-build-init.c:64 app/flatpak-builtins-run.c:160
msgid "DIR"
msgstr "საქაღალდე"

#: app/flatpak-builtins-build.c:53
msgid "Where to look for custom sdk dir (defaults to 'usr')"
msgstr ""
"ხელით მითითებული SDK-ის მოსაძებნი საქაღალდე (ნაგულისხმები მნიშვნელობაა 'usr')"

#: app/flatpak-builtins-build.c:54 app/flatpak-builtins-build-export.c:67
msgid "Use alternative file for the metadata"
msgstr "მეტამონაცემების სხვა ფაილის გამოყენება"

#: app/flatpak-builtins-build.c:55 app/flatpak-builtins-run.c:177
msgid "Kill processes when the parent process dies"
msgstr "პროცესების დახოცვა მშობელი პროცესის სიკვდილისას"

#: app/flatpak-builtins-build.c:56
msgid "Export application homedir directory to build"
msgstr "აპლიკაციის საწყისი საქაღალდის ასაგებად გატანა"

#: app/flatpak-builtins-build.c:57 app/flatpak-builtins-run.c:165
msgid "Log session bus calls"
msgstr "სესიის მატარებლის გამოძახებების ჟურნალი"

#: app/flatpak-builtins-build.c:58 app/flatpak-builtins-run.c:166
msgid "Log system bus calls"
msgstr "სისტემური მატარებლის გამოძახებების ჟურნალი"

#: app/flatpak-builtins-build.c:262
msgid "DIRECTORY [COMMAND [ARGUMENT…]] - Build in directory"
msgstr "საქაღალდე [ბრძანება [არგუმენტი…]] - აგების საქაღალდე"

#: app/flatpak-builtins-build.c:285 app/flatpak-builtins-build-finish.c:656
msgid "DIRECTORY must be specified"
msgstr "საქაღალდის მითითება აუცილებელია"

#: app/flatpak-builtins-build.c:296 app/flatpak-builtins-build-export.c:887
#, c-format
msgid "Build directory %s not initialized, use flatpak build-init"
msgstr ""
"აგების საქაღალდე %s ინიციალიზებული არაა. გამოიყენეთ flatpack build-init"

#: app/flatpak-builtins-build.c:315
msgid "metadata invalid, not application or runtime"
msgstr ""
"მეტამონაცემები არასწორია. არ წარმოადგენს არც აპლიკაციას, არც გაშვების გარემოს"

#: app/flatpak-builtins-build.c:446
#, c-format
msgid "No extension point matching %s in %s"
msgstr "%2$s-ში %1$s-ს გაფართოების წერტილი არ ემთხვევა"

#: app/flatpak-builtins-build.c:635
#, c-format
msgid "Missing '=' in bind mount option '%s'"
msgstr "მიბმული მიმაგრების პარამეტრში '%s' '=' მითითებული არაა"

#: app/flatpak-builtins-build.c:679 common/flatpak-run.c:3961
#, c-format
msgid "Unable to start app"
msgstr "აპის გასვების შეცდომა"

#: app/flatpak-builtins-build-commit-from.c:58
msgid "Source repo dir"
msgstr "საწყისი რეპოს საქაღალდე"

#: app/flatpak-builtins-build-commit-from.c:58
msgid "SRC-REPO"
msgstr "SRC-REPO"

#: app/flatpak-builtins-build-commit-from.c:59
msgid "Source repo ref"
msgstr "საწყისი რეპოს მიმართვა"

#: app/flatpak-builtins-build-commit-from.c:59
msgid "SRC-REF"
msgstr "SRC-REF"

#: app/flatpak-builtins-build-commit-from.c:64
#: app/flatpak-builtins-build-export.c:60
msgid "One line subject"
msgstr "ერთხაზიანი სათაური"

#: app/flatpak-builtins-build-commit-from.c:64
#: app/flatpak-builtins-build-export.c:60
msgid "SUBJECT"
msgstr "თემა"

#: app/flatpak-builtins-build-commit-from.c:65
#: app/flatpak-builtins-build-export.c:61
msgid "Full description"
msgstr "სრული აღწერა"

#: app/flatpak-builtins-build-commit-from.c:65
#: app/flatpak-builtins-build-export.c:61
msgid "BODY"
msgstr "BODY"

#: app/flatpak-builtins-build-commit-from.c:66
#: app/flatpak-builtins-build-export.c:64
#: app/flatpak-builtins-build-import-bundle.c:51
msgid "Update the appstream branch"
msgstr "Appstream ბრენჩის განახლება"

#: app/flatpak-builtins-build-commit-from.c:67
#: app/flatpak-builtins-build-export.c:65
#: app/flatpak-builtins-build-import-bundle.c:52
#: app/flatpak-builtins-build-update-repo.c:87
msgid "Don't update the summary"
msgstr "მიმოხილვა არ განახლდება"

#: app/flatpak-builtins-build-commit-from.c:68
#: app/flatpak-builtins-build-export.c:68
#: app/flatpak-builtins-build-import-bundle.c:49
#: app/flatpak-builtins-build-sign.c:44
msgid "GPG Key ID to sign the commit with"
msgstr "კომიტის ხელმოწერისთვის გამოყენებული GPG გასაღების ID"

#: app/flatpak-builtins-build-commit-from.c:70
#: app/flatpak-builtins-build-export.c:73
msgid "Mark build as end-of-life"
msgstr "აგების მხარდაჭერის ვადაამოწურულად მონიშვნა"

#: app/flatpak-builtins-build-commit-from.c:70
#: app/flatpak-builtins-build-export.c:73
msgid "REASON"
msgstr "REASON"

#: app/flatpak-builtins-build-commit-from.c:71
msgid ""
"Mark refs matching the OLDID prefix as end-of-life, to be replaced with the "
"given NEWID"
msgstr ""
"მიმართების, რომლებიც OLDID-ს ემთხვევა მხარდაჭერის ვადაამოწურულად მონიშვნა, "
"NEWID-ით ჩასანაცვლებლად"

#: app/flatpak-builtins-build-commit-from.c:71
msgid "OLDID=NEWID"
msgstr "OLDID=NEWID"

#: app/flatpak-builtins-build-commit-from.c:72
#: app/flatpak-builtins-build-export.c:75
msgid "Set type of token needed to install this commit"
msgstr "ამ კომიტის დასაყენებლად საჭირო კოდის ტიპის დაყენება"

#: app/flatpak-builtins-build-commit-from.c:72
#: app/flatpak-builtins-build-export.c:75
msgid "VAL"
msgstr "VAL"

#: app/flatpak-builtins-build-commit-from.c:73
msgid "Override the timestamp of the commit (NOW for current time)"
msgstr "კომიტის დროის შტამპის გადაფარვა (NOW - მიმდინარე დროს ნიშნავს)"

#: app/flatpak-builtins-build-commit-from.c:73
#: app/flatpak-builtins-build-export.c:76
msgid "TIMESTAMP"
msgstr "TIMESTAMP"

#: app/flatpak-builtins-build-commit-from.c:75
#: app/flatpak-builtins-build-export.c:80
#: app/flatpak-builtins-build-import-bundle.c:53
#: app/flatpak-builtins-build-update-repo.c:97
msgid "Don't generate a summary index"
msgstr "შეჯამების ინდექსი არ დაგენერირდება"

#: app/flatpak-builtins-build-commit-from.c:278
msgid "DST-REPO [DST-REF…] - Make a new commit from existing commits"
msgstr "DST-REPO [DST-REF…] - არსებული კომიტებისგან ახლი კომიტის შექმნა"

#: app/flatpak-builtins-build-commit-from.c:285
msgid "DST-REPO must be specified"
msgstr "DST-REPO-ის მითითება აუცილებელია"

#: app/flatpak-builtins-build-commit-from.c:293
msgid ""
"If --src-repo is not specified, exactly one destination ref must be specified"
msgstr ""
"თუ --src-repo მითითებული არაა, აუცილებელია ზუსტად ერთი სამიზნე მიმართვის "
"მითითება"

#: app/flatpak-builtins-build-commit-from.c:296
msgid ""
"If --src-ref is specified, exactly one destination ref must be specified"
msgstr ""
"თუ --src-ref მითითებულია, აუცილებელია ზუსტად ერთი სამიზნე მიმართვის მითითება"

#: app/flatpak-builtins-build-commit-from.c:299
msgid "Either --src-repo or --src-ref must be specified"
msgstr ""
"აუცილებელია მითითებული იყოს ერთ-ერთი პარამეტრებიდან --src-repo და --src-ref"

#: app/flatpak-builtins-build-commit-from.c:315
msgid "Invalid argument format of use  --end-of-life-rebase=OLDID=NEWID"
msgstr ""
"არასწორი არგუმენტის ფორმატი პარამეტრებისთვის  --end-of-life-"
"rebase=OLDID=NEWID"

#: app/flatpak-builtins-build-commit-from.c:321
#: app/flatpak-builtins-build-commit-from.c:324
#, c-format
msgid "Invalid name %s in --end-of-life-rebase"
msgstr "არასწორი სახელი %s პარამეტრში --end-of-life-rebase"

#: app/flatpak-builtins-build-commit-from.c:333
#: app/flatpak-builtins-build-export.c:1092
#, c-format
msgid "Could not parse '%s'"
msgstr "'%s'-ის დამუშავების შეცდომა"

#: app/flatpak-builtins-build-commit-from.c:498
msgid "Can't commit from partial source commit"
msgstr "ნაწილობრივი კოდის კომიტიდან კომიტი შეუძლებელია"

#: app/flatpak-builtins-build-commit-from.c:503
#, c-format
msgid "%s: no change\n"
msgstr "%s: ცვლილებების გარეშე\n"

#: app/flatpak-builtins-build-export.c:62
msgid "Architecture to export for (must be host compatible)"
msgstr ""
"არქიტექტურა, რომლისთვისაც გატანა მოხდება (აუცილებელია, ჰოსტთან იყოს "
"თავსებადი)"

#: app/flatpak-builtins-build-export.c:63
msgid "Commit runtime (/usr), not /app"
msgstr "გაშვების გარემოს (/usr) კომიტი, /app კი არა"

#: app/flatpak-builtins-build-export.c:66
msgid "Use alternative directory for the files"
msgstr "ფაილებისთვის სხვა საქაღალდის გამოყენება"

#: app/flatpak-builtins-build-export.c:66
msgid "SUBDIR"
msgstr "SUBDIR"

#: app/flatpak-builtins-build-export.c:69
msgid "Files to exclude"
msgstr "ამოსაღები ფაილები"

#: app/flatpak-builtins-build-export.c:69
#: app/flatpak-builtins-build-export.c:70
#: app/flatpak-builtins-build-update-repo.c:90
msgid "PATTERN"
msgstr "შაბლონი"

#: app/flatpak-builtins-build-export.c:70
msgid "Excluded files to include"
msgstr "ჩასასმელი ამოღებული ფაილები"

#: app/flatpak-builtins-build-export.c:74
msgid "Mark build as end-of-life, to be replaced with the given ID"
msgstr ""
"აგების მხარდაჭერის ვადაამოწურულად მონიშვნა, მითითებული ID-ით ჩანასანცვლებლად"

#: app/flatpak-builtins-build-export.c:74
#: app/flatpak-builtins-document-list.c:49 app/flatpak-cli-transaction.c:1427
msgid "ID"
msgstr "ID"

#: app/flatpak-builtins-build-export.c:76
msgid "Override the timestamp of the commit"
msgstr "კომიტის დროის შტამპის გადაფარვა"

#: app/flatpak-builtins-build-export.c:77
#: app/flatpak-builtins-build-update-repo.c:75
#: app/flatpak-builtins-remote-add.c:83 app/flatpak-builtins-remote-list.c:54
#: app/flatpak-builtins-remote-modify.c:88
msgid "Collection ID"
msgstr "კოლექციის ID"

#: app/flatpak-builtins-build-export.c:472
#, c-format
msgid "WARNING: Error running desktop-file-validate: %s\n"
msgstr "გაფრთხილება: desktop-file-validate-ის გაშვების შეცდომა: %s\n"

#: app/flatpak-builtins-build-export.c:480
#, c-format
msgid "WARNING: Error reading from desktop-file-validate: %s\n"
msgstr "გაფრთხილება: desktop-file-validate-დან წაკითხვის შეცდომა: %s\n"

#: app/flatpak-builtins-build-export.c:486
#, c-format
msgid "WARNING: Failed to validate desktop file %s: %s\n"
msgstr "გაფრთხილება:სამუშაო მაგიდის ფაილის %s გადამოწმების შეცდომა: %s\n"

#: app/flatpak-builtins-build-export.c:513
#, c-format
msgid "WARNING: Can't find Exec key in %s: %s\n"
msgstr "გაფრთხილება: %s-ში პარამეტრი Exec აღმოჩენილი არაა: %s\n"

#: app/flatpak-builtins-build-export.c:521
#: app/flatpak-builtins-build-export.c:614
#, c-format
msgid "WARNING: Binary not found for Exec line in %s: %s\n"
msgstr "გაფრთხილება: ხაზისთვის Exec %s-ში გამშვები ფაილი აღმოჩენილი არაა: %s\n"

#: app/flatpak-builtins-build-export.c:529
#, c-format
msgid "WARNING: Icon not matching app id in %s: %s\n"
msgstr "გაფრთხილება: %s-ში ხატულა აპის ID-ს არ ემთხვევა: %s\n"

#: app/flatpak-builtins-build-export.c:552
#, c-format
msgid "WARNING: Icon referenced in desktop file but not exported: %s\n"
msgstr ""
"გაფრთხილება: სამუშაო მაგიდის ფაილში ხატულაზე მიმართვა არსებობს, მაგრამ "
"გატანილი არაა: %s\n"

#: app/flatpak-builtins-build-export.c:719
#, c-format
msgid "Invalid uri type %s, only http/https supported"
msgstr "არასწორი URI-ის ტიპი %s, მხარდაჭერილია მხოლოდ http/https"

#: app/flatpak-builtins-build-export.c:737
#, c-format
msgid "Unable to find basename in %s, specify a name explicitly"
msgstr "%s-ში საბაზისო სახელი ვერ ვიპოვე. მიუთითეთ ის"

#: app/flatpak-builtins-build-export.c:746
#, c-format
msgid "No slashes allowed in extra data name"
msgstr "დამატებითი მონაცემების სახელში დახრილი ხაზები დაშვებული არაა"

#: app/flatpak-builtins-build-export.c:758
#, c-format
msgid "Invalid format for sha256 checksum: '%s'"
msgstr "SHA256 საკონტროლო ჯამის არასწორი ფორმატი: '%s'"

#: app/flatpak-builtins-build-export.c:768
#, c-format
msgid "Extra data sizes of zero not supported"
msgstr "ნულოვანი ზომის დამატებითი მონაცემები მხარდაჭერილი არაა"

#: app/flatpak-builtins-build-export.c:830
msgid ""
"LOCATION DIRECTORY [BRANCH] - Create a repository from a build directory"
msgstr "LOCATION DIRECTORY [BRANCH] - აგების საქაღალდიდან რეპოზიტორიის შექმნა"

#: app/flatpak-builtins-build-export.c:838
msgid "LOCATION and DIRECTORY must be specified"
msgstr "LOCATION და DIRECTORY მითითება აუცილებელია"

#: app/flatpak-builtins-build-export.c:859
#: app/flatpak-builtins-remote-add.c:327
#, c-format
msgid "‘%s’ is not a valid collection ID: %s"
msgstr "‘%s’ არასწორი კოლექციის ID-ია: %s"

#: app/flatpak-builtins-build-export.c:904
#: app/flatpak-builtins-build-finish.c:684
msgid "No name specified in the metadata"
msgstr "მეტამონაცემებში სახელი მითითებული არაა"

#: app/flatpak-builtins-build-export.c:1166
#, c-format
msgid "Commit: %s\n"
msgstr "კომიტი: %s\n"

#: app/flatpak-builtins-build-export.c:1167
#, c-format
msgid "Metadata Total: %u\n"
msgstr "მეტამონაცემები სულ: %u\n"

#: app/flatpak-builtins-build-export.c:1168
#, c-format
msgid "Metadata Written: %u\n"
msgstr "ჩაწერილი მეტამონაცემები: %u\n"

#: app/flatpak-builtins-build-export.c:1169
#, c-format
msgid "Content Total: %u\n"
msgstr "შემცველობა სულ: %u\n"

#: app/flatpak-builtins-build-export.c:1170
#, c-format
msgid "Content Written: %u\n"
msgstr "ჩაწერილი შემცველობა: %u\n"

#: app/flatpak-builtins-build-export.c:1171
#, c-format
msgid "Content Bytes Written:"
msgstr "ჩაწერილი შემცველობის ბაიტები:"

#: app/flatpak-builtins-build-finish.c:52
msgid "Command to set"
msgstr "დასაყენებელი ბრძანება"

#: app/flatpak-builtins-build-finish.c:52 app/flatpak-builtins-run.c:159
#: app/flatpak-main.c:209
msgid "COMMAND"
msgstr "ბრძანება"

#: app/flatpak-builtins-build-finish.c:53
msgid "Flatpak version to require"
msgstr "Flatpak-ის აუცილებელი ვერსია"

#: app/flatpak-builtins-build-finish.c:53
msgid "MAJOR.MINOR.MICRO"
msgstr "MAJOR.MINOR.MICRO"

#: app/flatpak-builtins-build-finish.c:54
msgid "Don't process exports"
msgstr "გატანები არ დამუშავდება"

#: app/flatpak-builtins-build-finish.c:55
msgid "Extra data info"
msgstr "ინფორმაცია დამატებით მონაცემებზე"

#: app/flatpak-builtins-build-finish.c:56 app/flatpak-builtins-build-init.c:63
msgid "Add extension point info"
msgstr "გაფართოების წერტილის ინფორმაციის დამატება"

#: app/flatpak-builtins-build-finish.c:56 app/flatpak-builtins-build-init.c:63
msgid "NAME=VARIABLE[=VALUE]"
msgstr "სახელი=ცვლადი[=მნიშვნელობა]"

#: app/flatpak-builtins-build-finish.c:57
msgid "Remove extension point info"
msgstr "გაფართოების წერტილის ინფორმაციის წაშლა"

#: app/flatpak-builtins-build-finish.c:57
#: app/flatpak-builtins-build-update-repo.c:79 app/flatpak-builtins-info.c:58
#: app/flatpak-builtins-remote-add.c:88 app/flatpak-builtins-remote-modify.c:94
#: app/flatpak-main.c:182
msgid "NAME"
msgstr "სახელი"

#: app/flatpak-builtins-build-finish.c:58
msgid "Set extension priority (only for extensions)"
msgstr "გაფართოების პრიორიტეტის დაყენება (მხოლოდ გაფართოებებისთვის)"

#: app/flatpak-builtins-build-finish.c:58
msgid "VALUE"
msgstr "მნიშვნელობა"

#: app/flatpak-builtins-build-finish.c:59
msgid "Change the sdk used for the app"
msgstr "აპისთვის გამოყენებული SDK-ის შეცვლა"

#: app/flatpak-builtins-build-finish.c:59
msgid "SDK"
msgstr "SDK"

#: app/flatpak-builtins-build-finish.c:60
msgid "Change the runtime used for the app"
msgstr "აპისთვის გამოყენებული გაშვების გარემოს შეცვლა"

#: app/flatpak-builtins-build-finish.c:60 app/flatpak-builtins-build-init.c:54
#: app/flatpak-builtins-list.c:53 app/flatpak-builtins-remote-ls.c:58
#: app/flatpak-builtins-run.c:163
msgid "RUNTIME"
msgstr "RUNTIME"

#: app/flatpak-builtins-build-finish.c:61
msgid "Set generic metadata option"
msgstr "ზოგადი მეტამონაცემების პარამეტრის დაყენება"

#: app/flatpak-builtins-build-finish.c:61
msgid "GROUP=KEY[=VALUE]"
msgstr "GROUP=KEY[=VALUE]"

#: app/flatpak-builtins-build-finish.c:62
msgid "Don't inherit permissions from runtime"
msgstr "გაშვების გარემოს წვდომების არ გამოყენება"

#: app/flatpak-builtins-build-finish.c:155
#, c-format
msgid "Not exporting %s, wrong extension\n"
msgstr "%s გატანილი არ იქნება. გაფართოება არასწორია\n"

#: app/flatpak-builtins-build-finish.c:163
#, c-format
msgid "Not exporting %s, non-allowed export filename\n"
msgstr "%s გატანილი არ იქნება. გატანის დაუშვებელი ფაილის სახელი\n"

#: app/flatpak-builtins-build-finish.c:167
#, c-format
msgid "Exporting %s\n"
msgstr "%s-ის გატანა\n"

#: app/flatpak-builtins-build-finish.c:440
#, c-format
msgid "More than one executable found\n"
msgstr "აღმოჩენილია ერთზე მეტი გამშვები ფაილი\n"

#: app/flatpak-builtins-build-finish.c:451
#, c-format
msgid "Using %s as command\n"
msgstr "%s გამოიყენება, როგორც ბრძანება\n"

#: app/flatpak-builtins-build-finish.c:456
#, c-format
msgid "No executable found\n"
msgstr "გამშვები ფაილი ვერ ვიპოვე\n"

#: app/flatpak-builtins-build-finish.c:511
#, c-format
msgid "Invalid --require-version argument: %s"
msgstr "არასწორი --require-version არგუმენტი: %s"

#: app/flatpak-builtins-build-finish.c:543
#, c-format
msgid "Too few elements in --extra-data argument %s"
msgstr "მეტისმეტად ცოტა ელემენტი --extra-data არგუმენტში %s"

#: app/flatpak-builtins-build-finish.c:575
#, c-format
msgid ""
"Too few elements in --metadata argument %s, format should be "
"GROUP=KEY[=VALUE]]"
msgstr ""
"მეტისმეტად ცოტა ელემენტი --metadata არგუმენტში %s. ფორმატი უნდა იყოს "
"GROUP=KEY[=VALUE]]"

#: app/flatpak-builtins-build-finish.c:597
#: app/flatpak-builtins-build-init.c:458
#, c-format
msgid ""
"Too few elements in --extension argument %s, format should be "
"NAME=VAR[=VALUE]"
msgstr ""
"მეტისმეტად ცოტა ელემენტი --extension არგუმენტში %s, ფორმატი უნდა იყოს "
"NAME=VAR[=VALUE]"

#: app/flatpak-builtins-build-finish.c:603
#: app/flatpak-builtins-build-init.c:461
#, c-format
msgid "Invalid extension name %s"
msgstr "გაფართოების არასწორი სახელი: %s"

#: app/flatpak-builtins-build-finish.c:646
msgid "DIRECTORY - Finalize a build directory"
msgstr "საქაღალდე - აგების საქაღალდის დასრულება"

#: app/flatpak-builtins-build-finish.c:668
#, c-format
msgid "Build directory %s not initialized"
msgstr "აგების საქაღალდე %s ინიციალიზებული არაა"

#: app/flatpak-builtins-build-finish.c:689
#, c-format
msgid "Build directory %s already finalized"
msgstr "აგების საქაღალდე %s უკვე ინიციალიზებულია"

#: app/flatpak-builtins-build-finish.c:702
#, c-format
msgid "Please review the exported files and the metadata\n"
msgstr "გადახედეთ გატანილ ფაილებს და მეტამონაცემებს\n"

#: app/flatpak-builtins-build-import-bundle.c:47
msgid "Override the ref used for the imported bundle"
msgstr "შემოტანილი პაკეტისთვის გამოყენებული მიმართვის გადაფარვა"

#: app/flatpak-builtins-build-import-bundle.c:47
msgid "REF"
msgstr "REF"

#: app/flatpak-builtins-build-import-bundle.c:48
msgid "Import oci image instead of flatpak bundle"
msgstr "Flatpak-ის პაკეტის მაგიერ OCI ასლის გატანა"

#: app/flatpak-builtins-build-import-bundle.c:77
#: app/flatpak-builtins-build-import-bundle.c:105
#, c-format
msgid "Importing %s (%s)\n"
msgstr "%s-ის (%s) შემოტანა\n"

#: app/flatpak-builtins-build-import-bundle.c:126
msgid "LOCATION FILENAME - Import a file bundle into a local repository"
msgstr "LOCATION FILENAME - ლოკალურ რეპოზიტორიაში ფაილის პაკეტის შემოტანა"

#: app/flatpak-builtins-build-import-bundle.c:133
msgid "LOCATION and FILENAME must be specified"
msgstr "LOCATION და FILENAME მითითება აუცილებელია"

#: app/flatpak-builtins-build-init.c:53 app/flatpak-builtins-info.c:55
#: app/flatpak-builtins-run.c:158
msgid "Arch to use"
msgstr "გამოსაყენებელი არქიტექტურა"

#: app/flatpak-builtins-build-init.c:54
msgid "Initialize var from named runtime"
msgstr "ცვლადის ინიციალიზაცია მითითებული გაშვების გარემოდან"

#: app/flatpak-builtins-build-init.c:55
msgid "Initialize apps from named app"
msgstr "აპების ინიციალიზაცია მითითბული აპიდან"

#: app/flatpak-builtins-build-init.c:55
msgid "APP"
msgstr "APP"

#: app/flatpak-builtins-build-init.c:56
msgid "Specify version for --base"
msgstr "მიუთითეთ ვერსია --base პარამეტრისთვის"

#: app/flatpak-builtins-build-init.c:56 app/flatpak-builtins-run.c:164
msgid "VERSION"
msgstr "VERSION"

#: app/flatpak-builtins-build-init.c:57
msgid "Include this base extension"
msgstr "ამ საბაზისო გაფართოების ჩასმა"

#: app/flatpak-builtins-build-init.c:57 app/flatpak-builtins-build-init.c:62
msgid "EXTENSION"
msgstr "EXTENSION"

#: app/flatpak-builtins-build-init.c:58
msgid "Extension tag to use if building extension"
msgstr "გაფართოების აგების შემთხვევაში გამოყენებული გაფართოების ჭდე"

#: app/flatpak-builtins-build-init.c:58
msgid "EXTENSION_TAG"
msgstr "EXTENSION_TAG"

#: app/flatpak-builtins-build-init.c:59
msgid "Initialize /usr with a writable copy of the sdk"
msgstr "/usr-ის ინიციალიზაცია SDK-ის ჩაწერადი ასლით"

#: app/flatpak-builtins-build-init.c:60
msgid "Specify the build type (app, runtime, extension)"
msgstr "მიუთითეთ აგების ტიპი (app, runtime, extension)"

#: app/flatpak-builtins-build-init.c:60
msgid "TYPE"
msgstr "ტიპი"

#: app/flatpak-builtins-build-init.c:61
msgid "Add a tag"
msgstr "ჭდის დამატება"

#: app/flatpak-builtins-build-init.c:61
msgid "TAG"
msgstr "ჭდე"

#: app/flatpak-builtins-build-init.c:62
msgid "Include this sdk extension in /usr"
msgstr "ამ SDK-ის გაფართოების /usr-ში ჩასმა"

#: app/flatpak-builtins-build-init.c:64
msgid "Where to store sdk (defaults to 'usr')"
msgstr "სად შევინახო SDK (ნაგულისხმებია 'usr')"

#: app/flatpak-builtins-build-init.c:65
msgid "Re-initialize the sdk/var"
msgstr "SDK/var-ის თავიდან ინიციალიზაცია"

#: app/flatpak-builtins-build-init.c:118
#, c-format
msgid "Requested extension %s/%s/%s is only partially installed"
msgstr "მოთხოვნილი გაფართოება %s/%s/%s მხოლოდ ნაწილობრივაა დაყენებული"

#: app/flatpak-builtins-build-init.c:147
#, c-format
msgid "Requested extension %s/%s/%s not installed"
msgstr "მოთხოვნილი გაფართოება %s/%s/%s დაყენებული არაა"

#: app/flatpak-builtins-build-init.c:207
msgid ""
"DIRECTORY APPNAME SDK RUNTIME [BRANCH] - Initialize a directory for building"
msgstr ""
"საქაღალდე აპისსახელი SDK გაშვებისგარემო [ბრენჩი] - საქაღალდის ინიციალიზაცია "
"აგებისთვის"

#: app/flatpak-builtins-build-init.c:214
msgid "RUNTIME must be specified"
msgstr "გაშვებისგარემოს მითითება აუცილებელია"

#: app/flatpak-builtins-build-init.c:235
#, c-format
msgid "'%s' is not a valid build type name, use app, runtime or extension"
msgstr ""
"'%s' აგების სწორი ტიპი არაა. გამოიყენეთ ერთერთი app, runtime ან extension"

#: app/flatpak-builtins-build-init.c:241 app/flatpak-builtins-override.c:79
#, c-format
msgid "'%s' is not a valid application name: %s"
msgstr "'%s' აპლიკაციის სწორი სახელი არაა: %s"

#: app/flatpak-builtins-build-init.c:295
#, c-format
msgid "Build directory %s already initialized"
msgstr "აგების საქაღალდე %s უკვე ინიციალიზებულია"

#: app/flatpak-builtins-build-sign.c:42 app/flatpak-builtins-install.c:67
#: app/flatpak-builtins-remote-info.c:54
msgid "Arch to install for"
msgstr "პროგრამები არქიტექტურისთვის"

#: app/flatpak-builtins-build-sign.c:43 app/flatpak-builtins-create-usb.c:48
#: app/flatpak-builtins-install.c:74 app/flatpak-builtins-remote-info.c:56
#: app/flatpak-builtins-uninstall.c:58 app/flatpak-builtins-update.c:64
msgid "Look for runtime with the specified name"
msgstr "მითითებული სახელის მქონე გაშვების გარემოს მოძებნა"

#: app/flatpak-builtins-build-sign.c:66
msgid "LOCATION [ID [BRANCH]] - Sign an application or runtime"
msgstr "მდებარეობა [ID [ბრენჩი]] - აპლიკაციის ან გაშვების გარემოს ხელმოწერა"

#: app/flatpak-builtins-build-sign.c:73
#: app/flatpak-builtins-build-update-repo.c:499
#: app/flatpak-builtins-remote-add.c:320 app/flatpak-builtins-repo.c:739
msgid "LOCATION must be specified"
msgstr "მდებარეობის მითითება აუცილებელია"

#: app/flatpak-builtins-build-sign.c:94
msgid "No gpg key ids specified"
msgstr "GPG გასაღების ID-ები მითითებული არაა"

#: app/flatpak-builtins-build-update-repo.c:68
msgid "Redirect this repo to a new URL"
msgstr "ამ რეპოზიტორიის ახალ URL-ზე გადამისამართება"

#: app/flatpak-builtins-build-update-repo.c:69
msgid "A nice name to use for this repository"
msgstr "მისაღები სახელი ამ რეპოზიტორიისთვის"

#: app/flatpak-builtins-build-update-repo.c:69
#: app/flatpak-builtins-remote-add.c:77 app/flatpak-builtins-remote-modify.c:82
msgid "TITLE"
msgstr "სათაური"

#: app/flatpak-builtins-build-update-repo.c:70
msgid "A one-line comment for this repository"
msgstr "ამ რეპოზიტორიის ერთხაზიანი კომენტარი"

#: app/flatpak-builtins-build-update-repo.c:70
#: app/flatpak-builtins-remote-add.c:78 app/flatpak-builtins-remote-modify.c:83
msgid "COMMENT"
msgstr "კომენტარი"

#: app/flatpak-builtins-build-update-repo.c:71
msgid "A full-paragraph description for this repository"
msgstr "სრული პარაგრაფის სიგრძის მქონე კომენტარი ამ რეპოზიტორიისთვის"

#: app/flatpak-builtins-build-update-repo.c:71
#: app/flatpak-builtins-remote-add.c:79 app/flatpak-builtins-remote-modify.c:84
msgid "DESCRIPTION"
msgstr "აღწერა"

#: app/flatpak-builtins-build-update-repo.c:72
msgid "URL for a website for this repository"
msgstr "ამ რეპოზიტორიის ვებსაიტის URL"

#: app/flatpak-builtins-build-update-repo.c:73
msgid "URL for an icon for this repository"
msgstr "ამ რეპოზიტორიის ხატულის URL"

#: app/flatpak-builtins-build-update-repo.c:74
msgid "Default branch to use for this repository"
msgstr "ამ რეპოზიტორიისთვის გამოსაყენებელი ნაგულისხმები ბრენჩი"

#: app/flatpak-builtins-build-update-repo.c:74
#: app/flatpak-builtins-remote-add.c:82 app/flatpak-builtins-remote-modify.c:87
#: app/flatpak-builtins-repo.c:713 app/flatpak-builtins-repo.c:714
#: app/flatpak-builtins-run.c:161
msgid "BRANCH"
msgstr "BRANCH"

#: app/flatpak-builtins-build-update-repo.c:75
#: app/flatpak-builtins-remote-add.c:83 app/flatpak-builtins-remote-modify.c:88
msgid "COLLECTION-ID"
msgstr "COLLECTION-ID"

#. Translators: A sideload is when you install from a local USB drive rather than the Internet.
#: app/flatpak-builtins-build-update-repo.c:77
msgid ""
"Permanently deploy collection ID to client remote configurations, only for "
"sideload support"
msgstr ""
"კოლექციის ID-ების სამუდამო გაშლა კლიენტის დაშორებულ კონფიგურაციებზე, მხოლოდ "
"გვერდითი ჩატვირთვის მხარდაჭერისთვის"

#: app/flatpak-builtins-build-update-repo.c:78
msgid "Permanently deploy collection ID to client remote configurations"
msgstr "კოლექციის ID-ების სამუდამო გაშლა კლიენტის დაშორებულ კონფიგურაციებზე"

#: app/flatpak-builtins-build-update-repo.c:79
msgid "Name of authenticator for this repository"
msgstr "ამ რეპოზიტორიის ავთენტიკატორის სახელი"

#: app/flatpak-builtins-build-update-repo.c:80
msgid "Autoinstall authenticator for this repository"
msgstr "ამ რეპოზიტორიის ავთენტიკატორის ავტომატური დაყენება"

#: app/flatpak-builtins-build-update-repo.c:81
msgid "Don't autoinstall authenticator for this repository"
msgstr "ამ რეპოზიტორიისთვის ავთენტიკატორი ავტომატურად დაყენებული არ იქნება"

#: app/flatpak-builtins-build-update-repo.c:82
#: app/flatpak-builtins-remote-add.c:89
msgid "Authenticator option"
msgstr "ავთენტიკატორის პარამეტრი"

#: app/flatpak-builtins-build-update-repo.c:82
#: app/flatpak-builtins-remote-add.c:89 app/flatpak-builtins-remote-modify.c:95
msgid "KEY=VALUE"
msgstr "KEY=VALUE"

#: app/flatpak-builtins-build-update-repo.c:83
msgid "Import new default GPG public key from FILE"
msgstr "ახალი ნაგულისხმები GPG საჯარო გასაღების შემოტანა მითითებული ფაილიდან"

#: app/flatpak-builtins-build-update-repo.c:84
msgid "GPG Key ID to sign the summary with"
msgstr "მიმოხილვის ხელმოწერა მითითებული ID-ის მქონე GPG გასაღებით"

#: app/flatpak-builtins-build-update-repo.c:86
msgid "Generate delta files"
msgstr "დელტა ფაილების გენერაცია"

#: app/flatpak-builtins-build-update-repo.c:88
msgid "Don't update the appstream branch"
msgstr "Appstream ბრენჩის არ განახლდება"

#: app/flatpak-builtins-build-update-repo.c:89
msgid "Max parallel jobs when creating deltas (default: NUMCPUs)"
msgstr ""
"დელტას შექმნისას გამოყენებული პარალელური დავალებების რაოდენობა "
"(ნაგულისხმები: ბირთვების რაოდენობა)"

#: app/flatpak-builtins-build-update-repo.c:89
msgid "NUM-JOBS"
msgstr "NUM-JOBS"

#: app/flatpak-builtins-build-update-repo.c:90
msgid "Don't create deltas matching refs"
msgstr "დელტები, რომლებიც მიმართვებს ემთხვევა, არ შეიქმნება"

#: app/flatpak-builtins-build-update-repo.c:91
msgid "Prune unused objects"
msgstr "გამოუყენებელი ობიექტების წაკვეთა"

#: app/flatpak-builtins-build-update-repo.c:92
msgid "Prune but don't actually remove anything"
msgstr "წაკვეთა, მაგრამ რეალურად არაფრის წაშლა"

#: app/flatpak-builtins-build-update-repo.c:93
msgid "Only traverse DEPTH parents for each commit (default: -1=infinite)"
msgstr ""
"თითოეული კომიტით მშობლებში მხოლოდ მითითებული სიღრმით ჩასვლა (ნაგულისხმები: "
"-1 = უსასრულო)"

#: app/flatpak-builtins-build-update-repo.c:93
msgid "DEPTH"
msgstr "DEPTH"

#: app/flatpak-builtins-build-update-repo.c:223
#, c-format
msgid "Generating delta: %s (%.10s)\n"
msgstr "დეტალს გენერაცია: %s (%.10s)\n"

#: app/flatpak-builtins-build-update-repo.c:225
#, c-format
msgid "Generating delta: %s (%.10s-%.10s)\n"
msgstr "დელტას გენერაცია: %s (%.10s-%.10s)\n"

#: app/flatpak-builtins-build-update-repo.c:233
#, c-format
msgid "Failed to generate delta %s (%.10s): "
msgstr "დელტა %s (%.10s) არ დაგენერირდება: "

#: app/flatpak-builtins-build-update-repo.c:236
#, c-format
msgid "Failed to generate delta %s (%.10s-%.10s): "
msgstr "დელტას %s (%.10s-%.10s) გენერაციის შეცდომა: "

#: app/flatpak-builtins-build-update-repo.c:492
msgid "LOCATION - Update repository metadata"
msgstr "მდებარეობა - რეპოზიტორიის მეტამონაცემის განახლება"

#: app/flatpak-builtins-build-update-repo.c:609
#, c-format
msgid "Updating appstream branch\n"
msgstr "Appstream ბრენჩის განახლება\n"

#: app/flatpak-builtins-build-update-repo.c:638
#, c-format
msgid "Updating summary\n"
msgstr "მიმოხილვის განახლება\n"

#: app/flatpak-builtins-build-update-repo.c:664
#, c-format
msgid "Total objects: %u\n"
msgstr "სულ ობიექტები: %u\n"

#: app/flatpak-builtins-build-update-repo.c:666
#, c-format
msgid "No unreachable objects\n"
msgstr "მიუწვდომელი დოკუმენტების გარეშე\n"

#: app/flatpak-builtins-build-update-repo.c:668
#, c-format
msgid "Deleted %u objects, %s freed\n"
msgstr "წაიშალა %u ობიექტი. გათავისუფლდა %s\n"

#: app/flatpak-builtins-config.c:41
msgid "List configuration keys and values"
msgstr "კონფიგურაციის პარამეტრების და მათი მნიშვნელობების გამოტანა"

#: app/flatpak-builtins-config.c:42
msgid "Get configuration for KEY"
msgstr "პარამეტრის კონფიგურაციის მიღება"

#: app/flatpak-builtins-config.c:43
msgid "Set configuration for KEY to VALUE"
msgstr "კონფიგურაციის პარამეტრის მითითებულ მნიშვნელობაზე დაყენება"

#: app/flatpak-builtins-config.c:44
msgid "Unset configuration for KEY"
msgstr "პარამეტრის მნიშვნელობის წაშლა"

#: app/flatpak-builtins-config.c:149
#, c-format
msgid "'%s' does not look like a language/locale code"
msgstr "'%s' ლოკალის/ენის კოდს არ წააგავს"

#: app/flatpak-builtins-config.c:172
#, c-format
msgid "'%s' does not look like a language code"
msgstr "'%s' ენის კოდს არ წააგავს"

#: app/flatpak-builtins-config.c:190
#, fuzzy, c-format
msgid "'%s' is not a valid value (use 'true' or 'false')"
msgstr "'%s' არასწორი რეპოზიტორიაა: "

#: app/flatpak-builtins-config.c:262
#, c-format
msgid "Unknown configure key '%s'"
msgstr "უცნობი კონფიგურაციის პარამეტრი '%s'"

#: app/flatpak-builtins-config.c:284
msgid "Too many arguments for --list"
msgstr "მეტისმეტად ბევრი არგუმენტი პარამეტრისთვის --list"

#: app/flatpak-builtins-config.c:314 app/flatpak-builtins-config.c:362
msgid "You must specify KEY"
msgstr "გასაღების მითითება აუცილებელია"

#: app/flatpak-builtins-config.c:316
msgid "Too many arguments for --get"
msgstr "მეტისმეტად ბევრი არგუმენტი პარამეტრისთვის --get"

#: app/flatpak-builtins-config.c:338
msgid "You must specify KEY and VALUE"
msgstr "პარამეტრის და მნიშვნელობის მითითება აუცილებელია"

#: app/flatpak-builtins-config.c:340
msgid "Too many arguments for --set"
msgstr "მეტისმეტად ბევრი არგუმენტი პარამეტრისთვის --set"

#: app/flatpak-builtins-config.c:364
msgid "Too many arguments for --unset"
msgstr "მეტისმეტად ბევრი არგუმენტი პარამეტრისთვის --unset"

#: app/flatpak-builtins-config.c:383
msgid "[KEY [VALUE]] - Manage configuration"
msgstr "[პარამეტრი [მნიშვნელობა]] - კონფიგურაციის მართვა"

#: app/flatpak-builtins-config.c:394
msgid "Can only use one of --list, --get, --set or --unset"
msgstr ""
"პარამეტრებიდან --list, --get, --set და --unset მხოლოდ ერთ-ერთის გამოყენება "
"შეგიძლიათ"

#: app/flatpak-builtins-config.c:408
msgid "Must specify one of --list, --get, --set or --unset"
msgstr ""
"პარამეტრებიდან --list, --get, --set და --unset ერთ-ერთის მითითება აუცილებელია"

#: app/flatpak-builtins-create-usb.c:45 app/flatpak-builtins-install.c:75
#: app/flatpak-builtins-remote-info.c:57 app/flatpak-builtins-uninstall.c:59
#: app/flatpak-builtins-update.c:65
msgid "Look for app with the specified name"
msgstr "მითითებული სახელის მქონე აპის მოძებნა"

#: app/flatpak-builtins-create-usb.c:46
msgid "Arch to copy"
msgstr "დასაკოპირებელი არქიტექტურა"

#: app/flatpak-builtins-create-usb.c:47
msgid "DEST"
msgstr "DEST"

#: app/flatpak-builtins-create-usb.c:49
msgid "Allow partial commits in the created repo"
msgstr "შექმნილ რეპოზიტორიაში ნაწილობრივი კომიტების დაშვება"

#: app/flatpak-builtins-create-usb.c:125 app/flatpak-builtins-create-usb.c:165
#, c-format
msgid ""
"Warning: Related ref ‘%s’ is partially installed. Use --allow-partial to "
"suppress this message.\n"
msgstr ""
"გაფრთხილება: შესაბამისი მიმართვა '%s' ნაწილობრივაა დაყენებული. ამ "
"შეტყობინების მოსაცილებლად გამოიყენეთ პარამეტრი --allow-partial.\n"

#: app/flatpak-builtins-create-usb.c:158
#, c-format
msgid "Warning: Omitting related ref ‘%s’ because it is not installed.\n"
msgstr ""
"გაფრთხილება: შესაბამისი მიმართვის '%s' გამოტოვება, რადგან ის დაყენებული "
"არაა.\n"

#: app/flatpak-builtins-create-usb.c:175
#, c-format
msgid ""
"Warning: Omitting related ref ‘%s’ because its remote ‘%s’ does not have a "
"collection ID set.\n"
msgstr ""
"გაფრთხილება: შესაბამისი მიმართვის '%s' გამოტოვება, რადგან მის დაშორებულს "
"'%s' კოლექციის ID დაყენებული არ აქვს.\n"

#: app/flatpak-builtins-create-usb.c:187
#, c-format
msgid "Warning: Omitting related ref ‘%s’ because it's extra-data.\n"
msgstr ""
"გაფრთხილება. შესაბამისი მიმართვის '%s' გამოტოვება, რადგან მას დამატებითი "
"მონაცემები გააჩნია.\n"

#: app/flatpak-builtins-create-usb.c:262 app/flatpak-builtins-create-usb.c:637
#, c-format
msgid ""
"Remote ‘%s’ does not have a collection ID set, which is required for P2P "
"distribution of ‘%s’."
msgstr ""
"დაშორებულს '%s' კოლექციის ID დაყენებული არ აქვს. ეს კი აუცილებელია '%s'ის "
"P2P დისტრიბუციისთვის."

#: app/flatpak-builtins-create-usb.c:272
#, c-format
msgid "Warning: Omitting ref ‘%s’ (runtime of ‘%s’) because it's extra-data.\n"
msgstr ""
"გაფრთხილება. შესაბამისი მიმართვის '%s' ('%s'-ის გაშვები გარემო) გამოტოვება, "
"რადგან მას დამატებითი მონაცემები გააჩნია.\n"

#: app/flatpak-builtins-create-usb.c:484
msgid "MOUNT-PATH [REF…] - Copy apps or runtimes onto removable media"
msgstr ""
"მიმაგრების-ბილიკი [მიმართვა...] - აპების ან გაშვების გარემოების კოპირება "
"მოხსნად მედიაზე"

#: app/flatpak-builtins-create-usb.c:493
msgid "MOUNT-PATH and REF must be specified"
msgstr "მიმაგრების-წერტილის და მიმართვის მითითება აუცილებელია"

#: app/flatpak-builtins-create-usb.c:607
#, c-format
msgid "Ref ‘%s’ found in multiple installations: %s. You must specify one."
msgstr ""
"მიმართვა '%s' მრავალ დაყენებაშია აღმოჩენილი: %s. აუცილებელია, მხოლოდ ერთი "
"მიუთითოთ."

#: app/flatpak-builtins-create-usb.c:620
#, c-format
msgid "Refs must all be in the same installation (found in %s and %s)."
msgstr "მიმართვები ყველა იგივე დაყენებაში უნდა იყოს (ნაპოვნია %s-ში და %s-ში)."

#: app/flatpak-builtins-create-usb.c:670
#, c-format
msgid ""
"Warning: Ref ‘%s’ is partially installed. Use --allow-partial to suppress "
"this message.\n"
msgstr ""
"გაფრთხილება: მიმართვა '%s' ნაწილობრივაა დაყენებული. ამ შეტყობინების "
"მოსაცილებლად გამოიყენეთ პარამეტრი --allow-partial.\n"

#: app/flatpak-builtins-create-usb.c:681
#, c-format
msgid "Installed ref ‘%s’ is extra-data, and cannot be distributed offline"
msgstr ""
"დაყენებული მიმართვა '%s' დამატებითი მონაცემია და ინტერნეტის გარეშე "
"დისტრიბუციას ვერ უზამთ"

#: app/flatpak-builtins-create-usb.c:721
#, c-format
msgid "Warning: Couldn't update repo metadata for remote ‘%s’: %s\n"
msgstr ""
"გაფრთხილება: რეპოზიტორიის მეტამონაცემების განახლების შეცდომა დაშორებულისთვის "
"'%s': %s\n"

#: app/flatpak-builtins-create-usb.c:751
#, c-format
msgid "Warning: Couldn't update appstream data for remote ‘%s’ arch ‘%s’: %s\n"
msgstr ""
"გაფრთხილება: Appstream-ის მონაცემების განახლების შეცდომა დაშორებულისთვის "
"'%s' არქიტექტურით '%s': %s\n"

#. Print a warning if both appstream and appstream2 are missing
#: app/flatpak-builtins-create-usb.c:784
#, c-format
msgid ""
"Warning: Couldn't find appstream data for remote ‘%s’ arch ‘%s’: %s; %s\n"
msgstr ""
"გაფრთხილება: Appstream-ის მონაცემების განახლების შეცდომა დაშორებულისთვის "
"'%s' არქიტექტურით '%s': %s; %s\n"

#. Appstream2 is only for efficiency, so just print a debug message
#: app/flatpak-builtins-create-usb.c:790
#, c-format
msgid "Couldn't find appstream2 data for remote ‘%s’ arch ‘%s’: %s\n"
msgstr ""
"Appstream2-ის მონაცემები დაშორებულისთვის '%s' არქიტექტურისთვის '%s ვერ "
"ვიპოვე: %s\n"

#: app/flatpak-builtins-document-export.c:62
msgid "Create a unique document reference"
msgstr "უნიკალური დოკუმენტის მიმართვის შექმნა"

#: app/flatpak-builtins-document-export.c:63
msgid "Make the document transient for the current session"
msgstr "დოკუმენტის დროებითად გამოცხადება მიმდინარე სესიისთვის"

#: app/flatpak-builtins-document-export.c:64
msgid "Don't require the file to exist already"
msgstr "ფაილის არსებობა მოთხოვნილი არ იქნება"

#: app/flatpak-builtins-document-export.c:65
msgid "Give the app read permissions"
msgstr "აპისთვის კითხვის უფლების მიცემა"

#: app/flatpak-builtins-document-export.c:66
msgid "Give the app write permissions"
msgstr "აპისთვის ჩაწერის უფლების მიცემა"

#: app/flatpak-builtins-document-export.c:67
msgid "Give the app delete permissions"
msgstr "აპისთვის წაშლის უფლების მიცემა"

#: app/flatpak-builtins-document-export.c:68
msgid "Give the app permissions to grant further permissions"
msgstr "აპისთვის წვდომების მინიჭების უფლების მიცემა"

#: app/flatpak-builtins-document-export.c:69
msgid "Revoke read permissions of the app"
msgstr "აპიდან წაკითხვის უფლების მოცილება"

#: app/flatpak-builtins-document-export.c:70
msgid "Revoke write permissions of the app"
msgstr "აპიდან ჩაწერის უფლების მოცილება"

#: app/flatpak-builtins-document-export.c:71
msgid "Revoke delete permissions of the app"
msgstr "აპიდან წაშლის უფლების მოცილება"

#: app/flatpak-builtins-document-export.c:72
msgid "Revoke the permission to grant further permissions"
msgstr "აპისთვის წვდომების მინჭების უფლების ჩამორთმევა"

#: app/flatpak-builtins-document-export.c:73
msgid "Add permissions for this app"
msgstr "ამ აპისთვის უფლებების დამატება"

#: app/flatpak-builtins-document-export.c:73
msgid "APPID"
msgstr "აპისID"

#: app/flatpak-builtins-document-export.c:100
msgid "FILE - Export a file to apps"
msgstr "ფაილი - ფაილის გატანა აპებამდე"

#: app/flatpak-builtins-document-export.c:109
#: app/flatpak-builtins-document-info.c:72
#: app/flatpak-builtins-document-unexport.c:67
msgid "FILE must be specified"
msgstr "ფაილი აუცილებლად უნდა მიუთითოთ"

#: app/flatpak-builtins-document-info.c:63
msgid "FILE - Get information about an exported file"
msgstr "ფაილი - ინფორმაციის მიღება გატანილი ფაილის შესახებ"

#: app/flatpak-builtins-document-info.c:100
#: app/flatpak-builtins-document-unexport.c:94
#, c-format
msgid "Not exported\n"
msgstr "გატანილი არაა\n"

#: app/flatpak-builtins-document-list.c:43 app/flatpak-builtins-history.c:53
#: app/flatpak-builtins-list.c:54 app/flatpak-builtins-ps.c:43
#: app/flatpak-builtins-remote-list.c:45 app/flatpak-builtins-remote-ls.c:59
#: app/flatpak-builtins-search.c:38
msgid "What information to show"
msgstr "რა ინფორმაცია ვაჩვენო"

#: app/flatpak-builtins-document-list.c:43 app/flatpak-builtins-history.c:53
#: app/flatpak-builtins-list.c:54 app/flatpak-builtins-ps.c:43
#: app/flatpak-builtins-remote-list.c:45 app/flatpak-builtins-remote-ls.c:59
#: app/flatpak-builtins-search.c:38
msgid "FIELD,…"
msgstr "FIELD,…"

#: app/flatpak-builtins-document-list.c:44 app/flatpak-builtins-history.c:54
#: app/flatpak-builtins-list.c:52 app/flatpak-builtins-permission-list.c:43
#: app/flatpak-builtins-permission-show.c:43 app/flatpak-builtins-ps.c:44
#: app/flatpak-builtins-remote-list.c:46 app/flatpak-builtins-remote-ls.c:63
#: app/flatpak-builtins-repo.c:717 app/flatpak-builtins-search.c:39
#, fuzzy
msgid "Show output in JSON format"
msgstr "დამატებითი ინფორმაციის ჩვენება"

#: app/flatpak-builtins-document-list.c:49
msgid "Show the document ID"
msgstr "დოკუმენტის ID-ს ჩვენება"

#: app/flatpak-builtins-document-list.c:50
msgid "Path"
msgstr "მისამართი"

#: app/flatpak-builtins-document-list.c:50
#: app/flatpak-builtins-document-list.c:51
msgid "Show the document path"
msgstr "დოკუმენტის ბილიკის ჩვენება"

#: app/flatpak-builtins-document-list.c:51 app/flatpak-builtins-list.c:66
#: app/flatpak-builtins-remote-ls.c:74
msgid "Origin"
msgstr "საწყისი"

#: app/flatpak-builtins-document-list.c:52 app/flatpak-builtins-history.c:62
#: app/flatpak-builtins-ps.c:52
msgid "Application"
msgstr "აპლიკაცია"

#: app/flatpak-builtins-document-list.c:52
msgid "Show applications with permission"
msgstr "წვდომის მქონე აპლიკაციების ჩვენება"

#: app/flatpak-builtins-document-list.c:53
#: app/flatpak-builtins-permission-list.c:182
#: app/flatpak-builtins-permission-show.c:145
msgid "Permissions"
msgstr "წვდომები"

#: app/flatpak-builtins-document-list.c:53
msgid "Show permissions for applications"
msgstr "აპლიკაციის წვდომების ჩვენება"

#: app/flatpak-builtins-document-list.c:161
#, fuzzy, c-format
msgid "No documents found\n"
msgstr "არაფერი მოიძებნა"

#: app/flatpak-builtins-document-list.c:180
msgid "[APPID] - List exported files"
msgstr "[APPID] - გატანილი ფაილების სია"

#: app/flatpak-builtins-document-unexport.c:43
msgid "Specify the document ID"
msgstr "მიუთითეთ დოკუმენტის ID"

#: app/flatpak-builtins-document-unexport.c:58
msgid "FILE - Unexport a file to apps"
msgstr "ფაილი - ფაილის აპლიკაციებისთვის გატანის გაუქმება"

#: app/flatpak-builtins-enter.c:88
msgid "INSTANCE COMMAND [ARGUMENT…] - Run a command inside a running sandbox"
msgstr ""
"გაშვებულიასლი ბრძანება [არგუმენტი…] - გაშვებული სენდბოქსის შიგნით ბრძანების "
"შესრულება"

#: app/flatpak-builtins-enter.c:111
msgid "INSTANCE and COMMAND must be specified"
msgstr "გაშვებულიასლის და ბრძანების მითითება აუცილებელია"

#: app/flatpak-builtins-enter.c:138
#, c-format
msgid "%s is neither a pid nor an application or instance ID"
msgstr "%s არც pid-ია, არც აპლიკაცია დაარც გაშვებული ასლის ID"

#: app/flatpak-builtins-enter.c:144
msgid "entering not supported (need unprivileged user namespaces, or sudo -E)"
msgstr ""
"შესვლა მხარდაჭერილი არაა (საჭიროა არაპრივილეგირებული მომხმარებლის სახელების "
"სივრცეები ან sudo -E)"

#: app/flatpak-builtins-enter.c:145
#, c-format
msgid "No such pid %s"
msgstr "PID %s არ არსებობს"

#: app/flatpak-builtins-enter.c:158
msgid "Can't read cwd"
msgstr "CWD-ის წაკითხვა შეუძლებელია"

#: app/flatpak-builtins-enter.c:163
msgid "Can't read root"
msgstr "ROOT-ის წაკითხვა შეუძლებელია"

#: app/flatpak-builtins-enter.c:191
#, c-format
msgid "Invalid %s namespace for pid %d"
msgstr "არასწორი %s სახელების სივრცე PID-სთვის %d"

#: app/flatpak-builtins-enter.c:202
#, c-format
msgid "Invalid %s namespace for self"
msgstr "არასწორი %s სახელების სივრცე იგივე პროცესისთვის"

#: app/flatpak-builtins-enter.c:216
#, c-format
msgid "Can't open %s namespace: %s"
msgstr "%s სახელების სივრცის გახსნის შეცდომა: %s"

#: app/flatpak-builtins-enter.c:226
msgid "entering not supported (need unprivileged user namespaces)"
msgstr ""
"შესვლა მხარდაჭერილი არაა (საჭიროა არაპრივილეგირებული მომხმარებლის სახელების "
"სივრცეები)"

#: app/flatpak-builtins-enter.c:227
#, c-format
msgid "Can't enter %s namespace: %s"
msgstr "%s სახელების სივრცეში შესვლის შეცდომა: %s"

#: app/flatpak-builtins-enter.c:234
msgid "Can't chdir"
msgstr "Chdir-ის შეცდომა"

#: app/flatpak-builtins-enter.c:237
msgid "Can't chroot"
msgstr "Chroot-ის შეცდომა"

#: app/flatpak-builtins-enter.c:240
msgid "Can't switch gid"
msgstr "GID-ის გადართვის შეცდომა"

#: app/flatpak-builtins-enter.c:243
msgid "Can't switch uid"
msgstr "UID-ის გადართვის შეცდომა"

#: app/flatpak-builtins-history.c:50
msgid "Only show changes after TIME"
msgstr "მხოლოდ მითითებული დროის შემდეგ მომხდარი ცვლილებების ჩვენება"

#: app/flatpak-builtins-history.c:50 app/flatpak-builtins-history.c:51
msgid "TIME"
msgstr "დრო"

#: app/flatpak-builtins-history.c:51
msgid "Only show changes before TIME"
msgstr "მხოლოდ მითითებულ დრომდე მომხდარი ცვლილებების ჩვენება"

#: app/flatpak-builtins-history.c:52
msgid "Show newest entries first"
msgstr "ჯერ უახლესი ჩანაწერების ჩვენება"

#: app/flatpak-builtins-history.c:59
msgid "Time"
msgstr "დრო"

#: app/flatpak-builtins-history.c:59
msgid "Show when the change happened"
msgstr "ჩვენება, როდის მოხდა ცვლილება"

#: app/flatpak-builtins-history.c:60
msgid "Change"
msgstr "შეცვლა"

#: app/flatpak-builtins-history.c:60
msgid "Show the kind of change"
msgstr "ცვლილების ტიპის ჩვენება"

#: app/flatpak-builtins-history.c:61 app/flatpak-builtins-list.c:68
#: app/flatpak-builtins-remote-ls.c:75 app/flatpak-builtins-repo.c:335
msgid "Ref"
msgstr "ბმა"

#: app/flatpak-builtins-history.c:61 app/flatpak-builtins-list.c:68
#: app/flatpak-builtins-remote-ls.c:75
msgid "Show the ref"
msgstr "მიმართვის ჩვენება"

#: app/flatpak-builtins-history.c:62
msgid "Show the application/runtime ID"
msgstr "აპლიკაციის/გაშვების გარემოს ID-ის ჩვენება"

#: app/flatpak-builtins-history.c:63 app/flatpak-builtins-list.c:64
#: app/flatpak-builtins-ps.c:53 app/flatpak-builtins-remote-ls.c:73
#: app/flatpak-cli-transaction.c:1435
msgid "Arch"
msgstr "არქიტექტურა"

#: app/flatpak-builtins-history.c:63 app/flatpak-builtins-list.c:64
#: app/flatpak-builtins-ps.c:53 app/flatpak-builtins-remote-ls.c:73
msgid "Show the architecture"
msgstr "არქიტექტურის ჩვენება"

#: app/flatpak-builtins-history.c:64 app/flatpak-builtins-list.c:63
#: app/flatpak-builtins-ps.c:54 app/flatpak-builtins-remote-ls.c:72
#: app/flatpak-builtins-search.c:48 app/flatpak-cli-transaction.c:1438
msgid "Branch"
msgstr "ბრენჩი"

#: app/flatpak-builtins-history.c:64 app/flatpak-builtins-list.c:63
#: app/flatpak-builtins-remote-ls.c:72
msgid "Show the branch"
msgstr "ბრენჩის ჩვენება"

#: app/flatpak-builtins-history.c:65 app/flatpak-builtins-list.c:67
msgid "Installation"
msgstr "დაყენება"

#: app/flatpak-builtins-history.c:65
msgid "Show the affected installation"
msgstr "მოყოლილი დაყენებების ჩვენება"

#: app/flatpak-builtins-history.c:66 app/flatpak-cli-transaction.c:1452
msgid "Remote"
msgstr "დაშორებული"

#: app/flatpak-builtins-history.c:66
msgid "Show the remote"
msgstr "დაშორებულის ჩვენება"

#: app/flatpak-builtins-history.c:67 app/flatpak-builtins-ps.c:55
#: app/flatpak-builtins-remote-ls.c:76
msgid "Commit"
msgstr "გადაცემა"

#: app/flatpak-builtins-history.c:67
msgid "Show the current commit"
msgstr "მიმდინარე კომიტის ჩვენება"

#: app/flatpak-builtins-history.c:68
msgid "Old Commit"
msgstr "ძველი კომიტი"

#: app/flatpak-builtins-history.c:68
msgid "Show the previous commit"
msgstr "წინა კომიტის ჩვენება"

#: app/flatpak-builtins-history.c:69
msgid "Show the remote URL"
msgstr "დაშორებული URL-ის ჩვენება"

#: app/flatpak-builtins-history.c:70 app/flatpak-cli-transaction.c:700
msgid "User"
msgstr "მომხმარებელი"

#: app/flatpak-builtins-history.c:70
msgid "Show the user doing the change"
msgstr "ცვლილების შემტანი მომხმარებლის ჩვენება"

#: app/flatpak-builtins-history.c:71
msgid "Tool"
msgstr "ხელსაწყო"

#: app/flatpak-builtins-history.c:71
msgid "Show the tool that was used"
msgstr "გამოყენებული პროგრამის ჩვენება"

#: app/flatpak-builtins-history.c:72 app/flatpak-builtins-list.c:62
#: app/flatpak-builtins-remote-ls.c:71 app/flatpak-builtins-search.c:47
msgid "Version"
msgstr "ვერსია"

#: app/flatpak-builtins-history.c:72
msgid "Show the Flatpak version"
msgstr "Flatpak-ის ვერსიის ჩვენება"

#: app/flatpak-builtins-history.c:91
#, c-format
msgid "Failed to get journal data (%s): %s"
msgstr "ჟურნალის მონაცემების (%s) მიღების შეცდომა: %s"

#: app/flatpak-builtins-history.c:146
#, c-format
msgid "Failed to open journal: %s"
msgstr "ჟურნალის გახსნის შეცდომა: %s"

#: app/flatpak-builtins-history.c:153
#, c-format
msgid "Failed to add match to journal: %s"
msgstr "დამთხვევის ჟურნალში ჩამატების შეცდომა: %s"

#: app/flatpak-builtins-history.c:471
msgid " - Show history"
msgstr " - ისტორიის ჩვენება"

#: app/flatpak-builtins-history.c:490
#, c-format
msgid "Failed to parse the --since option"
msgstr "შეცდომა --since პარამეტრის დამუშავებისას"

#: app/flatpak-builtins-history.c:501
#, c-format
msgid "Failed to parse the --until option"
msgstr "შეცდომა --until პარამეტრის დამუშავებისას"

#: app/flatpak-builtins-info.c:56
msgid "Show user installations"
msgstr "მომხმარებლის დაყენებული პროგრამების ჩვენება"

#: app/flatpak-builtins-info.c:57
msgid "Show system-wide installations"
msgstr "მთელი-სისტემისთვის დაყენებული პროგრამების ჩვენება"

#: app/flatpak-builtins-info.c:58
msgid "Show specific system-wide installations"
msgstr "მითითებული მთელი-სისტემისთვის დაყენებული პროგრამების ჩვენება"

#: app/flatpak-builtins-info.c:59 app/flatpak-builtins-remote-info.c:59
msgid "Show ref"
msgstr "მიმართვის ჩვენება"

#: app/flatpak-builtins-info.c:60 app/flatpak-builtins-remote-info.c:60
msgid "Show commit"
msgstr "კომიტის ჩვენება"

#: app/flatpak-builtins-info.c:61
msgid "Show origin"
msgstr "საწყისის ჩვენება"

#: app/flatpak-builtins-info.c:62
msgid "Show size"
msgstr "ზომის ჩვენება"

#: app/flatpak-builtins-info.c:63 app/flatpak-builtins-remote-info.c:62
msgid "Show metadata"
msgstr "მეტამონაცემების ჩვენება"

#: app/flatpak-builtins-info.c:64 app/flatpak-builtins-remote-info.c:63
msgid "Show runtime"
msgstr "გაშვების გარემოს ჩვენება"

#: app/flatpak-builtins-info.c:65 app/flatpak-builtins-remote-info.c:64
msgid "Show sdk"
msgstr "SDK-ის ჩვენება"

#: app/flatpak-builtins-info.c:66
msgid "Show permissions"
msgstr "წვდომების ჩვენება"

#: app/flatpak-builtins-info.c:67
msgid "Query file access"
msgstr "ფაილის წვდომების გამოთხოვა"

#: app/flatpak-builtins-info.c:67 app/flatpak-builtins-install.c:82
#: app/flatpak-builtins-install.c:88 app/flatpak-builtins-preinstall.c:68
#: app/flatpak-builtins-run.c:182 app/flatpak-builtins-run.c:184
#: app/flatpak-builtins-update.c:67 app/flatpak-builtins-update.c:71
msgid "PATH"
msgstr "PATH"

#: app/flatpak-builtins-info.c:68
msgid "Show extensions"
msgstr "გაფართოებების ჩვენება"

#: app/flatpak-builtins-info.c:69
msgid "Show location"
msgstr "მდებარეობის ჩვენება"

#: app/flatpak-builtins-info.c:116
msgid "NAME [BRANCH] - Get info about an installed app or runtime"
msgstr ""
"სახელი [ბრენჩი] - დაყენებული აპის ან გაშვების გარემოს შესახებ ინფორმაციის "
"მიღება"

#: app/flatpak-builtins-info.c:123 app/flatpak-builtins-remote-add.c:317
#: app/flatpak-builtins-remote-delete.c:63
msgid "NAME must be specified"
msgstr "სახელის მითითება აუცილებელია"

#: app/flatpak-builtins-info.c:196
msgid "ref not present in origin"
msgstr "საწყისში მიმართვა არ სებობს"

#: app/flatpak-builtins-info.c:211 app/flatpak-builtins-remote-info.c:217
#, c-format
msgid "Warning: Commit has no flatpak metadata\n"
msgstr "გართხილება: კომიტს flatpak-ის მეტამონაცემების არ გააჩნია\n"

#: app/flatpak-builtins-info.c:217 app/flatpak-builtins-info.c:259
#: app/flatpak-builtins-info.c:455 app/flatpak-builtins-info.c:513
#: app/flatpak-builtins-remote-info.c:236
#: app/flatpak-builtins-remote-info.c:271
msgid "ID:"
msgstr "ID:"

#: app/flatpak-builtins-info.c:218 app/flatpak-builtins-info.c:260
#: app/flatpak-builtins-remote-info.c:237
#: app/flatpak-builtins-remote-info.c:272
msgid "Ref:"
msgstr "მიმართვა:"

#: app/flatpak-builtins-info.c:219 app/flatpak-builtins-info.c:261
#: app/flatpak-builtins-remote-info.c:238
#: app/flatpak-builtins-remote-info.c:273
msgid "Arch:"
msgstr "არქიტექტურა:"

#: app/flatpak-builtins-info.c:220 app/flatpak-builtins-info.c:262
#: app/flatpak-builtins-remote-info.c:239
#: app/flatpak-builtins-remote-info.c:274
msgid "Branch:"
msgstr "ბრენჩი:"

#: app/flatpak-builtins-info.c:222 app/flatpak-builtins-info.c:264
#: app/flatpak-builtins-remote-info.c:241
#: app/flatpak-builtins-remote-info.c:276
msgid "Version:"
msgstr "ვერსია:"

#: app/flatpak-builtins-info.c:224 app/flatpak-builtins-info.c:266
#: app/flatpak-builtins-remote-info.c:243
#: app/flatpak-builtins-remote-info.c:278
msgid "License:"
msgstr "ლიცენზია:"

#: app/flatpak-builtins-info.c:226 app/flatpak-builtins-info.c:269
#: app/flatpak-builtins-remote-info.c:245
#: app/flatpak-builtins-remote-info.c:280
msgid "Collection:"
msgstr "კოლექცია:"

#: app/flatpak-builtins-info.c:227 app/flatpak-builtins-info.c:270
#: app/flatpak-builtins-info.c:458 app/flatpak-builtins-info.c:516
msgid "Installation:"
msgstr "დაყენება:"

#: app/flatpak-builtins-info.c:228 app/flatpak-builtins-info.c:271
#: app/flatpak-builtins-info.c:459 app/flatpak-builtins-info.c:517
#: app/flatpak-builtins-remote-info.c:249
#: app/flatpak-builtins-remote-info.c:284
#, fuzzy
msgid "Installed Size:"
msgstr "დაყენებული ზომა"

#: app/flatpak-builtins-info.c:231 app/flatpak-builtins-info.c:279
#: app/flatpak-builtins-remote-info.c:252
#: app/flatpak-builtins-remote-info.c:288
msgid "Runtime:"
msgstr "ხანგრძლივობა:"

#: app/flatpak-builtins-info.c:232 app/flatpak-builtins-info.c:288
#: app/flatpak-builtins-remote-info.c:253
#: app/flatpak-builtins-remote-info.c:293
msgid "Sdk:"
msgstr "Sdk:"

#: app/flatpak-builtins-info.c:235 app/flatpak-builtins-info.c:313
#: app/flatpak-builtins-remote-info.c:256
#: app/flatpak-builtins-remote-info.c:319
msgid "Date:"
msgstr "თარიღი:"

#: app/flatpak-builtins-info.c:237 app/flatpak-builtins-info.c:311
#: app/flatpak-builtins-remote-info.c:258
#: app/flatpak-builtins-remote-info.c:317
msgid "Subject:"
msgstr "სათაური:"

#: app/flatpak-builtins-info.c:240 app/flatpak-builtins-info.c:295
msgid "Active commit:"
msgstr "აქტიური კომიტი:"

#: app/flatpak-builtins-info.c:241 app/flatpak-builtins-info.c:298
msgid "Latest commit:"
msgstr "უახლესი კომიტი:"

#: app/flatpak-builtins-info.c:244 app/flatpak-builtins-info.c:303
#: app/flatpak-builtins-info.c:457 app/flatpak-builtins-info.c:515
#: app/flatpak-builtins-remote-info.c:259
#: app/flatpak-builtins-remote-info.c:298
msgid "Commit:"
msgstr "კომიტი:"

#: app/flatpak-builtins-info.c:246 app/flatpak-builtins-info.c:308
#: app/flatpak-builtins-remote-info.c:261
#: app/flatpak-builtins-remote-info.c:303
msgid "Parent:"
msgstr "მშობელი:"

#: app/flatpak-builtins-info.c:248 app/flatpak-builtins-info.c:321
msgid "Alt-id:"
msgstr "ალტ-ID:"

#: app/flatpak-builtins-info.c:250 app/flatpak-builtins-info.c:325
#: app/flatpak-builtins-remote-info.c:263
#: app/flatpak-builtins-remote-info.c:308
msgid "End-of-life:"
msgstr "მხარდაჭერა-დასრულებული:"

#: app/flatpak-builtins-info.c:252 app/flatpak-builtins-info.c:330
#: app/flatpak-builtins-remote-info.c:265
#: app/flatpak-builtins-remote-info.c:313
msgid "End-of-life-rebase:"
msgstr "მხარდაჭერა-დასრულებული-ჩანაცვლება:"

#: app/flatpak-builtins-info.c:254 app/flatpak-builtins-info.c:317
msgid "Subdirectories:"
msgstr "ქვესაქაღალდეები:"

#: app/flatpak-builtins-info.c:255 app/flatpak-builtins-info.c:454
#: app/flatpak-builtins-info.c:512
msgid "Extension:"
msgstr "გაფართოება:"

#: app/flatpak-builtins-info.c:267 app/flatpak-builtins-info.c:456
#: app/flatpak-builtins-info.c:514
msgid "Origin:"
msgstr "საწყისი:"

#: app/flatpak-builtins-info.c:460 app/flatpak-builtins-info.c:522
msgid "Subpaths:"
msgstr "ქვებილიკები:"

#: app/flatpak-builtins-info.c:478
msgid "unmaintained"
msgstr "მიუხედავი"

#: app/flatpak-builtins-info.c:480 app/flatpak-builtins-info.c:482
msgid "unknown"
msgstr "უცნობია"

#: app/flatpak-builtins-install.c:68 app/flatpak-builtins-preinstall.c:57
msgid "Don't pull, only install from local cache"
msgstr "პულის გარეშე, მხოლოდ ლოკალური კეშიდან დაყენება"

#: app/flatpak-builtins-install.c:69 app/flatpak-builtins-preinstall.c:58
#: app/flatpak-builtins-update.c:60
msgid "Don't deploy, only download to local cache"
msgstr "გაშლის გარეშე, მხოლოდ ლოკალურ კეშში გადმოწერა"

#: app/flatpak-builtins-install.c:70 app/flatpak-builtins-preinstall.c:59
msgid "Don't install related refs"
msgstr "დაკავშირებული მიმართვები დაყენებული არ იქნება"

#: app/flatpak-builtins-install.c:71 app/flatpak-builtins-preinstall.c:60
#: app/flatpak-builtins-update.c:62
msgid "Don't verify/install runtime dependencies"
msgstr "გაშვების გარემოს დამოკიდებულებების შემოწმება/დაყენება არ მოხდება"

#: app/flatpak-builtins-install.c:72
msgid "Don't automatically pin explicit installs"
msgstr "ხელით მითითებული დაყენებები ავტომატურად მიმაგრებული არ იქნება"

#: app/flatpak-builtins-install.c:73 app/flatpak-builtins-preinstall.c:61
#: app/flatpak-builtins-update.c:63
msgid "Don't use static deltas"
msgstr "სტატიკური დელტები გამოყენებული არ იქნება"

#: app/flatpak-builtins-install.c:76 app/flatpak-builtins-preinstall.c:62
msgid "Additionally install the SDK used to build the given refs"
msgstr "დამატებით მოცემული მითითებების აგებისას გამოყენებული SDK-ის დაყენება"

#: app/flatpak-builtins-install.c:77 app/flatpak-builtins-preinstall.c:63
msgid ""
"Additionally install the debug info for the given refs and their dependencies"
msgstr ""
"დამატებით მოცემული მითითებებისა და მისი დამოკიდებულებების გამართვის "
"ინფორმაციის დაყენება"

#: app/flatpak-builtins-install.c:78
msgid "Assume LOCATION is a .flatpak single-file bundle"
msgstr "მითითებული მდებარეობის .flatpak ერთფაილიან პაკეტად ჩათვლა"

#: app/flatpak-builtins-install.c:79
msgid "Assume LOCATION is a .flatpakref application description"
msgstr "მითითებული მდებარეობის .flatpakref აპლიკაციის აღწერად ჩათვლა"

#: app/flatpak-builtins-install.c:80
msgid "Assume LOCATION is containers-transports(5) reference to an OCI image"
msgstr ""

#: app/flatpak-builtins-install.c:81
msgid "Check bundle signatures with GPG key from FILE (- for stdin)"
msgstr ""
"პაკეტის ხელმოწერების მითითებული ფაილიდან წაკითხული GPG გასაღებებით შემოწმება "
"(- stdin-სთვის)"

#: app/flatpak-builtins-install.c:82
msgid "Only install this subpath"
msgstr "მხოლოდ ამ ქვებილიკის დაყენება"

#: app/flatpak-builtins-install.c:83 app/flatpak-builtins-preinstall.c:64
#: app/flatpak-builtins-uninstall.c:63 app/flatpak-builtins-update.c:68
msgid "Automatically answer yes for all questions"
msgstr "ყველა კითხვისთვის დადებითი პასუხის ავტომატური გაცემა"

#: app/flatpak-builtins-install.c:84 app/flatpak-builtins-preinstall.c:65
msgid "Uninstall first if already installed"
msgstr "ჯერ წაშლა, თუ უკვე დაყენებულია"

#: app/flatpak-builtins-install.c:85 app/flatpak-builtins-preinstall.c:66
#: app/flatpak-builtins-uninstall.c:64 app/flatpak-builtins-update.c:69
msgid "Produce minimal output and don't ask questions"
msgstr "მინიმალური ინფორმაციის გამოტანა და კითხვების არ-დასმა"

#: app/flatpak-builtins-install.c:86
msgid "Update install if already installed"
msgstr "განახლება, თუ პაკეტი უკვე დაყენებულია"

#. Translators: A sideload is when you install from a local USB drive rather than the Internet.
#: app/flatpak-builtins-install.c:88 app/flatpak-builtins-preinstall.c:68
#: app/flatpak-builtins-update.c:71
msgid "Use this local repo for sideloads"
msgstr "გვერდით ჩატვირთვებისთვის ამ ლოკალური რეპოზიტორიის გამოყენება"

#: app/flatpak-builtins-install.c:178
msgid "Bundle filename must be specified"
msgstr "პაკეტის ფაილის სახელის მითითება აუცილებელია"

#: app/flatpak-builtins-install.c:188
msgid "Remote bundles are not supported"
msgstr "დაშორებული პაკეტები მხარდაჭერილი არაა"

#: app/flatpak-builtins-install.c:231
msgid "Filename or uri must be specified"
msgstr "ფაილის სახელის ან URI-ის მითითება აუცილებელია"

#: app/flatpak-builtins-install.c:295
#, fuzzy
msgid "Image location must be specified"
msgstr "საჭიროა სულ ცოტა, ერთი მიმართვის მითთება"

#: app/flatpak-builtins-install.c:345
msgid "[LOCATION/REMOTE] [REF…] - Install applications or runtimes"
msgstr ""
"[მდებარეობა/დაშორებული] [მიმართვა…] - აპლიკაციის ან გაშვების გარემოს დაყენება"

#: app/flatpak-builtins-install.c:378
msgid "At least one REF must be specified"
msgstr "საჭიროა სულ ცოტა, ერთი მიმართვის მითთება"

#: app/flatpak-builtins-install.c:392
#, c-format
msgid "Looking for matches…\n"
msgstr "დამთხვევების ძებნა…\n"

#: app/flatpak-builtins-install.c:513
#, c-format
msgid "No remote refs found for ‘%s’"
msgstr "'%s'-სთვის დაშორებული მიმართვა ვერ ვიპოვე"

#: app/flatpak-builtins-install.c:573 app/flatpak-builtins-uninstall.c:405
#: common/flatpak-ref-utils.c:689 common/flatpak-ref-utils.c:1595
#, c-format
msgid "Invalid branch %s: %s"
msgstr "არასწორი ბრენჩი %s: %s"

#: app/flatpak-builtins-install.c:606
#, c-format
msgid "Nothing matches %s in local repository for remote %s"
msgstr "%s-ს ლოკალურ რეპოზიტორიაში დაშორებული %s-სთვის არაფერი ემთხვევა"

#: app/flatpak-builtins-install.c:608
#, c-format
msgid "Nothing matches %s in remote %s"
msgstr "%s-ს დაშორებულ %s-ში არაფერი ემთხვევა"

#: app/flatpak-builtins-install.c:629
#, c-format
msgid "Skipping: %s\n"
msgstr "გამოტოვება: %s\n"

#: app/flatpak-builtins-kill.c:110
#, c-format
msgid "%s is not running"
msgstr "%s გაშვებული არაა"

#: app/flatpak-builtins-kill.c:136
msgid "INSTANCE - Stop a running application"
msgstr "გაშვებულიასლი - გაშვებული აპლიკაციის გაჩერება"

#: app/flatpak-builtins-kill.c:144 app/flatpak-builtins-ps.c:256
msgid "Extra arguments given"
msgstr "მიწოდებული დამატებითი არგუმენტები"

#: app/flatpak-builtins-kill.c:150
msgid "Must specify the app to kill"
msgstr "მოსაკლავი აპლიკაციის მითითება აუცილებელია"

#: app/flatpak-builtins-list.c:47
msgid "Show extra information"
msgstr "დამატებითი ინფორმაციის ჩვენება"

#: app/flatpak-builtins-list.c:48
msgid "List installed runtimes"
msgstr "დაყენებული გაშვების გარემოების ჩვენება"

#: app/flatpak-builtins-list.c:49
msgid "List installed applications"
msgstr "დაყენებული აპლიკაციების სია"

#: app/flatpak-builtins-list.c:50
msgid "Arch to show"
msgstr "საჩვენებელი არქიტექტურა"

#: app/flatpak-builtins-list.c:51 app/flatpak-builtins-remote-ls.c:57
msgid "List all refs (including locale/debug)"
msgstr "ყველა მიმართვის სია (ლოკალის/გამართვის ჩათვლით)"

#: app/flatpak-builtins-list.c:53 app/flatpak-builtins-remote-ls.c:58
msgid "List all applications using RUNTIME"
msgstr "აპლიკაციების სია, რომლებიც ამ გაშვების გარემოს იყენებენ"

#: app/flatpak-builtins-list.c:59 app/flatpak-builtins-remote-list.c:51
#: app/flatpak-builtins-remote-ls.c:68 app/flatpak-builtins-search.c:44
msgid "Name"
msgstr "სახელი"

#: app/flatpak-builtins-list.c:59 app/flatpak-builtins-remote-list.c:51
#: app/flatpak-builtins-remote-ls.c:68 app/flatpak-builtins-search.c:44
msgid "Show the name"
msgstr "სახელის ჩვენება"

#: app/flatpak-builtins-list.c:60 app/flatpak-builtins-remote-list.c:60
#: app/flatpak-builtins-remote-ls.c:69 app/flatpak-builtins-search.c:45
msgid "Description"
msgstr "აღწერა"

#: app/flatpak-builtins-list.c:60 app/flatpak-builtins-remote-ls.c:69
#: app/flatpak-builtins-search.c:45
msgid "Show the description"
msgstr "აღწერის ჩვენება"

#: app/flatpak-builtins-list.c:61 app/flatpak-builtins-remote-ls.c:70
#: app/flatpak-builtins-search.c:46
msgid "Application ID"
msgstr "აპლიკაციის ID"

#: app/flatpak-builtins-list.c:61 app/flatpak-builtins-ps.c:52
#: app/flatpak-builtins-remote-ls.c:70 app/flatpak-builtins-search.c:46
msgid "Show the application ID"
msgstr "აპლიკაციის ID-ის ჩვენება"

#: app/flatpak-builtins-list.c:62 app/flatpak-builtins-remote-ls.c:71
#: app/flatpak-builtins-search.c:47
msgid "Show the version"
msgstr "ვერსიის ჩვენება"

#: app/flatpak-builtins-list.c:65 app/flatpak-builtins-ps.c:56
#: app/flatpak-builtins-remote-ls.c:77
msgid "Runtime"
msgstr "აქტივობა"

#: app/flatpak-builtins-list.c:65
msgid "Show the used runtime"
msgstr "გამოყენებული გაშვების გარემოს ჩვენება"

#: app/flatpak-builtins-list.c:66 app/flatpak-builtins-remote-ls.c:74
msgid "Show the origin remote"
msgstr "საწყისი დაშორებულის ჩვენება"

#: app/flatpak-builtins-list.c:67
msgid "Show the installation"
msgstr "დაყენების ჩვენება"

#: app/flatpak-builtins-list.c:69
msgid "Active commit"
msgstr "აქტიური კომიტი"

#: app/flatpak-builtins-list.c:69 app/flatpak-builtins-remote-ls.c:76
msgid "Show the active commit"
msgstr "აქტიური კომიტის ჩვენება"

#: app/flatpak-builtins-list.c:70
msgid "Latest commit"
msgstr "უახლესი კომიტი"

#: app/flatpak-builtins-list.c:70
msgid "Show the latest commit"
msgstr "უახლესი კომიტის ჩვენება"

#: app/flatpak-builtins-list.c:71 app/flatpak-builtins-remote-ls.c:78
msgid "Installed size"
msgstr "დაყენებული ზომა"

#: app/flatpak-builtins-list.c:71 app/flatpak-builtins-remote-ls.c:78
msgid "Show the installed size"
msgstr "დაყენებული ზომის ჩვენება"

#: app/flatpak-builtins-list.c:72 app/flatpak-builtins-remote-list.c:58
#: app/flatpak-builtins-remote-ls.c:80 app/flatpak-builtins-repo.c:340
msgid "Options"
msgstr "მორგება"

#: app/flatpak-builtins-list.c:72 app/flatpak-builtins-remote-list.c:58
#: app/flatpak-builtins-remote-ls.c:80
msgid "Show options"
msgstr "პარამეტრების ჩვენება"

#: app/flatpak-builtins-list.c:180
#, c-format
msgid "Unable to load details of %s: %s"
msgstr "%s-ის დეტალების ჩატვირთვა შეუძლებელია: %s"

#: app/flatpak-builtins-list.c:190
#, c-format
msgid "Unable to inspect current version of %s: %s"
msgstr "%s-ის მიმდინარე ვერსიის ინსპექტირება შეუძლებელია: %s"

#: app/flatpak-builtins-list.c:408
msgid " - List installed apps and/or runtimes"
msgstr " - დაყენებული აპებისა და გაშვების გარემოების სია"

#: app/flatpak-builtins-make-current.c:38
msgid "Arch to make current for"
msgstr "მიმდინარედ დასაყენებელი არქიტექტურა"

#: app/flatpak-builtins-make-current.c:58
msgid "APP BRANCH - Make branch of application current"
msgstr "აპის ბრენჩი - აპლიკაციის ბრენჩის მიმდინარედ დანიშვნა"

#: app/flatpak-builtins-make-current.c:69 app/flatpak-builtins-run.c:260
msgid "APP must be specified"
msgstr "აპის მითითება აუცილებელია"

#: app/flatpak-builtins-make-current.c:84
msgid "BRANCH must be specified"
msgstr "ბრენჩის მითითება აუცილებელია"

#: app/flatpak-builtins-make-current.c:97
#, c-format
msgid "App %s branch %s is not installed"
msgstr "%s აპის %s ბრენჩი დაყენებული არაა"

#: app/flatpak-builtins-mask.c:42
msgid "Remove matching masks"
msgstr "შესაბამისი ნიღბების წაშლა"

#: app/flatpak-builtins-mask.c:54
msgid ""
"[PATTERN…] - disable updates and automatic installation matching patterns"
msgstr ""
"[ნიმუში...] - დამთხვეული ნიმუშებისთვის განახლებებისა და ავტომატური დაყენების "
"გამორთვა"

#: app/flatpak-builtins-mask.c:73
#, c-format
msgid "No masked patterns\n"
msgstr "შენიღბული ნიმუშების გარეშე\n"

#: app/flatpak-builtins-mask.c:78
#, c-format
msgid "Masked patterns:\n"
msgstr "შენიღბული ნიმუშები:\n"

#: app/flatpak-builtins-override.c:42
msgid "Remove existing overrides"
msgstr "არსებული გადაფარვების წაშლა"

#: app/flatpak-builtins-override.c:43
msgid "Show existing overrides"
msgstr "არსებული გადაფარვების ჩვენება"

#: app/flatpak-builtins-override.c:59
msgid "[APP] - Override settings [for application]"
msgstr "[აპი] - მითითებული აპისთვის პარამეტრების გადაფარვა"

#: app/flatpak-builtins-permission-list.c:143
msgid "[TABLE] [ID] - List permissions"
msgstr "[ცხრილი] [ID] - წვდომების სია"

#: app/flatpak-builtins-permission-list.c:179
#: app/flatpak-builtins-permission-show.c:142
msgid "Table"
msgstr "ცხრილი"

#: app/flatpak-builtins-permission-list.c:180
#: app/flatpak-builtins-permission-show.c:143
msgid "Object"
msgstr "ობიექტი"

#: app/flatpak-builtins-permission-list.c:181
#: app/flatpak-builtins-permission-show.c:144
msgid "App"
msgstr "აპპი"

#: app/flatpak-builtins-permission-list.c:183
#: app/flatpak-builtins-permission-show.c:146
msgid "Data"
msgstr "მონაცემები"

#: app/flatpak-builtins-permission-remove.c:120
msgid "TABLE ID [APP_ID] - Remove item from permission store"
msgstr "ცხრილი ID [აპის_ID] -- წვდომების სიიდან ელემენტის წაშლა"

#: app/flatpak-builtins-permission-remove.c:129
#: app/flatpak-builtins-permission-set.c:120
msgid "Too few arguments"
msgstr "არასაკმარისი არგუმენტები"

#: app/flatpak-builtins-permission-reset.c:43
msgid "Reset all permissions"
msgstr "წვდომების საწყის მნიშვნელობებზე დაყენება"

#: app/flatpak-builtins-permission-reset.c:144
msgid "APP_ID - Reset permissions for an app"
msgstr "APP_ID - აპის წვდომების საწყის მნიშვნელობებზე დაყენება"

#: app/flatpak-builtins-permission-reset.c:153
#: app/flatpak-builtins-permission-show.c:124
msgid "Wrong number of arguments"
msgstr "არგუმენტების არასწორი რიცხვი"

#: app/flatpak-builtins-permission-set.c:42
msgid "Associate DATA with the entry"
msgstr "მითითებული მონაცემების ამ ჩანაწერთან ასოცირება"

#: app/flatpak-builtins-permission-set.c:42
msgid "DATA"
msgstr "მონაცემები"

#: app/flatpak-builtins-permission-set.c:111
msgid "TABLE ID APP_ID [PERMISSION...] - Set permissions"
msgstr "ცხრილი ID აპის_ID [წვდომა...] - წვდომების დაყენება"

#: app/flatpak-builtins-permission-set.c:132
#, c-format
msgid "Failed to parse '%s' as GVariant: "
msgstr "'%s'-ის GVariant-ის სახით დამუშავების შეცდომა: "

#: app/flatpak-builtins-permission-show.c:115
msgid "APP_ID - Show permissions for an app"
msgstr "APP_ID - აპის წვდომების ჩვენება"

#: app/flatpak-builtins-pin.c:44
msgid "Remove matching pins"
msgstr "შესაბამისი მიმაგრებების წაშლა"

#: app/flatpak-builtins-pin.c:56
msgid "[PATTERN…] - disable automatic removal of runtimes matching patterns"
msgstr ""
"[ნიმუში...] - დამთხვეული ნიმუშებისთვის გაშვების გარემოების ავტომატური წაშლის "
"გამორთვა"

#: app/flatpak-builtins-pin.c:75
#, c-format
msgid "No pinned patterns\n"
msgstr "მიმაგრებული ნიმუშების გარეშე\n"

#: app/flatpak-builtins-pin.c:80
#, c-format
msgid "Pinned patterns:\n"
msgstr "მიმაგრებული ნიმუშები:\n"

#: app/flatpak-builtins-preinstall.c:80
msgid "- Install flatpaks that are part of the operating system"
msgstr ""

#: app/flatpak-builtins-preinstall.c:118
#, c-format
msgid "Nothing to do.\n"
msgstr "გასაკეთებელი არაფერია.\n"

#: app/flatpak-builtins-ps.c:49
msgid "Instance"
msgstr "გაშვებული ასლი"

#: app/flatpak-builtins-ps.c:49
msgid "Show the instance ID"
msgstr "გაშვებული ასლის ID-ის ჩვენება"

#: app/flatpak-builtins-ps.c:50 app/flatpak-builtins-run.c:178
msgid "PID"
msgstr "PID"

#: app/flatpak-builtins-ps.c:50
msgid "Show the PID of the wrapper process"
msgstr "შემომსაზღვრელი პროცესის PID-ის ჩვენება"

#: app/flatpak-builtins-ps.c:51
msgid "Child-PID"
msgstr "შვილის-PID"

#: app/flatpak-builtins-ps.c:51
msgid "Show the PID of the sandbox process"
msgstr "სენდბოქსის პროცესის PID-ის ჩვენება"

#: app/flatpak-builtins-ps.c:54 app/flatpak-builtins-search.c:48
msgid "Show the application branch"
msgstr "აპლიკაციის ბრენჩის ჩვენება"

#: app/flatpak-builtins-ps.c:55
msgid "Show the application commit"
msgstr "აპლიკაციის კომიტის ჩვენება"

#: app/flatpak-builtins-ps.c:56
msgid "Show the runtime ID"
msgstr "გაშვების გარემოს ID-ის ჩვენება"

#: app/flatpak-builtins-ps.c:57
msgid "R.-Branch"
msgstr "R.-Branch"

#: app/flatpak-builtins-ps.c:57
msgid "Show the runtime branch"
msgstr "გაშვების გარემოს ბრენჩის ჩვენება"

#: app/flatpak-builtins-ps.c:58
msgid "R.-Commit"
msgstr "R.-Commit"

#: app/flatpak-builtins-ps.c:58
msgid "Show the runtime commit"
msgstr "გაშვების გარემოს კომიტის ჩვენება"

#: app/flatpak-builtins-ps.c:59
msgid "Active"
msgstr "აქტიური"

#: app/flatpak-builtins-ps.c:59
msgid "Show whether the app is active"
msgstr "ჩვენება, აქტიურია აპი, თუ არა"

#: app/flatpak-builtins-ps.c:60
msgid "Background"
msgstr "ფონი"

#: app/flatpak-builtins-ps.c:60
msgid "Show whether the app is background"
msgstr "ჩვენება, აპლიკაცია ფონურია, თუ არაა"

#: app/flatpak-builtins-ps.c:246
msgid " - Enumerate running sandboxes"
msgstr " - გაშვებული სენდბოქსების ჩამონათვალი"

#: app/flatpak-builtins-remote-add.c:66
msgid "Do nothing if the provided remote exists"
msgstr "თუ მითითებული დაშორებული არსებობს, არაფერი მოხდება"

#: app/flatpak-builtins-remote-add.c:67
msgid "LOCATION specifies a configuration file, not the repo location"
msgstr ""
"მითითებული მდებარეობა მიუთითებს კონფიგურაციის ფაილზე და არა რეპოზიტორიის "
"მდებარეობაზე"

#: app/flatpak-builtins-remote-add.c:72 app/flatpak-builtins-remote-modify.c:78
msgid "Disable GPG verification"
msgstr "GPG-ით გადამოწმების გათიშვა"

#: app/flatpak-builtins-remote-add.c:73 app/flatpak-builtins-remote-modify.c:79
msgid "Mark the remote as don't enumerate"
msgstr "დაშორებულის არა-ჩამოთვლადად მონიშვნა"

#: app/flatpak-builtins-remote-add.c:74 app/flatpak-builtins-remote-modify.c:80
msgid "Mark the remote as don't use for deps"
msgstr "დაშორებულის დამოკიდებულებების არ-გამოსაყენებლად მონიშვნა"

#: app/flatpak-builtins-remote-add.c:75 app/flatpak-builtins-remote-modify.c:81
msgid "Set priority (default 1, higher is more prioritized)"
msgstr "პრიორიტეტის დაყენება (ნაგულისხმები 1, რაც მაღალი, მით პრიორიტეტული)"

#: app/flatpak-builtins-remote-add.c:75 app/flatpak-builtins-remote-modify.c:81
msgid "PRIORITY"
msgstr "PRIORITY"

#: app/flatpak-builtins-remote-add.c:76
msgid "The named subset to use for this remote"
msgstr "სახელიანი ქვესეტი ამ დაშორებულისთვის გამოსაყენებლად"

#: app/flatpak-builtins-remote-add.c:76 app/flatpak-builtins-remote-modify.c:71
msgid "SUBSET"
msgstr "SUBSET"

#: app/flatpak-builtins-remote-add.c:77 app/flatpak-builtins-remote-modify.c:82
msgid "A nice name to use for this remote"
msgstr "მისაღები სახელი ამ დაშორებულისთვის"

#: app/flatpak-builtins-remote-add.c:78 app/flatpak-builtins-remote-modify.c:83
msgid "A one-line comment for this remote"
msgstr "ამ დაშორებულის ერთხაზიანი კომენტარი"

#: app/flatpak-builtins-remote-add.c:79 app/flatpak-builtins-remote-modify.c:84
msgid "A full-paragraph description for this remote"
msgstr "სრული პარაგრაფის სიგრძის მქონე კომენტარი ამ დაშორებულისთვის"

#: app/flatpak-builtins-remote-add.c:80 app/flatpak-builtins-remote-modify.c:85
msgid "URL for a website for this remote"
msgstr "ამ დაშორებულის გვებგვერდის ბმული"

#: app/flatpak-builtins-remote-add.c:81 app/flatpak-builtins-remote-modify.c:86
msgid "URL for an icon for this remote"
msgstr "ამ დაშორებული ხატულის ბმული"

#: app/flatpak-builtins-remote-add.c:82 app/flatpak-builtins-remote-modify.c:87
msgid "Default branch to use for this remote"
msgstr "ამ დაშორებულის ნაგულისხმები ბრენჩი"

#: app/flatpak-builtins-remote-add.c:84 app/flatpak-builtins-remote-modify.c:89
msgid "Import GPG key from FILE (- for stdin)"
msgstr "GPG გასაღების შემოტანა მითითებული ფაილიდან (stdin-სთვის გამოიყენეთ -)"

#: app/flatpak-builtins-remote-add.c:85 app/flatpak-builtins-remote-modify.c:90
msgid "Load signatures from URL"
msgstr ""

#: app/flatpak-builtins-remote-add.c:86 app/flatpak-builtins-remote-modify.c:92
msgid "Set path to local filter FILE"
msgstr "ბილიკის ლოკალური ფილტრის ფაილზე დაყენება"

#: app/flatpak-builtins-remote-add.c:87 app/flatpak-builtins-remote-modify.c:93
msgid "Disable the remote"
msgstr "დაშორებულის გამორთვა"

#: app/flatpak-builtins-remote-add.c:88 app/flatpak-builtins-remote-modify.c:94
msgid "Name of authenticator"
msgstr "ავთენტიკატორის სახელი"

#: app/flatpak-builtins-remote-add.c:90 app/flatpak-builtins-remote-modify.c:96
msgid "Autoinstall authenticator"
msgstr "ავთენტიკატორის ავტომატური დაყენება"

#: app/flatpak-builtins-remote-add.c:91 app/flatpak-builtins-remote-modify.c:97
msgid "Don't autoinstall authenticator"
msgstr "ავთენტიკატორი ავტომატურად დაყენებული არ იქნება"

#: app/flatpak-builtins-remote-add.c:92 app/flatpak-builtins-remote-modify.c:99
msgid "Don't follow the redirect set in the summary file"
msgstr "შეჯამების ფაილში გადამისამართების არ-მიყოლა"

#: app/flatpak-builtins-remote-add.c:261 app/flatpak-builtins-remote-add.c:268
#, c-format
msgid "Can't load uri %s: %s\n"
msgstr "URI %s-ის ჩატვირთვის შეცდომა: %s\n"

#: app/flatpak-builtins-remote-add.c:276 common/flatpak-dir.c:4643
#, c-format
msgid "Can't load file %s: %s\n"
msgstr "ფაილის %s ჩატვირთვის შეცდომა: %s\n"

#: app/flatpak-builtins-remote-add.c:304
msgid "NAME LOCATION - Add a remote repository"
msgstr "სახელი მდებარეობა - დაშორებული რეპოზიტორიის დამატება"

#: app/flatpak-builtins-remote-add.c:331
msgid "GPG verification is required if collections are enabled"
msgstr "თუ კოლექციები ჩართულია, GPG-ით გადამოწმება აუცილებელია"

#: app/flatpak-builtins-remote-add.c:393
#, c-format
msgid "Remote %s already exists"
msgstr "დაშორებული '%s' უკვე არსებობს"

#: app/flatpak-builtins-remote-add.c:405
#: app/flatpak-builtins-remote-modify.c:340
#, c-format
msgid "Invalid authenticator name %s"
msgstr "არასწორი ავთენტიკატორის სახელი %s"

#: app/flatpak-builtins-remote-add.c:422
#, c-format
msgid "Warning: Could not update extra metadata for '%s': %s\n"
msgstr ""
"გაფრთხილება: '%s'-ის დამატებითი მეტამონაცემების განახლების შეცდომა: %s\n"

#: app/flatpak-builtins-remote-delete.c:39
msgid "Remove remote even if in use"
msgstr "დაშორებულის წაშლა მაშინაც კი, თუ ის გამოიყენება"

#: app/flatpak-builtins-remote-delete.c:53
msgid "NAME - Delete a remote repository"
msgstr "სახელი - დაშორებული რეპოზიტორიის წაშლა"

#: app/flatpak-builtins-remote-delete.c:100
#, c-format
msgid "The following refs are installed from remote '%s':"
msgstr "დაშორებულიდან '%s' დაყენებულია შემდეგ მიმართვები:"

#: app/flatpak-builtins-remote-delete.c:101
msgid "Remove them?"
msgstr "წავშალო ელემენტი?"

#: app/flatpak-builtins-remote-delete.c:103
#, c-format
msgid "Can't remove remote '%s' with installed refs"
msgstr "დაყენებული მიმართვების მქონე დაშორებულის '%s' წაშლა შეუძლებელია"

#: app/flatpak-builtins-remote-info.c:55
msgid "Commit to show info for"
msgstr "კომიტი, რომლის ინფორმაციასაც გაჩვენებთ"

#: app/flatpak-builtins-remote-info.c:58
msgid "Display log"
msgstr "ჟურნალის ჩვენება"

#: app/flatpak-builtins-remote-info.c:61
msgid "Show parent"
msgstr "მშობლის ჩვენება"

#: app/flatpak-builtins-remote-info.c:65 app/flatpak-builtins-remote-ls.c:60
msgid "Use local caches even if they are stale"
msgstr "ლოკალური კეშის გამოყენება მაშინაც კი, როცა ის გაჭედილია"

#. Translators: A sideload is when you install from a local USB drive rather than the Internet.
#: app/flatpak-builtins-remote-info.c:67 app/flatpak-builtins-remote-ls.c:62
msgid "Only list refs available as sideloads"
msgstr "მხოლოდ გვერდით ჩასატვირთად ხელმისაწვდომი მიმართვების სია"

#: app/flatpak-builtins-remote-info.c:114
msgid ""
" REMOTE REF - Show information about an application or runtime in a remote"
msgstr ""
" დაშორებული მიმართვა - დაშორებულში არსებული აპლიკაციის ან გაშვების გარემოს "
"შესახებ ინფორმაციის ჩვენება"

#: app/flatpak-builtins-remote-info.c:125
msgid "REMOTE and REF must be specified"
msgstr "დაშორებულის და მიმართვის მითითება აუცილებელია"

#: app/flatpak-builtins-remote-info.c:247
#: app/flatpak-builtins-remote-info.c:282
#, fuzzy
msgid "Download Size:"
msgstr "გადმოწერის ზომა"

#: app/flatpak-builtins-remote-info.c:267
#: app/flatpak-builtins-remote-info.c:325
msgid "History:"
msgstr "ისტორია:"

#: app/flatpak-builtins-remote-info.c:348
msgid " Commit:"
msgstr " კომიტი:"

#: app/flatpak-builtins-remote-info.c:349
msgid " Subject:"
msgstr " თემა:"

#: app/flatpak-builtins-remote-info.c:350
msgid " Date:"
msgstr " თარიღი:"

#: app/flatpak-builtins-remote-info.c:383
#, c-format
msgid "Warning: Commit %s has no flatpak metadata\n"
msgstr "გართხილება: კომიტს %s flatpak-ის მეტამონაცემების არ გააჩნია\n"

#: app/flatpak-builtins-remote-list.c:43
msgid "Show remote details"
msgstr "დაშორებულის დეტალების ჩვენება"

#: app/flatpak-builtins-remote-list.c:44
msgid "Show disabled remotes"
msgstr "გამორთული დაშორებულების ჩვენება"

#: app/flatpak-builtins-remote-list.c:52
msgid "Title"
msgstr "სათაური"

#: app/flatpak-builtins-remote-list.c:52
msgid "Show the title"
msgstr "სათაურის ჩვენება"

#: app/flatpak-builtins-remote-list.c:53
msgid "Show the URL"
msgstr "URL-ის ჩვენება"

#: app/flatpak-builtins-remote-list.c:54
msgid "Show the collection ID"
msgstr "კოლექციის ID-ის ჩვენება"

#: app/flatpak-builtins-remote-list.c:55 app/flatpak-builtins-repo.c:392
msgid "Subset"
msgstr "ქვესეტი"

#: app/flatpak-builtins-remote-list.c:55
msgid "Show the subset"
msgstr "ქვესეტის ჩვენება"

#: app/flatpak-builtins-remote-list.c:56
msgid "Filter"
msgstr "ფილტრი"

#: app/flatpak-builtins-remote-list.c:56
msgid "Show filter file"
msgstr "ფილტრის ფაილის ჩვენება"

#: app/flatpak-builtins-remote-list.c:57
msgid "Priority"
msgstr "პრიორიტეტი"

#: app/flatpak-builtins-remote-list.c:57
msgid "Show the priority"
msgstr "პრიორიტეტის ჩვენება"

#: app/flatpak-builtins-remote-list.c:59
msgid "Comment"
msgstr "კომე_ნტარი"

#: app/flatpak-builtins-remote-list.c:59
msgid "Show comment"
msgstr "კომენტარის ჩვენება"

#: app/flatpak-builtins-remote-list.c:60
msgid "Show description"
msgstr "აღწერის ჩვენება"

#: app/flatpak-builtins-remote-list.c:61
msgid "Homepage"
msgstr "Homepage"

#: app/flatpak-builtins-remote-list.c:61
msgid "Show homepage"
msgstr "საწყისი გვერდის ჩვენება"

#: app/flatpak-builtins-remote-list.c:62
msgid "Icon"
msgstr "ხატულა"

#: app/flatpak-builtins-remote-list.c:62
msgid "Show icon"
msgstr "ხატულის ჩვენება"

#: app/flatpak-builtins-remote-list.c:231
msgid " - List remote repositories"
msgstr " - დაშორებული რეპოზიტორიების ჩვენება"

#: app/flatpak-builtins-remote-ls.c:52
msgid "Show arches and branches"
msgstr "არქიტექტურებისა და ბრენჩების ჩვენება"

#: app/flatpak-builtins-remote-ls.c:53
msgid "Show only runtimes"
msgstr "მხოლოდ გაშვების გარემოების ჩვენება"

#: app/flatpak-builtins-remote-ls.c:54
msgid "Show only apps"
msgstr "მხოლოდ აპების ჩვენება"

#: app/flatpak-builtins-remote-ls.c:55
msgid "Show only those where updates are available"
msgstr "მხოლოდ მათი ჩვენება, სადაც განახლება ხელმისაწვდომია"

#: app/flatpak-builtins-remote-ls.c:56
msgid "Limit to this arch (* for all)"
msgstr "ამ არქიტექტურაზე შეზღუდვა (* ყველასთვის)"

#: app/flatpak-builtins-remote-ls.c:77
msgid "Show the runtime"
msgstr "გაშვების გარემოების ჩვენება"

#: app/flatpak-builtins-remote-ls.c:79
msgid "Download size"
msgstr "გადმოწერის ზომა"

#: app/flatpak-builtins-remote-ls.c:79
msgid "Show the download size"
msgstr "გადმოწერის ზომის ჩვენება"

#: app/flatpak-builtins-remote-ls.c:391
msgid " [REMOTE or URI] - Show available runtimes and applications"
msgstr ""
" [დაშორებული ან URI] - ხელმისაწვდომი გაშვების გარემოებისა და აპლიკაციების "
"ჩვენება"

#: app/flatpak-builtins-remote-modify.c:67
msgid "Enable GPG verification"
msgstr "GPG-ით გადამოწმების ჩართვა"

#: app/flatpak-builtins-remote-modify.c:68
msgid "Mark the remote as enumerate"
msgstr "დაშორებულის ჩამოთვლადად მონიშვნა"

#: app/flatpak-builtins-remote-modify.c:69
msgid "Mark the remote as used for dependencies"
msgstr "დაშორებულის დამოკიდებულებებისთვის გამოსაყენებლად მონიშვნა"

#: app/flatpak-builtins-remote-modify.c:70
#, fuzzy
msgid "Set a new URL"
msgstr "ახალი URL-ის მითითება"

#: app/flatpak-builtins-remote-modify.c:71
msgid "Set a new subset to use"
msgstr "ახალი გამოსაყენებელი ქვესეტის მითითება"

#: app/flatpak-builtins-remote-modify.c:72
msgid "Enable the remote"
msgstr "დაშორებულის ჩართვა"

#: app/flatpak-builtins-remote-modify.c:73
msgid "Update extra metadata from the summary file"
msgstr "შეჯამების ფაილიდან დამატებითი მეტამონაცემების განახლება"

#: app/flatpak-builtins-remote-modify.c:91
msgid "Disable local filter"
msgstr "ლოკალური ფილტრის გამორთვა"

#: app/flatpak-builtins-remote-modify.c:95
msgid "Authenticator options"
msgstr "ავთნტიკატორის მორგება"

#: app/flatpak-builtins-remote-modify.c:98
msgid "Follow the redirect set in the summary file"
msgstr "შეჯამების ფაილში გადამისამართების მიყოლა"

#: app/flatpak-builtins-remote-modify.c:306
msgid "NAME - Modify a remote repository"
msgstr "NAME - დაშორებული რეპოზიტორიის შეცვლა"

#: app/flatpak-builtins-remote-modify.c:316
msgid "Remote NAME must be specified"
msgstr "დაშორებულის სახელის მითითება აუცილებელი"

#: app/flatpak-builtins-remote-modify.c:327
#, c-format
msgid "Updating extra metadata from remote summary for %s\n"
msgstr "%s-სთვის დაშორებული შეჯამებიდან დამატებითი მეტამონაცემების განახლება\n"

#: app/flatpak-builtins-remote-modify.c:330
#, c-format
msgid "Error updating extra metadata for '%s': %s\n"
msgstr "'%s'-სთვის დამატებითი მეტამონაცემების განახლების შეცდომა: %s\n"

#: app/flatpak-builtins-remote-modify.c:331
#, c-format
msgid "Could not update extra metadata for %s"
msgstr "%s-სთვის დამატებითი მეტამონაცემების განახლების შეცდომა"

#: app/flatpak-builtins-repair.c:43
msgid "Don't make any changes"
msgstr "ცვლილებები შეტანილი არ იქნება"

#: app/flatpak-builtins-repair.c:44
msgid "Reinstall all refs"
msgstr "ყველა მიმართვის თავიდან დაყენება"

#: app/flatpak-builtins-repair.c:68
#, c-format
msgid "Object missing: %s.%s\n"
msgstr "ობიექტი ვერ ვიპოვე: %s.%s\n"

#: app/flatpak-builtins-repair.c:76
#, c-format
msgid "Object invalid: %s.%s\n"
msgstr "არასწორი ობიექტი: %s.%s\n"

#: app/flatpak-builtins-repair.c:81
#, c-format
msgid "%s, deleting object\n"
msgstr "%s, ობიექტის წაშლა\n"

#: app/flatpak-builtins-repair.c:146
#, c-format
msgid "Can't load object %s: %s\n"
msgstr "ობიექტის %s ჩატვირთვის შეცდომა: %s\n"

#: app/flatpak-builtins-repair.c:228
#, c-format
msgid "Commit invalid %s: %s\n"
msgstr "არასწორი კომიტი %s: %s\n"

#: app/flatpak-builtins-repair.c:231
#, c-format
msgid "Deleting invalid commit %s: %s\n"
msgstr "არასწორი კომიტის %s წაშლა: %s\n"

#: app/flatpak-builtins-repair.c:261
#, c-format
msgid "Commit should be marked partial: %s\n"
msgstr "კომითი მონიშნული უნდა იყოს, როგორც ნაწილობრივი: %s\n"

#: app/flatpak-builtins-repair.c:264
#, c-format
msgid "Marking commit as partial: %s\n"
msgstr "კომიტის ნაწილობრივად მონიშვნა: %s\n"

#: app/flatpak-builtins-repair.c:293
#, c-format
msgid "Problems loading data for %s: %s\n"
msgstr "%s-სთვის მონაცემების ჩატვირთვის შეცდომა: %s\n"

#: app/flatpak-builtins-repair.c:306
#, c-format
msgid "Error reinstalling %s: %s\n"
msgstr "%s-ის თავიდან დაყენების შეცდომა: %s\n"

#: app/flatpak-builtins-repair.c:327
msgid "- Repair a flatpak installation"
msgstr "- flatpak -ის ფაილების შეკეთება"

#: app/flatpak-builtins-repair.c:406
#, c-format
msgid "Removing non-deployed ref %s…\n"
msgstr "არა-გაშლილი მიმართვის %s წაშლა...\n"

#: app/flatpak-builtins-repair.c:411
#, c-format
msgid "Skipping non-deployed ref %s…\n"
msgstr "არა-გაშლილი მიმართვის %s გამოტოვება...\n"

#: app/flatpak-builtins-repair.c:429
#, c-format
msgid "[%d/%d] Verifying %s…\n"
msgstr "[%d/%d] %s-ის გადამოწმება…\n"

#: app/flatpak-builtins-repair.c:435
#, c-format
msgid "Dry run: "
msgstr "მშრალი გაშვება: "

#: app/flatpak-builtins-repair.c:440
#, c-format
msgid "Deleting ref %s due to missing objects\n"
msgstr "ნაკლული ობიექტების გამო მიმართვა %s წაიშლება\n"

#: app/flatpak-builtins-repair.c:444
#, c-format
msgid "Deleting ref %s due to invalid objects\n"
msgstr "არასწორი ობიექტების გამო მიმართვა %s წაიშლება\n"

#: app/flatpak-builtins-repair.c:448
#, c-format
msgid "Deleting ref %s due to %d\n"
msgstr "მიმართვა %s წაიშლება %d-ის გამო\n"

#: app/flatpak-builtins-repair.c:464
#, c-format
msgid "Checking remotes...\n"
msgstr "დაშორებულების შემოწმება...\n"

#: app/flatpak-builtins-repair.c:482
#, c-format
msgid "Remote %s for ref %s is missing\n"
msgstr "დაშორებული %s მიმართვისთვის %s ვერ ვიპოვე\n"

#: app/flatpak-builtins-repair.c:484
#, c-format
msgid "Remote %s for ref %s is disabled\n"
msgstr "დაშორებული %s მიმართვისთვის %s გამორთულია\n"

#: app/flatpak-builtins-repair.c:490
#, c-format
msgid "Pruning objects\n"
msgstr "ობიექტების წაკვეთა\n"

#: app/flatpak-builtins-repair.c:498
#, c-format
msgid "Erasing .removed\n"
msgstr ".removed-ის წაშლა\n"

#: app/flatpak-builtins-repair.c:524
#, c-format
msgid "Reinstalling refs\n"
msgstr "მიმართვების თავიდან დაყენება\n"

#: app/flatpak-builtins-repair.c:526
#, c-format
msgid "Reinstalling removed refs\n"
msgstr "წაშლილი მიმართვების თავიდან დაყენება\n"

#: app/flatpak-builtins-repair.c:551
#, c-format
msgid "While removing appstream for %s: "
msgstr "%s-სთვის appstream-ის წაშლისას: "

#: app/flatpak-builtins-repair.c:558
#, c-format
msgid "While deploying appstream for %s: "
msgstr "%s-სთვის appstream-ის გაშლისას: "

#: app/flatpak-builtins-repo.c:106
#, c-format
msgid "Repo mode: %s\n"
msgstr "რეპოს რეჟიმი: %s\n"

#: app/flatpak-builtins-repo.c:113
#, c-format
msgid "Indexed summaries: %s\n"
msgstr "დაინდექსებული შეჯამებები: %s\n"

#: app/flatpak-builtins-repo.c:113 app/flatpak-builtins-repo.c:139
#: app/flatpak-builtins-repo.c:172
msgid "true"
msgstr "სიმართლე"

#: app/flatpak-builtins-repo.c:113 app/flatpak-builtins-repo.c:139
#: app/flatpak-builtins-repo.c:172
msgid "false"
msgstr "მცდარი"

#: app/flatpak-builtins-repo.c:121
#, c-format
msgid "Subsummaries: "
msgstr "ქვეშეჯამებები: "

#: app/flatpak-builtins-repo.c:136
#, c-format
msgid "Cache version: %d\n"
msgstr "ქეშის ვერსია: %d\n"

#: app/flatpak-builtins-repo.c:139
#, c-format
msgid "Indexed deltas: %s\n"
msgstr "დაინდექსებული დელტები: %s\n"

#: app/flatpak-builtins-repo.c:142
#, c-format
msgid "Title: %s\n"
msgstr "სათაური: %s\n"

#: app/flatpak-builtins-repo.c:145
#, c-format
msgid "Comment: %s\n"
msgstr "კომენტარი: %s\n"

#: app/flatpak-builtins-repo.c:148
#, c-format
msgid "Description: %s\n"
msgstr "აღწერა: %s\n"

#: app/flatpak-builtins-repo.c:151
#, c-format
msgid "Homepage: %s\n"
msgstr "საწყისი გვერდი: %s\n"

#: app/flatpak-builtins-repo.c:154
#, c-format
msgid "Icon: %s\n"
msgstr "ხატულა: %s\n"

#: app/flatpak-builtins-repo.c:157
#, c-format
msgid "Collection ID: %s\n"
msgstr "კოლექციის ID: %s\n"

#: app/flatpak-builtins-repo.c:160
#, c-format
msgid "Default branch: %s\n"
msgstr "ნაგულისხმები ბრენჩი: %s\n"

#: app/flatpak-builtins-repo.c:163
#, c-format
msgid "Redirect URL: %s\n"
msgstr "გადამისამართების URL: %s\n"

#: app/flatpak-builtins-repo.c:166
#, c-format
msgid "Deploy collection ID: %s\n"
msgstr "კოლექციის ID-ის ჩვენება: %s\n"

#: app/flatpak-builtins-repo.c:169
#, c-format
msgid "Authenticator name: %s\n"
msgstr "ავთენტიკატორის სახელი: %s\n"

#: app/flatpak-builtins-repo.c:172
#, c-format
msgid "Authenticator install: %s\n"
msgstr "ავთენტიკატორის დაყენება: %s\n"

#: app/flatpak-builtins-repo.c:180
#, c-format
msgid "GPG key hash: %s\n"
msgstr "GPG გასაღების ჰეში: %s\n"

#: app/flatpak-builtins-repo.c:184
#, c-format
msgid "%zd summary branches\n"
msgstr "%zd ჯამური ბრენჩი\n"

#: app/flatpak-builtins-repo.c:336
msgid "Installed"
msgstr "დაყენებულია"

#. Translators: Download is used here as a noun
#: app/flatpak-builtins-repo.c:338 app/flatpak-cli-transaction.c:1462
msgid "Download"
msgstr "ჩამოტვირთვა"

#: app/flatpak-builtins-repo.c:339
msgid "Subsets"
msgstr "ქვეჯგუფები"

#: app/flatpak-builtins-repo.c:393
msgid "Digest"
msgstr "დაიჯესტი"

#: app/flatpak-builtins-repo.c:394
msgid "History length"
msgstr "ისტორიის ხანგრძლივობა"

#: app/flatpak-builtins-repo.c:711
msgid "Print general information about the repository"
msgstr "რეპოზიტორიის მიმოხილვის ინფორმაციის გამოტანა"

#: app/flatpak-builtins-repo.c:712
msgid "List the branches in the repository"
msgstr "რეპოზიტორიის ბრენჩების სიის ჩვენება"

#: app/flatpak-builtins-repo.c:713
msgid "Print metadata for a branch"
msgstr "ბრენჩის მეტამონაცემების გამოტანა"

#: app/flatpak-builtins-repo.c:714
msgid "Show commits for a branch"
msgstr "ბრენჩის კომიტების ჩვენება"

#: app/flatpak-builtins-repo.c:715
msgid "Print information about the repo subsets"
msgstr "რეპოზიტორიებს ქვესეტების შესახებ ინფორმაციის გამოტანა"

#: app/flatpak-builtins-repo.c:716
msgid "Limit information to subsets with this prefix"
msgstr "ინფორმაციის ამ პრეფიქსის მქონე ქვესეტებზე შეზღუდვა"

#: app/flatpak-builtins-repo.c:732
msgid "LOCATION - Repository maintenance"
msgstr "მდებარეობა - რეპოზიტორიის რემონტი"

#: app/flatpak-builtins-run.c:159
msgid "Command to run"
msgstr "გასაშვები ბრძანება"

#: app/flatpak-builtins-run.c:160
msgid "Directory to run the command in"
msgstr "საქაღალდე, სადაც ბრძანება გაეშვება"

#: app/flatpak-builtins-run.c:161
msgid "Branch to use"
msgstr "გამოსაყენებელი ბრენჩი"

#: app/flatpak-builtins-run.c:162
msgid "Use development runtime"
msgstr "სატესტო გაშვების გარემოს გამოყენება"

#: app/flatpak-builtins-run.c:163
msgid "Runtime to use"
msgstr "გამოსაყენებელი გაშვების გარემო"

#: app/flatpak-builtins-run.c:164
msgid "Runtime version to use"
msgstr "გამოსაყენებელი გაშვების გარემოს ვერსია"

#: app/flatpak-builtins-run.c:167
msgid "Log accessibility bus calls"
msgstr "წვდომადობის მატარებლის გამოძახებების ჟურნალში ჩაწერა"

#: app/flatpak-builtins-run.c:168
msgid "Don't proxy accessibility bus calls"
msgstr "წვდომადობის მატარებლის გამოძახებები ჟურნალში არ ჩაიწერება"

#: app/flatpak-builtins-run.c:169
msgid "Proxy accessibility bus calls (default except when sandboxed)"
msgstr ""
"წვდომადობის მატარებლის გამოძახებებისთვის პროქსის გამოყენება (ნაგულისხმებია "
"გარდა იმ შემთხვევისა, როცა სენდბოქსშია გაშვებული)"

#: app/flatpak-builtins-run.c:170
msgid "Don't proxy session bus calls"
msgstr "წვდომადობის მატარებლის გამოძახებებისთვის პროქსი გამოყენებული არ იქნება"

#: app/flatpak-builtins-run.c:171
msgid "Proxy session bus calls (default except when sandboxed)"
msgstr ""
"სესიის მატარებლის გამოძახებებისთვის პროქსის გამოყენება (ნაგულისხმებია გარდა "
"იმ შემთხვევისა, როცა სენდბოქსშია გაშვებული)"

#: app/flatpak-builtins-run.c:172
msgid "Don't start portals"
msgstr "პორტალები არ გაეშვება"

#: app/flatpak-builtins-run.c:173
msgid "Enable file forwarding"
msgstr "ფაილების გადაგზავნის ჩართვა"

#: app/flatpak-builtins-run.c:174
msgid "Run specified commit"
msgstr "მითითებული კომიტის გაშვება"

#: app/flatpak-builtins-run.c:175
msgid "Use specified runtime commit"
msgstr "მითითებული გაშვების გარემოს კომიტის გამოყენება"

#: app/flatpak-builtins-run.c:176
msgid "Run completely sandboxed"
msgstr "სრულად სენდბოქსში გაშვება"

#: app/flatpak-builtins-run.c:178
msgid "Use PID as parent pid for sharing namespaces"
msgstr "სახელების სივრცეების გაზიარებისთვის PID-ად მშობლის PID-ის გამოყენება"

#: app/flatpak-builtins-run.c:179
msgid "Make processes visible in parent namespace"
msgstr "პროცესების გამოჩენა მშობელ სახელების სივრცეში"

#: app/flatpak-builtins-run.c:180
msgid "Share process ID namespace with parent"
msgstr "პროცესის ID-ის სახელების სივრცის მშობელთან გაზიარება"

#: app/flatpak-builtins-run.c:181
msgid "Write the instance ID to the given file descriptor"
msgstr "გაშვებული ასლის ID-ის ჩაწერა მითითებულ ფაილის დესკრიპტორში"

#: app/flatpak-builtins-run.c:182
msgid "Use PATH instead of the app's /app"
msgstr "აპის /app-ის მაგიერ მითითებული ბილიკის გამოყენება"

#: app/flatpak-builtins-run.c:183
#, fuzzy
msgid "Use FD instead of the app's /app"
msgstr "აპის /app-ის მაგიერ მითითებული ბილიკის გამოყენება"

#: app/flatpak-builtins-run.c:183 app/flatpak-builtins-run.c:185
#: app/flatpak-builtins-run.c:187 app/flatpak-builtins-run.c:188
#: common/flatpak-context.c:2672
msgid "FD"
msgstr "FD"

#: app/flatpak-builtins-run.c:184
msgid "Use PATH instead of the runtime's /usr"
msgstr "გაშვებული გარემოს /usr-ის მაგიერ მითითებული ბილიკის გამოყენება"

#: app/flatpak-builtins-run.c:185
#, fuzzy
msgid "Use FD instead of the runtime's /usr"
msgstr "გაშვებული გარემოს /usr-ის მაგიერ მითითებული ბილიკის გამოყენება"

#: app/flatpak-builtins-run.c:186
#, fuzzy
msgid "Clear all outside environment variables"
msgstr "გარემოს ცვლადის დაყენება"

#: app/flatpak-builtins-run.c:187
msgid ""
"Bind mount the file or directory referred to by FD to its canonicalized path"
msgstr ""

#: app/flatpak-builtins-run.c:188
msgid ""
"Bind mount the file or directory referred to by FD read-only to its "
"canonicalized path"
msgstr ""

#: app/flatpak-builtins-run.c:219
msgid "APP [ARGUMENT…] - Run an app"
msgstr "აპი [არგუმენტი…] - აპის გაშვება"

#: app/flatpak-builtins-run.c:370
#, c-format
msgid "runtime/%s/%s/%s not installed"
msgstr "გაშვების გარემო/%s/%s/%s დაყენებული არაა"

#: app/flatpak-builtins-run.c:419
msgid "app-fd and app-path cannot both be used"
msgstr ""

#: app/flatpak-builtins-run.c:449
msgid "usr-fd and usr-path cannot both be used"
msgstr ""

#: app/flatpak-builtins-search.c:37
msgid "Arch to search for"
msgstr "მოსაძებნი არქიტექტურა"

#: app/flatpak-builtins-search.c:49
msgid "Remotes"
msgstr "დაშორებულები"

#: app/flatpak-builtins-search.c:49
msgid "Show the remotes"
msgstr "დაშორებულების ჩვენება"

#: app/flatpak-builtins-search.c:244
msgid "TEXT - Search remote apps/runtimes for text"
msgstr "ტექსტი - დაშორებულ აპებში/გაშვების გარემოებში ტექსტის ძებნა"

#: app/flatpak-builtins-search.c:255
msgid "TEXT must be specified"
msgstr "TEXT -ის მითითება აუცილებელია"

#: app/flatpak-builtins-search.c:338
msgid "No matches found"
msgstr "არაფერი მოიძებნა"

#: app/flatpak-builtins-uninstall.c:54
msgid "Arch to uninstall"
msgstr "წასაშლელი არქიტექტურა"

#: app/flatpak-builtins-uninstall.c:55
msgid "Keep ref in local repository"
msgstr "ლოკალურ რეპოზიტორიაში მიმართვის შენახვა"

#: app/flatpak-builtins-uninstall.c:56
msgid "Don't uninstall related refs"
msgstr "დაკავშირებული მიმართვები არ წაიშლება"

#: app/flatpak-builtins-uninstall.c:57
msgid "Remove files even if running"
msgstr "ფაილები წაიშლება მაშინაც კი, თუ ისინი გაშვებულია"

#: app/flatpak-builtins-uninstall.c:60
msgid "Uninstall all"
msgstr "ყველას წაშლა"

#: app/flatpak-builtins-uninstall.c:61
msgid "Uninstall unused"
msgstr "გამოუყენებლის წაშლა"

#: app/flatpak-builtins-uninstall.c:62
msgid "Delete app data"
msgstr "აპლიკაციის მონაცემების წაშლა"

#: app/flatpak-builtins-uninstall.c:141
#, c-format
msgid "Delete data for %s?"
msgstr "წავშალო %s-ის მონაცემები?"

#: app/flatpak-builtins-uninstall.c:220
#, c-format
msgid "Info: applications using the extension %s%s%s branch %s%s%s:\n"
msgstr "ინფორმაცია: აპლიკაციები, რომლებიც იყენებენ %s%s%s ბრენჩს %s%s%s:\n"

#: app/flatpak-builtins-uninstall.c:223
#, c-format
msgid "Info: applications using the runtime %s%s%s branch %s%s%s:\n"
msgstr ""
"ინფორმაცია: აპლიკაციები, რომლებიც იყენებენ გაშვების გარემოს %s%s%s ბრენჩს "
"%s%s%s:\n"
"\n"

#: app/flatpak-builtins-uninstall.c:238
msgid "Really remove?"
msgstr "მართლა წავშალო?"

#: app/flatpak-builtins-uninstall.c:255
msgid "[REF…] - Uninstall applications or runtimes"
msgstr "[მიმართვა…] - აპლიკაციების ან გაშვების გარემოების წაშლა"

#: app/flatpak-builtins-uninstall.c:264
msgid "Must specify at least one REF, --unused, --all or --delete-data"
msgstr ""
"აუცილებელია მიუთითოთ ერთერთი პარამეტრებიდან: მიმართვა, --unused, --all და --"
"delete-data"

#: app/flatpak-builtins-uninstall.c:267
msgid "Must not specify REFs when using --all"
msgstr "--all პარამეტრის გამოყენებისას მიმართვის მითითება დაუშვებელია"

#: app/flatpak-builtins-uninstall.c:270
msgid "Must not specify REFs when using --unused"
msgstr "--unused პარამეტრის გამოყენებისას მიმართვის მითითება დაუშვებელია"

#: app/flatpak-builtins-uninstall.c:336
#, c-format
msgid ""
"\n"
"These runtimes in installation '%s' are pinned and won't be removed; see "
"flatpak-pin(1):\n"
msgstr ""
"\n"
"ეს გაშვების გარემოები პაკეტში '%s' მიმაგრებულია და არ წაიშლება. იხ. flatpack-"
"pin(1):\n"

#: app/flatpak-builtins-uninstall.c:370
#, c-format
msgid "Nothing unused to uninstall\n"
msgstr "წასაშლელად გამოუყენებელი ვერაფერი ვიპოვე\n"

#: app/flatpak-builtins-uninstall.c:444
#, c-format
msgid "No installed refs found for ‘%s’"
msgstr "'%s'-სთვის დაყენებული მიმართვები ნაპოვნი არაა"

#: app/flatpak-builtins-uninstall.c:447
#, c-format
msgid " with arch ‘%s’"
msgstr " არქიტექტურით ‘%s’"

#: app/flatpak-builtins-uninstall.c:449
#, c-format
msgid " with branch ‘%s’"
msgstr " ბრენჩით ‘%s’"

#: app/flatpak-builtins-uninstall.c:456
#, c-format
msgid "Warning: %s is not installed\n"
msgstr "გაფრთხილება: %s დაყენებული არაა\n"

#: app/flatpak-builtins-uninstall.c:490
#, c-format
msgid "None of the specified refs are installed"
msgstr "მითითებული მიმართვებიდან არც ერთია დაყენებული"

#: app/flatpak-builtins-uninstall.c:599
#, c-format
msgid "No app data to delete\n"
msgstr ""

#: app/flatpak-builtins-update.c:56
msgid "Arch to update for"
msgstr "განსაახლებელი არქიტექტურა"

#: app/flatpak-builtins-update.c:57
msgid "Commit to deploy"
msgstr "კომიტი განლაგებისთვის"

#: app/flatpak-builtins-update.c:58
msgid "Remove old files even if running"
msgstr "ფაილები წაიშლება მაშინაც კი, თუ ისინი გაშვებულია"

#: app/flatpak-builtins-update.c:59
msgid "Don't pull, only update from local cache"
msgstr "პულის გარეშე, მხოლოდ ლოკალური კეშიდან განახლება"

#: app/flatpak-builtins-update.c:61
msgid "Don't update related refs"
msgstr "დაკავშირებული მიმართვებ არ განახლდება"

#: app/flatpak-builtins-update.c:66
msgid "Update appstream for remote"
msgstr "დაშორებულისთვის appstream-ის განახლება"

#: app/flatpak-builtins-update.c:67
msgid "Only update this subpath"
msgstr "მხოლოდ ამ ქვებილიკის განახლება"

#: app/flatpak-builtins-update.c:90
msgid "[REF…] - Update applications or runtimes"
msgstr "[მიმართვა…] - აპლიკაციების ან გაშვების გარემოების განახლება"

#: app/flatpak-builtins-update.c:121
msgid "With --commit, only one REF may be specified"
msgstr "--commit -თან ერთად მხოლოდ ერთი მიმართვის მითითება შეგიძლიათ"

#: app/flatpak-builtins-update.c:162
#, c-format
msgid "Looking for updates…\n"
msgstr "განახლებების ძებნა…\n"

#: app/flatpak-builtins-update.c:215
#, c-format
msgid "Unable to update %s: %s\n"
msgstr "%s-ის განახლების შეცდომა: %s\n"

#: app/flatpak-builtins-update.c:274
#, fuzzy, c-format
msgid "Nothing to update.\n"
msgstr "გასაკეთებელი არაფერია.\n"

#: app/flatpak-builtins-utils.c:337
#, fuzzy, c-format
msgid ""
"Remote ‘%s’ found in multiple installations, unable to proceed in non-"
"interactive mode"
msgstr ""
"მიმართვა '%s' მრავალ დაყენებაშია აღმოჩენილი: %s. აუცილებელია, მხოლოდ ერთი "
"მიუთითოთ."

#: app/flatpak-builtins-utils.c:346
#, c-format
msgid "Remote ‘%s’ found in multiple installations:"
msgstr "დაშორებული '%s' ერთზე მეტ დაყენებულ პაკეტშია აღმოჩენილი:"

#: app/flatpak-builtins-utils.c:347 app/flatpak-builtins-utils.c:442
#: app/flatpak-builtins-utils.c:538 app/flatpak-builtins-utils.c:540
#: app/flatpak-builtins-utils.c:598
msgid "Which do you want to use (0 to abort)?"
msgstr "რომელი გნებავთ, გამოიყენოთ? (0 შესაწყვეტად)"

#: app/flatpak-builtins-utils.c:349
#, c-format
msgid "No remote chosen to resolve ‘%s’ which exists in multiple installations"
msgstr ""
"'%s'-ის, რომელიც ერთზე მეტ დაყენებულ პაკეტში არსებობს, ამოსახსნელად "
"დაშორებული მითითებული არაა"

#: app/flatpak-builtins-utils.c:358
#, c-format
msgid ""
"Remote \"%s\" not found\n"
"Hint: Use flatpak remote-add to add a remote"
msgstr ""
"დაშორებული '%s' აღმოჩენილი არაა\n"
"მინიშნება: დაშორებულის დასამატებლად გამოიყენეთ flatpack remote-add"

#: app/flatpak-builtins-utils.c:364
#, c-format
msgid "Remote \"%s\" not found in the %s installation"
msgstr "დაშორებული '%s' დაყენებულ პაკეტში '%s' აღმოჩენილი არაა"

#: app/flatpak-builtins-utils.c:404
#, c-format
msgid "Multiple refs match ‘%s’, unable to proceed in non-interactive mode"
msgstr ""

#. default to yes on Enter
#: app/flatpak-builtins-utils.c:430
#, c-format
msgid ""
"Found ref ‘%s’ in remote ‘%s’ (%s).\n"
"Use this ref?"
msgstr ""
"აღმოჩენილია მიმართვა '%s' დაშორებულში '%s' (%s).\n"
"გამოვიყენო ეს მიმართვა?"

#: app/flatpak-builtins-utils.c:434 app/flatpak-builtins-utils.c:444
#: app/flatpak-builtins-utils.c:522 app/flatpak-builtins-utils.c:543
#, c-format
msgid "No ref chosen to resolve matches for ‘%s’"
msgstr "'%s'-სთვის დამთხვევების ამოსახსნელად მიმართვა არჩეული არაა"

#: app/flatpak-builtins-utils.c:440
#, c-format
msgid "Similar refs found for ‘%s’ in remote ‘%s’ (%s):"
msgstr "მსგავსი მიმართვები აღმოჩენილია '%s'-სთვის დაშორებულში '%s' (%s):"

#: app/flatpak-builtins-utils.c:488
#, c-format
msgid ""
"Multiple installed refs match ‘%s’, unable to proceed in non-interactive mode"
msgstr ""

#. default to yes on Enter
#: app/flatpak-builtins-utils.c:518
#, c-format
msgid "Found installed ref ‘%s’ (%s). Is this correct?"
msgstr "ვიპოვე დაყენებული მიმართვა ‘%s’ (%s). სწორია?"

#: app/flatpak-builtins-utils.c:534
#, c-format
msgid "All of the above"
msgstr "ყველა ზემოდან"

#: app/flatpak-builtins-utils.c:535
#, c-format
msgid "Similar installed refs found for ‘%s’:"
msgstr "მსგავსი დაყენებული მიმართვები აღმოჩენილია '%s'-სთვის:"

#: app/flatpak-builtins-utils.c:579
#, c-format
msgid ""
"Multiple remotes have refs matching ‘%s’, unable to proceed in non-"
"interactive mode"
msgstr ""

#: app/flatpak-builtins-utils.c:597
#, c-format
msgid "Remotes found with refs similar to ‘%s’:"
msgstr "აღმოჩენილია '%s'-ის მსგავსი მიმართვების მქონე დაშორებულები:"

#: app/flatpak-builtins-utils.c:600
#, c-format
msgid "No remote chosen to resolve matches for ‘%s’"
msgstr "'%s'-სთვის დამთხვევების ამოსახსნელად დაშორებული არჩეული არაა"

#: app/flatpak-builtins-utils.c:696 app/flatpak-builtins-utils.c:699
#, c-format
msgid "Updating appstream data for user remote %s"
msgstr "Appstream-ის მონაცემების განახლება მომხმარებლის დაშორებულისთვის %s"

#: app/flatpak-builtins-utils.c:706 app/flatpak-builtins-utils.c:709
#, c-format
msgid "Updating appstream data for remote %s"
msgstr "Appstream-ის მონაცემების განახლება დაშორებულისთვის %s"

#: app/flatpak-builtins-utils.c:717 app/flatpak-builtins-utils.c:719
msgid "Error updating"
msgstr "განახლების შეცდომა"

#: app/flatpak-builtins-utils.c:755
#, c-format
msgid "Remote \"%s\" not found"
msgstr "დაშორებული \"%s\" ვერ ვიპოვე"

#: app/flatpak-builtins-utils.c:796
#, c-format
msgid "Ambiguous suffix: '%s'."
msgstr "ორაზროვანი სუფიქსი: '%s'."

#. Translators: don't translate the values
#: app/flatpak-builtins-utils.c:798 app/flatpak-builtins-utils.c:813
msgid "Possible values are :s[tart], :m[iddle], :e[nd] or :f[ull]"
msgstr ""
"შესაძლო მნიშვნელობებია: :s(გაშვება), :m(შუა), :e(დასასრული ან :f(სრული)"

#: app/flatpak-builtins-utils.c:811
#, c-format
msgid "Invalid suffix: '%s'."
msgstr "არასწორი სუფიქსი: \"%s\"."

#: app/flatpak-builtins-utils.c:846
#, c-format
msgid "Ambiguous column: %s"
msgstr "ორაზროვანი სვეტი: %s"

#: app/flatpak-builtins-utils.c:859
#, c-format
msgid "Unknown column: %s"
msgstr "უცნობი სვეტი: %s"

#: app/flatpak-builtins-utils.c:917
msgid "Available columns:\n"
msgstr "ხელმისაწვდომი სვეტები:\n"

#: app/flatpak-builtins-utils.c:927
msgid "Show all columns"
msgstr "ყველა სვეტის ჩვენება"

#: app/flatpak-builtins-utils.c:928
msgid "Show available columns"
msgstr "ხელმისაწვდომი სვეტების ჩვენება"

#: app/flatpak-builtins-utils.c:931
msgid "Append :s[tart], :m[iddle], :e[nd] or :f[ull] to change ellipsization"
msgstr ""
"ოვალიზაციის შესაცვლელად ბოლოში მიაწერეთ :s(დასაწყისი), m(შუა) ან f(სრული)"

#: app/flatpak-builtins-utils.c:1483
#, c-format
msgid "Unknown scheme in sideload location %s"
msgstr ""

#: app/flatpak-cli-transaction.c:96 app/flatpak-cli-transaction.c:102
#, c-format
msgid "Required runtime for %s (%s) found in remote %s\n"
msgstr "%s-სთვის (%s) აუცილებელი გაშვები გარემო აღმოჩენილია დაშორებულში %s\n"

#: app/flatpak-cli-transaction.c:104
msgid "Do you want to install it?"
msgstr "გნებავთ, დააყენოთ?"

#: app/flatpak-cli-transaction.c:110
#, c-format
msgid "Required runtime for %s (%s) found in remotes:"
msgstr "%s-სთვის (%s) აუცილებელი გაშვების გარემო აღმოჩენილია დაშორებულებში:"

#: app/flatpak-cli-transaction.c:112
msgid "Which do you want to install (0 to abort)?"
msgstr "რომელი გნებავთ, დააყენოთ (0 გასაუქმებლად)?"

#: app/flatpak-cli-transaction.c:132
#, c-format
msgid "Configuring %s as new remote '%s'\n"
msgstr "%s-ის მორგება, როგორც ახალი დაშორებული '%s'\n"

#. default to yes on Enter
#: app/flatpak-cli-transaction.c:139
#, c-format
msgid ""
"The remote '%s', referred to by '%s' at location %s contains additional "
"applications.\n"
"Should the remote be kept for future installations?"
msgstr ""
"დაშორებული '%s', რომელსაც მიმართავს '%s' მდებარეობაზე '%s' დამატებით "
"აპლიკაციებს შეიცავს.\n"
"დავიტოვო ეს დაშორებული მომავალში გამოსაყენებლად?"

#. default to yes on Enter
#: app/flatpak-cli-transaction.c:147
#, c-format
msgid ""
"The application %s depends on runtimes from:\n"
"  %s\n"
"Configure this as new remote '%s'"
msgstr ""
"აპლიკაცია %s დამოკიდებულია გაშვების გარემოებზე დაშორებულიდან:\n"
"  %s\n"
"ამის ახალ დაშორებულად '%s' გამოყენება"

#. Formatted size/remaining time in seconds
#: app/flatpak-cli-transaction.c:321
#, c-format
msgid "%s/s%s%s"
msgstr ""

#. Download progress percentage, use the appropriate
#. percent format for your language
#: app/flatpak-cli-transaction.c:359
#, c-format
msgid "%3d%%"
msgstr ""

#: app/flatpak-cli-transaction.c:414
msgid "Installing…"
msgstr "დაყენება…"

#: app/flatpak-cli-transaction.c:416
#, c-format
msgid "Installing %d/%d…"
msgstr "დაყენება %d/%d…"

#: app/flatpak-cli-transaction.c:421
msgid "Updating…"
msgstr "მიმდინარეობს განახლება…"

#: app/flatpak-cli-transaction.c:423
#, c-format
msgid "Updating %d/%d…"
msgstr "განახლება %d/%d…"

#: app/flatpak-cli-transaction.c:428
msgid "Uninstalling…"
msgstr "წაშლა…"

#: app/flatpak-cli-transaction.c:430
#, c-format
msgid "Uninstalling %d/%d…"
msgstr "%d/%d წაშლა…"

#: app/flatpak-cli-transaction.c:496 app/flatpak-quiet-transaction.c:161
#, c-format
msgid "Info: %s was skipped"
msgstr "ინფორმაცია: %s გამოტოვებულია"

#: app/flatpak-cli-transaction.c:519
#, c-format
msgid "Warning: %s%s%s already installed"
msgstr "გაფრთხილება: %s%s%s უკვე დაყენებულია"

#: app/flatpak-cli-transaction.c:522
#, c-format
msgid "Error: %s%s%s already installed"
msgstr "შეცდომა: %s%s%s უკვე დაყენებულია"

#: app/flatpak-cli-transaction.c:528
#, c-format
msgid "Warning: %s%s%s not installed"
msgstr "გაფრთხილება: %s%s%s დაყენებული არაა"

#: app/flatpak-cli-transaction.c:531
#, c-format
msgid "Error: %s%s%s not installed"
msgstr "შეცდომა: %s%s%s დაყენებული არაა"

#: app/flatpak-cli-transaction.c:537
#, c-format
msgid "Warning: %s%s%s needs a later flatpak version"
msgstr "გაფრთხილება: %s%s%s-ს flatpak-ის უფრო ახალი ვერსია სჭირდება"

#: app/flatpak-cli-transaction.c:540
#, c-format
msgid "Error: %s%s%s needs a later flatpak version"
msgstr "შეცდომა: %s%s%s-ს flatpak-ის უფრო ახალი ვერსია სჭირდება"

#: app/flatpak-cli-transaction.c:546
msgid "Warning: Not enough disk space to complete this operation"
msgstr "გაფრთხილება: ოპერაციის დასასრულებლად დისკზე საკმარისი ადგილი არაა"

#: app/flatpak-cli-transaction.c:548
msgid "Error: Not enough disk space to complete this operation"
msgstr "შეცდომა: ოპერაციის დასასრულებლად დისკზე საკმარისი ადგილი არაა"

#: app/flatpak-cli-transaction.c:553
#, c-format
msgid "Warning: %s"
msgstr "გაფრთხილება: %s"

#: app/flatpak-cli-transaction.c:555
#, c-format
msgid "Error: %s"
msgstr "შეცდომა:%s"

#: app/flatpak-cli-transaction.c:570
#, c-format
msgid "Failed to install %s%s%s: "
msgstr "%s%s%s-ის დაყენება ჩავარდა: "

#: app/flatpak-cli-transaction.c:577
#, c-format
msgid "Failed to update %s%s%s: "
msgstr "%s%s%s-ის განახლება ჩავარდა: "

#: app/flatpak-cli-transaction.c:584
#, c-format
msgid "Failed to install bundle %s%s%s: "
msgstr "ჩავარდა დაყენება პაკეტისთვის %s%s%s: "

#: app/flatpak-cli-transaction.c:591
#, c-format
msgid "Failed to uninstall %s%s%s: "
msgstr "%s%s%s-ის წაშლა ჩავარდა: "

#: app/flatpak-cli-transaction.c:642
#, c-format
msgid "Authentication required for remote '%s'\n"
msgstr "დაშორებული '%s'-ისთვის ავთენტიკაცია გჭირდებათ\n"

#: app/flatpak-cli-transaction.c:643
msgid "Open browser?"
msgstr "გავხსნა ბრაუზერში?"

#: app/flatpak-cli-transaction.c:699
#, c-format
msgid "Login required remote %s (realm %s)\n"
msgstr "დაშორებულის %s (რეალმი %s) გამოსაყენებლად შესვლა დაგჭირდებათ\n"

#: app/flatpak-cli-transaction.c:704
msgid "Password"
msgstr "პაროლი"

#. Only runtimes can be pinned
#: app/flatpak-cli-transaction.c:759
#, c-format
msgid ""
"\n"
"Info: (pinned) runtime %s%s%s branch %s%s%s is end-of-life, in favor of "
"%s%s%s branch %s%s%s\n"
msgstr ""
"\n"
"ინფორმაცია: (მიმაგრებული) გაშვების გარემოს %s%s%s ბრენჩის %s%s%s მხარდაჭერა "
"ამოწურულია. გამოიყენეთ %s%s%s ბრენჩი %s%s%s\n"

#: app/flatpak-cli-transaction.c:765
#, c-format
msgid ""
"\n"
"Info: runtime %s%s%s branch %s%s%s is end-of-life, in favor of %s%s%s branch "
"%s%s%s\n"
msgstr ""
"\n"
"ინფორმაცია: გაშვების გარემოს %s%s%s ბრენჩის %s%s%s მხარდაჭერა ამოწურულია. "
"გამოიყენეთ %s%s%s ბრენჩი %s%s%s\n"

#: app/flatpak-cli-transaction.c:768
#, c-format
msgid ""
"\n"
"Info: app %s%s%s branch %s%s%s is end-of-life, in favor of %s%s%s branch "
"%s%s%s\n"
msgstr ""
"\n"
"ინფორმაცია: აპის %s%s%s ბრენჩის %s%s%s მხარდაჭერა ამოწურულია. გამოიყენეთ "
"%s%s%s ბრენჩი %s%s%s\n"

#. Only runtimes can be pinned
#: app/flatpak-cli-transaction.c:780
#, c-format
msgid ""
"\n"
"Info: (pinned) runtime %s%s%s branch %s%s%s is end-of-life, with reason:\n"
msgstr ""
"\n"
"ინფორმაცია: (მიმაგრებული) გაშვების გარემოს %s%s%s ბრენჩის %s%s%s მხარდაჭერა "
"ამოწურულია მიზეზით:\n"

#: app/flatpak-cli-transaction.c:786
#, c-format
msgid ""
"\n"
"Info: runtime %s%s%s branch %s%s%s is end-of-life, with reason:\n"
msgstr ""
"\n"
"ინფორმაცია: გაშვების გარემოს %s%s%s ბრენჩის %s%s%s მხარდაჭერა ამოწურულია "
"მიზეზით:\n"

#: app/flatpak-cli-transaction.c:789
#, c-format
msgid ""
"\n"
"Info: app %s%s%s branch %s%s%s is end-of-life, with reason:\n"
msgstr ""
"\n"
"ინფორმაცია: აპის %s%s%s ბრენჩის %s%s%s მხარდაჭერა ამოწურულია მიზეზით:\n"

#: app/flatpak-cli-transaction.c:963
#, c-format
msgid "Info: applications using this extension:\n"
msgstr "ინფორმაცია: აპლიკაციები, რომლებიც ამ გაფართოებას იყენებენ:\n"

#: app/flatpak-cli-transaction.c:965
#, c-format
msgid "Info: applications using this runtime:\n"
msgstr "ინფორმაცია: აპლიკაციები, რომლებიც ამ გაშვების გარემოს იყენებენ:\n"

#: app/flatpak-cli-transaction.c:984
msgid "Replace?"
msgstr "ჩავანაცვლო?"

#: app/flatpak-cli-transaction.c:987 app/flatpak-quiet-transaction.c:247
#, c-format
msgid "Updating to rebased version\n"
msgstr "რებაზირებულ ვერსიაზე განახლება\n"

#: app/flatpak-cli-transaction.c:1011
#, c-format
msgid "Failed to rebase %s to %s: "
msgstr "%s-ის %s-ზე რებაზირების შეცდომა: "

#: app/flatpak-cli-transaction.c:1277
#, c-format
msgid "New %s%s%s permissions:"
msgstr "ახალი %s%s%s წვდომები:"

#: app/flatpak-cli-transaction.c:1279
#, c-format
msgid "%s%s%s permissions:"
msgstr "%s%s%s წვდომები:"

#: app/flatpak-cli-transaction.c:1343
msgid "Warning: "
msgstr "გაფრთხილება: "

#. translators: This is short for operation, the title of a one-char column
#: app/flatpak-cli-transaction.c:1442
msgid "Op"
msgstr "ოპი"

#. Avoid resizing the download column too much,
#. * by making the title as long as typical content
#.
#: app/flatpak-cli-transaction.c:1458 app/flatpak-cli-transaction.c:1503
msgid "partial"
msgstr "ნაწილობრივ"

#: app/flatpak-cli-transaction.c:1535
msgid "Proceed with these changes to the user installation?"
msgstr "გადავატარო ეს ცვლილებები მომხმარებლის დაყენებულ პროგრამას?"

#: app/flatpak-cli-transaction.c:1537
msgid "Proceed with these changes to the system installation?"
msgstr "გადავატარო ეს ცვლილებები სისტემაში დაყენებულ პროგრამას?"

#: app/flatpak-cli-transaction.c:1539
#, c-format
msgid "Proceed with these changes to the %s?"
msgstr "გადავატარო ეს ცვლილებები %s-ს?"

#: app/flatpak-cli-transaction.c:1711
msgid "Changes complete."
msgstr "ცვლილებები დასრულებულია."

#: app/flatpak-cli-transaction.c:1713
msgid "Uninstall complete."
msgstr "წაშლა დასრულებულია."

#: app/flatpak-cli-transaction.c:1715
msgid "Installation complete."
msgstr "დაყენება დასრულებულია."

#: app/flatpak-cli-transaction.c:1717
msgid "Updates complete."
msgstr "განახლება დასრულდა."

#. For updates/!stop_on_first_error we already printed all errors so we make up
#. a different one.
#: app/flatpak-cli-transaction.c:1750
msgid "There were one or more errors"
msgstr "მოხდა ერთ ან მეტი შეცდომა"

#. translators: please keep the leading space
#: app/flatpak-main.c:76
msgid " Manage installed applications and runtimes"
msgstr " დაყენებული აპლიკაციებისა და გაშვების გარემოების მართვა"

#: app/flatpak-main.c:77
msgid "Install an application or runtime"
msgstr "აპლიკაციის ან გაშვების გარემოს დაყენება"

#: app/flatpak-main.c:78
msgid "Update an installed application or runtime"
msgstr "დაყენებული აპლიკაციის ან გაშვების გარემოს განახლება"

#: app/flatpak-main.c:81
msgid "Uninstall an installed application or runtime"
msgstr "დაყენებული აპლიკაციის ან გაშვების გარემოს წაშლა"

#: app/flatpak-main.c:84
msgid "Mask out updates and automatic installation"
msgstr "განახლებებისა და ავტომატური დაყენებების შენიღბვა"

#: app/flatpak-main.c:85
msgid "Pin a runtime to prevent automatic removal"
msgstr "გაშვების გარემოს მიმაგრება მისი წაშლის თავიდან ასაცილებლად"

#: app/flatpak-main.c:86
msgid "List installed apps and/or runtimes"
msgstr "დაყენებული აპებისა და გაშვების გარემოების ჩამოთვლა"

#: app/flatpak-main.c:87
msgid "Show info for installed app or runtime"
msgstr "დაყენებული აპის ან გაშვების გარემოს შესახებ ინფორმაციის ჩვენება"

#: app/flatpak-main.c:88
msgid "Show history"
msgstr "ისტორიის ჩვენება"

#: app/flatpak-main.c:89
msgid "Configure flatpak"
msgstr "Flatpak-ის მორგება"

#: app/flatpak-main.c:90
msgid "Repair flatpak installation"
msgstr "Flatpak -ის ფაილების შეკეთება"

#: app/flatpak-main.c:91
msgid "Put applications or runtimes onto removable media"
msgstr "აპლიკაციების ან გაშვების გარემოების მოხსნად მედიაზე მოთავსება"

#: app/flatpak-main.c:92
msgid "Install flatpaks that are part of the operating system"
msgstr ""

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:95
msgid ""
"\n"
" Find applications and runtimes"
msgstr ""
"\n"
" აპლიკაციებისა და გაშვების გარემოების მოძებნა"

#: app/flatpak-main.c:96
msgid "Search for remote apps/runtimes"
msgstr "დაშორებული აპების/გაშვების გარემოების მოძებნა"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:99
msgid ""
"\n"
" Manage running applications"
msgstr ""
"\n"
"გაშვებული აპლიკაციების მართვა"

#: app/flatpak-main.c:100
msgid "Run an application"
msgstr "აპლიკაციის გაშვება"

#: app/flatpak-main.c:101
msgid "Override permissions for an application"
msgstr "აპლიკაციისთვის წვდომების გადაფარვა"

#: app/flatpak-main.c:102
msgid "Specify default version to run"
msgstr "მიუთითეთ ნაგულისხმები გასაშვები ვერსია"

#: app/flatpak-main.c:103
msgid "Enter the namespace of a running application"
msgstr "გაშვებული აპლიკაციის სახელების სივრცეში შესვლა"

#: app/flatpak-main.c:104
msgid "Enumerate running applications"
msgstr "გაშვებული პროგრამების ჩამონათვალი"

#: app/flatpak-main.c:105
msgid "Stop a running application"
msgstr "გაშვებული პროგრამის შეჩერება"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:108
msgid ""
"\n"
" Manage file access"
msgstr ""
"\n"
" ფაილებზე წვდომების მართვა"

#: app/flatpak-main.c:109
msgid "List exported files"
msgstr "გატანილი ფაილების სია"

#: app/flatpak-main.c:110
msgid "Grant an application access to a specific file"
msgstr "აპლიკაციისთვის მითითებულ ფაილზე წვდომის მიცემა"

#: app/flatpak-main.c:111
msgid "Revoke access to a specific file"
msgstr "მითითებულ ფაილზე წვდომის აკრძალვა"

#: app/flatpak-main.c:112
msgid "Show information about a specific file"
msgstr "მითითებული ფაილის შესახებ ინფორმაციის ჩვენება"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:116
msgid ""
"\n"
" Manage dynamic permissions"
msgstr ""
"\n"
"დინამიკური წვდომების მართვა"

#: app/flatpak-main.c:117
msgid "List permissions"
msgstr "წვდომების სია"

#: app/flatpak-main.c:118
msgid "Remove item from permission store"
msgstr "წვდომების სიიდან ელემენტის წაშლა"

#: app/flatpak-main.c:120
msgid "Set permissions"
msgstr "წვდომების დაყენება"

#: app/flatpak-main.c:121
msgid "Show app permissions"
msgstr "აპის წვდომების ჩვენება"

#: app/flatpak-main.c:122
msgid "Reset app permissions"
msgstr "აპის წვდომების საწყის მნიშვნელობებზე დაყენება"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:125
msgid ""
"\n"
" Manage remote repositories"
msgstr ""
"\n"
" დაშორებული რეპოზიტორიების მართვა"

#: app/flatpak-main.c:126
msgid "List all configured remotes"
msgstr "მორგებული დაშორებულების სია"

#: app/flatpak-main.c:127
msgid "Add a new remote repository (by URL)"
msgstr "ახალი დაშორებული რეპოზიტორიის დამატება (URL-ით)"

#: app/flatpak-main.c:128
msgid "Modify properties of a configured remote"
msgstr "მორგებული დაშორებულის თვისებების შეცვლა"

#: app/flatpak-main.c:129
msgid "Delete a configured remote"
msgstr "მორგებული დაშორებულის წაშლა"

#: app/flatpak-main.c:131
msgid "List contents of a configured remote"
msgstr "მორგებული დაშორებულის შემცველობის სია"

#: app/flatpak-main.c:132
msgid "Show information about a remote app or runtime"
msgstr "დაშორებული აპის ან გაშვების გარემოს შესახებ ინფორმაციის ჩვენება"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:135
msgid ""
"\n"
" Build applications"
msgstr ""
"\n"
"\n"
" აპლიკაციების აგება"

#: app/flatpak-main.c:136
msgid "Initialize a directory for building"
msgstr "აგების საქაღალდის ინიციალიზაცია"

#: app/flatpak-main.c:137
msgid "Run a build command inside the build dir"
msgstr "აგების საქაღალდეში აგების ბრძანების გაშვება"

#: app/flatpak-main.c:138
msgid "Finish a build dir for export"
msgstr "გასატანად აგების საქაღალდის დასრულება"

#: app/flatpak-main.c:139
msgid "Export a build dir to a repository"
msgstr "აგების საქაღალდის რეპოზიტორიაში გატანა"

#: app/flatpak-main.c:140
msgid "Create a bundle file from a ref in a local repository"
msgstr "ლოკალურ რეპოზიტორიაში მიმართვიდან პაკეტის შექმნა"

#: app/flatpak-main.c:141
msgid "Import a bundle file"
msgstr "პაკეტის ფაილის შემოტანა"

#: app/flatpak-main.c:142
msgid "Sign an application or runtime"
msgstr "აპლიკაციის ან გაშვების გარემოს ხელმოწერა"

#: app/flatpak-main.c:143
msgid "Update the summary file in a repository"
msgstr "რეპოზიტორიაში შეჯამების ფაილის განახლება"

#: app/flatpak-main.c:144
msgid "Create new commit based on existing ref"
msgstr "ახალი კომიტის შექმნა არსებულ მიმართვაზე დაყრდნობით"

#: app/flatpak-main.c:145
msgid "Show information about a repo"
msgstr "რეპოზიტორიის შესახებ ინფორმაციის ჩვენება"

#: app/flatpak-main.c:162
msgid "Show debug information, -vv for more detail"
msgstr "გამართვის ინფორმაციის ჩვენება. მეტი დეტალებისთვის გამოიყენეთ -vv"

#: app/flatpak-main.c:163
msgid "Show OSTree debug information"
msgstr "OSTree-ის გამართვის ინფორმაციის ჩვენება"

#: app/flatpak-main.c:169
msgid "Print version information and exit"
msgstr "ვერსიის ჩვენება და გასვლა"

#: app/flatpak-main.c:170
msgid "Print default arch and exit"
msgstr "ნაგულისხმები არქიტექტურის გამოტანა და გასვლა"

#: app/flatpak-main.c:171
msgid "Print supported arches and exit"
msgstr "მხარდაჭერილი არქიტექტურების გამოტანა და გასვლა"

#: app/flatpak-main.c:172
msgid "Print active gl drivers and exit"
msgstr "აქტიური GL დრაივერების გამოტანა და გასვლა"

#: app/flatpak-main.c:173
msgid "Print paths for system installations and exit"
msgstr "სისტემურ პაკეტებამდე ბილიკების გამოტანა და გასვლა"

#: app/flatpak-main.c:174
msgid "Print the updated environment needed to run flatpaks"
msgstr "Flatpak-ების გასაშვებად საჭირო განახლებული გარემოს გამოტანა"

#: app/flatpak-main.c:175
msgid "Only include the system installation with --print-updated-env"
msgstr ""
"--print-updated-env-თან ერთად მხოლოდ სისტემაში დაყენებული პაკეტების გამოტანა"

#: app/flatpak-main.c:180
msgid "Work on the user installation"
msgstr "მომხმარებლის დაყენებულ პროგრამებზე მუშაობა"

#: app/flatpak-main.c:181
msgid "Work on the system-wide installation (default)"
msgstr "მთელ სისტემაში დაყენებულ პაკეტებზე მუშაობა (ნაგულისხმები)"

#: app/flatpak-main.c:182
msgid "Work on a non-default system-wide installation"
msgstr "არანაგულისხმებ მთელ-სისტემაში-დაყენებულ პაკეტებზე მუშაობა"

#: app/flatpak-main.c:212
msgid "Builtin Commands:"
msgstr "ჩაშენებული ბრძანებები:"

#: app/flatpak-main.c:298
#, c-format
msgid ""
"Note that the directories %s are not in the search path set by the "
"XDG_DATA_DIRS environment variable, so applications installed by Flatpak may "
"not appear on your desktop until the session is restarted."
msgstr ""
"დაიმახსოვრეთ, რომ საქაღალდეები %s გარემოს ცვლადის XDG_DATA_DIRS მიერ "
"დაყენებულ ძებნის ბილიკში არ შედიან, ასე რომ აპლიკაციები, რომლებსაც Flatpak-ი "
"დააყენებს, თქვენს სამუშაო მაგიდაზე მანამდე, სანამ სესიას არ გადატვირთავთ, "
"შეიძლება, არ გამოჩნდეს."

#: app/flatpak-main.c:312
#, c-format
msgid ""
"Note that the directory %s is not in the search path set by the "
"XDG_DATA_DIRS environment variable, so applications installed by Flatpak may "
"not appear on your desktop until the session is restarted."
msgstr ""
"დაიმახსოვრეთ, რომ საქაღალდეი %s გარემოს ცვლადის XDG_DATA_DIRS მიერ დაყენებულ "
"ძებნის ბილიკში არ შედის, ასე რომ აპლიკაციები, რომლებსაც Flatpak-ი დააყენებს, "
"თქვენს სამუშაო მაგიდაზე მანამდე, სანამ სესიას არ გადატვირთავთ, შეიძლება, არ "
"გამოჩნდეს."

#: app/flatpak-main.c:381
msgid ""
"Refusing to operate under sudo with --user. Omit sudo to operate on the user "
"installation, or use a root shell to operate on the root user's installation."
msgstr ""
"--user-ით sudo-ის ქვეშ ოპერირება უარყოფილია. მომხმარებლისთვის დაყენებისას "
"ამოიღეთ sudo ან root მომხმარებლის დაყენებული პაკეტების სამართავად, root "
"მომხმარებლის გარსი გამოიყენეთ."

#: app/flatpak-main.c:453
msgid ""
"Multiple installations specified for a command that works on one installation"
msgstr ""
"ბრძანებას, რომელიც მხოლოდ ერთ დაყენებულ პაკეტზე მუშაობს, ერთზე მეტი "
"დაყენებული პაკეტი გადაეცა"

#: app/flatpak-main.c:504 app/flatpak-main.c:697
#, c-format
msgid "See '%s --help'"
msgstr "იხილეთ '%s --help'"

#: app/flatpak-main.c:706
#, c-format
msgid "'%s' is not a flatpak command. Did you mean '%s%s'?"
msgstr "'%s' flatpak-ის ბრძანება არაა. '%s%s' იგულისხმეთ?"

#: app/flatpak-main.c:709
#, c-format
msgid "'%s' is not a flatpak command"
msgstr "'%s' flatpak-ის ბრძანება არაა"

#: app/flatpak-main.c:824
msgid "No command specified"
msgstr "ბრძანება მითითებული არაა"

#: app/flatpak-main.c:980
msgid "error:"
msgstr "შეცდომა:"

#: app/flatpak-quiet-transaction.c:77
#, c-format
msgid "Installing %s\n"
msgstr "%s-ის დაყენება\n"

#: app/flatpak-quiet-transaction.c:81
#, c-format
msgid "Updating %s\n"
msgstr "%s-ის განახლება\n"

#: app/flatpak-quiet-transaction.c:85
#, c-format
msgid "Uninstalling %s\n"
msgstr "%s-ის წაშლა\n"

#: app/flatpak-quiet-transaction.c:107
#, c-format
msgid "Warning: Failed to install %s: %s\n"
msgstr ""
"გაფრთხილება: %s-ის დაყენება ჩავარდა: %s\n"
"\n"

#: app/flatpak-quiet-transaction.c:110
#, c-format
msgid "Error: Failed to install %s: %s\n"
msgstr ""
"შეცდომა: %s-ის დაყენება ჩავარდა: %s\n"
"\n"

#: app/flatpak-quiet-transaction.c:116
#, c-format
msgid "Warning: Failed to update %s: %s\n"
msgstr "გაფრთხილება: %s-ის განახლების შეცდომა: %s\n"

#: app/flatpak-quiet-transaction.c:119
#, c-format
msgid "Error: Failed to update %s: %s\n"
msgstr "შეცდომა: %s-ის განახლების შეცდომა: %s\n"

#: app/flatpak-quiet-transaction.c:125
#, c-format
msgid "Warning: Failed to install bundle %s: %s\n"
msgstr "გაფრთხილება: პაკეტის %s დაყენება ჩავარდა: %s\n"

#: app/flatpak-quiet-transaction.c:128
#, c-format
msgid "Error: Failed to install bundle %s: %s\n"
msgstr ""
"შეცდომა: პაკეტის %s დაყენება ჩავარდა: %s\n"
"\n"

#: app/flatpak-quiet-transaction.c:134
#, c-format
msgid "Warning: Failed to uninstall %s: %s\n"
msgstr "გაფრთხილება: %s-ის წაშლა ჩავარდა: %s\n"

#: app/flatpak-quiet-transaction.c:137
#, c-format
msgid "Error: Failed to uninstall %s: %s\n"
msgstr ""
"შეცდომა: %s-ის წაშლა ჩავარდა: %s\n"
"\n"

#: app/flatpak-quiet-transaction.c:166 common/flatpak-dir.c:11475
#, c-format
msgid "%s already installed"
msgstr "%s უკვე დაყენებულია"

#: app/flatpak-quiet-transaction.c:168 common/flatpak-dir.c:3622
#: common/flatpak-dir.c:4321 common/flatpak-dir.c:16968
#: common/flatpak-dir.c:17258 common/flatpak-dir-utils.c:166
#: common/flatpak-dir-utils.c:259 common/flatpak-transaction.c:2736
#: common/flatpak-transaction.c:2791
#, c-format
msgid "%s not installed"
msgstr "%s დაყენებული არაა"

#: app/flatpak-quiet-transaction.c:170
#, c-format
msgid "%s needs a later flatpak version"
msgstr "%s-ს flatpak-ის უფრო ახალი ვერსია სჭირდება"

#: app/flatpak-quiet-transaction.c:172
msgid "Not enough disk space to complete this operation"
msgstr "ოპერაციის დასასრულებლად დისკზე საკმარისი ადგილი არაა"

#: app/flatpak-quiet-transaction.c:239
#, c-format
msgid "Info: %s is end-of-life, in favor of %s\n"
msgstr "ინფორმაცია %s-ის მხარდაჭერა ამოწურულია. გამოიყენეთ %s\n"

#: app/flatpak-quiet-transaction.c:241
#, c-format
msgid "Info: %s is end-of-life, with reason: %s\n"
msgstr "ინფორმაცია %s-ის მხარდაჭერა ამოწურულია. მიზეზი: %s\n"

#: app/flatpak-quiet-transaction.c:251
#, c-format
msgid "Failed to rebase %s to %s: %s\n"
msgstr "%s-ის %s-ზე რებაზირების შეცდომა: %s\n"

#: common/flatpak-auth.c:58
#, c-format
msgid "No authenticator configured for remote `%s`"
msgstr "დაშორებულისთვის '%s' ავთენტიკატორი მორგებული არაა"

#: common/flatpak-context.c:637 common/flatpak-context.c:649
#, fuzzy, c-format
msgid "Invalid permission syntax: %s"
msgstr "გაფართოების არასწორი სახელი: %s"

#: common/flatpak-context.c:1207
#, c-format
msgid "Unknown share type %s, valid types are: %s"
msgstr "გაზიარებულის უცნობი ტიპი %s. სწორი ტიპებია %s"

#: common/flatpak-context.c:1228
#, c-format
msgid "Unknown policy type %s, valid types are: %s"
msgstr "პოლიტიკის უცნობი ტიპი %s. სწორი ტიპებია %s"

#: common/flatpak-context.c:1266
#, c-format
msgid "Invalid dbus name %s"
msgstr "არასწორი dbus სახელი %s"

#: common/flatpak-context.c:1279
#, c-format
msgid "Unknown socket type %s, valid types are: %s"
msgstr "სოკეტის უცნობი ტიპი %s. სწორი ტიპებია %s"

#: common/flatpak-context.c:1294
#, c-format
msgid "Unknown device type %s, valid types are: %s"
msgstr "მოწყობილობის უცნობი ტიპი %s. სწორი ტიპებია %s"

#: common/flatpak-context.c:1308
#, c-format
msgid "Unknown feature type %s, valid types are: %s"
msgstr "თვისების უცნობი ტიპი %s. სწორი ტიპებია %s"

#: common/flatpak-context.c:1840
#, c-format
msgid "Filesystem location \"%s\" contains \"..\""
msgstr "ფაილური სისტემის ბილიკი \"%s\" \"..\"-ს შეიცავს"

#: common/flatpak-context.c:1882
#, c-format
msgid ""
"--filesystem=/ is not available, use --filesystem=host for a similar result"
msgstr ""
"--filesystem=/ ხელმისაწვდომი არაა. მსგავსი შედეგისთვის გამოიყენეთ --"
"filesystem=host"

#: common/flatpak-context.c:1916
#, fuzzy, c-format
msgid ""
"Unknown filesystem location %s, valid locations are: host, host-os, host-"
"etc, host-root, home, xdg-*[/…], ~/dir, /dir"
msgstr ""
"ფაილური სისტემის უცნობი მდებარეობა %s, სწორი მდებარეობებია: host, host-os, "
"host-etc, home, xdg-*[/…], ~/dir, /dir"

#: common/flatpak-context.c:2015
#, fuzzy, c-format
msgid "Invalid syntax for %s: %s"
msgstr "არასწორი სახელი %s: %s"

#: common/flatpak-context.c:2142
#, c-format
msgid "fallback-x11 can not be conditional"
msgstr ""

#: common/flatpak-context.c:2318
#, c-format
msgid "Invalid env format %s"
msgstr "არასწორი გარემოს ფორმატი %s"

#: common/flatpak-context.c:2399
#, c-format
msgid "Environment variable name must not contain '=': %s"
msgstr "გარემოს ცვლადის სახელი \"=\" -ს არ შეიძლება შეიცავდეს: %s"

#: common/flatpak-context.c:2527 common/flatpak-context.c:2535
#, c-format
msgid "--add-policy arguments must be in the form SUBSYSTEM.KEY=VALUE"
msgstr ""
"--add-policy პარამეტრის არგუმენტები ქვესისტემა.პარამეტრი=მნიშვნელობა "
"ფორმატში უნდა იყოს"

#: common/flatpak-context.c:2542
#, c-format
msgid "--add-policy values can't start with \"!\""
msgstr "--add-policy-ის მნიშვნელობები \"!\"-ით არ შეიძლება, იწყებოდეს"

#: common/flatpak-context.c:2567 common/flatpak-context.c:2575
#, c-format
msgid "--remove-policy arguments must be in the form SUBSYSTEM.KEY=VALUE"
msgstr ""
"--remove-policy-ის არგუმენტები ქვესისტემა.პარამეტრი=მნიშვნელობა ფორმატში "
"უნდა იყოს"

#: common/flatpak-context.c:2582
#, c-format
msgid "--remove-policy values can't start with \"!\""
msgstr "--remove-policy-ის მნიშვნელობები \"!\"-ით არ შეიძლება, იწყებოდეს"

#: common/flatpak-context.c:2657
msgid "Share with host"
msgstr "ჰოსტთან გაზიარება"

#: common/flatpak-context.c:2657 common/flatpak-context.c:2658
msgid "SHARE"
msgstr "გაზიარება"

#: common/flatpak-context.c:2658
msgid "Unshare with host"
msgstr "ჰოსტთან გაზიარების მოხსნა"

#: common/flatpak-context.c:2659
msgid "Require conditions to be met for a subsystem to get shared"
msgstr ""

#: common/flatpak-context.c:2659
msgid "SHARE:CONDITION"
msgstr ""

#: common/flatpak-context.c:2660
msgid "Expose socket to app"
msgstr "სოკეტის გამოჩენა აპისთვის"

#: common/flatpak-context.c:2660 common/flatpak-context.c:2661
msgid "SOCKET"
msgstr "სოკეტი"

#: common/flatpak-context.c:2661
msgid "Don't expose socket to app"
msgstr "აპი სოკეტს  ვერ დაინახავს"

#: common/flatpak-context.c:2662
msgid "Require conditions to be met for a socket to get exposed"
msgstr ""

#: common/flatpak-context.c:2662
msgid "SOCKET:CONDITION"
msgstr ""

#: common/flatpak-context.c:2663
msgid "Expose device to app"
msgstr "მოწყობილობის გამოჩენა აპისთვის"

#: common/flatpak-context.c:2663 common/flatpak-context.c:2664
msgid "DEVICE"
msgstr "მოწყობილობა"

#: common/flatpak-context.c:2664
msgid "Don't expose device to app"
msgstr "აპი მოწყობილობას ვერ დაინახავს"

#: common/flatpak-context.c:2665
msgid "Require conditions to be met for a device to get exposed"
msgstr ""

#: common/flatpak-context.c:2665
msgid "DEVICE:CONDITION"
msgstr ""

#: common/flatpak-context.c:2666
msgid "Allow feature"
msgstr "ფუნქციის დაშვება"

#: common/flatpak-context.c:2666 common/flatpak-context.c:2667
msgid "FEATURE"
msgstr "თვისება"

#: common/flatpak-context.c:2667
msgid "Don't allow feature"
msgstr "ფუნქციის არ-დაშვება"

#: common/flatpak-context.c:2668
msgid "Require conditions to be met for a feature to get allowed"
msgstr ""

#: common/flatpak-context.c:2668
msgid "FEATURE:CONDITION"
msgstr ""

#: common/flatpak-context.c:2669
msgid "Expose filesystem to app (:ro for read-only)"
msgstr "აპისთვის ფაილური სისტემის დანახება (მხოლოდ-კითხვისთვის :ro)"

#: common/flatpak-context.c:2669
msgid "FILESYSTEM[:ro]"
msgstr "FILESYSTEM[:ro]"

#: common/flatpak-context.c:2670
msgid "Don't expose filesystem to app"
msgstr "აპი ფაილურ სისტემას ვერ დაინახავს"

#: common/flatpak-context.c:2670
msgid "FILESYSTEM"
msgstr "FILESYSTEM"

#: common/flatpak-context.c:2671
msgid "Set environment variable"
msgstr "გარემოს ცვლადის დაყენება"

#: common/flatpak-context.c:2671
msgid "VAR=VALUE"
msgstr "VAR=VALUE"

#: common/flatpak-context.c:2672
msgid "Read environment variables in env -0 format from FD"
msgstr "გარემოს ცვლადების წაკითხვა გარემოში -0 ფორმატით FD-დან"

#: common/flatpak-context.c:2673
msgid "Remove variable from environment"
msgstr "გარემოდან ცვლადის წაშლა"

#: common/flatpak-context.c:2673
msgid "VAR"
msgstr "VAR"

#: common/flatpak-context.c:2674
msgid "Allow app to own name on the session bus"
msgstr "აპისთვის სესიის მატარებელზე საკუთარი სახელის ქონის ნების დართვა"

#: common/flatpak-context.c:2674 common/flatpak-context.c:2675
#: common/flatpak-context.c:2676 common/flatpak-context.c:2677
#: common/flatpak-context.c:2678 common/flatpak-context.c:2679
#: common/flatpak-context.c:2680
msgid "DBUS_NAME"
msgstr "DBUS_NAME"

#: common/flatpak-context.c:2675
msgid "Allow app to talk to name on the session bus"
msgstr "აპისთვის სესიის მატარებელზე სახელთან ლაპარაკის ნების დართვა"

#: common/flatpak-context.c:2676
msgid "Don't allow app to talk to name on the session bus"
msgstr "აპისთვის სესიის მატარებელზე სახელთან ლაპარაკის აკრძალვა"

#: common/flatpak-context.c:2677
msgid "Allow app to own name on the system bus"
msgstr "აპისთვის სისტემურ მატარებელზე საკუთარი სახელის ქონის ნების დართვა"

#: common/flatpak-context.c:2678
msgid "Allow app to talk to name on the system bus"
msgstr "აპისთვის სესიის მატარებელზე სახელთან ლაპარაკის ნების დართვა"

#: common/flatpak-context.c:2679
msgid "Don't allow app to talk to name on the system bus"
msgstr "აპისთვის სისტემურ მატარებელზე სახელთან ლაპარაკის აკრძალვა"

#: common/flatpak-context.c:2680
msgid "Allow app to own name on the a11y bus"
msgstr "აპისთვის a11y მატარებელზე საკუთარი სახელის ქონის ნების დართვა"

#: common/flatpak-context.c:2681
msgid "Add generic policy option"
msgstr "ზოგადი პოლიტიკის პარამეტრის დამატება"

#: common/flatpak-context.c:2681 common/flatpak-context.c:2682
msgid "SUBSYSTEM.KEY=VALUE"
msgstr "ქვესისტემა.პარამეტრი=მნიშვნელობა"

#: common/flatpak-context.c:2682
msgid "Remove generic policy option"
msgstr "ზოგადი პოლიტიკის პარამეტრის წაშლა"

#: common/flatpak-context.c:2683
msgid "Add USB device to enumerables"
msgstr "USB მოწყობილობის დამატება ჩამოთვლადებსი"

#: common/flatpak-context.c:2683 common/flatpak-context.c:2684
msgid "VENDOR_ID:PRODUCT_ID"
msgstr "VENDOR_ID:PRODUCT_ID"

#: common/flatpak-context.c:2684
msgid "Add USB device to hidden list"
msgstr "USB მოწყობილობის დამატება დამალულების სიაში"

#: common/flatpak-context.c:2685
msgid "A list of USB devices that are enumerable"
msgstr "USB მოწყობილობების სია, რომლებიც ჩამოთვლადია"

#: common/flatpak-context.c:2685
msgid "LIST"
msgstr "სია"

#: common/flatpak-context.c:2686
msgid "File containing a list of USB devices to make enumerable"
msgstr ""
"ფაილი, რომელიც შეიცავს USB მოწყობილობების სიას ჩამოთვლადების შესაქმნელად"

#: common/flatpak-context.c:2686 common/flatpak-context.c:2687
msgid "FILENAME"
msgstr "ფაილის სახელი"

#: common/flatpak-context.c:2687
msgid "Persist home directory subpath"
msgstr "მუდმივი ბილიკი საწყის საქაღალდემდე"

#. This is not needed/used anymore, so hidden, but we accept it for backwards compat
#: common/flatpak-context.c:2689
msgid "Don't require a running session (no cgroups creation)"
msgstr "გაშვებული სესია მოთხოვნილი არ იქნება (cgroup-ები არ შეიქმნება)"

#: common/flatpak-context.c:3718
#, c-format
msgid "Not replacing \"%s\" with tmpfs: %s"
msgstr "\"%s\" tmpfs-ით არ ჩანაცვლდება: %s"

#: common/flatpak-context.c:3726
#, c-format
msgid "Not sharing \"%s\" with sandbox: %s"
msgstr "\"%s\" სენდბოქსთან არ გაზიარდება: %s"

#. Even if the error is one that we would normally silence, like
#. * the path not existing, it seems reasonable to make more of a fuss
#. * about the home directory not existing or otherwise being unusable,
#. * so this is intentionally not using cannot_export()
#: common/flatpak-context.c:3828
#, c-format
msgid "Not allowing home directory access: %s"
msgstr "საწყის საქაღალდესთან წვდომა მინიჭებული არ იქნება: %s"

#: common/flatpak-context.c:4062
#, c-format
msgid "Unable to provide a temporary home directory in the sandbox: %s"
msgstr "დროებითი საწყისი საქაღალდის მიწოდება შეუძლებელია სენდბოქსში: %s"

#: common/flatpak-dir.c:442
#, c-format
msgid "Configured collection ID ‘%s’ not in summary file"
msgstr "მორგებული კოლექციის ID '%s' შეჯამების ფაილი არაა"

#: common/flatpak-dir.c:587
#, c-format
msgid "Unable to load summary from remote %s: %s"
msgstr "დაშორებულიდან '%s' შეჯამების ჩატვირთვა შეუძლებელია: %s"

#: common/flatpak-dir.c:764 common/flatpak-dir.c:800 common/flatpak-dir.c:906
#, c-format
msgid "No such ref '%s' in remote %s"
msgstr "მიმართვა '%s' დაშორებულში %s არ არსებობს"

#: common/flatpak-dir.c:891 common/flatpak-dir.c:1051 common/flatpak-dir.c:1080
#: common/flatpak-dir.c:1092
#, c-format
msgid "No entry for %s in remote %s summary flatpak cache"
msgstr "ჩანაწერი %s არ არსებობს დაშორებულში '%s' შეჯამების flatpak კეშში"

#: common/flatpak-dir.c:1069
#, c-format
msgid "No summary or Flatpak cache available for remote %s"
msgstr "დაშორებულისთვის %s შეჯამება ან Flatpak-ის კეში მიუწვდომელია"

#: common/flatpak-dir.c:1097
#, c-format
msgid "Missing xa.data in summary for remote %s"
msgstr "დაშორებულისთვის %s შეჯამებაში xa.data აღმოჩენილი არაა"

#: common/flatpak-dir.c:1103 common/flatpak-dir.c:1546
#, c-format
msgid "Unsupported summary version %d for remote %s"
msgstr "მხარდაუჭერელი შეჯამების ვერსია %d დაშორებულისთვის %s"

#: common/flatpak-dir.c:1200
msgid "Remote OCI index has no registry uri"
msgstr "დაშორებულ OCI ინდექსს რეესტრის URI არ გააჩნია"

#: common/flatpak-dir.c:1261
#, c-format
msgid "Couldn't find ref %s in remote %s"
msgstr "მიმართვა %s დაშორებულში %s აღმოჩენილი არაა"

#: common/flatpak-dir.c:1288 common/flatpak-dir.c:1381
#, fuzzy, c-format
msgid "Commit has no requested ref ‘%s’ in ref binding metadata (found: ‘%s’)"
msgstr ""
"კომიტს მიმართვის მიბმის მეტამონაცემებში მოთხოვნილი მიმართვა '%s' არ გააჩნია"

#: common/flatpak-dir.c:1413
#, c-format
msgid "Configured collection ID ‘%s’ not in binding metadata"
msgstr "მიმაგრების მეტამონაცემებში მორგებული კოლექციის ID '%s' არაა"

#: common/flatpak-dir.c:1449 common/flatpak-dir.c:5645
#, c-format
msgid "Couldn't find latest checksum for ref %s in remote %s"
msgstr "მიმართვისთვის %s დაშორებულში %s უახლესი საკონტროლო ჯამი ვერ ვიპოვე"

#: common/flatpak-dir.c:1516 common/flatpak-dir.c:1552
#, c-format
msgid "No entry for %s in remote %s summary flatpak sparse cache"
msgstr ""
"%s-სთვის ჩანაწერი დაშორებული %s-ის შეჯამების flatpak-ის იშვიათ კეშში არ "
"არსებობს"

#: common/flatpak-dir.c:2540
#, c-format
msgid "Commit metadata for %s not matching expected metadata"
msgstr "კომიტის მეტამონაცემები %s-სთვის მოსალოდნელ მეტამონაცემებს არ ემთხვევა"

#: common/flatpak-dir.c:2823
msgid "Unable to connect to system bus"
msgstr "სისტემურ მატარებელთან მიერთება შეუძლებელია"

#: common/flatpak-dir.c:3419
msgid "User installation"
msgstr "მომხმარებლისთვის დაყენება"

#: common/flatpak-dir.c:3426
#, c-format
msgid "System (%s) installation"
msgstr "სისტემაში (%s) დაყენება"

#: common/flatpak-dir.c:3472
#, c-format
msgid "No overrides found for %s"
msgstr "%s-სთვის გადაფარვები ვერ ვიპოვე"

#: common/flatpak-dir.c:3625
#, c-format
msgid "%s (commit %s) not installed"
msgstr "%s (კომიტი %s) დაყენებული არაა"

#: common/flatpak-dir.c:4650
#, c-format
msgid "Error parsing system flatpakrepo file for %s: %s"
msgstr "%s-სთვის სისტემური flatpakrepo ფაილის დამუშავების შეცდომა: %s"

#: common/flatpak-dir.c:4735
#, c-format
msgid "While opening repository %s: "
msgstr "რეპოზიტორიის (%s) გახსნისას: "

#: common/flatpak-dir.c:5004
#, c-format
msgid "The config key %s is not set"
msgstr "კონფიგურაციის პარამეტრი %s დაყენებული არაა"

#: common/flatpak-dir.c:5140
#, c-format
msgid "No current %s pattern matching %s"
msgstr "მიმდინარე %s ნიმუში, რომელიც %s-ს ემთხვევა, აღმოჩენილი არაა"

#: common/flatpak-dir.c:5422
msgid "No appstream commit to deploy"
msgstr "გასალაგებელი appstream-ის კომიტის გარეშე"

#: common/flatpak-dir.c:5941 common/flatpak-dir.c:7266
#: common/flatpak-dir.c:10881 common/flatpak-dir.c:11618
msgid "Can't pull from untrusted non-gpg verified remote"
msgstr "არა-gpg-ით გადამოწმებული დაშორებულიდან პული შეუძლებელია"

#: common/flatpak-dir.c:6376 common/flatpak-dir.c:6591
msgid "Extra data not supported for non-gpg-verified local system installs"
msgstr ""
"არა-GPG-ით-გადამოწმებული ლოკალური სისტემური დაყენებებისთვის დამატებითი "
"მონაცემები მხარდაჭერილი არაა"

#: common/flatpak-dir.c:6415 common/flatpak-dir.c:6782
#, c-format
msgid "Invalid checksum for extra data uri %s"
msgstr "არასწორი საონტროლო ჯამი დამატებითი მონაცემები URI-სთვის %s"

#: common/flatpak-dir.c:6424
#, c-format
msgid "Empty name for extra data uri %s"
msgstr "ცარიელი სახელი დამატებითი მონაცემების URI-სთვის %s"

#: common/flatpak-dir.c:6432
#, c-format
msgid "Unsupported extra data uri %s"
msgstr "მხარდაუჭერელი დამატებითი მონაცემების URI %s"

#: common/flatpak-dir.c:6461
#, c-format
msgid "Failed to load local extra-data %s: %s"
msgstr "ლოკალური დამატებითი მონაცემის %s ჩატვირთვის შეცდომა: %s"

#: common/flatpak-dir.c:6469
#, c-format
msgid "Wrong size for extra-data %s"
msgstr "არასწორი ზომა დამატებითი-მონაცემებისთვის %s"

#: common/flatpak-dir.c:6488
#, c-format
msgid "While downloading %s: "
msgstr "%s-ის გადმოწერისას: "

#: common/flatpak-dir.c:6498
#, c-format
msgid "Wrong size for extra data %s"
msgstr "დამატებითი მონაცემების (%s) არასწორი ზომა"

#: common/flatpak-dir.c:6507
#, c-format
msgid "Invalid checksum for extra data %s"
msgstr "დამატებითი მონაცემების (%s) არასწორი საკონტროლო ჯამი"

#: common/flatpak-dir.c:7096 common/flatpak-dir.c:7349
#, c-format
msgid "While pulling %s from remote %s: "
msgstr "%s-ის პულისას დაშორებულიდან %s: "

#: common/flatpak-dir.c:7290 common/flatpak-repo-utils.c:3886
msgid "GPG signatures found, but none are in trusted keyring"
msgstr "აღმოჩენილია GPG ხელმოწერები, მაგრამ სანდო ბრელოკში არც ერთი არაა"

#: common/flatpak-dir.c:7307
#, c-format
msgid "Commit for ‘%s’ has no ref binding"
msgstr "კომიტს '%s'-სთვის მიმართვის მიმაგრება არ გააჩნია"

#: common/flatpak-dir.c:7312
#, c-format
msgid "Commit for ‘%s’ is not in expected bound refs: %s"
msgstr "'%s'-ის კომიტი მოსალოდნელ მიბმულ მიმართვებში არაა: %s"

#: common/flatpak-dir.c:7488
msgid "Only applications can be made current"
msgstr "მიმდინარედ მხოლოდ აპლიკაციების დაყენება შეგიძლიათ"

#: common/flatpak-dir.c:8192
msgid "Not enough memory"
msgstr "მეხსიერება საკმარისი არ არის"

#: common/flatpak-dir.c:8211
msgid "Failed to read from exported file"
msgstr "გატანილი ფაილიდან წაკითხვის შეცდომა"

#: common/flatpak-dir.c:8401
msgid "Error reading mimetype xml file"
msgstr "MIMtype XML ფაილის წაკითხვის შეცდომა"

#: common/flatpak-dir.c:8406
msgid "Invalid mimetype xml file"
msgstr "არასწორი mimetype xml ფაილი"

#: common/flatpak-dir.c:8492
#, c-format
msgid "D-Bus service file '%s' has wrong name"
msgstr "D-Bus-ის სერვისის ფაილის სახელი '%s' არასწორია"

#: common/flatpak-dir.c:8647
#, c-format
msgid "Invalid Exec argument %s"
msgstr "არასწორი გაშვების არგუმენტი %s"

#: common/flatpak-dir.c:9115
msgid "While getting detached metadata: "
msgstr "მოხსნილი მეტამონაცემების მიღებისას: "

#: common/flatpak-dir.c:9120 common/flatpak-dir.c:9125
#: common/flatpak-dir.c:9129
msgid "Extra data missing in detached metadata"
msgstr "მოხსნილ მეტამონაცემებში დამატებთი მონაცემები აღმოჩენილი არაა"

#: common/flatpak-dir.c:9133
msgid "While creating extradir: "
msgstr "დამატებითი საქაღალდის შექმნისას: "

#: common/flatpak-dir.c:9154 common/flatpak-dir.c:9187
msgid "Invalid checksum for extra data"
msgstr "დამატებითი მონაცემების არასწორი საკონტროლო ჯამი"

#: common/flatpak-dir.c:9183
msgid "Wrong size for extra data"
msgstr "დამატებითი მონაცემების არასწორი ზომა"

#: common/flatpak-dir.c:9196
#, c-format
msgid "While writing extra data file '%s': "
msgstr "დამატებითი მონაცემების ფაილის '%s' ჩაწერისას: "

#: common/flatpak-dir.c:9204
#, c-format
msgid "Extra data %s missing in detached metadata"
msgstr "მოხსნილ მეტამონაცემებში დამატებითი მონაცემი %s აღმოჩენილი არაა"

#: common/flatpak-dir.c:9278
#, fuzzy, c-format
msgid "Unable to get runtime key from metadata"
msgstr "მეტამონაცემების სხვა ფაილის გამოყენება"

#: common/flatpak-dir.c:9402
#, c-format
msgid "apply_extra script failed, exit status %d"
msgstr "apply_extra სკრიპტის შეცდომა. გამოსვლს სტატუსია %d"

#. Translators: The placeholder is for an app ref.
#: common/flatpak-dir.c:9591
#, c-format
msgid "Installing %s is not allowed by the policy set by your administrator"
msgstr "%s-ის დაყენება აკრძალულია თქვენი ადმინისტრატორის წესების მიერ"

#: common/flatpak-dir.c:9690
#, c-format
msgid "While trying to resolve ref %s: "
msgstr "მიმართვის %s ამოხსნის მცდელობისას: "

#: common/flatpak-dir.c:9702
#, c-format
msgid "%s is not available"
msgstr "%s ხელმიუწვდომელია"

#: common/flatpak-dir.c:9714 common/flatpak-dir.c:11495
#, c-format
msgid "%s commit %s already installed"
msgstr "%s (კომიტი %s) უკვე დაყენებულია"

#: common/flatpak-dir.c:9721
msgid "Can't create deploy directory"
msgstr "გაშლის საქაღალდის შექმნის შეცდომა"

#: common/flatpak-dir.c:9729
#, c-format
msgid "Failed to read commit %s: "
msgstr "კომიტის '%s' წაკითხვის შეცდომა: "

#: common/flatpak-dir.c:9750
#, c-format
msgid "While trying to checkout %s into %s: "
msgstr "%s-ის %s-ში გამოთხოვისას: "

#: common/flatpak-dir.c:9769
msgid "While trying to checkout metadata subpath: "
msgstr "მეტამონაცემების ქვებილიკში გამოთხოვისას: "

#: common/flatpak-dir.c:9801
#, c-format
msgid "While trying to checkout subpath ‘%s’: "
msgstr "ქვებილიკის '%s' გამოთხოვისას: "

#: common/flatpak-dir.c:9811
msgid "While trying to remove existing extra dir: "
msgstr "არსებული დამატებითი საქაღალდის წაშლის მცდელობისას: "

#: common/flatpak-dir.c:9822
msgid "While trying to apply extra data: "
msgstr "დამატებითი მონაცემების გადატარების მცდელობისას: "

#: common/flatpak-dir.c:9849
#, c-format
msgid "Invalid commit ref %s: "
msgstr "არასწორი კომიტის მიმართვა %s: "

#: common/flatpak-dir.c:9857 common/flatpak-dir.c:9869
#, c-format
msgid "Deployed ref %s does not match commit (%s)"
msgstr "გაშლილი მიმართვა %s კომიტს (%s) არ ემთხვევა"

#: common/flatpak-dir.c:9863
#, c-format
msgid "Deployed ref %s branch does not match commit (%s)"
msgstr "გაშლილი მიმართვა %s ბრენჩი კომიტს (%s) არ ემთხვევა"

#: common/flatpak-dir.c:10125 common/flatpak-installation.c:1911
#, c-format
msgid "%s branch %s already installed"
msgstr "%s ბრენჩი %s უკვე დაყენებულია"

#: common/flatpak-dir.c:10985
#, c-format
msgid "Could not unmount revokefs-fuse filesystem at %s: "
msgstr "შეცდომა revokefs-fuse ფაილური სისტემის მოხსნისას მისამართზე %s: "

#: common/flatpak-dir.c:11289
#, c-format
msgid "This version of %s is already installed"
msgstr "%s-ის ეს ვერსია უკვე დაყენებულია"

#: common/flatpak-dir.c:11302
#, c-format
msgid "Can't change remote during bundle install"
msgstr "პაკეტის დაყენებისას დაშორებულის შეცვლა შეუძლებელია"

#: common/flatpak-dir.c:11571
msgid "Can't update to a specific commit without root permissions"
msgstr "მითითებული კომიტის განახლება root-ის წვდომების გარეშე შეუძლებელია"

#: common/flatpak-dir.c:11852
#, c-format
msgid "Can't remove %s, it is needed for: %s"
msgstr "%s-ის წაშლა შეუძლებელია. ის %s-ს სჭირდება"

#: common/flatpak-dir.c:11912 common/flatpak-installation.c:2067
#, c-format
msgid "%s branch %s is not installed"
msgstr "%s ბრენჩი %s დაყენებული არაა"

#: common/flatpak-dir.c:12165
#, c-format
msgid "%s commit %s not installed"
msgstr "%s კომიტი %s დაყენებული არაა"

#: common/flatpak-dir.c:12501
#, c-format
msgid "Pruning repo failed: %s"
msgstr "რეპოზიტორიის წაკვეთის შეცდომა: %s"

#: common/flatpak-dir.c:12669 common/flatpak-dir.c:12675
#, c-format
msgid "Failed to load filter '%s'"
msgstr "შეცდომა ფილტრის '%s' ჩატვირთვისას"

#: common/flatpak-dir.c:12681
#, c-format
msgid "Failed to parse filter '%s'"
msgstr "შეცდომა ფილტრის '%s' დამუშავებისას"

#: common/flatpak-dir.c:12963
msgid "Failed to write summary cache: "
msgstr "შეჯამების კეშის ჩაწერის შეცდომა: "

#: common/flatpak-dir.c:12982
#, c-format
msgid "No oci summary cached for remote '%s'"
msgstr "OCI შეჯამება დაშორებულისთვის '%s' დაკეშილი არაა"

#: common/flatpak-dir.c:13207
#, c-format
msgid "No cached summary for remote '%s'"
msgstr "დაკეშილი შეჯამება დაშორებულისთვის '%s' ვერ ვიპოვე"

#: common/flatpak-dir.c:13248
#, c-format
msgid "Invalid checksum for indexed summary %s read from %s"
msgstr ""
"არასწორი საკონტროლო ჯამი დაინდექსებული შეჯამებისთვის %s. წაკითხულია %s-დან"

#: common/flatpak-dir.c:13321
#, c-format
msgid ""
"Remote listing for %s not available; server has no summary file. Check the "
"URL passed to remote-add was valid."
msgstr ""
"%s-სთვის დაშორებული ჩამონათვალი ხელმისაწვდომი არაა, რადგან სერვერს შეჯამების "
"ფაილი არ გააჩნია. გადაამოწმეთ remote-add-ისთვის გადაცემული URL-ის სისწორე."

#: common/flatpak-dir.c:13698
#, c-format
msgid "Invalid checksum for indexed summary %s for remote '%s'"
msgstr ""
"არასწორი საკონტროლო ჯამი დაინდექსებული შეჯამებისთვის %s დაშორებულისთვის '%s'"

#: common/flatpak-dir.c:14388
#, c-format
msgid "Multiple branches available for %s, you must specify one of: "
msgstr ""
"%s-სთვის ხელმისაწვდომია ერთზე მეტი ბრენჩი. ანუ, უნდა მიუთითოთ ერთ-ერთი "
"სიიდან: "

#: common/flatpak-dir.c:14454
#, c-format
msgid "Nothing matches %s"
msgstr "%s-ს არაფერი ემთხვევა"

#: common/flatpak-dir.c:14562
#, c-format
msgid "Can't find ref %s%s%s%s%s"
msgstr "ვერ ვიპოვე მიმართვა %s%s%s%s%s"

#: common/flatpak-dir.c:14605
#, c-format
msgid "Error searching remote %s: %s"
msgstr "დაშორებული %s-ის მოძებნის შეცდომა: %s"

#: common/flatpak-dir.c:14702
#, c-format
msgid "Error searching local repository: %s"
msgstr "ლოკალურ რეპოზიტორიაშ ძებნის შეცდომა: %s"

#: common/flatpak-dir.c:14839
#, c-format
msgid "%s/%s/%s not installed"
msgstr "%s/%s/%s დაყენებული არაა"

#: common/flatpak-dir.c:15042
#, c-format
msgid "Could not find installation %s"
msgstr "%s-ის დაყენებულებში მოძებნის შეცდომა"

#: common/flatpak-dir.c:15612
#, c-format
msgid "Invalid file format, no %s group"
msgstr "არასწორი ფაილის ფორმატი. %s ჯგუფის გარეშე"

#: common/flatpak-dir.c:15617 common/flatpak-repo-utils.c:2836
#, c-format
msgid "Invalid version %s, only 1 supported"
msgstr "არასწორი ვერსია %s. მხარდაჭერილია მხოლოდ 1"

#: common/flatpak-dir.c:15622 common/flatpak-dir.c:15627
#, c-format
msgid "Invalid file format, no %s specified"
msgstr "არასწორი ფაილის ფორმატი. %s მითითებული არაა"

#. Check some minimal size so we don't get crap
#: common/flatpak-dir.c:15647
msgid "Invalid file format, gpg key invalid"
msgstr "არასწორი ფაილის ფორმატი.  GPG გასაღები არასწორია"

#: common/flatpak-dir.c:15675 common/flatpak-repo-utils.c:2917
msgid "Collection ID requires GPG key to be provided"
msgstr "კოლექციის ID-სთვის GPG გასაღების მითითება აუცილებელია"

#: common/flatpak-dir.c:15718
#, c-format
msgid "Runtime %s, branch %s is already installed"
msgstr "გაშვების გარემო %s, ბრენჩი %s უკვე დაყენებულია"

#: common/flatpak-dir.c:15719
#, c-format
msgid "App %s, branch %s is already installed"
msgstr "აპი %s, ბრენჩი %s უკვე დაყენებულია"

#: common/flatpak-dir.c:15953
#, c-format
msgid "Can't remove remote '%s' with installed ref %s (at least)"
msgstr "დაშორებულის '%s' წაშლა დაყენებული მიმართვის (სულ ცოტა) %s"

#: common/flatpak-dir.c:16058
#, c-format
msgid "Invalid character '/' in remote name: %s"
msgstr "არასწორი სიმბოლო '/' დაშორებულის სახელში: %s"

#: common/flatpak-dir.c:16064
#, c-format
msgid "No configuration for remote %s specified"
msgstr "დაშორებულისთვის %s კონფიგურაცია მითითებული არაა"

#: common/flatpak-dir.c:17597
#, c-format
msgid "Skipping deletion of mirror ref (%s, %s)…\n"
msgstr "ასლის მიმართვის (%s, %s) წაშლის გამოტოვება...\n"

#: common/flatpak-exports.c:931
#, c-format
msgid "An absolute path is required"
msgstr "აუცილებელია აბსოლუტური ბილიკი"

#: common/flatpak-exports.c:948
#, c-format
msgid "Unable to open path \"%s\": %s"
msgstr "ვერ გავხსენი ბილიკი \"%s\": %s"

#: common/flatpak-exports.c:955
#, c-format
msgid "Unable to get file type of \"%s\": %s"
msgstr "ვერ მივიღე \"%s\"-ის ფაილის ტიპი: %s"

#: common/flatpak-exports.c:964
#, c-format
msgid "File \"%s\" has unsupported type 0o%o"
msgstr "ფაილს \"%s\" აქვს მხარდაუჭერელი ტიპი 0o%o"

#: common/flatpak-exports.c:970
#, c-format
msgid "Unable to get filesystem information for \"%s\": %s"
msgstr "ვერ მივიღე ფაილური სისტემის ინფორმაცია \"%s\"-სთვის: %s"

#: common/flatpak-exports.c:980
#, c-format
msgid "Ignoring blocking autofs path \"%s\""
msgstr "გამოტოვებულია დამბლოკავი autofs-ის ბილიკი \"%s\""

#: common/flatpak-exports.c:996 common/flatpak-exports.c:1009
#: common/flatpak-exports.c:1022
#, c-format
msgid "Path \"%s\" is reserved by Flatpak"
msgstr "ბილიკი \"%s\" დაცულია Flatpak-ის მიერ"

#: common/flatpak-exports.c:1076
#, c-format
msgid "Unable to resolve symbolic link \"%s\": %s"
msgstr "სიმბმულის \"%s\" ამოხსნა შეუძლებელია: %s"

#: common/flatpak-glib-backports.c:69
msgid "Empty string is not a number"
msgstr "ცარიელი სტრიქონი რიცხვი არაა"

#: common/flatpak-glib-backports.c:95
#, c-format
msgid "“%s” is not an unsigned number"
msgstr "\"%s\" უნიშნო რიცხვი არაა"

#: common/flatpak-glib-backports.c:105
#, c-format
msgid "Number “%s” is out of bounds [%s, %s]"
msgstr "რიცხვი \"%s\" დიაპაზონს გარეთაა [%s, %s]"

#: common/flatpak-image-source.c:83
msgid "Only sha256 image checksums are supported"
msgstr ""

#: common/flatpak-image-source.c:100 common/flatpak-image-source.c:108
msgid "Image is not a manifest"
msgstr "გამოსახულება მანიფესტს არ წარმოადგენს"

#: common/flatpak-image-source.c:123
msgid "No org.flatpak.ref found in image"
msgstr ""

#: common/flatpak-image-source.c:148
#, c-format
msgid "Ref '%s' not found in registry"
msgstr "მიმართვა '%s' რეესტრში აღმოჩენილი არაა"

#: common/flatpak-image-source.c:157
msgid "Multiple images in registry, specify a ref with --ref"
msgstr "რეესტრი ერთზე მეტ ასლს შეიცვს. მიმართვა --ref-ით მიუთითეთ"

#: common/flatpak-installation.c:834
#, c-format
msgid "Ref %s not installed"
msgstr "მიმართვა %s დაყენებული არაა"

#: common/flatpak-installation.c:875
#, c-format
msgid "App %s not installed"
msgstr "აპი %s დაყენებული არაა"

#: common/flatpak-installation.c:1395
#, c-format
msgid "Remote '%s' already exists"
msgstr "დაშორებული '%s' უკვე არსებობს"

#: common/flatpak-installation.c:1946
#, c-format
msgid "As requested, %s was only pulled, but not installed"
msgstr "მოთხოვნის მიხედვით, მოხდა %s-ის მხოლოდ პული, მაგრამ არა დაყენება"

#: common/flatpak-instance.c:533 common/flatpak-instance.c:687
#: common/flatpak-instance.c:728
#, c-format
msgid "Unable to create directory %s"
msgstr "საქაღალდის (%s) შექმნა შეუძლებელია"

#: common/flatpak-instance.c:554
#, c-format
msgid "Unable to lock %s"
msgstr "%s-ის ჩაკეტვის შეცდომა"

#: common/flatpak-instance.c:627
#, c-format
msgid "Unable to create temporary directory in %s"
msgstr "%s-ში დროებითი საქაღალდის შექმნის შეცდომა"

#: common/flatpak-instance.c:639
#, c-format
msgid "Unable to create file %s"
msgstr "ფაილის შექმნის შეცდომა (%s)"

#: common/flatpak-instance.c:646
#, c-format
msgid "Unable to update symbolic link %s/%s"
msgstr "სიმბმულის (%s/%s) განახლების შეცდომა"

#: common/flatpak-oci-registry.c:1197
msgid "Only Bearer authentication supported"
msgstr "მხარდაჭერილია მხოლოდ Bearer ავთენტიკაცია"

#: common/flatpak-oci-registry.c:1206
msgid "Only realm in authentication request"
msgstr "ავთენტიკაციის მოთხოვნაში მხოლოდ რეალმია"

#: common/flatpak-oci-registry.c:1213
msgid "Invalid realm in authentication request"
msgstr "არასწორი რეალმი ავთენტიკაციის მოთხოვნაში"

#: common/flatpak-oci-registry.c:1283
#, c-format
msgid "Authorization failed: %s"
msgstr "ავტორიზაციის შეცდომა: %s"

#: common/flatpak-oci-registry.c:1285
msgid "Authorization failed"
msgstr "ავტორიზაციის შეცდომა"

#: common/flatpak-oci-registry.c:1289
#, c-format
msgid "Unexpected response status %d when requesting token: %s"
msgstr "მოულოდნელი საპასუხო სტატუსი %d კოდის გამოთხოვისას: %s"

#: common/flatpak-oci-registry.c:1300
msgid "Invalid authentication request response"
msgstr "არასწორი პასუხი ავთენტიკაციის მოთხოვნაზე"

#: common/flatpak-oci-registry.c:1731
#, c-format
msgid "Flatpak was compiled without zstd support"
msgstr ""

#: common/flatpak-oci-registry.c:1923 common/flatpak-oci-registry.c:1975
#: common/flatpak-oci-registry.c:2004 common/flatpak-oci-registry.c:2059
#: common/flatpak-oci-registry.c:2115 common/flatpak-oci-registry.c:2193
msgid "Invalid delta file format"
msgstr "არასწორი დელტა ფაილის ფორმატი"

#: common/flatpak-oci-registry.c:3198 common/flatpak-oci-registry.c:3382
msgid "Invalid OCI image config"
msgstr "არასწორი OCI ასლის კონფიგურაცია"

#: common/flatpak-oci-registry.c:3260 common/flatpak-oci-registry.c:3531
#, c-format
msgid "Wrong layer checksum, expected %s, was %s"
msgstr "არასწორი ფენის საკონტროლო ჯამი. მოველოდი %s, აღმოჩნდა %s"

#: common/flatpak-oci-registry.c:3359
#, c-format
msgid "No ref specified for OCI image %s"
msgstr "OCI ასლისთვის %s მიმართვა მითითებული არაა"

#: common/flatpak-oci-registry.c:3369
#, c-format
msgid "Wrong ref (%s) specified for OCI image %s, expected %s"
msgstr ""
"მითითებული მიმართვა (%s) OCI გამოსახულებისთვის %s არასწორია. მოველოდი:%s"

#: common/flatpak-progress.c:236
#, c-format
msgid "Downloading metadata: %u/(estimating) %s"
msgstr "მეტამონაცემების გადმოწერა: %u/(დაახლოებით) %s"

#: common/flatpak-progress.c:260
#, c-format
msgid "Downloading: %s/%s"
msgstr "გადმოწერა: %s/%s"

#: common/flatpak-progress.c:280
#, c-format
msgid "Downloading extra data: %s/%s"
msgstr "დამატებითი ინფორმაციის გადმოწერა: %s/%s"

#: common/flatpak-progress.c:285
#, c-format
msgid "Downloading files: %d/%d %s"
msgstr "ფაილების გადმოწერა: %d/%d %s"

#: common/flatpak-ref-utils.c:122
msgid "Name can't be empty"
msgstr "სახელი ცარიელი ვერ იქნება"

#: common/flatpak-ref-utils.c:129
msgid "Name can't be longer than 255 characters"
msgstr "სახელი 255 სიმბოლოზე გრძელი ვერ იქნება"

#: common/flatpak-ref-utils.c:142
msgid "Name can't start with a period"
msgstr "სახელი გამოტოვებით ვერ დაიწყება"

#: common/flatpak-ref-utils.c:148
#, c-format
msgid "Name can't start with %c"
msgstr "სახელი %c-ით ვერ დაიწყება"

#: common/flatpak-ref-utils.c:164
msgid "Name can't end with a period"
msgstr "სახელი გამოტოვებით ვერ დასრულდება"

#: common/flatpak-ref-utils.c:171 common/flatpak-ref-utils.c:183
msgid "Only last name segment can contain -"
msgstr "- -ს მხოლოდ ბოლო სახელის სეგმენტი შეიძლება, შეიცავდეს"

#: common/flatpak-ref-utils.c:174
#, c-format
msgid "Name segment can't start with %c"
msgstr "სახელის სეგმენტი %c-ით ვერ დაიწყება"

#: common/flatpak-ref-utils.c:186
#, c-format
msgid "Name can't contain %c"
msgstr "სახელი არ შეიძლება, %c-ს შეიცავდეს"

#: common/flatpak-ref-utils.c:195
msgid "Names must contain at least 2 periods"
msgstr "სახელები სულ ცოტა ორ გამოტოვებას უნდა შეიცავდნენ"

#: common/flatpak-ref-utils.c:312
msgid "Arch can't be empty"
msgstr "არქიტექტურა ცარიელი ვერ იქნება"

#: common/flatpak-ref-utils.c:323
#, c-format
msgid "Arch can't contain %c"
msgstr "არქიტექტურის სახელი არ შეიძლება, %c-ს სეიცავდეს"

#: common/flatpak-ref-utils.c:385
msgid "Branch can't be empty"
msgstr "ბრენჩი არ შეიძლება, ცარიელი იყოს"

#: common/flatpak-ref-utils.c:395
#, c-format
msgid "Branch can't start with %c"
msgstr "ბრენჩის სახელი %c-ით ვერ დაიწყება"

#: common/flatpak-ref-utils.c:405
#, c-format
msgid "Branch can't contain %c"
msgstr "ბრენჩის სახელი არ შეიძლება, %c-ს სეიცავდეს"

#: common/flatpak-ref-utils.c:615 common/flatpak-ref-utils.c:865
msgid "Ref too long"
msgstr "მიმართვა მეტისმეტად გრძელია"

#: common/flatpak-ref-utils.c:627
msgid "Invalid remote name"
msgstr "არასწორი დაშორებულის სახელი"

#: common/flatpak-ref-utils.c:641
#, c-format
msgid "%s is not application or runtime"
msgstr "%s აპლიკაცია ან გაშვების გარემო არაა"

#: common/flatpak-ref-utils.c:650 common/flatpak-ref-utils.c:667
#: common/flatpak-ref-utils.c:683
#, c-format
msgid "Wrong number of components in %s"
msgstr "%s-ში კომპონენტების არასწორი რაოდენობა"

#: common/flatpak-ref-utils.c:656
#, c-format
msgid "Invalid name %.*s: %s"
msgstr "არასწორი სახელი %.*s: %s"

#: common/flatpak-ref-utils.c:673
#, c-format
msgid "Invalid arch: %.*s: %s"
msgstr "არასწორი არქიტექტურა: %.*s: %s"

#: common/flatpak-ref-utils.c:816
#, c-format
msgid "Invalid name %s: %s"
msgstr "არასწორი სახელი %s: %s"

#: common/flatpak-ref-utils.c:834
#, c-format
msgid "Invalid arch: %s: %s"
msgstr "არასწორი არქიტექტურა: %s: %s"

#: common/flatpak-ref-utils.c:853
#, c-format
msgid "Invalid branch: %s: %s"
msgstr "არასწორი ბრენჩი: %s: %s"

#: common/flatpak-ref-utils.c:962 common/flatpak-ref-utils.c:970
#: common/flatpak-ref-utils.c:978
#, c-format
msgid "Wrong number of components in partial ref %s"
msgstr "ნაწილობრივ მიმართვა %s-ში კომპონენტების არასწორი რაოდენობა"

#: common/flatpak-ref-utils.c:1298
msgid " development platform"
msgstr " სატესტო პლატფორმა"

#: common/flatpak-ref-utils.c:1300
msgid " platform"
msgstr " პლატფორმა"

#: common/flatpak-ref-utils.c:1302
msgid " application base"
msgstr " აპლიკაციის ბაზა"

#: common/flatpak-ref-utils.c:1305
msgid " debug symbols"
msgstr " გამართვის სიმბოლოები"

#: common/flatpak-ref-utils.c:1307
msgid " sourcecode"
msgstr " საწყისიკოდი"

#: common/flatpak-ref-utils.c:1309
msgid " translations"
msgstr " თარგმანები"

#: common/flatpak-ref-utils.c:1311
msgid " docs"
msgstr " დოკუმენტები"

#: common/flatpak-ref-utils.c:1578
#, c-format
msgid "Invalid id %s: %s"
msgstr "არასწორი id %s: %s"

#: common/flatpak-remote.c:1216
#, c-format
msgid "Bad remote name: %s"
msgstr "არასწორი დაშორებულის სახელი: %s"

#: common/flatpak-remote.c:1220
#, fuzzy
msgid "No URL specified"
msgstr "URL მითითებული არაა"

#: common/flatpak-remote.c:1266
msgid "GPG verification must be enabled when a collection ID is set"
msgstr "როცა კოლექციის ID დაყენებულია, GPG-ით გადამოწმების ჩართვა აუცილებელია"

#: common/flatpak-repo-utils.c:344
#, c-format
msgid "No extra data sources"
msgstr "დამატებითი მონაცემის წყაროების გარეშე"

#: common/flatpak-repo-utils.c:2817
#, c-format
msgid "Invalid %s: Missing group ‘%s’"
msgstr "არასწორი %s: ჯგუფი '%s' ვერ ვიპოვე"

#: common/flatpak-repo-utils.c:2826
#, c-format
msgid "Invalid %s: Missing key ‘%s’"
msgstr "არასწორი %s: გასაღები '%s' ვერ ვიპოვე"

#: common/flatpak-repo-utils.c:2876
msgid "Invalid gpg key"
msgstr "არასწორი GPG გასაღები"

#: common/flatpak-repo-utils.c:3217
#, c-format
msgid "Error copying 64x64 icon for component %s: %s\n"
msgstr "64x64 ხატულის კოპირების შეცდომა კომპონენტისთვის %s: %s\n"

#: common/flatpak-repo-utils.c:3223
#, c-format
msgid "Error copying 128x128 icon for component %s: %s\n"
msgstr "128x128 ხატულის კოპირების შეცდომა კომპონენტისთვის %s: %s\n"

#: common/flatpak-repo-utils.c:3362
#, c-format
msgid "%s is end-of-life, ignoring for appstream"
msgstr "%s-ის მხარდაჭერა ამოწურულია. გამოტოვება Appstream-ისთვის"

#: common/flatpak-repo-utils.c:3397
#, c-format
msgid "No appstream data for %s: %s\n"
msgstr "%s-სთვის Appstream-ის მონაცემები აღმოჩენილი არაა: %s\n"

#: common/flatpak-repo-utils.c:3744
msgid "Invalid bundle, no ref in metadata"
msgstr "არასწორი პაკეტი. მეტამონაცემებში მიმართვა აღმოჩენილი არაა"

#: common/flatpak-repo-utils.c:3846
#, c-format
msgid "Collection ‘%s’ of bundle doesn’t match collection ‘%s’ of remote"
msgstr "პაკეტის კოლექცია %s დაშორებულის კოლექციას '%s' არ ემთხვევა"

#: common/flatpak-repo-utils.c:3923
msgid "Metadata in header and app are inconsistent"
msgstr "თავსართში არსებული მეტამონაცემები და აპი არ ემთხვევა"

#: common/flatpak-run.c:951
msgid "No systemd user session available, cgroups not available"
msgstr ""
"Systemd-ის მომხმარებლის სესია ხელმისაწვდომი არაა. cgroup-ები ხელმისაწვდომი "
"არაა"

#: common/flatpak-run.c:1496
msgid "Unable to allocate instance id"
msgstr "გაშვებული ასლის ID-ის გამოყოფის შეცდომა"

#: common/flatpak-run.c:1632 common/flatpak-run.c:1641
#, c-format
msgid "Failed to open flatpak-info file: %s"
msgstr "შეცდომა flatpak-info ფაილის გახსნისას: %s"

#: common/flatpak-run.c:1668
#, c-format
msgid "Failed to open bwrapinfo.json file: %s"
msgstr "შეცდომა bwrapinfo.json ფაილის გახსნისას: %s"

#: common/flatpak-run.c:1689
#, c-format
msgid "Failed to write to instance id fd: %s"
msgstr "გაშვებული ასლის ID-ის ფაილის დესკრიპტორის ჩაწერის შეცდომა: %s"

#: common/flatpak-run.c:2096
msgid "Initialize seccomp failed"
msgstr "Seccomp-ის ინიციალიზაციის შეცდომა"

#: common/flatpak-run.c:2135
#, c-format
msgid "Failed to add architecture to seccomp filter: %s"
msgstr "Seccomp ფილტრში არქიტექტურის დამატების შეცდომა: %s"

#: common/flatpak-run.c:2143
#, c-format
msgid "Failed to add multiarch architecture to seccomp filter: %s"
msgstr "Seccomp ფილტრში multiarch არქიტექტურის დამატების შეცდომა: %s"

#: common/flatpak-run.c:2175 common/flatpak-run.c:2192
#: common/flatpak-run.c:2214
#, c-format
msgid "Failed to block syscall %d: %s"
msgstr "სისტემური გამოძახების %d დაბლოკვის შეცდომა: %s"

#: common/flatpak-run.c:2247
#, c-format
msgid "Failed to export bpf: %s"
msgstr "BPF_ის გატანის შეცდომა: %s"

#: common/flatpak-run.c:2587
#, c-format
msgid "Failed to open ‘%s’"
msgstr "'%s'-ის გახსნის შეცდომა"

#: common/flatpak-run.c:2597
#, c-format
msgid ""
"Directory forwarding needs version 4 of the document portal (have version %d)"
msgstr ""

#: common/flatpak-run.c:2915
#, c-format
msgid "ldconfig failed, exit status %d"
msgstr "ldconfig-ის შეცდომა. გამოსვლის სტატუსი %d"

#: common/flatpak-run.c:2922
msgid "Can't open generated ld.so.cache"
msgstr "გენერირებული ld.so.cache ფაილის გახსნა შეუძლებელია"

#. Translators: The placeholder is for an app ref.
#: common/flatpak-run.c:3045
#, c-format
msgid "Running %s is not allowed by the policy set by your administrator"
msgstr "%s-ის გაშვება აკრძალულია თქვენი ადმინისტრატორის წესების მიერ"

#: common/flatpak-run.c:3202
msgid ""
"\"flatpak run\" is not intended to be run as `sudo flatpak run`. Use `sudo "
"-i` or `su -l` instead and invoke \"flatpak run\" from inside the new shell."
msgstr ""
"\"flatpak run\"-ის გაშვება ბრძანებით `sudo flatpak run` შეუძლებელია. "
"გამოიყენეთ `sudo -i` ან `su -l` და \"flatpak run\" ახალი გარსიდან გაუშვით."

#: common/flatpak-run.c:3413
#, c-format
msgid "Failed to migrate from %s: %s"
msgstr "%s-დან მიგრაცის შეცდომა: %s"

#: common/flatpak-run.c:3434
#, c-format
msgid "Failed to migrate old app data directory %s to new name %s: %s"
msgstr ""
"ძველი აპის მონაცემების საქაღალდის %s ახალი სახელით %s მიგრაციის შეცდომა: %s"

#: common/flatpak-run.c:3443
#, c-format
msgid "Failed to create symlink while migrating %s: %s"
msgstr "%s-ის მიგრაციისას სიმბმულის შექმნის შეცდომა: %s"

#: common/flatpak-run-dbus.c:46
msgid "Failed to open app info file"
msgstr "აპის ინფორმაციის ფაილის გახსნის შეცდომა"

#: common/flatpak-run-dbus.c:149
msgid "Unable to create sync pipe"
msgstr "სინქრონიზაციის ფაიფის შექმნის შეცდომა"

#: common/flatpak-run-dbus.c:185
msgid "Failed to sync with dbus proxy"
msgstr "D-Bus-ის პროქსისთან სინქრონიზაციის შეცდომა"

#: common/flatpak-transaction.c:2275
#, c-format
msgid "Warning: Problem looking for related refs: %s"
msgstr "გაფრთხილება: შესაბამისი მიმართვების მოძებნის შეცდომა: %s"

#: common/flatpak-transaction.c:2493
#, c-format
msgid "The application %s requires the runtime %s which was not found"
msgstr "აპლიკაცია %s მოითხოვს გაშვების გარემოს %s, რომელიც ვერ ვიპოვე"

#: common/flatpak-transaction.c:2509
#, c-format
msgid "The application %s requires the runtime %s which is not installed"
msgstr "აპლიკაცია %s მოითხოვს გაშვების გარემოს %s, რომელიც დაყენებული არაა"

#: common/flatpak-transaction.c:2641
#, c-format
msgid "Can't uninstall %s which is needed by %s"
msgstr "%s-ის წაშლა შეუძლებელია. ის %s-ს სჭირდება"

#: common/flatpak-transaction.c:2740
#, c-format
msgid "Remote %s disabled, ignoring %s update"
msgstr "დაშორებული %s გამორთულია. %s განახლება გამოტოვებულია"

#: common/flatpak-transaction.c:2773
#, c-format
msgid "%s is already installed"
msgstr "%s უკვე დაყენებულია"

#: common/flatpak-transaction.c:2776
#, c-format
msgid "%s is already installed from remote %s"
msgstr "%s უკვე დაყენებულია დაშორებულიდან %s"

#: common/flatpak-transaction.c:3120
#, c-format
msgid "Invalid .flatpakref: %s"
msgstr "არასწორი .flatpakref: %s"

#: common/flatpak-transaction.c:3161
msgid "Warning: Could not mark already installed apps as preinstalled"
msgstr ""

#: common/flatpak-transaction.c:3382
#, c-format
msgid "Error updating remote metadata for '%s': %s"
msgstr "დაშორებული მეტამონაცემების განახლების შეცდომა '%s'-სთვის: %s"

#: common/flatpak-transaction.c:3885
#, c-format
msgid ""
"Warning: Treating remote fetch error as non-fatal since %s is already "
"installed: %s"
msgstr ""
"გაფრთხილება: დაშორებულის გამოთხოვის შეცდომის არაფატალურად ჩათვლა, რადგან %s "
"უკვე დაყენებულია: %s"

#: common/flatpak-transaction.c:4209
#, c-format
msgid "No authenticator installed for remote '%s'"
msgstr "დაშორებულისთვის '%s' ავთენტიკატორი დაყენებული არაა"

#: common/flatpak-transaction.c:4313 common/flatpak-transaction.c:4320
#, c-format
msgid "Failed to get tokens for ref: %s"
msgstr "მიმართვისთვის კოდების მიღების შეცდომა: %s"

#: common/flatpak-transaction.c:4315 common/flatpak-transaction.c:4322
msgid "Failed to get tokens for ref"
msgstr "მიმართვისთვის კოდების მიღების შეცდომა"

#: common/flatpak-transaction.c:4580
#, c-format
msgid "Ref %s from %s matches more than one transaction operation"
msgstr "მიმართვა %s %s-დან ერთზე მეტ ტრანზაქციის ოპერაციას ემთხვევა"

#: common/flatpak-transaction.c:4581 common/flatpak-transaction.c:4591
msgid "any remote"
msgstr "ნებისმიერი დაშორებული"

#: common/flatpak-transaction.c:4590
#, c-format
msgid "No transaction operation found for ref %s from %s"
msgstr "მიმართვისთვის '%s' '%s'-დან ტრანზაქციის ოპერაცია აღმოჩენილი არაა"

#: common/flatpak-transaction.c:4713
#, c-format
msgid "Flatpakrepo URL %s not file, HTTP or HTTPS"
msgstr "Flatpakrepo-ის URL %s არც ფაილია, არც HTTP და არც HTTPS"

#: common/flatpak-transaction.c:4719
#, c-format
msgid "Can't load dependent file %s: "
msgstr "დამოკიდებული ფაილის '%s' ჩატვირთვა შეუძლებელია: "

#: common/flatpak-transaction.c:4727
#, c-format
msgid "Invalid .flatpakrepo: %s"
msgstr "არასწორი .flatpakrepo: %s"

#: common/flatpak-transaction.c:5454
msgid "Transaction already executed"
msgstr "ტრანაქცია უკვე შესრულებულია"

#: common/flatpak-transaction.c:5469
msgid ""
"Refusing to operate on a user installation as root! This can lead to "
"incorrect file ownership and permission errors."
msgstr ""
"Root მომხმარებლით მომხმარებლის დაყენებულ პაკეტებზე ოპერირება უარყოფილია! "
"ამას არასწორი ფაილების მფლობელობამდე და წვდომების შეცდომებამდე შეუძლია, "
"მიგვიყვანოს."

#: common/flatpak-transaction.c:5567 common/flatpak-transaction.c:5580
msgid "Aborted by user"
msgstr "გაუქმდა მომხმარებლის მოთხოვნით"

#: common/flatpak-transaction.c:5605
#, c-format
msgid "Skipping %s due to previous error"
msgstr "%s-ს გამოტოვება წინა შეცდომის გამო"

#: common/flatpak-transaction.c:5659
#, c-format
msgid "Aborted due to failure (%s)"
msgstr "შეწყდა შეცდომის გამო (%s)"

#: common/flatpak-uri.c:118
#, no-c-format
msgid "Invalid %-encoding in URI"
msgstr "არასწორი %s-კოდირება URI-ში"

#: common/flatpak-uri.c:135
msgid "Illegal character in URI"
msgstr "დაუშვებელი სიმბოლო URI-ში"

#: common/flatpak-uri.c:169
msgid "Non-UTF-8 characters in URI"
msgstr "არა-UTF-8 სიმბოლოები URI-ში"

#: common/flatpak-uri.c:275
#, c-format
msgid "Invalid IPv6 address ‘%.*s’ in URI"
msgstr "არასწორი IPv6 მისამართი '%.*s' URI-ში"

#: common/flatpak-uri.c:330
#, c-format
msgid "Illegal encoded IP address ‘%.*s’ in URI"
msgstr "არასწორად კოდირებული IP მისამართი ‘%.*s’ URI-ში"

#: common/flatpak-uri.c:342
#, c-format
msgid "Illegal internationalized hostname ‘%.*s’ in URI"
msgstr "არასწორი არა-ASCII ჰოსტის სახელი '%.*s' URI-ში"

#: common/flatpak-uri.c:374 common/flatpak-uri.c:386
#, c-format
msgid "Could not parse port ‘%.*s’ in URI"
msgstr "URI-ში პორტის '%.*s'-ის დამუშავების შეცდომა"

#: common/flatpak-uri.c:393
#, c-format
msgid "Port ‘%.*s’ in URI is out of range"
msgstr "URI-ში პორტი '%.*s' დიაპაზონს გარეთაა"

#: common/flatpak-uri.c:910
msgid "URI is not absolute, and no base URI was provided"
msgstr "URI აბსოლუტური არაა და საბაზისო URI მითითებული არაა"

#: common/flatpak-usb.c:83
#, c-format
msgid "USB device query 'all' must not have data"
msgstr "USB მოწყობილობის მოთხოვნას 'all' მონაცემები არ უნდა ჰქონდეს"

#: common/flatpak-usb.c:102
#, c-format
msgid "USB query rule 'cls' must be in the form CLASS:SUBCLASS or CLASS:*"
msgstr "USB მოთხოვნის წესი 'cls' უნდა იყოს ფორმით CLASS:SUBCLASS ან CLASS:*"

#: common/flatpak-usb.c:111
#, c-format
msgid "Invalid USB class"
msgstr "არასწორი USB-ის კლასი"

#: common/flatpak-usb.c:125
#, c-format
msgid "Invalid USB subclass"
msgstr "არასწორი USB ქვეკლასი"

#: common/flatpak-usb.c:141 common/flatpak-usb.c:148
#, c-format
msgid "USB query rule 'dev' must have a valid 4-digit hexadecimal product id"
msgstr ""
"USB მოთხოვნის წესს 'dev' სწორი 4-ციფრიანი თექვსმეტობითი პროდუქტის id უნდა "
"ჰქონდეს"

#: common/flatpak-usb.c:164 common/flatpak-usb.c:171
#, c-format
msgid "USB query rule 'vnd' must have a valid 4-digit hexadecimal vendor id"
msgstr ""
"USB მოთხოვნის წესს 'vnd' სწორი 4-ციფრიანი თექვსმეტობითი პროდუქტის id უნდა "
"ჰქონდეს"

#: common/flatpak-usb.c:205
#, c-format
msgid "USB device queries must be in the form TYPE:DATA"
msgstr "USB მოწყობილობის მოთხოვნები უნდა იყოს ფორმით ტიპი:მონაცემები"

#: common/flatpak-usb.c:225
#, c-format
msgid "Unknown USB query rule %s"
msgstr "უცნობი USB მოთხოვნის წესი %s"

#: common/flatpak-usb.c:248
#, c-format
msgid "Empty USB query"
msgstr "ცარიელი USB მოთხოვნა"

#: common/flatpak-usb.c:274
#, c-format
msgid "Multiple USB query rules of the same type is not supported"
msgstr "ერთზე მეტი USB მოთხოვნის წესი იგივე ტიპით მხარდაჭერილი არაა"

#: common/flatpak-usb.c:283
#, c-format
msgid "'all' must not contain extra query rules"
msgstr "'all' დამატებითი მოთხოვნის წესებს არ უნდა შეიცავდეს"

#: common/flatpak-usb.c:291
#, c-format
msgid "USB queries with 'dev' must also specify vendors"
msgstr "USB მოთხოვნები სტრიქონით 'dev' ასევე უნდა შეიცავდეს მომწოდებელსაც"

#: common/flatpak-utils.c:712
msgid "Glob can't match apps"
msgstr "გლობი აპებს ვერ დაემთხვევა"

#: common/flatpak-utils.c:737
msgid "Empty glob"
msgstr "ცარიელი გლობი"

#: common/flatpak-utils.c:756
msgid "Too many segments in glob"
msgstr "გლობში მეტისმეტად ბევრი სეგმენტია"

#: common/flatpak-utils.c:777
#, c-format
msgid "Invalid glob character '%c'"
msgstr "არასწორი გლობის სიმბოლო '%c'"

#: common/flatpak-utils.c:831
#, c-format
msgid "Missing glob on line %d"
msgstr "გლობი ხაზზე %d აღმოჩენილი არაა"

#: common/flatpak-utils.c:835
#, c-format
msgid "Trailing text on line %d"
msgstr "მიწერილი ტექსტი ხაზზე %d"

#: common/flatpak-utils.c:839
#, c-format
msgid "on line %d"
msgstr "ხაზზე %d"

#: common/flatpak-utils.c:861
#, c-format
msgid "Unexpected word '%s' on line %d"
msgstr "მოულოდნელი სიტყვა '%s' ხაზზე %d"

#: common/flatpak-utils.c:2118
#, c-format
msgid "Invalid require-flatpak argument %s"
msgstr "არასწორი require-flatpak-ის არგუმენტი %s"

#: common/flatpak-utils.c:2128 common/flatpak-utils.c:2147
#, c-format
msgid "%s needs a later flatpak version (%s)"
msgstr "%s-ს flatpak-ის უფრო ახალი ვერსია სჭირდება (%s)"

#: oci-authenticator/flatpak-oci-authenticator.c:291
msgid "Not a oci remote, missing summary.xa.oci-repository"
msgstr ""
"არ წარმოადგენს OCI დაშორებულს, რადგან summary.xa.oci-repository ვერ ვიპოვე"

#: oci-authenticator/flatpak-oci-authenticator.c:477
msgid "Not a OCI remote"
msgstr "არ წარმოადგენს OCI დაშორებულს"

#: oci-authenticator/flatpak-oci-authenticator.c:488
msgid "Invalid token"
msgstr "არასწორი კოდი"

#: portal/flatpak-portal.c:2292
#, c-format
msgid "No portal support found"
msgstr "პორტალის მხარდაჭერა ვერ ვიპოვე"

#: portal/flatpak-portal.c:2298
msgid "Deny"
msgstr "უარყოფა"

#: portal/flatpak-portal.c:2300
msgid "Update"
msgstr "განახლება"

#: portal/flatpak-portal.c:2305
#, c-format
msgid "Update %s?"
msgstr "განვაახლო %s?"

#: portal/flatpak-portal.c:2317
msgid "The application wants to update itself."
msgstr "აპლიკაცია თავისი თავის განახლებას აპირებს."

#: portal/flatpak-portal.c:2318
msgid "Update access can be changed any time from the privacy settings."
msgstr ""
"განახლების წვდომა ნებისმიერ დროს კონფიდენციალობის პარამეტრებიდან შეიძლება "
"შეიცვალოს."

#: portal/flatpak-portal.c:2343
#, c-format
msgid "Application update not allowed"
msgstr "აპლიკაცის განახლება დაშვებული არაა"

#: portal/flatpak-portal.c:2501
#, c-format
msgid "Self update not supported, new version requires new permissions"
msgstr ""
"თვით-განახლება მხარდაჭერილი არაა, რადგან ახალ ვერსიას ახალი წვდომები სჭირდება"

#: portal/flatpak-portal.c:2684 portal/flatpak-portal.c:2702
#, c-format
msgid "Update ended unexpectedly"
msgstr "განახლება მოულოდნელად დასრულდა"

#. SECURITY:
#. - Normal users need admin authentication to install software
#. system-wide.
#. - Note that we install polkit rules that allow local users
#. in the wheel group to install without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:23
msgid "Install signed application"
msgstr "ხელმოწერილი აპლიკაციის დაყენება"

#: system-helper/org.freedesktop.Flatpak.policy.in:24
#: system-helper/org.freedesktop.Flatpak.policy.in:42
msgid "Authentication is required to install software"
msgstr "პროგრამის დასაწყენებლად ავთენტიკაცია დაგჭირდებათ"

#. SECURITY:
#. - Normal users need admin authentication to install software
#. system-wide.
#. - Note that we install polkit rules that allow local users
#. in the wheel group to install without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:41
msgid "Install signed runtime"
msgstr "ხელმოწერილი გაშვების გარემოს დაყენება"

#. SECURITY:
#. - Normal users do not require admin authentication to update an
#. app as the commit will be signed, and the action is required
#. to update the system when unattended.
#. - Changing this to anything other than 'yes' will break unattended
#. updates.
#: system-helper/org.freedesktop.Flatpak.policy.in:60
msgid "Update signed application"
msgstr "ხელმოწერილი აპლიკაციის განახლება"

#: system-helper/org.freedesktop.Flatpak.policy.in:61
#: system-helper/org.freedesktop.Flatpak.policy.in:80
msgid "Authentication is required to update software"
msgstr "პროგრამების განახლებისთვის ავთენტიკაცია დაგჭირდებათ"

#. SECURITY:
#. - Normal users do not require admin authentication to update a
#. runtime as the commit will be signed, and the action is required
#. to update the system when unattended.
#. - Changing this to anything other than 'yes' will break unattended
#. updates.
#: system-helper/org.freedesktop.Flatpak.policy.in:79
msgid "Update signed runtime"
msgstr "ხელმოწერილი გაშვების გარემოს განახლება"

#. SECURITY:
#. - Normal users do not need authentication to update metadata
#. from signed repositories.
#: system-helper/org.freedesktop.Flatpak.policy.in:94
msgid "Update remote metadata"
msgstr "დაშორებული მეტამონაცემების განახლება"

#: system-helper/org.freedesktop.Flatpak.policy.in:95
msgid "Authentication is required to update remote info"
msgstr "დაშორებული ინფორმაციის განახლებისთვის ავთენტიკაცია დაგჭირდებათ"

#. SECURITY:
#. - Normal users do not need authentication to modify the
#. OSTree repository
#. - Note that we install polkit rules that allow local users
#. in the wheel group to modify repos without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:111
msgid "Update system repository"
msgstr "სისტემური რეპოზიტორიის განახლება"

#: system-helper/org.freedesktop.Flatpak.policy.in:112
msgid "Authentication is required to modify a system repository"
msgstr "სისტემური რეპოზიტორიის შესაცვლელად ავთენტიკაცია დაგჭირდებათ"

#. SECURITY:
#. - Normal users need admin authentication to install software
#. system-wide.
#: system-helper/org.freedesktop.Flatpak.policy.in:126
msgid "Install bundle"
msgstr "პაკეტის დაყენება"

#: system-helper/org.freedesktop.Flatpak.policy.in:127
msgid "Authentication is required to install software from $(path)"
msgstr "%{path}-დან პროგრამის დასაყენებლად ავთენტიკაცია დაგჭირდებთ"

#. SECURITY:
#. - Normal users need admin authentication to uninstall software
#. system-wide.
#. - Note that we install polkit rules that allow local users
#. in the wheel group to uninstall without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:144
msgid "Uninstall runtime"
msgstr "გაშვების გარემოს წაშლა"

#: system-helper/org.freedesktop.Flatpak.policy.in:145
msgid "Authentication is required to uninstall software"
msgstr "პროგრამის წასაშლელად ავთენტიკაცია დაგჭირდებათ"

#. SECURITY:
#. - Normal users need admin authentication to uninstall software
#. system-wide.
#. - Note that we install polkit rules that allow local users
#. in the wheel group to uninstall without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:161
msgid "Uninstall app"
msgstr "აპის წაშლა"

#: system-helper/org.freedesktop.Flatpak.policy.in:162
msgid "Authentication is required to uninstall $(ref)"
msgstr "${ref}-ის წასაშლელად ავთენტიკაცია დაგჭირდებთ"

#. SECURITY:
#. - Normal users need admin authentication to configure system-wide
#. software repositories.
#: system-helper/org.freedesktop.Flatpak.policy.in:177
msgid "Configure Remote"
msgstr "დაშორებულის მორგება"

#: system-helper/org.freedesktop.Flatpak.policy.in:178
msgid "Authentication is required to configure software repositories"
msgstr "პროგრამის რეპოზიტორიების მოსარგებად ავთენტიკაცია დაგჭირდებათ"

#. SECURITY:
#. - Normal users need admin authentication to configure the system-wide
#. Flatpak installation.
#: system-helper/org.freedesktop.Flatpak.policy.in:192
msgid "Configure"
msgstr "მორგება"

#: system-helper/org.freedesktop.Flatpak.policy.in:193
msgid "Authentication is required to configure software installation"
msgstr "დაყენებული პროგრამების მოსარგებად ავთენტიკაცია დაგჭირდებათ"

#. SECURITY:
#. - Normal users do not require admin authentication to update
#. appstream data as it will be signed, and the action is required
#. to update the system when unattended.
#. - Changing this to anything other than 'yes' will break unattended
#. updates.
#: system-helper/org.freedesktop.Flatpak.policy.in:210
msgid "Update appstream"
msgstr "Appstream-ის განახლება"

#: system-helper/org.freedesktop.Flatpak.policy.in:211
msgid "Authentication is required to update information about software"
msgstr ""
"პროგრამების შესახებ ინფორმაციის განახლებისთვის ავთენტიკაცია დაგჭირდებათ"

#. SECURITY:
#. - Normal users do not require admin authentication to update
#. metadata as it will be signed, and the action is required
#. to update the system when unattended.
#. - Changing this to anything other than 'yes' will break unattended
#. updates.
#: system-helper/org.freedesktop.Flatpak.policy.in:228
msgid "Update metadata"
msgstr "მეტამონაცემების განახლება"

#: system-helper/org.freedesktop.Flatpak.policy.in:229
msgid "Authentication is required to update metadata"
msgstr "მეტამონაცემების განახლებისთვის ავთენტიკაცია დაგჭირდებათ"

#. SECURITY:
#. - Authorisation to actually install software is controlled by
#. org.freedesktop.Flatpak.app-install.
#. - This action is checked after app-install, as it can only be done
#. once the app’s data (including its content rating) has been
#. downloaded.
#. - This action is checked to see if the installation should be allowed
#. based on whether the app being installed has content which doesn’t
#. comply with the user’s parental controls policy (the content is
#. ‘too extreme’).
#. - It is checked only if an app has too extreme content for the user
#. who is trying to install it (in which case, the app is ‘unsafe’).
#. - Typically, normal users will need admin permission to install apps
#. with extreme content; admins will be able to install it without
#. additional checks.
#. - In order to configure the policy so that admins can install safe and
#. unsafe software anywhere without authorisation, and non-admins can
#. install safe software in their user or system dirs without
#. authorisation, but need authorisation to install unsafe software
#. anywhere:
#. * Unconditionally return `yes` from `app-install`.
#. * Return `auth_admin` from `override-parental-controls` for users
#. not in `@privileged_group@`, and `yes` for users in it.
#. * Set the malcontent `is-{user,system}-installation-allowed`
#. properties of all non-admins’ parental controls policies to true.
#. - In order to configure the policy so that admins can install safe and
#. unsafe software anywhere without authorisation, and non-admins can
#. install safe software in their user dir without authorisation, but
#. need authorisation to install safe software in the system dir or to
#. install unsafe software anywhere:
#. * Unconditionally return `yes` from `app-install`.
#. * Return `auth_admin` from `override-parental-controls` for users
#. not in `@privileged_group@`, and `yes` for users in it.
#. * Set the malcontent `is-user-installation-allowed` property of all
#. non-admins’ parental controls policies to true.
#. * Set the malcontent `is-system-installation-allowed` property of
#. all non-admins’ parental controls policies to false.
#. - In order to configure the policy so that all users (including
#. admins) can install safe software anywhere without authorisation,
#. but need authorisation to install unsafe software anywhere (i.e.
#. applying parental controls to admins too):
#. * Unconditionally return `yes` from `app-install`.
#. * Unconditionally return `auth_admin` from `override-parental-controls`.
#. * Set the malcontent `is-user-installation-allowed` property of all
#. users’ parental controls policies to true.
#. * Set the malcontent `is-system-installation-allowed` property of
#. all users’ parental controls policies to true.
#: system-helper/org.freedesktop.Flatpak.policy.in:287
#, fuzzy
msgid "Override parental controls for installs"
msgstr "მშობლის კონტროლის გადაფარვა"

#: system-helper/org.freedesktop.Flatpak.policy.in:288
msgid ""
"Authentication is required to install software which is restricted by your "
"parental controls policy"
msgstr ""
"თქვენი მშობლების საკონტროლო პოლიტიკის მიერ შეზღუდული პროგრამის დასაყენებლად "
"ავთენტიკაცია დაგჭირდებათ"

#. SECURITY:
#. - This is like org.freedesktop.Flatpak.override-parental-controls, but
#. it’s queried for app updates, whereas the former is queried for app
#. installs.
#. - As with the above action, this one is only queried if
#. org.freedesktop.Flatpak.app-update has allowed the app update, and
#. only if the app being updated has too extreme content for the user
#. who is trying to update it.
#. - The default policy for this is to *allow* updates to ‘too extreme’
#. apps by default, on the basis that having an out-of-date (i.e.
#. insecure or unsupported) app is a worse outcome than automatically
#. installing an update which has radically different content from the
#. version of the app which the parent originally vetted and installed.
#: system-helper/org.freedesktop.Flatpak.policy.in:313
#, fuzzy
msgid "Override parental controls for updates"
msgstr "მშობლის კონტროლის გადაფარვა"

#: system-helper/org.freedesktop.Flatpak.policy.in:314
#, fuzzy
msgid ""
"Authentication is required to update software which is restricted by your "
"parental controls policy"
msgstr ""
"თქვენი მშობლების საკონტროლო პოლიტიკის მიერ შეზღუდული პროგრამის დასაყენებლად "
"ავთენტიკაცია დაგჭირდებათ"

#~ msgid "Installed:"
#~ msgstr "დაყენებულია:"

#~ msgid "Download:"
#~ msgstr "გადმოწერა:"

#, c-format
#~ msgid "No gpg key found with ID %s (homedir: %s)"
#~ msgstr "ID %s-ის მქონე GPG გასაღები ნაპოვნი არაა (საწყისი საქაღალდე: %s)"

#, c-format
#~ msgid "Unable to lookup key ID %s: %d"
#~ msgstr "შეცდომა გასაღების ID %s მოძებნისას: %d"

#, c-format
#~ msgid "Error signing commit: %d"
#~ msgstr "კომიტის ხელმოწერის შეცდომა: %d"

===== ./po/uk.po =====
# Ukrainian translation for flatpak.
# Copyright (C) 2016 flatpak's COPYRIGHT HOLDER
# This file is distributed under the same license as the flatpak package.
#
# Yuri Chornoivan <yurchor@ukr.net>, 2016, 2017, 2018, 2019, 2020, 2021, 2022.
msgid ""
msgstr ""
"Project-Id-Version: flatpak master\n"
"Report-Msgid-Bugs-To: https://github.com/flatpak/flatpak/issues\n"
"POT-Creation-Date: 2026-05-27 16:39+0200\n"
"PO-Revision-Date: 2022-07-24 09:46+0300\n"
"Last-Translator: Yuri Chornoivan <yurchor@ukr.net>\n"
"Language-Team: Ukrainian <kde-i18n-uk@kde.org>\n"
"Language: uk\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=4; plural=n==1 ? 3 : n%10==1 && n%100!=11 ? 0 : "
"n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
"X-Generator: Lokalize 20.12.0\n"

#: app/flatpak-builtins-build-bundle.c:59
msgid "Export runtime instead of app"
msgstr "Експортувати середовище виконання замість програми"

#: app/flatpak-builtins-build-bundle.c:60
msgid "Arch to bundle for"
msgstr "Архітектура для пакунка"

#: app/flatpak-builtins-build-bundle.c:60
#: app/flatpak-builtins-build-export.c:62 app/flatpak-builtins-build-init.c:53
#: app/flatpak-builtins-build-sign.c:42 app/flatpak-builtins-create-usb.c:46
#: app/flatpak-builtins-info.c:55 app/flatpak-builtins-install.c:67
#: app/flatpak-builtins-list.c:50 app/flatpak-builtins-make-current.c:38
#: app/flatpak-builtins-remote-info.c:54 app/flatpak-builtins-remote-ls.c:56
#: app/flatpak-builtins-run.c:158 app/flatpak-builtins-search.c:37
#: app/flatpak-builtins-uninstall.c:54 app/flatpak-builtins-update.c:56
msgid "ARCH"
msgstr "АРХ"

#: app/flatpak-builtins-build-bundle.c:61
#, fuzzy
msgid "URL for repo"
msgstr "Адреса сховища"

#: app/flatpak-builtins-build-bundle.c:61
#: app/flatpak-builtins-build-bundle.c:62
#: app/flatpak-builtins-build-update-repo.c:68
#: app/flatpak-builtins-build-update-repo.c:72
#: app/flatpak-builtins-build-update-repo.c:73
#: app/flatpak-builtins-history.c:69 app/flatpak-builtins-remote-add.c:80
#: app/flatpak-builtins-remote-add.c:81 app/flatpak-builtins-remote-add.c:85
#: app/flatpak-builtins-remote-list.c:53
#: app/flatpak-builtins-remote-modify.c:70
#: app/flatpak-builtins-remote-modify.c:85
#: app/flatpak-builtins-remote-modify.c:86
#: app/flatpak-builtins-remote-modify.c:90
msgid "URL"
msgstr "АДРЕСА"

#: app/flatpak-builtins-build-bundle.c:62
#, fuzzy
msgid "URL for runtime flatpakrepo file"
msgstr "Адреса файла flatpakrepo середовища виконання"

#: app/flatpak-builtins-build-bundle.c:63
msgid "Add GPG key from FILE (- for stdin)"
msgstr "Додати ключ GPG з ФАЙЛА (- якщо дані слід взяти з stdin)"

#: app/flatpak-builtins-build-bundle.c:63 app/flatpak-builtins-build.c:54
#: app/flatpak-builtins-build-export.c:67
#: app/flatpak-builtins-build-update-repo.c:83
#: app/flatpak-builtins-install.c:81 app/flatpak-builtins-remote-add.c:84
#: app/flatpak-builtins-remote-add.c:86 app/flatpak-builtins-remote-modify.c:89
#: app/flatpak-builtins-remote-modify.c:92
msgid "FILE"
msgstr "ФАЙЛ"

#: app/flatpak-builtins-build-bundle.c:64
msgid "GPG Key ID to sign the OCI image with"
msgstr "Ідентифікатор ключа GPG для підписування образу OCI"

#: app/flatpak-builtins-build-bundle.c:64
#: app/flatpak-builtins-build-commit-from.c:68
#: app/flatpak-builtins-build-export.c:68
#: app/flatpak-builtins-build-import-bundle.c:49
#: app/flatpak-builtins-build-sign.c:44
#: app/flatpak-builtins-build-update-repo.c:84
msgid "KEY-ID"
msgstr "ІД КЛЮЧА"

#: app/flatpak-builtins-build-bundle.c:65
#: app/flatpak-builtins-build-commit-from.c:69
#: app/flatpak-builtins-build-export.c:71
#: app/flatpak-builtins-build-import-bundle.c:50
#: app/flatpak-builtins-build-sign.c:45
#: app/flatpak-builtins-build-update-repo.c:85
msgid "GPG Homedir to use when looking for keyrings"
msgstr "Домашній каталог GPG, яким слід користуватися для пошуку сховищ ключів"

#: app/flatpak-builtins-build-bundle.c:65
#: app/flatpak-builtins-build-commit-from.c:69
#: app/flatpak-builtins-build-export.c:71
#: app/flatpak-builtins-build-import-bundle.c:50
#: app/flatpak-builtins-build-sign.c:45
#: app/flatpak-builtins-build-update-repo.c:85
msgid "HOMEDIR"
msgstr "ДОМАШНІЙ-КАТАЛОГ"

#: app/flatpak-builtins-build-bundle.c:66
msgid "OSTree commit to create a delta bundle from"
msgstr "Внесок OSTree для створення пакунка відмінностей від"

#: app/flatpak-builtins-build-bundle.c:66 app/flatpak-builtins-remote-info.c:55
#: app/flatpak-builtins-update.c:57
msgid "COMMIT"
msgstr "COMMIT"

#: app/flatpak-builtins-build-bundle.c:67
msgid "Export oci image instead of flatpak bundle"
msgstr "Експортувати образ OCI замість пакунка flatpak"

#: app/flatpak-builtins-build-bundle.c:70
msgid "How to compress OCI image layers (default: gzip)"
msgstr ""

#: app/flatpak-builtins-build-bundle.c:634
msgid ""
"LOCATION FILENAME NAME [BRANCH] - Create a single file bundle from a local "
"repository"
msgstr ""
"РОЗТАШУВАННЯ НАЗВА_ФАЙЛА НАЗВА [ГІЛКА] - Створити пакунок з одного файла на "
"основі локального сховища"

#: app/flatpak-builtins-build-bundle.c:641
msgid "LOCATION, FILENAME and NAME must be specified"
msgstr "Слід вказати РОЗТАШУВАННЯ, НАЗВУ_ФАЙЛА та НАЗВУ"

#: app/flatpak-builtins-build-bundle.c:644
#: app/flatpak-builtins-build-export.c:844
#: app/flatpak-builtins-build-import-bundle.c:136
#: app/flatpak-builtins-build-init.c:217 app/flatpak-builtins-build-sign.c:76
#: app/flatpak-builtins-document-export.c:112
#: app/flatpak-builtins-document-info.c:75
#: app/flatpak-builtins-document-list.c:191
#: app/flatpak-builtins-document-unexport.c:70
#: app/flatpak-builtins-history.c:482 app/flatpak-builtins-info.c:130
#: app/flatpak-builtins-install.c:181 app/flatpak-builtins-install.c:234
#: app/flatpak-builtins-install.c:298 app/flatpak-builtins-list.c:419
#: app/flatpak-builtins-make-current.c:72 app/flatpak-builtins-override.c:73
#: app/flatpak-builtins-permission-list.c:162
#: app/flatpak-builtins-permission-remove.c:132
#: app/flatpak-builtins-remote-add.c:323
#: app/flatpak-builtins-remote-delete.c:68
#: app/flatpak-builtins-remote-list.c:241 app/flatpak-builtins-remote-ls.c:407
msgid "Too many arguments"
msgstr "Забагато аргументів"

#: app/flatpak-builtins-build-bundle.c:659
#: app/flatpak-builtins-build-commit-from.c:338
#: app/flatpak-builtins-build-commit-from.c:351
#: app/flatpak-builtins-build-import-bundle.c:145
#, c-format
msgid "'%s' is not a valid repository"
msgstr "«%s» не є коректним сховищем"

#: app/flatpak-builtins-build-bundle.c:663
#, c-format
msgid "'%s' is not a valid repository: "
msgstr "«%s» не є коректним сховищем:"

#: app/flatpak-builtins-build-bundle.c:674 app/flatpak-builtins-build-sign.c:88
#: common/flatpak-dir.c:14293
#, c-format
msgid "'%s' is not a valid name: %s"
msgstr "«%s» не є коректною назвою: %s"

#: app/flatpak-builtins-build-bundle.c:677
#: app/flatpak-builtins-build-export.c:865 app/flatpak-builtins-build-sign.c:91
#: common/flatpak-dir.c:14299
#, c-format
msgid "'%s' is not a valid branch name: %s"
msgstr "«%s» не є коректною назвою гілки: %s"

#: app/flatpak-builtins-build-bundle.c:691
#: app/flatpak-builtins-build-import-bundle.c:149
#: app/flatpak-builtins-build-init.c:281
#, c-format
msgid "'%s' is not a valid filename"
msgstr "«%s» не є коректною назвою файла"

#: app/flatpak-builtins-build-bundle.c:706
msgid "--oci-layer-compress value must be gzip or zstd"
msgstr ""

#: app/flatpak-builtins-build.c:49
msgid "Use Platform runtime rather than Sdk"
msgstr "Використовувати середовище виконання платформи замість SDK"

#: app/flatpak-builtins-build.c:50
msgid "Make destination readonly"
msgstr "Зробити призначення придатним лише для читання"

#: app/flatpak-builtins-build.c:51
msgid "Add bind mount"
msgstr "Додати монтування прив’язки"

#: app/flatpak-builtins-build.c:51
msgid "DEST=SRC"
msgstr "ПРИЗН=ДЖЕР"

#: app/flatpak-builtins-build.c:52
msgid "Start build in this directory"
msgstr "Почати збирання у цьому каталозі"

#: app/flatpak-builtins-build.c:52 app/flatpak-builtins-build.c:53
#: app/flatpak-builtins-build-init.c:64 app/flatpak-builtins-run.c:160
msgid "DIR"
msgstr "КАТАЛОГ"

#: app/flatpak-builtins-build.c:53
msgid "Where to look for custom sdk dir (defaults to 'usr')"
msgstr "Місце, де слід шукати нетиповий каталог sdk (типовим є каталог usr)"

#: app/flatpak-builtins-build.c:54 app/flatpak-builtins-build-export.c:67
msgid "Use alternative file for the metadata"
msgstr "Використовувати альтернативний файл для метаданих"

#: app/flatpak-builtins-build.c:55 app/flatpak-builtins-run.c:177
msgid "Kill processes when the parent process dies"
msgstr "Вбивати процеси, якщо завершив роботу батьківський процес"

#: app/flatpak-builtins-build.c:56
msgid "Export application homedir directory to build"
msgstr "Експортувати домашній каталог програми до каталогу збирання"

#: app/flatpak-builtins-build.c:57 app/flatpak-builtins-run.c:165
msgid "Log session bus calls"
msgstr "Записувати до журналу виклики до каналу сеансу"

#: app/flatpak-builtins-build.c:58 app/flatpak-builtins-run.c:166
msgid "Log system bus calls"
msgstr "Записувати до журналу виклики до каналу системи"

#: app/flatpak-builtins-build.c:262
msgid "DIRECTORY [COMMAND [ARGUMENT…]] - Build in directory"
msgstr "КАТАЛОГ [КОМАНДА [АРГУМЕНТ…]] - Зібрати у каталозі"

#: app/flatpak-builtins-build.c:285 app/flatpak-builtins-build-finish.c:656
msgid "DIRECTORY must be specified"
msgstr "Слід вказати КАТАЛОГ"

#: app/flatpak-builtins-build.c:296 app/flatpak-builtins-build-export.c:887
#, c-format
msgid "Build directory %s not initialized, use flatpak build-init"
msgstr ""
"Каталог збирання %s не ініціалізовано, скористайтеся командою flatpak build-"
"init"

#: app/flatpak-builtins-build.c:315
msgid "metadata invalid, not application or runtime"
msgstr "некоректні метадані, немає програми або середовища виконання"

#: app/flatpak-builtins-build.c:446
#, c-format
msgid "No extension point matching %s in %s"
msgstr "Немає точки розширення, яка відповідає %s у %s"

#: app/flatpak-builtins-build.c:635
#, c-format
msgid "Missing '=' in bind mount option '%s'"
msgstr "Пропущено «=» у параметрі монтування прив’язки «%s»"

#: app/flatpak-builtins-build.c:679 common/flatpak-run.c:3961
#, c-format
msgid "Unable to start app"
msgstr "Не вдалося запустити програму"

#: app/flatpak-builtins-build-commit-from.c:58
msgid "Source repo dir"
msgstr "Каталог сховища-джерела"

#: app/flatpak-builtins-build-commit-from.c:58
msgid "SRC-REPO"
msgstr "СХОВ-ДЖ"

#: app/flatpak-builtins-build-commit-from.c:59
msgid "Source repo ref"
msgstr "Посилання сховища-джерела"

#: app/flatpak-builtins-build-commit-from.c:59
msgid "SRC-REF"
msgstr "ПОС-ДЖ"

#: app/flatpak-builtins-build-commit-from.c:64
#: app/flatpak-builtins-build-export.c:60
msgid "One line subject"
msgstr "Тема у один рядок"

#: app/flatpak-builtins-build-commit-from.c:64
#: app/flatpak-builtins-build-export.c:60
msgid "SUBJECT"
msgstr "SUBJECT"

#: app/flatpak-builtins-build-commit-from.c:65
#: app/flatpak-builtins-build-export.c:61
msgid "Full description"
msgstr "Повний опис"

#: app/flatpak-builtins-build-commit-from.c:65
#: app/flatpak-builtins-build-export.c:61
msgid "BODY"
msgstr "BODY"

#: app/flatpak-builtins-build-commit-from.c:66
#: app/flatpak-builtins-build-export.c:64
#: app/flatpak-builtins-build-import-bundle.c:51
msgid "Update the appstream branch"
msgstr "Оновити гілку appstream"

#: app/flatpak-builtins-build-commit-from.c:67
#: app/flatpak-builtins-build-export.c:65
#: app/flatpak-builtins-build-import-bundle.c:52
#: app/flatpak-builtins-build-update-repo.c:87
msgid "Don't update the summary"
msgstr "Не оновлювати резюме"

#: app/flatpak-builtins-build-commit-from.c:68
#: app/flatpak-builtins-build-export.c:68
#: app/flatpak-builtins-build-import-bundle.c:49
#: app/flatpak-builtins-build-sign.c:44
msgid "GPG Key ID to sign the commit with"
msgstr "Ідентифікатор ключа GPG для підписування внеску"

#: app/flatpak-builtins-build-commit-from.c:70
#: app/flatpak-builtins-build-export.c:73
msgid "Mark build as end-of-life"
msgstr "Позначити збірку як таку, термін підтримки якої вичерпано"

#: app/flatpak-builtins-build-commit-from.c:70
#: app/flatpak-builtins-build-export.c:73
msgid "REASON"
msgstr "ПРИЧИНА"

#: app/flatpak-builtins-build-commit-from.c:71
msgid ""
"Mark refs matching the OLDID prefix as end-of-life, to be replaced with the "
"given NEWID"
msgstr ""
"Позначити посилання, які відповідають префіксу СТАРИЙІД як застарілі, такі, "
"які слід замінити вказаним ідентифікатором НОВИЙІД"

#: app/flatpak-builtins-build-commit-from.c:71
msgid "OLDID=NEWID"
msgstr "СТАРИЙІД=НОВИЙІД"

#: app/flatpak-builtins-build-commit-from.c:72
#: app/flatpak-builtins-build-export.c:75
msgid "Set type of token needed to install this commit"
msgstr "Встановити тип ключа, який потрібен для встановлення цього внеску"

#: app/flatpak-builtins-build-commit-from.c:72
#: app/flatpak-builtins-build-export.c:75
msgid "VAL"
msgstr "ЗНАЧЕННЯ"

#: app/flatpak-builtins-build-commit-from.c:73
msgid "Override the timestamp of the commit (NOW for current time)"
msgstr "Перевизначити часову позначку внеску (NOW — поточний момент)"

#: app/flatpak-builtins-build-commit-from.c:73
#: app/flatpak-builtins-build-export.c:76
msgid "TIMESTAMP"
msgstr "ЧАСОВА_ПОЗНАЧКА"

#: app/flatpak-builtins-build-commit-from.c:75
#: app/flatpak-builtins-build-export.c:80
#: app/flatpak-builtins-build-import-bundle.c:53
#: app/flatpak-builtins-build-update-repo.c:97
msgid "Don't generate a summary index"
msgstr "Не створювати індекс резюме"

#: app/flatpak-builtins-build-commit-from.c:278
msgid "DST-REPO [DST-REF…] - Make a new commit from existing commits"
msgstr "СХОВ-ПР [ПОС-ПР]… - створити новий внесок на основі наявних внесків"

#: app/flatpak-builtins-build-commit-from.c:285
msgid "DST-REPO must be specified"
msgstr "Слід вказати СХОВ-ПР"

#: app/flatpak-builtins-build-commit-from.c:293
msgid ""
"If --src-repo is not specified, exactly one destination ref must be specified"
msgstr ""
"Якщо не вказано --src-repo, має бути вказано точно одне посилання призначення"

#: app/flatpak-builtins-build-commit-from.c:296
msgid ""
"If --src-ref is specified, exactly one destination ref must be specified"
msgstr ""
"Якщо вказано --src-ref, має бути вказано точно одне посилання призначення"

#: app/flatpak-builtins-build-commit-from.c:299
msgid "Either --src-repo or --src-ref must be specified"
msgstr "Слід вказати або --src-repo, або --src-ref"

#: app/flatpak-builtins-build-commit-from.c:315
msgid "Invalid argument format of use  --end-of-life-rebase=OLDID=NEWID"
msgstr ""
"Некоректний формат аргументу для використання  --end-of-life-"
"rebase=СТАРИЙІД=НОВИЙІД"

#: app/flatpak-builtins-build-commit-from.c:321
#: app/flatpak-builtins-build-commit-from.c:324
#, c-format
msgid "Invalid name %s in --end-of-life-rebase"
msgstr "Некоректна назва %s у --end-of-life-rebase"

#: app/flatpak-builtins-build-commit-from.c:333
#: app/flatpak-builtins-build-export.c:1092
#, c-format
msgid "Could not parse '%s'"
msgstr "Не вдалося обробити «%s»"

#: app/flatpak-builtins-build-commit-from.c:498
msgid "Can't commit from partial source commit"
msgstr "Неможливо створити внесок на основі часткового внеску до джерела"

#: app/flatpak-builtins-build-commit-from.c:503
#, c-format
msgid "%s: no change\n"
msgstr "%s: без змін\n"

#: app/flatpak-builtins-build-export.c:62
msgid "Architecture to export for (must be host compatible)"
msgstr "Архітектура експортування (має бути сумісною із основною системою)"

#: app/flatpak-builtins-build-export.c:63
msgid "Commit runtime (/usr), not /app"
msgstr "Записати до середовища виконання (/usr), а не до /app"

#: app/flatpak-builtins-build-export.c:66
msgid "Use alternative directory for the files"
msgstr "Використовувати альтернативний каталог для файлів"

#: app/flatpak-builtins-build-export.c:66
msgid "SUBDIR"
msgstr "ПІДКАТАЛОГ"

#: app/flatpak-builtins-build-export.c:69
msgid "Files to exclude"
msgstr "Файли для виключення"

#: app/flatpak-builtins-build-export.c:69
#: app/flatpak-builtins-build-export.c:70
#: app/flatpak-builtins-build-update-repo.c:90
msgid "PATTERN"
msgstr "ЗРАЗОК"

#: app/flatpak-builtins-build-export.c:70
msgid "Excluded files to include"
msgstr "Виключені файли для включення"

#: app/flatpak-builtins-build-export.c:74
msgid "Mark build as end-of-life, to be replaced with the given ID"
msgstr ""
"Позначити збірку як застарілу, щоб її було замінено збіркою із вказаним "
"ідентифікатором"

#: app/flatpak-builtins-build-export.c:74
#: app/flatpak-builtins-document-list.c:49 app/flatpak-cli-transaction.c:1427
msgid "ID"
msgstr "ІД"

#: app/flatpak-builtins-build-export.c:76
msgid "Override the timestamp of the commit"
msgstr "Перевизначити часову позначку внеску"

#: app/flatpak-builtins-build-export.c:77
#: app/flatpak-builtins-build-update-repo.c:75
#: app/flatpak-builtins-remote-add.c:83 app/flatpak-builtins-remote-list.c:54
#: app/flatpak-builtins-remote-modify.c:88
msgid "Collection ID"
msgstr "Ідентифікатор збірки"

#: app/flatpak-builtins-build-export.c:472
#, c-format
msgid "WARNING: Error running desktop-file-validate: %s\n"
msgstr ""
"ПОПЕРЕДЖЕННЯ: помилка під час спроби виконати desktop-file-validate: %s\n"

#: app/flatpak-builtins-build-export.c:480
#, c-format
msgid "WARNING: Error reading from desktop-file-validate: %s\n"
msgstr ""
"ПОПЕРЕДЖЕННЯ: помилка під час спроби прочитати дані від desktop-file-"
"validate: %s\n"

#: app/flatpak-builtins-build-export.c:486
#, c-format
msgid "WARNING: Failed to validate desktop file %s: %s\n"
msgstr "ПОПЕРЕДЖЕННЯ: не вдалося перевірити файл desktop %s: %s\n"

#: app/flatpak-builtins-build-export.c:513
#, c-format
msgid "WARNING: Can't find Exec key in %s: %s\n"
msgstr "ПОПЕРЕДЖЕННЯ: не вдалося знайти ключ Exec у %s: %s\n"

#: app/flatpak-builtins-build-export.c:521
#: app/flatpak-builtins-build-export.c:614
#, c-format
msgid "WARNING: Binary not found for Exec line in %s: %s\n"
msgstr "ПОПЕРЕДЖЕННЯ: не знайдено виконуваного файла для рядка Exec у %s: %s\n"

#: app/flatpak-builtins-build-export.c:529
#, c-format
msgid "WARNING: Icon not matching app id in %s: %s\n"
msgstr ""
"ПОПЕРЕДЖЕННЯ: піктограма не відповідає ідентифікатору програми у %s: %s\n"

#: app/flatpak-builtins-build-export.c:552
#, c-format
msgid "WARNING: Icon referenced in desktop file but not exported: %s\n"
msgstr ""
"ПОПЕРЕДЖЕННЯ: у файлі desktop є посилання на піктограму, але її не "
"експортовано: %s\n"

#: app/flatpak-builtins-build-export.c:719
#, c-format
msgid "Invalid uri type %s, only http/https supported"
msgstr "Некоректний тип адреси %s, передбачено підтримку лише http/https"

#: app/flatpak-builtins-build-export.c:737
#, c-format
msgid "Unable to find basename in %s, specify a name explicitly"
msgstr "Не вдалося знайти базову назву у %s, вкажіть назву явним чином"

#: app/flatpak-builtins-build-export.c:746
#, c-format
msgid "No slashes allowed in extra data name"
msgstr "У назві додаткових даних не можна використовувати навскісні риски"

#: app/flatpak-builtins-build-export.c:758
#, c-format
msgid "Invalid format for sha256 checksum: '%s'"
msgstr "Некоректний формат контрольної суми sha256: «%s»"

#: app/flatpak-builtins-build-export.c:768
#, c-format
msgid "Extra data sizes of zero not supported"
msgstr "Підтримки нульових розмірів додаткових даних не передбачено"

#: app/flatpak-builtins-build-export.c:830
msgid ""
"LOCATION DIRECTORY [BRANCH] - Create a repository from a build directory"
msgstr ""
"РОЗТАШУВАННЯ КАТАЛОГ [ГІЛКА] - Створити сховище на основі каталогу збирання"

#: app/flatpak-builtins-build-export.c:838
msgid "LOCATION and DIRECTORY must be specified"
msgstr "Слід вказати РОЗТАШУВАННЯ і КАТАЛОГ"

#: app/flatpak-builtins-build-export.c:859
#: app/flatpak-builtins-remote-add.c:327
#, c-format
msgid "‘%s’ is not a valid collection ID: %s"
msgstr "«%s» не є коректним ідентифікатором збірки: %s"

#: app/flatpak-builtins-build-export.c:904
#: app/flatpak-builtins-build-finish.c:684
msgid "No name specified in the metadata"
msgstr "У метаданих не вказано назви"

#: app/flatpak-builtins-build-export.c:1166
#, c-format
msgid "Commit: %s\n"
msgstr "Внесок: %s\n"

#: app/flatpak-builtins-build-export.c:1167
#, c-format
msgid "Metadata Total: %u\n"
msgstr "Загалом метаданих: %u\n"

#: app/flatpak-builtins-build-export.c:1168
#, c-format
msgid "Metadata Written: %u\n"
msgstr "Записано метаданих: %u\n"

#: app/flatpak-builtins-build-export.c:1169
#, c-format
msgid "Content Total: %u\n"
msgstr "Загалом даних: %u\n"

#: app/flatpak-builtins-build-export.c:1170
#, c-format
msgid "Content Written: %u\n"
msgstr "Записано даних: %u\n"

#: app/flatpak-builtins-build-export.c:1171
#, c-format
msgid "Content Bytes Written:"
msgstr "Записано байтів даних:"

#: app/flatpak-builtins-build-finish.c:52
msgid "Command to set"
msgstr "Команда для встановлення"

#: app/flatpak-builtins-build-finish.c:52 app/flatpak-builtins-run.c:159
#: app/flatpak-main.c:209
msgid "COMMAND"
msgstr "КОМАНДА"

#: app/flatpak-builtins-build-finish.c:53
msgid "Flatpak version to require"
msgstr "Версія Flatpak, яку слід вимагати"

#: app/flatpak-builtins-build-finish.c:53
msgid "MAJOR.MINOR.MICRO"
msgstr "ОСНОВНА.ДРУГОРЯДНА.ТРЕТЬОРЯДНА"

#: app/flatpak-builtins-build-finish.c:54
msgid "Don't process exports"
msgstr "Не обробляти експортування"

#: app/flatpak-builtins-build-finish.c:55
msgid "Extra data info"
msgstr "Відомості щодо додаткових даних"

#: app/flatpak-builtins-build-finish.c:56 app/flatpak-builtins-build-init.c:63
msgid "Add extension point info"
msgstr "Додати дані щодо точки розширення"

#: app/flatpak-builtins-build-finish.c:56 app/flatpak-builtins-build-init.c:63
msgid "NAME=VARIABLE[=VALUE]"
msgstr "НАЗВА=ЗМІННА[=ЗНАЧЕННЯ]"

#: app/flatpak-builtins-build-finish.c:57
msgid "Remove extension point info"
msgstr "Вилучити дані щодо точки розширення"

#: app/flatpak-builtins-build-finish.c:57
#: app/flatpak-builtins-build-update-repo.c:79 app/flatpak-builtins-info.c:58
#: app/flatpak-builtins-remote-add.c:88 app/flatpak-builtins-remote-modify.c:94
#: app/flatpak-main.c:182
msgid "NAME"
msgstr "НАЗВА"

#: app/flatpak-builtins-build-finish.c:58
msgid "Set extension priority (only for extensions)"
msgstr "Встановити пріоритетність розширення (лише для розширень)"

#: app/flatpak-builtins-build-finish.c:58
msgid "VALUE"
msgstr "ЗНАЧЕННЯ"

#: app/flatpak-builtins-build-finish.c:59
msgid "Change the sdk used for the app"
msgstr "Змінити sdk, що використовується для програми"

#: app/flatpak-builtins-build-finish.c:59
msgid "SDK"
msgstr "SDK"

#: app/flatpak-builtins-build-finish.c:60
msgid "Change the runtime used for the app"
msgstr "Змінити середовище виконання, що використовується для програми"

#: app/flatpak-builtins-build-finish.c:60 app/flatpak-builtins-build-init.c:54
#: app/flatpak-builtins-list.c:53 app/flatpak-builtins-remote-ls.c:58
#: app/flatpak-builtins-run.c:163
msgid "RUNTIME"
msgstr "СЕРЕДОВИЩЕ ВИКОНАННЯ"

#: app/flatpak-builtins-build-finish.c:61
msgid "Set generic metadata option"
msgstr "Встановити параметр загальних метаданих"

#: app/flatpak-builtins-build-finish.c:61
msgid "GROUP=KEY[=VALUE]"
msgstr "ГРУПА=КЛЮЧ[=ЗНАЧЕННЯ]"

#: app/flatpak-builtins-build-finish.c:62
msgid "Don't inherit permissions from runtime"
msgstr "Не успадковувати права доступу з середовища виконання"

#: app/flatpak-builtins-build-finish.c:155
#, c-format
msgid "Not exporting %s, wrong extension\n"
msgstr "Не експортуємо %s, помилковий суфікс\n"

#: app/flatpak-builtins-build-finish.c:163
#, c-format
msgid "Not exporting %s, non-allowed export filename\n"
msgstr "Не експортуємо %s, заборонена назва файла експортування\n"

#: app/flatpak-builtins-build-finish.c:167
#, c-format
msgid "Exporting %s\n"
msgstr "Експортуємо %s\n"

#: app/flatpak-builtins-build-finish.c:440
#, c-format
msgid "More than one executable found\n"
msgstr "Знайдено декілька виконуваних файлів\n"

#: app/flatpak-builtins-build-finish.c:451
#, c-format
msgid "Using %s as command\n"
msgstr "Використовуємо як команду %s\n"

#: app/flatpak-builtins-build-finish.c:456
#, c-format
msgid "No executable found\n"
msgstr "Не знайдено виконуваного файла\n"

#: app/flatpak-builtins-build-finish.c:511
#, c-format
msgid "Invalid --require-version argument: %s"
msgstr "Некоректний аргумент --require-version: %s"

#: app/flatpak-builtins-build-finish.c:543
#, c-format
msgid "Too few elements in --extra-data argument %s"
msgstr "Замало елементів у аргументі --extra-data %s"

#: app/flatpak-builtins-build-finish.c:575
#, c-format
msgid ""
"Too few elements in --metadata argument %s, format should be "
"GROUP=KEY[=VALUE]]"
msgstr ""
"Замало елементів у аргументі --metadata %s; слід використовувати формат "
"ГРУПА=КЛЮЧ[=ЗНАЧЕННЯ]]"

#: app/flatpak-builtins-build-finish.c:597
#: app/flatpak-builtins-build-init.c:458
#, c-format
msgid ""
"Too few elements in --extension argument %s, format should be "
"NAME=VAR[=VALUE]"
msgstr ""
"Замало елементів у аргументі --extension %s, слід вказувати у форматі "
"НАЗВА=ЗМІННА[=ЗНАЧЕННЯ]"

#: app/flatpak-builtins-build-finish.c:603
#: app/flatpak-builtins-build-init.c:461
#, c-format
msgid "Invalid extension name %s"
msgstr "Некоректна назва розширення %s"

#: app/flatpak-builtins-build-finish.c:646
msgid "DIRECTORY - Finalize a build directory"
msgstr "КАТАЛОГ — завершити обробку каталогу збирання"

#: app/flatpak-builtins-build-finish.c:668
#, c-format
msgid "Build directory %s not initialized"
msgstr "Каталог збирання %s не ініціалізовано"

#: app/flatpak-builtins-build-finish.c:689
#, c-format
msgid "Build directory %s already finalized"
msgstr "Каталог збирання %s вже завершено"

#: app/flatpak-builtins-build-finish.c:702
#, c-format
msgid "Please review the exported files and the metadata\n"
msgstr "Будь ласка, перегляньте експортовані файли і метадані\n"

#: app/flatpak-builtins-build-import-bundle.c:47
msgid "Override the ref used for the imported bundle"
msgstr "Перевизначити посилання, використане для імпортованого пакунка"

#: app/flatpak-builtins-build-import-bundle.c:47
msgid "REF"
msgstr "ПОСИЛАННЯ"

#: app/flatpak-builtins-build-import-bundle.c:48
msgid "Import oci image instead of flatpak bundle"
msgstr "Імпортувати образ OCI замість пакунка flatpak"

#: app/flatpak-builtins-build-import-bundle.c:77
#: app/flatpak-builtins-build-import-bundle.c:105
#, c-format
msgid "Importing %s (%s)\n"
msgstr "Імпортуємо %s (%s)\n"

#: app/flatpak-builtins-build-import-bundle.c:126
msgid "LOCATION FILENAME - Import a file bundle into a local repository"
msgstr ""
"РОЗТАШУВАННЯ НАЗВА_ФАЙЛА - Імпортувати файловий пакунок до локального сховища"

#: app/flatpak-builtins-build-import-bundle.c:133
msgid "LOCATION and FILENAME must be specified"
msgstr "Слід вказати РОЗТАШУВАННЯ і НАЗВУ ФАЙЛА"

#: app/flatpak-builtins-build-init.c:53 app/flatpak-builtins-info.c:55
#: app/flatpak-builtins-run.c:158
msgid "Arch to use"
msgstr "Архітектура, яку слід використовувати"

#: app/flatpak-builtins-build-init.c:54
msgid "Initialize var from named runtime"
msgstr "Ініціалізувати змінну на основі іменованого середовища виконання"

#: app/flatpak-builtins-build-init.c:55
msgid "Initialize apps from named app"
msgstr "Ініціалізувати програми з названої програми"

#: app/flatpak-builtins-build-init.c:55
msgid "APP"
msgstr "ПРОГРАМА"

#: app/flatpak-builtins-build-init.c:56
msgid "Specify version for --base"
msgstr "Вказати версію для --base"

#: app/flatpak-builtins-build-init.c:56 app/flatpak-builtins-run.c:164
msgid "VERSION"
msgstr "ВЕРСІЯ"

#: app/flatpak-builtins-build-init.c:57
msgid "Include this base extension"
msgstr "Включити це базове розширення"

#: app/flatpak-builtins-build-init.c:57 app/flatpak-builtins-build-init.c:62
msgid "EXTENSION"
msgstr "РОЗШИРЕННЯ"

#: app/flatpak-builtins-build-init.c:58
msgid "Extension tag to use if building extension"
msgstr "Мітка розширення, яку слід використати, якщо збирається розширення"

#: app/flatpak-builtins-build-init.c:58
msgid "EXTENSION_TAG"
msgstr "МІТКА_РОЗШИРЕННЯ"

#: app/flatpak-builtins-build-init.c:59
msgid "Initialize /usr with a writable copy of the sdk"
msgstr "Ініціалізувати /usr придатною до запису копією sdk"

#: app/flatpak-builtins-build-init.c:60
msgid "Specify the build type (app, runtime, extension)"
msgstr ""
"Вказати тип збирання (програма (app), середовище виконання (runtime), "
"розширення (extension))"

#: app/flatpak-builtins-build-init.c:60
msgid "TYPE"
msgstr "ТИП"

#: app/flatpak-builtins-build-init.c:61
msgid "Add a tag"
msgstr "Додати мітку"

#: app/flatpak-builtins-build-init.c:61
msgid "TAG"
msgstr "МІТКА"

#: app/flatpak-builtins-build-init.c:62
msgid "Include this sdk extension in /usr"
msgstr "Включити це розширення середовища програмування до /usr"

#: app/flatpak-builtins-build-init.c:64
msgid "Where to store sdk (defaults to 'usr')"
msgstr "Місце для зберігання sdk (типово «usr»)"

#: app/flatpak-builtins-build-init.c:65
msgid "Re-initialize the sdk/var"
msgstr "Повторно ініціалізувати sdk/var"

#: app/flatpak-builtins-build-init.c:118
#, c-format
msgid "Requested extension %s/%s/%s is only partially installed"
msgstr "Потрібне розширення %s/%s/%s встановлено лише частково"

#: app/flatpak-builtins-build-init.c:147
#, c-format
msgid "Requested extension %s/%s/%s not installed"
msgstr "Бажане розширення %s/%s/%s не встановлено"

#: app/flatpak-builtins-build-init.c:207
msgid ""
"DIRECTORY APPNAME SDK RUNTIME [BRANCH] - Initialize a directory for building"
msgstr ""
"КАТАЛОГ НАЗВА_ПРОГРАМИ SDK СЕРЕДОВИЩЕ_ВИКОНАННЯ [ГІЛКА] - Ініціалізувати "
"каталог для збирання"

#: app/flatpak-builtins-build-init.c:214
msgid "RUNTIME must be specified"
msgstr "Має бути вказано СЕРЕДОВИЩЕ-ВИКОНАННЯ"

#: app/flatpak-builtins-build-init.c:235
#, c-format
msgid "'%s' is not a valid build type name, use app, runtime or extension"
msgstr ""
"«%s» не є коректною назвою типу збирання; коректними є такі назви: app, "
"runtime і extension"

#: app/flatpak-builtins-build-init.c:241 app/flatpak-builtins-override.c:79
#, c-format
msgid "'%s' is not a valid application name: %s"
msgstr "«%s» не є коректною назвою програми: %s"

#: app/flatpak-builtins-build-init.c:295
#, c-format
msgid "Build directory %s already initialized"
msgstr "Каталог збирання %s вже ініціалізовано"

#: app/flatpak-builtins-build-sign.c:42 app/flatpak-builtins-install.c:67
#: app/flatpak-builtins-remote-info.c:54
msgid "Arch to install for"
msgstr "Архітектура для встановлення"

#: app/flatpak-builtins-build-sign.c:43 app/flatpak-builtins-create-usb.c:48
#: app/flatpak-builtins-install.c:74 app/flatpak-builtins-remote-info.c:56
#: app/flatpak-builtins-uninstall.c:58 app/flatpak-builtins-update.c:64
msgid "Look for runtime with the specified name"
msgstr "Шукати середовище виконання із вказаною назвою"

#: app/flatpak-builtins-build-sign.c:66
msgid "LOCATION [ID [BRANCH]] - Sign an application or runtime"
msgstr ""
"РОЗТАШУВАННЯ [ІД [ГІЛКА]]  - Підписати програму або середовище виконання"

#: app/flatpak-builtins-build-sign.c:73
#: app/flatpak-builtins-build-update-repo.c:499
#: app/flatpak-builtins-remote-add.c:320 app/flatpak-builtins-repo.c:739
msgid "LOCATION must be specified"
msgstr "Слід вказати РОЗТАШУВАННЯ"

#: app/flatpak-builtins-build-sign.c:94
msgid "No gpg key ids specified"
msgstr "Не вказано ідентифікаторів ключів GPG"

#: app/flatpak-builtins-build-update-repo.c:68
msgid "Redirect this repo to a new URL"
msgstr "Переспрямувати це сховище на нову адресу"

#: app/flatpak-builtins-build-update-repo.c:69
msgid "A nice name to use for this repository"
msgstr "Зручна назва для цього сховища"

#: app/flatpak-builtins-build-update-repo.c:69
#: app/flatpak-builtins-remote-add.c:77 app/flatpak-builtins-remote-modify.c:82
msgid "TITLE"
msgstr "ЗАГОЛОВОК"

#: app/flatpak-builtins-build-update-repo.c:70
msgid "A one-line comment for this repository"
msgstr "Однорядковий коментар до цього сховища"

#: app/flatpak-builtins-build-update-repo.c:70
#: app/flatpak-builtins-remote-add.c:78 app/flatpak-builtins-remote-modify.c:83
msgid "COMMENT"
msgstr "КОМЕНТАР"

#: app/flatpak-builtins-build-update-repo.c:71
msgid "A full-paragraph description for this repository"
msgstr "Розгорнутий опис цього сховища"

#: app/flatpak-builtins-build-update-repo.c:71
#: app/flatpak-builtins-remote-add.c:79 app/flatpak-builtins-remote-modify.c:84
msgid "DESCRIPTION"
msgstr "ОПИС"

#: app/flatpak-builtins-build-update-repo.c:72
msgid "URL for a website for this repository"
msgstr "Адреса сайта цього сховища"

#: app/flatpak-builtins-build-update-repo.c:73
msgid "URL for an icon for this repository"
msgstr "Адреса піктограми цього сховища"

#: app/flatpak-builtins-build-update-repo.c:74
msgid "Default branch to use for this repository"
msgstr "Типова гілка для цього сховища"

#: app/flatpak-builtins-build-update-repo.c:74
#: app/flatpak-builtins-remote-add.c:82 app/flatpak-builtins-remote-modify.c:87
#: app/flatpak-builtins-repo.c:713 app/flatpak-builtins-repo.c:714
#: app/flatpak-builtins-run.c:161
msgid "BRANCH"
msgstr "ГІЛКА"

#: app/flatpak-builtins-build-update-repo.c:75
#: app/flatpak-builtins-remote-add.c:83 app/flatpak-builtins-remote-modify.c:88
msgid "COLLECTION-ID"
msgstr "ІД-ЗБІРКИ"

#. Translators: A sideload is when you install from a local USB drive rather than the Internet.
#: app/flatpak-builtins-build-update-repo.c:77
msgid ""
"Permanently deploy collection ID to client remote configurations, only for "
"sideload support"
msgstr ""
"Остаточно розгорнути ідентифікатор збірки у налаштуваннях віддалених сховищ "
"клієнта, лише для підтримки локальних вивантажень"

#: app/flatpak-builtins-build-update-repo.c:78
msgid "Permanently deploy collection ID to client remote configurations"
msgstr ""
"Остаточно розгорнути ідентифікатор збірки у налаштуваннях віддалених сховищ "
"клієнта"

#: app/flatpak-builtins-build-update-repo.c:79
msgid "Name of authenticator for this repository"
msgstr "Назва засобу розпізнавання для цього сховища"

#: app/flatpak-builtins-build-update-repo.c:80
msgid "Autoinstall authenticator for this repository"
msgstr "Автоматично встановлювати засіб розпізнавання для цього сховища"

#: app/flatpak-builtins-build-update-repo.c:81
msgid "Don't autoinstall authenticator for this repository"
msgstr "Не встановлювати автоматично засіб розпізнавання для цього сховища"

#: app/flatpak-builtins-build-update-repo.c:82
#: app/flatpak-builtins-remote-add.c:89
msgid "Authenticator option"
msgstr "Параметр засобу розпізнавання"

#: app/flatpak-builtins-build-update-repo.c:82
#: app/flatpak-builtins-remote-add.c:89 app/flatpak-builtins-remote-modify.c:95
msgid "KEY=VALUE"
msgstr "КЛЮЧ=ЗНАЧЕННЯ"

#: app/flatpak-builtins-build-update-repo.c:83
msgid "Import new default GPG public key from FILE"
msgstr "Імпортувати новий типовий відкритий ключ GPG з файла ФАЙЛ"

#: app/flatpak-builtins-build-update-repo.c:84
msgid "GPG Key ID to sign the summary with"
msgstr "Ідентифікатор ключа GPG для підписування резюме"

#: app/flatpak-builtins-build-update-repo.c:86
msgid "Generate delta files"
msgstr "Створити файли різниці"

#: app/flatpak-builtins-build-update-repo.c:88
msgid "Don't update the appstream branch"
msgstr "Не оновлювати гілку appstream"

#: app/flatpak-builtins-build-update-repo.c:89
msgid "Max parallel jobs when creating deltas (default: NUMCPUs)"
msgstr ""
"Максимальна кількість паралельних завдань при створенні різниць (типово: к-"
"ть процесорів)"

#: app/flatpak-builtins-build-update-repo.c:89
msgid "NUM-JOBS"
msgstr "К-ТЬ-ЗАВДАНЬ"

#: app/flatpak-builtins-build-update-repo.c:90
msgid "Don't create deltas matching refs"
msgstr "Не створювати посилань, які пов'язано із різницями"

#: app/flatpak-builtins-build-update-repo.c:91
msgid "Prune unused objects"
msgstr "Вилучити невикористані об’єкти"

#: app/flatpak-builtins-build-update-repo.c:92
msgid "Prune but don't actually remove anything"
msgstr "Очистити, але нічого насправді не вилучати"

#: app/flatpak-builtins-build-update-repo.c:93
msgid "Only traverse DEPTH parents for each commit (default: -1=infinite)"
msgstr ""
"Переносити лише ГЛИБИНУ батьківських елементів для кожного внеску (типово: "
"-1=нескінченна кількість)"

#: app/flatpak-builtins-build-update-repo.c:93
msgid "DEPTH"
msgstr "ГЛИБИНА"

#: app/flatpak-builtins-build-update-repo.c:223
#, c-format
msgid "Generating delta: %s (%.10s)\n"
msgstr "Створюємо різницю: %s (%.10s)\n"

#: app/flatpak-builtins-build-update-repo.c:225
#, c-format
msgid "Generating delta: %s (%.10s-%.10s)\n"
msgstr "Створюємо різницю: %s (%.10s-%.10s)\n"

#: app/flatpak-builtins-build-update-repo.c:233
#, c-format
msgid "Failed to generate delta %s (%.10s): "
msgstr "Не вдалося створити різницю %s (%.10s): "

#: app/flatpak-builtins-build-update-repo.c:236
#, c-format
msgid "Failed to generate delta %s (%.10s-%.10s): "
msgstr "Не вдалося створити різницю %s (%.10s-%.10s): "

#: app/flatpak-builtins-build-update-repo.c:492
msgid "LOCATION - Update repository metadata"
msgstr "РОЗТАШУВАННЯ - Оновити метадані сховища"

#: app/flatpak-builtins-build-update-repo.c:609
#, c-format
msgid "Updating appstream branch\n"
msgstr "Оновлюємо гілку appstream\n"

#: app/flatpak-builtins-build-update-repo.c:638
#, c-format
msgid "Updating summary\n"
msgstr "Оновлюємо резюме\n"

#: app/flatpak-builtins-build-update-repo.c:664
#, c-format
msgid "Total objects: %u\n"
msgstr "Загалом об’єктів: %u\n"

#: app/flatpak-builtins-build-update-repo.c:666
#, c-format
msgid "No unreachable objects\n"
msgstr "Немає недосяжних об’єктів\n"

#: app/flatpak-builtins-build-update-repo.c:668
#, c-format
msgid "Deleted %u objects, %s freed\n"
msgstr "Вилучено %u об’єктів, вивільнено %s\n"

#: app/flatpak-builtins-config.c:41
msgid "List configuration keys and values"
msgstr "Показати список ключів і значень налаштувань"

#: app/flatpak-builtins-config.c:42
msgid "Get configuration for KEY"
msgstr "Отримати налаштування для ключа КЛЮЧ"

#: app/flatpak-builtins-config.c:43
msgid "Set configuration for KEY to VALUE"
msgstr "Встановити налаштовування для ключа КЛЮЧ у значення ЗНАЧЕННЯ"

#: app/flatpak-builtins-config.c:44
msgid "Unset configuration for KEY"
msgstr "Скасувати налаштовування для ключа КЛЮЧ"

#: app/flatpak-builtins-config.c:149
#, c-format
msgid "'%s' does not look like a language/locale code"
msgstr "«%s» не схожий на код мови/локалі"

#: app/flatpak-builtins-config.c:172
#, c-format
msgid "'%s' does not look like a language code"
msgstr "«%s» не схожий на код мови"

#: app/flatpak-builtins-config.c:190
#, fuzzy, c-format
msgid "'%s' is not a valid value (use 'true' or 'false')"
msgstr "«%s» не є коректним сховищем:"

#: app/flatpak-builtins-config.c:262
#, c-format
msgid "Unknown configure key '%s'"
msgstr "Невідомий ключ налаштовування «%s»"

#: app/flatpak-builtins-config.c:284
msgid "Too many arguments for --list"
msgstr "Забагато аргументів до --list"

#: app/flatpak-builtins-config.c:314 app/flatpak-builtins-config.c:362
msgid "You must specify KEY"
msgstr "Вам слід вказати КЛЮЧ"

#: app/flatpak-builtins-config.c:316
msgid "Too many arguments for --get"
msgstr "Забагато аргументів до --get"

#: app/flatpak-builtins-config.c:338
msgid "You must specify KEY and VALUE"
msgstr "Вам слід вказати КЛЮЧ і ЗНАЧЕННЯ"

#: app/flatpak-builtins-config.c:340
msgid "Too many arguments for --set"
msgstr "Забагато аргументів до --set"

#: app/flatpak-builtins-config.c:364
msgid "Too many arguments for --unset"
msgstr "Забагато аргументів до --unset"

#: app/flatpak-builtins-config.c:383
msgid "[KEY [VALUE]] - Manage configuration"
msgstr "[КЛЮЧ [ЗНАЧЕННЯ]] - керувати налаштуваннями"

#: app/flatpak-builtins-config.c:394
msgid "Can only use one of --list, --get, --set or --unset"
msgstr ""
"Можна використовувати лише один із таких параметрів: --list, --get, --set "
"або --unset"

#: app/flatpak-builtins-config.c:408
msgid "Must specify one of --list, --get, --set or --unset"
msgstr ""
"Слід вказати один із таких параметрів: --list, --get, --set або --unset"

#: app/flatpak-builtins-create-usb.c:45 app/flatpak-builtins-install.c:75
#: app/flatpak-builtins-remote-info.c:57 app/flatpak-builtins-uninstall.c:59
#: app/flatpak-builtins-update.c:65
msgid "Look for app with the specified name"
msgstr "Шукати програму із вказаною назвою"

#: app/flatpak-builtins-create-usb.c:46
msgid "Arch to copy"
msgstr "Архітектура для копіювання"

#: app/flatpak-builtins-create-usb.c:47
msgid "DEST"
msgstr "ПРИЗН"

#: app/flatpak-builtins-create-usb.c:49
msgid "Allow partial commits in the created repo"
msgstr "Дозволити часткові внески до створеного сховища"

#: app/flatpak-builtins-create-usb.c:125 app/flatpak-builtins-create-usb.c:165
#, c-format
msgid ""
"Warning: Related ref ‘%s’ is partially installed. Use --allow-partial to "
"suppress this message.\n"
msgstr ""
"Попередження: пов'язане посилання «%s» встановлено частково. Скористайтеся "
"параметром --allow-partial, щоб придушити виведення цього повідомлення.\n"

#: app/flatpak-builtins-create-usb.c:158
#, c-format
msgid "Warning: Omitting related ref ‘%s’ because it is not installed.\n"
msgstr ""
"Попередження: пропускаємо пов'язане сховище «%s», оскільки його не "
"встановлено.\n"

#: app/flatpak-builtins-create-usb.c:175
#, c-format
msgid ""
"Warning: Omitting related ref ‘%s’ because its remote ‘%s’ does not have a "
"collection ID set.\n"
msgstr ""
"Попередження: пропускаємо пов'язане сховище «%s», оскільки для його "
"віддаленого сховища «%s» не встановлено ідентифікатор збірки.\n"

#: app/flatpak-builtins-create-usb.c:187
#, c-format
msgid "Warning: Omitting related ref ‘%s’ because it's extra-data.\n"
msgstr ""
"Попередження: пропускаємо пов'язане сховище «%s», оскільки це додаткові "
"дані.\n"

#: app/flatpak-builtins-create-usb.c:262 app/flatpak-builtins-create-usb.c:637
#, c-format
msgid ""
"Remote ‘%s’ does not have a collection ID set, which is required for P2P "
"distribution of ‘%s’."
msgstr ""
"Для віддаленого сховища «%s» не встановлено ідентифікатора збірки, який "
"потрібне для поширення P2P «%s»."

#: app/flatpak-builtins-create-usb.c:272
#, c-format
msgid "Warning: Omitting ref ‘%s’ (runtime of ‘%s’) because it's extra-data.\n"
msgstr ""
"Попередження: пропускаємо пов'язане сховище «%s» (середовище виконання "
"«%s»), оскільки це додаткові дані.\n"

#: app/flatpak-builtins-create-usb.c:484
msgid "MOUNT-PATH [REF…] - Copy apps or runtimes onto removable media"
msgstr ""
"ШЛЯХ-МОНТ СХОВ [СХОВ…] — скопіювати програми або середовища виконання на "
"портативний носій даних"

#: app/flatpak-builtins-create-usb.c:493
msgid "MOUNT-PATH and REF must be specified"
msgstr "Має бути вказано ШЛЯХ-МОНТУВАННЯ і СХОВИЩЕ"

#: app/flatpak-builtins-create-usb.c:607
#, c-format
msgid "Ref ‘%s’ found in multiple installations: %s. You must specify one."
msgstr ""
"Джерело «%s» виявлено у декількох встановленнях: %s. Вам слід вказати одне."

#: app/flatpak-builtins-create-usb.c:620
#, c-format
msgid "Refs must all be in the same installation (found in %s and %s)."
msgstr "Усі сховища мають належати одному встановленню (знайдено у %s і %s)."

#: app/flatpak-builtins-create-usb.c:670
#, c-format
msgid ""
"Warning: Ref ‘%s’ is partially installed. Use --allow-partial to suppress "
"this message.\n"
msgstr ""
"Попередження: посилання «%s» встановлено частково. Скористайтеся параметром "
"--allow-partial, щоб придушити виведення цього повідомлення.\n"

#: app/flatpak-builtins-create-usb.c:681
#, c-format
msgid "Installed ref ‘%s’ is extra-data, and cannot be distributed offline"
msgstr ""
"Встановлене пов'язане сховище «%s» є додатковими даними і не може "
"поширюватися без з'єднання з інтернетом"

#: app/flatpak-builtins-create-usb.c:721
#, c-format
msgid "Warning: Couldn't update repo metadata for remote ‘%s’: %s\n"
msgstr ""
"Попередження: не вдалося оновити метадані сховища для віддаленого сховища "
"«%s»: %s\n"

#: app/flatpak-builtins-create-usb.c:751
#, c-format
msgid "Warning: Couldn't update appstream data for remote ‘%s’ arch ‘%s’: %s\n"
msgstr ""
"Попередження: не вдалося оновити дані appstream для віддаленого сховища "
"«%s», архітектура «%s»: %s\n"

#. Print a warning if both appstream and appstream2 are missing
#: app/flatpak-builtins-create-usb.c:784
#, c-format
msgid ""
"Warning: Couldn't find appstream data for remote ‘%s’ arch ‘%s’: %s; %s\n"
msgstr ""
"Попередження: не вдалося знайти дані appstream для віддаленого сховища «%s», "
"архітектура «%s»: %s; %s\n"

#. Appstream2 is only for efficiency, so just print a debug message
#: app/flatpak-builtins-create-usb.c:790
#, c-format
msgid "Couldn't find appstream2 data for remote ‘%s’ arch ‘%s’: %s\n"
msgstr ""
"Не вдалося знайти дані appstream2 для віддаленого сховища «%s», архітектура "
"«%s»: %s\n"

#: app/flatpak-builtins-document-export.c:62
msgid "Create a unique document reference"
msgstr "Створити унікальне посилання на документ"

#: app/flatpak-builtins-document-export.c:63
msgid "Make the document transient for the current session"
msgstr "Зробити документ перехідним для поточного сеансу"

#: app/flatpak-builtins-document-export.c:64
msgid "Don't require the file to exist already"
msgstr "Не вимагати, щоб файл вже існував"

#: app/flatpak-builtins-document-export.c:65
msgid "Give the app read permissions"
msgstr "Надати програмі права доступу до читання"

#: app/flatpak-builtins-document-export.c:66
msgid "Give the app write permissions"
msgstr "Надати програмі права доступу до запису"

#: app/flatpak-builtins-document-export.c:67
msgid "Give the app delete permissions"
msgstr "Надати програмі права доступу до вилучення"

#: app/flatpak-builtins-document-export.c:68
msgid "Give the app permissions to grant further permissions"
msgstr "Надати програмі права доступу на надання подальших прав доступу"

#: app/flatpak-builtins-document-export.c:69
msgid "Revoke read permissions of the app"
msgstr "Відкликати від програми права доступу до читання"

#: app/flatpak-builtins-document-export.c:70
msgid "Revoke write permissions of the app"
msgstr "Відкликати від програми права доступу до запису"

#: app/flatpak-builtins-document-export.c:71
msgid "Revoke delete permissions of the app"
msgstr "Відкликати від програми права доступу до вилучення"

#: app/flatpak-builtins-document-export.c:72
msgid "Revoke the permission to grant further permissions"
msgstr ""
"Відкликати від програми права доступу на надання подальших прав доступу"

#: app/flatpak-builtins-document-export.c:73
msgid "Add permissions for this app"
msgstr "Додати права доступу для цієї програми"

#: app/flatpak-builtins-document-export.c:73
msgid "APPID"
msgstr "ІДЕНТИФІКАТОРПРОГРАМИ"

#: app/flatpak-builtins-document-export.c:100
msgid "FILE - Export a file to apps"
msgstr "ФАЙЛ -  Експортувати файл до програм"

#: app/flatpak-builtins-document-export.c:109
#: app/flatpak-builtins-document-info.c:72
#: app/flatpak-builtins-document-unexport.c:67
msgid "FILE must be specified"
msgstr "Слід вказати ФАЙЛ"

#: app/flatpak-builtins-document-info.c:63
msgid "FILE - Get information about an exported file"
msgstr "ФАЙЛ - Отримати інформацію щодо експортованого файла"

#: app/flatpak-builtins-document-info.c:100
#: app/flatpak-builtins-document-unexport.c:94
#, c-format
msgid "Not exported\n"
msgstr "Не експортовано\n"

#: app/flatpak-builtins-document-list.c:43 app/flatpak-builtins-history.c:53
#: app/flatpak-builtins-list.c:54 app/flatpak-builtins-ps.c:43
#: app/flatpak-builtins-remote-list.c:45 app/flatpak-builtins-remote-ls.c:59
#: app/flatpak-builtins-search.c:38
msgid "What information to show"
msgstr "Які дані слід показувати"

#: app/flatpak-builtins-document-list.c:43 app/flatpak-builtins-history.c:53
#: app/flatpak-builtins-list.c:54 app/flatpak-builtins-ps.c:43
#: app/flatpak-builtins-remote-list.c:45 app/flatpak-builtins-remote-ls.c:59
#: app/flatpak-builtins-search.c:38
msgid "FIELD,…"
msgstr "ПОЛЕ,…"

#: app/flatpak-builtins-document-list.c:44 app/flatpak-builtins-history.c:54
#: app/flatpak-builtins-list.c:52 app/flatpak-builtins-permission-list.c:43
#: app/flatpak-builtins-permission-show.c:43 app/flatpak-builtins-ps.c:44
#: app/flatpak-builtins-remote-list.c:46 app/flatpak-builtins-remote-ls.c:63
#: app/flatpak-builtins-repo.c:717 app/flatpak-builtins-search.c:39
#, fuzzy
msgid "Show output in JSON format"
msgstr "Показати додаткову інформацію"

#: app/flatpak-builtins-document-list.c:49
msgid "Show the document ID"
msgstr "Показати ідентифікатор документа"

#: app/flatpak-builtins-document-list.c:50
msgid "Path"
msgstr "Шлях"

#: app/flatpak-builtins-document-list.c:50
#: app/flatpak-builtins-document-list.c:51
msgid "Show the document path"
msgstr "Показати шлях до документа"

#: app/flatpak-builtins-document-list.c:51 app/flatpak-builtins-list.c:66
#: app/flatpak-builtins-remote-ls.c:74
msgid "Origin"
msgstr "Походження"

#: app/flatpak-builtins-document-list.c:52 app/flatpak-builtins-history.c:62
#: app/flatpak-builtins-ps.c:52
msgid "Application"
msgstr "Програма"

#: app/flatpak-builtins-document-list.c:52
msgid "Show applications with permission"
msgstr "Показати програми із правами доступу"

#: app/flatpak-builtins-document-list.c:53
#: app/flatpak-builtins-permission-list.c:182
#: app/flatpak-builtins-permission-show.c:145
msgid "Permissions"
msgstr "Права доступу"

#: app/flatpak-builtins-document-list.c:53
msgid "Show permissions for applications"
msgstr "Показати права доступу для програм"

#: app/flatpak-builtins-document-list.c:161
#, fuzzy, c-format
msgid "No documents found\n"
msgstr "Відповідників не знайдено"

#: app/flatpak-builtins-document-list.c:180
msgid "[APPID] - List exported files"
msgstr "[ІДЕНТИФІКАТОРПРОГРАМИ] - Вивести список експортованих файлів"

#: app/flatpak-builtins-document-unexport.c:43
msgid "Specify the document ID"
msgstr "Вказати ідентифікатор документа"

#: app/flatpak-builtins-document-unexport.c:58
msgid "FILE - Unexport a file to apps"
msgstr "ФАЙЛ - Скасувати експортування файла до програм"

#: app/flatpak-builtins-enter.c:88
msgid "INSTANCE COMMAND [ARGUMENT…] - Run a command inside a running sandbox"
msgstr "ЕКЗЕМПЛЯР КОМАНДА [АРГУМЕНТ…] — виконати команду у запущеній пісочниці"

#: app/flatpak-builtins-enter.c:111
msgid "INSTANCE and COMMAND must be specified"
msgstr "Слід вказати ЕКЗЕМПЛЯР та КОМАНДУ"

#: app/flatpak-builtins-enter.c:138
#, c-format
msgid "%s is neither a pid nor an application or instance ID"
msgstr ""
"%s не є ні ідентифікатором процесу, ні програмою, ні ідентифікатором "
"екземпляра"

#: app/flatpak-builtins-enter.c:144
msgid "entering not supported (need unprivileged user namespaces, or sudo -E)"
msgstr ""
"підтримки входу не передбачено (потребує непривілейованих просторів назв "
"користувачів або sudo -E)"

#: app/flatpak-builtins-enter.c:145
#, c-format
msgid "No such pid %s"
msgstr "Немає такого pid, %s"

#: app/flatpak-builtins-enter.c:158
msgid "Can't read cwd"
msgstr "Не вдалося прочитати cwd"

#: app/flatpak-builtins-enter.c:163
msgid "Can't read root"
msgstr "Не вдалося прочитати вміст кореневої теки"

#: app/flatpak-builtins-enter.c:191
#, c-format
msgid "Invalid %s namespace for pid %d"
msgstr "Некоректний простір назв %s для pid %d"

#: app/flatpak-builtins-enter.c:202
#, c-format
msgid "Invalid %s namespace for self"
msgstr "Некоректний простір назв %s для self"

#: app/flatpak-builtins-enter.c:216
#, c-format
msgid "Can't open %s namespace: %s"
msgstr "не вдалося відкрити простір назв %s: %s"

#: app/flatpak-builtins-enter.c:226
msgid "entering not supported (need unprivileged user namespaces)"
msgstr ""
"підтримки входу не передбачено (потребує непривілейованих просторів назв "
"користувачів)"

#: app/flatpak-builtins-enter.c:227
#, c-format
msgid "Can't enter %s namespace: %s"
msgstr "Не вдалося увійти до простору назв %s: %s"

#: app/flatpak-builtins-enter.c:234
msgid "Can't chdir"
msgstr "Не вдалося змінити каталог"

#: app/flatpak-builtins-enter.c:237
msgid "Can't chroot"
msgstr "Не вдалося змінити кореневий каталог"

#: app/flatpak-builtins-enter.c:240
msgid "Can't switch gid"
msgstr "Не вдалося перемкнути gid"

#: app/flatpak-builtins-enter.c:243
msgid "Can't switch uid"
msgstr "Не вдалося перемкнути uid"

#: app/flatpak-builtins-history.c:50
msgid "Only show changes after TIME"
msgstr "Показати зміни лише після моменту часу ЧАС"

#: app/flatpak-builtins-history.c:50 app/flatpak-builtins-history.c:51
msgid "TIME"
msgstr "ЧАС"

#: app/flatpak-builtins-history.c:51
msgid "Only show changes before TIME"
msgstr "Показати зміни лише до моменту часу ЧАС"

#: app/flatpak-builtins-history.c:52
msgid "Show newest entries first"
msgstr "Показати найновіші записи першими"

#: app/flatpak-builtins-history.c:59
msgid "Time"
msgstr "Час"

#: app/flatpak-builtins-history.c:59
msgid "Show when the change happened"
msgstr "Показувати, якщо було внесено зміну"

#: app/flatpak-builtins-history.c:60
msgid "Change"
msgstr "Зміна"

#: app/flatpak-builtins-history.c:60
msgid "Show the kind of change"
msgstr "Показати тип зміни"

#: app/flatpak-builtins-history.c:61 app/flatpak-builtins-list.c:68
#: app/flatpak-builtins-remote-ls.c:75 app/flatpak-builtins-repo.c:335
msgid "Ref"
msgstr "Джерело"

#: app/flatpak-builtins-history.c:61 app/flatpak-builtins-list.c:68
#: app/flatpak-builtins-remote-ls.c:75
msgid "Show the ref"
msgstr "Показати сховище"

#: app/flatpak-builtins-history.c:62
msgid "Show the application/runtime ID"
msgstr "Показати ідентифікатор програми або середовища виконання"

#: app/flatpak-builtins-history.c:63 app/flatpak-builtins-list.c:64
#: app/flatpak-builtins-ps.c:53 app/flatpak-builtins-remote-ls.c:73
#: app/flatpak-cli-transaction.c:1435
msgid "Arch"
msgstr "Архітектура"

#: app/flatpak-builtins-history.c:63 app/flatpak-builtins-list.c:64
#: app/flatpak-builtins-ps.c:53 app/flatpak-builtins-remote-ls.c:73
msgid "Show the architecture"
msgstr "Показати архітектуру"

#: app/flatpak-builtins-history.c:64 app/flatpak-builtins-list.c:63
#: app/flatpak-builtins-ps.c:54 app/flatpak-builtins-remote-ls.c:72
#: app/flatpak-builtins-search.c:48 app/flatpak-cli-transaction.c:1438
msgid "Branch"
msgstr "Гілка"

#: app/flatpak-builtins-history.c:64 app/flatpak-builtins-list.c:63
#: app/flatpak-builtins-remote-ls.c:72
msgid "Show the branch"
msgstr "Показати гілку"

#: app/flatpak-builtins-history.c:65 app/flatpak-builtins-list.c:67
msgid "Installation"
msgstr "Встановлення"

#: app/flatpak-builtins-history.c:65
msgid "Show the affected installation"
msgstr "Показати відповідне встановлення"

#: app/flatpak-builtins-history.c:66 app/flatpak-cli-transaction.c:1452
msgid "Remote"
msgstr "Віддалене сховище"

#: app/flatpak-builtins-history.c:66
msgid "Show the remote"
msgstr "Показати віддалене сховище"

#: app/flatpak-builtins-history.c:67 app/flatpak-builtins-ps.c:55
#: app/flatpak-builtins-remote-ls.c:76
msgid "Commit"
msgstr "Внесок"

#: app/flatpak-builtins-history.c:67
msgid "Show the current commit"
msgstr "Показати поточний внесок"

#: app/flatpak-builtins-history.c:68
msgid "Old Commit"
msgstr "Старий внесок"

#: app/flatpak-builtins-history.c:68
msgid "Show the previous commit"
msgstr "Показати попередній внесок"

#: app/flatpak-builtins-history.c:69
msgid "Show the remote URL"
msgstr "Показати адресу віддаленого сховища"

#: app/flatpak-builtins-history.c:70 app/flatpak-cli-transaction.c:700
msgid "User"
msgstr "Користувач"

#: app/flatpak-builtins-history.c:70
msgid "Show the user doing the change"
msgstr "Показати користувача, яким було внесено зміну"

#: app/flatpak-builtins-history.c:71
msgid "Tool"
msgstr "Інструмент"

#: app/flatpak-builtins-history.c:71
msgid "Show the tool that was used"
msgstr "Показати інструмент, який було використано"

#: app/flatpak-builtins-history.c:72 app/flatpak-builtins-list.c:62
#: app/flatpak-builtins-remote-ls.c:71 app/flatpak-builtins-search.c:47
msgid "Version"
msgstr "Версія"

#: app/flatpak-builtins-history.c:72
msgid "Show the Flatpak version"
msgstr "Показати версію Flatpak"

#: app/flatpak-builtins-history.c:91
#, c-format
msgid "Failed to get journal data (%s): %s"
msgstr "Не вдалося отримати дані журналу (%s): %s"

#: app/flatpak-builtins-history.c:146
#, c-format
msgid "Failed to open journal: %s"
msgstr "Не вдалося відкрити журнал: %s"

#: app/flatpak-builtins-history.c:153
#, c-format
msgid "Failed to add match to journal: %s"
msgstr "Не вдалося додати відповідність до журналу: %s"

#: app/flatpak-builtins-history.c:471
msgid " - Show history"
msgstr " - Показати журнал"

#: app/flatpak-builtins-history.c:490
#, c-format
msgid "Failed to parse the --since option"
msgstr "Не вдало обробити параметр --since"

#: app/flatpak-builtins-history.c:501
#, c-format
msgid "Failed to parse the --until option"
msgstr "Не вдало обробити параметр --until"

#: app/flatpak-builtins-info.c:56
msgid "Show user installations"
msgstr "Показати встановлення користувача"

#: app/flatpak-builtins-info.c:57
msgid "Show system-wide installations"
msgstr "Показати загальносистемні встановлення"

#: app/flatpak-builtins-info.c:58
msgid "Show specific system-wide installations"
msgstr "Показати вказані загальносистемні встановлення"

#: app/flatpak-builtins-info.c:59 app/flatpak-builtins-remote-info.c:59
msgid "Show ref"
msgstr "Показати посилання"

#: app/flatpak-builtins-info.c:60 app/flatpak-builtins-remote-info.c:60
msgid "Show commit"
msgstr "Показати внесок"

#: app/flatpak-builtins-info.c:61
msgid "Show origin"
msgstr "Показ початку координат"

#: app/flatpak-builtins-info.c:62
msgid "Show size"
msgstr "Показ розміру"

#: app/flatpak-builtins-info.c:63 app/flatpak-builtins-remote-info.c:62
msgid "Show metadata"
msgstr "Показ метаданих"

#: app/flatpak-builtins-info.c:64 app/flatpak-builtins-remote-info.c:63
msgid "Show runtime"
msgstr "Показ середовища виконання"

#: app/flatpak-builtins-info.c:65 app/flatpak-builtins-remote-info.c:64
msgid "Show sdk"
msgstr "Показ SDK"

#: app/flatpak-builtins-info.c:66
msgid "Show permissions"
msgstr "Показати права доступу"

#: app/flatpak-builtins-info.c:67
msgid "Query file access"
msgstr "Запит щодо доступу до файла"

#: app/flatpak-builtins-info.c:67 app/flatpak-builtins-install.c:82
#: app/flatpak-builtins-install.c:88 app/flatpak-builtins-preinstall.c:68
#: app/flatpak-builtins-run.c:182 app/flatpak-builtins-run.c:184
#: app/flatpak-builtins-update.c:67 app/flatpak-builtins-update.c:71
msgid "PATH"
msgstr "ШЛЯХ"

#: app/flatpak-builtins-info.c:68
msgid "Show extensions"
msgstr "Показати розширення"

#: app/flatpak-builtins-info.c:69
msgid "Show location"
msgstr "Показувати адресу"

#: app/flatpak-builtins-info.c:116
msgid "NAME [BRANCH] - Get info about an installed app or runtime"
msgstr ""
"НАЗВА [ГІЛКА] - Отримати інформацію щодо встановленої програми або "
"середовища виконання"

#: app/flatpak-builtins-info.c:123 app/flatpak-builtins-remote-add.c:317
#: app/flatpak-builtins-remote-delete.c:63
msgid "NAME must be specified"
msgstr "Має бути вказано НАЗВУ"

#: app/flatpak-builtins-info.c:196
msgid "ref not present in origin"
msgstr "посилання немає у джерелі"

#: app/flatpak-builtins-info.c:211 app/flatpak-builtins-remote-info.c:217
#, c-format
msgid "Warning: Commit has no flatpak metadata\n"
msgstr "Попередження: у внеску немає метаданих flatpak\n"

#: app/flatpak-builtins-info.c:217 app/flatpak-builtins-info.c:259
#: app/flatpak-builtins-info.c:455 app/flatpak-builtins-info.c:513
#: app/flatpak-builtins-remote-info.c:236
#: app/flatpak-builtins-remote-info.c:271
msgid "ID:"
msgstr "Ід.:"

#: app/flatpak-builtins-info.c:218 app/flatpak-builtins-info.c:260
#: app/flatpak-builtins-remote-info.c:237
#: app/flatpak-builtins-remote-info.c:272
msgid "Ref:"
msgstr "Джерело:"

#: app/flatpak-builtins-info.c:219 app/flatpak-builtins-info.c:261
#: app/flatpak-builtins-remote-info.c:238
#: app/flatpak-builtins-remote-info.c:273
msgid "Arch:"
msgstr "Арх.:"

#: app/flatpak-builtins-info.c:220 app/flatpak-builtins-info.c:262
#: app/flatpak-builtins-remote-info.c:239
#: app/flatpak-builtins-remote-info.c:274
msgid "Branch:"
msgstr "Гілка:"

#: app/flatpak-builtins-info.c:222 app/flatpak-builtins-info.c:264
#: app/flatpak-builtins-remote-info.c:241
#: app/flatpak-builtins-remote-info.c:276
msgid "Version:"
msgstr "Версія:"

#: app/flatpak-builtins-info.c:224 app/flatpak-builtins-info.c:266
#: app/flatpak-builtins-remote-info.c:243
#: app/flatpak-builtins-remote-info.c:278
msgid "License:"
msgstr "Ліцензування:"

#: app/flatpak-builtins-info.c:226 app/flatpak-builtins-info.c:269
#: app/flatpak-builtins-remote-info.c:245
#: app/flatpak-builtins-remote-info.c:280
msgid "Collection:"
msgstr "Збірка:"

#: app/flatpak-builtins-info.c:227 app/flatpak-builtins-info.c:270
#: app/flatpak-builtins-info.c:458 app/flatpak-builtins-info.c:516
msgid "Installation:"
msgstr "Встановлення:"

#: app/flatpak-builtins-info.c:228 app/flatpak-builtins-info.c:271
#: app/flatpak-builtins-info.c:459 app/flatpak-builtins-info.c:517
#: app/flatpak-builtins-remote-info.c:249
#: app/flatpak-builtins-remote-info.c:284
#, fuzzy
msgid "Installed Size:"
msgstr "Розмір встановленого"

#: app/flatpak-builtins-info.c:231 app/flatpak-builtins-info.c:279
#: app/flatpak-builtins-remote-info.c:252
#: app/flatpak-builtins-remote-info.c:288
msgid "Runtime:"
msgstr "Середовище виконання:"

#: app/flatpak-builtins-info.c:232 app/flatpak-builtins-info.c:288
#: app/flatpak-builtins-remote-info.c:253
#: app/flatpak-builtins-remote-info.c:293
msgid "Sdk:"
msgstr "Sdk:"

#: app/flatpak-builtins-info.c:235 app/flatpak-builtins-info.c:313
#: app/flatpak-builtins-remote-info.c:256
#: app/flatpak-builtins-remote-info.c:319
msgid "Date:"
msgstr "Дата:"

#: app/flatpak-builtins-info.c:237 app/flatpak-builtins-info.c:311
#: app/flatpak-builtins-remote-info.c:258
#: app/flatpak-builtins-remote-info.c:317
msgid "Subject:"
msgstr "Тема:"

#: app/flatpak-builtins-info.c:240 app/flatpak-builtins-info.c:295
msgid "Active commit:"
msgstr "Активний внесок:"

#: app/flatpak-builtins-info.c:241 app/flatpak-builtins-info.c:298
msgid "Latest commit:"
msgstr "Останній внесок:"

#: app/flatpak-builtins-info.c:244 app/flatpak-builtins-info.c:303
#: app/flatpak-builtins-info.c:457 app/flatpak-builtins-info.c:515
#: app/flatpak-builtins-remote-info.c:259
#: app/flatpak-builtins-remote-info.c:298
msgid "Commit:"
msgstr "Внесок:"

#: app/flatpak-builtins-info.c:246 app/flatpak-builtins-info.c:308
#: app/flatpak-builtins-remote-info.c:261
#: app/flatpak-builtins-remote-info.c:303
msgid "Parent:"
msgstr "Батьківський:"

#: app/flatpak-builtins-info.c:248 app/flatpak-builtins-info.c:321
msgid "Alt-id:"
msgstr "Альт-ід.:"

#: app/flatpak-builtins-info.c:250 app/flatpak-builtins-info.c:325
#: app/flatpak-builtins-remote-info.c:263
#: app/flatpak-builtins-remote-info.c:308
msgid "End-of-life:"
msgstr "Термін дії:"

#: app/flatpak-builtins-info.c:252 app/flatpak-builtins-info.c:330
#: app/flatpak-builtins-remote-info.c:265
#: app/flatpak-builtins-remote-info.c:313
msgid "End-of-life-rebase:"
msgstr "End-of-life-rebase:"

#: app/flatpak-builtins-info.c:254 app/flatpak-builtins-info.c:317
msgid "Subdirectories:"
msgstr "Підкаталоги:"

#: app/flatpak-builtins-info.c:255 app/flatpak-builtins-info.c:454
#: app/flatpak-builtins-info.c:512
msgid "Extension:"
msgstr "Суфікс:"

#: app/flatpak-builtins-info.c:267 app/flatpak-builtins-info.c:456
#: app/flatpak-builtins-info.c:514
msgid "Origin:"
msgstr "Походження:"

#: app/flatpak-builtins-info.c:460 app/flatpak-builtins-info.c:522
msgid "Subpaths:"
msgstr "Підшляхи:"

#: app/flatpak-builtins-info.c:478
msgid "unmaintained"
msgstr "немає супроводу"

#: app/flatpak-builtins-info.c:480 app/flatpak-builtins-info.c:482
msgid "unknown"
msgstr "невідомий"

#: app/flatpak-builtins-install.c:68 app/flatpak-builtins-preinstall.c:57
msgid "Don't pull, only install from local cache"
msgstr "Не отримувати зі сховища, встановити лише з локального кешу"

#: app/flatpak-builtins-install.c:69 app/flatpak-builtins-preinstall.c:58
#: app/flatpak-builtins-update.c:60
msgid "Don't deploy, only download to local cache"
msgstr "Не розгортати, лише отримати дані до локального кешу"

#: app/flatpak-builtins-install.c:70 app/flatpak-builtins-preinstall.c:59
msgid "Don't install related refs"
msgstr "Не встановлювати пов’язані посилання"

#: app/flatpak-builtins-install.c:71 app/flatpak-builtins-preinstall.c:60
#: app/flatpak-builtins-update.c:62
msgid "Don't verify/install runtime dependencies"
msgstr "Не перевіряти або не встановлювати залежності для виконання"

#: app/flatpak-builtins-install.c:72
msgid "Don't automatically pin explicit installs"
msgstr "Не пришпилювати автоматично явні встановлення"

#: app/flatpak-builtins-install.c:73 app/flatpak-builtins-preinstall.c:61
#: app/flatpak-builtins-update.c:63
msgid "Don't use static deltas"
msgstr "Не використовувати статичні різниці"

#: app/flatpak-builtins-install.c:76 app/flatpak-builtins-preinstall.c:62
msgid "Additionally install the SDK used to build the given refs"
msgstr ""
"Додатково встановити SDK, який використано для збирання вказаних посилань"

#: app/flatpak-builtins-install.c:77 app/flatpak-builtins-preinstall.c:63
msgid ""
"Additionally install the debug info for the given refs and their dependencies"
msgstr ""
"Додатково встановити діагностичні дані для вказаних посилань та їхніх "
"залежностей"

#: app/flatpak-builtins-install.c:78
msgid "Assume LOCATION is a .flatpak single-file bundle"
msgstr "Вважати значенням параметра МІСЦЕ однофайловий пакунок .flatpak"

#: app/flatpak-builtins-install.c:79
msgid "Assume LOCATION is a .flatpakref application description"
msgstr "Вважати значенням параметра МІСЦЕ опис програми .flatpakref"

#: app/flatpak-builtins-install.c:80
msgid "Assume LOCATION is containers-transports(5) reference to an OCI image"
msgstr ""

#: app/flatpak-builtins-install.c:81
msgid "Check bundle signatures with GPG key from FILE (- for stdin)"
msgstr ""
"Перевірити підписи пакунків за допомогою ключа GPG з ФАЙЛА (- якщо слід дані "
"слід взяти з stdin)"

#: app/flatpak-builtins-install.c:82
msgid "Only install this subpath"
msgstr "Встановити лише цей підшлях"

#: app/flatpak-builtins-install.c:83 app/flatpak-builtins-preinstall.c:64
#: app/flatpak-builtins-uninstall.c:63 app/flatpak-builtins-update.c:68
msgid "Automatically answer yes for all questions"
msgstr "Автоматично відповідати «так» на усі питання"

#: app/flatpak-builtins-install.c:84 app/flatpak-builtins-preinstall.c:65
msgid "Uninstall first if already installed"
msgstr "Спочатку вилучити, якщо вже встановлено"

#: app/flatpak-builtins-install.c:85 app/flatpak-builtins-preinstall.c:66
#: app/flatpak-builtins-uninstall.c:64 app/flatpak-builtins-update.c:69
msgid "Produce minimal output and don't ask questions"
msgstr "Мінімізувати виведення даних і не задавати питань"

#: app/flatpak-builtins-install.c:86
msgid "Update install if already installed"
msgstr "Оновити встановлене, якщо вже встановлено"

#. Translators: A sideload is when you install from a local USB drive rather than the Internet.
#: app/flatpak-builtins-install.c:88 app/flatpak-builtins-preinstall.c:68
#: app/flatpak-builtins-update.c:71
msgid "Use this local repo for sideloads"
msgstr "Використовувати це локальне сховище для локальних вивантажень"

#: app/flatpak-builtins-install.c:178
msgid "Bundle filename must be specified"
msgstr "Слід вказати назву файла пакунка"

#: app/flatpak-builtins-install.c:188
msgid "Remote bundles are not supported"
msgstr "Підтримки віддалених пакунків не передбачено"

#: app/flatpak-builtins-install.c:231
msgid "Filename or uri must be specified"
msgstr "Слід вказати назву файла або адресу"

#: app/flatpak-builtins-install.c:295
#, fuzzy
msgid "Image location must be specified"
msgstr "Слід вказати принаймні одне значення НАЗВА"

#: app/flatpak-builtins-install.c:345
msgid "[LOCATION/REMOTE] [REF…] - Install applications or runtimes"
msgstr ""
"[МІСЦЕ/СХОВИЩЕ] [НАЗВА…] - Встановити програму або середовища виконання"

#: app/flatpak-builtins-install.c:378
msgid "At least one REF must be specified"
msgstr "Слід вказати принаймні одне значення НАЗВА"

#: app/flatpak-builtins-install.c:392
#, c-format
msgid "Looking for matches…\n"
msgstr "Шукаємо відповідники…\n"

#: app/flatpak-builtins-install.c:513
#, c-format
msgid "No remote refs found for ‘%s’"
msgstr "Не знайдено віддалених посилань для «%s»"

#: app/flatpak-builtins-install.c:573 app/flatpak-builtins-uninstall.c:405
#: common/flatpak-ref-utils.c:689 common/flatpak-ref-utils.c:1595
#, c-format
msgid "Invalid branch %s: %s"
msgstr "Некоректна гілка %s: %s"

#: app/flatpak-builtins-install.c:606
#, c-format
msgid "Nothing matches %s in local repository for remote %s"
msgstr "Не знайдено локальних відповідників %s для віддаленого сховища %s"

#: app/flatpak-builtins-install.c:608
#, c-format
msgid "Nothing matches %s in remote %s"
msgstr "Не знайдено локальних відповідників %s у віддаленому сховищі %s"

#: app/flatpak-builtins-install.c:629
#, c-format
msgid "Skipping: %s\n"
msgstr "Пропускаємо: %s\n"

#: app/flatpak-builtins-kill.c:110
#, c-format
msgid "%s is not running"
msgstr "%s не запущено"

#: app/flatpak-builtins-kill.c:136
msgid "INSTANCE - Stop a running application"
msgstr "ЕКЗЕМПЛЯР — припинити роботу запущеної програми"

#: app/flatpak-builtins-kill.c:144 app/flatpak-builtins-ps.c:256
msgid "Extra arguments given"
msgstr "Вказано зайві аргументи"

#: app/flatpak-builtins-kill.c:150
msgid "Must specify the app to kill"
msgstr "Слід вказати програму, роботу якої слід завершити"

#: app/flatpak-builtins-list.c:47
msgid "Show extra information"
msgstr "Показати додаткову інформацію"

#: app/flatpak-builtins-list.c:48
msgid "List installed runtimes"
msgstr "Вивести список встановлених середовищ виконання"

#: app/flatpak-builtins-list.c:49
msgid "List installed applications"
msgstr "Вивести список встановлених програм"

#: app/flatpak-builtins-list.c:50
msgid "Arch to show"
msgstr "Архітектура для показу"

#: app/flatpak-builtins-list.c:51 app/flatpak-builtins-remote-ls.c:57
msgid "List all refs (including locale/debug)"
msgstr "Вивести список усіх джерел (включно з locale/debug)"

#: app/flatpak-builtins-list.c:53 app/flatpak-builtins-remote-ls.c:58
msgid "List all applications using RUNTIME"
msgstr "Вивести список усіх програми, де використовується СЕРЕДОВИЩЕ ВИКОНАННЯ"

#: app/flatpak-builtins-list.c:59 app/flatpak-builtins-remote-list.c:51
#: app/flatpak-builtins-remote-ls.c:68 app/flatpak-builtins-search.c:44
msgid "Name"
msgstr "Назва"

#: app/flatpak-builtins-list.c:59 app/flatpak-builtins-remote-list.c:51
#: app/flatpak-builtins-remote-ls.c:68 app/flatpak-builtins-search.c:44
msgid "Show the name"
msgstr "Показати назву"

#: app/flatpak-builtins-list.c:60 app/flatpak-builtins-remote-list.c:60
#: app/flatpak-builtins-remote-ls.c:69 app/flatpak-builtins-search.c:45
msgid "Description"
msgstr "Опис"

#: app/flatpak-builtins-list.c:60 app/flatpak-builtins-remote-ls.c:69
#: app/flatpak-builtins-search.c:45
msgid "Show the description"
msgstr "Показати опис"

#: app/flatpak-builtins-list.c:61 app/flatpak-builtins-remote-ls.c:70
#: app/flatpak-builtins-search.c:46
msgid "Application ID"
msgstr "Ід. програми"

#: app/flatpak-builtins-list.c:61 app/flatpak-builtins-ps.c:52
#: app/flatpak-builtins-remote-ls.c:70 app/flatpak-builtins-search.c:46
msgid "Show the application ID"
msgstr "Показати ідентифікатор програми"

#: app/flatpak-builtins-list.c:62 app/flatpak-builtins-remote-ls.c:71
#: app/flatpak-builtins-search.c:47
msgid "Show the version"
msgstr "Показати версію"

#: app/flatpak-builtins-list.c:65 app/flatpak-builtins-ps.c:56
#: app/flatpak-builtins-remote-ls.c:77
msgid "Runtime"
msgstr "Середовище виконання"

#: app/flatpak-builtins-list.c:65
msgid "Show the used runtime"
msgstr "Показувати використане середовище виконання"

#: app/flatpak-builtins-list.c:66 app/flatpak-builtins-remote-ls.c:74
msgid "Show the origin remote"
msgstr "Показати походження віддаленого сховища"

#: app/flatpak-builtins-list.c:67
msgid "Show the installation"
msgstr "Показати встановлення"

#: app/flatpak-builtins-list.c:69
msgid "Active commit"
msgstr "Активний внесок"

#: app/flatpak-builtins-list.c:69 app/flatpak-builtins-remote-ls.c:76
msgid "Show the active commit"
msgstr "Показати активний внесок"

#: app/flatpak-builtins-list.c:70
msgid "Latest commit"
msgstr "Останній внесок"

#: app/flatpak-builtins-list.c:70
msgid "Show the latest commit"
msgstr "Показати останній внесок"

#: app/flatpak-builtins-list.c:71 app/flatpak-builtins-remote-ls.c:78
msgid "Installed size"
msgstr "Розмір встановленого"

#: app/flatpak-builtins-list.c:71 app/flatpak-builtins-remote-ls.c:78
msgid "Show the installed size"
msgstr "Показати розмір встановленого"

#: app/flatpak-builtins-list.c:72 app/flatpak-builtins-remote-list.c:58
#: app/flatpak-builtins-remote-ls.c:80 app/flatpak-builtins-repo.c:340
msgid "Options"
msgstr "Параметри"

#: app/flatpak-builtins-list.c:72 app/flatpak-builtins-remote-list.c:58
#: app/flatpak-builtins-remote-ls.c:80
msgid "Show options"
msgstr "Показати параметри"

#: app/flatpak-builtins-list.c:180
#, fuzzy, c-format
msgid "Unable to load details of %s: %s"
msgstr "Не вдалося створити файл %s"

#: app/flatpak-builtins-list.c:190
#, fuzzy, c-format
msgid "Unable to inspect current version of %s: %s"
msgstr "Не вдалося створити файл %s"

#: app/flatpak-builtins-list.c:408
msgid " - List installed apps and/or runtimes"
msgstr " - Вивести список встановлених програм і/або середовищ виконання"

#: app/flatpak-builtins-make-current.c:38
msgid "Arch to make current for"
msgstr "Архітектура, яку слід зробити поточною"

#: app/flatpak-builtins-make-current.c:58
msgid "APP BRANCH - Make branch of application current"
msgstr "ПРОГРАМА ГІЛКА - Зробити гілку програми поточною"

#: app/flatpak-builtins-make-current.c:69 app/flatpak-builtins-run.c:260
msgid "APP must be specified"
msgstr "Слід вказати ПРОГРАМУ"

#: app/flatpak-builtins-make-current.c:84
msgid "BRANCH must be specified"
msgstr "Слід вказати ГІЛКУ"

#: app/flatpak-builtins-make-current.c:97
#, c-format
msgid "App %s branch %s is not installed"
msgstr "Програму %s, гілка %s не встановлено"

#: app/flatpak-builtins-mask.c:42
msgid "Remove matching masks"
msgstr "Вилучити відповідні маски"

#: app/flatpak-builtins-mask.c:54
msgid ""
"[PATTERN…] - disable updates and automatic installation matching patterns"
msgstr ""
"[ВЗІРЕЦЬ…] - вимкнути оновлення та автоматичне встановлення за відповідністю "
"взірцю"

#: app/flatpak-builtins-mask.c:73
#, c-format
msgid "No masked patterns\n"
msgstr "Немає замаскованих взірців\n"

#: app/flatpak-builtins-mask.c:78
#, c-format
msgid "Masked patterns:\n"
msgstr "Замасковані взірці:\n"

#: app/flatpak-builtins-override.c:42
msgid "Remove existing overrides"
msgstr "Вилучити наявні перевизначення"

#: app/flatpak-builtins-override.c:43
msgid "Show existing overrides"
msgstr "Показати наявні перевизначення"

#: app/flatpak-builtins-override.c:59
msgid "[APP] - Override settings [for application]"
msgstr "[ПРОГРАМА] - Перевизначити параметри [для програми]"

#: app/flatpak-builtins-permission-list.c:143
msgid "[TABLE] [ID] - List permissions"
msgstr "[ТАБЛИЦЯ] [ІД] - список прав доступу"

#: app/flatpak-builtins-permission-list.c:179
#: app/flatpak-builtins-permission-show.c:142
msgid "Table"
msgstr "Таблиця"

#: app/flatpak-builtins-permission-list.c:180
#: app/flatpak-builtins-permission-show.c:143
msgid "Object"
msgstr "Об'єкт"

#: app/flatpak-builtins-permission-list.c:181
#: app/flatpak-builtins-permission-show.c:144
msgid "App"
msgstr "Програма"

#: app/flatpak-builtins-permission-list.c:183
#: app/flatpak-builtins-permission-show.c:146
msgid "Data"
msgstr "Дані"

#: app/flatpak-builtins-permission-remove.c:120
msgid "TABLE ID [APP_ID] - Remove item from permission store"
msgstr "ТАБЛИЦЯ ІД [ІД_ПРОГРАМИ] - вилучити запис зі сховища прав доступу"

#: app/flatpak-builtins-permission-remove.c:129
#: app/flatpak-builtins-permission-set.c:120
msgid "Too few arguments"
msgstr "Замало параметрів"

#: app/flatpak-builtins-permission-reset.c:43
msgid "Reset all permissions"
msgstr "Скинути усі права доступу"

#: app/flatpak-builtins-permission-reset.c:144
msgid "APP_ID - Reset permissions for an app"
msgstr "ІД_ПРОГ - відновити початкові права доступу для програми"

#: app/flatpak-builtins-permission-reset.c:153
#: app/flatpak-builtins-permission-show.c:124
msgid "Wrong number of arguments"
msgstr "Помилкова кількість параметрів"

#: app/flatpak-builtins-permission-set.c:42
msgid "Associate DATA with the entry"
msgstr "Пов'язати ДАНІ із записом"

#: app/flatpak-builtins-permission-set.c:42
msgid "DATA"
msgstr "ДАНІ"

#: app/flatpak-builtins-permission-set.c:111
msgid "TABLE ID APP_ID [PERMISSION...] - Set permissions"
msgstr "ТАБЛИЦЯ ІД ІД_ПРОГРАМИ [ПРАВА_ДОСТУПУ…] — встановити права доступу"

#: app/flatpak-builtins-permission-set.c:132
#, c-format
msgid "Failed to parse '%s' as GVariant: "
msgstr "Не вдалося обробити «%s» як GVariant: "

#: app/flatpak-builtins-permission-show.c:115
msgid "APP_ID - Show permissions for an app"
msgstr "ІД_ПРОГ - показати права доступу для програми"

#: app/flatpak-builtins-pin.c:44
msgid "Remove matching pins"
msgstr "Вилучити відповідні пришпилення"

#: app/flatpak-builtins-pin.c:56
msgid "[PATTERN…] - disable automatic removal of runtimes matching patterns"
msgstr ""
"[ВЗІРЕЦЬ…] - вимкнути автоматичне вилучення середовищ виконання за "
"відповідністю взірцю"

#: app/flatpak-builtins-pin.c:75
#, c-format
msgid "No pinned patterns\n"
msgstr "Немає пришпилених взірців\n"

#: app/flatpak-builtins-pin.c:80
#, c-format
msgid "Pinned patterns:\n"
msgstr "Пришпилені взірці:\n"

#: app/flatpak-builtins-preinstall.c:80
msgid "- Install flatpaks that are part of the operating system"
msgstr ""

#: app/flatpak-builtins-preinstall.c:118
#, c-format
msgid "Nothing to do.\n"
msgstr "Немає що виконувати.\n"

#: app/flatpak-builtins-ps.c:49
msgid "Instance"
msgstr "Екземпляр"

#: app/flatpak-builtins-ps.c:49
msgid "Show the instance ID"
msgstr "Показати ідентифікатор екземпляра"

#: app/flatpak-builtins-ps.c:50 app/flatpak-builtins-run.c:178
msgid "PID"
msgstr "PID"

#: app/flatpak-builtins-ps.c:50
msgid "Show the PID of the wrapper process"
msgstr "Показати PID процесу-обгортки"

#: app/flatpak-builtins-ps.c:51
msgid "Child-PID"
msgstr "Дочірній-PID"

#: app/flatpak-builtins-ps.c:51
msgid "Show the PID of the sandbox process"
msgstr "Показати PID процесу пісочниці"

#: app/flatpak-builtins-ps.c:54 app/flatpak-builtins-search.c:48
msgid "Show the application branch"
msgstr "Показати гілку програми"

#: app/flatpak-builtins-ps.c:55
msgid "Show the application commit"
msgstr "Показати внесок програми"

#: app/flatpak-builtins-ps.c:56
msgid "Show the runtime ID"
msgstr "Показати ідентифікатор середовища виконання"

#: app/flatpak-builtins-ps.c:57
msgid "R.-Branch"
msgstr "Гілка-середовища"

#: app/flatpak-builtins-ps.c:57
msgid "Show the runtime branch"
msgstr "Показати гілку середовища виконання"

#: app/flatpak-builtins-ps.c:58
msgid "R.-Commit"
msgstr "Внесок-середовища"

#: app/flatpak-builtins-ps.c:58
msgid "Show the runtime commit"
msgstr "Показати внесок середовища виконання"

#: app/flatpak-builtins-ps.c:59
msgid "Active"
msgstr "Активна"

#: app/flatpak-builtins-ps.c:59
msgid "Show whether the app is active"
msgstr "Показувати, чи є програма активною"

#: app/flatpak-builtins-ps.c:60
msgid "Background"
msgstr "Фонова"

#: app/flatpak-builtins-ps.c:60
msgid "Show whether the app is background"
msgstr "Показувати, чи працює програма у фоновому режимі"

#: app/flatpak-builtins-ps.c:246
msgid " - Enumerate running sandboxes"
msgstr " - пронумерувати запущені пісочниці"

#: app/flatpak-builtins-remote-add.c:66
msgid "Do nothing if the provided remote exists"
msgstr "Нічого не робити, якщо вказане сховище існує"

#: app/flatpak-builtins-remote-add.c:67
msgid "LOCATION specifies a configuration file, not the repo location"
msgstr "МІСЦЕ вказує на файл налаштувань, а не на розташування сховища"

#: app/flatpak-builtins-remote-add.c:72 app/flatpak-builtins-remote-modify.c:78
msgid "Disable GPG verification"
msgstr "Вимкнути перевірку GPG"

#: app/flatpak-builtins-remote-add.c:73 app/flatpak-builtins-remote-modify.c:79
msgid "Mark the remote as don't enumerate"
msgstr "Позначити віддалене сховище як таке, яке не входить до переліку"

#: app/flatpak-builtins-remote-add.c:74 app/flatpak-builtins-remote-modify.c:80
msgid "Mark the remote as don't use for deps"
msgstr ""
"Позначити віддалене сховище як таке, яке не використовується для залежностей"

#: app/flatpak-builtins-remote-add.c:75 app/flatpak-builtins-remote-modify.c:81
msgid "Set priority (default 1, higher is more prioritized)"
msgstr ""
"Встановити пріоритетність (типово 1, більше значення — вища пріоритетність)"

#: app/flatpak-builtins-remote-add.c:75 app/flatpak-builtins-remote-modify.c:81
msgid "PRIORITY"
msgstr "ПРІОРИТЕТНІСТЬ"

#: app/flatpak-builtins-remote-add.c:76
msgid "The named subset to use for this remote"
msgstr ""
"Іменований піднабір, яким слід скористатися для цього віддаленого сховища"

#: app/flatpak-builtins-remote-add.c:76 app/flatpak-builtins-remote-modify.c:71
msgid "SUBSET"
msgstr "ПІДНАБІР"

#: app/flatpak-builtins-remote-add.c:77 app/flatpak-builtins-remote-modify.c:82
msgid "A nice name to use for this remote"
msgstr "Зрозуміла назва для використання цього віддаленого сховища"

#: app/flatpak-builtins-remote-add.c:78 app/flatpak-builtins-remote-modify.c:83
msgid "A one-line comment for this remote"
msgstr "Однорядковий коментар до цього віддаленого сховища"

#: app/flatpak-builtins-remote-add.c:79 app/flatpak-builtins-remote-modify.c:84
msgid "A full-paragraph description for this remote"
msgstr "Розгорнутий опис цього віддаленого сховища"

#: app/flatpak-builtins-remote-add.c:80 app/flatpak-builtins-remote-modify.c:85
msgid "URL for a website for this remote"
msgstr "Адреса сайта цього віддаленого сховища"

#: app/flatpak-builtins-remote-add.c:81 app/flatpak-builtins-remote-modify.c:86
msgid "URL for an icon for this remote"
msgstr "Адреса піктограми цього віддаленого сховища"

#: app/flatpak-builtins-remote-add.c:82 app/flatpak-builtins-remote-modify.c:87
msgid "Default branch to use for this remote"
msgstr "Типова гілка для цього віддаленого сховища"

#: app/flatpak-builtins-remote-add.c:84 app/flatpak-builtins-remote-modify.c:89
msgid "Import GPG key from FILE (- for stdin)"
msgstr "Імпортувати ключ GPG з ФАЙЛА (- — імпортувати із stdin)"

#: app/flatpak-builtins-remote-add.c:85 app/flatpak-builtins-remote-modify.c:90
msgid "Load signatures from URL"
msgstr ""

#: app/flatpak-builtins-remote-add.c:86 app/flatpak-builtins-remote-modify.c:92
msgid "Set path to local filter FILE"
msgstr "Встановити шлях до локального ФАЙЛа фільтрування"

#: app/flatpak-builtins-remote-add.c:87 app/flatpak-builtins-remote-modify.c:93
msgid "Disable the remote"
msgstr "Вимкнути віддалене сховище"

#: app/flatpak-builtins-remote-add.c:88 app/flatpak-builtins-remote-modify.c:94
msgid "Name of authenticator"
msgstr "Назва розпізнавальника"

#: app/flatpak-builtins-remote-add.c:90 app/flatpak-builtins-remote-modify.c:96
msgid "Autoinstall authenticator"
msgstr "Автоматично встановлювати засіб розпізнавання"

#: app/flatpak-builtins-remote-add.c:91 app/flatpak-builtins-remote-modify.c:97
msgid "Don't autoinstall authenticator"
msgstr "Не встановлювати засіб розпізнавання автоматично"

#: app/flatpak-builtins-remote-add.c:92 app/flatpak-builtins-remote-modify.c:99
msgid "Don't follow the redirect set in the summary file"
msgstr "Не виконувати переспрямовування, яке встановлено у файлі резюме"

#: app/flatpak-builtins-remote-add.c:261 app/flatpak-builtins-remote-add.c:268
#, c-format
msgid "Can't load uri %s: %s\n"
msgstr "Не вдалося завантажити адресу %s: %s\n"

#: app/flatpak-builtins-remote-add.c:276 common/flatpak-dir.c:4643
#, c-format
msgid "Can't load file %s: %s\n"
msgstr "Не вдалося завантажити файл %s: %s\n"

#: app/flatpak-builtins-remote-add.c:304
msgid "NAME LOCATION - Add a remote repository"
msgstr "НАЗВА РОЗТАШУВАННЯ - Додати віддалене сховище"

#: app/flatpak-builtins-remote-add.c:331
msgid "GPG verification is required if collections are enabled"
msgstr "Якщо увімкнено збірку, слід пройти перевірку GPG"

#: app/flatpak-builtins-remote-add.c:393
#, c-format
msgid "Remote %s already exists"
msgstr "Запис віддаленого сховища %s вже існує"

#: app/flatpak-builtins-remote-add.c:405
#: app/flatpak-builtins-remote-modify.c:340
#, c-format
msgid "Invalid authenticator name %s"
msgstr "Некоректна назва засобу розпізнавання, %s"

#: app/flatpak-builtins-remote-add.c:422
#, c-format
msgid "Warning: Could not update extra metadata for '%s': %s\n"
msgstr "Попередження: не вдалося оновити додаткові метадані для «%s»: %s\n"

#: app/flatpak-builtins-remote-delete.c:39
msgid "Remove remote even if in use"
msgstr "Вилучити віддалене сховища, навіть якщо воно використовується"

#: app/flatpak-builtins-remote-delete.c:53
msgid "NAME - Delete a remote repository"
msgstr "НАЗВА - Вилучити віддалене сховище"

#: app/flatpak-builtins-remote-delete.c:100
#, c-format
msgid "The following refs are installed from remote '%s':"
msgstr "Вказані нижче посилання встановлено з віддаленого сховища «%s»:"

#: app/flatpak-builtins-remote-delete.c:101
msgid "Remove them?"
msgstr "Вилучити їх?"

#: app/flatpak-builtins-remote-delete.c:103
#, c-format
msgid "Can't remove remote '%s' with installed refs"
msgstr "Не можна вилучати віддалене сховище «%s» зі встановленими посиланнями"

#: app/flatpak-builtins-remote-info.c:55
msgid "Commit to show info for"
msgstr "Внесок, щодо якого слід показати відомості"

#: app/flatpak-builtins-remote-info.c:58
msgid "Display log"
msgstr "Показати журнал"

#: app/flatpak-builtins-remote-info.c:61
msgid "Show parent"
msgstr "Показати батьківський запис"

#: app/flatpak-builtins-remote-info.c:65 app/flatpak-builtins-remote-ls.c:60
msgid "Use local caches even if they are stale"
msgstr "Використовувати локальні кеші, навіть якщо вони є застарілими"

#. Translators: A sideload is when you install from a local USB drive rather than the Internet.
#: app/flatpak-builtins-remote-info.c:67 app/flatpak-builtins-remote-ls.c:62
msgid "Only list refs available as sideloads"
msgstr "Показати лише сховища, які доступні для локального вивантаження"

#: app/flatpak-builtins-remote-info.c:114
msgid ""
" REMOTE REF - Show information about an application or runtime in a remote"
msgstr ""
" СХОВИЩЕ НАЗВА - Показати відомості щодо програми або середовища у "
"віддаленому сховищі"

#: app/flatpak-builtins-remote-info.c:125
msgid "REMOTE and REF must be specified"
msgstr "Має бути вказано СХОВИЩЕ і НАЗВУ"

#: app/flatpak-builtins-remote-info.c:247
#: app/flatpak-builtins-remote-info.c:282
#, fuzzy
msgid "Download Size:"
msgstr "Розмір отриманого"

#: app/flatpak-builtins-remote-info.c:267
#: app/flatpak-builtins-remote-info.c:325
msgid "History:"
msgstr "Журнал:"

#: app/flatpak-builtins-remote-info.c:348
msgid " Commit:"
msgstr " Внесок:"

#: app/flatpak-builtins-remote-info.c:349
msgid " Subject:"
msgstr " Тема:"

#: app/flatpak-builtins-remote-info.c:350
msgid " Date:"
msgstr " Дата:"

#: app/flatpak-builtins-remote-info.c:383
#, c-format
msgid "Warning: Commit %s has no flatpak metadata\n"
msgstr "Попередження: у внеску %s немає метаданих flatpak\n"

#: app/flatpak-builtins-remote-list.c:43
msgid "Show remote details"
msgstr "Показати подробиці щодо віддаленого сховища"

#: app/flatpak-builtins-remote-list.c:44
msgid "Show disabled remotes"
msgstr "Показати вимкнені віддалені сховища"

#: app/flatpak-builtins-remote-list.c:52
msgid "Title"
msgstr "Заголовок"

#: app/flatpak-builtins-remote-list.c:52
msgid "Show the title"
msgstr "Показати заголовок"

#: app/flatpak-builtins-remote-list.c:53
msgid "Show the URL"
msgstr "Показати адресу"

#: app/flatpak-builtins-remote-list.c:54
msgid "Show the collection ID"
msgstr "Показати ідентифікатор збірки"

#: app/flatpak-builtins-remote-list.c:55 app/flatpak-builtins-repo.c:392
msgid "Subset"
msgstr "Піднабір"

#: app/flatpak-builtins-remote-list.c:55
msgid "Show the subset"
msgstr "Показати піднабір"

#: app/flatpak-builtins-remote-list.c:56
msgid "Filter"
msgstr "Фільтр"

#: app/flatpak-builtins-remote-list.c:56
msgid "Show filter file"
msgstr "Показати файл фільтрування"

#: app/flatpak-builtins-remote-list.c:57
msgid "Priority"
msgstr "Пріоритетність"

#: app/flatpak-builtins-remote-list.c:57
msgid "Show the priority"
msgstr "Показати пріоритетність"

#: app/flatpak-builtins-remote-list.c:59
msgid "Comment"
msgstr "Коментар"

#: app/flatpak-builtins-remote-list.c:59
msgid "Show comment"
msgstr "Показати коментар"

#: app/flatpak-builtins-remote-list.c:60
msgid "Show description"
msgstr "Показати опис"

#: app/flatpak-builtins-remote-list.c:61
msgid "Homepage"
msgstr "Домашня сторінка"

#: app/flatpak-builtins-remote-list.c:61
msgid "Show homepage"
msgstr "Показати домашню сторінку"

#: app/flatpak-builtins-remote-list.c:62
msgid "Icon"
msgstr "Піктограма"

#: app/flatpak-builtins-remote-list.c:62
msgid "Show icon"
msgstr "Показати піктограму"

#: app/flatpak-builtins-remote-list.c:231
msgid " - List remote repositories"
msgstr " - Вивести список віддалених сховищ"

#: app/flatpak-builtins-remote-ls.c:52
msgid "Show arches and branches"
msgstr "Показати архітектури і гілки"

#: app/flatpak-builtins-remote-ls.c:53
msgid "Show only runtimes"
msgstr "Показати лише середовища виконання"

#: app/flatpak-builtins-remote-ls.c:54
msgid "Show only apps"
msgstr "Показати лише програми"

#: app/flatpak-builtins-remote-ls.c:55
msgid "Show only those where updates are available"
msgstr "Показати лише ті, для яких доступні оновлення"

#: app/flatpak-builtins-remote-ls.c:56
msgid "Limit to this arch (* for all)"
msgstr "Обмежитися вказаною архітектурою (* для усіх)"

#: app/flatpak-builtins-remote-ls.c:77
msgid "Show the runtime"
msgstr "Показати середовища виконання"

#: app/flatpak-builtins-remote-ls.c:79
msgid "Download size"
msgstr "Розмір отриманого"

#: app/flatpak-builtins-remote-ls.c:79
msgid "Show the download size"
msgstr "Показати розмір отриманого"

#: app/flatpak-builtins-remote-ls.c:391
msgid " [REMOTE or URI] - Show available runtimes and applications"
msgstr ""
" [СХОВИЩЕ або АДРЕСА] - Показати доступні середовища виконання і програми"

#: app/flatpak-builtins-remote-modify.c:67
msgid "Enable GPG verification"
msgstr "Увімкнути перевірку GPG"

#: app/flatpak-builtins-remote-modify.c:68
msgid "Mark the remote as enumerate"
msgstr "Позначити віддалене сховище як таке, яке входить до переліку"

#: app/flatpak-builtins-remote-modify.c:69
msgid "Mark the remote as used for dependencies"
msgstr ""
"Позначити віддалене сховище як таке, що використовується для залежностей"

#: app/flatpak-builtins-remote-modify.c:70
#, fuzzy
msgid "Set a new URL"
msgstr "Встановити нову адресу"

#: app/flatpak-builtins-remote-modify.c:71
msgid "Set a new subset to use"
msgstr "Встановити новий піднабір для використання"

#: app/flatpak-builtins-remote-modify.c:72
msgid "Enable the remote"
msgstr "Увімкнути віддалене сховище"

#: app/flatpak-builtins-remote-modify.c:73
msgid "Update extra metadata from the summary file"
msgstr "Оновити додаткові метадані з файла резюме"

#: app/flatpak-builtins-remote-modify.c:91
msgid "Disable local filter"
msgstr "Вимкнути локальний фільтр"

#: app/flatpak-builtins-remote-modify.c:95
msgid "Authenticator options"
msgstr "Параметри засобу розпізнавання"

#: app/flatpak-builtins-remote-modify.c:98
msgid "Follow the redirect set in the summary file"
msgstr "Виконувати переспрямовування, яке встановлено у файлі резюме"

#: app/flatpak-builtins-remote-modify.c:306
msgid "NAME - Modify a remote repository"
msgstr "НАЗВА - Змінити віддалене сховище"

#: app/flatpak-builtins-remote-modify.c:316
msgid "Remote NAME must be specified"
msgstr "Має бути вказано НАЗВУ віддаленого сховища"

#: app/flatpak-builtins-remote-modify.c:327
#, c-format
msgid "Updating extra metadata from remote summary for %s\n"
msgstr "Оновлюємо додаткові метадані з резюме віддаленого сховища для %s\n"

#: app/flatpak-builtins-remote-modify.c:330
#, c-format
msgid "Error updating extra metadata for '%s': %s\n"
msgstr "Помилка під час оновлення додаткових метаданих для «%s»: %s\n"

#: app/flatpak-builtins-remote-modify.c:331
#, c-format
msgid "Could not update extra metadata for %s"
msgstr "Не вдалося оновити додаткові метадані для %s"

#: app/flatpak-builtins-repair.c:43
msgid "Don't make any changes"
msgstr "Не вносити змін"

#: app/flatpak-builtins-repair.c:44
msgid "Reinstall all refs"
msgstr "Перевстановити усі посилання"

#: app/flatpak-builtins-repair.c:68
#, c-format
msgid "Object missing: %s.%s\n"
msgstr "Не вистачає об'єкта: %s.%s\n"

#: app/flatpak-builtins-repair.c:76
#, c-format
msgid "Object invalid: %s.%s\n"
msgstr "Некоректний об'єкт: %s.%s\n"

#: app/flatpak-builtins-repair.c:81
#, c-format
msgid "%s, deleting object\n"
msgstr "%s, вилучаємо об'єкт\n"

#: app/flatpak-builtins-repair.c:146
#, c-format
msgid "Can't load object %s: %s\n"
msgstr "Не вдалося завантажити об'єкт %s: %s\n"

#: app/flatpak-builtins-repair.c:228
#, c-format
msgid "Commit invalid %s: %s\n"
msgstr "Некоректний внесок %s: %s\n"

#: app/flatpak-builtins-repair.c:231
#, c-format
msgid "Deleting invalid commit %s: %s\n"
msgstr "Вилучаємо некоректний внесок %s: %s\n"

#: app/flatpak-builtins-repair.c:261
#, c-format
msgid "Commit should be marked partial: %s\n"
msgstr "Внесок має бути позначено як частковий: %s\n"

#: app/flatpak-builtins-repair.c:264
#, c-format
msgid "Marking commit as partial: %s\n"
msgstr "Позначаємо внесок як частковий: %s\n"

#: app/flatpak-builtins-repair.c:293
#, c-format
msgid "Problems loading data for %s: %s\n"
msgstr "Проблеми із завантаженням даних для %s: %s\n"

#: app/flatpak-builtins-repair.c:306
#, c-format
msgid "Error reinstalling %s: %s\n"
msgstr "Помилка під час перевстановлення %s: %s\n"

#: app/flatpak-builtins-repair.c:327
msgid "- Repair a flatpak installation"
msgstr "- Відновити встановлення flatpak"

#: app/flatpak-builtins-repair.c:406
#, c-format
msgid "Removing non-deployed ref %s…\n"
msgstr "Вилучаємо нерозгорнуте джерело %s…\n"

#: app/flatpak-builtins-repair.c:411
#, c-format
msgid "Skipping non-deployed ref %s…\n"
msgstr "Пропускаємо нерозгорнуте джерело %s…\n"

#: app/flatpak-builtins-repair.c:429
#, c-format
msgid "[%d/%d] Verifying %s…\n"
msgstr "[%d з %d] Перевіряємо %s…\n"

#: app/flatpak-builtins-repair.c:435
#, c-format
msgid "Dry run: "
msgstr "Тестовий запуск: "

#: app/flatpak-builtins-repair.c:440
#, c-format
msgid "Deleting ref %s due to missing objects\n"
msgstr "Вилучаємо %s через те, що не вистачає об'єктів\n"

#: app/flatpak-builtins-repair.c:444
#, c-format
msgid "Deleting ref %s due to invalid objects\n"
msgstr "Вилучаємо %s через некоректність об'єктів\n"

#: app/flatpak-builtins-repair.c:448
#, c-format
msgid "Deleting ref %s due to %d\n"
msgstr "Вилучаємо посилання %s через %d\n"

#: app/flatpak-builtins-repair.c:464
#, c-format
msgid "Checking remotes...\n"
msgstr "Перевіряємо віддалені сховища...\n"

#: app/flatpak-builtins-repair.c:482
#, c-format
msgid "Remote %s for ref %s is missing\n"
msgstr "Не вистачає віддаленого сховища %s для посилання %s\n"

#: app/flatpak-builtins-repair.c:484
#, c-format
msgid "Remote %s for ref %s is disabled\n"
msgstr "Віддалене сховище %s для посилання %s вимкнено\n"

#: app/flatpak-builtins-repair.c:490
#, c-format
msgid "Pruning objects\n"
msgstr "Вилучаємо об'єкти\n"

#: app/flatpak-builtins-repair.c:498
#, c-format
msgid "Erasing .removed\n"
msgstr "Вилучаємо .removed\n"

#: app/flatpak-builtins-repair.c:524
#, c-format
msgid "Reinstalling refs\n"
msgstr "Повторно встановлюємо посилання\n"

#: app/flatpak-builtins-repair.c:526
#, c-format
msgid "Reinstalling removed refs\n"
msgstr "Повторно встановлюємо вилучені джерела\n"

#: app/flatpak-builtins-repair.c:551
#, c-format
msgid "While removing appstream for %s: "
msgstr "Під час вилучення appstream %s: "

#: app/flatpak-builtins-repair.c:558
#, c-format
msgid "While deploying appstream for %s: "
msgstr "Під час розгортання appstream %s: "

#: app/flatpak-builtins-repo.c:106
#, c-format
msgid "Repo mode: %s\n"
msgstr "Режим сховища: %s\n"

#: app/flatpak-builtins-repo.c:113
#, c-format
msgid "Indexed summaries: %s\n"
msgstr "Індексовані резюме: %s\n"

#: app/flatpak-builtins-repo.c:113 app/flatpak-builtins-repo.c:139
#: app/flatpak-builtins-repo.c:172
msgid "true"
msgstr "true"

#: app/flatpak-builtins-repo.c:113 app/flatpak-builtins-repo.c:139
#: app/flatpak-builtins-repo.c:172
msgid "false"
msgstr "false"

#: app/flatpak-builtins-repo.c:121
#, c-format
msgid "Subsummaries: "
msgstr "Підрезюме: "

#: app/flatpak-builtins-repo.c:136
#, c-format
msgid "Cache version: %d\n"
msgstr "Версія кешу: %d\n"

#: app/flatpak-builtins-repo.c:139
#, c-format
msgid "Indexed deltas: %s\n"
msgstr "Індексовані різниці: %s\n"

#: app/flatpak-builtins-repo.c:142
#, c-format
msgid "Title: %s\n"
msgstr "Назва: %s\n"

#: app/flatpak-builtins-repo.c:145
#, c-format
msgid "Comment: %s\n"
msgstr "Коментар: %s\n"

#: app/flatpak-builtins-repo.c:148
#, c-format
msgid "Description: %s\n"
msgstr "Опис: %s\n"

#: app/flatpak-builtins-repo.c:151
#, c-format
msgid "Homepage: %s\n"
msgstr "Домашня сторінка: %s\n"

#: app/flatpak-builtins-repo.c:154
#, c-format
msgid "Icon: %s\n"
msgstr "Піктограма: %s\n"

#: app/flatpak-builtins-repo.c:157
#, c-format
msgid "Collection ID: %s\n"
msgstr "Ідентифікатор збірки: %s\n"

#: app/flatpak-builtins-repo.c:160
#, c-format
msgid "Default branch: %s\n"
msgstr "Типова гілка: %s\n"

#: app/flatpak-builtins-repo.c:163
#, c-format
msgid "Redirect URL: %s\n"
msgstr "Адреса переспрямовування: %s\n"

#: app/flatpak-builtins-repo.c:166
#, c-format
msgid "Deploy collection ID: %s\n"
msgstr "Ідентифікатор розгортання збірки: %s\n"

#: app/flatpak-builtins-repo.c:169
#, c-format
msgid "Authenticator name: %s\n"
msgstr "Назва засобу розпізнавання: %s\n"

#: app/flatpak-builtins-repo.c:172
#, c-format
msgid "Authenticator install: %s\n"
msgstr "Встановлення засобу розпізнавання: %s\n"

#: app/flatpak-builtins-repo.c:180
#, c-format
msgid "GPG key hash: %s\n"
msgstr "Хеш-сума ключа GPG: %s\n"

#: app/flatpak-builtins-repo.c:184
#, c-format
msgid "%zd summary branches\n"
msgstr "%zd гілок резюме\n"

#: app/flatpak-builtins-repo.c:336
msgid "Installed"
msgstr "Встановлено"

#. Translators: Download is used here as a noun
#: app/flatpak-builtins-repo.c:338 app/flatpak-cli-transaction.c:1462
msgid "Download"
msgstr "Отримати"

#: app/flatpak-builtins-repo.c:339
msgid "Subsets"
msgstr "Піднабори"

#: app/flatpak-builtins-repo.c:393
msgid "Digest"
msgstr "Контрольна сума"

#: app/flatpak-builtins-repo.c:394
msgid "History length"
msgstr "Довжина журналу"

#: app/flatpak-builtins-repo.c:711
msgid "Print general information about the repository"
msgstr "Вивести загальну інформацію щодо сховища"

#: app/flatpak-builtins-repo.c:712
msgid "List the branches in the repository"
msgstr "Вивести список гілок у сховищі"

#: app/flatpak-builtins-repo.c:713
msgid "Print metadata for a branch"
msgstr "Вивести метадані для гілки"

#: app/flatpak-builtins-repo.c:714
msgid "Show commits for a branch"
msgstr "Показати внески для гілки"

#: app/flatpak-builtins-repo.c:715
msgid "Print information about the repo subsets"
msgstr "Вивести інформацію щодо піднаборів сховища"

#: app/flatpak-builtins-repo.c:716
msgid "Limit information to subsets with this prefix"
msgstr "Обмежити відомості до піднаборів із цим префіксом"

#: app/flatpak-builtins-repo.c:732
msgid "LOCATION - Repository maintenance"
msgstr "РОЗТАШУВАННЯ - Супровід сховища"

#: app/flatpak-builtins-run.c:159
msgid "Command to run"
msgstr "Команда, яку слід виконати"

#: app/flatpak-builtins-run.c:160
msgid "Directory to run the command in"
msgstr "Каталог, у якому слід виконати команду"

#: app/flatpak-builtins-run.c:161
msgid "Branch to use"
msgstr "Гілка, яку слід використовувати"

#: app/flatpak-builtins-run.c:162
msgid "Use development runtime"
msgstr "Використовувати розробницьке середовище виконання"

#: app/flatpak-builtins-run.c:163
msgid "Runtime to use"
msgstr "Середовище виконання, яке слід використовувати"

#: app/flatpak-builtins-run.c:164
msgid "Runtime version to use"
msgstr "Версія середовища виконання, яку слід використовувати"

#: app/flatpak-builtins-run.c:167
msgid "Log accessibility bus calls"
msgstr "Записувати до журналу виклики до каналу доступності"

#: app/flatpak-builtins-run.c:168
msgid "Don't proxy accessibility bus calls"
msgstr "Не використовувати проксі для викликів до каналу доступності"

#: app/flatpak-builtins-run.c:169
msgid "Proxy accessibility bus calls (default except when sandboxed)"
msgstr ""
"Пропускати крізь проксі виклики каналу доступності (типова поведінка, якщо "
"не працюємо у пісочниці)"

#: app/flatpak-builtins-run.c:170
msgid "Don't proxy session bus calls"
msgstr "Не пропускати крізь проксі виклику каналу сеансу"

#: app/flatpak-builtins-run.c:171
msgid "Proxy session bus calls (default except when sandboxed)"
msgstr ""
"Пропускати крізь проксі виклики каналу сеансу (типова поведінка, якщо не "
"працюємо у пісочниці)"

#: app/flatpak-builtins-run.c:172
msgid "Don't start portals"
msgstr "Не запускати портали"

#: app/flatpak-builtins-run.c:173
msgid "Enable file forwarding"
msgstr "Увімкнути переспрямовування файлів"

#: app/flatpak-builtins-run.c:174
msgid "Run specified commit"
msgstr "Виконати вказаний внесок"

#: app/flatpak-builtins-run.c:175
msgid "Use specified runtime commit"
msgstr "Використати вказаний внесок середовища виконання"

#: app/flatpak-builtins-run.c:176
msgid "Run completely sandboxed"
msgstr "Запустити повністю у пісочниці"

#: app/flatpak-builtins-run.c:178
msgid "Use PID as parent pid for sharing namespaces"
msgstr ""
"Використовувати PID як батьківський pid для спільного використання просторів "
"назв"

#: app/flatpak-builtins-run.c:179
msgid "Make processes visible in parent namespace"
msgstr "Зробити процеси видимими у батьківському просторі назв"

#: app/flatpak-builtins-run.c:180
msgid "Share process ID namespace with parent"
msgstr ""
"Спільно використовувати простір назв ідентифікатора процесу із батьківським "
"процесом"

#: app/flatpak-builtins-run.c:181
msgid "Write the instance ID to the given file descriptor"
msgstr "Записати ідентифікатор екземпляра до вказаного дескриптора файла"

#: app/flatpak-builtins-run.c:182
msgid "Use PATH instead of the app's /app"
msgstr "Використовувати PATH замість /app програми"

#: app/flatpak-builtins-run.c:183
#, fuzzy
msgid "Use FD instead of the app's /app"
msgstr "Використовувати PATH замість /app програми"

#: app/flatpak-builtins-run.c:183 app/flatpak-builtins-run.c:185
#: app/flatpak-builtins-run.c:187 app/flatpak-builtins-run.c:188
#: common/flatpak-context.c:2672
msgid "FD"
msgstr "ДФ"

#: app/flatpak-builtins-run.c:184
msgid "Use PATH instead of the runtime's /usr"
msgstr "Використовувати PATH замість /usr середовища виконання"

#: app/flatpak-builtins-run.c:185
#, fuzzy
msgid "Use FD instead of the runtime's /usr"
msgstr "Використовувати PATH замість /usr середовища виконання"

#: app/flatpak-builtins-run.c:186
#, fuzzy
msgid "Clear all outside environment variables"
msgstr "Встановити змінну середовища"

#: app/flatpak-builtins-run.c:187
msgid ""
"Bind mount the file or directory referred to by FD to its canonicalized path"
msgstr ""

#: app/flatpak-builtins-run.c:188
msgid ""
"Bind mount the file or directory referred to by FD read-only to its "
"canonicalized path"
msgstr ""

#: app/flatpak-builtins-run.c:219
msgid "APP [ARGUMENT…] - Run an app"
msgstr "ПРОГРАМА [АРГУМЕНТ...] - Виконати програму"

#: app/flatpak-builtins-run.c:370
#, c-format
msgid "runtime/%s/%s/%s not installed"
msgstr "runtime/%s/%s/%s не встановлено"

#: app/flatpak-builtins-run.c:419
msgid "app-fd and app-path cannot both be used"
msgstr ""

#: app/flatpak-builtins-run.c:449
msgid "usr-fd and usr-path cannot both be used"
msgstr ""

#: app/flatpak-builtins-search.c:37
msgid "Arch to search for"
msgstr "Архітектура для пошуку"

#: app/flatpak-builtins-search.c:49
msgid "Remotes"
msgstr "Сховища"

#: app/flatpak-builtins-search.c:49
msgid "Show the remotes"
msgstr "Показати віддалені сховища"

#: app/flatpak-builtins-search.c:244
msgid "TEXT - Search remote apps/runtimes for text"
msgstr "ТЕКСТ - шукати у віддалених програмах або середовищах текст"

#: app/flatpak-builtins-search.c:255
msgid "TEXT must be specified"
msgstr "Має бути вказано ТЕКСТ"

#: app/flatpak-builtins-search.c:338
msgid "No matches found"
msgstr "Відповідників не знайдено"

#: app/flatpak-builtins-uninstall.c:54
msgid "Arch to uninstall"
msgstr "Архітектура для вилучення"

#: app/flatpak-builtins-uninstall.c:55
msgid "Keep ref in local repository"
msgstr "Зберігати посилання у локальному сховищі"

#: app/flatpak-builtins-uninstall.c:56
msgid "Don't uninstall related refs"
msgstr "Не встановлювати пов’язані посилання"

#: app/flatpak-builtins-uninstall.c:57
msgid "Remove files even if running"
msgstr "Вилучити файли, навіть якщо роботу ще не завершено"

#: app/flatpak-builtins-uninstall.c:60
msgid "Uninstall all"
msgstr "Вилучити все"

#: app/flatpak-builtins-uninstall.c:61
msgid "Uninstall unused"
msgstr "Вилучити невикористане"

#: app/flatpak-builtins-uninstall.c:62
msgid "Delete app data"
msgstr "Вилучити дані програми"

#: app/flatpak-builtins-uninstall.c:141
#, c-format
msgid "Delete data for %s?"
msgstr "Вилучити дані %s?"

#: app/flatpak-builtins-uninstall.c:220
#, c-format
msgid "Info: applications using the extension %s%s%s branch %s%s%s:\n"
msgstr ""
"Інформація: програми, що використовують розширення %s%s%s, гілка %s%s%s:\n"

#: app/flatpak-builtins-uninstall.c:223
#, c-format
msgid "Info: applications using the runtime %s%s%s branch %s%s%s:\n"
msgstr ""
"Інформація: програми, що використовують середовище виконання %s%s%s, гілка "
"%s%s%s:\n"

#: app/flatpak-builtins-uninstall.c:238
msgid "Really remove?"
msgstr "Справді вилучити?"

#: app/flatpak-builtins-uninstall.c:255
msgid "[REF…] - Uninstall applications or runtimes"
msgstr "[НАЗВА…] - Вилучити програми або середовища виконання"

#: app/flatpak-builtins-uninstall.c:264
msgid "Must specify at least one REF, --unused, --all or --delete-data"
msgstr "Слід вказати принаймні одне джерело, --unused, --all або --delete-data"

#: app/flatpak-builtins-uninstall.c:267
msgid "Must not specify REFs when using --all"
msgstr "Не слід вказувати ПОСИЛАННЯ, якщо використовується --all"

#: app/flatpak-builtins-uninstall.c:270
msgid "Must not specify REFs when using --unused"
msgstr "Не слід вказувати ПОСИЛАННЯ, якщо використовується --unused"

#: app/flatpak-builtins-uninstall.c:336
#, c-format
msgid ""
"\n"
"These runtimes in installation '%s' are pinned and won't be removed; see "
"flatpak-pin(1):\n"
msgstr ""
"\n"
"Ці середовища виконання у встановлені «%s» пришпилено — їх не буде вилучено; "
"див. flatpak-pin(1):\n"

#: app/flatpak-builtins-uninstall.c:370
#, c-format
msgid "Nothing unused to uninstall\n"
msgstr "Не знайдено невикористаного для вилучення\n"

#: app/flatpak-builtins-uninstall.c:444
#, c-format
msgid "No installed refs found for ‘%s’"
msgstr "Не знайдено встановлених посилань для «%s»"

#: app/flatpak-builtins-uninstall.c:447
#, c-format
msgid " with arch ‘%s’"
msgstr " з архітектурою «%s»"

#: app/flatpak-builtins-uninstall.c:449
#, c-format
msgid " with branch ‘%s’"
msgstr " з гілкою «%s»"

#: app/flatpak-builtins-uninstall.c:456
#, c-format
msgid "Warning: %s is not installed\n"
msgstr "Попередження: %s не встановлено\n"

#: app/flatpak-builtins-uninstall.c:490
#, c-format
msgid "None of the specified refs are installed"
msgstr "Не встановлено жодне із вказаних посилань"

#: app/flatpak-builtins-uninstall.c:599
#, c-format
msgid "No app data to delete\n"
msgstr ""

#: app/flatpak-builtins-update.c:56
msgid "Arch to update for"
msgstr "Архітектура для оновлення"

#: app/flatpak-builtins-update.c:57
msgid "Commit to deploy"
msgstr "Внесок для розгортання"

#: app/flatpak-builtins-update.c:58
msgid "Remove old files even if running"
msgstr "Вилучити застарілі файли, навіть якщо роботу ще не завершено"

#: app/flatpak-builtins-update.c:59
msgid "Don't pull, only update from local cache"
msgstr "Не отримувати зі сховища, оновити лише з локального кешу"

#: app/flatpak-builtins-update.c:61
msgid "Don't update related refs"
msgstr "Не оновлювати пов’язані посилання"

#: app/flatpak-builtins-update.c:66
msgid "Update appstream for remote"
msgstr "Оновити дані appstream для віддаленого сховища"

#: app/flatpak-builtins-update.c:67
msgid "Only update this subpath"
msgstr "Оновити лише вказаний підшлях"

#: app/flatpak-builtins-update.c:90
msgid "[REF…] - Update applications or runtimes"
msgstr "[НАЗВА…] - Оновити програми або середовища виконання"

#: app/flatpak-builtins-update.c:121
msgid "With --commit, only one REF may be specified"
msgstr "З --commit можна вказувати лише одну НАЗВУ"

#: app/flatpak-builtins-update.c:162
#, c-format
msgid "Looking for updates…\n"
msgstr "Шукаємо оновлення…\n"

#: app/flatpak-builtins-update.c:215
#, c-format
msgid "Unable to update %s: %s\n"
msgstr "Не вдалося оновити %s: %s\n"

#: app/flatpak-builtins-update.c:274
#, fuzzy, c-format
msgid "Nothing to update.\n"
msgstr "Немає що виконувати.\n"

#: app/flatpak-builtins-utils.c:337
#, fuzzy, c-format
msgid ""
"Remote ‘%s’ found in multiple installations, unable to proceed in non-"
"interactive mode"
msgstr ""
"Джерело «%s» виявлено у декількох встановленнях: %s. Вам слід вказати одне."

#: app/flatpak-builtins-utils.c:346
#, c-format
msgid "Remote ‘%s’ found in multiple installations:"
msgstr "Віддалене сховище «%s» знайдено у декількох встановленнях:"

#: app/flatpak-builtins-utils.c:347 app/flatpak-builtins-utils.c:442
#: app/flatpak-builtins-utils.c:538 app/flatpak-builtins-utils.c:540
#: app/flatpak-builtins-utils.c:598
msgid "Which do you want to use (0 to abort)?"
msgstr "Яким скористатися (0 — перервати)?"

#: app/flatpak-builtins-utils.c:349
#, c-format
msgid "No remote chosen to resolve ‘%s’ which exists in multiple installations"
msgstr ""
"Не вибрано віддаленого сховища для визначення «%s», що існує у декількох "
"встановленнях"

#: app/flatpak-builtins-utils.c:358
#, c-format
msgid ""
"Remote \"%s\" not found\n"
"Hint: Use flatpak remote-add to add a remote"
msgstr ""
"Віддаленого сховища «%s» не знайдено.\n"
"Підказка: скористайтеся командою flatpak remote-add для додавання "
"віддаленого сховища"

#: app/flatpak-builtins-utils.c:364
#, c-format
msgid "Remote \"%s\" not found in the %s installation"
msgstr "Віддалене сховище «%s» не знайдено у встановленні %s"

#: app/flatpak-builtins-utils.c:404
#, c-format
msgid "Multiple refs match ‘%s’, unable to proceed in non-interactive mode"
msgstr ""

#. default to yes on Enter
#: app/flatpak-builtins-utils.c:430
#, c-format
msgid ""
"Found ref ‘%s’ in remote ‘%s’ (%s).\n"
"Use this ref?"
msgstr ""
"Знайдено посилання «%s» у віддаленому сховищі «%s» (%s).\n"
"Використати це посилання?"

#: app/flatpak-builtins-utils.c:434 app/flatpak-builtins-utils.c:444
#: app/flatpak-builtins-utils.c:522 app/flatpak-builtins-utils.c:543
#, c-format
msgid "No ref chosen to resolve matches for ‘%s’"
msgstr "Не вибрано посилання для визначення відповідників для «%s»"

#: app/flatpak-builtins-utils.c:440
#, c-format
msgid "Similar refs found for ‘%s’ in remote ‘%s’ (%s):"
msgstr "Знайдено подібні посилання для «%s» у віддаленому сховищі «%s» (%s):"

#: app/flatpak-builtins-utils.c:488
#, c-format
msgid ""
"Multiple installed refs match ‘%s’, unable to proceed in non-interactive mode"
msgstr ""

#. default to yes on Enter
#: app/flatpak-builtins-utils.c:518
#, c-format
msgid "Found installed ref ‘%s’ (%s). Is this correct?"
msgstr "Знайдено встановлене посилання «%s» (%s). Чи є воно правильним?"

#: app/flatpak-builtins-utils.c:534
#, c-format
msgid "All of the above"
msgstr "Усе з наведеного вище"

#: app/flatpak-builtins-utils.c:535
#, c-format
msgid "Similar installed refs found for ‘%s’:"
msgstr "Подібні встановлені посилання, які знайдено для «%s»:"

#: app/flatpak-builtins-utils.c:579
#, c-format
msgid ""
"Multiple remotes have refs matching ‘%s’, unable to proceed in non-"
"interactive mode"
msgstr ""

#: app/flatpak-builtins-utils.c:597
#, c-format
msgid "Remotes found with refs similar to ‘%s’:"
msgstr "Знайдено віддалені сховища із посиланнями, подібними до «%s»:"

#: app/flatpak-builtins-utils.c:600
#, c-format
msgid "No remote chosen to resolve matches for ‘%s’"
msgstr "Не вибрано віддаленого сховища для визначення відповідників «%s»"

#: app/flatpak-builtins-utils.c:696 app/flatpak-builtins-utils.c:699
#, c-format
msgid "Updating appstream data for user remote %s"
msgstr "Оновлюємо дані appstream для віддаленого сховища користувача %s"

#: app/flatpak-builtins-utils.c:706 app/flatpak-builtins-utils.c:709
#, c-format
msgid "Updating appstream data for remote %s"
msgstr "Оновлюємо дані appstream для віддаленого сховища %s"

#: app/flatpak-builtins-utils.c:717 app/flatpak-builtins-utils.c:719
msgid "Error updating"
msgstr "Помилка під час спроби оновлення"

#: app/flatpak-builtins-utils.c:755
#, c-format
msgid "Remote \"%s\" not found"
msgstr "Не знайдено віддаленого сховища «%s»"

#: app/flatpak-builtins-utils.c:796
#, c-format
msgid "Ambiguous suffix: '%s'."
msgstr "Неоднозначний суфікс: «%s»."

#. Translators: don't translate the values
#: app/flatpak-builtins-utils.c:798 app/flatpak-builtins-utils.c:813
msgid "Possible values are :s[tart], :m[iddle], :e[nd] or :f[ull]"
msgstr "Можливі значення — :s[початок], :m[середина], :e[кінець] або :f[усе]"

#: app/flatpak-builtins-utils.c:811
#, c-format
msgid "Invalid suffix: '%s'."
msgstr "Некоректний суфікс: «%s»."

#: app/flatpak-builtins-utils.c:846
#, c-format
msgid "Ambiguous column: %s"
msgstr "Неоднозначний стовпчик: %s"

#: app/flatpak-builtins-utils.c:859
#, c-format
msgid "Unknown column: %s"
msgstr "Невідомий стовпчик: %s"

#: app/flatpak-builtins-utils.c:917
msgid "Available columns:\n"
msgstr "Доступні стовпчики:\n"

#: app/flatpak-builtins-utils.c:927
msgid "Show all columns"
msgstr "Показати усі стовпчики"

#: app/flatpak-builtins-utils.c:928
msgid "Show available columns"
msgstr "Показати доступні стовпчики"

#: app/flatpak-builtins-utils.c:931
msgid "Append :s[tart], :m[iddle], :e[nd] or :f[ull] to change ellipsization"
msgstr ""
"Допишіть :s[початок], :m[середина], :e[кінець] або :f[усе], щоб змінити "
"доповнення"

#: app/flatpak-builtins-utils.c:1483
#, c-format
msgid "Unknown scheme in sideload location %s"
msgstr ""

#: app/flatpak-cli-transaction.c:96 app/flatpak-cli-transaction.c:102
#, c-format
msgid "Required runtime for %s (%s) found in remote %s\n"
msgstr "Потрібне для %s (%s) середовище виконання виявлено у сховищі %s\n"

#: app/flatpak-cli-transaction.c:104
msgid "Do you want to install it?"
msgstr "Хочете встановити його?"

#: app/flatpak-cli-transaction.c:110
#, c-format
msgid "Required runtime for %s (%s) found in remotes:"
msgstr "Потрібне для %s (%s) середовище виконання виявлено у таких сховищах:"

#: app/flatpak-cli-transaction.c:112
msgid "Which do you want to install (0 to abort)?"
msgstr "Який з пакунків встановити (0 — перервати)?"

#: app/flatpak-cli-transaction.c:132
#, c-format
msgid "Configuring %s as new remote '%s'\n"
msgstr "Налаштовуємо %s як нове віддалене сховище «%s»\n"

#. default to yes on Enter
#: app/flatpak-cli-transaction.c:139
#, c-format
msgid ""
"The remote '%s', referred to by '%s' at location %s contains additional "
"applications.\n"
"Should the remote be kept for future installations?"
msgstr ""
"У віддаленому сховищі «%s», на яке посилається %s, у місці %s містяться "
"додаткові програми.\n"
"Хочете зберегти віддалено сховище для наступних встановлень?"

#. default to yes on Enter
#: app/flatpak-cli-transaction.c:147
#, c-format
msgid ""
"The application %s depends on runtimes from:\n"
"  %s\n"
"Configure this as new remote '%s'"
msgstr ""
"Програма %s залежить від середовища виконання звідси:\n"
"  %s\n"
"Налаштуйте як нове сховище «%s»"

#. Formatted size/remaining time in seconds
#: app/flatpak-cli-transaction.c:321
#, c-format
msgid "%s/s%s%s"
msgstr ""

#. Download progress percentage, use the appropriate
#. percent format for your language
#: app/flatpak-cli-transaction.c:359
#, c-format
msgid "%3d%%"
msgstr ""

#: app/flatpak-cli-transaction.c:414
msgid "Installing…"
msgstr "Встановлюємо…"

#: app/flatpak-cli-transaction.c:416
#, c-format
msgid "Installing %d/%d…"
msgstr "Встановлюємо %d з %d…"

#: app/flatpak-cli-transaction.c:421
msgid "Updating…"
msgstr "Оновлення…"

#: app/flatpak-cli-transaction.c:423
#, c-format
msgid "Updating %d/%d…"
msgstr "Оновлюємо %d з %d…"

#: app/flatpak-cli-transaction.c:428
msgid "Uninstalling…"
msgstr "Вилучаємо…"

#: app/flatpak-cli-transaction.c:430
#, c-format
msgid "Uninstalling %d/%d…"
msgstr "Вилучаємо %d з %d…"

#: app/flatpak-cli-transaction.c:496 app/flatpak-quiet-transaction.c:161
#, c-format
msgid "Info: %s was skipped"
msgstr "Інформація: %s було пропущено"

#: app/flatpak-cli-transaction.c:519
#, c-format
msgid "Warning: %s%s%s already installed"
msgstr "Попередження: %s%s%s вже встановлено"

#: app/flatpak-cli-transaction.c:522
#, c-format
msgid "Error: %s%s%s already installed"
msgstr "Помилка: %s%s%s вже встановлено"

#: app/flatpak-cli-transaction.c:528
#, c-format
msgid "Warning: %s%s%s not installed"
msgstr "Попередження: %s%s%s не встановлено"

#: app/flatpak-cli-transaction.c:531
#, c-format
msgid "Error: %s%s%s not installed"
msgstr "Помилка: %s%s%s не встановлено"

#: app/flatpak-cli-transaction.c:537
#, c-format
msgid "Warning: %s%s%s needs a later flatpak version"
msgstr "Попередження: %s%s%s потребує новішої версії flatpak"

#: app/flatpak-cli-transaction.c:540
#, c-format
msgid "Error: %s%s%s needs a later flatpak version"
msgstr "Помилка: %s%s%s потребує новішої версії flatpak"

#: app/flatpak-cli-transaction.c:546
msgid "Warning: Not enough disk space to complete this operation"
msgstr "Попередження: для завершення дії на диску недостатньо вільного місця"

#: app/flatpak-cli-transaction.c:548
msgid "Error: Not enough disk space to complete this operation"
msgstr "Помилка: для завершення дії на диску недостатньо вільного місця"

#: app/flatpak-cli-transaction.c:553
#, c-format
msgid "Warning: %s"
msgstr "Попередження: %s"

#: app/flatpak-cli-transaction.c:555
#, c-format
msgid "Error: %s"
msgstr "Помилка: %s"

#: app/flatpak-cli-transaction.c:570
#, c-format
msgid "Failed to install %s%s%s: "
msgstr "Не вдалося встановити %s%s%s: "

#: app/flatpak-cli-transaction.c:577
#, c-format
msgid "Failed to update %s%s%s: "
msgstr "Не вдалося оновити %s%s%s: "

#: app/flatpak-cli-transaction.c:584
#, c-format
msgid "Failed to install bundle %s%s%s: "
msgstr "Не вдалося встановити пакунок %s%s%s: "

#: app/flatpak-cli-transaction.c:591
#, c-format
msgid "Failed to uninstall %s%s%s: "
msgstr "Не вдалося вилучити %s%s%s: "

#: app/flatpak-cli-transaction.c:642
#, c-format
msgid "Authentication required for remote '%s'\n"
msgstr "Для доступу до віддаленого сховища «%s» слід пройти розпізнавання\n"

#: app/flatpak-cli-transaction.c:643
msgid "Open browser?"
msgstr "Відкрити браузер?"

#: app/flatpak-cli-transaction.c:699
#, c-format
msgid "Login required remote %s (realm %s)\n"
msgstr "Для входу до сховища %s потрібне ім'я користувача (область %s)\n"

#: app/flatpak-cli-transaction.c:704
msgid "Password"
msgstr "Пароль"

#. Only runtimes can be pinned
#: app/flatpak-cli-transaction.c:759
#, c-format
msgid ""
"\n"
"Info: (pinned) runtime %s%s%s branch %s%s%s is end-of-life, in favor of "
"%s%s%s branch %s%s%s\n"
msgstr ""
"\n"
"Інформація: строк супроводу (пришпиленого) середовища виконання %s%s%s, "
"гілка %s%s%s, завершено, його замінником є %s%s%s, гілка %s%s%s\n"

#: app/flatpak-cli-transaction.c:765
#, c-format
msgid ""
"\n"
"Info: runtime %s%s%s branch %s%s%s is end-of-life, in favor of %s%s%s branch "
"%s%s%s\n"
msgstr ""
"\n"
"Інформація: строк супроводу середовища виконання %s%s%s, гілка %s%s%s, "
"завершено, його замінником є %s%s%s, гілка %s%s%s\n"

#: app/flatpak-cli-transaction.c:768
#, c-format
msgid ""
"\n"
"Info: app %s%s%s branch %s%s%s is end-of-life, in favor of %s%s%s branch "
"%s%s%s\n"
msgstr ""
"\n"
"Інформація: строк супроводу програми %s%s%s, гілка %s%s%s, завершено, його "
"замінником є %s%s%s, гілка %s%s%s\n"

#. Only runtimes can be pinned
#: app/flatpak-cli-transaction.c:780
#, c-format
msgid ""
"\n"
"Info: (pinned) runtime %s%s%s branch %s%s%s is end-of-life, with reason:\n"
msgstr ""
"\n"
"Інформація: строк супроводу (пришпиленого) середовища виконання %s%s%s, "
"гілка %s%s%s, завершено, причина:\n"

#: app/flatpak-cli-transaction.c:786
#, c-format
msgid ""
"\n"
"Info: runtime %s%s%s branch %s%s%s is end-of-life, with reason:\n"
msgstr ""
"\n"
"Інформація: строк супроводу середовища виконання %s%s%s, гілка %s%s%s, "
"завершено, причина:\n"

#: app/flatpak-cli-transaction.c:789
#, c-format
msgid ""
"\n"
"Info: app %s%s%s branch %s%s%s is end-of-life, with reason:\n"
msgstr ""
"\n"
"Інформація: строк супроводу програми %s%s%s, гілка %s%s%s, завершено, "
"причина:\n"

#: app/flatpak-cli-transaction.c:963
#, c-format
msgid "Info: applications using this extension:\n"
msgstr "Інформація: програми, що використовують це розширення:\n"

#: app/flatpak-cli-transaction.c:965
#, c-format
msgid "Info: applications using this runtime:\n"
msgstr "Інформація: програми, що використовують це середовище виконання:\n"

#: app/flatpak-cli-transaction.c:984
msgid "Replace?"
msgstr "Замінити?"

#: app/flatpak-cli-transaction.c:987 app/flatpak-quiet-transaction.c:247
#, c-format
msgid "Updating to rebased version\n"
msgstr "Оновлюємо до перенесеної версії\n"

#: app/flatpak-cli-transaction.c:1011
#, c-format
msgid "Failed to rebase %s to %s: "
msgstr "Не вдалося перенести %s на %s: "

#: app/flatpak-cli-transaction.c:1277
#, c-format
msgid "New %s%s%s permissions:"
msgstr "Нові права доступу %s%s%s:"

#: app/flatpak-cli-transaction.c:1279
#, c-format
msgid "%s%s%s permissions:"
msgstr "Права доступу %s%s%s:"

#: app/flatpak-cli-transaction.c:1343
msgid "Warning: "
msgstr "Попередження: "

#. translators: This is short for operation, the title of a one-char column
#: app/flatpak-cli-transaction.c:1442
msgid "Op"
msgstr "Дія"

#. Avoid resizing the download column too much,
#. * by making the title as long as typical content
#.
#: app/flatpak-cli-transaction.c:1458 app/flatpak-cli-transaction.c:1503
msgid "partial"
msgstr "частка"

#: app/flatpak-cli-transaction.c:1535
msgid "Proceed with these changes to the user installation?"
msgstr "Продовжити із цими змінами у встановленому користувачем?"

#: app/flatpak-cli-transaction.c:1537
msgid "Proceed with these changes to the system installation?"
msgstr "Продовжити із цими змінами у встановленому загальносистемно?"

#: app/flatpak-cli-transaction.c:1539
#, c-format
msgid "Proceed with these changes to the %s?"
msgstr "Продовжити із цими змінами у %s?"

#: app/flatpak-cli-transaction.c:1711
msgid "Changes complete."
msgstr "Внесення змін завершено."

#: app/flatpak-cli-transaction.c:1713
msgid "Uninstall complete."
msgstr "Вилучення завершено."

#: app/flatpak-cli-transaction.c:1715
msgid "Installation complete."
msgstr "Встановлення завершено."

#: app/flatpak-cli-transaction.c:1717
msgid "Updates complete."
msgstr "Оновлення завершено."

#. For updates/!stop_on_first_error we already printed all errors so we make up
#. a different one.
#: app/flatpak-cli-transaction.c:1750
msgid "There were one or more errors"
msgstr "Сталася одна або декілька помилок"

#. translators: please keep the leading space
#: app/flatpak-main.c:76
msgid " Manage installed applications and runtimes"
msgstr " Керування встановленими програмами і середовищами виконання"

#: app/flatpak-main.c:77
msgid "Install an application or runtime"
msgstr "Встановити програму або середовище виконання"

#: app/flatpak-main.c:78
msgid "Update an installed application or runtime"
msgstr "Оновити встановлену програму або середовище виконання"

#: app/flatpak-main.c:81
msgid "Uninstall an installed application or runtime"
msgstr "Вилучити встановлену програму або середовище виконання"

#: app/flatpak-main.c:84
msgid "Mask out updates and automatic installation"
msgstr "Замаскувати оновлення та автоматичне встановлення"

#: app/flatpak-main.c:85
msgid "Pin a runtime to prevent automatic removal"
msgstr ""
"Пришпилити середовище виконання для запобігання автоматичному вилученні"

#: app/flatpak-main.c:86
msgid "List installed apps and/or runtimes"
msgstr "Вивести список встановлених програм і/або середовищ виконання"

#: app/flatpak-main.c:87
msgid "Show info for installed app or runtime"
msgstr ""
"Показати інформацію щодо встановленої програми або середовища виконання"

#: app/flatpak-main.c:88
msgid "Show history"
msgstr "Показати журнал"

#: app/flatpak-main.c:89
msgid "Configure flatpak"
msgstr "Налаштувати flatpak"

#: app/flatpak-main.c:90
msgid "Repair flatpak installation"
msgstr "Відновити встановлення flatpak"

#: app/flatpak-main.c:91
msgid "Put applications or runtimes onto removable media"
msgstr ""
"Розташувати програми або середовища виконання на портативному носієві даних"

#: app/flatpak-main.c:92
msgid "Install flatpaks that are part of the operating system"
msgstr ""

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:95
msgid ""
"\n"
" Find applications and runtimes"
msgstr ""
"\n"
" Пошук програм і середовищ"

#: app/flatpak-main.c:96
msgid "Search for remote apps/runtimes"
msgstr "Шукати віддалені програми або сховища"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:99
msgid ""
"\n"
" Manage running applications"
msgstr ""
"\n"
" Керування запущеними програмами"

#: app/flatpak-main.c:100
msgid "Run an application"
msgstr "Запустити програму"

#: app/flatpak-main.c:101
msgid "Override permissions for an application"
msgstr "Перевизначити права доступу для програми"

#: app/flatpak-main.c:102
msgid "Specify default version to run"
msgstr "Вказати типову версію для запуску"

#: app/flatpak-main.c:103
msgid "Enter the namespace of a running application"
msgstr "Введіть простір назв для запущеної програми"

#: app/flatpak-main.c:104
msgid "Enumerate running applications"
msgstr "Пронумерувати запущені програми"

#: app/flatpak-main.c:105
msgid "Stop a running application"
msgstr "Зупинити роботу запущеної програми"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:108
msgid ""
"\n"
" Manage file access"
msgstr ""
"\n"
" Керування доступом до файлів"

#: app/flatpak-main.c:109
msgid "List exported files"
msgstr "Вивести список експортованих файлів"

#: app/flatpak-main.c:110
msgid "Grant an application access to a specific file"
msgstr "Надати програмі доступ до вказаного файла"

#: app/flatpak-main.c:111
msgid "Revoke access to a specific file"
msgstr "Відкликати доступ до вказаного файла"

#: app/flatpak-main.c:112
msgid "Show information about a specific file"
msgstr "Показати інформацію щодо вказаного файла"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:116
msgid ""
"\n"
" Manage dynamic permissions"
msgstr ""
"\n"
" Керування динамічними правами доступу"

#: app/flatpak-main.c:117
msgid "List permissions"
msgstr "Показати список прав доступу"

#: app/flatpak-main.c:118
msgid "Remove item from permission store"
msgstr "Вилучити пункт зі сховища прав доступу"

#: app/flatpak-main.c:120
msgid "Set permissions"
msgstr "Встановити права доступу"

#: app/flatpak-main.c:121
msgid "Show app permissions"
msgstr "Показати права доступу програми"

#: app/flatpak-main.c:122
msgid "Reset app permissions"
msgstr "Скинути права доступу програми"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:125
msgid ""
"\n"
" Manage remote repositories"
msgstr ""
"\n"
" Керування віддаленими сховищами"

#: app/flatpak-main.c:126
msgid "List all configured remotes"
msgstr "Вивести список усіх налаштованих віддалених сховищ"

#: app/flatpak-main.c:127
msgid "Add a new remote repository (by URL)"
msgstr "Додати нове віддалене сховище (за адресою)"

#: app/flatpak-main.c:128
msgid "Modify properties of a configured remote"
msgstr "Змінити властивості налаштованого віддаленого сховища"

#: app/flatpak-main.c:129
msgid "Delete a configured remote"
msgstr "Вилучити налаштоване віддалене сховище"

#: app/flatpak-main.c:131
msgid "List contents of a configured remote"
msgstr "Вивести список вмісту налаштованого віддаленого сховища"

#: app/flatpak-main.c:132
msgid "Show information about a remote app or runtime"
msgstr "Показати відомості щодо віддаленої програми або середовища"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:135
msgid ""
"\n"
" Build applications"
msgstr ""
"\n"
" Зібрати програми"

#: app/flatpak-main.c:136
msgid "Initialize a directory for building"
msgstr "Ініціалізувати каталог для збирання"

#: app/flatpak-main.c:137
msgid "Run a build command inside the build dir"
msgstr "Виконати команду збирання у каталозі збирання"

#: app/flatpak-main.c:138
msgid "Finish a build dir for export"
msgstr "Завершити каталог збирання для експортування"

#: app/flatpak-main.c:139
msgid "Export a build dir to a repository"
msgstr "Експортувати каталог збирання до сховища"

#: app/flatpak-main.c:140
msgid "Create a bundle file from a ref in a local repository"
msgstr "Створити файл пакунка з посилання у локальному сховищі"

#: app/flatpak-main.c:141
msgid "Import a bundle file"
msgstr "Імпортувати файл пакунка"

#: app/flatpak-main.c:142
msgid "Sign an application or runtime"
msgstr "Підписати програму або середовище виконання"

#: app/flatpak-main.c:143
msgid "Update the summary file in a repository"
msgstr "Оновити файл резюме у сховищі"

#: app/flatpak-main.c:144
msgid "Create new commit based on existing ref"
msgstr "Створити внесок на основі наявного посилання"

#: app/flatpak-main.c:145
msgid "Show information about a repo"
msgstr "Вивести дані щодо сховища"

#: app/flatpak-main.c:162
msgid "Show debug information, -vv for more detail"
msgstr "Вивести діагностичні дані, -vv для збільшення докладності"

#: app/flatpak-main.c:163
msgid "Show OSTree debug information"
msgstr "Вивести діагностичні дані OSTree"

#: app/flatpak-main.c:169
msgid "Print version information and exit"
msgstr "Показати дані щодо версії і завершити роботу"

#: app/flatpak-main.c:170
msgid "Print default arch and exit"
msgstr "Вивести дані щодо типової архітектури і завершити роботу"

#: app/flatpak-main.c:171
msgid "Print supported arches and exit"
msgstr "Вивести список підтримуваних архітектур і завершити роботу"

#: app/flatpak-main.c:172
msgid "Print active gl drivers and exit"
msgstr "Вивести дані щодо активних драйверів gl і завершити роботу"

#: app/flatpak-main.c:173
msgid "Print paths for system installations and exit"
msgstr "Вивести дані щодо встановленого у системі і завершити роботу"

#: app/flatpak-main.c:174
msgid "Print the updated environment needed to run flatpaks"
msgstr "Вивести оновлене середовище, яке потрібне для запуску flatpak"

#: app/flatpak-main.c:175
msgid "Only include the system installation with --print-updated-env"
msgstr "Включати лише встановлення системи з --print-updated-env"

#: app/flatpak-main.c:180
msgid "Work on the user installation"
msgstr "Працювати над встановленим користувачем"

#: app/flatpak-main.c:181
msgid "Work on the system-wide installation (default)"
msgstr "Працювати над загальносистемними встановленими даними (типово)"

#: app/flatpak-main.c:182
msgid "Work on a non-default system-wide installation"
msgstr "Працювати із нетиповими загальносистемними встановленнями"

#: app/flatpak-main.c:212
msgid "Builtin Commands:"
msgstr "Вбудовані команди:"

#: app/flatpak-main.c:298
#, c-format
msgid ""
"Note that the directories %s are not in the search path set by the "
"XDG_DATA_DIRS environment variable, so applications installed by Flatpak may "
"not appear on your desktop until the session is restarted."
msgstr ""
"Зауважте, що каталоги %s не перебувають за шляхом для пошуку, встановленим "
"за допомогою змінної середовища XDG_DATA_DIRS, отже, програми, встановлені "
"Flatpak можуть не з'явитися на вашій стільниці, аж до перезапуску сеансу."

#: app/flatpak-main.c:312
#, c-format
msgid ""
"Note that the directory %s is not in the search path set by the "
"XDG_DATA_DIRS environment variable, so applications installed by Flatpak may "
"not appear on your desktop until the session is restarted."
msgstr ""
"Зауважте, що каталог %s не перебуває за шляхом для пошуку, встановленим за "
"допомогою змінної середовища XDG_DATA_DIRS, отже, програми, встановлені "
"Flatpak можуть не з'явитися на вашій стільниці, аж до перезапуску сеансу."

#: app/flatpak-main.c:381
msgid ""
"Refusing to operate under sudo with --user. Omit sudo to operate on the user "
"installation, or use a root shell to operate on the root user's installation."
msgstr ""
"Відмовляюся працювати з sudo з визначенням --user. Уникайте використання "
"sudo для роботи із встановленими для користувача пакунками або скористайтеся "
"оболонкою root для роботи з встановленими root пакунками користувача."

#: app/flatpak-main.c:453
msgid ""
"Multiple installations specified for a command that works on one installation"
msgstr ""
"Вказано декілька встановлень для для команди, яка працює для одного "
"встановлення"

#: app/flatpak-main.c:504 app/flatpak-main.c:697
#, c-format
msgid "See '%s --help'"
msgstr "Див. «%s --help»"

#: app/flatpak-main.c:706
#, c-format
msgid "'%s' is not a flatpak command. Did you mean '%s%s'?"
msgstr "«%s» не є командою flatpak. Можливо, ви мали на увазі «%s%s»?"

#: app/flatpak-main.c:709
#, c-format
msgid "'%s' is not a flatpak command"
msgstr "«%s» не є командою flatpak"

#: app/flatpak-main.c:824
msgid "No command specified"
msgstr "Команду не вказано"

#: app/flatpak-main.c:980
msgid "error:"
msgstr "помилка:"

#: app/flatpak-quiet-transaction.c:77
#, c-format
msgid "Installing %s\n"
msgstr "Встановлюємо %s\n"

#: app/flatpak-quiet-transaction.c:81
#, c-format
msgid "Updating %s\n"
msgstr "Оновлюємо %s\n"

#: app/flatpak-quiet-transaction.c:85
#, c-format
msgid "Uninstalling %s\n"
msgstr "Вилучаємо %s\n"

#: app/flatpak-quiet-transaction.c:107
#, c-format
msgid "Warning: Failed to install %s: %s\n"
msgstr "Попередження: не вдалося встановити %s: %s\n"

#: app/flatpak-quiet-transaction.c:110
#, c-format
msgid "Error: Failed to install %s: %s\n"
msgstr "Помилка: не вдалося встановити %s: %s\n"

#: app/flatpak-quiet-transaction.c:116
#, c-format
msgid "Warning: Failed to update %s: %s\n"
msgstr "Попередження: не вдалося оновити %s: %s\n"

#: app/flatpak-quiet-transaction.c:119
#, c-format
msgid "Error: Failed to update %s: %s\n"
msgstr "Помилка: не вдалося оновити %s: %s\n"

#: app/flatpak-quiet-transaction.c:125
#, c-format
msgid "Warning: Failed to install bundle %s: %s\n"
msgstr "Попередження: не вдалося встановити пакунок %s: %s\n"

#: app/flatpak-quiet-transaction.c:128
#, c-format
msgid "Error: Failed to install bundle %s: %s\n"
msgstr "Помилка: не вдалося встановити пакунок %s: %s\n"

#: app/flatpak-quiet-transaction.c:134
#, c-format
msgid "Warning: Failed to uninstall %s: %s\n"
msgstr "Попередження: не вдалося вилучити %s: %s\n"

#: app/flatpak-quiet-transaction.c:137
#, c-format
msgid "Error: Failed to uninstall %s: %s\n"
msgstr "Помилка: не вдалося вилучити %s: %s\n"

#: app/flatpak-quiet-transaction.c:166 common/flatpak-dir.c:11475
#, c-format
msgid "%s already installed"
msgstr "%s вже встановлено"

#: app/flatpak-quiet-transaction.c:168 common/flatpak-dir.c:3622
#: common/flatpak-dir.c:4321 common/flatpak-dir.c:16968
#: common/flatpak-dir.c:17258 common/flatpak-dir-utils.c:166
#: common/flatpak-dir-utils.c:259 common/flatpak-transaction.c:2736
#: common/flatpak-transaction.c:2791
#, c-format
msgid "%s not installed"
msgstr "%s не встановлено"

#: app/flatpak-quiet-transaction.c:170
#, c-format
msgid "%s needs a later flatpak version"
msgstr "%s потребує новішої версії flatpak"

#: app/flatpak-quiet-transaction.c:172
msgid "Not enough disk space to complete this operation"
msgstr "Для завершення дії на диску недостатньо вільного місця"

#: app/flatpak-quiet-transaction.c:239
#, c-format
msgid "Info: %s is end-of-life, in favor of %s\n"
msgstr "Інформація: термін підтримки %s сплив, встановіть %s\n"

#: app/flatpak-quiet-transaction.c:241
#, c-format
msgid "Info: %s is end-of-life, with reason: %s\n"
msgstr "Інформація: термін підтримки %s сплив, причина: %s\n"

#: app/flatpak-quiet-transaction.c:251
#, c-format
msgid "Failed to rebase %s to %s: %s\n"
msgstr "Не вдалося перенести %s на %s: %s\n"

#: common/flatpak-auth.c:58
#, c-format
msgid "No authenticator configured for remote `%s`"
msgstr "Для віддаленого сховища «%s» не налаштовано способу розпізнавання"

#: common/flatpak-context.c:637 common/flatpak-context.c:649
#, fuzzy, c-format
msgid "Invalid permission syntax: %s"
msgstr "Некоректна назва розширення %s"

#: common/flatpak-context.c:1207
#, c-format
msgid "Unknown share type %s, valid types are: %s"
msgstr "Невідомий тип спільного ресурсу %s, коректними типами є такі: %s"

#: common/flatpak-context.c:1228
#, c-format
msgid "Unknown policy type %s, valid types are: %s"
msgstr "Невідомий тип правил %s, коректними типами є такі: %s"

#: common/flatpak-context.c:1266
#, c-format
msgid "Invalid dbus name %s"
msgstr "Некоректна назва D-Bus, %s"

#: common/flatpak-context.c:1279
#, c-format
msgid "Unknown socket type %s, valid types are: %s"
msgstr "Невідомий тип сокета, %s, коректними типами є такі: %s"

#: common/flatpak-context.c:1294
#, c-format
msgid "Unknown device type %s, valid types are: %s"
msgstr "Невідомий тип пристрою, %s. Коректними типами є %s"

#: common/flatpak-context.c:1308
#, c-format
msgid "Unknown feature type %s, valid types are: %s"
msgstr "Невідомий тип можливості %s, коректними типами є такі: %s"

#: common/flatpak-context.c:1840
#, c-format
msgid "Filesystem location \"%s\" contains \"..\""
msgstr "Розташування файлової системи «%s» містить «..»"

#: common/flatpak-context.c:1882
#, c-format
msgid ""
"--filesystem=/ is not available, use --filesystem=host for a similar result"
msgstr ""
"--filesystem=/ є недоступним, скористайтеся --filesystem=host, щоб отримати "
"той самий результат"

#: common/flatpak-context.c:1916
#, fuzzy, c-format
msgid ""
"Unknown filesystem location %s, valid locations are: host, host-os, host-"
"etc, host-root, home, xdg-*[/…], ~/dir, /dir"
msgstr ""
"Невідоме розташування файлової системи, %s, коректними розташуваннями є "
"такі: host, host-os, host-etc, home, xdg-*[/…], ~/dir, /dir"

#: common/flatpak-context.c:2015
#, fuzzy, c-format
msgid "Invalid syntax for %s: %s"
msgstr "Некоректна назва %s: %s"

#: common/flatpak-context.c:2142
#, c-format
msgid "fallback-x11 can not be conditional"
msgstr ""

#: common/flatpak-context.c:2318
#, c-format
msgid "Invalid env format %s"
msgstr "Некоректне форматування середовища, %s"

#: common/flatpak-context.c:2399
#, c-format
msgid "Environment variable name must not contain '=': %s"
msgstr "У змінній середовища не повинно бути символу «=»: %s"

#: common/flatpak-context.c:2527 common/flatpak-context.c:2535
#, c-format
msgid "--add-policy arguments must be in the form SUBSYSTEM.KEY=VALUE"
msgstr ""
"Аргументи --add-policy має бути записано у такому форматі: "
"ПІДСИСТЕМА.КЛЮЧ=ЗНАЧЕННЯ"

#: common/flatpak-context.c:2542
#, c-format
msgid "--add-policy values can't start with \"!\""
msgstr "Значення --add-policy не можуть починатися з «!»"

#: common/flatpak-context.c:2567 common/flatpak-context.c:2575
#, c-format
msgid "--remove-policy arguments must be in the form SUBSYSTEM.KEY=VALUE"
msgstr ""
"Аргументи --remove-policy має бути записано у такому форматі: "
"ПІДСИСТЕМА.КЛЮЧ=ЗНАЧЕННЯ"

#: common/flatpak-context.c:2582
#, c-format
msgid "--remove-policy values can't start with \"!\""
msgstr "Значення --remove-policy не можуть починатися з «!»"

#: common/flatpak-context.c:2657
msgid "Share with host"
msgstr "Надати спільний доступ вузлу"

#: common/flatpak-context.c:2657 common/flatpak-context.c:2658
msgid "SHARE"
msgstr "СПІЛЬНИЙ РЕСУРС"

#: common/flatpak-context.c:2658
msgid "Unshare with host"
msgstr "Скасувати надання спільного ресурсу вузлу"

#: common/flatpak-context.c:2659
msgid "Require conditions to be met for a subsystem to get shared"
msgstr ""

#: common/flatpak-context.c:2659
msgid "SHARE:CONDITION"
msgstr ""

#: common/flatpak-context.c:2660
msgid "Expose socket to app"
msgstr "Відкрити сокет програмі"

#: common/flatpak-context.c:2660 common/flatpak-context.c:2661
msgid "SOCKET"
msgstr "СОКЕТ"

#: common/flatpak-context.c:2661
msgid "Don't expose socket to app"
msgstr "Не відкривати сокет програми"

#: common/flatpak-context.c:2662
msgid "Require conditions to be met for a socket to get exposed"
msgstr ""

#: common/flatpak-context.c:2662
msgid "SOCKET:CONDITION"
msgstr ""

#: common/flatpak-context.c:2663
msgid "Expose device to app"
msgstr "Відкрити пристрій програмі"

#: common/flatpak-context.c:2663 common/flatpak-context.c:2664
msgid "DEVICE"
msgstr "ПРИСТРІЙ"

#: common/flatpak-context.c:2664
msgid "Don't expose device to app"
msgstr "Не відкривати пристрій програмі"

#: common/flatpak-context.c:2665
msgid "Require conditions to be met for a device to get exposed"
msgstr ""

#: common/flatpak-context.c:2665
msgid "DEVICE:CONDITION"
msgstr ""

#: common/flatpak-context.c:2666
msgid "Allow feature"
msgstr "Увімкнути можливість"

#: common/flatpak-context.c:2666 common/flatpak-context.c:2667
msgid "FEATURE"
msgstr "МОЖЛИВІСТЬ"

#: common/flatpak-context.c:2667
msgid "Don't allow feature"
msgstr "Вимкнути можливість"

#: common/flatpak-context.c:2668
msgid "Require conditions to be met for a feature to get allowed"
msgstr ""

#: common/flatpak-context.c:2668
msgid "FEATURE:CONDITION"
msgstr ""

#: common/flatpak-context.c:2669
msgid "Expose filesystem to app (:ro for read-only)"
msgstr "Відкрити файлову систему програмі (:ro — лише для читання)"

#: common/flatpak-context.c:2669
msgid "FILESYSTEM[:ro]"
msgstr "ФАЙЛОВА_СИСТЕМА[:ro]"

#: common/flatpak-context.c:2670
msgid "Don't expose filesystem to app"
msgstr "Не відкривати файлову систему програмі"

#: common/flatpak-context.c:2670
msgid "FILESYSTEM"
msgstr "ФАЙЛОВА СИСТЕМА"

#: common/flatpak-context.c:2671
msgid "Set environment variable"
msgstr "Встановити змінну середовища"

#: common/flatpak-context.c:2671
msgid "VAR=VALUE"
msgstr "ЗМІННА=ЗНАЧЕННЯ"

#: common/flatpak-context.c:2672
msgid "Read environment variables in env -0 format from FD"
msgstr ""
"Прочитати змінні середовища у форматі env -0 з файла із вказаним дескриптором"

#: common/flatpak-context.c:2673
msgid "Remove variable from environment"
msgstr "Вилучити змінну з середовища"

#: common/flatpak-context.c:2673
msgid "VAR"
msgstr "ЗМІННА"

#: common/flatpak-context.c:2674
msgid "Allow app to own name on the session bus"
msgstr "Дозволити програмі бути власником назви на каналі сеансу"

#: common/flatpak-context.c:2674 common/flatpak-context.c:2675
#: common/flatpak-context.c:2676 common/flatpak-context.c:2677
#: common/flatpak-context.c:2678 common/flatpak-context.c:2679
#: common/flatpak-context.c:2680
msgid "DBUS_NAME"
msgstr "НАЗВА_DBUS"

#: common/flatpak-context.c:2675
msgid "Allow app to talk to name on the session bus"
msgstr "Дозволити програмі обмінюватися даними з назвою на каналі сеансу"

#: common/flatpak-context.c:2676
msgid "Don't allow app to talk to name on the session bus"
msgstr "Заборонити програмі обмінюватися даними з назвою на каналі сеансу"

#: common/flatpak-context.c:2677
msgid "Allow app to own name on the system bus"
msgstr "Дозволити програмі бути власником назви на каналі системи"

#: common/flatpak-context.c:2678
msgid "Allow app to talk to name on the system bus"
msgstr "Дозволити програмі обмінюватися даними з назвою на каналі системи"

#: common/flatpak-context.c:2679
msgid "Don't allow app to talk to name on the system bus"
msgstr "Заборонити програмі обмінюватися даними з назвою на каналі системи"

#: common/flatpak-context.c:2680
#, fuzzy
msgid "Allow app to own name on the a11y bus"
msgstr "Дозволити програмі бути власником назви на каналі системи"

#: common/flatpak-context.c:2681
msgid "Add generic policy option"
msgstr "Додати параметр загальних правил"

#: common/flatpak-context.c:2681 common/flatpak-context.c:2682
msgid "SUBSYSTEM.KEY=VALUE"
msgstr "ПІДСИСТЕМА.КЛЮЧ=ЗНАЧЕННЯ"

#: common/flatpak-context.c:2682
msgid "Remove generic policy option"
msgstr "Вилучити параметр загальних правил"

#: common/flatpak-context.c:2683
msgid "Add USB device to enumerables"
msgstr ""

#: common/flatpak-context.c:2683 common/flatpak-context.c:2684
msgid "VENDOR_ID:PRODUCT_ID"
msgstr ""

#: common/flatpak-context.c:2684
msgid "Add USB device to hidden list"
msgstr ""

#: common/flatpak-context.c:2685
msgid "A list of USB devices that are enumerable"
msgstr ""

#: common/flatpak-context.c:2685
msgid "LIST"
msgstr ""

#: common/flatpak-context.c:2686
msgid "File containing a list of USB devices to make enumerable"
msgstr ""

#: common/flatpak-context.c:2686 common/flatpak-context.c:2687
msgid "FILENAME"
msgstr "НАЗВА ФАЙЛА"

#: common/flatpak-context.c:2687
msgid "Persist home directory subpath"
msgstr "Не змінювати підшлях домашнього каталогу"

#. This is not needed/used anymore, so hidden, but we accept it for backwards compat
#: common/flatpak-context.c:2689
msgid "Don't require a running session (no cgroups creation)"
msgstr "Не вимагати запущеного сеансу (без створення cgroup)"

#: common/flatpak-context.c:3718
#, c-format
msgid "Not replacing \"%s\" with tmpfs: %s"
msgstr ""

#: common/flatpak-context.c:3726
#, c-format
msgid "Not sharing \"%s\" with sandbox: %s"
msgstr ""

#. Even if the error is one that we would normally silence, like
#. * the path not existing, it seems reasonable to make more of a fuss
#. * about the home directory not existing or otherwise being unusable,
#. * so this is intentionally not using cannot_export()
#: common/flatpak-context.c:3828
#, c-format
msgid "Not allowing home directory access: %s"
msgstr ""

#: common/flatpak-context.c:4062
#, fuzzy, c-format
msgid "Unable to provide a temporary home directory in the sandbox: %s"
msgstr "Не вдалося створити тимчасовий каталог у %s"

#: common/flatpak-dir.c:442
#, c-format
msgid "Configured collection ID ‘%s’ not in summary file"
msgstr "Налаштованого ідентифікатора збірки «%s» немає у файлі резюме"

#: common/flatpak-dir.c:587
#, c-format
msgid "Unable to load summary from remote %s: %s"
msgstr "Не вдалося завантажити резюме з віддаленого сховища %s: %s"

#: common/flatpak-dir.c:764 common/flatpak-dir.c:800 common/flatpak-dir.c:906
#, c-format
msgid "No such ref '%s' in remote %s"
msgstr "Немає такого джерела «%s» у сховищі %s"

#: common/flatpak-dir.c:891 common/flatpak-dir.c:1051 common/flatpak-dir.c:1080
#: common/flatpak-dir.c:1092
#, fuzzy, c-format
msgid "No entry for %s in remote %s summary flatpak cache"
msgstr "Немає запису %s у кеші flatpak резюме сховища «%s»"

#: common/flatpak-dir.c:1069
#, c-format
msgid "No summary or Flatpak cache available for remote %s"
msgstr "Немає резюме або кешу Flatpak для сховища %s"

#: common/flatpak-dir.c:1097
#, c-format
msgid "Missing xa.data in summary for remote %s"
msgstr "Не вистачає xa.data у резюме для віддаленого сховища %s"

#: common/flatpak-dir.c:1103 common/flatpak-dir.c:1546
#, c-format
msgid "Unsupported summary version %d for remote %s"
msgstr "Непідтримувана версія резюме, %d, для віддаленого сховища %s"

#: common/flatpak-dir.c:1200
msgid "Remote OCI index has no registry uri"
msgstr "У покажчику віддаленого OCI немає адреси реєстру"

#: common/flatpak-dir.c:1261
#, c-format
msgid "Couldn't find ref %s in remote %s"
msgstr "Не вдалося знайти посилання %s у віддаленому сховищі %s"

#: common/flatpak-dir.c:1288 common/flatpak-dir.c:1381
#, fuzzy, c-format
msgid "Commit has no requested ref ‘%s’ in ref binding metadata (found: ‘%s’)"
msgstr ""
"У внеску немає потрібного посилання «%s» у метаданих прив'язки до посилань"

#: common/flatpak-dir.c:1413
#, c-format
msgid "Configured collection ID ‘%s’ not in binding metadata"
msgstr "Налаштованого ідентифікатора збірки «%s» немає у метаданих прив'язки"

#: common/flatpak-dir.c:1449 common/flatpak-dir.c:5645
#, c-format
msgid "Couldn't find latest checksum for ref %s in remote %s"
msgstr ""
"Не вдалося знайти останню контрольну суму для %s у віддаленому сховищі %s"

#: common/flatpak-dir.c:1516 common/flatpak-dir.c:1552
#, c-format
msgid "No entry for %s in remote %s summary flatpak sparse cache"
msgstr "Немає запису %s у розрідженому кеші flatpak резюме сховища %s"

#: common/flatpak-dir.c:2540
#, c-format
msgid "Commit metadata for %s not matching expected metadata"
msgstr "Метадані внеску для %s не відповідають очікуваним метаданим"

#: common/flatpak-dir.c:2823
msgid "Unable to connect to system bus"
msgstr "Не вдалося встановити зв'язок із системним каналом даних"

#: common/flatpak-dir.c:3419
msgid "User installation"
msgstr "Встановлення для користувача"

#: common/flatpak-dir.c:3426
#, c-format
msgid "System (%s) installation"
msgstr "Встановлення системи (%s)"

#: common/flatpak-dir.c:3472
#, c-format
msgid "No overrides found for %s"
msgstr "Не знайдено перевизначень для %s"

#: common/flatpak-dir.c:3625
#, c-format
msgid "%s (commit %s) not installed"
msgstr "%s (внесок %s) не встановлено"

#: common/flatpak-dir.c:4650
#, c-format
msgid "Error parsing system flatpakrepo file for %s: %s"
msgstr ""
"Помилка під час спроби обробити загальносистемний файл flatpakrepo для %s: %s"

#: common/flatpak-dir.c:4735
#, c-format
msgid "While opening repository %s: "
msgstr "Під час спроби відкрити сховище %s: "

#: common/flatpak-dir.c:5004
#, c-format
msgid "The config key %s is not set"
msgstr "Ключ налаштування %s не встановлено"

#: common/flatpak-dir.c:5140
#, c-format
msgid "No current %s pattern matching %s"
msgstr "Жоден з поточних взірців %s не відповідає %s"

#: common/flatpak-dir.c:5422
msgid "No appstream commit to deploy"
msgstr "Немає внеску appstream для розгортання"

#: common/flatpak-dir.c:5941 common/flatpak-dir.c:7266
#: common/flatpak-dir.c:10881 common/flatpak-dir.c:11618
msgid "Can't pull from untrusted non-gpg verified remote"
msgstr ""
"Отримання даних з віддаленого сховища без довіри і перевірки gpg неможливе"

#: common/flatpak-dir.c:6376 common/flatpak-dir.c:6591
msgid "Extra data not supported for non-gpg-verified local system installs"
msgstr ""
"Для локальних встановлень у системі без перевірки gpg не передбачено "
"підтримки додаткових даних"

#: common/flatpak-dir.c:6415 common/flatpak-dir.c:6782
#, c-format
msgid "Invalid checksum for extra data uri %s"
msgstr "Некоректна контрольна сума для адреси додаткових даних %s"

#: common/flatpak-dir.c:6424
#, c-format
msgid "Empty name for extra data uri %s"
msgstr "Порожня назва для адреси додаткових даних %s"

#: common/flatpak-dir.c:6432
#, c-format
msgid "Unsupported extra data uri %s"
msgstr "Непідтримувана адреса додаткових даних %s"

#: common/flatpak-dir.c:6461
#, c-format
msgid "Failed to load local extra-data %s: %s"
msgstr "Не вдалося завантажити локальні додаткові дані %s: %s"

#: common/flatpak-dir.c:6469
#, c-format
msgid "Wrong size for extra-data %s"
msgstr "Помилковий розмір додаткових даних %s"

#: common/flatpak-dir.c:6488
#, c-format
msgid "While downloading %s: "
msgstr "Під час спроби отримання %s: "

#: common/flatpak-dir.c:6498
#, c-format
msgid "Wrong size for extra data %s"
msgstr "Помилковий розмір додаткових даних %s"

#: common/flatpak-dir.c:6507
#, c-format
msgid "Invalid checksum for extra data %s"
msgstr "Некоректна контрольна сума додаткових даних, %s"

#: common/flatpak-dir.c:7096 common/flatpak-dir.c:7349
#, c-format
msgid "While pulling %s from remote %s: "
msgstr "Під час отримання %s з віддаленого сховища %s: "

#: common/flatpak-dir.c:7290 common/flatpak-repo-utils.c:3886
msgid "GPG signatures found, but none are in trusted keyring"
msgstr ""
"Знайдено підписи GPG, але жоден із них не зберігається у сховищі надійних "
"ключів"

#: common/flatpak-dir.c:7307
#, c-format
msgid "Commit for ‘%s’ has no ref binding"
msgstr "Внесок для «%s» не має прив'язки до сховищ"

#: common/flatpak-dir.c:7312
#, c-format
msgid "Commit for ‘%s’ is not in expected bound refs: %s"
msgstr "Внесок для «%s» не перебуває у межах очікуваних сховищ: %s"

#: common/flatpak-dir.c:7488
msgid "Only applications can be made current"
msgstr "Поточними можна робити лише програми"

#: common/flatpak-dir.c:8192
msgid "Not enough memory"
msgstr "Не вистачає пам'яті"

#: common/flatpak-dir.c:8211
msgid "Failed to read from exported file"
msgstr "Не вдалося виконати читання з експортованого файла"

#: common/flatpak-dir.c:8401
msgid "Error reading mimetype xml file"
msgstr "Помилка під час читання файла xml типу MIME"

#: common/flatpak-dir.c:8406
msgid "Invalid mimetype xml file"
msgstr "Некоректний файл xml типу MIME"

#: common/flatpak-dir.c:8492
#, c-format
msgid "D-Bus service file '%s' has wrong name"
msgstr "Файл служби D-Bus «%s» має помилкову назву"

#: common/flatpak-dir.c:8647
#, c-format
msgid "Invalid Exec argument %s"
msgstr "Некоректний аргумент Exec, %s"

#: common/flatpak-dir.c:9115
msgid "While getting detached metadata: "
msgstr "Під час спроби отримання від’єднаних метаданих: "

#: common/flatpak-dir.c:9120 common/flatpak-dir.c:9125
#: common/flatpak-dir.c:9129
msgid "Extra data missing in detached metadata"
msgstr "У від’єднаних метаданих немає додаткових даних"

#: common/flatpak-dir.c:9133
msgid "While creating extradir: "
msgstr "Під час створення каталогу додаткових даних: "

#: common/flatpak-dir.c:9154 common/flatpak-dir.c:9187
msgid "Invalid checksum for extra data"
msgstr "Некоректна контрольна сума додаткових даних"

#: common/flatpak-dir.c:9183
msgid "Wrong size for extra data"
msgstr "Помилковий розмір додаткових даних"

#: common/flatpak-dir.c:9196
#, c-format
msgid "While writing extra data file '%s': "
msgstr "Під час записування файла додаткових даних «%s»: "

#: common/flatpak-dir.c:9204
#, c-format
msgid "Extra data %s missing in detached metadata"
msgstr "У від’єднаних метаданих немає додаткових даних %s"

#: common/flatpak-dir.c:9278
#, fuzzy, c-format
msgid "Unable to get runtime key from metadata"
msgstr "Використовувати альтернативний файл для метаданих"

#: common/flatpak-dir.c:9402
#, c-format
msgid "apply_extra script failed, exit status %d"
msgstr "Помилка скрипту apply_extra, стан виходу %d"

#. Translators: The placeholder is for an app ref.
#: common/flatpak-dir.c:9591
#, c-format
msgid "Installing %s is not allowed by the policy set by your administrator"
msgstr ""
"Встановлення %s заборонено правилами, які встановлено адміністратором вашої "
"системи"

#: common/flatpak-dir.c:9690
#, c-format
msgid "While trying to resolve ref %s: "
msgstr "Під час спроби визначити посилання %s: "

#: common/flatpak-dir.c:9702
#, c-format
msgid "%s is not available"
msgstr "%s недоступний"

#: common/flatpak-dir.c:9714 common/flatpak-dir.c:11495
#, c-format
msgid "%s commit %s already installed"
msgstr "%s, внесок %s вже встановлено"

#: common/flatpak-dir.c:9721
msgid "Can't create deploy directory"
msgstr "Не вдалося створити каталог розгортання"

#: common/flatpak-dir.c:9729
#, c-format
msgid "Failed to read commit %s: "
msgstr "Не вдалося прочитати внесок %s: "

#: common/flatpak-dir.c:9750
#, c-format
msgid "While trying to checkout %s into %s: "
msgstr "Під час спроби вивантаження %s до %s: "

#: common/flatpak-dir.c:9769
msgid "While trying to checkout metadata subpath: "
msgstr "Під час спроби вивантаження підшляху метаданих: "

#: common/flatpak-dir.c:9801
#, c-format
msgid "While trying to checkout subpath ‘%s’: "
msgstr "Під час спроби отримати підлеглий шлях «%s»: "

#: common/flatpak-dir.c:9811
msgid "While trying to remove existing extra dir: "
msgstr "Під час спроби вилучення наявного додаткового каталогу: "

#: common/flatpak-dir.c:9822
msgid "While trying to apply extra data: "
msgstr "Під час спроби застосування додаткових даних: "

#: common/flatpak-dir.c:9849
#, c-format
msgid "Invalid commit ref %s: "
msgstr "Некоректне посилання на внесок %s: "

#: common/flatpak-dir.c:9857 common/flatpak-dir.c:9869
#, c-format
msgid "Deployed ref %s does not match commit (%s)"
msgstr "Розміщене джерело %s не відповідає внеску (%s)"

#: common/flatpak-dir.c:9863
#, c-format
msgid "Deployed ref %s branch does not match commit (%s)"
msgstr "Гілка розміщеного посилання %s не відповідає внеску (%s)"

#: common/flatpak-dir.c:10125 common/flatpak-installation.c:1911
#, c-format
msgid "%s branch %s already installed"
msgstr "Гілку %s %s вже встановлено"

#: common/flatpak-dir.c:10985
#, c-format
msgid "Could not unmount revokefs-fuse filesystem at %s: "
msgstr "Не вдалося демонтувати файлову систему revokefs-fuse у %s: "

#: common/flatpak-dir.c:11289
#, c-format
msgid "This version of %s is already installed"
msgstr "Цю версію %s вже встановлено"

#: common/flatpak-dir.c:11302
#, c-format
msgid "Can't change remote during bundle install"
msgstr "Не можна змінювати сховище під час встановлення пакунка"

#: common/flatpak-dir.c:11571
msgid "Can't update to a specific commit without root permissions"
msgstr "Не вдалося оновитися до вказаного внеску без прав доступу root"

#: common/flatpak-dir.c:11852
#, c-format
msgid "Can't remove %s, it is needed for: %s"
msgstr "Не вдалося вилучити %s: цей запис потрібен для %s"

#: common/flatpak-dir.c:11912 common/flatpak-installation.c:2067
#, c-format
msgid "%s branch %s is not installed"
msgstr "%s, гілка %s не встановлено"

#: common/flatpak-dir.c:12165
#, c-format
msgid "%s commit %s not installed"
msgstr "%s, внесок %s не встановлено"

#: common/flatpak-dir.c:12501
#, c-format
msgid "Pruning repo failed: %s"
msgstr "Не вдалося спорожнити сховище: %s"

#: common/flatpak-dir.c:12669 common/flatpak-dir.c:12675
#, c-format
msgid "Failed to load filter '%s'"
msgstr "Не вдалося завантажити фільтр «%s»"

#: common/flatpak-dir.c:12681
#, c-format
msgid "Failed to parse filter '%s'"
msgstr "Не вдалося обробити фільтр «%s»"

#: common/flatpak-dir.c:12963
msgid "Failed to write summary cache: "
msgstr "Не вдалося записати кеш резюме: "

#: common/flatpak-dir.c:12982
#, c-format
msgid "No oci summary cached for remote '%s'"
msgstr "У кеші немає резюме oci для віддаленого сховища «%s»"

#: common/flatpak-dir.c:13207
#, c-format
msgid "No cached summary for remote '%s'"
msgstr "Немає кешованого резюме для віддаленого сховища «%s»"

#: common/flatpak-dir.c:13248
#, c-format
msgid "Invalid checksum for indexed summary %s read from %s"
msgstr ""
"Некоректна контрольна сума для індексованого резюме %s, яке прочитано з %s"

#: common/flatpak-dir.c:13321
#, c-format
msgid ""
"Remote listing for %s not available; server has no summary file. Check the "
"URL passed to remote-add was valid."
msgstr ""
"Список віддалених сховищ для %s є недоступним. На сервері немає файла "
"резюме. Перевірте, чи правильно вказано адресу, яку передано remote-add."

#: common/flatpak-dir.c:13698
#, c-format
msgid "Invalid checksum for indexed summary %s for remote '%s'"
msgstr ""
"Некоректна контрольна сума для індексованого резюме %s для віддаленого "
"сховища «%s»"

#: common/flatpak-dir.c:14388
#, c-format
msgid "Multiple branches available for %s, you must specify one of: "
msgstr ""
"Доступними є декілька гілок %s, вам слід вказати одне з таких значень: "

#: common/flatpak-dir.c:14454
#, c-format
msgid "Nothing matches %s"
msgstr "Немає відповідників %s"

#: common/flatpak-dir.c:14562
#, c-format
msgid "Can't find ref %s%s%s%s%s"
msgstr "Не вдалося знайти посилання %s%s%s%s%s"

#: common/flatpak-dir.c:14605
#, c-format
msgid "Error searching remote %s: %s"
msgstr "Помилка під час пошуку у віддаленому сховищі %s: %s"

#: common/flatpak-dir.c:14702
#, c-format
msgid "Error searching local repository: %s"
msgstr "Помилка під час пошуку у локальному сховищі: %s"

#: common/flatpak-dir.c:14839
#, c-format
msgid "%s/%s/%s not installed"
msgstr "%s/%s/%s не встановлено"

#: common/flatpak-dir.c:15042
#, c-format
msgid "Could not find installation %s"
msgstr "Не вдалося знайти встановлення %s"

#: common/flatpak-dir.c:15612
#, c-format
msgid "Invalid file format, no %s group"
msgstr "Некоректний формат файла, немає групи %s"

#: common/flatpak-dir.c:15617 common/flatpak-repo-utils.c:2836
#, c-format
msgid "Invalid version %s, only 1 supported"
msgstr "Некоректна версія %s, передбачено підтримку лише версії 1"

#: common/flatpak-dir.c:15622 common/flatpak-dir.c:15627
#, c-format
msgid "Invalid file format, no %s specified"
msgstr "Некоректний формат файла, не вказано %s"

#. Check some minimal size so we don't get crap
#: common/flatpak-dir.c:15647
msgid "Invalid file format, gpg key invalid"
msgstr "Некоректний формат файла, ключ gpg є некоректним"

#: common/flatpak-dir.c:15675 common/flatpak-repo-utils.c:2917
msgid "Collection ID requires GPG key to be provided"
msgstr "Визначення ідентифікатора збірки потребує надання ключа GPG"

#: common/flatpak-dir.c:15718
#, c-format
msgid "Runtime %s, branch %s is already installed"
msgstr "Середовище виконання %s, гілка %s вже встановлено"

#: common/flatpak-dir.c:15719
#, c-format
msgid "App %s, branch %s is already installed"
msgstr "Програму %s, гілка %s вже встановлено"

#: common/flatpak-dir.c:15953
#, c-format
msgid "Can't remove remote '%s' with installed ref %s (at least)"
msgstr ""
"Неможливо вилучити віддалене сховище «%s», оскільки (принаймні) встановлено "
"сховище %s"

#: common/flatpak-dir.c:16058
#, c-format
msgid "Invalid character '/' in remote name: %s"
msgstr "Некоректний символ, «/», у назві віддаленого сховища: %s"

#: common/flatpak-dir.c:16064
#, c-format
msgid "No configuration for remote %s specified"
msgstr "Не вказано налаштувань для віддаленого сховища %s"

#: common/flatpak-dir.c:17597
#, c-format
msgid "Skipping deletion of mirror ref (%s, %s)…\n"
msgstr "Пропускаємо вилучення посилання на дзеркало (%s, %s)…\n"

#: common/flatpak-exports.c:931
#, c-format
msgid "An absolute path is required"
msgstr ""

#: common/flatpak-exports.c:948
#, fuzzy, c-format
msgid "Unable to open path \"%s\": %s"
msgstr "Не вдалося оновити %s: %s\n"

#: common/flatpak-exports.c:955
#, fuzzy, c-format
msgid "Unable to get file type of \"%s\": %s"
msgstr "Не вдалося створити файл %s"

#: common/flatpak-exports.c:964
#, c-format
msgid "File \"%s\" has unsupported type 0o%o"
msgstr ""

#: common/flatpak-exports.c:970
#, c-format
msgid "Unable to get filesystem information for \"%s\": %s"
msgstr ""

#: common/flatpak-exports.c:980
#, c-format
msgid "Ignoring blocking autofs path \"%s\""
msgstr ""

#: common/flatpak-exports.c:996 common/flatpak-exports.c:1009
#: common/flatpak-exports.c:1022
#, c-format
msgid "Path \"%s\" is reserved by Flatpak"
msgstr ""

#: common/flatpak-exports.c:1076
#, fuzzy, c-format
msgid "Unable to resolve symbolic link \"%s\": %s"
msgstr "Не вдалося оновити символічне посилання %s/%s"

#: common/flatpak-glib-backports.c:69
msgid "Empty string is not a number"
msgstr "Порожній рядок не є числом"

#: common/flatpak-glib-backports.c:95
#, c-format
msgid "“%s” is not an unsigned number"
msgstr "«%s» не є додатним числом"

#: common/flatpak-glib-backports.c:105
#, c-format
msgid "Number “%s” is out of bounds [%s, %s]"
msgstr "Число «%s» не належить до діапазону [%s, %s]"

#: common/flatpak-image-source.c:83
msgid "Only sha256 image checksums are supported"
msgstr ""

#: common/flatpak-image-source.c:100 common/flatpak-image-source.c:108
msgid "Image is not a manifest"
msgstr "Образ не є маніфестом"

#: common/flatpak-image-source.c:123
msgid "No org.flatpak.ref found in image"
msgstr ""

#: common/flatpak-image-source.c:148
#, c-format
msgid "Ref '%s' not found in registry"
msgstr "Посилання «%s» немає у реєстрі"

#: common/flatpak-image-source.c:157
msgid "Multiple images in registry, specify a ref with --ref"
msgstr "У реєстрі декілька образів, вкажіть посилання за допомогою --ref"

#: common/flatpak-installation.c:834
#, c-format
msgid "Ref %s not installed"
msgstr "Сховище %s не встановлено"

#: common/flatpak-installation.c:875
#, c-format
msgid "App %s not installed"
msgstr "Програму %s не встановлено"

#: common/flatpak-installation.c:1395
#, c-format
msgid "Remote '%s' already exists"
msgstr "Запис віддаленого сховища «%s» вже існує"

#: common/flatpak-installation.c:1946
#, c-format
msgid "As requested, %s was only pulled, but not installed"
msgstr "Як і було наказано, лише отримали %s, без встановлення"

#: common/flatpak-instance.c:533 common/flatpak-instance.c:687
#: common/flatpak-instance.c:728
#, c-format
msgid "Unable to create directory %s"
msgstr "Не вдалося створити каталог %s"

#: common/flatpak-instance.c:554
#, c-format
msgid "Unable to lock %s"
msgstr "Не вдалося заблокувати %s"

#: common/flatpak-instance.c:627
#, c-format
msgid "Unable to create temporary directory in %s"
msgstr "Не вдалося створити тимчасовий каталог у %s"

#: common/flatpak-instance.c:639
#, c-format
msgid "Unable to create file %s"
msgstr "Не вдалося створити файл %s"

#: common/flatpak-instance.c:646
#, c-format
msgid "Unable to update symbolic link %s/%s"
msgstr "Не вдалося оновити символічне посилання %s/%s"

#: common/flatpak-oci-registry.c:1197
msgid "Only Bearer authentication supported"
msgstr "Передбачено підтримку лише розпізнавання Bearer"

#: common/flatpak-oci-registry.c:1206
msgid "Only realm in authentication request"
msgstr "У запиті щодо розпізнавання вказано лише область"

#: common/flatpak-oci-registry.c:1213
msgid "Invalid realm in authentication request"
msgstr "У запиті щодо розпізнавання вказано некоректну область"

#: common/flatpak-oci-registry.c:1283
#, c-format
msgid "Authorization failed: %s"
msgstr "Помилка під час спроби уповноваження: %s"

#: common/flatpak-oci-registry.c:1285
msgid "Authorization failed"
msgstr "Помилка при авторизації"

#: common/flatpak-oci-registry.c:1289
#, c-format
msgid "Unexpected response status %d when requesting token: %s"
msgstr ""
"Неочікуваний стан відповіді %d під час надсилання запиту щодо ключа: %s"

#: common/flatpak-oci-registry.c:1300
msgid "Invalid authentication request response"
msgstr "Некоректне відповідь на запит щодо розпізнавання"

#: common/flatpak-oci-registry.c:1731
#, c-format
msgid "Flatpak was compiled without zstd support"
msgstr ""

#: common/flatpak-oci-registry.c:1923 common/flatpak-oci-registry.c:1975
#: common/flatpak-oci-registry.c:2004 common/flatpak-oci-registry.c:2059
#: common/flatpak-oci-registry.c:2115 common/flatpak-oci-registry.c:2193
msgid "Invalid delta file format"
msgstr "Некоректне форматування файла різниці"

#: common/flatpak-oci-registry.c:3198 common/flatpak-oci-registry.c:3382
msgid "Invalid OCI image config"
msgstr "Некоректне налаштування образу OCI"

#: common/flatpak-oci-registry.c:3260 common/flatpak-oci-registry.c:3531
#, c-format
msgid "Wrong layer checksum, expected %s, was %s"
msgstr "Помилкова контрольна сума шару, мало бути %s, маємо %s"

#: common/flatpak-oci-registry.c:3359
#, c-format
msgid "No ref specified for OCI image %s"
msgstr "Не вказано сховища для образу OCI %s"

#: common/flatpak-oci-registry.c:3369
#, c-format
msgid "Wrong ref (%s) specified for OCI image %s, expected %s"
msgstr "Вказано помилкове сховище (%s) для образу OCI %s, мало бути %s"

#: common/flatpak-progress.c:236
#, c-format
msgid "Downloading metadata: %u/(estimating) %s"
msgstr "Отримуємо метадані: %u/(оцінка) %s"

#: common/flatpak-progress.c:260
#, c-format
msgid "Downloading: %s/%s"
msgstr "Отримуємо: %s/%s"

#: common/flatpak-progress.c:280
#, c-format
msgid "Downloading extra data: %s/%s"
msgstr "Отримуємо додаткові дані: %s з %s"

#: common/flatpak-progress.c:285
#, c-format
msgid "Downloading files: %d/%d %s"
msgstr "Отримуємо файли: %d з %d %s"

#: common/flatpak-ref-utils.c:122
msgid "Name can't be empty"
msgstr "Назва не може бути порожньою"

#: common/flatpak-ref-utils.c:129
msgid "Name can't be longer than 255 characters"
msgstr "Назва не може бути довшою за 255 символів"

#: common/flatpak-ref-utils.c:142
msgid "Name can't start with a period"
msgstr "Назва не може починатися з крапки"

#: common/flatpak-ref-utils.c:148
#, c-format
msgid "Name can't start with %c"
msgstr "Назва не може починатися з %c"

#: common/flatpak-ref-utils.c:164
msgid "Name can't end with a period"
msgstr "Назва не може завершуватися крапкою"

#: common/flatpak-ref-utils.c:171 common/flatpak-ref-utils.c:183
msgid "Only last name segment can contain -"
msgstr "Містити «-» може лише останній сегмент назви"

#: common/flatpak-ref-utils.c:174
#, c-format
msgid "Name segment can't start with %c"
msgstr "Назва сегмента не може починатися з %c"

#: common/flatpak-ref-utils.c:186
#, c-format
msgid "Name can't contain %c"
msgstr "Назва не може містити %c"

#: common/flatpak-ref-utils.c:195
msgid "Names must contain at least 2 periods"
msgstr "У назві має бути принаймні 2 крапки"

#: common/flatpak-ref-utils.c:312
msgid "Arch can't be empty"
msgstr "Архітектура не може бути порожньою"

#: common/flatpak-ref-utils.c:323
#, c-format
msgid "Arch can't contain %c"
msgstr "Архітектура не може містити %c"

#: common/flatpak-ref-utils.c:385
msgid "Branch can't be empty"
msgstr "Гілка не може бути порожньою"

#: common/flatpak-ref-utils.c:395
#, c-format
msgid "Branch can't start with %c"
msgstr "Гілка не може починатися з %c"

#: common/flatpak-ref-utils.c:405
#, c-format
msgid "Branch can't contain %c"
msgstr "Гілка не може містити %c"

#: common/flatpak-ref-utils.c:615 common/flatpak-ref-utils.c:865
msgid "Ref too long"
msgstr "Посилання є надто довгим"

#: common/flatpak-ref-utils.c:627
msgid "Invalid remote name"
msgstr "Некоректна назва віддаленого сховища"

#: common/flatpak-ref-utils.c:641
#, c-format
msgid "%s is not application or runtime"
msgstr "%s не є програмою або середовищем виконання"

#: common/flatpak-ref-utils.c:650 common/flatpak-ref-utils.c:667
#: common/flatpak-ref-utils.c:683
#, c-format
msgid "Wrong number of components in %s"
msgstr "Помилкова кількість компонентів у %s"

#: common/flatpak-ref-utils.c:656
#, c-format
msgid "Invalid name %.*s: %s"
msgstr "Некоректна назва %.*s: %s"

#: common/flatpak-ref-utils.c:673
#, c-format
msgid "Invalid arch: %.*s: %s"
msgstr "Некоректна архітектура: %.*s: %s"

#: common/flatpak-ref-utils.c:816
#, c-format
msgid "Invalid name %s: %s"
msgstr "Некоректна назва %s: %s"

#: common/flatpak-ref-utils.c:834
#, c-format
msgid "Invalid arch: %s: %s"
msgstr "Некоректна архітектура: %s: %s"

#: common/flatpak-ref-utils.c:853
#, c-format
msgid "Invalid branch: %s: %s"
msgstr "Некоректна гілка: %s: %s"

#: common/flatpak-ref-utils.c:962 common/flatpak-ref-utils.c:970
#: common/flatpak-ref-utils.c:978
#, c-format
msgid "Wrong number of components in partial ref %s"
msgstr "Помилкова кількість компонентів у частковому посиланні %s"

#: common/flatpak-ref-utils.c:1298
msgid " development platform"
msgstr " платформа для розробки"

#: common/flatpak-ref-utils.c:1300
msgid " platform"
msgstr " платформа"

#: common/flatpak-ref-utils.c:1302
msgid " application base"
msgstr " основа для програм"

#: common/flatpak-ref-utils.c:1305
msgid " debug symbols"
msgstr " дані для діагностики"

#: common/flatpak-ref-utils.c:1307
msgid " sourcecode"
msgstr " початковий код"

#: common/flatpak-ref-utils.c:1309
msgid " translations"
msgstr " переклади"

#: common/flatpak-ref-utils.c:1311
msgid " docs"
msgstr " документація"

#: common/flatpak-ref-utils.c:1578
#, c-format
msgid "Invalid id %s: %s"
msgstr "Некоректний ідентифікатор %s: %s"

#: common/flatpak-remote.c:1216
#, c-format
msgid "Bad remote name: %s"
msgstr "Помилкова назва віддаленого сховища: %s"

#: common/flatpak-remote.c:1220
#, fuzzy
msgid "No URL specified"
msgstr "Не вказано адреси"

#: common/flatpak-remote.c:1266
msgid "GPG verification must be enabled when a collection ID is set"
msgstr ""
"Якщо встановлено ідентифікатор збірки, має бути увімкнено перевірку за GPG"

#: common/flatpak-repo-utils.c:344
#, c-format
msgid "No extra data sources"
msgstr "Немає джерел додаткових даних"

#: common/flatpak-repo-utils.c:2817
#, c-format
msgid "Invalid %s: Missing group ‘%s’"
msgstr "Некоректний %s: пропущено групу «%s»"

#: common/flatpak-repo-utils.c:2826
#, c-format
msgid "Invalid %s: Missing key ‘%s’"
msgstr "Некоректний %s: пропущено ключ «%s»"

#: common/flatpak-repo-utils.c:2876
msgid "Invalid gpg key"
msgstr "Некоректний ключ gpg"

#: common/flatpak-repo-utils.c:3217
#, c-format
msgid "Error copying 64x64 icon for component %s: %s\n"
msgstr "Помилка під час копіювання піктограми 64x64 для компонента %s: %s\n"

#: common/flatpak-repo-utils.c:3223
#, c-format
msgid "Error copying 128x128 icon for component %s: %s\n"
msgstr "Помилка під час копіювання піктограми 128x128 для компонента %s: %s\n"

#: common/flatpak-repo-utils.c:3362
#, c-format
msgid "%s is end-of-life, ignoring for appstream"
msgstr "Строк підтримки %s минув, ігноруємо для appstream"

#: common/flatpak-repo-utils.c:3397
#, c-format
msgid "No appstream data for %s: %s\n"
msgstr "Немає даних appstream для %s: %s\n"

#: common/flatpak-repo-utils.c:3744
msgid "Invalid bundle, no ref in metadata"
msgstr "Некоректний пакунок, немає сховища у метаданих"

#: common/flatpak-repo-utils.c:3846
#, c-format
msgid "Collection ‘%s’ of bundle doesn’t match collection ‘%s’ of remote"
msgstr "Збірка «%s» пакунка не відповідає збірці «%s» віддаленого сховища"

#: common/flatpak-repo-utils.c:3923
msgid "Metadata in header and app are inconsistent"
msgstr "Метадані у заголовку і програмі є несумісними"

#: common/flatpak-run.c:951
msgid "No systemd user session available, cgroups not available"
msgstr "Немає доступного сеансу користувача systemd, cgroups є недоступними"

#: common/flatpak-run.c:1496
msgid "Unable to allocate instance id"
msgstr "Не вдалося розмістити у пам'яті ідентифікатор екземпляра"

#: common/flatpak-run.c:1632 common/flatpak-run.c:1641
#, c-format
msgid "Failed to open flatpak-info file: %s"
msgstr "Не вдалося відкрити файл flatpak-info: %s"

#: common/flatpak-run.c:1668
#, c-format
msgid "Failed to open bwrapinfo.json file: %s"
msgstr "Не вдалося відкрити файл bwrapinfo.json: %s"

#: common/flatpak-run.c:1689
#, c-format
msgid "Failed to write to instance id fd: %s"
msgstr "Не вдалося записати дескриптор файла до ідентифікатора екземпляра: %s"

#: common/flatpak-run.c:2096
msgid "Initialize seccomp failed"
msgstr "Не вдалося ініціалізувати seccomp"

#: common/flatpak-run.c:2135
#, c-format
msgid "Failed to add architecture to seccomp filter: %s"
msgstr "Не вдалося додати архітектуру до фільтра seccomp: %s"

#: common/flatpak-run.c:2143
#, c-format
msgid "Failed to add multiarch architecture to seccomp filter: %s"
msgstr "Не вдалося додати архітектуру multiarch до фільтра seccomp: %s"

#: common/flatpak-run.c:2175 common/flatpak-run.c:2192
#: common/flatpak-run.c:2214
#, c-format
msgid "Failed to block syscall %d: %s"
msgstr "Не вдалося заблокувати системний виклик %d: %s"

#: common/flatpak-run.c:2247
#, c-format
msgid "Failed to export bpf: %s"
msgstr "Не вдалося експортувати bpf: %s"

#: common/flatpak-run.c:2587
#, c-format
msgid "Failed to open ‘%s’"
msgstr "Не вдалося відкрити «%s»"

#: common/flatpak-run.c:2597
#, c-format
msgid ""
"Directory forwarding needs version 4 of the document portal (have version %d)"
msgstr ""

#: common/flatpak-run.c:2915
#, c-format
msgid "ldconfig failed, exit status %d"
msgstr "Помилка ldconfig, стан виходу %d"

#: common/flatpak-run.c:2922
msgid "Can't open generated ld.so.cache"
msgstr "Не вдалося відкрити створений ld.so.cache"

#. Translators: The placeholder is for an app ref.
#: common/flatpak-run.c:3045
#, c-format
msgid "Running %s is not allowed by the policy set by your administrator"
msgstr ""
"Запуск %s заборонено правилами, які встановлено адміністратором вашої системи"

#: common/flatpak-run.c:3202
msgid ""
"\"flatpak run\" is not intended to be run as `sudo flatpak run`. Use `sudo "
"-i` or `su -l` instead and invoke \"flatpak run\" from inside the new shell."
msgstr ""
"«flatpak run» не призначено для запуску як «sudo flatpak run», скористайтеся "
"замість цього «sudo -i» або «su -l» і викличте «flatpak run» з нової "
"командної оболонки"

#: common/flatpak-run.c:3413
#, c-format
msgid "Failed to migrate from %s: %s"
msgstr "Не вдалося перенести з %s: %s"

#: common/flatpak-run.c:3434
#, c-format
msgid "Failed to migrate old app data directory %s to new name %s: %s"
msgstr "Не вдалося перенести каталог даних старої програми %s до нового %s: %s"

#: common/flatpak-run.c:3443
#, c-format
msgid "Failed to create symlink while migrating %s: %s"
msgstr "Не вдалося створити символічне посилання під час перенесення %s: %s"

#: common/flatpak-run-dbus.c:46
msgid "Failed to open app info file"
msgstr "Не вдалося відкрити файл інформації щодо програми"

#: common/flatpak-run-dbus.c:149
msgid "Unable to create sync pipe"
msgstr "Не вдалося створити канал синхронізації"

#: common/flatpak-run-dbus.c:185
msgid "Failed to sync with dbus proxy"
msgstr "Не вдалося виконати синхронізацію із проміжним D-Bus"

#: common/flatpak-transaction.c:2275
#, c-format
msgid "Warning: Problem looking for related refs: %s"
msgstr "Попередження: проблема під час пошуку пов’язаних посилань: %s"

#: common/flatpak-transaction.c:2493
#, c-format
msgid "The application %s requires the runtime %s which was not found"
msgstr "Програма %s потребує середовища виконання %s, яке не знайдено"

#: common/flatpak-transaction.c:2509
#, c-format
msgid "The application %s requires the runtime %s which is not installed"
msgstr "Програма %s потребує середовища виконання %s, яке не встановлено"

#: common/flatpak-transaction.c:2641
#, c-format
msgid "Can't uninstall %s which is needed by %s"
msgstr "Не вдалося вилучити %s, оскільки цей запис потрібен для %s"

#: common/flatpak-transaction.c:2740
#, c-format
msgid "Remote %s disabled, ignoring %s update"
msgstr "Сховище %s вимкнено, ігноруємо оновлення %s"

#: common/flatpak-transaction.c:2773
#, c-format
msgid "%s is already installed"
msgstr "%s вже встановлено"

#: common/flatpak-transaction.c:2776
#, c-format
msgid "%s is already installed from remote %s"
msgstr "%s вже встановлено із віддаленого сховища %s"

#: common/flatpak-transaction.c:3120
#, c-format
msgid "Invalid .flatpakref: %s"
msgstr "Некоректний .flatpakref: %s"

#: common/flatpak-transaction.c:3161
msgid "Warning: Could not mark already installed apps as preinstalled"
msgstr ""

#: common/flatpak-transaction.c:3382
#, c-format
msgid "Error updating remote metadata for '%s': %s"
msgstr "Помилка під час оновлення метаданих сховища для «%s»: %s"

#: common/flatpak-transaction.c:3885
#, c-format
msgid ""
"Warning: Treating remote fetch error as non-fatal since %s is already "
"installed: %s"
msgstr ""
"Попередження: вважаємо помилку отримання даних віддаленого сховища "
"некритичною, оскільки %s вже встановлено: %s"

#: common/flatpak-transaction.c:4209
#, c-format
msgid "No authenticator installed for remote '%s'"
msgstr "Не встановлено засобу розпізнавання для віддаленого сховища «%s»"

#: common/flatpak-transaction.c:4313 common/flatpak-transaction.c:4320
#, c-format
msgid "Failed to get tokens for ref: %s"
msgstr "Не вдалося отримати ключі для посилання: %s"

#: common/flatpak-transaction.c:4315 common/flatpak-transaction.c:4322
msgid "Failed to get tokens for ref"
msgstr "Не вдалося отримати ключі для посилання"

#: common/flatpak-transaction.c:4580
#, c-format
msgid "Ref %s from %s matches more than one transaction operation"
msgstr "Посилання %s з %s відповідає декількома діям з перенесення"

#: common/flatpak-transaction.c:4581 common/flatpak-transaction.c:4591
msgid "any remote"
msgstr "будь-яке віддалене сховище"

#: common/flatpak-transaction.c:4590
#, c-format
msgid "No transaction operation found for ref %s from %s"
msgstr "Не знайдено операції для посилання %s з %s"

#: common/flatpak-transaction.c:4713
#, c-format
msgid "Flatpakrepo URL %s not file, HTTP or HTTPS"
msgstr ""
"Адреса Flatpakrepo %s не є ні файлом, ні адресою HTTP, ні адресою HTTPS"

#: common/flatpak-transaction.c:4719
#, c-format
msgid "Can't load dependent file %s: "
msgstr "Не вдалося завантажити залежний файл %s: "

#: common/flatpak-transaction.c:4727
#, c-format
msgid "Invalid .flatpakrepo: %s"
msgstr "Некоректний .flatpakrepo: %s"

#: common/flatpak-transaction.c:5454
msgid "Transaction already executed"
msgstr "Операцію вже виконано"

#: common/flatpak-transaction.c:5469
msgid ""
"Refusing to operate on a user installation as root! This can lead to "
"incorrect file ownership and permission errors."
msgstr ""
"Дії від імені root у каталогах звичайного користувача не виконуватимуться! "
"Виконання таких дій може призвести до помилок у визначенні власника об'єктів "
"та прав доступу."

#: common/flatpak-transaction.c:5567 common/flatpak-transaction.c:5580
msgid "Aborted by user"
msgstr "Перервано користувачем"

#: common/flatpak-transaction.c:5605
#, c-format
msgid "Skipping %s due to previous error"
msgstr "Пропускаємо %s через попередню помилку"

#: common/flatpak-transaction.c:5659
#, c-format
msgid "Aborted due to failure (%s)"
msgstr "Перервано через критичну помилку (%s)"

#: common/flatpak-uri.c:118
#, no-c-format
msgid "Invalid %-encoding in URI"
msgstr "Некоректне %-eкодування в адресі"

#: common/flatpak-uri.c:135
msgid "Illegal character in URI"
msgstr "Некоректний символ в адресі"

#: common/flatpak-uri.c:169
msgid "Non-UTF-8 characters in URI"
msgstr "Символи поза UTF-8 в адресі"

#: common/flatpak-uri.c:275
#, c-format
msgid "Invalid IPv6 address ‘%.*s’ in URI"
msgstr "Некоректна IPv6-адреса «%.*s» в адресі"

#: common/flatpak-uri.c:330
#, c-format
msgid "Illegal encoded IP address ‘%.*s’ in URI"
msgstr "Помилкове кодування IP-адреси «%.*s» в адресі"

#: common/flatpak-uri.c:342
#, c-format
msgid "Illegal internationalized hostname ‘%.*s’ in URI"
msgstr "Назва вузла із некоректними символами «%.*s» у адресі"

#: common/flatpak-uri.c:374 common/flatpak-uri.c:386
#, c-format
msgid "Could not parse port ‘%.*s’ in URI"
msgstr "Не вдалося обробити запис порту «%.*s» в адресі"

#: common/flatpak-uri.c:393
#, c-format
msgid "Port ‘%.*s’ in URI is out of range"
msgstr "Порт «%.*s» в адресі не належить до припустимого діапазону"

#: common/flatpak-uri.c:910
msgid "URI is not absolute, and no base URI was provided"
msgstr "Адреса не є абсолютною, і не вказано базової адреси"

#: common/flatpak-usb.c:83
#, c-format
msgid "USB device query 'all' must not have data"
msgstr ""

#: common/flatpak-usb.c:102
#, c-format
msgid "USB query rule 'cls' must be in the form CLASS:SUBCLASS or CLASS:*"
msgstr ""

#: common/flatpak-usb.c:111
#, fuzzy, c-format
msgid "Invalid USB class"
msgstr "Некоректний ідентифікатор %s: %s"

#: common/flatpak-usb.c:125
#, c-format
msgid "Invalid USB subclass"
msgstr ""

#: common/flatpak-usb.c:141 common/flatpak-usb.c:148
#, c-format
msgid "USB query rule 'dev' must have a valid 4-digit hexadecimal product id"
msgstr ""

#: common/flatpak-usb.c:164 common/flatpak-usb.c:171
#, c-format
msgid "USB query rule 'vnd' must have a valid 4-digit hexadecimal vendor id"
msgstr ""

#: common/flatpak-usb.c:205
#, c-format
msgid "USB device queries must be in the form TYPE:DATA"
msgstr ""

#: common/flatpak-usb.c:225
#, c-format
msgid "Unknown USB query rule %s"
msgstr ""

#: common/flatpak-usb.c:248
#, c-format
msgid "Empty USB query"
msgstr ""

#: common/flatpak-usb.c:274
#, c-format
msgid "Multiple USB query rules of the same type is not supported"
msgstr ""

#: common/flatpak-usb.c:283
#, c-format
msgid "'all' must not contain extra query rules"
msgstr ""

#: common/flatpak-usb.c:291
#, c-format
msgid "USB queries with 'dev' must also specify vendors"
msgstr ""

#: common/flatpak-utils.c:712
msgid "Glob can't match apps"
msgstr "Вираз-замінник не може відповідати програмам"

#: common/flatpak-utils.c:737
msgid "Empty glob"
msgstr "Порожній вираз-замінник"

#: common/flatpak-utils.c:756
msgid "Too many segments in glob"
msgstr "Забагато аргументів у виразі-заміннику"

#: common/flatpak-utils.c:777
#, c-format
msgid "Invalid glob character '%c'"
msgstr "Некоректний символ у виразі-заміннику, «%c»"

#: common/flatpak-utils.c:831
#, c-format
msgid "Missing glob on line %d"
msgstr "Пропущено вираз-замінник у рядку %d"

#: common/flatpak-utils.c:835
#, c-format
msgid "Trailing text on line %d"
msgstr "Зайвий текст наприкінці рядка %d"

#: common/flatpak-utils.c:839
#, c-format
msgid "on line %d"
msgstr "у рядку %d"

#: common/flatpak-utils.c:861
#, c-format
msgid "Unexpected word '%s' on line %d"
msgstr "Неочікуване слово «%s» у рядку %d"

#: common/flatpak-utils.c:2118
#, c-format
msgid "Invalid require-flatpak argument %s"
msgstr "Некоректний аргумент require-flatpak, %s"

#: common/flatpak-utils.c:2128 common/flatpak-utils.c:2147
#, c-format
msgid "%s needs a later flatpak version (%s)"
msgstr "%s потребує новішої версії flatpak (%s)"

#: oci-authenticator/flatpak-oci-authenticator.c:291
msgid "Not a oci remote, missing summary.xa.oci-repository"
msgstr "Не є віддаленим сховищем oci, не вистачає summary.xa.oci-repository"

#: oci-authenticator/flatpak-oci-authenticator.c:477
msgid "Not a OCI remote"
msgstr "Не є віддаленим сховищем OCI"

#: oci-authenticator/flatpak-oci-authenticator.c:488
msgid "Invalid token"
msgstr "Некоректний ключ"

#: portal/flatpak-portal.c:2292
#, c-format
msgid "No portal support found"
msgstr "Не виявлено підтримки порталу"

#: portal/flatpak-portal.c:2298
msgid "Deny"
msgstr "Заборонити"

#: portal/flatpak-portal.c:2300
msgid "Update"
msgstr "Оновлення"

#: portal/flatpak-portal.c:2305
#, c-format
msgid "Update %s?"
msgstr "Оновити %s?"

#: portal/flatpak-portal.c:2317
msgid "The application wants to update itself."
msgstr "Програма хоче оновити саму себе."

#: portal/flatpak-portal.c:2318
msgid "Update access can be changed any time from the privacy settings."
msgstr ""
"Параметри доступу до оновлення може бути будь-коли змінено за допомогою "
"налаштувань конфіденційності."

#: portal/flatpak-portal.c:2343
#, c-format
msgid "Application update not allowed"
msgstr "Оновлення програми заборонено"

#: portal/flatpak-portal.c:2501
#, c-format
msgid "Self update not supported, new version requires new permissions"
msgstr ""
"Підтримки самостійного оновлення не передбачено. Нова версія потребує нових "
"прав доступу."

#: portal/flatpak-portal.c:2684 portal/flatpak-portal.c:2702
#, c-format
msgid "Update ended unexpectedly"
msgstr "Результати оновлення є неочікуваними"

#. SECURITY:
#. - Normal users need admin authentication to install software
#. system-wide.
#. - Note that we install polkit rules that allow local users
#. in the wheel group to install without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:23
msgid "Install signed application"
msgstr "Встановлення підписаної програми"

#: system-helper/org.freedesktop.Flatpak.policy.in:24
#: system-helper/org.freedesktop.Flatpak.policy.in:42
msgid "Authentication is required to install software"
msgstr "Для встановлення програмного забезпечення слід пройти розпізнавання"

#. SECURITY:
#. - Normal users need admin authentication to install software
#. system-wide.
#. - Note that we install polkit rules that allow local users
#. in the wheel group to install without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:41
msgid "Install signed runtime"
msgstr "Встановлення підписаного середовища виконання"

#. SECURITY:
#. - Normal users do not require admin authentication to update an
#. app as the commit will be signed, and the action is required
#. to update the system when unattended.
#. - Changing this to anything other than 'yes' will break unattended
#. updates.
#: system-helper/org.freedesktop.Flatpak.policy.in:60
msgid "Update signed application"
msgstr "Оновлення підписаної програми"

#: system-helper/org.freedesktop.Flatpak.policy.in:61
#: system-helper/org.freedesktop.Flatpak.policy.in:80
msgid "Authentication is required to update software"
msgstr "Для оновлення програмного забезпечення слід пройти розпізнавання"

#. SECURITY:
#. - Normal users do not require admin authentication to update a
#. runtime as the commit will be signed, and the action is required
#. to update the system when unattended.
#. - Changing this to anything other than 'yes' will break unattended
#. updates.
#: system-helper/org.freedesktop.Flatpak.policy.in:79
msgid "Update signed runtime"
msgstr "Оновлення підписаного середовища виконання"

#. SECURITY:
#. - Normal users do not need authentication to update metadata
#. from signed repositories.
#: system-helper/org.freedesktop.Flatpak.policy.in:94
msgid "Update remote metadata"
msgstr "Оновити віддалені метадані"

#: system-helper/org.freedesktop.Flatpak.policy.in:95
msgid "Authentication is required to update remote info"
msgstr "Для оновлення даних віддаленого сховища слід пройти розпізнавання"

#. SECURITY:
#. - Normal users do not need authentication to modify the
#. OSTree repository
#. - Note that we install polkit rules that allow local users
#. in the wheel group to modify repos without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:111
msgid "Update system repository"
msgstr "Оновлення загальносистемного сховища"

#: system-helper/org.freedesktop.Flatpak.policy.in:112
msgid "Authentication is required to modify a system repository"
msgstr ""
"Для внесення змін до загальносистемного сховища слід пройти розпізнавання"

#. SECURITY:
#. - Normal users need admin authentication to install software
#. system-wide.
#: system-helper/org.freedesktop.Flatpak.policy.in:126
msgid "Install bundle"
msgstr "Встановити пакунок"

#: system-helper/org.freedesktop.Flatpak.policy.in:127
msgid "Authentication is required to install software from $(path)"
msgstr ""
"Для встановлення програмного забезпечення з $(path) слід пройти розпізнавання"

#. SECURITY:
#. - Normal users need admin authentication to uninstall software
#. system-wide.
#. - Note that we install polkit rules that allow local users
#. in the wheel group to uninstall without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:144
msgid "Uninstall runtime"
msgstr "Вилучення середовища виконання"

#: system-helper/org.freedesktop.Flatpak.policy.in:145
msgid "Authentication is required to uninstall software"
msgstr "Для вилучення програмного забезпечення слід пройти розпізнавання"

#. SECURITY:
#. - Normal users need admin authentication to uninstall software
#. system-wide.
#. - Note that we install polkit rules that allow local users
#. in the wheel group to uninstall without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:161
msgid "Uninstall app"
msgstr "Вилучити програму"

#: system-helper/org.freedesktop.Flatpak.policy.in:162
msgid "Authentication is required to uninstall $(ref)"
msgstr "Для вилучення $(ref) слід пройти розпізнавання"

#. SECURITY:
#. - Normal users need admin authentication to configure system-wide
#. software repositories.
#: system-helper/org.freedesktop.Flatpak.policy.in:177
msgid "Configure Remote"
msgstr "Налаштовування сховищ"

#: system-helper/org.freedesktop.Flatpak.policy.in:178
msgid "Authentication is required to configure software repositories"
msgstr ""
"Для налаштовування сховищ програмного забезпечення слід пройти розпізнавання"

#. SECURITY:
#. - Normal users need admin authentication to configure the system-wide
#. Flatpak installation.
#: system-helper/org.freedesktop.Flatpak.policy.in:192
msgid "Configure"
msgstr "Налаштувати"

#: system-helper/org.freedesktop.Flatpak.policy.in:193
msgid "Authentication is required to configure software installation"
msgstr ""
"Для налаштовування встановлення програмного забезпечення слід пройти "
"розпізнавання"

#. SECURITY:
#. - Normal users do not require admin authentication to update
#. appstream data as it will be signed, and the action is required
#. to update the system when unattended.
#. - Changing this to anything other than 'yes' will break unattended
#. updates.
#: system-helper/org.freedesktop.Flatpak.policy.in:210
msgid "Update appstream"
msgstr "Оновлення appstream"

#: system-helper/org.freedesktop.Flatpak.policy.in:211
msgid "Authentication is required to update information about software"
msgstr ""
"Для оновлення даних щодо програмного забезпечення слід пройти розпізнавання"

#. SECURITY:
#. - Normal users do not require admin authentication to update
#. metadata as it will be signed, and the action is required
#. to update the system when unattended.
#. - Changing this to anything other than 'yes' will break unattended
#. updates.
#: system-helper/org.freedesktop.Flatpak.policy.in:228
msgid "Update metadata"
msgstr "Оновлення метаданих"

#: system-helper/org.freedesktop.Flatpak.policy.in:229
msgid "Authentication is required to update metadata"
msgstr "Для оновлення метаданих слід пройти розпізнавання"

#. SECURITY:
#. - Authorisation to actually install software is controlled by
#. org.freedesktop.Flatpak.app-install.
#. - This action is checked after app-install, as it can only be done
#. once the app’s data (including its content rating) has been
#. downloaded.
#. - This action is checked to see if the installation should be allowed
#. based on whether the app being installed has content which doesn’t
#. comply with the user’s parental controls policy (the content is
#. ‘too extreme’).
#. - It is checked only if an app has too extreme content for the user
#. who is trying to install it (in which case, the app is ‘unsafe’).
#. - Typically, normal users will need admin permission to install apps
#. with extreme content; admins will be able to install it without
#. additional checks.
#. - In order to configure the policy so that admins can install safe and
#. unsafe software anywhere without authorisation, and non-admins can
#. install safe software in their user or system dirs without
#. authorisation, but need authorisation to install unsafe software
#. anywhere:
#. * Unconditionally return `yes` from `app-install`.
#. * Return `auth_admin` from `override-parental-controls` for users
#. not in `@privileged_group@`, and `yes` for users in it.
#. * Set the malcontent `is-{user,system}-installation-allowed`
#. properties of all non-admins’ parental controls policies to true.
#. - In order to configure the policy so that admins can install safe and
#. unsafe software anywhere without authorisation, and non-admins can
#. install safe software in their user dir without authorisation, but
#. need authorisation to install safe software in the system dir or to
#. install unsafe software anywhere:
#. * Unconditionally return `yes` from `app-install`.
#. * Return `auth_admin` from `override-parental-controls` for users
#. not in `@privileged_group@`, and `yes` for users in it.
#. * Set the malcontent `is-user-installation-allowed` property of all
#. non-admins’ parental controls policies to true.
#. * Set the malcontent `is-system-installation-allowed` property of
#. all non-admins’ parental controls policies to false.
#. - In order to configure the policy so that all users (including
#. admins) can install safe software anywhere without authorisation,
#. but need authorisation to install unsafe software anywhere (i.e.
#. applying parental controls to admins too):
#. * Unconditionally return `yes` from `app-install`.
#. * Unconditionally return `auth_admin` from `override-parental-controls`.
#. * Set the malcontent `is-user-installation-allowed` property of all
#. users’ parental controls policies to true.
#. * Set the malcontent `is-system-installation-allowed` property of
#. all users’ parental controls policies to true.
#: system-helper/org.freedesktop.Flatpak.policy.in:287
#, fuzzy
msgid "Override parental controls for installs"
msgstr "Перевизначення параметрів батьківського контролю"

#: system-helper/org.freedesktop.Flatpak.policy.in:288
msgid ""
"Authentication is required to install software which is restricted by your "
"parental controls policy"
msgstr ""
"Для встановлення програмного забезпечення, доступ до якого обмежено вашими "
"правилами батьківського контролю, слід пройти розпізнавання"

#. SECURITY:
#. - This is like org.freedesktop.Flatpak.override-parental-controls, but
#. it’s queried for app updates, whereas the former is queried for app
#. installs.
#. - As with the above action, this one is only queried if
#. org.freedesktop.Flatpak.app-update has allowed the app update, and
#. only if the app being updated has too extreme content for the user
#. who is trying to update it.
#. - The default policy for this is to *allow* updates to ‘too extreme’
#. apps by default, on the basis that having an out-of-date (i.e.
#. insecure or unsupported) app is a worse outcome than automatically
#. installing an update which has radically different content from the
#. version of the app which the parent originally vetted and installed.
#: system-helper/org.freedesktop.Flatpak.policy.in:313
#, fuzzy
msgid "Override parental controls for updates"
msgstr "Перевизначення параметрів батьківського контролю"

#: system-helper/org.freedesktop.Flatpak.policy.in:314
#, fuzzy
msgid ""
"Authentication is required to update software which is restricted by your "
"parental controls policy"
msgstr ""
"Для встановлення програмного забезпечення, доступ до якого обмежено вашими "
"правилами батьківського контролю, слід пройти розпізнавання"

#~ msgid "Installed:"
#~ msgstr "Встановлено:"

#~ msgid "Download:"
#~ msgstr "Отримання:"

#, c-format
#~ msgid "No gpg key found with ID %s (homedir: %s)"
#~ msgstr "Не знайдено ключа gpg із ідентифікатором %s (домашній каталог: %s)"

#, c-format
#~ msgid "Unable to lookup key ID %s: %d"
#~ msgstr "Не вдалося знайти ключ із ідентифікатором %s: %d"

#, c-format
#~ msgid "Error signing commit: %d"
#~ msgstr "Помилка у внеску підписування: %d"

#, c-format
#~ msgid ""
#~ "Found similar ref(s) for ‘%s’ in remote ‘%s’ (%s).\n"
#~ "Use this remote?"
#~ msgstr ""
#~ "Знайдено подібні до «%s» посилання у віддаленому сховищі «%s» (%s).\n"
#~ "Використовувати це віддалене сховище?"

#, c-format
#~ msgid "No entry for %s in remote '%s' summary cache "
#~ msgstr "Немає запису %s у кеші резюме сховища «%s»"

#, c-format
#~ msgid "Failed to uninstall %s for rebase to %s: "
#~ msgstr "Не вдалося вилучити %s для перенесення на %s: "

#, c-format
#~ msgid "Failed to uninstall %s for rebase to %s: %s\n"
#~ msgstr "Не вдалося вилучити %s для перенесення на %s: %s\n"

#, c-format
#~ msgid "Unable to open directory %s"
#~ msgstr "Не вдалося відкрити каталог «%s»"

===== ./po/sv.po =====
# Swedish translation for flatpak.
# Copyright © 2016-2026 flatpak's COPYRIGHT HOLDER
# This file is distributed under the same license as the flatpak package.
# Sebastian Rasmussen <sebras@gmail.com>, 2016.
# Josef Andersson <l10nl18nsweja@gmail.com>, 2017, 2018.
# Luna Jernberg <droidbittin@gmail.com>, 2020.
# Anders Jonsson <anders.jonsson@norsjovallen.se>, 2021, 2022, 2023, 2024, 2025, 2026.
#
msgid ""
msgstr ""
"Project-Id-Version: flatpak main\n"
"Report-Msgid-Bugs-To: https://github.com/flatpak/flatpak/issues\n"
"POT-Creation-Date: 2026-05-27 16:39+0200\n"
"PO-Revision-Date: 2026-02-23 00:36+0100\n"
"Last-Translator: Anders Jonsson <anders.jonsson@norsjovallen.se>\n"
"Language-Team: Swedish <tp-sv@listor.tp-sv.se>\n"
"Language: sv\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Generator: Poedit 3.8\n"

#: app/flatpak-builtins-build-bundle.c:59
msgid "Export runtime instead of app"
msgstr "Exportera exekveringsmiljö istället för program"

#: app/flatpak-builtins-build-bundle.c:60
msgid "Arch to bundle for"
msgstr "Arkitektur att skapa bunt för"

#: app/flatpak-builtins-build-bundle.c:60
#: app/flatpak-builtins-build-export.c:62 app/flatpak-builtins-build-init.c:53
#: app/flatpak-builtins-build-sign.c:42 app/flatpak-builtins-create-usb.c:46
#: app/flatpak-builtins-info.c:55 app/flatpak-builtins-install.c:67
#: app/flatpak-builtins-list.c:50 app/flatpak-builtins-make-current.c:38
#: app/flatpak-builtins-remote-info.c:54 app/flatpak-builtins-remote-ls.c:56
#: app/flatpak-builtins-run.c:158 app/flatpak-builtins-search.c:37
#: app/flatpak-builtins-uninstall.c:54 app/flatpak-builtins-update.c:56
msgid "ARCH"
msgstr "ARK"

#: app/flatpak-builtins-build-bundle.c:61
msgid "URL for repo"
msgstr "URL till förråd"

#: app/flatpak-builtins-build-bundle.c:61
#: app/flatpak-builtins-build-bundle.c:62
#: app/flatpak-builtins-build-update-repo.c:68
#: app/flatpak-builtins-build-update-repo.c:72
#: app/flatpak-builtins-build-update-repo.c:73
#: app/flatpak-builtins-history.c:69 app/flatpak-builtins-remote-add.c:80
#: app/flatpak-builtins-remote-add.c:81 app/flatpak-builtins-remote-add.c:85
#: app/flatpak-builtins-remote-list.c:53
#: app/flatpak-builtins-remote-modify.c:70
#: app/flatpak-builtins-remote-modify.c:85
#: app/flatpak-builtins-remote-modify.c:86
#: app/flatpak-builtins-remote-modify.c:90
msgid "URL"
msgstr "URL"

#: app/flatpak-builtins-build-bundle.c:62
msgid "URL for runtime flatpakrepo file"
msgstr "URL för flatpakrepo-fil i exekveringsmiljö"

#: app/flatpak-builtins-build-bundle.c:63
msgid "Add GPG key from FILE (- for stdin)"
msgstr "Lägg till GPG-nyckel från FIL (- för standard in)"

#: app/flatpak-builtins-build-bundle.c:63 app/flatpak-builtins-build.c:54
#: app/flatpak-builtins-build-export.c:67
#: app/flatpak-builtins-build-update-repo.c:83
#: app/flatpak-builtins-install.c:81 app/flatpak-builtins-remote-add.c:84
#: app/flatpak-builtins-remote-add.c:86 app/flatpak-builtins-remote-modify.c:89
#: app/flatpak-builtins-remote-modify.c:92
msgid "FILE"
msgstr "FIL"

#: app/flatpak-builtins-build-bundle.c:64
msgid "GPG Key ID to sign the OCI image with"
msgstr "GPG-nyckel-ID att signera OCI-avbilden med"

#: app/flatpak-builtins-build-bundle.c:64
#: app/flatpak-builtins-build-commit-from.c:68
#: app/flatpak-builtins-build-export.c:68
#: app/flatpak-builtins-build-import-bundle.c:49
#: app/flatpak-builtins-build-sign.c:44
#: app/flatpak-builtins-build-update-repo.c:84
msgid "KEY-ID"
msgstr "NYCKEL-ID"

#: app/flatpak-builtins-build-bundle.c:65
#: app/flatpak-builtins-build-commit-from.c:69
#: app/flatpak-builtins-build-export.c:71
#: app/flatpak-builtins-build-import-bundle.c:50
#: app/flatpak-builtins-build-sign.c:45
#: app/flatpak-builtins-build-update-repo.c:85
msgid "GPG Homedir to use when looking for keyrings"
msgstr "GPG-hemkatalog att använda vid sökning efter nyckelringar"

#: app/flatpak-builtins-build-bundle.c:65
#: app/flatpak-builtins-build-commit-from.c:69
#: app/flatpak-builtins-build-export.c:71
#: app/flatpak-builtins-build-import-bundle.c:50
#: app/flatpak-builtins-build-sign.c:45
#: app/flatpak-builtins-build-update-repo.c:85
msgid "HOMEDIR"
msgstr "HEMKAT"

#: app/flatpak-builtins-build-bundle.c:66
msgid "OSTree commit to create a delta bundle from"
msgstr "OSTree-incheckning att skapa deltabunt från"

#: app/flatpak-builtins-build-bundle.c:66 app/flatpak-builtins-remote-info.c:55
#: app/flatpak-builtins-update.c:57
msgid "COMMIT"
msgstr "INCHECKNING"

#: app/flatpak-builtins-build-bundle.c:67
msgid "Export oci image instead of flatpak bundle"
msgstr "Exportera oci-avbild istället för flatpak-bunt"

#: app/flatpak-builtins-build-bundle.c:70
msgid "How to compress OCI image layers (default: gzip)"
msgstr "Hur OCI-avbildslager ska komprimeras (standard: gzip)"

#: app/flatpak-builtins-build-bundle.c:634
msgid ""
"LOCATION FILENAME NAME [BRANCH] - Create a single file bundle from a local "
"repository"
msgstr "PLATS FILNAMN NAMN [GREN] - Skapa en enfilsbunt från ett lokalt förråd"

#: app/flatpak-builtins-build-bundle.c:641
msgid "LOCATION, FILENAME and NAME must be specified"
msgstr "PLATS, FILNAMN och NAMN måste anges"

#: app/flatpak-builtins-build-bundle.c:644
#: app/flatpak-builtins-build-export.c:844
#: app/flatpak-builtins-build-import-bundle.c:136
#: app/flatpak-builtins-build-init.c:217 app/flatpak-builtins-build-sign.c:76
#: app/flatpak-builtins-document-export.c:112
#: app/flatpak-builtins-document-info.c:75
#: app/flatpak-builtins-document-list.c:191
#: app/flatpak-builtins-document-unexport.c:70
#: app/flatpak-builtins-history.c:482 app/flatpak-builtins-info.c:130
#: app/flatpak-builtins-install.c:181 app/flatpak-builtins-install.c:234
#: app/flatpak-builtins-install.c:298 app/flatpak-builtins-list.c:419
#: app/flatpak-builtins-make-current.c:72 app/flatpak-builtins-override.c:73
#: app/flatpak-builtins-permission-list.c:162
#: app/flatpak-builtins-permission-remove.c:132
#: app/flatpak-builtins-remote-add.c:323
#: app/flatpak-builtins-remote-delete.c:68
#: app/flatpak-builtins-remote-list.c:241 app/flatpak-builtins-remote-ls.c:407
msgid "Too many arguments"
msgstr "För många argument"

#: app/flatpak-builtins-build-bundle.c:659
#: app/flatpak-builtins-build-commit-from.c:338
#: app/flatpak-builtins-build-commit-from.c:351
#: app/flatpak-builtins-build-import-bundle.c:145
#, c-format
msgid "'%s' is not a valid repository"
msgstr "”%s” är inte ett giltigt förråd"

#: app/flatpak-builtins-build-bundle.c:663
#, c-format
msgid "'%s' is not a valid repository: "
msgstr "”%s” är inte ett giltigt förråd: "

#: app/flatpak-builtins-build-bundle.c:674 app/flatpak-builtins-build-sign.c:88
#: common/flatpak-dir.c:14293
#, c-format
msgid "'%s' is not a valid name: %s"
msgstr "”%s” är inte ett giltigt namn: %s"

#: app/flatpak-builtins-build-bundle.c:677
#: app/flatpak-builtins-build-export.c:865 app/flatpak-builtins-build-sign.c:91
#: common/flatpak-dir.c:14299
#, c-format
msgid "'%s' is not a valid branch name: %s"
msgstr "”%s” är inte ett giltigt grennamn: %s"

#: app/flatpak-builtins-build-bundle.c:691
#: app/flatpak-builtins-build-import-bundle.c:149
#: app/flatpak-builtins-build-init.c:281
#, c-format
msgid "'%s' is not a valid filename"
msgstr "”%s” är inte ett giltigt filnamn"

#: app/flatpak-builtins-build-bundle.c:706
msgid "--oci-layer-compress value must be gzip or zstd"
msgstr "värde på --oci-layer-compress måste vara gzip eller zstd"

#: app/flatpak-builtins-build.c:49
msgid "Use Platform runtime rather than Sdk"
msgstr "Använd plattformsexekveringsmiljö snarare än SDK"

#: app/flatpak-builtins-build.c:50
msgid "Make destination readonly"
msgstr "Skrivskydda målet"

# sebras: how is this translated?
#: app/flatpak-builtins-build.c:51
msgid "Add bind mount"
msgstr "Lägg till bindningsmontering"

#: app/flatpak-builtins-build.c:51
msgid "DEST=SRC"
msgstr "MÅL=KÄLLA"

#: app/flatpak-builtins-build.c:52
msgid "Start build in this directory"
msgstr "Starta bygge i denna katalog"

#: app/flatpak-builtins-build.c:52 app/flatpak-builtins-build.c:53
#: app/flatpak-builtins-build-init.c:64 app/flatpak-builtins-run.c:160
msgid "DIR"
msgstr "KAT"

#: app/flatpak-builtins-build.c:53
msgid "Where to look for custom sdk dir (defaults to 'usr')"
msgstr "Var anpassad sdk-katalog ska eftersökas (standardvärdet är ”usr”)"

#: app/flatpak-builtins-build.c:54 app/flatpak-builtins-build-export.c:67
msgid "Use alternative file for the metadata"
msgstr "Använd alternativ fil för metadata"

#: app/flatpak-builtins-build.c:55 app/flatpak-builtins-run.c:177
msgid "Kill processes when the parent process dies"
msgstr "Döda processen när den överordnade processen dör"

#: app/flatpak-builtins-build.c:56
msgid "Export application homedir directory to build"
msgstr "Exportera programmets hemkatalog till bygge"

#: app/flatpak-builtins-build.c:57 app/flatpak-builtins-run.c:165
msgid "Log session bus calls"
msgstr "Logga sessionsbussanrop"

#: app/flatpak-builtins-build.c:58 app/flatpak-builtins-run.c:166
msgid "Log system bus calls"
msgstr "Logga systembussanrop"

#: app/flatpak-builtins-build.c:262
msgid "DIRECTORY [COMMAND [ARGUMENT…]] - Build in directory"
msgstr "KATALOG [KOMMANDO [ARGUMENT…]] - Bygg i katalog"

#: app/flatpak-builtins-build.c:285 app/flatpak-builtins-build-finish.c:656
msgid "DIRECTORY must be specified"
msgstr "KATALOG måste anges"

#: app/flatpak-builtins-build.c:296 app/flatpak-builtins-build-export.c:887
#, c-format
msgid "Build directory %s not initialized, use flatpak build-init"
msgstr "Byggkatalog %s är inte initierad, använd flatpak build-init"

#: app/flatpak-builtins-build.c:315
msgid "metadata invalid, not application or runtime"
msgstr "metadata ogiltigt, inte program eller exekveringsmiljö"

#: app/flatpak-builtins-build.c:446
#, c-format
msgid "No extension point matching %s in %s"
msgstr "Ingen tilläggspunkt matchar %s i %s"

# sebras: how is this translated?
#: app/flatpak-builtins-build.c:635
#, c-format
msgid "Missing '=' in bind mount option '%s'"
msgstr "Saknar ”=” i bindningsmonteringsargument ”%s”"

#: app/flatpak-builtins-build.c:679 common/flatpak-run.c:3961
#, c-format
msgid "Unable to start app"
msgstr "Kunde inte starta program"

#: app/flatpak-builtins-build-commit-from.c:58
msgid "Source repo dir"
msgstr "Katalog för källförråd"

#: app/flatpak-builtins-build-commit-from.c:58
msgid "SRC-REPO"
msgstr "KÄLL-REPO"

#: app/flatpak-builtins-build-commit-from.c:59
msgid "Source repo ref"
msgstr "Ref i källförråd"

#: app/flatpak-builtins-build-commit-from.c:59
msgid "SRC-REF"
msgstr "KÄLL-REF"

#: app/flatpak-builtins-build-commit-from.c:64
#: app/flatpak-builtins-build-export.c:60
msgid "One line subject"
msgstr "Enradsämne"

#: app/flatpak-builtins-build-commit-from.c:64
#: app/flatpak-builtins-build-export.c:60
msgid "SUBJECT"
msgstr "ÄMNE"

#: app/flatpak-builtins-build-commit-from.c:65
#: app/flatpak-builtins-build-export.c:61
msgid "Full description"
msgstr "Fullständig beskrivning"

#: app/flatpak-builtins-build-commit-from.c:65
#: app/flatpak-builtins-build-export.c:61
msgid "BODY"
msgstr "TEXT"

#: app/flatpak-builtins-build-commit-from.c:66
#: app/flatpak-builtins-build-export.c:64
#: app/flatpak-builtins-build-import-bundle.c:51
msgid "Update the appstream branch"
msgstr "Uppdatera appstream-grenen"

#: app/flatpak-builtins-build-commit-from.c:67
#: app/flatpak-builtins-build-export.c:65
#: app/flatpak-builtins-build-import-bundle.c:52
#: app/flatpak-builtins-build-update-repo.c:87
msgid "Don't update the summary"
msgstr "Uppdatera inte sammanfattningen"

#: app/flatpak-builtins-build-commit-from.c:68
#: app/flatpak-builtins-build-export.c:68
#: app/flatpak-builtins-build-import-bundle.c:49
#: app/flatpak-builtins-build-sign.c:44
msgid "GPG Key ID to sign the commit with"
msgstr "GPG-nyckel-ID att signera incheckning med"

#: app/flatpak-builtins-build-commit-from.c:70
#: app/flatpak-builtins-build-export.c:73
msgid "Mark build as end-of-life"
msgstr "Markera bygge som att det passerat slutet på sin livstid"

#: app/flatpak-builtins-build-commit-from.c:70
#: app/flatpak-builtins-build-export.c:73
msgid "REASON"
msgstr "ANLEDNING"

#: app/flatpak-builtins-build-commit-from.c:71
msgid ""
"Mark refs matching the OLDID prefix as end-of-life, to be replaced with the "
"given NEWID"
msgstr ""
"Markera referenser som matchar prefixet GAMMALT_ID som att de passerat "
"slutet på sin livstid, att ersättas med det angivna NYTT_ID"

#: app/flatpak-builtins-build-commit-from.c:71
msgid "OLDID=NEWID"
msgstr "GAMMALT_ID=NYTT_ID"

#: app/flatpak-builtins-build-commit-from.c:72
#: app/flatpak-builtins-build-export.c:75
msgid "Set type of token needed to install this commit"
msgstr "Ställ in typ av token som krävs för att installera denna incheckning"

#: app/flatpak-builtins-build-commit-from.c:72
#: app/flatpak-builtins-build-export.c:75
msgid "VAL"
msgstr "VÄR"

#: app/flatpak-builtins-build-commit-from.c:73
msgid "Override the timestamp of the commit (NOW for current time)"
msgstr "Åsidosätt tidsstämpel för incheckningen (NOW för aktuell tid)"

#: app/flatpak-builtins-build-commit-from.c:73
#: app/flatpak-builtins-build-export.c:76
msgid "TIMESTAMP"
msgstr "TIDSSTÄMPEL"

#: app/flatpak-builtins-build-commit-from.c:75
#: app/flatpak-builtins-build-export.c:80
#: app/flatpak-builtins-build-import-bundle.c:53
#: app/flatpak-builtins-build-update-repo.c:97
msgid "Don't generate a summary index"
msgstr "Generera inte ett sammanfattningsindex"

#: app/flatpak-builtins-build-commit-from.c:278
msgid "DST-REPO [DST-REF…] - Make a new commit from existing commits"
msgstr ""
"MÅL-FÖRRÅD [MÅL-REF…] - Skapa en ny incheckning baserad på befintliga "
"incheckningar"

#: app/flatpak-builtins-build-commit-from.c:285
msgid "DST-REPO must be specified"
msgstr "MÅL-FÖRRÅD måste anges"

#: app/flatpak-builtins-build-commit-from.c:293
msgid ""
"If --src-repo is not specified, exactly one destination ref must be specified"
msgstr "Om --src-repo inte anges måste exakt en målreferens anges"

#: app/flatpak-builtins-build-commit-from.c:296
msgid ""
"If --src-ref is specified, exactly one destination ref must be specified"
msgstr "Om --src-ref anges måste exakt en målreferens anges"

#: app/flatpak-builtins-build-commit-from.c:299
msgid "Either --src-repo or --src-ref must be specified"
msgstr "Antingen --src-repo eller --src-ref måste anges"

#: app/flatpak-builtins-build-commit-from.c:315
msgid "Invalid argument format of use  --end-of-life-rebase=OLDID=NEWID"
msgstr ""
"Ogiltigt argumentformat för användning --end-of-life-"
"rebase=GAMMALT_ID=NYTT_ID"

#: app/flatpak-builtins-build-commit-from.c:321
#: app/flatpak-builtins-build-commit-from.c:324
#, c-format
msgid "Invalid name %s in --end-of-life-rebase"
msgstr "Ogiltigt namn %s i --end-of-life-rebase"

#: app/flatpak-builtins-build-commit-from.c:333
#: app/flatpak-builtins-build-export.c:1092
#, c-format
msgid "Could not parse '%s'"
msgstr "Det gick inte att tolka ”%s”"

#: app/flatpak-builtins-build-commit-from.c:498
msgid "Can't commit from partial source commit"
msgstr "Det går inte att checka in från en partiell källkodsincheckning"

#: app/flatpak-builtins-build-commit-from.c:503
#, c-format
msgid "%s: no change\n"
msgstr "%s: ingen förändring\n"

#: app/flatpak-builtins-build-export.c:62
msgid "Architecture to export for (must be host compatible)"
msgstr "Arkitektur att exportera till (måste vara värdkompatibel)"

#: app/flatpak-builtins-build-export.c:63
msgid "Commit runtime (/usr), not /app"
msgstr "Checka in exekveringsmiljö (/usr), inte /app"

#: app/flatpak-builtins-build-export.c:66
msgid "Use alternative directory for the files"
msgstr "Använd alternativ katalog för filerna"

#: app/flatpak-builtins-build-export.c:66
msgid "SUBDIR"
msgstr "UNDERKAT"

#: app/flatpak-builtins-build-export.c:69
msgid "Files to exclude"
msgstr "Filer att exkludera"

#: app/flatpak-builtins-build-export.c:69
#: app/flatpak-builtins-build-export.c:70
#: app/flatpak-builtins-build-update-repo.c:90
msgid "PATTERN"
msgstr "MÖNSTER"

#: app/flatpak-builtins-build-export.c:70
msgid "Excluded files to include"
msgstr "Exkluderade filer att inkludera"

#: app/flatpak-builtins-build-export.c:74
msgid "Mark build as end-of-life, to be replaced with the given ID"
msgstr ""
"Markera bygge som att det passerat slutet på sin livstid, att ersättas med "
"angivet ID"

#: app/flatpak-builtins-build-export.c:74
#: app/flatpak-builtins-document-list.c:49 app/flatpak-cli-transaction.c:1427
msgid "ID"
msgstr "ID"

#: app/flatpak-builtins-build-export.c:76
msgid "Override the timestamp of the commit"
msgstr "Åsidosätt tidsstämpel för incheckningen"

#: app/flatpak-builtins-build-export.c:77
#: app/flatpak-builtins-build-update-repo.c:75
#: app/flatpak-builtins-remote-add.c:83 app/flatpak-builtins-remote-list.c:54
#: app/flatpak-builtins-remote-modify.c:88
msgid "Collection ID"
msgstr "Samlings-ID"

#: app/flatpak-builtins-build-export.c:472
#, c-format
msgid "WARNING: Error running desktop-file-validate: %s\n"
msgstr "VARNING: Fel vid körning av desktop-file-validate: %s\n"

#: app/flatpak-builtins-build-export.c:480
#, c-format
msgid "WARNING: Error reading from desktop-file-validate: %s\n"
msgstr "VARNING: Fel vid läsning av desktop-file-validate: %s\n"

#: app/flatpak-builtins-build-export.c:486
#, c-format
msgid "WARNING: Failed to validate desktop file %s: %s\n"
msgstr "VARNING: Misslyckades med att validera desktop-filen %s: %s\n"

#: app/flatpak-builtins-build-export.c:513
#, c-format
msgid "WARNING: Can't find Exec key in %s: %s\n"
msgstr "VARNING: Det går inte att hitta Exec-nyckeln i %s: %s\n"

#: app/flatpak-builtins-build-export.c:521
#: app/flatpak-builtins-build-export.c:614
#, c-format
msgid "WARNING: Binary not found for Exec line in %s: %s\n"
msgstr "VARNING: Binär inte funnen för Exec-rad i %s: %s\n"

#: app/flatpak-builtins-build-export.c:529
#, c-format
msgid "WARNING: Icon not matching app id in %s: %s\n"
msgstr "VARNING: Ikon matchar inte program-id i %s: %s\n"

#: app/flatpak-builtins-build-export.c:552
#, c-format
msgid "WARNING: Icon referenced in desktop file but not exported: %s\n"
msgstr "VARNING: Ikon hänvisad till i desktop-fil men inte exporterad: %s\n"

#: app/flatpak-builtins-build-export.c:719
#, c-format
msgid "Invalid uri type %s, only http/https supported"
msgstr "Ogiltig urityp %s, endast http/https stöds"

#: app/flatpak-builtins-build-export.c:737
#, c-format
msgid "Unable to find basename in %s, specify a name explicitly"
msgstr "Kunde inte hitta basnamn i %s, ange ett namn explicit"

#: app/flatpak-builtins-build-export.c:746
#, c-format
msgid "No slashes allowed in extra data name"
msgstr "Inga snedstreck tillåtna i namn för extra data"

#: app/flatpak-builtins-build-export.c:758
#, c-format
msgid "Invalid format for sha256 checksum: '%s'"
msgstr "Ogiltigt format för sha256-kontrollsumman: ”%s”"

#: app/flatpak-builtins-build-export.c:768
#, c-format
msgid "Extra data sizes of zero not supported"
msgstr "Extra datastorlekar med noll i storlek stöds inte"

#: app/flatpak-builtins-build-export.c:830
msgid ""
"LOCATION DIRECTORY [BRANCH] - Create a repository from a build directory"
msgstr "PLATS KATALOG [GREN] - Skapa ett förråd från en byggkatalog"

#: app/flatpak-builtins-build-export.c:838
msgid "LOCATION and DIRECTORY must be specified"
msgstr "PLATS och KATALOG måste anges"

#: app/flatpak-builtins-build-export.c:859
#: app/flatpak-builtins-remote-add.c:327
#, c-format
msgid "‘%s’ is not a valid collection ID: %s"
msgstr "”%s” är inte ett giltigt samlings-ID: %s"

#: app/flatpak-builtins-build-export.c:904
#: app/flatpak-builtins-build-finish.c:684
msgid "No name specified in the metadata"
msgstr "Inget namn angivet i metadata"

#: app/flatpak-builtins-build-export.c:1166
#, c-format
msgid "Commit: %s\n"
msgstr "Incheckning: %s\n"

#: app/flatpak-builtins-build-export.c:1167
#, c-format
msgid "Metadata Total: %u\n"
msgstr "Total metadata: %u\n"

#: app/flatpak-builtins-build-export.c:1168
#, c-format
msgid "Metadata Written: %u\n"
msgstr "Skrivna metadata: %u\n"

#: app/flatpak-builtins-build-export.c:1169
#, c-format
msgid "Content Total: %u\n"
msgstr "Totalt innehåll: %u\n"

#: app/flatpak-builtins-build-export.c:1170
#, c-format
msgid "Content Written: %u\n"
msgstr "Skrivet innehåll: %u\n"

#: app/flatpak-builtins-build-export.c:1171
#, c-format
msgid "Content Bytes Written:"
msgstr "Skrivna innehållsbyte:"

#: app/flatpak-builtins-build-finish.c:52
msgid "Command to set"
msgstr "Kommando att ställa in"

#: app/flatpak-builtins-build-finish.c:52 app/flatpak-builtins-run.c:159
#: app/flatpak-main.c:209
msgid "COMMAND"
msgstr "KOMMANDO"

#: app/flatpak-builtins-build-finish.c:53
msgid "Flatpak version to require"
msgstr "Flatpak-version att kräva"

#: app/flatpak-builtins-build-finish.c:53
msgid "MAJOR.MINOR.MICRO"
msgstr "MAJOR.MINOR.MICRO"

#: app/flatpak-builtins-build-finish.c:54
msgid "Don't process exports"
msgstr "Behandla inte exporter"

#: app/flatpak-builtins-build-finish.c:55
msgid "Extra data info"
msgstr "Extra datainfo"

#: app/flatpak-builtins-build-finish.c:56 app/flatpak-builtins-build-init.c:63
msgid "Add extension point info"
msgstr "Lägg till info om tilläggspunkt"

#: app/flatpak-builtins-build-finish.c:56 app/flatpak-builtins-build-init.c:63
msgid "NAME=VARIABLE[=VALUE]"
msgstr "NAMN=VARIABEL[=VÄRDE]"

#: app/flatpak-builtins-build-finish.c:57
msgid "Remove extension point info"
msgstr "Ta bort info om tilläggspunkt"

#: app/flatpak-builtins-build-finish.c:57
#: app/flatpak-builtins-build-update-repo.c:79 app/flatpak-builtins-info.c:58
#: app/flatpak-builtins-remote-add.c:88 app/flatpak-builtins-remote-modify.c:94
#: app/flatpak-main.c:182
msgid "NAME"
msgstr "NAMN"

#: app/flatpak-builtins-build-finish.c:58
msgid "Set extension priority (only for extensions)"
msgstr "Ställ in tilläggsprioritet (endast för tillägg)"

#: app/flatpak-builtins-build-finish.c:58
msgid "VALUE"
msgstr "VÄRDE"

#: app/flatpak-builtins-build-finish.c:59
msgid "Change the sdk used for the app"
msgstr "Ändra vilken sdk som används för programmet"

#: app/flatpak-builtins-build-finish.c:59
msgid "SDK"
msgstr "SDK"

#: app/flatpak-builtins-build-finish.c:60
msgid "Change the runtime used for the app"
msgstr "Ändra exekveringsmiljö som används för programmet"

#: app/flatpak-builtins-build-finish.c:60 app/flatpak-builtins-build-init.c:54
#: app/flatpak-builtins-list.c:53 app/flatpak-builtins-remote-ls.c:58
#: app/flatpak-builtins-run.c:163
msgid "RUNTIME"
msgstr "EXEKVERINGSMILJÖ"

#: app/flatpak-builtins-build-finish.c:61
msgid "Set generic metadata option"
msgstr "Ställ in alternativ för generella metadata"

#: app/flatpak-builtins-build-finish.c:61
msgid "GROUP=KEY[=VALUE]"
msgstr "GRUPP=NYCKEL[=VÄRDE]"

#: app/flatpak-builtins-build-finish.c:62
msgid "Don't inherit permissions from runtime"
msgstr "Ärv inte rättigheter från exekveringsmiljö"

# Kontrollerar filnamnet, så denna sträng handlar om filändelser snarare än tillägg till ett program
#: app/flatpak-builtins-build-finish.c:155
#, c-format
msgid "Not exporting %s, wrong extension\n"
msgstr "Exporterar inte %s, fel filändelse\n"

#: app/flatpak-builtins-build-finish.c:163
#, c-format
msgid "Not exporting %s, non-allowed export filename\n"
msgstr "Exporterar inte %s, exportfilnamnet tillåts inte\n"

#: app/flatpak-builtins-build-finish.c:167
#, c-format
msgid "Exporting %s\n"
msgstr "Exporterar %s\n"

#: app/flatpak-builtins-build-finish.c:440
#, c-format
msgid "More than one executable found\n"
msgstr "Fler än en körbar fil funnen\n"

#: app/flatpak-builtins-build-finish.c:451
#, c-format
msgid "Using %s as command\n"
msgstr "Använder %s som ett kommando\n"

#: app/flatpak-builtins-build-finish.c:456
#, c-format
msgid "No executable found\n"
msgstr "Ingen körbar fil funnen\n"

#: app/flatpak-builtins-build-finish.c:511
#, c-format
msgid "Invalid --require-version argument: %s"
msgstr "Ogiltigt argument för --require-version: %s"

#: app/flatpak-builtins-build-finish.c:543
#, c-format
msgid "Too few elements in --extra-data argument %s"
msgstr "För få element i --extra-data-argumentet %s"

# TODO: parentheses not matching?
#: app/flatpak-builtins-build-finish.c:575
#, c-format
msgid ""
"Too few elements in --metadata argument %s, format should be "
"GROUP=KEY[=VALUE]]"
msgstr ""
"För få element i --metadata-argumentet %s, formatet är GRUPP=NYCKEL[=VÄRDE]]"

#: app/flatpak-builtins-build-finish.c:597
#: app/flatpak-builtins-build-init.c:458
#, c-format
msgid ""
"Too few elements in --extension argument %s, format should be "
"NAME=VAR[=VALUE]"
msgstr ""
"För få element i --extension-argumentet %s, formatet är NAMN=VAR[=VÄRDE]"

#: app/flatpak-builtins-build-finish.c:603
#: app/flatpak-builtins-build-init.c:461
#, c-format
msgid "Invalid extension name %s"
msgstr "Ogiltigt tilläggsnamn %s"

#: app/flatpak-builtins-build-finish.c:646
msgid "DIRECTORY - Finalize a build directory"
msgstr "KATALOG - Slutför en byggkatalog"

#: app/flatpak-builtins-build-finish.c:668
#, c-format
msgid "Build directory %s not initialized"
msgstr "Byggkatalog %s är inte initierad"

#: app/flatpak-builtins-build-finish.c:689
#, c-format
msgid "Build directory %s already finalized"
msgstr "Byggkatalog %s redan slutförd"

#: app/flatpak-builtins-build-finish.c:702
#, c-format
msgid "Please review the exported files and the metadata\n"
msgstr "Granska de exporterade filerna och metadata\n"

#: app/flatpak-builtins-build-import-bundle.c:47
msgid "Override the ref used for the imported bundle"
msgstr "Åsidosätt referensen som använts för den importerade bunten"

#: app/flatpak-builtins-build-import-bundle.c:47
msgid "REF"
msgstr "REF"

#: app/flatpak-builtins-build-import-bundle.c:48
msgid "Import oci image instead of flatpak bundle"
msgstr "Importera oci-avbild istället för flatpak-bunt"

#: app/flatpak-builtins-build-import-bundle.c:77
#: app/flatpak-builtins-build-import-bundle.c:105
#, c-format
msgid "Importing %s (%s)\n"
msgstr "Importerar %s (%s)\n"

#: app/flatpak-builtins-build-import-bundle.c:126
msgid "LOCATION FILENAME - Import a file bundle into a local repository"
msgstr "PLATS FILNAMN - Importera en filbunt in i ett lokalt förråd"

#: app/flatpak-builtins-build-import-bundle.c:133
msgid "LOCATION and FILENAME must be specified"
msgstr "PLATS och FILNAMN måste anges"

#: app/flatpak-builtins-build-init.c:53 app/flatpak-builtins-info.c:55
#: app/flatpak-builtins-run.c:158
msgid "Arch to use"
msgstr "Ark att använda"

#: app/flatpak-builtins-build-init.c:54
msgid "Initialize var from named runtime"
msgstr "Initiera var. från angiven exekveringsmiljö"

#: app/flatpak-builtins-build-init.c:55
msgid "Initialize apps from named app"
msgstr "Initiera program från namngivet program"

#: app/flatpak-builtins-build-init.c:55
msgid "APP"
msgstr "PROG"

#: app/flatpak-builtins-build-init.c:56
msgid "Specify version for --base"
msgstr "Ange version för --base"

#: app/flatpak-builtins-build-init.c:56 app/flatpak-builtins-run.c:164
msgid "VERSION"
msgstr "VERSION"

#: app/flatpak-builtins-build-init.c:57
msgid "Include this base extension"
msgstr "Inkludera detta bastillägg"

#: app/flatpak-builtins-build-init.c:57 app/flatpak-builtins-build-init.c:62
msgid "EXTENSION"
msgstr "TILLÄGG"

#: app/flatpak-builtins-build-init.c:58
msgid "Extension tag to use if building extension"
msgstr "Tilläggstagg att använda om tillägg byggs"

#: app/flatpak-builtins-build-init.c:58
msgid "EXTENSION_TAG"
msgstr "TILLÄGGSTAGG"

#: app/flatpak-builtins-build-init.c:59
msgid "Initialize /usr with a writable copy of the sdk"
msgstr "Initiera /usr med en skrivbar kopia av SDK:n"

#: app/flatpak-builtins-build-init.c:60
msgid "Specify the build type (app, runtime, extension)"
msgstr "Ange byggtypen (app, runtime, extension)"

#: app/flatpak-builtins-build-init.c:60
msgid "TYPE"
msgstr "TYP"

#: app/flatpak-builtins-build-init.c:61
msgid "Add a tag"
msgstr "Lägg till en tagg"

#: app/flatpak-builtins-build-init.c:61
msgid "TAG"
msgstr "TAGG"

#: app/flatpak-builtins-build-init.c:62
msgid "Include this sdk extension in /usr"
msgstr "Inkludera detta SDK-tillägg i /usr"

#: app/flatpak-builtins-build-init.c:64
msgid "Where to store sdk (defaults to 'usr')"
msgstr "Var SDK:n ska sparas (standardvärdet är ”usr”)"

#: app/flatpak-builtins-build-init.c:65
msgid "Re-initialize the sdk/var"
msgstr "Återinitiera SDK/var"

#: app/flatpak-builtins-build-init.c:118
#, c-format
msgid "Requested extension %s/%s/%s is only partially installed"
msgstr "Begärt tillägg %s/%s/%s är bara delvis installerat"

#: app/flatpak-builtins-build-init.c:147
#, c-format
msgid "Requested extension %s/%s/%s not installed"
msgstr "Begärt tillägg %s/%s/%s är inte installerat"

#: app/flatpak-builtins-build-init.c:207
msgid ""
"DIRECTORY APPNAME SDK RUNTIME [BRANCH] - Initialize a directory for building"
msgstr ""
"KATALOG PROGNAMN SDK EXEKVERINGSMILJÖ [GREN] - Initiera katalog för bygge"

#: app/flatpak-builtins-build-init.c:214
msgid "RUNTIME must be specified"
msgstr "EXEKVERINGSMILJÖ måste anges"

#: app/flatpak-builtins-build-init.c:235
#, c-format
msgid "'%s' is not a valid build type name, use app, runtime or extension"
msgstr ""
"”%s” är inte ett giltigt byggtypsnamn, använd app, runtime eller extension"

#: app/flatpak-builtins-build-init.c:241 app/flatpak-builtins-override.c:79
#, c-format
msgid "'%s' is not a valid application name: %s"
msgstr "”%s” är inte ett giltigt programnamn: %s"

#: app/flatpak-builtins-build-init.c:295
#, c-format
msgid "Build directory %s already initialized"
msgstr "Byggkatalog %s är redan initierad"

#: app/flatpak-builtins-build-sign.c:42 app/flatpak-builtins-install.c:67
#: app/flatpak-builtins-remote-info.c:54
msgid "Arch to install for"
msgstr "Ark att installera för"

#: app/flatpak-builtins-build-sign.c:43 app/flatpak-builtins-create-usb.c:48
#: app/flatpak-builtins-install.c:74 app/flatpak-builtins-remote-info.c:56
#: app/flatpak-builtins-uninstall.c:58 app/flatpak-builtins-update.c:64
msgid "Look for runtime with the specified name"
msgstr "Leta efter exekveringsmiljö med angivet namn"

#: app/flatpak-builtins-build-sign.c:66
msgid "LOCATION [ID [BRANCH]] - Sign an application or runtime"
msgstr "PLATS [ID [GREN]] - Signera ett program eller en exekveringsmiljö"

#: app/flatpak-builtins-build-sign.c:73
#: app/flatpak-builtins-build-update-repo.c:499
#: app/flatpak-builtins-remote-add.c:320 app/flatpak-builtins-repo.c:739
msgid "LOCATION must be specified"
msgstr "PLATS måste anges"

#: app/flatpak-builtins-build-sign.c:94
msgid "No gpg key ids specified"
msgstr "Inga GPG-nyckel-ID angivna"

#: app/flatpak-builtins-build-update-repo.c:68
msgid "Redirect this repo to a new URL"
msgstr "Omdirigera detta förråd till en ny URL"

#: app/flatpak-builtins-build-update-repo.c:69
msgid "A nice name to use for this repository"
msgstr "Ett enkelt namn att använda för detta förråd"

#: app/flatpak-builtins-build-update-repo.c:69
#: app/flatpak-builtins-remote-add.c:77 app/flatpak-builtins-remote-modify.c:82
msgid "TITLE"
msgstr "TITEL"

#: app/flatpak-builtins-build-update-repo.c:70
msgid "A one-line comment for this repository"
msgstr "Enradskommentar för detta förråd"

#: app/flatpak-builtins-build-update-repo.c:70
#: app/flatpak-builtins-remote-add.c:78 app/flatpak-builtins-remote-modify.c:83
msgid "COMMENT"
msgstr "KOMMENTAR"

#: app/flatpak-builtins-build-update-repo.c:71
msgid "A full-paragraph description for this repository"
msgstr "Ett helt beskrivningsstycke för detta förråd"

#: app/flatpak-builtins-build-update-repo.c:71
#: app/flatpak-builtins-remote-add.c:79 app/flatpak-builtins-remote-modify.c:84
msgid "DESCRIPTION"
msgstr "BESKRIVNING"

#: app/flatpak-builtins-build-update-repo.c:72
msgid "URL for a website for this repository"
msgstr "URL för en webbplats för detta förråd"

#: app/flatpak-builtins-build-update-repo.c:73
msgid "URL for an icon for this repository"
msgstr "URL för en ikon för detta förråd"

#: app/flatpak-builtins-build-update-repo.c:74
msgid "Default branch to use for this repository"
msgstr "Standardgren att använda för detta förråd"

#: app/flatpak-builtins-build-update-repo.c:74
#: app/flatpak-builtins-remote-add.c:82 app/flatpak-builtins-remote-modify.c:87
#: app/flatpak-builtins-repo.c:713 app/flatpak-builtins-repo.c:714
#: app/flatpak-builtins-run.c:161
msgid "BRANCH"
msgstr "GREN"

#: app/flatpak-builtins-build-update-repo.c:75
#: app/flatpak-builtins-remote-add.c:83 app/flatpak-builtins-remote-modify.c:88
msgid "COLLECTION-ID"
msgstr "SAMLINGS-ID"

#. Translators: A sideload is when you install from a local USB drive rather than the Internet.
#: app/flatpak-builtins-build-update-repo.c:77
msgid ""
"Permanently deploy collection ID to client remote configurations, only for "
"sideload support"
msgstr ""
"Distribuera permanent samlings-ID till fjärrklienters konfigurationer, "
"endast för sidoinläsningsstöd"

#: app/flatpak-builtins-build-update-repo.c:78
msgid "Permanently deploy collection ID to client remote configurations"
msgstr "Distribuera permanent samlings-ID till fjärrklienters konfigurationer"

#: app/flatpak-builtins-build-update-repo.c:79
msgid "Name of authenticator for this repository"
msgstr "Namn på autentiserare för detta förråd"

#: app/flatpak-builtins-build-update-repo.c:80
msgid "Autoinstall authenticator for this repository"
msgstr "Installera automatiskt autentiserare för detta förråd"

#: app/flatpak-builtins-build-update-repo.c:81
msgid "Don't autoinstall authenticator for this repository"
msgstr "Installera inte automatiskt autentiserare för detta förråd"

#: app/flatpak-builtins-build-update-repo.c:82
#: app/flatpak-builtins-remote-add.c:89
msgid "Authenticator option"
msgstr "Autentiseraralternativ"

#: app/flatpak-builtins-build-update-repo.c:82
#: app/flatpak-builtins-remote-add.c:89 app/flatpak-builtins-remote-modify.c:95
msgid "KEY=VALUE"
msgstr "NYCKEL=VÄRDE"

#: app/flatpak-builtins-build-update-repo.c:83
msgid "Import new default GPG public key from FILE"
msgstr "Importera ny öppen GPG-standardnyckel från FIL"

#: app/flatpak-builtins-build-update-repo.c:84
msgid "GPG Key ID to sign the summary with"
msgstr "GPG-nyckel-ID att signera sammanfattningen med"

#: app/flatpak-builtins-build-update-repo.c:86
msgid "Generate delta files"
msgstr "Generera deltafiler"

#: app/flatpak-builtins-build-update-repo.c:88
msgid "Don't update the appstream branch"
msgstr "Uppdatera inte appstream-grenen"

#: app/flatpak-builtins-build-update-repo.c:89
msgid "Max parallel jobs when creating deltas (default: NUMCPUs)"
msgstr "Max antal parallella jobb när deltan skapas (standard: ANTALCPU)"

#: app/flatpak-builtins-build-update-repo.c:89
msgid "NUM-JOBS"
msgstr "ANT-JOBB"

#: app/flatpak-builtins-build-update-repo.c:90
msgid "Don't create deltas matching refs"
msgstr "Skapa inte deltan som matchar referenser"

#: app/flatpak-builtins-build-update-repo.c:91
msgid "Prune unused objects"
msgstr "Rensa oanvända objekt"

#: app/flatpak-builtins-build-update-repo.c:92
msgid "Prune but don't actually remove anything"
msgstr "Rensa men ta inte bort något på riktigt"

#: app/flatpak-builtins-build-update-repo.c:93
msgid "Only traverse DEPTH parents for each commit (default: -1=infinite)"
msgstr ""
"Gå endast DJUP steg upp i hierarkin för varje incheckning (standard: "
"-1=oändligt)"

#: app/flatpak-builtins-build-update-repo.c:93
msgid "DEPTH"
msgstr "DJUP"

#: app/flatpak-builtins-build-update-repo.c:223
#, c-format
msgid "Generating delta: %s (%.10s)\n"
msgstr "Genererar delta: %s (%.10s)\n"

# sebras: from-empty? why is there a dash?
#: app/flatpak-builtins-build-update-repo.c:225
#, c-format
msgid "Generating delta: %s (%.10s-%.10s)\n"
msgstr "Genererar delta: %s (%.10s-%.10s)\n"

#: app/flatpak-builtins-build-update-repo.c:233
#, c-format
msgid "Failed to generate delta %s (%.10s): "
msgstr "Misslyckades med att generera delta %s (%.10s): "

#: app/flatpak-builtins-build-update-repo.c:236
#, c-format
msgid "Failed to generate delta %s (%.10s-%.10s): "
msgstr "Misslyckades med att generera delta %s (%.10s-%.10s): "

#: app/flatpak-builtins-build-update-repo.c:492
msgid "LOCATION - Update repository metadata"
msgstr "PLATS - Uppdatera förrådsmetadata"

#: app/flatpak-builtins-build-update-repo.c:609
#, c-format
msgid "Updating appstream branch\n"
msgstr "Uppdaterar appstream-gren\n"

#: app/flatpak-builtins-build-update-repo.c:638
#, c-format
msgid "Updating summary\n"
msgstr "Uppdaterar sammanfattning\n"

#: app/flatpak-builtins-build-update-repo.c:664
#, c-format
msgid "Total objects: %u\n"
msgstr "Totalt antal objekt: %u\n"

#: app/flatpak-builtins-build-update-repo.c:666
#, c-format
msgid "No unreachable objects\n"
msgstr "Inga onåbara objekt\n"

#: app/flatpak-builtins-build-update-repo.c:668
#, c-format
msgid "Deleted %u objects, %s freed\n"
msgstr "Tog bort %u objekt, %s frigjort\n"

#: app/flatpak-builtins-config.c:41
msgid "List configuration keys and values"
msgstr "Lista konfigurationsnycklar och värden"

#: app/flatpak-builtins-config.c:42
msgid "Get configuration for KEY"
msgstr "Hämta konfiguration för NYCKEL"

#: app/flatpak-builtins-config.c:43
msgid "Set configuration for KEY to VALUE"
msgstr "Ställ in konfiguration för NYCKEL till VÄRDE"

#: app/flatpak-builtins-config.c:44
msgid "Unset configuration for KEY"
msgstr "Ta bort konfiguration för NYCKEL"

#: app/flatpak-builtins-config.c:149
#, c-format
msgid "'%s' does not look like a language/locale code"
msgstr "”%s” ser inte ut som en språk/lokalkod"

#: app/flatpak-builtins-config.c:172
#, c-format
msgid "'%s' does not look like a language code"
msgstr "”%s” ser inte ut som en språkkod"

#: app/flatpak-builtins-config.c:190
#, c-format
msgid "'%s' is not a valid value (use 'true' or 'false')"
msgstr "”%s” är inte ett giltigt värde (använd ”true” eller ”false”)"

#: app/flatpak-builtins-config.c:262
#, c-format
msgid "Unknown configure key '%s'"
msgstr "Okänd konfigurationsnyckel ”%s”"

#: app/flatpak-builtins-config.c:284
msgid "Too many arguments for --list"
msgstr "För många argument för --list"

#: app/flatpak-builtins-config.c:314 app/flatpak-builtins-config.c:362
msgid "You must specify KEY"
msgstr "Du måste ange NYCKEL"

#: app/flatpak-builtins-config.c:316
msgid "Too many arguments for --get"
msgstr "För många argument för --get"

#: app/flatpak-builtins-config.c:338
msgid "You must specify KEY and VALUE"
msgstr "Du måste ange NYCKEL och VÄRDE"

#: app/flatpak-builtins-config.c:340
msgid "Too many arguments for --set"
msgstr "För många argument för --set"

#: app/flatpak-builtins-config.c:364
msgid "Too many arguments for --unset"
msgstr "För många argument för --unset"

#: app/flatpak-builtins-config.c:383
msgid "[KEY [VALUE]] - Manage configuration"
msgstr "[NYCKEL [VÄRDE]] - Hantera konfiguration"

#: app/flatpak-builtins-config.c:394
msgid "Can only use one of --list, --get, --set or --unset"
msgstr "Kan endast använda en av --list, --get, --set eller --unset"

#: app/flatpak-builtins-config.c:408
msgid "Must specify one of --list, --get, --set or --unset"
msgstr "Måste ange en av --list, --get, --set eller --unset"

#: app/flatpak-builtins-create-usb.c:45 app/flatpak-builtins-install.c:75
#: app/flatpak-builtins-remote-info.c:57 app/flatpak-builtins-uninstall.c:59
#: app/flatpak-builtins-update.c:65
msgid "Look for app with the specified name"
msgstr "Sök efter program med det angivna namnet"

#: app/flatpak-builtins-create-usb.c:46
msgid "Arch to copy"
msgstr "Ark att kopiera"

#: app/flatpak-builtins-create-usb.c:47
msgid "DEST"
msgstr "MÅL"

#: app/flatpak-builtins-create-usb.c:49
msgid "Allow partial commits in the created repo"
msgstr "Tillåt partiella incheckningar i det skapade förrådet"

#: app/flatpak-builtins-create-usb.c:125 app/flatpak-builtins-create-usb.c:165
#, c-format
msgid ""
"Warning: Related ref ‘%s’ is partially installed. Use --allow-partial to "
"suppress this message.\n"
msgstr ""
"Varning: Relaterad ref ”%s” är partiellt installerad. Använd --allow-partial "
"för att undertrycka detta meddelande.\n"

#: app/flatpak-builtins-create-usb.c:158
#, c-format
msgid "Warning: Omitting related ref ‘%s’ because it is not installed.\n"
msgstr ""
"Varning: Utelämnar relaterad ref ”%s” för att den inte är installerad.\n"

#: app/flatpak-builtins-create-usb.c:175
#, c-format
msgid ""
"Warning: Omitting related ref ‘%s’ because its remote ‘%s’ does not have a "
"collection ID set.\n"
msgstr ""
"Varning: Utelämnar relaterad ref ”%s” för att dess fjärrförråd ”%s” inte har "
"ett samlings-ID inställt.\n"

#: app/flatpak-builtins-create-usb.c:187
#, c-format
msgid "Warning: Omitting related ref ‘%s’ because it's extra-data.\n"
msgstr "Varning: Utelämnar relaterad ref ”%s” för att den är extra-data.\n"

#: app/flatpak-builtins-create-usb.c:262 app/flatpak-builtins-create-usb.c:637
#, c-format
msgid ""
"Remote ‘%s’ does not have a collection ID set, which is required for P2P "
"distribution of ‘%s’."
msgstr ""
"Fjärrförrådet ”%s” har inte ett samlings-ID inställt, vilket krävs för P2P-"
"distribution av ”%s”."

#: app/flatpak-builtins-create-usb.c:272
#, c-format
msgid "Warning: Omitting ref ‘%s’ (runtime of ‘%s’) because it's extra-data.\n"
msgstr ""
"Varning: Utelämnar ref ”%s” (exekveringsmiljön för ”%s”) för att den är "
"extra-data.\n"

#: app/flatpak-builtins-create-usb.c:484
msgid "MOUNT-PATH [REF…] - Copy apps or runtimes onto removable media"
msgstr ""
"MONTERINGSSÖKVÄG [REF…] - Kopiera program eller exekveringsmiljöer till "
"flyttbara media"

#: app/flatpak-builtins-create-usb.c:493
msgid "MOUNT-PATH and REF must be specified"
msgstr "MONTERINGSSÖKVÄG och REF måste anges"

#: app/flatpak-builtins-create-usb.c:607
#, c-format
msgid "Ref ‘%s’ found in multiple installations: %s. You must specify one."
msgstr "Hittade ref ”%s” i flera installationer: %s. Du måste ange en."

#: app/flatpak-builtins-create-usb.c:620
#, c-format
msgid "Refs must all be in the same installation (found in %s and %s)."
msgstr ""
"Referenser måste alla vara i samma installation (hittades i %s och %s)."

#: app/flatpak-builtins-create-usb.c:670
#, c-format
msgid ""
"Warning: Ref ‘%s’ is partially installed. Use --allow-partial to suppress "
"this message.\n"
msgstr ""
"Varning: Ref ”%s” är partiellt installerad. Använd --allow-partial för att "
"undertrycka detta meddelande.\n"

#: app/flatpak-builtins-create-usb.c:681
#, c-format
msgid "Installed ref ‘%s’ is extra-data, and cannot be distributed offline"
msgstr ""
"Installerad ref ”%s” är extra-data, och kan inte distribueras i frånkopplat "
"läge"

#: app/flatpak-builtins-create-usb.c:721
#, c-format
msgid "Warning: Couldn't update repo metadata for remote ‘%s’: %s\n"
msgstr ""
"Varning: Det gick inte att uppdatera förrådsmetadata för fjärrförråd ”%s”: "
"%s\n"

#: app/flatpak-builtins-create-usb.c:751
#, c-format
msgid "Warning: Couldn't update appstream data for remote ‘%s’ arch ‘%s’: %s\n"
msgstr ""
"Varning: Det gick inte att uppdatera appstream-data för fjärrförråd ”%s” ark "
"”%s”: %s\n"

#. Print a warning if both appstream and appstream2 are missing
#: app/flatpak-builtins-create-usb.c:784
#, c-format
msgid ""
"Warning: Couldn't find appstream data for remote ‘%s’ arch ‘%s’: %s; %s\n"
msgstr ""
"Varning: Det gick inte att hitta appstream-data för fjärrförråd ”%s” ark "
"”%s”: %s; %s\n"

#. Appstream2 is only for efficiency, so just print a debug message
#: app/flatpak-builtins-create-usb.c:790
#, c-format
msgid "Couldn't find appstream2 data for remote ‘%s’ arch ‘%s’: %s\n"
msgstr ""
"Det gick inte att hitta appstream2-data för fjärrförråd ”%s” ark ”%s”: %s\n"

#: app/flatpak-builtins-document-export.c:62
msgid "Create a unique document reference"
msgstr "Skapa en unik dokumentreferens"

#: app/flatpak-builtins-document-export.c:63
msgid "Make the document transient for the current session"
msgstr "Gör dokumentet tillfälligt för den aktuella sessionen"

#: app/flatpak-builtins-document-export.c:64
msgid "Don't require the file to exist already"
msgstr "Kräv inte att filen redan existerar"

#: app/flatpak-builtins-document-export.c:65
msgid "Give the app read permissions"
msgstr "Ge programmet läsrättigheter"

#: app/flatpak-builtins-document-export.c:66
msgid "Give the app write permissions"
msgstr "Ge programmet skrivrättigheter"

#: app/flatpak-builtins-document-export.c:67
msgid "Give the app delete permissions"
msgstr "Ge programmet rättigheter att ta bort"

#: app/flatpak-builtins-document-export.c:68
msgid "Give the app permissions to grant further permissions"
msgstr "Ge programmet rättigheter att ge ytterligare rättigheter"

#: app/flatpak-builtins-document-export.c:69
msgid "Revoke read permissions of the app"
msgstr "Återkalla läsrättigheter för programmet"

#: app/flatpak-builtins-document-export.c:70
msgid "Revoke write permissions of the app"
msgstr "Återkalla skrivrättigheter för programmet"

#: app/flatpak-builtins-document-export.c:71
msgid "Revoke delete permissions of the app"
msgstr "Återkalla borttagningsrättigheter för programmet"

#: app/flatpak-builtins-document-export.c:72
msgid "Revoke the permission to grant further permissions"
msgstr "Återkalla rättigheter för programmet att ge ytterligare rättigheter"

#: app/flatpak-builtins-document-export.c:73
msgid "Add permissions for this app"
msgstr "Lägg till rättigheter för detta program"

#: app/flatpak-builtins-document-export.c:73
msgid "APPID"
msgstr "PROG-ID"

#: app/flatpak-builtins-document-export.c:100
msgid "FILE - Export a file to apps"
msgstr "FIL - Exportera en fil till program"

#: app/flatpak-builtins-document-export.c:109
#: app/flatpak-builtins-document-info.c:72
#: app/flatpak-builtins-document-unexport.c:67
msgid "FILE must be specified"
msgstr "FIL måste anges"

#: app/flatpak-builtins-document-info.c:63
msgid "FILE - Get information about an exported file"
msgstr "FIL - Hämta information om en exporterad fil"

#: app/flatpak-builtins-document-info.c:100
#: app/flatpak-builtins-document-unexport.c:94
#, c-format
msgid "Not exported\n"
msgstr "Inte exporterad\n"

#: app/flatpak-builtins-document-list.c:43 app/flatpak-builtins-history.c:53
#: app/flatpak-builtins-list.c:54 app/flatpak-builtins-ps.c:43
#: app/flatpak-builtins-remote-list.c:45 app/flatpak-builtins-remote-ls.c:59
#: app/flatpak-builtins-search.c:38
msgid "What information to show"
msgstr "Vilken information som ska visas"

#: app/flatpak-builtins-document-list.c:43 app/flatpak-builtins-history.c:53
#: app/flatpak-builtins-list.c:54 app/flatpak-builtins-ps.c:43
#: app/flatpak-builtins-remote-list.c:45 app/flatpak-builtins-remote-ls.c:59
#: app/flatpak-builtins-search.c:38
msgid "FIELD,…"
msgstr "FÄLT,…"

#: app/flatpak-builtins-document-list.c:44 app/flatpak-builtins-history.c:54
#: app/flatpak-builtins-list.c:52 app/flatpak-builtins-permission-list.c:43
#: app/flatpak-builtins-permission-show.c:43 app/flatpak-builtins-ps.c:44
#: app/flatpak-builtins-remote-list.c:46 app/flatpak-builtins-remote-ls.c:63
#: app/flatpak-builtins-repo.c:717 app/flatpak-builtins-search.c:39
msgid "Show output in JSON format"
msgstr "Visa utdata i JSON-format"

#: app/flatpak-builtins-document-list.c:49
msgid "Show the document ID"
msgstr "Visa dokument-ID"

#: app/flatpak-builtins-document-list.c:50
msgid "Path"
msgstr "Sökväg"

#: app/flatpak-builtins-document-list.c:50
#: app/flatpak-builtins-document-list.c:51
msgid "Show the document path"
msgstr "Visa dokumentets sökväg"

#: app/flatpak-builtins-document-list.c:51 app/flatpak-builtins-list.c:66
#: app/flatpak-builtins-remote-ls.c:74
msgid "Origin"
msgstr "Ursprung"

#: app/flatpak-builtins-document-list.c:52 app/flatpak-builtins-history.c:62
#: app/flatpak-builtins-ps.c:52
msgid "Application"
msgstr "Program"

#: app/flatpak-builtins-document-list.c:52
msgid "Show applications with permission"
msgstr "Visa program med rättigheter"

#: app/flatpak-builtins-document-list.c:53
#: app/flatpak-builtins-permission-list.c:182
#: app/flatpak-builtins-permission-show.c:145
msgid "Permissions"
msgstr "Rättigheter"

#: app/flatpak-builtins-document-list.c:53
msgid "Show permissions for applications"
msgstr "Visa rättigheter för program"

#: app/flatpak-builtins-document-list.c:161
#, c-format
msgid "No documents found\n"
msgstr "Inga dokument hittades\n"

#: app/flatpak-builtins-document-list.c:180
msgid "[APPID] - List exported files"
msgstr "[PROGID] - Lista exporterade filer"

#: app/flatpak-builtins-document-unexport.c:43
msgid "Specify the document ID"
msgstr "Ange dokument-ID:t"

#: app/flatpak-builtins-document-unexport.c:58
msgid "FILE - Unexport a file to apps"
msgstr "FIL - Sluta exportera en fil till program"

# sebras: is the sandbox translation correct?
#: app/flatpak-builtins-enter.c:88
msgid "INSTANCE COMMAND [ARGUMENT…] - Run a command inside a running sandbox"
msgstr ""
"INSTANS KOMMANDO [ARGUMENT…] - Kör ett kommando inuti en körande sandlåda"

#: app/flatpak-builtins-enter.c:111
msgid "INSTANCE and COMMAND must be specified"
msgstr "INSTANS och KOMMANDO måste anges"

#: app/flatpak-builtins-enter.c:138
#, c-format
msgid "%s is neither a pid nor an application or instance ID"
msgstr "%s är varken ett pid eller ett program- eller instans-ID"

# enter går in i ett programs eller en exekveringmiljös sandlåda
#: app/flatpak-builtins-enter.c:144
msgid "entering not supported (need unprivileged user namespaces, or sudo -E)"
msgstr ""
"inträde stöds inte (behöver oprivilegierade användarnamnrymder, eller sudo "
"-E)"

#: app/flatpak-builtins-enter.c:145
#, c-format
msgid "No such pid %s"
msgstr "Inget sådant pid %s"

#: app/flatpak-builtins-enter.c:158
msgid "Can't read cwd"
msgstr "Det går inte att läsa cwd"

#: app/flatpak-builtins-enter.c:163
msgid "Can't read root"
msgstr "Det går inte att läsa root"

#: app/flatpak-builtins-enter.c:191
#, c-format
msgid "Invalid %s namespace for pid %d"
msgstr "Ogiltig %s-namnrymd för pid %d"

# sebras: self? really?!
#: app/flatpak-builtins-enter.c:202
#, c-format
msgid "Invalid %s namespace for self"
msgstr "Ogiltig %s-namnrymd för själv"

#: app/flatpak-builtins-enter.c:216
#, c-format
msgid "Can't open %s namespace: %s"
msgstr "Det går inte att öppna %s-namnrymd: %s"

#: app/flatpak-builtins-enter.c:226
msgid "entering not supported (need unprivileged user namespaces)"
msgstr "inträde stöds inte (behöver oprivilegierade användarnamnrymder)"

#: app/flatpak-builtins-enter.c:227
#, c-format
msgid "Can't enter %s namespace: %s"
msgstr "Det går inte att gå in i %s-namnrymd: %s"

#: app/flatpak-builtins-enter.c:234
msgid "Can't chdir"
msgstr "Det går inte att köra chdir"

#: app/flatpak-builtins-enter.c:237
msgid "Can't chroot"
msgstr "Det går inte att köra chroot"

#: app/flatpak-builtins-enter.c:240
msgid "Can't switch gid"
msgstr "Det går inte att byta gid"

#: app/flatpak-builtins-enter.c:243
msgid "Can't switch uid"
msgstr "Det går inte att byta uid"

#: app/flatpak-builtins-history.c:50
msgid "Only show changes after TIME"
msgstr "Visa endast ändringar efter TID"

#: app/flatpak-builtins-history.c:50 app/flatpak-builtins-history.c:51
msgid "TIME"
msgstr "TID"

#: app/flatpak-builtins-history.c:51
msgid "Only show changes before TIME"
msgstr "Visa endast ändringar före TID"

#: app/flatpak-builtins-history.c:52
msgid "Show newest entries first"
msgstr "Visa nyaste poster först"

#: app/flatpak-builtins-history.c:59
msgid "Time"
msgstr "Tid"

#: app/flatpak-builtins-history.c:59
msgid "Show when the change happened"
msgstr "Visa när ändringen inträffade"

#: app/flatpak-builtins-history.c:60
msgid "Change"
msgstr "Ändring"

#: app/flatpak-builtins-history.c:60
msgid "Show the kind of change"
msgstr "Visa typen av ändring"

#: app/flatpak-builtins-history.c:61 app/flatpak-builtins-list.c:68
#: app/flatpak-builtins-remote-ls.c:75 app/flatpak-builtins-repo.c:335
msgid "Ref"
msgstr "Ref"

#: app/flatpak-builtins-history.c:61 app/flatpak-builtins-list.c:68
#: app/flatpak-builtins-remote-ls.c:75
msgid "Show the ref"
msgstr "Visa ref"

#: app/flatpak-builtins-history.c:62
msgid "Show the application/runtime ID"
msgstr "Visa ID för programmet/exekveringsmiljön"

#: app/flatpak-builtins-history.c:63 app/flatpak-builtins-list.c:64
#: app/flatpak-builtins-ps.c:53 app/flatpak-builtins-remote-ls.c:73
#: app/flatpak-cli-transaction.c:1435
msgid "Arch"
msgstr "Ark"

#: app/flatpak-builtins-history.c:63 app/flatpak-builtins-list.c:64
#: app/flatpak-builtins-ps.c:53 app/flatpak-builtins-remote-ls.c:73
msgid "Show the architecture"
msgstr "Visa arkitekturen"

#: app/flatpak-builtins-history.c:64 app/flatpak-builtins-list.c:63
#: app/flatpak-builtins-ps.c:54 app/flatpak-builtins-remote-ls.c:72
#: app/flatpak-builtins-search.c:48 app/flatpak-cli-transaction.c:1438
msgid "Branch"
msgstr "Gren"

#: app/flatpak-builtins-history.c:64 app/flatpak-builtins-list.c:63
#: app/flatpak-builtins-remote-ls.c:72
msgid "Show the branch"
msgstr "Visa grenen"

#: app/flatpak-builtins-history.c:65 app/flatpak-builtins-list.c:67
msgid "Installation"
msgstr "Installation"

#: app/flatpak-builtins-history.c:65
msgid "Show the affected installation"
msgstr "Visa den påverkade installationen"

#: app/flatpak-builtins-history.c:66 app/flatpak-cli-transaction.c:1452
msgid "Remote"
msgstr "Fjärrförråd"

#: app/flatpak-builtins-history.c:66
msgid "Show the remote"
msgstr "Visa fjärrförrådet"

#: app/flatpak-builtins-history.c:67 app/flatpak-builtins-ps.c:55
#: app/flatpak-builtins-remote-ls.c:76
msgid "Commit"
msgstr "Incheckning"

#: app/flatpak-builtins-history.c:67
msgid "Show the current commit"
msgstr "Visa aktuell incheckning"

#: app/flatpak-builtins-history.c:68
msgid "Old Commit"
msgstr "Gammal incheckning"

#: app/flatpak-builtins-history.c:68
msgid "Show the previous commit"
msgstr "Visa föregående incheckning"

#: app/flatpak-builtins-history.c:69
msgid "Show the remote URL"
msgstr "Visa fjärrförråds-URL"

#: app/flatpak-builtins-history.c:70 app/flatpak-cli-transaction.c:700
msgid "User"
msgstr "Användare"

#: app/flatpak-builtins-history.c:70
msgid "Show the user doing the change"
msgstr "Visa användaren som gör ändringen"

#: app/flatpak-builtins-history.c:71
msgid "Tool"
msgstr "Verktyg"

#: app/flatpak-builtins-history.c:71
msgid "Show the tool that was used"
msgstr "Visa verktyget som användes"

#: app/flatpak-builtins-history.c:72 app/flatpak-builtins-list.c:62
#: app/flatpak-builtins-remote-ls.c:71 app/flatpak-builtins-search.c:47
msgid "Version"
msgstr "Version"

#: app/flatpak-builtins-history.c:72
msgid "Show the Flatpak version"
msgstr "Visa Flatpak-versionen"

#: app/flatpak-builtins-history.c:91
#, c-format
msgid "Failed to get journal data (%s): %s"
msgstr "Misslyckades med att hämta journaldata (%s): %s"

#: app/flatpak-builtins-history.c:146
#, c-format
msgid "Failed to open journal: %s"
msgstr "Misslyckades med att öppna journal: %s"

#: app/flatpak-builtins-history.c:153
#, c-format
msgid "Failed to add match to journal: %s"
msgstr "Misslyckades med att lägga till matchning till journal: %s"

#: app/flatpak-builtins-history.c:471
msgid " - Show history"
msgstr " - Visa historik"

#: app/flatpak-builtins-history.c:490
#, c-format
msgid "Failed to parse the --since option"
msgstr "Misslyckades med att tolka flaggan --since"

#: app/flatpak-builtins-history.c:501
#, c-format
msgid "Failed to parse the --until option"
msgstr "Misslyckades med att tolka flaggan --until"

#: app/flatpak-builtins-info.c:56
msgid "Show user installations"
msgstr "Visa användarinstallationer"

#: app/flatpak-builtins-info.c:57
msgid "Show system-wide installations"
msgstr "Visa systeminstallationer"

#: app/flatpak-builtins-info.c:58
msgid "Show specific system-wide installations"
msgstr "Visa specifika systemomfattande installationer"

#: app/flatpak-builtins-info.c:59 app/flatpak-builtins-remote-info.c:59
msgid "Show ref"
msgstr "Visa ref"

#: app/flatpak-builtins-info.c:60 app/flatpak-builtins-remote-info.c:60
msgid "Show commit"
msgstr "Visa incheckning"

# origin = the remote the ref is installed from
#: app/flatpak-builtins-info.c:61
msgid "Show origin"
msgstr "Visa ursprung"

#: app/flatpak-builtins-info.c:62
msgid "Show size"
msgstr "Visa storlek"

#: app/flatpak-builtins-info.c:63 app/flatpak-builtins-remote-info.c:62
msgid "Show metadata"
msgstr "Visa metadata"

#: app/flatpak-builtins-info.c:64 app/flatpak-builtins-remote-info.c:63
msgid "Show runtime"
msgstr "Visa exekveringsmiljö"

#: app/flatpak-builtins-info.c:65 app/flatpak-builtins-remote-info.c:64
msgid "Show sdk"
msgstr "Visa sdk"

#: app/flatpak-builtins-info.c:66
msgid "Show permissions"
msgstr "Visa rättigheter"

#: app/flatpak-builtins-info.c:67
msgid "Query file access"
msgstr "Efterfråga filåtkomst"

#: app/flatpak-builtins-info.c:67 app/flatpak-builtins-install.c:82
#: app/flatpak-builtins-install.c:88 app/flatpak-builtins-preinstall.c:68
#: app/flatpak-builtins-run.c:182 app/flatpak-builtins-run.c:184
#: app/flatpak-builtins-update.c:67 app/flatpak-builtins-update.c:71
msgid "PATH"
msgstr "SÖKVÄG"

#: app/flatpak-builtins-info.c:68
msgid "Show extensions"
msgstr "Visa tillägg"

#: app/flatpak-builtins-info.c:69
msgid "Show location"
msgstr "Visa plats"

#: app/flatpak-builtins-info.c:116
msgid "NAME [BRANCH] - Get info about an installed app or runtime"
msgstr ""
"NAMN [GREN] - Hämta information om installerat program eller exekveringsmiljö"

#: app/flatpak-builtins-info.c:123 app/flatpak-builtins-remote-add.c:317
#: app/flatpak-builtins-remote-delete.c:63
msgid "NAME must be specified"
msgstr "NAMN måste anges"

#: app/flatpak-builtins-info.c:196
msgid "ref not present in origin"
msgstr "ref finns inte i ursprung"

#: app/flatpak-builtins-info.c:211 app/flatpak-builtins-remote-info.c:217
#, c-format
msgid "Warning: Commit has no flatpak metadata\n"
msgstr "Varning: Incheckning har inga flatpak-metadata\n"

#: app/flatpak-builtins-info.c:217 app/flatpak-builtins-info.c:259
#: app/flatpak-builtins-info.c:455 app/flatpak-builtins-info.c:513
#: app/flatpak-builtins-remote-info.c:236
#: app/flatpak-builtins-remote-info.c:271
msgid "ID:"
msgstr "ID:"

#: app/flatpak-builtins-info.c:218 app/flatpak-builtins-info.c:260
#: app/flatpak-builtins-remote-info.c:237
#: app/flatpak-builtins-remote-info.c:272
msgid "Ref:"
msgstr "Ref:"

#: app/flatpak-builtins-info.c:219 app/flatpak-builtins-info.c:261
#: app/flatpak-builtins-remote-info.c:238
#: app/flatpak-builtins-remote-info.c:273
msgid "Arch:"
msgstr "Ark:"

#: app/flatpak-builtins-info.c:220 app/flatpak-builtins-info.c:262
#: app/flatpak-builtins-remote-info.c:239
#: app/flatpak-builtins-remote-info.c:274
msgid "Branch:"
msgstr "Gren:"

#: app/flatpak-builtins-info.c:222 app/flatpak-builtins-info.c:264
#: app/flatpak-builtins-remote-info.c:241
#: app/flatpak-builtins-remote-info.c:276
msgid "Version:"
msgstr "Version:"

#: app/flatpak-builtins-info.c:224 app/flatpak-builtins-info.c:266
#: app/flatpak-builtins-remote-info.c:243
#: app/flatpak-builtins-remote-info.c:278
msgid "License:"
msgstr "Licens:"

#: app/flatpak-builtins-info.c:226 app/flatpak-builtins-info.c:269
#: app/flatpak-builtins-remote-info.c:245
#: app/flatpak-builtins-remote-info.c:280
msgid "Collection:"
msgstr "Samling:"

#: app/flatpak-builtins-info.c:227 app/flatpak-builtins-info.c:270
#: app/flatpak-builtins-info.c:458 app/flatpak-builtins-info.c:516
msgid "Installation:"
msgstr "Installation:"

#: app/flatpak-builtins-info.c:228 app/flatpak-builtins-info.c:271
#: app/flatpak-builtins-info.c:459 app/flatpak-builtins-info.c:517
#: app/flatpak-builtins-remote-info.c:249
#: app/flatpak-builtins-remote-info.c:284
msgid "Installed Size:"
msgstr "Installerad storlek:"

#: app/flatpak-builtins-info.c:231 app/flatpak-builtins-info.c:279
#: app/flatpak-builtins-remote-info.c:252
#: app/flatpak-builtins-remote-info.c:288
msgid "Runtime:"
msgstr "Exekvering:"

#: app/flatpak-builtins-info.c:232 app/flatpak-builtins-info.c:288
#: app/flatpak-builtins-remote-info.c:253
#: app/flatpak-builtins-remote-info.c:293
msgid "Sdk:"
msgstr "Sdk:"

#: app/flatpak-builtins-info.c:235 app/flatpak-builtins-info.c:313
#: app/flatpak-builtins-remote-info.c:256
#: app/flatpak-builtins-remote-info.c:319
msgid "Date:"
msgstr "Datum:"

#: app/flatpak-builtins-info.c:237 app/flatpak-builtins-info.c:311
#: app/flatpak-builtins-remote-info.c:258
#: app/flatpak-builtins-remote-info.c:317
msgid "Subject:"
msgstr "Ämne:"

#: app/flatpak-builtins-info.c:240 app/flatpak-builtins-info.c:295
msgid "Active commit:"
msgstr "Aktiv incheckning:"

#: app/flatpak-builtins-info.c:241 app/flatpak-builtins-info.c:298
msgid "Latest commit:"
msgstr "Senaste incheckning:"

#: app/flatpak-builtins-info.c:244 app/flatpak-builtins-info.c:303
#: app/flatpak-builtins-info.c:457 app/flatpak-builtins-info.c:515
#: app/flatpak-builtins-remote-info.c:259
#: app/flatpak-builtins-remote-info.c:298
msgid "Commit:"
msgstr "Incheckning:"

#: app/flatpak-builtins-info.c:246 app/flatpak-builtins-info.c:308
#: app/flatpak-builtins-remote-info.c:261
#: app/flatpak-builtins-remote-info.c:303
msgid "Parent:"
msgstr "Överordnad:"

#: app/flatpak-builtins-info.c:248 app/flatpak-builtins-info.c:321
msgid "Alt-id:"
msgstr "Alt-id:"

#: app/flatpak-builtins-info.c:250 app/flatpak-builtins-info.c:325
#: app/flatpak-builtins-remote-info.c:263
#: app/flatpak-builtins-remote-info.c:308
msgid "End-of-life:"
msgstr "End-of-life:"

#: app/flatpak-builtins-info.c:252 app/flatpak-builtins-info.c:330
#: app/flatpak-builtins-remote-info.c:265
#: app/flatpak-builtins-remote-info.c:313
msgid "End-of-life-rebase:"
msgstr "End-of-life-rebase:"

#: app/flatpak-builtins-info.c:254 app/flatpak-builtins-info.c:317
msgid "Subdirectories:"
msgstr "Underkataloger:"

#: app/flatpak-builtins-info.c:255 app/flatpak-builtins-info.c:454
#: app/flatpak-builtins-info.c:512
msgid "Extension:"
msgstr "Tillägg:"

#: app/flatpak-builtins-info.c:267 app/flatpak-builtins-info.c:456
#: app/flatpak-builtins-info.c:514
msgid "Origin:"
msgstr "Ursprung:"

#: app/flatpak-builtins-info.c:460 app/flatpak-builtins-info.c:522
msgid "Subpaths:"
msgstr "Undersökvägar:"

#: app/flatpak-builtins-info.c:478
msgid "unmaintained"
msgstr "underhålls inte"

#: app/flatpak-builtins-info.c:480 app/flatpak-builtins-info.c:482
msgid "unknown"
msgstr "okänd"

#: app/flatpak-builtins-install.c:68 app/flatpak-builtins-preinstall.c:57
msgid "Don't pull, only install from local cache"
msgstr "Hämta inte, installera endast från lokal cache"

#: app/flatpak-builtins-install.c:69 app/flatpak-builtins-preinstall.c:58
#: app/flatpak-builtins-update.c:60
msgid "Don't deploy, only download to local cache"
msgstr "Distribuera inte, hämta bara ner till lokal cache"

#: app/flatpak-builtins-install.c:70 app/flatpak-builtins-preinstall.c:59
msgid "Don't install related refs"
msgstr "Installera inte relaterade referenser"

#: app/flatpak-builtins-install.c:71 app/flatpak-builtins-preinstall.c:60
#: app/flatpak-builtins-update.c:62
msgid "Don't verify/install runtime dependencies"
msgstr "Verifiera/installera ej exekveringsberoenden"

#: app/flatpak-builtins-install.c:72
msgid "Don't automatically pin explicit installs"
msgstr "Nåla inte automatiskt explicita installationer"

#: app/flatpak-builtins-install.c:73 app/flatpak-builtins-preinstall.c:61
#: app/flatpak-builtins-update.c:63
msgid "Don't use static deltas"
msgstr "Använd inte statiska deltan"

#: app/flatpak-builtins-install.c:76 app/flatpak-builtins-preinstall.c:62
msgid "Additionally install the SDK used to build the given refs"
msgstr ""
"Installera dessutom den SDK som används för att bygga de angivna referenserna"

#: app/flatpak-builtins-install.c:77 app/flatpak-builtins-preinstall.c:63
msgid ""
"Additionally install the debug info for the given refs and their dependencies"
msgstr ""
"Installera dessutom felsökningsinfo för de angivna referenserna och deras "
"beroenden"

#: app/flatpak-builtins-install.c:78
msgid "Assume LOCATION is a .flatpak single-file bundle"
msgstr "Anta att PLATS är en enfils .flatpak-bunt"

#: app/flatpak-builtins-install.c:79
msgid "Assume LOCATION is a .flatpakref application description"
msgstr "Anta att PLATS är en programbeskrivning av typen .flatpakref"

#: app/flatpak-builtins-install.c:80
msgid "Assume LOCATION is containers-transports(5) reference to an OCI image"
msgstr ""
"Anta att PLATS är en containers-transports(5)-referens till en OCI-avbild"

#: app/flatpak-builtins-install.c:81
msgid "Check bundle signatures with GPG key from FILE (- for stdin)"
msgstr "Kontrollera buntsignaturer med GPG-nyckel från FIL (- för standard in)"

#: app/flatpak-builtins-install.c:82
msgid "Only install this subpath"
msgstr "Installera endast denna underkatalog"

#: app/flatpak-builtins-install.c:83 app/flatpak-builtins-preinstall.c:64
#: app/flatpak-builtins-uninstall.c:63 app/flatpak-builtins-update.c:68
msgid "Automatically answer yes for all questions"
msgstr "Svara automatiskt ja på alla frågor"

#: app/flatpak-builtins-install.c:84 app/flatpak-builtins-preinstall.c:65
msgid "Uninstall first if already installed"
msgstr "Avinstallera först om redan installerad"

#: app/flatpak-builtins-install.c:85 app/flatpak-builtins-preinstall.c:66
#: app/flatpak-builtins-uninstall.c:64 app/flatpak-builtins-update.c:69
msgid "Produce minimal output and don't ask questions"
msgstr "Producera minimal utmatning och ställ inga frågor"

#: app/flatpak-builtins-install.c:86
msgid "Update install if already installed"
msgstr "Uppdatera installation om den redan är installerad"

#. Translators: A sideload is when you install from a local USB drive rather than the Internet.
#: app/flatpak-builtins-install.c:88 app/flatpak-builtins-preinstall.c:68
#: app/flatpak-builtins-update.c:71
msgid "Use this local repo for sideloads"
msgstr "Använd detta lokala förråd för sidoinläsning"

#: app/flatpak-builtins-install.c:178
msgid "Bundle filename must be specified"
msgstr "Buntfilnamn måste anges"

#: app/flatpak-builtins-install.c:188
msgid "Remote bundles are not supported"
msgstr "Fjärrbuntar stöds inte"

#: app/flatpak-builtins-install.c:231
msgid "Filename or uri must be specified"
msgstr "Filnamn eller uri måste anges"

#: app/flatpak-builtins-install.c:295
msgid "Image location must be specified"
msgstr "Avbildsplats måste anges"

#: app/flatpak-builtins-install.c:345
msgid "[LOCATION/REMOTE] [REF…] - Install applications or runtimes"
msgstr ""
"[PLATS/FJÄRRFÖRRÅD] [REF…] - Installera program eller exekveringsmiljöer"

#: app/flatpak-builtins-install.c:378
msgid "At least one REF must be specified"
msgstr "Minst en REF måste anges"

#: app/flatpak-builtins-install.c:392
#, c-format
msgid "Looking for matches…\n"
msgstr "Söker efter matchningar…\n"

#: app/flatpak-builtins-install.c:513
#, c-format
msgid "No remote refs found for ‘%s’"
msgstr "Inga fjärreferenser hittades för ”%s”"

#: app/flatpak-builtins-install.c:573 app/flatpak-builtins-uninstall.c:405
#: common/flatpak-ref-utils.c:689 common/flatpak-ref-utils.c:1595
#, c-format
msgid "Invalid branch %s: %s"
msgstr "Ogiltig gren %s: %s"

#: app/flatpak-builtins-install.c:606
#, c-format
msgid "Nothing matches %s in local repository for remote %s"
msgstr "Ingenting matchar %s i lokalt förråd för fjärrförrådet %s"

#: app/flatpak-builtins-install.c:608
#, c-format
msgid "Nothing matches %s in remote %s"
msgstr "Ingenting matchar %s i fjärrförrådet %s"

#: app/flatpak-builtins-install.c:629
#, c-format
msgid "Skipping: %s\n"
msgstr "Hoppar över: %s\n"

#: app/flatpak-builtins-kill.c:110
#, c-format
msgid "%s is not running"
msgstr "%s körs inte"

#: app/flatpak-builtins-kill.c:136
msgid "INSTANCE - Stop a running application"
msgstr "INSTANS - Stoppa ett körande program"

#: app/flatpak-builtins-kill.c:144 app/flatpak-builtins-ps.c:256
msgid "Extra arguments given"
msgstr "Extra argument angivna"

#: app/flatpak-builtins-kill.c:150
msgid "Must specify the app to kill"
msgstr "Måste ange programmet att döda"

#: app/flatpak-builtins-list.c:47
msgid "Show extra information"
msgstr "Visa extra information"

#: app/flatpak-builtins-list.c:48
msgid "List installed runtimes"
msgstr "Lista installerade exekveringsmiljöer"

#: app/flatpak-builtins-list.c:49
msgid "List installed applications"
msgstr "Lista installerade program"

#: app/flatpak-builtins-list.c:50
msgid "Arch to show"
msgstr "Arkitektur att visa"

#: app/flatpak-builtins-list.c:51 app/flatpak-builtins-remote-ls.c:57
msgid "List all refs (including locale/debug)"
msgstr "Lista alla referenser (inklusive locale/debug)"

#: app/flatpak-builtins-list.c:53 app/flatpak-builtins-remote-ls.c:58
msgid "List all applications using RUNTIME"
msgstr "Lista alla program som använder EXEKVERINGSMILJÖ"

#: app/flatpak-builtins-list.c:59 app/flatpak-builtins-remote-list.c:51
#: app/flatpak-builtins-remote-ls.c:68 app/flatpak-builtins-search.c:44
msgid "Name"
msgstr "Namn"

#: app/flatpak-builtins-list.c:59 app/flatpak-builtins-remote-list.c:51
#: app/flatpak-builtins-remote-ls.c:68 app/flatpak-builtins-search.c:44
msgid "Show the name"
msgstr "Visa namn"

#: app/flatpak-builtins-list.c:60 app/flatpak-builtins-remote-list.c:60
#: app/flatpak-builtins-remote-ls.c:69 app/flatpak-builtins-search.c:45
msgid "Description"
msgstr "Beskrivning"

#: app/flatpak-builtins-list.c:60 app/flatpak-builtins-remote-ls.c:69
#: app/flatpak-builtins-search.c:45
msgid "Show the description"
msgstr "Visa beskrivning"

#: app/flatpak-builtins-list.c:61 app/flatpak-builtins-remote-ls.c:70
#: app/flatpak-builtins-search.c:46
msgid "Application ID"
msgstr "Program-ID"

#: app/flatpak-builtins-list.c:61 app/flatpak-builtins-ps.c:52
#: app/flatpak-builtins-remote-ls.c:70 app/flatpak-builtins-search.c:46
msgid "Show the application ID"
msgstr "Visa program-ID"

#: app/flatpak-builtins-list.c:62 app/flatpak-builtins-remote-ls.c:71
#: app/flatpak-builtins-search.c:47
msgid "Show the version"
msgstr "Visa version"

#: app/flatpak-builtins-list.c:65 app/flatpak-builtins-ps.c:56
#: app/flatpak-builtins-remote-ls.c:77
msgid "Runtime"
msgstr "Exekveringsmiljö"

#: app/flatpak-builtins-list.c:65
msgid "Show the used runtime"
msgstr "Visa exekveringsmiljön som används"

#: app/flatpak-builtins-list.c:66 app/flatpak-builtins-remote-ls.c:74
msgid "Show the origin remote"
msgstr "Visa ursprungsfjärrförrådet"

#: app/flatpak-builtins-list.c:67
msgid "Show the installation"
msgstr "Visa installationen"

#: app/flatpak-builtins-list.c:69
msgid "Active commit"
msgstr "Aktiv incheckning"

#: app/flatpak-builtins-list.c:69 app/flatpak-builtins-remote-ls.c:76
msgid "Show the active commit"
msgstr "Visa aktiv incheckning"

#: app/flatpak-builtins-list.c:70
msgid "Latest commit"
msgstr "Senaste incheckning"

#: app/flatpak-builtins-list.c:70
msgid "Show the latest commit"
msgstr "Visa senaste incheckning"

#: app/flatpak-builtins-list.c:71 app/flatpak-builtins-remote-ls.c:78
msgid "Installed size"
msgstr "Installerad storlek"

#: app/flatpak-builtins-list.c:71 app/flatpak-builtins-remote-ls.c:78
msgid "Show the installed size"
msgstr "Visa installerad storlek"

#: app/flatpak-builtins-list.c:72 app/flatpak-builtins-remote-list.c:58
#: app/flatpak-builtins-remote-ls.c:80 app/flatpak-builtins-repo.c:340
msgid "Options"
msgstr "Flaggor"

#: app/flatpak-builtins-list.c:72 app/flatpak-builtins-remote-list.c:58
#: app/flatpak-builtins-remote-ls.c:80
msgid "Show options"
msgstr "Visa flaggor"

#: app/flatpak-builtins-list.c:180
#, c-format
msgid "Unable to load details of %s: %s"
msgstr "Kunde inte läsa in detaljer för %s: %s"

#: app/flatpak-builtins-list.c:190
#, c-format
msgid "Unable to inspect current version of %s: %s"
msgstr "Kunde inte inspektera aktuell version för %s: %s"

#: app/flatpak-builtins-list.c:408
msgid " - List installed apps and/or runtimes"
msgstr " - Lista installerade program och/eller exekveringsmiljöer"

#: app/flatpak-builtins-make-current.c:38
msgid "Arch to make current for"
msgstr "Ark att göra aktuell för"

#: app/flatpak-builtins-make-current.c:58
msgid "APP BRANCH - Make branch of application current"
msgstr "PROG GREN - Gör gren av program aktuell"

#: app/flatpak-builtins-make-current.c:69 app/flatpak-builtins-run.c:260
msgid "APP must be specified"
msgstr "PROG måste anges"

#: app/flatpak-builtins-make-current.c:84
msgid "BRANCH must be specified"
msgstr "GREN måste anges"

#: app/flatpak-builtins-make-current.c:97
#, c-format
msgid "App %s branch %s is not installed"
msgstr "Program %s gren %s är inte installerad"

#: app/flatpak-builtins-mask.c:42
msgid "Remove matching masks"
msgstr "Ta bort matchande masker"

#: app/flatpak-builtins-mask.c:54
msgid ""
"[PATTERN…] - disable updates and automatic installation matching patterns"
msgstr ""
"[MÖNSTER…] - inaktivera uppdateringar och automatisk installation som "
"matchar mönster"

#: app/flatpak-builtins-mask.c:73
#, c-format
msgid "No masked patterns\n"
msgstr "Inga maskerade mönster\n"

#: app/flatpak-builtins-mask.c:78
#, c-format
msgid "Masked patterns:\n"
msgstr "Maskerade mönster:\n"

#: app/flatpak-builtins-override.c:42
msgid "Remove existing overrides"
msgstr "Ta bort befintliga åsidosättningar"

#: app/flatpak-builtins-override.c:43
msgid "Show existing overrides"
msgstr "Visa befintliga åsidosättningar"

#: app/flatpak-builtins-override.c:59
msgid "[APP] - Override settings [for application]"
msgstr "[PROGRAM] - Åsidosätt inställningar [för program]"

#: app/flatpak-builtins-permission-list.c:143
msgid "[TABLE] [ID] - List permissions"
msgstr "[TABELL] [ID] - Lista rättigheter"

#: app/flatpak-builtins-permission-list.c:179
#: app/flatpak-builtins-permission-show.c:142
msgid "Table"
msgstr "Tabell"

#: app/flatpak-builtins-permission-list.c:180
#: app/flatpak-builtins-permission-show.c:143
msgid "Object"
msgstr "Objekt"

#: app/flatpak-builtins-permission-list.c:181
#: app/flatpak-builtins-permission-show.c:144
msgid "App"
msgstr "Program"

#: app/flatpak-builtins-permission-list.c:183
#: app/flatpak-builtins-permission-show.c:146
msgid "Data"
msgstr "Data"

#: app/flatpak-builtins-permission-remove.c:120
msgid "TABLE ID [APP_ID] - Remove item from permission store"
msgstr "TABELL ID [PROG-ID] - Ta bort objekt från rättighetslagring"

#: app/flatpak-builtins-permission-remove.c:129
#: app/flatpak-builtins-permission-set.c:120
msgid "Too few arguments"
msgstr "För få argument"

#: app/flatpak-builtins-permission-reset.c:43
msgid "Reset all permissions"
msgstr "Återställ alla rättigheter"

#: app/flatpak-builtins-permission-reset.c:144
msgid "APP_ID - Reset permissions for an app"
msgstr "PROG-ID - Återställ rättigheter för ett program"

#: app/flatpak-builtins-permission-reset.c:153
#: app/flatpak-builtins-permission-show.c:124
msgid "Wrong number of arguments"
msgstr "Fel antal argument"

#: app/flatpak-builtins-permission-set.c:42
msgid "Associate DATA with the entry"
msgstr "Associera DATA med posten"

#: app/flatpak-builtins-permission-set.c:42
msgid "DATA"
msgstr "DATA"

#: app/flatpak-builtins-permission-set.c:111
msgid "TABLE ID APP_ID [PERMISSION...] - Set permissions"
msgstr "TABELL ID PROG-ID [RÄTTIGHET…] - Ställ in rättigheter"

#: app/flatpak-builtins-permission-set.c:132
#, c-format
msgid "Failed to parse '%s' as GVariant: "
msgstr "Misslyckades med att tolka ”%s” som GVariant: "

#: app/flatpak-builtins-permission-show.c:115
msgid "APP_ID - Show permissions for an app"
msgstr "PROG-ID - Visa rättigheter för ett program"

#: app/flatpak-builtins-pin.c:44
msgid "Remove matching pins"
msgstr "Ta bort matchande nålar"

#: app/flatpak-builtins-pin.c:56
msgid "[PATTERN…] - disable automatic removal of runtimes matching patterns"
msgstr ""
"[MÖNSTER…] - inaktivera automatisk borttagning av exekveringsmiljöer som "
"matchar mönster"

#: app/flatpak-builtins-pin.c:75
#, c-format
msgid "No pinned patterns\n"
msgstr "Inga nålade mönster\n"

#: app/flatpak-builtins-pin.c:80
#, c-format
msgid "Pinned patterns:\n"
msgstr "Nålade mönster:\n"

#: app/flatpak-builtins-preinstall.c:80
msgid "- Install flatpaks that are part of the operating system"
msgstr "- Installera flatpak-filer som är en del av operativsystemet"

#: app/flatpak-builtins-preinstall.c:118
#, c-format
msgid "Nothing to do.\n"
msgstr "Inget att göra.\n"

#: app/flatpak-builtins-ps.c:49
msgid "Instance"
msgstr "Instans"

#: app/flatpak-builtins-ps.c:49
msgid "Show the instance ID"
msgstr "Visa instans-ID:t"

#: app/flatpak-builtins-ps.c:50 app/flatpak-builtins-run.c:178
msgid "PID"
msgstr "PID"

#: app/flatpak-builtins-ps.c:50
msgid "Show the PID of the wrapper process"
msgstr "Visa PID för omslagsprocessen"

#: app/flatpak-builtins-ps.c:51
msgid "Child-PID"
msgstr "Underordnad-PID"

#: app/flatpak-builtins-ps.c:51
msgid "Show the PID of the sandbox process"
msgstr "Visa PID för sandlådeprocessen"

#: app/flatpak-builtins-ps.c:54 app/flatpak-builtins-search.c:48
msgid "Show the application branch"
msgstr "Visa programmets gren"

#: app/flatpak-builtins-ps.c:55
msgid "Show the application commit"
msgstr "Visa programmets incheckning"

#: app/flatpak-builtins-ps.c:56
msgid "Show the runtime ID"
msgstr "Visa exekveringsmiljöns ID"

#: app/flatpak-builtins-ps.c:57
msgid "R.-Branch"
msgstr "E.-gren"

#: app/flatpak-builtins-ps.c:57
msgid "Show the runtime branch"
msgstr "Visa exekveringsmiljöns gren"

#: app/flatpak-builtins-ps.c:58
msgid "R.-Commit"
msgstr "E.-incheckning"

#: app/flatpak-builtins-ps.c:58
msgid "Show the runtime commit"
msgstr "Visa exekveringsmiljöns incheckning"

#: app/flatpak-builtins-ps.c:59
msgid "Active"
msgstr "Aktivt"

#: app/flatpak-builtins-ps.c:59
msgid "Show whether the app is active"
msgstr "Visa huruvida programmet är aktivt"

#: app/flatpak-builtins-ps.c:60
msgid "Background"
msgstr "Bakgrund"

#: app/flatpak-builtins-ps.c:60
msgid "Show whether the app is background"
msgstr "Visa huruvida programmet är i bakgrunden"

#: app/flatpak-builtins-ps.c:246
msgid " - Enumerate running sandboxes"
msgstr " - Räkna upp sandlådor som körs"

#: app/flatpak-builtins-remote-add.c:66
msgid "Do nothing if the provided remote exists"
msgstr "Gör ingenting om angivet fjärrförråd existerar"

#: app/flatpak-builtins-remote-add.c:67
msgid "LOCATION specifies a configuration file, not the repo location"
msgstr "PLATS specificerar en konfigurationsfil, inte förrådsplatsen"

#: app/flatpak-builtins-remote-add.c:72 app/flatpak-builtins-remote-modify.c:78
msgid "Disable GPG verification"
msgstr "Inaktivera GPG-verifiering"

#: app/flatpak-builtins-remote-add.c:73 app/flatpak-builtins-remote-modify.c:79
msgid "Mark the remote as don't enumerate"
msgstr "Markera fjärrförrådet som icke uppräkningsbart"

#: app/flatpak-builtins-remote-add.c:74 app/flatpak-builtins-remote-modify.c:80
msgid "Mark the remote as don't use for deps"
msgstr "Markera fjärrförrådet med att det inte används för beroenden"

#: app/flatpak-builtins-remote-add.c:75 app/flatpak-builtins-remote-modify.c:81
msgid "Set priority (default 1, higher is more prioritized)"
msgstr "Ställ in prioritet (standard är 1, högre är mer prioriterade)"

#: app/flatpak-builtins-remote-add.c:75 app/flatpak-builtins-remote-modify.c:81
msgid "PRIORITY"
msgstr "PRIORITET"

#: app/flatpak-builtins-remote-add.c:76
msgid "The named subset to use for this remote"
msgstr "Den namngivna delmängden att använda för detta fjärrförråd"

#: app/flatpak-builtins-remote-add.c:76 app/flatpak-builtins-remote-modify.c:71
msgid "SUBSET"
msgstr "DELMÄNGD"

#: app/flatpak-builtins-remote-add.c:77 app/flatpak-builtins-remote-modify.c:82
msgid "A nice name to use for this remote"
msgstr "Ett enkelt namn att använda för detta fjärrförråd"

#: app/flatpak-builtins-remote-add.c:78 app/flatpak-builtins-remote-modify.c:83
msgid "A one-line comment for this remote"
msgstr "En enradskommentar för detta fjärrförråd"

#: app/flatpak-builtins-remote-add.c:79 app/flatpak-builtins-remote-modify.c:84
msgid "A full-paragraph description for this remote"
msgstr "Ett helt stycke med beskrivning för detta fjärrförråd"

#: app/flatpak-builtins-remote-add.c:80 app/flatpak-builtins-remote-modify.c:85
msgid "URL for a website for this remote"
msgstr "URL för en webbplats för detta fjärrförråd"

#: app/flatpak-builtins-remote-add.c:81 app/flatpak-builtins-remote-modify.c:86
msgid "URL for an icon for this remote"
msgstr "URL för en ikon för detta fjärrförråd"

#: app/flatpak-builtins-remote-add.c:82 app/flatpak-builtins-remote-modify.c:87
msgid "Default branch to use for this remote"
msgstr "Standardgren att använda för detta fjärrförråd"

#: app/flatpak-builtins-remote-add.c:84 app/flatpak-builtins-remote-modify.c:89
msgid "Import GPG key from FILE (- for stdin)"
msgstr "Importera GPG-nyckel från FIL (- för standard in)"

#: app/flatpak-builtins-remote-add.c:85 app/flatpak-builtins-remote-modify.c:90
msgid "Load signatures from URL"
msgstr "Läs in signaturer från URL"

#: app/flatpak-builtins-remote-add.c:86 app/flatpak-builtins-remote-modify.c:92
msgid "Set path to local filter FILE"
msgstr "Ställ in sökväg till FIL för lokalt filter"

#: app/flatpak-builtins-remote-add.c:87 app/flatpak-builtins-remote-modify.c:93
msgid "Disable the remote"
msgstr "Inaktivera fjärrförrådet"

#: app/flatpak-builtins-remote-add.c:88 app/flatpak-builtins-remote-modify.c:94
msgid "Name of authenticator"
msgstr "Namn på autentiserare"

#: app/flatpak-builtins-remote-add.c:90 app/flatpak-builtins-remote-modify.c:96
msgid "Autoinstall authenticator"
msgstr "Installera automatiskt autentiserare"

#: app/flatpak-builtins-remote-add.c:91 app/flatpak-builtins-remote-modify.c:97
msgid "Don't autoinstall authenticator"
msgstr "Installera inte automatiskt autentiserare"

#: app/flatpak-builtins-remote-add.c:92 app/flatpak-builtins-remote-modify.c:99
msgid "Don't follow the redirect set in the summary file"
msgstr "Följ inte omdirigeringen som satts i sammanfattningsfilen"

#: app/flatpak-builtins-remote-add.c:261 app/flatpak-builtins-remote-add.c:268
#, c-format
msgid "Can't load uri %s: %s\n"
msgstr "Det går inte att läsa in uri %s: %s\n"

#: app/flatpak-builtins-remote-add.c:276 common/flatpak-dir.c:4643
#, c-format
msgid "Can't load file %s: %s\n"
msgstr "Det går inte att läsa in filen %s: %s\n"

#: app/flatpak-builtins-remote-add.c:304
msgid "NAME LOCATION - Add a remote repository"
msgstr "NAMN PLATS - Lägg till ett fjärrförråd"

#: app/flatpak-builtins-remote-add.c:331
msgid "GPG verification is required if collections are enabled"
msgstr "GPG-verifiering krävs om samlingar är aktiverat"

#: app/flatpak-builtins-remote-add.c:393
#, c-format
msgid "Remote %s already exists"
msgstr "Fjärrförrådet %s existerar redan"

#: app/flatpak-builtins-remote-add.c:405
#: app/flatpak-builtins-remote-modify.c:340
#, c-format
msgid "Invalid authenticator name %s"
msgstr "Ogiltigt autentiserarnamn %s"

#: app/flatpak-builtins-remote-add.c:422
#, c-format
msgid "Warning: Could not update extra metadata for '%s': %s\n"
msgstr "Varning: Det gick inte att uppdatera extra metadata för ”%s”: %s\n"

#: app/flatpak-builtins-remote-delete.c:39
msgid "Remove remote even if in use"
msgstr "Ta bort fjärrförrådet även om det används"

#: app/flatpak-builtins-remote-delete.c:53
msgid "NAME - Delete a remote repository"
msgstr "NAMN - Ta bort ett fjärrförråd"

#: app/flatpak-builtins-remote-delete.c:100
#, c-format
msgid "The following refs are installed from remote '%s':"
msgstr "Följande referenser är installerade från fjärrförrådet ”%s”:"

#: app/flatpak-builtins-remote-delete.c:101
msgid "Remove them?"
msgstr "Ta bort dem?"

#: app/flatpak-builtins-remote-delete.c:103
#, c-format
msgid "Can't remove remote '%s' with installed refs"
msgstr ""
"Det går inte att ta bort fjärrförrådet ”%s” med installerade referenser"

#: app/flatpak-builtins-remote-info.c:55
msgid "Commit to show info for"
msgstr "Incheckning att visa information för"

#: app/flatpak-builtins-remote-info.c:58
msgid "Display log"
msgstr "Visa logg"

#: app/flatpak-builtins-remote-info.c:61
msgid "Show parent"
msgstr "Visa överordnad"

#: app/flatpak-builtins-remote-info.c:65 app/flatpak-builtins-remote-ls.c:60
msgid "Use local caches even if they are stale"
msgstr "Använd lokala cachar även om de är gamla"

#. Translators: A sideload is when you install from a local USB drive rather than the Internet.
#: app/flatpak-builtins-remote-info.c:67 app/flatpak-builtins-remote-ls.c:62
msgid "Only list refs available as sideloads"
msgstr "Lista endast referenser tillgängliga som sidoinläsningar"

#: app/flatpak-builtins-remote-info.c:114
msgid ""
" REMOTE REF - Show information about an application or runtime in a remote"
msgstr ""
" FJÄRRFÖRRÅD REF - visa information om ett program eller en exekveringsmiljö "
"i ett fjärrförråd"

#: app/flatpak-builtins-remote-info.c:125
msgid "REMOTE and REF must be specified"
msgstr "FJÄRRFÖRRÅD och REF måste anges"

#: app/flatpak-builtins-remote-info.c:247
#: app/flatpak-builtins-remote-info.c:282
msgid "Download Size:"
msgstr "Hämtningsstorlek:"

#: app/flatpak-builtins-remote-info.c:267
#: app/flatpak-builtins-remote-info.c:325
msgid "History:"
msgstr "Historik:"

#: app/flatpak-builtins-remote-info.c:348
msgid " Commit:"
msgstr " Incheckning:"

#: app/flatpak-builtins-remote-info.c:349
msgid " Subject:"
msgstr " Ämne:"

#: app/flatpak-builtins-remote-info.c:350
msgid " Date:"
msgstr " Datum:"

#: app/flatpak-builtins-remote-info.c:383
#, c-format
msgid "Warning: Commit %s has no flatpak metadata\n"
msgstr "Varning: Incheckning %s har inga flatpak-metadata\n"

#: app/flatpak-builtins-remote-list.c:43
msgid "Show remote details"
msgstr "Visa detaljer för fjärrförrådet"

#: app/flatpak-builtins-remote-list.c:44
msgid "Show disabled remotes"
msgstr "Visa inaktiverade fjärrförråd"

#: app/flatpak-builtins-remote-list.c:52
msgid "Title"
msgstr "Titel"

#: app/flatpak-builtins-remote-list.c:52
msgid "Show the title"
msgstr "Visa titeln"

#: app/flatpak-builtins-remote-list.c:53
msgid "Show the URL"
msgstr "Visa URL:en"

#: app/flatpak-builtins-remote-list.c:54
msgid "Show the collection ID"
msgstr "Visa samlings-ID"

#: app/flatpak-builtins-remote-list.c:55 app/flatpak-builtins-repo.c:392
msgid "Subset"
msgstr "Delmängd"

#: app/flatpak-builtins-remote-list.c:55
msgid "Show the subset"
msgstr "Visa delmängden"

#: app/flatpak-builtins-remote-list.c:56
msgid "Filter"
msgstr "Filter"

#: app/flatpak-builtins-remote-list.c:56
msgid "Show filter file"
msgstr "Visa filterfil"

#: app/flatpak-builtins-remote-list.c:57
msgid "Priority"
msgstr "Prioritet"

#: app/flatpak-builtins-remote-list.c:57
msgid "Show the priority"
msgstr "Visa prioritet"

#: app/flatpak-builtins-remote-list.c:59
msgid "Comment"
msgstr "Kommentar"

#: app/flatpak-builtins-remote-list.c:59
msgid "Show comment"
msgstr "Visa kommentar"

#: app/flatpak-builtins-remote-list.c:60
msgid "Show description"
msgstr "Visa beskrivning"

#: app/flatpak-builtins-remote-list.c:61
msgid "Homepage"
msgstr "Webbsida"

#: app/flatpak-builtins-remote-list.c:61
msgid "Show homepage"
msgstr "Visa webbsida"

#: app/flatpak-builtins-remote-list.c:62
msgid "Icon"
msgstr "Ikon"

#: app/flatpak-builtins-remote-list.c:62
msgid "Show icon"
msgstr "Visa ikon"

#: app/flatpak-builtins-remote-list.c:231
msgid " - List remote repositories"
msgstr " - Lista fjärrförråd"

#: app/flatpak-builtins-remote-ls.c:52
msgid "Show arches and branches"
msgstr "Visa arkitekturer och grenar"

#: app/flatpak-builtins-remote-ls.c:53
msgid "Show only runtimes"
msgstr "Visa endast exekveringsmiljöer"

#: app/flatpak-builtins-remote-ls.c:54
msgid "Show only apps"
msgstr "Visa endast program"

#: app/flatpak-builtins-remote-ls.c:55
msgid "Show only those where updates are available"
msgstr "Visa endast de där uppdateringar finns tillgängliga"

#: app/flatpak-builtins-remote-ls.c:56
msgid "Limit to this arch (* for all)"
msgstr "Begränsa till denna ark (* för alla)"

#: app/flatpak-builtins-remote-ls.c:77
msgid "Show the runtime"
msgstr "Visa exekveringsmiljön"

#: app/flatpak-builtins-remote-ls.c:79
msgid "Download size"
msgstr "Hämtningsstorlek"

#: app/flatpak-builtins-remote-ls.c:79
msgid "Show the download size"
msgstr "Visa hämtningsstorlek"

#: app/flatpak-builtins-remote-ls.c:391
msgid " [REMOTE or URI] - Show available runtimes and applications"
msgstr ""
" [FJÄRRFÖRRÅD eller URI] - Visa tillgängliga exekveringsmiljöer och program"

#: app/flatpak-builtins-remote-modify.c:67
msgid "Enable GPG verification"
msgstr "Aktivera GPG-verifiering"

#: app/flatpak-builtins-remote-modify.c:68
msgid "Mark the remote as enumerate"
msgstr "Markera fjärrförrådet som uppräkningsbart"

#: app/flatpak-builtins-remote-modify.c:69
msgid "Mark the remote as used for dependencies"
msgstr "Markera fjärrförrådet med att det används för beroenden"

#: app/flatpak-builtins-remote-modify.c:70
msgid "Set a new URL"
msgstr "Ställ in en ny URL"

#: app/flatpak-builtins-remote-modify.c:71
msgid "Set a new subset to use"
msgstr "Ställ in en ny delmängd att använda"

#: app/flatpak-builtins-remote-modify.c:72
msgid "Enable the remote"
msgstr "Aktivera fjärrförrådet"

#: app/flatpak-builtins-remote-modify.c:73
msgid "Update extra metadata from the summary file"
msgstr "Uppdatera extra metadata från sammanfattningsfilen"

#: app/flatpak-builtins-remote-modify.c:91
msgid "Disable local filter"
msgstr "Inaktivera lokalt filter"

#: app/flatpak-builtins-remote-modify.c:95
msgid "Authenticator options"
msgstr "Autentiseraralternativ"

#: app/flatpak-builtins-remote-modify.c:98
msgid "Follow the redirect set in the summary file"
msgstr "Följ omdirigeringen som satts i sammanfattningsfilen"

#: app/flatpak-builtins-remote-modify.c:306
msgid "NAME - Modify a remote repository"
msgstr "NAMN - Modifiera ett fjärrförråd"

#: app/flatpak-builtins-remote-modify.c:316
msgid "Remote NAME must be specified"
msgstr "Fjärrförrådets NAMN måste anges"

#: app/flatpak-builtins-remote-modify.c:327
#, c-format
msgid "Updating extra metadata from remote summary for %s\n"
msgstr "Uppdaterar extra metadata från sammanfattning av fjärrförråd för %s\n"

#: app/flatpak-builtins-remote-modify.c:330
#, c-format
msgid "Error updating extra metadata for '%s': %s\n"
msgstr "Fel vid uppdatering av extra metadata för ”%s”: %s\n"

#: app/flatpak-builtins-remote-modify.c:331
#, c-format
msgid "Could not update extra metadata for %s"
msgstr "Det gick inte att uppdatera extra metadata för %s"

#: app/flatpak-builtins-repair.c:43
msgid "Don't make any changes"
msgstr "Gör inte några ändringar"

#: app/flatpak-builtins-repair.c:44
msgid "Reinstall all refs"
msgstr "Ominstallera alla referenser"

#: app/flatpak-builtins-repair.c:68
#, c-format
msgid "Object missing: %s.%s\n"
msgstr "Objekt saknas: %s.%s\n"

#: app/flatpak-builtins-repair.c:76
#, c-format
msgid "Object invalid: %s.%s\n"
msgstr "Objekt ogiltigt: %s.%s\n"

#: app/flatpak-builtins-repair.c:81
#, c-format
msgid "%s, deleting object\n"
msgstr "%s, tar bort objekt\n"

#: app/flatpak-builtins-repair.c:146
#, c-format
msgid "Can't load object %s: %s\n"
msgstr "Det går inte att läsa in objekt %s: %s\n"

#: app/flatpak-builtins-repair.c:228
#, c-format
msgid "Commit invalid %s: %s\n"
msgstr "Ogiltig incheckning %s: %s\n"

#: app/flatpak-builtins-repair.c:231
#, c-format
msgid "Deleting invalid commit %s: %s\n"
msgstr "Tar bort ogiltig incheckning %s: %s\n"

#: app/flatpak-builtins-repair.c:261
#, c-format
msgid "Commit should be marked partial: %s\n"
msgstr "Incheckningen bör markeras som partiell: %s\n"

#: app/flatpak-builtins-repair.c:264
#, c-format
msgid "Marking commit as partial: %s\n"
msgstr "Markerar incheckning som partiell: %s\n"

#: app/flatpak-builtins-repair.c:293
#, c-format
msgid "Problems loading data for %s: %s\n"
msgstr "Problem vid inläsning av data för %s: %s\n"

#: app/flatpak-builtins-repair.c:306
#, c-format
msgid "Error reinstalling %s: %s\n"
msgstr "Fel vid ominstallation av %s: %s\n"

#: app/flatpak-builtins-repair.c:327
msgid "- Repair a flatpak installation"
msgstr "- Reparera en flatpak-installation"

#: app/flatpak-builtins-repair.c:406
#, c-format
msgid "Removing non-deployed ref %s…\n"
msgstr "Tar bort ej distribuerad ref %s…\n"

#: app/flatpak-builtins-repair.c:411
#, c-format
msgid "Skipping non-deployed ref %s…\n"
msgstr "Hoppar över ej distribuerad ref %s…\n"

#: app/flatpak-builtins-repair.c:429
#, c-format
msgid "[%d/%d] Verifying %s…\n"
msgstr "[%d/%d] Verifierar %s…\n"

#: app/flatpak-builtins-repair.c:435
#, c-format
msgid "Dry run: "
msgstr "Torrkörning: "

#: app/flatpak-builtins-repair.c:440
#, c-format
msgid "Deleting ref %s due to missing objects\n"
msgstr "Tar bort ref %s på grund av saknade objekt\n"

#: app/flatpak-builtins-repair.c:444
#, c-format
msgid "Deleting ref %s due to invalid objects\n"
msgstr "Tar bort ref %s på grund av ogiltiga objekt\n"

#: app/flatpak-builtins-repair.c:448
#, c-format
msgid "Deleting ref %s due to %d\n"
msgstr "Tar bort ref %s på grund av %d\n"

#: app/flatpak-builtins-repair.c:464
#, c-format
msgid "Checking remotes...\n"
msgstr "Kontrollerar fjärrförråd…\n"

#: app/flatpak-builtins-repair.c:482
#, c-format
msgid "Remote %s for ref %s is missing\n"
msgstr "Fjärrförråd %s för ref %s saknas\n"

#: app/flatpak-builtins-repair.c:484
#, c-format
msgid "Remote %s for ref %s is disabled\n"
msgstr "Fjärrförråd %s för ref %s är inaktiverat\n"

#: app/flatpak-builtins-repair.c:490
#, c-format
msgid "Pruning objects\n"
msgstr "Rensa objekt\n"

#: app/flatpak-builtins-repair.c:498
#, c-format
msgid "Erasing .removed\n"
msgstr "Tar bort .removed\n"

#: app/flatpak-builtins-repair.c:524
#, c-format
msgid "Reinstalling refs\n"
msgstr "Ominstallerar referenser\n"

#: app/flatpak-builtins-repair.c:526
#, c-format
msgid "Reinstalling removed refs\n"
msgstr "Ominstallerar borttagna referenser\n"

#: app/flatpak-builtins-repair.c:551
#, c-format
msgid "While removing appstream for %s: "
msgstr "Under borttagning av appstream för %s: "

#: app/flatpak-builtins-repair.c:558
#, c-format
msgid "While deploying appstream for %s: "
msgstr "Under distribuering av appstream för %s: "

#: app/flatpak-builtins-repo.c:106
#, c-format
msgid "Repo mode: %s\n"
msgstr "Förrådsläge: %s\n"

#: app/flatpak-builtins-repo.c:113
#, c-format
msgid "Indexed summaries: %s\n"
msgstr "Indexerade sammanfattningar: %s\n"

#: app/flatpak-builtins-repo.c:113 app/flatpak-builtins-repo.c:139
#: app/flatpak-builtins-repo.c:172
msgid "true"
msgstr "sant"

#: app/flatpak-builtins-repo.c:113 app/flatpak-builtins-repo.c:139
#: app/flatpak-builtins-repo.c:172
msgid "false"
msgstr "falskt"

#: app/flatpak-builtins-repo.c:121
#, c-format
msgid "Subsummaries: "
msgstr "Undersammanfattningar: "

#: app/flatpak-builtins-repo.c:136
#, c-format
msgid "Cache version: %d\n"
msgstr "Cacheversion: %d\n"

#: app/flatpak-builtins-repo.c:139
#, c-format
msgid "Indexed deltas: %s\n"
msgstr "Indexerade deltan: %s\n"

#: app/flatpak-builtins-repo.c:142
#, c-format
msgid "Title: %s\n"
msgstr "Titel: %s\n"

#: app/flatpak-builtins-repo.c:145
#, c-format
msgid "Comment: %s\n"
msgstr "Kommentar: %s\n"

#: app/flatpak-builtins-repo.c:148
#, c-format
msgid "Description: %s\n"
msgstr "Beskrivning: %s\n"

#: app/flatpak-builtins-repo.c:151
#, c-format
msgid "Homepage: %s\n"
msgstr "Webbsida: %s\n"

#: app/flatpak-builtins-repo.c:154
#, c-format
msgid "Icon: %s\n"
msgstr "Ikon: %s\n"

#: app/flatpak-builtins-repo.c:157
#, c-format
msgid "Collection ID: %s\n"
msgstr "Samlings-ID: %s\n"

#: app/flatpak-builtins-repo.c:160
#, c-format
msgid "Default branch: %s\n"
msgstr "Standardgren: %s\n"

#: app/flatpak-builtins-repo.c:163
#, c-format
msgid "Redirect URL: %s\n"
msgstr "Omdirigerings-URL: %s\n"

#: app/flatpak-builtins-repo.c:166
#, c-format
msgid "Deploy collection ID: %s\n"
msgstr "Distributionssamlings-ID: %s\n"

#: app/flatpak-builtins-repo.c:169
#, c-format
msgid "Authenticator name: %s\n"
msgstr "Namn på autentiserare: %s\n"

#: app/flatpak-builtins-repo.c:172
#, c-format
msgid "Authenticator install: %s\n"
msgstr "Autentiserarinstallation: %s\n"

#: app/flatpak-builtins-repo.c:180
#, c-format
msgid "GPG key hash: %s\n"
msgstr "GPG-nyckelhash: %s\n"

#: app/flatpak-builtins-repo.c:184
#, c-format
msgid "%zd summary branches\n"
msgstr "%zd sammanfattningsgrenar\n"

#: app/flatpak-builtins-repo.c:336
msgid "Installed"
msgstr "Installerad"

#. Translators: Download is used here as a noun
#: app/flatpak-builtins-repo.c:338 app/flatpak-cli-transaction.c:1462
msgid "Download"
msgstr "Hämta"

#: app/flatpak-builtins-repo.c:339
msgid "Subsets"
msgstr "Delmängder"

#: app/flatpak-builtins-repo.c:393
msgid "Digest"
msgstr "Sammandrag"

#: app/flatpak-builtins-repo.c:394
msgid "History length"
msgstr "Historiklängd"

#: app/flatpak-builtins-repo.c:711
msgid "Print general information about the repository"
msgstr "Skriv ut allmän information om förrådet"

#: app/flatpak-builtins-repo.c:712
msgid "List the branches in the repository"
msgstr "Lista grenar i förrådet"

#: app/flatpak-builtins-repo.c:713
msgid "Print metadata for a branch"
msgstr "Skriv ut metadata för en gren"

#: app/flatpak-builtins-repo.c:714
msgid "Show commits for a branch"
msgstr "Visa incheckningar för en gren"

#: app/flatpak-builtins-repo.c:715
msgid "Print information about the repo subsets"
msgstr "Skriv ut information om förrådsdelmängderna"

#: app/flatpak-builtins-repo.c:716
msgid "Limit information to subsets with this prefix"
msgstr "Begränsa information till delmängder med detta prefix"

#: app/flatpak-builtins-repo.c:732
msgid "LOCATION - Repository maintenance"
msgstr "PLATS - underhåll av förråd"

#: app/flatpak-builtins-run.c:159
msgid "Command to run"
msgstr "Kommando att köra"

#: app/flatpak-builtins-run.c:160
msgid "Directory to run the command in"
msgstr "Katalog att köra kommando i"

#: app/flatpak-builtins-run.c:161
msgid "Branch to use"
msgstr "Gren att använda"

#: app/flatpak-builtins-run.c:162
msgid "Use development runtime"
msgstr "Använd utvecklingsexekveringsmiljö"

#: app/flatpak-builtins-run.c:163
msgid "Runtime to use"
msgstr "Exekveringsmiljö att använda"

#: app/flatpak-builtins-run.c:164
msgid "Runtime version to use"
msgstr "Version av exekveringsmiljö att använda"

#: app/flatpak-builtins-run.c:167
msgid "Log accessibility bus calls"
msgstr "Logga hjälpmedelsbussanrop"

#: app/flatpak-builtins-run.c:168
msgid "Don't proxy accessibility bus calls"
msgstr "Använd inte proxy för hjälpmedelsbussanrop"

#: app/flatpak-builtins-run.c:169
msgid "Proxy accessibility bus calls (default except when sandboxed)"
msgstr "Använd proxy för hjälpmedelsbussanrop (standard utom när i sandlåda)"

#: app/flatpak-builtins-run.c:170
msgid "Don't proxy session bus calls"
msgstr "Använd inte proxy för sessionsbussanrop"

#: app/flatpak-builtins-run.c:171
msgid "Proxy session bus calls (default except when sandboxed)"
msgstr "Använd proxy för sessionsbussanrop (standard utom när i sandlåda)"

#: app/flatpak-builtins-run.c:172
msgid "Don't start portals"
msgstr "Starta inte portaler"

#: app/flatpak-builtins-run.c:173
msgid "Enable file forwarding"
msgstr "Aktivera filvidarebefordran"

#: app/flatpak-builtins-run.c:174
msgid "Run specified commit"
msgstr "Kör angiven incheckning"

#: app/flatpak-builtins-run.c:175
msgid "Use specified runtime commit"
msgstr "Använd angiven incheckning för exekveringsmiljö"

#: app/flatpak-builtins-run.c:176
msgid "Run completely sandboxed"
msgstr "Kör fullständigt i sandlåda"

#: app/flatpak-builtins-run.c:178
msgid "Use PID as parent pid for sharing namespaces"
msgstr "Använd PID som överordnad pid för att dela namnrymder"

#: app/flatpak-builtins-run.c:179
msgid "Make processes visible in parent namespace"
msgstr "Gör processer synliga i överordnad namnrymd"

#: app/flatpak-builtins-run.c:180
msgid "Share process ID namespace with parent"
msgstr "Dela namnrymd för process-ID med överordnad"

#: app/flatpak-builtins-run.c:181
msgid "Write the instance ID to the given file descriptor"
msgstr "Skriv instans-ID:t till det givna filhandtaget"

#: app/flatpak-builtins-run.c:182
msgid "Use PATH instead of the app's /app"
msgstr "Använd SÖKVÄG istället för programmets /app"

#: app/flatpak-builtins-run.c:183
#, fuzzy
msgid "Use FD instead of the app's /app"
msgstr "Använd SÖKVÄG istället för programmets /app"

# Filhandtag
#: app/flatpak-builtins-run.c:183 app/flatpak-builtins-run.c:185
#: app/flatpak-builtins-run.c:187 app/flatpak-builtins-run.c:188
#: common/flatpak-context.c:2672
msgid "FD"
msgstr "FH"

#: app/flatpak-builtins-run.c:184
msgid "Use PATH instead of the runtime's /usr"
msgstr "Använd SÖKVÄG istället för exekveringsmiljöns /usr"

#: app/flatpak-builtins-run.c:185
#, fuzzy
msgid "Use FD instead of the runtime's /usr"
msgstr "Använd SÖKVÄG istället för exekveringsmiljöns /usr"

#: app/flatpak-builtins-run.c:186
msgid "Clear all outside environment variables"
msgstr "Rensa alla yttre miljövariabler"

#: app/flatpak-builtins-run.c:187
msgid ""
"Bind mount the file or directory referred to by FD to its canonicalized path"
msgstr ""

#: app/flatpak-builtins-run.c:188
msgid ""
"Bind mount the file or directory referred to by FD read-only to its "
"canonicalized path"
msgstr ""

#: app/flatpak-builtins-run.c:219
msgid "APP [ARGUMENT…] - Run an app"
msgstr "PROGRAM [ARGUMENT…] - Kör ett program"

#: app/flatpak-builtins-run.c:370
#, c-format
msgid "runtime/%s/%s/%s not installed"
msgstr "runtime/%s/%s/%s inte installerad"

#: app/flatpak-builtins-run.c:419
msgid "app-fd and app-path cannot both be used"
msgstr ""

#: app/flatpak-builtins-run.c:449
msgid "usr-fd and usr-path cannot both be used"
msgstr ""

#: app/flatpak-builtins-search.c:37
msgid "Arch to search for"
msgstr "Ark att söka efter"

#: app/flatpak-builtins-search.c:49
msgid "Remotes"
msgstr "Fjärrförråd"

#: app/flatpak-builtins-search.c:49
msgid "Show the remotes"
msgstr "Visa fjärrförråden"

#: app/flatpak-builtins-search.c:244
msgid "TEXT - Search remote apps/runtimes for text"
msgstr "TEXT - Sök i fjärrprogram/exekveringsmiljöer efter text"

#: app/flatpak-builtins-search.c:255
msgid "TEXT must be specified"
msgstr "TEXT måste anges"

#: app/flatpak-builtins-search.c:338
msgid "No matches found"
msgstr "Inga träffar"

#: app/flatpak-builtins-uninstall.c:54
msgid "Arch to uninstall"
msgstr "Ark att avinstallera"

#: app/flatpak-builtins-uninstall.c:55
msgid "Keep ref in local repository"
msgstr "Behåll ref i lokalt förråd"

#: app/flatpak-builtins-uninstall.c:56
msgid "Don't uninstall related refs"
msgstr "Avinstallera inte relaterade referenser"

#: app/flatpak-builtins-uninstall.c:57
msgid "Remove files even if running"
msgstr "Ta bort filer även om de kör"

#: app/flatpak-builtins-uninstall.c:60
msgid "Uninstall all"
msgstr "Avinstallera alla"

#: app/flatpak-builtins-uninstall.c:61
msgid "Uninstall unused"
msgstr "Avinstallera oanvända"

#: app/flatpak-builtins-uninstall.c:62
msgid "Delete app data"
msgstr "Ta bort programdata"

#: app/flatpak-builtins-uninstall.c:141
#, c-format
msgid "Delete data for %s?"
msgstr "Ta bort data för %s?"

#: app/flatpak-builtins-uninstall.c:220
#, c-format
msgid "Info: applications using the extension %s%s%s branch %s%s%s:\n"
msgstr "Info: program använder tillägget %s%s%s gren %s%s%s:\n"

#: app/flatpak-builtins-uninstall.c:223
#, c-format
msgid "Info: applications using the runtime %s%s%s branch %s%s%s:\n"
msgstr "Info: program använder exekveringsmiljön %s%s%s gren %s%s%s:\n"

#: app/flatpak-builtins-uninstall.c:238
msgid "Really remove?"
msgstr "Vill du verkligen ta bort?"

#: app/flatpak-builtins-uninstall.c:255
msgid "[REF…] - Uninstall applications or runtimes"
msgstr "[REF…] - Avinstallera program eller exekveringsmiljöer"

#: app/flatpak-builtins-uninstall.c:264
msgid "Must specify at least one REF, --unused, --all or --delete-data"
msgstr "Måste ange åtminstone en REF, --unused, --all eller --delete-data"

#: app/flatpak-builtins-uninstall.c:267
msgid "Must not specify REFs when using --all"
msgstr "Får inte ange REFerenser då --all används"

#: app/flatpak-builtins-uninstall.c:270
msgid "Must not specify REFs when using --unused"
msgstr "Får inte ange REFerenser då --unused används"

#: app/flatpak-builtins-uninstall.c:336
#, c-format
msgid ""
"\n"
"These runtimes in installation '%s' are pinned and won't be removed; see "
"flatpak-pin(1):\n"
msgstr ""
"\n"
"Dessa exekveringsmiljöer i installationen ”%s” nålas och kommer inte tas "
"bort; se flatpak-pin(1):\n"

#: app/flatpak-builtins-uninstall.c:370
#, c-format
msgid "Nothing unused to uninstall\n"
msgstr "Inget oanvänt att avinstallera\n"

#: app/flatpak-builtins-uninstall.c:444
#, c-format
msgid "No installed refs found for ‘%s’"
msgstr "Inga installerade referenser hittades för ”%s”"

#: app/flatpak-builtins-uninstall.c:447
#, c-format
msgid " with arch ‘%s’"
msgstr " med ark ”%s”"

#: app/flatpak-builtins-uninstall.c:449
#, c-format
msgid " with branch ‘%s’"
msgstr " med gren ”%s”"

#: app/flatpak-builtins-uninstall.c:456
#, c-format
msgid "Warning: %s is not installed\n"
msgstr "Varning: %s är inte installerad\n"

#: app/flatpak-builtins-uninstall.c:490
#, c-format
msgid "None of the specified refs are installed"
msgstr "Inga av de angivna referenserna är installerade"

#: app/flatpak-builtins-uninstall.c:599
#, c-format
msgid "No app data to delete\n"
msgstr "Inga programdata att ta bort\n"

#: app/flatpak-builtins-update.c:56
msgid "Arch to update for"
msgstr "Ark att uppdatera för"

#: app/flatpak-builtins-update.c:57
msgid "Commit to deploy"
msgstr "Incheckning att distribuera"

#: app/flatpak-builtins-update.c:58
msgid "Remove old files even if running"
msgstr "Ta bort gamla filer även om de kör"

#: app/flatpak-builtins-update.c:59
msgid "Don't pull, only update from local cache"
msgstr "Hämta inte, uppdatera endast från lokal cache"

#: app/flatpak-builtins-update.c:61
msgid "Don't update related refs"
msgstr "Uppdatera inte relaterade referenser"

#: app/flatpak-builtins-update.c:66
msgid "Update appstream for remote"
msgstr "Uppdatera appstream för fjärrförråd"

#: app/flatpak-builtins-update.c:67
msgid "Only update this subpath"
msgstr "Uppdatera endast denna undersökväg"

#: app/flatpak-builtins-update.c:90
msgid "[REF…] - Update applications or runtimes"
msgstr "[REF…] - Uppdatera program eller exekveringsmiljöer"

#: app/flatpak-builtins-update.c:121
msgid "With --commit, only one REF may be specified"
msgstr "Med --commit får endast en REF anges"

#: app/flatpak-builtins-update.c:162
#, c-format
msgid "Looking for updates…\n"
msgstr "Söker efter uppdateringar…\n"

#: app/flatpak-builtins-update.c:215
#, c-format
msgid "Unable to update %s: %s\n"
msgstr "Kunde inte uppdatera %s: %s\n"

#: app/flatpak-builtins-update.c:274
#, fuzzy, c-format
msgid "Nothing to update.\n"
msgstr "Inget att göra.\n"

#: app/flatpak-builtins-utils.c:337
#, c-format
msgid ""
"Remote ‘%s’ found in multiple installations, unable to proceed in non-"
"interactive mode"
msgstr ""
"Hittade fjärr ”%s” i flera installationer, kan inte fortsätta i icke-"
"interaktivt läge"

#: app/flatpak-builtins-utils.c:346
#, c-format
msgid "Remote ‘%s’ found in multiple installations:"
msgstr "Fjärrförrådet ”%s” hittades i flera installationer:"

#: app/flatpak-builtins-utils.c:347 app/flatpak-builtins-utils.c:442
#: app/flatpak-builtins-utils.c:538 app/flatpak-builtins-utils.c:540
#: app/flatpak-builtins-utils.c:598
msgid "Which do you want to use (0 to abort)?"
msgstr "Vilken vill du använda (0 för att avbryta)?"

#: app/flatpak-builtins-utils.c:349
#, c-format
msgid "No remote chosen to resolve ‘%s’ which exists in multiple installations"
msgstr ""
"Inget fjärrförråd valt för att identifiera ”%s” som finns i flera "
"installationer"

#: app/flatpak-builtins-utils.c:358
#, c-format
msgid ""
"Remote \"%s\" not found\n"
"Hint: Use flatpak remote-add to add a remote"
msgstr ""
"Fjärrförrådet ”%s” hittades inte\n"
"Tips: Använd flatpak remote-add för att lägga till ett fjärrförråd"

#: app/flatpak-builtins-utils.c:364
#, c-format
msgid "Remote \"%s\" not found in the %s installation"
msgstr "Fjärrförrådet ”%s” hittades inte i %s-installationen"

#: app/flatpak-builtins-utils.c:404
#, c-format
msgid "Multiple refs match ‘%s’, unable to proceed in non-interactive mode"
msgstr ""
"Flera referenser matchar ”%s”, kan inte fortsätta i icke-interaktivt läge"

#. default to yes on Enter
#: app/flatpak-builtins-utils.c:430
#, c-format
msgid ""
"Found ref ‘%s’ in remote ‘%s’ (%s).\n"
"Use this ref?"
msgstr ""
"Hittade ref ”%s” i fjärrförrådet ”%s” (%s).\n"
"Använd denna ref?"

#: app/flatpak-builtins-utils.c:434 app/flatpak-builtins-utils.c:444
#: app/flatpak-builtins-utils.c:522 app/flatpak-builtins-utils.c:543
#, c-format
msgid "No ref chosen to resolve matches for ‘%s’"
msgstr "Ingen ref vald för att identifiera matchningar för ”%s”"

#: app/flatpak-builtins-utils.c:440
#, c-format
msgid "Similar refs found for ‘%s’ in remote ‘%s’ (%s):"
msgstr "Liknande referenser hittades för ”%s” i fjärrförrådet ”%s” (%s):"

#: app/flatpak-builtins-utils.c:488
#, c-format
msgid ""
"Multiple installed refs match ‘%s’, unable to proceed in non-interactive mode"
msgstr ""
"Flera installerade referenser matchar ”%s”, kan inte fortsätta i icke-"
"interaktivt läge"

#. default to yes on Enter
#: app/flatpak-builtins-utils.c:518
#, c-format
msgid "Found installed ref ‘%s’ (%s). Is this correct?"
msgstr "Hittade installerad ref ”%s” (%s). Stämmer detta?"

#: app/flatpak-builtins-utils.c:534
#, c-format
msgid "All of the above"
msgstr "Alla ovanstående"

#: app/flatpak-builtins-utils.c:535
#, c-format
msgid "Similar installed refs found for ‘%s’:"
msgstr "Liknande installerade referenser hittades för ”%s”:"

#: app/flatpak-builtins-utils.c:579
#, c-format
msgid ""
"Multiple remotes have refs matching ‘%s’, unable to proceed in non-"
"interactive mode"
msgstr ""
"Flera fjärrar har referenser som matchar ”%s”, kan inte fortsätta i icke-"
"interaktivt läge"

#: app/flatpak-builtins-utils.c:597
#, c-format
msgid "Remotes found with refs similar to ‘%s’:"
msgstr "Fjärrförråd hittades med referenser liknande ”%s”:"

#: app/flatpak-builtins-utils.c:600
#, c-format
msgid "No remote chosen to resolve matches for ‘%s’"
msgstr "Inget fjärrförråd valt för att identifiera matchningar för ”%s”"

#: app/flatpak-builtins-utils.c:696 app/flatpak-builtins-utils.c:699
#, c-format
msgid "Updating appstream data for user remote %s"
msgstr "Uppdaterar appstream-data för användarfjärrförrådet %s"

#: app/flatpak-builtins-utils.c:706 app/flatpak-builtins-utils.c:709
#, c-format
msgid "Updating appstream data for remote %s"
msgstr "Uppdaterar appstream-data för fjärrförrådet %s"

#: app/flatpak-builtins-utils.c:717 app/flatpak-builtins-utils.c:719
msgid "Error updating"
msgstr "Fel vid uppdatering"

#: app/flatpak-builtins-utils.c:755
#, c-format
msgid "Remote \"%s\" not found"
msgstr "Fann inte fjärrförrådet ”%s”"

#: app/flatpak-builtins-utils.c:796
#, c-format
msgid "Ambiguous suffix: '%s'."
msgstr "Tvetydigt suffix: ”%s”."

#. Translators: don't translate the values
#: app/flatpak-builtins-utils.c:798 app/flatpak-builtins-utils.c:813
msgid "Possible values are :s[tart], :m[iddle], :e[nd] or :f[ull]"
msgstr ""
"Möjliga värden är :s[tart], :m[iddle] (mitt), :e[nd] (slut) eller :f[ull]"

#: app/flatpak-builtins-utils.c:811
#, c-format
msgid "Invalid suffix: '%s'."
msgstr "Ogiltigt suffix: ”%s”."

#: app/flatpak-builtins-utils.c:846
#, c-format
msgid "Ambiguous column: %s"
msgstr "Tvetydig kolumn: %s"

#: app/flatpak-builtins-utils.c:859
#, c-format
msgid "Unknown column: %s"
msgstr "Okänd kolumn: %s"

#: app/flatpak-builtins-utils.c:917
msgid "Available columns:\n"
msgstr "Tillgängliga kolumner:\n"

#: app/flatpak-builtins-utils.c:927
msgid "Show all columns"
msgstr "Visa alla kolumner"

#: app/flatpak-builtins-utils.c:928
msgid "Show available columns"
msgstr "Visa tillgängliga kolumner"

#: app/flatpak-builtins-utils.c:931
msgid "Append :s[tart], :m[iddle], :e[nd] or :f[ull] to change ellipsization"
msgstr ""
"Lägg till :s[tart], :m[iddle] (mitt), :e[nd] (slut) eller :f[ull] för att "
"ändra elliptisering"

#: app/flatpak-builtins-utils.c:1483
#, c-format
msgid "Unknown scheme in sideload location %s"
msgstr "Okänt schema i sidoinläsningsplats %s"

#: app/flatpak-cli-transaction.c:96 app/flatpak-cli-transaction.c:102
#, c-format
msgid "Required runtime for %s (%s) found in remote %s\n"
msgstr "Exekveringsmiljön som krävs för %s (%s) hittades i fjärrförrådet %s\n"

#: app/flatpak-cli-transaction.c:104
msgid "Do you want to install it?"
msgstr "Vill du installera den?"

#: app/flatpak-cli-transaction.c:110
#, c-format
msgid "Required runtime for %s (%s) found in remotes:"
msgstr "Exekveringsmiljön som krävs för %s (%s) hittades i fjärrförråd:"

#: app/flatpak-cli-transaction.c:112
msgid "Which do you want to install (0 to abort)?"
msgstr "Vilka vill du installera (0 för att avbryta)?"

#: app/flatpak-cli-transaction.c:132
#, c-format
msgid "Configuring %s as new remote '%s'\n"
msgstr "Konfigurerar %s som ett nytt fjärrförråd ”%s”\n"

#. default to yes on Enter
#: app/flatpak-cli-transaction.c:139
#, c-format
msgid ""
"The remote '%s', referred to by '%s' at location %s contains additional "
"applications.\n"
"Should the remote be kept for future installations?"
msgstr ""
"Fjärrförrådet ”%s”, hänvisat till av ”%s” på plats %s innehåller ytterligare "
"program.\n"
"Vill du behålla fjärrförrådet för framtida installationer?"

#. default to yes on Enter
#: app/flatpak-cli-transaction.c:147
#, c-format
msgid ""
"The application %s depends on runtimes from:\n"
"  %s\n"
"Configure this as new remote '%s'"
msgstr ""
"Programmet %s är beroende av exekveringsmiljöer från:\n"
"  %s\n"
"Konfigurera detta som ett nytt fjärrförråd ”%s”"

#. Formatted size/remaining time in seconds
#: app/flatpak-cli-transaction.c:321
#, c-format
msgid "%s/s%s%s"
msgstr "%s/s%s%s"

#. Download progress percentage, use the appropriate
#. percent format for your language
#: app/flatpak-cli-transaction.c:359
#, c-format
msgid "%3d%%"
msgstr "%3d%%"

#: app/flatpak-cli-transaction.c:414
msgid "Installing…"
msgstr "Installerar…"

#: app/flatpak-cli-transaction.c:416
#, c-format
msgid "Installing %d/%d…"
msgstr "Installerar %d/%d…"

#: app/flatpak-cli-transaction.c:421
msgid "Updating…"
msgstr "Uppdaterar…"

#: app/flatpak-cli-transaction.c:423
#, c-format
msgid "Updating %d/%d…"
msgstr "Uppdaterar %d/%d…"

#: app/flatpak-cli-transaction.c:428
msgid "Uninstalling…"
msgstr "Avinstallerar…"

#: app/flatpak-cli-transaction.c:430
#, c-format
msgid "Uninstalling %d/%d…"
msgstr "Avinstallerar %d/%d…"

#: app/flatpak-cli-transaction.c:496 app/flatpak-quiet-transaction.c:161
#, c-format
msgid "Info: %s was skipped"
msgstr "Info: %s hoppades över"

#: app/flatpak-cli-transaction.c:519
#, c-format
msgid "Warning: %s%s%s already installed"
msgstr "Varning: %s%s%s redan installerad"

#: app/flatpak-cli-transaction.c:522
#, c-format
msgid "Error: %s%s%s already installed"
msgstr "Fel: %s%s%s redan installerad"

#: app/flatpak-cli-transaction.c:528
#, c-format
msgid "Warning: %s%s%s not installed"
msgstr "Varning: %s%s%s inte installerad"

#: app/flatpak-cli-transaction.c:531
#, c-format
msgid "Error: %s%s%s not installed"
msgstr "Fel: %s%s%s inte installerad"

#: app/flatpak-cli-transaction.c:537
#, c-format
msgid "Warning: %s%s%s needs a later flatpak version"
msgstr "Varning: %s%s%s behöver en senare flatpak-version"

#: app/flatpak-cli-transaction.c:540
#, c-format
msgid "Error: %s%s%s needs a later flatpak version"
msgstr "Fel: %s%s%s behöver en senare flatpak-version"

#: app/flatpak-cli-transaction.c:546
msgid "Warning: Not enough disk space to complete this operation"
msgstr "Varning: Otillräckligt diskutrymme för att slutföra denna åtgärd"

#: app/flatpak-cli-transaction.c:548
msgid "Error: Not enough disk space to complete this operation"
msgstr "Fel: Otillräckligt diskutrymme för att slutföra denna åtgärd"

#: app/flatpak-cli-transaction.c:553
#, c-format
msgid "Warning: %s"
msgstr "Varning: %s"

#: app/flatpak-cli-transaction.c:555
#, c-format
msgid "Error: %s"
msgstr "Fel: %s"

#: app/flatpak-cli-transaction.c:570
#, c-format
msgid "Failed to install %s%s%s: "
msgstr "Misslyckades med att installera %s%s%s: "

#: app/flatpak-cli-transaction.c:577
#, c-format
msgid "Failed to update %s%s%s: "
msgstr "Misslyckades med att uppdatera %s%s%s: "

#: app/flatpak-cli-transaction.c:584
#, c-format
msgid "Failed to install bundle %s%s%s: "
msgstr "Misslyckades med att installera bunten %s%s%s: "

#: app/flatpak-cli-transaction.c:591
#, c-format
msgid "Failed to uninstall %s%s%s: "
msgstr "Misslyckades med att avinstallera %s%s%s: "

#: app/flatpak-cli-transaction.c:642
#, c-format
msgid "Authentication required for remote '%s'\n"
msgstr "Autentisering krävs för fjärrförrådet ”%s”\n"

#: app/flatpak-cli-transaction.c:643
msgid "Open browser?"
msgstr "Öppna webbläsare?"

#: app/flatpak-cli-transaction.c:699
#, c-format
msgid "Login required remote %s (realm %s)\n"
msgstr "Inloggning krävde fjärrförrådet %s (rike %s)\n"

#: app/flatpak-cli-transaction.c:704
msgid "Password"
msgstr "Lösenord"

#. Only runtimes can be pinned
#: app/flatpak-cli-transaction.c:759
#, c-format
msgid ""
"\n"
"Info: (pinned) runtime %s%s%s branch %s%s%s is end-of-life, in favor of "
"%s%s%s branch %s%s%s\n"
msgstr ""
"\n"
"Info: (nålad) exekveringsmiljö %s%s%s gren %s%s%s har nått slutet på sin "
"livstid, till förmån för %s%s%s gren %s%s%s\n"

#: app/flatpak-cli-transaction.c:765
#, c-format
msgid ""
"\n"
"Info: runtime %s%s%s branch %s%s%s is end-of-life, in favor of %s%s%s branch "
"%s%s%s\n"
msgstr ""
"\n"
"Info: exekveringsmiljö %s%s%s gren %s%s%s har nått slutet på sin livstid, "
"till förmån för %s%s%s gren %s%s%s\n"

#: app/flatpak-cli-transaction.c:768
#, c-format
msgid ""
"\n"
"Info: app %s%s%s branch %s%s%s is end-of-life, in favor of %s%s%s branch "
"%s%s%s\n"
msgstr ""
"\n"
"Info: program %s%s%s gren %s%s%s har nått slutet på sin livstid, till förmån "
"för %s%s%s gren %s%s%s\n"

#. Only runtimes can be pinned
#: app/flatpak-cli-transaction.c:780
#, c-format
msgid ""
"\n"
"Info: (pinned) runtime %s%s%s branch %s%s%s is end-of-life, with reason:\n"
msgstr ""
"\n"
"Info: (nålad) exekveringsmiljö %s%s%s gren %s%s%s har nått slutet på sin "
"livstid, med anledning:\n"

#: app/flatpak-cli-transaction.c:786
#, c-format
msgid ""
"\n"
"Info: runtime %s%s%s branch %s%s%s is end-of-life, with reason:\n"
msgstr ""
"\n"
"Info: exekveringsmiljö %s%s%s gren %s%s%s har nått slutet på sin livstid, "
"med anledning:\n"

#: app/flatpak-cli-transaction.c:789
#, c-format
msgid ""
"\n"
"Info: app %s%s%s branch %s%s%s is end-of-life, with reason:\n"
msgstr ""
"\n"
"Info: program %s%s%s gren %s%s%s har nått slutet på sin livstid, med "
"anledning:\n"

#: app/flatpak-cli-transaction.c:963
#, c-format
msgid "Info: applications using this extension:\n"
msgstr "Info: program använder detta tillägg:\n"

#: app/flatpak-cli-transaction.c:965
#, c-format
msgid "Info: applications using this runtime:\n"
msgstr "Info: program använder denna exekveringsmiljö:\n"

#: app/flatpak-cli-transaction.c:984
msgid "Replace?"
msgstr "Ersätt?"

#: app/flatpak-cli-transaction.c:987 app/flatpak-quiet-transaction.c:247
#, c-format
msgid "Updating to rebased version\n"
msgstr "Uppdaterar till ombaserad version\n"

#: app/flatpak-cli-transaction.c:1011
#, c-format
msgid "Failed to rebase %s to %s: "
msgstr "Misslyckades med att ombasera %s till %s: "

#: app/flatpak-cli-transaction.c:1277
#, c-format
msgid "New %s%s%s permissions:"
msgstr "Nya rättigheter för %s%s%s:"

#: app/flatpak-cli-transaction.c:1279
#, c-format
msgid "%s%s%s permissions:"
msgstr "Rättigheter för %s%s%s:"

#: app/flatpak-cli-transaction.c:1343
msgid "Warning: "
msgstr "Varning: "

#. translators: This is short for operation, the title of a one-char column
#: app/flatpak-cli-transaction.c:1442
msgid "Op"
msgstr "Åtg"

#. Avoid resizing the download column too much,
#. * by making the title as long as typical content
#.
#: app/flatpak-cli-transaction.c:1458 app/flatpak-cli-transaction.c:1503
msgid "partial"
msgstr "partiell"

#: app/flatpak-cli-transaction.c:1535
msgid "Proceed with these changes to the user installation?"
msgstr "Fortsätt med dessa ändringar till användarinstallationen?"

#: app/flatpak-cli-transaction.c:1537
msgid "Proceed with these changes to the system installation?"
msgstr "Fortsätt med dessa ändringar till systeminstallationen?"

#: app/flatpak-cli-transaction.c:1539
#, c-format
msgid "Proceed with these changes to the %s?"
msgstr "Fortsätt med dessa ändringar till %s?"

#: app/flatpak-cli-transaction.c:1711
msgid "Changes complete."
msgstr "Ändringar slutförda."

#: app/flatpak-cli-transaction.c:1713
msgid "Uninstall complete."
msgstr "Avinstallation slutförd."

#: app/flatpak-cli-transaction.c:1715
msgid "Installation complete."
msgstr "Installation slutförd."

#: app/flatpak-cli-transaction.c:1717
msgid "Updates complete."
msgstr "Uppdateringar slutförda."

#. For updates/!stop_on_first_error we already printed all errors so we make up
#. a different one.
#: app/flatpak-cli-transaction.c:1750
msgid "There were one or more errors"
msgstr "Det fanns ett eller flera fel"

#. translators: please keep the leading space
#: app/flatpak-main.c:76
msgid " Manage installed applications and runtimes"
msgstr " Hantera installerade program och exekveringsmiljöer"

#: app/flatpak-main.c:77
msgid "Install an application or runtime"
msgstr "Installera ett program eller en exekveringsmiljö"

#: app/flatpak-main.c:78
msgid "Update an installed application or runtime"
msgstr "Uppdatera ett installerat program eller en exekveringsmiljö"

#: app/flatpak-main.c:81
msgid "Uninstall an installed application or runtime"
msgstr "Avinstallera ett installerat program eller en exekveringsmiljö"

#: app/flatpak-main.c:84
msgid "Mask out updates and automatic installation"
msgstr "Maskera uppdateringar och automatisk installation"

#: app/flatpak-main.c:85
msgid "Pin a runtime to prevent automatic removal"
msgstr "Nåla en exekveringsmiljö för att förhindra automatisk borttagning"

#: app/flatpak-main.c:86
msgid "List installed apps and/or runtimes"
msgstr "Lista installerade program och/eller exekveringsmiljöer"

#: app/flatpak-main.c:87
msgid "Show info for installed app or runtime"
msgstr "Visa information för installerade program eller exekveringsmiljöer"

#: app/flatpak-main.c:88
msgid "Show history"
msgstr "Visa historik"

#: app/flatpak-main.c:89
msgid "Configure flatpak"
msgstr "Konfigurera flatpak"

#: app/flatpak-main.c:90
msgid "Repair flatpak installation"
msgstr "Reparera flatpak-installation"

#: app/flatpak-main.c:91
msgid "Put applications or runtimes onto removable media"
msgstr "Placera program eller exekveringsmiljöer på flyttbara media"

#: app/flatpak-main.c:92
msgid "Install flatpaks that are part of the operating system"
msgstr "Installera flatpak-filer som är en del av operativsystemet"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:95
msgid ""
"\n"
" Find applications and runtimes"
msgstr ""
"\n"
" Hitta program och exekveringsmiljöer"

#: app/flatpak-main.c:96
msgid "Search for remote apps/runtimes"
msgstr "Sök efter fjärrprogram/exekveringsmiljöer"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:99
msgid ""
"\n"
" Manage running applications"
msgstr ""
"\n"
" Hantera körande program"

#: app/flatpak-main.c:100
msgid "Run an application"
msgstr "Kör ett program"

#: app/flatpak-main.c:101
msgid "Override permissions for an application"
msgstr "Åsidosätt rättigheter för ett program"

#: app/flatpak-main.c:102
msgid "Specify default version to run"
msgstr "Ange standardversion att köra"

#: app/flatpak-main.c:103
msgid "Enter the namespace of a running application"
msgstr "Ange namnrymden för ett körande program"

#: app/flatpak-main.c:104
msgid "Enumerate running applications"
msgstr "Räkna upp körande program"

#: app/flatpak-main.c:105
msgid "Stop a running application"
msgstr "Stoppa ett körande program"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:108
msgid ""
"\n"
" Manage file access"
msgstr ""
"\n"
" Hantera filåtkomst"

#: app/flatpak-main.c:109
msgid "List exported files"
msgstr "Lista exporterade filer"

#: app/flatpak-main.c:110
msgid "Grant an application access to a specific file"
msgstr "Ge ett program tillgång till en specifik fil"

#: app/flatpak-main.c:111
msgid "Revoke access to a specific file"
msgstr "Återkalla tillgång till en specifik fil"

#: app/flatpak-main.c:112
msgid "Show information about a specific file"
msgstr "Visa information om en specifik fil"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:116
msgid ""
"\n"
" Manage dynamic permissions"
msgstr ""
"\n"
" Hantera dynamiska rättigheter"

#: app/flatpak-main.c:117
msgid "List permissions"
msgstr "Lista rättigheter"

#: app/flatpak-main.c:118
msgid "Remove item from permission store"
msgstr "Ta bort objekt från rättighetslagring"

#: app/flatpak-main.c:120
msgid "Set permissions"
msgstr "Ställ in rättigheter"

#: app/flatpak-main.c:121
msgid "Show app permissions"
msgstr "Visa programrättigheter"

#: app/flatpak-main.c:122
msgid "Reset app permissions"
msgstr "Återställ programrättigheter"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:125
msgid ""
"\n"
" Manage remote repositories"
msgstr ""
"\n"
" Hantera fjärrförråd"

#: app/flatpak-main.c:126
msgid "List all configured remotes"
msgstr "Lista alla konfigurerade fjärrförråd"

#: app/flatpak-main.c:127
msgid "Add a new remote repository (by URL)"
msgstr "Lägg till ett nytt fjärrförråd (efter URL)"

#: app/flatpak-main.c:128
msgid "Modify properties of a configured remote"
msgstr "Modifiera egenskaper för ett konfigurerat fjärrförråd"

#: app/flatpak-main.c:129
msgid "Delete a configured remote"
msgstr "Ta bort ett konfigurerat fjärrförråd"

#: app/flatpak-main.c:131
msgid "List contents of a configured remote"
msgstr "Lista innehåll för ett konfigurerat fjärrförråd"

#: app/flatpak-main.c:132
msgid "Show information about a remote app or runtime"
msgstr "Visa information om ett fjärrprogram eller en exekveringsmiljö"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:135
msgid ""
"\n"
" Build applications"
msgstr ""
"\n"
" Bygg program"

#: app/flatpak-main.c:136
msgid "Initialize a directory for building"
msgstr "Initiera en katalog för bygge"

#: app/flatpak-main.c:137
msgid "Run a build command inside the build dir"
msgstr "Kör ett byggkommando inuti byggkatalogen"

#: app/flatpak-main.c:138
msgid "Finish a build dir for export"
msgstr "Avsluta en byggkatalog för export"

#: app/flatpak-main.c:139
msgid "Export a build dir to a repository"
msgstr "Exportera en byggkatalog till ett förråd"

#: app/flatpak-main.c:140
msgid "Create a bundle file from a ref in a local repository"
msgstr "Skapa en buntfil från en ref i ett lokalt förråd"

#: app/flatpak-main.c:141
msgid "Import a bundle file"
msgstr "Importera en buntfil"

#: app/flatpak-main.c:142
msgid "Sign an application or runtime"
msgstr "Signera ett program eller en exekveringsmiljö"

#: app/flatpak-main.c:143
msgid "Update the summary file in a repository"
msgstr "Uppdatera sammanfattningsfilen i ett förråd"

#: app/flatpak-main.c:144
msgid "Create new commit based on existing ref"
msgstr "Skapa ny incheckning baserad på befintlig ref"

#: app/flatpak-main.c:145
msgid "Show information about a repo"
msgstr "Visa information om ett förråd"

#: app/flatpak-main.c:162
msgid "Show debug information, -vv for more detail"
msgstr "Visa felsökningsinformation, -vv för ytterligare detaljer"

#: app/flatpak-main.c:163
msgid "Show OSTree debug information"
msgstr "Visa OSTree-felsökningsinformation"

#: app/flatpak-main.c:169
msgid "Print version information and exit"
msgstr "Skriv ut versionsinformation och avsluta"

#: app/flatpak-main.c:170
msgid "Print default arch and exit"
msgstr "Skriv ut standardarkitektur och avsluta"

#: app/flatpak-main.c:171
msgid "Print supported arches and exit"
msgstr "Skriv ut arkitekturer som stöds och avsluta"

#: app/flatpak-main.c:172
msgid "Print active gl drivers and exit"
msgstr "Skriv ut aktiva gl-drivrutiner och avsluta"

#: app/flatpak-main.c:173
msgid "Print paths for system installations and exit"
msgstr "Skriv ut sökvägar för systeminstallationer och avsluta"

#: app/flatpak-main.c:174
msgid "Print the updated environment needed to run flatpaks"
msgstr "Skriv ut den uppdaterade miljön som behövs för att köra flatpak-filer"

#: app/flatpak-main.c:175
msgid "Only include the system installation with --print-updated-env"
msgstr "Inkludera endast systeminstallationen med --print-updated-env"

#: app/flatpak-main.c:180
msgid "Work on the user installation"
msgstr "Arbeta på användarinstallationen"

#: app/flatpak-main.c:181
msgid "Work on the system-wide installation (default)"
msgstr "Arbeta på den systemomfattande installationen (standard)"

#: app/flatpak-main.c:182
msgid "Work on a non-default system-wide installation"
msgstr "Arbeta på en annan systemomfattande installation än standard"

#: app/flatpak-main.c:212
msgid "Builtin Commands:"
msgstr "Inbyggda kommandon:"

#: app/flatpak-main.c:298
#, c-format
msgid ""
"Note that the directories %s are not in the search path set by the "
"XDG_DATA_DIRS environment variable, so applications installed by Flatpak may "
"not appear on your desktop until the session is restarted."
msgstr ""
"Notera att katalogerna %s inte är i sökvägen som satts av miljövariabeln "
"XDG_DATA_DIRS, så program som installerats av Flatpak kanske inte dyker upp "
"på ditt skrivbord förrän sessionen har startats om."

#: app/flatpak-main.c:312
#, c-format
msgid ""
"Note that the directory %s is not in the search path set by the "
"XDG_DATA_DIRS environment variable, so applications installed by Flatpak may "
"not appear on your desktop until the session is restarted."
msgstr ""
"Notera att katalogen %s inte är i sökvägen som satts av miljövariabeln "
"XDG_DATA_DIRS, så program som installerats av Flatpak kanske inte dyker upp "
"på ditt skrivbord förrän sessionen har startats om."

#: app/flatpak-main.c:381
msgid ""
"Refusing to operate under sudo with --user. Omit sudo to operate on the user "
"installation, or use a root shell to operate on the root user's installation."
msgstr ""
"Vägrar att köras under sudo med --user. Skippa sudo för att köra på "
"användarinstallationen, eller använd ett root-skal för att köra på root-"
"användarens installation."

#: app/flatpak-main.c:453
msgid ""
"Multiple installations specified for a command that works on one installation"
msgstr ""
"Flera installationer angavs för ett kommando som är avsett för en "
"installation"

#: app/flatpak-main.c:504 app/flatpak-main.c:697
#, c-format
msgid "See '%s --help'"
msgstr "Se ”%s --help”"

#: app/flatpak-main.c:706
#, c-format
msgid "'%s' is not a flatpak command. Did you mean '%s%s'?"
msgstr "”%s” är inte ett flatpak-kommando. Menade du ”%s%s”?"

#: app/flatpak-main.c:709
#, c-format
msgid "'%s' is not a flatpak command"
msgstr "”%s” är inte ett flatpak-kommando"

#: app/flatpak-main.c:824
msgid "No command specified"
msgstr "Inget kommando angivet"

#: app/flatpak-main.c:980
msgid "error:"
msgstr "fel:"

#: app/flatpak-quiet-transaction.c:77
#, c-format
msgid "Installing %s\n"
msgstr "Installerar %s\n"

#: app/flatpak-quiet-transaction.c:81
#, c-format
msgid "Updating %s\n"
msgstr "Uppdaterar %s\n"

#: app/flatpak-quiet-transaction.c:85
#, c-format
msgid "Uninstalling %s\n"
msgstr "Avinstallerar %s\n"

#: app/flatpak-quiet-transaction.c:107
#, c-format
msgid "Warning: Failed to install %s: %s\n"
msgstr "Varning: Misslyckades med att installera %s: %s\n"

#: app/flatpak-quiet-transaction.c:110
#, c-format
msgid "Error: Failed to install %s: %s\n"
msgstr "Fel: Misslyckades med att installera %s: %s\n"

#: app/flatpak-quiet-transaction.c:116
#, c-format
msgid "Warning: Failed to update %s: %s\n"
msgstr "Varning: Misslyckades med att uppdatera %s: %s\n"

#: app/flatpak-quiet-transaction.c:119
#, c-format
msgid "Error: Failed to update %s: %s\n"
msgstr "Fel: Misslyckades med att uppdatera %s: %s\n"

#: app/flatpak-quiet-transaction.c:125
#, c-format
msgid "Warning: Failed to install bundle %s: %s\n"
msgstr "Varning: Misslyckades med att installera bunten %s: %s\n"

#: app/flatpak-quiet-transaction.c:128
#, c-format
msgid "Error: Failed to install bundle %s: %s\n"
msgstr "Fel: Misslyckades med att installera bunten %s: %s\n"

#: app/flatpak-quiet-transaction.c:134
#, c-format
msgid "Warning: Failed to uninstall %s: %s\n"
msgstr "Varning: Misslyckades med att avinstallera %s: %s\n"

#: app/flatpak-quiet-transaction.c:137
#, c-format
msgid "Error: Failed to uninstall %s: %s\n"
msgstr "Fel: Misslyckades med att avinstallera %s: %s\n"

#: app/flatpak-quiet-transaction.c:166 common/flatpak-dir.c:11475
#, c-format
msgid "%s already installed"
msgstr "%s redan installerad"

#: app/flatpak-quiet-transaction.c:168 common/flatpak-dir.c:3622
#: common/flatpak-dir.c:4321 common/flatpak-dir.c:16968
#: common/flatpak-dir.c:17258 common/flatpak-dir-utils.c:166
#: common/flatpak-dir-utils.c:259 common/flatpak-transaction.c:2736
#: common/flatpak-transaction.c:2791
#, c-format
msgid "%s not installed"
msgstr "%s inte installerad"

#: app/flatpak-quiet-transaction.c:170
#, c-format
msgid "%s needs a later flatpak version"
msgstr "%s behöver en senare flatpak-version"

#: app/flatpak-quiet-transaction.c:172
msgid "Not enough disk space to complete this operation"
msgstr "Otillräckligt diskutrymme för att slutföra denna åtgärd"

#: app/flatpak-quiet-transaction.c:239
#, c-format
msgid "Info: %s is end-of-life, in favor of %s\n"
msgstr "Info: %s har nått slutet på sin livstid, till förmån för %s\n"

#: app/flatpak-quiet-transaction.c:241
#, c-format
msgid "Info: %s is end-of-life, with reason: %s\n"
msgstr "Info: %s har nått slutet på sin livstid, med anledning: %s\n"

#: app/flatpak-quiet-transaction.c:251
#, c-format
msgid "Failed to rebase %s to %s: %s\n"
msgstr "Misslyckades med att ombasera %s till %s: %s\n"

#: common/flatpak-auth.c:58
#, c-format
msgid "No authenticator configured for remote `%s`"
msgstr "Ingen autentiserare konfigurerad för fjärrförrådet ”%s”"

#: common/flatpak-context.c:637 common/flatpak-context.c:649
#, c-format
msgid "Invalid permission syntax: %s"
msgstr "Ogiltig rättighetssyntax: %s"

#: common/flatpak-context.c:1207
#, c-format
msgid "Unknown share type %s, valid types are: %s"
msgstr "Okänd delningstyp %s, giltiga typer är: %s"

#: common/flatpak-context.c:1228
#, c-format
msgid "Unknown policy type %s, valid types are: %s"
msgstr "Okänd policytyp %s, giltiga typer är: %s"

#: common/flatpak-context.c:1266
#, c-format
msgid "Invalid dbus name %s"
msgstr "Ogiltigt dbusnamn %s"

#: common/flatpak-context.c:1279
#, c-format
msgid "Unknown socket type %s, valid types are: %s"
msgstr "Okänd uttagstyp %s, giltiga typer är: %s"

#: common/flatpak-context.c:1294
#, c-format
msgid "Unknown device type %s, valid types are: %s"
msgstr "Okänd enhetstyp %s, giltiga typer är: %s"

#: common/flatpak-context.c:1308
#, c-format
msgid "Unknown feature type %s, valid types are: %s"
msgstr "Okänd funktionstyp %s, giltiga typer är: %s"

#: common/flatpak-context.c:1840
#, c-format
msgid "Filesystem location \"%s\" contains \"..\""
msgstr "Filsystemsplatsen ”%s” innehåller ”..”"

#: common/flatpak-context.c:1882
#, c-format
msgid ""
"--filesystem=/ is not available, use --filesystem=host for a similar result"
msgstr ""
"--filesystem=/ är inte tillgängligt, använd --filesystem=host för ett "
"liknande resultat"

# host and home are hardcoded
#: common/flatpak-context.c:1916
#, c-format
msgid ""
"Unknown filesystem location %s, valid locations are: host, host-os, host-"
"etc, host-root, home, xdg-*[/…], ~/dir, /dir"
msgstr ""
"Okänd filsystemsplats %s, giltiga platser är: host, host-os, host-etc, host-"
"root, home, xdg-*[/…], ~/kat, /kat"

#: common/flatpak-context.c:2015
#, c-format
msgid "Invalid syntax for %s: %s"
msgstr "Ogiltig syntax för %s: %s"

#: common/flatpak-context.c:2142
#, c-format
msgid "fallback-x11 can not be conditional"
msgstr "fallback-x11 kan inte vara villkorlig"

#: common/flatpak-context.c:2318
#, c-format
msgid "Invalid env format %s"
msgstr "Ogiltigt miljöformat %s"

#: common/flatpak-context.c:2399
#, c-format
msgid "Environment variable name must not contain '=': %s"
msgstr "Miljövariabeln får inte innehålla '=': %s"

#: common/flatpak-context.c:2527 common/flatpak-context.c:2535
#, c-format
msgid "--add-policy arguments must be in the form SUBSYSTEM.KEY=VALUE"
msgstr ""
"Argument till --add-policy måste vara på formen UNDERSYSTEM.NYCKEL=VÄRDE"

#: common/flatpak-context.c:2542
#, c-format
msgid "--add-policy values can't start with \"!\""
msgstr "Värden till --add-policy får inte starta med ”!”"

#: common/flatpak-context.c:2567 common/flatpak-context.c:2575
#, c-format
msgid "--remove-policy arguments must be in the form SUBSYSTEM.KEY=VALUE"
msgstr ""
"Argument till --remove-policy måste vara på formen UNDERSYSTEM.NYCKEL=VÄRDE"

#: common/flatpak-context.c:2582
#, c-format
msgid "--remove-policy values can't start with \"!\""
msgstr "Värden till --remove-policy får inte starta med ”!”"

#: common/flatpak-context.c:2657
msgid "Share with host"
msgstr "Dela med värd"

#: common/flatpak-context.c:2657 common/flatpak-context.c:2658
msgid "SHARE"
msgstr "DELNING"

#: common/flatpak-context.c:2658
msgid "Unshare with host"
msgstr "Avsluta delning med värd"

#: common/flatpak-context.c:2659
msgid "Require conditions to be met for a subsystem to get shared"
msgstr "Kräv att villkor möts för att ett undersystem ska delas"

#: common/flatpak-context.c:2659
msgid "SHARE:CONDITION"
msgstr "DELNING:VILLKOR"

#: common/flatpak-context.c:2660
msgid "Expose socket to app"
msgstr "Exponera uttag för program"

#: common/flatpak-context.c:2660 common/flatpak-context.c:2661
msgid "SOCKET"
msgstr "UTTAG"

#: common/flatpak-context.c:2661
msgid "Don't expose socket to app"
msgstr "Exponera inte detta uttag för program"

#: common/flatpak-context.c:2662
msgid "Require conditions to be met for a socket to get exposed"
msgstr "Kräv att villkor möts för att ett uttag ska exponeras"

#: common/flatpak-context.c:2662
msgid "SOCKET:CONDITION"
msgstr "UTTAG:VILLKOR"

#: common/flatpak-context.c:2663
msgid "Expose device to app"
msgstr "Exponera enhet för program"

#: common/flatpak-context.c:2663 common/flatpak-context.c:2664
msgid "DEVICE"
msgstr "ENHET"

#: common/flatpak-context.c:2664
msgid "Don't expose device to app"
msgstr "Exponera inte enhet för program"

#: common/flatpak-context.c:2665
msgid "Require conditions to be met for a device to get exposed"
msgstr "Kräv att villkor möts för att en enhet ska exponeras"

#: common/flatpak-context.c:2665
msgid "DEVICE:CONDITION"
msgstr "ENHET:VILLKOR"

#: common/flatpak-context.c:2666
msgid "Allow feature"
msgstr "Tillåt funktion"

#: common/flatpak-context.c:2666 common/flatpak-context.c:2667
msgid "FEATURE"
msgstr "FUNKTION"

#: common/flatpak-context.c:2667
msgid "Don't allow feature"
msgstr "Tillåt inte funktion"

#: common/flatpak-context.c:2668
msgid "Require conditions to be met for a feature to get allowed"
msgstr "Kräv att villkor möts för att en funktion ska tillåtas"

#: common/flatpak-context.c:2668
msgid "FEATURE:CONDITION"
msgstr "FUNKTION:VILLKOR"

# :ro can't be translated
#: common/flatpak-context.c:2669
msgid "Expose filesystem to app (:ro for read-only)"
msgstr "Exponera filsystem för program (:ro för skrivskyddat)"

# :ro can't be translated
#: common/flatpak-context.c:2669
msgid "FILESYSTEM[:ro]"
msgstr "FILSYSTEM[:ro]"

#: common/flatpak-context.c:2670
msgid "Don't expose filesystem to app"
msgstr "Exponera inte filsystem för program"

#: common/flatpak-context.c:2670
msgid "FILESYSTEM"
msgstr "FILSYSTEM"

#: common/flatpak-context.c:2671
msgid "Set environment variable"
msgstr "Ställ in miljövariabel"

#: common/flatpak-context.c:2671
msgid "VAR=VALUE"
msgstr "VAR=VÄRDE"

#: common/flatpak-context.c:2672
msgid "Read environment variables in env -0 format from FD"
msgstr "Läs miljövariabler i formatet env -0 från FH"

#: common/flatpak-context.c:2673
msgid "Remove variable from environment"
msgstr "Ta bort variabel från miljö"

#: common/flatpak-context.c:2673
msgid "VAR"
msgstr "VAR"

#: common/flatpak-context.c:2674
msgid "Allow app to own name on the session bus"
msgstr "Tillåt program att äga namn på sessionsbussen"

#: common/flatpak-context.c:2674 common/flatpak-context.c:2675
#: common/flatpak-context.c:2676 common/flatpak-context.c:2677
#: common/flatpak-context.c:2678 common/flatpak-context.c:2679
#: common/flatpak-context.c:2680
msgid "DBUS_NAME"
msgstr "DBUSNAMN"

#: common/flatpak-context.c:2675
msgid "Allow app to talk to name on the session bus"
msgstr "Tillåt program att prata med namn på sessionsbussen"

#: common/flatpak-context.c:2676
msgid "Don't allow app to talk to name on the session bus"
msgstr "Tillåt inte program att prata med namn på sessionsbussen"

#: common/flatpak-context.c:2677
msgid "Allow app to own name on the system bus"
msgstr "Tillåt program att äga namn på systembussen"

#: common/flatpak-context.c:2678
msgid "Allow app to talk to name on the system bus"
msgstr "Tillåt program att prata med namn på systembussen"

#: common/flatpak-context.c:2679
msgid "Don't allow app to talk to name on the system bus"
msgstr "Tillåt inte program att prata med namn på systembussen"

#: common/flatpak-context.c:2680
msgid "Allow app to own name on the a11y bus"
msgstr "Tillåt program att äga namn på a11y-bussen"

#: common/flatpak-context.c:2681
msgid "Add generic policy option"
msgstr "Lägg till alternativ för generell policy"

#: common/flatpak-context.c:2681 common/flatpak-context.c:2682
msgid "SUBSYSTEM.KEY=VALUE"
msgstr "UNDERSYSTEM.NYCKEL=VÄRDE"

#: common/flatpak-context.c:2682
msgid "Remove generic policy option"
msgstr "Ta bort alternativet för generell policy"

#: common/flatpak-context.c:2683
msgid "Add USB device to enumerables"
msgstr "Lägg till USB-enhet till uppräkningsbara"

#: common/flatpak-context.c:2683 common/flatpak-context.c:2684
msgid "VENDOR_ID:PRODUCT_ID"
msgstr "TILLVERKAR-ID:PRODUKT-ID"

#: common/flatpak-context.c:2684
msgid "Add USB device to hidden list"
msgstr "Lägg till USB-enhet till dold lista"

#: common/flatpak-context.c:2685
msgid "A list of USB devices that are enumerable"
msgstr "En lista över USB-enheter som är uppräkningsbara"

#: common/flatpak-context.c:2685
msgid "LIST"
msgstr "LISTA"

#: common/flatpak-context.c:2686
msgid "File containing a list of USB devices to make enumerable"
msgstr "Fil som innehåller en lista över USB-enheter att göra uppräkningsbara"

#: common/flatpak-context.c:2686 common/flatpak-context.c:2687
msgid "FILENAME"
msgstr "FILNAMN"

# https://github.com/flatpak/flatpak/commit/d5909171bbd7f0157066e2b73007d326fa74df88
#: common/flatpak-context.c:2687
msgid "Persist home directory subpath"
msgstr "Gör undersökväg i hemkatalog beständig"

#. This is not needed/used anymore, so hidden, but we accept it for backwards compat
#: common/flatpak-context.c:2689
msgid "Don't require a running session (no cgroups creation)"
msgstr "Kräv inte en körande session (inget cgroups-skapande)"

#: common/flatpak-context.c:3718
#, c-format
msgid "Not replacing \"%s\" with tmpfs: %s"
msgstr "Ersätter inte ”%s” med tmpfs: %s"

#: common/flatpak-context.c:3726
#, c-format
msgid "Not sharing \"%s\" with sandbox: %s"
msgstr "Delar inte ”%s” med sandlåda: %s"

#. Even if the error is one that we would normally silence, like
#. * the path not existing, it seems reasonable to make more of a fuss
#. * about the home directory not existing or otherwise being unusable,
#. * so this is intentionally not using cannot_export()
#: common/flatpak-context.c:3828
#, c-format
msgid "Not allowing home directory access: %s"
msgstr "Tillåter inte åtkomst till hemkatalog: %s"

#: common/flatpak-context.c:4062
#, c-format
msgid "Unable to provide a temporary home directory in the sandbox: %s"
msgstr "Kunde inte tillhandahålla en temporär hemkatalog i sandlådan: %s"

#: common/flatpak-dir.c:442
#, c-format
msgid "Configured collection ID ‘%s’ not in summary file"
msgstr "Konfigurerat samlings-ID ”%s” inte i sammanfattningsfil"

#: common/flatpak-dir.c:587
#, c-format
msgid "Unable to load summary from remote %s: %s"
msgstr "Kunde inte läsa in sammanfattning från fjärrförrådet %s: %s"

# sebras: how to translate in here?
#: common/flatpak-dir.c:764 common/flatpak-dir.c:800 common/flatpak-dir.c:906
#, c-format
msgid "No such ref '%s' in remote %s"
msgstr "Ingen sådan ref ”%s” i fjärrförrådet %s"

#: common/flatpak-dir.c:891 common/flatpak-dir.c:1051 common/flatpak-dir.c:1080
#: common/flatpak-dir.c:1092
#, c-format
msgid "No entry for %s in remote %s summary flatpak cache"
msgstr "Ingen post för %s i flatpak-sammanfattningscache för fjärrförrådet %s"

#: common/flatpak-dir.c:1069
#, c-format
msgid "No summary or Flatpak cache available for remote %s"
msgstr ""
"Ingen sammanfattning eller Flatpak-cache tillgänglig för fjärrförrådet %s"

#: common/flatpak-dir.c:1097
#, c-format
msgid "Missing xa.data in summary for remote %s"
msgstr "Saknar xa.data i sammanfattning för fjärrförrådet %s"

#: common/flatpak-dir.c:1103 common/flatpak-dir.c:1546
#, c-format
msgid "Unsupported summary version %d for remote %s"
msgstr "Sammanfattningsversion %d som inte stöds för fjärrförrådet %s"

#: common/flatpak-dir.c:1200
msgid "Remote OCI index has no registry uri"
msgstr "OCI-index för fjärrförråd har ingen register-uri"

#: common/flatpak-dir.c:1261
#, c-format
msgid "Couldn't find ref %s in remote %s"
msgstr "Det gick inte att hitta ref %s i fjärrförrådet %s"

#: common/flatpak-dir.c:1288 common/flatpak-dir.c:1381
#, fuzzy, c-format
msgid "Commit has no requested ref ‘%s’ in ref binding metadata (found: ‘%s’)"
msgstr "Incheckning har ingen begärd ref ”%s” i refbindningsmetadata"

#: common/flatpak-dir.c:1413
#, c-format
msgid "Configured collection ID ‘%s’ not in binding metadata"
msgstr "Konfigurerat samlings-ID ”%s” inte i bindningsmetadata"

#: common/flatpak-dir.c:1449 common/flatpak-dir.c:5645
#, c-format
msgid "Couldn't find latest checksum for ref %s in remote %s"
msgstr ""
"Det gick inte att hitta senaste kontrollsumma för ref %s i fjärrförrådet %s"

#: common/flatpak-dir.c:1516 common/flatpak-dir.c:1552
#, c-format
msgid "No entry for %s in remote %s summary flatpak sparse cache"
msgstr ""
"Ingen post för %s i gles flatpak-sammanfattningscache för fjärrförrådet %s"

#: common/flatpak-dir.c:2540
#, c-format
msgid "Commit metadata for %s not matching expected metadata"
msgstr "Incheckningsmetadata för %s matchar inte förväntade metadata"

#: common/flatpak-dir.c:2823
msgid "Unable to connect to system bus"
msgstr "Kunde inte ansluta till systembussen"

#: common/flatpak-dir.c:3419
msgid "User installation"
msgstr "Användarinstallation"

#: common/flatpak-dir.c:3426
#, c-format
msgid "System (%s) installation"
msgstr "Systeminstallation (%s)"

#: common/flatpak-dir.c:3472
#, c-format
msgid "No overrides found for %s"
msgstr "Inga åsidosättningar funna för %s"

#: common/flatpak-dir.c:3625
#, c-format
msgid "%s (commit %s) not installed"
msgstr "%s (incheckning %s) inte installerad"

#: common/flatpak-dir.c:4650
#, c-format
msgid "Error parsing system flatpakrepo file for %s: %s"
msgstr "Fel vid tolkning av systemets flatpakrepo-fil för %s: %s"

#: common/flatpak-dir.c:4735
#, c-format
msgid "While opening repository %s: "
msgstr "Medan förråd %s öppnas: "

#: common/flatpak-dir.c:5004
#, c-format
msgid "The config key %s is not set"
msgstr "Konfigurationsnyckeln %s har inte satts"

#: common/flatpak-dir.c:5140
#, c-format
msgid "No current %s pattern matching %s"
msgstr "Inget aktuellt %s-mönster matchar %s"

#: common/flatpak-dir.c:5422
msgid "No appstream commit to deploy"
msgstr "Ingen appstream-incheckning att distribuera"

#: common/flatpak-dir.c:5941 common/flatpak-dir.c:7266
#: common/flatpak-dir.c:10881 common/flatpak-dir.c:11618
msgid "Can't pull from untrusted non-gpg verified remote"
msgstr ""
"Det går inte att hämta från ej betrott fjärrförråd som ej är gpg-verifierat"

#: common/flatpak-dir.c:6376 common/flatpak-dir.c:6591
msgid "Extra data not supported for non-gpg-verified local system installs"
msgstr ""
"Extra data stöds inte för lokala systeminstallationer som ej verifierats med "
"gpg"

#: common/flatpak-dir.c:6415 common/flatpak-dir.c:6782
#, c-format
msgid "Invalid checksum for extra data uri %s"
msgstr "Ogiltig kontrollsumma för extra data-uri %s"

#: common/flatpak-dir.c:6424
#, c-format
msgid "Empty name for extra data uri %s"
msgstr "Tomt namn för extra data-uri %s"

#: common/flatpak-dir.c:6432
#, c-format
msgid "Unsupported extra data uri %s"
msgstr "Extra data-uri %s som ej stöds"

#: common/flatpak-dir.c:6461
#, c-format
msgid "Failed to load local extra-data %s: %s"
msgstr "Misslyckades med att läsa lokala extra data %s: %s"

#: common/flatpak-dir.c:6469
#, c-format
msgid "Wrong size for extra-data %s"
msgstr "Fel storlek för extra data %s"

#: common/flatpak-dir.c:6488
#, c-format
msgid "While downloading %s: "
msgstr "Medan %s hämtas: "

#: common/flatpak-dir.c:6498
#, c-format
msgid "Wrong size for extra data %s"
msgstr "Fel storlek för extra data %s"

#: common/flatpak-dir.c:6507
#, c-format
msgid "Invalid checksum for extra data %s"
msgstr "Ogiltig kontrollsumma för extra data %s"

#: common/flatpak-dir.c:7096 common/flatpak-dir.c:7349
#, c-format
msgid "While pulling %s from remote %s: "
msgstr "Medan %s hämtas från fjärrförrådet %s: "

#: common/flatpak-dir.c:7290 common/flatpak-repo-utils.c:3886
msgid "GPG signatures found, but none are in trusted keyring"
msgstr "GPG-signaturer hittades, men ingen är i den betrodda nyckelringen"

#: common/flatpak-dir.c:7307
#, c-format
msgid "Commit for ‘%s’ has no ref binding"
msgstr "Incheckning för ”%s” har ingen refbindning"

#: common/flatpak-dir.c:7312
#, c-format
msgid "Commit for ‘%s’ is not in expected bound refs: %s"
msgstr "Incheckning för ”%s” är inte bland förväntade bundna referenser: %s"

#: common/flatpak-dir.c:7488
msgid "Only applications can be made current"
msgstr "Endast program kan göras aktuella"

#: common/flatpak-dir.c:8192
msgid "Not enough memory"
msgstr "Inte tillräckligt med minne"

#: common/flatpak-dir.c:8211
msgid "Failed to read from exported file"
msgstr "Misslyckades med att läsa från exporterad fil"

#: common/flatpak-dir.c:8401
msgid "Error reading mimetype xml file"
msgstr "Fel vid läsning av xml-fil för mimetyp"

#: common/flatpak-dir.c:8406
msgid "Invalid mimetype xml file"
msgstr "Ogiltig xml-fil för mimetyp"

#: common/flatpak-dir.c:8492
#, c-format
msgid "D-Bus service file '%s' has wrong name"
msgstr "D-Bus-tjänstfilen ”%s” har fel namn"

#: common/flatpak-dir.c:8647
#, c-format
msgid "Invalid Exec argument %s"
msgstr "Ogiltigt Exec-argument %s"

#: common/flatpak-dir.c:9115
msgid "While getting detached metadata: "
msgstr "Under hämtning av frånkopplade metadata: "

#: common/flatpak-dir.c:9120 common/flatpak-dir.c:9125
#: common/flatpak-dir.c:9129
msgid "Extra data missing in detached metadata"
msgstr "Extra data saknas i frånkopplade metadata"

#: common/flatpak-dir.c:9133
msgid "While creating extradir: "
msgstr "Under tiden extrakatalog skapas: "

#: common/flatpak-dir.c:9154 common/flatpak-dir.c:9187
msgid "Invalid checksum for extra data"
msgstr "Ogiltig kontrollsumma för extra data"

#: common/flatpak-dir.c:9183
msgid "Wrong size for extra data"
msgstr "Fel storlek för extra data"

#: common/flatpak-dir.c:9196
#, c-format
msgid "While writing extra data file '%s': "
msgstr "Under skrivning av extra data-filen ”%s”: "

#: common/flatpak-dir.c:9204
#, c-format
msgid "Extra data %s missing in detached metadata"
msgstr "Extra data %s saknas i frånkopplade metadata"

#: common/flatpak-dir.c:9278
#, c-format
msgid "Unable to get runtime key from metadata"
msgstr "Kunde inte få nyckel för exekveringsmiljö från metadata"

#: common/flatpak-dir.c:9402
#, c-format
msgid "apply_extra script failed, exit status %d"
msgstr "misslyckades med skriptet apply_extra, avslutningsstatus %d"

#. Translators: The placeholder is for an app ref.
#: common/flatpak-dir.c:9591
#, c-format
msgid "Installing %s is not allowed by the policy set by your administrator"
msgstr ""
"Installation av %s tillåts inte av policyn som har satts av din administratör"

#: common/flatpak-dir.c:9690
#, c-format
msgid "While trying to resolve ref %s: "
msgstr "Under upplösningsförsök för ref %s: "

#: common/flatpak-dir.c:9702
#, c-format
msgid "%s is not available"
msgstr "%s är inte tillgängligt"

#: common/flatpak-dir.c:9714 common/flatpak-dir.c:11495
#, c-format
msgid "%s commit %s already installed"
msgstr "%s incheckning %s redan installerad"

#: common/flatpak-dir.c:9721
msgid "Can't create deploy directory"
msgstr "Det går inte att skapa distributionskatalog"

#: common/flatpak-dir.c:9729
#, c-format
msgid "Failed to read commit %s: "
msgstr "Misslyckades läsa incheckning %s: "

#: common/flatpak-dir.c:9750
#, c-format
msgid "While trying to checkout %s into %s: "
msgstr "Under utcheckningsförsök av %s i %s: "

#: common/flatpak-dir.c:9769
msgid "While trying to checkout metadata subpath: "
msgstr "Under utcheckningsförsök av metadataundersökväg: "

#: common/flatpak-dir.c:9801
#, c-format
msgid "While trying to checkout subpath ‘%s’: "
msgstr "Under utcheckningsförsök av undersökvägen ”%s”: "

#: common/flatpak-dir.c:9811
msgid "While trying to remove existing extra dir: "
msgstr "Under försök att ta bort befintlig extra katalog: "

#: common/flatpak-dir.c:9822
msgid "While trying to apply extra data: "
msgstr "Under försök att tillämpa extra data: "

#: common/flatpak-dir.c:9849
#, c-format
msgid "Invalid commit ref %s: "
msgstr "Ogiltig incheckningsref %s: "

#: common/flatpak-dir.c:9857 common/flatpak-dir.c:9869
#, c-format
msgid "Deployed ref %s does not match commit (%s)"
msgstr "Distribuerad ref %s matchar inte incheckning (%s)"

#: common/flatpak-dir.c:9863
#, c-format
msgid "Deployed ref %s branch does not match commit (%s)"
msgstr "Distribuerad referens %s-gren matchar inte incheckning (%s)"

#: common/flatpak-dir.c:10125 common/flatpak-installation.c:1911
#, c-format
msgid "%s branch %s already installed"
msgstr "%s gren %s redan installerad"

#: common/flatpak-dir.c:10985
#, c-format
msgid "Could not unmount revokefs-fuse filesystem at %s: "
msgstr "Det gick inte att avmontera revokefs-fuse-filsystem på %s: "

#: common/flatpak-dir.c:11289
#, c-format
msgid "This version of %s is already installed"
msgstr "Denna version av %s är redan installerad"

#: common/flatpak-dir.c:11302
#, c-format
msgid "Can't change remote during bundle install"
msgstr "Kan inte ändra fjärrförråd under buntinstallering"

#: common/flatpak-dir.c:11571
msgid "Can't update to a specific commit without root permissions"
msgstr ""
"Det går inte att uppdatera till en specifik incheckning utan root-rättigheter"

#: common/flatpak-dir.c:11852
#, c-format
msgid "Can't remove %s, it is needed for: %s"
msgstr "Det går inte att ta bort %s, det behövs för: %s"

#: common/flatpak-dir.c:11912 common/flatpak-installation.c:2067
#, c-format
msgid "%s branch %s is not installed"
msgstr "%s gren %s är inte installerad"

#: common/flatpak-dir.c:12165
#, c-format
msgid "%s commit %s not installed"
msgstr "%s incheckning %s inte installerad"

#: common/flatpak-dir.c:12501
#, c-format
msgid "Pruning repo failed: %s"
msgstr "Rensning av förråd misslyckades: %s"

#: common/flatpak-dir.c:12669 common/flatpak-dir.c:12675
#, c-format
msgid "Failed to load filter '%s'"
msgstr "Misslyckades med att läsa in filtret ”%s”"

#: common/flatpak-dir.c:12681
#, c-format
msgid "Failed to parse filter '%s'"
msgstr "Misslyckades med att tolka filtret ”%s”"

#: common/flatpak-dir.c:12963
msgid "Failed to write summary cache: "
msgstr "Misslyckades med att skriva sammanfattningscache: "

#: common/flatpak-dir.c:12982
#, c-format
msgid "No oci summary cached for remote '%s'"
msgstr "Ingen oci-sammanfattning cachad för fjärrförrådet ”%s”"

#: common/flatpak-dir.c:13207
#, c-format
msgid "No cached summary for remote '%s'"
msgstr "Ingen cachad sammanfattning för fjärrförrådet ”%s”"

#: common/flatpak-dir.c:13248
#, c-format
msgid "Invalid checksum for indexed summary %s read from %s"
msgstr "Ogiltig kontrollsumma för indexerad sammanfattning %s lästes från %s"

#: common/flatpak-dir.c:13321
#, c-format
msgid ""
"Remote listing for %s not available; server has no summary file. Check the "
"URL passed to remote-add was valid."
msgstr ""
"Fjärrlista för %s inte tillgänglig; servern har ingen sammanfattningsfil. "
"Kontrollera att URL:en som skickades till remote-add var giltig."

#: common/flatpak-dir.c:13698
#, c-format
msgid "Invalid checksum for indexed summary %s for remote '%s'"
msgstr ""
"Ogiltig kontrollsumma för indexerad sammanfattning %s för fjärrförrådet ”%s”"

#: common/flatpak-dir.c:14388
#, c-format
msgid "Multiple branches available for %s, you must specify one of: "
msgstr "Flera grenar tillgängliga för %s, du måste ange en av: "

#: common/flatpak-dir.c:14454
#, c-format
msgid "Nothing matches %s"
msgstr "Ingenting matchar %s"

# sebras: how to translate in here?
#: common/flatpak-dir.c:14562
#, c-format
msgid "Can't find ref %s%s%s%s%s"
msgstr "Det går inte att hitta ref %s%s%s%s%s"

#: common/flatpak-dir.c:14605
#, c-format
msgid "Error searching remote %s: %s"
msgstr "Fel vid sökning av fjärrförråd %s: %s"

#: common/flatpak-dir.c:14702
#, c-format
msgid "Error searching local repository: %s"
msgstr "Fel vid sökning i lokalt förråd: %s"

#: common/flatpak-dir.c:14839
#, c-format
msgid "%s/%s/%s not installed"
msgstr "%s/%s/%s inte installerad"

#: common/flatpak-dir.c:15042
#, c-format
msgid "Could not find installation %s"
msgstr "Det gick inte att hitta installationen %s"

#: common/flatpak-dir.c:15612
#, c-format
msgid "Invalid file format, no %s group"
msgstr "Ogiltigt filformat, ingen %s-grupp"

#: common/flatpak-dir.c:15617 common/flatpak-repo-utils.c:2836
#, c-format
msgid "Invalid version %s, only 1 supported"
msgstr "Ogiltig version %s, endast 1 stöds"

#: common/flatpak-dir.c:15622 common/flatpak-dir.c:15627
#, c-format
msgid "Invalid file format, no %s specified"
msgstr "Ogiltigt filformat, ingen %s angiven"

#. Check some minimal size so we don't get crap
#: common/flatpak-dir.c:15647
msgid "Invalid file format, gpg key invalid"
msgstr "Ogiltigt filformat, gpg-nyckel ogiltig"

#: common/flatpak-dir.c:15675 common/flatpak-repo-utils.c:2917
msgid "Collection ID requires GPG key to be provided"
msgstr "Samlings-ID kräver att GPG-nyckel tillhandahålls"

#: common/flatpak-dir.c:15718
#, c-format
msgid "Runtime %s, branch %s is already installed"
msgstr "Exekveringsmiljö %s, gren %s är redan installerad"

#: common/flatpak-dir.c:15719
#, c-format
msgid "App %s, branch %s is already installed"
msgstr "Program %s, gren %s är redan installerad"

#: common/flatpak-dir.c:15953
#, c-format
msgid "Can't remove remote '%s' with installed ref %s (at least)"
msgstr ""
"Det går inte att ta bort fjärrförrådet ”%s” med installerad ref %s "
"(åtminstone)"

#: common/flatpak-dir.c:16058
#, c-format
msgid "Invalid character '/' in remote name: %s"
msgstr "Ogiltigt tecken ”/” i namn på fjärrförråd: %s"

#: common/flatpak-dir.c:16064
#, c-format
msgid "No configuration for remote %s specified"
msgstr "Ingen konfiguration angavs för fjärrförrådet %s"

#: common/flatpak-dir.c:17597
#, c-format
msgid "Skipping deletion of mirror ref (%s, %s)…\n"
msgstr "Hoppar över borttagning av spegelref (%s, %s)…\n"

#: common/flatpak-exports.c:931
#, c-format
msgid "An absolute path is required"
msgstr "En absolut sökväg krävs"

#: common/flatpak-exports.c:948
#, c-format
msgid "Unable to open path \"%s\": %s"
msgstr "Kunde inte öppna sökvägen ”%s”: %s"

#: common/flatpak-exports.c:955
#, c-format
msgid "Unable to get file type of \"%s\": %s"
msgstr "Kunde inte erhålla filtypen för ”%s”: %s"

#: common/flatpak-exports.c:964
#, c-format
msgid "File \"%s\" has unsupported type 0o%o"
msgstr "Filen ”%s” har typen 0o%o som inte stöds"

#: common/flatpak-exports.c:970
#, c-format
msgid "Unable to get filesystem information for \"%s\": %s"
msgstr "Kunde inte hämta filsystemsinformation för ”%s”: %s"

#: common/flatpak-exports.c:980
#, c-format
msgid "Ignoring blocking autofs path \"%s\""
msgstr "Ignorerar blockerande autofs-sökväg ”%s”"

#: common/flatpak-exports.c:996 common/flatpak-exports.c:1009
#: common/flatpak-exports.c:1022
#, c-format
msgid "Path \"%s\" is reserved by Flatpak"
msgstr "Sökvägen ”%s” är reserverad av Flatpak"

#: common/flatpak-exports.c:1076
#, c-format
msgid "Unable to resolve symbolic link \"%s\": %s"
msgstr "Kunde inte slå upp symbolisk länk ”%s”: %s"

#: common/flatpak-glib-backports.c:69
msgid "Empty string is not a number"
msgstr "Tom sträng är inte ett tal"

#: common/flatpak-glib-backports.c:95
#, c-format
msgid "“%s” is not an unsigned number"
msgstr "”%s” är inte ett teckenlöst tal"

#: common/flatpak-glib-backports.c:105
#, c-format
msgid "Number “%s” is out of bounds [%s, %s]"
msgstr "Talet ”%s” är utanför gränserna [%s, %s]"

#: common/flatpak-image-source.c:83
msgid "Only sha256 image checksums are supported"
msgstr "Endast sha256-avbildskontrollsummor stöds"

#: common/flatpak-image-source.c:100 common/flatpak-image-source.c:108
msgid "Image is not a manifest"
msgstr "Avbilden är inte ett manifest"

#: common/flatpak-image-source.c:123
msgid "No org.flatpak.ref found in image"
msgstr "Ingen org.flatpak.ref hittades i avbild"

#: common/flatpak-image-source.c:148
#, c-format
msgid "Ref '%s' not found in registry"
msgstr "Ref ”%s” hittades inte i registret"

#: common/flatpak-image-source.c:157
msgid "Multiple images in registry, specify a ref with --ref"
msgstr "Flera avbilder i registret, ange en ref med --ref"

#: common/flatpak-installation.c:834
#, c-format
msgid "Ref %s not installed"
msgstr "Ref %s inte installerad"

#: common/flatpak-installation.c:875
#, c-format
msgid "App %s not installed"
msgstr "Program %s inte installerat"

#: common/flatpak-installation.c:1395
#, c-format
msgid "Remote '%s' already exists"
msgstr "Fjärrförrådet ”%s” existerar redan"

#: common/flatpak-installation.c:1946
#, c-format
msgid "As requested, %s was only pulled, but not installed"
msgstr "Som begärt hämtades bara %s, men installerades inte"

#: common/flatpak-instance.c:533 common/flatpak-instance.c:687
#: common/flatpak-instance.c:728
#, c-format
msgid "Unable to create directory %s"
msgstr "Kunde inte skapa katalogen %s"

#: common/flatpak-instance.c:554
#, c-format
msgid "Unable to lock %s"
msgstr "Kunde inte låsa %s"

#: common/flatpak-instance.c:627
#, c-format
msgid "Unable to create temporary directory in %s"
msgstr "Kunde inte skapa temporär katalog i %s"

#: common/flatpak-instance.c:639
#, c-format
msgid "Unable to create file %s"
msgstr "Kunde inte skapa filen %s"

#: common/flatpak-instance.c:646
#, c-format
msgid "Unable to update symbolic link %s/%s"
msgstr "Kunde inte uppdatera symbolisk länk %s/%s"

#: common/flatpak-oci-registry.c:1197
msgid "Only Bearer authentication supported"
msgstr "Endast Bearer-autentisering stöds"

#: common/flatpak-oci-registry.c:1206
msgid "Only realm in authentication request"
msgstr "Endast rike i autentiseringsbegäran"

#: common/flatpak-oci-registry.c:1213
msgid "Invalid realm in authentication request"
msgstr "Ogiltigt rike i autentiseringsbegäran"

#: common/flatpak-oci-registry.c:1283
#, c-format
msgid "Authorization failed: %s"
msgstr "Auktorisering misslyckades: %s"

#: common/flatpak-oci-registry.c:1285
msgid "Authorization failed"
msgstr "Auktorisering misslyckades"

#: common/flatpak-oci-registry.c:1289
#, c-format
msgid "Unexpected response status %d when requesting token: %s"
msgstr "Oväntad svarsstatus %d då token begärdes: %s"

#: common/flatpak-oci-registry.c:1300
msgid "Invalid authentication request response"
msgstr "Ogiltigt svar på autentiseringsbegäran"

#: common/flatpak-oci-registry.c:1731
#, c-format
msgid "Flatpak was compiled without zstd support"
msgstr "Flatpak kompilerades utan stöd för zstd"

#: common/flatpak-oci-registry.c:1923 common/flatpak-oci-registry.c:1975
#: common/flatpak-oci-registry.c:2004 common/flatpak-oci-registry.c:2059
#: common/flatpak-oci-registry.c:2115 common/flatpak-oci-registry.c:2193
msgid "Invalid delta file format"
msgstr "Ogiltigt deltafilformat"

#: common/flatpak-oci-registry.c:3198 common/flatpak-oci-registry.c:3382
msgid "Invalid OCI image config"
msgstr "Ogiltig OCI-avbildskonfiguration"

#: common/flatpak-oci-registry.c:3260 common/flatpak-oci-registry.c:3531
#, c-format
msgid "Wrong layer checksum, expected %s, was %s"
msgstr "Fel kontrollsumma för lager, förväntade %s, var %s"

#: common/flatpak-oci-registry.c:3359
#, c-format
msgid "No ref specified for OCI image %s"
msgstr "Ingen ref angiven för OCI-avbild %s"

#: common/flatpak-oci-registry.c:3369
#, c-format
msgid "Wrong ref (%s) specified for OCI image %s, expected %s"
msgstr "Fel ref (%s) angiven för OCI-avbild %s, förväntade %s"

#: common/flatpak-progress.c:236
#, c-format
msgid "Downloading metadata: %u/(estimating) %s"
msgstr "Hämtar metadata: %u/(beräknad) %s"

#: common/flatpak-progress.c:260
#, c-format
msgid "Downloading: %s/%s"
msgstr "Hämtar: %s/%s"

#: common/flatpak-progress.c:280
#, c-format
msgid "Downloading extra data: %s/%s"
msgstr "Hämtar extra data: %s/%s"

#: common/flatpak-progress.c:285
#, c-format
msgid "Downloading files: %d/%d %s"
msgstr "Hämtar filer: %d/%d %s"

#: common/flatpak-ref-utils.c:122
msgid "Name can't be empty"
msgstr "Namn kan inte vara tomt"

#: common/flatpak-ref-utils.c:129
msgid "Name can't be longer than 255 characters"
msgstr "Namn kan inte vara längre än 255 tecken"

#: common/flatpak-ref-utils.c:142
msgid "Name can't start with a period"
msgstr "Namn kan inte börja med en punkt"

#: common/flatpak-ref-utils.c:148
#, c-format
msgid "Name can't start with %c"
msgstr "Namn kan inte börja med %c"

#: common/flatpak-ref-utils.c:164
msgid "Name can't end with a period"
msgstr "Namn kan inte sluta med en punkt"

#: common/flatpak-ref-utils.c:171 common/flatpak-ref-utils.c:183
msgid "Only last name segment can contain -"
msgstr "Endast det sista namnsegmentet kan innehålla -"

#: common/flatpak-ref-utils.c:174
#, c-format
msgid "Name segment can't start with %c"
msgstr "Namnsegment kan inte börja med %c"

#: common/flatpak-ref-utils.c:186
#, c-format
msgid "Name can't contain %c"
msgstr "Namn kan inte innehålla %c"

#: common/flatpak-ref-utils.c:195
msgid "Names must contain at least 2 periods"
msgstr "Namn måste innehålla minst 2 punkter"

#: common/flatpak-ref-utils.c:312
msgid "Arch can't be empty"
msgstr "Ark kan inte vara tom"

#: common/flatpak-ref-utils.c:323
#, c-format
msgid "Arch can't contain %c"
msgstr "Ark kan inte innehålla %c"

#: common/flatpak-ref-utils.c:385
msgid "Branch can't be empty"
msgstr "Gren kan inte vara tom"

#: common/flatpak-ref-utils.c:395
#, c-format
msgid "Branch can't start with %c"
msgstr "Gren kan inte börja med %c"

#: common/flatpak-ref-utils.c:405
#, c-format
msgid "Branch can't contain %c"
msgstr "Gren kan inte innehålla %c"

#: common/flatpak-ref-utils.c:615 common/flatpak-ref-utils.c:865
msgid "Ref too long"
msgstr "Ref för lång"

#: common/flatpak-ref-utils.c:627
msgid "Invalid remote name"
msgstr "Ogiltigt namn på fjärrförråd"

#: common/flatpak-ref-utils.c:641
#, c-format
msgid "%s is not application or runtime"
msgstr "%s är inte ett program eller en exekveringsmiljö"

#: common/flatpak-ref-utils.c:650 common/flatpak-ref-utils.c:667
#: common/flatpak-ref-utils.c:683
#, c-format
msgid "Wrong number of components in %s"
msgstr "Fel antal komponenter i %s"

#: common/flatpak-ref-utils.c:656
#, c-format
msgid "Invalid name %.*s: %s"
msgstr "Ogiltigt namn %.*s: %s"

#: common/flatpak-ref-utils.c:673
#, c-format
msgid "Invalid arch: %.*s: %s"
msgstr "Ogiltig ark: %.*s: %s"

#: common/flatpak-ref-utils.c:816
#, c-format
msgid "Invalid name %s: %s"
msgstr "Ogiltigt namn %s: %s"

#: common/flatpak-ref-utils.c:834
#, c-format
msgid "Invalid arch: %s: %s"
msgstr "Ogiltig ark: %s: %s"

#: common/flatpak-ref-utils.c:853
#, c-format
msgid "Invalid branch: %s: %s"
msgstr "Ogiltig gren: %s: %s"

#: common/flatpak-ref-utils.c:962 common/flatpak-ref-utils.c:970
#: common/flatpak-ref-utils.c:978
#, c-format
msgid "Wrong number of components in partial ref %s"
msgstr "Fel antal komponenter i partiell ref %s"

#: common/flatpak-ref-utils.c:1298
msgid " development platform"
msgstr " utvecklingsplattform"

#: common/flatpak-ref-utils.c:1300
msgid " platform"
msgstr " plattform"

#: common/flatpak-ref-utils.c:1302
msgid " application base"
msgstr " programbas"

#: common/flatpak-ref-utils.c:1305
msgid " debug symbols"
msgstr " felsökningssymboler"

#: common/flatpak-ref-utils.c:1307
msgid " sourcecode"
msgstr " källkod"

#: common/flatpak-ref-utils.c:1309
msgid " translations"
msgstr " översättningar"

#: common/flatpak-ref-utils.c:1311
msgid " docs"
msgstr " dokumentation"

#: common/flatpak-ref-utils.c:1578
#, c-format
msgid "Invalid id %s: %s"
msgstr "Ogiltigt id %s: %s"

#: common/flatpak-remote.c:1216
#, c-format
msgid "Bad remote name: %s"
msgstr "Ogiltigt namn på fjärrförråd: %s"

#: common/flatpak-remote.c:1220
msgid "No URL specified"
msgstr "Ingen URL angiven"

#: common/flatpak-remote.c:1266
msgid "GPG verification must be enabled when a collection ID is set"
msgstr "GPG-verifiering måste vara aktiverat då ett samlings-ID har satts"

#: common/flatpak-repo-utils.c:344
#, c-format
msgid "No extra data sources"
msgstr "Inga extra data-källor"

#: common/flatpak-repo-utils.c:2817
#, c-format
msgid "Invalid %s: Missing group ‘%s’"
msgstr "Ogiltig %s: Saknar grupp ”%s”"

#: common/flatpak-repo-utils.c:2826
#, c-format
msgid "Invalid %s: Missing key ‘%s’"
msgstr "Ogiltig %s: Saknar nyckel ”%s”"

#: common/flatpak-repo-utils.c:2876
msgid "Invalid gpg key"
msgstr "Ogiltig gpg-nyckel"

#: common/flatpak-repo-utils.c:3217
#, c-format
msgid "Error copying 64x64 icon for component %s: %s\n"
msgstr "Fel vid kopiering av 64x64-ikon för komponent %s: %s\n"

#: common/flatpak-repo-utils.c:3223
#, c-format
msgid "Error copying 128x128 icon for component %s: %s\n"
msgstr "Fel vid kopiering av 128x128-ikon för komponent %s: %s\n"

#: common/flatpak-repo-utils.c:3362
#, c-format
msgid "%s is end-of-life, ignoring for appstream"
msgstr "%s har nått slutet på sin livstid, ignorerar för appstream"

#: common/flatpak-repo-utils.c:3397
#, c-format
msgid "No appstream data for %s: %s\n"
msgstr "Inga appstream-data för %s: %s\n"

#: common/flatpak-repo-utils.c:3744
msgid "Invalid bundle, no ref in metadata"
msgstr "Ogiltig bunt, ingen ref i metadata"

#: common/flatpak-repo-utils.c:3846
#, c-format
msgid "Collection ‘%s’ of bundle doesn’t match collection ‘%s’ of remote"
msgstr "Samlingen ”%s” för bunt matchar inte samlingen ”%s” för fjärrförråd"

#: common/flatpak-repo-utils.c:3923
msgid "Metadata in header and app are inconsistent"
msgstr "Metadata i huvud och program är inkonsekventa"

#: common/flatpak-run.c:951
msgid "No systemd user session available, cgroups not available"
msgstr "Ingen systemd-användarsession tillgänglig, cgroups inte tillgängligt"

#: common/flatpak-run.c:1496
msgid "Unable to allocate instance id"
msgstr "Kunde inte allokera instans-ID"

#: common/flatpak-run.c:1632 common/flatpak-run.c:1641
#, c-format
msgid "Failed to open flatpak-info file: %s"
msgstr "Misslyckades med att öppna flatpak-info-fil: %s"

#: common/flatpak-run.c:1668
#, c-format
msgid "Failed to open bwrapinfo.json file: %s"
msgstr "Misslyckades med att öppna bwrapinfo.json-fil: %s"

#: common/flatpak-run.c:1689
#, c-format
msgid "Failed to write to instance id fd: %s"
msgstr "Misslyckades med att skriva till filhandtag för instans-ID: %s"

#: common/flatpak-run.c:2096
msgid "Initialize seccomp failed"
msgstr "Initiering av seccomp misslyckades"

#: common/flatpak-run.c:2135
#, c-format
msgid "Failed to add architecture to seccomp filter: %s"
msgstr "Misslyckades med att lägga till arkitektur till seccomp-filter: %s"

#: common/flatpak-run.c:2143
#, c-format
msgid "Failed to add multiarch architecture to seccomp filter: %s"
msgstr ""
"Misslyckades med att lägga till multiarch-arkitektur till seccomp-filter: %s"

#: common/flatpak-run.c:2175 common/flatpak-run.c:2192
#: common/flatpak-run.c:2214
#, c-format
msgid "Failed to block syscall %d: %s"
msgstr "Misslyckades med att blockera systemanrop %d: %s"

#: common/flatpak-run.c:2247
#, c-format
msgid "Failed to export bpf: %s"
msgstr "Misslyckades med att exportera bpf: %s"

#: common/flatpak-run.c:2587
#, c-format
msgid "Failed to open ‘%s’"
msgstr "Misslyckades med att öppna ”%s”"

#: common/flatpak-run.c:2597
#, c-format
msgid ""
"Directory forwarding needs version 4 of the document portal (have version %d)"
msgstr ""
"Katalogvidarebefordran behöver version 4 av dokumentportalen (har version %d)"

#: common/flatpak-run.c:2915
#, c-format
msgid "ldconfig failed, exit status %d"
msgstr "misslyckades med ldconfig, avslutningsstatus %d"

#: common/flatpak-run.c:2922
msgid "Can't open generated ld.so.cache"
msgstr "Det går inte att öppna genererad ld.so.cache"

#. Translators: The placeholder is for an app ref.
#: common/flatpak-run.c:3045
#, c-format
msgid "Running %s is not allowed by the policy set by your administrator"
msgstr ""
"Körning av %s tillåts inte av policyn som har satts av din administratör"

#: common/flatpak-run.c:3202
msgid ""
"\"flatpak run\" is not intended to be run as `sudo flatpak run`. Use `sudo "
"-i` or `su -l` instead and invoke \"flatpak run\" from inside the new shell."
msgstr ""
"”flatpak run” är inte avsett att köras som ”sudo flatpak run”, använd ”sudo "
"-i” eller ”su -l” istället och anropa ”flatpak run” inifrån det nya skalet."

#: common/flatpak-run.c:3413
#, c-format
msgid "Failed to migrate from %s: %s"
msgstr "Misslyckades att migrera från %s: %s"

#: common/flatpak-run.c:3434
#, c-format
msgid "Failed to migrate old app data directory %s to new name %s: %s"
msgstr ""
"Misslyckades med att migrera gammal programdatakatalog %s till nytt namn %s: "
"%s"

#: common/flatpak-run.c:3443
#, c-format
msgid "Failed to create symlink while migrating %s: %s"
msgstr "Misslyckades med att skapa symbolisk länk vid migrering av %s: %s"

#: common/flatpak-run-dbus.c:46
msgid "Failed to open app info file"
msgstr "Misslyckades med att öppna programinfo-fil"

#: common/flatpak-run-dbus.c:149
msgid "Unable to create sync pipe"
msgstr "Kunde inte skapa sync-rör"

#: common/flatpak-run-dbus.c:185
msgid "Failed to sync with dbus proxy"
msgstr "Misslyckades med att synkronisera med dbus-proxy"

#: common/flatpak-transaction.c:2275
#, c-format
msgid "Warning: Problem looking for related refs: %s"
msgstr "Varning: Problem vid sökning efter relaterade referenser: %s"

#: common/flatpak-transaction.c:2493
#, c-format
msgid "The application %s requires the runtime %s which was not found"
msgstr "Programmet %s kräver exekveringsmiljön %s som inte hittades"

#: common/flatpak-transaction.c:2509
#, c-format
msgid "The application %s requires the runtime %s which is not installed"
msgstr "Programmet %s kräver exekveringsmiljön %s som inte är installerad"

#: common/flatpak-transaction.c:2641
#, c-format
msgid "Can't uninstall %s which is needed by %s"
msgstr "Det går inte att avinstallera %s som behövs av %s"

#: common/flatpak-transaction.c:2740
#, c-format
msgid "Remote %s disabled, ignoring %s update"
msgstr "Fjärrförråd %s inaktiverat, ignorerar uppdatering för %s"

#: common/flatpak-transaction.c:2773
#, c-format
msgid "%s is already installed"
msgstr "%s är redan installerad"

#: common/flatpak-transaction.c:2776
#, c-format
msgid "%s is already installed from remote %s"
msgstr "%s är redan installerad från fjärrförrådet %s"

#: common/flatpak-transaction.c:3120
#, c-format
msgid "Invalid .flatpakref: %s"
msgstr "Ogiltig .flatpakref: %s"

#: common/flatpak-transaction.c:3161
msgid "Warning: Could not mark already installed apps as preinstalled"
msgstr ""
"Varning: Kunde inte markera redan installerade program som förinstallerade"

#: common/flatpak-transaction.c:3382
#, c-format
msgid "Error updating remote metadata for '%s': %s"
msgstr "Fel vid uppdatering av fjärrmetadata för ”%s”: %s"

#: common/flatpak-transaction.c:3885
#, c-format
msgid ""
"Warning: Treating remote fetch error as non-fatal since %s is already "
"installed: %s"
msgstr ""
"Varning: Behandlar fjärrhämtningsfel som icke ödesdigert då %s redan är "
"installerad: %s"

#: common/flatpak-transaction.c:4209
#, c-format
msgid "No authenticator installed for remote '%s'"
msgstr "Ingen autentiserare installerad för fjärrförrådet ”%s”"

#: common/flatpak-transaction.c:4313 common/flatpak-transaction.c:4320
#, c-format
msgid "Failed to get tokens for ref: %s"
msgstr "Misslyckades med att erhålla token för ref: %s"

#: common/flatpak-transaction.c:4315 common/flatpak-transaction.c:4322
msgid "Failed to get tokens for ref"
msgstr "Misslyckades med att erhålla token för ref"

#: common/flatpak-transaction.c:4580
#, c-format
msgid "Ref %s from %s matches more than one transaction operation"
msgstr "Ref %s från %s matchar mer än en transaktionsåtgärd"

#: common/flatpak-transaction.c:4581 common/flatpak-transaction.c:4591
msgid "any remote"
msgstr "alla fjärrförråd"

#: common/flatpak-transaction.c:4590
#, c-format
msgid "No transaction operation found for ref %s from %s"
msgstr "Ingen transaktionsåtgärd hittades för ref %s från %s"

#: common/flatpak-transaction.c:4713
#, c-format
msgid "Flatpakrepo URL %s not file, HTTP or HTTPS"
msgstr "Flatpakrepo-URL %s är inte file, HTTP eller HTTPS"

#: common/flatpak-transaction.c:4719
#, c-format
msgid "Can't load dependent file %s: "
msgstr "Det går inte att läsa in beroende fil %s: "

#: common/flatpak-transaction.c:4727
#, c-format
msgid "Invalid .flatpakrepo: %s"
msgstr "Ogiltig .flatpakrepo: %s"

#: common/flatpak-transaction.c:5454
msgid "Transaction already executed"
msgstr "Transaktion redan utförd"

#: common/flatpak-transaction.c:5469
msgid ""
"Refusing to operate on a user installation as root! This can lead to "
"incorrect file ownership and permission errors."
msgstr ""
"Vägrar att operera på en användarinstallation som root! Detta kan leda till "
"felaktigt filägarskap och rättighetsfel."

#: common/flatpak-transaction.c:5567 common/flatpak-transaction.c:5580
msgid "Aborted by user"
msgstr "Avbröts av användare"

#: common/flatpak-transaction.c:5605
#, c-format
msgid "Skipping %s due to previous error"
msgstr "Hoppar över %s på grund av tidigare fel"

#: common/flatpak-transaction.c:5659
#, c-format
msgid "Aborted due to failure (%s)"
msgstr "Avbröts på grund av fel (%s)"

#: common/flatpak-uri.c:118
#, no-c-format
msgid "Invalid %-encoding in URI"
msgstr "Ogiltig %-kodning i URI"

#: common/flatpak-uri.c:135
msgid "Illegal character in URI"
msgstr "Otillåtet tecken i URI"

#: common/flatpak-uri.c:169
msgid "Non-UTF-8 characters in URI"
msgstr "Tecken som inte är UTF-8 i URI"

#: common/flatpak-uri.c:275
#, c-format
msgid "Invalid IPv6 address ‘%.*s’ in URI"
msgstr "Ogiltig IPv6-adress ”%.*s” i URI"

#: common/flatpak-uri.c:330
#, c-format
msgid "Illegal encoded IP address ‘%.*s’ in URI"
msgstr "Otillåtet kodad IP-adress ”%.*s” i URI"

#: common/flatpak-uri.c:342
#, c-format
msgid "Illegal internationalized hostname ‘%.*s’ in URI"
msgstr "Otillåtet internationaliserat värdnamn ”%.*s” i URI"

#: common/flatpak-uri.c:374 common/flatpak-uri.c:386
#, c-format
msgid "Could not parse port ‘%.*s’ in URI"
msgstr "Kunde inte tolka port ”%.*s” i URI"

#: common/flatpak-uri.c:393
#, c-format
msgid "Port ‘%.*s’ in URI is out of range"
msgstr "Port ”%.*s” i URI är utanför intervallet"

#: common/flatpak-uri.c:910
msgid "URI is not absolute, and no base URI was provided"
msgstr "URI är inte absolut, och ingen bas-URI angavs"

#: common/flatpak-usb.c:83
#, c-format
msgid "USB device query 'all' must not have data"
msgstr "USB-enhetsfrågan ”all” får inte ha data"

#: common/flatpak-usb.c:102
#, c-format
msgid "USB query rule 'cls' must be in the form CLASS:SUBCLASS or CLASS:*"
msgstr ""
"USB-frågeregeln ”cls” måste vara på formen KLASS:UNDERKLASS eller KLASS:*"

#: common/flatpak-usb.c:111
#, c-format
msgid "Invalid USB class"
msgstr "Ogiltig USB-klass"

#: common/flatpak-usb.c:125
#, c-format
msgid "Invalid USB subclass"
msgstr "Ogiltig USB-underklass"

#: common/flatpak-usb.c:141 common/flatpak-usb.c:148
#, c-format
msgid "USB query rule 'dev' must have a valid 4-digit hexadecimal product id"
msgstr ""
"USB-frågeregeln ”dev” måste ha ett giltigt fyrsiffrigt hexadecimalt produkt-"
"ID"

#: common/flatpak-usb.c:164 common/flatpak-usb.c:171
#, c-format
msgid "USB query rule 'vnd' must have a valid 4-digit hexadecimal vendor id"
msgstr ""
"USB-frågeregeln ”vnd” måste ha ett giltigt fyrsiffrigt hexadecimalt "
"tillverkar-ID"

#: common/flatpak-usb.c:205
#, c-format
msgid "USB device queries must be in the form TYPE:DATA"
msgstr "USB-enhetsfrågor måste vara på formen TYP:DATA"

#: common/flatpak-usb.c:225
#, c-format
msgid "Unknown USB query rule %s"
msgstr "Okänd USB-frågeregel %s"

#: common/flatpak-usb.c:248
#, c-format
msgid "Empty USB query"
msgstr "Tom USB-fråga"

#: common/flatpak-usb.c:274
#, c-format
msgid "Multiple USB query rules of the same type is not supported"
msgstr "Flera USB-frågeregler av samma typ stöds inte"

#: common/flatpak-usb.c:283
#, c-format
msgid "'all' must not contain extra query rules"
msgstr "”all” får inte innehålla extra frågeregler"

#: common/flatpak-usb.c:291
#, c-format
msgid "USB queries with 'dev' must also specify vendors"
msgstr "USB-frågor med ”dev” måste också ange tillverkare"

#: common/flatpak-utils.c:712
msgid "Glob can't match apps"
msgstr "Matchningen kan inte matcha program"

#: common/flatpak-utils.c:737
msgid "Empty glob"
msgstr "Tom matchning"

#: common/flatpak-utils.c:756
msgid "Too many segments in glob"
msgstr "För många segment i matchning"

#: common/flatpak-utils.c:777
#, c-format
msgid "Invalid glob character '%c'"
msgstr "Ogiltigt matchningstecken ”%c”"

#: common/flatpak-utils.c:831
#, c-format
msgid "Missing glob on line %d"
msgstr "Saknar matchning på rad %d"

#: common/flatpak-utils.c:835
#, c-format
msgid "Trailing text on line %d"
msgstr "Eftersläpande text på rad %d"

#: common/flatpak-utils.c:839
#, c-format
msgid "on line %d"
msgstr "på rad %d"

#: common/flatpak-utils.c:861
#, c-format
msgid "Unexpected word '%s' on line %d"
msgstr "Oväntat ord ”%s” på rad %d"

#: common/flatpak-utils.c:2118
#, c-format
msgid "Invalid require-flatpak argument %s"
msgstr "Ogiltigt argument %s för require-flatpak"

#: common/flatpak-utils.c:2128 common/flatpak-utils.c:2147
#, c-format
msgid "%s needs a later flatpak version (%s)"
msgstr "%s behöver en senare flatpak-version (%s)"

#: oci-authenticator/flatpak-oci-authenticator.c:291
msgid "Not a oci remote, missing summary.xa.oci-repository"
msgstr "Inte ett oci-fjärrförråd, saknar summary.xa.oci-repository"

#: oci-authenticator/flatpak-oci-authenticator.c:477
msgid "Not a OCI remote"
msgstr "Inte ett OCI-fjärrförråd"

#: oci-authenticator/flatpak-oci-authenticator.c:488
msgid "Invalid token"
msgstr "Ogiltig token"

#: portal/flatpak-portal.c:2292
#, c-format
msgid "No portal support found"
msgstr "Inget portalstöd hittades"

#: portal/flatpak-portal.c:2298
msgid "Deny"
msgstr "Neka"

#: portal/flatpak-portal.c:2300
msgid "Update"
msgstr "Uppdatera"

#: portal/flatpak-portal.c:2305
#, c-format
msgid "Update %s?"
msgstr "Uppdatera %s?"

#: portal/flatpak-portal.c:2317
msgid "The application wants to update itself."
msgstr "Programmet vill uppdatera sig själv."

#: portal/flatpak-portal.c:2318
msgid "Update access can be changed any time from the privacy settings."
msgstr ""
"Uppdateringsåtkomst kan ändras när som helst från sekretessinställningarna."

#: portal/flatpak-portal.c:2343
#, c-format
msgid "Application update not allowed"
msgstr "Programuppdatering inte tillåten"

#: portal/flatpak-portal.c:2501
#, c-format
msgid "Self update not supported, new version requires new permissions"
msgstr "Självuppdatering stöds inte, nya versionen kräver nya rättigheter"

#: portal/flatpak-portal.c:2684 portal/flatpak-portal.c:2702
#, c-format
msgid "Update ended unexpectedly"
msgstr "Uppdateringen avslutades oväntat"

#. SECURITY:
#. - Normal users need admin authentication to install software
#. system-wide.
#. - Note that we install polkit rules that allow local users
#. in the wheel group to install without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:23
msgid "Install signed application"
msgstr "Installera signerat program"

#: system-helper/org.freedesktop.Flatpak.policy.in:24
#: system-helper/org.freedesktop.Flatpak.policy.in:42
msgid "Authentication is required to install software"
msgstr "Autentisering krävs för att installera program"

#. SECURITY:
#. - Normal users need admin authentication to install software
#. system-wide.
#. - Note that we install polkit rules that allow local users
#. in the wheel group to install without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:41
msgid "Install signed runtime"
msgstr "Installera signerad exekveringsmiljö"

#. SECURITY:
#. - Normal users do not require admin authentication to update an
#. app as the commit will be signed, and the action is required
#. to update the system when unattended.
#. - Changing this to anything other than 'yes' will break unattended
#. updates.
#: system-helper/org.freedesktop.Flatpak.policy.in:60
msgid "Update signed application"
msgstr "Uppdatera signerat program"

#: system-helper/org.freedesktop.Flatpak.policy.in:61
#: system-helper/org.freedesktop.Flatpak.policy.in:80
msgid "Authentication is required to update software"
msgstr "Autentisering krävs för att uppdatera program"

#. SECURITY:
#. - Normal users do not require admin authentication to update a
#. runtime as the commit will be signed, and the action is required
#. to update the system when unattended.
#. - Changing this to anything other than 'yes' will break unattended
#. updates.
#: system-helper/org.freedesktop.Flatpak.policy.in:79
msgid "Update signed runtime"
msgstr "Uppdatera signerad exekveringsmiljö"

#. SECURITY:
#. - Normal users do not need authentication to update metadata
#. from signed repositories.
#: system-helper/org.freedesktop.Flatpak.policy.in:94
msgid "Update remote metadata"
msgstr "Uppdatera fjärrförrådmetadata"

#: system-helper/org.freedesktop.Flatpak.policy.in:95
msgid "Authentication is required to update remote info"
msgstr "Autentisering krävs för att uppdatera fjärrförrådsinfo"

#. SECURITY:
#. - Normal users do not need authentication to modify the
#. OSTree repository
#. - Note that we install polkit rules that allow local users
#. in the wheel group to modify repos without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:111
msgid "Update system repository"
msgstr "Uppdaterar systemförråd"

#: system-helper/org.freedesktop.Flatpak.policy.in:112
msgid "Authentication is required to modify a system repository"
msgstr "Autentisering krävs för att ändra ett systemförråd"

#. SECURITY:
#. - Normal users need admin authentication to install software
#. system-wide.
#: system-helper/org.freedesktop.Flatpak.policy.in:126
msgid "Install bundle"
msgstr "Installera bunt"

#: system-helper/org.freedesktop.Flatpak.policy.in:127
msgid "Authentication is required to install software from $(path)"
msgstr "Autentisering krävs för att installera program från $(path)"

#. SECURITY:
#. - Normal users need admin authentication to uninstall software
#. system-wide.
#. - Note that we install polkit rules that allow local users
#. in the wheel group to uninstall without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:144
msgid "Uninstall runtime"
msgstr "Avinstallera exekveringsmiljö"

#: system-helper/org.freedesktop.Flatpak.policy.in:145
msgid "Authentication is required to uninstall software"
msgstr "Autentisering krävs för att avinstallera program"

#. SECURITY:
#. - Normal users need admin authentication to uninstall software
#. system-wide.
#. - Note that we install polkit rules that allow local users
#. in the wheel group to uninstall without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:161
msgid "Uninstall app"
msgstr "Avinstallera program"

#: system-helper/org.freedesktop.Flatpak.policy.in:162
msgid "Authentication is required to uninstall $(ref)"
msgstr "Autentisering krävs för att avinstallera $(ref)"

#. SECURITY:
#. - Normal users need admin authentication to configure system-wide
#. software repositories.
#: system-helper/org.freedesktop.Flatpak.policy.in:177
msgid "Configure Remote"
msgstr "Konfigurera fjärrförråd"

#: system-helper/org.freedesktop.Flatpak.policy.in:178
msgid "Authentication is required to configure software repositories"
msgstr "Autentisering krävs för att konfigurera programförråd"

#. SECURITY:
#. - Normal users need admin authentication to configure the system-wide
#. Flatpak installation.
#: system-helper/org.freedesktop.Flatpak.policy.in:192
msgid "Configure"
msgstr "Konfigurera"

#: system-helper/org.freedesktop.Flatpak.policy.in:193
msgid "Authentication is required to configure software installation"
msgstr "Autentisering krävs för att konfigurera programinstallationen"

#. SECURITY:
#. - Normal users do not require admin authentication to update
#. appstream data as it will be signed, and the action is required
#. to update the system when unattended.
#. - Changing this to anything other than 'yes' will break unattended
#. updates.
#: system-helper/org.freedesktop.Flatpak.policy.in:210
msgid "Update appstream"
msgstr "Uppdatera appstream"

#: system-helper/org.freedesktop.Flatpak.policy.in:211
msgid "Authentication is required to update information about software"
msgstr "Autentisering krävs för att uppdatera information om program"

#. SECURITY:
#. - Normal users do not require admin authentication to update
#. metadata as it will be signed, and the action is required
#. to update the system when unattended.
#. - Changing this to anything other than 'yes' will break unattended
#. updates.
#: system-helper/org.freedesktop.Flatpak.policy.in:228
msgid "Update metadata"
msgstr "Uppdatera metadata"

#: system-helper/org.freedesktop.Flatpak.policy.in:229
msgid "Authentication is required to update metadata"
msgstr "Autentisering krävs för att uppdatera metadata"

#. SECURITY:
#. - Authorisation to actually install software is controlled by
#. org.freedesktop.Flatpak.app-install.
#. - This action is checked after app-install, as it can only be done
#. once the app’s data (including its content rating) has been
#. downloaded.
#. - This action is checked to see if the installation should be allowed
#. based on whether the app being installed has content which doesn’t
#. comply with the user’s parental controls policy (the content is
#. ‘too extreme’).
#. - It is checked only if an app has too extreme content for the user
#. who is trying to install it (in which case, the app is ‘unsafe’).
#. - Typically, normal users will need admin permission to install apps
#. with extreme content; admins will be able to install it without
#. additional checks.
#. - In order to configure the policy so that admins can install safe and
#. unsafe software anywhere without authorisation, and non-admins can
#. install safe software in their user or system dirs without
#. authorisation, but need authorisation to install unsafe software
#. anywhere:
#. * Unconditionally return `yes` from `app-install`.
#. * Return `auth_admin` from `override-parental-controls` for users
#. not in `@privileged_group@`, and `yes` for users in it.
#. * Set the malcontent `is-{user,system}-installation-allowed`
#. properties of all non-admins’ parental controls policies to true.
#. - In order to configure the policy so that admins can install safe and
#. unsafe software anywhere without authorisation, and non-admins can
#. install safe software in their user dir without authorisation, but
#. need authorisation to install safe software in the system dir or to
#. install unsafe software anywhere:
#. * Unconditionally return `yes` from `app-install`.
#. * Return `auth_admin` from `override-parental-controls` for users
#. not in `@privileged_group@`, and `yes` for users in it.
#. * Set the malcontent `is-user-installation-allowed` property of all
#. non-admins’ parental controls policies to true.
#. * Set the malcontent `is-system-installation-allowed` property of
#. all non-admins’ parental controls policies to false.
#. - In order to configure the policy so that all users (including
#. admins) can install safe software anywhere without authorisation,
#. but need authorisation to install unsafe software anywhere (i.e.
#. applying parental controls to admins too):
#. * Unconditionally return `yes` from `app-install`.
#. * Unconditionally return `auth_admin` from `override-parental-controls`.
#. * Set the malcontent `is-user-installation-allowed` property of all
#. users’ parental controls policies to true.
#. * Set the malcontent `is-system-installation-allowed` property of
#. all users’ parental controls policies to true.
#: system-helper/org.freedesktop.Flatpak.policy.in:287
msgid "Override parental controls for installs"
msgstr "Åsidosätt föräldrakontroller för installationer"

#: system-helper/org.freedesktop.Flatpak.policy.in:288
msgid ""
"Authentication is required to install software which is restricted by your "
"parental controls policy"
msgstr ""
"Autentisering krävs för att installera program som begränsas av din policy "
"för föräldrakontroller"

#. SECURITY:
#. - This is like org.freedesktop.Flatpak.override-parental-controls, but
#. it’s queried for app updates, whereas the former is queried for app
#. installs.
#. - As with the above action, this one is only queried if
#. org.freedesktop.Flatpak.app-update has allowed the app update, and
#. only if the app being updated has too extreme content for the user
#. who is trying to update it.
#. - The default policy for this is to *allow* updates to ‘too extreme’
#. apps by default, on the basis that having an out-of-date (i.e.
#. insecure or unsupported) app is a worse outcome than automatically
#. installing an update which has radically different content from the
#. version of the app which the parent originally vetted and installed.
#: system-helper/org.freedesktop.Flatpak.policy.in:313
msgid "Override parental controls for updates"
msgstr "Åsidosätt föräldrakontroller för uppdateringar"

#: system-helper/org.freedesktop.Flatpak.policy.in:314
msgid ""
"Authentication is required to update software which is restricted by your "
"parental controls policy"
msgstr ""
"Autentisering krävs för att uppdatera program som begränsas av din policy "
"för föräldrakontroller"

#~ msgid "Installed:"
#~ msgstr "Installerad:"

#~ msgid "Download:"
#~ msgstr "Hämta:"

#, c-format
#~ msgid "No gpg key found with ID %s (homedir: %s)"
#~ msgstr "Ingen gpg-nyckel hittades med ID %s (hemkat: %s)"

#, c-format
#~ msgid "Unable to lookup key ID %s: %d"
#~ msgstr "Kunde inte slå upp nyckel-ID %s: %d"

#, c-format
#~ msgid "Error signing commit: %d"
#~ msgstr "Fel vid signering av incheckning: %d"

===== ./po/gl.po =====
# Galician translation for flatpak.
# Copyright (C) 2017 flatpak's COPYRIGHT HOLDER
# This file is distributed under the same license as the flatpak package.
# Fran Dieguez <frandieguez@gnome.org>, 2017.
#
msgid ""
msgstr ""
"Project-Id-Version: flatpak master\n"
"Report-Msgid-Bugs-To: https://github.com/flatpak/flatpak/issues\n"
"POT-Creation-Date: 2026-05-27 16:39+0200\n"
"PO-Revision-Date: 2019-12-28 11:56+0100\n"
"Last-Translator: Fran Diéguez <frandieguez@gnome.org>\n"
"Language-Team: Galician <gnome-l10n-gl@gnome.org>\n"
"Language: gl\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Generator: Poedit 2.2.4\n"

#: app/flatpak-builtins-build-bundle.c:59
msgid "Export runtime instead of app"
msgstr "Exportar o runtime no lugar da aplicación"

#: app/flatpak-builtins-build-bundle.c:60
msgid "Arch to bundle for"
msgstr "Arquitectura para empaquetar"

#: app/flatpak-builtins-build-bundle.c:60
#: app/flatpak-builtins-build-export.c:62 app/flatpak-builtins-build-init.c:53
#: app/flatpak-builtins-build-sign.c:42 app/flatpak-builtins-create-usb.c:46
#: app/flatpak-builtins-info.c:55 app/flatpak-builtins-install.c:67
#: app/flatpak-builtins-list.c:50 app/flatpak-builtins-make-current.c:38
#: app/flatpak-builtins-remote-info.c:54 app/flatpak-builtins-remote-ls.c:56
#: app/flatpak-builtins-run.c:158 app/flatpak-builtins-search.c:37
#: app/flatpak-builtins-uninstall.c:54 app/flatpak-builtins-update.c:56
msgid "ARCH"
msgstr "ARQUITECTURA"

#: app/flatpak-builtins-build-bundle.c:61
#, fuzzy
msgid "URL for repo"
msgstr "Url para o repo"

#: app/flatpak-builtins-build-bundle.c:61
#: app/flatpak-builtins-build-bundle.c:62
#: app/flatpak-builtins-build-update-repo.c:68
#: app/flatpak-builtins-build-update-repo.c:72
#: app/flatpak-builtins-build-update-repo.c:73
#: app/flatpak-builtins-history.c:69 app/flatpak-builtins-remote-add.c:80
#: app/flatpak-builtins-remote-add.c:81 app/flatpak-builtins-remote-add.c:85
#: app/flatpak-builtins-remote-list.c:53
#: app/flatpak-builtins-remote-modify.c:70
#: app/flatpak-builtins-remote-modify.c:85
#: app/flatpak-builtins-remote-modify.c:86
#: app/flatpak-builtins-remote-modify.c:90
msgid "URL"
msgstr "URL"

#: app/flatpak-builtins-build-bundle.c:62
#, fuzzy
msgid "URL for runtime flatpakrepo file"
msgstr "Url para o ficheiro flatpakrepo do runtime"

#: app/flatpak-builtins-build-bundle.c:63
msgid "Add GPG key from FILE (- for stdin)"
msgstr "Engadir chave GPG desde FICHEIRO (- para stdin)"

#: app/flatpak-builtins-build-bundle.c:63 app/flatpak-builtins-build.c:54
#: app/flatpak-builtins-build-export.c:67
#: app/flatpak-builtins-build-update-repo.c:83
#: app/flatpak-builtins-install.c:81 app/flatpak-builtins-remote-add.c:84
#: app/flatpak-builtins-remote-add.c:86 app/flatpak-builtins-remote-modify.c:89
#: app/flatpak-builtins-remote-modify.c:92
msgid "FILE"
msgstr "FICHEIRO"

#: app/flatpak-builtins-build-bundle.c:64
msgid "GPG Key ID to sign the OCI image with"
msgstr "ID de chave GPG coa que asinar a imaxe OCI"

#: app/flatpak-builtins-build-bundle.c:64
#: app/flatpak-builtins-build-commit-from.c:68
#: app/flatpak-builtins-build-export.c:68
#: app/flatpak-builtins-build-import-bundle.c:49
#: app/flatpak-builtins-build-sign.c:44
#: app/flatpak-builtins-build-update-repo.c:84
msgid "KEY-ID"
msgstr "ID-CHAVE"

#: app/flatpak-builtins-build-bundle.c:65
#: app/flatpak-builtins-build-commit-from.c:69
#: app/flatpak-builtins-build-export.c:71
#: app/flatpak-builtins-build-import-bundle.c:50
#: app/flatpak-builtins-build-sign.c:45
#: app/flatpak-builtins-build-update-repo.c:85
msgid "GPG Homedir to use when looking for keyrings"
msgstr ""
"Directorio de orixe dos ficheiros GPG para usar ao buscar por aneis de chaves"

#: app/flatpak-builtins-build-bundle.c:65
#: app/flatpak-builtins-build-commit-from.c:69
#: app/flatpak-builtins-build-export.c:71
#: app/flatpak-builtins-build-import-bundle.c:50
#: app/flatpak-builtins-build-sign.c:45
#: app/flatpak-builtins-build-update-repo.c:85
msgid "HOMEDIR"
msgstr "DIRECTORIO_DE_INICIO"

#: app/flatpak-builtins-build-bundle.c:66
msgid "OSTree commit to create a delta bundle from"
msgstr ""

#: app/flatpak-builtins-build-bundle.c:66 app/flatpak-builtins-remote-info.c:55
#: app/flatpak-builtins-update.c:57
msgid "COMMIT"
msgstr "REMISIÓN"

#: app/flatpak-builtins-build-bundle.c:67
msgid "Export oci image instead of flatpak bundle"
msgstr "Exportar imaxe oci no lugar dun paquete flatpak"

#: app/flatpak-builtins-build-bundle.c:70
msgid "How to compress OCI image layers (default: gzip)"
msgstr ""

#: app/flatpak-builtins-build-bundle.c:634
msgid ""
"LOCATION FILENAME NAME [BRANCH] - Create a single file bundle from a local "
"repository"
msgstr ""
"LOCALIZACION NOMEFICHEIRO NOME [RAME] - Crear un paquete de ficheiro único "
"desde un repositorio local"

#: app/flatpak-builtins-build-bundle.c:641
msgid "LOCATION, FILENAME and NAME must be specified"
msgstr "Debe especificar a LOCALIZACION, NOMEFICHEIRO e o NOME"

#: app/flatpak-builtins-build-bundle.c:644
#: app/flatpak-builtins-build-export.c:844
#: app/flatpak-builtins-build-import-bundle.c:136
#: app/flatpak-builtins-build-init.c:217 app/flatpak-builtins-build-sign.c:76
#: app/flatpak-builtins-document-export.c:112
#: app/flatpak-builtins-document-info.c:75
#: app/flatpak-builtins-document-list.c:191
#: app/flatpak-builtins-document-unexport.c:70
#: app/flatpak-builtins-history.c:482 app/flatpak-builtins-info.c:130
#: app/flatpak-builtins-install.c:181 app/flatpak-builtins-install.c:234
#: app/flatpak-builtins-install.c:298 app/flatpak-builtins-list.c:419
#: app/flatpak-builtins-make-current.c:72 app/flatpak-builtins-override.c:73
#: app/flatpak-builtins-permission-list.c:162
#: app/flatpak-builtins-permission-remove.c:132
#: app/flatpak-builtins-remote-add.c:323
#: app/flatpak-builtins-remote-delete.c:68
#: app/flatpak-builtins-remote-list.c:241 app/flatpak-builtins-remote-ls.c:407
msgid "Too many arguments"
msgstr "Demasiados argumento"

#: app/flatpak-builtins-build-bundle.c:659
#: app/flatpak-builtins-build-commit-from.c:338
#: app/flatpak-builtins-build-commit-from.c:351
#: app/flatpak-builtins-build-import-bundle.c:145
#, c-format
msgid "'%s' is not a valid repository"
msgstr "«%s» non é un repositorio válido"

#: app/flatpak-builtins-build-bundle.c:663
#, fuzzy, c-format
msgid "'%s' is not a valid repository: "
msgstr "«%s» non é un repositorio válido"

#: app/flatpak-builtins-build-bundle.c:674 app/flatpak-builtins-build-sign.c:88
#: common/flatpak-dir.c:14293
#, c-format
msgid "'%s' is not a valid name: %s"
msgstr "«%s» non é un nome válido: %s"

#: app/flatpak-builtins-build-bundle.c:677
#: app/flatpak-builtins-build-export.c:865 app/flatpak-builtins-build-sign.c:91
#: common/flatpak-dir.c:14299
#, c-format
msgid "'%s' is not a valid branch name: %s"
msgstr "«%s» non é un nome válido para unha rama: %s"

#: app/flatpak-builtins-build-bundle.c:691
#: app/flatpak-builtins-build-import-bundle.c:149
#: app/flatpak-builtins-build-init.c:281
#, fuzzy, c-format
msgid "'%s' is not a valid filename"
msgstr "«%s» non é un nome válido: %s"

#: app/flatpak-builtins-build-bundle.c:706
msgid "--oci-layer-compress value must be gzip or zstd"
msgstr ""

#: app/flatpak-builtins-build.c:49
msgid "Use Platform runtime rather than Sdk"
msgstr "Usar o «runtime» de plataforma no lugar de Sdk"

#: app/flatpak-builtins-build.c:50
msgid "Make destination readonly"
msgstr ""

#: app/flatpak-builtins-build.c:51
msgid "Add bind mount"
msgstr "Engadir punto de montaxe"

#: app/flatpak-builtins-build.c:51
msgid "DEST=SRC"
msgstr "DEST=ORIX"

#: app/flatpak-builtins-build.c:52
msgid "Start build in this directory"
msgstr "Iniciar a compilación neste cartafol"

#: app/flatpak-builtins-build.c:52 app/flatpak-builtins-build.c:53
#: app/flatpak-builtins-build-init.c:64 app/flatpak-builtins-run.c:160
msgid "DIR"
msgstr "DIR"

#: app/flatpak-builtins-build.c:53
msgid "Where to look for custom sdk dir (defaults to 'usr')"
msgstr "Onde buscar o directorio personalizado de SDK (por omisión «usr»)"

#: app/flatpak-builtins-build.c:54 app/flatpak-builtins-build-export.c:67
msgid "Use alternative file for the metadata"
msgstr "Usar o ficheiro alternativo para os metadatos"

#: app/flatpak-builtins-build.c:55 app/flatpak-builtins-run.c:177
msgid "Kill processes when the parent process dies"
msgstr "Matar os procesos cando o proceso pai morre"

#: app/flatpak-builtins-build.c:56
msgid "Export application homedir directory to build"
msgstr "Exportar cartafol homedir da aplicación para construír"

#: app/flatpak-builtins-build.c:57 app/flatpak-builtins-run.c:165
msgid "Log session bus calls"
msgstr "Rexistrar chamadas ao bus de sesión"

#: app/flatpak-builtins-build.c:58 app/flatpak-builtins-run.c:166
msgid "Log system bus calls"
msgstr "Rexistrar chamadas ao bus de sistema"

#: app/flatpak-builtins-build.c:262
#, fuzzy
msgid "DIRECTORY [COMMAND [ARGUMENT…]] - Build in directory"
msgstr "DIRECTORIO [ORDE [argumentos...]] - Construír no directorio"

#: app/flatpak-builtins-build.c:285 app/flatpak-builtins-build-finish.c:656
msgid "DIRECTORY must be specified"
msgstr "Debe especificar o DIRECTORIO"

#: app/flatpak-builtins-build.c:296 app/flatpak-builtins-build-export.c:887
#, c-format
msgid "Build directory %s not initialized, use flatpak build-init"
msgstr "Directorio de construción %s non iniciado, usar flatpak build-init"

#: app/flatpak-builtins-build.c:315
msgid "metadata invalid, not application or runtime"
msgstr "metadatos non válidos, sen aplicación ou runtime"

#: app/flatpak-builtins-build.c:446
#, c-format
msgid "No extension point matching %s in %s"
msgstr "Non hai ningún punto de extensión que coincida con %s en %s"

#: app/flatpak-builtins-build.c:635
#, c-format
msgid "Missing '=' in bind mount option '%s'"
msgstr "Falta o «=» na opción «%s» de punto de montaxe"

#: app/flatpak-builtins-build.c:679 common/flatpak-run.c:3961
#, c-format
msgid "Unable to start app"
msgstr "Non foi posíbel iniciar a aplicación"

#: app/flatpak-builtins-build-commit-from.c:58
msgid "Source repo dir"
msgstr "Directorio do repositorio de orixe"

#: app/flatpak-builtins-build-commit-from.c:58
msgid "SRC-REPO"
msgstr "SRC-REPO"

#: app/flatpak-builtins-build-commit-from.c:59
msgid "Source repo ref"
msgstr "Referencia do repositorio orixe"

#: app/flatpak-builtins-build-commit-from.c:59
msgid "SRC-REF"
msgstr "SRC-REF"

#: app/flatpak-builtins-build-commit-from.c:64
#: app/flatpak-builtins-build-export.c:60
msgid "One line subject"
msgstr "Suxeito nunha liña"

#: app/flatpak-builtins-build-commit-from.c:64
#: app/flatpak-builtins-build-export.c:60
msgid "SUBJECT"
msgstr "RESUMO"

#: app/flatpak-builtins-build-commit-from.c:65
#: app/flatpak-builtins-build-export.c:61
msgid "Full description"
msgstr "Descrición completa"

#: app/flatpak-builtins-build-commit-from.c:65
#: app/flatpak-builtins-build-export.c:61
msgid "BODY"
msgstr "CORPO"

#: app/flatpak-builtins-build-commit-from.c:66
#: app/flatpak-builtins-build-export.c:64
#: app/flatpak-builtins-build-import-bundle.c:51
msgid "Update the appstream branch"
msgstr "Actualizar a rama de appstream"

#: app/flatpak-builtins-build-commit-from.c:67
#: app/flatpak-builtins-build-export.c:65
#: app/flatpak-builtins-build-import-bundle.c:52
#: app/flatpak-builtins-build-update-repo.c:87
msgid "Don't update the summary"
msgstr "Non actualizar o resumo"

#: app/flatpak-builtins-build-commit-from.c:68
#: app/flatpak-builtins-build-export.c:68
#: app/flatpak-builtins-build-import-bundle.c:49
#: app/flatpak-builtins-build-sign.c:44
msgid "GPG Key ID to sign the commit with"
msgstr "ID da chave GPG coa que asinar a remisión"

#: app/flatpak-builtins-build-commit-from.c:70
#: app/flatpak-builtins-build-export.c:73
msgid "Mark build as end-of-life"
msgstr ""

#: app/flatpak-builtins-build-commit-from.c:70
#: app/flatpak-builtins-build-export.c:73
msgid "REASON"
msgstr ""

#: app/flatpak-builtins-build-commit-from.c:71
msgid ""
"Mark refs matching the OLDID prefix as end-of-life, to be replaced with the "
"given NEWID"
msgstr ""

#: app/flatpak-builtins-build-commit-from.c:71
msgid "OLDID=NEWID"
msgstr ""

#: app/flatpak-builtins-build-commit-from.c:72
#: app/flatpak-builtins-build-export.c:75
msgid "Set type of token needed to install this commit"
msgstr ""

#: app/flatpak-builtins-build-commit-from.c:72
#: app/flatpak-builtins-build-export.c:75
#, fuzzy
msgid "VAL"
msgstr "VAR=VALOR"

#: app/flatpak-builtins-build-commit-from.c:73
#, fuzzy
msgid "Override the timestamp of the commit (NOW for current time)"
msgstr "Sobrescribir a marca de tempo da remisión"

#: app/flatpak-builtins-build-commit-from.c:73
#: app/flatpak-builtins-build-export.c:76
#, fuzzy
msgid "TIMESTAMP"
msgstr "ISO-8601-TIMESTAMP"

#: app/flatpak-builtins-build-commit-from.c:75
#: app/flatpak-builtins-build-export.c:80
#: app/flatpak-builtins-build-import-bundle.c:53
#: app/flatpak-builtins-build-update-repo.c:97
#, fuzzy
msgid "Don't generate a summary index"
msgstr "Non actualizar o resumo"

#: app/flatpak-builtins-build-commit-from.c:278
#, fuzzy
msgid "DST-REPO [DST-REF…] - Make a new commit from existing commits"
msgstr ""
"REPO-DST [REF-DST]... - Facer unha nova remisión baseada na(s) remisión(s) "
"existente(s)"

#: app/flatpak-builtins-build-commit-from.c:285
msgid "DST-REPO must be specified"
msgstr "Debe especificar o DST-REPO"

#: app/flatpak-builtins-build-commit-from.c:293
msgid ""
"If --src-repo is not specified, exactly one destination ref must be specified"
msgstr ""
"Se --src-repo non se especifica, debe especificar exactamente unha "
"referencia de destino"

#: app/flatpak-builtins-build-commit-from.c:296
msgid ""
"If --src-ref is specified, exactly one destination ref must be specified"
msgstr ""
"Se --src-ref non está especificado, debe especificar exactamente unha "
"referencia de destino"

#: app/flatpak-builtins-build-commit-from.c:299
#, fuzzy
msgid "Either --src-repo or --src-ref must be specified"
msgstr "Debe especificar --src-repo ou --src-ref."

#: app/flatpak-builtins-build-commit-from.c:315
msgid "Invalid argument format of use  --end-of-life-rebase=OLDID=NEWID"
msgstr ""

#: app/flatpak-builtins-build-commit-from.c:321
#: app/flatpak-builtins-build-commit-from.c:324
#, c-format
msgid "Invalid name %s in --end-of-life-rebase"
msgstr ""

#: app/flatpak-builtins-build-commit-from.c:333
#: app/flatpak-builtins-build-export.c:1092
#, c-format
msgid "Could not parse '%s'"
msgstr ""

#: app/flatpak-builtins-build-commit-from.c:498
#, fuzzy
msgid "Can't commit from partial source commit"
msgstr "Non é posíbel remitir a partir dotra remisión parcial."

#: app/flatpak-builtins-build-commit-from.c:503
#, c-format
msgid "%s: no change\n"
msgstr ""

#: app/flatpak-builtins-build-export.c:62
msgid "Architecture to export for (must be host compatible)"
msgstr "Arquitectura á que exportar (debe ser compatíbel co anfitrión)"

#: app/flatpak-builtins-build-export.c:63
msgid "Commit runtime (/usr), not /app"
msgstr "Runtime de remisión (/usr), non /app"

#: app/flatpak-builtins-build-export.c:66
msgid "Use alternative directory for the files"
msgstr "Usar un directorio alternativo para os ficheiros"

#: app/flatpak-builtins-build-export.c:66
msgid "SUBDIR"
msgstr "SUBDIR"

#: app/flatpak-builtins-build-export.c:69
msgid "Files to exclude"
msgstr "Ficheiros a excluír"

#: app/flatpak-builtins-build-export.c:69
#: app/flatpak-builtins-build-export.c:70
#: app/flatpak-builtins-build-update-repo.c:90
msgid "PATTERN"
msgstr "PATRON"

#: app/flatpak-builtins-build-export.c:70
msgid "Excluded files to include"
msgstr "Ficheiros excluídos a incluír"

#: app/flatpak-builtins-build-export.c:74
msgid "Mark build as end-of-life, to be replaced with the given ID"
msgstr ""

#: app/flatpak-builtins-build-export.c:74
#: app/flatpak-builtins-document-list.c:49 app/flatpak-cli-transaction.c:1427
msgid "ID"
msgstr "ID"

#: app/flatpak-builtins-build-export.c:76
msgid "Override the timestamp of the commit"
msgstr "Sobrescribir a marca de tempo da remisión"

#: app/flatpak-builtins-build-export.c:77
#: app/flatpak-builtins-build-update-repo.c:75
#: app/flatpak-builtins-remote-add.c:83 app/flatpak-builtins-remote-list.c:54
#: app/flatpak-builtins-remote-modify.c:88
msgid "Collection ID"
msgstr "ID de colección"

#: app/flatpak-builtins-build-export.c:472
#, c-format
msgid "WARNING: Error running desktop-file-validate: %s\n"
msgstr ""

#: app/flatpak-builtins-build-export.c:480
#, c-format
msgid "WARNING: Error reading from desktop-file-validate: %s\n"
msgstr ""

#: app/flatpak-builtins-build-export.c:486
#, c-format
msgid "WARNING: Failed to validate desktop file %s: %s\n"
msgstr ""

#: app/flatpak-builtins-build-export.c:513
#, c-format
msgid "WARNING: Can't find Exec key in %s: %s\n"
msgstr ""

#: app/flatpak-builtins-build-export.c:521
#: app/flatpak-builtins-build-export.c:614
#, c-format
msgid "WARNING: Binary not found for Exec line in %s: %s\n"
msgstr ""

#: app/flatpak-builtins-build-export.c:529
#, c-format
msgid "WARNING: Icon not matching app id in %s: %s\n"
msgstr ""

#: app/flatpak-builtins-build-export.c:552
#, c-format
msgid "WARNING: Icon referenced in desktop file but not exported: %s\n"
msgstr ""

#: app/flatpak-builtins-build-export.c:719
#, c-format
msgid "Invalid uri type %s, only http/https supported"
msgstr "Tipo de uri non válido %s, só se admite http/https"

#: app/flatpak-builtins-build-export.c:737
#, c-format
msgid "Unable to find basename in %s, specify a name explicitly"
msgstr ""
"Non é posíbel atopar o nome base en %s, especifique un nome de forma "
"explícita"

#: app/flatpak-builtins-build-export.c:746
#, c-format
msgid "No slashes allowed in extra data name"
msgstr "Non se permiten as barras no nome de datos adicionais"

#: app/flatpak-builtins-build-export.c:758
#, c-format
msgid "Invalid format for sha256 checksum: '%s'"
msgstr "Formato non válido para a suma de verificación sha256: «%s»"

#: app/flatpak-builtins-build-export.c:768
#, c-format
msgid "Extra data sizes of zero not supported"
msgstr "Tamaños de datos adicionais de cero non admitidos"

#: app/flatpak-builtins-build-export.c:830
msgid ""
"LOCATION DIRECTORY [BRANCH] - Create a repository from a build directory"
msgstr ""
"LOCALIZACION DIRECTORIO [RAMA] - Crea un repositorio desde o directorio de "
"construción"

#: app/flatpak-builtins-build-export.c:838
msgid "LOCATION and DIRECTORY must be specified"
msgstr "Debe especificar a LOCALIZACION OU DIRECTORIO"

#: app/flatpak-builtins-build-export.c:859
#: app/flatpak-builtins-remote-add.c:327
#, c-format
msgid "‘%s’ is not a valid collection ID: %s"
msgstr "«%s» non é un ID de colección válido: %s"

#: app/flatpak-builtins-build-export.c:904
#: app/flatpak-builtins-build-finish.c:684
msgid "No name specified in the metadata"
msgstr "Non se especificou un nome nos metadatos"

#: app/flatpak-builtins-build-export.c:1166
#, c-format
msgid "Commit: %s\n"
msgstr "Remisión: %s\n"

#: app/flatpak-builtins-build-export.c:1167
#, c-format
msgid "Metadata Total: %u\n"
msgstr ""

#: app/flatpak-builtins-build-export.c:1168
#, c-format
msgid "Metadata Written: %u\n"
msgstr ""

#: app/flatpak-builtins-build-export.c:1169
#, c-format
msgid "Content Total: %u\n"
msgstr ""

#: app/flatpak-builtins-build-export.c:1170
#, c-format
msgid "Content Written: %u\n"
msgstr ""

#: app/flatpak-builtins-build-export.c:1171
#, c-format
msgid "Content Bytes Written:"
msgstr ""

#: app/flatpak-builtins-build-finish.c:52
msgid "Command to set"
msgstr "Orde a estabelecer"

#: app/flatpak-builtins-build-finish.c:52 app/flatpak-builtins-run.c:159
#: app/flatpak-main.c:209
msgid "COMMAND"
msgstr "ORDE"

#: app/flatpak-builtins-build-finish.c:53
msgid "Flatpak version to require"
msgstr "Versión de Flatpak a requirir"

#: app/flatpak-builtins-build-finish.c:53
msgid "MAJOR.MINOR.MICRO"
msgstr "MAIOR.MENOR.MICRO"

#: app/flatpak-builtins-build-finish.c:54
msgid "Don't process exports"
msgstr "Non procesar exportados"

#: app/flatpak-builtins-build-finish.c:55
msgid "Extra data info"
msgstr "Información de datos adicionais"

#: app/flatpak-builtins-build-finish.c:56 app/flatpak-builtins-build-init.c:63
msgid "Add extension point info"
msgstr "Engadir información de punto de extensión"

#: app/flatpak-builtins-build-finish.c:56 app/flatpak-builtins-build-init.c:63
msgid "NAME=VARIABLE[=VALUE]"
msgstr "NOME=VARIABEL[=VALOR]"

#: app/flatpak-builtins-build-finish.c:57
#, fuzzy
msgid "Remove extension point info"
msgstr "Engadir información de punto de extensión"

#: app/flatpak-builtins-build-finish.c:57
#: app/flatpak-builtins-build-update-repo.c:79 app/flatpak-builtins-info.c:58
#: app/flatpak-builtins-remote-add.c:88 app/flatpak-builtins-remote-modify.c:94
#: app/flatpak-main.c:182
msgid "NAME"
msgstr "NOME"

#: app/flatpak-builtins-build-finish.c:58
msgid "Set extension priority (only for extensions)"
msgstr ""

#: app/flatpak-builtins-build-finish.c:58
#, fuzzy
msgid "VALUE"
msgstr "VAR=VALOR"

#: app/flatpak-builtins-build-finish.c:59
msgid "Change the sdk used for the app"
msgstr "Cambiar o sdk usado para a aplicación"

#: app/flatpak-builtins-build-finish.c:59
msgid "SDK"
msgstr "SDK"

#: app/flatpak-builtins-build-finish.c:60
msgid "Change the runtime used for the app"
msgstr "Cambiar o «runtime» usado pola aplicación"

#: app/flatpak-builtins-build-finish.c:60 app/flatpak-builtins-build-init.c:54
#: app/flatpak-builtins-list.c:53 app/flatpak-builtins-remote-ls.c:58
#: app/flatpak-builtins-run.c:163
msgid "RUNTIME"
msgstr "RUNTIME"

#: app/flatpak-builtins-build-finish.c:61
msgid "Set generic metadata option"
msgstr "Estabelecer opción de metadatos xenérica"

#: app/flatpak-builtins-build-finish.c:61
msgid "GROUP=KEY[=VALUE]"
msgstr "GRUPO=CHAVE[=VALOR]"

#: app/flatpak-builtins-build-finish.c:62
msgid "Don't inherit permissions from runtime"
msgstr ""

#: app/flatpak-builtins-build-finish.c:155
#, c-format
msgid "Not exporting %s, wrong extension\n"
msgstr ""

#: app/flatpak-builtins-build-finish.c:163
#, c-format
msgid "Not exporting %s, non-allowed export filename\n"
msgstr ""

#: app/flatpak-builtins-build-finish.c:167
#, c-format
msgid "Exporting %s\n"
msgstr ""

#: app/flatpak-builtins-build-finish.c:440
#, c-format
msgid "More than one executable found\n"
msgstr ""

#: app/flatpak-builtins-build-finish.c:451
#, c-format
msgid "Using %s as command\n"
msgstr ""

#: app/flatpak-builtins-build-finish.c:456
#, c-format
msgid "No executable found\n"
msgstr ""

#: app/flatpak-builtins-build-finish.c:511
#, c-format
msgid "Invalid --require-version argument: %s"
msgstr ""

#: app/flatpak-builtins-build-finish.c:543
#, c-format
msgid "Too few elements in --extra-data argument %s"
msgstr "Demasiados poucos elementos no argumento --extra-data %s"

#: app/flatpak-builtins-build-finish.c:575
#, c-format
msgid ""
"Too few elements in --metadata argument %s, format should be "
"GROUP=KEY[=VALUE]]"
msgstr ""
"Demasiados poucos elementos no argumento --metadata %s, o formato debería "
"ser GRUPO=CHAVE[=VALOR]]"

#: app/flatpak-builtins-build-finish.c:597
#: app/flatpak-builtins-build-init.c:458
#, c-format
msgid ""
"Too few elements in --extension argument %s, format should be "
"NAME=VAR[=VALUE]"
msgstr ""
"Demasiados poucos elementos no argumento --extension %s, o formato debería "
"ser NOME=VAR[=VALOR]"

#: app/flatpak-builtins-build-finish.c:603
#: app/flatpak-builtins-build-init.c:461
#, fuzzy, c-format
msgid "Invalid extension name %s"
msgstr "Nome de autenticador %s non válido"

#: app/flatpak-builtins-build-finish.c:646
msgid "DIRECTORY - Finalize a build directory"
msgstr "DIRECTORIO - Finalizar un cartafol de construción"

#: app/flatpak-builtins-build-finish.c:668
#, c-format
msgid "Build directory %s not initialized"
msgstr "Directorio de construción %s non inicializado"

#: app/flatpak-builtins-build-finish.c:689
#, c-format
msgid "Build directory %s already finalized"
msgstr "Directorio de construción %s xa finalizado"

#: app/flatpak-builtins-build-finish.c:702
#, c-format
msgid "Please review the exported files and the metadata\n"
msgstr "Por favor revise os ficheiros exportados e o metadato\n"

#: app/flatpak-builtins-build-import-bundle.c:47
msgid "Override the ref used for the imported bundle"
msgstr "Sobrescribir a referencia usada para o paquete importado"

#: app/flatpak-builtins-build-import-bundle.c:47
msgid "REF"
msgstr "REF"

#: app/flatpak-builtins-build-import-bundle.c:48
msgid "Import oci image instead of flatpak bundle"
msgstr "Importar imaxe oci no lugar de paquete flatpak"

#: app/flatpak-builtins-build-import-bundle.c:77
#: app/flatpak-builtins-build-import-bundle.c:105
#, fuzzy, c-format
msgid "Importing %s (%s)\n"
msgstr "Actualizando: %s desde %s\n"

#: app/flatpak-builtins-build-import-bundle.c:126
msgid "LOCATION FILENAME - Import a file bundle into a local repository"
msgstr ""
"LOCALIZACION NOMEFICHEIRO - Importar un ficheiro empaquetado no repositorio "
"local"

#: app/flatpak-builtins-build-import-bundle.c:133
msgid "LOCATION and FILENAME must be specified"
msgstr "Debe especificar a LOCALIZACION e o NOMEFICHEIRO"

#: app/flatpak-builtins-build-init.c:53 app/flatpak-builtins-info.c:55
#: app/flatpak-builtins-run.c:158
msgid "Arch to use"
msgstr "Arquitectura a usar"

#: app/flatpak-builtins-build-init.c:54
msgid "Initialize var from named runtime"
msgstr "Inicializar a variable desde o runtime nomeado"

#: app/flatpak-builtins-build-init.c:55
msgid "Initialize apps from named app"
msgstr "Inicializar aplicacións desde a aplicación nomeada"

#: app/flatpak-builtins-build-init.c:55
msgid "APP"
msgstr "APP"

#: app/flatpak-builtins-build-init.c:56
msgid "Specify version for --base"
msgstr "Especique a versión para --base"

#: app/flatpak-builtins-build-init.c:56 app/flatpak-builtins-run.c:164
msgid "VERSION"
msgstr "VERSION"

#: app/flatpak-builtins-build-init.c:57
msgid "Include this base extension"
msgstr "Incluír esta extensión base"

#: app/flatpak-builtins-build-init.c:57 app/flatpak-builtins-build-init.c:62
msgid "EXTENSION"
msgstr "EXTENSION"

#: app/flatpak-builtins-build-init.c:58
msgid "Extension tag to use if building extension"
msgstr ""

#: app/flatpak-builtins-build-init.c:58
#, fuzzy
msgid "EXTENSION_TAG"
msgstr "EXTENSION"

#: app/flatpak-builtins-build-init.c:59
msgid "Initialize /usr with a writable copy of the sdk"
msgstr "Incializar /usr con unha copia con permisos de escritura do sdk"

#: app/flatpak-builtins-build-init.c:60
msgid "Specify the build type (app, runtime, extension)"
msgstr "Especifique o tipo de construción (aplicación, runtime, extensión)"

#: app/flatpak-builtins-build-init.c:60
msgid "TYPE"
msgstr "TIPO"

#: app/flatpak-builtins-build-init.c:61
msgid "Add a tag"
msgstr "Engadir unha etiqueta"

#: app/flatpak-builtins-build-init.c:61
msgid "TAG"
msgstr "ETIQUETA"

#: app/flatpak-builtins-build-init.c:62
msgid "Include this sdk extension in /usr"
msgstr "Incluír esta extensión de sdk en /usr"

#: app/flatpak-builtins-build-init.c:64
msgid "Where to store sdk (defaults to 'usr')"
msgstr "Onde almacenar o sdk (por omisión en «usr»)"

#: app/flatpak-builtins-build-init.c:65
msgid "Re-initialize the sdk/var"
msgstr "Reinicializar o sdk/var"

#: app/flatpak-builtins-build-init.c:118
#, fuzzy, c-format
msgid "Requested extension %s/%s/%s is only partially installed"
msgstr "A extensión %s solicitada só está instalada parcialmente"

#: app/flatpak-builtins-build-init.c:147
#, fuzzy, c-format
msgid "Requested extension %s/%s/%s not installed"
msgstr "A extensión %s solicitada non está instalada"

#: app/flatpak-builtins-build-init.c:207
msgid ""
"DIRECTORY APPNAME SDK RUNTIME [BRANCH] - Initialize a directory for building"
msgstr ""
"DIRECTORIO NOMEAPP SDK RUNTIME [RAMA] - Inicializar un directorio para "
"construír"

#: app/flatpak-builtins-build-init.c:214
msgid "RUNTIME must be specified"
msgstr "Debe especificar un RUNTIME"

#: app/flatpak-builtins-build-init.c:235
#, c-format
msgid "'%s' is not a valid build type name, use app, runtime or extension"
msgstr ""
"«%s» non é un nome de tipo de construción válido, use app, runtime ou "
"extensión"

#: app/flatpak-builtins-build-init.c:241 app/flatpak-builtins-override.c:79
#, c-format
msgid "'%s' is not a valid application name: %s"
msgstr "«%s» non é un nome de aplicación válido: %s"

#: app/flatpak-builtins-build-init.c:295
#, c-format
msgid "Build directory %s already initialized"
msgstr "Directorio de construción %s xa inicializado"

#: app/flatpak-builtins-build-sign.c:42 app/flatpak-builtins-install.c:67
#: app/flatpak-builtins-remote-info.c:54
msgid "Arch to install for"
msgstr "Arquitectura para a que instalar"

#: app/flatpak-builtins-build-sign.c:43 app/flatpak-builtins-create-usb.c:48
#: app/flatpak-builtins-install.c:74 app/flatpak-builtins-remote-info.c:56
#: app/flatpak-builtins-uninstall.c:58 app/flatpak-builtins-update.c:64
msgid "Look for runtime with the specified name"
msgstr "Buscar un «runtime» cun nome específico"

#: app/flatpak-builtins-build-sign.c:66
msgid "LOCATION [ID [BRANCH]] - Sign an application or runtime"
msgstr "LOCALIZACION [ID [RAMA]] - Asina unha aplicación ou runtime"

#: app/flatpak-builtins-build-sign.c:73
#: app/flatpak-builtins-build-update-repo.c:499
#: app/flatpak-builtins-remote-add.c:320 app/flatpak-builtins-repo.c:739
msgid "LOCATION must be specified"
msgstr "Debe especificar a LOCALIZACION"

#: app/flatpak-builtins-build-sign.c:94
msgid "No gpg key ids specified"
msgstr "Non se especificou ningún id de chave de gpg"

#: app/flatpak-builtins-build-update-repo.c:68
msgid "Redirect this repo to a new URL"
msgstr "Redireccionar este repositorio a unha URL nova"

#: app/flatpak-builtins-build-update-repo.c:69
msgid "A nice name to use for this repository"
msgstr "Un nome bonito a usar para este repositorio"

#: app/flatpak-builtins-build-update-repo.c:69
#: app/flatpak-builtins-remote-add.c:77 app/flatpak-builtins-remote-modify.c:82
msgid "TITLE"
msgstr "TÍTULO"

#: app/flatpak-builtins-build-update-repo.c:70
#, fuzzy
msgid "A one-line comment for this repository"
msgstr "Un nome bonito a usar para este repositorio"

#: app/flatpak-builtins-build-update-repo.c:70
#: app/flatpak-builtins-remote-add.c:78 app/flatpak-builtins-remote-modify.c:83
#, fuzzy
msgid "COMMENT"
msgstr "REMISIÓN"

#: app/flatpak-builtins-build-update-repo.c:71
#, fuzzy
msgid "A full-paragraph description for this repository"
msgstr "Rama por omisión a usar para este repositorio"

#: app/flatpak-builtins-build-update-repo.c:71
#: app/flatpak-builtins-remote-add.c:79 app/flatpak-builtins-remote-modify.c:84
msgid "DESCRIPTION"
msgstr ""

#: app/flatpak-builtins-build-update-repo.c:72
#, fuzzy
msgid "URL for a website for this repository"
msgstr "Un nome bonito a usar para este repositorio"

#: app/flatpak-builtins-build-update-repo.c:73
#, fuzzy
msgid "URL for an icon for this repository"
msgstr "Un nome bonito a usar para este repositorio"

#: app/flatpak-builtins-build-update-repo.c:74
msgid "Default branch to use for this repository"
msgstr "Rama por omisión a usar para este repositorio"

#: app/flatpak-builtins-build-update-repo.c:74
#: app/flatpak-builtins-remote-add.c:82 app/flatpak-builtins-remote-modify.c:87
#: app/flatpak-builtins-repo.c:713 app/flatpak-builtins-repo.c:714
#: app/flatpak-builtins-run.c:161
msgid "BRANCH"
msgstr "RAMA"

#: app/flatpak-builtins-build-update-repo.c:75
#: app/flatpak-builtins-remote-add.c:83 app/flatpak-builtins-remote-modify.c:88
msgid "COLLECTION-ID"
msgstr "ID-COLECTIÓN"

#. Translators: A sideload is when you install from a local USB drive rather than the Internet.
#: app/flatpak-builtins-build-update-repo.c:77
#, fuzzy
msgid ""
"Permanently deploy collection ID to client remote configurations, only for "
"sideload support"
msgstr ""
"ID da colección a desplegar de forma permanente ás configuracións do remoto "
"cliente"

#: app/flatpak-builtins-build-update-repo.c:78
msgid "Permanently deploy collection ID to client remote configurations"
msgstr ""
"ID da colección a desplegar de forma permanente ás configuracións do remoto "
"cliente"

#: app/flatpak-builtins-build-update-repo.c:79
#, fuzzy
msgid "Name of authenticator for this repository"
msgstr "Un nome bonito a usar para este repositorio"

#: app/flatpak-builtins-build-update-repo.c:80
#, fuzzy
msgid "Autoinstall authenticator for this repository"
msgstr "Un nome bonito a usar para este repositorio"

#: app/flatpak-builtins-build-update-repo.c:81
#, fuzzy
msgid "Don't autoinstall authenticator for this repository"
msgstr "Rama por omisión a usar para este repositorio"

#: app/flatpak-builtins-build-update-repo.c:82
#: app/flatpak-builtins-remote-add.c:89
#, fuzzy
msgid "Authenticator option"
msgstr "Mostrar as opcións de axuda"

#: app/flatpak-builtins-build-update-repo.c:82
#: app/flatpak-builtins-remote-add.c:89 app/flatpak-builtins-remote-modify.c:95
#, fuzzy
msgid "KEY=VALUE"
msgstr "VAR=VALOR"

#: app/flatpak-builtins-build-update-repo.c:83
msgid "Import new default GPG public key from FILE"
msgstr "Importa nova chave pública GPG por omisión desde o FICHEIRO"

#: app/flatpak-builtins-build-update-repo.c:84
msgid "GPG Key ID to sign the summary with"
msgstr "ID da chave GPG coa que asinar a descrición"

#: app/flatpak-builtins-build-update-repo.c:86
msgid "Generate delta files"
msgstr "Xerar ficheiros delta"

#: app/flatpak-builtins-build-update-repo.c:88
#, fuzzy
msgid "Don't update the appstream branch"
msgstr "Actualizar a rama de appstream"

#: app/flatpak-builtins-build-update-repo.c:89
msgid "Max parallel jobs when creating deltas (default: NUMCPUs)"
msgstr ""

#: app/flatpak-builtins-build-update-repo.c:89
msgid "NUM-JOBS"
msgstr ""

#: app/flatpak-builtins-build-update-repo.c:90
#, fuzzy
msgid "Don't create deltas matching refs"
msgstr "Non actualiar as referencias relacionadas"

#: app/flatpak-builtins-build-update-repo.c:91
msgid "Prune unused objects"
msgstr "Limpar obxectos non usados"

#: app/flatpak-builtins-build-update-repo.c:92
msgid "Prune but don't actually remove anything"
msgstr ""

#: app/flatpak-builtins-build-update-repo.c:93
msgid "Only traverse DEPTH parents for each commit (default: -1=infinite)"
msgstr ""
"So atravesar os pais de PROFUNDIDADE para cada remisión (por omisión: "
"-1=infinito)"

#: app/flatpak-builtins-build-update-repo.c:93
msgid "DEPTH"
msgstr "PROFUNDIDADE"

#: app/flatpak-builtins-build-update-repo.c:223
#, c-format
msgid "Generating delta: %s (%.10s)\n"
msgstr "Xerando delta: %s (%.10s)\n"

#: app/flatpak-builtins-build-update-repo.c:225
#, c-format
msgid "Generating delta: %s (%.10s-%.10s)\n"
msgstr "Xerando delta: %s (%.10s-%.10s)\n"

#: app/flatpak-builtins-build-update-repo.c:233
#, c-format
msgid "Failed to generate delta %s (%.10s): "
msgstr "Produciuse un fallo ao xerar o delta %s (%.10s): "

#: app/flatpak-builtins-build-update-repo.c:236
#, c-format
msgid "Failed to generate delta %s (%.10s-%.10s): "
msgstr "Produciuse un fallo ao xerar o delta %s (%.10s-%.10s): "

#: app/flatpak-builtins-build-update-repo.c:492
msgid "LOCATION - Update repository metadata"
msgstr "LOCALIZACION - Actualizar os metadatos do repositorio"

#: app/flatpak-builtins-build-update-repo.c:609
#, c-format
msgid "Updating appstream branch\n"
msgstr "Actualizando a rama de appstream\n"

#: app/flatpak-builtins-build-update-repo.c:638
#, c-format
msgid "Updating summary\n"
msgstr "Actualizando resumo\n"

#: app/flatpak-builtins-build-update-repo.c:664
#, c-format
msgid "Total objects: %u\n"
msgstr "Total de obxectos: %u\n"

#: app/flatpak-builtins-build-update-repo.c:666
#, c-format
msgid "No unreachable objects\n"
msgstr "Non hai obxectos alcanzábeis\n"

#: app/flatpak-builtins-build-update-repo.c:668
#, c-format
msgid "Deleted %u objects, %s freed\n"
msgstr "%u obxectos eliminados, %s liberados\n"

#: app/flatpak-builtins-config.c:41
msgid "List configuration keys and values"
msgstr ""

#: app/flatpak-builtins-config.c:42
msgid "Get configuration for KEY"
msgstr ""

#: app/flatpak-builtins-config.c:43
msgid "Set configuration for KEY to VALUE"
msgstr ""

#: app/flatpak-builtins-config.c:44
msgid "Unset configuration for KEY"
msgstr ""

#: app/flatpak-builtins-config.c:149
#, c-format
msgid "'%s' does not look like a language/locale code"
msgstr ""

#: app/flatpak-builtins-config.c:172
#, c-format
msgid "'%s' does not look like a language code"
msgstr ""

#: app/flatpak-builtins-config.c:190
#, fuzzy, c-format
msgid "'%s' is not a valid value (use 'true' or 'false')"
msgstr "«%s» non é un repositorio válido"

#: app/flatpak-builtins-config.c:262
#, fuzzy, c-format
msgid "Unknown configure key '%s'"
msgstr "Orde descoñecida «%s»"

#: app/flatpak-builtins-config.c:284
#, fuzzy
msgid "Too many arguments for --list"
msgstr "Demasiados argumento"

#: app/flatpak-builtins-config.c:314 app/flatpak-builtins-config.c:362
#, fuzzy
msgid "You must specify KEY"
msgstr "Debe especificar o APP"

#: app/flatpak-builtins-config.c:316
#, fuzzy
msgid "Too many arguments for --get"
msgstr "Demasiados argumento"

#: app/flatpak-builtins-config.c:338
#, fuzzy
msgid "You must specify KEY and VALUE"
msgstr "Debe especificar o APP"

#: app/flatpak-builtins-config.c:340
#, fuzzy
msgid "Too many arguments for --set"
msgstr "Demasiados argumento"

#: app/flatpak-builtins-config.c:364
#, fuzzy
msgid "Too many arguments for --unset"
msgstr "Demasiados argumento"

#: app/flatpak-builtins-config.c:383
msgid "[KEY [VALUE]] - Manage configuration"
msgstr ""

#: app/flatpak-builtins-config.c:394
msgid "Can only use one of --list, --get, --set or --unset"
msgstr ""

#: app/flatpak-builtins-config.c:408
msgid "Must specify one of --list, --get, --set or --unset"
msgstr ""

#: app/flatpak-builtins-create-usb.c:45 app/flatpak-builtins-install.c:75
#: app/flatpak-builtins-remote-info.c:57 app/flatpak-builtins-uninstall.c:59
#: app/flatpak-builtins-update.c:65
msgid "Look for app with the specified name"
msgstr "Buscar unha aplicación dun nome específico"

#: app/flatpak-builtins-create-usb.c:46
#, fuzzy
msgid "Arch to copy"
msgstr "Arquitectura a mostrar"

#: app/flatpak-builtins-create-usb.c:47
#, fuzzy
msgid "DEST"
msgstr "DEST=ORIX"

#: app/flatpak-builtins-create-usb.c:49
msgid "Allow partial commits in the created repo"
msgstr ""

#: app/flatpak-builtins-create-usb.c:125 app/flatpak-builtins-create-usb.c:165
#, c-format
msgid ""
"Warning: Related ref ‘%s’ is partially installed. Use --allow-partial to "
"suppress this message.\n"
msgstr ""

#: app/flatpak-builtins-create-usb.c:158
#, c-format
msgid "Warning: Omitting related ref ‘%s’ because it is not installed.\n"
msgstr ""

#: app/flatpak-builtins-create-usb.c:175
#, c-format
msgid ""
"Warning: Omitting related ref ‘%s’ because its remote ‘%s’ does not have a "
"collection ID set.\n"
msgstr ""

#: app/flatpak-builtins-create-usb.c:187
#, c-format
msgid "Warning: Omitting related ref ‘%s’ because it's extra-data.\n"
msgstr ""

#: app/flatpak-builtins-create-usb.c:262 app/flatpak-builtins-create-usb.c:637
#, c-format
msgid ""
"Remote ‘%s’ does not have a collection ID set, which is required for P2P "
"distribution of ‘%s’."
msgstr ""

#: app/flatpak-builtins-create-usb.c:272
#, c-format
msgid "Warning: Omitting ref ‘%s’ (runtime of ‘%s’) because it's extra-data.\n"
msgstr ""

#: app/flatpak-builtins-create-usb.c:484
msgid "MOUNT-PATH [REF…] - Copy apps or runtimes onto removable media"
msgstr ""

#: app/flatpak-builtins-create-usb.c:493
#, fuzzy
msgid "MOUNT-PATH and REF must be specified"
msgstr "Debe especificar REMOTO e REF"

#: app/flatpak-builtins-create-usb.c:607
#, c-format
msgid "Ref ‘%s’ found in multiple installations: %s. You must specify one."
msgstr ""

#: app/flatpak-builtins-create-usb.c:620
#, c-format
msgid "Refs must all be in the same installation (found in %s and %s)."
msgstr ""

#: app/flatpak-builtins-create-usb.c:670
#, c-format
msgid ""
"Warning: Ref ‘%s’ is partially installed. Use --allow-partial to suppress "
"this message.\n"
msgstr ""

#: app/flatpak-builtins-create-usb.c:681
#, c-format
msgid "Installed ref ‘%s’ is extra-data, and cannot be distributed offline"
msgstr ""

#: app/flatpak-builtins-create-usb.c:721
#, fuzzy, c-format
msgid "Warning: Couldn't update repo metadata for remote ‘%s’: %s\n"
msgstr ""
"Aviso: Non se puideron actualizar os metadatos adicionais para «%s»: %s\n"

#: app/flatpak-builtins-create-usb.c:751
#, fuzzy, c-format
msgid "Warning: Couldn't update appstream data for remote ‘%s’ arch ‘%s’: %s\n"
msgstr ""
"Aviso: Non se puideron actualizar os metadatos adicionais para «%s»: %s\n"

#. Print a warning if both appstream and appstream2 are missing
#: app/flatpak-builtins-create-usb.c:784
#, fuzzy, c-format
msgid ""
"Warning: Couldn't find appstream data for remote ‘%s’ arch ‘%s’: %s; %s\n"
msgstr ""
"Aviso: Non se puideron actualizar os metadatos adicionais para «%s»: %s\n"

#. Appstream2 is only for efficiency, so just print a debug message
#: app/flatpak-builtins-create-usb.c:790
#, fuzzy, c-format
msgid "Couldn't find appstream2 data for remote ‘%s’ arch ‘%s’: %s\n"
msgstr "Actualizando appstream para o remoto %s\n"

#: app/flatpak-builtins-document-export.c:62
msgid "Create a unique document reference"
msgstr "Crear unha referencia de documento única"

#: app/flatpak-builtins-document-export.c:63
msgid "Make the document transient for the current session"
msgstr "Facer o documento transitorio para a sesión actual"

#: app/flatpak-builtins-document-export.c:64
msgid "Don't require the file to exist already"
msgstr "Non requirir que o ficheiro de antemán"

#: app/flatpak-builtins-document-export.c:65
msgid "Give the app read permissions"
msgstr "Darlle á aplicación permisos de lectura"

#: app/flatpak-builtins-document-export.c:66
msgid "Give the app write permissions"
msgstr "Darlle á aplicación permisos de escritura"

#: app/flatpak-builtins-document-export.c:67
msgid "Give the app delete permissions"
msgstr "Darlle á aplicación permisos de eliminación"

#: app/flatpak-builtins-document-export.c:68
msgid "Give the app permissions to grant further permissions"
msgstr "Darlle á aplicación permisos para asignar permisos futuros"

#: app/flatpak-builtins-document-export.c:69
msgid "Revoke read permissions of the app"
msgstr "Revogarlle os permisos de lectura á aplicación"

#: app/flatpak-builtins-document-export.c:70
msgid "Revoke write permissions of the app"
msgstr "Revogarlle os permisos de escritura á aplicación"

#: app/flatpak-builtins-document-export.c:71
msgid "Revoke delete permissions of the app"
msgstr "Revogarlle os permisos de eliminación á aplicación"

#: app/flatpak-builtins-document-export.c:72
msgid "Revoke the permission to grant further permissions"
msgstr "Revogarlle os permisos para asignar permisos futuros"

#: app/flatpak-builtins-document-export.c:73
msgid "Add permissions for this app"
msgstr "Engadir permisos para esta aplicación"

#: app/flatpak-builtins-document-export.c:73
msgid "APPID"
msgstr "APPID"

#: app/flatpak-builtins-document-export.c:100
msgid "FILE - Export a file to apps"
msgstr "FICHEIRO - Exportar un ficheiro ás aplicacións"

#: app/flatpak-builtins-document-export.c:109
#: app/flatpak-builtins-document-info.c:72
#: app/flatpak-builtins-document-unexport.c:67
msgid "FILE must be specified"
msgstr "Debe especificar o FICHEIRO"

#: app/flatpak-builtins-document-info.c:63
msgid "FILE - Get information about an exported file"
msgstr "FICHEIRO - Obter información sobre un ficheiro exportado"

#: app/flatpak-builtins-document-info.c:100
#: app/flatpak-builtins-document-unexport.c:94
#, c-format
msgid "Not exported\n"
msgstr "Non exportado\n"

#: app/flatpak-builtins-document-list.c:43 app/flatpak-builtins-history.c:53
#: app/flatpak-builtins-list.c:54 app/flatpak-builtins-ps.c:43
#: app/flatpak-builtins-remote-list.c:45 app/flatpak-builtins-remote-ls.c:59
#: app/flatpak-builtins-search.c:38
#, fuzzy
msgid "What information to show"
msgstr "Imprimir información sobre un repositorio"

#: app/flatpak-builtins-document-list.c:43 app/flatpak-builtins-history.c:53
#: app/flatpak-builtins-list.c:54 app/flatpak-builtins-ps.c:43
#: app/flatpak-builtins-remote-list.c:45 app/flatpak-builtins-remote-ls.c:59
#: app/flatpak-builtins-search.c:38
msgid "FIELD,…"
msgstr ""

#: app/flatpak-builtins-document-list.c:44 app/flatpak-builtins-history.c:54
#: app/flatpak-builtins-list.c:52 app/flatpak-builtins-permission-list.c:43
#: app/flatpak-builtins-permission-show.c:43 app/flatpak-builtins-ps.c:44
#: app/flatpak-builtins-remote-list.c:46 app/flatpak-builtins-remote-ls.c:63
#: app/flatpak-builtins-repo.c:717 app/flatpak-builtins-search.c:39
#, fuzzy
msgid "Show output in JSON format"
msgstr "Mostrar información adicional"

#: app/flatpak-builtins-document-list.c:49
#, fuzzy
msgid "Show the document ID"
msgstr "Mostrar só os runtimes"

#: app/flatpak-builtins-document-list.c:50
msgid "Path"
msgstr ""

#: app/flatpak-builtins-document-list.c:50
#: app/flatpak-builtins-document-list.c:51
#, fuzzy
msgid "Show the document path"
msgstr "Mostrar só os runtimes"

#: app/flatpak-builtins-document-list.c:51 app/flatpak-builtins-list.c:66
#: app/flatpak-builtins-remote-ls.c:74
msgid "Origin"
msgstr "Orixe"

#: app/flatpak-builtins-document-list.c:52 app/flatpak-builtins-history.c:62
#: app/flatpak-builtins-ps.c:52
#, fuzzy
msgid "Application"
msgstr "ID de colección"

#: app/flatpak-builtins-document-list.c:52
#, fuzzy
msgid "Show applications with permission"
msgstr "Mostrar extensións"

#: app/flatpak-builtins-document-list.c:53
#: app/flatpak-builtins-permission-list.c:182
#: app/flatpak-builtins-permission-show.c:145
#, fuzzy
msgid "Permissions"
msgstr "Mostrar extensións"

#: app/flatpak-builtins-document-list.c:53
msgid "Show permissions for applications"
msgstr ""

#: app/flatpak-builtins-document-list.c:161
#, fuzzy, c-format
msgid "No documents found\n"
msgstr "Nada coincide con %s"

#: app/flatpak-builtins-document-list.c:180
msgid "[APPID] - List exported files"
msgstr "[APPID] - Obtén unha lista dos ficheiros exportados"

#: app/flatpak-builtins-document-unexport.c:43
#, fuzzy
msgid "Specify the document ID"
msgstr "Mostrar só os runtimes"

#: app/flatpak-builtins-document-unexport.c:58
msgid "FILE - Unexport a file to apps"
msgstr "FICHEIRO - Elimina a exportación dun ficheiro ás aplicacións"

#: app/flatpak-builtins-enter.c:88
#, fuzzy
msgid "INSTANCE COMMAND [ARGUMENT…] - Run a command inside a running sandbox"
msgstr ""
"SANDBOXEDPID [ORDE [args...]] - Executa unha orde dentro dun sandbox en "
"execución"

#: app/flatpak-builtins-enter.c:111
#, fuzzy
msgid "INSTANCE and COMMAND must be specified"
msgstr "Debe especificar o SANDBOXEDPID e a ORDE"

#: app/flatpak-builtins-enter.c:138
#, c-format
msgid "%s is neither a pid nor an application or instance ID"
msgstr ""

#: app/flatpak-builtins-enter.c:144
msgid "entering not supported (need unprivileged user namespaces, or sudo -E)"
msgstr ""

#: app/flatpak-builtins-enter.c:145
#, c-format
msgid "No such pid %s"
msgstr "Non existe o PID %s"

#: app/flatpak-builtins-enter.c:158
msgid "Can't read cwd"
msgstr "Non é posíbel ler cwd"

#: app/flatpak-builtins-enter.c:163
msgid "Can't read root"
msgstr "Non é posíbel ler root"

#: app/flatpak-builtins-enter.c:191
#, c-format
msgid "Invalid %s namespace for pid %d"
msgstr "Espazo de nomes %s non válido para o PID %d"

#: app/flatpak-builtins-enter.c:202
#, c-format
msgid "Invalid %s namespace for self"
msgstr "Espazo de nomes %s non válido para si mesmo"

#: app/flatpak-builtins-enter.c:216
#, c-format
msgid "Can't open %s namespace: %s"
msgstr "Non é posíbel abrir o espazo de nomes %s: %s"

#: app/flatpak-builtins-enter.c:226
msgid "entering not supported (need unprivileged user namespaces)"
msgstr ""

#: app/flatpak-builtins-enter.c:227
#, c-format
msgid "Can't enter %s namespace: %s"
msgstr "Non é posíbel entrar no espazo de nomes %s: %s"

#: app/flatpak-builtins-enter.c:234
msgid "Can't chdir"
msgstr "Non é posíbel facer chdir"

#: app/flatpak-builtins-enter.c:237
msgid "Can't chroot"
msgstr "Non é posíbel facer chroot"

#: app/flatpak-builtins-enter.c:240
msgid "Can't switch gid"
msgstr "Non é posíbel trocar o GID"

#: app/flatpak-builtins-enter.c:243
msgid "Can't switch uid"
msgstr "Non é posíbel trocar o UID"

#: app/flatpak-builtins-history.c:50
msgid "Only show changes after TIME"
msgstr ""

#: app/flatpak-builtins-history.c:50 app/flatpak-builtins-history.c:51
#, fuzzy
msgid "TIME"
msgstr "RUNTIME"

#: app/flatpak-builtins-history.c:51
msgid "Only show changes before TIME"
msgstr ""

#: app/flatpak-builtins-history.c:52
#, fuzzy
msgid "Show newest entries first"
msgstr "Mostrar extensións"

#: app/flatpak-builtins-history.c:59
msgid "Time"
msgstr ""

#: app/flatpak-builtins-history.c:59
#, fuzzy
msgid "Show when the change happened"
msgstr "Mostrar só os runtimes"

#: app/flatpak-builtins-history.c:60
msgid "Change"
msgstr ""

#: app/flatpak-builtins-history.c:60
msgid "Show the kind of change"
msgstr ""

#: app/flatpak-builtins-history.c:61 app/flatpak-builtins-list.c:68
#: app/flatpak-builtins-remote-ls.c:75 app/flatpak-builtins-repo.c:335
msgid "Ref"
msgstr "Referencia"

#: app/flatpak-builtins-history.c:61 app/flatpak-builtins-list.c:68
#: app/flatpak-builtins-remote-ls.c:75
#, fuzzy
msgid "Show the ref"
msgstr "Mostrar referencia"

#: app/flatpak-builtins-history.c:62
#, fuzzy
msgid "Show the application/runtime ID"
msgstr "ID de colección"

#: app/flatpak-builtins-history.c:63 app/flatpak-builtins-list.c:64
#: app/flatpak-builtins-ps.c:53 app/flatpak-builtins-remote-ls.c:73
#: app/flatpak-cli-transaction.c:1435
msgid "Arch"
msgstr "Arquitectura"

#: app/flatpak-builtins-history.c:63 app/flatpak-builtins-list.c:64
#: app/flatpak-builtins-ps.c:53 app/flatpak-builtins-remote-ls.c:73
msgid "Show the architecture"
msgstr ""

#: app/flatpak-builtins-history.c:64 app/flatpak-builtins-list.c:63
#: app/flatpak-builtins-ps.c:54 app/flatpak-builtins-remote-ls.c:72
#: app/flatpak-builtins-search.c:48 app/flatpak-cli-transaction.c:1438
msgid "Branch"
msgstr "Rama"

#: app/flatpak-builtins-history.c:64 app/flatpak-builtins-list.c:63
#: app/flatpak-builtins-remote-ls.c:72
#, fuzzy
msgid "Show the branch"
msgstr "Mostrar só os runtimes"

#: app/flatpak-builtins-history.c:65 app/flatpak-builtins-list.c:67
#, fuzzy
msgid "Installation"
msgstr "Instalado"

#: app/flatpak-builtins-history.c:65
#, fuzzy
msgid "Show the affected installation"
msgstr "Mostrar instalacións do usuario"

#: app/flatpak-builtins-history.c:66 app/flatpak-cli-transaction.c:1452
#, fuzzy
msgid "Remote"
msgstr "Sen remoto %s"

#: app/flatpak-builtins-history.c:66
#, fuzzy
msgid "Show the remote"
msgstr "Mostrar remotos desactivados"

#: app/flatpak-builtins-history.c:67 app/flatpak-builtins-ps.c:55
#: app/flatpak-builtins-remote-ls.c:76
msgid "Commit"
msgstr "Remisión"

#: app/flatpak-builtins-history.c:67
#, fuzzy
msgid "Show the current commit"
msgstr "Mostrar só os runtimes"

#: app/flatpak-builtins-history.c:68
msgid "Old Commit"
msgstr "Remisión antiga"

#: app/flatpak-builtins-history.c:68
#, fuzzy
msgid "Show the previous commit"
msgstr "Mostrar só os runtimes"

#: app/flatpak-builtins-history.c:69
#, fuzzy
msgid "Show the remote URL"
msgstr "Mostrar só os runtimes"

#: app/flatpak-builtins-history.c:70 app/flatpak-cli-transaction.c:700
msgid "User"
msgstr ""

#: app/flatpak-builtins-history.c:70
#, fuzzy
msgid "Show the user doing the change"
msgstr "Mostrar só os runtimes"

#: app/flatpak-builtins-history.c:71
msgid "Tool"
msgstr ""

#: app/flatpak-builtins-history.c:71
msgid "Show the tool that was used"
msgstr ""

#: app/flatpak-builtins-history.c:72 app/flatpak-builtins-list.c:62
#: app/flatpak-builtins-remote-ls.c:71 app/flatpak-builtins-search.c:47
msgid "Version"
msgstr ""

#: app/flatpak-builtins-history.c:72
#, fuzzy
msgid "Show the Flatpak version"
msgstr "ID de colección"

#: app/flatpak-builtins-history.c:91
#, fuzzy, c-format
msgid "Failed to get journal data (%s): %s"
msgstr "Produciuse un fallo ao cargar os datos adicinais locais %s: %s"

#: app/flatpak-builtins-history.c:146
#, fuzzy, c-format
msgid "Failed to open journal: %s"
msgstr "Produciuse un fallo ao abrir o ficheiro temporal flatpak-info: %s"

#: app/flatpak-builtins-history.c:153
#, fuzzy, c-format
msgid "Failed to add match to journal: %s"
msgstr "Produciuse un fallo ao cargar os datos adicinais locais %s: %s"

#: app/flatpak-builtins-history.c:471
msgid " - Show history"
msgstr ""

#: app/flatpak-builtins-history.c:490
#, fuzzy, c-format
msgid "Failed to parse the --since option"
msgstr "Non foi posíbel crear a tubería de sincronización"

#: app/flatpak-builtins-history.c:501
#, c-format
msgid "Failed to parse the --until option"
msgstr ""

#: app/flatpak-builtins-info.c:56
msgid "Show user installations"
msgstr "Mostrar instalacións do usuario"

#: app/flatpak-builtins-info.c:57
msgid "Show system-wide installations"
msgstr "Mostrar instalacións do sistema"

#: app/flatpak-builtins-info.c:58
msgid "Show specific system-wide installations"
msgstr "Mostrar instalacións específicas do sistema"

#: app/flatpak-builtins-info.c:59 app/flatpak-builtins-remote-info.c:59
msgid "Show ref"
msgstr "Mostrar referencia"

#: app/flatpak-builtins-info.c:60 app/flatpak-builtins-remote-info.c:60
msgid "Show commit"
msgstr "Mostrar remisión"

#: app/flatpak-builtins-info.c:61
msgid "Show origin"
msgstr "Mostrar orixe"

#: app/flatpak-builtins-info.c:62
msgid "Show size"
msgstr "Mostrar tamaño"

#: app/flatpak-builtins-info.c:63 app/flatpak-builtins-remote-info.c:62
msgid "Show metadata"
msgstr "Mostrar metadatos"

#: app/flatpak-builtins-info.c:64 app/flatpak-builtins-remote-info.c:63
#, fuzzy
msgid "Show runtime"
msgstr "Mostrar só os runtimes"

#: app/flatpak-builtins-info.c:65 app/flatpak-builtins-remote-info.c:64
#, fuzzy
msgid "Show sdk"
msgstr "Mostrar tamaño"

#: app/flatpak-builtins-info.c:66
#, fuzzy
msgid "Show permissions"
msgstr "Mostrar extensións"

#: app/flatpak-builtins-info.c:67
msgid "Query file access"
msgstr ""

#: app/flatpak-builtins-info.c:67 app/flatpak-builtins-install.c:82
#: app/flatpak-builtins-install.c:88 app/flatpak-builtins-preinstall.c:68
#: app/flatpak-builtins-run.c:182 app/flatpak-builtins-run.c:184
#: app/flatpak-builtins-update.c:67 app/flatpak-builtins-update.c:71
msgid "PATH"
msgstr "RUTA"

#: app/flatpak-builtins-info.c:68
msgid "Show extensions"
msgstr "Mostrar extensións"

#: app/flatpak-builtins-info.c:69
#, fuzzy
msgid "Show location"
msgstr "Mostrar as opcións de axuda"

#: app/flatpak-builtins-info.c:116
msgid "NAME [BRANCH] - Get info about an installed app or runtime"
msgstr ""
"NOME [RAMA] - Obtén información sobre a aplicación ou runtime instalado"

#: app/flatpak-builtins-info.c:123 app/flatpak-builtins-remote-add.c:317
#: app/flatpak-builtins-remote-delete.c:63
msgid "NAME must be specified"
msgstr "Debe especificar o NOME"

#: app/flatpak-builtins-info.c:196
msgid "ref not present in origin"
msgstr "referencia non presente no orixe"

#: app/flatpak-builtins-info.c:211 app/flatpak-builtins-remote-info.c:217
#, c-format
msgid "Warning: Commit has no flatpak metadata\n"
msgstr ""

#: app/flatpak-builtins-info.c:217 app/flatpak-builtins-info.c:259
#: app/flatpak-builtins-info.c:455 app/flatpak-builtins-info.c:513
#: app/flatpak-builtins-remote-info.c:236
#: app/flatpak-builtins-remote-info.c:271
msgid "ID:"
msgstr "ID:"

#: app/flatpak-builtins-info.c:218 app/flatpak-builtins-info.c:260
#: app/flatpak-builtins-remote-info.c:237
#: app/flatpak-builtins-remote-info.c:272
msgid "Ref:"
msgstr "Referencia:"

#: app/flatpak-builtins-info.c:219 app/flatpak-builtins-info.c:261
#: app/flatpak-builtins-remote-info.c:238
#: app/flatpak-builtins-remote-info.c:273
msgid "Arch:"
msgstr "Arquitectura:"

#: app/flatpak-builtins-info.c:220 app/flatpak-builtins-info.c:262
#: app/flatpak-builtins-remote-info.c:239
#: app/flatpak-builtins-remote-info.c:274
msgid "Branch:"
msgstr "Rama:"

#: app/flatpak-builtins-info.c:222 app/flatpak-builtins-info.c:264
#: app/flatpak-builtins-remote-info.c:241
#: app/flatpak-builtins-remote-info.c:276
#, fuzzy
msgid "Version:"
msgstr "Extensión:"

#: app/flatpak-builtins-info.c:224 app/flatpak-builtins-info.c:266
#: app/flatpak-builtins-remote-info.c:243
#: app/flatpak-builtins-remote-info.c:278
msgid "License:"
msgstr ""

#: app/flatpak-builtins-info.c:226 app/flatpak-builtins-info.c:269
#: app/flatpak-builtins-remote-info.c:245
#: app/flatpak-builtins-remote-info.c:280
msgid "Collection:"
msgstr "Colección"

#: app/flatpak-builtins-info.c:227 app/flatpak-builtins-info.c:270
#: app/flatpak-builtins-info.c:458 app/flatpak-builtins-info.c:516
msgid "Installation:"
msgstr "Instalación:"

#: app/flatpak-builtins-info.c:228 app/flatpak-builtins-info.c:271
#: app/flatpak-builtins-info.c:459 app/flatpak-builtins-info.c:517
#: app/flatpak-builtins-remote-info.c:249
#: app/flatpak-builtins-remote-info.c:284
#, fuzzy
msgid "Installed Size:"
msgstr "Tamaño instalado"

#: app/flatpak-builtins-info.c:231 app/flatpak-builtins-info.c:279
#: app/flatpak-builtins-remote-info.c:252
#: app/flatpak-builtins-remote-info.c:288
msgid "Runtime:"
msgstr "Runtime:"

#: app/flatpak-builtins-info.c:232 app/flatpak-builtins-info.c:288
#: app/flatpak-builtins-remote-info.c:253
#: app/flatpak-builtins-remote-info.c:293
msgid "Sdk:"
msgstr ""

#: app/flatpak-builtins-info.c:235 app/flatpak-builtins-info.c:313
#: app/flatpak-builtins-remote-info.c:256
#: app/flatpak-builtins-remote-info.c:319
msgid "Date:"
msgstr ""

#: app/flatpak-builtins-info.c:237 app/flatpak-builtins-info.c:311
#: app/flatpak-builtins-remote-info.c:258
#: app/flatpak-builtins-remote-info.c:317
msgid "Subject:"
msgstr ""

#: app/flatpak-builtins-info.c:240 app/flatpak-builtins-info.c:295
msgid "Active commit:"
msgstr "Remisión activa:"

#: app/flatpak-builtins-info.c:241 app/flatpak-builtins-info.c:298
msgid "Latest commit:"
msgstr "Última remisión:"

#: app/flatpak-builtins-info.c:244 app/flatpak-builtins-info.c:303
#: app/flatpak-builtins-info.c:457 app/flatpak-builtins-info.c:515
#: app/flatpak-builtins-remote-info.c:259
#: app/flatpak-builtins-remote-info.c:298
msgid "Commit:"
msgstr "Remisión:"

#: app/flatpak-builtins-info.c:246 app/flatpak-builtins-info.c:308
#: app/flatpak-builtins-remote-info.c:261
#: app/flatpak-builtins-remote-info.c:303
msgid "Parent:"
msgstr ""

#: app/flatpak-builtins-info.c:248 app/flatpak-builtins-info.c:321
msgid "Alt-id:"
msgstr "Alt-id:"

#: app/flatpak-builtins-info.c:250 app/flatpak-builtins-info.c:325
#: app/flatpak-builtins-remote-info.c:263
#: app/flatpak-builtins-remote-info.c:308
msgid "End-of-life:"
msgstr ""

#: app/flatpak-builtins-info.c:252 app/flatpak-builtins-info.c:330
#: app/flatpak-builtins-remote-info.c:265
#: app/flatpak-builtins-remote-info.c:313
msgid "End-of-life-rebase:"
msgstr ""

#: app/flatpak-builtins-info.c:254 app/flatpak-builtins-info.c:317
#, fuzzy
msgid "Subdirectories:"
msgstr "Subdirectorios da instalación:"

#: app/flatpak-builtins-info.c:255 app/flatpak-builtins-info.c:454
#: app/flatpak-builtins-info.c:512
msgid "Extension:"
msgstr "Extensión:"

#: app/flatpak-builtins-info.c:267 app/flatpak-builtins-info.c:456
#: app/flatpak-builtins-info.c:514
msgid "Origin:"
msgstr "Orixe:"

#: app/flatpak-builtins-info.c:460 app/flatpak-builtins-info.c:522
msgid "Subpaths:"
msgstr "Subdirectorios:"

#: app/flatpak-builtins-info.c:478
msgid "unmaintained"
msgstr ""

#: app/flatpak-builtins-info.c:480 app/flatpak-builtins-info.c:482
msgid "unknown"
msgstr ""

#: app/flatpak-builtins-install.c:68 app/flatpak-builtins-preinstall.c:57
msgid "Don't pull, only install from local cache"
msgstr "Non facer «pull», só instar desde a caché local"

#: app/flatpak-builtins-install.c:69 app/flatpak-builtins-preinstall.c:58
#: app/flatpak-builtins-update.c:60
msgid "Don't deploy, only download to local cache"
msgstr "No despregar, só descargar á caché local"

#: app/flatpak-builtins-install.c:70 app/flatpak-builtins-preinstall.c:59
msgid "Don't install related refs"
msgstr "Non instalar referencias relacionadas"

#: app/flatpak-builtins-install.c:71 app/flatpak-builtins-preinstall.c:60
#: app/flatpak-builtins-update.c:62
msgid "Don't verify/install runtime dependencies"
msgstr "Non verificar/instalar as dependencias de runtime"

#: app/flatpak-builtins-install.c:72
msgid "Don't automatically pin explicit installs"
msgstr ""

#: app/flatpak-builtins-install.c:73 app/flatpak-builtins-preinstall.c:61
#: app/flatpak-builtins-update.c:63
msgid "Don't use static deltas"
msgstr "Non usar deltas estáticos"

#: app/flatpak-builtins-install.c:76 app/flatpak-builtins-preinstall.c:62
msgid "Additionally install the SDK used to build the given refs"
msgstr ""

#: app/flatpak-builtins-install.c:77 app/flatpak-builtins-preinstall.c:63
msgid ""
"Additionally install the debug info for the given refs and their dependencies"
msgstr ""

#: app/flatpak-builtins-install.c:78
msgid "Assume LOCATION is a .flatpak single-file bundle"
msgstr "Asume que LOCALIZACION é un paquete .flatpak dun só ficheiro."

#: app/flatpak-builtins-install.c:79
msgid "Assume LOCATION is a .flatpakref application description"
msgstr "Asume que LOCALIZACION é uha descrición de aplicación .flatpakref"

#: app/flatpak-builtins-install.c:80
msgid "Assume LOCATION is containers-transports(5) reference to an OCI image"
msgstr ""

#: app/flatpak-builtins-install.c:81
msgid "Check bundle signatures with GPG key from FILE (- for stdin)"
msgstr ""
"Comproba as sinaturas do paquete coa chave GPG dese o FICHEIRO (- para stdin)"

#: app/flatpak-builtins-install.c:82
msgid "Only install this subpath"
msgstr "Só instalar esta subruta"

#: app/flatpak-builtins-install.c:83 app/flatpak-builtins-preinstall.c:64
#: app/flatpak-builtins-uninstall.c:63 app/flatpak-builtins-update.c:68
msgid "Automatically answer yes for all questions"
msgstr "Responder si automaticamente para todas as preguntas"

#: app/flatpak-builtins-install.c:84 app/flatpak-builtins-preinstall.c:65
#, fuzzy
msgid "Uninstall first if already installed"
msgstr "%s remisión %s xa instalado"

#: app/flatpak-builtins-install.c:85 app/flatpak-builtins-preinstall.c:66
#: app/flatpak-builtins-uninstall.c:64 app/flatpak-builtins-update.c:69
msgid "Produce minimal output and don't ask questions"
msgstr ""

#: app/flatpak-builtins-install.c:86
#, fuzzy
msgid "Update install if already installed"
msgstr "%s remisión %s xa instalado"

#. Translators: A sideload is when you install from a local USB drive rather than the Internet.
#: app/flatpak-builtins-install.c:88 app/flatpak-builtins-preinstall.c:68
#: app/flatpak-builtins-update.c:71
msgid "Use this local repo for sideloads"
msgstr ""

#: app/flatpak-builtins-install.c:178
msgid "Bundle filename must be specified"
msgstr "Debe especificar o nome de ficheiro do paquete"

#: app/flatpak-builtins-install.c:188
msgid "Remote bundles are not supported"
msgstr "Non se admiten os paquetes remotos"

#: app/flatpak-builtins-install.c:231
msgid "Filename or uri must be specified"
msgstr "Debe especificar o nome de ficheiro ou uri"

#: app/flatpak-builtins-install.c:295
#, fuzzy
msgid "Image location must be specified"
msgstr "Debe especificar REMOTO e REF"

#: app/flatpak-builtins-install.c:345
#, fuzzy
msgid "[LOCATION/REMOTE] [REF…] - Install applications or runtimes"
msgstr "LOCALIZACION/REMOTO [REF...] - Instalar aplicacións ou runtimes"

#: app/flatpak-builtins-install.c:378
#, fuzzy
msgid "At least one REF must be specified"
msgstr "Debe especificar REMOTO e REF"

#: app/flatpak-builtins-install.c:392
#, fuzzy, c-format
msgid "Looking for matches…\n"
msgstr "Non hai actualizacións.\n"

#: app/flatpak-builtins-install.c:513
#, fuzzy, c-format
msgid "No remote refs found for ‘%s’"
msgstr "Non se atopou ningunha sobrescritura para %s"

#: app/flatpak-builtins-install.c:573 app/flatpak-builtins-uninstall.c:405
#: common/flatpak-ref-utils.c:689 common/flatpak-ref-utils.c:1595
#, fuzzy, c-format
msgid "Invalid branch %s: %s"
msgstr "«%s» non é un nome válido para unha rama: %s"

#: app/flatpak-builtins-install.c:606
#, fuzzy, c-format
msgid "Nothing matches %s in local repository for remote %s"
msgstr "Produciuse un erro ao buscar no repositorio local: %s"

#: app/flatpak-builtins-install.c:608
#, fuzzy, c-format
msgid "Nothing matches %s in remote %s"
msgstr "Nada coincide con %s"

#: app/flatpak-builtins-install.c:629
#, fuzzy, c-format
msgid "Skipping: %s\n"
msgstr "Instalando: %s\n"

#: app/flatpak-builtins-kill.c:110
#, fuzzy, c-format
msgid "%s is not running"
msgstr "%s non está dispoñíbel"

#: app/flatpak-builtins-kill.c:136
msgid "INSTANCE - Stop a running application"
msgstr "INSTANCIA - Deter unha aplicación en execución"

#: app/flatpak-builtins-kill.c:144 app/flatpak-builtins-ps.c:256
#, fuzzy
msgid "Extra arguments given"
msgstr "Información de datos adicionais"

#: app/flatpak-builtins-kill.c:150
msgid "Must specify the app to kill"
msgstr ""

#: app/flatpak-builtins-list.c:47
msgid "Show extra information"
msgstr "Mostrar información adicional"

#: app/flatpak-builtins-list.c:48
msgid "List installed runtimes"
msgstr "Mostrar os runtime instalados"

#: app/flatpak-builtins-list.c:49
msgid "List installed applications"
msgstr "Mostrar as aplicacións instaladas"

#: app/flatpak-builtins-list.c:50
msgid "Arch to show"
msgstr "Arquitectura a mostrar"

#: app/flatpak-builtins-list.c:51 app/flatpak-builtins-remote-ls.c:57
msgid "List all refs (including locale/debug)"
msgstr "Mostrar todas as referencias (incluíndo as locais/depuración)"

#: app/flatpak-builtins-list.c:53 app/flatpak-builtins-remote-ls.c:58
msgid "List all applications using RUNTIME"
msgstr "Mostrar as aplicacións instaladas"

#: app/flatpak-builtins-list.c:59 app/flatpak-builtins-remote-list.c:51
#: app/flatpak-builtins-remote-ls.c:68 app/flatpak-builtins-search.c:44
msgid "Name"
msgstr "Nome"

#: app/flatpak-builtins-list.c:59 app/flatpak-builtins-remote-list.c:51
#: app/flatpak-builtins-remote-ls.c:68 app/flatpak-builtins-search.c:44
#, fuzzy
msgid "Show the name"
msgstr "Mostrar só os runtimes"

#: app/flatpak-builtins-list.c:60 app/flatpak-builtins-remote-list.c:60
#: app/flatpak-builtins-remote-ls.c:69 app/flatpak-builtins-search.c:45
#, fuzzy
msgid "Description"
msgstr "Descrición completa"

#: app/flatpak-builtins-list.c:60 app/flatpak-builtins-remote-ls.c:69
#: app/flatpak-builtins-search.c:45
#, fuzzy
msgid "Show the description"
msgstr "ID de colección"

#: app/flatpak-builtins-list.c:61 app/flatpak-builtins-remote-ls.c:70
#: app/flatpak-builtins-search.c:46
#, fuzzy
msgid "Application ID"
msgstr "ID de colección"

#: app/flatpak-builtins-list.c:61 app/flatpak-builtins-ps.c:52
#: app/flatpak-builtins-remote-ls.c:70 app/flatpak-builtins-search.c:46
#, fuzzy
msgid "Show the application ID"
msgstr "ID de colección"

#: app/flatpak-builtins-list.c:62 app/flatpak-builtins-remote-ls.c:71
#: app/flatpak-builtins-search.c:47
#, fuzzy
msgid "Show the version"
msgstr "ID de colección"

#: app/flatpak-builtins-list.c:65 app/flatpak-builtins-ps.c:56
#: app/flatpak-builtins-remote-ls.c:77
msgid "Runtime"
msgstr "Runtime"

#: app/flatpak-builtins-list.c:65
#, fuzzy
msgid "Show the used runtime"
msgstr "Mostrar só os runtimes"

#: app/flatpak-builtins-list.c:66 app/flatpak-builtins-remote-ls.c:74
#, fuzzy
msgid "Show the origin remote"
msgstr "Mostrar orixe"

#: app/flatpak-builtins-list.c:67
#, fuzzy
msgid "Show the installation"
msgstr "Mostrar instalacións do usuario"

#: app/flatpak-builtins-list.c:69
msgid "Active commit"
msgstr "Remisión activa"

#: app/flatpak-builtins-list.c:69 app/flatpak-builtins-remote-ls.c:76
#, fuzzy
msgid "Show the active commit"
msgstr "Mostrar só os runtimes"

#: app/flatpak-builtins-list.c:70
msgid "Latest commit"
msgstr "Última remisión"

#: app/flatpak-builtins-list.c:70
#, fuzzy
msgid "Show the latest commit"
msgstr "Mostrar só os runtimes"

#: app/flatpak-builtins-list.c:71 app/flatpak-builtins-remote-ls.c:78
msgid "Installed size"
msgstr "Tamaño instalado"

#: app/flatpak-builtins-list.c:71 app/flatpak-builtins-remote-ls.c:78
#, fuzzy
msgid "Show the installed size"
msgstr "Tamaño instalado"

#: app/flatpak-builtins-list.c:72 app/flatpak-builtins-remote-list.c:58
#: app/flatpak-builtins-remote-ls.c:80 app/flatpak-builtins-repo.c:340
msgid "Options"
msgstr "Opcións"

#: app/flatpak-builtins-list.c:72 app/flatpak-builtins-remote-list.c:58
#: app/flatpak-builtins-remote-ls.c:80
#, fuzzy
msgid "Show options"
msgstr "Mostrar as opcións de axuda"

#: app/flatpak-builtins-list.c:180
#, fuzzy, c-format
msgid "Unable to load details of %s: %s"
msgstr "Actualizando os metadatos adicionais desde o resumo remoto para %s\n"

#: app/flatpak-builtins-list.c:190
#, fuzzy, c-format
msgid "Unable to inspect current version of %s: %s"
msgstr "Non foi posíbel crear a tubería de sincronización"

#: app/flatpak-builtins-list.c:408
msgid " - List installed apps and/or runtimes"
msgstr " - Lista as aplicacións instaladas ou runtimes"

#: app/flatpak-builtins-make-current.c:38
msgid "Arch to make current for"
msgstr "Arquitectura que facer a actual"

#: app/flatpak-builtins-make-current.c:58
msgid "APP BRANCH - Make branch of application current"
msgstr "APP RAMA - Facer actual a rama da aplicación"

#: app/flatpak-builtins-make-current.c:69 app/flatpak-builtins-run.c:260
msgid "APP must be specified"
msgstr "Debe especificar o APP"

#: app/flatpak-builtins-make-current.c:84
msgid "BRANCH must be specified"
msgstr "Debe especificar a RAMA"

#: app/flatpak-builtins-make-current.c:97
#, c-format
msgid "App %s branch %s is not installed"
msgstr "A aplicación %s rama %s non está instalada"

#: app/flatpak-builtins-mask.c:42
#, fuzzy
msgid "Remove matching masks"
msgstr "Sen remoto %s"

#: app/flatpak-builtins-mask.c:54
msgid ""
"[PATTERN…] - disable updates and automatic installation matching patterns"
msgstr ""

#: app/flatpak-builtins-mask.c:73
#, c-format
msgid "No masked patterns\n"
msgstr ""

#: app/flatpak-builtins-mask.c:78
#, c-format
msgid "Masked patterns:\n"
msgstr ""

#: app/flatpak-builtins-override.c:42
msgid "Remove existing overrides"
msgstr ""

#: app/flatpak-builtins-override.c:43
msgid "Show existing overrides"
msgstr ""

#: app/flatpak-builtins-override.c:59
msgid "[APP] - Override settings [for application]"
msgstr "APP - Sobrescribir as configuracións da aplicación"

#: app/flatpak-builtins-permission-list.c:143
msgid "[TABLE] [ID] - List permissions"
msgstr ""

#: app/flatpak-builtins-permission-list.c:179
#: app/flatpak-builtins-permission-show.c:142
msgid "Table"
msgstr ""

#: app/flatpak-builtins-permission-list.c:180
#: app/flatpak-builtins-permission-show.c:143
msgid "Object"
msgstr ""

#: app/flatpak-builtins-permission-list.c:181
#: app/flatpak-builtins-permission-show.c:144
msgid "App"
msgstr ""

#: app/flatpak-builtins-permission-list.c:183
#: app/flatpak-builtins-permission-show.c:146
msgid "Data"
msgstr ""

#: app/flatpak-builtins-permission-remove.c:120
msgid "TABLE ID [APP_ID] - Remove item from permission store"
msgstr "Revogarlle os permisos de escritura á aplicación"

#: app/flatpak-builtins-permission-remove.c:129
#: app/flatpak-builtins-permission-set.c:120
#, fuzzy
msgid "Too few arguments"
msgstr "Demasiados argumento"

#: app/flatpak-builtins-permission-reset.c:43
#, fuzzy
msgid "Reset all permissions"
msgstr "Mostrar extensións"

#: app/flatpak-builtins-permission-reset.c:144
msgid "APP_ID - Reset permissions for an app"
msgstr "Engadir permisos para esta aplicación"

#: app/flatpak-builtins-permission-reset.c:153
#: app/flatpak-builtins-permission-show.c:124
#, fuzzy
msgid "Wrong number of arguments"
msgstr "Demasiados argumento"

#: app/flatpak-builtins-permission-set.c:42
msgid "Associate DATA with the entry"
msgstr ""

#: app/flatpak-builtins-permission-set.c:42
msgid "DATA"
msgstr ""

#: app/flatpak-builtins-permission-set.c:111
msgid "TABLE ID APP_ID [PERMISSION...] - Set permissions"
msgstr ""

#: app/flatpak-builtins-permission-set.c:132
#, fuzzy, c-format
msgid "Failed to parse '%s' as GVariant: "
msgstr "Produciuse un fallo ao ler a remisión %s: "

#: app/flatpak-builtins-permission-show.c:115
msgid "APP_ID - Show permissions for an app"
msgstr "Engadir permisos para esta aplicación"

#: app/flatpak-builtins-pin.c:44
#, fuzzy
msgid "Remove matching pins"
msgstr "Sen remoto %s"

#: app/flatpak-builtins-pin.c:56
msgid "[PATTERN…] - disable automatic removal of runtimes matching patterns"
msgstr ""

#: app/flatpak-builtins-pin.c:75
#, c-format
msgid "No pinned patterns\n"
msgstr ""

#: app/flatpak-builtins-pin.c:80
#, c-format
msgid "Pinned patterns:\n"
msgstr ""

#: app/flatpak-builtins-preinstall.c:80
msgid "- Install flatpaks that are part of the operating system"
msgstr ""

#: app/flatpak-builtins-preinstall.c:118
#, fuzzy, c-format
msgid "Nothing to do.\n"
msgstr "Nada coincide con %s"

#: app/flatpak-builtins-ps.c:49
#, fuzzy
msgid "Instance"
msgstr "Instalado"

#: app/flatpak-builtins-ps.c:49
#, fuzzy
msgid "Show the instance ID"
msgstr "Mostrar só os runtimes"

#: app/flatpak-builtins-ps.c:50 app/flatpak-builtins-run.c:178
#, fuzzy
msgid "PID"
msgstr "APPID"

#: app/flatpak-builtins-ps.c:50
msgid "Show the PID of the wrapper process"
msgstr ""

#: app/flatpak-builtins-ps.c:51
msgid "Child-PID"
msgstr ""

#: app/flatpak-builtins-ps.c:51
msgid "Show the PID of the sandbox process"
msgstr ""

#: app/flatpak-builtins-ps.c:54 app/flatpak-builtins-search.c:48
#, fuzzy
msgid "Show the application branch"
msgstr "Mostrar arquitecturas e ramas"

#: app/flatpak-builtins-ps.c:55
#, fuzzy
msgid "Show the application commit"
msgstr "Mostrar as opcións de axuda"

#: app/flatpak-builtins-ps.c:56
#, fuzzy
msgid "Show the runtime ID"
msgstr "Mostrar só os runtimes"

#: app/flatpak-builtins-ps.c:57
msgid "R.-Branch"
msgstr "R.-Rama"

#: app/flatpak-builtins-ps.c:57
#, fuzzy
msgid "Show the runtime branch"
msgstr "Mostrar só os runtimes"

#: app/flatpak-builtins-ps.c:58
#, fuzzy
msgid "R.-Commit"
msgstr "Remisión"

#: app/flatpak-builtins-ps.c:58
#, fuzzy
msgid "Show the runtime commit"
msgstr "Mostrar só os runtimes"

#: app/flatpak-builtins-ps.c:59
#, fuzzy
msgid "Active"
msgstr "Remisión activa"

#: app/flatpak-builtins-ps.c:59
#, fuzzy
msgid "Show whether the app is active"
msgstr "Mostrar só os runtimes"

#: app/flatpak-builtins-ps.c:60
msgid "Background"
msgstr ""

#: app/flatpak-builtins-ps.c:60
#, fuzzy
msgid "Show whether the app is background"
msgstr "Mostrar só os runtimes"

#: app/flatpak-builtins-ps.c:246
msgid " - Enumerate running sandboxes"
msgstr ""

#: app/flatpak-builtins-remote-add.c:66
msgid "Do nothing if the provided remote exists"
msgstr "Non facer nada se o fornecedor remoto existe"

#: app/flatpak-builtins-remote-add.c:67
msgid "LOCATION specifies a configuration file, not the repo location"
msgstr ""
"LOCATION especifica o ficheiro de configuracion, non unha localización de "
"repositorio"

#: app/flatpak-builtins-remote-add.c:72 app/flatpak-builtins-remote-modify.c:78
msgid "Disable GPG verification"
msgstr "Desactivar a comprobación GPG"

#: app/flatpak-builtins-remote-add.c:73 app/flatpak-builtins-remote-modify.c:79
msgid "Mark the remote as don't enumerate"
msgstr "Marcar o reomoto como non enumerado"

#: app/flatpak-builtins-remote-add.c:74 app/flatpak-builtins-remote-modify.c:80
msgid "Mark the remote as don't use for deps"
msgstr "Estabelecer o remoto como non usado para as dependencias"

#: app/flatpak-builtins-remote-add.c:75 app/flatpak-builtins-remote-modify.c:81
msgid "Set priority (default 1, higher is more prioritized)"
msgstr ""
"Estabelecer prioridade (1 por omisión, máis prioridade canto máis alto)"

#: app/flatpak-builtins-remote-add.c:75 app/flatpak-builtins-remote-modify.c:81
msgid "PRIORITY"
msgstr "PRIORIDADE"

#: app/flatpak-builtins-remote-add.c:76
#, fuzzy
msgid "The named subset to use for this remote"
msgstr "Un nome bonito para usar neste repositorio remoto"

#: app/flatpak-builtins-remote-add.c:76 app/flatpak-builtins-remote-modify.c:71
msgid "SUBSET"
msgstr ""

#: app/flatpak-builtins-remote-add.c:77 app/flatpak-builtins-remote-modify.c:82
msgid "A nice name to use for this remote"
msgstr "Un nome bonito para usar neste repositorio remoto"

#: app/flatpak-builtins-remote-add.c:78 app/flatpak-builtins-remote-modify.c:83
#, fuzzy
msgid "A one-line comment for this remote"
msgstr "Un nome bonito para usar neste repositorio remoto"

#: app/flatpak-builtins-remote-add.c:79 app/flatpak-builtins-remote-modify.c:84
#, fuzzy
msgid "A full-paragraph description for this remote"
msgstr "Rama por omisión que usar neste repositorio remoto"

#: app/flatpak-builtins-remote-add.c:80 app/flatpak-builtins-remote-modify.c:85
#, fuzzy
msgid "URL for a website for this remote"
msgstr "Un nome bonito para usar neste repositorio remoto"

#: app/flatpak-builtins-remote-add.c:81 app/flatpak-builtins-remote-modify.c:86
#, fuzzy
msgid "URL for an icon for this remote"
msgstr "Rama por omisión que usar neste repositorio remoto"

#: app/flatpak-builtins-remote-add.c:82 app/flatpak-builtins-remote-modify.c:87
msgid "Default branch to use for this remote"
msgstr "Rama por omisión que usar neste repositorio remoto"

#: app/flatpak-builtins-remote-add.c:84 app/flatpak-builtins-remote-modify.c:89
msgid "Import GPG key from FILE (- for stdin)"
msgstr "Importar a chave GPG desde o FICHEIRO (- para stdin)"

#: app/flatpak-builtins-remote-add.c:85 app/flatpak-builtins-remote-modify.c:90
msgid "Load signatures from URL"
msgstr ""

#: app/flatpak-builtins-remote-add.c:86 app/flatpak-builtins-remote-modify.c:92
msgid "Set path to local filter FILE"
msgstr ""

#: app/flatpak-builtins-remote-add.c:87 app/flatpak-builtins-remote-modify.c:93
msgid "Disable the remote"
msgstr "Desactivar o repositorio remoto"

#: app/flatpak-builtins-remote-add.c:88 app/flatpak-builtins-remote-modify.c:94
msgid "Name of authenticator"
msgstr ""

#: app/flatpak-builtins-remote-add.c:90 app/flatpak-builtins-remote-modify.c:96
msgid "Autoinstall authenticator"
msgstr "Autoinstalar autenticador"

#: app/flatpak-builtins-remote-add.c:91 app/flatpak-builtins-remote-modify.c:97
#, fuzzy
msgid "Don't autoinstall authenticator"
msgstr "Non desinstalar as referencias relacionadas"

#: app/flatpak-builtins-remote-add.c:92 app/flatpak-builtins-remote-modify.c:99
msgid "Don't follow the redirect set in the summary file"
msgstr ""

#: app/flatpak-builtins-remote-add.c:261 app/flatpak-builtins-remote-add.c:268
#, c-format
msgid "Can't load uri %s: %s\n"
msgstr ""

#: app/flatpak-builtins-remote-add.c:276 common/flatpak-dir.c:4643
#, c-format
msgid "Can't load file %s: %s\n"
msgstr "Non é posíbel cargar o ficheiro %s: %s\n"

#: app/flatpak-builtins-remote-add.c:304
msgid "NAME LOCATION - Add a remote repository"
msgstr "NOME LOCALIZACION - Engade un novo repositorio remoto"

#: app/flatpak-builtins-remote-add.c:331
msgid "GPG verification is required if collections are enabled"
msgstr "A comprobación GPG é obrigatoria se as coleccións están activadas"

#: app/flatpak-builtins-remote-add.c:393
#, c-format
msgid "Remote %s already exists"
msgstr "O repositorio remoto %s xa existe"

#: app/flatpak-builtins-remote-add.c:405
#: app/flatpak-builtins-remote-modify.c:340
#, c-format
msgid "Invalid authenticator name %s"
msgstr "Nome de autenticador %s non válido"

#: app/flatpak-builtins-remote-add.c:422
#, c-format
msgid "Warning: Could not update extra metadata for '%s': %s\n"
msgstr ""
"Aviso: Non se puideron actualizar os metadatos adicionais para «%s»: %s\n"

#: app/flatpak-builtins-remote-delete.c:39
msgid "Remove remote even if in use"
msgstr "Eliminar remoto incluso se está en uso"

#: app/flatpak-builtins-remote-delete.c:53
msgid "NAME - Delete a remote repository"
msgstr "NOME - Eliminar un repositorio remoto"

#: app/flatpak-builtins-remote-delete.c:100
#, c-format
msgid "The following refs are installed from remote '%s':"
msgstr ""

#: app/flatpak-builtins-remote-delete.c:101
msgid "Remove them?"
msgstr ""

#: app/flatpak-builtins-remote-delete.c:103
#, c-format
msgid "Can't remove remote '%s' with installed refs"
msgstr ""

#: app/flatpak-builtins-remote-info.c:55
msgid "Commit to show info for"
msgstr ""

#: app/flatpak-builtins-remote-info.c:58
msgid "Display log"
msgstr ""

#: app/flatpak-builtins-remote-info.c:61
#, fuzzy
msgid "Show parent"
msgstr "Mostrar referencia"

#: app/flatpak-builtins-remote-info.c:65 app/flatpak-builtins-remote-ls.c:60
msgid "Use local caches even if they are stale"
msgstr ""

#. Translators: A sideload is when you install from a local USB drive rather than the Internet.
#: app/flatpak-builtins-remote-info.c:67 app/flatpak-builtins-remote-ls.c:62
msgid "Only list refs available as sideloads"
msgstr ""

#: app/flatpak-builtins-remote-info.c:114
msgid ""
" REMOTE REF - Show information about an application or runtime in a remote"
msgstr ""

#: app/flatpak-builtins-remote-info.c:125
msgid "REMOTE and REF must be specified"
msgstr "Debe especificar REMOTO e REF"

#: app/flatpak-builtins-remote-info.c:247
#: app/flatpak-builtins-remote-info.c:282
#, fuzzy
msgid "Download Size:"
msgstr "Tamaño de descarga"

#: app/flatpak-builtins-remote-info.c:267
#: app/flatpak-builtins-remote-info.c:325
#, fuzzy
msgid "History:"
msgstr "Mostrar remisión"

#: app/flatpak-builtins-remote-info.c:348
#, fuzzy
msgid " Commit:"
msgstr "Remisión:"

#: app/flatpak-builtins-remote-info.c:349
msgid " Subject:"
msgstr ""

#: app/flatpak-builtins-remote-info.c:350
msgid " Date:"
msgstr ""

#: app/flatpak-builtins-remote-info.c:383
#, c-format
msgid "Warning: Commit %s has no flatpak metadata\n"
msgstr ""

#: app/flatpak-builtins-remote-list.c:43
msgid "Show remote details"
msgstr "Mostrar información do remoto"

#: app/flatpak-builtins-remote-list.c:44
msgid "Show disabled remotes"
msgstr "Mostrar remotos desactivados"

#: app/flatpak-builtins-remote-list.c:52
msgid "Title"
msgstr "Título"

#: app/flatpak-builtins-remote-list.c:52
#, fuzzy
msgid "Show the title"
msgstr "Mostrar só os runtimes"

#: app/flatpak-builtins-remote-list.c:53
#, fuzzy
msgid "Show the URL"
msgstr "Mostrar referencia"

#: app/flatpak-builtins-remote-list.c:54
#, fuzzy
msgid "Show the collection ID"
msgstr "ID de colección"

#: app/flatpak-builtins-remote-list.c:55 app/flatpak-builtins-repo.c:392
msgid "Subset"
msgstr ""

#: app/flatpak-builtins-remote-list.c:55
#, fuzzy
msgid "Show the subset"
msgstr "Mostrar referencia"

#: app/flatpak-builtins-remote-list.c:56
msgid "Filter"
msgstr ""

#: app/flatpak-builtins-remote-list.c:56
#, fuzzy
msgid "Show filter file"
msgstr "Mostrar só os runtimes"

#: app/flatpak-builtins-remote-list.c:57
msgid "Priority"
msgstr "Prioridade"

#: app/flatpak-builtins-remote-list.c:57
#, fuzzy
msgid "Show the priority"
msgstr "Mostrar só os runtimes"

#: app/flatpak-builtins-remote-list.c:59
#, fuzzy
msgid "Comment"
msgstr "Remisión"

#: app/flatpak-builtins-remote-list.c:59
#, fuzzy
msgid "Show comment"
msgstr "Mostrar remisión"

#: app/flatpak-builtins-remote-list.c:60
#, fuzzy
msgid "Show description"
msgstr "ID de colección"

#: app/flatpak-builtins-remote-list.c:61
msgid "Homepage"
msgstr ""

#: app/flatpak-builtins-remote-list.c:61
#, fuzzy
msgid "Show homepage"
msgstr "Mostrar só os runtimes"

#: app/flatpak-builtins-remote-list.c:62
msgid "Icon"
msgstr ""

#: app/flatpak-builtins-remote-list.c:62
#, fuzzy
msgid "Show icon"
msgstr "Mostrar as opcións de axuda"

#: app/flatpak-builtins-remote-list.c:231
msgid " - List remote repositories"
msgstr " - Lista os repositorios remotos"

#: app/flatpak-builtins-remote-ls.c:52
msgid "Show arches and branches"
msgstr "Mostrar arquitecturas e ramas"

#: app/flatpak-builtins-remote-ls.c:53
msgid "Show only runtimes"
msgstr "Mostrar só os runtimes"

#: app/flatpak-builtins-remote-ls.c:54
msgid "Show only apps"
msgstr "Mostrar só as aplicacións"

#: app/flatpak-builtins-remote-ls.c:55
msgid "Show only those where updates are available"
msgstr "Mostrar só aqueles para os que haxa actualizacións"

#: app/flatpak-builtins-remote-ls.c:56
msgid "Limit to this arch (* for all)"
msgstr "Limitar a esta arquitectura (* para todas)"

#: app/flatpak-builtins-remote-ls.c:77
#, fuzzy
msgid "Show the runtime"
msgstr "Mostrar só os runtimes"

#: app/flatpak-builtins-remote-ls.c:79
msgid "Download size"
msgstr "Tamaño de descarga"

#: app/flatpak-builtins-remote-ls.c:79
#, fuzzy
msgid "Show the download size"
msgstr "Tamaño de descarga"

#: app/flatpak-builtins-remote-ls.c:391
#, fuzzy
msgid " [REMOTE or URI] - Show available runtimes and applications"
msgstr " REMOTO - Mostrar os runtimes e aplicacións dispoñíbeis"

#: app/flatpak-builtins-remote-modify.c:67
msgid "Enable GPG verification"
msgstr "Activar comprobación GPG"

#: app/flatpak-builtins-remote-modify.c:68
msgid "Mark the remote as enumerate"
msgstr "Marcar o remoto como enumerado"

#: app/flatpak-builtins-remote-modify.c:69
msgid "Mark the remote as used for dependencies"
msgstr "Estabelecer o remoto como usado polas dependencias"

#: app/flatpak-builtins-remote-modify.c:70
#, fuzzy
msgid "Set a new URL"
msgstr "Estabelecer unha nova url"

#: app/flatpak-builtins-remote-modify.c:71
#, fuzzy
msgid "Set a new subset to use"
msgstr "Estabelecer unha nova url"

#: app/flatpak-builtins-remote-modify.c:72
msgid "Enable the remote"
msgstr "Activar o repositorio remoto"

#: app/flatpak-builtins-remote-modify.c:73
msgid "Update extra metadata from the summary file"
msgstr "Actualizar os metadatos adicionais desde o ficheiro de resumo"

#: app/flatpak-builtins-remote-modify.c:91
msgid "Disable local filter"
msgstr ""

#: app/flatpak-builtins-remote-modify.c:95
#, fuzzy
msgid "Authenticator options"
msgstr "Mostrar as opcións de axuda"

#: app/flatpak-builtins-remote-modify.c:98
#, fuzzy
msgid "Follow the redirect set in the summary file"
msgstr "Actualizar os metadatos adicionais desde o ficheiro de resumo"

#: app/flatpak-builtins-remote-modify.c:306
msgid "NAME - Modify a remote repository"
msgstr "NOME - Modificar un repositorio remoto"

#: app/flatpak-builtins-remote-modify.c:316
msgid "Remote NAME must be specified"
msgstr "Debe especifciar o NOME do repositorio remoto"

#: app/flatpak-builtins-remote-modify.c:327
#, c-format
msgid "Updating extra metadata from remote summary for %s\n"
msgstr "Actualizando os metadatos adicionais desde o resumo remoto para %s\n"

#: app/flatpak-builtins-remote-modify.c:330
#, c-format
msgid "Error updating extra metadata for '%s': %s\n"
msgstr ""
"Produciuse un erro ao actualizar os metadatos adicionais para «%s»: %s\n"

#: app/flatpak-builtins-remote-modify.c:331
#, c-format
msgid "Could not update extra metadata for %s"
msgstr "Non se puido actualizar os metadatos adicionais para %s"

#: app/flatpak-builtins-repair.c:43
msgid "Don't make any changes"
msgstr ""

#: app/flatpak-builtins-repair.c:44
msgid "Reinstall all refs"
msgstr "Reinstalar todas as referencias"

#: app/flatpak-builtins-repair.c:68
#, c-format
msgid "Object missing: %s.%s\n"
msgstr ""

#: app/flatpak-builtins-repair.c:76
#, c-format
msgid "Object invalid: %s.%s\n"
msgstr ""

#: app/flatpak-builtins-repair.c:81
#, c-format
msgid "%s, deleting object\n"
msgstr ""

#: app/flatpak-builtins-repair.c:146
#, fuzzy, c-format
msgid "Can't load object %s: %s\n"
msgstr "Non é posíbel abrir o espazo de nomes %s: %s"

#: app/flatpak-builtins-repair.c:228
#, fuzzy, c-format
msgid "Commit invalid %s: %s\n"
msgstr "PID %s non válido"

#: app/flatpak-builtins-repair.c:231
#, fuzzy, c-format
msgid "Deleting invalid commit %s: %s\n"
msgstr "Referencia de remisión %s non válida: "

#: app/flatpak-builtins-repair.c:261
#, c-format
msgid "Commit should be marked partial: %s\n"
msgstr ""

#: app/flatpak-builtins-repair.c:264
#, c-format
msgid "Marking commit as partial: %s\n"
msgstr ""

#: app/flatpak-builtins-repair.c:293
#, fuzzy, c-format
msgid "Problems loading data for %s: %s\n"
msgstr "Actualizando appstream para o remoto %s\n"

#: app/flatpak-builtins-repair.c:306
#, fuzzy, c-format
msgid "Error reinstalling %s: %s\n"
msgstr "Instalando: %s\n"

#: app/flatpak-builtins-repair.c:327
#, fuzzy
msgid "- Repair a flatpak installation"
msgstr "Mostrar instalacións do usuario"

#: app/flatpak-builtins-repair.c:406
#, fuzzy, c-format
msgid "Removing non-deployed ref %s…\n"
msgstr "Referencia %s despregada non válida: "

#: app/flatpak-builtins-repair.c:411
#, fuzzy, c-format
msgid "Skipping non-deployed ref %s…\n"
msgstr "Referencia %s despregada non válida: "

#: app/flatpak-builtins-repair.c:429
#, c-format
msgid "[%d/%d] Verifying %s…\n"
msgstr ""

#: app/flatpak-builtins-repair.c:435
#, c-format
msgid "Dry run: "
msgstr ""

#: app/flatpak-builtins-repair.c:440
#, c-format
msgid "Deleting ref %s due to missing objects\n"
msgstr ""

#: app/flatpak-builtins-repair.c:444
#, c-format
msgid "Deleting ref %s due to invalid objects\n"
msgstr ""

#: app/flatpak-builtins-repair.c:448
#, c-format
msgid "Deleting ref %s due to %d\n"
msgstr ""

#: app/flatpak-builtins-repair.c:464
#, c-format
msgid "Checking remotes...\n"
msgstr ""

#: app/flatpak-builtins-repair.c:482
#, c-format
msgid "Remote %s for ref %s is missing\n"
msgstr ""

#: app/flatpak-builtins-repair.c:484
#, c-format
msgid "Remote %s for ref %s is disabled\n"
msgstr ""

#: app/flatpak-builtins-repair.c:490
#, fuzzy, c-format
msgid "Pruning objects\n"
msgstr "Limpar obxectos non usados"

#: app/flatpak-builtins-repair.c:498
#, fuzzy, c-format
msgid "Erasing .removed\n"
msgstr "Non instalar referencias relacionadas"

#: app/flatpak-builtins-repair.c:524
#, fuzzy, c-format
msgid "Reinstalling refs\n"
msgstr "Non instalar referencias relacionadas"

#: app/flatpak-builtins-repair.c:526
#, fuzzy, c-format
msgid "Reinstalling removed refs\n"
msgstr "Non instalar referencias relacionadas"

#: app/flatpak-builtins-repair.c:551
#, fuzzy, c-format
msgid "While removing appstream for %s: "
msgstr "Ao abrir o repositorio %s: "

#: app/flatpak-builtins-repair.c:558
#, fuzzy, c-format
msgid "While deploying appstream for %s: "
msgstr "Ao abrir o repositorio %s: "

#: app/flatpak-builtins-repo.c:106
#, c-format
msgid "Repo mode: %s\n"
msgstr ""

#: app/flatpak-builtins-repo.c:113
#, c-format
msgid "Indexed summaries: %s\n"
msgstr ""

#: app/flatpak-builtins-repo.c:113 app/flatpak-builtins-repo.c:139
#: app/flatpak-builtins-repo.c:172
msgid "true"
msgstr ""

#: app/flatpak-builtins-repo.c:113 app/flatpak-builtins-repo.c:139
#: app/flatpak-builtins-repo.c:172
msgid "false"
msgstr ""

#: app/flatpak-builtins-repo.c:121
#, c-format
msgid "Subsummaries: "
msgstr ""

#: app/flatpak-builtins-repo.c:136
#, c-format
msgid "Cache version: %d\n"
msgstr ""

#: app/flatpak-builtins-repo.c:139
#, c-format
msgid "Indexed deltas: %s\n"
msgstr ""

#: app/flatpak-builtins-repo.c:142
#, fuzzy, c-format
msgid "Title: %s\n"
msgstr "Título"

#: app/flatpak-builtins-repo.c:145
#, fuzzy, c-format
msgid "Comment: %s\n"
msgstr "Remisión:"

#: app/flatpak-builtins-repo.c:148
#, fuzzy, c-format
msgid "Description: %s\n"
msgstr "Descrición completa"

#: app/flatpak-builtins-repo.c:151
#, c-format
msgid "Homepage: %s\n"
msgstr ""

#: app/flatpak-builtins-repo.c:154
#, fuzzy, c-format
msgid "Icon: %s\n"
msgstr "Remisión:"

#: app/flatpak-builtins-repo.c:157
#, fuzzy, c-format
msgid "Collection ID: %s\n"
msgstr "ID de colección"

#: app/flatpak-builtins-repo.c:160
#, c-format
msgid "Default branch: %s\n"
msgstr ""

#: app/flatpak-builtins-repo.c:163
#, c-format
msgid "Redirect URL: %s\n"
msgstr ""

#: app/flatpak-builtins-repo.c:166
#, fuzzy, c-format
msgid "Deploy collection ID: %s\n"
msgstr "ID de colección"

#: app/flatpak-builtins-repo.c:169
#, fuzzy, c-format
msgid "Authenticator name: %s\n"
msgstr "Nome de dbus %s non válido\n"

#: app/flatpak-builtins-repo.c:172
#, fuzzy, c-format
msgid "Authenticator install: %s\n"
msgstr "Mostrar as opcións de axuda"

#: app/flatpak-builtins-repo.c:180
#, c-format
msgid "GPG key hash: %s\n"
msgstr ""

#: app/flatpak-builtins-repo.c:184
#, c-format
msgid "%zd summary branches\n"
msgstr ""

#: app/flatpak-builtins-repo.c:336
msgid "Installed"
msgstr "Instalado"

#. Translators: Download is used here as a noun
#: app/flatpak-builtins-repo.c:338 app/flatpak-cli-transaction.c:1462
msgid "Download"
msgstr "Descargar"

#: app/flatpak-builtins-repo.c:339
msgid "Subsets"
msgstr ""

#: app/flatpak-builtins-repo.c:393
msgid "Digest"
msgstr ""

#: app/flatpak-builtins-repo.c:394
#, fuzzy
msgid "History length"
msgstr "Mostrar remisión"

#: app/flatpak-builtins-repo.c:711
msgid "Print general information about the repository"
msgstr "Imprimir a información xeral sobre o repositorio"

#: app/flatpak-builtins-repo.c:712
msgid "List the branches in the repository"
msgstr "Mostra as ramas no repositorio"

#: app/flatpak-builtins-repo.c:713
msgid "Print metadata for a branch"
msgstr "Imprime os metadatos para unha rama"

#: app/flatpak-builtins-repo.c:714
#, fuzzy
msgid "Show commits for a branch"
msgstr "Mostrar arquitecturas e ramas"

#: app/flatpak-builtins-repo.c:715
#, fuzzy
msgid "Print information about the repo subsets"
msgstr "Imprimir a información xeral sobre o repositorio"

#: app/flatpak-builtins-repo.c:716
msgid "Limit information to subsets with this prefix"
msgstr ""

#: app/flatpak-builtins-repo.c:732
msgid "LOCATION - Repository maintenance"
msgstr "LOCALIZACION - Mantemento do repositorio"

#: app/flatpak-builtins-run.c:159
msgid "Command to run"
msgstr "Orde a executar"

#: app/flatpak-builtins-run.c:160
msgid "Directory to run the command in"
msgstr ""

#: app/flatpak-builtins-run.c:161
msgid "Branch to use"
msgstr "Rama a usar"

#: app/flatpak-builtins-run.c:162
msgid "Use development runtime"
msgstr "Usar runtime de desenvolvemento"

#: app/flatpak-builtins-run.c:163
msgid "Runtime to use"
msgstr "Runtime a usar"

#: app/flatpak-builtins-run.c:164
msgid "Runtime version to use"
msgstr "Versión do runtime a usar"

#: app/flatpak-builtins-run.c:167
msgid "Log accessibility bus calls"
msgstr "Rexistrar chamadas ao bus de accesibilidade"

#: app/flatpak-builtins-run.c:168
#, fuzzy
msgid "Don't proxy accessibility bus calls"
msgstr "Rexistrar chamadas ao bus de accesibilidade"

#: app/flatpak-builtins-run.c:169
msgid "Proxy accessibility bus calls (default except when sandboxed)"
msgstr ""

#: app/flatpak-builtins-run.c:170
#, fuzzy
msgid "Don't proxy session bus calls"
msgstr "Rexistrar chamadas ao bus de accesibilidade"

#: app/flatpak-builtins-run.c:171
msgid "Proxy session bus calls (default except when sandboxed)"
msgstr ""

#: app/flatpak-builtins-run.c:172
#, fuzzy
msgid "Don't start portals"
msgstr "Non usar deltas estáticos"

#: app/flatpak-builtins-run.c:173
msgid "Enable file forwarding"
msgstr "Activar redirección de ficheiro"

#: app/flatpak-builtins-run.c:174
#, fuzzy
msgid "Run specified commit"
msgstr "Remisión activa"

#: app/flatpak-builtins-run.c:175
#, fuzzy
msgid "Use specified runtime commit"
msgstr "Actualizar runtime asinado"

#: app/flatpak-builtins-run.c:176
msgid "Run completely sandboxed"
msgstr ""

#: app/flatpak-builtins-run.c:178
msgid "Use PID as parent pid for sharing namespaces"
msgstr ""

#: app/flatpak-builtins-run.c:179
msgid "Make processes visible in parent namespace"
msgstr ""

#: app/flatpak-builtins-run.c:180
msgid "Share process ID namespace with parent"
msgstr ""

#: app/flatpak-builtins-run.c:181
msgid "Write the instance ID to the given file descriptor"
msgstr ""

#: app/flatpak-builtins-run.c:182
msgid "Use PATH instead of the app's /app"
msgstr ""

#: app/flatpak-builtins-run.c:183
msgid "Use FD instead of the app's /app"
msgstr ""

#: app/flatpak-builtins-run.c:183 app/flatpak-builtins-run.c:185
#: app/flatpak-builtins-run.c:187 app/flatpak-builtins-run.c:188
#: common/flatpak-context.c:2672
msgid "FD"
msgstr ""

#: app/flatpak-builtins-run.c:184
msgid "Use PATH instead of the runtime's /usr"
msgstr ""

#: app/flatpak-builtins-run.c:185
msgid "Use FD instead of the runtime's /usr"
msgstr ""

#: app/flatpak-builtins-run.c:186
#, fuzzy
msgid "Clear all outside environment variables"
msgstr "Estabelecer variábel de ambiente"

#: app/flatpak-builtins-run.c:187
msgid ""
"Bind mount the file or directory referred to by FD to its canonicalized path"
msgstr ""

#: app/flatpak-builtins-run.c:188
msgid ""
"Bind mount the file or directory referred to by FD read-only to its "
"canonicalized path"
msgstr ""

#: app/flatpak-builtins-run.c:219
#, fuzzy
msgid "APP [ARGUMENT…] - Run an app"
msgstr "APP [argumentos...] - Executa unha aplicación"

#: app/flatpak-builtins-run.c:370
#, fuzzy, c-format
msgid "runtime/%s/%s/%s not installed"
msgstr "%s %s non está instalado"

#: app/flatpak-builtins-run.c:419
msgid "app-fd and app-path cannot both be used"
msgstr ""

#: app/flatpak-builtins-run.c:449
msgid "usr-fd and usr-path cannot both be used"
msgstr ""

#: app/flatpak-builtins-search.c:37
#, fuzzy
msgid "Arch to search for"
msgstr "Arquitectura para a que instalar"

#: app/flatpak-builtins-search.c:49
#, fuzzy
msgid "Remotes"
msgstr "Sen remoto %s"

#: app/flatpak-builtins-search.c:49
#, fuzzy
msgid "Show the remotes"
msgstr "Mostrar remotos desactivados"

#: app/flatpak-builtins-search.c:244
msgid "TEXT - Search remote apps/runtimes for text"
msgstr ""

#: app/flatpak-builtins-search.c:255
#, fuzzy
msgid "TEXT must be specified"
msgstr "Debe especificar o NOME"

#: app/flatpak-builtins-search.c:338
#, fuzzy
msgid "No matches found"
msgstr "Nada coincide con %s"

#: app/flatpak-builtins-uninstall.c:54
msgid "Arch to uninstall"
msgstr "Arquitectura a desinstalar"

#: app/flatpak-builtins-uninstall.c:55
msgid "Keep ref in local repository"
msgstr "Manter referencia no repositorio local"

#: app/flatpak-builtins-uninstall.c:56
msgid "Don't uninstall related refs"
msgstr "Non desinstalar as referencias relacionadas"

#: app/flatpak-builtins-uninstall.c:57
msgid "Remove files even if running"
msgstr "Eliminar os ficheiros incluso se está en execución"

#: app/flatpak-builtins-uninstall.c:60
msgid "Uninstall all"
msgstr "Desinstalar todo"

#: app/flatpak-builtins-uninstall.c:61
#, fuzzy
msgid "Uninstall unused"
msgstr "Desinstalar paquete"

#: app/flatpak-builtins-uninstall.c:62
msgid "Delete app data"
msgstr ""

#: app/flatpak-builtins-uninstall.c:141
#, c-format
msgid "Delete data for %s?"
msgstr ""

#: app/flatpak-builtins-uninstall.c:220
#, c-format
msgid "Info: applications using the extension %s%s%s branch %s%s%s:\n"
msgstr ""

#: app/flatpak-builtins-uninstall.c:223
#, fuzzy, c-format
msgid "Info: applications using the runtime %s%s%s branch %s%s%s:\n"
msgstr ""
"\n"
"Buscando aplicacións e «runtimes»"

#: app/flatpak-builtins-uninstall.c:238
#, fuzzy
msgid "Really remove?"
msgstr "Sen remoto %s"

#: app/flatpak-builtins-uninstall.c:255
#, fuzzy
msgid "[REF…] - Uninstall applications or runtimes"
msgstr "[REF...] - Actualizar aplicacións ou runtimes"

#: app/flatpak-builtins-uninstall.c:264
#, fuzzy
msgid "Must specify at least one REF, --unused, --all or --delete-data"
msgstr "Debe especificar cando menos unha vez a REF"

#: app/flatpak-builtins-uninstall.c:267
msgid "Must not specify REFs when using --all"
msgstr ""

#: app/flatpak-builtins-uninstall.c:270
msgid "Must not specify REFs when using --unused"
msgstr ""

#: app/flatpak-builtins-uninstall.c:336
#, c-format
msgid ""
"\n"
"These runtimes in installation '%s' are pinned and won't be removed; see "
"flatpak-pin(1):\n"
msgstr ""

#: app/flatpak-builtins-uninstall.c:370
#, fuzzy, c-format
msgid "Nothing unused to uninstall\n"
msgstr "Arquitectura a desinstalar"

#: app/flatpak-builtins-uninstall.c:444
#, fuzzy, c-format
msgid "No installed refs found for ‘%s’"
msgstr "Non se atopou ningunha sobrescritura para %s"

#: app/flatpak-builtins-uninstall.c:447
#, c-format
msgid " with arch ‘%s’"
msgstr ""

#: app/flatpak-builtins-uninstall.c:449
#, c-format
msgid " with branch ‘%s’"
msgstr ""

#: app/flatpak-builtins-uninstall.c:456
#, fuzzy, c-format
msgid "Warning: %s is not installed\n"
msgstr "%s rama %s non está instalado"

#: app/flatpak-builtins-uninstall.c:490
#, c-format
msgid "None of the specified refs are installed"
msgstr ""

#: app/flatpak-builtins-uninstall.c:599
#, c-format
msgid "No app data to delete\n"
msgstr ""

#: app/flatpak-builtins-update.c:56
msgid "Arch to update for"
msgstr "Arquitectura para a que actualizar"

#: app/flatpak-builtins-update.c:57
msgid "Commit to deploy"
msgstr "Remisión a despregar"

#: app/flatpak-builtins-update.c:58
msgid "Remove old files even if running"
msgstr "Eliminar os ficheiros antigos incluso se está en execución"

#: app/flatpak-builtins-update.c:59
msgid "Don't pull, only update from local cache"
msgstr "Non facer «pull», só actualizar desde a caché local"

#: app/flatpak-builtins-update.c:61
msgid "Don't update related refs"
msgstr "Non actualiar as referencias relacionadas"

#: app/flatpak-builtins-update.c:66
msgid "Update appstream for remote"
msgstr "Actualizar appstream desde o remoto"

#: app/flatpak-builtins-update.c:67
msgid "Only update this subpath"
msgstr "Só actualizar esta subruta"

#: app/flatpak-builtins-update.c:90
#, fuzzy
msgid "[REF…] - Update applications or runtimes"
msgstr "[REF...] - Actualizar aplicacións ou runtimes"

#: app/flatpak-builtins-update.c:121
#, fuzzy
msgid "With --commit, only one REF may be specified"
msgstr "Debe especificar REMOTO e REF"

#: app/flatpak-builtins-update.c:162
#, fuzzy, c-format
msgid "Looking for updates…\n"
msgstr "Non hai actualizacións.\n"

#: app/flatpak-builtins-update.c:215
#, fuzzy, c-format
msgid "Unable to update %s: %s\n"
msgstr "Ao obter %s desde o remoto %s: "

#: app/flatpak-builtins-update.c:274
#, fuzzy, c-format
msgid "Nothing to update.\n"
msgstr "Nada coincide con %s"

#: app/flatpak-builtins-utils.c:337
#, c-format
msgid ""
"Remote ‘%s’ found in multiple installations, unable to proceed in non-"
"interactive mode"
msgstr ""

#: app/flatpak-builtins-utils.c:346
#, c-format
msgid "Remote ‘%s’ found in multiple installations:"
msgstr ""

#: app/flatpak-builtins-utils.c:347 app/flatpak-builtins-utils.c:442
#: app/flatpak-builtins-utils.c:538 app/flatpak-builtins-utils.c:540
#: app/flatpak-builtins-utils.c:598
#, fuzzy
msgid "Which do you want to use (0 to abort)?"
msgstr "Cal desexa instalar (0 para abortar)?"

#: app/flatpak-builtins-utils.c:349
#, c-format
msgid "No remote chosen to resolve ‘%s’ which exists in multiple installations"
msgstr ""

#: app/flatpak-builtins-utils.c:358
#, c-format
msgid ""
"Remote \"%s\" not found\n"
"Hint: Use flatpak remote-add to add a remote"
msgstr ""

#: app/flatpak-builtins-utils.c:364
#, fuzzy, c-format
msgid "Remote \"%s\" not found in the %s installation"
msgstr "Traballar nas instalacións de usuario"

#: app/flatpak-builtins-utils.c:404
#, c-format
msgid "Multiple refs match ‘%s’, unable to proceed in non-interactive mode"
msgstr ""

#. default to yes on Enter
#: app/flatpak-builtins-utils.c:430
#, c-format
msgid ""
"Found ref ‘%s’ in remote ‘%s’ (%s).\n"
"Use this ref?"
msgstr ""

#: app/flatpak-builtins-utils.c:434 app/flatpak-builtins-utils.c:444
#: app/flatpak-builtins-utils.c:522 app/flatpak-builtins-utils.c:543
#, c-format
msgid "No ref chosen to resolve matches for ‘%s’"
msgstr ""

#: app/flatpak-builtins-utils.c:440
#, c-format
msgid "Similar refs found for ‘%s’ in remote ‘%s’ (%s):"
msgstr ""

#: app/flatpak-builtins-utils.c:488
#, c-format
msgid ""
"Multiple installed refs match ‘%s’, unable to proceed in non-interactive mode"
msgstr ""

#. default to yes on Enter
#: app/flatpak-builtins-utils.c:518
#, c-format
msgid "Found installed ref ‘%s’ (%s). Is this correct?"
msgstr ""

#: app/flatpak-builtins-utils.c:534
#, c-format
msgid "All of the above"
msgstr ""

#: app/flatpak-builtins-utils.c:535
#, c-format
msgid "Similar installed refs found for ‘%s’:"
msgstr ""

#: app/flatpak-builtins-utils.c:579
#, c-format
msgid ""
"Multiple remotes have refs matching ‘%s’, unable to proceed in non-"
"interactive mode"
msgstr ""

#: app/flatpak-builtins-utils.c:597
#, c-format
msgid "Remotes found with refs similar to ‘%s’:"
msgstr ""

#: app/flatpak-builtins-utils.c:600
#, c-format
msgid "No remote chosen to resolve matches for ‘%s’"
msgstr ""

#: app/flatpak-builtins-utils.c:696 app/flatpak-builtins-utils.c:699
#, fuzzy, c-format
msgid "Updating appstream data for user remote %s"
msgstr "Actualizando appstream para o remoto %s\n"

#: app/flatpak-builtins-utils.c:706 app/flatpak-builtins-utils.c:709
#, fuzzy, c-format
msgid "Updating appstream data for remote %s"
msgstr "Actualizando appstream para o remoto %s\n"

#: app/flatpak-builtins-utils.c:717 app/flatpak-builtins-utils.c:719
#, fuzzy
msgid "Error updating"
msgstr ""
"Produciuse un erro ao actualizar os metadatos adicionais para «%s»: %s\n"

#: app/flatpak-builtins-utils.c:755
#, c-format
msgid "Remote \"%s\" not found"
msgstr ""

#: app/flatpak-builtins-utils.c:796
#, c-format
msgid "Ambiguous suffix: '%s'."
msgstr ""

#. Translators: don't translate the values
#: app/flatpak-builtins-utils.c:798 app/flatpak-builtins-utils.c:813
msgid "Possible values are :s[tart], :m[iddle], :e[nd] or :f[ull]"
msgstr ""

#: app/flatpak-builtins-utils.c:811
#, fuzzy, c-format
msgid "Invalid suffix: '%s'."
msgstr "PID %s non válido"

#: app/flatpak-builtins-utils.c:846
#, c-format
msgid "Ambiguous column: %s"
msgstr ""

#: app/flatpak-builtins-utils.c:859
#, fuzzy, c-format
msgid "Unknown column: %s"
msgstr "Orde descoñecida «%s»"

#: app/flatpak-builtins-utils.c:917
msgid "Available columns:\n"
msgstr ""

#: app/flatpak-builtins-utils.c:927
#, fuzzy
msgid "Show all columns"
msgstr "Mostrar as opcións de axuda"

#: app/flatpak-builtins-utils.c:928
#, fuzzy
msgid "Show available columns"
msgstr "Mostrar remotos desactivados"

#: app/flatpak-builtins-utils.c:931
msgid "Append :s[tart], :m[iddle], :e[nd] or :f[ull] to change ellipsization"
msgstr ""

#: app/flatpak-builtins-utils.c:1483
#, c-format
msgid "Unknown scheme in sideload location %s"
msgstr ""

#: app/flatpak-cli-transaction.c:96 app/flatpak-cli-transaction.c:102
#, fuzzy, c-format
msgid "Required runtime for %s (%s) found in remote %s\n"
msgstr "O runtime requirido para %s (%s) non instalado, buscando…\n"

#: app/flatpak-cli-transaction.c:104
#, fuzzy
msgid "Do you want to install it?"
msgstr "Cal desexa instalar (0 para abortar)?"

#: app/flatpak-cli-transaction.c:110
#, fuzzy, c-format
msgid "Required runtime for %s (%s) found in remotes:"
msgstr "O runtime requirido para %s (%s) non instalado, buscando…\n"

#: app/flatpak-cli-transaction.c:112
msgid "Which do you want to install (0 to abort)?"
msgstr "Cal desexa instalar (0 para abortar)?"

#: app/flatpak-cli-transaction.c:132
#, fuzzy, c-format
msgid "Configuring %s as new remote '%s'\n"
msgstr "Configurar %s como un novo remoto «%s»"

#. default to yes on Enter
#: app/flatpak-cli-transaction.c:139
#, c-format
msgid ""
"The remote '%s', referred to by '%s' at location %s contains additional "
"applications.\n"
"Should the remote be kept for future installations?"
msgstr ""
"O remoto «%s», referida por «%s» na localización %s contén aplicacións "
"adicionais.\n"
"Desexa instalar outras aplicacións desde aquí?"

#. default to yes on Enter
#: app/flatpak-cli-transaction.c:147
#, c-format
msgid ""
"The application %s depends on runtimes from:\n"
"  %s\n"
"Configure this as new remote '%s'"
msgstr ""
"Esta aplicación %s depende dos runtimes de:\n"
"  %s\n"
"Configure esta como o novo remoto «%s»"

#. Formatted size/remaining time in seconds
#: app/flatpak-cli-transaction.c:321
#, c-format
msgid "%s/s%s%s"
msgstr ""

#. Download progress percentage, use the appropriate
#. percent format for your language
#: app/flatpak-cli-transaction.c:359
#, c-format
msgid "%3d%%"
msgstr ""

#: app/flatpak-cli-transaction.c:414
#, fuzzy
msgid "Installing…"
msgstr "Instalado"

#: app/flatpak-cli-transaction.c:416
#, fuzzy, c-format
msgid "Installing %d/%d…"
msgstr "Instalando: %s\n"

#: app/flatpak-cli-transaction.c:421
msgid "Updating…"
msgstr ""

#: app/flatpak-cli-transaction.c:423
#, fuzzy, c-format
msgid "Updating %d/%d…"
msgstr "Actualizando: %s desde %s\n"

#: app/flatpak-cli-transaction.c:428
#, fuzzy
msgid "Uninstalling…"
msgstr "Instalando: %s\n"

#: app/flatpak-cli-transaction.c:430
#, fuzzy, c-format
msgid "Uninstalling %d/%d…"
msgstr "Instalando: %s\n"

#: app/flatpak-cli-transaction.c:496 app/flatpak-quiet-transaction.c:161
#, c-format
msgid "Info: %s was skipped"
msgstr ""

#: app/flatpak-cli-transaction.c:519
#, fuzzy, c-format
msgid "Warning: %s%s%s already installed"
msgstr "%s remisión %s xa instalado"

#: app/flatpak-cli-transaction.c:522
#, fuzzy, c-format
msgid "Error: %s%s%s already installed"
msgstr "%s remisión %s xa instalado"

#: app/flatpak-cli-transaction.c:528
#, fuzzy, c-format
msgid "Warning: %s%s%s not installed"
msgstr "%s rama %s non está instalado"

#: app/flatpak-cli-transaction.c:531
#, fuzzy, c-format
msgid "Error: %s%s%s not installed"
msgstr "%s %s non está instalado"

#: app/flatpak-cli-transaction.c:537
#, fuzzy, c-format
msgid "Warning: %s%s%s needs a later flatpak version"
msgstr "%s precisa unha versión de flatpak posterior (%s)"

#: app/flatpak-cli-transaction.c:540
#, fuzzy, c-format
msgid "Error: %s%s%s needs a later flatpak version"
msgstr "%s precisa unha versión de flatpak posterior (%s)"

#: app/flatpak-cli-transaction.c:546
msgid "Warning: Not enough disk space to complete this operation"
msgstr ""

#: app/flatpak-cli-transaction.c:548
msgid "Error: Not enough disk space to complete this operation"
msgstr ""

#: app/flatpak-cli-transaction.c:553
#, c-format
msgid "Warning: %s"
msgstr ""

#: app/flatpak-cli-transaction.c:555
#, fuzzy, c-format
msgid "Error: %s"
msgstr "erro:"

#: app/flatpak-cli-transaction.c:570
#, fuzzy, c-format
msgid "Failed to install %s%s%s: "
msgstr "Erro: fallou o %s %s: %s\n"

#: app/flatpak-cli-transaction.c:577
#, fuzzy, c-format
msgid "Failed to update %s%s%s: "
msgstr "Erro: fallou o %s %s: %s\n"

#: app/flatpak-cli-transaction.c:584
#, fuzzy, c-format
msgid "Failed to install bundle %s%s%s: "
msgstr "Erro: fallou o %s %s: %s\n"

#: app/flatpak-cli-transaction.c:591
#, fuzzy, c-format
msgid "Failed to uninstall %s%s%s: "
msgstr "Erro: fallou o %s %s: %s\n"

#: app/flatpak-cli-transaction.c:642
#, fuzzy, c-format
msgid "Authentication required for remote '%s'\n"
msgstr "Requírese autenticación para actualizar software"

#: app/flatpak-cli-transaction.c:643
msgid "Open browser?"
msgstr ""

#: app/flatpak-cli-transaction.c:699
#, c-format
msgid "Login required remote %s (realm %s)\n"
msgstr ""

#: app/flatpak-cli-transaction.c:704
msgid "Password"
msgstr ""

#. Only runtimes can be pinned
#: app/flatpak-cli-transaction.c:759
#, c-format
msgid ""
"\n"
"Info: (pinned) runtime %s%s%s branch %s%s%s is end-of-life, in favor of "
"%s%s%s branch %s%s%s\n"
msgstr ""

#: app/flatpak-cli-transaction.c:765
#, c-format
msgid ""
"\n"
"Info: runtime %s%s%s branch %s%s%s is end-of-life, in favor of %s%s%s branch "
"%s%s%s\n"
msgstr ""

#: app/flatpak-cli-transaction.c:768
#, c-format
msgid ""
"\n"
"Info: app %s%s%s branch %s%s%s is end-of-life, in favor of %s%s%s branch "
"%s%s%s\n"
msgstr ""

#. Only runtimes can be pinned
#: app/flatpak-cli-transaction.c:780
#, c-format
msgid ""
"\n"
"Info: (pinned) runtime %s%s%s branch %s%s%s is end-of-life, with reason:\n"
msgstr ""

#: app/flatpak-cli-transaction.c:786
#, c-format
msgid ""
"\n"
"Info: runtime %s%s%s branch %s%s%s is end-of-life, with reason:\n"
msgstr ""

#: app/flatpak-cli-transaction.c:789
#, c-format
msgid ""
"\n"
"Info: app %s%s%s branch %s%s%s is end-of-life, with reason:\n"
msgstr ""

#: app/flatpak-cli-transaction.c:963
#, fuzzy, c-format
msgid "Info: applications using this extension:\n"
msgstr ""
"\n"
"Buscando aplicacións e «runtimes»"

#: app/flatpak-cli-transaction.c:965
#, fuzzy, c-format
msgid "Info: applications using this runtime:\n"
msgstr ""
"\n"
"Buscando aplicacións e «runtimes»"

#: app/flatpak-cli-transaction.c:984
msgid "Replace?"
msgstr ""

#: app/flatpak-cli-transaction.c:987 app/flatpak-quiet-transaction.c:247
#, fuzzy, c-format
msgid "Updating to rebased version\n"
msgstr "Actualizando a rama de appstream\n"

#: app/flatpak-cli-transaction.c:1011
#, fuzzy, c-format
msgid "Failed to rebase %s to %s: "
msgstr "Erro: fallou o %s %s: %s\n"

#: app/flatpak-cli-transaction.c:1277
#, fuzzy, c-format
msgid "New %s%s%s permissions:"
msgstr "Mostrar extensións"

#: app/flatpak-cli-transaction.c:1279
#, fuzzy, c-format
msgid "%s%s%s permissions:"
msgstr "Mostrar extensións"

#: app/flatpak-cli-transaction.c:1343
msgid "Warning: "
msgstr ""

#. translators: This is short for operation, the title of a one-char column
#: app/flatpak-cli-transaction.c:1442
msgid "Op"
msgstr ""

#. Avoid resizing the download column too much,
#. * by making the title as long as typical content
#.
#: app/flatpak-cli-transaction.c:1458 app/flatpak-cli-transaction.c:1503
msgid "partial"
msgstr ""

#: app/flatpak-cli-transaction.c:1535
#, fuzzy
msgid "Proceed with these changes to the user installation?"
msgstr "Mostrar instalacións do usuario"

#: app/flatpak-cli-transaction.c:1537
#, fuzzy
msgid "Proceed with these changes to the system installation?"
msgstr "Mostrar instalacións do usuario"

#: app/flatpak-cli-transaction.c:1539
#, fuzzy, c-format
msgid "Proceed with these changes to the %s?"
msgstr "Mostrar instalacións do usuario"

#: app/flatpak-cli-transaction.c:1711
msgid "Changes complete."
msgstr ""

#: app/flatpak-cli-transaction.c:1713
msgid "Uninstall complete."
msgstr "Desinstalación completada."

#: app/flatpak-cli-transaction.c:1715
msgid "Installation complete."
msgstr "Instalación completada."

#: app/flatpak-cli-transaction.c:1717
msgid "Updates complete."
msgstr "Actualización completada."

#. For updates/!stop_on_first_error we already printed all errors so we make up
#. a different one.
#: app/flatpak-cli-transaction.c:1750
msgid "There were one or more errors"
msgstr ""

#. translators: please keep the leading space
#: app/flatpak-main.c:76
#, fuzzy
msgid " Manage installed applications and runtimes"
msgstr " Xestionar as aplicacións ou runtimes instalados"

#: app/flatpak-main.c:77
msgid "Install an application or runtime"
msgstr "Instalar unha aplicación ou runtime"

#: app/flatpak-main.c:78
msgid "Update an installed application or runtime"
msgstr "Actualizar unha aplicación ou runtime instalado"

#: app/flatpak-main.c:81
msgid "Uninstall an installed application or runtime"
msgstr "Desinstalar unha aplicación ou runtime instalado"

#: app/flatpak-main.c:84
msgid "Mask out updates and automatic installation"
msgstr ""

#: app/flatpak-main.c:85
msgid "Pin a runtime to prevent automatic removal"
msgstr ""

#: app/flatpak-main.c:86
msgid "List installed apps and/or runtimes"
msgstr "Mostrar as aplicacións e/ou runtimes instalados"

#: app/flatpak-main.c:87
msgid "Show info for installed app or runtime"
msgstr "Mostrar información para as aplicacións ou runtime instaladas"

#: app/flatpak-main.c:88
#, fuzzy
msgid "Show history"
msgstr "Mostrar remisión"

#: app/flatpak-main.c:89
#, fuzzy
msgid "Configure flatpak"
msgstr "Configurar remoto"

#: app/flatpak-main.c:90
#, fuzzy
msgid "Repair flatpak installation"
msgstr "Mostrar instalacións do usuario"

#: app/flatpak-main.c:91
msgid "Put applications or runtimes onto removable media"
msgstr ""

#: app/flatpak-main.c:92
msgid "Install flatpaks that are part of the operating system"
msgstr ""

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:95
#, fuzzy
msgid ""
"\n"
" Find applications and runtimes"
msgstr ""
"\n"
"Buscando aplicacións e «runtimes»"

#: app/flatpak-main.c:96
msgid "Search for remote apps/runtimes"
msgstr ""

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:99
#, fuzzy
msgid ""
"\n"
" Manage running applications"
msgstr ""
"\n"
" Aplicacións en execución"

#: app/flatpak-main.c:100
msgid "Run an application"
msgstr "Executa unha aplicación"

#: app/flatpak-main.c:101
msgid "Override permissions for an application"
msgstr "Sobrescribir permisos para unha aplicación"

#: app/flatpak-main.c:102
msgid "Specify default version to run"
msgstr "Especifica a versión por omisión a executar"

#: app/flatpak-main.c:103
msgid "Enter the namespace of a running application"
msgstr "Entrar no espazo de nomes dunha aplicación en execución"

#: app/flatpak-main.c:104
msgid "Enumerate running applications"
msgstr "Enumerar aplicacións en execución"

#: app/flatpak-main.c:105
msgid "Stop a running application"
msgstr "Deter unha aplicación en execución"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:108
msgid ""
"\n"
" Manage file access"
msgstr ""
"\n"
" Xestionar o acceso ao ficheiro"

#: app/flatpak-main.c:109
msgid "List exported files"
msgstr "Mostrar os ficheiros exportados"

#: app/flatpak-main.c:110
msgid "Grant an application access to a specific file"
msgstr "Darlle a unha aplicación acceso a un ficheiro específico"

#: app/flatpak-main.c:111
msgid "Revoke access to a specific file"
msgstr "Revogar acceso a un ficheiro específico"

#: app/flatpak-main.c:112
msgid "Show information about a specific file"
msgstr "Mostrar información sobre un ficheiro específico"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:116
msgid ""
"\n"
" Manage dynamic permissions"
msgstr ""
"\n"
"Xestionar os permisos dinámicos"

#: app/flatpak-main.c:117
#, fuzzy
msgid "List permissions"
msgstr "Mostrar extensións"

#: app/flatpak-main.c:118
msgid "Remove item from permission store"
msgstr "Revogarlle os permisos de escritura á aplicación"

#: app/flatpak-main.c:120
#, fuzzy
msgid "Set permissions"
msgstr "Mostrar extensións"

#: app/flatpak-main.c:121
#, fuzzy
msgid "Show app permissions"
msgstr "Mostrar extensións"

#: app/flatpak-main.c:122
#, fuzzy
msgid "Reset app permissions"
msgstr "Mostrar extensións"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:125
msgid ""
"\n"
" Manage remote repositories"
msgstr ""
"\n"
" Xestionar os repositorios remotos"

#: app/flatpak-main.c:126
msgid "List all configured remotes"
msgstr "Mostrar todos os remotos configurados"

#: app/flatpak-main.c:127
msgid "Add a new remote repository (by URL)"
msgstr "Engadir un repositorio remoto novo (por URL)"

#: app/flatpak-main.c:128
msgid "Modify properties of a configured remote"
msgstr "Modificar as propiedades dun remoto configurado"

#: app/flatpak-main.c:129
msgid "Delete a configured remote"
msgstr "Eliminar un remoto configurado"

#: app/flatpak-main.c:131
msgid "List contents of a configured remote"
msgstr "Mostrar os contidos dun remoto configurado"

#: app/flatpak-main.c:132
#, fuzzy
msgid "Show information about a remote app or runtime"
msgstr "Mostrar información para as aplicacións ou runtime instalados"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:135
msgid ""
"\n"
" Build applications"
msgstr ""
"\n"
" Construír aplicacións"

#: app/flatpak-main.c:136
msgid "Initialize a directory for building"
msgstr "Inicializar un directorio para a construción"

#: app/flatpak-main.c:137
msgid "Run a build command inside the build dir"
msgstr "Executar unha orde de construción dentro do directorio de construción"

#: app/flatpak-main.c:138
msgid "Finish a build dir for export"
msgstr "Rematar un directorio de construción para exportar"

#: app/flatpak-main.c:139
msgid "Export a build dir to a repository"
msgstr "Exportar un directorio de construción a un repositorio"

#: app/flatpak-main.c:140
#, fuzzy
msgid "Create a bundle file from a ref in a local repository"
msgstr "Crear un ficheiro empaquetado desde un directorio de construción"

#: app/flatpak-main.c:141
msgid "Import a bundle file"
msgstr "Importar un ficheiro empaquetado"

#: app/flatpak-main.c:142
msgid "Sign an application or runtime"
msgstr "Asinar unha aplicación ou runtime"

#: app/flatpak-main.c:143
msgid "Update the summary file in a repository"
msgstr "Actualizaar o ficheiro de resumo no repositorio"

#: app/flatpak-main.c:144
msgid "Create new commit based on existing ref"
msgstr "Crear nova remisión baseada na referencia existente"

#: app/flatpak-main.c:145
#, fuzzy
msgid "Show information about a repo"
msgstr "Imprimir información sobre un repositorio"

#: app/flatpak-main.c:162
#, fuzzy
msgid "Show debug information, -vv for more detail"
msgstr "Imprimir información de depuración durante o procesado da orde"

#: app/flatpak-main.c:163
#, fuzzy
msgid "Show OSTree debug information"
msgstr "Mostrar información adicional"

#: app/flatpak-main.c:169
msgid "Print version information and exit"
msgstr "Imprimir información da versión e saír"

#: app/flatpak-main.c:170
msgid "Print default arch and exit"
msgstr "Imprimir arquitectura por omisión e saír"

#: app/flatpak-main.c:171
msgid "Print supported arches and exit"
msgstr "Imprimir as arquitecturas compatíbeis e saír"

#: app/flatpak-main.c:172
msgid "Print active gl drivers and exit"
msgstr "Imprimir os controladores gl activos e saír"

#: app/flatpak-main.c:173
#, fuzzy
msgid "Print paths for system installations and exit"
msgstr "Imprimir información da versión e saír"

#: app/flatpak-main.c:174
msgid "Print the updated environment needed to run flatpaks"
msgstr ""

#: app/flatpak-main.c:175
msgid "Only include the system installation with --print-updated-env"
msgstr ""

#: app/flatpak-main.c:180
#, fuzzy
msgid "Work on the user installation"
msgstr "Traballar nas instalacións de usuario"

#: app/flatpak-main.c:181
#, fuzzy
msgid "Work on the system-wide installation (default)"
msgstr "Traballar nas instalacións a nivel de sistema (por omisión)"

#: app/flatpak-main.c:182
#, fuzzy
msgid "Work on a non-default system-wide installation"
msgstr "Traballar nunha instalación a nivel de sistema específica"

#: app/flatpak-main.c:212
msgid "Builtin Commands:"
msgstr "Ordes incrustadas:"

#: app/flatpak-main.c:298
#, c-format
msgid ""
"Note that the directories %s are not in the search path set by the "
"XDG_DATA_DIRS environment variable, so applications installed by Flatpak may "
"not appear on your desktop until the session is restarted."
msgstr ""

#: app/flatpak-main.c:312
#, c-format
msgid ""
"Note that the directory %s is not in the search path set by the "
"XDG_DATA_DIRS environment variable, so applications installed by Flatpak may "
"not appear on your desktop until the session is restarted."
msgstr ""

#: app/flatpak-main.c:381
msgid ""
"Refusing to operate under sudo with --user. Omit sudo to operate on the user "
"installation, or use a root shell to operate on the root user's installation."
msgstr ""

#: app/flatpak-main.c:453
msgid ""
"Multiple installations specified for a command that works on one installation"
msgstr ""

#: app/flatpak-main.c:504 app/flatpak-main.c:697
#, c-format
msgid "See '%s --help'"
msgstr ""

#: app/flatpak-main.c:706
#, c-format
msgid "'%s' is not a flatpak command. Did you mean '%s%s'?"
msgstr "«%s» non é unha orde de flatpak. Quixo dicir «%s%s»?"

#: app/flatpak-main.c:709
#, c-format
msgid "'%s' is not a flatpak command"
msgstr ""

#: app/flatpak-main.c:824
msgid "No command specified"
msgstr "Non se especificou ningunha orde"

#: app/flatpak-main.c:980
msgid "error:"
msgstr "erro:"

#: app/flatpak-quiet-transaction.c:77
#, fuzzy, c-format
msgid "Installing %s\n"
msgstr "Instalando: %s\n"

#: app/flatpak-quiet-transaction.c:81
#, fuzzy, c-format
msgid "Updating %s\n"
msgstr "Actualizando resumo\n"

#: app/flatpak-quiet-transaction.c:85
#, fuzzy, c-format
msgid "Uninstalling %s\n"
msgstr "Instalando: %s desde %s\n"

#: app/flatpak-quiet-transaction.c:107
#, fuzzy, c-format
msgid "Warning: Failed to install %s: %s\n"
msgstr "Erro: fallou o %s %s: %s\n"

#: app/flatpak-quiet-transaction.c:110
#, fuzzy, c-format
msgid "Error: Failed to install %s: %s\n"
msgstr "Instalando: %s\n"

#: app/flatpak-quiet-transaction.c:116
#, fuzzy, c-format
msgid "Warning: Failed to update %s: %s\n"
msgstr "Ao obter %s desde o remoto %s: "

#: app/flatpak-quiet-transaction.c:119
#, fuzzy, c-format
msgid "Error: Failed to update %s: %s\n"
msgstr "Ao obter %s desde o remoto %s: "

#: app/flatpak-quiet-transaction.c:125
#, fuzzy, c-format
msgid "Warning: Failed to install bundle %s: %s\n"
msgstr "Erro: fallou o %s %s: %s\n"

#: app/flatpak-quiet-transaction.c:128
#, fuzzy, c-format
msgid "Error: Failed to install bundle %s: %s\n"
msgstr "Instalando: %s\n"

#: app/flatpak-quiet-transaction.c:134
#, fuzzy, c-format
msgid "Warning: Failed to uninstall %s: %s\n"
msgstr "Erro: fallou o %s %s: %s\n"

#: app/flatpak-quiet-transaction.c:137
#, fuzzy, c-format
msgid "Error: Failed to uninstall %s: %s\n"
msgstr "Instalando: %s\n"

#: app/flatpak-quiet-transaction.c:166 common/flatpak-dir.c:11475
#, fuzzy, c-format
msgid "%s already installed"
msgstr "%s remisión %s xa instalado"

#: app/flatpak-quiet-transaction.c:168 common/flatpak-dir.c:3622
#: common/flatpak-dir.c:4321 common/flatpak-dir.c:16968
#: common/flatpak-dir.c:17258 common/flatpak-dir-utils.c:166
#: common/flatpak-dir-utils.c:259 common/flatpak-transaction.c:2736
#: common/flatpak-transaction.c:2791
#, c-format
msgid "%s not installed"
msgstr "%s non instalado"

#: app/flatpak-quiet-transaction.c:170
#, fuzzy, c-format
msgid "%s needs a later flatpak version"
msgstr "%s precisa unha versión de flatpak posterior (%s)"

#: app/flatpak-quiet-transaction.c:172
msgid "Not enough disk space to complete this operation"
msgstr ""

#: app/flatpak-quiet-transaction.c:239
#, c-format
msgid "Info: %s is end-of-life, in favor of %s\n"
msgstr ""

#: app/flatpak-quiet-transaction.c:241
#, c-format
msgid "Info: %s is end-of-life, with reason: %s\n"
msgstr ""

#: app/flatpak-quiet-transaction.c:251
#, fuzzy, c-format
msgid "Failed to rebase %s to %s: %s\n"
msgstr "Erro: fallou o %s %s: %s\n"

#: common/flatpak-auth.c:58
#, fuzzy, c-format
msgid "No authenticator configured for remote `%s`"
msgstr "Requírese autenticación para actualizar software"

#: common/flatpak-context.c:637 common/flatpak-context.c:649
#, fuzzy, c-format
msgid "Invalid permission syntax: %s"
msgstr "Nome de autenticador %s non válido"

#: common/flatpak-context.c:1207
#, c-format
msgid "Unknown share type %s, valid types are: %s"
msgstr "Tipo de compartido %s descoñecido, os tipos validos son: %s"

#: common/flatpak-context.c:1228
#, c-format
msgid "Unknown policy type %s, valid types are: %s"
msgstr "Tipo de normativa %s descoñecida, os tipos válidos son: %s"

#: common/flatpak-context.c:1266
#, c-format
msgid "Invalid dbus name %s"
msgstr "Nome de dbus %s non "

#: common/flatpak-context.c:1279
#, c-format
msgid "Unknown socket type %s, valid types are: %s"
msgstr "Tipo de socket %s descoñecido, os tipos validos son: %s"

#: common/flatpak-context.c:1294
#, c-format
msgid "Unknown device type %s, valid types are: %s"
msgstr "Tipo de dispositivo %s descoñecido, os tipos válidos son: %s"

#: common/flatpak-context.c:1308
#, c-format
msgid "Unknown feature type %s, valid types are: %s"
msgstr "Tipo de característica %s descoñecida, os tipos validos son: %s"

#: common/flatpak-context.c:1840
#, c-format
msgid "Filesystem location \"%s\" contains \"..\""
msgstr ""

#: common/flatpak-context.c:1882
#, c-format
msgid ""
"--filesystem=/ is not available, use --filesystem=host for a similar result"
msgstr ""

#: common/flatpak-context.c:1916
#, fuzzy, c-format
msgid ""
"Unknown filesystem location %s, valid locations are: host, host-os, host-"
"etc, host-root, home, xdg-*[/…], ~/dir, /dir"
msgstr ""
"Localización de sistema de ficheiros %s descoñecido, as localizacións "
"válidas son: hos, home, xdg-*[/...], ~/dir, /dir"

#: common/flatpak-context.c:2015
#, fuzzy, c-format
msgid "Invalid syntax for %s: %s"
msgstr "Nome de dbus %s non válido\n"

#: common/flatpak-context.c:2142
#, c-format
msgid "fallback-x11 can not be conditional"
msgstr ""

#: common/flatpak-context.c:2318
#, c-format
msgid "Invalid env format %s"
msgstr "Formato de env %s non válido"

#: common/flatpak-context.c:2399
#, c-format
msgid "Environment variable name must not contain '=': %s"
msgstr ""

#: common/flatpak-context.c:2527 common/flatpak-context.c:2535
#, c-format
msgid "--add-policy arguments must be in the form SUBSYSTEM.KEY=VALUE"
msgstr ""

#: common/flatpak-context.c:2542
#, c-format
msgid "--add-policy values can't start with \"!\""
msgstr ""

#: common/flatpak-context.c:2567 common/flatpak-context.c:2575
#, c-format
msgid "--remove-policy arguments must be in the form SUBSYSTEM.KEY=VALUE"
msgstr ""

#: common/flatpak-context.c:2582
#, c-format
msgid "--remove-policy values can't start with \"!\""
msgstr ""

#: common/flatpak-context.c:2657
msgid "Share with host"
msgstr "Compartir co anfitrión"

#: common/flatpak-context.c:2657 common/flatpak-context.c:2658
msgid "SHARE"
msgstr "COMPARTIR"

#: common/flatpak-context.c:2658
msgid "Unshare with host"
msgstr "Deixar de compartir co anfitrión"

#: common/flatpak-context.c:2659
msgid "Require conditions to be met for a subsystem to get shared"
msgstr ""

#: common/flatpak-context.c:2659
msgid "SHARE:CONDITION"
msgstr ""

#: common/flatpak-context.c:2660
msgid "Expose socket to app"
msgstr "Expoñer o socket á aplicación"

#: common/flatpak-context.c:2660 common/flatpak-context.c:2661
msgid "SOCKET"
msgstr "SOCKET"

#: common/flatpak-context.c:2661
msgid "Don't expose socket to app"
msgstr "Non expoñer o socket á aplicación"

#: common/flatpak-context.c:2662
msgid "Require conditions to be met for a socket to get exposed"
msgstr ""

#: common/flatpak-context.c:2662
msgid "SOCKET:CONDITION"
msgstr ""

#: common/flatpak-context.c:2663
msgid "Expose device to app"
msgstr "Expoñer o dispositivo á aplicación"

#: common/flatpak-context.c:2663 common/flatpak-context.c:2664
msgid "DEVICE"
msgstr "DISPOSITIVO"

#: common/flatpak-context.c:2664
msgid "Don't expose device to app"
msgstr "Non expoñer o dispositivo á aplicación"

#: common/flatpak-context.c:2665
msgid "Require conditions to be met for a device to get exposed"
msgstr ""

#: common/flatpak-context.c:2665
msgid "DEVICE:CONDITION"
msgstr ""

#: common/flatpak-context.c:2666
msgid "Allow feature"
msgstr "Permitir característica"

#: common/flatpak-context.c:2666 common/flatpak-context.c:2667
msgid "FEATURE"
msgstr "CARACTERÍSTICA"

#: common/flatpak-context.c:2667
msgid "Don't allow feature"
msgstr "No permitir característica"

#: common/flatpak-context.c:2668
msgid "Require conditions to be met for a feature to get allowed"
msgstr ""

#: common/flatpak-context.c:2668
msgid "FEATURE:CONDITION"
msgstr ""

#: common/flatpak-context.c:2669
msgid "Expose filesystem to app (:ro for read-only)"
msgstr "Expoñer o sistema de ficheiros á aplicación (:ro para só lectura)"

#: common/flatpak-context.c:2669
msgid "FILESYSTEM[:ro]"
msgstr "SISTEMA_FICHEIROS[:ro]"

#: common/flatpak-context.c:2670
msgid "Don't expose filesystem to app"
msgstr "Non expoñer o sistema de ficheiros á aplicación"

#: common/flatpak-context.c:2670
msgid "FILESYSTEM"
msgstr "SISTEMA_FICHEIROS"

#: common/flatpak-context.c:2671
msgid "Set environment variable"
msgstr "Estabelecer variábel de ambiente"

#: common/flatpak-context.c:2671
msgid "VAR=VALUE"
msgstr "VAR=VALOR"

#: common/flatpak-context.c:2672
msgid "Read environment variables in env -0 format from FD"
msgstr ""

#: common/flatpak-context.c:2673
#, fuzzy
msgid "Remove variable from environment"
msgstr "Revogarlle os permisos de escritura á aplicación"

#: common/flatpak-context.c:2673
#, fuzzy
msgid "VAR"
msgstr "VAR=VALOR"

#: common/flatpak-context.c:2674
msgid "Allow app to own name on the session bus"
msgstr "Permitir que a aplicación teña un nome propio no bus de sesión"

#: common/flatpak-context.c:2674 common/flatpak-context.c:2675
#: common/flatpak-context.c:2676 common/flatpak-context.c:2677
#: common/flatpak-context.c:2678 common/flatpak-context.c:2679
#: common/flatpak-context.c:2680
msgid "DBUS_NAME"
msgstr "NOME_DBUS"

#: common/flatpak-context.c:2675
msgid "Allow app to talk to name on the session bus"
msgstr "Permitir á aplicación falar cun nome no bus de sesión"

#: common/flatpak-context.c:2676
msgid "Don't allow app to talk to name on the session bus"
msgstr "Permitir á aplicación falar cun nome no bus de sesión"

#: common/flatpak-context.c:2677
msgid "Allow app to own name on the system bus"
msgstr "Permitir á aplicación posuír un nome propio no bus do sistema"

#: common/flatpak-context.c:2678
msgid "Allow app to talk to name on the system bus"
msgstr "Permitir á aplicación falar cun nome no bus de sistema"

#: common/flatpak-context.c:2679
msgid "Don't allow app to talk to name on the system bus"
msgstr "Permitir á aplicación falar cun nome no bus de sistema"

#: common/flatpak-context.c:2680
#, fuzzy
msgid "Allow app to own name on the a11y bus"
msgstr "Permitir á aplicación posuír un nome propio no bus do sistema"

#: common/flatpak-context.c:2681
msgid "Add generic policy option"
msgstr "Engadir unha opción de normativa xenérica"

#: common/flatpak-context.c:2681 common/flatpak-context.c:2682
msgid "SUBSYSTEM.KEY=VALUE"
msgstr "SUBSISTEMA.CHAVE=VALOR"

#: common/flatpak-context.c:2682
msgid "Remove generic policy option"
msgstr "Eliminar opción de normativa xenérica"

#: common/flatpak-context.c:2683
msgid "Add USB device to enumerables"
msgstr ""

#: common/flatpak-context.c:2683 common/flatpak-context.c:2684
msgid "VENDOR_ID:PRODUCT_ID"
msgstr ""

#: common/flatpak-context.c:2684
msgid "Add USB device to hidden list"
msgstr ""

#: common/flatpak-context.c:2685
msgid "A list of USB devices that are enumerable"
msgstr ""

#: common/flatpak-context.c:2685
msgid "LIST"
msgstr ""

#: common/flatpak-context.c:2686
msgid "File containing a list of USB devices to make enumerable"
msgstr ""

#: common/flatpak-context.c:2686 common/flatpak-context.c:2687
msgid "FILENAME"
msgstr "NOME_FICHEIRO"

#: common/flatpak-context.c:2687
#, fuzzy
msgid "Persist home directory subpath"
msgstr "Persistir o directorio persoal"

#. This is not needed/used anymore, so hidden, but we accept it for backwards compat
#: common/flatpak-context.c:2689
msgid "Don't require a running session (no cgroups creation)"
msgstr "Non requirir unha sesión en execución (sen creación de cgroups)"

#: common/flatpak-context.c:3718
#, c-format
msgid "Not replacing \"%s\" with tmpfs: %s"
msgstr ""

#: common/flatpak-context.c:3726
#, c-format
msgid "Not sharing \"%s\" with sandbox: %s"
msgstr ""

#. Even if the error is one that we would normally silence, like
#. * the path not existing, it seems reasonable to make more of a fuss
#. * about the home directory not existing or otherwise being unusable,
#. * so this is intentionally not using cannot_export()
#: common/flatpak-context.c:3828
#, c-format
msgid "Not allowing home directory access: %s"
msgstr ""

#: common/flatpak-context.c:4062
#, fuzzy, c-format
msgid "Unable to provide a temporary home directory in the sandbox: %s"
msgstr "Non é posíbel crear o directorio de despregue"

#: common/flatpak-dir.c:442
#, c-format
msgid "Configured collection ID ‘%s’ not in summary file"
msgstr ""

#: common/flatpak-dir.c:587
#, fuzzy, c-format
msgid "Unable to load summary from remote %s: %s"
msgstr "Ao obter %s desde o remoto %s: "

#: common/flatpak-dir.c:764 common/flatpak-dir.c:800 common/flatpak-dir.c:906
#, fuzzy, c-format
msgid "No such ref '%s' in remote %s"
msgstr "Non é posíbel atopar %s no remoto %s"

#: common/flatpak-dir.c:891 common/flatpak-dir.c:1051 common/flatpak-dir.c:1080
#: common/flatpak-dir.c:1092
#, fuzzy, c-format
msgid "No entry for %s in remote %s summary flatpak cache"
msgstr "Non hai ningunha entrada para %s na caché de flatpak do resumo remoto "

#: common/flatpak-dir.c:1069
#, fuzzy, c-format
msgid "No summary or Flatpak cache available for remote %s"
msgstr "Non hai caché de flatpak na descrición do remoto"

#: common/flatpak-dir.c:1097
#, fuzzy, c-format
msgid "Missing xa.data in summary for remote %s"
msgstr "Non hai caché de flatpak na descrición do remoto"

#: common/flatpak-dir.c:1103 common/flatpak-dir.c:1546
#, fuzzy, c-format
msgid "Unsupported summary version %d for remote %s"
msgstr "Non hai caché de flatpak na descrición do remoto"

#: common/flatpak-dir.c:1200
msgid "Remote OCI index has no registry uri"
msgstr ""

#: common/flatpak-dir.c:1261
#, fuzzy, c-format
msgid "Couldn't find ref %s in remote %s"
msgstr "Non é posíbel atopar %s no remoto %s"

#: common/flatpak-dir.c:1288 common/flatpak-dir.c:1381
#, c-format
msgid "Commit has no requested ref ‘%s’ in ref binding metadata (found: ‘%s’)"
msgstr ""

#: common/flatpak-dir.c:1413
#, c-format
msgid "Configured collection ID ‘%s’ not in binding metadata"
msgstr ""

#: common/flatpak-dir.c:1449 common/flatpak-dir.c:5645
#, fuzzy, c-format
msgid "Couldn't find latest checksum for ref %s in remote %s"
msgstr "Non é posíbel atopar %s no remoto %s"

#: common/flatpak-dir.c:1516 common/flatpak-dir.c:1552
#, fuzzy, c-format
msgid "No entry for %s in remote %s summary flatpak sparse cache"
msgstr "Non hai ningunha entrada para %s na caché de flatpak do resumo remoto "

#: common/flatpak-dir.c:2540
#, c-format
msgid "Commit metadata for %s not matching expected metadata"
msgstr ""

#: common/flatpak-dir.c:2823
msgid "Unable to connect to system bus"
msgstr "Non foi posíbel conectarse ao bus do sistema"

#: common/flatpak-dir.c:3419
#, fuzzy
msgid "User installation"
msgstr "Mostrar instalacións do usuario"

#: common/flatpak-dir.c:3426
#, fuzzy, c-format
msgid "System (%s) installation"
msgstr "Mostrar instalacións do usuario"

#: common/flatpak-dir.c:3472
#, c-format
msgid "No overrides found for %s"
msgstr "Non se atopou ningunha sobrescritura para %s"

#: common/flatpak-dir.c:3625
#, fuzzy, c-format
msgid "%s (commit %s) not installed"
msgstr "%s %s non está instalado"

#: common/flatpak-dir.c:4650
#, fuzzy, c-format
msgid "Error parsing system flatpakrepo file for %s: %s"
msgstr ""
"Produciuse un erro ao actualizar os metadatos adicionais para «%s»: %s\n"

#: common/flatpak-dir.c:4735
#, c-format
msgid "While opening repository %s: "
msgstr "Ao abrir o repositorio %s: "

#: common/flatpak-dir.c:5004
#, c-format
msgid "The config key %s is not set"
msgstr ""

#: common/flatpak-dir.c:5140
#, fuzzy, c-format
msgid "No current %s pattern matching %s"
msgstr "Non actualiar as referencias relacionadas"

#: common/flatpak-dir.c:5422
#, fuzzy
msgid "No appstream commit to deploy"
msgstr "Remisión a despregar"

#: common/flatpak-dir.c:5941 common/flatpak-dir.c:7266
#: common/flatpak-dir.c:10881 common/flatpak-dir.c:11618
msgid "Can't pull from untrusted non-gpg verified remote"
msgstr ""

#: common/flatpak-dir.c:6376 common/flatpak-dir.c:6591
msgid "Extra data not supported for non-gpg-verified local system installs"
msgstr ""

#: common/flatpak-dir.c:6415 common/flatpak-dir.c:6782
#, fuzzy, c-format
msgid "Invalid checksum for extra data uri %s"
msgstr "Suma de verificación non válida para os datos adicinais %s"

#: common/flatpak-dir.c:6424
#, c-format
msgid "Empty name for extra data uri %s"
msgstr "Nome baleiro para o uri de datos adicinais %s"

#: common/flatpak-dir.c:6432
#, c-format
msgid "Unsupported extra data uri %s"
msgstr "URI de datos adicinais %s non admitido"

#: common/flatpak-dir.c:6461
#, c-format
msgid "Failed to load local extra-data %s: %s"
msgstr "Produciuse un fallo ao cargar os datos adicinais locais %s: %s"

#: common/flatpak-dir.c:6469
#, c-format
msgid "Wrong size for extra-data %s"
msgstr "Tamaño dos datos adicinais incorrecto %s"

#: common/flatpak-dir.c:6488
#, c-format
msgid "While downloading %s: "
msgstr "Ao descargar %s: "

#: common/flatpak-dir.c:6498
#, c-format
msgid "Wrong size for extra data %s"
msgstr "Tamaño dos datos adicinais %s incorrecto"

#: common/flatpak-dir.c:6507
#, c-format
msgid "Invalid checksum for extra data %s"
msgstr "Suma de verificación non válida para os datos adicinais %s"

#: common/flatpak-dir.c:7096 common/flatpak-dir.c:7349
#, c-format
msgid "While pulling %s from remote %s: "
msgstr "Ao obter %s desde o remoto %s: "

#: common/flatpak-dir.c:7290 common/flatpak-repo-utils.c:3886
msgid "GPG signatures found, but none are in trusted keyring"
msgstr ""

#: common/flatpak-dir.c:7307
#, c-format
msgid "Commit for ‘%s’ has no ref binding"
msgstr ""

#: common/flatpak-dir.c:7312
#, c-format
msgid "Commit for ‘%s’ is not in expected bound refs: %s"
msgstr ""

#: common/flatpak-dir.c:7488
#, fuzzy
msgid "Only applications can be made current"
msgstr ""
"\n"
"Buscando aplicacións e «runtimes»"

#: common/flatpak-dir.c:8192
msgid "Not enough memory"
msgstr "Non hai momoria dabondo"

#: common/flatpak-dir.c:8211
msgid "Failed to read from exported file"
msgstr "Produciuse un fallo ao ler o ficheiro exportado"

#: common/flatpak-dir.c:8401
msgid "Error reading mimetype xml file"
msgstr "Produciuse un erro ao ler o ficheiro xml de mimetype"

#: common/flatpak-dir.c:8406
msgid "Invalid mimetype xml file"
msgstr "Ficheiro xml de mimetype non válido"

#: common/flatpak-dir.c:8492
#, c-format
msgid "D-Bus service file '%s' has wrong name"
msgstr ""

#: common/flatpak-dir.c:8647
#, fuzzy, c-format
msgid "Invalid Exec argument %s"
msgstr "Formato de env %s non válido"

#: common/flatpak-dir.c:9115
msgid "While getting detached metadata: "
msgstr "Mentres se obtiñan os metadatos desanexados: "

#: common/flatpak-dir.c:9120 common/flatpak-dir.c:9125
#: common/flatpak-dir.c:9129
#, fuzzy
msgid "Extra data missing in detached metadata"
msgstr "Mentres se obtiñan os metadatos desanexados: "

#: common/flatpak-dir.c:9133
msgid "While creating extradir: "
msgstr "Ao crear o directorio adicional: "

#: common/flatpak-dir.c:9154 common/flatpak-dir.c:9187
msgid "Invalid checksum for extra data"
msgstr "Suma de verificación non válida para os datos adicinais"

#: common/flatpak-dir.c:9183
msgid "Wrong size for extra data"
msgstr "Tamaño dos datos adicinais incorrecto"

#: common/flatpak-dir.c:9196
#, c-format
msgid "While writing extra data file '%s': "
msgstr "Ao escribir o ficheiro de datos adicionais «%s»: "

#: common/flatpak-dir.c:9204
#, fuzzy, c-format
msgid "Extra data %s missing in detached metadata"
msgstr "Mentres se obtiñan os metadatos desanexados: "

#: common/flatpak-dir.c:9278
#, fuzzy, c-format
msgid "Unable to get runtime key from metadata"
msgstr "Usar o ficheiro alternativo para os metadatos"

#: common/flatpak-dir.c:9402
#, c-format
msgid "apply_extra script failed, exit status %d"
msgstr "apply_extra script failed, estado de saída %d"

#. Translators: The placeholder is for an app ref.
#: common/flatpak-dir.c:9591
#, c-format
msgid "Installing %s is not allowed by the policy set by your administrator"
msgstr ""

#: common/flatpak-dir.c:9690
#, c-format
msgid "While trying to resolve ref %s: "
msgstr "Ao tentar resolver a referencia %s: "

#: common/flatpak-dir.c:9702
#, c-format
msgid "%s is not available"
msgstr "%s non está dispoñíbel"

#: common/flatpak-dir.c:9714 common/flatpak-dir.c:11495
#, c-format
msgid "%s commit %s already installed"
msgstr "%s remisión %s xa instalado"

#: common/flatpak-dir.c:9721
msgid "Can't create deploy directory"
msgstr "Non é posíbel crear o directorio de despregue"

#: common/flatpak-dir.c:9729
#, c-format
msgid "Failed to read commit %s: "
msgstr "Produciuse un fallo ao ler a remisión %s: "

#: common/flatpak-dir.c:9750
#, c-format
msgid "While trying to checkout %s into %s: "
msgstr "Ao tentar obter %s en %s: "

#: common/flatpak-dir.c:9769
msgid "While trying to checkout metadata subpath: "
msgstr "Ao tentar obter a subruta de metadatos: "

#: common/flatpak-dir.c:9801
#, fuzzy, c-format
msgid "While trying to checkout subpath ‘%s’: "
msgstr "Ao tentar obter %s en %s: "

#: common/flatpak-dir.c:9811
msgid "While trying to remove existing extra dir: "
msgstr "Ao tentar eliminar o directorio adicinal existente: "

#: common/flatpak-dir.c:9822
msgid "While trying to apply extra data: "
msgstr "Ao tentar aplicar os datos adicionais: "

#: common/flatpak-dir.c:9849
#, c-format
msgid "Invalid commit ref %s: "
msgstr "Referencia de remisión %s non válida: "

#: common/flatpak-dir.c:9857 common/flatpak-dir.c:9869
#, c-format
msgid "Deployed ref %s does not match commit (%s)"
msgstr "A referencia %s despregada non coincide coa remisión (%s)"

#: common/flatpak-dir.c:9863
#, c-format
msgid "Deployed ref %s branch does not match commit (%s)"
msgstr "A rama %s da referencia despregada non coincide coa remisión (%s)"

#: common/flatpak-dir.c:10125 common/flatpak-installation.c:1911
#, c-format
msgid "%s branch %s already installed"
msgstr "%s rama %s xa instalado"

#: common/flatpak-dir.c:10985
#, c-format
msgid "Could not unmount revokefs-fuse filesystem at %s: "
msgstr ""

#: common/flatpak-dir.c:11289
#, c-format
msgid "This version of %s is already installed"
msgstr "Esta versión de %s xa está instalada"

#: common/flatpak-dir.c:11302
#, c-format
msgid "Can't change remote during bundle install"
msgstr "Non é posíbel cambiar o remoto durante a instalación dun paquete"

#: common/flatpak-dir.c:11571
msgid "Can't update to a specific commit without root permissions"
msgstr ""

#: common/flatpak-dir.c:11852
#, c-format
msgid "Can't remove %s, it is needed for: %s"
msgstr ""

#: common/flatpak-dir.c:11912 common/flatpak-installation.c:2067
#, c-format
msgid "%s branch %s is not installed"
msgstr "%s rama %s non está instalado"

#: common/flatpak-dir.c:12165
#, fuzzy, c-format
msgid "%s commit %s not installed"
msgstr "%s %s non está instalado"

#: common/flatpak-dir.c:12501
#, c-format
msgid "Pruning repo failed: %s"
msgstr ""

#: common/flatpak-dir.c:12669 common/flatpak-dir.c:12675
#, fuzzy, c-format
msgid "Failed to load filter '%s'"
msgstr "Produciuse un fallo ao ler a remisión %s: "

#: common/flatpak-dir.c:12681
#, fuzzy, c-format
msgid "Failed to parse filter '%s'"
msgstr "Produciuse un fallo ao ler a remisión %s: "

#: common/flatpak-dir.c:12963
#, fuzzy
msgid "Failed to write summary cache: "
msgstr "Produciuse un fallo ao crear o ficheiro temporal"

#: common/flatpak-dir.c:12982
#, fuzzy, c-format
msgid "No oci summary cached for remote '%s'"
msgstr "Non hai caché de flatpak na descrición do remoto"

#: common/flatpak-dir.c:13207
#, fuzzy, c-format
msgid "No cached summary for remote '%s'"
msgstr "Non hai caché de flatpak na descrición do remoto"

#: common/flatpak-dir.c:13248
#, fuzzy, c-format
msgid "Invalid checksum for indexed summary %s read from %s"
msgstr "Suma de verificación non válida para os datos adicinais %s"

#: common/flatpak-dir.c:13321
#, c-format
msgid ""
"Remote listing for %s not available; server has no summary file. Check the "
"URL passed to remote-add was valid."
msgstr ""

#: common/flatpak-dir.c:13698
#, fuzzy, c-format
msgid "Invalid checksum for indexed summary %s for remote '%s'"
msgstr "Suma de verificación non válida para os datos adicinais %s"

#: common/flatpak-dir.c:14388
#, c-format
msgid "Multiple branches available for %s, you must specify one of: "
msgstr ""

#: common/flatpak-dir.c:14454
#, c-format
msgid "Nothing matches %s"
msgstr "Nada coincide con %s"

#: common/flatpak-dir.c:14562
#, c-format
msgid "Can't find ref %s%s%s%s%s"
msgstr "Non se puido atopar a referencia %s%s%s%s%s"

#: common/flatpak-dir.c:14605
#, c-format
msgid "Error searching remote %s: %s"
msgstr "Produciuse un erro ao buscar o remoto %s: %s"

#: common/flatpak-dir.c:14702
#, c-format
msgid "Error searching local repository: %s"
msgstr "Produciuse un erro ao buscar no repositorio local: %s"

#: common/flatpak-dir.c:14839
#, fuzzy, c-format
msgid "%s/%s/%s not installed"
msgstr "%s %s non está instalado"

#: common/flatpak-dir.c:15042
#, c-format
msgid "Could not find installation %s"
msgstr "Non foi posíbel atopar a instalación %s"

#: common/flatpak-dir.c:15612
#, fuzzy, c-format
msgid "Invalid file format, no %s group"
msgstr "Formato de env %s non válido"

#: common/flatpak-dir.c:15617 common/flatpak-repo-utils.c:2836
#, fuzzy, c-format
msgid "Invalid version %s, only 1 supported"
msgstr "Tipo de uri non válido %s, só se admite http/https"

#: common/flatpak-dir.c:15622 common/flatpak-dir.c:15627
#, fuzzy, c-format
msgid "Invalid file format, no %s specified"
msgstr "Formato de env %s non válido"

#. Check some minimal size so we don't get crap
#: common/flatpak-dir.c:15647
#, fuzzy
msgid "Invalid file format, gpg key invalid"
msgstr "Formato de env %s non válido"

#: common/flatpak-dir.c:15675 common/flatpak-repo-utils.c:2917
msgid "Collection ID requires GPG key to be provided"
msgstr ""

#: common/flatpak-dir.c:15718
#, c-format
msgid "Runtime %s, branch %s is already installed"
msgstr "Runtime %s, rama %s xa está instalado"

#: common/flatpak-dir.c:15719
#, c-format
msgid "App %s, branch %s is already installed"
msgstr "Aplicación %s, rama %s xa está instalado"

#: common/flatpak-dir.c:15953
#, c-format
msgid "Can't remove remote '%s' with installed ref %s (at least)"
msgstr ""

#: common/flatpak-dir.c:16058
#, fuzzy, c-format
msgid "Invalid character '/' in remote name: %s"
msgstr "Non é posíbel atopar %s no remoto %s"

#: common/flatpak-dir.c:16064
#, c-format
msgid "No configuration for remote %s specified"
msgstr ""

#: common/flatpak-dir.c:17597
#, fuzzy, c-format
msgid "Skipping deletion of mirror ref (%s, %s)…\n"
msgstr "Referencia %s despregada non válida: "

#: common/flatpak-exports.c:931
#, c-format
msgid "An absolute path is required"
msgstr ""

#: common/flatpak-exports.c:948
#, fuzzy, c-format
msgid "Unable to open path \"%s\": %s"
msgstr "Ao obter %s desde o remoto %s: "

#: common/flatpak-exports.c:955
#, fuzzy, c-format
msgid "Unable to get file type of \"%s\": %s"
msgstr "Non foi posíbel crear a tubería de sincronización"

#: common/flatpak-exports.c:964
#, c-format
msgid "File \"%s\" has unsupported type 0o%o"
msgstr ""

#: common/flatpak-exports.c:970
#, c-format
msgid "Unable to get filesystem information for \"%s\": %s"
msgstr ""

#: common/flatpak-exports.c:980
#, c-format
msgid "Ignoring blocking autofs path \"%s\""
msgstr ""

#: common/flatpak-exports.c:996 common/flatpak-exports.c:1009
#: common/flatpak-exports.c:1022
#, c-format
msgid "Path \"%s\" is reserved by Flatpak"
msgstr ""

#: common/flatpak-exports.c:1076
#, fuzzy, c-format
msgid "Unable to resolve symbolic link \"%s\": %s"
msgstr "Ao obter %s desde o remoto %s: "

#: common/flatpak-glib-backports.c:69
msgid "Empty string is not a number"
msgstr ""

#: common/flatpak-glib-backports.c:95
#, c-format
msgid "“%s” is not an unsigned number"
msgstr ""

#: common/flatpak-glib-backports.c:105
#, c-format
msgid "Number “%s” is out of bounds [%s, %s]"
msgstr ""

#: common/flatpak-image-source.c:83
msgid "Only sha256 image checksums are supported"
msgstr ""

#: common/flatpak-image-source.c:100 common/flatpak-image-source.c:108
msgid "Image is not a manifest"
msgstr ""

#: common/flatpak-image-source.c:123
msgid "No org.flatpak.ref found in image"
msgstr ""

#: common/flatpak-image-source.c:148
#, c-format
msgid "Ref '%s' not found in registry"
msgstr "Referencia «%s» non atopada no rexistro"

#: common/flatpak-image-source.c:157
msgid "Multiple images in registry, specify a ref with --ref"
msgstr "Imaxes múltiples no rexistro, especifique unha referencia con --ref"

#: common/flatpak-installation.c:834
#, fuzzy, c-format
msgid "Ref %s not installed"
msgstr "%s non instalado"

#: common/flatpak-installation.c:875
#, fuzzy, c-format
msgid "App %s not installed"
msgstr "%s non instalado"

#: common/flatpak-installation.c:1395
#, fuzzy, c-format
msgid "Remote '%s' already exists"
msgstr "O repositorio remoto %s xa existe"

#: common/flatpak-installation.c:1946
#, fuzzy, c-format
msgid "As requested, %s was only pulled, but not installed"
msgstr "A extensión %s solicitada só está instalada parcialmente"

#: common/flatpak-instance.c:533 common/flatpak-instance.c:687
#: common/flatpak-instance.c:728
#, fuzzy, c-format
msgid "Unable to create directory %s"
msgstr "Non foi posíbel crear a tubería de sincronización"

#: common/flatpak-instance.c:554
#, fuzzy, c-format
msgid "Unable to lock %s"
msgstr "Non foi posíbel crear a tubería de sincronización"

#: common/flatpak-instance.c:627
#, fuzzy, c-format
msgid "Unable to create temporary directory in %s"
msgstr "Non é posíbel crear o directorio de despregue"

#: common/flatpak-instance.c:639
#, fuzzy, c-format
msgid "Unable to create file %s"
msgstr "Non foi posíbel crear a tubería de sincronización"

#: common/flatpak-instance.c:646
#, fuzzy, c-format
msgid "Unable to update symbolic link %s/%s"
msgstr "Ao obter %s desde o remoto %s: "

#: common/flatpak-oci-registry.c:1197
msgid "Only Bearer authentication supported"
msgstr ""

#: common/flatpak-oci-registry.c:1206
#, fuzzy
msgid "Only realm in authentication request"
msgstr "Nome de autenticador %s non válido"

#: common/flatpak-oci-registry.c:1213
#, fuzzy
msgid "Invalid realm in authentication request"
msgstr "Nome de autenticador %s non válido"

#: common/flatpak-oci-registry.c:1283
#, fuzzy, c-format
msgid "Authorization failed: %s"
msgstr "Nome de dbus %s non válido\n"

#: common/flatpak-oci-registry.c:1285
msgid "Authorization failed"
msgstr ""

#: common/flatpak-oci-registry.c:1289
#, c-format
msgid "Unexpected response status %d when requesting token: %s"
msgstr ""

#: common/flatpak-oci-registry.c:1300
#, fuzzy
msgid "Invalid authentication request response"
msgstr "Nome de autenticador %s non válido"

#: common/flatpak-oci-registry.c:1731
#, c-format
msgid "Flatpak was compiled without zstd support"
msgstr ""

#: common/flatpak-oci-registry.c:1923 common/flatpak-oci-registry.c:1975
#: common/flatpak-oci-registry.c:2004 common/flatpak-oci-registry.c:2059
#: common/flatpak-oci-registry.c:2115 common/flatpak-oci-registry.c:2193
#, fuzzy
msgid "Invalid delta file format"
msgstr "Formato de env %s non válido"

#: common/flatpak-oci-registry.c:3198 common/flatpak-oci-registry.c:3382
msgid "Invalid OCI image config"
msgstr ""

#: common/flatpak-oci-registry.c:3260 common/flatpak-oci-registry.c:3531
#, c-format
msgid "Wrong layer checksum, expected %s, was %s"
msgstr ""

#: common/flatpak-oci-registry.c:3359
#, c-format
msgid "No ref specified for OCI image %s"
msgstr ""

#: common/flatpak-oci-registry.c:3369
#, c-format
msgid "Wrong ref (%s) specified for OCI image %s, expected %s"
msgstr ""

#: common/flatpak-progress.c:236
#, fuzzy, c-format
msgid "Downloading metadata: %u/(estimating) %s"
msgstr "Non hai orixes de datos adicionais"

#: common/flatpak-progress.c:260
#, fuzzy, c-format
msgid "Downloading: %s/%s"
msgstr "Ao descargar %s: "

#: common/flatpak-progress.c:280
#, fuzzy, c-format
msgid "Downloading extra data: %s/%s"
msgstr "Non hai orixes de datos adicionais"

#: common/flatpak-progress.c:285
#, fuzzy, c-format
msgid "Downloading files: %d/%d %s"
msgstr "Ao descargar %s: "

#: common/flatpak-ref-utils.c:122
msgid "Name can't be empty"
msgstr ""

#: common/flatpak-ref-utils.c:129
msgid "Name can't be longer than 255 characters"
msgstr ""

#: common/flatpak-ref-utils.c:142
msgid "Name can't start with a period"
msgstr ""

#: common/flatpak-ref-utils.c:148
#, c-format
msgid "Name can't start with %c"
msgstr ""

#: common/flatpak-ref-utils.c:164
msgid "Name can't end with a period"
msgstr ""

#: common/flatpak-ref-utils.c:171 common/flatpak-ref-utils.c:183
msgid "Only last name segment can contain -"
msgstr ""

#: common/flatpak-ref-utils.c:174
#, c-format
msgid "Name segment can't start with %c"
msgstr ""

#: common/flatpak-ref-utils.c:186
#, c-format
msgid "Name can't contain %c"
msgstr ""

#: common/flatpak-ref-utils.c:195
msgid "Names must contain at least 2 periods"
msgstr ""

#: common/flatpak-ref-utils.c:312
msgid "Arch can't be empty"
msgstr ""

#: common/flatpak-ref-utils.c:323
#, c-format
msgid "Arch can't contain %c"
msgstr ""

#: common/flatpak-ref-utils.c:385
msgid "Branch can't be empty"
msgstr ""

#: common/flatpak-ref-utils.c:395
#, c-format
msgid "Branch can't start with %c"
msgstr ""

#: common/flatpak-ref-utils.c:405
#, c-format
msgid "Branch can't contain %c"
msgstr ""

#: common/flatpak-ref-utils.c:615 common/flatpak-ref-utils.c:865
msgid "Ref too long"
msgstr ""

#: common/flatpak-ref-utils.c:627
#, fuzzy
msgid "Invalid remote name"
msgstr "Sen remoto %s"

#: common/flatpak-ref-utils.c:641
#, c-format
msgid "%s is not application or runtime"
msgstr "%s non é unha aplicación ou runtime"

#: common/flatpak-ref-utils.c:650 common/flatpak-ref-utils.c:667
#: common/flatpak-ref-utils.c:683
#, fuzzy, c-format
msgid "Wrong number of components in %s"
msgstr "Demasiados argumento"

#: common/flatpak-ref-utils.c:656
#, fuzzy, c-format
msgid "Invalid name %.*s: %s"
msgstr "Nome de dbus %s non válido\n"

#: common/flatpak-ref-utils.c:673
#, fuzzy, c-format
msgid "Invalid arch: %.*s: %s"
msgstr "«%s» non é un nome válido para unha rama: %s"

#: common/flatpak-ref-utils.c:816
#, fuzzy, c-format
msgid "Invalid name %s: %s"
msgstr "Nome de dbus %s non válido\n"

#: common/flatpak-ref-utils.c:834
#, fuzzy, c-format
msgid "Invalid arch: %s: %s"
msgstr "«%s» non é un nome válido para unha rama: %s"

#: common/flatpak-ref-utils.c:853
#, fuzzy, c-format
msgid "Invalid branch: %s: %s"
msgstr "«%s» non é un nome válido para unha rama: %s"

#: common/flatpak-ref-utils.c:962 common/flatpak-ref-utils.c:970
#: common/flatpak-ref-utils.c:978
#, fuzzy, c-format
msgid "Wrong number of components in partial ref %s"
msgstr "Demasiados argumento"

#: common/flatpak-ref-utils.c:1298
#, fuzzy
msgid " development platform"
msgstr "Usar runtime de desenvolvemento"

#: common/flatpak-ref-utils.c:1300
msgid " platform"
msgstr ""

#: common/flatpak-ref-utils.c:1302
#, fuzzy
msgid " application base"
msgstr "ID de colección"

#: common/flatpak-ref-utils.c:1305
msgid " debug symbols"
msgstr ""

#: common/flatpak-ref-utils.c:1307
msgid " sourcecode"
msgstr ""

#: common/flatpak-ref-utils.c:1309
#, fuzzy
msgid " translations"
msgstr "Instalado"

#: common/flatpak-ref-utils.c:1311
msgid " docs"
msgstr ""

#: common/flatpak-ref-utils.c:1578
#, fuzzy, c-format
msgid "Invalid id %s: %s"
msgstr "PID %s non válido"

#: common/flatpak-remote.c:1216
#, fuzzy, c-format
msgid "Bad remote name: %s"
msgstr "Sen remoto %s"

#: common/flatpak-remote.c:1220
#, fuzzy
msgid "No URL specified"
msgstr "Non se especificou ningunha orde"

#: common/flatpak-remote.c:1266
#, fuzzy
msgid "GPG verification must be enabled when a collection ID is set"
msgstr "A comprobación GPG é obrigatoria se as coleccións están activadas"

#: common/flatpak-repo-utils.c:344
#, c-format
msgid "No extra data sources"
msgstr "Non hai orixes de datos adicionais"

#: common/flatpak-repo-utils.c:2817
#, c-format
msgid "Invalid %s: Missing group ‘%s’"
msgstr ""

#: common/flatpak-repo-utils.c:2826
#, c-format
msgid "Invalid %s: Missing key ‘%s’"
msgstr ""

#: common/flatpak-repo-utils.c:2876
#, fuzzy
msgid "Invalid gpg key"
msgstr "PID %s non válido"

#: common/flatpak-repo-utils.c:3217
#, fuzzy, c-format
msgid "Error copying 64x64 icon for component %s: %s\n"
msgstr "Produciuse un erro ao buscar o remoto %s: %s"

#: common/flatpak-repo-utils.c:3223
#, fuzzy, c-format
msgid "Error copying 128x128 icon for component %s: %s\n"
msgstr "Produciuse un erro ao buscar o remoto %s: %s"

#: common/flatpak-repo-utils.c:3362
#, c-format
msgid "%s is end-of-life, ignoring for appstream"
msgstr ""

#: common/flatpak-repo-utils.c:3397
#, fuzzy, c-format
msgid "No appstream data for %s: %s\n"
msgstr "Actualizando appstream para o remoto %s\n"

#: common/flatpak-repo-utils.c:3744
#, fuzzy
msgid "Invalid bundle, no ref in metadata"
msgstr "Suma de verificación non válida para os datos adicinais"

#: common/flatpak-repo-utils.c:3846
#, c-format
msgid "Collection ‘%s’ of bundle doesn’t match collection ‘%s’ of remote"
msgstr ""

#: common/flatpak-repo-utils.c:3923
msgid "Metadata in header and app are inconsistent"
msgstr ""

#: common/flatpak-run.c:951
msgid "No systemd user session available, cgroups not available"
msgstr ""

#: common/flatpak-run.c:1496
#, fuzzy
msgid "Unable to allocate instance id"
msgstr "Non foi posíbel crear a tubería de sincronización"

#: common/flatpak-run.c:1632 common/flatpak-run.c:1641
#, fuzzy, c-format
msgid "Failed to open flatpak-info file: %s"
msgstr "Produciuse un fallo ao abrir o ficheiro temporal flatpak-info: %s"

#: common/flatpak-run.c:1668
#, fuzzy, c-format
msgid "Failed to open bwrapinfo.json file: %s"
msgstr "Produciuse un fallo ao abrir o ficheiro temporal flatpak-info: %s"

#: common/flatpak-run.c:1689
#, fuzzy, c-format
msgid "Failed to write to instance id fd: %s"
msgstr "Produciuse un fallo ao crear o ficheiro temporal"

#: common/flatpak-run.c:2096
msgid "Initialize seccomp failed"
msgstr ""

#: common/flatpak-run.c:2135
#, fuzzy, c-format
msgid "Failed to add architecture to seccomp filter: %s"
msgstr "Produciuse un fallo ao escribir no ficheiro temporal"

#: common/flatpak-run.c:2143
#, fuzzy, c-format
msgid "Failed to add multiarch architecture to seccomp filter: %s"
msgstr "Produciuse un fallo ao escribir no ficheiro temporal"

#: common/flatpak-run.c:2175 common/flatpak-run.c:2192
#: common/flatpak-run.c:2214
#, fuzzy, c-format
msgid "Failed to block syscall %d: %s"
msgstr "Erro: fallou o %s %s: %s\n"

#: common/flatpak-run.c:2247
#, fuzzy, c-format
msgid "Failed to export bpf: %s"
msgstr "Produciuse un fallo ao ler o ficheiro exportado"

#: common/flatpak-run.c:2587
#, fuzzy, c-format
msgid "Failed to open ‘%s’"
msgstr "Produciuse un fallo ao abrir o ficheiro temporal flatpak-info: %s"

#: common/flatpak-run.c:2597
#, c-format
msgid ""
"Directory forwarding needs version 4 of the document portal (have version %d)"
msgstr ""

#: common/flatpak-run.c:2915
#, fuzzy, c-format
msgid "ldconfig failed, exit status %d"
msgstr "apply_extra script failed, estado de saída %d"

#: common/flatpak-run.c:2922
#, fuzzy
msgid "Can't open generated ld.so.cache"
msgstr "Non é posíbel abrir o espazo de nomes %s: %s"

#. Translators: The placeholder is for an app ref.
#: common/flatpak-run.c:3045
#, c-format
msgid "Running %s is not allowed by the policy set by your administrator"
msgstr ""

#: common/flatpak-run.c:3202
msgid ""
"\"flatpak run\" is not intended to be run as `sudo flatpak run`. Use `sudo "
"-i` or `su -l` instead and invoke \"flatpak run\" from inside the new shell."
msgstr ""

#: common/flatpak-run.c:3413
#, fuzzy, c-format
msgid "Failed to migrate from %s: %s"
msgstr "Produciuse un fallo ao ler a remisión %s: "

#: common/flatpak-run.c:3434
#, c-format
msgid "Failed to migrate old app data directory %s to new name %s: %s"
msgstr ""

#: common/flatpak-run.c:3443
#, fuzzy, c-format
msgid "Failed to create symlink while migrating %s: %s"
msgstr "Produciuse un fallo ao ler a remisión %s: "

#: common/flatpak-run-dbus.c:46
msgid "Failed to open app info file"
msgstr "Produciuse un fallo ao abrir o ficheiro de información de aplicación"

#: common/flatpak-run-dbus.c:149
msgid "Unable to create sync pipe"
msgstr "Non foi posíbel crear a tubería de sincronización"

#: common/flatpak-run-dbus.c:185
msgid "Failed to sync with dbus proxy"
msgstr "Procuciuse un fallo ao sincronizarse co proxi de dbus"

#: common/flatpak-transaction.c:2275
#, fuzzy, c-format
msgid "Warning: Problem looking for related refs: %s"
msgstr "Aviso: Problema ao buscar por referencias relacionadas: %s\n"

#: common/flatpak-transaction.c:2493
#, c-format
msgid "The application %s requires the runtime %s which was not found"
msgstr "A aplicación %s require o runtime %s que non está instalado"

#: common/flatpak-transaction.c:2509
#, c-format
msgid "The application %s requires the runtime %s which is not installed"
msgstr "A aplicación %s require o runtime %s que non está instalado"

#: common/flatpak-transaction.c:2641
#, c-format
msgid "Can't uninstall %s which is needed by %s"
msgstr ""

#: common/flatpak-transaction.c:2740
#, c-format
msgid "Remote %s disabled, ignoring %s update"
msgstr "Remoto %s descactivado, ignorando a actualización %s"

#: common/flatpak-transaction.c:2773
#, fuzzy, c-format
msgid "%s is already installed"
msgstr "%s remisión %s xa instalado"

#: common/flatpak-transaction.c:2776
#, fuzzy, c-format
msgid "%s is already installed from remote %s"
msgstr "%s remisión %s xa instalado"

#: common/flatpak-transaction.c:3120
#, fuzzy, c-format
msgid "Invalid .flatpakref: %s"
msgstr "Referencia de remisión %s non válida: "

#: common/flatpak-transaction.c:3161
msgid "Warning: Could not mark already installed apps as preinstalled"
msgstr ""

#: common/flatpak-transaction.c:3382
#, fuzzy, c-format
msgid "Error updating remote metadata for '%s': %s"
msgstr ""
"Produciuse un erro ao actualizar os metadatos adicionais para «%s»: %s\n"

#: common/flatpak-transaction.c:3885
#, c-format
msgid ""
"Warning: Treating remote fetch error as non-fatal since %s is already "
"installed: %s"
msgstr ""

#: common/flatpak-transaction.c:4209
#, fuzzy, c-format
msgid "No authenticator installed for remote '%s'"
msgstr "Requírese autenticación para actualizar software"

#: common/flatpak-transaction.c:4313 common/flatpak-transaction.c:4320
#, fuzzy, c-format
msgid "Failed to get tokens for ref: %s"
msgstr "Produciuse un fallo ao abrir o ficheiro temporal: %s"

#: common/flatpak-transaction.c:4315 common/flatpak-transaction.c:4322
#, fuzzy
msgid "Failed to get tokens for ref"
msgstr "Produciuse un fallo ao abrir o ficheiro temporal: %s"

#: common/flatpak-transaction.c:4580
#, c-format
msgid "Ref %s from %s matches more than one transaction operation"
msgstr ""

#: common/flatpak-transaction.c:4581 common/flatpak-transaction.c:4591
#, fuzzy
msgid "any remote"
msgstr "Sen remoto %s"

#: common/flatpak-transaction.c:4590
#, c-format
msgid "No transaction operation found for ref %s from %s"
msgstr ""

#: common/flatpak-transaction.c:4713
#, c-format
msgid "Flatpakrepo URL %s not file, HTTP or HTTPS"
msgstr ""

#: common/flatpak-transaction.c:4719
#, fuzzy, c-format
msgid "Can't load dependent file %s: "
msgstr "Non é posíbel abrir o espazo de nomes %s: %s"

#: common/flatpak-transaction.c:4727
#, fuzzy, c-format
msgid "Invalid .flatpakrepo: %s"
msgstr "PID %s non válido"

#: common/flatpak-transaction.c:5454
msgid "Transaction already executed"
msgstr ""

#: common/flatpak-transaction.c:5469
msgid ""
"Refusing to operate on a user installation as root! This can lead to "
"incorrect file ownership and permission errors."
msgstr ""

#: common/flatpak-transaction.c:5567 common/flatpak-transaction.c:5580
msgid "Aborted by user"
msgstr ""

#: common/flatpak-transaction.c:5605
#, c-format
msgid "Skipping %s due to previous error"
msgstr ""

#: common/flatpak-transaction.c:5659
#, c-format
msgid "Aborted due to failure (%s)"
msgstr ""

#: common/flatpak-uri.c:118
#, fuzzy, no-c-format
msgid "Invalid %-encoding in URI"
msgstr "Nome de autenticador %s non válido"

#: common/flatpak-uri.c:135
msgid "Illegal character in URI"
msgstr ""

#: common/flatpak-uri.c:169
msgid "Non-UTF-8 characters in URI"
msgstr ""

#: common/flatpak-uri.c:275
#, c-format
msgid "Invalid IPv6 address ‘%.*s’ in URI"
msgstr ""

#: common/flatpak-uri.c:330
#, c-format
msgid "Illegal encoded IP address ‘%.*s’ in URI"
msgstr ""

#: common/flatpak-uri.c:342
#, c-format
msgid "Illegal internationalized hostname ‘%.*s’ in URI"
msgstr ""

#: common/flatpak-uri.c:374 common/flatpak-uri.c:386
#, c-format
msgid "Could not parse port ‘%.*s’ in URI"
msgstr ""

#: common/flatpak-uri.c:393
#, c-format
msgid "Port ‘%.*s’ in URI is out of range"
msgstr ""

#: common/flatpak-uri.c:910
msgid "URI is not absolute, and no base URI was provided"
msgstr ""

#: common/flatpak-usb.c:83
#, c-format
msgid "USB device query 'all' must not have data"
msgstr ""

#: common/flatpak-usb.c:102
#, c-format
msgid "USB query rule 'cls' must be in the form CLASS:SUBCLASS or CLASS:*"
msgstr ""

#: common/flatpak-usb.c:111
#, fuzzy, c-format
msgid "Invalid USB class"
msgstr "PID %s non válido"

#: common/flatpak-usb.c:125
#, c-format
msgid "Invalid USB subclass"
msgstr ""

#: common/flatpak-usb.c:141 common/flatpak-usb.c:148
#, c-format
msgid "USB query rule 'dev' must have a valid 4-digit hexadecimal product id"
msgstr ""

#: common/flatpak-usb.c:164 common/flatpak-usb.c:171
#, c-format
msgid "USB query rule 'vnd' must have a valid 4-digit hexadecimal vendor id"
msgstr ""

#: common/flatpak-usb.c:205
#, c-format
msgid "USB device queries must be in the form TYPE:DATA"
msgstr ""

#: common/flatpak-usb.c:225
#, c-format
msgid "Unknown USB query rule %s"
msgstr ""

#: common/flatpak-usb.c:248
#, c-format
msgid "Empty USB query"
msgstr ""

#: common/flatpak-usb.c:274
#, c-format
msgid "Multiple USB query rules of the same type is not supported"
msgstr ""

#: common/flatpak-usb.c:283
#, c-format
msgid "'all' must not contain extra query rules"
msgstr ""

#: common/flatpak-usb.c:291
#, c-format
msgid "USB queries with 'dev' must also specify vendors"
msgstr ""

#: common/flatpak-utils.c:712
msgid "Glob can't match apps"
msgstr ""

#: common/flatpak-utils.c:737
msgid "Empty glob"
msgstr ""

#: common/flatpak-utils.c:756
#, fuzzy
msgid "Too many segments in glob"
msgstr "Demasiados argumento"

#: common/flatpak-utils.c:777
#, fuzzy, c-format
msgid "Invalid glob character '%c'"
msgstr "PID %s non válido"

#: common/flatpak-utils.c:831
#, c-format
msgid "Missing glob on line %d"
msgstr ""

#: common/flatpak-utils.c:835
#, c-format
msgid "Trailing text on line %d"
msgstr ""

#: common/flatpak-utils.c:839
#, c-format
msgid "on line %d"
msgstr ""

#: common/flatpak-utils.c:861
#, c-format
msgid "Unexpected word '%s' on line %d"
msgstr ""

#: common/flatpak-utils.c:2118
#, c-format
msgid "Invalid require-flatpak argument %s"
msgstr ""

#: common/flatpak-utils.c:2128 common/flatpak-utils.c:2147
#, c-format
msgid "%s needs a later flatpak version (%s)"
msgstr "%s precisa unha versión de flatpak posterior (%s)"

#: oci-authenticator/flatpak-oci-authenticator.c:291
msgid "Not a oci remote, missing summary.xa.oci-repository"
msgstr ""

#: oci-authenticator/flatpak-oci-authenticator.c:477
msgid "Not a OCI remote"
msgstr ""

#: oci-authenticator/flatpak-oci-authenticator.c:488
#, fuzzy
msgid "Invalid token"
msgstr "PID %s non válido"

#: portal/flatpak-portal.c:2292
#, fuzzy, c-format
msgid "No portal support found"
msgstr "Nada coincide con %s"

#: portal/flatpak-portal.c:2298
msgid "Deny"
msgstr ""

#: portal/flatpak-portal.c:2300
#, fuzzy
msgid "Update"
msgstr "actualizar"

#: portal/flatpak-portal.c:2305
#, fuzzy, c-format
msgid "Update %s?"
msgstr "Actualizando resumo\n"

#: portal/flatpak-portal.c:2317
msgid "The application wants to update itself."
msgstr ""

#: portal/flatpak-portal.c:2318
msgid "Update access can be changed any time from the privacy settings."
msgstr ""

#: portal/flatpak-portal.c:2343
#, c-format
msgid "Application update not allowed"
msgstr ""

#: portal/flatpak-portal.c:2501
#, c-format
msgid "Self update not supported, new version requires new permissions"
msgstr ""

#: portal/flatpak-portal.c:2684 portal/flatpak-portal.c:2702
#, fuzzy, c-format
msgid "Update ended unexpectedly"
msgstr "Actualizar runtime asinado"

#. SECURITY:
#. - Normal users need admin authentication to install software
#. system-wide.
#. - Note that we install polkit rules that allow local users
#. in the wheel group to install without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:23
msgid "Install signed application"
msgstr "Instalar aplicación asinada"

#: system-helper/org.freedesktop.Flatpak.policy.in:24
#: system-helper/org.freedesktop.Flatpak.policy.in:42
#, fuzzy
msgid "Authentication is required to install software"
msgstr "Requírese autenticación para actualizar software"

#. SECURITY:
#. - Normal users need admin authentication to install software
#. system-wide.
#. - Note that we install polkit rules that allow local users
#. in the wheel group to install without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:41
msgid "Install signed runtime"
msgstr "Instalar runtime asinado"

#. SECURITY:
#. - Normal users do not require admin authentication to update an
#. app as the commit will be signed, and the action is required
#. to update the system when unattended.
#. - Changing this to anything other than 'yes' will break unattended
#. updates.
#: system-helper/org.freedesktop.Flatpak.policy.in:60
msgid "Update signed application"
msgstr "Actualizar aplicación asinada"

#: system-helper/org.freedesktop.Flatpak.policy.in:61
#: system-helper/org.freedesktop.Flatpak.policy.in:80
msgid "Authentication is required to update software"
msgstr "Requírese autenticación para actualizar software"

#. SECURITY:
#. - Normal users do not require admin authentication to update a
#. runtime as the commit will be signed, and the action is required
#. to update the system when unattended.
#. - Changing this to anything other than 'yes' will break unattended
#. updates.
#: system-helper/org.freedesktop.Flatpak.policy.in:79
msgid "Update signed runtime"
msgstr "Actualizar runtime asinado"

#. SECURITY:
#. - Normal users do not need authentication to update metadata
#. from signed repositories.
#: system-helper/org.freedesktop.Flatpak.policy.in:94
msgid "Update remote metadata"
msgstr "Actualizar metadatos do remoto"

#: system-helper/org.freedesktop.Flatpak.policy.in:95
#, fuzzy
msgid "Authentication is required to update remote info"
msgstr "Requírese autenticación para actualizar software"

#. SECURITY:
#. - Normal users do not need authentication to modify the
#. OSTree repository
#. - Note that we install polkit rules that allow local users
#. in the wheel group to modify repos without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:111
#, fuzzy
msgid "Update system repository"
msgstr "Actualizaar o ficheiro de resumo no repositorio"

#: system-helper/org.freedesktop.Flatpak.policy.in:112
#, fuzzy
msgid "Authentication is required to modify a system repository"
msgstr "Requírese autenticación para actualizar a información do remoto"

#. SECURITY:
#. - Normal users need admin authentication to install software
#. system-wide.
#: system-helper/org.freedesktop.Flatpak.policy.in:126
msgid "Install bundle"
msgstr "Instalar paquete"

#: system-helper/org.freedesktop.Flatpak.policy.in:127
#, fuzzy
msgid "Authentication is required to install software from $(path)"
msgstr "Requírese autenticación para instalar software"

#. SECURITY:
#. - Normal users need admin authentication to uninstall software
#. system-wide.
#. - Note that we install polkit rules that allow local users
#. in the wheel group to uninstall without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:144
msgid "Uninstall runtime"
msgstr "Desinstalar paquete"

#: system-helper/org.freedesktop.Flatpak.policy.in:145
#, fuzzy
msgid "Authentication is required to uninstall software"
msgstr "Requírese autenticación para desinstalar software"

#. SECURITY:
#. - Normal users need admin authentication to uninstall software
#. system-wide.
#. - Note that we install polkit rules that allow local users
#. in the wheel group to uninstall without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:161
msgid "Uninstall app"
msgstr "Desactivar aplicación"

#: system-helper/org.freedesktop.Flatpak.policy.in:162
#, fuzzy
msgid "Authentication is required to uninstall $(ref)"
msgstr "Requírese autenticación para desinstalar software"

#. SECURITY:
#. - Normal users need admin authentication to configure system-wide
#. software repositories.
#: system-helper/org.freedesktop.Flatpak.policy.in:177
msgid "Configure Remote"
msgstr "Configurar remoto"

#: system-helper/org.freedesktop.Flatpak.policy.in:178
#, fuzzy
msgid "Authentication is required to configure software repositories"
msgstr "Requírese autenticación para configurar os repositorios de software"

#. SECURITY:
#. - Normal users need admin authentication to configure the system-wide
#. Flatpak installation.
#: system-helper/org.freedesktop.Flatpak.policy.in:192
#, fuzzy
msgid "Configure"
msgstr "Configurar remoto"

#: system-helper/org.freedesktop.Flatpak.policy.in:193
#, fuzzy
msgid "Authentication is required to configure software installation"
msgstr "Requírese autenticación para configurar os repositorios de software"

#. SECURITY:
#. - Normal users do not require admin authentication to update
#. appstream data as it will be signed, and the action is required
#. to update the system when unattended.
#. - Changing this to anything other than 'yes' will break unattended
#. updates.
#: system-helper/org.freedesktop.Flatpak.policy.in:210
msgid "Update appstream"
msgstr "Actualizar appstream"

#: system-helper/org.freedesktop.Flatpak.policy.in:211
#, fuzzy
msgid "Authentication is required to update information about software"
msgstr "Requírese autenticación para actualizar a información do remoto"

#. SECURITY:
#. - Normal users do not require admin authentication to update
#. metadata as it will be signed, and the action is required
#. to update the system when unattended.
#. - Changing this to anything other than 'yes' will break unattended
#. updates.
#: system-helper/org.freedesktop.Flatpak.policy.in:228
#, fuzzy
msgid "Update metadata"
msgstr "Actualizar metadatos do remoto"

#: system-helper/org.freedesktop.Flatpak.policy.in:229
#, fuzzy
msgid "Authentication is required to update metadata"
msgstr "Requírese autenticación para actualizar software"

#. SECURITY:
#. - Authorisation to actually install software is controlled by
#. org.freedesktop.Flatpak.app-install.
#. - This action is checked after app-install, as it can only be done
#. once the app’s data (including its content rating) has been
#. downloaded.
#. - This action is checked to see if the installation should be allowed
#. based on whether the app being installed has content which doesn’t
#. comply with the user’s parental controls policy (the content is
#. ‘too extreme’).
#. - It is checked only if an app has too extreme content for the user
#. who is trying to install it (in which case, the app is ‘unsafe’).
#. - Typically, normal users will need admin permission to install apps
#. with extreme content; admins will be able to install it without
#. additional checks.
#. - In order to configure the policy so that admins can install safe and
#. unsafe software anywhere without authorisation, and non-admins can
#. install safe software in their user or system dirs without
#. authorisation, but need authorisation to install unsafe software
#. anywhere:
#. * Unconditionally return `yes` from `app-install`.
#. * Return `auth_admin` from `override-parental-controls` for users
#. not in `@privileged_group@`, and `yes` for users in it.
#. * Set the malcontent `is-{user,system}-installation-allowed`
#. properties of all non-admins’ parental controls policies to true.
#. - In order to configure the policy so that admins can install safe and
#. unsafe software anywhere without authorisation, and non-admins can
#. install safe software in their user dir without authorisation, but
#. need authorisation to install safe software in the system dir or to
#. install unsafe software anywhere:
#. * Unconditionally return `yes` from `app-install`.
#. * Return `auth_admin` from `override-parental-controls` for users
#. not in `@privileged_group@`, and `yes` for users in it.
#. * Set the malcontent `is-user-installation-allowed` property of all
#. non-admins’ parental controls policies to true.
#. * Set the malcontent `is-system-installation-allowed` property of
#. all non-admins’ parental controls policies to false.
#. - In order to configure the policy so that all users (including
#. admins) can install safe software anywhere without authorisation,
#. but need authorisation to install unsafe software anywhere (i.e.
#. applying parental controls to admins too):
#. * Unconditionally return `yes` from `app-install`.
#. * Unconditionally return `auth_admin` from `override-parental-controls`.
#. * Set the malcontent `is-user-installation-allowed` property of all
#. users’ parental controls policies to true.
#. * Set the malcontent `is-system-installation-allowed` property of
#. all users’ parental controls policies to true.
#: system-helper/org.freedesktop.Flatpak.policy.in:287
msgid "Override parental controls for installs"
msgstr ""

#: system-helper/org.freedesktop.Flatpak.policy.in:288
#, fuzzy
msgid ""
"Authentication is required to install software which is restricted by your "
"parental controls policy"
msgstr "Requírese autenticación para instalar software"

#. SECURITY:
#. - This is like org.freedesktop.Flatpak.override-parental-controls, but
#. it’s queried for app updates, whereas the former is queried for app
#. installs.
#. - As with the above action, this one is only queried if
#. org.freedesktop.Flatpak.app-update has allowed the app update, and
#. only if the app being updated has too extreme content for the user
#. who is trying to update it.
#. - The default policy for this is to *allow* updates to ‘too extreme’
#. apps by default, on the basis that having an out-of-date (i.e.
#. insecure or unsupported) app is a worse outcome than automatically
#. installing an update which has radically different content from the
#. version of the app which the parent originally vetted and installed.
#: system-helper/org.freedesktop.Flatpak.policy.in:313
msgid "Override parental controls for updates"
msgstr ""

#: system-helper/org.freedesktop.Flatpak.policy.in:314
#, fuzzy
msgid ""
"Authentication is required to update software which is restricted by your "
"parental controls policy"
msgstr "Requírese autenticación para instalar software"

#~ msgid "Installed:"
#~ msgstr "Instalado:"

#, fuzzy
#~ msgid "Download:"
#~ msgstr "Descargar"

#, fuzzy, c-format
#~ msgid "Unable to lookup key ID %s: %d"
#~ msgstr "Ao obter %s desde o remoto %s: "

#, fuzzy, c-format
#~ msgid "Error signing commit: %d"
#~ msgstr "Produciuse un erro ao buscar o remoto %s: %s"

#, fuzzy, c-format
#~ msgid "No entry for %s in remote '%s' summary cache "
#~ msgstr ""
#~ "Non hai ningunha entrada para %s na caché de flatpak do resumo remoto "

#, fuzzy, c-format
#~ msgid "Failed to uninstall %s for rebase to %s: "
#~ msgstr "Erro: fallou o %s %s: %s\n"

#, fuzzy, c-format
#~ msgid "Failed to uninstall %s for rebase to %s: %s\n"
#~ msgstr "Erro: fallou o %s %s: %s\n"

#, fuzzy, c-format
#~ msgid "Unable to open directory %s"
#~ msgstr "Non foi posíbel conectarse ao bus do sistema"

#~ msgid "install"
#~ msgstr "instalar"

#~ msgid "update"
#~ msgstr "actualizar"

#~ msgid "install bundle"
#~ msgstr "instalar paquete"

#, fuzzy
#~ msgid "uninstall"
#~ msgstr "instalar"

#, fuzzy
#~ msgid "runtime"
#~ msgstr "Runtime"

#, fuzzy
#~ msgid "[REF…] - Uninstall an application"
#~ msgstr "REF... - Desinstalar unha aplicación"

#, c-format
#~ msgid "Invalid deployed ref %s: "
#~ msgstr "Referencia %s despregada non válida: "

#, c-format
#~ msgid "Deployed ref %s kind does not match commit (%s)"
#~ msgstr "O tipo %s da referencia despregada non coincide coa remisión (%s)"

#, c-format
#~ msgid "Deployed ref %s name does not match commit (%s)"
#~ msgstr "O nome %s da referencia despregada non coincide coa remisión (%s)"

#, c-format
#~ msgid "Deployed ref %s arch does not match commit (%s)"
#~ msgstr ""
#~ "A arquitectura %s da referencia despregada non coincide coa remisión (%s)"

#, fuzzy, c-format
#~ msgid "Failed to determine parts from ref: %s"
#~ msgstr "Produciuse un fallo ao abrir o ficheiro temporal: %s"

#, fuzzy, c-format
#~ msgid "Invalid arch %s"
#~ msgstr "PID %s non válido"

#, fuzzy, c-format
#~ msgid "Related ref '%s' is only partially installed"
#~ msgstr "A extensión %s solicitada só está instalada parcialmente"

#, fuzzy, c-format
#~ msgid "Ref '%s' is only partially installed"
#~ msgstr "A extensión %s solicitada só está instalada parcialmente"

#, fuzzy, c-format
#~ msgid "No such ref (%s, %s) in remote %s"
#~ msgstr "Non é posíbel atopar %s no remoto %s"

#, fuzzy, c-format
#~ msgid "No flatpak cache in remote '%s' summary"
#~ msgstr "Non hai caché de flatpak na descrición do remoto"

#, fuzzy, c-format
#~ msgid "No such ref (%s, %s) in remote %s or elsewhere"
#~ msgstr "Non é posíbel atopar %s no remoto %s"

#, fuzzy
#~ msgid "No summary found"
#~ msgstr "Nada coincide con %s"

#~ msgid "Deployed metadata does not match commit"
#~ msgstr "Os metadatos despregados non coinciden coa remisión"

#, fuzzy, c-format
#~ msgid "No repo metadata cached for remote '%s'"
#~ msgstr "Non hai caché de flatpak na descrición do remoto"

#, fuzzy
#~ msgid "No metadata branch for OCI"
#~ msgstr "Imprime os metadatos para unha rama"

#, fuzzy, c-format
#~ msgid "Invalid group: %d"
#~ msgstr "PID %s non válido"

#, fuzzy, c-format
#~ msgid "Warning: Can't find %s metadata for dependencies: %s"
#~ msgstr ""
#~ "Aviso: Non se puideron actualizar os metadatos adicionais para «%s»: %s\n"

===== ./po/fr.po =====
# French translation for flatpak.
# Copyright (C) 2021 Flatpak team and others.
# This file is distributed under the same license as the flatpak package.
# Hari Rana / TheEvilSkeleton <theevilskeleton@riseup.net>, 2021.
#
msgid ""
msgstr ""
"Project-Id-Version: flatpak master\n"
"Report-Msgid-Bugs-To: https://github.com/flatpak/flatpak/issues\n"
"POT-Creation-Date: 2026-05-27 16:39+0200\n"
"PO-Revision-Date: 2021-11-30 21:01-0500\n"
"Last-Translator: Hari Rana / TheEvilSkeleton <theevilskeleton@riseup.net>\n"
"Language-Team: \n"
"Language: fr\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: Poedit 3.0\n"

#: app/flatpak-builtins-build-bundle.c:59
msgid "Export runtime instead of app"
msgstr "Exporter le runtime au lieu de l'appli"

#: app/flatpak-builtins-build-bundle.c:60
msgid "Arch to bundle for"
msgstr "Architecture à regrouper pour"

#: app/flatpak-builtins-build-bundle.c:60
#: app/flatpak-builtins-build-export.c:62 app/flatpak-builtins-build-init.c:53
#: app/flatpak-builtins-build-sign.c:42 app/flatpak-builtins-create-usb.c:46
#: app/flatpak-builtins-info.c:55 app/flatpak-builtins-install.c:67
#: app/flatpak-builtins-list.c:50 app/flatpak-builtins-make-current.c:38
#: app/flatpak-builtins-remote-info.c:54 app/flatpak-builtins-remote-ls.c:56
#: app/flatpak-builtins-run.c:158 app/flatpak-builtins-search.c:37
#: app/flatpak-builtins-uninstall.c:54 app/flatpak-builtins-update.c:56
msgid "ARCH"
msgstr "ARCHITECTURE"

#: app/flatpak-builtins-build-bundle.c:61
#, fuzzy
msgid "URL for repo"
msgstr "Url du dépôt"

#: app/flatpak-builtins-build-bundle.c:61
#: app/flatpak-builtins-build-bundle.c:62
#: app/flatpak-builtins-build-update-repo.c:68
#: app/flatpak-builtins-build-update-repo.c:72
#: app/flatpak-builtins-build-update-repo.c:73
#: app/flatpak-builtins-history.c:69 app/flatpak-builtins-remote-add.c:80
#: app/flatpak-builtins-remote-add.c:81 app/flatpak-builtins-remote-add.c:85
#: app/flatpak-builtins-remote-list.c:53
#: app/flatpak-builtins-remote-modify.c:70
#: app/flatpak-builtins-remote-modify.c:85
#: app/flatpak-builtins-remote-modify.c:86
#: app/flatpak-builtins-remote-modify.c:90
msgid "URL"
msgstr "URL"

#: app/flatpak-builtins-build-bundle.c:62
#, fuzzy
msgid "URL for runtime flatpakrepo file"
msgstr "Url du runtime du fichier flatpakrepo"

#: app/flatpak-builtins-build-bundle.c:63
msgid "Add GPG key from FILE (- for stdin)"
msgstr "Ajouter une clé GPG par FICHIER (- pour stdin)"

#: app/flatpak-builtins-build-bundle.c:63 app/flatpak-builtins-build.c:54
#: app/flatpak-builtins-build-export.c:67
#: app/flatpak-builtins-build-update-repo.c:83
#: app/flatpak-builtins-install.c:81 app/flatpak-builtins-remote-add.c:84
#: app/flatpak-builtins-remote-add.c:86 app/flatpak-builtins-remote-modify.c:89
#: app/flatpak-builtins-remote-modify.c:92
msgid "FILE"
msgstr "FICHIER"

#: app/flatpak-builtins-build-bundle.c:64
msgid "GPG Key ID to sign the OCI image with"
msgstr "ID de clé GPG pour signer l'image OCI avec"

#: app/flatpak-builtins-build-bundle.c:64
#: app/flatpak-builtins-build-commit-from.c:68
#: app/flatpak-builtins-build-export.c:68
#: app/flatpak-builtins-build-import-bundle.c:49
#: app/flatpak-builtins-build-sign.c:44
#: app/flatpak-builtins-build-update-repo.c:84
msgid "KEY-ID"
msgstr "ID-DE-CLÉ"

#: app/flatpak-builtins-build-bundle.c:65
#: app/flatpak-builtins-build-commit-from.c:69
#: app/flatpak-builtins-build-export.c:71
#: app/flatpak-builtins-build-import-bundle.c:50
#: app/flatpak-builtins-build-sign.c:45
#: app/flatpak-builtins-build-update-repo.c:85
msgid "GPG Homedir to use when looking for keyrings"
msgstr ""
"Répertoire personnel GPG à utiliser lors de la recherche de trousseaux de "
"clés"

#: app/flatpak-builtins-build-bundle.c:65
#: app/flatpak-builtins-build-commit-from.c:69
#: app/flatpak-builtins-build-export.c:71
#: app/flatpak-builtins-build-import-bundle.c:50
#: app/flatpak-builtins-build-sign.c:45
#: app/flatpak-builtins-build-update-repo.c:85
msgid "HOMEDIR"
msgstr "RÉPERTOIRE PERSONNEL"

#: app/flatpak-builtins-build-bundle.c:66
msgid "OSTree commit to create a delta bundle from"
msgstr "OSTree commit pour créer une liasse delta à partir de"

#: app/flatpak-builtins-build-bundle.c:66 app/flatpak-builtins-remote-info.c:55
#: app/flatpak-builtins-update.c:57
msgid "COMMIT"
msgstr "COMMIT"

#: app/flatpak-builtins-build-bundle.c:67
msgid "Export oci image instead of flatpak bundle"
msgstr "Exporter l'image oci au lieu d'une liasse flatpak"

#: app/flatpak-builtins-build-bundle.c:70
msgid "How to compress OCI image layers (default: gzip)"
msgstr ""

#: app/flatpak-builtins-build-bundle.c:634
msgid ""
"LOCATION FILENAME NAME [BRANCH] - Create a single file bundle from a local "
"repository"
msgstr ""
"LOCALISATION NOMDUFICHIER NOM [BRANCHE] - Créer une liasse simple à partir "
"d'un dépôt locale"

#: app/flatpak-builtins-build-bundle.c:641
msgid "LOCATION, FILENAME and NAME must be specified"
msgstr "LOCALISATION, NOMDUFICHIER et NOM doivent êtres spécifiés"

#: app/flatpak-builtins-build-bundle.c:644
#: app/flatpak-builtins-build-export.c:844
#: app/flatpak-builtins-build-import-bundle.c:136
#: app/flatpak-builtins-build-init.c:217 app/flatpak-builtins-build-sign.c:76
#: app/flatpak-builtins-document-export.c:112
#: app/flatpak-builtins-document-info.c:75
#: app/flatpak-builtins-document-list.c:191
#: app/flatpak-builtins-document-unexport.c:70
#: app/flatpak-builtins-history.c:482 app/flatpak-builtins-info.c:130
#: app/flatpak-builtins-install.c:181 app/flatpak-builtins-install.c:234
#: app/flatpak-builtins-install.c:298 app/flatpak-builtins-list.c:419
#: app/flatpak-builtins-make-current.c:72 app/flatpak-builtins-override.c:73
#: app/flatpak-builtins-permission-list.c:162
#: app/flatpak-builtins-permission-remove.c:132
#: app/flatpak-builtins-remote-add.c:323
#: app/flatpak-builtins-remote-delete.c:68
#: app/flatpak-builtins-remote-list.c:241 app/flatpak-builtins-remote-ls.c:407
msgid "Too many arguments"
msgstr "Trop d'arguments"

#: app/flatpak-builtins-build-bundle.c:659
#: app/flatpak-builtins-build-commit-from.c:338
#: app/flatpak-builtins-build-commit-from.c:351
#: app/flatpak-builtins-build-import-bundle.c:145
#, c-format
msgid "'%s' is not a valid repository"
msgstr "`%s` n'est pas un dépôt valide"

#: app/flatpak-builtins-build-bundle.c:663
#, c-format
msgid "'%s' is not a valid repository: "
msgstr "`%s` n'est pas un dépôt valide: "

#: app/flatpak-builtins-build-bundle.c:674 app/flatpak-builtins-build-sign.c:88
#: common/flatpak-dir.c:14293
#, c-format
msgid "'%s' is not a valid name: %s"
msgstr "'%s' n'est pas un nom valide: %s"

#: app/flatpak-builtins-build-bundle.c:677
#: app/flatpak-builtins-build-export.c:865 app/flatpak-builtins-build-sign.c:91
#: common/flatpak-dir.c:14299
#, c-format
msgid "'%s' is not a valid branch name: %s"
msgstr "'%s' n'est pas un nom de branche valide: %s"

#: app/flatpak-builtins-build-bundle.c:691
#: app/flatpak-builtins-build-import-bundle.c:149
#: app/flatpak-builtins-build-init.c:281
#, c-format
msgid "'%s' is not a valid filename"
msgstr "'%s' n'est pas un nomdufichier valide"

#: app/flatpak-builtins-build-bundle.c:706
msgid "--oci-layer-compress value must be gzip or zstd"
msgstr ""

#: app/flatpak-builtins-build.c:49
msgid "Use Platform runtime rather than Sdk"
msgstr "Utiliser le runtime de la plateforme plutôt que le Sdk"

#: app/flatpak-builtins-build.c:50
msgid "Make destination readonly"
msgstr "Rendre la cible en read-only"

#: app/flatpak-builtins-build.c:51
msgid "Add bind mount"
msgstr ""

#: app/flatpak-builtins-build.c:51
msgid "DEST=SRC"
msgstr "DEST=SRC"

#: app/flatpak-builtins-build.c:52
msgid "Start build in this directory"
msgstr ""

#: app/flatpak-builtins-build.c:52 app/flatpak-builtins-build.c:53
#: app/flatpak-builtins-build-init.c:64 app/flatpak-builtins-run.c:160
msgid "DIR"
msgstr ""

#: app/flatpak-builtins-build.c:53
msgid "Where to look for custom sdk dir (defaults to 'usr')"
msgstr ""

#: app/flatpak-builtins-build.c:54 app/flatpak-builtins-build-export.c:67
msgid "Use alternative file for the metadata"
msgstr ""

#: app/flatpak-builtins-build.c:55 app/flatpak-builtins-run.c:177
msgid "Kill processes when the parent process dies"
msgstr ""

#: app/flatpak-builtins-build.c:56
msgid "Export application homedir directory to build"
msgstr ""

#: app/flatpak-builtins-build.c:57 app/flatpak-builtins-run.c:165
msgid "Log session bus calls"
msgstr ""

#: app/flatpak-builtins-build.c:58 app/flatpak-builtins-run.c:166
msgid "Log system bus calls"
msgstr ""

#: app/flatpak-builtins-build.c:262
msgid "DIRECTORY [COMMAND [ARGUMENT…]] - Build in directory"
msgstr ""

#: app/flatpak-builtins-build.c:285 app/flatpak-builtins-build-finish.c:656
msgid "DIRECTORY must be specified"
msgstr ""

#: app/flatpak-builtins-build.c:296 app/flatpak-builtins-build-export.c:887
#, c-format
msgid "Build directory %s not initialized, use flatpak build-init"
msgstr ""

#: app/flatpak-builtins-build.c:315
msgid "metadata invalid, not application or runtime"
msgstr ""

#: app/flatpak-builtins-build.c:446
#, c-format
msgid "No extension point matching %s in %s"
msgstr ""

#: app/flatpak-builtins-build.c:635
#, c-format
msgid "Missing '=' in bind mount option '%s'"
msgstr ""

#: app/flatpak-builtins-build.c:679 common/flatpak-run.c:3961
#, c-format
msgid "Unable to start app"
msgstr ""

#: app/flatpak-builtins-build-commit-from.c:58
msgid "Source repo dir"
msgstr ""

#: app/flatpak-builtins-build-commit-from.c:58
msgid "SRC-REPO"
msgstr ""

#: app/flatpak-builtins-build-commit-from.c:59
msgid "Source repo ref"
msgstr ""

#: app/flatpak-builtins-build-commit-from.c:59
msgid "SRC-REF"
msgstr ""

#: app/flatpak-builtins-build-commit-from.c:64
#: app/flatpak-builtins-build-export.c:60
msgid "One line subject"
msgstr ""

#: app/flatpak-builtins-build-commit-from.c:64
#: app/flatpak-builtins-build-export.c:60
msgid "SUBJECT"
msgstr ""

#: app/flatpak-builtins-build-commit-from.c:65
#: app/flatpak-builtins-build-export.c:61
msgid "Full description"
msgstr ""

#: app/flatpak-builtins-build-commit-from.c:65
#: app/flatpak-builtins-build-export.c:61
msgid "BODY"
msgstr ""

#: app/flatpak-builtins-build-commit-from.c:66
#: app/flatpak-builtins-build-export.c:64
#: app/flatpak-builtins-build-import-bundle.c:51
msgid "Update the appstream branch"
msgstr ""

#: app/flatpak-builtins-build-commit-from.c:67
#: app/flatpak-builtins-build-export.c:65
#: app/flatpak-builtins-build-import-bundle.c:52
#: app/flatpak-builtins-build-update-repo.c:87
msgid "Don't update the summary"
msgstr ""

#: app/flatpak-builtins-build-commit-from.c:68
#: app/flatpak-builtins-build-export.c:68
#: app/flatpak-builtins-build-import-bundle.c:49
#: app/flatpak-builtins-build-sign.c:44
msgid "GPG Key ID to sign the commit with"
msgstr ""

#: app/flatpak-builtins-build-commit-from.c:70
#: app/flatpak-builtins-build-export.c:73
msgid "Mark build as end-of-life"
msgstr ""

#: app/flatpak-builtins-build-commit-from.c:70
#: app/flatpak-builtins-build-export.c:73
msgid "REASON"
msgstr ""

#: app/flatpak-builtins-build-commit-from.c:71
msgid ""
"Mark refs matching the OLDID prefix as end-of-life, to be replaced with the "
"given NEWID"
msgstr ""

#: app/flatpak-builtins-build-commit-from.c:71
msgid "OLDID=NEWID"
msgstr ""

#: app/flatpak-builtins-build-commit-from.c:72
#: app/flatpak-builtins-build-export.c:75
msgid "Set type of token needed to install this commit"
msgstr ""

#: app/flatpak-builtins-build-commit-from.c:72
#: app/flatpak-builtins-build-export.c:75
msgid "VAL"
msgstr ""

#: app/flatpak-builtins-build-commit-from.c:73
msgid "Override the timestamp of the commit (NOW for current time)"
msgstr ""

#: app/flatpak-builtins-build-commit-from.c:73
#: app/flatpak-builtins-build-export.c:76
msgid "TIMESTAMP"
msgstr ""

#: app/flatpak-builtins-build-commit-from.c:75
#: app/flatpak-builtins-build-export.c:80
#: app/flatpak-builtins-build-import-bundle.c:53
#: app/flatpak-builtins-build-update-repo.c:97
msgid "Don't generate a summary index"
msgstr ""

#: app/flatpak-builtins-build-commit-from.c:278
msgid "DST-REPO [DST-REF…] - Make a new commit from existing commits"
msgstr ""

#: app/flatpak-builtins-build-commit-from.c:285
msgid "DST-REPO must be specified"
msgstr ""

#: app/flatpak-builtins-build-commit-from.c:293
msgid ""
"If --src-repo is not specified, exactly one destination ref must be specified"
msgstr ""

#: app/flatpak-builtins-build-commit-from.c:296
msgid ""
"If --src-ref is specified, exactly one destination ref must be specified"
msgstr ""

#: app/flatpak-builtins-build-commit-from.c:299
msgid "Either --src-repo or --src-ref must be specified"
msgstr ""

#: app/flatpak-builtins-build-commit-from.c:315
msgid "Invalid argument format of use  --end-of-life-rebase=OLDID=NEWID"
msgstr ""

#: app/flatpak-builtins-build-commit-from.c:321
#: app/flatpak-builtins-build-commit-from.c:324
#, c-format
msgid "Invalid name %s in --end-of-life-rebase"
msgstr ""

#: app/flatpak-builtins-build-commit-from.c:333
#: app/flatpak-builtins-build-export.c:1092
#, c-format
msgid "Could not parse '%s'"
msgstr ""

#: app/flatpak-builtins-build-commit-from.c:498
msgid "Can't commit from partial source commit"
msgstr ""

#: app/flatpak-builtins-build-commit-from.c:503
#, c-format
msgid "%s: no change\n"
msgstr ""

#: app/flatpak-builtins-build-export.c:62
msgid "Architecture to export for (must be host compatible)"
msgstr ""

#: app/flatpak-builtins-build-export.c:63
msgid "Commit runtime (/usr), not /app"
msgstr ""

#: app/flatpak-builtins-build-export.c:66
msgid "Use alternative directory for the files"
msgstr ""

#: app/flatpak-builtins-build-export.c:66
msgid "SUBDIR"
msgstr ""

#: app/flatpak-builtins-build-export.c:69
msgid "Files to exclude"
msgstr ""

#: app/flatpak-builtins-build-export.c:69
#: app/flatpak-builtins-build-export.c:70
#: app/flatpak-builtins-build-update-repo.c:90
msgid "PATTERN"
msgstr ""

#: app/flatpak-builtins-build-export.c:70
msgid "Excluded files to include"
msgstr ""

#: app/flatpak-builtins-build-export.c:74
msgid "Mark build as end-of-life, to be replaced with the given ID"
msgstr ""

#: app/flatpak-builtins-build-export.c:74
#: app/flatpak-builtins-document-list.c:49 app/flatpak-cli-transaction.c:1427
msgid "ID"
msgstr ""

#: app/flatpak-builtins-build-export.c:76
msgid "Override the timestamp of the commit"
msgstr ""

#: app/flatpak-builtins-build-export.c:77
#: app/flatpak-builtins-build-update-repo.c:75
#: app/flatpak-builtins-remote-add.c:83 app/flatpak-builtins-remote-list.c:54
#: app/flatpak-builtins-remote-modify.c:88
msgid "Collection ID"
msgstr ""

#: app/flatpak-builtins-build-export.c:472
#, c-format
msgid "WARNING: Error running desktop-file-validate: %s\n"
msgstr ""

#: app/flatpak-builtins-build-export.c:480
#, c-format
msgid "WARNING: Error reading from desktop-file-validate: %s\n"
msgstr ""

#: app/flatpak-builtins-build-export.c:486
#, c-format
msgid "WARNING: Failed to validate desktop file %s: %s\n"
msgstr ""

#: app/flatpak-builtins-build-export.c:513
#, c-format
msgid "WARNING: Can't find Exec key in %s: %s\n"
msgstr ""

#: app/flatpak-builtins-build-export.c:521
#: app/flatpak-builtins-build-export.c:614
#, c-format
msgid "WARNING: Binary not found for Exec line in %s: %s\n"
msgstr ""

#: app/flatpak-builtins-build-export.c:529
#, c-format
msgid "WARNING: Icon not matching app id in %s: %s\n"
msgstr ""

#: app/flatpak-builtins-build-export.c:552
#, c-format
msgid "WARNING: Icon referenced in desktop file but not exported: %s\n"
msgstr ""

#: app/flatpak-builtins-build-export.c:719
#, c-format
msgid "Invalid uri type %s, only http/https supported"
msgstr ""

#: app/flatpak-builtins-build-export.c:737
#, c-format
msgid "Unable to find basename in %s, specify a name explicitly"
msgstr ""

#: app/flatpak-builtins-build-export.c:746
#, c-format
msgid "No slashes allowed in extra data name"
msgstr ""

#: app/flatpak-builtins-build-export.c:758
#, c-format
msgid "Invalid format for sha256 checksum: '%s'"
msgstr ""

#: app/flatpak-builtins-build-export.c:768
#, c-format
msgid "Extra data sizes of zero not supported"
msgstr ""

#: app/flatpak-builtins-build-export.c:830
msgid ""
"LOCATION DIRECTORY [BRANCH] - Create a repository from a build directory"
msgstr ""

#: app/flatpak-builtins-build-export.c:838
msgid "LOCATION and DIRECTORY must be specified"
msgstr ""

#: app/flatpak-builtins-build-export.c:859
#: app/flatpak-builtins-remote-add.c:327
#, c-format
msgid "‘%s’ is not a valid collection ID: %s"
msgstr ""

#: app/flatpak-builtins-build-export.c:904
#: app/flatpak-builtins-build-finish.c:684
msgid "No name specified in the metadata"
msgstr ""

#: app/flatpak-builtins-build-export.c:1166
#, c-format
msgid "Commit: %s\n"
msgstr ""

#: app/flatpak-builtins-build-export.c:1167
#, c-format
msgid "Metadata Total: %u\n"
msgstr ""

#: app/flatpak-builtins-build-export.c:1168
#, c-format
msgid "Metadata Written: %u\n"
msgstr ""

#: app/flatpak-builtins-build-export.c:1169
#, c-format
msgid "Content Total: %u\n"
msgstr ""

#: app/flatpak-builtins-build-export.c:1170
#, c-format
msgid "Content Written: %u\n"
msgstr ""

#: app/flatpak-builtins-build-export.c:1171
#, c-format
msgid "Content Bytes Written:"
msgstr ""

#: app/flatpak-builtins-build-finish.c:52
msgid "Command to set"
msgstr ""

#: app/flatpak-builtins-build-finish.c:52 app/flatpak-builtins-run.c:159
#: app/flatpak-main.c:209
msgid "COMMAND"
msgstr ""

#: app/flatpak-builtins-build-finish.c:53
msgid "Flatpak version to require"
msgstr ""

#: app/flatpak-builtins-build-finish.c:53
msgid "MAJOR.MINOR.MICRO"
msgstr ""

#: app/flatpak-builtins-build-finish.c:54
msgid "Don't process exports"
msgstr ""

#: app/flatpak-builtins-build-finish.c:55
msgid "Extra data info"
msgstr ""

#: app/flatpak-builtins-build-finish.c:56 app/flatpak-builtins-build-init.c:63
msgid "Add extension point info"
msgstr ""

#: app/flatpak-builtins-build-finish.c:56 app/flatpak-builtins-build-init.c:63
msgid "NAME=VARIABLE[=VALUE]"
msgstr ""

#: app/flatpak-builtins-build-finish.c:57
msgid "Remove extension point info"
msgstr ""

#: app/flatpak-builtins-build-finish.c:57
#: app/flatpak-builtins-build-update-repo.c:79 app/flatpak-builtins-info.c:58
#: app/flatpak-builtins-remote-add.c:88 app/flatpak-builtins-remote-modify.c:94
#: app/flatpak-main.c:182
msgid "NAME"
msgstr ""

#: app/flatpak-builtins-build-finish.c:58
msgid "Set extension priority (only for extensions)"
msgstr ""

#: app/flatpak-builtins-build-finish.c:58
msgid "VALUE"
msgstr ""

#: app/flatpak-builtins-build-finish.c:59
msgid "Change the sdk used for the app"
msgstr ""

#: app/flatpak-builtins-build-finish.c:59
msgid "SDK"
msgstr ""

#: app/flatpak-builtins-build-finish.c:60
msgid "Change the runtime used for the app"
msgstr ""

#: app/flatpak-builtins-build-finish.c:60 app/flatpak-builtins-build-init.c:54
#: app/flatpak-builtins-list.c:53 app/flatpak-builtins-remote-ls.c:58
#: app/flatpak-builtins-run.c:163
msgid "RUNTIME"
msgstr ""

#: app/flatpak-builtins-build-finish.c:61
msgid "Set generic metadata option"
msgstr ""

#: app/flatpak-builtins-build-finish.c:61
msgid "GROUP=KEY[=VALUE]"
msgstr ""

#: app/flatpak-builtins-build-finish.c:62
msgid "Don't inherit permissions from runtime"
msgstr ""

#: app/flatpak-builtins-build-finish.c:155
#, c-format
msgid "Not exporting %s, wrong extension\n"
msgstr ""

#: app/flatpak-builtins-build-finish.c:163
#, c-format
msgid "Not exporting %s, non-allowed export filename\n"
msgstr ""

#: app/flatpak-builtins-build-finish.c:167
#, c-format
msgid "Exporting %s\n"
msgstr ""

#: app/flatpak-builtins-build-finish.c:440
#, c-format
msgid "More than one executable found\n"
msgstr ""

#: app/flatpak-builtins-build-finish.c:451
#, c-format
msgid "Using %s as command\n"
msgstr ""

#: app/flatpak-builtins-build-finish.c:456
#, c-format
msgid "No executable found\n"
msgstr ""

#: app/flatpak-builtins-build-finish.c:511
#, c-format
msgid "Invalid --require-version argument: %s"
msgstr ""

#: app/flatpak-builtins-build-finish.c:543
#, c-format
msgid "Too few elements in --extra-data argument %s"
msgstr ""

#: app/flatpak-builtins-build-finish.c:575
#, c-format
msgid ""
"Too few elements in --metadata argument %s, format should be "
"GROUP=KEY[=VALUE]]"
msgstr ""

#: app/flatpak-builtins-build-finish.c:597
#: app/flatpak-builtins-build-init.c:458
#, c-format
msgid ""
"Too few elements in --extension argument %s, format should be "
"NAME=VAR[=VALUE]"
msgstr ""

#: app/flatpak-builtins-build-finish.c:603
#: app/flatpak-builtins-build-init.c:461
#, c-format
msgid "Invalid extension name %s"
msgstr ""

#: app/flatpak-builtins-build-finish.c:646
msgid "DIRECTORY - Finalize a build directory"
msgstr ""

#: app/flatpak-builtins-build-finish.c:668
#, c-format
msgid "Build directory %s not initialized"
msgstr ""

#: app/flatpak-builtins-build-finish.c:689
#, c-format
msgid "Build directory %s already finalized"
msgstr ""

#: app/flatpak-builtins-build-finish.c:702
#, c-format
msgid "Please review the exported files and the metadata\n"
msgstr ""

#: app/flatpak-builtins-build-import-bundle.c:47
msgid "Override the ref used for the imported bundle"
msgstr ""

#: app/flatpak-builtins-build-import-bundle.c:47
msgid "REF"
msgstr ""

#: app/flatpak-builtins-build-import-bundle.c:48
msgid "Import oci image instead of flatpak bundle"
msgstr ""

#: app/flatpak-builtins-build-import-bundle.c:77
#: app/flatpak-builtins-build-import-bundle.c:105
#, c-format
msgid "Importing %s (%s)\n"
msgstr ""

#: app/flatpak-builtins-build-import-bundle.c:126
msgid "LOCATION FILENAME - Import a file bundle into a local repository"
msgstr ""

#: app/flatpak-builtins-build-import-bundle.c:133
msgid "LOCATION and FILENAME must be specified"
msgstr ""

#: app/flatpak-builtins-build-init.c:53 app/flatpak-builtins-info.c:55
#: app/flatpak-builtins-run.c:158
msgid "Arch to use"
msgstr ""

#: app/flatpak-builtins-build-init.c:54
msgid "Initialize var from named runtime"
msgstr ""

#: app/flatpak-builtins-build-init.c:55
msgid "Initialize apps from named app"
msgstr ""

#: app/flatpak-builtins-build-init.c:55
msgid "APP"
msgstr ""

#: app/flatpak-builtins-build-init.c:56
msgid "Specify version for --base"
msgstr ""

#: app/flatpak-builtins-build-init.c:56 app/flatpak-builtins-run.c:164
msgid "VERSION"
msgstr ""

#: app/flatpak-builtins-build-init.c:57
msgid "Include this base extension"
msgstr ""

#: app/flatpak-builtins-build-init.c:57 app/flatpak-builtins-build-init.c:62
msgid "EXTENSION"
msgstr ""

#: app/flatpak-builtins-build-init.c:58
msgid "Extension tag to use if building extension"
msgstr ""

#: app/flatpak-builtins-build-init.c:58
msgid "EXTENSION_TAG"
msgstr ""

#: app/flatpak-builtins-build-init.c:59
msgid "Initialize /usr with a writable copy of the sdk"
msgstr ""

#: app/flatpak-builtins-build-init.c:60
msgid "Specify the build type (app, runtime, extension)"
msgstr ""

#: app/flatpak-builtins-build-init.c:60
msgid "TYPE"
msgstr ""

#: app/flatpak-builtins-build-init.c:61
msgid "Add a tag"
msgstr ""

#: app/flatpak-builtins-build-init.c:61
msgid "TAG"
msgstr ""

#: app/flatpak-builtins-build-init.c:62
msgid "Include this sdk extension in /usr"
msgstr ""

#: app/flatpak-builtins-build-init.c:64
msgid "Where to store sdk (defaults to 'usr')"
msgstr ""

#: app/flatpak-builtins-build-init.c:65
msgid "Re-initialize the sdk/var"
msgstr ""

#: app/flatpak-builtins-build-init.c:118
#, c-format
msgid "Requested extension %s/%s/%s is only partially installed"
msgstr ""

#: app/flatpak-builtins-build-init.c:147
#, c-format
msgid "Requested extension %s/%s/%s not installed"
msgstr ""

#: app/flatpak-builtins-build-init.c:207
msgid ""
"DIRECTORY APPNAME SDK RUNTIME [BRANCH] - Initialize a directory for building"
msgstr ""

#: app/flatpak-builtins-build-init.c:214
msgid "RUNTIME must be specified"
msgstr ""

#: app/flatpak-builtins-build-init.c:235
#, c-format
msgid "'%s' is not a valid build type name, use app, runtime or extension"
msgstr ""

#: app/flatpak-builtins-build-init.c:241 app/flatpak-builtins-override.c:79
#, c-format
msgid "'%s' is not a valid application name: %s"
msgstr ""

#: app/flatpak-builtins-build-init.c:295
#, c-format
msgid "Build directory %s already initialized"
msgstr ""

#: app/flatpak-builtins-build-sign.c:42 app/flatpak-builtins-install.c:67
#: app/flatpak-builtins-remote-info.c:54
msgid "Arch to install for"
msgstr ""

#: app/flatpak-builtins-build-sign.c:43 app/flatpak-builtins-create-usb.c:48
#: app/flatpak-builtins-install.c:74 app/flatpak-builtins-remote-info.c:56
#: app/flatpak-builtins-uninstall.c:58 app/flatpak-builtins-update.c:64
msgid "Look for runtime with the specified name"
msgstr ""

#: app/flatpak-builtins-build-sign.c:66
msgid "LOCATION [ID [BRANCH]] - Sign an application or runtime"
msgstr ""

#: app/flatpak-builtins-build-sign.c:73
#: app/flatpak-builtins-build-update-repo.c:499
#: app/flatpak-builtins-remote-add.c:320 app/flatpak-builtins-repo.c:739
msgid "LOCATION must be specified"
msgstr ""

#: app/flatpak-builtins-build-sign.c:94
msgid "No gpg key ids specified"
msgstr ""

#: app/flatpak-builtins-build-update-repo.c:68
msgid "Redirect this repo to a new URL"
msgstr ""

#: app/flatpak-builtins-build-update-repo.c:69
msgid "A nice name to use for this repository"
msgstr ""

#: app/flatpak-builtins-build-update-repo.c:69
#: app/flatpak-builtins-remote-add.c:77 app/flatpak-builtins-remote-modify.c:82
msgid "TITLE"
msgstr ""

#: app/flatpak-builtins-build-update-repo.c:70
msgid "A one-line comment for this repository"
msgstr ""

#: app/flatpak-builtins-build-update-repo.c:70
#: app/flatpak-builtins-remote-add.c:78 app/flatpak-builtins-remote-modify.c:83
msgid "COMMENT"
msgstr ""

#: app/flatpak-builtins-build-update-repo.c:71
msgid "A full-paragraph description for this repository"
msgstr ""

#: app/flatpak-builtins-build-update-repo.c:71
#: app/flatpak-builtins-remote-add.c:79 app/flatpak-builtins-remote-modify.c:84
msgid "DESCRIPTION"
msgstr ""

#: app/flatpak-builtins-build-update-repo.c:72
msgid "URL for a website for this repository"
msgstr ""

#: app/flatpak-builtins-build-update-repo.c:73
msgid "URL for an icon for this repository"
msgstr ""

#: app/flatpak-builtins-build-update-repo.c:74
msgid "Default branch to use for this repository"
msgstr ""

#: app/flatpak-builtins-build-update-repo.c:74
#: app/flatpak-builtins-remote-add.c:82 app/flatpak-builtins-remote-modify.c:87
#: app/flatpak-builtins-repo.c:713 app/flatpak-builtins-repo.c:714
#: app/flatpak-builtins-run.c:161
msgid "BRANCH"
msgstr ""

#: app/flatpak-builtins-build-update-repo.c:75
#: app/flatpak-builtins-remote-add.c:83 app/flatpak-builtins-remote-modify.c:88
msgid "COLLECTION-ID"
msgstr ""

#. Translators: A sideload is when you install from a local USB drive rather than the Internet.
#: app/flatpak-builtins-build-update-repo.c:77
msgid ""
"Permanently deploy collection ID to client remote configurations, only for "
"sideload support"
msgstr ""

#: app/flatpak-builtins-build-update-repo.c:78
msgid "Permanently deploy collection ID to client remote configurations"
msgstr ""

#: app/flatpak-builtins-build-update-repo.c:79
msgid "Name of authenticator for this repository"
msgstr ""

#: app/flatpak-builtins-build-update-repo.c:80
msgid "Autoinstall authenticator for this repository"
msgstr ""

#: app/flatpak-builtins-build-update-repo.c:81
msgid "Don't autoinstall authenticator for this repository"
msgstr ""

#: app/flatpak-builtins-build-update-repo.c:82
#: app/flatpak-builtins-remote-add.c:89
msgid "Authenticator option"
msgstr ""

#: app/flatpak-builtins-build-update-repo.c:82
#: app/flatpak-builtins-remote-add.c:89 app/flatpak-builtins-remote-modify.c:95
msgid "KEY=VALUE"
msgstr ""

#: app/flatpak-builtins-build-update-repo.c:83
msgid "Import new default GPG public key from FILE"
msgstr ""

#: app/flatpak-builtins-build-update-repo.c:84
msgid "GPG Key ID to sign the summary with"
msgstr ""

#: app/flatpak-builtins-build-update-repo.c:86
msgid "Generate delta files"
msgstr ""

#: app/flatpak-builtins-build-update-repo.c:88
msgid "Don't update the appstream branch"
msgstr ""

#: app/flatpak-builtins-build-update-repo.c:89
msgid "Max parallel jobs when creating deltas (default: NUMCPUs)"
msgstr ""

#: app/flatpak-builtins-build-update-repo.c:89
msgid "NUM-JOBS"
msgstr ""

#: app/flatpak-builtins-build-update-repo.c:90
msgid "Don't create deltas matching refs"
msgstr ""

#: app/flatpak-builtins-build-update-repo.c:91
msgid "Prune unused objects"
msgstr ""

#: app/flatpak-builtins-build-update-repo.c:92
msgid "Prune but don't actually remove anything"
msgstr ""

#: app/flatpak-builtins-build-update-repo.c:93
msgid "Only traverse DEPTH parents for each commit (default: -1=infinite)"
msgstr ""

#: app/flatpak-builtins-build-update-repo.c:93
msgid "DEPTH"
msgstr ""

#: app/flatpak-builtins-build-update-repo.c:223
#, c-format
msgid "Generating delta: %s (%.10s)\n"
msgstr ""

#: app/flatpak-builtins-build-update-repo.c:225
#, c-format
msgid "Generating delta: %s (%.10s-%.10s)\n"
msgstr ""

#: app/flatpak-builtins-build-update-repo.c:233
#, c-format
msgid "Failed to generate delta %s (%.10s): "
msgstr ""

#: app/flatpak-builtins-build-update-repo.c:236
#, c-format
msgid "Failed to generate delta %s (%.10s-%.10s): "
msgstr ""

#: app/flatpak-builtins-build-update-repo.c:492
msgid "LOCATION - Update repository metadata"
msgstr ""

#: app/flatpak-builtins-build-update-repo.c:609
#, c-format
msgid "Updating appstream branch\n"
msgstr ""

#: app/flatpak-builtins-build-update-repo.c:638
#, c-format
msgid "Updating summary\n"
msgstr ""

#: app/flatpak-builtins-build-update-repo.c:664
#, c-format
msgid "Total objects: %u\n"
msgstr ""

#: app/flatpak-builtins-build-update-repo.c:666
#, c-format
msgid "No unreachable objects\n"
msgstr ""

#: app/flatpak-builtins-build-update-repo.c:668
#, c-format
msgid "Deleted %u objects, %s freed\n"
msgstr ""

#: app/flatpak-builtins-config.c:41
msgid "List configuration keys and values"
msgstr ""

#: app/flatpak-builtins-config.c:42
msgid "Get configuration for KEY"
msgstr ""

#: app/flatpak-builtins-config.c:43
msgid "Set configuration for KEY to VALUE"
msgstr ""

#: app/flatpak-builtins-config.c:44
msgid "Unset configuration for KEY"
msgstr ""

#: app/flatpak-builtins-config.c:149
#, c-format
msgid "'%s' does not look like a language/locale code"
msgstr ""

#: app/flatpak-builtins-config.c:172
#, c-format
msgid "'%s' does not look like a language code"
msgstr ""

#: app/flatpak-builtins-config.c:190
#, fuzzy, c-format
msgid "'%s' is not a valid value (use 'true' or 'false')"
msgstr "`%s` n'est pas un dépôt valide: "

#: app/flatpak-builtins-config.c:262
#, c-format
msgid "Unknown configure key '%s'"
msgstr ""

#: app/flatpak-builtins-config.c:284
msgid "Too many arguments for --list"
msgstr ""

#: app/flatpak-builtins-config.c:314 app/flatpak-builtins-config.c:362
msgid "You must specify KEY"
msgstr ""

#: app/flatpak-builtins-config.c:316
msgid "Too many arguments for --get"
msgstr ""

#: app/flatpak-builtins-config.c:338
msgid "You must specify KEY and VALUE"
msgstr ""

#: app/flatpak-builtins-config.c:340
msgid "Too many arguments for --set"
msgstr ""

#: app/flatpak-builtins-config.c:364
msgid "Too many arguments for --unset"
msgstr ""

#: app/flatpak-builtins-config.c:383
msgid "[KEY [VALUE]] - Manage configuration"
msgstr ""

#: app/flatpak-builtins-config.c:394
msgid "Can only use one of --list, --get, --set or --unset"
msgstr ""

#: app/flatpak-builtins-config.c:408
msgid "Must specify one of --list, --get, --set or --unset"
msgstr ""

#: app/flatpak-builtins-create-usb.c:45 app/flatpak-builtins-install.c:75
#: app/flatpak-builtins-remote-info.c:57 app/flatpak-builtins-uninstall.c:59
#: app/flatpak-builtins-update.c:65
msgid "Look for app with the specified name"
msgstr ""

#: app/flatpak-builtins-create-usb.c:46
msgid "Arch to copy"
msgstr ""

#: app/flatpak-builtins-create-usb.c:47
msgid "DEST"
msgstr ""

#: app/flatpak-builtins-create-usb.c:49
msgid "Allow partial commits in the created repo"
msgstr ""

#: app/flatpak-builtins-create-usb.c:125 app/flatpak-builtins-create-usb.c:165
#, c-format
msgid ""
"Warning: Related ref ‘%s’ is partially installed. Use --allow-partial to "
"suppress this message.\n"
msgstr ""

#: app/flatpak-builtins-create-usb.c:158
#, c-format
msgid "Warning: Omitting related ref ‘%s’ because it is not installed.\n"
msgstr ""

#: app/flatpak-builtins-create-usb.c:175
#, c-format
msgid ""
"Warning: Omitting related ref ‘%s’ because its remote ‘%s’ does not have a "
"collection ID set.\n"
msgstr ""

#: app/flatpak-builtins-create-usb.c:187
#, c-format
msgid "Warning: Omitting related ref ‘%s’ because it's extra-data.\n"
msgstr ""

#: app/flatpak-builtins-create-usb.c:262 app/flatpak-builtins-create-usb.c:637
#, c-format
msgid ""
"Remote ‘%s’ does not have a collection ID set, which is required for P2P "
"distribution of ‘%s’."
msgstr ""

#: app/flatpak-builtins-create-usb.c:272
#, c-format
msgid "Warning: Omitting ref ‘%s’ (runtime of ‘%s’) because it's extra-data.\n"
msgstr ""

#: app/flatpak-builtins-create-usb.c:484
msgid "MOUNT-PATH [REF…] - Copy apps or runtimes onto removable media"
msgstr ""

#: app/flatpak-builtins-create-usb.c:493
msgid "MOUNT-PATH and REF must be specified"
msgstr ""

#: app/flatpak-builtins-create-usb.c:607
#, c-format
msgid "Ref ‘%s’ found in multiple installations: %s. You must specify one."
msgstr ""

#: app/flatpak-builtins-create-usb.c:620
#, c-format
msgid "Refs must all be in the same installation (found in %s and %s)."
msgstr ""

#: app/flatpak-builtins-create-usb.c:670
#, c-format
msgid ""
"Warning: Ref ‘%s’ is partially installed. Use --allow-partial to suppress "
"this message.\n"
msgstr ""

#: app/flatpak-builtins-create-usb.c:681
#, c-format
msgid "Installed ref ‘%s’ is extra-data, and cannot be distributed offline"
msgstr ""

#: app/flatpak-builtins-create-usb.c:721
#, c-format
msgid "Warning: Couldn't update repo metadata for remote ‘%s’: %s\n"
msgstr ""

#: app/flatpak-builtins-create-usb.c:751
#, c-format
msgid "Warning: Couldn't update appstream data for remote ‘%s’ arch ‘%s’: %s\n"
msgstr ""

#. Print a warning if both appstream and appstream2 are missing
#: app/flatpak-builtins-create-usb.c:784
#, c-format
msgid ""
"Warning: Couldn't find appstream data for remote ‘%s’ arch ‘%s’: %s; %s\n"
msgstr ""

#. Appstream2 is only for efficiency, so just print a debug message
#: app/flatpak-builtins-create-usb.c:790
#, c-format
msgid "Couldn't find appstream2 data for remote ‘%s’ arch ‘%s’: %s\n"
msgstr ""

#: app/flatpak-builtins-document-export.c:62
msgid "Create a unique document reference"
msgstr ""

#: app/flatpak-builtins-document-export.c:63
msgid "Make the document transient for the current session"
msgstr ""

#: app/flatpak-builtins-document-export.c:64
msgid "Don't require the file to exist already"
msgstr ""

#: app/flatpak-builtins-document-export.c:65
msgid "Give the app read permissions"
msgstr ""

#: app/flatpak-builtins-document-export.c:66
msgid "Give the app write permissions"
msgstr ""

#: app/flatpak-builtins-document-export.c:67
msgid "Give the app delete permissions"
msgstr ""

#: app/flatpak-builtins-document-export.c:68
msgid "Give the app permissions to grant further permissions"
msgstr ""

#: app/flatpak-builtins-document-export.c:69
msgid "Revoke read permissions of the app"
msgstr ""

#: app/flatpak-builtins-document-export.c:70
msgid "Revoke write permissions of the app"
msgstr ""

#: app/flatpak-builtins-document-export.c:71
msgid "Revoke delete permissions of the app"
msgstr ""

#: app/flatpak-builtins-document-export.c:72
msgid "Revoke the permission to grant further permissions"
msgstr ""

#: app/flatpak-builtins-document-export.c:73
msgid "Add permissions for this app"
msgstr ""

#: app/flatpak-builtins-document-export.c:73
msgid "APPID"
msgstr ""

#: app/flatpak-builtins-document-export.c:100
msgid "FILE - Export a file to apps"
msgstr ""

#: app/flatpak-builtins-document-export.c:109
#: app/flatpak-builtins-document-info.c:72
#: app/flatpak-builtins-document-unexport.c:67
msgid "FILE must be specified"
msgstr ""

#: app/flatpak-builtins-document-info.c:63
msgid "FILE - Get information about an exported file"
msgstr ""

#: app/flatpak-builtins-document-info.c:100
#: app/flatpak-builtins-document-unexport.c:94
#, c-format
msgid "Not exported\n"
msgstr ""

#: app/flatpak-builtins-document-list.c:43 app/flatpak-builtins-history.c:53
#: app/flatpak-builtins-list.c:54 app/flatpak-builtins-ps.c:43
#: app/flatpak-builtins-remote-list.c:45 app/flatpak-builtins-remote-ls.c:59
#: app/flatpak-builtins-search.c:38
msgid "What information to show"
msgstr ""

#: app/flatpak-builtins-document-list.c:43 app/flatpak-builtins-history.c:53
#: app/flatpak-builtins-list.c:54 app/flatpak-builtins-ps.c:43
#: app/flatpak-builtins-remote-list.c:45 app/flatpak-builtins-remote-ls.c:59
#: app/flatpak-builtins-search.c:38
msgid "FIELD,…"
msgstr ""

#: app/flatpak-builtins-document-list.c:44 app/flatpak-builtins-history.c:54
#: app/flatpak-builtins-list.c:52 app/flatpak-builtins-permission-list.c:43
#: app/flatpak-builtins-permission-show.c:43 app/flatpak-builtins-ps.c:44
#: app/flatpak-builtins-remote-list.c:46 app/flatpak-builtins-remote-ls.c:63
#: app/flatpak-builtins-repo.c:717 app/flatpak-builtins-search.c:39
msgid "Show output in JSON format"
msgstr ""

#: app/flatpak-builtins-document-list.c:49
msgid "Show the document ID"
msgstr ""

#: app/flatpak-builtins-document-list.c:50
msgid "Path"
msgstr ""

#: app/flatpak-builtins-document-list.c:50
#: app/flatpak-builtins-document-list.c:51
msgid "Show the document path"
msgstr ""

#: app/flatpak-builtins-document-list.c:51 app/flatpak-builtins-list.c:66
#: app/flatpak-builtins-remote-ls.c:74
msgid "Origin"
msgstr ""

#: app/flatpak-builtins-document-list.c:52 app/flatpak-builtins-history.c:62
#: app/flatpak-builtins-ps.c:52
msgid "Application"
msgstr ""

#: app/flatpak-builtins-document-list.c:52
msgid "Show applications with permission"
msgstr ""

#: app/flatpak-builtins-document-list.c:53
#: app/flatpak-builtins-permission-list.c:182
#: app/flatpak-builtins-permission-show.c:145
msgid "Permissions"
msgstr ""

#: app/flatpak-builtins-document-list.c:53
msgid "Show permissions for applications"
msgstr ""

#: app/flatpak-builtins-document-list.c:161
#, c-format
msgid "No documents found\n"
msgstr ""

#: app/flatpak-builtins-document-list.c:180
msgid "[APPID] - List exported files"
msgstr ""

#: app/flatpak-builtins-document-unexport.c:43
msgid "Specify the document ID"
msgstr ""

#: app/flatpak-builtins-document-unexport.c:58
msgid "FILE - Unexport a file to apps"
msgstr ""

#: app/flatpak-builtins-enter.c:88
msgid "INSTANCE COMMAND [ARGUMENT…] - Run a command inside a running sandbox"
msgstr ""

#: app/flatpak-builtins-enter.c:111
msgid "INSTANCE and COMMAND must be specified"
msgstr ""

#: app/flatpak-builtins-enter.c:138
#, c-format
msgid "%s is neither a pid nor an application or instance ID"
msgstr ""

#: app/flatpak-builtins-enter.c:144
msgid "entering not supported (need unprivileged user namespaces, or sudo -E)"
msgstr ""

#: app/flatpak-builtins-enter.c:145
#, c-format
msgid "No such pid %s"
msgstr ""

#: app/flatpak-builtins-enter.c:158
msgid "Can't read cwd"
msgstr ""

#: app/flatpak-builtins-enter.c:163
msgid "Can't read root"
msgstr ""

#: app/flatpak-builtins-enter.c:191
#, c-format
msgid "Invalid %s namespace for pid %d"
msgstr ""

#: app/flatpak-builtins-enter.c:202
#, c-format
msgid "Invalid %s namespace for self"
msgstr ""

#: app/flatpak-builtins-enter.c:216
#, c-format
msgid "Can't open %s namespace: %s"
msgstr ""

#: app/flatpak-builtins-enter.c:226
msgid "entering not supported (need unprivileged user namespaces)"
msgstr ""

#: app/flatpak-builtins-enter.c:227
#, c-format
msgid "Can't enter %s namespace: %s"
msgstr ""

#: app/flatpak-builtins-enter.c:234
msgid "Can't chdir"
msgstr ""

#: app/flatpak-builtins-enter.c:237
msgid "Can't chroot"
msgstr ""

#: app/flatpak-builtins-enter.c:240
msgid "Can't switch gid"
msgstr ""

#: app/flatpak-builtins-enter.c:243
msgid "Can't switch uid"
msgstr ""

#: app/flatpak-builtins-history.c:50
msgid "Only show changes after TIME"
msgstr ""

#: app/flatpak-builtins-history.c:50 app/flatpak-builtins-history.c:51
msgid "TIME"
msgstr ""

#: app/flatpak-builtins-history.c:51
msgid "Only show changes before TIME"
msgstr ""

#: app/flatpak-builtins-history.c:52
msgid "Show newest entries first"
msgstr ""

#: app/flatpak-builtins-history.c:59
msgid "Time"
msgstr ""

#: app/flatpak-builtins-history.c:59
msgid "Show when the change happened"
msgstr ""

#: app/flatpak-builtins-history.c:60
msgid "Change"
msgstr ""

#: app/flatpak-builtins-history.c:60
msgid "Show the kind of change"
msgstr ""

#: app/flatpak-builtins-history.c:61 app/flatpak-builtins-list.c:68
#: app/flatpak-builtins-remote-ls.c:75 app/flatpak-builtins-repo.c:335
msgid "Ref"
msgstr ""

#: app/flatpak-builtins-history.c:61 app/flatpak-builtins-list.c:68
#: app/flatpak-builtins-remote-ls.c:75
msgid "Show the ref"
msgstr ""

#: app/flatpak-builtins-history.c:62
msgid "Show the application/runtime ID"
msgstr ""

#: app/flatpak-builtins-history.c:63 app/flatpak-builtins-list.c:64
#: app/flatpak-builtins-ps.c:53 app/flatpak-builtins-remote-ls.c:73
#: app/flatpak-cli-transaction.c:1435
msgid "Arch"
msgstr ""

#: app/flatpak-builtins-history.c:63 app/flatpak-builtins-list.c:64
#: app/flatpak-builtins-ps.c:53 app/flatpak-builtins-remote-ls.c:73
msgid "Show the architecture"
msgstr ""

#: app/flatpak-builtins-history.c:64 app/flatpak-builtins-list.c:63
#: app/flatpak-builtins-ps.c:54 app/flatpak-builtins-remote-ls.c:72
#: app/flatpak-builtins-search.c:48 app/flatpak-cli-transaction.c:1438
msgid "Branch"
msgstr ""

#: app/flatpak-builtins-history.c:64 app/flatpak-builtins-list.c:63
#: app/flatpak-builtins-remote-ls.c:72
msgid "Show the branch"
msgstr ""

#: app/flatpak-builtins-history.c:65 app/flatpak-builtins-list.c:67
msgid "Installation"
msgstr ""

#: app/flatpak-builtins-history.c:65
msgid "Show the affected installation"
msgstr ""

#: app/flatpak-builtins-history.c:66 app/flatpak-cli-transaction.c:1452
msgid "Remote"
msgstr ""

#: app/flatpak-builtins-history.c:66
msgid "Show the remote"
msgstr ""

#: app/flatpak-builtins-history.c:67 app/flatpak-builtins-ps.c:55
#: app/flatpak-builtins-remote-ls.c:76
msgid "Commit"
msgstr ""

#: app/flatpak-builtins-history.c:67
msgid "Show the current commit"
msgstr ""

#: app/flatpak-builtins-history.c:68
msgid "Old Commit"
msgstr ""

#: app/flatpak-builtins-history.c:68
msgid "Show the previous commit"
msgstr ""

#: app/flatpak-builtins-history.c:69
msgid "Show the remote URL"
msgstr ""

#: app/flatpak-builtins-history.c:70 app/flatpak-cli-transaction.c:700
msgid "User"
msgstr ""

#: app/flatpak-builtins-history.c:70
msgid "Show the user doing the change"
msgstr ""

#: app/flatpak-builtins-history.c:71
msgid "Tool"
msgstr ""

#: app/flatpak-builtins-history.c:71
msgid "Show the tool that was used"
msgstr ""

#: app/flatpak-builtins-history.c:72 app/flatpak-builtins-list.c:62
#: app/flatpak-builtins-remote-ls.c:71 app/flatpak-builtins-search.c:47
msgid "Version"
msgstr ""

#: app/flatpak-builtins-history.c:72
msgid "Show the Flatpak version"
msgstr ""

#: app/flatpak-builtins-history.c:91
#, c-format
msgid "Failed to get journal data (%s): %s"
msgstr ""

#: app/flatpak-builtins-history.c:146
#, c-format
msgid "Failed to open journal: %s"
msgstr ""

#: app/flatpak-builtins-history.c:153
#, c-format
msgid "Failed to add match to journal: %s"
msgstr ""

#: app/flatpak-builtins-history.c:471
msgid " - Show history"
msgstr ""

#: app/flatpak-builtins-history.c:490
#, c-format
msgid "Failed to parse the --since option"
msgstr ""

#: app/flatpak-builtins-history.c:501
#, c-format
msgid "Failed to parse the --until option"
msgstr ""

#: app/flatpak-builtins-info.c:56
msgid "Show user installations"
msgstr ""

#: app/flatpak-builtins-info.c:57
msgid "Show system-wide installations"
msgstr ""

#: app/flatpak-builtins-info.c:58
msgid "Show specific system-wide installations"
msgstr ""

#: app/flatpak-builtins-info.c:59 app/flatpak-builtins-remote-info.c:59
msgid "Show ref"
msgstr ""

#: app/flatpak-builtins-info.c:60 app/flatpak-builtins-remote-info.c:60
msgid "Show commit"
msgstr ""

#: app/flatpak-builtins-info.c:61
msgid "Show origin"
msgstr ""

#: app/flatpak-builtins-info.c:62
msgid "Show size"
msgstr ""

#: app/flatpak-builtins-info.c:63 app/flatpak-builtins-remote-info.c:62
msgid "Show metadata"
msgstr ""

#: app/flatpak-builtins-info.c:64 app/flatpak-builtins-remote-info.c:63
msgid "Show runtime"
msgstr ""

#: app/flatpak-builtins-info.c:65 app/flatpak-builtins-remote-info.c:64
msgid "Show sdk"
msgstr ""

#: app/flatpak-builtins-info.c:66
msgid "Show permissions"
msgstr ""

#: app/flatpak-builtins-info.c:67
msgid "Query file access"
msgstr ""

#: app/flatpak-builtins-info.c:67 app/flatpak-builtins-install.c:82
#: app/flatpak-builtins-install.c:88 app/flatpak-builtins-preinstall.c:68
#: app/flatpak-builtins-run.c:182 app/flatpak-builtins-run.c:184
#: app/flatpak-builtins-update.c:67 app/flatpak-builtins-update.c:71
msgid "PATH"
msgstr ""

#: app/flatpak-builtins-info.c:68
msgid "Show extensions"
msgstr ""

#: app/flatpak-builtins-info.c:69
msgid "Show location"
msgstr ""

#: app/flatpak-builtins-info.c:116
msgid "NAME [BRANCH] - Get info about an installed app or runtime"
msgstr ""

#: app/flatpak-builtins-info.c:123 app/flatpak-builtins-remote-add.c:317
#: app/flatpak-builtins-remote-delete.c:63
msgid "NAME must be specified"
msgstr ""

#: app/flatpak-builtins-info.c:196
msgid "ref not present in origin"
msgstr ""

#: app/flatpak-builtins-info.c:211 app/flatpak-builtins-remote-info.c:217
#, c-format
msgid "Warning: Commit has no flatpak metadata\n"
msgstr ""

#: app/flatpak-builtins-info.c:217 app/flatpak-builtins-info.c:259
#: app/flatpak-builtins-info.c:455 app/flatpak-builtins-info.c:513
#: app/flatpak-builtins-remote-info.c:236
#: app/flatpak-builtins-remote-info.c:271
msgid "ID:"
msgstr ""

#: app/flatpak-builtins-info.c:218 app/flatpak-builtins-info.c:260
#: app/flatpak-builtins-remote-info.c:237
#: app/flatpak-builtins-remote-info.c:272
msgid "Ref:"
msgstr ""

#: app/flatpak-builtins-info.c:219 app/flatpak-builtins-info.c:261
#: app/flatpak-builtins-remote-info.c:238
#: app/flatpak-builtins-remote-info.c:273
msgid "Arch:"
msgstr ""

#: app/flatpak-builtins-info.c:220 app/flatpak-builtins-info.c:262
#: app/flatpak-builtins-remote-info.c:239
#: app/flatpak-builtins-remote-info.c:274
msgid "Branch:"
msgstr ""

#: app/flatpak-builtins-info.c:222 app/flatpak-builtins-info.c:264
#: app/flatpak-builtins-remote-info.c:241
#: app/flatpak-builtins-remote-info.c:276
msgid "Version:"
msgstr ""

#: app/flatpak-builtins-info.c:224 app/flatpak-builtins-info.c:266
#: app/flatpak-builtins-remote-info.c:243
#: app/flatpak-builtins-remote-info.c:278
msgid "License:"
msgstr ""

#: app/flatpak-builtins-info.c:226 app/flatpak-builtins-info.c:269
#: app/flatpak-builtins-remote-info.c:245
#: app/flatpak-builtins-remote-info.c:280
msgid "Collection:"
msgstr ""

#: app/flatpak-builtins-info.c:227 app/flatpak-builtins-info.c:270
#: app/flatpak-builtins-info.c:458 app/flatpak-builtins-info.c:516
msgid "Installation:"
msgstr ""

#: app/flatpak-builtins-info.c:228 app/flatpak-builtins-info.c:271
#: app/flatpak-builtins-info.c:459 app/flatpak-builtins-info.c:517
#: app/flatpak-builtins-remote-info.c:249
#: app/flatpak-builtins-remote-info.c:284
msgid "Installed Size:"
msgstr ""

#: app/flatpak-builtins-info.c:231 app/flatpak-builtins-info.c:279
#: app/flatpak-builtins-remote-info.c:252
#: app/flatpak-builtins-remote-info.c:288
msgid "Runtime:"
msgstr ""

#: app/flatpak-builtins-info.c:232 app/flatpak-builtins-info.c:288
#: app/flatpak-builtins-remote-info.c:253
#: app/flatpak-builtins-remote-info.c:293
msgid "Sdk:"
msgstr ""

#: app/flatpak-builtins-info.c:235 app/flatpak-builtins-info.c:313
#: app/flatpak-builtins-remote-info.c:256
#: app/flatpak-builtins-remote-info.c:319
msgid "Date:"
msgstr ""

#: app/flatpak-builtins-info.c:237 app/flatpak-builtins-info.c:311
#: app/flatpak-builtins-remote-info.c:258
#: app/flatpak-builtins-remote-info.c:317
msgid "Subject:"
msgstr ""

#: app/flatpak-builtins-info.c:240 app/flatpak-builtins-info.c:295
msgid "Active commit:"
msgstr ""

#: app/flatpak-builtins-info.c:241 app/flatpak-builtins-info.c:298
msgid "Latest commit:"
msgstr ""

#: app/flatpak-builtins-info.c:244 app/flatpak-builtins-info.c:303
#: app/flatpak-builtins-info.c:457 app/flatpak-builtins-info.c:515
#: app/flatpak-builtins-remote-info.c:259
#: app/flatpak-builtins-remote-info.c:298
msgid "Commit:"
msgstr ""

#: app/flatpak-builtins-info.c:246 app/flatpak-builtins-info.c:308
#: app/flatpak-builtins-remote-info.c:261
#: app/flatpak-builtins-remote-info.c:303
msgid "Parent:"
msgstr ""

#: app/flatpak-builtins-info.c:248 app/flatpak-builtins-info.c:321
msgid "Alt-id:"
msgstr ""

#: app/flatpak-builtins-info.c:250 app/flatpak-builtins-info.c:325
#: app/flatpak-builtins-remote-info.c:263
#: app/flatpak-builtins-remote-info.c:308
msgid "End-of-life:"
msgstr ""

#: app/flatpak-builtins-info.c:252 app/flatpak-builtins-info.c:330
#: app/flatpak-builtins-remote-info.c:265
#: app/flatpak-builtins-remote-info.c:313
msgid "End-of-life-rebase:"
msgstr ""

#: app/flatpak-builtins-info.c:254 app/flatpak-builtins-info.c:317
msgid "Subdirectories:"
msgstr ""

#: app/flatpak-builtins-info.c:255 app/flatpak-builtins-info.c:454
#: app/flatpak-builtins-info.c:512
msgid "Extension:"
msgstr ""

#: app/flatpak-builtins-info.c:267 app/flatpak-builtins-info.c:456
#: app/flatpak-builtins-info.c:514
msgid "Origin:"
msgstr ""

#: app/flatpak-builtins-info.c:460 app/flatpak-builtins-info.c:522
msgid "Subpaths:"
msgstr ""

#: app/flatpak-builtins-info.c:478
msgid "unmaintained"
msgstr ""

#: app/flatpak-builtins-info.c:480 app/flatpak-builtins-info.c:482
msgid "unknown"
msgstr ""

#: app/flatpak-builtins-install.c:68 app/flatpak-builtins-preinstall.c:57
msgid "Don't pull, only install from local cache"
msgstr ""

#: app/flatpak-builtins-install.c:69 app/flatpak-builtins-preinstall.c:58
#: app/flatpak-builtins-update.c:60
msgid "Don't deploy, only download to local cache"
msgstr ""

#: app/flatpak-builtins-install.c:70 app/flatpak-builtins-preinstall.c:59
msgid "Don't install related refs"
msgstr ""

#: app/flatpak-builtins-install.c:71 app/flatpak-builtins-preinstall.c:60
#: app/flatpak-builtins-update.c:62
msgid "Don't verify/install runtime dependencies"
msgstr ""

#: app/flatpak-builtins-install.c:72
msgid "Don't automatically pin explicit installs"
msgstr ""

#: app/flatpak-builtins-install.c:73 app/flatpak-builtins-preinstall.c:61
#: app/flatpak-builtins-update.c:63
msgid "Don't use static deltas"
msgstr ""

#: app/flatpak-builtins-install.c:76 app/flatpak-builtins-preinstall.c:62
msgid "Additionally install the SDK used to build the given refs"
msgstr ""

#: app/flatpak-builtins-install.c:77 app/flatpak-builtins-preinstall.c:63
msgid ""
"Additionally install the debug info for the given refs and their dependencies"
msgstr ""

#: app/flatpak-builtins-install.c:78
msgid "Assume LOCATION is a .flatpak single-file bundle"
msgstr ""

#: app/flatpak-builtins-install.c:79
msgid "Assume LOCATION is a .flatpakref application description"
msgstr ""

#: app/flatpak-builtins-install.c:80
msgid "Assume LOCATION is containers-transports(5) reference to an OCI image"
msgstr ""

#: app/flatpak-builtins-install.c:81
msgid "Check bundle signatures with GPG key from FILE (- for stdin)"
msgstr ""

#: app/flatpak-builtins-install.c:82
msgid "Only install this subpath"
msgstr ""

#: app/flatpak-builtins-install.c:83 app/flatpak-builtins-preinstall.c:64
#: app/flatpak-builtins-uninstall.c:63 app/flatpak-builtins-update.c:68
msgid "Automatically answer yes for all questions"
msgstr ""

#: app/flatpak-builtins-install.c:84 app/flatpak-builtins-preinstall.c:65
msgid "Uninstall first if already installed"
msgstr ""

#: app/flatpak-builtins-install.c:85 app/flatpak-builtins-preinstall.c:66
#: app/flatpak-builtins-uninstall.c:64 app/flatpak-builtins-update.c:69
msgid "Produce minimal output and don't ask questions"
msgstr ""

#: app/flatpak-builtins-install.c:86
msgid "Update install if already installed"
msgstr ""

#. Translators: A sideload is when you install from a local USB drive rather than the Internet.
#: app/flatpak-builtins-install.c:88 app/flatpak-builtins-preinstall.c:68
#: app/flatpak-builtins-update.c:71
msgid "Use this local repo for sideloads"
msgstr ""

#: app/flatpak-builtins-install.c:178
msgid "Bundle filename must be specified"
msgstr ""

#: app/flatpak-builtins-install.c:188
msgid "Remote bundles are not supported"
msgstr ""

#: app/flatpak-builtins-install.c:231
msgid "Filename or uri must be specified"
msgstr ""

#: app/flatpak-builtins-install.c:295
msgid "Image location must be specified"
msgstr ""

#: app/flatpak-builtins-install.c:345
msgid "[LOCATION/REMOTE] [REF…] - Install applications or runtimes"
msgstr ""

#: app/flatpak-builtins-install.c:378
msgid "At least one REF must be specified"
msgstr ""

#: app/flatpak-builtins-install.c:392
#, c-format
msgid "Looking for matches…\n"
msgstr ""

#: app/flatpak-builtins-install.c:513
#, c-format
msgid "No remote refs found for ‘%s’"
msgstr ""

#: app/flatpak-builtins-install.c:573 app/flatpak-builtins-uninstall.c:405
#: common/flatpak-ref-utils.c:689 common/flatpak-ref-utils.c:1595
#, c-format
msgid "Invalid branch %s: %s"
msgstr ""

#: app/flatpak-builtins-install.c:606
#, c-format
msgid "Nothing matches %s in local repository for remote %s"
msgstr ""

#: app/flatpak-builtins-install.c:608
#, c-format
msgid "Nothing matches %s in remote %s"
msgstr ""

#: app/flatpak-builtins-install.c:629
#, c-format
msgid "Skipping: %s\n"
msgstr ""

#: app/flatpak-builtins-kill.c:110
#, c-format
msgid "%s is not running"
msgstr ""

#: app/flatpak-builtins-kill.c:136
msgid "INSTANCE - Stop a running application"
msgstr ""

#: app/flatpak-builtins-kill.c:144 app/flatpak-builtins-ps.c:256
msgid "Extra arguments given"
msgstr ""

#: app/flatpak-builtins-kill.c:150
msgid "Must specify the app to kill"
msgstr ""

#: app/flatpak-builtins-list.c:47
msgid "Show extra information"
msgstr ""

#: app/flatpak-builtins-list.c:48
msgid "List installed runtimes"
msgstr ""

#: app/flatpak-builtins-list.c:49
msgid "List installed applications"
msgstr ""

#: app/flatpak-builtins-list.c:50
msgid "Arch to show"
msgstr ""

#: app/flatpak-builtins-list.c:51 app/flatpak-builtins-remote-ls.c:57
msgid "List all refs (including locale/debug)"
msgstr ""

#: app/flatpak-builtins-list.c:53 app/flatpak-builtins-remote-ls.c:58
msgid "List all applications using RUNTIME"
msgstr ""

#: app/flatpak-builtins-list.c:59 app/flatpak-builtins-remote-list.c:51
#: app/flatpak-builtins-remote-ls.c:68 app/flatpak-builtins-search.c:44
msgid "Name"
msgstr ""

#: app/flatpak-builtins-list.c:59 app/flatpak-builtins-remote-list.c:51
#: app/flatpak-builtins-remote-ls.c:68 app/flatpak-builtins-search.c:44
msgid "Show the name"
msgstr ""

#: app/flatpak-builtins-list.c:60 app/flatpak-builtins-remote-list.c:60
#: app/flatpak-builtins-remote-ls.c:69 app/flatpak-builtins-search.c:45
msgid "Description"
msgstr ""

#: app/flatpak-builtins-list.c:60 app/flatpak-builtins-remote-ls.c:69
#: app/flatpak-builtins-search.c:45
msgid "Show the description"
msgstr ""

#: app/flatpak-builtins-list.c:61 app/flatpak-builtins-remote-ls.c:70
#: app/flatpak-builtins-search.c:46
msgid "Application ID"
msgstr ""

#: app/flatpak-builtins-list.c:61 app/flatpak-builtins-ps.c:52
#: app/flatpak-builtins-remote-ls.c:70 app/flatpak-builtins-search.c:46
msgid "Show the application ID"
msgstr ""

#: app/flatpak-builtins-list.c:62 app/flatpak-builtins-remote-ls.c:71
#: app/flatpak-builtins-search.c:47
msgid "Show the version"
msgstr ""

#: app/flatpak-builtins-list.c:65 app/flatpak-builtins-ps.c:56
#: app/flatpak-builtins-remote-ls.c:77
msgid "Runtime"
msgstr ""

#: app/flatpak-builtins-list.c:65
msgid "Show the used runtime"
msgstr ""

#: app/flatpak-builtins-list.c:66 app/flatpak-builtins-remote-ls.c:74
msgid "Show the origin remote"
msgstr ""

#: app/flatpak-builtins-list.c:67
msgid "Show the installation"
msgstr ""

#: app/flatpak-builtins-list.c:69
msgid "Active commit"
msgstr ""

#: app/flatpak-builtins-list.c:69 app/flatpak-builtins-remote-ls.c:76
msgid "Show the active commit"
msgstr ""

#: app/flatpak-builtins-list.c:70
msgid "Latest commit"
msgstr ""

#: app/flatpak-builtins-list.c:70
msgid "Show the latest commit"
msgstr ""

#: app/flatpak-builtins-list.c:71 app/flatpak-builtins-remote-ls.c:78
msgid "Installed size"
msgstr ""

#: app/flatpak-builtins-list.c:71 app/flatpak-builtins-remote-ls.c:78
msgid "Show the installed size"
msgstr ""

#: app/flatpak-builtins-list.c:72 app/flatpak-builtins-remote-list.c:58
#: app/flatpak-builtins-remote-ls.c:80 app/flatpak-builtins-repo.c:340
msgid "Options"
msgstr ""

#: app/flatpak-builtins-list.c:72 app/flatpak-builtins-remote-list.c:58
#: app/flatpak-builtins-remote-ls.c:80
msgid "Show options"
msgstr ""

#: app/flatpak-builtins-list.c:180
#, c-format
msgid "Unable to load details of %s: %s"
msgstr ""

#: app/flatpak-builtins-list.c:190
#, c-format
msgid "Unable to inspect current version of %s: %s"
msgstr ""

#: app/flatpak-builtins-list.c:408
msgid " - List installed apps and/or runtimes"
msgstr ""

#: app/flatpak-builtins-make-current.c:38
msgid "Arch to make current for"
msgstr ""

#: app/flatpak-builtins-make-current.c:58
msgid "APP BRANCH - Make branch of application current"
msgstr ""

#: app/flatpak-builtins-make-current.c:69 app/flatpak-builtins-run.c:260
msgid "APP must be specified"
msgstr ""

#: app/flatpak-builtins-make-current.c:84
msgid "BRANCH must be specified"
msgstr ""

#: app/flatpak-builtins-make-current.c:97
#, c-format
msgid "App %s branch %s is not installed"
msgstr ""

#: app/flatpak-builtins-mask.c:42
msgid "Remove matching masks"
msgstr ""

#: app/flatpak-builtins-mask.c:54
msgid ""
"[PATTERN…] - disable updates and automatic installation matching patterns"
msgstr ""

#: app/flatpak-builtins-mask.c:73
#, c-format
msgid "No masked patterns\n"
msgstr ""

#: app/flatpak-builtins-mask.c:78
#, c-format
msgid "Masked patterns:\n"
msgstr ""

#: app/flatpak-builtins-override.c:42
msgid "Remove existing overrides"
msgstr ""

#: app/flatpak-builtins-override.c:43
msgid "Show existing overrides"
msgstr ""

#: app/flatpak-builtins-override.c:59
msgid "[APP] - Override settings [for application]"
msgstr ""

#: app/flatpak-builtins-permission-list.c:143
msgid "[TABLE] [ID] - List permissions"
msgstr ""

#: app/flatpak-builtins-permission-list.c:179
#: app/flatpak-builtins-permission-show.c:142
msgid "Table"
msgstr ""

#: app/flatpak-builtins-permission-list.c:180
#: app/flatpak-builtins-permission-show.c:143
msgid "Object"
msgstr ""

#: app/flatpak-builtins-permission-list.c:181
#: app/flatpak-builtins-permission-show.c:144
msgid "App"
msgstr ""

#: app/flatpak-builtins-permission-list.c:183
#: app/flatpak-builtins-permission-show.c:146
msgid "Data"
msgstr ""

#: app/flatpak-builtins-permission-remove.c:120
msgid "TABLE ID [APP_ID] - Remove item from permission store"
msgstr ""

#: app/flatpak-builtins-permission-remove.c:129
#: app/flatpak-builtins-permission-set.c:120
msgid "Too few arguments"
msgstr ""

#: app/flatpak-builtins-permission-reset.c:43
msgid "Reset all permissions"
msgstr ""

#: app/flatpak-builtins-permission-reset.c:144
msgid "APP_ID - Reset permissions for an app"
msgstr ""

#: app/flatpak-builtins-permission-reset.c:153
#: app/flatpak-builtins-permission-show.c:124
msgid "Wrong number of arguments"
msgstr ""

#: app/flatpak-builtins-permission-set.c:42
msgid "Associate DATA with the entry"
msgstr ""

#: app/flatpak-builtins-permission-set.c:42
msgid "DATA"
msgstr ""

#: app/flatpak-builtins-permission-set.c:111
msgid "TABLE ID APP_ID [PERMISSION...] - Set permissions"
msgstr ""

#: app/flatpak-builtins-permission-set.c:132
#, c-format
msgid "Failed to parse '%s' as GVariant: "
msgstr ""

#: app/flatpak-builtins-permission-show.c:115
msgid "APP_ID - Show permissions for an app"
msgstr ""

#: app/flatpak-builtins-pin.c:44
msgid "Remove matching pins"
msgstr ""

#: app/flatpak-builtins-pin.c:56
msgid "[PATTERN…] - disable automatic removal of runtimes matching patterns"
msgstr ""

#: app/flatpak-builtins-pin.c:75
#, c-format
msgid "No pinned patterns\n"
msgstr ""

#: app/flatpak-builtins-pin.c:80
#, c-format
msgid "Pinned patterns:\n"
msgstr ""

#: app/flatpak-builtins-preinstall.c:80
msgid "- Install flatpaks that are part of the operating system"
msgstr ""

#: app/flatpak-builtins-preinstall.c:118
#, c-format
msgid "Nothing to do.\n"
msgstr ""

#: app/flatpak-builtins-ps.c:49
msgid "Instance"
msgstr ""

#: app/flatpak-builtins-ps.c:49
msgid "Show the instance ID"
msgstr ""

#: app/flatpak-builtins-ps.c:50 app/flatpak-builtins-run.c:178
msgid "PID"
msgstr ""

#: app/flatpak-builtins-ps.c:50
msgid "Show the PID of the wrapper process"
msgstr ""

#: app/flatpak-builtins-ps.c:51
msgid "Child-PID"
msgstr ""

#: app/flatpak-builtins-ps.c:51
msgid "Show the PID of the sandbox process"
msgstr ""

#: app/flatpak-builtins-ps.c:54 app/flatpak-builtins-search.c:48
msgid "Show the application branch"
msgstr ""

#: app/flatpak-builtins-ps.c:55
msgid "Show the application commit"
msgstr ""

#: app/flatpak-builtins-ps.c:56
msgid "Show the runtime ID"
msgstr ""

#: app/flatpak-builtins-ps.c:57
msgid "R.-Branch"
msgstr ""

#: app/flatpak-builtins-ps.c:57
msgid "Show the runtime branch"
msgstr ""

#: app/flatpak-builtins-ps.c:58
msgid "R.-Commit"
msgstr ""

#: app/flatpak-builtins-ps.c:58
msgid "Show the runtime commit"
msgstr ""

#: app/flatpak-builtins-ps.c:59
msgid "Active"
msgstr ""

#: app/flatpak-builtins-ps.c:59
msgid "Show whether the app is active"
msgstr ""

#: app/flatpak-builtins-ps.c:60
msgid "Background"
msgstr ""

#: app/flatpak-builtins-ps.c:60
msgid "Show whether the app is background"
msgstr ""

#: app/flatpak-builtins-ps.c:246
msgid " - Enumerate running sandboxes"
msgstr ""

#: app/flatpak-builtins-remote-add.c:66
msgid "Do nothing if the provided remote exists"
msgstr ""

#: app/flatpak-builtins-remote-add.c:67
msgid "LOCATION specifies a configuration file, not the repo location"
msgstr ""

#: app/flatpak-builtins-remote-add.c:72 app/flatpak-builtins-remote-modify.c:78
msgid "Disable GPG verification"
msgstr ""

#: app/flatpak-builtins-remote-add.c:73 app/flatpak-builtins-remote-modify.c:79
msgid "Mark the remote as don't enumerate"
msgstr ""

#: app/flatpak-builtins-remote-add.c:74 app/flatpak-builtins-remote-modify.c:80
msgid "Mark the remote as don't use for deps"
msgstr ""

#: app/flatpak-builtins-remote-add.c:75 app/flatpak-builtins-remote-modify.c:81
msgid "Set priority (default 1, higher is more prioritized)"
msgstr ""

#: app/flatpak-builtins-remote-add.c:75 app/flatpak-builtins-remote-modify.c:81
msgid "PRIORITY"
msgstr ""

#: app/flatpak-builtins-remote-add.c:76
msgid "The named subset to use for this remote"
msgstr ""

#: app/flatpak-builtins-remote-add.c:76 app/flatpak-builtins-remote-modify.c:71
msgid "SUBSET"
msgstr ""

#: app/flatpak-builtins-remote-add.c:77 app/flatpak-builtins-remote-modify.c:82
msgid "A nice name to use for this remote"
msgstr ""

#: app/flatpak-builtins-remote-add.c:78 app/flatpak-builtins-remote-modify.c:83
msgid "A one-line comment for this remote"
msgstr ""

#: app/flatpak-builtins-remote-add.c:79 app/flatpak-builtins-remote-modify.c:84
msgid "A full-paragraph description for this remote"
msgstr ""

#: app/flatpak-builtins-remote-add.c:80 app/flatpak-builtins-remote-modify.c:85
msgid "URL for a website for this remote"
msgstr ""

#: app/flatpak-builtins-remote-add.c:81 app/flatpak-builtins-remote-modify.c:86
msgid "URL for an icon for this remote"
msgstr ""

#: app/flatpak-builtins-remote-add.c:82 app/flatpak-builtins-remote-modify.c:87
msgid "Default branch to use for this remote"
msgstr ""

#: app/flatpak-builtins-remote-add.c:84 app/flatpak-builtins-remote-modify.c:89
msgid "Import GPG key from FILE (- for stdin)"
msgstr ""

#: app/flatpak-builtins-remote-add.c:85 app/flatpak-builtins-remote-modify.c:90
msgid "Load signatures from URL"
msgstr ""

#: app/flatpak-builtins-remote-add.c:86 app/flatpak-builtins-remote-modify.c:92
msgid "Set path to local filter FILE"
msgstr ""

#: app/flatpak-builtins-remote-add.c:87 app/flatpak-builtins-remote-modify.c:93
msgid "Disable the remote"
msgstr ""

#: app/flatpak-builtins-remote-add.c:88 app/flatpak-builtins-remote-modify.c:94
msgid "Name of authenticator"
msgstr ""

#: app/flatpak-builtins-remote-add.c:90 app/flatpak-builtins-remote-modify.c:96
msgid "Autoinstall authenticator"
msgstr ""

#: app/flatpak-builtins-remote-add.c:91 app/flatpak-builtins-remote-modify.c:97
msgid "Don't autoinstall authenticator"
msgstr ""

#: app/flatpak-builtins-remote-add.c:92 app/flatpak-builtins-remote-modify.c:99
msgid "Don't follow the redirect set in the summary file"
msgstr ""

#: app/flatpak-builtins-remote-add.c:261 app/flatpak-builtins-remote-add.c:268
#, c-format
msgid "Can't load uri %s: %s\n"
msgstr ""

#: app/flatpak-builtins-remote-add.c:276 common/flatpak-dir.c:4643
#, c-format
msgid "Can't load file %s: %s\n"
msgstr ""

#: app/flatpak-builtins-remote-add.c:304
msgid "NAME LOCATION - Add a remote repository"
msgstr ""

#: app/flatpak-builtins-remote-add.c:331
msgid "GPG verification is required if collections are enabled"
msgstr ""

#: app/flatpak-builtins-remote-add.c:393
#, c-format
msgid "Remote %s already exists"
msgstr ""

#: app/flatpak-builtins-remote-add.c:405
#: app/flatpak-builtins-remote-modify.c:340
#, c-format
msgid "Invalid authenticator name %s"
msgstr ""

#: app/flatpak-builtins-remote-add.c:422
#, c-format
msgid "Warning: Could not update extra metadata for '%s': %s\n"
msgstr ""

#: app/flatpak-builtins-remote-delete.c:39
msgid "Remove remote even if in use"
msgstr ""

#: app/flatpak-builtins-remote-delete.c:53
msgid "NAME - Delete a remote repository"
msgstr ""

#: app/flatpak-builtins-remote-delete.c:100
#, c-format
msgid "The following refs are installed from remote '%s':"
msgstr ""

#: app/flatpak-builtins-remote-delete.c:101
msgid "Remove them?"
msgstr ""

#: app/flatpak-builtins-remote-delete.c:103
#, c-format
msgid "Can't remove remote '%s' with installed refs"
msgstr ""

#: app/flatpak-builtins-remote-info.c:55
msgid "Commit to show info for"
msgstr ""

#: app/flatpak-builtins-remote-info.c:58
msgid "Display log"
msgstr ""

#: app/flatpak-builtins-remote-info.c:61
msgid "Show parent"
msgstr ""

#: app/flatpak-builtins-remote-info.c:65 app/flatpak-builtins-remote-ls.c:60
msgid "Use local caches even if they are stale"
msgstr ""

#. Translators: A sideload is when you install from a local USB drive rather than the Internet.
#: app/flatpak-builtins-remote-info.c:67 app/flatpak-builtins-remote-ls.c:62
msgid "Only list refs available as sideloads"
msgstr ""

#: app/flatpak-builtins-remote-info.c:114
msgid ""
" REMOTE REF - Show information about an application or runtime in a remote"
msgstr ""

#: app/flatpak-builtins-remote-info.c:125
msgid "REMOTE and REF must be specified"
msgstr ""

#: app/flatpak-builtins-remote-info.c:247
#: app/flatpak-builtins-remote-info.c:282
msgid "Download Size:"
msgstr ""

#: app/flatpak-builtins-remote-info.c:267
#: app/flatpak-builtins-remote-info.c:325
msgid "History:"
msgstr ""

#: app/flatpak-builtins-remote-info.c:348
msgid " Commit:"
msgstr ""

#: app/flatpak-builtins-remote-info.c:349
msgid " Subject:"
msgstr ""

#: app/flatpak-builtins-remote-info.c:350
msgid " Date:"
msgstr ""

#: app/flatpak-builtins-remote-info.c:383
#, c-format
msgid "Warning: Commit %s has no flatpak metadata\n"
msgstr ""

#: app/flatpak-builtins-remote-list.c:43
msgid "Show remote details"
msgstr ""

#: app/flatpak-builtins-remote-list.c:44
msgid "Show disabled remotes"
msgstr ""

#: app/flatpak-builtins-remote-list.c:52
msgid "Title"
msgstr ""

#: app/flatpak-builtins-remote-list.c:52
msgid "Show the title"
msgstr ""

#: app/flatpak-builtins-remote-list.c:53
msgid "Show the URL"
msgstr ""

#: app/flatpak-builtins-remote-list.c:54
msgid "Show the collection ID"
msgstr ""

#: app/flatpak-builtins-remote-list.c:55 app/flatpak-builtins-repo.c:392
msgid "Subset"
msgstr ""

#: app/flatpak-builtins-remote-list.c:55
msgid "Show the subset"
msgstr ""

#: app/flatpak-builtins-remote-list.c:56
msgid "Filter"
msgstr ""

#: app/flatpak-builtins-remote-list.c:56
msgid "Show filter file"
msgstr ""

#: app/flatpak-builtins-remote-list.c:57
msgid "Priority"
msgstr ""

#: app/flatpak-builtins-remote-list.c:57
msgid "Show the priority"
msgstr ""

#: app/flatpak-builtins-remote-list.c:59
msgid "Comment"
msgstr ""

#: app/flatpak-builtins-remote-list.c:59
msgid "Show comment"
msgstr ""

#: app/flatpak-builtins-remote-list.c:60
msgid "Show description"
msgstr ""

#: app/flatpak-builtins-remote-list.c:61
msgid "Homepage"
msgstr ""

#: app/flatpak-builtins-remote-list.c:61
msgid "Show homepage"
msgstr ""

#: app/flatpak-builtins-remote-list.c:62
msgid "Icon"
msgstr ""

#: app/flatpak-builtins-remote-list.c:62
msgid "Show icon"
msgstr ""

#: app/flatpak-builtins-remote-list.c:231
msgid " - List remote repositories"
msgstr ""

#: app/flatpak-builtins-remote-ls.c:52
msgid "Show arches and branches"
msgstr ""

#: app/flatpak-builtins-remote-ls.c:53
msgid "Show only runtimes"
msgstr ""

#: app/flatpak-builtins-remote-ls.c:54
msgid "Show only apps"
msgstr ""

#: app/flatpak-builtins-remote-ls.c:55
msgid "Show only those where updates are available"
msgstr ""

#: app/flatpak-builtins-remote-ls.c:56
msgid "Limit to this arch (* for all)"
msgstr ""

#: app/flatpak-builtins-remote-ls.c:77
msgid "Show the runtime"
msgstr ""

#: app/flatpak-builtins-remote-ls.c:79
msgid "Download size"
msgstr ""

#: app/flatpak-builtins-remote-ls.c:79
msgid "Show the download size"
msgstr ""

#: app/flatpak-builtins-remote-ls.c:391
msgid " [REMOTE or URI] - Show available runtimes and applications"
msgstr ""

#: app/flatpak-builtins-remote-modify.c:67
msgid "Enable GPG verification"
msgstr ""

#: app/flatpak-builtins-remote-modify.c:68
msgid "Mark the remote as enumerate"
msgstr ""

#: app/flatpak-builtins-remote-modify.c:69
msgid "Mark the remote as used for dependencies"
msgstr ""

#: app/flatpak-builtins-remote-modify.c:70
msgid "Set a new URL"
msgstr ""

#: app/flatpak-builtins-remote-modify.c:71
msgid "Set a new subset to use"
msgstr ""

#: app/flatpak-builtins-remote-modify.c:72
msgid "Enable the remote"
msgstr ""

#: app/flatpak-builtins-remote-modify.c:73
msgid "Update extra metadata from the summary file"
msgstr ""

#: app/flatpak-builtins-remote-modify.c:91
msgid "Disable local filter"
msgstr ""

#: app/flatpak-builtins-remote-modify.c:95
msgid "Authenticator options"
msgstr ""

#: app/flatpak-builtins-remote-modify.c:98
msgid "Follow the redirect set in the summary file"
msgstr ""

#: app/flatpak-builtins-remote-modify.c:306
msgid "NAME - Modify a remote repository"
msgstr ""

#: app/flatpak-builtins-remote-modify.c:316
msgid "Remote NAME must be specified"
msgstr ""

#: app/flatpak-builtins-remote-modify.c:327
#, c-format
msgid "Updating extra metadata from remote summary for %s\n"
msgstr ""

#: app/flatpak-builtins-remote-modify.c:330
#, c-format
msgid "Error updating extra metadata for '%s': %s\n"
msgstr ""

#: app/flatpak-builtins-remote-modify.c:331
#, c-format
msgid "Could not update extra metadata for %s"
msgstr ""

#: app/flatpak-builtins-repair.c:43
msgid "Don't make any changes"
msgstr ""

#: app/flatpak-builtins-repair.c:44
msgid "Reinstall all refs"
msgstr ""

#: app/flatpak-builtins-repair.c:68
#, c-format
msgid "Object missing: %s.%s\n"
msgstr ""

#: app/flatpak-builtins-repair.c:76
#, c-format
msgid "Object invalid: %s.%s\n"
msgstr ""

#: app/flatpak-builtins-repair.c:81
#, c-format
msgid "%s, deleting object\n"
msgstr ""

#: app/flatpak-builtins-repair.c:146
#, c-format
msgid "Can't load object %s: %s\n"
msgstr ""

#: app/flatpak-builtins-repair.c:228
#, c-format
msgid "Commit invalid %s: %s\n"
msgstr ""

#: app/flatpak-builtins-repair.c:231
#, c-format
msgid "Deleting invalid commit %s: %s\n"
msgstr ""

#: app/flatpak-builtins-repair.c:261
#, c-format
msgid "Commit should be marked partial: %s\n"
msgstr ""

#: app/flatpak-builtins-repair.c:264
#, c-format
msgid "Marking commit as partial: %s\n"
msgstr ""

#: app/flatpak-builtins-repair.c:293
#, c-format
msgid "Problems loading data for %s: %s\n"
msgstr ""

#: app/flatpak-builtins-repair.c:306
#, c-format
msgid "Error reinstalling %s: %s\n"
msgstr ""

#: app/flatpak-builtins-repair.c:327
msgid "- Repair a flatpak installation"
msgstr ""

#: app/flatpak-builtins-repair.c:406
#, c-format
msgid "Removing non-deployed ref %s…\n"
msgstr ""

#: app/flatpak-builtins-repair.c:411
#, c-format
msgid "Skipping non-deployed ref %s…\n"
msgstr ""

#: app/flatpak-builtins-repair.c:429
#, c-format
msgid "[%d/%d] Verifying %s…\n"
msgstr ""

#: app/flatpak-builtins-repair.c:435
#, c-format
msgid "Dry run: "
msgstr ""

#: app/flatpak-builtins-repair.c:440
#, c-format
msgid "Deleting ref %s due to missing objects\n"
msgstr ""

#: app/flatpak-builtins-repair.c:444
#, c-format
msgid "Deleting ref %s due to invalid objects\n"
msgstr ""

#: app/flatpak-builtins-repair.c:448
#, c-format
msgid "Deleting ref %s due to %d\n"
msgstr ""

#: app/flatpak-builtins-repair.c:464
#, c-format
msgid "Checking remotes...\n"
msgstr ""

#: app/flatpak-builtins-repair.c:482
#, c-format
msgid "Remote %s for ref %s is missing\n"
msgstr ""

#: app/flatpak-builtins-repair.c:484
#, c-format
msgid "Remote %s for ref %s is disabled\n"
msgstr ""

#: app/flatpak-builtins-repair.c:490
#, c-format
msgid "Pruning objects\n"
msgstr ""

#: app/flatpak-builtins-repair.c:498
#, c-format
msgid "Erasing .removed\n"
msgstr ""

#: app/flatpak-builtins-repair.c:524
#, c-format
msgid "Reinstalling refs\n"
msgstr ""

#: app/flatpak-builtins-repair.c:526
#, c-format
msgid "Reinstalling removed refs\n"
msgstr ""

#: app/flatpak-builtins-repair.c:551
#, c-format
msgid "While removing appstream for %s: "
msgstr ""

#: app/flatpak-builtins-repair.c:558
#, c-format
msgid "While deploying appstream for %s: "
msgstr ""

#: app/flatpak-builtins-repo.c:106
#, c-format
msgid "Repo mode: %s\n"
msgstr ""

#: app/flatpak-builtins-repo.c:113
#, c-format
msgid "Indexed summaries: %s\n"
msgstr ""

#: app/flatpak-builtins-repo.c:113 app/flatpak-builtins-repo.c:139
#: app/flatpak-builtins-repo.c:172
msgid "true"
msgstr ""

#: app/flatpak-builtins-repo.c:113 app/flatpak-builtins-repo.c:139
#: app/flatpak-builtins-repo.c:172
msgid "false"
msgstr ""

#: app/flatpak-builtins-repo.c:121
#, c-format
msgid "Subsummaries: "
msgstr ""

#: app/flatpak-builtins-repo.c:136
#, c-format
msgid "Cache version: %d\n"
msgstr ""

#: app/flatpak-builtins-repo.c:139
#, c-format
msgid "Indexed deltas: %s\n"
msgstr ""

#: app/flatpak-builtins-repo.c:142
#, c-format
msgid "Title: %s\n"
msgstr ""

#: app/flatpak-builtins-repo.c:145
#, c-format
msgid "Comment: %s\n"
msgstr ""

#: app/flatpak-builtins-repo.c:148
#, c-format
msgid "Description: %s\n"
msgstr ""

#: app/flatpak-builtins-repo.c:151
#, c-format
msgid "Homepage: %s\n"
msgstr ""

#: app/flatpak-builtins-repo.c:154
#, c-format
msgid "Icon: %s\n"
msgstr ""

#: app/flatpak-builtins-repo.c:157
#, c-format
msgid "Collection ID: %s\n"
msgstr ""

#: app/flatpak-builtins-repo.c:160
#, c-format
msgid "Default branch: %s\n"
msgstr ""

#: app/flatpak-builtins-repo.c:163
#, c-format
msgid "Redirect URL: %s\n"
msgstr ""

#: app/flatpak-builtins-repo.c:166
#, c-format
msgid "Deploy collection ID: %s\n"
msgstr ""

#: app/flatpak-builtins-repo.c:169
#, c-format
msgid "Authenticator name: %s\n"
msgstr ""

#: app/flatpak-builtins-repo.c:172
#, c-format
msgid "Authenticator install: %s\n"
msgstr ""

#: app/flatpak-builtins-repo.c:180
#, c-format
msgid "GPG key hash: %s\n"
msgstr ""

#: app/flatpak-builtins-repo.c:184
#, c-format
msgid "%zd summary branches\n"
msgstr ""

#: app/flatpak-builtins-repo.c:336
msgid "Installed"
msgstr ""

#. Translators: Download is used here as a noun
#: app/flatpak-builtins-repo.c:338 app/flatpak-cli-transaction.c:1462
msgid "Download"
msgstr ""

#: app/flatpak-builtins-repo.c:339
msgid "Subsets"
msgstr ""

#: app/flatpak-builtins-repo.c:393
msgid "Digest"
msgstr ""

#: app/flatpak-builtins-repo.c:394
msgid "History length"
msgstr ""

#: app/flatpak-builtins-repo.c:711
msgid "Print general information about the repository"
msgstr ""

#: app/flatpak-builtins-repo.c:712
msgid "List the branches in the repository"
msgstr ""

#: app/flatpak-builtins-repo.c:713
msgid "Print metadata for a branch"
msgstr ""

#: app/flatpak-builtins-repo.c:714
msgid "Show commits for a branch"
msgstr ""

#: app/flatpak-builtins-repo.c:715
msgid "Print information about the repo subsets"
msgstr ""

#: app/flatpak-builtins-repo.c:716
msgid "Limit information to subsets with this prefix"
msgstr ""

#: app/flatpak-builtins-repo.c:732
msgid "LOCATION - Repository maintenance"
msgstr ""

#: app/flatpak-builtins-run.c:159
msgid "Command to run"
msgstr ""

#: app/flatpak-builtins-run.c:160
msgid "Directory to run the command in"
msgstr ""

#: app/flatpak-builtins-run.c:161
msgid "Branch to use"
msgstr ""

#: app/flatpak-builtins-run.c:162
msgid "Use development runtime"
msgstr ""

#: app/flatpak-builtins-run.c:163
msgid "Runtime to use"
msgstr ""

#: app/flatpak-builtins-run.c:164
msgid "Runtime version to use"
msgstr ""

#: app/flatpak-builtins-run.c:167
msgid "Log accessibility bus calls"
msgstr ""

#: app/flatpak-builtins-run.c:168
msgid "Don't proxy accessibility bus calls"
msgstr ""

#: app/flatpak-builtins-run.c:169
msgid "Proxy accessibility bus calls (default except when sandboxed)"
msgstr ""

#: app/flatpak-builtins-run.c:170
msgid "Don't proxy session bus calls"
msgstr ""

#: app/flatpak-builtins-run.c:171
msgid "Proxy session bus calls (default except when sandboxed)"
msgstr ""

#: app/flatpak-builtins-run.c:172
msgid "Don't start portals"
msgstr ""

#: app/flatpak-builtins-run.c:173
msgid "Enable file forwarding"
msgstr ""

#: app/flatpak-builtins-run.c:174
msgid "Run specified commit"
msgstr ""

#: app/flatpak-builtins-run.c:175
msgid "Use specified runtime commit"
msgstr ""

#: app/flatpak-builtins-run.c:176
msgid "Run completely sandboxed"
msgstr ""

#: app/flatpak-builtins-run.c:178
msgid "Use PID as parent pid for sharing namespaces"
msgstr ""

#: app/flatpak-builtins-run.c:179
msgid "Make processes visible in parent namespace"
msgstr ""

#: app/flatpak-builtins-run.c:180
msgid "Share process ID namespace with parent"
msgstr ""

#: app/flatpak-builtins-run.c:181
msgid "Write the instance ID to the given file descriptor"
msgstr ""

#: app/flatpak-builtins-run.c:182
msgid "Use PATH instead of the app's /app"
msgstr ""

#: app/flatpak-builtins-run.c:183
msgid "Use FD instead of the app's /app"
msgstr ""

#: app/flatpak-builtins-run.c:183 app/flatpak-builtins-run.c:185
#: app/flatpak-builtins-run.c:187 app/flatpak-builtins-run.c:188
#: common/flatpak-context.c:2672
msgid "FD"
msgstr ""

#: app/flatpak-builtins-run.c:184
msgid "Use PATH instead of the runtime's /usr"
msgstr ""

#: app/flatpak-builtins-run.c:185
msgid "Use FD instead of the runtime's /usr"
msgstr ""

#: app/flatpak-builtins-run.c:186
msgid "Clear all outside environment variables"
msgstr ""

#: app/flatpak-builtins-run.c:187
msgid ""
"Bind mount the file or directory referred to by FD to its canonicalized path"
msgstr ""

#: app/flatpak-builtins-run.c:188
msgid ""
"Bind mount the file or directory referred to by FD read-only to its "
"canonicalized path"
msgstr ""

#: app/flatpak-builtins-run.c:219
msgid "APP [ARGUMENT…] - Run an app"
msgstr ""

#: app/flatpak-builtins-run.c:370
#, c-format
msgid "runtime/%s/%s/%s not installed"
msgstr ""

#: app/flatpak-builtins-run.c:419
msgid "app-fd and app-path cannot both be used"
msgstr ""

#: app/flatpak-builtins-run.c:449
msgid "usr-fd and usr-path cannot both be used"
msgstr ""

#: app/flatpak-builtins-search.c:37
msgid "Arch to search for"
msgstr ""

#: app/flatpak-builtins-search.c:49
msgid "Remotes"
msgstr ""

#: app/flatpak-builtins-search.c:49
msgid "Show the remotes"
msgstr ""

#: app/flatpak-builtins-search.c:244
msgid "TEXT - Search remote apps/runtimes for text"
msgstr ""

#: app/flatpak-builtins-search.c:255
msgid "TEXT must be specified"
msgstr ""

#: app/flatpak-builtins-search.c:338
msgid "No matches found"
msgstr ""

#: app/flatpak-builtins-uninstall.c:54
msgid "Arch to uninstall"
msgstr ""

#: app/flatpak-builtins-uninstall.c:55
msgid "Keep ref in local repository"
msgstr ""

#: app/flatpak-builtins-uninstall.c:56
msgid "Don't uninstall related refs"
msgstr ""

#: app/flatpak-builtins-uninstall.c:57
msgid "Remove files even if running"
msgstr ""

#: app/flatpak-builtins-uninstall.c:60
msgid "Uninstall all"
msgstr ""

#: app/flatpak-builtins-uninstall.c:61
msgid "Uninstall unused"
msgstr ""

#: app/flatpak-builtins-uninstall.c:62
msgid "Delete app data"
msgstr ""

#: app/flatpak-builtins-uninstall.c:141
#, c-format
msgid "Delete data for %s?"
msgstr ""

#: app/flatpak-builtins-uninstall.c:220
#, c-format
msgid "Info: applications using the extension %s%s%s branch %s%s%s:\n"
msgstr ""

#: app/flatpak-builtins-uninstall.c:223
#, c-format
msgid "Info: applications using the runtime %s%s%s branch %s%s%s:\n"
msgstr ""

#: app/flatpak-builtins-uninstall.c:238
msgid "Really remove?"
msgstr ""

#: app/flatpak-builtins-uninstall.c:255
msgid "[REF…] - Uninstall applications or runtimes"
msgstr ""

#: app/flatpak-builtins-uninstall.c:264
msgid "Must specify at least one REF, --unused, --all or --delete-data"
msgstr ""

#: app/flatpak-builtins-uninstall.c:267
msgid "Must not specify REFs when using --all"
msgstr ""

#: app/flatpak-builtins-uninstall.c:270
msgid "Must not specify REFs when using --unused"
msgstr ""

#: app/flatpak-builtins-uninstall.c:336
#, c-format
msgid ""
"\n"
"These runtimes in installation '%s' are pinned and won't be removed; see "
"flatpak-pin(1):\n"
msgstr ""

#: app/flatpak-builtins-uninstall.c:370
#, c-format
msgid "Nothing unused to uninstall\n"
msgstr ""

#: app/flatpak-builtins-uninstall.c:444
#, c-format
msgid "No installed refs found for ‘%s’"
msgstr ""

#: app/flatpak-builtins-uninstall.c:447
#, c-format
msgid " with arch ‘%s’"
msgstr ""

#: app/flatpak-builtins-uninstall.c:449
#, c-format
msgid " with branch ‘%s’"
msgstr ""

#: app/flatpak-builtins-uninstall.c:456
#, c-format
msgid "Warning: %s is not installed\n"
msgstr ""

#: app/flatpak-builtins-uninstall.c:490
#, c-format
msgid "None of the specified refs are installed"
msgstr ""

#: app/flatpak-builtins-uninstall.c:599
#, c-format
msgid "No app data to delete\n"
msgstr ""

#: app/flatpak-builtins-update.c:56
msgid "Arch to update for"
msgstr ""

#: app/flatpak-builtins-update.c:57
msgid "Commit to deploy"
msgstr ""

#: app/flatpak-builtins-update.c:58
msgid "Remove old files even if running"
msgstr ""

#: app/flatpak-builtins-update.c:59
msgid "Don't pull, only update from local cache"
msgstr ""

#: app/flatpak-builtins-update.c:61
msgid "Don't update related refs"
msgstr ""

#: app/flatpak-builtins-update.c:66
msgid "Update appstream for remote"
msgstr ""

#: app/flatpak-builtins-update.c:67
msgid "Only update this subpath"
msgstr ""

#: app/flatpak-builtins-update.c:90
msgid "[REF…] - Update applications or runtimes"
msgstr ""

#: app/flatpak-builtins-update.c:121
msgid "With --commit, only one REF may be specified"
msgstr ""

#: app/flatpak-builtins-update.c:162
#, c-format
msgid "Looking for updates…\n"
msgstr ""

#: app/flatpak-builtins-update.c:215
#, c-format
msgid "Unable to update %s: %s\n"
msgstr ""

#: app/flatpak-builtins-update.c:274
#, c-format
msgid "Nothing to update.\n"
msgstr ""

#: app/flatpak-builtins-utils.c:337
#, c-format
msgid ""
"Remote ‘%s’ found in multiple installations, unable to proceed in non-"
"interactive mode"
msgstr ""

#: app/flatpak-builtins-utils.c:346
#, c-format
msgid "Remote ‘%s’ found in multiple installations:"
msgstr ""

#: app/flatpak-builtins-utils.c:347 app/flatpak-builtins-utils.c:442
#: app/flatpak-builtins-utils.c:538 app/flatpak-builtins-utils.c:540
#: app/flatpak-builtins-utils.c:598
msgid "Which do you want to use (0 to abort)?"
msgstr ""

#: app/flatpak-builtins-utils.c:349
#, c-format
msgid "No remote chosen to resolve ‘%s’ which exists in multiple installations"
msgstr ""

#: app/flatpak-builtins-utils.c:358
#, c-format
msgid ""
"Remote \"%s\" not found\n"
"Hint: Use flatpak remote-add to add a remote"
msgstr ""

#: app/flatpak-builtins-utils.c:364
#, c-format
msgid "Remote \"%s\" not found in the %s installation"
msgstr ""

#: app/flatpak-builtins-utils.c:404
#, c-format
msgid "Multiple refs match ‘%s’, unable to proceed in non-interactive mode"
msgstr ""

#. default to yes on Enter
#: app/flatpak-builtins-utils.c:430
#, c-format
msgid ""
"Found ref ‘%s’ in remote ‘%s’ (%s).\n"
"Use this ref?"
msgstr ""

#: app/flatpak-builtins-utils.c:434 app/flatpak-builtins-utils.c:444
#: app/flatpak-builtins-utils.c:522 app/flatpak-builtins-utils.c:543
#, c-format
msgid "No ref chosen to resolve matches for ‘%s’"
msgstr ""

#: app/flatpak-builtins-utils.c:440
#, c-format
msgid "Similar refs found for ‘%s’ in remote ‘%s’ (%s):"
msgstr ""

#: app/flatpak-builtins-utils.c:488
#, c-format
msgid ""
"Multiple installed refs match ‘%s’, unable to proceed in non-interactive mode"
msgstr ""

#. default to yes on Enter
#: app/flatpak-builtins-utils.c:518
#, c-format
msgid "Found installed ref ‘%s’ (%s). Is this correct?"
msgstr ""

#: app/flatpak-builtins-utils.c:534
#, c-format
msgid "All of the above"
msgstr ""

#: app/flatpak-builtins-utils.c:535
#, c-format
msgid "Similar installed refs found for ‘%s’:"
msgstr ""

#: app/flatpak-builtins-utils.c:579
#, c-format
msgid ""
"Multiple remotes have refs matching ‘%s’, unable to proceed in non-"
"interactive mode"
msgstr ""

#: app/flatpak-builtins-utils.c:597
#, c-format
msgid "Remotes found with refs similar to ‘%s’:"
msgstr ""

#: app/flatpak-builtins-utils.c:600
#, c-format
msgid "No remote chosen to resolve matches for ‘%s’"
msgstr ""

#: app/flatpak-builtins-utils.c:696 app/flatpak-builtins-utils.c:699
#, c-format
msgid "Updating appstream data for user remote %s"
msgstr ""

#: app/flatpak-builtins-utils.c:706 app/flatpak-builtins-utils.c:709
#, c-format
msgid "Updating appstream data for remote %s"
msgstr ""

#: app/flatpak-builtins-utils.c:717 app/flatpak-builtins-utils.c:719
msgid "Error updating"
msgstr ""

#: app/flatpak-builtins-utils.c:755
#, c-format
msgid "Remote \"%s\" not found"
msgstr ""

#: app/flatpak-builtins-utils.c:796
#, c-format
msgid "Ambiguous suffix: '%s'."
msgstr ""

#. Translators: don't translate the values
#: app/flatpak-builtins-utils.c:798 app/flatpak-builtins-utils.c:813
msgid "Possible values are :s[tart], :m[iddle], :e[nd] or :f[ull]"
msgstr ""

#: app/flatpak-builtins-utils.c:811
#, c-format
msgid "Invalid suffix: '%s'."
msgstr ""

#: app/flatpak-builtins-utils.c:846
#, c-format
msgid "Ambiguous column: %s"
msgstr ""

#: app/flatpak-builtins-utils.c:859
#, c-format
msgid "Unknown column: %s"
msgstr ""

#: app/flatpak-builtins-utils.c:917
msgid "Available columns:\n"
msgstr ""

#: app/flatpak-builtins-utils.c:927
msgid "Show all columns"
msgstr ""

#: app/flatpak-builtins-utils.c:928
msgid "Show available columns"
msgstr ""

#: app/flatpak-builtins-utils.c:931
msgid "Append :s[tart], :m[iddle], :e[nd] or :f[ull] to change ellipsization"
msgstr ""

#: app/flatpak-builtins-utils.c:1483
#, c-format
msgid "Unknown scheme in sideload location %s"
msgstr ""

#: app/flatpak-cli-transaction.c:96 app/flatpak-cli-transaction.c:102
#, c-format
msgid "Required runtime for %s (%s) found in remote %s\n"
msgstr ""

#: app/flatpak-cli-transaction.c:104
msgid "Do you want to install it?"
msgstr ""

#: app/flatpak-cli-transaction.c:110
#, c-format
msgid "Required runtime for %s (%s) found in remotes:"
msgstr ""

#: app/flatpak-cli-transaction.c:112
msgid "Which do you want to install (0 to abort)?"
msgstr ""

#: app/flatpak-cli-transaction.c:132
#, c-format
msgid "Configuring %s as new remote '%s'\n"
msgstr ""

#. default to yes on Enter
#: app/flatpak-cli-transaction.c:139
#, c-format
msgid ""
"The remote '%s', referred to by '%s' at location %s contains additional "
"applications.\n"
"Should the remote be kept for future installations?"
msgstr ""

#. default to yes on Enter
#: app/flatpak-cli-transaction.c:147
#, c-format
msgid ""
"The application %s depends on runtimes from:\n"
"  %s\n"
"Configure this as new remote '%s'"
msgstr ""

#. Formatted size/remaining time in seconds
#: app/flatpak-cli-transaction.c:321
#, c-format
msgid "%s/s%s%s"
msgstr ""

#. Download progress percentage, use the appropriate
#. percent format for your language
#: app/flatpak-cli-transaction.c:359
#, c-format
msgid "%3d%%"
msgstr ""

#: app/flatpak-cli-transaction.c:414
msgid "Installing…"
msgstr ""

#: app/flatpak-cli-transaction.c:416
#, c-format
msgid "Installing %d/%d…"
msgstr ""

#: app/flatpak-cli-transaction.c:421
msgid "Updating…"
msgstr ""

#: app/flatpak-cli-transaction.c:423
#, c-format
msgid "Updating %d/%d…"
msgstr ""

#: app/flatpak-cli-transaction.c:428
msgid "Uninstalling…"
msgstr ""

#: app/flatpak-cli-transaction.c:430
#, c-format
msgid "Uninstalling %d/%d…"
msgstr ""

#: app/flatpak-cli-transaction.c:496 app/flatpak-quiet-transaction.c:161
#, c-format
msgid "Info: %s was skipped"
msgstr ""

#: app/flatpak-cli-transaction.c:519
#, c-format
msgid "Warning: %s%s%s already installed"
msgstr ""

#: app/flatpak-cli-transaction.c:522
#, c-format
msgid "Error: %s%s%s already installed"
msgstr ""

#: app/flatpak-cli-transaction.c:528
#, c-format
msgid "Warning: %s%s%s not installed"
msgstr ""

#: app/flatpak-cli-transaction.c:531
#, c-format
msgid "Error: %s%s%s not installed"
msgstr ""

#: app/flatpak-cli-transaction.c:537
#, c-format
msgid "Warning: %s%s%s needs a later flatpak version"
msgstr ""

#: app/flatpak-cli-transaction.c:540
#, c-format
msgid "Error: %s%s%s needs a later flatpak version"
msgstr ""

#: app/flatpak-cli-transaction.c:546
msgid "Warning: Not enough disk space to complete this operation"
msgstr ""

#: app/flatpak-cli-transaction.c:548
msgid "Error: Not enough disk space to complete this operation"
msgstr ""

#: app/flatpak-cli-transaction.c:553
#, c-format
msgid "Warning: %s"
msgstr ""

#: app/flatpak-cli-transaction.c:555
#, c-format
msgid "Error: %s"
msgstr ""

#: app/flatpak-cli-transaction.c:570
#, c-format
msgid "Failed to install %s%s%s: "
msgstr ""

#: app/flatpak-cli-transaction.c:577
#, c-format
msgid "Failed to update %s%s%s: "
msgstr ""

#: app/flatpak-cli-transaction.c:584
#, c-format
msgid "Failed to install bundle %s%s%s: "
msgstr ""

#: app/flatpak-cli-transaction.c:591
#, c-format
msgid "Failed to uninstall %s%s%s: "
msgstr ""

#: app/flatpak-cli-transaction.c:642
#, c-format
msgid "Authentication required for remote '%s'\n"
msgstr ""

#: app/flatpak-cli-transaction.c:643
msgid "Open browser?"
msgstr ""

#: app/flatpak-cli-transaction.c:699
#, c-format
msgid "Login required remote %s (realm %s)\n"
msgstr ""

#: app/flatpak-cli-transaction.c:704
msgid "Password"
msgstr ""

#. Only runtimes can be pinned
#: app/flatpak-cli-transaction.c:759
#, c-format
msgid ""
"\n"
"Info: (pinned) runtime %s%s%s branch %s%s%s is end-of-life, in favor of "
"%s%s%s branch %s%s%s\n"
msgstr ""

#: app/flatpak-cli-transaction.c:765
#, c-format
msgid ""
"\n"
"Info: runtime %s%s%s branch %s%s%s is end-of-life, in favor of %s%s%s branch "
"%s%s%s\n"
msgstr ""

#: app/flatpak-cli-transaction.c:768
#, c-format
msgid ""
"\n"
"Info: app %s%s%s branch %s%s%s is end-of-life, in favor of %s%s%s branch "
"%s%s%s\n"
msgstr ""

#. Only runtimes can be pinned
#: app/flatpak-cli-transaction.c:780
#, c-format
msgid ""
"\n"
"Info: (pinned) runtime %s%s%s branch %s%s%s is end-of-life, with reason:\n"
msgstr ""

#: app/flatpak-cli-transaction.c:786
#, c-format
msgid ""
"\n"
"Info: runtime %s%s%s branch %s%s%s is end-of-life, with reason:\n"
msgstr ""

#: app/flatpak-cli-transaction.c:789
#, c-format
msgid ""
"\n"
"Info: app %s%s%s branch %s%s%s is end-of-life, with reason:\n"
msgstr ""

#: app/flatpak-cli-transaction.c:963
#, c-format
msgid "Info: applications using this extension:\n"
msgstr ""

#: app/flatpak-cli-transaction.c:965
#, c-format
msgid "Info: applications using this runtime:\n"
msgstr ""

#: app/flatpak-cli-transaction.c:984
msgid "Replace?"
msgstr ""

#: app/flatpak-cli-transaction.c:987 app/flatpak-quiet-transaction.c:247
#, c-format
msgid "Updating to rebased version\n"
msgstr ""

#: app/flatpak-cli-transaction.c:1011
#, c-format
msgid "Failed to rebase %s to %s: "
msgstr ""

#: app/flatpak-cli-transaction.c:1277
#, c-format
msgid "New %s%s%s permissions:"
msgstr ""

#: app/flatpak-cli-transaction.c:1279
#, c-format
msgid "%s%s%s permissions:"
msgstr ""

#: app/flatpak-cli-transaction.c:1343
msgid "Warning: "
msgstr ""

#. translators: This is short for operation, the title of a one-char column
#: app/flatpak-cli-transaction.c:1442
msgid "Op"
msgstr ""

#. Avoid resizing the download column too much,
#. * by making the title as long as typical content
#.
#: app/flatpak-cli-transaction.c:1458 app/flatpak-cli-transaction.c:1503
msgid "partial"
msgstr ""

#: app/flatpak-cli-transaction.c:1535
msgid "Proceed with these changes to the user installation?"
msgstr ""

#: app/flatpak-cli-transaction.c:1537
msgid "Proceed with these changes to the system installation?"
msgstr ""

#: app/flatpak-cli-transaction.c:1539
#, c-format
msgid "Proceed with these changes to the %s?"
msgstr ""

#: app/flatpak-cli-transaction.c:1711
msgid "Changes complete."
msgstr ""

#: app/flatpak-cli-transaction.c:1713
msgid "Uninstall complete."
msgstr ""

#: app/flatpak-cli-transaction.c:1715
msgid "Installation complete."
msgstr ""

#: app/flatpak-cli-transaction.c:1717
msgid "Updates complete."
msgstr ""

#. For updates/!stop_on_first_error we already printed all errors so we make up
#. a different one.
#: app/flatpak-cli-transaction.c:1750
msgid "There were one or more errors"
msgstr ""

#. translators: please keep the leading space
#: app/flatpak-main.c:76
msgid " Manage installed applications and runtimes"
msgstr ""

#: app/flatpak-main.c:77
msgid "Install an application or runtime"
msgstr ""

#: app/flatpak-main.c:78
msgid "Update an installed application or runtime"
msgstr ""

#: app/flatpak-main.c:81
msgid "Uninstall an installed application or runtime"
msgstr ""

#: app/flatpak-main.c:84
msgid "Mask out updates and automatic installation"
msgstr ""

#: app/flatpak-main.c:85
msgid "Pin a runtime to prevent automatic removal"
msgstr ""

#: app/flatpak-main.c:86
msgid "List installed apps and/or runtimes"
msgstr ""

#: app/flatpak-main.c:87
msgid "Show info for installed app or runtime"
msgstr ""

#: app/flatpak-main.c:88
msgid "Show history"
msgstr ""

#: app/flatpak-main.c:89
msgid "Configure flatpak"
msgstr ""

#: app/flatpak-main.c:90
msgid "Repair flatpak installation"
msgstr ""

#: app/flatpak-main.c:91
msgid "Put applications or runtimes onto removable media"
msgstr ""

#: app/flatpak-main.c:92
msgid "Install flatpaks that are part of the operating system"
msgstr ""

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:95
msgid ""
"\n"
" Find applications and runtimes"
msgstr ""

#: app/flatpak-main.c:96
msgid "Search for remote apps/runtimes"
msgstr ""

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:99
msgid ""
"\n"
" Manage running applications"
msgstr ""

#: app/flatpak-main.c:100
msgid "Run an application"
msgstr ""

#: app/flatpak-main.c:101
msgid "Override permissions for an application"
msgstr ""

#: app/flatpak-main.c:102
msgid "Specify default version to run"
msgstr ""

#: app/flatpak-main.c:103
msgid "Enter the namespace of a running application"
msgstr ""

#: app/flatpak-main.c:104
msgid "Enumerate running applications"
msgstr ""

#: app/flatpak-main.c:105
msgid "Stop a running application"
msgstr ""

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:108
msgid ""
"\n"
" Manage file access"
msgstr ""

#: app/flatpak-main.c:109
msgid "List exported files"
msgstr ""

#: app/flatpak-main.c:110
msgid "Grant an application access to a specific file"
msgstr ""

#: app/flatpak-main.c:111
msgid "Revoke access to a specific file"
msgstr ""

#: app/flatpak-main.c:112
msgid "Show information about a specific file"
msgstr ""

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:116
msgid ""
"\n"
" Manage dynamic permissions"
msgstr ""

#: app/flatpak-main.c:117
msgid "List permissions"
msgstr ""

#: app/flatpak-main.c:118
msgid "Remove item from permission store"
msgstr ""

#: app/flatpak-main.c:120
msgid "Set permissions"
msgstr ""

#: app/flatpak-main.c:121
msgid "Show app permissions"
msgstr ""

#: app/flatpak-main.c:122
msgid "Reset app permissions"
msgstr ""

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:125
msgid ""
"\n"
" Manage remote repositories"
msgstr ""

#: app/flatpak-main.c:126
msgid "List all configured remotes"
msgstr ""

#: app/flatpak-main.c:127
msgid "Add a new remote repository (by URL)"
msgstr ""

#: app/flatpak-main.c:128
msgid "Modify properties of a configured remote"
msgstr ""

#: app/flatpak-main.c:129
msgid "Delete a configured remote"
msgstr ""

#: app/flatpak-main.c:131
msgid "List contents of a configured remote"
msgstr ""

#: app/flatpak-main.c:132
msgid "Show information about a remote app or runtime"
msgstr ""

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:135
msgid ""
"\n"
" Build applications"
msgstr ""

#: app/flatpak-main.c:136
msgid "Initialize a directory for building"
msgstr ""

#: app/flatpak-main.c:137
msgid "Run a build command inside the build dir"
msgstr ""

#: app/flatpak-main.c:138
msgid "Finish a build dir for export"
msgstr ""

#: app/flatpak-main.c:139
msgid "Export a build dir to a repository"
msgstr ""

#: app/flatpak-main.c:140
msgid "Create a bundle file from a ref in a local repository"
msgstr ""

#: app/flatpak-main.c:141
msgid "Import a bundle file"
msgstr ""

#: app/flatpak-main.c:142
msgid "Sign an application or runtime"
msgstr ""

#: app/flatpak-main.c:143
msgid "Update the summary file in a repository"
msgstr ""

#: app/flatpak-main.c:144
msgid "Create new commit based on existing ref"
msgstr ""

#: app/flatpak-main.c:145
msgid "Show information about a repo"
msgstr ""

#: app/flatpak-main.c:162
msgid "Show debug information, -vv for more detail"
msgstr ""

#: app/flatpak-main.c:163
msgid "Show OSTree debug information"
msgstr ""

#: app/flatpak-main.c:169
msgid "Print version information and exit"
msgstr ""

#: app/flatpak-main.c:170
msgid "Print default arch and exit"
msgstr ""

#: app/flatpak-main.c:171
msgid "Print supported arches and exit"
msgstr ""

#: app/flatpak-main.c:172
msgid "Print active gl drivers and exit"
msgstr ""

#: app/flatpak-main.c:173
msgid "Print paths for system installations and exit"
msgstr ""

#: app/flatpak-main.c:174
msgid "Print the updated environment needed to run flatpaks"
msgstr ""

#: app/flatpak-main.c:175
msgid "Only include the system installation with --print-updated-env"
msgstr ""

#: app/flatpak-main.c:180
msgid "Work on the user installation"
msgstr ""

#: app/flatpak-main.c:181
msgid "Work on the system-wide installation (default)"
msgstr ""

#: app/flatpak-main.c:182
msgid "Work on a non-default system-wide installation"
msgstr ""

#: app/flatpak-main.c:212
msgid "Builtin Commands:"
msgstr ""

#: app/flatpak-main.c:298
#, c-format
msgid ""
"Note that the directories %s are not in the search path set by the "
"XDG_DATA_DIRS environment variable, so applications installed by Flatpak may "
"not appear on your desktop until the session is restarted."
msgstr ""

#: app/flatpak-main.c:312
#, c-format
msgid ""
"Note that the directory %s is not in the search path set by the "
"XDG_DATA_DIRS environment variable, so applications installed by Flatpak may "
"not appear on your desktop until the session is restarted."
msgstr ""

#: app/flatpak-main.c:381
msgid ""
"Refusing to operate under sudo with --user. Omit sudo to operate on the user "
"installation, or use a root shell to operate on the root user's installation."
msgstr ""

#: app/flatpak-main.c:453
msgid ""
"Multiple installations specified for a command that works on one installation"
msgstr ""

#: app/flatpak-main.c:504 app/flatpak-main.c:697
#, c-format
msgid "See '%s --help'"
msgstr ""

#: app/flatpak-main.c:706
#, c-format
msgid "'%s' is not a flatpak command. Did you mean '%s%s'?"
msgstr ""

#: app/flatpak-main.c:709
#, c-format
msgid "'%s' is not a flatpak command"
msgstr ""

#: app/flatpak-main.c:824
msgid "No command specified"
msgstr ""

#: app/flatpak-main.c:980
msgid "error:"
msgstr ""

#: app/flatpak-quiet-transaction.c:77
#, c-format
msgid "Installing %s\n"
msgstr ""

#: app/flatpak-quiet-transaction.c:81
#, c-format
msgid "Updating %s\n"
msgstr ""

#: app/flatpak-quiet-transaction.c:85
#, c-format
msgid "Uninstalling %s\n"
msgstr ""

#: app/flatpak-quiet-transaction.c:107
#, c-format
msgid "Warning: Failed to install %s: %s\n"
msgstr ""

#: app/flatpak-quiet-transaction.c:110
#, c-format
msgid "Error: Failed to install %s: %s\n"
msgstr ""

#: app/flatpak-quiet-transaction.c:116
#, c-format
msgid "Warning: Failed to update %s: %s\n"
msgstr ""

#: app/flatpak-quiet-transaction.c:119
#, c-format
msgid "Error: Failed to update %s: %s\n"
msgstr ""

#: app/flatpak-quiet-transaction.c:125
#, c-format
msgid "Warning: Failed to install bundle %s: %s\n"
msgstr ""

#: app/flatpak-quiet-transaction.c:128
#, c-format
msgid "Error: Failed to install bundle %s: %s\n"
msgstr ""

#: app/flatpak-quiet-transaction.c:134
#, c-format
msgid "Warning: Failed to uninstall %s: %s\n"
msgstr ""

#: app/flatpak-quiet-transaction.c:137
#, c-format
msgid "Error: Failed to uninstall %s: %s\n"
msgstr ""

#: app/flatpak-quiet-transaction.c:166 common/flatpak-dir.c:11475
#, c-format
msgid "%s already installed"
msgstr ""

#: app/flatpak-quiet-transaction.c:168 common/flatpak-dir.c:3622
#: common/flatpak-dir.c:4321 common/flatpak-dir.c:16968
#: common/flatpak-dir.c:17258 common/flatpak-dir-utils.c:166
#: common/flatpak-dir-utils.c:259 common/flatpak-transaction.c:2736
#: common/flatpak-transaction.c:2791
#, c-format
msgid "%s not installed"
msgstr ""

#: app/flatpak-quiet-transaction.c:170
#, c-format
msgid "%s needs a later flatpak version"
msgstr ""

#: app/flatpak-quiet-transaction.c:172
msgid "Not enough disk space to complete this operation"
msgstr ""

#: app/flatpak-quiet-transaction.c:239
#, c-format
msgid "Info: %s is end-of-life, in favor of %s\n"
msgstr ""

#: app/flatpak-quiet-transaction.c:241
#, c-format
msgid "Info: %s is end-of-life, with reason: %s\n"
msgstr ""

#: app/flatpak-quiet-transaction.c:251
#, c-format
msgid "Failed to rebase %s to %s: %s\n"
msgstr ""

#: common/flatpak-auth.c:58
#, c-format
msgid "No authenticator configured for remote `%s`"
msgstr ""

#: common/flatpak-context.c:637 common/flatpak-context.c:649
#, c-format
msgid "Invalid permission syntax: %s"
msgstr ""

#: common/flatpak-context.c:1207
#, c-format
msgid "Unknown share type %s, valid types are: %s"
msgstr ""

#: common/flatpak-context.c:1228
#, c-format
msgid "Unknown policy type %s, valid types are: %s"
msgstr ""

#: common/flatpak-context.c:1266
#, c-format
msgid "Invalid dbus name %s"
msgstr ""

#: common/flatpak-context.c:1279
#, c-format
msgid "Unknown socket type %s, valid types are: %s"
msgstr ""

#: common/flatpak-context.c:1294
#, c-format
msgid "Unknown device type %s, valid types are: %s"
msgstr ""

#: common/flatpak-context.c:1308
#, c-format
msgid "Unknown feature type %s, valid types are: %s"
msgstr ""

#: common/flatpak-context.c:1840
#, c-format
msgid "Filesystem location \"%s\" contains \"..\""
msgstr ""

#: common/flatpak-context.c:1882
#, c-format
msgid ""
"--filesystem=/ is not available, use --filesystem=host for a similar result"
msgstr ""

#: common/flatpak-context.c:1916
#, c-format
msgid ""
"Unknown filesystem location %s, valid locations are: host, host-os, host-"
"etc, host-root, home, xdg-*[/…], ~/dir, /dir"
msgstr ""

#: common/flatpak-context.c:2015
#, c-format
msgid "Invalid syntax for %s: %s"
msgstr ""

#: common/flatpak-context.c:2142
#, c-format
msgid "fallback-x11 can not be conditional"
msgstr ""

#: common/flatpak-context.c:2318
#, c-format
msgid "Invalid env format %s"
msgstr ""

#: common/flatpak-context.c:2399
#, c-format
msgid "Environment variable name must not contain '=': %s"
msgstr ""

#: common/flatpak-context.c:2527 common/flatpak-context.c:2535
#, c-format
msgid "--add-policy arguments must be in the form SUBSYSTEM.KEY=VALUE"
msgstr ""

#: common/flatpak-context.c:2542
#, c-format
msgid "--add-policy values can't start with \"!\""
msgstr ""

#: common/flatpak-context.c:2567 common/flatpak-context.c:2575
#, c-format
msgid "--remove-policy arguments must be in the form SUBSYSTEM.KEY=VALUE"
msgstr ""

#: common/flatpak-context.c:2582
#, c-format
msgid "--remove-policy values can't start with \"!\""
msgstr ""

#: common/flatpak-context.c:2657
msgid "Share with host"
msgstr ""

#: common/flatpak-context.c:2657 common/flatpak-context.c:2658
msgid "SHARE"
msgstr ""

#: common/flatpak-context.c:2658
msgid "Unshare with host"
msgstr ""

#: common/flatpak-context.c:2659
msgid "Require conditions to be met for a subsystem to get shared"
msgstr ""

#: common/flatpak-context.c:2659
msgid "SHARE:CONDITION"
msgstr ""

#: common/flatpak-context.c:2660
msgid "Expose socket to app"
msgstr ""

#: common/flatpak-context.c:2660 common/flatpak-context.c:2661
msgid "SOCKET"
msgstr ""

#: common/flatpak-context.c:2661
msgid "Don't expose socket to app"
msgstr ""

#: common/flatpak-context.c:2662
msgid "Require conditions to be met for a socket to get exposed"
msgstr ""

#: common/flatpak-context.c:2662
msgid "SOCKET:CONDITION"
msgstr ""

#: common/flatpak-context.c:2663
msgid "Expose device to app"
msgstr ""

#: common/flatpak-context.c:2663 common/flatpak-context.c:2664
msgid "DEVICE"
msgstr ""

#: common/flatpak-context.c:2664
msgid "Don't expose device to app"
msgstr ""

#: common/flatpak-context.c:2665
msgid "Require conditions to be met for a device to get exposed"
msgstr ""

#: common/flatpak-context.c:2665
msgid "DEVICE:CONDITION"
msgstr ""

#: common/flatpak-context.c:2666
msgid "Allow feature"
msgstr ""

#: common/flatpak-context.c:2666 common/flatpak-context.c:2667
msgid "FEATURE"
msgstr ""

#: common/flatpak-context.c:2667
msgid "Don't allow feature"
msgstr ""

#: common/flatpak-context.c:2668
msgid "Require conditions to be met for a feature to get allowed"
msgstr ""

#: common/flatpak-context.c:2668
msgid "FEATURE:CONDITION"
msgstr ""

#: common/flatpak-context.c:2669
msgid "Expose filesystem to app (:ro for read-only)"
msgstr ""

#: common/flatpak-context.c:2669
msgid "FILESYSTEM[:ro]"
msgstr ""

#: common/flatpak-context.c:2670
msgid "Don't expose filesystem to app"
msgstr ""

#: common/flatpak-context.c:2670
msgid "FILESYSTEM"
msgstr ""

#: common/flatpak-context.c:2671
msgid "Set environment variable"
msgstr ""

#: common/flatpak-context.c:2671
msgid "VAR=VALUE"
msgstr ""

#: common/flatpak-context.c:2672
msgid "Read environment variables in env -0 format from FD"
msgstr ""

#: common/flatpak-context.c:2673
msgid "Remove variable from environment"
msgstr ""

#: common/flatpak-context.c:2673
msgid "VAR"
msgstr ""

#: common/flatpak-context.c:2674
msgid "Allow app to own name on the session bus"
msgstr ""

#: common/flatpak-context.c:2674 common/flatpak-context.c:2675
#: common/flatpak-context.c:2676 common/flatpak-context.c:2677
#: common/flatpak-context.c:2678 common/flatpak-context.c:2679
#: common/flatpak-context.c:2680
msgid "DBUS_NAME"
msgstr ""

#: common/flatpak-context.c:2675
msgid "Allow app to talk to name on the session bus"
msgstr ""

#: common/flatpak-context.c:2676
msgid "Don't allow app to talk to name on the session bus"
msgstr ""

#: common/flatpak-context.c:2677
msgid "Allow app to own name on the system bus"
msgstr ""

#: common/flatpak-context.c:2678
msgid "Allow app to talk to name on the system bus"
msgstr ""

#: common/flatpak-context.c:2679
msgid "Don't allow app to talk to name on the system bus"
msgstr ""

#: common/flatpak-context.c:2680
msgid "Allow app to own name on the a11y bus"
msgstr ""

#: common/flatpak-context.c:2681
msgid "Add generic policy option"
msgstr ""

#: common/flatpak-context.c:2681 common/flatpak-context.c:2682
msgid "SUBSYSTEM.KEY=VALUE"
msgstr ""

#: common/flatpak-context.c:2682
msgid "Remove generic policy option"
msgstr ""

#: common/flatpak-context.c:2683
msgid "Add USB device to enumerables"
msgstr ""

#: common/flatpak-context.c:2683 common/flatpak-context.c:2684
msgid "VENDOR_ID:PRODUCT_ID"
msgstr ""

#: common/flatpak-context.c:2684
msgid "Add USB device to hidden list"
msgstr ""

#: common/flatpak-context.c:2685
msgid "A list of USB devices that are enumerable"
msgstr ""

#: common/flatpak-context.c:2685
msgid "LIST"
msgstr ""

#: common/flatpak-context.c:2686
msgid "File containing a list of USB devices to make enumerable"
msgstr ""

#: common/flatpak-context.c:2686 common/flatpak-context.c:2687
msgid "FILENAME"
msgstr ""

#: common/flatpak-context.c:2687
msgid "Persist home directory subpath"
msgstr ""

#. This is not needed/used anymore, so hidden, but we accept it for backwards compat
#: common/flatpak-context.c:2689
msgid "Don't require a running session (no cgroups creation)"
msgstr ""

#: common/flatpak-context.c:3718
#, c-format
msgid "Not replacing \"%s\" with tmpfs: %s"
msgstr ""

#: common/flatpak-context.c:3726
#, c-format
msgid "Not sharing \"%s\" with sandbox: %s"
msgstr ""

#. Even if the error is one that we would normally silence, like
#. * the path not existing, it seems reasonable to make more of a fuss
#. * about the home directory not existing or otherwise being unusable,
#. * so this is intentionally not using cannot_export()
#: common/flatpak-context.c:3828
#, c-format
msgid "Not allowing home directory access: %s"
msgstr ""

#: common/flatpak-context.c:4062
#, c-format
msgid "Unable to provide a temporary home directory in the sandbox: %s"
msgstr ""

#: common/flatpak-dir.c:442
#, c-format
msgid "Configured collection ID ‘%s’ not in summary file"
msgstr ""

#: common/flatpak-dir.c:587
#, c-format
msgid "Unable to load summary from remote %s: %s"
msgstr ""

#: common/flatpak-dir.c:764 common/flatpak-dir.c:800 common/flatpak-dir.c:906
#, c-format
msgid "No such ref '%s' in remote %s"
msgstr ""

#: common/flatpak-dir.c:891 common/flatpak-dir.c:1051 common/flatpak-dir.c:1080
#: common/flatpak-dir.c:1092
#, c-format
msgid "No entry for %s in remote %s summary flatpak cache"
msgstr ""

#: common/flatpak-dir.c:1069
#, c-format
msgid "No summary or Flatpak cache available for remote %s"
msgstr ""

#: common/flatpak-dir.c:1097
#, c-format
msgid "Missing xa.data in summary for remote %s"
msgstr ""

#: common/flatpak-dir.c:1103 common/flatpak-dir.c:1546
#, c-format
msgid "Unsupported summary version %d for remote %s"
msgstr ""

#: common/flatpak-dir.c:1200
msgid "Remote OCI index has no registry uri"
msgstr ""

#: common/flatpak-dir.c:1261
#, c-format
msgid "Couldn't find ref %s in remote %s"
msgstr ""

#: common/flatpak-dir.c:1288 common/flatpak-dir.c:1381
#, c-format
msgid "Commit has no requested ref ‘%s’ in ref binding metadata (found: ‘%s’)"
msgstr ""

#: common/flatpak-dir.c:1413
#, c-format
msgid "Configured collection ID ‘%s’ not in binding metadata"
msgstr ""

#: common/flatpak-dir.c:1449 common/flatpak-dir.c:5645
#, c-format
msgid "Couldn't find latest checksum for ref %s in remote %s"
msgstr ""

#: common/flatpak-dir.c:1516 common/flatpak-dir.c:1552
#, c-format
msgid "No entry for %s in remote %s summary flatpak sparse cache"
msgstr ""

#: common/flatpak-dir.c:2540
#, c-format
msgid "Commit metadata for %s not matching expected metadata"
msgstr ""

#: common/flatpak-dir.c:2823
msgid "Unable to connect to system bus"
msgstr ""

#: common/flatpak-dir.c:3419
msgid "User installation"
msgstr ""

#: common/flatpak-dir.c:3426
#, c-format
msgid "System (%s) installation"
msgstr ""

#: common/flatpak-dir.c:3472
#, c-format
msgid "No overrides found for %s"
msgstr ""

#: common/flatpak-dir.c:3625
#, c-format
msgid "%s (commit %s) not installed"
msgstr ""

#: common/flatpak-dir.c:4650
#, c-format
msgid "Error parsing system flatpakrepo file for %s: %s"
msgstr ""

#: common/flatpak-dir.c:4735
#, c-format
msgid "While opening repository %s: "
msgstr ""

#: common/flatpak-dir.c:5004
#, c-format
msgid "The config key %s is not set"
msgstr ""

#: common/flatpak-dir.c:5140
#, c-format
msgid "No current %s pattern matching %s"
msgstr ""

#: common/flatpak-dir.c:5422
msgid "No appstream commit to deploy"
msgstr ""

#: common/flatpak-dir.c:5941 common/flatpak-dir.c:7266
#: common/flatpak-dir.c:10881 common/flatpak-dir.c:11618
msgid "Can't pull from untrusted non-gpg verified remote"
msgstr ""

#: common/flatpak-dir.c:6376 common/flatpak-dir.c:6591
msgid "Extra data not supported for non-gpg-verified local system installs"
msgstr ""

#: common/flatpak-dir.c:6415 common/flatpak-dir.c:6782
#, c-format
msgid "Invalid checksum for extra data uri %s"
msgstr ""

#: common/flatpak-dir.c:6424
#, c-format
msgid "Empty name for extra data uri %s"
msgstr ""

#: common/flatpak-dir.c:6432
#, c-format
msgid "Unsupported extra data uri %s"
msgstr ""

#: common/flatpak-dir.c:6461
#, c-format
msgid "Failed to load local extra-data %s: %s"
msgstr ""

#: common/flatpak-dir.c:6469
#, c-format
msgid "Wrong size for extra-data %s"
msgstr ""

#: common/flatpak-dir.c:6488
#, c-format
msgid "While downloading %s: "
msgstr ""

#: common/flatpak-dir.c:6498
#, c-format
msgid "Wrong size for extra data %s"
msgstr ""

#: common/flatpak-dir.c:6507
#, c-format
msgid "Invalid checksum for extra data %s"
msgstr ""

#: common/flatpak-dir.c:7096 common/flatpak-dir.c:7349
#, c-format
msgid "While pulling %s from remote %s: "
msgstr ""

#: common/flatpak-dir.c:7290 common/flatpak-repo-utils.c:3886
msgid "GPG signatures found, but none are in trusted keyring"
msgstr ""

#: common/flatpak-dir.c:7307
#, c-format
msgid "Commit for ‘%s’ has no ref binding"
msgstr ""

#: common/flatpak-dir.c:7312
#, c-format
msgid "Commit for ‘%s’ is not in expected bound refs: %s"
msgstr ""

#: common/flatpak-dir.c:7488
msgid "Only applications can be made current"
msgstr ""

#: common/flatpak-dir.c:8192
msgid "Not enough memory"
msgstr ""

#: common/flatpak-dir.c:8211
msgid "Failed to read from exported file"
msgstr ""

#: common/flatpak-dir.c:8401
msgid "Error reading mimetype xml file"
msgstr ""

#: common/flatpak-dir.c:8406
msgid "Invalid mimetype xml file"
msgstr ""

#: common/flatpak-dir.c:8492
#, c-format
msgid "D-Bus service file '%s' has wrong name"
msgstr ""

#: common/flatpak-dir.c:8647
#, c-format
msgid "Invalid Exec argument %s"
msgstr ""

#: common/flatpak-dir.c:9115
msgid "While getting detached metadata: "
msgstr ""

#: common/flatpak-dir.c:9120 common/flatpak-dir.c:9125
#: common/flatpak-dir.c:9129
msgid "Extra data missing in detached metadata"
msgstr ""

#: common/flatpak-dir.c:9133
msgid "While creating extradir: "
msgstr ""

#: common/flatpak-dir.c:9154 common/flatpak-dir.c:9187
msgid "Invalid checksum for extra data"
msgstr ""

#: common/flatpak-dir.c:9183
msgid "Wrong size for extra data"
msgstr ""

#: common/flatpak-dir.c:9196
#, c-format
msgid "While writing extra data file '%s': "
msgstr ""

#: common/flatpak-dir.c:9204
#, c-format
msgid "Extra data %s missing in detached metadata"
msgstr ""

#: common/flatpak-dir.c:9278
#, c-format
msgid "Unable to get runtime key from metadata"
msgstr ""

#: common/flatpak-dir.c:9402
#, c-format
msgid "apply_extra script failed, exit status %d"
msgstr ""

#. Translators: The placeholder is for an app ref.
#: common/flatpak-dir.c:9591
#, c-format
msgid "Installing %s is not allowed by the policy set by your administrator"
msgstr ""

#: common/flatpak-dir.c:9690
#, c-format
msgid "While trying to resolve ref %s: "
msgstr ""

#: common/flatpak-dir.c:9702
#, c-format
msgid "%s is not available"
msgstr ""

#: common/flatpak-dir.c:9714 common/flatpak-dir.c:11495
#, c-format
msgid "%s commit %s already installed"
msgstr ""

#: common/flatpak-dir.c:9721
msgid "Can't create deploy directory"
msgstr ""

#: common/flatpak-dir.c:9729
#, c-format
msgid "Failed to read commit %s: "
msgstr ""

#: common/flatpak-dir.c:9750
#, c-format
msgid "While trying to checkout %s into %s: "
msgstr ""

#: common/flatpak-dir.c:9769
msgid "While trying to checkout metadata subpath: "
msgstr ""

#: common/flatpak-dir.c:9801
#, c-format
msgid "While trying to checkout subpath ‘%s’: "
msgstr ""

#: common/flatpak-dir.c:9811
msgid "While trying to remove existing extra dir: "
msgstr ""

#: common/flatpak-dir.c:9822
msgid "While trying to apply extra data: "
msgstr ""

#: common/flatpak-dir.c:9849
#, c-format
msgid "Invalid commit ref %s: "
msgstr ""

#: common/flatpak-dir.c:9857 common/flatpak-dir.c:9869
#, c-format
msgid "Deployed ref %s does not match commit (%s)"
msgstr ""

#: common/flatpak-dir.c:9863
#, c-format
msgid "Deployed ref %s branch does not match commit (%s)"
msgstr ""

#: common/flatpak-dir.c:10125 common/flatpak-installation.c:1911
#, c-format
msgid "%s branch %s already installed"
msgstr ""

#: common/flatpak-dir.c:10985
#, c-format
msgid "Could not unmount revokefs-fuse filesystem at %s: "
msgstr ""

#: common/flatpak-dir.c:11289
#, c-format
msgid "This version of %s is already installed"
msgstr ""

#: common/flatpak-dir.c:11302
#, c-format
msgid "Can't change remote during bundle install"
msgstr ""

#: common/flatpak-dir.c:11571
msgid "Can't update to a specific commit without root permissions"
msgstr ""

#: common/flatpak-dir.c:11852
#, c-format
msgid "Can't remove %s, it is needed for: %s"
msgstr ""

#: common/flatpak-dir.c:11912 common/flatpak-installation.c:2067
#, c-format
msgid "%s branch %s is not installed"
msgstr ""

#: common/flatpak-dir.c:12165
#, c-format
msgid "%s commit %s not installed"
msgstr ""

#: common/flatpak-dir.c:12501
#, c-format
msgid "Pruning repo failed: %s"
msgstr ""

#: common/flatpak-dir.c:12669 common/flatpak-dir.c:12675
#, c-format
msgid "Failed to load filter '%s'"
msgstr ""

#: common/flatpak-dir.c:12681
#, c-format
msgid "Failed to parse filter '%s'"
msgstr ""

#: common/flatpak-dir.c:12963
msgid "Failed to write summary cache: "
msgstr ""

#: common/flatpak-dir.c:12982
#, c-format
msgid "No oci summary cached for remote '%s'"
msgstr ""

#: common/flatpak-dir.c:13207
#, c-format
msgid "No cached summary for remote '%s'"
msgstr ""

#: common/flatpak-dir.c:13248
#, c-format
msgid "Invalid checksum for indexed summary %s read from %s"
msgstr ""

#: common/flatpak-dir.c:13321
#, c-format
msgid ""
"Remote listing for %s not available; server has no summary file. Check the "
"URL passed to remote-add was valid."
msgstr ""

#: common/flatpak-dir.c:13698
#, c-format
msgid "Invalid checksum for indexed summary %s for remote '%s'"
msgstr ""

#: common/flatpak-dir.c:14388
#, c-format
msgid "Multiple branches available for %s, you must specify one of: "
msgstr ""

#: common/flatpak-dir.c:14454
#, c-format
msgid "Nothing matches %s"
msgstr ""

#: common/flatpak-dir.c:14562
#, c-format
msgid "Can't find ref %s%s%s%s%s"
msgstr ""

#: common/flatpak-dir.c:14605
#, c-format
msgid "Error searching remote %s: %s"
msgstr ""

#: common/flatpak-dir.c:14702
#, c-format
msgid "Error searching local repository: %s"
msgstr ""

#: common/flatpak-dir.c:14839
#, c-format
msgid "%s/%s/%s not installed"
msgstr ""

#: common/flatpak-dir.c:15042
#, c-format
msgid "Could not find installation %s"
msgstr ""

#: common/flatpak-dir.c:15612
#, c-format
msgid "Invalid file format, no %s group"
msgstr ""

#: common/flatpak-dir.c:15617 common/flatpak-repo-utils.c:2836
#, c-format
msgid "Invalid version %s, only 1 supported"
msgstr ""

#: common/flatpak-dir.c:15622 common/flatpak-dir.c:15627
#, c-format
msgid "Invalid file format, no %s specified"
msgstr ""

#. Check some minimal size so we don't get crap
#: common/flatpak-dir.c:15647
msgid "Invalid file format, gpg key invalid"
msgstr ""

#: common/flatpak-dir.c:15675 common/flatpak-repo-utils.c:2917
msgid "Collection ID requires GPG key to be provided"
msgstr ""

#: common/flatpak-dir.c:15718
#, c-format
msgid "Runtime %s, branch %s is already installed"
msgstr ""

#: common/flatpak-dir.c:15719
#, c-format
msgid "App %s, branch %s is already installed"
msgstr ""

#: common/flatpak-dir.c:15953
#, c-format
msgid "Can't remove remote '%s' with installed ref %s (at least)"
msgstr ""

#: common/flatpak-dir.c:16058
#, c-format
msgid "Invalid character '/' in remote name: %s"
msgstr ""

#: common/flatpak-dir.c:16064
#, c-format
msgid "No configuration for remote %s specified"
msgstr ""

#: common/flatpak-dir.c:17597
#, c-format
msgid "Skipping deletion of mirror ref (%s, %s)…\n"
msgstr ""

#: common/flatpak-exports.c:931
#, c-format
msgid "An absolute path is required"
msgstr ""

#: common/flatpak-exports.c:948
#, c-format
msgid "Unable to open path \"%s\": %s"
msgstr ""

#: common/flatpak-exports.c:955
#, c-format
msgid "Unable to get file type of \"%s\": %s"
msgstr ""

#: common/flatpak-exports.c:964
#, c-format
msgid "File \"%s\" has unsupported type 0o%o"
msgstr ""

#: common/flatpak-exports.c:970
#, c-format
msgid "Unable to get filesystem information for \"%s\": %s"
msgstr ""

#: common/flatpak-exports.c:980
#, c-format
msgid "Ignoring blocking autofs path \"%s\""
msgstr ""

#: common/flatpak-exports.c:996 common/flatpak-exports.c:1009
#: common/flatpak-exports.c:1022
#, c-format
msgid "Path \"%s\" is reserved by Flatpak"
msgstr ""

#: common/flatpak-exports.c:1076
#, c-format
msgid "Unable to resolve symbolic link \"%s\": %s"
msgstr ""

#: common/flatpak-glib-backports.c:69
msgid "Empty string is not a number"
msgstr ""

#: common/flatpak-glib-backports.c:95
#, c-format
msgid "“%s” is not an unsigned number"
msgstr ""

#: common/flatpak-glib-backports.c:105
#, c-format
msgid "Number “%s” is out of bounds [%s, %s]"
msgstr ""

#: common/flatpak-image-source.c:83
msgid "Only sha256 image checksums are supported"
msgstr ""

#: common/flatpak-image-source.c:100 common/flatpak-image-source.c:108
msgid "Image is not a manifest"
msgstr ""

#: common/flatpak-image-source.c:123
msgid "No org.flatpak.ref found in image"
msgstr ""

#: common/flatpak-image-source.c:148
#, c-format
msgid "Ref '%s' not found in registry"
msgstr ""

#: common/flatpak-image-source.c:157
msgid "Multiple images in registry, specify a ref with --ref"
msgstr ""

#: common/flatpak-installation.c:834
#, c-format
msgid "Ref %s not installed"
msgstr ""

#: common/flatpak-installation.c:875
#, c-format
msgid "App %s not installed"
msgstr ""

#: common/flatpak-installation.c:1395
#, c-format
msgid "Remote '%s' already exists"
msgstr ""

#: common/flatpak-installation.c:1946
#, c-format
msgid "As requested, %s was only pulled, but not installed"
msgstr ""

#: common/flatpak-instance.c:533 common/flatpak-instance.c:687
#: common/flatpak-instance.c:728
#, c-format
msgid "Unable to create directory %s"
msgstr ""

#: common/flatpak-instance.c:554
#, c-format
msgid "Unable to lock %s"
msgstr ""

#: common/flatpak-instance.c:627
#, c-format
msgid "Unable to create temporary directory in %s"
msgstr ""

#: common/flatpak-instance.c:639
#, c-format
msgid "Unable to create file %s"
msgstr ""

#: common/flatpak-instance.c:646
#, c-format
msgid "Unable to update symbolic link %s/%s"
msgstr ""

#: common/flatpak-oci-registry.c:1197
msgid "Only Bearer authentication supported"
msgstr ""

#: common/flatpak-oci-registry.c:1206
msgid "Only realm in authentication request"
msgstr ""

#: common/flatpak-oci-registry.c:1213
msgid "Invalid realm in authentication request"
msgstr ""

#: common/flatpak-oci-registry.c:1283
#, c-format
msgid "Authorization failed: %s"
msgstr ""

#: common/flatpak-oci-registry.c:1285
msgid "Authorization failed"
msgstr ""

#: common/flatpak-oci-registry.c:1289
#, c-format
msgid "Unexpected response status %d when requesting token: %s"
msgstr ""

#: common/flatpak-oci-registry.c:1300
msgid "Invalid authentication request response"
msgstr ""

#: common/flatpak-oci-registry.c:1731
#, c-format
msgid "Flatpak was compiled without zstd support"
msgstr ""

#: common/flatpak-oci-registry.c:1923 common/flatpak-oci-registry.c:1975
#: common/flatpak-oci-registry.c:2004 common/flatpak-oci-registry.c:2059
#: common/flatpak-oci-registry.c:2115 common/flatpak-oci-registry.c:2193
msgid "Invalid delta file format"
msgstr ""

#: common/flatpak-oci-registry.c:3198 common/flatpak-oci-registry.c:3382
msgid "Invalid OCI image config"
msgstr ""

#: common/flatpak-oci-registry.c:3260 common/flatpak-oci-registry.c:3531
#, c-format
msgid "Wrong layer checksum, expected %s, was %s"
msgstr ""

#: common/flatpak-oci-registry.c:3359
#, c-format
msgid "No ref specified for OCI image %s"
msgstr ""

#: common/flatpak-oci-registry.c:3369
#, c-format
msgid "Wrong ref (%s) specified for OCI image %s, expected %s"
msgstr ""

#: common/flatpak-progress.c:236
#, c-format
msgid "Downloading metadata: %u/(estimating) %s"
msgstr ""

#: common/flatpak-progress.c:260
#, c-format
msgid "Downloading: %s/%s"
msgstr ""

#: common/flatpak-progress.c:280
#, c-format
msgid "Downloading extra data: %s/%s"
msgstr ""

#: common/flatpak-progress.c:285
#, c-format
msgid "Downloading files: %d/%d %s"
msgstr ""

#: common/flatpak-ref-utils.c:122
msgid "Name can't be empty"
msgstr ""

#: common/flatpak-ref-utils.c:129
msgid "Name can't be longer than 255 characters"
msgstr ""

#: common/flatpak-ref-utils.c:142
msgid "Name can't start with a period"
msgstr ""

#: common/flatpak-ref-utils.c:148
#, c-format
msgid "Name can't start with %c"
msgstr ""

#: common/flatpak-ref-utils.c:164
msgid "Name can't end with a period"
msgstr ""

#: common/flatpak-ref-utils.c:171 common/flatpak-ref-utils.c:183
msgid "Only last name segment can contain -"
msgstr ""

#: common/flatpak-ref-utils.c:174
#, c-format
msgid "Name segment can't start with %c"
msgstr ""

#: common/flatpak-ref-utils.c:186
#, c-format
msgid "Name can't contain %c"
msgstr ""

#: common/flatpak-ref-utils.c:195
msgid "Names must contain at least 2 periods"
msgstr ""

#: common/flatpak-ref-utils.c:312
msgid "Arch can't be empty"
msgstr ""

#: common/flatpak-ref-utils.c:323
#, c-format
msgid "Arch can't contain %c"
msgstr ""

#: common/flatpak-ref-utils.c:385
msgid "Branch can't be empty"
msgstr ""

#: common/flatpak-ref-utils.c:395
#, c-format
msgid "Branch can't start with %c"
msgstr ""

#: common/flatpak-ref-utils.c:405
#, c-format
msgid "Branch can't contain %c"
msgstr ""

#: common/flatpak-ref-utils.c:615 common/flatpak-ref-utils.c:865
msgid "Ref too long"
msgstr ""

#: common/flatpak-ref-utils.c:627
msgid "Invalid remote name"
msgstr ""

#: common/flatpak-ref-utils.c:641
#, c-format
msgid "%s is not application or runtime"
msgstr ""

#: common/flatpak-ref-utils.c:650 common/flatpak-ref-utils.c:667
#: common/flatpak-ref-utils.c:683
#, c-format
msgid "Wrong number of components in %s"
msgstr ""

#: common/flatpak-ref-utils.c:656
#, c-format
msgid "Invalid name %.*s: %s"
msgstr ""

#: common/flatpak-ref-utils.c:673
#, c-format
msgid "Invalid arch: %.*s: %s"
msgstr ""

#: common/flatpak-ref-utils.c:816
#, c-format
msgid "Invalid name %s: %s"
msgstr ""

#: common/flatpak-ref-utils.c:834
#, c-format
msgid "Invalid arch: %s: %s"
msgstr ""

#: common/flatpak-ref-utils.c:853
#, c-format
msgid "Invalid branch: %s: %s"
msgstr ""

#: common/flatpak-ref-utils.c:962 common/flatpak-ref-utils.c:970
#: common/flatpak-ref-utils.c:978
#, c-format
msgid "Wrong number of components in partial ref %s"
msgstr ""

#: common/flatpak-ref-utils.c:1298
msgid " development platform"
msgstr ""

#: common/flatpak-ref-utils.c:1300
msgid " platform"
msgstr ""

#: common/flatpak-ref-utils.c:1302
msgid " application base"
msgstr ""

#: common/flatpak-ref-utils.c:1305
msgid " debug symbols"
msgstr ""

#: common/flatpak-ref-utils.c:1307
msgid " sourcecode"
msgstr ""

#: common/flatpak-ref-utils.c:1309
msgid " translations"
msgstr ""

#: common/flatpak-ref-utils.c:1311
msgid " docs"
msgstr ""

#: common/flatpak-ref-utils.c:1578
#, c-format
msgid "Invalid id %s: %s"
msgstr ""

#: common/flatpak-remote.c:1216
#, c-format
msgid "Bad remote name: %s"
msgstr ""

#: common/flatpak-remote.c:1220
msgid "No URL specified"
msgstr ""

#: common/flatpak-remote.c:1266
msgid "GPG verification must be enabled when a collection ID is set"
msgstr ""

#: common/flatpak-repo-utils.c:344
#, c-format
msgid "No extra data sources"
msgstr ""

#: common/flatpak-repo-utils.c:2817
#, c-format
msgid "Invalid %s: Missing group ‘%s’"
msgstr ""

#: common/flatpak-repo-utils.c:2826
#, c-format
msgid "Invalid %s: Missing key ‘%s’"
msgstr ""

#: common/flatpak-repo-utils.c:2876
msgid "Invalid gpg key"
msgstr ""

#: common/flatpak-repo-utils.c:3217
#, c-format
msgid "Error copying 64x64 icon for component %s: %s\n"
msgstr ""

#: common/flatpak-repo-utils.c:3223
#, c-format
msgid "Error copying 128x128 icon for component %s: %s\n"
msgstr ""

#: common/flatpak-repo-utils.c:3362
#, c-format
msgid "%s is end-of-life, ignoring for appstream"
msgstr ""

#: common/flatpak-repo-utils.c:3397
#, c-format
msgid "No appstream data for %s: %s\n"
msgstr ""

#: common/flatpak-repo-utils.c:3744
msgid "Invalid bundle, no ref in metadata"
msgstr ""

#: common/flatpak-repo-utils.c:3846
#, c-format
msgid "Collection ‘%s’ of bundle doesn’t match collection ‘%s’ of remote"
msgstr ""

#: common/flatpak-repo-utils.c:3923
msgid "Metadata in header and app are inconsistent"
msgstr ""

#: common/flatpak-run.c:951
msgid "No systemd user session available, cgroups not available"
msgstr ""

#: common/flatpak-run.c:1496
msgid "Unable to allocate instance id"
msgstr ""

#: common/flatpak-run.c:1632 common/flatpak-run.c:1641
#, c-format
msgid "Failed to open flatpak-info file: %s"
msgstr ""

#: common/flatpak-run.c:1668
#, c-format
msgid "Failed to open bwrapinfo.json file: %s"
msgstr ""

#: common/flatpak-run.c:1689
#, c-format
msgid "Failed to write to instance id fd: %s"
msgstr ""

#: common/flatpak-run.c:2096
msgid "Initialize seccomp failed"
msgstr ""

#: common/flatpak-run.c:2135
#, c-format
msgid "Failed to add architecture to seccomp filter: %s"
msgstr ""

#: common/flatpak-run.c:2143
#, c-format
msgid "Failed to add multiarch architecture to seccomp filter: %s"
msgstr ""

#: common/flatpak-run.c:2175 common/flatpak-run.c:2192
#: common/flatpak-run.c:2214
#, c-format
msgid "Failed to block syscall %d: %s"
msgstr ""

#: common/flatpak-run.c:2247
#, c-format
msgid "Failed to export bpf: %s"
msgstr ""

#: common/flatpak-run.c:2587
#, c-format
msgid "Failed to open ‘%s’"
msgstr ""

#: common/flatpak-run.c:2597
#, c-format
msgid ""
"Directory forwarding needs version 4 of the document portal (have version %d)"
msgstr ""

#: common/flatpak-run.c:2915
#, c-format
msgid "ldconfig failed, exit status %d"
msgstr ""

#: common/flatpak-run.c:2922
msgid "Can't open generated ld.so.cache"
msgstr ""

#. Translators: The placeholder is for an app ref.
#: common/flatpak-run.c:3045
#, c-format
msgid "Running %s is not allowed by the policy set by your administrator"
msgstr ""

#: common/flatpak-run.c:3202
msgid ""
"\"flatpak run\" is not intended to be run as `sudo flatpak run`. Use `sudo "
"-i` or `su -l` instead and invoke \"flatpak run\" from inside the new shell."
msgstr ""

#: common/flatpak-run.c:3413
#, c-format
msgid "Failed to migrate from %s: %s"
msgstr ""

#: common/flatpak-run.c:3434
#, c-format
msgid "Failed to migrate old app data directory %s to new name %s: %s"
msgstr ""

#: common/flatpak-run.c:3443
#, c-format
msgid "Failed to create symlink while migrating %s: %s"
msgstr ""

#: common/flatpak-run-dbus.c:46
msgid "Failed to open app info file"
msgstr ""

#: common/flatpak-run-dbus.c:149
msgid "Unable to create sync pipe"
msgstr ""

#: common/flatpak-run-dbus.c:185
msgid "Failed to sync with dbus proxy"
msgstr ""

#: common/flatpak-transaction.c:2275
#, c-format
msgid "Warning: Problem looking for related refs: %s"
msgstr ""

#: common/flatpak-transaction.c:2493
#, c-format
msgid "The application %s requires the runtime %s which was not found"
msgstr ""

#: common/flatpak-transaction.c:2509
#, c-format
msgid "The application %s requires the runtime %s which is not installed"
msgstr ""

#: common/flatpak-transaction.c:2641
#, c-format
msgid "Can't uninstall %s which is needed by %s"
msgstr ""

#: common/flatpak-transaction.c:2740
#, c-format
msgid "Remote %s disabled, ignoring %s update"
msgstr ""

#: common/flatpak-transaction.c:2773
#, c-format
msgid "%s is already installed"
msgstr ""

#: common/flatpak-transaction.c:2776
#, c-format
msgid "%s is already installed from remote %s"
msgstr ""

#: common/flatpak-transaction.c:3120
#, c-format
msgid "Invalid .flatpakref: %s"
msgstr ""

#: common/flatpak-transaction.c:3161
msgid "Warning: Could not mark already installed apps as preinstalled"
msgstr ""

#: common/flatpak-transaction.c:3382
#, c-format
msgid "Error updating remote metadata for '%s': %s"
msgstr ""

#: common/flatpak-transaction.c:3885
#, c-format
msgid ""
"Warning: Treating remote fetch error as non-fatal since %s is already "
"installed: %s"
msgstr ""

#: common/flatpak-transaction.c:4209
#, c-format
msgid "No authenticator installed for remote '%s'"
msgstr ""

#: common/flatpak-transaction.c:4313 common/flatpak-transaction.c:4320
#, c-format
msgid "Failed to get tokens for ref: %s"
msgstr ""

#: common/flatpak-transaction.c:4315 common/flatpak-transaction.c:4322
msgid "Failed to get tokens for ref"
msgstr ""

#: common/flatpak-transaction.c:4580
#, c-format
msgid "Ref %s from %s matches more than one transaction operation"
msgstr ""

#: common/flatpak-transaction.c:4581 common/flatpak-transaction.c:4591
msgid "any remote"
msgstr ""

#: common/flatpak-transaction.c:4590
#, c-format
msgid "No transaction operation found for ref %s from %s"
msgstr ""

#: common/flatpak-transaction.c:4713
#, c-format
msgid "Flatpakrepo URL %s not file, HTTP or HTTPS"
msgstr ""

#: common/flatpak-transaction.c:4719
#, c-format
msgid "Can't load dependent file %s: "
msgstr ""

#: common/flatpak-transaction.c:4727
#, c-format
msgid "Invalid .flatpakrepo: %s"
msgstr ""

#: common/flatpak-transaction.c:5454
msgid "Transaction already executed"
msgstr ""

#: common/flatpak-transaction.c:5469
msgid ""
"Refusing to operate on a user installation as root! This can lead to "
"incorrect file ownership and permission errors."
msgstr ""

#: common/flatpak-transaction.c:5567 common/flatpak-transaction.c:5580
msgid "Aborted by user"
msgstr ""

#: common/flatpak-transaction.c:5605
#, c-format
msgid "Skipping %s due to previous error"
msgstr ""

#: common/flatpak-transaction.c:5659
#, c-format
msgid "Aborted due to failure (%s)"
msgstr ""

#: common/flatpak-uri.c:118
#, no-c-format
msgid "Invalid %-encoding in URI"
msgstr ""

#: common/flatpak-uri.c:135
msgid "Illegal character in URI"
msgstr ""

#: common/flatpak-uri.c:169
msgid "Non-UTF-8 characters in URI"
msgstr ""

#: common/flatpak-uri.c:275
#, c-format
msgid "Invalid IPv6 address ‘%.*s’ in URI"
msgstr ""

#: common/flatpak-uri.c:330
#, c-format
msgid "Illegal encoded IP address ‘%.*s’ in URI"
msgstr ""

#: common/flatpak-uri.c:342
#, c-format
msgid "Illegal internationalized hostname ‘%.*s’ in URI"
msgstr ""

#: common/flatpak-uri.c:374 common/flatpak-uri.c:386
#, c-format
msgid "Could not parse port ‘%.*s’ in URI"
msgstr ""

#: common/flatpak-uri.c:393
#, c-format
msgid "Port ‘%.*s’ in URI is out of range"
msgstr ""

#: common/flatpak-uri.c:910
msgid "URI is not absolute, and no base URI was provided"
msgstr ""

#: common/flatpak-usb.c:83
#, c-format
msgid "USB device query 'all' must not have data"
msgstr ""

#: common/flatpak-usb.c:102
#, c-format
msgid "USB query rule 'cls' must be in the form CLASS:SUBCLASS or CLASS:*"
msgstr ""

#: common/flatpak-usb.c:111
#, c-format
msgid "Invalid USB class"
msgstr ""

#: common/flatpak-usb.c:125
#, c-format
msgid "Invalid USB subclass"
msgstr ""

#: common/flatpak-usb.c:141 common/flatpak-usb.c:148
#, c-format
msgid "USB query rule 'dev' must have a valid 4-digit hexadecimal product id"
msgstr ""

#: common/flatpak-usb.c:164 common/flatpak-usb.c:171
#, c-format
msgid "USB query rule 'vnd' must have a valid 4-digit hexadecimal vendor id"
msgstr ""

#: common/flatpak-usb.c:205
#, c-format
msgid "USB device queries must be in the form TYPE:DATA"
msgstr ""

#: common/flatpak-usb.c:225
#, c-format
msgid "Unknown USB query rule %s"
msgstr ""

#: common/flatpak-usb.c:248
#, c-format
msgid "Empty USB query"
msgstr ""

#: common/flatpak-usb.c:274
#, c-format
msgid "Multiple USB query rules of the same type is not supported"
msgstr ""

#: common/flatpak-usb.c:283
#, c-format
msgid "'all' must not contain extra query rules"
msgstr ""

#: common/flatpak-usb.c:291
#, c-format
msgid "USB queries with 'dev' must also specify vendors"
msgstr ""

#: common/flatpak-utils.c:712
msgid "Glob can't match apps"
msgstr ""

#: common/flatpak-utils.c:737
msgid "Empty glob"
msgstr ""

#: common/flatpak-utils.c:756
msgid "Too many segments in glob"
msgstr ""

#: common/flatpak-utils.c:777
#, c-format
msgid "Invalid glob character '%c'"
msgstr ""

#: common/flatpak-utils.c:831
#, c-format
msgid "Missing glob on line %d"
msgstr ""

#: common/flatpak-utils.c:835
#, c-format
msgid "Trailing text on line %d"
msgstr ""

#: common/flatpak-utils.c:839
#, c-format
msgid "on line %d"
msgstr ""

#: common/flatpak-utils.c:861
#, c-format
msgid "Unexpected word '%s' on line %d"
msgstr ""

#: common/flatpak-utils.c:2118
#, c-format
msgid "Invalid require-flatpak argument %s"
msgstr ""

#: common/flatpak-utils.c:2128 common/flatpak-utils.c:2147
#, c-format
msgid "%s needs a later flatpak version (%s)"
msgstr ""

#: oci-authenticator/flatpak-oci-authenticator.c:291
msgid "Not a oci remote, missing summary.xa.oci-repository"
msgstr ""

#: oci-authenticator/flatpak-oci-authenticator.c:477
msgid "Not a OCI remote"
msgstr ""

#: oci-authenticator/flatpak-oci-authenticator.c:488
msgid "Invalid token"
msgstr ""

#: portal/flatpak-portal.c:2292
#, c-format
msgid "No portal support found"
msgstr ""

#: portal/flatpak-portal.c:2298
msgid "Deny"
msgstr ""

#: portal/flatpak-portal.c:2300
msgid "Update"
msgstr ""

#: portal/flatpak-portal.c:2305
#, c-format
msgid "Update %s?"
msgstr ""

#: portal/flatpak-portal.c:2317
msgid "The application wants to update itself."
msgstr ""

#: portal/flatpak-portal.c:2318
msgid "Update access can be changed any time from the privacy settings."
msgstr ""

#: portal/flatpak-portal.c:2343
#, c-format
msgid "Application update not allowed"
msgstr ""

#: portal/flatpak-portal.c:2501
#, c-format
msgid "Self update not supported, new version requires new permissions"
msgstr ""

#: portal/flatpak-portal.c:2684 portal/flatpak-portal.c:2702
#, c-format
msgid "Update ended unexpectedly"
msgstr ""

#. SECURITY:
#. - Normal users need admin authentication to install software
#. system-wide.
#. - Note that we install polkit rules that allow local users
#. in the wheel group to install without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:23
msgid "Install signed application"
msgstr ""

#: system-helper/org.freedesktop.Flatpak.policy.in:24
#: system-helper/org.freedesktop.Flatpak.policy.in:42
msgid "Authentication is required to install software"
msgstr ""

#. SECURITY:
#. - Normal users need admin authentication to install software
#. system-wide.
#. - Note that we install polkit rules that allow local users
#. in the wheel group to install without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:41
msgid "Install signed runtime"
msgstr ""

#. SECURITY:
#. - Normal users do not require admin authentication to update an
#. app as the commit will be signed, and the action is required
#. to update the system when unattended.
#. - Changing this to anything other than 'yes' will break unattended
#. updates.
#: system-helper/org.freedesktop.Flatpak.policy.in:60
msgid "Update signed application"
msgstr ""

#: system-helper/org.freedesktop.Flatpak.policy.in:61
#: system-helper/org.freedesktop.Flatpak.policy.in:80
msgid "Authentication is required to update software"
msgstr ""

#. SECURITY:
#. - Normal users do not require admin authentication to update a
#. runtime as the commit will be signed, and the action is required
#. to update the system when unattended.
#. - Changing this to anything other than 'yes' will break unattended
#. updates.
#: system-helper/org.freedesktop.Flatpak.policy.in:79
msgid "Update signed runtime"
msgstr ""

#. SECURITY:
#. - Normal users do not need authentication to update metadata
#. from signed repositories.
#: system-helper/org.freedesktop.Flatpak.policy.in:94
msgid "Update remote metadata"
msgstr ""

#: system-helper/org.freedesktop.Flatpak.policy.in:95
msgid "Authentication is required to update remote info"
msgstr ""

#. SECURITY:
#. - Normal users do not need authentication to modify the
#. OSTree repository
#. - Note that we install polkit rules that allow local users
#. in the wheel group to modify repos without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:111
msgid "Update system repository"
msgstr ""

#: system-helper/org.freedesktop.Flatpak.policy.in:112
msgid "Authentication is required to modify a system repository"
msgstr ""

#. SECURITY:
#. - Normal users need admin authentication to install software
#. system-wide.
#: system-helper/org.freedesktop.Flatpak.policy.in:126
msgid "Install bundle"
msgstr ""

#: system-helper/org.freedesktop.Flatpak.policy.in:127
msgid "Authentication is required to install software from $(path)"
msgstr ""

#. SECURITY:
#. - Normal users need admin authentication to uninstall software
#. system-wide.
#. - Note that we install polkit rules that allow local users
#. in the wheel group to uninstall without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:144
msgid "Uninstall runtime"
msgstr ""

#: system-helper/org.freedesktop.Flatpak.policy.in:145
msgid "Authentication is required to uninstall software"
msgstr ""

#. SECURITY:
#. - Normal users need admin authentication to uninstall software
#. system-wide.
#. - Note that we install polkit rules that allow local users
#. in the wheel group to uninstall without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:161
msgid "Uninstall app"
msgstr "Désinstaller l'appli"

#: system-helper/org.freedesktop.Flatpak.policy.in:162
msgid "Authentication is required to uninstall $(ref)"
msgstr ""

#. SECURITY:
#. - Normal users need admin authentication to configure system-wide
#. software repositories.
#: system-helper/org.freedesktop.Flatpak.policy.in:177
msgid "Configure Remote"
msgstr ""

#: system-helper/org.freedesktop.Flatpak.policy.in:178
msgid "Authentication is required to configure software repositories"
msgstr ""

#. SECURITY:
#. - Normal users need admin authentication to configure the system-wide
#. Flatpak installation.
#: system-helper/org.freedesktop.Flatpak.policy.in:192
msgid "Configure"
msgstr ""

#: system-helper/org.freedesktop.Flatpak.policy.in:193
msgid "Authentication is required to configure software installation"
msgstr ""

#. SECURITY:
#. - Normal users do not require admin authentication to update
#. appstream data as it will be signed, and the action is required
#. to update the system when unattended.
#. - Changing this to anything other than 'yes' will break unattended
#. updates.
#: system-helper/org.freedesktop.Flatpak.policy.in:210
msgid "Update appstream"
msgstr ""

#: system-helper/org.freedesktop.Flatpak.policy.in:211
msgid "Authentication is required to update information about software"
msgstr ""

#. SECURITY:
#. - Normal users do not require admin authentication to update
#. metadata as it will be signed, and the action is required
#. to update the system when unattended.
#. - Changing this to anything other than 'yes' will break unattended
#. updates.
#: system-helper/org.freedesktop.Flatpak.policy.in:228
msgid "Update metadata"
msgstr "Mettre à jour la métadonnée"

#: system-helper/org.freedesktop.Flatpak.policy.in:229
msgid "Authentication is required to update metadata"
msgstr ""

#. SECURITY:
#. - Authorisation to actually install software is controlled by
#. org.freedesktop.Flatpak.app-install.
#. - This action is checked after app-install, as it can only be done
#. once the app’s data (including its content rating) has been
#. downloaded.
#. - This action is checked to see if the installation should be allowed
#. based on whether the app being installed has content which doesn’t
#. comply with the user’s parental controls policy (the content is
#. ‘too extreme’).
#. - It is checked only if an app has too extreme content for the user
#. who is trying to install it (in which case, the app is ‘unsafe’).
#. - Typically, normal users will need admin permission to install apps
#. with extreme content; admins will be able to install it without
#. additional checks.
#. - In order to configure the policy so that admins can install safe and
#. unsafe software anywhere without authorisation, and non-admins can
#. install safe software in their user or system dirs without
#. authorisation, but need authorisation to install unsafe software
#. anywhere:
#. * Unconditionally return `yes` from `app-install`.
#. * Return `auth_admin` from `override-parental-controls` for users
#. not in `@privileged_group@`, and `yes` for users in it.
#. * Set the malcontent `is-{user,system}-installation-allowed`
#. properties of all non-admins’ parental controls policies to true.
#. - In order to configure the policy so that admins can install safe and
#. unsafe software anywhere without authorisation, and non-admins can
#. install safe software in their user dir without authorisation, but
#. need authorisation to install safe software in the system dir or to
#. install unsafe software anywhere:
#. * Unconditionally return `yes` from `app-install`.
#. * Return `auth_admin` from `override-parental-controls` for users
#. not in `@privileged_group@`, and `yes` for users in it.
#. * Set the malcontent `is-user-installation-allowed` property of all
#. non-admins’ parental controls policies to true.
#. * Set the malcontent `is-system-installation-allowed` property of
#. all non-admins’ parental controls policies to false.
#. - In order to configure the policy so that all users (including
#. admins) can install safe software anywhere without authorisation,
#. but need authorisation to install unsafe software anywhere (i.e.
#. applying parental controls to admins too):
#. * Unconditionally return `yes` from `app-install`.
#. * Unconditionally return `auth_admin` from `override-parental-controls`.
#. * Set the malcontent `is-user-installation-allowed` property of all
#. users’ parental controls policies to true.
#. * Set the malcontent `is-system-installation-allowed` property of
#. all users’ parental controls policies to true.
#: system-helper/org.freedesktop.Flatpak.policy.in:287
msgid "Override parental controls for installs"
msgstr ""

#: system-helper/org.freedesktop.Flatpak.policy.in:288
msgid ""
"Authentication is required to install software which is restricted by your "
"parental controls policy"
msgstr ""

#. SECURITY:
#. - This is like org.freedesktop.Flatpak.override-parental-controls, but
#. it’s queried for app updates, whereas the former is queried for app
#. installs.
#. - As with the above action, this one is only queried if
#. org.freedesktop.Flatpak.app-update has allowed the app update, and
#. only if the app being updated has too extreme content for the user
#. who is trying to update it.
#. - The default policy for this is to *allow* updates to ‘too extreme’
#. apps by default, on the basis that having an out-of-date (i.e.
#. insecure or unsupported) app is a worse outcome than automatically
#. installing an update which has radically different content from the
#. version of the app which the parent originally vetted and installed.
#: system-helper/org.freedesktop.Flatpak.policy.in:313
msgid "Override parental controls for updates"
msgstr ""

#: system-helper/org.freedesktop.Flatpak.policy.in:314
msgid ""
"Authentication is required to update software which is restricted by your "
"parental controls policy"
msgstr ""

===== ./po/hr.po =====
# Croatian translation for flatpak.
# Copyright (C) 2020 flatpak's COPYRIGHT HOLDER
# This file is distributed under the same license as the flatpak package.
# Milo Ivir <mail@milotype.de>, 2020., 2025.
#
msgid ""
msgstr ""
"Project-Id-Version: flatpak master\n"
"Report-Msgid-Bugs-To: https://github.com/flatpak/flatpak/issues\n"
"POT-Creation-Date: 2026-05-27 16:39+0200\n"
"PO-Revision-Date: 2025-11-09 15:59+0100\n"
"Last-Translator: Milo Ivir <mail@mivirtype.de>\n"
"Language-Team: Croatian <hr@li.org>\n"
"Language: hr\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && "
"n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
"X-Generator: Poedit 3.8\n"

#: app/flatpak-builtins-build-bundle.c:59
msgid "Export runtime instead of app"
msgstr "Izvezi okruženje umjesto programa"

#: app/flatpak-builtins-build-bundle.c:60
msgid "Arch to bundle for"
msgstr "Arhitektura za paketiranje za"

#: app/flatpak-builtins-build-bundle.c:60
#: app/flatpak-builtins-build-export.c:62 app/flatpak-builtins-build-init.c:53
#: app/flatpak-builtins-build-sign.c:42 app/flatpak-builtins-create-usb.c:46
#: app/flatpak-builtins-info.c:55 app/flatpak-builtins-install.c:67
#: app/flatpak-builtins-list.c:50 app/flatpak-builtins-make-current.c:38
#: app/flatpak-builtins-remote-info.c:54 app/flatpak-builtins-remote-ls.c:56
#: app/flatpak-builtins-run.c:158 app/flatpak-builtins-search.c:37
#: app/flatpak-builtins-uninstall.c:54 app/flatpak-builtins-update.c:56
msgid "ARCH"
msgstr "ARHITEKTURA"

#: app/flatpak-builtins-build-bundle.c:61
#, fuzzy
msgid "URL for repo"
msgstr "Url za repozitorij"

#: app/flatpak-builtins-build-bundle.c:61
#: app/flatpak-builtins-build-bundle.c:62
#: app/flatpak-builtins-build-update-repo.c:68
#: app/flatpak-builtins-build-update-repo.c:72
#: app/flatpak-builtins-build-update-repo.c:73
#: app/flatpak-builtins-history.c:69 app/flatpak-builtins-remote-add.c:80
#: app/flatpak-builtins-remote-add.c:81 app/flatpak-builtins-remote-add.c:85
#: app/flatpak-builtins-remote-list.c:53
#: app/flatpak-builtins-remote-modify.c:70
#: app/flatpak-builtins-remote-modify.c:85
#: app/flatpak-builtins-remote-modify.c:86
#: app/flatpak-builtins-remote-modify.c:90
msgid "URL"
msgstr "URL"

#: app/flatpak-builtins-build-bundle.c:62
#, fuzzy
msgid "URL for runtime flatpakrepo file"
msgstr "Url za okruženje datoteke flatpak repozitorija"

#: app/flatpak-builtins-build-bundle.c:63
msgid "Add GPG key from FILE (- for stdin)"
msgstr "Dodaj GPG ključ iz DATOTEKE (- za stdin)"

#: app/flatpak-builtins-build-bundle.c:63 app/flatpak-builtins-build.c:54
#: app/flatpak-builtins-build-export.c:67
#: app/flatpak-builtins-build-update-repo.c:83
#: app/flatpak-builtins-install.c:81 app/flatpak-builtins-remote-add.c:84
#: app/flatpak-builtins-remote-add.c:86 app/flatpak-builtins-remote-modify.c:89
#: app/flatpak-builtins-remote-modify.c:92
msgid "FILE"
msgstr "DATOTEKA"

#: app/flatpak-builtins-build-bundle.c:64
msgid "GPG Key ID to sign the OCI image with"
msgstr "ID GPG ključa za potpisivanje OCI slike"

#: app/flatpak-builtins-build-bundle.c:64
#: app/flatpak-builtins-build-commit-from.c:68
#: app/flatpak-builtins-build-export.c:68
#: app/flatpak-builtins-build-import-bundle.c:49
#: app/flatpak-builtins-build-sign.c:44
#: app/flatpak-builtins-build-update-repo.c:84
msgid "KEY-ID"
msgstr "KLJUČ-ID"

#: app/flatpak-builtins-build-bundle.c:65
#: app/flatpak-builtins-build-commit-from.c:69
#: app/flatpak-builtins-build-export.c:71
#: app/flatpak-builtins-build-import-bundle.c:50
#: app/flatpak-builtins-build-sign.c:45
#: app/flatpak-builtins-build-update-repo.c:85
msgid "GPG Homedir to use when looking for keyrings"
msgstr "Početni direktorij GPG-a kad se traže privjesci za ključeve"

#: app/flatpak-builtins-build-bundle.c:65
#: app/flatpak-builtins-build-commit-from.c:69
#: app/flatpak-builtins-build-export.c:71
#: app/flatpak-builtins-build-import-bundle.c:50
#: app/flatpak-builtins-build-sign.c:45
#: app/flatpak-builtins-build-update-repo.c:85
msgid "HOMEDIR"
msgstr "POČETNI-DIREKTORIJ"

#: app/flatpak-builtins-build-bundle.c:66
msgid "OSTree commit to create a delta bundle from"
msgstr "OSTree izmjena za stvaranje paketa delta datoteka"

#: app/flatpak-builtins-build-bundle.c:66 app/flatpak-builtins-remote-info.c:55
#: app/flatpak-builtins-update.c:57
msgid "COMMIT"
msgstr "IZMJENA"

#: app/flatpak-builtins-build-bundle.c:67
msgid "Export oci image instead of flatpak bundle"
msgstr "Izvezi oci sliku umjesto flatpak paket"

#: app/flatpak-builtins-build-bundle.c:70
msgid "How to compress OCI image layers (default: gzip)"
msgstr ""

#: app/flatpak-builtins-build-bundle.c:634
msgid ""
"LOCATION FILENAME NAME [BRANCH] - Create a single file bundle from a local "
"repository"
msgstr ""
"LOKACIJA IME-DATOTEKE IME [GRANA] – Stvori jedan paket datoteka iz lokalnog "
"repozitorija"

#: app/flatpak-builtins-build-bundle.c:641
msgid "LOCATION, FILENAME and NAME must be specified"
msgstr "LOKACIJA, IME_DATOTEKE i IME se moraju odrediti"

#: app/flatpak-builtins-build-bundle.c:644
#: app/flatpak-builtins-build-export.c:844
#: app/flatpak-builtins-build-import-bundle.c:136
#: app/flatpak-builtins-build-init.c:217 app/flatpak-builtins-build-sign.c:76
#: app/flatpak-builtins-document-export.c:112
#: app/flatpak-builtins-document-info.c:75
#: app/flatpak-builtins-document-list.c:191
#: app/flatpak-builtins-document-unexport.c:70
#: app/flatpak-builtins-history.c:482 app/flatpak-builtins-info.c:130
#: app/flatpak-builtins-install.c:181 app/flatpak-builtins-install.c:234
#: app/flatpak-builtins-install.c:298 app/flatpak-builtins-list.c:419
#: app/flatpak-builtins-make-current.c:72 app/flatpak-builtins-override.c:73
#: app/flatpak-builtins-permission-list.c:162
#: app/flatpak-builtins-permission-remove.c:132
#: app/flatpak-builtins-remote-add.c:323
#: app/flatpak-builtins-remote-delete.c:68
#: app/flatpak-builtins-remote-list.c:241 app/flatpak-builtins-remote-ls.c:407
msgid "Too many arguments"
msgstr "Previše argumenata"

#: app/flatpak-builtins-build-bundle.c:659
#: app/flatpak-builtins-build-commit-from.c:338
#: app/flatpak-builtins-build-commit-from.c:351
#: app/flatpak-builtins-build-import-bundle.c:145
#, c-format
msgid "'%s' is not a valid repository"
msgstr "„%s” nije ispravan repozitorij"

#: app/flatpak-builtins-build-bundle.c:663
#, c-format
msgid "'%s' is not a valid repository: "
msgstr "„%s” nije ispravan repozitorij: "

#: app/flatpak-builtins-build-bundle.c:674 app/flatpak-builtins-build-sign.c:88
#: common/flatpak-dir.c:14293
#, c-format
msgid "'%s' is not a valid name: %s"
msgstr "„%s” nije ispravno ime: %s"

#: app/flatpak-builtins-build-bundle.c:677
#: app/flatpak-builtins-build-export.c:865 app/flatpak-builtins-build-sign.c:91
#: common/flatpak-dir.c:14299
#, c-format
msgid "'%s' is not a valid branch name: %s"
msgstr "„%s” nije ispravno ime grane: %s"

#: app/flatpak-builtins-build-bundle.c:691
#: app/flatpak-builtins-build-import-bundle.c:149
#: app/flatpak-builtins-build-init.c:281
#, c-format
msgid "'%s' is not a valid filename"
msgstr "„%s” nije ispravno ime datoteke"

#: app/flatpak-builtins-build-bundle.c:706
msgid "--oci-layer-compress value must be gzip or zstd"
msgstr ""

#: app/flatpak-builtins-build.c:49
msgid "Use Platform runtime rather than Sdk"
msgstr "Koristi okruženje za platformu umjesto sdk"

#: app/flatpak-builtins-build.c:50
msgid "Make destination readonly"
msgstr "Postavi odredište na samo-za-čitanje"

#: app/flatpak-builtins-build.c:51
msgid "Add bind mount"
msgstr "Dodaj bind mount"

#: app/flatpak-builtins-build.c:51
msgid "DEST=SRC"
msgstr "ODREDIŠTE=IZVOR"

#: app/flatpak-builtins-build.c:52
msgid "Start build in this directory"
msgstr "Počni gradnju u ovom direktoriju"

#: app/flatpak-builtins-build.c:52 app/flatpak-builtins-build.c:53
#: app/flatpak-builtins-build-init.c:64 app/flatpak-builtins-run.c:160
msgid "DIR"
msgstr "DIR"

#: app/flatpak-builtins-build.c:53
msgid "Where to look for custom sdk dir (defaults to 'usr')"
msgstr "Gdje tražiti prilagođeni sdk direktorij (standardno je „usr”)"

#: app/flatpak-builtins-build.c:54 app/flatpak-builtins-build-export.c:67
msgid "Use alternative file for the metadata"
msgstr "Koristi alternativne datoteka za metapodatke"

#: app/flatpak-builtins-build.c:55 app/flatpak-builtins-run.c:177
msgid "Kill processes when the parent process dies"
msgstr "Ubij procese kad nadređeni proces umre"

#: app/flatpak-builtins-build.c:56
msgid "Export application homedir directory to build"
msgstr "Izvezi početni direktorij aplikacije u direktorij gradnje"

#: app/flatpak-builtins-build.c:57 app/flatpak-builtins-run.c:165
msgid "Log session bus calls"
msgstr "Zapiši bus pozive sesije"

#: app/flatpak-builtins-build.c:58 app/flatpak-builtins-run.c:166
msgid "Log system bus calls"
msgstr "Zapiši bus pozive sustava"

#: app/flatpak-builtins-build.c:262
msgid "DIRECTORY [COMMAND [ARGUMENT…]] - Build in directory"
msgstr "DIREKTORIJ [NAREDBA [ARGUMENT …]] – Gradi u direktoriju"

#: app/flatpak-builtins-build.c:285 app/flatpak-builtins-build-finish.c:656
msgid "DIRECTORY must be specified"
msgstr "DIREKTORIJ se mora odrediti"

#: app/flatpak-builtins-build.c:296 app/flatpak-builtins-build-export.c:887
#, c-format
msgid "Build directory %s not initialized, use flatpak build-init"
msgstr "Direktorij gradnje %s nije inicijaliziran, koristi flatpak build-init"

#: app/flatpak-builtins-build.c:315
msgid "metadata invalid, not application or runtime"
msgstr "metapodaci neispravni, nije program ili okruženje"

#: app/flatpak-builtins-build.c:446
#, c-format
msgid "No extension point matching %s in %s"
msgstr "Nijedna točka proširenja se ne poklapa s %s u %s"

#: app/flatpak-builtins-build.c:635
#, c-format
msgid "Missing '=' in bind mount option '%s'"
msgstr "U bind mount opciji „%s” nedostaje znak „=”"

#: app/flatpak-builtins-build.c:679 common/flatpak-run.c:3961
#, c-format
msgid "Unable to start app"
msgstr "Nije moguće pokrenuti program"

#: app/flatpak-builtins-build-commit-from.c:58
msgid "Source repo dir"
msgstr "Direktorij repozitorija izvora"

#: app/flatpak-builtins-build-commit-from.c:58
msgid "SRC-REPO"
msgstr "IZVOR-REPOZITORIJ"

#: app/flatpak-builtins-build-commit-from.c:59
msgid "Source repo ref"
msgstr "Referenca repozitorija izvora"

#: app/flatpak-builtins-build-commit-from.c:59
msgid "SRC-REF"
msgstr "IZVOR-REFERENCA"

#: app/flatpak-builtins-build-commit-from.c:64
#: app/flatpak-builtins-build-export.c:60
msgid "One line subject"
msgstr "Kratki opis predmeta"

#: app/flatpak-builtins-build-commit-from.c:64
#: app/flatpak-builtins-build-export.c:60
msgid "SUBJECT"
msgstr "PREDMET"

#: app/flatpak-builtins-build-commit-from.c:65
#: app/flatpak-builtins-build-export.c:61
msgid "Full description"
msgstr "Potpuni opis"

#: app/flatpak-builtins-build-commit-from.c:65
#: app/flatpak-builtins-build-export.c:61
msgid "BODY"
msgstr "TIJELO"

#: app/flatpak-builtins-build-commit-from.c:66
#: app/flatpak-builtins-build-export.c:64
#: app/flatpak-builtins-build-import-bundle.c:51
msgid "Update the appstream branch"
msgstr "Aktualiziraj appstream granu"

#: app/flatpak-builtins-build-commit-from.c:67
#: app/flatpak-builtins-build-export.c:65
#: app/flatpak-builtins-build-import-bundle.c:52
#: app/flatpak-builtins-build-update-repo.c:87
msgid "Don't update the summary"
msgstr "Ne aktualiziraj sažetak"

#: app/flatpak-builtins-build-commit-from.c:68
#: app/flatpak-builtins-build-export.c:68
#: app/flatpak-builtins-build-import-bundle.c:49
#: app/flatpak-builtins-build-sign.c:44
msgid "GPG Key ID to sign the commit with"
msgstr "ID GPG ključa za potpisivanje izmjene"

#: app/flatpak-builtins-build-commit-from.c:70
#: app/flatpak-builtins-build-export.c:73
msgid "Mark build as end-of-life"
msgstr "Označi gradnju kao kraj-života"

#: app/flatpak-builtins-build-commit-from.c:70
#: app/flatpak-builtins-build-export.c:73
msgid "REASON"
msgstr "RAZLOG"

#: app/flatpak-builtins-build-commit-from.c:71
msgid ""
"Mark refs matching the OLDID prefix as end-of-life, to be replaced with the "
"given NEWID"
msgstr ""
"Označi reference koje se poklapaju sa STARI-ID prefiksom kao kraj-života, "
"zamijenit će se s datom NOVI-ID oznakom"

#: app/flatpak-builtins-build-commit-from.c:71
msgid "OLDID=NEWID"
msgstr "STARI-ID=NOVI-ID"

#: app/flatpak-builtins-build-commit-from.c:72
#: app/flatpak-builtins-build-export.c:75
msgid "Set type of token needed to install this commit"
msgstr "Postavi vrstu tokena koja je potrebna za instaliranje ove izmjene"

#: app/flatpak-builtins-build-commit-from.c:72
#: app/flatpak-builtins-build-export.c:75
msgid "VAL"
msgstr "VRIJEDNOST"

#: app/flatpak-builtins-build-commit-from.c:73
msgid "Override the timestamp of the commit (NOW for current time)"
msgstr "Nadjačaj vremensku oznaku izmjene (NOW za trenutačno vrijeme)"

#: app/flatpak-builtins-build-commit-from.c:73
#: app/flatpak-builtins-build-export.c:76
msgid "TIMESTAMP"
msgstr "VREMENSKA_OZNAKA"

#: app/flatpak-builtins-build-commit-from.c:75
#: app/flatpak-builtins-build-export.c:80
#: app/flatpak-builtins-build-import-bundle.c:53
#: app/flatpak-builtins-build-update-repo.c:97
msgid "Don't generate a summary index"
msgstr "Nemoj generirati indeks sažetka"

#: app/flatpak-builtins-build-commit-from.c:278
msgid "DST-REPO [DST-REF…] - Make a new commit from existing commits"
msgstr ""
"DISTRIBUCIJA-REPOZITORIJ [DISTRIBUCIJA-REPOZITORIJ …] – Izradi novu izmjenu "
"iz postojeće izmjene"

#: app/flatpak-builtins-build-commit-from.c:285
msgid "DST-REPO must be specified"
msgstr "DISTRIBUCIJA-REPOZITORIJ se mora odrediti"

#: app/flatpak-builtins-build-commit-from.c:293
msgid ""
"If --src-repo is not specified, exactly one destination ref must be specified"
msgstr ""
"Ako je --src-ref nije određeno, mora se odrediti samo jedna referenca "
"odredišta"

#: app/flatpak-builtins-build-commit-from.c:296
msgid ""
"If --src-ref is specified, exactly one destination ref must be specified"
msgstr ""
"Ako je --src-ref određeno, mora se odrediti samo jedna referenca odredišta"

#: app/flatpak-builtins-build-commit-from.c:299
msgid "Either --src-repo or --src-ref must be specified"
msgstr "--src-repo ili --src-ref se moraju odrediti"

#: app/flatpak-builtins-build-commit-from.c:315
msgid "Invalid argument format of use  --end-of-life-rebase=OLDID=NEWID"
msgstr ""
"Neispravni format argument upotrebe  --end-of-life-rebase=STARI-ID=NOVI-ID"

#: app/flatpak-builtins-build-commit-from.c:321
#: app/flatpak-builtins-build-commit-from.c:324
#, c-format
msgid "Invalid name %s in --end-of-life-rebase"
msgstr "Neispravno ime %s u --end-of-life-rebase"

#: app/flatpak-builtins-build-commit-from.c:333
#: app/flatpak-builtins-build-export.c:1092
#, c-format
msgid "Could not parse '%s'"
msgstr "Nije bilo moguće obraditi „%s”"

#: app/flatpak-builtins-build-commit-from.c:498
msgid "Can't commit from partial source commit"
msgstr "Nije moguće izmijeniti iz djelomične izmjene izvora"

#: app/flatpak-builtins-build-commit-from.c:503
#, c-format
msgid "%s: no change\n"
msgstr "%s: bez promjene\n"

#: app/flatpak-builtins-build-export.c:62
msgid "Architecture to export for (must be host compatible)"
msgstr "Izvozna arhitektura za (mora bit kompatibilna s računalom)"

#: app/flatpak-builtins-build-export.c:63
msgid "Commit runtime (/usr), not /app"
msgstr "Izmijeni okruženje (/usr), ne /app"

#: app/flatpak-builtins-build-export.c:66
msgid "Use alternative directory for the files"
msgstr "Koristi alternativni direktorij za datoteke"

#: app/flatpak-builtins-build-export.c:66
msgid "SUBDIR"
msgstr "PODDIREKTORIJ"

#: app/flatpak-builtins-build-export.c:69
msgid "Files to exclude"
msgstr "Datoteke koje treba izuzeti"

#: app/flatpak-builtins-build-export.c:69
#: app/flatpak-builtins-build-export.c:70
#: app/flatpak-builtins-build-update-repo.c:90
msgid "PATTERN"
msgstr "UZORAK"

#: app/flatpak-builtins-build-export.c:70
msgid "Excluded files to include"
msgstr "Izuzete su datoteke koje treba uključiti"

#: app/flatpak-builtins-build-export.c:74
msgid "Mark build as end-of-life, to be replaced with the given ID"
msgstr "Označi gradnju kao kraj-života, zamijenit će se s zadatom ID oznakom"

#: app/flatpak-builtins-build-export.c:74
#: app/flatpak-builtins-document-list.c:49 app/flatpak-cli-transaction.c:1427
msgid "ID"
msgstr "ID"

#: app/flatpak-builtins-build-export.c:76
msgid "Override the timestamp of the commit"
msgstr "Nadjačaj vremensku oznaku izmjene"

#: app/flatpak-builtins-build-export.c:77
#: app/flatpak-builtins-build-update-repo.c:75
#: app/flatpak-builtins-remote-add.c:83 app/flatpak-builtins-remote-list.c:54
#: app/flatpak-builtins-remote-modify.c:88
msgid "Collection ID"
msgstr "ID zbirke"

#: app/flatpak-builtins-build-export.c:472
#, c-format
msgid "WARNING: Error running desktop-file-validate: %s\n"
msgstr "UPOZORENJE: Greška pri pokretanju desktop-file-validate: %s\n"

#: app/flatpak-builtins-build-export.c:480
#, c-format
msgid "WARNING: Error reading from desktop-file-validate: %s\n"
msgstr "UPOZORENJE: Greška pri čitanju desktop-file-validate: %s\n"

#: app/flatpak-builtins-build-export.c:486
#, c-format
msgid "WARNING: Failed to validate desktop file %s: %s\n"
msgstr "UPOZORENJE: Greška u provjeravanju datoteke radne površine %s: %s\n"

#: app/flatpak-builtins-build-export.c:513
#, c-format
msgid "WARNING: Can't find Exec key in %s: %s\n"
msgstr "UPOZORENJE: Nije moguće pronaći Exec ključ u %s: %s\n"

#: app/flatpak-builtins-build-export.c:521
#: app/flatpak-builtins-build-export.c:614
#, c-format
msgid "WARNING: Binary not found for Exec line in %s: %s\n"
msgstr "UPOZORENJE: Binarna dataoteka nije pronađena za Exec redak u %s: %s\n"

#: app/flatpak-builtins-build-export.c:529
#, c-format
msgid "WARNING: Icon not matching app id in %s: %s\n"
msgstr "UPOZORENJE: Ikona se ne poklapa s id oznakom programa u %s: %s\n"

#: app/flatpak-builtins-build-export.c:552
#, c-format
msgid "WARNING: Icon referenced in desktop file but not exported: %s\n"
msgstr ""
"UPOZORENJE: Ikona je referencirana u datoteci radne površine, ali nije "
"izvezena: %s\n"

#: app/flatpak-builtins-build-export.c:719
#, c-format
msgid "Invalid uri type %s, only http/https supported"
msgstr "Neispravna uri vrsta %s, podržava se samo http/https"

#: app/flatpak-builtins-build-export.c:737
#, c-format
msgid "Unable to find basename in %s, specify a name explicitly"
msgstr "Nije moguće pronaći onsovno ime u %s, odredi ime nedvosmisleno"

#: app/flatpak-builtins-build-export.c:746
#, c-format
msgid "No slashes allowed in extra data name"
msgstr "Kose crte nisu dozvoljene u imenu dodatnih podataka"

#: app/flatpak-builtins-build-export.c:758
#, c-format
msgid "Invalid format for sha256 checksum: '%s'"
msgstr "Neispravni sha256 kontrolni zbroj: „%s”"

#: app/flatpak-builtins-build-export.c:768
#, c-format
msgid "Extra data sizes of zero not supported"
msgstr "Nula veličina dodatnih podataka nije podržano"

#: app/flatpak-builtins-build-export.c:830
msgid ""
"LOCATION DIRECTORY [BRANCH] - Create a repository from a build directory"
msgstr ""
"LOKACIJA DIREKTORIJ [GRANA] – Stvori repozitorij iz direktorija gradnje"

#: app/flatpak-builtins-build-export.c:838
msgid "LOCATION and DIRECTORY must be specified"
msgstr "LOKACIJA i DIREKTORIJ se moraju odrediti"

#: app/flatpak-builtins-build-export.c:859
#: app/flatpak-builtins-remote-add.c:327
#, c-format
msgid "‘%s’ is not a valid collection ID: %s"
msgstr "„%s” nije ispravna ID oznaka zbirke: %s"

#: app/flatpak-builtins-build-export.c:904
#: app/flatpak-builtins-build-finish.c:684
msgid "No name specified in the metadata"
msgstr "Nema određenog imena u metapodacima"

#: app/flatpak-builtins-build-export.c:1166
#, c-format
msgid "Commit: %s\n"
msgstr "Izmjena: %s\n"

#: app/flatpak-builtins-build-export.c:1167
#, c-format
msgid "Metadata Total: %u\n"
msgstr "Metapodataka ukupno: %u\n"

#: app/flatpak-builtins-build-export.c:1168
#, c-format
msgid "Metadata Written: %u\n"
msgstr "Metapodataka zapisano: %u\n"

#: app/flatpak-builtins-build-export.c:1169
#, c-format
msgid "Content Total: %u\n"
msgstr "Sadržaja ukupno: %u\n"

#: app/flatpak-builtins-build-export.c:1170
#, c-format
msgid "Content Written: %u\n"
msgstr "Sadržaja zapisano: %u\n"

#: app/flatpak-builtins-build-export.c:1171
#, c-format
msgid "Content Bytes Written:"
msgstr "Zapisani bajtovi sadržaja:"

#: app/flatpak-builtins-build-finish.c:52
msgid "Command to set"
msgstr "Naredba za postavljanje"

#: app/flatpak-builtins-build-finish.c:52 app/flatpak-builtins-run.c:159
#: app/flatpak-main.c:209
msgid "COMMAND"
msgstr "NAREDBA"

#: app/flatpak-builtins-build-finish.c:53
msgid "Flatpak version to require"
msgstr "Zatraži Flatpak verziju"

#: app/flatpak-builtins-build-finish.c:53
msgid "MAJOR.MINOR.MICRO"
msgstr "MAJOR.MINOR.MICRO"

#: app/flatpak-builtins-build-finish.c:54
msgid "Don't process exports"
msgstr "Nemoj obraditi izvoze"

#: app/flatpak-builtins-build-finish.c:55
msgid "Extra data info"
msgstr "Informacije o dodatnim podacima"

#: app/flatpak-builtins-build-finish.c:56 app/flatpak-builtins-build-init.c:63
msgid "Add extension point info"
msgstr "Dodaj informacije o točki proširenja"

#: app/flatpak-builtins-build-finish.c:56 app/flatpak-builtins-build-init.c:63
msgid "NAME=VARIABLE[=VALUE]"
msgstr "IME=VARIJABLA[=VRIJEDNOST]"

#: app/flatpak-builtins-build-finish.c:57
msgid "Remove extension point info"
msgstr "Ukloni informacije o točki proširenja"

#: app/flatpak-builtins-build-finish.c:57
#: app/flatpak-builtins-build-update-repo.c:79 app/flatpak-builtins-info.c:58
#: app/flatpak-builtins-remote-add.c:88 app/flatpak-builtins-remote-modify.c:94
#: app/flatpak-main.c:182
msgid "NAME"
msgstr "IME"

#: app/flatpak-builtins-build-finish.c:58
msgid "Set extension priority (only for extensions)"
msgstr "Postavi prioritet proširenja (samo za proširenja)"

#: app/flatpak-builtins-build-finish.c:58
msgid "VALUE"
msgstr "VRIJEDNOST"

#: app/flatpak-builtins-build-finish.c:59
msgid "Change the sdk used for the app"
msgstr "Promijeni sdk koji se koristi za program"

#: app/flatpak-builtins-build-finish.c:59
msgid "SDK"
msgstr "SDK"

#: app/flatpak-builtins-build-finish.c:60
msgid "Change the runtime used for the app"
msgstr "Promijeni okruženje koji se koristi za program"

#: app/flatpak-builtins-build-finish.c:60 app/flatpak-builtins-build-init.c:54
#: app/flatpak-builtins-list.c:53 app/flatpak-builtins-remote-ls.c:58
#: app/flatpak-builtins-run.c:163
msgid "RUNTIME"
msgstr "OKRUŽENJE"

#: app/flatpak-builtins-build-finish.c:61
msgid "Set generic metadata option"
msgstr "Postavi opću opciju metapodataka"

#: app/flatpak-builtins-build-finish.c:61
msgid "GROUP=KEY[=VALUE]"
msgstr "GRUPA=KLJUČ[=VRIJEDNOST]"

#: app/flatpak-builtins-build-finish.c:62
msgid "Don't inherit permissions from runtime"
msgstr "Nemoj naslijediti dozvole od okruženja"

#: app/flatpak-builtins-build-finish.c:155
#, c-format
msgid "Not exporting %s, wrong extension\n"
msgstr "%s se ne izvozi, krivo proširenje\n"

#: app/flatpak-builtins-build-finish.c:163
#, c-format
msgid "Not exporting %s, non-allowed export filename\n"
msgstr "%s se ne izvozi, nedozvoljen izvoz imena datoteke\n"

#: app/flatpak-builtins-build-finish.c:167
#, c-format
msgid "Exporting %s\n"
msgstr "Izvoz %s\n"

#: app/flatpak-builtins-build-finish.c:440
#, c-format
msgid "More than one executable found\n"
msgstr "Pronađeno je više od jedne izvršne datoteke\n"

#: app/flatpak-builtins-build-finish.c:451
#, c-format
msgid "Using %s as command\n"
msgstr "Koristi se %s kao naredba\n"

#: app/flatpak-builtins-build-finish.c:456
#, c-format
msgid "No executable found\n"
msgstr "Nema izvršnih datoteka\n"

#: app/flatpak-builtins-build-finish.c:511
#, c-format
msgid "Invalid --require-version argument: %s"
msgstr "Neispravni --require-version argument: %s"

#: app/flatpak-builtins-build-finish.c:543
#, c-format
msgid "Too few elements in --extra-data argument %s"
msgstr "Nedovoljno elemenata u --extra-data argumentu %s"

#: app/flatpak-builtins-build-finish.c:575
#, c-format
msgid ""
"Too few elements in --metadata argument %s, format should be "
"GROUP=KEY[=VALUE]]"
msgstr ""
"Nedovoljno elemenata u --metadata argumentu %s, format mora biti "
"GRUPA=KLJUČ[=VRIJEDNOST]"

#: app/flatpak-builtins-build-finish.c:597
#: app/flatpak-builtins-build-init.c:458
#, c-format
msgid ""
"Too few elements in --extension argument %s, format should be "
"NAME=VAR[=VALUE]"
msgstr ""
"Nedovoljno elemenata u --extension argumentu %s, format mora biti "
"IME=VARIJABLA[=VRIJEDNOST]"

#: app/flatpak-builtins-build-finish.c:603
#: app/flatpak-builtins-build-init.c:461
#, c-format
msgid "Invalid extension name %s"
msgstr "Neispravno ime proširenja %s"

#: app/flatpak-builtins-build-finish.c:646
msgid "DIRECTORY - Finalize a build directory"
msgstr "DIREKTORIJ – Završi direktorij gradnje"

#: app/flatpak-builtins-build-finish.c:668
#, c-format
msgid "Build directory %s not initialized"
msgstr "Direktorij gradnje %s nije inicijaliziran"

#: app/flatpak-builtins-build-finish.c:689
#, c-format
msgid "Build directory %s already finalized"
msgstr "Direktorij gradnje %s već završen"

#: app/flatpak-builtins-build-finish.c:702
#, c-format
msgid "Please review the exported files and the metadata\n"
msgstr "Pregledaj izvezene datoteke i metapodatke\n"

#: app/flatpak-builtins-build-import-bundle.c:47
msgid "Override the ref used for the imported bundle"
msgstr "Nadjačaj referencu koja se koristi za uvezeni paket"

#: app/flatpak-builtins-build-import-bundle.c:47
msgid "REF"
msgstr "REFERENCA"

#: app/flatpak-builtins-build-import-bundle.c:48
msgid "Import oci image instead of flatpak bundle"
msgstr "Uvezi oci sliku umjesto flatpak paket"

#: app/flatpak-builtins-build-import-bundle.c:77
#: app/flatpak-builtins-build-import-bundle.c:105
#, c-format
msgid "Importing %s (%s)\n"
msgstr "Uvozo se %s (%s)\n"

#: app/flatpak-builtins-build-import-bundle.c:126
msgid "LOCATION FILENAME - Import a file bundle into a local repository"
msgstr "LOKACIJA IME-DATOTEKE – Uvezi paket datoteka u lokalni repozitorij"

#: app/flatpak-builtins-build-import-bundle.c:133
msgid "LOCATION and FILENAME must be specified"
msgstr "LOKACIJA i IME_DATOTEKE se moraju odrediti"

#: app/flatpak-builtins-build-init.c:53 app/flatpak-builtins-info.c:55
#: app/flatpak-builtins-run.c:158
msgid "Arch to use"
msgstr "Korištena arhitektura"

#: app/flatpak-builtins-build-init.c:54
msgid "Initialize var from named runtime"
msgstr "Inicijaliziraj var iz imenovanog okruženja"

#: app/flatpak-builtins-build-init.c:55
msgid "Initialize apps from named app"
msgstr "Inicijaliziraj programe iz imenovanog programa"

#: app/flatpak-builtins-build-init.c:55
msgid "APP"
msgstr "PROGRAM"

#: app/flatpak-builtins-build-init.c:56
msgid "Specify version for --base"
msgstr "Odredi verziju za --base"

#: app/flatpak-builtins-build-init.c:56 app/flatpak-builtins-run.c:164
msgid "VERSION"
msgstr "VERZIJA"

#: app/flatpak-builtins-build-init.c:57
msgid "Include this base extension"
msgstr "Uključi ovo osnovno proširenje"

#: app/flatpak-builtins-build-init.c:57 app/flatpak-builtins-build-init.c:62
msgid "EXTENSION"
msgstr "PROŠIRENJE"

#: app/flatpak-builtins-build-init.c:58
msgid "Extension tag to use if building extension"
msgstr "Korištena oznaka proširenja, ako se gradi proširenje"

#: app/flatpak-builtins-build-init.c:58
msgid "EXTENSION_TAG"
msgstr "PROŠIRENJE_OZNAKA"

#: app/flatpak-builtins-build-init.c:59
msgid "Initialize /usr with a writable copy of the sdk"
msgstr "Inicijaliziraj /usr s prepisivom sdk kopijom"

#: app/flatpak-builtins-build-init.c:60
msgid "Specify the build type (app, runtime, extension)"
msgstr "Odredi vrstu gradnje (program, okruženje, proširenje)"

#: app/flatpak-builtins-build-init.c:60
msgid "TYPE"
msgstr "VRSTA"

#: app/flatpak-builtins-build-init.c:61
msgid "Add a tag"
msgstr "Dodaj oznaku"

#: app/flatpak-builtins-build-init.c:61
msgid "TAG"
msgstr "OZNAKA"

#: app/flatpak-builtins-build-init.c:62
msgid "Include this sdk extension in /usr"
msgstr "Uključi ovo sdk proširenje u /usr"

#: app/flatpak-builtins-build-init.c:64
msgid "Where to store sdk (defaults to 'usr')"
msgstr "Gdje spremiti sdk (standardno je „usr”)"

#: app/flatpak-builtins-build-init.c:65
msgid "Re-initialize the sdk/var"
msgstr "Ponovo inicijaliziraj sdk/var"

#: app/flatpak-builtins-build-init.c:118
#, c-format
msgid "Requested extension %s/%s/%s is only partially installed"
msgstr "Zatraženo proširenje %s/%s/%s je samo djelomično instalirano"

#: app/flatpak-builtins-build-init.c:147
#, c-format
msgid "Requested extension %s/%s/%s not installed"
msgstr "Zatraženo proširenje %s/%s/%s nije instalirano"

#: app/flatpak-builtins-build-init.c:207
msgid ""
"DIRECTORY APPNAME SDK RUNTIME [BRANCH] - Initialize a directory for building"
msgstr ""
"DIREKTORIJ IME-PROGRAMA SDK RUNTIME [GRANA] – Inicijaliziraj direktorij za "
"izgradnju"

#: app/flatpak-builtins-build-init.c:214
msgid "RUNTIME must be specified"
msgstr "OKRUŽENJE se mora odrediti"

#: app/flatpak-builtins-build-init.c:235
#, c-format
msgid "'%s' is not a valid build type name, use app, runtime or extension"
msgstr ""
"„%s” nije ispravno ime za vrstu gradnje, koristi program, okruženje ili "
"proširenje"

#: app/flatpak-builtins-build-init.c:241 app/flatpak-builtins-override.c:79
#, c-format
msgid "'%s' is not a valid application name: %s"
msgstr "„%s” nije ispravno ime programa: %s"

#: app/flatpak-builtins-build-init.c:295
#, c-format
msgid "Build directory %s already initialized"
msgstr "Direktorij gradnje %s već inicijaliziran"

#: app/flatpak-builtins-build-sign.c:42 app/flatpak-builtins-install.c:67
#: app/flatpak-builtins-remote-info.c:54
msgid "Arch to install for"
msgstr "Arhitektura za instaliranje za"

#: app/flatpak-builtins-build-sign.c:43 app/flatpak-builtins-create-usb.c:48
#: app/flatpak-builtins-install.c:74 app/flatpak-builtins-remote-info.c:56
#: app/flatpak-builtins-uninstall.c:58 app/flatpak-builtins-update.c:64
msgid "Look for runtime with the specified name"
msgstr "Pazi na okruženja s određenim imenom"

#: app/flatpak-builtins-build-sign.c:66
msgid "LOCATION [ID [BRANCH]] - Sign an application or runtime"
msgstr "LOKACIJA [ID [GRANA]] – Potpiši program ili okruženje"

#: app/flatpak-builtins-build-sign.c:73
#: app/flatpak-builtins-build-update-repo.c:499
#: app/flatpak-builtins-remote-add.c:320 app/flatpak-builtins-repo.c:739
msgid "LOCATION must be specified"
msgstr "LOKACIJA se mora odrediti"

#: app/flatpak-builtins-build-sign.c:94
msgid "No gpg key ids specified"
msgstr "Nema određenih ID oznaka gpg ključeva"

#: app/flatpak-builtins-build-update-repo.c:68
msgid "Redirect this repo to a new URL"
msgstr "Preusmjeri ovaj repozitorij na novi URL"

#: app/flatpak-builtins-build-update-repo.c:69
msgid "A nice name to use for this repository"
msgstr "Korišteno lijepo ime za ovaj repozitorij"

#: app/flatpak-builtins-build-update-repo.c:69
#: app/flatpak-builtins-remote-add.c:77 app/flatpak-builtins-remote-modify.c:82
msgid "TITLE"
msgstr "NASLOV"

#: app/flatpak-builtins-build-update-repo.c:70
msgid "A one-line comment for this repository"
msgstr "Kratki komentar za ovaj repozitorij"

#: app/flatpak-builtins-build-update-repo.c:70
#: app/flatpak-builtins-remote-add.c:78 app/flatpak-builtins-remote-modify.c:83
msgid "COMMENT"
msgstr "KOMENTAR"

#: app/flatpak-builtins-build-update-repo.c:71
msgid "A full-paragraph description for this repository"
msgstr "Komentar u obliku odlomka za ovaj repozitorij"

#: app/flatpak-builtins-build-update-repo.c:71
#: app/flatpak-builtins-remote-add.c:79 app/flatpak-builtins-remote-modify.c:84
msgid "DESCRIPTION"
msgstr "OPIS"

#: app/flatpak-builtins-build-update-repo.c:72
msgid "URL for a website for this repository"
msgstr "URL za web-stranicu za ovaj repozitorij"

#: app/flatpak-builtins-build-update-repo.c:73
msgid "URL for an icon for this repository"
msgstr "URL za ikonu za ovaj repozitorij"

#: app/flatpak-builtins-build-update-repo.c:74
msgid "Default branch to use for this repository"
msgstr "Korištena standardna grana za ovaj repozitorij"

#: app/flatpak-builtins-build-update-repo.c:74
#: app/flatpak-builtins-remote-add.c:82 app/flatpak-builtins-remote-modify.c:87
#: app/flatpak-builtins-repo.c:713 app/flatpak-builtins-repo.c:714
#: app/flatpak-builtins-run.c:161
msgid "BRANCH"
msgstr "GRANA"

#: app/flatpak-builtins-build-update-repo.c:75
#: app/flatpak-builtins-remote-add.c:83 app/flatpak-builtins-remote-modify.c:88
msgid "COLLECTION-ID"
msgstr "ZBIRKA-ID"

#. Translators: A sideload is when you install from a local USB drive rather than the Internet.
#: app/flatpak-builtins-build-update-repo.c:77
msgid ""
"Permanently deploy collection ID to client remote configurations, only for "
"sideload support"
msgstr ""
"Trajno implementiraj ID zbirke u konfiguracije klijenta udaljenog "
"repozitorija, samo za podršku lokalnog preuzimanja"

#: app/flatpak-builtins-build-update-repo.c:78
msgid "Permanently deploy collection ID to client remote configurations"
msgstr ""
"Trajno implementiraj ID zbirke u konfiguracije klijenta udaljenog "
"repozitorija"

#: app/flatpak-builtins-build-update-repo.c:79
msgid "Name of authenticator for this repository"
msgstr "Ime autentifikatora za ovaj repozitorij"

#: app/flatpak-builtins-build-update-repo.c:80
msgid "Autoinstall authenticator for this repository"
msgstr "Automatski instaliraj autentifikatora za ovaj repozitorij"

#: app/flatpak-builtins-build-update-repo.c:81
msgid "Don't autoinstall authenticator for this repository"
msgstr "Nemoj automatski instalirati autentifikatora za ovaj repozitorij"

#: app/flatpak-builtins-build-update-repo.c:82
#: app/flatpak-builtins-remote-add.c:89
msgid "Authenticator option"
msgstr "Opcija autentifikatora"

#: app/flatpak-builtins-build-update-repo.c:82
#: app/flatpak-builtins-remote-add.c:89 app/flatpak-builtins-remote-modify.c:95
msgid "KEY=VALUE"
msgstr "KLJUČ=VRIJEDNOST"

#: app/flatpak-builtins-build-update-repo.c:83
msgid "Import new default GPG public key from FILE"
msgstr "Uvezi novi standardan javni GPG ključ iz DATOTEKA"

#: app/flatpak-builtins-build-update-repo.c:84
msgid "GPG Key ID to sign the summary with"
msgstr "ID GPG ključa za potpisivanje sažetka"

#: app/flatpak-builtins-build-update-repo.c:86
msgid "Generate delta files"
msgstr "Izradi delta datoteke"

#: app/flatpak-builtins-build-update-repo.c:88
msgid "Don't update the appstream branch"
msgstr "Nemoj aktualizirati granu podataka programa"

#: app/flatpak-builtins-build-update-repo.c:89
msgid "Max parallel jobs when creating deltas (default: NUMCPUs)"
msgstr ""
"Maksimalni broj paralelnih poslova prilikom stvaranja delta datoteka "
"(standardno: NUMCPU)"

#: app/flatpak-builtins-build-update-repo.c:89
msgid "NUM-JOBS"
msgstr "BROJ-POSLOVA"

#: app/flatpak-builtins-build-update-repo.c:90
msgid "Don't create deltas matching refs"
msgstr "Nemoj stvoriti delta datoteke koje se poklapaju s refencama"

#: app/flatpak-builtins-build-update-repo.c:91
msgid "Prune unused objects"
msgstr "Odreži neiskorištene predmete"

#: app/flatpak-builtins-build-update-repo.c:92
msgid "Prune but don't actually remove anything"
msgstr ""

#: app/flatpak-builtins-build-update-repo.c:93
msgid "Only traverse DEPTH parents for each commit (default: -1=infinite)"
msgstr ""
"Zaobiđi samo DUBINA nadređenih za svaku izmjenu (standardno: -1 = beskonačno)"

#: app/flatpak-builtins-build-update-repo.c:93
msgid "DEPTH"
msgstr "DUBINA"

#: app/flatpak-builtins-build-update-repo.c:223
#, c-format
msgid "Generating delta: %s (%.10s)\n"
msgstr "Izrada delta datoteke: %s (%.10s)\n"

#: app/flatpak-builtins-build-update-repo.c:225
#, c-format
msgid "Generating delta: %s (%.10s-%.10s)\n"
msgstr "Izrada delta datoteke: %s (%.10s – %.10s)\n"

#: app/flatpak-builtins-build-update-repo.c:233
#, c-format
msgid "Failed to generate delta %s (%.10s): "
msgstr "Neuspjela izrada delta datoteke %s (%.10s): "

#: app/flatpak-builtins-build-update-repo.c:236
#, c-format
msgid "Failed to generate delta %s (%.10s-%.10s): "
msgstr "Neuspjela izrada delta datoteke %s (%.10s – %.10s): "

#: app/flatpak-builtins-build-update-repo.c:492
msgid "LOCATION - Update repository metadata"
msgstr "LOKACIJA – Aktualiziraj metapodatke repozitorija"

#: app/flatpak-builtins-build-update-repo.c:609
#, c-format
msgid "Updating appstream branch\n"
msgstr "Aktualiziranje appstream grane\n"

#: app/flatpak-builtins-build-update-repo.c:638
#, c-format
msgid "Updating summary\n"
msgstr "Aktualiziranje sažetka\n"

#: app/flatpak-builtins-build-update-repo.c:664
#, c-format
msgid "Total objects: %u\n"
msgstr "Ukupno objekata: %u\n"

#: app/flatpak-builtins-build-update-repo.c:666
#, c-format
msgid "No unreachable objects\n"
msgstr "Nema objekata koji nisu \n"

#: app/flatpak-builtins-build-update-repo.c:668
#, c-format
msgid "Deleted %u objects, %s freed\n"
msgstr "Ukloniti %u objekte, %s oslobođeno\n"

#: app/flatpak-builtins-config.c:41
msgid "List configuration keys and values"
msgstr "Izradi popis konfiguracijskih ključeva i vrijednosti"

#: app/flatpak-builtins-config.c:42
msgid "Get configuration for KEY"
msgstr "Dobavi kofiguraciju za KLJUČ"

#: app/flatpak-builtins-config.c:43
msgid "Set configuration for KEY to VALUE"
msgstr "Postavi kofiguraciju za KLJUČ i VRIJEDNOST"

#: app/flatpak-builtins-config.c:44
msgid "Unset configuration for KEY"
msgstr "Poništi kofiguraciju za KLJUČ"

#: app/flatpak-builtins-config.c:149
#, c-format
msgid "'%s' does not look like a language/locale code"
msgstr "„%s” ne sliči kodu za jezik/lokalizaciju"

#: app/flatpak-builtins-config.c:172
#, c-format
msgid "'%s' does not look like a language code"
msgstr "„%s” ne sliči kodu za jezik"

#: app/flatpak-builtins-config.c:190
#, fuzzy, c-format
msgid "'%s' is not a valid value (use 'true' or 'false')"
msgstr "„%s” nije ispravan repozitorij: "

#: app/flatpak-builtins-config.c:262
#, c-format
msgid "Unknown configure key '%s'"
msgstr "Nepoznati ključ konfiguracije „%s”"

#: app/flatpak-builtins-config.c:284
msgid "Too many arguments for --list"
msgstr "Previše argumenata za --list"

#: app/flatpak-builtins-config.c:314 app/flatpak-builtins-config.c:362
msgid "You must specify KEY"
msgstr "Moraš odrediti KLJUČ"

#: app/flatpak-builtins-config.c:316
msgid "Too many arguments for --get"
msgstr "Previše argumenata za --get"

#: app/flatpak-builtins-config.c:338
msgid "You must specify KEY and VALUE"
msgstr "Moraš odrediti KLJUČ ili VRIJEDNOST"

#: app/flatpak-builtins-config.c:340
msgid "Too many arguments for --set"
msgstr "Previše argumenata za --set"

#: app/flatpak-builtins-config.c:364
msgid "Too many arguments for --unset"
msgstr "Previše argumenata za --unset"

#: app/flatpak-builtins-config.c:383
msgid "[KEY [VALUE]] - Manage configuration"
msgstr "[KLJUČ [VRIJEDNOST]] – Upravljaj konfiguracijom"

#: app/flatpak-builtins-config.c:394
msgid "Can only use one of --list, --get, --set or --unset"
msgstr ""
"Moguće je koristiti samo jedno od sljedećih: --list, --get, --set ili --unset"

#: app/flatpak-builtins-config.c:408
msgid "Must specify one of --list, --get, --set or --unset"
msgstr "Moraš odrediti jednu od sljedećih: --list, --get, --set ili --unset"

#: app/flatpak-builtins-create-usb.c:45 app/flatpak-builtins-install.c:75
#: app/flatpak-builtins-remote-info.c:57 app/flatpak-builtins-uninstall.c:59
#: app/flatpak-builtins-update.c:65
msgid "Look for app with the specified name"
msgstr "Pazi na programe s određenim imenom"

#: app/flatpak-builtins-create-usb.c:46
msgid "Arch to copy"
msgstr "Arhitektura za kopiranje"

#: app/flatpak-builtins-create-usb.c:47
msgid "DEST"
msgstr "ODREDIŠTE"

#: app/flatpak-builtins-create-usb.c:49
msgid "Allow partial commits in the created repo"
msgstr "Dozvoli djelomične izmjene u stvorenom repozitoriju"

#: app/flatpak-builtins-create-usb.c:125 app/flatpak-builtins-create-usb.c:165
#, c-format
msgid ""
"Warning: Related ref ‘%s’ is partially installed. Use --allow-partial to "
"suppress this message.\n"
msgstr ""
"Upozorenje: Povezana referenca „%s” je djelomično instalirana. Koristi --"
"allow-partial za suzbijanje ove poruke.\n"

#: app/flatpak-builtins-create-usb.c:158
#, c-format
msgid "Warning: Omitting related ref ‘%s’ because it is not installed.\n"
msgstr ""
"Upozorenje: Zanemaruje se povezana referenca „%s”, jer nije instalirana.\n"

#: app/flatpak-builtins-create-usb.c:175
#, c-format
msgid ""
"Warning: Omitting related ref ‘%s’ because its remote ‘%s’ does not have a "
"collection ID set.\n"
msgstr ""
"Upozorenje: Zanemaruje se povezana referenca „%s”, jer njen udaljeni "
"repozitorij „%s” nema postavljenu ID oznaku zbirke.\n"

#: app/flatpak-builtins-create-usb.c:187
#, c-format
msgid "Warning: Omitting related ref ‘%s’ because it's extra-data.\n"
msgstr ""
"Upozorenje: Zanemaruje se povezana referenca „%s”, jer se radi o dodatnim "
"podacima.\n"

#: app/flatpak-builtins-create-usb.c:262 app/flatpak-builtins-create-usb.c:637
#, c-format
msgid ""
"Remote ‘%s’ does not have a collection ID set, which is required for P2P "
"distribution of ‘%s’."
msgstr ""
"Udaljeni repozitorij „%s” nema postavljeni ID zbirke, što je potrebno za P2P "
"distribuciju za „%s”."

#: app/flatpak-builtins-create-usb.c:272
#, c-format
msgid "Warning: Omitting ref ‘%s’ (runtime of ‘%s’) because it's extra-data.\n"
msgstr ""
"Upozorenje: Zanemaruje se referenca „%s” (okruženje od „%s”), jer se radi o "
"dodatnim podacima.\n"

#: app/flatpak-builtins-create-usb.c:484
msgid "MOUNT-PATH [REF…] - Copy apps or runtimes onto removable media"
msgstr ""
"STAZA-JEDINICE [REFERENCA …] – Kopiraj programe ili okurženja na prijenosne "
"medije"

#: app/flatpak-builtins-create-usb.c:493
msgid "MOUNT-PATH and REF must be specified"
msgstr "STAZA-JEDINICE i REFERENCA moraju se odrediti"

#: app/flatpak-builtins-create-usb.c:607
#, c-format
msgid "Ref ‘%s’ found in multiple installations: %s. You must specify one."
msgstr ""
"Referenca „%s” je pronađena u višestrukim instalacijama: %s. Odredi jednu."

#: app/flatpak-builtins-create-usb.c:620
#, c-format
msgid "Refs must all be in the same installation (found in %s and %s)."
msgstr ""
"Sve reference moraju se nalaziti u istoj instalaciji (pronađene su u %s i "
"%s)."

#: app/flatpak-builtins-create-usb.c:670
#, c-format
msgid ""
"Warning: Ref ‘%s’ is partially installed. Use --allow-partial to suppress "
"this message.\n"
msgstr ""
"Upozorenje: Referenca „%s” je djelomično instalirana. Koristi —allow-partial "
"za suzbijanje ove poruke.\n"

#: app/flatpak-builtins-create-usb.c:681
#, c-format
msgid "Installed ref ‘%s’ is extra-data, and cannot be distributed offline"
msgstr ""
"Instalirana referenca „%s” su dodatni podaci i ne mogu se distribuirati bez "
"postojanja mreže"

#: app/flatpak-builtins-create-usb.c:721
#, c-format
msgid "Warning: Couldn't update repo metadata for remote ‘%s’: %s\n"
msgstr ""
"Upozorenje: Nije bilo moguće aktualizirati metapodatke za udaljeni "
"repozitorij „%s”: %s\n"

#: app/flatpak-builtins-create-usb.c:751
#, c-format
msgid "Warning: Couldn't update appstream data for remote ‘%s’ arch ‘%s’: %s\n"
msgstr ""
"Upozorenje: Nije bilo moguće aktualizirati appstream podatke za udaljeni "
"repozitorij „%s” arhitektura „%s”: %s\n"

#. Print a warning if both appstream and appstream2 are missing
#: app/flatpak-builtins-create-usb.c:784
#, c-format
msgid ""
"Warning: Couldn't find appstream data for remote ‘%s’ arch ‘%s’: %s; %s\n"
msgstr ""
"Upozorenje: Nije bilo moguće pronaći appstream podatke za udaljeni "
"repozitorij „%s” arhitektura „%s”: %s, %s\n"

#. Appstream2 is only for efficiency, so just print a debug message
#: app/flatpak-builtins-create-usb.c:790
#, c-format
msgid "Couldn't find appstream2 data for remote ‘%s’ arch ‘%s’: %s\n"
msgstr ""
"Nije bilo moguće naći appstream2 podatke za udaljeni repozitorij „%s” "
"arhitektura „%s”: %s\n"

#: app/flatpak-builtins-document-export.c:62
msgid "Create a unique document reference"
msgstr "Izradi jedinstvenu referencu za dokument"

#: app/flatpak-builtins-document-export.c:63
msgid "Make the document transient for the current session"
msgstr "Učini dokument prolaznim za trenutačnu sesiju"

#: app/flatpak-builtins-document-export.c:64
msgid "Don't require the file to exist already"
msgstr "Ne zahtijevaj, da datoteka već postoji"

#: app/flatpak-builtins-document-export.c:65
msgid "Give the app read permissions"
msgstr "Dodijeli programu dozvole za čitanje"

#: app/flatpak-builtins-document-export.c:66
msgid "Give the app write permissions"
msgstr "Dodijeli programu dozvole za pisanje"

#: app/flatpak-builtins-document-export.c:67
msgid "Give the app delete permissions"
msgstr "Dodijeli programu dozvole za brisanje"

#: app/flatpak-builtins-document-export.c:68
msgid "Give the app permissions to grant further permissions"
msgstr "Dodijeli programu dozvole za davanje daljnjih dozvola"

#: app/flatpak-builtins-document-export.c:69
msgid "Revoke read permissions of the app"
msgstr "Programu oduzmi dozvole za čitanje"

#: app/flatpak-builtins-document-export.c:70
msgid "Revoke write permissions of the app"
msgstr "Programu oduzmi dozvole za pisanje"

#: app/flatpak-builtins-document-export.c:71
msgid "Revoke delete permissions of the app"
msgstr "Programu oduzmi dozvole za brisanje"

#: app/flatpak-builtins-document-export.c:72
msgid "Revoke the permission to grant further permissions"
msgstr "Programu oduzmi dozvole za davanje daljnjih dozvola"

#: app/flatpak-builtins-document-export.c:73
msgid "Add permissions for this app"
msgstr "Dodaj dozvolu za ovaj program"

#: app/flatpak-builtins-document-export.c:73
msgid "APPID"
msgstr "PROGRAMID"

#: app/flatpak-builtins-document-export.c:100
msgid "FILE - Export a file to apps"
msgstr "DATOTEKA – Izvezi datoteku u programe"

#: app/flatpak-builtins-document-export.c:109
#: app/flatpak-builtins-document-info.c:72
#: app/flatpak-builtins-document-unexport.c:67
msgid "FILE must be specified"
msgstr "DATOTEKA se mora odrediti"

#: app/flatpak-builtins-document-info.c:63
msgid "FILE - Get information about an exported file"
msgstr "DATOTEKA – Dobavi informacije o izvezenoj datoteci"

#: app/flatpak-builtins-document-info.c:100
#: app/flatpak-builtins-document-unexport.c:94
#, c-format
msgid "Not exported\n"
msgstr "Nije izvezeno\n"

#: app/flatpak-builtins-document-list.c:43 app/flatpak-builtins-history.c:53
#: app/flatpak-builtins-list.c:54 app/flatpak-builtins-ps.c:43
#: app/flatpak-builtins-remote-list.c:45 app/flatpak-builtins-remote-ls.c:59
#: app/flatpak-builtins-search.c:38
msgid "What information to show"
msgstr "Koje informacije treba prikazati"

#: app/flatpak-builtins-document-list.c:43 app/flatpak-builtins-history.c:53
#: app/flatpak-builtins-list.c:54 app/flatpak-builtins-ps.c:43
#: app/flatpak-builtins-remote-list.c:45 app/flatpak-builtins-remote-ls.c:59
#: app/flatpak-builtins-search.c:38
msgid "FIELD,…"
msgstr "POLJE, …"

#: app/flatpak-builtins-document-list.c:44 app/flatpak-builtins-history.c:54
#: app/flatpak-builtins-list.c:52 app/flatpak-builtins-permission-list.c:43
#: app/flatpak-builtins-permission-show.c:43 app/flatpak-builtins-ps.c:44
#: app/flatpak-builtins-remote-list.c:46 app/flatpak-builtins-remote-ls.c:63
#: app/flatpak-builtins-repo.c:717 app/flatpak-builtins-search.c:39
msgid "Show output in JSON format"
msgstr "Prikaži rezultat u JSON formatu"

#: app/flatpak-builtins-document-list.c:49
msgid "Show the document ID"
msgstr "Prikaži ID dokumenta"

#: app/flatpak-builtins-document-list.c:50
msgid "Path"
msgstr "Staza"

#: app/flatpak-builtins-document-list.c:50
#: app/flatpak-builtins-document-list.c:51
msgid "Show the document path"
msgstr "Prikaži stazu dokumenta"

#: app/flatpak-builtins-document-list.c:51 app/flatpak-builtins-list.c:66
#: app/flatpak-builtins-remote-ls.c:74
msgid "Origin"
msgstr "Izvor"

#: app/flatpak-builtins-document-list.c:52 app/flatpak-builtins-history.c:62
#: app/flatpak-builtins-ps.c:52
msgid "Application"
msgstr "Program"

#: app/flatpak-builtins-document-list.c:52
msgid "Show applications with permission"
msgstr "Prikaži programe s dozvolom"

#: app/flatpak-builtins-document-list.c:53
#: app/flatpak-builtins-permission-list.c:182
#: app/flatpak-builtins-permission-show.c:145
msgid "Permissions"
msgstr "Dozvole"

#: app/flatpak-builtins-document-list.c:53
msgid "Show permissions for applications"
msgstr "Prikaži dozvole za programe"

#: app/flatpak-builtins-document-list.c:161
#, c-format
msgid "No documents found\n"
msgstr "Nije pronađen niti jedan dokumenti\n"

#: app/flatpak-builtins-document-list.c:180
msgid "[APPID] - List exported files"
msgstr "[PROGRAMID] – Izradi popis izvezenih datoteka"

#: app/flatpak-builtins-document-unexport.c:43
msgid "Specify the document ID"
msgstr "Odredi ID dokumenta"

#: app/flatpak-builtins-document-unexport.c:58
msgid "FILE - Unexport a file to apps"
msgstr "DATOTEKA – Poništi izvoz datoteke u programe"

#: app/flatpak-builtins-enter.c:88
msgid "INSTANCE COMMAND [ARGUMENT…] - Run a command inside a running sandbox"
msgstr ""
"INSTANCA NAREDBA [ARGUMENT …] – Pokreni naredbu unutar pokrenutog sandboxa"

#: app/flatpak-builtins-enter.c:111
msgid "INSTANCE and COMMAND must be specified"
msgstr "INSTANCA i NAREDBA se moraju odrediti"

#: app/flatpak-builtins-enter.c:138
#, c-format
msgid "%s is neither a pid nor an application or instance ID"
msgstr "%s nije niti pid niti program ili ID instance"

#: app/flatpak-builtins-enter.c:144
msgid "entering not supported (need unprivileged user namespaces, or sudo -E)"
msgstr ""
"upisivanje nije podržano (potreni su neprivilegirani korisnički imenski "
"prostori ili sudo -E)"

#: app/flatpak-builtins-enter.c:145
#, c-format
msgid "No such pid %s"
msgstr "Ne postoji takav pid %s"

#: app/flatpak-builtins-enter.c:158
msgid "Can't read cwd"
msgstr "Nije moguće čitati direktrorij"

#: app/flatpak-builtins-enter.c:163
msgid "Can't read root"
msgstr "Nije moguće čitati administratora"

#: app/flatpak-builtins-enter.c:191
#, c-format
msgid "Invalid %s namespace for pid %d"
msgstr "Neispravni imenski prostor %s za pid %d"

#: app/flatpak-builtins-enter.c:202
#, c-format
msgid "Invalid %s namespace for self"
msgstr "Neispravni imenski prostor %s za self"

#: app/flatpak-builtins-enter.c:216
#, c-format
msgid "Can't open %s namespace: %s"
msgstr "Nije moguće otvoriti %s imenski prostor: %s"

#: app/flatpak-builtins-enter.c:226
msgid "entering not supported (need unprivileged user namespaces)"
msgstr ""
"upisivanje nije podržano (potreni su neprivilegirani korisnički imenski "
"prostori)"

#: app/flatpak-builtins-enter.c:227
#, c-format
msgid "Can't enter %s namespace: %s"
msgstr "Nije moguće ući u %s imenski prostor: %s"

#: app/flatpak-builtins-enter.c:234
msgid "Can't chdir"
msgstr "Nije moguće promijeniti direktorij"

#: app/flatpak-builtins-enter.c:237
msgid "Can't chroot"
msgstr "Nije moguće promijeniti administratora"

#: app/flatpak-builtins-enter.c:240
msgid "Can't switch gid"
msgstr "Nije moguće zamijeniti gid"

#: app/flatpak-builtins-enter.c:243
msgid "Can't switch uid"
msgstr "Nije moguće zamijeniti uid"

#: app/flatpak-builtins-history.c:50
msgid "Only show changes after TIME"
msgstr "Prikaži samo promjene nakon VREMENA"

#: app/flatpak-builtins-history.c:50 app/flatpak-builtins-history.c:51
msgid "TIME"
msgstr "VRIJEME"

#: app/flatpak-builtins-history.c:51
msgid "Only show changes before TIME"
msgstr "Prikaži samo promjene prije VREMENA"

#: app/flatpak-builtins-history.c:52
msgid "Show newest entries first"
msgstr "Najprije prikaži najnovije unose"

#: app/flatpak-builtins-history.c:59
msgid "Time"
msgstr "Vrijeme"

#: app/flatpak-builtins-history.c:59
msgid "Show when the change happened"
msgstr "Prikaži vrijeme promjene"

#: app/flatpak-builtins-history.c:60
msgid "Change"
msgstr "Promjena"

#: app/flatpak-builtins-history.c:60
msgid "Show the kind of change"
msgstr "Prikaži vrstu promjene"

#: app/flatpak-builtins-history.c:61 app/flatpak-builtins-list.c:68
#: app/flatpak-builtins-remote-ls.c:75 app/flatpak-builtins-repo.c:335
msgid "Ref"
msgstr "Referenca"

#: app/flatpak-builtins-history.c:61 app/flatpak-builtins-list.c:68
#: app/flatpak-builtins-remote-ls.c:75
msgid "Show the ref"
msgstr "Prikaži ref"

#: app/flatpak-builtins-history.c:62
msgid "Show the application/runtime ID"
msgstr "Prikaži ID programa/okruženja"

#: app/flatpak-builtins-history.c:63 app/flatpak-builtins-list.c:64
#: app/flatpak-builtins-ps.c:53 app/flatpak-builtins-remote-ls.c:73
#: app/flatpak-cli-transaction.c:1435
msgid "Arch"
msgstr "Arhitektura"

#: app/flatpak-builtins-history.c:63 app/flatpak-builtins-list.c:64
#: app/flatpak-builtins-ps.c:53 app/flatpak-builtins-remote-ls.c:73
msgid "Show the architecture"
msgstr "Prikaži arhitekturu"

#: app/flatpak-builtins-history.c:64 app/flatpak-builtins-list.c:63
#: app/flatpak-builtins-ps.c:54 app/flatpak-builtins-remote-ls.c:72
#: app/flatpak-builtins-search.c:48 app/flatpak-cli-transaction.c:1438
msgid "Branch"
msgstr "Grana"

#: app/flatpak-builtins-history.c:64 app/flatpak-builtins-list.c:63
#: app/flatpak-builtins-remote-ls.c:72
msgid "Show the branch"
msgstr "Prikaži granu"

#: app/flatpak-builtins-history.c:65 app/flatpak-builtins-list.c:67
msgid "Installation"
msgstr "Instalacija"

#: app/flatpak-builtins-history.c:65
msgid "Show the affected installation"
msgstr "Prikaži pogođenu instalaciju"

#: app/flatpak-builtins-history.c:66 app/flatpak-cli-transaction.c:1452
msgid "Remote"
msgstr "Udaljeni repozitorij"

#: app/flatpak-builtins-history.c:66
msgid "Show the remote"
msgstr "Prikaži udaljeni repozitorij"

#: app/flatpak-builtins-history.c:67 app/flatpak-builtins-ps.c:55
#: app/flatpak-builtins-remote-ls.c:76
msgid "Commit"
msgstr "Izmjena"

#: app/flatpak-builtins-history.c:67
msgid "Show the current commit"
msgstr "Prikaži trenutačnu izmjenu"

#: app/flatpak-builtins-history.c:68
msgid "Old Commit"
msgstr "Stara izmjena"

#: app/flatpak-builtins-history.c:68
msgid "Show the previous commit"
msgstr "Prikaži prethodnu izmjenu"

#: app/flatpak-builtins-history.c:69
msgid "Show the remote URL"
msgstr "Prikaži URL udaljenog repozitorija"

#: app/flatpak-builtins-history.c:70 app/flatpak-cli-transaction.c:700
msgid "User"
msgstr "Korisnik"

#: app/flatpak-builtins-history.c:70
msgid "Show the user doing the change"
msgstr "Prikaži korisnika koji je izradio promjene"

#: app/flatpak-builtins-history.c:71
msgid "Tool"
msgstr "Alat"

#: app/flatpak-builtins-history.c:71
msgid "Show the tool that was used"
msgstr "Prikaži alat koji se koristio"

#: app/flatpak-builtins-history.c:72 app/flatpak-builtins-list.c:62
#: app/flatpak-builtins-remote-ls.c:71 app/flatpak-builtins-search.c:47
msgid "Version"
msgstr "Verzija"

#: app/flatpak-builtins-history.c:72
msgid "Show the Flatpak version"
msgstr "Prikaži Flatpak verziju"

#: app/flatpak-builtins-history.c:91
#, c-format
msgid "Failed to get journal data (%s): %s"
msgstr "Neuspjelo dobivanje podataka dnevnika (%s): %s"

#: app/flatpak-builtins-history.c:146
#, c-format
msgid "Failed to open journal: %s"
msgstr "Neuspjelo otvaranje dnevnika: %s"

#: app/flatpak-builtins-history.c:153
#, c-format
msgid "Failed to add match to journal: %s"
msgstr "Neuspjelo dodavanje poklapanja u dnevnika: %s"

#: app/flatpak-builtins-history.c:471
msgid " - Show history"
msgstr " – Prikaži kronologiju"

#: app/flatpak-builtins-history.c:490
#, c-format
msgid "Failed to parse the --since option"
msgstr "Neuspjela obrada opcije --since"

#: app/flatpak-builtins-history.c:501
#, c-format
msgid "Failed to parse the --until option"
msgstr "Neuspjela obrada opcije --until"

#: app/flatpak-builtins-info.c:56
msgid "Show user installations"
msgstr "Prikaži korisničke instalacije"

#: app/flatpak-builtins-info.c:57
msgid "Show system-wide installations"
msgstr "Prikaži sustavske instalacije"

#: app/flatpak-builtins-info.c:58
msgid "Show specific system-wide installations"
msgstr "Prikaži određene sustavske instalacije"

#: app/flatpak-builtins-info.c:59 app/flatpak-builtins-remote-info.c:59
msgid "Show ref"
msgstr "Prikaži referencu"

#: app/flatpak-builtins-info.c:60 app/flatpak-builtins-remote-info.c:60
msgid "Show commit"
msgstr "Prikaži izmjenu"

#: app/flatpak-builtins-info.c:61
msgid "Show origin"
msgstr "Prikaži izvor"

#: app/flatpak-builtins-info.c:62
msgid "Show size"
msgstr "Prikaži veličinu"

#: app/flatpak-builtins-info.c:63 app/flatpak-builtins-remote-info.c:62
msgid "Show metadata"
msgstr "Prikaži metapodatke"

#: app/flatpak-builtins-info.c:64 app/flatpak-builtins-remote-info.c:63
msgid "Show runtime"
msgstr "Prikaži okruženje"

#: app/flatpak-builtins-info.c:65 app/flatpak-builtins-remote-info.c:64
msgid "Show sdk"
msgstr "Prikaži sdk"

#: app/flatpak-builtins-info.c:66
msgid "Show permissions"
msgstr "Prikaži dozvole"

#: app/flatpak-builtins-info.c:67
msgid "Query file access"
msgstr "Upitaj stanje pristupa datoteka"

#: app/flatpak-builtins-info.c:67 app/flatpak-builtins-install.c:82
#: app/flatpak-builtins-install.c:88 app/flatpak-builtins-preinstall.c:68
#: app/flatpak-builtins-run.c:182 app/flatpak-builtins-run.c:184
#: app/flatpak-builtins-update.c:67 app/flatpak-builtins-update.c:71
msgid "PATH"
msgstr "STAZA"

#: app/flatpak-builtins-info.c:68
msgid "Show extensions"
msgstr "Prikaži proširenja"

#: app/flatpak-builtins-info.c:69
msgid "Show location"
msgstr "Prikaži lokaciju"

#: app/flatpak-builtins-info.c:116
msgid "NAME [BRANCH] - Get info about an installed app or runtime"
msgstr "IME [GRANA] – Dobij informacije o instaliranom programu ili okruženju"

#: app/flatpak-builtins-info.c:123 app/flatpak-builtins-remote-add.c:317
#: app/flatpak-builtins-remote-delete.c:63
msgid "NAME must be specified"
msgstr "IME se mora odrediti"

#: app/flatpak-builtins-info.c:196
msgid "ref not present in origin"
msgstr "reference nema u izvoru"

#: app/flatpak-builtins-info.c:211 app/flatpak-builtins-remote-info.c:217
#, c-format
msgid "Warning: Commit has no flatpak metadata\n"
msgstr "Upozorenje: Izmjena nema flatpak metapodatke\n"

#: app/flatpak-builtins-info.c:217 app/flatpak-builtins-info.c:259
#: app/flatpak-builtins-info.c:455 app/flatpak-builtins-info.c:513
#: app/flatpak-builtins-remote-info.c:236
#: app/flatpak-builtins-remote-info.c:271
msgid "ID:"
msgstr "ID:"

#: app/flatpak-builtins-info.c:218 app/flatpak-builtins-info.c:260
#: app/flatpak-builtins-remote-info.c:237
#: app/flatpak-builtins-remote-info.c:272
msgid "Ref:"
msgstr "Referenca:"

#: app/flatpak-builtins-info.c:219 app/flatpak-builtins-info.c:261
#: app/flatpak-builtins-remote-info.c:238
#: app/flatpak-builtins-remote-info.c:273
msgid "Arch:"
msgstr "Arhitektura:"

#: app/flatpak-builtins-info.c:220 app/flatpak-builtins-info.c:262
#: app/flatpak-builtins-remote-info.c:239
#: app/flatpak-builtins-remote-info.c:274
msgid "Branch:"
msgstr "Grana:"

#: app/flatpak-builtins-info.c:222 app/flatpak-builtins-info.c:264
#: app/flatpak-builtins-remote-info.c:241
#: app/flatpak-builtins-remote-info.c:276
msgid "Version:"
msgstr "Verzija:"

#: app/flatpak-builtins-info.c:224 app/flatpak-builtins-info.c:266
#: app/flatpak-builtins-remote-info.c:243
#: app/flatpak-builtins-remote-info.c:278
msgid "License:"
msgstr "Licenca:"

#: app/flatpak-builtins-info.c:226 app/flatpak-builtins-info.c:269
#: app/flatpak-builtins-remote-info.c:245
#: app/flatpak-builtins-remote-info.c:280
msgid "Collection:"
msgstr "Zbirka:"

#: app/flatpak-builtins-info.c:227 app/flatpak-builtins-info.c:270
#: app/flatpak-builtins-info.c:458 app/flatpak-builtins-info.c:516
msgid "Installation:"
msgstr "Instalacija:"

#: app/flatpak-builtins-info.c:228 app/flatpak-builtins-info.c:271
#: app/flatpak-builtins-info.c:459 app/flatpak-builtins-info.c:517
#: app/flatpak-builtins-remote-info.c:249
#: app/flatpak-builtins-remote-info.c:284
#, fuzzy
msgid "Installed Size:"
msgstr "Instalirana veličina"

#: app/flatpak-builtins-info.c:231 app/flatpak-builtins-info.c:279
#: app/flatpak-builtins-remote-info.c:252
#: app/flatpak-builtins-remote-info.c:288
msgid "Runtime:"
msgstr "Okruženje:"

#: app/flatpak-builtins-info.c:232 app/flatpak-builtins-info.c:288
#: app/flatpak-builtins-remote-info.c:253
#: app/flatpak-builtins-remote-info.c:293
msgid "Sdk:"
msgstr "Sdk:"

#: app/flatpak-builtins-info.c:235 app/flatpak-builtins-info.c:313
#: app/flatpak-builtins-remote-info.c:256
#: app/flatpak-builtins-remote-info.c:319
msgid "Date:"
msgstr "Datum:"

#: app/flatpak-builtins-info.c:237 app/flatpak-builtins-info.c:311
#: app/flatpak-builtins-remote-info.c:258
#: app/flatpak-builtins-remote-info.c:317
msgid "Subject:"
msgstr "Predmet:"

#: app/flatpak-builtins-info.c:240 app/flatpak-builtins-info.c:295
msgid "Active commit:"
msgstr "Aktivna izmjena:"

#: app/flatpak-builtins-info.c:241 app/flatpak-builtins-info.c:298
msgid "Latest commit:"
msgstr "Zadnja izmjena:"

#: app/flatpak-builtins-info.c:244 app/flatpak-builtins-info.c:303
#: app/flatpak-builtins-info.c:457 app/flatpak-builtins-info.c:515
#: app/flatpak-builtins-remote-info.c:259
#: app/flatpak-builtins-remote-info.c:298
msgid "Commit:"
msgstr "Izmjena:"

#: app/flatpak-builtins-info.c:246 app/flatpak-builtins-info.c:308
#: app/flatpak-builtins-remote-info.c:261
#: app/flatpak-builtins-remote-info.c:303
msgid "Parent:"
msgstr "Nadređeni:"

#: app/flatpak-builtins-info.c:248 app/flatpak-builtins-info.c:321
msgid "Alt-id:"
msgstr "Alt-id:"

#: app/flatpak-builtins-info.c:250 app/flatpak-builtins-info.c:325
#: app/flatpak-builtins-remote-info.c:263
#: app/flatpak-builtins-remote-info.c:308
msgid "End-of-life:"
msgstr "Kraj-života:"

#: app/flatpak-builtins-info.c:252 app/flatpak-builtins-info.c:330
#: app/flatpak-builtins-remote-info.c:265
#: app/flatpak-builtins-remote-info.c:313
msgid "End-of-life-rebase:"
msgstr "Kraj-života-premještanje:"

#: app/flatpak-builtins-info.c:254 app/flatpak-builtins-info.c:317
msgid "Subdirectories:"
msgstr "Poddirektoriji:"

#: app/flatpak-builtins-info.c:255 app/flatpak-builtins-info.c:454
#: app/flatpak-builtins-info.c:512
msgid "Extension:"
msgstr "Proširenje:"

#: app/flatpak-builtins-info.c:267 app/flatpak-builtins-info.c:456
#: app/flatpak-builtins-info.c:514
msgid "Origin:"
msgstr "Izvor:"

#: app/flatpak-builtins-info.c:460 app/flatpak-builtins-info.c:522
msgid "Subpaths:"
msgstr "Podstaze:"

#: app/flatpak-builtins-info.c:478
msgid "unmaintained"
msgstr "ne održava se"

#: app/flatpak-builtins-info.c:480 app/flatpak-builtins-info.c:482
msgid "unknown"
msgstr "nepoznato"

#: app/flatpak-builtins-install.c:68 app/flatpak-builtins-preinstall.c:57
msgid "Don't pull, only install from local cache"
msgstr "Nemoj povući, samo instaliraj s lokalne predmemorije"

#: app/flatpak-builtins-install.c:69 app/flatpak-builtins-preinstall.c:58
#: app/flatpak-builtins-update.c:60
msgid "Don't deploy, only download to local cache"
msgstr "Nemoj implementirati, samo preuzmi na lokalnu predmemoriju"

#: app/flatpak-builtins-install.c:70 app/flatpak-builtins-preinstall.c:59
msgid "Don't install related refs"
msgstr "Nemoj instalirati povezane reference"

#: app/flatpak-builtins-install.c:71 app/flatpak-builtins-preinstall.c:60
#: app/flatpak-builtins-update.c:62
msgid "Don't verify/install runtime dependencies"
msgstr "Nemoj provjeritit/instalirati ovisnosti za okruženje"

#: app/flatpak-builtins-install.c:72
msgid "Don't automatically pin explicit installs"
msgstr "Nemoj automatski prikvačiti eksplicitne instalacije"

#: app/flatpak-builtins-install.c:73 app/flatpak-builtins-preinstall.c:61
#: app/flatpak-builtins-update.c:63
msgid "Don't use static deltas"
msgstr "Nemoj koristiti statičke delta datoteke"

#: app/flatpak-builtins-install.c:76 app/flatpak-builtins-preinstall.c:62
msgid "Additionally install the SDK used to build the given refs"
msgstr ""

#: app/flatpak-builtins-install.c:77 app/flatpak-builtins-preinstall.c:63
msgid ""
"Additionally install the debug info for the given refs and their dependencies"
msgstr ""

#: app/flatpak-builtins-install.c:78
msgid "Assume LOCATION is a .flatpak single-file bundle"
msgstr "Pretpostavi da je LOKACIJA .flatpak paket s jednom datotekom"

#: app/flatpak-builtins-install.c:79
msgid "Assume LOCATION is a .flatpakref application description"
msgstr "Pretpostavi da je LOKACIJA .flatpakref opis programa"

#: app/flatpak-builtins-install.c:80
msgid "Assume LOCATION is containers-transports(5) reference to an OCI image"
msgstr ""

#: app/flatpak-builtins-install.c:81
msgid "Check bundle signatures with GPG key from FILE (- for stdin)"
msgstr "Provjeri potpise paketa s GPG ključem iz DATOTEKA (- za stdin)"

#: app/flatpak-builtins-install.c:82
msgid "Only install this subpath"
msgstr "Instaliraj samo ovu podstazu"

#: app/flatpak-builtins-install.c:83 app/flatpak-builtins-preinstall.c:64
#: app/flatpak-builtins-uninstall.c:63 app/flatpak-builtins-update.c:68
msgid "Automatically answer yes for all questions"
msgstr "Automatski odgovori s „Da” na sva pitanja"

#: app/flatpak-builtins-install.c:84 app/flatpak-builtins-preinstall.c:65
msgid "Uninstall first if already installed"
msgstr "Najprije deinstaliraj, ako je već instalirano"

#: app/flatpak-builtins-install.c:85 app/flatpak-builtins-preinstall.c:66
#: app/flatpak-builtins-uninstall.c:64 app/flatpak-builtins-update.c:69
msgid "Produce minimal output and don't ask questions"
msgstr "Proizvedi najmanji rezultat i ne postavljaj pitanja"

#: app/flatpak-builtins-install.c:86
msgid "Update install if already installed"
msgstr "Aktualiziraj instalaciju, ako je već instalirana"

#. Translators: A sideload is when you install from a local USB drive rather than the Internet.
#: app/flatpak-builtins-install.c:88 app/flatpak-builtins-preinstall.c:68
#: app/flatpak-builtins-update.c:71
msgid "Use this local repo for sideloads"
msgstr "Koristi ovaj lokalni repozitorij za lokalno preuzimanje"

#: app/flatpak-builtins-install.c:178
msgid "Bundle filename must be specified"
msgstr "Ime datoteke paketa se mora odrediti"

#: app/flatpak-builtins-install.c:188
msgid "Remote bundles are not supported"
msgstr "Paketi udaljenih repozitorija nisu pdržani"

#: app/flatpak-builtins-install.c:231
msgid "Filename or uri must be specified"
msgstr "Ime datoteke ili uri se moraju odrediti"

#: app/flatpak-builtins-install.c:295
msgid "Image location must be specified"
msgstr "Mjesto slike se mora odrediti"

#: app/flatpak-builtins-install.c:345
msgid "[LOCATION/REMOTE] [REF…] - Install applications or runtimes"
msgstr ""
"[LOKACIJA/UDALJENI-ROPOZITORIJ] [REFERENCA …] – Instaliraj programe ili "
"okruženja"

#: app/flatpak-builtins-install.c:378
msgid "At least one REF must be specified"
msgstr "Mora se odrediti barem jedna REFERENCA"

#: app/flatpak-builtins-install.c:392
#, c-format
msgid "Looking for matches…\n"
msgstr "Traženje poklapanja …\n"

#: app/flatpak-builtins-install.c:513
#, fuzzy, c-format
msgid "No remote refs found for ‘%s’"
msgstr "Nema referenca udaljenog repozitorija koje sliče „%s”"

#: app/flatpak-builtins-install.c:573 app/flatpak-builtins-uninstall.c:405
#: common/flatpak-ref-utils.c:689 common/flatpak-ref-utils.c:1595
#, c-format
msgid "Invalid branch %s: %s"
msgstr "Neispravna grana %s: %s"

#: app/flatpak-builtins-install.c:606
#, c-format
msgid "Nothing matches %s in local repository for remote %s"
msgstr ""
"Ništa se ne poklapa s %s u lokalnom repozitoriju za udaljeni repozitorij %s"

#: app/flatpak-builtins-install.c:608
#, c-format
msgid "Nothing matches %s in remote %s"
msgstr "Ništa se ne poklapa s %s u udaljenom repozitoriju %s"

#: app/flatpak-builtins-install.c:629
#, c-format
msgid "Skipping: %s\n"
msgstr "Preskakanje: %s\n"

#: app/flatpak-builtins-kill.c:110
#, c-format
msgid "%s is not running"
msgstr "%s nije pokrenut"

#: app/flatpak-builtins-kill.c:136
msgid "INSTANCE - Stop a running application"
msgstr "INSTANCA – Zaustavi pokrenuti program"

#: app/flatpak-builtins-kill.c:144 app/flatpak-builtins-ps.c:256
msgid "Extra arguments given"
msgstr "Dodatni argumenti zadani"

#: app/flatpak-builtins-kill.c:150
msgid "Must specify the app to kill"
msgstr "Moraš odrediti program za ubijanje"

#: app/flatpak-builtins-list.c:47
msgid "Show extra information"
msgstr "Prikaži dodatne informacije"

#: app/flatpak-builtins-list.c:48
msgid "List installed runtimes"
msgstr "Izradi popis instaliranih okruženja"

#: app/flatpak-builtins-list.c:49
msgid "List installed applications"
msgstr "Izradi popis instaliranih programa"

#: app/flatpak-builtins-list.c:50
msgid "Arch to show"
msgstr "Arhitektura za prikaz"

#: app/flatpak-builtins-list.c:51 app/flatpak-builtins-remote-ls.c:57
msgid "List all refs (including locale/debug)"
msgstr ""
"Izradi popis svih referenca (uključujući lokalizacije/pronalaženje grešaka)"

#: app/flatpak-builtins-list.c:53 app/flatpak-builtins-remote-ls.c:58
msgid "List all applications using RUNTIME"
msgstr "Izradi popis programa koji koriste OKRUŽENJE"

#: app/flatpak-builtins-list.c:59 app/flatpak-builtins-remote-list.c:51
#: app/flatpak-builtins-remote-ls.c:68 app/flatpak-builtins-search.c:44
msgid "Name"
msgstr "Ime"

#: app/flatpak-builtins-list.c:59 app/flatpak-builtins-remote-list.c:51
#: app/flatpak-builtins-remote-ls.c:68 app/flatpak-builtins-search.c:44
msgid "Show the name"
msgstr "Prikaži ime"

#: app/flatpak-builtins-list.c:60 app/flatpak-builtins-remote-list.c:60
#: app/flatpak-builtins-remote-ls.c:69 app/flatpak-builtins-search.c:45
msgid "Description"
msgstr "Opis"

#: app/flatpak-builtins-list.c:60 app/flatpak-builtins-remote-ls.c:69
#: app/flatpak-builtins-search.c:45
msgid "Show the description"
msgstr "Prikaži opis"

#: app/flatpak-builtins-list.c:61 app/flatpak-builtins-remote-ls.c:70
#: app/flatpak-builtins-search.c:46
msgid "Application ID"
msgstr "ID programa"

#: app/flatpak-builtins-list.c:61 app/flatpak-builtins-ps.c:52
#: app/flatpak-builtins-remote-ls.c:70 app/flatpak-builtins-search.c:46
msgid "Show the application ID"
msgstr "Prikaži ID programa"

#: app/flatpak-builtins-list.c:62 app/flatpak-builtins-remote-ls.c:71
#: app/flatpak-builtins-search.c:47
msgid "Show the version"
msgstr "Prikaži verziju"

#: app/flatpak-builtins-list.c:65 app/flatpak-builtins-ps.c:56
#: app/flatpak-builtins-remote-ls.c:77
msgid "Runtime"
msgstr "Okruženje"

#: app/flatpak-builtins-list.c:65
msgid "Show the used runtime"
msgstr "Prikaži korišteno okruženje"

#: app/flatpak-builtins-list.c:66 app/flatpak-builtins-remote-ls.c:74
msgid "Show the origin remote"
msgstr "Prikaži repozitorij izvora"

#: app/flatpak-builtins-list.c:67
msgid "Show the installation"
msgstr "Prikaži instalaciju"

#: app/flatpak-builtins-list.c:69
msgid "Active commit"
msgstr "Aktivna izmjena"

#: app/flatpak-builtins-list.c:69 app/flatpak-builtins-remote-ls.c:76
msgid "Show the active commit"
msgstr "Prikaži aktivnu izmjenu"

#: app/flatpak-builtins-list.c:70
msgid "Latest commit"
msgstr "Zadnja izmjena"

#: app/flatpak-builtins-list.c:70
msgid "Show the latest commit"
msgstr "Prikaži zadnju izmjenu"

#: app/flatpak-builtins-list.c:71 app/flatpak-builtins-remote-ls.c:78
msgid "Installed size"
msgstr "Instalirana veličina"

#: app/flatpak-builtins-list.c:71 app/flatpak-builtins-remote-ls.c:78
msgid "Show the installed size"
msgstr "Prikaži instaliranu veličinu"

#: app/flatpak-builtins-list.c:72 app/flatpak-builtins-remote-list.c:58
#: app/flatpak-builtins-remote-ls.c:80 app/flatpak-builtins-repo.c:340
msgid "Options"
msgstr "Opcije"

#: app/flatpak-builtins-list.c:72 app/flatpak-builtins-remote-list.c:58
#: app/flatpak-builtins-remote-ls.c:80
msgid "Show options"
msgstr "Prikaži opcije"

#: app/flatpak-builtins-list.c:180
#, c-format
msgid "Unable to load details of %s: %s"
msgstr "Nije moguće učitati detalje o %s: %s"

#: app/flatpak-builtins-list.c:190
#, c-format
msgid "Unable to inspect current version of %s: %s"
msgstr "Nije moguće pregledati trenutačnu verziju od %s: %s"

#: app/flatpak-builtins-list.c:408
msgid " - List installed apps and/or runtimes"
msgstr " - Izradi popis programa i/ili okruženja"

#: app/flatpak-builtins-make-current.c:38
msgid "Arch to make current for"
msgstr "Arhitektura za postaviti kao trenutačnu za"

#: app/flatpak-builtins-make-current.c:58
msgid "APP BRANCH - Make branch of application current"
msgstr "PROGRAM GRANA – Postavi granu programa kao trenutačnu"

#: app/flatpak-builtins-make-current.c:69 app/flatpak-builtins-run.c:260
msgid "APP must be specified"
msgstr "PROGRAM se mora odrediti"

#: app/flatpak-builtins-make-current.c:84
msgid "BRANCH must be specified"
msgstr "GRANA se mora odrediti"

#: app/flatpak-builtins-make-current.c:97
#, c-format
msgid "App %s branch %s is not installed"
msgstr "Program %s grana %s nije instaliran"

#: app/flatpak-builtins-mask.c:42
msgid "Remove matching masks"
msgstr "Ukloni poklapajuće maske"

#: app/flatpak-builtins-mask.c:54
msgid ""
"[PATTERN…] - disable updates and automatic installation matching patterns"
msgstr ""
"[UZORAK …] – deaktiviraj aktualiziranja i automatsko instaliranje koji se "
"poklapaju s uzorcima"

#: app/flatpak-builtins-mask.c:73
#, c-format
msgid "No masked patterns\n"
msgstr "Nema maskiranih uzoraka\n"

#: app/flatpak-builtins-mask.c:78
#, c-format
msgid "Masked patterns:\n"
msgstr "Maskirani uzorci:\n"

#: app/flatpak-builtins-override.c:42
msgid "Remove existing overrides"
msgstr "Ukloni postojeća nadjačavanja"

#: app/flatpak-builtins-override.c:43
msgid "Show existing overrides"
msgstr "Prikaži postojeća nadjačavanja"

#: app/flatpak-builtins-override.c:59
msgid "[APP] - Override settings [for application]"
msgstr "[PROGRAM] – Postavke nadjačavanja [za program]"

#: app/flatpak-builtins-permission-list.c:143
msgid "[TABLE] [ID] - List permissions"
msgstr "[TABLICA] [ID] – Izradi popis dozvola"

#: app/flatpak-builtins-permission-list.c:179
#: app/flatpak-builtins-permission-show.c:142
msgid "Table"
msgstr "Tablica"

#: app/flatpak-builtins-permission-list.c:180
#: app/flatpak-builtins-permission-show.c:143
msgid "Object"
msgstr "Objekt"

#: app/flatpak-builtins-permission-list.c:181
#: app/flatpak-builtins-permission-show.c:144
msgid "App"
msgstr "Program"

#: app/flatpak-builtins-permission-list.c:183
#: app/flatpak-builtins-permission-show.c:146
msgid "Data"
msgstr "Podaci"

#: app/flatpak-builtins-permission-remove.c:120
msgid "TABLE ID [APP_ID] - Remove item from permission store"
msgstr "TABLICA ID [PROGRAM_ID] – Ukloni stavku iz spremišta dozvola"

#: app/flatpak-builtins-permission-remove.c:129
#: app/flatpak-builtins-permission-set.c:120
msgid "Too few arguments"
msgstr "Nedovoljno argumenata"

#: app/flatpak-builtins-permission-reset.c:43
msgid "Reset all permissions"
msgstr "Ponovo postavi sve dozvole"

#: app/flatpak-builtins-permission-reset.c:144
msgid "APP_ID - Reset permissions for an app"
msgstr "PROGRAM_ID – Ponovo postavi dozvole za program"

#: app/flatpak-builtins-permission-reset.c:153
#: app/flatpak-builtins-permission-show.c:124
msgid "Wrong number of arguments"
msgstr "Krivi broj argumenata"

#: app/flatpak-builtins-permission-set.c:42
msgid "Associate DATA with the entry"
msgstr "Poveži PODATKE s unosom"

#: app/flatpak-builtins-permission-set.c:42
msgid "DATA"
msgstr "PODACI"

#: app/flatpak-builtins-permission-set.c:111
msgid "TABLE ID APP_ID [PERMISSION...] - Set permissions"
msgstr "TABLICA ID PROGRAM_ID [DOZVOLA …] – Postavi dozvole"

#: app/flatpak-builtins-permission-set.c:132
#, c-format
msgid "Failed to parse '%s' as GVariant: "
msgstr "Neuspjela obrada „%s” kao GVariant: "

#: app/flatpak-builtins-permission-show.c:115
msgid "APP_ID - Show permissions for an app"
msgstr "PROGRAM_ID – Prikaži dozvole za program"

#: app/flatpak-builtins-pin.c:44
msgid "Remove matching pins"
msgstr "Ukloni poklapajuća prikvačivanja"

#: app/flatpak-builtins-pin.c:56
msgid "[PATTERN…] - disable automatic removal of runtimes matching patterns"
msgstr ""
"[UZORAK …] – deaktiviraj automatsko uklanjanje okruženja koji se poklapaju s "
"uzorcima"

#: app/flatpak-builtins-pin.c:75
#, c-format
msgid "No pinned patterns\n"
msgstr "Nema prikvačenih uzoraka\n"

#: app/flatpak-builtins-pin.c:80
#, c-format
msgid "Pinned patterns:\n"
msgstr "Prikvačeni uzorci:\n"

#: app/flatpak-builtins-preinstall.c:80
msgid "- Install flatpaks that are part of the operating system"
msgstr "- Instaliraj flatpakove koji su dio operacijskog sustava"

#: app/flatpak-builtins-preinstall.c:118
#, c-format
msgid "Nothing to do.\n"
msgstr "Nema se što raditi.\n"

#: app/flatpak-builtins-ps.c:49
msgid "Instance"
msgstr "Instanca"

#: app/flatpak-builtins-ps.c:49
msgid "Show the instance ID"
msgstr "Prikaži ID instance"

#: app/flatpak-builtins-ps.c:50 app/flatpak-builtins-run.c:178
msgid "PID"
msgstr "PID"

#: app/flatpak-builtins-ps.c:50
msgid "Show the PID of the wrapper process"
msgstr "Prikaži PID procesa wrappera"

#: app/flatpak-builtins-ps.c:51
msgid "Child-PID"
msgstr "PID podređenog"

#: app/flatpak-builtins-ps.c:51
msgid "Show the PID of the sandbox process"
msgstr "Prikaži PID procesa sandboxa"

#: app/flatpak-builtins-ps.c:54 app/flatpak-builtins-search.c:48
msgid "Show the application branch"
msgstr "Prikaži granu programa"

#: app/flatpak-builtins-ps.c:55
msgid "Show the application commit"
msgstr "Prikaži izmjenu programa"

#: app/flatpak-builtins-ps.c:56
msgid "Show the runtime ID"
msgstr "Prikaži ID okruženja"

#: app/flatpak-builtins-ps.c:57
msgid "R.-Branch"
msgstr "O.-grana"

#: app/flatpak-builtins-ps.c:57
msgid "Show the runtime branch"
msgstr "Prikaži granu okruženja"

#: app/flatpak-builtins-ps.c:58
msgid "R.-Commit"
msgstr "O.-izmjena"

#: app/flatpak-builtins-ps.c:58
msgid "Show the runtime commit"
msgstr "Prikaži izmjenu okruženja"

#: app/flatpak-builtins-ps.c:59
msgid "Active"
msgstr "Aktivno"

#: app/flatpak-builtins-ps.c:59
msgid "Show whether the app is active"
msgstr "Prikaži, je li program aktivan"

#: app/flatpak-builtins-ps.c:60
msgid "Background"
msgstr "Pozadina"

#: app/flatpak-builtins-ps.c:60
msgid "Show whether the app is background"
msgstr "Prikaži, je li program pozadina"

#: app/flatpak-builtins-ps.c:246
msgid " - Enumerate running sandboxes"
msgstr " - Pobroji pokrenute sandboxe"

#: app/flatpak-builtins-remote-add.c:66
msgid "Do nothing if the provided remote exists"
msgstr "Ne radi ništa, ako navedeni udaljeni repozitorij postoji"

#: app/flatpak-builtins-remote-add.c:67
msgid "LOCATION specifies a configuration file, not the repo location"
msgstr "LOKACIJA određuje datoteku konfiguracije, nije lokacija repozitorija"

#: app/flatpak-builtins-remote-add.c:72 app/flatpak-builtins-remote-modify.c:78
msgid "Disable GPG verification"
msgstr "Deaktiviraj GPG provjeru"

#: app/flatpak-builtins-remote-add.c:73 app/flatpak-builtins-remote-modify.c:79
msgid "Mark the remote as don't enumerate"
msgstr "Označi udaljeni repozitorij da ne pobrojava"

#: app/flatpak-builtins-remote-add.c:74 app/flatpak-builtins-remote-modify.c:80
msgid "Mark the remote as don't use for deps"
msgstr "Označi udaljeni repozitorij da se ne koristi za ovisnosti"

#: app/flatpak-builtins-remote-add.c:75 app/flatpak-builtins-remote-modify.c:81
msgid "Set priority (default 1, higher is more prioritized)"
msgstr "Postavi prioritet (standardno je 1, veći broj znači veći prioritet)"

#: app/flatpak-builtins-remote-add.c:75 app/flatpak-builtins-remote-modify.c:81
msgid "PRIORITY"
msgstr "PRIORITET"

#: app/flatpak-builtins-remote-add.c:76
msgid "The named subset to use for this remote"
msgstr "Imenovani podskup za ovaj udaljeni repozitorij"

#: app/flatpak-builtins-remote-add.c:76 app/flatpak-builtins-remote-modify.c:71
msgid "SUBSET"
msgstr "PODSKUP"

#: app/flatpak-builtins-remote-add.c:77 app/flatpak-builtins-remote-modify.c:82
msgid "A nice name to use for this remote"
msgstr "Korišteno lijepo ime za ovaj udaljeni repozitorij"

#: app/flatpak-builtins-remote-add.c:78 app/flatpak-builtins-remote-modify.c:83
msgid "A one-line comment for this remote"
msgstr "Kratki komentar za ovaj udaljeni repozitorij"

#: app/flatpak-builtins-remote-add.c:79 app/flatpak-builtins-remote-modify.c:84
msgid "A full-paragraph description for this remote"
msgstr "Komentar u obliku odlomka za ovaj udaljeni repozitorij"

#: app/flatpak-builtins-remote-add.c:80 app/flatpak-builtins-remote-modify.c:85
msgid "URL for a website for this remote"
msgstr "URL za web-stranicu za ovaj udaljeni repozitorij"

#: app/flatpak-builtins-remote-add.c:81 app/flatpak-builtins-remote-modify.c:86
msgid "URL for an icon for this remote"
msgstr "URL za ikonu za ovaj udaljeni repozitorij"

#: app/flatpak-builtins-remote-add.c:82 app/flatpak-builtins-remote-modify.c:87
msgid "Default branch to use for this remote"
msgstr "Korištena standardna grana za ovaj udaljeni repozitorij"

#: app/flatpak-builtins-remote-add.c:84 app/flatpak-builtins-remote-modify.c:89
msgid "Import GPG key from FILE (- for stdin)"
msgstr "Uvezi GPG ključ iz DATOTEKA (- za stdin)"

#: app/flatpak-builtins-remote-add.c:85 app/flatpak-builtins-remote-modify.c:90
msgid "Load signatures from URL"
msgstr ""

#: app/flatpak-builtins-remote-add.c:86 app/flatpak-builtins-remote-modify.c:92
msgid "Set path to local filter FILE"
msgstr "Postavi stazu na lokalnu DATOTEKU filtra"

#: app/flatpak-builtins-remote-add.c:87 app/flatpak-builtins-remote-modify.c:93
msgid "Disable the remote"
msgstr "Deaktiviraj udaljeni repozitorij"

#: app/flatpak-builtins-remote-add.c:88 app/flatpak-builtins-remote-modify.c:94
msgid "Name of authenticator"
msgstr "Ime autentifikatora"

#: app/flatpak-builtins-remote-add.c:90 app/flatpak-builtins-remote-modify.c:96
msgid "Autoinstall authenticator"
msgstr "Automatski instaliraj autentifikatora"

#: app/flatpak-builtins-remote-add.c:91 app/flatpak-builtins-remote-modify.c:97
msgid "Don't autoinstall authenticator"
msgstr "Nemoj automatski instalirati autentifikatora"

#: app/flatpak-builtins-remote-add.c:92 app/flatpak-builtins-remote-modify.c:99
msgid "Don't follow the redirect set in the summary file"
msgstr "Ne prati preusmjeravanje postavljeno u datoteci sažetka"

#: app/flatpak-builtins-remote-add.c:261 app/flatpak-builtins-remote-add.c:268
#, c-format
msgid "Can't load uri %s: %s\n"
msgstr "Nije moguće učitati uri %s: %s\n"

#: app/flatpak-builtins-remote-add.c:276 common/flatpak-dir.c:4643
#, c-format
msgid "Can't load file %s: %s\n"
msgstr "Nije moguće učitati datoteku %s: %s\n"

#: app/flatpak-builtins-remote-add.c:304
msgid "NAME LOCATION - Add a remote repository"
msgstr "IME LOKACIJE – Dodaj udaljeni repozitorij"

#: app/flatpak-builtins-remote-add.c:331
msgid "GPG verification is required if collections are enabled"
msgstr "GPG provjera je potrebna, ako su zbirke aktivirane"

#: app/flatpak-builtins-remote-add.c:393
#, c-format
msgid "Remote %s already exists"
msgstr "Udaljeni repozitorij „%s” već postoji"

#: app/flatpak-builtins-remote-add.c:405
#: app/flatpak-builtins-remote-modify.c:340
#, c-format
msgid "Invalid authenticator name %s"
msgstr "Neispravno ime autentifikatora %s"

#: app/flatpak-builtins-remote-add.c:422
#, c-format
msgid "Warning: Could not update extra metadata for '%s': %s\n"
msgstr ""
"Upozorenje: Nije bilo moguće aktualizirati dodatne metapodatke za „%s”: %s\n"

#: app/flatpak-builtins-remote-delete.c:39
msgid "Remove remote even if in use"
msgstr "Ukloni udaljeni repozitorij, čak i ako se koristi"

#: app/flatpak-builtins-remote-delete.c:53
msgid "NAME - Delete a remote repository"
msgstr "IME – Ukloni udaljeni repozitorij"

#: app/flatpak-builtins-remote-delete.c:100
#, c-format
msgid "The following refs are installed from remote '%s':"
msgstr "Sljedeće reference su instalirane s udaljenog repozitorija „%s”:"

#: app/flatpak-builtins-remote-delete.c:101
msgid "Remove them?"
msgstr "Ukloniti ih?"

#: app/flatpak-builtins-remote-delete.c:103
#, c-format
msgid "Can't remove remote '%s' with installed refs"
msgstr ""
"Nije moguće ukloniti udaljeni repozitorij „%s” s instaliranim referencama"

#: app/flatpak-builtins-remote-info.c:55
msgid "Commit to show info for"
msgstr "Izmijena za prikaz informacija za"

#: app/flatpak-builtins-remote-info.c:58
msgid "Display log"
msgstr "Prikaži log-zapise"

#: app/flatpak-builtins-remote-info.c:61
msgid "Show parent"
msgstr "Prikaži nadređeni"

#: app/flatpak-builtins-remote-info.c:65 app/flatpak-builtins-remote-ls.c:60
msgid "Use local caches even if they are stale"
msgstr "Koristi lokalnu predmemoriju, čak i ako je zastarjela"

#. Translators: A sideload is when you install from a local USB drive rather than the Internet.
#: app/flatpak-builtins-remote-info.c:67 app/flatpak-builtins-remote-ls.c:62
msgid "Only list refs available as sideloads"
msgstr "Navedi samo reference koje su dostupne kao lokalna preuzimanja"

#: app/flatpak-builtins-remote-info.c:114
msgid ""
" REMOTE REF - Show information about an application or runtime in a remote"
msgstr ""
" UDALJENI_REPOZITORIJ REFERENCA – Prikaži informacije o programu ili "
"okruženju u udaljenom repozitoriju"

#: app/flatpak-builtins-remote-info.c:125
msgid "REMOTE and REF must be specified"
msgstr "UDALJENI_REPOZITORIJ i REFERENCA se moraju odrediti"

#: app/flatpak-builtins-remote-info.c:247
#: app/flatpak-builtins-remote-info.c:282
#, fuzzy
msgid "Download Size:"
msgstr "Veličina preuzimanja"

#: app/flatpak-builtins-remote-info.c:267
#: app/flatpak-builtins-remote-info.c:325
msgid "History:"
msgstr "Kronologija:"

#: app/flatpak-builtins-remote-info.c:348
msgid " Commit:"
msgstr " Izmjena:"

#: app/flatpak-builtins-remote-info.c:349
msgid " Subject:"
msgstr " Predmet:"

#: app/flatpak-builtins-remote-info.c:350
msgid " Date:"
msgstr " Datum:"

#: app/flatpak-builtins-remote-info.c:383
#, c-format
msgid "Warning: Commit %s has no flatpak metadata\n"
msgstr "Upozorenje: Izmjena %s nema flatpak metapodatke\n"

#: app/flatpak-builtins-remote-list.c:43
msgid "Show remote details"
msgstr "Prikaži detalje udaljenog repozitorija"

#: app/flatpak-builtins-remote-list.c:44
msgid "Show disabled remotes"
msgstr "Prikaži deaktivirane udaljene repozitorije"

#: app/flatpak-builtins-remote-list.c:52
msgid "Title"
msgstr "Naslov"

#: app/flatpak-builtins-remote-list.c:52
msgid "Show the title"
msgstr "Prikaži naslov"

#: app/flatpak-builtins-remote-list.c:53
msgid "Show the URL"
msgstr "Prikaži URL"

#: app/flatpak-builtins-remote-list.c:54
msgid "Show the collection ID"
msgstr "Prikaži ID zbirke"

#: app/flatpak-builtins-remote-list.c:55 app/flatpak-builtins-repo.c:392
msgid "Subset"
msgstr "Podskup"

#: app/flatpak-builtins-remote-list.c:55
msgid "Show the subset"
msgstr "Prikaži podskup"

#: app/flatpak-builtins-remote-list.c:56
msgid "Filter"
msgstr "Filtar"

#: app/flatpak-builtins-remote-list.c:56
msgid "Show filter file"
msgstr "Prikaži datoteku filtra"

#: app/flatpak-builtins-remote-list.c:57
msgid "Priority"
msgstr "Prioritet"

#: app/flatpak-builtins-remote-list.c:57
msgid "Show the priority"
msgstr "Prikaži prioritet"

#: app/flatpak-builtins-remote-list.c:59
msgid "Comment"
msgstr "Komentar"

#: app/flatpak-builtins-remote-list.c:59
msgid "Show comment"
msgstr "Prikaži komentar"

#: app/flatpak-builtins-remote-list.c:60
msgid "Show description"
msgstr "Prikaži opis"

#: app/flatpak-builtins-remote-list.c:61
msgid "Homepage"
msgstr "Početna web-stranica"

#: app/flatpak-builtins-remote-list.c:61
msgid "Show homepage"
msgstr "Prikaži početnu web-stranicu"

#: app/flatpak-builtins-remote-list.c:62
msgid "Icon"
msgstr "Ikona"

#: app/flatpak-builtins-remote-list.c:62
msgid "Show icon"
msgstr "Prikaži ikonu"

#: app/flatpak-builtins-remote-list.c:231
msgid " - List remote repositories"
msgstr " - Izradi popis udaljenih repozitorija"

#: app/flatpak-builtins-remote-ls.c:52
msgid "Show arches and branches"
msgstr "Prikaži arhitekture i grane"

#: app/flatpak-builtins-remote-ls.c:53
msgid "Show only runtimes"
msgstr "Prikaži samo programe"

#: app/flatpak-builtins-remote-ls.c:54
msgid "Show only apps"
msgstr "Prikaži samo programe"

#: app/flatpak-builtins-remote-ls.c:55
msgid "Show only those where updates are available"
msgstr "Prikaži samo one, za koje postoje aktualiziranja"

#: app/flatpak-builtins-remote-ls.c:56
msgid "Limit to this arch (* for all)"
msgstr "Ograniči na ovu arhitekturu (* za sve)"

#: app/flatpak-builtins-remote-ls.c:77
msgid "Show the runtime"
msgstr "Prikaži okruženje"

#: app/flatpak-builtins-remote-ls.c:79
msgid "Download size"
msgstr "Veličina preuzimanja"

#: app/flatpak-builtins-remote-ls.c:79
msgid "Show the download size"
msgstr "Prikaži veličinu preuzimanja"

#: app/flatpak-builtins-remote-ls.c:391
msgid " [REMOTE or URI] - Show available runtimes and applications"
msgstr ""
" [UDALJENI-REPOZITORIJ ili URI] – Prikaži dostupna okruženja i programe"

#: app/flatpak-builtins-remote-modify.c:67
msgid "Enable GPG verification"
msgstr "Aktiviraj GPG provjeru"

#: app/flatpak-builtins-remote-modify.c:68
msgid "Mark the remote as enumerate"
msgstr "Označi udaljeni repozitorij da pobrojava"

#: app/flatpak-builtins-remote-modify.c:69
msgid "Mark the remote as used for dependencies"
msgstr "Označi udaljeni repozitorij da se koristi za ovisnosti"

#: app/flatpak-builtins-remote-modify.c:70
#, fuzzy
msgid "Set a new URL"
msgstr "Postavi novi url"

#: app/flatpak-builtins-remote-modify.c:71
msgid "Set a new subset to use"
msgstr "Postavi novi podskup za korištenje"

#: app/flatpak-builtins-remote-modify.c:72
msgid "Enable the remote"
msgstr "Anktiviraj udaljeni repozitorij"

#: app/flatpak-builtins-remote-modify.c:73
msgid "Update extra metadata from the summary file"
msgstr "Aktualiziraj dodatne metapodatke iz datoteke sažetka"

#: app/flatpak-builtins-remote-modify.c:91
msgid "Disable local filter"
msgstr "Deaktiviraj lokalni filtar"

#: app/flatpak-builtins-remote-modify.c:95
msgid "Authenticator options"
msgstr "Opcije autentifikatora"

#: app/flatpak-builtins-remote-modify.c:98
msgid "Follow the redirect set in the summary file"
msgstr "Prati preusmjeravanje postavljeno u datoteci sažetka"

#: app/flatpak-builtins-remote-modify.c:306
msgid "NAME - Modify a remote repository"
msgstr "IME – Promijeni udaljeni repozitorij"

#: app/flatpak-builtins-remote-modify.c:316
msgid "Remote NAME must be specified"
msgstr "IME udaljenog repozitorija se mora odrediti"

#: app/flatpak-builtins-remote-modify.c:327
#, c-format
msgid "Updating extra metadata from remote summary for %s\n"
msgstr ""
"Aktualiziraj dodatne metapodatke iz sažetka udaljenog repozitorija za %s\n"

#: app/flatpak-builtins-remote-modify.c:330
#, c-format
msgid "Error updating extra metadata for '%s': %s\n"
msgstr "Greška pri aktualiziranju dodatnih metapodataka za „%s”: %s\n"

#: app/flatpak-builtins-remote-modify.c:331
#, c-format
msgid "Could not update extra metadata for %s"
msgstr "Nije bilo moguće aktualizirati dodatne metapodatke za %s"

#: app/flatpak-builtins-repair.c:43
msgid "Don't make any changes"
msgstr "Nemoj ništa mijenjati"

#: app/flatpak-builtins-repair.c:44
msgid "Reinstall all refs"
msgstr "Ponovo instaliraj sve reference"

#: app/flatpak-builtins-repair.c:68
#, c-format
msgid "Object missing: %s.%s\n"
msgstr "Objekt nedostaje: %s.%s\n"

#: app/flatpak-builtins-repair.c:76
#, c-format
msgid "Object invalid: %s.%s\n"
msgstr "Objekt neispravan: %s.%s\n"

#: app/flatpak-builtins-repair.c:81
#, c-format
msgid "%s, deleting object\n"
msgstr "%s, uklanjanje objekata\n"

#: app/flatpak-builtins-repair.c:146
#, c-format
msgid "Can't load object %s: %s\n"
msgstr "Nije moguće učitati objekt %s: %s\n"

#: app/flatpak-builtins-repair.c:228
#, c-format
msgid "Commit invalid %s: %s\n"
msgstr "Izmjena neispravna: %s.%s\n"

#: app/flatpak-builtins-repair.c:231
#, c-format
msgid "Deleting invalid commit %s: %s\n"
msgstr "Brisanje nevažećih izmjena %s: %s\n"

#: app/flatpak-builtins-repair.c:261
#, c-format
msgid "Commit should be marked partial: %s\n"
msgstr "Izmjena bi se trebala označiti kao djelomična: %s\n"

#: app/flatpak-builtins-repair.c:264
#, c-format
msgid "Marking commit as partial: %s\n"
msgstr ""

#: app/flatpak-builtins-repair.c:293
#, c-format
msgid "Problems loading data for %s: %s\n"
msgstr "Problemi pri učitavanju podataka za %s: %s\n"

#: app/flatpak-builtins-repair.c:306
#, c-format
msgid "Error reinstalling %s: %s\n"
msgstr "Greška pri ponovnom instaliranju %s: %s\n"

#: app/flatpak-builtins-repair.c:327
msgid "- Repair a flatpak installation"
msgstr "- Popravi flatpak instalaciju"

#: app/flatpak-builtins-repair.c:406
#, c-format
msgid "Removing non-deployed ref %s…\n"
msgstr "Uklanjanje neimplementirane reference %s …\n"

#: app/flatpak-builtins-repair.c:411
#, c-format
msgid "Skipping non-deployed ref %s…\n"
msgstr "Preskače se neimplementirana referenca %s …\n"

#: app/flatpak-builtins-repair.c:429
#, c-format
msgid "[%d/%d] Verifying %s…\n"
msgstr "[%d/%d] Potvrđivanje %s…\n"

#: app/flatpak-builtins-repair.c:435
#, c-format
msgid "Dry run: "
msgstr "Probno pokretanje: "

#: app/flatpak-builtins-repair.c:440
#, c-format
msgid "Deleting ref %s due to missing objects\n"
msgstr "Uklanjanje reference %s zbog nedostajućeg objekta\n"

#: app/flatpak-builtins-repair.c:444
#, c-format
msgid "Deleting ref %s due to invalid objects\n"
msgstr "Uklanjanje reference %s zbog neispravnog objekta\n"

#: app/flatpak-builtins-repair.c:448
#, c-format
msgid "Deleting ref %s due to %d\n"
msgstr "Uklanjanje reference %s zbog %d\n"

#: app/flatpak-builtins-repair.c:464
#, c-format
msgid "Checking remotes...\n"
msgstr "Provjeravanje udaljenih repozitorija …\n"

#: app/flatpak-builtins-repair.c:482
#, c-format
msgid "Remote %s for ref %s is missing\n"
msgstr "Udaljeni repozitorij „%s” za referencu %s nedostaje\n"

#: app/flatpak-builtins-repair.c:484
#, c-format
msgid "Remote %s for ref %s is disabled\n"
msgstr "Udaljeni repozitorij „%s” za referencu %s je deaktiviran\n"

#: app/flatpak-builtins-repair.c:490
#, c-format
msgid "Pruning objects\n"
msgstr "Odrezivanje predmeta\n"

#: app/flatpak-builtins-repair.c:498
#, c-format
msgid "Erasing .removed\n"
msgstr "Brisanje .removed\n"

#: app/flatpak-builtins-repair.c:524
#, c-format
msgid "Reinstalling refs\n"
msgstr "Ponovno instaliranje referenca\n"

#: app/flatpak-builtins-repair.c:526
#, c-format
msgid "Reinstalling removed refs\n"
msgstr "Ponovno instaliranje uklonjenih referenca\n"

#: app/flatpak-builtins-repair.c:551
#, c-format
msgid "While removing appstream for %s: "
msgstr "Prilikom uklanjanja appstreama za %s: "

#: app/flatpak-builtins-repair.c:558
#, c-format
msgid "While deploying appstream for %s: "
msgstr "Prilikom implementiranja appstreama za %s: "

#: app/flatpak-builtins-repo.c:106
#, c-format
msgid "Repo mode: %s\n"
msgstr "Modus repozitorija: %s\n"

#: app/flatpak-builtins-repo.c:113
#, c-format
msgid "Indexed summaries: %s\n"
msgstr "Indeksirani sažetci: %s\n"

#: app/flatpak-builtins-repo.c:113 app/flatpak-builtins-repo.c:139
#: app/flatpak-builtins-repo.c:172
msgid "true"
msgstr "točno"

#: app/flatpak-builtins-repo.c:113 app/flatpak-builtins-repo.c:139
#: app/flatpak-builtins-repo.c:172
msgid "false"
msgstr "netočno"

#: app/flatpak-builtins-repo.c:121
#, c-format
msgid "Subsummaries: "
msgstr "Podsažetci: "

#: app/flatpak-builtins-repo.c:136
#, c-format
msgid "Cache version: %d\n"
msgstr "Verzija predmemorije : %d\n"

#: app/flatpak-builtins-repo.c:139
#, c-format
msgid "Indexed deltas: %s\n"
msgstr "Indeksirane delta datoteke: %s\n"

#: app/flatpak-builtins-repo.c:142
#, c-format
msgid "Title: %s\n"
msgstr "Naslov: %s\n"

#: app/flatpak-builtins-repo.c:145
#, c-format
msgid "Comment: %s\n"
msgstr "Komentar: %s\n"

#: app/flatpak-builtins-repo.c:148
#, c-format
msgid "Description: %s\n"
msgstr "Opis: %s\n"

#: app/flatpak-builtins-repo.c:151
#, c-format
msgid "Homepage: %s\n"
msgstr "Početna web-stranica: %s\n"

#: app/flatpak-builtins-repo.c:154
#, c-format
msgid "Icon: %s\n"
msgstr "Ikona: %s\n"

#: app/flatpak-builtins-repo.c:157
#, c-format
msgid "Collection ID: %s\n"
msgstr "ID zbirke: %s\n"

#: app/flatpak-builtins-repo.c:160
#, c-format
msgid "Default branch: %s\n"
msgstr "Standardna grana: %s\n"

#: app/flatpak-builtins-repo.c:163
#, c-format
msgid "Redirect URL: %s\n"
msgstr "URL preusmjeravanja: %s\n"

#: app/flatpak-builtins-repo.c:166
#, c-format
msgid "Deploy collection ID: %s\n"
msgstr "Implementiraj ID zbirke: %s\n"

#: app/flatpak-builtins-repo.c:169
#, c-format
msgid "Authenticator name: %s\n"
msgstr "Ime autentifikatora: %s\n"

#: app/flatpak-builtins-repo.c:172
#, c-format
msgid "Authenticator install: %s\n"
msgstr "Instalacija autentifikatora: %s\n"

#: app/flatpak-builtins-repo.c:180
#, c-format
msgid "GPG key hash: %s\n"
msgstr "Hash GPG ključa: %s\n"

#: app/flatpak-builtins-repo.c:184
#, c-format
msgid "%zd summary branches\n"
msgstr "%zd grane sažetka\n"

#: app/flatpak-builtins-repo.c:336
msgid "Installed"
msgstr "Instalirano"

#. Translators: Download is used here as a noun
#: app/flatpak-builtins-repo.c:338 app/flatpak-cli-transaction.c:1462
msgid "Download"
msgstr "Preuzimanje"

#: app/flatpak-builtins-repo.c:339
msgid "Subsets"
msgstr "Podskupovi"

#: app/flatpak-builtins-repo.c:393
msgid "Digest"
msgstr "Sažetak poruke"

#: app/flatpak-builtins-repo.c:394
msgid "History length"
msgstr "Količina kronologije"

#: app/flatpak-builtins-repo.c:711
msgid "Print general information about the repository"
msgstr "Ispiši opće informacije o repozitoriju"

#: app/flatpak-builtins-repo.c:712
msgid "List the branches in the repository"
msgstr "Izradi popis grana u repozitoriju"

#: app/flatpak-builtins-repo.c:713
msgid "Print metadata for a branch"
msgstr "Ispiši metapodatke za granu"

#: app/flatpak-builtins-repo.c:714
msgid "Show commits for a branch"
msgstr "Prikaži izmjene za jednu granu"

#: app/flatpak-builtins-repo.c:715
msgid "Print information about the repo subsets"
msgstr "Ispiši informacije o podskupovima repozitorija"

#: app/flatpak-builtins-repo.c:716
msgid "Limit information to subsets with this prefix"
msgstr "Ograniči informacije na podskupove s ovim prefiksom"

#: app/flatpak-builtins-repo.c:732
msgid "LOCATION - Repository maintenance"
msgstr "LOKACIJA – Održavanje repozitorija"

#: app/flatpak-builtins-run.c:159
msgid "Command to run"
msgstr "Naredba za pokretanje"

#: app/flatpak-builtins-run.c:160
msgid "Directory to run the command in"
msgstr "Direktorij u kojem se pokreće naredba"

#: app/flatpak-builtins-run.c:161
msgid "Branch to use"
msgstr "Korištena grana"

#: app/flatpak-builtins-run.c:162
msgid "Use development runtime"
msgstr "Koristi razvojno okruženje"

#: app/flatpak-builtins-run.c:163
msgid "Runtime to use"
msgstr "Korišteno okruženje"

#: app/flatpak-builtins-run.c:164
msgid "Runtime version to use"
msgstr "Korištena verzija okruženja"

#: app/flatpak-builtins-run.c:167
msgid "Log accessibility bus calls"
msgstr "Zapiši bus pozive pristupačnosti"

#: app/flatpak-builtins-run.c:168
msgid "Don't proxy accessibility bus calls"
msgstr "Nemoj bus pozive pristupačnosti proxija"

#: app/flatpak-builtins-run.c:169
msgid "Proxy accessibility bus calls (default except when sandboxed)"
msgstr "Bus pozivi pristupačnosti proxija (standardno, osim ako je u sandboxu)"

#: app/flatpak-builtins-run.c:170
msgid "Don't proxy session bus calls"
msgstr "Nemoj bus pozive sesije proxija"

#: app/flatpak-builtins-run.c:171
msgid "Proxy session bus calls (default except when sandboxed)"
msgstr "Bus pozivi sesije proxija (standardno, osim ako je u sandboxu)"

#: app/flatpak-builtins-run.c:172
msgid "Don't start portals"
msgstr "Nemoj pokrenuti portale"

#: app/flatpak-builtins-run.c:173
msgid "Enable file forwarding"
msgstr "Aktiviraj proslijeđivanje datoteka"

#: app/flatpak-builtins-run.c:174
msgid "Run specified commit"
msgstr "Pokreni određenu izmjenu"

#: app/flatpak-builtins-run.c:175
msgid "Use specified runtime commit"
msgstr "Koristi određenu izmjenu okruženja"

#: app/flatpak-builtins-run.c:176
msgid "Run completely sandboxed"
msgstr "Pokreni potpuno u sandboxu"

#: app/flatpak-builtins-run.c:178
msgid "Use PID as parent pid for sharing namespaces"
msgstr "Koristi PID kao nadređeni PID za dijeljenje imenskih prostora"

#: app/flatpak-builtins-run.c:179
msgid "Make processes visible in parent namespace"
msgstr "Omogući vidljivost procesa u nadređenom imenskom prostoru"

#: app/flatpak-builtins-run.c:180
msgid "Share process ID namespace with parent"
msgstr "Dijeli imenski prostor ID procesa s nadređenim"

#: app/flatpak-builtins-run.c:181
msgid "Write the instance ID to the given file descriptor"
msgstr "Zapiši ID instance navedenom deskriptoru datoteka"

#: app/flatpak-builtins-run.c:182
msgid "Use PATH instead of the app's /app"
msgstr "Koristi STAZU umjesto programi/program"

#: app/flatpak-builtins-run.c:183
#, fuzzy
msgid "Use FD instead of the app's /app"
msgstr "Koristi STAZU umjesto programi/program"

#: app/flatpak-builtins-run.c:183 app/flatpak-builtins-run.c:185
#: app/flatpak-builtins-run.c:187 app/flatpak-builtins-run.c:188
#: common/flatpak-context.c:2672
msgid "FD"
msgstr "FD"

#: app/flatpak-builtins-run.c:184
msgid "Use PATH instead of the runtime's /usr"
msgstr "Koristi STAZU umjesto okruženje/korisnik"

#: app/flatpak-builtins-run.c:185
#, fuzzy
msgid "Use FD instead of the runtime's /usr"
msgstr "Koristi STAZU umjesto okruženje/korisnik"

#: app/flatpak-builtins-run.c:186
msgid "Clear all outside environment variables"
msgstr "Izbriši sve vanjske varijable okruženja"

#: app/flatpak-builtins-run.c:187
msgid ""
"Bind mount the file or directory referred to by FD to its canonicalized path"
msgstr ""

#: app/flatpak-builtins-run.c:188
msgid ""
"Bind mount the file or directory referred to by FD read-only to its "
"canonicalized path"
msgstr ""

#: app/flatpak-builtins-run.c:219
msgid "APP [ARGUMENT…] - Run an app"
msgstr "PROGRAM [ARGUMENT …] – Pokreni jedan program"

#: app/flatpak-builtins-run.c:370
#, c-format
msgid "runtime/%s/%s/%s not installed"
msgstr "okruženje/%s/%s/%s nije instalirano"

#: app/flatpak-builtins-run.c:419
msgid "app-fd and app-path cannot both be used"
msgstr ""

#: app/flatpak-builtins-run.c:449
msgid "usr-fd and usr-path cannot both be used"
msgstr ""

#: app/flatpak-builtins-search.c:37
msgid "Arch to search for"
msgstr "Arhitektura za pretraživanje"

#: app/flatpak-builtins-search.c:49
msgid "Remotes"
msgstr "Udaljeni repozitoriji"

#: app/flatpak-builtins-search.c:49
msgid "Show the remotes"
msgstr "Prikaži udaljene repozitorije"

#: app/flatpak-builtins-search.c:244
msgid "TEXT - Search remote apps/runtimes for text"
msgstr "TEKST – Traži tekst u programima/okruženjima udaljenog repozitorija"

#: app/flatpak-builtins-search.c:255
msgid "TEXT must be specified"
msgstr "TEKST se mora odrediti"

#: app/flatpak-builtins-search.c:338
msgid "No matches found"
msgstr "Nema poklapanja"

#: app/flatpak-builtins-uninstall.c:54
msgid "Arch to uninstall"
msgstr "Arhitektura za deinstaliranje"

#: app/flatpak-builtins-uninstall.c:55
msgid "Keep ref in local repository"
msgstr "Zadrži referencu u lokalnom repozitoriju"

#: app/flatpak-builtins-uninstall.c:56
msgid "Don't uninstall related refs"
msgstr "Nemoj deinstalirati povezane reference"

#: app/flatpak-builtins-uninstall.c:57
msgid "Remove files even if running"
msgstr "Ukloni datoteke, čak i ako su pokrenute"

#: app/flatpak-builtins-uninstall.c:60
msgid "Uninstall all"
msgstr "Deinstaliraj sve"

#: app/flatpak-builtins-uninstall.c:61
msgid "Uninstall unused"
msgstr "Deinstaliraj nekorišteni"

#: app/flatpak-builtins-uninstall.c:62
msgid "Delete app data"
msgstr "Ukloni podatke programa"

#: app/flatpak-builtins-uninstall.c:141
#, c-format
msgid "Delete data for %s?"
msgstr "Ukloniti podatke za %s?"

#: app/flatpak-builtins-uninstall.c:220
#, c-format
msgid "Info: applications using the extension %s%s%s branch %s%s%s:\n"
msgstr ""

#: app/flatpak-builtins-uninstall.c:223
#, fuzzy, c-format
msgid "Info: applications using the runtime %s%s%s branch %s%s%s:\n"
msgstr "Programi koji koriste ovo okruženje:\n"

#: app/flatpak-builtins-uninstall.c:238
msgid "Really remove?"
msgstr "Stvarno ukloniti?"

#: app/flatpak-builtins-uninstall.c:255
#, fuzzy
msgid "[REF…] - Uninstall applications or runtimes"
msgstr "[REFERENCA …] – Aktualiziraj programe ili okruženja"

#: app/flatpak-builtins-uninstall.c:264
msgid "Must specify at least one REF, --unused, --all or --delete-data"
msgstr ""
"Moraš odrediti barem jednu REFERENCU, --unused, --all ili --delete-data"

#: app/flatpak-builtins-uninstall.c:267
msgid "Must not specify REFs when using --all"
msgstr "Ne određuj REFERENCE kad koristiš --all"

#: app/flatpak-builtins-uninstall.c:270
msgid "Must not specify REFs when using --unused"
msgstr "Ne određuj REFERENCE kad koristiš --unused"

#: app/flatpak-builtins-uninstall.c:336
#, c-format
msgid ""
"\n"
"These runtimes in installation '%s' are pinned and won't be removed; see "
"flatpak-pin(1):\n"
msgstr ""
"\n"
"Ova okruženja u instalaciji „%s” su prikvačeni i neće se ukloniti; pogledj "
"flatpak-pin(1):\n"

#: app/flatpak-builtins-uninstall.c:370
#, c-format
msgid "Nothing unused to uninstall\n"
msgstr "Ništa neupotrebljenog za deinstalirati\n"

#: app/flatpak-builtins-uninstall.c:444
#, fuzzy, c-format
msgid "No installed refs found for ‘%s’"
msgstr "Slične instalirane reference su pronađene za „%s”:"

#: app/flatpak-builtins-uninstall.c:447
#, c-format
msgid " with arch ‘%s’"
msgstr ""

#: app/flatpak-builtins-uninstall.c:449
#, c-format
msgid " with branch ‘%s’"
msgstr ""

#: app/flatpak-builtins-uninstall.c:456
#, c-format
msgid "Warning: %s is not installed\n"
msgstr "Upozorenje: %s nije instalirano\n"

#: app/flatpak-builtins-uninstall.c:490
#, c-format
msgid "None of the specified refs are installed"
msgstr "Nijedna od navedenih referenci nije instalirana"

#: app/flatpak-builtins-uninstall.c:599
#, c-format
msgid "No app data to delete\n"
msgstr ""

#: app/flatpak-builtins-update.c:56
msgid "Arch to update for"
msgstr "Arhitektura za aktualiziranje za"

#: app/flatpak-builtins-update.c:57
msgid "Commit to deploy"
msgstr "Izmjena za implementiranje"

#: app/flatpak-builtins-update.c:58
msgid "Remove old files even if running"
msgstr "Ukloni stare datoteke, čak i ako su pokrenute"

#: app/flatpak-builtins-update.c:59
msgid "Don't pull, only update from local cache"
msgstr "Nemoj povući, samo aktualiziraj s lokalne predmemorije"

#: app/flatpak-builtins-update.c:61
msgid "Don't update related refs"
msgstr "Nemoj aktualizirati povezane reference"

#: app/flatpak-builtins-update.c:66
msgid "Update appstream for remote"
msgstr "Aktualiziraj podatke programa za udaljeni repozitorij"

#: app/flatpak-builtins-update.c:67
msgid "Only update this subpath"
msgstr "Aktualiziraj samo ovu podstazu"

#: app/flatpak-builtins-update.c:90
msgid "[REF…] - Update applications or runtimes"
msgstr "[REFERENCA …] – Aktualiziraj programe ili okruženja"

#: app/flatpak-builtins-update.c:121
msgid "With --commit, only one REF may be specified"
msgstr "Pomoću --commit može se odrediti samo jedna REFERENCA"

#: app/flatpak-builtins-update.c:162
#, c-format
msgid "Looking for updates…\n"
msgstr "Traženje aktualiziranja …\n"

#: app/flatpak-builtins-update.c:215
#, c-format
msgid "Unable to update %s: %s\n"
msgstr "Nije moguće aktualizirati %s: %s\n"

#: app/flatpak-builtins-update.c:274
#, fuzzy, c-format
msgid "Nothing to update.\n"
msgstr "Nema se što raditi.\n"

#: app/flatpak-builtins-utils.c:337
#, fuzzy, c-format
msgid ""
"Remote ‘%s’ found in multiple installations, unable to proceed in non-"
"interactive mode"
msgstr ""
"Referenca „%s” je pronađena u višestrukim instalacijama: %s. Odredi jednu."

#: app/flatpak-builtins-utils.c:346
#, c-format
msgid "Remote ‘%s’ found in multiple installations:"
msgstr "Udaljeni repozitorij „%s” je pronađen u višestrukim instalacijama:"

#: app/flatpak-builtins-utils.c:347 app/flatpak-builtins-utils.c:442
#: app/flatpak-builtins-utils.c:538 app/flatpak-builtins-utils.c:540
#: app/flatpak-builtins-utils.c:598
msgid "Which do you want to use (0 to abort)?"
msgstr "Koji želiš koristiti (0 za prekid)?"

#: app/flatpak-builtins-utils.c:349
#, c-format
msgid "No remote chosen to resolve ‘%s’ which exists in multiple installations"
msgstr ""
"Nije odabran udaljeni repozitorij za rješavanje „%s”, što postoji u više "
"instalacija"

#: app/flatpak-builtins-utils.c:358
#, c-format
msgid ""
"Remote \"%s\" not found\n"
"Hint: Use flatpak remote-add to add a remote"
msgstr ""
"Udaljeni repozitorij „%s” nije pronađen\n"
"Savjet: Koristi flatpak remote-add za dodavanje udaljeneg repozitorija"

#: app/flatpak-builtins-utils.c:364
#, c-format
msgid "Remote \"%s\" not found in the %s installation"
msgstr "Udaljeni repozitorij „%s” nije pronađen u %s instalaciji"

#: app/flatpak-builtins-utils.c:404
#, c-format
msgid "Multiple refs match ‘%s’, unable to proceed in non-interactive mode"
msgstr ""

#. default to yes on Enter
#: app/flatpak-builtins-utils.c:430
#, c-format
msgid ""
"Found ref ‘%s’ in remote ‘%s’ (%s).\n"
"Use this ref?"
msgstr ""
"Pronađena je referenca „%s” u udaljenom repozitoriju „%s” (%s).\n"
"Koristiti ovu referencu?"

#: app/flatpak-builtins-utils.c:434 app/flatpak-builtins-utils.c:444
#: app/flatpak-builtins-utils.c:522 app/flatpak-builtins-utils.c:543
#, c-format
msgid "No ref chosen to resolve matches for ‘%s’"
msgstr "Nije odabrana referenca za rješavanje poklapanja za „%s”"

#: app/flatpak-builtins-utils.c:440
#, c-format
msgid "Similar refs found for ‘%s’ in remote ‘%s’ (%s):"
msgstr ""
"Slične reference su pronađene za „%s” u udaljenom repozitoriju „%s” (%s):"

#: app/flatpak-builtins-utils.c:488
#, c-format
msgid ""
"Multiple installed refs match ‘%s’, unable to proceed in non-interactive mode"
msgstr ""

#. default to yes on Enter
#: app/flatpak-builtins-utils.c:518
#, c-format
msgid "Found installed ref ‘%s’ (%s). Is this correct?"
msgstr "Pronađena na instalirana referenca „%s” (%s). Je li to točno?"

#: app/flatpak-builtins-utils.c:534
#, c-format
msgid "All of the above"
msgstr "Sve gore navedeno"

#: app/flatpak-builtins-utils.c:535
#, c-format
msgid "Similar installed refs found for ‘%s’:"
msgstr "Slične instalirane reference su pronađene za „%s”:"

#: app/flatpak-builtins-utils.c:579
#, c-format
msgid ""
"Multiple remotes have refs matching ‘%s’, unable to proceed in non-"
"interactive mode"
msgstr ""

#: app/flatpak-builtins-utils.c:597
#, c-format
msgid "Remotes found with refs similar to ‘%s’:"
msgstr "Pronađeni udaljeni repozitoriji s referencom koja sliči „%s”:"

#: app/flatpak-builtins-utils.c:600
#, c-format
msgid "No remote chosen to resolve matches for ‘%s’"
msgstr "Nije odabran udaljeni repozitorij za rješavanje poklapanja za „%s”"

#: app/flatpak-builtins-utils.c:696 app/flatpak-builtins-utils.c:699
#, c-format
msgid "Updating appstream data for user remote %s"
msgstr "Aktualiziranje appstream podatke za korisnički udaljeni repozitorij %s"

#: app/flatpak-builtins-utils.c:706 app/flatpak-builtins-utils.c:709
#, c-format
msgid "Updating appstream data for remote %s"
msgstr "Aktualiziranje appstream podatke za udaljeni repozitorij %s"

#: app/flatpak-builtins-utils.c:717 app/flatpak-builtins-utils.c:719
msgid "Error updating"
msgstr "Greška pri aktualiziranju"

#: app/flatpak-builtins-utils.c:755
#, c-format
msgid "Remote \"%s\" not found"
msgstr "Udaljeni repozitorij „%s” nije pronađen"

#: app/flatpak-builtins-utils.c:796
#, c-format
msgid "Ambiguous suffix: '%s'."
msgstr "Dvosmislen nastavak: „%s”."

#. Translators: don't translate the values
#: app/flatpak-builtins-utils.c:798 app/flatpak-builtins-utils.c:813
msgid "Possible values are :s[tart], :m[iddle], :e[nd] or :f[ull]"
msgstr "Moguće vrijednosti su :s[tart], :m[iddle], :e[nd] ili :f[ull]"

#: app/flatpak-builtins-utils.c:811
#, c-format
msgid "Invalid suffix: '%s'."
msgstr "Neispravan datotečni nastavak: „%s”."

#: app/flatpak-builtins-utils.c:846
#, c-format
msgid "Ambiguous column: %s"
msgstr "Dvosmislen stupac: %s"

#: app/flatpak-builtins-utils.c:859
#, c-format
msgid "Unknown column: %s"
msgstr "Nepoznati stupac: %s"

#: app/flatpak-builtins-utils.c:917
msgid "Available columns:\n"
msgstr "Dostupni stupci:\n"

#: app/flatpak-builtins-utils.c:927
msgid "Show all columns"
msgstr "Prikaži sve stupce"

#: app/flatpak-builtins-utils.c:928
msgid "Show available columns"
msgstr "Prikaži dostupne stupce"

#: app/flatpak-builtins-utils.c:931
msgid "Append :s[tart], :m[iddle], :e[nd] or :f[ull] to change ellipsization"
msgstr ""
"Dodaj :s[tart], :m[iddle], :e[nd] ili :f[ull] za mijenjanje izostavljanja"

#: app/flatpak-builtins-utils.c:1483
#, c-format
msgid "Unknown scheme in sideload location %s"
msgstr ""

#: app/flatpak-cli-transaction.c:96 app/flatpak-cli-transaction.c:102
#, c-format
msgid "Required runtime for %s (%s) found in remote %s\n"
msgstr ""
"Potrebno okruženje za %s (%s) je pronađeno u udaljenom repozitoriju %s\n"

#: app/flatpak-cli-transaction.c:104
msgid "Do you want to install it?"
msgstr "Želiš li ga instalirati?"

#: app/flatpak-cli-transaction.c:110
#, c-format
msgid "Required runtime for %s (%s) found in remotes:"
msgstr "Potrebno okruženje za %s (%s) je pronađeno u udaljenim repozitorijima:"

#: app/flatpak-cli-transaction.c:112
msgid "Which do you want to install (0 to abort)?"
msgstr "Koji želiš instalirati (0 za prekid)?"

#: app/flatpak-cli-transaction.c:132
#, fuzzy, c-format
msgid "Configuring %s as new remote '%s'\n"
msgstr "Konfiguriraj %s kao novi udaljeni repozitorij „%s”\n"

#. default to yes on Enter
#: app/flatpak-cli-transaction.c:139
#, c-format
msgid ""
"The remote '%s', referred to by '%s' at location %s contains additional "
"applications.\n"
"Should the remote be kept for future installations?"
msgstr ""
"Udaljeni repozitorij „%s”, na koji se poziva „%s” na lokaciji %s, sadrži "
"dodatne programe.\n"
"Treba li se udaljeni repozitorij čuvati za buduće instalacije?"

#. default to yes on Enter
#: app/flatpak-cli-transaction.c:147
#, c-format
msgid ""
"The application %s depends on runtimes from:\n"
"  %s\n"
"Configure this as new remote '%s'"
msgstr ""
"Program %s ovisi o okruženjima iz:\n"
"  %s\n"
"Konfiguriraj ovo kao novi udaljeni repozitorij „%s”"

#. Formatted size/remaining time in seconds
#: app/flatpak-cli-transaction.c:321
#, c-format
msgid "%s/s%s%s"
msgstr ""

#. Download progress percentage, use the appropriate
#. percent format for your language
#: app/flatpak-cli-transaction.c:359
#, c-format
msgid "%3d%%"
msgstr ""

#: app/flatpak-cli-transaction.c:414
msgid "Installing…"
msgstr "Instaliranje …"

#: app/flatpak-cli-transaction.c:416
#, c-format
msgid "Installing %d/%d…"
msgstr "Instaliranje %d/%d …"

#: app/flatpak-cli-transaction.c:421
msgid "Updating…"
msgstr "Aktualiziranje …"

#: app/flatpak-cli-transaction.c:423
#, c-format
msgid "Updating %d/%d…"
msgstr "Aktualiziranje %d/%d …"

#: app/flatpak-cli-transaction.c:428
msgid "Uninstalling…"
msgstr "Deinstaliranje …"

#: app/flatpak-cli-transaction.c:430
#, c-format
msgid "Uninstalling %d/%d…"
msgstr "Deinstaliranje %d/%d …"

#: app/flatpak-cli-transaction.c:496 app/flatpak-quiet-transaction.c:161
#, c-format
msgid "Info: %s was skipped"
msgstr "Informacija: %s je preskočeno"

#: app/flatpak-cli-transaction.c:519
#, c-format
msgid "Warning: %s%s%s already installed"
msgstr "Upozorenje: %s%s%s je već instalirano"

#: app/flatpak-cli-transaction.c:522
#, c-format
msgid "Error: %s%s%s already installed"
msgstr "Greška: %s%s%s već je instalirano"

#: app/flatpak-cli-transaction.c:528
#, c-format
msgid "Warning: %s%s%s not installed"
msgstr "Upozorenje: %s%s%s nije instalirano"

#: app/flatpak-cli-transaction.c:531
#, c-format
msgid "Error: %s%s%s not installed"
msgstr "Greška: %s%s%s nije instalirano"

#: app/flatpak-cli-transaction.c:537
#, c-format
msgid "Warning: %s%s%s needs a later flatpak version"
msgstr "Upozorenje: %s%s%s treba noviju flatpak verziju"

#: app/flatpak-cli-transaction.c:540
#, c-format
msgid "Error: %s%s%s needs a later flatpak version"
msgstr "Greška: %s%s%s treba noviju flatpak verziju"

#: app/flatpak-cli-transaction.c:546
msgid "Warning: Not enough disk space to complete this operation"
msgstr "Nema dovoljno memorije na disku za završavanje ove operacije"

#: app/flatpak-cli-transaction.c:548
msgid "Error: Not enough disk space to complete this operation"
msgstr "Nema dovoljno memorije na disku za završavanje ove operacije"

#: app/flatpak-cli-transaction.c:553
#, c-format
msgid "Warning: %s"
msgstr "Upozorenje: %s"

#: app/flatpak-cli-transaction.c:555
#, c-format
msgid "Error: %s"
msgstr "Greška: %s"

#: app/flatpak-cli-transaction.c:570
#, c-format
msgid "Failed to install %s%s%s: "
msgstr "Neuspjelo instaliranje %s%s%s: "

#: app/flatpak-cli-transaction.c:577
#, c-format
msgid "Failed to update %s%s%s: "
msgstr "Neuspjelo aktualiziranje %s%s%s: "

#: app/flatpak-cli-transaction.c:584
#, c-format
msgid "Failed to install bundle %s%s%s: "
msgstr "Neuspjelo instaliranje paketa %s%s%s: "

#: app/flatpak-cli-transaction.c:591
#, c-format
msgid "Failed to uninstall %s%s%s: "
msgstr "Neuspjelo deinstaliranje %s%s%s: "

#: app/flatpak-cli-transaction.c:642
#, c-format
msgid "Authentication required for remote '%s'\n"
msgstr "Potrebna je autentifikacija za udaljeni repozitorij „%s”\n"

#: app/flatpak-cli-transaction.c:643
msgid "Open browser?"
msgstr "Otvoriti preglednik?"

#: app/flatpak-cli-transaction.c:699
#, c-format
msgid "Login required remote %s (realm %s)\n"
msgstr "Prijava zahtijeva udaljeni repozitorij %s (domena %s)\n"

#: app/flatpak-cli-transaction.c:704
msgid "Password"
msgstr "Lozinka"

#. Only runtimes can be pinned
#: app/flatpak-cli-transaction.c:759
#, fuzzy, c-format
msgid ""
"\n"
"Info: (pinned) runtime %s%s%s branch %s%s%s is end-of-life, in favor of "
"%s%s%s branch %s%s%s\n"
msgstr "Informacija: (prikvačeno) %s//%s je kraj-života, namjesto %s\n"

#: app/flatpak-cli-transaction.c:765
#, fuzzy, c-format
msgid ""
"\n"
"Info: runtime %s%s%s branch %s%s%s is end-of-life, in favor of %s%s%s branch "
"%s%s%s\n"
msgstr "Informacija: %s//%s je kraj-života, namjesto %s\n"

#: app/flatpak-cli-transaction.c:768
#, fuzzy, c-format
msgid ""
"\n"
"Info: app %s%s%s branch %s%s%s is end-of-life, in favor of %s%s%s branch "
"%s%s%s\n"
msgstr "Informacija: %s//%s je kraj-života, namjesto %s\n"

#. Only runtimes can be pinned
#: app/flatpak-cli-transaction.c:780
#, fuzzy, c-format
msgid ""
"\n"
"Info: (pinned) runtime %s%s%s branch %s%s%s is end-of-life, with reason:\n"
msgstr "Informacija: (prikvačeno) %s//%s je kraj-životaa, s razlogom:\n"

#: app/flatpak-cli-transaction.c:786
#, fuzzy, c-format
msgid ""
"\n"
"Info: runtime %s%s%s branch %s%s%s is end-of-life, with reason:\n"
msgstr "Informacija: %s//%s je kraj-života, s razlogom:\n"

#: app/flatpak-cli-transaction.c:789
#, fuzzy, c-format
msgid ""
"\n"
"Info: app %s%s%s branch %s%s%s is end-of-life, with reason:\n"
msgstr "Informacija: %s//%s je kraj-života, s razlogom:\n"

#: app/flatpak-cli-transaction.c:963
#, c-format
msgid "Info: applications using this extension:\n"
msgstr "Informacija: aplikacije koje koriste ovo proširenje:\n"

#: app/flatpak-cli-transaction.c:965
#, c-format
msgid "Info: applications using this runtime:\n"
msgstr "Informacija: aplikacije koje koriste ovo vrijeme izvođenja:\n"

#: app/flatpak-cli-transaction.c:984
msgid "Replace?"
msgstr "Zamijeniti?"

#: app/flatpak-cli-transaction.c:987 app/flatpak-quiet-transaction.c:247
#, c-format
msgid "Updating to rebased version\n"
msgstr "Aktualiziranje na premještenu verziju\n"

#: app/flatpak-cli-transaction.c:1011
#, c-format
msgid "Failed to rebase %s to %s: "
msgstr "Neuspjelo premještanje %s na %s: "

#: app/flatpak-cli-transaction.c:1277
#, c-format
msgid "New %s%s%s permissions:"
msgstr "Nove %s%s%s dozvole:"

#: app/flatpak-cli-transaction.c:1279
#, c-format
msgid "%s%s%s permissions:"
msgstr "%s%s%s dozvole:"

#: app/flatpak-cli-transaction.c:1343
msgid "Warning: "
msgstr "Upozorenje: "

#. translators: This is short for operation, the title of a one-char column
#: app/flatpak-cli-transaction.c:1442
msgid "Op"
msgstr "Op"

#. Avoid resizing the download column too much,
#. * by making the title as long as typical content
#.
#: app/flatpak-cli-transaction.c:1458 app/flatpak-cli-transaction.c:1503
msgid "partial"
msgstr "djelomično"

#: app/flatpak-cli-transaction.c:1535
msgid "Proceed with these changes to the user installation?"
msgstr "Nastaviti s ovim promjenama na instalaciji korisnika?"

#: app/flatpak-cli-transaction.c:1537
msgid "Proceed with these changes to the system installation?"
msgstr "Nastaviti s ovim promjenama na instalaciji sustava?"

#: app/flatpak-cli-transaction.c:1539
#, c-format
msgid "Proceed with these changes to the %s?"
msgstr "Nastaviti s ovim promjenama na %s?"

#: app/flatpak-cli-transaction.c:1711
msgid "Changes complete."
msgstr "Promjene završene."

#: app/flatpak-cli-transaction.c:1713
msgid "Uninstall complete."
msgstr "Deinstaliranje završeno."

#: app/flatpak-cli-transaction.c:1715
msgid "Installation complete."
msgstr "Instaliranje završeno."

#: app/flatpak-cli-transaction.c:1717
msgid "Updates complete."
msgstr "Aktualiziranje završeno."

#. For updates/!stop_on_first_error we already printed all errors so we make up
#. a different one.
#: app/flatpak-cli-transaction.c:1750
msgid "There were one or more errors"
msgstr "Ustanovljene su neke greške"

#. translators: please keep the leading space
#: app/flatpak-main.c:76
msgid " Manage installed applications and runtimes"
msgstr " Upravljaj instaliranim programima i okruženjima"

#: app/flatpak-main.c:77
msgid "Install an application or runtime"
msgstr "Instaliraj program ili okruženje"

#: app/flatpak-main.c:78
msgid "Update an installed application or runtime"
msgstr "Instaliraj jedan instalirani program ili okruženje"

#: app/flatpak-main.c:81
msgid "Uninstall an installed application or runtime"
msgstr "Deinstaliraj jedan instalirani program ili okruženje"

#: app/flatpak-main.c:84
msgid "Mask out updates and automatic installation"
msgstr "Maskiraj aktualiziranja i automatsku instalaciju"

#: app/flatpak-main.c:85
msgid "Pin a runtime to prevent automatic removal"
msgstr "Prikvači okruženje kako bi se spriječilo automatsko uklanjanje"

#: app/flatpak-main.c:86
msgid "List installed apps and/or runtimes"
msgstr "Izradi popis instaliranih programa i/ili okruženja"

#: app/flatpak-main.c:87
msgid "Show info for installed app or runtime"
msgstr "Prikaži informacije za instalirani program ili okruženje"

#: app/flatpak-main.c:88
msgid "Show history"
msgstr "Prikaži kronologiju"

#: app/flatpak-main.c:89
msgid "Configure flatpak"
msgstr "Konfiguriraj flatpak"

#: app/flatpak-main.c:90
msgid "Repair flatpak installation"
msgstr "Popravi Flatpak instalaciju"

#: app/flatpak-main.c:91
msgid "Put applications or runtimes onto removable media"
msgstr "Stavi programe ili okurženja na prijenosne medije"

#: app/flatpak-main.c:92
msgid "Install flatpaks that are part of the operating system"
msgstr "Instaliraj flatpakove koji su dio operacijskog sustava"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:95
msgid ""
"\n"
" Find applications and runtimes"
msgstr ""
"\n"
" Pronađi programe i okruženja"

#: app/flatpak-main.c:96
msgid "Search for remote apps/runtimes"
msgstr "Traži programe/okruženja na udaljenom repozitoriju"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:99
msgid ""
"\n"
" Manage running applications"
msgstr ""
"\n"
" Upravljaj pokrenutim programima"

#: app/flatpak-main.c:100
msgid "Run an application"
msgstr "Pokreni program"

#: app/flatpak-main.c:101
msgid "Override permissions for an application"
msgstr "Nadjačaj dozvole za program"

#: app/flatpak-main.c:102
msgid "Specify default version to run"
msgstr "Odredi standardnu verziju za pokretanje"

#: app/flatpak-main.c:103
msgid "Enter the namespace of a running application"
msgstr "Upiši imenski prostor pokrenutog programa"

#: app/flatpak-main.c:104
msgid "Enumerate running applications"
msgstr "Pobroji pokrenute programe"

#: app/flatpak-main.c:105
msgid "Stop a running application"
msgstr "Zaustavi pokrenuti program"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:108
msgid ""
"\n"
" Manage file access"
msgstr ""
"\n"
" Upravljaj pristupima datotekama"

#: app/flatpak-main.c:109
msgid "List exported files"
msgstr "Izradi popis izvezenih datoteka"

#: app/flatpak-main.c:110
msgid "Grant an application access to a specific file"
msgstr "Dozvoli programu pristup određenoj datoteci"

#: app/flatpak-main.c:111
msgid "Revoke access to a specific file"
msgstr "Oduzmi dozvole za pristup određenoj datoteci"

#: app/flatpak-main.c:112
msgid "Show information about a specific file"
msgstr "Prikaži informacije o određenoj datoteci"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:116
msgid ""
"\n"
" Manage dynamic permissions"
msgstr ""
"\n"
" Upravljaj dinamičnim dozvolama"

#: app/flatpak-main.c:117
msgid "List permissions"
msgstr "Izradi popis dozvola"

#: app/flatpak-main.c:118
msgid "Remove item from permission store"
msgstr "Ukloni stavku iz spremišta dozvola"

#: app/flatpak-main.c:120
msgid "Set permissions"
msgstr "Postavi dozvole"

#: app/flatpak-main.c:121
msgid "Show app permissions"
msgstr "Prikaži dozvole programa"

#: app/flatpak-main.c:122
msgid "Reset app permissions"
msgstr "Ponovo postavi dozvole programa"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:125
msgid ""
"\n"
" Manage remote repositories"
msgstr ""
"\n"
" Upravljaj udaljenim repozitorijima"

#: app/flatpak-main.c:126
msgid "List all configured remotes"
msgstr "Izradi popis svih konfiguriranih udaljenih repozitorija"

#: app/flatpak-main.c:127
msgid "Add a new remote repository (by URL)"
msgstr "Dodaj novi udaljeni repozitorij (pomoću URL-a)"

#: app/flatpak-main.c:128
msgid "Modify properties of a configured remote"
msgstr "Promijeni svojstva konfiguriranog udaljenog repozitorija"

#: app/flatpak-main.c:129
msgid "Delete a configured remote"
msgstr "Izbriši konfiguriran udaljeni repozitorij"

#: app/flatpak-main.c:131
msgid "List contents of a configured remote"
msgstr "Izradi sadržaj konfiguriranog udaljenog okruženja"

#: app/flatpak-main.c:132
msgid "Show information about a remote app or runtime"
msgstr "Prikaži informacije o programu ili okruženju u udaljenom repozitoriju"

#. translators: please keep the leading newline and space
#: app/flatpak-main.c:135
msgid ""
"\n"
" Build applications"
msgstr ""
"\n"
" Izgradi programe"

#: app/flatpak-main.c:136
msgid "Initialize a directory for building"
msgstr "Inicijaliziraj direktorij za izgradnju"

#: app/flatpak-main.c:137
msgid "Run a build command inside the build dir"
msgstr "Pokreni naredbu za izgradnju unutar direktorija gradnje"

#: app/flatpak-main.c:138
msgid "Finish a build dir for export"
msgstr "Završi direktorij gradnje za izvoz"

#: app/flatpak-main.c:139
msgid "Export a build dir to a repository"
msgstr "Izvezi direktorij gradnje u repozitorij"

#: app/flatpak-main.c:140
msgid "Create a bundle file from a ref in a local repository"
msgstr "Stvori datoteku paketa iz reference u lokalnom repozitoriju"

#: app/flatpak-main.c:141
msgid "Import a bundle file"
msgstr "Uvezi datoteku paketa"

#: app/flatpak-main.c:142
msgid "Sign an application or runtime"
msgstr "Potpiši program ili okruženje"

#: app/flatpak-main.c:143
msgid "Update the summary file in a repository"
msgstr "Aktualiziraj datoteku sažetka u repozitoriju"

#: app/flatpak-main.c:144
msgid "Create new commit based on existing ref"
msgstr "Izradi novu izmjenu na osnovi postojeće reference"

#: app/flatpak-main.c:145
msgid "Show information about a repo"
msgstr "Prikaži informacije o repozitoriju"

#: app/flatpak-main.c:162
msgid "Show debug information, -vv for more detail"
msgstr "Prikaži informacije pronalaženja grešaka, -vv za više detalja"

#: app/flatpak-main.c:163
msgid "Show OSTree debug information"
msgstr "Prikaži OSTree informacije pronalaženja grešaka"

#: app/flatpak-main.c:169
msgid "Print version information and exit"
msgstr "Ispiši informacije o verziji i izađi"

#: app/flatpak-main.c:170
msgid "Print default arch and exit"
msgstr "Ispiši standardnu arhitekturu i izađi"

#: app/flatpak-main.c:171
msgid "Print supported arches and exit"
msgstr "Ispiši podržane arhitekture i izađi"

#: app/flatpak-main.c:172
msgid "Print active gl drivers and exit"
msgstr "Ispiši aktivne gl upravljačke programe i izađi"

#: app/flatpak-main.c:173
msgid "Print paths for system installations and exit"
msgstr "Ispiši stazu za instalacije sustava i izađi"

#: app/flatpak-main.c:174
msgid "Print the updated environment needed to run flatpaks"
msgstr "Ispiši aktualizirano okruženje potrebno za pokretanje flatpaksa"

#: app/flatpak-main.c:175
msgid "Only include the system installation with --print-updated-env"
msgstr "Uključi samo instalaciju sustava s --print-updated-env"

#: app/flatpak-main.c:180
msgid "Work on the user installation"
msgstr "Radi na korisničkoj instalaciji"

#: app/flatpak-main.c:181
msgid "Work on the system-wide installation (default)"
msgstr "Radi na sustavskoj instalaciji (standardno)"

#: app/flatpak-main.c:182
msgid "Work on a non-default system-wide installation"
msgstr "Radi na ne-standardnoj sustavskoj instalaciji"

#: app/flatpak-main.c:212
msgid "Builtin Commands:"
msgstr "Ugrađene naredbe:"

#: app/flatpak-main.c:298
#, c-format
msgid ""
"Note that the directories %s are not in the search path set by the "
"XDG_DATA_DIRS environment variable, so applications installed by Flatpak may "
"not appear on your desktop until the session is restarted."
msgstr ""
"Imaj na umu da se direktoriji %s ne nalaze u stazi pretraživanja koju je "
"zadala XDG_DATA_DIRS varijabla okruženja, tako da se Flatpakom instalirani "
"programi možda neće pojaviti na radnoj površini, sve dok se sesija ponovo ne "
"pokrene."

#: app/flatpak-main.c:312
#, c-format
msgid ""
"Note that the directory %s is not in the search path set by the "
"XDG_DATA_DIRS environment variable, so applications installed by Flatpak may "
"not appear on your desktop until the session is restarted."
msgstr ""
"Imaj na umu da se direktorij %s ne nalazi u stazi pretraživanja koju je "
"zadala XDG_DATA_DIRS varijabla okruženja, tako da se Flatpakom instalirani "
"programi možda neće pojaviti na radnoj površini, sve dok se sesija ponovo ne "
"pokrene."

#: app/flatpak-main.c:381
msgid ""
"Refusing to operate under sudo with --user. Omit sudo to operate on the user "
"installation, or use a root shell to operate on the root user's installation."
msgstr ""

#: app/flatpak-main.c:453
msgid ""
"Multiple installations specified for a command that works on one installation"
msgstr ""
"Višestruke instalacije određene za naredbu koja radi na jednoj instalaciji"

#: app/flatpak-main.c:504 app/flatpak-main.c:697
#, c-format
msgid "See '%s --help'"
msgstr "Pogledaj „%s --help”"

#: app/flatpak-main.c:706
#, c-format
msgid "'%s' is not a flatpak command. Did you mean '%s%s'?"
msgstr "„%s” nije flatpak naredba. Misliš možda na „%s%s”?"

#: app/flatpak-main.c:709
#, c-format
msgid "'%s' is not a flatpak command"
msgstr "„%s” nije flatpak naredba"

#: app/flatpak-main.c:824
msgid "No command specified"
msgstr "Nijedna naredba nije određena"

#: app/flatpak-main.c:980
msgid "error:"
msgstr "greška:"

#: app/flatpak-quiet-transaction.c:77
#, c-format
msgid "Installing %s\n"
msgstr "Instaliranje programa %s\n"

#: app/flatpak-quiet-transaction.c:81
#, c-format
msgid "Updating %s\n"
msgstr "Aktualiziranje %s\n"

#: app/flatpak-quiet-transaction.c:85
#, c-format
msgid "Uninstalling %s\n"
msgstr "Deinstaliranje %s\n"

#: app/flatpak-quiet-transaction.c:107
#, c-format
msgid "Warning: Failed to install %s: %s\n"
msgstr "Greška: Neuspjelo intaliranje %s: %s\n"

#: app/flatpak-quiet-transaction.c:110
#, c-format
msgid "Error: Failed to install %s: %s\n"
msgstr "Greška: Neuspjelo intaliranje %s: %s\n"

#: app/flatpak-quiet-transaction.c:116
#, c-format
msgid "Warning: Failed to update %s: %s\n"
msgstr "Greška: Neuspjelo aktualiziranje %s: %s\n"

#: app/flatpak-quiet-transaction.c:119
#, c-format
msgid "Error: Failed to update %s: %s\n"
msgstr "Greška: Neuspjelo aktualiziranje %s: %s\n"

#: app/flatpak-quiet-transaction.c:125
#, c-format
msgid "Warning: Failed to install bundle %s: %s\n"
msgstr "Greška: Neuspjelo intaliranje paketa %s: %s\n"

#: app/flatpak-quiet-transaction.c:128
#, c-format
msgid "Error: Failed to install bundle %s: %s\n"
msgstr "Greška: Neuspjelo intaliranje paketa %s: %s\n"

#: app/flatpak-quiet-transaction.c:134
#, c-format
msgid "Warning: Failed to uninstall %s: %s\n"
msgstr "Greška: Neuspjelo deintaliranje %s: %s\n"

#: app/flatpak-quiet-transaction.c:137
#, c-format
msgid "Error: Failed to uninstall %s: %s\n"
msgstr "Greška: Neuspjelo deintaliranje %s: %s\n"

#: app/flatpak-quiet-transaction.c:166 common/flatpak-dir.c:11475
#, c-format
msgid "%s already installed"
msgstr "%s već instalirano"

#: app/flatpak-quiet-transaction.c:168 common/flatpak-dir.c:3622
#: common/flatpak-dir.c:4321 common/flatpak-dir.c:16968
#: common/flatpak-dir.c:17258 common/flatpak-dir-utils.c:166
#: common/flatpak-dir-utils.c:259 common/flatpak-transaction.c:2736
#: common/flatpak-transaction.c:2791
#, c-format
msgid "%s not installed"
msgstr "%s još nije instalirano"

#: app/flatpak-quiet-transaction.c:170
#, c-format
msgid "%s needs a later flatpak version"
msgstr "%s treba noviju flatpak verziju"

#: app/flatpak-quiet-transaction.c:172
msgid "Not enough disk space to complete this operation"
msgstr "Nema dovoljno prostora na disku za završavanje ove operacije"

#: app/flatpak-quiet-transaction.c:239
#, c-format
msgid "Info: %s is end-of-life, in favor of %s\n"
msgstr "Informacija: %s je kraj-života, namjesto %s\n"

#: app/flatpak-quiet-transaction.c:241
#, c-format
msgid "Info: %s is end-of-life, with reason: %s\n"
msgstr "Informacija: %s je kraj-života, s razlogom: %s\n"

#: app/flatpak-quiet-transaction.c:251
#, c-format
msgid "Failed to rebase %s to %s: %s\n"
msgstr "Neuspjelo premještanje %s na %s: %s\n"

#: common/flatpak-auth.c:58
#, c-format
msgid "No authenticator configured for remote `%s`"
msgstr "Nijedan autentifikator nije konfiguriran za udaljeni repozitorij „%s”"

#: common/flatpak-context.c:637 common/flatpak-context.c:649
#, c-format
msgid "Invalid permission syntax: %s"
msgstr "Neispravna sintaksa dozvola: %s"

#: common/flatpak-context.c:1207
#, c-format
msgid "Unknown share type %s, valid types are: %s"
msgstr "Nepoznata vrsta dijeljenja %s, ispravne vrijednosti su: %s"

#: common/flatpak-context.c:1228
#, c-format
msgid "Unknown policy type %s, valid types are: %s"
msgstr "Nepoznata vrsta pravila %s, ispravne vrijednosti su: %s"

#: common/flatpak-context.c:1266
#, c-format
msgid "Invalid dbus name %s"
msgstr "Neispravno dbus ime %s"

#: common/flatpak-context.c:1279
#, c-format
msgid "Unknown socket type %s, valid types are: %s"
msgstr "Nepoznata vrsta utičnice %s, ispravne vrijednosti su: %s"

#: common/flatpak-context.c:1294
#, c-format
msgid "Unknown device type %s, valid types are: %s"
msgstr "Nepoznata vrsta uređaja %s, ispravne vrijednosti su: %s"

#: common/flatpak-context.c:1308
#, c-format
msgid "Unknown feature type %s, valid types are: %s"
msgstr "Nepoznata vrsta funkcije %s, ispravne vrijednosti su: %s"

#: common/flatpak-context.c:1840
#, c-format
msgid "Filesystem location \"%s\" contains \"..\""
msgstr "Nepoznata lokacija „%s” datotečnog sustava sadrži „..”"

#: common/flatpak-context.c:1882
#, c-format
msgid ""
"--filesystem=/ is not available, use --filesystem=host for a similar result"
msgstr ""
"--filesystem=/ nije dostupno, koristi --filesystem=host za sličan rezultat"

#: common/flatpak-context.c:1916
#, fuzzy, c-format
msgid ""
"Unknown filesystem location %s, valid locations are: host, host-os, host-"
"etc, host-root, home, xdg-*[/…], ~/dir, /dir"
msgstr ""
"Nepoznata lokacija %s datotečnog sustava, ispravne lokacije su: host, host-"
"os, host-etc, home, xdg-*[/…], ~/dir, /dir"

#: common/flatpak-context.c:2015
#, c-format
msgid "Invalid syntax for %s: %s"
msgstr "Neispravna sintaksa za %s: %s"

#: common/flatpak-context.c:2142
#, c-format
msgid "fallback-x11 can not be conditional"
msgstr "rezervni x11 ne može biti uvjetan"

#: common/flatpak-context.c:2318
#, c-format
msgid "Invalid env format %s"
msgstr "Neispravan format okruženja %s"

#: common/flatpak-context.c:2399
#, c-format
msgid "Environment variable name must not contain '=': %s"
msgstr "Ime varijable okruženja ne smije sadržavati '=': %s"

#: common/flatpak-context.c:2527 common/flatpak-context.c:2535
#, c-format
msgid "--add-policy arguments must be in the form SUBSYSTEM.KEY=VALUE"
msgstr "--add-policy argumenti moraju biti u obliku PODSUSTAV.KLJUČ=VRIJEDNOST"

#: common/flatpak-context.c:2542
#, c-format
msgid "--add-policy values can't start with \"!\""
msgstr "--add-policy vrijednosti ne smiju započeti s uskličnikom (!)"

#: common/flatpak-context.c:2567 common/flatpak-context.c:2575
#, c-format
msgid "--remove-policy arguments must be in the form SUBSYSTEM.KEY=VALUE"
msgstr ""
"--remove-policy argumenti moraju biti u obliku PODSUSTAV.KLJUČ=VRIJEDNOST"

#: common/flatpak-context.c:2582
#, c-format
msgid "--remove-policy values can't start with \"!\""
msgstr "--remove-policy vrijednosti ne smiju započeti s uskličnikom (!)"

#: common/flatpak-context.c:2657
msgid "Share with host"
msgstr "Dijeli s računalom"

#: common/flatpak-context.c:2657 common/flatpak-context.c:2658
msgid "SHARE"
msgstr "DIJELI"

#: common/flatpak-context.c:2658
msgid "Unshare with host"
msgstr "Prekini dijeliti s računalom"

#: common/flatpak-context.c:2659
msgid "Require conditions to be met for a subsystem to get shared"
msgstr ""

#: common/flatpak-context.c:2659
#, fuzzy
msgid "SHARE:CONDITION"
msgstr "UREĐAJ:STANJE"

#: common/flatpak-context.c:2660
msgid "Expose socket to app"
msgstr "Omogući programu vidjeti utičnicu"

#: common/flatpak-context.c:2660 common/flatpak-context.c:2661
msgid "SOCKET"
msgstr "UTIČNICA"

#: common/flatpak-context.c:2661
msgid "Don't expose socket to app"
msgstr "Onemogući programu vidjeti utičnicu"

#: common/flatpak-context.c:2662
msgid "Require conditions to be met for a socket to get exposed"
msgstr ""

#: common/flatpak-context.c:2662
#, fuzzy
msgid "SOCKET:CONDITION"
msgstr "UREĐAJ:STANJE"

#: common/flatpak-context.c:2663
msgid "Expose device to app"
msgstr "Omogući programu vidjeti uređaj"

#: common/flatpak-context.c:2663 common/flatpak-context.c:2664
msgid "DEVICE"
msgstr "UREĐAJ"

#: common/flatpak-context.c:2664
msgid "Don't expose device to app"
msgstr "Onemogući programu vidjeti uređaj"

#: common/flatpak-context.c:2665
msgid "Require conditions to be met for a device to get exposed"
msgstr ""

#: common/flatpak-context.c:2665
msgid "DEVICE:CONDITION"
msgstr "UREĐAJ:STANJE"

#: common/flatpak-context.c:2666
msgid "Allow feature"
msgstr "Dozvoli funkciju"

#: common/flatpak-context.c:2666 common/flatpak-context.c:2667
msgid "FEATURE"
msgstr "FUNKCIJA"

#: common/flatpak-context.c:2667
msgid "Don't allow feature"
msgstr "Nemoj dozvoliti funkciju"

#: common/flatpak-context.c:2668
msgid "Require conditions to be met for a feature to get allowed"
msgstr ""

#: common/flatpak-context.c:2668
#, fuzzy
msgid "FEATURE:CONDITION"
msgstr "UREĐAJ:STANJE"

#: common/flatpak-context.c:2669
msgid "Expose filesystem to app (:ro for read-only)"
msgstr "Omogući programu vidjeti datotečni sustav (:ro za samo-za-čitanje)"

#: common/flatpak-context.c:2669
msgid "FILESYSTEM[:ro]"
msgstr "DATOTEČNI-SUSTAV[:ro]"

#: common/flatpak-context.c:2670
msgid "Don't expose filesystem to app"
msgstr "Onemogući programu vidjeti datotečni sustav"

#: common/flatpak-context.c:2670
msgid "FILESYSTEM"
msgstr "DATOTEČNI-SUSTAV"

#: common/flatpak-context.c:2671
msgid "Set environment variable"
msgstr "Postavi varijablu okruženja"

#: common/flatpak-context.c:2671
msgid "VAR=VALUE"
msgstr "VARIJABLA=VRIJEDNOST"

#: common/flatpak-context.c:2672
msgid "Read environment variables in env -0 format from FD"
msgstr "Čitaj varijable okruženja u env -0 formatu iz FD-a"

#: common/flatpak-context.c:2673
msgid "Remove variable from environment"
msgstr "Ukloni varijablu iz okruženja"

#: common/flatpak-context.c:2673
msgid "VAR"
msgstr "VARIJABLA"

#: common/flatpak-context.c:2674
msgid "Allow app to own name on the session bus"
msgstr "Dozvoli programu posjedovati ime na busu sesije"

#: common/flatpak-context.c:2674 common/flatpak-context.c:2675
#: common/flatpak-context.c:2676 common/flatpak-context.c:2677
#: common/flatpak-context.c:2678 common/flatpak-context.c:2679
#: common/flatpak-context.c:2680
msgid "DBUS_NAME"
msgstr "DBUS_IME"

#: common/flatpak-context.c:2675
msgid "Allow app to talk to name on the session bus"
msgstr "Dozvoli programu komunicirati s imenom na busu sesije"

#: common/flatpak-context.c:2676
msgid "Don't allow app to talk to name on the session bus"
msgstr "Nemoj dozvoliti programu komunicirati s imenom na busu sesije"

#: common/flatpak-context.c:2677
msgid "Allow app to own name on the system bus"
msgstr "Dozvoli programu posjedovati ime na busu sustava"

#: common/flatpak-context.c:2678
msgid "Allow app to talk to name on the system bus"
msgstr "Dozvoli programu komunicirati s imenom na busu sustava"

#: common/flatpak-context.c:2679
msgid "Don't allow app to talk to name on the system bus"
msgstr "Nemoj dozvoliti programu komunicirati s imenom na busu sustava"

#: common/flatpak-context.c:2680
#, fuzzy
msgid "Allow app to own name on the a11y bus"
msgstr "Dozvoli programu posjedovati ime na busu sustava"

#: common/flatpak-context.c:2681
msgid "Add generic policy option"
msgstr "Dodaj opću opciju pravila"

#: common/flatpak-context.c:2681 common/flatpak-context.c:2682
msgid "SUBSYSTEM.KEY=VALUE"
msgstr "PODSUSTAV.KLJUČ=VRIJEDNOST"

#: common/flatpak-context.c:2682
msgid "Remove generic policy option"
msgstr "Ukloni opću opciju pravila"

#: common/flatpak-context.c:2683
msgid "Add USB device to enumerables"
msgstr ""

#: common/flatpak-context.c:2683 common/flatpak-context.c:2684
msgid "VENDOR_ID:PRODUCT_ID"
msgstr ""

#: common/flatpak-context.c:2684
msgid "Add USB device to hidden list"
msgstr "Dodaj USB uređaj u skriveni popis"

#: common/flatpak-context.c:2685
msgid "A list of USB devices that are enumerable"
msgstr ""

#: common/flatpak-context.c:2685
msgid "LIST"
msgstr "POPIS"

#: common/flatpak-context.c:2686
msgid "File containing a list of USB devices to make enumerable"
msgstr ""

#: common/flatpak-context.c:2686 common/flatpak-context.c:2687
msgid "FILENAME"
msgstr "IME-DATOTEKE"

#: common/flatpak-context.c:2687
msgid "Persist home directory subpath"
msgstr "Neka podstaza osnovnog direktorija postane trajna"

#. This is not needed/used anymore, so hidden, but we accept it for backwards compat
#: common/flatpak-context.c:2689
msgid "Don't require a running session (no cgroups creation)"
msgstr "Ne zahtijevaj pokrenutu sesiju (cgroups se ne izrađuje)"

#: common/flatpak-context.c:3718
#, c-format
msgid "Not replacing \"%s\" with tmpfs: %s"
msgstr ""

#: common/flatpak-context.c:3726
#, c-format
msgid "Not sharing \"%s\" with sandbox: %s"
msgstr ""

#. Even if the error is one that we would normally silence, like
#. * the path not existing, it seems reasonable to make more of a fuss
#. * about the home directory not existing or otherwise being unusable,
#. * so this is intentionally not using cannot_export()
#: common/flatpak-context.c:3828
#, c-format
msgid "Not allowing home directory access: %s"
msgstr ""

#: common/flatpak-context.c:4062
#, fuzzy, c-format
msgid "Unable to provide a temporary home directory in the sandbox: %s"
msgstr "Nije moguće stvoriti privremeni direktorij u %s"

#: common/flatpak-dir.c:442
#, c-format
msgid "Configured collection ID ‘%s’ not in summary file"
msgstr "Kongiurirani ID „%s” zbirke, nije u datoteci sažetka"

#: common/flatpak-dir.c:587
#, c-format
msgid "Unable to load summary from remote %s: %s"
msgstr "Nije moguće učitati sažetak s udaljenog repozitorija %s: %s"

#: common/flatpak-dir.c:764 common/flatpak-dir.c:800 common/flatpak-dir.c:906
#, c-format
msgid "No such ref '%s' in remote %s"
msgstr "Nema ovakve reference „%s” u udaljenom repozitoriju %s"

#: common/flatpak-dir.c:891 common/flatpak-dir.c:1051 common/flatpak-dir.c:1080
#: common/flatpak-dir.c:1092
#, fuzzy, c-format
msgid "No entry for %s in remote %s summary flatpak cache"
msgstr ""
"Nema unosa za %s u sažetku flatpak predmemorije udaljenog repozitorija „%s” "

#: common/flatpak-dir.c:1069
#, c-format
msgid "No summary or Flatpak cache available for remote %s"
msgstr "Nema sažetka ili Flatpak predmemorije za udaljeni repozitorij „%s”"

#: common/flatpak-dir.c:1097
#, c-format
msgid "Missing xa.data in summary for remote %s"
msgstr "Nedostaje xa.data u sažetku za udaljeni repozitorij „%s”"

#: common/flatpak-dir.c:1103 common/flatpak-dir.c:1546
#, c-format
msgid "Unsupported summary version %d for remote %s"
msgstr "Nepodržana verzija %d sažetka za udaljeni repozitorij „%s”"

#: common/flatpak-dir.c:1200
msgid "Remote OCI index has no registry uri"
msgstr "OCI indeks udaljenog repozitorija nema uri registra"

#: common/flatpak-dir.c:1261
#, c-format
msgid "Couldn't find ref %s in remote %s"
msgstr "Nije moguće pronaći referencu %s u udaljenom repozitoriju %s"

#: common/flatpak-dir.c:1288 common/flatpak-dir.c:1381
#, fuzzy, c-format
msgid "Commit has no requested ref ‘%s’ in ref binding metadata (found: ‘%s’)"
msgstr ""
"Izmjena nema zatraženu referencu „%s” u metapodacima za povezivanje reference"

#: common/flatpak-dir.c:1413
#, c-format
msgid "Configured collection ID ‘%s’ not in binding metadata"
msgstr "Kongiurirani ID „%s” zbirke, nije u metapodacima za povezivanje"

#: common/flatpak-dir.c:1449 common/flatpak-dir.c:5645
#, c-format
msgid "Couldn't find latest checksum for ref %s in remote %s"
msgstr ""
"Nije moguće pronaći najnoviji kontrolni zbroj za referencu %s u udaljenom "
"repozitoriju %s"

#: common/flatpak-dir.c:1516 common/flatpak-dir.c:1552
#, fuzzy, c-format
msgid "No entry for %s in remote %s summary flatpak sparse cache"
msgstr ""
"Nema unosa za %s u sažetku prorijeđene flatpak predmemorije udaljenog "
"repozitorija "

#: common/flatpak-dir.c:2540
#, c-format
msgid "Commit metadata for %s not matching expected metadata"
msgstr "Metapodaci izmjene za %s ne poklapaju se s očekivanim metapodacima"

#: common/flatpak-dir.c:2823
msgid "Unable to connect to system bus"
msgstr "Nije moguće povezati se na bus sustava"

#: common/flatpak-dir.c:3419
msgid "User installation"
msgstr "Korisnička instalacija"

#: common/flatpak-dir.c:3426
#, c-format
msgid "System (%s) installation"
msgstr "Instalacija sustava (%s)"

#: common/flatpak-dir.c:3472
#, c-format
msgid "No overrides found for %s"
msgstr "Nema nadjačavanja za %s"

#: common/flatpak-dir.c:3625
#, c-format
msgid "%s (commit %s) not installed"
msgstr "%s (izmjena %s) nije instalirano"

#: common/flatpak-dir.c:4650
#, c-format
msgid "Error parsing system flatpakrepo file for %s: %s"
msgstr "Greška prilikom obrade sustavske datoteke flatpak repozitorija %s: %s"

#: common/flatpak-dir.c:4735
#, c-format
msgid "While opening repository %s: "
msgstr "Prilikom otvaranja repozitorija %s: "

#: common/flatpak-dir.c:5004
#, c-format
msgid "The config key %s is not set"
msgstr "Konfiguracijski ključ %s nije postavljen"

#: common/flatpak-dir.c:5140
#, c-format
msgid "No current %s pattern matching %s"
msgstr "Nijedan se trenutačni uzorak %s ne poklapa s %s"

#: common/flatpak-dir.c:5422
msgid "No appstream commit to deploy"
msgstr "Nema appstream izmjene za implementiranje"

#: common/flatpak-dir.c:5941 common/flatpak-dir.c:7266
#: common/flatpak-dir.c:10881 common/flatpak-dir.c:11618
msgid "Can't pull from untrusted non-gpg verified remote"
msgstr ""
"Nije moguće povući s nepouzdanog ne-gpg provjerenog udaljenog repozitorija"

#: common/flatpak-dir.c:6376 common/flatpak-dir.c:6591
msgid "Extra data not supported for non-gpg-verified local system installs"
msgstr ""
"Dodatni podaci nisu podržani za ne-gpg provjerene lokalne sustavske "
"instalacije"

#: common/flatpak-dir.c:6415 common/flatpak-dir.c:6782
#, c-format
msgid "Invalid checksum for extra data uri %s"
msgstr "Neispravan kontrolni zbroj za uri dodatnih podataka %s"

#: common/flatpak-dir.c:6424
#, c-format
msgid "Empty name for extra data uri %s"
msgstr "Prazno ime za uri dodatnih podataka %s"

#: common/flatpak-dir.c:6432
#, c-format
msgid "Unsupported extra data uri %s"
msgstr "URI nepodržanih dodatnih podataka %s"

#: common/flatpak-dir.c:6461
#, c-format
msgid "Failed to load local extra-data %s: %s"
msgstr "Neuspjelo učitavanje lokalnih extra-data (dodatnih podataka) %s: %s"

#: common/flatpak-dir.c:6469
#, c-format
msgid "Wrong size for extra-data %s"
msgstr "Kriva veličina za extra-data %s"

#: common/flatpak-dir.c:6488
#, c-format
msgid "While downloading %s: "
msgstr "Prilikom preuzimanja %s: "

#: common/flatpak-dir.c:6498
#, c-format
msgid "Wrong size for extra data %s"
msgstr "Kriva veličina za dodatne podatke %s"

#: common/flatpak-dir.c:6507
#, c-format
msgid "Invalid checksum for extra data %s"
msgstr "Neispravan kontrolni zbroj za dodatne podatke %s"

#: common/flatpak-dir.c:7096 common/flatpak-dir.c:7349
#, c-format
msgid "While pulling %s from remote %s: "
msgstr "Prilikom povlačenja %s s udaljenog repozitorija %s: "

#: common/flatpak-dir.c:7290 common/flatpak-repo-utils.c:3886
msgid "GPG signatures found, but none are in trusted keyring"
msgstr ""
"GPG potpisi su pronađeni, ali niti jedan se ne nalazi u pouzdanom privjesku "
"za ključeve"

#: common/flatpak-dir.c:7307
#, c-format
msgid "Commit for ‘%s’ has no ref binding"
msgstr "Izmjena za „%s” nema povezivanje s referencom"

#: common/flatpak-dir.c:7312
#, c-format
msgid "Commit for ‘%s’ is not in expected bound refs: %s"
msgstr "Izmjena za „%s” nije u očekivanoj povezanoj referenci: %s"

#: common/flatpak-dir.c:7488
msgid "Only applications can be made current"
msgstr "Samo se programi mogu izraditi kao trenutačni"

#: common/flatpak-dir.c:8192
msgid "Not enough memory"
msgstr "Nedovoljno memorije"

#: common/flatpak-dir.c:8211
msgid "Failed to read from exported file"
msgstr "Neuspjelo čitanje iz izvezene datoteke"

#: common/flatpak-dir.c:8401
msgid "Error reading mimetype xml file"
msgstr "Greška pri čitanju mimetype xml datoteke"

#: common/flatpak-dir.c:8406
msgid "Invalid mimetype xml file"
msgstr "Neispravni mimetype xml datoteke"

#: common/flatpak-dir.c:8492
#, c-format
msgid "D-Bus service file '%s' has wrong name"
msgstr "Datoteka „%s” D-Bus usluge ima krivo ime"

#: common/flatpak-dir.c:8647
#, c-format
msgid "Invalid Exec argument %s"
msgstr "Neispravni Exec argument %s"

#: common/flatpak-dir.c:9115
msgid "While getting detached metadata: "
msgstr "Prilikom dohvaćanja nespojenih metapodataka: "

#: common/flatpak-dir.c:9120 common/flatpak-dir.c:9125
#: common/flatpak-dir.c:9129
msgid "Extra data missing in detached metadata"
msgstr "Dodatni podaci nedostaju u odspojenim metapodacima"

#: common/flatpak-dir.c:9133
msgid "While creating extradir: "
msgstr "Prilikom stvaranja dodatnog direktorija: "

#: common/flatpak-dir.c:9154 common/flatpak-dir.c:9187
msgid "Invalid checksum for extra data"
msgstr "Neispravan kontrolni zbroj za dodatne podatke"

#: common/flatpak-dir.c:9183
msgid "Wrong size for extra data"
msgstr "Kriva veličina za dodatne podatke"

#: common/flatpak-dir.c:9196
#, c-format
msgid "While writing extra data file '%s': "
msgstr "Prilikom pisanja datoteke dodatnih podataka „%s”: "

#: common/flatpak-dir.c:9204
#, c-format
msgid "Extra data %s missing in detached metadata"
msgstr "Dodatni podaci %s nedostaju u odspojenim metapodacima"

#: common/flatpak-dir.c:9278
#, fuzzy, c-format
msgid "Unable to get runtime key from metadata"
msgstr "Koristi alternativne datoteka za metapodatke"

#: common/flatpak-dir.c:9402
#, c-format
msgid "apply_extra script failed, exit status %d"
msgstr "apply_extra skripta neuspjela, stanje izlaza %d"

#. Translators: The placeholder is for an app ref.
#: common/flatpak-dir.c:9591
#, c-format
msgid "Installing %s is not allowed by the policy set by your administrator"
msgstr ""
"Instaliranje programa %s nije dozvoljeno na osnovi administratorskih pravila"

#: common/flatpak-dir.c:9690
#, c-format
msgid "While trying to resolve ref %s: "
msgstr "Prilikom pokušaja rješavanja referene %s: "

#: common/flatpak-dir.c:9702
#, c-format
msgid "%s is not available"
msgstr "%s nije dostupan"

#: common/flatpak-dir.c:9714 common/flatpak-dir.c:11495
#, c-format
msgid "%s commit %s already installed"
msgstr "%s izmjena %s već instalirano"

#: common/flatpak-dir.c:9721
msgid "Can't create deploy directory"
msgstr "Nije moguće stvoriti direktorij za implementaciju"

#: common/flatpak-dir.c:9729
#, c-format
msgid "Failed to read commit %s: "
msgstr "Neuspjelo čitanje izmjene %s: "

#: common/flatpak-dir.c:9750
#, c-format
msgid "While trying to checkout %s into %s: "
msgstr "Prilikom pokušaja mijenjanja %s u %s: "

#: common/flatpak-dir.c:9769
msgid "While trying to checkout metadata subpath: "
msgstr "Prilikom pokušaja mijenjanja podstaze metapodataka: "

#: common/flatpak-dir.c:9801
#, c-format
msgid "While trying to checkout subpath ‘%s’: "
msgstr "Prilikom pokušaja mijenjanja podstaze „%s”: "

#: common/flatpak-dir.c:9811
msgid "While trying to remove existing extra dir: "
msgstr "Prilikom pokušaja uklanjanja postojećeg dodatnog direktorija: "

#: common/flatpak-dir.c:9822
msgid "While trying to apply extra data: "
msgstr "Prilikom pokušaja primjenjivanja dodatnih podataka: "

#: common/flatpak-dir.c:9849
#, c-format
msgid "Invalid commit ref %s: "
msgstr "Neispravna referenca izmjene %s: "

#: common/flatpak-dir.c:9857 common/flatpak-dir.c:9869
#, c-format
msgid "Deployed ref %s does not match commit (%s)"
msgstr "Implementirana referenca %s ne se poklapa s izmjenom (%s)"

#: common/flatpak-dir.c:9863
#, c-format
msgid "Deployed ref %s branch does not match commit (%s)"
msgstr "Grana implementirane reference %s ne se poklapa s izmjenom (%s)"

#: common/flatpak-dir.c:10125 common/flatpak-installation.c:1911
#, c-format
msgid "%s branch %s already installed"
msgstr "%s grana %s već instalirano"

#: common/flatpak-dir.c:10985
#, c-format
msgid "Could not unmount revokefs-fuse filesystem at %s: "
msgstr "Nije bilo moguće odspojiti datotečni sustav revokefs-fuse na %s: "

#: common/flatpak-dir.c:11289
#, c-format
msgid "This version of %s is already installed"
msgstr "Ova %s verzija je već instalirana"

#: common/flatpak-dir.c:11302
#, c-format
msgid "Can't change remote during bundle install"
msgstr ""
"Nije moguće promijeniti udaljeni repozitorij tijekom instaliranja paketa"

#: common/flatpak-dir.c:11571
msgid "Can't update to a specific commit without root permissions"
msgstr ""
"Nije moguće aktualizirati određenu izmjenu bez administratorskih dozvola"

#: common/flatpak-dir.c:11852
#, c-format
msgid "Can't remove %s, it is needed for: %s"
msgstr "Nije moguće ukloniti %s, mora postojati za: %s"

#: common/flatpak-dir.c:11912 common/flatpak-installation.c:2067
#, c-format
msgid "%s branch %s is not installed"
msgstr "%s grana %s nije instalirano"

#: common/flatpak-dir.c:12165
#, c-format
msgid "%s commit %s not installed"
msgstr "%s izmjena %s nije instalirano"

#: common/flatpak-dir.c:12501
#, c-format
msgid "Pruning repo failed: %s"
msgstr "Odrezivanje repozitorija neuspjelo: %s"

#: common/flatpak-dir.c:12669 common/flatpak-dir.c:12675
#, c-format
msgid "Failed to load filter '%s'"
msgstr "Neuspjelo učitavanje filtra „%s”"

#: common/flatpak-dir.c:12681
#, c-format
msgid "Failed to parse filter '%s'"
msgstr "Neuspjela obrada filtra „%s”"

#: common/flatpak-dir.c:12963
msgid "Failed to write summary cache: "
msgstr "Neuspjelo zapisivanje predmemorije sažetka: "

#: common/flatpak-dir.c:12982
#, c-format
msgid "No oci summary cached for remote '%s'"
msgstr "Nema oci sažetka u predmemoriji za udaljeni repozitorij „%s”"

#: common/flatpak-dir.c:13207
#, c-format
msgid "No cached summary for remote '%s'"
msgstr "Nema predmemoriranog sažetka za udaljeni repozitorij „%s”"

#: common/flatpak-dir.c:13248
#, c-format
msgid "Invalid checksum for indexed summary %s read from %s"
msgstr "Neispravan kontrolni zbroj za indeksirani sažetak %s učitan od %s"

#: common/flatpak-dir.c:13321
#, c-format
msgid ""
"Remote listing for %s not available; server has no summary file. Check the "
"URL passed to remote-add was valid."
msgstr ""
"Popis za %s na udaljenom repozitoriju nije dostupan: poslužitelj nema "
"datoteku sažetka. Provjeri ispravnost URL-a za remote-add."

#: common/flatpak-dir.c:13698
#, c-format
msgid "Invalid checksum for indexed summary %s for remote '%s'"
msgstr ""
"Neispravan kontrolni zbroj za indeksirani sažetak %s za udaljeni repozitorij "
"„%s”"

#: common/flatpak-dir.c:14388
#, c-format
msgid "Multiple branches available for %s, you must specify one of: "
msgstr "Dostupne su višestruke grane za %s, moraš odrediti jednu od: "

#: common/flatpak-dir.c:14454
#, c-format
msgid "Nothing matches %s"
msgstr "Ništa se ne poklapa s %s"

#: common/flatpak-dir.c:14562
#, c-format
msgid "Can't find ref %s%s%s%s%s"
msgstr "Nije moguće naći referencu %s%s%s%s%s"

#: common/flatpak-dir.c:14605
#, c-format
msgid "Error searching remote %s: %s"
msgstr "Greška pri traženju udaljenog repozitorija %s: %s"

#: common/flatpak-dir.c:14702
#, c-format
msgid "Error searching local repository: %s"
msgstr "Greška pri traženju lokalnog repozitorija: %s"

#: common/flatpak-dir.c:14839
#, c-format
msgid "%s/%s/%s not installed"
msgstr "%s/%s/%s nije instalirano"

#: common/flatpak-dir.c:15042
#, c-format
msgid "Could not find installation %s"
msgstr "Nije bilo moguće naći instalaciju %s"

#: common/flatpak-dir.c:15612
#, c-format
msgid "Invalid file format, no %s group"
msgstr "Neispravan datotečni format, nema %s grupe"

#: common/flatpak-dir.c:15617 common/flatpak-repo-utils.c:2836
#, c-format
msgid "Invalid version %s, only 1 supported"
msgstr "Neispravna verzija %s, podržava se samo 1"

#: common/flatpak-dir.c:15622 common/flatpak-dir.c:15627
#, c-format
msgid "Invalid file format, no %s specified"
msgstr "Neispravan datotečni format, %s nije određen"

#. Check some minimal size so we don't get crap
#: common/flatpak-dir.c:15647
msgid "Invalid file format, gpg key invalid"
msgstr "Neispravan datotečni format, gpg ključ neispravan"

#: common/flatpak-dir.c:15675 common/flatpak-repo-utils.c:2917
msgid "Collection ID requires GPG key to be provided"
msgstr "ID zbirke zahtijeva GPG ključ"

#: common/flatpak-dir.c:15718
#, c-format
msgid "Runtime %s, branch %s is already installed"
msgstr "Okruženje %s, grana %s je već instalirano"

#: common/flatpak-dir.c:15719
#, c-format
msgid "App %s, branch %s is already installed"
msgstr "Program %s, grana %s je već instaliran"

#: common/flatpak-dir.c:15953
#, c-format
msgid "Can't remove remote '%s' with installed ref %s (at least)"
msgstr ""
"Nije moguće ukloniti udaljeni repozitorij „%s” s instaliranom referencom %s "
"(barem)"

#: common/flatpak-dir.c:16058
#, c-format
msgid "Invalid character '/' in remote name: %s"
msgstr "Neispravan znak „/” u imenu udaljenog repozitorija: %s"

#: common/flatpak-dir.c:16064
#, c-format
msgid "No configuration for remote %s specified"
msgstr "Nijedna konfiguracija za udaljeni repozitorij %s nije određena"

#: common/flatpak-dir.c:17597
#, c-format
msgid "Skipping deletion of mirror ref (%s, %s)…\n"
msgstr "Preskače se brisanje reference zrcaljenog repozitorija (%s, %s) …\n"

#: common/flatpak-exports.c:931
#, c-format
msgid "An absolute path is required"
msgstr "Potrebna je apsolutna putanja"

#: common/flatpak-exports.c:948
#, c-format
msgid "Unable to open path \"%s\": %s"
msgstr "Nije moguće otvoriti putanju „%s“: %s"

#: common/flatpak-exports.c:955
#, c-format
msgid "Unable to get file type of \"%s\": %s"
msgstr "Nije moguće dobiti vrstu datoteke od „%s“: %s"

#: common/flatpak-exports.c:964
#, c-format
msgid "File \"%s\" has unsupported type 0o%o"
msgstr ""

#: common/flatpak-exports.c:970
#, c-format
msgid "Unable to get filesystem information for \"%s\": %s"
msgstr ""

#: common/flatpak-exports.c:980
#, c-format
msgid "Ignoring blocking autofs path \"%s\""
msgstr ""

#: common/flatpak-exports.c:996 common/flatpak-exports.c:1009
#: common/flatpak-exports.c:1022
#, c-format
msgid "Path \"%s\" is reserved by Flatpak"
msgstr "Putanja „%s“ je rezervirana od Flatpaka"

#: common/flatpak-exports.c:1076
#, fuzzy, c-format
msgid "Unable to resolve symbolic link \"%s\": %s"
msgstr "Nije moguće aktualizirati simbolsku poveznicu %s/%s"

#: common/flatpak-glib-backports.c:69
msgid "Empty string is not a number"
msgstr "Prazan znakovni niz nije broj"

#: common/flatpak-glib-backports.c:95
#, c-format
msgid "“%s” is not an unsigned number"
msgstr "„%s” nije nedodijeljeni broj"

#: common/flatpak-glib-backports.c:105
#, c-format
msgid "Number “%s” is out of bounds [%s, %s]"
msgstr "Broj „%s” je izvan granica [%s, %s]"

#: common/flatpak-image-source.c:83
msgid "Only sha256 image checksums are supported"
msgstr ""

#: common/flatpak-image-source.c:100 common/flatpak-image-source.c:108
msgid "Image is not a manifest"
msgstr "Slika nije manifest"

#: common/flatpak-image-source.c:123
msgid "No org.flatpak.ref found in image"
msgstr ""

#: common/flatpak-image-source.c:148
#, c-format
msgid "Ref '%s' not found in registry"
msgstr "Referenca „%s” nije pronađena u registru"

#: common/flatpak-image-source.c:157
msgid "Multiple images in registry, specify a ref with --ref"
msgstr "Višestruke slike u registru, odredi referencu pomoću --ref"

#: common/flatpak-installation.c:834
#, c-format
msgid "Ref %s not installed"
msgstr "Referenca „%s” nije instalirana"

#: common/flatpak-installation.c:875
#, c-format
msgid "App %s not installed"
msgstr "Program %s nije instaliran"

#: common/flatpak-installation.c:1395
#, c-format
msgid "Remote '%s' already exists"
msgstr "Udaljeni repozitorij „%s” već postoji"

#: common/flatpak-installation.c:1946
#, c-format
msgid "As requested, %s was only pulled, but not installed"
msgstr "Kako je zatraženo, %s je samo povučen, ali nije instaliran"

#: common/flatpak-instance.c:533 common/flatpak-instance.c:687
#: common/flatpak-instance.c:728
#, c-format
msgid "Unable to create directory %s"
msgstr "Nije moguće stvoriti direktorij %s"

#: common/flatpak-instance.c:554
#, c-format
msgid "Unable to lock %s"
msgstr "Nije moguće zaključati %s"

#: common/flatpak-instance.c:627
#, c-format
msgid "Unable to create temporary directory in %s"
msgstr "Nije moguće stvoriti privremeni direktorij u %s"

#: common/flatpak-instance.c:639
#, c-format
msgid "Unable to create file %s"
msgstr "Nije moguće stvoriti datoteku %s"

#: common/flatpak-instance.c:646
#, c-format
msgid "Unable to update symbolic link %s/%s"
msgstr "Nije moguće aktualizirati simbolsku poveznicu %s/%s"

#: common/flatpak-oci-registry.c:1197
msgid "Only Bearer authentication supported"
msgstr "Podržava se samo Bearer autentifikacija"

#: common/flatpak-oci-registry.c:1206
msgid "Only realm in authentication request"
msgstr "Samo domena u zahtjevu autentifikacije"

#: common/flatpak-oci-registry.c:1213
msgid "Invalid realm in authentication request"
msgstr "Neispravna domena u zahtjevu autentifikacije"

#: common/flatpak-oci-registry.c:1283
#, c-format
msgid "Authorization failed: %s"
msgstr "Autorizacija je neuspjela: %s"

#: common/flatpak-oci-registry.c:1285
msgid "Authorization failed"
msgstr "Autorizacija je neuspjela"

#: common/flatpak-oci-registry.c:1289
#, c-format
msgid "Unexpected response status %d when requesting token: %s"
msgstr "Neočekivano stanje odgovora %d prilikom traženjenja tokena: %s"

#: common/flatpak-oci-registry.c:1300
msgid "Invalid authentication request response"
msgstr "Neispravan odgovor na zahtjev autentifikacije"

#: common/flatpak-oci-registry.c:1731
#, c-format
msgid "Flatpak was compiled without zstd support"
msgstr ""

#: common/flatpak-oci-registry.c:1923 common/flatpak-oci-registry.c:1975
#: common/flatpak-oci-registry.c:2004 common/flatpak-oci-registry.c:2059
#: common/flatpak-oci-registry.c:2115 common/flatpak-oci-registry.c:2193
msgid "Invalid delta file format"
msgstr "Neispravan datotečni format delta"

#: common/flatpak-oci-registry.c:3198 common/flatpak-oci-registry.c:3382
msgid "Invalid OCI image config"
msgstr "Neispravna konfiguracija OCI slike"

#: common/flatpak-oci-registry.c:3260 common/flatpak-oci-registry.c:3531
#, c-format
msgid "Wrong layer checksum, expected %s, was %s"
msgstr "Krivi kontrolni zbroj sloja, očekivan %s, dobiven %s"

#: common/flatpak-oci-registry.c:3359
#, c-format
msgid "No ref specified for OCI image %s"
msgstr "Nema određene reference za OCI sliku %s"

#: common/flatpak-oci-registry.c:3369
#, c-format
msgid "Wrong ref (%s) specified for OCI image %s, expected %s"
msgstr "Kriva referenca (%s) je određena za OCI sliku %s, očekuje se %s"

#: common/flatpak-progress.c:236
#, c-format
msgid "Downloading metadata: %u/(estimating) %s"
msgstr "Preuzimanje metapodataka: %u/(otprilike) %s"

#: common/flatpak-progress.c:260
#, c-format
msgid "Downloading: %s/%s"
msgstr "Preuzimanje: %s/%s"

#: common/flatpak-progress.c:280
#, c-format
msgid "Downloading extra data: %s/%s"
msgstr "Preuzimanje dodatnih podataka: %s/%s"

#: common/flatpak-progress.c:285
#, c-format
msgid "Downloading files: %d/%d %s"
msgstr "Preuzimanje datoteka: %d/%d %s"

#: common/flatpak-ref-utils.c:122
msgid "Name can't be empty"
msgstr "Ime ne može biti prazno"

#: common/flatpak-ref-utils.c:129
msgid "Name can't be longer than 255 characters"
msgstr "Ime ne može sadržati više od 255 znakova"

#: common/flatpak-ref-utils.c:142
msgid "Name can't start with a period"
msgstr "Ime ne može započeti s točkom"

#: common/flatpak-ref-utils.c:148
#, c-format
msgid "Name can't start with %c"
msgstr "Ime ne može započeti s %c"

#: common/flatpak-ref-utils.c:164
msgid "Name can't end with a period"
msgstr "Ime ne može završiti s točkom"

#: common/flatpak-ref-utils.c:171 common/flatpak-ref-utils.c:183
msgid "Only last name segment can contain -"
msgstr "Samo segment prezimena smije sadržati crticu (-)"

#: common/flatpak-ref-utils.c:174
#, c-format
msgid "Name segment can't start with %c"
msgstr "Segment imena ne može započeti s %c"

#: common/flatpak-ref-utils.c:186
#, c-format
msgid "Name can't contain %c"
msgstr "Ime ne može sadržati %c"

#: common/flatpak-ref-utils.c:195
msgid "Names must contain at least 2 periods"
msgstr "Imena moraju sadržati barem dvije točke"

#: common/flatpak-ref-utils.c:312
msgid "Arch can't be empty"
msgstr "Arhitektura ne može biti prazna"

#: common/flatpak-ref-utils.c:323
#, c-format
msgid "Arch can't contain %c"
msgstr "Arhitektura ne može sadržati %c"

#: common/flatpak-ref-utils.c:385
msgid "Branch can't be empty"
msgstr "Grana ne može biti prazna"

#: common/flatpak-ref-utils.c:395
#, c-format
msgid "Branch can't start with %c"
msgstr "Grana ne može započeti s %c"

#: common/flatpak-ref-utils.c:405
#, c-format
msgid "Branch can't contain %c"
msgstr "Grana ne može sadržati %c"

#: common/flatpak-ref-utils.c:615 common/flatpak-ref-utils.c:865
msgid "Ref too long"
msgstr "Referenca predugačka"

#: common/flatpak-ref-utils.c:627
msgid "Invalid remote name"
msgstr "Neispravno ime udaljenog repozitorija"

#: common/flatpak-ref-utils.c:641
#, c-format
msgid "%s is not application or runtime"
msgstr "%s nije program ili okruženje"

#: common/flatpak-ref-utils.c:650 common/flatpak-ref-utils.c:667
#: common/flatpak-ref-utils.c:683
#, c-format
msgid "Wrong number of components in %s"
msgstr "Krivi broj komponenata u %s"

#: common/flatpak-ref-utils.c:656
#, c-format
msgid "Invalid name %.*s: %s"
msgstr "Neispravno ime %.*s: %s"

#: common/flatpak-ref-utils.c:673
#, c-format
msgid "Invalid arch: %.*s: %s"
msgstr "Neispravna arhitektura: %.*s: %s"

#: common/flatpak-ref-utils.c:816
#, c-format
msgid "Invalid name %s: %s"
msgstr "Neispravno ime %s: %s"

#: common/flatpak-ref-utils.c:834
#, c-format
msgid "Invalid arch: %s: %s"
msgstr "Neispravna arhitektura: %s: %s"

#: common/flatpak-ref-utils.c:853
#, c-format
msgid "Invalid branch: %s: %s"
msgstr "Neispravna grana: %s: %s"

#: common/flatpak-ref-utils.c:962 common/flatpak-ref-utils.c:970
#: common/flatpak-ref-utils.c:978
#, c-format
msgid "Wrong number of components in partial ref %s"
msgstr "Krivi broj komponenata u djelomičnoj referenci %s"

#: common/flatpak-ref-utils.c:1298
msgid " development platform"
msgstr " platforma za razvoj"

#: common/flatpak-ref-utils.c:1300
msgid " platform"
msgstr " platforma"

#: common/flatpak-ref-utils.c:1302
msgid " application base"
msgstr " osnova programa"

#: common/flatpak-ref-utils.c:1305
msgid " debug symbols"
msgstr " ispravljanje simbola"

#: common/flatpak-ref-utils.c:1307
msgid " sourcecode"
msgstr " izvorni kod"

#: common/flatpak-ref-utils.c:1309
msgid " translations"
msgstr " prijevodi"

#: common/flatpak-ref-utils.c:1311
msgid " docs"
msgstr " dokumenti"

#: common/flatpak-ref-utils.c:1578
#, c-format
msgid "Invalid id %s: %s"
msgstr "Neispravni ID %s: %s"

#: common/flatpak-remote.c:1216
#, c-format
msgid "Bad remote name: %s"
msgstr "Neispravno ime repozitorija: %s"

#: common/flatpak-remote.c:1220
#, fuzzy
msgid "No URL specified"
msgstr "Url nije određen"

#: common/flatpak-remote.c:1266
msgid "GPG verification must be enabled when a collection ID is set"
msgstr "GPG provjera mora biti aktivirana, kad se postavlja ID oznaka zbirke"

#: common/flatpak-repo-utils.c:344
#, c-format
msgid "No extra data sources"
msgstr "Nema izvora dodatnih dodataka"

#: common/flatpak-repo-utils.c:2817
#, c-format
msgid "Invalid %s: Missing group ‘%s’"
msgstr "Neispravno %s: Nedostaje grupa „%s”"

#: common/flatpak-repo-utils.c:2826
#, c-format
msgid "Invalid %s: Missing key ‘%s’"
msgstr "Neispravno %s: Nedostaje ključ „%s”"

#: common/flatpak-repo-utils.c:2876
msgid "Invalid gpg key"
msgstr "Neispravnan gpg ključ"

#: common/flatpak-repo-utils.c:3217
#, c-format
msgid "Error copying 64x64 icon for component %s: %s\n"
msgstr "Greška pri kopiranju ikone 64 × 64 za komponentu %s: %s\n"

#: common/flatpak-repo-utils.c:3223
#, c-format
msgid "Error copying 128x128 icon for component %s: %s\n"
msgstr "Greška pri kopiranju ikone 128 × 128 za komponentu %s: %s\n"

#: common/flatpak-repo-utils.c:3362
#, c-format
msgid "%s is end-of-life, ignoring for appstream"
msgstr "%s je kraj-života, zanemaruje se za appstream"

#: common/flatpak-repo-utils.c:3397
#, c-format
msgid "No appstream data for %s: %s\n"
msgstr "Nema appstream podataka za %s: %s\n"

#: common/flatpak-repo-utils.c:3744
msgid "Invalid bundle, no ref in metadata"
msgstr "Neispravan paket, nema reference u metapodacima"

#: common/flatpak-repo-utils.c:3846
#, c-format
msgid "Collection ‘%s’ of bundle doesn’t match collection ‘%s’ of remote"
msgstr ""
"Zbirka „%s” paketa ne se poklapa sa zbirkom „%s” udaljenog repozitorija"

#: common/flatpak-repo-utils.c:3923
msgid "Metadata in header and app are inconsistent"
msgstr "Metapodaci u zaglavlju i programu su nedosljedni"

#: common/flatpak-run.c:951
msgid "No systemd user session available, cgroups not available"
msgstr "Nema korisničke sesije systemd, cgroups nije dostupno"

#: common/flatpak-run.c:1496
msgid "Unable to allocate instance id"
msgstr "Nije moguće alocirati id instance"

#: common/flatpak-run.c:1632 common/flatpak-run.c:1641
#, c-format
msgid "Failed to open flatpak-info file: %s"
msgstr "Neuspjelo otvaranje datoteke flatpak-info: %s"

#: common/flatpak-run.c:1668
#, c-format
msgid "Failed to open bwrapinfo.json file: %s"
msgstr "Neuspjelo otvaranje datoteke bwrapinfo.json: %s"

#: common/flatpak-run.c:1689
#, c-format
msgid "Failed to write to instance id fd: %s"
msgstr "Neuspjelo zapisivanje ID-u instance fd: %s"

#: common/flatpak-run.c:2096
msgid "Initialize seccomp failed"
msgstr "Inicijaliziraj seccomp neuspjelo"

#: common/flatpak-run.c:2135
#, c-format
msgid "Failed to add architecture to seccomp filter: %s"
msgstr "Neuspjelo dodavanje arhitekture seccomp filtru: %s"

#: common/flatpak-run.c:2143
#, c-format
msgid "Failed to add multiarch architecture to seccomp filter: %s"
msgstr ""
"Neuspjelo dodavanje arhitekture višestrukih arhitektura seccomp filtru: %s"

#: common/flatpak-run.c:2175 common/flatpak-run.c:2192
#: common/flatpak-run.c:2214
#, c-format
msgid "Failed to block syscall %d: %s"
msgstr "Neuspjelo blokiranje syscall %d: %s"

#: common/flatpak-run.c:2247
#, c-format
msgid "Failed to export bpf: %s"
msgstr "Neuspio bdf izvoz: %s"

#: common/flatpak-run.c:2587
#, c-format
msgid "Failed to open ‘%s’"
msgstr "Neuspjelo otvaranje „%s”"

#: common/flatpak-run.c:2597
#, c-format
msgid ""
"Directory forwarding needs version 4 of the document portal (have version %d)"
msgstr ""

#: common/flatpak-run.c:2915
#, c-format
msgid "ldconfig failed, exit status %d"
msgstr "ldconfig neuspjelo, stanje izlaza %d"

#: common/flatpak-run.c:2922
msgid "Can't open generated ld.so.cache"
msgstr "Nije moguće otvoriti generirani ld.so.cache"

#. Translators: The placeholder is for an app ref.
#: common/flatpak-run.c:3045
#, c-format
msgid "Running %s is not allowed by the policy set by your administrator"
msgstr ""
"Pokretanje programa %s nije dozvoljeno na osnovi administratorskih pravila"

#: common/flatpak-run.c:3202
#, fuzzy
msgid ""
"\"flatpak run\" is not intended to be run as `sudo flatpak run`. Use `sudo "
"-i` or `su -l` instead and invoke \"flatpak run\" from inside the new shell."
msgstr ""
"„flatpak run” nije namijenjen za pokretanje kao `sudo flatpak run`, umjesto "
"toga koristi `sudo -i` ili `su -l` i pozovi „flatpak run” iz nove ljuske"

#: common/flatpak-run.c:3413
#, c-format
msgid "Failed to migrate from %s: %s"
msgstr "Neuspjelo migriranje iz %s: %s"

#: common/flatpak-run.c:3434
#, c-format
msgid "Failed to migrate old app data directory %s to new name %s: %s"
msgstr ""
"Neuspjelo migriranje starog direktorija za podatke programa %s u novo ime "
"%s: %s"

#: common/flatpak-run.c:3443
#, c-format
msgid "Failed to create symlink while migrating %s: %s"
msgstr ""
"Neuspjelo stvaranje simboličke veze (symlink) prilikom migriranja %s: %s"

#: common/flatpak-run-dbus.c:46
msgid "Failed to open app info file"
msgstr "Neuspjelo otvaranje datoteke s informacijama o programu"

#: common/flatpak-run-dbus.c:149
msgid "Unable to create sync pipe"
msgstr "Nije moguće stvoriti pipe za sinkronizaciju"

#: common/flatpak-run-dbus.c:185
msgid "Failed to sync with dbus proxy"
msgstr "Neuspjela sinkronizacija s dbus proxijem"

#: common/flatpak-transaction.c:2275
#, c-format
msgid "Warning: Problem looking for related refs: %s"
msgstr "Upozorenje: Problem u treženju povezanih referenca: %s"

#: common/flatpak-transaction.c:2493
#, c-format
msgid "The application %s requires the runtime %s which was not found"
msgstr "Program %s zahtijeva okruženje %s, koje nije pronađeno"

#: common/flatpak-transaction.c:2509
#, c-format
msgid "The application %s requires the runtime %s which is not installed"
msgstr "Program %s zahtijeva okruženje %s, koje nije instalirano"

#: common/flatpak-transaction.c:2641
#, c-format
msgid "Can't uninstall %s which is needed by %s"
msgstr "Nije moguće deinstalirati %s, što %s zahtijeva"

#: common/flatpak-transaction.c:2740
#, c-format
msgid "Remote %s disabled, ignoring %s update"
msgstr "Udaljeni repozitorij „%s” deaktiviran, zanemaruje se %s aktualiziranje"

#: common/flatpak-transaction.c:2773
#, c-format
msgid "%s is already installed"
msgstr "%s je već instalirano"

#: common/flatpak-transaction.c:2776
#, c-format
msgid "%s is already installed from remote %s"
msgstr "%s je već instalirano s udaljenog repozitorija %s"

#: common/flatpak-transaction.c:3120
#, c-format
msgid "Invalid .flatpakref: %s"
msgstr "Neispravni .flatpakref: %s"

#: common/flatpak-transaction.c:3161
msgid "Warning: Could not mark already installed apps as preinstalled"
msgstr ""
"Upozorenje: nije bilo moguće označiti već instalirane aplikacije kao "
"unaprijed instalirane"

#: common/flatpak-transaction.c:3382
#, c-format
msgid "Error updating remote metadata for '%s': %s"
msgstr ""
"Greška pri aktualiziranju metapodataka udaljenog repozitorija za „%s”: %s"

#: common/flatpak-transaction.c:3885
#, c-format
msgid ""
"Warning: Treating remote fetch error as non-fatal since %s is already "
"installed: %s"
msgstr ""
"Upozorenje: Obradi greške u preuzimanju izmjena kao nekritične, budući da je "
"%s već instaliran: %s"

#: common/flatpak-transaction.c:4209
#, c-format
msgid "No authenticator installed for remote '%s'"
msgstr "Nijedan autentifikator nije instaliran za udaljeni repozitorij „%s”"

#: common/flatpak-transaction.c:4313 common/flatpak-transaction.c:4320
#, c-format
msgid "Failed to get tokens for ref: %s"
msgstr "Neuspjelo dobavljanje tokena za referencu: %s"

#: common/flatpak-transaction.c:4315 common/flatpak-transaction.c:4322
msgid "Failed to get tokens for ref"
msgstr "Neuspjelo dobavljanje tokena za referencu"

#: common/flatpak-transaction.c:4580
#, c-format
msgid "Ref %s from %s matches more than one transaction operation"
msgstr ""

#: common/flatpak-transaction.c:4581 common/flatpak-transaction.c:4591
msgid "any remote"
msgstr "bilo koji udaljeni uređaj"

#: common/flatpak-transaction.c:4590
#, c-format
msgid "No transaction operation found for ref %s from %s"
msgstr ""

#: common/flatpak-transaction.c:4713
#, c-format
msgid "Flatpakrepo URL %s not file, HTTP or HTTPS"
msgstr "URL %s Flatpak repozitorija nije datoteka, HTTP ili HTTPS"

#: common/flatpak-transaction.c:4719
#, c-format
msgid "Can't load dependent file %s: "
msgstr "Nije moguće učitati ovisnu datoteku %s: "

#: common/flatpak-transaction.c:4727
#, c-format
msgid "Invalid .flatpakrepo: %s"
msgstr "Neispravni .flatpakrepo: %s"

#: common/flatpak-transaction.c:5454
msgid "Transaction already executed"
msgstr "Transakcija je već izvršena"

#: common/flatpak-transaction.c:5469
msgid ""
"Refusing to operate on a user installation as root! This can lead to "
"incorrect file ownership and permission errors."
msgstr ""
"Odbija raditi na korisničkoj instalaciji kao administrator! To može dovesti "
"do krivih vlasništva nad datotekama i do grešaka u dozvolama."

#: common/flatpak-transaction.c:5567 common/flatpak-transaction.c:5580
msgid "Aborted by user"
msgstr "Prekinuto od korisnika"

#: common/flatpak-transaction.c:5605
#, c-format
msgid "Skipping %s due to previous error"
msgstr "%s se preskače zbog prethodne greške"

#: common/flatpak-transaction.c:5659
#, c-format
msgid "Aborted due to failure (%s)"
msgstr "Prekinuto zbog greške (%s)"

#: common/flatpak-uri.c:118
#, no-c-format
msgid "Invalid %-encoding in URI"
msgstr "Neispravno %-enkodiranje u URI-ju"

#: common/flatpak-uri.c:135
msgid "Illegal character in URI"
msgstr "Neisravni znak u URI-ju"

#: common/flatpak-uri.c:169
msgid "Non-UTF-8 characters in URI"
msgstr "Znakovi koji nisu UTF-8 u URI-ju"

#: common/flatpak-uri.c:275
#, c-format
msgid "Invalid IPv6 address ‘%.*s’ in URI"
msgstr "Neispravna IPv6 adresa „%.*s“ u URI-ju"

#: common/flatpak-uri.c:330
#, c-format
msgid "Illegal encoded IP address ‘%.*s’ in URI"
msgstr "Neisravno kodirana IP adresa „%.*s“ u URI-ju"

#: common/flatpak-uri.c:342
#, c-format
msgid "Illegal internationalized hostname ‘%.*s’ in URI"
msgstr ""

#: common/flatpak-uri.c:374 common/flatpak-uri.c:386
#, fuzzy, c-format
msgid "Could not parse port ‘%.*s’ in URI"
msgstr "Nije bilo moguće obraditi „%s”"

#: common/flatpak-uri.c:393
#, c-format
msgid "Port ‘%.*s’ in URI is out of range"
msgstr ""

#: common/flatpak-uri.c:910
msgid "URI is not absolute, and no base URI was provided"
msgstr "URI nije apsolutan i nije naveden osnovni URI"

#: common/flatpak-usb.c:83
#, c-format
msgid "USB device query 'all' must not have data"
msgstr ""

#: common/flatpak-usb.c:102
#, c-format
msgid "USB query rule 'cls' must be in the form CLASS:SUBCLASS or CLASS:*"
msgstr ""

#: common/flatpak-usb.c:111
#, c-format
msgid "Invalid USB class"
msgstr "Neispravna USB klasa"

#: common/flatpak-usb.c:125
#, c-format
msgid "Invalid USB subclass"
msgstr "Neispravna USB podklasa"

#: common/flatpak-usb.c:141 common/flatpak-usb.c:148
#, c-format
msgid "USB query rule 'dev' must have a valid 4-digit hexadecimal product id"
msgstr ""

#: common/flatpak-usb.c:164 common/flatpak-usb.c:171
#, c-format
msgid "USB query rule 'vnd' must have a valid 4-digit hexadecimal vendor id"
msgstr ""

#: common/flatpak-usb.c:205
#, c-format
msgid "USB device queries must be in the form TYPE:DATA"
msgstr ""

#: common/flatpak-usb.c:225
#, c-format
msgid "Unknown USB query rule %s"
msgstr ""

#: common/flatpak-usb.c:248
#, c-format
msgid "Empty USB query"
msgstr ""

#: common/flatpak-usb.c:274
#, c-format
msgid "Multiple USB query rules of the same type is not supported"
msgstr ""

#: common/flatpak-usb.c:283
#, c-format
msgid "'all' must not contain extra query rules"
msgstr ""

#: common/flatpak-usb.c:291
#, c-format
msgid "USB queries with 'dev' must also specify vendors"
msgstr ""

#: common/flatpak-utils.c:712
msgid "Glob can't match apps"
msgstr "Globalna naredba ne može usporediti aplikacije"

#: common/flatpak-utils.c:737
msgid "Empty glob"
msgstr "Prazna globalna naredba"

#: common/flatpak-utils.c:756
msgid "Too many segments in glob"
msgstr "Previše segmenata u globalnoj naredbi"

#: common/flatpak-utils.c:777
#, c-format
msgid "Invalid glob character '%c'"
msgstr "Neispravan znak „%c” u globalnoj naredbi"

#: common/flatpak-utils.c:831
#, c-format
msgid "Missing glob on line %d"
msgstr "Nedostaje globalna naredba u %d. retku"

#: common/flatpak-utils.c:835
#, c-format
msgid "Trailing text on line %d"
msgstr "Dodatni tekst u %d. retku"

#: common/flatpak-utils.c:839
#, c-format
msgid "on line %d"
msgstr "u %d. retku"

#: common/flatpak-utils.c:861
#, c-format
msgid "Unexpected word '%s' on line %d"
msgstr "Neočekivana riječ „%s” u %d. retku"

#: common/flatpak-utils.c:2118
#, c-format
msgid "Invalid require-flatpak argument %s"
msgstr "Neispravni require-flatpak argument %s"

#: common/flatpak-utils.c:2128 common/flatpak-utils.c:2147
#, c-format
msgid "%s needs a later flatpak version (%s)"
msgstr "%s treba noviju flatpak verziju (%s)"

#: oci-authenticator/flatpak-oci-authenticator.c:291
msgid "Not a oci remote, missing summary.xa.oci-repository"
msgstr "Nije udaljeni OCI, nedostaje summary.xa.oci-repository"

#: oci-authenticator/flatpak-oci-authenticator.c:477
msgid "Not a OCI remote"
msgstr "Nije udaljeni OCI"

#: oci-authenticator/flatpak-oci-authenticator.c:488
msgid "Invalid token"
msgstr "Neispravan token"

#: portal/flatpak-portal.c:2292
#, c-format
msgid "No portal support found"
msgstr "Nema podrške za portal"

#: portal/flatpak-portal.c:2298
msgid "Deny"
msgstr "Odbij"

#: portal/flatpak-portal.c:2300
msgid "Update"
msgstr "Aktualiziraj"

#: portal/flatpak-portal.c:2305
#, c-format
msgid "Update %s?"
msgstr "Aktualizirati %s?"

#: portal/flatpak-portal.c:2317
msgid "The application wants to update itself."
msgstr "Program se želi aktualizirati."

#: portal/flatpak-portal.c:2318
msgid "Update access can be changed any time from the privacy settings."
msgstr ""
"Pristup aktualiziranju je uvijek moguće promijeniti u postavkama privatnosti."

#: portal/flatpak-portal.c:2343
#, c-format
msgid "Application update not allowed"
msgstr "Aktualiziranje programa nije dozvoljeno"

#: portal/flatpak-portal.c:2501
#, c-format
msgid "Self update not supported, new version requires new permissions"
msgstr ""
"Samoauktualiziranje nije podržano, za novu verziju su potrebne nove dozvole"

#: portal/flatpak-portal.c:2684 portal/flatpak-portal.c:2702
#, c-format
msgid "Update ended unexpectedly"
msgstr "Aktualiziranje je neočekivano prekinuto"

#. SECURITY:
#. - Normal users need admin authentication to install software
#. system-wide.
#. - Note that we install polkit rules that allow local users
#. in the wheel group to install without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:23
msgid "Install signed application"
msgstr "Instaliraj potpisani program"

#: system-helper/org.freedesktop.Flatpak.policy.in:24
#: system-helper/org.freedesktop.Flatpak.policy.in:42
msgid "Authentication is required to install software"
msgstr "Potrebna je autentifikacija za instaliranje softvera"

#. SECURITY:
#. - Normal users need admin authentication to install software
#. system-wide.
#. - Note that we install polkit rules that allow local users
#. in the wheel group to install without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:41
msgid "Install signed runtime"
msgstr "Instaliraj potpisano okruženje"

#. SECURITY:
#. - Normal users do not require admin authentication to update an
#. app as the commit will be signed, and the action is required
#. to update the system when unattended.
#. - Changing this to anything other than 'yes' will break unattended
#. updates.
#: system-helper/org.freedesktop.Flatpak.policy.in:60
msgid "Update signed application"
msgstr "Aktualiziraj potpisani program"

#: system-helper/org.freedesktop.Flatpak.policy.in:61
#: system-helper/org.freedesktop.Flatpak.policy.in:80
msgid "Authentication is required to update software"
msgstr "Potrebna je autentifikacija za aktualiziranje softvera"

#. SECURITY:
#. - Normal users do not require admin authentication to update a
#. runtime as the commit will be signed, and the action is required
#. to update the system when unattended.
#. - Changing this to anything other than 'yes' will break unattended
#. updates.
#: system-helper/org.freedesktop.Flatpak.policy.in:79
msgid "Update signed runtime"
msgstr "Aktualiziraj potpisano okruženje"

#. SECURITY:
#. - Normal users do not need authentication to update metadata
#. from signed repositories.
#: system-helper/org.freedesktop.Flatpak.policy.in:94
msgid "Update remote metadata"
msgstr "Aktualiziraj metapodatke udaljenog repozitorija"

#: system-helper/org.freedesktop.Flatpak.policy.in:95
msgid "Authentication is required to update remote info"
msgstr ""
"Potrebna je autentifikacija za aktualiziranje podataka udaljenog repozitorija"

#. SECURITY:
#. - Normal users do not need authentication to modify the
#. OSTree repository
#. - Note that we install polkit rules that allow local users
#. in the wheel group to modify repos without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:111
msgid "Update system repository"
msgstr "Aktualiziraj repozitorij sustava"

#: system-helper/org.freedesktop.Flatpak.policy.in:112
msgid "Authentication is required to modify a system repository"
msgstr "Potrebna je autentifikacija za mijenjanje repozitorija sustava"

#. SECURITY:
#. - Normal users need admin authentication to install software
#. system-wide.
#: system-helper/org.freedesktop.Flatpak.policy.in:126
msgid "Install bundle"
msgstr "Instaliraj paket"

#: system-helper/org.freedesktop.Flatpak.policy.in:127
msgid "Authentication is required to install software from $(path)"
msgstr "Potrebna je autentifikacija za instaliranje softvera iz $(path)"

#. SECURITY:
#. - Normal users need admin authentication to uninstall software
#. system-wide.
#. - Note that we install polkit rules that allow local users
#. in the wheel group to uninstall without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:144
msgid "Uninstall runtime"
msgstr "Deinstaliraj okruženje"

#: system-helper/org.freedesktop.Flatpak.policy.in:145
msgid "Authentication is required to uninstall software"
msgstr "Potrebna je autentifikacija za deinstaliranje softvera"

#. SECURITY:
#. - Normal users need admin authentication to uninstall software
#. system-wide.
#. - Note that we install polkit rules that allow local users
#. in the wheel group to uninstall without authenticating.
#: system-helper/org.freedesktop.Flatpak.policy.in:161
msgid "Uninstall app"
msgstr "Deinstaliraj program"

#: system-helper/org.freedesktop.Flatpak.policy.in:162
msgid "Authentication is required to uninstall $(ref)"
msgstr "Potrebna je autentifikacija za deinstaliranje $(ref)"

#. SECURITY:
#. - Normal users need admin authentication to configure system-wide
#. software repositories.
#: system-helper/org.freedesktop.Flatpak.policy.in:177
msgid "Configure Remote"
msgstr "Konfiguriraj udaljeni repozitorij"

#: system-helper/org.freedesktop.Flatpak.policy.in:178
msgid "Authentication is required to configure software repositories"
msgstr "Potrebna je autentifikacija za konfiguriranje repozitorija softvera"

#. SECURITY:
#. - Normal users need admin authentication to configure the system-wide
#. Flatpak installation.
#: system-helper/org.freedesktop.Flatpak.policy.in:192
msgid "Configure"
msgstr "Konfiguriraj"

#: system-helper/org.freedesktop.Flatpak.policy.in:193
msgid "Authentication is required to configure software installation"
msgstr "Potrebna je autentifikacija za konfiguriranje instalacije softvera"

#. SECURITY:
#. - Normal users do not require admin authentication to update
#. appstream data as it will be signed, and the action is required
#. to update the system when unattended.
#. - Changing this to anything other than 'yes' will break unattended
#. updates.
#: system-helper/org.freedesktop.Flatpak.policy.in:210
msgid "Update appstream"
msgstr "Aktualiziraj podatke programa"

#: system-helper/org.freedesktop.Flatpak.policy.in:211
msgid "Authentication is required to update information about software"
msgstr "Potrebna je autentifikacija za aktualiziranje podataka o softveru"

#. SECURITY:
#. - Normal users do not require admin authentication to update
#. metadata as it will be signed, and the action is required
#. to update the system when unattended.
#. - Changing this to anything other than 'yes' will break unattended
#. updates.
#: system-helper/org.freedesktop.Flatpak.policy.in:228
msgid "Update metadata"
msgstr "Aktualiziraj metapodatke"

#: system-helper/org.freedesktop.Flatpak.policy.in:229
msgid "Authentication is required to update metadata"
msgstr "Potrebna je autentifikacija za aktualiziranje metapodataka"

#. SECURITY:
#. - Authorisation to actually install software is controlled by
#. org.freedesktop.Flatpak.app-install.
#. - This action is checked after app-install, as it can only be done
#. once the app’s data (including its content rating) has been
#. downloaded.
#. - This action is checked to see if the installation should be allowed
#. based on whether the app being installed has content which doesn’t
#. comply with the user’s parental controls policy (the content is
#. ‘too extreme’).
#. - It is checked only if an app has too extreme content for the user
#. who is trying to install it (in which case, the app is ‘unsafe’).
#. - Typically, normal users will need admin permission to install apps
#. with extreme content; admins will be able to install it without
#. additional checks.
#. - In order to configure the policy so that admins can install safe and
#. unsafe software anywhere without authorisation, and non-admins can
#. install safe software in their user or system dirs without
#. authorisation, but need authorisation to install unsafe software
#. anywhere:
#. * Unconditionally return `yes` from `app-install`.
#. * Return `auth_admin` from `override-parental-controls` for users
#. not in `@privileged_group@`, and `yes` for users in it.
#. * Set the malcontent `is-{user,system}-installation-allowed`
#. properties of all non-admins’ parental controls policies to true.
#. - In order to configure the policy so that admins can install safe and
#. unsafe software anywhere without authorisation, and non-admins can
#. install safe software in their user dir without authorisation, but
#. need authorisation to install safe software in the system dir or to
#. install unsafe software anywhere:
#. * Unconditionally return `yes` from `app-install`.
#. * Return `auth_admin` from `override-parental-controls` for users
#. not in `@privileged_group@`, and `yes` for users in it.
#. * Set the malcontent `is-user-installation-allowed` property of all
#. non-admins’ parental controls policies to true.
#. * Set the malcontent `is-system-installation-allowed` property of
#. all non-admins’ parental controls policies to false.
#. - In order to configure the policy so that all users (including
#. admins) can install safe software anywhere without authorisation,
#. but need authorisation to install unsafe software anywhere (i.e.
#. applying parental controls to admins too):
#. * Unconditionally return `yes` from `app-install`.
#. * Unconditionally return `auth_admin` from `override-parental-controls`.
#. * Set the malcontent `is-user-installation-allowed` property of all
#. users’ parental controls policies to true.
#. * Set the malcontent `is-system-installation-allowed` property of
#. all users’ parental controls policies to true.
#: system-helper/org.freedesktop.Flatpak.policy.in:287
msgid "Override parental controls for installs"
msgstr "Isključi roditeljski nadzor za instaliranja"

#: system-helper/org.freedesktop.Flatpak.policy.in:288
msgid ""
"Authentication is required to install software which is restricted by your "
"parental controls policy"
msgstr ""
"Potrebna je autentifikacija za instaliranje softvera, koja je ograničena "
"tvojim pravilima roditeljskog nadzora"

#. SECURITY:
#. - This is like org.freedesktop.Flatpak.override-parental-controls, but
#. it’s queried for app updates, whereas the former is queried for app
#. installs.
#. - As with the above action, this one is only queried if
#. org.freedesktop.Flatpak.app-update has allowed the app update, and
#. only if the app being updated has too extreme content for the user
#. who is trying to update it.
#. - The default policy for this is to *allow* updates to ‘too extreme’
#. apps by default, on the basis that having an out-of-date (i.e.
#. insecure or unsupported) app is a worse outcome than automatically
#. installing an update which has radically different content from the
#. version of the app which the parent originally vetted and installed.
#: system-helper/org.freedesktop.Flatpak.policy.in:313
msgid "Override parental controls for updates"
msgstr "Isključi roditeljski nadzor za aktualiziranja"

#: system-helper/org.freedesktop.Flatpak.policy.in:314
msgid ""
"Authentication is required to update software which is restricted by your "
"parental controls policy"
msgstr ""
"Za instaliranje softvera je potrebna autentifikacija, koja je ograničena "
"tvojim pravilima roditeljskog nadzora"

#~ msgid "Installed:"
#~ msgstr "Instalirano:"

#~ msgid "Download:"
#~ msgstr "Preuzimanje:"

#, c-format
#~ msgid "No gpg key found with ID %s (homedir: %s)"
#~ msgstr "Nema gpg ključa s ID oznakom %s (početni direktorij: %s)"

#, fuzzy, c-format
#~ msgid "Unable to lookup key ID %s: %d"
#~ msgstr "Nije moguće pregledati ID ključa %s: %d)"

#, c-format
#~ msgid "Error signing commit: %d"
#~ msgstr "Greška pri potpisivanju izmjene: %d"

#, c-format
#~ msgid ""
#~ "Found similar ref(s) for ‘%s’ in remote ‘%s’ (%s).\n"
#~ "Use this remote?"
#~ msgstr ""
#~ "Pronađena je slična referenca „%s” u udaljenom repozitoriju „%s” (%s).\n"
#~ "Koristiti ovaj udaljeni repozitorij?"

#, c-format
#~ msgid "No entry for %s in remote '%s' summary cache "
#~ msgstr ""
#~ "Nema unosa za %s u predmemoriji sažetka udaljenog repozitorija „%s” "

#, fuzzy, c-format
#~ msgid "Failed to uninstall %s for rebase to %s: "
#~ msgstr "Neuspjelo premještanje %s na %s: "

#, fuzzy, c-format
#~ msgid "Failed to uninstall %s for rebase to %s: %s\n"
#~ msgstr "Neuspjelo premještanje %s na %s: %s\n"

#, c-format
#~ msgid "Unable to open directory %s"
#~ msgstr "Nije moguće otvoriti direktorij %s"

#~ msgid "install"
#~ msgstr "instaliraj"

#~ msgid "update"
#~ msgstr "aktualiziraj"

#~ msgid "install bundle"
#~ msgstr "instaliraj paket"

#~ msgid "uninstall"
#~ msgstr "deinstaliraj"

#~ msgid "(internal error, please report)"
#~ msgstr "(interna greška, prijavi je)"

#~ msgid "Warning:"
#~ msgstr "Upozorenje:"

#, fuzzy
#~ msgid "runtime"
#~ msgstr "Okruženje"

#, fuzzy
#~ msgid "app"
#~ msgstr "Program"

#~ msgid "[REF…] - Uninstall an application"
#~ msgstr "[REFERENCA …] – Deinstaliraj jedan program"

#, c-format
#~ msgid "Replace it with %s?"
#~ msgstr "Zamijeniti s %s?"

===== ./po/POTFILES.skip =====
# List of source files that should *not* be translated.
# Please keep this file sorted alphabetically.
app/flatpak-builtins-utils.h
app/parse-datetime.c
common/flatpak-dir-private.h
common/valgrind-private.h

===== ./buildutil/tap-test =====
#! /bin/bash
#
# Run a test in tap mode, ensuring we have a temporary directory.
#
# The test binary is passed as $1

srcd=$(cd $(dirname $1) && pwd)
bn=$(basename $1)
shift
tempdir=$(mktemp -d /tmp/tap-test.XXXXXX)
touch ${tempdir}/.testtmp
function cleanup () {
    if test -n "${TEST_SKIP_CLEANUP:-}"; then
        echo "Skipping cleanup of ${tempdir}"
    else if test -f ${tempdir}/.testtmp; then
        rm "${tempdir}" -rf
    fi
    fi
}
trap cleanup EXIT
cd ${tempdir}
if [[ $bn == *.wrap ]]; then
    WRAPPER=${srcd}/test-wrapper.sh
fi
$WRAPPER ${srcd}/${bn} -k --tap "$@"

===== ./tests/test-wrapper.sh =====
#!/bin/bash

for feature in $(echo $1 | sed "s/^.*@\(.*\).wrap/\1/" | tr "," "\n"); do
    case $feature in
        system)
            export USE_SYSTEMDIR=yes
            ;;
        system-norevokefs)
            export USE_SYSTEMDIR=yes
            export FLATPAK_DISABLE_REVOKEFS=yes
            ;;
        user)
            export USE_SYSTEMDIR=no
            ;;
        deltas)
            export USE_DELTAS=yes
            ;;
        newsummary)
            export SUMMARY_FORMAT=new
            ;;
        oldsummary)
            export SUMMARY_FORMAT=old
            ;;
        nodeltas)
            export USE_DELTAS=no
            ;;
        labels)
            export USE_OCI_LABELS=yes
            ;;
        annotations)
            export USE_OCI_ANNOTATIONS=yes
            ;;
        https)
            export USE_HTTPS=yes
            ;;
        http)
            export USE_HTTPS=no
            ;;
        *)
            echo unsupported test feature $feature
            exit 1
    esac
done

WRAPPED=$(echo $1 | sed "s/@.*/\.sh/")
. $WRAPPED "$@"

===== ./tests/tap.test.in =====
[Test]
Type=session
Exec=env G_TEST_SRCDIR=@installed_testdir@ G_TEST_BUILDDIR=@installed_testdir@ @wrapper@ @installed_testdir@/@basename@ --tap
Output=TAP

===== ./tests/apply-extra-static.c =====
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

static const char msg[] = "noruntime-extra-data\n";

int main(void) {
    mkdir("/app/extra", 0755);
    int fd = open("/app/extra/ran", O_WRONLY | O_CREAT | O_TRUNC, 0644);
    if (fd < 0)
        return 1;
    ssize_t ret = write(fd, msg, sizeof(msg) - 1);
    (void)ret;
    close(fd);
    return 0;
}

===== ./tests/can-use-fuse.h =====
/*
 * Copyright 2019-2021 Collabora Ltd.
 * SPDX-License-Identifier: LGPL-2.1-or-later
 */

#pragma once

#include <glib.h>

extern gchar *cannot_use_fuse;
gboolean check_fuse (void);
gboolean check_fuse_or_skip_test (void);

===== ./tests/can-use-fuse.c =====
/* vi:set et sw=2 sts=2 cin cino=t0,f0,(0,{s,>2s,n-s,^-s,e-s:
 * Copyright 2019-2021 Collabora Ltd.
 * SPDX-License-Identifier: LGPL-2.1-or-later
 */

#include "config.h"

#include "can-use-fuse.h"

#include <unistd.h>

#include <glib/gstdio.h>

#include "libglnx.h"

#ifndef FUSE_USE_VERSION
#error config.h needs to define FUSE_USE_VERSION
#endif

#if FUSE_USE_VERSION >= 31
#include <fuse.h>
#else
#include <fuse_lowlevel.h>
#endif

gchar *cannot_use_fuse = NULL;

/*
 * If we cannot use FUSE, set cannot_use_fuse and return %FALSE.
 */
gboolean
check_fuse (void)
{
  g_autofree gchar *fusermount = NULL;
  g_autofree gchar *path = NULL;
  static const char * const argv[] = { "flatpak-fuse-test", NULL };
  struct fuse_args args = FUSE_ARGS_INIT (G_N_ELEMENTS (argv) - 1, (char **) argv);
  g_autoptr(GError) error = NULL;
#if FUSE_USE_VERSION >= 31
  struct fuse *fuse = NULL;
  const struct fuse_operations ops = { NULL };
#else
  struct fuse_chan *chan = NULL;
#endif

  if (cannot_use_fuse != NULL)
    return FALSE;

  if (access ("/dev/fuse", W_OK) != 0)
    {
      cannot_use_fuse = g_strdup_printf ("access /dev/fuse: %s",
                                         g_strerror (errno));
      return FALSE;
    }

  fusermount = g_find_program_in_path (FUSERMOUNT);

  if (fusermount == NULL)
    {
      cannot_use_fuse = g_strdup ("fusermount not found in PATH");
      return FALSE;
    }

  if (!g_file_test (fusermount, G_FILE_TEST_IS_EXECUTABLE))
    {
      cannot_use_fuse = g_strdup_printf ("%s not executable", fusermount);
      return FALSE;
    }

  if (!g_file_test ("/etc/mtab", G_FILE_TEST_EXISTS))
    {
      cannot_use_fuse = g_strdup ("fusermount won't work without /etc/mtab");
      return FALSE;
    }

  path = g_dir_make_tmp ("flatpak-test.XXXXXX", &error);
  g_assert_no_error (error);

#if FUSE_USE_VERSION >= 31
  fuse = fuse_new (&args, &ops, sizeof (ops), NULL);

  if (fuse == NULL)
    {
      fuse_opt_free_args (&args);
      cannot_use_fuse = g_strdup_printf ("fuse_new: %s",
                                         g_strerror (errno));
      return FALSE;
    }

  if (fuse_mount (fuse, path) != 0)
    {
      fuse_destroy (fuse);
      fuse_opt_free_args (&args);
      cannot_use_fuse = g_strdup_printf ("fuse_mount: %s",
                                         g_strerror (errno));
      return FALSE;
    }
#else
  chan = fuse_mount (path, &args);

  if (chan == NULL)
    {
      fuse_opt_free_args (&args);
      cannot_use_fuse = g_strdup_printf ("fuse_mount: %s",
                                         g_strerror (errno));
      return FALSE;
    }
#endif

  g_test_message ("Successfully set up test FUSE fs on %s", path);

#if FUSE_USE_VERSION >= 31
  fuse_unmount (fuse);
  fuse_destroy (fuse);
#else
  fuse_unmount (path, chan);
#endif

  if (g_rmdir (path) != 0)
    g_error ("rmdir %s: %s", path, g_strerror (errno));

  fuse_opt_free_args (&args);

  return TRUE;
}

gboolean
check_fuse_or_skip_test (void)
{
  if (!check_fuse ())
    {
      g_assert (cannot_use_fuse != NULL);
      g_test_skip (cannot_use_fuse);
      return FALSE;
    }

  return TRUE;
}

===== ./tests/test-oci-registry.sh =====
#!/bin/bash
#
# Copyright (C) 2018 Red Hat, Inc.
#
# 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 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., 59 Temple Place - Suite 330,
# Boston, MA 02111-1307, USA.

set -euo pipefail

. $(dirname $0)/libtest.sh

skip_without_bwrap

echo "1..18"

# Start the fake registry server

if [ x${USE_HTTPS} = xyes ] ; then
    cat > openssl.config <<EOF
[req]
distinguished_name=default_dn

[v3_ca]
basicConstraints=critical,CA:TRUE,pathlen:0

[server_cert]
basicConstraints=CA:FALSE
subjectAltName=DNS:registry.example.com,IP:127.0.0.1

[usr_cert]
subjectAltName=email:copy
basicConstraints=CA:FALSE
keyUsage=digitalSignature
extendedKeyUsage=clientAuth

[default_dn]
CN=Unused
EOF

    openssl req -x509 -newkey rsa:4096 -sha256 -days 3650 \
        -nodes -keyout example.com.ca.key -out example.com.ca.crt \
        -subj="/CN=Example CA/O=example.com/emailAddress=nomail@example.com" \
        -config openssl.config -extensions v3_ca

    openssl req -newkey rsa:4096 -sha256 \
        -nodes -keyout example.com.key -out example.com.csr \
	-subj "/CN=registry.example.com"

    openssl x509 -req -in example.com.csr -days 3650 \
        -CA example.com.ca.crt -CAkey example.com.ca.key -CAcreateserial \
	-extfile openssl.config -extensions server_cert \
	-out example.com.crt

    openssl req -newkey rsa:4096 -sha256 \
        -nodes -keyout client.key -out client.csr \
        -subj="/CN=User/O=example.com/emailAddress=user@example.com"

    openssl x509 -req -in client.csr -days 3650 \
	-CA example.com.ca.crt -CAkey example.com.ca.key -CAcreateserial \
	-extfile openssl.config -extensions usr_cert \
	-out client.cert

    server_args="--cert=example.com.crt --key=example.com.key --mtls-cacert=example.com.ca.crt"
else
    server_args=
    client_args=
fi

httpd oci-registry-server.py --dir=. $server_args
port=$(cat httpd-port)

if [ x${USE_HTTPS} = xyes ] ; then
    scheme=https
    client_args="--cert=client.cert --key=client.key --cacert=example.com.ca.crt"

    hostdir=$FLATPAK_SYSTEM_CERTS_D/127.0.0.1:${port}
    mkdir -p $hostdir
    cp example.com.ca.crt client.key client.cert $hostdir
else
    scheme=http
    client_args=
fi

client="python3 $test_srcdir/oci-registry-client.py $client_args --url=${scheme}://127.0.0.1:${port}"

setup_repo_no_add oci

# Add OCI bundles to it

${FLATPAK} build-bundle --runtime --oci $FL_GPGARGS repos/oci oci/platform-image org.test.Platform >&2
$client add platform latest $(pwd)/oci/platform-image

${FLATPAK} build-bundle --oci $FL_GPGARGS repos/oci oci/app-image org.test.Hello >&2
$client add hello latest $(pwd)/oci/app-image

# Add an OCI remote

${FLATPAK} remote-add ${U} oci-registry "oci+${scheme}://127.0.0.1:${port}" >&2

# Check that the images we expect are listed

images=$(${FLATPAK} remote-ls ${U} --columns=app oci-registry | sort | tr '\n' ' ' | sed 's/ $//')
assert_streq "$images" "org.test.Hello org.test.Platform"
ok "list remote"

# Pull appstream data

${FLATPAK} update ${U} --appstream oci-registry >&2

# Check that the appstream and icons exist

if [ x${USE_SYSTEMDIR-} == xyes ] ; then
    appstream=$SYSTEMDIR/appstream/oci-registry/$ARCH/appstream.xml.gz
    icondir=$SYSTEMDIR/appstream/oci-registry/$ARCH/icons
else
    appstream=$USERDIR/appstream/oci-registry/$ARCH/appstream.xml.gz
    icondir=$USERDIR/appstream/oci-registry/$ARCH/icons
fi

gunzip -c $appstream > appstream-uncompressed
assert_file_has_content appstream-uncompressed '<id>org\.test\.Hello\.desktop</id>'
assert_has_file $icondir/64x64/org.test.Hello.png

ok "appstream"

# Test that 'flatpak search' works
${FLATPAK} search org.test.Hello > search-results
assert_file_has_content search-results "Print a greeting"

ok "search"

# Replace with the app image with detached icons, check that the icons work

old_icon_hash=(md5sum $icondir/64x64/org.test.Hello.png)
rm $icondir/64x64/org.test.Hello.png
$client delete hello latest
$client  add --detach-icons hello latest $(pwd)/oci/app-image
${FLATPAK} update ${U} --appstream oci-registry >&2
assert_has_file $icondir/64x64/org.test.Hello.png
new_icon_hash=(md5sum $icondir/64x64/org.test.Hello.png)
assert_streq $old_icon_hash $new_icon_hash

ok "detached icons"

# Try installing from the remote

${FLATPAK} ${U} install -y oci-registry org.test.Hello >&2

run org.test.Hello &> hello_out
assert_file_has_content hello_out '^Hello world, from a sandbox$'

ok "install"

make_updated_app oci

${FLATPAK} build-bundle --oci $FL_GPGARGS repos/oci oci/app-image org.test.Hello >&2

$client add hello latest $(pwd)/oci/app-image

OLD_COMMIT=`${FLATPAK} ${U} info --show-commit org.test.Hello`

${FLATPAK} ${U} update -y -vv --ostree-verbose org.test.Hello >&2

NEW_COMMIT=`${FLATPAK} ${U} info --show-commit org.test.Hello`

assert_not_streq "$OLD_COMMIT" "$NEW_COMMIT"

run org.test.Hello &> hello_out
assert_file_has_content hello_out '^Hello world, from a sandboxUPDATED$'

ok "update"

# Remove the app from the registry, check that things were removed properly

$client delete hello latest

images=$(${FLATPAK} remote-ls ${U} --columns=app oci-registry | sort | tr '\n' ' ' | sed 's/ $//')
assert_streq "$images" "org.test.Platform"

${FLATPAK} update ${U} --appstream oci-registry >&2

assert_not_file_has_content $appstream '<id>org\.test\.Hello\.desktop</id>'
assert_not_has_file $icondir/64x64/org.test.Hello.png
assert_not_has_file $icondir/64x64

ok "appstream change"

# Build and install an app with zstd-compressed layers

make_updated_app oci "" "" "ZSTD"

${FLATPAK} build-bundle --oci --oci-layer-compress=zstd $FL_GPGARGS repos/oci oci/app-image-zstd org.test.Hello >&2
file "$(pwd)/oci/app-image-zstd/blobs"/**/* | grep -q Zstandard
$client add hello latest "$(pwd)/oci/app-image-zstd"

${FLATPAK} ${U} update -y -vv --ostree-verbose org.test.Hello >&2

run org.test.Hello &> hello_out
assert_file_has_content hello_out '^Hello world, from a sandboxZSTD$'

ok "export and install zstd layers"

# Change the remote to a non-OCI remote, check that we cleaned up

if [ x${USE_SYSTEMDIR-} == xyes ] ; then
    base=$SYSTEMDIR
else
    base=$USERDIR
fi

assert_has_file $base/oci/oci-registry.index.gz
assert_has_file $base/oci/oci-registry.summary
assert_has_dir $base/appstream/oci-registry
${FLATPAK} remote-modify ${U} --url=${scheme}://127.0.0.1:${port} oci-registry >&2
assert_not_has_file $base/oci/oci-registry.index.gz
assert_not_has_file $base/oci/oci-registry.summary
assert_not_has_dir $base/appstream/oci-registry

ok "change remote to non-OCI"

# Change it back and refetch

${FLATPAK} remote-modify ${U} --url=oci+${scheme}://127.0.0.1:${port} oci-registry >&2
${FLATPAK} update ${U} --appstream oci-registry >&2

# Delete the remote, check that everything was removed

assert_has_file $base/oci/oci-registry.index.gz
assert_has_file $base/oci/oci-registry.summary
assert_has_dir $base/appstream/oci-registry
${FLATPAK} ${U} -y uninstall org.test.Hello >&2
${FLATPAK} ${U} -y uninstall org.test.Platform >&2
${FLATPAK} ${U} remote-delete oci-registry >&2
assert_not_has_file $base/oci/oci-registry.index.gz
assert_not_has_file $base/oci/oci-registry.summary
assert_not_has_dir $base/appstream/oci-registry

ok "delete remote"

# Try installing the platform via a flatpakref file. We use a different URL
# for the runtime repo so we can test that the origin remote is pruned on
# uninstall below.

cat << EOF > runtime-repo.flatpakrepo
[Flatpak Repo]
Version=1
Url=oci+${scheme}://localhost:${port}
Title=The OCI Title
EOF

cat << EOF > org.test.Platform.flatpakref
[Flatpak Ref]
Title=Test Platform
Name=org.test.Platform
Branch=master
Url=oci+${scheme}://127.0.0.1:${port}
IsRuntime=true
RuntimeRepo=file://$(pwd)/runtime-repo.flatpakrepo
EOF

${FLATPAK} ${U} install -y --from ./org.test.Platform.flatpakref >&2

${FLATPAK} remotes > remotes-list
assert_file_has_content remotes-list '^platform-origin'

assert_has_file $base/oci/platform-origin.index.gz

ok "install via flatpakref"

# Uninstall, check that the origin remote was pruned, and files were
# cleaned up properly

${FLATPAK} ${U} -y uninstall org.test.Platform >&2

${FLATPAK} remotes > remotes-list
assert_not_file_has_content remotes-list '^platform-origin'

assert_not_has_file $base/oci/platform-origin.index.gz

ok "prune origin remote"

# Install from a (non-OCI) bundle, check that the repo-url is respected

${FLATPAK} build-bundle --runtime --repo-url "oci+${scheme}://127.0.0.1:${port}" $FL_GPGARGS repos/oci org.test.Platform.flatpak org.test.Platform >&2

${FLATPAK} ${U} install -y --bundle org.test.Platform.flatpak >&2

${FLATPAK} remotes -d > remotes-list
assert_file_has_content remotes-list "^platform-origin.*[ 	]oci+${scheme}://127\.0\.0\.1:${port}"

assert_has_file $base/oci/platform-origin.index.gz

ok "install via bundle"

# Install an app from a bundle

${FLATPAK} build-bundle --repo-url "oci+${scheme}://127.0.0.1:${port}" $FL_GPGARGS repos/oci org.test.Hello.flatpak org.test.Hello >&2

${FLATPAK} ${U} install -y --bundle org.test.Hello.flatpak >&2

${FLATPAK} remotes -d > remotes-list
assert_file_has_content remotes-list "^hello-origin.*[ 	]oci+${scheme}://127\.0\.0\.1:${port}"

assert_has_file $base/oci/hello-origin.index.gz

ok "app install via bundle"

# Install an updated app bundle with a different origin

make_updated_app oci
${FLATPAK} build-bundle --repo-url "${scheme}://127.0.0.1:${port}" $FL_GPGARGS repos/oci org.test.Hello.flatpak org.test.Hello >&2

${FLATPAK} ${U} install -y --bundle org.test.Hello.flatpak >&2

${FLATPAK} remotes -d > remotes-list
assert_file_has_content remotes-list "^hello-origin.*[ 	]${scheme}://127\.0\.0\.1:${port}"

assert_not_has_file $base/oci/hello-origin.index.gz

ok "change remote origin via bundle"

${FLATPAK} ${U} -y uninstall org.test.Hello >&2
${FLATPAK} ${U} -y uninstall org.test.Platform >&2

${FLATPAK} ${U} list --columns=application,origin > flatpak-list
assert_not_file_has_content flatpak-list 'org.test.Platform'
assert_not_file_has_content flatpak-list 'org.test.Hello'

${FLATPAK} ${U} remotes --show-disabled > remotes-list
assert_not_file_has_content remotes-list '^platform-origin'
assert_not_file_has_content remotes-list '^hello-origin'

ok "clean up"

# Install from registry via a docker:// location
# TODO: docker:// locations only support HTTPS
# This needs https://github.com/flatpak/flatpak/pull/5916

if false && [ x${USE_SYSTEMDIR-} != xyes ]; then
    $FLATPAK --user -y install docker://127.0.0.1/platform-image:latest >&2

    ${FLATPAK} ${U} list --columns=application,origin > flatpak-list
    assert_file_has_content flatpak-list '^org.test.Platform	*platform-origin$'

    ${FLATPAK} ${U} remotes --show-disabled > remotes-list
    assert_file_has_content remotes-list '^platform-origin'

    ok "install image from registry"
else
    ok "install image from registry # skip  Not supported"
fi

# Test OCI signing

${FLATPAK} build-bundle --runtime --oci "${FL_GPGARGS}" repos/oci oci/platform-image org.test.Platform >&2
digest=$(jq -r '.manifests[0].digest' "$(pwd)/oci/platform-image/index.json")
make_oci_signature "${digest}" "127.0.0.1:${port}/platform:latest" > "$(pwd)/oci/platform-image-signature-1"
make_oci_signature "${digest}" "127.0.0.1:${port}/platform:latest" "${FL_GPGCMDARGS2}"> "$(pwd)/oci/platform-image-signature-2"

$client add platform latest "$(pwd)/oci/platform-image"
$client add-signature platform "${digest}" "$(pwd)/oci/platform-image-signature-1"

${FLATPAK} build-bundle --oci "${FL_GPGARGS}" repos/oci oci/app-image org.test.Hello >&2
digest=$(jq -r '.manifests[0].digest' "$(pwd)/oci/app-image/index.json")
make_oci_signature "${digest}" "127.0.0.1:${port}/hello:latest" > "$(pwd)/oci/app-image-signature-1"
make_oci_signature "${digest}" "127.0.0.1:${port}/hello:latest" "$FL_GPGCMDARGS2" > "$(pwd)/oci/app-image-signature-2"

$client add hello latest "$(pwd)/oci/app-image"

${FLATPAK} ${U} remote-add oci-registry-sig "oci+${scheme}://127.0.0.1:${port}" \
    --signature-lookaside "${scheme}://127.0.0.1:${port}/sig-lookaside" \
    --gpg-import=${FL_GPG_HOMEDIR}/pubring.gpg >&2

if ${FLATPAK} ${U} install -y oci-registry-sig org.test.Hello >&2; then
    assert_not_reached "Should fail install due to missing signature key"
fi

$client add-signature hello "${digest}" "$(pwd)/oci/app-image-signature-2"
if ${FLATPAK} ${U} install -y oci-registry-sig org.test.Hello >&2; then
    assert_not_reached "Should fail install due to wrong signature key"
fi

$client add-signature hello "${digest}" "$(pwd)/oci/app-image-signature-1"
${FLATPAK} ${U} install -y oci-registry-sig org.test.Hello >&2

${FLATPAK} build-bundle --oci "${FL_GPGARGS}" repos/oci oci/app-image org.test.Hello >&2
digest=$(jq -r '.manifests[0].digest' "$(pwd)/oci/app-image/index.json")
make_oci_signature "${digest}" "127.0.0.1:${port}/hello:latest" > "$(pwd)/oci/app-image-signature-1"
make_oci_signature "${digest}" "127.0.0.1:${port}/hello:latest" "$FL_GPGCMDARGS2" > "$(pwd)/oci/app-image-signature-2"

$client add hello latest "$(pwd)/oci/app-image"
if ${FLATPAK} update -y org.test.Hello >&2; then
    assert_not_reached "Should fail install due to outdated signature key"
fi

$client add-signature hello "${digest}" "$(pwd)/oci/app-image-signature-1"
${FLATPAK} update -y org.test.Hello >&2

${FLATPAK} uninstall -y org.test.Hello >&2

${FLATPAK} ${U} remote-delete --force oci-registry-sig >&2
${FLATPAK} ${U} remote-add oci-registry-sig "oci+${scheme}://127.0.0.1:${port}" \
    --signature-lookaside "${scheme}://127.0.0.1:${port}/sig-lookaside" \
    --gpg-import=${FL_GPG_HOMEDIR2}/pubring.gpg >&2

if ${FLATPAK} ${U} install -y oci-registry-sig org.test.Hello >&2; then
    assert_not_reached "Should fail install due to locally changed trusted key"
fi

$client add-signature hello "${digest}" "$(pwd)/oci/app-image-signature-2"

${FLATPAK} ${U} install -y oci-registry-sig org.test.Hello >&2

ok "signed images"
===== ./tests/test-unused.sh =====
#!/bin/bash
#
# Copyright (C) 2020 Alexander Larsson <alexl@redhat.com>
#
# 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 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., 59 Temple Place - Suite 330,
# Boston, MA 02111-1307, USA.

set -euo pipefail

# We default to use systemdir, so we can also test shadowing from the user dir
export USE_SYSTEMDIR=yes

. $(dirname $0)/libtest.sh

skip_without_bwrap
skip_revokefs_without_fuse

echo "1..3"

setup_empty_repo &> /dev/null

# Manually add the user remote too
$FLATPAK remote-add --user --gpg-import=${FL_GPG_HOMEDIR}/pubring.gpg test-repo "http://127.0.0.1:${port}/test" >&2


# This tests the detection of unused refs. Used refs are any that have
# some kind of dependency from an installed application to the ref.
#
# Possible reasons a ref are used:
# Direct use:
# * App is installed
# * Runtime is marked as pinned and installed
#
# Dependent ref (of a used ref)
# * App $USED uses runtime $DEP
# * App $USED uses runtime $DEP as sdk (so that if you're developing the app we don't remove the sdk)
# * Runtime $USED has extra-data and not NoRuntime, and lists $DEP as "ExtensionOf"
# * Runtime $USED uses runtime $DEP as sdk
#
# Related ref (of a used ref):
# * App $USED uses extension $REL, which is not marked as autoprune-unless
# * Runtime $USED uses extension $REL, which is not marked as autoprune-unless
#
# There are options to affect this:
# * Specific refs can be excluded (never considered used), used to emulate them being uninstalled in a transaction
# * Specify custom new metadata for an installed ref, used to emulate it being updated in a transaction
#
# Additionally, for the system installation, the dependencies are considered from the user installation, such that any dependencies
# in the user installation that are resolved from the system installation (i.e. not in the user installation) are considered used.
# I.E. if an app and its runtime both are installed in the user dir, it is not considered used in the system installation, but if
# only the app is, then it is considered used.

create_runtime () {
    local ID="${1}"
    local SDK="${2}"

    local BRANCH=stable
    local DIR=`mktemp -d`

    mkdir ${DIR}/files
    mkdir ${DIR}/usr
    cat > ${DIR}/metadata <<EOF
[Runtime]
name=${ID}
runtime=${ID}/$ARCH/$BRANCH
EOF

    if test x$SDK != "x"; then
       cat >> ${DIR}/metadata <<EOF
sdk=${SDK}/$ARCH/$BRANCH
EOF
    fi

    $FLATPAK build-finish $DIR ${finish_args[$ID]:-} &> /dev/null
    $FLATPAK build-export -v ${FL_GPGARGS} --disable-sandbox --runtime repos/test ${DIR} ${BRANCH} &> /dev/null
    rm -rf ${DIR}
}

create_app () {
    local ID="${1}"
    local RUNTIME="${2}"
    local SDK="${3}"

    local BRANCH=stable
    local DIR=`mktemp -d`

    mkdir ${DIR}/files
    cat > ${DIR}/metadata <<EOF
[Application]
name=${ID}
runtime=${RUNTIME}/$ARCH/$BRANCH
EOF

    if test x$SDK != "x"; then
       cat >> ${DIR}/metadata <<EOF
sdk=${SDK}/$ARCH/$BRANCH
EOF
    fi

    set -x
    $FLATPAK build-finish ${DIR}  ${finish_args[$ID]:-} &> /dev/null

    $FLATPAK build-export ${FL_GPGARGS} --disable-sandbox repos/test ${DIR} ${BRANCH} &> /dev/null > /dev/null
    rm -rf ${DIR}
}

declare -a runtimes
declare -A runtimes_sdk
declare -A runtimes_pinned
declare -a apps
declare -A apps_runtime
declare -A apps_sdk

declare -A finish_args

declare -A installs_in

make_runtime() {
    { set +x; } 2>/dev/null
    local ID="org.runtime.${1}"
    local SDK="${2:-}"
    if test x$SDK != x; then
        SDK=org.runtime.$SDK
    fi
    runtimes+=( "$ID" )
    runtimes_sdk["$ID"]="$SDK"
    set -x
}

pin_runtime() {
    { set +x; } 2>/dev/null
    local ID="org.runtime.${1}"
    runtimes_pinned["$ID"]="yes"
    set -x
}

install_runtime_in() {
    { set +x; } 2>/dev/null
    local ID="org.runtime.${1}"
    local WHERE="${2}"
    installs_in["$ID"]=$WHERE
    set -x
}

make_extension() {
    { set +x; } 2>/dev/null
    local ID="org.extension.${1}"
    runtimes+=( "$ID" )
    set -x
}

pin_extension() {
    { set +x; } 2>/dev/null
    local ID="org.extension.${1}"
    runtimes_pinned["$ID"]="yes"
    set -x
}

install_extension_in() {
    { set +x; } 2>/dev/null
    local ID="org.extension.${1}"
    local WHERE="${2}"
    installs_in["$ID"]=$WHERE
    set -x
}

runtime_add_extension() {
    { set +x; } 2>/dev/null
    local RUNTIME="org.runtime.${1}"
    local EXT="org.extension.${2}"
    finish_args["$RUNTIME"]="${finish_args[$RUNTIME]:-} --extension=${EXT}=directory=/ext"
    set -x
}

runtime_add_autoprune_extension() {
    { set +x; } 2>/dev/null
    local RUNTIME="org.runtime.${1}"
    local EXT="org.extension.${2}"
    finish_args["$RUNTIME"]="${finish_args[$RUNTIME]:-} --extension=${EXT}=directory=/ext --extension=${EXT}=autoprune-unless=active-gl-driver"
    set -x
}

make_runtime_full() {
    make_runtime "$1" "${2:-}"
    make_extension "$1.Locale"
    runtime_add_extension "$1" $1.Locale
    make_extension "$1.Debug"
    runtime_add_extension "$1" $1.Debug
}

app_add_extension() {
    { set +x; } 2>/dev/null
    local APP="org.app.${1}"
    local EXT="org.extension.${2}"
    finish_args["$APP"]="${finish_args[$APP]:-} --extension=${EXT}=directory=/ext"
    set -x
}

install_app_in() {
    { set +x; } 2>/dev/null
    local ID="org.app.${1}"
    local WHERE="${2}"
    installs_in["$ID"]=$WHERE
    set -x
}

app_add_autoprune_extension() {
    { set +x; } 2>/dev/null
    local APP="org.app.${1}"
    local EXT="org.extension.${2}"
    finish_args["$RUNTIME"]="${finish_args[$APP]:-} --extension=${EXT}=directory=/ext --extension=${EXT}=autoprune-unless=active-gl-driver"
    set -x
}

make_app() {
    { set +x; } 2>/dev/null
    local ID="org.app.${1}"
    local RUNTIME="org.runtime.${2}"
    local SDK="${3:-}"
    if test x$SDK != x; then
        SDK=org.runtime.$SDK
    fi

    apps+=( $ID )
    apps_runtime[$ID]="$RUNTIME"
    apps_sdk[$ID]="$SDK"
    set -x
}

make_app_full() {
    make_app "$1" "$2" "${3:-}"
    make_extension "$1.Locale"
    app_add_extension "$1" $1.Locale
    make_extension "$1.Debug"
    app_add_extension "$1" $1.Debug
}

make_it_happen() {
    { set +x; } 2>/dev/null
    for runtime in "${runtimes[@]}"; do
        create_runtime "$runtime" "${runtimes_sdk[$runtime]:-}"
    done
    for app in "${apps[@]}"; do
        create_app "$app" "${apps_runtime[$app]}" "${apps_sdk[$app]}"
    done
    update_repo  &> /dev/null

    for runtime in "${runtimes[@]}"; do
        local in=${installs_in[${runtime}]:-system}
        if test $in = system -o $in = both; then
            $FLATPAK install -y --system --no-deps --no-related --no-auto-pin test-repo runtime/$runtime/$ARCH/stable  &> /dev/null
        fi
        if test $in = user -o $in = both; then
            $FLATPAK install -y --user --no-deps --no-related --no-auto-pin test-repo runtime/$runtime/$ARCH/stable  &> /dev/null
        fi
        if test "x${runtimes_pinned[$runtime]:-}" == "xyes"; then
            $FLATPAK pin $runtime//stable
        fi
    done
    for app in "${apps[@]}"; do
        local in=${installs_in[$app]:-system}
        if test $in = system -o $in = both; then
            $FLATPAK install -y --system --no-deps --no-related --no-auto-pin test-repo app/$app/$ARCH/stable  &> /dev/null
        fi
        if test $in = user -o $in = both; then
            $FLATPAK install -y --user --no-deps --no-related --no-auto-pin test-repo app/$app/$ARCH/stable  &> /dev/null
        fi
    done

    $FLATPAK list --system -a --columns=ref | sort > installed.txt
    $FLATPAK list --user -a --columns=ref | sort > user-installed.txt

    # No USER_ should be in system dir
    assert_not_file_has_content installed.txt USER_

    set -x
}

verify_unused() {
    comm -23 installed.txt unused.txt > used.txt
    comm -12 used.txt unused.txt > used-and-unused.txt
    assert_file_empty used-and-unused.txt

    #echo ======= UNUSED ==============
    #cat unused.txt
    #echo ======= USED ==============
    #cat used.txt
    #echo =============================

    assert_not_file_has_content unused.txt "\.USED"
    assert_not_file_has_content used.txt "\.UNUSED"
    # Also, no app or app extensions are unused
    assert_not_file_has_content unused.txt "\.APP"
}

verify_autopruned() {
    assert_file_has_content autopruned.txt "\.NONACTIVEGL"
    assert_not_file_has_content autopruned.txt "PINNED_.\.NONACTIVEGL"
}

# This is used for the autoprune check
export FLATPAK_GL_DRIVERS=ACTIVEGL

# Runtime for app A, and it has its own sdk
make_runtime_full USED_A USED_A_SDK
make_runtime_full USED_A_SDK
# Sdk for app A, and it has its own sdk
make_runtime USED_A_SDK2 USED_A_SDK3
make_runtime USED_A_SDK3
# App A
make_app_full APP_A USED_A USED_A_SDK2

# Plain unused runtime
make_runtime_full UNUSED_B

# unused runtime with sdk
make_runtime_full UNUSED_C UNUSED_B_SDK
make_runtime_full UNUSED_C_SDK

# Unused extension and dependency
make_extension UNUSED_D

# Pinned runtime
make_runtime_full USED_E
pin_runtime USED_E

# Pinned extension
make_extension USED_F
pin_extension USED_F

# app with runtime with autopruned extension
make_app APP_G USED_G
make_runtime USED_G
make_extension USED_G.ACTIVEGL
runtime_add_autoprune_extension USED_G USED_G.ACTIVEGL
make_extension UNUSED_G.NONACTIVEGL
runtime_add_autoprune_extension USED_G UNUSED_G.NONACTIVEGL
make_extension PINNED_G.NONACTIVEGL
runtime_add_autoprune_extension USED_G PINNED_G.NONACTIVEGL
pin_extension PINNED_G.NONACTIVEGL

# unused runtime with autopruned extension
make_runtime UNUSED_H
make_extension UNUSED_H.ACTIVEGL
runtime_add_autoprune_extension UNUSED_H UNUSED_H.ACTIVEGL
make_extension UNUSED_H.NONACTIVEGL
runtime_add_autoprune_extension UNUSED_H UNUSED_H.NONACTIVEGL

# pinned runtime with autopruned extension
make_runtime USED_I
pin_runtime USED_I
make_extension USED_I.ACTIVEGL
runtime_add_autoprune_extension USED_I USED_I.ACTIVEGL
make_extension UNUSED_I.NONACTIVEGL
runtime_add_autoprune_extension USED_I UNUSED_I.NONACTIVEGL

# System runtime used by user app
make_runtime USED_J
make_app USER_APP_J USED_J
install_app_in USER_APP_J user

# System runtime shadowed by user app and runtime, but with and extension that isn't shadowed and one that is
make_extension USED_EXT_K
make_extension UNUSED_EXT2_K
install_extension_in UNUSED_EXT2_K both
make_runtime UNUSED_K
install_runtime_in UNUSED_K both
runtime_add_extension UNUSED_K USED_EXT_K
runtime_add_extension UNUSED_K UNUSED_EXT2_K
make_app USER_APP_K UNUSED_K
install_app_in USER_APP_K user

make_it_happen

# Verify that the right thing got user-installed
assert_file_has_content user-installed.txt USER_APP_J
assert_file_has_content user-installed.txt USER_APP_K
assert_file_has_content user-installed.txt UNUSED_K
assert_file_has_content user-installed.txt UNUSED_EXT2_K
assert_not_file_has_content user-installed.txt USED_EXT_K

${test_builddir}/list-unused | sed s@^app/@@g | sed s@^runtime/@@g | sort > unused.txt

verify_unused

ok "list unused regular"

${test_builddir}/list-unused --filter-autoprune | sed s@^app/@@g | sed s@^runtime/@@g | sort > autopruned.txt

verify_autopruned

ok "list autopruned"

mv unused.txt old-unused.txt

${test_builddir}/list-unused --exclude "app/org.app.APP_A/$ARCH/stable" | sed s@^app/@@g | sed s@^runtime/@@g | sort > unused.txt

# We don't report the excluded ref itself as unused. It's as if it wasn't even installed
assert_not_file_has_content unused.txt "org.app.APP_A/"

# Excluding a ref should not use more refs
comm -23 old-unused.txt unused.txt > newly-used.txt
assert_file_empty newly-used.txt

# We should add all dependencies from the app, but no more
assert_file_has_content unused.txt "org.extension.APP_A.Debug/"
assert_file_has_content unused.txt "org.extension.APP_A.Locale/"
assert_file_has_content unused.txt "org.runtime.USED_A/"
assert_file_has_content unused.txt "org.extension.USED_A.Debug/"
assert_file_has_content unused.txt "org.extension.USED_A.Locale/"
assert_file_has_content unused.txt "org.runtime.USED_A_SDK/"
assert_file_has_content unused.txt "org.extension.USED_A_SDK.Debug/"
assert_file_has_content unused.txt "org.extension.USED_A_SDK.Locale/"
assert_file_has_content unused.txt "org.runtime.USED_A_SDK2/"
assert_file_has_content unused.txt "org.runtime.USED_A_SDK3/"

comm -13 old-unused.txt unused.txt > newly-unused.txt
if [ $(cat newly-unused.txt | wc -l) -ne 10 ]; then
    assert_not_reached "Unexpected unused ref"
fi

ok "list unused exclude"

===== ./tests/test-portal.c =====
/* vi:set et sw=2 sts=2 cin cino=t0,f0,(0,{s,>2s,n-s,^-s,e-s:
 * Copyright © 2018-2021 Collabora Ltd.
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 */

#include <errno.h>
#include <fcntl.h>
#include <string.h>
#include <sys/stat.h>
#include <unistd.h>

#include "libglnx.h"

#include <glib.h>
#include <gio/gio.h>
#include <gio/gunixfdlist.h>

#include "portal/flatpak-portal.h"
#include "portal/flatpak-portal-dbus.h"
#include "testlib.h"

typedef struct
{
  TestsDBusDaemon dbus_daemon;
  GSubprocess *portal;
  gchar *portal_path;
  gchar *mock_flatpak;
  PortalFlatpak *proxy;
  GDBusConnection *conn;
} Fixture;

typedef struct
{
  int dummy;
} Config;

static void
setup (Fixture *f,
       gconstpointer context G_GNUC_UNUSED)
{
  g_autoptr(GError) error = NULL;

  tests_dbus_daemon_setup (&f->dbus_daemon);

  f->portal_path = g_strdup (g_getenv ("FLATPAK_PORTAL"));

  if (f->portal_path == NULL)
    f->portal_path = g_strdup (LIBEXECDIR "/flatpak-portal");

  f->mock_flatpak = g_test_build_filename (G_TEST_BUILT, "mock-flatpak", NULL);

  f->conn = g_dbus_connection_new_for_address_sync (f->dbus_daemon.dbus_address,
                                                    (G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT |
                                                     G_DBUS_CONNECTION_FLAGS_MESSAGE_BUS_CONNECTION),
                                                    NULL, NULL, &error);
  g_assert_no_error (error);
  g_assert_nonnull (f->conn);
}

/* Don't corrupt TAP output if portal outputs on stdout */
static void
launcher_stdout_to_our_stderr (GSubprocessLauncher *launcher)
{
  glnx_autofd int stderr_copy = -1;

  stderr_copy = dup (STDERR_FILENO);
  g_assert_no_errno (stderr_copy);
  g_assert_no_errno (fcntl (stderr_copy, F_SETFD, FD_CLOEXEC));
  g_subprocess_launcher_take_stdout_fd (launcher, g_steal_fd (&stderr_copy));
}

static GSubprocessLauncher *
fixture_make_launcher (Fixture *f)
{
  g_autoptr(GSubprocessLauncher) launcher = NULL;

  launcher = g_subprocess_launcher_new (G_SUBPROCESS_FLAGS_NONE);
  launcher_stdout_to_our_stderr (launcher);
  g_subprocess_launcher_setenv (launcher,
                                "DBUS_SESSION_BUS_ADDRESS",
                                f->dbus_daemon.dbus_address,
                                TRUE);
  g_subprocess_launcher_setenv (launcher,
                                "FLATPAK_PORTAL_MOCK_FLATPAK",
                                f->mock_flatpak,
                                TRUE);

  return g_steal_pointer (&launcher);
}

static void
name_appeared_cb (GDBusConnection *conn,
                  const char *name,
                  const char *owner,
                  gpointer user_data)
{
  gchar **name_owner_p = user_data;

  g_clear_pointer (name_owner_p, g_free);
  *name_owner_p = g_strdup (owner);
}

static void
name_vanished_cb (GDBusConnection *conn,
                  const char *name,
                  gpointer user_data)
{
  gchar **name_owner_p = user_data;

  g_clear_pointer (name_owner_p, g_free);
  *name_owner_p = g_strdup ("");
}

static void
name_owner_watch_removed_cb (gpointer user_data)
{
  gchar **name_owner_p = user_data;

  g_clear_pointer (name_owner_p, g_free);
}

static void
fixture_wait_for_name_to_be_owned (Fixture *f,
                                   const char *name)
{
  g_autofree gchar *name_owner = NULL;
  guint watch;

  watch = g_bus_watch_name_on_connection (f->conn,
                                          name,
                                          G_BUS_NAME_WATCHER_FLAGS_NONE,
                                          name_appeared_cb,
                                          name_vanished_cb,
                                          &name_owner,
                                          name_owner_watch_removed_cb);

  /* Wait for name to become owned */
  while (name_owner == NULL || name_owner[0] == '\0')
    g_main_context_iteration (NULL, TRUE);

  g_bus_unwatch_name (watch);

  /* Wait for watch to be cleaned up */
  while (name_owner != NULL)
    g_main_context_iteration (NULL, TRUE);
}

static void
fixture_start_portal (Fixture *f)
{
  g_autoptr(GError) error = NULL;
  g_autoptr(GSubprocessLauncher) launcher = NULL;

  launcher = fixture_make_launcher (f);
  f->portal = g_subprocess_launcher_spawn (launcher, &error,
                                           f->portal_path,
                                           NULL);
  g_assert_no_error (error);
  g_assert_nonnull (f->portal);

  fixture_wait_for_name_to_be_owned (f, FLATPAK_PORTAL_BUS_NAME);

  f->proxy = portal_flatpak_proxy_new_sync (f->conn,
                                            G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START,
                                            FLATPAK_PORTAL_BUS_NAME,
                                            FLATPAK_PORTAL_PATH,
                                            NULL,
                                            &error);
  g_assert_no_error (error);
  g_assert_nonnull (f->proxy);
}

static void
test_help (Fixture *f,
           gconstpointer context G_GNUC_UNUSED)
{
  g_autoptr(GSubprocessLauncher) launcher = NULL;
  g_autofree gchar *stdout_buf;
  g_autofree gchar *stderr_buf;
  g_autoptr(GError) error = NULL;

  /* Don't use fixture_make_launcher() here because we want to
   * capture stdout */
  launcher = g_subprocess_launcher_new (G_SUBPROCESS_FLAGS_STDOUT_PIPE |
                                        G_SUBPROCESS_FLAGS_STDERR_PIPE);
  g_subprocess_launcher_setenv (launcher,
                                "DBUS_SESSION_BUS_ADDRESS",
                                f->dbus_daemon.dbus_address,
                                TRUE);

  f->portal = g_subprocess_launcher_spawn (launcher, &error,
                                           f->portal_path,
                                           "--help",
                                           NULL);
  g_assert_no_error (error);
  g_assert_nonnull (f->portal);

  g_subprocess_communicate_utf8 (f->portal, NULL, NULL, &stdout_buf,
                                 &stderr_buf, &error);
  g_assert_nonnull (stdout_buf);
  g_assert_nonnull (stderr_buf);
  g_test_message ("flatpak-portal --help: %s", stdout_buf);
  g_assert_true (strstr (stdout_buf, "--replace") != NULL);

  g_subprocess_wait_check (f->portal, NULL, &error);
  g_assert_no_error (error);
}

static void
count_successful_exit_cb (PortalFlatpak *proxy,
                          guint pid,
                          guint wait_status,
                          gpointer user_data)
{
  gsize *times_exited_p = user_data;

  g_info ("Process %u exited with wait status %u", pid, wait_status);
  g_assert_true (WIFEXITED (wait_status));
  g_assert_cmpuint (WEXITSTATUS (wait_status), ==, 0);
  (*times_exited_p) += 1;
}

static void
test_basic (Fixture *f,
            gconstpointer context G_GNUC_UNUSED)
{
  g_autoptr(GError) error = NULL;
  g_autoptr(GUnixFDList) fds_out = NULL;
  guint pid;
  gboolean ok;
  const char * const argv[] = { "hello", NULL };
  gsize times_exited = 0;
  gulong handler_id;

  fixture_start_portal (f);

  /* We can't easily tell whether EXPOSE_PIDS ought to be set or not */
  g_assert_cmpuint ((portal_flatpak_get_supports (f->proxy) &
                     (~FLATPAK_SPAWN_SUPPORT_FLAGS_EXPOSE_PIDS)), ==, 0);
  g_assert_cmpuint (portal_flatpak_get_version (f->proxy), ==, 8);

  handler_id = g_signal_connect (f->proxy, "spawn-exited",
                                 G_CALLBACK (count_successful_exit_cb),
                                 &times_exited);

  ok = portal_flatpak_call_spawn_sync (f->proxy,
                                       "/",           /* cwd */
                                       argv,          /* argv */
                                       g_variant_new ("a{uh}", NULL),
                                       g_variant_new ("a{ss}", NULL),
                                       FLATPAK_SPAWN_FLAGS_NONE,
                                       g_variant_new ("a{sv}", NULL),
                                       NULL,          /* fd list */
                                       &pid,
                                       &fds_out,
                                       NULL,
                                       &error);
  g_assert_no_error (error);
  g_assert_true (ok);
  g_assert_cmpuint (pid, >, 1);

  while (times_exited == 0)
    g_main_context_iteration (NULL, TRUE);

  g_signal_handler_disconnect (f->proxy, handler_id);

  if (fds_out != NULL)
    g_assert_cmpint (g_unix_fd_list_get_length (fds_out), ==, 0);

  g_subprocess_send_signal (f->portal, SIGTERM);
  g_subprocess_wait (f->portal, NULL, &error);
  g_assert_no_error (error);
}

static void
test_fd_passing (Fixture *f,
                 gconstpointer context G_GNUC_UNUSED)
{
#define SOME_FDS 16
  g_autoptr(GError) error = NULL;
  char *tempfile_paths[SOME_FDS];
  int tempfile_fds[SOME_FDS];
  guint gap_size;
  gsize times_exited = 0;
  gulong handler_id;
  gsize i;

  fixture_start_portal (f);

  handler_id = g_signal_connect (f->proxy, "spawn-exited",
                                 G_CALLBACK (count_successful_exit_cb),
                                 &times_exited);

  for (i = 0; i < SOME_FDS; i++)
    {
      tempfile_paths[i] = g_strdup ("/tmp/flatpak-portal-test.XXXXXX");
      tempfile_fds[i] = g_mkstemp (tempfile_paths[i]);
      g_assert_no_errno (tempfile_fds[i]);
    }

  /* Using a non-contiguous block of fds can help to tickle bugs in the
   * portal. */
  for (gap_size = 0; gap_size < 128; gap_size += 16)
    {
      g_autoptr(GUnixFDList) fds_in = g_unix_fd_list_new ();
      g_autoptr(GUnixFDList) fds_out = NULL;
      g_auto(GVariantBuilder) fd_map_builder = {};
      g_auto(GVariantBuilder) env_builder = {};
      guint pid;
      gboolean ok;
      const char * const argv[] = { "hello", NULL };
      g_autofree char *output = NULL;

      g_variant_builder_init (&fd_map_builder, G_VARIANT_TYPE ("a{uh}"));
      g_variant_builder_init (&env_builder, G_VARIANT_TYPE ("a{ss}"));
      times_exited = 0;

      g_variant_builder_add (&env_builder, "{ss}", "FOO", "bar");

      for (i = 0; i < SOME_FDS; i++)
        {
          int handle = g_unix_fd_list_append (fds_in, tempfile_fds[i], &error);
          guint32 desired_fd;

          g_assert_no_error (error);
          g_assert_cmpint (handle, >=, 0);

          if (i <= STDERR_FILENO)
            desired_fd = i;
          else
            desired_fd = i + gap_size;

          g_variant_builder_add (&fd_map_builder, "{uh}",
                                 desired_fd, (gint32) handle);
        }

      ok = portal_flatpak_call_spawn_sync (f->proxy,
                                           "/",           /* cwd */
                                           argv,          /* argv */
                                           g_variant_builder_end (&fd_map_builder),
                                           g_variant_builder_end (&env_builder),
                                           FLATPAK_SPAWN_FLAGS_NONE,
                                           g_variant_new ("a{sv}", NULL),
                                           fds_in,
                                           &pid,
                                           &fds_out,
                                           NULL,
                                           &error);
      g_assert_no_error (error);
      g_assert_true (ok);
      g_assert_cmpuint (pid, >, 1);

      /* Wait for this one to exit */
      while (times_exited == 0)
        g_main_context_iteration (NULL, TRUE);

      if (fds_out != NULL)
        g_assert_cmpint (g_unix_fd_list_get_length (fds_out), ==, 0);

      /* stdout from the portal should have ended up in temp file [1] */
      g_assert_no_errno (lseek (tempfile_fds[1], 0, SEEK_SET));
      output = glnx_fd_readall_utf8 (tempfile_fds[1], NULL, NULL, &error);
      g_assert_no_error (error);
      g_assert_nonnull (output);
      g_assert_no_errno (lseek (tempfile_fds[1], 0, SEEK_SET));
      g_assert_no_errno (ftruncate (tempfile_fds[1], 0));
      g_test_message ("Output from mock Flatpak: %s", output);

      if (strstr (output, "env[FOO] = bar") != NULL)
        g_test_message ("Found env[FOO] = bar in output");
      else
        g_error ("env[FOO] = bar not found in \"%s\"", output);

      for (i = 0; i < SOME_FDS; i++)
        {
          struct stat stat_buf;
          g_autofree char *expected = NULL;
          int desired_fd;

          g_assert_no_errno (fstat (tempfile_fds[i], &stat_buf));

          if (i <= STDERR_FILENO)
            desired_fd = i;
          else
            desired_fd = i + gap_size;

          expected = g_strdup_printf ("fd[%d] = (dev=%" G_GUINT64_FORMAT " ino=%" G_GUINT64_FORMAT ")",
                                      desired_fd,
                                      (guint64) stat_buf.st_dev,
                                      (guint64) stat_buf.st_ino);

          if (strstr (output, expected) != NULL)
            g_test_message ("fd %d OK: \"%s\"", desired_fd, expected);
          else
            g_error ("\"%s\" not found in \"%s\"", expected, output);
        }
    }

  g_signal_handler_disconnect (f->proxy, handler_id);

  g_subprocess_send_signal (f->portal, SIGTERM);
  g_subprocess_wait (f->portal, NULL, &error);
  g_assert_no_error (error);

  for (i = 0; i < SOME_FDS; i++)
    {
      g_assert_no_errno (unlink (tempfile_paths[i]));
      glnx_close_fd (&tempfile_fds[i]);
      g_free (tempfile_paths[i]);
    }
}

static void
test_replace (Fixture *f,
              gconstpointer context G_GNUC_UNUSED)
{
  g_autoptr(GSubprocessLauncher) launcher = NULL;
  g_autoptr(GError) error = NULL;
  g_autoptr(GSubprocess) gets_replaced = NULL;

  /* Not using fixture_start_portal() here because we want to --replace */
  launcher = fixture_make_launcher (f);
  gets_replaced = g_subprocess_launcher_spawn (launcher, &error,
                                               f->portal_path,
                                               "--replace",
                                               NULL);
  g_assert_no_error (error);
  g_assert_nonnull (gets_replaced);

  fixture_wait_for_name_to_be_owned (f, FLATPAK_PORTAL_BUS_NAME);

  g_clear_object (&launcher);
  launcher = fixture_make_launcher (f);
  f->portal = g_subprocess_launcher_spawn (launcher, &error,
                                           f->portal_path,
                                           "--replace",
                                           NULL);
  g_assert_no_error (error);
  g_assert_nonnull (f->portal);

  /* f->portal replaces gets_replaced, which exits 0 */
  g_subprocess_wait_check (gets_replaced, NULL, &error);
  g_assert_no_error (error);

  g_subprocess_send_signal (f->portal, SIGTERM);
  g_subprocess_wait (f->portal, NULL, &error);
  g_assert_no_error (error);
}

static void
teardown (Fixture *f,
          gconstpointer context G_GNUC_UNUSED)
{
  tests_dbus_daemon_teardown (&f->dbus_daemon);
  g_clear_object (&f->portal);
  g_free (f->portal_path);
  g_free (f->mock_flatpak);
}

int
main (int argc,
      char **argv)
{
  g_test_init (&argc, &argv, NULL);

  g_test_add ("/help", Fixture, NULL, setup, test_help, teardown);
  g_test_add ("/basic", Fixture, NULL, setup, test_basic, teardown);
  g_test_add ("/fd-passing", Fixture, NULL, setup, test_fd_passing, teardown);
  g_test_add ("/replace", Fixture, NULL, setup, test_replace, teardown);

  return g_test_run ();
}

===== ./tests/libpreload.c =====
/* vi:set et sw=2 sts=2 cin cino=t0,f0,(0,{s,>2s,n-s,^-s,e-s:
 * Copyright 2021 Collabora Ltd.
 * SPDX-License-Identifier: LGPL-2-or-later
 */

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>

__attribute__((constructor)) static void
ctor (void)
{
  pid_t me = getpid ();
  struct stat buf;

  fprintf (stderr, "LD_PRELOAD module got loaded by process %d\n", me);

  if (stat ("/.flatpak-info", &buf) == 0)
    {
      fprintf (stderr, "OK: pid %d is in a Flatpak sandbox\n", me);
    }
  else
    {
      /* If the --env=LD_PRELOAD had come from a call to flatpak-portal,
       * then this would be a sandbox escape (GHSA-4ppf-fxf6-vxg2). */
      fprintf (stderr, "Error: pid %d is not in a Flatpak sandbox\n", me);
      abort ();
    }
}

===== ./tests/test-metadata-validation.sh =====
#!/bin/bash
#
# Copyright (C) 2021 Matthew Leeds <mwleeds@protonmail.com>
#
# SPDX-License-Identifier: LGPL-2.0-or-later

set -euo pipefail

. $(dirname $0)/libtest.sh

echo "1..7"

setup_repo

COUNTER=1

create_app () {
    local OPTIONS="$1"
    local DIR=`mktemp -d`

    mkdir ${DIR}/files
    echo $COUNTER > ${DIR}/files/counter
    let COUNTER=COUNTER+1

    local INVALID=""
    if [[ $OPTIONS =~ "invalid" ]]; then
        INVALID=invalidkeyfileline
    fi
    cat > ${DIR}/metadata <<EOF
[Application]
name=org.test.Malicious
runtime=org.test.Platform/${ARCH}/master
$INVALID

[Context]
EOF
    if [[ $OPTIONS =~ "mismatch" ]]; then
        echo -e "filesystems=host;" >> ${DIR}/metadata
    fi
    if [[ $OPTIONS =~ "hidden" ]]; then
        echo -ne "\0" >> ${DIR}/metadata
        echo -e "\nfilesystems=home;" >> ${DIR}/metadata
    fi
    local XA_METADATA=--add-metadata-string=xa.metadata="$(head -n6 ${DIR}/metadata)"$'\n'
    if [[ $OPTIONS =~ "no-xametadata" ]]; then
        XA_METADATA="--add-metadata-string=xa.nometadata=1"
    fi
    ostree commit --repo=repos/test --branch=app/org.test.Malicious/${ARCH}/master ${FL_GPGARGS} "$XA_METADATA" ${DIR}/ >&2
    if [[ $OPTIONS =~ "no-cache-in-summary" ]]; then
        ostree --repo=repos/test ${FL_GPGARGS} summary -u >&2
        # force use of legacy summary format
        rm -rf repos/test/summary.idx repos/test/summaries
    else
        update_repo
    fi
    rm -rf ${DIR}
}

cleanup_repo () {
    ostree refs --repo=repos/test --delete app/org.test.Malicious/${ARCH}/master >&2
    update_repo
}

create_app "hidden"

if ${FLATPAK} ${U} install -y test-repo org.test.Malicious &>install-error-log; then
    assert_not_reached "Should not be able to install app with hidden permissions"
fi

assert_file_has_content install-error-log "not matching expected metadata"

assert_not_has_dir $FL_DIR/app/org.test.Malicious/current/active

cleanup_repo

ok "app with hidden permissions can't be installed (CVE-2021-43860)"

create_app no-xametadata

# The install will fail because the metadata in the summary doesn't match the metadata on the commit
# The missing xa.metadata in the commit got turned into "" in the xa.cache
if ${FLATPAK} ${U} install -y test-repo org.test.Malicious &>install-error-log; then
    assert_not_reached "Should not be able to install app with missing xa.metadata"
fi

assert_file_has_content install-error-log "not matching expected metadata"

assert_not_has_dir $FL_DIR/app/org.test.Malicious/current/active

cleanup_repo

ok "app with no xa.metadata can't be installed"

create_app "no-xametadata no-cache-in-summary"

# The install will fail because there's no metadata in the summary or on the commit
if ${FLATPAK} ${U} install -y test-repo org.test.Malicious &>install-error-log; then
    assert_not_reached "Should not be able to install app with missing metadata"
fi
assert_file_has_content install-error-log "No xa.metadata in local commit"

assert_not_has_dir $FL_DIR/app/org.test.Malicious/current/active

cleanup_repo

ok "app with no xa.metadata and no metadata in summary can't be installed"

create_app "invalid"

if ${FLATPAK} ${U} install -y test-repo org.test.Malicious &>install-error-log; then
    assert_not_reached "Should not be able to install app with invalid metadata"
fi
assert_file_has_content install-error-log "Metadata for .* is invalid"

assert_not_has_dir $FL_DIR/app/org.test.Malicious/current/active

cleanup_repo

ok "app with invalid metadata (in summary) can't be installed"

create_app "invalid no-cache-in-summary"

if ${FLATPAK} ${U} install -y test-repo org.test.Malicious &>install-error-log; then
    assert_not_reached "Should not be able to install app with invalid metadata"
fi
assert_file_has_content install-error-log "Metadata for .* is invalid"

assert_not_has_dir $FL_DIR/app/org.test.Malicious/current/active

cleanup_repo

ok "app with invalid metadata (in commit) can't be installed"

create_app "mismatch no-cache-in-summary"

if ${FLATPAK} ${U} install -y test-repo org.test.Malicious &>install-error-log; then
    assert_not_reached "Should not be able to install app with non-matching metadata"
fi
assert_file_has_content install-error-log "Commit metadata for .* not matching expected metadata"

assert_not_has_dir $FL_DIR/app/org.test.Malicious/current/active

cleanup_repo

ok "app with mismatched metadata (in commit) can't be installed"

create_app "mismatch"

if ${FLATPAK} ${U} install -y test-repo org.test.Malicious &>install-error-log; then
    assert_not_reached "Should not be able to install app with non-matching metadata"
fi
assert_file_has_content install-error-log "Commit metadata for .* not matching expected metadata"

assert_not_has_dir $FL_DIR/app/org.test.Malicious/current/active

cleanup_repo

ok "app with mismatched metadata (in summary) can't be installed"

===== ./tests/test-completion.sh =====
#!/bin/bash
#
# Copyright (C) 2019 Matthias Clasen
#
# 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 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., 59 Temple Place - Suite 330,
# Boston, MA 02111-1307, USA.

set -euo pipefail

#FLATPAK=flatpak
. $(dirname $0)/libtest.sh

skip_revokefs_without_fuse

# This test looks for specific localized strings.
export LC_ALL=C

echo "1..17"

setup_repo
install_repo

${FLATPAK} complete "flatpak a" 9 "a" | sort > complete_out
(diff -u complete_out - || exit 1) <<EOF
EOF

ok "complete a commands"

${FLATPAK} complete "flatpak b" 9 "b" | sort > complete_out
(diff -u complete_out - || exit 1) <<EOF
build 
build-bundle 
build-commit-from 
build-export 
build-finish 
build-import-bundle 
build-init 
build-sign 
build-update-repo 
EOF

ok "complete b commands"

${FLATPAK} complete "flatpak i" 9 "i" | sort > complete_out
(diff -u complete_out - || exit 1) <<EOF
info 
install 
EOF

ok "complete i commands"

${FLATPAK} complete "flatpak --" 10 "--" | sort > complete_out
(diff -u complete_out - || exit 1) <<EOF
--default-arch 
--gl-drivers 
--help 
--installation=
--installations 
--ostree-verbose 
--print-system-only 
--print-updated-env 
--supported-arches 
--system 
--user 
--verbose 
--version 
EOF

ok "complete global options"

${FLATPAK} complete "flatpak list --" 15 "--" | sort > complete_out
(diff -u complete_out - || exit 1) <<EOF
--all 
--app 
--app-runtime=
--arch=
--columns=
--help 
--installation=
--json 
--ostree-verbose 
--runtime 
--show-details 
--system 
--user 
--verbose 
EOF

ok "complete list options"

${FLATPAK} complete "flatpak create-usb /" 20 "/" | sort > complete_out
#(diff -u complete_out - || echo "fail") <<EOF
#__FLATPAK_DIR
#EOF

ok "complete create-usb"

${FLATPAK} complete "flatpak list --arch=" 20 "--arch=" | sort > complete_out
(diff -u complete_out - || exit 1) <<EOF
aarch64 
arm 
i386 
x86_64 
EOF

ok "complete --arch"

${FLATPAK} complete "flatpak override --allow=" 25 "--allow=" | sort > complete_out
(diff -u complete_out - || exit 1) <<EOF
bluetooth 
canbus 
devel 
multiarch 
per-app-dev-shm 
EOF

ok "complete --allow"

${FLATPAK} complete "flatpak config --set l" 23 "l" > complete_out
(diff -u complete_out - || exit 1) <<EOF
languages
EOF

ok "complete config"

${FLATPAK} complete "flatpak info o" 16 "o" | sort > complete_out
(diff -u complete_out - || exit 1) <<EOF
org.test.Hello 
org.test.Hello.Locale 
org.test.Platform 
EOF

ok "complete ref"

${FLATPAK} complete "flatpak permission-reset o" 26 "o" | sort > complete_out
(diff -u complete_out - || exit 1) <<EOF
org.test.Hello
EOF

ok "complete partial ref"

for cmd in build-bundle build-commit-from build-export build-finish \
           build-import-bundle build-init build-sign build-update-repo \
           build document-export document-info document-list document-unexport \
           enter kill permission-list permission-remove permission-reset \
           permission-show ps repo; do
  len=$(awk '{ print length($0) }' <<< "flatpak $cmd --")
  ${FLATPAK} complete "flatpak $cmd --" $len "--"  > complete_out
  assert_not_file_has_content complete_out "^--system "
  assert_not_file_has_content complete_out "^--user "
  assert_not_file_has_content complete_out "^--installation="
done

ok "complete NO_DIR commands"

for cmd in history info list run update mask \
           config install make-current override remote-add repair \
           create-usb remote-delete remote-info remote-list remote-ls \
           remote-modify search uninstall update; do
  len=$(awk '{ print length($0) }' <<< "flatpak $cmd --")
  ${FLATPAK} complete "flatpak $cmd --" $len "--"  > complete_out
  assert_file_has_content complete_out "^--system "
  assert_file_has_content complete_out "^--user "
  assert_file_has_content complete_out "^--installation="
done

ok "complete non-NO_DIR commands"

${FLATPAK} complete "flatpak list --columns=" 24 "--columns=" | sort > complete_out
(diff -u complete_out - || exit 1) <<EOF
active
all
application
arch
branch
description
help
installation
latest
name
options
origin
ref
runtime
size
version
EOF

ok "complete list --columns="

${FLATPAK} complete "flatpak list --columns=all" 27 "--columns=all" | sort > complete_out
assert_file_empty complete-out

ok "complete list --columns=all"

${FLATPAK} complete "flatpak list --columns=hel" 27 "--columns=hel" | sort > complete_out
(diff -u complete_out - || exit 1) <<EOF
help
EOF

ok "complete list --columns=hel"

${FLATPAK} complete "flatpak list --columns=arch," 29 "--columns=arch," | sort > complete_out
(diff -u complete_out - || exit 1) <<EOF
arch,active
arch,application
arch,branch
arch,description
arch,installation
arch,latest
arch,name
arch,options
arch,origin
arch,ref
arch,runtime
arch,size
arch,version
EOF

ok "complete list --columns=arch,"


===== ./tests/share/xdg-desktop-portal/portals/meson.build =====
configure_file(
  input : project_source_root / 'tests/test.portal.in',
  output : 'test.portal',
  copy : true,
)


===== ./tests/test-auth.sh =====
#!/bin/bash
#
# Copyright (C) 2019 Alexander Larsson <alexl@redhat.com>
#
# 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 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., 59 Temple Place - Suite 330,
# Boston, MA 02111-1307, USA.

set -euo pipefail

. $(dirname $0)/libtest.sh


echo "1..3"

setup_repo

commit_to_obj () {
    echo objects/$(echo $1 | cut -b 1-2)/$(echo $1 | cut -b 3-).commit
}

mark_need_token () {
    REF=$1
    TOKEN=${2:-secret}
    REPO=${3:-test}

    COMMIT=$(cat repos/$REPO/refs/heads/$REF)
    echo -n $TOKEN > repos/$REPO/$(commit_to_obj $COMMIT).need_token
}

assert_failed_with_401 () {
    LOGFILE=${1:-install-error-log}
    assert_file_has_content $LOGFILE "401"
}

make_updated_app test "" autoinstall "" org.flatpak.Authenticator.test master

assert_not_has_dir $FL_DIR/app/org.flatpak.Authenticator.test/$ARCH/autoinstall/active/files

# Mark as need token, even though the app doesn't have token-type set
# We should not be able to install this because we will not present
# the token unnecessarily
mark_need_token app/org.test.Hello/$ARCH/master the-secret

if ${FLATPAK} ${U} install -y test-repo org.test.Hello master &> install-error-log; then
    assert_not_reached "Should not be able to install with no secret"
fi
assert_failed_with_401
assert_not_has_dir $FL_DIR/app/org.flatpak.Authenticator.test/$ARCH/autoinstall/active/files

# Properly mark it with token-type
EXPORT_ARGS="--token-type=2" make_updated_app
mark_need_token app/org.test.Hello/$ARCH/master the-secret

# Install with no authenticator
if ${FLATPAK} ${U} install -y test-repo org.test.Hello master &> install-error-log; then
    assert_not_reached "Should not be able to install without authenticator"
fi
assert_file_has_content install-error-log "No authenticator configured for remote"
assert_not_has_dir $FL_DIR/app/org.flatpak.Authenticator.test/$ARCH/autoinstall/active/files

${FLATPAK} ${U} remote-modify test-repo --authenticator-name org.flatpak.Authenticator.test --authenticator-install >&2

flatpak remote-ls test-repo -a -d >&2
# Install with wrong token
echo -n not-the-secret > ${XDG_RUNTIME_DIR}/required-token
if ${FLATPAK} ${U} install -y test-repo org.test.Hello master &> install-error-log; then
    assert_not_reached "Should not be able to install with wrong secret"
fi
assert_failed_with_401
# Now we should have auto-installed the authenticator!
assert_has_dir $FL_DIR/app/org.flatpak.Authenticator.test/$ARCH/autoinstall/active/files

# Install with right token
echo -n the-secret > ${XDG_RUNTIME_DIR}/required-token
${FLATPAK} ${U} install -y test-repo org.test.Hello master >&2
assert_file_has_content ${XDG_RUNTIME_DIR}/request "^remote: test-repo$"
assert_file_has_content ${XDG_RUNTIME_DIR}/request "^uri: http://127.0.0.1:${port}/test$"
if [ x${USE_COLLECTIONS_IN_CLIENT-} == xyes ] ; then
    assert_file_has_content ${XDG_RUNTIME_DIR}/request "^options: .*'collection-id': <'org.test.Collection.test'>"
fi

EXPORT_ARGS="--token-type=2" make_updated_app test "" master UPDATE2
mark_need_token app/org.test.Hello/$ARCH/master the-secret

# Update with wrong token
echo -n not-the-secret > ${XDG_RUNTIME_DIR}/required-token
if ${FLATPAK} ${U} update -y org.test.Hello &> install-error-log; then
    assert_not_reached "Should not be able to install with wrong secret"
fi
assert_failed_with_401

# Update with right token
echo -n the-secret > ${XDG_RUNTIME_DIR}/required-token
${FLATPAK} ${U} update -y org.test.Hello >&2

ok "installed build-exported token-type app"

# Drop token-type on main version
make_updated_app test "" master UPDATE3
# And ensure its installable with no token
${FLATPAK} ${U} update -y org.test.Hello >&2

# Use build-commit-from to add it to a new version
$FLATPAK build-commit-from  --no-update-summary ${FL_GPGARGS} --token-type=2 --disable-fsync --src-ref=app/org.test.Hello/$ARCH/master repos/test app/org.test.Hello/$ARCH/copy >&2
update_repo
mark_need_token app/org.test.Hello/$ARCH/copy the-secret

# Install with wrong token
echo -n not-the-secret > ${XDG_RUNTIME_DIR}/required-token
if ${FLATPAK} ${U} install -y test-repo org.test.Hello//copy &> install-error-log; then
    assert_not_reached "Should not be able to install with wrong secret"
fi
assert_failed_with_401

# Install with right token
echo -n the-secret > ${XDG_RUNTIME_DIR}/required-token
${FLATPAK} ${U} install -y test-repo org.test.Hello//copy >&2

ok "installed build-commit-from token-type app"

EXPORT_ARGS="--token-type=2" make_updated_app test "" master UPDATE4
mark_need_token app/org.test.Hello/$ARCH/master the-secret

# In the below test, do a webflow
touch ${XDG_RUNTIME_DIR}/request-webflow
touch ${XDG_RUNTIME_DIR}/require-webflow
echo -n the-secret > ${XDG_RUNTIME_DIR}/required-token

# Broken browser, will not do webflow
export BROWSER=no-such-binary

# This should fail with no auth due to missing binary
if ${FLATPAK} ${U} update -y org.test.Hello >&2; then
    assert_not_reached "Should not be able to install with webflow"
fi

rm ${XDG_RUNTIME_DIR}/require-webflow

# This should be ok, falling back to silent no-auth case due to !require-webflow
${FLATPAK} ${U} update -y org.test.Hello >&2

# Try again with real webflow handler (curl)
touch ${XDG_RUNTIME_DIR}/require-webflow
export BROWSER=curl

EXPORT_ARGS="--token-type=2" make_updated_app test "" master UPDATE5
mark_need_token app/org.test.Hello/$ARCH/master the-secret

ok "update with webflow"

===== ./tests/glib.supp =====
# Based on the libhif suppressions
{
   gobject_init_1
   Memcheck:Leak
   ...
   fun:gobject_init
}
{
   g_type_register_static_1
   Memcheck:Leak
   ...
   fun:g_type_register_static
}
{
   g_type_register_fundamental
   Memcheck:Leak
   ...
   fun:g_type_register_fundamental
}
{
   g_type_register_dynamic_1
   Memcheck:Leak
   ...
   fun:g_type_register_dynamic
}
{
   g_type_init_with_debug_flags
   Memcheck:Leak
   ...
   fun:g_type_init_with_debug_flags
}
{
   g_type_class_ref_1
   Memcheck:Leak
   ...
   fun:type_iface_vtable_base_init_Wm
   ...
   fun:g_type_class_ref
}
{
   g_type_class_ref_2
   Memcheck:Leak
   ...
   fun:type_class_init_Wm
   ...
   fun:g_type_class_ref
}
{
   g_type_add_interface_static
   Memcheck:Leak
   ...
   fun:g_type_add_interface_static
}
{
   g_param_spec_internal
   Memcheck:Leak
   ...
   fun:g_type_class_ref
   fun:g_type_create_instance
   fun:g_param_spec_internal
}
{
   g_param_spec_enum
   Memcheck:Leak
   ...
   fun:g_type_class_ref
   fun:g_param_spec_enum
}
{
   g_param_spec_flags
   Memcheck:Leak
   ...
   fun:g_type_class_ref
   fun:g_param_spec_flags
}
{
   g_quark_from_static_string
   Memcheck:Leak
   ...
   fun:g_quark_from_static_string
}
{
   g_quark_from_string
   Memcheck:Leak
   ...
   fun:g_quark_from_string
}
{
   g_value_register_transform_func
   Memcheck:Leak
   ...
   fun:g_value_register_transform_func
}
{
   test_run_seed
   Memcheck:Leak
   ...
   fun:g_rand_new_with_seed_array
   fun:test_run_seed
   ...
   fun:g_test_run_suite
}
{
   g_test_init
   Memcheck:Leak
   ...
   fun:g_rand_new_with_seed_array
   ...
   fun:g_test_init
}
{
   g_intern_static_string
   Memcheck:Leak
   ...
   fun:g_intern_static_string
}
{
   g_main_context_push_thread_default
   Memcheck:Leak
   ...
   fun:g_queue_new
   fun:g_main_context_push_thread_default
}
{
   g_main_context_push_thread_default_inlined
   Memcheck:Leak
   ...
   fun:g_slice_alloc0
   fun:g_main_context_push_thread_default
}
{
   g_dbus_error_register_error
   Memcheck:Leak
   ...
   fun:g_dbus_error_register_error
}
{
   g_param_spec_pool_insert
   Memcheck:Leak
   ...
   fun:g_param_spec_pool_insert
}
{
   g_main_context_default
   Memcheck:Leak
   ...
   fun:g_main_context_default
}
{
   g_main_context_check
   Memcheck:Leak
   ...
   fun:g_ptr_array_add
   fun:g_main_context_check
}
{
   g_test_run_suite
   Memcheck:Leak
   ...
   fun:g_slist_copy
   fun:g_test_run_suite_internal
   fun:g_test_run_suite
}
{
   g_dbus_interface_info_cache_build
   Memcheck:Leak
   ...
   fun:g_dbus_interface_info_cache_build
}
{
   g_cancellable_push_current
   Memcheck:Leak
   ...
   fun:thread_memory_from_self
   ...
   fun:g_cancellable_push_current
}
{
   g-io-module-default-singleton-malloc
   Memcheck:Leak
   ...
   fun:g_type_create_instance
   ...
   fun:_g_io_module_get_default
}
{
   g-io-module-default-singleton-malloc2
   Memcheck:Leak
   fun:malloc
   ...
   fun:_g_io_module_get_default
}
{
   g_io_scheduler_push_job
   Memcheck:Leak
   ...
   fun:init_scheduler
   fun:g_once_impl
   fun:g_io_scheduler_push_job
}
{
   g_io_scheduler_push_job_2
   Memcheck:Leak
   ...
   fun:g_system_thread_new
   ...
   fun:g_io_scheduler_push_job
}
{
   g_bus_get_sync__available_connections
   Memcheck:Leak
   ...
   fun:g_hash_table_new
   fun:initable_init
   fun:g_initable_init
   fun:g_bus_get_sync
}
{
   g_socket_connection_factory_register_type
   Memcheck:Leak
   ...
   fun:g_socket_connection_factory_register_type
}
{
   g_test_add_vtable
   Memcheck:Leak
   ...
   fun:g_test_add_vtable
}
{
   g_mutex_lock
   Memcheck:Leak
   ...
   fun:g_mutex_impl_new
   fun:g_mutex_get_impl
   fun:g_mutex_lock
}
{
   g_thread_self
   Memcheck:Leak
   ...
   fun:g_thread_self
}
{
   g_rec_mutex_lock
   Memcheck:Leak
   ...
   fun:g_rec_mutex_impl_new
   fun:g_rec_mutex_get_impl
   fun:g_rec_mutex_lock
}
{
   test_case_run
   Memcheck:Leak
   ...
   fun:g_malloc0
   fun:test_case_run
   ...
   fun:g_test_run_suite
}
{
   g_get_charset
   Memcheck:Leak
   ...
   fun:g_get_charset
}
{
   g_test_run_suite__timer_new
   Memcheck:Leak
   ...
   fun:g_timer_new
   fun:test_case_run
   ...
   fun:g_test_run_suite
}
{
   g_test_run_suite__timer_new2
   Memcheck:Leak
   ...
   fun:g_timer_new
   fun:test_case_run_suite_internal
   ...
   fun:g_test_run_suite
}
{
   g_test_run_suite__strconcat
   Memcheck:Leak
   ...
   fun:g_strconcat
   fun:test_case_run
   ...
   fun:g_test_run_suite
   fun:g_test_run
}
{
   g_type_interface_add_prerequisite
   Memcheck:Leak
   ...
   fun:g_type_interface_add_prerequisite
}
{
   <insert_a_suppression_name_here>
   Memcheck:Leak
   ...
   fun:g_slist_copy
   fun:g_test_run_suite_internal
   ...
   fun:g_test_run_suite
}
{
   g_set_prgname
   Memcheck:Leak
   ...
   fun:g_set_prgname
}
{
   g_test_run_suite__strconcat_2
   Memcheck:Leak
   ...
   fun:g_strconcat
   fun:g_test_run_suite_internal
}
{
   g_test_run_suite__strdup
   Memcheck:Leak
   ...
   fun:g_strdup
   fun:g_test_run_suite_internal
}
{
   g_private_get
   Memcheck:Leak
   ...
   fun:g_private_get
}
{
   g_private_set
   Memcheck:Leak
   ...
   fun:g_private_set
}
{
   g_private_set_alloc0
   Memcheck:Leak
   ...
   fun:g_private_set_alloc0
}
{
   g_static_mutex_get_mutex_impl
   Memcheck:Leak
   ...
   fun:g_static_mutex_get_mutex_impl
}
{
   g_variant_type_info_unref
   Memcheck:Leak
   ...
   fun:g_hash_table_remove
   fun:g_variant_type_info_unref
}
{
   g_rw_lock_reader_lock
   Memcheck:Leak
   ...
   fun:g_rw_lock_impl_new
   fun:g_rw_lock_get_impl
   fun:g_rw_lock_reader_lock
}
{
   g_child_watch_finalize__rt_sigaction
   Memcheck:Param
   rt_sigaction(act->sa_flags)
   fun:__libc_sigaction
   ...
   fun:g_child_watch_finalize
}
{
   g_dbus_worker_new
   Memcheck:Leak
   fun:calloc
   ...
   fun:_g_dbus_worker_new
}
{
   gdbus_shared_thread_func
   Memcheck:Leak
   match-leak-kinds: definite
   ...
   fun:g_malloc
   ...
   fun:gdbus_shared_thread_func
}
{
   g_task_start_task_thread
   Memcheck:Leak
   match-leak-kinds: definite
   fun:malloc
   fun:g_malloc
   fun:g_slice_alloc
   fun:g_slice_alloc0
   ...
   fun:g_thread_pool_push
   fun:g_task_start_task_thread
}
{
   g_get_language_names
   Memcheck:Leak
   match-leak-kinds: definite
   fun:calloc
   fun:g_malloc0
   fun:g_get_language_names
}
{
   g-get-language-names-malloc
   Memcheck:Leak
   fun:malloc
   ...
   fun:g_get_language_names_with_category
}
{
   g-get-language-names-malloc2
   Memcheck:Leak
   fun:calloc
   ...
   fun:g_get_language_names_with_category
}
{
   g_get_filename_charsets
   Memcheck:Leak
   match-leak-kinds: definite
   ...
   fun:g_get_filename_charsets
   fun:g_filename_display_name
}
{
   g_main_current_source
   Memcheck:Leak
   match-leak-kinds: definite
   fun:malloc
   fun:g_malloc
   ...
   fun:g_main_current_source
   fun:g_task_return
   fun:g_task_thread_pool_thread
}
{
   g_once_init_enter
   Memcheck:Leak
   match-leak-kinds: definite
   ...
   fun:g_once_init_enter
}
{
   g_child_watch_source_new
   Memcheck:Leak
   match-leak-kinds: definite
   ...
   fun:g_thread_new
   ...
   fun:g_child_watch_source_new
}
{
   continue_writing_in_idle_cb
   Memcheck:Leak
   match-leak-kinds: definite
   ...
   fun:g_task_new
   ...
   fun:continue_writing_in_idle_cb
   fun:g_main_context_dispatch
}
{
   g_main_current_source
   Memcheck:Leak
   match-leak-kinds: definite
   fun:malloc
   ...
   fun:g_main_current_source
}
{
   g_thread_pool_push
   Memcheck:Leak
   match-leak-kinds: definite
   fun:malloc
   ...
   fun:g_thread_pool_push
}
{
   leak_test_dbus_dispose
   Memcheck:Leak
   match-leak-kinds: definite
   fun:malloc
   ...
   fun:g_main_loop_run
   fun:g_test_dbus_down
}
{
   leak_test_dbus_down
   Memcheck:Leak
   match-leak-kinds: definite
   fun:calloc
   fun:g_malloc0
   fun:g_main_loop_new
   fun:g_test_dbus_down
}
{
   leak_socket_client_connect
   Memcheck:Leak
   match-leak-kinds: definite
   fun:malloc
   fun:g_malloc
   fun:g_slice_alloc
   fun:g_slice_alloc0
   fun:g_socket_client_connect_async
   fun:g_socket_client_connect_to_uri_async
}
{
   leak_signal_handlers_disconnect_matched
   Memcheck:Leak
   match-leak-kinds: definite
   fun:calloc
   fun:g_malloc0
   ...
   fun:g_slice_alloc
   ...
   fun:g_signal_handlers_disconnect_matched
}
{
   g_tls_connection_gnutls_init_priorities
   Memcheck:Leak
   match-leak-kinds: definite
   fun:malloc
   fun:g_malloc
   fun:g_strdup
   fun:g_tls_connection_gnutls_init_priorities
}
{
   g_tls_connection_gnutls_heisenbug_likely_same_as_above
   Memcheck:Leak
   match-leak-kinds: definite
   fun:malloc
   fun:g_malloc
   fun:g_strdup
   ...
   fun:g_tls_client_connection_new
}
{
   g_unix_signal_add_full
   Memcheck:Leak
   match-leak-kinds: definite
   fun:malloc
   fun:g_malloc
   ...
   fun:g_thread_new
   ...
   fun:g_unix_signal_add_full
}
{
   glib_worker_1
   Memcheck:Leak
   ...
   fun:glib_worker_main
}
{
   glib_dispatch_1
   Memcheck:Leak
   fun:malloc
   fun:g_malloc
   ...
   fun:get_dispatch
   fun:g_main_dispatch
}
{
   glib_dispatch_2
   Memcheck:Leak
   fun:calloc
   fun:g_malloc0
   ...
   fun:get_dispatch
   fun:g_main_current_source
}
{
   glib_dlopen_1
   Memcheck:Leak
   fun:calloc
   fun:_dlerror_run
   fun:dlopen*
   ...
   fun:g_module_open
}
{
   libc_tls
   Memcheck:Leak
   fun:calloc
   fun:_dl_allocate_tls
   fun:pthread_create*
}
{
   gio_namespace_cache_leak_ns_info
   Memcheck:Leak
   match-leak-kinds: definite
   fun:calloc
   fun:g_malloc0
   fun:_lookup_namespace
}
{
   gio_namespace_cache_leak_ns_name
   Memcheck:Leak
   match-leak-kinds: definite
   fun:malloc
   fun:g_malloc
   fun:g_strdup
   fun:_lookup_namespace
}
{
   gio_extension_points_global
   Memcheck:Leak
   match-leak-kinds: definite
   fun:calloc
   fun:g_malloc0
   fun:g_io_extension_point_register
}
{
   glib_dbus_thread_private
   Memcheck:Leak
   match-leak-kinds: definite
   fun:calloc
   fun:g_malloc0
   fun:g_private_set_alloc0
   ...
   fun:gdbus_shared_thread_func
}
{
   dbus_shared_socket
   Memcheck:Leak
   match-leak-kinds: definite
   ...
   fun:g_socket_create_source
   ...
   fun:gdbus_shared_thread_func
}
{
   polkit_agent_leak
   Memcheck:Leak
   match-leak-kinds: definite
   fun:calloc
   fun:g_malloc0
   fun:g_dbus_connection_register_object
   ...
   fun:g_thread_proxy
}
{
   polkit_agent_leak2
   Memcheck:Leak
   match-leak-kinds: definite
   fun:calloc
   fun:g_malloc0
   fun:g_private_set_alloc0
   ...
   fun:g_thread_proxy
}

===== ./tests/test-update-remote-configuration.sh =====
#!/bin/bash
#
# Copyright © 2017 Endless Mobile, Inc.
#
# 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 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., 59 Temple Place - Suite 330,
# Boston, MA 02111-1307, USA.
#
# Authors:
#  - Philip Withnall <withnall@endlessm.com>

set -euo pipefail

. $(dirname $0)/libtest.sh

skip_without_bwrap
skip_revokefs_without_fuse

echo "1..3"

# Configure a repository without a collection ID and pull it locally.
setup_repo
install_repo

DIR=$(mktemp -d)
${FLATPAK} build-init ${DIR} org.test.App org.test.Platform org.test.Platform >&2
mkdir -p ${DIR}/files/a
echo "a" > ${DIR}/files/a/data
${FLATPAK} build-finish ${DIR} --socket=x11 --share=network --command=true >&2
${FLATPAK} build-export --no-update-summary ${FL_GPGARGS} --update-appstream repos/test ${DIR} master >&2
update_repo

${FLATPAK} ${U} install -y test-repo org.test.App master >&2

assert_file_has_content ${FL_DIR}/repo/config '^gpg-verify-summary=true$'
assert_not_file_has_content ${FL_DIR}/repo/config '^gpg-verify-summary=false$'
assert_file_has_content ${FL_DIR}/repo/config '^gpg-verify=true$'
assert_not_file_has_content ${FL_DIR}/repo/config '^gpg-verify=false$'
assert_not_file_has_content ${FL_DIR}/repo/config '^collection-id='

# Change its configuration to include a collection ID, update the repository,
# but don’t mark the collection ID as to be deployed yet. Ensure it doesn’t
# appear in the client’s configuration.
echo -e "[core]\ncollection-id=org.test.Collection" >> repos/test/config
${FLATPAK} build-export --no-update-summary  ${FL_GPGARGS} --update-appstream repos/test --collection-id org.test.Collection ${DIR} master >&2
UPDATE_REPO_ARGS="--collection-id=org.test.Collection" update_repo

${FLATPAK} ${U} update -y org.test.App master >&2

assert_file_has_content ${FL_DIR}/repo/config '^gpg-verify-summary=true$'
assert_not_file_has_content ${FL_DIR}/repo/config '^gpg-verify-summary=false$'
assert_file_has_content ${FL_DIR}/repo/config '^gpg-verify=true$'
assert_not_file_has_content ${FL_DIR}/repo/config '^gpg-verify=false$'
assert_not_file_has_content ${FL_DIR}/repo/config '^collection-id='
assert_not_file_has_content ${FL_DIR}/repo/config '^collection-id='

ok "1 update repo config without deploying collection ID"

# Now mark the collection ID as to be deployed. The client configuration should
# be updated.
UPDATE_REPO_ARGS="--collection-id=org.test.Collection --deploy-collection-id" update_repo
assert_file_has_content repos/test/config '^deploy-collection-id=true$'

${FLATPAK} ${U} update -y org.test.App master >&2

assert_file_has_content ${FL_DIR}/repo/config '^gpg-verify-summary=true$'
assert_not_file_has_content ${FL_DIR}/repo/config '^gpg-verify-summary=false$'
assert_file_has_content ${FL_DIR}/repo/config '^gpg-verify=true$'
assert_not_file_has_content ${FL_DIR}/repo/config '^gpg-verify=false$'
assert_file_has_content ${FL_DIR}/repo/config '^collection-id=org\.test\.Collection$'

# Try the deploy for sideload only method
sed -i "s/deploy-collection-id=true//" repos/test/config
assert_not_file_has_content repos/test/config '^deploy-collection-id=true$'

${FLATPAK} remote-modify --collection-id= test-repo >&2
assert_not_file_has_content ${FL_DIR}/repo/config '^collection-id=org\.test\.Collection$'

UPDATE_REPO_ARGS="--collection-id=org.test.Collection --deploy-sideload-collection-id" update_repo
assert_file_has_content repos/test/config '^deploy-sideload-collection-id=true$'

${FLATPAK} ${U} update -y org.test.App master >&2

assert_file_has_content ${FL_DIR}/repo/config '^collection-id=org\.test\.Collection$'

ok "2 update repo config to deploy collection ID"

# Try updating the collection ID to some other non-empty value on the server.
# The client should ignore the update (otherwise we have a security vulnerability).
# We have to manually add refs under the old collection ID so the client can pull
# using its old collection ID.
#UPDATE_REPO_ARGS="--collection-id=net.malicious.NewCollection --deploy-collection-id" update_repo
#for ref in app/org.test.App/$(flatpak --default-arch)/master app/org.test.Hello/$(flatpak --default-arch)/master appstream/$(flatpak --default-arch) ostree-metadata runtime/org.test.Platform/$(flatpak --default-arch)/master; do
#  ostree --repo=repos/test refs --collections --create=org.test.Collection:$ref $ref
#done
ostree --repo=repos/test summary --update --add-metadata="ostree.deploy-collection-id='net.malicious.NewCollection'" >&2
${FLATPAK} ${U} update org.test.App master >&2

assert_file_has_content ${FL_DIR}/repo/config '^collection-id=org\.test\.Collection$'
assert_not_file_has_content ${FL_DIR}/repo/config '^collection-id=net\.malicious\.NewCollection$'

ok "3 update repo config with different collection ID"

===== ./tests/make-runtime-repos =====
#!/bin/sh
# Copyright 2018-2020 Red Hat Inc.
# Copyright 2018-2019 Matthew Leeds
# Copyright 2022 Collabora Ltd.

set -eu

flatpak_dir="$1"
make_test_runtime="$2"
target="$3"
stamp="$4"

export PATH="$flatpak_dir:$PATH"

rm -fr "$target"
"$make_test_runtime" "$target" org.test.Platform master "" ""
"$make_test_runtime" "$target" org.test.Platform stable "" ""
touch "$stamp"

===== ./tests/test-override.sh =====
#!/bin/bash

set -euo pipefail

. $(dirname $0)/libtest.sh
if [ -e "${test_builddir}/.libs/libpreload.so" ]; then
    install "${test_builddir}/.libs/libpreload.so" "${test_tmpdir}"
else
    install "${test_builddir}/libpreload.so" "${test_tmpdir}"
fi

skip_revokefs_without_fuse

reset_overrides () {
    ${FLATPAK} override --user --reset org.test.Hello
    ${FLATPAK} override --user --show org.test.Hello > info
    assert_file_empty info
}

echo "1..20"

setup_repo
install_repo

reset_overrides

${FLATPAK} override --user --socket=wayland org.test.Hello
${FLATPAK} override --user --nosocket=ssh-auth org.test.Hello
${FLATPAK} override --user --show org.test.Hello > override

assert_file_has_content override "^\[Context\]$"
assert_file_has_content override "^sockets=!ssh-auth;wayland;$"

ok "override --socket"

reset_overrides

${FLATPAK} override --user --socket-if=wayland:!has-wayland org.test.Hello
${FLATPAK} override --user --socket-if=wayland:true org.test.Hello
${FLATPAK} override --user --show org.test.Hello > override

assert_file_has_content override "^\[Context\]$"
assert_file_has_content override "^sockets=wayland;if:wayland:!has-wayland;if:wayland:true;$"
ok "override --socket-if"

reset_overrides

${FLATPAK} override --user --device=dri org.test.Hello
${FLATPAK} override --user --nodevice=kvm org.test.Hello
${FLATPAK} override --user --show org.test.Hello > override

assert_file_has_content override "^\[Context\]$"
assert_file_has_content override "^devices=dri;!kvm;$"

ok "override --device"

reset_overrides

${FLATPAK} override --user --share=network org.test.Hello
${FLATPAK} override --user --unshare=ipc org.test.Hello
${FLATPAK} override --user --show org.test.Hello > override

assert_file_has_content override "^\[Context\]$"
assert_file_has_content override "^shared=!ipc;network;$"

ok "override --share"

reset_overrides

${FLATPAK} override --user --device-if=dri:a org.test.Hello
${FLATPAK} override --user --device-if=kvm:x --device-if=dri:b org.test.Hello
${FLATPAK} override --user --device-if=dri:!c --device-if=dri:!d org.test.Hello
${FLATPAK} override --user --show org.test.Hello > override

assert_file_has_content override "^\[Context\]$"
assert_file_has_content override "^devices=dri;if:dri:!c;if:dri:!d;if:dri:a;if:dri:b;kvm;if:kvm:x;$"
ok "override --device-if"

reset_overrides

reset_overrides

${FLATPAK} override --user --allow=multiarch org.test.Hello
${FLATPAK} override --user --disallow=bluetooth org.test.Hello
${FLATPAK} override --user --show org.test.Hello > override

assert_file_has_content override "^\[Context\]$"
assert_file_has_content override "^features=!bluetooth;multiarch;$"

ok "override --allow"

reset_overrides

${FLATPAK} override --user --env=FOO=BAR org.test.Hello
${FLATPAK} override --user --env=BAR= org.test.Hello
${FLATPAK} override --user --unset-env=CLEARME org.test.Hello
# --env-fd with terminating \0 (strictly as documented).
printf '%s\0' "SECRET_TOKEN=3047225e-5e38-4357-b21c-eac83b7e8ea6" > env.3
# --env-fd without terminating \0 (which we also accept).
# TMPDIR and TZDIR are filtered out by ld.so for setuid processes,
# so setting these gives us a way to verify that we can pass them through
# a setuid bwrap (without special-casing them, as we previously did for
# TMPDIR).
printf '%s\0%s' "TMPDIR=/nonexistent/tmp" "TZDIR=/nonexistent/tz" > env.4
${FLATPAK} override --user --env-fd=3 --env-fd=4 org.test.Hello \
    3<env.3 4<env.4
${FLATPAK} override --user --show org.test.Hello > override

assert_file_has_content override "^\[Environment\]$"
assert_file_has_content override "^FOO=BAR$"
assert_file_has_content override "^BAR=$"
assert_file_has_content override "^SECRET_TOKEN=3047225e-5e38-4357-b21c-eac83b7e8ea6$"
assert_file_has_content override "^TMPDIR=/nonexistent/tmp$"
assert_file_has_content override "^TZDIR=/nonexistent/tz$"
assert_file_has_content override "^unset-environment=CLEARME;$"

ok "override --env"

if skip_one_without_bwrap "sandbox environment variables"; then
  :
else
  CLEARME=wrong ${FLATPAK} run --command=bash org.test.Hello \
      -c 'echo "FOO=$FOO"; echo "BAR=${BAR-unset}"; echo "SECRET_TOKEN=$SECRET_TOKEN"; echo "TMPDIR=$TMPDIR"; echo "TZDIR=$TZDIR"; echo "CLEARME=${CLEARME-unset}"' > out
  assert_file_has_content out '^FOO=BAR$'
  assert_file_has_content out '^BAR=$'
  assert_file_has_content out '^SECRET_TOKEN=3047225e-5e38-4357-b21c-eac83b7e8ea6$'
  # The variables that would be filtered out by a setuid bwrap get set
  assert_file_has_content out '^TZDIR=/nonexistent/tz$'
  assert_file_has_content out '^TMPDIR=/nonexistent/tmp$'
  assert_file_has_content out '^CLEARME=unset$'
  ${FLATPAK} run --command=cat org.test.Hello -- /proc/1/cmdline > out
  # The secret doesn't end up in bubblewrap's cmdline where other users
  # could see it
  assert_not_file_has_content out 3047225e-5e38-4357-b21c-eac83b7e8ea6

  ok "sandbox environment variables"
fi

reset_overrides

if skip_one_without_bwrap "temporary environment variables"; then
  :
else
  ${FLATPAK} override --user --env=FOO=wrong org.test.Hello
  ${FLATPAK} override --user --unset-env=BAR org.test.Hello
  ${FLATPAK} override --user --env=SECRET_TOKEN=wrong org.test.Hello
  ${FLATPAK} override --user --env=TMPDIR=/nonexistent/wrong org.test.Hello
  ${FLATPAK} override --user --env=TZDIR=/nonexistent/wrong org.test.Hello
  ${FLATPAK} override --user --env=CLEARME=wrong org.test.Hello
  ${FLATPAK} override --user --show org.test.Hello > override

  CLEARME=also-wrong ${FLATPAK} run --command=bash \
      --filesystem="${test_tmpdir}" \
      --unset-env=CLEARME \
      --env=FOO=BAR \
      --env=BAR= \
      --env-fd=3 \
      --env-fd=4 \
      org.test.Hello \
      -c 'echo "FOO=$FOO"; echo "BAR=${BAR-unset}"; echo "SECRET_TOKEN=$SECRET_TOKEN"; echo "TMPDIR=$TMPDIR"; echo "TZDIR=$TZDIR"; echo "CLEARME=${CLEARME-unset}"' \
      3<env.3 4<env.4 > out
  # The versions from `flatpak run` overrule `flatpak override`
  assert_file_has_content out '^FOO=BAR$'
  assert_file_has_content out '^BAR=$'
  assert_file_has_content out '^SECRET_TOKEN=3047225e-5e38-4357-b21c-eac83b7e8ea6$'
  assert_file_has_content out '^TZDIR=/nonexistent/tz$'
  assert_file_has_content out '^TMPDIR=/nonexistent/tmp$'
  assert_file_has_content out '^CLEARME=unset$'
  ${FLATPAK} run --command=cat org.test.Hello -- /proc/1/cmdline > out
  # The secret doesn't end up in bubblewrap's cmdline where other users
  # could see it
  assert_not_file_has_content out 3047225e-5e38-4357-b21c-eac83b7e8ea6

  # libpreload.so will abort() if it gets loaded into the `flatpak run`
  # or `bwrap` processes, so if this succeeds, everything's OK
  ${FLATPAK} run --command=bash \
      --filesystem="${test_tmpdir}" \
      --env=LD_PRELOAD="${test_tmpdir}/libpreload.so" \
      org.test.Hello -c ''
  printf '%s\0' "LD_PRELOAD=${test_tmpdir}/libpreload.so" > env.ldpreload
  ${FLATPAK} run --command=bash \
      --filesystem="${test_tmpdir}" \
      --env-fd=3 \
      org.test.Hello -c '' 3<env.ldpreload

  ok "temporary environment variables"
fi

reset_overrides

${FLATPAK} override --user --filesystem=home org.test.Hello
${FLATPAK} override --user --filesystem=xdg-desktop/foo:create org.test.Hello
${FLATPAK} override --user --filesystem=xdg-config:ro org.test.Hello
${FLATPAK} override --user --filesystem=/media org.test.Hello
${FLATPAK} override --user --nofilesystem=xdg-documents org.test.Hello
${FLATPAK} override --user --show org.test.Hello > override

assert_file_has_content override "^\[Context\]$"
filesystems="$(sed -ne 's/^filesystems=//p' override)"
assert_semicolon_list_contains "$filesystems" "/media"
assert_not_semicolon_list_contains "$filesystems" "!/media"
assert_semicolon_list_contains "$filesystems" "home"
assert_not_semicolon_list_contains "$filesystems" "!home"
assert_not_semicolon_list_contains "$filesystems" "xdg-documents"
assert_semicolon_list_contains "$filesystems" "!xdg-documents"
assert_semicolon_list_contains "$filesystems" "xdg-desktop/foo:create"
assert_not_semicolon_list_contains "$filesystems" "!xdg-desktop/foo"
assert_not_semicolon_list_contains "$filesystems" "!xdg-desktop/foo:create"
assert_semicolon_list_contains "$filesystems" "xdg-config:ro"
assert_not_semicolon_list_contains "$filesystems" "!xdg-config"
assert_not_semicolon_list_contains "$filesystems" "!xdg-config:ro"

${FLATPAK} override --user --nofilesystem=host:reset org.test.Hello
${FLATPAK} override --user --show org.test.Hello > override
filesystems="$(sed -ne 's/^filesystems=//p' override)"
assert_not_semicolon_list_contains "$filesystems" "host"
assert_not_semicolon_list_contains "$filesystems" "host:reset"
assert_semicolon_list_contains "$filesystems" "!host"
assert_semicolon_list_contains "$filesystems" "!host:reset"
assert_not_semicolon_list_contains "$filesystems" "host-reset"
assert_not_semicolon_list_contains "$filesystems" "!host-reset"

# !host-reset is the same as !host:reset, and serializes as !host:reset
${FLATPAK} override --user --nofilesystem=host-reset org.test.Hello
${FLATPAK} override --user --show org.test.Hello > override
filesystems="$(sed -ne 's/^filesystems=//p' override)"
assert_not_semicolon_list_contains "$filesystems" "host"
assert_not_semicolon_list_contains "$filesystems" "host:reset"
assert_semicolon_list_contains "$filesystems" "!host"
assert_semicolon_list_contains "$filesystems" "!host:reset"
assert_not_semicolon_list_contains "$filesystems" "host-reset"
assert_not_semicolon_list_contains "$filesystems" "!host-reset"

# --filesystem=...:reset => error
e=0
${FLATPAK} override --user --filesystem=host:reset org.test.Hello 2>log || e=$?
assert_file_has_content log "Filesystem suffix \"reset\" only applies to --nofilesystem"
assert_not_streq "$e" 0

# --filesystem=host-reset => error
e=0
${FLATPAK} override --user --filesystem=host-reset org.test.Hello 2>log || e=$?
assert_file_has_content log "Filesystem token \"host-reset\" is only applicable for --nofilesystem"
assert_not_streq "$e" 0

# --filesystem=host-reset:suffix => error
e=0
${FLATPAK} override --user --nofilesystem=host-reset:suffix org.test.Hello 2>log || e=$?
assert_file_has_content log "Filesystem token \"host-reset\" cannot be used with a suffix"
assert_not_streq "$e" 0

# --nofilesystem=/foo:reset => error
e=0
${FLATPAK} override --user --nofilesystem=/foo:reset org.test.Hello 2>log || e=$?
assert_file_has_content log "Filesystem suffix \"reset\" can only be applied to --nofilesystem=host"
assert_not_streq "$e" 0

# --nofilesystem=...:rw => warning
# Warnings need to be made temporarily non-fatal here.
e=0
G_DEBUG= ${FLATPAK} override --user --nofilesystem=/foo:rw org.test.Hello 2>log || e=$?
assert_file_has_content log "Filesystem suffix \"rw\" is not applicable for --nofilesystem"
assert_streq "$e" 0

# --filesystem=...:bar => warning
# Warnings need to be made temporarily non-fatal here.
e=0
G_DEBUG= ${FLATPAK} override --user --filesystem=/foo:bar org.test.Hello 2>log || e=$?
assert_file_has_content log "Unexpected filesystem suffix bar, ignoring"
assert_streq "$e" 0

# --nofilesystem=...:bar => warning
# Warnings need to be made temporarily non-fatal here.
e=0
G_DEBUG= ${FLATPAK} override --user --nofilesystem=/foo:bar org.test.Hello 2>log || e=$?
assert_file_has_content log "Unexpected filesystem suffix bar, ignoring"
assert_streq "$e" 0

ok "override --filesystem"

reset_overrides

${FLATPAK} override --user --own-name=org.foo.Own org.test.Hello
${FLATPAK} override --user --talk-name=org.foo.Talk org.test.Hello
${FLATPAK} override --user --talk-name=org.foo.NoTalk org.test.Hello
${FLATPAK} override --user --no-talk-name=org.foo.NoTalk org.test.Hello
${FLATPAK} override --user --show org.test.Hello > override

assert_file_has_content override "^\[Session Bus Policy\]$"
assert_file_has_content override "^org\.foo\.Own=own$"
assert_file_has_content override "^org\.foo\.Talk=talk$"
assert_file_has_content override "^org\.foo\.NoTalk=none$"

ok "override session bus names"

reset_overrides

${FLATPAK} override --user --system-own-name=org.foo.Own.System org.test.Hello
${FLATPAK} override --user --system-talk-name=org.foo.Talk.System org.test.Hello
${FLATPAK} override --user --system-talk-name=org.foo.NoTalk.System org.test.Hello
${FLATPAK} override --user --system-no-talk-name=org.foo.NoTalk.System org.test.Hello
${FLATPAK} override --user --show org.test.Hello > override

assert_file_has_content override "^\[System Bus Policy\]$"
assert_file_has_content override "^org\.foo\.Own\.System=own$"
assert_file_has_content override "^org\.foo\.Talk\.System=talk$"
assert_file_has_content override "^org\.foo\.NoTalk\.System=none$"

ok "override system bus names"

reset_overrides

if skip_one_without_bwrap "sandbox wayland socket"; then
  :
elif [ -S "${XDG_RUNTIME_DIR}/wayland-0" ]; then
  ${FLATPAK} override --user --socket=wayland org.test.Hello
  ${FLATPAK} run --command=ls org.test.Hello -- /run/user/1000 > out
  assert_file_has_content out "wayland-0"

  ${FLATPAK} override --user --nosocket=wayland org.test.Hello
  ${FLATPAK} run --command=ls org.test.Hello -- /run/user/1000 > out
  assert_not_file_has_content out "wayland-0"

  ok "sandbox wayland socket"
else
  ok "sandbox wayland socket # skip not supported without Wayland"
fi

reset_overrides

if skip_one_without_bwrap "sandbox dri device"; then
  :
elif [ -d "/dev/dri" ]; then
  ${FLATPAK} override --user --device=dri org.test.Hello
  ${FLATPAK} run --command=ls org.test.Hello -- /dev > out
  assert_file_has_content out "dri"

  ${FLATPAK} override --user --nodevice=dri org.test.Hello
  ${FLATPAK} run --command=ls org.test.Hello -- /dev > out
  assert_not_file_has_content out "dri"

  ok "sandbox dri device"
else
  ok "sandbox dri device # skip not supported without /dev/dri"
fi

reset_overrides

if ! skip_one_without_bwrap "sandbox dri device"; then
  ${FLATPAK} override --user --env=FOO=BAR org.test.Hello

  ${FLATPAK} run --command=sh org.test.Hello -c 'echo $FOO' > out
  assert_file_has_content out "BAR"
  FOO=bar ${FLATPAK} run --command=sh org.test.Hello -c 'echo $FOO' > out
  assert_file_has_content out "BAR"

  ok "sandbox env"
fi

reset_overrides

if ! skip_one_without_bwrap "sandbox filesystem"; then
  echo "hello" > $HOME/example

  ${FLATPAK} override --user --filesystem=home:ro org.test.Hello

  ${FLATPAK} run --command=ls org.test.Hello $HOME > out
  assert_file_has_content out example

  ${FLATPAK} run --command=sh org.test.Hello -c "echo goodbye > $HOME/example" || true
  assert_file_has_content $HOME/example hello

  rm $HOME/example

  ok "sandbox filesystem"
fi

reset_overrides

if ! skip_one_without_bwrap "persist"; then
  ${FLATPAK} override --user --persist=example org.test.Hello
  ${FLATPAK} run --command=sh org.test.Hello -c "echo goodbye > $HOME/example/bye"
  assert_file_has_content $HOME/.var/app/org.test.Hello/example/bye goodbye

  ok "persist"
fi

reset_overrides

if ! skip_one_without_bwrap "runtime override --nofilesystem=home"; then
  mkdir -p "$HOME/dir"
  mkdir -p "$TEST_DATA_DIR/dir1"
  mkdir -p "$TEST_DATA_DIR/dir2"
  echo "hello" > "$HOME/example"
  echo "hello" > "$HOME/dir/example"
  echo "hello" > "$TEST_DATA_DIR/dir1/example"
  echo "hello" > "$TEST_DATA_DIR/dir2/example"

  ${FLATPAK} override --user --filesystem=home org.test.Hello
  ${FLATPAK} override --user --filesystem='~/dir' org.test.Hello
  ${FLATPAK} override --user --filesystem="$TEST_DATA_DIR/dir1" org.test.Hello

  ${FLATPAK} run --env=TEST_DATA_DIR="$TEST_DATA_DIR" \
    --command=sh --nofilesystem=home org.test.Hello -c '
    echo overwritten > "$HOME/dir/example" || true
    echo overwritten > "$HOME/example" || true
    echo overwritten > "$TEST_DATA_DIR/dir1/example" || true
    echo overwritten > "$TEST_DATA_DIR/dir2/example" || true
  '
  # --nofilesystem=home does not cancel a more narrowly-scoped permission
  # such as --filesystem=~/dir
  assert_file_has_content "$HOME/dir/example" overwritten
  # --nofilesystem=home cancels the --filesystem=home at a lower precedence,
  # so $HOME/example was not shared
  assert_file_has_content "$HOME/example" hello
  # --nofilesystem=home does not affect access to files outside $HOME
  assert_file_has_content "$TEST_DATA_DIR/dir1/example" overwritten
  assert_file_has_content "$TEST_DATA_DIR/dir2/example" hello

  rm -fr "$HOME/dir"
  rm -fr "$HOME/example"
  rm -fr "$TEST_DATA_DIR/dir1"
  rm -fr "$TEST_DATA_DIR/dir2"

  ok "runtime override --nofilesystem=home"
fi

reset_overrides

if ! skip_one_without_bwrap "runtime override --nofilesystem=host"; then
  mkdir -p "$HOME/dir"
  mkdir -p "$TEST_DATA_DIR/dir1"
  mkdir -p "$TEST_DATA_DIR/dir2"
  echo "hello" > "$HOME/example"
  echo "hello" > "$HOME/dir/example"
  echo "hello" > "$TEST_DATA_DIR/dir1/example"
  echo "hello" > "$TEST_DATA_DIR/dir2/example"

  ${FLATPAK} override --user --filesystem=host org.test.Hello
  ${FLATPAK} override --user --filesystem='~/dir' org.test.Hello
  ${FLATPAK} override --user --filesystem="$TEST_DATA_DIR/dir1" org.test.Hello

  ${FLATPAK} run --env=TEST_DATA_DIR="$TEST_DATA_DIR" \
    --command=sh --nofilesystem=host org.test.Hello -c '
    echo overwritten > "$HOME/dir/example" || true
    echo overwritten > "$HOME/example" || true
    echo overwritten > "$TEST_DATA_DIR/dir1/example" || true
    echo overwritten > "$TEST_DATA_DIR/dir2/example" || true
  '
  # --nofilesystem=host does not cancel a more narrowly-scoped permission
  # such as --filesystem=~/dir
  assert_file_has_content "$HOME/dir/example" overwritten
  assert_file_has_content "$TEST_DATA_DIR/dir1/example" overwritten
  # --nofilesystem=host cancels the --filesystem=host at a lower precedence,
  # so $HOME/example was not shared
  assert_file_has_content "$HOME/example" hello
  assert_file_has_content "$TEST_DATA_DIR/dir2/example" hello

  rm -fr "$HOME/dir"
  rm -fr "$HOME/example"
  rm -fr "$TEST_DATA_DIR/dir1"
  rm -fr "$TEST_DATA_DIR/dir2"

  ok "runtime override --nofilesystem=host"
fi

reset_overrides

if ! skip_one_without_bwrap "runtime override --nofilesystem=host:reset"; then
  mkdir -p "$HOME/dir"
  mkdir -p "$TEST_DATA_DIR/dir1"
  mkdir -p "$TEST_DATA_DIR/dir2"
  echo "hello" > "$HOME/example"
  echo "hello" > "$HOME/dir/example"
  echo "hello" > "$TEST_DATA_DIR/dir1/example"
  echo "hello" > "$TEST_DATA_DIR/dir2/example"

  ${FLATPAK} override --user --filesystem=host org.test.Hello
  ${FLATPAK} override --user --filesystem='~/dir' org.test.Hello
  ${FLATPAK} override --user --filesystem="$TEST_DATA_DIR/dir1" org.test.Hello

  ${FLATPAK} run --env=TEST_DATA_DIR="$TEST_DATA_DIR" \
    --command=sh --nofilesystem=host:reset org.test.Hello -c '
    echo overwritten > "$HOME/dir/example" || true
    echo overwritten > "$HOME/example" || true
    echo overwritten > "$TEST_DATA_DIR/dir1/example" || true
    echo overwritten > "$TEST_DATA_DIR/dir2/example" || true
  '
  # --nofilesystem=host:reset cancels all --filesystem permissions from
  # lower-precedence layers
  assert_file_has_content "$HOME/dir/example" hello
  assert_file_has_content "$TEST_DATA_DIR/dir1/example" hello
  assert_file_has_content "$HOME/example" hello
  assert_file_has_content "$TEST_DATA_DIR/dir2/example" hello

  rm -fr "$HOME/dir"
  rm -fr "$HOME/example"
  rm -fr "$TEST_DATA_DIR/dir1"
  rm -fr "$TEST_DATA_DIR/dir2"

  ok "runtime override --nofilesystem=host:reset"
fi

===== ./tests/test-run.sh =====
#!/bin/bash
#
# Copyright (C) 2011 Colin Walters <walters@verbum.org>
#
# 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 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., 59 Temple Place - Suite 330,
# Boston, MA 02111-1307, USA.

set -euo pipefail

. $(dirname $0)/libtest.sh

skip_without_bwrap
skip_revokefs_without_fuse

echo "1..27"

# Use stable rather than master as the branch so we can test that the run
# command automatically finds the branch correctly
setup_repo "" "" stable
install_repo "" stable

# Verify that app is correctly installed

assert_has_dir $FL_DIR/app/org.test.Hello
assert_has_symlink $FL_DIR/app/org.test.Hello/current
assert_symlink_has_content $FL_DIR/app/org.test.Hello/current ^$ARCH/stable$
assert_has_dir $FL_DIR/app/org.test.Hello/$ARCH/stable
assert_has_symlink $FL_DIR/app/org.test.Hello/$ARCH/stable/active
ID=`readlink $FL_DIR/app/org.test.Hello/$ARCH/stable/active`
assert_has_file $FL_DIR/app/org.test.Hello/$ARCH/stable/active/deploy
assert_has_file $FL_DIR/app/org.test.Hello/$ARCH/stable/active/metadata
assert_has_dir $FL_DIR/app/org.test.Hello/$ARCH/stable/active/files
assert_has_dir $FL_DIR/app/org.test.Hello/$ARCH/stable/active/export
assert_has_file $FL_DIR/exports/share/applications/org.test.Hello.desktop
assert_has_file $FL_DIR/exports/share/metainfo/org.test.Hello.metainfo.xml
assert_has_file $FL_DIR/exports/share/metainfo/org.test.Hello.cmd.appdata.xml
# Ensure Exec key is rewritten
assert_file_has_content $FL_DIR/exports/share/applications/org.test.Hello.desktop "^Exec=.*flatpak run --branch=stable --arch=$ARCH --command=hello\.sh org\.test\.Hello$"
assert_has_file $FL_DIR/exports/share/gnome-shell/search-providers/org.test.Hello.search-provider.ini
assert_file_has_content $FL_DIR/exports/share/gnome-shell/search-providers/org.test.Hello.search-provider.ini "^DefaultDisabled=true$"
assert_has_file $FL_DIR/exports/share/krunner/dbusplugins/org.test.Hello.desktop
assert_file_has_content $FL_DIR/exports/share/krunner/dbusplugins/org.test.Hello.desktop "^X-KDE-PluginInfo-EnabledByDefault=false$"
assert_has_file $FL_DIR/exports/share/icons/hicolor/64x64/apps/org.test.Hello.png
assert_not_has_file $FL_DIR/exports/share/icons/hicolor/64x64/apps/dont-export.png
assert_has_file $FL_DIR/exports/share/icons/HighContrast/64x64/apps/org.test.Hello.png

$FLATPAK list ${U} | grep org.test.Hello > /dev/null
$FLATPAK list ${U} -d | grep org.test.Hello | grep test-repo > /dev/null
$FLATPAK list ${U} -d | grep org.test.Hello | grep current > /dev/null
$FLATPAK list ${U} -d | grep org.test.Hello | grep ${ID:0:12} > /dev/null

$FLATPAK info ${U} org.test.Hello > /dev/null
$FLATPAK info ${U} org.test.Hello | grep test-repo > /dev/null
$FLATPAK info ${U} org.test.Hello | grep $ID > /dev/null

ok "install"

if command -v update-desktop-database >/dev/null &&
   command -v update-mime-database >/dev/null &&
   command -v gtk-update-icon-cache >/dev/null; then
    # Ensure triggers ran
    assert_has_file $FL_DIR/exports/share/applications/mimeinfo.cache
    assert_file_has_content $FL_DIR/exports/share/applications/mimeinfo.cache x-test/Hello
    assert_has_file $FL_DIR/exports/share/icons/hicolor/icon-theme.cache
    assert_has_file $FL_DIR/exports/share/icons/hicolor/index.theme

    ok "install triggers"
else
    ok "install triggers # skip  Dependencies not available"
fi

run org.test.Hello &> hello_out
assert_file_has_content hello_out '^Hello world, from a sandbox$'

ok "hello"

# This should try and fail to run e.g. /usr/bin/--tmpfs, which will
# exit with a nonzero status because there is no such executable.
# It should not pass "--tmpfs /blah hello.sh" as bwrap options.
exit_status=0
run --command=--tmpfs org.test.Hello /blah hello.sh >&2 || exit_status=$?
assert_not_streq "$exit_status" 0

ok "avoided CVE-2024-32462"

true > value-in-sandbox
head value-in-sandbox >&2
run_sh org.test.Hello 'echo fd passthrough >&5' 5>value-in-sandbox
assert_file_has_content value-in-sandbox '^fd passthrough$'

ok "redirected fds can pass through to the app"

# XDG_RUNTIME_DIR is set to <temp directory>/runtime by libtest.sh,
# so we always have the necessary setup to reproduce #4372
assert_not_streq "$XDG_RUNTIME_DIR" "/run/user/$(id -u)"
run_sh org.test.Platform 'echo $XDG_RUNTIME_DIR' > value-in-sandbox
head value-in-sandbox >&2
assert_file_has_content value-in-sandbox "^/run/user/$(id -u)\$"

ok "XDG_RUNTIME_DIR=$XDG_RUNTIME_DIR not inherited"

assert_streq "$XDG_CACHE_HOME" "${TEST_DATA_DIR}/home/cache"
run_sh org.test.Hello 'echo "$XDG_CACHE_HOME"' > value-in-sandbox
head value-in-sandbox >&2
assert_file_has_content value-in-sandbox "^${TEST_DATA_DIR}/home/\\.var/app/org\\.test\\.Hello/cache\$"
test -d "${TEST_DATA_DIR}/home/.var/app/org.test.Hello/cache"
run_sh org.test.Hello 'echo "$HOST_XDG_CACHE_HOME"' > host-value-in-sandbox
head host-value-in-sandbox >&2
assert_file_has_content host-value-in-sandbox "^${TEST_DATA_DIR}/home/cache\$"

assert_streq "$XDG_CONFIG_HOME" "${TEST_DATA_DIR}/home/config"
run_sh org.test.Hello 'echo "$XDG_CONFIG_HOME"' > value-in-sandbox
head value-in-sandbox >&2
assert_file_has_content value-in-sandbox "^${TEST_DATA_DIR}/home/\\.var/app/org\\.test\\.Hello/config\$"
test -d "${TEST_DATA_DIR}/home/.var/app/org.test.Hello/config"
run_sh org.test.Hello 'echo "$HOST_XDG_CONFIG_HOME"' > host-value-in-sandbox
head host-value-in-sandbox >&2
assert_file_has_content host-value-in-sandbox "^${TEST_DATA_DIR}/home/config\$"

assert_streq "$XDG_DATA_HOME" "${TEST_DATA_DIR}/home/share"
run_sh org.test.Hello 'echo "$XDG_DATA_HOME"' > value-in-sandbox
head value-in-sandbox >&2
assert_file_has_content value-in-sandbox "^${TEST_DATA_DIR}/home/\\.var/app/org\\.test\\.Hello/data\$"
test -d "${TEST_DATA_DIR}/home/.var/app/org.test.Hello/data"
run_sh org.test.Hello 'echo "$HOST_XDG_DATA_HOME"' > host-value-in-sandbox
head host-value-in-sandbox >&2
assert_file_has_content host-value-in-sandbox "^${TEST_DATA_DIR}/home/share\$"

assert_streq "$XDG_STATE_HOME" "${TEST_DATA_DIR}/home/state"
run_sh org.test.Hello 'echo "$XDG_STATE_HOME"' > value-in-sandbox
head value-in-sandbox >&2
assert_file_has_content value-in-sandbox "^${TEST_DATA_DIR}/home/\\.var/app/org\\.test\\.Hello/\\.local/state\$"
test -d "${TEST_DATA_DIR}/home/.var/app/org.test.Hello/.local/state"
run_sh org.test.Hello 'echo "$HOST_XDG_STATE_HOME"' > host-value-in-sandbox
head host-value-in-sandbox >&2
assert_file_has_content host-value-in-sandbox "^${TEST_DATA_DIR}/home/state\$"

ok "XDG_foo_HOME work as expected"

run_sh org.test.Platform cat /.flatpak-info >runtime-fpi
assert_file_has_content runtime-fpi "[Runtime]"
assert_file_has_content runtime-fpi "^runtime=runtime/org\.test\.Platform/$ARCH/stable$"

ok "run a runtime"

if [ -f /etc/os-release ]; then
    run_sh org.test.Platform cat /run/host/os-release >os-release
    (cd /etc; md5sum os-release) | md5sum -c >&2

    ARGS="--filesystem=host-etc" run_sh org.test.Platform cat /run/host/os-release >os-release
    (cd /etc; md5sum os-release) | md5sum -c >&2

    if run_sh org.test.Platform "echo test >> /run/host/os-release"; then exit 1; fi
    if run_sh org.test.Platform "echo test >> /run/host/os-release"; then exit 1; fi
elif [ -f /usr/lib/os-release ]; then
    run_sh org.test.Platform cat /run/host/os-release >os-release
    (cd /usr/lib; md5sum os-release) | md5sum -c >&2

    ARGS="--filesystem=host-os" run_sh org.test.Platform cat /run/host/os-release >os-release
    (cd /usr/lib; md5sum os-release) | md5sum -c >&2

    if run_sh org.test.Platform "echo test >> /run/host/os-release"; then exit 1; fi
    if run_sh org.test.Platform "echo test >> /run/host/os-release"; then exit 1; fi
fi

ok "host os-release"

run_sh org.test.Platform 'cat /run/host/container-manager' > container-manager
echo flatpak > expected
diff -u expected container-manager >&2
run_sh org.test.Platform 'echo "${container}"' > container-manager
diff -u expected container-manager >&2

ok "host container-manager"

if run org.test.Nonexistent 2> run-error-log >&2; then
    assert_not_reached "Unexpectedly able to run non-existent runtime"
fi
assert_file_has_content run-error-log "error: app/org\.test\.Nonexistent/$ARCH/master not installed"

if ${FLATPAK} run --commit=abc runtime/org.test.Platform 2> run-error-log >&2; then
    assert_not_reached "Unexpectedly able to run non-existent commit"
fi
assert_file_has_content run-error-log "error: runtime/org\.test\.Platform/$ARCH/stable (commit abc) not installed"

if run runtime/org.test.Nonexistent 2> run-error-log >&2; then
    assert_not_reached "Unexpectedly able to run non-existent runtime"
fi
assert_file_has_content run-error-log "error: runtime/org\.test\.Nonexistent/\*unspecified\*/\*unspecified\* not installed"

ok "error handling for invalid refs"

run_sh org.test.Hello cat /run/user/`id -u`/flatpak-info > fpi
assert_file_has_content fpi '^name=org\.test\.Hello$'

ok "flatpak-info"

run_sh org.test.Hello readlink /proc/self/ns/net > unshared_net_ns
ARGS="--share=network" run_sh org.test.Hello readlink /proc/self/ns/net > shared_net_ns
assert_not_streq `cat unshared_net_ns` `readlink /proc/self/ns/net`
assert_streq `cat shared_net_ns` `readlink /proc/self/ns/net`

run_sh org.test.Hello readlink /proc/self/ns/ipc > unshared_ipc_ns
ARGS="--share=ipc" run_sh org.test.Hello readlink /proc/self/ns/ipc > shared_ipc_ns
assert_not_streq `cat unshared_ipc_ns` `readlink /proc/self/ns/ipc`
assert_streq `cat shared_ipc_ns` `readlink /proc/self/ns/ipc`

# We try the filesystem namespace tests several times with different
# shared-or-not directories, because:
# - --filesystem=/foo doesn't work if /foo is read-only in the container
#   (notably, --filesystem=/usr/... won't work)
# - --filesystem=host doesn't expose either /usr or /var/... or /var/tmp
#   from the host because they're on the list of things we expect to be
#   supplied by the container

test_filesystem_binding () {
    local dir="$1"

    if run_sh org.test.Hello cat "$dir/package_version.txt" &> /dev/null; then
        assert_not_reached "Unexpectedly allowed to access file"
    fi

    case "$dir" in
        (/home/*|/opt/*|/var/tmp/*)
            if ! ARGS="--filesystem=$dir" run_sh org.test.Hello cat "$dir/package_version.txt" > /dev/null; then
                assert_not_reached "Failed to share --filesystem=$dir"
            fi
            ;;
        (*)
            echo "Not testing --filesystem=$dir, it won't necessarily work" >&2
            ;;
    esac

    case "$dir" in
        (/home/*|/opt/*)
            if ! ARGS="--filesystem=host" run_sh org.test.Hello cat "$dir/package_version.txt" > /dev/null; then
                assert_not_reached "Failed to share $dir as part of host filesystem"
            fi
            ;;
        (*)
            echo "Not testing --filesystem=host with $dir, it won't necessarily work" >&2
            ;;
    esac
}

test_filesystem_binding "${test_builddir}"

mkdir "${TEST_DATA_DIR}/shareable"
cp "${test_builddir}/package_version.txt" "${TEST_DATA_DIR}/shareable/"
test_filesystem_binding "${TEST_DATA_DIR}/shareable"

# We don't want to pollute the home directory unprompted, but the user
# can opt-in by creating this directory.
if [ -e "${HOME}/.flatpak-tests" ]; then
    cp "${test_builddir}/package_version.txt" "${HOME}/.flatpak-tests/"
    test_filesystem_binding "${HOME}/.flatpak-tests"
else
    echo "not testing \$HOME binding, \$HOME/.flatpak-tests/ does not exist" >&2
fi

ok "namespaces"

test_overrides () {
    local dir="$1"

    if run_sh org.test.Hello cat "$dir/package_version.txt" &> /dev/null; then
        assert_not_reached "Unexpectedly allowed to access file"
    fi

    $FLATPAK override ${U} --filesystem=host org.test.Hello >&2

    case "$dir" in
        (/home/*|/opt/*)
            if ! run_sh org.test.Hello cat "$dir/package_version.txt" > /dev/null; then
                assert_not_reached "Failed to share $dir as part of host filesystem"
            fi
            ;;
        (*)
            echo "Not testing --filesystem=host with $dir, it won't necessarily work" >&2
            ;;
    esac

    if ARGS="--nofilesystem=host" run_sh org.test.Hello cat "${dir}/package_version.txt" &> /dev/null; then
        assert_not_reached "Unexpectedly allowed to access --nofilesystem=host file"
    fi

    $FLATPAK override ${U} --nofilesystem=host org.test.Hello >&2

    if run_sh org.test.Hello cat "${dir}/package_version.txt" &> /dev/null; then
        assert_not_reached "Unexpectedly allowed to access file"
    fi
}

test_overrides "${test_builddir}"

if [ -e "${HOME}/.flatpak-tests" ]; then
    cp "${test_builddir}/package_version.txt" "${HOME}/.flatpak-tests/"
    test_overrides "${HOME}/.flatpak-tests"
else
    echo "not testing \$HOME binding overrides, \$HOME/.flatpak-tests/ does not exist" >&2
fi

ok "overrides"

OLD_COMMIT=`${FLATPAK} ${U} info --show-commit org.test.Hello`

# TODO: For weird reasons this breaks in the system case. Needs debugging
if [ x${USE_SYSTEMDIR-} != xyes ] ; then
    ${FLATPAK} ${U} update -y -v org.test.Hello stable >&2
    ALSO_OLD_COMMIT=`${FLATPAK} ${U} info --show-commit org.test.Hello`
    assert_streq "$OLD_COMMIT" "$ALSO_OLD_COMMIT"
fi

ok "null update"

make_updated_app "" "" stable

${FLATPAK} ${U} update -y org.test.Hello >&2

NEW_COMMIT=`${FLATPAK} ${U} info --show-commit org.test.Hello`

assert_not_streq "$OLD_COMMIT" "$NEW_COMMIT"

run org.test.Hello &> hello_out
assert_file_has_content hello_out '^Hello world, from a sandboxUPDATED$'

ok "update"

ostree --repo=repos/test reset app/org.test.Hello/$ARCH/stable "$OLD_COMMIT" >&2
update_repo

if ${FLATPAK} ${U} update -y org.test.Hello >&2; then
    assert_not_reached "Should not be able to update to older commit"
fi

NEW_NEW_COMMIT=`${FLATPAK} ${U} info --show-commit org.test.Hello`

assert_streq "$NEW_COMMIT" "$NEW_NEW_COMMIT"

ok "backwards update"

make_updated_app "" "" stable UPDATED2

OLD_COMMIT=`${FLATPAK} ${U} info --show-commit org.test.Hello`

# We should ignore the update (and warn) by default
${FLATPAK} ${U} install -y test-repo org.test.Hello >& install_stderr

NEW_COMMIT=`${FLATPAK} ${U} info --show-commit org.test.Hello`

assert_streq "$OLD_COMMIT" "$NEW_COMMIT"
assert_file_has_content install_stderr 'org.test.Hello/.* is already installed'

# But --or-update should do the update
${FLATPAK} ${U} install -y --or-update test-repo org.test.Hello >&2

NEW_COMMIT=`${FLATPAK} ${U} info --show-commit org.test.Hello`

assert_not_streq "$OLD_COMMIT" "$NEW_COMMIT"

ok "install --or-update"

DIR=`mktemp -d`
${FLATPAK} build-init ${DIR} org.test.Split org.test.Platform org.test.Platform stable >&2

mkdir -p ${DIR}/files/a
echo "a" > ${DIR}/files/a/data
mkdir -p ${DIR}/files/b
echo "b" > ${DIR}/files/b/data
mkdir -p ${DIR}/files/c
echo "c" > ${DIR}/files/c/data
mkdir -p ${DIR}/files/d
echo "d" > ${DIR}/files/d/data
echo "nope" > ${DIR}/files/nope

${FLATPAK} build-finish --command=hello.sh ${DIR} >&2
${FLATPAK} build-export --no-update-summary ${FL_GPGARGS} repos/test ${DIR} stable >&2
update_repo

${FLATPAK} ${U} install -y test-repo org.test.Split --subpath=/a --subpath=/b --subpath=/nosuchdir stable >&2

COMMIT=`${FLATPAK} ${U} info --show-commit org.test.Split`
if [ x${USE_SYSTEMDIR-} != xyes ] ; then
    # Work around bug in ostree: local pulls don't do commitpartials
    assert_has_file $FL_DIR/repo/state/${COMMIT}.commitpartial
fi

assert_has_file $FL_DIR/app/org.test.Split/$ARCH/stable/active/files/a/data
assert_has_file $FL_DIR/app/org.test.Split/$ARCH/stable/active/files/b/data
assert_not_has_file $FL_DIR/app/org.test.Split/$ARCH/stable/active/files/c
assert_not_has_file $FL_DIR/app/org.test.Split/$ARCH/stable/active/files/d
assert_not_has_file $FL_DIR/app/org.test.Split/$ARCH/stable/active/files/nope
assert_not_has_file $FL_DIR/app/org.test.Split/$ARCH/stable/active/files/nosuchdir

echo "aa" > ${DIR}/files/a/data2
rm  ${DIR}/files/a/data
mkdir -p ${DIR}/files/e
echo "e" > ${DIR}/files/e/data
mkdir -p ${DIR}/files/f
echo "f" > ${DIR}/files/f/data
rm -rf  ${DIR}/files/b

${FLATPAK} build-export --no-update-summary ${FL_GPGARGS} repos/test ${DIR} stable >&2
update_repo

${FLATPAK} ${U} update -y --subpath=/a --subpath=/b --subpath=/e --subpath=/nosuchdir org.test.Split >&2

COMMIT=`${FLATPAK} ${U} info --show-commit org.test.Split`
if [ x${USE_SYSTEMDIR-} != xyes ] ; then
    # Work around bug in ostree: local pulls don't do commitpartials
    assert_has_file $FL_DIR/repo/state/${COMMIT}.commitpartial
fi

assert_not_has_file $FL_DIR/app/org.test.Split/$ARCH/stable/active/files/a/data
assert_has_file $FL_DIR/app/org.test.Split/$ARCH/stable/active/files/a/data2
assert_not_has_file $FL_DIR/app/org.test.Split/$ARCH/stable/active/files/b
assert_not_has_file $FL_DIR/app/org.test.Split/$ARCH/stable/active/files/c
assert_not_has_file $FL_DIR/app/org.test.Split/$ARCH/stable/active/files/d
assert_has_file $FL_DIR/app/org.test.Split/$ARCH/stable/active/files/e/data
assert_not_has_file $FL_DIR/app/org.test.Split/$ARCH/stable/active/files/f
assert_not_has_file $FL_DIR/app/org.test.Split/$ARCH/stable/active/files/nope

${FLATPAK} build-export --no-update-summary ${FL_GPGARGS} repos/test ${DIR} stable >&2
update_repo

# Test reusing the old subpath list
${FLATPAK} ${U} update -y org.test.Split >&2

COMMIT=`${FLATPAK} ${U} info --show-commit org.test.Split`
if [ x${USE_SYSTEMDIR-} != xyes ] ; then
    # Work around bug in ostree: local pulls don't do commitpartials
    assert_has_file $FL_DIR/repo/state/${COMMIT}.commitpartial
fi

assert_not_has_file $FL_DIR/app/org.test.Split/$ARCH/stable/active/files/a/data
assert_has_file $FL_DIR/app/org.test.Split/$ARCH/stable/active/files/a/data2
assert_not_has_file $FL_DIR/app/org.test.Split/$ARCH/stable/active/files/b
assert_not_has_file $FL_DIR/app/org.test.Split/$ARCH/stable/active/files/c
assert_not_has_file $FL_DIR/app/org.test.Split/$ARCH/stable/active/files/d
assert_has_file $FL_DIR/app/org.test.Split/$ARCH/stable/active/files/e/data
assert_not_has_file $FL_DIR/app/org.test.Split/$ARCH/stable/active/files/f
assert_not_has_file $FL_DIR/app/org.test.Split/$ARCH/stable/active/files/nope

ok "subpaths"

VERSION=`cat "$test_builddir/package_version.txt"`

DIR=`mktemp -d`
${FLATPAK} build-init ${DIR} org.test.CurrentVersion org.test.Platform org.test.Platform stable >&2
${FLATPAK} build-finish --require-version=${VERSION} --command=hello.sh ${DIR} >&2
${FLATPAK} build-export --no-update-summary ${FL_GPGARGS} repos/test ${DIR} stable >&2
DIR=`mktemp -d`
${FLATPAK} build-init ${DIR} org.test.OldVersion org.test.Platform org.test.Platform stable >&2
${FLATPAK} build-finish --require-version=0.6.10 --command=hello.sh ${DIR} >&2
${FLATPAK} build-export --no-update-summary ${FL_GPGARGS} repos/test ${DIR} stable >&2
DIR=`mktemp -d`
${FLATPAK} build-init ${DIR} org.test.NewVersion org.test.Platform org.test.Platform stable >&2
${FLATPAK} build-finish --require-version=1${VERSION} --command=hello.sh ${DIR} >&2
${FLATPAK} build-export --no-update-summary ${FL_GPGARGS} repos/test ${DIR} stable >&2

update_repo

${FLATPAK} ${U} install -y test-repo org.test.OldVersion stable >&2
${FLATPAK} ${U} install -y test-repo org.test.CurrentVersion stable >&2
(! ${FLATPAK} ${U} install -y test-repo org.test.NewVersion stable) >&2

DIR=`mktemp -d`
${FLATPAK} build-init ${DIR} org.test.OldVersion org.test.Platform org.test.Platform stable >&2
${FLATPAK} build-finish --require-version=99.0.0 --command=hello.sh ${DIR} >&2
${FLATPAK} build-export  --no-update-summary ${FL_GPGARGS} repos/test ${DIR} stable >&2
update_repo

(! ${FLATPAK} ${U} update -y org.test.OldVersion) >&2

DIR=`mktemp -d`
${FLATPAK} build-init ${DIR} org.test.OldVersion org.test.Platform org.test.Platform stable >&2
${FLATPAK} build-finish --require-version=0.1.1 --command=hello.sh ${DIR} >&2
${FLATPAK} build-export  --no-update-summary ${FL_GPGARGS} repos/test ${DIR} stable >&2
update_repo

${FLATPAK} ${U} update -y org.test.OldVersion >&2

# Make sure a multi-ref update succeeds even if some update requires a newer version
# Note that updates are in alphabetical order, so CurrentVersion will be pulled first
# and should not block a successful install of OldVersion later

DIR=`mktemp -d`
${FLATPAK} build-init ${DIR} org.test.CurrentVersion org.test.Platform org.test.Platform stable >&2
touch ${DIR}/files/updated
${FLATPAK} build-finish --require-version=99.0.0 --command=hello.sh ${DIR} >&2
${FLATPAK} build-export --no-update-summary ${FL_GPGARGS} repos/test ${DIR} stable >&2
DIR=`mktemp -d`
${FLATPAK} build-init ${DIR} org.test.OldVersion org.test.Platform org.test.Platform stable >&2
touch ${DIR}/files/updated
${FLATPAK} build-finish --require-version=${VERSION} --command=hello.sh ${DIR} >&2
${FLATPAK} build-export --no-update-summary ${FL_GPGARGS} repos/test ${DIR} stable >&2
update_repo

if ${FLATPAK} ${U} update -y &> err_version.txt; then
    assert_not_reached "Should not have been able to update due to version"
fi
assert_file_has_content err_version.txt "needs a later flatpak version"

assert_not_has_file $FL_DIR/app/org.test.CurrentVersion/$ARCH/stable/active/files/updated
assert_has_file $FL_DIR/app/org.test.OldVersion/$ARCH/stable/active/files/updated

ok "version checks"

rm -rf app
${FLATPAK} build-init app org.test.Writable org.test.Platform org.test.Platform stable >&2
mkdir -p app/files/a-dir
chmod a+rwx app/files/a-dir
${FLATPAK} build-finish --command=hello.sh app >&2
# Note: not --canonical-permissions
${FLATPAK} build-export -vv  --no-update-summary --disable-sandbox --files=files repos/test app stable >&2
ostree --repo=repos/test commit  --keep-metadata=xa.metadata --owner-uid=0 --owner-gid=0  --no-xattrs  ${FL_GPGARGS} --branch=app/org.test.Writable/$ARCH/stable app >&2
update_repo

# In the system-helper case this fails to install due to the permission canonicalization happening in the
# child-repo making objects get the wrong checksum, whereas in the user case we successfully import it, but
# it will have canonicalized permissions.
if ${FLATPAK} ${U} install -y test-repo org.test.Writable >&2; then
    assert_file_has_mode $FL_DIR/app/org.test.Writable/$ARCH/stable/active/files/a-dir 775
fi

ok "no world writable dir"

rm -rf app
${FLATPAK} build-init app org.test.Setuid org.test.Platform org.test.Platform stable >&2
mkdir -p app/files/
touch app/files/exe
chmod u+s app/files/exe
${FLATPAK} build-finish --command=hello.sh app >&2
# Note: not --canonical-permissions
${FLATPAK} build-export -vv  --no-update-summary --disable-sandbox --files=files repos/test app stable >&2
ostree -v --repo=repos/test commit --keep-metadata=xa.metadata --owner-uid=0 --owner-gid=0 --no-xattrs  ${FL_GPGARGS} --branch=app/org.test.Setuid/$ARCH/stable app >&2
update_repo

if ${FLATPAK} ${U} install -y test-repo org.test.Setuid &> err2.txt; then
    assert_not_reached "Should not be able to install with setuid file"
fi
assert_file_has_content err2.txt [Ii]nvalid

ok "no setuid"

rm -rf app
${FLATPAK} build-init app org.test.App org.test.Platform org.test.Platform stable >&2
mkdir -p app/files/
touch app/files/exe
${FLATPAK} build-finish --command=hello.sh --sdk=org.test.Sdk app >&2
${FLATPAK} build-export  --no-update-summary ${FL_GPGARGS} repos/test app stable >&2
update_repo

${FLATPAK} ${U} install -y test-repo org.test.App >&2
${FLATPAK} ${U} info -m org.test.App > out

assert_file_has_content out "^sdk=org\.test\.Sdk/$(flatpak --default-arch)/stable$"

ok "--sdk option"

rm -fr "$HOME/.var/app/org.test.Hello"
mkdir -p "$HOME/.var/app/org.test.Hello"
run --command=sh --persist=.persist org.test.Hello -c 'echo can-persist > .persist/rc'
sed -e 's,^,#--persist=.persist# ,g' < "$HOME/.var/app/org.test.Hello/.persist/rc" >&2
assert_file_has_content "$HOME/.var/app/org.test.Hello/.persist/rc" "can-persist"

ok "--persist=.persist persists a directory"

rm -fr "$HOME/.var/app/org.test.Hello"
mkdir -p "$HOME/.var/app/org.test.Hello"
# G_DEBUG='' to avoid the deprecation warning being fatal
G_DEBUG='' run --command=sh --persist=/.persist org.test.Hello -c 'echo can-persist > .persist/rc'
sed -e 's,^,#--persist=/.persist# ,g' < "$HOME/.var/app/org.test.Hello/.persist/rc" >&2
assert_file_has_content "$HOME/.var/app/org.test.Hello/.persist/rc" "can-persist"

ok "--persist=/.persist is a deprecated form of --persist=.persist"

rm -fr "$HOME/.var/app/org.test.Hello"
mkdir -p "$HOME/.var/app/org.test.Hello"
run --command=sh --persist=. org.test.Hello -c 'echo can-persist > .persistrc'
sed -e 's,^,#--persist=.# ,g' < "$HOME/.var/app/org.test.Hello/.persistrc" >&2
assert_file_has_content "$HOME/.var/app/org.test.Hello/.persistrc" "can-persist"

ok "--persist=. persists all files"

mkdir "${TEST_DATA_DIR}/inaccessible"
echo FOO > ${TEST_DATA_DIR}/inaccessible/secret-file
rm -fr "$HOME/.var/app/org.test.Hello"
mkdir -p "$HOME/.var/app/org.test.Hello"
ln -fns "${TEST_DATA_DIR}/inaccessible" "$HOME/.var/app/org.test.Hello/persist"
# G_DEBUG='' to avoid the warnings being fatal when we reject a --persist option.
# LC_ALL=C so we get the expected non-localized string.
LC_ALL=C G_DEBUG='' run --command=ls --persist=persist --persist=relative/../escape org.test.Hello -la ~/persist &> hello_out || true
sed -e 's,^,#--persist=symlink# ,g' < hello_out >&2
assert_file_has_content hello_out "not allowed to avoid sandbox escape"
assert_not_file_has_content hello_out "secret-file"

ok "--persist doesn't allow sandbox escape via a symlink (CVE-2024-42472)"

===== ./tests/installed-services/meson.build =====
# Copyright 2022 Collabora Ltd.
# SPDX-License-Identifier: LGPL-2.1-or-later

foreach triple : [
  ['oci-authenticator', 'org.flatpak.Authenticator.Oci', {}],
  ['portal', 'org.freedesktop.portal.Flatpak', {
    'extraargs' : ' --poll-timeout=1',
  }],
  ['session-helper', 'org.freedesktop.Flatpak', {}],
  ['system-helper', 'org.freedesktop.Flatpak.SystemHelper', {
    'extraargs' : ' --session --no-idle-exit',
  }],
]
  directory = triple[0]
  service = triple[1]
  options = triple[2]

  configure_file(
    input : project_source_root / directory / (service + '.service.in'),
    output : service + '.service',
    configuration : {
      'extraargs' : options.get('extraargs', ''),
      'libexecdir' : get_option('prefix') / get_option('libexecdir'),
    },
    install_dir : installed_testdir / 'services',
  )
endforeach

foreach service : [
  'org.flatpak.Authenticator.test',
  'org.freedesktop.impl.portal.desktop.test',
]
  configure_file(
    input : project_source_root / 'tests' / (service + '.service.in'),
    output : service + '.service',
    configuration : {
      'libexecdir' : installed_testdir,
    },
    install_dir : installed_testdir / 'services',
  )
endforeach

install_data(
  project_source_root / 'tests/test.portal.in',
  install_dir : installed_testdir / 'share/xdg-desktop-portal/portals',
  rename : 'test.portal',
)

===== ./tests/test-keyring/secring.gpg =====
V o>N|ߝLJZ\VҰi0%ބEXIl6F̞z^xHlp;r,WVeD	AëLЯ^)P#FqWa#'SkS˕8cS=_;miDɦg0io\r)O@iι4a>JC!/,5HWhm{ʟ.	!U1ς|Q
vx7L	q-5i]   .<pO+*	CX`@8HƏ2(65	k_~@A  HĦzFQeî](4&2FEn}I̸M!׮,)'vԏ*H/֙s*(#mg=7,i3X)"Y[-]1p^ւYA*IJqv2&, )z]p0k^g eׯ{Ih?hEvb xH:>E2e {gpB#w$VoS;<"y!o(9!͚.5Cax2inmRѩuRb7vqe
VFV=zwF  ,XԂ:|_)roj۪+LrV <\ܻ åbTA`a~d0sk .'v߫OZQ7c^8zpڈyK.KDARĐyN*#eGw,v Le\Jucy-Umcf+y ɲ$gy诇2/0h`D=>7<S[`+I&tW.-6iXdg-app testing8 "V		
 
	1{	aMI㶭?#@dB5iY#Z(ޠB*/8e昘8씁yR%x`F]WH
[_"CpXoZ
$P' ETdkRnIǨhvNb{L ڔJd !şݛ1n1=NTKFś<ғݼS03X 88V /tن&8NcHerڹqQP޿`.Z8N4~Zi;h0ݶ:{ i	yi>aF=ZME>jsX5R_|u
RB@ZUK:N;hJ`:2㕈3`p~'w|a%7
.Yey/ݻa-FrCp\Fh	u={8&:)Fy;   I<0۟(sMT;e]CѢ5);0e?;iv(%ѦGܘxW@	8js4WП'4"fW>@7;~R?!mY'akA&$#"Y,4s:*.GG".dDlV`G@_Ԫ5 xD.we҄hqfӐKJ7h7fhd0-r-VuXj n :du]G	p$BF0@"T64 eŊktvƄȤ@e)?nkEeXhdmBٜt\>L2+ꕭK
kUGT#2U&V4KD! q-ʎy
dm{kёW"5i<+"7|=KKL?7*)Cq+ /'38{EmZ|E=5pn?oyF %ܭj3MNkULUށ-60^V!h%YKLCB8z|fpwIX:,_|J86+k-&Or: ?U҈JLڪz@de+6Z 	V 
	1{	aL/z"7oNilÃ-&KƑ
!RI93bqYf% -L8*}SfF Wo8DFhSyo()MsOITH«CWЂ|M&Q ƥa}cuFO!tFIpFۼzufD	b.2RObݡjCobpt&6-Ge~*a}dk}~3p_b
===== ./tests/test-keyring/pubring.gpg =====
V o>N|ߝLJZ\VҰi0%ބEXIl6F̞z^xHlp;r,WVeD	AëLЯ^)P#FqWa#'SkS˕8cS=_;miDɦg0io\r)O@iι4a>JC!/,5HWhm{ʟ.	!U1ς|Q
vx7L	q-5i]  Xdg-app testing8 "V		
 
	1{	aMI㶭?#@dB5iY#Z(ޠB*/8e昘8씁yR%x`F]WH
[_"CpXoZ
$P' ETdkRnIǨhvNb{L ڔJd !şݛ1n1=NTKFś<ғݼS03X 88V /tن&8NcHerڹqQP޿`.Z8N4~Zi;h0ݶ:{ i	yi>aF=ZME>jsX5R_|u
RB@ZUK:N;hJ`:2㕈3`p~'w|a%7
.Yey/ݻa-FrCp\Fh	u={8&:)Fy;   	V 
	1{	aL/z"7oNilÃ-&KƑ
!RI93bqYf% -L8*}SfF Wo8DFhSyo()MsOITH«CWЂ|M&Q ƥa}cuFO!tFIpFۼzufD	b.2RObݡjCobpt&6-Ge~*a}dk}~3p_b
===== ./tests/test-keyring/README =====
These are completely random keys, which include the secret key.
Use these for testing gpg signing, do *NOT* ever use these for any
real application.

===== ./tests/test-keyring/meson.build =====
# Copyright 2022 Collabora Ltd.
# SPDX-License-Identifier: LGPL-2.1-or-later

foreach file : [
  'README',
  'pubring.gpg',
  'secring.gpg',
]
  configure_file(
    input : file,
    output : file,
    copy : true,
    install : get_option('installed_tests'),
    install_dir : installed_testdir / 'test-keyring',
    install_mode : 'rw-r--r--',
  )
endforeach

===== ./tests/oci-registry-server.py =====
#!/usr/bin/python3

import argparse
import base64
import hashlib
import json
import os
import ssl
import time

from urllib.parse import parse_qs
import http.server as http_server

repositories = {}
icons = {}
signatures = {}


def get_index():
    results = []
    for repo_name in sorted(repositories.keys()):
        repo = repositories[repo_name]
        results.append(
            {
                "Name": repo_name,
                "Images": repo["images"],
                "Lists": [],
            }
        )

    return json.dumps({"Registry": "/", "Results": results}, indent=4).encode("UTF-8")


def cache_icon(data_uri):
    prefix = "data:image/png;base64,"
    assert data_uri.startswith(prefix)
    data = base64.b64decode(data_uri[len(prefix) :])
    h = hashlib.sha256()
    h.update(data)
    digest = h.hexdigest()
    filename = digest + ".png"
    icons[filename] = data

    return "/icons/" + filename


serial = 0
server_start_time = int(time.time())


def get_etag():
    return str(server_start_time) + "-" + str(serial)


def modified():
    global serial
    serial += 1


class RequestHandler(http_server.BaseHTTPRequestHandler):
    def check_route(self, route):
        parts = self.path.split("?", 1)
        path = parts[0].split("/")

        route_path = route.split("/")
        if len(route_path) != len(path):
            return False

        matches = {}
        for i in range(1, len(route_path)):
            if route_path[i][0] == "@":
                matches[route_path[i][1:]] = path[i]
            elif route_path[i] != path[i]:
                return False

        self.matches = matches
        if len(parts) == 1:
            self.query = {}
        else:
            self.query = parse_qs(parts[1], keep_blank_values=True)

        return True

    def do_GET(self):
        response = 404
        response_string = b""
        response_content_type = "application/octet-stream"

        add_headers = {}

        def get_file_contents(repo_name, type, ref):
            try:
                path = repositories[repo_name][type][ref]
                with open(path, "rb") as f:
                    return 200, f.read()
            except KeyError:
                return 404, b""

        if self.check_route("/v2/@repo_name/blobs/@digest"):
            repo_name = self.matches["repo_name"]
            digest = self.matches["digest"]
            response, response_string = get_file_contents(repo_name, "blobs", digest)
        elif self.check_route("/v2/@repo_name/manifests/@ref"):
            repo_name = self.matches["repo_name"]
            ref = self.matches["ref"]
            response, response_string = get_file_contents(repo_name, "manifests", ref)
        elif self.check_route("/index/static") or self.check_route("/index/dynamic"):
            etag = get_etag()
            add_headers["Etag"] = etag
            if self.headers.get("If-None-Match") == etag:
                response = 304
                response_string = b""
            else:
                response = 200
                response_string = get_index()
        elif self.check_route("/icons/@filename"):
            response = 200
            response_string = icons[self.matches["filename"]]
            response_content_type = "image/png"
        elif self.check_route("/sig-lookaside/@ref/@sig"):
            ref = self.matches["ref"]
            sig = self.matches["sig"]
            index = int(sig.removeprefix("signature-")) - 1
            try:
                response = 200
                response_string = signatures[ref][index]
            except (KeyError, IndexError):
                response = 404

        assert isinstance(response, int)
        assert isinstance(response_string, bytes)
        assert isinstance(response_content_type, str)

        add_headers["Content-Length"] = len(response_string)

        self.send_response(response)
        for k, v in list(add_headers.items()):
            self.send_header(k, v)

        if response == 200:
            self.send_header("Content-Type", response_content_type)

        if response == 200 or response == 304:
            self.send_header("Cache-Control", "no-cache")

        self.end_headers()

        self.wfile.write(response_string)

    def do_HEAD(self):
        return self.do_GET()

    def do_POST(self):
        if self.check_route("/testing/@repo_name/@tag"):
            repo_name = self.matches["repo_name"]
            tag = self.matches["tag"]
            d = self.query["d"][0]
            detach_icons = "detach-icons" in self.query

            repo = repositories.setdefault(repo_name, {})
            blobs = repo.setdefault("blobs", {})
            manifests = repo.setdefault("manifests", {})
            images = repo.setdefault("images", [])

            with open(os.path.join(d, "index.json")) as f:
                index = json.load(f)

            manifest_digest = index["manifests"][0]["digest"]
            manifest_path = os.path.join(d, "blobs", *manifest_digest.split(":"))
            manifests[manifest_digest] = manifest_path
            manifests[tag] = manifest_path

            with open(manifest_path) as f:
                manifest = json.load(f)

            config_digest = manifest["config"]["digest"]
            config_path = os.path.join(d, "blobs", *config_digest.split(":"))

            with open(config_path) as f:
                config = json.load(f)

            for dig in os.listdir(os.path.join(d, "blobs", "sha256")):
                digest = "sha256:" + dig
                path = os.path.join(d, "blobs", "sha256", dig)
                if digest != manifest_digest:
                    blobs[digest] = path

            if detach_icons:
                for size in (64, 128):
                    annotation = "org.freedesktop.appstream.icon-{}".format(size)
                    icon = manifest.get("annotations", {}).get(annotation)
                    if icon:
                        path = cache_icon(icon)
                        manifest["annotations"][annotation] = path
                    else:
                        icon = (
                            config.get("config", {}).get("Labels", {}).get(annotation)
                        )
                        if icon:
                            path = cache_icon(icon)
                            config["config"]["Labels"][annotation] = path

            image = {
                "Tags": [tag],
                "Digest": manifest_digest,
                "MediaType": "application/vnd.oci.image.manifest.v1+json",
                "OS": config["os"],
                "Architecture": config["architecture"],
                "Annotations": manifest.get("annotations", {}),
                "Labels": config.get("config", {}).get("Labels", {}),
            }

            # Delete old versions
            for i in images:
                if tag in i["Tags"]:
                    images.remove(i)
                    del manifests[i["Digest"]]

            images.append(image)

            modified()
            self.send_response(200)
            self.end_headers()
            return
        elif self.check_route("/testing-sig/@repo_name/@digest"):
            repo_name = self.matches["repo_name"]
            digest = self.matches["digest"]
            s = self.query["s"][0]

            with open(s, "rb") as f:
                signature_bytes = f.read()

            digest = digest.replace(":", "=")
            ref = f"{repo_name}@{digest}"
            sigs = signatures.setdefault(ref, [])
            sigs.append(signature_bytes)
            self.send_response(200)
            self.end_headers()
        else:
            self.send_response(404)
            self.end_headers()
            return

    def do_DELETE(self):
        if self.check_route("/testing/@repo_name/@ref"):
            repo_name = self.matches["repo_name"]
            ref = self.matches["ref"]

            repo = repositories.setdefault(repo_name, {})
            repo.setdefault("blobs", {})
            manifests = repo.setdefault("manifests", {})
            images = repo.setdefault("images", [])

            image = None
            for i in images:
                if i["Digest"] == ref or ref in i["Tags"]:
                    image = i
                    break

            assert image

            images.remove(image)
            del manifests[image["Digest"]]
            for t in image["Tags"]:
                del manifests[t]

            modified()
            self.send_response(200)
            self.end_headers()
            return
        elif self.check_route("/testing-sig/@repo_name/@digest"):
            repo_name = self.matches["repo_name"]
            digest = self.matches["digest"]

            digest = digest.replace(":", "=")
            ref = f"{repo_name}@{digest}"
            signatures[ref] = list()
            self.send_response(200)
            self.end_headers()
            return
        else:
            self.send_response(404)
            self.end_headers()
            return


def run(args):
    RequestHandler.protocol_version = "HTTP/1.0"
    httpd = http_server.HTTPServer(("127.0.0.1", 0), RequestHandler)

    if args.cert:
        context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
        context.options |= ssl.OP_NO_TLSv1 | ssl.OP_NO_TLSv1_1
        context.load_cert_chain(certfile=args.cert, keyfile=args.key)

        if args.mtls_cacert:
            context.load_verify_locations(cafile=args.mtls_cacert)
            # In a real application, we'd need to check the CN against authorized users
            context.verify_mode = ssl.CERT_REQUIRED

        httpd.socket = context.wrap_socket(httpd.socket, server_side=True)

    host, port = httpd.socket.getsockname()[:2]
    with open("httpd-port", "w") as file:
        file.write("%d" % port)
    try:
        os.write(3, bytes("Started\n", "utf-8"))
    except OSError:
        pass
    if args.cert:
        print("Serving HTTPS on port %d" % port)
    else:
        print("Serving HTTP on port %d" % port)
    if args.dir:
        os.chdir(args.dir)
    httpd.serve_forever()


if __name__ == "__main__":
    parser = argparse.ArgumentParser()
    parser.add_argument("--dir")
    parser.add_argument("--cert")
    parser.add_argument("--key")
    parser.add_argument("--mtls-cacert")
    args = parser.parse_args()

    run(args)

===== ./tests/try-syscall.c =====
/* vi:set et sw=2 sts=2 cin cino=t0,f0,(0,{s,>2s,n-s,^-s,e-s:
 * Copyright 2021 Simon McVittie
 * SPDX-License-Identifier: LGPL-2.0-or-later
 *
 * Try one or more system calls that might have been blocked by a
 * seccomp filter. Return the last value of errno seen.
 *
 * In general, we pass a bad fd or pointer to each syscall that will
 * accept one, so that it will fail with EBADF or EFAULT without side-effects.
 *
 * This helper is used for regression tests in both bubblewrap and flatpak.
 * Please keep both copies in sync.
 */

#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <sys/prctl.h>
#include <sys/socket.h>
#include <sys/syscall.h>
#include <sys/stat.h>
#include <sys/types.h>

#if defined(_MIPS_SIM)
# if _MIPS_SIM == _ABIO32
#   define MISSING_SYSCALL_BASE 4000
# elif _MIPS_SIM == _ABI64
#   define MISSING_SYSCALL_BASE 5000
# elif _MIPS_SIM == _ABIN32
#   define MISSING_SYSCALL_BASE 6000
# else
#   error "Unknown MIPS ABI"
# endif
#endif

#if defined(__ia64__)
# define MISSING_SYSCALL_BASE 1024
#endif

#if defined(__alpha__)
# define MISSING_SYSCALL_BASE 110
#endif

#if defined(__x86_64__) && defined(__ILP32__)
# define MISSING_SYSCALL_BASE 0x40000000
#endif

/*
 * MISSING_SYSCALL_BASE:
 *
 * Number to add to the syscall numbers of recently-added syscalls
 * to get the appropriate syscall for the current ABI.
 */
#ifndef MISSING_SYSCALL_BASE
# define MISSING_SYSCALL_BASE 0
#endif

#ifndef __NR_clone3
# define __NR_clone3 (MISSING_SYSCALL_BASE + 435)
#endif

/*
 * The size of clone3's parameter (as of 2021)
 */
#define SIZEOF_STRUCT_CLONE_ARGS ((size_t) 88)

/*
 * An invalid pointer that will cause syscalls to fail with EFAULT
 */
#define WRONG_POINTER ((char *) 1)

#ifndef PR_GET_CHILD_SUBREAPER
#define PR_GET_CHILD_SUBREAPER 37
#endif

int
main (int argc, char **argv)
{
  int errsv = 0;
  int i;

  for (i = 1; i < argc; i++)
    {
      const char *arg = argv[i];

      if (strcmp (arg, "print-errno-values") == 0)
        {
          printf ("EBADF=%d\n", EBADF);
          printf ("EFAULT=%d\n", EFAULT);
          printf ("ENOENT=%d\n", ENOENT);
          printf ("ENOSYS=%d\n", ENOSYS);
          printf ("EPERM=%d\n", EPERM);
        }
      else if (strcmp (arg, "chmod") == 0)
        {
          /* If not blocked by seccomp, this will fail with EFAULT */
          if (chmod (WRONG_POINTER, 0700) != 0)
            {
              errsv = errno;
              perror (arg);
            }
        }
      else if (strcmp (arg, "chroot") == 0)
        {
          /* If not blocked by seccomp, this will fail with EFAULT */
          if (chroot (WRONG_POINTER) != 0)
            {
              errsv = errno;
              perror (arg);
            }
        }
      else if (strcmp (arg, "clone3") == 0)
        {
          /* If not blocked by seccomp, this will fail with EFAULT */
          if (syscall (__NR_clone3, WRONG_POINTER, SIZEOF_STRUCT_CLONE_ARGS) != 0)
            {
              errsv = errno;
              perror (arg);
            }
        }
      else if (strcmp (arg, "ioctl TIOCNOTTY") == 0)
        {
          /* If not blocked by seccomp, this will fail with EBADF */
          if (ioctl (-1, TIOCNOTTY) != 0)
            {
              errsv = errno;
              perror (arg);
            }
        }
      else if (strcmp (arg, "ioctl TIOCSTI") == 0)
        {
          /* If not blocked by seccomp, this will fail with EBADF */
          if (ioctl (-1, TIOCSTI, WRONG_POINTER) != 0)
            {
              errsv = errno;
              perror (arg);
            }
        }
#ifdef __LP64__
      else if (strcmp (arg, "ioctl TIOCSTI CVE-2019-10063") == 0)
        {
          unsigned long not_TIOCSTI = (0x123UL << 32) | (unsigned long) TIOCSTI;

          /* If not blocked by seccomp, this will fail with EBADF */
          if (syscall (__NR_ioctl, -1, not_TIOCSTI, WRONG_POINTER) != 0)
            {
              errsv = errno;
              perror (arg);
            }
        }
#endif
      else if (strcmp (arg, "ioctl TIOCLINUX") == 0)
        {
          /* If not blocked by seccomp, this will fail with EBADF */
          if (ioctl (-1, TIOCLINUX, WRONG_POINTER) != 0)
            {
              errsv = errno;
              perror (arg);
            }
        }
     else if (strcmp (arg, "listen") == 0)
        {
          /* If not blocked by seccomp, this will fail with EBADF */
          if (listen (-1, 42) != 0)
            {
              errsv = errno;
              perror (arg);
            }
        }
     else if (strcmp (arg, "prctl") == 0)
        {
          /* If not blocked by seccomp, this will fail with EFAULT */
          if (prctl (PR_GET_CHILD_SUBREAPER, WRONG_POINTER, 0, 0, 0) != 0)
            {
              errsv = errno;
              perror (arg);
            }
        }
      else
        {
          fprintf (stderr, "Unsupported syscall \"%s\"\n", arg);
          errsv = ENOENT;
        }
   }

  return errsv;
}

===== ./tests/testlib.c =====
/* vi:set et sw=2 sts=2 cin cino=t0,f0,(0,{s,>2s,n-s,^-s,e-s:
 * Copyright © 2018-2021 Collabora Ltd.
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 */

#include "config.h"
#include "testlib.h"

#include <glib.h>
#include <glib/gstdio.h>

#include "libglnx.h"

char *
assert_mkdtemp (char *tmpl)
{
  char *ret = g_mkdtemp (tmpl);

  if (ret == NULL)
    g_error ("%s", g_strerror (errno));
  else
    g_assert_true (ret == tmpl);

  return ret;
}

char *isolated_test_dir = NULL;

void
isolated_test_dir_global_setup (void)
{
  g_autofree char *cachedir = NULL;
  g_autofree char *configdir = NULL;
  g_autofree char *datadir = NULL;
  g_autofree char *statedir = NULL;
  g_autofree char *homedir = NULL;
  g_autofree char *runtimedir = NULL;

  isolated_test_dir = g_strdup ("/tmp/flatpak-test-XXXXXX");
  assert_mkdtemp (isolated_test_dir);
  g_test_message ("isolated_test_dir: %s", isolated_test_dir);

  homedir = g_strconcat (isolated_test_dir, "/home", NULL);
  g_assert_no_errno (g_mkdir_with_parents (homedir, S_IRWXU | S_IRWXG | S_IRWXO));

  g_setenv ("HOME", homedir, TRUE);
  g_test_message ("setting HOME=%s", homedir);

  cachedir = g_strconcat (isolated_test_dir, "/home/cache", NULL);
  g_assert_no_errno (g_mkdir_with_parents (cachedir, S_IRWXU | S_IRWXG | S_IRWXO));
  g_setenv ("XDG_CACHE_HOME", cachedir, TRUE);
  g_test_message ("setting XDG_CACHE_HOME=%s", cachedir);

  configdir = g_strconcat (isolated_test_dir, "/home/config", NULL);
  g_assert_no_errno (g_mkdir_with_parents (configdir, S_IRWXU | S_IRWXG | S_IRWXO));
  g_setenv ("XDG_CONFIG_HOME", configdir, TRUE);
  g_test_message ("setting XDG_CONFIG_HOME=%s", configdir);

  datadir = g_strconcat (isolated_test_dir, "/home/share", NULL);
  g_assert_no_errno (g_mkdir_with_parents (datadir, S_IRWXU | S_IRWXG | S_IRWXO));
  g_setenv ("XDG_DATA_HOME", datadir, TRUE);
  g_test_message ("setting XDG_DATA_HOME=%s", datadir);

  statedir = g_strconcat (isolated_test_dir, "/home/state", NULL);
  g_assert_no_errno (g_mkdir_with_parents (statedir, S_IRWXU | S_IRWXG | S_IRWXO));
  g_setenv ("XDG_STATE_HOME", statedir, TRUE);
  g_test_message ("setting XDG_STATE_HOME=%s", statedir);

  runtimedir = g_strconcat (isolated_test_dir, "/runtime", NULL);
  g_assert_no_errno (g_mkdir_with_parents (runtimedir, S_IRWXU));
  g_setenv ("XDG_RUNTIME_DIR", runtimedir, TRUE);
  g_test_message ("setting XDG_RUNTIME_DIR=%s", runtimedir);

  g_reload_user_special_dirs_cache ();

  g_assert_cmpstr (g_get_user_cache_dir (), ==, cachedir);
  g_assert_cmpstr (g_get_user_config_dir (), ==, configdir);
  g_assert_cmpstr (g_get_user_data_dir (), ==, datadir);
  g_assert_cmpstr (g_getenv ("XDG_STATE_HOME"), ==, statedir);
  g_assert_cmpstr (g_get_user_runtime_dir (), ==, runtimedir);
}

void
isolated_test_dir_global_teardown (void)
{
  if (g_getenv ("SKIP_TEARDOWN"))
    return;

  glnx_shutil_rm_rf_at (-1, isolated_test_dir, NULL, NULL);
  g_free (isolated_test_dir);
  isolated_test_dir = NULL;
}

static void
replace_tokens (const char *in_path,
                const char *out_path)
{
  g_autoptr(GError) error = NULL;
  g_autoptr(GString) buffer = NULL;
  g_autofree char *contents = NULL;
  const char *iter;

  g_file_get_contents (in_path, &contents, NULL, &error);
  g_assert_no_error (error);

  buffer = g_string_new ("");
  iter = contents;

  while (iter[0] != '\0')
    {
      const char *first_at = strchr (iter, '@');
      const char *second_at;

      if (first_at == NULL)
        {
          /* no more @token@s, append [iter..end] and stop */
          g_string_append (buffer, iter);
          break;
        }

      second_at = strchr (first_at + 1, '@');

      if (second_at == NULL)
        g_error ("Unterminated @token@ in %s: %s", in_path, first_at);

      /* append the literal text [iter..first_at - 1], if non-empty */
      if (first_at != iter)
        g_string_append_len (buffer, iter, first_at - iter);

      /* append the replacement for [first_at..second_at] if known */
      if (g_str_has_prefix (first_at, "@testdir@"))
        {
          g_autofree char *testdir = g_test_build_filename (G_TEST_DIST, ".", NULL);

          g_string_append (buffer, testdir);
        }
      else
        {
          g_error ("Unknown @token@ in %s: %.*s",
                   in_path, (int) (second_at - first_at) + 1, first_at);
        }

      /* continue to process [second_at + 1..end] */
      iter = second_at + 1;
    }

  g_file_set_contents (out_path, buffer->str, -1, &error);
  g_assert_no_error (error);
}

void
tests_dbus_daemon_setup (TestsDBusDaemon *self)
{
  g_autoptr(GSubprocessLauncher) launcher = NULL;
  g_autoptr(GError) error = NULL;
  g_autofree char *config_arg = NULL;
  g_autofree char *session_conf = NULL;
  g_autofree char *session_conf_in = NULL;
  GInputStream *address_pipe;
  gchar address_buffer[4096] = { 0 };
  char *newline;

  g_return_if_fail (self != NULL);
  g_return_if_fail (self->dbus_daemon == NULL);
  g_return_if_fail (self->dbus_address == NULL);
  g_return_if_fail (self->temp_dir == NULL);

  self->temp_dir = g_dir_make_tmp ("flatpak-test.XXXXXX", &error);
  g_assert_no_error (error);
  g_assert_nonnull (self->temp_dir);

  session_conf_in = g_test_build_filename (G_TEST_DIST, "session.conf.in", NULL);
  session_conf = g_build_filename (self->temp_dir, "test-bus.conf", NULL);
  replace_tokens (session_conf_in, session_conf);
  config_arg = g_strdup_printf ("--config-file=%s", session_conf);
  launcher = g_subprocess_launcher_new (G_SUBPROCESS_FLAGS_STDOUT_PIPE);
  self->dbus_daemon = g_subprocess_launcher_spawn (launcher, &error,
                                                   "dbus-daemon",
                                                   config_arg,
                                                   "--print-address=1",
                                                   "--nofork",
                                                   NULL);
  g_assert_no_error (error);
  g_assert_nonnull (self->dbus_daemon);

  address_pipe = g_subprocess_get_stdout_pipe (self->dbus_daemon);
  g_assert_nonnull (address_pipe);

  /* Crash if it takes too long to get the address */
  alarm (30);

  while (strchr (address_buffer, '\n') == NULL)
    {
      if (strlen (address_buffer) >= sizeof (address_buffer) - 1)
        g_error ("Read %" G_GSIZE_FORMAT " bytes from dbus-daemon with "
                 "no newline",
                 sizeof (address_buffer) - 1);

      g_input_stream_read (address_pipe,
                           address_buffer + strlen (address_buffer),
                           sizeof (address_buffer) - strlen (address_buffer),
                           NULL, &error);
      g_assert_no_error (error);
    }

  /* Disable alarm */
  alarm (0);

  newline = strchr (address_buffer, '\n');
  g_assert_nonnull (newline);
  *newline = '\0';
  self->dbus_address = g_strdup (address_buffer);
}

void
tests_dbus_daemon_teardown (TestsDBusDaemon *self)
{
  g_autoptr(GError) error = NULL;

  if (self->dbus_daemon != NULL)
    {
      g_subprocess_send_signal (self->dbus_daemon, SIGTERM);
      g_subprocess_wait (self->dbus_daemon, NULL, &error);
      g_assert_no_error (error);
    }

  if (self->temp_dir != NULL)
    {
      glnx_shutil_rm_rf_at (AT_FDCWD, self->temp_dir, NULL, &error);
      g_assert_no_error (error);
    }

  g_clear_object (&self->dbus_daemon);
  g_clear_pointer (&self->dbus_address, g_free);
  g_clear_pointer (&self->temp_dir, g_free);
}

struct _TestsStdoutToStderr
{
  int fd;
};

TestsStdoutToStderr *
tests_stdout_to_stderr_begin (void)
{
  TestsStdoutToStderr *original = g_new0 (TestsStdoutToStderr, 1);

  original->fd = fcntl (STDOUT_FILENO, F_DUPFD_CLOEXEC, 3);

  if (original->fd < 0)
    g_error ("fcntl F_DUPFD_CLOEXEC: %s", g_strerror (errno));

  if (dup2 (STDERR_FILENO, STDOUT_FILENO) < 0)
    g_error ("dup2: %s", g_strerror (errno));

  /* STDOUT_FILENO is intentionally not close-on-exec */

  return original;
}

void
tests_stdout_to_stderr_end (TestsStdoutToStderr *original)
{
  g_return_if_fail (original != NULL);
  g_return_if_fail (original->fd >= 0);

  if (dup2 (original->fd, STDOUT_FILENO) < 0)
    g_error ("dup2: %s", g_strerror (errno));

  /* STDOUT_FILENO is intentionally not close-on-exec */

  g_close (original->fd, NULL);
  g_free (original);
}

===== ./tests/test.portal.in =====
[portal]
DBusName=org.freedesktop.impl.portal.desktop.test
Interfaces=org.freedesktop.impl.portal.Access
UseIn=test

===== ./tests/testlib.h =====
/*
 * Copyright © 2018-2021 Collabora Ltd.
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 */

#ifndef TESTLIB_H
#define TESTLIB_H

#include <glib.h>
#include <gio/gio.h>
#include <libglnx.h>

char *assert_mkdtemp (char *tmpl);

extern char *isolated_test_dir;
void isolated_test_dir_global_setup (void);
void isolated_test_dir_global_teardown (void);

typedef struct
{
  GSubprocess *dbus_daemon;
  gchar *dbus_address;
  gchar *temp_dir;
} TestsDBusDaemon;

void tests_dbus_daemon_setup (TestsDBusDaemon *self);
void tests_dbus_daemon_teardown (TestsDBusDaemon *self);

typedef struct _TestsStdoutToStderr TestsStdoutToStderr;
TestsStdoutToStderr *tests_stdout_to_stderr_begin (void);
void tests_stdout_to_stderr_end (TestsStdoutToStderr *original);
G_DEFINE_AUTOPTR_CLEANUP_FUNC (TestsStdoutToStderr, tests_stdout_to_stderr_end);

#define TESTS_SCOPED_STDOUT_TO_STDERR \
  G_GNUC_UNUSED g_autoptr(TestsStdoutToStderr) _tests_stdout_to_stderr = tests_stdout_to_stderr_begin ()

/*
 * assert_cmpstr_free_lhs:
 * @lhs: (transfer full): An expression returning an owned string,
 *  which will be freed
 * @op: Either `==`, `!=`, `<=`, `<`, `>` or `>=`
 * @rhs: (transfer none): An expression returning an unowned string
 *
 * Assert that @lhs has the given relationship with @rhs, then free @lhs.
 */
#define assert_cmpstr_free_lhs(lhs, op, rhs) \
  do { \
    g_autofree char *free_lhs = NULL; \
    g_assert_cmpstr ((free_lhs = (lhs)), op, (rhs)); \
  } while (0)

/*
 * assert_cmpstr_free_rhs:
 * @lhs: (transfer none): An expression returning an unowned string
 * @op: Either `==`, `!=`, `<=`, `<`, `>` or `>=`
 * @rhs: (transfer full): An expression returning an owned string,
 *  which will be freed
 *
 * Assert that @lhs has the given relationship with @rhs, then free @rhs.
 */
#define assert_cmpstr_free_rhs(lhs, op, rhs) \
  do { \
    g_autofree char *free_rhs = NULL; \
    g_assert_cmpstr ((lhs), op, (free_rhs = (rhs))); \
  } while (0)

/*
 * assert_cmpstr_free_both:
 * @lhs: (transfer full): An expression returning an owned string,
 *  which will be freed
 * @op: Either `==`, `!=`, `<=`, `<`, `>` or `>=`
 * @rhs: (transfer full): An expression returning an owned string,
 *  which will be freed
 *
 * Assert that @lhs has the given relationship with @rhs, then free both
 * strings.
 */
#define assert_cmpstr_free_both(lhs, op, rhs) \
  do { \
    g_autofree char *free_lhs = NULL; \
    g_autofree char *free_rhs = NULL; \
    g_assert_cmpstr ((free_lhs = (lhs)), op, (free_rhs = (rhs))); \
  } while (0)

#endif

===== ./tests/test-repair.sh =====
#!/bin/bash
#
# Copyright (C) 2021 Matthew Leeds <mwleeds@protonmail.com>
#
# SPDX-License-Identifier: LGPL-2.0-or-later

set -euo pipefail

. $(dirname $0)/libtest.sh

echo "1..2"

setup_repo
${FLATPAK} ${U} install -y test-repo org.test.Hello >&2

# delete the object for files/bin/hello.sh
rm ${FL_DIR}/repo/objects/0d/30582c0ac8a2f89f23c0f62e548ba7853f5285d21848dd503460a567b5d253.file

# dry run repair shouldn't replace the missing file
${FLATPAK} ${U} repair --dry-run >&2
assert_not_has_file ${FL_DIR}/repo/objects/0d/30582c0ac8a2f89f23c0f62e548ba7853f5285d21848dd503460a567b5d253.file

# normal repair should replace the missing file
${FLATPAK} ${U} repair >&2
assert_has_file ${FL_DIR}/repo/objects/0d/30582c0ac8a2f89f23c0f62e548ba7853f5285d21848dd503460a567b5d253.file

# app should've been reinstalled
${FLATPAK} ${U} list -d > list-log
assert_file_has_content list-log "org\.test\.Hello/"

ok "repair command handles missing files"

# Test that flatpak repair --reinstall-all does not change pin state
# https://github.com/flatpak/flatpak/issues/6565
# Reuse the repo and installation from the previous test.

# Clear any pins to ensure a known-empty state before repair
${FLATPAK} ${U} pin --remove "runtime/org.test.Platform/$ARCH/master" &>/dev/null || true

${FLATPAK} ${U} pin > pins-before
${FLATPAK} ${U} repair --reinstall-all >&2
${FLATPAK} ${U} pin > pins-after

# Pin state must be identical after repair
diff -q pins-before pins-after >/dev/null || \
    assert_not_reached "repair --reinstall-all changed pin state"
rm pins-before pins-after

# Clean up
${FLATPAK} ${U} uninstall -y org.test.Platform org.test.Hello >&2
${FLATPAK} ${U} remote-delete test-repo >&2

ok "repair --reinstall-all preserves pin state"

===== ./tests/libtest.sh =====
# Source library for shell script tests
#
# Copyright (C) 2016 Alexander Larsson <alexl@redhat.com>
# Copyright (C) 2011 Colin Walters <walters@verbum.org>
#
# 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 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., 59 Temple Place - Suite 330,
# Boston, MA 02111-1307, USA.

# Under Autotools, redirect stderr to stdout, otherwise the log will have
# command output out of order with xtrace output.
# Under Meson, we need stdout to be in strict TAP format, so we'll
# consistently send everything except TAP to stderr instead.
if [ -z "${FLATPAK_TESTS_STRICT_TAP-}" ]; then
    exec 2>&1
fi

if [ -n "${G_TEST_SRCDIR:-}" ]; then
    test_srcdir="${G_TEST_SRCDIR}"
else
    test_srcdir=$(dirname $0)
fi

if [ -n "${G_TEST_BUILDDIR:-}" ]; then
    test_builddir="${G_TEST_BUILDDIR}"
else
    test_builddir=$(dirname $0)
fi

if [ -e "$test_srcdir/installed-tests.sh" ]; then
    . "$test_srcdir/installed-tests.sh"
fi

# All the asserts and ok functions below are wrapped such that they
# don't output any set -x traces of their internals (but still echo
# errors to stderr). This way the log output focuses on tracing what
# is essential to the test (the asserts being run and errors from them)

assert_not_reached () {
    { { local BASH_XTRACEFD=3; } 2> /dev/null
    echo $@ 1>&2; exit 1
    } 3> /dev/null
}

ok () {
    { { local BASH_XTRACEFD=3; } 2> /dev/null
        echo "ok $@";
        echo "================ $(basename ${BASH_SOURCE[1]}):${BASH_LINENO[0]} - $@ ================" >&2;
    } 3> /dev/null
}

test_tmpdir=$(pwd)

# Sanity check that we're in a tmpdir that has
# just .testtmp (created by tap-driver for `make check`,
# or nothing at all (as ginstest-runner does)
if ! test -f .testtmp; then
    files=$(ls)
    if test -n "${files}"; then
        ls -l
        assert_not_reached "test tmpdir=${test_tmpdir} is not empty; run this test via \`make check TESTS=\`, not directly"
    fi
    # Remember that this is an acceptable test $(pwd), for the benefit of
    # C and JS tests which may source this file again
    touch .testtmp
fi

export G_DEBUG=fatal-warnings

# Also, unbreak `tar` inside `make check`...Automake will inject
# TAR_OPTIONS: --owner=0 --group=0 --numeric-owner presumably so that
# tarballs are predictable, except we don't want this in our tests.
unset TAR_OPTIONS

if test -n "${FLATPAK_TESTS_VALGRIND:-}"; then
    CMD_PREFIX="env G_SLICE=always-malloc valgrind -q --leak-check=no --error-exitcode=1 --gen-suppressions=all --num-callers=30 --suppressions=${test_srcdir}/flatpak.supp --suppressions=${test_srcdir}/glib.supp"
elif test -n "${FLATPAK_TESTS_VALGRIND_LEAKS:-}"; then
    CMD_PREFIX="env G_SLICE=always-malloc valgrind -q --leak-check=full  --errors-for-leak-kinds=definite --error-exitcode=1 --gen-suppressions=all --num-callers=30 --suppressions=${test_srcdir}/flatpak.supp --suppressions=${test_srcdir}/glib.supp"
else
    CMD_PREFIX=""
fi
unset OSTREE_DEBUG_HTTP

export MALLOC_CHECK_=3
export MALLOC_PERTURB_=$(($RANDOM % 255 + 1))

TEST_DATA_DIR=`mktemp -d /tmp/test-flatpak-XXXXXX`
mkdir -p ${TEST_DATA_DIR}/home
mkdir -p ${TEST_DATA_DIR}/runtime
mkdir -p ${TEST_DATA_DIR}/system
mkdir -p ${TEST_DATA_DIR}/config
mkdir -p ${TEST_DATA_DIR}/run
export FLATPAK_SYSTEM_DIR=${TEST_DATA_DIR}/system
export FLATPAK_SYSTEM_CACHE_DIR=${TEST_DATA_DIR}/system-cache
export FLATPAK_SYSTEM_HELPER_ON_SESSION=1
export FLATPAK_CONFIG_DIR=${TEST_DATA_DIR}/config
export FLATPAK_DATA_DIR=${TEST_DATA_DIR}/datadir
export FLATPAK_RUN_DIR=${TEST_DATA_DIR}/run
export FLATPAK_FANCY_OUTPUT=0
export FLATPAK_FORCE_ALLOW_FUZZY_MATCHING=1

export HOME=${TEST_DATA_DIR}/home
export XDG_CACHE_HOME=${TEST_DATA_DIR}/home/cache
export XDG_CONFIG_HOME=${TEST_DATA_DIR}/home/config
export XDG_DATA_HOME=${TEST_DATA_DIR}/home/share
export XDG_STATE_HOME=${TEST_DATA_DIR}/home/state
export XDG_RUNTIME_DIR=${TEST_DATA_DIR}/runtime

export XDG_DESKTOP_PORTAL_DIR=${test_builddir}/share/xdg-desktop-portal/portals
export XDG_CURRENT_DESKTOP=test

# On Debian derivatives, /usr/sbin and /sbin aren't in ordinary users'
# PATHs, but ldconfig and capsh are kept in /sbin
PATH="$PATH:/usr/sbin:/sbin"

export USERDIR=${TEST_DATA_DIR}/home/share/flatpak
export SYSTEMDIR=${TEST_DATA_DIR}/system
export ARCH=`flatpak --default-arch`

if [ x${SUMMARY_FORMAT-} == xold ] ; then
    export BUILD_UPDATE_REPO_FLAGS="--no-summary-index"
fi

if [ x${USE_SYSTEMDIR-} == xyes ] ; then
    export FL_DIR=${SYSTEMDIR}
    export U=
    export INVERT_U=--user
    if [ x${UID} == x0 ] ; then
        # If running as root (which happens on some build machines), the
        # system-helper will not be used, and hence the fallback cache dir will
        # be used in _flatpak_dir_ensure_repo().
        export FL_CACHE_DIR=$FL_DIR/repo/tmp/cache
    else
        export FL_CACHE_DIR=${XDG_CACHE_HOME}/flatpak/system-cache
    fi
else
    export FL_DIR=${USERDIR}
    export U="--user"
    export INVERT_U=--system
    export FL_CACHE_DIR=$FL_DIR/repo/tmp/cache
fi

if [ x${USE_DELTAS-} == xyes ] ; then
    export UPDATE_REPO_ARGS="--generate-static-deltas"
fi

export FLATPAK="${CMD_PREFIX} flatpak"

assert_streq () {
    { { local BASH_XTRACEFD=3; } 2> /dev/null
    test "$1" = "$2" || (echo 1>&2 "$1 != $2 at $(basename ${BASH_SOURCE[1]}):${BASH_LINENO[0]}"; exit 1)
    } 3> /dev/null
}

assert_not_streq () {
    { { local BASH_XTRACEFD=3; } 2> /dev/null
    (! test "$1" = "$2") || (echo 1>&2 "$1 == $2 at $(basename ${BASH_SOURCE[1]}):${BASH_LINENO[0]}"; exit 1)
    } 3> /dev/null
}

assert_has_file () {
    { { local BASH_XTRACEFD=3; } 2> /dev/null
    test -f "$1" || (echo 1>&2 "Couldn't find '$1' at $(basename ${BASH_SOURCE[1]}):${BASH_LINENO[0]}"; exit 1)
    } 3> /dev/null
}

assert_has_symlink () {
    { { local BASH_XTRACEFD=3; } 2> /dev/null
    test -L "$1" || (echo 1>&2 "Couldn't find '$1' at $(basename ${BASH_SOURCE[1]}):${BASH_LINENO[0]}"; exit 1)
    } 3> /dev/null
}

assert_has_dir () {
    { { local BASH_XTRACEFD=3; } 2> /dev/null
    test -d "$1" || (echo 1>&2 "Couldn't find '$1' at $(basename ${BASH_SOURCE[1]}):${BASH_LINENO[0]}"; exit 1)
    } 3> /dev/null
}

assert_not_has_file () {
    { { local BASH_XTRACEFD=3; } 2> /dev/null
    if test -f "$1"; then
        sed -e 's/^/# /' < "$1" >&2
        echo 1>&2 "File '$1' exists at $(basename ${BASH_SOURCE[1]}):${BASH_LINENO[0]}"
        exit 1
    fi
    } 3> /dev/null
}

assert_not_file_has_content () {
    { { local BASH_XTRACEFD=3; } 2> /dev/null
    if grep -q -e "$2" "$1"; then
        sed -e 's/^/# /' < "$1" >&2
        echo 1>&2 "File '$1' incorrectly matches regexp '$2' at $(basename ${BASH_SOURCE[1]}):${BASH_LINENO[0]}"
        exit 1
    fi
    } 3> /dev/null
}

assert_file_has_mode () {
    { { local BASH_XTRACEFD=3; } 2> /dev/null
    mode=$(stat -c '%a' $1)
    if [ "$mode" != "$2" ]; then
        echo 1>&2 "File '$1' has wrong mode: expected $2, but got $mode at $(basename ${BASH_SOURCE[1]}):${BASH_LINENO[0]}"
        exit 1
    fi
    } 3> /dev/null
}

assert_not_has_dir () {
    { { local BASH_XTRACEFD=3; } 2> /dev/null
    if test -d "$1"; then
        echo 1>&2 "Directory '$1' exists at $(basename ${BASH_SOURCE[1]}):${BASH_LINENO[0]}"; exit 1
    fi
    } 3> /dev/null
}

assert_file_has_content () {
    { { local BASH_XTRACEFD=3; } 2> /dev/null
    if ! grep -q -e "$2" "$1"; then
        sed -e 's/^/# /' < "$1" >&2
        echo 1>&2 "File '$1' doesn't match regexp '$2' at $(basename ${BASH_SOURCE[1]}):${BASH_LINENO[0]}"
        exit 1
    fi
    } 3> /dev/null
}

assert_log_has_gpg_signature_error () {
    { { local BASH_XTRACEFD=3; } 2> /dev/null
    if ! grep -q -e "GPG signatures found, but none are in trusted keyring" "$1"; then
        if ! grep -q -e "Can't check signature: public key not found" "$1"; then
            sed -e 's/^/# /' < "$1" >&2
            echo 1>&2 "File '$1' doesn't have gpg signature error at $(basename ${BASH_SOURCE[1]}):${BASH_LINENO[0]}"
            exit 1
        fi
    fi
    } 3> /dev/null
}

assert_symlink_has_content () {
    { { local BASH_XTRACEFD=3; } 2> /dev/null
    if ! readlink "$1" | grep -q -e "$2"; then
        readlink "$1" |sed -e 's/^/# /' >&2
        echo 1>&2 "Symlink '$1' doesn't match regexp '$2' at $(basename ${BASH_SOURCE[1]}):${BASH_LINENO[0]}"
        exit 1
    fi
    } 3> /dev/null
}

assert_file_empty() {
    { { local BASH_XTRACEFD=3; } 2> /dev/null
    if test -s "$1"; then
        sed -e 's/^/# /' < "$1" >&2
        echo 1>&2 "File '$1' is not empty at $(basename ${BASH_SOURCE[1]}):${BASH_LINENO[0]}"
        exit 1
    fi
    } 3> /dev/null
}

assert_remote_has_config () {
    { { local BASH_XTRACEFD=3; } 2> /dev/null
    ostree config --repo=$FL_DIR/repo get --group 'remote "'"$1"'"' "$2" > key-output
    assert_file_has_content key-output "$3"
    } 3> /dev/null
}

assert_remote_has_no_config () {
    { { local BASH_XTRACEFD=3; } 2> /dev/null
    if ostree config --repo=$FL_DIR/repo get --group 'remote "'"$1"'"' "$2" &> /dev/null; then
        echo 1>&2 "Remote '$1' unexpectedly has key '$2' at $(basename ${BASH_SOURCE[1]}):${BASH_LINENO[0]}"
        exit 1
    fi
    } 3> /dev/null
}

assert_fail () {
    if "$@"; then
        { { local BASH_XTRACEFD=3; } 2> /dev/null
            echo "Command '$*' should not have succeeded at $(basename ${BASH_SOURCE[1]}):${BASH_LINENO[0]}" >&2
            exit 1
        } 3> /dev/null
    fi
}

export FL_GPG_HOMEDIR=${TEST_DATA_DIR}/gpghome
export FL_GPG_HOMEDIR2=${TEST_DATA_DIR}/gpghome2
mkdir -p ${FL_GPG_HOMEDIR}
mkdir -p ${FL_GPG_HOMEDIR2}
# This need to be writable, so copy the keys
cp $(dirname $0)/test-keyring/*.gpg ${FL_GPG_HOMEDIR}/
cp $(dirname $0)/test-keyring2/*.gpg ${FL_GPG_HOMEDIR2}/

export FL_GPG_ID=7B0961FD
export FL_GPG_ID2=B2314EFC
export FL_GPGARGS="--gpg-homedir=${FL_GPG_HOMEDIR} --gpg-sign=${FL_GPG_ID}"
export FL_GPGARGS2="--gpg-homedir=${FL_GPG_HOMEDIR2} --gpg-sign=${FL_GPG_ID2}"
export FL_GPGCMDARGS="--homedir ${FL_GPG_HOMEDIR} -u ${FL_GPG_ID}"
export FL_GPGCMDARGS2="--homedir ${FL_GPG_HOMEDIR2} -u ${FL_GPG_ID2}"
export FL_GPG_BASE64="mQENBFbPBvoBCADWbz5O+XzuyN+dDExK81pci+gIzBNWB+7SsN0EgoJppKgwBCX+Bd6ERe9Yz0nJbJB/tjazRp7MnnoPnh6fXnhIbHA766/Eciy4sL5X8laqDmWmROCqCe79QZH/w6vYTKsDmoLQrw9eKRP1ilCvECNGcVdhIyfTDlNrU//uy5U4h2PVUz1/Al87lvaJnrj5423m5GnX+qpEG8mmpmcw52lvXNPuC95ykylPQJjI0WnOuaTcxzRhm5eHPkqKQ+nPIS+66iw1SFdobYuye/vg/rDiyp8uyQkh7FWXnzHxz4J8ovesnrCM7pKI4VEHCnZ4/sj2v9E3l0wJlqZxLTULaV3lABEBAAG0D1hkZy1hcHAgdGVzdGluZ4kBOAQTAQIAIgUCVs8G+gIbAwYLCQgHAwIGFQgCCQoLBBYCAwECHgECF4AACgkQE4sx4HsJYf2DiAf7BQ8anU3CgYpJjuO2rT8jQPO0jGRCNaPyaeAcBx8IjFkjf8daKMPCAt6gQioEpC8OhDig86Bl5piYOB7L7JSB53mgUrADJXhgC/dG4soCt7/U4wW30MseXdlXSOqHGApblF/bIs4B30OBGReBj3DcWIqyb48GraSKlPlaCpkZFySNEAcGUCeCqbbygxCQAM8MDq9FgVRk5oVrE/nAUm6oScEBhseoB7+CaHaRTmLoe/SBs0z2AJ7alIH1Sv4X3mQXpfsAIcWf3Zu2MZydF/Vuh8vTMROwPYtOVEtGxZvEBN3h5uc88dHSk928maqsop9T6oEwM43mBKCOu1gdAOw4OLkBDQRWzwb6AQgAx/XuEaQvdI3J2YYmOE6RY0jJZXLauXH46cJR4q70mlDev/OqYKTSLlo4q06D4ozCwzTYflppDak7kmjWMN224/u1koqFOtF76LsglAeLaQmweWmX0ecbPrzFYaX30kaQAqQ9Wk0PRe0+arRzWDWfUv3qX3y1decKUrBCuEC6WvVVwooWs+zX0cUBS8CROhazTjvXFAz36mhK0u+B3WCBlK+T2tIPOjLjlYgzYARw+X7/J6B3C798r2Hw/yXqCDcKLrq7WWUB33kv3buuG2G6LUamctdD8IsTBxi+nIjAvQITFqq4cPbbXAJGaAnWGuLOddQ9e/GhCOI4JjopRnnjOwARAQABiQEfBBgBAgAJBQJWzwb6AhsMAAoJEBOLMeB7CWH9TC8H/A6oreCxeiL8DPOWN29OaQ5sEw7Dg7bnLSZLu8aREgwfCiFSv0numOABjn/G89Y5M6NiEXFZZhUa+SXOALiBLUy98O84lyp9hlP9qGbWRgBXwe5vOAJERqtoUwR5bygpAw5Nc4y3wddPC4vH7upJ8ftU/eEFtPdI0cKrrAZDFdhXFp3RxdCC6fD62wbofE0mo1Ea1iD3xqVh2t7jfWN1RhMV308htHRGkkmWcEbbvHqugwL6dWZEvQmLYi6/7tQyA1KdG4AZksBP/MBi3t2hthRqQx1v52JwdCaZNuItuEe5rWXhfvoGxPoqYZt9ZPjna6yJfcfJwPbMfjNwX2LR4p4="
export FL_GPG_BASE642="mQENBFkSyx4BCACq/8XFcF+NTpJKfoo8F6YyR8RQXww6kCV47zN78Dt7aCh43WSYLRUBRt1tW5MRT8R60pwCsGvKnFiNS2Vqe4T1IW4mDnFMZIZJXdNVwKUqVBPL/jzkIDnQ9NXtuPNH0qET6VhYnb9aykLo/MiBmx6q+4MvYd/qwiN8kstRifRIxjjZx6wsg+muY6yx9fZKxlgvhc3nsrl3oyDo7/+V+b3heYLtMCQFwlHRKz3Yf2X9H0aUSbDYcgTy6w3q94HVNCpJSqeiR+kBG175BQYKR2l7WYdaVPFf5LMEvAJh0SGnqu77X+8TYYRQiiBB5fYjGOeHfOh6uH5GAJRQymVIJwy/ABEBAAG0KkZsYXRwYWsgKFRlc3Qga2V5IDIpIDxmbGF0cGFrQGZsYXRwYWsub3JnPokBOAQTAQIAIgUCWRLLHgIbAwYLCQgHAwIGFQgCCQoLBBYCAwECHgECF4AACgkQdZ9f0LIxTvyeUQf/euAZpipXBkGWxeW4G10r1QRi2tZAWNeLpy8SB17eo9E6yB61SdH80jALborVs/plnZzKcFf+nLvjCn51FLMh6QPL3S+079WHsed//qtUWfbJ85hLevfCMTZMLktUmqwwUh238WW/gKtbUjYOqr1IZSMBoMiQtc0iOVBP7HUdhYigxTKvs/MBEGHANeQkY07ZnX9oFXElOo+EIPAHScwEOSwEVrXUVHpQODzIfjOoPUHWAZtM1yJT+iWmVHe4HtU8CyBnPyUcnTmTWKr92QmgfWkb1T7ugT5gXt/6ZlYAaZGnr9yNuSk3MMhDMOyldtJBM5Zl8eScE9KBf7pRJoxnMLkBDQRZEsseAQgAvA29IyiJpB+jUHj3MOyVyTBOmvLme+0Ndhpt/mTh+swchJUvzb0IzQS9Le5yVAvn+ppAtDCMb+bV4Xh5zrbiH0Hu0qwK4Qk+KcIKRE8ImDiUM8NFE2SZoomZSsgZ1NBWbAdEyVpkBfrt3Dd8FssMrwPF6kqo02TZr7Pxng+BEHUZT6jPCxueqyXyv2cLbQMe1H0U7klsxPmnnIYUqdwOmPxUspVEYP9oJb5y123mx0yj5JuYdZMjWbP3cRLox1RKIlFWgQqOn2yJiEoWzpqdbtb7sE3ggnbZKJED0ZxUZIakjnyMhX+GAEA8ZMZ6+HfDt1iHV8qHcYiLW5A3AQTxZwARAQABiQEfBBgBAgAJBQJZEsseAhsMAAoJEHWfX9CyMU78Ns4IAJRQ5UJ9KkeZClHm1EjYlgsAq1UJr9wgbyBFKTEkGZ/CAvVmgg+BUXcN/SPAkELbEAOJZTyv8C5cuJC49iFHOxUbRZXZ5eN2SvhZzl+5gep2uHwVLdqRIxFDTHbLWnmtHxPeU7IRA9u86q3wV1N0pD7kreNN7BWKY3/tI33hY2/XVVFy0MN5sutPn+lVK66MqAHqtode5xqqz9Z8LmS7LlqokQkAytcGd6Xqsx99NTk8kk3bnk9HWsAvDO8tRZroeseKeRNmbhGvCNUxPSB6bpYBJLvQtjA9ZVv6sNm0E+SuiXKizZkBGO5AH50pDoy0+MCGoOhwwXeY5+1kZAOzkMI="

make_oci_signature () {
    DIGEST="$1"
    REFERENCE="$2"
    GPGARGS="${3:-${FL_GPGCMDARGS}}"

    gpg ${GPGARGS} --sign - <<EOF
{
    "critical": {
        "type": "atomic container signature",
        "image": {
            "docker-manifest-digest": "$DIGEST"
        },
        "identity": {
            "docker-reference": "$REFERENCE"
        }
    },
    "optional": {}
}
EOF
}

make_runtime () {
    REPONAME="$1"
    COLLECTION_ID="$2"
    BRANCH="$3"
    GPGARGS="$4"

    RUNTIME_REF="runtime/org.test.Platform/$(flatpak --default-arch)/${BRANCH}"
    if [ ! -z "${SRC_RUNTIME_REPO:-}" ]; then
        RUNTIME_REPO=repos/${SRC_RUNTIME_REPO}
    elif [ -f ${test_builddir}/runtime-repo/refs/heads/${RUNTIME_REF} ]; then
        RUNTIME_REPO=${test_builddir}/runtime-repo
    else
        RUNTIME_REPO=${TEST_DATA_DIR}/runtime-repo
        (
            flock -s 200
            if [ ! -f "${RUNTIME_REPO}/refs/heads/${RUNTIME_REF}" ]; then
                $(dirname $0)/make-test-runtime.sh ${RUNTIME_REPO} org.test.Platform ${BRANCH} "" "" > /dev/null
            fi
        ) 200>${TEST_DATA_DIR}/runtime-repo-lock
    fi

    if [ ! -d repos/${REPONAME} ]; then
        if [ "x${COLLECTION_ID}" != "x" ]; then
            collection_args=--collection-id=${COLLECTION_ID}
        else
            collection_args=
        fi
        mkdir -p repos
        ostree --repo=repos/${REPONAME} init --mode=archive-z2 ${collection_args} >&2
    fi

    flatpak build-commit-from --disable-fsync --no-update-summary --src-repo=${RUNTIME_REPO} --force ${GPGARGS} ${EXPORT_ARGS-}  repos/${REPONAME}  ${RUNTIME_REF} >&2
}

httpd () {
    if [ $# -eq 0 ] ; then
        set web-server.py repos
    fi

    COMMAND=$1
    shift

    rm -f httpd-pipe
    mkfifo httpd-pipe
    PYTHONUNBUFFERED=1 $(dirname $0)/$COMMAND "$@" 3> httpd-pipe 2>&1 | tee -a httpd-log >&2 &
    read < httpd-pipe
}

httpd_clear_log () {
    truncate -s 0 httpd-log
}

setup_repo_no_add () {
    REPONAME=${1:-test}
    if [ x${USE_COLLECTIONS_IN_SERVER-} == xyes ] ; then
        COLLECTION_ID=${2:-org.test.Collection.${REPONAME}}
    else
        COLLECTION_ID=
    fi
    BRANCH=${3:-master}

    make_runtime "${REPONAME}" "${COLLECTION_ID}" "${BRANCH}" "${GPGARGS:-${FL_GPGARGS}}"
    GPGARGS="${GPGARGS:-${FL_GPGARGS}}" $(dirname $0)/make-test-app.sh repos/${REPONAME} "" "${BRANCH}" "${COLLECTION_ID}" > /dev/null
    update_repo $REPONAME "${COLLECTION_ID}"
    if [ $REPONAME == "test" ]; then
        httpd
    fi
}

setup_repo () {
    REPONAME=${1:-test}
    COLLECTION_ID=${2:-org.test.Collection.${REPONAME}}

    setup_repo_no_add "$@"

    port=$(cat httpd-port)
    if [ x${GPGPUBKEY:-${FL_GPG_HOMEDIR}/pubring.gpg} != x ]; then
        import_args=--gpg-import=${GPGPUBKEY:-${FL_GPG_HOMEDIR}/pubring.gpg}
    else
        import_args=
    fi
    if [ x${USE_COLLECTIONS_IN_CLIENT-} == xyes ] ; then
        collection_args=--collection-id=${COLLECTION_ID}
    else
        collection_args=
    fi

    flatpak remote-add ${U} ${collection_args} ${import_args} ${REPONAME}-repo "http://127.0.0.1:${port}/$REPONAME" >&2
}

setup_empty_repo () {
    REPONAME=${1:-test}
    COLLECTION_ID=${2:-org.test.Collection.${REPONAME}}

    if [ x${USE_COLLECTIONS_IN_SERVER-} == xyes ] ; then
        COLLECTION_ID=${2:-org.test.Collection.${REPONAME}}
    else
        COLLECTION_ID=
    fi

    mkdir -p repos
    ostree --repo=repos/${REPONAME} init --mode=archive-z2 >&2
    update_repo $REPONAME "${COLLECTION_ID}"
    if [ $REPONAME == "test" ]; then
        httpd
    fi

    port=$(cat httpd-port)
    if [ x${GPGPUBKEY:-${FL_GPG_HOMEDIR}/pubring.gpg} != x ]; then
        import_args=--gpg-import=${GPGPUBKEY:-${FL_GPG_HOMEDIR}/pubring.gpg}
    else
        import_args=
    fi
    if [ x${USE_COLLECTIONS_IN_CLIENT-} == xyes ] ; then
        collection_args=--collection-id=${COLLECTION_ID}
    else
        collection_args=
    fi

    flatpak remote-add ${U} ${collection_args} ${import_args} ${REPONAME}-repo "http://127.0.0.1:${port}/$REPONAME" >&2
}

update_repo () {
    REPONAME=${1:-test}
    COLLECTION_ID=${2:-org.test.Collection.${REPONAME}}

    if [ x${USE_COLLECTIONS_IN_SERVER-} == xyes ] ; then
        collection_args=--collection-id=${COLLECTION_ID}
    else
        collection_args=
    fi

    ${FLATPAK} build-update-repo ${BUILD_UPDATE_REPO_FLAGS-} ${collection_args} ${GPGARGS:-${FL_GPGARGS}} ${UPDATE_REPO_ARGS-} repos/${REPONAME} >&2
    if [ x${SUMMARY_FORMAT-} == xold ] ; then
        assert_not_has_file repos/${REPONAME}/summary.idx
    else
        assert_has_file repos/${REPONAME}/summary.idx
    fi
}

make_updated_app () {
    REPONAME=${1:-test}
    if [ x${USE_COLLECTIONS_IN_SERVER-} == xyes ] ; then
        COLLECTION_ID=${2:-org.test.Collection.${REPONAME}}
    else
        COLLECTION_ID=""
    fi
    BRANCH=${3:-master}
    TEXT=${4:-UPDATED}
    APP_ID=${5:-""}
    RUNTIME_BRANCH=${6:-$BRANCH}

    RUNTIME_BRANCH=$RUNTIME_BRANCH GPGARGS="${GPGARGS:-${FL_GPGARGS}}" $(dirname $0)/make-test-app.sh repos/${REPONAME} "${APP_ID}" "${BRANCH}" "${COLLECTION_ID}" "${TEXT}" > /dev/null
    update_repo $REPONAME "${COLLECTION_ID}"
}

make_updated_runtime () {
    REPONAME=${1:-test}
    if [ x${USE_COLLECTIONS_IN_SERVER-} == xyes ] ; then
        COLLECTION_ID=${2:-org.test.Collection.${REPONAME}}
    else
        COLLECTION_ID=""
    fi
    BRANCH=${3:-master}
    TEXT=${4:-UPDATED}

    GPGARGS="${GPGARGS:-${FL_GPGARGS}}" $(dirname $0)/make-test-runtime.sh repos/${REPONAME} org.test.Platform "${BRANCH}" "${COLLECTION_ID}" "${TEXT}" > /dev/null
    update_repo $REPONAME "${COLLECTION_ID}"
}

setup_sdk_repo () {
    REPONAME=${1:-test}
    if [ x${USE_COLLECTIONS_IN_SERVER-} == xyes ] ; then
        COLLECTION_ID=${2:-org.test.Collection.${REPONAME}}
    else
        COLLECTION_ID=""
    fi
    BRANCH=${3:-master}

    GPGARGS="${GPGARGS:-${FL_GPGARGS}}" . $(dirname $0)/make-test-runtime.sh repos/${REPONAME} org.test.Sdk "${BRANCH}" "${COLLECTION_ID}" "" make mkdir cp touch > /dev/null
    update_repo $REPONAME "${COLLECTION_ID}"
}

install_repo () {
    REPONAME=${1:-test}
    BRANCH=${2:-master}
    ${FLATPAK} ${U} install -y ${REPONAME}-repo org.test.Platform ${BRANCH} >&2
    ${FLATPAK} ${U} install -y ${REPONAME}-repo org.test.Hello ${BRANCH} >&2
}

install_sdk_repo () {
    REPONAME=${1:-test}
    BRANCH=${2:-master}
    ${FLATPAK} ${U} install -y ${REPONAME}-repo org.test.Sdk ${BRANCH} >&2
}

run () {
    ${CMD_PREFIX} flatpak run "$@"

}

run_with_sandboxed_bus () {
    BUSSOCK=$(mktemp ${test_tmpdir}/bus.XXXXXX)
    rm -rf ${BUSSOCK}
    run --command=socat --filesystem=${test_tmpdir} org.test.Hello unix-listen:${BUSSOCK} unix-connect:/run/user/`id -u`/bus &
    while [ ! -e ${BUSSOCK} ]; do sleep 1; done
    DBUS_SESSION_BUS_ADDRESS="unix:path=${BUSSOCK}" "$@"
}

run_sh () {
    ID=${1:-org.test.Hello}
    shift
    ${CMD_PREFIX} flatpak run --command=bash ${ARGS-} ${ID} -c "$*"
}

# true, false, or empty for indeterminate
_flatpak_bwrap_works=

if [ -z "${FLATPAK_BWRAP:-}" ]; then
    # running installed-tests: assume we know what we're doing
    _flatpak_bwrap_works=true
elif ! "$FLATPAK_BWRAP" --unshare-ipc --unshare-net --unshare-pid \
        --ro-bind / / /bin/true > bwrap-result 2>&1; then
    _flatpak_bwrap_works=false
else
    _flatpak_bwrap_works=true
fi

have_working_bwrap() {
    [[ "${_flatpak_bwrap_works}" == "true" ]]
    return $?
}

# Use to skip all of these tests
skip() {
    echo "1..0 # SKIP" "$@"
    exit 0
}

skip_without_bwrap () {
    if "${_flatpak_bwrap_works}"; then
        return 0
    else
        sed -e 's/^/# /' < bwrap-result
        skip "Cannot run bwrap"
    fi
}

skip_one_without_bwrap () {
    if "${_flatpak_bwrap_works}"; then
        return 1
    else
        echo "ok $* # SKIP Cannot run bwrap"
        return 0
    fi
}

skip_without_fuse () {
    "${FUSERMOUNT}" --version >/dev/null 2>&1 || skip "no fusermount"

    capsh --print | grep -q 'Bounding set.*[^a-z]cap_sys_admin' || \
        skip "No cap_sys_admin in bounding set, can't use FUSE"

    [ -w /dev/fuse ] || skip "no write access to /dev/fuse"
    [ -e /etc/mtab ] || skip "no /etc/mtab"
}

skip_revokefs_without_fuse () {
    if [ "x${USE_SYSTEMDIR-}" = xyes ] && [ "x${FLATPAK_DISABLE_REVOKEFS-}" != xyes ]; then
        skip_without_fuse
    fi
}

skip_without_p2p () {
    if [ x${USE_COLLECTIONS_IN_CLIENT-} == xyes ] ; then
        return 0
    else
        skip "No P2P support enabled"
    fi
}

# Usage: skip_without_ostree_version 2019 2
skip_without_ostree_version () {
    OSTREE_YEAR_VERSION=$(ostree --version | sed -n "s/^ Version: '\([0-9]\+\)\.[0-9]\+'$/\1/p")
    OSTREE_RELEASE_VERSION=$(ostree --version | sed -n "s/^ Version: '[0-9]\+\.\([0-9]\+\)'$/\1/p")
    if [ "$OSTREE_YEAR_VERSION" -gt "$1" ]; then
        return 0
    elif [ "$OSTREE_YEAR_VERSION" -eq "$1" ] && [ "$OSTREE_RELEASE_VERSION" -ge "$2" ]; then
        return 0
    else
        skip "OSTree version requirement $1.$2 not met"
    fi
}

skip_without_libsystemd () {
  ${FLATPAK} history > history-log 2>&1 || true
  if  grep -q 'history not available without libsystemd' history-log; then
      skip "no libsystemd available"
  fi
}

FLATPAK_SYSTEM_CERTS_D=$(pwd)/certs.d
export FLATPAK_SYSTEM_CERTS_D

sed s#@testdir@#${test_builddir}# ${test_srcdir}/session.conf.in > session.conf
dbus-daemon --fork --config-file=session.conf --print-address=3 --print-pid=4 \
    3> dbus-session-bus-address 4> dbus-session-bus-pid

DBUS_SESSION_BUS_ADDRESS="$(cat dbus-session-bus-address)"
export DBUS_SESSION_BUS_ADDRESS
DBUS_SESSION_BUS_PID="$(cat dbus-session-bus-pid)"

if ! /bin/kill -0 "$DBUS_SESSION_BUS_PID"; then
    assert_not_reached "Failed to start dbus-daemon"
fi

gdb_bt () {
    gdb -batch -ex "run" -ex "thread apply all bt" -ex "quit 1"  --args "$@"
}

commit_to_path () {
    COMMIT=$1
    EXT=$2
    echo "objects/$(echo $COMMIT | cut -b 1-2)/$(echo $COMMIT | cut -b 3-)".${EXT}
}

cleanup () {
    /bin/kill -9 $DBUS_SESSION_BUS_PID
    gpg-connect-agent --homedir "${FL_GPG_HOMEDIR}" killagent /bye >&2 || true
    "${FUSERMOUNT}" -u $XDG_RUNTIME_DIR/doc >&2 || :
    kill $(jobs -p) &> /dev/null || true
    if test -n "${TEST_SKIP_CLEANUP:-}"; then
        echo "# Skipping cleanup of ${TEST_DATA_DIR}"
    else
        rm -rf $TEST_DATA_DIR
    fi
}
trap cleanup EXIT

if test -n "${FLATPAK_TESTS_DEBUG:-}"; then
    set -x
fi

assert_semicolon_list_contains () {
    list="$1"
    member="$2"

    case ";$list;" in
        (*";$member;"*)
            ;;
        (*)
            assert_not_reached "\"$list\" should contain \"$member\""
            ;;
    esac
}

assert_not_semicolon_list_contains () {
    local list="$1"
    local member="$2"

    case ";$list;" in
        (*";$member;"*)
            assert_not_reached "\"$list\" should not contain \"$member\""
            ;;
    esac
}

===== ./tests/test-history.sh =====
#!/bin/bash
# Copyright (C) 2021 Matthew Leeds <mwleeds@protonmail.com>
# SPDX-License-Identifier: LGPL-2.0-or-later

set -euo pipefail

USE_SYSTEMDIR=yes

. $(dirname $0)/libtest.sh

skip_without_bwrap
skip_revokefs_without_fuse
skip_without_libsystemd

HISTORY_START_TIME=$(date +"%Y-%m-%d %H:%M:%S")
sleep 1

MESSAGE="Checking whether Flatpak can use the journal..."
if ! logger "${MESSAGE}"; then
    skip "Cannot write to Journal with logger"
fi

if ! journalctl --user --since="${HISTORY_START_TIME}" | grep -q "${MESSAGE}"; then
    skip "Cannot read back from Journal with journalctl"
fi

echo "1..1"

mkdir -p ${TEST_DATA_DIR}/system-history-installation
mkdir -p ${FLATPAK_CONFIG_DIR}/installations.d
cat << EOF > ${FLATPAK_CONFIG_DIR}/installations.d/history-installation.conf
[Installation "history-installation"]
Path=${TEST_DATA_DIR}/system-history-installation
EOF

# setup repo and install from it
setup_repo_no_add
port=$(cat httpd-port)
${FLATPAK} --installation=history-installation remote-add \
    --gpg-import=${FL_GPG_HOMEDIR}/pubring.gpg test-repo "http://127.0.0.1:${port}/test" >&2
${FLATPAK} --installation=history-installation install -y test-repo org.test.Hello master >&2

# appstream update shouldn't show up in history
${FLATPAK} ${U} --appstream update test-repo >&2

# update, uninstall, and remote-delete should show up
EXPORT_ARGS="" make_updated_app
${FLATPAK} --installation=history-installation update -y org.test.Hello >&2
${FLATPAK} --installation=history-installation uninstall -y org.test.Platform org.test.Hello >&2
${FLATPAK} --installation=history-installation remote-delete test-repo >&2

# need --since and --columns here to make the test idempotent
if ! ${FLATPAK} --installation=history-installation history --since="${HISTORY_START_TIME}" \
    --columns=change,application,branch,installation,remote > history-log 2>&1; then
    cat history-log >&2
    echo "Bail out! 'flatpak history' failed"
    exit 1
fi

diff history-log - >&2 << EOF
add remote			system (history-installation)	test-repo
deploy install	org.test.Hello.Locale	master	system (history-installation)	test-repo
deploy install	org.test.Platform	master	system (history-installation)	test-repo
deploy install	org.test.Hello	master	system (history-installation)	test-repo
deploy update	org.test.Hello.Locale	master	system (history-installation)	test-repo
deploy update	org.test.Hello	master	system (history-installation)	test-repo
uninstall	org.test.Hello	master	system (history-installation)
uninstall	org.test.Platform	master	system (history-installation)
uninstall	org.test.Hello.Locale	master	system (history-installation)
remove remote			system (history-installation)	test-repo
EOF

if ! ${FLATPAK} --installation=history-installation history --since="${HISTORY_START_TIME}" \
    --columns=change,application,branch,installation,remote --json > history-log 2>&1; then
    cat history-log >&2
    echo "Bail out! 'flatpak history' failed"
    exit 1
fi

diff history-log - >&2 << EOF
[
  {
    "change" : "add remote",
    "application" : "",
    "branch" : "",
    "installation" : "system (history-installation)",
    "remote" : "test-repo"
  },
  {
    "change" : "deploy install",
    "application" : "org.test.Hello.Locale",
    "branch" : "master",
    "installation" : "system (history-installation)",
    "remote" : "test-repo"
  },
  {
    "change" : "deploy install",
    "application" : "org.test.Platform",
    "branch" : "master",
    "installation" : "system (history-installation)",
    "remote" : "test-repo"
  },
  {
    "change" : "deploy install",
    "application" : "org.test.Hello",
    "branch" : "master",
    "installation" : "system (history-installation)",
    "remote" : "test-repo"
  },
  {
    "change" : "deploy update",
    "application" : "org.test.Hello.Locale",
    "branch" : "master",
    "installation" : "system (history-installation)",
    "remote" : "test-repo"
  },
  {
    "change" : "deploy update",
    "application" : "org.test.Hello",
    "branch" : "master",
    "installation" : "system (history-installation)",
    "remote" : "test-repo"
  },
  {
    "change" : "uninstall",
    "application" : "org.test.Hello",
    "branch" : "master",
    "installation" : "system (history-installation)",
    "remote" : ""
  },
  {
    "change" : "uninstall",
    "application" : "org.test.Platform",
    "branch" : "master",
    "installation" : "system (history-installation)",
    "remote" : ""
  },
  {
    "change" : "uninstall",
    "application" : "org.test.Hello.Locale",
    "branch" : "master",
    "installation" : "system (history-installation)",
    "remote" : ""
  },
  {
    "change" : "remove remote",
    "application" : "",
    "branch" : "",
    "installation" : "system (history-installation)",
    "remote" : "test-repo"
  }
]
EOF

rm -f ${FLATPAK_CONFIG_DIR}/installations.d/history-inst.conf
rm -rf ${TEST_DATA_DIR}/system-history-installation

ok "history looks correct"

===== ./tests/testapp.c =====
#include "config.h"

#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>

#include <glib.h>
#include "flatpak.h"
#include "flatpak-utils-private.h"
#include "flatpak-appdata-private.h"
#include "flatpak-builtins-utils.h"
#include "flatpak-run-private.h"
#include "flatpak-table-printer.h"
#include "flatpak-tty-utils-private.h"
#include "parse-datetime.h"

static void
test_fancy_output (void)
{
  if (!isatty (STDOUT_FILENO))
    g_assert_false (flatpak_fancy_output ()); // no tty
  else
    g_assert_true (flatpak_fancy_output ()); // a tty
  flatpak_enable_fancy_output ();
  g_assert_true (flatpak_fancy_output ());
  flatpak_disable_fancy_output ();
  g_assert_false (flatpak_fancy_output ());
}

static GString *g_print_buffer;

static void
my_print_func (const char *string)
{
  g_string_append (g_print_buffer, string);
}

static void
test_format_choices (void)
{
  GPrintFunc print_func;
  const char *choices[] = { "one", "two", "three", NULL };
  const char *many_choices[] = {
    "one", "two", "three", "four", "five", "six",
    "seven", "eight", "nine", "ten", "eleven",
    NULL
  };

  g_assert_null (g_print_buffer);
  g_print_buffer = g_string_new ("");
  print_func = g_set_print_handler (my_print_func);

  flatpak_format_choices (choices, "A prompt for %d choices:", 3);

  g_assert_cmpstr (g_print_buffer->str, ==,
                   "A prompt for 3 choices:\n\n"
                   "   1) one\n"
                   "   2) two\n"
                   "   3) three\n"
                   "\n");

  g_string_truncate (g_print_buffer, 0);

  flatpak_format_choices (many_choices, "A prompt for %d choices:", 11);
  g_assert_cmpstr (g_print_buffer->str, ==,
                   "A prompt for 11 choices:\n\n"
                   "   1) one\n"
                   "   2) two\n"
                   "   3) three\n"
                   "   4) four\n"
                   "   5) five\n"
                   "   6) six\n"
                   "   7) seven\n"
                   "   8) eight\n"
                   "   9) nine\n"
                   "  10) ten\n"
                   "  11) eleven\n"
                   "\n");

  g_string_truncate (g_print_buffer, 0);

  g_set_print_handler (print_func);
  g_string_free (g_print_buffer, TRUE);
  g_print_buffer = NULL;
}

static void
test_yes_no_prompt (void)
{
  GPrintFunc print_func;
  gboolean ret;

  g_assert_null (g_print_buffer);
  g_print_buffer = g_string_new ("");
  print_func = g_set_print_handler (my_print_func);

  /* not a tty, so flatpak_yes_no_prompt will auto-answer 'n' */
  ret = flatpak_yes_no_prompt (TRUE, "Prompt %d ?", 1);
  g_assert_false (ret);
  g_assert_cmpstr (g_print_buffer->str, ==, "Prompt 1 ? [Y/n]: n\n");
  g_string_truncate (g_print_buffer, 0);

  ret = flatpak_yes_no_prompt (FALSE, "Prompt %d ?", 2);
  g_assert_false (ret);
  g_assert_cmpstr (g_print_buffer->str, ==, "Prompt 2 ? [y/n]: n\n");

  g_set_print_handler (print_func);
  g_string_free (g_print_buffer, TRUE);
  g_print_buffer = NULL;
}

static void
test_number_prompt (void)
{
  GPrintFunc print_func;
  gboolean ret;

  g_assert_null (g_print_buffer);
  g_print_buffer = g_string_new ("");
  print_func = g_set_print_handler (my_print_func);

  /* not a tty, so flatpak_number_prompt will auto-answer '0' */
  ret = flatpak_number_prompt (TRUE, 0, 8, "Prompt %d ?", 1);
  g_assert_false (ret);
  g_assert_cmpstr (g_print_buffer->str, ==, "Prompt 1 ? [0-8]: 0\n");
  g_string_truncate (g_print_buffer, 0);

  ret = flatpak_number_prompt (FALSE, 1, 3, "Prompt %d ?", 2);
  g_assert_false (ret);
  g_assert_cmpstr (g_print_buffer->str, ==, "Prompt 2 ? [1-3]: 0\n");

  g_set_print_handler (print_func);
  g_string_free (g_print_buffer, TRUE);
  g_print_buffer = NULL;
}

static void
assert_numbers (int *num, ...)
{
  va_list args;
  int n;
  int i;

  g_assert_nonnull (num);

  va_start (args, num);
  for (i = 0; num[i]; i++)
    {
      n = va_arg (args, int);
      g_assert_true (n == num[i]);
    }

  n = va_arg (args, int);
  g_assert_true (n == 0);
  va_end (args);
}

static void
test_parse_numbers (void)
{
  g_autofree int *numbers = NULL;

  numbers = flatpak_parse_numbers ("", 0, 10);
  assert_numbers (numbers, 0);
  g_clear_pointer (&numbers, g_free);

  numbers = flatpak_parse_numbers ("1", 0, 10);
  assert_numbers (numbers, 1, 0);
  g_clear_pointer (&numbers, g_free);

  numbers = flatpak_parse_numbers ("1 3 2", 0, 10);
  assert_numbers (numbers, 1, 3, 2, 0);
  g_clear_pointer (&numbers, g_free);

  numbers = flatpak_parse_numbers ("1-3", 0, 10);
  assert_numbers (numbers, 1, 2, 3, 0);
  g_clear_pointer (&numbers, g_free);

  numbers = flatpak_parse_numbers ("1", 2, 4);
  g_assert_null (numbers);

  numbers = flatpak_parse_numbers ("2-6", 2, 4);
  g_assert_null (numbers);

  numbers = flatpak_parse_numbers ("1,2 2", 1, 4);
  assert_numbers (numbers, 1, 2, 0);
  g_clear_pointer (&numbers, g_free);

  numbers = flatpak_parse_numbers ("1-3,2-4", 1, 4);
  assert_numbers (numbers, 1, 2, 3, 4, 0);
  g_clear_pointer (&numbers, g_free);

  numbers = flatpak_parse_numbers ("-1", 1, 4);
  g_assert_null (numbers);
}

static void
test_looks_like_branch (void)
{
  g_assert_false (looks_like_branch ("abc/d"));
  g_assert_false (looks_like_branch ("ab.c.d"));
  g_assert_true (looks_like_branch ("master"));
  g_assert_true (looks_like_branch ("stable"));
  g_assert_true (looks_like_branch ("3.30"));
}

static void
test_columns (void)
{
  Column columns[] = {
    { "column1", "col1", "col1",       0, 0, 1, 1 },
    { "install", "install", "install", 0, 0, 0, 1 },
    { "helper", "helper", "helper",    0, 0, 1, 0 },
    { "column2", "col2", "col2",       0, 0, 0, 0 },
    { NULL, }
  };
  Column *cols;
  g_autofree char *help = NULL;
  g_autoptr(GError) error = NULL;
  const char *args[3];

  help = column_help (columns);
  g_assert_cmpstr (help, ==,
                   "Available columns:\n"
                   "  column1     col1\n"
                   "  install     install\n"
                   "  helper      helper\n"
                   "  column2     col2\n"
                   "  all         Show all columns\n"
                   "  help        Show available columns\n"
                   "\n"
                   "Append :s[tart], :m[iddle], :e[nd] or :f[ull] to change ellipsization\n");

  cols = handle_column_args (columns, FALSE, NULL, &error);
  g_assert_no_error (error);
  g_assert_cmpstr (cols[0].name, ==, "column1");
  g_assert_cmpstr (cols[1].name, ==, "install");
  g_assert_null (cols[2].name);
  g_free (cols);

  cols = handle_column_args (columns, TRUE, NULL, &error);
  g_assert_no_error (error);
  g_assert_cmpstr (cols[0].name, ==, "column1");
  g_assert_cmpstr (cols[1].name, ==, "install");
  g_assert_cmpstr (cols[2].name, ==, "helper");
  g_assert_null (cols[3].name);
  g_free (cols);

  args[0] = "all";
  args[1] = NULL;
  cols = handle_column_args (columns, FALSE, args, &error);
  g_assert_no_error (error);
  g_assert_cmpstr (cols[0].name, ==, "column1");
  g_assert_cmpstr (cols[1].name, ==, "install");
  g_assert_cmpstr (cols[2].name, ==, "helper");
  g_assert_null (cols[3].name);
  g_free (cols);

  args[0] = "column1,column2";
  args[1] = "helper";
  args[2] = NULL;
  cols = handle_column_args (columns, FALSE, args, &error);
  g_assert_no_error (error);
  g_assert_cmpstr (cols[0].name, ==, "column1");
  g_assert_cmpstr (cols[1].name, ==, "column2");
  g_assert_cmpstr (cols[2].name, ==, "helper");
  g_assert_null (cols[3].name);
  g_free (cols);

  args[0] = "column";
  args[1] = NULL;
  cols = handle_column_args (columns, FALSE, args, &error);
  g_assert_null (cols);
  g_assert_error (error, G_IO_ERROR, G_IO_ERROR_FAILED);
  g_clear_error (&error);

  args[0] = "app";
  args[1] = NULL;
  cols = handle_column_args (columns, FALSE, args, &error);
  g_assert_null (cols);
  g_assert_error (error, G_IO_ERROR, G_IO_ERROR_FAILED);
  g_clear_error (&error);
}

typedef struct
{
  const char          *in;
  int                  len;
  FlatpakEllipsizeMode mode;
  const char          *out;
} EllipsizeData;

static EllipsizeData ellipsize[] = {
  { "abcdefghijklmnopqrstuvwxyz", 10, FLATPAK_ELLIPSIZE_MODE_NONE,   "abcdefghijklmnopqrstuvwxyz" },
  { "abcdefghijklmnopqrstuvwxyz", 10, FLATPAK_ELLIPSIZE_MODE_END,    "abcdefghi…" },
  { "abcdefghijklmnopqrstuvwxyz", 10, FLATPAK_ELLIPSIZE_MODE_MIDDLE, "abcde…wxyz" },
  { "abcdefghijklmnopqrstuvwxyz", 10, FLATPAK_ELLIPSIZE_MODE_START,  "…rstuvwxyz" },
  { "ģ☢ab", 3, FLATPAK_ELLIPSIZE_MODE_START,  "…ab" },
  { "ģ☢ab", 3, FLATPAK_ELLIPSIZE_MODE_MIDDLE, "ģ…b" },
  { "ģ☢ab", 3, FLATPAK_ELLIPSIZE_MODE_END,    "ģ☢…" }
};

static void
test_string_ellipsize (void)
{
  gsize idx;

  for (idx = 0; idx < G_N_ELEMENTS (ellipsize); idx++)
    {
      EllipsizeData *data = &ellipsize[idx];
      g_autofree char *ret = NULL;

      ret = ellipsize_string_full (data->in, data->len, data->mode);
      g_assert_cmpstr (ret, ==, data->out);
    }
}

static void
test_table (void)
{
  GPrintFunc print_func;
  FlatpakTablePrinter *printer;

  g_assert_null (g_print_buffer);
  g_print_buffer = g_string_new ("");
  print_func = g_set_print_handler (my_print_func);
  flatpak_enable_fancy_output ();

  printer = flatpak_table_printer_new ();

  flatpak_table_printer_set_column_title (printer, 0, "Column1");
  flatpak_table_printer_set_column_title (printer, 1, "Column2");

  flatpak_table_printer_add_column (printer, "text1");
  flatpak_table_printer_add_column (printer, "text2");
  flatpak_table_printer_finish_row (printer);

  flatpak_table_printer_add_column (printer, "text3");
  flatpak_table_printer_add_column (printer, "text4");
  flatpak_table_printer_finish_row (printer);

  flatpak_table_printer_print (printer);
  g_assert_cmpstr (g_print_buffer->str, ==,
                   FLATPAK_ANSI_BOLD_ON
                   "Column1 Column2" FLATPAK_ANSI_BOLD_OFF "\n"
                   "text1   text2\n"
                   "text3   text4\n");
  g_string_truncate (g_print_buffer, 0);

  flatpak_table_printer_set_cell (printer, 0, 0, "newtext1");
  flatpak_table_printer_set_decimal_cell (printer, 0, 1, "0.123");
  flatpak_table_printer_set_decimal_cell (printer, 1, 1, "123.0");
  flatpak_table_printer_print (printer);
  g_assert_cmpstr (g_print_buffer->str, ==,
                   FLATPAK_ANSI_BOLD_ON
                   "Column1  Column2" FLATPAK_ANSI_BOLD_OFF "\n"
                   "newtext1   0.123\n"
                   "text3    123.0\n");
  g_string_truncate (g_print_buffer, 0);

  flatpak_table_printer_free (printer);

  flatpak_disable_fancy_output ();
  g_set_print_handler (print_func);
  g_string_free (g_print_buffer, TRUE);
  g_print_buffer = NULL;
}

static void
test_table_expand (void)
{
  GPrintFunc print_func;
  FlatpakTablePrinter *printer;
  int rows, cols;

  g_assert_null (g_print_buffer);
  g_print_buffer = g_string_new ("");
  print_func = g_set_print_handler (my_print_func);
  flatpak_enable_fancy_output ();

  printer = flatpak_table_printer_new ();

  flatpak_table_printer_set_column_title (printer, 0, "Column1");
  flatpak_table_printer_set_column_title (printer, 1, "Column2");
  flatpak_table_printer_set_column_title (printer, 2, "Column3");

  flatpak_table_printer_add_column (printer, "text1");
  flatpak_table_printer_add_column (printer, "text2");
  flatpak_table_printer_add_column (printer, "text3");
  flatpak_table_printer_finish_row (printer);
  flatpak_table_printer_add_span (printer, "012345678901234567890234567890123456789");
  flatpak_table_printer_finish_row (printer);

  flatpak_table_printer_set_column_expand (printer, 0, TRUE);

  flatpak_table_printer_print_full (printer, 0, 40, &rows, &cols);

  g_assert_cmpint (rows, ==, 3);
  g_assert_cmpint (cols, ==, 34);
  g_assert_cmpstr (g_print_buffer->str, ==,
                   FLATPAK_ANSI_BOLD_ON
                   "Column1            Column2 Column3" FLATPAK_ANSI_BOLD_OFF "\n"
                   "text1              text2   text3" "\n"
                   "012345678901234567890234567890123456789");
  g_string_truncate (g_print_buffer, 0);

  flatpak_table_printer_set_column_expand (printer, 2, TRUE);

  flatpak_table_printer_print_full (printer, 0, 40, &rows, &cols);

  g_assert_cmpint (rows, ==, 3);
  g_assert_cmpint (cols, ==, 34);
  g_assert_cmpstr (g_print_buffer->str, ==,
                   FLATPAK_ANSI_BOLD_ON
                   "Column1       Column2 Column3" FLATPAK_ANSI_BOLD_OFF "\n"
                   "text1         text2   text3" "\n"
                   "012345678901234567890234567890123456789");
  g_string_truncate (g_print_buffer, 0);

  flatpak_table_printer_free (printer);

  flatpak_disable_fancy_output ();
  g_set_print_handler (print_func);
  g_string_free (g_print_buffer, TRUE);
  g_print_buffer = NULL;
}

static void
test_table_shrink (void)
{
  GPrintFunc print_func;
  FlatpakTablePrinter *printer;
  int rows, cols;

  g_assert_null (g_print_buffer);
  g_print_buffer = g_string_new ("");
  print_func = g_set_print_handler (my_print_func);
  flatpak_enable_fancy_output ();

  printer = flatpak_table_printer_new ();

  flatpak_table_printer_set_column_title (printer, 0, "Column1");
  flatpak_table_printer_set_column_title (printer, 1, "Column2");
  flatpak_table_printer_set_column_title (printer, 2, "Column3");

  flatpak_table_printer_add_column (printer, "a very long text");
  flatpak_table_printer_add_column (printer, "text2");
  flatpak_table_printer_add_column (printer, "long text too");
  flatpak_table_printer_finish_row (printer);

  flatpak_table_printer_add_column (printer, "short");
  flatpak_table_printer_add_column (printer, "short");
  flatpak_table_printer_add_column (printer, "short");
  flatpak_table_printer_finish_row (printer);

  flatpak_table_printer_add_span (printer, "0123456789012345678902345");
  flatpak_table_printer_finish_row (printer);

  flatpak_table_printer_set_column_ellipsize (printer, 0, FLATPAK_ELLIPSIZE_MODE_END);

  flatpak_table_printer_print_full (printer, 0, 25, &rows, &cols);

  g_assert_cmpint (rows, ==, 4);
  g_assert_cmpint (cols, ==, 25);
  g_assert_cmpstr (g_print_buffer->str, ==,
                   FLATPAK_ANSI_BOLD_ON
                   "Co… Column2 Column3" FLATPAK_ANSI_BOLD_OFF "\n"
                   "a … text2   long text too" "\n"
                   "sh… short   short" "\n"
                   "0123456789012345678902345");
  g_string_truncate (g_print_buffer, 0);

  flatpak_table_printer_set_column_ellipsize (printer, 2, FLATPAK_ELLIPSIZE_MODE_MIDDLE);

  flatpak_table_printer_print_full (printer, 0, 25, &rows, &cols);

  g_assert_cmpint (rows, ==, 4);
  g_assert_cmpint (cols, ==, 25);
  g_assert_cmpstr (g_print_buffer->str, ==,
                   FLATPAK_ANSI_BOLD_ON
                   "Column1  Column2 Column3" FLATPAK_ANSI_BOLD_OFF "\n"
                   "a very … text2   long…too" "\n"
                   "short    short   short" "\n"
                                                                                                                         "0123456789012345678902345");
  g_string_truncate (g_print_buffer, 0);

  flatpak_table_printer_free (printer);

  flatpak_disable_fancy_output ();
  g_set_print_handler (print_func);
  g_string_free (g_print_buffer, TRUE);
  g_print_buffer = NULL;
}

static void
test_table_shrink_more (void)
{
  GPrintFunc print_func;
  FlatpakTablePrinter *printer;
  int rows, cols;

  g_assert_null (g_print_buffer);
  g_print_buffer = g_string_new ("");
  print_func = g_set_print_handler (my_print_func);
  flatpak_enable_fancy_output ();

  printer = flatpak_table_printer_new ();

  flatpak_table_printer_set_column_title (printer, 0, "Column1");
  flatpak_table_printer_set_column_title (printer, 1, "Column2");
  flatpak_table_printer_set_column_title (printer, 2, "Column3");

  flatpak_table_printer_add_column (printer, "a very long text");
  flatpak_table_printer_add_column (printer, "midsize text");
  flatpak_table_printer_add_column (printer, "another very long text");
  flatpak_table_printer_finish_row (printer);

  flatpak_table_printer_set_column_ellipsize (printer, 1, FLATPAK_ELLIPSIZE_MODE_END);

  flatpak_table_printer_print_full (printer, 0, 25, &rows, &cols);

  g_assert_cmpint (rows, ==, 4);
  g_assert_cmpint (cols, ==, 40);
  g_assert_cmpstr (g_print_buffer->str, ==,
                   FLATPAK_ANSI_BOLD_ON
                   "Column1          … Column3" FLATPAK_ANSI_BOLD_OFF "\n"
                   "a very long text … another very long text");

  flatpak_table_printer_free (printer);

  flatpak_disable_fancy_output ();
  g_set_print_handler (print_func);
  g_string_free (g_print_buffer, TRUE);
  g_print_buffer = NULL;
}

static void
test_parse_datetime (void)
{
  struct timespec ts;
  struct timespec now;
  gboolean ret;
  g_autoptr(GDateTime) dt = NULL;
  GTimeVal tv;

  clock_gettime (CLOCK_REALTIME, &now);
  ret = parse_datetime (&ts, "NOW", NULL);
  g_assert_true (ret);

  g_assert_true (ts.tv_sec == now.tv_sec); // close enough

  ret = parse_datetime (&ts, "2018-10-29 00:19:07 +0000", NULL);
  g_assert_true (ret);
  dt = g_date_time_new_utc (2018, 10, 29, 0, 19, 7);
  g_date_time_to_timeval (dt, &tv);

  g_assert_true (tv.tv_sec == ts.tv_sec &&
                 tv.tv_usec == ts.tv_nsec / 1000);

  ret = parse_datetime (&ts, "nonsense", NULL);
  g_assert_false (ret);
}

int
main (int argc, char *argv[])
{
  int res;

  g_test_init (&argc, &argv, NULL);

  g_test_add_func ("/app/columns", test_columns);
  g_test_add_func ("/app/fancy-output", test_fancy_output);
  g_test_add_func ("/app/format-choices", test_format_choices);
  g_test_add_func ("/app/looks-like-branch", test_looks_like_branch);
  g_test_add_func ("/app/number-prompt", test_number_prompt);
  g_test_add_func ("/app/parse-datetime", test_parse_datetime);
  g_test_add_func ("/app/parse-numbers", test_parse_numbers);
  g_test_add_func ("/app/string-ellipsize", test_string_ellipsize);
  g_test_add_func ("/app/table", test_table);
  g_test_add_func ("/app/table-expand", test_table_expand);
  g_test_add_func ("/app/table-shrink", test_table_shrink);
  g_test_add_func ("/app/table-shrink-more", test_table_shrink_more);
  g_test_add_func ("/app/yes-no-prompt", test_yes_no_prompt);

  res = g_test_run ();

  return res;
}

===== ./tests/test.filter =====
deny *
allow org.test.Platform

===== ./tests/session.conf.in =====
<!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-Bus Bus Configuration 1.0//EN"
 "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
<busconfig>
  <!-- Our well-known bus type, don't change this -->
  <type>session</type>

  <!-- If we fork, keep the user's original umask to avoid affecting
       the behavior of child processes. -->
  <keep_umask/>

  <listen>unix:tmpdir=/tmp</listen>

  <servicedir>@testdir@/services</servicedir>

  <!-- disabled for now; this causes gnome-keyring to be spawned, which can
       interfere with user's real keyrings, as well as causing long delays
       during D-BUS activation -->
  <!-- <standard_session_servicedirs /> -->

  <policy context="default">
    <!-- Allow everything to be sent -->
    <allow send_destination="*" eavesdrop="true"/>
    <!-- Allow everything to be received -->
    <allow eavesdrop="true"/>
    <!-- Allow anyone to own anything -->
    <allow own="*"/>
  </policy>

  <include if_selinux_enabled="yes" selinux_root_relative="yes">contexts/dbus_contexts</include>

  <!-- For the session bus, override the default relatively-low limits 
       with essentially infinite limits, since the bus is just running 
       as the user anyway, using up bus resources is not something we need 
       to worry about. In some cases, we do set the limits lower than 
       "all available memory" if exceeding the limit is almost certainly a bug, 
       having the bus enforce a limit is nicer than a huge memory leak. But the 
       intent is that these limits should never be hit. -->

  <!-- the memory limits are 1G instead of say 4G because they can't exceed 32-bit signed int max -->
  <limit name="max_incoming_bytes">1000000000</limit>
  <limit name="max_incoming_unix_fds">250000000</limit>
  <limit name="max_outgoing_bytes">1000000000</limit>
  <limit name="max_outgoing_unix_fds">250000000</limit>
  <limit name="max_message_size">1000000000</limit>
  <limit name="max_message_unix_fds">4096</limit>
  <limit name="service_start_timeout">120000</limit>  
  <limit name="auth_timeout">240000</limit>
  <limit name="max_completed_connections">100000</limit>  
  <limit name="max_incomplete_connections">10000</limit>
  <limit name="max_connections_per_user">100000</limit>
  <limit name="max_pending_service_starts">10000</limit>
  <limit name="max_names_per_connection">50000</limit>
  <limit name="max_match_rules_per_connection">50000</limit>
  <limit name="max_replies_per_connection">50000</limit>

</busconfig>

===== ./tests/meson.build =====
# Copyright 2022 Collabora Ltd.
# SPDX-License-Identifier: LGPL-2.1-or-later

installed_testdir = get_option('prefix') / get_option('libexecdir') / 'installed-tests' / 'Flatpak'
installed_tests_metadir = get_option('prefix') / get_option('datadir') / 'installed-tests' / 'Flatpak'

if get_option('system_bubblewrap') == ''
  env_flatpak_bwrap = project_build_root / 'subprojects' / 'bubblewrap' / 'flatpak-bwrap'
else
  env_flatpak_bwrap = get_option('system_bubblewrap')
endif

if get_option('system_dbus_proxy') == ''
  env_flatpak_dbusproxy = project_build_root / 'subprojects' / 'dbus-proxy' / 'flatpak-dbus-proxy'
else
  env_flatpak_dbusproxy = get_option('system_dbus_proxy')
endif

tests_environment = {
  'FLATPAK_CONFIG_DIR' : '/dev/null',
  'FLATPAK_DATA_DIR' : '/dev/null',
  'FLATPAK_PORTAL' : project_build_root / 'portal' / 'flatpak-portal',
  'FLATPAK_REVOKEFS_FUSE' : project_build_root / 'revokefs' / 'revokefs-fuse',
  'FLATPAK_TESTS_DEBUG' : '1',
  'FLATPAK_TESTS_STRICT_TAP' : '1',
  'FLATPAK_TRIGGERSDIR' : project_source_root / 'triggers',
  'FLATPAK_VALIDATE_ICON' : project_build_root / 'icon-validator' / 'flatpak-validate-icon',
  'FUSERMOUNT' : fusermount,
  'G_TEST_BUILDDIR' : meson.current_build_dir(),
  'G_TEST_SRCDIR' : meson.current_source_dir(),
  'FLATPAK_BWRAP' : env_flatpak_bwrap,
  'FLATPAK_DBUSPROXY' : env_flatpak_dbusproxy,
}

tests_environment_prepend = {
  'GI_TYPELIB_PATH' : project_build_root / 'common',
  'LD_LIBRARY_PATH' : project_build_root / 'common',
  'PATH' : project_build_root / 'app',
}

lsan_options = 'log_threads=1:suppressions=' + meson.current_source_dir() / 'flatpak-asan.supp'

if get_option('installed_tests')
  configure_file(
    input : 'installed-tests.sh.in',
    output : 'installed-tests.sh',
    configuration : {
      'FUSERMOUNT' : fusermount,
      'FLATPAK_TRIGGERSDIR' : get_option('prefix') / get_option('datadir') / 'flatpak' / 'triggers',
    },
    install_dir : installed_testdir,
  )
endif

# Explicitly doing a find_program() for this avoids lots of output with
# older Meson versions
tap_test = find_program(
  files(project_source_root / 'buildutil/tap-test'),
)

if can_run_host_binaries
  runtime_repo = custom_target(
    'runtime-repo',
    build_by_default : false,
    command : [
      files('make-runtime-repos'),
      project_build_root / 'app',
      files('make-test-runtime.sh'),
      project_build_root / 'tests/runtime-repo',
      '@OUTPUT@',
    ],
    depends : [flatpak_exe],
    output : 'runtime-repo.stamp',
  )
endif

libtestlib = static_library(
  'testlib',
  'testlib.c',
  include_directories : [common_include_directories],
  dependencies : [
    base_deps,
    libglnx_dep,
  ],
  install : false,
)
libtestlib_dep = declare_dependency(
  dependencies : [
    base_deps,
    libglnx_dep,
  ],
  include_directories : [common_include_directories],
  link_with : libtestlib,
)

c_tests = [
  ['testapp', {
    'extra_dependencies' : [
      libflatpak_app_dep,
    ],
  }],
  ['testcommon', {}],
  ['testlibrary', {
    'dependencies' : [
      base_deps,
      fuse_dep,
      libflatpak_dep,
      libglnx_dep,
      libostree_dep,
    ],
    'extra_sources' : [
      'can-use-fuse.c',
      'testlib.c',
    ],
    'timeout' : 150,
  }],
  ['test-context', {}],
  ['test-exports', {}],
  ['test-instance', {
    'extra_dependencies' : [
      libglnx_testlib_dep,
    ],
  }],
  ['test-locale-utils', {}],
  ['test-portal', {
    'extra_sources' : [
      portal_gdbus[0],
      portal_gdbus[1],
    ],
  }],
]

foreach testcase : c_tests
  name = testcase[0]
  options = testcase[1]

  exe = executable(
    name,
    dependencies : options.get('dependencies', [
      base_deps,
      appstream_dep,
      json_glib_dep,
      libflatpak_common_dep,
      libflatpak_common_base_dep,
      libglnx_dep,
      libostree_dep,
      libtestlib_dep,
    ] + options.get('extra_dependencies', [])),
    sources : [name + '.c'] + options.get('extra_sources', []),
    install : get_option('installed_tests'),
    install_dir : installed_testdir,
  )

  if get_option('installed_tests')
    configure_file(
      input : 'tap.test.in',
      output : name + '.test',
      configuration : {
        'basename' : name,
        'installed_testdir' : installed_testdir,
        'wrapper' : '',
      },
      install_dir : installed_tests_metadir,
    )
  endif

  test_env = environment(tests_environment)
  foreach k, v: tests_environment_prepend
    test_env.prepend(k, v)
  endforeach

  lsan_log_path = ':log_path=' + meson.current_build_dir() / \
                  'asan_' + name.underscorify() + '.log'
  test_env.set('LSAN_OPTIONS', lsan_options + lsan_log_path)

  if can_run_host_binaries
    test(
      name,
      tap_test,
      args : [exe],
      depends : runtime_repo,
      env : test_env,
      protocol : 'tap',
      timeout : options.get('timeout', 30),
    )
  endif
endforeach

executable(
  'hold-lock',
  'hold-lock.c',
  dependencies : [
    base_deps,
    libglnx_dep,
  ],
  include_directories : [common_include_directories],
  install : get_option('installed_tests'),
  install_dir : installed_testdir,
)

executable(
  'httpcache',
  'httpcache.c',
  dependencies : [
    base_deps,
    json_glib_dep,
    libflatpak_common_dep,
    libflatpak_common_base_dep,
    libglnx_dep,
    libostree_dep,
  ],
  include_directories : [common_include_directories],
  install : get_option('installed_tests'),
  install_dir : installed_testdir,
)

executable(
  'mock-flatpak',
  'mock-flatpak.c',
  dependencies : [
    base_deps,
    appstream_dep,
    json_glib_dep,
    libflatpak_app_dep,
    libflatpak_common_dep,
    libflatpak_common_base_dep,
    libtestlib_dep,
    libglnx_dep,
    libostree_dep,
  ],
  install : get_option('installed_tests'),
  install_dir : installed_testdir,
)

executable(
  'test-update-portal',
  sources : [
    'test-update-portal.c',
  ] + portal_gdbus,
  dependencies : base_deps,
  include_directories : [common_include_directories],
  install : get_option('installed_tests'),
  install_dir : installed_testdir,
)

executable(
  'test-portal-impl',
  'test-portal-impl.c',
  dependencies : base_deps,
  include_directories : [common_include_directories],
  install : get_option('installed_tests'),
  install_dir : installed_testdir,
)

executable(
  'test-authenticator',
  'test-authenticator.c',
  dependencies : [
    base_deps,
    libflatpak_common_dep,
    libflatpak_common_base_dep,
    libglnx_dep,
  ],
  install : get_option('installed_tests'),
  install_dir : installed_testdir,
)

executable(
  'try-syscall',
  'try-syscall.c',
  include_directories : [common_include_directories],
  install : get_option('installed_tests'),
  install_dir : installed_testdir,
  override_options: ['b_sanitize=none'],
)

executable(
  'list-unused',
  'list-unused.c',
  dependencies : [
    base_deps,
    libflatpak_common_dep,
    libflatpak_common_base_dep,
    libglnx_dep,
    libostree_dep,
  ],
  include_directories : [common_include_directories],
  install : get_option('installed_tests'),
  install_dir : installed_testdir,
)

if cc.links('#include <stdio.h>\nint main(void) { printf("test"); return 0; }',
            args: ['-static'],
            name: 'static libc')
  executable(
    'apply-extra-static',
    'apply-extra-static.c',
    install : get_option('installed_tests'),
    install_dir : installed_testdir,
    override_options : ['b_sanitize=none'],
    link_args : ['-static'],
  )
else
  warning('static libc not available, apply-extra-static will be skipped')
endif

subdir('share/xdg-desktop-portal/portals')
subdir('services')
subdir('test-keyring')
subdir('test-keyring2')

configure_file(
  input : 'package_version.txt.in',
  output : 'package_version.txt',
  configuration : {
    'PACKAGE_VERSION' : meson.project_version(),
  },
  install : get_option('installed_tests'),
  install_dir : installed_testdir,
)

if get_option('installed_tests')
  subdir('installed-services')

  install_data(
    'http-utils-test-server.py',
    'make-multi-collection-id-repo.sh',
    'make-test-app.sh',
    'make-test-runtime.sh',
    'oci-registry-client.py',
    'oci-registry-server.py',
    'test-webserver.sh',
    'test-wrapper.sh',
    'web-server.py',

    install_dir : installed_testdir,
    install_mode : 'rwxr-xr-x',
  )

  install_data(
    'gphoto2-list',
    'libtest.sh',
    'org.flatpak.Authenticator.test.service.in',
    'org.freedesktop.impl.portal.desktop.test.service.in',
    'org.test.Hello.png',
    'session.conf.in',
    'test.filter',
    'test.portal.in',

    install_dir : installed_testdir,
    install_mode : 'rw-r--r--',
  )
endif

shared_module(
  'preload',
  'libpreload.c',
  install : get_option('installed_tests'),
  install_dir : installed_testdir,
  override_options: ['b_sanitize=none'],
)

tests = {
  'basic': {},
  'completion': {},
  'config': {},
  'build-update-repo': {},
  'http-utils': {},
  'run': {'wrap': [
    'user,nodeltas',
    'user,deltas',
    'system,nodeltas',
    'system,deltas',
    'system-norevokefs,nodeltas',
    'system-norevokefs,deltas',
  ]},
  'info': {'wrap': ['user', 'system']},
  'repo': {'wrap': [
    'user',
    'system',
    'system-norevokefs',
    'user,oldsummary',
    'system,oldsummary',
  ]},
  'history': {},
  'sideload': {'wrap': ['user', 'system']},
  'default-remotes': {},
  'metadata-validation': {},
  'extensions': {},
  'extension-branch-follow': {},
  'bundle': {'wrap': ['user', 'system', 'system-norevokefs']},
  'oci': {},
  'oci-registry': {'wrap': [
    'user,http',
    'user,https',
    'system,http',
    'system,https',
  ]},
  'update-remote-configuration': {'wrap': ['newsummary', 'oldsummary']},
  'override': {},
  'update-portal': {'wrap': ['user', 'system']},
  'auth': {},
  'unused': {},
  'summaries': {'wrap': ['user', 'system']},
  'subset': {'wrap': ['user', 'system']},
  'prune': {},
  'seccomp': {},
  'repair': {},
  'extra-data': {'wrap': ['user', 'system']},
  'preinstall': {},
  'run-custom': {'wrap': ['user', 'system']},
  'upgrade-from-header': {'wrap': ['user', 'system', 'system-norevokefs']},
}

wrapped_tests = []
foreach name, testcase : tests
  script = 'test-@0@.sh'.format(name)

  if not testcase.has_key('wrap')
    wrapped_tests += {'name': script, 'script': script}
    continue
  endif

  foreach wrap : testcase['wrap']
    wrapped_tests += {
      'name': 'test-@0@@@1@.wrap'.format(name, wrap),
      'script': script,
    }
  endforeach
endforeach

foreach testcase : wrapped_tests
  name = testcase['name']
  script = testcase.get('script', name)

  timeout = {
    'test-bundle.sh' : 60,
    'test-oci-registry.sh' : 60,
    'test-repo.sh' : 300,
    'test-run.sh' : 90,
    'test-summaries.sh' : 60,
    'test-unused.sh' : 90,
    'test-update-portal.sh' : 90,
    'test-extra-data.sh' : 90,
  }.get(script, 30)

  is_parallel = {
    'test-history.sh' : false,
  }.get(script, true)

  if get_option('installed_tests')
    if name == script
      wrapper = ''
    else
      wrapper = installed_testdir / 'test-wrapper.sh'
    endif

    install_data(
      script,
      install_dir : installed_testdir,
      install_mode : 'rwxr-xr-x',
    )
    configure_file(
      input : 'tap.test.in',
      output : name + '.test',
      configuration : {
        'basename' : name,
        'installed_testdir' : installed_testdir,
        'wrapper' : wrapper,
      },
      install_dir : installed_tests_metadir,
    )
  endif

  test_env = environment(tests_environment)
  foreach k, v: tests_environment_prepend
    test_env.prepend(k, v)
  endforeach

  lsan_log_path = ':log_path=' + meson.current_build_dir() / \
                  'asan_' + name.underscorify() + '.log'
  test_env.set('LSAN_OPTIONS', lsan_options + lsan_log_path)

  if can_run_host_binaries
    test(
      name,
      tap_test,
      args : [meson.current_source_dir() / name],
      depends : runtime_repo,
      env : test_env,
      is_parallel : is_parallel,
      protocol : 'tap',
      timeout : timeout,
    )
  endif
endforeach

===== ./tests/web-server.py =====
#!/usr/bin/python3

from wsgiref.handlers import format_date_time
from email.utils import parsedate
from calendar import timegm
import gzip
import sys
import time
import zlib
import os
from http import HTTPStatus
from urllib.parse import parse_qs
import http.server as http_server
from io import BytesIO
import sys

class RequestHandler(http_server.SimpleHTTPRequestHandler):
    headers_log_file = None

    def handle_tokens(self):
        need_token_path = self.translate_path(self.path) + ".need_token"
        if os.path.isfile(need_token_path):
            with open(need_token_path, 'r') as content_file:
                token_content = content_file.read()
            token = None
            auth = self.headers.get("Authorization")
            if auth and auth.startswith("Bearer "):
                token = auth[7:]
            if token == None:
                self.send_response(HTTPStatus.UNAUTHORIZED, "No token")
                self.end_headers()
                return True
            if token != token_content:
                self.send_response(HTTPStatus.UNAUTHORIZED, "Wrong token")
                self.end_headers()
                return True
        return False

    def log_flatpak_headers(self):
        if self.headers_log_file is None:
            return

        for name in ("Flatpak-Ref", "Flatpak-Upgrade-From", "Flatpak-Is-Update"):
            value = self.headers.get(name)
            if value is not None:
                with open(self.headers_log_file, 'a+') as f:
                    f.write("%s: %s\n" % (name, value))

    def do_GET(self):
        self.log_flatpak_headers()
        if self.handle_tokens():
            return None
        self.headers.__delitem__("If-Modified-Since")
        return super().do_GET()

def run(dir, headers_log=None):
    RequestHandler.protocol_version = "HTTP/1.0"
    RequestHandler.headers_log_file = headers_log
    httpd = http_server.HTTPServer( ("127.0.0.1", 0), RequestHandler)
    host, port = httpd.socket.getsockname()[:2]
    with open("httpd-port", 'w') as file:
        file.write("%d" % port)
    with open("httpd-pid", 'w') as file:
        file.write("%d" % os.getpid())
    try:
        os.write(3, bytes("Started\n", 'utf-8'));
    except:
        pass
    print("Serving HTTP on port %d" % port);
    if dir:
        os.chdir(dir)
    httpd.serve_forever()

if __name__ == '__main__':
    dir = None
    headers_log = None
    if len(sys.argv) >= 2 and len(sys.argv[1]) > 0:
        dir = sys.argv[1]
    if len(sys.argv) >= 3 and len(sys.argv[2]) > 0:
        headers_log = sys.argv[2]

    run(dir, headers_log)

===== ./tests/test-exports.c =====
/* vi:set et sw=2 sts=2 cin cino=t0,f0,(0,{s,>2s,n-s,^-s,e-s:
 * Copyright © 2020 Collabora Ltd.
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 */

#include "config.h"

#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

#include <glib.h>
#include "flatpak.h"
#include "flatpak-bwrap-private.h"
#include "flatpak-context-private.h"
#include "flatpak-exports-private.h"
#include "flatpak-metadata-private.h"
#include "flatpak-utils-base-private.h"
#include "flatpak-utils-private.h"

#include "tests/testlib.h"

/*
 * Assert that the next few arguments starting from @i are setting up
 * /run/host/os-release. Return the next argument that hasn't been used.
 */
G_GNUC_WARN_UNUSED_RESULT static gsize
assert_next_is_os_release (FlatpakBwrap *bwrap,
                           gsize i)
{
  if (g_file_test ("/etc/os-release", G_FILE_TEST_EXISTS))
    {
      g_assert_cmpuint (i, <, bwrap->argv->len);
      g_assert_cmpstr (bwrap->argv->pdata[i++], ==, "--ro-bind");
      g_assert_cmpuint (i, <, bwrap->argv->len);
      g_assert_cmpstr (bwrap->argv->pdata[i++], ==, "/etc/os-release");
      g_assert_cmpuint (i, <, bwrap->argv->len);
      g_assert_cmpstr (bwrap->argv->pdata[i++], ==, "/run/host/os-release");
    }
  else if (g_file_test ("/usr/lib/os-release", G_FILE_TEST_EXISTS))
    {
      g_assert_cmpuint (i, <, bwrap->argv->len);
      g_assert_cmpstr (bwrap->argv->pdata[i++], ==, "--ro-bind");
      g_assert_cmpuint (i, <, bwrap->argv->len);
      g_assert_cmpstr (bwrap->argv->pdata[i++], ==, "/usr/lib/os-release");
      g_assert_cmpuint (i, <, bwrap->argv->len);
      g_assert_cmpstr (bwrap->argv->pdata[i++], ==, "/run/host/os-release");
    }
  else
    {
      g_test_message ("neither /etc/os-release nor /usr/lib/os-release exists on this host");
    }

  return i;
}

/* Assert that arguments starting from @i are --dir @dir.
 * Return the new @i. */
G_GNUC_WARN_UNUSED_RESULT static gsize
assert_next_is_dir (FlatpakBwrap *bwrap,
                    gsize i,
                    const char *dir)
{
  g_assert_cmpuint (i, <, bwrap->argv->len);
  g_assert_cmpstr (bwrap->argv->pdata[i++], ==, "--dir");
  g_assert_cmpuint (i, <, bwrap->argv->len);
  g_assert_cmpstr (bwrap->argv->pdata[i++], ==, dir);
  return i;
}

/* Assert that arguments starting from @i are --tmpfs @dir.
 * Return the new @i. */
G_GNUC_WARN_UNUSED_RESULT static gsize
assert_next_is_tmpfs (FlatpakBwrap *bwrap,
                      gsize i,
                      const char *dir)
{
  g_assert_cmpuint (i, <, bwrap->argv->len);
  g_assert_cmpstr (bwrap->argv->pdata[i++], ==, "--tmpfs");
  g_assert_cmpuint (i, <, bwrap->argv->len);
  g_assert_cmpstr (bwrap->argv->pdata[i++], ==, dir);
  return i;
}

/* Assert that arguments starting from @i are @how @path @path.
 * Return the new @i. */
G_GNUC_WARN_UNUSED_RESULT static gsize
assert_next_is_bind (FlatpakBwrap *bwrap,
                     gsize i,
                     const char *how,
                     const char *path,
                     const char *dest)
{
  g_assert_cmpuint (i, <, bwrap->argv->len);
  g_assert_cmpstr (bwrap->argv->pdata[i++], ==, how);
  g_assert_cmpuint (i, <, bwrap->argv->len);
  g_assert_cmpstr (bwrap->argv->pdata[i++], ==, path);
  g_assert_cmpuint (i, <, bwrap->argv->len);
  g_assert_cmpstr (bwrap->argv->pdata[i++], ==, dest);
  return i;
}

/* Assert that arguments starting from @i are --symlink @rel_target @path,
 * where @rel_target goes up from @path to the root and back down to the
 * target of the symlink. Return the new @i. */
G_GNUC_WARN_UNUSED_RESULT static gsize
assert_next_is_symlink (FlatpakBwrap *bwrap,
                      gsize i,
                      const char *target,
                      const char *path)
{
  const char *got_target;
  g_autofree gchar *dir = NULL;
  g_autofree gchar *resolved = NULL;
  g_autofree gchar *canon = NULL;
  g_autofree gchar *resolved_target = NULL;
  g_autofree gchar *expected = NULL;

  g_assert_cmpuint (i, <, bwrap->argv->len);
  g_assert_cmpstr (bwrap->argv->pdata[i++], ==, "--symlink");
  g_assert_cmpuint (i, <, bwrap->argv->len);

  got_target = bwrap->argv->pdata[i++];
  g_assert_false (g_path_is_absolute (got_target));
  dir = g_path_get_dirname (path);

  resolved = g_build_filename (dir, got_target, NULL);
  canon = flatpak_canonicalize_filename (resolved);

  if (g_path_is_absolute (target))
    resolved_target = g_strdup (target);
  else
    resolved_target = g_build_filename (dir, target, NULL);

  expected = flatpak_canonicalize_filename (resolved_target);

  g_assert_cmpstr (canon, ==, expected);
  g_assert_true (g_str_has_suffix (got_target, target));

  g_assert_cmpuint (i, <, bwrap->argv->len);
  g_assert_cmpstr (bwrap->argv->pdata[i++], ==, path);
  return i;
}

/* Print the arguments of a call to bwrap. */
static void
print_bwrap (FlatpakBwrap *bwrap)
{
  guint i;

  for (i = 0; i < bwrap->argv->len && bwrap->argv->pdata[i] != NULL; i++)
    g_test_message ("%s", (const char *) bwrap->argv->pdata[i]);

  g_test_message ("--");
}

static void
test_empty_context (void)
{
  g_autoptr(FlatpakBwrap) bwrap = flatpak_bwrap_new (NULL);
  g_autoptr(FlatpakContext) context = flatpak_context_new ();
  g_autoptr(FlatpakExports) exports = NULL;
  g_autofree char *xdg_dirs_conf = NULL;
  gboolean home_access = FALSE;

  g_assert_cmpuint (g_hash_table_size (context->env_vars), ==, 0);
  g_assert_cmpuint (g_hash_table_size (context->persistent), ==, 0);
  g_assert_cmpuint (g_hash_table_size (context->filesystems), ==, 0);
  g_assert_cmpuint (g_hash_table_size (context->session_bus_policy), ==, 0);
  g_assert_cmpuint (g_hash_table_size (context->system_bus_policy), ==, 0);
  g_assert_cmpuint (g_hash_table_size (context->generic_policy), ==, 0);
  g_assert_cmpuint (g_hash_table_size (context->shares_permissions), ==, 0);
  g_assert_cmpuint (g_hash_table_size (context->socket_permissions), ==, 0);
  g_assert_cmpuint (g_hash_table_size (context->device_permissions), ==, 0);
  g_assert_cmpuint (g_hash_table_size (context->features_permissions), ==, 0);

  exports = flatpak_context_get_exports (context, "com.example.App");
  g_assert_nonnull (exports);

  g_clear_pointer (&exports, flatpak_exports_free);
  exports = flatpak_context_get_exports_full (context,
                                              NULL, NULL,
                                              TRUE, TRUE,
                                              &xdg_dirs_conf, &home_access);
  g_assert_nonnull (exports);
  g_assert_nonnull (xdg_dirs_conf);
  flatpak_context_append_bwrap_filesystem (context, bwrap,
                                           "com.example.App",
                                           NULL, exports, xdg_dirs_conf,
                                           home_access);
  print_bwrap (bwrap);
}

static void
test_full_context (void)
{
  g_autoptr(FlatpakBwrap) bwrap = flatpak_bwrap_new (NULL);
  g_autoptr(FlatpakContext) context = flatpak_context_new ();
  g_autoptr(FlatpakExports) exports = NULL;
  g_autoptr(GError) error = NULL;
  g_autoptr(GKeyFile) keyfile = g_key_file_new ();
  g_autofree gchar *text = NULL;
  g_autofree char *xdg_dirs_conf = NULL;
  g_auto(GStrv) strv = NULL;
  gsize i, n;
  gboolean home_access = FALSE;

  g_key_file_set_value (keyfile,
                        FLATPAK_METADATA_GROUP_CONTEXT,
                        FLATPAK_METADATA_KEY_SHARED,
                        "network;ipc;");
  g_key_file_set_value (keyfile,
                        FLATPAK_METADATA_GROUP_CONTEXT,
                        FLATPAK_METADATA_KEY_SOCKETS,
                        "x11;wayland;pulseaudio;session-bus;system-bus;"
                        "fallback-x11;ssh-auth;pcsc;cups;inherit-wayland-socket;");
  g_key_file_set_value (keyfile,
                        FLATPAK_METADATA_GROUP_CONTEXT,
                        FLATPAK_METADATA_KEY_DEVICES,
                        "dri;all;kvm;shm;if:all:true;if:all:!has-wayland;");
  g_key_file_set_value (keyfile,
                        FLATPAK_METADATA_GROUP_CONTEXT,
                        FLATPAK_METADATA_KEY_FEATURES,
                        "devel;multiarch;bluetooth;canbus;per-app-dev-shm;");
  g_key_file_set_value (keyfile,
                        FLATPAK_METADATA_GROUP_CONTEXT,
                        FLATPAK_METADATA_KEY_FILESYSTEMS,
                        "host;/home;!/opt");
  g_key_file_set_value (keyfile,
                        FLATPAK_METADATA_GROUP_CONTEXT,
                        FLATPAK_METADATA_KEY_PERSISTENT,
                        ".openarena;");
  g_key_file_set_value (keyfile,
                        FLATPAK_METADATA_GROUP_SESSION_BUS_POLICY,
                        "org.example.SessionService",
                        "own");
  g_key_file_set_value (keyfile,
                        FLATPAK_METADATA_GROUP_SYSTEM_BUS_POLICY,
                        "net.example.SystemService",
                        "talk");
  g_key_file_set_value (keyfile,
                        FLATPAK_METADATA_GROUP_ENVIRONMENT,
                        "HYPOTHETICAL_PATH", "/foo:/bar");
  g_key_file_set_value (keyfile,
                        FLATPAK_METADATA_GROUP_ENVIRONMENT,
                        "LD_PRELOAD", "");
  g_key_file_set_value (keyfile,
                        FLATPAK_METADATA_GROUP_CONTEXT,
                        FLATPAK_METADATA_KEY_UNSET_ENVIRONMENT,
                        "LD_PRELOAD;LD_AUDIT;");
  g_key_file_set_value (keyfile,
                        FLATPAK_METADATA_GROUP_PREFIX_POLICY "MyPolicy",
                        "Colours", "blue;green;");

  flatpak_context_load_metadata (context, keyfile, &error);
  g_assert_no_error (error);

  FlatpakContextShares shares = flatpak_context_compute_allowed_shares (context, NULL);
  g_assert_cmpuint (shares, ==,
                    (FLATPAK_CONTEXT_SHARED_NETWORK |
                     FLATPAK_CONTEXT_SHARED_IPC));
  FlatpakContextDevices devices = flatpak_context_compute_allowed_devices (context, NULL);
  g_assert_cmpuint (devices, ==,
                    (FLATPAK_CONTEXT_DEVICE_DRI |
                     FLATPAK_CONTEXT_DEVICE_ALL |
                     FLATPAK_CONTEXT_DEVICE_KVM |
                     FLATPAK_CONTEXT_DEVICE_SHM));
  FlatpakContextSockets sockets = flatpak_context_compute_allowed_sockets (context, NULL);
  g_assert_cmpuint (sockets, ==,
                    (FLATPAK_CONTEXT_SOCKET_WAYLAND |
                     FLATPAK_CONTEXT_SOCKET_INHERIT_WAYLAND_SOCKET |
                     FLATPAK_CONTEXT_SOCKET_PULSEAUDIO |
                     FLATPAK_CONTEXT_SOCKET_SESSION_BUS |
                     FLATPAK_CONTEXT_SOCKET_SYSTEM_BUS |
                     FLATPAK_CONTEXT_SOCKET_SSH_AUTH |
                     FLATPAK_CONTEXT_SOCKET_PCSC |
                     FLATPAK_CONTEXT_SOCKET_CUPS));
  FlatpakContextFeatures features = flatpak_context_compute_allowed_features (context, NULL);
  g_assert_cmpuint (features, ==,
                    (FLATPAK_CONTEXT_FEATURE_DEVEL |
                     FLATPAK_CONTEXT_FEATURE_MULTIARCH |
                     FLATPAK_CONTEXT_FEATURE_BLUETOOTH |
                     FLATPAK_CONTEXT_FEATURE_CANBUS |
                     FLATPAK_CONTEXT_FEATURE_PER_APP_DEV_SHM));

  g_assert_cmpuint (g_hash_table_size (context->env_vars), ==, 3);
  g_assert_true (g_hash_table_contains (context->env_vars, "LD_AUDIT"));
  g_assert_null (g_hash_table_lookup (context->env_vars, "LD_AUDIT"));
  g_assert_true (g_hash_table_contains (context->env_vars, "LD_PRELOAD"));
  g_assert_null (g_hash_table_lookup (context->env_vars, "LD_PRELOAD"));
  g_assert_true (g_hash_table_contains (context->env_vars, "HYPOTHETICAL_PATH"));
  g_assert_cmpstr (g_hash_table_lookup (context->env_vars, "HYPOTHETICAL_PATH"),
                   ==, "/foo:/bar");

  exports = flatpak_context_get_exports (context, "com.example.App");
  g_assert_nonnull (exports);

  g_clear_pointer (&exports, flatpak_exports_free);
  exports = flatpak_context_get_exports_full (context,
                                              NULL, NULL,
                                              TRUE, TRUE,
                                              &xdg_dirs_conf, &home_access);
  g_assert_nonnull (exports);
  g_assert_nonnull (xdg_dirs_conf);
  flatpak_context_append_bwrap_filesystem (context, bwrap,
                                           "com.example.App",
                                           NULL, exports, xdg_dirs_conf,
                                           home_access);
  print_bwrap (bwrap);

  g_clear_pointer (&keyfile, g_key_file_unref);
  keyfile = g_key_file_new ();
  flatpak_context_save_metadata (context, FALSE, keyfile);
  text = g_key_file_to_data (keyfile, NULL, NULL);
  g_test_message ("Saved:\n%s", text);
  g_clear_pointer (&text, g_free);

  /* Test that keys round-trip back into the file */
  strv = g_key_file_get_string_list (keyfile, FLATPAK_METADATA_GROUP_CONTEXT,
                                     FLATPAK_METADATA_KEY_FILESYSTEMS,
                                     &n, &error);
  g_assert_nonnull (strv);
  /* The order is undefined, so sort them first */
  qsort (strv, n, sizeof (char *), flatpak_strcmp0_ptr);
  i = 0;
  g_assert_cmpstr (strv[i++], ==, "!/opt");
  g_assert_cmpstr (strv[i++], ==, "/home");
  g_assert_cmpstr (strv[i++], ==, "host");
  g_assert_cmpstr (strv[i], ==, NULL);
  g_assert_cmpuint (i, ==, n);
  g_clear_pointer (&strv, g_strfreev);

  strv = g_key_file_get_string_list (keyfile, FLATPAK_METADATA_GROUP_CONTEXT,
                                     FLATPAK_METADATA_KEY_SHARED,
                                     &n, &error);
  g_assert_no_error (error);
  g_assert_nonnull (strv);
  qsort (strv, n, sizeof (char *), flatpak_strcmp0_ptr);
  i = 0;
  g_assert_cmpstr (strv[i++], ==, "ipc");
  g_assert_cmpstr (strv[i++], ==, "network");
  g_assert_cmpstr (strv[i], ==, NULL);
  g_assert_cmpuint (i, ==, n);
  g_clear_pointer (&strv, g_strfreev);

  strv = g_key_file_get_string_list (keyfile, FLATPAK_METADATA_GROUP_CONTEXT,
                                     FLATPAK_METADATA_KEY_SOCKETS,
                                     &n, &error);
  g_assert_no_error (error);
  g_assert_nonnull (strv);
  qsort (strv, n, sizeof (char *), flatpak_strcmp0_ptr);
  i = 0;
  g_assert_cmpstr (strv[i++], ==, "cups");
  g_assert_cmpstr (strv[i++], ==, "fallback-x11");
  g_assert_cmpstr (strv[i++], ==, "inherit-wayland-socket");
  g_assert_cmpstr (strv[i++], ==, "pcsc");
  g_assert_cmpstr (strv[i++], ==, "pulseaudio");
  g_assert_cmpstr (strv[i++], ==, "session-bus");
  g_assert_cmpstr (strv[i++], ==, "ssh-auth");
  g_assert_cmpstr (strv[i++], ==, "system-bus");
  g_assert_cmpstr (strv[i++], ==, "wayland");
  g_assert_cmpstr (strv[i++], ==, "x11");
  g_assert_cmpstr (strv[i], ==, NULL);
  g_assert_cmpuint (i, ==, n);
  g_clear_pointer (&strv, g_strfreev);

  strv = g_key_file_get_string_list (keyfile, FLATPAK_METADATA_GROUP_CONTEXT,
                                     FLATPAK_METADATA_KEY_DEVICES,
                                     &n, &error);
  g_assert_no_error (error);
  g_assert_nonnull (strv);
  qsort (strv, n, sizeof (char *), flatpak_strcmp0_ptr);
  i = 0;
  g_assert_cmpstr (strv[i++], ==, "all");
  g_assert_cmpstr (strv[i++], ==, "dri");
  g_assert_cmpstr (strv[i++], ==, "if:all:!has-wayland");
  g_assert_cmpstr (strv[i++], ==, "if:all:true");
  g_assert_cmpstr (strv[i++], ==, "kvm");
  g_assert_cmpstr (strv[i++], ==, "shm");
  g_assert_cmpstr (strv[i], ==, NULL);
  g_assert_cmpuint (i, ==, n);
  g_clear_pointer (&strv, g_strfreev);

  strv = g_key_file_get_string_list (keyfile, FLATPAK_METADATA_GROUP_CONTEXT,
                                     FLATPAK_METADATA_KEY_PERSISTENT,
                                     &n, &error);
  g_assert_no_error (error);
  g_assert_nonnull (strv);
  qsort (strv, n, sizeof (char *), flatpak_strcmp0_ptr);
  i = 0;
  g_assert_cmpstr (strv[i++], ==, ".openarena");
  g_assert_cmpstr (strv[i], ==, NULL);
  g_assert_cmpuint (i, ==, n);
  g_clear_pointer (&strv, g_strfreev);

  strv = g_key_file_get_string_list (keyfile, FLATPAK_METADATA_GROUP_CONTEXT,
                                     FLATPAK_METADATA_KEY_UNSET_ENVIRONMENT,
                                     &n, &error);
  g_assert_no_error (error);
  g_assert_nonnull (strv);
  qsort (strv, n, sizeof (char *), flatpak_strcmp0_ptr);
  i = 0;
  g_assert_cmpstr (strv[i++], ==, "LD_AUDIT");
  g_assert_cmpstr (strv[i++], ==, "LD_PRELOAD");
  g_assert_cmpstr (strv[i], ==, NULL);
  g_assert_cmpuint (i, ==, n);
  g_clear_pointer (&strv, g_strfreev);

  strv = g_key_file_get_keys (keyfile, FLATPAK_METADATA_GROUP_SESSION_BUS_POLICY,
                              &n, &error);
  g_assert_no_error (error);
  g_assert_nonnull (strv);
  qsort (strv, n, sizeof (char *), flatpak_strcmp0_ptr);
  i = 0;
  g_assert_cmpstr (strv[i++], ==, "org.example.SessionService");
  g_assert_cmpstr (strv[i], ==, NULL);
  g_assert_cmpuint (i, ==, n);
  g_clear_pointer (&strv, g_strfreev);

  text = g_key_file_get_string (keyfile, FLATPAK_METADATA_GROUP_SESSION_BUS_POLICY,
                                "org.example.SessionService", &error);
  g_assert_no_error (error);
  g_assert_cmpstr (text, ==, "own");
  g_clear_pointer (&text, g_free);

  strv = g_key_file_get_keys (keyfile, FLATPAK_METADATA_GROUP_SYSTEM_BUS_POLICY,
                              &n, &error);
  g_assert_no_error (error);
  g_assert_nonnull (strv);
  qsort (strv, n, sizeof (char *), flatpak_strcmp0_ptr);
  i = 0;
  g_assert_cmpstr (strv[i++], ==, "net.example.SystemService");
  g_assert_cmpstr (strv[i], ==, NULL);
  g_assert_cmpuint (i, ==, n);
  g_clear_pointer (&strv, g_strfreev);

  text = g_key_file_get_string (keyfile, FLATPAK_METADATA_GROUP_SYSTEM_BUS_POLICY,
                                "net.example.SystemService", &error);
  g_assert_no_error (error);
  g_assert_cmpstr (text, ==, "talk");
  g_clear_pointer (&text, g_free);

  strv = g_key_file_get_keys (keyfile, FLATPAK_METADATA_GROUP_ENVIRONMENT,
                              &n, &error);
  g_assert_no_error (error);
  g_assert_nonnull (strv);
  qsort (strv, n, sizeof (char *), flatpak_strcmp0_ptr);
  i = 0;
  g_assert_cmpstr (strv[i++], ==, "HYPOTHETICAL_PATH");
  g_assert_cmpstr (strv[i++], ==, "LD_AUDIT");
  g_assert_cmpstr (strv[i++], ==, "LD_PRELOAD");
  g_assert_cmpstr (strv[i], ==, NULL);
  g_assert_cmpuint (i, ==, n);
  g_clear_pointer (&strv, g_strfreev);

  text = g_key_file_get_string (keyfile, FLATPAK_METADATA_GROUP_ENVIRONMENT,
                                "HYPOTHETICAL_PATH", &error);
  g_assert_no_error (error);
  g_assert_cmpstr (text, ==, "/foo:/bar");
  g_clear_pointer (&text, g_free);
  text = g_key_file_get_string (keyfile, FLATPAK_METADATA_GROUP_ENVIRONMENT,
                                "LD_AUDIT", &error);
  g_assert_no_error (error);
  g_assert_cmpstr (text, ==, "");
  g_clear_pointer (&text, g_free);
  text = g_key_file_get_string (keyfile, FLATPAK_METADATA_GROUP_ENVIRONMENT,
                                "LD_PRELOAD", &error);
  g_assert_no_error (error);
  g_assert_cmpstr (text, ==, "");
  g_clear_pointer (&text, g_free);

  strv = g_key_file_get_keys (keyfile, FLATPAK_METADATA_GROUP_PREFIX_POLICY "MyPolicy",
                              &n, &error);
  g_assert_no_error (error);
  g_assert_nonnull (strv);
  qsort (strv, n, sizeof (char *), flatpak_strcmp0_ptr);
  i = 0;
  g_assert_cmpstr (strv[i++], ==, "Colours");
  g_assert_cmpstr (strv[i], ==, NULL);
  g_assert_cmpuint (i, ==, n);
  g_clear_pointer (&strv, g_strfreev);

  strv = g_key_file_get_string_list (keyfile, FLATPAK_METADATA_GROUP_PREFIX_POLICY "MyPolicy",
                                     "Colours", &n, &error);
  g_assert_no_error (error);
  g_assert_nonnull (strv);
  qsort (strv, n, sizeof (char *), flatpak_strcmp0_ptr);
  i = 0;
  g_assert_cmpstr (strv[i++], ==, "blue");
  g_assert_cmpstr (strv[i++], ==, "green");
  g_assert_cmpstr (strv[i], ==, NULL);
  g_assert_cmpuint (i, ==, n);
  g_clear_pointer (&strv, g_strfreev);
}

typedef struct
{
  const char *input;
  GOptionError code;
} NotFilesystem;

static const NotFilesystem not_filesystems[] =
{
  { "", G_OPTION_ERROR_FAILED },
  { "homework", G_OPTION_ERROR_FAILED },
  { "xdg-download/foo/bar/..", G_OPTION_ERROR_BAD_VALUE },
  { "xdg-download/../foo/bar", G_OPTION_ERROR_BAD_VALUE },
  { "xdg-download/foo/../bar", G_OPTION_ERROR_BAD_VALUE },
  { "xdg-run", G_OPTION_ERROR_FAILED },
  { "/", G_OPTION_ERROR_BAD_VALUE },
  { "/////././././././//////", G_OPTION_ERROR_BAD_VALUE },
  { "host:reset", G_OPTION_ERROR_FAILED },
  { "host-reset", G_OPTION_ERROR_FAILED },
  { "host-reset:rw", G_OPTION_ERROR_FAILED },
  { "host-reset:reset", G_OPTION_ERROR_FAILED },
  { "!host-reset:reset", G_OPTION_ERROR_FAILED },
  { "/foo:reset", G_OPTION_ERROR_FAILED },
  { "!/foo:reset", G_OPTION_ERROR_FAILED },
};

typedef struct
{
  const char *input;
  FlatpakFilesystemMode mode;
  const char *fs;
} Filesystem;

static const Filesystem filesystems[] =
{
  { "home", FLATPAK_FILESYSTEM_MODE_READ_WRITE },
  { "host", FLATPAK_FILESYSTEM_MODE_READ_WRITE },
  { "host-etc", FLATPAK_FILESYSTEM_MODE_READ_WRITE },
  { "host-os", FLATPAK_FILESYSTEM_MODE_READ_WRITE },
  { "host:ro", FLATPAK_FILESYSTEM_MODE_READ_ONLY, "host" },
  { "home:rw", FLATPAK_FILESYSTEM_MODE_READ_WRITE, "home" },
  { "~/Music", FLATPAK_FILESYSTEM_MODE_READ_WRITE },
  { "/srv/obs/debian\\:sid\\:main:create", FLATPAK_FILESYSTEM_MODE_CREATE,
    "/srv/obs/debian:sid:main" },
  { "/srv/c\\:\\\\Program Files\\\\Steam", FLATPAK_FILESYSTEM_MODE_READ_WRITE,
    "/srv/c:\\Program Files\\Steam" },
  { "/srv/escaped\\unnecessarily", FLATPAK_FILESYSTEM_MODE_READ_WRITE,
    "/srv/escapedunnecessarily" },
  { "xdg-desktop", FLATPAK_FILESYSTEM_MODE_READ_WRITE },
  { "xdg-desktop/Stuff", FLATPAK_FILESYSTEM_MODE_READ_WRITE },
  { "xdg-documents", FLATPAK_FILESYSTEM_MODE_READ_WRITE },
  { "xdg-documents/Stuff", FLATPAK_FILESYSTEM_MODE_READ_WRITE },
  { "xdg-download", FLATPAK_FILESYSTEM_MODE_READ_WRITE },
  { "xdg-download/Stuff", FLATPAK_FILESYSTEM_MODE_READ_WRITE },
  { "xdg-music", FLATPAK_FILESYSTEM_MODE_READ_WRITE },
  { "xdg-music/Stuff", FLATPAK_FILESYSTEM_MODE_READ_WRITE },
  { "xdg-pictures", FLATPAK_FILESYSTEM_MODE_READ_WRITE },
  { "xdg-pictures/Stuff", FLATPAK_FILESYSTEM_MODE_READ_WRITE },
  { "xdg-public-share", FLATPAK_FILESYSTEM_MODE_READ_WRITE },
  { "xdg-public-share/Stuff", FLATPAK_FILESYSTEM_MODE_READ_WRITE },
  { "xdg-templates", FLATPAK_FILESYSTEM_MODE_READ_WRITE },
  { "xdg-templates/Stuff", FLATPAK_FILESYSTEM_MODE_READ_WRITE },
  { "xdg-videos", FLATPAK_FILESYSTEM_MODE_READ_WRITE },
  { "xdg-videos/Stuff", FLATPAK_FILESYSTEM_MODE_READ_WRITE },
  { "xdg-data", FLATPAK_FILESYSTEM_MODE_READ_WRITE },
  { "xdg-data/Stuff", FLATPAK_FILESYSTEM_MODE_READ_WRITE },
  { "xdg-cache", FLATPAK_FILESYSTEM_MODE_READ_WRITE },
  { "xdg-cache/Stuff", FLATPAK_FILESYSTEM_MODE_READ_WRITE },
  { "xdg-config", FLATPAK_FILESYSTEM_MODE_READ_WRITE },
  { "xdg-config/Stuff", FLATPAK_FILESYSTEM_MODE_READ_WRITE },
  { "xdg-config/././///.///././.", FLATPAK_FILESYSTEM_MODE_READ_WRITE, "xdg-config" },
  { "xdg-config/////", FLATPAK_FILESYSTEM_MODE_READ_WRITE, "xdg-config" },
  { "xdg-run/dbus", FLATPAK_FILESYSTEM_MODE_READ_WRITE },
  { "~", FLATPAK_FILESYSTEM_MODE_READ_WRITE, "home" },
  { "~/.", FLATPAK_FILESYSTEM_MODE_READ_WRITE, "home" },
  { "~/", FLATPAK_FILESYSTEM_MODE_READ_WRITE, "home" },
  { "~///././//", FLATPAK_FILESYSTEM_MODE_READ_WRITE, "home" },
  { "home/", FLATPAK_FILESYSTEM_MODE_READ_WRITE, "home" },
  { "home/Projects", FLATPAK_FILESYSTEM_MODE_READ_WRITE, "~/Projects" },
  { "!home", FLATPAK_FILESYSTEM_MODE_NONE, "home" },
  { "!host:reset", FLATPAK_FILESYSTEM_MODE_NONE, "host-reset" },
  { "!host-reset", FLATPAK_FILESYSTEM_MODE_NONE, "host-reset" },
};

static void
test_filesystems (void)
{
  gsize i;

  for (i = 0; i < G_N_ELEMENTS (filesystems); i++)
    {
      const Filesystem *fs = &filesystems[i];
      const char *input = fs->input;
      gboolean negated = FALSE;
      g_autoptr(GError) error = NULL;
      g_autofree char *normalized;
      FlatpakFilesystemMode mode;
      gboolean ret;

      g_test_message ("%s", fs->input);

      if (input[0] == '!')
        {
          g_test_message ("-> input is negated");
          negated = TRUE;
          input++;
        }

      ret = flatpak_context_parse_filesystem (input, negated,
                                              &normalized, &mode, &error);
      g_assert_no_error (error);
      g_assert_true (ret);

      g_test_message ("-> mode: %u", mode);
      g_test_message ("-> normalized filesystem: %s", normalized);

      if (fs->fs == NULL)
        g_assert_cmpstr (normalized, ==, input);
      else
        g_assert_cmpstr (normalized, ==, fs->fs);

      g_assert_cmpuint (mode, ==, fs->mode);
    }

  for (i = 0; i < G_N_ELEMENTS (not_filesystems); i++)
    {
      const NotFilesystem *not = &not_filesystems[i];
      const char *input = not->input;
      gboolean negated = FALSE;
      g_autoptr(GError) error = NULL;
      char *normalized = NULL;
      FlatpakFilesystemMode mode;
      gboolean ret;

      g_test_message ("%s", not->input);

      if (input[0] == '!')
        {
          negated = TRUE;
          input++;
        }

      ret = flatpak_context_parse_filesystem (input, negated,
                                              &normalized, &mode, &error);
      g_test_message ("-> %s", error ? error->message : "(no error)");
      g_assert_error (error, G_OPTION_ERROR, not->code);
      g_assert_false (ret);
      g_assert_null (normalized);
    }
}

static void
test_empty (void)
{
  g_autoptr(FlatpakBwrap) bwrap = flatpak_bwrap_new (NULL);
  g_autoptr(FlatpakExports) exports = flatpak_exports_new ();
  gsize i;

  g_assert_false (flatpak_exports_path_is_visible (exports, "/run"));
  g_assert_cmpint (flatpak_exports_path_get_mode (exports, "/tmp"), ==,
                   FLATPAK_FILESYSTEM_MODE_NONE);

  flatpak_bwrap_add_arg (bwrap, "bwrap");
  flatpak_exports_append_bwrap_args (exports, bwrap);
  flatpak_bwrap_finish (bwrap);
  print_bwrap (bwrap);

  i = 0;
  g_assert_cmpuint (i, <, bwrap->argv->len);
  g_assert_cmpstr (bwrap->argv->pdata[i++], ==, "bwrap");

  i = assert_next_is_os_release (bwrap, i);

  g_assert_cmpuint (i, <, bwrap->argv->len);
  g_assert_cmpstr (bwrap->argv->pdata[i++], ==, NULL);
  g_assert_cmpuint (i, ==, bwrap->argv->len);
}

static void
test_full (void)
{
  g_autoptr(GError) error = NULL;
  g_autoptr(FlatpakBwrap) bwrap = flatpak_bwrap_new (NULL);
  g_autoptr(FlatpakExports) exports = flatpak_exports_new ();
  g_autofree gchar *subdir = g_build_filename (isolated_test_dir, "test_full", NULL);
  g_autofree gchar *expose_rw = g_build_filename (subdir, "expose-rw", NULL);
  g_autofree gchar *in_expose_rw = g_build_filename (subdir, "expose-rw",
                                                     "file", NULL);
  g_autofree gchar *dangling_link_in_expose_rw = g_build_filename (subdir,
                                                                   "expose-rw",
                                                                   "dangling",
                                                                   NULL);
  g_autofree gchar *expose_ro = g_build_filename (subdir, "expose-ro", NULL);
  g_autofree gchar *in_expose_ro = g_build_filename (subdir, "expose-ro",
                                                     "file", NULL);
  g_autofree gchar *hide = g_build_filename (subdir, "hide", NULL);
  g_autofree gchar *dont_hide = g_build_filename (subdir, "dont-hide", NULL);
  g_autofree gchar *hide_below_expose = g_build_filename (subdir,
                                                          "expose-ro",
                                                          "hide-me",
                                                          NULL);
  g_autofree gchar *enoent = g_build_filename (subdir, "ENOENT", NULL);
  g_autofree gchar *one = g_build_filename (subdir, "1", NULL);
  g_autofree gchar *rel_link = g_build_filename (subdir, "1", "rel-link", NULL);
  g_autofree gchar *abs_link = g_build_filename (subdir, "1", "abs-link", NULL);
  g_autofree gchar *in_abs_link = g_build_filename (subdir, "1", "abs-link",
                                                    "file", NULL);
  g_autofree gchar *dangling = g_build_filename (subdir, "1", "dangling", NULL);
  g_autofree gchar *in_dangling = g_build_filename (subdir, "1", "dangling",
                                                    "file", NULL);
  g_autofree gchar *abs_target = g_build_filename (subdir, "2", "abs-target", NULL);
  g_autofree gchar *target = g_build_filename (subdir, "2", "target", NULL);
  g_autofree gchar *create_dir = g_build_filename (subdir, "create-dir", NULL);
  g_autofree gchar *create_dir2 = g_build_filename (subdir, "create-dir2", NULL);
  gsize i;
  gboolean ok;

  glnx_shutil_rm_rf_at (-1, subdir, NULL, &error);

  if (error != NULL)
    {
      g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND);
      g_clear_error (&error);
    }

  if (g_mkdir_with_parents (expose_rw, S_IRWXU) != 0)
    g_error ("mkdir: %s", g_strerror (errno));

  if (g_mkdir_with_parents (expose_ro, S_IRWXU) != 0)
    g_error ("mkdir: %s", g_strerror (errno));

  if (g_mkdir_with_parents (hide_below_expose, S_IRWXU) != 0)
    g_error ("mkdir: %s", g_strerror (errno));

  if (g_mkdir_with_parents (hide, S_IRWXU) != 0)
    g_error ("mkdir: %s", g_strerror (errno));

  if (g_mkdir_with_parents (dont_hide, S_IRWXU) != 0)
    g_error ("mkdir: %s", g_strerror (errno));

  if (g_mkdir_with_parents (abs_target, S_IRWXU) != 0)
    g_error ("mkdir: %s", g_strerror (errno));

  if (g_mkdir_with_parents (target, S_IRWXU) != 0)
    g_error ("mkdir: %s", g_strerror (errno));

  if (g_mkdir_with_parents (one, S_IRWXU) != 0)
    g_error ("mkdir: %s", g_strerror (errno));

  if (g_mkdir_with_parents (create_dir, S_IRWXU) != 0)
    g_error ("mkdir: %s", g_strerror (errno));

  if (symlink (abs_target, abs_link) != 0)
    g_error ("symlink: %s", g_strerror (errno));

  if (symlink ("nope", dangling) != 0)
    g_error ("symlink: %s", g_strerror (errno));

  if (symlink ("nope", dangling_link_in_expose_rw) != 0)
    g_error ("symlink: %s", g_strerror (errno));

  if (symlink ("../2/target", rel_link) != 0)
    g_error ("symlink: %s", g_strerror (errno));

  flatpak_exports_add_host_etc_expose (exports,
                                       FLATPAK_FILESYSTEM_MODE_READ_WRITE);
  flatpak_exports_add_host_os_expose (exports,
                                      FLATPAK_FILESYSTEM_MODE_READ_ONLY);
  ok = flatpak_exports_add_path_expose (exports,
                                        FLATPAK_FILESYSTEM_MODE_READ_WRITE,
                                        expose_rw, &error);
  g_assert_no_error (error);
  g_assert_true (ok);
  ok = flatpak_exports_add_path_expose (exports,
                                        FLATPAK_FILESYSTEM_MODE_READ_ONLY,
                                        expose_ro, &error);
  g_assert_no_error (error);
  g_assert_true (ok);
  ok = flatpak_exports_add_path_tmpfs (exports, hide_below_expose, &error);
  g_assert_no_error (error);
  g_assert_true (ok);
  ok = flatpak_exports_add_path_expose_or_hide (exports,
                                                FLATPAK_FILESYSTEM_MODE_NONE,
                                                hide, &error);
  g_assert_no_error (error);
  g_assert_true (ok);
  ok = flatpak_exports_add_path_expose_or_hide (exports,
                                                FLATPAK_FILESYSTEM_MODE_READ_ONLY,
                                                dont_hide, &error);
  g_assert_no_error (error);
  g_assert_true (ok);

  ok = flatpak_exports_add_path_expose_or_hide (exports,
                                                FLATPAK_FILESYSTEM_MODE_READ_ONLY,
                                                enoent, &error);
  g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND);
  g_assert_false (ok);
  g_clear_error (&error);

  ok = flatpak_exports_add_path_expose_or_hide (exports,
                                                FLATPAK_FILESYSTEM_MODE_READ_WRITE,
                                                rel_link, &error);
  g_assert_no_error (error);
  g_assert_true (ok);
  ok = flatpak_exports_add_path_expose_or_hide (exports,
                                                FLATPAK_FILESYSTEM_MODE_READ_WRITE,
                                                abs_link, &error);
  g_assert_no_error (error);
  g_assert_true (ok);
  ok = flatpak_exports_add_path_dir (exports, create_dir, &error);
  g_assert_no_error (error);
  g_assert_true (ok);

  ok = flatpak_exports_add_path_dir (exports, create_dir2, &error);
  g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND);
  g_assert_false (ok);
  g_clear_error (&error);

  g_assert_cmpuint (flatpak_exports_path_get_mode (exports, expose_rw), ==,
                    FLATPAK_FILESYSTEM_MODE_READ_WRITE);
  g_assert_cmpuint (flatpak_exports_path_get_mode (exports, expose_ro), ==,
                    FLATPAK_FILESYSTEM_MODE_READ_ONLY);
  g_assert_cmpuint (flatpak_exports_path_get_mode (exports, hide_below_expose), ==,
                    FLATPAK_FILESYSTEM_MODE_NONE);
  g_assert_cmpuint (flatpak_exports_path_get_mode (exports, hide), ==,
                    FLATPAK_FILESYSTEM_MODE_NONE);
  g_assert_cmpuint (flatpak_exports_path_get_mode (exports, dont_hide), ==,
                    FLATPAK_FILESYSTEM_MODE_READ_ONLY);
  /* It knows enoent didn't really exist */
  g_assert_cmpuint (flatpak_exports_path_get_mode (exports, enoent), ==,
                    FLATPAK_FILESYSTEM_MODE_NONE);
  g_assert_cmpuint (flatpak_exports_path_get_mode (exports, abs_link), ==,
                    FLATPAK_FILESYSTEM_MODE_READ_WRITE);
  g_assert_cmpuint (flatpak_exports_path_get_mode (exports, rel_link), ==,
                    FLATPAK_FILESYSTEM_MODE_READ_WRITE);

  /* Files the app would be allowed to create count as exposed */
  g_assert_cmpuint (flatpak_exports_path_get_mode (exports, in_expose_ro), ==,
                    FLATPAK_FILESYSTEM_MODE_NONE);
  g_assert_cmpuint (flatpak_exports_path_get_mode (exports, in_expose_rw), ==,
                    FLATPAK_FILESYSTEM_MODE_READ_WRITE);
  g_assert_cmpuint (flatpak_exports_path_get_mode (exports, in_abs_link), ==,
                    FLATPAK_FILESYSTEM_MODE_READ_WRITE);
  g_assert_cmpuint (flatpak_exports_path_get_mode (exports, in_dangling), ==,
                    FLATPAK_FILESYSTEM_MODE_NONE);

  flatpak_bwrap_add_arg (bwrap, "bwrap");
  flatpak_exports_append_bwrap_args (exports, bwrap);
  flatpak_bwrap_finish (bwrap);
  print_bwrap (bwrap);

  i = 0;
  g_assert_cmpuint (i, <, bwrap->argv->len);
  g_assert_cmpstr (bwrap->argv->pdata[i++], ==, "bwrap");

  i = assert_next_is_symlink (bwrap, i, abs_target, abs_link);
  i = assert_next_is_symlink (bwrap, i, "../2/target", rel_link);
  i = assert_next_is_bind (bwrap, i, "--bind", abs_target, abs_target);
  i = assert_next_is_bind (bwrap, i, "--bind", target, target);
  i = assert_next_is_dir (bwrap, i, create_dir);

  /* create_dir2 is not currently created with --dir inside the container
   * because it doesn't exist outside the container.
   * (Is this correct? For now, tolerate either way) */
  if (i + 2 < bwrap->argv->len &&
      g_strcmp0 (bwrap->argv->pdata[i], "--dir") == 0 &&
      g_strcmp0 (bwrap->argv->pdata[i + 1], create_dir2) == 0)
    i += 2;

  i = assert_next_is_bind (bwrap, i, "--ro-bind", dont_hide, dont_hide);
  i = assert_next_is_bind (bwrap, i, "--ro-bind", expose_ro, expose_ro);

  /* We don't create a FAKE_MODE_TMPFS in the container unless there is
   * a directory on the host to mount it on.
   * Hiding $subdir/expose-ro/hide-me has to use --tmpfs because
   * $subdir/expose-ro *is* exposed. */
  i = assert_next_is_tmpfs (bwrap, i, hide_below_expose);

  i = assert_next_is_bind (bwrap, i, "--bind", expose_rw, expose_rw);

  /* Hiding $subdir/hide just uses --dir, because $subdir is not
   * exposed. */
  i = assert_next_is_dir (bwrap, i, hide);

  while (i < bwrap->argv->len && bwrap->argv->pdata[i] != NULL)
    {
      /* An unknown number of --bind, --ro-bind and --symlink,
       * depending how your /usr and /etc are set up.
       * About the only thing we can say is that they are in threes. */
      g_assert_cmpuint (i++, <, bwrap->argv->len);
      g_assert_cmpuint (i++, <, bwrap->argv->len);
      g_assert_cmpuint (i++, <, bwrap->argv->len);
    }

  g_assert_cmpuint (i, ==, bwrap->argv->len - 1);
  g_assert_cmpstr (bwrap->argv->pdata[i++], ==, NULL);
  g_assert_cmpuint (i, ==, bwrap->argv->len);

  glnx_shutil_rm_rf_at (-1, subdir, NULL, &error);

  if (error != NULL)
    {
      g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND);
      g_clear_error (&error);
    }
}

typedef enum
{
  FAKE_DIR,
  FAKE_FILE,
  FAKE_SYMLINK,
} FakeFileType;

typedef struct
{
  const char *name;
  FakeFileType type;
  const char *target;
} FakeFile;

static void
create_fake_files (const FakeFile *files)
{
  gsize i;

  for (i = 0; files[i].name != NULL; i++)
    {
      g_autoptr(GError) error = NULL;
      g_autofree gchar *path = g_build_filename (isolated_test_dir, "host",
                                                 files[i].name, NULL);

      g_assert (files[i].name[0] != '/');

      switch (files[i].type)
        {
          case FAKE_DIR:
            if (g_mkdir_with_parents (path, S_IRWXU) != 0)
              g_error ("mkdir: %s", g_strerror (errno));

            break;

          case FAKE_FILE:
            g_file_set_contents (path, "", 0, &error);
            g_assert_no_error (error);
            break;


          case FAKE_SYMLINK:
            g_assert (files[i].target != NULL);

            if (symlink (files[i].target, path) != 0)
              g_error ("symlink: %s", g_strerror (errno));

            break;


          default:
            g_return_if_reached ();
        }
    }
}

static FlatpakExports *
test_host_exports_setup (const FakeFile *files,
                         FlatpakFilesystemMode etc_mode,
                         FlatpakFilesystemMode os_mode)
{
  g_autoptr(FlatpakExports) exports = flatpak_exports_new ();
  g_autoptr(GError) error = NULL;
  g_autofree gchar *host = g_build_filename (isolated_test_dir, "host", NULL);
  glnx_autofd int fd = -1;

  glnx_shutil_rm_rf_at (-1, host, NULL, &error);

  if (error != NULL)
    {
      g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND);
      g_clear_error (&error);
    }

  create_fake_files (files);
  glnx_openat_rdonly (AT_FDCWD, host, TRUE, &fd, &error);
  g_assert_no_error (error);
  g_assert_cmpint (fd, >=, 0);
  flatpak_exports_take_host_fd (exports, g_steal_fd (&fd));

  if (etc_mode > FLATPAK_FILESYSTEM_MODE_NONE)
    flatpak_exports_add_host_etc_expose (exports, etc_mode);

  if (os_mode > FLATPAK_FILESYSTEM_MODE_NONE)
    flatpak_exports_add_host_os_expose (exports, os_mode);

  return g_steal_pointer (&exports);
}

static void
test_host_exports_finish (FlatpakExports *exports,
                          FlatpakBwrap *bwrap)
{
  g_autofree gchar *host = g_build_filename (isolated_test_dir, "host", NULL);
  g_autoptr(GError) error = NULL;

  flatpak_bwrap_add_arg (bwrap, "bwrap");
  flatpak_exports_append_bwrap_args (exports, bwrap);
  flatpak_bwrap_finish (bwrap);
  print_bwrap (bwrap);

  glnx_shutil_rm_rf_at (-1, host, NULL, &error);

  if (error != NULL)
    {
      g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND);
      g_clear_error (&error);
    }
}

static void
test_host_exports (const FakeFile *files,
                   FlatpakBwrap *bwrap,
                   FlatpakFilesystemMode etc_mode,
                   FlatpakFilesystemMode os_mode)
{
  g_autoptr(FlatpakExports) exports = NULL;

  exports = test_host_exports_setup (files, etc_mode, os_mode);
  test_host_exports_finish (exports, bwrap);
}

/*
 * Test --filesystem=host-os with an OS that looks like Arch Linux.
 */
static void
test_exports_arch (void)
{
  static const FakeFile files[] =
  {
    { "etc", FAKE_DIR },
    { "etc/ld.so.cache", FAKE_FILE },
    { "etc/ld.so.conf", FAKE_FILE },
    { "etc/ld.so.conf.d", FAKE_DIR },
    { "bin", FAKE_SYMLINK, "usr/bin" },
    { "lib", FAKE_SYMLINK, "usr/lib" },
    { "lib64", FAKE_SYMLINK, "usr/lib" },
    { "sbin", FAKE_SYMLINK, "usr/bin" },
    { "usr/bin", FAKE_DIR },
    { "usr/lib", FAKE_DIR },
    { "usr/lib32", FAKE_DIR },
    { "usr/lib64", FAKE_SYMLINK, "lib" },
    { "usr/sbin", FAKE_SYMLINK, "bin" },
    { "usr/share", FAKE_DIR },
    { NULL }
  };
  g_autoptr(FlatpakBwrap) bwrap = flatpak_bwrap_new (NULL);
  gsize i;

  test_host_exports (files, bwrap, FLATPAK_FILESYSTEM_MODE_NONE,
                     FLATPAK_FILESYSTEM_MODE_READ_ONLY);

  i = 0;
  g_assert_cmpuint (i, <, bwrap->argv->len);
  g_assert_cmpstr (bwrap->argv->pdata[i++], ==, "bwrap");

  i = assert_next_is_bind (bwrap, i, "--ro-bind", "/usr", "/run/host/usr");
  i = assert_next_is_symlink (bwrap, i, "usr/bin", "/run/host/bin");
  i = assert_next_is_symlink (bwrap, i, "usr/lib", "/run/host/lib");
  i = assert_next_is_symlink (bwrap, i, "usr/lib", "/run/host/lib64");
  i = assert_next_is_symlink (bwrap, i, "usr/bin", "/run/host/sbin");
  i = assert_next_is_bind (bwrap, i, "--ro-bind", "/etc/ld.so.cache",
                           "/run/host/etc/ld.so.cache");

  g_assert_cmpuint (i, ==, bwrap->argv->len - 1);
  g_assert_cmpstr (bwrap->argv->pdata[i++], ==, NULL);
  g_assert_cmpuint (i, ==, bwrap->argv->len);
}

/*
 * Test --filesystem=host-os with an OS that looks like Fedora.
 */
static void
test_exports_fedora (void)
{
  static const FakeFile files[] =
  {
    { "etc", FAKE_DIR },
    { "etc/ld.so.cache", FAKE_FILE },
    { "etc/ld.so.conf", FAKE_FILE },
    { "etc/ld.so.conf.d", FAKE_DIR },
    { "bin", FAKE_SYMLINK, "usr/bin" },
    { "lib", FAKE_SYMLINK, "usr/lib" },
    { "lib64", FAKE_SYMLINK, "usr/lib64" },
    { "sbin", FAKE_SYMLINK, "usr/sbin" },
    { "usr/bin", FAKE_DIR },
    { "usr/lib", FAKE_DIR },
    { "usr/lib64", FAKE_DIR },
    { "usr/local", FAKE_SYMLINK, "../var/usrlocal" },
    { "usr/sbin", FAKE_DIR },
    { "usr/share", FAKE_DIR },
    { "var/usrlocal", FAKE_DIR },
    { NULL }
  };
  g_autoptr(FlatpakBwrap) bwrap = flatpak_bwrap_new (NULL);
  gsize i;

  test_host_exports (files, bwrap, FLATPAK_FILESYSTEM_MODE_NONE,
                     FLATPAK_FILESYSTEM_MODE_READ_ONLY);

  i = 0;
  g_assert_cmpuint (i, <, bwrap->argv->len);
  g_assert_cmpstr (bwrap->argv->pdata[i++], ==, "bwrap");

  i = assert_next_is_bind (bwrap, i, "--ro-bind", "/usr", "/run/host/usr");
  i = assert_next_is_bind (bwrap, i, "--ro-bind", "/var/usrlocal",
                           "/run/host/var/usrlocal");
  i = assert_next_is_symlink (bwrap, i, "usr/bin", "/run/host/bin");
  i = assert_next_is_symlink (bwrap, i, "usr/lib", "/run/host/lib");
  i = assert_next_is_symlink (bwrap, i, "usr/lib64", "/run/host/lib64");
  i = assert_next_is_symlink (bwrap, i, "usr/sbin", "/run/host/sbin");
  i = assert_next_is_bind (bwrap, i, "--ro-bind", "/etc/ld.so.cache",
                           "/run/host/etc/ld.so.cache");

  g_assert_cmpuint (i, ==, bwrap->argv->len - 1);
  g_assert_cmpstr (bwrap->argv->pdata[i++], ==, NULL);
  g_assert_cmpuint (i, ==, bwrap->argv->len);
}

/*
 * Test --filesystem=host-os with an OS that looks like Debian,
 * without the /usr merge, and with x86 and x32 multilib.
 */
static void
test_exports_debian (void)
{
  static const FakeFile files[] =
  {
    { "etc", FAKE_DIR },
    { "etc/alternatives", FAKE_DIR },
    { "etc/ld.so.cache", FAKE_FILE },
    { "etc/ld.so.conf", FAKE_FILE },
    { "etc/ld.so.conf.d", FAKE_DIR },
    { "etc/os-release", FAKE_FILE },
    { "bin", FAKE_DIR },
    { "lib", FAKE_DIR },
    { "lib32", FAKE_DIR },
    { "lib64", FAKE_DIR },
    { "libx32", FAKE_DIR },
    { "sbin", FAKE_DIR },
    { "usr/bin", FAKE_DIR },
    { "usr/lib", FAKE_DIR },
    { "usr/lib/os-release", FAKE_FILE },
    { "usr/lib32", FAKE_DIR },
    { "usr/lib64", FAKE_DIR },
    { "usr/libexec", FAKE_DIR },
    { "usr/libx32", FAKE_DIR },
    { "usr/sbin", FAKE_DIR },
    { "usr/share", FAKE_DIR },
    { NULL }
  };
  g_autoptr(FlatpakBwrap) bwrap = flatpak_bwrap_new (NULL);
  gsize i;

  test_host_exports (files, bwrap, FLATPAK_FILESYSTEM_MODE_NONE,
                     FLATPAK_FILESYSTEM_MODE_READ_ONLY);

  i = 0;
  g_assert_cmpuint (i, <, bwrap->argv->len);
  g_assert_cmpstr (bwrap->argv->pdata[i++], ==, "bwrap");

  i = assert_next_is_bind (bwrap, i, "--ro-bind", "/usr", "/run/host/usr");
  i = assert_next_is_bind (bwrap, i, "--ro-bind", "/bin", "/run/host/bin");
  i = assert_next_is_bind (bwrap, i, "--ro-bind", "/lib", "/run/host/lib");
  i = assert_next_is_bind (bwrap, i, "--ro-bind", "/lib32", "/run/host/lib32");
  i = assert_next_is_bind (bwrap, i, "--ro-bind", "/lib64", "/run/host/lib64");
  /* libx32 is not currently implemented */
  i = assert_next_is_bind (bwrap, i, "--ro-bind", "/sbin", "/run/host/sbin");
  i = assert_next_is_bind (bwrap, i, "--ro-bind", "/etc/ld.so.cache",
                           "/run/host/etc/ld.so.cache");
  i = assert_next_is_bind (bwrap, i, "--ro-bind", "/etc/alternatives",
                           "/run/host/etc/alternatives");
  i = assert_next_is_bind (bwrap, i, "--ro-bind", "/etc/os-release",
                           "/run/host/os-release");

  g_assert_cmpuint (i, ==, bwrap->argv->len - 1);
  g_assert_cmpstr (bwrap->argv->pdata[i++], ==, NULL);
  g_assert_cmpuint (i, ==, bwrap->argv->len);
}

/*
 * Test --filesystem=host-os and --filesystem=host-etc with an OS that
 * looks like Debian, with the /usr merge.
 */
static void
test_exports_debian_merged (void)
{
  static const FakeFile files[] =
  {
    { "etc", FAKE_DIR },
    { "etc/alternatives", FAKE_DIR },
    { "etc/ld.so.cache", FAKE_FILE },
    { "etc/ld.so.conf", FAKE_FILE },
    { "etc/ld.so.conf.d", FAKE_DIR },
    { "bin", FAKE_SYMLINK, "usr/bin" },
    { "lib", FAKE_SYMLINK, "usr/lib" },
    /* This one uses an absolute symlink just to check that we handle
     * that correctly */
    { "sbin", FAKE_SYMLINK, "/usr/sbin" },
    { "usr/bin", FAKE_DIR },
    { "usr/lib", FAKE_DIR },
    { "usr/lib/os-release", FAKE_FILE },
    { "usr/libexec", FAKE_DIR },
    { "usr/sbin", FAKE_DIR },
    { "usr/share", FAKE_DIR },
    { NULL }
  };
  g_autoptr(FlatpakBwrap) bwrap = flatpak_bwrap_new (NULL);
  gsize i;

  test_host_exports (files, bwrap, FLATPAK_FILESYSTEM_MODE_READ_ONLY,
                     FLATPAK_FILESYSTEM_MODE_READ_ONLY);

  i = 0;
  g_assert_cmpuint (i, <, bwrap->argv->len);
  g_assert_cmpstr (bwrap->argv->pdata[i++], ==, "bwrap");

  i = assert_next_is_bind (bwrap, i, "--ro-bind", "/usr", "/run/host/usr");
  i = assert_next_is_symlink (bwrap, i, "usr/bin", "/run/host/bin");
  i = assert_next_is_symlink (bwrap, i, "usr/lib", "/run/host/lib");
  i = assert_next_is_symlink (bwrap, i, "usr/sbin", "/run/host/sbin");
  i = assert_next_is_bind (bwrap, i, "--ro-bind", "/etc", "/run/host/etc");
  i = assert_next_is_bind (bwrap, i, "--ro-bind", "/usr/lib/os-release",
                           "/run/host/os-release");

  g_assert_cmpuint (i, ==, bwrap->argv->len - 1);
  g_assert_cmpstr (bwrap->argv->pdata[i++], ==, NULL);
  g_assert_cmpuint (i, ==, bwrap->argv->len);
}

static const struct
{
  const char *tried;
  const char *because;
}
reserved_filesystems[] =
{
  { "/", "/.flatpak-info" },
  { "/.flatpak-info", "/.flatpak-info" },
  { "/app", "/app" },
  { "/app/foo", "/app" },
  { "/bin", "/bin" },
  { "/bin/sh", "/bin" },
  { "/dev", "/dev" },
  { "/etc", "/etc" },
  { "/etc/passwd", "/etc" },
  { "/lib", "/lib" },
  { "/lib/ld-linux.so.2", "/lib" },
  { "/lib64", "/lib64" },
  { "/lib64/ld-linux-x86-64.so.2", "/lib64" },
  { "/proc", "/proc" },
  { "/proc/1", "/proc" },
  { "/proc/sys/net", "/proc" },
  { "/run", "/run/flatpak" },
  { "/run/flatpak/foo/bar", "/run/flatpak" },
  { "/run/host/foo", "/run/host" },
  { "/sbin", "/sbin" },
  { "/sbin/ldconfig", "/sbin" },
  { "/usr", "/usr" },
  { "/usr/bin/env", "/usr" },
  { "/usr/foo/bar", "/usr" },
};

static void
test_exports_ignored (void)
{
  g_autoptr(FlatpakBwrap) bwrap = flatpak_bwrap_new (NULL);
  g_autoptr(FlatpakExports) exports = flatpak_exports_new ();
  gsize i;

  for (i = 0; i < G_N_ELEMENTS (reserved_filesystems); i++)
    {
      const char *tried = reserved_filesystems[i].tried;
      const char *because = reserved_filesystems[i].because;
      g_autoptr(GError) error = NULL;
      gboolean ok;

      ok = flatpak_exports_add_path_expose (exports,
                                            FLATPAK_FILESYSTEM_MODE_READ_ONLY,
                                            tried,
                                            &error);
      g_assert_nonnull (error);
      g_assert_nonnull (error->message);
      g_test_message ("Trying to export %s -> %s", tried, error->message);
      g_assert_false (ok);

      if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_NOT_MOUNTABLE_FILE))
        {
          g_autofree char *pattern = g_strdup_printf ("Path \"%s\" is reserved by Flatpak",
                                                      because);

          g_test_message ("Expecting to see pattern: %s", pattern);
          g_assert_nonnull (strstr (error->message, pattern));
        }
    }

  flatpak_bwrap_add_arg (bwrap, "bwrap");
  flatpak_exports_append_bwrap_args (exports, bwrap);
  flatpak_bwrap_finish (bwrap);
  print_bwrap (bwrap);

  i = 0;
  g_assert_cmpuint (i, <, bwrap->argv->len);
  g_assert_cmpstr (bwrap->argv->pdata[i++], ==, "bwrap");

  i = assert_next_is_os_release (bwrap, i);

  g_assert_cmpuint (i, ==, bwrap->argv->len - 1);
  g_assert_cmpstr (bwrap->argv->pdata[i++], ==, NULL);
  g_assert_cmpuint (i, ==, bwrap->argv->len);
}

/*
 * Test various corner-cases using a mock root.
 */
static void
test_exports_unusual (void)
{
  static const FakeFile files[] =
  {
    { "TMP", FAKE_DIR },
    { "dangling-link", FAKE_SYMLINK, "nonexistent" },
    { "etc", FAKE_DIR },
    { "etc/ld.so.cache", FAKE_FILE },
    { "etc/ld.so.conf", FAKE_FILE },
    { "etc/ld.so.conf.d", FAKE_DIR },
    { "bin", FAKE_SYMLINK, "usr/bin" },
    { "broken-autofs", FAKE_DIR },
    { "home", FAKE_SYMLINK, "var/home" },
    { "lib", FAKE_SYMLINK, "usr/lib" },
    { "recursion", FAKE_SYMLINK, "recursion" },
    { "symlink-to-root", FAKE_SYMLINK, "." },
    { "tmp", FAKE_SYMLINK, "TMP" },
    { "usr/bin", FAKE_DIR },
    { "usr/lib", FAKE_DIR },
    { "usr/share", FAKE_DIR },
    { "var/home/me", FAKE_DIR },
    { "var/volatile/tmp", FAKE_DIR },
    { "var/tmp", FAKE_SYMLINK, "volatile/tmp" },
    { NULL }
  };
  g_autoptr(FlatpakBwrap) bwrap = flatpak_bwrap_new (NULL);
  g_autoptr(FlatpakExports) exports = NULL;
  gsize i;
  g_autoptr(GError) error = NULL;
  gboolean ok;

  exports = test_host_exports_setup (files,
                                     FLATPAK_FILESYSTEM_MODE_NONE,
                                     FLATPAK_FILESYSTEM_MODE_READ_ONLY);
  flatpak_exports_set_test_flags (exports, FLATPAK_EXPORTS_TEST_FLAGS_AUTOFS);
  ok = flatpak_exports_add_path_expose (exports,
                                        FLATPAK_FILESYSTEM_MODE_READ_ONLY,
                                        "/broken-autofs", &error);
  g_assert_error (error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK);
  g_test_message ("attempting to export /broken-autofs: %s", error->message);
  g_assert_false (ok);
  g_clear_error (&error);

  ok = flatpak_exports_add_path_expose (exports,
                                        FLATPAK_FILESYSTEM_MODE_READ_ONLY,
                                        "/dangling-link", &error);
  g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND);
  g_test_message ("attempting to export /dangling-link: %s", error->message);
  g_assert_false (ok);
  g_clear_error (&error);

  ok = flatpak_exports_add_path_expose (exports,
                                        FLATPAK_FILESYSTEM_MODE_READ_ONLY,
                                        "/home/me", &error);
  g_assert_no_error (error);
  g_assert_true (ok);

  ok = flatpak_exports_add_path_expose (exports,
                                        FLATPAK_FILESYSTEM_MODE_READ_ONLY,
                                        "/nonexistent", &error);
  g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND);
  g_test_message ("attempting to export /nonexistent: %s", error->message);
  g_assert_false (ok);
  g_clear_error (&error);

  ok = flatpak_exports_add_path_expose (exports,
                                        FLATPAK_FILESYSTEM_MODE_READ_ONLY,
                                        "/recursion", &error);
  g_assert_error (error, G_IO_ERROR, G_IO_ERROR_TOO_MANY_LINKS);
  g_test_message ("attempting to export /recursion: %s", error->message);
  g_assert_false (ok);
  g_clear_error (&error);

  ok = flatpak_exports_add_path_expose (exports,
                                        FLATPAK_FILESYSTEM_MODE_READ_ONLY,
                                        "/symlink-to-root", &error);
  g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_MOUNTABLE_FILE);
  g_test_message ("attempting to export /symlink-to-root: %s", error->message);
  g_assert_false (ok);
  g_clear_error (&error);

  ok = flatpak_exports_add_path_expose (exports,
                                        FLATPAK_FILESYSTEM_MODE_READ_ONLY,
                                        "/tmp", &error);
  g_assert_no_error (error);
  g_assert_true (ok);

  ok = flatpak_exports_add_path_expose (exports,
                                        FLATPAK_FILESYSTEM_MODE_READ_WRITE,
                                        "/var/tmp", &error);
  g_assert_no_error (error);
  g_assert_true (ok);

  ok = flatpak_exports_add_path_expose (exports,
                                        FLATPAK_FILESYSTEM_MODE_READ_ONLY,
                                        "not-absolute", &error);
  g_assert_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_FILENAME);
  g_test_message ("attempting to export not-absolute: %s", error->message);
  g_assert_false (ok);
  g_clear_error (&error);

  test_host_exports_finish (exports, bwrap);

  i = 0;
  g_assert_cmpuint (i, <, bwrap->argv->len);
  g_assert_cmpstr (bwrap->argv->pdata[i++], ==, "bwrap");

  i = assert_next_is_bind (bwrap, i, "--symlink", "var/home", "/home");
  i = assert_next_is_bind (bwrap, i, "--ro-bind", "/tmp", "/tmp");
  i = assert_next_is_bind (bwrap, i, "--ro-bind", "/var/home/me",
                           "/var/home/me");
  i = assert_next_is_bind (bwrap, i, "--bind", "/var/tmp",
                           "/var/tmp");
  i = assert_next_is_bind (bwrap, i, "--ro-bind", "/usr", "/run/host/usr");
  i = assert_next_is_symlink (bwrap, i, "usr/bin", "/run/host/bin");
  i = assert_next_is_symlink (bwrap, i, "usr/lib", "/run/host/lib");
  i = assert_next_is_bind (bwrap, i, "--ro-bind", "/etc/ld.so.cache",
                           "/run/host/etc/ld.so.cache");

  g_assert_cmpuint (i, ==, bwrap->argv->len - 1);
  g_assert_cmpstr (bwrap->argv->pdata[i++], ==, NULL);
  g_assert_cmpuint (i, ==, bwrap->argv->len);
}

int
main (int argc, char *argv[])
{
  int res;

  /* Do not call setlocale() here: some tests look at untranslated error
   * messages. */

  g_test_init (&argc, &argv, NULL);
  isolated_test_dir_global_setup ();

  g_test_add_func ("/context/empty", test_empty_context);
  g_test_add_func ("/context/filesystems", test_filesystems);
  g_test_add_func ("/context/full", test_full_context);
  g_test_add_func ("/exports/empty", test_empty);
  g_test_add_func ("/exports/full", test_full);
  g_test_add_func ("/exports/host/arch", test_exports_arch);
  g_test_add_func ("/exports/host/debian", test_exports_debian);
  g_test_add_func ("/exports/host/debian-usrmerge", test_exports_debian_merged);
  g_test_add_func ("/exports/host/fedora", test_exports_fedora);
  g_test_add_func ("/exports/ignored", test_exports_ignored);
  g_test_add_func ("/exports/unusual", test_exports_unusual);

  res = g_test_run ();

  isolated_test_dir_global_teardown ();

  return res;
}

===== ./tests/test-config.sh =====
#!/bin/bash
#
# Copyright (C) 2019 Matthias Clasen
#
# 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 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., 59 Temple Place - Suite 330,
# Boston, MA 02111-1307, USA.

set -euo pipefail

. $(dirname $0)/libtest.sh

# This test looks for specific localized strings.
export LC_ALL=C

echo "1..5"

${FLATPAK} config --list > list_out
assert_file_has_content list_out "^languages:"

ok "config list"

${FLATPAK} config --set languages "de;fr"
${FLATPAK} config --get languages > get_out
assert_file_has_content get_out "^de;fr"

ok "config set"

${FLATPAK} config --set languages "*"
${FLATPAK} config --get languages > get_out
assert_file_has_content get_out "*"

ok "config languages *"

${FLATPAK} config --set languages "all"
${FLATPAK} config --get languages > get_out
assert_file_has_content get_out "all"

ok "config languages *"

${FLATPAK} config --unset languages
${FLATPAK} config --get languages > get_out
assert_file_has_content get_out "^[*]unset[*]"

ok "config unset"

===== ./tests/gphoto2-list =====
# List from gphoto2
#
# Modified for tests, not for use.


vnd:0979+dev:0227
vnd:4102+dev:1230
!vnd:4102+dev:1213
!vnd:0502+dev:365e;!vnd:0502+dev:387a
vnd:0502+dev:3841;!vnd:0502+dev:33c3
vnd:0502+dev:33c4
vnd:0502+dev:3643
vnd:0502+dev:353c
vnd:0502+dev:362d
vnd:0502+dev:3586
vnd:0502+dev:3841
vnd:0502+dev:394b
vnd:0502+dev:3348
vnd:0502+dev:3349
vnd:0502+dev:334a
vnd:0502+dev:33d8
vnd:0502+dev:337c
vnd:0502+dev:337d
vnd:0502+dev:33cb
vnd:0502+dev:3325
vnd:0502+dev:3341
vnd:0502+dev:3344
vnd:0502+dev:3345
vnd:0502+dev:3389
vnd:0502+dev:338a
vnd:0502+dev:3378
vnd:0502+dev:3514
vnd:0502+dev:35a8
vnd:0502+dev:3644
vnd:0502+dev:3938
vnd:0502+dev:3725
vnd:0502+dev:3609
vnd:0502+dev:3473
vnd:0502+dev:355f
vnd:0502+dev:374f
vnd:0502+dev:3750
vnd:0502+dev:3750
vnd:0502+dev:37ef
vnd:0502+dev:38a5
vnd:0502+dev:38bb
vnd:0502+dev:3657
vnd:0502+dev:33aa
vnd:0502+dev:35e4
vnd:0502+dev:361d
vnd:0502+dev:3683
vnd:0502+dev:3822
vnd:0502+dev:3823
vnd:0502+dev:3886
vnd:16d5+dev:8006
vnd:16d5+dev:8005
vnd:08ca+dev:0111
vnd:1bbb+dev:0168
vnd:1bbb+dev:901b
vnd:1bbb+dev:2008
vnd:1bbb+dev:0c02
vnd:1bbb+dev:a00e
vnd:1bbb+dev:f003
vnd:1bbb+dev:af2b
vnd:1bbb+dev:af00
vnd:1bbb+dev:af2a
vnd:1bbb+dev:a00f
vnd:1bbb+dev:904d
vnd:1bbb+dev:0167
vnd:271d+dev:4016
vnd:0979+dev:0227
vnd:1949+dev:0800
vnd:1949+dev:0c31
vnd:1949+dev:0007
vnd:1949+dev:0008
vnd:1949+dev:000a
vnd:1949+dev:000c
vnd:1949+dev:0012
vnd:1949+dev:000b
vnd:1949+dev:000d
vnd:1949+dev:05e1
vnd:1949+dev:0005
vnd:1949+dev:0222
vnd:1949+dev:0221
vnd:1949+dev:0271
vnd:1949+dev:0121
vnd:1949+dev:0211
vnd:1949+dev:0261
vnd:1949+dev:0212
vnd:1949+dev:0331
vnd:1949+dev:0332
vnd:1949+dev:0262
vnd:1949+dev:00f2
vnd:1949+dev:0581
vnd:1949+dev:0272
vnd:1949+dev:0281
vnd:1949+dev:03f1
vnd:0979+dev:0224
vnd:05ac+dev:129a
vnd:05ac+dev:12ab
vnd:05ac+dev:1290
vnd:05ac+dev:1292
vnd:05ac+dev:1294
vnd:05ac+dev:1297
vnd:05ac+dev:12a0
vnd:05ac+dev:12a8
vnd:05ac+dev:1291
vnd:05ac+dev:1293
vnd:05ac+dev:1299
vnd:0e79+dev:5008
vnd:0e79+dev:5009
vnd:0e79+dev:4002
vnd:0e79+dev:1528
vnd:0e79+dev:1529
vnd:0e79+dev:1539
vnd:0e79+dev:1538
vnd:0e79+dev:14b9
vnd:0e79+dev:528c
vnd:0e79+dev:528d
vnd:0e79+dev:1548
vnd:0e79+dev:542f
vnd:0e79+dev:51c6
vnd:0e79+dev:120a
vnd:0e79+dev:131d
vnd:0e79+dev:120c
vnd:0e79+dev:52c2
vnd:0e79+dev:1301
vnd:0e79+dev:1303
vnd:0e79+dev:1311
vnd:0e79+dev:1321
vnd:0e79+dev:31f3
vnd:0e79+dev:1421
vnd:0e79+dev:1331
vnd:0e79+dev:1333
vnd:0e79+dev:3229
vnd:0e79+dev:322a
vnd:0e79+dev:5229
vnd:0e79+dev:522a
vnd:0e79+dev:53a7
vnd:0e79+dev:1307
vnd:0e79+dev:31bd
vnd:0e79+dev:2008
vnd:0e79+dev:5371
vnd:0e79+dev:545c
vnd:0e79+dev:5465
vnd:0e79+dev:544a
vnd:0e79+dev:1357
vnd:0e79+dev:1351
vnd:0e79+dev:1309
vnd:0e79+dev:130b
vnd:0e79+dev:1313
vnd:0e79+dev:1315
vnd:0e79+dev:1335
vnd:0e79+dev:15ba
vnd:0e79+dev:130d
vnd:0e79+dev:130f
vnd:0e79+dev:1319
vnd:0e79+dev:5395
vnd:0e79+dev:14ef
vnd:0e79+dev:1568
vnd:0e79+dev:1569
vnd:0e79+dev:14bf
vnd:0e79+dev:1518
vnd:0e79+dev:1508
vnd:0e79+dev:1509
vnd:0e79+dev:14ad
vnd:0e79+dev:149a
vnd:0e79+dev:5217
vnd:0e79+dev:146b
vnd:0e79+dev:145e
vnd:0e79+dev:1458
vnd:0e79+dev:31ab
vnd:0e79+dev:5603
vnd:0e79+dev:5305
vnd:0e79+dev:1207
vnd:0e79+dev:31d8
vnd:0e79+dev:31e1
vnd:0e79+dev:1341
vnd:0e79+dev:131b
vnd:0e79+dev:1208
vnd:0979+dev:0227
vnd:2770+dev:9120
vnd:093a+dev:010f
vnd:093a+dev:010f
vnd:2770+dev:913c
vnd:0979+dev:0227
vnd:093a+dev:010f
vnd:0979+dev:0227
vnd:2770+dev:905c
vnd:0b05+dev:5a0f
vnd:0b05+dev:590f
vnd:0b05+dev:4ce0
vnd:0b05+dev:4ce1
vnd:0b05+dev:514f
vnd:0b05+dev:7773
vnd:0b05+dev:540f
vnd:0b05+dev:541f
vnd:0b05+dev:550f
vnd:0b05+dev:5500
vnd:0b05+dev:4cd0
vnd:0b05+dev:4cd1
vnd:0b05+dev:521f
vnd:0b05+dev:520f
vnd:0b05+dev:4cc0
vnd:0b05+dev:4cc1
vnd:0b05+dev:7770
vnd:0b05+dev:5460
vnd:0b05+dev:5468
vnd:0b05+dev:5400
vnd:0b05+dev:5410
vnd:0b05+dev:5411
vnd:0b05+dev:5466
vnd:0b05+dev:7772
vnd:0b05+dev:5506
vnd:0b05+dev:5561
vnd:0b05+dev:5200
vnd:0b05+dev:5201
vnd:0b05+dev:5210
vnd:0b05+dev:5211
vnd:0b05+dev:5214
vnd:0b05+dev:5220
vnd:0b05+dev:5221
vnd:0b05+dev:5230
vnd:0b05+dev:5231
vnd:0b05+dev:4e00
vnd:0b05+dev:4e01
vnd:0b05+dev:4e0f
vnd:0b05+dev:4e1f
vnd:0b05+dev:4d00
vnd:0b05+dev:4d01
vnd:0b05+dev:4c80
vnd:0b05+dev:4c81
vnd:0b05+dev:4c90
vnd:0b05+dev:4c91
vnd:0b05+dev:4ca0
vnd:0b05+dev:4ca1
vnd:0b05+dev:561f
vnd:0b05+dev:5601
vnd:0b05+dev:5600
vnd:0b05+dev:5f02
vnd:0b05+dev:5f03
vnd:0b05+dev:580f
vnd:0b05+dev:581f
vnd:0b05+dev:5480
vnd:0b05+dev:5481
vnd:0b05+dev:7780
vnd:0b05+dev:7781
vnd:0b05+dev:5490
vnd:0b05+dev:5491
vnd:0b05+dev:2008
vnd:0b05+dev:610f
vnd:0b05+dev:600f
vnd:0b05+dev:5e0f
vnd:1908+dev:1315
vnd:1908+dev:1320
vnd:1908+dev:0102
vnd:1908+dev:3335
vnd:2770+dev:9051
vnd:2080+dev:000a
vnd:2080+dev:0006
vnd:2080+dev:0005
vnd:1d45+dev:459d
vnd:0fca+dev:8041
vnd:0fca+dev:8042
vnd:0fca+dev:8031
vnd:271d+dev:4017
vnd:271d+dev:4016
vnd:271d+dev:4008
vnd:2a47+dev:200d
vnd:2a47+dev:4ee1
vnd:2a47+dev:3003
vnd:2a47+dev:7f10
vnd:2a47+dev:901b
vnd:2a47+dev:9039
vnd:2a47+dev:903a
vnd:2a47+dev:7f11
vnd:2a47+dev:201d
vnd:2a47+dev:2008
vnd:2a47+dev:0c02
vnd:2a47+dev:f003
vnd:0e8d+dev:0c03
vnd:04a9+dev:3047
vnd:04a9+dev:31c2
vnd:04a9+dev:31bd
vnd:04a9+dev:31e6
vnd:04a9+dev:31f3
vnd:04a9+dev:327d
vnd:04a9+dev:32c0
vnd:04a9+dev:32d4
vnd:04a9+dev:3268
vnd:04a9+dev:30c0
vnd:04a9+dev:304d
vnd:04a9+dev:31f7
vnd:04a9+dev:3066
vnd:04a9+dev:30bf
vnd:04a9+dev:3075
vnd:04a9+dev:30ba
vnd:04a9+dev:310e
vnd:04a9+dev:30b4
vnd:04a9+dev:30ff
vnd:04a9+dev:311c
vnd:04a9+dev:30fe
vnd:04a9+dev:314f
vnd:04a9+dev:30f2
vnd:04a9+dev:314e
vnd:04a9+dev:3116
vnd:04a9+dev:3184
vnd:04a9+dev:3119
vnd:04a9+dev:3174
vnd:04a9+dev:3136
vnd:04a9+dev:3160
vnd:04a9+dev:3174
vnd:04a9+dev:3115
vnd:04a9+dev:31c4
vnd:04a9+dev:314b
vnd:04a9+dev:315f
vnd:04a9+dev:3173
vnd:04a9+dev:3193
vnd:04a9+dev:31c1
vnd:04a9+dev:309b
vnd:04a9+dev:309b
vnd:04a9+dev:30c4
vnd:04a9+dev:3072
vnd:04a9+dev:30b6
vnd:04a9+dev:30f4
vnd:04a9+dev:3052
vnd:04a9+dev:3065
vnd:04a9+dev:3070
vnd:04a9+dev:3071
vnd:04a9+dev:30f1
vnd:04a9+dev:32d6
vnd:04a9+dev:30ee
vnd:04a9+dev:306a
vnd:04a9+dev:3088
vnd:04a9+dev:3087
vnd:04a9+dev:30a5
vnd:04a9+dev:317b
vnd:04a9+dev:3270
vnd:04a9+dev:3083
vnd:04a9+dev:30bc
vnd:04a9+dev:3217
vnd:04a9+dev:327f
vnd:04a9+dev:32b4
vnd:04a9+dev:32e1
vnd:04a9+dev:3252
vnd:04a9+dev:30ea
vnd:04a9+dev:3147
vnd:04a9+dev:31d0
vnd:04a9+dev:3219
vnd:04a9+dev:3292
vnd:04a9+dev:32e8
vnd:04a9+dev:32e1
vnd:04a9+dev:32cc
vnd:04a9+dev:30eb
vnd:04a9+dev:30ec
vnd:04a9+dev:32e9
vnd:04a9+dev:3084
vnd:04a9+dev:3099
vnd:04a9+dev:3113
vnd:04a9+dev:30ef
vnd:04a9+dev:30ee
vnd:04a9+dev:30ee
vnd:04a9+dev:32d9
vnd:04a9+dev:3110
vnd:04a9+dev:3146
vnd:04a9+dev:3145
vnd:04a9+dev:31cf
vnd:04a9+dev:319b
vnd:04a9+dev:31ea
vnd:04a9+dev:3101
vnd:04a9+dev:3102
vnd:04a9+dev:3199
vnd:04a9+dev:323a
vnd:04a9+dev:3281
vnd:04a9+dev:3295
vnd:04a9+dev:32af
vnd:04a9+dev:3218
vnd:04a9+dev:3215
vnd:04a9+dev:323b
vnd:04a9+dev:3250
vnd:04a9+dev:32ca
vnd:04a9+dev:3272
vnd:04a9+dev:3253
vnd:04a9+dev:32a1
vnd:04a9+dev:3280
vnd:04a9+dev:32cb
vnd:04a9+dev:319a
vnd:04a9+dev:326f
vnd:04a9+dev:32c9
vnd:04a9+dev:3294
vnd:04a9+dev:32f1
vnd:04a9+dev:32ea
vnd:04a9+dev:3044
vnd:04a9+dev:3060
vnd:04a9+dev:3084
vnd:04a9+dev:3099
vnd:04a9+dev:3110
vnd:04a9+dev:3084
vnd:04a9+dev:3099
vnd:04a9+dev:30ee
vnd:04a9+dev:3110
vnd:04a9+dev:3145
vnd:04a9+dev:31cf
vnd:04a9+dev:323d
vnd:04a9+dev:32a0
vnd:04a9+dev:32d1
vnd:04a9+dev:3273
vnd:04a9+dev:32ef
vnd:04a9+dev:3299
vnd:04a9+dev:32bb
vnd:04a9+dev:32d2
vnd:04a9+dev:32f9
vnd:04a9+dev:32c5
vnd:04a9+dev:32e7
vnd:04a9+dev:32da
vnd:04a9+dev:32f8
vnd:04a9+dev:3312
vnd:04a9+dev:32fc
vnd:04a9+dev:32f4
vnd:04a9+dev:3303
vnd:04a9+dev:330d
vnd:04a9+dev:32f5
vnd:04a9+dev:330b
vnd:04a9+dev:32f7
vnd:04a9+dev:330c
vnd:04a9+dev:31cf
vnd:04a9+dev:32b4
vnd:04a9+dev:32c9
vnd:04a9+dev:32f1
vnd:04a9+dev:3145
vnd:04a9+dev:32e2
vnd:04a9+dev:308e
vnd:04a9+dev:3241
vnd:04a9+dev:32aa
vnd:04a9+dev:32a9
vnd:04a9+dev:3225
vnd:04a9+dev:31e6
vnd:04a9+dev:3193
vnd:04a9+dev:3046
vnd:04a9+dev:304b
vnd:04a9+dev:30c0
vnd:04a9+dev:30c4
vnd:04a9+dev:306b
vnd:04a9+dev:3096
vnd:04a9+dev:307c
vnd:04a9+dev:307a
vnd:04a9+dev:30a0
vnd:04a9+dev:3096
vnd:04a9+dev:308e
vnd:04a9+dev:3081
vnd:04a9+dev:3080
vnd:04a9+dev:30a9
vnd:04a9+dev:306b
vnd:04a9+dev:308d
vnd:04a9+dev:3082
vnd:04a9+dev:307f
vnd:04a9+dev:3080
vnd:04a9+dev:306b
vnd:04a9+dev:3096
vnd:04a9+dev:30a9
vnd:04a9+dev:3105
vnd:04a9+dev:308e
vnd:04a9+dev:304f
vnd:04a9+dev:3061
vnd:04a9+dev:318e
vnd:04a9+dev:31c3
vnd:04a9+dev:323e
vnd:04a9+dev:3264
vnd:04a9+dev:304e
vnd:04a9+dev:3062
vnd:04a9+dev:3191
vnd:04a9+dev:31be
vnd:04a9+dev:322a
vnd:04a9+dev:324a
vnd:04a9+dev:3249
vnd:04a9+dev:3271
vnd:04a9+dev:3262
vnd:04a9+dev:3059
vnd:04a9+dev:3076
vnd:04a9+dev:31f2
vnd:04a9+dev:30b8
vnd:04a9+dev:31f1
vnd:04a9+dev:3261
vnd:04a9+dev:3058
vnd:04a9+dev:30b7
vnd:04a9+dev:3243
vnd:04a9+dev:30f9
vnd:04a9+dev:310f
vnd:04a9+dev:30f8
vnd:04a9+dev:3155
vnd:04a9+dev:3149
vnd:04a9+dev:317a
vnd:04a9+dev:31bf
vnd:04a9+dev:31ef
vnd:04a9+dev:30c2
vnd:04a9+dev:30c1
vnd:04a9+dev:3126
vnd:04a9+dev:311b
vnd:04a9+dev:3150
vnd:04a9+dev:314d
vnd:04a9+dev:314c
vnd:04a9+dev:3177
vnd:04a9+dev:3176
vnd:04a9+dev:3074
vnd:04a9+dev:30fd
vnd:04a9+dev:30fc
vnd:04a9+dev:313a
vnd:04a9+dev:3139
vnd:04a9+dev:315b
vnd:04a9+dev:3073
vnd:04a9+dev:3117
vnd:04a9+dev:3138
vnd:04a9+dev:315d
vnd:04a9+dev:30b5
vnd:04a9+dev:309a
vnd:04a9+dev:3226
vnd:04a9+dev:323f
vnd:04a9+dev:30b9
vnd:04a9+dev:30bb
vnd:04a9+dev:31bc
vnd:04a9+dev:32ab
vnd:04a9+dev:3288
vnd:04a9+dev:3289
vnd:04a9+dev:3048
vnd:04a9+dev:3233
vnd:04a9+dev:318f
vnd:04a9+dev:31df
vnd:04a9+dev:320f
vnd:04a9+dev:3258
vnd:04a9+dev:3274
vnd:04a9+dev:3055
vnd:04a9+dev:306e
vnd:04a9+dev:306f
vnd:04a9+dev:32a8
vnd:04a9+dev:3085
vnd:04a9+dev:32b3
vnd:04a9+dev:30b3
vnd:04a9+dev:3125
vnd:04a9+dev:329d
vnd:04a9+dev:32bc
vnd:04a9+dev:315a
vnd:04a9+dev:32c7
vnd:04a9+dev:309b
vnd:04a9+dev:3049
vnd:04a9+dev:309c
vnd:04a9+dev:3041
vnd:04a9+dev:3236
vnd:04a9+dev:3045
vnd:04a9+dev:3051
vnd:04a9+dev:325b
vnd:04a9+dev:3275
vnd:04a9+dev:30f0
vnd:04a9+dev:3043
vnd:04a9+dev:3065
vnd:04a9+dev:3070
vnd:04a9+dev:3071
vnd:04a9+dev:311a
vnd:04a9+dev:3057
vnd:04a9+dev:304c
vnd:04a9+dev:3066
vnd:04a9+dev:3056
vnd:04a9+dev:3075
vnd:04a9+dev:30ba
vnd:04a9+dev:306c
vnd:04a9+dev:306d
vnd:04a9+dev:3148
vnd:04a9+dev:3077
vnd:04a9+dev:30b4
vnd:04a9+dev:30b2
vnd:04a9+dev:30b1
vnd:04a9+dev:30fa
vnd:04a9+dev:3212
vnd:04a9+dev:309b
vnd:04a9+dev:3072
vnd:04a9+dev:314f
vnd:04a9+dev:30b6
vnd:04a9+dev:3184
vnd:04a9+dev:31c4
vnd:04a9+dev:31f4
vnd:04a9+dev:30c4
vnd:04a9+dev:30c0
vnd:04a9+dev:3137
vnd:04a9+dev:30f1
vnd:04a9+dev:30ff
vnd:04a9+dev:30f2
vnd:04a9+dev:311c
vnd:04a9+dev:30fe
vnd:04a9+dev:3119
vnd:04a9+dev:314e
vnd:04a9+dev:3175
vnd:04a9+dev:31c2
vnd:04a9+dev:3174
vnd:04a9+dev:314b
vnd:04a9+dev:3196
vnd:04a9+dev:3115
vnd:04a9+dev:31e6
vnd:04a9+dev:31c1
vnd:04a9+dev:3193
vnd:04a9+dev:318d
vnd:04a9+dev:315e
vnd:04a9+dev:3192
vnd:04a9+dev:31e0
vnd:04a9+dev:3211
vnd:04a9+dev:3234
vnd:04a9+dev:325a
vnd:04a9+dev:3276
vnd:04a9+dev:31e4
vnd:04a9+dev:31c0
vnd:04a9+dev:31f6
vnd:04a9+dev:322c
vnd:04a9+dev:3228
vnd:04a9+dev:3245
vnd:04a9+dev:3244
vnd:04a9+dev:325f
vnd:04a9+dev:3238
vnd:04a9+dev:325c
vnd:04a9+dev:3277
vnd:04a9+dev:329b
vnd:04a9+dev:329f
vnd:04a9+dev:32be
vnd:04a9+dev:3286
vnd:04a9+dev:329a
vnd:04a9+dev:32ee
vnd:04a9+dev:32e4
vnd:04a9+dev:3050
vnd:04a9+dev:305c
vnd:04a9+dev:31ea
vnd:04a9+dev:3217
vnd:04a9+dev:3218
vnd:04a9+dev:323b
vnd:04a9+dev:32c3
vnd:04a9+dev:32c2
vnd:04a9+dev:3078
vnd:07cf+dev:1049
vnd:07cf+dev:1042
vnd:07cf+dev:104d
vnd:07cf+dev:104c
vnd:07cf+dev:117a
vnd:0409+dev:02ed
vnd:04b7+dev:88b9
vnd:04b7+dev:88d0
vnd:04b7+dev:88b0
vnd:04b7+dev:88c6
vnd:04b7+dev:88a9
vnd:04b7+dev:88aa
vnd:04b7+dev:88c0
vnd:04b7+dev:88c1
vnd:04b7+dev:88d6
vnd:04b7+dev:88f1
vnd:2770+dev:9120
vnd:2770+dev:905c
vnd:0979+dev:0224
vnd:2770+dev:905c
vnd:1e74+dev:6512
vnd:1e53+dev:0005
vnd:2770+dev:9120
vnd:2770+dev:9120
vnd:1ebf+dev:7029
vnd:0e21+dev:0952
vnd:0e21+dev:0711
vnd:0e21+dev:0751
vnd:0e21+dev:0911
vnd:0e21+dev:0941
vnd:0e21+dev:0801
vnd:0e21+dev:0871
vnd:0e21+dev:0891
vnd:0e21+dev:0861
vnd:0e21+dev:0881
vnd:0e21+dev:0921
vnd:0e21+dev:0901
vnd:0e21+dev:0701
vnd:0e21+dev:0761
vnd:0e21+dev:0931
vnd:041e+dev:4123
vnd:041e+dev:4157
vnd:041e+dev:411e
vnd:041e+dev:4130
vnd:041e+dev:413c
vnd:041e+dev:4133
vnd:041e+dev:4161
vnd:041e+dev:4137
vnd:041e+dev:413d
vnd:041e+dev:4131
vnd:041e+dev:4150
vnd:041e+dev:4158
vnd:041e+dev:4152
vnd:041e+dev:411f
vnd:041e+dev:4153
vnd:041e+dev:413e
vnd:041e+dev:4151
vnd:041e+dev:4162
vnd:041e+dev:4169
vnd:041e+dev:4128
vnd:109b+dev:9130
vnd:106c+dev:3215
vnd:2770+dev:905c
vnd:2770+dev:9120
vnd:0c45+dev:8000
vnd:041e+dev:4132
vnd:041e+dev:412f
vnd:413c+dev:b10b
vnd:413c+dev:b11a
vnd:413c+dev:b11b
vnd:413c+dev:4500
vnd:0bb4+dev:0c08
vnd:2770+dev:905c
vnd:1f3a+dev:0c02
vnd:093a+dev:010e
vnd:0979+dev:0227
vnd:0aa6+dev:6021
vnd:2770+dev:9050
vnd:2770+dev:9052
vnd:2b43+dev:0006
vnd:10d6+dev:2200
vnd:093a+dev:010e
vnd:093a+dev:010f
vnd:04b8+dev:0403
vnd:04b8+dev:0402
vnd:2e17+dev:c033
vnd:2e17+dev:c030
vnd:2ae5+dev:f003
vnd:2ae5+dev:6764
vnd:2ae5+dev:9039
vnd:09cb+dev:100b
vnd:2970+dev:4002
vnd:2970+dev:2008
vnd:2970+dev:0c02
vnd:2970+dev:4001
vnd:06d3+dev:21ba
vnd:0489+dev:c00b
vnd:0489+dev:c025
vnd:0489+dev:e111
vnd:0489+dev:1ab0
vnd:0489+dev:c026
vnd:0489+dev:e040
vnd:04cb+dev:014a
vnd:04cb+dev:01d0
vnd:04cb+dev:01d2
vnd:04cb+dev:01c6
vnd:04cb+dev:01d3
vnd:04cb+dev:021b
vnd:04cb+dev:0193
vnd:04cb+dev:01e0
vnd:04cb+dev:01c0
vnd:04cb+dev:01e4
vnd:04cb+dev:019b
vnd:04cb+dev:01c1
vnd:04cb+dev:01c5
vnd:04cb+dev:01d4
vnd:04cb+dev:01e6
vnd:04cb+dev:01fa
vnd:04cb+dev:020e
vnd:04cb+dev:022d
vnd:04cb+dev:0271
vnd:04cb+dev:0250
vnd:04cb+dev:01dd
vnd:04cb+dev:01db
vnd:04cb+dev:01ef
vnd:04cb+dev:0200
vnd:04cb+dev:01e8
vnd:04cb+dev:0209
vnd:04cb+dev:0240
vnd:04cb+dev:027d
vnd:04cb+dev:0265
vnd:04cb+dev:0298
vnd:04cb+dev:01c4
vnd:04cb+dev:01d7
vnd:04cb+dev:01bf
vnd:04cb+dev:0142
vnd:04cb+dev:02b9
vnd:04cb+dev:018f
vnd:04cb+dev:029c
vnd:04cb+dev:0233
vnd:04cb+dev:0283
vnd:04cb+dev:026e
vnd:04cb+dev:0263
vnd:04cb+dev:02a6
vnd:04cb+dev:0288
vnd:04cb+dev:01d8
vnd:04cb+dev:0201
vnd:04cb+dev:020d
vnd:04cb+dev:01fe
vnd:04cb+dev:02ea
vnd:04cb+dev:02e9
vnd:04cb+dev:02de
vnd:04cb+dev:02c6
vnd:04cb+dev:02d5
vnd:04cb+dev:02b5
vnd:04cb+dev:02d6
vnd:04cb+dev:02e8
vnd:04cb+dev:02d7
vnd:04cb+dev:02f2
vnd:04cb+dev:02f0
vnd:04cb+dev:02b6
vnd:04cb+dev:02cb
vnd:04cb+dev:02e4
vnd:04cb+dev:02ea
vnd:04cb+dev:02bf
vnd:04cb+dev:02c8
vnd:04cb+dev:02cd
vnd:04cb+dev:02d4
vnd:04cb+dev:02dd
vnd:04cb+dev:02e3
vnd:04cb+dev:02e6
vnd:04cb+dev:02fc
vnd:04cb+dev:02d1
vnd:04cb+dev:02e5
vnd:04cb+dev:02c1
vnd:04cb+dev:02ba
vnd:04cb+dev:02dc
vnd:04cb+dev:02d3
vnd:04cb+dev:01c3
vnd:04c5+dev:13dd
vnd:04c5+dev:1378
vnd:04c5+dev:1140
vnd:04c5+dev:133b
vnd:04c5+dev:158c
vnd:091e+dev:4dac
vnd:091e+dev:488b
vnd:091e+dev:4c7c
vnd:091e+dev:4dab
vnd:091e+dev:4cba
vnd:091e+dev:4e76
vnd:091e+dev:4f67
vnd:091e+dev:4b54
vnd:091e+dev:4cda
vnd:091e+dev:4cd8
vnd:091e+dev:4cdb
vnd:091e+dev:4f43
vnd:091e+dev:4f42
vnd:091e+dev:5116
vnd:091e+dev:4dad
vnd:091e+dev:4c05
vnd:091e+dev:4f97
vnd:091e+dev:50a1
vnd:091e+dev:4b48
vnd:091e+dev:4e05
vnd:091e+dev:4c29
vnd:091e+dev:4fb8
vnd:091e+dev:50db
vnd:091e+dev:4f96
vnd:091e+dev:4cae
vnd:091e+dev:4caf
vnd:091e+dev:2585
vnd:091e+dev:4daa
vnd:091e+dev:5027
vnd:091e+dev:4c9a
vnd:091e+dev:4e77
vnd:091e+dev:4f0b
vnd:091e+dev:4e78
vnd:091e+dev:4e9c
vnd:091e+dev:4e0c
vnd:091e+dev:4bac
vnd:091e+dev:4bfa
vnd:091e+dev:4c99
vnd:091e+dev:4c98
vnd:091e+dev:4d9c
vnd:2770+dev:9120
vnd:0458+dev:7005
vnd:040d+dev:885c
vnd:0414+dev:2008
vnd:0414+dev:0c02
vnd:0979+dev:0227
vnd:0979+dev:0227
vnd:2770+dev:9120
vnd:18d1+dev:0007
vnd:18d1+dev:0006
vnd:18d1+dev:4e41
vnd:18d1+dev:4e42
vnd:18d1+dev:4e0f
vnd:18d1+dev:4d00
vnd:18d1+dev:2d02
vnd:18d1+dev:0a07
vnd:18d1+dev:740a
vnd:18d1+dev:d10a
vnd:18d1+dev:d109
vnd:18d1+dev:b00a
vnd:18d1+dev:70a8
vnd:18d1+dev:7169
vnd:18d1+dev:4e12
vnd:18d1+dev:05b3
vnd:18d1+dev:7102
vnd:18d1+dev:4ee1
vnd:18d1+dev:4ee2
vnd:18d1+dev:4ee5
vnd:18d1+dev:4ee6
vnd:18d1+dev:5202
vnd:18d1+dev:5203
vnd:2672+dev:000c
vnd:2672+dev:0021
vnd:2672+dev:0011
vnd:2672+dev:000e
vnd:2672+dev:0056
vnd:2672+dev:0059
vnd:2672+dev:005a
vnd:2672+dev:000d
vnd:2672+dev:0027
vnd:2672+dev:0029
vnd:2672+dev:0037
vnd:2672+dev:0047
vnd:2672+dev:0043
vnd:2672+dev:0042
vnd:2672+dev:0049
vnd:2672+dev:004d
vnd:2770+dev:9120
vnd:201e+dev:a0c1
vnd:1302+dev:1016
vnd:1302+dev:1017
vnd:093a+dev:010e
vnd:03f0+dev:7e1d
vnd:03f0+dev:5d1d
vnd:03f0+dev:5c1d
vnd:109b+dev:9106
vnd:109b+dev:9109
vnd:109b+dev:9105
vnd:339b+dev:107d
vnd:03f0+dev:6502
vnd:03f0+dev:7c02
vnd:03f0+dev:7d02
vnd:03f0+dev:6302
vnd:03f0+dev:6602
vnd:03f0+dev:7402
vnd:03f0+dev:7802
vnd:03f0+dev:7202
vnd:03f0+dev:6e02
vnd:03f0+dev:7902
vnd:03f0+dev:6d02
vnd:03f0+dev:6302
vnd:03f0+dev:6802
vnd:03f0+dev:7102
vnd:03f0+dev:6b02
vnd:03f0+dev:6402
vnd:03f0+dev:7602
vnd:03f0+dev:6702
vnd:03f0+dev:6c02
vnd:03f0+dev:6a02
vnd:03f0+dev:4202
vnd:03f0+dev:7702
vnd:03f0+dev:7e02
vnd:03f0+dev:4302
vnd:03f0+dev:4402
vnd:03f0+dev:4502
vnd:03f0+dev:6002
vnd:03f0+dev:8b02
vnd:03f0+dev:9a02
vnd:03f0+dev:8c02
vnd:03f0+dev:7502
vnd:03f0+dev:7b02
vnd:03f0+dev:7302
vnd:03f0+dev:7a02
vnd:03f0+dev:8002
vnd:03f0+dev:8102
vnd:03f0+dev:8202
vnd:03f0+dev:9b02
vnd:03f0+dev:8402
vnd:03f0+dev:8502
vnd:03f0+dev:9602
vnd:03f0+dev:9702
vnd:03f0+dev:8702
vnd:03f0+dev:8802
vnd:0bb4+dev:685c
vnd:0bb4+dev:6860
vnd:0bb4+dev:0c02
vnd:0bb4+dev:2008
vnd:0bb4+dev:0ec7
vnd:0bb4+dev:0ec6
vnd:0bb4+dev:05fd
vnd:0bb4+dev:05f0
vnd:0bb4+dev:0edd
vnd:0bb4+dev:0668
vnd:0bb4+dev:0edb
vnd:0bb4+dev:0ebd
vnd:0bb4+dev:0dff
vnd:0bb4+dev:0c93
vnd:0bb4+dev:0ca8
vnd:0bb4+dev:0dfe
vnd:0bb4+dev:0de4
vnd:0bb4+dev:0670
vnd:0bb4+dev:0dd5
vnd:0bb4+dev:0e31
vnd:0bb4+dev:0e32
vnd:0bb4+dev:0df5
vnd:0bb4+dev:07ae
vnd:0bb4+dev:0dda
vnd:0bb4+dev:0f91
vnd:0bb4+dev:0f64
vnd:0bb4+dev:0f63
vnd:0bb4+dev:0f87
vnd:0bb4+dev:0f5f
vnd:0bb4+dev:0f60
vnd:0bb4+dev:0dea
vnd:0bb4+dev:0dd2
vnd:0bb4+dev:07ca
vnd:0bb4+dev:0f25
vnd:0bb4+dev:061a
vnd:0bb4+dev:0fb4
vnd:0bb4+dev:0fb5
vnd:0bb4+dev:07cb
vnd:0bb4+dev:07d9
vnd:0bb4+dev:0cec
vnd:0bb4+dev:0df8
vnd:0bb4+dev:0df9
vnd:0bb4+dev:0f26
vnd:0bb4+dev:0dfa
vnd:0bb4+dev:0dfb
vnd:0bb4+dev:0dfc
vnd:0bb4+dev:0dfd
vnd:0bb4+dev:07a1
vnd:0bb4+dev:07d8
vnd:0bb4+dev:0401
vnd:0bb4+dev:201d
vnd:0bb4+dev:2012
vnd:0bb4+dev:060b
vnd:0bb4+dev:040b
vnd:0bb4+dev:065c
vnd:0bb4+dev:4ee1
vnd:0bb4+dev:4ee2
vnd:0bb4+dev:0dcd
vnd:0bb4+dev:0629
vnd:0bb4+dev:05e3
vnd:0bb4+dev:f0ca
vnd:0bb4+dev:0ba1
vnd:0bb4+dev:0ba2
vnd:12d1+dev:1082
vnd:12d1+dev:2608
vnd:12d1+dev:1079
vnd:12d1+dev:107a
vnd:12d1+dev:2012
vnd:12d1+dev:1074
vnd:12d1+dev:260b
vnd:12d1+dev:360f
vnd:12d1+dev:361f
vnd:12d1+dev:1051
vnd:12d1+dev:1052
vnd:12d1+dev:107d
vnd:12d1+dev:107e
vnd:12d1+dev:2406
vnd:12d1+dev:256b
vnd:12d1+dev:2567
vnd:12d1+dev:107f
vnd:12d1+dev:257c
vnd:12d1+dev:259c
vnd:12d1+dev:2008
vnd:12d1+dev:255d
vnd:2207+dev:0017
vnd:2770+dev:9120
vnd:093a+dev:010e
vnd:19ff+dev:0303
vnd:19ff+dev:0309
vnd:19ff+dev:0307
vnd:8087+dev:0a5f
vnd:8087+dev:0a15
vnd:8087+dev:0a16
vnd:8087+dev:092a
vnd:8087+dev:0a5e
vnd:8087+dev:09fb
vnd:05c6+dev:0a07
vnd:093a+dev:010f
vnd:4102+dev:1195
vnd:4102+dev:1200
vnd:4102+dev:112a
vnd:4102+dev:1126
vnd:4102+dev:1141
vnd:4102+dev:1142
vnd:4102+dev:1152
vnd:4102+dev:1167
vnd:4102+dev:1151
vnd:4102+dev:2101
vnd:4102+dev:2105
vnd:4102+dev:2102
vnd:1006+dev:3004
vnd:4102+dev:1008
vnd:4102+dev:1122
vnd:1006+dev:4002
vnd:1006+dev:4003
vnd:4102+dev:1147
vnd:4102+dev:1113
vnd:4102+dev:1120
vnd:4102+dev:1117
vnd:4102+dev:1115
vnd:4102+dev:1114
vnd:4102+dev:1118
vnd:4102+dev:1119
vnd:4102+dev:1153
vnd:4102+dev:1134
vnd:1042+dev:1143
vnd:1e68+dev:1002
vnd:1e68+dev:1007
vnd:4102+dev:1116
vnd:4102+dev:1132
vnd:1f3a+dev:1007
vnd:0b20+dev:ddee
vnd:0979+dev:0227
vnd:2770+dev:905c
vnd:0979+dev:0227
vnd:2770+dev:9120
vnd:2931+dev:0a01
vnd:2931+dev:0a05
vnd:2931+dev:0a07
vnd:04f1+dev:6105
vnd:2970+dev:9039
vnd:0b28+dev:100c
vnd:2237+dev:d108
vnd:2237+dev:d109
vnd:2237+dev:b108
vnd:040a+dev:0617
vnd:040a+dev:060b
vnd:040a+dev:057e
vnd:040a+dev:058a
vnd:040a+dev:058c
vnd:040a+dev:058d
vnd:040a+dev:0589
vnd:040a+dev:05aa
vnd:040a+dev:059a
vnd:040a+dev:05a2
vnd:040a+dev:05b7
vnd:040a+dev:05ba
vnd:040a+dev:05a7
vnd:040a+dev:05af
vnd:040a+dev:05ae
vnd:040a+dev:05c3
vnd:040a+dev:05a9
vnd:040a+dev:05c6
vnd:040a+dev:059c
vnd:040a+dev:0560
vnd:040a+dev:0560
vnd:040a+dev:0535
vnd:040a+dev:0566
vnd:040a+dev:0566
vnd:040a+dev:0574
vnd:040a+dev:0573
vnd:040a+dev:0571
vnd:040a+dev:0584
vnd:040a+dev:0579
vnd:040a+dev:0578
vnd:040a+dev:0578
vnd:040a+dev:057a
vnd:040a+dev:057b
vnd:040a+dev:0586
vnd:040a+dev:057c
vnd:040a+dev:0120
vnd:040a+dev:0121
vnd:040a+dev:0130
vnd:040a+dev:0132
vnd:040a+dev:0160
vnd:040a+dev:0131
vnd:040a+dev:0525
vnd:040a+dev:0500
vnd:040a+dev:0510
vnd:040a+dev:0530
vnd:040a+dev:0170
vnd:040a+dev:0555
vnd:040a+dev:0576
vnd:040a+dev:0550
vnd:040a+dev:0570
vnd:040a+dev:0572
vnd:040a+dev:0575
vnd:040a+dev:057d
vnd:040a+dev:057f
vnd:040a+dev:0577
vnd:040a+dev:0540
vnd:040a+dev:0568
vnd:040a+dev:0569
vnd:040a+dev:0565
vnd:040a+dev:0567
vnd:040a+dev:05ce
vnd:040a+dev:0600
vnd:040a+dev:0665
vnd:040a+dev:059f
vnd:040a+dev:05c1
vnd:040a+dev:05ad
vnd:040a+dev:0585
vnd:040a+dev:0400
vnd:040a+dev:0592
vnd:040a+dev:0593
vnd:040a+dev:058e
vnd:040a+dev:058f
vnd:040a+dev:0591
vnd:040a+dev:05a0
vnd:040a+dev:05ac
vnd:040a+dev:05ab
vnd:040a+dev:05b8
vnd:040a+dev:059d
vnd:040a+dev:059e
vnd:040a+dev:0587
vnd:040a+dev:05b3
vnd:040a+dev:05b4
vnd:040a+dev:0580
vnd:040a+dev:0588
vnd:040a+dev:0403
vnd:040a+dev:05b5
vnd:040a+dev:0595
vnd:040a+dev:05cf
vnd:040a+dev:05cd
vnd:040a+dev:0613
vnd:040a+dev:05c0
vnd:132b+dev:0001
vnd:132b+dev:0019
vnd:132b+dev:0009
vnd:132b+dev:0007
vnd:132b+dev:0018
vnd:132b+dev:0022
vnd:132b+dev:0033
vnd:1f3a+dev:1006
vnd:0482+dev:09fc
vnd:0482+dev:0a73
vnd:0482+dev:0979
vnd:0482+dev:0a9a
vnd:0482+dev:0591
vnd:0482+dev:073c
vnd:0482+dev:085e
vnd:0482+dev:09cb
vnd:0482+dev:0810
vnd:0482+dev:0571
vnd:0482+dev:059a
vnd:2770+dev:9051
vnd:04da+dev:2375
vnd:1a98+dev:0002
vnd:1a98+dev:2376
vnd:04da+dev:2041
vnd:1a98+dev:2041
vnd:2b0e+dev:1714
vnd:2b0e+dev:171b
vnd:17ef+dev:789a
vnd:17ef+dev:789b
vnd:17ef+dev:7928
vnd:17ef+dev:7929
vnd:17ef+dev:7737
vnd:17ef+dev:7738
vnd:17ef+dev:772b
vnd:17ef+dev:772a
vnd:17ef+dev:7853
vnd:17ef+dev:7852
vnd:17ef+dev:7882
vnd:17ef+dev:7614
vnd:17ef+dev:7730
vnd:17ef+dev:7731
vnd:17ef+dev:7498
vnd:17ef+dev:7a18
vnd:17ef+dev:7a36
vnd:17ef+dev:75bc
vnd:17ef+dev:75be
vnd:17ef+dev:7542
vnd:17ef+dev:757d
vnd:17ef+dev:76e8
vnd:17ef+dev:740a
vnd:17ef+dev:7883
vnd:17ef+dev:7993
vnd:17ef+dev:7a2a
vnd:17ef+dev:75b5
vnd:17ef+dev:75b3
vnd:17ef+dev:7713
vnd:17ef+dev:778f
vnd:17ef+dev:7c6f
vnd:17ef+dev:775a
vnd:17ef+dev:78b0
vnd:17ef+dev:74cc
vnd:17ef+dev:9039
vnd:17ef+dev:7921
vnd:17ef+dev:7920
vnd:17ef+dev:7a36
vnd:17ef+dev:2008
vnd:17ef+dev:0c02
vnd:17ef+dev:7497
vnd:17ef+dev:74a6
vnd:17ef+dev:78d1
vnd:17ef+dev:7802
vnd:17ef+dev:74f8
vnd:17ef+dev:7718
vnd:17ef+dev:770a
vnd:17ef+dev:7a50
vnd:17ef+dev:7949
vnd:17ef+dev:78da
vnd:17ef+dev:79de
vnd:17ef+dev:7bdf
vnd:17ef+dev:7cb3
vnd:17ef+dev:7bd3
vnd:17ef+dev:7d4b
vnd:17ef+dev:77d8
vnd:17ef+dev:7b25
vnd:17ef+dev:7ac5
vnd:17ef+dev:7bc7
vnd:17ef+dev:7ad0
vnd:17ef+dev:7b3c
vnd:17ef+dev:7b84
vnd:17ef+dev:7a6b
vnd:17ef+dev:7c97
vnd:17ef+dev:7c45
vnd:17ef+dev:7c46
vnd:17ef+dev:79a2
vnd:17ef+dev:79de
vnd:17ef+dev:741c
vnd:17ef+dev:76f2
vnd:17ef+dev:79b7
vnd:17ef+dev:78f6
vnd:17ef+dev:74ee
vnd:17ef+dev:7999
vnd:17ef+dev:78fc
vnd:17ef+dev:78a7
vnd:17ef+dev:7902
vnd:17ef+dev:77ea
vnd:17ef+dev:79af
vnd:17ef+dev:7932
vnd:17ef+dev:76ff
vnd:17ef+dev:77a5
vnd:17ef+dev:77a4
vnd:17ef+dev:77b1
vnd:17ef+dev:795c
vnd:2b0e+dev:1704
vnd:2b0e+dev:1840
vnd:2b0e+dev:1844
vnd:2b0e+dev:1768
vnd:2b0e+dev:1778
vnd:2b0e+dev:1700
vnd:2b0e+dev:182c
vnd:2b0e+dev:1830
vnd:1004+dev:6263
vnd:1004+dev:61f1
vnd:1004+dev:61f9
vnd:1004+dev:6225
vnd:1004+dev:621c
vnd:1004+dev:627f
vnd:1004+dev:626e
vnd:1004+dev:611b
vnd:1004+dev:608f
vnd:1004+dev:6132
vnd:1004+dev:633e
vnd:1004+dev:633f
vnd:1004+dev:62ce
vnd:1004+dev:62c9
vnd:1004+dev:6259
vnd:1004+dev:6239
vnd:1004+dev:623d
vnd:1004+dev:622a
vnd:1004+dev:619a
vnd:043e+dev:7040
vnd:1004+dev:628a
vnd:043e+dev:70b1
vnd:1004+dev:631c
vnd:1004+dev:6265
vnd:1004+dev:6010
vnd:13d1+dev:7002
vnd:1c9e+dev:f003
vnd:2770+dev:9120
vnd:2ad9+dev:000b
vnd:066f+dev:846c
vnd:29e4+dev:1201
vnd:0e8d+dev:0050
vnd:0e8d+dev:201d
vnd:0e8d+dev:200a
vnd:0e8d+dev:2012
vnd:0e8d+dev:2008
vnd:0e8d+dev:4001
vnd:0408+dev:b00a
vnd:17ef+dev:7483
vnd:05ca+dev:2205
vnd:066f+dev:8550
vnd:066f+dev:8588
vnd:0408+dev:b009
vnd:17ef+dev:f003
vnd:17ef+dev:78ae
vnd:1271+dev:2012
vnd:201e+dev:42ab
vnd:2a45+dev:2008
vnd:2a45+dev:0c02
vnd:18d1+dev:d001
vnd:10d6+dev:2300
vnd:0db0+dev:5572
vnd:045e+dev:0640
vnd:045e+dev:0a00
vnd:045e+dev:0622
vnd:045e+dev:04ec
vnd:045e+dev:0710
vnd:045e+dev:063e
vnd:045e+dev:f0ca
vnd:045e+dev:00c9
vnd:045e+dev:0641
vnd:0c45+dev:8008
vnd:2770+dev:9120
vnd:2770+dev:9120
vnd:22b8+dev:60ca
vnd:22b8+dev:7088
vnd:22b8+dev:64cf
vnd:22b8+dev:2e32
vnd:22b8+dev:2e33
vnd:22b8+dev:2e67
vnd:22b8+dev:2ea5
vnd:22b8+dev:2e61
vnd:22b8+dev:2ea8
vnd:22b8+dev:2e68
vnd:22b8+dev:41d6
vnd:22b8+dev:41da
vnd:22b8+dev:42a7
vnd:22b8+dev:437f
vnd:22b8+dev:4373
vnd:22b8+dev:4811
vnd:22b8+dev:2dff
vnd:22b8+dev:41dc
vnd:22b8+dev:70ca
vnd:22b8+dev:2e76
vnd:22b8+dev:2e82
vnd:22b8+dev:2e84
vnd:22b8+dev:2ea4
vnd:22b8+dev:2e62
vnd:22b8+dev:2e63
vnd:22b8+dev:2e66
vnd:22b8+dev:2e81
vnd:22b8+dev:6413
vnd:22b8+dev:64b5
vnd:22b8+dev:64b6
vnd:22b8+dev:2e50
vnd:22b8+dev:2e51
vnd:22b8+dev:6415
vnd:22b8+dev:2a65
vnd:22b8+dev:2e24
vnd:22b8+dev:70a3
vnd:22b8+dev:70a8
vnd:22b8+dev:70a9
vnd:22b8+dev:4311
vnd:22b8+dev:4306
vnd:22b8+dev:41cf
vnd:22b8+dev:2e83
vnd:22b8+dev:002e
vnd:22b8+dev:710d
vnd:22b8+dev:710e
vnd:22b8+dev:4362
vnd:3310+dev:0100
vnd:0aa6+dev:9601
vnd:0409+dev:0326
vnd:0409+dev:0432
vnd:0409+dev:0242
vnd:1f85+dev:6a12
vnd:0402+dev:5668
vnd:2c3f+dev:0001
vnd:2770+dev:905c
vnd:04b0+dev:0302
vnd:04b0+dev:0117
vnd:04b0+dev:0116
vnd:04b0+dev:0122
vnd:04b0+dev:0123
vnd:04b0+dev:0109
vnd:04b0+dev:0108
vnd:04b0+dev:0115
vnd:04b0+dev:0121
vnd:04b0+dev:0111
vnd:04b0+dev:0110
vnd:04b0+dev:011d
vnd:04b0+dev:012d
vnd:04b0+dev:012c
vnd:04b0+dev:0204
vnd:04b0+dev:010f
vnd:04b0+dev:010e
vnd:04b0+dev:010b
vnd:04b0+dev:0130
vnd:04b0+dev:0131
vnd:04b0+dev:0129
vnd:04b0+dev:0113
vnd:04b0+dev:0206
vnd:04b0+dev:0119
vnd:04b0+dev:012e
vnd:04b0+dev:010d
vnd:04b0+dev:0135
vnd:04b0+dev:0139
vnd:04b0+dev:0137
vnd:04b0+dev:011f
vnd:04b0+dev:0103
vnd:04b0+dev:0127
vnd:04b0+dev:0112
vnd:04b0+dev:0191
vnd:04b0+dev:0102
vnd:04b0+dev:0104
vnd:04b0+dev:0226
vnd:04b0+dev:019e
vnd:04b0+dev:0188
vnd:04b0+dev:0194
vnd:04b0+dev:0198
vnd:04b0+dev:0362
vnd:04b0+dev:0231
vnd:04b0+dev:0208
vnd:04b0+dev:030b
vnd:04b0+dev:0174
vnd:04b0+dev:0309
vnd:04b0+dev:017e
vnd:04b0+dev:015f
vnd:04b0+dev:0185
vnd:04b0+dev:0315
vnd:04b0+dev:0318
vnd:04b0+dev:0317
vnd:04b0+dev:0324
vnd:04b0+dev:0343
vnd:04b0+dev:0361
vnd:04b0+dev:0305
vnd:04b0+dev:032f
vnd:04b0+dev:0192
vnd:04b0+dev:035a
vnd:04b0+dev:0140
vnd:04b0+dev:017d
vnd:04b0+dev:0232
vnd:04b0+dev:0142
vnd:04b0+dev:0221
vnd:04b0+dev:0227
vnd:04b0+dev:020c
vnd:04b0+dev:0169
vnd:04b0+dev:0184
vnd:04b0+dev:015b
vnd:04b0+dev:0223
vnd:04b0+dev:0163
vnd:04b0+dev:0228
vnd:04b0+dev:0311
vnd:04b0+dev:016f
vnd:04b0+dev:017f
vnd:04b0+dev:018b
vnd:04b0+dev:0225
vnd:04b0+dev:0229
vnd:04b0+dev:016b
vnd:04b0+dev:016c
vnd:04b0+dev:0173
vnd:04b0+dev:019c
vnd:04b0+dev:0337
vnd:04b0+dev:0346
vnd:04b0+dev:014e
vnd:04b0+dev:0161
vnd:04b0+dev:0177
vnd:04b0+dev:0178
vnd:04b0+dev:0321
vnd:04b0+dev:032d
vnd:04b0+dev:033f
vnd:04b0+dev:035e
vnd:04b0+dev:031b
vnd:04b0+dev:0320
vnd:04b0+dev:0334
vnd:04b0+dev:032a
vnd:04b0+dev:0353
vnd:04b0+dev:035c
vnd:04b0+dev:0144
vnd:04b0+dev:0329
vnd:04b0+dev:015d
vnd:04b0+dev:0220
vnd:04b0+dev:014e
vnd:04b0+dev:0171
vnd:04b0+dev:021e
vnd:04b0+dev:021c
vnd:04b0+dev:032c
vnd:04b0+dev:0350
vnd:04b0+dev:0157
vnd:04b0+dev:021f
vnd:04b0+dev:0222
vnd:04b0+dev:0186
vnd:04b0+dev:0193
vnd:04b0+dev:034b
vnd:04b0+dev:0202
vnd:04b0+dev:0401
vnd:04b0+dev:0404
vnd:04b0+dev:040c
vnd:04b0+dev:0408
vnd:04b0+dev:041c
vnd:04b0+dev:040a
vnd:04b0+dev:0402
vnd:04b0+dev:0410
vnd:04b0+dev:0416
vnd:04b0+dev:041a
vnd:04b0+dev:0424
vnd:04b0+dev:0425
vnd:04b0+dev:0427
vnd:04b0+dev:042c
vnd:04b0+dev:0433
vnd:04b0+dev:043d
vnd:04b0+dev:0445
vnd:04b0+dev:0426
vnd:04b0+dev:0420
vnd:04b0+dev:042b
vnd:04b0+dev:0414
vnd:04b0+dev:0418
vnd:04b0+dev:0435
vnd:04b0+dev:043a
vnd:04b0+dev:043c
vnd:04b0+dev:0423
vnd:04b0+dev:0429
vnd:04b0+dev:042f
vnd:04b0+dev:0431
vnd:04b0+dev:0438
vnd:04b0+dev:043f
vnd:04b0+dev:0447
vnd:04b0+dev:041e
vnd:04b0+dev:042d
vnd:04b0+dev:0434
vnd:04b0+dev:0406
vnd:04b0+dev:0422
vnd:04b0+dev:0428
vnd:04b0+dev:040e
vnd:04b0+dev:0430
vnd:04b0+dev:0439
vnd:04b0+dev:0437
vnd:04b0+dev:0440
vnd:04b0+dev:0446
vnd:04b0+dev:0412
vnd:04b0+dev:042a
vnd:04b0+dev:042e
vnd:04b0+dev:0436
vnd:04b0+dev:043b
vnd:04b0+dev:0441
vnd:04b0+dev:0421
vnd:04b0+dev:0432
vnd:04b0+dev:0602
vnd:04b0+dev:0603
vnd:04b0+dev:0605
vnd:04b0+dev:0609
vnd:04b0+dev:060b
vnd:04b0+dev:0364
vnd:04b0+dev:019f
vnd:04b0+dev:036d
vnd:04b0+dev:0606
vnd:04b0+dev:0608
vnd:04b0+dev:0601
vnd:04b0+dev:0604
vnd:04b0+dev:060a
vnd:04b0+dev:0452
vnd:04b0+dev:0448
vnd:04b0+dev:0444
vnd:04b0+dev:0443
vnd:04b0+dev:044c
vnd:04b0+dev:0442
vnd:04b0+dev:044b
vnd:04b0+dev:0451
vnd:04b0+dev:0450
vnd:04b0+dev:044f
vnd:057e+dev:201d
vnd:16c0+dev:0489
vnd:0979+dev:0224
vnd:0421+dev:02c1
vnd:0421+dev:0065
vnd:0421+dev:005f
vnd:0421+dev:0462
vnd:0421+dev:01ee
vnd:0421+dev:05c0
vnd:0421+dev:0209
vnd:0421+dev:04be
vnd:0421+dev:02e2
vnd:0421+dev:04ba
vnd:0421+dev:006c
vnd:0421+dev:00ea
vnd:0421+dev:047e
vnd:0421+dev:0229
vnd:0421+dev:04b4
vnd:0421+dev:0154
vnd:0421+dev:0155
vnd:0421+dev:0159
vnd:2e04+dev:c025
vnd:2e04+dev:c026
vnd:2e04+dev:c02a
vnd:0421+dev:002e
vnd:0421+dev:0098
vnd:0421+dev:008d
vnd:0421+dev:003c
vnd:0421+dev:0297
vnd:0421+dev:0530
vnd:0421+dev:05d3
vnd:0421+dev:0592
vnd:0421+dev:0595
vnd:0421+dev:03c1
vnd:0421+dev:03cd
vnd:0421+dev:01cf
vnd:0421+dev:032f
vnd:0421+dev:0179
vnd:0421+dev:00e5
vnd:0421+dev:0334
vnd:0421+dev:0335
vnd:0421+dev:00e4
vnd:0421+dev:01a1
vnd:0421+dev:0221
vnd:0421+dev:06fc
vnd:0421+dev:0666
vnd:0421+dev:0661
vnd:0421+dev:0524
vnd:0421+dev:0488
vnd:0421+dev:04d1
vnd:0421+dev:04e1
vnd:0421+dev:0079
vnd:0421+dev:0186
vnd:0421+dev:02fe
vnd:0421+dev:0302
vnd:0421+dev:04f1
vnd:0421+dev:000a
vnd:0421+dev:0074
vnd:0421+dev:0092
vnd:0421+dev:051a
vnd:0421+dev:0485
vnd:0421+dev:0478
vnd:0421+dev:04e5
vnd:0421+dev:04ef
vnd:0421+dev:006e
vnd:0421+dev:03d2
vnd:0421+dev:0039
vnd:0421+dev:01f5
vnd:0421+dev:026b
vnd:0421+dev:01f4
vnd:0421+dev:0708
vnd:0421+dev:0274
vnd:0421+dev:06e8
vnd:18d1+dev:685c
vnd:1703+dev:0001
vnd:1703+dev:0002
vnd:1e0a+dev:1001
vnd:0955+dev:70a9
vnd:0955+dev:7721
vnd:0955+dev:b401
vnd:0955+dev:b400
vnd:0955+dev:b42a
vnd:0955+dev:cf07
vnd:0955+dev:cf05
vnd:0955+dev:cf02
vnd:0955+dev:7100
vnd:0955+dev:7102
vnd:0746+dev:a003
vnd:1e53+dev:0006
vnd:2833+dev:0183
vnd:2833+dev:0182
vnd:07b4+dev:0105
vnd:07b4+dev:0100
vnd:07b4+dev:0100
vnd:07b4+dev:0105
vnd:07b4+dev:0100
vnd:07b4+dev:0105
vnd:07b4+dev:0114
vnd:07b4+dev:0114
vnd:07b4+dev:0109
vnd:07b4+dev:0105
vnd:07b4+dev:0105
vnd:07b4+dev:0114
vnd:07b4+dev:0114
vnd:07b4+dev:0105
vnd:07b4+dev:0105
vnd:07b4+dev:0105
vnd:07b4+dev:0109
vnd:07b4+dev:0114
vnd:07b4+dev:0114
vnd:07b4+dev:0110
vnd:07b4+dev:0130
vnd:07b4+dev:0130
vnd:07b4+dev:0135
vnd:07b4+dev:012f
vnd:07b4+dev:0130
vnd:07b4+dev:012f
vnd:07b4+dev:0109
vnd:07b4+dev:0116
vnd:07b4+dev:0114
vnd:07b4+dev:0113
vnd:07b4+dev:0136
vnd:07b4+dev:0109
vnd:07b4+dev:012f
vnd:07b4+dev:0125
vnd:07b4+dev:0116
vnd:07b4+dev:0114
vnd:07b4+dev:0114
vnd:07b4+dev:0109
vnd:07b4+dev:0116
vnd:07b4+dev:0116
vnd:2a70+dev:9011
vnd:2a70+dev:f003
vnd:05c6+dev:f000
vnd:2a70+dev:9012
vnd:2207+dev:000c
vnd:2207+dev:000d
vnd:2207+dev:0014
vnd:2207+dev:0015
vnd:22d9+dev:2764
vnd:22d9+dev:2765
vnd:22d9+dev:2774
vnd:22d9+dev:2773
vnd:2836+dev:0010
vnd:04da+dev:2382
vnd:04da+dev:2374
vnd:04da+dev:2374
vnd:04da+dev:2374
vnd:04da+dev:2374
vnd:04da+dev:2374
vnd:04da+dev:2374
vnd:04da+dev:2374
vnd:04da+dev:2374
vnd:04da+dev:2374
vnd:04da+dev:2374
vnd:04da+dev:2374
vnd:04da+dev:2374
vnd:04da+dev:2374
vnd:04da+dev:2145
vnd:04da+dev:2158
vnd:106c+dev:f003
vnd:19cf+dev:5038
vnd:19cf+dev:5039
vnd:1d4d+dev:5036
vnd:1d4d+dev:5035
vnd:1d4d+dev:504a
vnd:25fb+dev:0130
vnd:25fb+dev:0178
vnd:25fb+dev:0179
vnd:0a17+dev:0070
vnd:0a17+dev:00a1
vnd:0a17+dev:006e
vnd:25fb+dev:0183
vnd:0a17+dev:0093
vnd:0a17+dev:0091
vnd:25fb+dev:0164
vnd:25fb+dev:0165
vnd:25fb+dev:017b
vnd:25fb+dev:0132
vnd:25fb+dev:017a
vnd:25fb+dev:0189
vnd:25fb+dev:0160
vnd:25fb+dev:0102
vnd:25fb+dev:0148
vnd:25fb+dev:014a
vnd:25fb+dev:017c
vnd:25fb+dev:017d
vnd:25fb+dev:017e
vnd:25fb+dev:017f
vnd:0a17+dev:0009
vnd:0a17+dev:000d
vnd:0a17+dev:0007
vnd:0a17+dev:00f7
vnd:0aa6+dev:9702
vnd:0471+dev:207c
vnd:0471+dev:20b9
vnd:0471+dev:2138
vnd:0471+dev:0165
vnd:0471+dev:2077
vnd:0471+dev:208e
vnd:0471+dev:2004
vnd:0471+dev:0857
vnd:0471+dev:084e
vnd:0471+dev:2002
vnd:0471+dev:014f
vnd:0471+dev:2075
vnd:0471+dev:207b
vnd:0471+dev:20b7
vnd:0471+dev:20e5
vnd:0471+dev:014d
vnd:0471+dev:014c
vnd:0471+dev:01eb
vnd:0471+dev:014b
vnd:0471+dev:190b
vnd:093a+dev:010e
vnd:0471+dev:2190
vnd:0471+dev:7e01
vnd:0471+dev:0181
vnd:0471+dev:0164
vnd:0471+dev:2022
vnd:0471+dev:0172
vnd:0471+dev:2008
vnd:08e4+dev:0142
vnd:0746+dev:a023
vnd:08e4+dev:0148
vnd:093a+dev:010e
vnd:2770+dev:905c
vnd:18dd+dev:1000
vnd:2770+dev:9120
vnd:0546+dev:2035
vnd:0546+dev:0daf
vnd:2770+dev:905c
vnd:2770+dev:9120
vnd:093a+dev:010f
vnd:29e4+dev:3201
vnd:29e4+dev:1203
vnd:29e4+dev:1103
vnd:29e4+dev:b003
vnd:29e4+dev:b001
vnd:46f4+dev:0004
vnd:0e8d+dev:2026
vnd:05c6+dev:8800
vnd:05c6+dev:0229
vnd:05c6+dev:3196
vnd:05c6+dev:6764
vnd:05c6+dev:6765
vnd:05c6+dev:f003
vnd:05c6+dev:9039
vnd:05c6+dev:9025
vnd:05c6+dev:901b
vnd:22d9+dev:202a
vnd:2523+dev:d209
vnd:2523+dev:d109
vnd:2717+dev:1260
vnd:2717+dev:1268
vnd:2770+dev:9120
vnd:05ca+dev:220b
vnd:05ca+dev:2203
vnd:05ca+dev:2204
vnd:05ca+dev:2208
vnd:05ca+dev:220c
vnd:05ca+dev:0325
vnd:05ca+dev:2214
vnd:05ca+dev:032d
vnd:05ca+dev:220d
vnd:05ca+dev:2212
vnd:05ca+dev:032b
vnd:05ca+dev:2213
vnd:05ca+dev:2216
vnd:05ca+dev:032f
vnd:05ca+dev:2217
vnd:05ca+dev:221a
vnd:05ca+dev:0110
vnd:05ca+dev:2202
vnd:05ca+dev:033d
vnd:05ca+dev:220d
vnd:25fb+dev:25fb
vnd:05ca+dev:0365
vnd:05ca+dev:0366
vnd:05ca+dev:0367
vnd:05ca+dev:0368
vnd:05ca+dev:0368
vnd:05ca+dev:036d
vnd:05ca+dev:036d
vnd:25fb+dev:210b
vnd:0fca+dev:8007
vnd:05ca+dev:220f
vnd:05ca+dev:220f
vnd:2770+dev:913d
vnd:2770+dev:913d
vnd:2770+dev:913d
vnd:0979+dev:0227
vnd:0c45+dev:8003
vnd:0c45+dev:8003
vnd:0c45+dev:8003
vnd:093a+dev:010e
vnd:093a+dev:010f
vnd:0979+dev:0227
vnd:0979+dev:0227
vnd:2770+dev:9120
vnd:0979+dev:0227
vnd:2770+dev:905c
vnd:0979+dev:0227
vnd:093a+dev:010f
vnd:0979+dev:0227
vnd:0979+dev:0227
vnd:0979+dev:0227
vnd:0979+dev:0227
vnd:0979+dev:0227
vnd:0979+dev:0227
vnd:04e8+dev:6866
vnd:04e8+dev:6727
vnd:04e8+dev:6860
vnd:04e8+dev:685c
vnd:04e8+dev:6877
vnd:04e8+dev:6752
vnd:04e8+dev:68af
vnd:04e8+dev:e20c
vnd:04e8+dev:6819
vnd:04e8+dev:04a4
vnd:04e8+dev:4f1f
vnd:04e8+dev:6734
vnd:04e8+dev:6642
vnd:04e8+dev:140c
vnd:04e8+dev:1384
vnd:04e8+dev:684a
vnd:04e8+dev:6763
vnd:04e8+dev:6709
vnd:04e8+dev:68a9
vnd:04e8+dev:6702
vnd:04e8+dev:502e
vnd:04e8+dev:501d
vnd:04e8+dev:5022
vnd:04e8+dev:502f
vnd:04e8+dev:5024
vnd:04e8+dev:5a0f
vnd:04e8+dev:5033
vnd:04e8+dev:0409
vnd:04e8+dev:5057
vnd:04e8+dev:5081
vnd:04e8+dev:505a
vnd:04e8+dev:5118
vnd:04e8+dev:5083
vnd:04e8+dev:511a
vnd:04e8+dev:5115
vnd:04e8+dev:511d
vnd:04e8+dev:5130
vnd:04e8+dev:5125
vnd:04e8+dev:510f
vnd:04e8+dev:512e
vnd:04e8+dev:5091
vnd:04e8+dev:508b
vnd:04e8+dev:508a
vnd:04e8+dev:5047
vnd:04e8+dev:507f
vnd:04e8+dev:5054
vnd:04e8+dev:507d
vnd:04e8+dev:5093
vnd:04e8+dev:5121
vnd:04e8+dev:5137
vnd:04e8+dev:503c
vnd:0781+dev:7410
vnd:0781+dev:7450
vnd:0781+dev:7452
vnd:0781+dev:7432
vnd:0781+dev:7434
vnd:0781+dev:74e4
vnd:0781+dev:74d0
vnd:0781+dev:7480
vnd:0781+dev:7420
vnd:0781+dev:7422
vnd:0781+dev:7460
vnd:0781+dev:74c0
vnd:0781+dev:74c2
vnd:0781+dev:74e0
vnd:0781+dev:7401
vnd:0781+dev:7400
vnd:0781+dev:7430
vnd:0781+dev:74b0
vnd:0474+dev:0230
vnd:0474+dev:02e5
vnd:05ca+dev:0353
vnd:05ca+dev:220e
vnd:05ca+dev:0327
vnd:2770+dev:9120
vnd:2770+dev:9120
vnd:2770+dev:9120
vnd:04dd+dev:9c90
vnd:04dd+dev:9d6e
vnd:04dd+dev:9661
vnd:04dd+dev:96ca
vnd:0489+dev:c025
vnd:04dd+dev:99d2
vnd:3360+dev:2008
vnd:093a+dev:010e
vnd:1003+dev:c432
vnd:1003+dev:c442
vnd:066f+dev:a010
vnd:18f6+dev:0102
vnd:18f6+dev:0110
vnd:1bdc+dev:fabf
vnd:054c+dev:0e78
vnd:054c+dev:074e
vnd:054c+dev:07c6
vnd:054c+dev:0957
vnd:054c+dev:08e7
vnd:054c+dev:094e
vnd:054c+dev:08b7
vnd:054c+dev:0d13
vnd:054c+dev:0d14
vnd:054c+dev:079c
vnd:054c+dev:077a
vnd:054c+dev:0784
vnd:054c+dev:07a4
vnd:054c+dev:0d0f
vnd:054c+dev:0d10
vnd:054c+dev:079b
vnd:054c+dev:0779
vnd:054c+dev:094c
vnd:054c+dev:0c03
vnd:054c+dev:0c34
vnd:054c+dev:0da6
vnd:054c+dev:0da7
vnd:054c+dev:0953
vnd:054c+dev:096f
vnd:054c+dev:094d
vnd:054c+dev:0a6b
vnd:054c+dev:0c00
vnd:054c+dev:0c33
vnd:054c+dev:0954
vnd:054c+dev:08e2
vnd:054c+dev:0a71
vnd:054c+dev:0c2a
vnd:054c+dev:079e
vnd:054c+dev:0c2f
vnd:054c+dev:0a70
vnd:054c+dev:1294
vnd:054c+dev:0ca6
vnd:054c+dev:02c0
vnd:054c+dev:0ccc
vnd:054c+dev:0d18
vnd:054c+dev:0d17
vnd:054c+dev:02e7
vnd:054c+dev:004e
vnd:054c+dev:004e
vnd:054c+dev:004e
vnd:054c+dev:004e
vnd:054c+dev:004e
vnd:054c+dev:004e
vnd:054c+dev:0543
vnd:054c+dev:061f
vnd:054c+dev:061c
vnd:054c+dev:06ee
vnd:054c+dev:08ac
vnd:054c+dev:0491
vnd:054c+dev:08ad
vnd:054c+dev:0780
vnd:054c+dev:09e8
vnd:054c+dev:004e
vnd:054c+dev:004e
vnd:054c+dev:004e
vnd:054c+dev:004e
vnd:054c+dev:004e
vnd:054c+dev:004e
vnd:054c+dev:004e
vnd:054c+dev:004e
vnd:054c+dev:004e
vnd:054c+dev:004e
vnd:054c+dev:004e
vnd:054c+dev:004e
vnd:054c+dev:004e
vnd:054c+dev:004e
vnd:054c+dev:004e
vnd:054c+dev:004e
vnd:054c+dev:004e
vnd:054c+dev:004e
vnd:054c+dev:004e
vnd:054c+dev:0a77
vnd:054c+dev:004e
vnd:054c+dev:0bfd
vnd:054c+dev:0c32
vnd:054c+dev:052b
vnd:054c+dev:052a
vnd:054c+dev:074b
vnd:054c+dev:0a6d
vnd:054c+dev:07a3
vnd:054c+dev:0cb1
vnd:054c+dev:0cb2
vnd:054c+dev:0830
vnd:054c+dev:0c38
vnd:054c+dev:0cae
vnd:054c+dev:07a3
vnd:054c+dev:079d
vnd:054c+dev:004e
vnd:054c+dev:004e
vnd:054c+dev:0296
vnd:054c+dev:004e
vnd:054c+dev:0296
vnd:054c+dev:004e
vnd:054c+dev:004e
vnd:054c+dev:004e
vnd:054c+dev:004e
vnd:054c+dev:004e
vnd:054c+dev:004e
vnd:054c+dev:004e
vnd:054c+dev:004e
vnd:054c+dev:004e
vnd:054c+dev:0343
vnd:054c+dev:02f8
vnd:054c+dev:004e
vnd:054c+dev:053c
vnd:054c+dev:004e
vnd:054c+dev:08d7
vnd:054c+dev:08b0
vnd:054c+dev:0603
vnd:054c+dev:05f7
vnd:054c+dev:0d1c
vnd:054c+dev:0caa
vnd:054c+dev:0d2b
vnd:054c+dev:0a6a
vnd:054c+dev:09e7
vnd:054c+dev:0d9b
vnd:054c+dev:0d9f
vnd:054c+dev:0e0c
vnd:054c+dev:0da3
vnd:0fce+dev:5175
vnd:0fce+dev:a175
vnd:0fce+dev:b175
vnd:0fce+dev:0172
vnd:0fce+dev:5172
vnd:0fce+dev:4172
vnd:0fce+dev:0186
vnd:0fce+dev:5186
vnd:0fce+dev:4186
vnd:0fce+dev:0169
vnd:0fce+dev:5169
vnd:0fce+dev:4169
vnd:0fce+dev:0175
vnd:0fce+dev:4175
vnd:0fce+dev:0176
vnd:0fce+dev:4176
vnd:0fce+dev:0177
vnd:0fce+dev:5177
vnd:0fce+dev:4177
vnd:0fce+dev:a177
vnd:0fce+dev:b177
vnd:0fce+dev:0178
vnd:0fce+dev:5178
vnd:0fce+dev:4178
vnd:0fce+dev:0182
vnd:0fce+dev:5182
vnd:0fce+dev:4182
vnd:0fce+dev:0173
vnd:0fce+dev:5173
vnd:0fce+dev:4173
vnd:0fce+dev:a173
vnd:0fce+dev:b173
vnd:054c+dev:004e
vnd:054c+dev:004e
vnd:054c+dev:072f
vnd:054c+dev:066f
vnd:054c+dev:0678
vnd:054c+dev:057d
vnd:054c+dev:04a5
vnd:054c+dev:0d00
vnd:054c+dev:0e6e
vnd:054c+dev:0c71
vnd:054c+dev:0d01
vnd:054c+dev:035c
vnd:054c+dev:0325
vnd:054c+dev:035b
vnd:054c+dev:0404
vnd:054c+dev:036e
vnd:054c+dev:03d8
vnd:054c+dev:04be
vnd:054c+dev:059a
vnd:054c+dev:0689
vnd:054c+dev:03fc
vnd:054c+dev:04cb
vnd:054c+dev:0882
vnd:054c+dev:0385
vnd:054c+dev:03fd
vnd:054c+dev:05a6
vnd:054c+dev:06a9
vnd:054c+dev:0326
vnd:054c+dev:03fe
vnd:054c+dev:0327
vnd:054c+dev:038e
vnd:054c+dev:035a
vnd:054c+dev:038c
vnd:054c+dev:04cc
vnd:054c+dev:05a8
vnd:054c+dev:0388
vnd:054c+dev:04bb
vnd:054c+dev:0397
vnd:054c+dev:0398
vnd:054c+dev:004e
vnd:054c+dev:08e3
vnd:054c+dev:04a7
vnd:054c+dev:0321
vnd:054c+dev:0669
vnd:054c+dev:04a3
vnd:054c+dev:0669
vnd:054c+dev:0736
vnd:054c+dev:0737
vnd:054c+dev:0574
vnd:054c+dev:0577
vnd:054c+dev:0675
vnd:0fce+dev:5176
vnd:0fce+dev:a176
vnd:0fce+dev:b176
vnd:0fce+dev:0181
vnd:0fce+dev:5181
vnd:0fce+dev:4181
vnd:054c+dev:04d1
vnd:054c+dev:05b3
vnd:054c+dev:05b4
vnd:0fce+dev:0171
vnd:0fce+dev:0170
vnd:0fce+dev:5170
vnd:0fce+dev:4170
vnd:0fce+dev:0180
vnd:0fce+dev:5180
vnd:0fce+dev:4180
vnd:0fce+dev:5171
vnd:0fce+dev:4171
vnd:0fce+dev:017e
vnd:0fce+dev:517e
vnd:0fce+dev:417e
vnd:0fce+dev:a17e
vnd:0fce+dev:b17e
vnd:054c+dev:0a79
vnd:0fce+dev:016d
vnd:0fce+dev:0205
vnd:0fce+dev:5205
vnd:0fce+dev:4205
vnd:0fce+dev:0201
vnd:0fce+dev:5201
vnd:0fce+dev:4201
vnd:0fce+dev:020a
vnd:0fce+dev:020d
vnd:0fce+dev:520d
vnd:0fce+dev:420d
vnd:0fce+dev:520a
vnd:0fce+dev:420a
vnd:0fce+dev:0198
vnd:0fce+dev:5198
vnd:0fce+dev:01a3
vnd:0fce+dev:51a3
vnd:0fce+dev:41a3
vnd:0fce+dev:01d2
vnd:0fce+dev:51d2
vnd:0fce+dev:41d2
vnd:0fce+dev:018c
vnd:0fce+dev:518c
vnd:0fce+dev:418c
vnd:0fce+dev:01b5
vnd:0fce+dev:51b5
vnd:0fce+dev:41b5
vnd:0fce+dev:01bc
vnd:0fce+dev:51bc
vnd:0fce+dev:41bc
vnd:0fce+dev:01c5
vnd:0fce+dev:51c5
vnd:0fce+dev:41c5
vnd:0fce+dev:01cb
vnd:0fce+dev:51cb
vnd:0fce+dev:41cb
vnd:0fce+dev:0188
vnd:0fce+dev:5188
vnd:0fce+dev:4188
vnd:0fce+dev:0192
vnd:0fce+dev:5192
vnd:0fce+dev:4192
vnd:0fce+dev:01f6
vnd:0fce+dev:51f6
vnd:0fce+dev:41f6
vnd:0fce+dev:0207
vnd:0fce+dev:5207
vnd:0fce+dev:4207
vnd:0fce+dev:019b
vnd:0fce+dev:519b
vnd:0fce+dev:419b
vnd:0fce+dev:01b8
vnd:0fce+dev:51b8
vnd:0fce+dev:41b8
vnd:0fce+dev:01ab
vnd:0fce+dev:51ab
vnd:0fce+dev:41ab
vnd:0fce+dev:01aa
vnd:0fce+dev:51aa
vnd:0fce+dev:41aa
vnd:0fce+dev:01c4
vnd:0fce+dev:51c4
vnd:0fce+dev:41c4
vnd:0fce+dev:01d6
vnd:0fce+dev:51d6
vnd:0fce+dev:41d6
vnd:0fce+dev:01e1
vnd:0fce+dev:51e1
vnd:0fce+dev:41e1
vnd:0fce+dev:0195
vnd:0fce+dev:5195
vnd:0fce+dev:4195
vnd:0fce+dev:01a9
vnd:0fce+dev:51a9
vnd:0fce+dev:41a9
vnd:054c+dev:06ac
vnd:0fce+dev:018d
vnd:0fce+dev:0194
vnd:0fce+dev:518d
vnd:0fce+dev:5194
vnd:0fce+dev:418d
vnd:0fce+dev:4194
vnd:0fce+dev:01e8
vnd:0fce+dev:51e8
vnd:0fce+dev:41e8
vnd:0fce+dev:01e0
vnd:0fce+dev:51e0
vnd:0fce+dev:41e0
vnd:0fce+dev:01de
vnd:0fce+dev:51de
vnd:0fce+dev:41de
vnd:0fce+dev:01eb
vnd:0fce+dev:51eb
vnd:0fce+dev:41eb
vnd:0fce+dev:01ef
vnd:0fce+dev:51ef
vnd:0fce+dev:41ef
vnd:0fce+dev:0a07
vnd:0fce+dev:01f7
vnd:0fce+dev:51f7
vnd:0fce+dev:41f7
vnd:0fce+dev:01f8
vnd:0fce+dev:51f8
vnd:0fce+dev:41f8
vnd:0fce+dev:01ed
vnd:0fce+dev:51ed
vnd:0fce+dev:41ed
vnd:0fce+dev:01e7
vnd:0fce+dev:51e7
vnd:0fce+dev:41e7
vnd:0fce+dev:01f1
vnd:0fce+dev:51f1
vnd:0fce+dev:41f1
vnd:0fce+dev:01f3
vnd:0fce+dev:51f3
vnd:0fce+dev:01f4
vnd:0fce+dev:51f4
vnd:0fce+dev:41f4
vnd:0fce+dev:41f3
vnd:0fce+dev:01fa
vnd:0fce+dev:51fa
vnd:0fce+dev:41fa
vnd:0fce+dev:01f9
vnd:0fce+dev:51f9
vnd:0fce+dev:41f9
vnd:0fce+dev:01fb
vnd:0fce+dev:51fb
vnd:0fce+dev:41fb
vnd:0fce+dev:01ff
vnd:0fce+dev:51ff
vnd:0fce+dev:41ff
vnd:0fce+dev:0193
vnd:0fce+dev:5193
vnd:0fce+dev:4193
vnd:0fce+dev:01b6
vnd:0fce+dev:0196
vnd:0fce+dev:019c
vnd:0fce+dev:51b6
vnd:0fce+dev:5196
vnd:0fce+dev:519c
vnd:0fce+dev:41b6
vnd:0fce+dev:419c
vnd:0fce+dev:01a7
vnd:0fce+dev:41a7
vnd:0fce+dev:51a7
vnd:0fce+dev:019e
vnd:0fce+dev:519e
vnd:0fce+dev:419e
vnd:0fce+dev:01af
vnd:0fce+dev:51af
vnd:0fce+dev:41af
vnd:0fce+dev:01b1
vnd:0fce+dev:51b1
vnd:0fce+dev:41b1
vnd:0fce+dev:01bb
vnd:0fce+dev:51bb
vnd:0fce+dev:41bb
vnd:0fce+dev:01ba
vnd:0fce+dev:51ba
vnd:0fce+dev:41ba
vnd:0fce+dev:01c0
vnd:0fce+dev:51c0
vnd:0fce+dev:41c0
vnd:0fce+dev:01c9
vnd:0fce+dev:51c9
vnd:0fce+dev:41c9
vnd:0fce+dev:01b0
vnd:0fce+dev:51b0
vnd:0fce+dev:41b0
vnd:0fce+dev:01da
vnd:0fce+dev:51da
vnd:0fce+dev:41da
vnd:0fce+dev:01d9
vnd:0fce+dev:51d9
vnd:0fce+dev:41d9
vnd:0fce+dev:01db
vnd:0fce+dev:51db
vnd:0fce+dev:41db
vnd:0fce+dev:0189
vnd:0fce+dev:5189
vnd:0fce+dev:4189
vnd:0fce+dev:0197
vnd:0fce+dev:5197
vnd:054c+dev:0c1b
vnd:054c+dev:0c44
vnd:054c+dev:0d97
vnd:054c+dev:0de3
vnd:0fce+dev:00d9
vnd:0fce+dev:00d4
vnd:0fce+dev:00ef
vnd:0fce+dev:0157
vnd:0fce+dev:5157
vnd:0fce+dev:4157
vnd:0fce+dev:014e
vnd:0fce+dev:d144
vnd:0fce+dev:0144
vnd:0fce+dev:e000
vnd:0fce+dev:0075
vnd:0fce+dev:514f
vnd:0fce+dev:014f
vnd:0fce+dev:015a
vnd:0fce+dev:515a
vnd:0fce+dev:0156
vnd:0fce+dev:5156
vnd:0fce+dev:015d
vnd:0fce+dev:515d
vnd:0fce+dev:0166
vnd:0fce+dev:5166
vnd:0fce+dev:0167
vnd:0fce+dev:5167
vnd:0fce+dev:0168
vnd:0fce+dev:5168
vnd:0fce+dev:4168
vnd:0fce+dev:0161
vnd:0fce+dev:5161
vnd:0fce+dev:00fb
vnd:0fce+dev:0133
vnd:0fce+dev:013a
vnd:0fce+dev:10c8
vnd:0fce+dev:00f3
vnd:0fce+dev:0105
vnd:0fce+dev:00c6
vnd:0fce+dev:00b3
vnd:0fce+dev:00f5
vnd:0fce+dev:0076
vnd:0fce+dev:00da
vnd:0fce+dev:0112
vnd:0fce+dev:516d
vnd:0fce+dev:0146
vnd:0fce+dev:5146
vnd:2770+dev:905c
vnd:1782+dev:4001
vnd:1782+dev:4002
vnd:1782+dev:4003
vnd:2770+dev:9120
vnd:1403+dev:0001
vnd:2770+dev:905c
vnd:2207+dev:0031
vnd:2770+dev:913d
vnd:2770+dev:9120
vnd:0451+dev:d108
vnd:13d1+dev:7017
vnd:2367+dev:0102
vnd:0aa6+dev:3011
vnd:069b+dev:3035
vnd:069b+dev:0777
vnd:069b+dev:0774
vnd:069b+dev:077c
vnd:069b+dev:301a
vnd:069b+dev:3028
vnd:4173+dev:8000
vnd:1f85+dev:6056
vnd:1390+dev:5455
vnd:11db+dev:1000
vnd:0930+dev:0960
vnd:0930+dev:0963
vnd:0930+dev:000c
vnd:0930+dev:0009
vnd:0930+dev:001d
vnd:0930+dev:001a
vnd:0930+dev:0018
vnd:0930+dev:0011
vnd:0930+dev:000f
vnd:0930+dev:0010
vnd:0930+dev:0019
vnd:0930+dev:0016
vnd:0930+dev:0014
vnd:1132+dev:4332
vnd:1132+dev:4335
vnd:1132+dev:4334
vnd:0930+dev:7100
vnd:2357+dev:0314
vnd:2357+dev:031a
vnd:2357+dev:033c
vnd:2357+dev:0328
vnd:2357+dev:0320
vnd:2357+dev:038c
vnd:0168+dev:3011
vnd:1e68+dev:0002
vnd:0402+dev:0611
vnd:1e68+dev:1045
vnd:066f+dev:842a
vnd:08ca+dev:0110
vnd:2207+dev:000b
vnd:2207+dev:0001
vnd:2207+dev:0011
vnd:10a9+dev:1105
vnd:0408+dev:3899
vnd:2770+dev:9120
vnd:2770+dev:9120
vnd:0979+dev:0227
vnd:093a+dev:010e
vnd:093a+dev:010f
vnd:0c45+dev:800a
vnd:2770+dev:905c
vnd:2d95+dev:6002
vnd:2d95+dev:6003
vnd:0e8d+dev:ff00
vnd:0f88+dev:0684
vnd:0531+dev:2001
vnd:0c45+dev:8001
vnd:2970+dev:201d
vnd:2970+dev:2281
vnd:2970+dev:2282
vnd:1e53+dev:0007
vnd:2717+dev:1360
vnd:2717+dev:1368
vnd:2717+dev:1248
vnd:2717+dev:1240
vnd:0a9d+dev:ff40
vnd:2717+dev:f003
vnd:2717+dev:9039
vnd:2717+dev:ff40
vnd:2717+dev:ff48
vnd:2717+dev:0368
vnd:2717+dev:0360
vnd:2717+dev:0660
vnd:2717+dev:0668
vnd:2717+dev:ff60
vnd:2717+dev:ff68
vnd:2207+dev:0006
vnd:2916+dev:9139
vnd:2916+dev:914d
vnd:2916+dev:f003
vnd:2916+dev:9039
vnd:1ebf+dev:7f29
vnd:041e+dev:6000
vnd:2770+dev:905c
vnd:19d2+dev:2008
vnd:19d2+dev:0343
vnd:19d2+dev:ffce
vnd:19d2+dev:0244
vnd:19d2+dev:0245
vnd:19d2+dev:0306
vnd:19d2+dev:0307
vnd:19d2+dev:0383
vnd:19d2+dev:ffcf
vnd:2b4c+dev:1004
vnd:2b4c+dev:1005
vnd:2b4c+dev:101a
vnd:2b4c+dev:1013

===== ./tests/test-update-portal.sh =====
#!/bin/bash
#
# Copyright (C) 2019 Colin Walters <walters@verbum.org>
#
# 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 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., 59 Temple Place - Suite 330,
# Boston, MA 02111-1307, USA.

set -euo pipefail

. $(dirname $0)/libtest.sh

skip_without_bwrap
skip_revokefs_without_fuse

echo "1..6"

setup_repo
install_repo

run_with_sandboxed_bus ${test_builddir}/test-update-portal monitor monitor.pid > update-monitor.out
MONITOR_PID=$(cat monitor.pid)

OLD_COMMIT=$(cat repos/test/refs/heads/app/org.test.Hello/$ARCH/master)
make_updated_app
NEW_COMMIT=$(cat repos/test/refs/heads/app/org.test.Hello/$ARCH/master)

for i in {15..1}; do
    if grep -q -e "update_available .* remote=${NEW_COMMIT}" update-monitor.out >&2; then
        assert_file_has_content update-monitor.out "running=${OLD_COMMIT} local=${OLD_COMMIT} remote=${NEW_COMMIT}"
        echo found update ${NEW_COMMIT} >&2
        break
    fi
    if [ $i == 1 ]; then
        assert_not_reached "Timed out when looking for update 1"
    fi
    sleep 1
done

make_updated_app test "" master UPDATE2

NEWER_COMMIT=$(cat repos/test/refs/heads/app/org.test.Hello/$ARCH/master)

for i in {15..1}; do
    if grep -q -e "update_available .* remote=${NEWER_COMMIT}"  update-monitor.out >&2; then
        assert_file_has_content update-monitor.out "running=${OLD_COMMIT} local=${OLD_COMMIT} remote=${NEWER_COMMIT}"
        echo found update ${NEWER_COMMIT} >&2
        break
    fi
    if [ $i == 1 ]; then
        assert_not_reached "Timed out when looking for update 2"
    fi
    sleep 1
done

# Make sure monitor is dead
kill -9 $MONITOR_PID

ok "monitor updates"

run_with_sandboxed_bus ${test_builddir}/test-update-portal update monitor.pid >&2

ok "update self"

run_with_sandboxed_bus ${test_builddir}/test-update-portal update-null monitor.pid >&2

ok "null-update self"

make_updated_app test "" master UPDATE3

# Break the repo so that the update fails
cp -r repos/test/objects repos/test/orig-objects
find repos/test/objects -name "*.filez" | xargs  -I FILENAME mv FILENAME FILENAME.broken

run_with_sandboxed_bus ${test_builddir}/test-update-portal update-fail monitor.pid >&2

# Unbreak it again
rm -rf repos/test/objects
mv repos/test/orig-objects repos/test/objects

ok "update fail"

${FLATPAK} ${U} mask "org.test.Hello*" >&2

NEW_COMMIT=$(cat repos/test/refs/heads/app/org.test.Hello/$ARCH/master)

# Should not report update due to mask
run_with_sandboxed_bus ${test_builddir}/test-update-portal monitor monitor.pid > update-monitor.out
MONITOR_PID=$(cat monitor.pid)
sleep 4; # 4 secs should be ok, as poll timeout is 1 sec.
assert_not_file_has_content update-monitor.out "remote=${NEW_COMMIT}"

# Make sure monitor is dead
kill -9 $MONITOR_PID

# Should be a "null" update due to mask
run_with_sandboxed_bus ${test_builddir}/test-update-portal update-null monitor.pid >&2

${FLATPAK} ${U} mask --remove "org.test.Hello*" >&2

ok "update vs masked"

BUILD_FINISH_ARGS="--filesystem=host" make_updated_app test "" master UPDATE41
run_with_sandboxed_bus ${test_builddir}/test-update-portal update-notsupp monitor.pid >&2

BUILD_FINISH_ARGS="--share=network" make_updated_app test "" master UPDATE42
run_with_sandboxed_bus ${test_builddir}/test-update-portal update-notsupp monitor.pid >&2

BUILD_FINISH_ARGS="--socket=x11" make_updated_app test "" master UPDATE43
run_with_sandboxed_bus ${test_builddir}/test-update-portal update-notsupp monitor.pid >&2

BUILD_FINISH_ARGS="--own-name=org.some.Name" make_updated_app test "" master UPDATE44
run_with_sandboxed_bus ${test_builddir}/test-update-portal update-notsupp monitor.pid >&2

make_updated_app test "" master UPDATE45
run_with_sandboxed_bus ${test_builddir}/test-update-portal update monitor.pid >&2

ok "update with changed permissions"

===== ./tests/installed-tests.sh.in =====
# Copyright 2024 Collabora Ltd.
# SPDX-License-Identifier: LGPL-2.1-or-later

FLATPAK_TRIGGERSDIR='@FLATPAK_TRIGGERSDIR@'
FUSERMOUNT='@FUSERMOUNT@'

export FLATPAK_TRIGGERSDIR

===== ./tests/test-instance.c =====
/* vi:set et sw=2 sts=2 cin cino=t0,f0,(0,{s,>2s,n-s,^-s,e-s:
 * Copyright © 2021 Collabora Ltd.
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 */

#include "config.h"

#include <fcntl.h>
#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <utime.h>

#include <glib.h>
#include <glib/gstdio.h>

#include "flatpak.h"
#include "flatpak-instance-private.h"
#include "flatpak-metadata-private.h"

#include "libglnx.h"
#include "tests/libglnx-testlib.h"

#include "testlib.h"

static void
populate_with_files (const char *dir)
{
  static const char * const names[] = { "one", "two", "three" };
  gsize i;

  for (i = 0; i < G_N_ELEMENTS (names); i++)
    {
      g_autoptr(GError) error = NULL;
      g_autofree char *path = g_build_filename (dir, names[i], NULL);

      g_file_set_contents (path, "hello", -1, &error);
      g_assert_no_error (error);
    }
}

static void
test_gc (void)
{
  g_autoptr(GBytes) bytes = NULL;
  g_autoptr(GError) error = NULL;
  g_autoptr(GPtrArray) instances = NULL;
  g_autofree char *instances_dir = flatpak_instance_get_instances_directory ();
  g_autofree char *apps_dir = flatpak_instance_get_instances_directory ();
  g_autofree char *hold_lock = g_test_build_filename (G_TEST_BUILT, "hold-lock", NULL);
  g_autofree char *alive_app_dir = NULL;
  g_autofree char *alive_app_lock = NULL;
  g_autofree char *alive_app_tmp = NULL;
  g_autofree char *alive_instance_dir = NULL;
  g_autofree char *alive_instance_info = NULL;
  g_autofree char *alive_instance_lock = NULL;
  g_autofree char *alive_dead_instance_dir = NULL;
  g_autofree char *alive_dead_instance_info = NULL;
  g_autofree char *alive_dead_instance_lock = NULL;
  g_autofree char *dead_app_dir = NULL;
  g_autofree char *dead_app_lock = NULL;
  g_autofree char *dead_app_tmp = NULL;
  g_autofree char *dead_instance_dir = NULL;
  g_autofree char *dead_instance_info = NULL;
  g_autofree char *dead_instance_lock = NULL;
  struct utimbuf a_while_ago = {};
  const char *hold_lock_argv[] =
  {
    "<BUILT>/hold-lock",
    "--lock-file",
    "<instance>/.ref",
    "--lock-file",
    "<appID>/.ref",
    NULL
  };
  GPid pid = -1;
  int stdout_fd = -1;
  int wstatus = 0;
  FlatpakInstance *instance;
  struct stat stat_buf;

  /* com.example.Alive has one instance, #1, running.
   * A second instance, #2, was running until recently but has exited. */
  alive_app_dir = g_build_filename (apps_dir, "com.example.Alive", NULL);
  g_assert_no_errno (g_mkdir_with_parents (alive_app_dir, 0700));
  alive_app_tmp = g_build_filename (alive_app_dir, "tmp", NULL);
  g_assert_no_errno (g_mkdir_with_parents (alive_app_tmp, 0700));
  populate_with_files (alive_app_tmp);
  alive_app_lock = g_build_filename (alive_app_dir, ".ref", NULL);
  g_file_set_contents (alive_app_lock, "", 0, &error);
  g_assert_no_error (error);

  alive_instance_dir = g_build_filename (instances_dir, "1", NULL);
  g_assert_no_errno (g_mkdir_with_parents (alive_instance_dir, 0700));
  alive_instance_info = g_build_filename (alive_instance_dir, "info", NULL);
  g_file_set_contents (alive_instance_info,
                       "[" FLATPAK_METADATA_GROUP_APPLICATION "]\n"
                       FLATPAK_METADATA_KEY_NAME "=com.example.Alive\n",
                       -1, &error);
  g_assert_no_error (error);
  alive_instance_lock = g_build_filename (alive_instance_dir, ".ref", NULL);
  g_file_set_contents (alive_instance_lock, "", 0, &error);
  g_assert_no_error (error);

  alive_dead_instance_dir = g_build_filename (instances_dir, "2", NULL);
  g_assert_no_errno (g_mkdir_with_parents (alive_dead_instance_dir, 0700));
  alive_dead_instance_info = g_build_filename (alive_dead_instance_dir, "info", NULL);
  g_file_set_contents (alive_dead_instance_info,
                       "[" FLATPAK_METADATA_GROUP_APPLICATION "]\n"
                       FLATPAK_METADATA_KEY_NAME "=com.example.Alive\n",
                       -1, &error);
  g_assert_no_error (error);
  alive_dead_instance_lock = g_build_filename (alive_dead_instance_dir, ".ref", NULL);
  g_file_set_contents (alive_dead_instance_lock, "", 0, &error);
  g_assert_no_error (error);

  /* This represents the running instance #1. We have to do this
   * out-of-process because the locks we use are process-oriented,
   * so the locks we take during GC would not conflict with locks held
   * by our own process. */
  hold_lock_argv[0] = hold_lock;
  hold_lock_argv[2] = alive_instance_lock;
  hold_lock_argv[4] = alive_app_lock;
  g_spawn_async_with_pipes (NULL,
                            (gchar **) hold_lock_argv,
                            NULL,
                            G_SPAWN_DO_NOT_REAP_CHILD,
                            NULL,
                            NULL,
                            &pid,
                            NULL,
                            &stdout_fd,
                            NULL,
                            &error);
  g_assert_no_error (error);
  g_assert_cmpint (pid, >, 1);
  g_assert_cmpint (stdout_fd, >=, 0);

  /* com.example.Dead has no instances running.
   * Instance #4 was running until recently but has exited. */
  dead_app_dir = g_build_filename (apps_dir, "com.example.Dead", NULL);
  g_assert_no_errno (g_mkdir_with_parents (dead_app_dir, 0700));
  dead_app_tmp = g_build_filename (dead_app_dir, "tmp", NULL);
  g_assert_no_errno (g_mkdir_with_parents (dead_app_tmp, 0700));
  populate_with_files (dead_app_tmp);
  dead_app_lock = g_build_filename (dead_app_dir, ".ref", NULL);
  g_file_set_contents (dead_app_lock, "", 0, &error);
  g_assert_no_error (error);

  dead_instance_dir = g_build_filename (instances_dir, "4", NULL);
  g_assert_no_errno (g_mkdir_with_parents (dead_instance_dir, 0700));
  dead_instance_info = g_build_filename (dead_instance_dir, "info", NULL);
  g_file_set_contents (dead_instance_info,
                       "[" FLATPAK_METADATA_GROUP_APPLICATION "]\n"
                       FLATPAK_METADATA_KEY_NAME "=com.example.Dead\n",
                       -1, &error);
  g_assert_no_error (error);
  dead_instance_lock = g_build_filename (dead_instance_dir, ".ref", NULL);
  g_file_set_contents (dead_instance_lock, "", 0, &error);
  g_assert_no_error (error);

  /* Wait for the child to be ready */
  bytes = glnx_fd_readall_bytes (stdout_fd, NULL, &error);
  g_assert_no_error (error);
  g_assert_nonnull (bytes);
  g_assert_cmpuint (g_bytes_get_size (bytes), ==, 0);

  /* Pretend the locks were created in early 1970, to bypass the workaround
   * for a race */
  g_assert_no_errno (g_utime (alive_app_lock, &a_while_ago));
  g_assert_no_errno (g_utime (alive_instance_lock, &a_while_ago));
  g_assert_no_errno (g_utime (alive_dead_instance_lock, &a_while_ago));
  g_assert_no_errno (g_utime (dead_app_lock, &a_while_ago));
  g_assert_no_errno (g_utime (dead_instance_lock, &a_while_ago));

  /* This has the side-effect of GC'ing instances */
  instances = flatpak_instance_get_all ();

  /* We GC exactly those instances that are no longer running */
  g_assert_no_errno (stat (alive_instance_dir, &stat_buf));
  g_assert_cmpint (stat (alive_dead_instance_dir, &stat_buf) == 0 ? 0 : errno, ==, ENOENT);
  g_assert_cmpint (stat (dead_instance_dir, &stat_buf) == 0 ? 0 : errno, ==, ENOENT);

  /* We don't GC the per-app directories themselves, or their lock files */
  g_assert_no_errno (stat (alive_app_dir, &stat_buf));
  g_assert_no_errno (stat (alive_app_lock, &stat_buf));
  g_assert_no_errno (stat (dead_app_dir, &stat_buf));
  g_assert_no_errno (stat (dead_app_lock, &stat_buf));

  /* We GC the tmp subdirectory if there is no instance alive.
   * We do not GC it if there is still an instance holding the lock. */
  g_assert_no_errno (stat (alive_app_tmp, &stat_buf));
  g_assert_cmpint (stat (dead_app_tmp, &stat_buf) == 0 ? 0 : errno, ==, ENOENT);

  g_assert_cmpuint (instances->len, ==, 1);
  instance = g_ptr_array_index (instances, 0);
  g_assert_true (FLATPAK_IS_INSTANCE (instance));
  g_assert_cmpstr (flatpak_instance_get_id (instance), ==, "1");

  kill (pid, SIGTERM);
  g_assert_no_errno (waitpid (pid, &wstatus, 0));
  g_assert_true (WIFSIGNALED (wstatus));
  g_assert_cmpint (WTERMSIG (wstatus), ==, SIGTERM);
  g_spawn_close_pid (pid);
}

static void
test_claim_per_app_temp_directory (void)
{
  /* Run in a temporary directory so we can create a bunch of symlinks */
  _GLNX_TEST_SCOPED_TEMP_DIR;

  gboolean ok;
  glnx_autofd int lock_fd = -1;
  glnx_autofd int fd = -1;
  g_autofree char *result = NULL;
  g_autofree char *flag_path = NULL;
  g_autofree char *symlink_path = NULL;
  g_autofree char *non_directory_path = NULL;
  g_autofree char *dir_in_tmp = NULL;
  g_autoptr(GError) error = NULL;
  struct stat stat_buf;

  /* In real life this would be the per-app-ID lock, but in fact
   * we just need some sort of file descriptor - as currently
   * implemented, we don't even need to lock it. */
  lock_fd = open ("mock-per-app-id-lock",
                  O_CLOEXEC | O_CREAT | O_NOCTTY | O_NOFOLLOW,
                  0600);
  g_assert_no_errno (lock_fd >= 0 ? 0 : -1);

  /* This emulates the sort of directory that we want to reuse. */
  dir_in_tmp = g_strdup ("/tmp/flatpak-com.example.App-XXXXXX");
  g_assert_nonnull (g_mkdtemp (dir_in_tmp));

  ok = flatpak_instance_claim_per_app_temp_directory ("com.example.App",
                                                      lock_fd,
                                                      AT_FDCWD,
                                                      "doesnt-exist",
                                                      "/tmp",
                                                      &result,
                                                      &error);
  g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND);
  g_assert_null (result);
  g_assert_false (ok);
  g_clear_error (&error);

  /* If link_path is a symlink to a directory not in /tmp, we refuse
   * to reuse it */
  g_assert_no_errno (symlink ("/nope", "bad-prefix"));
  ok = flatpak_instance_claim_per_app_temp_directory ("com.example.App",
                                                      lock_fd,
                                                      AT_FDCWD,
                                                      "bad-prefix",
                                                      "/tmp",
                                                      &result,
                                                      &error);
  g_assert_nonnull (error);
  g_assert_cmpstr (error->message, ==, "/nope does not start with /tmp");
  g_assert_null (result);
  g_assert_false (ok);
  g_clear_error (&error);

  /* Similar */
  g_assert_no_errno (symlink ("/tmptation", "bad-prefix2"));
  ok = flatpak_instance_claim_per_app_temp_directory ("com.example.App",
                                                      lock_fd,
                                                      AT_FDCWD,
                                                      "bad-prefix2",
                                                      "/tmp",
                                                      &result,
                                                      &error);
  g_assert_nonnull (error);
  g_assert_cmpstr (error->message, ==, "/tmptation does not start with /tmp/");
  g_assert_null (result);
  g_assert_false (ok);
  g_clear_error (&error);

  /* If link_path points to a subdirectory of /tmp that doesn't match the
   * expected pattern, we refuse to reuse it */
  g_assert_no_errno (symlink ("/tmp/nope", "bad-prefix3"));
  ok = flatpak_instance_claim_per_app_temp_directory ("com.example.App",
                                                      lock_fd,
                                                      AT_FDCWD,
                                                      "bad-prefix3",
                                                      "/tmp",
                                                      &result,
                                                      &error);
  g_assert_nonnull (error);
  g_assert_cmpstr (error->message, ==, "/tmp/nope does not start with /tmp/flatpak-");
  g_assert_null (result);
  g_assert_false (ok);
  g_clear_error (&error);

  /* Similar */
  g_assert_no_errno (symlink ("/tmp/flatpak-/nope", "too-many-levels"));
  ok = flatpak_instance_claim_per_app_temp_directory ("com.example.App",
                                                      lock_fd,
                                                      AT_FDCWD,
                                                      "too-many-levels",
                                                      "/tmp",
                                                      &result,
                                                      &error);
  g_assert_nonnull (error);
  g_assert_cmpstr (error->message, ==,
                   "/tmp/flatpak-/nope has too many directory separators");
  g_assert_null (result);
  g_assert_false (ok);
  g_clear_error (&error);

  /* Similar */
  g_assert_no_errno (symlink ("/tmp/flatpak-abc/", "too-many-levels2"));
  ok = flatpak_instance_claim_per_app_temp_directory ("com.example.App",
                                                      lock_fd,
                                                      AT_FDCWD,
                                                      "too-many-levels2",
                                                      "/tmp",
                                                      &result,
                                                      &error);
  g_assert_nonnull (error);
  g_assert_cmpstr (error->message, ==,
                   "/tmp/flatpak-abc/ has too many directory separators");
  g_assert_null (result);
  g_assert_false (ok);
  g_clear_error (&error);

  g_assert_no_errno (symlink ("/tmp/flatpak-org.example.Other-XXXXXX", "wrong-app"));
  ok = flatpak_instance_claim_per_app_temp_directory ("com.example.App",
                                                      lock_fd,
                                                      AT_FDCWD,
                                                      "wrong-app",
                                                      "/tmp",
                                                      &result,
                                                      &error);
  g_assert_nonnull (error);
  g_assert_cmpstr (error->message, ==,
                   "/tmp/flatpak-org.example.Other-XXXXXX does not "
                   "start with /tmp/flatpak-com.example.App");
  g_assert_null (result);
  g_assert_false (ok);
  g_clear_error (&error);

  g_assert_no_errno (symlink ("/tmp/flatpak-com.example.ApparentlyNot", "wrong-app2"));
  ok = flatpak_instance_claim_per_app_temp_directory ("com.example.App",
                                                      lock_fd,
                                                      AT_FDCWD,
                                                      "wrong-app2",
                                                      "/tmp",
                                                      &result,
                                                      &error);
  g_assert_nonnull (error);
  g_assert_cmpstr (error->message, ==,
                   "/tmp/flatpak-com.example.ApparentlyNot does not "
                   "start with /tmp/flatpak-com.example.App-");
  g_assert_null (result);
  g_assert_false (ok);
  g_clear_error (&error);

  /* If it points to a filesystem object matching the right pattern, but
   * that is not a directory, we refuse to reuse it */
  non_directory_path = g_strdup ("/tmp/flatpak-com.example.App-XXXXXX");
  g_assert_no_errno ((fd = g_mkstemp (non_directory_path)));
  g_assert_no_errno (symlink (non_directory_path, "not-a-directory"));
  ok = flatpak_instance_claim_per_app_temp_directory ("com.example.App",
                                                      lock_fd,
                                                      AT_FDCWD,
                                                      "not-a-directory",
                                                      "/tmp",
                                                      &result,
                                                      &error);
  g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_DIRECTORY);
  g_assert_null (result);
  g_assert_false (ok);
  g_clear_error (&error);

  /* Reuse @non_directory_path as the name of a symlink to a directory:
   * we consider that to be equally invalid. Create it inside our
   * directory in /tmp so that we can rename() it into place,
   * because symlink() does not overwrite, but rename() does. */
  symlink_path = g_build_filename (dir_in_tmp, "symlink", NULL);
  g_assert_no_errno (symlink (dir_in_tmp, symlink_path));
  /* Overwrite the file with the symlink */
  g_assert_no_errno (rename (symlink_path, non_directory_path));

  /* We'll refuse to follow the symlink: for all we know it could be
   * attacker-controlled. */
  ok = flatpak_instance_claim_per_app_temp_directory ("com.example.App",
                                                      lock_fd,
                                                      AT_FDCWD,
                                                      "not-a-directory",
                                                      "/tmp",
                                                      &result,
                                                      &error);

  /* Either of these would be reasonable */
  if (error->code == G_IO_ERROR_TOO_MANY_LINKS)
    g_assert_error (error, G_IO_ERROR, G_IO_ERROR_TOO_MANY_LINKS);
  else
    g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_DIRECTORY);

  g_assert_null (result);
  g_assert_false (ok);
  g_clear_error (&error);

  /* If link_path points to a directory owned by someone else, we refuse
   * to use it. This part of the test will be skipped unless you pre-create
   * this directory as root. */
  if (stat ("/tmp/flatpak-com.example.App-OwnedByRoot", &stat_buf) == 0
      && stat_buf.st_uid == 0
      && geteuid () != 0)
    {
      g_assert_no_errno (symlink ("/tmp/flatpak-com.example.App-OwnedByRoot",
                                  "not-our-directory"));
      ok = flatpak_instance_claim_per_app_temp_directory ("com.example.App",
                                                          lock_fd,
                                                          AT_FDCWD,
                                                          "not-our-directory",
                                                          "/tmp",
                                                          &result,
                                                          &error);
      g_assert_nonnull (error);
      g_assert_cmpstr (error->message, ==,
                       "/tmp/flatpak-com.example.App-OwnedByRoot does not "
                       "belong to this user");
      g_assert_null (result);
      g_assert_false (ok);
      g_clear_error (&error);
    }
  else
    {
      g_test_message ("pre-create /tmp/flatpak-com.example.App-OwnedByRoot as root to enable this check");
    }

  glnx_close_fd (&fd);
  g_assert_no_errno (unlink (non_directory_path));
  g_clear_pointer (&non_directory_path, g_free);

  /* Even when we have a symlink to a directory matching the right pattern
   * that we own, if it doesn't contain the flag file that indicates that
   * it's one of our temp directories, we'll still refuse to use it. */
  g_assert_no_errno (symlink (dir_in_tmp, "good-symlink"));
  ok = flatpak_instance_claim_per_app_temp_directory ("com.example.App",
                                                      lock_fd,
                                                      AT_FDCWD,
                                                      "good-symlink",
                                                      "/tmp",
                                                      &result,
                                                      &error);
  g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND);
  g_assert_true (g_str_has_prefix (error->message,
                                   "opening flag file /tmp/flatpak-com.example.App-"));
  g_assert_nonnull (strstr (error->message, "/.flatpak-tmpdir:"));
  g_assert_null (result);
  g_assert_false (ok);
  g_clear_error (&error);

  /* Create the flag file (of course in real life this would have happened
   * much sooner) */
  flag_path = g_build_filename (dir_in_tmp, ".flatpak-tmpdir", NULL);
  g_file_set_contents (flag_path, "", 0, &error);
  g_assert_no_error (error);

  /* Now we are finally willing to reuse the directory! A happy ending
   * at last. */
  ok = flatpak_instance_claim_per_app_temp_directory ("com.example.App",
                                                      lock_fd,
                                                      AT_FDCWD,
                                                      "good-symlink",
                                                      "/tmp",
                                                      &result,
                                                      &error);
  g_assert_no_error (error);
  g_assert_cmpstr (result, ==, dir_in_tmp);
  g_assert_true (ok);

  g_assert_no_errno (unlink (flag_path));
}

int
main (int argc, char *argv[])
{
  int res;

  g_test_init (&argc, &argv, NULL);
  isolated_test_dir_global_setup ();

  g_test_add_func ("/instance/gc", test_gc);
  g_test_add_func ("/instance/claim-per-app-temp-directory",
                   test_claim_per_app_temp_directory);

  res = g_test_run ();

  isolated_test_dir_global_teardown ();

  return res;
}

===== ./tests/hold-lock.c =====
/* vi:set et sw=2 sts=2 cin cino=t0,f0,(0,{s,>2s,n-s,^-s,e-s:
 * Copyright © 2019-2021 Collabora Ltd.
 *
 * SPDX-License-Identifier: LGPL-2.1-or-later
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 */

#include "config.h"

#include <glib.h>
#include <glib/gstdio.h>

#include <fcntl.h>
#include <fcntl.h>
#include <sysexits.h>
#include <sys/prctl.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>

#include "libglnx.h"

static GArray *global_locks = NULL;
static gboolean opt_wait = FALSE;
static gboolean opt_write = FALSE;

static gboolean
opt_fd_cb (const char *name,
           const char *value,
           gpointer data,
           GError **error)
{
  char *endptr;
  gint64 i64 = g_ascii_strtoll (value, &endptr, 10);
  int fd;
  int fd_flags;

  g_return_val_if_fail (global_locks != NULL, FALSE);
  g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
  g_return_val_if_fail (value != NULL, FALSE);

  if (i64 < 0 || i64 > G_MAXINT || endptr == value || *endptr != '\0')
    {
      g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE,
                   "Integer out of range or invalid: %s", value);
      return FALSE;
    }

  fd = (int) i64;

  fd_flags = fcntl (fd, F_GETFD);

  if (fd_flags < 0)
    return glnx_throw_errno_prefix (error, "Unable to receive --fd %d", fd);

  if ((fd_flags & FD_CLOEXEC) == 0
      && fcntl (fd, F_SETFD, fd_flags | FD_CLOEXEC) != 0)
    return glnx_throw_errno_prefix (error,
                                    "Unable to configure --fd %d for "
                                    "close-on-exec",
                                    fd);

  g_array_append_val (global_locks, fd);
  return TRUE;
}

static gboolean
opt_lock_file_cb (const char *name,
                  const char *value,
                  gpointer data,
                  GError **error)
{
  int open_flags = O_CLOEXEC | O_CREAT | O_NOCTTY | O_RDWR;
  int fd;
  int cmd;
  struct flock l =
  {
    .l_type = F_RDLCK,
    .l_whence = SEEK_SET,
    .l_start = 0,
    .l_len = 0,
  };

  g_return_val_if_fail (global_locks != NULL, FALSE);
  g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
  g_return_val_if_fail (value != NULL, FALSE);

  fd = TEMP_FAILURE_RETRY (open (value, open_flags, 0644));

  if (fd < 0)
    return glnx_throw_errno_prefix (error, "open %s", value);

  if (opt_write)
    l.l_type = F_WRLCK;

  if (opt_wait)
    cmd = F_SETLKW;
  else
    cmd = F_SETLK;

  if (TEMP_FAILURE_RETRY (fcntl (fd, cmd, &l)) < 0)
    {
      if (errno == EACCES || errno == EAGAIN)
        g_set_error (error, G_IO_ERROR, G_IO_ERROR_BUSY,
                     "Unable to lock %s: file is busy", value);
      else
        glnx_throw_errno_prefix (error, "lock %s", value);

      close (fd);
      return FALSE;
    }

  g_array_append_val (global_locks, fd);
  return TRUE;
}

static GOptionEntry options[] =
{
  { "fd", '\0',
    G_OPTION_FLAG_NONE, G_OPTION_ARG_CALLBACK, opt_fd_cb,
    "Take a file descriptor, already locked if desired, and keep it "
    "open. May be repeated.",
    NULL },

  { "wait", '\0',
    G_OPTION_FLAG_NONE, G_OPTION_ARG_NONE, &opt_wait,
    "Wait for each subsequent lock file.",
    NULL },
  { "no-wait", '\0',
    G_OPTION_FLAG_REVERSE, G_OPTION_ARG_NONE, &opt_wait,
    "Exit unsuccessfully if a lock-file is busy [default].",
    NULL },

  { "write", '\0',
    G_OPTION_FLAG_NONE, G_OPTION_ARG_NONE, &opt_write,
    "Lock each subsequent lock file for write access.",
    NULL },
  { "no-write", '\0',
    G_OPTION_FLAG_REVERSE, G_OPTION_ARG_NONE, &opt_write,
    "Lock each subsequent lock file for read-only access [default].",
    NULL },

  { "lock-file", '\0',
    G_OPTION_FLAG_NONE, G_OPTION_ARG_CALLBACK, opt_lock_file_cb,
    "Open the given file and lock it, affected by options appearing "
    "earlier on the command-line. May be repeated.",
    NULL },

  { NULL }
};

int
main (int argc,
      char *argv[])
{
  g_autoptr(GArray) locks = NULL;
  g_autoptr(GOptionContext) context = NULL;
  g_autoptr(GError) local_error = NULL;
  GError **error = &local_error;
  int ret = EX_USAGE;

  locks = g_array_new (FALSE, FALSE, sizeof (int));
  global_locks = locks;

  context = g_option_context_new (NULL);
  g_option_context_add_main_entries (context, options, NULL);

  if (!g_option_context_parse (context, &argc, &argv, error))
    {
      if (g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_BUSY))
        ret = EX_TEMPFAIL;
      else if (local_error->domain == G_OPTION_ERROR)
        ret = EX_USAGE;
      else
        ret = EX_UNAVAILABLE;

      goto out;
    }

  ret = EX_UNAVAILABLE;

  /* Self-destruct when parent exits */
  if (prctl (PR_SET_PDEATHSIG, SIGTERM, 0, 0, 0) != 0)
    {
      glnx_throw_errno_prefix (error,
                               "Unable to set parent death signal");
      goto out;
    }

  /* Signal to caller that we are ready */
  fclose (stdout);

  while (TRUE)
    pause ();

  g_assert_not_reached ();

out:
  global_locks = NULL;

  if (local_error != NULL)
    g_warning ("%s", local_error->message);

  return ret;
}

===== ./tests/test-extension-branch-follow.sh =====
#!/bin/bash

set -euo pipefail

# shellcheck source=tests/libtest.sh
# shellcheck disable=SC1091
. "$(dirname "$0")/libtest.sh"

skip_without_bwrap

echo "1..1"

setup_repo () {
    mkdir -p repos
    ostree init --repo=repos/test --mode=archive-z2
}

make_extension () {
    local ID=$1
    local VERSION=$2

    local DIR
    DIR=$(mktemp -d)

    cat > "${DIR}/metadata" <<EOF
[Runtime]
name=${ID}
EOF
    mkdir -p "${DIR}/usr"
    mkdir -p "${DIR}/files"
    touch "${DIR}/usr/extension-$ID:$VERSION"

    # shellcheck disable=SC2086
    ${FLATPAK} build-export --no-update-summary --runtime ${GPGARGS-} repos/test "${DIR}" "${VERSION}" >&2
    update_repo
    rm -rf "${DIR}"
}

setup_repo

"$(dirname "$0")/make-test-runtime.sh" repos/test org.test.Platform master "" "" bash ls cat echo readlink > /dev/null

# Create app version 1 with extension version 1.0
mkdir -p hello
cat > hello/metadata <<EOF
[Application]
name=org.test.Hello
runtime=org.test.Platform/$(uname -m)/master
sdk=org.test.Platform/$(uname -m)/master

[Extension org.test.Extension]
directory=files/ext
version=1.0
no-autodownload=true
EOF
mkdir -p hello/files/ext
${FLATPAK} build-finish --no-inherit-permissions hello >&2
${FLATPAK} build-export --no-update-summary --disable-sandbox repos/test hello master >&2
update_repo

# Create extension branch 1.0
make_extension org.test.Extension 1.0

# Install app and extension 1.0
${FLATPAK} remote-add --user --no-gpg-verify test-repo repos/test >&2
${FLATPAK} --user install -y test-repo org.test.Hello master >&2
${FLATPAK} --user install -y test-repo org.test.Extension 1.0 >&2

if ! ${FLATPAK} --user list --runtime | grep -q "org.test.Extension.*1.0"; then
    ${FLATPAK} --user list --runtime >&2
    assert_not_reached "Extension 1.0 not installed"
fi
echo "# Extension 1.0 installed successfully" >&2

# Create app version 2 with extension version 2.0
mkdir -p hello2
cat > hello2/metadata <<EOF
[Application]
name=org.test.Hello
runtime=org.test.Platform/$(uname -m)/master
sdk=org.test.Platform/$(uname -m)/master

[Extension org.test.Extension]
directory=files/ext
version=2.0
no-autodownload=true
EOF
mkdir -p hello2/files/ext
${FLATPAK} build-finish --no-inherit-permissions hello2 >&2
${FLATPAK} build-export --no-update-summary --disable-sandbox repos/test hello2 master >&2
update_repo

# Create extension branch 2.0
make_extension org.test.Extension 2.0

# Update the app
${FLATPAK} --user update -y --verbose org.test.Hello master >&2

# Check if extension 2.0 was installed
${FLATPAK} --user list --runtime >&2
if ${FLATPAK} --user list --runtime | grep -q "org.test.Extension.*2.0"; then
    echo "# Success: Extension 2.0 installed automatically after branch follow"
else
    assert_not_reached "Extension 2.0 NOT installed automatically"
fi

ok "extension branch follow"

===== ./tests/test-extensions.sh =====
#!/bin/bash
#
# Copyright (C) 2011 Colin Walters <walters@verbum.org>
#
# 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 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., 59 Temple Place - Suite 330,
# Boston, MA 02111-1307, USA.

set -euo pipefail

. $(dirname $0)/libtest.sh

skip_without_bwrap

echo "1..2"

make_extension () {
    local ID=$1
    local VERSION=$2

    local DIR=`mktemp -d`

    cat > ${DIR}/metadata <<EOF
[Runtime]
name=${ID}
EOF
    mkdir -p ${DIR}/usr
    mkdir -p ${DIR}/files
    touch ${DIR}/usr/exists
    touch ${DIR}/usr/extension-$ID:$VERSION

    ${FLATPAK} build-export --no-update-summary --runtime ${GPGARGS-} repos/test ${DIR} ${VERSION} >&2
    update_repo
    rm -rf ${DIR}

    ${FLATPAK} --user install -y test-repo $ID $VERSION >&2
}

add_extensions () {
    local DIR=$1

    mkdir -p $DIR/files/foo/ext1
    mkdir -p $DIR/files/foo/ext2
    mkdir -p $DIR/files/foo/ext3
    mkdir -p $DIR/files/foo/ext4
    mkdir -p $DIR/files/foo/none
    mkdir -p $DIR/files/foo/dir
    mkdir -p $DIR/files/foo/dir2
    mkdir -p $DIR/files/foo/multiversion

    cat >> $DIR/metadata <<EOF
[Extension org.test.Extension1]
directory=foo/ext1

[Extension org.test.Extension2]
directory=foo/ext2
version=master

[Extension org.test.Extension3]
directory=foo/ext3
version=not-master

[Extension org.test.Extension4]
directory=foo/ext4
version=not-master

[Extension org.test.None]
directory=foo/none

[Extension org.test.Dir]
directory=foo/dir
subdirectories=true

[Extension org.test.Dir2]
directory=foo/dir2
subdirectories=true

[Extension org.test.Multiversion]
directory=foo/multiversion
versions=not-master;master
subdirectories=true

EOF
}

mkdir -p repos
ostree init --repo=repos/test --mode=archive-z2
$(dirname $0)/make-test-runtime.sh repos/test org.test.Platform master "" "" bash ls cat echo readlink > /dev/null
$(dirname $0)/make-test-app.sh repos/test "" master "" > /dev/null

# Modify platform metadata
ostree checkout -U --repo=repos/test runtime/org.test.Platform/${ARCH}/master platform >&2
add_extensions platform
${FLATPAK} build-export --no-update-summary --disable-sandbox repos/test platform --files=files master >&2
update_repo

${FLATPAK} remote-add --user --no-gpg-verify test-repo repos/test >&2
${FLATPAK} --user install -y test-repo org.test.Platform master >&2
${FLATPAK} --user install -y test-repo org.test.Hello master >&2

make_extension org.test.Extension1 master
make_extension org.test.Extension1 not-master
make_extension org.test.Extension2 master
make_extension org.test.Extension2 not-master
make_extension org.test.Extension3 master
make_extension org.test.Extension3 not-master
make_extension org.test.Extension4 master
make_extension org.test.Dir.foo master
make_extension org.test.Dir.bar master
make_extension org.test.Multiversion.master master
make_extension org.test.Multiversion.notmaster not-master

assert_has_extension_file () {
    local prefix=$1
    local file=$2 
    run_sh org.test.Hello "test -f $prefix/foo/$file" || (echo 1>&2 "Couldn't find '$file'"; exit 1)
}

assert_not_has_extension_file () {
    local prefix=$1
    local file=$2 
    if run_sh org.test.Hello "test -f $prefix/foo/$file" >&2; then
        echo 1>&2 "File '$file' exists";
        exit 1
    fi
}

assert_has_extension_file /usr ext1/exists
assert_has_extension_file /usr ext1/extension-org.test.Extension1:master
assert_has_extension_file /usr ext2/exists
assert_has_extension_file /usr ext2/extension-org.test.Extension2:master
assert_has_extension_file /usr ext3/exists
assert_has_extension_file /usr ext3/extension-org.test.Extension3:not-master
assert_not_has_extension_file /usr ext4/exists
assert_has_extension_file /usr dir/foo/exists
assert_has_extension_file /usr dir/foo/extension-org.test.Dir.foo:master
assert_has_extension_file /usr dir/bar/extension-org.test.Dir.bar:master
assert_not_has_extension_file /usr dir2/foo/exists
run_sh org.test.Hello "ls -lR /usr/foo/multiversion" >&2
assert_has_extension_file /usr multiversion/master/extension-org.test.Multiversion.master:master
assert_has_extension_file /usr multiversion/notmaster/extension-org.test.Multiversion.notmaster:not-master

ok "runtime extensions"

# Modify app metadata
ostree checkout -U --repo=repos/test app/org.test.Hello/${ARCH}/master hello >&2
add_extensions hello
${FLATPAK} build-export --no-update-summary --disable-sandbox repos/test hello master >&2
update_repo

${FLATPAK} --user update -y org.test.Hello master >&2

assert_has_extension_file /app ext1/exists
assert_has_extension_file /app ext1/extension-org.test.Extension1:master
assert_has_extension_file /app ext2/exists
assert_has_extension_file /app ext2/extension-org.test.Extension2:master
assert_has_extension_file /app ext3/exists
assert_has_extension_file /app ext3/extension-org.test.Extension3:not-master
assert_not_has_extension_file /app ext4/exists
assert_has_extension_file /app dir/foo/exists
assert_has_extension_file /app dir/foo/extension-org.test.Dir.foo:master
assert_has_extension_file /app dir/bar/extension-org.test.Dir.bar:master
assert_not_has_extension_file /app dir2/foo/exists
assert_has_extension_file /app multiversion/master/extension-org.test.Multiversion.master:master
assert_has_extension_file /app multiversion/notmaster/extension-org.test.Multiversion.notmaster:not-master

ok "app extensions"

===== ./tests/test-subset.sh =====
#!/bin/bash
#
# Copyright (C) 2020 Alexander Larsson <alexl@redhat.com>
#
# 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 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., 59 Temple Place - Suite 330,
# Boston, MA 02111-1307, USA.

set -euo pipefail

. $(dirname $0)/libtest.sh

skip_without_bwrap
skip_revokefs_without_fuse

echo "1..3"

EXPORT_ARGS="--subset=subset1 --subset=subset2" setup_repo

$FLATPAK repo repos/test > repo-info.txt
assert_file_has_content repo-info.txt "Subsummaries: .*subset1-$ARCH.*"
assert_file_has_content repo-info.txt "Subsummaries: .*subset2-$ARCH.*"

$FLATPAK repo --branches repos/test > repo-all.txt
assert_file_has_content repo-all.txt "app/org\.test\.Hello/$ARCH/master"
assert_file_has_content repo-all.txt "runtime/org\.test\.Platform/$ARCH/master"

EXPORT_ARGS="--subset=subset1 " GPGARGS="${FL_GPGARGS}" $(dirname $0)/make-test-app.sh repos/test org.test.SubsetOne master ""
EXPORT_ARGS="--subset=subset2 " GPGARGS="${FL_GPGARGS}" $(dirname $0)/make-test-app.sh repos/test org.test.SubsetTwo master ""
EXPORT_ARGS="" GPGARGS="${FL_GPGARGS}" $(dirname $0)/make-test-app.sh repos/test org.test.NoSubset master ""
${FLATPAK} build-update-repo ${BUILD_UPDATE_REPO_FLAGS-} ${FL_GPGARGS} repos/test >&2

$FLATPAK repo repos/test > repo-info.txt
assert_file_has_content repo-info.txt "Subsummaries: .*subset1-$ARCH.*"
assert_file_has_content repo-info.txt "Subsummaries: .*subset2-$ARCH.*"

$FLATPAK repo --branches repos/test > repo-all.txt
assert_file_has_content repo-all.txt "app/org\.test\.Hello/$ARCH/master"
assert_file_has_content repo-all.txt "app/org\.test\.SubsetOne/$ARCH/master"
assert_file_has_content repo-all.txt "app/org\.test\.SubsetTwo/$ARCH/master"
assert_file_has_content repo-all.txt "app/org\.test\.NoSubset/$ARCH/master"
assert_file_has_content repo-all.txt "runtime/org\.test\.Platform/$ARCH/master"

$FLATPAK repo --branches repos/test --subset=subset1 > repo-subset1.txt
assert_file_has_content repo-subset1.txt "app/org\.test\.Hello/$ARCH/master"
assert_file_has_content repo-subset1.txt "app/org\.test\.SubsetOne/$ARCH/master"
assert_not_file_has_content repo-subset1.txt "app/org\.test\.SubsetTwo/$ARCH/master"
assert_not_file_has_content repo-subset1.txt "app/org\.test\.NoSubset/$ARCH/master"
assert_file_has_content repo-subset1.txt "runtime/org\.test\.Platform/$ARCH/master"

$FLATPAK repo --branches repos/test --subset=subset2 > repo-subset2.txt
assert_file_has_content repo-subset2.txt "app/org\.test\.Hello/$ARCH/master"
assert_not_file_has_content repo-subset2.txt "app/org\.test\.SubsetOne/$ARCH/master"
assert_file_has_content repo-subset2.txt "app/org\.test\.SubsetTwo/$ARCH/master"
assert_not_file_has_content repo-subset2.txt "app/org\.test\.NoSubset/$ARCH/master"
assert_file_has_content repo-subset2.txt "runtime/org\.test\.Platform/$ARCH/master"

ok "repo has right refs in right subset"

${FLATPAK} ${U} remote-modify --subset=subset1 test-repo >&2

${FLATPAK} ${U} remote-ls --columns=ref test-repo > remote-subset1.txt
assert_file_has_content remote-subset1.txt "org\.test\.Hello/"
assert_file_has_content remote-subset1.txt "org\.test\.SubsetOne/"
assert_not_file_has_content remote-subset1.txt "org\.test\.SubsetTwo/"
assert_not_file_has_content remote-subset1.txt "org\.test\.NoSubset/"
assert_file_has_content remote-subset1.txt "org\.test\.Platform/"

${FLATPAK} ${U} install -y org.test.Hello &> /dev/null
${FLATPAK} ${U} install -y org.test.SubsetOne &> /dev/null

if ${FLATPAK} ${U} install -y org.test.SubsetTwo &> /dev/null; then
    assert_not_reached "Subset2 should not be visible"
fi

${FLATPAK} ${U} update --appstream >&2
assert_has_file $FL_DIR/appstream/test-repo/$ARCH/active/appstream.xml
assert_file_has_content $FL_DIR/appstream/test-repo/$ARCH/active/appstream.xml org.test.Hello.desktop
assert_file_has_content $FL_DIR/appstream/test-repo/$ARCH/active/appstream.xml org.test.SubsetOne.desktop
assert_not_file_has_content $FL_DIR/appstream/test-repo/$ARCH/active/appstream.xml org.test.SubsetTwo.desktop
assert_not_file_has_content $FL_DIR/appstream/test-repo/$ARCH/active/appstream.xml org.test.NoSubset.desktop

ok "remote subset handling works"

${FLATPAK} ${U} remote-modify --subset=subset2 test-repo >&2

${FLATPAK} ${U} remote-ls --columns=ref test-repo > remote-subset2.txt
assert_file_has_content remote-subset2.txt "org\.test\.Hello/"
assert_not_file_has_content remote-subset2.txt "org\.test\.SubsetOne/"
assert_file_has_content remote-subset2.txt "org\.test\.SubsetTwo/"
assert_not_file_has_content remote-subset1.txt "org\.test\.NoSubset/"
assert_file_has_content remote-subset2.txt "org\.test\.Platform/"

${FLATPAK} ${U} install -y org.test.SubsetTwo &> /dev/null

${FLATPAK} ${U} update --appstream >&2
assert_has_file $FL_DIR/appstream/test-repo/$ARCH/active/appstream.xml
assert_file_has_content $FL_DIR/appstream/test-repo/$ARCH/active/appstream.xml org.test.Hello.desktop
assert_not_file_has_content $FL_DIR/appstream/test-repo/$ARCH/active/appstream.xml org.test.SubsetOne.desktop
assert_file_has_content $FL_DIR/appstream/test-repo/$ARCH/active/appstream.xml org.test.SubsetTwo.desktop
assert_not_file_has_content $FL_DIR/appstream/test-repo/$ARCH/active/appstream.xml org.test.NoSubset.desktop

ok "remote subset switching works"

===== ./tests/test-context.c =====
/* vi:set et sw=2 sts=2 cin cino=t0,f0,(0,{s,>2s,n-s,^-s,e-s:
 * Copyright © 2021 Collabora Ltd.
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 */

#include "config.h"

#include <stdarg.h>

#include <glib.h>
#include "flatpak.h"
#include "flatpak-context-private.h"
#include "flatpak-metadata-private.h"
#include "flatpak-utils-private.h"

#include "tests/testlib.h"

/* g_str_has_prefix as a GEqualFunc */
static gboolean
str_has_prefix (gconstpointer candidate,
                gconstpointer pattern)
{
  return g_str_has_prefix (candidate, pattern);
}

static void
test_context_env (void)
{
  g_autoptr(FlatpakContext) context = flatpak_context_new ();
  g_autoptr(GError) error = NULL;
  gboolean ok;
  const char env[] = "ONE=one\0TWO=two\0THREE=three\0EMPTY=\0X=x";

  ok = flatpak_context_parse_env_block (context, env, sizeof (env), &error);
  g_assert_no_error (error);
  g_assert_true (ok);
  g_assert_cmpstr (g_hash_table_lookup (context->env_vars, "ONE"), ==, "one");
  g_assert_cmpstr (g_hash_table_lookup (context->env_vars, "EMPTY"), ==, "");
  g_assert_cmpstr (g_hash_table_lookup (context->env_vars, "nope"), ==, NULL);

  ok = flatpak_context_parse_env_block (context,
                                        "FOO=barnstorming past the end",
                                        strlen ("FOO=bar"),
                                        &error);
  g_assert_no_error (error);
  g_assert_true (ok);
  g_assert_cmpstr (g_hash_table_lookup (context->env_vars, "FOO"), ==, "bar");

  ok = flatpak_context_parse_env_block (context,
                                        "BAD=barnstorming past the end",
                                        strlen ("BA"),
                                        &error);
  g_assert_nonnull (error);
  g_test_message ("Got error as expected: %s #%d: %s",
                  g_quark_to_string (error->domain), error->code,
                  error->message);
  g_assert_false (ok);
  g_assert_cmpstr (g_hash_table_lookup (context->env_vars, "BA"), ==, NULL);
  g_assert_cmpstr (g_hash_table_lookup (context->env_vars, "BAD"), ==, NULL);
  g_clear_error (&error);

  ok = flatpak_context_parse_env_block (context, "=x", strlen ("=x"), &error);
  g_assert_nonnull (error);
  g_test_message ("Got error as expected: %s #%d: %s",
                  g_quark_to_string (error->domain), error->code,
                  error->message);
  g_assert_false (ok);
  g_assert_cmpstr (g_hash_table_lookup (context->env_vars, ""), ==, NULL);
  g_clear_error (&error);

  ok = flatpak_context_parse_env_block (context, "\0", 1, &error);
  g_assert_nonnull (error);
  g_test_message ("Got error as expected: %s #%d: %s",
                  g_quark_to_string (error->domain), error->code,
                  error->message);
  g_assert_false (ok);
  g_assert_cmpstr (g_hash_table_lookup (context->env_vars, ""), ==, NULL);
  g_clear_error (&error);

  ok = flatpak_context_parse_env_block (context, "", 0, &error);
  g_assert_no_error (error);
  g_assert_true (ok);
}

static void
test_context_env_fd (void)
{
  g_autoptr(FlatpakContext) context = flatpak_context_new ();
  g_autoptr(GError) error = NULL;
  gboolean ok;
  const char env[] = "ONE=one\0TWO=two\0THREE=three\0EMPTY=\0X=x";
  glnx_autofd int fd = -1;
  g_autofree char *path = NULL;
  int bad_fd;

  path = g_strdup_printf ("/tmp/flatpak-test.XXXXXX");
  fd = g_mkstemp (path);
  g_assert_no_errno (glnx_loop_write (fd, env, sizeof (env)));
  g_assert_no_errno (lseek (fd, 0, SEEK_SET));

  ok = flatpak_context_parse_env_fd (context, fd, &error);
  g_assert_no_error (error);
  g_assert_true (ok);
  g_assert_cmpstr (g_hash_table_lookup (context->env_vars, "ONE"), ==, "one");
  g_assert_cmpstr (g_hash_table_lookup (context->env_vars, "EMPTY"), ==, "");
  g_assert_cmpstr (g_hash_table_lookup (context->env_vars, "nope"), ==, NULL);

  bad_fd = fd;
  glnx_close_fd (&fd);
  ok = flatpak_context_parse_env_fd (context, bad_fd, &error);
  g_assert_nonnull (error);
  g_test_message ("Got error as expected: %s #%d: %s",
                  g_quark_to_string (error->domain), error->code,
                  error->message);
  g_assert_false (ok);
  g_clear_error (&error);
}

static void context_parse_args (FlatpakContext *context,
                                GError        **error,
                                ...) G_GNUC_NULL_TERMINATED;

static void
context_parse_args (FlatpakContext *context,
                    GError        **error,
                    ...)
{
  g_autoptr(GOptionContext) oc = NULL;
  g_autoptr(GOptionGroup) group = NULL;
  g_autoptr(GPtrArray) args = g_ptr_array_new_with_free_func (g_free);
  g_auto(GStrv) argv = NULL;
  const char *arg;
  va_list ap;

  g_ptr_array_add (args, g_strdup ("argv[0]"));

  va_start (ap, error);

  while ((arg = va_arg (ap, const char *)) != NULL)
    g_ptr_array_add (args, g_strdup (arg));

  va_end (ap);

  g_ptr_array_add (args, NULL);
  argv = (GStrv) g_ptr_array_free (g_steal_pointer (&args), FALSE);

  oc = g_option_context_new ("");
  group = flatpak_context_get_options (context);
  g_option_context_add_group (oc, g_steal_pointer (&group));
  g_option_context_parse_strv (oc, &argv, error);
}

static void
test_context_merge_fs (void)
{
  /*
   * We want to arrive at the same result regardless of whether we:
   * - start from lowest precedence, and successively merge higher
   *   precedences into it, discarding them when done;
   * - successively merge highest precedence into second-highest, and
   *   then discard highest
   */
  enum { LOWEST_FIRST, HIGHEST_FIRST, INVALID } merge_order;

  for (merge_order = LOWEST_FIRST; merge_order < INVALID; merge_order++)
    {
      g_autoptr(FlatpakContext) lowest = flatpak_context_new ();
      g_autoptr(FlatpakContext) middle = flatpak_context_new ();
      g_autoptr(FlatpakContext) highest = flatpak_context_new ();
      g_autoptr(GError) local_error = NULL;
      gpointer value;

      context_parse_args (lowest,
                          &local_error,
                          "--filesystem=/one",
                          NULL);
      g_assert_no_error (local_error);
      context_parse_args (middle,
                          &local_error,
                          "--nofilesystem=host:reset",
                          "--filesystem=/two",
                          NULL);
      g_assert_no_error (local_error);
      context_parse_args (highest,
                          &local_error,
                          "--nofilesystem=host",
                          "--filesystem=/three",
                          NULL);
      g_assert_no_error (local_error);

      g_assert_false (g_hash_table_lookup_extended (lowest->filesystems, "host", NULL, NULL));
      g_assert_false (g_hash_table_lookup_extended (lowest->filesystems, "host-reset", NULL, NULL));
      g_assert_true (g_hash_table_lookup_extended (lowest->filesystems, "/one", NULL, &value));
      g_assert_cmpint (GPOINTER_TO_INT (value), ==, FLATPAK_FILESYSTEM_MODE_READ_WRITE);
      g_assert_false (g_hash_table_lookup_extended (lowest->filesystems, "/two", NULL, NULL));
      g_assert_false (g_hash_table_lookup_extended (lowest->filesystems, "/three", NULL, NULL));

      g_assert_true (g_hash_table_lookup_extended (middle->filesystems, "host", NULL, &value));
      g_assert_cmpint (GPOINTER_TO_INT (value), ==, FLATPAK_FILESYSTEM_MODE_NONE);
      g_assert_true (g_hash_table_lookup_extended (middle->filesystems, "host-reset", NULL, &value));
      g_assert_cmpint (GPOINTER_TO_INT (value), ==, FLATPAK_FILESYSTEM_MODE_NONE);
      g_assert_false (g_hash_table_lookup_extended (middle->filesystems, "/one", NULL, NULL));
      g_assert_true (g_hash_table_lookup_extended (middle->filesystems, "/two", NULL, &value));
      g_assert_cmpint (GPOINTER_TO_INT (value), ==, FLATPAK_FILESYSTEM_MODE_READ_WRITE);
      g_assert_false (g_hash_table_lookup_extended (middle->filesystems, "/three", NULL, NULL));

      g_assert_true (g_hash_table_lookup_extended (highest->filesystems, "host", NULL, &value));
      g_assert_cmpint (GPOINTER_TO_INT (value), ==, FLATPAK_FILESYSTEM_MODE_NONE);
      g_assert_false (g_hash_table_lookup_extended (highest->filesystems, "host-reset", NULL, NULL));
      g_assert_false (g_hash_table_lookup_extended (highest->filesystems, "/one", NULL, NULL));
      g_assert_false (g_hash_table_lookup_extended (highest->filesystems, "/two", NULL, NULL));
      g_assert_true (g_hash_table_lookup_extended (highest->filesystems, "/three", NULL, &value));
      g_assert_cmpint (GPOINTER_TO_INT (value), ==, FLATPAK_FILESYSTEM_MODE_READ_WRITE);

      if (merge_order == LOWEST_FIRST)
        {
          flatpak_context_merge (lowest, middle);

          g_assert_true (g_hash_table_lookup_extended (lowest->filesystems, "host", NULL, &value));
          g_assert_cmpint (GPOINTER_TO_INT (value), ==, FLATPAK_FILESYSTEM_MODE_NONE);
          g_assert_true (g_hash_table_lookup_extended (lowest->filesystems, "host-reset", NULL, &value));
          g_assert_cmpint (GPOINTER_TO_INT (value), ==, FLATPAK_FILESYSTEM_MODE_NONE);
          g_assert_false (g_hash_table_lookup_extended (lowest->filesystems, "/one", NULL, NULL));
          g_assert_true (g_hash_table_lookup_extended (lowest->filesystems, "/two", NULL, &value));
          g_assert_cmpint (GPOINTER_TO_INT (value), ==, FLATPAK_FILESYSTEM_MODE_READ_WRITE);
          g_assert_false (g_hash_table_lookup_extended (lowest->filesystems, "/three", NULL, NULL));

          flatpak_context_merge (lowest, highest);
        }
      else
        {
          flatpak_context_merge (middle, highest);

          g_assert_true (g_hash_table_lookup_extended (middle->filesystems, "host", NULL, &value));
          g_assert_cmpint (GPOINTER_TO_INT (value), ==, FLATPAK_FILESYSTEM_MODE_NONE);
          g_assert_true (g_hash_table_lookup_extended (middle->filesystems, "host-reset", NULL, &value));
          g_assert_cmpint (GPOINTER_TO_INT (value), ==, FLATPAK_FILESYSTEM_MODE_NONE);
          g_assert_false (g_hash_table_lookup_extended (middle->filesystems, "/one", NULL, NULL));
          g_assert_true (g_hash_table_lookup_extended (middle->filesystems, "/two", NULL, &value));
          g_assert_cmpint (GPOINTER_TO_INT (value), ==, FLATPAK_FILESYSTEM_MODE_READ_WRITE);
          g_assert_true (g_hash_table_lookup_extended (middle->filesystems, "/three", NULL, &value));
          g_assert_cmpint (GPOINTER_TO_INT (value), ==, FLATPAK_FILESYSTEM_MODE_READ_WRITE);

          flatpak_context_merge (lowest, middle);
        }

      g_assert_true (g_hash_table_lookup_extended (lowest->filesystems, "host", NULL, &value));
      g_assert_cmpint (GPOINTER_TO_INT (value), ==, FLATPAK_FILESYSTEM_MODE_NONE);
      g_assert_true (g_hash_table_lookup_extended (lowest->filesystems, "host-reset", NULL, &value));
      g_assert_cmpint (GPOINTER_TO_INT (value), ==, FLATPAK_FILESYSTEM_MODE_NONE);
      g_assert_false (g_hash_table_lookup_extended (lowest->filesystems, "/one", NULL, NULL));
      g_assert_true (g_hash_table_lookup_extended (lowest->filesystems, "/two", NULL, &value));
      g_assert_cmpint (GPOINTER_TO_INT (value), ==, FLATPAK_FILESYSTEM_MODE_READ_WRITE);
      g_assert_true (g_hash_table_lookup_extended (lowest->filesystems, "/three", NULL, &value));
      g_assert_cmpint (GPOINTER_TO_INT (value), ==, FLATPAK_FILESYSTEM_MODE_READ_WRITE);
    }

  for (merge_order = LOWEST_FIRST; merge_order < INVALID; merge_order++)
    {
      g_autoptr(FlatpakContext) lowest = flatpak_context_new ();
      g_autoptr(FlatpakContext) mid_low = flatpak_context_new ();
      g_autoptr(FlatpakContext) mid_high = flatpak_context_new ();
      g_autoptr(FlatpakContext) highest = flatpak_context_new ();
      g_autoptr(GError) local_error = NULL;
      g_autoptr(GKeyFile) metakey = g_key_file_new ();
      g_autoptr(GPtrArray) args = g_ptr_array_new_with_free_func (g_free);
      g_autofree char *filesystems = NULL;
      gpointer value;

      context_parse_args (lowest,
                          &local_error,
                          "--filesystem=/one",
                          NULL);
      g_assert_no_error (local_error);
      context_parse_args (mid_low,
                          &local_error,
                          "--nofilesystem=host:reset",
                          "--filesystem=/two",
                          NULL);
      g_assert_no_error (local_error);
      context_parse_args (mid_high,
                          &local_error,
                          "--filesystem=host",
                          "--filesystem=/three",
                          NULL);
      g_assert_no_error (local_error);
      context_parse_args (highest,
                          &local_error,
                          "--nofilesystem=host",
                          "--filesystem=/four",
                          NULL);
      g_assert_no_error (local_error);

      g_assert_false (g_hash_table_lookup_extended (lowest->filesystems, "host", NULL, NULL));
      g_assert_false (g_hash_table_lookup_extended (lowest->filesystems, "host-reset", NULL, NULL));
      g_assert_true (g_hash_table_lookup_extended (lowest->filesystems, "/one", NULL, &value));
      g_assert_cmpint (GPOINTER_TO_INT (value), ==, FLATPAK_FILESYSTEM_MODE_READ_WRITE);
      g_assert_false (g_hash_table_lookup_extended (lowest->filesystems, "/two", NULL, NULL));
      g_assert_false (g_hash_table_lookup_extended (lowest->filesystems, "/three", NULL, NULL));
      g_assert_false (g_hash_table_lookup_extended (lowest->filesystems, "/four", NULL, NULL));

      g_assert_true (g_hash_table_lookup_extended (mid_low->filesystems, "host", NULL, &value));
      g_assert_cmpint (GPOINTER_TO_INT (value), ==, FLATPAK_FILESYSTEM_MODE_NONE);
      g_assert_true (g_hash_table_lookup_extended (mid_low->filesystems, "host-reset", NULL, &value));
      g_assert_cmpint (GPOINTER_TO_INT (value), ==, FLATPAK_FILESYSTEM_MODE_NONE);
      g_assert_false (g_hash_table_lookup_extended (mid_low->filesystems, "/one", NULL, NULL));
      g_assert_true (g_hash_table_lookup_extended (mid_low->filesystems, "/two", NULL, &value));
      g_assert_cmpint (GPOINTER_TO_INT (value), ==, FLATPAK_FILESYSTEM_MODE_READ_WRITE);
      g_assert_false (g_hash_table_lookup_extended (mid_low->filesystems, "/three", NULL, NULL));
      g_assert_false (g_hash_table_lookup_extended (mid_low->filesystems, "/four", NULL, NULL));

      g_assert_true (g_hash_table_lookup_extended (mid_high->filesystems, "host", NULL, &value));
      g_assert_cmpint (GPOINTER_TO_INT (value), ==, FLATPAK_FILESYSTEM_MODE_READ_WRITE);
      g_assert_false (g_hash_table_lookup_extended (mid_high->filesystems, "host-reset", NULL, NULL));
      g_assert_false (g_hash_table_lookup_extended (mid_high->filesystems, "/one", NULL, NULL));
      g_assert_false (g_hash_table_lookup_extended (mid_high->filesystems, "/two", NULL, NULL));
      g_assert_true (g_hash_table_lookup_extended (mid_high->filesystems, "/three", NULL, &value));
      g_assert_cmpint (GPOINTER_TO_INT (value), ==, FLATPAK_FILESYSTEM_MODE_READ_WRITE);
      g_assert_false (g_hash_table_lookup_extended (mid_high->filesystems, "/four", NULL, NULL));

      g_assert_true (g_hash_table_lookup_extended (highest->filesystems, "host", NULL, &value));
      g_assert_cmpint (GPOINTER_TO_INT (value), ==, FLATPAK_FILESYSTEM_MODE_NONE);
      g_assert_false (g_hash_table_lookup_extended (highest->filesystems, "host-reset", NULL, NULL));
      g_assert_false (g_hash_table_lookup_extended (highest->filesystems, "/one", NULL, NULL));
      g_assert_false (g_hash_table_lookup_extended (highest->filesystems, "/two", NULL, NULL));
      g_assert_false (g_hash_table_lookup_extended (highest->filesystems, "/three", NULL, NULL));
      g_assert_true (g_hash_table_lookup_extended (highest->filesystems, "/four", NULL, &value));
      g_assert_cmpint (GPOINTER_TO_INT (value), ==, FLATPAK_FILESYSTEM_MODE_READ_WRITE);

      if (merge_order == LOWEST_FIRST)
        {
          flatpak_context_merge (lowest, mid_low);

          g_assert_true (g_hash_table_lookup_extended (lowest->filesystems, "host", NULL, &value));
          g_assert_cmpint (GPOINTER_TO_INT (value), ==, FLATPAK_FILESYSTEM_MODE_NONE);
          g_assert_true (g_hash_table_lookup_extended (lowest->filesystems, "host-reset", NULL, &value));
          g_assert_cmpint (GPOINTER_TO_INT (value), ==, FLATPAK_FILESYSTEM_MODE_NONE);
          g_assert_false (g_hash_table_lookup_extended (lowest->filesystems, "/one", NULL, NULL));
          g_assert_true (g_hash_table_lookup_extended (lowest->filesystems, "/two", NULL, &value));
          g_assert_cmpint (GPOINTER_TO_INT (value), ==, FLATPAK_FILESYSTEM_MODE_READ_WRITE);
          g_assert_false (g_hash_table_lookup_extended (lowest->filesystems, "/three", NULL, NULL));
          g_assert_false (g_hash_table_lookup_extended (lowest->filesystems, "/four", NULL, NULL));

          flatpak_context_merge (lowest, mid_high);

          g_assert_true (g_hash_table_lookup_extended (lowest->filesystems, "host", NULL, &value));
          g_assert_cmpint (GPOINTER_TO_INT (value), ==, FLATPAK_FILESYSTEM_MODE_READ_WRITE);
          g_assert_true (g_hash_table_lookup_extended (lowest->filesystems, "host-reset", NULL, &value));
          g_assert_cmpint (GPOINTER_TO_INT (value), ==, FLATPAK_FILESYSTEM_MODE_NONE);
          g_assert_false (g_hash_table_lookup_extended (lowest->filesystems, "/one", NULL, NULL));
          g_assert_true (g_hash_table_lookup_extended (lowest->filesystems, "/two", NULL, &value));
          g_assert_cmpint (GPOINTER_TO_INT (value), ==, FLATPAK_FILESYSTEM_MODE_READ_WRITE);
          g_assert_true (g_hash_table_lookup_extended (lowest->filesystems, "/three", NULL, &value));
          g_assert_cmpint (GPOINTER_TO_INT (value), ==, FLATPAK_FILESYSTEM_MODE_READ_WRITE);
          g_assert_false (g_hash_table_lookup_extended (lowest->filesystems, "/four", NULL, NULL));

          flatpak_context_merge (lowest, highest);
        }
      else
        {
          flatpak_context_merge (mid_high, highest);

          g_assert_true (g_hash_table_lookup_extended (mid_high->filesystems, "host", NULL, &value));
          g_assert_cmpint (GPOINTER_TO_INT (value), ==, FLATPAK_FILESYSTEM_MODE_NONE);
          g_assert_false (g_hash_table_lookup_extended (mid_high->filesystems, "host-reset", NULL, NULL));
          g_assert_false (g_hash_table_lookup_extended (mid_high->filesystems, "/one", NULL, NULL));
          g_assert_false (g_hash_table_lookup_extended (mid_high->filesystems, "/two", NULL, NULL));
          g_assert_true (g_hash_table_lookup_extended (mid_high->filesystems, "/three", NULL, &value));
          g_assert_cmpint (GPOINTER_TO_INT (value), ==, FLATPAK_FILESYSTEM_MODE_READ_WRITE);
          g_assert_true (g_hash_table_lookup_extended (mid_high->filesystems, "/four", NULL, &value));
          g_assert_cmpint (GPOINTER_TO_INT (value), ==, FLATPAK_FILESYSTEM_MODE_READ_WRITE);

          flatpak_context_merge (mid_low, mid_high);

          g_assert_true (g_hash_table_lookup_extended (mid_low->filesystems, "host", NULL, &value));
          g_assert_cmpint (GPOINTER_TO_INT (value), ==, FLATPAK_FILESYSTEM_MODE_NONE);
          g_assert_true (g_hash_table_lookup_extended (mid_low->filesystems, "host-reset", NULL, &value));
          g_assert_cmpint (GPOINTER_TO_INT (value), ==, FLATPAK_FILESYSTEM_MODE_NONE);
          g_assert_false (g_hash_table_lookup_extended (mid_low->filesystems, "/one", NULL, NULL));
          g_assert_true (g_hash_table_lookup_extended (mid_low->filesystems, "/two", NULL, &value));
          g_assert_cmpint (GPOINTER_TO_INT (value), ==, FLATPAK_FILESYSTEM_MODE_READ_WRITE);
          g_assert_true (g_hash_table_lookup_extended (mid_low->filesystems, "/three", NULL, &value));
          g_assert_cmpint (GPOINTER_TO_INT (value), ==, FLATPAK_FILESYSTEM_MODE_READ_WRITE);
          g_assert_true (g_hash_table_lookup_extended (mid_low->filesystems, "/four", NULL, &value));
          g_assert_cmpint (GPOINTER_TO_INT (value), ==, FLATPAK_FILESYSTEM_MODE_READ_WRITE);

          flatpak_context_merge (lowest, mid_low);
        }

      g_assert_true (g_hash_table_lookup_extended (lowest->filesystems, "host", NULL, &value));
      g_assert_cmpint (GPOINTER_TO_INT (value), ==, FLATPAK_FILESYSTEM_MODE_NONE);
      g_assert_true (g_hash_table_lookup_extended (lowest->filesystems, "host-reset", NULL, &value));
      g_assert_cmpint (GPOINTER_TO_INT (value), ==, FLATPAK_FILESYSTEM_MODE_NONE);
      g_assert_false (g_hash_table_lookup_extended (lowest->filesystems, "/one", NULL, NULL));
      g_assert_true (g_hash_table_lookup_extended (lowest->filesystems, "/two", NULL, &value));
      g_assert_cmpint (GPOINTER_TO_INT (value), ==, FLATPAK_FILESYSTEM_MODE_READ_WRITE);
      g_assert_true (g_hash_table_lookup_extended (lowest->filesystems, "/three", NULL, &value));
      g_assert_cmpint (GPOINTER_TO_INT (value), ==, FLATPAK_FILESYSTEM_MODE_READ_WRITE);
      g_assert_true (g_hash_table_lookup_extended (lowest->filesystems, "/four", NULL, &value));
      g_assert_cmpint (GPOINTER_TO_INT (value), ==, FLATPAK_FILESYSTEM_MODE_READ_WRITE);

      flatpak_context_save_metadata (lowest, FALSE, metakey);
      filesystems = g_key_file_get_value (metakey,
                                          FLATPAK_METADATA_GROUP_CONTEXT,
                                          FLATPAK_METADATA_KEY_FILESYSTEMS,
                                          &local_error);
      g_assert_no_error (local_error);
      g_test_message ("%s=%s", FLATPAK_METADATA_KEY_FILESYSTEMS, filesystems);
      /* !host:reset is serialized first */
      g_assert_true (g_str_has_prefix (filesystems, "!host:reset;"));
      /* The rest are serialized in arbitrary order */
      g_assert_nonnull (strstr (filesystems, ";!host;"));
      g_assert_null (strstr (filesystems, "/one"));
      g_assert_nonnull (strstr (filesystems, ";/two;"));
      g_assert_nonnull (strstr (filesystems, ";/three;"));
      g_assert_nonnull (strstr (filesystems, ";/four;"));

      flatpak_context_to_args (lowest, args);
      /* !host:reset is serialized first */
      g_assert_cmpuint (args->len, >, 0);
      g_assert_cmpstr (g_ptr_array_index (args, 0), ==,
                       "--nofilesystem=host:reset");
      /* The rest are serialized in arbitrary order */
      g_assert_true (g_ptr_array_find_with_equal_func (args, "--nofilesystem=host", g_str_equal, NULL));
      g_assert_false (g_ptr_array_find_with_equal_func (args, "--filesystem=/one", str_has_prefix, NULL));
      g_assert_false (g_ptr_array_find_with_equal_func (args, "--nofilesystem=/one", str_has_prefix, NULL));
      g_assert_true (g_ptr_array_find_with_equal_func (args, "--filesystem=/two", g_str_equal, NULL));
      g_assert_true (g_ptr_array_find_with_equal_func (args, "--filesystem=/three", g_str_equal, NULL));
      g_assert_true (g_ptr_array_find_with_equal_func (args, "--filesystem=/four", g_str_equal, NULL));
    }
}

const char *invalid_path_args[] = {
  "--filesystem=/\033[J:ro",
  "--filesystem=/\033[J",
  "--persist=\033[J",
};

/* CVE-2023-28101 */
static void
test_validate_path_args (void)
{
  gsize idx;

  for (idx = 0; idx < G_N_ELEMENTS (invalid_path_args); idx++)
    {
      g_autoptr(FlatpakContext) context = flatpak_context_new ();
      g_autoptr(GError) local_error = NULL;
      const char *path = invalid_path_args[idx];

      context_parse_args (context, &local_error, path, NULL);
      g_assert_error (local_error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA);
      g_assert (strstr (local_error->message, "Non-graphical character"));
    }
}

typedef struct {
  const char *key;
  const char *value;
} PathValidityData;

PathValidityData invalid_path_meta[] = {
  {FLATPAK_METADATA_KEY_FILESYSTEMS, "\033[J"},
  {FLATPAK_METADATA_KEY_PERSISTENT, "\033[J"},
};

/* CVE-2023-28101 */
static void
test_validate_path_meta (void)
{
  gsize idx;

  for (idx = 0; idx < G_N_ELEMENTS (invalid_path_meta); idx++)
    {
      g_autoptr(FlatpakContext) context = flatpak_context_new ();
      g_autoptr(GKeyFile) metakey = g_key_file_new ();
      g_autoptr(GError) local_error = NULL;
      PathValidityData *data = &invalid_path_meta[idx];
      gboolean ret = FALSE;

      g_key_file_set_string_list (metakey, FLATPAK_METADATA_GROUP_CONTEXT,
                                  data->key, &data->value, 1);

      ret = flatpak_context_load_metadata (context, metakey, &local_error);
      g_assert_false (ret);
      g_assert_error (local_error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA);
      g_assert (strstr (local_error->message, "Non-graphical character"));
    }

}

static void
test_usb_list (void)
{
  const char *gtest_srcdir = NULL;
  g_autofree char *test_file_path = NULL;
  g_autofree char *content = NULL;
  g_autofree char *list = NULL;
  gboolean ret = FALSE;
  g_autoptr(GError) error = NULL;
  g_autoptr(GHashTable) enumerable = g_hash_table_new_full (g_str_hash, g_str_equal,
							 g_free, (GDestroyNotify) flatpak_usb_query_free);
  g_autoptr(GHashTable) hidden = g_hash_table_new_full (g_str_hash, g_str_equal,
							 g_free, (GDestroyNotify) flatpak_usb_query_free);

  gtest_srcdir = g_getenv ("G_TEST_SRCDIR");
  g_assert (gtest_srcdir);
  test_file_path = g_build_filename (gtest_srcdir, "gphoto2-list", NULL);

  ret = g_file_get_contents (test_file_path, &content, NULL, &error);
  g_assert (ret);

  ret = flatpak_usb_parse_usb_list (content, enumerable, hidden, &error);

  g_assert (ret);
  g_assert_no_error (error);
  g_assert_cmpint (g_hash_table_size (hidden), ==, 4);
  g_assert_cmpint (g_hash_table_size (enumerable), ==, 2344);

  list = flatpak_context_devices_to_usb_list (hidden, TRUE);
  g_assert_cmpstr (list, ==, "!vnd:0502+dev:33c3;!vnd:4102+dev:1213;!vnd:0502+dev:365e;!vnd:0502+dev:387a;");

  g_hash_table_remove_all (enumerable);
  g_hash_table_remove_all (hidden);
  ret = flatpak_usb_parse_usb_list (list, enumerable, hidden, &error);
  g_assert (ret);
  g_assert_no_error (error);
  g_assert_cmpint (g_hash_table_size (hidden), ==, 4);
  g_assert_cmpint (g_hash_table_size (enumerable), ==, 0);
}

static void
test_usb_rules_all (void)
{
  g_autoptr(FlatpakUsbRule) usb_rule = NULL;
  g_autoptr(GError) local_error = NULL;
  gboolean ret = FALSE;

  /* Valid USB 'all' rule */
  ret = flatpak_usb_parse_usb_rule ("all", &usb_rule, &local_error);
  g_assert_true (ret);
  g_assert_no_error (local_error);
  g_assert_cmpint (usb_rule->rule_type, ==, FLATPAK_USB_RULE_TYPE_ALL);
    {
      g_autoptr(GString) string = g_string_new (NULL);
      flatpak_usb_rule_print (usb_rule, string);
      g_assert_cmpstr (string->str, ==, "all");
    }
  g_clear_pointer (&usb_rule, flatpak_usb_rule_free);

  /* Invalid USB 'all' rule */
  ret = flatpak_usb_parse_usb_rule ("all:09", &usb_rule, &local_error);
  g_assert_false (ret);
  g_assert_null (usb_rule);
  g_assert_error (local_error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE);
  g_clear_error (&local_error);
}

static void
test_usb_rules_cls (void)
{
  g_autoptr(FlatpakUsbRule) usb_rule = NULL;
  g_autoptr(GError) local_error = NULL;
  gboolean ret = FALSE;

  /* Valid USB 'cls' rules */
  ret = flatpak_usb_parse_usb_rule ("cls:09:03", &usb_rule, &local_error);
  g_assert_true (ret);
  g_assert_no_error (local_error);
  g_assert_cmpint (usb_rule->rule_type, ==, FLATPAK_USB_RULE_TYPE_CLASS);
  g_assert_cmpint (usb_rule->d.device_class.type, ==, FLATPAK_USB_RULE_CLASS_TYPE_CLASS_SUBCLASS);
  g_assert_cmpuint (usb_rule->d.device_class.class, ==, 0x09);
  g_assert_cmpuint (usb_rule->d.device_class.subclass, ==, 0x03);
    {
      g_autoptr(GString) string = g_string_new (NULL);
      flatpak_usb_rule_print (usb_rule, string);
      g_assert_cmpstr (string->str, ==, "cls:09:03");
    }
  g_clear_pointer (&usb_rule, flatpak_usb_rule_free);

  ret = flatpak_usb_parse_usb_rule ("cls:09:*", &usb_rule, &local_error);
  g_assert_true (ret);
  g_assert_no_error (local_error);
  g_assert_cmpint (usb_rule->rule_type, ==, FLATPAK_USB_RULE_TYPE_CLASS);
  g_assert_cmpint (usb_rule->d.device_class.type, ==, FLATPAK_USB_RULE_CLASS_TYPE_CLASS_ONLY);
  g_assert_cmpuint (usb_rule->d.device_class.class, ==, 0x09);
    {
      g_autoptr(GString) string = g_string_new (NULL);
      flatpak_usb_rule_print (usb_rule, string);
      g_assert_cmpstr (string->str, ==, "cls:09:*");
    }
  g_clear_pointer (&usb_rule, flatpak_usb_rule_free);

  ret = flatpak_usb_parse_usb_rule ("cls:00:00", &usb_rule, &local_error);
  g_assert_true (ret);
  g_assert_no_error (local_error);
  g_clear_pointer (&usb_rule, flatpak_usb_rule_free);

  /* Invalid USB 'cls' rules */
  ret = flatpak_usb_parse_usb_rule ("cls:0009:0003", &usb_rule, &local_error);
  g_assert_false (ret);
  g_assert_null (usb_rule);
  g_assert_error (local_error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE);
  g_clear_pointer (&usb_rule, flatpak_usb_rule_free);
  g_clear_error (&local_error);

  ret = flatpak_usb_parse_usb_rule ("cls:*:03", &usb_rule, &local_error);
  g_assert_false (ret);
  g_assert_null (usb_rule);
  g_assert_error (local_error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE);
  g_clear_pointer (&usb_rule, flatpak_usb_rule_free);
  g_clear_error (&local_error);

  ret = flatpak_usb_parse_usb_rule ("cls:*:*", &usb_rule, &local_error);
  g_assert_false (ret);
  g_assert_null (usb_rule);
  g_assert_error (local_error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE);
  g_clear_pointer (&usb_rule, flatpak_usb_rule_free);
  g_clear_error (&local_error);

  ret = flatpak_usb_parse_usb_rule ("cls:*", &usb_rule, &local_error);
  g_assert_false (ret);
  g_assert_null (usb_rule);
  g_assert_error (local_error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE);
  g_clear_pointer (&usb_rule, flatpak_usb_rule_free);
  g_clear_error (&local_error);

  ret = flatpak_usb_parse_usb_rule ("cls", &usb_rule, &local_error);
  g_assert_false (ret);
  g_assert_null (usb_rule);
  g_assert_error (local_error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE);
  g_clear_pointer (&usb_rule, flatpak_usb_rule_free);
  g_clear_error (&local_error);
}

static void
test_usb_rules_dev (void)
{
  g_autoptr(FlatpakUsbRule) usb_rule = NULL;
  g_autoptr(GError) local_error = NULL;
  gboolean ret = FALSE;

  /* Valid USB 'dev' rules */
  ret = flatpak_usb_parse_usb_rule ("dev:0060", &usb_rule, &local_error);
  g_assert_true (ret);
  g_assert_no_error (local_error);
  g_assert_cmpint (usb_rule->rule_type, ==, FLATPAK_USB_RULE_TYPE_DEVICE);
  g_assert_cmpuint (usb_rule->d.product.id, ==, 0x0060);
    {
      g_autoptr(GString) string = g_string_new (NULL);
      flatpak_usb_rule_print (usb_rule, string);
      g_assert_cmpstr (string->str, ==, "dev:0060");
    }
  g_clear_pointer (&usb_rule, flatpak_usb_rule_free);

  ret = flatpak_usb_parse_usb_rule ("dev:0000", &usb_rule, &local_error);
  g_assert_true (ret);
  g_assert_no_error (local_error);
  g_clear_pointer (&usb_rule, flatpak_usb_rule_free);

  /* Invalid USB 'dev' rules */
  ret = flatpak_usb_parse_usb_rule ("dev:00", &usb_rule, &local_error);
  g_assert_false (ret);
  g_assert_null (usb_rule);
  g_assert_error (local_error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE);
  g_clear_pointer (&usb_rule, flatpak_usb_rule_free);
  g_clear_error (&local_error);

  ret = flatpak_usb_parse_usb_rule ("dev:*", &usb_rule, &local_error);
  g_assert_false (ret);
  g_assert_null (usb_rule);
  g_assert_error (local_error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE);
  g_clear_pointer (&usb_rule, flatpak_usb_rule_free);
  g_clear_error (&local_error);

  ret = flatpak_usb_parse_usb_rule ("dev", &usb_rule, &local_error);
  g_assert_false (ret);
  g_assert_null (usb_rule);
  g_assert_error (local_error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE);
  g_clear_pointer (&usb_rule, flatpak_usb_rule_free);
  g_clear_error (&local_error);
}

static void
test_usb_rules_vnd (void)
{
  g_autoptr(FlatpakUsbRule) usb_rule = NULL;
  g_autoptr(GError) local_error = NULL;
  gboolean ret = FALSE;

  /* Valid USB 'vnd' rules */
  ret = flatpak_usb_parse_usb_rule ("vnd:0fd9", &usb_rule, &local_error);
  g_assert_true (ret);
  g_assert_no_error (local_error);
  g_assert_cmpint (usb_rule->rule_type, ==, FLATPAK_USB_RULE_TYPE_VENDOR);
  g_assert_cmpuint (usb_rule->d.vendor.id, ==, 0x0fd9);
    {
      g_autoptr(GString) string = g_string_new (NULL);
      flatpak_usb_rule_print (usb_rule, string);
      g_assert_cmpstr (string->str, ==, "vnd:0fd9");
    }
  g_clear_pointer (&usb_rule, flatpak_usb_rule_free);

  ret = flatpak_usb_parse_usb_rule ("vnd:0000", &usb_rule, &local_error);
  g_assert_true (ret);
  g_assert_no_error (local_error);
  g_clear_pointer (&usb_rule, flatpak_usb_rule_free);

  /* Invalid USB 'vnd' rules */
  ret = flatpak_usb_parse_usb_rule ("vnd:00", &usb_rule, &local_error);
  g_assert_false (ret);
  g_assert_null (usb_rule);
  g_assert_error (local_error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE);
  g_clear_pointer (&usb_rule, flatpak_usb_rule_free);
  g_clear_error (&local_error);

  ret = flatpak_usb_parse_usb_rule ("vnd:*", &usb_rule, &local_error);
  g_assert_false (ret);
  g_assert_null (usb_rule);
  g_assert_error (local_error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE);
  g_clear_pointer (&usb_rule, flatpak_usb_rule_free);
  g_clear_error (&local_error);

  ret = flatpak_usb_parse_usb_rule ("vnd", &usb_rule, &local_error);
  g_assert_false (ret);
  g_assert_null (usb_rule);
  g_assert_error (local_error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE);
  g_clear_pointer (&usb_rule, flatpak_usb_rule_free);
  g_clear_error (&local_error);
}

static void
test_usb_query_simple (void)
{
  g_autoptr(FlatpakUsbQuery) usb_query = NULL;
  g_autoptr(GError) local_error = NULL;
  gboolean ret = FALSE;

  ret = flatpak_usb_parse_usb ("all", &usb_query, &local_error);
  g_assert_true (ret);
  g_assert_nonnull (usb_query);
  g_assert_no_error (local_error);
  g_assert_cmpuint (usb_query->rules->len, ==, 1);
    {
      FlatpakUsbRule *usb_rule = g_ptr_array_index (usb_query->rules, 0);
      g_assert_cmpint (usb_rule->rule_type, ==, FLATPAK_USB_RULE_TYPE_ALL);
    }
    {
      g_autoptr(GString) string = g_string_new (NULL);
      flatpak_usb_query_print (usb_query, string);
      g_assert_cmpstr (string->str, ==, "all");
    }
  g_clear_pointer (&usb_query, flatpak_usb_query_free);

  ret = flatpak_usb_parse_usb ("cls:03:*", &usb_query, &local_error);
  g_assert_true (ret);
  g_assert_nonnull (usb_query);
  g_assert_no_error (local_error);
  g_assert_cmpuint (usb_query->rules->len, ==, 1);
    {
      FlatpakUsbRule *usb_rule = g_ptr_array_index (usb_query->rules, 0);
      g_assert_cmpint (usb_rule->rule_type, ==, FLATPAK_USB_RULE_TYPE_CLASS);
      g_assert_cmpint (usb_rule->d.device_class.type, ==, FLATPAK_USB_RULE_CLASS_TYPE_CLASS_ONLY);
      g_assert_cmpuint (usb_rule->d.device_class.class, ==, 0x03);
    }
    {
      g_autoptr(GString) string = g_string_new (NULL);
      flatpak_usb_query_print (usb_query, string);
      g_assert_cmpstr (string->str, ==, "cls:03:*");
    }
  g_clear_pointer (&usb_query, flatpak_usb_query_free);

  ret = flatpak_usb_parse_usb ("vnd:0fd9", &usb_query, &local_error);
  g_assert_true (ret);
  g_assert_nonnull (usb_query);
  g_assert_no_error (local_error);
  g_assert_cmpuint (usb_query->rules->len, ==, 1);
    {
      FlatpakUsbRule *usb_rule = g_ptr_array_index (usb_query->rules, 0);
      g_assert_cmpint (usb_rule->rule_type, ==, FLATPAK_USB_RULE_TYPE_VENDOR);
      g_assert_cmpuint (usb_rule->d.vendor.id, ==, 0x0fd9);
    }
    {
      g_autoptr(GString) string = g_string_new (NULL);
      flatpak_usb_query_print (usb_query, string);
      g_assert_cmpstr (string->str, ==, "vnd:0fd9");
    }
  g_clear_pointer (&usb_query, flatpak_usb_query_free);

  /* Invalid USB query */
  ret = flatpak_usb_parse_usb ("all:0123", &usb_query, &local_error);
  g_assert_false (ret);
  g_assert_null (usb_query);
  g_assert_error (local_error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE);
  g_clear_pointer (&usb_query, flatpak_usb_query_free);
  g_clear_error (&local_error);

  /* Invalid empty USB query */
  ret = flatpak_usb_parse_usb ("", &usb_query, &local_error);
  g_assert_false (ret);
  g_assert_null (usb_query);
  g_assert_error (local_error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE);
  g_clear_pointer (&usb_query, flatpak_usb_query_free);
  g_clear_error (&local_error);
}

static void
test_usb_query_device_and_vendor (void)
{
  g_autoptr(FlatpakUsbQuery) usb_query = NULL;
  g_autoptr(GError) local_error = NULL;
  gboolean ret = FALSE;

  ret = flatpak_usb_parse_usb ("vnd:0fd9+dev:0063", &usb_query, &local_error);
  g_assert_true (ret);
  g_assert_no_error (local_error);
  g_assert_cmpuint (usb_query->rules->len, ==, 2);
    {
      FlatpakUsbRule *usb_rule;

      usb_rule = g_ptr_array_index (usb_query->rules, 0);
      g_assert_cmpint (usb_rule->rule_type, ==, FLATPAK_USB_RULE_TYPE_VENDOR);
      g_assert_cmpuint (usb_rule->d.vendor.id, ==, 0x0fd9);

      usb_rule = g_ptr_array_index (usb_query->rules, 1);
      g_assert_cmpint (usb_rule->rule_type, ==, FLATPAK_USB_RULE_TYPE_DEVICE);
      g_assert_cmpuint (usb_rule->d.product.id, ==, 0x063);
    }
    {
      g_autoptr(GString) string = g_string_new (NULL);
      flatpak_usb_query_print (usb_query, string);
      g_assert_cmpstr (string->str, ==, "vnd:0fd9+dev:0063");
    }
  g_clear_pointer (&usb_query, flatpak_usb_query_free);

  ret = flatpak_usb_parse_usb ("vnd:0fd9+dev:0063+cls:09:*", &usb_query, &local_error);
  g_assert_true (ret);
  g_assert_no_error (local_error);
  g_assert_cmpuint (usb_query->rules->len, ==, 3);
    {
      FlatpakUsbRule *usb_rule;

      usb_rule = g_ptr_array_index (usb_query->rules, 0);
      g_assert_cmpint (usb_rule->rule_type, ==, FLATPAK_USB_RULE_TYPE_VENDOR);
      g_assert_cmpuint (usb_rule->d.vendor.id, ==, 0x0fd9);

      usb_rule = g_ptr_array_index (usb_query->rules, 1);
      g_assert_cmpint (usb_rule->rule_type, ==, FLATPAK_USB_RULE_TYPE_DEVICE);
      g_assert_cmpuint (usb_rule->d.product.id, ==, 0x063);

      usb_rule = g_ptr_array_index (usb_query->rules, 2);
      g_assert_cmpint (usb_rule->rule_type, ==, FLATPAK_USB_RULE_TYPE_CLASS);
      g_assert_cmpint (usb_rule->d.device_class.type, ==, FLATPAK_USB_RULE_CLASS_TYPE_CLASS_ONLY);
      g_assert_cmpuint (usb_rule->d.device_class.class, ==, 0x09);
    }
    {
      g_autoptr(GString) string = g_string_new (NULL);
      flatpak_usb_query_print (usb_query, string);
      g_assert_cmpstr (string->str, ==, "vnd:0fd9+dev:0063+cls:09:*");
    }
  g_clear_pointer (&usb_query, flatpak_usb_query_free);

  /* Device without vendor is invalid */
  ret = flatpak_usb_parse_usb ("dev:0063", &usb_query, &local_error);
  g_assert_false (ret);
  g_assert_null (usb_query);
  g_assert_error (local_error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE);
  g_clear_pointer (&usb_query, flatpak_usb_query_free);
  g_clear_error (&local_error);

  /* 'all' in the query invalidates further rules */
  ret = flatpak_usb_parse_usb ("all+dev:0063", &usb_query, &local_error);
  g_assert_false (ret);
  g_assert_null (usb_query);
  g_assert_error (local_error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE);
  g_clear_pointer (&usb_query, flatpak_usb_query_free);
  g_clear_error (&local_error);

  ret = flatpak_usb_parse_usb ("all+vnd:0fd+dev:0063", &usb_query, &local_error);
  g_assert_false (ret);
  g_assert_null (usb_query);
  g_assert_error (local_error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE);
  g_clear_pointer (&usb_query, flatpak_usb_query_free);
  g_clear_error (&local_error);
}

static void
test_devices (void)
{
  FlatpakContextDevices devices;

  /* single layer behavior */
  g_autoptr(GKeyFile) keyfile = g_key_file_new ();
  g_key_file_set_value (keyfile,
                        FLATPAK_METADATA_GROUP_CONTEXT,
                        FLATPAK_METADATA_KEY_DEVICES,
                        "!dri;input;all;if:all:!true");
  g_autoptr(FlatpakContext) context1 = flatpak_context_new ();
  flatpak_context_load_metadata (context1, keyfile, NULL);

  devices = flatpak_context_compute_allowed_devices (context1, NULL);
  g_assert_cmpint (devices, ==, FLATPAK_CONTEXT_DEVICE_INPUT);

  /* conditional in the next layer gives access to all */
  g_autoptr(GKeyFile) keyfile2 = g_key_file_new ();
  g_key_file_set_value (keyfile2,
                        FLATPAK_METADATA_GROUP_CONTEXT,
                        FLATPAK_METADATA_KEY_DEVICES,
                        "if:all:true");
  g_autoptr(FlatpakContext) context2 = flatpak_context_new ();
  flatpak_context_load_metadata (context2, keyfile2, NULL);
  flatpak_context_merge (context1, context2);
  devices = flatpak_context_compute_allowed_devices (context1, NULL);
  g_assert_cmpint (devices, ==, FLATPAK_CONTEXT_DEVICE_INPUT | FLATPAK_CONTEXT_DEVICE_ALL);

  /* removing permission in the next layer should result in no permission */
  g_autoptr(GKeyFile) keyfile3 = g_key_file_new ();
  g_key_file_set_value (keyfile3,
                        FLATPAK_METADATA_GROUP_CONTEXT,
                        FLATPAK_METADATA_KEY_DEVICES,
                        "!all");
  g_autoptr(FlatpakContext) context3 = flatpak_context_new ();
  flatpak_context_load_metadata (context3, keyfile3, NULL);
  flatpak_context_merge (context1, context3);
  devices = flatpak_context_compute_allowed_devices (context1, NULL);
  g_assert_cmpint (devices, ==, FLATPAK_CONTEXT_DEVICE_INPUT);

  /* the previous conditional gets reset by specifying all or !all */
  g_autoptr(GKeyFile) keyfile4 = g_key_file_new ();
  g_key_file_set_value (keyfile4,
                        FLATPAK_METADATA_GROUP_CONTEXT,
                        FLATPAK_METADATA_KEY_DEVICES,
                        "all;if:all:false");
  g_autoptr(FlatpakContext) context4 = flatpak_context_new ();
  flatpak_context_load_metadata (context4, keyfile4, NULL);
  flatpak_context_merge (context1, context4);
  devices = flatpak_context_compute_allowed_devices (context1, NULL);
  g_assert_cmpint (devices, ==, FLATPAK_CONTEXT_DEVICE_INPUT);
}

static gboolean
test_sockets_evaluate_conditions_false (FlatpakContextConditions condition)
{
  return FALSE;
}

static gboolean
test_sockets_evaluate_conditions_has_wayland (FlatpakContextConditions condition)
{
  switch (condition)
    {
    case FLATPAK_CONTEXT_CONDITION_HAS_WAYLAND:
      return TRUE;
    default:
      return FALSE;
    }
}

static void
test_sockets (void)
{
  FlatpakContextSockets sockets;

  /* test fallback-x11 special handling */
  g_autoptr(GKeyFile) keyfile1 = g_key_file_new ();
  g_key_file_set_value (keyfile1,
                        FLATPAK_METADATA_GROUP_CONTEXT,
                        FLATPAK_METADATA_KEY_SOCKETS,
                        "fallback-x11;wayland");
  g_autoptr(FlatpakContext) context1 = flatpak_context_new ();
  flatpak_context_load_metadata (context1, keyfile1, NULL);


  g_autoptr(GKeyFile) metakey = g_key_file_new ();
  g_autofree char *sockets_str = NULL;
  flatpak_context_save_metadata (context1, FALSE, metakey);
  sockets_str = g_key_file_get_value (metakey,
                                      FLATPAK_METADATA_GROUP_CONTEXT,
                                      FLATPAK_METADATA_KEY_SOCKETS,
                                      NULL);
  g_assert_cmpstr (sockets_str, ==, "fallback-x11;wayland;");

  sockets = flatpak_context_compute_allowed_sockets (
    context1,
    test_sockets_evaluate_conditions_false);
  g_assert_cmpint (sockets, ==, FLATPAK_CONTEXT_SOCKET_X11 |
                                FLATPAK_CONTEXT_SOCKET_WAYLAND);

  sockets = flatpak_context_compute_allowed_sockets (
    context1,
    test_sockets_evaluate_conditions_has_wayland);
  g_assert_cmpint (sockets, ==, FLATPAK_CONTEXT_SOCKET_WAYLAND);

  g_autoptr(GKeyFile) keyfile2 = g_key_file_new ();
  g_key_file_set_value (keyfile2,
                        FLATPAK_METADATA_GROUP_CONTEXT,
                        FLATPAK_METADATA_KEY_SOCKETS,
                        "!x11");
  g_autoptr(FlatpakContext) context2 = flatpak_context_new ();
  flatpak_context_load_metadata (context2, keyfile2, NULL);
  flatpak_context_merge (context1, context2);

  sockets = flatpak_context_compute_allowed_sockets (
    context1,
    test_sockets_evaluate_conditions_false);
  g_assert_cmpint (sockets, ==, FLATPAK_CONTEXT_SOCKET_WAYLAND);

  sockets = flatpak_context_compute_allowed_sockets (
    context1,
    test_sockets_evaluate_conditions_has_wayland);
  g_assert_cmpint (sockets, ==, FLATPAK_CONTEXT_SOCKET_WAYLAND);
}

int
main (int argc, char *argv[])
{
  g_test_init (&argc, &argv, NULL);

  g_test_add_func ("/context/env", test_context_env);
  g_test_add_func ("/context/env-fd", test_context_env_fd);
  g_test_add_func ("/context/merge-fs", test_context_merge_fs);
  g_test_add_func ("/context/validate-path-args", test_validate_path_args);
  g_test_add_func ("/context/validate-path-meta", test_validate_path_meta);
  g_test_add_func ("/context/devices", test_devices);
  g_test_add_func ("/context/sockets", test_sockets);

  g_test_add_func ("/context/usb-list", test_usb_list);
  g_test_add_func ("/context/usb-rules/all", test_usb_rules_all);
  g_test_add_func ("/context/usb-rules/cls", test_usb_rules_cls);
  g_test_add_func ("/context/usb-rules/dev", test_usb_rules_dev);
  g_test_add_func ("/context/usb-rules/vnd", test_usb_rules_vnd);

  g_test_add_func ("/context/usb-query/simple", test_usb_query_simple);
  g_test_add_func ("/context/usb-query/device-and-vendor", test_usb_query_device_and_vendor);

  return g_test_run ();
}

===== ./tests/testcommon.c =====
#include "config.h"

#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>

#include <glib.h>
#include "flatpak.h"
#include "flatpak-utils-private.h"
#include "flatpak-appdata-private.h"
#include "flatpak-run-private.h"
#include "flatpak-run-x11-private.h"

static void
test_has_path_prefix (void)
{
  g_assert_true (flatpak_has_path_prefix ("/a/prefix/foo/bar", "/a/prefix"));
  g_assert_true (flatpak_has_path_prefix ("/a///prefix/foo/bar", "/a/prefix"));
  g_assert_true (flatpak_has_path_prefix ("/a/prefix/foo/bar", "/a/prefix/"));
  g_assert_true (flatpak_has_path_prefix ("/a/prefix/foo/bar", "/a/prefix//"));
  g_assert_true (flatpak_has_path_prefix ("/a/prefix/foo/bar", ""));
  g_assert_false (flatpak_has_path_prefix ("/a/prefixfoo/bar", "/a/prefix"));
}

static void
test_path_match_prefix (void)
{
  g_assert_cmpstr (flatpak_path_match_prefix ("/?/pre*", "/a/prefix/x"), ==, "/x");
  g_assert_cmpstr (flatpak_path_match_prefix ("/a/prefix/*", "/a/prefix/"), ==, "");
  g_assert_null (flatpak_path_match_prefix ("/?/pre?", "/a/prefix/x"));
}

static void
test_arches (void)
{
  const char **arches = flatpak_get_arches ();

#if defined(__i386__)
  g_assert_cmpstr (flatpak_get_arch (), ==, "i386");
  g_assert_false (g_strv_contains (arches, "x86_64"));
  g_assert_true (g_strv_contains (arches, "i386"));
#elif defined(__x86_64__)
  g_assert_cmpstr (flatpak_get_arch (), ==, "x86_64");
  g_assert_true (g_strv_contains (arches, "x86_64"));
  g_assert_true (g_strv_contains (arches, "i386"));
  g_assert_true (flatpak_is_linux32_arch ("i386"));
  g_assert_false (flatpak_is_linux32_arch ("x86_64"));
#else
  g_assert_true (g_strv_contains (arches, flatpak_get_arch ()));
#endif
}

static void
test_extension_matches (void)
{
  g_assert_true (flatpak_extension_matches_reason ("org.foo.bar", "", TRUE));
  g_assert_false (flatpak_extension_matches_reason ("org.foo.nosuchdriver", "active-gl-driver", TRUE));
  g_assert_false (flatpak_extension_matches_reason ("org.foo.nosuchtheme", "active-gtk-theme", TRUE));
  g_assert_false (flatpak_extension_matches_reason ("org.foo.nonono", "on-xdg-desktop-nosuchdesktop", TRUE));
  g_assert_false (flatpak_extension_matches_reason ("org.foo.nonono", "active-gl-driver;active-gtk-theme", TRUE));
}

static void
test_valid_name (void)
{
  g_assert_false (flatpak_is_valid_name ("", -1, NULL));
  g_assert_false (flatpak_is_valid_name ("org", -1, NULL));
  g_assert_false (flatpak_is_valid_name ("org.", -1, NULL));
  g_assert_false (flatpak_is_valid_name ("org..", -1, NULL));
  g_assert_false (flatpak_is_valid_name ("org..test", -1, NULL));
  g_assert_false (flatpak_is_valid_name ("org.flatpak", -1, NULL));
  g_assert_false (flatpak_is_valid_name ("org.1flatpak.test", -1, NULL));
  g_assert_false (flatpak_is_valid_name ("org.flat-pak.test", -1, NULL));
  g_assert_false (flatpak_is_valid_name ("org.-flatpak.test", -1, NULL));
  g_assert_false (flatpak_is_valid_name ("org.flat,pak.test", -1, NULL));
  g_assert_false (flatpak_is_valid_name ("org.flatpak.test", 0, NULL));
  g_assert_false (flatpak_is_valid_name ("org.flatpak.test", 3, NULL));
  g_assert_false (flatpak_is_valid_name ("org.flatpak.test", 4, NULL));

  g_assert_true (flatpak_is_valid_name ("org.flatpak.test", -1, NULL));
  g_assert_true (flatpak_is_valid_name ("org.flatpak.test", strlen("org.flatpak.test"), NULL));
  g_assert_true (flatpak_is_valid_name ("org.FlatPak.TEST", -1, NULL));
  g_assert_true (flatpak_is_valid_name ("org0.f1atpak.test", -1, NULL));
  g_assert_true (flatpak_is_valid_name ("org.flatpak.-test", -1, NULL));
  g_assert_true (flatpak_is_valid_name ("org.flatpak._test", -1, NULL));
  g_assert_true (flatpak_is_valid_name ("org.flat_pak__.te--st", -1, NULL));
}

static void
test_decompose (void)
{
  g_autoptr(FlatpakDecomposed) app_ref = NULL;
  g_autoptr(FlatpakDecomposed) runtime_ref = NULL;
  g_autoptr(FlatpakDecomposed) refspec = NULL;
  g_autoptr(GError) error = NULL;
  g_autofree char *app_id = NULL;
  g_autofree char *app_arch = NULL;
  g_autofree char *app_branch = NULL;
  g_autofree char *runtime_id = NULL;
  g_autofree char *runtime_arch = NULL;
  g_autofree char *runtime_branch = NULL;
  gsize len, len2;

  g_assert_null (flatpak_decomposed_new_from_ref ("app/wrong/mips64/master", &error));
  g_assert (error != NULL);
  g_assert (error->domain == FLATPAK_ERROR);
  g_assert (error->code == FLATPAK_ERROR_INVALID_REF);
  g_clear_error (&error);

  g_assert_null (flatpak_decomposed_new_from_ref ("app/org.the.app//master", &error));
  g_assert (error != NULL);
  g_assert (error->domain == FLATPAK_ERROR);
  g_assert (error->code == FLATPAK_ERROR_INVALID_REF);
  g_clear_error (&error);

  g_assert_null (flatpak_decomposed_new_from_ref ("app/org.the.app/mips64/@foo", &error));
  g_assert (error != NULL);
  g_assert (error->domain == FLATPAK_ERROR);
  g_assert (error->code == FLATPAK_ERROR_INVALID_REF);
  g_clear_error (&error);

  g_assert_null (flatpak_decomposed_new_from_ref ("wrong/org.the.wrong/mips64/master", &error));
  g_assert (error != NULL);
  g_assert (error->domain == FLATPAK_ERROR);
  g_assert (error->code == FLATPAK_ERROR_INVALID_REF);
  g_clear_error (&error);

  g_assert_null (flatpak_decomposed_new_from_ref ("app/org.the.app/mips64/master/extra", &error));
  g_assert (error != NULL);
  g_assert (error->domain == FLATPAK_ERROR);
  g_assert (error->code == FLATPAK_ERROR_INVALID_REF);
  g_clear_error (&error);

  g_assert_null (flatpak_decomposed_new_from_ref ("app/org.the.app/mips64", &error));
  g_assert (error != NULL);
  g_assert (error->domain == FLATPAK_ERROR);
  g_assert (error->code == FLATPAK_ERROR_INVALID_REF);
  g_clear_error (&error);

  runtime_ref = flatpak_decomposed_new_from_ref ("runtime/org.the.runtime/mips64/master", &error);
  g_assert (runtime_ref != NULL);
  g_assert_null (error);

  g_assert_cmpstr (flatpak_decomposed_get_ref (runtime_ref), ==, "runtime/org.the.runtime/mips64/master");
  g_assert_cmpstr (flatpak_decomposed_get_refspec (runtime_ref), ==, "runtime/org.the.runtime/mips64/master");
  g_assert (flatpak_decomposed_equal (runtime_ref, runtime_ref));
  g_assert (flatpak_decomposed_hash (runtime_ref) == g_str_hash ("runtime/org.the.runtime/mips64/master"));
  g_assert (!flatpak_decomposed_is_app (runtime_ref));
  g_assert (flatpak_decomposed_is_runtime (runtime_ref));
  g_assert (flatpak_decomposed_get_kinds (runtime_ref) == FLATPAK_KINDS_RUNTIME);
  g_assert (flatpak_decomposed_get_kind (runtime_ref) == FLATPAK_REF_KIND_RUNTIME);

  g_assert_cmpstr (flatpak_decomposed_peek_id (runtime_ref, &len), ==, "org.the.runtime/mips64/master");
  g_assert (len == strlen("org.the.runtime"));
  runtime_id = flatpak_decomposed_dup_id (runtime_ref);
  g_assert_cmpstr (runtime_id, ==, "org.the.runtime");
  g_assert (flatpak_decomposed_is_id (runtime_ref, "org.the.runtime"));
  g_assert (!flatpak_decomposed_is_id (runtime_ref, "org.the.runtim"));
  g_assert (!flatpak_decomposed_is_id (runtime_ref, "org.the.runtimee"));

  g_assert_cmpstr (flatpak_decomposed_peek_arch (runtime_ref, &len), ==, "mips64/master");
  g_assert (len == strlen ("mips64"));
  runtime_arch = flatpak_decomposed_dup_arch (runtime_ref);
  g_assert_cmpstr (runtime_arch, ==, "mips64");
  g_assert (flatpak_decomposed_is_arch (runtime_ref, "mips64"));
  g_assert (!flatpak_decomposed_is_arch (runtime_ref, "mips6"));
  g_assert (!flatpak_decomposed_is_arch (runtime_ref, "mips644"));

  g_assert_cmpstr (flatpak_decomposed_peek_branch (runtime_ref, &len), ==, "master");
  g_assert (len == strlen ("master"));
  runtime_branch = flatpak_decomposed_dup_branch (runtime_ref);
  g_assert_cmpstr (runtime_branch, ==, "master");
  g_assert (flatpak_decomposed_is_branch (runtime_ref, "master"));
  g_assert (!flatpak_decomposed_is_branch (runtime_ref, "maste"));
  g_assert (!flatpak_decomposed_is_branch (runtime_ref, "masterr"));

  app_ref = flatpak_decomposed_new_from_ref ("app/org.the.app/mips64/master", &error);
  g_assert (app_ref != NULL);
  g_assert_null (error);

  g_assert_cmpstr (flatpak_decomposed_get_ref (app_ref), ==, "app/org.the.app/mips64/master");
  g_assert_cmpstr (flatpak_decomposed_get_refspec (app_ref), ==, "app/org.the.app/mips64/master");
  g_assert (flatpak_decomposed_equal (app_ref, app_ref));
  g_assert (!flatpak_decomposed_equal (app_ref, runtime_ref));
  g_assert (flatpak_decomposed_hash (app_ref) == g_str_hash ("app/org.the.app/mips64/master"));
  g_assert (flatpak_decomposed_is_app (app_ref));
  g_assert (!flatpak_decomposed_is_runtime (app_ref));
  g_assert (flatpak_decomposed_get_kinds (app_ref) == FLATPAK_KINDS_APP);
  g_assert (flatpak_decomposed_get_kind (app_ref) == FLATPAK_REF_KIND_APP);

  g_assert_cmpstr (flatpak_decomposed_peek_id (app_ref, &len), ==, "org.the.app/mips64/master");
  g_assert (len == strlen ("org.the.app"));
  app_id = flatpak_decomposed_dup_id (app_ref);
  g_assert_cmpstr (app_id, ==, "org.the.app");
  g_assert (flatpak_decomposed_is_id (app_ref, "org.the.app"));
  g_assert (!flatpak_decomposed_is_id (app_ref, "org.the.ap"));
  g_assert (!flatpak_decomposed_is_id (app_ref, "org.the.appp"));

  g_assert_cmpstr (flatpak_decomposed_peek_arch (app_ref, &len), ==, "mips64/master");
  g_assert (len == strlen ("mips64"));
  app_arch = flatpak_decomposed_dup_arch (app_ref);
  g_assert_cmpstr (app_arch, ==, "mips64");
  g_assert (flatpak_decomposed_is_arch (app_ref, "mips64"));
  g_assert (!flatpak_decomposed_is_arch (app_ref, "mips6"));
  g_assert (!flatpak_decomposed_is_arch (app_ref, "mips644"));

  g_assert_cmpstr (flatpak_decomposed_get_branch (app_ref), ==, "master");
  g_assert_cmpstr (flatpak_decomposed_peek_branch (app_ref, &len), ==, "master");
  g_assert (len == strlen ("master"));
  app_branch = flatpak_decomposed_dup_branch (app_ref);
  g_assert_cmpstr (app_branch, ==, "master");
  g_assert (flatpak_decomposed_is_branch (app_ref, "master"));
  g_assert (!flatpak_decomposed_is_branch (app_ref, "maste"));
  g_assert (!flatpak_decomposed_is_branch (app_ref, "masterr"));

  refspec = flatpak_decomposed_new_from_ref ("remote:app/org.the.app/mips64/master", &error);
  g_assert (refspec == NULL);
  g_assert (error != NULL);
  g_assert (error->domain == FLATPAK_ERROR);
  g_assert (error->code == FLATPAK_ERROR_INVALID_REF);
  g_clear_error (&error);

  refspec = flatpak_decomposed_new_from_refspec ("remote/broken:app/org.the.app/mips64/master", &error);
  g_assert (refspec == NULL);
  g_assert (error != NULL);
  g_assert (error->domain == FLATPAK_ERROR);
  g_assert (error->code == FLATPAK_ERROR_INVALID_REF);
  g_clear_error (&error);

  refspec = flatpak_decomposed_new_from_refspec ("remote:app/org.the.app/mips64/master", &error);
  g_assert (refspec != NULL);
  g_assert_null (error);

  g_assert_cmpstr (flatpak_decomposed_get_ref (refspec), ==, "app/org.the.app/mips64/master");
  g_assert_cmpstr (flatpak_decomposed_get_refspec (refspec), ==, "remote:app/org.the.app/mips64/master");
  g_autofree char *refspec_remote = flatpak_decomposed_dup_remote (refspec);
  g_assert_cmpstr (refspec_remote, ==, "remote");
  g_autofree char *refspec_ref = flatpak_decomposed_dup_ref (refspec);
  g_assert_cmpstr (refspec_ref, ==, "app/org.the.app/mips64/master");
  g_autofree char *refspec_refspec = flatpak_decomposed_dup_refspec (refspec);
  g_assert_cmpstr (refspec_refspec, ==, "remote:app/org.the.app/mips64/master");

  {
    FlatpakDecomposed *old = runtime_ref;
    g_autoptr(FlatpakDecomposed) new = flatpak_decomposed_new_from_decomposed (old, 0, NULL, NULL, NULL, &error);
    g_assert (new != NULL);
    g_assert_null (error);

    g_assert_cmpstr (flatpak_decomposed_get_ref (new), ==, flatpak_decomposed_get_ref (old));
    g_assert_cmpstr (flatpak_decomposed_peek_id (new, &len), ==, flatpak_decomposed_peek_id (old, &len2));
    g_assert (len == len2);
    g_assert_cmpstr (flatpak_decomposed_peek_arch (new, &len), ==, flatpak_decomposed_peek_arch (old, &len2));
    g_assert (len == len2);
    g_assert_cmpstr (flatpak_decomposed_peek_branch (new, &len), ==, flatpak_decomposed_peek_branch (old, &len2));
    g_assert (len == len2);
  }

  {
    FlatpakDecomposed *old = app_ref;
    g_autoptr(FlatpakDecomposed) new = flatpak_decomposed_new_from_decomposed (old, 0, NULL, NULL, NULL, &error);
    g_assert (new != NULL);
    g_assert_null (error);

    g_assert_cmpstr (flatpak_decomposed_get_ref (new), ==, flatpak_decomposed_get_ref (old));
    g_assert_cmpstr (flatpak_decomposed_peek_id (new, &len), ==, flatpak_decomposed_peek_id (old, &len2));
    g_assert (len == len2);
    g_assert_cmpstr (flatpak_decomposed_peek_arch (new, &len), ==, flatpak_decomposed_peek_arch (old, &len2));
    g_assert (len == len2);
    g_assert_cmpstr (flatpak_decomposed_peek_branch (new, &len), ==, flatpak_decomposed_peek_branch (old, &len2));
    g_assert (len == len2);
  }

  {
    FlatpakDecomposed *old = app_ref;
    g_autofree gchar *new_id = NULL;

    g_autoptr(FlatpakDecomposed) new = flatpak_decomposed_new_from_decomposed (old, FLATPAK_KINDS_RUNTIME, "org.new.app", NULL, NULL, &error);
    g_assert (new != NULL);
    g_assert_null (error);

    g_assert_cmpstr (flatpak_decomposed_get_ref (new), ==, "runtime/org.new.app/mips64/master");

    g_assert (flatpak_decomposed_get_kinds (new) == FLATPAK_KINDS_RUNTIME);
    new_id = flatpak_decomposed_dup_id (new);
    g_assert_cmpstr (new_id, ==, "org.new.app");

    g_assert_cmpstr (flatpak_decomposed_peek_arch (new, &len), ==, flatpak_decomposed_peek_arch (old, &len2));
    g_assert (len == len2);
    g_assert_cmpstr (flatpak_decomposed_peek_branch (new, &len), ==, flatpak_decomposed_peek_branch (old, &len2));
    g_assert (len == len2);
  }

  {
    FlatpakDecomposed *old = app_ref;
    g_autofree gchar *old_id = NULL;
    g_autofree gchar *new_id = NULL;
    g_autofree gchar *new_arch = NULL;
    g_autofree gchar *old_branch = NULL;
    g_autofree gchar *new_branch = NULL;

    g_autoptr(FlatpakDecomposed) new = flatpak_decomposed_new_from_decomposed (old, 0, NULL, "m68k", NULL, &error);
    g_assert (new != NULL);
    g_assert_null (error);

    g_assert_cmpstr (flatpak_decomposed_get_ref (new), ==, "app/org.the.app/m68k/master");

    g_assert (flatpak_decomposed_get_kinds (new) == FLATPAK_KINDS_APP);

    new_id = flatpak_decomposed_dup_id (new);
    old_id = flatpak_decomposed_dup_id (old);
    g_assert_cmpstr (new_id, ==, old_id);

    new_arch = flatpak_decomposed_dup_arch (new);
    g_assert_cmpstr (new_arch, ==, "m68k");

    new_branch = flatpak_decomposed_dup_branch (new);
    old_branch = flatpak_decomposed_dup_branch (old);
    g_assert_cmpstr (new_branch, ==, old_branch);
  }

  {
    FlatpakDecomposed *old = app_ref;
    g_autofree gchar *old_id = NULL;
    g_autofree gchar *new_id = NULL;
    g_autofree gchar *new_arch = NULL;
    g_autofree gchar *old_arch = NULL;
    g_autofree gchar *new_branch = NULL;

    g_autoptr(FlatpakDecomposed) new = flatpak_decomposed_new_from_decomposed (old, 0, NULL, NULL, "beta", &error);
    g_assert (new != NULL);
    g_assert_null (error);

    g_assert_cmpstr (flatpak_decomposed_get_ref (new), ==, "app/org.the.app/mips64/beta");

    g_assert (flatpak_decomposed_get_kinds (new) == FLATPAK_KINDS_APP);

    new_id = flatpak_decomposed_dup_id (new);
    old_id = flatpak_decomposed_dup_id (old);
    g_assert_cmpstr (new_id, ==, old_id);

    new_arch = flatpak_decomposed_dup_arch (new);
    old_arch = flatpak_decomposed_dup_arch (old);
    g_assert_cmpstr (new_arch, ==, old_arch);

    new_branch = flatpak_decomposed_dup_branch (new);
    g_assert_cmpstr (new_branch, ==, "beta");
  }

  {
    FlatpakDecomposed *old = app_ref;
    g_autofree gchar *new_id = NULL;
    g_autofree gchar *new_arch = NULL;
    g_autofree gchar *new_branch = NULL;

    g_autoptr(FlatpakDecomposed) new = flatpak_decomposed_new_from_decomposed (old, FLATPAK_KINDS_RUNTIME, "org.new.app", "m68k", "beta", &error);
    g_assert (new != NULL);
    g_assert_null (error);

    g_assert_cmpstr (flatpak_decomposed_get_ref (new), ==, "runtime/org.new.app/m68k/beta");

    g_assert (flatpak_decomposed_get_kinds (new) == FLATPAK_KINDS_RUNTIME);
    new_id = flatpak_decomposed_dup_id (new);
    g_assert_cmpstr (new_id, ==, "org.new.app");
    new_arch = flatpak_decomposed_dup_arch (new);
    g_assert_cmpstr (new_arch, ==, "m68k");
    new_branch = flatpak_decomposed_dup_branch (new);
    g_assert_cmpstr (new_branch, ==, "beta");
  }

  {
    g_autoptr(FlatpakDecomposed) pref = NULL;
    g_autofree gchar *id = NULL;
    g_autofree gchar *arch = NULL;
    g_autofree gchar *branch = NULL;

    pref = flatpak_decomposed_new_from_pref (FLATPAK_KINDS_RUNTIME, "org.the.@pp.Locale/mips64/master", &error);
    g_assert_null (pref);
    g_assert (error != NULL);
    g_assert (error->domain == FLATPAK_ERROR);
    g_assert (error->code == FLATPAK_ERROR_INVALID_REF);
    g_clear_error (&error);

    pref = flatpak_decomposed_new_from_pref (FLATPAK_KINDS_RUNTIME, "org.the.app.Locale/x86@64/master", &error);
    g_assert_null (pref);
    g_assert (error != NULL);
    g_assert (error->domain == FLATPAK_ERROR);
    g_assert (error->code == FLATPAK_ERROR_INVALID_REF);
    g_clear_error (&error);

    pref = flatpak_decomposed_new_from_pref (FLATPAK_KINDS_RUNTIME, "org.the.app.Locale//master", &error);
    g_assert_null (pref);
    g_assert (error != NULL);
    g_assert (error->domain == FLATPAK_ERROR);
    g_assert (error->code == FLATPAK_ERROR_INVALID_REF);
    g_clear_error (&error);

    pref = flatpak_decomposed_new_from_pref (FLATPAK_KINDS_RUNTIME, "org.the.app.Locale/mips64", &error);
    g_assert_null (pref);
    g_assert (error != NULL);
    g_assert (error->domain == FLATPAK_ERROR);
    g_assert (error->code == FLATPAK_ERROR_INVALID_REF);
    g_clear_error (&error);

    pref = flatpak_decomposed_new_from_pref (FLATPAK_KINDS_RUNTIME, "org.the.app.Locale/mips64/master", &error);
    if (error)
      g_print ("XXXXXXXX error: %s\n", error->message);
    g_assert_nonnull (pref);
    g_assert (error == NULL);

    g_assert_cmpstr (flatpak_decomposed_get_ref (pref), ==, "runtime/org.the.app.Locale/mips64/master");

    g_assert (flatpak_decomposed_get_kinds (pref) == FLATPAK_KINDS_RUNTIME);
    id = flatpak_decomposed_dup_id (pref);
    g_assert_cmpstr (id, ==, "org.the.app.Locale");
    arch = flatpak_decomposed_dup_arch (pref);
    g_assert_cmpstr (arch, ==, "mips64");
    branch = flatpak_decomposed_dup_branch (pref);
    g_assert_cmpstr (branch, ==, "master");
  }


  {
    g_autoptr(FlatpakDecomposed) a = flatpak_decomposed_new_from_ref ("app/org.app.A/mips64/master", NULL);
    g_autoptr(FlatpakDecomposed) a_l = flatpak_decomposed_new_from_ref ("runtime/org.app.A.Locale/mips64/master", NULL);
    g_autoptr(FlatpakDecomposed) b = flatpak_decomposed_new_from_ref ("app/org.app.B/mips64/master", NULL);
    g_autoptr(FlatpakDecomposed) b_l = flatpak_decomposed_new_from_ref ("runtime/org.app.B.Locale/mips64/master", NULL);
    g_autoptr(FlatpakDecomposed) c = flatpak_decomposed_new_from_ref ("app/org.app.A/m68k/master", NULL);
    g_autoptr(FlatpakDecomposed) c_l = flatpak_decomposed_new_from_ref ("runtime/org.app.A.Locale/m68k/master", NULL);
    g_autoptr(FlatpakDecomposed) d = flatpak_decomposed_new_from_ref ("app/org.app.A/mips64/beta", NULL);
    g_autoptr(FlatpakDecomposed) d_l = flatpak_decomposed_new_from_ref ("runtime/org.app.A.Locale/mips64/beta", NULL);

    g_assert (flatpak_decomposed_id_is_subref_of (a_l, a));
    g_assert (!flatpak_decomposed_id_is_subref_of (b_l, a));
    g_assert (!flatpak_decomposed_id_is_subref_of (c_l, a));
    g_assert (!flatpak_decomposed_id_is_subref_of (d_l, a));
    g_assert (!flatpak_decomposed_id_is_subref_of (a, a));
    g_assert (!flatpak_decomposed_id_is_subref_of (b, a));
    g_assert (!flatpak_decomposed_id_is_subref_of (c, a));
    g_assert (!flatpak_decomposed_id_is_subref_of (d, a));

    g_assert (!flatpak_decomposed_id_is_subref_of (a_l, b));
    g_assert (flatpak_decomposed_id_is_subref_of (b_l, b));
    g_assert (!flatpak_decomposed_id_is_subref_of (c_l, b));
    g_assert (!flatpak_decomposed_id_is_subref_of (d_l, b));
    g_assert (!flatpak_decomposed_id_is_subref_of (a, b));
    g_assert (!flatpak_decomposed_id_is_subref_of (b, b));
    g_assert (!flatpak_decomposed_id_is_subref_of (c, b));
    g_assert (!flatpak_decomposed_id_is_subref_of (d, b));

    g_assert (!flatpak_decomposed_id_is_subref_of (a_l, c));
    g_assert (!flatpak_decomposed_id_is_subref_of (b_l, c));
    g_assert (flatpak_decomposed_id_is_subref_of (c_l, c));
    g_assert (!flatpak_decomposed_id_is_subref_of (d_l, c));
    g_assert (!flatpak_decomposed_id_is_subref_of (a, c));
    g_assert (!flatpak_decomposed_id_is_subref_of (b, c));
    g_assert (!flatpak_decomposed_id_is_subref_of (c, c));
    g_assert (!flatpak_decomposed_id_is_subref_of (d, c));

    g_assert (!flatpak_decomposed_id_is_subref_of (a_l, d));
    g_assert (!flatpak_decomposed_id_is_subref_of (b_l, d));
    g_assert (!flatpak_decomposed_id_is_subref_of (c_l, d));
    g_assert (flatpak_decomposed_id_is_subref_of (d_l, d));
    g_assert (!flatpak_decomposed_id_is_subref_of (a, d));
    g_assert (!flatpak_decomposed_id_is_subref_of (b, d));
    g_assert (!flatpak_decomposed_id_is_subref_of (c, d));
    g_assert (!flatpak_decomposed_id_is_subref_of (d, d));
  }
}


typedef struct
{
  const gchar *str;
  guint        base;
  gint         min;
  gint         max;
  gint         expected;
  gboolean     should_fail;
  GNumberParserError code;
} TestData;

const TestData test_data[] = {
  /* typical cases for unsigned */
  { "-1", 10, 0, 2, 0, TRUE, G_NUMBER_PARSER_ERROR_INVALID },
  { "1", 10, 0, 2, 1, FALSE, 0},
  { "+1", 10, 0, 2, 0, TRUE, G_NUMBER_PARSER_ERROR_INVALID },
  { "0", 10, 0, 2, 0, FALSE, 0},
  { "+0", 10, 0, 2, 0, TRUE, G_NUMBER_PARSER_ERROR_INVALID },
  { "-0", 10, 0, 2, 0, TRUE, G_NUMBER_PARSER_ERROR_INVALID },
  { "2", 10, 0, 2, 2, FALSE, 0},
  { "+2", 10, 0, 2, 0, TRUE, G_NUMBER_PARSER_ERROR_INVALID },
  { "3", 10, 0, 2, 0, TRUE, G_NUMBER_PARSER_ERROR_OUT_OF_BOUNDS },
  { "+3", 10, 0, 2, 0, TRUE, G_NUMBER_PARSER_ERROR_INVALID },

  /* min == max cases for unsigned */
  { "2", 10, 2, 2, 2, FALSE, 0 },
  { "3", 10, 2, 2, 0, TRUE, G_NUMBER_PARSER_ERROR_OUT_OF_BOUNDS },
  { "1", 10, 2, 2, 0, TRUE, G_NUMBER_PARSER_ERROR_OUT_OF_BOUNDS },

  /* invalid inputs */
  { "",   10,  0,  2,  0, TRUE, G_NUMBER_PARSER_ERROR_INVALID },
  { "a",  10,  0,  2,  0, TRUE, G_NUMBER_PARSER_ERROR_INVALID },
  { "1a", 10,  0,  2,  0, TRUE, G_NUMBER_PARSER_ERROR_INVALID },

  /* leading/trailing whitespace */
  { " 1", 10,  0,  2,  0, TRUE, G_NUMBER_PARSER_ERROR_INVALID },
  { "1 ", 10,  0,  2,  0, TRUE, G_NUMBER_PARSER_ERROR_INVALID },

  /* hexadecimal numbers */
  { "a",    16,   0, 15, 10, FALSE, 0 },
  { "0xa",  16,   0, 15,  0, TRUE, G_NUMBER_PARSER_ERROR_INVALID },
  { "-0xa", 16,   0, 15,  0, TRUE, G_NUMBER_PARSER_ERROR_INVALID },
  { "+0xa", 16,   0, 15,  0, TRUE, G_NUMBER_PARSER_ERROR_INVALID },
  { "- 0xa", 16,   0, 15,  0, TRUE, G_NUMBER_PARSER_ERROR_INVALID },
  { "+ 0xa", 16,   0, 15,  0, TRUE, G_NUMBER_PARSER_ERROR_INVALID },
};

static void
test_string_to_unsigned (void)
{
  gsize idx;

  for (idx = 0; idx < G_N_ELEMENTS (test_data); ++idx)
    {
      GError *error = NULL;
      const TestData *data = &test_data[idx];
      gboolean result;
      gint value;
      guint64 value64 = 0;
      result = g_ascii_string_to_unsigned (data->str,
                                           data->base,
                                           data->min,
                                           data->max,
                                           &value64,
                                           &error);
      value = value64;
      g_assert_cmpint (value, ==, value64);

      if (data->should_fail)
        {
          g_assert_false (result);
          g_assert_error (error, G_NUMBER_PARSER_ERROR, data->code);
          g_clear_error (&error);
        }
      else
        {
          g_assert_true (result);
          g_assert_no_error (error);
          g_assert_cmpint (value, ==, data->expected);
          g_assert_cmpint (data->code, ==, 0);
        }
    }
}

typedef struct
{
  const char *a;
  const char *b;
  int         distance;
} Levenshtein;

static Levenshtein levenshtein_tests[] = {
  { "", "", 0 },
  { "abcdef", "abcdef", 0 },
  { "kitten", "sitting", 3 },
  { "Saturday", "Sunday", 3 }
};

static void
test_levenshtein (void)
{
  gsize idx;

  for (idx = 0; idx < G_N_ELEMENTS (levenshtein_tests); idx++)
    {
      Levenshtein *data = &levenshtein_tests[idx];

      g_assert_cmpint (flatpak_levenshtein_distance (data->a, -1, data->b, -1), ==, data->distance);
      g_assert_cmpint (flatpak_levenshtein_distance (data->b, -1, data->a, -1), ==, data->distance);
    }
}

static void
assert_strv_equal (char **strv1,
                   char **strv2)
{
  if (strv1 == strv2)
    return;

  for (; *strv1 != NULL && *strv2 != NULL; strv1++, strv2++)
    g_assert_true (g_str_equal (*strv1, *strv2));

  g_assert_true (*strv1 == NULL && *strv2 == NULL);
}

static void
test_subpaths_merge (void)
{
  char *empty[] = { NULL };
  char *buba[] = { "bu", "ba", NULL };
  char *bla[] = { "bla", "ba", NULL };
  char *bla_sorted[] = { "ba", "bla", NULL };
  char *bubabla[] = { "ba", "bla", "bu", NULL };
  g_auto(GStrv) res = NULL;

  res = flatpak_subpaths_merge (NULL, bla);
  assert_strv_equal (res, bla_sorted);
  g_clear_pointer (&res, g_strfreev);

  res = flatpak_subpaths_merge (bla, NULL);
  assert_strv_equal (res, bla_sorted);
  g_clear_pointer (&res, g_strfreev);

  res = flatpak_subpaths_merge (empty, bla);
  assert_strv_equal (res, empty);
  g_clear_pointer (&res, g_strfreev);

  res = flatpak_subpaths_merge (bla, empty);
  assert_strv_equal (res, empty);
  g_clear_pointer (&res, g_strfreev);

  res = flatpak_subpaths_merge (buba, bla);
  assert_strv_equal (res, bubabla);
  g_clear_pointer (&res, g_strfreev);

  res = flatpak_subpaths_merge (bla, buba);
  assert_strv_equal (res, bubabla);
  g_clear_pointer (&res, g_strfreev);

  res = flatpak_subpaths_merge (bla, bla);
  assert_strv_equal (res, bla_sorted);
  g_clear_pointer (&res, g_strfreev);
}

static void
test_parse_appdata (void)
{
  const char appdata1[] =
    "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
    "<components version=\"0.8\">\n"
    "  <component type=\"desktop\">\n"
    "    <id>org.test.Hello.desktop</id>\n"
    "    <name>Hello world test app: org.test.Hello</name>\n"
    "    <summary>Print a greeting</summary>\n"
    "    <description><p>This is a test app.</p></description>\n"
    "    <categories>\n"
    "      <category>Utility</category>\n"
    "    </categories>\n"
    "    <icon height=\"64\" width=\"64\" type=\"cached\">64x64/org.gnome.gedit.png</icon>\n"
    "    <releases>\n"
    "      <release timestamp=\"1525132800\" version=\"0.0.1\"/>\n" /* 01-05-2018 */
    "    </releases>\n"
    "    <content_rating type=\"oars-1.0\">\n"
    "      <content_attribute id=\"drugs-alcohol\">moderate</content_attribute>\n"
    "      <content_attribute id=\"language-humor\">mild</content_attribute>\n"
    "      <content_attribute id=\"violence-blood\">none</content_attribute>\n"
    "    </content_rating>\n"
    "  </component>\n"
    "</components>";
  const char appdata2[] =
    "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
    "<components version=\"0.8\">\n"
    "  <component type=\"desktop\">\n"
    "    <id>org.test.Hello.desktop</id>\n"
    "    <name>Hello world test app: org.test.Hello</name>\n"
    "    <name xml:lang=\"de\">Hallo Welt test app: org.test.Hello</name>\n"
    "    <summary>Print a greeting</summary>\n"
    "    <summary xml:lang=\"de\">Schreib mal was</summary>\n"
    "    <description><p>This is a test app.</p></description>\n"
    "    <categories>\n"
    "      <category>Utility</category>\n"
    "    </categories>\n"
    "    <icon height=\"64\" width=\"64\" type=\"cached\">64x64/org.gnome.gedit.png</icon>\n"
    "    <releases>\n"
    "      <release timestamp=\"1525132800\" version=\"0.1.0\"/>\n"
    "      <release timestamp=\"1525000800\" date=\"2018-05-02\" version=\"0.0.2\"/>\n"
    "      <release date=\"2017-05-02\" version=\"0.0.3\"/>\n"
    "      <release timestamp=\"1000000000\" version=\"0.0.1\" type=\"stable\" urgency=\"low\"/>\n"
    "    </releases>\n"
    "    <project_license>anything goes</project_license>\n"
    "    <content_rating type=\"oars-1.1\">\n"
    "    </content_rating>\n"
    "  </component>\n"
    "</components>";
  g_autoptr(GHashTable) names = NULL;
  g_autoptr(GHashTable) comments = NULL;
  g_autofree char *version = NULL;
  g_autofree char *license = NULL;
  g_autofree char *content_rating_type = NULL;
  g_autoptr(GHashTable) content_rating = NULL;
  gboolean res;
  char *name;
  char *comment;

  res = flatpak_parse_appdata (appdata1, "org.test.Hello", &names, &comments, &version, &license, &content_rating_type, &content_rating);
  g_assert_true (res);
  g_assert_cmpstr (version, ==, "0.0.1");
  g_assert_null (license);
  g_assert_nonnull (names);
  g_assert_nonnull (comments);
  g_assert_cmpint (g_hash_table_size (names), ==, 1);
  g_assert_cmpint (g_hash_table_size (comments), ==, 1);
  name = g_hash_table_lookup (names, "C");
  g_assert_cmpstr (name, ==, "Hello world test app: org.test.Hello");
  comment = g_hash_table_lookup (comments, "C");
  g_assert_cmpstr (comment, ==, "Print a greeting");
  g_assert_cmpstr (content_rating_type, ==, "oars-1.0");
  g_assert_cmpuint (g_hash_table_size (content_rating), ==, 3);
  g_assert_cmpstr (g_hash_table_lookup (content_rating, "drugs-alcohol"), ==, "moderate");
  g_assert_cmpstr (g_hash_table_lookup (content_rating, "language-humor"), ==, "mild");
  g_assert_cmpstr (g_hash_table_lookup (content_rating, "violence-blood"), ==, "none");

  g_clear_pointer (&names, g_hash_table_unref);
  g_clear_pointer (&comments, g_hash_table_unref);
  g_clear_pointer (&version, g_free);
  g_clear_pointer (&license, g_free);
  g_clear_pointer (&content_rating_type, g_free);
  g_clear_pointer (&content_rating, g_hash_table_unref);

  res = flatpak_parse_appdata (appdata2, "org.test.Hello", &names, &comments, &version, &license, &content_rating_type, &content_rating);
  g_assert_true (res);
  g_assert_cmpstr (version, ==, "0.1.0");
  g_assert_cmpstr (license, ==, "anything goes");
  g_assert_nonnull (names);
  g_assert_nonnull (comments);
  g_assert_cmpint (g_hash_table_size (names), ==, 2);
  g_assert_cmpint (g_hash_table_size (comments), ==, 2);
  name = g_hash_table_lookup (names, "C");
  g_assert_cmpstr (name, ==, "Hello world test app: org.test.Hello");
  name = g_hash_table_lookup (names, "de");
  g_assert_cmpstr (name, ==, "Hallo Welt test app: org.test.Hello");
  comment = g_hash_table_lookup (comments, "C");
  g_assert_cmpstr (comment, ==, "Print a greeting");
  comment = g_hash_table_lookup (comments, "de");
  g_assert_cmpstr (comment, ==, "Schreib mal was");
  g_assert_cmpstr (content_rating_type, ==, "oars-1.1");
  g_assert_cmpuint (g_hash_table_size (content_rating), ==, 0);
}

static void
test_name_matching (void)
{
  gboolean res;

  /* examples from 8f428fd7683765dd706da06e9f376d3732ce5c0c */

  res = flatpak_name_matches_one_wildcard_prefix ("org.sparkleshare.SparkleShare.Invites",
                                                  (const char *[]){"org.sparkleshare.SparkleShare.*", NULL},
                                                  FALSE);
  g_assert_true (res);

  res = flatpak_name_matches_one_wildcard_prefix ("org.sparkleshare.SparkleShare-symbolic",
                                                  (const char *[]){"org.sparkleshare.SparkleShare.*", NULL},
                                                  FALSE);
  g_assert_true (res);

  res = flatpak_name_matches_one_wildcard_prefix ("org.libreoffice.LibreOffice",
                                                  (const char *[]){"org.libreoffice.LibreOffice.*", NULL},
                                                  FALSE);
  g_assert_true (res);

  res = flatpak_name_matches_one_wildcard_prefix ("org.libreoffice.LibreOffice-impress",
                                                  (const char *[]){"org.libreoffice.LibreOffice.*", NULL},
                                                  FALSE);
  g_assert_true (res);

  res = flatpak_name_matches_one_wildcard_prefix ("org.libreoffice.LibreOffice-writer",
                                                  (const char *[]){"org.libreoffice.LibreOffice.*", NULL},
                                                  FALSE);
  g_assert_true (res);

  res = flatpak_name_matches_one_wildcard_prefix ("org.libreoffice.LibreOffice-calc",
                                                  (const char *[]){"org.libreoffice.LibreOffice.*", NULL},
                                                  FALSE);
  g_assert_true (res);

  res = flatpak_name_matches_one_wildcard_prefix ("com.github.bajoja.indicator-kdeconnect",
                                                  (const char *[]){"com.github.bajoja.indicator-kdeconnect.*", NULL},
                                                  FALSE);
  g_assert_true (res);

  res = flatpak_name_matches_one_wildcard_prefix ("com.github.bajoja.indicator-kdeconnect.settings",
                                                  (const char *[]){"com.github.bajoja.indicator-kdeconnect.*", NULL},
                                                  FALSE);
  g_assert_true (res);

  res = flatpak_name_matches_one_wildcard_prefix ("com.github.bajoja.indicator-kdeconnect.tablettrusted",
                                                  (const char *[]){"com.github.bajoja.indicator-kdeconnect.*", NULL},
                                                  FALSE);
  g_assert_true (res);

  res = flatpak_name_matches_one_wildcard_prefix ("org.gnome.Characters.BackgroundService",
                                                  (const char *[]){"org.gnome.Characters.*", NULL},
                                                  TRUE);
  g_assert_true (res);

  res = flatpak_name_matches_one_wildcard_prefix ("org.example.Example.Tracker1.Miner.Applications",
                                                  (const char *[]){"org.example.Example.*", NULL},
                                                  TRUE);
  g_assert_true (res);
}

/* Test various syntax errors */
static void
test_filter_parser (void)
{
  struct {
    const char *filter;
    guint expected_error;
  } filters[] = {
    {
     "foobar",
     FLATPAK_ERROR_INVALID_DATA
    },
    {
     "foobar *",
     FLATPAK_ERROR_INVALID_DATA
    },
    {
     "deny",
     FLATPAK_ERROR_INVALID_DATA
    },
    {
     "deny 23+123",
     FLATPAK_ERROR_INVALID_DATA
    },
    {
     "deny *\n"
     "allow",
     FLATPAK_ERROR_INVALID_DATA
    },
    {
     "deny *\n"
     "allow org.foo.bar extra\n",
     FLATPAK_ERROR_INVALID_DATA
    }
  };
  gboolean ret;
  int i;

  for (i = 0; i < G_N_ELEMENTS(filters); i++)
    {
      g_autoptr(GError) error = NULL;
      g_autoptr(GRegex) allow_refs = NULL;
      g_autoptr(GRegex) deny_refs = NULL;

      ret = flatpak_parse_filters (filters[i].filter, &allow_refs, &deny_refs, &error);
      g_assert_error (error, FLATPAK_ERROR, filters[i].expected_error);
      g_assert_true (ret == FALSE);
      g_assert_true (allow_refs == NULL);
      g_assert_true (deny_refs == NULL);
    }
}

static void
test_filter (void)
{
  GError *error = NULL;
  g_autoptr(GRegex) allow_refs = NULL;
  g_autoptr(GRegex) deny_refs = NULL;
  gboolean ret;
  int i;
  const char *filter =
    " # This is a comment\n"
    "\tallow\t org.foo.*#comment\n"
    "  deny   org.*   # Comment\n"
    "  deny   com.*   # Comment\n"
    " # another comment\n"
    "allow com.foo.bar\n"
    "allow app/com.bar.foo*/*/stable\n"
    "allow app/com.armed.foo*/arm\n"
    "allow runtime/com.gazonk\n"
    "allow runtime/com.gazonk.*\t#comment*a*"; /* Note: lack of last newline to test */
  struct {
    const char *ref;
    gboolean expected_result;
  } filter_refs[] = {
     /* General denies (org/com)*/
     { "app/org.filter.this/mips64/stable", FALSE },
     { "app/com.filter.this/arm/stable", FALSE },
     /* But net. not denied */
     { "app/net.dont.filter.this/mips64/stable", TRUE },
     { "runtime/net.dont.filter.this/mips64/1.0", TRUE },

     /* Special allow overrides */

     /* allow com.foo.bar */
     { "app/com.foo.bar/mips64/stable", TRUE },
     { "app/com.foo.bar/arm/foo", TRUE },
     { "runtime/com.foo.bar/mips64/1.0", TRUE },

     /* allow app/com.bar.foo* / * /stable */
     { "app/com.bar.foo/mips64/stable", TRUE },
     { "app/com.bar.foo/arm/stable", TRUE },
     { "app/com.bar.foobar/mips64/stable", TRUE },
     { "app/com.bar.foobar/arm/stable", TRUE },
     { "app/com.bar.foo.bar/mips64/stable", TRUE },
     { "app/com.bar.foo.bar/arm/stable", TRUE },
     { "app/com.bar.foo/mips64/unstable", FALSE },
     { "app/com.bar.foobar/mips64/unstable", FALSE },
     { "runtime/com.bar.foo/mips64/stable", FALSE },

     /* allow app/com.armed.foo* /arm */
     { "app/com.armed.foo/arm/stable", TRUE },
     { "app/com.armed.foo/arm/unstable", TRUE },
     { "app/com.armed.foo/mips64/stable", FALSE },
     { "app/com.armed.foo/mips64/unstable", FALSE },
     { "app/com.armed.foobar/arm/stable", TRUE },
     { "app/com.armed.foobar/arm/unstable", TRUE },
     { "app/com.armed.foobar/mips64/stable", FALSE },
     { "app/com.armed.foobar/mips64/unstable", FALSE },
     { "runtime/com.armed.foo/arm/stable", FALSE },
     { "runtime/com.armed.foobar/arm/stable", FALSE },
     { "runtime/com.armed.foo/mips64/stable", FALSE },
     { "runtime/com.armed.foobar/mips64/stable", FALSE },

     /* allow runtime/com.gazonk */
     /* allow runtime/com.gazonk.* */
     { "runtime/com.gazonk/mips64/1.0", TRUE },
     { "runtime/com.gazonk.Locale/mips64/1.0", TRUE },
     { "runtime/com.gazonked/mips64/1.0", FALSE },
     { "runtime/com.gazonk/arm/1.0", TRUE },
     { "runtime/com.gazonk.Locale/arm/1.0", TRUE },
     { "app/com.gazonk/mips64/stable", FALSE },
     { "app/com.gazonk.Locale/mips64/stable", FALSE },

  };

  ret = flatpak_parse_filters (filter, &allow_refs, &deny_refs, &error);
  g_assert_no_error (error);
  g_assert_true (ret == TRUE);

  g_assert_true (allow_refs != NULL);
  g_assert_true (deny_refs != NULL);

  for (i = 0; i < G_N_ELEMENTS(filter_refs); i++)
    g_assert_cmpint (flatpak_filters_allow_ref (allow_refs, deny_refs, filter_refs[i].ref), ==, filter_refs[i].expected_result);
}

static void
test_dconf_app_id (void)
{
  struct {
    const char *app_id;
    const char *path;
  } tests[] = {
    { "org.gnome.Builder", "/org/gnome/Builder/" },
    { "org.gnome.builder", "/org/gnome/builder/" },
    { "org.gnome.builder-2", "/org/gnome/builder-2/" },
  };
  int i;

  for (i = 0; i < G_N_ELEMENTS (tests); i++)
    {
      g_autofree char *path = NULL;

      path = flatpak_dconf_path_for_app_id (tests[i].app_id);
      g_assert_cmpstr (path, ==, tests[i].path);
    }
}

static void
test_dconf_paths (void)
{
  struct {
    const char *path1;
    const char *path2;
    gboolean result;
  } tests[] = {
    { "/org/gnome/Builder/", "/org/gnome/builder/", 1 },
    { "/org/gnome/Builder-2/", "/org/gnome/Builder_2/", 1 },
    { "/org/gnome/Builder/", "/org/gnome/Builder", 0 },
    { "/org/gnome/Builder/", "/org/gnome/Buildex/", 0 },
    { "/org/gnome/Rhythmbox3/", "/org/gnome/rhythmbox/", 1 },
    { "/org/gnome/Rhythmbox3/", "/org/gnome/rhythmbox", 0 },
    { "/org/gnome1/Rhythmbox/", "/org/gnome/rhythmbox", 0 },
    { "/org/gnome1/Rhythmbox", "/org/gnome/rhythmbox/", 0 },
    { "/org/gnome/Rhythmbox3plus/", "/org/gnome/rhythmbox/", 0 },
    { "/org/gnome/SoundJuicer/", "/org/gnome/sound-juicer/", 1 },
    { "/org/gnome/Sound-Juicer/", "/org/gnome/sound-juicer/", 1 },
    { "/org/gnome/Soundjuicer/", "/org/gnome/sound-juicer/", 0 },
    { "/org/gnome/Soundjuicer/", "/org/gnome/soundjuicer/", 1 },
    { "/org/gnome/sound-juicer/", "/org/gnome/SoundJuicer/", 1 },
  };
  int i;

  for (i = 0; i < G_N_ELEMENTS (tests); i++)
    {
      gboolean result;

      result = flatpak_dconf_path_is_similar (tests[i].path1, tests[i].path2);
      if (result != tests[i].result)
        g_error ("Unexpected %s: flatpak_dconf_path_is_similar (%s, %s) = %d",
                 result ? "success" : "failure",
                 tests[i].path1,
                 tests[i].path2,
                 result);
    }
}

static void
test_envp_cmp (void)
{
  static const char * const unsorted[] =
  {
    "SAME_NAME=2",
    "EARLY_NAME=a",
    "SAME_NAME=222",
    "Z_LATE_NAME=b",
    "SUFFIX_ADDED=23",
    "SAME_NAME=1",
    "SAME_NAME=",
    "SUFFIX=42",
    "SAME_NAME=3",
    "SAME_NAME",
  };
  static const char * const sorted[] =
  {
    "EARLY_NAME=a",
    "SAME_NAME",
    "SAME_NAME=",
    "SAME_NAME=1",
    "SAME_NAME=2",
    "SAME_NAME=222",
    "SAME_NAME=3",
    "SUFFIX=42",
    "SUFFIX_ADDED=23",
    "Z_LATE_NAME=b",
  };
  const char **sort_this = NULL;
  gsize i, j;

  G_STATIC_ASSERT (G_N_ELEMENTS (sorted) == G_N_ELEMENTS (unsorted));

  for (i = 0; i < G_N_ELEMENTS (sorted); i++)
    {
      g_autofree gchar *copy = g_strdup (sorted[i]);

      g_test_message ("%s == %s", copy, sorted[i]);
      g_assert_cmpint (flatpak_envp_cmp (&copy, &sorted[i]), ==, 0);
      g_assert_cmpint (flatpak_envp_cmp (&sorted[i], &copy), ==, 0);

      for (j = i + 1; j < G_N_ELEMENTS (sorted); j++)
        {
          g_test_message ("%s < %s", sorted[i], sorted[j]);
          g_assert_cmpint (flatpak_envp_cmp (&sorted[i], &sorted[j]), <, 0);
          g_assert_cmpint (flatpak_envp_cmp (&sorted[j], &sorted[i]), >, 0);
        }
    }

  sort_this = g_new0 (const char *, G_N_ELEMENTS (unsorted));

  for (i = 0; i < G_N_ELEMENTS (unsorted); i++)
    sort_this[i] = unsorted[i];

  qsort (sort_this, G_N_ELEMENTS (unsorted), sizeof (char *),
         flatpak_envp_cmp);

  for (i = 0; i < G_N_ELEMENTS (sorted); i++)
    g_assert_cmpstr (sorted[i], ==, sort_this[i]);

  g_free (sort_this);
}

static void
test_needs_quoting (void)
{
  static const char * const needs_quoting[] =
  {
    "",
    "$var",
    "{}",
    "()",
    "[]",
    "*",
    "?",
    "`exec`",
    "has space",
    "quoted-\"",
    "quoted-'",
    "back\\slash",
    "control\001char",
  };
  static const char * const does_not_need_quoting[] =
  {
    "foo",
    "--foo=bar",
    "-x",
    "foo@bar:/srv/big_files",
    "~smcv",
    "7-zip.org",
  };
  gsize i;

  for (i = 0; i < G_N_ELEMENTS (needs_quoting); i++)
    {
      const char *orig = needs_quoting[i];
      g_autoptr(GError) error = NULL;
      g_autofree char *quoted = NULL;
      int argc = -1;
      g_auto(GStrv) argv = NULL;
      gboolean ok;

      g_assert_true (flatpak_argument_needs_quoting (orig));
      quoted = flatpak_quote_argv (&orig, 1);
      g_test_message ("Unquoted: \"%s\"", orig);
      g_test_message ("  Quoted: \"%s\"", quoted);
      g_assert_cmpstr (quoted, !=, orig);

      ok = g_shell_parse_argv (quoted, &argc, &argv, &error);
      g_assert_no_error (error);
      g_assert_true (ok);
      g_assert_cmpint (argc, ==, 1);
      g_assert_nonnull (argv);
      g_assert_cmpstr (argv[0], ==, orig);
      g_assert_cmpstr (argv[1], ==, NULL);
    }

  for (i = 0; i < G_N_ELEMENTS (does_not_need_quoting); i++)
    {
      const char *orig = does_not_need_quoting[i];
      g_autoptr(GError) error = NULL;
      g_autofree char *quoted = NULL;
      int argc = -1;
      g_auto(GStrv) argv = NULL;
      gboolean ok;

      g_assert_false (flatpak_argument_needs_quoting (orig));
      quoted = flatpak_quote_argv (&orig, 1);
      g_assert_cmpstr (quoted, ==, orig);

      ok = g_shell_parse_argv (quoted, &argc, &argv, &error);
      g_assert_no_error (error);
      g_assert_true (ok);
      g_assert_cmpint (argc, ==, 1);
      g_assert_nonnull (argv);
      g_assert_cmpstr (argv[0], ==, orig);
      g_assert_cmpstr (argv[1], ==, NULL);
    }
}

static void
test_quote_argv (void)
{
  static const char * const orig[] =
  {
    "foo",
    "--bar",
    "",
    "baz",
    NULL
  };
  gsize i;
  g_autofree char *quoted = NULL;
  g_autoptr(GError) error = NULL;
  int argc = -1;
  g_auto(GStrv) argv = NULL;
  gboolean ok;

  quoted = flatpak_quote_argv ((const char **) orig, -1);
  ok = g_shell_parse_argv (quoted, &argc, &argv, &error);
  g_assert_no_error (error);
  g_assert_true (ok);
  g_assert_cmpint (argc, >, 0);
  g_assert_cmpuint ((gsize) argc, ==, G_N_ELEMENTS (orig) - 1);
  g_assert_nonnull (argv);

  for (i = 0; i < G_N_ELEMENTS (orig); i++)
    g_assert_cmpstr (argv[i], ==, orig[i]);

  g_clear_pointer (&quoted, g_free);
  g_clear_pointer (&argv, g_strfreev);

  quoted = flatpak_quote_argv ((const char **) orig, 3);
  ok = g_shell_parse_argv (quoted, &argc, &argv, &error);
  g_assert_no_error (error);
  g_assert_true (ok);
  g_assert_cmpint (argc, ==, 3);
  g_assert_nonnull (argv);

  for (i = 0; i < 3; i++)
    g_assert_cmpstr (argv[i], ==, orig[i]);

  g_assert_cmpstr (argv[i], ==, NULL);
}

static void
test_str_is_integer (void)
{
  g_assert_true (flatpak_str_is_integer ("0"));
  g_assert_true (flatpak_str_is_integer ("1234567890987654356765432121245674"));
  g_assert_false (flatpak_str_is_integer (NULL));
  g_assert_false (flatpak_str_is_integer (""));
  g_assert_false (flatpak_str_is_integer ("0.0"));
  g_assert_false (flatpak_str_is_integer ("0e0"));
  g_assert_false (flatpak_str_is_integer ("bees"));
  g_assert_false (flatpak_str_is_integer ("1234a"));
  g_assert_false (flatpak_str_is_integer ("a1234"));
}

/* These are part of the X11 protocol, so we can safely hard-code them here */
#define FamilyInternet6 6
#define FamilyLocal 256
#define FamilyWild 65535

typedef struct
{
  const char *display;
  int family;
  const char *x11_socket;
  const char *remote_host;
  const char *display_number;
} DisplayTest;

static const DisplayTest x11_display_tests[] =
{
  /* Valid test-cases */
  { ":0", FamilyLocal, "/tmp/.X11-unix/X0", NULL, "0" },
  { ":0.0", FamilyLocal, "/tmp/.X11-unix/X0", NULL, "0" },
  { ":42.0", FamilyLocal, "/tmp/.X11-unix/X42", NULL, "42" },
  { "unix:42", FamilyLocal, "/tmp/.X11-unix/X42", NULL, "42" },
  { "othermachine:23", FamilyWild, NULL, "othermachine", "23" },
  { "bees.example.com:23", FamilyWild, NULL, "bees.example.com", "23" },
  { "[::1]:0", FamilyInternet6, NULL, "::1", "0" },

  /* Invalid test-cases */
  { "", 0 },
  { "nope", 0 },
  { ":!", 0 },
  { "othermachine::" },
};

static void
test_parse_x11_display (void)
{
  gsize i;

  for (i = 0; i < G_N_ELEMENTS (x11_display_tests); i++)
    {
      const DisplayTest *test = &x11_display_tests[i];
      int family = -1;
      g_autofree char *x11_socket = NULL;
      g_autofree char *remote_host = NULL;
      g_autofree char *display_number = NULL;
      gboolean ok;
      g_autoptr(GError) error = NULL;

      g_test_message ("%s", test->display);

      ok = flatpak_run_parse_x11_display (test->display,
                                          &family,
                                          &x11_socket,
                                          &remote_host,
                                          &display_number,
                                          &error);

      if (test->family == 0)
        {
          g_assert_nonnull (error);
          g_assert_false (ok);
          g_assert_null (x11_socket);
          g_assert_null (remote_host);
          g_assert_null (display_number);
          g_test_message ("-> could not parse: %s", error->message);
        }
      else
        {
          g_assert_no_error (error);
          g_assert_true (ok);
          g_assert_cmpint (family, ==, test->family);
          g_assert_cmpstr (x11_socket, ==, test->x11_socket);
          g_assert_cmpstr (remote_host, ==, test->remote_host);
          g_assert_cmpstr (display_number, ==, test->display_number);
          g_test_message ("-> successfully parsed");
        }
    }
}

typedef struct {
  const char        *in;
  FlatpakEscapeFlags flags;
  const char        *out;
} EscapeData;

static EscapeData escapes[] = {
  {"abc def", FLATPAK_ESCAPE_DEFAULT, "abc def"},
  {"やあ", FLATPAK_ESCAPE_DEFAULT, "やあ"},
  {"\033[;1m", FLATPAK_ESCAPE_DEFAULT, "'\\x1B[;1m'"},
  /* U+061C ARABIC LETTER MARK, non-printable */
  {"\u061C", FLATPAK_ESCAPE_DEFAULT, "'\\u061C'"},
  /* U+1343F EGYPTIAN HIEROGLYPH END WALLED ENCLOSURE, non-printable and
   * outside BMP */
  {"\xF0\x93\x90\xBF", FLATPAK_ESCAPE_DEFAULT, "'\\U0001343F'"},
  /* invalid utf-8 */
  {"\xD8\1", FLATPAK_ESCAPE_DEFAULT, "'\\xD8\\x01'"},
  {"\b \n abc ' \\", FLATPAK_ESCAPE_DEFAULT, "'\\x08 \\x0A abc \\' \\\\'"},
  {"\b \n abc ' \\", FLATPAK_ESCAPE_DO_NOT_QUOTE, "\\x08 \\x0A abc ' \\\\"},
  {"abc\tdef\n\033[;1m ghi\b", FLATPAK_ESCAPE_ALLOW_NEWLINES | FLATPAK_ESCAPE_DO_NOT_QUOTE,
   "abc\\x09def\n\\x1B[;1m ghi\\x08"},
};

/* CVE-2023-28101 */
static void
test_string_escape (void)
{
  gsize idx;

  for (idx = 0; idx < G_N_ELEMENTS (escapes); idx++)
    {
      EscapeData *data = &escapes[idx];
      g_autofree char *ret = NULL;

      ret = flatpak_escape_string (data->in, data->flags);
      g_assert_cmpstr (ret, ==, data->out);
    }
}

typedef struct {
  const char *path;
  gboolean ret;
} PathValidityData;

static PathValidityData paths[] = {
  {"/a/b/../c.def", TRUE},
  {"やあ", TRUE},
  /* U+061C ARABIC LETTER MARK, non-printable */
  {"\u061C", FALSE},
  /* U+1343F EGYPTIAN HIEROGLYPH END WALLED ENCLOSURE, non-printable and
   * outside BMP */
  {"\xF0\x93\x90\xBF", FALSE},
  /* invalid utf-8 */
  {"\xD8\1", FALSE},
};

/* CVE-2023-28101 */
static void
test_validate_path_characters (void)
{
  gsize idx;

  for (idx = 0; idx < G_N_ELEMENTS (paths); idx++)
    {
      PathValidityData *data = &paths[idx];
      gboolean ret = FALSE;

      ret = flatpak_validate_path_characters (data->path, NULL);
      g_assert_cmpint (ret, ==, data->ret);
    }
}

int
main (int argc, char *argv[])
{
  int res;

  g_test_init (&argc, &argv, NULL);

  g_test_add_func ("/common/has-path-prefix", test_has_path_prefix);
  g_test_add_func ("/common/path-match-prefix", test_path_match_prefix);
  g_test_add_func ("/common/arches", test_arches);
  g_test_add_func ("/common/extension-matches", test_extension_matches);
  g_test_add_func ("/common/valid-name", test_valid_name);
  g_test_add_func ("/common/string-to-unsigned", test_string_to_unsigned);
  g_test_add_func ("/common/levenshtein", test_levenshtein);
  g_test_add_func ("/common/subpaths-merge", test_subpaths_merge);
  g_test_add_func ("/common/appdata", test_parse_appdata);
  g_test_add_func ("/common/name-matching", test_name_matching);
  g_test_add_func ("/common/filter_parser", test_filter_parser);
  g_test_add_func ("/common/filter", test_filter);
  g_test_add_func ("/common/dconf-app-id", test_dconf_app_id);
  g_test_add_func ("/common/dconf-paths", test_dconf_paths);
  g_test_add_func ("/common/decompose-ref", test_decompose);
  g_test_add_func ("/common/envp-cmp", test_envp_cmp);
  g_test_add_func ("/common/needs-quoting", test_needs_quoting);
  g_test_add_func ("/common/quote-argv", test_quote_argv);
  g_test_add_func ("/common/str-is-integer", test_str_is_integer);
  g_test_add_func ("/common/parse-x11-display", test_parse_x11_display);
  g_test_add_func ("/common/string-escape", test_string_escape);
  g_test_add_func ("/common/validate-path-characters", test_validate_path_characters);

  res = g_test_run ();

  return res;
}

===== ./tests/test-authenticator.c =====
/* vi:set et sw=2 sts=2 cin cino=t0,f0,(0,{s,>2s,n-s,^-s,e-s:
 * Copyright © 2019 Red Hat, Inc
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Alexander Larsson <alexl@redhat.com>
 */

#include "config.h"
#include <locale.h>

#include "flatpak-auth-private.h"
#include "flatpak-utils-base-private.h"
#include "flatpak-dbus-generated.h"

static GMainLoop *main_loop;
static guint name_owner_id = 0;
FlatpakAuthenticator *global_authenticator;

typedef struct {
  FlatpakAuthenticatorRequest *request;
  GSocketService *server;
  char **arg_refs;
} TokenRequestData;

static void
token_request_data_free (TokenRequestData *data)
{
  g_clear_object (&data->request);
  g_socket_service_stop  (data->server);
  g_clear_object (&data->server);
  g_strfreev (data->arg_refs);
  g_free (data);
}

static TokenRequestData *
token_request_data_new (FlatpakAuthenticatorRequest *request,
                        GSocketService *server,
                        const gchar *const *arg_refs)
{
  TokenRequestData *data = g_new0 (TokenRequestData, 1);
  data->request = g_object_ref (request);
  data->server = g_object_ref (server);
  data->arg_refs = g_strdupv ((char **)arg_refs);
  return data;
}

static char *
get_required_token (void)
{
  g_autofree char *required_token_file = NULL;
  g_autofree char *required_token = NULL;

  required_token_file = g_build_filename (g_get_user_runtime_dir (), "required-token", NULL);
  if (!g_file_get_contents (required_token_file, &required_token, NULL, NULL))
    required_token = g_strdup ("default-token");
  return g_steal_pointer (&required_token);
}

static void
write_request (char *str)
{
  g_autofree char *request_file = NULL;

  request_file = g_build_filename (g_get_user_runtime_dir (), "request", NULL);
  g_file_set_contents (request_file, str, -1, NULL);
  g_free (str);
}

static gboolean
requires_webflow (void)
{
  g_autofree char *require_webflow_file = g_build_filename (g_get_user_runtime_dir (), "require-webflow", NULL);

  return g_file_test (require_webflow_file, G_FILE_TEST_EXISTS);
}

static gboolean
request_webflow (void)
{
  g_autofree char *request_webflow_file = g_build_filename (g_get_user_runtime_dir (), "request-webflow", NULL);

  return g_file_test (request_webflow_file, G_FILE_TEST_EXISTS);
}

static void
finish_request_ref_tokens (TokenRequestData *data)
{
  g_autofree char *required_token = NULL;
  GVariantBuilder tokens;
  GVariantBuilder results;

  g_assert_true (data->request != NULL);

  required_token = get_required_token ();

  g_variant_builder_init (&tokens, G_VARIANT_TYPE ("a{sas}"));
  g_variant_builder_add (&tokens, "{s^as}", required_token, data->arg_refs);

  g_variant_builder_init (&results, G_VARIANT_TYPE ("a{sv}"));
  g_variant_builder_add (&results, "{sv}", "tokens", g_variant_builder_end (&tokens));

  g_info ("emitting response");
  flatpak_authenticator_request_emit_response (data->request,
                                               FLATPAK_AUTH_RESPONSE_OK,
                                               g_variant_builder_end (&results));
}

static gboolean
http_incoming (GSocketService    *service,
               GSocketConnection *connection,
               GObject           *source_object,
               gpointer           user_data)
{
  TokenRequestData *data = user_data;
  g_autoptr(GVariant) options = g_variant_ref_sink (g_variant_new_array (G_VARIANT_TYPE ("{sv}"), NULL, 0));

  g_assert_true (data->request != NULL);

  /* For the test, just assume any connection is a valid use of the web flow */
  g_info ("handling incoming http request");

  g_info ("emitting webflow done");
  flatpak_authenticator_request_emit_webflow_done (data->request, options);

  finish_request_ref_tokens (data);

  token_request_data_free (data);

  return TRUE;
}

static gboolean
handle_request_close (FlatpakAuthenticatorRequest *object,
                      GDBusMethodInvocation *invocation,
                      gpointer           user_data)
{
  TokenRequestData *data = user_data;

  g_info ("handle_request_close");

  flatpak_authenticator_request_complete_close (object, invocation);

  if (requires_webflow ())
    {
      GVariantBuilder results;

      g_info ("Webflow was cancelled by client");

      g_variant_builder_init (&results, G_VARIANT_TYPE ("a{sv}"));
      flatpak_authenticator_request_emit_response (data->request,
                                                   FLATPAK_AUTH_RESPONSE_CANCELLED,
                                                   g_variant_builder_end (&results));
    }
  else
    {
      g_info ("Ignored webflow cancel by client");
      finish_request_ref_tokens (data); /* Silently succeed anyway */
    }

  token_request_data_free (data);

  return G_DBUS_METHOD_INVOCATION_HANDLED;
}

static gboolean
handle_request_ref_tokens (FlatpakAuthenticator *authenticator,
                           GDBusMethodInvocation *invocation,
                           const gchar *arg_handle_token,
                           GVariant *arg_authenticator_option,
                           const gchar *arg_remote,
                           const gchar *arg_remote_uri,
                           GVariant *arg_refs,
                           GVariant *arg_options,
                           const gchar *arg_parent_window)
{
  g_autoptr(GError) error = NULL;
  g_autoptr(GSocketService) server = NULL;
  g_autoptr(AutoFlatpakAuthenticatorRequest) request = NULL;
  g_autofree char *uri = NULL;
  g_autofree char *request_path = NULL;
  guint16 port;
  g_autoptr(GPtrArray) refs = NULL;
  gsize n_refs, i;
  g_autofree char *options_s = NULL;

  g_info ("handling RequestRefTokens");

  options_s = g_variant_print (arg_options, FALSE);
  write_request (g_strdup_printf ("remote: %s\n"
                                  "uri: %s\n"
                                  "options: %s",
                                  arg_remote,
                                  arg_remote_uri,
                                  options_s));

  request_path = flatpak_auth_create_request_path (g_dbus_method_invocation_get_sender (invocation),
                                                   arg_handle_token, NULL);
  if (request_path == NULL)
    {
      g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
                                             G_DBUS_ERROR_INVALID_ARGS,
                                             "Invalid token");
      return G_DBUS_METHOD_INVOCATION_HANDLED;
    }

  request = flatpak_authenticator_request_skeleton_new ();
  if (!g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (request),
                                         g_dbus_method_invocation_get_connection (invocation),
                                         request_path,
                                         &error))
    {
      g_dbus_method_invocation_return_gerror (invocation, error);
      return G_DBUS_METHOD_INVOCATION_HANDLED;
    }

  server = g_socket_service_new ();
  port = g_socket_listener_add_any_inet_port (G_SOCKET_LISTENER (server), NULL, &error);
  if (port == 0)
    {
      g_dbus_method_invocation_return_gerror (invocation, error);
      return G_DBUS_METHOD_INVOCATION_HANDLED;
    }

  refs = g_ptr_array_new_with_free_func (g_free);
  n_refs = g_variant_n_children (arg_refs);
  for (i = 0; i < n_refs; i++)
    {
      const char *ref, *commit;
      gint32 token_type;
      g_autoptr(GVariant) data = NULL;

      g_variant_get_child (arg_refs, i, "(&s&si@a{sv})", &ref, &commit, &token_type, &data);

      g_ptr_array_add (refs, g_strdup (ref));
    }
  g_ptr_array_add (refs, NULL);

  TokenRequestData *data;
  data = token_request_data_new (request, server, (const char *const*)refs->pdata);

  g_signal_connect (server, "incoming", (GCallback)http_incoming, data);
  g_signal_connect (request, "handle-close", G_CALLBACK (handle_request_close), data);

  flatpak_authenticator_complete_request_ref_tokens (authenticator, invocation, request_path);

  if (request_webflow ())
    {
      g_autoptr(GVariant) options = g_variant_ref_sink (g_variant_new_array (G_VARIANT_TYPE ("{sv}"), NULL, 0));
      uri = g_strdup_printf ("http://localhost:%d", (int)port);
      g_info ("Requesting webflow %s", uri);
      flatpak_authenticator_request_emit_webflow (request, uri, options);
    }
  else
    {
      finish_request_ref_tokens (data);
      token_request_data_free (data);
    }

  return G_DBUS_METHOD_INVOCATION_HANDLED;
}

static void
on_bus_acquired (GDBusConnection *connection,
                 const gchar     *name,
                 gpointer         user_data)
{
  GError *error = NULL;

  g_info ("Bus acquired, creating skeleton");

  g_dbus_connection_set_exit_on_close (connection, FALSE);

  global_authenticator = flatpak_authenticator_skeleton_new ();
  flatpak_authenticator_set_version (global_authenticator, 0);

  g_signal_connect (global_authenticator, "handle-request-ref-tokens", G_CALLBACK (handle_request_ref_tokens), NULL);

  if (!g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (global_authenticator),
                                         connection,
                                         FLATPAK_AUTHENTICATOR_OBJECT_PATH,
                                         &error))
    {
      g_warning ("error: %s", error->message);
      g_error_free (error);
    }
}

static void
on_name_acquired (GDBusConnection *connection,
                  const gchar     *name,
                  gpointer         user_data)
{
  g_info ("Name acquired");
}

static void
on_name_lost (GDBusConnection *connection,
              const gchar     *name,
              gpointer         user_data)
{
  g_info ("Name lost");
}


static void
message_handler (const gchar   *log_domain,
                 GLogLevelFlags log_level,
                 const gchar   *message,
                 gpointer       user_data)
{
  /* Make this look like normal console output */
  if (log_level & (G_LOG_LEVEL_DEBUG | G_LOG_LEVEL_INFO))
    g_printerr ("F: %s\n", message);
  else
    g_printerr ("%s: %s\n", g_get_prgname (), message);
}

int
main (int    argc,
      char **argv)
{
  gboolean replace;
  gboolean opt_verbose;
  GOptionContext *context;
  GDBusConnection *session_bus;
  GBusNameOwnerFlags flags;
  g_autoptr(GError) error = NULL;
  const GOptionEntry options[] = {
    { "replace", 'r', 0, G_OPTION_ARG_NONE, &replace,  "Replace old daemon.", NULL },
    { "verbose", 'v', 0, G_OPTION_ARG_NONE, &opt_verbose,  "Enable debug output.", NULL },
    { NULL }
  };

  setlocale (LC_ALL, "");

  g_setenv ("GIO_USE_VFS", "local", TRUE);

  g_set_prgname (argv[0]);

  g_log_set_handler (G_LOG_DOMAIN, G_LOG_LEVEL_MESSAGE, message_handler, NULL);

  context = g_option_context_new ("");

  replace = FALSE;
  opt_verbose = FALSE;

  g_option_context_set_summary (context, "Flatpak portal");
  g_option_context_add_main_entries (context, options, GETTEXT_PACKAGE);

  if (!g_option_context_parse (context, &argc, &argv, &error))
    {
      g_printerr ("%s: %s", g_get_application_name (), error->message);
      g_printerr ("\n");
      g_printerr ("Try \"%s --help\" for more information.",
                  g_get_prgname ());
      g_printerr ("\n");
      g_option_context_free (context);
      return 1;
    }

  if (opt_verbose)
    g_log_set_handler (G_LOG_DOMAIN, G_LOG_LEVEL_INFO, message_handler, NULL);

  g_info ("Started test-authenticator");

  session_bus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error);
  if (session_bus == NULL)
    {
      g_printerr ("Can't find bus: %s\n", error->message);
      return 1;
    }

  flags = G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT;
  if (replace)
    flags |= G_BUS_NAME_OWNER_FLAGS_REPLACE;

  name_owner_id = g_bus_own_name (G_BUS_TYPE_SESSION,
                                  "org.flatpak.Authenticator.test",
                                  flags,
                                  on_bus_acquired,
                                  on_name_acquired,
                                  on_name_lost,
                                  NULL,
                                  NULL);

  main_loop = g_main_loop_new (NULL, FALSE);
  g_main_loop_run (main_loop);

  return 0;
}

===== ./tests/flatpak-asan.supp =====
# GOnce, deliberately leaking once per process
leak:flatpak_get_user_base_dir_location
leak:flatpak_get_system_default_base_dir_location
# external (libostree)
leak:static_delta_part_execute_thread
leak:_ostree_static_delta_part_open
# external (glib/gdk-pixbuf) used in validate-icon
leak:g_daemon_vfs_init
# Bugs in our code
# Take a look at them and try to figure out  what's going on!
leak:flatpak_authenticator_request_proxy_new_for_bus_sync
leak:flatpak_authenticator_proxy_new_for_bus_sync

===== ./tests/testlibrary.c =====
#include "config.h"

#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>

#include <glib.h>
#include <ostree.h>

#include "libglnx.h"
#include "flatpak.h"

#include "can-use-fuse.h"
#include "testlib.h"

void flatpak_add_all_tests (void);

static char *testdir;
static char *flatpak_runtimedir;
static char *flatpak_systemdir;
static char *flatpak_systemcachedir;
static char *flatpak_configdir;
static char *flatpak_installationsdir;
static char *gpg_homedir;
static char *gpg_args;
static char *repo_collection_id;
static char *httpd_port; /* TODO: leaked? */
int httpd_pid = -1;

static const char *gpg_id = "7B0961FD";
const char *repo_name = "test-repo";

typedef enum {
  RUN_TEST_SUBPROCESS_DEFAULT = 0,
  RUN_TEST_SUBPROCESS_IGNORE_FAILURE = (1 << 0),
  RUN_TEST_SUBPROCESS_NO_CAPTURE = (1 << 1),
} RunTestSubprocessFlags;

static void run_test_subprocess (char                 **argv,
                                 RunTestSubprocessFlags flags);
static void empty_installation (FlatpakInstallation *inst);
static void make_test_app (const char *app_repo_name);
static void update_test_app (void);
static void update_test_app_extension_version (void);
static void update_test_app_extension (void);
static void update_test_runtime (void);
static void update_repo (const char *update_repo_name);
static void rename_test_app (const char *update_repo_name);

typedef struct
{
  const char        *id;
  const char        *display_name;
  gint               priority;
  FlatpakStorageType storage_type;
} InstallationExtraData;

static void
test_library_version (void)
{
  assert_cmpstr_free_lhs (g_strdup_printf ("%d.%d.%d" G_STRINGIFY (PACKAGE_EXTRA_VERSION),
                                           FLATPAK_MAJOR_VERSION,
                                           FLATPAK_MINOR_VERSION,
                                           FLATPAK_MICRO_VERSION),
                          ==, PACKAGE_VERSION);
}

static void
test_library_types (void)
{
  g_assert_true (g_type_is_a (FLATPAK_TYPE_REF, G_TYPE_OBJECT));
  g_assert_true (g_type_is_a (FLATPAK_TYPE_INSTALLED_REF, FLATPAK_TYPE_REF));
  g_assert_true (g_type_is_a (FLATPAK_TYPE_REMOTE_REF, FLATPAK_TYPE_REF));
  g_assert_true (g_type_is_a (FLATPAK_TYPE_BUNDLE_REF, FLATPAK_TYPE_REF));
  g_assert_true (g_type_is_a (FLATPAK_TYPE_RELATED_REF, FLATPAK_TYPE_REF));
  g_assert_true (g_type_is_a (FLATPAK_TYPE_INSTALLATION, G_TYPE_OBJECT));
  g_assert_true (g_type_is_a (FLATPAK_TYPE_INSTANCE, G_TYPE_OBJECT));
  g_assert_true (g_type_is_a (FLATPAK_TYPE_REMOTE, G_TYPE_OBJECT));
  g_assert_true (g_type_is_a (FLATPAK_TYPE_TRANSACTION, G_TYPE_OBJECT));
  g_assert_true (g_type_is_a (FLATPAK_TYPE_TRANSACTION_OPERATION, G_TYPE_OBJECT));
  g_assert_true (g_type_is_a (FLATPAK_TYPE_TRANSACTION_PROGRESS, G_TYPE_OBJECT));
  g_assert_true (g_type_is_a (FLATPAK_TYPE_ERROR, G_TYPE_ENUM));
  g_assert_true (g_type_is_a (FLATPAK_TYPE_PORTAL_ERROR, G_TYPE_ENUM));
  g_assert_true (g_type_is_a (FLATPAK_TYPE_INSTALL_FLAGS, G_TYPE_FLAGS));
  g_assert_true (g_type_is_a (FLATPAK_TYPE_UPDATE_FLAGS, G_TYPE_FLAGS));
  g_assert_true (g_type_is_a (FLATPAK_TYPE_UNINSTALL_FLAGS, G_TYPE_FLAGS));
  g_assert_true (g_type_is_a (FLATPAK_TYPE_STORAGE_TYPE, G_TYPE_ENUM));
  g_assert_true (g_type_is_a (FLATPAK_TYPE_REF_KIND, G_TYPE_ENUM));
  g_assert_true (g_type_is_a (FLATPAK_TYPE_REMOTE_TYPE, G_TYPE_ENUM));
  g_assert_true (g_type_is_a (FLATPAK_TYPE_TRANSACTION_OPERATION_TYPE, G_TYPE_ENUM));
  g_assert_true (g_type_is_a (FLATPAK_TYPE_TRANSACTION_ERROR_DETAILS, G_TYPE_FLAGS));
  g_assert_true (g_type_is_a (FLATPAK_TYPE_TRANSACTION_RESULT, G_TYPE_FLAGS));
  g_assert_true (g_type_is_a (FLATPAK_TYPE_TRANSACTION_REMOTE_REASON, G_TYPE_ENUM));
}

static void
test_user_installation (void)
{
  g_autoptr(FlatpakInstallation) inst = NULL;
  g_autoptr(GError) error = NULL;
  g_autoptr(GFile) dir = NULL;

  inst = flatpak_installation_new_user (NULL, &error);
  g_assert_no_error (error);
  g_assert_nonnull (inst);

  g_assert_true (flatpak_installation_get_is_user (inst));

  dir = flatpak_installation_get_path (inst);
  assert_cmpstr_free_both (g_file_get_path (dir), ==,
                           g_build_filename (g_get_user_data_dir (), "flatpak", NULL));
}

static void
test_system_installation (void)
{
  g_autoptr(FlatpakInstallation) inst = NULL;
  g_autoptr(GError) error = NULL;
  g_autoptr(GFile) dir = NULL;

  inst = flatpak_installation_new_system (NULL, &error);
  g_assert_no_error (error);
  g_assert_nonnull (inst);

  g_assert_false (flatpak_installation_get_is_user (inst));

  dir = flatpak_installation_get_path (inst);
  assert_cmpstr_free_lhs (g_file_get_path (dir), ==, flatpak_systemdir);
}

static void
test_multiple_system_installations (void)
{
  /* This is sorted according to the specific priority of each installation */
  static InstallationExtraData expected_installations[] = {
    { "extra-installation-2", "Extra system installation 2", 25, FLATPAK_STORAGE_TYPE_SDCARD},
    { "extra-installation-1", "Extra system installation 1", 10, FLATPAK_STORAGE_TYPE_MMC},
    { "extra-installation-3", "System (extra-installation-3) installation", 0, FLATPAK_STORAGE_TYPE_DEFAULT},
    { "default", "Default system installation", 0, FLATPAK_STORAGE_TYPE_DEFAULT},
  };
  g_autoptr(GPtrArray) system_dirs = NULL;
  g_autoptr(GError) error = NULL;

  FlatpakInstallation *installation = NULL;
  const char *current_id = NULL;
  const char *current_display_name = NULL;
  gint current_priority = 0;
  FlatpakStorageType current_storage_type = FLATPAK_STORAGE_TYPE_DEFAULT;
  int i;

  system_dirs = flatpak_get_system_installations (NULL, &error);
  g_assert_no_error (error);
  g_assert_nonnull (system_dirs);
  g_assert_cmpint (system_dirs->len, ==, 4);

  for (i = 0; i < system_dirs->len; i++)
    {
      g_autoptr(FlatpakInstallation) new_install = NULL;
      g_autoptr(GFile) installation_path = NULL;
      g_autofree char *path_str = NULL;

      installation = (FlatpakInstallation *) g_ptr_array_index (system_dirs, i);
      g_assert_false (flatpak_installation_get_is_user (installation));

      installation_path = flatpak_installation_get_path (installation);
      g_assert_nonnull (installation_path);

      current_id = flatpak_installation_get_id (installation);
      g_assert_cmpstr (current_id, ==, expected_installations[i].id);

      path_str = g_file_get_path (installation_path);
      if (g_strcmp0 (current_id, "default") == 0)
        g_assert_cmpstr (path_str, ==, flatpak_systemdir);
      else
        g_assert_cmpstr (path_str, !=, flatpak_systemdir);

      current_display_name = flatpak_installation_get_display_name (installation);
      g_assert_cmpstr (current_display_name, ==, expected_installations[i].display_name);

      current_priority = flatpak_installation_get_priority (installation);
      g_assert_cmpint (current_priority, ==, expected_installations[i].priority);

      current_storage_type = flatpak_installation_get_storage_type (installation);
      g_assert_cmpint (current_storage_type, ==, expected_installations[i].storage_type);

      /* Now test that flatpak_installation_new_system_with_id() works too */

      new_install = flatpak_installation_new_system_with_id (current_id, NULL, &error);
      g_assert_nonnull (new_install);

      g_assert_cmpstr (current_id, ==, flatpak_installation_get_id (new_install));
      g_assert_cmpstr (current_display_name, ==, flatpak_installation_get_display_name (new_install));
      g_assert_cmpint (current_priority, ==, flatpak_installation_get_priority (new_install));
      g_assert_cmpint (current_storage_type, ==, flatpak_installation_get_storage_type (new_install));
    }
}

static void
test_installation_config (void)
{
  g_autoptr(FlatpakInstallation) inst = NULL;
  g_autofree char *path = NULL;
  g_autoptr(GFile) file = NULL;
  g_autoptr(GError) error = NULL;
  gboolean res;
  guint64 bytes;

  path = g_build_filename (g_get_user_data_dir (), "flatpak", NULL);
  file = g_file_new_for_path (path);
  inst = flatpak_installation_new_for_path (file, TRUE, NULL, &error);
  g_assert_no_error (error);
  g_assert_nonnull (inst);

  assert_cmpstr_free_lhs (flatpak_installation_get_config (inst, "test", NULL, &error),
                          ==, NULL);
  g_assert_error (error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_KEY_NOT_FOUND);
  g_clear_error (&error);

  res = flatpak_installation_set_config_sync (inst, "test", "hello", NULL, &error);
  g_assert_true (res);
  g_assert_no_error (error);

  assert_cmpstr_free_lhs (flatpak_installation_get_config (inst, "test", NULL, &error),
                          ==, "hello");
  g_assert_no_error (error);

  g_clear_object (&inst);

  inst = flatpak_installation_new_user (NULL, &error);
  g_assert_no_error (error);
  g_assert_nonnull (inst);

  assert_cmpstr_free_lhs (flatpak_installation_get_config (inst, "test", NULL, &error),
                          ==, "hello");
  g_assert_no_error (error);

  res = flatpak_installation_get_min_free_space_bytes (inst, &bytes, &error);
  g_assert_true (res);
  g_assert_no_error (error);
}

static void
configure_languages (const char *lang)
{
  const char *argv[] = { "flatpak", "config", "--user", "--set", "languages", lang, NULL };

  run_test_subprocess ((char **)argv, RUN_TEST_SUBPROCESS_DEFAULT);
}

static void
clean_languages (void)
{
  char *argv[] = { "flatpak", "config", "--user", "--unset", "languages", NULL };

  run_test_subprocess (argv, RUN_TEST_SUBPROCESS_DEFAULT);
}

static void
configure_extra_languages (void)
{
  char *argv[] = { "flatpak", "config", "--user", "--set", "extra-languages", "de_DE", NULL };

  run_test_subprocess (argv, RUN_TEST_SUBPROCESS_DEFAULT);
}

static void
clean_extra_languages (void)
{
  char *argv[] = { "flatpak", "config", "--user", "--unset", "extra-languages", NULL };

  run_test_subprocess (argv, RUN_TEST_SUBPROCESS_DEFAULT);
}

static void
test_languages_config (void)
{
  g_autoptr(FlatpakInstallation) inst = NULL;
  g_autofree char *path = NULL;
  g_autoptr(GFile) file = NULL;
  g_autoptr(GError) error = NULL;
  g_auto(GStrv) value = NULL;
  gboolean res;

  clean_languages ();
  path = g_build_filename (g_get_user_data_dir (), "flatpak", NULL);
  file = g_file_new_for_path (path);
  inst = flatpak_installation_new_for_path (file, TRUE, NULL, &error);
  g_assert_no_error (error);
  g_assert_nonnull (inst);

  value = flatpak_installation_get_default_languages (inst, &error);
  g_assert_no_error (error);
  g_assert_cmpstr (value[0], ==, "en");
  g_assert_null (value[1]);

  g_clear_pointer (&value, g_strfreev);

  res = flatpak_installation_set_config_sync (inst, "extra-languages", "pt_BR;uz_UZ.utf8@cyrillic;es;zh_HK.big5hkscs;uz_UZ@cyrillic", NULL, &error);
  g_assert_no_error (error);
  g_assert_true (res);

  value = flatpak_installation_get_default_languages (inst, &error);
  g_assert_no_error (error);
  g_assert_cmpstr (value[0], ==, "en");
  g_assert_cmpstr (value[1], ==, "es");
  g_assert_cmpstr (value[2], ==, "pt");
  g_assert_cmpstr (value[3], ==, "uz");
  g_assert_cmpstr (value[4], ==, "zh");
  g_assert_null (value[5]);

  g_clear_pointer (&value, g_strfreev);

  value = flatpak_installation_get_default_locales (inst, &error);
  g_assert_no_error (error);
  g_assert_cmpstr (value[0], ==, "en");
  g_assert_cmpstr (value[1], ==, "es");
  g_assert_cmpstr (value[2], ==, "pt_BR");
  g_assert_cmpstr (value[3], ==, "uz_UZ.utf8@cyrillic");
  g_assert_cmpstr (value[4], ==, "uz_UZ@cyrillic");
  g_assert_cmpstr (value[5], ==, "zh_HK.big5hkscs");
  g_assert_null (value[6]);

  g_clear_pointer (&value, g_strfreev);

  res = flatpak_installation_set_config_sync (inst, "languages", "ar;es", NULL, &error);
  g_assert_no_error (error);
  g_assert_true (res);

  value = flatpak_installation_get_default_languages (inst, &error);
  g_assert_no_error (error);
  g_assert_cmpstr (value[0], ==, "ar");
  g_assert_cmpstr (value[1], ==, "es");
  g_assert_null (value[2]);

  g_clear_pointer (&value, g_strfreev);
  clean_extra_languages ();
  configure_languages ("de");
}

static void
test_arches (void)
{
  const char *default_arch;
  const char *const *supported_arches;

  default_arch = flatpak_get_default_arch ();
  supported_arches = flatpak_get_supported_arches ();

  g_assert_nonnull (default_arch);
  g_assert_cmpstr (default_arch, !=, "");

  g_assert_nonnull (supported_arches);
  g_assert_true (g_strv_contains (supported_arches, default_arch));
}

static void
test_ref (void)
{
  g_autoptr(FlatpakRef) ref = NULL;
  g_autoptr(GError) error = NULL;
  const char *valid;
  FlatpakRefKind kind;
  g_autofree char *name = NULL;
  g_autofree char *arch = NULL;
  g_autofree char *branch = NULL;
  g_autofree char *commit = NULL;
  g_autofree char *collection_id = NULL;

  ref = flatpak_ref_parse ("", &error);
  g_assert_null (ref);
  g_assert_error (error, FLATPAK_ERROR, FLATPAK_ERROR_INVALID_REF);
  g_clear_error (&error);

  ref = flatpak_ref_parse ("ref/or not", &error);
  g_assert_null (ref);
  g_assert_error (error, FLATPAK_ERROR, FLATPAK_ERROR_INVALID_REF);
  g_clear_error (&error);

  ref = flatpak_ref_parse ("ref/one/2/3", &error);
  g_assert_null (ref);
  g_assert_error (error, FLATPAK_ERROR, FLATPAK_ERROR_INVALID_REF);
  g_clear_error (&error);

  ref = flatpak_ref_parse ("app/a/b/c", &error);
  g_assert_null (ref);
  g_assert_error (error, FLATPAK_ERROR, FLATPAK_ERROR_INVALID_REF);
  g_clear_error (&error);

  ref = flatpak_ref_parse ("app/org.flatpak.Hello/b/.", &error);
  g_assert_null (ref);
  g_assert_error (error, FLATPAK_ERROR, FLATPAK_ERROR_INVALID_REF);
  g_clear_error (&error);

  ref = flatpak_ref_parse ("foo/org.flatpak.Hello/b/.", &error);
  g_assert_null (ref);
  g_assert_error (error, FLATPAK_ERROR, FLATPAK_ERROR_INVALID_REF);
  g_clear_error (&error);

  ref = flatpak_ref_parse ("app//m68k/master", &error);
  g_assert_null (ref);
  g_assert_error (error, FLATPAK_ERROR, FLATPAK_ERROR_INVALID_REF);
  g_clear_error (&error);

  ref = flatpak_ref_parse ("app/org.test.Hello/m68k/", &error);
  g_assert_null (ref);
  g_assert_error (error, FLATPAK_ERROR, FLATPAK_ERROR_INVALID_REF);
  g_clear_error (&error);

  ref = flatpak_ref_parse ("app/org.test.Hello/m68k/a[b]c", &error);
  g_assert_null (ref);
  g_assert_error (error, FLATPAK_ERROR, FLATPAK_ERROR_INVALID_REF);
  g_clear_error (&error);

  ref = flatpak_ref_parse ("app/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
                           "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
                           "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
                           "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
                           "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
                           "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
                           "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
                           "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
                           "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
                           "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
                           "/m68k/master", &error);
  g_assert_null (ref);
  g_assert_error (error, FLATPAK_ERROR, FLATPAK_ERROR_INVALID_REF);
  g_clear_error (&error);

  ref = flatpak_ref_parse ("app/.abc/m68k/master", &error);
  g_assert_null (ref);
  g_assert_error (error, FLATPAK_ERROR, FLATPAK_ERROR_INVALID_REF);
  g_clear_error (&error);

  ref = flatpak_ref_parse ("app/0abc/m68k/master", &error);
  g_assert_null (ref);
  g_assert_error (error, FLATPAK_ERROR, FLATPAK_ERROR_INVALID_REF);
  g_clear_error (&error);

  valid = "app/org.flatpak.Hello/m68k/master";
  ref = flatpak_ref_parse (valid, &error);
  g_assert_no_error (error);
  g_assert_true (FLATPAK_IS_REF (ref));
  g_assert_cmpint (flatpak_ref_get_kind (ref), ==, FLATPAK_REF_KIND_APP);
  g_assert_cmpstr (flatpak_ref_get_name (ref), ==, "org.flatpak.Hello");
  g_assert_cmpstr (flatpak_ref_get_arch (ref), ==, "m68k");
  g_assert_cmpstr (flatpak_ref_get_branch (ref), ==, "master");
  g_assert_null (flatpak_ref_get_collection_id (ref));

  assert_cmpstr_free_lhs (flatpak_ref_format_ref (ref), ==, valid);

  g_clear_object (&ref);

  valid = "runtime/org.gnome.Platform/m68k/stable";
  ref = flatpak_ref_parse (valid, &error);
  g_assert_no_error (error);
  g_assert_true (FLATPAK_IS_REF (ref));

  g_object_get (ref,
                "kind", &kind,
                "name", &name,
                "arch", &arch,
                "branch", &branch,
                "commit", &commit,
                "collection-id", &collection_id,
                NULL);
  g_assert_cmpint (kind, ==, FLATPAK_REF_KIND_RUNTIME);
  g_assert_cmpstr (name, ==, "org.gnome.Platform");
  g_assert_cmpstr (arch, ==, "m68k");
  g_assert_cmpstr (branch, ==, "stable");
  g_assert_null (commit);
  g_assert_null (collection_id);

  assert_cmpstr_free_lhs (flatpak_ref_format_ref (ref), ==, valid);

  g_clear_object (&ref);

  ref = g_object_new (FLATPAK_TYPE_REF,
                      "kind", FLATPAK_REF_KIND_RUNTIME,
                      "name", "org.gnome.Platform",
                      "arch", "m68k",
                      "branch", "stable",
                      "commit", "0123456789",
                      "collection-id", "org.flathub.Stable",
                      NULL);

  g_assert_cmpstr (flatpak_ref_get_commit (ref), ==, "0123456789");
  g_assert_cmpstr (flatpak_ref_get_collection_id (ref), ==, "org.flathub.Stable");

  g_clear_object (&ref);
}

static void
test_list_remotes (void)
{
  g_autoptr(FlatpakInstallation) inst = NULL;
  g_autoptr(GError) error = NULL;
  g_autoptr(GPtrArray) remotes = NULL;
  g_autoptr(GPtrArray) remotes2 = NULL;
  FlatpakRemote *remote;
  const FlatpakRemoteType types[] = { FLATPAK_REMOTE_TYPE_STATIC };
  const FlatpakRemoteType types2[] = { FLATPAK_REMOTE_TYPE_LAN };
  gboolean res;

  inst = flatpak_installation_new_user (NULL, &error);
  g_assert_no_error (error);

  res = flatpak_installation_update_remote_sync (inst, repo_name, NULL, &error);
  g_assert_no_error (error);
  g_assert_true (res);

  res = flatpak_installation_update_appstream_sync (inst, repo_name, NULL, NULL, NULL, &error);
  g_assert_no_error (error);
  g_assert_true (res);

  remotes = flatpak_installation_list_remotes (inst, NULL, &error);
  g_assert_no_error (error);
  g_assert_nonnull (remotes);
  g_assert_true (remotes->len == 1);

  remote = g_ptr_array_index (remotes, 0);
  g_assert_true (FLATPAK_IS_REMOTE (remote));

  remotes2 = flatpak_installation_list_remotes_by_type (inst, types,
                                                        G_N_ELEMENTS (types),
                                                        NULL, &error);
  g_assert_no_error (error);
  g_assert_cmpuint (remotes2->len, ==, remotes->len);

  for (guint i = 0; i < remotes->len; ++i)
    {
      FlatpakRemote *remote1 = g_ptr_array_index (remotes, i);
      FlatpakRemote *remote2 = g_ptr_array_index (remotes2, i);

      g_assert_cmpstr (flatpak_remote_get_name (remote1), ==,
                       flatpak_remote_get_name (remote2));
      assert_cmpstr_free_both (flatpak_remote_get_url (remote1), ==,
                               flatpak_remote_get_url (remote2));
    }

  g_ptr_array_unref (remotes2);
  remotes2 = flatpak_installation_list_remotes_by_type (inst,
                                                        types2,
                                                        G_N_ELEMENTS (types2),
                                                        NULL, &error);
  g_assert_no_error (error);
  g_assert_cmpuint (remotes2->len, ==, 0);
}

static void
test_timestamp (void)
{
  g_autoptr(FlatpakInstallation) inst = NULL;
  g_autoptr(GError) error = NULL;
  g_autoptr(FlatpakRemote) remote = NULL;
  guint64 mtime1, mtime2, mtime3;

  inst = flatpak_installation_new_user (NULL, &error);
  g_assert_no_error (error);

  /* Get initial modification time */
  mtime1 = flatpak_installation_get_timestamp (inst);
  g_assert_cmpuint (mtime1, <, G_MAXUINT64);

  /* Wait at least 1 second */
  sleep (1);

  /* Modification time should stay the same when nothing changes */
  mtime2 = flatpak_installation_get_timestamp (inst);
  g_assert_cmpuint (mtime2, ==, mtime1);

  /* Modifying a remote should update the modification time */
  remote = flatpak_installation_get_remote_by_name (inst, repo_name, NULL, &error);
  g_assert_no_error (error);
  g_assert_nonnull (remote);

  flatpak_remote_set_disabled (remote, TRUE);
  flatpak_installation_modify_remote (inst, remote, NULL, &error);
  g_assert_no_error (error);

  /* Need to drop caches to see the new modification time */
  flatpak_installation_drop_caches (inst, NULL, NULL);

  mtime3 = flatpak_installation_get_timestamp (inst);
  g_assert_cmpuint (mtime3, >, mtime2);

  /* Restore the remote state */
  flatpak_remote_set_disabled (remote, FALSE);
  flatpak_installation_modify_remote (inst, remote, NULL, &error);
  g_assert_no_error (error);
}

static void
test_remote_by_name (void)
{
  g_autoptr(FlatpakInstallation) inst = NULL;
  g_autoptr(GError) error = NULL;
  g_autoptr(FlatpakRemote) remote = NULL;
  g_autofree char *name = NULL;
  FlatpakRemoteType type;
  g_autoptr(GFile) file = NULL;
  g_autofree char *repo_url = NULL;

  inst = flatpak_installation_new_user (NULL, &error);
  g_assert_no_error (error);

  remote = flatpak_installation_get_remote_by_name (inst, repo_name, NULL, &error);
  g_assert_no_error (error);

  repo_url = g_strdup_printf ("http://127.0.0.1:%s/test", httpd_port);

  g_assert_true (FLATPAK_IS_REMOTE (remote));
  g_assert_cmpstr (flatpak_remote_get_name (remote), ==, repo_name);
  assert_cmpstr_free_lhs (flatpak_remote_get_url (remote), ==, repo_url);
  assert_cmpstr_free_lhs (flatpak_remote_get_title (remote), ==, NULL);
  g_assert_cmpint (flatpak_remote_get_remote_type (remote), ==, FLATPAK_REMOTE_TYPE_STATIC);
  g_assert_false (flatpak_remote_get_noenumerate (remote));
  g_assert_false (flatpak_remote_get_disabled (remote));
  g_assert_true (flatpak_remote_get_gpg_verify (remote));
  g_assert_cmpint (flatpak_remote_get_prio (remote), ==, 1);

  assert_cmpstr_free_lhs (flatpak_remote_get_collection_id (remote), ==, repo_collection_id);

  g_object_get (remote,
                "name", &name,
                "type", &type,
                NULL);

  g_assert_cmpstr (name, ==, repo_name);
  g_assert_cmpint (type, ==, FLATPAK_REMOTE_TYPE_STATIC);

  file = flatpak_remote_get_appstream_dir (remote, NULL);
  g_assert_nonnull (file);
  g_clear_object (&file);

  file = flatpak_remote_get_appstream_timestamp (remote, NULL);
  g_assert_nonnull (file);
}

static void
test_remote (void)
{
  g_autoptr(FlatpakInstallation) inst = NULL;
  g_autoptr(GError) error = NULL;
  g_autoptr(FlatpakRemote) remote = NULL;
  g_autoptr(GFile) inst_file = NULL;
  g_autoptr(GFile) repo_file = NULL;
  g_autoptr(OstreeRepo) repo = NULL;
  gboolean gpg_verify_summary;
  gboolean res;

  inst = flatpak_installation_new_user (NULL, &error);
  g_assert_no_error (error);

  remote = flatpak_installation_get_remote_by_name (inst, repo_name, NULL, &error);
  g_assert_no_error (error);

  assert_cmpstr_free_lhs (flatpak_remote_get_collection_id (remote), ==, repo_collection_id);

  /* Flatpak doesn't provide access to gpg-verify-summary, so use ostree */
  res = flatpak_installation_modify_remote (inst, remote, NULL, &error);
  g_assert_no_error (error);
  g_assert_true (res);
  inst_file = flatpak_installation_get_path (inst);
  repo_file = g_file_get_child (inst_file, "repo");
  repo = ostree_repo_new (repo_file);
  res = ostree_repo_open (repo, NULL, &error);
  g_assert_no_error (error);
  g_assert_true (res);
  res = ostree_repo_get_remote_boolean_option (repo, repo_name, "gpg-verify-summary", FALSE, &gpg_verify_summary, &error);
  g_assert_no_error (error);
  g_assert_true (res);
  g_assert_true (gpg_verify_summary);

  /* Temporarily unset the collection ID */
  flatpak_remote_set_collection_id (remote, NULL);
  g_assert_cmpstr (flatpak_remote_get_collection_id (remote), ==, NULL);

  res = flatpak_installation_modify_remote (inst, remote, NULL, &error);
  g_assert_no_error (error);
  g_assert_true (res);
  res = ostree_repo_reload_config (repo, NULL, &error);
  g_assert_no_error (error);
  g_assert_true (res);
  res = ostree_repo_get_remote_boolean_option (repo, repo_name, "gpg-verify-summary", FALSE, &gpg_verify_summary, &error);
  g_assert_no_error (error);
  g_assert_true (res);
  g_assert_true (gpg_verify_summary);

  flatpak_remote_set_collection_id (remote, repo_collection_id);
  assert_cmpstr_free_lhs (flatpak_remote_get_collection_id (remote), ==, repo_collection_id);

  g_assert_cmpstr (flatpak_remote_get_title (remote), ==, NULL);
  flatpak_remote_set_title (remote, "Test Repo");
  assert_cmpstr_free_lhs (flatpak_remote_get_title (remote), ==, "Test Repo");

  g_assert_cmpint (flatpak_remote_get_prio (remote), ==, 1);
  flatpak_remote_set_prio (remote, 15);
  g_assert_cmpint (flatpak_remote_get_prio (remote), ==, 15);

  g_assert_false (flatpak_remote_get_noenumerate (remote));
  flatpak_remote_set_noenumerate (remote, TRUE);
  g_assert_true (flatpak_remote_get_noenumerate (remote));

  g_assert_false (flatpak_remote_get_nodeps (remote));
  flatpak_remote_set_nodeps (remote, TRUE);
  g_assert_true (flatpak_remote_get_nodeps (remote));

  g_assert_false (flatpak_remote_get_disabled (remote));
  flatpak_remote_set_disabled (remote, TRUE);
  g_assert_true (flatpak_remote_get_disabled (remote));

  g_assert_null (flatpak_remote_get_default_branch (remote));
  flatpak_remote_set_default_branch (remote, "master");
  assert_cmpstr_free_lhs (flatpak_remote_get_default_branch (remote), ==, "master");

  /* It should be an error to disable GPG while a collection ID is set. */
  g_assert_true (flatpak_remote_get_gpg_verify (remote));
  flatpak_remote_set_gpg_verify (remote, FALSE);
  g_assert_false (flatpak_remote_get_gpg_verify (remote));
  res = flatpak_installation_modify_remote (inst, remote, NULL, &error);
  g_assert_error (error, FLATPAK_ERROR, FLATPAK_ERROR_INVALID_DATA);
  g_clear_error (&error);
  g_assert_false (res);

  /* Unset the collection ID and try again. */
  flatpak_remote_set_collection_id (remote, NULL);
  g_assert_cmpstr (flatpak_remote_get_collection_id (remote), ==, NULL);
  g_assert_false (flatpak_remote_get_gpg_verify (remote));

  res = flatpak_installation_modify_remote (inst, remote, NULL, &error);
  g_assert_no_error (error);
  g_assert_true (res);

  g_clear_object (&remote);

  remote = flatpak_installation_get_remote_by_name (inst, repo_name, NULL, &error);
  g_assert_no_error (error);

  assert_cmpstr_free_lhs (flatpak_remote_get_title (remote), ==, "Test Repo");
  g_assert_cmpint (flatpak_remote_get_prio (remote), ==, 15);
  g_assert_true (flatpak_remote_get_noenumerate (remote));
  g_assert_true (flatpak_remote_get_nodeps (remote));
  g_assert_false (flatpak_remote_get_gpg_verify (remote));
  assert_cmpstr_free_lhs (flatpak_remote_get_default_branch (remote), ==, "master");

  /* back to defaults */
  flatpak_remote_set_title (remote, NULL);
  flatpak_remote_set_prio (remote, 1);
  flatpak_remote_set_noenumerate (remote, FALSE);
  flatpak_remote_set_nodeps (remote, FALSE);
  flatpak_remote_set_disabled (remote, FALSE);
  flatpak_remote_set_default_branch (remote, NULL);
  flatpak_remote_set_gpg_verify (remote, TRUE);
  flatpak_remote_set_collection_id (remote, repo_collection_id);

  res = flatpak_installation_modify_remote (inst, remote, NULL, &error);
  g_assert_no_error (error);
  g_assert_true (res);
}

static void
test_remote_new (void)
{
  g_autoptr(FlatpakInstallation) inst = NULL;
  g_autoptr(FlatpakRemote) remote = NULL;
  g_autoptr(GError) error = NULL;
  gboolean res;

  inst = flatpak_installation_new_user (NULL, &error);
  g_assert_no_error (error);

  remote = flatpak_installation_get_remote_by_name (inst, "my-first-remote", NULL, &error);
  g_assert_null (remote);
  g_assert_error (error, FLATPAK_ERROR, FLATPAK_ERROR_REMOTE_NOT_FOUND);
  g_clear_error (&error);

  remote = flatpak_remote_new ("my-first-remote");

  g_assert_null (flatpak_remote_get_appstream_dir (remote, NULL));
  g_assert_null (flatpak_remote_get_appstream_timestamp (remote, NULL));
  g_assert_null (flatpak_remote_get_url (remote));
  g_assert_null (flatpak_remote_get_collection_id (remote));
  g_assert_null (flatpak_remote_get_title (remote));
  g_assert_null (flatpak_remote_get_default_branch (remote));
  g_assert_false (flatpak_remote_get_noenumerate (remote));
  g_assert_false (flatpak_remote_get_nodeps (remote));
  g_assert_false (flatpak_remote_get_disabled (remote));
  g_assert_cmpint (flatpak_remote_get_prio (remote), ==, 1);
  g_assert_false (flatpak_remote_get_gpg_verify (remote));

  res = flatpak_installation_add_remote (inst, remote, FALSE, NULL, &error);
  g_assert_error (error, FLATPAK_ERROR, FLATPAK_ERROR_INVALID_DATA);
  g_assert_false (res);
  g_clear_error (&error);

  flatpak_remote_set_url (remote, "http://127.0.0.1/nowhere");

  res = flatpak_installation_add_remote (inst, remote, FALSE, NULL, &error);
  g_assert_no_error (error);
  g_assert_true (res);

  g_clear_object (&remote);

  remote = flatpak_installation_get_remote_by_name (inst, "my-first-remote", NULL, &error);
  g_assert_no_error (error);

  assert_cmpstr_free_lhs (flatpak_remote_get_url (remote), ==, "http://127.0.0.1/nowhere");

  g_clear_object (&remote);

  remote = flatpak_remote_new ("my-first-remote");
  flatpak_remote_set_url (remote, "http://127.0.0.1/elsewhere");

  res = flatpak_installation_add_remote (inst, remote, FALSE, NULL, &error);
  g_assert_error (error, FLATPAK_ERROR, FLATPAK_ERROR_ALREADY_INSTALLED);
  g_clear_error (&error);
  g_assert_false (res);

  /* add if needed */
  res = flatpak_installation_add_remote (inst, remote, TRUE, NULL, &error);
  g_assert_no_error (error);
  g_assert_true (res);

  g_clear_object (&remote);

  remote = flatpak_installation_get_remote_by_name (inst, "my-first-remote", NULL, &error);
  g_assert_no_error (error);

  /* Should be the old value */
  assert_cmpstr_free_lhs (flatpak_remote_get_url (remote), ==, "http://127.0.0.1/nowhere");

  g_clear_object (&remote);

  res = flatpak_installation_remove_remote (inst, "my-first-remote", NULL, &error);
  g_assert_no_error (error);
  g_assert_true (res);

  remote = flatpak_installation_get_remote_by_name (inst, "my-first-remote", NULL, &error);
  g_assert_null (remote);
  g_assert_error (error, FLATPAK_ERROR, FLATPAK_ERROR_REMOTE_NOT_FOUND);
  g_clear_error (&error);
}

static void
_remove_remote (const char *remote_name,
                gboolean    system)
{
  char *argv[] = { "flatpak", "remote-delete", NULL, "name", NULL };

  argv[2] = system ? "--system" : "--user";
  argv[3] = (char *)remote_name;

  run_test_subprocess (argv, RUN_TEST_SUBPROCESS_DEFAULT);
}

static void
remove_remote_system (const char *remote_name)
{
  _remove_remote (remote_name, TRUE);
}

static void
remove_remote_user (const char *remote_name)
{
  _remove_remote (remote_name, FALSE);
}

static void
test_remote_new_from_file (void)
{
  g_autoptr(FlatpakInstallation) inst = NULL;
  g_autoptr(FlatpakRemote) remote = NULL;
  g_autoptr(GError) error = NULL;
  gboolean res;
  const char *_data =
    "[Flatpak Repo]\n"
    "Url=http://127.0.0.1/repo\n"
    "Title=The Title\n"
    "Comment=The Comment\n"
    "Description=The Description\n"
    "Homepage=https://the.homepage/\n"
    "Icon=https://the.icon/\n"
    "DefaultBranch=default-branch\n"
    "NoDeps=true\n";
  g_autoptr(GBytes) data = g_bytes_new_static (_data, strlen (_data));

  inst = flatpak_installation_new_user (NULL, &error);
  g_assert_no_error (error);

  remote = flatpak_installation_get_remote_by_name (inst, "file-remote", NULL, &error);
  g_assert_null (remote);
  g_assert_error (error, FLATPAK_ERROR, FLATPAK_ERROR_REMOTE_NOT_FOUND);
  g_clear_error (&error);

  remote = flatpak_remote_new_from_file ("file-remote", data, &error);
  g_assert_nonnull (remote);
  g_assert_no_error (error);

  res = flatpak_installation_add_remote (inst, remote, FALSE, NULL, &error);
  g_assert_no_error (error);
  g_assert_true (res);

  g_clear_object (&remote);

  remote = flatpak_installation_get_remote_by_name (inst, "file-remote", NULL, &error);
  g_assert_no_error (error);

  assert_cmpstr_free_lhs (flatpak_remote_get_url (remote), ==, "http://127.0.0.1/repo");
  assert_cmpstr_free_lhs (flatpak_remote_get_title (remote), ==, "The Title");
  assert_cmpstr_free_lhs (flatpak_remote_get_comment (remote), ==, "The Comment");
  assert_cmpstr_free_lhs (flatpak_remote_get_description (remote), ==, "The Description");
  assert_cmpstr_free_lhs (flatpak_remote_get_homepage (remote), ==, "https://the.homepage/");
  assert_cmpstr_free_lhs (flatpak_remote_get_icon (remote), ==, "https://the.icon/");
  assert_cmpstr_free_lhs (flatpak_remote_get_default_branch (remote), ==, "default-branch");
  g_assert_cmpint (flatpak_remote_get_nodeps (remote), ==, TRUE);

  g_clear_object (&remote);

  remote = flatpak_installation_get_remote_by_name (inst, "file-remote", NULL, &error);
  g_assert_no_error (error);

  g_assert_cmpstr (flatpak_remote_get_filter (remote), ==, NULL);

  flatpak_remote_set_url (remote, "http://127.0.0.1/other");
  flatpak_remote_set_filter (remote, "/some/path/to/filter");

  res = flatpak_installation_modify_remote (inst, remote, NULL, &error);
  g_assert_no_error (error);
  g_assert_true (res);

  g_clear_object (&remote);

  remote = flatpak_installation_get_remote_by_name (inst, "file-remote", NULL, &error);
  g_assert_no_error (error);

  assert_cmpstr_free_lhs (flatpak_remote_get_url (remote), ==, "http://127.0.0.1/other");
  assert_cmpstr_free_lhs (flatpak_remote_get_filter (remote), ==, "/some/path/to/filter");

  g_clear_object (&remote);

  remote = flatpak_remote_new_from_file ("file-remote", data, &error);
  g_assert_nonnull (remote);
  g_assert_no_error (error);

  /* regular add fails */
  res = flatpak_installation_add_remote (inst, remote, FALSE, NULL, &error);
  g_assert_error (error, FLATPAK_ERROR, FLATPAK_ERROR_ALREADY_INSTALLED);
  g_clear_error (&error);
  g_assert_false (res);

  /* add if needed succeeds and resets filter */
  res = flatpak_installation_add_remote (inst, remote, TRUE, NULL, &error);
  g_assert_no_error (error);
  g_assert_true (res);

  g_clear_object (&remote);

  remote = flatpak_installation_get_remote_by_name (inst, "file-remote", NULL, &error);
  g_assert_no_error (error);

  assert_cmpstr_free_lhs (flatpak_remote_get_url (remote), ==, "http://127.0.0.1/other");
  assert_cmpstr_free_lhs (flatpak_remote_get_filter (remote), ==, NULL);

  g_clear_object (&remote);

  remove_remote_user ("file-remote");
}

static void
test_list_refs (void)
{
  g_autoptr(FlatpakInstallation) inst = NULL;
  g_autoptr(GError) error = NULL;
  g_autoptr(GPtrArray) refs = NULL;

  inst = flatpak_installation_new_user (NULL, &error);
  g_assert_no_error (error);

  refs = flatpak_installation_list_installed_refs (inst, NULL, &error);
  g_assert_no_error (error);
  g_assert_nonnull (refs);
  g_assert_cmpint (refs->len, ==, 0);
}

static void
create_multi_collection_id_repo (const char *repo_dir)
{
  g_autofree char *arg0 = NULL;

  /* Create a repository in which each app has a different collection-id */
  arg0 = g_test_build_filename (G_TEST_DIST, "make-multi-collection-id-repo.sh", NULL);
  const char *argv[] = { arg0, repo_dir, NULL };
  run_test_subprocess ((char **) argv, RUN_TEST_SUBPROCESS_DEFAULT);
}

static void
test_list_refs_in_remotes (void)
{
  const char *repo_name2 = "multi-refs-repo";
  g_autofree char *repo_url = NULL;
  g_autoptr(GPtrArray) refs1 = NULL;
  g_autoptr(GPtrArray) refs2 = NULL;
  g_autoptr(FlatpakInstallation) inst = NULL;
  g_autoptr(GError) error = NULL;
  g_autoptr(FlatpakRemote) remote = NULL;
  g_autofree char *repo_dir = g_build_filename (testdir, repo_name2, NULL);
  g_autofree char *repo_uri = NULL;
  g_autoptr(GHashTable) ref_specs = g_hash_table_new_full (g_str_hash,
                                                           g_str_equal,
                                                           NULL,
                                                           NULL);

  create_multi_collection_id_repo (repo_dir);

  repo_url = g_strdup_printf ("file://%s", repo_dir);

  const char *argv[] = { "flatpak", "remote-add", "--user", "--no-gpg-verify",
                         repo_name2, repo_url, NULL };

  /* Add the repo we created above, which holds one collection ID per ref */
  run_test_subprocess ((char **) argv, RUN_TEST_SUBPROCESS_DEFAULT);

  inst = flatpak_installation_new_user (NULL, &error);
  g_assert_no_error (error);

  /* Ensure the remote can be successfully found */
  remote = flatpak_installation_get_remote_by_name (inst, repo_name2, NULL, &error);
  g_assert_no_error (error);
  g_assert_nonnull (remote);

  /* List the refs in the remote we've just added */
  refs1 = flatpak_installation_list_remote_refs_sync (inst, repo_name2, NULL, &error);

  g_assert_no_error (error);
  g_assert_nonnull (refs1);
  g_assert_true (refs1->len > 1);

  /* Listing from the remote only gets refs for the main collection id of the remote, and no collection ids */
  for (guint i = 0; i < refs1->len; ++i)
    {
      FlatpakRef *ref = g_ptr_array_index (refs1, i);
      const char *ref_spec = flatpak_ref_format_ref_cached (ref);
      const char *collection_id = flatpak_ref_get_collection_id (ref);

      /* There is no collection ref defined for the remote, so collection id is NULL */
      g_assert_null (collection_id);

      g_hash_table_add (ref_specs, (char *)ref_spec);
    }

  /* But listing by file: uri gives us all */
  repo_uri = flatpak_remote_get_url (remote);
  refs2 = flatpak_installation_list_remote_refs_sync (inst, repo_uri, NULL, &error);

  g_assert_no_error (error);
  g_assert_nonnull (refs2);
  g_assert_cmpuint (refs2->len, ==, 3 * refs1->len);

  for (guint i = 0; i < refs2->len; ++i)
    {
      FlatpakRef *ref = g_ptr_array_index (refs2, i);
      const char *ref_spec = flatpak_ref_format_ref_cached (ref);
      const char *collection_id = flatpak_ref_get_collection_id (ref);

      /* Directly listing a file:/ uri remote returns collection ids for all refs */
      g_assert_nonnull (collection_id);

      /* All the main 1 collection ids should have been recorded above */
      if (g_str_has_suffix (collection_id, "1"))
        g_assert_nonnull (g_hash_table_lookup (ref_specs, ref_spec));
      else
        g_assert_null (g_hash_table_lookup (ref_specs, ref_spec));
    }

  remove_remote_user ("multi-refs-repo");
}

static void
test_list_remote_refs (void)
{
  g_autoptr(FlatpakInstallation) inst = NULL;
  g_autoptr(GError) error = NULL;
  g_autoptr(GPtrArray) refs = NULL;
  int i;

  inst = flatpak_installation_new_user (NULL, &error);
  g_assert_no_error (error);

  refs = flatpak_installation_list_remote_refs_sync (inst, repo_name, NULL, &error);
  g_assert_no_error (error);
  g_assert_nonnull (refs);
  g_assert_cmpint (refs->len, >, 1);


  for (i = 0; i < refs->len; i++)
    {
      FlatpakRemoteRef *remote_ref = g_ptr_array_index (refs, i);
      FlatpakRef *ref = FLATPAK_REF (remote_ref);
      GBytes *metadata;
      g_autoptr(GBytes) metadata2 = NULL;
      g_autofree char *name = NULL;
      guint64 installed_size;
      guint64 download_size;
      g_autofree char *eol = NULL;
      g_autofree char *eol_rebase = NULL;

      g_assert_true (ref != NULL);

      if (strcmp ("org.test.Hello", flatpak_ref_get_name (ref)) == 0)
        {
          g_assert_cmpint (flatpak_ref_get_kind (ref), ==, FLATPAK_REF_KIND_APP);
        }
      else if (strcmp ("org.test.Hello.Locale", flatpak_ref_get_name (ref)) == 0 ||
               strcmp ("org.test.Hello.Plugin.fun", flatpak_ref_get_name (ref)) == 0)
        {
          g_assert_cmpint (flatpak_ref_get_kind (ref), ==, FLATPAK_REF_KIND_RUNTIME);
        }
      else
        {
          g_assert_cmpstr (flatpak_ref_get_name (ref), ==, "org.test.Platform");
          g_assert_cmpint (flatpak_ref_get_kind (ref), ==, FLATPAK_REF_KIND_RUNTIME);
        }

      if (strcmp ("org.test.Hello.Plugin.fun", flatpak_ref_get_name (ref)) == 0)
        g_assert_cmpstr (flatpak_ref_get_branch (ref), ==, "v1");
      else
        g_assert_cmpstr (flatpak_ref_get_branch (ref), ==, "master");

      g_assert_cmpstr (flatpak_ref_get_commit (ref), !=, NULL);
      g_assert_cmpstr (flatpak_ref_get_arch (ref), ==, flatpak_get_default_arch ());

      g_assert_cmpstr (flatpak_remote_ref_get_remote_name (remote_ref), ==, repo_name);
      g_assert_cmpstr (flatpak_remote_ref_get_eol (remote_ref), ==, NULL);
      g_assert_cmpstr (flatpak_remote_ref_get_eol_rebase (remote_ref), ==, NULL);

      g_assert_cmpuint (flatpak_remote_ref_get_installed_size (remote_ref), >, 0);
      g_assert_cmpuint (flatpak_remote_ref_get_download_size (remote_ref), >, 0);

      metadata = flatpak_remote_ref_get_metadata (remote_ref);
      g_assert_true (metadata != NULL);

      if (strcmp ("org.test.Hello", flatpak_ref_get_name (ref)) == 0)
        g_assert_true (g_str_has_prefix ((char *) g_bytes_get_data (metadata, NULL), "[Application]"));
      else
        g_assert_true (g_str_has_prefix ((char *) g_bytes_get_data (metadata, NULL), "[Runtime]"));

      g_object_get (ref,
                    "remote-name", &name,
                    "installed-size", &installed_size,
                    "download-size", &download_size,
                    "metadata", &metadata2,
                    "end-of-life", &eol,
                    "end-of-life-rebase", &eol_rebase,
                    NULL);

      g_assert_cmpstr (name, ==, repo_name);
      g_assert_cmpuint (installed_size, >, 0);
      g_assert_cmpuint (download_size, >, 0);
      g_assert_true (metadata2 == metadata);
      g_assert_null (eol);
      g_assert_null (eol_rebase);
    }
}

/* Test the xa.noenumerate option on a remote, which should mask non-installed refs */
static void
test_list_remote_refs_noenumerate (void)
{
  g_autoptr(FlatpakInstallation) inst = NULL;
  g_autoptr(GError) error = NULL;
  g_autoptr(GPtrArray) refs = NULL;
  g_autoptr(FlatpakRemote) remote = NULL;
  g_autoptr(FlatpakInstalledRef) runtime_ref = NULL;
  gboolean res;

  inst = flatpak_installation_new_user (NULL, &error);
  g_assert_no_error (error);

  empty_installation (inst);

  refs = flatpak_installation_list_remote_refs_sync (inst, repo_name, NULL, &error);
  g_assert_no_error (error);
  g_assert_nonnull (refs);
  g_assert_cmpint (refs->len, ==, 4);

  /* Install a runtime */
  G_GNUC_BEGIN_IGNORE_DEPRECATIONS
  runtime_ref = flatpak_installation_install (inst,
                                              repo_name,
                                              FLATPAK_REF_KIND_RUNTIME,
                                              "org.test.Platform",
                                              NULL, "master", NULL, NULL, NULL,
                                              &error);
  G_GNUC_END_IGNORE_DEPRECATIONS
  g_assert_no_error (error);
  g_assert_true (FLATPAK_IS_INSTALLED_REF (runtime_ref));

  /* Set xa.noenumerate=true */
  remote = flatpak_installation_get_remote_by_name (inst, repo_name, NULL, &error);
  g_assert_no_error (error);
  flatpak_remote_set_noenumerate (remote, TRUE);
  res = flatpak_installation_modify_remote (inst, remote, NULL, &error);
  g_assert_no_error (error);
  g_assert_true (res);

  /* Only the platform should be visible */
  g_clear_pointer (&refs, g_ptr_array_unref);
  refs = flatpak_installation_list_remote_refs_sync (inst, repo_name, NULL, &error);
  g_assert_no_error (error);
  g_assert_nonnull (refs);
  g_assert_cmpint (refs->len, ==, 1);

  empty_installation (inst);

  /* Set xa.noenumerate=false */
  flatpak_remote_set_noenumerate (remote, FALSE);
  res = flatpak_installation_modify_remote (inst, remote, NULL, &error);
  g_assert_no_error (error);
  g_assert_true (res);
}

static void
test_update_installed_ref_if_missing_runtime (void)
{
  g_autoptr(FlatpakInstallation) inst = NULL;
  g_autoptr(FlatpakTransaction) transaction = NULL;
  g_autoptr(GPtrArray) updatable_refs = NULL;
  g_autoptr(GError) error = NULL;
  FlatpakInstalledRef *iref = NULL;
  gboolean res;
  g_autofree char *app = NULL;

  app = g_strdup_printf ("app/org.test.Hello/%s/master",
                         flatpak_get_default_arch ());

  inst = flatpak_installation_new_user (NULL, &error);
  g_assert_no_error (error);
  g_assert_nonnull (inst);

  empty_installation (inst);

  /* Install the app */
  G_GNUC_BEGIN_IGNORE_DEPRECATIONS
  iref = flatpak_installation_install (inst,
                                       repo_name,
                                       FLATPAK_REF_KIND_APP,
                                       "org.test.Hello",
                                       flatpak_get_default_arch (),
                                       "master",
                                       NULL, NULL, NULL, &error);
  G_GNUC_END_IGNORE_DEPRECATIONS
  g_assert_no_error (error);
  g_assert_true (FLATPAK_IS_INSTALLED_REF (iref));
  g_clear_object (&iref);

  /* Install the Locale extension */
  G_GNUC_BEGIN_IGNORE_DEPRECATIONS
  iref = flatpak_installation_install (inst,
                                       repo_name,
                                       FLATPAK_REF_KIND_RUNTIME,
                                       "org.test.Hello.Locale",
                                       flatpak_get_default_arch (),
                                       "master",
                                       NULL, NULL, NULL, &error);
  G_GNUC_END_IGNORE_DEPRECATIONS
  g_assert_no_error (error);
  g_assert_true (FLATPAK_IS_INSTALLED_REF (iref));
  g_clear_object (&iref);

  updatable_refs = flatpak_installation_list_installed_refs_for_update (inst, NULL, &error);
  g_assert_cmpint (updatable_refs->len, ==, 1);
  iref = g_ptr_array_index (updatable_refs, 0);
  g_assert_cmpstr (flatpak_ref_get_name (FLATPAK_REF (iref)), ==, "org.test.Hello");
  iref = NULL;

  /* Prepare an update transaction to update org.test.Hello. The missing org.test.Platform
     runtime should automatically be installed with it. */
  transaction = flatpak_transaction_new_for_installation (inst, NULL, &error);
  g_assert_no_error (error);
  g_assert_nonnull (transaction);

  res = flatpak_transaction_add_update (transaction, app, NULL, NULL, &error);
  g_assert_no_error (error);
  g_assert_true (res);

  res = flatpak_transaction_run (transaction, NULL, &error);
  g_assert_no_error (error);
  g_assert_true (res);

  iref = flatpak_installation_get_installed_ref (inst, FLATPAK_REF_KIND_RUNTIME, "org.test.Platform", NULL, NULL, NULL, &error);
  g_assert_nonnull (iref);
  g_assert_no_error (error);
  g_clear_object (&iref);
}

static void
test_update_related_refs (void)
{
  g_autoptr(FlatpakInstallation) inst = NULL;
  g_autoptr(FlatpakTransaction) transaction = NULL;
  g_autoptr(GPtrArray) updatable_refs = NULL;
  g_autoptr(GPtrArray) related_refs = NULL;
  g_autoptr(GError) error = NULL;
  g_autoptr(FlatpakInstalledRef) iref = NULL;
  g_autoptr(FlatpakInstalledRef) runtime_ref = NULL;
  gboolean res;
  g_autofree char *app = NULL;
  g_autofree char *app_locale = NULL;
  const char * const *subpaths;

  app = g_strdup_printf ("app/org.test.Hello/%s/master",
                         flatpak_get_default_arch ());

  inst = flatpak_installation_new_user (NULL, &error);
  g_assert_no_error (error);
  g_assert_nonnull (inst);

  empty_installation (inst);

  /* Install a runtime */
  G_GNUC_BEGIN_IGNORE_DEPRECATIONS
  runtime_ref = flatpak_installation_install (inst,
                                              repo_name,
                                              FLATPAK_REF_KIND_RUNTIME,
                                              "org.test.Platform",
                                              NULL, "master", NULL, NULL, NULL,
                                              &error);
  G_GNUC_END_IGNORE_DEPRECATIONS
  g_assert_no_error (error);
  g_assert_true (FLATPAK_IS_INSTALLED_REF (runtime_ref));

  G_GNUC_BEGIN_IGNORE_DEPRECATIONS
  iref = flatpak_installation_install (inst,
                                       repo_name,
                                       FLATPAK_REF_KIND_APP,
                                       "org.test.Hello",
                                       NULL, "master", NULL, NULL, NULL,
                                       &error);
  G_GNUC_END_IGNORE_DEPRECATIONS
  g_assert_no_error (error);
  g_assert_true (FLATPAK_IS_INSTALLED_REF (iref));
  g_clear_object (&iref);

  /* We expect no installed related refs (i.e. org.test.Hello.Locale) at this point */
  related_refs = flatpak_installation_list_installed_related_refs_sync (inst, repo_name, app, NULL, &error);
  g_assert_cmpint (related_refs->len, ==, 0);

  updatable_refs = flatpak_installation_list_installed_refs_for_update (inst, NULL, &error);
  g_assert_no_error (error);
  g_assert_cmpint (updatable_refs->len, ==, 1);
  iref = g_ptr_array_index (updatable_refs, 0);
  g_assert_cmpstr (flatpak_ref_get_name (FLATPAK_REF (iref)), ==, "org.test.Hello");

  /* Prepare an update transaction to update org.test.Hello. The missing related .Locale
     extension should automatically be installed with it. */
  transaction = flatpak_transaction_new_for_installation (inst, NULL, &error);
  g_assert_no_error (error);
  g_assert_nonnull (transaction);

  res = flatpak_transaction_add_update (transaction, app, NULL, NULL, &error);
  g_assert_no_error (error);
  g_assert_true (res);

  res = flatpak_transaction_run (transaction, NULL, &error);
  g_assert_no_error (error);
  g_assert_true (res);

  iref = flatpak_installation_get_installed_ref (inst, FLATPAK_REF_KIND_RUNTIME, "org.test.Hello.Locale", NULL, NULL, NULL, &error);
  g_assert_nonnull (iref);
  g_assert_no_error (error);

  /* Now check that when we have only subpaths of the locale extension
   * installed and we change the configured languages, it shows as needing an
   * update.
   */
  subpaths = flatpak_installed_ref_get_subpaths (iref);
  g_assert_cmpint (g_strv_length ((char **) subpaths), ==, 1);
  g_assert_cmpstr (subpaths[0], ==, "/de");
  g_clear_object (&iref);

  configure_languages ("es");
  flatpak_installation_drop_caches (inst, NULL, &error);
  g_assert_no_error (error);

  g_clear_pointer (&updatable_refs, g_ptr_array_unref);
  updatable_refs = flatpak_installation_list_installed_refs_for_update (inst, NULL, &error);
  g_assert_no_error (error);
  g_assert_cmpint (updatable_refs->len, ==, 1);
  iref = g_ptr_array_index (updatable_refs, 0);
  g_assert_cmpstr (flatpak_ref_get_name (FLATPAK_REF (iref)), ==, "org.test.Hello.Locale");

  /* Now update org.test.Hello.Locale and check that the subpaths are updated. */
  g_clear_object (&transaction);
  transaction = flatpak_transaction_new_for_installation (inst, NULL, &error);
  g_assert_no_error (error);
  g_assert_nonnull (transaction);

  app_locale = g_strdup_printf ("runtime/org.test.Hello.Locale/%s/master",
                                flatpak_get_default_arch ());

  res = flatpak_transaction_add_update (transaction, app_locale, NULL, NULL, &error);
  g_assert_no_error (error);
  g_assert_true (res);

  res = flatpak_transaction_run (transaction, NULL, &error);
  g_assert_no_error (error);
  g_assert_true (res);

  flatpak_installation_drop_caches (inst, NULL, &error);
  g_assert_no_error (error);
  iref = flatpak_installation_get_installed_ref (inst, FLATPAK_REF_KIND_RUNTIME, "org.test.Hello.Locale", NULL, NULL, NULL, &error);
  g_assert_nonnull (iref);
  g_assert_no_error (error);

  subpaths = flatpak_installed_ref_get_subpaths (iref);
  g_assert_cmpint (g_strv_length ((char **) subpaths), ==, 2);
  g_assert_cmpstr (subpaths[0], ==, "/de");
  g_assert_cmpstr (subpaths[1], ==, "/es");

  /* Reset things */
  configure_languages ("de");
  empty_installation (inst);
}

static void
test_list_remote_related_refs (void)
{
  g_autoptr(FlatpakInstallation) inst = NULL;
  g_autoptr(GError) error = NULL;
  g_autoptr(GPtrArray) refs = NULL;
  FlatpakRelatedRef *ref;
  g_auto(GStrv) subpaths = NULL;
  gboolean should_download;
  gboolean should_delete;
  gboolean should_autoprune;
  g_autofree char *app = NULL;

  app = g_strdup_printf ("app/org.test.Hello/%s/master",
                         flatpak_get_default_arch ());
  inst = flatpak_installation_new_user (NULL, &error);
  g_assert_no_error (error);

  refs = flatpak_installation_list_remote_related_refs_sync (inst, repo_name, app, NULL, &error);
  g_assert_nonnull (refs);
  g_assert_no_error (error);

  g_assert_cmpint (refs->len, ==, 2);
  ref = g_ptr_array_index (refs, 0);

  g_assert_cmpstr (flatpak_ref_get_name (FLATPAK_REF (ref)), ==, "org.test.Hello.Locale");
  g_assert_true (flatpak_related_ref_should_download (ref));
  g_assert_true (flatpak_related_ref_should_delete (ref));
  g_assert_false (flatpak_related_ref_should_autoprune (ref));
  g_assert_true (g_strv_length ((char **) flatpak_related_ref_get_subpaths (ref)) == 1);
  g_assert_cmpstr (flatpak_related_ref_get_subpaths (ref)[0], ==, "/de");

  g_object_get (ref,
                "subpaths", &subpaths,
                "should-download", &should_download,
                "should-delete", &should_delete,
                "should-autoprune", &should_autoprune,
                NULL);

  g_assert_true (g_strv_length (subpaths) == 1);
  g_assert_cmpstr (subpaths[0], ==, "/de");
  g_assert_true (should_download);
  g_assert_true (should_delete);
  g_assert_false (should_autoprune);
  g_clear_pointer (&subpaths, g_strfreev);

  ref = g_ptr_array_index (refs, 1);
  g_assert_cmpstr (flatpak_ref_get_name (FLATPAK_REF (ref)), ==, "org.test.Hello.Plugin.fun");

  // Make the test with extra-languages, instead of languages
  clean_languages();
  configure_extra_languages();
  flatpak_installation_drop_caches (inst, NULL, &error);
  g_assert_no_error (error);

  g_clear_pointer (&refs, g_ptr_array_unref);
  refs = flatpak_installation_list_remote_related_refs_sync (inst, repo_name, app, NULL, &error);
  g_assert_nonnull (refs);
  g_assert_no_error (error);

  g_assert_cmpint (refs->len, ==, 2);
  ref = g_ptr_array_index (refs, 0);

  g_assert_cmpstr (flatpak_ref_get_name (FLATPAK_REF (ref)), ==, "org.test.Hello.Locale");
  g_assert_true (flatpak_related_ref_should_download (ref));
  g_assert_true (flatpak_related_ref_should_delete (ref));
  g_assert_false (flatpak_related_ref_should_autoprune (ref));
  g_assert_true (g_strv_length ((char **) flatpak_related_ref_get_subpaths (ref)) == 2);
  g_assert_cmpstr (flatpak_related_ref_get_subpaths (ref)[0], ==, "/de");
  g_assert_cmpstr (flatpak_related_ref_get_subpaths (ref)[1], ==, "/en");

  g_object_get (ref,
                "subpaths", &subpaths,
                "should-download", &should_download,
                "should-delete", &should_delete,
                "should-autoprune", &should_autoprune,
                NULL);

  g_assert_true (g_strv_length (subpaths) == 2);
  g_assert_cmpstr (subpaths[0], ==, "/de");
  g_assert_cmpstr (subpaths[1], ==, "/en");
  g_assert_true (should_download);
  g_assert_true (should_delete);
  g_assert_false (should_autoprune);

  ref = g_ptr_array_index (refs, 1);
  g_assert_cmpstr (flatpak_ref_get_name (FLATPAK_REF (ref)), ==, "org.test.Hello.Plugin.fun");

  configure_languages ("de");
  clean_extra_languages ();
}

static void
test_list_remote_related_refs_for_installed (void)
{
  g_autoptr(FlatpakInstallation) inst = NULL;
  g_autoptr(GError) error = NULL;
  g_autoptr(GPtrArray) refs = NULL;
  g_autoptr(FlatpakInstalledRef) iref = NULL;
  FlatpakRelatedRef *ref;
  g_autofree char *app = NULL;

  app = g_strdup_printf ("app/org.test.Hello/%s/master",
                         flatpak_get_default_arch ());
  inst = flatpak_installation_new_user (NULL, &error);
  g_assert_no_error (error);

  empty_installation (inst);

  G_GNUC_BEGIN_IGNORE_DEPRECATIONS
  iref = flatpak_installation_install (inst, repo_name, FLATPAK_REF_KIND_APP, "org.test.Hello", NULL, "master", NULL, NULL, NULL, &error);
  G_GNUC_END_IGNORE_DEPRECATIONS
  g_assert_no_error (error);
  g_assert_nonnull (iref);

  refs = flatpak_installation_list_remote_related_refs_for_installed_sync (inst, repo_name, app, NULL, &error);
  g_assert_nonnull (refs);
  g_assert_no_error (error);

  g_assert_cmpint (refs->len, ==, 2);
  ref = g_ptr_array_index (refs, 0);

  g_assert_cmpstr (flatpak_ref_get_name (FLATPAK_REF (ref)), ==, "org.test.Hello.Locale");

  ref = g_ptr_array_index (refs, 1);
  g_assert_cmpstr (flatpak_ref_get_name (FLATPAK_REF (ref)), ==, "org.test.Hello.Plugin.fun");
  g_assert_cmpstr (flatpak_ref_get_branch (FLATPAK_REF (ref)), ==, "v1");

  /* Update the app on the server so its extension version is v2 */
  update_test_app_extension_version ();
  update_repo ("test");
  flatpak_installation_drop_caches (inst, NULL, &error);
  g_assert_no_error (error);

  g_clear_pointer (&refs, g_ptr_array_unref);
  refs = flatpak_installation_list_remote_related_refs_for_installed_sync (inst, repo_name, app, NULL, &error);
  g_assert_nonnull (refs);
  g_assert_no_error (error);

  g_assert_cmpint (refs->len, ==, 2);
  ref = g_ptr_array_index (refs, 0);

  g_assert_cmpstr (flatpak_ref_get_name (FLATPAK_REF (ref)), ==, "org.test.Hello.Locale");

  /* The installed version needs v1 of the plugin even though v2 is available */
  ref = g_ptr_array_index (refs, 1);
  g_assert_cmpstr (flatpak_ref_get_name (FLATPAK_REF (ref)), ==, "org.test.Hello.Plugin.fun");
  g_assert_cmpstr (flatpak_ref_get_branch (FLATPAK_REF (ref)), ==, "v1");

  /* list_remote_related_refs_sync() should list only v2 since that's the only
   * version the remote app is compatible with
   */
  g_clear_pointer (&refs, g_ptr_array_unref);
  refs = flatpak_installation_list_remote_related_refs_sync (inst, repo_name, app, NULL, &error);
  g_assert_nonnull (refs);
  g_assert_no_error (error);

  g_assert_cmpint (refs->len, ==, 2);
  ref = g_ptr_array_index (refs, 0);

  g_assert_cmpstr (flatpak_ref_get_name (FLATPAK_REF (ref)), ==, "org.test.Hello.Locale");

  ref = g_ptr_array_index (refs, 1);
  g_assert_cmpstr (flatpak_ref_get_name (FLATPAK_REF (ref)), ==, "org.test.Hello.Plugin.fun");
  g_assert_cmpstr (flatpak_ref_get_branch (FLATPAK_REF (ref)), ==, "v2");

  /* Reset things */
  empty_installation (inst);
}

static void
progress_cb (const char *status,
             guint       progress,
             gboolean    estimating,
             gpointer    user_data)
{
  int *count = user_data;

  *count += 1;
}

static void
changed_cb (GFileMonitor     *monitor,
            GFile            *file,
            GFile            *other_file,
            GFileMonitorEvent event_type,
            gpointer          user_data)
{
  int *count = user_data;

  *count += 1;
}

static gboolean
timeout_cb (gpointer data)
{
  gboolean *timeout_reached = data;

  *timeout_reached = TRUE;
  return G_SOURCE_CONTINUE;
}

static gboolean
check_bwrap_support (void)
{
  g_autoptr(GError) error = NULL;
  const char *bwrap = g_getenv ("FLATPAK_BWRAP");

  if (bwrap != NULL)
    {
      gint exit_code = 0;
      char *argv[] = { (char *) bwrap, "--unshare-ipc", "--unshare-net",
                       "--unshare-pid", "--ro-bind", "/", "/", "/bin/true", NULL };
      g_autofree char *argv_str = g_strjoinv (" ", argv);
      g_test_message ("Spawning %s", argv_str);
      g_spawn_sync (NULL, argv, NULL, G_SPAWN_SEARCH_PATH, NULL, NULL, NULL, NULL, &exit_code, &error);
      g_assert_no_error (error);
      if (exit_code != 0)
        return FALSE;
    }

  return TRUE;
}

static void
test_install_launch_uninstall (void)
{
  g_autoptr(FlatpakInstallation) inst = NULL;
  g_autoptr(GFileMonitor) monitor = NULL;
  g_autoptr(GError) error = NULL;
  g_autoptr(FlatpakInstalledRef) ref = NULL;
  g_autoptr(FlatpakInstalledRef) runtime_ref = NULL;
  FlatpakInstalledRef *ref1 = NULL;
  GPtrArray *refs = NULL;
  int progress_count, changed_count;
  gboolean timeout_reached;
  guint timeout_id;
  gboolean res;

  if (!check_bwrap_support ())
    {
      g_test_skip ("bwrap not supported");
      return;
    }

  inst = flatpak_installation_new_user (NULL, &error);
  g_assert_no_error (error);

  monitor = flatpak_installation_create_monitor (inst, NULL, &error);
  g_assert_no_error (error);
  g_assert_true (G_IS_FILE_MONITOR (monitor));
  g_file_monitor_set_rate_limit (monitor, 100);

  g_signal_connect (monitor, "changed", G_CALLBACK (changed_cb), &changed_count);

  refs = flatpak_installation_list_installed_refs (inst, NULL, &error);
  g_assert_no_error (error);
  g_assert_cmpint (refs->len, ==, 0);
  g_ptr_array_unref (refs);

  changed_count = 0;
  progress_count = 0;
  timeout_reached = FALSE;
  G_GNUC_BEGIN_IGNORE_DEPRECATIONS
  ref = flatpak_installation_install (inst,
                                      repo_name,
                                      FLATPAK_REF_KIND_RUNTIME,
                                      "org.test.Platform",
                                      NULL,
                                      NULL,
                                      progress_cb,
                                      &progress_count,
                                      NULL,
                                      &error);
  G_GNUC_END_IGNORE_DEPRECATIONS
  g_assert_no_error (error);
  g_assert_true (FLATPAK_IS_INSTALLED_REF (ref));
  g_assert_cmpint (progress_count, >, 0);

  timeout_id = g_timeout_add (20000, timeout_cb, &timeout_reached);
  while (!timeout_reached && changed_count == 0)
    g_main_context_iteration (NULL, TRUE);
  g_source_remove (timeout_id);

  g_assert_cmpint (changed_count, >, 0);

  g_assert_cmpstr (flatpak_ref_get_name (FLATPAK_REF (ref)), ==, "org.test.Platform");
  g_assert_cmpstr (flatpak_ref_get_arch (FLATPAK_REF (ref)), ==, flatpak_get_default_arch ());
  g_assert_cmpstr (flatpak_ref_get_branch (FLATPAK_REF (ref)), ==, "master");
  g_assert_cmpint (flatpak_ref_get_kind (FLATPAK_REF (ref)), ==, FLATPAK_REF_KIND_RUNTIME);
  g_assert_cmpstr (flatpak_ref_get_collection_id (FLATPAK_REF (ref)), ==, repo_collection_id);

  g_assert_cmpuint (flatpak_installed_ref_get_installed_size (ref), >, 0);

  refs = flatpak_installation_list_installed_refs (inst, NULL, &error);
  g_assert_no_error (error);
  g_assert_cmpint (refs->len, ==, 1);

  ref1 = g_ptr_array_index (refs, 0);
  g_assert_cmpstr (flatpak_ref_get_commit (FLATPAK_REF (ref1)), ==, flatpak_ref_get_commit (FLATPAK_REF (ref)));

  assert_cmpstr_free_both (flatpak_ref_format_ref (FLATPAK_REF (ref)), ==,
                           flatpak_ref_format_ref (FLATPAK_REF (ref1)));
  g_ptr_array_unref (refs);

  runtime_ref = g_object_ref (ref);
  g_clear_object (&ref);

  changed_count = 0;
  progress_count = 0;
  timeout_reached = FALSE;
  G_GNUC_BEGIN_IGNORE_DEPRECATIONS
  ref = flatpak_installation_install (inst,
                                      repo_name,
                                      FLATPAK_REF_KIND_APP,
                                      "org.test.Hello",
                                      NULL,
                                      NULL,
                                      progress_cb,
                                      &progress_count,
                                      NULL,
                                      &error);
  G_GNUC_END_IGNORE_DEPRECATIONS
  g_assert_no_error (error);
  g_assert_true (FLATPAK_IS_INSTALLED_REF (ref));
  g_assert_cmpint (progress_count, >, 0);

  timeout_id = g_timeout_add (20000, timeout_cb, &timeout_reached);
  while (!timeout_reached && changed_count == 0)
    g_main_context_iteration (NULL, TRUE);
  g_source_remove (timeout_id);

  g_assert_cmpint (changed_count, >, 0);

  g_assert_cmpstr (flatpak_ref_get_name (FLATPAK_REF (ref)), ==, "org.test.Hello");
  g_assert_cmpstr (flatpak_ref_get_arch (FLATPAK_REF (ref)), ==, flatpak_get_default_arch ());
  g_assert_cmpstr (flatpak_ref_get_branch (FLATPAK_REF (ref)), ==, "master");
  g_assert_cmpint (flatpak_ref_get_kind (FLATPAK_REF (ref)), ==, FLATPAK_REF_KIND_APP);
  g_assert_cmpstr (flatpak_ref_get_collection_id (FLATPAK_REF (ref)), ==, repo_collection_id);

  g_assert_cmpuint (flatpak_installed_ref_get_installed_size (ref), >, 0);
  g_assert_true (flatpak_installed_ref_get_is_current (ref));

  refs = flatpak_installation_list_installed_refs (inst, NULL, &error);
  g_assert_no_error (error);
  g_assert_cmpint (refs->len, ==, 2);

  g_ptr_array_unref (refs);

  /* first test an error */
  {
    TESTS_SCOPED_STDOUT_TO_STDERR;
    res = flatpak_installation_launch (inst, "org.test.Hellooo", NULL, NULL, NULL, NULL, &error);
  }
  g_assert_error (error, FLATPAK_ERROR, FLATPAK_ERROR_NOT_INSTALLED);
  g_assert_false (res);
  g_clear_error (&error);

  /* now launch the right thing */
  {
    TESTS_SCOPED_STDOUT_TO_STDERR;
    res = flatpak_installation_launch (inst, "org.test.Hello", NULL, NULL, NULL, NULL, &error);
  }
  g_assert_no_error (error);
  g_assert_true (res);

  timeout_reached = FALSE;
  timeout_id = g_timeout_add (500, timeout_cb, &timeout_reached);
  while (!timeout_reached)
    g_main_context_iteration (NULL, TRUE);
  g_source_remove (timeout_id);

  changed_count = 0;
  progress_count = 0;
  G_GNUC_BEGIN_IGNORE_DEPRECATIONS
  res = flatpak_installation_uninstall (inst,
                                        flatpak_ref_get_kind (FLATPAK_REF (ref)),
                                        flatpak_ref_get_name (FLATPAK_REF (ref)),
                                        flatpak_ref_get_arch (FLATPAK_REF (ref)),
                                        flatpak_ref_get_branch (FLATPAK_REF (ref)),
                                        progress_cb,
                                        &progress_count,
                                        NULL,
                                        &error);
  G_GNUC_END_IGNORE_DEPRECATIONS
  g_assert_no_error (error);
  g_assert_true (res);
  //FIXME: no progress for uninstall
  //g_assert_cmpint (progress_count, >, 0);

  timeout_reached = FALSE;
  timeout_id = g_timeout_add (500, timeout_cb, &timeout_reached);
  while (!timeout_reached && changed_count == 0)
    g_main_context_iteration (NULL, TRUE);
  g_source_remove (timeout_id);

  refs = flatpak_installation_list_installed_refs (inst, NULL, &error);
  g_assert_no_error (error);
  g_assert_cmpint (refs->len, ==, 1);

  g_ptr_array_unref (refs);

  changed_count = 0;
  progress_count = 0;
  G_GNUC_BEGIN_IGNORE_DEPRECATIONS
  res = flatpak_installation_uninstall (inst,
                                        flatpak_ref_get_kind (FLATPAK_REF (runtime_ref)),
                                        flatpak_ref_get_name (FLATPAK_REF (runtime_ref)),
                                        flatpak_ref_get_arch (FLATPAK_REF (runtime_ref)),
                                        flatpak_ref_get_branch (FLATPAK_REF (runtime_ref)),
                                        progress_cb,
                                        &progress_count,
                                        NULL,
                                        &error);
  G_GNUC_END_IGNORE_DEPRECATIONS
  g_assert_no_error (error);
  g_assert_true (res);
  //FIXME: no progress for uninstall
  //g_assert_cmpint (progress_count, >, 0);

  timeout_reached = FALSE;
  timeout_id = g_timeout_add (500, timeout_cb, &timeout_reached);
  while (!timeout_reached && changed_count == 0)
    g_main_context_iteration (NULL, TRUE);
  g_source_remove (timeout_id);

  refs = flatpak_installation_list_installed_refs (inst, NULL, &error);
  g_assert_no_error (error);
  g_assert_cmpint (refs->len, ==, 0);

  g_ptr_array_unref (refs);
}

static const char *
flatpak_deploy_data_get_origin (GVariant *deploy_data)
{
  const char *origin;

  g_variant_get_child (deploy_data, 0, "&s", &origin);
  return origin;
}

static const char *
flatpak_deploy_data_get_commit (GVariant *deploy_data)
{
  const char *commit;

  g_variant_get_child (deploy_data, 1, "&s", &commit);
  return commit;
}

static const char *
flatpak_deploy_data_get_runtime (GVariant *deploy_data)
{
  g_autoptr(GVariant) metadata = g_variant_get_child_value (deploy_data, 4);
  const char *runtime = NULL;

  g_variant_lookup (metadata, "runtime", "&s", &runtime);

  return runtime;
}

/**
 * flatpak_deploy_data_get_subpaths:
 *
 * Returns: (array length=length zero-terminated=1) (transfer container): an array of constant strings
 **/
static const char **
flatpak_deploy_data_get_subpaths (GVariant *deploy_data)
{
  const char **subpaths;

  g_variant_get_child (deploy_data, 2, "^a&s", &subpaths);
  return subpaths;
}

static guint64
flatpak_deploy_data_get_installed_size (GVariant *deploy_data)
{
  guint64 size;

  g_variant_get_child (deploy_data, 3, "t", &size);
  return GUINT64_FROM_BE (size);
}

static GVariant *
flatpak_dir_new_deploy_data (const char *origin,
                             const char *commit,
                             char      **subpaths,
                             guint64     installed_size,
                             GVariant   *metadata)
{
  char *empty_subpaths[] = {NULL};
  GVariantBuilder builder;

  if (metadata == NULL)
    {
      g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sv}"));
      metadata = g_variant_builder_end (&builder);
    }

  return g_variant_ref_sink (g_variant_new ("(ss^ast@a{sv})",
                                            origin,
                                            commit,
                                            subpaths ? subpaths : empty_subpaths,
                                            GUINT64_TO_BE (installed_size),
                                            metadata));
}

#define FLATPAK_DEPLOY_DATA_GVARIANT_STRING "(ssasta{sv})"
#define FLATPAK_DEPLOY_DATA_GVARIANT_FORMAT G_VARIANT_TYPE (FLATPAK_DEPLOY_DATA_GVARIANT_STRING)

static GVariant *
flatpak_load_deploy_data (GFile        *deploy_dir)
{
  g_autoptr(GFile) data_file = NULL;
  g_autoptr(GError) error = NULL;
  char *data = NULL;
  gsize data_size;

  data_file = g_file_get_child (deploy_dir, "deploy");
  g_file_load_contents (data_file, NULL, &data, &data_size, NULL, &error);
  g_assert_no_error (error);

  return g_variant_ref_sink (g_variant_new_from_data (FLATPAK_DEPLOY_DATA_GVARIANT_FORMAT,
                                                      data, data_size,
                                                      FALSE, g_free, data));
}

static gboolean
flatpak_variant_save (GFile        *dest,
                      GVariant     *variant,
                      GCancellable *cancellable,
                      GError      **error)
{
  g_autoptr(GOutputStream) out = NULL;
  gsize bytes_written;

  out = (GOutputStream *) g_file_replace (dest, NULL, FALSE,
                                          G_FILE_CREATE_REPLACE_DESTINATION,
                                          cancellable, error);
  if (out == NULL)
    return FALSE;

  if (!g_output_stream_write_all (out,
                                  g_variant_get_data (variant),
                                  g_variant_get_size (variant),
                                  &bytes_written,
                                  cancellable,
                                  error))
    return FALSE;

  if (!g_output_stream_close (out, cancellable, error))
    return FALSE;

  return TRUE;
}

static void
mangle_deploy_file (FlatpakInstalledRef *ref)
{
  g_autoptr(GFile) dir = NULL;
  g_autoptr(GVariant) data = NULL;
  g_autoptr(GVariant) new_data = NULL;
  g_autoptr(GFile) deploy_data_file = NULL;
  GVariantBuilder metadata_builder;
  g_autoptr(GError) error = NULL;
  const char * const previous_ids[] = { "net.example.Goodbye", NULL };
  g_autofree const char **subpaths = NULL;

  dir = g_file_new_for_path (flatpak_installed_ref_get_deploy_dir (ref));
  data = flatpak_load_deploy_data (dir);

  g_variant_builder_init (&metadata_builder, G_VARIANT_TYPE ("a{sv}"));
  g_variant_builder_add (&metadata_builder, "{s@v}", "runtime",
                         g_variant_new_variant (g_variant_new_string (flatpak_deploy_data_get_runtime (data))));
  g_variant_builder_add (&metadata_builder, "{s@v}", "previous-ids",
                         g_variant_new_variant (g_variant_new_strv (previous_ids, -1)));

  subpaths = flatpak_deploy_data_get_subpaths (data);
  new_data = flatpak_dir_new_deploy_data (flatpak_deploy_data_get_origin (data),
                                          flatpak_deploy_data_get_commit (data),
                                          (char **) subpaths,
                                          flatpak_deploy_data_get_installed_size (data),
                                          g_variant_builder_end (&metadata_builder));

  deploy_data_file = g_file_get_child (dir, "deploy");
  flatpak_variant_save (deploy_data_file, new_data, NULL, &error);
  g_assert_no_error (error);
}

static void
check_desktop_file (FlatpakInstalledRef *ref,
                    const char          *file,
                    const char          *expected_renamed_from)
{
  g_autofree char *path = g_build_path (G_DIR_SEPARATOR_S,
                                        flatpak_installed_ref_get_deploy_dir (ref),
                                        "export",
                                        "share",
                                        "applications",
                                        file,
                                        NULL);
  g_autoptr(GKeyFile) kf = g_key_file_new ();
  g_autofree char *renamed_from = NULL;
  g_autoptr(GError) error = NULL;

  g_key_file_load_from_file (kf, path, G_KEY_FILE_NONE, &error);
  g_assert_no_error (error);

  renamed_from = g_key_file_get_value (kf,
                                       G_KEY_FILE_DESKTOP_GROUP,
                                       "X-Flatpak-RenamedFrom",
                                       &error);
  g_assert_no_error (error);
  g_assert_cmpstr (renamed_from, ==, expected_renamed_from);
}

static void
test_list_updates (void)
{
  g_autoptr(FlatpakInstallation) inst = NULL;
  g_autoptr(FlatpakTransaction) transaction = NULL;
  g_autoptr(GError) error = NULL;
  g_autoptr(FlatpakInstalledRef) ref = NULL;
  g_autoptr(GPtrArray) refs = NULL;
  FlatpakInstalledRef *update_ref = NULL;
  g_autoptr(FlatpakInstalledRef) updated_ref = NULL;
  g_autofree gchar *app = NULL;
  gboolean res;

  app = g_strdup_printf ("app/org.test.Hello/%s/master",
                         flatpak_get_default_arch ());

  inst = flatpak_installation_new_user (NULL, &error);
  g_assert_no_error (error);

  empty_installation (inst);

  transaction = flatpak_transaction_new_for_installation (inst, NULL, &error);
  g_assert_no_error (error);
  g_assert_nonnull (transaction);

  /* install org.test.Hello, and have org.test.Hello.Locale and org.test.Platform
   * added as deps/related
   */
  res = flatpak_transaction_add_install (transaction, repo_name, app, NULL, &error);
  g_assert_no_error (error);
  g_assert_true (res);

  res = flatpak_transaction_run (transaction, NULL, &error);
  g_assert_no_error (error);
  g_assert_true (res);
  g_clear_object (&transaction);

  refs = flatpak_installation_list_installed_refs (inst, NULL, &error);
  g_assert_no_error (error);
  g_assert_nonnull (refs);
  g_assert_cmpint (refs->len, ==, 3);
  g_clear_pointer (&refs, g_ptr_array_unref);

  ref = flatpak_installation_get_installed_ref (inst,
                                                FLATPAK_REF_KIND_APP,
                                                "org.test.Hello",
                                                flatpak_get_default_arch (),
                                                "master", NULL, &error);
  g_assert_nonnull (ref);
  g_assert_no_error (error);

  /* Add a previous-id to the deploy file */
  mangle_deploy_file (ref);

  /* Update the test app and the runtime and list the updates */
  update_test_app ();
  update_test_runtime ();
  update_repo ("test");

  /* Drop all in-memory summary caches so we can find the new update */
  flatpak_installation_drop_caches (inst, NULL, &error);
  g_assert_no_error (error);

  refs = flatpak_installation_list_installed_refs_for_update (inst, NULL, &error);
  g_assert_no_error (error);
  g_assert_nonnull (refs);
  g_assert_cmpint (refs->len, ==, 3);
  update_ref = g_ptr_array_index (refs, 0);
  g_assert_cmpstr (flatpak_ref_get_name (FLATPAK_REF (update_ref)), ==, "org.test.Hello");
  g_assert_cmpint (flatpak_ref_get_kind (FLATPAK_REF (update_ref)), ==, FLATPAK_REF_KIND_APP);
  update_ref = g_ptr_array_index (refs, 1);
  g_assert_cmpstr (flatpak_ref_get_name (FLATPAK_REF (update_ref)), ==, "org.test.Hello.Locale");
  g_assert_cmpint (flatpak_ref_get_kind (FLATPAK_REF (update_ref)), ==, FLATPAK_REF_KIND_RUNTIME);
  update_ref = g_ptr_array_index (refs, 2);
  g_assert_cmpstr (flatpak_ref_get_name (FLATPAK_REF (update_ref)), ==, "org.test.Platform");
  g_assert_cmpint (flatpak_ref_get_kind (FLATPAK_REF (update_ref)), ==, FLATPAK_REF_KIND_RUNTIME);

  /* Install the app update */
  G_GNUC_BEGIN_IGNORE_DEPRECATIONS
  updated_ref = flatpak_installation_update (inst,
                                             FLATPAK_UPDATE_FLAGS_NONE,
                                             FLATPAK_REF_KIND_APP,
                                             "org.test.Hello",
                                             flatpak_get_default_arch (), "master",
                                             NULL, NULL, NULL, &error);
  G_GNUC_END_IGNORE_DEPRECATIONS
  g_assert_no_error (error);
  g_assert_true (FLATPAK_IS_INSTALLED_REF (updated_ref));

  check_desktop_file (updated_ref,
                      "org.test.Hello.desktop",
                      "net.example.Goodbye.desktop;");
  check_desktop_file (updated_ref,
                      "org.test.Hello.Again.desktop",
                      "hello-again.desktop;net.example.Goodbye.Again.desktop;");

  /* Uninstall the runtime and app */
  empty_installation (inst);
}

static void
test_list_undeployed_updates (void)
{
  g_autoptr(FlatpakInstallation) inst = NULL;
  g_autoptr(FlatpakTransaction) transaction = NULL;
  g_autoptr(GError) error = NULL;
  g_autoptr(GPtrArray) refs = NULL;
  FlatpakInstalledRef *update_ref = NULL;
  g_autoptr(FlatpakInstalledRef) updated_ref = NULL;
  g_autofree gchar *app = NULL;
  gboolean res;

  app = g_strdup_printf ("app/org.test.Hello/%s/master",
                         flatpak_get_default_arch ());

  inst = flatpak_installation_new_user (NULL, &error);
  g_assert_no_error (error);

  empty_installation (inst);

  transaction = flatpak_transaction_new_for_installation (inst, NULL, &error);
  g_assert_no_error (error);
  g_assert_nonnull (transaction);

  /* install org.test.Hello, and have org.test.Hello.Locale and org.test.Platform
   * added as deps/related
   */
  res = flatpak_transaction_add_install (transaction, repo_name, app, NULL, &error);
  g_assert_no_error (error);
  g_assert_true (res);

  res = flatpak_transaction_run (transaction, NULL, &error);
  g_assert_no_error (error);
  g_assert_true (res);
  g_clear_object (&transaction);

  refs = flatpak_installation_list_installed_refs (inst, NULL, &error);
  g_assert_no_error (error);
  g_assert_nonnull (refs);
  g_assert_cmpint (refs->len, ==, 3);
  g_clear_pointer (&refs, g_ptr_array_unref);

  update_test_app ();
  update_repo ("test");

  /* Drop all in-memory summary caches so we can find the new update */
  flatpak_installation_drop_caches (inst, NULL, &error);
  g_assert_no_error (error);

  /* Install the app update but don't deploy it */
  G_GNUC_BEGIN_IGNORE_DEPRECATIONS
  updated_ref = flatpak_installation_update (inst,
                                             FLATPAK_UPDATE_FLAGS_NO_DEPLOY,
                                             FLATPAK_REF_KIND_APP,
                                             "org.test.Hello",
                                             flatpak_get_default_arch (), "master",
                                             NULL, NULL, NULL, &error);
  G_GNUC_END_IGNORE_DEPRECATIONS
  g_assert_no_error (error);
  g_assert_true (FLATPAK_IS_INSTALLED_REF (updated_ref));

  refs = flatpak_installation_list_installed_refs_for_update (inst, NULL, &error);
  g_assert_no_error (error);
  g_assert_nonnull (refs);
  g_assert_cmpint (refs->len, ==, 2);
  update_ref = g_ptr_array_index (refs, 0);
  g_assert_cmpstr (flatpak_ref_get_name (FLATPAK_REF (update_ref)), ==, "org.test.Hello");
  g_assert_cmpint (flatpak_ref_get_kind (FLATPAK_REF (update_ref)), ==, FLATPAK_REF_KIND_APP);
  update_ref = g_ptr_array_index (refs, 1);
  g_assert_cmpstr (flatpak_ref_get_name (FLATPAK_REF (update_ref)), ==, "org.test.Hello.Locale");
  g_assert_cmpint (flatpak_ref_get_kind (FLATPAK_REF (update_ref)), ==, FLATPAK_REF_KIND_RUNTIME);

  /* Uninstall the runtime and app */
  empty_installation (inst);
}

static void
test_list_rename_updates (void)
{
  g_autoptr(FlatpakInstallation) inst = NULL;
  g_autoptr(FlatpakTransaction) transaction = NULL;
  g_autoptr(GError) error = NULL;
  g_autoptr(GPtrArray) refs = NULL;
  FlatpakInstalledRef *update_ref = NULL;
  g_autofree gchar *app = NULL;
  gboolean res;

  app = g_strdup_printf ("app/org.test.Hello/%s/master",
                         flatpak_get_default_arch ());

  inst = flatpak_installation_new_user (NULL, &error);
  g_assert_no_error (error);

  empty_installation (inst);

  /* Rename the app on the server before installing it. This will follow a
   * different code path than if we the installed commit is older than the
   * commit with the eol-rebase metadata.
   */
  rename_test_app ("test");

  transaction = flatpak_transaction_new_for_installation (inst, NULL, &error);
  g_assert_no_error (error);
  g_assert_nonnull (transaction);

  /* install org.test.Hello, and have org.test.Hello.Locale and org.test.Platform
   * added as deps/related
   */
  res = flatpak_transaction_add_install (transaction, repo_name, app, NULL, &error);
  g_assert_no_error (error);
  g_assert_true (res);

  res = flatpak_transaction_run (transaction, NULL, &error);
  g_assert_no_error (error);
  g_assert_true (res);
  g_clear_object (&transaction);

  refs = flatpak_installation_list_installed_refs (inst, NULL, &error);
  g_assert_no_error (error);
  g_assert_nonnull (refs);
  g_assert_cmpint (refs->len, ==, 3);
  g_clear_pointer (&refs, g_ptr_array_unref);

  /* Check that the app shows as updatable */
  refs = flatpak_installation_list_installed_refs_for_update (inst, NULL, &error);
  g_assert_no_error (error);
  g_assert_nonnull (refs);
  g_assert_cmpint (refs->len, ==, 2);
  update_ref = g_ptr_array_index (refs, 0);
  g_assert_cmpstr (flatpak_ref_get_name (FLATPAK_REF (update_ref)), ==, "org.test.Hello");
  g_assert_cmpint (flatpak_ref_get_kind (FLATPAK_REF (update_ref)), ==, FLATPAK_REF_KIND_APP);
  update_ref = g_ptr_array_index (refs, 1);
  g_assert_cmpstr (flatpak_ref_get_name (FLATPAK_REF (update_ref)), ==, "org.test.Hello.Locale");
  g_assert_cmpint (flatpak_ref_get_kind (FLATPAK_REF (update_ref)), ==, FLATPAK_REF_KIND_RUNTIME);

  /* Uninstall the runtime and app */
  empty_installation (inst);

  /* Undo the rename for the benefit of future tests */
  make_test_app ("test");
  update_repo ("test");
}

static void
test_list_updates_offline (void)
{
  g_autoptr(FlatpakInstallation) inst = NULL;
  g_autoptr(GError) error = NULL;
  g_autoptr(GPtrArray) refs = NULL;
  g_autoptr(FlatpakInstalledRef) runtime_ref = NULL;
  g_autoptr(FlatpakRemote) remote = NULL;
  gboolean res;
  g_autofree char *saved_url = NULL;
  g_autofree char *wrong_url = NULL;

  inst = flatpak_installation_new_user (NULL, &error);
  g_assert_no_error (error);
  g_assert_nonnull (inst);

  /* Install a runtime */
  G_GNUC_BEGIN_IGNORE_DEPRECATIONS
  runtime_ref = flatpak_installation_install (inst,
                                              repo_name,
                                              FLATPAK_REF_KIND_RUNTIME,
                                              "org.test.Platform",
                                              NULL, NULL, NULL, NULL, NULL,
                                              &error);
  G_GNUC_END_IGNORE_DEPRECATIONS
  g_assert_no_error (error);
  g_assert_true (FLATPAK_IS_INSTALLED_REF (runtime_ref));

  /* Note: here we could create an update for the runtime, but it won't be
   * found anyway since the URL will be wrong.
   */

  /* Make the URL wrong to simulate being offline */
  remote = flatpak_installation_get_remote_by_name (inst, repo_name, NULL, &error);
  g_assert_no_error (error);
  g_assert_nonnull (remote);
  saved_url = flatpak_remote_get_url (remote);
  wrong_url = g_strdup_printf ("http://127.0.0.1:%s/nonexistent", httpd_port);
  flatpak_remote_set_url (remote, wrong_url);
  res = flatpak_installation_modify_remote (inst, remote, NULL, &error);
  g_assert_no_error (error);
  g_assert_true (res);

  /* Listing updates offline should return an empty array */
  refs = flatpak_installation_list_installed_refs_for_update (inst, NULL, &error);
  g_assert_no_error (error);
  g_assert_nonnull (refs);
  g_assert_cmpint (refs->len, ==, 0);

  /* Restore the correct URL to the remote */
  flatpak_remote_set_url (remote, saved_url);
  res = flatpak_installation_modify_remote (inst, remote, NULL, &error);
  g_assert_no_error (error);
  g_assert_true (res);

  /* Uninstall the runtime */
  G_GNUC_BEGIN_IGNORE_DEPRECATIONS
  res = flatpak_installation_uninstall (inst,
                                        flatpak_ref_get_kind (FLATPAK_REF (runtime_ref)),
                                        flatpak_ref_get_name (FLATPAK_REF (runtime_ref)),
                                        flatpak_ref_get_arch (FLATPAK_REF (runtime_ref)),
                                        flatpak_ref_get_branch (FLATPAK_REF (runtime_ref)),
                                        NULL, NULL, NULL,
                                        &error);
  G_GNUC_END_IGNORE_DEPRECATIONS
  g_assert_no_error (error);
  g_assert_true (res);
}

static void
run_test_subprocess (char                 **argv,
                     RunTestSubprocessFlags flags)
{
  int status;
  g_autoptr(GError) error = NULL;
  g_autofree char *argv_str = g_strjoinv (" ", argv);
  g_autofree char *output = NULL;
  g_autofree char *errors = NULL;

  g_test_message ("Spawning %s", argv_str);

  if (flags & RUN_TEST_SUBPROCESS_NO_CAPTURE)
    g_spawn_sync (NULL, argv, NULL, G_SPAWN_SEARCH_PATH | G_SPAWN_STDOUT_TO_DEV_NULL, NULL, NULL, NULL, NULL, &status, &error);
  else
    g_spawn_sync (NULL, argv, NULL, G_SPAWN_SEARCH_PATH, NULL, NULL, &output, &errors, &status, &error);

  g_assert_no_error (error);

  if (output != NULL && output[0] != '\0')
    {
      g_autofree char *escaped = g_strescape (output, NULL);

      g_test_message ("\"%s\" stdout: %s", argv_str, escaped);
    }

  if (errors != NULL && errors[0] != '\0')
    {
      g_autofree char *escaped = g_strescape (errors, NULL);

      g_test_message ("\"%s\" stderr: %s", argv_str, escaped);
    }

  g_test_message ("\"%s\" wait status: %d", argv_str, status);

  if (WIFEXITED (status))
    g_test_message ("\"%s\" exited %d", argv_str, WEXITSTATUS (status));

  if (WIFSIGNALED (status))
    g_test_message ("\"%s\" killed by signal %d", argv_str, WTERMSIG (status));

  if (g_spawn_check_exit_status (status, &error))
    return;
  else if (flags & RUN_TEST_SUBPROCESS_IGNORE_FAILURE)
    g_test_message ("\"%s\" failed: %s", argv_str, error->message);
  else
    g_assert_no_error (error);
}

static void
make_bundle (void)
{
  g_autofree char *repo_url = g_strdup_printf ("http://127.0.0.1:%s/test", httpd_port);
  g_autofree char *arg2 = g_strdup_printf ("--repo-url=%s", repo_url);
  g_autofree char *path = g_build_filename (testdir, "bundles", NULL);
  g_autofree char *file = g_build_filename (path, "hello.flatpak", NULL);
  char *argv[] = { "flatpak", "build-bundle", "repo-url", "repos/test", "filename", "org.test.Hello", NULL };

  argv[2] = arg2;
  argv[4] = file;

  g_info ("Making dir %s", path);
  g_mkdir_with_parents (path, S_IRWXU | S_IRWXG | S_IRWXO);

  run_test_subprocess (argv, RUN_TEST_SUBPROCESS_DEFAULT);
}

static void
make_test_runtime (const char *runtime_repo_name)
{
  g_autofree char *arg0 = NULL;
  g_autofree char *arg1 = NULL;
  char *argv[] = {
    NULL, NULL, "org.test.Platform", "master", "", "", NULL
  };

  arg0 = g_test_build_filename (G_TEST_DIST, "make-test-runtime.sh", NULL);
  arg1 = g_strdup_printf ("repos/%s", runtime_repo_name);
  argv[0] = arg0;
  argv[1] = arg1;
  argv[4] = repo_collection_id;

  run_test_subprocess (argv, RUN_TEST_SUBPROCESS_DEFAULT);
}

static void
make_test_app (const char *app_repo_name)
{
  g_autofree char *arg0 = NULL;
  g_autofree char *arg1 = NULL;
  char *argv[] = { NULL, NULL, "", "master", "", NULL };

  arg0 = g_test_build_filename (G_TEST_DIST, "make-test-app.sh", NULL);
  arg1 = g_strdup_printf ("repos/%s", app_repo_name);
  argv[0] = arg0;
  argv[1] = arg1;
  argv[4] = repo_collection_id;

  run_test_subprocess (argv, RUN_TEST_SUBPROCESS_DEFAULT);
}

static void
update_test_app (void)
{
  g_autofree char *arg0 = NULL;
  char *argv[] = { NULL, "repos/test", "", "master", "", "SPIN", NULL };

  arg0 = g_test_build_filename (G_TEST_DIST, "make-test-app.sh", NULL);
  argv[0] = arg0;
  argv[4] = repo_collection_id;

  run_test_subprocess (argv, RUN_TEST_SUBPROCESS_DEFAULT);
}

static void
update_test_app_extension_version (void)
{
  g_autofree char *arg0 = NULL;
  char *argv[] = { NULL, "repos/test", "", "master", "", "EXTENSIONS", NULL };

  arg0 = g_test_build_filename (G_TEST_DIST, "make-test-app.sh", NULL);
  argv[0] = arg0;
  argv[4] = repo_collection_id;

  run_test_subprocess (argv, RUN_TEST_SUBPROCESS_DEFAULT);
}

static void
rename_test_app (const char *update_repo_name)
{
  g_autofree char *arg5 = NULL;
  g_autofree char *arg6 = NULL;
  g_autofree char *app_ref = NULL;
  g_autofree char *app_locale_ref = NULL;
  char *argv[] = { "flatpak", "build-commit-from", "--gpg-homedir=", "--gpg-sign=",
                   "--end-of-life-rebase=org.test.Hello=org.test.Hello2",
                   "--src-repo=",
                   NULL, NULL, NULL, NULL };
  g_auto(GStrv) gpgargs = NULL;

  gpgargs = g_strsplit (gpg_args, " ", 0);
  arg5 = g_strdup_printf ("--src-repo=repos/%s", update_repo_name);
  arg6 = g_strdup_printf ("repos/%s", update_repo_name);
  app_ref = g_strdup_printf ("app/org.test.Hello/%s/master",
                             flatpak_get_default_arch ());
  app_locale_ref = g_strdup_printf ("runtime/org.test.Hello.Locale/%s/master",
                                    flatpak_get_default_arch ());
  argv[2] = gpgargs[0];
  argv[3] = gpgargs[1];
  argv[5] = arg5;
  argv[6] = arg6;
  argv[7] = app_ref;
  argv[8] = app_locale_ref;

  run_test_subprocess (argv, RUN_TEST_SUBPROCESS_DEFAULT);
}

static void
update_test_app_extension (void)
{
  g_autofree char *app_plugin_ref = NULL;
  char *argv[] = { "flatpak", "build-commit-from", "--force",
                   "--gpg-homedir=", "--gpg-sign=",
                   "--src-repo=repos/test", "repos/test",
                   NULL, NULL };
  g_auto(GStrv) gpgargs = NULL;

  gpgargs = g_strsplit (gpg_args, " ", 0);
  app_plugin_ref = g_strdup_printf ("runtime/org.test.Hello.Plugin.fun/%s/v1",
                                    flatpak_get_default_arch ());
  argv[3] = gpgargs[0];
  argv[4] = gpgargs[1];
  argv[7] = app_plugin_ref;

  run_test_subprocess (argv, RUN_TEST_SUBPROCESS_DEFAULT);
}

static void
update_test_runtime (void)
{
  g_autofree char *arg0 = NULL;
  char *argv[] = { NULL, "repos/test", "org.test.Platform", "master", "", "UPDATED", NULL };

  arg0 = g_test_build_filename (G_TEST_DIST, "make-test-runtime.sh", NULL);
  argv[0] = arg0;
  argv[4] = repo_collection_id;

  run_test_subprocess (argv, RUN_TEST_SUBPROCESS_DEFAULT);
}

static void
update_repo (const char *update_repo_name)
{
  g_autofree char *arg4 = NULL;
  char *argv[] = { "flatpak", "build-update-repo", "--gpg-homedir=", "--gpg-sign=", NULL, NULL };
  g_auto(GStrv) gpgargs = NULL;

  gpgargs = g_strsplit (gpg_args, " ", 0);
  arg4 = g_strdup_printf ("repos/%s", update_repo_name);
  argv[2] = gpgargs[0];
  argv[3] = gpgargs[1];
  argv[4] = arg4;

  run_test_subprocess (argv, RUN_TEST_SUBPROCESS_DEFAULT);
}

static void
launch_httpd (void)
{
  g_autoptr(GError) error = NULL;
  g_autofree char *port = NULL;
  g_autofree char *pid = NULL;
  g_autofree char *path = g_test_build_filename (G_TEST_DIST, "test-webserver.sh", NULL);
  char *argv[] = {path, "repos", NULL };

  /* The web server puts itself in the background, so we can't wait
   * for EOF on its stdout, stderr */
  run_test_subprocess (argv, RUN_TEST_SUBPROCESS_NO_CAPTURE);

  g_file_get_contents ("httpd-pid", &pid, NULL, &error);
  g_assert_no_error (error);

  httpd_pid = atoi (pid);
  g_assert_cmpint (httpd_pid, !=, 0);

  g_file_get_contents ("httpd-port", &port, NULL, &error);
  g_assert_no_error (error);

  if (port[strlen (port) - 1] == '\n')
    port[strlen (port) - 1] = '\0';

  httpd_port = g_strdup (port);
}

static void
_add_remote (const char *remote_repo_name,
             const char *remote_name_override,
             gboolean    system)
{
  char *argv[] = { "flatpak", "remote-add", NULL, "--gpg-import=", "--collection-id=", "name", "url", NULL };
  g_autofree char *gpgimport = NULL;
  g_autofree char *collection_id_arg = NULL;
  g_autofree char *remote_name = NULL;
  g_autofree char *repo_url = NULL;

  gpgimport = g_strdup_printf ("--gpg-import=%s/pubring.gpg", gpg_homedir);
  repo_url = g_strdup_printf ("http://127.0.0.1:%s/%s", httpd_port, remote_repo_name);
  collection_id_arg = g_strdup_printf ("--collection-id=%s", repo_collection_id);
  if (remote_name_override != NULL)
    remote_name = g_strdup (remote_name_override);
  else
    remote_name = g_strdup_printf ("%s-repo", remote_repo_name);

  argv[2] = system ? "--system" : "--user";
  argv[3] = gpgimport;
  argv[4] = collection_id_arg;
  argv[5] = remote_name;
  argv[6] = repo_url;

  run_test_subprocess (argv, RUN_TEST_SUBPROCESS_DEFAULT);
}

static void
add_remote_system (const char *remote_repo_name,
                   const char *remote_name_override)
{
  _add_remote (remote_repo_name, remote_name_override, TRUE);
}

static void
add_remote_user (const char *remote_repo_name,
                 const char *remote_name_override)
{
  _add_remote (remote_repo_name, remote_name_override, FALSE);
}

static void
add_flatpakrepo (const char *flatpakrepo_repo_name)
{
  g_autofree char *data = NULL;
  g_autoptr(GError) error = NULL;
  g_autofree char *file_path = NULL;

  data = g_strconcat ("[Flatpak Repo]\n"
                      "Version=1\n"
                      "Url=http://127.0.0.1:", httpd_port, "/", flatpakrepo_repo_name, "\n"
                      "DefaultBranch=master\n"
                      "Title=Test repo\n", NULL);

  file_path = g_strdup_printf ("repos/%s/%s-repo.flatpakrepo", flatpakrepo_repo_name, flatpakrepo_repo_name);
  g_file_set_contents (file_path, data, -1, &error);
  g_assert_no_error (error);
}

static void
add_extra_installation (const char *id,
                        const char *display_name,
                        const char *storage_type,
                        const char *priority)
{
  g_autofree char *conffile_path = NULL;
  g_autofree char *contents_string = NULL;
  g_autofree char *path = NULL;
  g_autoptr(GPtrArray) contents_array = NULL;
  g_autoptr(GError) error = NULL;

  path = g_strconcat (testdir, "/system-", id, NULL);
  g_mkdir_with_parents (path, S_IRWXU | S_IRWXG | S_IRWXO);

  contents_array = g_ptr_array_new_with_free_func ((GDestroyNotify) g_free);

  g_ptr_array_add (contents_array,
                   g_strdup_printf ("[Installation \"%s\"]\n"
                                    "Path=%s",
                                    id, path));

  if (display_name != NULL)
    g_ptr_array_add (contents_array, g_strdup_printf ("DisplayName=%s", display_name));

  if (storage_type != NULL)
    g_ptr_array_add (contents_array, g_strdup_printf ("StorageType=%s", storage_type));

  if (priority != NULL)
    g_ptr_array_add (contents_array, g_strdup_printf ("Priority=%s", priority));

  g_ptr_array_add (contents_array, NULL);
  contents_string = g_strjoinv ("\n", (char **) contents_array->pdata);

  conffile_path = g_strconcat (flatpak_installationsdir, "/", id, ".conf", NULL);
  g_file_set_contents (conffile_path, contents_string, -1, &error);
  g_assert_no_error (error);
}

static void
setup_multiple_installations (void)
{
  flatpak_installationsdir = g_strconcat (flatpak_configdir, "/installations.d", NULL);
  g_mkdir_with_parents (flatpak_installationsdir, S_IRWXU | S_IRWXG | S_IRWXO);

  add_extra_installation ("extra-installation-1", "Extra system installation 1", "mmc", "10");
  add_extra_installation ("extra-installation-2", "Extra system installation 2", "sdcard", "25");
  add_extra_installation ("extra-installation-3", NULL, NULL, NULL);
}

static void
setup_repo (void)
{
  repo_collection_id = "com.example.Test";

  make_test_runtime ("test");
  make_test_app ("test");
  update_repo ("test");
  launch_httpd ();
  add_remote_user ("test", NULL);
  add_flatpakrepo ("test");
  configure_languages ("de");

  /* another copy of the same repo, with different url */
  g_assert_cmpint (symlink ("test", "repos/copy-of-test"), ==, 0);

  /* another repo, with only the app */
  make_test_app ("test-without-runtime");
  update_repo ("test-without-runtime");

  /* another repo, with only the runtime */
  make_test_runtime ("test-runtime-only");
  update_repo ("test-runtime-only");
  add_flatpakrepo ("test-runtime-only");
}

static void
copy_file (const char *src, const char *dest)
{
  gchar *buffer = NULL;
  gsize length;
  g_autoptr(GError) error = NULL;

  g_test_message ("copying %s to %s", src, dest);

  if (g_file_get_contents (src, &buffer, &length, &error))
    g_file_set_contents (dest, buffer, length, &error);
  g_assert_no_error (error);
  g_free (buffer);
}

static void
copy_gpg (void)
{
  char *src;
  char *dest;

  src = g_test_build_filename (G_TEST_DIST, "test-keyring", "pubring.gpg", NULL);
  dest = g_strconcat (gpg_homedir, "/pubring.gpg", NULL);
  copy_file (src, dest);
  g_free (src);
  g_free (dest);

  src = g_test_build_filename (G_TEST_DIST, "test-keyring", "secring.gpg", NULL);
  dest = g_strconcat (gpg_homedir, "/secring.gpg", NULL);
  copy_file (src, dest);
  g_free (src);
  g_free (dest);
}

GTestDBus *test_bus = NULL;

static void
global_setup (void)
{
  g_autofree char *cachedir = NULL;
  g_autofree char *configdir = NULL;
  g_autofree char *datadir = NULL;
  g_autofree char *statedir = NULL;
  g_autofree char *homedir = NULL;
  g_autofree char *services_dir = NULL;

  testdir = g_strdup ("/tmp/flatpak-test-XXXXXX");
  g_mkdtemp (testdir);
  g_test_message ("testdir: %s", testdir);

  homedir = g_strconcat (testdir, "/home", NULL);
  g_mkdir_with_parents (homedir, S_IRWXU | S_IRWXG | S_IRWXO);

  g_setenv ("HOME", homedir, TRUE);
  g_test_message ("setting HOME=%s", homedir);

  cachedir = g_strconcat (testdir, "/home/cache", NULL);
  g_mkdir_with_parents (cachedir, S_IRWXU | S_IRWXG | S_IRWXO);
  g_setenv ("XDG_CACHE_HOME", cachedir, TRUE);
  g_test_message ("setting XDG_CACHE_HOME=%s", cachedir);

  configdir = g_strconcat (testdir, "/home/config", NULL);
  g_mkdir_with_parents (configdir, S_IRWXU | S_IRWXG | S_IRWXO);
  g_setenv ("XDG_CONFIG_HOME", configdir, TRUE);
  g_test_message ("setting XDG_CONFIG_HOME=%s", configdir);

  datadir = g_strconcat (testdir, "/home/share", NULL);
  g_mkdir_with_parents (datadir, S_IRWXU | S_IRWXG | S_IRWXO);
  g_setenv ("XDG_DATA_HOME", datadir, TRUE);
  g_test_message ("setting XDG_DATA_HOME=%s", datadir);

  statedir = g_strconcat (testdir, "/home/state", NULL);
  g_mkdir_with_parents (statedir, S_IRWXU | S_IRWXG | S_IRWXO);
  g_setenv ("XDG_STATE_HOME", statedir, TRUE);
  g_test_message ("setting XDG_STATE_HOME=%s", statedir);

  flatpak_runtimedir = g_strconcat (testdir, "/runtime", NULL);
  g_mkdir_with_parents (flatpak_runtimedir, S_IRWXU | S_IRWXG | S_IRWXO);
  g_setenv ("XDG_RUNTIME_DIR", flatpak_runtimedir, TRUE);
  g_test_message ("setting XDG_RUNTIME_DIR=%s", flatpak_runtimedir);

  flatpak_systemdir = g_strconcat (testdir, "/system", NULL);
  g_mkdir_with_parents (flatpak_systemdir, S_IRWXU | S_IRWXG | S_IRWXO);
  g_setenv ("FLATPAK_SYSTEM_DIR", flatpak_systemdir, TRUE);
  g_test_message ("setting FLATPAK_SYSTEM_DIR=%s", flatpak_systemdir);

  flatpak_systemcachedir = g_strconcat (testdir, "/system-cache", NULL);
  g_mkdir_with_parents (flatpak_systemcachedir, S_IRWXU | S_IRWXG | S_IRWXO);
  g_setenv ("FLATPAK_SYSTEM_CACHE_DIR", flatpak_systemcachedir, TRUE);
  g_test_message ("setting FLATPAK_SYSTEM_CACHE_DIR=%s", flatpak_systemcachedir);

  flatpak_configdir = g_strconcat (testdir, "/config", NULL);
  g_mkdir_with_parents (flatpak_configdir, S_IRWXU | S_IRWXG | S_IRWXO);
  g_setenv ("FLATPAK_CONFIG_DIR", flatpak_configdir, TRUE);
  g_test_message ("setting FLATPAK_CONFIG_DIR=%s", flatpak_configdir);

  gpg_homedir = g_strconcat (testdir, "/gpghome", NULL);
  g_mkdir_with_parents (gpg_homedir, S_IRWXU | S_IRWXG | S_IRWXO);

  gpg_args = g_strdup_printf ("--gpg-homedir=%s --gpg-sign=%s", gpg_homedir, gpg_id);
  g_setenv ("GPGARGS", gpg_args, TRUE);
  g_test_message ("setting GPGARGS=%s", gpg_args);

  g_reload_user_special_dirs_cache ();

  g_assert_cmpstr (g_get_user_cache_dir (), ==, cachedir);
  g_assert_cmpstr (g_get_user_config_dir (), ==, configdir);
  g_assert_cmpstr (g_get_user_data_dir (), ==, datadir);
  g_assert_cmpstr (g_get_user_runtime_dir (), ==, flatpak_runtimedir);

  g_setenv ("FLATPAK_SYSTEM_HELPER_ON_SESSION", "1", TRUE);
  g_setenv ("LANGUAGE", "en", TRUE);

  if (!check_fuse ())
    {
      g_test_message ("FUSE doesn't seem to work? Disabling revokefs");
      g_setenv ("FLATPAK_DISABLE_REVOKEFS", "1", TRUE);
    }

  test_bus = g_test_dbus_new (G_TEST_DBUS_NONE);

  services_dir = g_test_build_filename (G_TEST_BUILT, "services", NULL);
  g_test_dbus_add_service_dir (test_bus, services_dir);

  g_test_dbus_up (test_bus);

  copy_gpg ();
  setup_multiple_installations ();
  setup_repo ();
  make_bundle ();
}

static void
global_teardown (void)
{
  char *argv[] = { "gpg-connect-agent", "--homedir", "<placeholder>", "killagent", "/bye", NULL };

  if (g_getenv ("SKIP_TEARDOWN"))
    return;

  g_test_dbus_down (test_bus);

  argv[2] = gpg_homedir;

  if (httpd_pid != -1)
    kill (httpd_pid, SIGKILL);

  run_test_subprocess (argv, RUN_TEST_SUBPROCESS_IGNORE_FAILURE);

  glnx_shutil_rm_rf_at (-1, testdir, NULL, NULL);
  g_free (testdir);
}

/* Check some basic transaction getters, without running a transaction
 * or adding ops.
 */
static void
test_misc_transaction (void)
{
  struct { int         op;
           const char *name;
  } kinds[] = {
    { FLATPAK_TRANSACTION_OPERATION_INSTALL, "install" },
    { FLATPAK_TRANSACTION_OPERATION_UPDATE, "update" },
    { FLATPAK_TRANSACTION_OPERATION_INSTALL_BUNDLE, "install-bundle" },
    { FLATPAK_TRANSACTION_OPERATION_UNINSTALL, "uninstall" },
    { FLATPAK_TRANSACTION_OPERATION_LAST_TYPE, NULL }
  };
  int i;
  g_autoptr(GError) error = NULL;
  g_autoptr(FlatpakInstallation) inst = NULL;
  g_autoptr(FlatpakInstallation) inst2 = NULL;
  g_autoptr(FlatpakInstallation) inst3 = NULL;
  g_autoptr(FlatpakTransaction) transaction = NULL;
  g_autoptr(FlatpakTransactionOperation) op = NULL;
  GList *list = NULL;

  for (i = 0; i < G_N_ELEMENTS (kinds); i++)
    g_assert_cmpstr (kinds[i].name, ==, flatpak_transaction_operation_type_to_string (kinds[i].op));

  inst = flatpak_installation_new_user (NULL, &error);
  g_assert_no_error (error);
  g_assert_nonnull (inst);

  transaction = flatpak_transaction_new_for_installation (NULL, NULL, &error);
  g_assert_nonnull (error);
  g_assert_null (transaction);
  g_clear_error (&error);

  transaction = flatpak_transaction_new_for_installation (inst, NULL, &error);
  g_assert_no_error (error);
  g_assert_nonnull (transaction);

  g_object_get (transaction, "installation", &inst2, NULL);
  g_assert_true (inst2 == inst);

  inst3 = flatpak_transaction_get_installation (transaction);
  g_assert_true (inst3 == inst);

  op = flatpak_transaction_get_current_operation (transaction);
  g_assert_null (op);

  list = flatpak_transaction_get_operations (transaction);
  g_assert_null (list);

  flatpak_transaction_set_no_deploy (transaction, TRUE);
  g_assert_true (flatpak_transaction_get_no_deploy (transaction) == TRUE);

  flatpak_transaction_set_no_pull (transaction, TRUE);
  g_assert_true (flatpak_transaction_get_no_pull (transaction) == TRUE);

  g_assert_true (flatpak_transaction_is_empty (transaction));
}

static void
empty_installation (FlatpakInstallation *inst)
{
  g_autoptr(GPtrArray) refs = NULL;
  g_autoptr(GError) error = NULL;
  int i;

  refs = flatpak_installation_list_installed_refs (inst, NULL, &error);
  g_assert_no_error (error);

  for (i = 0; i < refs->len; i++)
    {
      FlatpakRef *ref = g_ptr_array_index (refs, i);

      G_GNUC_BEGIN_IGNORE_DEPRECATIONS
      flatpak_installation_uninstall_full (inst,
                                           FLATPAK_UNINSTALL_FLAGS_NO_TRIGGERS,
                                           flatpak_ref_get_kind (ref),
                                           flatpak_ref_get_name (ref),
                                           flatpak_ref_get_arch (ref),
                                           flatpak_ref_get_branch (ref),
                                           NULL, NULL, NULL, &error);
      G_GNUC_END_IGNORE_DEPRECATIONS
      g_assert_no_error (error);
    }

  flatpak_installation_run_triggers (inst, NULL, &error);
  g_assert_no_error (error);

  flatpak_installation_prune_local_repo (inst, NULL, &error);
  g_assert_no_error (error);

  flatpak_installation_drop_caches (inst, NULL, &error);
  g_assert_no_error (error);
}

static int ready_count;
static int new_op_count;
static int op_done_count;

static gboolean
op_error (FlatpakTransaction             *transaction,
          FlatpakTransactionOperation    *op,
          GError                         *error,
          FlatpakTransactionErrorDetails *details)
{
  g_assert_not_reached ();
  return TRUE;
}

static gboolean
choose_remote (FlatpakTransaction *transaction,
               const char         *ref,
               const char         *runtime,
               const char        **remotes)
{
  g_assert_cmpint (g_strv_length ((char **) remotes), ==, 1);
  return 0;
}

static void
end_of_lifed (FlatpakTransaction *transaction,
              const char         *ref,
              const char         *reason,
              const char         *rebase)
{
  g_assert_not_reached ();
}

static gboolean
add_new_remote (FlatpakTransaction             *transaction,
                FlatpakTransactionRemoteReason  reason,
                const char                     *from_id,
                const char                     *suggested_name,
                const char                     *url)
{
  g_assert_not_reached ();
  return TRUE;
}

static gboolean
ready (FlatpakTransaction *transaction)
{
  GList *ops, *l;

  ready_count++;

  ops = flatpak_transaction_get_operations (transaction);
  g_assert_cmpint (g_list_length (ops), ==, 3);

  for (l = ops; l; l = l->next)
    {
      FlatpakTransactionOperation *op = l->data;

      g_assert_cmpint (flatpak_transaction_operation_get_operation_type (op), ==, FLATPAK_TRANSACTION_OPERATION_INSTALL);
      g_assert_nonnull (flatpak_transaction_operation_get_commit (op));
    }

  g_list_free_full (ops, g_object_unref);

  return TRUE;
}

static void
new_op (FlatpakTransaction          *transaction,
        FlatpakTransactionOperation *op,
        FlatpakTransactionProgress  *progress)
{
  g_autoptr(FlatpakTransactionOperation) current = NULL;
  g_auto(GStrv) refs = NULL;

  refs = g_new0 (gchar *, 4);
  refs[0] = g_strdup_printf ("runtime/org.test.Platform/%s/master",
                             flatpak_get_default_arch ());
  refs[1] = g_strdup_printf ("app/org.test.Hello/%s/master",
                             flatpak_get_default_arch ());
  refs[2] = g_strdup_printf ("runtime/org.test.Hello.Locale/%s/master",
                             flatpak_get_default_arch ());
  refs[3] = NULL;

  new_op_count++;

  current = flatpak_transaction_get_current_operation (transaction);
  g_assert_true (op == current);

  g_assert_cmpint (flatpak_transaction_operation_get_operation_type (op), ==, FLATPAK_TRANSACTION_OPERATION_INSTALL);
  g_assert_true (g_strv_contains ((const gchar * const *) refs, flatpak_transaction_operation_get_ref (op)));

  assert_cmpstr_free_lhs (flatpak_transaction_progress_get_status (progress),
                          ==, "Initializing");
  g_assert_true (flatpak_transaction_progress_get_is_estimating (progress));
  g_assert_cmpint (flatpak_transaction_progress_get_progress (progress), ==, 0);
}

static void
op_done (FlatpakTransaction          *transaction,
         FlatpakTransactionOperation *op,
         const char                  *commit,
         int                          result)
{
  g_auto(GStrv) refs = NULL;

  refs = g_new0 (gchar *, 4);
  refs[0] = g_strdup_printf ("runtime/org.test.Platform/%s/master",
                             flatpak_get_default_arch ());
  refs[1] = g_strdup_printf ("app/org.test.Hello/%s/master",
                             flatpak_get_default_arch ());
  refs[2] = g_strdup_printf ("runtime/org.test.Hello.Locale/%s/master",
                             flatpak_get_default_arch ());
  refs[3] = NULL;

  op_done_count++;

  g_assert_cmpint (flatpak_transaction_operation_get_operation_type (op), ==, FLATPAK_TRANSACTION_OPERATION_INSTALL);
  g_assert_true (g_strv_contains ((const gchar * const *) refs, flatpak_transaction_operation_get_ref (op)));

  g_assert_cmpint (result, ==, 0);
}

static void
op_done_no_change (FlatpakTransaction          *transaction,
                   FlatpakTransactionOperation *op,
                   const char                  *commit,
                   int                          result)
{
  assert_cmpstr_free_rhs (flatpak_transaction_operation_get_ref (op), ==,
                          g_strdup_printf ("app/org.test.Hello/%s/master",
                                           flatpak_get_default_arch ()));
  g_assert_cmpint (flatpak_transaction_operation_get_operation_type (op), ==, FLATPAK_TRANSACTION_OPERATION_UPDATE);
  g_assert_cmpint (result, ==, FLATPAK_TRANSACTION_RESULT_NO_CHANGE);
}

static void
op_done_with_change (FlatpakTransaction          *transaction,
                     FlatpakTransactionOperation *op,
                     const char                  *commit,
                     int                          result)
{
  assert_cmpstr_free_rhs (flatpak_transaction_operation_get_ref (op), ==,
                          g_strdup_printf ("app/org.test.Hello/%s/master",
                                           flatpak_get_default_arch ()));
  g_assert_cmpint (flatpak_transaction_operation_get_operation_type (op), ==, FLATPAK_TRANSACTION_OPERATION_UPDATE);
  g_assert_cmpint (result, ==, 0);
}

/* Do a bunch of installs and uninstalls with a transaction, and check
 * that ops looks as expected, and that signal are fired.
 */
static void
test_transaction_install_uninstall (void)
{
  g_autoptr(FlatpakInstallation) inst = NULL;
  g_autoptr(FlatpakTransaction) transaction = NULL;
  g_autoptr(FlatpakTransactionOperation) op = NULL;
  gboolean res;
  g_autoptr(GError) error = NULL;
  GList *list;
  g_autoptr(GPtrArray) refs = NULL;
  g_autoptr(FlatpakInstalledRef) ref = NULL;
  gboolean is_current;
  g_autofree char *origin = NULL;
  guint64 size;
  g_auto(GStrv) subpaths = NULL;
  g_autofree char *eol = NULL;
  g_autofree char *eol_rebase = NULL;
  g_autofree char *commit = NULL;
  g_autofree char *deploy = NULL;
  GBytes *bytes = NULL;
  const char *empty_subpaths[] = { "", NULL };
  g_autofree char *app = NULL;
  g_autofree char *runtime = NULL;

  app = g_strdup_printf ("app/org.test.Hello/%s/master",
                         flatpak_get_default_arch ());
  runtime = g_strdup_printf ("runtime/org.test.Platform/%s/master",
                             flatpak_get_default_arch ());

  inst = flatpak_installation_new_user (NULL, &error);
  g_assert_no_error (error);
  g_assert_nonnull (inst);

  /* start from a clean slate */
  empty_installation (inst);

  /* Check that it is indeed empty */
  ref = flatpak_installation_get_current_installed_app (inst, "org.test.Hello", NULL, &error);
  g_assert_error (error, FLATPAK_ERROR, FLATPAK_ERROR_NOT_INSTALLED);
  g_assert_null (ref);
  g_clear_error (&error);

  /* update org.test.Hello, we expect a non-installed error */
  transaction = flatpak_transaction_new_for_installation (inst, NULL, &error);
  g_assert_no_error (error);
  g_assert_nonnull (transaction);

  g_assert_true (flatpak_transaction_is_empty (transaction));

  res = flatpak_transaction_add_update (transaction, app, NULL, NULL, &error);
  g_assert_error (error, FLATPAK_ERROR, FLATPAK_ERROR_NOT_INSTALLED);
  g_assert_false (res);
  g_clear_error (&error);

  g_clear_object (&transaction);

  /* install org.test.Hello, and have org.test.Hello.Locale and org.test.Platform
   * added as deps/related
   */
  transaction = flatpak_transaction_new_for_installation (inst, NULL, &error);
  g_assert_no_error (error);
  g_assert_nonnull (transaction);

  res = flatpak_transaction_add_install (transaction, repo_name, app, NULL, &error);
  g_assert_no_error (error);
  g_assert_true (res);

  g_assert_true (!flatpak_transaction_is_empty (transaction));

  list = flatpak_transaction_get_operations (transaction);
  g_assert_cmpint (g_list_length (list), ==, 1);
  op = (FlatpakTransactionOperation *) list->data;

  g_list_free (list);

  g_assert_cmpint (flatpak_transaction_operation_get_operation_type (op), ==, FLATPAK_TRANSACTION_OPERATION_INSTALL);
  g_assert_cmpstr (flatpak_transaction_operation_get_ref (op), ==, app);
  g_assert_cmpstr (flatpak_transaction_operation_get_remote (op), ==, repo_name);
  g_assert_null (flatpak_transaction_operation_get_bundle_path (op));
  g_assert_null (flatpak_transaction_operation_get_commit (op));

  g_signal_connect (transaction, "ready", G_CALLBACK (ready), NULL);
  g_signal_connect (transaction, "new-operation", G_CALLBACK (new_op), NULL);
  g_signal_connect (transaction, "operation-done", G_CALLBACK (op_done), NULL);
  g_signal_connect (transaction, "operation-error", G_CALLBACK (op_error), NULL);
  g_signal_connect (transaction, "choose-remote-for-ref", G_CALLBACK (choose_remote), NULL);
  g_signal_connect (transaction, "end-of-lifed", G_CALLBACK (end_of_lifed), NULL);
  g_signal_connect (transaction, "add-new-remote", G_CALLBACK (add_new_remote), NULL);

  ready_count = 0;
  new_op_count = 0;
  op_done_count = 0;

  res = flatpak_transaction_run (transaction, NULL, &error);
  g_assert_no_error (error);
  g_assert_true (res);

  g_assert_cmpint (ready_count, ==, 1);
  g_assert_cmpint (new_op_count, ==, 3);
  g_assert_cmpint (op_done_count, ==, 3);

  refs = flatpak_installation_list_installed_refs (inst, NULL, &error);
  g_assert_no_error (error);
  g_assert_nonnull (refs);
  g_assert_cmpint (refs->len, ==, 3);
  g_clear_pointer (&refs, g_ptr_array_unref);

  ref = flatpak_installation_get_current_installed_app (inst, "org.test.Hello", NULL, &error);
  g_assert_no_error (error);
  g_assert_nonnull (ref);

  g_assert_cmpstr (flatpak_installed_ref_get_origin (ref), ==, repo_name);
  g_assert_null (flatpak_installed_ref_get_subpaths (ref));
  g_assert_cmpuint (flatpak_installed_ref_get_installed_size (ref), >, 0);
  g_assert_true (flatpak_installed_ref_get_is_current (ref));
  g_assert_nonnull (flatpak_installed_ref_get_latest_commit (ref));
  g_assert_nonnull (flatpak_installed_ref_get_deploy_dir (ref));
  g_assert_null (flatpak_installed_ref_get_eol (ref));
  g_assert_null (flatpak_installed_ref_get_eol_rebase (ref));
  g_assert_cmpstr (flatpak_installed_ref_get_appdata_name (ref), ==, "Hello world test app: org.test.Hello");
  g_assert_cmpstr (flatpak_installed_ref_get_appdata_summary (ref), ==, "Print a greeting");
  g_assert_cmpstr (flatpak_installed_ref_get_appdata_version (ref), ==, "0.0.1");
  g_object_get (ref,
                "is-current", &is_current,
                "origin", &origin,
                "installed-size", &size,
                "latest-commit", &commit,
                "deploy-dir", &deploy,
                "subpaths", &subpaths,
                "end-of-life", &eol,
                "end-of-life-rebase", &eol_rebase,
                NULL);
  g_assert_true (is_current);
  g_assert_cmpstr (origin, ==, repo_name);
  g_assert_cmpuint (size, >, 0);
  g_assert_nonnull (commit);
  g_assert_nonnull (deploy);
  g_assert_null (subpaths);
  g_assert_null (eol);
  g_assert_null (eol_rebase);
  g_clear_object (&ref);

  refs = flatpak_installation_list_installed_refs_by_kind (inst,
                                                           FLATPAK_REF_KIND_RUNTIME,
                                                           NULL,
                                                           &error);
  g_assert_no_error (error);
  g_assert_cmpint (refs->len, ==, 2);

  ref = g_object_ref (g_ptr_array_index (refs, 0));
  bytes = flatpak_installed_ref_load_metadata (ref, NULL, &error);
  g_assert_no_error (error);
  g_assert_nonnull (bytes);
  g_bytes_unref (bytes);
  g_clear_object (&ref);
  g_clear_pointer (&refs, g_ptr_array_unref);

  g_clear_object (&transaction);

  /* install org.test.Hello again. we expect an already-installed error */
  transaction = flatpak_transaction_new_for_installation (inst, NULL, &error);
  g_assert_no_error (error);
  g_assert_nonnull (transaction);

  res = flatpak_transaction_add_install (transaction, repo_name, app, NULL, &error);
  g_assert_error (error, FLATPAK_ERROR, FLATPAK_ERROR_ALREADY_INSTALLED);
  g_assert_false (res);
  g_clear_error (&error);

  g_clear_object (&transaction);

  /* uninstall org.test.Hello with no_deploy set to TRUE. This should be a
   * no-op.
   */
  transaction = flatpak_transaction_new_for_installation (inst, NULL, &error);
  g_assert_no_error (error);
  g_assert_nonnull (transaction);

  flatpak_transaction_set_no_deploy (transaction, TRUE);
  g_assert_true (flatpak_transaction_get_no_deploy (transaction));

  res = flatpak_transaction_add_uninstall (transaction, app, &error);
  g_assert_no_error (error);
  g_assert_true (res);

  g_assert_true (flatpak_transaction_is_empty (transaction));

  list = flatpak_transaction_get_operations (transaction);
  g_assert_cmpint (g_list_length (list), ==, 0);
  g_list_free (list);

  g_clear_object (&transaction);

  /* uninstall org.test.Hello, we expect org.test.Hello.Locale to be
   * removed with it, but org.test.Platform to stay
   */
  transaction = flatpak_transaction_new_for_installation (inst, NULL, &error);
  g_assert_no_error (error);
  g_assert_nonnull (transaction);

  res = flatpak_transaction_add_uninstall (transaction, app, &error);
  g_assert_no_error (error);
  g_assert_true (res);

  res = flatpak_transaction_run (transaction, NULL, &error);
  g_assert_no_error (error);
  g_assert_true (res);

  refs = flatpak_installation_list_installed_refs (inst, NULL, &error);
  g_assert_no_error (error);
  g_assert_nonnull (refs);
  g_assert_cmpint (refs->len, ==, 1);
  ref = g_object_ref (g_ptr_array_index (refs, 0));
  g_assert_cmpstr (flatpak_ref_get_name (FLATPAK_REF (ref)), ==, "org.test.Platform");
  g_clear_object (&ref);
  g_clear_pointer (&refs, g_ptr_array_unref);

  /* run the transaction again, expect an error */
  res = flatpak_transaction_run (transaction, NULL, &error);
  g_assert_nonnull (error);
  g_assert_false (res);
  g_clear_error (&error);

  g_clear_object (&transaction);

  /* install org.test.Hello and uninstall org.test.Platform. This is
   * expected to yield an error
   */
  transaction = flatpak_transaction_new_for_installation (inst, NULL, &error);
  g_assert_no_error (error);
  g_assert_nonnull (transaction);

  res = flatpak_transaction_add_install (transaction, repo_name, app, NULL, &error);
  g_assert_no_error (error);
  g_assert_true (res);

  res = flatpak_transaction_add_uninstall (transaction, runtime, &error);
  g_assert_no_error (error);
  g_assert_true (res);

  res = flatpak_transaction_run (transaction, NULL, &error);
  g_assert_error (error, FLATPAK_ERROR, FLATPAK_ERROR_RUNTIME_USED);
  g_assert_false (res);
  g_clear_error (&error);

  g_clear_object (&transaction);

  /* try again to install org.test.Hello. We'll end up with 3 refs */
  transaction = flatpak_transaction_new_for_installation (inst, NULL, &error);
  g_assert_no_error (error);
  g_assert_nonnull (transaction);

  res = flatpak_transaction_add_install (transaction, repo_name, app, empty_subpaths, &error);
  g_assert_no_error (error);
  g_assert_true (res);

  res = flatpak_transaction_run (transaction, NULL, &error);
  g_assert_no_error (error);
  g_assert_true (res);

  refs = flatpak_installation_list_installed_refs (inst, NULL, &error);
  g_assert_no_error (error);
  g_assert_nonnull (refs);
  g_assert_cmpint (refs->len, ==, 3);
  g_clear_pointer (&refs, g_ptr_array_unref);

  ref = flatpak_installation_get_installed_ref (inst, FLATPAK_REF_KIND_APP, "org.test.Hello", "xzy", "master", NULL, &error);
  g_assert_null (ref);
  g_assert_error (error, FLATPAK_ERROR, FLATPAK_ERROR_NOT_INSTALLED);
  g_clear_error (&error);

  ref = flatpak_installation_get_installed_ref (inst, FLATPAK_REF_KIND_APP, "org.test.Hello", NULL, "master", NULL, &error);
  g_assert_nonnull (ref);
  g_assert_no_error (error);

  g_assert_cmpstr (flatpak_ref_get_name (FLATPAK_REF (ref)), ==, "org.test.Hello");
  g_clear_object (&ref);

  g_clear_object (&transaction);

  /* update org.test.Hello. Check that this is a no-op */
  transaction = flatpak_transaction_new_for_installation (inst, NULL, &error);
  g_assert_no_error (error);
  g_assert_nonnull (transaction);

  res = flatpak_transaction_add_update (transaction, app, NULL, NULL, &error);
  g_assert_no_error (error);
  g_assert_true (res);

  g_signal_connect (transaction, "operation-done", G_CALLBACK (op_done_no_change), NULL);

  res = flatpak_transaction_run (transaction, NULL, &error);
  g_assert_no_error (error);
  g_assert_true (res);

  g_clear_object (&transaction);

  /* update again, using { "", NULL } as subpaths, to install all */
  transaction = flatpak_transaction_new_for_installation (inst, NULL, &error);
  g_assert_no_error (error);
  g_assert_nonnull (transaction);

  res = flatpak_transaction_add_update (transaction, app, empty_subpaths, NULL, &error);
  g_assert_no_error (error);
  g_assert_true (res);

  g_signal_connect (transaction, "operation-done", G_CALLBACK (op_done_with_change), NULL);

  res = flatpak_transaction_run (transaction, NULL, &error);
  g_assert_no_error (error);
  g_assert_true (res);

  g_clear_object (&transaction);

  /* uninstall both org.test.Hello and org.test.Platform, leaving an empty installation */
  transaction = flatpak_transaction_new_for_installation (inst, NULL, &error);
  g_assert_no_error (error);
  g_assert_nonnull (transaction);

  res = flatpak_transaction_add_uninstall (transaction, app, &error);
  g_assert_no_error (error);
  g_assert_true (res);

  res = flatpak_transaction_add_uninstall (transaction, runtime, &error);
  g_assert_no_error (error);
  g_assert_true (res);

  res = flatpak_transaction_run (transaction, NULL, &error);
  g_assert_no_error (error);
  g_assert_true (res);

  g_clear_object (&transaction);

  /* uninstall again, expect a not-installed error */
  transaction = flatpak_transaction_new_for_installation (inst, NULL, &error);
  g_assert_no_error (error);
  g_assert_nonnull (transaction);

  res = flatpak_transaction_add_uninstall (transaction, app, &error);
  g_assert_error (error, FLATPAK_ERROR, FLATPAK_ERROR_NOT_INSTALLED);
  g_assert_false (res);

  g_clear_object (&transaction);
}

static int remote_added;

static gboolean
add_new_remote2 (FlatpakTransaction             *transaction,
                 FlatpakTransactionRemoteReason  reason,
                 const char                     *from_id,
                 const char                     *suggested_name,
                 const char                     *url)
{
  remote_added++;
  g_assert_cmpstr (suggested_name, ==, "my-little-repo");
  return TRUE;
}

/* test installing a flatpakref with a transaction */
static void
test_transaction_install_flatpakref (void)
{
  g_autoptr(FlatpakInstallation) inst = NULL;
  g_autoptr(FlatpakTransaction) transaction = NULL;
  g_autoptr(GError) error = NULL;
  g_autoptr(GPtrArray) refs = NULL;
  gboolean res;
  g_autofree char *s = NULL;
  g_autoptr(GBytes) data = NULL;
  g_autofree char *app = NULL;
  g_autofree char *runtime = NULL;

  app = g_strdup_printf ("app/org.test.Hello/%s/master",
                         flatpak_get_default_arch ());
  runtime = g_strdup_printf ("runtime/org.test.Platform/%s/master",
                             flatpak_get_default_arch ());

  inst = flatpak_installation_new_user (NULL, &error);
  g_assert_no_error (error);
  g_assert_nonnull (inst);

  /* start from a clean slate */
  empty_installation (inst);

  transaction = flatpak_transaction_new_for_installation (inst, NULL, &error);
  g_assert_no_error (error);
  g_assert_nonnull (transaction);

  /* pointless, but do it anyway */
  flatpak_transaction_add_dependency_source (transaction, inst);

  data = g_bytes_new ("shoobidoo", strlen ("shoobidoo"));
  res = flatpak_transaction_add_install_flatpakref (transaction, data, &error);
  g_assert_error (error, FLATPAK_ERROR, FLATPAK_ERROR_INVALID_DATA);
  g_clear_error (&error);
  g_assert_false (res);
  g_clear_pointer (&data, g_bytes_unref);

  s = g_strconcat ("[Flatpak Ref]\n"
                   "Title=Test App\n"
                   "Name=org.test.Hello\n"
                   "Branch=master\n"
                   /* Uses a different url for the repo, so we can ensure it gets added */
                   "Url=http://127.0.0.1:", httpd_port, "/copy-of-test\n"
                   "IsRuntime=false\n"
                   "SuggestRemoteName=my-little-repo\n"
                   "RuntimeRepo=http://127.0.0.1:", httpd_port, "/test/test-repo.flatpakrepo\n",
                   NULL);

  data = g_bytes_new (s, strlen (s));
  res = flatpak_transaction_add_install_flatpakref (transaction, data, &error);
  g_assert_no_error (error);
  g_assert_true (res);

  remote_added = 0;
  g_signal_connect (transaction, "add-new-remote", G_CALLBACK (add_new_remote2), NULL);

  res = flatpak_transaction_run (transaction, NULL, &error);
  g_assert_no_error (error);
  g_assert_true (res);

  g_assert_cmpint (remote_added, >, 0);

  refs = flatpak_installation_list_installed_refs (inst, NULL, &error);
  g_assert_no_error (error);
  g_assert_nonnull (refs);
  g_assert_cmpint (refs->len, ==, 3);
  g_clear_pointer (&refs, g_ptr_array_unref);

  transaction = flatpak_transaction_new_for_installation (inst, NULL, &error);
  g_assert_no_error (error);
  g_assert_nonnull (transaction);

  res = flatpak_transaction_add_uninstall (transaction, app, &error);
  g_assert_no_error (error);
  g_assert_true (res);

  res = flatpak_transaction_add_uninstall (transaction, runtime, &error);
  g_assert_no_error (error);
  g_assert_true (res);

  res = flatpak_transaction_run (transaction, NULL, &error);
  g_assert_no_error (error);
  g_assert_true (res);

  remove_remote_user ("my-little-repo");
}

static gboolean
_is_remote_in_installation (FlatpakInstallation *installation,
                            const char          *remote_name)
{
  g_autoptr(GError) error = NULL;
  g_autoptr(GPtrArray) remotes = NULL;

  remotes = flatpak_installation_list_remotes (installation, NULL, &error);
  g_assert_no_error (error);
  g_assert_nonnull (remotes);

  for (guint i = 0; i < remotes->len; ++i)
    {
      FlatpakRemote *remote = g_ptr_array_index (remotes, i);
      if (g_strcmp0 (remote_name, flatpak_remote_get_name (remote)) == 0)
        return TRUE;
    }

  return FALSE;
}

#define assert_remote_in_installation(inst, remote)        \
  G_STMT_START {                                           \
    if (!_is_remote_in_installation (inst, remote))        \
      g_assertion_message (G_LOG_DOMAIN,                   \
                           __FILE__, __LINE__, G_STRFUNC,  \
                           "remote " remote " not found"); \
  } G_STMT_END

#define assert_remote_not_in_installation(inst, remote)    \
  G_STMT_START {                                           \
    if (_is_remote_in_installation (inst, remote))         \
      g_assertion_message (G_LOG_DOMAIN,                   \
                           __FILE__, __LINE__, G_STRFUNC,  \
                           "remote " remote " was found"); \
  } G_STMT_END

static gboolean
add_new_remote3 (FlatpakTransaction             *transaction,
                 FlatpakTransactionRemoteReason  reason,
                 const char                     *from_id,
                 const char                     *suggested_name,
                 const char                     *url)
{
  return TRUE;
}

static gboolean
ready_check_get_op (FlatpakTransaction *transaction)
{
  g_autoptr(GError) error = NULL;
  g_autofree char *app = NULL;
  g_autoptr(FlatpakTransactionOperation) op = NULL;

  app = g_strdup_printf ("app/org.test.Hello/%s/master",
                         flatpak_get_default_arch ());

  op = flatpak_transaction_get_operation_for_ref (transaction, NULL, app, &error);
  g_assert_no_error (error);
  g_assert_nonnull (op);

  g_assert_cmpint (flatpak_transaction_operation_get_operation_type (op), ==, FLATPAK_TRANSACTION_OPERATION_INSTALL);
  g_assert_cmpstr (flatpak_transaction_operation_get_ref (op), ==, app);
  g_assert_cmpstr (flatpak_transaction_operation_get_remote (op), ==, "test-without-runtime-repo");

  return TRUE;
}

/* Test that installing a flatpakref causes both the origin remote and the
 * runtime remote to be created, even if they already exist in another
 * installation */
static void
test_transaction_flatpakref_remote_creation (void)
{
  g_autoptr(FlatpakInstallation) user_inst = NULL;
  g_autoptr(FlatpakInstallation) system_inst = NULL;
  g_autoptr(FlatpakTransaction) transaction = NULL;
  g_autoptr(FlatpakRemote) remote = NULL;
  g_autoptr(GError) error = NULL;
  g_autofree char *s = NULL;
  g_autofree char *remote_title = NULL;
  g_autoptr(GBytes) data = NULL;
  gboolean res;

  system_inst = flatpak_installation_new_system (NULL, &error);
  g_assert_no_error (error);
  g_assert_nonnull (system_inst);

  empty_installation (system_inst);

  add_remote_system ("test-without-runtime", NULL);
  add_remote_system ("test-runtime-only", NULL);

  user_inst = flatpak_installation_new_user (NULL, &error);
  g_assert_no_error (error);
  g_assert_nonnull (user_inst);

  empty_installation (user_inst);

  assert_remote_not_in_installation (user_inst, "test-without-runtime-repo");
  assert_remote_not_in_installation (user_inst, "test-runtime-only-repo");

  transaction = flatpak_transaction_new_for_installation (user_inst, NULL, &error);
  g_assert_no_error (error);
  g_assert_nonnull (transaction);

  s = g_strconcat ("[Flatpak Ref]\n"
                   "Title=Test App\n"
                   "Name=org.test.Hello\n"
                   "Branch=master\n"
                   "Url=http://127.0.0.1:", httpd_port, "/test-without-runtime\n"
                   "IsRuntime=false\n"
                   "SuggestRemoteName=test-without-runtime-repo\n"
                   "RuntimeRepo=http://127.0.0.1:", httpd_port, "/test-runtime-only/test-runtime-only-repo.flatpakrepo\n",
                   NULL);

  data = g_bytes_new (s, strlen (s));
  res = flatpak_transaction_add_install_flatpakref (transaction, data, &error);
  g_assert_no_error (error);
  g_assert_true (res);

  g_signal_connect (transaction, "add-new-remote", G_CALLBACK (add_new_remote3), NULL);
  g_signal_connect (transaction, "ready", G_CALLBACK (ready_check_get_op), NULL);

  res = flatpak_transaction_run (transaction, NULL, &error);
  g_assert_no_error (error);
  g_assert_true (res);

  assert_remote_in_installation (user_inst, "test-without-runtime-repo");
  assert_remote_in_installation (user_inst, "test-runtime-only-repo");

  /* The remote should not use the title of the app as its title */
  remote = flatpak_installation_get_remote_by_name (user_inst, "test-without-runtime-repo", NULL, &error);
  g_assert_no_error (error);
  g_assert_nonnull (remote);
  remote_title = flatpak_remote_get_title (remote);
  g_assert_null (remote_title);

  empty_installation (user_inst);
  remove_remote_user ("test-without-runtime-repo");
  remove_remote_user ("test-runtime-only-repo");
  remove_remote_system ("test-without-runtime-repo");
  remove_remote_system ("test-runtime-only-repo");
}

static gboolean
ready_check_origin_remote (FlatpakTransaction *transaction)
{
  g_autoptr(FlatpakInstallation) installation = NULL;
  g_autoptr(FlatpakRemoteRef) remote_ref = NULL;
  g_autoptr(FlatpakRemote) remote = NULL;
  g_autoptr(GError) error = NULL;
  installation = flatpak_transaction_get_installation (transaction);

  /* The remote should return the ref set as xa.main-ref on it despite having xa.noenumerate set */
  remote = flatpak_installation_get_remote_by_name (installation, "hello-origin", NULL, &error);
  g_assert_no_error (error);
  g_assert_nonnull (remote);
  g_assert_true (flatpak_remote_get_noenumerate (remote));
  assert_cmpstr_free_both (flatpak_remote_get_main_ref (remote), ==,
                           g_strdup_printf ("app/org.test.Hello/%s/master",
                                            flatpak_get_default_arch ()));

  remote_ref = flatpak_installation_fetch_remote_ref_sync (installation,
                                                           "hello-origin",
                                                           FLATPAK_REF_KIND_APP,
                                                           "org.test.Hello",
                                                           flatpak_get_default_arch (),
                                                           "master",
                                                           NULL, &error);
  g_assert_no_error (error);
  g_assert_nonnull (remote_ref);

  /* An extension with the main ref as a prefix should also be visible */
  g_clear_object (&remote_ref);
  remote_ref = flatpak_installation_fetch_remote_ref_sync (installation,
                                                           "hello-origin",
                                                           FLATPAK_REF_KIND_RUNTIME,
                                                           "org.test.Hello.Plugin.fun",
                                                           flatpak_get_default_arch (),
                                                           "v1",
                                                           NULL, &error);
  g_assert_no_error (error);
  g_assert_nonnull (remote_ref);

  return TRUE;
}

/* Test that installing a flatpakref causes an origin remote to be created when
 * the file has no SuggestRemoteName= option, and check the options set on the
 * remote */
static void
test_transaction_flatpakref_origin_remote_creation (void)
{
  g_autoptr(FlatpakInstallation) user_inst = NULL;
  g_autoptr(FlatpakTransaction) transaction = NULL;
  g_autoptr(GError) error = NULL;
  g_autofree char *s = NULL;
  g_autoptr(GBytes) data = NULL;
  gboolean res;

  user_inst = flatpak_installation_new_user (NULL, &error);
  g_assert_no_error (error);
  g_assert_nonnull (user_inst);

  empty_installation (user_inst);

  assert_remote_not_in_installation (user_inst, "hello-origin");
  assert_remote_not_in_installation (user_inst, "test-runtime-only-repo");

  transaction = flatpak_transaction_new_for_installation (user_inst, NULL, &error);
  g_assert_no_error (error);
  g_assert_nonnull (transaction);

  s = g_strconcat ("[Flatpak Ref]\n"
                   "Title=Test App\n"
                   "Name=org.test.Hello\n"
                   "Branch=master\n"
                   "Url=http://127.0.0.1:", httpd_port, "/test-without-runtime\n"
                   "IsRuntime=False\n"
                   "RuntimeRepo=http://127.0.0.1:", httpd_port, "/test-runtime-only/test-runtime-only-repo.flatpakrepo\n",
                   NULL);

  data = g_bytes_new (s, strlen (s));
  res = flatpak_transaction_add_install_flatpakref (transaction, data, &error);
  g_assert_no_error (error);
  g_assert_true (res);

  g_signal_connect (transaction, "add-new-remote", G_CALLBACK (add_new_remote3), NULL);
  g_signal_connect (transaction, "ready", G_CALLBACK (ready_check_origin_remote), NULL);

  res = flatpak_transaction_run (transaction, NULL, &error);
  g_assert_no_error (error);
  g_assert_true (res);

  assert_remote_in_installation (user_inst, "hello-origin");
  assert_remote_in_installation (user_inst, "test-runtime-only-repo");

  empty_installation (user_inst);
  /* note: the origin remote will be removed automatically in the above prune */
  assert_remote_not_in_installation (user_inst, "hello-origin");
  remove_remote_user ("test-runtime-only-repo");
}

static gboolean
check_ready1_abort (FlatpakTransaction *transaction)
{
  GList *ops;
  FlatpakTransactionOperation *op;

  ops = flatpak_transaction_get_operations (transaction);
  g_assert_cmpint (g_list_length (ops), ==, 1);
  op = ops->data;

  g_assert_cmpint (flatpak_transaction_operation_get_operation_type (op), ==, FLATPAK_TRANSACTION_OPERATION_INSTALL);
  assert_cmpstr_free_rhs (flatpak_transaction_operation_get_ref (op), ==,
                          g_strdup_printf ("app/org.test.Hello/%s/master",
                                           flatpak_get_default_arch ()));

  g_list_free_full (ops, g_object_unref);

  return FALSE;
}

static gboolean
check_ready3_abort (FlatpakTransaction *transaction)
{
  GList *ops;
  FlatpakTransactionOperation *op;

  ops = flatpak_transaction_get_operations (transaction);
  g_assert_cmpint (g_list_length (ops), ==, 3);
  op = ops->data;
  g_assert_cmpint (flatpak_transaction_operation_get_operation_type (op), ==, FLATPAK_TRANSACTION_OPERATION_INSTALL);
  assert_cmpstr_free_rhs (flatpak_transaction_operation_get_ref (op), ==,
                          g_strdup_printf ("runtime/org.test.Hello.Locale/%s/master",
                                           flatpak_get_default_arch ()));

  op = ops->next->data;
  g_assert_cmpint (flatpak_transaction_operation_get_operation_type (op), ==, FLATPAK_TRANSACTION_OPERATION_INSTALL);
  assert_cmpstr_free_rhs (flatpak_transaction_operation_get_ref (op), ==,
                          g_strdup_printf ("runtime/org.test.Platform/%s/master",
                                           flatpak_get_default_arch ()));


  op = ops->next->next->data;
  g_assert_cmpint (flatpak_transaction_operation_get_operation_type (op), ==, FLATPAK_TRANSACTION_OPERATION_INSTALL);
  assert_cmpstr_free_rhs (flatpak_transaction_operation_get_ref (op), ==,
                          g_strdup_printf ("app/org.test.Hello/%s/master",
                                           flatpak_get_default_arch ()));

  g_list_free_full (ops, g_object_unref);

  return FALSE;
}

/* test disabling dependencies and related */
static void
test_transaction_deps (void)
{
  g_autoptr(FlatpakInstallation) inst = NULL;
  g_autoptr(FlatpakTransaction) transaction = NULL;
  g_autoptr(GError) error = NULL;
  gboolean res;
  g_autofree char *app = NULL;

  app = g_strdup_printf ("app/org.test.Hello/%s/master",
                         flatpak_get_default_arch ());

  inst = flatpak_installation_new_user (NULL, &error);
  g_assert_no_error (error);
  g_assert_nonnull (inst);

  empty_installation (inst);

  transaction = flatpak_transaction_new_for_installation (inst, NULL, &error);
  g_assert_no_error (error);
  g_assert_nonnull (transaction);

  flatpak_transaction_set_disable_dependencies (transaction, TRUE);
  flatpak_transaction_set_disable_related (transaction, TRUE);

  res = flatpak_transaction_add_install (transaction, repo_name, app, NULL, &error);
  g_assert_no_error (error);
  g_assert_true (res);

  g_signal_connect (transaction, "ready", G_CALLBACK (check_ready1_abort), NULL);
  flatpak_transaction_run (transaction, NULL, &error);
  g_assert_error (error, FLATPAK_ERROR, FLATPAK_ERROR_ABORTED);
  g_clear_error (&error);

  g_clear_object (&transaction);

  transaction = flatpak_transaction_new_for_installation (inst, NULL, &error);
  g_assert_no_error (error);
  g_assert_nonnull (transaction);

  flatpak_transaction_set_disable_dependencies (transaction, FALSE);
  flatpak_transaction_set_disable_related (transaction, FALSE);

  res = flatpak_transaction_add_install (transaction, repo_name, app, NULL, &error);
  g_assert_no_error (error);
  g_assert_true (res);

  g_signal_connect (transaction, "ready", G_CALLBACK (check_ready3_abort), NULL);
  flatpak_transaction_run (transaction, NULL, &error);
  g_assert_error (error, FLATPAK_ERROR, FLATPAK_ERROR_ABORTED);
}

/* install from a local repository */
static void
test_transaction_install_local (void)
{
  g_autoptr(FlatpakInstallation) inst = NULL;
  g_autoptr(FlatpakTransaction) transaction = NULL;
  g_autoptr(GError) error = NULL;
  gboolean res;
  g_autofree char *dir = NULL;
  g_autofree char *path = NULL;
  g_autofree char *url = NULL;
  g_autoptr(FlatpakRemote) remote = NULL;
  g_autofree char *app = NULL;

  app = g_strdup_printf ("app/org.test.Hello/%s/master",
                         flatpak_get_default_arch ());

  inst = flatpak_installation_new_user (NULL, &error);
  g_assert_no_error (error);
  g_assert_nonnull (inst);

  empty_installation (inst);

  remote = flatpak_installation_get_remote_by_name (inst, "hello-origin", NULL, &error);
  g_assert_error (error, FLATPAK_ERROR, FLATPAK_ERROR_REMOTE_NOT_FOUND);
  g_assert_null (remote);
  g_clear_error (&error);

  transaction = flatpak_transaction_new_for_installation (inst, NULL, &error);
  g_assert_no_error (error);
  g_assert_nonnull (transaction);

  dir = g_get_current_dir ();
  path = g_build_filename (dir, "repos", "test", NULL);
  url = g_strconcat ("file://", path, NULL);
  res = flatpak_transaction_add_install (transaction, url, app, NULL, &error);
  g_assert_no_error (error);
  g_assert_true (res);

  res = flatpak_transaction_run (transaction, NULL, &error);
  g_assert_no_error (error);
  g_assert_true (res);

  remote = flatpak_installation_get_remote_by_name (inst, "hello-origin", NULL, &error);
  g_assert_no_error (error);
  g_assert_nonnull (remote);
}

/* Test that we pull the runtime from the same remote as the app even if
 * another remote also provides the runtime and sorts earlier via strcmp() */
static void
test_transaction_app_runtime_same_remote (void)
{
  g_autoptr(FlatpakInstallation) inst = NULL;
  g_autoptr(FlatpakTransaction) transaction = NULL;
  g_autoptr(FlatpakInstalledRef) installed_runtime = NULL;
  g_autoptr(GError) error = NULL;
  g_autofree char *app = NULL;
  const char *runtime_origin;
  gboolean res;

  app = g_strdup_printf ("app/org.test.Hello/%s/master",
                         flatpak_get_default_arch ());

  inst = flatpak_installation_new_user (NULL, &error);
  g_assert_no_error (error);
  g_assert_nonnull (inst);

  empty_installation (inst);

  add_remote_user ("test-runtime-only", "aaatest-runtime-only-repo");

  /* Drop caches so we find the new remote */
  flatpak_installation_drop_caches (inst, NULL, &error);
  g_assert_no_error (error);

  /* Even with aaatest-runtime-only-repo sorting before test-repo, the runtime
   * should come from test-repo */
  g_assert_true (strcmp ("aaatest-runtime-only-repo", "test-repo") < 0);

  transaction = flatpak_transaction_new_for_installation (inst, NULL, &error);
  g_assert_no_error (error);
  g_assert_nonnull (transaction);

  res = flatpak_transaction_add_install (transaction, repo_name, app, NULL, &error);
  g_assert_no_error (error);
  g_assert_true (res);

  res = flatpak_transaction_run (transaction, NULL, &error);
  g_assert_no_error (error);
  g_assert_true (res);

  installed_runtime = flatpak_installation_get_installed_ref (inst,
                                                              FLATPAK_REF_KIND_RUNTIME,
                                                              "org.test.Platform",
                                                              flatpak_get_default_arch (),
                                                              "master", NULL, &error);
  g_assert_nonnull (installed_runtime);
  g_assert_no_error (error);

  runtime_origin = flatpak_installed_ref_get_origin (installed_runtime);
  g_assert_nonnull (runtime_origin);
  g_assert_cmpstr (runtime_origin, ==, repo_name);

  /* Reset things */
  empty_installation (inst);
  remove_remote_user ("aaatest-runtime-only-repo");
}

/* Test that an installed related ref is updated from its origin remote even if
 * the thing it's related to comes from a different remote which also provides
 * the related ref */
static void
test_transaction_update_related_from_different_remote (void)
{
  g_autoptr(FlatpakInstallation) inst = NULL;
  g_autoptr(FlatpakTransaction) transaction = NULL;
  g_autoptr(FlatpakInstalledRef) installed_ref = NULL;
  g_autoptr(FlatpakRemoteRef) remote_ref = NULL;
  g_autoptr(GError) error = NULL;
  g_autofree char *app = NULL;
  g_autofree char *app_plugin = NULL;
  const char *app_origin = repo_name;
  const char *app_plugin_origin = "test-without-runtime-repo";
  gboolean res;

  app = g_strdup_printf ("app/org.test.Hello/%s/master",
                         flatpak_get_default_arch ());
  app_plugin = g_strdup_printf ("runtime/org.test.Hello.Plugin.fun/%s/v1",
                                flatpak_get_default_arch ());

  inst = flatpak_installation_new_user (NULL, &error);
  g_assert_no_error (error);
  g_assert_nonnull (inst);

  empty_installation (inst);

  add_remote_user ("test-without-runtime", NULL);

  /* Drop caches so we find the new remote */
  flatpak_installation_drop_caches (inst, NULL, &error);
  g_assert_no_error (error);

  /* Install the plugin only from its remote */
  transaction = flatpak_transaction_new_for_installation (inst, NULL, &error);
  g_assert_no_error (error);
  g_assert_nonnull (transaction);

  res = flatpak_transaction_add_install (transaction, app_plugin_origin, app_plugin, NULL, &error);
  g_assert_no_error (error);
  g_assert_true (res);

  res = flatpak_transaction_run (transaction, NULL, &error);
  g_assert_no_error (error);
  g_assert_true (res);

  /* Update the related ref in the main repo, so we can check that it's not
   * updated since we should check for updates in its origin repo */
  update_test_app_extension ();
  update_repo ("test");

  /* Install the app from the main remote. The plugin should not be updated */
  g_clear_object (&transaction);
  transaction = flatpak_transaction_new_for_installation (inst, NULL, &error);
  g_assert_no_error (error);
  g_assert_nonnull (transaction);

  res = flatpak_transaction_add_install (transaction, app_origin, app, NULL, &error);
  g_assert_no_error (error);
  g_assert_true (res);

  res = flatpak_transaction_run (transaction, NULL, &error);
  g_assert_no_error (error);
  g_assert_true (res);

  /* Check to make sure the plugin is on a different commit locally than in the
   * main remote */
  installed_ref = flatpak_installation_get_installed_ref (inst, FLATPAK_REF_KIND_RUNTIME,
                                                          "org.test.Hello.Plugin.fun",
                                                          NULL, "v1", NULL, &error);
  g_assert_no_error (error);
  g_assert_nonnull (installed_ref);

  remote_ref = flatpak_installation_fetch_remote_ref_sync (inst, app_origin, FLATPAK_REF_KIND_RUNTIME,
                                                          "org.test.Hello.Plugin.fun",
                                                          NULL, "v1", NULL, &error);
  g_assert_no_error (error);
  g_assert_nonnull (remote_ref);

  g_assert_cmpstr (flatpak_installed_ref_get_origin (installed_ref), !=, app_origin);
  g_assert_cmpstr (flatpak_ref_get_commit (FLATPAK_REF (installed_ref)), ==,
                   flatpak_installed_ref_get_latest_commit (installed_ref));
  g_assert_cmpstr (flatpak_ref_get_commit (FLATPAK_REF (installed_ref)), !=,
                   flatpak_ref_get_commit (FLATPAK_REF (remote_ref)));

  /* Reset things */
  empty_installation (inst);
  remove_remote_user ("test-without-runtime-repo");
}

static gboolean
ready_set_nodeps_on_remote (FlatpakTransaction *transaction)
{
  g_autoptr(FlatpakInstallation) installation = NULL;
  g_autoptr(FlatpakRemote) remote = NULL;
  g_autoptr(GError) error = NULL;
  gboolean res;

  installation = flatpak_transaction_get_installation (transaction);

  /* Set the nodeps option on the runtime remote */
  remote = flatpak_installation_get_remote_by_name (installation, "test-runtime-only-repo", NULL, &error);
  g_assert_no_error (error);
  g_assert_nonnull (remote);
  g_assert_false (flatpak_remote_get_nodeps (remote));

  flatpak_remote_set_nodeps (remote, TRUE);
  res = flatpak_installation_modify_remote (installation, remote, NULL, &error);
  g_assert_no_error (error);
  g_assert_true (res);

  /* Abort since this transaction is already resolved; we need a new one */
  return FALSE;
}

/* Test that setting xa.nodeps=true on the remote providing the runtime causes
 * app installation to fail */
static void
test_remote_nodeps_option (void)
{
  g_autoptr(FlatpakInstallation) user_inst = NULL;
  g_autoptr(FlatpakRemote) remote = NULL;
  g_autoptr(FlatpakTransaction) transaction = NULL;
  g_autoptr(GError) error = NULL;
  g_autofree char *s = NULL;
  g_autoptr(GBytes) data = NULL;
  gboolean res;

  user_inst = flatpak_installation_new_user (NULL, &error);
  g_assert_no_error (error);
  g_assert_nonnull (user_inst);

  empty_installation (user_inst);

  assert_remote_not_in_installation (user_inst, "hello-origin");
  assert_remote_not_in_installation (user_inst, "test-runtime-only-repo");

  /* Set the nodeps option on the test-repo remote */
  remote = flatpak_installation_get_remote_by_name (user_inst, "test-repo", NULL, &error);
  g_assert_no_error (error);
  g_assert_nonnull (remote);
  g_assert_false (flatpak_remote_get_nodeps (remote));
  flatpak_remote_set_nodeps (remote, TRUE);
  res = flatpak_installation_modify_remote (user_inst, remote, NULL, &error);
  g_assert_no_error (error);
  g_assert_true (res);

  transaction = flatpak_transaction_new_for_installation (user_inst, NULL, &error);
  g_assert_no_error (error);
  g_assert_nonnull (transaction);

  s = g_strconcat ("[Flatpak Ref]\n"
                   "Title=Test App\n"
                   "Name=org.test.Hello\n"
                   "Branch=master\n"
                   "Url=http://127.0.0.1:", httpd_port, "/test-without-runtime\n"
                   "IsRuntime=False\n"
                   "RuntimeRepo=http://127.0.0.1:", httpd_port, "/test-runtime-only/test-runtime-only-repo.flatpakrepo\n",
                   NULL);

  data = g_bytes_new (s, strlen (s));
  res = flatpak_transaction_add_install_flatpakref (transaction, data, &error);
  g_assert_no_error (error);
  g_assert_true (res);

  g_signal_connect (transaction, "add-new-remote", G_CALLBACK (add_new_remote3), NULL);
  g_signal_connect (transaction, "ready", G_CALLBACK (ready_set_nodeps_on_remote), NULL);

  res = flatpak_transaction_run (transaction, NULL, &error);
  g_assert_error (error, FLATPAK_ERROR, FLATPAK_ERROR_ABORTED);
  g_assert_false (res);
  g_clear_error (&error);

  /* Make a new transaction so the runtime resolution happens again */
  g_clear_object (&transaction);
  transaction = flatpak_transaction_new_for_installation (user_inst, NULL, &error);
  g_assert_no_error (error);
  g_assert_nonnull (transaction);
  res = flatpak_transaction_add_install_flatpakref (transaction, data, &error);
  g_assert_no_error (error);
  g_assert_true (res);
  g_signal_connect (transaction, "add-new-remote", G_CALLBACK (add_new_remote3), NULL);

  res = flatpak_transaction_run (transaction, NULL, &error);
  g_assert_error (error, FLATPAK_ERROR, FLATPAK_ERROR_RUNTIME_NOT_FOUND);
  g_assert_false (res);
  g_clear_error (&error);

  /* Set nodeps back to false */
  flatpak_remote_set_nodeps (remote, FALSE);
  res = flatpak_installation_modify_remote (user_inst, remote, NULL, &error);
  g_assert_no_error (error);
  g_assert_true (res);

  empty_installation (user_inst);
  remove_remote_user ("hello-origin");
  remove_remote_user ("test-runtime-only-repo");
}

typedef struct
{
  GMainLoop *loop;
  guint      stop_waiting_id;
  guint      hello_dead_cb_id;
  gboolean   hello_dead;
} TestInstanceContext;

static gboolean
stop_waiting (gpointer data)
{
  TestInstanceContext *context = data;

  g_main_loop_quit (context->loop);
  context->stop_waiting_id = 0;

  return G_SOURCE_REMOVE;
}

static void
hello_dead_cb (GPid     pid,
               int      status,
               gpointer data)
{
  TestInstanceContext *context = data;

  context->hello_dead = TRUE;
  context->hello_dead_cb_id = 0;

  g_main_loop_quit (context->loop);
}

/* test the instance api: install an app, launch it, get the instance,
 * kill it, wait for it to die
 */
static void
test_instance (void)
{
  g_autoptr(FlatpakInstallation) inst = NULL;
  g_autoptr(FlatpakTransaction) transaction = NULL;
  g_autoptr(GError) error = NULL;
  gboolean res;
  g_autoptr(GPtrArray) instances = NULL;
  g_autoptr(FlatpakInstance) instance = NULL;
  GKeyFile *info;
  int i;
  g_autofree char *app = NULL;
  g_autofree char *runtime = NULL;
  TestInstanceContext context = { NULL, 0, 0, FALSE };

  app = g_strdup_printf ("app/org.test.Hello/%s/master",
                         flatpak_get_default_arch ());
  runtime = g_strdup_printf ("runtime/org.test.Platform/%s/master",
                             flatpak_get_default_arch ());

  update_test_app ();
  update_repo ("test");

  if (!check_bwrap_support ())
    {
      g_test_skip ("bwrap not supported");
      return;
    }

  inst = flatpak_installation_new_user (NULL, &error);
  g_assert_no_error (error);
  g_assert_nonnull (inst);

  empty_installation (inst);

  transaction = flatpak_transaction_new_for_installation (inst, NULL, &error);
  g_assert_no_error (error);
  g_assert_nonnull (transaction);

  res = flatpak_transaction_add_install (transaction, repo_name, app, NULL, &error);
  g_assert_no_error (error);
  g_assert_true (res);

  res = flatpak_transaction_run (transaction, NULL, &error);
  g_assert_no_error (error);
  g_assert_true (res);

  g_clear_object (&transaction);

  {
    TESTS_SCOPED_STDOUT_TO_STDERR;
    res = flatpak_installation_launch_full (inst, FLATPAK_LAUNCH_FLAGS_DO_NOT_REAP,
                                            "org.test.Hello", NULL, NULL, NULL, &instance, NULL, &error);
  }
  g_assert_no_error (error);
  g_assert_true (res);
  g_assert_nonnull (instance);

  instances = flatpak_instance_get_all ();
  for (i = 0; i < instances->len; i++)
    {
      FlatpakInstance *instance2 = g_ptr_array_index (instances, i);
      if (strcmp (flatpak_instance_get_id (instance), flatpak_instance_get_id (instance2)) == 0)
        break;
    }
  g_assert_cmpint (i, <, instances->len);
  g_clear_pointer (&instances, g_ptr_array_unref);

  g_assert_true (flatpak_instance_is_running (instance));

  g_assert_nonnull (flatpak_instance_get_id (instance));
  info = flatpak_instance_get_info (instance);
  g_assert_nonnull (info);
  assert_cmpstr_free_lhs (g_key_file_get_string (info, "Application", "name", &error),
                          ==, "org.test.Hello");
  assert_cmpstr_free_lhs (g_key_file_get_string (info, "Instance", "instance-id", &error),
                          ==, flatpak_instance_get_id (instance));

  g_assert_cmpstr (flatpak_instance_get_app (instance), ==, "org.test.Hello");
  g_assert_cmpstr (flatpak_instance_get_arch (instance), ==,
                   flatpak_get_default_arch ());
  g_assert_cmpstr (flatpak_instance_get_branch (instance), ==, "master");
  g_assert_nonnull (flatpak_instance_get_commit (instance));
  g_assert_cmpstr (flatpak_instance_get_runtime (instance), ==, runtime);
  g_assert_nonnull (flatpak_instance_get_runtime_commit (instance));
  g_assert_cmpint (flatpak_instance_get_pid (instance), >, 0);
  while (flatpak_instance_get_child_pid (instance) == 0)
    g_usleep (10000);
  g_assert_cmpint (flatpak_instance_get_child_pid (instance), >, 0);

  context.loop = g_main_loop_new (NULL, FALSE);

  context.hello_dead = FALSE;
  context.hello_dead_cb_id = g_child_watch_add (flatpak_instance_get_pid (instance),
                                                hello_dead_cb, &context);
  context.stop_waiting_id = g_timeout_add (5000, stop_waiting, &context);

  kill (flatpak_instance_get_child_pid (instance), SIGKILL);

  g_main_loop_run (context.loop);

  if (context.hello_dead_cb_id != 0)
    g_source_remove (context.hello_dead_cb_id);

  if (context.stop_waiting_id != 0)
    g_source_remove (context.stop_waiting_id);

  g_main_loop_unref (context.loop);

  g_assert_true (context.hello_dead);
  g_assert_false (flatpak_instance_is_running (instance));

  transaction = flatpak_transaction_new_for_installation (inst, NULL, &error);
  g_assert_no_error (error);
  g_assert_nonnull (transaction);

  res = flatpak_transaction_add_uninstall (transaction, app, &error);
  g_assert_no_error (error);
  g_assert_true (res);

  res = flatpak_transaction_run (transaction, NULL, &error);
  g_assert_no_error (error);
  g_assert_true (res);
}

static void
test_update_subpaths (void)
{
  g_autoptr(FlatpakInstallation) inst = NULL;
  g_autoptr(FlatpakInstalledRef) ref = NULL;
  gboolean res;
  g_autoptr(GError) error = NULL;
  g_autoptr(FlatpakTransaction) transaction = NULL;
  const char * const *subpaths;
  const char * subpaths2[] = { "/de", "/fr", NULL };
  g_autofree char *app = NULL;

  app = g_strdup_printf ("app/org.test.Hello/%s/master",
                         flatpak_get_default_arch ());

  inst = flatpak_installation_new_user (NULL, &error);
  g_assert_no_error (error);
  g_assert_nonnull (inst);

  empty_installation (inst);

  transaction = flatpak_transaction_new_for_installation (inst, NULL, &error);
  g_assert_no_error (error);
  g_assert_nonnull (transaction);

  res = flatpak_transaction_add_install (transaction, repo_name, app, NULL, &error);
  g_assert_no_error (error);
  g_assert_true (res);

  res = flatpak_transaction_run (transaction, NULL, &error);
  g_assert_no_error (error);
  g_assert_true (res);

  g_clear_object (&transaction);

  ref = flatpak_installation_get_installed_ref (inst, FLATPAK_REF_KIND_RUNTIME, "org.test.Hello.Locale", flatpak_get_default_arch (), "master", NULL, &error);
  g_assert_no_error (error);

  subpaths = flatpak_installed_ref_get_subpaths (ref);
  g_assert_cmpint (g_strv_length ((char **) subpaths), ==, 1);
  g_assert_cmpstr (subpaths[0], ==, "/de");

  g_clear_object (&transaction);
  g_clear_object (&ref);

  G_GNUC_BEGIN_IGNORE_DEPRECATIONS
  ref = flatpak_installation_update_full (inst, 0, FLATPAK_REF_KIND_RUNTIME, "org.test.Hello.Locale", flatpak_get_default_arch (), "master", subpaths2, NULL, NULL, NULL, &error);
  G_GNUC_END_IGNORE_DEPRECATIONS
  g_assert_no_error (error);

  subpaths = flatpak_installed_ref_get_subpaths (ref);
  g_assert_cmpint (g_strv_length ((char **) subpaths), ==, 2);
  g_assert_cmpstr (subpaths[0], ==, "/de");
  g_assert_cmpstr (subpaths[1], ==, "/fr");
}

static void
test_overrides (void)
{
  g_autoptr(FlatpakInstallation) inst = NULL;
  g_autoptr(GError) error = NULL;
  g_autofree char *data = NULL;
  g_autoptr(GKeyFile) overrides = NULL;
  gboolean res;
  g_autoptr(FlatpakInstalledRef) ref = NULL;
  g_auto(GStrv) list = NULL;
  gsize len;

  if (!check_bwrap_support ())
    {
      g_test_skip ("bwrap not supported");
      return;
    }

  /* no library api to set overrides, so... */
  const char *argv[] = { "flatpak", "override", "--user",
                         "--allow=bluetooth",
                         "--disallow=canbus",
                         "--device=dri",
                         "--nodevice=kvm",
                         "--filesystem=xdg-music",
                         "--filesystem=~/foo:ro",
                         "--filesystem=xdg-download/subdir:create",
                         "--env=FOO=BAR",
                         "--own-name=foo.bar.baz",
                         "--talk-name=hello.bla.bla.*",
                         "--socket=wayland",
                         "--nosocket=pulseaudio",
                         "org.test.Hello",
                         NULL };
  run_test_subprocess ((char **) argv, RUN_TEST_SUBPROCESS_DEFAULT);

  inst = flatpak_installation_new_user (NULL, &error);
  g_assert_no_error (error);
  g_assert_nonnull (inst);

  empty_installation (inst);

  G_GNUC_BEGIN_IGNORE_DEPRECATIONS
  ref = flatpak_installation_update (inst, 0, FLATPAK_REF_KIND_APP, "org.test.Hello", NULL, "master", NULL, NULL, NULL, &error);
  G_GNUC_END_IGNORE_DEPRECATIONS
  g_assert_error (error, FLATPAK_ERROR, FLATPAK_ERROR_NOT_INSTALLED);
  g_assert_null (ref);
  g_clear_error (&error);

  G_GNUC_BEGIN_IGNORE_DEPRECATIONS
  ref = flatpak_installation_install (inst, repo_name, FLATPAK_REF_KIND_APP, "org.test.Hello", NULL, "master", NULL, NULL, NULL, &error);
  G_GNUC_END_IGNORE_DEPRECATIONS
  g_assert_no_error (error);
  g_assert_nonnull (ref);
  g_clear_object (&ref);

  G_GNUC_BEGIN_IGNORE_DEPRECATIONS
  ref = flatpak_installation_install (inst, repo_name, FLATPAK_REF_KIND_RUNTIME, "org.test.Platform", NULL, "master", NULL, NULL, NULL, &error);
  G_GNUC_END_IGNORE_DEPRECATIONS
  g_assert_no_error (error);
  g_assert_nonnull (ref);
  g_clear_object (&ref);

  {
    TESTS_SCOPED_STDOUT_TO_STDERR;
    res = flatpak_installation_launch (inst, "org.test.Hello", NULL, "master", NULL, NULL, &error);
  }
  g_assert_no_error (error);
  g_assert_true (res);

  data = flatpak_installation_load_app_overrides (inst, "org.test.Hello", NULL, &error);
  g_assert_no_error (error);
  g_assert_nonnull (data);

  overrides = g_key_file_new ();
  res = g_key_file_load_from_data (overrides, data, -1, 0, &error);
  g_assert_no_error (error);
  g_assert_true (res);

  assert_cmpstr_free_lhs (g_key_file_get_string (overrides, "Context", "devices", &error),
                          ==, "dri;!kvm;");

  assert_cmpstr_free_lhs (g_key_file_get_string (overrides, "Context", "features", &error),
                          ==, "bluetooth;!canbus;");

  list = g_key_file_get_string_list (overrides, "Context", "filesystems", &len, &error);
  g_assert_cmpint (len, ==, 3);
  g_assert_true (g_strv_contains ((const char * const *) list, "xdg-download/subdir:create"));
  g_assert_true (g_strv_contains ((const char * const *) list, "xdg-music"));
  g_assert_true (g_strv_contains ((const char * const *) list, "~/foo:ro"));
  g_clear_pointer (&list, g_strfreev);

  list = g_key_file_get_string_list (overrides, "Context", "sockets", &len, &error);
  g_assert_cmpint (len, ==, 2);
  g_assert_true (g_strv_contains ((const char * const *) list, "wayland"));
  g_assert_true (g_strv_contains ((const char * const *) list, "!pulseaudio"));
  g_clear_pointer (&list, g_strfreev);

  assert_cmpstr_free_lhs (g_key_file_get_string (overrides, "Session Bus Policy", "hello.bla.bla.*", &error),
                          ==, "talk");

  assert_cmpstr_free_lhs (g_key_file_get_string (overrides, "Session Bus Policy", "foo.bar.baz", &error),
                          ==, "own");

  assert_cmpstr_free_lhs (g_key_file_get_string (overrides, "Environment", "FOO", &error),
                          ==, "BAR");

  const char *argv2[] = { "flatpak", "override", "--user", "--reset", "org.test.Hello", NULL };
  run_test_subprocess ((char **) argv2, RUN_TEST_SUBPROCESS_DEFAULT);
}

/* basic tests for bundle ref apis */
static void
test_bundle (void)
{
  g_autoptr(FlatpakBundleRef) ref = NULL;
  g_autoptr(GFile) file = NULL;
  g_autoptr(GError) error = NULL;
  g_autofree char *path = NULL;
  g_autoptr(GFile) file2 = NULL;
  g_autofree char *origin = NULL;
  g_autofree char *repo_url = g_strdup_printf ("http://127.0.0.1:%s/test", httpd_port);
  g_autoptr(GBytes) metadata = NULL;
  g_autoptr(GBytes) appstream = NULL;
  g_autoptr(GBytes) icon = NULL;

  file = g_file_new_for_path ("/dev/null");

  ref = flatpak_bundle_ref_new (file, &error);
  g_assert_nonnull (error);
  g_assert_null (ref);
  g_clear_error (&error);

  g_clear_object (&file);

  path = g_build_filename (testdir, "bundles", "hello.flatpak", NULL);
  file = g_file_new_for_path (path);
  ref = flatpak_bundle_ref_new (file, &error);
  g_assert_no_error (error);
  g_assert_nonnull (ref);

  g_assert_cmpstr (flatpak_ref_get_name (FLATPAK_REF (ref)), ==, "org.test.Hello");
  g_assert_cmpstr (flatpak_ref_get_arch (FLATPAK_REF (ref)), ==, flatpak_get_default_arch ());
  g_assert_cmpstr (flatpak_ref_get_branch (FLATPAK_REF (ref)), ==, "master");
  g_assert_cmpint (flatpak_ref_get_kind (FLATPAK_REF (ref)), ==, FLATPAK_REF_KIND_APP);
  g_assert_cmpstr (flatpak_ref_get_collection_id (FLATPAK_REF (ref)), ==, "com.example.Test");

  file2 = flatpak_bundle_ref_get_file (ref);
  g_assert_true (g_file_equal (file, file2));

  origin = flatpak_bundle_ref_get_origin (ref);
  g_assert_cmpstr (origin, ==, repo_url);

  g_assert_null (flatpak_bundle_ref_get_runtime_repo_url (ref));

  g_assert_cmpint (flatpak_bundle_ref_get_installed_size (ref), >, 0);

  metadata = flatpak_bundle_ref_get_metadata (ref);
  g_assert_nonnull (metadata);
  /* FIXME verify format */

  appstream = flatpak_bundle_ref_get_appstream (ref);
  g_assert_nonnull (appstream);
  /* FIXME verify format */

  icon = flatpak_bundle_ref_get_icon (ref, 64);
  g_assert_nonnull (icon);
  /* FIXME verify format */
  g_clear_pointer (&icon, g_bytes_unref);

  icon = flatpak_bundle_ref_get_icon (ref, 128);
  g_assert_null (icon);
  g_clear_pointer (&icon, g_bytes_unref);

  g_clear_object (&file2);

  g_object_get (ref, "file", &file2, NULL);
  g_assert_true (g_file_equal (file, file2));
}

/* use the installation api to install a bundle */
static void
test_install_bundle (void)
{
  g_autoptr(FlatpakInstallation) inst = NULL;
  g_autoptr(GError) error = NULL;
  g_autoptr(GFile) file = NULL;
  g_autofree char *path = NULL;
  g_autoptr(FlatpakInstalledRef) ref = NULL;

  inst = flatpak_installation_new_user (NULL, &error);
  g_assert_no_error (error);
  g_assert_nonnull (inst);

  empty_installation (inst);

  path = g_build_filename (testdir, "bundles", "hello.flatpak", NULL);
  file = g_file_new_for_path (path);

  G_GNUC_BEGIN_IGNORE_DEPRECATIONS
  ref = flatpak_installation_install_bundle (inst, file, NULL, NULL, NULL, &error);
  G_GNUC_END_IGNORE_DEPRECATIONS
  g_assert_no_error (error);
  g_assert_nonnull (ref);
}

/* use the installation api to install a flatpakref */
static void
test_install_flatpakref (void)
{
  g_autoptr(FlatpakInstallation) inst = NULL;
  g_autoptr(GError) error = NULL;
  g_autoptr(FlatpakRemoteRef) ref = NULL;
  g_autofree char *s = NULL;
  g_autoptr(GBytes) data = NULL;

  inst = flatpak_installation_new_user (NULL, &error);
  g_assert_no_error (error);
  g_assert_nonnull (inst);

  empty_installation (inst);

  s = g_strconcat ("[Flatpak Ref]\n"
                   "Title=Test App\n"
                   "Name=org.test.Hello\n"
                   "Branch=master\n"
                   "Url=http://127.0.0.1:", httpd_port, "/test\n"
                   "IsRuntime=false\n"
                   "SuggestRemoteName=test-repo\n"
                   "RuntimeRepo=http://127.0.0.1:", httpd_port, "/test/test-repo.flatpakrepo\n",
                   NULL);
  data = g_bytes_new (s, strlen (s));

  G_GNUC_BEGIN_IGNORE_DEPRECATIONS
  ref = flatpak_installation_install_ref_file (inst, data, NULL, &error);
  G_GNUC_END_IGNORE_DEPRECATIONS
  g_assert_no_error (error);
  g_assert_nonnull (ref);
}

/* test the installation method to list installed related refs */
static void
test_list_installed_related_refs (void)
{
  g_autoptr(FlatpakInstallation) inst = NULL;
  g_autoptr(FlatpakTransaction) transaction = NULL;
  g_autoptr(GPtrArray) refs = NULL;
  g_autoptr(GError) error = NULL;
  FlatpakRelatedRef *ref;
  FlatpakInstalledRef *iref;
  gboolean res;
  g_autofree char *app = NULL;

  app = g_strdup_printf ("app/org.test.Hello/%s/master",
                         flatpak_get_default_arch ());

  inst = flatpak_installation_new_user (NULL, &error);
  g_assert_no_error (error);
  g_assert_nonnull (inst);

  empty_installation (inst);

  refs = flatpak_installation_list_installed_related_refs_sync (inst, repo_name, app, NULL, &error);
  g_assert_error (error, FLATPAK_ERROR, FLATPAK_ERROR_NOT_INSTALLED);
  g_assert_null (refs);
  g_clear_error (&error);

  G_GNUC_BEGIN_IGNORE_DEPRECATIONS
  iref = flatpak_installation_install (inst, repo_name, FLATPAK_REF_KIND_APP, "org.test.Hello", NULL, "master", NULL, NULL, NULL, &error);
  G_GNUC_END_IGNORE_DEPRECATIONS
  g_assert_no_error (error);
  g_assert_nonnull (iref);
  g_clear_object (&iref);

  refs = flatpak_installation_list_installed_related_refs_sync (inst, repo_name, app, NULL, &error);
  g_assert_no_error (error);
  g_assert_nonnull (refs);
  g_assert_cmpint (refs->len, ==, 0);
  g_clear_pointer (&refs, g_ptr_array_unref);

  transaction = flatpak_transaction_new_for_installation (inst, NULL, &error);
  g_assert_no_error (error);
  g_assert_nonnull (transaction);

  res = flatpak_transaction_add_update (transaction, app, NULL, NULL, &error);
  g_assert_no_error (error);
  g_assert_true (res);

  res = flatpak_transaction_run (transaction, NULL, &error);
  g_assert_no_error (error);
  g_assert_true (res);

  g_clear_object (&transaction);

  refs = flatpak_installation_list_installed_related_refs_sync (inst, repo_name, app, NULL, &error);
  g_assert_no_error (error);
  g_assert_nonnull (refs);
  g_assert_cmpint (refs->len, ==, 1);

  ref = g_ptr_array_index (refs, 0);

  g_assert_cmpstr (flatpak_ref_get_name (FLATPAK_REF (ref)), ==, "org.test.Hello.Locale");
  g_assert_true (flatpak_related_ref_should_download (ref));
  g_assert_true (flatpak_related_ref_should_delete (ref));
  g_assert_false (flatpak_related_ref_should_autoprune (ref));
  g_assert_true (g_strv_length ((char **) flatpak_related_ref_get_subpaths (ref)) == 1);
  g_assert_cmpstr (flatpak_related_ref_get_subpaths (ref)[0], ==, "/de");

  g_clear_pointer (&refs, g_ptr_array_unref);

  // Make the test with extra-languages, instead of languages
  clean_languages();
  configure_extra_languages();
  empty_installation (inst);

  refs = flatpak_installation_list_installed_related_refs_sync (inst, repo_name, app, NULL, &error);
  g_assert_error (error, FLATPAK_ERROR, FLATPAK_ERROR_NOT_INSTALLED);
  g_assert_null (refs);
  g_clear_error (&error);

  G_GNUC_BEGIN_IGNORE_DEPRECATIONS
  iref = flatpak_installation_install (inst, repo_name, FLATPAK_REF_KIND_APP, "org.test.Hello", NULL, "master", NULL, NULL, NULL, &error);
  G_GNUC_END_IGNORE_DEPRECATIONS
  g_assert_no_error (error);
  g_assert_nonnull (iref);
  g_clear_object (&iref);

  refs = flatpak_installation_list_installed_related_refs_sync (inst, repo_name, app, NULL, &error);
  g_assert_no_error (error);
  g_assert_nonnull (refs);
  g_assert_cmpint (refs->len, ==, 0);
  g_clear_pointer (&refs, g_ptr_array_unref);

  transaction = flatpak_transaction_new_for_installation (inst, NULL, &error);
  g_assert_no_error (error);
  g_assert_nonnull (transaction);

  res = flatpak_transaction_add_update (transaction, app, NULL, NULL, &error);
  g_assert_no_error (error);
  g_assert_true (res);

  res = flatpak_transaction_run (transaction, NULL, &error);
  g_assert_no_error (error);
  g_assert_true (res);

  g_clear_object (&transaction);

  refs = flatpak_installation_list_installed_related_refs_sync (inst, repo_name, app, NULL, &error);
  g_assert_no_error (error);
  g_assert_nonnull (refs);
  g_assert_cmpint (refs->len, ==, 1);

  ref = g_ptr_array_index (refs, 0);

  g_assert_cmpstr (flatpak_ref_get_name (FLATPAK_REF (ref)), ==, "org.test.Hello.Locale");
  g_assert_true (flatpak_related_ref_should_download (ref));
  g_assert_true (flatpak_related_ref_should_delete (ref));
  g_assert_false (flatpak_related_ref_should_autoprune (ref));
  g_assert_true (g_strv_length ((char **) flatpak_related_ref_get_subpaths (ref)) == 2);
  g_assert_cmpstr (flatpak_related_ref_get_subpaths (ref)[0], ==, "/de");
  g_assert_cmpstr (flatpak_related_ref_get_subpaths (ref)[1], ==, "/en");

  configure_languages ("de");
  clean_extra_languages ();
}

static void
test_no_deploy (void)
{
  g_autoptr(FlatpakInstallation) inst = NULL;
  g_autoptr(GError) error = NULL;
  g_autoptr(FlatpakInstalledRef) ref = NULL;
  gboolean res;
  g_autofree char *app = NULL;

  app = g_strdup_printf ("app/org.test.Hello/%s/master",
                         flatpak_get_default_arch ());

  inst = flatpak_installation_new_user (NULL, &error);
  g_assert_no_error (error);
  g_assert_nonnull (inst);

  empty_installation (inst);

  G_GNUC_BEGIN_IGNORE_DEPRECATIONS
  ref = flatpak_installation_install_full (inst,
                                           FLATPAK_INSTALL_FLAGS_NO_DEPLOY,
                                           repo_name,
                                           FLATPAK_REF_KIND_APP,
                                           "org.test.Hello",
                                           NULL,
                                           "master",
                                           NULL,
                                           NULL,
                                           NULL,
                                           NULL,
                                           &error);
  G_GNUC_END_IGNORE_DEPRECATIONS
  g_assert_error (error, FLATPAK_ERROR, FLATPAK_ERROR_ONLY_PULLED);
  g_assert_null (ref);
  g_clear_error (&error);

  res = flatpak_installation_remove_local_ref_sync (inst,
                                                    repo_name,
                                                    app,
                                                    NULL,
                                                    &error);
  g_assert_no_error (error);
  g_assert_true (res);

  res = flatpak_installation_prune_local_repo (inst, NULL, &error);
  g_assert_no_error (error);
  g_assert_true (res);
}

static void
test_bad_remote_name (void)
{
  g_autoptr(FlatpakInstallation) inst = NULL;
  g_autoptr(GError) error = NULL;
  g_autoptr(FlatpakRemote) remote = NULL;
  gboolean res;

  inst = flatpak_installation_new_user (NULL, &error);
  g_assert_no_error (error);
  g_assert_nonnull (inst);

  empty_installation (inst);

  remote = flatpak_remote_new ("3X \n bad");
  flatpak_remote_set_url (remote, "not a url at all");

  res = flatpak_installation_modify_remote (inst, remote, NULL, &error);
  g_assert_error (error, FLATPAK_ERROR, FLATPAK_ERROR_INVALID_DATA);
  g_assert_false (res);
}

/* Disable all remotes, and install an app from a repo that does not have the runtime.
 * We expect an error.
 */
static void
test_transaction_no_runtime (void)
{
  g_autoptr(FlatpakInstallation) inst = NULL;
  g_autoptr(GError) error = NULL;
  g_autoptr(FlatpakTransaction) transaction = NULL;
  gboolean res;
  g_autofree char *s = NULL;
  g_autoptr(GBytes) data = NULL;
  FlatpakRemote *remote = NULL;
  g_autoptr(GPtrArray) remotes = NULL;
  int i;

  inst = flatpak_installation_new_user (NULL, &error);
  g_assert_no_error (error);
  g_assert_nonnull (inst);

  empty_installation (inst);

  remotes = flatpak_installation_list_remotes (inst, NULL, &error);
  g_assert_no_error (error);
  for (i = 0; i < remotes->len; i++)
    {
      remote = g_ptr_array_index (remotes, i);
      flatpak_remote_set_disabled (remote, TRUE);
      res = flatpak_installation_modify_remote (inst, remote, NULL, &error);
      g_assert_no_error (error);
      g_assert_true (res);
    }

  transaction = flatpak_transaction_new_for_installation (inst, NULL, &error);
  g_assert_no_error (error);
  g_assert_nonnull (transaction);

  s = g_strconcat ("[Flatpak Ref]\n"
                   "Title=Test App\n"
                   "Name=org.test.Hello\n"
                   "Branch=master\n"
                   "Url=http://127.0.0.1:", httpd_port, "/test-without-runtime\n"
                   "IsRuntime=false\n"
                   "SuggestRemoteName=my-little-repo\n"
                   "RuntimeRepo=http://127.0.0.1:", httpd_port, "/test/test-repo.flatpakrepo\n",
                   NULL);

  data = g_bytes_new (s, strlen (s));
  res = flatpak_transaction_add_install_flatpakref (transaction, data, &error);
  g_assert_no_error (error);
  g_assert_true (res);

  res = flatpak_transaction_run (transaction, NULL, &error);
  g_assert_error (error, FLATPAK_ERROR, FLATPAK_ERROR_RUNTIME_NOT_FOUND);
  g_assert_false (res);
  g_clear_error (&error);

  for (i = 0; i < remotes->len; i++)
    {
      remote = g_ptr_array_index (remotes, i);
      flatpak_remote_set_disabled (remote, FALSE);
      res = flatpak_installation_modify_remote (inst, remote, NULL, &error);
      g_assert_no_error (error);
      g_assert_true (res);
    }
}

static void
test_installation_no_interaction (void)
{
  g_autoptr(FlatpakInstallation) inst = NULL;
  g_autoptr(GError) error = NULL;

  inst = flatpak_installation_new_user (NULL, &error);
  g_assert_no_error (error);

  g_assert_false (flatpak_installation_get_no_interaction (inst));
  flatpak_installation_set_no_interaction (inst, TRUE);
  g_assert_true (flatpak_installation_get_no_interaction (inst));
}

static void
test_installation_unused_refs (void)
{
  g_autoptr(FlatpakInstallation) inst = NULL;
  g_autoptr(GError) error = NULL;
  g_autoptr(GPtrArray) refs = NULL;
  FlatpakInstalledRef *iref;

  inst = flatpak_installation_new_user (NULL, &error);
  g_assert_no_error (error);

  empty_installation (inst);

  G_GNUC_BEGIN_IGNORE_DEPRECATIONS
  iref = flatpak_installation_install (inst, repo_name, FLATPAK_REF_KIND_APP, "org.test.Hello", NULL, "master", NULL, NULL, NULL, &error);
  G_GNUC_END_IGNORE_DEPRECATIONS
  g_assert_no_error (error);
  g_assert_nonnull (iref);
  g_clear_object (&iref);

  refs = flatpak_installation_list_unused_refs (inst, NULL, NULL, &error);
  g_assert_nonnull (refs);
  g_assert_no_error (error);
  g_assert_cmpint (refs->len, ==, 0);
}

static void
test_installation_unused_refs_excludes_pins (void)
{
  g_autoptr(FlatpakInstallation) inst = NULL;
  g_autoptr(FlatpakTransaction) transaction = NULL;
  g_autoptr(GPtrArray) refs = NULL;
  g_autoptr(GError) error = NULL;
  g_autofree char *runtime = NULL;
  gboolean res;

  runtime = g_strdup_printf ("runtime/org.test.Platform/%s/master",
                             flatpak_get_default_arch ());

  inst = flatpak_installation_new_user (NULL, &error);
  g_assert_no_error (error);
  g_assert_nonnull (inst);

  empty_installation (inst);

  transaction = flatpak_transaction_new_for_installation (inst, NULL, &error);
  g_assert_no_error (error);
  g_assert_nonnull (transaction);

  res = flatpak_transaction_add_install (transaction, repo_name, runtime, NULL, &error);
  g_assert_no_error (error);
  g_assert_true (res);

  res = flatpak_transaction_run (transaction, NULL, &error);
  g_assert_no_error (error);
  g_assert_true (res);

  /* Even though the runtime is unused, it shouldn't show up in
   * list_unused_refs() because it was installed explicitly not as a dependency
   * of an app */
  refs = flatpak_installation_list_unused_refs (inst, NULL, NULL, &error);
  g_assert_nonnull (refs);
  g_assert_no_error (error);
  g_assert_cmpint (refs->len, ==, 0);
}

static void
test_installation_unused_refs_across_installations (void)
{
  g_autoptr(FlatpakInstallation) system_inst = NULL;
  g_autoptr(FlatpakInstallation) user_inst = NULL;
  g_autoptr(FlatpakTransaction) transaction = NULL;
  g_autoptr(GPtrArray) refs = NULL;
  g_autoptr(GError) error = NULL;
  g_autofree char *runtime = NULL;
  g_autofree char *app = NULL;
  FlatpakInstalledRef *unused_ref;
  gboolean res;

  runtime = g_strdup_printf ("runtime/org.test.Platform/%s/master",
                             flatpak_get_default_arch ());
  app = g_strdup_printf ("app/org.test.Hello/%s/master",
                         flatpak_get_default_arch ());

  system_inst = flatpak_installation_new_system (NULL, &error);
  g_assert_no_error (error);
  g_assert_nonnull (system_inst);

  user_inst = flatpak_installation_new_user (NULL, &error);
  g_assert_no_error (error);
  g_assert_nonnull (user_inst);

  empty_installation (system_inst);
  empty_installation (user_inst);

  add_remote_system ("test-runtime-only", NULL);

  transaction = flatpak_transaction_new_for_installation (system_inst, NULL, &error);
  g_assert_no_error (error);
  g_assert_nonnull (transaction);

  /* We don't want the runtime pinned in this case */
  flatpak_transaction_set_disable_auto_pin (transaction, TRUE);

  res = flatpak_transaction_add_install (transaction, "test-runtime-only-repo", runtime, NULL, &error);
  g_assert_no_error (error);
  g_assert_true (res);

  res = flatpak_transaction_run (transaction, NULL, &error);
  g_assert_no_error (error);
  g_assert_true (res);
  g_clear_object (&transaction);

  /* The runtime should show as unused */
  refs = flatpak_installation_list_unused_refs (system_inst, NULL, NULL, &error);
  g_assert_nonnull (refs);
  g_assert_no_error (error);
  g_assert_cmpint (refs->len, ==, 1);
  unused_ref = g_ptr_array_index (refs, 0);
  g_assert_cmpstr (flatpak_ref_get_name (FLATPAK_REF (unused_ref)), ==, "org.test.Platform");
  g_clear_pointer (&refs, g_ptr_array_unref);

  /* Install an app in the user installation that uses the runtime in the
   * system installation */
  transaction = flatpak_transaction_new_for_installation (user_inst, NULL, &error);
  g_assert_no_error (error);
  g_assert_nonnull (transaction);

  flatpak_transaction_add_dependency_source (transaction, system_inst);

  res = flatpak_transaction_add_install (transaction, repo_name, app, NULL, &error);
  g_assert_no_error (error);
  g_assert_true (res);

  res = flatpak_transaction_run (transaction, NULL, &error);
  g_assert_no_error (error);
  g_assert_true (res);

  /* Now the runtime should be used */
  refs = flatpak_installation_list_unused_refs (system_inst, NULL, NULL, &error);
  g_assert_nonnull (refs);
  g_assert_no_error (error);
  g_assert_cmpint (refs->len, ==, 0);

  empty_installation (user_inst);
  empty_installation (system_inst);
  remove_remote_system ("test-runtime-only-repo");
}

int
main (int argc, char *argv[])
{
  int res;

  g_test_init (&argc, &argv, NULL);

  g_test_add_func ("/library/version", test_library_version);
  g_test_add_func ("/library/types", test_library_types);
  g_test_add_func ("/library/user-installation", test_user_installation);
  g_test_add_func ("/library/system-installation", test_system_installation);
  g_test_add_func ("/library/multiple-system-installation", test_multiple_system_installations);
  g_test_add_func ("/library/installation-config", test_installation_config);
  g_test_add_func ("/library/languages-config", test_languages_config);
  g_test_add_func ("/library/arches", test_arches);
  g_test_add_func ("/library/ref", test_ref);
  g_test_add_func ("/library/list-remotes", test_list_remotes);
  g_test_add_func ("/library/timestamp", test_timestamp);
  g_test_add_func ("/library/remote-by-name", test_remote_by_name);
  g_test_add_func ("/library/remote", test_remote);
  g_test_add_func ("/library/remote-new", test_remote_new);
  g_test_add_func ("/library/remote-new-from-file", test_remote_new_from_file);
  g_test_add_func ("/library/list-remote-refs", test_list_remote_refs);
  g_test_add_func ("/library/list-remote-refs-noenumerate", test_list_remote_refs_noenumerate);
  g_test_add_func ("/library/list-remote-related-refs", test_list_remote_related_refs);
  g_test_add_func ("/library/list-remote-related-refs-for-installed", test_list_remote_related_refs_for_installed);
  g_test_add_func ("/library/list-refs", test_list_refs);
  g_test_add_func ("/library/install-launch-uninstall", test_install_launch_uninstall);
  g_test_add_func ("/library/list-refs-in-remote", test_list_refs_in_remotes);
  g_test_add_func ("/library/list-updates", test_list_updates);
  g_test_add_func ("/library/list-undeployed-updates", test_list_undeployed_updates);
  g_test_add_func ("/library/list-rename-updates", test_list_rename_updates);
  g_test_add_func ("/library/list-updates-offline", test_list_updates_offline);
  g_test_add_func ("/library/transaction", test_misc_transaction);
  g_test_add_func ("/library/transaction-install-uninstall", test_transaction_install_uninstall);
  g_test_add_func ("/library/transaction-install-flatpakref", test_transaction_install_flatpakref);
  g_test_add_func ("/library/transaction-flatpakref-remote-creation", test_transaction_flatpakref_remote_creation);
  g_test_add_func ("/library/transaction-flatpakref-origin-remote-creation", test_transaction_flatpakref_origin_remote_creation);
  g_test_add_func ("/library/transaction-deps", test_transaction_deps);
  g_test_add_func ("/library/transaction-install-local", test_transaction_install_local);
  g_test_add_func ("/library/transaction-app-runtime-same-remote", test_transaction_app_runtime_same_remote);
  g_test_add_func ("/library/transaction-update-related-from-different-remote", test_transaction_update_related_from_different_remote);
  g_test_add_func ("/library/remote-nodeps-option", test_remote_nodeps_option);
  g_test_add_func ("/library/instance", test_instance);
  g_test_add_func ("/library/update-subpaths", test_update_subpaths);
  g_test_add_func ("/library/overrides", test_overrides);
  g_test_add_func ("/library/bundle", test_bundle);
  g_test_add_func ("/library/install-bundle", test_install_bundle);
  g_test_add_func ("/library/install-flatpakref", test_install_flatpakref);
  g_test_add_func ("/library/list-installed-related-refs", test_list_installed_related_refs);
  g_test_add_func ("/library/update-related-refs", test_update_related_refs);
  g_test_add_func ("/library/update-installed-ref-if-missing-runtime", test_update_installed_ref_if_missing_runtime);
  g_test_add_func ("/library/no-deploy", test_no_deploy);
  g_test_add_func ("/library/bad-remote-name", test_bad_remote_name);
  g_test_add_func ("/library/transaction-no-runtime", test_transaction_no_runtime);
  g_test_add_func ("/library/installation-no-interaction", test_installation_no_interaction);
  g_test_add_func ("/library/installation-unused-refs", test_installation_unused_refs);
  g_test_add_func ("/library/installation-unused-refs-excludes-pins", test_installation_unused_refs_excludes_pins);
  g_test_add_func ("/library/installation-unused-refs-across-installations", test_installation_unused_refs_across_installations);

  flatpak_add_all_tests ();

  global_setup ();

  res = g_test_run ();

  global_teardown ();

  return res;
}

===== ./tests/test-bundle.sh =====
#!/bin/bash
#
# Copyright (C) 2011 Colin Walters <walters@verbum.org>
#
# 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 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., 59 Temple Place - Suite 330,
# Boston, MA 02111-1307, USA.

set -euo pipefail

. $(dirname $0)/libtest.sh

skip_without_bwrap
skip_revokefs_without_fuse

echo "1..9"

mkdir bundles

setup_repo

${FLATPAK} build-bundle repos/test --repo-url=file://`pwd`/repos/test --gpg-keys=${FL_GPG_HOMEDIR}/pubring.gpg bundles/hello.flatpak org.test.Hello >&2
assert_has_file bundles/hello.flatpak

${FLATPAK} build-bundle repos/test --runtime --repo-url=file://`pwd`/repos/test --gpg-keys=${FL_GPG_HOMEDIR}/pubring.gpg bundles/platform.flatpak org.test.Platform >&2
assert_has_file bundles/platform.flatpak

ok "create bundles server-side"

rm bundles/hello.flatpak
${FLATPAK} ${U} install -y test-repo org.test.Hello >&2
${FLATPAK} build-bundle $FL_DIR/repo --repo-url=file://`pwd`/repos/test --gpg-keys=${FL_GPG_HOMEDIR}/pubring.gpg bundles/hello.flatpak org.test.Hello >&2
assert_has_file bundles/hello.flatpak

ok "create bundles client-side"

${FLATPAK} uninstall ${U} -y org.test.Hello >&2
${FLATPAK} install ${U} -y --bundle bundles/hello.flatpak >&2

# Installing again without reinstall option should fail...
assert_fail ${FLATPAK} install ${U} -y --bundle bundles/hello.flatpak >&2
# Now with reinstall option it should pass...
${FLATPAK} install ${U} -y --bundle bundles/hello.flatpak --reinstall >&2

# This should have installed the runtime dependency too
assert_has_file $FL_DIR/repo/refs/remotes/test-repo/runtime/org.test.Platform/$ARCH/master

assert_has_file $FL_DIR/repo/refs/remotes/hello-origin/app/org.test.Hello/$ARCH/master
APP_COMMIT=`cat $FL_DIR/repo/refs/remotes/hello-origin/app/org.test.Hello/$ARCH/master`
assert_has_file $FL_DIR/repo/objects/$(echo $APP_COMMIT | cut -b 1-2)/$(echo $APP_COMMIT | cut -b 3-).commit
assert_has_file $FL_DIR/repo/objects/$(echo $APP_COMMIT | cut -b 1-2)/$(echo $APP_COMMIT | cut -b 3-).commitmeta

assert_has_dir $FL_DIR/app/org.test.Hello
assert_has_symlink $FL_DIR/app/org.test.Hello/current
assert_symlink_has_content $FL_DIR/app/org.test.Hello/current ^$ARCH/master$
assert_has_dir $FL_DIR/app/org.test.Hello/$ARCH/master
assert_has_symlink $FL_DIR/app/org.test.Hello/$ARCH/master/active
ID=`readlink $FL_DIR/app/org.test.Hello/$ARCH/master/active`
assert_has_file $FL_DIR/app/org.test.Hello/$ARCH/master/active/deploy
assert_has_file $FL_DIR/app/org.test.Hello/$ARCH/master/active/metadata
assert_has_dir $FL_DIR/app/org.test.Hello/$ARCH/master/active/files
assert_has_dir $FL_DIR/app/org.test.Hello/$ARCH/master/active/export
assert_has_file $FL_DIR/exports/share/applications/org.test.Hello.desktop
# Ensure Exec key is rewritten
assert_file_has_content $FL_DIR/exports/share/applications/org.test.Hello.desktop "^Exec=.*flatpak run --branch=master --arch=$ARCH --command=hello\.sh org\.test\.Hello$"
assert_has_file $FL_DIR/exports/share/icons/hicolor/64x64/apps/org.test.Hello.png
assert_has_file $FL_DIR/exports/share/icons/HighContrast/64x64/apps/org.test.Hello.png

$FLATPAK list ${U} | grep org.test.Hello > /dev/null
$FLATPAK list ${U} -d | grep org.test.Hello | grep hello-origin > /dev/null
$FLATPAK list ${U} -d | grep org.test.Hello | grep current > /dev/null
$FLATPAK list ${U} -d | grep org.test.Hello | grep ${ID:0:12} > /dev/null

$FLATPAK info ${U} org.test.Hello > /dev/null
$FLATPAK info ${U} org.test.Hello | grep hello-origin > /dev/null
$FLATPAK info ${U} org.test.Hello | grep $ID > /dev/null

$FLATPAK remote-list ${U} -d | grep hello-origin > /dev/null
$FLATPAK remote-list ${U} -d | grep hello-origin | grep no-enumerate > /dev/null
assert_has_file $FL_DIR/repo/hello-origin.trustedkeys.gpg

ok "install app bundle"

if command -v update-desktop-database >/dev/null &&
   command -v update-mime-database >/dev/null &&
   command -v gtk-update-icon-cache >/dev/null &&
   test -f /usr/share/icons/hicolor/index.theme; then
    # Ensure triggers ran
    assert_has_file $FL_DIR/exports/share/applications/mimeinfo.cache
    assert_file_has_content $FL_DIR/exports/share/applications/mimeinfo.cache x-test/Hello
    assert_has_file $FL_DIR/exports/share/icons/hicolor/icon-theme.cache
    assert_has_file $FL_DIR/exports/share/icons/hicolor/index.theme

    ok "install app bundle triggers"
else
    ok "install app bundle triggers triggers # skip  Dependencies not available"
fi

${FLATPAK} uninstall -y --force-remove ${U} org.test.Platform >&2

assert_not_has_file $FL_DIR/repo/refs/remotes/platform-origin/runtime/org.test.Platform/$ARCH/master

${FLATPAK} install -y ${U} --bundle bundles/platform.flatpak >&2

assert_has_file $FL_DIR/repo/refs/remotes/platform-origin/runtime/org.test.Platform/$ARCH/master
RUNTIME_COMMIT=`cat $FL_DIR/repo/refs/remotes/platform-origin/runtime/org.test.Platform/$ARCH/master`
assert_has_file $FL_DIR/repo/objects/$(echo $RUNTIME_COMMIT | cut -b 1-2)/$(echo $RUNTIME_COMMIT | cut -b 3-).commit
assert_has_file $FL_DIR/repo/objects/$(echo $RUNTIME_COMMIT | cut -b 1-2)/$(echo $RUNTIME_COMMIT | cut -b 3-).commitmeta

assert_has_dir $FL_DIR/runtime/org.test.Platform
assert_has_dir $FL_DIR/runtime/org.test.Platform/$ARCH/master
assert_has_symlink $FL_DIR/runtime/org.test.Platform/$ARCH/master/active
ID=`readlink $FL_DIR/runtime/org.test.Platform/$ARCH/master/active`
assert_has_file $FL_DIR/runtime/org.test.Platform/$ARCH/master/active/deploy
assert_has_file $FL_DIR/runtime/org.test.Platform/$ARCH/master/active/metadata
assert_has_dir $FL_DIR/runtime/org.test.Platform/$ARCH/master/active/files

$FLATPAK list ${U} --runtime | grep org.test.Platform > /dev/null
$FLATPAK list ${U} -d --runtime | grep org.test.Platform | grep platform-origin > /dev/null
$FLATPAK list ${U} -d --runtime | grep org.test.Platform | grep ${ID:0:12} > /dev/null

$FLATPAK info ${U} org.test.Platform > /dev/null
$FLATPAK info ${U} org.test.Platform | grep platform-origin > /dev/null
$FLATPAK info ${U} org.test.Platform | grep $ID > /dev/null

$FLATPAK remote-list ${U} -d | grep platform-origin > /dev/null
$FLATPAK remote-list ${U} -d | grep platform-origin | grep no-enumerate > /dev/null
assert_has_file $FL_DIR/repo/platform-origin.trustedkeys.gpg

ok "install runtime bundle"

run org.test.Hello &> hello_out
assert_file_has_content hello_out '^Hello world, from a sandbox$'

ok "run"


OLD_COMMIT=`${FLATPAK} ${U} info --show-commit org.test.Hello`

# TODO: For weird reasons this breaks in the system case. Needs debugging
if [ x${USE_SYSTEMDIR-} != xyes ] ; then
    ${FLATPAK} ${U} update -y -v org.test.Hello master >&2
    ALSO_OLD_COMMIT=`${FLATPAK} ${U} info --show-commit org.test.Hello`
    assert_streq "$OLD_COMMIT" "$ALSO_OLD_COMMIT"
fi

ok "null update"

make_updated_app

${FLATPAK} ${U} update -y org.test.Hello >&2

NEW_COMMIT=`${FLATPAK} ${U} info --show-commit org.test.Hello`

assert_not_streq "$OLD_COMMIT" "$NEW_COMMIT"

run org.test.Hello &> hello_out
assert_file_has_content hello_out '^Hello world, from a sandboxUPDATED$'

ok "update"

make_updated_app test org.test.Collection.test master UPDATED2

${FLATPAK} build-bundle repos/test --repo-url=file://`pwd`/repos/test --gpg-keys=${FL_GPG_HOMEDIR}/pubring.gpg bundles/hello2.flatpak org.test.Hello >&2
assert_has_file bundles/hello2.flatpak

${FLATPAK} install ${U} -y --bundle bundles/hello2.flatpak >&2

NEW2_COMMIT=`${FLATPAK} ${U} info --show-commit org.test.Hello`

assert_not_streq "$NEW_COMMIT" "$NEW2_COMMIT"

run org.test.Hello &> hello_out
assert_file_has_content hello_out '^Hello world, from a sandboxUPDATED2$'

ok "update as bundle"

===== ./tests/test-prune.sh =====
#!/bin/bash
#
# Copyright (C) 2021 Alexander Larsson <alexl@redhat.com>
#
# 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 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., 59 Temple Place - Suite 330,
# Boston, MA 02111-1307, USA.

set -euo pipefail

. $(dirname $0)/libtest.sh

echo "1..5"

create_commit() {
    # Wrap this to avoid set -x showing the commands
    { { local BASH_XTRACEFD=3; } 2> /dev/null
        local REPO=${1}
        local APP=${2}
        local DEPTH=${3}

        local F=$(mktemp -d files.XXXXXX)

        # Each commit has:
        #  * 2 unique file objects
        #  * 2 app shared file objects
        #  * 2 unique dirtree object
        #  * 1 app shared dirtree object
        #  * 1 global shared dirmeta object
        #  * 1 unique commit object
        # => 5 unique + 4 app shared + 1 global shared == 10 total
        #
        # Additionally, each commit will generate one commitmeta2
        # files once prune has been run. However, these will not
        # be reported as total or deleted objects by the prune call,
        # as they are purely side-caches.

        echo "$APP.$DEPTH.1" > $F/file1
        mkdir $F/dir
        echo "$APP.$DEPTH.2" > $F/dir/file2
        echo "$APP.shared1" > $F/dir/shared1
        mkdir $F/shared-dir
        echo "$APP.shared2" > $F/shared-dir/shared2

        echo committing $APP depth $DEPTH >&2
        ostree --repo=$REPO --branch=$APP --fsync=false --canonical-permissions --no-xattrs commit $F >&2
        rm -rf $F

    if [ ${DEPTH} != "1" ]; then
        create_commit $REPO $APP $((${DEPTH} - 1 ))
    fi
    } 3> /dev/null
}

count_objects() {
    # Wrap this to avoid set -x showing the ls commands
    { { local BASH_XTRACEFD=3; } 2> /dev/null
        NUM_FILE=$(ls -d $1/objects/*/*.filez | wc -l)
        NUM_DIRTREE=$(ls -d $1/objects/*/*.dirtree | wc -l)
        NUM_COMMIT=$(ls -d $1/objects/*/*.commit | wc -l)
        NUM_DIRMETA=$(ls -d $1/objects/*/*.dirmeta | wc -l)
        NUM_COMMITMETA2=0
        if compgen -G "$1/objects/*/*.commitmeta2" > /dev/null; then
            NUM_COMMITMETA2=$(ls -d $1/objects/*/*.commitmeta2 | wc -l)
        fi
        NUM_OBJECT=$(ls -d $1/objects/*/* | wc -l)
        echo OBJCOUNT $1: $NUM_FILE files + $NUM_DIRTREE dirtree + $NUM_COMMIT commit + $NUM_DIRMETA dirmeta + $NUM_COMMITMETA2 commitmeta2 == $NUM_OBJECT objects >&2
    } 3> /dev/null
}


ostree --repo=orig-repo --mode=archive init >&2

create_commit orig-repo app1 3 #   8f 7d 3c 2m == 20
create_commit orig-repo app2 4 #+ 10f 9d 4c 0m == 23
create_commit orig-repo app3 3 #+  8f 7d 3c 0m == 18
#####################   26 23 10  2     61

count_objects orig-repo
assert_streq $NUM_FILE 26
assert_streq $NUM_DIRTREE 23
assert_streq $NUM_COMMIT 10
assert_streq $NUM_DIRMETA 2
assert_streq $NUM_OBJECT 61
assert_streq $NUM_COMMITMETA2 0

#################### Try a no-op prune, should do nothing but create commitmeta2 objects

cp -a orig-repo repo # Work on a copy

# Prune with full depth should change nothing
$FLATPAK build-update-repo --no-update-summary --no-update-appstream --prune --prune-depth=-1 repo > prune.log
cat prune.log >&2

assert_file_has_content prune.log "Total objects: 61"

count_objects repo
assert_streq $NUM_FILE 26
assert_streq $NUM_DIRTREE 23
assert_streq $NUM_COMMIT 10
assert_streq $NUM_DIRMETA 2
assert_streq $NUM_COMMITMETA2 $NUM_COMMIT
assert_streq $NUM_OBJECT 71

cp -a repo incremental-repo # Make a copy of the orig repo with the commitmeta2 objects

# Try again with the commitmeta existing

# Prune with full depth should change nothing
$FLATPAK build-update-repo --no-update-summary --no-update-appstream --prune --prune-depth=-1 repo > prune.log
cat prune.log >&2

assert_file_has_content prune.log "Total objects: 61"

count_objects repo
assert_streq $NUM_FILE 26
assert_streq $NUM_DIRTREE 23
assert_streq $NUM_COMMIT 10
assert_streq $NUM_DIRMETA 2
assert_streq $NUM_COMMITMETA2 $NUM_COMMIT
assert_streq $NUM_OBJECT 71

ok "no-op prune"

############# Try various depth prunes, with and without .commitmeta2

rm -rf repo
cp -a orig-repo repo # Work on a copy

# depth = 2 will only remove one commit from app2

$FLATPAK build-update-repo --no-update-summary --no-update-appstream --prune --prune-depth=2 repo > prune.log
cat prune.log >&2

assert_file_has_content prune.log "Total objects: 61"
assert_file_has_content prune.log "Deleted 5 objects,"

count_objects repo
assert_streq $NUM_FILE 24
assert_streq $NUM_DIRTREE 21
assert_streq $NUM_COMMIT 9
assert_streq $NUM_DIRMETA 2
assert_streq $NUM_COMMITMETA2 $NUM_COMMIT
assert_streq $NUM_OBJECT 65

rm -rf repo
cp -a incremental-repo repo # Work on a copy w/ commitmeta2s

# depth = 2 will only remove one commit from app2

$FLATPAK build-update-repo --no-update-summary --no-update-appstream --prune --prune-depth=2 repo > prune.log
cat prune.log >&2

assert_file_has_content prune.log "Total objects: 61"
assert_file_has_content prune.log "Deleted 5 objects,"

count_objects repo
assert_streq $NUM_FILE 24
assert_streq $NUM_DIRTREE 21
assert_streq $NUM_COMMIT 9
assert_streq $NUM_DIRMETA 2
assert_streq $NUM_COMMITMETA2 $NUM_COMMIT
assert_streq $NUM_OBJECT 65

# depth = 1 will only remove 4 commits

rm -rf repo
cp -a orig-repo repo # Work on a copy

$FLATPAK build-update-repo --no-update-summary --no-update-appstream --prune --prune-depth=1 repo > prune.log
cat prune.log >&2

assert_file_has_content prune.log "Total objects: 61"
assert_file_has_content prune.log "Deleted 20 objects,"

count_objects repo
assert_streq $NUM_FILE 18
assert_streq $NUM_DIRTREE 15
assert_streq $NUM_COMMIT 6
assert_streq $NUM_DIRMETA 2
assert_streq $NUM_COMMITMETA2 $NUM_COMMIT
assert_streq $NUM_OBJECT 47

rm -rf repo
cp -a incremental-repo repo # Work on a copy w/ commitmeta2s

$FLATPAK build-update-repo --no-update-summary --no-update-appstream --prune --prune-depth=1 repo > prune.log
cat prune.log >&2

assert_file_has_content prune.log "Total objects: 61"
assert_file_has_content prune.log "Deleted 20 objects,"

count_objects repo
assert_streq $NUM_FILE 18
assert_streq $NUM_DIRTREE 15
assert_streq $NUM_COMMIT 6
assert_streq $NUM_DIRMETA 2
assert_streq $NUM_COMMITMETA2 $NUM_COMMIT
assert_streq $NUM_OBJECT 47

ok "depth prune"

############# Try non-reachable prunes, with and without .commitmeta2

rm -rf repo
cp -a orig-repo repo # Work on a copy

rm repo/refs/heads/app3 # Removes 3 commits

$FLATPAK build-update-repo --no-update-summary --no-update-appstream --prune --prune-depth=-1 repo > prune.log
cat prune.log >&2
assert_file_has_content prune.log "Total objects: 61"
assert_file_has_content prune.log "Deleted 18 objects,"

count_objects repo
assert_streq $NUM_FILE 18
assert_streq $NUM_DIRTREE 16
assert_streq $NUM_COMMIT 7
assert_streq $NUM_DIRMETA 2
assert_streq $NUM_COMMITMETA2 $NUM_COMMIT
assert_streq $NUM_OBJECT 50

rm -rf repo
cp -a incremental-repo repo # Work on a copy w/ commitmeta2s

rm repo/refs/heads/app3 # Removes 3 commits

$FLATPAK build-update-repo --no-update-summary --no-update-appstream --prune --prune-depth=-1 repo > prune.log
cat prune.log >&2
assert_file_has_content prune.log "Total objects: 61"
assert_file_has_content prune.log "Deleted 18 objects,"

count_objects repo
assert_streq $NUM_FILE 18
assert_streq $NUM_DIRTREE 16
assert_streq $NUM_COMMIT 7
assert_streq $NUM_DIRMETA 2
assert_streq $NUM_COMMITMETA2 $NUM_COMMIT
assert_streq $NUM_OBJECT 50

ok "unreachable prune"

# Combine depth and unreachable

rm -rf repo
cp -a orig-repo repo # Work on a copy

rm repo/refs/heads/app3 # Removes 3 commits

$FLATPAK build-update-repo --no-update-summary --no-update-appstream --prune --prune-depth=2 repo > prune.log
cat prune.log >&2
assert_file_has_content prune.log "Total objects: 61"
assert_file_has_content prune.log "Deleted 23 objects,"

count_objects repo
assert_streq $NUM_FILE 16
assert_streq $NUM_DIRTREE 14
assert_streq $NUM_COMMIT 6
assert_streq $NUM_DIRMETA 2
assert_streq $NUM_COMMITMETA2 $NUM_COMMIT
assert_streq $NUM_OBJECT 44

rm -rf repo
cp -a incremental-repo repo # Work on a copy w/ commitmeta2s

rm repo/refs/heads/app3 # Removes 3 commits

$FLATPAK build-update-repo --no-update-summary --no-update-appstream --prune --prune-depth=2 repo > prune.log
cat prune.log >&2
assert_file_has_content prune.log "Total objects: 61"
assert_file_has_content prune.log "Deleted 23 objects,"

count_objects repo
assert_streq $NUM_FILE 16
assert_streq $NUM_DIRTREE 14
assert_streq $NUM_COMMIT 6
assert_streq $NUM_DIRMETA 2
assert_streq $NUM_COMMITMETA2 $NUM_COMMIT
assert_streq $NUM_OBJECT 44

ok "unreachable and depth prune"

# Compare last result with ostree prune:
cp -a orig-repo ostree-repo
rm ostree-repo/refs/heads/app3 # Removes 3 commits
ostree prune --refs-only --depth=2 --repo=ostree-repo >&2
rm -rf repo/objects/*/*.commitmeta2
diff -r repo ostree-repo >&2

ok "Compare with ostree prune"

===== ./tests/test-portal-impl.c =====
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>

#include <sys/stat.h>
#include <fcntl.h>

#include <gio/gio.h>

static guint name_owner_id = 0;
static GMainLoop *main_loop;

static void
access_method_call (GDBusConnection       *connection,
                    const gchar           *sender,
                    const gchar           *object_path,
                    const gchar           *interface_name,
                    const gchar           *method_name,
                    GVariant              *parameters,
                    GDBusMethodInvocation *invocation,
                    gpointer               user_data)
{
  if (g_strcmp0 (method_name, "AccessDialog") == 0)
    {
      GVariantBuilder res_builder;

      /* Always allow */
      g_variant_builder_init (&res_builder, G_VARIANT_TYPE_VARDICT);
      g_dbus_method_invocation_return_value (invocation,
                                             g_variant_new ("(u@a{sv})",
                                                            0,
                                                            g_variant_builder_end (&res_builder)));
    }
  else
    g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_UNKNOWN_METHOD,
                                           "Method %s is not implemented on interface %s",
                                           method_name, interface_name);
}


static const GDBusArgInfo access_dialog_IN_ARG_handle = { -1, (gchar *) "handle", (gchar *) "o", NULL };
static const GDBusArgInfo access_dialog_IN_ARG_app_id = { -1, (gchar *) "app_id",  (gchar *) "s",  NULL };
static const GDBusArgInfo access_dialog_IN_ARG_parent_window = {  -1,  (gchar *) "parent_window",  (gchar *) "s",  NULL };
static const GDBusArgInfo access_dialog_IN_ARG_title = { -1,  (gchar *) "title",  (gchar *) "s",  NULL };
static const GDBusArgInfo access_dialog_IN_ARG_subtitle = {  -1,  (gchar *) "subtitle",  (gchar *) "s",  NULL };
static const GDBusArgInfo access_dialog_IN_ARG_body = {  -1,  (gchar *) "body",  (gchar *) "s",  NULL };
static const GDBusArgInfo access_dialog_IN_ARG_options = {  -1,  (gchar *) "options",  (gchar *) "a{sv}",  NULL };
static const GDBusArgInfo * const access_dialog_IN_ARG_pointers[] = {
  &access_dialog_IN_ARG_handle,
  &access_dialog_IN_ARG_app_id,
  &access_dialog_IN_ARG_parent_window,
  &access_dialog_IN_ARG_title,
  &access_dialog_IN_ARG_subtitle,
  &access_dialog_IN_ARG_body,
  &access_dialog_IN_ARG_options,
  NULL
};

static const GDBusArgInfo access_dialog_OUT_ARG_response = { -1, (gchar *) "response", (gchar *) "u", NULL };
static const GDBusArgInfo access_dialog_OUT_ARG_results = { -1, (gchar *) "results", (gchar *) "a{sv}", NULL };
static const GDBusArgInfo * const access_dialog_OUT_ARG_pointers[] = {
  &access_dialog_OUT_ARG_response,
  &access_dialog_OUT_ARG_results,
  NULL
};

static const GDBusMethodInfo access_dialog = {
 -1,
 (gchar *) "AccessDialog",
 (GDBusArgInfo **) &access_dialog_IN_ARG_pointers,
 (GDBusArgInfo **) &access_dialog_OUT_ARG_pointers,
 NULL
};

static const GDBusMethodInfo * const access_dialog_methods[] = {
  &access_dialog,
  NULL
};

static const GDBusInterfaceInfo access_interface_info = {
  -1,
  "org.freedesktop.impl.portal.Access",
  (GDBusMethodInfo **) &access_dialog_methods,
  (GDBusSignalInfo **) NULL,
  (GDBusPropertyInfo **) NULL,
  NULL,
};

static const GDBusInterfaceVTable access_vtable = {
  access_method_call, /* _method_call */
  NULL, /* _get_property */
  NULL  /* _set_property */
};

static void
on_bus_acquired (GDBusConnection *connection,
                 const gchar     *name,
                 gpointer         user_data)
{
  GError *error = NULL;
  guint registration_id;

  g_info ("Bus acquired, creating skeleton");
  registration_id = g_dbus_connection_register_object (connection,
                                                       "/org/freedesktop/portal/desktop",
                                                       (GDBusInterfaceInfo *) &access_interface_info,
                                                       &access_vtable,
                                                       NULL, NULL, &error);
  g_assert_true (registration_id != 0);
}

static void
on_name_acquired (GDBusConnection *connection,
                  const gchar     *name,
                  gpointer         user_data)
{
  g_info ("Name acquired");
}

static void
on_name_lost (GDBusConnection *connection,
              const gchar     *name,
              gpointer         user_data)
{
  g_info ("Name lost");
}

int
main (int argc, char *argv[])
{
  name_owner_id = g_bus_own_name (G_BUS_TYPE_SESSION,
                                  "org.freedesktop.impl.portal.desktop.test",
                                  G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT,
                                  on_bus_acquired,
                                  on_name_acquired,
                                  on_name_lost,
                                  NULL,
                                  NULL);

  main_loop = g_main_loop_new (NULL, FALSE);
  g_main_loop_run (main_loop);

  return 0;
}

===== ./tests/test-upgrade-from-header.sh =====
#!/bin/bash

set -euo pipefail

. "$(dirname "$0")"/libtest.sh

skip_without_bwrap
skip_revokefs_without_fuse

echo "1..6"

# Override the httpd function to enable header logging before setup_repo calls
# it. The web-server.py will log Flatpak-Ref and Flatpak-Upgrade-From headers
# to httpd-headers-log.
httpd () {
    if [ $# -eq 0 ] ; then
        set web-server.py repos "$(pwd)"/httpd-headers-log
    fi

    COMMAND=$1
    shift

    rm -f httpd-pipe
    mkfifo httpd-pipe
    PYTHONUNBUFFERED=1 "$(dirname "$0")"/$COMMAND "$@" 3> httpd-pipe 2>&1 | tee -a httpd-log >&2 &
    read < httpd-pipe
}

touch httpd-headers-log

setup_repo

truncate -s 0 httpd-headers-log

install_repo

APP_REF="app/org.test.Hello/${ARCH}/master"

assert_not_file_has_content httpd-headers-log "Flatpak-Upgrade-From"

ok "no Flatpak-Upgrade-From header on fresh install"

assert_file_has_content httpd-headers-log "Flatpak-Ref: ${APP_REF}"

ok "Flatpak-Ref header sent on fresh install"

INSTALLED_COMMIT=$(${FLATPAK} ${U} info --show-commit org.test.Hello)

make_updated_app
truncate -s 0 httpd-headers-log

${FLATPAK} ${U} update -y org.test.Hello >&2

assert_file_has_content httpd-headers-log "Flatpak-Upgrade-From: ${INSTALLED_COMMIT}"

ok "Flatpak-Upgrade-From header sent with correct commit hash on update"

assert_file_has_content httpd-headers-log "Flatpak-Ref: ${APP_REF}"

ok "Flatpak-Ref header sent on update"

# Scenario: the remote tracking ref in the local OSTree repo is missing.
#
# That ref can be absent when, for example:
#   - the remote was removed and re-added without re-installing the app
#   - the app was installed from a bundle (no remote tracking ref ever written)
#   - the ref was deleted by ostree-prune or flatpak-repair

INSTALLED_COMMIT2=$(${FLATPAK} ${U} info --show-commit org.test.Hello)

REMOTE_REF_FILE="${FL_DIR}/repo/refs/remotes/test-repo/app/org.test.Hello/${ARCH}/master"
assert_has_file "${REMOTE_REF_FILE}"
cp "${REMOTE_REF_FILE}" "${REMOTE_REF_FILE}.bak"
rm -f "${REMOTE_REF_FILE}"

make_updated_app test "" master UPDATED2
truncate -s 0 httpd-headers-log

${FLATPAK} ${U} update -y org.test.Hello >&2

# Restore the ref so cleanup does not trip over a partially-inconsistent repo.
mv "${REMOTE_REF_FILE}.bak" "${REMOTE_REF_FILE}"

assert_file_has_content httpd-headers-log "Flatpak-Upgrade-From: ${INSTALLED_COMMIT2}"

ok "Flatpak-Upgrade-From header sent when remote tracking ref is missing"

assert_file_has_content httpd-headers-log "Flatpak-Ref: ${APP_REF}"

ok "Flatpak-Ref header sent when remote tracking ref is missing"

===== ./tests/test-webserver.sh =====
#!/bin/bash

set -euo pipefail

dir=$1

rm -f httpd-pipe
mkfifo httpd-pipe
$(dirname $0)/web-server.py "$dir" 3> httpd-pipe &
read < httpd-pipe

===== ./tests/test-basic.sh =====
#!/bin/bash
#
# Copyright (C) 2011 Colin Walters <walters@verbum.org>
#
# 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 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., 59 Temple Place - Suite 330,
# Boston, MA 02111-1307, USA.

set -euo pipefail

. $(dirname $0)/libtest.sh

# This test looks for specific localized strings.
export LC_ALL=C

echo "1..11"

${FLATPAK} --version > version_out

VERSION=`cat "$test_builddir/package_version.txt"`
assert_file_has_content version_out "^Flatpak $VERSION$"

ok "version"

${FLATPAK} --help > help_out

assert_file_has_content help_out "^Usage:$"

ok "help"

${FLATPAK} --default-arch > arch

${FLATPAK} --supported-arches > arches

assert_streq `head -1 arches` `cat arch`

ok "default arch"

${FLATPAK} --print-updated-env > updated_env
${FLATPAK} --print-updated-env --print-system-only > updated_env_system

assert_file_has_content updated_env "exports/share"
assert_file_has_content updated_env "^XDG_DATA_DIRS="
assert_file_has_content updated_env_system "exports/share"
assert_file_has_content updated_env_system "^XDG_DATA_DIRS="

ok "print updated env"

${FLATPAK} --gl-drivers > drivers

assert_file_has_content drivers "^default$";
assert_file_has_content drivers "^host$";

ok "gl drivers"

for cmd in install update uninstall list info config repair create-usb \
           search run override make-current enter ps document-export \
           document-unexport document-info documents permission-remove \
           permissions permission-show permission-reset remotes remote-add \
           remote-modify remote-delete remote-ls remote-info build-init \
           build build-finish build-export build-bundle build-import-bundle \
           build-sign build-update-repo build-commit-from repo kill history \
           mask preinstall;
do
  ${FLATPAK} $cmd --help > help_out
  head -2 help_out > help_out2

  assert_file_has_content help_out2 "^Usage:$"
  assert_file_has_content help_out2 "flatpak $cmd"
done

ok "command help"

for cmd in list ps remote-ls remotes documents history;
do
  ${FLATPAK} $cmd --columns=help > help_out

  assert_file_has_content help_out "^Available columns:$"
  assert_file_has_content help_out "^  all"
  assert_file_has_content help_out "^  help"
done

ok "columns help"

${FLATPAK} >out 2>&1 || true

assert_file_has_content out "^error: No command specified$"
assert_file_has_content out "flatpak --help"

ok "missing command"

${FLATPAK} indo >out 2>&1 || true

assert_file_has_content out "^error: .* 'info'"
assert_file_has_content out "flatpak --help"

ok "misspelt command"

${FLATPAK} info >out 2>&1 || true

assert_file_has_content out "^error: NAME must be specified$"
assert_file_has_content out "flatpak info --help"

ok "info missing NAME"

for cmd in config make-current override remote-add repair; do
  ${FLATPAK} $cmd --system --user >out 2>&1 || true
  assert_file_has_content out "^error: Multiple installations specified"
  ${FLATPAK} $cmd --system --installation=foo >out 2>&1 || true
  assert_file_has_content out "^error: Multiple installations specified"
  ${FLATPAK} $cmd --user --installation=foo >out 2>&1 || true
  assert_file_has_content out "^error: Multiple installations specified"
  ${FLATPAK} $cmd --installation=foo --installation=bar >out 2>&1 || true
  assert_file_has_content out "^error: Multiple installations specified"
done

ok "ONE_DIR commands"

===== ./tests/test-info.sh =====
#!/bin/bash

set -euo pipefail

. $(dirname $0)/libtest.sh

skip_revokefs_without_fuse

echo "1..9"

INCLUDE_SPECIAL_CHARACTER=1 setup_repo
install_repo

COMMIT=`${FLATPAK} ${U} info --show-commit org.test.Hello`

${FLATPAK} info -rcos  org.test.Hello > info

assert_file_has_content info "^app/org\.test\.Hello/$(flatpak --default-arch)/master test-repo ${COMMIT}"

ok "info -rcos"

${FLATPAK} info --show-metadata  org.test.Hello > info

# CVE-2023-28101
assert_file_has_content info "name=org\.test\.Hello"
assert_file_has_content info "^A=x\\\\x09y"

ok "info --show-metadata"

${FLATPAK} info --show-permissions  org.test.Hello > info

assert_file_has_content info "^A=x\\\\x09y"

ok "info --show-permissions"

${FLATPAK} info --show-location  org.test.Hello > info

assert_file_has_content info "app/org\.test\.Hello/$(flatpak --default-arch)/master/${COMMIT}"

ok "info --show-location"

${FLATPAK} info --show-runtime  org.test.Hello > info

assert_file_has_content info "^org\.test\.Platform/$(flatpak --default-arch)/master$"

ok "info --show-runtime"

${FLATPAK} info --show-sdk  org.test.Hello > info

assert_file_has_content info "^org\.test\.Platform/$(flatpak --default-arch)/master$"

ok "info --show-sdk"

${FLATPAK} info --show-extensions org.test.Hello > info

assert_file_has_content info "Extension: runtime/org\.test\.Hello\.Locale/$(flatpak --default-arch)/master$"

ok "info --show-extensions"

${FLATPAK} info --file-access=home org.test.Hello > info

assert_file_has_content info "^hidden$"

ok "info --file-access"

${FLATPAK} info org.test.Hello > info

assert_file_has_content info "^Hello world test app: org\.test\.Hello - Print a greeting$"

ok "info (name header)"

===== ./tests/test-run-custom.sh =====
#!/bin/bash
#
# Copyright (C) 2026 Red Hat, Inc.
#
# 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 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., 59 Temple Place - Suite 330,
# Boston, MA 02111-1307, USA.

set -euo pipefail

. "$(dirname "$0")/libtest.sh"

skip_without_bwrap
skip_revokefs_without_fuse

echo "1..12"

# Use stable rather than master as the branch so we can test that the run
# command automatically finds the branch correctly
setup_repo "" "" stable
install_repo "" stable

setup_repo_no_add custom org.test.Collection.Custom master
make_updated_runtime custom org.test.Collection.Custom master CUSTOM
make_updated_app custom org.test.Collection.Custom master CUSTOM

ostree checkout -U --repo=repos/custom runtime/org.test.Platform/${ARCH}/master custom-runtime >&2
ostree checkout -U --repo=repos/custom app/org.test.Hello/$ARCH/master custom-app >&2

cat custom-runtime/files/bin/runtime_hello.sh > runtime_hello
assert_file_has_content runtime_hello "runtimeCUSTOM"
cat custom-app/files/bin/hello.sh > app_hello
assert_file_has_content app_hello "sandboxCUSTOM"

run org.test.Hello > hello_out
assert_file_has_content hello_out '^Hello world, from a sandbox$'

run --command=/usr/bin/runtime_hello.sh org.test.Hello > hello_out
assert_file_has_content hello_out '^Hello world, from a runtime$'

ok "setup"

assert_fail run --app-path="" --command=/app/bin/hello.sh org.test.Hello > /dev/null

run --app-path="" --command=/usr/bin/runtime_hello.sh org.test.Hello > hello_out
assert_file_has_content hello_out '^Hello world, from a runtime$'

run --app-path="" --command=/run/parent/app/bin/hello.sh org.test.Hello > hello_out
assert_file_has_content hello_out '^Hello world, from a sandbox$'

assert_fail run --app-path="" --command=/run/parent/usr/bin/runtime_hello.sh org.test.Hello > /dev/null

ok "empty app path"

run --app-path=custom-app/files --command=/app/bin/hello.sh org.test.Hello > hello_out
assert_file_has_content hello_out '^Hello world, from a sandboxCUSTOM$'

run --app-path=custom-app/files --command=/usr/bin/runtime_hello.sh org.test.Hello > hello_out
assert_file_has_content hello_out '^Hello world, from a runtime$'

run --app-path=custom-app/files --command=/run/parent/app/bin/hello.sh org.test.Hello > hello_out
assert_file_has_content hello_out '^Hello world, from a sandbox$'

assert_fail run --app-path=custom-app/files --command=/run/parent/usr/bin/runtime_hello.sh org.test.Hello > /dev/null

ok "custom app path"

assert_fail run --app-path=path-which-does-not-exist org.test.Hello > /dev/null

ok "bad custom app path"

exec 3< custom-app/files
run --app-fd=3 --command=/app/bin/hello.sh org.test.Hello > hello_out
assert_file_has_content hello_out '^Hello world, from a sandboxCUSTOM$'
exec 3>&-

assert_fail run --app-fd=3 --command=/app/bin/hello.sh org.test.Hello > /dev/null

ok "custom app fd"

run --usr-path=custom-runtime/files --command=/app/bin/hello.sh org.test.Hello > hello_out
assert_file_has_content hello_out '^Hello world, from a sandbox$'

run --usr-path=custom-runtime/files --command=/usr/bin/runtime_hello.sh org.test.Hello > hello_out
assert_file_has_content hello_out '^Hello world, from a runtimeCUSTOM$'

assert_fail run --usr-path=custom-runtime/files --command=/run/parent/app/bin/hello.sh org.test.Hello > /dev/null

run --usr-path=custom-runtime/files --command=/run/parent/usr/bin/runtime_hello.sh org.test.Hello > hello_out
assert_file_has_content hello_out '^Hello world, from a runtime$'

ok "custom usr path"

assert_fail run --usr-path=path-which-does-not-exist org.test.Hello > /dev/null

ok "bad custom usr path"

exec 3< custom-runtime/files
run --usr-fd=3 --command=/app/bin/hello.sh org.test.Hello > hello_out
assert_file_has_content hello_out '^Hello world, from a sandbox$'
exec 3>&-

exec 3< custom-runtime/files
run --usr-fd=3 --command=/usr/bin/runtime_hello.sh org.test.Hello > hello_out
assert_file_has_content hello_out '^Hello world, from a runtimeCUSTOM$'
exec 3>&-

assert_fail run --usr-fd=3 --command=/app/bin/hello.sh org.test.Hello > /dev/null

ok "custom usr fd"

run --usr-path=custom-runtime/files --app-path=custom-app/files \
    --command=/app/bin/hello.sh org.test.Hello > hello_out
assert_file_has_content hello_out '^Hello world, from a sandboxCUSTOM$'

run --usr-path=custom-runtime/files --app-path=custom-app/files \
    --command=/usr/bin/runtime_hello.sh org.test.Hello > hello_out
assert_file_has_content hello_out '^Hello world, from a runtimeCUSTOM$'

run --usr-path=custom-runtime/files --app-path=custom-app/files \
    --command=/run/parent/app/bin/hello.sh org.test.Hello > hello_out
assert_file_has_content hello_out '^Hello world, from a sandbox$'

run --usr-path=custom-runtime/files --app-path=custom-app/files \
    --command=/run/parent/usr/bin/runtime_hello.sh org.test.Hello > hello_out
assert_file_has_content hello_out '^Hello world, from a runtime$'

ok "custom usr and app path"

assert_fail run --usr-path=custom-runtime/files --app-path="" \
               --command=/app/bin/hello.sh org.test.Hello > /dev/null

run --usr-path=custom-runtime/files --app-path="" \
    --command=/usr/bin/runtime_hello.sh org.test.Hello > hello_out
assert_file_has_content hello_out '^Hello world, from a runtimeCUSTOM$'

run --usr-path=custom-runtime/files --app-path="" \
    --command=/run/parent/app/bin/hello.sh org.test.Hello > hello_out
assert_file_has_content hello_out '^Hello world, from a sandbox$'

run --usr-path=custom-runtime/files --app-path="" \
    --command=/run/parent/usr/bin/runtime_hello.sh org.test.Hello > hello_out
assert_file_has_content hello_out '^Hello world, from a runtime$'

ok "custom usr and empty app path"

path="$(readlink -f .)/foo"
echo "bar" > "${path}"

exec 3< "${path}"
run --bind-fd=3 --command=cat org.test.Hello "${path}" > hello_out
assert_file_has_content hello_out '^bar$'

exec 3< "${path}"
run --bind-fd=3 --command=bash org.test.Hello -c "echo baz > ${path}" > /dev/null
assert_file_has_content "${path}" '^baz$'
exec 3>&-

exec 3< "${path}"
run --ro-bind-fd=3 --command=cat org.test.Hello "${path}" > hello_out
assert_file_has_content hello_out '^baz$'
exec 3>&-

exec 3< "${path}"
assert_fail run --ro-bind-fd=3 --command=bash org.test.Hello -c "echo baz > ${path}" > /dev/null
exec 3>&-

ok "bind-fd and ro-bind-fd"

exec 3< custom-app/files
exec 4< custom-runtime/files
exec 5< "${path}"
exec 6< "${path}"
run --app-fd=3 --usr-fd=4 --bind-fd=5 --ro-bind-fd=6 \
    --command=sh org.test.Hello \
    -c 'for fd in $(ls /proc/self/fd); do readlink -f /proc/self/fd/$fd; done' > hello_out
exec 6>&-
exec 5>&-
exec 4>&-
exec 3>&-

wd="$(readlink -f .)"
while read fdpath; do
  if [[ "$fdpath" == "$wd"* && "$fdpath" != "$wd/hello_out" ]]; then
    assert_not_reached "A fd for '$fdpath' unexpectedly made it to the app"
  fi
done < hello_out

ok "check no fd leak"
===== ./tests/http-utils-test-server.py =====
#!/usr/bin/python3

from wsgiref.handlers import format_date_time
from email.utils import parsedate
from calendar import timegm
import gzip
import sys
import time
import zlib
import os

from urllib.parse import parse_qs
import http.server as http_server
from io import BytesIO

server_start_time = int(time.time())

def parse_http_date(date):
    parsed = parsedate(date)
    if parsed is not None:
        return timegm(parsed)
    else:
        return None

class RequestHandler(http_server.BaseHTTPRequestHandler):
    def do_GET(self):
        parts = self.path.split('?', 1)
        path = parts[0]
        if len(parts) == 1:
            query = {}
        else:
            query = parse_qs(parts[1], keep_blank_values=True)

        response = 200
        add_headers = {}

        if 'modified-time' in query:
            modified_since = self.headers.get("If-Modified-Since")
            if modified_since:
                modified_since_time = parse_http_date(modified_since)
                if modified_since_time <= server_start_time:
                    response = 304
            add_headers["Last-Modified"] = format_date_time(server_start_time)

        if 'etag' in query:
            etag = str(server_start_time)

            if self.headers.get("If-None-Match") == etag:
                response = 304
            add_headers['Etag'] = etag

        self.send_response(response)
        for k, v in list(add_headers.items()):
            self.send_header(k, v)

        if 'max-age' in query:
            self.send_header('Cache-Control', 'max-age=' + query['max-age'][0])
        if 'no-cache' in query:
            self.send_header('Cache-Control', 'no-cache')
        if 'expires-past' in query:
            self.send_header('Expires', format_date_time(server_start_time - 3600))
        if 'expires-future' in query:
            self.send_header('Expires', format_date_time(server_start_time + 3600))

        if response == 200:
            self.send_header("Content-Type", "text/plain; charset=UTF-8")

        contents = "path=" + self.path + "\n"

        if not 'ignore-accept-encoding' in query:
            accept_encoding = self.headers.get("Accept-Encoding")
            if accept_encoding and accept_encoding == 'gzip':
                self.send_header("Content-Encoding", "gzip")

                buf = BytesIO()
                gzfile = gzip.GzipFile(mode='wb', fileobj=buf)
                if isinstance(contents, bytes):
                    gzfile.write(contents)
                else:
                    gzfile.write(contents.encode('utf-8'))
                gzfile.close()
                contents = buf.getvalue()

        self.end_headers()

        if response == 200:
            if isinstance(contents, bytes):
                self.wfile.write(contents)
            else:
                self.wfile.write(contents.encode('utf-8'))

def run(dir):
    RequestHandler.protocol_version = "HTTP/1.0"
    httpd = http_server.HTTPServer( ("127.0.0.1", 0), RequestHandler)
    host, port = httpd.socket.getsockname()[:2]
    with open("httpd-port", 'w') as file:
        file.write("%d" % port)
    try:
        os.write(3, bytes("Started\n", 'utf-8'));
    except:
        pass
    print("Serving HTTP on port %d" % port);
    if dir:
        os.chdir(dir)
    httpd.serve_forever()

if __name__ == '__main__':
    dir = None
    if len(sys.argv) >= 2 and len(sys.argv[1]) > 0:
        dir = sys.argv[1]

    run(dir)

===== ./tests/oci-registry-client.py =====
#!/usr/bin/python3

import argparse
import ssl
import sys

import http.client
import urllib.parse


def get_conn(args):
    parsed = urllib.parse.urlparse(args.url)
    if parsed.scheme == "http":
        return http.client.HTTPConnection(host=parsed.hostname, port=parsed.port)
    elif parsed.scheme == "https":
        context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
        context.options |= ssl.OP_NO_TLSv1 | ssl.OP_NO_TLSv1_1
        if args.cert:
            context.load_cert_chain(certfile=args.cert, keyfile=args.key)
        if args.cacert:
            context.load_verify_locations(cafile=args.cacert)
        return http.client.HTTPSConnection(
            host=parsed.hostname, port=parsed.port, context=context
        )
    else:
        assert False, "Bad scheme: " + parsed.scheme


def run_add(args):
    params = {"d": args.oci_dir}
    if args.detach_icons:
        params["detach-icons"] = "1"
    query = urllib.parse.urlencode(params)
    conn = get_conn(args)
    path = "/testing/{repo}/{tag}?{query}".format(
        repo=args.repo, tag=args.tag, query=query
    )
    conn.request("POST", path)
    response = conn.getresponse()
    if response.status != 200:
        print(response.read(), file=sys.stderr)
        print("Failed: status={}".format(response.status), file=sys.stderr)
        sys.exit(1)


def run_delete(args):
    conn = get_conn(args)
    path = "/testing/{repo}/{ref}".format(repo=args.repo, ref=args.ref)
    conn.request("DELETE", path)
    response = conn.getresponse()
    if response.status != 200:
        print(response.read(), file=sys.stderr)
        print("Failed: status={}".format(response.status), file=sys.stderr)
        sys.exit(1)


def run_add_sig(args):
    params = {"s": args.signature}
    query = urllib.parse.urlencode(params)
    conn = get_conn(args)
    path = "/testing-sig/{repo}/{digest}?{query}".format(
        repo=args.repo, digest=args.digest, query=query
    )
    conn.request("POST", path)
    response = conn.getresponse()
    if response.status != 200:
        print(response.read(), file=sys.stderr)
        print("Failed: status={}".format(response.status), file=sys.stderr)
        sys.exit(1)


def run_delete_sig(args):
    conn = get_conn(args)
    path = "/testing-sig/{repo}/{digest}".format(
        repo=args.repo, digest=args.digest
    )
    conn.request("DELETE", path)
    response = conn.getresponse()
    if response.status != 200:
        print(response.read(), file=sys.stderr)
        print("Failed: status={}".format(response.status), file=sys.stderr)
        sys.exit(1)


parser = argparse.ArgumentParser()
parser.add_argument("--url", required=True)
parser.add_argument("--cacert")
parser.add_argument("--cert")
parser.add_argument("--key")

subparsers = parser.add_subparsers()
subparsers.required = True

add_parser = subparsers.add_parser("add")
add_parser.add_argument("repo")
add_parser.add_argument("tag")
add_parser.add_argument("oci_dir")
add_parser.add_argument("--detach-icons", action="store_true", default=False)
add_parser.set_defaults(func=run_add)

delete_parser = subparsers.add_parser("delete")
delete_parser.add_argument("repo")
delete_parser.add_argument("ref")
delete_parser.set_defaults(func=run_delete)

add_sig_parser = subparsers.add_parser("add-signature")
add_sig_parser.add_argument("repo")
add_sig_parser.add_argument("digest")
add_sig_parser.add_argument("signature")
add_sig_parser.set_defaults(func=run_add_sig)

delete_sig_parser = subparsers.add_parser("delete-signature")
delete_sig_parser.add_argument("repo")
delete_sig_parser.add_argument("digest")
delete_sig_parser.set_defaults(func=run_delete_sig)

args = parser.parse_args()
args.func(args)

===== ./tests/httpcache.c =====
#include "libglnx.h"
#include "common/flatpak-utils-http-private.h"
#include "common/flatpak-utils-private.h"

int
main (int argc, char *argv[])
{
  g_autoptr(FlatpakHttpSession) session = flatpak_create_http_session (PACKAGE_STRING);
  g_autoptr(GError) error = NULL;
  const char *url, *dest;
  int flags = 0;

  if (argc == 3)
    {
      url = argv[1];
      dest = argv[2];
    }
  else if (argc == 4 && g_strcmp0 (argv[1], "--compressed") == 0)
    {
      url = argv[2];
      dest = argv[3];
      flags |= FLATPAK_HTTP_FLAGS_STORE_COMPRESSED;
    }
  else
    {
      g_printerr ("Usage httpcache [--compressed] URL DEST\n");
      return 1;
    }


  if (!flatpak_cache_http_uri (session,
                               url, NULL,
                               flags,
                               AT_FDCWD, dest,
                               NULL, NULL, NULL, &error))
    {
      g_print ("%s\n", error->message);
      return 1;
    }
  else
    {
      g_print ("Server returned status 200: ok\n");
      return 0;
    }
}

===== ./tests/make-multi-collection-id-repo.sh =====
#!/bin/bash
#
# make-multi-collection-id-repo.sh: Creates an  ostree repository
# that will hold a different collection ID per ref.
#
# Copyright (C) 2017 Endless, Inc.
#
# Authors:
#     Joaquim Rocha <jrocha@endlessm.com>
#
# 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 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., 59 Temple Place - Suite 330,
# Boston, MA 02111-1307, USA.

set -e

. $(dirname $0)/libtest.sh

REPO_DIR=$1
REPO_NAME=$(basename $REPO_DIR)

COLLECTION_ID_PREFIX=org.test.Collection

ostree --repo=${REPO_DIR} init --mode=archive --collection-id=${COLLECTION_ID_PREFIX}1 >&2

for i in {1..3}; do
    APP_REPO=test${i}
    APP_REPO_DIR=`pwd`/repos/${APP_REPO}
    APP_ID=org.test.Hello${i}
    COLLECTION_ID=${COLLECTION_ID_PREFIX}${i}

    $(dirname $0)/make-test-app.sh repos/${APP_REPO} ${APP_ID} master ${COLLECTION_ID}
    ref=$(ostree --repo=${APP_REPO_DIR} refs | grep ${APP_ID})

    ostree --repo=${REPO_DIR} remote add --no-gpg-verify --collection-id=${COLLECTION_ID} ${APP_REPO} file://${APP_REPO_DIR} >&2
    ostree --repo=${REPO_DIR} pull ${APP_REPO} ${ref} >&2
done

ostree --repo=${REPO_DIR} summary --update >&2

===== ./tests/mock-flatpak.c =====
/* vi:set et sw=2 sts=2 cin cino=t0,f0,(0,{s,>2s,n-s,^-s,e-s:
 * Copyright © 2018-2021 Collabora Ltd.
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 */

#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

#include "libglnx.h"

#include <glib.h>
#include <gio/gio.h>

#include "flatpak-context-private.h"

int
main (int argc,
      char **argv)
{
  int i;

  g_info ("This is a mock implementation of `flatpak run` for the portal");

  for (i = 0; i < argc; i++)
    g_print ("argv[%d] = %s\n", i, argv[i]);

  for (i = 0; i < argc; i++)
    {
      if (g_str_has_prefix (argv[i], "--env-fd="))
        {
          g_autoptr(FlatpakContext) context = flatpak_context_new ();
          const char *value = argv[i] + strlen ("--env-fd=");
          g_autoptr(GError) error = NULL;
          guint64 fd;
          gchar *endptr;
          GHashTableIter iter;
          gpointer k, v;

          fd = g_ascii_strtoull (value, &endptr, 10);

          if (endptr == NULL || *endptr != '\0' || fd > G_MAXINT)
            g_error ("Not a valid file descriptor: %s", value);

          flatpak_context_parse_env_fd (context, (int) fd, &error);
          g_assert_no_error (error);

          g_hash_table_iter_init (&iter, context->env_vars);

          while (g_hash_table_iter_next (&iter, &k, &v))
            g_print ("env[%s] = %s\n", (const char *) k, (const char *) v);
        }
    }

  for (i = 0; i < 256; i++)
    {
      struct stat stat_buf;

      if (fstat (i, &stat_buf) < 0)
        {
          int saved_errno = errno;

          g_assert_cmpint (saved_errno, ==, EBADF);
        }
      else
        {
          g_print ("fd[%d] = (dev=%" G_GUINT64_FORMAT " ino=%" G_GUINT64_FORMAT ")\n",
                   i,
                   (guint64) stat_buf.st_dev,
                   (guint64) stat_buf.st_ino);
        }
    }

  return 0;
}

===== ./tests/make-test-app.sh =====
#!/bin/bash

set -e

# Don't inherit the -x from the testsuite
set +x

DIR=`mktemp -d`

REPO=$1
shift
APP_ID=$1
shift
BRANCH=$1
shift
COLLECTION_ID=$1
shift

if [ x$APP_ID = x ]; then
    APP_ID=org.test.Hello
fi

RUNTIME_BRANCH=${RUNTIME_BRANCH:-$BRANCH}

EXTRA="${1-}"

ARCH=`flatpak --default-arch`

# Init dir
cat > ${DIR}/metadata <<EOF
[Application]
name=$APP_ID
runtime=org.test.Platform/$ARCH/$RUNTIME_BRANCH
sdk=org.test.Platform/$ARCH/$RUNTIME_BRANCH
EOF

if [ x${REQUIRED_VERSION-} != x ]; then
cat >> ${DIR}/metadata <<EOF
required-flatpak=$REQUIRED_VERSION
EOF
fi

if [ x${INCLUDE_SPECIAL_CHARACTER-} != x ]; then
TAB=$'\t'
cat >> ${DIR}/metadata <<EOF
[Environment]
A=x${TAB}y
EOF
fi

cat >> ${DIR}/metadata <<EOF
[Extension $APP_ID.Locale]
directory=share/runtime/locale
autodelete=true
locale-subset=true
EOF

cat >> ${DIR}/metadata <<EOF
[Extension $APP_ID.Plugin]
directory=share/hello/extra
autodelete=true
no-autodownload=true
subdirectories=true
merge-dirs=plug-ins
EOF

if [ "$EXTRA" = "EXTENSIONS" ]; then
cat >> ${DIR}/metadata <<EOF
version=v2
EOF
else
cat >> ${DIR}/metadata <<EOF
version=v1
EOF
fi

mkdir -p ${DIR}/files/bin
cat > ${DIR}/files/bin/hello.sh <<EOF
#!/bin/sh
echo "Hello world, from a sandbox$EXTRA"
if [ "$EXTRA" = "SPIN" ]; then
  exec sh
fi
EOF
chmod a+x ${DIR}/files/bin/hello.sh

mkdir -p ${DIR}/files/share/applications
cat > ${DIR}/files/share/applications/org.test.Hello.desktop <<EOF
[Desktop Entry]
Version=1.0
Type=Application
Name=Hello
Exec=hello.sh
Icon=$APP_ID
MimeType=x-test/Hello;
EOF
cat > ${DIR}/files/share/applications/org.test.Hello.Again.desktop <<EOF
[Desktop Entry]
Version=1.0
Type=Application
Name=Hello Again
Exec=hello.sh --again
Icon=$APP_ID
MimeType=x-test/Hello;
X-Flatpak-RenamedFrom=hello-again.desktop;
EOF

mkdir -p ${DIR}/files/share/gnome-shell/search-providers
cat > ${DIR}/files/share/gnome-shell/search-providers/org.test.Hello.search-provider.ini <<EOF
[Shell Search Provider]
DesktopId=org.test.Hello.desktop
BusName=org.test.Hello.SearchProvider
ObjectPath=/org/test/Hello/SearchProvider
Version=2
EOF

mkdir -p ${DIR}/files/share/krunner/dbusplugins
cat > ${DIR}/files/share/krunner/dbusplugins/org.test.Hello.desktop <<EOF
[Desktop Entry]
Name=Hello
X-KDE-ServiceTypes=Plasma/Runner
Type=Service
Icon=org.test.Hello
X-KDE-ServiceTypes=Plasma/Runner
X-KDE-PluginInfo-EnabledByDefault=true
X-Plasma-API=DBus
X-Plasma-DBusRunner-Service=org.test.Hello.KRunner
X-Plasma-DBusRunner-Path=/org/test/Hello/KRunner
EOF

mkdir -p ${DIR}/files/share/icons/hicolor/64x64/apps
cp $(dirname $0)/org.test.Hello.png ${DIR}/files/share/icons/hicolor/64x64/apps/${APP_ID}.png
cp $(dirname $0)/org.test.Hello.png ${DIR}/files/share/icons/hicolor/64x64/apps/dont-export.png
mkdir -p ${DIR}/files/share/icons/HighContrast/64x64/apps
cp $(dirname $0)/org.test.Hello.png ${DIR}/files/share/icons/HighContrast/64x64/apps/${APP_ID}.png


mkdir -p ${DIR}/files/share/metainfo
cat <<EOF > ${DIR}/files/share/metainfo/${APP_ID}.metainfo.xml
<?xml version="1.0" encoding="UTF-8"?>
<components version="0.8">
  <component type="desktop">
    <id>$APP_ID.desktop</id>
    <name>Hello world test app: $APP_ID</name>
    <summary>Print a greeting</summary>
    <description><p>This is a test app.</p></description>
    <developer>
      <name>Developer name</name>
    </developer>
    <categories>
      <category>Utility</category>
    </categories>
    <icon height="64" width="64" type="cached">64x64/org.gnome.gedit.png</icon>
    <releases>
      <release timestamp="1525132800" version="0.0.1"/>
    </releases>
  </component>
</components>
EOF

# Also check that the legacy path works
mkdir -p ${DIR}/files/share/appdata
cat <<EOF > ${DIR}/files/share/appdata/${APP_ID}.cmd.appdata.xml
<?xml version="1.0" encoding="UTF-8"?>
<components version="0.8">
  <component type="console-application">
    <id>$APP_ID.cmd</id>
    <name>Command line client for Hello world test app</name>
    <summary>Adds cool functionality</summary>
    <provides>
      <binary>hello</binary>
    </provides>
  </component>
</components>
EOF

mkdir -p ${DIR}/files/share/app-info/xmls
mkdir -p ${DIR}/files/share/app-info/icons/flatpak/64x64
gzip -c ${DIR}/files/share/metainfo/${APP_ID}.metainfo.xml > ${DIR}/files/share/app-info/xmls/${APP_ID}.xml.gz
gzip -c ${DIR}/files/share/appdata/${APP_ID}.cmd.appdata.xml > ${DIR}/files/share/app-info/xmls/${APP_ID}.cmd.xml.gz
cp $(dirname $0)/org.test.Hello.png ${DIR}/files/share/app-info/icons/flatpak/64x64/${APP_ID}.png

if [ x$COLLECTION_ID != x ]; then
    collection_args=--collection-id=${COLLECTION_ID}
else
    collection_args=
fi

mkdir -p ${DIR}/files/share/locale
mkdir -p ${DIR}/files/share/runtime/locale/de
ln -s ../../share/runtime/locale/de/share/de ${DIR}/files/share/locale
mkdir -p ${DIR}/files/share/runtime/locale/fr
ln -s ../../share/runtime/locale/fr/share/fr ${DIR}/files/share/locale

flatpak build-finish ${BUILD_FINISH_ARGS-} --command=hello.sh ${DIR} >&2
mkdir -p repos
flatpak build-export --no-update-summary --disable-sandbox ${collection_args} ${GPGARGS-} ${EXPORT_ARGS-} ${REPO} ${DIR} ${BRANCH} >&2
rm -rf ${DIR}

# build a locale extension

DIR=`mktemp -d`

# Init dir
cat > ${DIR}/metadata <<EOF
[Runtime]
name=${APP_ID}.Locale

[ExtensionOf]
ref=app/$APP_ID/$ARCH/$BRANCH
EOF

cat > de.po <<EOF
msgid "Hello world"
msgstr "Hallo Welt"
EOF
mkdir -p ${DIR}/files/de/share/de/LC_MESSAGES
msgfmt --output-file ${DIR}/files/de/share/de/LC_MESSAGES/helloworld.mo de.po
cat > fr.po <<EOF
msgid "Hello world"
msgstr "Bonjour le monde"
EOF
mkdir -p ${DIR}/files/fr/share/fr/LC_MESSAGES
msgfmt --output-file ${DIR}/files/fr/share/fr/LC_MESSAGES/helloworld.mo fr.po

flatpak build-finish ${DIR} >&2
mkdir -p repos
flatpak build-export --no-update-summary --runtime ${collection_args} ${GPGARGS-} ${EXPORT_ARGS-} ${REPO} ${DIR} ${BRANCH} >&2
rm -rf ${DIR}

# build a plugin extension

DIR=`mktemp -d`

# Init dir
cat > ${DIR}/metadata <<EOF
[Runtime]
name=${APP_ID}.Plugin.fun

[ExtensionOf]
ref=app/$APP_ID/$ARCH/$BRANCH
EOF

mkdir -p ${DIR}/files/plug-ins/fun

flatpak build-finish ${DIR} >&2
mkdir -p repos

if [ "$EXTRA" = "EXTENSIONS" ]; then
  flatpak build-export --no-update-summary --runtime ${collection_args} ${GPGARGS-} ${EXPORT_ARGS-} ${REPO} ${DIR} v2 >&2
else
  flatpak build-export --no-update-summary --runtime ${collection_args} ${GPGARGS-} ${EXPORT_ARGS-} ${REPO} ${DIR} v1 >&2
fi

rm -rf ${DIR}

===== ./tests/flatpak.supp =====
# Use this to suppress "possibly lost" for global statistics
{
   handle_reflink
   Memcheck:Param
   ioctl(generic)
   fun:ioctl
   fun:btrfs_reflink_with_progress
   fun:file_copy_fallback
}

# https://github.com/ostreedev/ostree/issues/533
{
   ignore_static_delta_uninitialized
   Memcheck:Cond
   ...
   fun:_ostree_lzma_compressor_convert
   fun:write_internal
   fun:g_output_stream_real_splice
   fun:g_output_stream_splice
   fun:ostree_repo_static_delta_generate
}

# ioctl FICLONE is apparently not supported
{
   ignore_ioctl_ficlone
   Memcheck:Param
   ioctl(generic)
   fun:ioctl
   fun:glnx_regfile_copy_bytes
}

# There seem to be some leaks in "ostree pull", lets just ignore them for now
{
  ignore_ostree_pull1
  Memcheck:Leak
  fun:malloc
  ...
  fun:ostree_fetcher_session_thread
}
{
  ignore_ostree_pull2
  Memcheck:Leak
  fun:realloc
  ...
  fun:ostree_fetcher_session_thread
}
{
  ignore_ostree_pull3
  Memcheck:Leak
  fun:malloc
  ...
  fun:ostree_repo_write_metadata_async
}
{
  ignore_ostree_pull4
  Memcheck:Leak
  fun:calloc
  ...
  fun:ostree_repo_write_metadata_async
}
{
  ignore_ostree_pull5
  Memcheck:Leak
  fun:malloc
  ...
  fun:write_metadata_thread
}
{
  ignore_ostree_pull6
  Memcheck:Leak
  fun:calloc
  ...
  fun:write_metadata_thread
}
# static delta generation seem to leak too...
{
  ignore_ostree_delta1
  Memcheck:Leak
  fun:malloc
  ...
  fun:generate_delta_thread
}
{
  ignore_ostree_delta2
  Memcheck:Leak
  fun:calloc
  ...
  fun:generate_delta_thread
}
{
  ignore_ostree_delta3
  Memcheck:Leak
  fun:realloc
  ...
  fun:generate_delta_thread
}
# writing content...
{
  ignore_ostree_write_content1
  Memcheck:Leak
  fun:g_type_create_instance
  ...
  fun:write_content_thread
}
{
  ignore_ostree_write_content2
  Memcheck:Leak
  fun:malloc
  ...
  fun:write_content_thread
}
{
  ignore_ostree_write_content3
  Memcheck:Leak
  fun:malloc
  ...
  fun:ostree_repo_write_content_async
}

# Some glib threadpool issue?
{
  ignore_gthreadpool1
  Memcheck:Leak
  fun:calloc
  ...
  fun:g_idle_source_new
  ...
  fun:g_thread_pool_thread_proxy
}

# glibc valgrind fnmatch issue (https://www.mail-archive.com/kde-bugs-dist@kde.org/msg214842.html)
{
  ignore_glibc_fnmatch
  Memcheck:Cond
  fun:__wmemchr_avx2
  fun:internal_fnwmatch
  fun:fnmatch@@GLIBC_2.2.5
}

# ostree reflink check
{
  ignore_ostree_reflink_check_ioctl
  Memcheck:Param
  ioctl(generic)
  fun:ioctl
  fun:_check_support_reflink
}

# Some unsupported ioctl
{
   ignore_ostree_write_ioctl
   Memcheck:Param
   ioctl(generic)
   fun:ioctl
   obj:*/libostree-1.so.1.0.0
}

# ostree pthread_create issue
{
   ostree_pthread_create_issue
   Memcheck:Leak
   match-leak-kinds: possible
   fun:calloc
   fun:allocate_dtv
   fun:_dl_allocate_tls
   fun:pthread_create@@GLIBC_2.2.5
   fun:g_system_thread_new
}

# Weird leak of UnixInputStream in ostree, can't figure it out
{
   ostree_unix_stream_leak
   Memcheck:Leak
   match-leak-kinds: definite
   ...
   fun:g_type_create_instance
   ...
   fun:g_object_new
   fun:g_unix_input_stream_new
   fun:repo_load_file_archive
   fun:ostree_repo_load_file
   fun:_ostree_repo_import_object
   fun:async_import_in_thread
}
{
   ostree_mutable_tree_write_tree_leak
   Memcheck:Leak
   match-leak-kinds: definite
   fun:malloc
   ...
   fun:ostree_repo_write_dfd_to_mtree
}
{
   polkit_agent_leak
   Memcheck:Leak
   match-leak-kinds: definite
   fun:calloc
   fun:g_malloc0
   fun:thread_memory_from_self
   fun:g_slice_alloc
   fun:g_hash_table_new_full
   fun:g_main_context_new
}
{
   polkit_agent_leak2
   Memcheck:Leak
   match-leak-kinds: definite
   fun:malloc
   fun:g_malloc
   ...
   fun:polkit_agent_listener_register_with_options
   fun:main
}
{
   polkit_agent_leak3
   Memcheck:Leak
   match-leak-kinds: definite
   fun:realloc
   ...
   fun:polkit_agent_listener_register_with_options
}
# Ostree transaction repo locks seem to leak if the repo is not finalized on same thread
{
   ostree_repo_lock_leak
   Memcheck:Leak
   match-leak-kinds: definite
   fun:calloc
   fun:g_malloc0
   fun:push_repo_lock
}
# Some gnutls conditional failure
{
   gnutls_import_fail
   Memcheck:Cond
   ...
   fun:gnutls_x509_ext_import_subject_alt_names
   fun:gnutls_x509_crt_import
}
# Deliberately leaking once per process
{
   flatpak_get_user_base_dir_location
   Memcheck:Leak
   ...
   fun:g_file_new_for_path
   fun:flatpak_get_user_base_dir_location
}
# Deliberately leaking once per process
{
   flatpak_get_system_default_base_dir_location
   Memcheck:Leak
   ...
   fun:g_file_new_for_path
   fun:flatpak_get_system_default_base_dir_location
}

# https://github.com/ostreedev/ostree/issues/2592
{
   ostree_issue_2592
   Memcheck:Cond
   ...
   fun:_ostree_repo_auto_transaction_unref
   fun:glib_autoptr_clear_OstreeRepoAutoTransaction
   fun:glib_autoptr_cleanup_OstreeRepoAutoTransaction
   fun:ostree_repo_prepare_transaction
}

===== ./tests/test-extra-data.sh =====
#!/bin/bash
#
# Copyright (C) 2025 Red Hat, Inc
#
# 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 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., 59 Temple Place - Suite 330,
# Boston, MA 02111-1307, USA.

set -euo pipefail

. "$(dirname $0)/libtest.sh"

skip_without_bwrap

REPONAME="test"
BRANCH="master"
COLLECTION_ID="org.test.Collection.${REPONAME}"

setup_repo ${REPONAME} ${COLLECTION_ID}

# create the extra data
EXTRA_DATA_FILE="extra-data-test"
EXTRA_DATA_DIR="${TEST_DATA_DIR}/extra-data-server/"
mkdir -p "${EXTRA_DATA_DIR}"
echo "extra-data-test-content" > "${EXTRA_DATA_DIR}/${EXTRA_DATA_FILE}"

# serve the extra data
httpd web-server.py "${EXTRA_DATA_DIR}"
EXTRA_DATA_URL="http://127.0.0.1:$(cat httpd-port)/${EXTRA_DATA_FILE}"

# download to get the size and sha256 sum
DOWNLOADED_EXTRA_DATA="${TEST_DATA_DIR}/downloaded-extra-data"
curl "${EXTRA_DATA_URL}" -o "${DOWNLOADED_EXTRA_DATA}"
EXTRA_DATA_SIZE=$(stat --printf="%s" "${DOWNLOADED_EXTRA_DATA}")
EXTRA_DATA_SHA256=$(sha256sum "${DOWNLOADED_EXTRA_DATA}" | cut -f1 -d' ')

echo "1..3"

# build the app with the extra data
EXTRA_DATA="--extra-data=test:${EXTRA_DATA_SHA256}:${EXTRA_DATA_SIZE}:${EXTRA_DATA_SIZE}:${EXTRA_DATA_URL}"
BUILD_FINISH_ARGS=${EXTRA_DATA} make_updated_app ${REPONAME} ${COLLECTION_ID} ${BRANCH} UPDATE1

# ensure it installs correctly
install_repo ${REPONAME} ${BRANCH}

# ensure the right extra-data got downloaded
${FLATPAK} run --command=sh org.test.Hello -c "cat /app/extra/test" > out
assert_file_has_content out "extra-data-test-content"

${FLATPAK} ${U} uninstall -y org.test.Hello >&2

ok "install extra data app with ostree"

# Start the fake registry server

httpd oci-registry-server.py --dir=.
port=$(cat httpd-port)
scheme=http

client="python3 $test_srcdir/oci-registry-client.py --url=${scheme}://127.0.0.1:${port}"

# Add OCI bundles to it

${FLATPAK} build-bundle --runtime --oci $FL_GPGARGS repos/test oci/platform-image org.test.Platform >&2
$client add platform latest "$(pwd)/oci/platform-image"

${FLATPAK} build-bundle --oci $FL_GPGARGS repos/test oci/app-image org.test.Hello >&2
$client add hello latest "$(pwd)/oci/app-image"

# Add an OCI remote

${FLATPAK} remote-add ${U} oci-registry "oci+${scheme}://127.0.0.1:${port}" >&2

# Check that the images we expect are listed

images=$(${FLATPAK} remote-ls ${U} --columns=app oci-registry | sort | tr '\n' ' ' | sed 's/ $//')
assert_streq "$images" "org.test.Hello org.test.Platform"

${FLATPAK} ${U} install -y oci-registry org.test.Hello >&2

# ensure the right extra-data got downloaded
${FLATPAK} run --command=sh org.test.Hello -c "cat /app/extra/test" > out
assert_file_has_content out "extra-data-test-content"

${FLATPAK} ${U} uninstall -y org.test.Hello >&2

ok "install extra data app with oci"

build_extra_data_noruntime_app() {
    local repo="$1"
    local branch="$2"

    DIR="$(mktemp -d)"
    ARCH="$(flatpak --default-arch)"

    mkdir -p "${DIR}/files/bin"

    cp "${G_TEST_BUILDDIR}/apply-extra-static" "${DIR}/files/bin/apply_extra"
    chmod +x "${DIR}/files/bin/apply_extra"

    cat > "${DIR}/metadata" <<EOF
[Application]
name=org.test.ExtraDataNoRuntime
runtime=org.test.Platform/${ARCH}/${branch}

[Extra Data]
NoRuntime=true
uri=${EXTRA_DATA_URL}
size=${EXTRA_DATA_SIZE}
checksum=${EXTRA_DATA_SHA256}
EOF

    flatpak build-finish "${DIR}" >&2
    flatpak build-export ${FL_GPGARGS} "${repo}" "${DIR}" "${branch}" >&2
    rm -rf "${DIR}"
}

if test -f "${G_TEST_BUILDDIR}/apply-extra-static"; then
    build_extra_data_noruntime_app repos/test ${BRANCH}
    update_repo ${REPONAME} ${COLLECTION_ID}
    ${FLATPAK} ${U} install --or-update -y ${REPONAME}-repo org.test.ExtraDataNoRuntime ${BRANCH} >&2
    DEPLOY_DIR="$(${FLATPAK} ${U} info --show-location org.test.ExtraDataNoRuntime)"
    assert_file_has_content "${DEPLOY_DIR}/files/extra/ran" "^noruntime-extra-data$"
    ${FLATPAK} ${U} uninstall -y org.test.ExtraDataNoRuntime >&2
    ok "install+run extra data app with NoRuntime"
else
    ok "# SKIP install+run extra data app with NoRuntime apply-extra-static not found"
fi

===== ./tests/list-unused.c =====
#include "config.h"

#include "flatpak-dir-private.h"

static char **opt_exclude_refs;
static gboolean opt_user;
static gboolean opt_filter_eol;
static gboolean opt_filter_autoprune;

static GOptionEntry options[] = {
  { "user", 0, 0, G_OPTION_ARG_NONE, &opt_user, "Work on the user installation", NULL },
  { "exclude", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_exclude_refs, "Exclude ref", "REF" },
  { "filter-eol", 0, 0, G_OPTION_ARG_NONE, &opt_filter_eol, "Filter results to include end-of-life refs", NULL },
  { "filter-autoprune", 0, 0, G_OPTION_ARG_NONE, &opt_filter_autoprune, "Filter results to include autopruned refs", NULL },
  { NULL }
};


int
main (int argc, char *argv[])
{
  g_autoptr(FlatpakDir) dir = NULL;
  g_autoptr(GError) error = NULL;
  g_auto(GStrv) refs = NULL;
  g_autoptr(GOptionContext) context = NULL;
  FlatpakDirFilterFlags filter_flags = FLATPAK_DIR_FILTER_NONE;
  int i;

  context = g_option_context_new ("");

  g_option_context_add_main_entries (context, options, NULL);
  if (!g_option_context_parse (context, &argc, &argv, &error))
    {
      g_print("Arg error: %s\n", error->message);
      return 1;
    }

  if (opt_user)
    dir = flatpak_dir_get_user ();
  else
    dir = flatpak_dir_get_system_default ();

  if (opt_filter_eol)
    filter_flags |= FLATPAK_DIR_FILTER_EOL;

  if (opt_filter_autoprune)
    filter_flags |= FLATPAK_DIR_FILTER_AUTOPRUNE;

  refs = flatpak_dir_list_unused_refs (dir, NULL, NULL, NULL, (const char * const *)opt_exclude_refs, filter_flags, NULL, &error);
  g_assert_nonnull (refs);
  g_assert_no_error (error);

  for (i = 0; refs[i] != NULL; i++)
    g_print ("%s\n", refs[i]);

  return 0;
}

===== ./tests/test-update-portal.c =====
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>

#include <sys/stat.h>
#include <fcntl.h>

#include <gio/gio.h>
#include "portal/flatpak-portal.h"
#include "portal/flatpak-portal-dbus.h"

GDBusConnection *connection;

const char *portal_name = FLATPAK_PORTAL_BUS_NAME;
const char *portal_path = FLATPAK_PORTAL_PATH;

static PortalFlatpakUpdateMonitor *
create_monitor (PortalFlatpak *portal,
                GCallback update_available_cb,
                gpointer cb_data,
                GError **error)
{
  static int counter = 1;
  PortalFlatpakUpdateMonitor *monitor;
  g_autofree char *token = NULL;
  g_autofree char *monitor_path = NULL;
  g_autofree char *sender = NULL;
  g_autofree char *monitor_handle = NULL;
  char *s;
  GVariantBuilder opt_builder;

  sender = g_strdup (g_dbus_connection_get_unique_name (connection) + 1);
  while ((s = strchr (sender, '.')) != NULL)
    *s = '_';

  token = g_strdup_printf ("test_token%d", counter++);

  monitor_path = g_strdup_printf ("%s/update_monitor/%s/%s", FLATPAK_PORTAL_PATH, sender, token);
  monitor = portal_flatpak_update_monitor_proxy_new_sync (connection, G_DBUS_PROXY_FLAGS_NONE,
                                                          portal_name, monitor_path,
                                                          NULL, error);
  if (monitor == NULL)
    return NULL;

  if (update_available_cb)
    g_signal_connect (monitor, "update-available", update_available_cb, cb_data);

  g_variant_builder_init (&opt_builder, G_VARIANT_TYPE_VARDICT);
  g_variant_builder_add (&opt_builder, "{sv}", "handle_token", g_variant_new_string (token));

  if (!portal_flatpak_call_create_update_monitor_sync (portal,
                                                       g_variant_builder_end (&opt_builder),
                                                       &monitor_handle,
                                                       NULL, error))
    return NULL;

  return monitor;
}

static void
update_available (PortalFlatpakUpdateMonitor *object,
                  GVariant *arg_update_info,
                  gpointer user_data)
{
  const char *running, *local, *remote;

  g_variant_lookup (arg_update_info, "running-commit", "&s", &running);
  g_variant_lookup (arg_update_info, "local-commit", "&s", &local);
  g_variant_lookup (arg_update_info, "remote-commit", "&s", &remote);

  g_print ("update_available running=%s local=%s remote=%s\n", running, local, remote);
}

static void
write_status (int res, int status_pipe)
{
  char c = res;
  const ssize_t write_ret = write (status_pipe, &c, 1);
  if (write_ret < 0)
    g_printerr ("write_status() failed with %zd\n", write_ret);
}

typedef int (*TestCallback) (PortalFlatpak *portal, int status_pipe);

static int
monitor_test (PortalFlatpak *portal, int status_pipe)
{
  g_autoptr(GError) error = NULL;
  PortalFlatpakUpdateMonitor *monitor;
  GMainLoop *loop;

  monitor = create_monitor (portal,
                            (GCallback)update_available, NULL,
                            &error);
  if (monitor == NULL)
    {
      g_printerr ("Error creating monitor: %s\n", error->message);
      return 1;
    }

  /* Return 0, to indicate we've successfully started monitor */
  write_status (0, status_pipe);

  g_print ("Entering main loop waiting for updates\n");
  loop = g_main_loop_new (NULL, FALSE);
  g_main_loop_run (loop);

  return 0;
}

typedef enum {
  PROGRESS_STATUS_RUNNING = 0,
  PROGRESS_STATUS_EMPTY   = 1,
  PROGRESS_STATUS_DONE    = 2,
  PROGRESS_STATUS_ERROR   = 3
} UpdateStatus;

typedef struct {
  GMainLoop *loop;
  int expected_end_status;
  int expected_n_ops;
  const char *expected_error;

  int expected_op;

  int exit_status;
} UpdateData;

static void
progress_cb (PortalFlatpakUpdateMonitor *object,
             GVariant *arg_info,
             UpdateData *data)
{
  guint32 op = 0;
  guint32 n_ops = 0;
  guint32 progress = 0;
  guint32 status = 0;
  const char *error = "";
  const char *error_message = "";

  g_variant_lookup (arg_info, "op", "u", &op);
  g_variant_lookup (arg_info, "n_ops", "u", &n_ops);
  g_variant_lookup (arg_info, "progress", "u", &progress);
  g_variant_lookup (arg_info, "status", "u", &status);
  g_variant_lookup (arg_info, "error", "&s", &error);
  g_variant_lookup (arg_info, "error_message", "&s", &error_message);

  g_print ("progress op=%d n_ops=%d progress=%d status=%d error=%s error_message='%s'\n", op, n_ops, progress, status, error, error_message);

  if (status == PROGRESS_STATUS_RUNNING)
    {
      if (n_ops != data->expected_n_ops)
        {
          g_printerr ("Unexpected number of ops: %d (expected %d)\n", n_ops, data->expected_n_ops);
          data->exit_status = 1;
          g_main_loop_quit (data->loop);
        }

      if (op == data->expected_op)
        {
          if (progress == 100)
            data->expected_op = op + 1;
        }
      else
        {
          g_printerr ("Unexpected op nr: %d (expected %d)\n", op, data->expected_op);
          data->exit_status = 1;
          g_main_loop_quit (data->loop);
        }
    }
  else
    {
      if (data->expected_end_status != status)
        {
          g_printerr ("Unexpected end status: %d (error %s: %s)\n", status, error, error_message);
          data->exit_status = 1;
        }
      else if (status == PROGRESS_STATUS_DONE)
        {
          if (data->expected_op != data->expected_n_ops)
            {
              g_printerr ("Unexpected number of ops seen: %d, should be %d\n", data->expected_op, data->expected_n_ops);
              data->exit_status = 1;
            }
        }
      else if (status == PROGRESS_STATUS_ERROR)
        {
          if (data->expected_error != NULL &&
              strcmp (data->expected_error, error) != 0)
            {
              g_printerr ("Unexpected error: %s, should be %s\n", error, data->expected_error);
              data->exit_status = 1;
            }
        }

      g_main_loop_quit (data->loop);
    }
}

static int
update_test (PortalFlatpak *portal, int status_pipe)
{
  g_autoptr(GError) error = NULL;
  PortalFlatpakUpdateMonitor *monitor;
  GVariantBuilder opt_builder;
  g_autoptr(GMainLoop) loop = g_main_loop_new (NULL, FALSE);
  UpdateData data = { loop };

  monitor = create_monitor (portal, NULL, NULL, &error);
  if (monitor == NULL)
    {
      g_printerr ("Error creating monitor: %s\n", error->message);
      return 1;
    }

  g_variant_builder_init (&opt_builder, G_VARIANT_TYPE_VARDICT);

  g_signal_connect (monitor, "progress", G_CALLBACK (progress_cb), &data);

  data.expected_end_status = PROGRESS_STATUS_DONE;
  data.expected_n_ops = 2;

  if (!portal_flatpak_update_monitor_call_update_sync (monitor, "",
                                                       g_variant_builder_end (&opt_builder),
                                                       NULL, &error))
    {
      g_printerr ("Error calling update: %s\n", error->message);
      return 1;
    }

  g_main_loop_run (loop);

  return data.exit_status;
}

static int
update_null_test (PortalFlatpak *portal, int status_pipe)
{
  g_autoptr(GError) error = NULL;
  PortalFlatpakUpdateMonitor *monitor;
  GVariantBuilder opt_builder;
  g_autoptr(GMainLoop) loop = g_main_loop_new (NULL, FALSE);
  UpdateData data = { loop };

  monitor = create_monitor (portal, NULL, NULL, &error);
  if (monitor == NULL)
    {
      g_printerr ("Error creating monitor: %s\n", error->message);
      return 1;
    }

  g_variant_builder_init (&opt_builder, G_VARIANT_TYPE_VARDICT);

  g_signal_connect (monitor, "progress", G_CALLBACK (progress_cb), &data);

  data.expected_end_status = PROGRESS_STATUS_EMPTY;
  data.expected_n_ops = 0;

  if (!portal_flatpak_update_monitor_call_update_sync (monitor, "",
                                                       g_variant_builder_end (&opt_builder),
                                                       NULL, &error))
    {
      g_printerr ("Error calling update: %s\n", error->message);
      return 1;
    }

  g_main_loop_run (loop);

  return data.exit_status;
}

static int
update_fail_test (PortalFlatpak *portal, int status_pipe)
{
  g_autoptr(GError) error = NULL;
  PortalFlatpakUpdateMonitor *monitor;
  GVariantBuilder opt_builder;
  g_autoptr(GMainLoop) loop = g_main_loop_new (NULL, FALSE);
  UpdateData data = { loop };

  monitor = create_monitor (portal, NULL, NULL, &error);
  if (monitor == NULL)
    {
      g_printerr ("Error creating monitor: %s\n", error->message);
      return 1;
    }

  g_variant_builder_init (&opt_builder, G_VARIANT_TYPE_VARDICT);

  g_signal_connect (monitor, "progress", G_CALLBACK (progress_cb), &data);

  data.expected_end_status = PROGRESS_STATUS_ERROR;
  data.expected_n_ops = 2;

  if (!portal_flatpak_update_monitor_call_update_sync (monitor, "",
                                                       g_variant_builder_end (&opt_builder),
                                                       NULL, &error))
    {
      g_printerr ("Error calling update: %s\n", error->message);
      return 1;
    }

  g_main_loop_run (loop);

  return data.exit_status;
}

static int
update_notsupp_test (PortalFlatpak *portal, int status_pipe)
{
  g_autoptr(GError) error = NULL;
  PortalFlatpakUpdateMonitor *monitor;
  GVariantBuilder opt_builder;
  g_autoptr(GMainLoop) loop = g_main_loop_new (NULL, FALSE);
  UpdateData data = { loop };

  monitor = create_monitor (portal, NULL, NULL, &error);
  if (monitor == NULL)
    {
      g_printerr ("Error creating monitor: %s\n", error->message);
      return 1;
    }

  g_variant_builder_init (&opt_builder, G_VARIANT_TYPE_VARDICT);

  g_signal_connect (monitor, "progress", G_CALLBACK (progress_cb), &data);

  data.expected_end_status = PROGRESS_STATUS_ERROR;
  data.expected_n_ops = 2;
  data.expected_error = "org.freedesktop.DBus.Error.NotSupported";

  if (!portal_flatpak_update_monitor_call_update_sync (monitor, "",
                                                       g_variant_builder_end (&opt_builder),
                                                       NULL, &error))
    {
      g_printerr ("Error calling update: %s\n", error->message);
      return 1;
    }

  g_main_loop_run (loop);

  return data.exit_status;
}

static int
run_test (int status_pipe, const char *pidfile, TestCallback test)
{
  g_autoptr(GError) error = NULL;
  PortalFlatpak *portal;
  g_autofree char *pid = NULL;

  pid = g_strdup_printf ("%d", getpid ());
  if (!g_file_set_contents (pidfile, pid, -1, &error))
    {
      g_printerr ("Error creating pidfile: %s\n", error->message);
      return 1;
    }

  connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error);
  if (connection == NULL)
    {
      g_printerr ("Error connecting: %s\n", error->message);
      return 1;
    }

  portal = portal_flatpak_proxy_new_sync (connection, G_DBUS_PROXY_FLAGS_NONE,
                                          portal_name, portal_path,
                                          NULL, &error);
  if (portal == NULL)
    {
      g_printerr ("Error creating proxy: %s\n", error->message);
      return 1;
    }

  return test (portal, status_pipe);
}


int
main (int argc, char *argv[])
{
  pid_t pid;
  int pipes[2];
  TestCallback test_callback;

  if (argc < 2)
    {
      g_printerr ("No test command specified");
      return 1;
    }

  if (strcmp (argv[1], "monitor") == 0)
    test_callback = monitor_test;
  else if (strcmp (argv[1], "update") == 0)
    test_callback = update_test;
  else if (strcmp (argv[1], "update-null") == 0)
    test_callback = update_null_test;
  else if (strcmp (argv[1], "update-fail") == 0)
    test_callback = update_fail_test;
  else if (strcmp (argv[1], "update-notsupp") == 0)
    test_callback = update_notsupp_test;
  else
    {
      g_printerr ("Unknown command %s specified\n", argv[1]);
      return 1;
    }

  if (pipe (pipes) != 0)
    {
      perror ("pipe:");
      return 1;
    }

  pid = fork();
  if (pid == -1)
    {
      perror ("pipe:");
      return 1;
    }

  if (pid != 0)
    {
      char c;

      /* parent */
      close (pipes[1]);
      if (read (pipes[0], &c, 1) != 1)
        return 1;

      return c;
    }
  else
    {
      int res;

      close (pipes[0]);

      res = run_test (pipes[1], argc > 2 ? argv[2] : "pid.out", test_callback);
      /* If this returned early we have some setup failure, report it */
      write_status (res, pipes[1]);
      exit (res);
    }
}

===== ./tests/test-preinstall.sh =====
#!/bin/bash
#
# Copyright (C) 2025 Red Hat, Inc
#
# 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 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., 59 Temple Place - Suite 330,
# Boston, MA 02111-1307, USA.

set -euo pipefail

USE_COLLECTIONS_IN_SERVER=yes
USE_COLLECTIONS_IN_CLIENT=yes

. $(dirname $0)/libtest.sh

mkdir -p $FLATPAK_DATA_DIR/preinstall.d
mkdir -p $FLATPAK_CONFIG_DIR/preinstall.d

cat << EOF > hello-install.preinstall
[Flatpak Preinstall org.test.Hello]
EOF

cat << EOF > hello-not-install.preinstall
[Flatpak Preinstall org.test.Hello]
Install=false
EOF

cat << EOF > hello-install-multi.preinstall
[Flatpak Preinstall org.test.Hello]
[Flatpak Preinstall org.test.Hello2]
CollectionID=org.test.Collection.test
EOF

cat << EOF > hello-install-devel.preinstall
[Flatpak Preinstall org.test.Hello]
Branch=devel
EOF

cat << EOF > hello-install-collection.preinstall
[Flatpak Preinstall org.test.Hello2]
CollectionID=org.test.Collection.test2
EOF

cat << EOF > bad.preinstall
[Wrong Group]
a=b

[Flatpak Preinstall ]
Install=false

[Flatpak Preinstall]
Install=true
EOF

cat << EOF > hello-3.preinstall
[Flatpak Preinstall org.test.Hello3]
EOF

# Set up the runtimes
# org.test.Platform//master and org.test.Platform//devel
# and the apps
# org.test.Hello//master, org.test.Hello//devel,
# org.test.Hello2//master, org.test.Hello2//devel
setup_repo test
make_updated_runtime test org.test.Collection.test devel HELLO_DEVEL org.test.Hello
make_updated_app test org.test.Collection.test devel HELLO_DEVEL org.test.Hello
make_updated_app test org.test.Collection.test master HELLO2_MASTER org.test.Hello2
make_updated_app test org.test.Collection.test devel HELLO2_DEVEL org.test.Hello2

setup_repo test2
make_updated_app test2 org.test.Collection.test2 master HELLO2_MASTER_C2 org.test.Hello2
make_updated_app test2 org.test.Collection.test2 master HELLO2_MASTER_C3 org.test.Hello3

echo "1..12"

# just checking that the test remote got added
port=$(cat httpd-port)
assert_remote_has_config test-repo url "http://127.0.0.1:${port}/test"
assert_remote_has_config test2-repo url "http://127.0.0.1:${port}/test2"

ok "setup"

# if we have nothing configured and nothing is marked as preinstalled
# calling preinstall should be a no-op
${FLATPAK} ${U} preinstall -y > nothingtodo
assert_file_has_content nothingtodo "Nothing to do"

ok "no config"

# make sure nothing is installed
${FLATPAK} ${U} list --columns=ref > list-log
assert_file_empty list-log
assert_fail ostree config --repo=$XDG_DATA_HOME/flatpak/repo get --group "core" xa.preinstalled

# The preinstall config wants org.test.Hello.
cp hello-install.preinstall $FLATPAK_DATA_DIR/preinstall.d/

${FLATPAK} ${U} preinstall -y >&2

# Make sure it and the runtime were installed
${FLATPAK} ${U} list --columns=ref > list-log
assert_file_has_content     list-log "^org\.test\.Hello/.*/master$"
assert_not_file_has_content list-log "^org\.test\.Hello/.*/devel$"
assert_not_file_has_content list-log "^org\.test\.Hello2/.*/master$"
assert_not_file_has_content list-log "^org\.test\.Hello2/.*/devel$"
assert_file_has_content     list-log "^org\.test\.Platform/.*/master$"
assert_not_file_has_content list-log "^org\.test\.Platform/.*/devel$"

ostree config --repo=$XDG_DATA_HOME/flatpak/repo get --group "core" xa.preinstalled > marked-preinstalled
assert_file_has_content marked-preinstalled "^app/org\.test\.Hello/.*/master$"

ok "simple preinstall"

# Make sure calling preinstall with the same config again is a no-op...
${FLATPAK} ${U} preinstall -y > nothingtodo
assert_file_has_content nothingtodo "Nothing to do"

# ...and everything is still installed
${FLATPAK} ${U} list --columns=ref > list-log
assert_file_has_content     list-log "^org\.test\.Hello/.*/master$"
assert_not_file_has_content list-log "^org\.test\.Hello/.*/devel$"
assert_not_file_has_content list-log "^org\.test\.Hello2/.*/master$"
assert_not_file_has_content list-log "^org\.test\.Hello2/.*/devel$"
assert_file_has_content     list-log "^org\.test\.Platform/.*/master$"
assert_not_file_has_content list-log "^org\.test\.Platform/.*/devel$"

ok "simple preinstall no op"

${FLATPAK} ${U} uninstall -y org.test.Hello >&2

${FLATPAK} ${U} list --columns=ref > list-log
assert_not_file_has_content list-log "^org\.test\.Hello/.*/master$"
assert_not_file_has_content list-log "^org\.test\.Hello/.*/devel$"
assert_not_file_has_content list-log "^org\.test\.Hello2/.*/master$"
assert_not_file_has_content list-log "^org\.test\.Hello2/.*/devel$"
assert_file_has_content     list-log "^org\.test\.Platform/.*/master$"
assert_not_file_has_content list-log "^org\.test\.Platform/.*/devel$"

# Make sure calling preinstall with the same config again is a no-op
# Even if the user uninstalled the app (it is marked as preinstalled)
${FLATPAK} ${U} preinstall -y > nothingtodo
assert_file_has_content nothingtodo "Nothing to do"

# Make sure nothing has changed
${FLATPAK} ${U} list --columns=ref > list-log
assert_not_file_has_content list-log "^org\.test\.Hello/.*/master$"
assert_not_file_has_content list-log "^org\.test\.Hello/.*/devel$"
assert_not_file_has_content list-log "^org\.test\.Hello2/.*/master$"
assert_not_file_has_content list-log "^org\.test\.Hello2/.*/devel$"
assert_file_has_content     list-log "^org\.test\.Platform/.*/master$"
assert_not_file_has_content list-log "^org\.test\.Platform/.*/devel$"

ok "uninstall preinstall"

${FLATPAK} ${U} install test-repo -y org.test.Hello master >&2

${FLATPAK} ${U} list --columns=ref > list-log
assert_file_has_content     list-log "^org\.test\.Hello/.*/master$"
assert_not_file_has_content list-log "^org\.test\.Hello/.*/devel$"
assert_not_file_has_content list-log "^org\.test\.Hello2/.*/master$"
assert_not_file_has_content list-log "^org\.test\.Hello2/.*/devel$"
assert_file_has_content     list-log "^org\.test\.Platform/.*/master$"
assert_not_file_has_content list-log "^org\.test\.Platform/.*/devel$"

# Add a config to /etc which overwrites the config in /usr ($FLATPAK_DATA_DIR)
# It has the Install=false setting which means it shall not be installed.
cp hello-not-install.preinstall $FLATPAK_CONFIG_DIR/preinstall.d/

${FLATPAK} ${U} preinstall -y >&2

# Make sure preinstall removed org.test.Hello as indicated by the config
${FLATPAK} ${U} list --columns=ref > list-log
assert_not_file_has_content list-log "^org\.test\.Hello/.*/master$"
assert_not_file_has_content list-log "^org\.test\.Hello/.*/devel$"
assert_not_file_has_content list-log "^org\.test\.Hello2/.*/master$"
assert_not_file_has_content list-log "^org\.test\.Hello2/.*/devel$"
assert_file_has_content     list-log "^org\.test\.Platform/.*/master$"
assert_not_file_has_content list-log "^org\.test\.Platform/.*/devel$"

ok "preinstall install false"

# Remove the existing configs
rm -rf $FLATPAK_CONFIG_DIR/preinstall.d/*
rm -rf $FLATPAK_DATA_DIR/preinstall.d/*

# Add a config file which wants org.test.Hello and org.test.Hello2 installed
cp hello-install-multi.preinstall $FLATPAK_DATA_DIR/preinstall.d/

${FLATPAK} ${U} preinstall -y >&2

# Make sure both apps got installed
${FLATPAK} ${U} list --columns=ref > list-log
assert_file_has_content     list-log "^org\.test\.Hello/.*/master$"
assert_not_file_has_content list-log "^org\.test\.Hello/.*/devel$"
assert_file_has_content     list-log "^org\.test\.Hello2/.*/master$"
assert_not_file_has_content list-log "^org\.test\.Hello2/.*/devel$"
assert_file_has_content     list-log "^org\.test\.Platform/.*/master$"
assert_not_file_has_content list-log "^org\.test\.Platform/.*/devel$"

if have_working_bwrap; then
  # Also make sure we installed the app from the right CollectionID
  ${FLATPAK} run org.test.Hello2 > hello2-output
  assert_file_has_content hello2-output "HELLO2_MASTER$"
fi

ok "install multi"

# Overwrite the branch of org.test.Hello from master to devel
cp hello-install-devel.preinstall $FLATPAK_CONFIG_DIR/preinstall.d/

${FLATPAK} ${U} preinstall -y >&2

# Make sure org.test.Hello//devel replaced org.test.Hello//master
${FLATPAK} ${U} list --columns=ref > list-log
assert_not_file_has_content list-log "^org\.test\.Hello/.*/master$"
assert_file_has_content     list-log "^org\.test\.Hello/.*/devel$"
assert_file_has_content     list-log "^org\.test\.Hello2/.*/master$"
assert_not_file_has_content list-log "^org\.test\.Hello2/.*/devel$"
assert_file_has_content     list-log "^org\.test\.Platform/.*/master$"
assert_file_has_content     list-log "^org\.test\.Platform/.*/devel$"

ok "overwrite branch"

# Overwrite the CollectionID we're installing org.test.Hello2 from
cp hello-install-collection.preinstall $FLATPAK_CONFIG_DIR/preinstall.d/

# Changing the collection id doesn't automatically change apps over so we need
# to uninstall and mark it as not pre-installed
${FLATPAK} ${U} uninstall -y org.test.Hello2 >&2
ostree config --repo=$XDG_DATA_HOME/flatpak/repo unset --group "core" xa.preinstalled

${FLATPAK} ${U} preinstall -y >&2

if have_working_bwrap; then
  # Make sure the app with the right CollectionID got installed
  ${FLATPAK} run org.test.Hello2 > hello2-output
  assert_file_has_content hello2-output "HELLO2_MASTER_C2$"
fi

ok "change collection id"

# Make sure some config file parsing edge cases don't blow up
cp bad.preinstall $FLATPAK_CONFIG_DIR/preinstall.d/

${FLATPAK} ${U} preinstall -y > nothingtodo
assert_file_has_content nothingtodo "Nothing to do"

ok "bad config"

# Hello3 is in the second repo. Make sure we still manage to install it.
cp hello-3.preinstall $FLATPAK_CONFIG_DIR/preinstall.d/

${FLATPAK} ${U} preinstall -y >&2

${FLATPAK} ${U} list --columns=ref > list-log
assert_file_has_content list-log "^org\.test\.Hello3/.*/master$"

ok "app not in first repo"

# create sideload repo
${FLATPAK} ${U} install -y test-repo org.test.Hello//master >&2
mkdir usb_dir
${FLATPAK} ${U} create-usb --destination-repo=repo usb_dir org.test.Hello//master >&2
SIDELOAD_REPO=$(realpath usb_dir/repo)
${FLATPAK} ${U} uninstall -y --all >&2

# make sure nothing is installed
${FLATPAK} ${U} list --columns=ref > list-log
assert_file_empty list-log
ostree config --repo=$XDG_DATA_HOME/flatpak/repo unset --group "core" xa.preinstalled

# The preinstall config wants org.test.Hello.
cp hello-install.preinstall $FLATPAK_DATA_DIR/preinstall.d/

# simulate broken network
${FLATPAK} ${U} remote-modify --url="http://no.127.0.0.1:${port}/test" test-repo >&2
${FLATPAK} ${U} remote-modify --url="http://no.127.0.0.1:${port}/test" test2-repo >&2

# ensure that installation from the sideload repo works
${FLATPAK} ${U} -vvvv preinstall -y --sideload-repo=${SIDELOAD_REPO} >&2

ok "sideload with network failure"
===== ./tests/test-summaries.sh =====
#!/bin/bash
#
# Copyright (C) 2020 Alexander Larsson <alexl@redhat.com>
#
# 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 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., 59 Temple Place - Suite 330,
# Boston, MA 02111-1307, USA.

set -euo pipefail

. $(dirname $0)/libtest.sh

echo "1..2"

setup_repo

sha256() {
    sha256sum -b | awk "{ print \$1 }"
}

gunzip_sha256() {
    gunzip -c $1 | sha256
}

make_app() {
    APP_ID=$1
    APPARCH=$2
    REPO=$3

    DIR=`mktemp -d`
    cat > ${DIR}/metadata <<EOF
[Application]
name=$APP_ID
runtime=org.test.Platform/$APPARCH/master
EOF

    mkdir -p ${DIR}/files/bin
    cat > ${DIR}/files/bin/hello.sh <<EOF
#!/bin/sh
echo "Hello world, from a sandbox"
EOF
    chmod a+x ${DIR}/files/bin/hello.sh

    mkdir -p ${DIR}/files/share/app-info/xmls
    mkdir -p ${DIR}/files/share/app-info/icons/flatpak/64x64
    gzip -c > ${DIR}/files/share/app-info/xmls/${APP_ID}.xml.gz <<EOF
<?xml version="1.0" encoding="UTF-8"?>
<components version="0.8">
  <component type="desktop">
    <id>$APP_ID.desktop</id>
    <name>Hello world test app: $APP_ID</name>
    <summary>Print a greeting</summary>
    <description><p>This is a test app.</p></description>
    <releases>
      <release timestamp="1525132800" version="0.0.1"/>
    </releases>
  </component>
</components>
EOF
    cp $(dirname $0)/org.test.Hello.png ${DIR}/files/share/app-info/icons/flatpak/64x64/${APP_ID}.png

    $FLATPAK build-finish --command=hello.sh ${DIR} &> /dev/null
    $FLATPAK build-export --no-update-summary ${GPGARGS} --arch=$APPARCH --disable-sandbox  ${REPO} ${DIR} &> /dev/null
    rm -rf ${DIR}
}

active_subsets() {
    REPO=$1
    $FLATPAK repo --subsets $REPO | awk "{ print \$2 }"
}

active_subset_for_arch() {
    REPO=$1
    THE_ARCH=$2
    $FLATPAK repo --subsets $REPO --subset $THE_ARCH | awk "{ print \$2 }"
}

active_subset() {
    active_subset_for_arch $1 $ARCH
}

n_histories() {
    REPO=$1
    $FLATPAK repo --subsets $REPO | awk "{ sum +=\$3 } END {print sum}"
}

verify_subsummaries() {
    REPO=$1

    ACTIVE_SUBSETS=$(active_subsets $REPO)
    for SUBSET in $ACTIVE_SUBSETS; do
        assert_has_file $REPO/summaries/$SUBSET.gz
    done

    N_HISTORIES=$(n_histories $REPO)

    N_DELTAS=0
    for DELTA_FILE in $REPO/summaries/*.delta; do
        DELTA=$(basename $DELTA_FILE .delta)
        FROM=$(echo $DELTA | cut -d "-" -f 1)
        TO=$(echo $DELTA | cut -d "-" -f 2)

        # All TO should be in an active SUBSET
        if [[ "$ACTIVE_SUBSETS" != *"$TO"* ]]; then
            assert_not_reached
        fi
        N_DELTAS=$(($N_DELTAS+1))
    done
    assert_streq "$N_DELTAS" "$N_HISTORIES"

    N_OLD=0
    for SUMMARY_FILE in $REPO/summaries/*.gz; do
        DIGEST=$(basename $SUMMARY_FILE .gz)
        COMPUTED_DIGEST=$(gunzip_sha256 $SUMMARY_FILE)
        assert_streq "$DIGEST" "$COMPUTED_DIGEST"

        if [[ "$ACTIVE_SUBSETS" != *"$DIGEST"* ]]; then
            N_OLD=$(($N_OLD+1))
        fi
    done
    assert_streq "$N_OLD" "$N_HISTORIES"

}

set +x

# A non-default arch (that isn't compatible)
if [ $ARCH == x86_64 -o $ARCH == i386 ]; then
    OTHER_ARCH=aarch64
else
    OTHER_ARCH=x86_64
fi

# Set up some arches, including the current one
declare -A arches
for A in x86_64 aarch64 arm $($FLATPAK --supported-arches); do
    arches[$A]=1
done
ARCHES=${!arches[@]}

for A in $ARCHES; do
    # Create runtimes for all arches (based on $ARCH version)
    if [ $A != $ARCH ]; then
        $FLATPAK build-commit-from  ${GPGARGS} --src-ref=runtime/org.test.Platform/$ARCH/master repos/test runtime/org.test.Platform/$A/master >&2
    fi

    # Create a bunch of apps (for all arches)
    for I in $(seq 10); do
        make_app org.app.App$I $A repos/test
    done

    update_repo

    # Make sure we have no superfluous summary files
    verify_subsummaries repos/test
done

set -x

ok subsummary update generations

ACTIVE_SUBSET=$(active_subset repos/test)
ACTIVE_SUBSET_OTHER=$(active_subset_for_arch repos/test $OTHER_ARCH)

# Ensure we have no initial cache
rm -rf $FL_CACHE_DIR/summaries/*

assert_not_has_file $FL_CACHE_DIR/summaries/test-repo-${ACTIVE_SUBSET}.sub
assert_not_has_file $FL_CACHE_DIR/summaries/test-repo-${ACTIVE_SUBSET_OTHER}.sub

httpd_clear_log
# Prime cache for default arch
$FLATPAK $U remote-ls test-repo  > /dev/null

assert_has_file $FL_CACHE_DIR/summaries/test-repo-${ARCH}-${ACTIVE_SUBSET}.sub
assert_not_has_file $FL_CACHE_DIR/summaries/test-repo-${OTHER_ARCH}-${ACTIVE_SUBSET_OTHER}.sub
# We downloaded the full summary (not delta)
assert_file_has_content httpd-log summaries/${ACTIVE_SUBSET}.gz

httpd_clear_log
$FLATPAK $U remote-ls test-repo --arch=$OTHER_ARCH  > /dev/null

assert_has_file $FL_CACHE_DIR/summaries/test-repo-${ARCH}-${ACTIVE_SUBSET}.sub
assert_has_file $FL_CACHE_DIR/summaries/test-repo-${OTHER_ARCH}-${ACTIVE_SUBSET_OTHER}.sub
# We downloaded the full summary (not delta)
assert_file_has_content httpd-log summaries/${ACTIVE_SUBSET_OTHER}.gz

# Modify the ARCH subset
$FLATPAK build-commit-from ${GPGARGS} --src-ref=app/org.app.App1/$ARCH/master repos/test app/org.app.App1.NEW/$ARCH/master >&2

OLD_ACTIVE_SUBSET=$ACTIVE_SUBSET
OLD_ACTIVE_SUBSET_OTHER=$ACTIVE_SUBSET_OTHER
ACTIVE_SUBSET=$(active_subset repos/test)
ACTIVE_SUBSET_OTHER=$(active_subset_for_arch repos/test $OTHER_ARCH)

assert_not_streq "$OLD_ACTIVE_SUBSET" "$ACTIVE_SUBSET"
assert_streq "$OLD_ACTIVE_SUBSET_OTHER" "$ACTIVE_SUBSET_OTHER"

sleep 1 # Ensure mtime differs for cached summary files (so they are removed)
httpd_clear_log
$FLATPAK $U remote-ls test-repo > /dev/null

assert_has_file $FL_CACHE_DIR/summaries/test-repo-${ARCH}-${ACTIVE_SUBSET}.sub
assert_not_has_file $FL_CACHE_DIR/summaries/test-repo-${ARCH}-${OLD_ACTIVE_SUBSET}.sub
assert_has_file $FL_CACHE_DIR/summaries/test-repo-${OTHER_ARCH}-${ACTIVE_SUBSET_OTHER}.sub # This is the same as before
# We should have uses the delta
assert_not_file_has_content httpd-log summaries/${ACTIVE_SUBSET}.gz
assert_file_has_content httpd-log summaries/${OLD_ACTIVE_SUBSET}-${ACTIVE_SUBSET}.delta

# Modify the ARCH *and* OTHER_ARCH subset
$FLATPAK build-commit-from ${GPGARGS} --src-ref=app/org.app.App1/$ARCH/master repos/test app/org.app.App1.NEW2/$ARCH/master >&2
$FLATPAK build-commit-from ${GPGARGS} --src-ref=app/org.app.App1/$OTHER_ARCH/master repos/test app/org.app.App1.NEW2/$OTHER_ARCH/master >&2

OLD_OLD_ACTIVE_SUBSET=$OLD_ACTIVE_SUBSET
OLD_OLD_ACTIVE_SUBSET_OTHER=$OLD_ACTIVE_SUBSET_OTHER
OLD_ACTIVE_SUBSET=$ACTIVE_SUBSET
OLD_ACTIVE_SUBSET_OTHER=$ACTIVE_SUBSET_OTHER
ACTIVE_SUBSET=$(active_subset repos/test)
ACTIVE_SUBSET_OTHER=$(active_subset_for_arch repos/test $OTHER_ARCH)

assert_not_streq "$OLD_ACTIVE_SUBSET" "$ACTIVE_SUBSET"
assert_not_streq "$OLD_ACTIVE_SUBSET_OTHER" "$ACTIVE_SUBSET_OTHER"

sleep 1 # Ensure mtime differs for cached summary files (so they are removed)
httpd_clear_log
$FLATPAK $U remote-ls test-repo > /dev/null # Only update for $ARCH

assert_has_file $FL_CACHE_DIR/summaries/test-repo-${ARCH}-${ACTIVE_SUBSET}.sub
assert_not_has_file $FL_CACHE_DIR/summaries/test-repo-${ARCH}-${OLD_ACTIVE_SUBSET}.sub
# We didn't get OTHER_ARCH summary
assert_not_has_file $FL_CACHE_DIR/summaries/test-repo-${OTHER_ARCH}-${ACTIVE_SUBSET_OTHER}.sub
assert_has_file $FL_CACHE_DIR/summaries/test-repo-${OTHER_ARCH}-${OLD_ACTIVE_SUBSET_OTHER}.sub
# We should have used the delta
assert_not_file_has_content httpd-log summaries/${ACTIVE_SUBSET}.gz
assert_file_has_content httpd-log summaries/${OLD_ACTIVE_SUBSET}-${ACTIVE_SUBSET}.delta

sleep 1 # Ensure mtime differs for cached summary files (so they are removed)
httpd_clear_log
$FLATPAK $U remote-ls --arch=* test-repo > /dev/null # update for all arches

assert_has_file $FL_CACHE_DIR/summaries/test-repo-${ARCH}-${ACTIVE_SUBSET}.sub
assert_not_has_file $FL_CACHE_DIR/summaries/test-repo-${ARCH}-${OLD_ACTIVE_SUBSET}.sub
assert_has_file $FL_CACHE_DIR/summaries/test-repo-${OTHER_ARCH}-${ACTIVE_SUBSET_OTHER}.sub
assert_not_has_file $FL_CACHE_DIR/summaries/test-repo-${OTHER_ARCH}-${OLD_ACTIVE_SUBSET_OTHER}.sub
# We should have used the delta
assert_not_file_has_content httpd-log summaries/${ACTIVE_SUBSET_OTHER}.gz
assert_file_has_content httpd-log summaries/${OLD_ACTIVE_SUBSET_OTHER}-${ACTIVE_SUBSET_OTHER}.delta
# We should have used the $ARCH one from the cache
assert_not_file_has_content httpd-log summaries/${ACTIVE_SUBSET}.gz
assert_not_file_has_content httpd-log summaries/${OLD_ACTIVE_SUBSET}-${ACTIVE_SUBSET}.delta

ok subsummary fetching and caching

===== ./tests/test-sideload.sh =====
#!/bin/bash
#
# Copyright (C) 2011 Colin Walters <walters@verbum.org>
#
# 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 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., 59 Temple Place - Suite 330,
# Boston, MA 02111-1307, USA.

set -euo pipefail

USE_COLLECTIONS_IN_SERVER=yes
USE_COLLECTIONS_IN_CLIENT=yes

. $(dirname $0)/libtest.sh

skip_without_bwrap
skip_revokefs_without_fuse

echo "1..9"

#Regular repo
setup_repo

# Ensure we have the full locale extension:
${FLATPAK} ${U} config  --set languages "*" >&2

${FLATPAK} ${U} install -y test-repo org.test.Hello >&2

mkdir usb_dir

${FLATPAK} ${U} create-usb --destination-repo=repo usb_dir org.test.Hello >&2

assert_has_file usb_dir/repo/config
assert_has_file usb_dir/repo/summary
assert_has_file usb_dir/repo/refs/mirrors/org.test.Collection.test/app/org.test.Hello/${ARCH}/master
assert_has_file usb_dir/repo/refs/mirrors/org.test.Collection.test/runtime/org.test.Hello.Locale/${ARCH}/master
assert_has_file usb_dir/repo/refs/mirrors/org.test.Collection.test/runtime/org.test.Platform/${ARCH}/master
assert_has_file usb_dir/repo/refs/mirrors/org.test.Collection.test/appstream2/${ARCH}

${FLATPAK} ${U} uninstall -y --all >&2

ok "created sideloaded repo"

${FLATPAK} ${U} remote-modify --url="http://no.127.0.0.1:${port}/test" test-repo >&2

if ${FLATPAK} ${U} install -y test-repo org.test.Hello &> /dev/null; then
    assert_not_reached "Should not be able to install with wrong url"
fi

mkdir $FL_DIR/sideload-repos
SIDELOAD_REPO_LINK=$FL_DIR/sideload-repos/sideload1
mkdir $FLATPAK_RUN_DIR/sideload-repos
SIDELOAD_REPO_LINK2=$FLATPAK_RUN_DIR/sideload-repos/sideload1

SIDELOAD_REPO=$(realpath usb_dir/repo)

# This one uses the sideload repo in /run, the rest in the flatpak dir
ln -s $SIDELOAD_REPO $SIDELOAD_REPO_LINK2

${FLATPAK} ${U} install -y test-repo org.test.Hello >&2
assert_has_file $FL_DIR/app/org.test.Hello/$ARCH/master/active/metadata
assert_has_file $FL_DIR/repo/refs/remotes/test-repo/app/org.test.Hello/${ARCH}/master
assert_not_has_file $FL_DIR/repo/refs/mirrors/org.test.Collection.test/app/org.test.Hello/${ARCH}/master

ok "installed sideloaded app"

rm $SIDELOAD_REPO_LINK2

${FLATPAK} ${U} uninstall -y org.test.Hello >&2
${FLATPAK} ${U} install --sideload-repo=${SIDELOAD_REPO} -y test-repo org.test.Hello >&2

assert_has_file $FL_DIR/app/org.test.Hello/$ARCH/master/active/metadata
assert_has_file $FL_DIR/repo/refs/remotes/test-repo/app/org.test.Hello/${ARCH}/master
assert_not_has_file $FL_DIR/repo/refs/mirrors/org.test.Collection.test/app/org.test.Hello/${ARCH}/master

ln -s $SIDELOAD_REPO $SIDELOAD_REPO_LINK

ok "installed w/ runtime sideload option"

# Remove old appstream checkouts so we can update from the sideload
rm -rf $FL_DIR/appstream/test-repo/$ARCH/
rm -rf $FL_DIR/repo/refs/remotes/test-repo/appstream2/$ARCH
ostree prune --repo=$FL_DIR/repo --refs-only >&2

${FLATPAK} ${U} update --appstream test-repo >&2

assert_has_file $FL_DIR/appstream/test-repo/$ARCH/active/appstream.xml

ok "updated sideloaded appstream"

${FLATPAK} ${U} remote-modify --url="http://127.0.0.1:${port}/test" test-repo >&2
${FLATPAK} ${U} uninstall -y --all >&2

# Disable sideload repo and "break" online repo
rm $SIDELOAD_REPO_LINK
mv repos/test/objects repos/test/objects.disabled

httpd_clear_log

# Ensure this fails (but still loads summary)
if ${FLATPAK} ${U} install -y test-repo org.test.Hello &> install-error-log; then
    assert_not_reached "Disabled online install broken"
fi
assert_file_has_content install-error-log "Server returned .*404.*"
assert_file_has_content httpd-log "GET .*commit .*404"

ln -s $SIDELOAD_REPO $SIDELOAD_REPO_LINK

${FLATPAK} ${U} install -y test-repo org.test.Hello >&2
assert_has_file $FL_DIR/app/org.test.Hello/$ARCH/master/active/metadata

# Re-enable online repo
mv repos/test/objects.disabled repos/test/objects

ok "installed sideloaded app when online"

OLD_COMMIT=$(cat repos/test/refs/heads/app/org.test.Hello/${ARCH}/master)

# Make new app version
make_updated_app
update_repo

NEW_COMMIT=$(cat repos/test/refs/heads/app/org.test.Hello/$ARCH/master)

# (Re)install the new version (online), ensure we used sideload repo for objects shared between new and old version
SHARED_OBJECT=$(ostree ls --repo=repos/test -C app/org.test.Hello/$ARCH/master /files/share/applications/org.test.Hello.desktop | awk '{ print $5 }')
SHARED_OBJECT_PATH=$(commit_to_path $SHARED_OBJECT filez)
${FLATPAK} ${U} uninstall -y app/org.test.Hello/$ARCH/master >&2

httpd_clear_log
${FLATPAK} ${U} install -y app/org.test.Hello/$ARCH/master >&2

assert_not_file_has_content httpd-log "GET /test/${SHARED_OBJECT_PATH}"

# Prepare sideload repo for NEW_COMMIT
${FLATPAK} ${U} create-usb --destination-repo=repo2 usb_dir org.test.Hello >&2

UPDATED_COMMIT=$( ${FLATPAK} ${U} info --show-commit app/org.test.Hello/${ARCH}/master )
assert_streq "$NEW_COMMIT" "$UPDATED_COMMIT"

# Update again should do nothing
${FLATPAK} ${U} update -y >&2
UPDATED_COMMIT=$( ${FLATPAK} ${U} info --show-commit app/org.test.Hello/${ARCH}/master )
assert_streq "$NEW_COMMIT" "$UPDATED_COMMIT"

# Ensure that offline update don't downgrade to older version
${FLATPAK} ${U} remote-modify --url="http://no.127.0.0.1:${port}/test" test-repo >&2
${FLATPAK} ${U} update -y >&2
UPDATED_COMMIT=$( ${FLATPAK} ${U} info --show-commit app/org.test.Hello/${ARCH}/master )
assert_streq "$NEW_COMMIT" "$UPDATED_COMMIT"

ok "updates from sideload don't go backwards"

if [ x${USE_SYSTEMDIR-} == xyes ]; then
    # --commit + --system works only as root, so lets just "fake it" by installing the current sideload version
    ${FLATPAK} ${U} uninstall -y --no-related org.test.Hello >&2
    ${FLATPAK} ${U} install -y org.test.Hello >&2
else
    # Try (offline) to update to the old version
    ${FLATPAK} ${U} update -y --commit $OLD_COMMIT org.test.Hello >&2
fi

UPDATED_COMMIT=$( ${FLATPAK} ${U} info --show-commit app/org.test.Hello/${ARCH}/master )
assert_streq "$OLD_COMMIT" "$UPDATED_COMMIT"

ok "update to explicit old version"

# Switch to updated usb repo
mv usb_dir/repo usb_dir/repo.old
mv usb_dir/repo2 usb_dir/repo

# Try with --sideload-repo instead of config
rm $SIDELOAD_REPO_LINK

# And update to it (offline)
${FLATPAK} ${U} update -y --sideload-repo=${SIDELOAD_REPO} >&2

UPDATED_COMMIT=$( ${FLATPAK} ${U} info --show-commit app/org.test.Hello/${ARCH}/master )
assert_streq "$NEW_COMMIT" "$UPDATED_COMMIT"

# Re enable (go online)
${FLATPAK} ${U} remote-modify --url="http://127.0.0.1:${port}/test" test-repo >&2

ok "update offline to new version"

assert_file_has_content ${FL_DIR}/repo/config '^gpg-verify-summary=true$'
assert_not_file_has_content ${FL_DIR}/repo/config '^gpg-verify-summary=false$'

ostree --repo=$FL_DIR/repo config set --group='remote "test-repo"' gpg-verify-summary false >&2

assert_file_has_content ${FL_DIR}/repo/config '^gpg-verify-summary=false$'
assert_not_file_has_content ${FL_DIR}/repo/config '^gpg-verify-summary=true$'

${FLATPAK} ${U} update -y >&2

assert_file_has_content ${FL_DIR}/repo/config '^gpg-verify-summary=true$'
assert_not_file_has_content ${FL_DIR}/repo/config '^gpg-verify-summary=false$'

ok "migrate to gpg-verify-summary"

===== ./tests/package_version.txt.in =====
@PACKAGE_VERSION@

===== ./tests/test-keyring2/secring.gpg =====
Y p_NJ~<2GP_:%x3{;{h(xd-Fm[OzҜkʜXKej{!n&qLdI]U*T< 9GҡXXZBȁ/a#|QH8Ǭ,cJX/粹w y0$Q+=eFIr4*IJG^
Gi{YZT_a!_aP A#|z~F PeH'   *gE9  G)gI*-GɶQqYC놣$Q=)yyc>>㕽HsvTCv&Y csb+<샯 qGSGxX:$y8SOwb~fᓒ<ݽA"+b1LYT <wyu~2aha <kKΎsB49ߩ6E @猫]Qf>])%uAДySoDV@0AlϽ ǤM?GMԌ4˯D)fUďMU2I!h'z*L#ygZy8ȅL!ofyXM񽝡뻁vvB EbIzQ޿?gl/b,8_8]qF_
UlKuR1 *jP3򇤬k/7tcJ0&҇B6=D;$De
ۭpS6o@a'Y EV01Jd>1q+ShAlnXˬd9sΡJU$WԄ:hW P7`b"9b*Flatpak (Test key 2) <flatpak@flatpak.org>8 "Y		
 
	u_в1NQz*WA]+b@X׋/^ޣ:I0nճepW
~u!/ՇTYKz16L.KT0Re[R6He#Ȑ"9POu2a5$cNٝhq%: I9,VTzP8<~3=AL"S%Tw< g?%9X	}i>>`^fV i܍)70C0vA3eҁQ&g0  Y #(Px00N{vmd/ͽ-rT@0oxyζAҬ
	>)
DO83EdJVlDZd7|JdٯuO%gm}IlTD`h%rmL䛘u#YqTJ"QV
lJΚnMv(ќTd| @<dzw÷XWʇq[7g   [Ɉ9v6l~Ο=ג1FCYΎ#'Lg'~aA8?ѲOku@8iM/M'9WM?f1tGV/VLҰ8]-+rEi;>V;66=aςh(v_MANproT[7\J m:$[*m8P_=eKf7E XnҤ!B! /%tQ! c~ipoMj|P[R| /0(?Dre@o'qy&GzSP1}Ay=?e )ΏC/'	Zf(ϣVMhe7O/6!6*K#z9`4X0CW
h2Q52k`:]w5{_Q\	G}AUj* Pj:cp#Ǝ.s{SIPp-th[	)(_(<0ݢDEe)qL4"`-4C":Y)M>N 	Y 
	u_в1N6 PB}*G
QHؖ U	 o E)1$fQw#Be<.\!G;EvJY_v|-ڑ#CLvZySۼWSt>Mc#}coUQryOU+궇^|.d.Z	 w}59<M۞OGZ/-EzǊyfn1= zn$ж0=e[ٴ䮉r͙@)pwdd°  
===== ./tests/test-keyring2/pubring.gpg =====
Y p_NJ~<2GP_:%x3{;{h(xd-Fm[OzҜkʜXKej{!n&qLdI]U*T< 9GҡXXZBȁ/a#|QH8Ǭ,cJX/粹w y0$Q+=eFIr4*IJG^
Gi{YZT_a!_aP A#|z~F PeH'  *Flatpak (Test key 2) <flatpak@flatpak.org>8 "Y		
 
	u_в1NQz*WA]+b@X׋/^ޣ:I0nճepW
~u!/ՇTYKz16L.KT0Re[R6He#Ȑ"9POu2a5$cNٝhq%: I9,VTzP8<~3=AL"S%Tw< g?%9X	}i>>`^fV i܍)70C0vA3eҁQ&g0 Y #(Px00N{vmd/ͽ-rT@0oxyζAҬ
	>)
DO83EdJVlDZd7|JdٯuO%gm}IlTD`h%rmL䛘u#YqTJ"QV
lJΚnMv(ќTd| @<dzw÷XWʇq[7g   	Y 
	u_в1N6 PB}*G
QHؖ U	 o E)1$fQw#Be<.\!G;EvJY_v|-ڑ#CLvZySۼWSt>Mc#}coUQryOU+궇^|.d.Z	 w}59<M۞OGZ/-EzǊyfn1= zn$ж0=e[ٴ䮉r͙@)pwdd° 
===== ./tests/test-keyring2/README =====
These are completely random keys, which include the secret key.
Use these for testing gpg signing, do *NOT* ever use these for any
real application.

===== ./tests/test-keyring2/meson.build =====
# Copyright 2022 Collabora Ltd.
# SPDX-License-Identifier: LGPL-2.1-or-later

foreach file : [
  'README',
  'pubring.gpg',
  'secring.gpg',
]
  configure_file(
    input : file,
    output : file,
    copy : true,
    install : get_option('installed_tests'),
    install_dir : installed_testdir / 'test-keyring2',
    install_mode : 'rw-r--r--',
  )
endforeach

===== ./tests/test-oci.sh =====
#!/bin/bash
#
# Copyright (C) 2011 Colin Walters <walters@verbum.org>
#
# 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 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., 59 Temple Place - Suite 330,
# Boston, MA 02111-1307, USA.

set -euo pipefail

. $(dirname $0)/libtest.sh

skip_without_bwrap

echo "1..4"

setup_repo_no_add oci

mkdir -p oci
${FLATPAK} build-bundle --oci $FL_GPGARGS repos/oci oci/image org.test.Hello >&2

assert_has_file oci/image/oci-layout
assert_has_dir oci/image/blobs/sha256
assert_has_file oci/image/index.json

for i in oci/image/blobs/sha256/*; do
     echo $(basename $i) $i >> sums
done
sha256sum -c sums >&2

digest=$(grep sha256: oci/image/index.json | sed s'@.*sha256:\([a-fA-F0-9]\+\).*@\1@')
manifest=oci/image/blobs/sha256/$digest

assert_has_file $manifest

DIGEST=$(grep -C2 application/vnd.oci.image.config.v1+json $manifest | grep digest  | sed s/.*\"sha256:\\\(.*\\\)\".*/\\1/)
echo DIGEST: $DIGEST >&2
image=oci/image/blobs/sha256/$DIGEST

assert_has_file $image
assert_file_has_content $image "org\.freedesktop\.appstream\.appdata.*<summary>Print a greeting</summary>"
assert_file_has_content $image "org\.freedesktop\.appstream\.icon-64"
assert_file_has_content $image org.flatpak.ref.*app/"org.test.Hello/$ARCH/master"

ok "export oci"

ostree --repo=repo2 init --mode=archive-z2 >&2

$FLATPAK build-import-bundle --oci repo2 oci/image >&2

ostree checkout -U --repo=repo2 app/org.test.Hello/$ARCH/master checked-out >&2

assert_has_dir checked-out/files
assert_has_file checked-out/files/bin/hello.sh
assert_has_file checked-out/metadata

ok "import oci"

# Trying installing the bundle directly

${FLATPAK} build-bundle --runtime --oci $FL_GPGARGS repos/oci oci/platform-image org.test.Platform >&2

${FLATPAK} --user list --columns=application,origin > flatpak-list
assert_not_file_has_content flatpak-list 'org.test.Platform'

${FLATPAK} --user remotes --show-disabled > remotes-list
assert_not_file_has_content remotes-list '^platform-origin'

$FLATPAK --user -y install oci:oci/platform-image >&2

${FLATPAK} --user list --columns=application,origin > flatpak-list
assert_file_has_content flatpak-list '^org.test.Platform	*platform-origin$'

${FLATPAK} --user remotes --show-disabled > remotes-list
assert_file_has_content remotes-list '^platform-origin'

${FLATPAK} ${U} -y uninstall org.test.Platform >&2

ok "install oci"

# Trying installing an OCI archive bundle

(cd oci/platform-image && tar cf - .) > oci/platform-image.tar

${FLATPAK} --user list --columns=application,origin > flatpak-list
assert_not_file_has_content flatpak-list 'org.test.Platform'

${FLATPAK} --user remotes --show-disabled > remotes-list
assert_not_file_has_content remotes-list '^platform-origin'

$FLATPAK --user -y install oci-archive:oci/platform-image.tar >&2

${FLATPAK} --user list --columns=application,origin > flatpak-list
assert_file_has_content flatpak-list '^org.test.Platform	*platform-origin$'

${FLATPAK} --user remotes --show-disabled > remotes-list
assert_file_has_content remotes-list '^platform-origin'

ok "install oci archive"

===== ./tests/org.flatpak.Authenticator.test.service.in =====
[D-BUS Service]
Name=org.flatpak.Authenticator.test
Exec=@libexecdir@/test-authenticator

===== ./tests/services/meson.build =====
# Copyright 2022 Collabora Ltd.
# SPDX-License-Identifier: LGPL-2.1-or-later

foreach triple : [
  ['oci-authenticator', 'org.flatpak.Authenticator.Oci', {}],
  ['portal', 'org.freedesktop.portal.Flatpak', {
    'extraargs' : ' --poll-timeout=1',
  }],
  ['session-helper', 'org.freedesktop.Flatpak', {}],
  ['system-helper', 'org.freedesktop.Flatpak.SystemHelper', {
    'extraargs' : ' --session --no-idle-exit',
  }],
  ['tests', 'org.flatpak.Authenticator.test', {}],
  ['tests', 'org.freedesktop.impl.portal.desktop.test', {}],
]
  directory = triple[0]
  service = triple[1]
  options = triple[2]

  configure_file(
    input : project_source_root / directory / (service + '.service.in'),
    output : service + '.service',
    configuration : {
      'extraargs' : options.get('extraargs', ''),
      'libexecdir' : project_build_root / directory,
    }
  )
endforeach

===== ./tests/org.test.Hello.png =====
PNG

   IHDR   @   @   iq   sRGB    	pHYs    ^   tIME%@   bKGD     xIDATxV5;Mi]6m۶Ok6߶1sLgOem{kJUsoY?ӟ}}}Cu𜳿qa'^3351u/,_ع[n'?yk% m'`r\BP}׎4NWG?})㿦ʰWu_>v|vGeq&U\)Ir9F}ԻNl?Uׯ֭moY޽|C֮]˕RlllL?Oe̴!y]95kò,u_ykT(R^'}ɓGkfT4M;e0a?L((rhP.-Vֲ.H#gXnsP1xj͚5t78mWĵ,ESJW)iNiZG=[A9*w~%G
{{xNoxg?M'N|xxTi&b0wJNYyu>T	\gޫK-[}K;h4RssB(mowqwp]P7r5/RP[7pHKr<3 8pZPF)x4)qVvZJ%>yΆ^;4WUA655-[f ?hxVrf붎I^:WYsGRR繹89Y&&&v/YszS_p%D<yԺ̶nS%
ն-zwjnΠZnӌGq\A(A(ȈRZo3iZ=5=[g%SF?mr<<KՋFGF³E0efҫQ4595eK:_js5gzrS~Ӂ @1s/X('5t$Fp/,8yO9K3euwPN(S^x!?s8Wqclx<(6atUwVg[-A6ԗP'͡xj0a 0;ر]v.W&I;$	i5(,% 50Җ~I#֡4?5>Z6/@a  CܹK ~{axddX	*=bms.{ƅRVl`&Δ2 (\81=t:ۦIvFP}L#6A٧q/=i2$T
CnA09[2ύJlӭсmqE 
qW,Ѯ~%+]=wZx*fÑƭŉlTRU,IDΌaueS\8Q?A-$X6k-4	9BTTE:`75F-JaQjL<M;Ң!'TFmS8ؒ∹3,tuUqbB
IM63>"(D00igDȤ0׵YK-o#ı+<eĖTs4^sE	+,Jr\mS[͂JItwU^=Ӧw 3?l5IL$IRp̎kaC!XQq?g]!Hu͠&Iެ}(mX%V*zZc,-R
ڱZ)p4d*#IkRd Qu@rk40:ar?߳k_{Ciu\fw;&1A2)L6MC @R1vjwGmi#رY@?ShZm=k1c9vK5 =61 /֍z=JHg|_KjQSxB<IedLFQ渦3EH,Z/-5=2~e 4rHhW,}K:#}m;|v{oo~ހOW5 `.b3yU[rsls\-{Cm0s>|l6	?MiV_;/KdusNU:J*qyk{+,* ghcKDI`CppQ`)&U\Ii^N⪡:F|5Y\Q~HBN8N2ۑR.Yh2; PEE8>R	lm-hfEo`LV}N>-:jr0YS~ T[-FͧM{ZתJj,\QJh7A'=}t!ng+E{>+J;Rj(~uKPOhd	l6.Bub5j~ސlJXQVfwX	}0wv/R4c8Fg MJ_+!I\_HtB|fg	,Z;w9YO<	v>@s8<2זp5J	V6ks *A;>>Gmc,V{\2m5bv{Uw\1Hǽ	-ڪ>>I&bfVԾop/~ቧ;K?|[򖼑F;eC-ނ4&Alogo(rюNaTnw$<Y= յ 4k}]B"$D*!xSE|ȯ~x7 N
˽`odx--(ROJYD6<9 iD߁`^9`H5T)g[#ڠ?uv / V!ƅ3?Ν=W|_R1"CMk2>o1n"oRjJ<
 "
,sߏ
TQD&}g\pK<'h-#ͪ]q΅?y-_GcGLC16+aєM	(/r?hEd]ny=[oXX
0V-*tF w+$/J"nnI:׽꺹g|WsQ1!=	3%,٦tRRxbK»0GcP߹Kfu4v ؀A9LmkRgoAm5*kixɧp!rSSKt$M0 Y5(~Ler̻ä́@Mb Q LZltR`Xǌf ەQ+Xj/'OAHn4h' O<DЃ˸+o09~K<L*gY%jm<f1@#>͉84tӅ26d 3UH>a>: z5h<qEN~m-  looN[rtnZfK)?NVUQK퐹Iָ2owza\׼7xgߡf&`T{`HVDnyN=Lu]W_>^cjvn n)+ML-a\2VXP"/bte866:W٤]dR9P)ojT~sfypx7e~yÌ;*0c8#E7>f[g<9Mv.^}=qfټYx(S$dc\*ď{s}˳;	ncۥ'L}\AËVnyUx_eɶ(fA%R%MHH}zrw_/.8>gV,K2,lǎ9//e6M즎)`bŸZE2w;|ɓ'ca5q*j!
ڝIsMuTXmq)CRb{O炜
|jjMDh  ((@Vag3v`QavdTd@VhmsBf:ўb1R$BV-| xH}u( cbW\jj*K/ sN6sR:JDfش)3oT1|pyE*y8
<WlBkKsgObE RlV/<^.tDGqT2D'!3+` uSKDlX0*[@"y(^ A7$ݐqbs
UnRĬ؎;ߟ.
 @w:s[YًNUZFFym6uBΊ!ɣZW#\&2˄N+Hhժ{K3a48onNzr}V;Q[s&W#'EwBϊd*U+m|<֛<Ό-6l~pgEil	4XZũT͑榴DCOsy3=Z7ȵe7\PVF`}71m,ly}	*wQivIL7WY335|oAGNҌmY$?^b_Dӏʅڀݹzߞu^ۿS@,~U%$ՇZQhKURֲS'cioh`Ιͼ1YB|t7Qv׸æ0l"{9RR9.u1'kcJﱞI&[m1X_e@,iނ϶VXw]v&`j=sSACv1 _U˻ᵵ% 8mLҀ
M;rJ-,DKM{wVr1&"e)Q+D652ҠMɽN{sy3gB2A%b_;|;_m+^:!v+zY/?臦gB0h%Uau-ʢS%_9B3(cS'@K6Gq#T5	g+JKr;\8[k1aH
'UG<`0nW*Dy	t[XfHRp:Ѭ'|4L]7ChΙ5;0`2w@;2 ,`<m: NcGC<|ߡ@"\'eVZtg8 ~he%:|r%u/C@,Q|~x<(`PdUZ-TqR@`GlaY9ώ9b=  x|_?%&,fȮ5]ȌyQ	[mvϦ>@LMr	}^5[Zk|C@<
i?{Kd2B!T*dyz5<x_\?K_$-xٕ~Aos;gR-UZݭafJ$|*>'?nl4v>PI9$83Hi:vt915R& 8qƗֻO^_L5wĹq	]KELuYZ">,H	u5rL$
p0]`ѵzoaԳ,m[<3\zÆ &Hڲz{ut{_w9kԄ$#~B'-%,ypR2 '${xrkgZaI<?:-9N?kerYeyB9b9;ojxB[vRγdUo?q=O<Nj:Z:A﹣,U+D^Ύ6w<Nmf8Z/UOбcOHx[UQ˵k;oY,;9naGA4J%$đ\3}^3uҹ3K0(d3(QrٱW7WʌG  JE bE~nY IR)'~ZyPI6>v.*<CT&@7LYU==895tZh8Pz*djڧ%CͦpLTT/<ގa8*ܭRbɆ'rbӅzCI3âY?w|_| MجyRf_JGy7_eLEG͚/)E2|tn7o*)-/1v\A씰8V\jmF`˱W݀Z\սp5 ʲ\>&q#Ђs{\Z.2gO{o^2EM@!_Zf@e9 >CprHըQ##
<Èi0AXf#C lEApǇBz0cG|atLqE:T%Ch}Ť(<A'o+U $d%q:RlXR)!J<o{=P׻7ѝ~|͛)C?>-C 0q%BSs`@Rd=xJI8fa?TC3buԊcKQFbUL萧jxJ&F*pf/=O5Yۂi3~B:+f^Hf- hՇoax]JC/@21i2	Sg >		~
	W;#t%LB"ph+VOP^1bBJL_RA{	,%8ZJ	82b1F"ݎ88$/s'DA5*tâRWS3S^x' "lBwҎ? Bޣ;^m3åR`>[ڕW|ɊSQ:IY {=|+J<֪    IENDB`
===== ./tests/make-test-runtime.sh =====
#!/bin/bash

set -e

# Don't inherit the -x from the testsuite
set +x

DIR=`mktemp -d`

REPO=$1
shift
ID=$1
shift
BRANCH=$1
shift
COLLECTION_ID=$1
shift

EXTRA="${1-}"
shift

mkdir ${DIR}/files
mkdir ${DIR}/usr
cat > ${DIR}/metadata <<EOF
[Runtime]
name=${ID}
EOF

# On Debian derivatives, /usr/sbin and /sbin aren't in ordinary users'
# PATHs, but ldconfig is kept in /sbin
PATH="$PATH:/usr/sbin:/sbin"

# Add bash and dependencies
mkdir -p ${DIR}/usr/bin
mkdir -p ${DIR}/usr/lib
ln -s ../lib ${DIR}/usr/lib64
ln -s ../lib ${DIR}/usr/lib32
if test -f /sbin/ldconfig.real; then
    cp /sbin/ldconfig.real ${DIR}/usr/bin/ldconfig
else
    cp "$(type -P ldconfig)" "${DIR}/usr/bin"
fi
LIBS=`mktemp`
BINS=`mktemp`

add_bin() {
    local f=$1
    shift

    # Check if the program is installed
    if ! command -v "${f}" &> /dev/null; then
        echo "${f} not found"
        exit 1
    fi

    if grep -qFe "${f}" $BINS; then
        # Already handled
        return 0
    fi

    echo $f >> $BINS

    # Add library dependencies
    (ldd "${f}" | sed "s/.* => //"  | awk '{ print $1}' | grep ^/ | sort -u -o $LIBS $LIBS -)  || true

    local shebang=$(sed -n '1s/^#!\([^ ]*\).*/\1/p' "${f}")
    if [ x$shebang != x ]; then
        add_bin "$shebang"
    fi
}

for i in $@ bash ls cat echo readlink socat; do
    I=$(type -P "$i")
    add_bin "$I"
done
for i in `cat $BINS`; do
    #echo Adding binary $i 1>&2
    cp "$i" ${DIR}/usr/bin/
done
for i in `cat $LIBS`; do
    #echo Adding library $i 1>&2
    cp "$i" ${DIR}/usr/lib/
done
ln -s bash ${DIR}/usr/bin/sh

# This only exists so we can update the runtime
cat > ${DIR}/usr/bin/runtime_hello.sh <<EOF
#!/bin/sh
echo "Hello world, from a runtime$EXTRA"
EOF
chmod a+x ${DIR}/usr/bin/runtime_hello.sh

# We copy the C.UTF8 locale and call it en_US. Its a bit of a lie, but
# the real en_US locale is often not available, because its in the
# local archive.
if [ -d /usr/lib/locale ]; then
    mkdir -p ${DIR}/usr/lib/locale/
    cp -r /usr/lib/locale/C.* ${DIR}/usr/lib/locale/en_US
fi

if [ x$COLLECTION_ID != x ]; then
    collection_args=--collection-id=${COLLECTION_ID}
else
    collection_args=
fi

mkdir -p repos
flatpak build-export ${collection_args} --no-update-summary --disable-sandbox --runtime ${GPGARGS-} ${EXPORT_ARGS-} ${REPO} ${DIR} ${BRANCH} >&2
rm -rf ${DIR}

===== ./tests/test-default-remotes.sh =====
#!/bin/bash
#
# Copyright (C) 2019 Alexander Larsson <alexl@redhat.com>
#
# 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 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., 59 Temple Place - Suite 330,
# Boston, MA 02111-1307, USA.

set -euo pipefail

USE_SYSTEMDIR=yes

. $(dirname $0)/libtest.sh

skip_without_bwrap
skip_revokefs_without_fuse

setup_repo

cat << EOF > added-default.flatpakrepo
[Flatpak Repo]
Url=http://127.0.0.1/test
Title=The Title
Comment=The Comment
Description=The Description
Homepage=https://the.homepage/
Icon=https://the.icon/
EOF

echo "1..5"

mkdir -p $FLATPAK_CONFIG_DIR/remotes.d

${FLATPAK} -vv --system  remotes > remotes
assert_not_file_has_content remotes "added-default"

cp added-default.flatpakrepo $FLATPAK_CONFIG_DIR/remotes.d/

${FLATPAK}  --system remotes > remotes
assert_file_has_content remotes "added-default"

assert_remote_has_config added-default url "http://127.0.0.1/test"
assert_remote_has_config added-default gpg-verify "false"
assert_remote_has_config added-default xa.title "The Title"
assert_remote_has_no_config added-default xa.title-is-set
assert_remote_has_config added-default xa.comment "The Comment"
assert_remote_has_no_config added-default xa.comment-is-set
assert_remote_has_config added-default xa.description "The Description"
assert_remote_has_no_config added-default xa.description-is-set
assert_remote_has_config added-default xa.homepage "https://the.homepage/"
assert_remote_has_no_config added-default xa.homepage-is-set
assert_remote_has_config added-default xa.icon "https://the.icon/"
assert_remote_has_no_config added-default xa.icon-is-set
assert_remote_has_no_config added-default xa.noenumerate
assert_remote_has_no_config added-default xa.filter

ok "pre-existing installation"

rm -rf $FL_DIR

${FLATPAK}  --system remotes > remotes
assert_file_has_content remotes "added-default"

ok "non-existing installation"

${FLATPAK} --system remotes > remotes
assert_file_has_content remotes "added-default"

${FLATPAK}  --system remote-delete added-default

# Doesn't come back once removed
${FLATPAK} --system remotes > remotes
assert_not_file_has_content remotes "added-default"

ok "allow remove"

rm -rf $FL_DIR
rm -rf $FLATPAK_CONFIG_DIR/remotes.d/*

${FLATPAK}  --system remote-add  --title "Title2" added-default http://127.0.0.1/other-url

${FLATPAK}  --system remotes > remotes
assert_file_has_content remotes "added-default"

assert_remote_has_config added-default url "http://127.0.0.1/other-url"

cp added-default.flatpakrepo $FLATPAK_CONFIG_DIR/remotes.d/

${FLATPAK}  --system remotes > remotes
assert_file_has_content remotes "added-default"

# Should keep the old value
assert_remote_has_config added-default url "http://127.0.0.1/other-url"

# And none of the fields from the file
assert_remote_has_config added-default xa.title "Title2"
assert_remote_has_no_config added-default xa.comment
assert_remote_has_no_config added-default xa.description
assert_remote_has_no_config added-default xa.homepage

ok "pre-existing remote"

rm -rf $FL_DIR
rm -rf $FLATPAK_CONFIG_DIR/remotes.d/*

cp added-default.flatpakrepo $FLATPAK_CONFIG_DIR/remotes.d/
echo "Filter=${test_builddir}/test.filter" >> $FLATPAK_CONFIG_DIR/remotes.d/added-default.flatpakrepo

${FLATPAK} --system remotes > remotes
assert_file_has_content remotes "added-default"

assert_remote_has_config added-default xa.filter "${test_builddir}/test.filter"

# --if-not-exists will still magically override the filter
${FLATPAK}  --system remote-add --if-not-exists --from added-default added-default.flatpakrepo

${FLATPAK} --system remotes > remotes
assert_file_has_content remotes "added-default"

assert_remote_has_no_config added-default xa.filter

ok "override default filter"

===== ./tests/test-http-utils.sh =====
#!/bin/bash
#
# Copyright (C) 2018 Red Hat, Inc.
#
# 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 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., 59 Temple Place - Suite 330,
# Boston, MA 02111-1307, USA.

set -euo pipefail

. $(dirname $0)/libtest.sh

httpd http-utils-test-server.py .
port=$(cat httpd-port)

assert_result() {
    test_string=$1
    compressed=
    if [ "$2" = "--compressed" ] ; then
	compressed="--compressed"
	shift
    fi
    remote=$2
    local=$3

    out=`${test_builddir}/httpcache $compressed "http://localhost:$port$remote" $local || :`

    case "$out" in
	$test_string*)
	    return
	    ;;
	*)
	    echo "For $remote => $local, expected '$test_string', got '$out'"
	    exit 1
	    ;;
    esac
}

assert_cached() {
    assert_result "Reusing cached value" $@
}

assert_304() {
    assert_result "Server returned status 304" $@
}

assert_ok() {
    assert_result "Server returned status 200" $@
}


have_xattrs() {
    touch $1/test-xattrs
    setfattr -n user.testvalue -v somevalue $1/test-xattrs > /dev/null 2>&1
}

echo "1..6"

# Without anything else, cached for 30 minutes
assert_ok "/" $test_tmpdir/output
assert_cached "/" $test_tmpdir/output
rm -f $test_tmpdir/output*

# An explicit cache-lifetime
assert_ok "/?max-age=3600" $test_tmpdir/output
assert_cached "/?max-age=3600" $test_tmpdir/output
rm -f $test_tmpdir/output*

# Turn off caching
assert_ok "/?max-age=0" $test_tmpdir/output
assert_ok "/?max-age=0" $test_tmpdir/output
rm -f $test_tmpdir/output*

# Turn off caching a different way
assert_ok "/?no-cache" $test_tmpdir/output
assert_ok "/?no-cache" $test_tmpdir/output
rm -f $test_tmpdir/output*

# Expires support
assert_ok "/?expires-future" $test_tmpdir/output
assert_cached "/?expires-future" $test_tmpdir/output
rm -f $test_tmpdir/output*

assert_ok "/?expires-past" $test_tmpdir/output
assert_ok "/?expires-past" $test_tmpdir/output
rm -f $test_tmpdir/output*

ok 'http cache lifetimes'

# Revalidation with an etag
assert_ok "/?etag&no-cache" $test_tmpdir/output
assert_304 "/?etag&no-cache" $test_tmpdir/output
rm -f $test_tmpdir/output*

# Revalidation with a modified time
assert_ok "/?modified-time&no-cache" $test_tmpdir/output
assert_304 "/?modified-time&no-cache" $test_tmpdir/output
rm -f $test_tmpdir/output*

ok 'http revalidation'

# Test compressed downloading and storage
assert_ok --compressed "/compress" $test_tmpdir/output
contents=$(gunzip -c < $test_tmpdir/output)
assert_streq $contents path=/compress
rm -f $test_tmpdir/output*

ok 'compressed download'

# Test uncompressed downloading with compressed storage
assert_ok --compressed "/compress?ignore-accept-encoding" $test_tmpdir/output
contents=$(gunzip -c < $test_tmpdir/output)
assert_streq $contents path=/compress?ignore-accept-encoding
rm -f $test_tmpdir/output*

ok 'compress after download'

# Testing that things work without xattr support

if command -v setfattr >/dev/null &&
   ! have_xattrs $test_tmpdir ; then
    assert_ok "/?etag&no-cache" $test_tmpdir/output
    assert_has_file $test_tmpdir/output.flatpak.http
    assert_304 "/?etag&no-cache" $test_tmpdir/output
    rm -f $test_tmpdir/output*
    ok "no-xattrs"
else
    ok "no-xattrs # skip No setfattr or /tmp doesn't have user xattr support"
fi

# Testing with xattr support

xattrs_tempdir=`mktemp -d /var/tmp/test-flatpak-XXXXXX`
xattrs_cleanup () {
    rm -rf xattrs_tempdir
    cleanup
}
trap xattrs_cleanup EXIT

if command -v setfattr >/dev/null &&
   have_xattrs $xattrs_tempdir ; then
    assert_ok "/?etag&no-cache" $xattrs_tempdir/output
    assert_not_has_file $xattrs_tempdir/output.flatpak.http
    assert_304 "/?etag&no-cache" $xattrs_tempdir/output
    rm -f $xattrs_tempdir/output*
    ok "xattrs"
else
    ok "xattrs # skip No setfattr or /var/tmp has user no xattr support"
fi

===== ./tests/test-seccomp.sh =====
#!/bin/bash
# Copyright 2021 Collabora Ltd.
# SPDX-License-Identifier: LGPL-2.0-or-later

set -euo pipefail

. $(dirname $0)/libtest.sh

skip_without_bwrap

echo "1..18"

setup_repo
install_repo

cp -a "$G_TEST_BUILDDIR/try-syscall" "$test_tmpdir/try-syscall"

# How this works:
# try-syscall tries to make various syscalls, some benign, some not.
#
# The parameters are chosen to make them fail with EBADF or EFAULT if
# not blocked. If they are blocked, we get ENOSYS or EPERM. If the syscall
# is impossible for a particular architecture, we get ENOENT.
#
# The exit status is an errno value, which we can compare with the expected
# errno value.

eval "$("$test_tmpdir/try-syscall" print-errno-values)"

try_syscall () {
  ${FLATPAK} run \
    --filesystem="$test_tmpdir" \
    --command="$test_tmpdir/try-syscall" \
    $extra_argv \
    org.test.Hello "$@"
}

for extra_argv in "" "--allow=multiarch"; do
  echo "# testing with extra argv: '$extra_argv'"

  echo "# chmod (benign)"
  e=0
  try_syscall chmod || e="$?"
  assert_streq "$e" "$EFAULT"
  ok "chmod not blocked"

  echo "# chroot (harmful)"
  e=0
  try_syscall chroot || e="$?"
  assert_streq "$e" "$EPERM"
  ok "chroot blocked with EPERM"

  echo "# clone3 (harmful)"
  e=0
  try_syscall clone3 || e="$?"
  # This is either ENOSYS because the kernel genuinely doesn't implement it,
  # or because we successfully blocked it. We can't tell which.
  assert_streq "$e" "$ENOSYS"
  ok "clone3 blocked with ENOSYS (CVE-2021-41133)"

  echo "# ioctl TIOCNOTTY (benign)"
  e=0
  try_syscall "ioctl TIOCNOTTY" || e="$?"
  assert_streq "$e" "$EBADF"
  ok "ioctl TIOCNOTTY not blocked"

  echo "# ioctl TIOCSTI (CVE-2017-5226)"
  e=0
  try_syscall "ioctl TIOCSTI" || e="$?"
  assert_streq "$e" "$EPERM"
  ok "ioctl TIOCSTI blocked (CVE-2017-5226)"

  echo "# ioctl TIOCSTI (trying to repeat CVE-2019-10063)"
  e=0
  try_syscall "ioctl TIOCSTI CVE-2019-10063" || e="$?"
  if test "$e" = "$ENOENT"; then
    echo "ok # SKIP Cannot replicate CVE-2019-10063 on 32-bit architecture"
  else
    assert_streq "$e" "$EPERM"
    ok "ioctl TIOCSTI with high bits blocked (CVE-2019-10063)"
  fi

  echo "# ioctl TIOCLINUX (CVE-2023-28100)"
  e=0
  try_syscall "ioctl TIOCLINUX" || e="$?"
  assert_streq "$e" "$EPERM"
  ok "ioctl TIOCLINUX blocked"

  echo "# listen (benign)"
  e=0
  try_syscall "listen" || e="$?"
  assert_streq "$e" "$EBADF"
  ok "listen not blocked"

  echo "# prctl (benign)"
  e=0
  try_syscall "prctl" || e="$?"
  assert_streq "$e" "$EFAULT"
  ok "prctl not blocked"
done

===== ./tests/test-build-update-repo.sh =====
#!/bin/bash
#
# Copyright © 2018 Endless Mobile, Inc.
#
# 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 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., 59 Temple Place - Suite 330,
# Boston, MA 02111-1307, USA.
#
# Authors:
#  - Philip Withnall <withnall@endlessm.com>

set -euo pipefail

. $(dirname $0)/libtest.sh

skip_without_bwrap
skip_revokefs_without_fuse

echo "1..5"

# Configure a repository, then set a collection ID on it and check that the ID
# is saved in the config file.
setup_repo
install_repo

${FLATPAK} build-update-repo --collection-id=org.test.Collection repos/test >&2

assert_file_has_content repos/test/config '^collection-id=org\.test\.Collection$'

ok "1 update repo to add collection ID"

# Test that you’re not allowed to change the collection ID once it’s already set.
if ${FLATPAK} build-update-repo --collection-id=org.test.Collection2 repos/test &> build-update-repo-error-log; then
    assert_not_reached "flatpak build-update-repo should not set a collection ID when one is already set"
fi

assert_file_has_content repos/test/config '^collection-id=org\.test\.Collection$'
assert_not_file_has_content repos/test/config '^collection-id=org\.test\.Collection2$'

ok "2 collection ID cannot be changed"

${FLATPAK} build-update-repo --title="My little repo" repos/test >&2

assert_file_has_content repos/test/config '^title=My little repo$'

ok "can update repo title"

${FLATPAK} build-update-repo --redirect-url=http://no.where/ repos/test >&2

assert_file_has_content repos/test/config '^redirect-url=http://no\.where/$'

ok "can update redirect url"

${FLATPAK} build-update-repo --default-branch=no-such-branch repos/test >&2

assert_file_has_content repos/test/config '^default-branch=no-such-branch$'

ok "can update default branch"

===== ./tests/test-repo.sh =====
#!/bin/bash
#
# Copyright (C) 2011 Colin Walters <walters@verbum.org>
#
# 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 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., 59 Temple Place - Suite 330,
# Boston, MA 02111-1307, USA.

set -euo pipefail

. $(dirname $0)/libtest.sh

skip_without_bwrap
skip_revokefs_without_fuse

echo "1..47"

#Regular repo
setup_repo

# Ensure we have appdata
if ! ostree show --repo=repos/test appstream/${ARCH} > /dev/null; then
    assert_not_reached "No appstream branch"
fi
if ! ostree show --repo=repos/test appstream2/${ARCH} > /dev/null; then
    assert_not_reached "No appstream2 branch"
fi
ostree cat --repo=repos/test appstream/${ARCH} /appstream.xml.gz | gunzip -d > appdata.xml
assert_file_has_content appdata.xml "<id>org\.test\.Hello\.desktop</id>"

ostree cat --repo=repos/test appstream2/${ARCH} /appstream.xml > appdata2.xml
assert_file_has_content appdata2.xml "<id>org\.test\.Hello\.desktop</id>"

# Unsigned repo (not supported with collections; client-side use of collections requires GPG)
if [ x${USE_COLLECTIONS_IN_CLIENT-} == xyes ] ; then
    if GPGPUBKEY=" " GPGARGS=" " setup_repo test-no-gpg org.test.Collection.NoGpg; then
        assert_not_reached "Should fail remote-add due to missing GPG key"
    fi
elif [ x${USE_COLLECTIONS_IN_SERVER-} == xyes ] ; then
    # Set a collection ID and GPG on the server, but not in the client configuration
    setup_repo_no_add test-no-gpg org.test.Collection.NoGpg
    port=$(cat httpd-port)
    ${FLATPAK} remote-add ${U} --no-gpg-verify test-no-gpg-repo "http://127.0.0.1:${port}/test-no-gpg" >&2
else
    GPGPUBKEY="" GPGARGS="" setup_repo test-no-gpg
fi

${FLATPAK} remote-add ${U} --no-gpg-verify local-test-no-gpg-repo `pwd`/repos/test-no-gpg >&2

#alternative gpg key repo
GPGPUBKEY="${FL_GPG_HOMEDIR2}/pubring.gpg" GPGARGS="${FL_GPGARGS2}" setup_repo test-gpg2 org.test.Collection.Gpg2

#remote with missing GPG key
# Don’t use --collection-id= here, or the collections code will grab the appropriate
# GPG key from one of the previously-configured remotes with the same collection ID.
port=$(cat httpd-port)
if ${FLATPAK} remote-add ${U} test-missing-gpg-repo "http://127.0.0.1:${port}/test" >&2; then
    assert_not_reached "Should fail metadata-update due to missing gpg key"
fi

#remote with wrong GPG key
port=$(cat httpd-port)
if ${FLATPAK} remote-add ${U} --gpg-import=${FL_GPG_HOMEDIR2}/pubring.gpg test-wrong-gpg-repo "http://127.0.0.1:${port}/test" >&2; then
    assert_not_reached "Should fail metadata-update due to wrong gpg key"
fi

# Remove new appstream branch so we can test deploying the old one
rm -rf repos/test/refs/heads/appstream2
${FLATPAK} build-update-repo ${BUILD_UPDATE_REPO_FLAGS-} --no-update-appstream ${FL_GPGARGS} repos/test >&2

${FLATPAK} ${U} --appstream update test-repo >&2

assert_has_file $FL_DIR/repo/refs/remotes/test-repo/appstream/$ARCH
assert_not_has_file $FL_DIR/repo/refs/remotes/test-repo/appstream2/$ARCH

assert_has_file $FL_DIR/appstream/test-repo/$ARCH/.timestamp
assert_has_symlink $FL_DIR/appstream/test-repo/$ARCH/active
assert_has_file $FL_DIR/appstream/test-repo/$ARCH/active/appstream.xml
assert_has_file $FL_DIR/appstream/test-repo/$ARCH/active/appstream.xml.gz

ok "update compat appstream"

# Then regenerate new appstream branch and verify that we update to it
update_repo

${FLATPAK} ${U} --appstream update test-repo >&2

assert_has_file $FL_DIR/repo/refs/remotes/test-repo/appstream2/$ARCH

assert_has_file $FL_DIR/appstream/test-repo/$ARCH/.timestamp
assert_has_symlink $FL_DIR/appstream/test-repo/$ARCH/active
assert_has_file $FL_DIR/appstream/test-repo/$ARCH/active/appstream.xml
assert_has_file $FL_DIR/appstream/test-repo/$ARCH/active/appstream.xml.gz

ok "update appstream"

# Test that 'flatpak search' works
${FLATPAK} search Hello > search-results
assert_file_has_content search-results "Print a greeting"

ok "search"

if [ x${USE_COLLECTIONS_IN_CLIENT-} != xyes ] ; then
    install_repo test-no-gpg
    ok "install without gpg key"

    ${FLATPAK} ${U} uninstall -y org.test.Platform org.test.Hello >&2
else
    ok "install without gpg key # skip not supported for collections"
fi

install_repo local-test-no-gpg
${FLATPAK} ${U} uninstall -y org.test.Platform org.test.Hello >&2
${FLATPAK} ${U} update --appstream local-test-no-gpg-repo >&2

ok "local without gpg key"

install_repo test-gpg2
ok "with alternative gpg key"

if ${FLATPAK} ${U} install -y test-repo org.test.Platform &> install-error-log; then
    assert_not_reached "Should not be able to install again from different remote without reinstall"
fi
ok "failed to install again from different remote"

port=$(cat httpd-port)
echo "bad key" > badkey

gpg2_repo_url=$(ostree config --repo=$FL_DIR/repo get --group 'remote "test-gpg2-repo"' url)
cp "$FL_DIR/repo/test-gpg2-repo.trustedkeys.gpg" gpg2_repo_key
${FLATPAK} ${U} remote-modify --gpg-import=badkey test-gpg2-repo >&2 || true
gpg2_repo_url2=$(ostree config --repo=$FL_DIR/repo get --group 'remote "test-gpg2-repo"' url)
cp "$FL_DIR/repo/test-gpg2-repo.trustedkeys.gpg" gpg2_repo_key2

if [[ "${gpg2_repo_url}" != "${gpg2_repo_url2}" ]] || ! diff -q gpg2_repo_key gpg2_repo_key2 > /dev/null 2>&1; then
  assert_not_reached "remote-modify failed but remote was modified"
fi

${FLATPAK} ${U} remote-add --gpg-import=badkey test-broken-repo "http://127.0.0.1:${port}/test-broken-repo" >&2 && false
ostree config --repo=$FL_DIR/repo get --group 'remote "test-broken-repo"' url > /dev/null 2>&1 && \
    assert_not_reached "Bug #6449: Remote added with broken GPG key"
[[ -f "$FL_DIR/repo/test-broken-repo.trustedkeys.gpg" ]] && false

ok "fail with broken repo"

cat << EOF > test-broken-repo.flatpakrepo
[Flatpak Repo]
Version=1
Url=http://no.127.0.0.1:$(cat httpd-port)/test-broken/
Title=The Remote Title
GPGKey=AAA${FL_GPG_BASE64}AAA
EOF

mkdir -p $FLATPAK_CONFIG_DIR/remotes.d
cp test-broken-repo.flatpakrepo $FLATPAK_CONFIG_DIR/remotes.d/

${FLATPAK} ${U} remote-add --from test-broken-repo >&2 && false
ostree config --repo=$FL_DIR/repo get --group 'remote "test-broken-repo"' url > /dev/null 2>&1 && \
    assert_not_reached "Bug #6449: Remote added with broken GPG key"
[[ -f "$FL_DIR/repo/test-broken-repo.trustedkeys.gpg" ]] && false

rm -rf $FLATPAK_CONFIG_DIR/remotes.d/

ok "fail with statically configured broken repo"

${FLATPAK} ${U} install -y --reinstall test-repo org.test.Platform >&2
ok "re-install"

${FLATPAK} ${U} uninstall -y org.test.Hello >&2

# Note: This typo is only auto-corrected without user interaction because we're using -y
${FLATPAK} ${U} install --app -y test-repo hello >install-log
assert_file_has_content install-log "org\.test\.Hello"

${FLATPAK} ${U} list --columns=ref > list-log
assert_file_has_content list-log "org\.test\.Hello/"

ok "typo correction works for install"

if ${FLATPAK} ${U} install -y test-repo Hllo// >install-log; then
    assert_not_reached "Should not be able to install with an incorrect ref that contains slashes"
fi

ok "no typo correction if ref contains slashes"

if ${FLATPAK} ${U} install -y test-repo org.test.Hllo >install-log; then
    assert_not_reached "Should not be able to install with an incorrect ref that contains periods"
fi

ok "no typo correction if ref contains periods"

${FLATPAK} ${U} uninstall -y org.test.Hello >&2

# Temporarily disable some remotes so that org.test.Hello only exists in one
${FLATPAK} ${U} remote-modify --disable test-missing-gpg-repo >&2
${FLATPAK} ${U} remote-modify --disable test-wrong-gpg-repo >&2
${FLATPAK} ${U} remote-modify --disable test-gpg2-repo >&2
${FLATPAK} ${U} remote-modify --disable local-test-no-gpg-repo >&2
if [ x${USE_COLLECTIONS_IN_CLIENT-} != xyes ] ; then
    ${FLATPAK} ${U} remote-modify --disable test-no-gpg-repo >&2
fi

# Note: The missing remote is only auto-corrected without user interaction because we're using -y
${FLATPAK} ${U} install -y org.test.Hello |& tee install-log >&2
assert_file_has_content install-log "org\.test\.Hello"

${FLATPAK} ${U} list --columns=ref > list-log
assert_file_has_content list-log "org\.test\.Hello/"

${FLATPAK} ${U} remote-modify --enable test-missing-gpg-repo >&2
${FLATPAK} ${U} remote-modify --enable test-wrong-gpg-repo >&2
${FLATPAK} ${U} remote-modify --enable test-gpg2-repo >&2
${FLATPAK} ${U} remote-modify --enable local-test-no-gpg-repo >&2
if [ x${USE_COLLECTIONS_IN_CLIENT-} != xyes ] ; then
    ${FLATPAK} ${U} remote-modify --enable test-no-gpg-repo >&2
fi

ok "missing remote name auto-corrects for install"

port=$(cat httpd-port)
if ${FLATPAK} ${U} install -y http://127.0.0.1:${port}/nonexistent.flatpakref &> install-error-log; then
    assert_not_reached "Should not be able to install a nonexistent flatpakref"
fi
assert_file_has_content install-error-log "Server returned status 404"

ok "install fails gracefully for 404 URLs"

# Use a new remote so we can be sure it doesn't match any existing one's URL
setup_repo_no_add flatpakref org.test.Collection.Flatpakref

cat << EOF > repos/flatpakref/flatpakref-repo.flatpakrepo
[Flatpak Repo]
Version=1
Url=http://127.0.0.1:$(cat httpd-port)/flatpakref/
Title=The Remote Title
GPGKey=${FL_GPG_BASE64}
EOF

if [ x${USE_COLLECTIONS_IN_CLIENT-} == xyes ]; then
    echo "DeploySideloadCollectionID=org.test.Collection.Flatpakref" >> repos/flatpakref/flatpakref-repo.flatpakrepo
fi

cat << EOF > org.test.Hello.flatpakref
[Flatpak Ref]
Name=org.test.Hello
Branch=master
Url=http://127.0.0.1:$(cat httpd-port)/flatpakref
SuggestRemoteName=allthegoodstuff
GPGKey=${FL_GPG_BASE64}
RuntimeRepo=http://127.0.0.1:$(cat httpd-port)/flatpakref/flatpakref-repo.flatpakrepo
EOF

if [ x${USE_COLLECTIONS_IN_CLIENT-} == xyes ]; then
    echo "DeploySideloadCollectionID=org.test.Collection.Flatpakref" >> org.test.Hello.flatpakref
fi

${FLATPAK} ${U} uninstall -y org.test.Platform org.test.Hello >&2

# Ensure that only one remote is added even though the URL in the flatpakref
# does not have a trailing slash and the URL in the flatpakrepo file does
NUM_REMOTES_BEFORE=$(flatpak remotes | wc -l)
${FLATPAK} ${U} install -y org.test.Hello.flatpakref >&2
NUM_REMOTES_AFTER=$(flatpak remotes | wc -l)

if [ $NUM_REMOTES_AFTER -ne $((NUM_REMOTES_BEFORE + 1)) ]; then
    assert_not_reached "install of flatpakref should only add one remote"
fi

ok "install flatpakref normalizes remote URL trailing slash"

assert_remote_has_config allthegoodstuff xa.title "The Remote Title"

ok "install flatpakref uses RuntimeRepo metadata for remote"

if [ x${USE_COLLECTIONS_IN_CLIENT-} == xyes ]; then
    assert_remote_has_config allthegoodstuff collection-id "org.test.Collection.Flatpakref"
else
    assert_remote_has_no_config allthegoodstuff collection-id
fi

ok "install flatpakref sets collection-id on remote if available"

${FLATPAK} ${U} uninstall -y org.test.Platform org.test.Hello >&2

if ${FLATPAK} ${U} install -y test-missing-gpg-repo org.test.Platform &> install-error-log; then
    assert_not_reached "Should not be able to install with missing gpg key"
fi
assert_log_has_gpg_signature_error install-error-log

if ${FLATPAK} ${U} install test-missing-gpg-repo org.test.Hello &> install-error-log; then
    assert_not_reached "Should not be able to install with missing gpg key"
fi
assert_log_has_gpg_signature_error install-error-log

ok "fail with missing gpg key"

if ${FLATPAK} ${U} install test-wrong-gpg-repo org.test.Platform &> install-error-log; then
    assert_not_reached "Should not be able to install with wrong gpg key"
fi
assert_log_has_gpg_signature_error install-error-log

if ${FLATPAK} ${U} install test-wrong-gpg-repo org.test.Hello &> install-error-log; then
    assert_not_reached "Should not be able to install with wrong gpg key"
fi
assert_log_has_gpg_signature_error install-error-log

ok "fail with wrong gpg key"

make_required_version_app () {
    APP_ID=${1}
    VERSION=${2}
    if [ x${USE_COLLECTIONS_IN_SERVER-} == xyes ] ; then
        CID=org.test.Collection.test
    else
        CID=""
    fi

    REQUIRED_VERSION="${VERSION}" GPGARGS="${FL_GPGARGS}" $(dirname $0)/make-test-app.sh repos/test ${APP_ID} master "${CID}" > /dev/null
}

CURRENT_VERSION=`cat "$test_builddir/package_version.txt"`
V=( ${CURRENT_VERSION//./ } )  # Split parts to array

make_required_version_app org.test.SameVersion "${V[0]}.${V[1]}.${V[2]}"
make_required_version_app org.test.NeedNewerMicro "${V[0]}.${V[1]}.$(expr ${V[2]} + 1)"
make_required_version_app org.test.NeedNewerMinor "${V[0]}.$(expr ${V[1]} + 1).${V[2]}"
make_required_version_app org.test.NeedNewerMajor "$(expr ${V[0]} + 1).${V[1]}.${V[2]}"
make_required_version_app org.test.NeedOlderMinor "${V[0]}.$(expr ${V[1]} - 1).${V[2]}"
make_required_version_app org.test.MultiVersionFallback "${V[0]}.${V[1]}.${V[2]};1.0.0;"
make_required_version_app org.test.MultiVersionFallbackFail "${V[0]}.$(expr ${V[1]} + 1).${V[2]};1.0.0;"
make_required_version_app org.test.MultiVersionOk "${V[0]}.$(expr ${V[1]} + 1).0;${V[0]}.${V[1]}.${V[2]};"
make_required_version_app org.test.MultiVersionNotOk "${V[0]}.$(expr ${V[1]} + 1).0;${V[0]}.${V[1]}.$(expr ${V[2]} + 1);"

update_repo

${FLATPAK} ${U} install -y test-repo org.test.SameVersion >&2
${FLATPAK} ${U} install -y test-repo org.test.NeedOlderMinor >&2

if ${FLATPAK} ${U} install -y test-repo org.test.NeedNewerMicro &> install-error-log; then
    assert_not_reached "Should not be able to install with wrong micro version"
fi
assert_file_has_content install-error-log "needs a later flatpak version"

if ${FLATPAK} ${U} install -y test-repo org.test.NeedNewerMinor &> install-error-log; then
    assert_not_reached "Should not be able to install with wrong minor version"
fi
assert_file_has_content install-error-log "needs a later flatpak version"

if ${FLATPAK} ${U} install -y test-repo org.test.NeedNewerMajor &> install-error-log; then
    assert_not_reached "Should not be able to install with wrong major version"
fi
assert_file_has_content install-error-log "needs a later flatpak version"

${FLATPAK} ${U} install -y test-repo org.test.MultiVersionFallback >&2

if ${FLATPAK} ${U} install -y test-repo org.test.MultiVersionFallbackFail &> install-error-log; then
    assert_not_reached "Should not be able to install with wrong fallback version"
fi
assert_file_has_content install-error-log "needs a later flatpak version"

${FLATPAK} ${U} install -y test-repo org.test.MultiVersionOk >&2

if ${FLATPAK} ${U} install -y test-repo org.test.MultiVersionNotOk &> install-error-log; then
    assert_not_reached "Should not be able to install with wrong multi version"
fi
assert_file_has_content install-error-log "needs a later flatpak version"

${FLATPAK} ${U} uninstall -y --all >&2

ok "handles version requirements"

${FLATPAK} ${U} remotes -d | grep ^test-repo > repo-info
assert_not_file_has_content repo-info "new-title"
UPDATE_REPO_ARGS=--title=new-title update_repo
assert_file_has_content repos/test/config new-title

# This should make us automatically pick up the new metadata
${FLATPAK} ${U} install -y test-repo org.test.Platform >&2
${FLATPAK} ${U} remotes -d | grep ^test-repo > repo-info
assert_file_has_content repo-info "new-title"

ok "update metadata"

if [ x${USE_COLLECTIONS_IN_SERVER-} == xyes ] ; then
    COPY_COLLECTION_ID=org.test.Collection.test
    copy_collection_args=--collection-id=${COLLECTION_ID}
else
    COPY_COLLECTION_ID=
    copy_collection_args=
fi

ostree init --repo=repos/test-copy --mode=archive-z2 ${copy_collection_args} >&2
${FLATPAK} build-commit-from --no-update-summary --end-of-life=Reason1 --src-repo=repos/test repos/test-copy app/org.test.Hello/$ARCH/master >&2
update_repo test-copy ${COPY_COLLECTION_ID}

# Ensure we have no eol app in appdata
if ! ostree show --repo=repos/test-copy appstream/${ARCH} > /dev/null; then
    assert_not_reached "No appstream branch"
fi
ostree cat --repo=repos/test-copy appstream/${ARCH} /appstream.xml.gz | gunzip -d > appdata.xml
assert_not_file_has_content appdata.xml "org\.test\.Hello\.desktop"

${FLATPAK} repo --branches repos/test-copy > branches-log
assert_file_has_content branches-log "^app/org\.test\.Hello/.*eol=Reason1"

ok "eol build-commit-from"

${FLATPAK} ${U} install -y test-repo org.test.Hello >&2

EXPORT_ARGS="--end-of-life=Reason2" make_updated_app

# Ensure we have no eol app in appdata
if ! ostree show --repo=repos/test appstream/${ARCH} > /dev/null; then
    assert_not_reached "No appstream branch"
fi
ostree cat --repo=repos/test appstream/${ARCH} /appstream.xml.gz | gunzip -d > appdata.xml
assert_not_file_has_content appdata.xml "org\.test\.Hello\.desktop"

${FLATPAK} repo --branches repos/test > branches-log
assert_file_has_content branches-log "^app/org\.test\.Hello/.*eol=Reason2"

# eol only visible in remote-ls if -a:
${FLATPAK} ${U} remote-ls --columns=ref test-repo > remote-ls-log
assert_not_file_has_content remote-ls-log "app/org\.test\.Hello/"

${FLATPAK} ${U} remote-ls --columns=ref,options -a test-repo > remote-ls-log
assert_file_has_content remote-ls-log "app/org\.test\.Hello/.*eol=Reason2"

${FLATPAK} ${U} update -y org.test.Hello > update-log
assert_file_has_content update-log "org\.test\.Hello.*end-of-life"
assert_file_has_content update-log "Reason2"

${FLATPAK} ${U} info org.test.Hello > info-log
assert_file_has_content info-log "End-of-life: Reason2"

${FLATPAK} ${U} list --columns=ref,options > list-log
assert_file_has_content list-log "org\.test\.Hello/.*eol=Reason2"

${FLATPAK} ${U} uninstall -y org.test.Hello >&2

# Remove eol for future tests
EXPORT_ARGS="" make_updated_app

ok "eol build-export"

if [ x${USE_COLLECTIONS_IN_SERVER-} == xyes ] ; then
    REBASE_COLLECTION_ID=org.test.Collection.rebase
    rebase_collection_args=--collection-id=${REBASE_COLLECTION_ID}
else
    REBASE_COLLECTION_ID=
    rebase_collection_args=
fi

ostree init --repo=repos/test-rebase --mode=archive-z2 ${rebase_collection_args} >&2
${FLATPAK} build-commit-from --no-update-summary --src-repo=repos/test ${FL_GPGARGS} repos/test-rebase app/org.test.Hello/$ARCH/master runtime/org.test.Hello.Locale/$ARCH/master >&2
update_repo test-rebase ${REBASE_COLLECTION_ID}

${FLATPAK} remote-add ${U} --gpg-import=${FL_GPG_HOMEDIR}/pubring.gpg test-rebase "http://127.0.0.1:${port}/test-rebase" >&2

${FLATPAK} ${U} install -y test-rebase org.test.Hello >&2

assert_not_has_dir $HOME/.var/app/org.test.Hello
${FLATPAK} run --command=bash org.test.Hello -c 'echo foo > $XDG_DATA_HOME/a-file' >&2
assert_has_dir $HOME/.var/app/org.test.Hello
assert_has_file $HOME/.var/app/org.test.Hello/data/a-file

${FLATPAK} build-commit-from --no-update-summary --end-of-life-rebase=org.test.Hello=org.test.NewHello --src-repo=repos/test ${FL_GPGARGS} repos/test-rebase app/org.test.Hello/$ARCH/master runtime/org.test.Hello.Locale/$ARCH/master >&2
GPGARGS="${FL_GPGARGS}" $(dirname $0)/make-test-app.sh repos/test-rebase org.test.NewHello master "${REBASE_COLLECTION_ID}" "NEW" > /dev/null
update_repo test-rebase

# Temporarily set the minimum free space to something astronomical to make the
# install of the rebased app fail.
orig_min_free_space=$(ostree --repo=$FL_DIR/repo config get core.min-free-space-size || :)
ostree --repo=$FL_DIR/repo config set core.min-free-space-size 999TB

if ${FLATPAK} ${U} update -y org.test.Hello >&2; then
    assert_not_reached "flatpak update should fail with insufficient free space"
fi

# Check that the old app is still installed and the new app is not installed.
# See https://github.com/flatpak/flatpak/pull/5332
assert_has_dir $FL_DIR/app/org.test.Hello/$ARCH/master/active/files
assert_not_has_dir $FL_DIR/app/org.test.NewHello/$ARCH/master/active/files

# Restore the original minimum free space.
if [ -n "$orig_min_free_space" ]; then
    ostree --repo=$FL_DIR/repo config set core.min-free-space-size "$orig_min_free_space"
else
    ostree --repo=$FL_DIR/repo config unset core.min-free-space-size
fi

# Now do a --no-deploy update and check the old version is still installed
${FLATPAK} ${U} update -y --no-deploy org.test.Hello >&2

assert_has_dir $HOME/.var/app/org.test.Hello
assert_has_file $HOME/.var/app/org.test.Hello/data/a-file
assert_not_has_dir $HOME/.var/app/org.test.NewHello

# Finally actually do the update.
${FLATPAK} ${U} update -y org.test.Hello >&2

# Make sure we got the new version installed
assert_has_dir $FL_DIR/app/org.test.NewHello/$ARCH/master/active/files
assert_not_has_file $FL_DIR/app/org.test.NewHello/$ARCH/master/active/files

${FLATPAK} run --command=bash org.test.NewHello -c 'echo foo > $XDG_DATA_HOME/another-file' >&2

# Ensure we migrated the app data
assert_has_dir $HOME/.var/app/org.test.NewHello
assert_has_file $HOME/.var/app/org.test.NewHello/data/a-file
assert_has_file $HOME/.var/app/org.test.NewHello/data/another-file

# And that the old is symlinked
assert_has_symlink $HOME/.var/app/org.test.Hello
assert_has_file $HOME/.var/app/org.test.Hello/data/a-file
assert_has_file $HOME/.var/app/org.test.Hello/data/another-file

# Simulate removal of app data dir
rm -rf $HOME/.var/app/org.test.NewHello

${FLATPAK} run org.test.NewHello >&2

# Ensure the data dir is re-created instead of migrating the symlink
assert_has_dir $HOME/.var/app/org.test.NewHello

${FLATPAK} ${U} uninstall -y org.test.NewHello org.test.Platform >&2

ok "eol-rebase"

# Remove any pin of the runtime from an earlier test
${FLATPAK} ${U} pin --remove runtime/org.test.Platform/$ARCH/master &>/dev/null || true

EXPORT_ARGS="--end-of-life=Reason3" make_updated_runtime

${FLATPAK} ${U} install -y test-repo org.test.Hello >&2
${FLATPAK} ${U} list --columns=ref > list-log
assert_file_has_content list-log "org\.test\.Hello/"
assert_file_has_content list-log "org\.test\.Platform/"

${FLATPAK} ${U} uninstall -y org.test.Hello >&2

${FLATPAK} ${U} list --columns=ref -a > list-log
assert_not_file_has_content list-log "org\.test\.Hello/"
assert_not_file_has_content list-log "org\.test\.Platform/"
assert_not_file_has_content list-log "org\.test\.Platform.Locale/"

ok "eol runtime uninstalled with app"

${FLATPAK} ${U} install -y test-repo org.test.Hello >&2

${FLATPAK} ${U} info org.test.Platform > info-log
assert_file_has_content info-log "End-of-life: Reason3"

assert_has_dir $FL_DIR/runtime/org.test.Platform/$ARCH/master/active/files

# Update the app to a different runtime branch
make_updated_runtime "" "" "mainline" ""
make_updated_app "" "" "" "UPDATED99" "" "mainline"

# First update with --no-deploy and check the old runtime is still installed
${FLATPAK} ${U} update -y --no-deploy org.test.Hello >&2

assert_has_dir $FL_DIR/runtime/org.test.Platform/$ARCH/master/active/files
assert_not_has_dir $FL_DIR/runtime/org.test.Platform/$ARCH/mainline/active/files

${FLATPAK} ${U} update -y org.test.Hello >&2

# The previous runtime should have been removed during the update
assert_has_dir $FL_DIR/runtime/org.test.Platform/$ARCH/mainline/active/files
assert_not_has_dir $FL_DIR/runtime/org.test.Platform/$ARCH/master/active/files

# Revert things for future tests
EXPORT_ARGS="" make_updated_runtime
make_updated_app "" "" "" "UPDATED100" "" "master"
${FLATPAK} ${U} uninstall -y --all >&2
ostree refs --repo=repos/test --delete runtime/org.test.Platform/$ARCH/mainline >&2
ostree refs --repo=repos/test --delete runtime/org.test.Platform.Locale/$ARCH/mainline >&2
update_repo

ok "eol runtime uninstalled on app update to different runtime"

${FLATPAK} ${U} install -y test-repo org.test.Hello >&2

# Runtime isn't EOL at time of app uninstall, so it's left alone
${FLATPAK} ${U} uninstall -y org.test.Hello >&2
assert_has_dir $FL_DIR/runtime/org.test.Platform/$ARCH/master/active/files

EXPORT_ARGS="--end-of-life=Reason4" make_updated_runtime
${FLATPAK} ${U} update -y org.test.Platform >&2
${FLATPAK} ${U} info org.test.Platform > info-log
assert_file_has_content info-log "End-of-life: Reason4"

# Now that the runtime is EOL and unused it should be uninstalled by the
# update command. Check first that it's not uninstalled with --no-deploy.
${FLATPAK} ${U} update -y --no-deploy >&2
assert_has_dir $FL_DIR/runtime/org.test.Platform/$ARCH/master/active/files

${FLATPAK} ${U} update -y >&2
assert_not_has_dir $FL_DIR/runtime/org.test.Platform/$ARCH/master/active/files

# Revert things for future tests
EXPORT_ARGS="" make_updated_runtime
${FLATPAK} ${U} uninstall -y --all >&2

ok "eol runtime uninstalled during update run"

${FLATPAK} ${U} install -y test-repo org.test.Platform >&2

port=$(cat httpd-port)
UPDATE_REPO_ARGS="--redirect-url=http://127.0.0.1:${port}/test-gpg3 --gpg-import=${FL_GPG_HOMEDIR2}/pubring.gpg" update_repo
SRC_RUNTIME_REPO="test" GPGPUBKEY="${FL_GPG_HOMEDIR2}/pubring.gpg" GPGARGS="${FL_GPGARGS2}" setup_repo_no_add test-gpg3 org.test.Collection.test master

${FLATPAK} ${U} update -y org.test.Platform >&2
# Ensure we have the new uri
${FLATPAK} ${U} remotes -d | grep ^test-repo > repo-info
assert_file_has_content repo-info "/test-gpg3"

# Make sure we also get new installs from the new repo
GPGARGS="${FL_GPGARGS2}" make_updated_app test-gpg3 org.test.Collection.test master
update_repo test-gpg3 org.test.Collection.test

${FLATPAK} ${U} install -y test-repo org.test.Hello >&2
assert_file_has_content $FL_DIR/app/org.test.Hello/$ARCH/master/active/files/bin/hello.sh UPDATED

# Switch back to the old url to unconfuse other tests
UPDATE_REPO_ARGS="--redirect-url=" update_repo
${FLATPAK} ${U} remote-modify --url="http://127.0.0.1:${port}/test" test-repo >&2

# Also remove app so we can install the older one from the previous repo
${FLATPAK} ${U} uninstall -y org.test.Hello >&2

ok "redirect url and gpg key"

${FLATPAK} ${U} install -y -v test-repo org.test.Hello >&2

# Test https://github.com/flatpak/flatpak/issues/3222
mkdir -p $FL_DIR/repo/refs/mirrors/org.test.Collection.test/app/org.test.Hello/$ARCH/
cp $FL_DIR/repo/refs/remotes/test-repo/app/org.test.Hello/$ARCH/master $FL_DIR/repo/refs/mirrors/org.test.Collection.test/app/org.test.Hello/$ARCH/
make_updated_app test org.test.Collection.test master UPDATE2
${FLATPAK} ${U} update -y org.test.Hello >&2
assert_not_has_file $FL_DIR/repo/refs/mirrors/org.test.Collection.test/app/org.test.Hello/$ARCH/master
assert_has_file $FL_DIR/repo/refs/remotes/test-repo/app/org.test.Hello/$ARCH/master

ok "mirror ref deletion on update"

${FLATPAK} ${U} list --arch=$ARCH --columns=ref > list-log
assert_file_has_content list-log "org\.test\.Hello/"
assert_file_has_content list-log "org\.test\.Platform/"

ok "flatpak list --arch --columns works"

if ${FLATPAK} ${INVERT_U} uninstall -y org.test.Hello >&2; then
    assert_not_reached "Should not be able to uninstall ${INVERT_U} when installed ${U}"
fi

# Test that unspecified --user/--system finds the right one, so no ${U}
${FLATPAK} uninstall -y org.test.Platform org.test.Hello >&2

${FLATPAK} ${U} list --columns=ref > list-log
assert_not_file_has_content list-log "org\.test\.Hello/"
assert_not_file_has_content list-log "org\.test\.Platform/"

ok "uninstall vs installations"

${FLATPAK} ${U} install -y test-repo org.test.Hello >&2

${FLATPAK} ${U} list --columns=ref > list-log
assert_file_has_content list-log "org\.test\.Hello/"
assert_file_has_content list-log "org\.test\.Platform/"

if ${FLATPAK} ${U} uninstall -y org.test.Platform >&2; then
    assert_not_reached "Should not be able to uninstall ${U} when there is a dependency installed"
fi

${FLATPAK} ${U} uninstall -y org.test.Hello >&2
${FLATPAK} ${U} uninstall -y org.test.Platform >&2

${FLATPAK} ${U} list --columns=ref > list-log
assert_not_file_has_content list-log "org\.test\.Hello/"
assert_not_file_has_content list-log "org\.test\.Platform/"

ok "uninstall dependencies"

${FLATPAK} ${U} install -y test-repo org.test.Hello >&2

# Note: This typo is only auto-corrected without user interaction because we're using -y
${FLATPAK} ${U} uninstall -y hello >&2
${FLATPAK} ${U} uninstall -y platform >&2

ok "typo correction works for uninstall"

${FLATPAK} ${U} install -y test-repo org.test.Hello master >&2

${FLATPAK} ${U} uninstall -y org.test.Hello master >&2
${FLATPAK} ${U} uninstall -y org.test.Platform master >&2

ok "install and uninstall support 'NAME BRANCH' syntax"

${FLATPAK} ${U} install -y --no-deploy test-repo org.test.Hello >&2

${FLATPAK} ${U} list --columns=ref > list-log
assert_not_file_has_content list-log "org\.test\.Hello/"
assert_not_file_has_content list-log "org\.test\.Platform/"

# Disable the remote to make sure we don't do i/o
port=$(cat httpd-port)
${FLATPAK} ${U} remote-modify --url="http://127.0.0.1:${port}/disable-test" test-repo

${FLATPAK} ${U} install -y --no-pull test-repo org.test.Hello >&2

# re-enable remote
${FLATPAK} ${U} remote-modify --url="http://127.0.0.1:${port}/test" test-repo >&2

${FLATPAK} ${U} list --columns=ref > list-log
assert_file_has_content list-log "org\.test\.Hello/"
assert_file_has_content list-log "org\.test\.Platform/"

ok "install with --no-deploy and then --no-pull"

${FLATPAK} uninstall -y --all >&2

${FLATPAK} ${U} list --columns=ref > list-log
assert_not_file_has_content list-log "org\.test\.Hello/"
assert_not_file_has_content list-log "org\.test\.Platform/"

ok "uninstall --all"

${FLATPAK} ${U} install -y test-repo org.test.Hello >&2

${FLATPAK} ${U} list -a --columns=ref > list-log
assert_file_has_content list-log "org\.test\.Hello/"
assert_file_has_content list-log "org\.test\.Hello\.Locale/"

${FLATPAK} ${U} remote-delete --force test-repo >&2
${FLATPAK} ${U} uninstall -y org.test.Hello >&2

${FLATPAK} ${U} list -a --columns=ref > list-log
assert_not_file_has_content list-log "org\.test\.Hello/"
assert_not_file_has_content list-log "org\.test\.Hello\.Locale/"

setup_repo

ok "uninstall with missing remote"

# Remove any pin of the runtime from an earlier test
${FLATPAK} ${U} pin --remove runtime/org.test.Platform/$ARCH/master &>/dev/null || true

${FLATPAK} ${U} list -a --columns=ref > list-log
assert_file_has_content list-log "org\.test\.Platform/"

${FLATPAK} ${U} uninstall -y --unused >&2

${FLATPAK} ${U} list -a --columns=ref > list-log
assert_not_file_has_content list-log "org\.test\.Platform/"

ok "uninstall --unused"

${FLATPAK} ${U} install -y test-repo org.test.Platform >&2

${FLATPAK} ${U} list -a --columns=ref > list-log
assert_file_has_content list-log "org\.test\.Platform/"

# Check that the runtime won't be removed if it's pinned
# (which happens during the install above)
${FLATPAK} ${U} pin > pins
assert_file_has_content pins "runtime/org\.test\.Platform/$ARCH/master"
NUM_PINS=$(cat pins | wc -l)
if [ $NUM_PINS -ne 1 ]; then
    assert_not_reached "There should only be one pinned runtime"
fi
rm pins

${FLATPAK} ${U} uninstall -y --unused >&2

${FLATPAK} ${U} list -a --columns=ref > list-log
assert_file_has_content list-log "org\.test\.Platform/"

# Remove the pin and try again
${FLATPAK} ${U} pin --remove "runtime/org.test.Platform/$ARCH/master" >&2
${FLATPAK} ${U} uninstall -y --unused >&2
${FLATPAK} ${U} list -a --columns=ref > list-log
assert_not_file_has_content list-log "org\.test\.Platform/"

ok "uninstall --unused ignores pinned runtimes"

# Test that remote-ls works in all of the following cases:
# * system remote, and --system is used
# * system remote, and --system is omitted
# * user remote, and --user is used
# * user remote, and --user is omitted
# and fails in the following cases:
# * system remote, and --user is used
# * user remote, and --system is used
if [ x${USE_SYSTEMDIR-} == xyes ]; then
    ${FLATPAK} --system remote-ls --columns=ref test-repo > repo-list
    assert_file_has_content repo-list "org\.test\.Hello/"

    ${FLATPAK} remote-ls --columns=ref test-repo > repo-list
    assert_file_has_content repo-list "org\.test\.Hello/"

    if ${FLATPAK} --user remote-ls test-repo &> remote-ls-error-log; then
        assert_not_reached "flatpak --user remote-ls should not work for system remotes"
    fi
    assert_file_has_content remote-ls-error-log "Remote \"test-repo\" not found"
else
    ${FLATPAK} --user remote-ls --columns=ref test-repo > repo-list
    assert_file_has_content repo-list "org\.test\.Hello/"

    ${FLATPAK} remote-ls --columns=ref test-repo > repo-list
    assert_file_has_content repo-list "org\.test\.Hello/"

    if ${FLATPAK} --system remote-ls test-repo &> remote-ls-error-log; then
        assert_not_reached "flatpak --system remote-ls should not work for user remotes"
    fi
    assert_file_has_content remote-ls-error-log "Remote \"test-repo\" not found"
fi

ok "remote-ls"

# Test that remote-ls can take a file:// URI
${FLATPAK} build-update-repo  ${BUILD_UPDATE_REPO_FLAGS-} --no-update-appstream repos/test >&2
${FLATPAK} remote-ls --columns=ref file://`pwd`/repos/test > repo-list
assert_file_has_content repo-list "org\.test\.Hello/"

ok "remote-ls URI"

# Test that remote-modify works in all of the following cases:
# * system remote, and --system is used
# * system remote, and --system is omitted
# * user remote, and --user is used
# * user remote, and --user is omitted
# and fails in the following cases:
# * system remote, and --user is used
# * user remote, and --system is used
if [ x${USE_SYSTEMDIR-} == xyes ]; then
    ${FLATPAK} --system remote-modify --title=NewTitle test-repo >&2
    ${FLATPAK} remotes -d | grep ^test-repo > repo-info
    assert_file_has_content repo-info "NewTitle"
    ${FLATPAK} --system remote-modify --title=OldTitle test-repo >&2

    ${FLATPAK} remote-modify --title=NewTitle test-repo >&2
    ${FLATPAK} remotes -d | grep ^test-repo > repo-info
    assert_file_has_content repo-info "NewTitle"
    ${FLATPAK} --system remote-modify --title=OldTitle test-repo >&2

    if ${FLATPAK} --user remote-modify --title=NewTitle test-repo &> remote-modify-error-log; then
        assert_not_reached "flatpak --user remote-modify should not work for system remotes"
    fi
    assert_file_has_content remote-modify-error-log "Remote \"test-repo\" not found"
else
    ${FLATPAK} --user remote-modify --title=NewTitle test-repo >&2
    ${FLATPAK} remotes -d | grep ^test-repo > repo-info
    assert_file_has_content repo-info "NewTitle"
    ${FLATPAK} --user remote-modify --title=OldTitle test-repo >&2

    ${FLATPAK} remote-modify --title=NewTitle test-repo >&2
    ${FLATPAK} remotes -d | grep ^test-repo > repo-info
    assert_file_has_content repo-info "NewTitle"
    ${FLATPAK} remote-modify --title=OldTitle test-repo >&2

    if ${FLATPAK} --system remote-modify --title=NewTitle test-repo &> remote-modify-error-log; then
        assert_not_reached "flatpak --system remote-modify should not work for user remotes"
    fi
    assert_file_has_content remote-modify-error-log "Remote \"test-repo\" not found"
fi

ok "remote-modify"

# Test that remote-delete works in all of the following cases:
# * system remote, and --system is used
# * system remote, and --system is omitted
# * user remote, and --user is used
# * user remote, and --user is omitted
# and fails in the following cases:
# * system remote, and --user is used
# * user remote, and --system is used
if [ x${USE_SYSTEMDIR-} == xyes ]; then
    ${FLATPAK} --system remote-delete test-repo >&2
    ${FLATPAK} remotes > repo-info
    assert_not_file_has_content repo-info "test-repo"
    setup_repo

    ${FLATPAK} remote-delete test-repo >&2
    ${FLATPAK} remotes > repo-list
    assert_not_file_has_content repo-info "test-repo"
    setup_repo

    if ${FLATPAK} --user remote-delete test-repo &> remote-delete-error-log; then
        assert_not_reached "flatpak --user remote-delete should not work for system remotes"
    fi
    assert_file_has_content remote-delete-error-log "Remote \"test-repo\" not found"
else
    ${FLATPAK} --user remote-delete test-repo >&2
    ${FLATPAK} remotes > repo-info
    assert_not_file_has_content repo-info "test-repo"
    setup_repo

    ${FLATPAK} remote-delete test-repo >&2
    ${FLATPAK} remotes > repo-info
    assert_not_file_has_content repo-info "test-repo"
    setup_repo

    if ${FLATPAK} --system remote-delete test-repo &> remote-delete-error-log; then
        assert_not_reached "flatpak --system remote-delete should not work for user remotes"
    fi
    assert_file_has_content remote-delete-error-log "Remote \"test-repo\" not found"
fi

ok "remote-delete"

# Test that remote-info works in all of the following cases:
# * system remote, and --system is used
# * system remote, and --system is omitted
# * user remote, and --user is used
# * user remote, and --user is omitted
# and fails in the following cases:
# * system remote, and --user is used
# * user remote, and --system is used
if [ x${USE_SYSTEMDIR-} == xyes ]; then
    ${FLATPAK} --system remote-info test-repo org.test.Hello > remote-ref-info
    assert_file_has_content remote-ref-info "ID: org\.test\.Hello$"

    ${FLATPAK} remote-info test-repo org.test.Hello > remote-ref-info
    assert_file_has_content remote-ref-info "ID: org\.test\.Hello$"

    if ${FLATPAK} --user remote-info test-repo org.test.Hello &> remote-info-error-log; then
        assert_not_reached "flatpak --user remote-info should not work for system remotes"
    fi
    assert_file_has_content remote-info-error-log "Remote \"test-repo\" not found"
else
    ${FLATPAK} --user remote-info test-repo org.test.Hello > remote-ref-info
    assert_file_has_content remote-ref-info "ID: org\.test\.Hello$"

    ${FLATPAK} remote-info test-repo org.test.Hello > remote-ref-info
    assert_file_has_content remote-ref-info "ID: org\.test\.Hello$"

    if ${FLATPAK} --system remote-info test-repo org.test.Hello &> remote-info-error-log; then
        assert_not_reached "flatpak --system remote-info should not work for user remotes"
    fi
    assert_file_has_content remote-info-error-log "Remote \"test-repo\" not found"
fi

ok "remote-info"

${FLATPAK} ${U} remote-ls --columns=ref -a test-repo > remote-ls-log
assert_file_has_content remote-ls-log "app/org\.test\.Hello/"
assert_file_has_content remote-ls-log "runtime/org\.test\.Hello\.Locale/"
assert_file_has_content remote-ls-log "runtime/org\.test\.Platform/"

${FLATPAK}  ${U} remote-info test-repo org.test.Hello > remote-ref-info
assert_file_has_content remote-ref-info "ID: org\.test\.Hello$"

${FLATPAK} ${U} update --appstream test-repo >&2
assert_file_has_content $FL_DIR/appstream/test-repo/$ARCH/active/appstream.xml "app/org\.test\.Hello/"

# Make a copy so we can remove it later
cp ${test_srcdir}/test.filter test.filter
${FLATPAK} ${U} remote-modify test-repo --filter $(pwd)/test.filter >&2

${FLATPAK} ${U} remote-ls --columns=ref -a test-repo > remote-ls-log

assert_not_file_has_content remote-ls-log "app/org\.test\.Hello/"
assert_not_file_has_content remote-ls-log "runtime/org\.test\.Hello\.Locale/"
assert_file_has_content remote-ls-log "runtime/org\.test\.Platform/"

if ${FLATPAK}  ${U} remote-info test-repo org.test.Hello > remote-ref-info 2> /dev/null; then
    assert_not_reached "flatpak remote-info test-repo org.test.Hello should fail due to filter"
fi

if ${FLATPAK} ${U} install -y test-repo org.test.Hello &> /dev/null; then
    assert_not_reached "should not be able to install org.test.Hello should fail due to filter"
fi

${FLATPAK} ${U} update --appstream test-repo >&2
assert_not_file_has_content $FL_DIR/appstream/test-repo/$ARCH/active/appstream.xml "app/org\.test\.Hello/"

# Ensure that filter works even when the filter file is removed (uses the backup)
rm -f test.filter
${FLATPAK} ${U} remote-ls --columns=ref -a test-repo > remote-ls-log
assert_not_file_has_content remote-ls-log "app/org\.test\.Hello/"
assert_not_file_has_content remote-ls-log "runtime/org\.test\.Hello\.Locale/"
assert_file_has_content remote-ls-log "runtime/org\.test\.Platform/"
if ${FLATPAK}  ${U} remote-info test-repo org.test.Hello > remote-ref-info; then
    assert_not_reached "flatpak remote-info test-repo org.test.Hello should fail due to filter"
fi
if ${FLATPAK} ${U} install -y test-repo org.test.Hello >&2; then
    assert_not_reached "should not be able to install org.test.Hello should fail due to filter"
fi

${FLATPAK} ${U} update --appstream test-repo >&2
assert_not_file_has_content $FL_DIR/appstream/test-repo/$ARCH/active/appstream.xml "app/org\.test\.Hello/"

# Remove filter

${FLATPAK} ${U} remote-modify test-repo --no-filter >&2

${FLATPAK} ${U} remote-ls --columns=ref -a test-repo > remote-ls-log
assert_file_has_content remote-ls-log "app/org\.test\.Hello/"
assert_file_has_content remote-ls-log "runtime/org\.test\.Hello\.Locale/"
assert_file_has_content remote-ls-log "runtime/org\.test\.Platform/"

ok "filter"

# Try installing it from a flatpakrepo file. Don’t uninstall afterwards because
# we need it for the next test.
cat << EOF > test.flatpakrepo
[Flatpak Repo]
Url=http://127.0.0.1:${port}/test-no-gpg
Title=The Title
Comment=The Comment
Description=The Description
Homepage=https://the.homepage/
Icon=https://the.icon/
DefaultBranch=default-branch
NoDeps=true
EOF

if ${FLATPAK} ${U} remote-add test-repo test.flatpakrepo >&2; then
    assert_not_reached "should not be able to add pre-existing remote"
fi

# No-op
${FLATPAK} ${U} remote-add --if-not-exists test-repo test.flatpakrepo >&2


${FLATPAK} ${U} remote-add new-repo test.flatpakrepo >&2

assert_remote_has_config new-repo url "http://127.0.0.1:${port}/test-no-gpg"
assert_remote_has_config new-repo gpg-verify "false"
assert_remote_has_config new-repo xa.title "The Title"
assert_remote_has_no_config new-repo xa.title-is-set
assert_remote_has_config new-repo xa.comment "The Comment"
assert_remote_has_no_config new-repo xa.comment-is-set
assert_remote_has_config new-repo xa.description "The Description"
assert_remote_has_no_config new-repo xa.description-is-set
assert_remote_has_config new-repo xa.homepage "https://the.homepage/"
assert_remote_has_no_config new-repo xa.homepage-is-set
assert_remote_has_config new-repo xa.icon "https://the.icon/"
assert_remote_has_no_config new-repo xa.icon-is-set
assert_remote_has_config new-repo xa.default-branch "default-branch"
assert_remote_has_no_config new-repo xa.default-branch-is-set
assert_remote_has_config new-repo xa.nodeps "true"
assert_remote_has_no_config new-repo xa.noenumerate
assert_remote_has_no_config new-repo xa.filter

${FLATPAK} ${U} remote-delete new-repo >&2
${FLATPAK} ${U} remote-add  --title=Title2 --comment=Comment2 --default-branch=branch2 new-repo test.flatpakrepo >&2

assert_remote_has_config new-repo url "http://127.0.0.1:${port}/test-no-gpg"
assert_remote_has_config new-repo gpg-verify "false"
assert_remote_has_config new-repo xa.title "Title2"
assert_remote_has_config new-repo xa.title-is-set true
assert_remote_has_config new-repo xa.comment "Comment2"
assert_remote_has_config new-repo xa.comment-is-set true
assert_remote_has_config new-repo xa.description "The Description"
assert_remote_has_no_config new-repo xa.description-is-set
assert_remote_has_config new-repo xa.homepage "https://the.homepage/"
assert_remote_has_no_config new-repo xa.homepage-is-set
assert_remote_has_config new-repo xa.icon "https://the.icon/"
assert_remote_has_no_config new-repo xa.icon-is-set
assert_remote_has_config new-repo xa.default-branch "branch2"
assert_remote_has_config new-repo xa.default-branch-is-set true
assert_remote_has_config new-repo xa.nodeps "true"
assert_remote_has_no_config new-repo xa.noenumerate
assert_remote_has_no_config new-repo xa.filter

${FLATPAK} ${U} remote-delete new-repo >&2
${FLATPAK} ${U} remote-add  --filter="${test_srcdir}/test.filter" new-repo test.flatpakrepo >&2

assert_remote_has_config new-repo xa.filter "${test_srcdir}/test.filter"

# This should unset the filter:
${FLATPAK} ${U} remote-add --if-not-exists new-repo test.flatpakrepo >&2
assert_remote_has_no_config new-repo xa.filter

ok "flatpakrepo"

===== ./tests/org.freedesktop.impl.portal.desktop.test.service.in =====
[D-BUS Service]
Name=org.freedesktop.impl.portal.desktop.test
Exec=@libexecdir@/test-portal-impl

===== ./tests/test-locale-utils.c =====
/*
 * Copyright 2023 Collabora Ltd.
 * SPDX-License-Identifier: LGPL-2.1-or-later
 */

#include "config.h"

#include <glib.h>
#include "libglnx.h"
#include "flatpak.h"

#include "flatpak-locale-utils-private.h"

#include "tests/testlib.h"

static void
test_get_system_locales (void)
{
  const GPtrArray *result = flatpak_get_system_locales ();
  const GPtrArray *again;
  gsize i;

  g_test_message ("System locales:");

  for (i = 0; i < result->len; i++)
    {
      if (i == result->len - 1)
        {
          g_test_message ("(end)");
          g_assert_null (g_ptr_array_index (result, i));
        }
      else
        {
          g_assert_nonnull (g_ptr_array_index (result, i));
          g_test_message ("- %s", (char *) g_ptr_array_index (result, i));
        }
    }

  again = flatpak_get_system_locales ();
  g_assert_cmpuint (again->len, ==, result->len);

  for (i = 0; i < again->len; i++)
    g_assert_cmpstr (g_ptr_array_index (again, i), ==, g_ptr_array_index (result, i));
}

static void
test_get_user_locales (void)
{
  const GPtrArray *result = flatpak_get_user_locales ();
  const GPtrArray *again;
  gsize i;

  g_test_message ("User locales:");

  for (i = 0; i < result->len; i++)
    {
      if (i == result->len - 1)
        {
          g_test_message ("(end)");
          g_assert_null (g_ptr_array_index (result, i));
        }
      else
        {
          g_assert_nonnull (g_ptr_array_index (result, i));
          g_test_message ("- %s", (char *) g_ptr_array_index (result, i));
        }
    }

  again = flatpak_get_user_locales ();
  g_assert_cmpuint (again->len, ==, result->len);

  for (i = 0; i < again->len; i++)
    g_assert_cmpstr (g_ptr_array_index (again, i), ==, g_ptr_array_index (result, i));
}

static const struct
{
  const char *in;
  const char *expected;
} lang_from_locale_tests[] =
{
  { "C", NULL },
  { "C.UTF-8", NULL },
  { "en.ISO-8859-15", "en" },
  { "en@cantab", "en" },
  { "en_GB", "en" },
  { "en_US.utf8", "en" },
  { "sv_FI@euro", "sv" },
};

static void
test_lang_from_locale (void)
{
  gsize i;

  for (i = 0; i < G_N_ELEMENTS (lang_from_locale_tests); i++)
    {
      const char *in = lang_from_locale_tests[i].in;
      const char *expected = lang_from_locale_tests[i].expected;
      g_autofree char *actual = NULL;

      g_test_message ("%s", in);
      actual = flatpak_get_lang_from_locale (in);
      g_test_message ("-> %s", actual ? actual : "(null)");
      g_assert_cmpstr (actual, ==, expected);
    }
}

static void
test_langs_from_accountsservice (void)
{
  g_autoptr(GDBusProxy) proxy = flatpak_locale_get_accounts_dbus_proxy ();
  g_autoptr(GPtrArray) langs = g_ptr_array_new_with_free_func (g_free);
  gsize i;

  if (proxy == NULL)
    {
      g_test_skip ("Unable to communicate with accountsservice");
      return;
    }

  if (flatpak_get_all_langs_from_accounts_dbus (proxy, langs))
    {
      g_test_message ("Languages from accountsservice (new method):");

      for (i = 0; i < langs->len; i++)
        {
          g_assert_nonnull (g_ptr_array_index (langs, i));
          g_test_message ("- %s", (char *) g_ptr_array_index (langs, i));
        }

      g_test_message ("(end)");
    }
  else
    {
      g_test_message ("accountsservice doesn't support GetUsersLanguages");
    }

  g_ptr_array_set_size (langs, 0);
  flatpak_get_locale_langs_from_accounts_dbus (proxy, langs);

  g_test_message ("Languages from accountsservice (old method):");

  for (i = 0; i < langs->len; i++)
    {
      g_assert_nonnull (g_ptr_array_index (langs, i));
      g_test_message ("- %s", (char *) g_ptr_array_index (langs, i));
    }

  g_test_message ("(end)");

  g_ptr_array_set_size (langs, 0);
  flatpak_get_locale_langs_from_accounts_dbus_for_user (proxy, langs, getuid ());

  g_test_message ("Languages from accountsservice (for uid %u only):", getuid ());

  for (i = 0; i < langs->len; i++)
    {
      g_assert_nonnull (g_ptr_array_index (langs, i));
      g_test_message ("- %s", (char *) g_ptr_array_index (langs, i));
    }

  g_test_message ("(end)");
}

static void
test_langs_from_localed (void)
{
  g_autoptr(GDBusProxy) proxy = flatpak_locale_get_localed_dbus_proxy ();
  g_autoptr(GPtrArray) langs = g_ptr_array_new_with_free_func (g_free);
  gsize i;

  if (proxy == NULL)
    {
      g_test_skip ("Unable to communicate with localed");
      return;
    }

  flatpak_get_locale_langs_from_localed_dbus (proxy, langs);

  g_test_message ("Languages from localed:");

  for (i = 0; i < langs->len; i++)
    {
      g_assert_nonnull (g_ptr_array_index (langs, i));
      g_test_message ("- %s", (char *) g_ptr_array_index (langs, i));
    }

  g_test_message ("(end)");
}

int
main (int argc, char *argv[])
{
  int res;

  g_test_init (&argc, &argv, NULL);
  isolated_test_dir_global_setup ();

  g_test_add_func ("/locale/get-system-locales", test_get_system_locales);
  g_test_add_func ("/locale/get-user-locales", test_get_user_locales);
  g_test_add_func ("/locale/lang-from-locale", test_lang_from_locale);
  g_test_add_func ("/locale/langs-from-accountsservice",
                   test_langs_from_accountsservice);
  g_test_add_func ("/locale/langs-from-localed", test_langs_from_localed);

  res = g_test_run ();

  isolated_test_dir_global_teardown ();

  return res;
}

===== ./meson.build =====
# Copyright 2022 Collabora Ltd.
# SPDX-License-Identifier: LGPL-2.1-or-later

project(
  'flatpak',
  'c',
  version : '1.18.0',
  default_options: [
    'warning_level=2',
  ],
  meson_version : '>=0.53.0',
)

flatpak_major_version = 1
flatpak_minor_version = 18
flatpak_micro_version = 0
flatpak_extra_version = ''

flatpak_interface_age = 0
flatpak_binary_age = (
  10000 * flatpak_major_version
  + 100 * flatpak_minor_version
  + flatpak_micro_version
)

if '@0@.@1@.@2@@3@'.format(
  flatpak_major_version,
  flatpak_minor_version,
  flatpak_micro_version,
  flatpak_extra_version,
) != meson.project_version()
  error('Project version does not match parts')
endif

required_glib = '2.46'
# Before increasing this, update subprojects/bubblewrap.wrap
required_bwrap = '0.10.0'
# Before increasing this, update subprojects/dbus-proxy.wrap
required_dbus_proxy = '0.1.0'
required_libostree = '2020.8'

fs = import('fs')
gnome = import('gnome')
i18n = import('i18n')
pkgconfig = import('pkgconfig')

# TODO: We can replace these with meson.project_foo_root()
# when we depend on meson 0.56
project_build_root = meson.current_build_dir()
project_source_root = meson.current_source_dir()

if meson.version().version_compare('>=0.58')
  global_source_root = meson.global_source_root()
else
  global_source_root = meson.source_root()
endif

if meson.version().version_compare('>=0.55.0')
  can_run_host_binaries = meson.can_run_host_binaries()
else
  can_run_host_binaries = meson.has_exe_wrapper() or not meson.is_cross_build()
endif

cc = meson.get_compiler('c')
add_project_arguments('-include', 'config.h', language : 'c')
common_include_directories = include_directories(
  '.',
  'common',
)

# Keep this in sync with ostree, except remove -Wall (part of Meson
# warning_level 2) and -Werror=declaration-after-statement
add_project_arguments(
  cc.get_supported_arguments([
    '-Werror=shadow',
    '-Werror=empty-body',
    '-Werror=strict-prototypes',
    '-Werror=missing-prototypes',
    '-Werror=implicit-function-declaration',
    '-Werror=pointer-arith',
    '-Werror=init-self',
    '-Werror=missing-declarations',
    '-Werror=return-type',
    '-Werror=overflow',
    '-Werror=int-conversion',
    '-Werror=parenthesis',
    '-Werror=incompatible-pointer-types',
    '-Werror=misleading-indentation',
    '-Werror=missing-include-dirs',

    # Meson warning_level=2 would do this, but we are not fully
    # signedness-safe yet
    '-Wno-sign-compare',
    '-Wno-error=sign-compare',

    # Meson warning_level=2 would do this
    '-Wno-cast-function-type',
    '-Wno-error=cast-function-type',

    # Deliberately not warning about these, ability to zero-initialize
    # a struct is a feature
    '-Wno-missing-field-initializers',
    '-Wno-error=missing-field-initializers',

    # Deliberately not warning about these
    '-Wno-unused-parameter',
    '-Wno-error=unused-parameter',
  ]),
  language : 'c',
)
# Flatpak is Linux-specific, so for now we assume that -fvisibility=hidden
# is always supported
add_project_arguments('-fvisibility=hidden', language : 'c')

if (
  cc.has_argument('-Werror=format=2')
  and cc.has_argument('-Werror=format-security')
  and cc.has_argument('-Werror=format-nonliteral')
)
  add_project_arguments([
    '-Werror=format=2',
    '-Werror=format-security',
    '-Werror=format-nonliteral',
  ], language : 'c')
endif

dbus_config_dir = get_option('dbus_config_dir')
if dbus_config_dir == ''
  dbus_config_dir = get_option('datadir') / 'dbus-1' / 'system.d'
endif

dbus_service_dir = get_option('dbus_service_dir')
if dbus_service_dir == ''
  dbus_service_dir = get_option('datadir') / 'dbus-1' / 'services'
endif

profile_dir = get_option('profile_dir')
if profile_dir == ''
  profile_dir = get_option('sysconfdir') / 'profile.d'
endif

system_install_dir = get_option('system_install_dir')
if system_install_dir == ''
  system_install_dir = get_option('localstatedir') / 'lib' / 'flatpak'
endif

docdir = get_option('docdir')
if docdir == ''
  docdir = get_option('datadir') / 'doc' / 'flatpak'
endif

if not cc.check_header('sys/xattr.h')
  error('You must have sys/xattr.h from glibc')
endif

libglnx = subproject(
  'libglnx',
  default_options : [
    'warning_level=1',
    'tests=false',
  ],
)

not_found = dependency('', required : false)
threads_dep = dependency('threads')
bison = find_program('bison')
libcap_dep = dependency('libcap')
libglnx_dep = libglnx.get_variable('libglnx_dep')
libglnx_testlib_dep = libglnx.get_variable('libglnx_testlib_dep')
libarchive_dep = dependency('libarchive', version : '>=2.8.0')
glib_dep = dependency('glib-2.0', version : '>=' + required_glib)
gio_dep = dependency('gio-2.0', version : '>=' + required_glib)
gio_unix_dep = dependency('gio-unix-2.0', version : '>=' + required_glib)
libcurl_dep = dependency('libcurl', version : '>=7.29.0')
libxml_dep = dependency('libxml-2.0', version : '>=2.4')
libzstd_dep = dependency('libzstd', version : '>=0.8.1', required : get_option('libzstd'))
dconf_dep = dependency('dconf', version : '>=0.26', required : get_option('dconf'))
libsystemd_dep = dependency('libsystemd', required : get_option('systemd'))
malcontent_dep = dependency('malcontent-0', version : '>=0.5.0', required : get_option('malcontent'))
polkit_agent_dep = dependency('polkit-agent-1', version : '>=0.98', required : get_option('system_helper'))
build_system_helper = polkit_agent_dep.found()

fuse_dep = dependency('fuse3', version : '>=3.1.1', required : false)
if fuse_dep.found()
  fuse_api = 31
else
  fuse_dep = dependency('fuse', version : '>=2.9.2')
  fuse_api = 26
endif

fusermount = get_option('system_fusermount')
if fusermount == ''
  if fuse_api >= 30
    fusermount_program = find_program('fusermount3', required: true)
  else
    fusermount_program = find_program('fusermount', required: true)
  endif
  if meson.version().version_compare('>=0.55')
    fusermount = fusermount_program.full_path()
  else
    fusermount = fusermount_program.path()
  endif
endif

xau_dep = dependency('xau', required : get_option('xauth'))
libostree_dep = dependency('ostree-1', version : '>=' + required_libostree)
json_glib_dep = dependency('json-glib-1.0')
appstream_dep = dependency('appstream', version : '>=0.12.0')
gdk_pixbuf_dep = dependency('gdk-pixbuf-2.0')
libseccomp_dep = dependency('libseccomp', required : get_option('seccomp'))
gir_dep = dependency('gobject-introspection-1.0', version : '>=1.40.0', required : get_option('gir'))
gtkdoc_dep = dependency('gtk-doc', required : get_option('gtkdoc'), native : true)
build_gtk_doc = gtkdoc_dep.found()

wayland_client = dependency('wayland-client', required : get_option('wayland_security_context'))
wayland_scanner = dependency('wayland-scanner', version : '>= 1.15', required : get_option('wayland_security_context'), native : true)
wayland_protocols = dependency('wayland-protocols', version : '>= 1.32', required : get_option('wayland_security_context'))
build_wayland_security_context = wayland_client.found() and wayland_scanner.found() and wayland_protocols.found()

base_deps = [glib_dep, gio_dep, gio_unix_dep]

gpgme_dep = dependency('gpgme', version : '>=1.8.0')

if get_option('selinux_module').disabled()
  build_selinux_module = false
else
  build_selinux_module = fs.is_file('/usr/share/selinux/devel/Makefile')

  if get_option('selinux_module').enabled() and not build_selinux_module
    error('selinux-policy-devel needed to build selinux module')
  endif
endif

manpages_xsl = 'http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl'
xsltproc = find_program('xsltproc', required : get_option('man'))
build_man_pages = false

if xsltproc.found()
  if run_command([
    xsltproc, '--nonet', manpages_xsl,
  ], check : false).returncode() == 0
    message('Docbook XSL found')
    build_man_pages = true
  elif get_option('man').enabled()
    error('Man page requested, but Docbook XSL stylesheets not found')
  else
    message('Docbook XSL not found, man page disabled automatically')
  endif
endif

xmlto = find_program('xmlto', required : get_option('docbook_docs'))

if run_command(
  'python3', '-c', 'import pyparsing',
  check : false
).returncode() != 0
  error('python3 "pyparsing" module is required')
endif

foreach system_executable : [
  ['bubblewrap', required_bwrap, 'system_bubblewrap'],
  ['xdg-dbus-proxy', required_dbus_proxy, 'system_dbus_proxy'],
]
  name = system_executable[0]
  required = system_executable[1]
  option_name = system_executable[2]
  value = get_option(option_name)

  if value != ''
    version = ''

    if can_run_host_binaries
      result = run_command(
        value, '--version',
        capture : true,
        check : true,
      )
      output = result.stdout()

      if output.startswith(name + ' ')
        version = output.split()[1]
      endif
    endif

    if version == ''
      # Cross-compiling, or unable to parse --version output
      warning(
        'Unable to determine version of @0@ (@1@), please ensure it is >= @2@'.format(
          name, value, required,
        )
      )
    elif version.version_compare('<' + required)
      error(
        '@0@ must be version >= @1@ (found: @2@)'.format(
          option_name, required, version,
        )
      )
    endif
  endif
endforeach

# We don't actually need this, but we do need the polkit daemon itself,
# and they're generally packaged together.
find_program('pkcheck', required : get_option('tests'))

find_program('socat', required : get_option('tests'))

if get_option('installed_tests') and not get_option('tests')
  error('-Dinstalled_tests=true is incompatible with -Dtests=false')
endif

cdata = configuration_data()
cdata.set('_GNU_SOURCE', 1)
cdata.set('FLATPAK_COMPILATION', 1)
cdata.set('PACKAGE_MAJOR_VERSION', flatpak_major_version)
cdata.set('PACKAGE_MINOR_VERSION', flatpak_minor_version)
cdata.set('PACKAGE_MICRO_VERSION', flatpak_micro_version)
cdata.set('PACKAGE_EXTRA_VERSION', flatpak_extra_version)
cdata.set_quoted(
  'PACKAGE_STRING',
  'Flatpak @0@'.format(meson.project_version()),
)
cdata.set_quoted('PACKAGE_VERSION', meson.project_version())
cdata.set_quoted(
  'FLATPAK_BINDIR',
  get_option('prefix') / get_option('bindir'),
)
cdata.set_quoted(
  'FLATPAK_SYSTEMDIR',
  get_option('prefix') / system_install_dir,
)
cdata.set_quoted(
  'FLATPAK_CONFIGDIR',
  get_option('prefix') / get_option('sysconfdir') / 'flatpak',
)
cdata.set_quoted(
  'FLATPAK_DATADIR',
  get_option('prefix') / get_option('datadir') / 'flatpak',
)
cdata.set_quoted('LIBEXECDIR', get_option('prefix') / get_option('libexecdir'))
cdata.set_quoted('DATADIR', get_option('prefix') / get_option('datadir'))
cdata.set_quoted('LOCALEDIR', get_option('prefix') / get_option('localedir'))
cdata.set_quoted('SYSTEM_FONTS_DIR', get_option('system_fonts_dir'))
cdata.set_quoted('SYSTEM_HELPER_USER', get_option('system_helper_user'))
cdata.set_quoted(
  'SYSTEM_FONT_CACHE_DIRS',
  ':'.join(get_option('system_font_cache_dirs')),
)
cdata.set_quoted('G_LOG_DOMAIN', 'flatpak')
cdata.set_quoted('GETTEXT_PACKAGE', 'flatpak')
cdata.set('FUSE_USE_VERSION', fuse_api)
cdata.set_quoted('FUSERMOUNT', fusermount)

if get_option('internal_tests')
  cdata.set('INCLUDE_INTERNAL_TESTS', 1)
endif

if get_option('system_bubblewrap') == ''
  cdata.set_quoted('HELPER', get_option('prefix') / get_option('libexecdir') / 'flatpak-bwrap')
else
  cdata.set_quoted('HELPER', get_option('system_bubblewrap'))
endif

if get_option('system_dbus_proxy') == ''
  cdata.set_quoted('DBUSPROXY', get_option('prefix') / get_option('libexecdir') / 'flatpak-dbus-proxy')
else
  cdata.set_quoted('DBUSPROXY', get_option('system_dbus_proxy'))
endif

# Flatpak is Linux-specific, so we assume this is always supported
cdata.set('FLATPAK_EXTERN', '__attribute__((visibility("default"))) extern')

if glib_dep.version().version_compare('>=2.60')
  # Ignore massive GTimeVal deprecation warnings in 2.62
  cdata.set('GLIB_VERSION_MIN_REQUIRED', 'GLIB_VERSION_2_60')
endif

if dconf_dep.found()
  cdata.set('HAVE_DCONF', 1)
endif

if libseccomp_dep.found()
  cdata.set('ENABLE_SECCOMP', 1)
endif

if libsystemd_dep.found()
  cdata.set('HAVE_LIBSYSTEMD', 1)
endif

if libzstd_dep.found()
  cdata.set('HAVE_ZSTD', 1)
endif

if malcontent_dep.found()
  cdata.set('HAVE_LIBMALCONTENT', 1)
endif

if xau_dep.found()
  cdata.set('ENABLE_XAUTH', 1)
endif

if build_wayland_security_context
  cdata.set('ENABLE_WAYLAND_SECURITY_CONTEXT', 1)
endif

if not get_option('sandboxed_triggers')
  cdata.set('DISABLE_SANDBOXED_TRIGGERS', 1)
endif

if cc.has_function(
  'archive_read_support_filter_all',
  dependencies : libarchive_dep,
  prefix : '#include <archive.h>',
)
  cdata.set('HAVE_ARCHIVE_READ_SUPPORT_FILTER_ALL', 1)
endif

if build_system_helper
  cdata.set('USE_SYSTEM_HELPER', '1')
endif

configure_file(
  output : 'config.h',
  configuration : cdata,
)

# TODO: When we depend on Meson >= 0.57.0, we can print dependencies
# as themselves rather than as booleans if we want to.
summary(
  {
    'Build system helper' : build_system_helper,
    'Build selinux module' : build_selinux_module,
    'Build bubblewrap' : (get_option('system_bubblewrap') == ''),
    'Build dbus-proxy' : (get_option('system_dbus_proxy') == ''),
    'fusermount executable' : fusermount,
    'Use sandboxed triggers' : get_option('sandboxed_triggers'),
    'Use seccomp' : libseccomp_dep.found(),
    'Privileged group' : get_option('privileged_group'),
    'Use dconf' : dconf_dep.found(),
    'Use libsystemd' : libsystemd_dep.found(),
    'Use libmalcontent' : malcontent_dep.found(),
    'Use libzstd' : libzstd_dep.found(),
    'Use auto sideloading' : get_option('auto_sideloading'),
    'Wayland security context' : build_wayland_security_context,
  },
  bool_yn : true,
)

if get_option('system_bubblewrap') == ''
  subproject(
    'bubblewrap',
    default_options : [
      'program_prefix=flatpak-',
      'tests=false',
    ],
  )
endif

if get_option('system_dbus_proxy') == ''
  subproject(
    'dbus-proxy',
    default_options : [
      'warning_level=1',
      'program_prefix=flatpak-',
      'tests=false',
    ],
  )
endif

# Used for .service files in multiple subdirectories
service_conf_data = configuration_data()
service_conf_data.set('libexecdir', get_option('prefix') / get_option('libexecdir'))
service_conf_data.set('localstatedir', get_option('prefix') / get_option('localstatedir'))
service_conf_data.set('media_dir', get_option('prefix') / get_option('run_media_dir'))
service_conf_data.set('extraargs', '')

subdir('common')
subdir('data')

subdir('app')
subdir('env.d')
subdir('profile')
subdir('icon-validator')
subdir('oci-authenticator')
subdir('portal')
subdir('revokefs')
subdir('session-helper')
subdir('scripts')

subdir('completion')
subdir('doc')
subdir('po')
subdir('triggers')

if get_option('auto_sideloading')
  subdir('sideload-repos-systemd')
endif

if build_selinux_module
  subdir('selinux')
endif

if build_system_helper
  subdir('system-helper')
endif

if get_option('tests')
  subdir('tests')
endif

pkgconfig_variables = []

# TODO: These can be dropped when we require Meson >= 0.62.0
pkgconfig_variables += 'exec_prefix=${prefix}'
pkgconfig_variables += 'datadir=' + ('${prefix}' / get_option('datadir'))

pkgconfig_variables += 'datarootdir=' + ('${prefix}' / get_option('datadir'))
pkgconfig_variables += 'interfaces_dir=${datadir}/dbus-1/interfaces/'

pkgconfig.generate(
  libflatpak,
  description : 'Application sandboxing framework',
  subdirs : 'flatpak',
  requires : [
    'glib-2.0',
    'gio-2.0',
    'ostree-1',
  ],
  requires_private : [
    'gio-unix-2.0',
  ],
  variables : pkgconfig_variables,
)

===== ./.devcontainer/devcontainer.json =====
{
  "name": "Ubuntu",
  "image": "mcr.microsoft.com/devcontainers/base:jammy",
  "features": {
    "ghcr.io/rocker-org/devcontainer-features/apt-packages:1": {
      "packages": "policykit-1,libappstream-dev,bison,meson,attr,autopoint,bubblewrap,debhelper,desktop-file-utils,dh-autoreconf,dh-exec,dh-strip-nondeterminism,docbook,docbook-to-man,docbook-xml,docbook-xsl,dwz,fuse,gir1.2-appstreamglib-1.0,gir1.2-freedesktop,gir1.2-gcab-1.0,gir1.2-gdkpixbuf-2.0,gir1.2-json-1.0,gir1.2-ostree-1.0,gir1.2-polkit-1.0,gobject-introspection,gtk-doc-tools,intltool-debian,libappstream-glib-dev,libappstream-glib8,libarchive-dev,libarchive-zip-perl,libassuan-dev,libattr1-dev,libavahi-glib1,libbrotli-dev,libcap-dev,libdconf-dev,libdebhelper-perl,libdw-dev,libelf-dev,libfile-stripnondeterminism-perl,libfuse-dev,libfuse2,libgcab-1.0-0,libgcab-dev,libgdk-pixbuf2.0-bin,libgdk-pixbuf2.0-dev,libgirepository1.0-dev,libglib2.0-doc,libgpgme-dev,libgpgme11,libjson-glib-dev,libosp5,libostree-1-1,libostree-dev,libostree-doc,libpolkit-agent-1-dev,libpolkit-gobject-1-dev,libpsl-dev,libseccomp-dev,libsub-override-perl,libsystemd-dev,libxml2-utils,opensp,ostree,po-debconf,python3-lxml,python3-mako,python3-markdown,python3-markupsafe,python3-packaging,python3-pyparsing,sgml-base,sgml-data,socat,xdg-dbus-proxy,xml-core,xmlto,xsltproc"
    }
  },
  "runArgs": ["--privileged"]
}
===== ./flatpak.png =====
PNG

   IHDR         \rf   	pHYs    e   tEXtSoftware www.inkscape.org<   RtEXtCopyright CC Attribution-ShareAlike http://creativecommons.org/licenses/by-sa/4.0/Tb  PIDATxypeONI'}pF	W Ɋ;8Z
:#x&{T[[l֮5[53HQ->4
)GttX~^Z!>{("ɬ H; ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `V@*1c Ɠp"CoJ 3IPYjt7NhnAE:xI]؀fn31ڻƮ #Ĉ P{3?p?VoH$+G xevd"+6vP{"Oc 8߂{f{JalIXǹOF$`MX4KxఫsEdT91w|<7wџߐ\w 9jZE!Pi:xqk'6s~ '1 9fˆk}5֡PLs[Vn3P
0 9a7j7nբ%Si|?@.~~psI	7_[yWA|e\>o|cSFއ^CH[0ocOKTE0 :+/T9JV<Ŋhz(t~Մn,væ5ց+`.-87	UN<0C&	V`4՛p0 hh/5yEЊ[](ˊЈa94sհ1N.Q|I1 l9M~#	埐2ńESJq\
Uk{)ev4֗ar2KΞ DˊU h80$;tB4{We(+VgH/o`݁*G*Fmx·Z\: [Yne +Pt3}-b</nrrŀێ (b6XVㅳ@w/7 Ծj "ȲiPC'7^i  m'
B;sYq61 YR^jòO(z(W$ *3.,v#Oͭ=X-qU! Aj/JcW]xe{ \ڦ{) ?Dv<D@^M Q+7v`ߩ^UH+05d; xSΆr1 A0jQ* ^O+^n;^Xj}0hUEx֗}@wt_
pÂa;H(J  lu"_;n6c͒Ix1W["ƚ_:*2sU#rV	y/1JKxsY0ӟ7ZU9Y`Swf/)
Ϸ0y|zvъ֞Q@ՄY8+
}\ |cÓj\H	 V	O,,hS WuqBT)5cAqxupL7*$#OsRAX\Rs 8,s_z,|ڮȁ K9#[`3tXw Agq~ ?όۧ3_yYEc)Zz[Nj8좿9-Ǔ¿w2+-/~saHnjn`UD*LCWOVL<3F2[iI5l%h'}֌xvtzqexIlaz_r=k[v#KaǱ(Tptd=v_%CܸU/ d'v;-|?|9F2F·1>]$6 'CqSVQ2Tp"Kƛ3}- (_mX:5YgƝ3\X\V,c ,8fow& q^
RU
%bc@0ydC)磱Gy)Pю9X_کSd1 *q,/ZOP٬&~o4 (HAl8_#0 8/ϡUBףX-1 :އzULӱ4Nu7jaO&M\#3NNl8VdָJR 9}O=iH׻keˆk}9$Щ<zkvnN X2n3ۃESK`,r>0ï:uxB406?H 䐓8~fs2(_xʩP
1 9hǱ(8ESKq\f46 mMG"X:ǃ&		x_1_B?&ug.40\e壱އkFp0 uG&Z/ʊ;?vXUAc $`vj7pfob¢)\
4k 0 KN|ˆt07ێ?ׅ2]n|R({ ţ|
=nӕ"vX7vo[&$'x̱=440Xf4uepDPw3
iuc c c c c c c c c c c c c c c c c c c c c c c c T*𮙆k'OfF74h<4#6 ݱ5Weq$Hܷ b$Jg?Fq>A*"ZC3b۟P<-+/o	_1oڂ1%0  C}1zN檡@t v3{+1BqFEjuCД idRX8}$FmY!җDskД $i|+k7ҁ.YIB[U  {Be ل-i..ҩ4 җۻY|}x:0OC z. $>  Uf6x׎_x$)tecxg7   JO)"lXWEAZ%_hsI^6	wtc18=D*><0#b c3+2b]zxEb43hn}|yﶩ2At|<}wi8.+Vʹ$68&{υ0 pLت*1UNpX,きˊj׉(ւ^i᳇8r	uP"uBcU_%|*ϣ@wtxh˽v	Ns'ܪ=ك8)<F@<Cî z3<E
x7T9tp(UM~QfNHy<gr_) 磱U*Gc);5_~8a;իPr!i`>T(y< Dx}G|t'!3.,v#OԁΡ/h $Ril(zS KKmXVQ`lZ ?b nB4P鱫|C}+8M~b a1IN,v01+2{ '@"4b To==X4DAR^%Pb T1eCC3*<_"ڽ]xi[{1 j-"@U9PW hn'ׅE~z
?Xw P` TfhJ)AMeŇaF?= H=A+8?竊Јa94YA &?ķ] \lL@cWXAz)yB0, bc;hx`WՃAф	a=@GVWmA!oTvǣX]ܦ7MUzzYVmm8Vn.+@v<Tܦ;xΥal?֍ݸmKmW*Ja50o ǌtpƪrlws	U8}.vbf5hj)aW)yo
*z;5R` ێt])um 8evd" Pb<0ߋal;>4s25`n,Ɖ%nfxkw}C; 3 'az\ۢh:܍gza ӽ 3c"$h팣u$a Oqc"H0H0H0H0H0H0H0H0H0H0H0H0H0H0H0H0H0H0H0H0H0H0H0H0H0H0H0H0H0H0H0H0H0H0H0H0H0H0H0H0H0H0H0H0H0H0H0H0H0H0H0H0H<nS}n    IENDB`
===== ./.github/workflows/release.yml =====
name: Release new version

on:
  push:
    tags:
      - '[0-9]+.[0-9]+.[0-9]+'

jobs:
  release:
    name: Build and publish a release
    runs-on: ubuntu-latest
    permissions:
      contents: write
    steps:
      - name: Install Dependencies
        run: |
          head -v -n-0 /etc/apt/sources.list || :
          head -v -n-0 /etc/apt/sources.list.d/* || :
          # Workaround for https://github.com/orgs/community/discussions/120966
          sudo rm -f /etc/apt/sources.list.d/microsoft-prod.list
          # Workaround for apparmor breaking bwrap by disabling unpriv userns
          sudo sysctl -w kernel.apparmor_restrict_unprivileged_userns=0
          sudo systemctl reload apparmor
          # Dependencies
          sudo apt-get update
          sudo apt-get install -y libglib2.0-dev attr gettext bison  dbus gtk-doc-tools \
          libfuse3-dev ostree libostree-dev libarchive-dev libzstd-dev libcap-dev libattr1-dev libdw-dev libelf-dev python3-pyparsing \
          libjson-glib-dev shared-mime-info desktop-file-utils libpolkit-agent-1-dev libpolkit-gobject-1-dev \
          libseccomp-dev libcurl4-openssl-dev libsystemd-dev libxml2-utils libgpgme11-dev gobject-introspection \
          libgirepository1.0-dev libappstream-dev libdconf-dev clang socat meson libdbus-1-dev e2fslibs-dev bubblewrap xdg-dbus-proxy \
          meson ninja-build libyaml-dev libstemmer-dev gperf itstool libmalcontent-0-dev libxau-dev libgdk-pixbuf2.0-dev openssl
          # One of the tests wants this
          sudo mkdir /tmp/flatpak-com.example.App-OwnedByRoot

      - name: Checkout the repository
        uses: actions/checkout@v4

      - name: Build flatpak
        run: |
          meson setup _build
          meson dist -C _build

      - name: Extract release information
        run: |
          # Extract the release version
          releaseVersion=`meson introspect --projectinfo _build/ | jq -r .version`
          echo "releaseVersion=$releaseVersion" | tee -a $GITHUB_ENV
          echo $releaseVersion

          # Extract the changelog
          {
            echo "releaseChangelog<<EOF"
            perl -0777nE 'print $& if /(?<=\n\n).*?(?=\nChanges in)/sg' NEWS
            echo ""
            echo "EOF"
          } | tee -a $GITHUB_ENV
          echo $releaseChangelog

          # Check if version is a pre-release
          preRelease=$((`echo $releaseVersion | cut -d '.' -f2` % 2))
          {
            echo -n "preRelease="
            if [ $preRelease = 1 ] || [ $preRelease = "true" ]; then
              echo "true";
            else
              echo "false";
            fi
          } | tee -a $GITHUB_ENV
          echo $preRelease

      - name: Create release
        uses: ncipollo/release-action@v1.20.0
        with:
          tag: ${{ env.releaseVersion }}
          body: ${{ env.releaseChangelog }}
          prerelease: ${{ env.preRelease }}
          artifacts: _build/meson-dist/*
          immutableCreate: true
===== ./.github/workflows/check.yml =====
name: Flatpak CI

on:
  push:
    branches:
    - main
    - 'flatpak-1.[0-9]+.x'
  pull_request:
    branches:
    - main
    - 'flatpak-1.[0-9]+.x'
  merge_group:
    types:
    - checks_requested

permissions:
  contents: read

jobs:
  check:
    name: Build with gcc and test
    runs-on: ubuntu-24.04
    steps:
    - name: Install Dependencies
      run: |
        head -v -n-0 /etc/apt/sources.list || :
        head -v -n-0 /etc/apt/sources.list.d/* || :
        # Workaround for https://github.com/orgs/community/discussions/120966
        sudo rm -f /etc/apt/sources.list.d/microsoft-prod.list
        # Workaround for apparmor breaking bwrap by disabling unpriv userns
        sudo sysctl -w kernel.apparmor_restrict_unprivileged_userns=0
        sudo systemctl reload apparmor
        # Dependencies
        sudo apt-get update
        sudo apt-get install -y libglib2.0-dev attr gettext bison  dbus gtk-doc-tools \
        libfuse3-dev ostree libostree-dev libarchive-dev libzstd-dev libcap-dev libattr1-dev libdw-dev libelf-dev python3-pyparsing \
        libjson-glib-dev shared-mime-info desktop-file-utils libpolkit-agent-1-dev libpolkit-gobject-1-dev \
        libseccomp-dev libcurl4-openssl-dev libsystemd-dev libxml2-utils libgpgme11-dev gobject-introspection \
        libgirepository1.0-dev libappstream-dev libdconf-dev clang socat meson libdbus-1-dev e2fslibs-dev bubblewrap xdg-dbus-proxy \
        meson ninja-build libyaml-dev libstemmer-dev gperf itstool libmalcontent-0-dev libxau-dev libgdk-pixbuf2.0-dev openssl libc6-dev
        # One of the tests wants this
        sudo mkdir /tmp/flatpak-com.example.App-OwnedByRoot
    - name: Check out flatpak
      uses: actions/checkout@v4
      with:
        submodules: true
    - name: Create logs dir
      run: mkdir test-logs
    - name: configure
      # We don't do gtk-doc or GObject-Introspection here, because they can
      # clash with AddressSanitizer. Instead, the clang build enables those.
      run: |
        meson setup \
          -Db_sanitize=address,undefined \
          -Dgir=disabled \
          -Dgtkdoc=disabled \
          -Dinternal_checks=true \
          -Dinternal_tests=true \
          -Dsystem_dbus_proxy=xdg-dbus-proxy \
          _build
      env:
        CFLAGS: -O2 -Wp,-D_FORTIFY_SOURCE=2
    - name: Build flatpak
      run: meson compile -C _build
      env:
        ASAN_OPTIONS: detect_leaks=0 # Right now we're not fully clean, but this gets us use-after-free etc
    - name: Run tests
      run: meson test -C _build
      env:
        ASAN_OPTIONS: detect_leaks=0 # Right now we're not fully clean, but this gets us use-after-free etc
        LC_ALL: en_US.UTF-8
    - name: Collect logs on failure
      if: failure() || cancelled()
      run: mv _build/meson-logs/* test-logs/ || true
    - name: Upload test logs
      uses: actions/upload-artifact@v4
      if: failure() || cancelled()
      with:
        name: test logs
        path: test-logs

  # This is similar to the above, but runs on an older OS with some different configuration:
  # * Soup instead of curl
  # * Use built in bubblewrap instead of external
  # * Use built in xdg-dbus-proxy instead of external
  # * Disable malcontent build-dependency
  check-alt2:
    name: Build with gcc and test (older)
    runs-on: ubuntu-22.04
    steps:
    - name: Install Dependencies
      run: |
        sudo add-apt-repository ppa:flatpak/stable
        sudo apt-get update
        sudo apt-get install -y libglib2.0-dev attr gettext bison dbus gtk-doc-tools \
        libfuse-dev ostree libostree-dev libarchive-dev libzstd-dev libcap-dev libattr1-dev libdw-dev libelf-dev python3-pyparsing \
        libjson-glib-dev shared-mime-info desktop-file-utils libpolkit-agent-1-dev libpolkit-gobject-1-dev \
        libseccomp-dev libcurl4-openssl-dev libsystemd-dev libxml2-utils libgpgme11-dev gobject-introspection \
        libgirepository1.0-dev libappstream-dev libdconf-dev clang socat meson libdbus-1-dev e2fslibs-dev libc6-dev
        # One of the tests wants this
        sudo mkdir /tmp/flatpak-com.example.App-OwnedByRoot
    - name: Check out flatpak
      uses: actions/checkout@v4
      with:
        submodules: true
    - name: Create logs dir
      run: mkdir test-logs
    - name: Configure
      # Sometimes the older sanitizer toolchains will trigger issues that are either
      # false positive or that have been already against in newer versions, so we don't
      # enable them here.
      run: |
        meson setup \
          -Dgir=disabled \
          -Dgtkdoc=disabled \
          -Dinternal_checks=true \
          -Dinternal_tests=true \
          _build
      env:
        CFLAGS: -O2 -Wp,-D_FORTIFY_SOURCE=2
    - name: Build flatpak
      # Can't use `meson compile` here because Ubuntu 20.04 is too old
      run: ninja -C _build
    - name: Run tests
      run: meson test -C _build
      env:
        LC_ALL: en_US.UTF-8
    - name: Collect overall test logs on failure
      if: failure()
      run: mv _build/test-suite.log test-logs/ || true
    - name: Collect individual test logs on cancel
      if: failure() || cancelled()
      run: mv _build/meson-logs/* test-logs/ || true
    - name: Upload test logs
      uses: actions/upload-artifact@v4
      if: failure() || cancelled()
      with:
        name: test logs
        path: test-logs

  clang:
    permissions:
      security-events: write # for codeql
    name: Build with clang and analyze
    runs-on: ubuntu-24.04
    strategy:
      fail-fast: false
      matrix:
        language: [ 'cpp', 'python' ]
        # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ]
        # Learn more:
        # https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed
    steps:
    # Initializes the CodeQL tools for scanning.
    - name: Initialize CodeQL
      uses: github/codeql-action/init@v3
      with:
        languages: ${{ matrix.language }}
        # If you wish to specify custom queries, you can do so here or in a config file.
        # By default, queries listed here will override any specified in a config file.
        # Prefix the list here with "+" to use these queries and those in the config file.
        # queries: ./path/to/local/query, your-org/your-repo/queries@main
    - name: Install Dependencies
      run: |
        sudo add-apt-repository ppa:flatpak/stable
        sudo apt-get update
        sudo apt-get install -y libglib2.0-dev attr gettext bison dbus gtk-doc-tools \
        libfuse-dev ostree libostree-dev libarchive-dev libzstd-dev libcap-dev libattr1-dev libdw-dev libelf-dev python3-pyparsing \
        libjson-glib-dev shared-mime-info desktop-file-utils libpolkit-agent-1-dev libpolkit-gobject-1-dev \
        libseccomp-dev libcurl4-openssl-dev libsystemd-dev libxml2-utils libgpgme11-dev gobject-introspection \
        libgirepository1.0-dev libappstream-dev libdconf-dev clang e2fslibs-dev meson socat libxau-dev libgdk-pixbuf2.0-dev \
        xmlto libc6-dev
    - name: Check out flatpak
      uses: actions/checkout@v4
      with:
        submodules: true
    - name: Configure
      run: |
        meson setup \
          -Dgir=enabled \
          -Dgtkdoc=enabled \
          _build
      env:
        CC: clang
        CFLAGS: -Werror=unused-variable
    - name: Build flatpak
      # Can't use `meson compile` here because Ubuntu 20.04 is too old
      run: ninja -C _build
    - name: Perform CodeQL Analysis
      uses: github/codeql-action/analyze@v3
    - name: Upload docs
      uses: actions/upload-artifact@v4
      with:
        if-no-files-found: error
        overwrite: true
        name: docs
        path: |
          _build/doc/

  valgrind:
    name: Run tests in valgrind
    needs: check # Don't run expensive test if main check fails
    runs-on: ubuntu-24.04 # Might as well test with a different one too
    if: ${{ false }} # Currently Valgrind takes too long and always fails
    steps:
    - name: Install Dependencies
      run: |
        sudo add-apt-repository ppa:flatpak/stable
        sudo apt-get update
        sudo apt-get install -y libglib2.0-dev attr gettext bison dbus gtk-doc-tools \
        libfuse-dev ostree libostree-dev libarchive-dev libzstd-dev libcap-dev libattr1-dev libdw-dev libelf-dev python3-pyparsing \
        libjson-glib-dev shared-mime-info desktop-file-utils libpolkit-agent-1-dev libpolkit-gobject-1-dev \
        libseccomp-dev libcurl4-openssl-dev libsystemd-dev libxml2-utils libgpgme11-dev gobject-introspection \
        libgirepository1.0-dev libappstream-dev libdconf-dev clang socat meson libdbus-1-dev \
        valgrind e2fslibs-dev meson libxau-dev libgdk-pixbuf2.0-dev libc6-dev
    - name: Check out flatpak
      uses: actions/checkout@v4
      with:
        submodules: true
    - name: Create logs dir
      run: mkdir test-logs
    - name: Configure
      run: |
        meson setup \
          -Dgir=enabled \
          -Dgtkdoc=enabled \
          _build
      env:
        CFLAGS: -O2
    - name: Build flatpak
      run: meson compile -C _build
    - name: Run tests under valgrind
      run: meson test -C _build
      env:
        FLATPAK_TESTS_VALGRIND: true
    - name: Collect overall test logs on failure
      if: failure()
      run: mv _build/meson-logs/* test-logs/ || true
    - name: Collect individual test logs on cancel
      if: failure() || cancelled()
      run: mv _build/tests/*.log test-logs/ || true
    - name: Upload test logs
      uses: actions/upload-artifact@v4
      if: failure() || cancelled()
      with:
        name: test logs
        path: test-logs

  # This is a workaround to CodeQL not reporting status to the
  # merge queue.
  check_codeql_status:
    name: Check CodeQL Status
    needs: clang
    permissions:
      contents: read
      checks: read
      pull-requests: read
    runs-on: ubuntu-latest
    if: ${{ github.event_name == 'pull_request' }}
    steps:
    - name: Check CodeQL Status
      uses: eldrick19/code-scanning-status-checker@v2
      with:
        token: ${{ secrets.GITHUB_TOKEN }}
        pr_number: ${{ github.event.pull_request.number }}
        repo: ${{ github.repository }}

===== ./.github/workflows/check-potfiles.sh =====
#!/usr/bin/env bash

# FIXME stolen from gnome-control-center, GPLv2
# This project is LGPLv2
# https://gitlab.gnome.org/GNOME/gnome-control-center/-/merge_requests/2269#note_2079291

srcdirs=(app common oci-authenticator portal system-helper)
uidirs=( "${srcdirs[@]}" )
desktopdirs=( "${srcdirs[@]}" )
policydirs=( "${srcdirs[@]}" )
xmldirs=( "${srcdirs[@]}" )

# find source files that contain gettext functions with literal or GETTEXT_PACKAGE argument
files=$(grep -lRs --include='*.c' 'gettext *(\("\|GETTEXT_PACKAGE,\)' "${srcdirs[@]}")

# find source files that contain gettext macros
files="$files "$(grep -lRs --include='*.c' --include='*.h' '[^I_)]_(' "${srcdirs[@]}")

# find ui files that contain translatable string
files="$files "$(grep -lRis --include='*.ui' 'translatable="[ty1]' "${uidirs[@]}")

# find .desktop files
files="$files "$(find "${desktopdirs[@]}" -name '*.desktop*')

# find .policy files
files="$files "$(find "${policydirs[@]}" -name '*.policy*')

# find .xml.in and .gschema.xml files
files="$files "$(find "${xmldirs[@]}" -not -name '*.gresource.xml*' \
                               -name '*.xml.in*' -o \
                               -name '*.gschema.xml')

# filter out excluded files
if [ -f po/POTFILES.skip ]; then
  files=$(for f in $files; do
            ! grep -q "^$f" po/POTFILES.skip && echo "$f"
          done)
fi

# find those that aren't listed in POTFILES.in
missing=$(for f in $files; do
            ! grep -q "^$f" po/POTFILES.in && echo "$f"
          done)

# find those that are listed in POTFILES.in but do not contain translatable strings
invalid=$(while IFS= read -r f; do
            ! grep -q "$f" <<< "$files" && echo "$f"
          done < <(grep '^[^#]' po/POTFILES.in))

# find out if POTFILES.in is sorted correctly, ignoring empty lines
sorted=$(grep '^[^#]' po/POTFILES.in | \
         LC_ALL=en_US.UTF-8 sort -cu 2>&1 >/dev/null | \
         awk -F ': *' '{print $5}')

if [ ${#missing} -eq 0 ] && [ ${#invalid} -eq 0 ] && [ ${#sorted} -eq 0 ]; then
  exit 0
fi

if [ ${#missing} -ne 0 ]; then
  cat >&2 << EOT

The following files are missing from po/POTFILES.in or po/POTFILES.skip:

EOT
  for f in $missing; do
    echo "  $f" >&2
  done
fi

if [ ${#invalid} -ne 0 ]; then
  cat >&2 << EOT

The following files are in po/POTFILES.in but are missing or not translatable:

EOT
  for f in $invalid; do
    echo "  $f" >&2
  done
fi

if [ ${#sorted} -ne 0 ]; then
  cat >&2 << EOT

The following file is not sorted properly in po/POTFILES.in:

EOT
  echo "  $sorted" >&2
fi

echo >&2

exit 1

===== ./.github/workflows/block-autosquash-commits.yml =====
on:
  pull_request:
  merge_group:
    types:
    - checks_requested

name: Pull Requests

jobs:
  message-check:
    name: Block Autosquash Commits

    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v4

      - name: Determine PR number
        run: |
          if [[ "${{ github.event_name }}" == "merge_group" ]]; then
            echo "Running in merge_group context"
            echo "Branch ref: $GITHUB_REF_NAME"
            PR_NUMBER=$(echo "$GITHUB_REF_NAME" | grep -oP 'pr-\K[0-9]+')
          elif [[ "${{ github.event_name }}" == "pull_request" ]]; then
            echo "Running in pull_request context"
            PR_NUMBER="${{ github.event.pull_request.number }}"
          else
            echo "Unsupported event: ${{ github.event_name }}"
            exit 1
          fi

          echo "Resolved PR Number: $PR_NUMBER"
          echo "PR_NUMBER=$PR_NUMBER" >> "$GITHUB_ENV"

      - name: Check for fixup/squash commits in PR ${{ env.PR_NUMBER }}
        env:
          GH_TOKEN: ${{ github.token }}
        run: |
          gh pr view "$PR_NUMBER" --json commits --jq '.commits[].messageHeadline' | \
          grep -E '^(fixup!|squash!)' && \
          { echo "❌ Found fixup!/squash! commits in PR #$PR_NUMBER"; exit 1; } || \
          echo "✅ PR #$PR_NUMBER is clean!"

===== ./.github/workflows/differential-shellcheck.yml =====

# Doc: https://github.com/redhat-plumbers-in-action/differential-shellcheck#usage
---

name: Differential ShellCheck
on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

permissions:
  contents: read

jobs:
  lint:
    runs-on: ubuntu-latest

    permissions:
      security-events: write

    steps:
      - name: Repository checkout
        uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Differential ShellCheck
        uses: redhat-plumbers-in-action/differential-shellcheck@v4
        with:
          severity: warning
          token: ${{ secrets.GITHUB_TOKEN }}

===== ./.github/workflows/check-potfiles.yml =====
name: Check POTFILES.in

on:
  push:
    branches:
    - main
    - 'flatpak-1.[0-9]+.x'
  pull_request:
    branches:
    - main
    - 'flatpak-1.[0-9]+.x'
  merge_group:
    types:
    - checks_requested

jobs:
  potfiles:
    name: Check POTFILES.in
    runs-on: ubuntu-latest

    steps:
      - name: Repository checkout
        uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Check POTFILES.in
        run: .github/workflows/check-potfiles.sh
===== ./.github/ISSUE_TEMPLATE/feature_request.yml =====
name: Feature request
description: Request a feature
title: "[Feature request]: "
labels:
  - "enhancement"
  - "needs triage"
body:
- type: checkboxes
  attributes:
    label: Checklist
    description: Please make sure you have read the following.
    options:
      - label: I agree to follow the [Code of Conduct](https://github.com/flatpak/flatpak/blob/main/CODE_OF_CONDUCT.md) that this project adheres to.
        required: true
      - label: I have searched the [issue tracker](https://www.github.com/flatpak/flatpak/issues) for a feature request that matches the one I want to file, without success.
        required: true
- type: textarea
  attributes:
    label: Suggestion
    description: A clear and concise description of what you would like to see in the upcoming releases. Afterwards, describe the specific use case(s) that would be helped by this enhancement.
  validations:
    required: true

===== ./.github/ISSUE_TEMPLATE/bug_template.yml =====
name: Bug Report
description: Report a bug in Flatpak
title: "[Bug]: "
labels: "needs triage"
body:
- type: checkboxes
  attributes:
    label: Checklist
    description: Please make sure you have read the following.
    options:
      - label: I agree to follow the [Code of Conduct](https://github.com/flatpak/flatpak/blob/main/CODE_OF_CONDUCT.md) that this project adheres to.
        required: true
      - label: I have searched the [issue tracker](https://www.github.com/flatpak/flatpak/issues) for a bug that matches the one I want to file, without success.
        required: true
      - label: If this is an issue with a particular app, I have tried filing it in the appropriate issue tracker for the app (e.g. under https://github.com/flathub/) and determined that it is an issue with Flatpak itself.
        required: true
      - label: This issue is not a report of a security vulnerability (see [here](https://github.com/flatpak/flatpak/blob/main/SECURITY.md) if you need to report a security issue).
        required: true
- type: input
  attributes:
    label: Flatpak version
    description: What version of Flatpak are you using? If unsure, run `flatpak --version` in the terminal.
    placeholder: 1.10.2
  validations:
    required: true
- type: dropdown
  attributes:
    label: What Linux distribution are you using?
    options:
      - Alpine Linux
      - Arch Linux
      - Artix Linux
      - CentOS
      - ChromeOS
      - Clear Linux
      - Debian
      - Endless OS
      - Fedora Linux
      - Fedora Silverblue
      - Gentoo Linux
      - openSUSE
      - Linux Mint
      - Manjaro Linux
      - MicroOS
      - NixOS
      - Pop!_OS
      - Raspberry Pi OS
      - Solus
      - Ubuntu
      - Void Linux
      - Other (specify below)
  validations:
    required: true
- type: input
  attributes:
    label: Linux distribution version
    description: What Linux distribution version are you using? If unsure, run `uname -a` in the terminal.
    placeholder: "e.g. 34, 20.04"
- type: dropdown
  attributes:
    label: What architecture are you using?
    options:
      - i386
      - x86_64
      - aarch64
      - arm
      - armeb
  validations:
    required: true
- type: textarea
  attributes:
    label: How to reproduce
    description: A clear description of how to reproduce the problem.
    placeholder: |
      1. Go to `...`
      2. Click on `...`
      3. Scroll down to `...`
      4. See error
  validations:
    required: false
- type: textarea
  attributes:
    label: Expected Behavior
    description: A clear and concise description of what you expected to happen.
  validations:
    required: true
- type: textarea
  attributes:
    label: Actual Behavior
    description: A clear description of what actually happens.
  validations:
    required: true
- type: textarea
  attributes:
    label: Additional Information
    description: If your problem needs further explanation, or if the issue you're seeing cannot be reproduced in a gist, please add more information here.

===== ./oci-authenticator/org.flatpak.Authenticator.Oci.service.in =====
[D-BUS Service]
Name=org.flatpak.Authenticator.Oci
Exec=@libexecdir@/flatpak-oci-authenticator
SystemdService=flatpak-oci-authenticator.service

===== ./oci-authenticator/meson.build =====
# Copyright 2022 Collabora Ltd.
# SPDX-License-Identifier: LGPL-2.1-or-later

executable(
  'flatpak-oci-authenticator',
  'flatpak-oci-authenticator.c',
  dependencies : [
    base_deps,
    json_glib_dep,
    libflatpak_common_base_dep,
    libflatpak_common_dep,
    libglnx_dep,
    libostree_dep,
  ],
  include_directories : [
    include_directories('.'),
  ],
  install : true,
  install_dir : get_option('libexecdir'),
)

configure_file(
  input : 'flatpak-oci-authenticator.service.in',
  output : 'flatpak-oci-authenticator.service',
  configuration : service_conf_data,
  install_dir : get_option('systemduserunitdir'),
)

configure_file(
  input : 'org.flatpak.Authenticator.Oci.service.in',
  output : 'org.flatpak.Authenticator.Oci.service',
  configuration : service_conf_data,
  install_dir : dbus_service_dir,
)

===== ./oci-authenticator/flatpak-oci-authenticator.c =====
/* vi:set et sw=2 sts=2 cin cino=t0,f0,(0,{s,>2s,n-s,^-s,e-s:
 * Copyright © 2019 Red Hat, Inc
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Alexander Larsson <alexl@redhat.com>
 */

#include "config.h"
#include <locale.h>

#include <glib/gi18n-lib.h>
#include <json-glib/json-glib.h>
#include "flatpak-oci-registry-private.h"
#include "flatpak-utils-base-private.h"
#include "flatpak-utils-http-private.h"
#include "flatpak-auth-private.h"
#include "flatpak-dbus-generated.h"

FlatpakAuthenticator *authenticator;
static GMainLoop *main_loop = NULL;
static guint name_owner_id = 0;
static gboolean no_idle_exit = FALSE;
static FlatpakHttpSession *http_session = NULL;

#define IDLE_TIMEOUT_SECS 10 * 60

static void
skeleton_died_cb (gpointer data)
{
  g_info ("skeleton finalized, exiting");
  g_main_loop_quit (main_loop);
}

static gboolean
unref_skeleton_in_timeout_cb (gpointer user_data)
{
  static gboolean unreffed = FALSE;

  g_info ("unreffing authenticator main ref");
  if (!unreffed)
    {
      g_object_unref (authenticator);
      unreffed = TRUE;
    }

  return G_SOURCE_REMOVE;
}

static void
unref_skeleton_in_timeout (void)
{
  if (name_owner_id)
    g_bus_unown_name (name_owner_id);
  name_owner_id = 0;

  /* After we've lost the name or idled we drop the main ref on the authenticator
     so that we'll exit when it drops to zero. However, if there are
     outstanding calls these will keep the refcount up during the
     execution of them. We do the unref on a timeout to make sure
     we're completely draining the queue of (stale) requests. */
  g_timeout_add (500, unref_skeleton_in_timeout_cb, NULL);
}

static gboolean
idle_timeout_cb (gpointer user_data)
{
  if (name_owner_id)
    {
      g_info ("Idle - unowning name");
      unref_skeleton_in_timeout ();
    }
  return G_SOURCE_REMOVE;
}

static void
schedule_idle_callback (void)
{
  static guint idle_timeout_id = 0;

  if (!no_idle_exit)
    {
      if (idle_timeout_id != 0)
        g_source_remove (idle_timeout_id);

      idle_timeout_id = g_timeout_add_seconds (IDLE_TIMEOUT_SECS, idle_timeout_cb, NULL);
    }
}

typedef struct {
  gboolean done;
  char *user;
  char *password;
  GCond cond;
  GMutex mutex;
} BasicAuthData;


G_LOCK_DEFINE (active_auth);
static GHashTable *active_auth;

static void
cancel_basic_auth (BasicAuthData *auth)
{
  g_mutex_lock (&auth->mutex);
  if (!auth->done)
    {
      auth->done = TRUE;
      g_cond_signal (&auth->cond);
    }
  g_mutex_unlock (&auth->mutex);
}

static gboolean
handle_request_ref_tokens_close (FlatpakAuthenticatorRequest *object,
                                 GDBusMethodInvocation *invocation,
                                 gpointer user_data)
{
  BasicAuthData *auth = user_data;

  g_info ("handling Request.Close");

  flatpak_authenticator_request_complete_close (object, invocation);

  cancel_basic_auth (auth);

  return G_DBUS_METHOD_INVOCATION_HANDLED;
}

static void
add_auth_for_peer (const char *sender,
                   BasicAuthData *auth)
{
  GList *list;

  G_LOCK (active_auth);
  if (active_auth == NULL)
    active_auth = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);

  list = g_hash_table_lookup (active_auth, sender);
  list = g_list_prepend (list, auth);
  g_hash_table_insert (active_auth, g_strdup (sender), list);

  G_UNLOCK (active_auth);
}

static void
remove_auth_for_peer (const char *sender,
                      BasicAuthData *auth)
{
  GList *list;

  G_LOCK (active_auth);
  list = g_hash_table_lookup (active_auth, sender);
  list = g_list_remove (list, auth);
  g_hash_table_insert (active_auth, g_strdup (sender), list);

  G_UNLOCK (active_auth);
}

static gpointer
peer_died (const char *name)
{
  G_LOCK (active_auth);
  if (active_auth)
    {
      GList *active = g_hash_table_lookup (active_auth, name);
      if (active)
        {
          for (GList *l = active; l != NULL; l = l->next)
            {
              g_info ("Cancelling auth operation for dying peer %s", name);
              cancel_basic_auth (l->data);
            }
          g_list_free (active);
          g_hash_table_remove (active_auth, name);
        }
    }
  G_UNLOCK (active_auth);
  return NULL;
}

static gboolean
handle_request_ref_tokens_basic_auth_reply (FlatpakAuthenticatorRequest *object,
                                            GDBusMethodInvocation *invocation,
                                            const gchar *arg_user,
                                            const gchar *arg_password,
                                            GVariant *options,
                                            gpointer user_data)
{
  BasicAuthData *auth = user_data;

  g_info ("handling Request.BasicAuthReply %s %s", arg_user, arg_password);

  flatpak_authenticator_request_complete_basic_auth_reply (object, invocation);

  g_mutex_lock (&auth->mutex);
  if (!auth->done)
    {
      auth->done = TRUE;
      auth->user = g_strdup (arg_user);
      auth->password = g_strdup (arg_password);
      g_cond_signal (&auth->cond);
    }
  g_mutex_unlock (&auth->mutex);

  return G_DBUS_METHOD_INVOCATION_HANDLED;
}

static char *
run_basic_auth (FlatpakAuthenticatorRequest *request,
                const char *sender,
                const char *realm,
                const char *previous_error)
{
  BasicAuthData auth = { FALSE };
  int id1, id2;
  g_autofree char *combined = NULL;
  g_autoptr(GVariant) options = NULL;
  GVariantBuilder options_builder;

  g_variant_builder_init (&options_builder, G_VARIANT_TYPE ("a{sv}"));

  if (previous_error)
    g_variant_builder_add (&options_builder, "{sv}", "previous-error", g_variant_new_string (previous_error));

  options = g_variant_ref_sink (g_variant_builder_end (&options_builder));

  g_cond_init (&auth.cond);
  g_mutex_init (&auth.mutex);

  g_mutex_lock (&auth.mutex);

  add_auth_for_peer (sender, &auth);

  id1 = g_signal_connect (request, "handle-close", G_CALLBACK (handle_request_ref_tokens_close), &auth);
  id2 = g_signal_connect (request, "handle-basic-auth-reply", G_CALLBACK (handle_request_ref_tokens_basic_auth_reply), &auth);

  flatpak_authenticator_request_emit_basic_auth (request, realm, options);

  while (!auth.done)
    g_cond_wait (&auth.cond, &auth.mutex);

  g_signal_handler_disconnect (request, id1);
  g_signal_handler_disconnect (request, id2);

  remove_auth_for_peer (sender, &auth);

  g_mutex_unlock (&auth.mutex);

  g_cond_clear (&auth.cond);
  g_mutex_clear (&auth.mutex);

  if (auth.user == NULL)
    return NULL;

  combined = g_strdup_printf ("%s:%s", auth.user, auth.password);
  g_free (auth.user);
  g_free (auth.password);

  return g_base64_encode ((guchar *)combined, strlen (combined));
}

static char *
get_token_for_ref (FlatpakOciRegistry *registry,
                   GVariant *ref_data,
                   const char *basic_auth,
                   GError **error)
{
  g_autofree char *oci_digest = NULL;
  const char *ref, *commit, *oci_repository;
  g_autoptr(GVariant) data = NULL;
  gint32 token_type;

  g_variant_get (ref_data, "(&s&si@a{sv})", &ref, &commit, &token_type, &data);

  if (!g_variant_lookup (data, "summary.xa.oci-repository", "&s", &oci_repository))
    {
      flatpak_fail (error, _("Not a oci remote, missing summary.xa.oci-repository"));
      return NULL;
    }

  oci_digest = g_strconcat ("sha256:", commit, NULL);

  return flatpak_oci_registry_get_token (registry, oci_repository, oci_digest, basic_auth, NULL, error);
}

static gboolean
cancel_request (FlatpakAuthenticatorRequest *request,
                const char *sender)
{
  GVariantBuilder results;

  g_variant_builder_init (&results, G_VARIANT_TYPE ("a{sv}"));
  flatpak_authenticator_request_emit_response (request,
                                               FLATPAK_AUTH_RESPONSE_CANCELLED,
                                               g_variant_builder_end (&results));
  return G_DBUS_METHOD_INVOCATION_HANDLED;
}

static gboolean
error_request_raw (FlatpakAuthenticatorRequest *request,
                   const char *sender,
                   gint32 error_code,
                   const char *error_message)
{
  GVariantBuilder results;

  g_variant_builder_init (&results, G_VARIANT_TYPE ("a{sv}"));
  g_variant_builder_add (&results, "{sv}", "error-message", g_variant_new_string (error_message));
  g_variant_builder_add (&results, "{sv}", "error-code", g_variant_new_int32 (error_code));
  flatpak_authenticator_request_emit_response (request,
                                               FLATPAK_AUTH_RESPONSE_ERROR,
                                               g_variant_builder_end (&results));
  return G_DBUS_METHOD_INVOCATION_HANDLED;
}

static gboolean
error_request (FlatpakAuthenticatorRequest *request,
               const char *sender,
               GError *error)
{
  int error_code = -1;

  if (error->domain == FLATPAK_ERROR)
    error_code = error->code;

  return error_request_raw (request, sender, error_code, error->message);
}

static char *
canonicalize_registry_uri (const char *oci_registry_uri)
{
  const char *slash;
  /* Skip http: part */
  while (*oci_registry_uri != 0 &&
         *oci_registry_uri != ':')
    oci_registry_uri++;

  if (*oci_registry_uri != 0)
    oci_registry_uri++;

  /* Skip slashes */
  while (*oci_registry_uri != 0 &&
         *oci_registry_uri == '/')
    oci_registry_uri++;

  slash = strchr (oci_registry_uri, '/');
  if (slash)
    return g_strndup (oci_registry_uri, slash - oci_registry_uri);
  else
    return g_strdup (oci_registry_uri);
}

static char *
lookup_auth_from_config_path (const char *oci_registry_uri,
                              const char *path)
{
  g_autofree char *data = NULL;
  g_autoptr(JsonNode) json = NULL;
  JsonObject *auths = NULL, *registry_auth = NULL;

  if (!g_file_get_contents (path, &data, NULL, NULL))
    return NULL;

  json = json_from_string (data, NULL);
  if (json == NULL)
    return NULL;
  if (json_object_has_member (json_node_get_object (json), "auths"))
    auths = json_object_get_object_member (json_node_get_object (json), "auths");
  if (auths)
    {
      if (json_object_has_member (auths, oci_registry_uri))
        registry_auth = json_object_get_object_member (auths, oci_registry_uri);
      if (registry_auth == NULL)
        {
          g_autofree char *canonical = canonicalize_registry_uri (oci_registry_uri);
          if (canonical && json_object_has_member (auths, canonical))
            registry_auth = json_object_get_object_member (auths, canonical);
        }
      if (registry_auth != NULL)
        {
          if (json_object_has_member (registry_auth, "auth"))
            {
              return g_strdup (json_object_get_string_member (registry_auth, "auth"));
            }
        }
    }

  return NULL;
}


static char *
lookup_auth_from_config (const char *oci_registry_uri)
{
  /* These are flatpak specific, but use same format as docker/skopeo: */
  g_autofree char *flatpak_user_path = g_build_filename (g_get_user_config_dir (), "flatpak/oci-auth.json", NULL);
  const char *flatpak_global_path = "/etc/flatpak/oci-auth.json";

  /* These are what skopeo & co use as per:
     https://github.com/containers/image/blob/HEAD/pkg/docker/config/config.go#L34
  */
  g_autofree char *user_container_path = g_build_filename (g_get_user_runtime_dir (), "containers/auth.json", NULL);
  g_autofree char *container_path = g_strdup_printf ("/run/containers/%d/auth.json", getuid ());
  g_autofree char *docker_path = g_build_filename (g_get_home_dir (), ".docker/config.json", NULL);

  char *auth;

  auth = lookup_auth_from_config_path (oci_registry_uri, flatpak_user_path);
  if (auth != NULL)
    return auth;
  auth = lookup_auth_from_config_path (oci_registry_uri, flatpak_global_path);
  if (auth != NULL)
    return auth;
  auth = lookup_auth_from_config_path (oci_registry_uri, user_container_path);
  if (auth != NULL)
    return auth;
  auth = lookup_auth_from_config_path (oci_registry_uri, container_path);
  if (auth != NULL)
    return auth;
  auth = lookup_auth_from_config_path (oci_registry_uri, docker_path);
  if (auth != NULL)
    return auth;

  return NULL;
}

/* Note: This runs on a thread, so we can just block */
static gboolean
handle_request_ref_tokens (FlatpakAuthenticator *f_authenticator,
                           GDBusMethodInvocation *invocation,
                           const gchar *arg_handle_token,
                           GVariant *arg_authenticator_options,
                           const gchar *arg_remote,
                           const gchar *arg_remote_uri,
                           GVariant *arg_refs,
                           GVariant *arg_options,
                           const gchar *arg_parent_window)
{
  g_autofree char *request_path = NULL;
  g_autoptr(GError) error = NULL;
  g_autoptr(GError) anon_error = NULL;
  g_autoptr(AutoFlatpakAuthenticatorRequest) request = NULL;
  const char *auth = NULL;
  gboolean have_auth;
  const char *oci_registry_uri = NULL;
  gsize n_refs, i;
  gboolean no_interaction = FALSE;
  g_autoptr(FlatpakOciRegistry) registry = NULL;
  g_autofree char *first_token = NULL;
  GVariantBuilder tokens;
  GVariantBuilder results;
  g_autofree char *sender = g_strdup (g_dbus_method_invocation_get_sender (invocation));

  g_info ("handling Authenticator.RequestRefTokens");

  g_variant_lookup (arg_authenticator_options, "auth", "&s", &auth);
  have_auth = auth != NULL;

  if (!g_variant_lookup (arg_options, "xa.oci-registry-uri", "&s", &oci_registry_uri))
    {
      g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
                                             G_DBUS_ERROR_INVALID_ARGS,
                                             _("Not a OCI remote"));
      return G_DBUS_METHOD_INVOCATION_HANDLED;
    }
  g_variant_lookup (arg_options, "no-interaction", "b", &no_interaction);

  request_path = flatpak_auth_create_request_path (g_dbus_method_invocation_get_sender (invocation),
                                                   arg_handle_token, NULL);
  if (request_path == NULL)
    {
      g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
                                             G_DBUS_ERROR_INVALID_ARGS,
                                             _("Invalid token"));
      return G_DBUS_METHOD_INVOCATION_HANDLED;
    }

  request = flatpak_authenticator_request_skeleton_new ();
  if (!g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (request),
                                         g_dbus_method_invocation_get_connection (invocation),
                                         request_path,
                                         &error))
    {
      g_dbus_method_invocation_return_gerror (invocation, error);
      return G_DBUS_METHOD_INVOCATION_HANDLED;
    }

  flatpak_authenticator_complete_request_ref_tokens (f_authenticator, invocation, request_path);

  registry = flatpak_oci_registry_new (oci_registry_uri, FALSE, -1, NULL, &error);
  if (registry == NULL)
    return error_request (request, sender, error);


  /* Look up credentials in config files */
  if (!have_auth)
    {
      g_info ("Looking for %s in auth info", oci_registry_uri);
      auth = lookup_auth_from_config (oci_registry_uri);
      have_auth = auth != NULL;
    }

  /* Try to see if we can get a token without presenting credentials */
  n_refs = g_variant_n_children (arg_refs);
  if (!have_auth && n_refs > 0)
    {
      g_autoptr(GVariant) ref_data = g_variant_get_child_value (arg_refs, 0);

      g_info ("Trying anonymous authentication");

      first_token = get_token_for_ref (registry, ref_data, NULL, &anon_error);
      if (first_token != NULL)
        have_auth = TRUE;
      else
        {
          if (g_error_matches (anon_error, FLATPAK_ERROR, FLATPAK_ERROR_NOT_AUTHORIZED))
            {
              g_info ("Anonymous authentication failed: %s", anon_error->message);

              /* Continue trying with authentication below */
            }
          else
            {
              /* We failed with some weird reason (network issue maybe?) and it is unlikely
               * that adding some authentication will fix it. It will just cause a bad UX like
               * described in #3753, so just return the error early.
               */
              return error_request (request, sender, anon_error);
            }
        }
    }

  /* Prompt the user for credentials */
  n_refs = g_variant_n_children (arg_refs);
  if (!have_auth && n_refs > 0 &&
      !no_interaction)
    {
      g_autoptr(GVariant) ref_data = g_variant_get_child_value (arg_refs, 0);

      g_info ("Trying user/password based authentication");

      while (auth == NULL)
        {
          g_autofree char *test_auth = NULL;

          test_auth = run_basic_auth (request, sender, oci_registry_uri, error ? error->message : NULL);

          if (test_auth == NULL)
            return cancel_request (request, sender);

          g_clear_error (&error);

          first_token = get_token_for_ref (registry, ref_data, test_auth, &error);
          if (first_token != NULL)
            {
              auth = g_steal_pointer (&test_auth);
              have_auth = TRUE;
            }
          else
            {
              if (!g_error_matches (error, FLATPAK_ERROR, FLATPAK_ERROR_NOT_AUTHORIZED))
                return error_request (request, sender, error);
              else
                {
                  g_info ("Auth failed getting token: %s", error->message);
                  /* Keep error for reporting below, or clear on next iteration start */
                }
            }
        }
    }

  if (!have_auth && n_refs > 0)
    return error_request (request, sender, error ? error : anon_error);

  g_variant_builder_init (&tokens, G_VARIANT_TYPE ("a{sas}"));

  for (i = 0; i < n_refs; i++)
    {
      g_autoptr(GVariant) ref_data = g_variant_get_child_value (arg_refs, i);
      char *for_refs_strv[2] = { NULL, NULL};
      g_autofree char *token = NULL;

      if (i == 0 && first_token != NULL)
        {
          token = g_steal_pointer (&first_token);
        }
      else
        {
          token = get_token_for_ref (registry, ref_data, auth, &error);
          if (token == NULL)
            return error_request (request, sender, error);
        }

      g_variant_get_child (ref_data, 0, "&s", &for_refs_strv[0]);
      g_variant_builder_add (&tokens, "{s^as}", token, for_refs_strv);
    }

  g_variant_builder_init (&results, G_VARIANT_TYPE ("a{sv}"));
  g_variant_builder_add (&results, "{sv}", "tokens", g_variant_builder_end (&tokens));

  g_info ("emitting OK response");
  flatpak_authenticator_request_emit_response (request,
                                               FLATPAK_AUTH_RESPONSE_OK,
                                               g_variant_builder_end (&results));

  return G_DBUS_METHOD_INVOCATION_HANDLED;
}

static gboolean
flatpak_authorize_method_handler (GDBusInterfaceSkeleton *interface,
                                  GDBusMethodInvocation  *invocation,
                                  gpointer                user_data)

{
  /* Ensure we don't idle exit */
  schedule_idle_callback ();

  return TRUE;
}

static void
on_bus_acquired (GDBusConnection *connection,
                 const gchar     *name,
                 gpointer         user_data)
{
  GError *error = NULL;

  g_info ("Bus acquired, creating skeleton");

  g_dbus_connection_set_exit_on_close (connection, FALSE);

  authenticator = flatpak_authenticator_skeleton_new ();
  flatpak_authenticator_set_version (authenticator, 0);

  g_object_set_data_full (G_OBJECT (authenticator), "track-alive", GINT_TO_POINTER (42), skeleton_died_cb);

  g_signal_connect (authenticator, "handle-request-ref-tokens", G_CALLBACK (handle_request_ref_tokens), NULL);

  g_dbus_interface_skeleton_set_flags (G_DBUS_INTERFACE_SKELETON (authenticator),
                                       G_DBUS_INTERFACE_SKELETON_FLAGS_HANDLE_METHOD_INVOCATIONS_IN_THREAD);

  /* This is only used for idle tracking atm */
  g_signal_connect (authenticator, "g-authorize-method",
                    G_CALLBACK (flatpak_authorize_method_handler),
                    NULL);

  if (!g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (authenticator),
                                         connection,
                                         FLATPAK_AUTHENTICATOR_OBJECT_PATH,
                                         &error))
    {
      g_warning ("error: %s", error->message);
      g_error_free (error);
    }
}

static void
on_name_acquired (GDBusConnection *connection,
                  const gchar     *name,
                  gpointer         user_data)
{
  g_info ("Name acquired");
}

static void
on_name_lost (GDBusConnection *connection,
              const gchar     *name,
              gpointer         user_data)
{
  g_info ("Name lost");
}


static void
message_handler (const gchar   *log_domain,
                 GLogLevelFlags log_level,
                 const gchar   *message,
                 gpointer       user_data)
{
  /* Make this look like normal console output */
  if (log_level & (G_LOG_LEVEL_DEBUG | G_LOG_LEVEL_INFO))
    g_printerr ("F: %s\n", message);
  else
    g_printerr ("%s: %s\n", g_get_prgname (), message);
}

static void
name_owner_changed (GDBusConnection *connection,
                    const gchar     *sender_name,
                    const gchar     *object_path,
                    const gchar     *interface_name,
                    const gchar     *signal_name,
                    GVariant        *parameters,
                    gpointer         user_data)
{
  const char *name, *from, *to;

  g_variant_get (parameters, "(&s&s&s)", &name, &from, &to);

  if (name[0] == ':' &&
      strcmp (name, from) == 0 &&
      strcmp (to, "") == 0)
    {
      peer_died (name);
    }
}


int
main (int    argc,
      char **argv)
{
  gboolean replace;
  gboolean opt_verbose;
  g_autoptr(GOptionContext) context = NULL;
  GDBusConnection *session_bus;
  GBusNameOwnerFlags flags;
  g_autoptr(GError) error = NULL;
  const GOptionEntry options[] = {
    { "replace", 'r', 0, G_OPTION_ARG_NONE, &replace,  "Replace old daemon.", NULL },
    { "verbose", 'v', 0, G_OPTION_ARG_NONE, &opt_verbose,  "Enable debug output.", NULL },
    { "no-idle-exit", 0, 0, G_OPTION_ARG_NONE, &no_idle_exit,  "Don't exit when idle.", NULL },
    { NULL }
  };

  setlocale (LC_ALL, "");

  g_setenv ("GIO_USE_VFS", "local", TRUE);

  g_set_prgname (argv[0]);

  g_log_set_handler (G_LOG_DOMAIN, G_LOG_LEVEL_MESSAGE, message_handler, NULL);

  context = g_option_context_new ("");

  replace = FALSE;
  opt_verbose = FALSE;

  g_option_context_set_summary (context, "Flatpak authenticator");
  g_option_context_add_main_entries (context, options, GETTEXT_PACKAGE);

  if (!g_option_context_parse (context, &argc, &argv, &error))
    {
      g_printerr ("%s: %s", g_get_application_name (), error->message);
      g_printerr ("\n");
      g_printerr ("Try \"%s --help\" for more information.",
                  g_get_prgname ());
      g_printerr ("\n");
      g_option_context_free (context);
      return 1;
    }

  if (opt_verbose)
    g_log_set_handler (G_LOG_DOMAIN, G_LOG_LEVEL_INFO, message_handler, NULL);

  g_info ("Started flatpak-authenticator");

  http_session = flatpak_create_http_session (PACKAGE_STRING);

  session_bus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error);
  if (session_bus == NULL)
    {
      g_printerr ("Can't find bus: %s\n", error->message);
      return 1;
    }

  flags = G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT;
  if (replace)
    flags |= G_BUS_NAME_OWNER_FLAGS_REPLACE;

  name_owner_id = g_bus_own_name (G_BUS_TYPE_SESSION,
                                  "org.flatpak.Authenticator.Oci",
                                  flags,
                                  on_bus_acquired,
                                  on_name_acquired,
                                  on_name_lost,
                                  NULL,
                                  NULL);

  /* Ensure we don't idle exit */
  schedule_idle_callback ();

  g_dbus_connection_signal_subscribe (session_bus,
                                      "org.freedesktop.DBus",
                                      "org.freedesktop.DBus",
                                      "NameOwnerChanged",
                                      "/org/freedesktop/DBus",
                                      NULL,
                                      G_DBUS_SIGNAL_FLAGS_NONE,
                                      name_owner_changed,
                                      NULL, NULL);

  main_loop = g_main_loop_new (NULL, FALSE);
  g_main_loop_run (main_loop);

  return 0;
}

===== ./oci-authenticator/flatpak-oci-authenticator.service.in =====
[Unit]
Description=flatpak oci authenticator

[Service]
BusName=org.flatpak.Authenticator.Oci
ExecStart=@libexecdir@/flatpak-oci-authenticator
Type=dbus

===== ./log =====

===== ./triggers/gtk-icon-cache.trigger =====
#!/bin/sh

if command -v gtk-update-icon-cache >/dev/null && test -d "$1/exports/share/icons/hicolor"; then
    cp /usr/share/icons/hicolor/index.theme "$1/exports/share/icons/hicolor/"
    for dir in "$1"/exports/share/icons/*; do
        if test -f "$dir/index.theme"; then
            if ! gtk-update-icon-cache --quiet "$dir"; then
                echo "Failed to run gtk-update-icon-cache for $dir"
                exit 1
            fi
        fi
    done
fi

===== ./triggers/mime-database.trigger =====
#!/bin/sh

if command -v update-mime-database >/dev/null && test -d "$1/exports/share/mime/packages"; then
    exec update-mime-database "$1/exports/share/mime"
fi

===== ./triggers/meson.build =====
# Copyright 2022 Collabora Ltd.
# SPDX-License-Identifier: LGPL-2.1-or-later

install_data(
  'desktop-database.trigger',
  'gtk-icon-cache.trigger',
  'mime-database.trigger',
  install_dir : get_option('datadir') / 'flatpak' / 'triggers',
)

===== ./triggers/desktop-database.trigger =====
#!/bin/sh

if command -v update-desktop-database >/dev/null && test -d "$1/exports/share/applications"; then
    exec update-desktop-database -q "$1/exports/share/applications"
fi

===== ./session-helper/flatpak-session-helper.c =====
/* vi:set et sw=2 sts=2 cin cino=t0,f0,(0,{s,>2s,n-s,^-s,e-s:
 * Copyright © 2014-2019 Red Hat, Inc
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Alexander Larsson <alexl@redhat.com>
 */

#include "config.h"

#include <errno.h>
#include <locale.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <sys/ioctl.h>
#include <gio/gio.h>
#include <gio/gunixfdlist.h>
#include "flatpak-dbus-generated.h"
#include "flatpak-session-helper.h"
#include "flatpak-utils-base-private.h"

static GStrv original_environ = NULL;
static char *monitor_dir;
static char *p11_kit_server_socket_path;
static int p11_kit_server_pid = 0;

static GHashTable *client_pid_data_hash = NULL;
static GDBusConnection *session_bus = NULL;

static void
do_atexit (void)
{
  if (p11_kit_server_pid != 0)
    kill (p11_kit_server_pid, SIGTERM);
}

static void
handle_sigterm (int signum)
{
  struct sigaction action = { 0 };
  do_atexit ();
  action.sa_handler = SIG_DFL;
  sigaction (signum, &action, NULL);
  raise (signum);
}

typedef struct
{
  GPid     pid;
  char    *client;
  guint    child_watch;
  gboolean watch_bus;
} PidData;

static void
pid_data_free (PidData *data)
{
  g_free (data->client);
  g_free (data);
}

static gboolean
handle_request_session (FlatpakSessionHelper  *object,
                        GDBusMethodInvocation *invocation,
                        gpointer               user_data)
{
  GVariantBuilder builder;

  g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sv}"));

  g_variant_builder_add (&builder, "{s@v}", "path",
                         g_variant_new_variant (g_variant_new_string (monitor_dir)));
  if (p11_kit_server_socket_path)
    g_variant_builder_add (&builder, "{s@v}", "pkcs11-socket",
                           g_variant_new_variant (g_variant_new_string (p11_kit_server_socket_path)));

  flatpak_session_helper_complete_request_session (object, invocation,
                                                   g_variant_builder_end (&builder));

  return G_DBUS_METHOD_INVOCATION_HANDLED;
}


static void
child_watch_died (GPid     pid,
                  gint     status,
                  gpointer user_data)
{
  PidData *pid_data = user_data;
  g_autoptr(GVariant) signal_variant = NULL;

  g_info ("Client Pid %d died", pid_data->pid);

  signal_variant = g_variant_ref_sink (g_variant_new ("(uu)", pid, status));
  g_dbus_connection_emit_signal (session_bus,
                                 pid_data->client,
                                 FLATPAK_SESSION_HELPER_PATH_DEVELOPMENT,
                                 FLATPAK_SESSION_HELPER_INTERFACE_DEVELOPMENT,
                                 "HostCommandExited",
                                 signal_variant,
                                 NULL);

  /* This frees the pid_data, so be careful */
  g_hash_table_remove (client_pid_data_hash, GUINT_TO_POINTER (pid_data->pid));
}

typedef struct
{
  int from;
  int to;
  int final;
} FdMapEntry;

typedef struct
{
  FdMapEntry *fd_map;
  int         fd_map_len;
  gboolean    set_tty;
  int         tty;
} ChildSetupData;

static void
child_setup_func (gpointer user_data)
{
  ChildSetupData *data = (ChildSetupData *) user_data;
  FdMapEntry *fd_map = data->fd_map;
  sigset_t set;
  int i;

  /* Unblock all signals */
  sigemptyset (&set);
  if (pthread_sigmask (SIG_SETMASK, &set, NULL) == -1)
    {
      g_error ("Failed to unblock signals when starting child");
      return;
    }

  /* Reset the handlers for all signals to their defaults. */
  for (i = 1; i < NSIG; i++)
    {
      if (i != SIGSTOP && i != SIGKILL)
        signal (i, SIG_DFL);
    }

  for (i = 0; i < data->fd_map_len; i++)
    {
      if (fd_map[i].from != fd_map[i].to)
        {
          dup2 (fd_map[i].from, fd_map[i].to);
          close (fd_map[i].from);
        }
    }

  /* Second pass in case we needed an in-between fd value to avoid conflicts */
  for (i = 0; i < data->fd_map_len; i++)
    {
      if (fd_map[i].to != fd_map[i].final)
        {
          dup2 (fd_map[i].to, fd_map[i].final);
          close (fd_map[i].to);
        }
    }

  /* We become our own session and process group, because it never makes sense
     to share the flatpak-session-helper dbus activated process group */
  setsid ();
  setpgid (0, 0);

  if (data->set_tty)
    {
      /* data->tty is our from fd which is closed at this point.
       * so locate the destination fd and use it for the ioctl.
       */
      for (i = 0; i < data->fd_map_len; i++)
        {
          if (fd_map[i].from == data->tty)
            {
              if (ioctl (fd_map[i].final, TIOCSCTTY, 0) == -1)
                g_info ("ioctl(%d, TIOCSCTTY, 0) failed: %s",
                        fd_map[i].final, strerror (errno));
              break;
            }
        }
    }
}


static gboolean
handle_host_command (FlatpakDevelopment    *object,
                     GDBusMethodInvocation *invocation,
                     GUnixFDList           *fd_list,
                     const gchar           *arg_cwd_path,
                     const gchar *const    *arg_argv,
                     GVariant              *arg_fds,
                     GVariant              *arg_envs,
                     guint                  flags)
{
  g_autoptr(GError) error = NULL;
  ChildSetupData child_setup_data = { NULL };
  GPid pid;
  PidData *pid_data;
  gsize i, j, n_fds, n_envs;
  const gint *fds;
  g_autofree FdMapEntry *fd_map = NULL;
  g_auto(GStrv) env = NULL;
  gint32 max_fd;

  if (*arg_cwd_path == 0)
    arg_cwd_path = NULL;

  if (arg_argv == NULL || *arg_argv == NULL || *arg_argv[0] == 0)
    {
      g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
                                             G_DBUS_ERROR_INVALID_ARGS,
                                             "No command given");
      return G_DBUS_METHOD_INVOCATION_HANDLED;
    }

  if (!g_variant_is_of_type (arg_fds, G_VARIANT_TYPE ("a{uh}")) ||
      !g_variant_is_of_type (arg_envs, G_VARIANT_TYPE ("a{ss}")) ||
      (flags & ~(FLATPAK_HOST_COMMAND_FLAGS_CLEAR_ENV |
                 FLATPAK_HOST_COMMAND_FLAGS_WATCH_BUS)) != 0)
    {
      g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
                                             G_DBUS_ERROR_INVALID_ARGS,
                                             "Unexpected argument");
      return G_DBUS_METHOD_INVOCATION_HANDLED;
    }

  g_info ("Running host command %s", arg_argv[0]);

  n_fds = 0;
  fds = NULL;
  if (fd_list != NULL)
    {
      n_fds = g_variant_n_children (arg_fds);
      fds = g_unix_fd_list_peek_fds (fd_list, NULL);
    }
  fd_map = g_new0 (FdMapEntry, n_fds);

  child_setup_data.fd_map = fd_map;
  child_setup_data.fd_map_len = n_fds;

  max_fd = -1;
  for (i = 0; i < n_fds; i++)
    {
      gint32 handle, fd;
      g_variant_get_child (arg_fds, i, "{uh}", &fd, &handle);
      fd_map[i].to = fd;
      fd_map[i].from = fds[i];
      fd_map[i].final = fd_map[i].to;

      /* If stdin/out/err is a tty we try to set it as the controlling
         tty for the app, this way we can use this to run in a terminal. */
      if ((fd == 0 || fd == 1 || fd == 2) &&
          !child_setup_data.set_tty &&
          isatty (fds[i]))
        {
          child_setup_data.set_tty = TRUE;
          child_setup_data.tty = fds[i];
        }

      max_fd = MAX (max_fd, fd_map[i].to);
      max_fd = MAX (max_fd, fd_map[i].from);
    }

  /* We make a second pass over the fds to find if any "to" fd index
     overlaps an already in use fd (i.e. one in the "from" category
     that are allocated randomly). If a fd overlaps "to" fd then its
     a caller issue and not our fault, so we ignore that. */
  for (i = 0; i < n_fds; i++)
    {
      int to_fd = fd_map[i].to;
      gboolean conflict = FALSE;

      /* At this point we're fine with using "from" values for this
         value (because we handle to==from in the code), or values
         that are before "i" in the fd_map (because those will be
         closed at this point when dup:ing). However, we can't
         reuse a fd that is in "from" for j > i. */
      for (j = i + 1; j < n_fds; j++)
        {
          int from_fd = fd_map[j].from;
          if (from_fd == to_fd)
            {
              conflict = TRUE;
              break;
            }
        }

      if (conflict)
        fd_map[i].to = ++max_fd;
    }

  if (flags & FLATPAK_HOST_COMMAND_FLAGS_CLEAR_ENV)
    {
      char *empty[] = { NULL };
      env = g_strdupv (empty);
    }
  else
    env = g_strdupv (original_environ);

  n_envs = g_variant_n_children (arg_envs);
  for (i = 0; i < n_envs; i++)
    {
      const char *var = NULL;
      const char *val = NULL;
      g_variant_get_child (arg_envs, i, "{&s&s}", &var, &val);

      env = g_environ_setenv (env, var, val, TRUE);
    }

  if (!g_spawn_async_with_pipes (arg_cwd_path,
                                 (char **) arg_argv,
                                 env,
                                 G_SPAWN_SEARCH_PATH | G_SPAWN_DO_NOT_REAP_CHILD,
                                 child_setup_func, &child_setup_data,
                                 &pid,
                                 NULL,
                                 NULL,
                                 NULL,
                                 &error))
    {
      gint code = G_DBUS_ERROR_FAILED;
      if (g_error_matches (error, G_SPAWN_ERROR, G_SPAWN_ERROR_ACCES))
        code = G_DBUS_ERROR_ACCESS_DENIED;
      else if (g_error_matches (error, G_SPAWN_ERROR, G_SPAWN_ERROR_NOENT))
        code = G_DBUS_ERROR_FILE_NOT_FOUND;
      g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, code,
                                             "Failed to start command: %s",
                                             error->message);
      return G_DBUS_METHOD_INVOCATION_HANDLED;
    }

  pid_data = g_new0 (PidData, 1);
  pid_data->pid = pid;
  pid_data->client = g_strdup (g_dbus_method_invocation_get_sender (invocation));
  pid_data->watch_bus = (flags & FLATPAK_HOST_COMMAND_FLAGS_WATCH_BUS) != 0;
  pid_data->child_watch = g_child_watch_add_full (G_PRIORITY_DEFAULT,
                                                  pid,
                                                  child_watch_died,
                                                  pid_data,
                                                  NULL);

  g_info ("Client Pid is %d", pid_data->pid);

  g_hash_table_replace (client_pid_data_hash, GUINT_TO_POINTER (pid_data->pid),
                        pid_data);


  flatpak_development_complete_host_command (object, invocation, NULL,
                                             pid_data->pid);
  return G_DBUS_METHOD_INVOCATION_HANDLED;
}

static gboolean
handle_host_command_signal (FlatpakDevelopment    *object,
                            GDBusMethodInvocation *invocation,
                            guint                  arg_pid,
                            guint                  arg_signal,
                            gboolean               to_process_group)
{
  PidData *pid_data = NULL;

  pid_data = g_hash_table_lookup (client_pid_data_hash, GUINT_TO_POINTER (arg_pid));
  if (pid_data == NULL ||
      strcmp (pid_data->client, g_dbus_method_invocation_get_sender (invocation)) != 0)
    {
      g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
                                             G_DBUS_ERROR_UNIX_PROCESS_ID_UNKNOWN,
                                             "No such pid");
      return G_DBUS_METHOD_INVOCATION_HANDLED;
    }

  g_info ("Sending signal %d to client pid %d", arg_signal, arg_pid);

  if (to_process_group)
    killpg (pid_data->pid, arg_signal);
  else
    kill (pid_data->pid, arg_signal);

  flatpak_development_complete_host_command_signal (object, invocation);

  return G_DBUS_METHOD_INVOCATION_HANDLED;
}

static void
name_owner_changed (GDBusConnection *connection,
                    const gchar     *sender_name,
                    const gchar     *object_path,
                    const gchar     *interface_name,
                    const gchar     *signal_name,
                    GVariant        *parameters,
                    gpointer         user_data)
{
  const char *name, *from, *to;

  g_variant_get (parameters, "(&s&s&s)", &name, &from, &to);

  if (name[0] == ':' &&
      strcmp (name, from) == 0 &&
      strcmp (to, "") == 0)
    {
      GHashTableIter iter;
      PidData *pid_data = NULL;
      gpointer value = NULL;
      GList *list = NULL, *l;

      g_hash_table_iter_init (&iter, client_pid_data_hash);
      while (g_hash_table_iter_next (&iter, NULL, &value))
        {
          pid_data = value;

          if (pid_data->watch_bus && g_str_equal (pid_data->client, name))
            list = g_list_prepend (list, pid_data);
        }

      for (l = list; l; l = l->next)
        {
          pid_data = l->data;
          killpg (pid_data->pid, SIGINT);
        }

      g_list_free (list);
    }
}

#define DBUS_NAME_DBUS "org.freedesktop.DBus"
#define DBUS_INTERFACE_DBUS DBUS_NAME_DBUS
#define DBUS_PATH_DBUS "/org/freedesktop/DBus"

static void
on_bus_acquired (GDBusConnection *connection,
                 const gchar     *name,
                 gpointer         user_data)
{
  FlatpakSessionHelper *helper;
  FlatpakDevelopment *devel;
  GError *error = NULL;

  g_dbus_connection_signal_subscribe (connection,
                                      DBUS_NAME_DBUS,
                                      DBUS_INTERFACE_DBUS,
                                      "NameOwnerChanged",
                                      DBUS_PATH_DBUS,
                                      NULL,
                                      G_DBUS_SIGNAL_FLAGS_NONE,
                                      name_owner_changed,
                                      NULL, NULL);

  helper = flatpak_session_helper_skeleton_new ();

  flatpak_session_helper_set_version (FLATPAK_SESSION_HELPER (helper), 1);

  g_signal_connect (helper, "handle-request-session", G_CALLBACK (handle_request_session), NULL);

  if (!g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (helper),
                                         connection,
                                         FLATPAK_SESSION_HELPER_PATH,
                                         &error))
    {
      g_warning ("error: %s", error->message);
      g_error_free (error);
    }

  devel = flatpak_development_skeleton_new ();
  flatpak_development_set_version (FLATPAK_DEVELOPMENT (devel), 1);
  g_signal_connect (devel, "handle-host-command", G_CALLBACK (handle_host_command), NULL);
  g_signal_connect (devel, "handle-host-command-signal", G_CALLBACK (handle_host_command_signal), NULL);

  if (!g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (devel),
                                         connection,
                                         FLATPAK_SESSION_HELPER_PATH_DEVELOPMENT,
                                         &error))
    {
      g_warning ("error: %s", error->message);
      g_error_free (error);
    }
}

static void
on_name_acquired (GDBusConnection *connection,
                  const gchar     *name,
                  gpointer         user_data)
{
}

static void
on_name_lost (GDBusConnection *connection,
              const gchar     *name,
              gpointer         user_data)
{
  exit (1);
}

/*
 * In the case that the monitored file is a symlink, we set up a separate
 * GFileMonitor for the real target of the link so that we don't miss updates
 * to the linked file contents. This is critical in the case of resolv.conf
 * which on stateless systems is often a symlink to a dyamically-generated
 * or updated file in /run.
 */
typedef struct
{
  const gchar  *source;
  char         *real;
  GFileMonitor *monitor_source;
  GFileMonitor *monitor_real;
} MonitorData;

static void
monitor_data_free (MonitorData *data)
{
  free (data->real);
  g_signal_handlers_disconnect_by_data (data->monitor_source, data);
  g_object_unref (data->monitor_source);
  if (data->monitor_real)
    {
      g_signal_handlers_disconnect_by_data (data->monitor_real, data);
      g_object_unref (data->monitor_real);
    }
  g_free (data);
}

G_DEFINE_AUTOPTR_CLEANUP_FUNC (MonitorData, monitor_data_free)

static void
copy_file (const char *source,
           const char *target_dir)
{
  char *basename = g_path_get_basename (source);
  char *dest = g_build_filename (target_dir, basename, NULL);
  gchar *contents = NULL;
  gsize len;

  if (g_file_get_contents (source, &contents, &len, NULL))
    g_file_set_contents (dest, contents, len, NULL);

  g_free (basename);
  g_free (dest);
  g_free (contents);
}

static void file_changed (GFileMonitor     *monitor,
                          GFile            *file,
                          GFile            *other_file,
                          GFileMonitorEvent event_type,
                          MonitorData      *data);

static void
update_real_monitor (MonitorData *data)
{
  char *real = NULL;
  g_autoptr(GError) error = NULL;

  real = flatpak_realpath (data->source, &error);

  if (real == NULL)
    {
      g_info ("unable to get real path to monitor host file %s: %s", data->source,
              error->message);
      return;
    }

  /* source path matches real path, second monitor is not required, but an old
   * one may still exist. set to NULL and compare to what we have. */
  if (!g_strcmp0 (data->source, real))
    {
      free (real);
      real = NULL;
    }

  /* no more work needed if the monitor we have matches the additional monitor
     we need (including NULL == NULL) */
  if (!g_strcmp0 (data->real, real))
    {
      free (real);
      return;
    }

  /* otherwise we're not monitoring the right thing and need to remove
     any old monitor and make a new one if needed */
  free (data->real);
  data->real = real;

  if (data->monitor_real)
    {
      g_signal_handlers_disconnect_by_data (data->monitor_real, data);
      g_clear_object (&(data->monitor_real));
    }

  if (!real)
    return;

  g_autoptr(GFile) r = g_file_new_for_path (real);
  g_autoptr(GError) err = NULL;
  data->monitor_real = g_file_monitor_file (r, G_FILE_MONITOR_NONE, NULL, &err);
  if (!data->monitor_real)
    {
      g_info ("failed to monitor host file %s (real path of %s): %s",
               real, data->source, err->message);
      return;
    }

  g_signal_connect (data->monitor_real, "changed", G_CALLBACK (file_changed), data);
}

static void
file_monitor_do (MonitorData *data)
{
  update_real_monitor (data);
  copy_file (data->source, monitor_dir);

  if (strcmp (data->source, "/etc/localtime") == 0)
    {
      /* We can't update the /etc/localtime symlink at runtime, nor can we make it a of the
       * correct form "../usr/share/zoneinfo/$timezone". So, instead we use the old debian
       * /etc/timezone file for telling the sandbox the timezone. */
      g_autofree char *dest = g_build_filename (monitor_dir, "timezone", NULL);
      g_autofree char *raw_timezone = flatpak_get_timezone ();
      g_autofree char *timezone_content = g_strdup_printf ("%s\n", raw_timezone);

      g_file_set_contents (dest, timezone_content, -1, NULL);
    }
}

static void
file_changed (GFileMonitor     *monitor,
              GFile            *file,
              GFile            *other_file,
              GFileMonitorEvent event_type,
              MonitorData      *data)
{
  if (event_type != G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT)
    return;

  file_monitor_do (data);
}

static MonitorData *
setup_file_monitor (const char *source)
{
  g_autoptr(GFile) s = g_file_new_for_path (source);
  g_autoptr(GError) err = NULL;
  GFileMonitor *monitor = NULL;
  MonitorData *data = NULL;

  data = g_new0 (MonitorData, 1);
  data->source = source;

  monitor = g_file_monitor_file (s, G_FILE_MONITOR_NONE, NULL, &err);
  if (monitor)
    {
      data->monitor_source = monitor;
      g_signal_connect (monitor, "changed", G_CALLBACK (file_changed), data);
    }
  else
    {
      g_info ("failed to monitor host file %s: %s", source, err->message);
    }

  file_monitor_do (data);

  return data;
}

static void
message_handler (const gchar   *log_domain,
                 GLogLevelFlags log_level,
                 const gchar   *message,
                 gpointer       user_data)
{
  /* Make this look like normal console output */
  if (log_level & (G_LOG_LEVEL_DEBUG | G_LOG_LEVEL_INFO))
    g_printerr ("F: %s\n", message);
  else
    g_printerr ("%s: %s\n", g_get_prgname (), message);
}

static void
start_p11_kit_server (const char *flatpak_dir)
{
  g_autofree char *socket_basename = g_strdup_printf ("pkcs11-flatpak-%d", getpid ());
  g_autofree char *socket_path = g_build_filename (flatpak_dir, socket_basename, NULL);
  g_autofree char *p11_kit_stdout = NULL;
  gint exit_status;
  g_autoptr(GError) local_error = NULL;
  g_auto(GStrv) stdout_lines = NULL;
  int i;
  const char * const p11_argv[] = {
    "p11-kit", "server",
    /* We explicitly request --sh here, because we then fail on earlier versions that doesn't support
     * this flag. This is good, because those earlier versions did not properly daemonize and caused
     * the spawn_sync to hang forever, waiting for the pipe to close.
     */
    "--sh",
    "-n", socket_path,
    "--provider",  "p11-kit-trust.so",
    "pkcs11:model=p11-kit-trust?write-protected=yes",
    NULL
  };

  g_info ("starting p11-kit server");

  if (!g_spawn_sync (NULL,
                     (char **) p11_argv, NULL,
                     G_SPAWN_SEARCH_PATH | G_SPAWN_STDERR_TO_DEV_NULL,
                     NULL, NULL,
                     &p11_kit_stdout, NULL,
                     &exit_status, &local_error))
    {
      g_warning ("Unable to start p11-kit server: %s", local_error->message);
      return;
    }

  if (!g_spawn_check_exit_status (exit_status, &local_error))
    {
      g_warning ("Unable to start p11-kit server: %s", local_error->message);
      return;
    }

  stdout_lines = g_strsplit (p11_kit_stdout, "\n", 0);
  /* Output is something like:
     P11_KIT_SERVER_ADDRESS=unix:path=/run/user/1000/p11-kit/pkcs11-2603742; export P11_KIT_SERVER_ADDRESS;
     P11_KIT_SERVER_PID=2603743; export P11_KIT_SERVER_PID;
   */
  for (i = 0; stdout_lines[i] != NULL; i++)
    {
      char *line = stdout_lines[i];

      if (g_str_has_prefix (line, "P11_KIT_SERVER_PID="))
        {
          char *pid = line + strlen ("P11_KIT_SERVER_PID=");
          char *p = pid;
          while (g_ascii_isdigit (*p))
            p++;

          *p = 0;
          p11_kit_server_pid = atol (pid);
        }
    }

  if (p11_kit_server_pid != 0)
    {
      g_info ("Using p11-kit socket path %s, pid %d", socket_path, p11_kit_server_pid);
      p11_kit_server_socket_path = g_steal_pointer (&socket_path);
    }
  else
    g_info ("Not using p11-kit due to older version");
}

int
main (int    argc,
      char **argv)
{
  guint owner_id;
  GMainLoop *loop;
  gboolean replace;
  gboolean verbose;
  gboolean show_version;
  g_autoptr(GOptionContext) context = NULL;
  GBusNameOwnerFlags flags;
  g_autofree char *pk11_program = NULL;
  g_autofree char *flatpak_dir = NULL;
  g_autoptr(GError) error = NULL;
  const GOptionEntry options[] = {
    { "replace", 'r', 0, G_OPTION_ARG_NONE, &replace,  "Replace old daemon.", NULL },
    { "verbose", 'v', 0, G_OPTION_ARG_NONE, &verbose,  "Enable debug output.", NULL },
    { "version", 0, 0, G_OPTION_ARG_NONE, &show_version, "Show program version.", NULL},
    { NULL }
  };
  g_autoptr(MonitorData) m_resolv_conf = NULL,
                         m_host_conf = NULL,
                         m_hosts = NULL,
                         m_gai_conf = NULL,
                         m_localtime = NULL;
  struct sigaction action;

  /* Save the environment before changing anything, so that subprocesses
   * can get the unchanged version */
  original_environ = g_get_environ ();

  atexit (do_atexit);

  memset (&action, 0, sizeof (struct sigaction));
  action.sa_handler = handle_sigterm;
  sigaction (SIGTERM, &action, NULL);
  sigaction (SIGHUP, &action, NULL);
  sigaction (SIGINT, &action, NULL);

  setlocale (LC_ALL, "");

  g_setenv ("GIO_USE_VFS", "local", TRUE);

  g_set_prgname (argv[0]);

  g_log_set_handler (G_LOG_DOMAIN, G_LOG_LEVEL_MESSAGE, message_handler, NULL);

  context = g_option_context_new ("");

  replace = FALSE;
  verbose = FALSE;
  show_version = FALSE;

  g_option_context_set_summary (context, "Flatpak session helper");
  g_option_context_add_main_entries (context, options, GETTEXT_PACKAGE);

  if (!g_option_context_parse (context, &argc, &argv, &error))
    {
      g_printerr ("%s: %s", g_get_application_name (), error->message);
      g_printerr ("\n");
      g_printerr ("Try \"%s --help\" for more information.",
                  g_get_prgname ());
      g_printerr ("\n");
      return 1;
    }

  g_clear_pointer (&context, g_option_context_free);

  if (show_version)
    {
      g_print (PACKAGE_STRING "\n");
      return 0;
    }

  if (verbose)
    g_log_set_handler (G_LOG_DOMAIN, G_LOG_LEVEL_INFO, message_handler, NULL);

  client_pid_data_hash = g_hash_table_new_full (NULL, NULL, NULL, (GDestroyNotify) pid_data_free);

  session_bus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error);
  if (session_bus == NULL)
    {
      g_printerr ("Can't find bus: %s\n", error->message);
      return 1;
    }

  flatpak_dir = g_build_filename (g_get_user_runtime_dir (), ".flatpak-helper", NULL);
  if (g_mkdir_with_parents (flatpak_dir, 0700) != 0)
    {
      g_print ("Can't create %s\n", monitor_dir);
      exit (1);
    }

  pk11_program = g_find_program_in_path ("p11-kit");
  if (pk11_program)
    start_p11_kit_server (flatpak_dir);
  else
    g_info ("p11-kit not found");

  monitor_dir = g_build_filename (flatpak_dir, "monitor", NULL);
  if (g_mkdir_with_parents (monitor_dir, 0755) != 0)
    {
      g_print ("Can't create %s\n", monitor_dir);
      exit (1);
    }

  m_resolv_conf = setup_file_monitor ("/etc/resolv.conf");
  m_host_conf   = setup_file_monitor ("/etc/host.conf");
  m_hosts       = setup_file_monitor ("/etc/hosts");
  m_gai_conf    = setup_file_monitor ("/etc/gai.conf");
  m_localtime   = setup_file_monitor ("/etc/localtime");

  flags = G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT;
  if (replace)
    flags |= G_BUS_NAME_OWNER_FLAGS_REPLACE;

  owner_id = g_bus_own_name (G_BUS_TYPE_SESSION,
                             FLATPAK_SESSION_HELPER_BUS_NAME,
                             flags,
                             on_bus_acquired,
                             on_name_acquired,
                             on_name_lost,
                             NULL,
                             NULL);

  loop = g_main_loop_new (NULL, FALSE);
  g_main_loop_run (loop);

  g_bus_unown_name (owner_id);

  g_strfreev (original_environ);
  return 0;
}

===== ./session-helper/meson.build =====
# Copyright 2022 Collabora Ltd.
# SPDX-License-Identifier: LGPL-2.1-or-later

executable(
  'flatpak-session-helper',
  dependencies : [
    base_deps,
    threads_dep,
    libglnx_dep,
    libflatpak_common_base_dep,
  ],
  install : true,
  install_dir : get_option('libexecdir'),
  sources : ['flatpak-session-helper.c'],
)

configure_file(
  input : 'flatpak-session-helper.service.in',
  output : 'flatpak-session-helper.service',
  configuration : service_conf_data,
  install_dir : get_option('systemduserunitdir'),
)

configure_file(
  input : 'org.freedesktop.Flatpak.service.in',
  output : 'org.freedesktop.Flatpak.service',
  configuration : service_conf_data,
  install_dir : dbus_service_dir,
)

===== ./session-helper/org.freedesktop.Flatpak.service.in =====
[D-BUS Service]
Name=org.freedesktop.Flatpak
Exec=@libexecdir@/flatpak-session-helper
SystemdService=flatpak-session-helper.service

===== ./session-helper/flatpak-session-helper.h =====
/*
 * Copyright © 2021 Collabora Ltd.
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 */

#ifndef __FLATPAK_SESSION_HELPER_H__
#define __FLATPAK_SESSION_HELPER_H__

#define FLATPAK_SESSION_HELPER_BUS_NAME "org.freedesktop.Flatpak"

#define FLATPAK_SESSION_HELPER_PATH "/org/freedesktop/Flatpak/SessionHelper"
#define FLATPAK_SESSION_HELPER_INTERFACE "org.freedesktop.Flatpak.SessionHelper"

#define FLATPAK_SESSION_HELPER_PATH_DEVELOPMENT "/org/freedesktop/Flatpak/Development"
#define FLATPAK_SESSION_HELPER_INTERFACE_DEVELOPMENT "org.freedesktop.Flatpak.Development"

typedef enum {
  FLATPAK_HOST_COMMAND_FLAGS_CLEAR_ENV = 1 << 0,
  FLATPAK_HOST_COMMAND_FLAGS_WATCH_BUS = 1 << 1,
  FLATPAK_HOST_COMMAND_FLAGS_NONE = 0
} FlatpakHostCommandFlags;

#endif

===== ./session-helper/flatpak-session-helper.service.in =====
[Unit]
Description=flatpak session helper
PartOf=graphical-session.target

[Service]
BusName=org.freedesktop.Flatpak
ExecStart=@libexecdir@/flatpak-session-helper
Type=dbus

===== ./meson_options.txt =====
# Copyright 2022 Collabora Ltd.
# SPDX-License-Identifier: LGPL-2.1-or-later

option(
  'auto_sideloading',
  type : 'boolean',
  description : 'enable systemd units which make Flatpak sideload from inserted USB drives',
  value : false,
)
option(
  'dconf',
  type : 'feature',
  description : 'Use dconf?',
  value : 'auto',
)
option(
  'dbus_config_dir',
  type : 'string',
  description : 'directory for D-Bus system configuration [$datadir/dbus-1/system.d]',
  value : '',
)
option(
  'dbus_service_dir',
  type : 'string',
  description : 'directory for D-Bus session service files [$datadir/dbus-1/services]',
  value : '',
)
option(
  'docbook_docs',
  type : 'feature',
  description : 'build documentation with xmlto',
  value : 'auto',
)
option(
  'docdir',
  type : 'string',
  description : 'documentation directory [$datadir/doc/flatpak]',
  value : '',
)
option(
  'gdm_env_file',
  type : 'boolean',
  description : 'install gdm env.d file (not needed if systemd generators work',
  value : false,
)
option(
  'gir',
  type : 'feature',
  description : 'build GObject-Introspection metadata',
  value : 'auto',
)
option(
  'gtkdoc',
  type : 'feature',
  description : 'build API reference documentation with gtk-doc',
  value : 'auto',
)
option(
  'installed_tests',
  type : 'boolean',
  description : 'install automated tests',
  value : false,
)
option(
  'internal_checks',
  type : 'boolean',
  description : 'enable internal checking',
  value : false,
)
option(
  'internal_tests',
  type : 'boolean',
  description : 'include internal tests in binary',
  value : false,
)
option(
  'libzstd',
  type : 'feature',
  description : 'use libzstd?',
  value : 'auto',
)
option(
  'malcontent',
  type : 'feature',
  description : 'use libmalcontent for parental controls?',
  value : 'auto',
)
option(
  'man',
  type : 'feature',
  description : 'build man pages',
  value : 'auto',
)
option(
  'privileged_group',
  type : 'string',
  description : 'name of root-equivalent group',
  value : 'wheel',
)
option(
  'profile_dir',
  type : 'string',
  description : 'directory for profile.d files',
  value : '',
)
option(
  'run_media_dir',
  type : 'string',
  description : 'location of auto-mounted USB drives]',
  value : '/run/media',
)
option(
  'sandboxed_triggers',
  type : 'boolean',
  description : 'enable sandboxed triggers',
  value : true,
)
option(
  'seccomp',
  type : 'feature',
  description : 'enable seccomp',
  value : 'enabled',
)
option(
  'selinux_module',
  type : 'feature',
  description : 'enable selinux module for system-helper',
  value : 'auto',
)
option(
  'system_bubblewrap',
  type : 'string',
  description : 'system bwrap executable, or empty string to build subproject',
  value : '',
)
option(
  'system_dbus_proxy',
  type : 'string',
  description : 'system xdg-dbus-proxy executable, or empty string to build subproject',
  value : '',
)
option(
  'system_fusermount',
  type : 'string',
  description : 'system fusermount executable, or empty string to auto-select based on fuse version',
  value : '',
)
option(
  'system_font_cache_dirs',
  type : 'array',
  description : 'directory where the system font cache is',
  value : ['/var/cache/fontconfig', '/usr/lib/fontconfig/cache'],
)
option(
  'system_fonts_dir',
  type : 'string',
  description : 'Directory where system fonts are',
  value : '/usr/share/fonts',
)
option(
  'system_helper',
  type : 'feature',
  description : 'enable system helper',
  value : 'enabled',
)
option(
  'system_helper_user',
  type : 'string',
  description : 'name of the system helper user',
  value : 'flatpak',
)
option(
  'system_install_dir',
  type : 'string',
  description : 'location of system installation [$localstatedir/lib/flatpak]',
  value : '',
)
option(
  'systemdsystemenvgendir',
  type : 'string',
  description : 'directory for systemd system environment generators',
  value : 'lib/systemd/system-environment-generators',
)
option(
  'systemd',
  type : 'feature',
  description : 'build with systemd support',
  value : 'auto',
)
option(
  'systemdsystemunitdir',
  type : 'string',
  description : 'directory for systemd system service files',
  # deliberately lib and not based on get_option('libdir'):
  # this should not be lib64 or lib/x86_64-linux-gnu
  value : 'lib/systemd/system',
)
option(
  'systemduserenvgendir',
  type : 'string',
  description : 'directory for systemd user environment generators',
  value : 'lib/systemd/user-environment-generators',
)
option(
  'systemduserunitdir',
  type : 'string',
  description : 'directory for systemd user service files',
  value : 'lib/systemd/user',
)
option(
  'sysusersdir',
  type : 'string',
  description : 'directory for systemd sysusers.d configuration files',
  value : 'lib/sysusers.d'
)
option(
  'tmpfilesdir',
  type : 'string',
  description : 'directory for systemd tmpfiles.d configuration files',
  value : 'lib/tmpfiles.d'
)
option(
  'tests',
  type : 'boolean',
  description : 'build tests',
  value : true,
)
option(
  'xauth',
  type : 'feature',
  description : 'enable Xauth use',
  value : 'enabled',
)
option(
  'wayland_security_context',
  type : 'feature',
  description : 'enable wayland security-context protocol support',
  value : 'auto',
)
option(
  'xmlto_flags',
  type : 'array',
  description : 'options to pass to xmlto',
  value : [],
)

===== ./NEWS =====
Changes in 1.18.0
~~~~~~~~~~~~~~~~~
Released: 2026-06-08

Enhancements:

* Improve error handling and printed output of `flatpak-coredumpctl` (#6649,
  #6680)

* Support the AMD vendor specific compute interface (`/dev/kfd`) via the DRI
  device permission (#6648)

* Improve the output of `flatpak update` with failure causes (#6657)

* Improve startup time for fish shell integration (#6635)

* Translation updates: ‎zh_CN (#6671)

Bug fixes:

* Fix building when HAVE_LIBSYSTEMD but not USE_SYSTEM_HELPER is defined (#6652)

* Ignore system bus failures in parental controls check (#6663)

* Fix some return values and replace deprecated `GTimeVal` with
  `g_get_real_time()` (#6646)

* Suppress an unused-result warning in the tests (#6655)

Changes in 1.17.7
~~~~~~~~~~~~~~~~~~
Released: 2026-05-06

Enhancements:

* Add the new permission conditionals `has-usb-device` and `has-usb-portal` to
  allow apps to drop --device=all and --device=usb permissions (#6560)

* Always send the `Flatpak-Upgrade-From` header when updating instead of
  freshly installing, to improve the quality of statistics (#6626)

* Improve how the absence of the system repo is handled (#6621)

* Changes to repos are now more atomic which helps to avoid them being in an
  invalid state. This could be observed when importing the GPG key failed,
  because the system clock was wrong. (#6547)

* A function to report the age of the configuration was added to libflatpak,
  which will help GNOME Software to prevent unnecessary work (#6532)

* Improvements to the build system (#6614, #6610)

* Improve various tests (#6604, #6606, #6619, #6617, #6605, #6625)

* Translation updates: tr (#6629), ‎zh_CN (#6630)

Bug fixes:

* Fix a regression in handling of the fallback-x11 permission, which was
  affecting overrides from Flatseal (#6632)

* Fix a memory leak in the Flatpak portal (#6613)

* Install SELinux configuration files to the right directory (#6622)

* Silence wrong `lseek()` errors when creating sub-sandboxes (#6609)

Changes in 1.17.6
~~~~~~~~~~~~~~~~~~
Released: 2026-04-10

Bug fixes:

* Fix the remaining regression for Chromium based browsers by not leaking file
  descriptors down to wrapped command (#6589, #6594)

* Fix a regression when installing extra-data without a runtime, which is the
  case for openh264 (#6587)

* Fix the remaining regression for Epiphany by ignoring unusable sandbox-expose
  paths for sub-sandboxes in the portal (#6588)

* Fix the installed tests by allowing to add a new ref to an existing temporary
  ostree repo (#6592)

* Avoid closing fds 0/1/2 when they are used as a bad argument to flatpak-run,
  and reduce duplication in handling file descriptor arguments (#6598)

Enhancements:

* Disable auto-pin in flatpak-repair to preserve the pin state across
  re-installs (#6571)

* Small improvements for the tests (#6596, #6595, #6597)

Changes in 1.17.5
~~~~~~~~~~~~~~~~~~
Released: 2026-04-09

Bug fixes:

* Fix regressions caused by the sandbox escape security fix, which impact some
  browsers, browser-based apps and Steam (#6577, #6569, #6576, #6574)

Enhancements:

* Expand test coverage of flatpak-run features used by flatpak-portal (#6573)

Changes in 1.17.4
~~~~~~~~~~~~~~~~~~
Released: 2026-04-08

Security fixes:

* Fix a complete sandbox escape which leads to host file access and code
  execution in the host context (CVE-2026-34078)

* Prevent arbitrary file deletion on the host filesystem (CVE-2026-34079)

* Prevent arbitrary read-access to files in the system-helper context
  (GHSA-2fxp-43j9-pwvc)

* Prevent orphaning cross-user pull operations (GHSA-89xm-3m96-w3jg)

Enhancements:

* Enable ntsync unconditionally (#6546)

* Automatic branch following for extensions to ensure that "no-autodownload"
  extensions stay functional after an update that requires a new branch (#6550)

* Translation updates: eo (#6538), kk (#6553), sr (#6537), zh_CN (#6534)

Bug fixes:

* Prevent CPR sequence from showing up in the terminal (#6549)

* Fix a crash for apps/runtimes with multiarch permission (#6535)

* Fixes for Coverity warnings (#4932)

* Add test-preinstall.sh to the test matrix source (#6551)

* Fix a test message to refer to "systemd-localed" instead of "located" (#6536)

Changes in 1.17.3
~~~~~~~~~~~~~~~~~~
Released: 2026-03-14

Enhancements:

* Improve check for --filesystem paths pointing to a parent folder (#6473)

* Fail if non-interactive and multiple refs, remotes or installations match
  (#5754)

* Default to text auth on WSL (#6491)

* Add build instructions for Ubuntu 24.04 (#6498)

* Show a better message when there are no refs to update (#6521)

* Silence AppStream refresh output on non-interactive runs (#6521)

* Translation updates: pt_BR (#6483), sl (#6468, #6475), sv (#6514), tr (#6528),
  zh_CN (#6469, #6477)

Bug fixes:

* Map the font-dirs.xml file more selectively (#6450)

* Change const pointers. This fixes build issues with glibc 2.43. (#6490)

* Add custom type flatpak_home_t for ~/.local/share/flatpak for SELinux (#6437)

* Fix build warnings when compiling with -Wanalyzer-null-argument and with
  -Wanalyzer-null-dereference (#6527)

* Use raw string for regular expression in the flatpak-bisect script (#6519)

Internal changes:

* Set the `FLATPAK_TRIGGERSDIR` environment variable when running
  installed tests. This fixes a regression with autopkg tests in
  Debian. (#6444)

* Add translator comments for some translatable strings (#6462)

* Fix typos in translatable strings (#6463)

* Fix lots of typos in code comments (#6482)

* Remove an unused function (#6529)

* Update two strings (#6464)

Changes in 1.17.2
~~~~~~~~~~~~~~~~~~
Released: 2025-12-15

This is a follow-up release for the 1.17.1 release, which was published
immutably without the dist artifacts due to a bug in the release workflow.

Changes in 1.17.1
~~~~~~~~~~~~~~~~~~
Released: 2025-12-15

Enhancements:

* Drop libsoup2 support in favor of libcurl. The `http_backend` build option has
  been dropped as well. (#6395)

* Support conditional permissions for shared subsystems and features. This
  extends the conditional permission system that was introduced in 1.17.0 to
  shares and features.

* Enable progress escape sequence by default (#6393)

* Allow passing device permissions to sub-sandbox created via the Flatpak portal
  (#6123)

* Add the runtime repository to the OCI image metadata when building OCI bundles
  (#6409)

* The CI now checks for translatable files and is now used to do releases
  (#6408, #6407)

* OCI remotes can now be configured to check for a matching signature in a
  standard OCI signature storage lookaside service, when installing apps and
  runtimes. (#6426)

* Applications distributed as OCI images now support the extra-data mechanism
  which should help with h.265 playback in Fedora Flatpaks (#6299)

* Add support for building OCI bundles with zstd compressed layers. This speeds
  up compression by several times, resulting in about a 20% smaller result. gzip
  is kept as the default for maximum compatibility. (#5540)

* Improve i18n of the command line progress reporting (#6397)

* Translation updates: tr (#6388), hr (#6387), sl (#6405), zh_CN (#6366, #6410)

Bug fixes:

* Fix an issue where the home directory would accidentally be accessible when
  a bad version of glib is in use, the app has access to a standard XDG
  directory, and that directory is not available on the system. (#6420)

* Fix incorrect CURLM_OK comparison in curl_easy_setopt checks (#6396)

* Error out when mandatory OCI JSON fields are missing (#6402)

* Fix various memory leaks (#6403, #6093)

Internal changes:

* Avoid triggering glib thumbnailing when enumerating `.portals` files
  (#6427)

* Add a test case for pre-installing from a sideload repo and a non-reachable
  network repo (#6423)

* Remove references to the defunct Open Collective (#6406)

* Improve various tests (#6406)

* Update note on seccomp filter code sharing (#6383)

Changes in 1.17.0
~~~~~~~~~~~~~~~~~~
Released: 2025-11-03

Enhancements:

* Allow directories to be forwarded to the sandboxed app as command-line
  arguments. This requires xdg-desktop-portal >= 1.7.0. (#6247)

* Allow Flatpak apps that are conceptually part of the operating system
  to be preinstalled by dropping files into `preinstall.d` directories.
  (#6116)

* Allow direct installation from an OCI image (#5972)

* Allow OCI remotes to have a collection ID, so they can be used with
  flatpak preinstall (#6083)

* Show a message if `flatpak document-list` finds no documents, and if
  `flatpak uninstall` finds nothing to uninstall (#6197)

* Support sideloading from OCI repositories and archives. This allows
  installing apps from OCI images stored in local sideload repositories.
  (#6294)

* Add support for flatpak+https:// URIs in `flatpak install --from`
  (#6372)

* New `--clear-env` option for `flatpak run` to clear the environment
  from the host before running the application (#6298)

* Support for conditional permissions. Permissions can now be conditioned
  on system and runtime capabilities. This for example allows to replace
  `--device=all` permissions with
  `--device-if=all:!has-input-device --device=input`. (#6285)

* Add host-root export which exposes the host's root directory at
  /run/host/root in the sandbox (#6314)

* Enable the VA-API extension for Intel Xe GPUs (#6311)

* JSON output support for various commands, making it easier to parse
  flatpak command output programmatically (#6337)

* Add basic OS information to Flatpak-Os-Info header when pulling objects,
  helping repository administrators understand their user base (#6346)

* `flatpak build` does not grant the host permissions by default, improving
  build isolation and reproducibility (#6308)

* Support the reinstall option on bundle installations (#5546)

* Drop a workaround for AppStream CIDs with duplicate `.desktop` suffixes
  (#6350)

* Add cancellation support for curl downloads (#6356)

* `build-finish` exports external AppStream release metainfo (#6133)

* The default D-Bus configuration moved from /etc to /usr (#6347)

* Documentation improvements (#6266, #6348, #6240, #6374)

* Translation updates: cs (#6306), nl (#6241), pl (#6290, #6288),
  sl (#6279, #6377), ru (#6278), zh_CN (#6304, #6334, #6354, #6366)

Bug fixes:

* Provide an empty /run/host/font-dirs.xml during `flatpak build` (#6138)

* Various bug fixes for the OCI support (#6296)

* Improve clearing the environment in the flatpak portal to fix support for
  FLATPAK_SPAWN_FLAGS_CLEAR_ENV with FLATPAK_SPAWN_FLAGS_NOTIFY_START (#6298)

* Fix various issues with `flatpak mask` and `flatpak pin` by reloading the
  repo configuration after changes done via the system helper (#6073)

* Fix propagation of `resolv.conf` into the sandbox via the session-helper by
  improving the file monitoring in case of broken symlinks (#6349)

* Preinstallation now works if the ref is not available in the first configured
  remote (#6373)

* Flatpak now allows the usage of sudo for changing the user (#6371)

* `flatpak-kill` will no longer send SIGKILL to all processes in the current
  process group (#6375)

* Authorization for parental controls no longer relies on racy PIDs (#6303)

* Fix various memory leaks (#6286, #6260)

* Fix various crashes (#6074, #6376)

Internal changes:

* Testing and CI improvements (#6284, #6302, #6291, #6295, #6067)

* Improvements to the formatting (#6331)

* Avoid using an uninitialised variable (#6345)

* Remove duplicate pointer clearing (#6361)

Changes in 1.16.1
~~~~~~~~~~~~~~~~~~
Released: 2025-05-10

Enhancements:

* When using parental controls, allow a child account to update existing
  apps by default, to ensure that security and bugfix updates can be
  installed. This can be overridden by setting polkit policy rules for
  the new `org.freedesktop.Flatpak.override-parental-controls-update`
  action if necessary. (#5552)

* Make systemd scopes easier to match to Flatpak app instances,
  by using the instance ID instead of the top-level process ID in the
  scope name (#6015)

* Access to `--device=dri` now includes `/dev/udmabuf` (#6158)

* Improve the error message for an invalid parameter to
  flatpak-spawn --sandbox-a11y-own-name (#6048)

* Speed up `flatpak prune --dry-run` by not calculating potential freed
  space and avoiding operations that would need to hold a lock
  (#5813, #6121)

* Speed up `flatpak permission-reset` by only writing entries that have
  actually changed (#5772)

* Documentation improvements (#4859, #6066, #6134)

* Look for TLS certificates at /etc/containers/certs.d when interacting with
  OCI registries (#5916)

* Translation updates: bg (#6120), ka (#6176), pl (#6106),
  pt_BR (#6076, #6188), ro (#6139), ru (#6145), sl (#6054), sv (#6193),
  tr (#6109)

Bug fixes:

* Fix intermittent flatpak-portal crashes by avoiding unnecessary
  multi-threading (#5605)

* Don't show a confusing confirmation prompt when `flatpak remove --unused`
  removes `autoprune-unless` extensions that are no longer needed, such as
  older Nvidia drivers (#5712, #2718)

* Don't propagate `$PYTHONPYCACHEPREFIX` from host into sandbox (#6110)

* Don't propagate `$WAYLAND_DISPLAY`, `$WAYLAND_SOCKET` from host into
  sandbox if access to the Wayland socket has been denied (#3948)

* When discovering the AT-SPI bus, treat `$AT_SPI_BUS_ADDRESS` as
  higher-priority than GetAddress(), more closely matching the behaviour
  of AT-SPI itself (#6173)

* Fix a memory leak when installing extra-data (#6069)

* Don't show fatal transaction errors twice (#3400)

* Fix the build with -Ddefault_library=static (#6119)

* Fix incorrect error reporting (#6127, #5170)

* When using `FLATPAK_TTY_PROGRESS`, terminate OSC escape sequence with
  standard ST sequence instead of xterm-specific BEL (#6092)

* Include all options in shell completion for `flatpak search` (#6096)

Internal changes:

* Fix an unclear boolean expression (no functional change) (#5013)

* Avoid a duplicate redirection in the test suite (#6117)

* CI updates

Changes in 1.16.0
~~~~~~~~~~~~~~~~~~
Released: 2025-01-09

Bug fixes:

 * Update libglnx to 2024-12-06:
    - Fix an assertion failure if creating a parent directory encounters a
      dangling symlink (GNOME/libglnx#1)
    - Fix a Meson warning

* Don't emit terminal progress indicator escape sequences by default. They are
  interpreted as notifications by some terminal emulators. (#6052)

* Fix introspection annotations in libflatpak

Enhancements:

* Add the `FLATPAK_TTY_PROGRESS` environment variable, which re-enables the
  terminal progress indicator escape sequences added in 1.15.91.

* Document the `FLATPAK_FANCY_OUTPUT` environment variable, which allows
  disabling the fancy formatting when outputting to a terminal.

Changes in 1.15.91
~~~~~~~~~~~~~~~~~~
Released: 2024-12-19

Enhancements:

 * Add the `FLATPAK_DATA_DIR` environment variable, which allows overriding
   at runtime the data directory location that Flatpak uses to search for
   configuration files such as remotes. This is useful for running tests,
   and for when installing using Flatpak in a chroot.

 * Add a `FLATPAK_DOWNLOAD_TMPDIR` variable. This allows using download
   directories other than /var/tmp.

 * Emit progress escape sequence. This can be used by terminal emulators
   to detect and display progress of Flatpak operations on their graphical
   user interfaces.

Bug fixes:

 * Install missing test data. This should fix "as-installed" tests via
   `ginsttest-runner`, used for example in Debian's autopkgtest framework.

 * Unify and improve how the Wayland socket is passed to the sandboxed app.
   This should fix a regression that is triggered by compositors that both
   implement the security-context-v1 protocol, and sets the `WAYLAND_DISPLAY`
   environment variable when launching Flatpak apps. (#5863)

 * Fix the plural form of a translatable string.

Changes in 1.15.12
~~~~~~~~~~~~~~~~~~
Released: 2024-11-28

Bug fixes:

 * Return to using the process ID of the Flatpak app in the cgroup name.
   Using the instance ID in 1.15.11 caused crashes when installing apps,
   extensions or runtimes that use the "extra data" mechanism, which
   does not set up an instance ID. (#6009)

Changes in 1.15.11
~~~~~~~~~~~~~~~~~~
Released: 2024-11-26

Dependencies:

 * In distributions that compile Flatpak to use a separate bubblewrap
   executable, version 0.11.0 is recommended (but not required).
   The minimum bubblewrap continues to be 0.10.0.

 * In distributions that compile Flatpak to use a separate xdg-dbus-proxy
   executable, version 0.1.6 is recommended (but not required).
   The minimum xdg-dbus-proxy continues to be 0.1.0.

Enhancements:

 * Allow applications like WebKit to connect the AT-SPI accessibility tree
   of processes in a sub-sandbox with the tree in the main process (#5898)

     * New sandboxing parameter `flatpak run --a11y-own-name`, which is
       like `--own-name` but for the accessibility bus

     * flatpak-portal API v7: add new sandbox-a11y-own-names option, which
       accepts names matching `${FLATPAK_ID}.*`

     * Apps may call the `org.a11y.atspi.Socket.Embedded` method on names
       matching `${FLATPAK_ID}.Sandboxed.*` by default

 * `flatpak run -vv $app_id` shows all applicable sandboxing parameters
   and their source, including overrides, as debug messages (#5895)

 * Add --device=usb, a subset of --device=all

 * Introduce USB device listing

   * Apps can list which USB devices they want to access ahead of time by
     using the `--usb` parameter. Check the manpages for the more information
     about the accepted syntax.

   * Denying access to USB devices is also possible with the `--no-usb`
     parameter. The syntax is equal to `--usb`.

   * Both options merely store metadata, and aren't used by Flatpak itself.
     This metadata is intended to be used by the (as of now, still in
     progress) USB portal to decide which devices the app can enumerate and
     request access.

 * Add support for KDE search completion

 * Use the instance id of the Flatpak app as part of the cgroup name. This
   better matches the naming conventions for cgroup.

 * Preconfigured repositories can now be set up by OS vendors using
   `${datadir}/flatpak/remotes.d` (typically /usr/share/flatpak/remotes.d),
   in addition to `${sysconfdir}/flatpak/remotes.d` (typically
   /etc/flatpak/remotes.d) which is intended for local sysadmin use

Bug fixes:

 * Update libglnx to 2024-08-23 (#5918)

     * fix build in environments that use -Werror=return-type, such as
       openSUSE Tumbleweed (#5778)

     * add a fallback definition for G_PID_FORMAT with older GLib

     * avoid warnings for g_steal_fd() with newer GLib

     * improve compatibility of g_closefrom() backport with newer GLib

 * Update meson wrap file for bubblewrap to version 0.11.0:

     * drop Autotools build system

     * improve handling of EINTR

     * improve handling of socket control messages

     * improve compatibility with busybox

     * improve compatibility with older Meson

     * fix deprecation warnings

 * Update meson wrap file for xdg-dbus-proxy to version 0.1.6:

     * compatibility with D-Bus implementations that pipeline the
       authentication handshake, such as sd-bus and zbus

     * compatibility with D-Bus implementations that use non-consecutive
       serial numbers, such as godbus and zbus

     * broadcast signals can be allowed without having to add TALK permission
       (#5828)

     * fix memory leaks

 * Fix some memory leaks

 * Translation updates: cs, pl, zh_CN

Internal changes:

 * Better const-correctness (#5913)
 * Fix a shellcheck warning in the tests (#5914)

Changes in 1.15.10
~~~~~~~~~~~~~~~~~~
Released: 2024-08-14

Dependencies:

 * In distributions that compile Flatpak to use a separate bubblewrap (bwrap)
   executable, version 0.10.0 is required.
   This version adds a new feature which is required by the security fix
   in this release.

Security fixes:

 * Don't follow symbolic links when mounting persistent directories
   (--persist option). This prevents a sandbox escape where a malicious or
   compromised app could edit the symlink to point to a directory that
   the app should not have been allowed to read or write.
   (CVE-2024-42472, GHSA-7hgv-f2j8-xw87)

Documentation:

 * Mark the 1.12.x and 1.10.x branches as end-of-life (#5352)

Other bug fixes:

 * Fix several memory leaks (#5883, #5884)

Internal changes:

 * Record a log file when running build-time tests with
   AddressSanitizer (#5884)

 * Add initial suppressions file for AddressSanitizer (#5884)

Changes in 1.15.9
~~~~~~~~~~~~~~~~~
Released: 2024-07-22

Dependencies:

 * bubblewrap and xdg-dbus-proxy are now provided by Meson wrap files
   instead of being directly vendored via `git submodule`.
   If downloading external software during build is not allowed in your
   environment, please install suitable versions of bubblewrap and
   xdg-dbus-proxy separately, then configure Flatpak with options similar to
   `-Dsystem_bubblewrap=bwrap -Dsystem_dbus_proxy=xdg-dbus-proxy`
   (most major distributions package it like this already).

Enhancements:

 * If xdg-dbus-proxy is new enough (0.1.6 or later, not yet released),
   allow two broadcast signals from AT-SPI by default, allowing bus
   traffic to be reduced. If xdg-dbus-proxy is older, this change will
   have no practical effect but is harmless. (#5828)

 * Install csh profile snippet (#5753)

Bug fixes:

 * Expand the list of environment variables that Flatpak apps do not
   inherit from the host system (#5765, #5785)

 * Take time zone information from $TZDIR if set (#5850)

 * Fix a memory leak since 1.15.7 when reloading D-Bus configuration (#5856)

 * Fix a memory leak when running `flatpak permissions` (#5844)

 * Fix memory leaks in `flatpak update` (#5816)

 * Fix memory leaks when installing packages (#5811)

 * Use more similar translatable strings for some error messages (#5748)

 * Document `flatpak config --set languages '*all*'` correctly:
   it is really `*all*` (or equivalently `*`), not just `all` (#5836)

 * Fix a misleading comment in the test for CVE-2024-32462 (#5779)

 * Fix a copy/paste error in the 1.15.7 release notes

 * On systems where subdirectories of /sys have been made inaccessible,
   continue without them (#5138)

 * Make tests more compatible with non-GNU shell utilities (#5812)

 * Translation updates: ka (#5873), hi (#5838), pt_BR (#5877), zh_CN (#5843)

Internal changes:

 * libglnx and variant-schema-compiler are now managed as `git subtree`
   instead of `git submodule`.
   Maintainers and contributors, please see `subprojects/README.md` for
   details of how to interact with these.
   In particular this means that submodules no longer need to be set up
   before working on a git clone. (#5800, #5845)

 * Split library code into more, smaller translation units, reducing
   internal circular dependencies (#5409, #5801, #5803)

 * Add some convenience macros in the test suite (#5693)

 * Minor internal robustness improvement (#5833)

 * Add configuration for Github Codespaces (#5767)

 * Improve CI configuration (#5791)

 * Work around infrastructure issues in third-party apt repositories
   used by default in Github Workflows (#5786)

Changes in 1.15.8
~~~~~~~~~~~~~~~~~
Released: 2024-04-18

Security fixes:

 * Don't allow an executable name to be misinterpreted as a command-line
   option for bwrap(1). This prevents a sandbox escape where a malicious
   or compromised app could ask xdg-desktop-portal to generate a .desktop
   file with access to files outside the sandbox. (CVE-2024-32462)

Other bug fixes:

 * Pass the -export-dynamic linker option as -Wl,-export-dynamic,
   fixing build failures with clang 18 and lld 18 (#5760)

 * Fix a double-free when installation is cancelled (#5763)

 * Fix installed-tests failure with "FUSERMOUNT: unbound variable"
   (#5751)

 * Translation updates: pt_BR (#5762), tr (#5761)

Changes in 1.15.7
~~~~~~~~~~~~~~~~~
Released: 2024-03-27

Dependencies:

 * The Meson build system is now required.
   Compiling with Autotools is no longer possible.

 * In distributions that compile Flatpak to use a separate bubblewrap (bwrap)
   executable, version 0.9.0 is recommended. Several of the bug fixes listed
   below will not be active if an older version is used.

 * In distributions that compile Flatpak to use a separate xdg-dbus-proxy
   executable, version 0.1.5 is recommended.

 * If libmalcontent (parental controls) is enabled, it must be version 0.5.0
   or later.

New features:

 * Automatically remove obsolete driver versions and other autopruned refs
   (#5632)

 * `--socket=inherit-wayland-socket` (#5614)

 * Automatically reload D-Bus session bus configuration after installing
   or upgrading apps, to pick up any exported D-Bus services (#3342)

Bug fixes:

 * Update included copy of bubblewrap to version 0.9.0:

     * `--symlink` is now idempotent, meaning it succeeds if the
       symlink already exists and already has the desired target
       (#2387, #3477, #5255)
     * Report a better error message if `mount(2)` fails with `ENOSPC`
     * Fix a double-close on error reading from `--args`, `--seccomp` or
       `--add-seccomp-fd` argument
     * Improve memory allocation behaviour
     * Silence various compiler warnings

 * Update included copy of xdg-dbus-proxy to version 0.1.5:

     * Fix handling of long object paths

 * Don't parse `<developer><name/></developer>` as the application name
   (#5700)

 * Don't refuse to start apps when there is no D-Bus system bus available
   (#5076)

 * Don't try to repeat migration of apps whose data was migrated to a new
   name and then deleted (#5668)

 * Improve handling of mixed locales on systems with systemd-localed (#5497)

 * Improve display of ellipsized columns in wide terminals (#5722)

 * Make `flatpak info -e` look for extensions in all installations (#5670)

 * Fix warnings from newer GLib versions (#5660, #5737)

 * Always set the `container` environment variable (#5610)

 * Always let the app inherit redirected file descriptors (#5626)

 * In `flatpak ps`, add xdg-desktop-portal-gnome to the list of backends
   we'll use to learn which apps are running in the background (#5729)

 * Don't use `WAYLAND_SOCKET` unless given `--socket=inherit-wayland-socket`
   (#5614)

 * Use `fusermount3` if compiled with FUSE 3, overridable with
   `-Dsystem_fusermount` compile-time option (#5104)

 * Avoid leaking a temporary variable from /etc/profile.d/flatpak.sh into
   the shell environment (#5574)

 * Improve async-signal safety (#5687)

 * Fix various memory leaks (#5683, #5690, #5691)

 * Avoid undefined behaviour of signed left-shift when storing object IDs
   in a hash table (#5738)

 * Detect the correct gtk-doc when cross-compiling (#5650)

 * Detect the correct wayland-scanner when cross-compiling (#5596)

 * Documentation improvements (#5659, #5677, #5682, #5664, #5719)

 * Skip more tests when FUSE isn't available (#5611)

 * Translation updates (#5602, #5707)

Changes in 1.15.6
~~~~~~~~~~~~~~~~~
Released: 2023-11-14

Dependencies:

 * In distributions that compile Flatpak to use a separate bubblewrap (bwrap)
   executable, version 0.8.0 is now required.

 * Enabling the optional Wayland security context feature requires
   libwayland-client, wayland-scanner >= 1.15 and wayland-protocols >= 1.32.

 * Ubuntu 18.04 is no longer routinely tested. Support for dependency
   versions included in Ubuntu 18.04 should be considered "at risk".

Features:

 * Add --device=input, for access to evdev devices in /dev/input (#5481)

 * Update bundled copy of bubblewrap to version 0.8.0, and rely on its
   features:
     * Improve error message if seccomp is disabled in kernel config
     * Security hardening: set user namespace limit to 0, to prevent creation
       of nested user namespaces in a more robust way (#5084)

 * For subsandboxes started by flatpak-portal, inherit environment
   variables from the `flatpak run` that started the original instance
   rather than from flatpak-portal, fixing behaviour of FLATPAK_GL_DRIVERS
   and similar features (#5278)

 * Stop http transfers if a download in progress becomes very slow (#5519)

 * Make it easier to configure extra languages, by picking them up from
   AccountsService if configured there (#5006)

 * Add new flatpak_transaction_add_rebase_and_uninstall() API,
   allowing end-of-life apps to be replaced by their intended replacement
   more reliably (#3991)

 * Create a private Wayland socket with the "security context" extension
   if available, allowing the compositor to identify connections from
   sandboxed apps as belonging to the sandbox (#4920, #5507, #5558)

 * Update libglnx to 2023-08-29
     * Use features of newer GLib versions if available
     * Turn off system-level crash reporting infrastructure during
       some unit tests that involve intentional assertion failures

 * Add anchors to link to sections of flatpak-metadata documentation (#5582)

 * New translations: ka, nl.

Bug fixes:

 * Avoid warnings processing symbolic links with GLib >= 2.77.0, and
   with GLib 2.76.0 (GLib 2.76.1 or later silences these warnings)

 * Bypass page cache for backend requests in revokefs, fixing installation
   errors with libostree 2023.4 (#5452)

 * Show AppStream metadata in `flatpak remote-info` as intended
   (#5523; regression in 1.9.1)

 * Don't let Flatpak apps inherit VK_DRIVER_FILES or VK_ICD_FILENAMES
   from the host system, which would be wrong for the sandbox (#5553)

 * Fix build failure with prereleases of libappstream 0.17.x (#5472)

 * Forward-compatibility with libappstream 1.0 (#5563)

 * Fix installation with Meson if configured with -Dauto_sideloading=true
   (#5495)

 * Fix a memory leak (#5329)

 * Fix compiler warnings (#5362, #5366)

 * Make the tests fail more comprehensibly if a required tool is missing
   (#5020)

 * Clean up `/var/tmp/flatpak-cache-*` directories on boot (#1119)

 * Don't force `GIO_USE_VFS=local` for programs launched via flatpak-spawn
   (#5567)

 * Clarify documentation for D-Bus name ownership (#5582)

 * Translation updates: id, tr, zh_CN
   (#5332, #5565)

Internal changes:

 * Split up large source files into smaller modules, reducing internal
   circular dependencies (#5410, #5411, #5415, #5419, #5416, #5414)

 * Re-synchronize code backported from GLib with the version in GLib
   (#5410)

 * Make the flags used to apply "extra data" clearer (#5466)

 * Use glnx_opendirat() where possible (#5527)

 * CI improvements (#5374, #5381)

Changes in 1.15.4
~~~~~~~~~~~~~~~~~
Released: 2023-03-16

Security fixes:

* Escape special characters when displaying permissions and metadata,
  preventing malicious apps from manipulating the appearance of the
  permissions list using crafted metadata (CVE-2023-28101).

* If a Flatpak app is run on a Linux virtual console (tty1, tty2, etc.),
  don't allow copy/paste via the TIOCLINUX ioctl (CVE-2023-28100).
  Note that this is specific to virtual consoles: Flatpak is not
  vulnerable to this if run from a graphical terminal emulator such as
  xterm, gnome-terminal or Konsole.

Other bug fixes:

* Document the path used for `flatpak override`
* Translation updates: oc, pl, ru, sv, tr

Changes in 1.15.3
~~~~~~~~~~~~~~~~~
Released: 2023-02-21

Build system:

* Building this version of Flatpak with Meson is recommended. The source
  release flatpak-1.15.3.tar.xz no longer contains Autotools-generated
  files, although this version can still be built using Autotools after
  running `./autogen.sh`. Future versions are likely to remove the
  Autotools build system.

Bug fixes:

* When splitting an upgrade into two steps (download without installing, and
  then upgrade without allowing further downloads) like GNOME Software does,
  if an app is marked EOL and superseded by a replacement, don't remove the
  superseded app in the first step, which would result in the replacement
  incorrectly not being installed (#5172)
* Fix a crash when --socket=gpg-agent is used (#5095)
* Fix a crash when listing apps if one of them is broken or misconfigured
  (#5293)
* If an app has invalid syntax in its overrides or metadata, mention the
  filename in the error message (#5293)
* Unset $GDK_BACKEND for apps, ensuring GTK apps with --socket=fallback-x11
  can work (#5303)
* Fix a deprecation warning when compiled with curl >= 7.85 (#5284)
* Translation updates: es, ru (#5266, #5312, #5313)

Internal changes:

* Better diagnostic messages for why runtimes are or are not considered
  unused (#5237)

Changes in 1.15.2
~~~~~~~~~~~~~~~~~
Released: 2023-02-06

Bug fixes:

* Never try to export a parent of reserved directories as a --filesystem,
  for example /run, which would prevent the app from starting (#5205, #5207)
* Never try to export a --filesystem below /run/flatpak or /run/host,
  which could similarly prevent the app from starting
* The above change also fixes apps not starting if a --filesystem is a
  symlink to the root directory (#1357)
* Show a warning when the --filesystem exists but cannot be shared with
  the sandbox (#1357, #5035, #5205, #5207)
* Display the intended messages for `flatpak repair` (#5204)
* Exporting an app to an existing repository on a CIFS filesystem
  now works as intended (#5257)
* Unset $GIO_EXTRA_MODULES for apps, avoiding misbehaviour in some GLib
  apps when set to a path on the host (#5206)
* Unset $XKB_CONFIG_ROOT for apps, avoiding crashes in GTK and Qt apps
  under Wayland when this variable is set to a path not available in the
  sandbox (#5194)
* When using the fish shell, avoid duplicate XDG_DATA_DIRS entries if the
  profile script is sourced more than once (#5198)
* Update included copy of bubblewrap to 0.7.0 for better error messages
* Install SELinux files correctly when building with Meson
* Translation updates: ru, tr (#5256, #5262)

Internal changes:

* Update included copy of libglnx
* flatpak -v now uses the INFO log level, and flatpak -vv uses the
  DEBUG log level in the flatpak log domain. Previously, the extra
  messages that were logged by flatpak -vv were in a separate "flatpak2"
  log domain. G_MESSAGES_DEBUG=flatpak previously had an effect similar to
  flatpak -v, and is now more similar to flatpak -vv. (#5001)

Changes in 1.15.1
~~~~~~~~~~~~~~~~~
Released: 2022-11-17

Dependencies:

* When building with Meson, gpgme 1.8.0 is now required.
  Older versions can still be used by building with Autotools.

Features:

* If an old temporary deploy directory was leaked by versions before #5146,
  clean it up the next time the same app is updated (#5164)

Bug fixes:

* If an app update is blocked by parental controls policies, clean up the
  temporary deploy directory (#5146)
* Fix Autotools build with versions of gpgme that no longer provide
  gpgme-config(1) (#5173)
* Fix a possible parallel build failure with Meson (#5165)
* Fix a compiler warning on 32-bit architectures (#5148)
* When building with Autotools, be more consistent about applying compiler
  warning flags (#5149)
* Unset $TEMP, $TEMPDIR and $TMP for apps, the same as $TMPDIR (#5168)
* Treat /efi the same as /boot/efi (#5155)

Changes in 1.15.0
~~~~~~~~~~~~~~~~~
Released: 2022-10-24

Build system:

* Flatpak can now be compiled using Meson instead of Autotools.
  This requires Meson 0.53.0 or later, and Python 3.5 or later.
  The Autotools build system is likely to be removed during either the
  1.15.x or 1.17.x cycle. (#4845)

New features:

* Allow the `modify_ldt` system call as part of `--allow=multiarch`.
  This increases attack surface, but is required when running 16-bit
  executables in some versions of Wine. (#4297)
* Share gssproxy socket, which acts like a portal for Kerberos authentication.
  This lets apps use Kerberos authentication without needing a sandbox hole.
  (#4914)
* Add a httpbackend variable to flatpak.pc, allowing dependent projects
  like GNOME Software to detect whether they are compatible with libflatpak
  (#5054)

Bug fixes:

* Terminate the flatpak-session-helper and flatpak-portal services when the
  session ends, so that applications will not inherit outdated Wayland
  and X11 socket addresses (#5068)
* When using `fish` shell, don't overwrite a previously-set XDG_DATA_DIRS
  (#5123)
* Don't try to enable HTTP 2 if linked to a libcurl version that doesn't
  support it (#5074)
* Stop systemd reporting the session-helper as failed when terminated by
  a signal (#5129)
* Fix a warning when listing a document with no permissions (#5055)
* Fix compilation with GLib 2.66.x (as used in Debian 11) (#5062)
* Fix compilation with GLib 2.58.x (as used in Debian 10) (#5066)
* Make generated files more reproducible (#5085)
* Translation updates: cs, id, pl, pt_BR (#5052, #5056, #5059, #5126)

Internal changes:

* Update project logo in README (#5119)
* Update libglnx subproject (#5140)

Changes in 1.14.0
~~~~~~~~~~~~~~~~~
Released: 2022-08-22

Known issues:
* There may be an issue where non-primary architecture builds don't show up
  (https://github.com/flatpak/flatpak/issues/5045)
* There is a new security advisory on Flatpak but all supported versions are
  not affected due to using new enough versions of libostree
  (https://github.com/flatpak/flatpak/security/advisories/GHSA-45jq-5658-v38x)

Dependencies:

* Conditional on a build time option, revokefs will now use version 3 of the
  FUSE API rather than version 2 (#4326)
* Libappstream should be updated to at least 0.15.3 to avoid critical warning
  messages when using the "flatpak search" command
  (https://github.com/ximion/appstream/issues/384)

New features:

* A new key "DeploySideloadCollectionID" is now supported in flatpakref and
  flatpakrepo files, to allow setting a collection ID at the time a remote is
  added from one of those files, rather than when metadata is pulled from the
  remote, and without affecting versions of Flatpak with the older pre-sideload
  P2P implementation (#4826)
* Allow sub-sandboxes to own MPRIS names on the session bus (#5023)
* Commands that accept "--user" will now also take "-u" as an alias for that
  (#5014)
* The CLI now properly informs the user of which apps are (indirectly) using
  end-of-life runtime extensions in end-of-life info messages (#4835)
* The CLI now takes into account operations in the pending transaction when
  printing end-of-life messages (#4835)
* The uninstall command now asks for confirmation before removing in-use
  runtimes or runtime extensions (#4835)
* A "--socket=gpg-agent" option is now recognized by "flatpak run" and related
  commands (#4958)

Bug fixes:

* Fix a memory corruption issue caused by use of libcurl in an unsafe way
  (#5046)
* Update selinux policy to cover symbolic links in /var/lib/flatpak (#4992)
* Fix a crash in case a .desktop file processed by the build-export command has
  no Exec= key, and some related fixes for handling such .desktop files (#4817)
* Preserve the X11 display number rather than redirecting it to :99 (#5034)

Other changes:

* Various improvements to the unit tests, CI infra, and documentation
* Some changes were made to ensure translators can work on full sentences
  rather than fragments in several places
* Translation updates: de, ru, sv, tr, uk, zh_CN

Changes in 1.13.3
~~~~~~~~~~~~~~~~~
Released: 2022-06-16

Dependencies:

 * Support curl 7.29 or later as an additional, and the default, HTTP backend
   alongwith libsoup 2.x (#4943)
 * Clarify that glib 2.46 or later is now required (#4944)

New features:

 * Implement support for rewriting dynamic launchers when an app is renamed
   (#4703)
 * Add --include-sdk/debug options to install command to install SDK/debuginfo
   along with a ref (#4777)
 * Improve --sideload-repo option to take create-usb dirs (#4843)
 * Add a new library API flatpak_transaction_get_operation_for_ref() (#4947)

Bug fixes:

 * Update the SELinux module to explicitly permit the system helper have read
   access to /etc/passwd and systemd-userdbd, read and lock access to
   /var/lib/flatpak, and watch files inside $libexecdir (#4852, #4855, #4892)
 * Fix the error messages and the exit code of the 'uninstall' command when
   non-existent refs are specified (#4857)
 * Be more careful with errors when creating directories and deleting files,
   and address some memory errors (#4930)
 * Fix support for --noninteractive in the 'uninstall' command (#4947)

Other changes:

 * Cosmetic improvements to end-of-life messages and other aspects of the CLI
   output (#4947)
 * Speed up the tests by not installing the polkit agent (#4942)
 * Disable fuzzy ref matching when ID has a period or a slash, or when the
   standard input or output is not a TTY (#4829, #4848)
 * Update the icon-validator to print the format and size for consumption by
   the dynamic launcher portal (#4803, #4808)
 * Remove a pointless test (#4856)
 * Improve various details of the GitHub workflows (#4870)
 * Prepare for the addition of a Meson build (#4842, #4871, #4888, #4889, #4890)
 * Only add the specified 'summary-arches' to the compat summary. This is
   important since we're nearing the 10MB size limit for Flathub's legacy
   summary files. (#4880)
 * Translation updates: id, pt, sv, tr, uk

Changes in 1.13.2
~~~~~~~~~~~~~~~~~
Released: 2022-03-14

Bug fixes:

 * Consistently pass relative subpaths to libostree, working around a bug
   in libostree < 2021.6 when used with GLib >= 2.71 (#4805)
 * Document have-kernel-module-* as having been added in 1.13.1
 * Fix some memory leaks in GVariant data processing

Changes in 1.13.1
~~~~~~~~~~~~~~~~~
Released: 2022-03-01

Dependencies:

 * libappstream 0.12.0 or later is now required
 * appstream-glib is no longer required
 * In distributions that compile Flatpak to use a separate bubblewrap (bwrap)
   executable, version 0.5.0 is now required

New features:

 * Create a directory for XDG_STATE_HOME and set the environment variable
   (#4477)
   - Apps requiring a state directory without a dependency on this updated
     Flatpak version can get similar functionality by using:
     --persist=.local/state --unset-env=XDG_STATE_HOME
     which will use the same storage location
 * Set HOST_XDG_STATE_HOME environment variable (#4477)
 * Add have-kernel-module-foo family of conditionals for extensions, a
   generalization of have-intel-gpu (which is now mostly equivalent to
   have-kernel-module-i915) (#4647)
 * Add `flatpak document-unexport --doc-id=...` (#1897)
 * Export Appstream metadata for host system to use (#4350, #4599)
 * Add command-line completion for the Fish shell (#3109)
 * Add FlatpakTransaction:no-interaction API (#4699)
 * We now allow networked access to X11 and PulseAudio services
   if that is configured, and the application has network access.
   (#397, #3908, #4702)
 * `flatpak build-init` automatically sets the build directory to be
   ignored by git (#4741)

Other changes:

 * Updated bundled xdg-dbus-proxy to 0.1.3 (#4737)
 * Updated bundled bubblewrap to 0.6.1 (#4779)
 * The default branch in the Github repository is now named 'main'
 * Don't offer options in CLI tab completion unless the user typed a '-'
   (#4753)
 * Disable fancy output (e.g. progress bars that get redrawn) when
   G_MESSAGES_DEBUG is set in the environment (#4767)
 * Most commands now work if /var/lib/flatpak exists but /var/lib/flatpak/repo
   does not, and will automatically populate the repo directory if
   possible (#4111)
 * Disable session bus access for `flatpak-spawn --sandbox` as intended
   (#4630)
 * Make `sudo flatpak --user ...` fail with an error message, since acting
   on root's per-user installation is unlikely to be what was intended
   (#4638)
 * Don't mention "negative" permissions like !host in /.flatpak-info (#4691)
 * Improve performance when finding related refs
 * Use SHA256 instead of SHA1 to avoid false-positives from static analysis
   (in fact the use of SHA1 was not security-sensitive here) (#4716)
 * Create sandbox's XDG_RUNTIME_DIR with 0700 permissions (#3397)
 * Always create /.flatpak-info with 0600 permissions
 * Absolute paths in WAYLAND_DISPLAY now work (#4752)
 * Improve reliability of detecting the current GTK theme (#4754)
 * Fix some error code paths when deploying malformed apps
 * Improve some error messages
 * Use URN for fontconfig DTD, consistent with fontconfig itself (#4617)
 * Use `type -P` or `command -v` in preference to which(1) (#4696)
 * Improve measurement of test coverage (#4681)
 * Translation updates: de, fr, hi, hr, id, oc, pl, pt_BR, sv, uk, zh_CN

Changes in 1.12.6
~~~~~~~~~~~~~~~~~
Released: 2022-02-21

 * Fix a bug that sometimes caused repo corruption in case downloads are
   interrupted or canceled, necessitating a "flatpak repair" to recover
   (#3479, #4258)
 * More reliably detect the GTK theme (#4754)
 * Fix history command unit test in some edge cases (#4764)
 * Improve NEWS for 1.12.5
 * Translation update: pt_BR

Changes in 1.12.5
~~~~~~~~~~~~~~~~~
Released: 2022-02-11

 * Fixed a case where temporary data was sometimes left in
   /var/lib/flatpak/appstream, and we now detect such leftover data and
   remove it. (#4735)
 * Fix regressions in `flatpak history` since 1.9.1 (#4121, #4332)
   - Don't display the appstream branch used internally
   - Don't display temporary repositories used internally
   - Warn instead of failing if other non-app, non-runtime refs are found
   - Don't set up an unnecessary polkit agent for `flatpak history`
   - Add test coverage
 * Don't propagate GStreamer-related environment variables into
   sandbox (#4728)
 * Fix a typo in an error message
 * Fix incorrect year in NEWS for 1.12.4 release
 * Translation update: pl

Changes in 1.12.4
~~~~~~~~~~~~~~~~~
Released: 2022-01-18

This is a regression fix update, reverting non-backwards-compatible
behaviour changes in the solution previously chosen for CVE-2022-21682.

Flatpak 1.12.3 and 1.10.6 changed the behaviour of `--nofilesystem=host`
and `--nofilesystem=home` in a way that was not backwards-compatible in
all cases. For example, some Flatpak users previously used a global
`flatpak override --nofilesystem=home` or
`flatpak override --nofilesystem=host`, but expected that individual apps
would still be able to have finer-grained filesystem access granted by the
app manifest, such as Zoom's `--filesystem=~/Documents/Zoom:create`. With
the changes in 1.12.3, this no longer had the intended result, because
`--nofilesystem=home` was special-cased to disallow inheriting the
finer-grained `--filesystem`.

Flatpak 1.12.4 and 1.10.7 return to the previous behaviour of
`--nofilesystem=host` and `--nofilesystem=home`. Instead, CVE-2022-21682
will be resolved by a new 1.2.2 release of flatpak-builder, which will
use a new option `--nofilesystem=host:reset` introduced in Flatpak 1.12.4
and 1.10.7. In addition to behaving like `--nofilesystem=host`, the new
option prevents filesystem permissions from being inherited from the
app manifest.

Other changes:

 * Clarify documentation of `--nofilesystem`
 * Improve unit test coverage around `--filesystem` and `--nofilesystem`
 * Restore compatibility with older appstream-glib versions, fixing a
   regression in 1.12.3

Changes in 1.12.3
~~~~~~~~~~~~~~~~~
Released: 2022-01-12

This is a security update that fixes two issues that were found in flatpak:

https://github.com/flatpak/flatpak/security/advisories/GHSA-qpjc-vq3c-572j
(also known as CVE-2021-43860)

This issue is about the possibility for a malicious repository to send
invalid application metadata in a way that hides some of the app
permissions displayed during installation.

https://github.com/flatpak/flatpak/security/advisories/GHSA-8ch7-5j3h-g4fx
(also known as CVE-2022-21682)

This issue is a problem with how flatpak-builder uses flatpak, that
can cause `flatpak-builder --mirror-screenshots-url` commands to be
allowed to create directories outside of the build directory.

The fix for this is done in flatpak by making the --nofilesystem=host
and --nofilesystem=home more powerful. They previously only removed
access to the particular location, i.e. `--nofilesystem=host` negated
`--filesystem=host`, but not `--filesytem=/some/dir`. This is a minor
change in behavior, as it may change the behavior of an override
with these specific options, however it is likely that the new
behavior was the expected one.

Other changes:

 * Extra-data downloading now properly handles compressed content-encodings
   which fixes checksum verification (see #4415)
   Note: In some corner case server setups this may require the extra-data
   checksum to be changed
 * Avoid unnecessary policy-kit dialog due to auto-pinning when installing runtimes
 * Better handling of updates of extensions that exist in multiple repositories
 * Fixed (initial) installation apps with renamed ids
 * Support more pulseaudio configuration, including the one used in WSL2
 * Fixed regression in updates from no-enumerate remotes
 * We now verify checksums of summary caches, to better handle local file
   corruption
 * Improved cli output for non-terminal targets
 * Flatpak run --session-bus now works
 * Fix build with PyParsing >= 3.0.4
 * Fixed "Since" annotations on FlatpakTransaction signals
 * bash auto completion now doesn't complete on command name aliases
 * Minor improvements to the search command
 * Minor improvements to the list command
 * Minor improvements to the repair command
 * Add more tests
 * Updated translations and docs

Changes in 1.12.2
~~~~~~~~~~~~~~~~~
Released: 2021-10-12

 * Install translations referenced by LANG, LANGUAGE or LC_ALL
 * Fix error handling for the syscalls that are blocked when not using --devel
 * Improve diagnostic messages when seccomp rules cannot be applied
 * Update Polish translation

Changes in 1.12.1
~~~~~~~~~~~~~~~~~
Released: 2021-10-08

The security fix in the 1.12.0 release failed when used with some
older versions of libseccomp (that don't know about the new syscalls).

More specifically, installing modules that use extra-data would fail, and so
would running applications with the --allow=multiarch feature, such as Steam.
This release fixes those regressions.

Changes in 1.12.0
~~~~~~~~~~~~~~~~~
Released: 2021-10-08

This is the first stable release in the 1.12.x series. The major changes
in this series is the support for better control of sub-sandboxes, as
used by the Steam Flatpak app to run Windows games under Proton.

In addition, this release fixes a security vulnerability in the portal
support. Some recently added syscalls were not blocked by the seccomp rules
which allowed the application to create sub-sandboxes which can confuse
the sandboxing verification mechanisms of the portal. This has been
fixed by extending the seccomp rules. (CVE-2021-41133)
For details, see:
  https://github.com/flatpak/flatpak/security/advisories/GHSA-67h7-w3jq-vh4q

Other changes in this version:
 * Some test fixes
 * Update translations
 * Support for specifying the flatpak binary to use during exports
 * Install translations for all languages in the locale, not just the ones in
   LC_MESSAGES.
 * Fix progress reporting in flatpak fsck
 * Handle cases where /var/tmp is a symlink
 * Expose /etc/gai.conf to the sandbox
 * Fix the parental control checks for root
 * Handle missing /etc/ld.so.cache (musl)

Changes in 1.11.3
~~~~~~~~~~~~~~~~~
Released: 2021-08-25

Dependencies:

* For Linux distributions that compile Flatpak to use a separate
    bubblewrap (bwrap) executable, updating to version 0.5.0 is recommended,
    but not required. The minimal version is still 0.4.0.

Bug fixes:

* Don't inherit an unusual $XDG_RUNTIME_DIR setting into the sandbox, fixing
  a regression introduced when CVE-2021-21261 was fixed in 1.8.5 and 1.10.0
* Update the included copy of bubblewrap (flatpak-bwrap) to 0.5.0
    - Better diagnostics when a --bind or other bind-mount fails
    - Create non-directories with safer permissions
    - Allow mounting an non-directory over an existing non-directory
    - Silence kernel messages for our bind-mounts
    - Improve ability to bind-mount directories on case-insensitive filesystems
* Don't ask user which remote to download from if there is only one option
* Improve robustness of autogen.sh

Internal changes:

* Improve test coverage
* Spelling fixes

Translation updates: Brazilian Portuguese, Russian, Spanish, Ukrainian

Changes in 1.11.2
~~~~~~~~~~~~~~~~~
Released: 2021-06-17

Bug fixes:

* Fix logic error when migrating AppStream XML
* Improve error-checking
* Fix various memory and file descriptor leaks, in particular with
  flatpak-spawn --env=...
* Fix fd confusion in flatpak-spawn --env=... --forward-fd=..., which
  caused "Steam Linux Runtime" containers to fail to start
* Avoid a crash when looking up summary for a ref without an arch
* Improve handling of refs belonging to more than one architecture,
  e.g. for cross-compilation
* Don't abort uninstall if deploy metadata is missing
* Don't fail transaction if searching for dependencies fails in one remote
* Fix test failure when running tests as root
* Improve error message for 'sudo flatpak run'

Internal changes:

* Improve printf format string validation
* Improve test coverage
* Reduce risk of accidentally hard-coding x86 in the tests

Translation updates: Danish, Indonesian, Russian

Changes in 1.11.1
~~~~~~~~~~~~~~~~~
Released: 2021-04-26

This is the first unstable release in the series that will lead to 1.12.

New features:

* All instances of the same app-ID share their /tmp directory
* All instances of the same app-ID share their $XDG_RUNTIME_DIR
* Instances of the same app-ID can optionally share their /dev/shm directory
  (enabled by a new --allow flag, --allow=per-app-dev-shm)
* Allow a subsandbox to have a different /usr and/or /app.
  Steam will use this to launch games with its own container runtime
  as /usr (the "Steam Linux Runtime" mechanism).
* enter: Improve support for TUI programs like gdb
* build-update-repo: Add a higher-performance reimplementation of
  `ostree prune` specialized for archive-mode repositories

Bug fixes:

* Fix deploys of local remotes in system-helper
* Fix test failures on non-x86_64 systems
* Fix two intermittent test failures
* Make polkit queries non-interactive when operating in non-interactive mode
* Use a local main-context when using libsoup in a thread
* create-usb: Skip copying extra-data flatpaks
* OCI: Switch to pax-format tar archives
* history: Handle transaction log entries with empty REF field
* portal: Fix flatpak-spawn --clear-env on OSs where flatpak is not on
  the fallback PATH, such as NixOS
* Fix various issues detected by scan-build

Internal changes:

* Use GNU bison to build parse-datetime.y
* Add information about security support and security vulnerability
  reporting (see `SECURITY.md`)
* Move all git submodules into subprojects/ directory
* Several sockets are now created in /run/flatpak in the sandbox, with
  symbolic links in $XDG_RUNTIME_DIR

Changes in 1.10.2
~~~~~~~~~~~~~~~~~
Released: 2021-03-10

This is a security update which fixes a potential attack where
a flatpak application could use custom formatted .desktop files to
gain access to files on the host system.

Other changes:

* Fix memory leaks
* Some test fixes
* Documentation updates
* G_BEGIN/END_DECLS added to library headers for c++ use
* Fix for X11 cookies on OpenSUSE
* Spawn portal better handles non-utf8 filenames

Changes in 1.10.1
~~~~~~~~~~~~~~~~~
Released: 2021-01-21

 * Fix flatpak build on systems with setuid bwrap
 * Fix some compiler warnings
 * Add --enable-asan configure option
 * Fix crash on updating apps with no deploy data
 * Update translations

Changes in 1.10.0
~~~~~~~~~~~~~~~~~
Released: 2021-01-14

This is the first stable release after the 1.9.x unstable series.
The major new feature in this series compared to 1.8 is the support
for the new repo format which should make updates faster and download
less data.

This release also contains the security fixes from 1.8.5, so everyone
on the 1.9.x series should update immediately. (CVE-2021-21261)

Other changes since 1.9.3:

 * The systemd generator snippets now call flatpak --print-updated-env
   in place of a bunch of shell for better login performance.
 * The .profile snippets now disable GVfs when calling flatpak to
   avoid spawning a gvfs daemon when logging in via ssh.
 * Build fixes for GCC 11.
 * Flatpak now finds the pulseaudio sockets better in uncommon
   configurations.
 * Sandboxes with network access it now also has access to the
   systemd-resolved socket to do dns lookups.
 * Flatpak supports unsetting env vars in the sandbox using --unset-env,
   and `--env=FOO=` now sets FOO to the empty string instead of
   unsetting it.
 * Similarly the spawn portal has an option to unset an env var.
 * The spawn portal now has an option to share the pid namespace
   with the sub-sandbox.

Changes in 1.9.3
~~~~~~~~~~~~~~~~
Released: 2020-12-22

I expect this to be the final 1.9.x release, and we can expect 1.10.0
early next year, containing basically what's in this release in terms
of features.

A minor change in the new indexed summary format in this release. The
gpg signature of the summary index is now stored in a filename indexed
by the checksum of the index rather than a static filename. This fixes
an update race between clients accessing the two files during and update.
It also helps in keeping mirrors and cached coherent. The old filename
is still created/used for backwards compat with 1.9.1, but may go
away in the future.

Other changes:

 * --filesystem=host now exposed /var/usrlocal (as seen on ostree)
 * Better error messages in flatpak portal.
 * Rebases during update now install the new app before uninstalling
   the old, which means failure during the first doesn't leave the app
   uninstalled.
 * flatpak_installation_list_installed_refs_for_update() now handles
   some case better when apps in the user installation depends on
   runtimes in the system installation.
 * New version of the deploy files which guarantees the existence of
   a bit more data. This is useful for eol detection of apps that were
   installed with previous flatpak versions.
 * Some corner cases when installing an app with extra-data into a nonstandard
   installation were fixed.
 * Fixed crashed when killing and entering running instance that have
   was running a runtime, not an app.
 * The root user can now bypass parental controls.
 * Some fixes to library annotations.
 * Updated translations

Changes in 1.9.2
~~~~~~~~~~~~~~~~
Released: 2020-11-20

 * Some build fixes on non-x86-64 arches
 * Fix permission issue in endless installer
 * Fixed a bug where flatpak was accidentally clearing the summary cache
   during updates in the user installation.
 * Fix handling of the multiarch permission.,
 * Add back the commit timestamp to the summary file.

Changes in 1.9.1
~~~~~~~~~~~~~~~~
Released: 2020-11-19

This is the first unstable release in the series that will lead to
1.10. The main change in this version is a new format for the summary
file used when accessing an OSTree repository on the network. For this
reason we now require OSTree version 2020.8.

The new format should make getting the initial metadata required for
most flatpak operations much faster, and use less network
bandwidth. This will allow repositories to scale to more apps and more
architectures without affecting clients. The old format is still
generated for compatibility with older clients.

The new format also allows repositories to publish named subsets, and
for clients to declare that they only want to see that subset. The
goal here is to allow for example flathub to mark all FOSS apps, and
make it possible for users to use a flathub-foss remote without
flathub having to maintain two duplicated repositories. This is
accessible by passing --subset=SUBSET to the build-commit-from and
build-export commands.

The new repo option `flatpak.summary-arches` controls which architectures
are put in the old format summary. This can be used to avoid newly added
architectures making old clients slower, at the cost of requiring a newer
flatpak client version for the new architecture.

Other major changes
 * There is a new `flatpak pin` command that lets you pin runtimes
   so that they are not considered unused. Also, we now by default pin
   runtimes that are installed explicitly (i.e. not as a dependency of an
   app).
 * During a regular update or uninstall of an app, if the operation
   makes a previously used runtime unused, and the runtime is marked
   as end-of-lifed, then the runtime is automatically uninstalled.
 * During `flatpak update` (i.e. with no specific app given) flatpak
   now automatically adds uninstall operations for end-of-life runtimes
   that are unused.
 * The end-of-life warnings in the flatpak CLI are now better, showing
   more useful details (like version and what apps are using the runtime)
   and less useless details.
 * Some changes was made in which dconf paths were considered "similar"
   to the app id, allowing for example `org.gnome.SoundJuicer` to
   migrate from `/org/gnome/sound-juicer`.
 * Flatpak run now implements the new standard for os-release in containers
   (https://www.freedesktop.org/software/systemd/man/os-release.html).
 * There is now a tcsh profile snippet
 * The origin remote for an app is now prioritized over other remotes with
   the same priority when looking for dependencies.
 * We now allow extra-data apply_extra processes to run multiarch code.
 * A new internal representation for ostree ref strings was added which
   is more efficient. This should not affect the behaviour of flatpak
   but the large amounts of changes to use this may have accidentally
   introduced regressions.
 * Some fixes to the in-memory summary cache make it more efficient.
 * --filesystem=/ is now explicitly forbidden as it doesn't work (and never
   did).
 * Flatpak install/update now only prints `(partial)` for an update that
   actually is partial (not just for all locales).
 * Flatpak remote-ls on a file: uri (for example a sideloaded repo) now
   correctly lists the refs in the repo.
 * New library APIS: flatpak_installation_list_pinned_refs,
   flatpak_transaction_set_disable_auto_pin,
   flatpak_transaction_set_include_unused_uninstall_ops,
   flatpak_transaction_operation_get_subpaths,
   flatpak_transaction_operation_get_requires_authentication.
 * flatpak_installation_list_installed_refs_for_update() now returns
   refs that have a end-of-life rebase that it could be updated to.
 * There is a new `ready-pre-auth` signal in FlatpakTransaction allowing
   clients new ways to handling authentication.
 * Fix bug where extension sources were sometimes auto-installed

Changes in 1.8.3
~~~~~~~~~~~~~~~~
Released: 2020-11-17

  * Fixed progress reporting for OCI and extra-data
  * The in-memory summary cache is more efficient
  * Fixed authentication getting stuck in a loop in some cases
  * Fixed authentication error reporting
  * We now extract OCI info for runtimes as well as apps
  * Fixed crash if anonymous authentication fails and -y is specified
  * flatpak info now only looks at the specified installation
    if one is specified
  * Better error reporting for server HTTP errors during download
  * Uninstall now removes applications before the runtime it depends on
  * Fixed test-suite to pass with the latest OSTree version
  * Fixed dbus environment variables in flatpak enter
  * Avoid updating metadata from the remote when uninstalling
  * Fixed error message handling in various places
  * FlatpakTransaction now verifies all passed in refs to avoid
    potential issues with invalid names
  * Updated translations

Changes in 1.8.2
================

 * Added validation of collection id settings for remotes
 * Fix seccomp filters on s390
 * Robustness fixes to the spawn portal
 * Fix support for masking update in the system installation
 * Better support for distros with uncommon models of merged /usr
 * Cache responses from located/AccoutService
 * Fix hangs in cases where xdg-dbus-proxy fails to start
 * Fix double-free in cups socket detection
 * OCI authenticator now doesn't ask for auth in case of http errors

Changes in 1.8.1
================

 * Avoid calling authenticator in update if ref didn't change
 * Don't fail transaction if ref is already installed (after transaction start)
 * Fix flatpak run handling of userns in the --device=all case
 * Fix handling of extensions from different remotes
 * Fix flatpak run --no-session-bus
 * Updated translations

Changes in 1.8.0
================

New stable release series 1.8.

Changes:
 * FlatpakTransaction has a new signal "install-authenticator" which clients can handle to
   install authenticators needed for the transaction. This is done in the CLI commands.
 * We now always expose the host timezone data, allowing us the expose the host /etc/localtime
   in a way that works better, fixing several apps that had timezone issues.
 * Fix flatpak enter which didn't work in some cases.
 * We now ship a systemd unit (not installed by default) to automatically detect plugged in
   usb sticks with sideload repos.
 * By default we no longer install the gdm env.d file, as the systemd generators work better
 * create-usb now exports partial commits by default
 * Fix handling of docker media types in oci remotes
 * Fix subjects in remote-info --log output

Changes in 1.7.3
================

 * Allow direct ALSA device access if app has pulseaudio access.
 * Flatpak now ships a sysusers.d file for allowing systemd to create the required users.
 * Fix issue in remote-delete where it failed to delete system remotes if it had to uninstall
   something first.
 * New library calls flatpak_transaction_operation_get_related_to_ops(), flatpak_transaction_operation_get_is_skipped() and
   flatpak_transaction_set_no_interaction().
 * New options --[no-]follow-redirect in remote-add/modify
 * New spawn portal APIs to get real pid of launched app.
 * By default, all OCI remotes now use the flatpak-oci-authenticator.
 * Support flatpak remote-info and flatpak update --commit= to specific versions for OCI remotes.
 * Initial work in progress on using deltas for OCI remotes.
 * Fix race in the generation of ld.so.cache when starting copies of the same app at the same time.
 * Minor fix in what locales are installed on update.
 * Flatpak uninstall now doesn't fail if one ref (of many) was not installed.
 * Flatpak systemd transient units now have an app-prefix to match new XDG spec for
   cgroup names.
 * In some cases we previously downloaded the summary twice.
 * flatpak upgrade is now an alias for flatpak update.
 * Fix to selinux module to work without unconfined module.
 * Respect user XDG basedirs when finding users fonts and icons.
 * Fix issue where thread were sometimes initialized causing flatpak enter to fail.
 * Better error reporting when authentication goes wrong.

Changes in 1.7.2
================

This fixes some regressions in progress reporting in 1.7.1, where it would report > 100%.

Other changes:
 * Completion support for fish shell
 * Properly handle migration of remotes with collection ids
 * The summary now has some extra-data download size info which can make downloads slightly more efficient

Changes in 1.7.1
================

This is the first release in the 1.7.x unstable release series.

A major change is that the support for the ostree peer-to-peer installation has been
simplified. Flatpak no longer supports installing from local network peers, and sideloading
from local usb stick is no longer automatic. To enable sideloading you have to configure
a sideload repository by creating a symlink to it from /var/lib/flatpak/sideload-repos or
/run/flatpak/sideload-repos. Due to this the flatpak code has been simplified internally
and the p2p support is more efficient.

Other major changes
 * If an app has filesystem access, the host /lib is accessible as /run/host/lib, etc.
 * New filesystem permission "host-etc" and "host-os" give access to system /usr and /etc.
 * Flatpak now uses variant-schema-compiler to generate more efficient code for
   parsing GVariant files from ostreee.
 * libsystemd use is now optional in configure.
 * Journal sockets are mounted readonly
 * document-export now supports exporting directories (requires new portal version)
 * DConf migration now allows version numbers in object paths

Changes in 1.6.3
================

The main change in this version is a fix for a regression in the progress calculation
for applications using extra-data. Additionally the bundled version of bubblewrap
is updated to 0.4.1 which fixes a security issue in some cases. See
  https://github.com/containers/bubblewrap/security/advisories/GHSA-j2qp-rvxj-43vj
for details.

Other changes:
 * Updated translations
 * Don't break if users primary gid is not in the nsswitch database
 * Fix crash in flatpak repair if no remotes are configured
 * Some updates to the oci authenticator
 * Retry downloads of extra data

Changes in 1.6.2
================

Due to a combination of some behaviour in flatpak and recent versions of ostree we at some
point lost the use of deltas for the initial install case, instead always falling back
to a full ostree operation which is a lot less efficient for pulls with many small files
like a runtime. This caused some very slow installs from e.g. flathub, so I recommend
everyone update to this version to get better install performance.

Other changes are:
 * We now correctly handle TMPDIR env var overrides when bwrap is setuid
 * Disallow running "flatpak run" under sudo (as it doesn't work and causes issues)
 * Fix build with older versions of glib
 * Minor documentation updates
 * Updated translations

Changes in 1.6.1
================

This is a (mild) security update. Flatpak 1.6.0 added the ability for an application to request it to be
updated, as long as the new version doesn't require new permissions. Unfortunately in some special cases,
if an app had access to the home directory, but not the rest of the filesystem it would still allow a
self-update where the new version could access some files outside the home directory..

This is fixed in this version, and all users of 1.6.0 are recommended to update.

Other changes are:

 * New permission --device=shm giving access to host /dev/shm, as needed for jack.
 * Generated correct download size in build-commit-from
 * sub-sandbox now allows the child to share the gpu of the caller has full device access
 * Fix crash with disabled remotes
 * Fix builds with older versions of glib
 * Update translations

Changes in 1.6.0
================

This is the first stable release in the 1.6 series, main changes
since 1.4 is the support for protected content and improvements
in the self-sandboxing support.

There is one change in the support for OCI remotes, we now
only support the use of labels, not annotations, as labels
work with more registries. This means pre-existing OCI flatpak
registries (like fedora) may need some changes.

Changes since 1.5.2:
 * New permissions --socket=cups for direct cups access
 * Fix some leaks
 * Fix reporting of progress with latest version of ostree
 * New no-interaction flag for authenticators
 * Support for auto-installing authenticators from a flatpak remote
 * Warn less about unset XDG_DATA_DIRS
 * Don't poll for updates in the portal when on a metered connection

Changes in 1.5.2
================

This version has further changes to the protocol and API for handing
authentication, in order to make it more flexible and futureproof. The
sample authenticator has been updated to the new APIs. Flatpak now
ships with a OCI authenticator that can be used to access private OCI
registries.

FlatpakTransaction now also has a callback for simple user/password
authentication for an authenticator (the basic-auth-start signal)
modeled on HTTP basic authentication. This is handled in the flatpak
CLI by interactive prompts on the terminal. This is needed by the OCI
authenticator, but can also be used by other authenticators that have
simple authentication requirements.

There were also some fixes to the new self-sandboxing support of the
flatpak spawn portal, allowing webkit to use it.

Other changes:
 * Show background status in flatpak ps
 * Improved docs and help output
 * Fix support for fd forwarding and the allow_a11y flag in the sandboxing portal
 * Some improvements to the new permission-set command
 * New remote option that allows setting the default token type (mostly for debugging)



Changes in 1.5.1
================

The major new feature of this is the support for protected applications and the system
around authenticating downloads to it. This is not considered stable yet, but this release
has the initial work to make it possible for developers to play around with this. I
will send out a separate mail about this later.

Other changes:
 * Flatpak now bundles bubblewrap 0.4.0, and requires 0.4.0 to use the system bubblewrap.
 * Optional support for parental controls using libmalcontent.
 * Transaction now installs extensions before apps to ensure we have a working app immediately after install.
 * Changes in temporary file use makes flatpak run work better in low disk space situations.
 * flatpak enter now works without sudo, and works better in general.
 * New features for the flatpak portal:
   * Support starting a sub-sandbox with the child processes visible in the original sandbox.
   * Support adding some kinds of permissions to sub-sandboxes
 * New commands flatpak permission-set and permission-remove
 * flatpak install CLI now always shows what kind of operations everything is.
 * libflatpak now returns apps as updatable if doing so would auto-download missing extensions or runtimes.
 * new API: flatpak_transaction_get_no_(deploy|pull).
 * We can now store locale info in the extra-languages key (in addition to the country code).
 * remote-ls and list --app-runtime now only shows apps, no runtimes.
 * Stop using mirror refs and delete any useless mirror refs you might have in your repo.
 * Fix busy-loop regression in revokefs-fuse in 1.5.0

Changes in 1.5.0
================

 * New options flatpak install --or-update operation.
 * New command flatpak mask allows pinning version and avoiding auto-downloads.
 * Support self-updates and update monitoring in the flatpak portal.
 * Fix updates of exported services with dbus-broken.
 * Don't show arch columns in terminal output if all are the same.
 * Fix some cases where origin remotes were not properly removed.
 * flatpak-session-helper now links to more libraries.
 * OCI: Support images tagged with labels as well as annotations.
 * OCI: Always generate a history for images.
 * OCI: Support docker mimetypes in addition to OCI mimetypes.
 * Uninstall now always work, even if the remote it came from was force removed.
 * New config key default-languages that allows additions to the system list
  instead of overriding it.
 * Various minor tweak to CLI behaviour and output.

Changes in 1.4.3
================
 * Fix crash in revokefs.
 * Handle 'versions' extension key (in addition to 'version') when
   checking for local extensions, which was causing us to uninstall
   some actually used extensions with uninstall --unused.
 * The 'required-flatpak' metadata key now supports listing multiple
   versions to support backported features.
 * Fix crash with older versions of polkit.
 * Fix installation of bundles.
 * Fix crash on deploy error.
 * Support building bundles of apps installed from a remote.
 * OCI: Fix handling of locally cached icons.
 * Fix crash when listing unconfigured remotes.
 * Ignore differences in trailing slashes for repo uris.

Changes in 1.4.2
================

 * Support extra_data in extensions.
 * Handle double slashes ("//")in XDG_DATA_DIRS.
 * Fix detection of local related refs.

Changes in 1.4.1
================

*WARNING* *WARNING* *WARNING*

There was an accidental ABI break in libflatpak in 1.4.0 compared to
the 1.2.x ABI which caused crashes in apps like gnome-software.

This has been fixed in this release so it is now ABI compatible with
1.2.x, but *NOT* compatible with 1.4.0. It is recommended that all
distributions that shipped 1.4.0 update to 1.4.1 and rebuild all
dependencies of libflatpak.

 * Make ABI compatible with 1.2.x
 * Update translations
 * Fix some potential crashes
 * Fix some corner case where it was impossible to remove a remote
 * Restore support for file: uris in the RuntimeRepo key in flatpakref files

Changes in 1.4.0
================

This is the new stable series, ending the 1.3.x series. The major changes
since the 1.2.x is the improved I/O use for system-installed applications,
and the new format for pre-configured remotes.

 * Recalculate download-size when moving between repos in
   build-commit-from.
 * New library error FLATPAK_ERROR_REF_NOT_FOUND returned instead of
   G_IO_ERROR_NOT_FOUND.
 * Fix installed tests when running on a tty.
 * Fix a double-set of a GError.
 * Grant more permissions on the /run/host/monitor directory to
   work with e.g. toolbox on the host.

Changes in 1.3.4
================

This version changes how default remotes are configured. We still
use files in /etc/flatpak/remotes.d, however instead of the old
*.conf files we now use regular flatpakrepo files, and the first
time you use flatpak these are automatically imported.

The advantage of this new model is that the configuration is imported
once, but then becomes writable and removable, just like a manually
added remote. In the previous model the remote was always there and it
was impossible to change or remove.

However, this means that anyone currently shipping a .conf file with
a distro needs to change this to a .flatpakrepo file.

 * Support for flatpakrepo files in /etc/flatpak/remotes.d
 * Support for client side filtering of a remote. This allows you
   to limit what apps are seen from a remote, using either a whitelist
   or a blacklist model.
 * Add library API to easily add remotes from flatpakref files.
 * Fix the dconf support.
 * Fix app updates in system-wide OCI remotes.
 * Fix CLI completion if G_MESSAGES_DEBUG is set
 * Add a docker seccomp profile for running flatpak inside a container.
 * Look for the new default dbus session socket at $XDG_RUNTIME_DIR/bus
 * Improve ability to pull from multiple p2p sources (needs latest ostree).

Changes in 1.3.3
================

 * Fixed a crash in the system helper that made installation via
   the helper sometimes not work.
 * Fix build with older versions of glib
 * The list and remote-ls output is now less wide, not showing the
   appdata summary by default and only showing the architecture and
   origin if necessary (i.e. not if its the same for all rows).
 * flatpak remote-ls now filters end-of-lifed apps by default.
 * flatpak permission-reset now supports --all
 * Flatpak now works will all set values of umask.
 * The flatpak profile.d snippet now works if flatpak is not installed
   (in case it gets left over after deletion).
 * Fixed flatpak install --noninteractive still asking questions in some cases.
 * flatpak now returns a failure exit status if you abort the operation early.
 * flatpak remote-ls and remote-info now supports --cached to prefer
   using locally cached data.
 * libflatpak grew a FLATPAK_QUERY_FLAGS_ONLY_CACHED that allows you to
   get at locally cached data about remotes without doing network i/o.
 * Documentation updates

Changes in 1.3.2
================

This release contains a major change in how flatpak does system-wide
installation as a user. We used to pull into a temporary user-owned
directory and then ask the flatpak system-helper to import from this
directory. Unfortunately, since we can't trust the user directory
it had to copy these files as they were being imported, which caused
unnecessary i/o, as well as temporarily using more diskspace.

The new setup uses a new custom fuse filesystem which the user writes
to, and then when this is done we can safely revoke any access to this
from the user, meaning the files can be directly imported into the
system repository without needing to make a copy.

However, this makes packaging flatpak a bit more complex, as we now
require flatpak to have a user. By default flatpak will look for a user
called "flatpak", and for the new feature to work you need to create
it in your package. If you want to use a different name you can specify
that in configure as --with-system-helper-user=USERNAME.

Additionally, the new code passed a unix socket over the system bus, which
is prohibited by the default selinux policy. To work around this flatpak
now ships with a custom selinux module (enable with --enable-selinux-module).
For the new feature to work you need to install this module and ensure
the flatpak-system-helper binary gets the proper selinux context.

Other changes:

 * We now support specifying a rebasing version of end-of-life, where
   the clients will be asked if they want to use the new version. At
   runtime any old per-user application data will be migrated to the
   new name. Note: This works for the CLI app, but needs some changes
   for installers to take advantage of the automatic rebasing.
 * New permission --socket=pcsc for access to smart cards.
 * We now store the description, comment, icon and homepage fields from
   the flatpakrepo files in the remote configuration and have new library
   APIs to read these back.
 * The fields above are now also settable in a repo and changes to these
   can propagate to clients.
 * run now tries the determine what branch to use when you run a runtime.
 * Print maximum icon size when icon-validator fails.
 * flatpak override can now disallow access to a dbus name.
 * flatpak list now has a new runtime column

Changes in 1.3.1
================

This release fixes CVE-2019-10063.

It has been discovered that the previous fix for CVE-2017-5226, which uses
seccomp to prevent sandboxed apps from using the (dangerous) TIOCSTI ioctl
was only incomplete on 64bit arches. This is now fixed.

 * seccomp: Only compare the low 32bit of the TIOCSTI ioctl args.
 * Fix the required runtime prompt during installation.
 * When installing, only check dependencies from the same installation.
 * flatpak list --arch now works correctly again.
 * Create origin symlinks in appstream branch for libappstream compat.

Changes in 1.3.0
================

This is the start of a new unstable series, targeting stable release
as 1.4.0.

Major changes:

 * Support systems with multiple nvidia devices
 * Checks are update output are green again
 * Fix support for systems like gentoo where /var/run is a symlink.
 * Initial support for sandboxed dconf support.
 * build-update-repo: New options --no-update-[summary,appstream] and
   --static-delta-ignore-ref=PATTERN.
 * Regenerating the appstream branch is now much faster for large
   repositories.
 * We no longer limit the size of svgs in the icon validator.

Changes in 1.2.3
================

This release fixes CVE-2019-8308.

The CVE-2019-5736 runc vulnerability is about using /proc/self/exe
to modify the host side binary from the sandbox. This mostly does not
affect flatpak since the flatpak sandbox is not run with root permissions.
However, there is one case (running the apply_extra script for system
installs) where this happens, so this release contains a fix for that.

 * Don't expose /proc in apply_extra script sandbox.

Changes in 1.2.2
================

 * Reverted green checkbox as they caused table alignment issues
 * Fix a division by zero if the terminal reports a zero terminal
   width (which happens in the flathub build environment).

Changes in 1.2.1
================

 * Ensure flatpak builds with older versions of glib and appstream-glib.
 * build-commit-from: Fix the new --extra-id option.
 * build-export: Allow disabling the sandboxing of the icon validator and
   do so during the tests.
 * profile: Don't break if debug logging is enabled.
 * Better handling of the appdata release attribute.
 * Don't install polkit agent when not needed, avoiding some unnecessary
   log lines in some cases.
 * Fix the output of the sandboxed icon validator not being visible.
 * builld-init: Allow specifying a full ref for the sdk, which is used to
   select the branch name when checking sdk extensions.
 * Make the ok checks in the output green

Changes in 1.2
==============

 * Ensure DeployCollectionID works in flatpakrepo files in all cases.
 * Don't error out with empty installations in uninstall.
 * Add helper that validates icon files during export.
 * Don't allow root to modify the (non-root) per-user flatpak installation,
   as this risks causing problems later.
 * Remove some incorrect warnings from flatpak repair.
 * Allow multiple name segments after prefix when exporting files.
 * Allow specification of ellipsization in --colums options.
 * Handle dates as well as timestamps in appdata
 * Fixed a bug where flatpak remote-delete removed too many refs.
 * Now we use raw terminal mode during a transaction to a avoid problems with input
   during the operation causing problems with escape sequences.
 * Generate a fontconfig directory remapping snippet as will be needed
   for newer versions of fontconfig.
 * Support --extra-collection-id in build-commit-from to bind the commit
   to multiple collection ids. This is work in progress in ostree.

Changes in 1.1.3
================

 * Various fixes to the CLI output changes
 * New flatpak --installations option to list all installations
 * Extract license info from appdata among with the other fields.
   This is shown in e.g. info and remote-info, and has library API.
 * install/update/uninstall now has --noninteractive option with less output
   that is useful when called from scripts, etc.
 * --devel is now properly forwarded to sub-sandboxes using the flatpak portal.
 * Drop dependency on libappstream-glib from libflatpak.
 * Initial support for exposing the system dconf defaults to the sandbox.
 * We now create deploy refs for the deployed commits to avoid a prune removing
   objects that are in use.
 * Ask about removing all refs when deleting a remote.
 * New environment generator that handles custom installations,
   replacing the old dbus service config file.
 * Documentation updates
 * More robust completion
 * Try to report out-of-space errors better.
 * Add more tests.
 * Various improvements to the repair command.

Changes in 1.1.2
================

 * Refreshed the CLI output layout, in particular the install/update progress
   and application list/info commands.
 * The host XDG_{DATA,CONFIG,CACHE}_HOME env vars are now available as
   with the HOST_ prefix in the sandbox.
 * FLATPAK_ID is set to the app id in the sandbox (this previously
   only happened in flatpak build).
 * The spawn portal command now has a kill with parent option.
 * Flatpak shells now have custom prompts
 * New library APIs: Access to deployed appstream data, list unused refs.
 * Flatpak run now has --cwd option.
 * New option --static-delta-jobs to limit number of parallel delta
   generation jobs in build-update-repo.
 * Fixed critical warning with newer policykit versions.

Changes in 1.1.1
================

 * New libflatpak function: flatpak_remote_get_main_ref()
 * Various changes to the policykit rules in order to cause less, and
   more understandable policykit authentication dialogs.
 * Give DRI apps access to more nvidia device nodes required for CUDA/OpenCL support.
 * search now doesn't search noenumerate remotes.
 * Renamed operations permission-list to permissions and document-list to
   documents. The old names are still supported as aliases.
 * New property 'non-interactive' for installations that allow frontends
   to do background updates without triggering policykit authentications.
 * New flag in HostCommand to allow killing the child process when
   the spawner exits the session bus.
 * Flatpak now authenticates on the terminal in case there is no desktop-wide
   policykit agent.
 * update with no arguments now updates all installations (i.e. also custom
   systemwide installations).
 * Use system helper to generate summary files for OCI remotes.
 * Better progress reporting for OCI downloads.
 * New conditional extension download feature, 'on-xdg-desktop-FOO'  which downloads
   when XDG_CURRENT_DESKTOP matches FOO.
 * More sockets are now mounted read-only in the sandbox
 * Updated docs, error messages and translations


Changes in 1.1
==============

This is the first release in the new unstable 1.1.x series, leading up to 1.2
which is expected around the end of the year.

Changes in this version:
 * New command flatpak kill to kill running flatpak instances.
 * The remote argument is now optional in the flatpak install in
   interactive installs. Instead you are prompted for which
   remote to install from.
 * All commands printing tables now support --columns option to specify
   exactly what to output.
 * flatpak uninstall now supports --delete-data to delete the application
   data directory in your homedirectory. If no application is specified
   it will remove data from all uninstalled apps.
 * flatpak list now supports filtering by runtime with:
   --app-runtime=org.gnome.Platform//3.24
 * flatpak remote-ls can now show the runtime used for each app.
 * flatpak repo now supports --info to show information
   about a repository, and it is the default operation
   for the flatpak repo.
 * flatpak repo now supports --commits to list commits in branch.
 * flatpak now logs transactions to the systemd journal if built
   against libsystemd.
 * libflatpak now exposed FlatpakInstance for a running instance.
 * Better error output if a flatpak command is misspelled
 * Drop support for migration from xdg-app (previous name for flatpak).
 * New library function flatpak_installation_get_min_free_space_bytes.
 * In interactive mode "yes" is now the default in most prompts.
 * Bumped ostree requirement to 2018.9
 * Cleanups and improvements to the test suite.
 * Improvements to documentation.
 * buildsystem support for coverage generation.

Changes in 1.0.6
================

This release fixes an issue that lets system-wide installed
applications create setuid root files inside their app dir (somewhere
in /var/lib/flatpak/app). Setuid support is disabled inside flatpaks,
so such files are only a risk if the user runs them manually outside
flatpak.

Installing a flatpak system-wide is needs root access, so this isn't a
privilege elevation for non-root users, and allowing root to install
setuid files is something all traditional packaging systems
allow. However flatpak tries to be better than that, in order to make
it easier to trust third party repositories. Thus, it is recommended
that all distros update to this version, or backport commit
b98e09b20dfab896616b4a65e15c31f684a5f9f2.

Changes in this version:
 * The permissions of the files created by the apply_extra script is
   canonicalized and the script itself is run without any capabilities.
 * Better matching of existing remotes when the local and remote configuration
   differs wrt collection ids.
 * New flatpakrepo DeployCollectionID replaces CollectionID, doing the
   same thing. It is recommended to use this instead because older versions
   of flatpak has bugs in the support of collection ids, and this key
   will only be respected in versions where it works.
 * The X11 socket is now mounted read-only.

Changes in 1.0.5
================

There was a sandbox bug in the previous version where parts of the runtime
/etc was not mounted read-only. In case the runtime was installed as the
user (not the default) this means that the app could modify files on the
runtime. Nothing in the host uses the runtime files, so this is not a direct
sandbox escape, but it is possible that an app can confuse a different app
that has higher permissions and so gain privileges.

So, it is recommended that everyone shipping flatpak to update to
1.0.5, or at least backport the change in commit
6711d7ae99c50a9dca8e4e2e9e9989a8fa6c3f06.

Changes in this version:

 * Make the /etc -> /usr/etc bind-mounts read-only.
 * Make various app-specific configuration files read-only.
 * flatpak is more picky about remote names to avoid problems with storing weird
   names in the ostree config.
 * A segfault in libflatpak handling of bundles was fixed.
 * Updated translations
 * Fixed a regression in flatpak run that caused problems running user-installed
   apps when the system installation was broken.

Changes in 1.0.4
================

 * Flatpak 0.99.1 removed the inheritance of permissions from the runtime due
   to concerns with dynamic app permissions. Due to popular requests, this
   version re-introduces such inheritance, but does it instead at build time.
   This solved the issues with dynamic permissions while still allowing runtimes
   to have default permissions. Apps can disable this by passing
   --no-inherit-permissions to build-finish.
 * The sandbox now always includes a /etc/timezone file, following the (old)
   debian standard for this. This is needed, because the more modern way
   of exposing the timezone name by having /etc/localtime be a symlink
   into /usr/share/zoneinfo doesn't work when exposing the host timezone.
 * All apps now have automatic permissions to own their own app id as a
   subname of org.mpris.MediaPlayer2.
 * We now properly re-load remote state in FlatpakTransaction if the
   metadata was updated for the remote.
 * The signature of the FlatpakTransaction::operation-done signal was wrong
   in the header and has now been corrected to the signature that is actually
   emitted.
 * A crash was fixed when reading invalid .flatpakref files.
 * A crash during updates when a local ref was unexpectedly missing was fixed.
 * An error case on uninstalling was incorrectly returning success even
   thought there was an error.
 * flatpak_installation_modify_remote did not correctly save the nodeps state.
 * flatpak_installation_load_app_overrides() was improperly returning freed
   memory.
 * The tarball now ships with an icon (flatpak.png).

Changes in 1.0.3
================

 * run: You can now use --system to run an app that otherwise would run the
   user version.
 * New permission --allow=canbus that filters out access to AF_CAN sockets.
 * lib: New install flags FLATPAK_INSTALL_FLAGS_NO_TRIGGERS and new function
   flatpak_installation_run_triggers()
 * lib: Better error reporting, including some new error values that
   replace the generic FAILED.
 * uninstall --unused: Improve handling of which .Locale extensions are used
 * run: Make flatpak run on systems where $XDG_RUNTIME_DIR contains a symlink
   beneath /var (commonly /var/run -> /run).
 * Don't export any desktop/dbus/mimetype files in subdirectories.
 * build-init: We now record the base ref (if used) in the metadata. Nothing
   uses this atm, but it can be used by tools.
 * We now respect the upstream ostree.deploy-collection-id instead of the
   flatpak-specific xa.collection-id metadata key to decide whether to switch
   to collection ids for a remote. This is useful, because if you use the
   new one, only new clients (that support it better) will use it.
 * create-usb: Fix assertion failure in some error cases
 * create-usb: Always create archive-z2 repos
 * create-usb: Don't create unnecessary summary in repo
 * permissions: Avoid errors if there is no permissions table
 * repo: Fix flatpak repo sometimes using the wrong ostree-metadata ref.
 * Avoid fsync when updating $installation/.changed.
 * Add the missing appstream2 ref to the xa.cache metadata
 * The test-suite got some modifications to make it easier to maintain.
 * Documentation updates
 * Translation updates

Changes in 1.0.2
================

 * The dbus proxy is now available in a separate git module, xdg-dbus-portal,
   which is imported into flatpak as a submodule. It is possible to build
   flatpak against the system xdg-dbus-portal instead, but this is not currently
   very useful as no other applications yet depend on xdg-dbus-portal.
 * Build regressions with older versions of glib have been fixed.
 * Flatpak ps now also tracks the pid the main process inside the sandbox.
 * Added flatpak override --reset to reset overrides for an app.
 * Added flatpak override --show to show overrides for an app.
 * flatpak install now automatically pick user or system based on the remote
   name given (unless the remote exists in both).
 * flatpak uninstall --unused now does not remove SDKs if some installed app
   refers to them.
 * Fixed bug where flatpak uninstall --unused prompted for uninstall twice.
 * Set IO class on the system helper to "idle", which should cause background
   updates to affect the system less.
 * Fixed regression in flatpak uninstall --no-related.
 * Better handling of empty collection ids in flatpak bundles.
 * Cleaned up some error messages.
 * Various documentation fixes and cleanups.
 * Updated translations.

Changes in 1.0.1
================

This fixes various build and test failures that were detected when
packaging 1.0, as well as translations and doc updates. It also
has some minor features, including a new subcommand "flatpak ps"
to list the running flatpak instances for your user.

 * Print application tags in the prompt when installing/updating.
 * Make sure we don't accidentally leak the host /proc into
   the sandbox.
 * Translation updates.
 * Added a "flatpak ps" command that lists running flatpak instances.
 * Improve error reporting when exporting documents.
 * Improve detection of dynamic p2p remotes.
 * Build fixes for older versions of glib.
 * Fix threading issue in the OCI support that was causing the
   installed tests to sometimes fail.
 * Fix OCI AppStream support on 32bit architectures.
 * Fix utf8 issue in the dbus API description.
 * Some install fixes to make installed tests work
 * Make the tests work with python3 (as well as python2)
 * Improve introspection annotations in libflatpak
 * Improve libflatpak API docs

Changes in 1.0
==============

Flatpak 1.0 is the first version in a new stable release series. This
new 1.x series is the successor to the 0.10.x series, which was first
introduced in October 2017. 1.0 is the new standard Flatpak version,
and distributions are recommended to update to it as soon as possible.

The following release notes describe the major changes since
0.10.0. For a complete overview of Flatpak, please see
[docs.flatpak.org](http://docs.flatpak.org/en/latest/).

## For users, app developers and distributors

Flatpak 1.0 marks a significant improvement in performance and
reliability, and includes a big collection of bug fixes. 1.0 also
includes a collection of new features, including:

 * Faster installation and updates.
 * Applications can now be marked as end-of-life. App centers and
   desktops can use this information to warn users who have an end-of-life
   version installed.
 * Permissions now use an up-front verification model: users are
   asked to confirm app permissions at install time, if an update
   requires additional permissions, the user must also confirm.
 * A [new portal](https://flatpak.github.io/xdg-desktop-portal/portal-docs.html#gdbus-org.freedesktop.portal.Flatpak)
   allows apps to create sandboxes and restart themselves. This allows
   applications to restart themselves after they have been updated (to
   start using the new version), and to increase sandboxing for parts
   of the application.
 * `flatpak-spawn` is a new tool for running host commands (if
   permissions allow) and creating new sandboxes from an app (this
   uses the above portals APIs).
 * Apps can now export D-Bus services for all the D-Bus names they are
   privileged to own (rather than just the application ID).
 * Flatpak's support for OCI bundles has been updated to the latest
   specification. Also, AppData can now be distributed through OCI
   repositories.
 * Host TLS certificates are now exposed to applications, using
   p11-kit-server. This removes a point of friction when accessing
   network services in some environments.
 * Apps can now request access the host SSH agent to securely access
   remote servers or Git repositories.
 * A new application permission can be used to grant access to
   Bluetooth devices.
 * A new `fallback-x11` permission grants X11 access, but only if the
   user is running in a X11 session. For applications that support
   both Wayland and X11, this can be used to ensure that the app
   doesn't have unnecessary X11 access while in Wayland, but still
   works in an X11 session.
 * Peer-to-peer installation (via USB sticks or local network) is now
   enabled and supported by default in all builds.

The Flatpak command line also introduces new commands and options, including:

 * `uninstall --unused` automatically removes unused runtimes and
   extensions (if you've removed all apps that depend on a runtime, or
   all the apps you had depending on it have upgraded to a newer
   version).
 * New `info` options, including `--show-permissions`,
   `--file-access`, `--show-location`, `--show-runtime`, `--show-sdk`.
 * `repair` - fixes broken installs by scanning for errors, removing
   invalid objects and reinstalling anything that's missing.
 * `permission-*` - allows interaction with the portals permissions
   store. This is useful for testing and for getting back to a clean
   state.
 * `create-usb` - can be used to prepare an repository to be used as a
   local updates source.

Finally, the command line has a collection of other improvements, such as:

 * If `--system` or `--user` aren't specified, one is automatically
   picked if it is obvious (or it will ask if the correct option isn't
   obvious).
 * The `install`, `update` and `uninstall` commands now ask for
   confirmation of changes before proceeding, in order to prevent
   mistakes, and to show the required application permissions.
 * The `uninstall` command now does not allow you to remove a runtime
   if some installed application requires it.
 * `flatpak remove` is now an alias for `flatpak uninstall`.

## For Linux distributors, OS and platform developers

 * Flatpak no longer requires a filesystem that supports `xattr`.
 * Portals are now more cleanly separated from Flatpak, thanks to the
   document portal and permission store having been moved to
   `xdg-desktop-portal`. It is recommended that the flatpak package has
   a weak dependency on `xdg-desktop-portal`.
 * `libflatpak` now has a transaction API for install, update and
   uninstall operations. This means that it is much easier to use as
   the basis of app centers and other graphical app management
   software.
 * Flatpak now sets several HTTP headers when installing applications,
   which make it easier for Flatpak repositories to log things like
   app download statistics and Flatpak versions in use.
 * It is now recommended that Flatpak packages add a dependency on
   p11-kit-server, as this allows apps to access host
   certificates. However, this does not need to be a hard dependency.
 * Requires bubblewrap 0.2.1 or later, and comes bundled with 0.3.0.
 * Requires OSTree 2018.7.

Major changes in 0.99.3
=======================

 * Fixed case where system install would sometimes fail
   due to the system-helper idle exiting.
 * Support installing flatpakref files in FlatpakTransaction,
   including a new signal add-new-remote for when remotes
   might be added.
 * Added some new FlatpakError codes.
 * We now support .flatpakrepo files with no gpg signatures
 * Fix crash in system-helper when updating appstream
 * New command create-usb which can be used to prepare
   an repo for offline updates.
 * Fix some non-handled cases of the CLI not working when
   /var/lib/flatpak doesn't exist.
 * Fix crash when running with a gid that is not in
   /etc/groups.
 * Add new permission-* commands to interact with the
   permissions store from the portals.
 * Include appdata in OCI bundle.

Major changes in 0.99.2
=======================

 * Fix race condition on instance id allocation
 * Translation updates
 * Build fixes for new glibc versions
 * Build fixes for new libsoup versions
 * Build fixes for old glib versions

Major changes in 0.99.1
=======================

This is the first pre-release before flatpak 1.0. This is considered
feature-complete and we expect no features or major changes before
1.0, only bugfixes.

Note: There were some (minor) API changes in the FlatpakTransaction
APIs that were added in 0.11.8, so please don't use the old
version. (Note: I know of no user of this API).

Changes since last minor release:
 * Ostree 2018.6 is required, and with this, the p2p code in
   flatpak is made non-optional.
 * flatpak install/update/ininstall now lists all the operations
   that it will do and asks for confirmation before starting.
 * In the above confirmation the permissions (new permissions
   for updates) are shown for all applications.
 * The FlatpakTranscation API has a new ::ready signal that
   allows users to do similar confirmation prompts.
 * P2P updates are more efficient
 * system-wide installation uses less fsync calls so should
   installation should be faster.
 * New ssh agent permissions allows granting an app
   ssh access.

Major changes in 0.11.8.3
=========================

 * Fix a 25 second timeout on startup if using p11-kit < 0.23.10
 * Minor change in dbus proxy default filter, now broadcasts are
   not accepted from portals.

Major changes in 0.11.8.2
=========================

 * Fix crash when building some apps
 * Allow multiple appstream components per app
 * Fix handling of gl drivers in uninstall --unused
 * Don't prompt if nothing changed in uninstall --unused
 * Longer timeouts in test suite
 * Updated translations

Major changes in 0.11.8.1
=========================

 * Fixed regression running apps with --own=* permissions

Major changes in 0.11.8
=======================

 * Flatpak uninstall now accepts --all to remove everything and --unused to remove unused
   runtimes.
 * New command "flatpak repair" allows checking and repairing a flatpak installation.
 * New permission --allow=bluetooth allows use of AF_BLUETOOTH sockets
 * If p11-kit-server is installed on the host, this is now used to forward the host
   certificate trust store to the sandboxed app.
 * New transaction API in libflatpak that makes it much easier to implement
  installation and updates in frontends.
 * Flatpak uninstall now does not allow you to remove a runtime if some installed app requires it.
 * We now have tab-completion for zsh.
 * New installations of flatpak now defaults to bare-user-only repos, which means
   that it works with filesystems that don't support xattrs.
 * New flatpak info options: --show-location, --show-runtime, --show-sdk
 * New flatpak remote-info options: --show-runtime, --show-sdk
 * p2p operations now work when offline.
 * Work around hanging on app startup on blocking autofs mounts.
 * The dbus proxy filtering now works matches the new dbus containers filtering API.
 * Various optimizations make installation and updates faster. In particular
   operations like running triggers and pruning only happens once per
   install/update operation.
 * We now respect multiple extension versions matches when auto-downloading extensions.
 * New http header Flatpak-Upgrade-From sent when upgrading.
 * Commands like "flatpak info/list/remotes/search" now work properly if /var/lib/flatpak doesn't exist.
 * The bubblewrap version required for system-bwrap is now 0.2.1.

Major changes in 0.11.7
=======================

 * Fix regression in installing .flatpak bundles

Major changes in 0.11.6
=======================

 * Further work on the export filename regression, now also fixes the
   same issue as in 0.11.5 but in flatpak build-finish.
 * Fix segfault when installing from .flatpakref in gnome-software
 * Build yacc parser from source.
 * Don't tab-complete Sources/Locale/Debug extension by default.
 * Fix tests on debian.

Major changes in 0.11.5
=======================

 * Fix a regression which caused installation of epiphany and
   other apps that export multiple .service files to fail.
 * Fix appstream updates in p2p mode.
 * Don't distribute generated gdbus code with tarball.
 * Add documentation for the flatpak portal

Major changes in 0.11.4
=======================

 * flatpak remove is now an alias for flatpak uninstall.
 * flatpak uninstall now picks system or user automatically if not specified
 * New appstream branch format which is more efficient to distribute,
   the old is still generated for backwards compat.
 * Appstream data now contains compatible arches (for applications
   that doesn't exist for the primary arch). For example, an
   i386-only app is now listed in the x86-64 appstream.
 * The flatpak version is included in the user agent when downloading.
 * The Flatpak-Ref http header is set to the currently installing ref when
   downloading.
 * New argument --timestamp in build-commit-from.
 * When updating many apps we now only prune the local repo when all
   updates are done, making multi-app updates faster.
 * flatpak build now always allows multiarch use.
 * flatpak build now mounts app extensions during build.
 * flatpak build-init now supports --extension to add extension points earlier
   than build-finish. Also build-finish now supports --remove-extension.
 * New flatpak portal allows applications to sandbox themselves and restart a
   newer version of themselves.
 * New flatpak run options: --no-a11y-bus, --no-documents-portal.
 * Initial support for end-of-life:ing applications.
 * New option X-Flatpak-RunOptions in exported desktop/files allow you to specify
   no-a11y-bus and no-documents-portal.
 * Support for tagged extension points, which is useful if you want to use
   the same extension id (but maybe different versions) multiple times in an app.
 * We now export .service files for names that the app is allowed to own on
   the session bus.
 * libflatpak got new methods for listing remotes by type.
 * libflatpak now has support in FlatpakRemoteRef for getting remote metadata
   such as end-of-life, download size, metadata etc.
 * There was some internal restructuring on how installs/updates are done
   which should improve performance and maintainability.

Major changes in 0.11.3
=======================

 * Fix "open with" and flatpak run --file-forwarding crash
 * Fix build with glibc 2.27

Major changes in 0.11.2
=======================

 * Remove fuse dependency, since we don't ship document portal anymore
 * Fix various issues with /home being a symlink to /var/home (atomic)
 * Allow downgrades when using collection ids
 * Search on all supported architectures

Major changes in 0.11.1
=======================

This release removes the document portal and the permission store as they
have been added to xdg-desktop-portal 0.10. Packagers need to update
these two in lock-step. Flatpak technically doesn't depend on
xdg-desktop-portal, but it is recommended that the flatpak package
depends on xdg-desktop-portal in some way, because most flatpaks will
want it.

 * Remove document portal and permission store
 * Add --socket=fallback-x11 permission
 * Fix dbus proxy vulnerability in authentication phase
 * Allow personality syscall in devel mode
 * commit-from: Migrate static deltas with commit
 * Add "network" storage type for installations
 * Add flatpak info --show-permissions
 * Add flatpak info --file-access
 * search: Update appstream (if stale) before searching
 * Make libflatpak work when /var/lib/flatpak is empty
 * build-bundle: Add --from-commit option
 * Allow appstream ids that don't end in .desktop
 * Make permission handling ignore unknown permissions for forwards
   compatibility
 * Removed incorrect error message in update --appdata when there
   was no updates
 * Fix handling of abort in the duplicate remote prompt
 * Fix division by zero in progress calculation
 * Fix flatpak remote-info --show-metadata
 * Fixed crash when installing some flatpak bundle files
 * Fix installation of telegram
 * remote-ls -u only considers app from the origin remote
 * Fix assertion error in extra-data progress reporting
 * Report nicer errors when trying to downgrade as non-root
 * pulseaudio: Try to find pulseaudio socket better
 * Fixed some warnings reported by coverity
 * Cleaned up code by splitting up some large source files

Major changes in 0.10.2
=======================

 * Flatpak now requires OSTree 2017.14
 * flatpak update now updates from both system and user installations
   by default.
 * flatpak update is less noisy when updating appstream info.
 * All the remote-* commands now by default automatically decide to use
   --user or --system based on the given remote name.
 * flatpak remote-ls with no remote lists the content of all remotes
 * Fixed regression that made xdg-user-dirs and theme selection
   for kde apps break.
 * flatpak override with no argument now overrides globally, i.e. for
   all apps.
 * flatpak override now supports --nofilesystem properly. For example
   flatpak override --nofilesystem=~/.ssh hides the ssh dir for all
   apps, even those who have homedir access.
 * flatpak install now takes a --reinstall argument which uninstalls
   a previously installed version if necessary. This is very useful
   when you want to install a new version from a different source.
 * flatpak install now allows you to pass an absolute pathname as
   remote name, which will create a temporary remote and install
   from that. The remote will be removed when the app is uninstalled.
   This is very useful during development and testing.
 * Flatpak now creates CLI wrappers for all installed apps, so if you
   add /var/lib/flatpak/exports/bin or ~/.local/share/flatpak/exports/bin
   to your PATH you can easily  start flatpak apps by their application id.

Major changes in 0.10.1
=======================

 * New command "flatpak remote-info" shows information about applications
   in a remote. In particular the --log operation shows the history and
   can be used in combination with flatpak update --commit=XYZ to roll
   back to a previous version.
 * New command "flatpak search" which allows you to search the appstream
   data from the commandline.
 * flatpak update now updates appstream data for all configured remotes, which
   is important for search to work.
 * Allow automatic installation of gtk themes matching the active theme.
 * Handle the case when /etc/resolv.conf is a symlink
 * /usr an /etc are now expose in /run/host in the app if the app has
   full filesystem access.
 * flatpak remote-add now works as a user when /var/lib/flatpak is empty,
   allowing flatpak to work on stateless systems.
 * Add support for flatpak build --log-session/system-bus, similar to
   what flatpak run already does.
 * flatpak build --readonly runs with the target directory (normally /app)
   mounted read-only.
 * Fall back to LD_LIBRARY_PATH if a runtime doesn't have /usr/bin/ldconfig.
 * Updated the support for OCI remotes. This is work in progress and still
   disabled by default though.

Major changes in 0.10
=====================

This is the first release in a new series of stable releases called
0.10.x. New features will be added to 0.11.x, and bugfixes will be
backported to 0.10.x. During the early phase of the 0.10.x series we
may also backport minor features, but we guarantee backwards
compatibility.

Changes since 0.9.99
 * Added the flatpak config option which can set the language settings
 * Fix issue where sometimes ld.so.conf were not generated
 * /dev/mali0 is added to --device=dri
 * Work around ostree static delta issues in some cases

Major changes in 0.9.99
=======================

 * Requires ostree 2017.12 for important pull stability fix
 * New libflatpak API: flatpak_dir_cleanup_undeployed_refs, flatpak_installation_prune_local_repo,
    flatpak_installation_remove_local_ref_sync, flatpak_installation_cleanup_local_refs_sync
 * build: FLATPAK_ID and FLATPAK_ARCH are now set in the environment when building
 * update: Don't fail the entire update if some remote fails to update its metadata
 * run: /.flatpak-info now lists exact commits and extensions in use
 * run: We now use a per-app ld.so.cache file when running. This should speed things up,
   and allows ldconfig to report the correct results.
 * The verbose mode was changed into two levels, use -vv to show the more detailed info, which
   currently only contains the full bubblewrap argument lists.
 * run: Some common problematic host environment variables are now unset in the sandbox
   (PYTHONPATH, PERLLIB, PERL5LIB and XCURSOR_PATH)
 * run: Fixed failure when a higher prio extensions depended on a lower prio one.
 * run: The extension ld path order is now: app extensions, app, runtime extension, runtime.
   This was previously incorrect in that the app could override app extensions.
 * Extensions are now not downloaded if a matching unmaintained extension is already installed
 * Preemptive changes to handle new bubblewrap change which doesn't user /newroot
 * document portal: Disable debug spew that was accidentally enabled
 * build-finish: New --extension-priority option
 * run: Fix regression in --persist in 0.9.98
 * run: Use sealed memfds (instead of just temporary files) when passing data to bubblewrap

Major changes in 0.9.98.2
=========================

 * Fix permission denied when using the system-helper

Major changes in 0.9.98.1
=========================

 * run: Fix homedir access if the app has --filesystem=host access
 * build-update: Fix appstream update in case one arch didn't change

Major changes in 0.9.98
=======================

 * libflatpak now correctly finds metadata for subset installations (like locale data)
 * flatpak build now supports --appdir which exposes the per-app directory in the
   user homedir. This is useful when testing builds.
 * The host fontconfig caches are exposed to the sandbox, next to the fonts in /run/host.
   This will (pending fontconfig work) allow sharing host fontconfig caches, allowing
   much faster initial startup for flatpak apps.
 * flatpak install now supports --no-pull
 * Added new extension property "locale-subset", which makes the extension point
   act like a locale extension (i.e. only install the subset configured by the
   locale).
 * flatpak remote-add --oci is disabled for now, as this is not up to date with
   the latest OCI work, and we don't want to break existing deployments if this
   has to change when this lands.
 * Parallel installation/updates are now safe because we take a filesystem lock
   whenever we prune the local ostree repo.
 * Flatpak run now works when important paths like $HOME, etc, are symlinks.
 * The ostree min-free-space property is is set to zero by default for the
   flatpak repos. This was causing a lot of problems for people, but the feature
   is still there if you manually enable it.

Major changes in 0.9.12
=======================

 * Fixed a regression in extra-data installation
 * Don't expose the a11y bus in flatpak build

Major changes in 0.9.11
=======================

 * You can now show all outstanding updates with: flatpak remote-ls --updates
 * The dbus filter "org.name.*" now means all subnames of org.name, not just
   the first level. This matches how dbus arg0namespace works, and how the
   coming dbus container support will work.
 * Fixed segfault on update
 * Better commandline tab completion
 * Flatpak now exposes host icons readonly as /run/host/share/icons to the sandbox.

Major changes in 0.9.10
=======================

 Fix regression in dbus proxy that causes some apps to not
 work in 0.9.9.

Major changes in 0.9.9
======================

flatpak-builder was split out into its own module:
  https://github.com/flatpak/flatpak-builder

 * When downloading to a temporary directory for later install to the
   system repo we now write to /var/tmp instead of $HOME. This is more
   likely to be the same filesystem as /var/lib/flatpak, and thus will
   not run into issues with e.g. filesystem full.
 * We now get the default language list from AccountService if possible.
 * A regression that made --devel crash was fixed.
 * New feature for flatpakrefs, SuggestRemoteName=remotename will cause
   flatpak to ask if you want to create a generic (not app specific)
   remote for the repo url.
 * flatpak build now does not die with the parent by default, you have
   to pass --die-with-parent. This was done because die-with-parent
   uses PR_SET_PDEATHSIG which does not work well if the parent is
   threaded, like e.g. gnome-software is.
 * We now always re-set the personality in the sandboxed process
   in order to avoid inheriting weird settings.
 * We now share a single dbus proxy instance for all proxies for a sandbox.
 * dbus-proxy now properly disallows old-style eavesdropping.
 * We now support accessibility by starting a customized dbus proxy for the
   a11y bus.

Major changes in 0.9.8
======================

Core:

 * Experimental support for peer2peer installation, enable with --enable-p2p
 * Add default language setting to flatpak config. Defaults to all locales for
   system installs and the users locale for per-user installs.
 * build-update-repo: Now always keeps the *two* latest deltas around to avoid
   race conditions with outstanding downloads at the time or running the update.
 * Support loading extra data from local lookaside cache.

Flatpak-builder:

 * Set terminal title to the currently building module
 * Added ability to specify http url for sources mirror with --extra-sources-url.
 * --install-deps-from=REMOTE installs the dependencies needed for the
   manifest.
 * New option --delete-build-dirs to always delete build directories,
   even on a failed build.
 * New property "add-extension" makes it nicer to create extension points.

Major changes in 0.9.7
======================

 * Don't re-download git repo when bundling sources
 * Build modules with no source if buildsystem is "simple"
 * Build cleanups

Major changes in 0.9.6
======================

This version requires the latest ostree version (2017.7) because it
uses a new feature that hardens the security of flatpak. Previously,
if you installed to a system-wide repository, the files created for an
application were as specified by the remote repo, but owned by root,
which could include problematic permissions like setuid or
world-writable. We now never create such problematic files or
directories on disk. Flatpak export was also changed to never
create problematic files in new apps.

Related to this, newly created flatpak installations also use the
new "bare-user-only" mode for the repositories, which means you
can now install applications even if your filesystem does not
support extended attributes.

Other changes:

 * flatpak info --show-metadata now only shows the metadata, in
   a machine parseable way.
 * build-export now records the flatpak version in the commit message
 * builder: The .pyc timestamp fixer now allows .pyc files with no
   corresponding .py file.
 * builder: New feature 'inherit-extensions' lets you copy extension
   info from the parent runtime.
 * builder: Set ExtensionOf in auto-created extensions (like Locale
   and Debug)
 * builder: Setting CPPFLAGS now works

Major changes in 0.9.5
======================

 Changes in flatpak:

 * Fix installation of installed tests
 * Don't show an error when updating if a remote is disabled
 * Store the app id in the X-Flatpak key when exporting a
   desktop file.
 * flatpak run: Handle paths when rewriting %u urls during
   file forwarding.
 * builder: Always assume separate builddir when using meson, as
   meson only works with this.
 * document-portal: The app-specific directory is always accessible
   to the app, take this into consideration for AddFull.
 * builder: Don't warn for unknown keys if they start with x-
 * Fix a race condition when restarting the document portal
 * build-update-repo: Don't list removed deltas in the summary
 * list: Don't show .Locale/.Debug/.Sources by default. Show with -a.
 * remote-ls: Don't show .Locale/.Debug/.Sources, or non-primary
   arches (unless the primary does not exist) by default.
   Show with -a.
 * dbus-portal: Fix handling of NameHasOwner
 * builder: Add --export-only to export a previous build.
 * run: Allow regular files for --filesystem=xdg-config/path
 * run: Allow --filesystem=xdg-config/subdir:ro (previously
   it needed to be writable).
 * build-commit-from: Properly handle xa.ref when rewriting
   refnames.

Major changes in 0.9.4
======================

 Changes in flatpak:

 * Now requires ostree 2017.6 and bubblewrap 0.1.8
 * Better progress reporting in CLI and UI
 * Improved output from commands info, list, remotes,
   remote-ls: More detail, colors, nicer table formatting.
 * New command flatpak repo that lets you show information
   about local repositories.
 * When launching exported desktop files, the paths
   passed to it are automatically created as documents
   to allow access to the arguments, if needed.
 * Flatpak install of an already installed application is
   now a warning, not an error.
 * flatpak build now kills all the processes in the
   sandbox when it exits.
 * flatpak update --subpath=... now updates the app event
   if there is no new upstream version, but the subpath is
   different from what is currently installed.
 * Exports are now whitelisted, and the only thing you can
   export are:
     desktop files, icons, dbus services, mime definitions, and
     gnome-shell search providers
 * Exported gnome-shell search providers are automatically
   disabled by default.
 * Exported mimetypes are rewritten to only allow globs, and to
   make the globs have a low priority vs system mime info.
 * A remote can now redirect to a new URL and/or a new GPG key, by
   using build-update-repo --redirect-url=URL --gpg-import=FILE.
   When clients see this they permanently change the local configuration.
   This is very useful when migrating official repositories.
 * flatpak caches in the homedir are now stored in ~/.cache
   (or $XDG_CACHE_HOME) instead of ~/.local/share/flatpak/system-cache.
 * Added version field to all exported dbus interfaces.
 * New AddFull method in the Document Portal, which allows
   exporting multiple files, as-needed by a particular target
   app. This is useful for implementations of dbus activation
   for desktop files.
 * New flag --no-static-deltas for install/update without
   using static deltas. Mostly useful for debugging.
 * TMPDIR is now unset in the sandbox, if set on the
   host. Each sandbox has a personal /tmp that is used.
 * Flatpak run now works if /tmp is a symlink on the
   host.
 * /etc/hosts and /etc/hosts.conf from the host are now exposed
   in the sandbox in addition to /etc/resolv.conf.
 * Titles and default branches are now automatically updated from
   the remote unless they are explicitly set. You no longer have
   to run flatpak remote-modify --update.
 * Some performance improvements when installing apps.
 * When exporting a build, the commit objects now always include
   the branchname, the metadata and install/download size.
   The sizes are reused for faster summary building, and the
   others changes are for future use. The fields are verified
   against the deployed metadata during installation, so it
   is trusted.
 * Fixed minor race condition in portal application identification.
 * lib: New  flatpak_installation_update_appstream_full_sync method
   that allows progress reporting.
 * bash-completion: Fix out-of-bounds read that could produce
   weird completion at times.

 Changes in flatpak-builder:

 * Added support for appdata screenshot mirroring.
 * New property "install-rule" lets you change what Makefile rule to
   use in the install phase.
 * The git "commit" property can now specify both a tag object and the
   commit object it refers to.
 * New cppflags property, similar to e.g. cflags.
 * The "env" property now overrides the cflags/cxxflags/ldflags
   properties, to allow these to be reset.
 * Initial checkout of git/bzr to a temporary directory so that errors
   during checkout do not persist.
 * Properly take the "buildsystem" field into account when calculating
   cache freshness.
 * Don't crash if appstream-compose fails.
 * "ldflags" property now works  correctly.

Major changes in 0.9.3
======================
 Changes in flatpak-builder:

 * "rename-icon" renames in translated icons too
 * Moved manifest format docs to own manpage, "flatpak-manifest".
 * "bootstrap.sh" is now recognized as an autogen.sh alternative
 * Fall back to not using rofiles-fuse if it is not available.
 * Make sure flatpak-builder --run grants the app access to dbus.
 * Make paths paths for module includes and module dependencies
   relative to the included module rather than the "base" json file.
 * When cross-compiling 32bit apps on 64bit arches (like i386 on x86-64)
   then we automatically set a linux32 personallity.
 * Print warnings for unhandled json properties.
 * Make sure flatpak-builder --run works if --extra-data is in the
   finish args.
 * Take build-commands into consideration when considering if the
   build cache is stale.
 * Support for --extra-sources= to pre-seed downloaded sources.
 * Support for --bundle-sources which creates a runtime with the sources
   that were used to build the app.
 * Handle trailing whitespace in git submodule uris
 * Progress reporting while downloading files.

 Other changes:
 * build-export now always exports directories as readable and executable.
 * build-update-repo --generate-static-deltas now fork the work process
   rather than using threads, which avoids problems with this using
   a lot of memory in a single process in some cases.
 * Report flatpak version in HTTP request user agent.
 * New "flatpak repo" command added that has some options for maintaining
   a repository.
 * flatpak info can now report more information and handles multiple
   installed branches better.
 * Support non-default WAYLAND_DISPLAY environment var.
 * Handle application ids that end with .desktop when generating
   appstream data.
 * Documentation updates

Major changes in 0.9.2
======================

 * Fixed a use-after-free and some leaks in the dbus-proxy. This
   is not currently believed to be exploitable, but the proxy is a
   security boundary, so we still  recommend to update.
 * Regular updates now never allow updates to an older version
   than what is currently installed (unless you explicitly specify
   an old commit id). This closes a hole where a MITM attacker can
   force clients to downgrade to an earlier (gpg-signed) version of
   the application.
 * The automatic detection of --from in flatpak install now detects
   flatpakref extensions even in URIs that end in a query string such as
   https://git.gnome.org/browse/gnome-apps-nightly/plain/gedit.flatpakref?h=stable
 * OCI support now supports GPG signatures
 * OCI support now works with the system-helper for unprivileged systemwide
   installation.
 * Experimental support for the new ostree bare-user-only repo mode that
   allows flatpak to run on filesystems without xattrs. Set
   FLATPAK_OSTREE_REPO_MODE=user-only in the environment to use this.
 * builder: New property disable-fsckobjects for git sources
 * builder: New property commit for git sources. This lets you specify
   both a tag (for readability) and a commit id (to ensure the tag doesn't
   change).
 * builder: The manifest file format docs have been split out into its
   own manpage.
 * builder: App manifests now support specifying sdk-extensions that has
   to be installed for the app to build.
 * builder: When creating the platform, remove all sdk-specific extensions,
   allowing creation of sdk-specific extensions.
 * builder: Correctly handle absolute pathnames in the specified
   command.
 * builder: Support --default-branch which defined the branch to build in
   case the manifest doesn't specify one.
 * When exporting builds to ostree we now use the canonical permissions
   for bare-user files, which means the resulting builds can safely
   be used with the new ostree bare-user-only repository type.
 * The detection of "unmaintained" system extensions was broken, and
   in some cases these extensions were not found. This now always
   works.
 * Flatpak now builds with latest OSTree. This required some fixing for
   multiple definitions of the g_auto* macros as OSTree now exports
   those.
 * We no longer rely on ostree trivial-httpd for the tests, because
   this is optional in later versions of ostree. Instead we use
   they python SimpleHTTPServer.
 * The minimum glib version has been corrected to 2.44.
 * The minimum automake version has been increased to 1.13.4
   because some older version didn't work.

Major changes in 0.9.1
======================

This release mostly has changes to flatpak-builder and the build
machinery. All flatpaks built with this version can run
on flatpak 0.8.x, but there has been additions and minor
changes in flatpak-builder that may require minor changes
to existing builder manifests, see below.

The flatpak-builder build cache now uses an ostree feature called
rofiles-fuse. This allows the build to work directly against
hardlinked checkouts of the cache, because rofiles-fuse disallows
writes to the hardlinked files (but allows replacing them). This makes
cache commits and checkouts much faster. However, it also means that
installation cannot do in-place modification of files in the
installation directory. There is a new per-module property called
"ensure-writable" that takes a list of patterns and ensures all files
matching them are writable (by manually breaking the hardlinks). This
may need to be added to some manifests to keep them building in the new
version.

The cflags and cxxflags module properties now work by appending,
rather that replacing, when there are multiple values specified. For
instance, the per-arch or per-module cflags will be appended to the
base cflags. This may cause old json files do duplicate cflags in
some cases. Normally compiler flags are repeatable without problems
though, so it is unlikely to cause problems.

Here are a short summary of the rest of the flatpak-builder changes:

 * The build cache was changed so that it is not invalidated if
   the installed version of the SDK changed. This means that the app
   will not rebuilt if you updated the SDK. This is generally the right
   thing to do, as SDKs are meant to be compatible.  If you want
   to avoid this (for instance when building against an unstable sdk)
   you can use the --rebuild-on-sdk-change argument.
 * The build cache is now per-arch, so building on one arch doesn't
   invalidate the cache for another arch.
 * New buildsystem "cmake-ninja" which works like "cmake", but builds
   using ninja, rather than make.
 * New buildsystem "simple" which doesn't use configure or make, it
   just runs a set of shell commands specified in the "build-commands"
   property. Note: build-commands is also available to other buildsystems
   and are run between make and make install.
 * flatpak-builder now has build-runtime and build-extension properties that
   makes it easier to build runtimes and extensions.
 * FLATPAK_DEST is set in the build environment to the installation
   destination (i.e. typically /app). It is particularly useful when
   building an extension where the destination is more complex.
 * flatpak-builder now supports --from-git=URL which pulls the
   json manifest and related files directly from a git repo.
 * modules have a new no-make-install property which skips
   the make install step.
 * Modules and sources have only-arches and skip-arches properties,
   which lets you enable/disable them based on the build architecture.
 * build-options has a new property ldflags, which is similar
   to cflags and cxxflags.
 * flatpak build (and thus flatpak-builder --run) now supports
    dbus proxies when needed.
 * All git repos are cloned with fsckObjects=true, which means
   we verify that the repos are valid.
 * New flatpak-builder argument --build-shell=MODULE extracts and
   prepares the sources for a specified module and then starts
   a build sandbox inside it.

There are also some other changes:

 * build-export: Now supports --timestamp=ISO-8601-TIMESTAMP, which
   allows you to create reproducible commits.
 * The OCI support has been updated to the latest version of the
   OCI image specification format.
 * There is a new flatpak-bisect script that can be used to bisect
   flatpak applications, looking for regressions.
 * flatpak list got a revamp. It now shows more information, and
   shows both apps and runtimes by default.
 * flatpak remote-list was renamed flatpak remotes in order
   to minimize confusion with flatpak remote-ls. The old name
   is deprecated but still works.

Major changes in 0.8.4
======================

In addition to the regular list of bugfixes this stable release
include backports of one more feature required for making OpenGL work
well. Now extra-data using extensions (such as the nvidia driver) can
specify that it doesn't need a runtime to run its apply script. We use
this in the nvidia driver by making the script a static binary, which
lets us use the nvidia driver for multiple runtimes without requering
that a particular one is installed. We also support an extension point
supporting multiple versions, which will be use for sharing the
nvidia driver between different runtime versions.

Additional fixes:
 * Documentation fixes
 * Crash fixes
 * Fix xauth propagation in some cases
 * Don't remove origin remotes on uninstall if some other app
   is installed from it.
 * Don't reset what locales are installed when updating a locale
   extension
 * Disable splice for the documentation portal as it seems
   to be broken in fuse
 * Append, don't override XDG_DATA_DIRS in profile script
 * Fix progress reporting in libflatpak to go from 0 to
   100% once, merging the various phases.

Major changes in 0.8.3
======================

In addition to the regular list of bugfixes this stable release
include backports of a the updated OpenGL support from master.  This,
in combination with the work in the runtime allows flatpak to work out
of the box with out-of-tree OpenGL drivers, including the nvidia
driver.

Additionally, due to some complicated issues wrt ptrace and user
namespaces this version disables the use of user namespaces if
bubblewrap is setuid, as it cause problems for the way flatpak
portals identifies applications. (See issue #557 for details)

 * Better handling of errors for extra-data
 * Handle extra-data properly for runtimes (as well as apps)
 * Respect required version for runtimes (as well as apps)
 * flatpak list: Don't break if some local ref is not deployed
 * builder: Look for appstream data in /app/share/metadata also
 * builder: Fix buildsystem=cmake builds
 * Add progress reporting to extra-data download
 * Fix uid/gid for directories in document portal

Major changes in 0.8.2
======================

This is a bugfix and security update.

Some of the bind-mounts that flatpak sets up were not read-only as
they should have. This includes: extensions, system fonts,
resolv.conf, localtime and machine-id. Many of these are typically only
writable by root, but some, like the user-specific fonts and
user-installed extensions could be modified from the sandbox.

Everyone using 0.8.x is recommended to update to this version.

Other fixes:

 * There are new configure options for where to install dbus configuration
 * Broken symlinks in the root directory no longer break flatpak run
 * flatpak run with HOME in /var now works
 * dri access now also handles mali devices
 * install handles --arch when installing flatpakrefs
 * system-helper activation fixed on systemd-less setups
 * dbus-proxy now works without /run
 * During installation, failing to update a dependency is now not
   fatal.
 * /etc is now fully writable when building runtimes
 * --filesystem=xdg-config/foo now sets up the bind-mount from the host dir
   even when not using :create.

Major changes in 0.8.1
======================

This is a bugfix and security update (CVE-2017-5226).

Flatpak now uses seccomp to disallow the TIOCSTI ioctl in the sandbox,
which works around the possibility to inject text on the controlling
tty (CVE-2017-5226).

This was previously fixed in bubblewrap in 0.1.6, but that change has
now been reverted as it introduced other problems for flatpak.

 * Update bundled bubblewrap to 0.1.7
 * Fix writing new file with O_EXCL in the document portal.
 * Allow appstream data that doesn't have .desktop in the component id,
   such as data for runtimes.
 * Drop json-glib dependency from 1.2 to 1.0
 * Builder: Fail if unable to read included file
 * OCI: Ensure exported layers are readable by everyone
 * Fix extra-data download in gnome-software
 * Fix update-mime-database trigger when installing via
   the system helper.
 * Updating an app by installing a newer bundle now works
   again.
 * Make /var/tmp not be on a tmpfs (it is now in
   ~/.var/app/$appid/cache/tmp).
 * Documentation / translation updates

Major changes in 0.8.0
======================

This is the first release in a new series of stable releases called
0.8.x. New features will be added to 0.9.x, and only bugfixes will be
backported to 0.8.x. The featureset of this release is a good base to
target if you're creating flatpaks that should be widely usable.

This release technically requires only OSTree 2016.14, and it build
fine with this, but we recommend using OSTree 2016.15, because of the
change in how it verifies the checksums of commits in delta files.

 * Flatpakrepo files now support a RuntimeRepo= key which points to
   a flatpakrepo file. This means the user don't have to manually
   configure a remote for the runtime, just reply to the prompt
   to automatically do this when installing the app.
 * We now support dependencies when installing bundles. This includes
   required runtimes, related refs, and the equivalent of RuntimeRepo.
 * The support for OCI in flatpak has been updated to the latest
   OCI spec version, and support has been added to directly install
   flatpak applications from an OCI image.
 * In flatpak install, the --from and --bundle options are now optional
   if the argument has the correct suffix (.flatpakref and .flatpak)
 * Flatpak install now supports -y to let you avoid interactive prompts.
 * build-finish: We now export mime type files with the right name.
 * build-finish: New --require-version option let you specify a particular
   version of flatpak, and older version of flatpak will not install
   or update to the new version.
 * build-sign: Allow signing all apps by omitting the id.
 * Fix regression in the document portal when adding named files.
 * build-import-bundle now signs the commit if you specify a gpg key.
 * Flatpak now reads configuration from /etc/flatpak/installations.d
   which lets you support multiple system-level installation paths.
   These can be accessed with new --installation=... arguments to
   most of the commands.
 * flatpak-builder: Support --jobs=N to limit parallel builds
 * flatpak-builder: Patch source got new options property that lets
   you pass arguments to patch.
 * flatpak-builder: New generic "buildsystem: type" option that
   replace the (now deprecated) "cmake: true" option. This
   supports "autotools", "cmake" and "meson".

Major changes in 0.6.14
=======================
 * Update bundled bubblewrap to 0.1.4 which has some nice bugfixes.
   If you are using an external bubblewrap it is recommended, but
   not required to update.
 * Requires OSTree 2016.14, which allows us to drop some old
   workarounds.
 * When installing an application system-wide, don't consider
   dependencies that are installed for the user only.
 * Flatpak install --from now tries to reuse existing remotes to
   avoid creating unnecessary origin remotes.
 * Using --filesystem=$dir when $dir is a symlink-to-directory now works.
 * Using --filesystem=$file to expose unix sockets to the app is now
   allowed.
 * By default all the directories in ~/.var/app (except the app), as
   well as ~/.local/share/flatpak are hidden in the sandbox.
 * New option --filesystem=$dir:create which will create the destination
   if it did not previously exist.
 * --filesystem= now supports for xdg-[config|cache|data]. This
   allows you access to the host versions of these xdg dirs. Additionally
   if you use these with a subdirectory, like:
     --filesystem=xdg-config/subdir
   then that subdirectory on the host will be shared with the per-app
   instance of the xdg-dir.
 * Builder now correctly handles app-ids that have dashes in them.
   Previously this generated invalid ids for the debuginfo and locale
   extensions.
 * The experimental OCI file format support was changed from creating an
   OCI container to creating an OCI image.
 * Fix regression where "flatpak update --appstream remotename" broke

Major changes in 0.6.13
=======================
 * The command line arguments for install/update/uninstall changed

   These used to take an application id and an optional branch name as
   two arguments. This meant you could not specify multiple apps
   to install in a single command. So, instead of having the branch
   as a separate argument we now support partial references.
   If you only specify an id we try to match the rest as best we
   can depending on what is installed/available, but if this
   matches multiple things you have to specify more details.

   For example you can use:
     * org.my.App//stable - Any compatible arch, stable branch
     * org.my.App/x86_64 - x86-64, look for available branch
     * org.my.App/x86_64/stable - exact reference

   This means install/update/uninstall can now install multiple apps
   in a single operation.

 * Application runtime depencenies are checked/downloaded

   Whenever you install or update an application we check that the
   required runtime is installed. If not, we check if it is available
   in any configured remote, and if found asks the user if/where to
   install it from. If it is not found, the install/update fails.

   You can mark remotes as --no-use-for-deps, which means flatpak will
   never search for runtime dependencies in such remotes. This makes
   the dependency search faster if you have app-only remotes.
   It is recommended that app-only .flatpakrepo file define this
   by specifying NoDeps=true.

 * remote-add and install --from now supports uris

   This means you can install flatpakrefs and flatpakrepos in a
   single command like so:

    * flatpak remote-add --from gnome https://sdk.gnome.org/gnome.flatpakrepo
    * flatpak install --from https://sdk.gnome.org/gedit.flatpakref

 * flatpak run can now launch a runtime directly

   For example, "flatpak run org.gnome.Platform//3.22" will launch a shell
   inside a sandboxy with the gnome 3.22 runtime and an empty /app.
   This is useful for development and testing.

 * included bubblewrap was bumped to 0.1.3 which has a security fix
 * Support for defining the default branch per remote
 * remote-add/modify: --update-metadata pulls current title and default branch
   from remote summary file
 * Applications can now list a set of URIs that will be downloaded with the
   application. The app can then extract these and use as a part of the
   application data. This is useful for applications using freely downloadable
   parts that can't be redistributed elsewhere.
 * flatpak-builder: Support --finish-only and --allow-missing-runtimes
 * flatpak-builder: Support app layering

   An app can define a "base" application which is used for the initial
   content before the application is built. This way applications can
   be built in a layered fashion.

 * dbus proxy: The filtering has been tightened up
 * build-finish: Now exports icons for themes other than hicolor too
 * There is support in the app metadata for generic policies.

   These are read and propagated and supports overriding, but are
   not otherwise interpreted by flatpak. They can be used by other
   host services as static permissions for the application.

 * Support for extensions directories

   In addition to using flatpak maintained runtime as an extensions
   flatpak can now use raw directories in ~/.local/share/flatpak/extension
   and /var/lib/flatpak/extension. For example, if you create a
   directory called org.freedesktop.Platform.GStreamer.MyPlugins/x86_64/1.4
   there it will be used as a source for gstreamer plugins for all
   runtimes based on the freedesktop 1.4 runtime.

Major changes in 0.6.12
=======================
 * Partial revert in application id rules. Application ids
   can now only have dashes in the last element. This allows
   apps to export files such as org.my.App-extra.desktop which
   was used by the libreoffice builds.
 * By default the kernel keyring is not accessible, as it is
   not containable.
 * Some robustness fixes for build-commit-from
 * Better error messages
 * flatpak update --appstream now updates for all remotes
 * Made flatpak enter work, and you can now use any pid in the sandbox.
   However, it requires root permissions.
 * Support for --device=kvm for /dev/kvm access
 * Support for --allow=multiarch to support non-primary arch support.
   For example running i686 code in an x86_64 app.
 * Add new default-branch setting for the remote configuration

Major changes in 0.6.11
=======================

 * Dashes are now allowed in application ids. However, to still work  with
   symbolic icon names, they may not end with "-symbolic".
 * HostCommand now handles ptys correctly
 * Various documentation updates
 * New FLATPAK_CHECK_VERSION macro in libflatpak
 * HostCommand now returns the real PID rather than a fake one.
 * Fix regression in flatpak update --appstream
 * Fix regression installing bundles without origin urls
 * New flatpak-builder option --show-deps lists all the files
   the manifest depends on.

Major changes in 0.6.10
=======================

 * Dropped requirement for systemd --user.
   The way we detect if an process we're talking to is sandboxed, and
   what application id it has doesn't use cgroups anymore, which means
   that the dependency on systemd in the user session is now optional.
   This also means the --no-desktop argument is not needed any more.
   (It is still accepted but does nothing.)
 * Initial support has been added for .flatpakref files. These are simple key
   value files similar to .flatpakrepo files, however they specify an application
   to install in addition to the repo information. For example, gedit can be
   installed by downloading https://sdk.gnome.org/gedit.flatpakref and running:
     flatpak install --from gedit.flatpakref
   There is also library support for this so it can be added to graphical
   installers (such as gnome-software).
 * Requires OSTree 2016.10. The change in how OSTree handles mtimes in
   checkouts that was introduced in 2016.7 has been reverted, and
   the required changes in Flatpak has been made. This means that
   flatpak now depends on OSTree 2016.10.
 * Requires Bubblewrap 0.1.2 for builds using the system bubblewrap.
   Builds using the included copy need no changes.
 * The $XDG_RUNTIME_DIR/flatpak-info file has added information
   about the running application, and is now also securely available
   for a running application from the host as "/proc/$fd/root/.flatpak-info".
   This is what is used to identify remote apps instead of the cgroup
   info.
 * A new run permission --allow=devel has been added. An application with
   this permission is allowed to use ptrace and perf. This was previously
   only available during "flatpak build" and "flatpak run -d". This
   is useful if you're packaging e.g. an IDE.
 * When an application is updated or removed a /app/.updated or /app/.removed
   file is created for running instances. This can be used by applications to
   trigger e.g. a restart for the new version.
 * A new dbus request "HostCommand" has been added to org.freedesktop.Flatpak.
   This lets you run any command on the host, and is therefore clearly not
   sandboxed, so access to this should be limited. However, it is very useful
   if you're using flatpak mainly as a distribution mechanism, for a non-sandboxed
   application.
 * flatpak-builder now supports running from inside a flatpak, by auto-detecting
   this and using the HostCommand service to run recursive flatpaks.
 * Consecutive calls to flatpak build-update-repo has been speed up.
 * The document portal now allows sandboxed applications to create references
   to files in /app and /usr (in the app/runtime).
 * The update process noew doesn't stop at the first failure.

Major changes in 0.6.9
======================

 * Dropped dependency on libgsystem
 * Allow passing partial refs whenever a CLI command takes
   an app or runtime name.
 * New command build-commit-from creates a new commit based
   on the contents of another commit (optionally from another
   local repo).
 * The sandbox now contains $XDG_RUNTIME_DIR/app/$APPID from the
   host (and the directory is created if needed).
 * update: Better output, and faster for the no updates case
 * build-export: Don't make most validation errors fail, instead
   just print a warning.
 * builder: Support local path references for git sources
 * builder: Better handling of recursive git submodules
 * builder: Fixed issues with the .pyc mtime rewriting
 * builder: Handle symbolic icons for rename-icon
 * builder: Add --stop-at=$module to do partial builds
 * builder: Add --sandbox flag to disable the build from escaping
   from the sandbox via build-args.

Major changes in 0.6.8
======================

 * Requires OSTree 2016.7, allowing us to enable use of static delta
   for system downloads again.
 * Support --no-desktop which allows you to run a flatpak app outside
   a desktop, with some loss of functionality (for example, there
   will be no systemd --user scope created for the app)..
 * More documentation.
 * Memory leak fixes.
 * Initial support for rpms as flatpak-builder archive sources.
 * Start work on translating the CLI.
 * Install systemd config snippet to set the right XDG_DATA_DIRS path.
 * Support --arch in flatpak list.
 * Support access() in the document portal.
 * Validate exported desktop files.

Major changes in 0.6.7
======================

 * Automatically download and update related references such
   as locales when using the CLI.
 * lib: Support for getting related references
 * Document metadata format
 * Support build using system-installed bwrap
 * Allow access to the journal socket in the sandbox
 * builder: Support applying patches with git (useful for binary diffs)
 * Require ostree 2016.6

Major changes in 0.6.6
======================

 * Better support for multi-arch (for instance, will automatically install
   i386-only app on x86_64 without user having to specify --arch).
 * Support --device=all to access the full host /dev
 * More command line support for managing exported documents
 * Extended API for the document portal: Lookup, Info, List
 * flatpak-builder: Support initializing /var from a runtime
   extension.
 * Disable static deltas when updating via the system helper to
   work around bug in ostree.

Major changes in 0.6.5
======================

 * Documentation improvements
 * builder: Check that the specified command exists after build is done
 * builder: Fix up mtime in headers for python precompiled files
 * builder: Allow submodules and including modules from other json files
 * system-helper builds are optional (--disable-system-helper)
 * system-helper: Support installing from local remotes and bundles
 * Improved support for --subpath installs, including libflatpak support
 * Improved command line completion

Major changes in 0.6.4
======================

 * Fix an issue where flatpak sometimes created empty "repo"
   directories in the CWD

Major changes in 0.6.3
======================

 * Fix resolv.conf regression in `flatpak build`
 * Fix LD_LIBRARY_PATH override support in `flatpak build`
 * Support forwarding app permissions in `flatpak-builder --run`
 * Flatpak is now smarter about the default branch to use in most operations
 * update will not fail on the first error if updating several things
 * New much more complete bash completion system
 * Faster installations
 * Support new keyfile format for remote-add --from=file

Major changes in 0.6.2
======================

 * Fixed no-network support regression in setuid mode.
 * Fixed creation of root-owned file in home dir when using sudo in some cases
 * New --with-privileged-group configure option

Major changes in 0.6.1
======================

 * Fixed support for systems without user namespaces (default for Arch) or
   unprivileged support for user namespaces (default for Debian).
 * Fix memory leak during install/update.
 * update: Fix support for --arch.
 * Set the right location for the system directory in the environment.
 * system-helper: Support updating without deploying (needed for
   gnome-software support).
 * lib: Fix support for updates

Major changes in 0.6.0
======================

Renamed from xdg-app to Flatpak.  Existing repositories should keep
working, and locally user installed apps/runtime will be migrated
automatically. However, there are some things that you have to be
aware of:
 * The command names are now flatpak/flatpak-builder
 * System-wide installed apps/runtimes need to be reinstalled
 * flatpak-builder uses a ".flatpak-builder" subdirectory instead
   of ".xdg-app-builder".
 * The bus name and interface name for the permission
   store is changed, it was in org.freedesktop.XdgApp, but is
   now in org.freedesktop.impl.portal.DesktopPortal.
 * The installation migration is a one-time operation so you can't
   go back to xdg-app after updating.
 * The library API (and name) changed due to the rename.

Other changes:
 * Flatpak now hard-requires ostree 2016.5
 * Switch from using xdg-app-helper to an included version of bubblewrap:
   https://github.com/projectatomic/bubblewrap
 * Added a policykit-based system helper that allows you to authenticate
   via polkit to install into the system repository.
 * Added an experimental command to export/import applications and runtimes
   as an OCI tarball.
 * builder: Fix creation of locale extensions if there was no locale data in the
   build.
 * It is now possible to disable/enable configured remotes.
 * A lot of new tests where added, and we now support installed tests.
 * builder now has an optional --arch argument for multiarch building.
 * Builder modules can be disabled with "disabled": true.
 * Using --filesystem=/tmp now hides the system X11 sockets.


Major changes in 0.5.2
======================

* The way locale extensions work has changed. Now we build a single extension
  for all locales, but we allow you to specify a subset of it during installation
  and update time using the --subpath commandline flag.
  The main reason for this is that the many extensions didn't scale, both in
  technical terms (large ostree summary file size), but also in terms of the
  UI listing hundreds of uninteresting things.
* We no longer use sizes in the commit objects to get installed and download size,
  instead we store some extra metadata in the summary file. This allows us
  to get much faster access to these, as with recent ostree versions we can
  cache the summary file.
* New command xdg-app build-sign that lets you sign a commit at any time.
* New argument xdg-app build --force-clean that removes pre-existing build dirs.
* xdg-app run now uses the "current" version as the default if you specify no
  branch or arch. It used to default to the "master" branch. This will default
  to the last installed version, but can be changed with xdg-app make-current.
* Added config-opts to the build-options in xdg-app-builder. This allows you
  to extend the configure flags in an arch dependent way.
* Documentation updates

Major changes in 0.5.1
=======================
* Make xdg-app-builder --build-only not export the results
* Create all-in-one Locale extension that combines all the locale extensions
* Extract icons for all appdata nodes when creating appstream
* Documentation updates
* Better handling of metadata in xdg-app-builder cache
* Respect the specified branch when exporting in xdg-app-builder
* Fix support for multi-arch with i386 userspace and 64bit kernel
* Avoid deprecated 32bit capabilities syscalls

Major changes in 0.5.0
=======================
* Some libxdg-app API additions for handling bundles
* Default to /bin/sh as user shell in sandbox
* Fix detection of which apps are in use during uninstall
* New implementation of fuse filesystem for document portal.
  It is now cleaner and works on 32bit.
* Honor the noenumerate flag on remotes in CLI and libxdg-app.
* Add change notification for permissions store
* Require signed summaries for gpg-signed remotes
* Fix summary signatures of deltas in xdg-app build-update.

Major changes in 0.4.13
=======================
* Fix misgeneration of appdata xml in some cases
* Various improvements to bundles, and support in libxdgapp
* Add sources to Debug extensions created by xdg-app-builder
* Allow specifying subdirs of xdg-* dirs, for instance:
   --filesystem=xdg-download/some-dir
* Add support for --filesystem=xdg-run/subdir which means
  XDG_RUNTIME_DIR dir, rather than xdg-user-dirs.
* Add --generate-static-deltas option to build-update-repo.

Major changes in 0.4.12
=======================
* Fix crashes.
* Update exports when removing apps.
* Remove appstream and repo refs when removing a remote.
* Add some build options to make libxdg-app usable inside a sandbox.
* xdg-app-builder builds are now in the .xdg-app-builder/build subdir.
* Make system repo bare-user to avoid creating any setuid binaries.
* Add xdg-app-builder --run operation that runs a command with the
  build environment set up.
* Support creating locale extensions with xdg-app-builder.
* Add support for tags to metadata.
* Put runtime info and tags in the appstream data

Major changes in 0.4.11
=======================
* Fix assertion when installing runtime

Major changes in 0.4.10
=======================
* App desktop files and icons were not being exported to the desktop

Major changes in 0.4.9
======================
* Fix crash at end of runtime install.
* xdg-app-builder has a new source type "shell" which lets you run arbitrary
  shell commands.
* Allow apps with writable homedir access to modify the xdg-app repos.
* New xdg-app info command gives you status of an installed app or runtime.
* The xdg-app-builder cache now contains the sdk commit id, so that a new
  version of the sdk invalidates the cache.
* Fixed a regression in the xdg-app install-app backwards compatibility
  handling.
* xdg-app now gives the application access to the deployment path, which can
  be used to give host-side services access to app files (such as help
  documents).
* build-export no longer exports appstream files, and when generating appstream
  files we don't need them to be.
* The default architecture tag used by xdg-app is now made canonical when needed
  (i.e. on arm/x86/mips).

Major changes in 0.4.8
======================
* Changed global installation directory to /var/lib/xdg-app (not /var/xdg-app).
* Add support for a dbus filtering on the system bus.
* Choosing user namespaces or setuid is now a runtime option, not build time.
* Fix xml-escaping in the appstream generation.
* Various build fixes.
* Added some more documentation for the library.
* Disable support for running apps on systems without a systemd user session.
* Fix uninitialized memory read in xdg-app-builder during git checkouts.
* Correctly handle disabled git submodules in xdg-app-builder
* Fix hiding of non-exported symbols in libxdgapp

Major changes in 0.4.7
======================
* Enabled build of libxdg-app by default, now the API is stable
  enough for e.g. gnome-software to use it.
* Restructured the command line interface to xdg-app, it is now
  more streamlined and easy to use. For instance, to install
  both apps or runtimes, now use "xdg-app install $name".
  The old commands still work, but are deprecated and not
  in the docs.
* xdg-app-builder has gotten a bunch of new features that
  makes it easier to build apps, and some initial work to
  make it possible to create runtimes using it
* build-export now finds and export any app-info installed by
  the app, and build-update-repo collects all such exports
  into a per-repo branch for appstream and icons.
* The client (and libs) support for locally mirroring the appstream
  branch for each remote. This allows use to create graphical appstores
  with user-readable information and icons.
* On the client side one can now specify priorities for each
  remote.

Major changes in 0.4.6
======================
* Added an initial version of libxdg-app, a highlevel library
  intended to be used by user interface frontends to xdg-app.
  It is not yet API stable, so it is disabled by default.
  Enable with --enable-libxdgapp
* Added xdg-app-builder, a separate tool that makes it easier to build
  applications with external dependencies.
* Add support for single-file bundles, which can be a useful way
  to distribute apps on e.g. a usb stick. Only works with the
  latest version of ostree.
* Always allow apps to talk to the built-in portals
* Support granting read-only access to the filesystem with e.g. --filesystem=host:ro
* Add /run/user/$uid/xdg-app-info file that contains the current permissions of the app
* Add --writable-sdk option to xdg-app build-init
* Add file locking to better handle concurrent xdg-app operations like update and install
* Various fixes

Major changes in 0.4.5
======================
* Support signing commits in build-export
* Correctly handle symlinks in host root when app has host-fs access
* Always regenerate summary after build-export
* Make uninstall a bit more robust
* Install the dbus introspection files
* Add human readable size to build-export report
* Add /dev/ptmx symlink in app
* Fix apps not getting SIGCHILD
* Only expose minimal /etc/[passwd|group] in app

Major changes in 0.4.4
======================
* Fix race condition in fuse fs
* Don't save uid/gid/xattrs in build-export
* run: Handle existing mounts with spaces in them
* propagate xauth cookies to sandbox

Major changes in 0.4.3
======================
* Build with older ostree
* Add --nofilesystem flag to e.g. xdg-app run
* Add xdg-app dump-runtime command

Major changes in 0.4.2.1
======================
* Fix dbus proxy

Major changes in 0.4.2
======================
* Fix build with older versions of glib
* Fix regression in filesystem access configuration
* Make seccomp use optional (for arches without it)
* Add xdg-app enter command to enter a running sandbox
* Fix /var/cache being readonly
* Add /var/data and /var/config shortcuts for per-app data
* Minor fixes to bash completion

Major changes in 0.4.1
======================
* Fixed a parallel build issue
* Fixed a build issue where openat() didn't get a mode passed
* Don't block ptrace and perf in debug and build runs
* Put nvidia drivers in sandbox if DRI allowed
* Support specifying a version for runtime extensions

Major changes in 0.4.0
======================
* A new permissions store was added to the dbus api.
  This can be used by portal implementations that want to store
  per-app permissions for objects.
* The document portal was added. This is a dbus api
  which you can use to create document ids and assign
  apps permissions to see these documents. The documents
  themselves are accessed via a custom fuse filesystem.
* perf and strace are now blocked via the seccomp filters
* You can now override application metadata on a system
  and per-user level, giving apps more or less access
  than what they request.
* New command modify-remote added which lets you change
  configuration of a remote after it has been added with
  add-remote.
* Support for adding trusted gpg keys on a per-remote basis
  has been added to add-remote and modify-remote.
* The repo-contents command has been renamed to ls-remote
  to better match the other commands.
* The list-remotes command can now show more information
  about the remotes.
* The bash completion implementation has been improved.

Major changes in 0.3.6
======================

* Fix a typo in the socket seccomp rules that made ipv6 not work
* Export the users fonts (~/.local/share/fonts or ~/.fonts) in the sandbox
* Fix seccomp rules to work on i386
* Make exposing xdg user dirs work right

===== ./scripts/flatpak-bisect =====
#!/usr/bin/env python3

import re
import argparse
import os
import gi
import json
import subprocess

gi.require_version('Flatpak', '1.0')
from gi.repository import Flatpak
from gi.repository import GLib

def get_bisection_data():
        return {'ref': None, 'good': None, 'bad': None,
                'refs': None, 'log': None, 'messages': None}

class Bisector():
    def load_cache(self):
        try:
            os.makedirs(os.path.join(GLib.get_user_cache_dir(), 'flatpak'))
        except FileExistsError:
            pass

        self.cache_path = os.path.join(GLib.get_user_cache_dir(),
                                       'flatpak', '%s-%s-bisect.status' % (
                                       self.name, self.branch))
        try:
            with open(self.cache_path, 'rb') as f:
                self.data = json.load(f)
        except FileNotFoundError:
            self.data = None

    def dump_data(self):
        with open(self.cache_path, 'w') as f:
            json.dump(self.data, f)

    def setup_flatpak_app(self):
        self.installation = Flatpak.Installation.new_user()
        kind = Flatpak.RefKind.APP
        if self.runtime:
            kind = Flatpak.RefKind.RUNTIME
        try:
            self.cref = self.installation.get_installed_ref(kind, self.name, None, self.branch, None)
        except GLib.Error as e:
            print("%s\n\nMake sure %s is installed as a "
                  "user (flatpak install --user) and specify `--runtime`"
                  " if it is a runtime." % (e, self.name))
            return -1
        return 0

    def run(self):
        self.name = self.name[0]
        self.load_cache()
        res = self.setup_flatpak_app()
        if res:
            return res

        try:
            func = getattr(self, self.subparser_name)
        except AttributeError:
            print('No action called %s' % self.subparser_name)

            return -1

        res = func()

        if self.data:
            self.dump_data()

        return res

    def set_reference_commits(self, set_name, check_name):
        if not self.data:
            print("You need to first start the bisection")
            return -1
        ref = self.cref.get_latest_commit()

        if self.data[check_name] == ref:
            print('Commit %s is already set as %s...' % (
                ref, check_name))
            return 1

        if ref not in self.data['refs']:
            print("%s is not a known commit." % ref)
            return -1

        print("Setting %s as %s commit" % (ref, set_name))
        self.data[set_name] = ref

        if self.data[set_name] and self.data[check_name]:
            x1 = self.data['refs'].index(self.data['good'])
            x2 = self.data['refs'].index(self.data['bad'])

            refs = self.data['refs'][x1:x2]
            if not refs:
                print("=========================="
                      "First bad commit is:\n%s"
                      "==========================" % self.data['message'][self.data['bad']])
                exit(0)
            ref = refs[int(len(refs) / 2)]
            if self.data['good'] == ref:
                print("\n==========================\n"
                      "First bad commit is:\n\n%s"
                      "==========================" % self.data['messages'][self.data['bad']])
                exit(0)

            return self.checkout(ref)

        return -1

    def load_refs(self):
        repodir, refname = self.download_history()
        history = subprocess.check_output(['ostree', 'log', '--repo', repodir, refname]).decode()

        refs = []
        messages = {}
        message = ""
        _hash = ''
        for l in history.split('\n'):
            rehash = re.search(r'(?<=^commit )\w+', l)
            if rehash:
                if message:
                    messages[_hash] = message
                _hash = rehash.group(0)
                refs.insert(0, _hash)
                message = ""
            message += l + '\n'

        if message:
            messages[_hash] = message

        self.data['refs'] = refs
        self.data['log'] = history
        self.data['messages'] = messages

    def good(self):
        if not self.data['bad']:
            print("Set the bad commit first")
            exit(-1)
        return self.set_reference_commits('good', 'bad')

    def bad(self):
        return self.set_reference_commits('bad', 'good')

    def start(self):
        if self.data:
            print('Bisection already started')
            return -1

        print("Updating to %s latest commit" % self.name)
        self.reset(False)
        self.data = get_bisection_data()
        self.load_refs()

    def download_history(self):
        print("Getting history")
        appidir = os.path.abspath(os.path.join(self.cref.get_deploy_dir(), '..'))
        dirname = "app"
        if self.runtime:
            dirname = "runtime"
        appidir = appidir.split('/%s/' % dirname)
        repodir = os.path.join(appidir[0], 'repo')
        refname = self.cref.get_origin() + ':' + dirname + '/' + self.cref.get_name() + '/' + self.cref.get_arch() + '/' + self.cref.get_branch()
        # FIXME Getting `error: Exceeded maximum recursion` in ostree if using --depth=-1 (or > 250)
        subprocess.call(['ostree', 'pull', '--depth=250', '--commit-metadata-only', '--repo', repodir, refname])

        return repodir, refname

    def log(self):
        if self.data:
            cmd = ['echo', self.data['log']]
        else:
            repodir, refname = self.download_history()
            cmd = ['ostree', 'log', '--repo', repodir, refname]
        pager = os.environ.get('PAGER')
        if pager:
            stdout = subprocess.PIPE
        else:
            stdout = None
        p = subprocess.Popen(cmd, stdout=stdout)
        if pager:
            subprocess.check_call((pager), stdin=p.stdout)
        p.wait()

    def checkout(self, commit=None):
        if not commit:
            commit = self.commit[0]
        refname = self.cref.get_name() + '/' + self.cref.get_arch() + '/' + self.cref.get_branch()
        print("Checking out %s" % commit)
        return subprocess.call(['flatpak', 'update', '--user', refname, '--commit', commit])

    def reset(self, v=True):
        if not self.data:
            if v:
                print("Not bisecting, nothing to reset")
            return -1

        refname = self.cref.get_name() + '/' + self.cref.get_arch() + '/' + self.cref.get_branch()
        print("Removing %s" % self.cache_path)
        os.remove(self.cache_path)
        self.data = None
        return subprocess.call(['flatpak', 'update', '--user', refname])

if __name__ == "__main__":
    parser = argparse.ArgumentParser()
    parser.add_argument('name', nargs=1, help='Application/Runtime to bisect')
    parser.add_argument('-b', '--branch', default='master', help='The branch to bisect')
    parser.add_argument('-r', '--runtime',  action="store_true", help='Bisecting a runtime not an app')

    subparsers = parser.add_subparsers(dest='subparser_name')
    subparsers.required = True
    start_parser = subparsers.add_parser('start', help="Start bisection")
    bad_parser = subparsers.add_parser('bad', help="Set current version as bad")
    good_parser = subparsers.add_parser('good', help="Set current version as good")
    log_parser = subparsers.add_parser('log', help="Download and print application commit history")

    checkout_parser = subparsers.add_parser('checkout', help="Checkout defined commit")
    checkout_parser.add_argument('commit', nargs=1, help='The commit hash to checkout')

    reset_parser = subparsers.add_parser('reset', help="Reset all bisecting data and go back to latest commit")

    bisector = Bisector()
    options = parser.parse_args(namespace=bisector)
    bisector.run()

===== ./scripts/meson.build =====
# Copyright 2022 Collabora Ltd.
# SPDX-License-Identifier: LGPL-2.1-or-later

install_data(
  'flatpak-bisect',
  'flatpak-coredumpctl',
  install_dir : get_option('bindir'),
  install_mode : 'rwxr-xr-x',
)

===== ./scripts/flatpak-coredumpctl =====
#!/usr/bin/env python3
import sys

if sys.version_info < (3, 10):
    print(
        f'A minimum Python version of at least 3.10 is required, '
        f'{sys.version_info.major}.{sys.version_info.minor}.{sys.version_info.micro} was found',
        file=sys.stderr
    )
    sys.exit(1)

import argparse
import re
import shutil
import subprocess
import shlex
import tempfile


class CoreDumper():
    def __init__(self):
        self.build_directory = None
        self.app = None
        self.coredumpctl_matches = ""
        self.extra_flatpak_args = ""
        self.gdb_arguments = ""

    def clean_args(self):
        if not self.build_directory and not self.app:
            print("Either `--build-directory` or `APP` must be specified.",
                file=sys.stderr)
            return False

        return True

    def run(self):
        if not shutil.which("coredumpctl"):
            print("'coredumpctl' not present on the system, can't run.",
                  file=sys.stderr)
            sys.exit(1)

        # We need access to the host from the sandbox to run.
        flatpak_command = ["flatpak", "build" if self.build_directory else "run", "--filesystem=home",
                           f"--filesystem={tempfile.gettempdir()}"] + shlex.split(self.extra_flatpak_args)
        if not self.build_directory:
            flatpak_command.extend(["--command=gdb",
                                    "--devel", self.app])
        else:
            flatpak_command.extend([self.build_directory, "gdb"])

        with tempfile.NamedTemporaryFile() as coredump:
            dumpres = subprocess.run(
                ["coredumpctl", "dump"] + shlex.split(self.coredumpctl_matches),
                stdout=coredump, stderr=subprocess.PIPE, text=True
            )
            if dumpres.returncode != 0:
                print("Failed to retrieve coredump via coredumpctl.", file=sys.stderr)
                if dumpres.stderr:
                    print(f"Reason:\n{dumpres.stderr}", file=sys.stderr)

                sys.exit(dumpres.returncode)

            matches = re.findall(r".*Executable: (.*)", dumpres.stderr)
            if len(matches) != 1:
                print(f"Could not determine executable from coredumpctl output "
                      f"(found {len(matches)} 'Executable:' line(s)).",
                      file=sys.stderr)
                sys.exit(1)
            executable = matches[0]
            if not executable.startswith(("/newroot/", "/app/")):
                print(f"Executable {executable} doesn't seem to be a flatpaked application.",
                    file=sys.stderr)
            executable = executable.replace("/newroot", "", 1)
            flatpak_command.extend([executable, coredump.name])
            flatpak_command.extend(shlex.split(self.gdb_arguments))

            print(f"Running: `{shlex.join(flatpak_command)}`")
            sys.exit(subprocess.run(flatpak_command).returncode)


if __name__ == "__main__":
    parser = argparse.ArgumentParser(description=
        "Debug in gdb an application that crashed inside flatpak."
        " It uses (and thus requires) coredumpctl to retrieve the coredump file.")
    parser.add_argument("-b", "--build-directory", default=None,
                        help="The build directory to use. It allows you to retrieve a coredump"
                        " for applications being built")
    parser.add_argument("--extra-flatpak-args", default="",
                        help="Extra argument to pass to flatpak")
    parser.add_argument("app", nargs="?",
                        help="The flatpak application to use. eg. `org.gnome.Epiphany//3.28`.")
    parser.add_argument("-m", "--coredumpctl-matches", default="", nargs="?",
                        help="Coredumpctl matches, see `man coredumpctl` for more information.")
    parser.add_argument("--gdb-arguments", default="",
                        help="Arguments to pass to gdb.")

    coredumper = CoreDumper()
    options = parser.parse_args(namespace=coredumper)
    if not coredumper.clean_args():
        parser.print_help(sys.stderr)
        sys.exit(1)

    coredumper.run()

===== ./uncrustify.sh =====
#!/bin/sh
uncrustify -c uncrustify.cfg --no-backup `git ls-tree --name-only -r HEAD | grep \\\.[ch]$ | grep -v common/valgrind-private.h | grep -v app/flatpak-polkit-agent-text-listener\\\.[ch]`

===== ./.gitignore =====
*.la
*.o
*.lo
.deps
.libs
ABOUT-NLS
INSTALL
Makefile
Makefile.in
aclocal.m4
autom4te.cache/
test-driver
compile
config.rpath
config.guess
config.h
config.log
config.status
config.sub
configure
depcomp
install-sh
libtool
ltmain.sh
m4/*.m4
!m4/glibtests.m4
!m4/attributes.m4
missing
stamp-h1
config.h.in
stamp-*
gtk-doc.make
flatpak
flatpak-*.tar.xz
/flatpak-1.*/
flatpak-session-helper
flatpak-portal
flatpak-validate-icon
flatpak-oci-authenticator
*~
profile/flatpak.sh
*-dbus-generated.[ch]
flatpak-variant-private.h
flatpak-variant-impl-private.h
flatpak-resources.[ch]
flatpak-permission-dbus.[ch]
flatpak-portal-dbus.[ch]
flatpak-dbus-proxy
permission-store-dbus.[ch]
flatpak-system-helper
oci-authenticator/*.service
portal/*.service
session-helper/*.service
system-helper/*.service
sideload-repos-systemd/flatpak-sideload-usb-repo.service
sideload-repos-systemd/flatpak-sideload-usb-repo.path
flatpak.conf
flatpak.env
flatpak.sh
document-portal/xdp-dbus.[ch]
document-portal/xdp-resources.[ch]
.dirstamp
test-suite*.log
common/flatpak-version-macros.h
flatpak.pc
flatpak.pp.bz2
common/flatpak-enum-types.c
common/flatpak-enum-types.h
test-libflatpak
httpcache
revokefs-fuse
revokefs-demo
Flatpak-1.0.*
libglnx-config.h
/app/parse-datetime.c
/doc/reference/gtkdoc-check.log
/doc/reference/gtkdoc-check.test
/doc/reference/gtkdoc-check.trs
/doc/reference/libflatpak-docs.html
/doc/reference/version.xml
/doc/flatpak-docs.html
/doc/flatpak-docs.xml
/doc/*.1
/doc/*.5
/tags
/test-libglnx-errors
/test-libglnx-errors.log
/test-libglnx-errors.trs
/test-libglnx-fdio
/test-libglnx-fdio.log
/test-libglnx-fdio.trs
/test-libglnx-macros
/test-libglnx-macros.log
/test-libglnx-macros.trs
/test-libglnx-shutil
/test-libglnx-shutil.log
/test-libglnx-shutil.trs
/test-libglnx-xattrs
/test-libglnx-xattrs.log
/test-libglnx-xattrs.trs
/testlibrary
/testlibrary.log
/testlibrary.trs
/testcommon
/testcommon.log
/testcommon.trs
/test-context
/test-context.log
/test-context.trs
/test-exports
/test-exports.log
/test-exports.trs
/test-instance
/test-instance.log
/test-instance.trs
/test-portal
/test-portal.log
/test-portal.trs
/tests/test-keyring/.gpg-v21-migrated
/tests/test-keyring/private-keys-v1.d/
/tests/test-keyring/trustdb.gpg
/tests/test-keyring2/.gpg-v21-migrated
/tests/test-keyring2/private-keys-v1.d/
/tests/test-keyring2/trustdb.gpg
/tests/hello*.flatpak
/tests/platform*.flatpak
/tests/repo
/tests/runtime-repo
/tests/runtime-repo.stamp
/tests/package_version.txt
/tests/test-authenticator
/tests/test-update-portal
/tests/test-portal-impl
/tests/hold-lock
/tests/list-unused
/tests/mock-flatpak
/tests/services/*.service
/tests/share/xdg-desktop-portal/portals/*.portal
/tests/try-syscall
*.test
/tests/*.sh.log
/tests/*.sh.test
/tests/*.sh.trs
/tests/*.wrap.log
/tests/*.wrap.test
/tests/*.wrap.trs
po/.intltool-merge-cache
po/Makefile.in.in
po/POTFILES
po/Flatpak.pot
po/Makevars.template
po/Rules-quot
po/flatpak.pot
po/*.gmo
po/*.sed
po/*.header
po/*.sin
/subprojects/Makefile-*.am.inc
system-helper/org.freedesktop.Flatpak.policy
system-helper/org.freedesktop.Flatpak.rules
flatpak-bwrap
py-compile

===== ./CONTRIBUTING.md =====
## Compiling Flatpak

If you need to build Flatpak from source, you can do so with Meson or
with GNU Autotools. The recommended build system for this version of
Flatpak is Meson, and the Autotools build system is likely to be removed
from a future version of Flatpak.

The exact steps required depend on your distribution. Below are some
steps that should work on Debian and Fedora, based on the configure
options used to build those distributions' packages, These options will
install into `/usr`, which will overwrite your distribution-provided
system copy of Flatpak.
**You should only do this if you understand the risks of it to the
stability of your system, and you probably want to do it in a VM or on
a development machine that's expected to break sometimes!**

### On Debian

Make sure that `deb-src` apt sources are enabled in `/etc/apt/sources.list.d/*.sources` or `/etc/apt/sources.list`. 
See distribution documentation for details.

Then use commands similar to these:

```
git clone https://github.com/flatpak/flatpak
cd flatpak
sudo apt build-dep flatpak
git submodule update --init
meson setup --prefix=/usr --sysconfdir=/etc --localstatedir=/var -Dselinux_module=disabled -Dinstalled_tests=true -Ddbus_config_dir=/usr/share/dbus-1/system.d -Dprivileged_group=sudo -Drun_media_dir=/media -Dsystem_bubblewrap=bwrap -Dsystem_dbus_proxy=xdg-dbus-proxy -Dsystemdsystemunitdir=/lib/systemd/system -Dsystemdsystemenvgendir=/lib/systemd/system-environment-generators -Dsystem_helper_user=_flatpak -Dgtkdoc=disabled _build
meson compile -C _build
meson test -C _build
sudo meson install -C _build
```

Note: Older versions of Ubuntu/Debian, such as `Ubuntu 24.04`, may require also installing `meson` and cannot use the system `bwrap`.

### On Fedora

```
git clone https://github.com/flatpak/flatpak
cd flatpak
sudo dnf builddep flatpak
sudo dnf install gettext-devel socat
git submodule update --init
meson setup --prefix=/usr --sysconfdir=/etc --localstatedir=/var -Dinstalled_tests=true -Dselinux_module=enabled -Dsystem_bubblewrap=bwrap -Dsystem_dbus_proxy=xdg-dbus-proxy _build
meson compile -C _build
meson test -C _build
sudo meson install -C _build
```

## How to run a specified set of tests

Sometimes you don't want to run the whole test suite but just one you're
working on. This can be accomplished with a command like:

```
meson test -C _build test-info@user.wrap test-info@system.wrap
```

## More info
Dependencies you will need include: meson, bison,
gettext, gtk-doc, gobject-introspection, libcap, libarchive, libxml2, libcurl,
gpgme, polkit, libXau, ostree, json-glib, appstream, libseccomp (or their devel
packages).

Most configure arguments are documented in `meson_options.txt`. However,
there are some options that are a bit more complicated.

Flatpak relies on a project called
[Bubblewrap](https://github.com/containers/bubblewrap) for the low-level
sandboxing. By default, an in-tree copy of this is built (distributed in the
tarball or using git submodules in the git tree). This will build a helper
called flatpak-bwrap. If your system has a recent enough version of Bubblewrap
already, you can use `-Dsystem_bubblewrap=bwrap` to use that instead.

Bubblewrap can run in two modes, either using unprivileged user
namespaces or setuid mode. This requires that the kernel supports this,
which some distributions disable. For instance, Debian and Arch
([linux](https://www.archlinux.org/packages/?name=linux) kernel v4.14.5
or later), support user namespaces with the `kernel.unprivileged_userns_clone`
sysctl enabled.

If unprivileged user namespaces are not available, then Bubblewrap must
be built as setuid root. This is believed to be safe, as it is
designed to do this. Any build of Bubblewrap supports both
unprivileged and setuid mode, you just need to set the setuid bit for
it to change mode. The Meson build does not do this automatically.

There are some complications when building Flatpak to a different
prefix than the system-installed version. First of all, the newly
built Flatpak will look for system-installed flatpaks in
`$PREFIX/var/lib/flatpak`, which will not match existing installations.
You can use `-Dsystem_install_dir=/var/lib/flatpak` to make both
installations use the same location.

Secondly, Flatpak ships with a root-privileged PolicyKit helper for
system-wide installation, called `flatpak-system-helper`. It is D-Bus
activated (on the system bus) and if you install in a non-standard
location it is likely that D-Bus will not find it and PolicyKit
integration will not work. However, if the system installation is
synchronized, you can often use the system installed helper instead—
at least if the two versions are close enough.

## This repository

The Flatpak project consists of multiple pieces, and it can be
a bit challenging to find your way around at first. Here is a
quick intro to each of the important subdirectories:
* `app`: the commandline client. Each command has a `flatpak-builtins-` source file
* `common`: contains the library, libflatpak. It also contains various pieces
  of code that are shared between the library, the client and the services.
  Non-public code can be recognized by having a `-private.h` header file.
* `completion`: commandline auto completion support
* `data`: D-Bus interface definition files and GVariant schemas
* `doc`: The sources for the documentation, both man pages and library documentation
* `icon-validator`: A small utility that is used to validate icons
* `oci-authenticator`: service used for authenticating the user for installing
  from oci remotes (e.g. for paid apps)
* `po`: translations
* `portal`: The Flatpak portal service, which lets sandboxed apps request the
  creation of new sandboxes
* `revokefs`: A FUSE filesystem that is used to transfer files downloaded by
  the user to the system-helper without copying
* `session-helper`: The flatpak-session-helper service, which provides various
  helpers for the sandbox setup at runtime
* `tests`: The testsuite
* `subprojects/bubblewrap`: Flatpak's unprivileged sandboxing tool which is
  developed separately and exists here as a submodule
* `subprojects/libglnx`: a small utility library for projects that use GLib on
  Linux, as a submodule
* `subprojects/dbus-proxy`: a filtering proxy for D-Bus connections, as a submodule
* `subprojects/variant-schema-compiler`: a tool for generating code to
  efficiently access data encoded using GVariant, as a submodule
* `system-helper`: The flatpak-system-helper service, which runs as root on the
  system bus and allows non-root users to modify system installations

===== ./icon-validator/validate-icon.c =====
/* vi:set et sw=2 sts=2 cin cino=t0,f0,(0,{s,>2s,n-s,^-s,e-s:
 * Copyright © 2018 Red Hat, Inc
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Matthias Clasen <mclasen@redhat.com>
 */

/* The canonical copy of this file is in:
 * - https://github.com/flatpak/flatpak at icon-validator/validate-icon.c
 * Known copies of this file are in:
 * - https://github.com/flatpak/xdg-desktop-portal at src/validate-icon.c
 */

#include <gdk-pixbuf/gdk-pixbuf.h>
#include <glib/gstdio.h>
#include <errno.h>
#include <unistd.h>

#define ICON_VALIDATOR_GROUP "Icon Validator"

static int
validate_icon (const char *arg_width,
               const char *arg_height,
               const char *filename)
{
  GdkPixbufFormat *format;
  int max_width, max_height;
  int width, height;
  g_autofree char *name = NULL;
  const char *allowed_formats[] = { "png", "jpeg", "svg", NULL };
  g_autoptr(GdkPixbuf) pixbuf = NULL;
  g_autoptr(GError) error = NULL;
  g_autoptr(GKeyFile) key_file = NULL;
  g_autofree char *key_file_data = NULL;

  format = gdk_pixbuf_get_file_info (filename, &width, &height);
  if (format == NULL)
    {
      g_printerr ("Format not recognized\n");
      return 1;
    }

  name = gdk_pixbuf_format_get_name (format);
  if (!g_strv_contains (allowed_formats, name))
    {
      g_printerr ("Format %s not accepted\n", name);
      return 1;
    }

  if (!g_str_equal (name, "svg"))
    {
      max_width = g_ascii_strtoll (arg_width, NULL, 10);
      if (max_width < 16 || max_width > 4096)
        {
          g_printerr ("Bad width limit: %s\n", arg_width);
          return 1;
        }

      max_height = g_ascii_strtoll (arg_height, NULL, 10);
      if (max_height < 16 || max_height > 4096)
        {
          g_printerr ("Bad height limit: %s\n", arg_height);
          return 1;
        }
    }
  else
    {
      /* Sanity check for vector files */
      max_height = max_width = 4096;
    }

  if (width > max_width || height > max_height)
    {
      g_printerr ("Image too large (%dx%d). Max. size %dx%d\n", width, height, max_width, max_height);
      return 1;
    }

  pixbuf = gdk_pixbuf_new_from_file (filename, &error);
  if (pixbuf == NULL)
    {
      g_printerr ("Failed to load image: %s\n", error->message);
      return 1;
    }

  if (width != height)
    {
      g_printerr ("Expected a square icon but got: %dx%d\n", width, height);
      return 1;
    }

  /* Print the format and size for consumption by (at least) the dynamic
   * launcher portal. xdg-desktop-portal has a copy of this file. Use a
   * GKeyFile so the output can be easily extended in the future in a backwards
   * compatible way.
   */
  key_file = g_key_file_new ();
  g_key_file_set_string (key_file, ICON_VALIDATOR_GROUP, "format", name);
  g_key_file_set_integer (key_file, ICON_VALIDATOR_GROUP, "width", width);
  key_file_data = g_key_file_to_data (key_file, NULL, NULL);
  g_print ("%s", key_file_data);

  return 0;
}

G_GNUC_NULL_TERMINATED
static void
add_args (GPtrArray *argv_array, ...)
{
  va_list args;
  const char *arg;

  va_start (args, argv_array);
  while ((arg = va_arg (args, const gchar *)))
    g_ptr_array_add (argv_array, g_strdup (arg));
  va_end (args);
}

static const char *
flatpak_get_bwrap (void)
{
  const char *e = g_getenv ("FLATPAK_BWRAP");

  if (e != NULL)
    return e;
  return HELPER;
}


static gboolean
path_is_usrmerged (const char *dir)
{
  /* does /dir point to /usr/dir? */
  g_autofree char *target = NULL;
  GStatBuf stat_buf_src, stat_buf_target;

  if (g_stat (dir, &stat_buf_src) < 0)
    return FALSE;

  target = g_strdup_printf ("/usr/%s", dir);

  if (g_stat (target, &stat_buf_target) < 0)
    return FALSE;

  return (stat_buf_src.st_dev == stat_buf_target.st_dev) &&
         (stat_buf_src.st_ino == stat_buf_target.st_ino);
}

static int
rerun_in_sandbox (const char *arg_width,
                  const char *arg_height,
                  const char *filename)
{
  const char * const usrmerged_dirs[] = { "bin", "lib32", "lib64", "lib", "sbin" };
  int i;
  g_autoptr(GPtrArray) args = g_ptr_array_new_with_free_func (g_free);
  char validate_icon[PATH_MAX + 1];
  ssize_t symlink_size;

  symlink_size = readlink ("/proc/self/exe", validate_icon, sizeof (validate_icon) - 1);
  if (symlink_size < 0 || (size_t) symlink_size >= sizeof (validate_icon))
    {
      g_printerr ("Error: failed to read /proc/self/exe\n");
      return 1;
    }

  validate_icon[symlink_size] = 0;

  add_args (args,
            flatpak_get_bwrap (),
            "--unshare-ipc",
            "--unshare-net",
            "--unshare-pid",
            "--ro-bind", "/usr", "/usr",
            "--ro-bind-try", "/etc/ld.so.cache", "/etc/ld.so.cache",
            "--ro-bind", validate_icon, validate_icon,
            NULL);

  /* These directories might be symlinks into /usr/... */
  for (i = 0; i < G_N_ELEMENTS (usrmerged_dirs); i++)
    {
      g_autofree char *absolute_dir = g_strdup_printf ("/%s", usrmerged_dirs[i]);

      if (!g_file_test (absolute_dir, G_FILE_TEST_EXISTS))
        continue;

      if (path_is_usrmerged (absolute_dir))
        {
          g_autofree char *symlink_target = g_strdup_printf ("/usr/%s", absolute_dir);

          add_args (args,
                    "--symlink", symlink_target, absolute_dir,
                    NULL);
        }
      else
        {
          add_args (args,
                    "--ro-bind", absolute_dir, absolute_dir,
                    NULL);
        }
    }

  add_args (args,
            "--tmpfs", "/tmp",
            "--proc", "/proc",
            "--dev", "/dev",
            "--chdir", "/",
            "--setenv", "GIO_USE_VFS", "local",
            "--unsetenv", "TMPDIR",
            "--die-with-parent",
            "--ro-bind", filename, filename,
            NULL);

  if (g_getenv ("G_MESSAGES_DEBUG"))
    add_args (args, "--setenv", "G_MESSAGES_DEBUG", g_getenv ("G_MESSAGES_DEBUG"), NULL);
  if (g_getenv ("G_MESSAGES_PREFIXED"))
    add_args (args, "--setenv", "G_MESSAGES_PREFIXED", g_getenv ("G_MESSAGES_PREFIXED"), NULL);

  add_args (args, "--", validate_icon, arg_width, arg_height, filename, NULL);
  g_ptr_array_add (args, NULL);

  {
    g_autofree char *cmdline = g_strjoinv (" ", (char **) args->pdata);
    g_info ("Icon validation: Spawning %s", cmdline);
  }

  execvpe (flatpak_get_bwrap (), (char **) args->pdata, NULL);
  /* If we get here, then execvpe() failed. */
  g_printerr ("Icon validation: execvpe %s: %s\n", flatpak_get_bwrap (), g_strerror (errno));
  return 1;
}

static gboolean opt_sandbox;

static GOptionEntry entries[] = {
  { "sandbox", 0, 0, G_OPTION_ARG_NONE, &opt_sandbox, "Run in a sandbox", NULL },
  { NULL }
};

int
main (int argc, char *argv[])
{
  g_autoptr(GOptionContext) context = NULL;
  g_autoptr(GError) error = NULL;

  context = g_option_context_new ("WIDTH HEIGHT PATH");
  g_option_context_add_main_entries (context, entries, NULL);
  if (!g_option_context_parse (context, &argc, &argv, &error))
    {
      g_printerr ("Error: %s\n", error->message);
      return 1;
    }

  if (argc != 4)
    {
      g_printerr ("Usage: %s [OPTION…] WIDTH HEIGHT PATH\n", argv[0]);
      return 1;
    }

  if (opt_sandbox)
    return rerun_in_sandbox (argv[1], argv[2], argv[3]);
  else
    return validate_icon (argv[1], argv[2], argv[3]);
}

===== ./icon-validator/meson.build =====
# Copyright 2022 Collabora Ltd.
# SPDX-License-Identifier: LGPL-2.1-or-later

executable(
  'flatpak-validate-icon',
  install : true,
  install_dir : get_option('libexecdir'),
  dependencies : [
    gdk_pixbuf_dep,
  ],
  sources : ['validate-icon.c'],
)

===== ./search =====
#!/usr/bin/env bash

DIR="${1:-.}"

find "$DIR" -type f -print0 | while IFS= read -r -d '' file; do
  echo "===== $file ====="
  cat "$file"
  echo
done

===== ./sideload-repos-systemd/tmpfiles.d/flatpak-sideload-repos.conf =====
D /run/flatpak/sideload-repos 0777 - - -

===== ./sideload-repos-systemd/flatpak-sideload-usb-repo.path.in =====
# This unit is intended to be installed in the systemd user instance, and
# depends on /run/flatpak/sideload-repos having been created via
# systemd-tmpfiles. The idea here is that we add any USB drive mounts to the
# appropriate directory so Flatpak can find and pull from them in case they
# have flatpaks on them, both when a new drive is inserted and at the start of
# the user session.
[Path]
PathChanged=@media_dir@/%u

[Install]
WantedBy=default.target

===== ./sideload-repos-systemd/meson.build =====
# Copyright 2022 Collabora Ltd.
# SPDX-License-Identifier: LGPL-2.1-or-later

install_data(
  'flatpak-create-sideload-symlinks.sh',
  install_dir : get_option('libexecdir'),
  install_mode : 'rwxr-xr-x',
)

configure_file(
  input : 'flatpak-sideload-usb-repo.service.in',
  output : 'flatpak-sideload-usb-repo.service',
  configuration : service_conf_data,
  install_dir : get_option('systemduserunitdir'),
)

configure_file(
  input : 'flatpak-sideload-usb-repo.path.in',
  output : 'flatpak-sideload-usb-repo.path',
  configuration : service_conf_data,
  install_dir : get_option('systemduserunitdir'),
)

install_data(
  'tmpfiles.d/flatpak-sideload-repos.conf',
  install_dir : get_option('tmpfilesdir'),
)

===== ./sideload-repos-systemd/flatpak-sideload-usb-repo.service.in =====
# This unit is intended to be installed in the systemd user instance; see the
# docs in flatpak-sideload-usb-repo.path
[Service]
Type=oneshot
ExecStart=@libexecdir@/flatpak-create-sideload-symlinks.sh @media_dir@/%u

[Install]
WantedBy=default.target

===== ./sideload-repos-systemd/flatpak-create-sideload-symlinks.sh =====
#!/usr/bin/env bash

# This script is intended to be run by flatpak-sideload-usb-repo.service

shopt -s nullglob
media_dir=${1:?path to media directory is required}

# Add a link to any newly inserted drives which might have been copied to with
# "flatpak create-usb". If we were to check for a repo on the drive that would
# break the case of using it for sideloading directly after copying to it (e.g.
# for testing).
for f in "$media_dir"/*; do
    if ! test -d "$f"; then
        continue
    fi
    unique_name=automount$(systemd-escape "$f")
    if test -e "/run/flatpak/sideload-repos/$unique_name"; then
        continue
    fi
    ln -s "$f" "/run/flatpak/sideload-repos/$unique_name"
done

# Remove any broken symlinks e.g. from drives that were removed
for f in /run/flatpak/sideload-repos/automount*; do
    OWNER=$(stat -c '%u' "$f")
    if [ "$UID" != "$OWNER" ]; then
        continue
    fi
    if ! test -e "$f"; then
        rm "$f"
    fi
done

===== ./uncrustify.cfg =====
newlines                lf

input_tab_size          8
output_tab_size         8

string_escape_char      92
string_escape_char2     0

# indenting
indent_columns          2
indent_with_tabs        0
indent_align_string     True
indent_brace            2
indent_braces           false
indent_braces_no_func   True
indent_func_call_param  false
indent_func_def_param   false
indent_func_proto_param false
indent_switch_case      0
indent_case_brace       2
indent_paren_close      1

# spacing
sp_arith                        Add
sp_assign                       Add
sp_enum_assign                  Add
sp_bool                         Add
sp_compare                      Add
sp_inside_paren                 Remove
sp_inside_fparens               Remove
sp_func_def_paren               Force
sp_func_proto_paren             Force
sp_paren_paren                  Remove
sp_balance_nested_parens        False
sp_paren_brace                  Remove
sp_before_square                Remove
sp_before_squares               Remove
sp_inside_square                Remove
sp_before_ptr_star              Add
sp_between_ptr_star             Remove
sp_after_comma                  Add
sp_before_comma                 Remove
sp_after_cast                   Add
sp_sizeof_paren                 Add
sp_not                          Remove
sp_inv                          Remove
sp_addr                         Remove
sp_member                       Remove
sp_deref                        Remove
sp_sign                         Remove
sp_incdec                       Remove
sp_attribute_paren              remove
sp_macro                        Force
sp_func_call_paren              Force
sp_func_call_user_paren         Remove
set func_call_user _ N_ C_ g_autoptr g_auto
sp_brace_typedef                add
sp_cond_colon                   add
sp_cond_question                add
sp_defined_paren                remove

# alignment
align_keep_tabs                 False
align_with_tabs                 False
align_on_tabstop                False
align_number_left               True
align_func_params               True
align_var_def_span              0
align_var_def_amp_style         1
align_var_def_colon             true
align_enum_equ_span             0
align_var_struct_span           2
align_var_def_star_style        2
align_var_def_amp_style         2
align_typedef_span              2
align_typedef_func              0
align_typedef_star_style        2
align_typedef_amp_style         2

# newlines
nl_assign_leave_one_liners      True
nl_enum_leave_one_liners        False
nl_func_leave_one_liners        False
nl_if_leave_one_liners          False
nl_end_of_file                  Add
nl_assign_brace                 Remove
nl_fcall_brace                  Add
nl_enum_brace                   Remove
nl_struct_brace                 Force
nl_union_brace                  Force
nl_if_brace                     Force
nl_brace_else                   Force
nl_elseif_brace                 Force
nl_else_brace                   Add
nl_for_brace                    Force
nl_while_brace                  Force
nl_do_brace                     Force
nl_brace_while                  Force
nl_switch_brace                 Force
nl_before_case                  True
nl_after_case                   False
nl_func_type_name               Force
nl_func_proto_type_name         Remove
nl_func_paren                   Remove
nl_func_decl_start              Remove
nl_func_decl_args               Force
nl_func_decl_end                Remove
nl_fdef_brace                   Force
nl_after_return                 False
nl_define_macro                 False
nl_create_if_one_liner          False
nl_create_for_one_liner         False
nl_create_while_one_liner       False
nl_after_semicolon              True
nl_multi_line_cond              true

eat_blanks_after_open_brace     true
eat_blanks_before_close_brace   true

# mod
# I'd like these to be remove, but that removes brackets in if { if { foo } }, which i dislike
# Not clear what to do about that...
#mod_full_brace_for              Remove
#mod_full_brace_if               Remove
#mod_full_brace_if_chain         True
#mod_full_brace_while            Remove
#mod_full_brace_do               Remove
#mod_full_brace_nl               3

mod_paren_on_return             Remove

# line splitting
#code_width                     = 78
ls_for_split_full               True
ls_func_split_full              True

# positioning
pos_bool                        Trail
pos_conditional                 Trail

